aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_wait_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_wait_scan.c')
-rw-r--r--drivers/scsi/scsi_wait_scan.c31
1 files changed, 0 insertions, 31 deletions
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c
deleted file mode 100644
index 8a636103083..00000000000
--- a/drivers/scsi/scsi_wait_scan.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * scsi_wait_scan.c
- *
- * Copyright (C) 2006 James Bottomley <James.Bottomley@SteelEye.com>
- *
- * This is a simple module to wait until all the async scans are
- * complete. The idea is to use it in initrd/initramfs scripts. You
- * modprobe it after all the modprobes of the root SCSI drivers and it
- * will wait until they have all finished scanning their busses before
- * allowing the boot to proceed
- */
-
-#include <linux/module.h>
-#include "scsi_priv.h"
-
-static int __init wait_scan_init(void)
-{
- scsi_complete_async_scans();
- return 0;
-}
-
-static void __exit wait_scan_exit(void)
-{
-}
-
-MODULE_DESCRIPTION("SCSI wait for scans");
-MODULE_AUTHOR("James Bottomley");
-MODULE_LICENSE("GPL");
-
-late_initcall(wait_scan_init);
-module_exit(wait_scan_exit);
c3f96d'>drivers/net/3c523.c1309
-rw-r--r--drivers/net/3c523.h355
-rw-r--r--drivers/net/3c527.c1661
-rw-r--r--drivers/net/3c527.h81
-rw-r--r--drivers/net/7990.c675
-rw-r--r--drivers/net/7990.h254
-rw-r--r--drivers/net/8390.c60
-rw-r--r--drivers/net/8390p.c63
-rw-r--r--drivers/net/Kconfig3011
-rw-r--r--drivers/net/Makefile289
-rw-r--r--drivers/net/Space.c211
-rw-r--r--drivers/net/ac3200.c422
-rw-r--r--drivers/net/acenic_firmware.h9456
-rw-r--r--drivers/net/appletalk/Kconfig20
-rw-r--r--drivers/net/appletalk/cops.c83
-rw-r--r--drivers/net/appletalk/ipddp.c105
-rw-r--r--drivers/net/appletalk/ltpc.c68
-rw-r--r--drivers/net/arcnet/Kconfig12
-rw-r--r--drivers/net/arcnet/Makefile1
-rw-r--r--drivers/net/arcnet/arc-rawmode.c11
-rw-r--r--drivers/net/arcnet/arc-rimi.c34
-rw-r--r--drivers/net/arcnet/arcnet.c164
-rw-r--r--drivers/net/arcnet/capmode.c188
-rw-r--r--drivers/net/arcnet/com20020-isa.c12
-rw-r--r--drivers/net/arcnet/com20020-pci.c19
-rw-r--r--drivers/net/arcnet/com20020.c41
-rw-r--r--drivers/net/arcnet/com20020_cs.c (renamed from drivers/net/pcmcia/com20020_cs.c)205
-rw-r--r--drivers/net/arcnet/com90io.c10
-rw-r--r--drivers/net/arcnet/com90xx.c16
-rw-r--r--drivers/net/arcnet/rfc1051.c18
-rw-r--r--drivers/net/arcnet/rfc1201.c60
-rw-r--r--drivers/net/ariadne.c867
-rw-r--r--drivers/net/arm/Kconfig57
-rw-r--r--drivers/net/arm/Makefile12
-rw-r--r--drivers/net/arm/at91_ether.c1250
-rw-r--r--drivers/net/arm/at91_ether.h109
-rw-r--r--drivers/net/at1700.c915
-rw-r--r--drivers/net/atlx/Makefile1
-rw-r--r--drivers/net/au1000_eth.c1308
-rw-r--r--drivers/net/ax88796.c1008
-rw-r--r--drivers/net/bfin_mac.c1204
-rw-r--r--drivers/net/bnx2_fw.h4613
-rw-r--r--drivers/net/bnx2_fw2.h4616
-rw-r--r--drivers/net/bnx2x.h1165
-rw-r--r--drivers/net/bnx2x_fw_defs.h403
-rw-r--r--drivers/net/bnx2x_hsi.h2873
-rw-r--r--drivers/net/bnx2x_init.h811
-rw-r--r--drivers/net/bnx2x_init_values.h14723
-rw-r--r--drivers/net/bnx2x_link.c4878
-rw-r--r--drivers/net/bnx2x_link.h173
-rw-r--r--drivers/net/bnx2x_main.c10459
-rw-r--r--drivers/net/bonding/Makefile5
-rw-r--r--drivers/net/bonding/bond_3ad.c2242
-rw-r--r--drivers/net/bonding/bond_3ad.h260
-rw-r--r--drivers/net/bonding/bond_alb.c1262
-rw-r--r--drivers/net/bonding/bond_alb.h85
-rw-r--r--drivers/net/bonding/bond_debugfs.c145
-rw-r--r--drivers/net/bonding/bond_main.c5553
-rw-r--r--drivers/net/bonding/bond_netlink.c573
-rw-r--r--drivers/net/bonding/bond_options.c1394
-rw-r--r--drivers/net/bonding/bond_options.h130
-rw-r--r--drivers/net/bonding/bond_procfs.c296
-rw-r--r--drivers/net/bonding/bond_sysfs.c1461
-rw-r--r--drivers/net/bonding/bond_sysfs_slave.c144
-rw-r--r--drivers/net/bonding/bonding.h604
-rw-r--r--drivers/net/caif/Kconfig56
-rw-r--r--drivers/net/caif/Makefile14
-rw-r--r--drivers/net/caif/caif_hsi.c1482
-rw-r--r--drivers/net/caif/caif_serial.c474
-rw-r--r--drivers/net/caif/caif_spi.c871
-rw-r--r--drivers/net/caif/caif_spi_slave.c254
-rw-r--r--drivers/net/caif/caif_virtio.c791
-rw-r--r--drivers/net/can/Kconfig149
-rw-r--r--drivers/net/can/Makefile26
-rw-r--r--drivers/net/can/at91_can.c1439
-rw-r--r--drivers/net/can/bfin_can.c692
-rw-r--r--drivers/net/can/c_can/Kconfig23
-rw-r--r--drivers/net/can/c_can/Makefile9
-rw-r--r--drivers/net/can/c_can/c_can.c1274
-rw-r--r--drivers/net/can/c_can/c_can.h207
-rw-r--r--drivers/net/can/c_can/c_can_pci.c292
-rw-r--r--drivers/net/can/c_can/c_can_platform.c432
-rw-r--r--drivers/net/can/cc770/Kconfig21
-rw-r--r--drivers/net/can/cc770/Makefile9
-rw-r--r--drivers/net/can/cc770/cc770.c883
-rw-r--r--drivers/net/can/cc770/cc770.h203
-rw-r--r--drivers/net/can/cc770/cc770_isa.c380
-rw-r--r--drivers/net/can/cc770/cc770_platform.c274
-rw-r--r--drivers/net/can/dev.c939
-rw-r--r--drivers/net/can/flexcan.c1256
-rw-r--r--drivers/net/can/grcan.c1752
-rw-r--r--drivers/net/can/janz-ican3.c1924
-rw-r--r--drivers/net/can/led.c127
-rw-r--r--drivers/net/can/mscan/Kconfig24
-rw-r--r--drivers/net/can/mscan/Makefile5
-rw-r--r--drivers/net/can/mscan/mpc5xxx_can.c459
-rw-r--r--drivers/net/can/mscan/mscan.c737
-rw-r--r--drivers/net/can/mscan/mscan.h303
-rw-r--r--drivers/net/can/pch_can.c1279
-rw-r--r--drivers/net/can/rcar_can.c876
-rw-r--r--drivers/net/can/sja1000/Kconfig103
-rw-r--r--drivers/net/can/sja1000/Makefile16
-rw-r--r--drivers/net/can/sja1000/ems_pci.c372
-rw-r--r--drivers/net/can/sja1000/ems_pcmcia.c320
-rw-r--r--drivers/net/can/sja1000/kvaser_pci.c399
-rw-r--r--drivers/net/can/sja1000/peak_pci.c761
-rw-r--r--drivers/net/can/sja1000/peak_pcmcia.c744
-rw-r--r--drivers/net/can/sja1000/plx_pci.c650
-rw-r--r--drivers/net/can/sja1000/sja1000.c694
-rw-r--r--drivers/net/can/sja1000/sja1000.h182
-rw-r--r--drivers/net/can/sja1000/sja1000_isa.c324
-rw-r--r--drivers/net/can/sja1000/sja1000_platform.c261
-rw-r--r--drivers/net/can/sja1000/tscan1.c216
-rw-r--r--drivers/net/can/slcan.c782
-rw-r--r--drivers/net/can/softing/Kconfig30
-rw-r--r--drivers/net/can/softing/Makefile6
-rw-r--r--drivers/net/can/softing/softing.h167
-rw-r--r--drivers/net/can/softing/softing_cs.c346
-rw-r--r--drivers/net/can/softing/softing_fw.c692
-rw-r--r--drivers/net/can/softing/softing_main.c870
-rw-r--r--drivers/net/can/softing/softing_platform.h40
-rw-r--r--drivers/net/can/spi/Kconfig10
-rw-r--r--drivers/net/can/spi/Makefile8
-rw-r--r--drivers/net/can/spi/mcp251x.c1266
-rw-r--r--drivers/net/can/ti_hecc.c1055
-rw-r--r--drivers/net/can/usb/Kconfig67
-rw-r--r--drivers/net/can/usb/Makefile12
-rw-r--r--drivers/net/can/usb/ems_usb.c1090
-rw-r--r--drivers/net/can/usb/esd_usb2.c1157
-rw-r--r--drivers/net/can/usb/gs_usb.c971
-rw-r--r--drivers/net/can/usb/kvaser_usb.c1665
-rw-r--r--drivers/net/can/usb/peak_usb/Makefile2
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb.c903
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_core.c950
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_core.h145
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_pro.c1064
-rw-r--r--drivers/net/can/usb/peak_usb/pcan_usb_pro.h179
-rw-r--r--drivers/net/can/usb/usb_8dev.c1035
-rw-r--r--drivers/net/can/vcan.c71
-rw-r--r--drivers/net/can/xilinx_can.c1208
-rw-r--r--drivers/net/cris/eth_v10.c131
-rw-r--r--drivers/net/cs89x0.c1991
-rw-r--r--drivers/net/cxgb3/ael1002.c257
-rw-r--r--drivers/net/cxgb3/vsc8211.c228
-rw-r--r--drivers/net/de600.c537
-rw-r--r--drivers/net/de600.h168
-rw-r--r--drivers/net/de620.c1027
-rw-r--r--drivers/net/de620.h117
-rw-r--r--drivers/net/depca.c2095
-rw-r--r--drivers/net/depca.h185
-rw-r--r--drivers/net/dsa/Kconfig39
-rw-r--r--drivers/net/dsa/Makefile9
-rw-r--r--drivers/net/dsa/mv88e6060.c286
-rw-r--r--drivers/net/dsa/mv88e6123_61_65.c409
-rw-r--r--drivers/net/dsa/mv88e6131.c398
-rw-r--r--drivers/net/dsa/mv88e6xxx.c521
-rw-r--r--drivers/net/dsa/mv88e6xxx.h95
-rw-r--r--drivers/net/dummy.c113
-rw-r--r--drivers/net/e1000/e1000_hw.c8878
-rw-r--r--drivers/net/e1000/e1000_hw.h3406
-rw-r--r--drivers/net/e1000e/82571.c1377
-rw-r--r--drivers/net/e1000e/e1000.h540
-rw-r--r--drivers/net/e1000e/hw.h891
-rw-r--r--drivers/net/e1000e/ich8lan.c2437
-rw-r--r--drivers/net/e1000e/lib.c2500
-rw-r--r--drivers/net/e1000e/netdev.c4835
-rw-r--r--drivers/net/e1000e/param.c421
-rw-r--r--drivers/net/e1000e/phy.c2099
-rw-r--r--drivers/net/e2100.c477
-rw-r--r--drivers/net/eepro.c1817
-rw-r--r--drivers/net/eepro100.c2401
-rw-r--r--drivers/net/eexpress.c1719
-rw-r--r--drivers/net/eexpress.h179
-rw-r--r--drivers/net/ehea/ehea_hcall.h51
-rw-r--r--drivers/net/eql.c137
-rw-r--r--drivers/net/es3210.c471
-rw-r--r--drivers/net/eth16i.c1489
-rw-r--r--drivers/net/ethernet/3com/3c509.c (renamed from drivers/net/3c509.c)307
-rw-r--r--drivers/net/ethernet/3com/3c515.c (renamed from drivers/net/3c515.c)223
-rw-r--r--drivers/net/ethernet/3com/3c574_cs.c (renamed from drivers/net/pcmcia/3c574_cs.c)348
-rw-r--r--drivers/net/ethernet/3com/3c589_cs.c971
-rw-r--r--drivers/net/ethernet/3com/3c59x.c (renamed from drivers/net/3c59x.c)968
-rw-r--r--drivers/net/ethernet/3com/Kconfig107
-rw-r--r--drivers/net/ethernet/3com/Makefile10
-rw-r--r--drivers/net/ethernet/3com/typhoon.c (renamed from drivers/net/typhoon.c)628
-rw-r--r--drivers/net/ethernet/3com/typhoon.h (renamed from drivers/net/typhoon.h)260
-rw-r--r--drivers/net/ethernet/8390/8390.c103
-rw-r--r--drivers/net/ethernet/8390/8390.h (renamed from drivers/net/8390.h)49
-rw-r--r--drivers/net/ethernet/8390/8390p.c105
-rw-r--r--drivers/net/ethernet/8390/Kconfig205
-rw-r--r--drivers/net/ethernet/8390/Makefile18
-rw-r--r--drivers/net/ethernet/8390/apne.c (renamed from drivers/net/apne.c)99
-rw-r--r--drivers/net/ethernet/8390/ax88796.c1016
-rw-r--r--drivers/net/ethernet/8390/axnet_cs.c (renamed from drivers/net/pcmcia/axnet_cs.c)650
-rw-r--r--drivers/net/ethernet/8390/etherh.c (renamed from drivers/net/arm/etherh.c)99
-rw-r--r--drivers/net/ethernet/8390/hydra.c (renamed from drivers/net/hydra.c)71
-rw-r--r--drivers/net/ethernet/8390/lib8390.c (renamed from drivers/net/lib8390.c)429
-rw-r--r--drivers/net/ethernet/8390/mac8390.c882
-rw-r--r--drivers/net/ethernet/8390/mcf8390.c481
-rw-r--r--drivers/net/ethernet/8390/ne.c (renamed from drivers/net/ne.c)402
-rw-r--r--drivers/net/ethernet/8390/ne2k-pci.c (renamed from drivers/net/ne2k-pci.c)115
-rw-r--r--drivers/net/ethernet/8390/pcnet_cs.c (renamed from drivers/net/pcmcia/pcnet_cs.c)643
-rw-r--r--drivers/net/ethernet/8390/smc-ultra.c (renamed from drivers/net/smc-ultra.c)86
-rw-r--r--drivers/net/ethernet/8390/stnic.c (renamed from drivers/net/stnic.c)57
-rw-r--r--drivers/net/ethernet/8390/wd.c (renamed from drivers/net/wd.c)84
-rw-r--r--drivers/net/ethernet/8390/zorro8390.c458
-rw-r--r--drivers/net/ethernet/Kconfig186
-rw-r--r--drivers/net/ethernet/Makefile83
-rw-r--r--drivers/net/ethernet/adaptec/Kconfig35
-rw-r--r--drivers/net/ethernet/adaptec/Makefile5
-rw-r--r--drivers/net/ethernet/adaptec/starfire.c (renamed from drivers/net/starfire.c)410
-rw-r--r--drivers/net/ethernet/adi/Kconfig69
-rw-r--r--drivers/net/ethernet/adi/Makefile5
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.c1921
-rw-r--r--drivers/net/ethernet/adi/bfin_mac.h (renamed from drivers/net/bfin_mac.h)43
-rw-r--r--drivers/net/ethernet/aeroflex/Kconfig11
-rw-r--r--drivers/net/ethernet/aeroflex/Makefile5
-rw-r--r--drivers/net/ethernet/aeroflex/greth.c1607
-rw-r--r--drivers/net/ethernet/aeroflex/greth.h142
-rw-r--r--drivers/net/ethernet/allwinner/Kconfig37
-rw-r--r--drivers/net/ethernet/allwinner/Makefile5
-rw-r--r--drivers/net/ethernet/allwinner/sun4i-emac.c970
-rw-r--r--drivers/net/ethernet/allwinner/sun4i-emac.h108
-rw-r--r--drivers/net/ethernet/alteon/Kconfig48
-rw-r--r--drivers/net/ethernet/alteon/Makefile5
-rw-r--r--drivers/net/ethernet/alteon/acenic.c (renamed from drivers/net/acenic.c)394
-rw-r--r--drivers/net/ethernet/alteon/acenic.h (renamed from drivers/net/acenic.h)27
-rw-r--r--drivers/net/ethernet/altera/Kconfig9
-rw-r--r--drivers/net/ethernet/altera/Makefile8
-rw-r--r--drivers/net/ethernet/altera/altera_msgdma.c206
-rw-r--r--drivers/net/ethernet/altera/altera_msgdma.h35
-rw-r--r--drivers/net/ethernet/altera/altera_msgdmahw.h162
-rw-r--r--drivers/net/ethernet/altera/altera_sgdma.c540
-rw-r--r--drivers/net/ethernet/altera/altera_sgdma.h36
-rw-r--r--drivers/net/ethernet/altera/altera_sgdmahw.h126
-rw-r--r--drivers/net/ethernet/altera/altera_tse.h537
-rw-r--r--drivers/net/ethernet/altera/altera_tse_ethtool.c275
-rw-r--r--drivers/net/ethernet/altera/altera_tse_main.c1577
-rw-r--r--drivers/net/ethernet/altera/altera_utils.c44
-rw-r--r--drivers/net/ethernet/altera/altera_utils.h27
-rw-r--r--drivers/net/ethernet/amd/7990.c666
-rw-r--r--drivers/net/ethernet/amd/7990.h250
-rw-r--r--drivers/net/ethernet/amd/Kconfig192
-rw-r--r--drivers/net/ethernet/amd/Makefile20
-rw-r--r--drivers/net/ethernet/amd/a2065.c (renamed from drivers/net/a2065.c)454
-rw-r--r--drivers/net/ethernet/amd/a2065.h (renamed from drivers/net/a2065.h)0
-rw-r--r--drivers/net/ethernet/amd/am79c961a.c (renamed from drivers/net/arm/am79c961a.c)233
-rw-r--r--drivers/net/ethernet/amd/am79c961a.h (renamed from drivers/net/arm/am79c961a.h)3
-rw-r--r--drivers/net/ethernet/amd/amd8111e.c (renamed from drivers/net/amd8111e.c)234
-rw-r--r--drivers/net/ethernet/amd/amd8111e.h (renamed from drivers/net/amd8111e.h)16
-rw-r--r--drivers/net/ethernet/amd/ariadne.c792
-rw-r--r--drivers/net/ethernet/amd/ariadne.h (renamed from drivers/net/ariadne.h)2
-rw-r--r--drivers/net/ethernet/amd/atarilance.c (renamed from drivers/net/atarilance.c)141
-rw-r--r--drivers/net/ethernet/amd/au1000_eth.c1347
-rw-r--r--drivers/net/ethernet/amd/au1000_eth.h (renamed from drivers/net/au1000_eth.h)64
-rw-r--r--drivers/net/ethernet/amd/declance.c (renamed from drivers/net/declance.c)129
-rw-r--r--drivers/net/ethernet/amd/hplance.c (renamed from drivers/net/hplance.c)148
-rw-r--r--drivers/net/ethernet/amd/hplance.h (renamed from drivers/net/hplance.h)0
-rw-r--r--drivers/net/ethernet/amd/lance.c (renamed from drivers/net/lance.c)153
-rw-r--r--drivers/net/ethernet/amd/mvme147.c (renamed from drivers/net/mvme147.c)73
-rw-r--r--drivers/net/ethernet/amd/ni65.c (renamed from drivers/net/ni65.c)148
-rw-r--r--drivers/net/ethernet/amd/ni65.h (renamed from drivers/net/ni65.h)0
-rw-r--r--drivers/net/ethernet/amd/nmclan_cs.c (renamed from drivers/net/pcmcia/nmclan_cs.c)413
-rw-r--r--drivers/net/ethernet/amd/pcnet32.c (renamed from drivers/net/pcnet32.c)1090
-rw-r--r--drivers/net/ethernet/amd/sun3lance.c (renamed from drivers/net/sun3lance.c)63
-rw-r--r--drivers/net/ethernet/amd/sunlance.c (renamed from drivers/net/sunlance.c)284
-rw-r--r--drivers/net/ethernet/amd/xgbe/Makefile6
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-common.h1007
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c375
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-desc.c556
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-dev.c2182
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c1351
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c510
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-main.c513
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-mdio.c433
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe.h676
-rw-r--r--drivers/net/ethernet/apple/Kconfig65
-rw-r--r--drivers/net/ethernet/apple/Makefile7
-rw-r--r--drivers/net/ethernet/apple/bmac.c (renamed from drivers/net/bmac.c)115
-rw-r--r--drivers/net/ethernet/apple/bmac.h (renamed from drivers/net/bmac.h)0
-rw-r--r--drivers/net/ethernet/apple/mace.c (renamed from drivers/net/mace.c)95
-rw-r--r--drivers/net/ethernet/apple/mace.h (renamed from drivers/net/mace.h)0
-rw-r--r--drivers/net/ethernet/apple/macmace.c (renamed from drivers/net/macmace.c)113
-rw-r--r--drivers/net/ethernet/arc/Kconfig31
-rw-r--r--drivers/net/ethernet/arc/Makefile6
-rw-r--r--drivers/net/ethernet/arc/emac.h214
-rw-r--r--drivers/net/ethernet/arc/emac_main.c887
-rw-r--r--drivers/net/ethernet/arc/emac_mdio.c152
-rw-r--r--drivers/net/ethernet/atheros/Kconfig83
-rw-r--r--drivers/net/ethernet/atheros/Makefile9
-rw-r--r--drivers/net/ethernet/atheros/alx/Makefile3
-rw-r--r--drivers/net/ethernet/atheros/alx/alx.h117
-rw-r--r--drivers/net/ethernet/atheros/alx/ethtool.c313
-rw-r--r--drivers/net/ethernet/atheros/alx/hw.c1110
-rw-r--r--drivers/net/ethernet/atheros/alx/hw.h581
-rw-r--r--drivers/net/ethernet/atheros/alx/main.c1557
-rw-r--r--drivers/net/ethernet/atheros/alx/reg.h854
-rw-r--r--drivers/net/ethernet/atheros/atl1c/Makefile2
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c.h605
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c309
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_hw.c865
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_hw.h1024
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c2803
-rw-r--r--drivers/net/ethernet/atheros/atl1e/Makefile (renamed from drivers/net/atl1e/Makefile)0
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e.h (renamed from drivers/net/atl1e/atl1e.h)32
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c (renamed from drivers/net/atl1e/atl1e_ethtool.c)55
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_hw.c (renamed from drivers/net/atl1e/atl1e_hw.c)67
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_hw.h (renamed from drivers/net/atl1e/atl1e_hw.h)111
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_main.c (renamed from drivers/net/atl1e/atl1e_main.c)734
-rw-r--r--drivers/net/ethernet/atheros/atl1e/atl1e_param.c (renamed from drivers/net/atl1e/atl1e_param.c)44
-rw-r--r--drivers/net/ethernet/atheros/atlx/Makefile3
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.c (renamed from drivers/net/atlx/atl1.c)739
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl1.h (renamed from drivers/net/atlx/atl1.h)41
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl2.c3090
-rw-r--r--drivers/net/ethernet/atheros/atlx/atl2.h524
-rw-r--r--drivers/net/ethernet/atheros/atlx/atlx.c (renamed from drivers/net/atlx/atlx.c)111
-rw-r--r--drivers/net/ethernet/atheros/atlx/atlx.h (renamed from drivers/net/atlx/atlx.h)7
-rw-r--r--drivers/net/ethernet/broadcom/Kconfig164
-rw-r--r--drivers/net/ethernet/broadcom/Makefile14
-rw-r--r--drivers/net/ethernet/broadcom/b44.c (renamed from drivers/net/b44.c)818
-rw-r--r--drivers/net/ethernet/broadcom/b44.h (renamed from drivers/net/b44.h)23
-rw-r--r--drivers/net/ethernet/broadcom/bcm63xx_enet.c2919
-rw-r--r--drivers/net/ethernet/broadcom/bcm63xx_enet.h360
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c1633
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.h678
-rw-r--r--drivers/net/ethernet/broadcom/bgmac.c1588
-rw-r--r--drivers/net/ethernet/broadcom/bgmac.h488
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.c (renamed from drivers/net/bnx2.c)3903
-rw-r--r--drivers/net/ethernet/broadcom/bnx2.h (renamed from drivers/net/bnx2.h)438
-rw-r--r--drivers/net/ethernet/broadcom/bnx2_fw.h88
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/Makefile8
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h2557
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c4971
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h1326
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c2555
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h205
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h2220
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c3513
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h392
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h38
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h5794
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h786
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h934
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c13716
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h543
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c14166
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_mfw_req.h168
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h (renamed from drivers/net/bnx2x_reg.h)3734
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c5943
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h1425
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c3001
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h584
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c2006
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h555
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c2034
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h434
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c5760
-rw-r--r--drivers/net/ethernet/broadcom/cnic.h426
-rw-r--r--drivers/net/ethernet/broadcom/cnic_defs.h5461
-rw-r--r--drivers/net/ethernet/broadcom/cnic_if.h370
-rw-r--r--drivers/net/ethernet/broadcom/genet/Makefile2
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c2584
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.h628
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmmii.c469
-rw-r--r--drivers/net/ethernet/broadcom/sb1250-mac.c (renamed from drivers/net/sb1250-mac.c)468
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c18214
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h (renamed from drivers/net/tg3.h)1334
-rw-r--r--drivers/net/ethernet/brocade/Kconfig23
-rw-r--r--drivers/net/ethernet/brocade/Makefile5
-rw-r--r--drivers/net/ethernet/brocade/bna/Kconfig17
-rw-r--r--drivers/net/ethernet/brocade/bna/Makefile12
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_cee.c287
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_cee.h65
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_cs.h124
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_defs.h295
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_defs_cna.h220
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_defs_mfg_comm.h154
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_defs_status.h215
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_ioc.c3398
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_ioc.h368
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c944
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_msgq.c667
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_msgq.h130
-rw-r--r--drivers/net/ethernet/brocade/bna/bfi.h570
-rw-r--r--drivers/net/ethernet/brocade/bna/bfi_cna.h163
-rw-r--r--drivers/net/ethernet/brocade/bna/bfi_enet.h858
-rw-r--r--drivers/net/ethernet/brocade/bna/bfi_reg.h456
-rw-r--r--drivers/net/ethernet/brocade/bna/bna.h564
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_enet.c2155
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_hw_defs.h410
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_tx_rx.c4017
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_types.h956
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c3899
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.h431
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad_debugfs.c588
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad_ethtool.c1141
-rw-r--r--drivers/net/ethernet/brocade/bna/cna.h106
-rw-r--r--drivers/net/ethernet/brocade/bna/cna_fwimg.c93
-rw-r--r--drivers/net/ethernet/cadence/Kconfig44
-rw-r--r--drivers/net/ethernet/cadence/Makefile6
-rw-r--r--drivers/net/ethernet/cadence/at91_ether.c483
-rw-r--r--drivers/net/ethernet/cadence/macb.c2067
-rw-r--r--drivers/net/ethernet/cadence/macb.h (renamed from drivers/net/macb.h)243
-rw-r--r--drivers/net/ethernet/calxeda/Kconfig7
-rw-r--r--drivers/net/ethernet/calxeda/Makefile1
-rw-r--r--drivers/net/ethernet/calxeda/xgmac.c1950
-rw-r--r--drivers/net/ethernet/chelsio/Kconfig108
-rw-r--r--drivers/net/ethernet/chelsio/Makefile8
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/Makefile (renamed from drivers/net/chelsio/Makefile)0
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/common.h (renamed from drivers/net/chelsio/common.h)105
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/cphy.h (renamed from drivers/net/chelsio/cphy.h)54
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/cpl5_cmd.h (renamed from drivers/net/chelsio/cpl5_cmd.h)3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/cxgb2.c (renamed from drivers/net/chelsio/cxgb2.c)308
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/elmer0.h (renamed from drivers/net/chelsio/elmer0.h)3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/espi.c (renamed from drivers/net/chelsio/espi.c)7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/espi.h (renamed from drivers/net/chelsio/espi.h)3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/fpga_defs.h (renamed from drivers/net/chelsio/fpga_defs.h)0
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/gmac.h (renamed from drivers/net/chelsio/gmac.h)3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c (renamed from drivers/net/chelsio/mv88e1xxx.c)7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.h (renamed from drivers/net/chelsio/mv88e1xxx.h)0
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/mv88x201x.c (renamed from drivers/net/chelsio/mv88x201x.c)53
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/my3126.c (renamed from drivers/net/chelsio/my3126.c)16
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/pm3393.c (renamed from drivers/net/chelsio/pm3393.c)33
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/regs.h (renamed from drivers/net/chelsio/regs.h)3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/sge.c (renamed from drivers/net/chelsio/sge.c)195
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/sge.h (renamed from drivers/net/chelsio/sge.h)7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/subr.c (renamed from drivers/net/chelsio/subr.c)145
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/suni1x10gexp_regs.h (renamed from drivers/net/chelsio/suni1x10gexp_regs.h)3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/tp.c (renamed from drivers/net/chelsio/tp.c)7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/tp.h (renamed from drivers/net/chelsio/tp.h)1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/vsc7326.c (renamed from drivers/net/chelsio/vsc7326.c)28
-rw-r--r--drivers/net/ethernet/chelsio/cxgb/vsc7326_reg.h (renamed from drivers/net/chelsio/vsc7326_reg.h)0
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/Makefile (renamed from drivers/net/cxgb3/Makefile)2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/adapter.h (renamed from drivers/net/cxgb3/adapter.h)81
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/ael1002.c941
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/aq100x.c354
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/common.h (renamed from drivers/net/cxgb3/common.h)208
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_ctl_defs.h (renamed from drivers/net/cxgb3/cxgb3_ctl_defs.h)19
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_defs.h (renamed from drivers/net/cxgb3/cxgb3_defs.h)5
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_ioctl.h (renamed from drivers/net/cxgb3/cxgb3_ioctl.h)4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c (renamed from drivers/net/cxgb3/cxgb3_main.c)1365
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c (renamed from drivers/net/cxgb3/cxgb3_offload.c)270
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.h (renamed from drivers/net/cxgb3/cxgb3_offload.h)17
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/firmware_exports.h (renamed from drivers/net/cxgb3/firmware_exports.h)2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/l2t.c (renamed from drivers/net/cxgb3/l2t.c)93
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/l2t.h (renamed from drivers/net/cxgb3/l2t.h)27
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/mc5.c (renamed from drivers/net/cxgb3/mc5.c)42
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/regs.h (renamed from drivers/net/cxgb3/regs.h)80
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/sge.c (renamed from drivers/net/cxgb3/sge.c)884
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/sge_defs.h (renamed from drivers/net/cxgb3/sge_defs.h)0
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/t3_cpl.h (renamed from drivers/net/cxgb3/t3_cpl.h)2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/t3_hw.c (renamed from drivers/net/cxgb3/t3_hw.c)851
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/t3cdev.h (renamed from drivers/net/cxgb3/t3cdev.h)4
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/version.h (renamed from drivers/net/cxgb3/version.h)6
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/vsc8211.c416
-rw-r--r--drivers/net/ethernet/chelsio/cxgb3/xgmac.c (renamed from drivers/net/cxgb3/xgmac.c)116
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/Makefile7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h1052
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c6445
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h295
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/l2t.c665
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/l2t.h111
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sge.c2831
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c3986
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.h220
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_msg.h835
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h1298
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h2208
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/Makefile7
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/adapter.h533
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c3009
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/sge.c2461
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h305
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_defs.h121
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c1392
-rw-r--r--drivers/net/ethernet/cirrus/Kconfig64
-rw-r--r--drivers/net/ethernet/cirrus/Makefile7
-rw-r--r--drivers/net/ethernet/cirrus/cs89x0.c1925
-rw-r--r--drivers/net/ethernet/cirrus/cs89x0.h (renamed from drivers/net/cs89x0.h)4
-rw-r--r--drivers/net/ethernet/cirrus/ep93xx_eth.c (renamed from drivers/net/arm/ep93xx_eth.c)333
-rw-r--r--drivers/net/ethernet/cirrus/mac89x0.c (renamed from drivers/net/mac89x0.c)118
-rw-r--r--drivers/net/ethernet/cisco/Kconfig23
-rw-r--r--drivers/net/ethernet/cisco/Makefile5
-rw-r--r--drivers/net/ethernet/cisco/enic/Kconfig9
-rw-r--r--drivers/net/ethernet/cisco/enic/Makefile6
-rw-r--r--drivers/net/ethernet/cisco/enic/cq_desc.h80
-rw-r--r--drivers/net/ethernet/cisco/enic/cq_enet_desc.h185
-rw-r--r--drivers/net/ethernet/cisco/enic/enic.h213
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_api.c48
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_api.h30
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_dev.c292
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_dev.h65
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_ethtool.c306
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c2476
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.c368
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.h36
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_res.c384
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_res.h153
-rw-r--r--drivers/net/ethernet/cisco/enic/rq_enet_desc.h60
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_cq.c91
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_cq.h123
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.c1050
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_dev.h137
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_devcmd.h627
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_enet.h57
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_intr.c68
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_intr.h111
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_nic.h72
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_resource.h76
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rq.c216
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rq.h212
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_rss.h40
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_stats.h70
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_vic.c79
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_vic.h83
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_wq.c195
-rw-r--r--drivers/net/ethernet/cisco/enic/vnic_wq.h175
-rw-r--r--drivers/net/ethernet/cisco/enic/wq_enet_desc.h98
-rw-r--r--drivers/net/ethernet/davicom/Kconfig23
-rw-r--r--drivers/net/ethernet/davicom/Makefile5
-rw-r--r--drivers/net/ethernet/davicom/dm9000.c (renamed from drivers/net/dm9000.c)863
-rw-r--r--drivers/net/ethernet/davicom/dm9000.h (renamed from drivers/net/dm9000.h)38
-rw-r--r--drivers/net/ethernet/dec/Kconfig21
-rw-r--r--drivers/net/ethernet/dec/Makefile5
-rw-r--r--drivers/net/ethernet/dec/tulip/21142.c (renamed from drivers/net/tulip/21142.c)106
-rw-r--r--drivers/net/ethernet/dec/tulip/Kconfig (renamed from drivers/net/tulip/Kconfig)45
-rw-r--r--drivers/net/ethernet/dec/tulip/Makefile (renamed from drivers/net/tulip/Makefile)2
-rw-r--r--drivers/net/ethernet/dec/tulip/de2104x.c (renamed from drivers/net/tulip/de2104x.c)476
-rw-r--r--drivers/net/ethernet/dec/tulip/de4x5.c (renamed from drivers/net/tulip/de4x5.c)322
-rw-r--r--drivers/net/ethernet/dec/tulip/de4x5.h (renamed from drivers/net/tulip/de4x5.h)2
-rw-r--r--drivers/net/ethernet/dec/tulip/dmfe.c (renamed from drivers/net/tulip/dmfe.c)591
-rw-r--r--drivers/net/ethernet/dec/tulip/eeprom.c (renamed from drivers/net/tulip/eeprom.c)91
-rw-r--r--drivers/net/ethernet/dec/tulip/interrupt.c (renamed from drivers/net/tulip/interrupt.c)296
-rw-r--r--drivers/net/ethernet/dec/tulip/media.c (renamed from drivers/net/tulip/media.c)95
-rw-r--r--drivers/net/ethernet/dec/tulip/pnic.c (renamed from drivers/net/tulip/pnic.c)41
-rw-r--r--drivers/net/ethernet/dec/tulip/pnic2.c (renamed from drivers/net/tulip/pnic2.c)74
-rw-r--r--drivers/net/ethernet/dec/tulip/timer.c (renamed from drivers/net/tulip/timer.c)50
-rw-r--r--drivers/net/ethernet/dec/tulip/tulip.h (renamed from drivers/net/tulip/tulip.h)112
-rw-r--r--drivers/net/ethernet/dec/tulip/tulip_core.c (renamed from drivers/net/tulip/tulip_core.c)565
-rw-r--r--drivers/net/ethernet/dec/tulip/uli526x.c (renamed from drivers/net/tulip/uli526x.c)694
-rw-r--r--drivers/net/ethernet/dec/tulip/winbond-840.c (renamed from drivers/net/tulip/winbond-840.c)292
-rw-r--r--drivers/net/ethernet/dec/tulip/xircom_cb.c (renamed from drivers/net/tulip/xircom_cb.c)625
-rw-r--r--drivers/net/ethernet/dlink/Kconfig55
-rw-r--r--drivers/net/ethernet/dlink/Makefile6
-rw-r--r--drivers/net/ethernet/dlink/dl2k.c (renamed from drivers/net/dl2k.c)753
-rw-r--r--drivers/net/ethernet/dlink/dl2k.h (renamed from drivers/net/dl2k.h)139
-rw-r--r--drivers/net/ethernet/dlink/sundance.c (renamed from drivers/net/sundance.c)659
-rw-r--r--drivers/net/ethernet/dnet.c975
-rw-r--r--drivers/net/ethernet/dnet.h225
-rw-r--r--drivers/net/ethernet/ec_bhf.c706
-rw-r--r--drivers/net/ethernet/emulex/Kconfig23
-rw-r--r--drivers/net/ethernet/emulex/Makefile5
-rw-r--r--drivers/net/ethernet/emulex/benet/Kconfig14
-rw-r--r--drivers/net/ethernet/emulex/benet/Makefile7
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h894
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c3957
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h2170
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c1188
-rw-r--r--drivers/net/ethernet/emulex/benet/be_hw.h560
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c5115
-rw-r--r--drivers/net/ethernet/emulex/benet/be_roce.c185
-rw-r--r--drivers/net/ethernet/emulex/benet/be_roce.h78
-rw-r--r--drivers/net/ethernet/ethoc.c1327
-rw-r--r--drivers/net/ethernet/faraday/Kconfig39
-rw-r--r--drivers/net/ethernet/faraday/Makefile6
-rw-r--r--drivers/net/ethernet/faraday/ftgmac100.c1346
-rw-r--r--drivers/net/ethernet/faraday/ftgmac100.h246
-rw-r--r--drivers/net/ethernet/faraday/ftmac100.c1203
-rw-r--r--drivers/net/ethernet/faraday/ftmac100.h180
-rw-r--r--drivers/net/ethernet/fealnx.c (renamed from drivers/net/fealnx.c)200
-rw-r--r--drivers/net/ethernet/freescale/Kconfig97
-rw-r--r--drivers/net/ethernet/freescale/Makefile19
-rw-r--r--drivers/net/ethernet/freescale/fec.h353
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c2726
-rw-r--r--drivers/net/ethernet/freescale/fec_mpc52xx.c (renamed from drivers/net/fec_mpc52xx.c)551
-rw-r--r--drivers/net/ethernet/freescale/fec_mpc52xx.h (renamed from drivers/net/fec_mpc52xx.h)4
-rw-r--r--drivers/net/ethernet/freescale/fec_mpc52xx_phy.c (renamed from drivers/net/fec_mpc52xx_phy.c)132
-rw-r--r--drivers/net/ethernet/freescale/fec_ptp.c400
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/Kconfig (renamed from drivers/net/fs_enet/Kconfig)10
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/Makefile (renamed from drivers/net/fs_enet/Makefile)0
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/fec.h (renamed from drivers/net/fs_enet/fec.h)6
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c (renamed from drivers/net/fs_enet/fs_enet-main.c)380
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/fs_enet.h (renamed from drivers/net/fs_enet/fs_enet.h)56
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-fcc.c (renamed from drivers/net/fs_enet/mac-fcc.c)91
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-fec.c (renamed from drivers/net/fs_enet/mac-fec.c)150
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mac-scc.c (renamed from drivers/net/fs_enet/mac-scc.c)55
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c (renamed from drivers/net/fs_enet/mii-bitbang.c)87
-rw-r--r--drivers/net/ethernet/freescale/fs_enet/mii-fec.c (renamed from drivers/net/fs_enet/mii-fec.c)143
-rw-r--r--drivers/net/ethernet/freescale/fsl_pq_mdio.c488
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c3481
-rw-r--r--drivers/net/ethernet/freescale/gianfar.h (renamed from drivers/net/gianfar.h)781
-rw-r--r--drivers/net/ethernet/freescale/gianfar_ethtool.c1906
-rw-r--r--drivers/net/ethernet/freescale/gianfar_ptp.c576
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth.c (renamed from drivers/net/ucc_geth.c)2644
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth.h (renamed from drivers/net/ucc_geth.h)260
-rw-r--r--drivers/net/ethernet/freescale/ucc_geth_ethtool.c (renamed from drivers/net/ucc_geth_ethtool.c)97
-rw-r--r--drivers/net/ethernet/freescale/xgmac_mdio.c277
-rw-r--r--drivers/net/ethernet/fujitsu/Kconfig31
-rw-r--r--drivers/net/ethernet/fujitsu/Makefile5
-rw-r--r--drivers/net/ethernet/fujitsu/fmvj18x_cs.c (renamed from drivers/net/pcmcia/fmvj18x_cs.c)533
-rw-r--r--drivers/net/ethernet/hisilicon/Kconfig27
-rw-r--r--drivers/net/ethernet/hisilicon/Makefile5
-rw-r--r--drivers/net/ethernet/hisilicon/hix5hd2_gmac.c1066
-rw-r--r--drivers/net/ethernet/hp/Kconfig32
-rw-r--r--drivers/net/ethernet/hp/Makefile5
-rw-r--r--drivers/net/ethernet/hp/hp100.c (renamed from drivers/net/hp100.c)274
-rw-r--r--drivers/net/ethernet/hp/hp100.h (renamed from drivers/net/hp100.h)2
-rw-r--r--drivers/net/ethernet/i825xx/82596.c (renamed from drivers/net/82596.c)292
-rw-r--r--drivers/net/ethernet/i825xx/Kconfig69
-rw-r--r--drivers/net/ethernet/i825xx/Makefile10
-rw-r--r--drivers/net/ethernet/i825xx/ether1.c (renamed from drivers/net/arm/ether1.c)82
-rw-r--r--drivers/net/ethernet/i825xx/ether1.h (renamed from drivers/net/arm/ether1.h)1
-rw-r--r--drivers/net/ethernet/i825xx/lasi_82596.c (renamed from drivers/net/lasi_82596.c)18
-rw-r--r--drivers/net/ethernet/i825xx/lib82596.c (renamed from drivers/net/lib82596.c)105
-rw-r--r--drivers/net/ethernet/i825xx/sni_82596.c (renamed from drivers/net/sni_82596.c)10
-rw-r--r--drivers/net/ethernet/i825xx/sun3_82586.c (renamed from drivers/net/sun3_82586.c)151
-rw-r--r--drivers/net/ethernet/i825xx/sun3_82586.h (renamed from drivers/net/sun3_82586.h)4
-rw-r--r--drivers/net/ethernet/ibm/Kconfig42
-rw-r--r--drivers/net/ethernet/ibm/Makefile7
-rw-r--r--drivers/net/ethernet/ibm/ehea/Makefile (renamed from drivers/net/ehea/Makefile)0
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea.h (renamed from drivers/net/ehea/ehea.h)62
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_ethtool.c (renamed from drivers/net/ehea/ehea_ethtool.c)110
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_hw.h (renamed from drivers/net/ehea/ehea_hw.h)27
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_main.c (renamed from drivers/net/ehea/ehea_main.c)1637
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_phyp.c (renamed from drivers/net/ehea/ehea_phyp.c)72
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_phyp.h (renamed from drivers/net/ehea/ehea_phyp.h)25
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_qmr.c (renamed from drivers/net/ehea/ehea_qmr.c)381
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_qmr.h (renamed from drivers/net/ehea/ehea_qmr.h)27
-rw-r--r--drivers/net/ethernet/ibm/emac/Kconfig (renamed from drivers/net/ibm_newemac/Kconfig)48
-rw-r--r--drivers/net/ethernet/ibm/emac/Makefile11
-rw-r--r--drivers/net/ethernet/ibm/emac/core.c (renamed from drivers/net/ibm_newemac/core.c)444
-rw-r--r--drivers/net/ethernet/ibm/emac/core.h (renamed from drivers/net/ibm_newemac/core.h)60
-rw-r--r--drivers/net/ethernet/ibm/emac/debug.c (renamed from drivers/net/ibm_newemac/debug.c)15
-rw-r--r--drivers/net/ethernet/ibm/emac/debug.h (renamed from drivers/net/ibm_newemac/debug.h)22
-rw-r--r--drivers/net/ethernet/ibm/emac/emac.h (renamed from drivers/net/ibm_newemac/emac.h)28
-rw-r--r--drivers/net/ethernet/ibm/emac/mal.c (renamed from drivers/net/ibm_newemac/mal.c)174
-rw-r--r--drivers/net/ethernet/ibm/emac/mal.h (renamed from drivers/net/ibm_newemac/mal.h)60
-rw-r--r--drivers/net/ethernet/ibm/emac/phy.c (renamed from drivers/net/ibm_newemac/phy.c)97
-rw-r--r--drivers/net/ethernet/ibm/emac/phy.h (renamed from drivers/net/ibm_newemac/phy.h)4
-rw-r--r--drivers/net/ethernet/ibm/emac/rgmii.c (renamed from drivers/net/ibm_newemac/rgmii.c)82
-rw-r--r--drivers/net/ethernet/ibm/emac/rgmii.h (renamed from drivers/net/ibm_newemac/rgmii.h)26
-rw-r--r--drivers/net/ethernet/ibm/emac/tah.c (renamed from drivers/net/ibm_newemac/tah.c)60
-rw-r--r--drivers/net/ethernet/ibm/emac/tah.h (renamed from drivers/net/ibm_newemac/tah.h)22
-rw-r--r--drivers/net/ethernet/ibm/emac/zmii.c (renamed from drivers/net/ibm_newemac/zmii.c)69
-rw-r--r--drivers/net/ethernet/ibm/emac/zmii.h (renamed from drivers/net/ibm_newemac/zmii.h)26
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.c1631
-rw-r--r--drivers/net/ethernet/ibm/ibmveth.h (renamed from drivers/net/ibmveth.h)88
-rw-r--r--drivers/net/ethernet/icplus/Kconfig13
-rw-r--r--drivers/net/ethernet/icplus/Makefile5
-rw-r--r--drivers/net/ethernet/icplus/ipg.c (renamed from drivers/net/ipg.c)349
-rw-r--r--drivers/net/ethernet/icplus/ipg.h (renamed from drivers/net/ipg.h)176
-rw-r--r--drivers/net/ethernet/intel/Kconfig303
-rw-r--r--drivers/net/ethernet/intel/Makefile14
-rw-r--r--drivers/net/ethernet/intel/e100.c (renamed from drivers/net/e100.c)1346
-rw-r--r--drivers/net/ethernet/intel/e1000/Makefile (renamed from drivers/net/e1000/Makefile)0
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000.h (renamed from drivers/net/e1000/e1000.h)185
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_ethtool.c (renamed from drivers/net/e1000/e1000_ethtool.c)693
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_hw.c5769
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_hw.h3112
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_main.c (renamed from drivers/net/e1000/e1000_main.c)3613
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_osdep.h (renamed from drivers/net/e1000/e1000_osdep.h)32
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_param.c (renamed from drivers/net/e1000/e1000_param.c)188
-rw-r--r--drivers/net/ethernet/intel/e1000e/80003es2lan.c (renamed from drivers/net/e1000e/es2lan.c)884
-rw-r--r--drivers/net/ethernet/intel/e1000e/80003es2lan.h88
-rw-r--r--drivers/net/ethernet/intel/e1000e/82571.c2067
-rw-r--r--drivers/net/ethernet/intel/e1000e/82571.h53
-rw-r--r--drivers/net/ethernet/intel/e1000e/Makefile (renamed from drivers/net/e1000e/Makefile)12
-rw-r--r--drivers/net/ethernet/intel/e1000e/defines.h (renamed from drivers/net/e1000e/defines.h)383
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h591
-rw-r--r--drivers/net/ethernet/intel/e1000e/ethtool.c (renamed from drivers/net/e1000e/ethtool.c)1668
-rw-r--r--drivers/net/ethernet/intel/e1000e/hw.h692
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c5155
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.h290
-rw-r--r--drivers/net/ethernet/intel/e1000e/mac.c1801
-rw-r--r--drivers/net/ethernet/intel/e1000e/mac.h68
-rw-r--r--drivers/net/ethernet/intel/e1000e/manage.c344
-rw-r--r--drivers/net/ethernet/intel/e1000e/manage.h65
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c7247
-rw-r--r--drivers/net/ethernet/intel/e1000e/nvm.c631
-rw-r--r--drivers/net/ethernet/intel/e1000e/nvm.h40
-rw-r--r--drivers/net/ethernet/intel/e1000e/param.c533
-rw-r--r--drivers/net/ethernet/intel/e1000e/phy.c3237
-rw-r--r--drivers/net/ethernet/intel/e1000e/phy.h236
-rw-r--r--drivers/net/ethernet/intel/e1000e/ptp.c275
-rw-r--r--drivers/net/ethernet/intel/e1000e/regs.h247
-rw-r--r--drivers/net/ethernet/intel/i40e/Makefile46
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h647
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c1024
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.h110
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h2173
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_alloc.h58
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c2764
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_dcb.c472
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_dcb.h107
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c316
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_debugfs.c2248
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_diag.c154
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_diag.h51
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c1765
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_hmc.c360
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_hmc.h236
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c1000
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h169
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c9044
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c355
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_osdep.h81
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h265
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ptp.c625
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_register.h4674
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_status.h100
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c2344
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.h290
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h1165
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl.h363
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c2441
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h130
-rw-r--r--drivers/net/ethernet/intel/i40evf/Makefile36
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.c978
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.h110
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h2197
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_alloc.h58
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_common.c624
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_hmc.h236
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h169
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_osdep.h75
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_prototype.h94
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_register.h4674
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_status.h100
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.c1667
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_txrx.h287
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_type.h1165
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_virtchnl.h363
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf.h298
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c704
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c2475
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c781
-rw-r--r--drivers/net/ethernet/intel/igb/Makefile (renamed from drivers/net/igb/Makefile)9
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c2865
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.h279
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h (renamed from drivers/net/igb/e1000_defines.h)661
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_hw.h (renamed from drivers/net/igb/e1000_hw.h)406
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c902
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.h93
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.c (renamed from drivers/net/igb/e1000_mac.c)843
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.h87
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mbx.c443
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mbx.h73
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.c (renamed from drivers/net/igb/e1000_nvm.c)422
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.h56
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.c (renamed from drivers/net/igb/e1000_phy.c)1502
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.h174
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_regs.h (renamed from drivers/net/igb/e1000_regs.h)249
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h576
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c3042
-rw-r--r--drivers/net/ethernet/intel/igb/igb_hwmon.c249
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c8184
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c944
-rw-r--r--drivers/net/ethernet/intel/igbvf/Makefile (renamed from drivers/net/ixgbe/Makefile)16
-rw-r--r--drivers/net/ethernet/intel/igbvf/defines.h122
-rw-r--r--drivers/net/ethernet/intel/igbvf/ethtool.c479
-rw-r--r--drivers/net/ethernet/intel/igbvf/igbvf.h329
-rw-r--r--drivers/net/ethernet/intel/igbvf/mbx.c350
-rw-r--r--drivers/net/ethernet/intel/igbvf/mbx.h75
-rw-r--r--drivers/net/ethernet/intel/igbvf/netdev.c2914
-rw-r--r--drivers/net/ethernet/intel/igbvf/regs.h108
-rw-r--r--drivers/net/ethernet/intel/igbvf/vf.c400
-rw-r--r--drivers/net/ethernet/intel/igbvf/vf.h266
-rw-r--r--drivers/net/ethernet/intel/ixgb/Makefile (renamed from drivers/net/ixgb/Makefile)0
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb.h (renamed from drivers/net/ixgb/ixgb.h)43
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_ee.c (renamed from drivers/net/ixgb/ixgb_ee.c)77
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_ee.h (renamed from drivers/net/ixgb/ixgb_ee.h)4
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_ethtool.c (renamed from drivers/net/ixgb/ixgb_ethtool.c)201
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_hw.c (renamed from drivers/net/ixgb/ixgb_hw.c)205
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_hw.h (renamed from drivers/net/ixgb/ixgb_hw.h)55
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_ids.h (renamed from drivers/net/ixgb/ixgb_ids.h)5
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_main.c (renamed from drivers/net/ixgb/ixgb_main.c)721
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_osdep.h (renamed from drivers/net/ixgb/ixgb_osdep.h)19
-rw-r--r--drivers/net/ethernet/intel/ixgb/ixgb_param.c (renamed from drivers/net/ixgb/ixgb_param.c)76
-rw-r--r--drivers/net/ethernet/intel/ixgbe/Makefile44
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h977
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c1358
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c2543
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c3877
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.h206
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.c404
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb.h171
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c288
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.h97
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c363
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.h125
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c814
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c276
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c3093
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c1007
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h87
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c1199
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c8830
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c471
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h121
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c2057
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h160
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c1007
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c1301
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h69
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c230
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h3102
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c897
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/Makefile38
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/defines.h298
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ethtool.c817
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf.h470
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c3809
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/mbx.c349
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/mbx.h126
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/regs.h75
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.c604
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/vf.h211
-rw-r--r--drivers/net/ethernet/jme.c3372
-rw-r--r--drivers/net/ethernet/jme.h1278
-rw-r--r--drivers/net/ethernet/korina.c (renamed from drivers/net/korina.c)356
-rw-r--r--drivers/net/ethernet/lantiq_etop.c818
-rw-r--r--drivers/net/ethernet/marvell/Kconfig134
-rw-r--r--drivers/net/ethernet/marvell/Makefile10
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c3220
-rw-r--r--drivers/net/ethernet/marvell/mvmdio.c301
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c3121
-rw-r--r--drivers/net/ethernet/marvell/pxa168_eth.c1623
-rw-r--r--drivers/net/ethernet/marvell/skge.c (renamed from drivers/net/skge.c)947
-rw-r--r--drivers/net/ethernet/marvell/skge.h (renamed from drivers/net/skge.h)16
-rw-r--r--drivers/net/ethernet/marvell/sky2.c (renamed from drivers/net/sky2.c)2698
-rw-r--r--drivers/net/ethernet/marvell/sky2.h (renamed from drivers/net/sky2.h)350
-rw-r--r--drivers/net/ethernet/mellanox/Kconfig24
-rw-r--r--drivers/net/ethernet/mellanox/Makefile6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/Kconfig46
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/Makefile10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/alloc.c (renamed from drivers/net/mlx4/alloc.c)119
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/catas.c (renamed from drivers/net/mlx4/catas.c)68
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c2610
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cq.c (renamed from drivers/net/mlx4/cq.c)163
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_clock.c334
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_cq.c232
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c263
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c1244
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_main.c369
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c2664
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_port.c223
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_port.h560
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_resources.c115
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c1165
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_selftest.c177
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c919
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c1400
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c2018
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.h (renamed from drivers/net/mlx4/fw.h)60
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.c (renamed from drivers/net/mlx4/icm.c)159
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.h (renamed from drivers/net/mlx4/icm.h)21
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/intf.c (renamed from drivers/net/mlx4/intf.c)35
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c2855
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c1474
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h1315
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h860
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c995
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/pd.c286
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c1292
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/profile.c (renamed from drivers/net/mlx4/profile.c)70
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/qp.c625
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/reset.c (renamed from drivers/net/mlx4/reset.c)35
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c4876
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/sense.c143
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/srq.c (renamed from drivers/net/mlx4/srq.c)155
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/Kconfig8
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/Makefile5
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/alloc.c238
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cmd.c1577
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cq.c237
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/debugfs.c610
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c526
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fw.c185
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/health.c200
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mad.c78
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c548
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mcg.c106
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h75
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/mr.c248
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c531
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pd.c101
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/port.c104
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/qp.c302
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/srq.c223
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/uar.c224
-rw-r--r--drivers/net/ethernet/micrel/Kconfig66
-rw-r--r--drivers/net/ethernet/micrel/Makefile9
-rw-r--r--drivers/net/ethernet/micrel/ks8695net.c1631
-rw-r--r--drivers/net/ethernet/micrel/ks8695net.h107
-rw-r--r--drivers/net/ethernet/micrel/ks8842.c1272
-rw-r--r--drivers/net/ethernet/micrel/ks8851.c1623
-rw-r--r--drivers/net/ethernet/micrel/ks8851.h298
-rw-r--r--drivers/net/ethernet/micrel/ks8851_mll.c1713
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c7264
-rw-r--r--drivers/net/ethernet/microchip/Kconfig38
-rw-r--r--drivers/net/ethernet/microchip/Makefile5
-rw-r--r--drivers/net/ethernet/microchip/enc28j60.c (renamed from drivers/net/enc28j60.c)183
-rw-r--r--drivers/net/ethernet/microchip/enc28j60_hw.h (renamed from drivers/net/enc28j60_hw.h)2
-rw-r--r--drivers/net/ethernet/moxa/Kconfig30
-rw-r--r--drivers/net/ethernet/moxa/Makefile5
-rw-r--r--drivers/net/ethernet/moxa/moxart_ether.c567
-rw-r--r--drivers/net/ethernet/moxa/moxart_ether.h330
-rw-r--r--drivers/net/ethernet/myricom/Kconfig46
-rw-r--r--drivers/net/ethernet/myricom/Makefile5
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/Makefile (renamed from drivers/net/myri10ge/Makefile)0
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c (renamed from drivers/net/myri10ge/myri10ge.c)1553
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp.h (renamed from drivers/net/myri10ge/myri10ge_mcp.h)177
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp_gen_header.h (renamed from drivers/net/myri10ge/myri10ge_mcp_gen_header.h)15
-rw-r--r--drivers/net/ethernet/natsemi/Kconfig67
-rw-r--r--drivers/net/ethernet/natsemi/Makefile9
-rw-r--r--drivers/net/ethernet/natsemi/jazzsonic.c (renamed from drivers/net/jazzsonic.c)90
-rw-r--r--drivers/net/ethernet/natsemi/macsonic.c (renamed from drivers/net/macsonic.c)279
-rw-r--r--drivers/net/ethernet/natsemi/natsemi.c (renamed from drivers/net/natsemi.c)289
-rw-r--r--drivers/net/ethernet/natsemi/ns83820.c (renamed from drivers/net/ns83820.c)254
-rw-r--r--drivers/net/ethernet/natsemi/sonic.c (renamed from drivers/net/sonic.c)31
-rw-r--r--drivers/net/ethernet/natsemi/sonic.h (renamed from drivers/net/sonic.h)20
-rw-r--r--drivers/net/ethernet/natsemi/xtsonic.c321
-rw-r--r--drivers/net/ethernet/neterion/Kconfig55
-rw-r--r--drivers/net/ethernet/neterion/Makefile6
-rw-r--r--drivers/net/ethernet/neterion/s2io-regs.h (renamed from drivers/net/s2io-regs.h)7
-rw-r--r--drivers/net/ethernet/neterion/s2io.c (renamed from drivers/net/s2io.c)4296
-rw-r--r--drivers/net/ethernet/neterion/s2io.h (renamed from drivers/net/s2io.h)64
-rw-r--r--drivers/net/ethernet/neterion/vxge/Makefile7
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-config.c5114
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-config.h2111
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-ethtool.c1132
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-ethtool.h67
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-main.c4871
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-main.h520
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-reg.h4636
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-traffic.c2480
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-traffic.h2290
-rw-r--r--drivers/net/ethernet/neterion/vxge/vxge-version.h49
-rw-r--r--drivers/net/ethernet/netx-eth.c (renamed from drivers/net/netx-eth.c)50
-rw-r--r--drivers/net/ethernet/nuvoton/Kconfig30
-rw-r--r--drivers/net/ethernet/nuvoton/Makefile5
-rw-r--r--drivers/net/ethernet/nuvoton/w90p910_ether.c1095
-rw-r--r--drivers/net/ethernet/nvidia/Kconfig32
-rw-r--r--drivers/net/ethernet/nvidia/Makefile5
-rw-r--r--drivers/net/ethernet/nvidia/forcedeth.c (renamed from drivers/net/forcedeth.c)3136
-rw-r--r--drivers/net/ethernet/nxp/Kconfig8
-rw-r--r--drivers/net/ethernet/nxp/Makefile1
-rw-r--r--drivers/net/ethernet/nxp/lpc_eth.c1609
-rw-r--r--drivers/net/ethernet/octeon/Kconfig14
-rw-r--r--drivers/net/ethernet/octeon/Makefile5
-rw-r--r--drivers/net/ethernet/octeon/octeon_mgmt.c1619
-rw-r--r--drivers/net/ethernet/oki-semi/Kconfig23
-rw-r--r--drivers/net/ethernet/oki-semi/Makefile5
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/Kconfig22
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/Makefile4
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h689
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.c262
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_api.h35
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_ethtool.c512
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c2845
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c521
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.c377
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_phy.h37
-rw-r--r--drivers/net/ethernet/packetengines/Kconfig47
-rw-r--r--drivers/net/ethernet/packetengines/Makefile6
-rw-r--r--drivers/net/ethernet/packetengines/hamachi.c (renamed from drivers/net/hamachi.c)302
-rw-r--r--drivers/net/ethernet/packetengines/yellowfin.c (renamed from drivers/net/yellowfin.c)345
-rw-r--r--drivers/net/ethernet/pasemi/Kconfig30
-rw-r--r--drivers/net/ethernet/pasemi/Makefile6
-rw-r--r--drivers/net/ethernet/pasemi/pasemi_mac.c (renamed from drivers/net/pasemi_mac.c)154
-rw-r--r--drivers/net/ethernet/pasemi/pasemi_mac.h (renamed from drivers/net/pasemi_mac.h)6
-rw-r--r--drivers/net/ethernet/pasemi/pasemi_mac_ethtool.c (renamed from drivers/net/pasemi_mac_ethtool.c)34
-rw-r--r--drivers/net/ethernet/qlogic/Kconfig96
-rw-r--r--drivers/net/ethernet/qlogic/Makefile8
-rw-r--r--drivers/net/ethernet/qlogic/netxen/Makefile (renamed from drivers/net/netxen/Makefile)18
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic.h1889
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c943
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c959
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h (renamed from drivers/net/netxen/netxen_nic_hdr.h)257
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c2593
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.h (renamed from drivers/net/netxen/netxen_nic_hw.h)271
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c1931
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c3527
-rw-r--r--drivers/net/ethernet/qlogic/qla3xxx.c (renamed from drivers/net/qla3xxx.c)1654
-rw-r--r--drivers/net/ethernet/qlogic/qla3xxx.h (renamed from drivers/net/qla3xxx.h)10
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/Makefile15
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h2378
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c4065
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h661
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c2448
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c284
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c1428
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c1147
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h122
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c1874
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h948
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c1686
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h225
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c1310
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c2208
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c4300
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c1358
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h276
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c2209
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c2047
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c1424
-rw-r--r--drivers/net/ethernet/qlogic/qlge/Makefile7
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge.h2338
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_dbg.c2042
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c735
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_main.c5010
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_mpi.c1284
-rw-r--r--drivers/net/ethernet/rdc/Kconfig34
-rw-r--r--drivers/net/ethernet/rdc/Makefile5
-rw-r--r--drivers/net/ethernet/rdc/r6040.c (renamed from drivers/net/r6040.c)773
-rw-r--r--drivers/net/ethernet/realtek/8139cp.c (renamed from drivers/net/8139cp.c)559
-rw-r--r--drivers/net/ethernet/realtek/8139too.c (renamed from drivers/net/8139too.c)724
-rw-r--r--drivers/net/ethernet/realtek/Kconfig115
-rw-r--r--drivers/net/ethernet/realtek/Makefile8
-rw-r--r--drivers/net/ethernet/realtek/atp.c (renamed from drivers/net/atp.c)128
-rw-r--r--drivers/net/ethernet/realtek/atp.h (renamed from drivers/net/atp.h)2
-rw-r--r--drivers/net/ethernet/realtek/r8169.c7245
-rw-r--r--drivers/net/ethernet/renesas/Kconfig16
-rw-r--r--drivers/net/ethernet/renesas/Makefile5
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c3000
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.h573
-rw-r--r--drivers/net/ethernet/s6gmac.c1059
-rw-r--r--drivers/net/ethernet/samsung/Kconfig32
-rw-r--r--drivers/net/ethernet/samsung/Makefile5
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/Makefile4
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h537
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c284
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c522
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h296
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c368
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.h50
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c524
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c2319
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c254
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c254
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.h104
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c259
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h491
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_xpcs.c91
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_xpcs.h38
-rw-r--r--drivers/net/ethernet/seeq/Kconfig35
-rw-r--r--drivers/net/ethernet/seeq/Makefile6
-rw-r--r--drivers/net/ethernet/seeq/ether3.c (renamed from drivers/net/arm/ether3.c)113
-rw-r--r--drivers/net/ethernet/seeq/ether3.h (renamed from drivers/net/arm/ether3.h)1
-rw-r--r--drivers/net/ethernet/seeq/sgiseeq.c (renamed from drivers/net/sgiseeq.c)92
-rw-r--r--drivers/net/ethernet/seeq/sgiseeq.h (renamed from drivers/net/sgiseeq.h)2
-rw-r--r--drivers/net/ethernet/sfc/Kconfig38
-rw-r--r--drivers/net/ethernet/sfc/Makefile8
-rw-r--r--drivers/net/ethernet/sfc/bitfield.h (renamed from drivers/net/sfc/bitfield.h)227
-rw-r--r--drivers/net/ethernet/sfc/ef10.c3699
-rw-r--r--drivers/net/ethernet/sfc/ef10_regs.h355
-rw-r--r--drivers/net/ethernet/sfc/efx.c3288
-rw-r--r--drivers/net/ethernet/sfc/efx.h250
-rw-r--r--drivers/net/ethernet/sfc/enum.h181
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c1133
-rw-r--r--drivers/net/ethernet/sfc/falcon.c2875
-rw-r--r--drivers/net/ethernet/sfc/falcon_boards.c764
-rw-r--r--drivers/net/ethernet/sfc/farch.c2959
-rw-r--r--drivers/net/ethernet/sfc/farch_regs.h2932
-rw-r--r--drivers/net/ethernet/sfc/filter.h272
-rw-r--r--drivers/net/ethernet/sfc/io.h302
-rw-r--r--drivers/net/ethernet/sfc/mcdi.c1891
-rw-r--r--drivers/net/ethernet/sfc/mcdi.h361
-rw-r--r--drivers/net/ethernet/sfc/mcdi_mon.c534
-rw-r--r--drivers/net/ethernet/sfc/mcdi_pcol.h7907
-rw-r--r--drivers/net/ethernet/sfc/mcdi_port.c1024
-rw-r--r--drivers/net/ethernet/sfc/mdio_10g.c323
-rw-r--r--drivers/net/ethernet/sfc/mdio_10g.h110
-rw-r--r--drivers/net/ethernet/sfc/mtd.c133
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h1359
-rw-r--r--drivers/net/ethernet/sfc/nic.c534
-rw-r--r--drivers/net/ethernet/sfc/nic.h798
-rw-r--r--drivers/net/ethernet/sfc/phy.h (renamed from drivers/net/sfc/phy.h)36
-rw-r--r--drivers/net/ethernet/sfc/ptp.c1939
-rw-r--r--drivers/net/ethernet/sfc/qt202x_phy.c495
-rw-r--r--drivers/net/ethernet/sfc/rx.c981
-rw-r--r--drivers/net/ethernet/sfc/selftest.c789
-rw-r--r--drivers/net/ethernet/sfc/selftest.h (renamed from drivers/net/sfc/selftest.h)37
-rw-r--r--drivers/net/ethernet/sfc/siena.c1017
-rw-r--r--drivers/net/ethernet/sfc/siena_sriov.c1645
-rw-r--r--drivers/net/ethernet/sfc/tenxpress.c494
-rw-r--r--drivers/net/ethernet/sfc/tx.c1347
-rw-r--r--drivers/net/ethernet/sfc/txc43128_phy.c560
-rw-r--r--drivers/net/ethernet/sfc/vfdi.h255
-rw-r--r--drivers/net/ethernet/sfc/workarounds.h53
-rw-r--r--drivers/net/ethernet/sgi/Kconfig35
-rw-r--r--drivers/net/ethernet/sgi/Makefile6
-rw-r--r--drivers/net/ethernet/sgi/ioc3-eth.c (renamed from drivers/net/ioc3-eth.c)208
-rw-r--r--drivers/net/ethernet/sgi/meth.c (renamed from drivers/net/meth.c)155
-rw-r--r--drivers/net/ethernet/sgi/meth.h (renamed from drivers/net/meth.h)4
-rw-r--r--drivers/net/ethernet/silan/Kconfig33
-rw-r--r--drivers/net/ethernet/silan/Makefile5
-rw-r--r--drivers/net/ethernet/silan/sc92031.c (renamed from drivers/net/sc92031.c)180
-rw-r--r--drivers/net/ethernet/sis/Kconfig51
-rw-r--r--drivers/net/ethernet/sis/Makefile6
-rw-r--r--drivers/net/ethernet/sis/sis190.c (renamed from drivers/net/sis190.c)408
-rw-r--r--drivers/net/ethernet/sis/sis900.c (renamed from drivers/net/sis900.c)674
-rw-r--r--drivers/net/ethernet/sis/sis900.h (renamed from drivers/net/sis900.h)2
-rw-r--r--drivers/net/ethernet/smsc/Kconfig131
-rw-r--r--drivers/net/ethernet/smsc/Makefile11
-rw-r--r--drivers/net/ethernet/smsc/epic100.c (renamed from drivers/net/epic100.c)661
-rw-r--r--drivers/net/ethernet/smsc/smc911x.c (renamed from drivers/net/smc911x.c)516
-rw-r--r--drivers/net/ethernet/smsc/smc911x.h (renamed from drivers/net/smc911x.h)56
-rw-r--r--drivers/net/ethernet/smsc/smc9194.c (renamed from drivers/net/smc9194.c)193
-rw-r--r--drivers/net/ethernet/smsc/smc9194.h (renamed from drivers/net/smc9194.h)0
-rw-r--r--drivers/net/ethernet/smsc/smc91c92_cs.c (renamed from drivers/net/pcmcia/smc91c92_cs.c)965
-rw-r--r--drivers/net/ethernet/smsc/smc91x.c (renamed from drivers/net/smc91x.c)629
-rw-r--r--drivers/net/ethernet/smsc/smc91x.h (renamed from drivers/net/smc91x.h)320
-rw-r--r--drivers/net/ethernet/smsc/smsc911x.c2634
-rw-r--r--drivers/net/ethernet/smsc/smsc911x.h405
-rw-r--r--drivers/net/ethernet/smsc/smsc9420.c1751
-rw-r--r--drivers/net/ethernet/smsc/smsc9420.h275
-rw-r--r--drivers/net/ethernet/stmicro/Kconfig23
-rw-r--r--drivers/net/ethernet/stmicro/Makefile5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Kconfig90
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Makefile10
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/chain_mode.c160
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h458
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/descs.h219
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/descs_com.h134
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c130
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c330
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c140
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100.h126
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000.h266
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c391
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c201
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c189
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c146
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h116
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c267
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/enh_desc.c402
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/mmc.h135
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/mmc_core.c267
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/norm_desc.c273
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/ring_mode.c135
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h201
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c780
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c148
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c3014
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c318
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c195
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c340
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c212
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h74
-rw-r--r--drivers/net/ethernet/sun/Kconfig88
-rw-r--r--drivers/net/ethernet/sun/Makefile11
-rw-r--r--drivers/net/ethernet/sun/cassini.c (renamed from drivers/net/cassini.c)712
-rw-r--r--drivers/net/ethernet/sun/cassini.h (renamed from drivers/net/cassini.h)1535
-rw-r--r--drivers/net/ethernet/sun/niu.c (renamed from drivers/net/niu.c)2659
-rw-r--r--drivers/net/ethernet/sun/niu.h (renamed from drivers/net/niu.h)50
-rw-r--r--drivers/net/ethernet/sun/sunbmac.c (renamed from drivers/net/sunbmac.c)350
-rw-r--r--drivers/net/ethernet/sun/sunbmac.h (renamed from drivers/net/sunbmac.h)23
-rw-r--r--drivers/net/ethernet/sun/sungem.c (renamed from drivers/net/sungem.c)1461
-rw-r--r--drivers/net/ethernet/sun/sungem.h (renamed from drivers/net/sungem.h)32
-rw-r--r--drivers/net/ethernet/sun/sunhme.c (renamed from drivers/net/sunhme.c)626
-rw-r--r--drivers/net/ethernet/sun/sunhme.h (renamed from drivers/net/sunhme.h)10
-rw-r--r--drivers/net/ethernet/sun/sunqe.c (renamed from drivers/net/sunqe.c)261
-rw-r--r--drivers/net/ethernet/sun/sunqe.h (renamed from drivers/net/sunqe.h)4
-rw-r--r--drivers/net/ethernet/sun/sunvnet.c (renamed from drivers/net/sunvnet.c)172
-rw-r--r--drivers/net/ethernet/sun/sunvnet.h (renamed from drivers/net/sunvnet.h)0
-rw-r--r--drivers/net/ethernet/tehuti/Kconfig27
-rw-r--r--drivers/net/ethernet/tehuti/Makefile5
-rw-r--r--drivers/net/ethernet/tehuti/tehuti.c (renamed from drivers/net/tehuti.c)688
-rw-r--r--drivers/net/ethernet/tehuti/tehuti.h (renamed from drivers/net/tehuti.h)49
-rw-r--r--drivers/net/ethernet/ti/Kconfig105
-rw-r--r--drivers/net/ethernet/ti/Makefile12
-rw-r--r--drivers/net/ethernet/ti/cpmac.c (renamed from drivers/net/cpmac.c)269
-rw-r--r--drivers/net/ethernet/ti/cpsw-phy-sel.c221
-rw-r--r--drivers/net/ethernet/ti/cpsw.c2364
-rw-r--r--drivers/net/ethernet/ti/cpsw.h44
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.c765
-rw-r--r--drivers/net/ethernet/ti/cpsw_ale.h108
-rw-r--r--drivers/net/ethernet/ti/cpts.c416
-rw-r--r--drivers/net/ethernet/ti/cpts.h144
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.c1043
-rw-r--r--drivers/net/ethernet/ti/davinci_cpdma.h117
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c2121
-rw-r--r--drivers/net/ethernet/ti/davinci_mdio.c488
-rw-r--r--drivers/net/ethernet/ti/tlan.c3253
-rw-r--r--drivers/net/ethernet/ti/tlan.h (renamed from drivers/net/tlan.h)202
-rw-r--r--drivers/net/ethernet/tile/Kconfig18
-rw-r--r--drivers/net/ethernet/tile/Makefile10
-rw-r--r--drivers/net/ethernet/tile/tilegx.c2281
-rw-r--r--drivers/net/ethernet/tile/tilepro.c2425
-rw-r--r--drivers/net/ethernet/toshiba/Kconfig57
-rw-r--r--drivers/net/ethernet/toshiba/Makefile10
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_net.c (renamed from drivers/net/ps3_gelic_net.c)497
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_net.h (renamed from drivers/net/ps3_gelic_net.h)61
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_wireless.c (renamed from drivers/net/ps3_gelic_wireless.c)324
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_wireless.h (renamed from drivers/net/ps3_gelic_wireless.h)22
-rw-r--r--drivers/net/ethernet/toshiba/spider_net.c (renamed from drivers/net/spider_net.c)122
-rw-r--r--drivers/net/ethernet/toshiba/spider_net.h (renamed from drivers/net/spider_net.h)13
-rw-r--r--drivers/net/ethernet/toshiba/spider_net_ethtool.c (renamed from drivers/net/spider_net_ethtool.c)39
-rw-r--r--drivers/net/ethernet/toshiba/tc35815.c (renamed from drivers/net/tc35815.c)642
-rw-r--r--drivers/net/ethernet/tundra/Kconfig29
-rw-r--r--drivers/net/ethernet/tundra/Makefile5
-rw-r--r--drivers/net/ethernet/tundra/tsi108_eth.c (renamed from drivers/net/tsi108_eth.c)157
-rw-r--r--drivers/net/ethernet/tundra/tsi108_eth.h (renamed from drivers/net/tsi108_eth.h)12
-rw-r--r--drivers/net/ethernet/via/Kconfig56
-rw-r--r--drivers/net/ethernet/via/Makefile6
-rw-r--r--drivers/net/ethernet/via/via-rhine.c (renamed from drivers/net/via-rhine.c)1784
-rw-r--r--drivers/net/ethernet/via/via-velocity.c (renamed from drivers/net/via-velocity.c)4131
-rw-r--r--drivers/net/ethernet/via/via-velocity.h (renamed from drivers/net/via-velocity.h)149
-rw-r--r--drivers/net/ethernet/wiznet/Kconfig74
-rw-r--r--drivers/net/ethernet/wiznet/Makefile2
-rw-r--r--drivers/net/ethernet/wiznet/w5100.c801
-rw-r--r--drivers/net/ethernet/wiznet/w5300.c713
-rw-r--r--drivers/net/ethernet/xilinx/Kconfig44
-rw-r--r--drivers/net/ethernet/xilinx/Makefile9
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac.h385
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_main.c1184
-rw-r--r--drivers/net/ethernet/xilinx/ll_temac_mdio.c122
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet.h506
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_main.c1659
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c239
-rw-r--r--drivers/net/ethernet/xilinx/xilinx_emaclite.c1259
-rw-r--r--drivers/net/ethernet/xircom/Kconfig31
-rw-r--r--drivers/net/ethernet/xircom/Makefile5
-rw-r--r--drivers/net/ethernet/xircom/xirc2ps_cs.c (renamed from drivers/net/pcmcia/xirc2ps_cs.c)813
-rw-r--r--drivers/net/ethernet/xscale/Kconfig31
-rw-r--r--drivers/net/ethernet/xscale/Makefile5
-rw-r--r--drivers/net/ethernet/xscale/ixp4xx_eth.c (renamed from drivers/net/arm/ixp4xx_eth.c)687
-rw-r--r--drivers/net/ewrk3.c1983
-rw-r--r--drivers/net/ewrk3.h322
-rw-r--r--drivers/net/fddi/Kconfig77
-rw-r--r--drivers/net/fddi/Makefile6
-rw-r--r--drivers/net/fddi/defxx.c (renamed from drivers/net/defxx.c)240
-rw-r--r--drivers/net/fddi/defxx.h (renamed from drivers/net/defxx.h)0
-rw-r--r--drivers/net/fddi/skfp/Makefile (renamed from drivers/net/skfp/Makefile)2
-rw-r--r--drivers/net/fddi/skfp/cfm.c (renamed from drivers/net/skfp/cfm.c)10
-rw-r--r--drivers/net/fddi/skfp/drvfbi.c (renamed from drivers/net/skfp/drvfbi.c)16
-rw-r--r--drivers/net/fddi/skfp/ecm.c (renamed from drivers/net/skfp/ecm.c)0
-rw-r--r--drivers/net/fddi/skfp/ess.c (renamed from drivers/net/skfp/ess.c)56
-rw-r--r--drivers/net/fddi/skfp/fplustm.c (renamed from drivers/net/skfp/fplustm.c)61
-rw-r--r--drivers/net/fddi/skfp/h/cmtdef.h (renamed from drivers/net/skfp/h/cmtdef.h)8
-rw-r--r--drivers/net/fddi/skfp/h/fddi.h (renamed from drivers/net/skfp/h/fddi.h)0
-rw-r--r--drivers/net/fddi/skfp/h/fddimib.h (renamed from drivers/net/skfp/h/fddimib.h)0
-rw-r--r--drivers/net/fddi/skfp/h/fplustm.h (renamed from drivers/net/skfp/h/fplustm.h)4
-rw-r--r--drivers/net/fddi/skfp/h/hwmtm.h (renamed from drivers/net/skfp/h/hwmtm.h)4
-rw-r--r--drivers/net/fddi/skfp/h/mbuf.h (renamed from drivers/net/skfp/h/mbuf.h)0
-rw-r--r--drivers/net/fddi/skfp/h/osdef1st.h (renamed from drivers/net/skfp/h/osdef1st.h)0
-rw-r--r--drivers/net/fddi/skfp/h/sba.h (renamed from drivers/net/skfp/h/sba.h)4
-rw-r--r--drivers/net/fddi/skfp/h/sba_def.h (renamed from drivers/net/skfp/h/sba_def.h)0
-rw-r--r--drivers/net/fddi/skfp/h/skfbi.h (renamed from drivers/net/skfp/h/skfbi.h)0
-rw-r--r--drivers/net/fddi/skfp/h/skfbiinc.h (renamed from drivers/net/skfp/h/skfbiinc.h)2
-rw-r--r--drivers/net/fddi/skfp/h/smc.h (renamed from drivers/net/skfp/h/smc.h)41
-rw-r--r--drivers/net/fddi/skfp/h/smt.h (renamed from drivers/net/skfp/h/smt.h)4
-rw-r--r--drivers/net/fddi/skfp/h/smt_p.h (renamed from drivers/net/skfp/h/smt_p.h)0
-rw-r--r--drivers/net/fddi/skfp/h/smtstate.h (renamed from drivers/net/skfp/h/smtstate.h)0
-rw-r--r--drivers/net/fddi/skfp/h/supern_2.h (renamed from drivers/net/skfp/h/supern_2.h)100
-rw-r--r--drivers/net/fddi/skfp/h/targethw.h (renamed from drivers/net/skfp/h/targethw.h)6
-rw-r--r--drivers/net/fddi/skfp/h/targetos.h (renamed from drivers/net/skfp/h/targetos.h)3
-rw-r--r--drivers/net/fddi/skfp/h/types.h (renamed from drivers/net/skfp/h/types.h)0
-rw-r--r--drivers/net/fddi/skfp/hwmtm.c (renamed from drivers/net/skfp/hwmtm.c)41
-rw-r--r--drivers/net/fddi/skfp/hwt.c (renamed from drivers/net/skfp/hwt.c)6
-rw-r--r--drivers/net/fddi/skfp/pcmplc.c (renamed from drivers/net/skfp/pcmplc.c)37
-rw-r--r--drivers/net/fddi/skfp/pmf.c (renamed from drivers/net/skfp/pmf.c)109
-rw-r--r--drivers/net/fddi/skfp/queue.c (renamed from drivers/net/skfp/queue.c)2
-rw-r--r--drivers/net/fddi/skfp/rmt.c (renamed from drivers/net/skfp/rmt.c)0
-rw-r--r--drivers/net/fddi/skfp/skfddi.c (renamed from drivers/net/skfp/skfddi.c)303
-rw-r--r--drivers/net/fddi/skfp/smt.c (renamed from drivers/net/skfp/smt.c)98
-rw-r--r--drivers/net/fddi/skfp/smtdef.c (renamed from drivers/net/skfp/smtdef.c)4
-rw-r--r--drivers/net/fddi/skfp/smtinit.c (renamed from drivers/net/skfp/smtinit.c)2
-rw-r--r--drivers/net/fddi/skfp/smttimer.c (renamed from drivers/net/skfp/smttimer.c)0
-rw-r--r--drivers/net/fddi/skfp/srf.c (renamed from drivers/net/skfp/srf.c)28
-rw-r--r--drivers/net/fec.c2592
-rw-r--r--drivers/net/fec.h165
-rw-r--r--drivers/net/gianfar.c2135
-rw-r--r--drivers/net/gianfar_ethtool.c625
-rw-r--r--drivers/net/gianfar_mii.c279
-rw-r--r--drivers/net/gianfar_mii.h49
-rw-r--r--drivers/net/gianfar_sysfs.c312
-rw-r--r--drivers/net/hamradio/6pack.c66
-rw-r--r--drivers/net/hamradio/Kconfig6
-rw-r--r--drivers/net/hamradio/Makefile2
-rw-r--r--drivers/net/hamradio/baycom_epp.c65
-rw-r--r--drivers/net/hamradio/baycom_par.c5
-rw-r--r--drivers/net/hamradio/baycom_ser_fdx.c14
-rw-r--r--drivers/net/hamradio/baycom_ser_hdx.c6
-rw-r--r--drivers/net/hamradio/bpqether.c125
-rw-r--r--drivers/net/hamradio/dmascc.c87
-rw-r--r--drivers/net/hamradio/hdlcdrv.c65
-rw-r--r--drivers/net/hamradio/mkiss.c113
-rw-r--r--drivers/net/hamradio/scc.c66
-rw-r--r--drivers/net/hamradio/yam.c163
-rw-r--r--drivers/net/hamradio/yam1200.h343
-rw-r--r--drivers/net/hamradio/yam9600.h343
-rw-r--r--drivers/net/hippi/Kconfig39
-rw-r--r--drivers/net/hippi/Makefile5
-rw-r--r--drivers/net/hippi/rrunner.c (renamed from drivers/net/rrunner.c)163
-rw-r--r--drivers/net/hippi/rrunner.h (renamed from drivers/net/rrunner.h)3
-rw-r--r--drivers/net/hp-plus.c499
-rw-r--r--drivers/net/hp.c462
-rw-r--r--drivers/net/hyperv/Kconfig5
-rw-r--r--drivers/net/hyperv/Makefile3
-rw-r--r--drivers/net/hyperv/hyperv_net.h1181
-rw-r--r--drivers/net/hyperv/netvsc.c1104
-rw-r--r--drivers/net/hyperv/netvsc_drv.c923
-rw-r--r--drivers/net/hyperv/rndis_filter.c1185
-rw-r--r--drivers/net/ibm_newemac/Makefile11
-rw-r--r--drivers/net/ibmlana.c1070
-rw-r--r--drivers/net/ibmlana.h278
-rw-r--r--drivers/net/ibmveth.c1620
-rw-r--r--drivers/net/ieee802154/Kconfig53
-rw-r--r--drivers/net/ieee802154/Makefile4
-rw-r--r--drivers/net/ieee802154/at86rf230.c1240
-rw-r--r--drivers/net/ieee802154/fakehard.c426
-rw-r--r--drivers/net/ieee802154/fakelb.c294
-rw-r--r--drivers/net/ieee802154/mrf24j40.c739
-rw-r--r--drivers/net/ifb.c157
-rw-r--r--drivers/net/igb/e1000_82575.c1454
-rw-r--r--drivers/net/igb/e1000_82575.h173
-rw-r--r--drivers/net/igb/e1000_mac.h96
-rw-r--r--drivers/net/igb/e1000_nvm.h40
-rw-r--r--drivers/net/igb/e1000_phy.h98
-rw-r--r--drivers/net/igb/igb.h331
-rw-r--r--drivers/net/igb/igb_ethtool.c2033
-rw-r--r--drivers/net/igb/igb_main.c4516
-rw-r--r--drivers/net/irda/Kconfig121
-rw-r--r--drivers/net/irda/Makefile4
-rw-r--r--drivers/net/irda/act200l-sir.c2
-rw-r--r--drivers/net/irda/ali-ircc.c172
-rw-r--r--drivers/net/irda/ali-ircc.h1
-rw-r--r--drivers/net/irda/au1000_ircc.h126
-rw-r--r--drivers/net/irda/au1k_ir.c1228
-rw-r--r--drivers/net/irda/bfin_sir.c818
-rw-r--r--drivers/net/irda/bfin_sir.h96
-rw-r--r--drivers/net/irda/donauboe.c78
-rw-r--r--drivers/net/irda/donauboe.h9
-rw-r--r--drivers/net/irda/ep7211-sir.c89
-rw-r--r--drivers/net/irda/esi-sir.c4
-rw-r--r--drivers/net/irda/girbil-sir.c2
-rw-r--r--drivers/net/irda/irda-usb.c173
-rw-r--r--drivers/net/irda/irda-usb.h3
-rw-r--r--drivers/net/irda/irtty-sir.c36
-rw-r--r--drivers/net/irda/kingsun-sir.c106
-rw-r--r--drivers/net/irda/ks959-sir.c103
-rw-r--r--drivers/net/irda/ksdazzle-sir.c121
-rw-r--r--drivers/net/irda/litelink-sir.c4
-rw-r--r--drivers/net/irda/ma600-sir.c6
-rw-r--r--drivers/net/irda/mcs7780.c157
-rw-r--r--drivers/net/irda/mcs7780.h5
-rw-r--r--drivers/net/irda/nsc-ircc.c126
-rw-r--r--drivers/net/irda/nsc-ircc.h3
-rw-r--r--drivers/net/irda/old_belkin-sir.c4
-rw-r--r--drivers/net/irda/pxaficp_ir.c251
-rw-r--r--drivers/net/irda/sa1100_ir.c1016
-rw-r--r--drivers/net/irda/sh_irda.c875
-rw-r--r--drivers/net/irda/sh_sir.c811
-rw-r--r--drivers/net/irda/sir-dev.h30
-rw-r--r--drivers/net/irda/sir_dev.c73
-rw-r--r--drivers/net/irda/sir_dongle.c3
-rw-r--r--drivers/net/irda/smsc-ircc2.c172
-rw-r--r--drivers/net/irda/smsc-ircc2.h4
-rw-r--r--drivers/net/irda/stir4200.c120
-rw-r--r--drivers/net/irda/toim3232-sir.c3
-rw-r--r--drivers/net/irda/via-ircc.c264
-rw-r--r--drivers/net/irda/via-ircc.h10
-rw-r--r--drivers/net/irda/vlsi_ir.c188
-rw-r--r--drivers/net/irda/vlsi_ir.h17
-rw-r--r--drivers/net/irda/w83977af_ir.c174
-rw-r--r--drivers/net/irda/w83977af_ir.h1
-rw-r--r--drivers/net/isa-skeleton.c725
-rw-r--r--drivers/net/iseries_veth.c1723
-rw-r--r--drivers/net/ixgbe/ixgbe.h327
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c527
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c1179
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h86
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c980
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c3871
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c494
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.h49
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h1334
-rw-r--r--drivers/net/ixp2000/Kconfig6
-rw-r--r--drivers/net/ixp2000/Makefile3
-rw-r--r--drivers/net/ixp2000/caleb.c136
-rw-r--r--drivers/net/ixp2000/caleb.h22
-rw-r--r--drivers/net/ixp2000/enp2611.c248
-rw-r--r--drivers/net/ixp2000/ixp2400-msf.c212
-rw-r--r--drivers/net/ixp2000/ixp2400-msf.h115
-rw-r--r--drivers/net/ixp2000/ixp2400_rx.uc408
-rw-r--r--drivers/net/ixp2000/ixp2400_rx.ucode130
-rw-r--r--drivers/net/ixp2000/ixp2400_tx.uc272
-rw-r--r--drivers/net/ixp2000/ixp2400_tx.ucode98
-rw-r--r--drivers/net/ixp2000/ixpdev.c424
-rw-r--r--drivers/net/ixp2000/ixpdev.h29
-rw-r--r--drivers/net/ixp2000/ixpdev_priv.h57
-rw-r--r--drivers/net/ixp2000/pm3386.c351
-rw-r--r--drivers/net/ixp2000/pm3386.h29
-rw-r--r--drivers/net/lne390.c458
-rw-r--r--drivers/net/loopback.c146
-rw-r--r--drivers/net/lp486e.c1333
-rw-r--r--drivers/net/mac8390.c860
-rw-r--r--drivers/net/macb.c1343
-rw-r--r--drivers/net/macvlan.c1023
-rw-r--r--drivers/net/macvtap.c1252
-rw-r--r--drivers/net/mdio.c423
-rw-r--r--drivers/net/mii.c138
-rw-r--r--drivers/net/mipsnet.c335
-rw-r--r--drivers/net/mlx4/Makefile4
-rw-r--r--drivers/net/mlx4/cmd.c439
-rw-r--r--drivers/net/mlx4/eq.c660
-rw-r--r--drivers/net/mlx4/fw.c874
-rw-r--r--drivers/net/mlx4/main.c982
-rw-r--r--drivers/net/mlx4/mcg.c384
-rw-r--r--drivers/net/mlx4/mlx4.h349
-rw-r--r--drivers/net/mlx4/mr.c660
-rw-r--r--drivers/net/mlx4/pd.c109
-rw-r--r--drivers/net/mlx4/qp.c332
-rw-r--r--drivers/net/mv643xx_eth.c2697
-rw-r--r--drivers/net/myri_code.h5006
-rw-r--r--drivers/net/myri_sbus.c1172
-rw-r--r--drivers/net/myri_sbus.h311
-rw-r--r--drivers/net/ne-h8300.c673
-rw-r--r--drivers/net/ne2.c824
-rw-r--r--drivers/net/ne3210.c371
-rw-r--r--drivers/net/netconsole.c262
-rw-r--r--drivers/net/netxen/netxen_nic.h1625
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c713
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c909
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c2226
-rw-r--r--drivers/net/netxen/netxen_nic_init.c1577
-rw-r--r--drivers/net/netxen/netxen_nic_main.c1617
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c934
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h175
-rw-r--r--drivers/net/ni5010.c779
-rw-r--r--drivers/net/ni5010.h144
-rw-r--r--drivers/net/ni52.c1352
-rw-r--r--drivers/net/ni52.h310
-rw-r--r--drivers/net/nlmon.c181
-rw-r--r--drivers/net/ntb_netdev.c422
-rw-r--r--drivers/net/pci-skeleton.c1939
-rw-r--r--drivers/net/pcmcia/3c589_cs.c994
-rw-r--r--drivers/net/pcmcia/Kconfig123
-rw-r--r--drivers/net/pcmcia/Makefile16
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c439
-rw-r--r--drivers/net/pcmcia/ositech.h358
-rw-r--r--drivers/net/phy/Kconfig129
-rw-r--r--drivers/net/phy/Makefile20
-rw-r--r--drivers/net/phy/amd-xgbe-phy.c1357
-rw-r--r--drivers/net/phy/amd.c96
-rw-r--r--drivers/net/phy/at803x.c376
-rw-r--r--drivers/net/phy/bcm63xx.c124
-rw-r--r--drivers/net/phy/bcm7xxx.c359
-rw-r--r--drivers/net/phy/bcm87xx.c233
-rw-r--r--drivers/net/phy/broadcom.c634
-rw-r--r--drivers/net/phy/cicada.c52
-rw-r--r--drivers/net/phy/davicom.c66
-rw-r--r--drivers/net/phy/dp83640.c1441
-rw-r--r--drivers/net/phy/dp83640_reg.h267
-rw-r--r--drivers/net/phy/et1011c.c119
-rw-r--r--drivers/net/phy/fixed.c124
-rw-r--r--drivers/net/phy/icplus.c180
-rw-r--r--drivers/net/phy/lxt.c215
-rw-r--r--drivers/net/phy/marvell.c692
-rw-r--r--drivers/net/phy/mdio-bitbang.c74
-rw-r--r--drivers/net/phy/mdio-gpio.c272
-rw-r--r--drivers/net/phy/mdio-moxart.c200
-rw-r--r--drivers/net/phy/mdio-mux-gpio.c140
-rw-r--r--drivers/net/phy/mdio-mux-mmioreg.c170
-rw-r--r--drivers/net/phy/mdio-mux.c198
-rw-r--r--drivers/net/phy/mdio-octeon.c284
-rw-r--r--drivers/net/phy/mdio-ofgpio.c205
-rw-r--r--drivers/net/phy/mdio-sun4i.c188
-rw-r--r--drivers/net/phy/mdio_bus.c562
-rw-r--r--drivers/net/phy/micrel.c645
-rw-r--r--drivers/net/phy/national.c168
-rw-r--r--drivers/net/phy/phy.c908
-rw-r--r--drivers/net/phy/phy_device.c1005
-rw-r--r--drivers/net/phy/qsemi.c8
-rw-r--r--drivers/net/phy/realtek.c81
-rw-r--r--drivers/net/phy/smsc.c200
-rw-r--r--drivers/net/phy/spi_ks8995.c387
-rw-r--r--drivers/net/phy/ste10Xp.c140
-rw-r--r--drivers/net/phy/vitesse.c266
-rw-r--r--drivers/net/plip/Kconfig38
-rw-r--r--drivers/net/plip/Makefile5
-rw-r--r--drivers/net/plip/plip.c (renamed from drivers/net/plip.c)103
-rw-r--r--drivers/net/ppp/Kconfig178
-rw-r--r--drivers/net/ppp/Makefile13
-rw-r--r--drivers/net/ppp/bsd_comp.c (renamed from drivers/net/bsd_comp.c)4
-rw-r--r--drivers/net/ppp/ppp_async.c (renamed from drivers/net/ppp_async.c)64
-rw-r--r--drivers/net/ppp/ppp_deflate.c (renamed from drivers/net/ppp_deflate.c)90
-rw-r--r--drivers/net/ppp/ppp_generic.c (renamed from drivers/net/ppp_generic.c)1200
-rw-r--r--drivers/net/ppp/ppp_mppe.c (renamed from drivers/net/ppp_mppe.c)18
-rw-r--r--drivers/net/ppp/ppp_mppe.h (renamed from drivers/net/ppp_mppe.h)0
-rw-r--r--drivers/net/ppp/ppp_synctty.c (renamed from drivers/net/ppp_synctty.c)95
-rw-r--r--drivers/net/ppp/pppoe.c (renamed from drivers/net/pppoe.c)603
-rw-r--r--drivers/net/ppp/pppox.c (renamed from drivers/net/pppox.c)24
-rw-r--r--drivers/net/ppp/pptp.c719
-rw-r--r--drivers/net/pppol2tp.c2588
-rw-r--r--drivers/net/r8169.c3148
-rw-r--r--drivers/net/rionet.c339
-rw-r--r--drivers/net/sb1000.c40
-rw-r--r--drivers/net/seeq8005.c757
-rw-r--r--drivers/net/seeq8005.h156
-rw-r--r--drivers/net/sfc/Kconfig14
-rw-r--r--drivers/net/sfc/Makefile5
-rw-r--r--drivers/net/sfc/boards.c164
-rw-r--r--drivers/net/sfc/boards.h27
-rw-r--r--drivers/net/sfc/efx.c2239
-rw-r--r--drivers/net/sfc/efx.h67
-rw-r--r--drivers/net/sfc/enum.h99
-rw-r--r--drivers/net/sfc/ethtool.c717
-rw-r--r--drivers/net/sfc/ethtool.h27
-rw-r--r--drivers/net/sfc/falcon.c2741
-rw-r--r--drivers/net/sfc/falcon.h133
-rw-r--r--drivers/net/sfc/falcon_hwdefs.h1149
-rw-r--r--drivers/net/sfc/falcon_io.h256
-rw-r--r--drivers/net/sfc/falcon_xmac.c655
-rw-r--r--drivers/net/sfc/gmii.h195
-rw-r--r--drivers/net/sfc/mac.h33
-rw-r--r--drivers/net/sfc/mdio_10g.c360
-rw-r--r--drivers/net/sfc/mdio_10g.h254
-rw-r--r--drivers/net/sfc/net_driver.h917
-rw-r--r--drivers/net/sfc/rx.c890
-rw-r--r--drivers/net/sfc/rx.h29
-rw-r--r--drivers/net/sfc/selftest.c719
-rw-r--r--drivers/net/sfc/sfe4001.c272
-rw-r--r--drivers/net/sfc/spi.h71
-rw-r--r--drivers/net/sfc/tenxpress.c519
-rw-r--r--drivers/net/sfc/tx.c1120
-rw-r--r--drivers/net/sfc/tx.h24
-rw-r--r--drivers/net/sfc/workarounds.h56
-rw-r--r--drivers/net/sfc/xenpack.h62
-rw-r--r--drivers/net/sfc/xfp_phy.c170
-rw-r--r--drivers/net/sh_eth.c1329
-rw-r--r--drivers/net/sh_eth.h680
-rw-r--r--drivers/net/slip/Kconfig80
-rw-r--r--drivers/net/slip/Makefile6
-rw-r--r--drivers/net/slip/slhc.c (renamed from drivers/net/slhc.c)20
-rw-r--r--drivers/net/slip/slip.c (renamed from drivers/net/slip.c)354
-rw-r--r--drivers/net/slip/slip.h (renamed from drivers/net/slip.h)20
-rw-r--r--drivers/net/smc-mca.c564
-rw-r--r--drivers/net/smc-ultra32.c453
-rw-r--r--drivers/net/starfire_firmware.h346
-rw-r--r--drivers/net/starfire_firmware.pl31
-rw-r--r--drivers/net/sungem_phy.c22
-rw-r--r--drivers/net/sungem_phy.h132
-rw-r--r--drivers/net/team/Kconfig76
-rw-r--r--drivers/net/team/Makefile10
-rw-r--r--drivers/net/team/team.c2918
-rw-r--r--drivers/net/team/team_mode_activebackup.c148
-rw-r--r--drivers/net/team/team_mode_broadcast.c77
-rw-r--r--drivers/net/team/team_mode_loadbalance.c678
-rw-r--r--drivers/net/team/team_mode_random.c67
-rw-r--r--drivers/net/team/team_mode_roundrobin.c79
-rw-r--r--drivers/net/tehuti_fw.h10712
-rw-r--r--drivers/net/tg3.c13761
-rw-r--r--drivers/net/tlan.c3366
-rw-r--r--drivers/net/tokenring/3c359.c1810
-rw-r--r--drivers/net/tokenring/3c359.h288
-rw-r--r--drivers/net/tokenring/3c359_microcode.h1581
-rw-r--r--drivers/net/tokenring/Kconfig185
-rw-r--r--drivers/net/tokenring/Makefile15
-rw-r--r--drivers/net/tokenring/abyss.c465
-rw-r--r--drivers/net/tokenring/abyss.h58
-rw-r--r--drivers/net/tokenring/ibmtr.c1973
-rw-r--r--drivers/net/tokenring/lanstreamer.c1936
-rw-r--r--drivers/net/tokenring/lanstreamer.h344
-rw-r--r--drivers/net/tokenring/madgemc.c777
-rw-r--r--drivers/net/tokenring/madgemc.h70
-rw-r--r--drivers/net/tokenring/olympic.c1775
-rw-r--r--drivers/net/tokenring/olympic.h322
-rw-r--r--drivers/net/tokenring/proteon.c419
-rw-r--r--drivers/net/tokenring/skisa.c429
-rw-r--r--drivers/net/tokenring/smctr.c5744
-rw-r--r--drivers/net/tokenring/smctr.h1586
-rw-r--r--drivers/net/tokenring/tms380tr.c2393
-rw-r--r--drivers/net/tokenring/tms380tr.h1140
-rw-r--r--drivers/net/tokenring/tmspci.c252
-rw-r--r--drivers/net/tun.c2002
-rw-r--r--drivers/net/typhoon-firmware.h3778
-rw-r--r--drivers/net/ucc_geth_mii.c286
-rw-r--r--drivers/net/ucc_geth_mii.h100
-rw-r--r--drivers/net/usb/Kconfig258
-rw-r--r--drivers/net/usb/Makefile22
-rw-r--r--drivers/net/usb/asix.c1477
-rw-r--r--drivers/net/usb/asix.h234
-rw-r--r--drivers/net/usb/asix_common.c582
-rw-r--r--drivers/net/usb/asix_devices.c1116
-rw-r--r--drivers/net/usb/ax88172a.c422
-rw-r--r--drivers/net/usb/ax88179_178a.c1487
-rw-r--r--drivers/net/usb/catc.c229
-rw-r--r--drivers/net/usb/cdc-phonet.c466
-rw-r--r--drivers/net/usb/cdc_eem.c381
-rw-r--r--drivers/net/usb/cdc_ether.c419
-rw-r--r--drivers/net/usb/cdc_mbim.c625
-rw-r--r--drivers/net/usb/cdc_ncm.c1616
-rw-r--r--drivers/net/usb/cdc_subset.c32
-rw-r--r--drivers/net/usb/cx82310_eth.c326
-rw-r--r--drivers/net/usb/dm9601.c373
-rw-r--r--drivers/net/usb/gl620a.c34
-rw-r--r--drivers/net/usb/hso.c1167
-rw-r--r--drivers/net/usb/huawei_cdc_ncm.c221
-rw-r--r--drivers/net/usb/int51x1.c199
-rw-r--r--drivers/net/usb/ipheth.c588
-rw-r--r--drivers/net/usb/kalmia.c366
-rw-r--r--drivers/net/usb/kaweth.c374
-rw-r--r--drivers/net/usb/lg-vl600.c353
-rw-r--r--drivers/net/usb/mcs7830.c395
-rw-r--r--drivers/net/usb/net1080.c306
-rw-r--r--drivers/net/usb/pegasus.c810
-rw-r--r--drivers/net/usb/pegasus.h307
-rw-r--r--drivers/net/usb/plusb.c60
-rw-r--r--drivers/net/usb/qmi_wwan.c878
-rw-r--r--drivers/net/usb/r8152.c3539
-rw-r--r--drivers/net/usb/rndis_host.c252
-rw-r--r--drivers/net/usb/rtl8150.c409
-rw-r--r--drivers/net/usb/sierra_net.c969
-rw-r--r--drivers/net/usb/smsc75xx.c2286
-rw-r--r--drivers/net/usb/smsc75xx.h421
-rw-r--r--drivers/net/usb/smsc95xx.c2030
-rw-r--r--drivers/net/usb/smsc95xx.h290
-rw-r--r--drivers/net/usb/sr9700.c559
-rw-r--r--drivers/net/usb/sr9700.h173
-rw-r--r--drivers/net/usb/sr9800.c874
-rw-r--r--drivers/net/usb/sr9800.h202
-rw-r--r--drivers/net/usb/usbnet.c1371
-rw-r--r--drivers/net/usb/zaurus.c57
-rw-r--r--drivers/net/veth.c432
-rw-r--r--drivers/net/virtio_net.c1963
-rw-r--r--drivers/net/vmxnet3/Makefile35
-rw-r--r--drivers/net/vmxnet3/upt1_defs.h96
-rw-r--r--drivers/net/vmxnet3/vmxnet3_defs.h629
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c3376
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c643
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h423
-rw-r--r--drivers/net/vxlan.c2984
-rw-r--r--drivers/net/wan/Kconfig100
-rw-r--r--drivers/net/wan/Makefile17
-rw-r--r--drivers/net/wan/c101.c53
-rw-r--r--drivers/net/wan/cosa.c312
-rw-r--r--drivers/net/wan/cycx_drv.c576
-rw-r--r--drivers/net/wan/cycx_main.c348
-rw-r--r--drivers/net/wan/cycx_x25.c1613
-rw-r--r--drivers/net/wan/dlci.c227
-rw-r--r--drivers/net/wan/dscc4.c177
-rw-r--r--drivers/net/wan/farsync.c356
-rw-r--r--drivers/net/wan/hd64570.c (renamed from drivers/net/wan/hd6457x.c)269
-rw-r--r--drivers/net/wan/hd64570.h6
-rw-r--r--drivers/net/wan/hd64572.c639
-rw-r--r--drivers/net/wan/hd64572.h2
-rw-r--r--drivers/net/wan/hdlc.c62
-rw-r--r--drivers/net/wan/hdlc_cisco.c73
-rw-r--r--drivers/net/wan/hdlc_fr.c185
-rw-r--r--drivers/net/wan/hdlc_ppp.c653
-rw-r--r--drivers/net/wan/hdlc_raw.c6
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c14
-rw-r--r--drivers/net/wan/hdlc_x25.c62
-rw-r--r--drivers/net/wan/hostess_sv11.c32
-rw-r--r--drivers/net/wan/ixp4xx_hss.c1419
-rw-r--r--drivers/net/wan/lapbether.c104
-rw-r--r--drivers/net/wan/lmc/Makefile2
-rw-r--r--drivers/net/wan/lmc/lmc_main.c117
-rw-r--r--drivers/net/wan/lmc/lmc_media.c1
-rw-r--r--drivers/net/wan/lmc/lmc_proto.c19
-rw-r--r--drivers/net/wan/lmc/lmc_var.h6
-rw-r--r--drivers/net/wan/n2.c74
-rw-r--r--drivers/net/wan/pc300-falc-lh.h1238
-rw-r--r--drivers/net/wan/pc300.h436
-rw-r--r--drivers/net/wan/pc300_drv.c3677
-rw-r--r--drivers/net/wan/pc300_tty.c1098
-rw-r--r--drivers/net/wan/pc300too.c169
-rw-r--r--drivers/net/wan/pci200syn.c136
-rw-r--r--drivers/net/wan/sbni.c392
-rw-r--r--drivers/net/wan/sdla.c271
-rw-r--r--drivers/net/wan/sealevel.c43
-rw-r--r--drivers/net/wan/syncppp.c1479
-rw-r--r--drivers/net/wan/wanxl.c138
-rw-r--r--drivers/net/wan/wanxlfw.S1
-rw-r--r--drivers/net/wan/x25_asy.c216
-rw-r--r--drivers/net/wan/x25_asy.h6
-rw-r--r--drivers/net/wan/z85230.c75
-rw-r--r--drivers/net/wan/z85230.h28
-rw-r--r--drivers/net/wimax/Kconfig17
-rw-r--r--drivers/net/wimax/Makefile5
-rw-r--r--drivers/net/wimax/i2400m/Kconfig36
-rw-r--r--drivers/net/wimax/i2400m/Makefile22
-rw-r--r--drivers/net/wimax/i2400m/control.c1436
-rw-r--r--drivers/net/wimax/i2400m/debug-levels.h46
-rw-r--r--drivers/net/wimax/i2400m/debugfs.c371
-rw-r--r--drivers/net/wimax/i2400m/driver.c1025
-rw-r--r--drivers/net/wimax/i2400m/fw.c1657
-rw-r--r--drivers/net/wimax/i2400m/i2400m-usb.h275
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h973
-rw-r--r--drivers/net/wimax/i2400m/netdev.c638
-rw-r--r--drivers/net/wimax/i2400m/op-rfkill.c210
-rw-r--r--drivers/net/wimax/i2400m/rx.c1396
-rw-r--r--drivers/net/wimax/i2400m/sysfs.c80
-rw-r--r--drivers/net/wimax/i2400m/tx.c1013
-rw-r--r--drivers/net/wimax/i2400m/usb-debug-levels.h42
-rw-r--r--drivers/net/wimax/i2400m/usb-fw.c364
-rw-r--r--drivers/net/wimax/i2400m/usb-notif.c259
-rw-r--r--drivers/net/wimax/i2400m/usb-rx.c465
-rw-r--r--drivers/net/wimax/i2400m/usb-tx.c273
-rw-r--r--drivers/net/wimax/i2400m/usb.c817
-rw-r--r--drivers/net/wireless/Kconfig614
-rw-r--r--drivers/net/wireless/Makefile51
-rw-r--r--drivers/net/wireless/adm8211.c274
-rw-r--r--drivers/net/wireless/adm8211.h10
-rw-r--r--drivers/net/wireless/airo.c1917
-rw-r--r--drivers/net/wireless/airo_cs.c359
-rw-r--r--drivers/net/wireless/arlan-main.c1891
-rw-r--r--drivers/net/wireless/arlan-proc.c1253
-rw-r--r--drivers/net/wireless/arlan.h539
-rw-r--r--drivers/net/wireless/at76c50x-usb.c2617
-rw-r--r--drivers/net/wireless/at76c50x-usb.h466
-rw-r--r--drivers/net/wireless/ath/Kconfig54
-rw-r--r--drivers/net/wireless/ath/Makefile20
-rw-r--r--drivers/net/wireless/ath/ar5523/Kconfig8
-rw-r--r--drivers/net/wireless/ath/ar5523/Makefile1
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c1799
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.h152
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523_hw.h431
-rw-r--r--drivers/net/wireless/ath/ath.h307
-rw-r--r--drivers/net/wireless/ath/ath10k/Kconfig46
-rw-r--r--drivers/net/wireless/ath/ath10k/Makefile20
-rw-r--r--drivers/net/wireless/ath/ath10k/bmi.c318
-rw-r--r--drivers/net/wireless/ath/ath10k/bmi.h226
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c1213
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.h442
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c1098
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h506
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c934
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h113
-rw-r--r--drivers/net/wireless/ath/ath10k/hif.h181
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c866
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.h363
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.c112
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h1353
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c1554
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c541
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h364
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c4826
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.h64
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c2817
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h319
-rw-r--r--drivers/net/wireless/ath/ath10k/rx_desc.h1010
-rw-r--r--drivers/net/wireless/ath/ath10k/targaddrs.h449
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.c20
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h215
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c221
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.h37
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c3659
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h4322
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig75
-rw-r--r--drivers/net/wireless/ath/ath5k/Makefile22
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c234
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.c754
-rw-r--r--drivers/net/wireless/ath/ath5k/ani.h119
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h1715
-rw-r--r--drivers/net/wireless/ath/ath5k/attach.c360
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c3155
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h121
-rw-r--r--drivers/net/wireless/ath/ath5k/caps.c154
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.c1041
-rw-r--r--drivers/net/wireless/ath/ath5k/debug.h (renamed from drivers/net/wireless/ath5k/debug.h)73
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.c786
-rw-r--r--drivers/net/wireless/ath/ath5k/desc.h367
-rw-r--r--drivers/net/wireless/ath/ath5k/dma.c928
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c1796
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h495
-rw-r--r--drivers/net/wireless/ath/ath5k/gpio.c213
-rw-r--r--drivers/net/wireless/ath/ath5k/initvals.c1605
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c202
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c830
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c343
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c1009
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c3965
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c737
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h (renamed from drivers/net/wireless/ath5k/reg.h)1051
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c1404
-rw-r--r--drivers/net/wireless/ath/ath5k/rfbuffer.h853
-rw-r--r--drivers/net/wireless/ath/ath5k/rfgain.h534
-rw-r--r--drivers/net/wireless/ath/ath5k/rfkill.c116
-rw-r--r--drivers/net/wireless/ath/ath5k/sysfs.c122
-rw-r--r--drivers/net/wireless/ath/ath5k/trace.h106
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig65
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile49
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c548
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.h270
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c3875
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h65
-rw-r--r--drivers/net/wireless/ath/ath6kl/common.h85
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.c346
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h964
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c1875
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h144
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h187
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c702
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h282
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc-ops.h113
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.h677
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_mbox.c2935
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_pipe.c1711
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c1866
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c1307
-rw-r--r--drivers/net/wireless/ath/ath6kl/recovery.c160
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c1460
-rw-r--r--drivers/net/wireless/ath/ath6kl/target.h356
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.c102
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.h40
-rw-r--r--drivers/net/wireless/ath/ath6kl/trace.c23
-rw-r--r--drivers/net/wireless/ath/ath6kl/trace.h332
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c1877
-rw-r--r--drivers/net/wireless/ath/ath6kl/usb.c1264
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c4130
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h2731
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig153
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile70
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c192
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c520
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h125
-rw-r--r--drivers/net/wireless/ath/ath9k/antenna.c849
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_initvals.h674
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c1279
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9001_initvals.h1089
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c989
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c456
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_initvals.h3180
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c405
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c727
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h (renamed from drivers/net/wireless/ath9k/phy.h)192
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h1755
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_buffalo_initvals.h126
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c1683
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c5456
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h359
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c1048
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c593
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h123
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c1485
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.h335
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c1013
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c2010
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h1348
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.c258
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.h29
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_wow.c422
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h1020
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h507
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9340_initvals.h1298
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h1250
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h291
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h1240
-rw-r--r--drivers/net/wireless/ath/ath9k/ar953x_initvals.h718
-rw-r--r--drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h760
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h1168
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h64
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h1219
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h850
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c651
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c410
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h124
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c445
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h123
-rw-r--r--drivers/net/wireless/ath/ath9k/common-beacon.c180
-rw-r--r--drivers/net/wireless/ath/ath9k/common-beacon.h26
-rw-r--r--drivers/net/wireless/ath/ath9k/common-debug.c253
-rw-r--r--drivers/net/wireless/ath/ath9k/common-debug.h72
-rw-r--r--drivers/net/wireless/ath/ath9k/common-init.c244
-rw-r--r--drivers/net/wireless/ath/ath9k/common-init.h20
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c415
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h90
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c1372
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h325
-rw-r--r--drivers/net/wireless/ath/ath9k/debug_sta.c268
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs.c193
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs.h45
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.c151
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.h70
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c586
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h717
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c1101
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c1020
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c1365
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c500
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c1382
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h116
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h632
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c505
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c529
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c328
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c862
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1870
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c1163
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c515
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h230
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h277
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c3122
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1152
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c950
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c534
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c982
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h743
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c2280
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c768
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.h178
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c976
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h58
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c1141
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h2402
-rw-r--r--drivers/net/wireless/ath/ath9k/spectral.c543
-rw-r--r--drivers/net/wireless/ath/ath9k/spectral.h212
-rw-r--r--drivers/net/wireless/ath/ath9k/tx99.c272
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c349
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h191
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c360
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c2792
-rw-r--r--drivers/net/wireless/ath/carl9170/Kconfig56
-rw-r--r--drivers/net/wireless/ath/carl9170/Makefile4
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h669
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.c222
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.h174
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c896
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.h134
-rw-r--r--drivers/net/wireless/ath/carl9170/eeprom.h216
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c447
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h326
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h277
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h817
-rw-r--r--drivers/net/wireless/ath/carl9170/led.c190
-rw-r--r--drivers/net/wireless/ath/carl9170/mac.c538
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c2122
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c1730
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.h564
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c1012
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c1711
-rw-r--r--drivers/net/wireless/ath/carl9170/usb.c1178
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h7
-rw-r--r--drivers/net/wireless/ath/carl9170/wlan.h435
-rw-r--r--drivers/net/wireless/ath/debug.c47
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.c363
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.h112
-rw-r--r--drivers/net/wireless/ath/dfs_pri_detector.c429
-rw-r--r--drivers/net/wireless/ath/dfs_pri_detector.h77
-rw-r--r--drivers/net/wireless/ath/hw.c190
-rw-r--r--drivers/net/wireless/ath/key.c609
-rw-r--r--drivers/net/wireless/ath/main.c89
-rw-r--r--drivers/net/wireless/ath/reg.h65
-rw-r--r--drivers/net/wireless/ath/regd.c791
-rw-r--r--drivers/net/wireless/ath/regd.h263
-rw-r--r--drivers/net/wireless/ath/regd_common.h478
-rw-r--r--drivers/net/wireless/ath/wcn36xx/Kconfig16
-rw-r--r--drivers/net/wireless/ath/wcn36xx/Makefile7
-rw-r--r--drivers/net/wireless/ath/wcn36xx/debug.c181
-rw-r--r--drivers/net/wireless/ath/wcn36xx/debug.h49
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c813
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.h284
-rw-r--r--drivers/net/wireless/ath/wcn36xx/hal.h4659
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c1099
-rw-r--r--drivers/net/wireless/ath/wcn36xx/pmc.c62
-rw-r--r--drivers/net/wireless/ath/wcn36xx/pmc.h33
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c2166
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.h130
-rw-r--r--drivers/net/wireless/ath/wcn36xx/txrx.c283
-rw-r--r--drivers/net/wireless/ath/wcn36xx/txrx.h160
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h246
-rw-r--r--drivers/net/wireless/ath/wil6210/Kconfig41
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile18
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c779
-rw-r--r--drivers/net/wireless/ath/wil6210/debug.c69
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c760
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c550
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c591
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c200
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c220
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c201
-rw-r--r--drivers/net/wireless/ath/wil6210/trace.c20
-rw-r--r--drivers/net/wireless/ath/wil6210/trace.h239
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c1139
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h446
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h537
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c1198
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h1293
-rw-r--r--drivers/net/wireless/ath5k/Kconfig40
-rw-r--r--drivers/net/wireless/ath5k/Makefile6
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h1165
-rw-r--r--drivers/net/wireless/ath5k/base.c3086
-rw-r--r--drivers/net/wireless/ath5k/base.h192
-rw-r--r--drivers/net/wireless/ath5k/debug.c579
-rw-r--r--drivers/net/wireless/ath5k/hw.c4529
-rw-r--r--drivers/net/wireless/ath5k/hw.h616
-rw-r--r--drivers/net/wireless/ath5k/initvals.c1812
-rw-r--r--drivers/net/wireless/ath5k/phy.c2503
-rw-r--r--drivers/net/wireless/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath9k/Makefile11
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h1021
-rw-r--r--drivers/net/wireless/ath9k/beacon.c992
-rw-r--r--drivers/net/wireless/ath9k/core.c1930
-rw-r--r--drivers/net/wireless/ath9k/core.h1072
-rw-r--r--drivers/net/wireless/ath9k/hw.c8575
-rw-r--r--drivers/net/wireless/ath9k/hw.h969
-rw-r--r--drivers/net/wireless/ath9k/initvals.h3146
-rw-r--r--drivers/net/wireless/ath9k/main.c1498
-rw-r--r--drivers/net/wireless/ath9k/phy.c436
-rw-r--r--drivers/net/wireless/ath9k/rc.c2126
-rw-r--r--drivers/net/wireless/ath9k/rc.h316
-rw-r--r--drivers/net/wireless/ath9k/recv.c1319
-rw-r--r--drivers/net/wireless/ath9k/reg.h1385
-rw-r--r--drivers/net/wireless/ath9k/regd.c1026
-rw-r--r--drivers/net/wireless/ath9k/regd.h412
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h1915
-rw-r--r--drivers/net/wireless/ath9k/xmit.c2871
-rw-r--r--drivers/net/wireless/atmel.c763
-rw-r--r--drivers/net/wireless/atmel.h4
-rw-r--r--drivers/net/wireless/atmel_cs.c311
-rw-r--r--drivers/net/wireless/atmel_pci.c26
-rw-r--r--drivers/net/wireless/b43/Kconfig137
-rw-r--r--drivers/net/wireless/b43/Makefile23
-rw-r--r--drivers/net/wireless/b43/b43.h618
-rw-r--r--drivers/net/wireless/b43/bus.c255
-rw-r--r--drivers/net/wireless/b43/bus.h80
-rw-r--r--drivers/net/wireless/b43/debugfs.c211
-rw-r--r--drivers/net/wireless/b43/debugfs.h12
-rw-r--r--drivers/net/wireless/b43/dma.c674
-rw-r--r--drivers/net/wireless/b43/dma.h59
-rw-r--r--drivers/net/wireless/b43/leds.c281
-rw-r--r--drivers/net/wireless/b43/leds.h34
-rw-r--r--drivers/net/wireless/b43/lo.c216
-rw-r--r--drivers/net/wireless/b43/lo.h4
-rw-r--r--drivers/net/wireless/b43/main.c4066
-rw-r--r--drivers/net/wireless/b43/main.h67
-rw-r--r--drivers/net/wireless/b43/nphy.c486
-rw-r--r--drivers/net/wireless/b43/pcmcia.c83
-rw-r--r--drivers/net/wireless/b43/phy.c3906
-rw-r--r--drivers/net/wireless/b43/phy.h340
-rw-r--r--drivers/net/wireless/b43/phy_a.c595
-rw-r--r--drivers/net/wireless/b43/phy_a.h130
-rw-r--r--drivers/net/wireless/b43/phy_common.c633
-rw-r--r--drivers/net/wireless/b43/phy_common.h463
-rw-r--r--drivers/net/wireless/b43/phy_g.c3055
-rw-r--r--drivers/net/wireless/b43/phy_g.h208
-rw-r--r--drivers/net/wireless/b43/phy_ht.c1140
-rw-r--r--drivers/net/wireless/b43/phy_ht.h136
-rw-r--r--drivers/net/wireless/b43/phy_lcn.c902
-rw-r--r--drivers/net/wireless/b43/phy_lcn.h31
-rw-r--r--drivers/net/wireless/b43/phy_lp.c2730
-rw-r--r--drivers/net/wireless/b43/phy_lp.h912
-rw-r--r--drivers/net/wireless/b43/phy_n.c5787
-rw-r--r--drivers/net/wireless/b43/phy_n.h (renamed from drivers/net/wireless/b43/nphy.h)508
-rw-r--r--drivers/net/wireless/b43/pio.c284
-rw-r--r--drivers/net/wireless/b43/pio.h51
-rw-r--r--drivers/net/wireless/b43/radio_2055.c1335
-rw-r--r--drivers/net/wireless/b43/radio_2055.h259
-rw-r--r--drivers/net/wireless/b43/radio_2056.c10318
-rw-r--r--drivers/net/wireless/b43/radio_2056.h1100
-rw-r--r--drivers/net/wireless/b43/radio_2057.c141
-rw-r--r--drivers/net/wireless/b43/radio_2057.h430
-rw-r--r--drivers/net/wireless/b43/radio_2059.c155
-rw-r--r--drivers/net/wireless/b43/radio_2059.h46
-rw-r--r--drivers/net/wireless/b43/rfkill.c178
-rw-r--r--drivers/net/wireless/b43/rfkill.h47
-rw-r--r--drivers/net/wireless/b43/sdio.c207
-rw-r--r--drivers/net/wireless/b43/sdio.h45
-rw-r--r--drivers/net/wireless/b43/sysfs.c30
-rw-r--r--drivers/net/wireless/b43/tables.c45
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c2456
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.h44
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c3676
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h217
-rw-r--r--drivers/net/wireless/b43/tables_phy_ht.c836
-rw-r--r--drivers/net/wireless/b43/tables_phy_ht.h26
-rw-r--r--drivers/net/wireless/b43/tables_phy_lcn.c724
-rw-r--r--drivers/net/wireless/b43/tables_phy_lcn.h24
-rw-r--r--drivers/net/wireless/b43/wa.c147
-rw-r--r--drivers/net/wireless/b43/xmit.c407
-rw-r--r--drivers/net/wireless/b43/xmit.h137
-rw-r--r--drivers/net/wireless/b43legacy/Kconfig12
-rw-r--r--drivers/net/wireless/b43legacy/Makefile2
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h84
-rw-r--r--drivers/net/wireless/b43legacy/debugfs.c13
-rw-r--r--drivers/net/wireless/b43legacy/dma.c627
-rw-r--r--drivers/net/wireless/b43legacy/dma.h126
-rw-r--r--drivers/net/wireless/b43legacy/ilt.c2
-rw-r--r--drivers/net/wireless/b43legacy/leds.c24
-rw-r--r--drivers/net/wireless/b43legacy/leds.h2
-rw-r--r--drivers/net/wireless/b43legacy/main.c1017
-rw-r--r--drivers/net/wireless/b43legacy/main.h2
-rw-r--r--drivers/net/wireless/b43legacy/phy.c54
-rw-r--r--drivers/net/wireless/b43legacy/phy.h2
-rw-r--r--drivers/net/wireless/b43legacy/pio.c51
-rw-r--r--drivers/net/wireless/b43legacy/pio.h11
-rw-r--r--drivers/net/wireless/b43legacy/radio.c32
-rw-r--r--drivers/net/wireless/b43legacy/radio.h2
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c184
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.h54
-rw-r--r--drivers/net/wireless/b43legacy/sysfs.c4
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c75
-rw-r--r--drivers/net/wireless/b43legacy/xmit.h16
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig66
-rw-r--r--drivers/net/wireless/brcm80211/Makefile23
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile46
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.c375
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c1218
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/btcoex.c497
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/btcoex.h29
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c1035
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.h91
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h195
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h200
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c393
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c245
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h196
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c1123
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c4224
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.c332
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.h36
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c456
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h277
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c348
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h100
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h431
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c2172
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h34
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c2424
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.h183
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.c62
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.h57
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h334
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.c22
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h152
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c1448
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.h53
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h75
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c5681
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h493
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/Makefile48
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.c710
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.h229
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c1144
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.h53
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/antsel.c309
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/antsel.h27
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c23
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h255
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c774
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.h47
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/d11.h1902
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.c156
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.h76
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.c1564
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.h125
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/led.c126
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/led.h36
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c1703
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h113
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c8177
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.h669
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c2957
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h284
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h1142
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c5247
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h121
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c28729
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c308
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h42
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h1533
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h167
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c3293
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h55
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c10630
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h50
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c216
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h172
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pmu.c165
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pmu.h26
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h341
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/rate.c514
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/rate.h245
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/scb.h81
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/stf.c440
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/stf.h37
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/types.h303
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.c109
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h56
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/Makefile23
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/d11.c221
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/utils.c295
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h48
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_d11.h145
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_utils.h221
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_wifi.h274
-rw-r--r--drivers/net/wireless/brcm80211/include/chipcommon.h296
-rw-r--r--drivers/net/wireless/brcm80211/include/defs.h108
-rw-r--r--drivers/net/wireless/brcm80211/include/soc.h36
-rw-r--r--drivers/net/wireless/cw1200/Kconfig30
-rw-r--r--drivers/net/wireless/cw1200/Makefile21
-rw-r--r--drivers/net/wireless/cw1200/bh.c619
-rw-r--r--drivers/net/wireless/cw1200/bh.h28
-rw-r--r--drivers/net/wireless/cw1200/cw1200.h323
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sdio.c425
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c483
-rw-r--r--drivers/net/wireless/cw1200/debug.c430
-rw-r--r--drivers/net/wireless/cw1200/debug.h93
-rw-r--r--drivers/net/wireless/cw1200/fwio.c519
-rw-r--r--drivers/net/wireless/cw1200/fwio.h39
-rw-r--r--drivers/net/wireless/cw1200/hwbus.h33
-rw-r--r--drivers/net/wireless/cw1200/hwio.c312
-rw-r--r--drivers/net/wireless/cw1200/hwio.h247
-rw-r--r--drivers/net/wireless/cw1200/main.c603
-rw-r--r--drivers/net/wireless/cw1200/pm.c368
-rw-r--r--drivers/net/wireless/cw1200/pm.h43
-rw-r--r--drivers/net/wireless/cw1200/queue.c583
-rw-r--r--drivers/net/wireless/cw1200/queue.h116
-rw-r--r--drivers/net/wireless/cw1200/scan.c462
-rw-r--r--drivers/net/wireless/cw1200/scan.h56
-rw-r--r--drivers/net/wireless/cw1200/sta.c2402
-rw-r--r--drivers/net/wireless/cw1200/sta.h124
-rw-r--r--drivers/net/wireless/cw1200/txrx.c1472
-rw-r--r--drivers/net/wireless/cw1200/txrx.h106
-rw-r--r--drivers/net/wireless/cw1200/wsm.c1822
-rw-r--r--drivers/net/wireless/cw1200/wsm.h1870
-rw-r--r--drivers/net/wireless/hostap/Kconfig24
-rw-r--r--drivers/net/wireless/hostap/hostap.h4
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h30
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c198
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c134
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c807
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h16
-rw-r--r--drivers/net/wireless/hostap/hostap_common.h23
-rw-r--r--drivers/net/wireless/hostap/hostap_config.h4
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c400
-rw-r--r--drivers/net/wireless/hostap/hostap_download.c70
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c197
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c26
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c205
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c197
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c23
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c22
-rw-r--r--drivers/net/wireless/hostap/hostap_proc.c628
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h54
-rw-r--r--drivers/net/wireless/i82586.h413
-rw-r--r--drivers/net/wireless/i82593.h229
-rw-r--r--drivers/net/wireless/ipw2x00/Kconfig197
-rw-r--r--drivers/net/wireless/ipw2x00/Makefile14
-rw-r--r--drivers/net/wireless/ipw2x00/ipw.h23
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c (renamed from drivers/net/wireless/ipw2100.c)1031
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.h (renamed from drivers/net/wireless/ipw2100.h)54
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c (renamed from drivers/net/wireless/ipw2200.c)2609
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.h (renamed from drivers/net/wireless/ipw2200.h)169
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h1013
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_geo.c193
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c335
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c1797
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_tx.c536
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c744
-rw-r--r--drivers/net/wireless/iwlegacy/3945-debug.c511
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c3959
-rw-r--r--drivers/net/wireless/iwlegacy/3945-rs.c979
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c2741
-rw-r--r--drivers/net/wireless/iwlegacy/3945.h593
-rw-r--r--drivers/net/wireless/iwlegacy/4965-calib.c934
-rw-r--r--drivers/net/wireless/iwlegacy/4965-debug.c752
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c6870
-rw-r--r--drivers/net/wireless/iwlegacy/4965-rs.c2835
-rw-r--r--drivers/net/wireless/iwlegacy/4965.c1950
-rw-r--r--drivers/net/wireless/iwlegacy/4965.h1284
-rw-r--r--drivers/net/wireless/iwlegacy/Kconfig100
-rw-r--r--drivers/net/wireless/iwlegacy/Makefile17
-rw-r--r--drivers/net/wireless/iwlegacy/commands.h (renamed from drivers/net/wireless/iwlwifi/iwl-commands.h)2386
-rw-r--r--drivers/net/wireless/iwlegacy/common.c5584
-rw-r--r--drivers/net/wireless/iwlegacy/common.h3084
-rw-r--r--drivers/net/wireless/iwlegacy/csr.h419
-rw-r--r--drivers/net/wireless/iwlegacy/debug.c1430
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-spectrum.h (renamed from drivers/net/wireless/iwlwifi/iwl-spectrum.h)19
-rw-r--r--drivers/net/wireless/iwlegacy/prph.h522
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig228
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile31
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/Makefile13
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h492
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c (renamed from drivers/net/wireless/iwlwifi/iwl-calib.c)731
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.h (renamed from drivers/net/wireless/iwlwifi/iwl-3945-core.h)32
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h4003
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c2445
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h949
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/devices.c690
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/led.c223
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/led.h (renamed from drivers/net/wireless/iwlwifi/iwl-led.h)49
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c1301
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c1636
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c2108
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c386
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.h (renamed from drivers/net/wireless/iwlwifi/iwl-rfkill.h)35
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c3346
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.h (renamed from drivers/net/wireless/iwlwifi/iwl-agn-rs.h)249
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c1132
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c1559
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c1084
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c1475
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c690
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.h128
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c1418
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c456
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c138
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c211
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h1696
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debug.h167
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h488
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h426
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c412
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h74
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c988
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h215
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2673
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h958
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h1016
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c2414
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1718
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c383
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c248
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c135
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h (renamed from drivers/net/wireless/iwlwifi/iwl-5000-hw.h)105
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c2615
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c4534
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h343
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1455
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h410
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h379
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.c136
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h299
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c431
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1166
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h515
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c1396
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h154
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c940
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h140
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.c464
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.h70
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c604
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h397
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h302
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h134
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h178
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h317
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c282
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h205
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c267
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h415
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c444
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h125
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.c191
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.h138
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c570
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h81
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h271
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c471
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.h (renamed from drivers/net/wireless/iwlwifi/iwl-calib.h)42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c433
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h89
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h587
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c146
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1297
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c934
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c995
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h916
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c1554
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c8354
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c211
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c1322
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h86
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c1771
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c596
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c1204
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.h101
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h358
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h422
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h386
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h365
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h353
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h604
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h415
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h591
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h1503
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c567
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c136
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c1282
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c2498
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h1042
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c529
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/offloading.c215
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c1270
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c263
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c936
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c293
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c3276
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h403
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c488
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c950
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c289
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c1450
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h408
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/testmode.h95
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c540
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h217
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c560
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c968
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c744
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c602
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h500
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c1232
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c1926
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c1809
-rw-r--r--drivers/net/wireless/libertas/11d.c698
-rw-r--r--drivers/net/wireless/libertas/11d.h104
-rw-r--r--drivers/net/wireless/libertas/Kconfig45
-rw-r--r--drivers/net/wireless/libertas/Makefile14
-rw-r--r--drivers/net/wireless/libertas/README36
-rw-r--r--drivers/net/wireless/libertas/assoc.c1915
-rw-r--r--drivers/net/wireless/libertas/assoc.h39
-rw-r--r--drivers/net/wireless/libertas/cfg.c2218
-rw-r--r--drivers/net/wireless/libertas/cfg.h20
-rw-r--r--drivers/net/wireless/libertas/cmd.c1872
-rw-r--r--drivers/net/wireless/libertas/cmd.h124
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c467
-rw-r--r--drivers/net/wireless/libertas/debugfs.c318
-rw-r--r--drivers/net/wireless/libertas/decl.h108
-rw-r--r--drivers/net/wireless/libertas/defs.h206
-rw-r--r--drivers/net/wireless/libertas/dev.h457
-rw-r--r--drivers/net/wireless/libertas/ethtool.c142
-rw-r--r--drivers/net/wireless/libertas/firmware.c227
-rw-r--r--drivers/net/wireless/libertas/host.h1013
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h730
-rw-r--r--drivers/net/wireless/libertas/if_cs.c426
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c879
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h7
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1319
-rw-r--r--drivers/net/wireless/libertas/if_spi.h206
-rw-r--r--drivers/net/wireless/libertas/if_usb.c357
-rw-r--r--drivers/net/wireless/libertas/if_usb.h20
-rw-r--r--drivers/net/wireless/libertas/main.c1442
-rw-r--r--drivers/net/wireless/libertas/mesh.c1188
-rw-r--r--drivers/net/wireless/libertas/mesh.h77
-rw-r--r--drivers/net/wireless/libertas/persistcfg.c453
-rw-r--r--drivers/net/wireless/libertas/radiotap.h17
-rw-r--r--drivers/net/wireless/libertas/rx.c263
-rw-r--r--drivers/net/wireless/libertas/scan.c1199
-rw-r--r--drivers/net/wireless/libertas/scan.h29
-rw-r--r--drivers/net/wireless/libertas/tx.c75
-rw-r--r--drivers/net/wireless/libertas/types.h247
-rw-r--r--drivers/net/wireless/libertas/wext.c2201
-rw-r--r--drivers/net/wireless/libertas/wext.h10
-rw-r--r--drivers/net/wireless/libertas_tf/Makefile6
-rw-r--r--drivers/net/wireless/libertas_tf/cmd.c807
-rw-r--r--drivers/net/wireless/libertas_tf/deb_defs.h104
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c930
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.h98
-rw-r--r--drivers/net/wireless/libertas_tf/libertas_tf.h519
-rw-r--r--drivers/net/wireless/libertas_tf/main.c769
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c2673
-rw-r--r--drivers/net/wireless/mac80211_hwsim.h157
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c382
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h45
-rw-r--r--drivers/net/wireless/mwifiex/11h.c101
-rw-r--r--drivers/net/wireless/mwifiex/11n.c793
-rw-r--r--drivers/net/wireless/mwifiex/11n.h211
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c310
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.h33
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c762
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h83
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig42
-rw-r--r--drivers/net/wireless/mwifiex/Makefile55
-rw-r--r--drivers/net/wireless/mwifiex/README210
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c2988
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h29
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c511
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1607
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c782
-rw-r--r--drivers/net/wireless/mwifiex/decl.h188
-rw-r--r--drivers/net/wireless/mwifiex/ethtool.c70
-rw-r--r--drivers/net/wireless/mwifiex/fw.h1878
-rw-r--r--drivers/net/wireless/mwifiex/ie.c446
-rw-r--r--drivers/net/wireless/mwifiex/init.c720
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h454
-rw-r--r--drivers/net/wireless/mwifiex/join.c1479
-rw-r--r--drivers/net/wireless/mwifiex/main.c1048
-rw-r--r--drivers/net/wireless/mwifiex/main.h1253
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c2453
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h325
-rw-r--r--drivers/net/wireless/mwifiex/scan.c2345
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c2018
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h453
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c2070
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c1129
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c513
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c1433
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c254
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c225
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c1103
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c209
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c771
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c198
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c404
-rw-r--r--drivers/net/wireless/mwifiex/usb.c1052
-rw-r--r--drivers/net/wireless/mwifiex/usb.h103
-rw-r--r--drivers/net/wireless/mwifiex/util.c368
-rw-r--r--drivers/net/wireless/mwifiex/util.h76
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c1307
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h130
-rw-r--r--drivers/net/wireless/mwl8k.c6348
-rw-r--r--drivers/net/wireless/netwave_cs.c1425
-rw-r--r--drivers/net/wireless/orinoco.c4410
-rw-r--r--drivers/net/wireless/orinoco.h164
-rw-r--r--drivers/net/wireless/orinoco/Kconfig141
-rw-r--r--drivers/net/wireless/orinoco/Makefile17
-rw-r--r--drivers/net/wireless/orinoco/airport.c (renamed from drivers/net/wireless/airport.c)150
-rw-r--r--drivers/net/wireless/orinoco/cfg.c291
-rw-r--r--drivers/net/wireless/orinoco/cfg.h15
-rw-r--r--drivers/net/wireless/orinoco/fw.c387
-rw-r--r--drivers/net/wireless/orinoco/fw.h21
-rw-r--r--drivers/net/wireless/orinoco/hermes.c (renamed from drivers/net/wireless/hermes.c)493
-rw-r--r--drivers/net/wireless/orinoco/hermes.h (renamed from drivers/net/wireless/hermes.h)177
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c477
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.h52
-rw-r--r--drivers/net/wireless/orinoco/hermes_rid.h (renamed from drivers/net/wireless/hermes_rid.h)17
-rw-r--r--drivers/net/wireless/orinoco/hw.c1356
-rw-r--r--drivers/net/wireless/orinoco/hw.h59
-rw-r--r--drivers/net/wireless/orinoco/main.c2431
-rw-r--r--drivers/net/wireless/orinoco/main.h50
-rw-r--r--drivers/net/wireless/orinoco/mic.c79
-rw-r--r--drivers/net/wireless/orinoco/mic.h22
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h253
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c (renamed from drivers/net/wireless/orinoco_cs.c)446
-rw-r--r--drivers/net/wireless/orinoco/orinoco_nortel.c (renamed from drivers/net/wireless/orinoco_nortel.c)55
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c (renamed from drivers/net/wireless/orinoco_pci.c)54
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.h68
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c (renamed from drivers/net/wireless/orinoco_plx.c)54
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c (renamed from drivers/net/wireless/orinoco_tmd.c)51
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c1754
-rw-r--r--drivers/net/wireless/orinoco/scan.c249
-rw-r--r--drivers/net/wireless/orinoco/scan.h21
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c320
-rw-r--r--drivers/net/wireless/orinoco/wext.c1413
-rw-r--r--drivers/net/wireless/orinoco/wext.h13
-rw-r--r--drivers/net/wireless/orinoco_pci.h109
-rw-r--r--drivers/net/wireless/p54/Kconfig70
-rw-r--r--drivers/net/wireless/p54/Makefile4
-rw-r--r--drivers/net/wireless/p54/eeprom.c982
-rw-r--r--drivers/net/wireless/p54/eeprom.h245
-rw-r--r--drivers/net/wireless/p54/fwio.c762
-rw-r--r--drivers/net/wireless/p54/led.c161
-rw-r--r--drivers/net/wireless/p54/lmac.h562
-rw-r--r--drivers/net/wireless/p54/main.c866
-rw-r--r--drivers/net/wireless/p54/net2280.h19
-rw-r--r--drivers/net/wireless/p54/p54.h296
-rw-r--r--drivers/net/wireless/p54/p54common.c1060
-rw-r--r--drivers/net/wireless/p54/p54common.h253
-rw-r--r--drivers/net/wireless/p54/p54pci.c703
-rw-r--r--drivers/net/wireless/p54/p54pci.h30
-rw-r--r--drivers/net/wireless/p54/p54spi.c721
-rw-r--r--drivers/net/wireless/p54/p54spi.h125
-rw-r--r--drivers/net/wireless/p54/p54spi_eeprom.h679
-rw-r--r--drivers/net/wireless/p54/p54usb.c779
-rw-r--r--drivers/net/wireless/p54/p54usb.h36
-rw-r--r--drivers/net/wireless/p54/txrx.c940
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c3
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h3
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c406
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.h5
-rw-r--r--drivers/net/wireless/prism54/isl_oid.h21
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c85
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h7
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c56
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.h9
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c26
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c34
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h12
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c16
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.h3
-rw-r--r--drivers/net/wireless/prism54/prismcompat.h3
-rw-r--r--drivers/net/wireless/ray_cs.c4030
-rw-r--r--drivers/net/wireless/ray_cs.h3
-rw-r--r--drivers/net/wireless/rayctl.h6
-rw-r--r--drivers/net/wireless/rndis_wlan.c4007
-rw-r--r--drivers/net/wireless/rsi/Kconfig30
-rw-r--r--drivers/net/wireless/rsi/Makefile12
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_core.c344
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_debugfs.c336
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c1009
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_main.c295
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c1307
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_pkt.c196
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio.c849
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio_ops.c564
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb.c587
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb_ops.c177
-rw-r--r--drivers/net/wireless/rsi/rsi_boot_params.h126
-rw-r--r--drivers/net/wireless/rsi/rsi_common.h87
-rw-r--r--drivers/net/wireless/rsi/rsi_debugfs.h48
-rw-r--r--drivers/net/wireless/rsi/rsi_main.h218
-rw-r--r--drivers/net/wireless/rsi/rsi_mgmt.h286
-rw-r--r--drivers/net/wireless/rsi/rsi_sdio.h129
-rw-r--r--drivers/net/wireless/rsi/rsi_usb.h68
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig279
-rw-r--r--drivers/net/wireless/rt2x00/Makefile10
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1327
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h67
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1439
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h54
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c1197
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h52
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h2974
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c8007
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h231
-rw-r--r--drivers/net/wireless/rt2x00/rt2800mmio.c871
-rw-r--r--drivers/net/wireless/rt2x00/rt2800mmio.h163
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c471
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.h42
-rw-r--r--drivers/net/wireless/rt2x00/rt2800soc.c261
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c1451
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h110
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1148
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c336
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c256
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c333
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.h20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c1415
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dump.h20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c51
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c112
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h312
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c498
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c768
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.c214
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.h117
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c255
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h96
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c1129
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h355
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h66
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c161
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.c160
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00soc.h40
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c684
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h237
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2113
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h169
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1802
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h116
-rw-r--r--drivers/net/wireless/rtl8180_dev.c1080
-rw-r--r--drivers/net/wireless/rtl818x.h196
-rw-r--r--drivers/net/wireless/rtl818x/Kconfig88
-rw-r--r--drivers/net/wireless/rtl818x/Makefile2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/Makefile5
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c1925
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/grf5101.c (renamed from drivers/net/wireless/rtl8180_grf5101.c)20
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/grf5101.h (renamed from drivers/net/wireless/rtl8180_grf5101.h)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/max2820.c (renamed from drivers/net/wireless/rtl8180_max2820.c)26
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/max2820.h (renamed from drivers/net/wireless/rtl8180_max2820.h)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8180.h (renamed from drivers/net/wireless/rtl8180.h)119
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8225.c (renamed from drivers/net/wireless/rtl8180_rtl8225.c)34
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8225.h (renamed from drivers/net/wireless/rtl8180_rtl8225.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c475
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8225se.h61
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/sa2400.c (renamed from drivers/net/wireless/rtl8180_sa2400.c)36
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/sa2400.h (renamed from drivers/net/wireless/rtl8180_sa2400.h)2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/Makefile5
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c (renamed from drivers/net/wireless/rtl8187_dev.c)1005
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/leds.c245
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/leds.h59
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rfkill.c64
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rfkill.h8
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8187.h (renamed from drivers/net/wireless/rtl8187.h)119
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8225.c (renamed from drivers/net/wireless/rtl8187_rtl8225.c)455
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/rtl8225.h (renamed from drivers/net/wireless/rtl8187_rtl8225.h)4
-rw-r--r--drivers/net/wireless/rtl818x/rtl818x.h405
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig129
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile32
-rw-r--r--drivers/net/wireless/rtlwifi/base.c1911
-rw-r--r--drivers/net/wireless/rtlwifi/base.h157
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/Makefile7
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h75
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c3698
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h173
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c1001
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h559
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c218
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h52
-rw-r--r--drivers/net/wireless/rtlwifi/cam.c348
-rw-r--r--drivers/net/wireless/rtlwifi/cam.h56
-rw-r--r--drivers/net/wireless/rtlwifi/core.c1423
-rw-r--r--drivers/net/wireless/rtlwifi/core.h49
-rw-r--r--drivers/net/wireless/rtlwifi/debug.c54
-rw-r--r--drivers/net/wireless/rtlwifi/debug.h244
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.c1237
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.h122
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c2196
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h294
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c1039
-rw-r--r--drivers/net/wireless/rtlwifi/ps.h114
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c282
-rw-r--r--drivers/net/wireless/rtlwifi/rc.h47
-rw-r--r--drivers/net/wireless/rtlwifi/regd.c421
-rw-r--r--drivers/net/wireless/rtlwifi/regd.h61
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/Makefile15
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/def.h324
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.c1793
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.h326
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/fw.c830
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/fw.h301
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c2517
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.h66
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/led.c157
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/led.h38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/phy.c2127
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/phy.h234
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.c109
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseq.h326
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.c140
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/pwrseqcmd.h97
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/reg.h2242
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/rf.c467
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/rf.h46
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/sw.c404
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/sw.h36
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/table.c643
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/table.h47
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.c817
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.h795
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/Makefile9
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c1809
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h185
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c907
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h103
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/main.c40
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c1940
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h254
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/Makefile13
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h251
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.c109
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.h163
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c2425
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.h80
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.c151
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/led.h38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.c573
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.h250
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h2056
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.c509
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c387
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/table.c1224
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/table.h58
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c754
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.h730
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/Makefile14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/def.h58
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/dm.c116
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/dm.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c2372
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.h116
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/led.c141
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/led.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.c944
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.h174
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.c548
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.h50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/reg.h30
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.c489
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.h50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c401
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.h53
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/table.c1888
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/table.h71
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c687
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.h435
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/Makefile14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/def.h271
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.c1342
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.h161
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/fw.c780
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/fw.h155
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c2307
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.h65
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/led.c159
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/led.h38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/phy.c3608
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/phy.h173
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/reg.h1298
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/rf.c623
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/rf.h42
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c418
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/table.c1690
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/table.h57
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.c872
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.h748
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/Makefile15
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h554
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.c742
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.h120
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.c656
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.h376
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c2546
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.h78
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/led.c151
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/led.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.c1656
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.h102
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/reg.h1168
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/rf.c535
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c442
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.h36
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/table.c634
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/table.h49
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c660
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.h48
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/Makefile21
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/btc.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/def.h158
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.c959
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.h154
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.c622
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/fw.h90
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c543
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h160
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c1786
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h151
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c2385
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.h71
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/led.c157
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/led.h39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.c1573
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/phy.h201
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c109
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h321
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c129
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h98
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/reg.h2081
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.c505
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.h42
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c389
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/table.c738
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/table.h50
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.c681
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/trx.h720
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/Makefile19
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/def.h248
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.c1325
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.h310
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/fw.c620
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/fw.h248
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2503
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.h62
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/led.c153
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/led.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.c2156
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.h217
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.c106
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseq.h304
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.c140
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/pwrseqcmd.h95
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/reg.h2277
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.c504
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.c387
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.h35
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/table.c572
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/table.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/trx.c959
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/trx.h617
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/Makefile9
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/dm_common.c65
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/dm_common.h33
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/fw_common.c329
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/fw_common.h126
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/main.c33
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/phy_common.c434
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723com/phy_common.h89
-rw-r--r--drivers/net/wireless/rtlwifi/stats.c282
-rw-r--r--drivers/net/wireless/rtlwifi/stats.h46
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c1174
-rw-r--r--drivers/net/wireless/rtlwifi/usb.h169
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h2790
-rw-r--r--drivers/net/wireless/spectrum_cs.c928
-rw-r--r--drivers/net/wireless/strip.c2804
-rw-r--r--drivers/net/wireless/ti/Kconfig24
-rw-r--r--drivers/net/wireless/ti/Makefile7
-rw-r--r--drivers/net/wireless/ti/wilink_platform_data.c74
-rw-r--r--drivers/net/wireless/ti/wl1251/Kconfig33
-rw-r--r--drivers/net/wireless/ti/wl1251/Makefile10
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.c1056
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.h1499
-rw-r--r--drivers/net/wireless/ti/wl1251/boot.c555
-rw-r--r--drivers/net/wireless/ti/wl1251/boot.h39
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.c514
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.h421
-rw-r--r--drivers/net/wireless/ti/wl1251/debugfs.c539
-rw-r--r--drivers/net/wireless/ti/wl1251/debugfs.h31
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c236
-rw-r--r--drivers/net/wireless/ti/wl1251/event.h127
-rw-r--r--drivers/net/wireless/ti/wl1251/init.c428
-rw-r--r--drivers/net/wireless/ti/wl1251/init.h86
-rw-r--r--drivers/net/wireless/ti/wl1251/io.c194
-rw-r--r--drivers/net/wireless/ti/wl1251/io.h83
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c1615
-rw-r--r--drivers/net/wireless/ti/wl1251/ps.c184
-rw-r--r--drivers/net/wireless/ti/wl1251/ps.h35
-rw-r--r--drivers/net/wireless/ti/wl1251/reg.h655
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.c235
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.h122
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c387
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c369
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.h59
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.c593
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.h231
-rw-r--r--drivers/net/wireless/ti/wl1251/wl1251.h453
-rw-r--r--drivers/net/wireless/ti/wl1251/wl12xx_80211.h155
-rw-r--r--drivers/net/wireless/ti/wl12xx/Kconfig9
-rw-r--r--drivers/net/wireless/ti/wl12xx/Makefile3
-rw-r--r--drivers/net/wireless/ti/wl12xx/acx.c53
-rw-r--r--drivers/net/wireless/ti/wl12xx/acx.h273
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.c323
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.h132
-rw-r--r--drivers/net/wireless/ti/wl12xx/conf.h50
-rw-r--r--drivers/net/wireless/ti/wl12xx/debugfs.c243
-rw-r--r--drivers/net/wireless/ti/wl12xx/debugfs.h28
-rw-r--r--drivers/net/wireless/ti/wl12xx/event.c116
-rw-r--r--drivers/net/wireless/ti/wl12xx/event.h111
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c1923
-rw-r--r--drivers/net/wireless/ti/wl12xx/reg.h556
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.c501
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.h140
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h135
-rw-r--r--drivers/net/wireless/ti/wl18xx/Kconfig7
-rw-r--r--drivers/net/wireless/ti/wl18xx/Makefile3
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.c196
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.h340
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.c80
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.h52
-rw-r--r--drivers/net/wireless/ti/wl18xx/conf.h121
-rw-r--r--drivers/net/wireless/ti/wl18xx/debugfs.c403
-rw-r--r--drivers/net/wireless/ti/wl18xx/debugfs.h28
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.c111
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.h97
-rw-r--r--drivers/net/wireless/ti/wl18xx/io.c75
-rw-r--r--drivers/net/wireless/ti/wl18xx/io.h28
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c2013
-rw-r--r--drivers/net/wireless/ti/wl18xx/reg.h248
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.c326
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.h127
-rw-r--r--drivers/net/wireless/ti/wl18xx/tx.c171
-rw-r--r--drivers/net/wireless/ti/wl18xx/tx.h46
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h196
-rw-r--r--drivers/net/wireless/ti/wlcore/Kconfig35
-rw-r--r--drivers/net/wireless/ti/wlcore/Makefile12
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c1853
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h1136
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c533
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.h55
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c2045
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h702
-rw-r--r--drivers/net/wireless/ti/wlcore/conf.h1387
-rw-r--r--drivers/net/wireless/ti/wlcore/debug.h112
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c1346
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.h120
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c309
-rw-r--r--drivers/net/wireless/ti/wlcore/event.h87
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h263
-rw-r--r--drivers/net/wireless/ti/wlcore/ini.h232
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c756
-rw-r--r--drivers/net/wireless/ti/wlcore/init.h39
-rw-r--r--drivers/net/wireless/ti/wlcore/io.c200
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h238
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c6213
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c336
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.h41
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c342
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.h152
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c488
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.h172
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c413
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c434
-rw-r--r--drivers/net/wireless/ti/wlcore/sysfs.c216
-rw-r--r--drivers/net/wireless/ti/wlcore/sysfs.h28
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.c397
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.h32
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c1329
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.h287
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx_80211.h137
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h638
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h545
-rw-r--r--drivers/net/wireless/wavelan.c4410
-rw-r--r--drivers/net/wireless/wavelan.h370
-rw-r--r--drivers/net/wireless/wavelan.p.h703
-rw-r--r--drivers/net/wireless/wavelan_cs.c4679
-rw-r--r--drivers/net/wireless/wavelan_cs.h386
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h772
-rw-r--r--drivers/net/wireless/wl3501.h23
-rw-r--r--drivers/net/wireless/wl3501_cs.c338
-rw-r--r--drivers/net/wireless/zd1201.c237
-rw-r--r--drivers/net/wireless/zd1201.h1
-rw-r--r--drivers/net/wireless/zd1211rw/Kconfig2
-rw-r--r--drivers/net/wireless/zd1211rw/Makefile6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c619
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h574
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h16
-rw-r--r--drivers/net/wireless/zd1211rw/zd_ieee80211.c100
-rw-r--r--drivers/net/wireless/zd1211rw/zd_ieee80211.h95
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c980
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h127
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c201
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c243
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_rf2959.c83
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_uw2453.c92
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c895
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h64
-rw-r--r--drivers/net/xen-netback/Makefile3
-rw-r--r--drivers/net/xen-netback/common.h306
-rw-r--r--drivers/net/xen-netback/interface.c734
-rw-r--r--drivers/net/xen-netback/netback.c2045
-rw-r--r--drivers/net/xen-netback/xenbus.c786
-rw-r--r--drivers/net/xen-netfront.c1970
-rw-r--r--drivers/net/znet.c927
-rw-r--r--drivers/net/zorro8390.c446
3040 files changed, 1616989 insertions, 511553 deletions
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
deleted file mode 100644
index 5ba4bab6d43..00000000000
--- a/drivers/net/3c501.c
+++ /dev/null
@@ -1,900 +0,0 @@
-/* 3c501.c: A 3Com 3c501 Ethernet driver for Linux. */
-/*
- Written 1992,1993,1994 Donald Becker
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- This is a device driver for the 3Com Etherlink 3c501.
- Do not purchase this card, even as a joke. It's performance is horrible,
- and it breaks in many ways.
-
- The original author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- Fixed (again!) the missing interrupt locking on TX/RX shifting.
- Alan Cox <Alan.Cox@linux.org>
-
- Removed calls to init_etherdev since they are no longer needed, and
- cleaned up modularization just a bit. The driver still allows only
- the default address for cards when loaded as a module, but that's
- really less braindead than anyone using a 3c501 board. :)
- 19950208 (invid@msen.com)
-
- Added traps for interrupts hitting the window as we clear and TX load
- the board. Now getting 150K/second FTP with a 3c501 card. Still playing
- with a TX-TX optimisation to see if we can touch 180-200K/second as seems
- theoretically maximum.
- 19950402 Alan Cox <Alan.Cox@linux.org>
-
- Cleaned up for 2.3.x because we broke SMP now.
- 20000208 Alan Cox <alan@redhat.com>
-
- Check up pass for 2.5. Nothing significant changed
- 20021009 Alan Cox <alan@redhat.com>
-
- Fixed zero fill corner case
- 20030104 Alan Cox <alan@redhat.com>
-
-
- For the avoidance of doubt the "preferred form" of this code is one which
- is in an open non patent encumbered format. Where cryptographic key signing
- forms part of the process of creating an executable the information
- including keys needed to generate an equivalently functional executable
- are deemed to be part of the source code.
-
-*/
-
-
-/**
- * DOC: 3c501 Card Notes
- *
- * Some notes on this thing if you have to hack it. [Alan]
- *
- * Some documentation is available from 3Com. Due to the boards age
- * standard responses when you ask for this will range from 'be serious'
- * to 'give it to a museum'. The documentation is incomplete and mostly
- * of historical interest anyway.
- *
- * The basic system is a single buffer which can be used to receive or
- * transmit a packet. A third command mode exists when you are setting
- * things up.
- *
- * If it's transmitting it's not receiving and vice versa. In fact the
- * time to get the board back into useful state after an operation is
- * quite large.
- *
- * The driver works by keeping the board in receive mode waiting for a
- * packet to arrive. When one arrives it is copied out of the buffer
- * and delivered to the kernel. The card is reloaded and off we go.
- *
- * When transmitting lp->txing is set and the card is reset (from
- * receive mode) [possibly losing a packet just received] to command
- * mode. A packet is loaded and transmit mode triggered. The interrupt
- * handler runs different code for transmit interrupts and can handle
- * returning to receive mode or retransmissions (yes you have to help
- * out with those too).
- *
- * DOC: Problems
- *
- * There are a wide variety of undocumented error returns from the card
- * and you basically have to kick the board and pray if they turn up. Most
- * only occur under extreme load or if you do something the board doesn't
- * like (eg touching a register at the wrong time).
- *
- * The driver is less efficient than it could be. It switches through
- * receive mode even if more transmits are queued. If this worries you buy
- * a real Ethernet card.
- *
- * The combination of slow receive restart and no real multicast
- * filter makes the board unusable with a kernel compiled for IP
- * multicasting in a real multicast environment. That's down to the board,
- * but even with no multicast programs running a multicast IP kernel is
- * in group 224.0.0.1 and you will therefore be listening to all multicasts.
- * One nv conference running over that Ethernet and you can give up.
- *
- */
-
-#define DRV_NAME "3c501"
-#define DRV_VERSION "2002/10/09"
-
-
-static const char version[] =
- DRV_NAME ".c: " DRV_VERSION " Alan Cox (alan@redhat.com).\n";
-
-/*
- * Braindamage remaining:
- * The 3c501 board.
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-
-#include "3c501.h"
-
-/*
- * The boilerplate probe code.
- */
-
-static int io = 0x280;
-static int irq = 5;
-static int mem_start;
-
-/**
- * el1_probe: - probe for a 3c501
- * @dev: The device structure passed in to probe.
- *
- * This can be called from two places. The network layer will probe using
- * a device structure passed in with the probe information completed. For a
- * modular driver we use #init_module to fill in our own structure and probe
- * for it.
- *
- * Returns 0 on success. ENXIO if asked not to probe and ENODEV if asked to
- * probe and failing to find anything.
- */
-
-struct net_device * __init el1_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- static unsigned ports[] = { 0x280, 0x300, 0};
- unsigned *port;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- mem_start = dev->mem_start & 7;
- }
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = el1_probe1(dev, io);
- } else if (io != 0) {
- err = -ENXIO; /* Don't probe at all. */
- } else {
- for (port = ports; *port && el1_probe1(dev, *port); port++)
- ;
- if (!*port)
- err = -ENODEV;
- }
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- release_region(dev->base_addr, EL1_IO_EXTENT);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-/**
- * el1_probe1:
- * @dev: The device structure to use
- * @ioaddr: An I/O address to probe at.
- *
- * The actual probe. This is iterated over by #el1_probe in order to
- * check all the applicable device locations.
- *
- * Returns 0 for a success, in which case the device is activated,
- * EAGAIN if the IRQ is in use by another driver, and ENODEV if the
- * board cannot be found.
- */
-
-static int __init el1_probe1(struct net_device *dev, int ioaddr)
-{
- struct net_local *lp;
- const char *mname; /* Vendor name */
- unsigned char station_addr[6];
- int autoirq = 0;
- int i;
-
- /*
- * Reserve I/O resource for exclusive use by this driver
- */
-
- if (!request_region(ioaddr, EL1_IO_EXTENT, DRV_NAME))
- return -ENODEV;
-
- /*
- * Read the station address PROM data from the special port.
- */
-
- for (i = 0; i < 6; i++) {
- outw(i, ioaddr + EL1_DATAPTR);
- station_addr[i] = inb(ioaddr + EL1_SAPROM);
- }
- /*
- * Check the first three octets of the S.A. for 3Com's prefix, or
- * for the Sager NP943 prefix.
- */
-
- if (station_addr[0] == 0x02 && station_addr[1] == 0x60
- && station_addr[2] == 0x8c)
- mname = "3c501";
- else if (station_addr[0] == 0x00 && station_addr[1] == 0x80
- && station_addr[2] == 0xC8)
- mname = "NP943";
- else {
- release_region(ioaddr, EL1_IO_EXTENT);
- return -ENODEV;
- }
-
- /*
- * We auto-IRQ by shutting off the interrupt line and letting it
- * float high.
- */
-
- dev->irq = irq;
-
- if (dev->irq < 2) {
- unsigned long irq_mask;
-
- irq_mask = probe_irq_on();
- inb(RX_STATUS); /* Clear pending interrupts. */
- inb(TX_STATUS);
- outb(AX_LOOP + 1, AX_CMD);
-
- outb(0x00, AX_CMD);
-
- mdelay(20);
- autoirq = probe_irq_off(irq_mask);
-
- if (autoirq == 0) {
- printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
- mname, ioaddr);
- release_region(ioaddr, EL1_IO_EXTENT);
- return -EAGAIN;
- }
- }
-
- outb(AX_RESET+AX_LOOP, AX_CMD); /* Loopback mode. */
- dev->base_addr = ioaddr;
- memcpy(dev->dev_addr, station_addr, ETH_ALEN);
-
- if (mem_start & 0xf)
- el_debug = mem_start & 0x7;
- if (autoirq)
- dev->irq = autoirq;
-
- printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
- dev->name, mname, dev->base_addr,
- autoirq ? "auto":"assigned ", dev->irq);
-
-#ifdef CONFIG_IP_MULTICAST
- printk(KERN_WARNING "WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
-#endif
-
- if (el_debug)
- printk(KERN_DEBUG "%s", version);
-
- memset(dev->priv, 0, sizeof(struct net_local));
- lp = netdev_priv(dev);
- spin_lock_init(&lp->lock);
-
- /*
- * The EL1-specific entries in the device structure.
- */
-
- dev->open = &el_open;
- dev->hard_start_xmit = &el_start_xmit;
- dev->tx_timeout = &el_timeout;
- dev->watchdog_timeo = HZ;
- dev->stop = &el1_close;
- dev->set_multicast_list = &set_multicast_list;
- dev->ethtool_ops = &netdev_ethtool_ops;
- return 0;
-}
-
-/**
- * el1_open:
- * @dev: device that is being opened
- *
- * When an ifconfig is issued which changes the device flags to include
- * IFF_UP this function is called. It is only called when the change
- * occurs, not when the interface remains up. #el1_close will be called
- * when it goes down.
- *
- * Returns 0 for a successful open, or -EAGAIN if someone has run off
- * with our interrupt line.
- */
-
-static int el_open(struct net_device *dev)
-{
- int retval;
- int ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
-
- if (el_debug > 2)
- printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
-
- retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
- if (retval)
- return retval;
-
- spin_lock_irqsave(&lp->lock, flags);
- el_reset(dev);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- lp->txing = 0; /* Board in RX mode */
- outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
- netif_start_queue(dev);
- return 0;
-}
-
-/**
- * el_timeout:
- * @dev: The 3c501 card that has timed out
- *
- * Attempt to restart the board. This is basically a mixture of extreme
- * violence and prayer
- *
- */
-
-static void el_timeout(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if (el_debug)
- printk(KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
- dev->name, inb(TX_STATUS),
- inb(AX_STATUS), inb(RX_STATUS));
- dev->stats.tx_errors++;
- outb(TX_NORM, TX_CMD);
- outb(RX_NORM, RX_CMD);
- outb(AX_OFF, AX_CMD); /* Just trigger a false interrupt. */
- outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
- lp->txing = 0; /* Ripped back in to RX */
- netif_wake_queue(dev);
-}
-
-
-/**
- * el_start_xmit:
- * @skb: The packet that is queued to be sent
- * @dev: The 3c501 card we want to throw it down
- *
- * Attempt to send a packet to a 3c501 card. There are some interesting
- * catches here because the 3c501 is an extremely old and therefore
- * stupid piece of technology.
- *
- * If we are handling an interrupt on the other CPU we cannot load a packet
- * as we may still be attempting to retrieve the last RX packet buffer.
- *
- * When a transmit times out we dump the card into control mode and just
- * start again. It happens enough that it isnt worth logging.
- *
- * We avoid holding the spin locks when doing the packet load to the board.
- * The device is very slow, and its DMA mode is even slower. If we held the
- * lock while loading 1500 bytes onto the controller we would drop a lot of
- * serial port characters. This requires we do extra locking, but we have
- * no real choice.
- */
-
-static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- unsigned long flags;
-
- /*
- * Avoid incoming interrupts between us flipping txing and flipping
- * mode as the driver assumes txing is a faithful indicator of card
- * state
- */
-
- spin_lock_irqsave(&lp->lock, flags);
-
- /*
- * Avoid timer-based retransmission conflicts.
- */
-
- netif_stop_queue(dev);
-
- do {
- int len = skb->len;
- int pad = 0;
- int gp_start;
- unsigned char *buf = skb->data;
-
- if (len < ETH_ZLEN)
- pad = ETH_ZLEN - len;
-
- gp_start = 0x800 - (len + pad);
-
- lp->tx_pkt_start = gp_start;
- lp->collisions = 0;
-
- dev->stats.tx_bytes += skb->len;
-
- /*
- * Command mode with status cleared should [in theory]
- * mean no more interrupts can be pending on the card.
- */
-
- outb_p(AX_SYS, AX_CMD);
- inb_p(RX_STATUS);
- inb_p(TX_STATUS);
-
- lp->loading = 1;
- lp->txing = 1;
-
- /*
- * Turn interrupts back on while we spend a pleasant
- * afternoon loading bytes into the board
- */
-
- spin_unlock_irqrestore(&lp->lock, flags);
-
- /* Set rx packet area to 0. */
- outw(0x00, RX_BUF_CLR);
- /* aim - packet will be loaded into buffer start */
- outw(gp_start, GP_LOW);
- /* load buffer (usual thing each byte increments the pointer) */
- outsb(DATAPORT, buf, len);
- if (pad) {
- while (pad--) /* Zero fill buffer tail */
- outb(0, DATAPORT);
- }
- /* the board reuses the same register */
- outw(gp_start, GP_LOW);
-
- if (lp->loading != 2) {
- /* fire ... Trigger xmit. */
- outb(AX_XMIT, AX_CMD);
- lp->loading = 0;
- dev->trans_start = jiffies;
- if (el_debug > 2)
- printk(KERN_DEBUG " queued xmit.\n");
- dev_kfree_skb(skb);
- return 0;
- }
- /* A receive upset our load, despite our best efforts */
- if (el_debug > 2)
- printk(KERN_DEBUG "%s: burped during tx load.\n",
- dev->name);
- spin_lock_irqsave(&lp->lock, flags);
- } while (1);
-}
-
-/**
- * el_interrupt:
- * @irq: Interrupt number
- * @dev_id: The 3c501 that burped
- *
- * Handle the ether interface interrupts. The 3c501 needs a lot more
- * hand holding than most cards. In particular we get a transmit interrupt
- * with a collision error because the board firmware isnt capable of rewinding
- * its own transmit buffer pointers. It can however count to 16 for us.
- *
- * On the receive side the card is also very dumb. It has no buffering to
- * speak of. We simply pull the packet out of its PIO buffer (which is slow)
- * and queue it for the kernel. Then we reset the card for the next packet.
- *
- * We sometimes get surprise interrupts late both because the SMP IRQ delivery
- * is message passing and because the card sometimes seems to deliver late. I
- * think if it is part way through a receive and the mode is changed it carries
- * on receiving and sends us an interrupt. We have to band aid all these cases
- * to get a sensible 150kBytes/second performance. Even then you want a small
- * TCP window.
- */
-
-static irqreturn_t el_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr;
- int axsr; /* Aux. status reg. */
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- spin_lock(&lp->lock);
-
- /*
- * What happened ?
- */
-
- axsr = inb(AX_STATUS);
-
- /*
- * Log it
- */
-
- if (el_debug > 3)
- printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x",
- dev->name, axsr);
-
- if (lp->loading == 1 && !lp->txing)
- printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
- dev->name);
-
- if (lp->txing) {
- /*
- * Board in transmit mode. May be loading. If we are
- * loading we shouldn't have got this.
- */
- int txsr = inb(TX_STATUS);
-
- if (lp->loading == 1) {
- if (el_debug > 2) {
- printk(KERN_DEBUG "%s: Interrupt while loading [",
- dev->name);
- printk(" txsr=%02x gp=%04x rp=%04x]\n",
- txsr, inw(GP_LOW), inw(RX_LOW));
- }
- /* Force a reload */
- lp->loading = 2;
- spin_unlock(&lp->lock);
- goto out;
- }
- if (el_debug > 6)
- printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x",
- txsr, inw(GP_LOW), inw(RX_LOW));
-
- if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
- /*
- * FIXME: is there a logic to whether to keep
- * on trying or reset immediately ?
- */
- if (el_debug > 1)
- printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
- dev->name, txsr, axsr,
- inw(ioaddr + EL1_DATAPTR),
- inw(ioaddr + EL1_RXPTR));
- lp->txing = 0;
- netif_wake_queue(dev);
- } else if (txsr & TX_16COLLISIONS) {
- /*
- * Timed out
- */
- if (el_debug)
- printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
- outb(AX_SYS, AX_CMD);
- lp->txing = 0;
- dev->stats.tx_aborted_errors++;
- netif_wake_queue(dev);
- } else if (txsr & TX_COLLISION) {
- /*
- * Retrigger xmit.
- */
-
- if (el_debug > 6)
- printk(KERN_DEBUG " retransmitting after a collision.\n");
- /*
- * Poor little chip can't reset its own start
- * pointer
- */
-
- outb(AX_SYS, AX_CMD);
- outw(lp->tx_pkt_start, GP_LOW);
- outb(AX_XMIT, AX_CMD);
- dev->stats.collisions++;
- spin_unlock(&lp->lock);
- goto out;
- } else {
- /*
- * It worked.. we will now fall through and receive
- */
- dev->stats.tx_packets++;
- if (el_debug > 6)
- printk(KERN_DEBUG " Tx succeeded %s\n",
- (txsr & TX_RDY) ? "." :
- "but tx is busy!");
- /*
- * This is safe the interrupt is atomic WRT itself.
- */
- lp->txing = 0;
- /* In case more to transmit */
- netif_wake_queue(dev);
- }
- } else {
- /*
- * In receive mode.
- */
-
- int rxsr = inb(RX_STATUS);
- if (el_debug > 5)
- printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW));
- /*
- * Just reading rx_status fixes most errors.
- */
- if (rxsr & RX_MISSED)
- dev->stats.rx_missed_errors++;
- else if (rxsr & RX_RUNT) {
- /* Handled to avoid board lock-up. */
- dev->stats.rx_length_errors++;
- if (el_debug > 5)
- printk(KERN_DEBUG " runt.\n");
- } else if (rxsr & RX_GOOD) {
- /*
- * Receive worked.
- */
- el_receive(dev);
- } else {
- /*
- * Nothing? Something is broken!
- */
- if (el_debug > 2)
- printk(KERN_DEBUG "%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
- dev->name, rxsr);
- el_reset(dev);
- }
- if (el_debug > 3)
- printk(KERN_DEBUG ".\n");
- }
-
- /*
- * Move into receive mode
- */
-
- outb(AX_RX, AX_CMD);
- outw(0x00, RX_BUF_CLR);
- inb(RX_STATUS); /* Be certain that interrupts are cleared. */
- inb(TX_STATUS);
- spin_unlock(&lp->lock);
-out:
- return IRQ_HANDLED;
-}
-
-
-/**
- * el_receive:
- * @dev: Device to pull the packets from
- *
- * We have a good packet. Well, not really "good", just mostly not broken.
- * We must check everything to see if it is good. In particular we occasionally
- * get wild packet sizes from the card. If the packet seems sane we PIO it
- * off the card and queue it for the protocol layers.
- */
-
-static void el_receive(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- int pkt_len;
- struct sk_buff *skb;
-
- pkt_len = inw(RX_LOW);
-
- if (el_debug > 4)
- printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
-
- if (pkt_len < 60 || pkt_len > 1536) {
- if (el_debug)
- printk(KERN_DEBUG "%s: bogus packet, length=%d\n",
- dev->name, pkt_len);
- dev->stats.rx_over_errors++;
- return;
- }
-
- /*
- * Command mode so we can empty the buffer
- */
-
- outb(AX_SYS, AX_CMD);
- skb = dev_alloc_skb(pkt_len+2);
-
- /*
- * Start of frame
- */
-
- outw(0x00, GP_LOW);
- if (skb == NULL) {
- printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- return;
- } else {
- skb_reserve(skb, 2); /* Force 16 byte alignment */
- /*
- * The read increments through the bytes. The interrupt
- * handler will fix the pointer when it returns to
- * receive mode.
- */
- insb(DATAPORT, skb_put(skb, pkt_len), pkt_len);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
- return;
-}
-
-/**
- * el_reset: Reset a 3c501 card
- * @dev: The 3c501 card about to get zapped
- *
- * Even resetting a 3c501 isnt simple. When you activate reset it loses all
- * its configuration. You must hold the lock when doing this. The function
- * cannot take the lock itself as it is callable from the irq handler.
- */
-
-static void el_reset(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if (el_debug > 2)
- printk(KERN_INFO "3c501 reset...");
- outb(AX_RESET, AX_CMD); /* Reset the chip */
- /* Aux control, irq and loopback enabled */
- outb(AX_LOOP, AX_CMD);
- {
- int i;
- for (i = 0; i < 6; i++) /* Set the station address. */
- outb(dev->dev_addr[i], ioaddr + i);
- }
-
- outw(0, RX_BUF_CLR); /* Set rx packet area to 0. */
- outb(TX_NORM, TX_CMD); /* tx irq on done, collision */
- outb(RX_NORM, RX_CMD); /* Set Rx commands. */
- inb(RX_STATUS); /* Clear status. */
- inb(TX_STATUS);
- lp->txing = 0;
-}
-
-/**
- * el1_close:
- * @dev: 3c501 card to shut down
- *
- * Close a 3c501 card. The IFF_UP flag has been cleared by the user via
- * the SIOCSIFFLAGS ioctl. We stop any further transmissions being queued,
- * and then disable the interrupts. Finally we reset the chip. The effects
- * of the rest will be cleaned up by #el1_open. Always returns 0 indicating
- * a success.
- */
-
-static int el1_close(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (el_debug > 2)
- printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n",
- dev->name, ioaddr);
-
- netif_stop_queue(dev);
-
- /*
- * Free and disable the IRQ.
- */
-
- free_irq(dev->irq, dev);
- outb(AX_RESET, AX_CMD); /* Reset the chip */
-
- return 0;
-}
-
-/**
- * set_multicast_list:
- * @dev: The device to adjust
- *
- * Set or clear the multicast filter for this adaptor to use the best-effort
- * filtering supported. The 3c501 supports only three modes of filtering.
- * It always receives broadcasts and packets for itself. You can choose to
- * optionally receive all packets, or all multicast packets on top of this.
- */
-
-static void set_multicast_list(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (dev->flags & IFF_PROMISC) {
- outb(RX_PROM, RX_CMD);
- inb(RX_STATUS);
- } else if (dev->mc_list || dev->flags & IFF_ALLMULTI) {
- /* Multicast or all multicast is the same */
- outb(RX_MULT, RX_CMD);
- inb(RX_STATUS); /* Clear status. */
- } else {
- outb(RX_NORM, RX_CMD);
- inb(RX_STATUS);
- }
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-#ifdef MODULE
-
-static struct net_device *dev_3c501;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "EtherLink I/O base address");
-MODULE_PARM_DESC(irq, "EtherLink IRQ number");
-
-/**
- * init_module:
- *
- * When the driver is loaded as a module this function is called. We fake up
- * a device structure with the base I/O and interrupt set as if it were being
- * called from Space.c. This minimises the extra code that would otherwise
- * be required.
- *
- * Returns 0 for success or -EIO if a card is not found. Returning an error
- * here also causes the module to be unloaded
- */
-
-int __init init_module(void)
-{
- dev_3c501 = el1_probe(-1);
- if (IS_ERR(dev_3c501))
- return PTR_ERR(dev_3c501);
- return 0;
-}
-
-/**
- * cleanup_module:
- *
- * The module is being unloaded. We unhook our network device from the system
- * and then free up the resources we took when the card was found.
- */
-
-void __exit cleanup_module(void)
-{
- struct net_device *dev = dev_3c501;
- unregister_netdev(dev);
- release_region(dev->base_addr, EL1_IO_EXTENT);
- free_netdev(dev);
-}
-
-#endif /* MODULE */
-
-MODULE_AUTHOR("Donald Becker, Alan Cox");
-MODULE_DESCRIPTION("Support for the ancient 3Com 3c501 ethernet card");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/net/3c501.h b/drivers/net/3c501.h
deleted file mode 100644
index cfec64efff7..00000000000
--- a/drivers/net/3c501.h
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Index to functions.
- */
-
-static int el1_probe1(struct net_device *dev, int ioaddr);
-static int el_open(struct net_device *dev);
-static void el_timeout(struct net_device *dev);
-static int el_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el_interrupt(int irq, void *dev_id);
-static void el_receive(struct net_device *dev);
-static void el_reset(struct net_device *dev);
-static int el1_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-#define EL1_IO_EXTENT 16
-
-#ifndef EL_DEBUG
-#define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */
-#endif /* Anything above 5 is wordy death! */
-#define debug el_debug
-static int el_debug = EL_DEBUG;
-
-/*
- * Board-specific info in dev->priv.
- */
-
-struct net_local
-{
- int tx_pkt_start; /* The length of the current Tx packet. */
- int collisions; /* Tx collisions this packet */
- int loading; /* Spot buffer load collisions */
- int txing; /* True if card is in TX mode */
- spinlock_t lock; /* Serializing lock */
-};
-
-
-#define RX_STATUS (ioaddr + 0x06)
-#define RX_CMD RX_STATUS
-#define TX_STATUS (ioaddr + 0x07)
-#define TX_CMD TX_STATUS
-#define GP_LOW (ioaddr + 0x08)
-#define GP_HIGH (ioaddr + 0x09)
-#define RX_BUF_CLR (ioaddr + 0x0A)
-#define RX_LOW (ioaddr + 0x0A)
-#define RX_HIGH (ioaddr + 0x0B)
-#define SAPROM (ioaddr + 0x0C)
-#define AX_STATUS (ioaddr + 0x0E)
-#define AX_CMD AX_STATUS
-#define DATAPORT (ioaddr + 0x0F)
-#define TX_RDY 0x08 /* In TX_STATUS */
-
-#define EL1_DATAPTR 0x08
-#define EL1_RXPTR 0x0A
-#define EL1_SAPROM 0x0C
-#define EL1_DATAPORT 0x0f
-
-/*
- * Writes to the ax command register.
- */
-
-#define AX_OFF 0x00 /* Irq off, buffer access on */
-#define AX_SYS 0x40 /* Load the buffer */
-#define AX_XMIT 0x44 /* Transmit a packet */
-#define AX_RX 0x48 /* Receive a packet */
-#define AX_LOOP 0x0C /* Loopback mode */
-#define AX_RESET 0x80
-
-/*
- * Normal receive mode written to RX_STATUS. We must intr on short packets
- * to avoid bogus rx lockups.
- */
-
-#define RX_NORM 0xA8 /* 0x68 == all addrs, 0xA8 only to me. */
-#define RX_PROM 0x68 /* Senior Prom, uhmm promiscuous mode. */
-#define RX_MULT 0xE8 /* Accept multicast packets. */
-#define TX_NORM 0x0A /* Interrupt on everything that might hang the chip */
-
-/*
- * TX_STATUS register.
- */
-
-#define TX_COLLISION 0x02
-#define TX_16COLLISIONS 0x04
-#define TX_READY 0x08
-
-#define RX_RUNT 0x08
-#define RX_MISSED 0x01 /* Missed a packet due to 3c501 braindamage. */
-#define RX_GOOD 0x30 /* Good packet 0x20, or simple overflow 0x10. */
-
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
deleted file mode 100644
index 900b0ffdcc6..00000000000
--- a/drivers/net/3c503.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/* 3c503.c: A shared-memory NS8390 ethernet driver for linux. */
-/*
- Written 1992-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
-
- This driver should work with the 3c503 and 3c503/16. It should be used
- in shared memory mode for best performance, although it may also work
- in programmed-I/O mode.
-
- Sources:
- EtherLink II Technical Reference Manual,
- EtherLink II/16 Technical Reference Manual Supplement,
- 3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145
-
- The Crynwr 3c503 packet driver.
-
- Changelog:
-
- Paul Gortmaker : add support for the 2nd 8kB of RAM on 16 bit cards.
- Paul Gortmaker : multiple card support for module users.
- rjohnson@analogic.com : Fix up PIO interface for efficient operation.
- Jeff Garzik : ethtool support
-
-*/
-
-#define DRV_NAME "3c503"
-#define DRV_VERSION "1.10a"
-#define DRV_RELDATE "11/17/2001"
-
-
-static const char version[] =
- DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/ethtool.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/byteorder.h>
-
-#include "8390.h"
-#include "3c503.h"
-#define WRD_COUNT 4
-
-static int el2_pio_probe(struct net_device *dev);
-static int el2_probe1(struct net_device *dev, int ioaddr);
-
-/* A zero-terminated list of I/O addresses to be probed in PIO mode. */
-static unsigned int netcard_portlist[] __initdata =
- { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
-
-#define EL2_IO_EXTENT 16
-
-static int el2_open(struct net_device *dev);
-static int el2_close(struct net_device *dev);
-static void el2_reset_8390(struct net_device *dev);
-static void el2_init_card(struct net_device *dev);
-static void el2_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page);
-static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb,
- int ring_offset);
-static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-
-/* This routine probes for a memory-mapped 3c503 board by looking for
- the "location register" at the end of the jumpered boot PROM space.
- This works even if a PROM isn't there.
-
- If the ethercard isn't found there is an optional probe for
- ethercard jumpered to programmed-I/O mode.
- */
-static int __init do_el2_probe(struct net_device *dev)
-{
- int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el2_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (addr = addrs; *addr; addr++) {
- void __iomem *p = ioremap(*addr, 1);
- unsigned base_bits;
- int i;
-
- if (!p)
- continue;
- base_bits = readb(p);
- iounmap(p);
- i = ffs(base_bits) - 1;
- if (i == -1 || base_bits != (1 << i))
- continue;
- if (el2_probe1(dev, netcard_portlist[i]) == 0)
- return 0;
- dev->irq = irq;
- }
-#if ! defined(no_probe_nonshared_memory)
- return el2_pio_probe(dev);
-#else
- return -ENODEV;
-#endif
-}
-
-/* Try all of the locations that aren't obviously empty. This touches
- a lot of locations, and is much riskier than the code above. */
-static int __init
-el2_pio_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el2_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (i = 0; netcard_portlist[i]; i++) {
- if (el2_probe1(dev, netcard_portlist[i]) == 0)
- return 0;
- dev->irq = irq;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init el2_probe(int unit)
-{
- struct net_device *dev = alloc_eip_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_el2_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-/* Probe for the Etherlink II card at I/O port base IOADDR,
- returning non-zero on success. If found, set the station
- address and memory parameters in DEVICE. */
-static int __init
-el2_probe1(struct net_device *dev, int ioaddr)
-{
- int i, iobase_reg, membase_reg, saved_406, wordlength, retval;
- static unsigned version_printed;
- unsigned long vendor_id;
- DECLARE_MAC_BUF(mac);
-
- if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) {
- retval = -EBUSY;
- goto out;
- }
-
- /* Reset and/or avoid any lurking NE2000 */
- if (inb(ioaddr + 0x408) == 0xff) {
- mdelay(1);
- retval = -ENODEV;
- goto out1;
- }
-
- /* We verify that it's a 3C503 board by checking the first three octets
- of its ethernet address. */
- iobase_reg = inb(ioaddr+0x403);
- membase_reg = inb(ioaddr+0x404);
- /* ASIC location registers should be 0 or have only a single bit set. */
- if ( (iobase_reg & (iobase_reg - 1))
- || (membase_reg & (membase_reg - 1))) {
- retval = -ENODEV;
- goto out1;
- }
- saved_406 = inb_p(ioaddr + 0x406);
- outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
- outb_p(ECNTRL_THIN, ioaddr + 0x406);
- /* Map the station addr PROM into the lower I/O ports. We now check
- for both the old and new 3Com prefix */
- outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
- vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2);
- if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) {
- /* Restore the register we frobbed. */
- outb(saved_406, ioaddr + 0x406);
- retval = -ENODEV;
- goto out1;
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- dev->base_addr = ioaddr;
-
- printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + i);
- printk("%s", print_mac(mac, dev->dev_addr));
-
- /* Map the 8390 back into the window. */
- outb(ECNTRL_THIN, ioaddr + 0x406);
-
- /* Check for EL2/16 as described in tech. man. */
- outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
- outb_p(0, ioaddr + EN0_DCFG);
- outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
- wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
- outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
-
- /* Probe for, turn on and clear the board's shared memory. */
- if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
- outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
-
- /* This should be probed for (or set via an ioctl()) at run-time.
- Right now we use a sleazy hack to pass in the interface number
- at boot-time via the low bits of the mem_end field. That value is
- unused, and the low bits would be discarded even if it was used. */
-#if defined(EI8390_THICK) || defined(EL2_AUI)
- ei_status.interface_num = 1;
-#else
- ei_status.interface_num = dev->mem_end & 0xf;
-#endif
- printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
-
- if ((membase_reg & 0xf0) == 0) {
- dev->mem_start = 0;
- ei_status.name = "3c503-PIO";
- ei_status.mem = NULL;
- } else {
- dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
- ((membase_reg & 0xA0) ? 0x4000 : 0);
-#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
- ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE);
-
-#ifdef EL2MEMTEST
- /* This has never found an error, but someone might care.
- Note that it only tests the 2nd 8kB on 16kB 3c503/16
- cards between card addr. 0x2000 and 0x3fff. */
- { /* Check the card's memory. */
- void __iomem *mem_base = ei_status.mem;
- unsigned int test_val = 0xbbadf00d;
- writel(0xba5eba5e, mem_base);
- for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
- writel(test_val, mem_base + i);
- if (readl(mem_base) != 0xba5eba5e
- || readl(mem_base + i) != test_val) {
- printk("3c503: memory failure or memory address conflict.\n");
- dev->mem_start = 0;
- ei_status.name = "3c503-PIO";
- iounmap(mem_base);
- ei_status.mem = NULL;
- break;
- }
- test_val += 0x55555555;
- writel(0, mem_base + i);
- }
- }
-#endif /* EL2MEMTEST */
-
- if (dev->mem_start)
- dev->mem_end = dev->mem_start + EL2_MEMSIZE;
-
- if (wordlength) { /* No Tx pages to skip over to get to Rx */
- ei_status.priv = 0;
- ei_status.name = "3c503/16";
- } else {
- ei_status.priv = TX_PAGES * 256;
- ei_status.name = "3c503";
- }
- }
-
- /*
- Divide up the memory on the card. This is the same regardless of
- whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
- we use the entire 8k of bank1 for an Rx ring. We only use 3k
- of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
- (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
- 5kB for an Rx ring. */
-
- if (wordlength) {
- ei_status.tx_start_page = EL2_MB0_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG;
- } else {
- ei_status.tx_start_page = EL2_MB1_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
- }
-
- /* Finish setting the board's parameters. */
- ei_status.stop_page = EL2_MB1_STOP_PG;
- ei_status.word16 = wordlength;
- ei_status.reset_8390 = &el2_reset_8390;
- ei_status.get_8390_hdr = &el2_get_8390_hdr;
- ei_status.block_input = &el2_block_input;
- ei_status.block_output = &el2_block_output;
-
- if (dev->irq == 2)
- dev->irq = 9;
- else if (dev->irq > 5 && dev->irq != 9) {
- printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
- dev->irq);
- dev->irq = 0;
- }
-
- ei_status.saved_irq = dev->irq;
-
- dev->open = &el2_open;
- dev->stop = &el2_close;
- dev->ethtool_ops = &netdev_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = eip_poll;
-#endif
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
-
- if (dev->mem_start)
- printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
- dev->name, ei_status.name, (wordlength+1)<<3,
- dev->mem_start, dev->mem_end-1);
-
- else
- {
- ei_status.tx_start_page = EL2_MB1_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
- printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
- dev->name, ei_status.name, (wordlength+1)<<3);
- }
- release_region(ioaddr + 0x400, 8);
- return 0;
-out1:
- release_region(ioaddr + 0x400, 8);
-out:
- release_region(ioaddr, EL2_IO_EXTENT);
- return retval;
-}
-
-static int
-el2_open(struct net_device *dev)
-{
- int retval = -EAGAIN;
-
- if (dev->irq < 2) {
- int irqlist[] = {5, 9, 3, 4, 0};
- int *irqp = irqlist;
-
- outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */
- do {
- if (request_irq (*irqp, NULL, 0, "bogus", dev) != -EBUSY) {
- /* Twinkle the interrupt, and check if it's seen. */
- unsigned long cookie = probe_irq_on();
- outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
- outb_p(0x00, E33G_IDCFR);
- if (*irqp == probe_irq_off(cookie) /* It's a good IRQ line! */
- && ((retval = request_irq(dev->irq = *irqp,
- eip_interrupt, 0, dev->name, dev)) == 0))
- break;
- }
- } while (*++irqp);
- if (*irqp == 0) {
- outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
- return retval;
- }
- } else {
- if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
- return retval;
- }
- }
-
- el2_init_card(dev);
- eip_open(dev);
- return 0;
-}
-
-static int
-el2_close(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- dev->irq = ei_status.saved_irq;
- outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
-
- eip_close(dev);
- return 0;
-}
-
-/* This is called whenever we have a unrecoverable failure:
- transmit timeout
- Bad ring buffer packet header
- */
-static void
-el2_reset_8390(struct net_device *dev)
-{
- if (ei_debug > 1) {
- printk("%s: Resetting the 3c503 board...", dev->name);
- printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
- E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
- }
- outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
- ei_status.txing = 0;
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
- el2_init_card(dev);
- if (ei_debug > 1) printk("done\n");
-}
-
-/* Initialize the 3c503 GA registers after a reset. */
-static void
-el2_init_card(struct net_device *dev)
-{
- /* Unmap the station PROM and select the DIX or BNC connector. */
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-
- /* Set ASIC copy of rx's first and last+1 buffer pages */
- /* These must be the same as in the 8390. */
- outb(ei_status.rx_start_page, E33G_STARTPG);
- outb(ei_status.stop_page, E33G_STOPPG);
-
- /* Point the vector pointer registers somewhere ?harmless?. */
- outb(0xff, E33G_VP2); /* Point at the ROM restart location 0xffff0 */
- outb(0xff, E33G_VP1);
- outb(0x00, E33G_VP0);
- /* Turn off all interrupts until we're opened. */
- outb_p(0x00, dev->base_addr + EN0_IMR);
- /* Enable IRQs iff started. */
- outb(EGACFR_NORM, E33G_GACFR);
-
- /* Set the interrupt line. */
- outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
- outb_p((WRD_COUNT << 1), E33G_DRQCNT); /* Set burst size to 8 */
- outb_p(0x20, E33G_DMAAH); /* Put a valid addr in the GA DMA */
- outb_p(0x00, E33G_DMAAL);
- return; /* We always succeed */
-}
-
-/*
- * Either use the shared memory (if enabled on the board) or put the packet
- * out through the ASIC FIFO.
- */
-static void
-el2_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- unsigned short int *wrd;
- int boguscount; /* timeout counter */
- unsigned short word; /* temporary for better machine code */
- void __iomem *base = ei_status.mem;
-
- if (ei_status.word16) /* Tx packets go into bank 0 on EL2/16 card */
- outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
- else
- outb(EGACFR_NORM, E33G_GACFR);
-
- if (base) { /* Shared memory transfer */
- memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8),
- buf, count);
- outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */
- return;
- }
-
-/*
- * No shared memory, put the packet out the other way.
- * Set up then start the internal memory transfer to Tx Start Page
- */
-
- word = (unsigned short)start_page;
- outb(word&0xFF, E33G_DMAAH);
- outb(word>>8, E33G_DMAAL);
-
- outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
- | ECNTRL_START, E33G_CNTRL);
-
-/*
- * Here I am going to write data to the FIFO as quickly as possible.
- * Note that E33G_FIFOH is defined incorrectly. It is really
- * E33G_FIFOL, the lowest port address for both the byte and
- * word write. Variable 'count' is NOT checked. Caller must supply a
- * valid count. Note that I may write a harmless extra byte to the
- * 8390 if the byte-count was not even.
- */
- wrd = (unsigned short int *) buf;
- count = (count + 1) >> 1;
- for(;;)
- {
- boguscount = 0x1000;
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- {
- if(!boguscount--)
- {
- printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
- el2_reset_8390(dev);
- goto blocked;
- }
- }
- if(count > WRD_COUNT)
- {
- outsw(E33G_FIFOH, wrd, WRD_COUNT);
- wrd += WRD_COUNT;
- count -= WRD_COUNT;
- }
- else
- {
- outsw(E33G_FIFOH, wrd, count);
- break;
- }
- }
- blocked:;
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
- return;
-}
-
-/* Read the 4 byte, page aligned 8390 specific header. */
-static void
-el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int boguscount;
- void __iomem *base = ei_status.mem;
- unsigned short word;
-
- if (base) { /* Use the shared memory. */
- void __iomem *hdr_start = base + ((ring_page - EL2_MB1_START_PG)<<8);
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
- hdr->count = le16_to_cpu(hdr->count);
- return;
- }
-
-/*
- * No shared memory, use programmed I/O.
- */
-
- word = (unsigned short)ring_page;
- outb(word&0xFF, E33G_DMAAH);
- outb(word>>8, E33G_DMAAL);
-
- outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
- | ECNTRL_START, E33G_CNTRL);
- boguscount = 0x1000;
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- {
- if(!boguscount--)
- {
- printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
- memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
- el2_reset_8390(dev);
- goto blocked;
- }
- }
- insw(E33G_FIFOH, hdr, (sizeof(struct e8390_pkt_hdr))>> 1);
- blocked:;
- outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-
-static void
-el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int boguscount = 0;
- void __iomem *base = ei_status.mem;
- unsigned short int *buf;
- unsigned short word;
-
- /* Maybe enable shared memory just be to be safe... nahh.*/
- if (base) { /* Use the shared memory. */
- ring_offset -= (EL2_MB1_START_PG<<8);
- if (ring_offset + count > EL2_MEMSIZE) {
- /* We must wrap the input move. */
- int semi_count = EL2_MEMSIZE - ring_offset;
- memcpy_fromio(skb->data, base + ring_offset, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count);
- } else {
- memcpy_fromio(skb->data, base + ring_offset, count);
- }
- return;
- }
-
-/*
- * No shared memory, use programmed I/O.
- */
- word = (unsigned short) ring_offset;
- outb(word>>8, E33G_DMAAH);
- outb(word&0xFF, E33G_DMAAL);
-
- outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
- | ECNTRL_START, E33G_CNTRL);
-
-/*
- * Here I also try to get data as fast as possible. I am betting that I
- * can read one extra byte without clobbering anything in the kernel because
- * this would only occur on an odd byte-count and allocation of skb->data
- * is word-aligned. Variable 'count' is NOT checked. Caller must check
- * for a valid count.
- * [This is currently quite safe.... but if one day the 3c503 explodes
- * you know where to come looking ;)]
- */
-
- buf = (unsigned short int *) skb->data;
- count = (count + 1) >> 1;
- for(;;)
- {
- boguscount = 0x1000;
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- {
- if(!boguscount--)
- {
- printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
- el2_reset_8390(dev);
- goto blocked;
- }
- }
- if(count > WRD_COUNT)
- {
- insw(E33G_FIFOH, buf, WRD_COUNT);
- buf += WRD_COUNT;
- count -= WRD_COUNT;
- }
- else
- {
- insw(E33G_FIFOH, buf, count);
- break;
- }
- }
- blocked:;
- outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
- return;
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
-#ifdef MODULE
-#define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */
-
-static struct net_device *dev_el2[MAX_EL2_CARDS];
-static int io[MAX_EL2_CARDS];
-static int irq[MAX_EL2_CARDS];
-static int xcvr[MAX_EL2_CARDS]; /* choose int. or ext. xcvr */
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(xcvr, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
-MODULE_DESCRIPTION("3Com ISA EtherLink II, II/16 (3c503, 3c503/16) driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int __init
-init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- dev = alloc_eip_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */
- if (do_el2_probe(dev) == 0) {
- dev_el2[found++] = dev;
- continue;
- }
- free_netdev(dev);
- printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: el2_close() handles free_irq */
- release_region(dev->base_addr, EL2_IO_EXTENT);
- if (ei_status.mem)
- iounmap(ei_status.mem);
-}
-
-void __exit
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
- struct net_device *dev = dev_el2[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/3c503.h b/drivers/net/3c503.h
deleted file mode 100644
index e2367b82a2e..00000000000
--- a/drivers/net/3c503.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Definitions for the 3Com 3c503 Etherlink 2. */
-/* This file is distributed under the GPL.
- Many of these names and comments are directly from the Crynwr packet
- drivers, which are released under the GPL. */
-
-#define EL2H (dev->base_addr + 0x400)
-#define EL2L (dev->base_addr)
-
-/* Vendor unique hardware addr. prefix. 3Com has 2 because they ran
- out of available addresses on the first one... */
-
-#define OLD_3COM_ID 0x02608c
-#define NEW_3COM_ID 0x0020af
-
-/* Shared memory management parameters. NB: The 8 bit cards have only
- one bank (MB1) which serves both Tx and Rx packet space. The 16bit
- cards have 2 banks, MB0 for Tx packets, and MB1 for Rx packets.
- You choose which bank appears in the sh. mem window with EGACFR_MBSn */
-
-#define EL2_MB0_START_PG (0x00) /* EL2/16 Tx packets go in bank 0 */
-#define EL2_MB1_START_PG (0x20) /* First page of bank 1 */
-#define EL2_MB1_STOP_PG (0x40) /* Last page +1 of bank 1 */
-
-/* 3Com 3c503 ASIC registers */
-#define E33G_STARTPG (EL2H+0) /* Start page, matching EN0_STARTPG */
-#define E33G_STOPPG (EL2H+1) /* Stop page, must match EN0_STOPPG */
-#define E33G_DRQCNT (EL2H+2) /* DMA burst count */
-#define E33G_IOBASE (EL2H+3) /* Read of I/O base jumpers. */
- /* (non-useful, but it also appears at the end of EPROM space) */
-#define E33G_ROMBASE (EL2H+4) /* Read of memory base jumpers. */
-#define E33G_GACFR (EL2H+5) /* Config/setup bits for the ASIC GA */
-#define E33G_CNTRL (EL2H+6) /* Board's main control register */
-#define E33G_STATUS (EL2H+7) /* Status on completions. */
-#define E33G_IDCFR (EL2H+8) /* Interrupt/DMA config register */
- /* (Which IRQ to assert, DMA chan to use) */
-#define E33G_DMAAH (EL2H+9) /* High byte of DMA address reg */
-#define E33G_DMAAL (EL2H+10) /* Low byte of DMA address reg */
-/* "Vector pointer" - if this address matches a read, the EPROM (rather than
- shared RAM) is mapped into memory space. */
-#define E33G_VP2 (EL2H+11)
-#define E33G_VP1 (EL2H+12)
-#define E33G_VP0 (EL2H+13)
-#define E33G_FIFOH (EL2H+14) /* FIFO for programmed I/O moves */
-#define E33G_FIFOL (EL2H+15) /* ... low byte of above. */
-
-/* Bits in E33G_CNTRL register: */
-
-#define ECNTRL_RESET (0x01) /* Software reset of the ASIC and 8390 */
-#define ECNTRL_THIN (0x02) /* Onboard xcvr enable, AUI disable */
-#define ECNTRL_AUI (0x00) /* Onboard xcvr disable, AUI enable */
-#define ECNTRL_SAPROM (0x04) /* Map the station address prom */
-#define ECNTRL_DBLBFR (0x20) /* FIFO configuration bit */
-#define ECNTRL_OUTPUT (0x40) /* PC-to-3C503 direction if 1 */
-#define ECNTRL_INPUT (0x00) /* 3C503-to-PC direction if 0 */
-#define ECNTRL_START (0x80) /* Start the DMA logic */
-
-/* Bits in E33G_STATUS register: */
-
-#define ESTAT_DPRDY (0x80) /* Data port (of FIFO) ready */
-#define ESTAT_UFLW (0x40) /* Tried to read FIFO when it was empty */
-#define ESTAT_OFLW (0x20) /* Tried to write FIFO when it was full */
-#define ESTAT_DTC (0x10) /* Terminal Count from PC bus DMA logic */
-#define ESTAT_DIP (0x08) /* DMA In Progress */
-
-/* Bits in E33G_GACFR register: */
-
-#define EGACFR_NIM (0x80) /* NIC interrupt mask */
-#define EGACFR_TCM (0x40) /* DMA term. count interrupt mask */
-#define EGACFR_RSEL (0x08) /* Map a bank of card mem into system mem */
-#define EGACFR_MBS2 (0x04) /* Memory bank select, bit 2. */
-#define EGACFR_MBS1 (0x02) /* Memory bank select, bit 1. */
-#define EGACFR_MBS0 (0x01) /* Memory bank select, bit 0. */
-
-#define EGACFR_NORM (0x49) /* TCM | RSEL | MBS0 */
-#define EGACFR_IRQOFF (0xc9) /* TCM | RSEL | MBS0 | NIM */
-
-/*
- MBS2 MBS1 MBS0 Sh. mem windows card mem at:
- ---- ---- ---- -----------------------------
- 0 0 0 0x0000 -- bank 0
- 0 0 1 0x2000 -- bank 1 (only choice for 8bit card)
- 0 1 0 0x4000 -- bank 2, not used
- 0 1 1 0x6000 -- bank 3, not used
-
-There was going to be a 32k card that used bank 2 and 3, but it
-never got produced.
-
-*/
-
-
-/* End of 3C503 parameter definitions */
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
deleted file mode 100644
index fdfb2b2cb73..00000000000
--- a/drivers/net/3c505.c
+++ /dev/null
@@ -1,1668 +0,0 @@
-/*
- * Linux Ethernet device driver for the 3Com Etherlink Plus (3C505)
- * By Craig Southeren, Juha Laiho and Philip Blundell
- *
- * 3c505.c This module implements an interface to the 3Com
- * Etherlink Plus (3c505) Ethernet card. Linux device
- * driver interface reverse engineered from the Linux 3C509
- * device drivers. Some 3C505 information gleaned from
- * the Crynwr packet driver. Still this driver would not
- * be here without 3C505 technical reference provided by
- * 3Com.
- *
- * $Id: 3c505.c,v 1.10 1996/04/16 13:06:27 phil Exp $
- *
- * Authors: Linux 3c505 device driver by
- * Craig Southeren, <craigs@ineluki.apana.org.au>
- * Final debugging by
- * Andrew Tridgell, <tridge@nimbus.anu.edu.au>
- * Auto irq/address, tuning, cleanup and v1.1.4+ kernel mods by
- * Juha Laiho, <jlaiho@ichaos.nullnet.fi>
- * Linux 3C509 driver by
- * Donald Becker, <becker@super.org>
- * (Now at <becker@scyld.com>)
- * Crynwr packet driver by
- * Krishnan Gopalan and Gregg Stefancik,
- * Clemson University Engineering Computer Operations.
- * Portions of the code have been adapted from the 3c505
- * driver for NCSA Telnet by Bruce Orchard and later
- * modified by Warren Van Houten and krus@diku.dk.
- * 3C505 technical information provided by
- * Terry Murphy, of 3Com Network Adapter Division
- * Linux 1.3.0 changes by
- * Alan Cox <Alan.Cox@linux.org>
- * More debugging, DMA support, currently maintained by
- * Philip Blundell <philb@gnu.org>
- * Multicard/soft configurable dma channel/rev 2 hardware support
- * by Christopher Collins <ccollins@pcug.org.au>
- * Ethtool support (jgarzik), 11/17/2001
- */
-
-#define DRV_NAME "3c505"
-#define DRV_VERSION "1.10a"
-
-
-/* Theory of operation:
- *
- * The 3c505 is quite an intelligent board. All communication with it is done
- * by means of Primary Command Blocks (PCBs); these are transferred using PIO
- * through the command register. The card has 256k of on-board RAM, which is
- * used to buffer received packets. It might seem at first that more buffers
- * are better, but in fact this isn't true. From my tests, it seems that
- * more than about 10 buffers are unnecessary, and there is a noticeable
- * performance hit in having more active on the card. So the majority of the
- * card's memory isn't, in fact, used. Sadly, the card only has one transmit
- * buffer and, short of loading our own firmware into it (which is what some
- * drivers resort to) there's nothing we can do about this.
- *
- * We keep up to 4 "receive packet" commands active on the board at a time.
- * When a packet comes in, so long as there is a receive command active, the
- * board will send us a "packet received" PCB and then add the data for that
- * packet to the DMA queue. If a DMA transfer is not already in progress, we
- * set one up to start uploading the data. We have to maintain a list of
- * backlogged receive packets, because the card may decide to tell us about
- * a newly-arrived packet at any time, and we may not be able to start a DMA
- * transfer immediately (ie one may already be going on). We can't NAK the
- * PCB, because then it would throw the packet away.
- *
- * Trying to send a PCB to the card at the wrong moment seems to have bad
- * effects. If we send it a transmit PCB while a receive DMA is happening,
- * it will just NAK the PCB and so we will have wasted our time. Worse, it
- * sometimes seems to interrupt the transfer. The majority of the low-level
- * code is protected by one huge semaphore -- "busy" -- which is set whenever
- * it probably isn't safe to do anything to the card. The receive routine
- * must gain a lock on "busy" before it can start a DMA transfer, and the
- * transmit routine must gain a lock before it sends the first PCB to the card.
- * The send_pcb() routine also has an internal semaphore to protect it against
- * being re-entered (which would be disastrous) -- this is needed because
- * several things can happen asynchronously (re-priming the receiver and
- * asking the card for statistics, for example). send_pcb() will also refuse
- * to talk to the card at all if a DMA upload is happening. The higher-level
- * networking code will reschedule a later retry if some part of the driver
- * is blocked. In practice, this doesn't seem to happen very often.
- */
-
-/* This driver may now work with revision 2.x hardware, since all the read
- * operations on the HCR have been removed (we now keep our own softcopy).
- * But I don't have an old card to test it on.
- *
- * This has had the bad effect that the autoprobe routine is now a bit
- * less friendly to other devices. However, it was never very good.
- * before, so I doubt it will hurt anybody.
- */
-
-/* The driver is a mess. I took Craig's and Juha's code, and hacked it firstly
- * to make it more reliable, and secondly to add DMA mode. Many things could
- * probably be done better; the concurrency protection is particularly awful.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-
-#include "3c505.h"
-
-/*********************************************************
- *
- * define debug messages here as common strings to reduce space
- *
- *********************************************************/
-
-static const char filename[] = __FILE__;
-
-static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
-#define TIMEOUT_MSG(lineno) \
- printk(timeout_msg, filename,__FUNCTION__,(lineno))
-
-static const char invalid_pcb_msg[] =
-"*** invalid pcb length %d at %s:%s (line %d) ***\n";
-#define INVALID_PCB_MSG(len) \
- printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
-
-static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
-
-static char stilllooking_msg[] __initdata = "still looking...";
-
-static char found_msg[] __initdata = "found.\n";
-
-static char notfound_msg[] __initdata = "not found (reason = %d)\n";
-
-static char couldnot_msg[] __initdata = KERN_INFO "%s: 3c505 not found\n";
-
-/*********************************************************
- *
- * various other debug stuff
- *
- *********************************************************/
-
-#ifdef ELP_DEBUG
-static int elp_debug = ELP_DEBUG;
-#else
-static int elp_debug;
-#endif
-#define debug elp_debug
-
-/*
- * 0 = no messages (well, some)
- * 1 = messages when high level commands performed
- * 2 = messages when low level commands performed
- * 3 = messages when interrupts received
- */
-
-/*****************************************************************
- *
- * List of I/O-addresses we try to auto-sense
- * Last element MUST BE 0!
- *****************************************************************/
-
-static int addr_list[] __initdata = {0x300, 0x280, 0x310, 0};
-
-/* Dma Memory related stuff */
-
-static unsigned long dma_mem_alloc(int size)
-{
- int order = get_order(size);
- return __get_dma_pages(GFP_KERNEL, order);
-}
-
-
-/*****************************************************************
- *
- * Functions for I/O (note the inline !)
- *
- *****************************************************************/
-
-static inline unsigned char inb_status(unsigned int base_addr)
-{
- return inb(base_addr + PORT_STATUS);
-}
-
-static inline int inb_command(unsigned int base_addr)
-{
- return inb(base_addr + PORT_COMMAND);
-}
-
-static inline void outb_control(unsigned char val, struct net_device *dev)
-{
- outb(val, dev->base_addr + PORT_CONTROL);
- ((elp_device *)(dev->priv))->hcr_val = val;
-}
-
-#define HCR_VAL(x) (((elp_device *)((x)->priv))->hcr_val)
-
-static inline void outb_command(unsigned char val, unsigned int base_addr)
-{
- outb(val, base_addr + PORT_COMMAND);
-}
-
-static inline unsigned int backlog_next(unsigned int n)
-{
- return (n + 1) % BACKLOG_SIZE;
-}
-
-/*****************************************************************
- *
- * useful functions for accessing the adapter
- *
- *****************************************************************/
-
-/*
- * use this routine when accessing the ASF bits as they are
- * changed asynchronously by the adapter
- */
-
-/* get adapter PCB status */
-#define GET_ASF(addr) \
- (get_status(addr)&ASF_PCB_MASK)
-
-static inline int get_status(unsigned int base_addr)
-{
- unsigned long timeout = jiffies + 10*HZ/100;
- register int stat1;
- do {
- stat1 = inb_status(base_addr);
- } while (stat1 != inb_status(base_addr) && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- return stat1;
-}
-
-static inline void set_hsf(struct net_device *dev, int hsf)
-{
- elp_device *adapter = dev->priv;
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->lock, flags);
- outb_control((HCR_VAL(dev) & ~HSF_PCB_MASK) | hsf, dev);
- spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static bool start_receive(struct net_device *, pcb_struct *);
-
-static inline void adapter_reset(struct net_device *dev)
-{
- unsigned long timeout;
- elp_device *adapter = dev->priv;
- unsigned char orig_hcr = adapter->hcr_val;
-
- outb_control(0, dev);
-
- if (inb_status(dev->base_addr) & ACRF) {
- do {
- inb_command(dev->base_addr);
- timeout = jiffies + 2*HZ/100;
- while (time_before_eq(jiffies, timeout) && !(inb_status(dev->base_addr) & ACRF));
- } while (inb_status(dev->base_addr) & ACRF);
- set_hsf(dev, HSF_PCB_NAK);
- }
- outb_control(adapter->hcr_val | ATTN | DIR, dev);
- mdelay(10);
- outb_control(adapter->hcr_val & ~ATTN, dev);
- mdelay(10);
- outb_control(adapter->hcr_val | FLSH, dev);
- mdelay(10);
- outb_control(adapter->hcr_val & ~FLSH, dev);
- mdelay(10);
-
- outb_control(orig_hcr, dev);
- if (!start_receive(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: start receive command failed \n", dev->name);
-}
-
-/* Check to make sure that a DMA transfer hasn't timed out. This should
- * never happen in theory, but seems to occur occasionally if the card gets
- * prodded at the wrong time.
- */
-static inline void check_3c505_dma(struct net_device *dev)
-{
- elp_device *adapter = dev->priv;
- if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
- unsigned long flags, f;
- printk(KERN_ERR "%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
- spin_lock_irqsave(&adapter->lock, flags);
- adapter->dmaing = 0;
- adapter->busy = 0;
-
- f=claim_dma_lock();
- disable_dma(dev->dma);
- release_dma_lock(f);
-
- if (adapter->rx_active)
- adapter->rx_active--;
- outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
- spin_unlock_irqrestore(&adapter->lock, flags);
- }
-}
-
-/* Primitive functions used by send_pcb() */
-static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte)
-{
- unsigned long timeout;
- outb_command(byte, base_addr);
- for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
- if (inb_status(base_addr) & HCRE)
- return false;
- }
- printk(KERN_WARNING "3c505: send_pcb_slow timed out\n");
- return true;
-}
-
-static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
-{
- unsigned int timeout;
- outb_command(byte, base_addr);
- for (timeout = 0; timeout < 40000; timeout++) {
- if (inb_status(base_addr) & HCRE)
- return false;
- }
- printk(KERN_WARNING "3c505: send_pcb_fast timed out\n");
- return true;
-}
-
-/* Check to see if the receiver needs restarting, and kick it if so */
-static inline void prime_rx(struct net_device *dev)
-{
- elp_device *adapter = dev->priv;
- while (adapter->rx_active < ELP_RX_PCBS && netif_running(dev)) {
- if (!start_receive(dev, &adapter->itx_pcb))
- break;
- }
-}
-
-/*****************************************************************
- *
- * send_pcb
- * Send a PCB to the adapter.
- *
- * output byte to command reg --<--+
- * wait until HCRE is non zero |
- * loop until all bytes sent -->--+
- * set HSF1 and HSF2 to 1
- * output pcb length
- * wait until ASF give ACK or NAK
- * set HSF1 and HSF2 to 0
- *
- *****************************************************************/
-
-/* This can be quite slow -- the adapter is allowed to take up to 40ms
- * to respond to the initial interrupt.
- *
- * We run initially with interrupts turned on, but with a semaphore set
- * so that nobody tries to re-enter this code. Once the first byte has
- * gone through, we turn interrupts off and then send the others (the
- * timeout is reduced to 500us).
- */
-
-static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
-{
- int i;
- unsigned long timeout;
- elp_device *adapter = dev->priv;
- unsigned long flags;
-
- check_3c505_dma(dev);
-
- if (adapter->dmaing && adapter->current_dma.direction == 0)
- return false;
-
- /* Avoid contention */
- if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
- if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: send_pcb entered while threaded\n", dev->name);
- }
- return false;
- }
- /*
- * load each byte into the command register and
- * wait for the HCRE bit to indicate the adapter
- * had read the byte
- */
- set_hsf(dev, 0);
-
- if (send_pcb_slow(dev->base_addr, pcb->command))
- goto abort;
-
- spin_lock_irqsave(&adapter->lock, flags);
-
- if (send_pcb_fast(dev->base_addr, pcb->length))
- goto sti_abort;
-
- for (i = 0; i < pcb->length; i++) {
- if (send_pcb_fast(dev->base_addr, pcb->data.raw[i]))
- goto sti_abort;
- }
-
- outb_control(adapter->hcr_val | 3, dev); /* signal end of PCB */
- outb_command(2 + pcb->length, dev->base_addr);
-
- /* now wait for the acknowledgement */
- spin_unlock_irqrestore(&adapter->lock, flags);
-
- for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
- switch (GET_ASF(dev->base_addr)) {
- case ASF_PCB_ACK:
- adapter->send_pcb_semaphore = 0;
- return true;
-
- case ASF_PCB_NAK:
-#ifdef ELP_DEBUG
- printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name);
-#endif
- goto abort;
- }
- }
-
- if (elp_debug >= 1)
- printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr));
- goto abort;
-
- sti_abort:
- spin_unlock_irqrestore(&adapter->lock, flags);
- abort:
- adapter->send_pcb_semaphore = 0;
- return false;
-}
-
-
-/*****************************************************************
- *
- * receive_pcb
- * Read a PCB from the adapter
- *
- * wait for ACRF to be non-zero ---<---+
- * input a byte |
- * if ASF1 and ASF2 were not both one |
- * before byte was read, loop --->---+
- * set HSF1 and HSF2 for ack
- *
- *****************************************************************/
-
-static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
-{
- int i, j;
- int total_length;
- int stat;
- unsigned long timeout;
- unsigned long flags;
-
- elp_device *adapter = dev->priv;
-
- set_hsf(dev, 0);
-
- /* get the command code */
- timeout = jiffies + 2*HZ/100;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- return false;
- }
- pcb->command = inb_command(dev->base_addr);
-
- /* read the data length */
- timeout = jiffies + 3*HZ/100;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- printk(KERN_INFO "%s: status %02x\n", dev->name, stat);
- return false;
- }
- pcb->length = inb_command(dev->base_addr);
-
- if (pcb->length > MAX_PCB_DATA) {
- INVALID_PCB_MSG(pcb->length);
- adapter_reset(dev);
- return false;
- }
- /* read the data */
- spin_lock_irqsave(&adapter->lock, flags);
- i = 0;
- do {
- j = 0;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000);
- pcb->data.raw[i++] = inb_command(dev->base_addr);
- if (i > MAX_PCB_DATA)
- INVALID_PCB_MSG(i);
- } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000);
- spin_unlock_irqrestore(&adapter->lock, flags);
- if (j >= 20000) {
- TIMEOUT_MSG(__LINE__);
- return false;
- }
- /* woops, the last "data" byte was really the length! */
- total_length = pcb->data.raw[--i];
-
- /* safety check total length vs data length */
- if (total_length != (pcb->length + 2)) {
- if (elp_debug >= 2)
- printk(KERN_WARNING "%s: mangled PCB received\n", dev->name);
- set_hsf(dev, HSF_PCB_NAK);
- return false;
- }
-
- if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) {
- if (test_and_set_bit(0, (void *) &adapter->busy)) {
- if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
- set_hsf(dev, HSF_PCB_NAK);
- printk(KERN_WARNING "%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
- pcb->command = 0;
- return true;
- } else {
- pcb->command = 0xff;
- }
- }
- }
- set_hsf(dev, HSF_PCB_ACK);
- return true;
-}
-
-/******************************************************
- *
- * queue a receive command on the adapter so we will get an
- * interrupt when a packet is received.
- *
- ******************************************************/
-
-static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
-{
- bool status;
- elp_device *adapter = dev->priv;
-
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: restarting receiver\n", dev->name);
- tx_pcb->command = CMD_RECEIVE_PACKET;
- tx_pcb->length = sizeof(struct Rcv_pkt);
- tx_pcb->data.rcv_pkt.buf_seg
- = tx_pcb->data.rcv_pkt.buf_ofs = 0; /* Unused */
- tx_pcb->data.rcv_pkt.buf_len = 1600;
- tx_pcb->data.rcv_pkt.timeout = 0; /* set timeout to zero */
- status = send_pcb(dev, tx_pcb);
- if (status)
- adapter->rx_active++;
- return status;
-}
-
-/******************************************************
- *
- * extract a packet from the adapter
- * this routine is only called from within the interrupt
- * service routine, so no cli/sti calls are needed
- * note that the length is always assumed to be even
- *
- ******************************************************/
-
-static void receive_packet(struct net_device *dev, int len)
-{
- int rlen;
- elp_device *adapter = dev->priv;
- void *target;
- struct sk_buff *skb;
- unsigned long flags;
-
- rlen = (len + 1) & ~1;
- skb = dev_alloc_skb(rlen + 2);
-
- if (!skb) {
- printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
- target = adapter->dma_buffer;
- adapter->current_dma.target = NULL;
- /* FIXME: stats */
- return;
- }
-
- skb_reserve(skb, 2);
- target = skb_put(skb, rlen);
- if ((unsigned long)(target + rlen) >= MAX_DMA_ADDRESS) {
- adapter->current_dma.target = target;
- target = adapter->dma_buffer;
- } else {
- adapter->current_dma.target = NULL;
- }
-
- /* if this happens, we die */
- if (test_and_set_bit(0, (void *) &adapter->dmaing))
- printk(KERN_ERR "%s: rx blocked, DMA in progress, dir %d\n", dev->name, adapter->current_dma.direction);
-
- adapter->current_dma.direction = 0;
- adapter->current_dma.length = rlen;
- adapter->current_dma.skb = skb;
- adapter->current_dma.start_time = jiffies;
-
- outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev);
-
- flags=claim_dma_lock();
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, 0x04); /* dma read */
- set_dma_addr(dev->dma, isa_virt_to_bus(target));
- set_dma_count(dev->dma, rlen);
- enable_dma(dev->dma);
- release_dma_lock(flags);
-
- if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: rx DMA transfer started\n", dev->name);
- }
-
- if (adapter->rx_active)
- adapter->rx_active--;
-
- if (!adapter->busy)
- printk(KERN_WARNING "%s: receive_packet called, busy not set.\n", dev->name);
-}
-
-/******************************************************
- *
- * interrupt handler
- *
- ******************************************************/
-
-static irqreturn_t elp_interrupt(int irq, void *dev_id)
-{
- int len;
- int dlen;
- int icount = 0;
- struct net_device *dev;
- elp_device *adapter;
- unsigned long timeout;
-
- dev = dev_id;
- adapter = (elp_device *) dev->priv;
-
- spin_lock(&adapter->lock);
-
- do {
- /*
- * has a DMA transfer finished?
- */
- if (inb_status(dev->base_addr) & DONE) {
- if (!adapter->dmaing) {
- printk(KERN_WARNING "%s: phantom DMA completed\n", dev->name);
- }
- if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr));
- }
-
- outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
- if (adapter->current_dma.direction) {
- dev_kfree_skb_irq(adapter->current_dma.skb);
- } else {
- struct sk_buff *skb = adapter->current_dma.skb;
- if (skb) {
- if (adapter->current_dma.target) {
- /* have already done the skb_put() */
- memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length);
- }
- skb->protocol = eth_type_trans(skb,dev);
- dev->stats.rx_bytes += skb->len;
- netif_rx(skb);
- dev->last_rx = jiffies;
- }
- }
- adapter->dmaing = 0;
- if (adapter->rx_backlog.in != adapter->rx_backlog.out) {
- int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
- adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
- if (elp_debug >= 2)
- printk(KERN_DEBUG "%s: receiving backlogged packet (%d)\n", dev->name, t);
- receive_packet(dev, t);
- } else {
- adapter->busy = 0;
- }
- } else {
- /* has one timed out? */
- check_3c505_dma(dev);
- }
-
- /*
- * receive a PCB from the adapter
- */
- timeout = jiffies + 3*HZ/100;
- while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) {
- if (receive_pcb(dev, &adapter->irx_pcb)) {
- switch (adapter->irx_pcb.command)
- {
- case 0:
- break;
- /*
- * received a packet - this must be handled fast
- */
- case 0xff:
- case CMD_RECEIVE_PACKET_COMPLETE:
- /* if the device isn't open, don't pass packets up the stack */
- if (!netif_running(dev))
- break;
- len = adapter->irx_pcb.data.rcv_resp.pkt_len;
- dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
- if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
- printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name);
- } else {
- if (elp_debug >= 3) {
- printk(KERN_DEBUG "%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
- }
- if (adapter->irx_pcb.command == 0xff) {
- if (elp_debug >= 2)
- printk(KERN_DEBUG "%s: adding packet to backlog (len = %d)\n", dev->name, dlen);
- adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
- adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
- } else {
- receive_packet(dev, dlen);
- }
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: packet received\n", dev->name);
- }
- break;
-
- /*
- * 82586 configured correctly
- */
- case CMD_CONFIGURE_82586_RESPONSE:
- adapter->got[CMD_CONFIGURE_82586] = 1;
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: interrupt - configure response received\n", dev->name);
- break;
-
- /*
- * Adapter memory configuration
- */
- case CMD_CONFIGURE_ADAPTER_RESPONSE:
- adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: Adapter memory configuration %s.\n", dev->name,
- adapter->irx_pcb.data.failed ? "failed" : "succeeded");
- break;
-
- /*
- * Multicast list loading
- */
- case CMD_LOAD_MULTICAST_RESPONSE:
- adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: Multicast address list loading %s.\n", dev->name,
- adapter->irx_pcb.data.failed ? "failed" : "succeeded");
- break;
-
- /*
- * Station address setting
- */
- case CMD_SET_ADDRESS_RESPONSE:
- adapter->got[CMD_SET_STATION_ADDRESS] = 1;
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: Ethernet address setting %s.\n", dev->name,
- adapter->irx_pcb.data.failed ? "failed" : "succeeded");
- break;
-
-
- /*
- * received board statistics
- */
- case CMD_NETWORK_STATISTICS_RESPONSE:
- dev->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv;
- dev->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit;
- dev->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC;
- dev->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align;
- dev->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun;
- dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
- adapter->got[CMD_NETWORK_STATISTICS] = 1;
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name);
- break;
-
- /*
- * sent a packet
- */
- case CMD_TRANSMIT_PACKET_COMPLETE:
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: interrupt - packet sent\n", dev->name);
- if (!netif_running(dev))
- break;
- switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
- case 0xffff:
- dev->stats.tx_aborted_errors++;
- printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name);
- break;
- case 0xfffe:
- dev->stats.tx_fifo_errors++;
- printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name);
- break;
- }
- netif_wake_queue(dev);
- break;
-
- /*
- * some unknown PCB
- */
- default:
- printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
- break;
- }
- } else {
- printk(KERN_WARNING "%s: failed to read PCB on interrupt\n", dev->name);
- adapter_reset(dev);
- }
- }
-
- } while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE)));
-
- prime_rx(dev);
-
- /*
- * indicate no longer in interrupt routine
- */
- spin_unlock(&adapter->lock);
- return IRQ_HANDLED;
-}
-
-
-/******************************************************
- *
- * open the board
- *
- ******************************************************/
-
-static int elp_open(struct net_device *dev)
-{
- elp_device *adapter;
- int retval;
-
- adapter = dev->priv;
-
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to open device\n", dev->name);
-
- /*
- * make sure we actually found the device
- */
- if (adapter == NULL) {
- printk(KERN_ERR "%s: Opening a non-existent physical device\n", dev->name);
- return -EAGAIN;
- }
- /*
- * disable interrupts on the board
- */
- outb_control(0, dev);
-
- /*
- * clear any pending interrupts
- */
- inb_command(dev->base_addr);
- adapter_reset(dev);
-
- /*
- * no receive PCBs active
- */
- adapter->rx_active = 0;
-
- adapter->busy = 0;
- adapter->send_pcb_semaphore = 0;
- adapter->rx_backlog.in = 0;
- adapter->rx_backlog.out = 0;
-
- spin_lock_init(&adapter->lock);
-
- /*
- * install our interrupt service routine
- */
- if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) {
- printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq);
- return retval;
- }
- if ((retval = request_dma(dev->dma, dev->name))) {
- free_irq(dev->irq, dev);
- printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
- return retval;
- }
- adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
- if (!adapter->dma_buffer) {
- printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name);
- free_dma(dev->dma);
- free_irq(dev->irq, dev);
- return -ENOMEM;
- }
- adapter->dmaing = 0;
-
- /*
- * enable interrupts on the board
- */
- outb_control(CMDE, dev);
-
- /*
- * configure adapter memory: we need 10 multicast addresses, default==0
- */
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
- adapter->tx_pcb.data.memconf.cmd_q = 10;
- adapter->tx_pcb.data.memconf.rcv_q = 20;
- adapter->tx_pcb.data.memconf.mcast = 10;
- adapter->tx_pcb.data.memconf.frame = 20;
- adapter->tx_pcb.data.memconf.rcv_b = 20;
- adapter->tx_pcb.data.memconf.progs = 0;
- adapter->tx_pcb.length = sizeof(struct Memconf);
- adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send memory configuration command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- }
-
-
- /*
- * configure adapter to receive broadcast messages and wait for response
- */
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_82586;
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
- adapter->tx_pcb.length = 2;
- adapter->got[CMD_CONFIGURE_82586] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- }
-
- /* enable burst-mode DMA */
- /* outb(0x1, dev->base_addr + PORT_AUXDMA); */
-
- /*
- * queue receive commands to provide buffering
- */
- prime_rx(dev);
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
-
- /*
- * device is now officially open!
- */
-
- netif_start_queue(dev);
- return 0;
-}
-
-
-/******************************************************
- *
- * send a packet to the adapter
- *
- ******************************************************/
-
-static bool send_packet(struct net_device *dev, struct sk_buff *skb)
-{
- elp_device *adapter = dev->priv;
- unsigned long target;
- unsigned long flags;
-
- /*
- * make sure the length is even and no shorter than 60 bytes
- */
- unsigned int nlen = (((skb->len < 60) ? 60 : skb->len) + 1) & (~1);
-
- if (test_and_set_bit(0, (void *) &adapter->busy)) {
- if (elp_debug >= 2)
- printk(KERN_DEBUG "%s: transmit blocked\n", dev->name);
- return false;
- }
-
- dev->stats.tx_bytes += nlen;
-
- /*
- * send the adapter a transmit packet command. Ignore segment and offset
- * and make sure the length is even
- */
- adapter->tx_pcb.command = CMD_TRANSMIT_PACKET;
- adapter->tx_pcb.length = sizeof(struct Xmit_pkt);
- adapter->tx_pcb.data.xmit_pkt.buf_ofs
- = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0; /* Unused */
- adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen;
-
- if (!send_pcb(dev, &adapter->tx_pcb)) {
- adapter->busy = 0;
- return false;
- }
- /* if this happens, we die */
- if (test_and_set_bit(0, (void *) &adapter->dmaing))
- printk(KERN_DEBUG "%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
-
- adapter->current_dma.direction = 1;
- adapter->current_dma.start_time = jiffies;
-
- if ((unsigned long)(skb->data + nlen) >= MAX_DMA_ADDRESS || nlen != skb->len) {
- skb_copy_from_linear_data(skb, adapter->dma_buffer, nlen);
- memset(adapter->dma_buffer+skb->len, 0, nlen-skb->len);
- target = isa_virt_to_bus(adapter->dma_buffer);
- }
- else {
- target = isa_virt_to_bus(skb->data);
- }
- adapter->current_dma.skb = skb;
-
- flags=claim_dma_lock();
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, 0x48); /* dma memory -> io */
- set_dma_addr(dev->dma, target);
- set_dma_count(dev->dma, nlen);
- outb_control(adapter->hcr_val | DMAE | TCEN, dev);
- enable_dma(dev->dma);
- release_dma_lock(flags);
-
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: DMA transfer started\n", dev->name);
-
- return true;
-}
-
-/*
- * The upper layer thinks we timed out
- */
-
-static void elp_timeout(struct net_device *dev)
-{
- int stat;
-
- stat = inb_status(dev->base_addr);
- printk(KERN_WARNING "%s: transmit timed out, lost %s?\n", dev->name, (stat & ACRF) ? "interrupt" : "command");
- if (elp_debug >= 1)
- printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat);
- dev->trans_start = jiffies;
- dev->stats.tx_dropped++;
- netif_wake_queue(dev);
-}
-
-/******************************************************
- *
- * start the transmitter
- * return 0 if sent OK, else return 1
- *
- ******************************************************/
-
-static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- elp_device *adapter = dev->priv;
-
- spin_lock_irqsave(&adapter->lock, flags);
- check_3c505_dma(dev);
-
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to send packet of length %d\n", dev->name, (int) skb->len);
-
- netif_stop_queue(dev);
-
- /*
- * send the packet at skb->data for skb->len
- */
- if (!send_packet(dev, skb)) {
- if (elp_debug >= 2) {
- printk(KERN_DEBUG "%s: failed to transmit packet\n", dev->name);
- }
- spin_unlock_irqrestore(&adapter->lock, flags);
- return 1;
- }
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: packet of length %d sent\n", dev->name, (int) skb->len);
-
- /*
- * start the transmit timeout
- */
- dev->trans_start = jiffies;
-
- prime_rx(dev);
- spin_unlock_irqrestore(&adapter->lock, flags);
- netif_start_queue(dev);
- return 0;
-}
-
-/******************************************************
- *
- * return statistics on the board
- *
- ******************************************************/
-
-static struct net_device_stats *elp_get_stats(struct net_device *dev)
-{
- elp_device *adapter = (elp_device *) dev->priv;
-
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request for stats\n", dev->name);
-
- /* If the device is closed, just return the latest stats we have,
- - we cannot ask from the adapter without interrupts */
- if (!netif_running(dev))
- return &dev->stats;
-
- /* send a get statistics command to the board */
- adapter->tx_pcb.command = CMD_NETWORK_STATISTICS;
- adapter->tx_pcb.length = 0;
- adapter->got[CMD_NETWORK_STATISTICS] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send get statistics command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- return &dev->stats;
- }
- }
-
- /* statistics are now up to date */
- return &dev->stats;
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-/******************************************************
- *
- * close the board
- *
- ******************************************************/
-
-static int elp_close(struct net_device *dev)
-{
- elp_device *adapter;
-
- adapter = dev->priv;
-
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to close device\n", dev->name);
-
- netif_stop_queue(dev);
-
- /* Someone may request the device statistic information even when
- * the interface is closed. The following will update the statistics
- * structure in the driver, so we'll be able to give current statistics.
- */
- (void) elp_get_stats(dev);
-
- /*
- * disable interrupts on the board
- */
- outb_control(0, dev);
-
- /*
- * release the IRQ
- */
- free_irq(dev->irq, dev);
-
- free_dma(dev->dma);
- free_pages((unsigned long) adapter->dma_buffer, get_order(DMA_BUFFER_SIZE));
-
- return 0;
-}
-
-
-/************************************************************
- *
- * Set multicast list
- * num_addrs==0: clear mc_list
- * num_addrs==-1: set promiscuous mode
- * num_addrs>0: set mc_list
- *
- ************************************************************/
-
-static void elp_set_mc_list(struct net_device *dev)
-{
- elp_device *adapter = (elp_device *) dev->priv;
- struct dev_mc_list *dmi = dev->mc_list;
- int i;
- unsigned long flags;
-
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: request to set multicast list\n", dev->name);
-
- spin_lock_irqsave(&adapter->lock, flags);
-
- if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
- /* send a "load multicast list" command to the board, max 10 addrs/cmd */
- /* if num_addrs==0 the list will be cleared */
- adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
- adapter->tx_pcb.length = 6 * dev->mc_count;
- for (i = 0; i < dev->mc_count; i++) {
- memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr, 6);
- dmi = dmi->next;
- }
- adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk(KERN_ERR "%s: couldn't send set_multicast command\n", dev->name);
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout)) {
- TIMEOUT_MSG(__LINE__);
- }
- }
- if (dev->mc_count)
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI;
- else /* num_addrs == 0 */
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
- } else
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC;
- /*
- * configure adapter to receive messages (as specified above)
- * and wait for response
- */
- if (elp_debug >= 3)
- printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_82586;
- adapter->tx_pcb.length = 2;
- adapter->got[CMD_CONFIGURE_82586] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- {
- spin_unlock_irqrestore(&adapter->lock, flags);
- printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
- }
- else {
- unsigned long timeout = jiffies + TIMEOUT;
- spin_unlock_irqrestore(&adapter->lock, flags);
- while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
- if (time_after_eq(jiffies, timeout))
- TIMEOUT_MSG(__LINE__);
- }
-}
-
-/************************************************************
- *
- * A couple of tests to see if there's 3C505 or not
- * Called only by elp_autodetect
- ************************************************************/
-
-static int __init elp_sense(struct net_device *dev)
-{
- int addr = dev->base_addr;
- const char *name = dev->name;
- byte orig_HSR;
-
- if (!request_region(addr, ELP_IO_EXTENT, "3c505"))
- return -ENODEV;
-
- orig_HSR = inb_status(addr);
-
- if (elp_debug > 0)
- printk(search_msg, name, addr);
-
- if (orig_HSR == 0xff) {
- if (elp_debug > 0)
- printk(notfound_msg, 1);
- goto out;
- }
-
- /* Wait for a while; the adapter may still be booting up */
- if (elp_debug > 0)
- printk(stilllooking_msg);
-
- if (orig_HSR & DIR) {
- /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
- outb(0, dev->base_addr + PORT_CONTROL);
- msleep(300);
- if (inb_status(addr) & DIR) {
- if (elp_debug > 0)
- printk(notfound_msg, 2);
- goto out;
- }
- } else {
- /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */
- outb(DIR, dev->base_addr + PORT_CONTROL);
- msleep(300);
- if (!(inb_status(addr) & DIR)) {
- if (elp_debug > 0)
- printk(notfound_msg, 3);
- goto out;
- }
- }
- /*
- * It certainly looks like a 3c505.
- */
- if (elp_debug > 0)
- printk(found_msg);
-
- return 0;
-out:
- release_region(addr, ELP_IO_EXTENT);
- return -ENODEV;
-}
-
-/*************************************************************
- *
- * Search through addr_list[] and try to find a 3C505
- * Called only by eplus_probe
- *************************************************************/
-
-static int __init elp_autodetect(struct net_device *dev)
-{
- int idx = 0;
-
- /* if base address set, then only check that address
- otherwise, run through the table */
- if (dev->base_addr != 0) { /* dev->base_addr == 0 ==> plain autodetect */
- if (elp_sense(dev) == 0)
- return dev->base_addr;
- } else
- while ((dev->base_addr = addr_list[idx++])) {
- if (elp_sense(dev) == 0)
- return dev->base_addr;
- }
-
- /* could not find an adapter */
- if (elp_debug > 0)
- printk(couldnot_msg, dev->name);
-
- return 0; /* Because of this, the layer above will return -ENODEV */
-}
-
-
-/******************************************************
- *
- * probe for an Etherlink Plus board at the specified address
- *
- ******************************************************/
-
-/* There are three situations we need to be able to detect here:
-
- * a) the card is idle
- * b) the card is still booting up
- * c) the card is stuck in a strange state (some DOS drivers do this)
- *
- * In case (a), all is well. In case (b), we wait 10 seconds to see if the
- * card finishes booting, and carry on if so. In case (c), we do a hard reset,
- * loop round, and hope for the best.
- *
- * This is all very unpleasant, but hopefully avoids the problems with the old
- * probe code (which had a 15-second delay if the card was idle, and didn't
- * work at all if it was in a weird state).
- */
-
-static int __init elplus_setup(struct net_device *dev)
-{
- elp_device *adapter = dev->priv;
- int i, tries, tries1, okay;
- unsigned long timeout;
- unsigned long cookie = 0;
- int err = -ENODEV;
- DECLARE_MAC_BUF(mac);
-
- /*
- * setup adapter structure
- */
-
- dev->base_addr = elp_autodetect(dev);
- if (!dev->base_addr)
- return -ENODEV;
-
- adapter->send_pcb_semaphore = 0;
-
- for (tries1 = 0; tries1 < 3; tries1++) {
- outb_control((adapter->hcr_val | CMDE) & ~DIR, dev);
- /* First try to write just one byte, to see if the card is
- * responding at all normally.
- */
- timeout = jiffies + 5*HZ/100;
- okay = 0;
- while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE));
- if ((inb_status(dev->base_addr) & HCRE)) {
- outb_command(0, dev->base_addr); /* send a spurious byte */
- timeout = jiffies + 5*HZ/100;
- while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE));
- if (inb_status(dev->base_addr) & HCRE)
- okay = 1;
- }
- if (!okay) {
- /* Nope, it's ignoring the command register. This means that
- * either it's still booting up, or it's died.
- */
- printk(KERN_ERR "%s: command register wouldn't drain, ", dev->name);
- if ((inb_status(dev->base_addr) & 7) == 3) {
- /* If the adapter status is 3, it *could* still be booting.
- * Give it the benefit of the doubt for 10 seconds.
- */
- printk("assuming 3c505 still starting\n");
- timeout = jiffies + 10*HZ;
- while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
- if (inb_status(dev->base_addr) & 7) {
- printk(KERN_ERR "%s: 3c505 failed to start\n", dev->name);
- } else {
- okay = 1; /* It started */
- }
- } else {
- /* Otherwise, it must just be in a strange
- * state. We probably need to kick it.
- */
- printk("3c505 is sulking\n");
- }
- }
- for (tries = 0; tries < 5 && okay; tries++) {
-
- /*
- * Try to set the Ethernet address, to make sure that the board
- * is working.
- */
- adapter->tx_pcb.command = CMD_STATION_ADDRESS;
- adapter->tx_pcb.length = 0;
- cookie = probe_irq_on();
- if (!send_pcb(dev, &adapter->tx_pcb)) {
- printk(KERN_ERR "%s: could not send first PCB\n", dev->name);
- probe_irq_off(cookie);
- continue;
- }
- if (!receive_pcb(dev, &adapter->rx_pcb)) {
- printk(KERN_ERR "%s: could not read first PCB\n", dev->name);
- probe_irq_off(cookie);
- continue;
- }
- if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
- (adapter->rx_pcb.length != 6)) {
- printk(KERN_ERR "%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length);
- probe_irq_off(cookie);
- continue;
- }
- goto okay;
- }
- /* It's broken. Do a hard reset to re-initialise the board,
- * and try again.
- */
- printk(KERN_INFO "%s: resetting adapter\n", dev->name);
- outb_control(adapter->hcr_val | FLSH | ATTN, dev);
- outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
- }
- printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name);
- goto out;
-
- okay:
- if (dev->irq) { /* Is there a preset IRQ? */
- int rpt = probe_irq_off(cookie);
- if (dev->irq != rpt) {
- printk(KERN_WARNING "%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
- }
- /* if dev->irq == probe_irq_off(cookie), all is well */
- } else /* No preset IRQ; just use what we can detect */
- dev->irq = probe_irq_off(cookie);
- switch (dev->irq) { /* Legal, sane? */
- case 0:
- printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n",
- dev->name);
- goto out;
- case 1:
- case 6:
- case 8:
- case 13:
- printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n",
- dev->name, dev->irq);
- goto out;
- }
- /*
- * Now we have the IRQ number so we can disable the interrupts from
- * the board until the board is opened.
- */
- outb_control(adapter->hcr_val & ~CMDE, dev);
-
- /*
- * copy Ethernet address into structure
- */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i];
-
- /* find a DMA channel */
- if (!dev->dma) {
- if (dev->mem_start) {
- dev->dma = dev->mem_start & 7;
- }
- else {
- printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name);
- dev->dma = ELP_DMA;
- }
- }
-
- /*
- * print remainder of startup message
- */
- printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, "
- "addr %s, ",
- dev->name, dev->base_addr, dev->irq, dev->dma,
- print_mac(mac, dev->dev_addr));
-
- /*
- * read more information from the adapter
- */
-
- adapter->tx_pcb.command = CMD_ADAPTER_INFO;
- adapter->tx_pcb.length = 0;
- if (!send_pcb(dev, &adapter->tx_pcb) ||
- !receive_pcb(dev, &adapter->rx_pcb) ||
- (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
- (adapter->rx_pcb.length != 10)) {
- printk("not responding to second PCB\n");
- }
- printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
-
- /*
- * reconfigure the adapter memory to better suit our purposes
- */
- adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
- adapter->tx_pcb.length = 12;
- adapter->tx_pcb.data.memconf.cmd_q = 8;
- adapter->tx_pcb.data.memconf.rcv_q = 8;
- adapter->tx_pcb.data.memconf.mcast = 10;
- adapter->tx_pcb.data.memconf.frame = 10;
- adapter->tx_pcb.data.memconf.rcv_b = 10;
- adapter->tx_pcb.data.memconf.progs = 0;
- if (!send_pcb(dev, &adapter->tx_pcb) ||
- !receive_pcb(dev, &adapter->rx_pcb) ||
- (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
- (adapter->rx_pcb.length != 2)) {
- printk(KERN_ERR "%s: could not configure adapter memory\n", dev->name);
- }
- if (adapter->rx_pcb.data.configure) {
- printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
- }
-
- dev->open = elp_open; /* local */
- dev->stop = elp_close; /* local */
- dev->get_stats = elp_get_stats; /* local */
- dev->hard_start_xmit = elp_start_xmit; /* local */
- dev->tx_timeout = elp_timeout; /* local */
- dev->watchdog_timeo = 10*HZ;
- dev->set_multicast_list = elp_set_mc_list; /* local */
- dev->ethtool_ops = &netdev_ethtool_ops; /* local */
-
- dev->mem_start = dev->mem_end = 0;
-
- err = register_netdev(dev);
- if (err)
- goto out;
-
- return 0;
-out:
- release_region(dev->base_addr, ELP_IO_EXTENT);
- return err;
-}
-
-#ifndef MODULE
-struct net_device * __init elplus_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(elp_device));
- int err;
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = elplus_setup(dev);
- if (err) {
- free_netdev(dev);
- return ERR_PTR(err);
- }
- return dev;
-}
-
-#else
-static struct net_device *dev_3c505[ELP_MAX_CARDS];
-static int io[ELP_MAX_CARDS];
-static int irq[ELP_MAX_CARDS];
-static int dma[ELP_MAX_CARDS];
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(dma, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)");
-MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)");
-
-int __init init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
- struct net_device *dev = alloc_etherdev(sizeof(elp_device));
- if (!dev)
- break;
-
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- if (dma[this_dev]) {
- dev->dma = dma[this_dev];
- } else {
- dev->dma = ELP_DMA;
- printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n");
- }
- if (io[this_dev] == 0) {
- if (this_dev) {
- free_netdev(dev);
- break;
- }
- printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n");
- }
- if (elplus_setup(dev) != 0) {
- printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
- free_netdev(dev);
- break;
- }
- dev_3c505[this_dev] = dev;
- found++;
- }
- if (!found)
- return -ENODEV;
- return 0;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
- struct net_device *dev = dev_3c505[this_dev];
- if (dev) {
- unregister_netdev(dev);
- release_region(dev->base_addr, ELP_IO_EXTENT);
- free_netdev(dev);
- }
- }
-}
-
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/3c505.h b/drivers/net/3c505.h
deleted file mode 100644
index 04df2a9002b..00000000000
--- a/drivers/net/3c505.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/*****************************************************************
- *
- * defines for 3Com Etherlink Plus adapter
- *
- *****************************************************************/
-
-#define ELP_DMA 6
-#define ELP_RX_PCBS 4
-#define ELP_MAX_CARDS 4
-
-/*
- * I/O register offsets
- */
-#define PORT_COMMAND 0x00 /* read/write, 8-bit */
-#define PORT_STATUS 0x02 /* read only, 8-bit */
-#define PORT_AUXDMA 0x02 /* write only, 8-bit */
-#define PORT_DATA 0x04 /* read/write, 16-bit */
-#define PORT_CONTROL 0x06 /* read/write, 8-bit */
-
-#define ELP_IO_EXTENT 0x10 /* size of used IO registers */
-
-/*
- * host control registers bits
- */
-#define ATTN 0x80 /* attention */
-#define FLSH 0x40 /* flush data register */
-#define DMAE 0x20 /* DMA enable */
-#define DIR 0x10 /* direction */
-#define TCEN 0x08 /* terminal count interrupt enable */
-#define CMDE 0x04 /* command register interrupt enable */
-#define HSF2 0x02 /* host status flag 2 */
-#define HSF1 0x01 /* host status flag 1 */
-
-/*
- * combinations of HSF flags used for PCB transmission
- */
-#define HSF_PCB_ACK HSF1
-#define HSF_PCB_NAK HSF2
-#define HSF_PCB_END (HSF2|HSF1)
-#define HSF_PCB_MASK (HSF2|HSF1)
-
-/*
- * host status register bits
- */
-#define HRDY 0x80 /* data register ready */
-#define HCRE 0x40 /* command register empty */
-#define ACRF 0x20 /* adapter command register full */
-/* #define DIR 0x10 direction - same as in control register */
-#define DONE 0x08 /* DMA done */
-#define ASF3 0x04 /* adapter status flag 3 */
-#define ASF2 0x02 /* adapter status flag 2 */
-#define ASF1 0x01 /* adapter status flag 1 */
-
-/*
- * combinations of ASF flags used for PCB reception
- */
-#define ASF_PCB_ACK ASF1
-#define ASF_PCB_NAK ASF2
-#define ASF_PCB_END (ASF2|ASF1)
-#define ASF_PCB_MASK (ASF2|ASF1)
-
-/*
- * host aux DMA register bits
- */
-#define DMA_BRST 0x01 /* DMA burst */
-
-/*
- * maximum amount of data allowed in a PCB
- */
-#define MAX_PCB_DATA 62
-
-/*****************************************************************
- *
- * timeout value
- * this is a rough value used for loops to stop them from
- * locking up the whole machine in the case of failure or
- * error conditions
- *
- *****************************************************************/
-
-#define TIMEOUT 300
-
-/*****************************************************************
- *
- * PCB commands
- *
- *****************************************************************/
-
-enum {
- /*
- * host PCB commands
- */
- CMD_CONFIGURE_ADAPTER_MEMORY = 0x01,
- CMD_CONFIGURE_82586 = 0x02,
- CMD_STATION_ADDRESS = 0x03,
- CMD_DMA_DOWNLOAD = 0x04,
- CMD_DMA_UPLOAD = 0x05,
- CMD_PIO_DOWNLOAD = 0x06,
- CMD_PIO_UPLOAD = 0x07,
- CMD_RECEIVE_PACKET = 0x08,
- CMD_TRANSMIT_PACKET = 0x09,
- CMD_NETWORK_STATISTICS = 0x0a,
- CMD_LOAD_MULTICAST_LIST = 0x0b,
- CMD_CLEAR_PROGRAM = 0x0c,
- CMD_DOWNLOAD_PROGRAM = 0x0d,
- CMD_EXECUTE_PROGRAM = 0x0e,
- CMD_SELF_TEST = 0x0f,
- CMD_SET_STATION_ADDRESS = 0x10,
- CMD_ADAPTER_INFO = 0x11,
- NUM_TRANSMIT_CMDS,
-
- /*
- * adapter PCB commands
- */
- CMD_CONFIGURE_ADAPTER_RESPONSE = 0x31,
- CMD_CONFIGURE_82586_RESPONSE = 0x32,
- CMD_ADDRESS_RESPONSE = 0x33,
- CMD_DOWNLOAD_DATA_REQUEST = 0x34,
- CMD_UPLOAD_DATA_REQUEST = 0x35,
- CMD_RECEIVE_PACKET_COMPLETE = 0x38,
- CMD_TRANSMIT_PACKET_COMPLETE = 0x39,
- CMD_NETWORK_STATISTICS_RESPONSE = 0x3a,
- CMD_LOAD_MULTICAST_RESPONSE = 0x3b,
- CMD_CLEAR_PROGRAM_RESPONSE = 0x3c,
- CMD_DOWNLOAD_PROGRAM_RESPONSE = 0x3d,
- CMD_EXECUTE_RESPONSE = 0x3e,
- CMD_SELF_TEST_RESPONSE = 0x3f,
- CMD_SET_ADDRESS_RESPONSE = 0x40,
- CMD_ADAPTER_INFO_RESPONSE = 0x41
-};
-
-/* Definitions for the PCB data structure */
-
-/* Data units */
-typedef unsigned char byte;
-typedef unsigned short int word;
-typedef unsigned long int dword;
-
-/* Data structures */
-struct Memconf {
- word cmd_q,
- rcv_q,
- mcast,
- frame,
- rcv_b,
- progs;
-};
-
-struct Rcv_pkt {
- word buf_ofs,
- buf_seg,
- buf_len,
- timeout;
-};
-
-struct Xmit_pkt {
- word buf_ofs,
- buf_seg,
- pkt_len;
-};
-
-struct Rcv_resp {
- word buf_ofs,
- buf_seg,
- buf_len,
- pkt_len,
- timeout,
- status;
- dword timetag;
-};
-
-struct Xmit_resp {
- word buf_ofs,
- buf_seg,
- c_stat,
- status;
-};
-
-
-struct Netstat {
- dword tot_recv,
- tot_xmit;
- word err_CRC,
- err_align,
- err_res,
- err_ovrrun;
-};
-
-
-struct Selftest {
- word error;
- union {
- word ROM_cksum;
- struct {
- word ofs, seg;
- } RAM;
- word i82586;
- } failure;
-};
-
-struct Info {
- byte minor_vers,
- major_vers;
- word ROM_cksum,
- RAM_sz,
- free_ofs,
- free_seg;
-};
-
-struct Memdump {
- word size,
- off,
- seg;
-};
-
-/*
-Primary Command Block. The most important data structure. All communication
-between the host and the adapter is done with these. (Except for the actual
-Ethernet data, which has different packaging.)
-*/
-typedef struct {
- byte command;
- byte length;
- union {
- struct Memconf memconf;
- word configure;
- struct Rcv_pkt rcv_pkt;
- struct Xmit_pkt xmit_pkt;
- byte multicast[10][6];
- byte eth_addr[6];
- byte failed;
- struct Rcv_resp rcv_resp;
- struct Xmit_resp xmit_resp;
- struct Netstat netstat;
- struct Selftest selftest;
- struct Info info;
- struct Memdump memdump;
- byte raw[62];
- } data;
-} pcb_struct;
-
-/* These defines for 'configure' */
-#define RECV_STATION 0x00
-#define RECV_BROAD 0x01
-#define RECV_MULTI 0x02
-#define RECV_PROMISC 0x04
-#define NO_LOOPBACK 0x00
-#define INT_LOOPBACK 0x08
-#define EXT_LOOPBACK 0x10
-
-/*****************************************************************
- *
- * structure to hold context information for adapter
- *
- *****************************************************************/
-
-#define DMA_BUFFER_SIZE 1600
-#define BACKLOG_SIZE 4
-
-typedef struct {
- volatile short got[NUM_TRANSMIT_CMDS]; /* flags for
- command completion */
- pcb_struct tx_pcb; /* PCB for foreground sending */
- pcb_struct rx_pcb; /* PCB for foreground receiving */
- pcb_struct itx_pcb; /* PCB for background sending */
- pcb_struct irx_pcb; /* PCB for background receiving */
-
- void *dma_buffer;
-
- struct {
- unsigned int length[BACKLOG_SIZE];
- unsigned int in;
- unsigned int out;
- } rx_backlog;
-
- struct {
- unsigned int direction;
- unsigned int length;
- struct sk_buff *skb;
- void *target;
- unsigned long start_time;
- } current_dma;
-
- /* flags */
- unsigned long send_pcb_semaphore;
- unsigned long dmaing;
- unsigned long busy;
-
- unsigned int rx_active; /* number of receive PCBs */
- volatile unsigned char hcr_val; /* what we think the HCR contains */
- spinlock_t lock; /* Interrupt v tx lock */
-} elp_device;
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
deleted file mode 100644
index 030c147211b..00000000000
--- a/drivers/net/3c507.c
+++ /dev/null
@@ -1,951 +0,0 @@
-/* 3c507.c: An EtherLink16 device driver for Linux. */
-/*
- Written 1993,1994 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
-
- Thanks go to jennings@Montrouge.SMR.slb.com ( Patrick Jennings)
- and jrs@world.std.com (Rick Sladkey) for testing and bugfixes.
- Mark Salazar <leslie@access.digex.net> made the changes for cards with
- only 16K packet buffers.
-
- Things remaining to do:
- Verify that the tx and rx buffers don't have fencepost errors.
- Move the theory of operation and memory map documentation.
- The statistics need to be updated correctly.
-*/
-
-#define DRV_NAME "3c507"
-#define DRV_VERSION "1.10a"
-#define DRV_RELDATE "11/17/2001"
-
-static const char version[] =
- DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n";
-
-/*
- Sources:
- This driver wouldn't have been written with the availability of the
- Crynwr driver source code. It provided a known-working implementation
- that filled in the gaping holes of the Intel documentation. Three cheers
- for Russ Nelson.
-
- Intel Microcommunications Databook, Vol. 1, 1990. It provides just enough
- info that the casual reader might think that it documents the i82586 :-<.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-/* use 0 for production, 1 for verification, 2..7 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-#define debug net_debug
-
-
-/*
- Details of the i82586.
-
- You'll really need the databook to understand the details of this part,
- but the outline is that the i82586 has two separate processing units.
- Both are started from a list of three configuration tables, of which only
- the last, the System Control Block (SCB), is used after reset-time. The SCB
- has the following fields:
- Status word
- Command word
- Tx/Command block addr.
- Rx block addr.
- The command word accepts the following controls for the Tx and Rx units:
- */
-
-#define CUC_START 0x0100
-#define CUC_RESUME 0x0200
-#define CUC_SUSPEND 0x0300
-#define RX_START 0x0010
-#define RX_RESUME 0x0020
-#define RX_SUSPEND 0x0030
-
-/* The Rx unit uses a list of frame descriptors and a list of data buffer
- descriptors. We use full-sized (1518 byte) data buffers, so there is
- a one-to-one pairing of frame descriptors to buffer descriptors.
-
- The Tx ("command") unit executes a list of commands that look like:
- Status word Written by the 82586 when the command is done.
- Command word Command in lower 3 bits, post-command action in upper 3
- Link word The address of the next command.
- Parameters (as needed).
-
- Some definitions related to the Command Word are:
- */
-#define CMD_EOL 0x8000 /* The last command of the list, stop. */
-#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
-#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
-
-enum commands {
- CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
- CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
-
-/* Information that need to be kept for each board. */
-struct net_local {
- int last_restart;
- ushort rx_head;
- ushort rx_tail;
- ushort tx_head;
- ushort tx_cmd_link;
- ushort tx_reap;
- ushort tx_pkts_in_ring;
- spinlock_t lock;
- void __iomem *base;
-};
-
-/*
- Details of the EtherLink16 Implementation
- The 3c507 is a generic shared-memory i82586 implementation.
- The host can map 16K, 32K, 48K, or 64K of the 64K memory into
- 0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
- */
-
-/* Offsets from the base I/O address. */
-#define SA_DATA 0 /* Station address data, or 3Com signature. */
-#define MISC_CTRL 6 /* Switch the SA_DATA banks, and bus config bits. */
-#define RESET_IRQ 10 /* Reset the latched IRQ line. */
-#define SIGNAL_CA 11 /* Frob the 82586 Channel Attention line. */
-#define ROM_CONFIG 13
-#define MEM_CONFIG 14
-#define IRQ_CONFIG 15
-#define EL16_IO_EXTENT 16
-
-/* The ID port is used at boot-time to locate the ethercard. */
-#define ID_PORT 0x100
-
-/* Offsets to registers in the mailbox (SCB). */
-#define iSCB_STATUS 0x8
-#define iSCB_CMD 0xA
-#define iSCB_CBL 0xC /* Command BLock offset. */
-#define iSCB_RFA 0xE /* Rx Frame Area offset. */
-
-/* Since the 3c507 maps the shared memory window so that the last byte is
- at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
- 48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
- We can account for this be setting the 'SBC Base' entry in the ISCP table
- below for all the 16 bit offset addresses, and also adding the 'SCB Base'
- value to all 24 bit physical addresses (in the SCP table and the TX and RX
- Buffer Descriptors).
- -Mark
- */
-#define SCB_BASE ((unsigned)64*1024 - (dev->mem_end - dev->mem_start))
-
-/*
- What follows in 'init_words[]' is the "program" that is downloaded to the
- 82586 memory. It's mostly tables and command blocks, and starts at the
- reset address 0xfffff6. This is designed to be similar to the EtherExpress,
- thus the unusual location of the SCB at 0x0008.
-
- Even with the additional "don't care" values, doing it this way takes less
- program space than initializing the individual tables, and I feel it's much
- cleaner.
-
- The databook is particularly useless for the first two structures, I had
- to use the Crynwr driver as an example.
-
- The memory setup is as follows:
- */
-
-#define CONFIG_CMD 0x0018
-#define SET_SA_CMD 0x0024
-#define SA_OFFSET 0x002A
-#define IDLELOOP 0x30
-#define TDR_CMD 0x38
-#define TDR_TIME 0x3C
-#define DUMP_CMD 0x40
-#define DIAG_CMD 0x48
-#define SET_MC_CMD 0x4E
-#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
-
-#define TX_BUF_START 0x0100
-#define NUM_TX_BUFS 5
-#define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */
-
-#define RX_BUF_START 0x2000
-#define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */
-#define RX_BUF_END (dev->mem_end - dev->mem_start)
-
-#define TX_TIMEOUT 5
-
-/*
- That's it: only 86 bytes to set up the beast, including every extra
- command available. The 170 byte buffer at DUMP_DATA is shared between the
- Dump command (called only by the diagnostic program) and the SetMulticastList
- command.
-
- To complete the memory setup you only have to write the station address at
- SA_OFFSET and create the Tx & Rx buffer lists.
-
- The Tx command chain and buffer list is setup as follows:
- A Tx command table, with the data buffer pointing to...
- A Tx data buffer descriptor. The packet is in a single buffer, rather than
- chaining together several smaller buffers.
- A NoOp command, which initially points to itself,
- And the packet data.
-
- A transmit is done by filling in the Tx command table and data buffer,
- re-writing the NoOp command, and finally changing the offset of the last
- command to point to the current Tx command. When the Tx command is finished,
- it jumps to the NoOp, when it loops until the next Tx command changes the
- "link offset" in the NoOp. This way the 82586 never has to go through the
- slow restart sequence.
-
- The Rx buffer list is set up in the obvious ring structure. We have enough
- memory (and low enough interrupt latency) that we can avoid the complicated
- Rx buffer linked lists by alway associating a full-size Rx data buffer with
- each Rx data frame.
-
- I current use four transmit buffers starting at TX_BUF_START (0x0100), and
- use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
-
- */
-
-static unsigned short init_words[] = {
- /* System Configuration Pointer (SCP). */
- 0x0000, /* Set bus size to 16 bits. */
- 0,0, /* pad words. */
- 0x0000,0x0000, /* ISCP phys addr, set in init_82586_mem(). */
-
- /* Intermediate System Configuration Pointer (ISCP). */
- 0x0001, /* Status word that's cleared when init is done. */
- 0x0008,0,0, /* SCB offset, (skip, skip) */
-
- /* System Control Block (SCB). */
- 0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */
- CONFIG_CMD, /* Command list pointer, points to Configure. */
- RX_BUF_START, /* Rx block list. */
- 0,0,0,0, /* Error count: CRC, align, buffer, overrun. */
-
- /* 0x0018: Configure command. Change to put MAC data with packet. */
- 0, CmdConfigure, /* Status, command. */
- SET_SA_CMD, /* Next command is Set Station Addr. */
- 0x0804, /* "4" bytes of config data, 8 byte FIFO. */
- 0x2e40, /* Magic values, including MAC data location. */
- 0, /* Unused pad word. */
-
- /* 0x0024: Setup station address command. */
- 0, CmdSASetup,
- SET_MC_CMD, /* Next command. */
- 0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */
-
- /* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */
- 0, CmdNOp, IDLELOOP, 0 /* pad */,
-
- /* 0x0038: A unused Time-Domain Reflectometer command. */
- 0, CmdTDR, IDLELOOP, 0,
-
- /* 0x0040: An unused Dump State command. */
- 0, CmdDump, IDLELOOP, DUMP_DATA,
-
- /* 0x0048: An unused Diagnose command. */
- 0, CmdDiagnose, IDLELOOP,
-
- /* 0x004E: An empty set-multicast-list command. */
- 0, CmdMulticastList, IDLELOOP, 0,
-};
-
-/* Index to functions, as function prototypes. */
-
-static int el16_probe1(struct net_device *dev, int ioaddr);
-static int el16_open(struct net_device *dev);
-static int el16_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el16_interrupt(int irq, void *dev_id);
-static void el16_rx(struct net_device *dev);
-static int el16_close(struct net_device *dev);
-static void el16_tx_timeout (struct net_device *dev);
-
-static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad);
-static void init_82586_mem(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-static void init_rx_bufs(struct net_device *);
-
-static int io = 0x300;
-static int irq;
-static int mem_start;
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, (detachable devices only) allocate space for the
- device and return success.
- */
-
-struct net_device * __init el16_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- static unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0};
- unsigned *port;
- int err = -ENODEV;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- mem_start = dev->mem_start & 15;
- }
-
- if (io > 0x1ff) /* Check a single specified location. */
- err = el16_probe1(dev, io);
- else if (io != 0)
- err = -ENXIO; /* Don't probe at all. */
- else {
- for (port = ports; *port; port++) {
- err = el16_probe1(dev, *port);
- if (!err)
- break;
- }
- }
-
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- free_irq(dev->irq, dev);
- iounmap(((struct net_local *)netdev_priv(dev))->base);
- release_region(dev->base_addr, EL16_IO_EXTENT);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static int __init el16_probe1(struct net_device *dev, int ioaddr)
-{
- static unsigned char init_ID_done, version_printed;
- int i, irq, irqval, retval;
- struct net_local *lp;
- DECLARE_MAC_BUF(mac);
-
- if (init_ID_done == 0) {
- ushort lrs_state = 0xff;
- /* Send the ID sequence to the ID_PORT to enable the board(s). */
- outb(0x00, ID_PORT);
- for(i = 0; i < 255; i++) {
- outb(lrs_state, ID_PORT);
- lrs_state <<= 1;
- if (lrs_state & 0x100)
- lrs_state ^= 0xe7;
- }
- outb(0x00, ID_PORT);
- init_ID_done = 1;
- }
-
- if (!request_region(ioaddr, EL16_IO_EXTENT, DRV_NAME))
- return -ENODEV;
-
- if ((inb(ioaddr) != '*') || (inb(ioaddr + 1) != '3') ||
- (inb(ioaddr + 2) != 'C') || (inb(ioaddr + 3) != 'O')) {
- retval = -ENODEV;
- goto out;
- }
-
- if (net_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: 3c507 at %#x,", dev->name, ioaddr);
-
- /* We should make a few more checks here, like the first three octets of
- the S.A. for the manufacturer's code. */
-
- irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
-
- irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
- if (irqval) {
- printk(KERN_ERR "3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
- retval = -EAGAIN;
- goto out;
- }
-
- /* We've committed to using the board, and can start filling in *dev. */
- dev->base_addr = ioaddr;
-
- outb(0x01, ioaddr + MISC_CTRL);
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + i);
- printk(" %s", print_mac(mac, dev->dev_addr));
-
- if (mem_start)
- net_debug = mem_start & 7;
-
-#ifdef MEM_BASE
- dev->mem_start = MEM_BASE;
- dev->mem_end = dev->mem_start + 0x10000;
-#else
- {
- int base;
- int size;
- char mem_config = inb(ioaddr + MEM_CONFIG);
- if (mem_config & 0x20) {
- size = 64*1024;
- base = 0xf00000 + (mem_config & 0x08 ? 0x080000
- : ((mem_config & 3) << 17));
- } else {
- size = ((mem_config & 3) + 1) << 14;
- base = 0x0c0000 + ( (mem_config & 0x18) << 12);
- }
- dev->mem_start = base;
- dev->mem_end = base + size;
- }
-#endif
-
- dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
- dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
-
- printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
- dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
-
- if (net_debug)
- printk(version);
-
- lp = netdev_priv(dev);
- memset(lp, 0, sizeof(*lp));
- spin_lock_init(&lp->lock);
- lp->base = ioremap(dev->mem_start, RX_BUF_END);
- if (!lp->base) {
- printk(KERN_ERR "3c507: unable to remap memory\n");
- retval = -EAGAIN;
- goto out1;
- }
-
- dev->open = el16_open;
- dev->stop = el16_close;
- dev->hard_start_xmit = el16_send_packet;
- dev->tx_timeout = el16_tx_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
- dev->ethtool_ops = &netdev_ethtool_ops;
- dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
- return 0;
-out1:
- free_irq(dev->irq, dev);
-out:
- release_region(ioaddr, EL16_IO_EXTENT);
- return retval;
-}
-
-static int el16_open(struct net_device *dev)
-{
- /* Initialize the 82586 memory and start it. */
- init_82586_mem(dev);
-
- netif_start_queue(dev);
- return 0;
-}
-
-
-static void el16_tx_timeout (struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- void __iomem *shmem = lp->base;
-
- if (net_debug > 1)
- printk ("%s: transmit timed out, %s? ", dev->name,
- readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
- "network cable problem");
- /* Try to restart the adaptor. */
- if (lp->last_restart == dev->stats.tx_packets) {
- if (net_debug > 1)
- printk ("Resetting board.\n");
- /* Completely reset the adaptor. */
- init_82586_mem (dev);
- lp->tx_pkts_in_ring = 0;
- } else {
- /* Issue the channel attention signal and hope it "gets better". */
- if (net_debug > 1)
- printk ("Kicking board.\n");
- writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
- outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
- lp->last_restart = dev->stats.tx_packets;
- }
- dev->trans_start = jiffies;
- netif_wake_queue (dev);
-}
-
-
-static int el16_send_packet (struct sk_buff *skb, struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- unsigned long flags;
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- netif_stop_queue (dev);
-
- spin_lock_irqsave (&lp->lock, flags);
-
- dev->stats.tx_bytes += length;
- /* Disable the 82586's input to the interrupt line. */
- outb (0x80, ioaddr + MISC_CTRL);
-
- hardware_send_packet (dev, buf, skb->len, length - skb->len);
-
- dev->trans_start = jiffies;
- /* Enable the 82586 interrupt input. */
- outb (0x84, ioaddr + MISC_CTRL);
-
- spin_unlock_irqrestore (&lp->lock, flags);
-
- dev_kfree_skb (skb);
-
- /* You might need to clean up and record Tx statistics here. */
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static irqreturn_t el16_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr, status, boguscount = 0;
- ushort ack_cmd = 0;
- void __iomem *shmem;
-
- if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
- return IRQ_NONE;
- }
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
- shmem = lp->base;
-
- spin_lock(&lp->lock);
-
- status = readw(shmem+iSCB_STATUS);
-
- if (net_debug > 4) {
- printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
- }
-
- /* Disable the 82586's input to the interrupt line. */
- outb(0x80, ioaddr + MISC_CTRL);
-
- /* Reap the Tx packet buffers. */
- while (lp->tx_pkts_in_ring) {
- unsigned short tx_status = readw(shmem+lp->tx_reap);
- if (!(tx_status & 0x8000)) {
- if (net_debug > 5)
- printk("Tx command incomplete (%#x).\n", lp->tx_reap);
- break;
- }
- /* Tx unsuccessful or some interesting status bit set. */
- if (!(tx_status & 0x2000) || (tx_status & 0x0f3f)) {
- dev->stats.tx_errors++;
- if (tx_status & 0x0600) dev->stats.tx_carrier_errors++;
- if (tx_status & 0x0100) dev->stats.tx_fifo_errors++;
- if (!(tx_status & 0x0040)) dev->stats.tx_heartbeat_errors++;
- if (tx_status & 0x0020) dev->stats.tx_aborted_errors++;
- dev->stats.collisions += tx_status & 0xf;
- }
- dev->stats.tx_packets++;
- if (net_debug > 5)
- printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
- lp->tx_reap += TX_BUF_SIZE;
- if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
- lp->tx_reap = TX_BUF_START;
-
- lp->tx_pkts_in_ring--;
- /* There is always more space in the Tx ring buffer now. */
- netif_wake_queue(dev);
-
- if (++boguscount > 10)
- break;
- }
-
- if (status & 0x4000) { /* Packet received. */
- if (net_debug > 5)
- printk("Received packet, rx_head %04x.\n", lp->rx_head);
- el16_rx(dev);
- }
-
- /* Acknowledge the interrupt sources. */
- ack_cmd = status & 0xf000;
-
- if ((status & 0x0700) != 0x0200 && netif_running(dev)) {
- if (net_debug)
- printk("%s: Command unit stopped, status %04x, restarting.\n",
- dev->name, status);
- /* If this ever occurs we should really re-write the idle loop, reset
- the Tx list, and do a complete restart of the command unit.
- For now we rely on the Tx timeout if the resume doesn't work. */
- ack_cmd |= CUC_RESUME;
- }
-
- if ((status & 0x0070) != 0x0040 && netif_running(dev)) {
- /* The Rx unit is not ready, it must be hung. Restart the receiver by
- initializing the rx buffers, and issuing an Rx start command. */
- if (net_debug)
- printk("%s: Rx unit stopped, status %04x, restarting.\n",
- dev->name, status);
- init_rx_bufs(dev);
- writew(RX_BUF_START,shmem+iSCB_RFA);
- ack_cmd |= RX_START;
- }
-
- writew(ack_cmd,shmem+iSCB_CMD);
- outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
-
- /* Clear the latched interrupt. */
- outb(0, ioaddr + RESET_IRQ);
-
- /* Enable the 82586's interrupt input. */
- outb(0x84, ioaddr + MISC_CTRL);
- spin_unlock(&lp->lock);
- return IRQ_HANDLED;
-}
-
-static int el16_close(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- void __iomem *shmem = lp->base;
-
- netif_stop_queue(dev);
-
- /* Flush the Tx and disable Rx. */
- writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD);
- outb(0, ioaddr + SIGNAL_CA);
-
- /* Disable the 82586's input to the interrupt line. */
- outb(0x80, ioaddr + MISC_CTRL);
-
- /* We always physically use the IRQ line, so we don't do free_irq(). */
-
- /* Update the statistics here. */
-
- return 0;
-}
-
-/* Initialize the Rx-block list. */
-static void init_rx_bufs(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- void __iomem *write_ptr;
- unsigned short SCB_base = SCB_BASE;
-
- int cur_rxbuf = lp->rx_head = RX_BUF_START;
-
- /* Initialize each Rx frame + data buffer. */
- do { /* While there is room for one more. */
-
- write_ptr = lp->base + cur_rxbuf;
-
- writew(0x0000,write_ptr); /* Status */
- writew(0x0000,write_ptr+=2); /* Command */
- writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2); /* Link */
- writew(cur_rxbuf + 22,write_ptr+=2); /* Buffer offset */
- writew(0x0000,write_ptr+=2); /* Pad for dest addr. */
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2); /* Pad for source addr. */
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2);
- writew(0x0000,write_ptr+=2); /* Pad for protocol. */
-
- writew(0x0000,write_ptr+=2); /* Buffer: Actual count */
- writew(-1,write_ptr+=2); /* Buffer: Next (none). */
- writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */
- writew(0x0000,write_ptr+=2);
- /* Finally, the number of bytes in the buffer. */
- writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2);
-
- lp->rx_tail = cur_rxbuf;
- cur_rxbuf += RX_BUF_SIZE;
- } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
-
- /* Terminate the list by setting the EOL bit, and wrap the pointer to make
- the list a ring. */
- write_ptr = lp->base + lp->rx_tail + 2;
- writew(0xC000,write_ptr); /* Command, mark as last. */
- writew(lp->rx_head,write_ptr+2); /* Link */
-}
-
-static void init_82586_mem(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- void __iomem *shmem = lp->base;
-
- /* Enable loopback to protect the wire while starting up,
- and hold the 586 in reset during the memory initialization. */
- outb(0x20, ioaddr + MISC_CTRL);
-
- /* Fix the ISCP address and base. */
- init_words[3] = SCB_BASE;
- init_words[7] = SCB_BASE;
-
- /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
- memcpy_toio(lp->base + RX_BUF_END - 10, init_words, 10);
-
- /* Write the words at 0x0000. */
- memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10);
-
- /* Fill in the station address. */
- memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr,
- sizeof(dev->dev_addr));
-
- /* The Tx-block list is written as needed. We just set up the values. */
- lp->tx_cmd_link = IDLELOOP + 4;
- lp->tx_head = lp->tx_reap = TX_BUF_START;
-
- init_rx_bufs(dev);
-
- /* Start the 586 by releasing the reset line, but leave loopback. */
- outb(0xA0, ioaddr + MISC_CTRL);
-
- /* This was time consuming to track down: you need to give two channel
- attention signals to reliably start up the i82586. */
- outb(0, ioaddr + SIGNAL_CA);
-
- {
- int boguscnt = 50;
- while (readw(shmem+iSCB_STATUS) == 0)
- if (--boguscnt == 0) {
- printk("%s: i82586 initialization timed out with status %04x, "
- "cmd %04x.\n", dev->name,
- readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
- break;
- }
- /* Issue channel-attn -- the 82586 won't start. */
- outb(0, ioaddr + SIGNAL_CA);
- }
-
- /* Disable loopback and enable interrupts. */
- outb(0x84, ioaddr + MISC_CTRL);
- if (net_debug > 4)
- printk("%s: Initialized 82586, status %04x.\n", dev->name,
- readw(shmem+iSCB_STATUS));
- return;
-}
-
-static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad)
-{
- struct net_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- ushort tx_block = lp->tx_head;
- void __iomem *write_ptr = lp->base + tx_block;
- static char padding[ETH_ZLEN];
-
- /* Set the write pointer to the Tx block, and put out the header. */
- writew(0x0000,write_ptr); /* Tx status */
- writew(CMD_INTR|CmdTx,write_ptr+=2); /* Tx command */
- writew(tx_block+16,write_ptr+=2); /* Next command is a NoOp. */
- writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */
-
- /* Output the data buffer descriptor. */
- writew((pad + length) | 0x8000,write_ptr+=2); /* Byte count parameter. */
- writew(-1,write_ptr+=2); /* No next data buffer. */
- writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */
- writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */
-
- /* Output the Loop-back NoOp command. */
- writew(0x0000,write_ptr+=2); /* Tx status */
- writew(CmdNOp,write_ptr+=2); /* Tx command */
- writew(tx_block+16,write_ptr+=2); /* Next is myself. */
-
- /* Output the packet at the write pointer. */
- memcpy_toio(write_ptr+2, buf, length);
- if (pad)
- memcpy_toio(write_ptr+length+2, padding, pad);
-
- /* Set the old command link pointing to this send packet. */
- writew(tx_block,lp->base + lp->tx_cmd_link);
- lp->tx_cmd_link = tx_block + 20;
-
- /* Set the next free tx region. */
- lp->tx_head = tx_block + TX_BUF_SIZE;
- if (lp->tx_head > RX_BUF_START - TX_BUF_SIZE)
- lp->tx_head = TX_BUF_START;
-
- if (net_debug > 4) {
- printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
- dev->name, ioaddr, length, tx_block, lp->tx_head);
- }
-
- /* Grimly block further packets if there has been insufficient reaping. */
- if (++lp->tx_pkts_in_ring < NUM_TX_BUFS)
- netif_wake_queue(dev);
-}
-
-static void el16_rx(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- void __iomem *shmem = lp->base;
- ushort rx_head = lp->rx_head;
- ushort rx_tail = lp->rx_tail;
- ushort boguscount = 10;
- short frame_status;
-
- while ((frame_status = readw(shmem+rx_head)) < 0) { /* Command complete */
- void __iomem *read_frame = lp->base + rx_head;
- ushort rfd_cmd = readw(read_frame+2);
- ushort next_rx_frame = readw(read_frame+4);
- ushort data_buffer_addr = readw(read_frame+6);
- void __iomem *data_frame = lp->base + data_buffer_addr;
- ushort pkt_len = readw(data_frame);
-
- if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
- || (pkt_len & 0xC000) != 0xC000) {
- printk(KERN_ERR "%s: Rx frame at %#x corrupted, "
- "status %04x cmd %04x next %04x "
- "data-buf @%04x %04x.\n",
- dev->name, rx_head, frame_status, rfd_cmd,
- next_rx_frame, data_buffer_addr, pkt_len);
- } else if ((frame_status & 0x2000) == 0) {
- /* Frame Rxed, but with error. */
- dev->stats.rx_errors++;
- if (frame_status & 0x0800) dev->stats.rx_crc_errors++;
- if (frame_status & 0x0400) dev->stats.rx_frame_errors++;
- if (frame_status & 0x0200) dev->stats.rx_fifo_errors++;
- if (frame_status & 0x0100) dev->stats.rx_over_errors++;
- if (frame_status & 0x0080) dev->stats.rx_length_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- pkt_len &= 0x3fff;
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL) {
- printk(KERN_ERR "%s: Memory squeeze, "
- "dropping packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- break;
- }
-
- skb_reserve(skb,2);
-
- /* 'skb->data' points to the start of sk_buff data area. */
- memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len);
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
-
- /* Clear the status word and set End-of-List on the rx frame. */
- writew(0,read_frame);
- writew(0xC000,read_frame+2);
- /* Clear the end-of-list on the prev. RFD. */
- writew(0x0000,lp->base + rx_tail + 2);
-
- rx_tail = rx_head;
- rx_head = next_rx_frame;
- if (--boguscount == 0)
- break;
- }
-
- lp->rx_head = rx_head;
- lp->rx_tail = rx_tail;
-}
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-#ifdef MODULE
-static struct net_device *dev_3c507;
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "EtherLink16 I/O base address");
-MODULE_PARM_DESC(irq, "(ignored)");
-
-int __init init_module(void)
-{
- if (io == 0)
- printk("3c507: You should not use auto-probing with insmod!\n");
- dev_3c507 = el16_probe(-1);
- return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
-}
-
-void __exit
-cleanup_module(void)
-{
- struct net_device *dev = dev_3c507;
- unregister_netdev(dev);
- free_irq(dev->irq, dev);
- iounmap(((struct net_local *)netdev_priv(dev))->base);
- release_region(dev->base_addr, EL16_IO_EXTENT);
- free_netdev(dev);
-}
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
-
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -I/usr/src/linux/drivers/net -Wall -Wstrict-prototypes -O6 -m486 -c 3c507.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * c-indent-level: 4
- * End:
- */
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
deleted file mode 100644
index e2ce41d3828..00000000000
--- a/drivers/net/3c523.c
+++ /dev/null
@@ -1,1309 +0,0 @@
-/*
- net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
-
-
- This is an extension to the Linux operating system, and is covered by the
- same GNU General Public License that covers that work.
-
- Copyright 1995, 1996 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
-
- This is basically Michael Hipp's ni52 driver, with a new probing
- algorithm and some minor changes to the 82586 CA and reset routines.
- Thanks a lot Michael for a really clean i82586 implementation! Unless
- otherwise documented in ni52.c, any bugs are mine.
-
- Contrary to the Ethernet-HOWTO, this isn't based on the 3c507 driver in
- any way. The ni52 is a lot easier to modify.
-
- sources:
- ni52.c
-
- Crynwr packet driver collection was a great reference for my first
- attempt at this sucker. The 3c507 driver also helped, until I noticed
- that ni52.c was a lot nicer.
-
- EtherLink/MC: Micro Channel Ethernet Adapter Technical Reference
- Manual, courtesy of 3Com CardFacts, documents the 3c523-specific
- stuff. Information on CardFacts is found in the Ethernet HOWTO.
- Also see <a href="http://www.3com.com/">
-
- Microprocessor Communications Support Chips, T.J. Byers, ISBN
- 0-444-01224-9, has a section on the i82586. It tells you just enough
- to know that you really don't want to learn how to program the chip.
-
- The original device probe code was stolen from ps2esdi.c
-
- Known Problems:
- Since most of the code was stolen from ni52.c, you'll run across the
- same bugs in the 0.62 version of ni52.c, plus maybe a few because of
- the 3c523 idiosynchacies. The 3c523 has 16K of RAM though, so there
- shouldn't be the overrun problem that the 8K ni52 has.
-
- This driver is for a 16K adapter. It should work fine on the 64K
- adapters, but it will only use one of the 4 banks of RAM. Modifying
- this for the 64K version would require a lot of heinous bank
- switching, which I'm sure not interested in doing. If you try to
- implement a bank switching version, you'll basically have to remember
- what bank is enabled and do a switch everytime you access a memory
- location that's not current. You'll also have to remap pointers on
- the driver side, because it only knows about 16K of the memory.
- Anyone desperate or masochistic enough to try?
-
- It seems to be stable now when multiple transmit buffers are used. I
- can't see any performance difference, but then I'm working on a 386SX.
-
- Multicast doesn't work. It doesn't even pretend to work. Don't use
- it. Don't compile your kernel with multicast support. I don't know
- why.
-
- Features:
- This driver is useable as a loadable module. If you try to specify an
- IRQ or a IO address (via insmod 3c523.o irq=xx io=0xyyy), it will
- search the MCA slots until it finds a 3c523 with the specified
- parameters.
-
- This driver does support multiple ethernet cards when used as a module
- (up to MAX_3C523_CARDS, the default being 4)
-
- This has been tested with both BNC and TP versions, internal and
- external transceivers. Haven't tested with the 64K version (that I
- know of).
-
- History:
- Jan 1st, 1996
- first public release
- Feb 4th, 1996
- update to 1.3.59, incorporated multicast diffs from ni52.c
- Feb 15th, 1996
- added shared irq support
- Apr 1999
- added support for multiple cards when used as a module
- added option to disable multicast as is causes problems
- Ganesh Sittampalam <ganesh.sittampalam@magdalen.oxford.ac.uk>
- Stuart Adamson <stuart.adamson@compsoc.net>
- Nov 2001
- added support for ethtool (jgarzik)
-
- $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
- */
-
-#define DRV_NAME "3c523"
-#define DRV_VERSION "17-Nov-2001"
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/mca-legacy.h>
-#include <linux/ethtool.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-
-#include "3c523.h"
-
-/*************************************************************************/
-#define DEBUG /* debug on */
-#define SYSBUSVAL 0 /* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */
-#undef ELMC_MULTICAST /* Disable multicast support as it is somewhat seriously broken at the moment */
-
-#define make32(ptr16) (p->memtop + (short) (ptr16) )
-#define make24(ptr32) ((char *) (ptr32) - p->base)
-#define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop ))
-
-/*************************************************************************/
-/*
- Tables to which we can map values in the configuration registers.
- */
-static int irq_table[] __initdata = {
- 12, 7, 3, 9
-};
-
-static int csr_table[] __initdata = {
- 0x300, 0x1300, 0x2300, 0x3300
-};
-
-static int shm_table[] __initdata = {
- 0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000
-};
-
-/******************* how to calculate the buffers *****************************
-
-
- * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
- * --------------- in a different (more stable?) mode. Only in this mode it's
- * possible to configure the driver with 'NO_NOPCOMMANDS'
-
-sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
-sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12;
-sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8;
-
- * if you don't know the driver, better do not change this values: */
-
-#define RECV_BUFF_SIZE 1524 /* slightly oversized */
-#define XMIT_BUFF_SIZE 1524 /* slightly oversized */
-#define NUM_XMIT_BUFFS 1 /* config for both, 8K and 16K shmem */
-#define NUM_RECV_BUFFS_8 4 /* config for 8K shared mem */
-#define NUM_RECV_BUFFS_16 9 /* config for 16K shared mem */
-
-#if (NUM_XMIT_BUFFS == 1)
-#define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
-#endif
-
-/**************************************************************************/
-
-#define DELAY(x) { mdelay(32 * x); }
-
-/* a much shorter delay: */
-#define DELAY_16(); { udelay(16) ; }
-
-/* wait for command with timeout: */
-#define WAIT_4_SCB_CMD() { int i; \
- for(i=0;i<1024;i++) { \
- if(!p->scb->cmd) break; \
- DELAY_16(); \
- if(i == 1023) { \
- printk(KERN_WARNING "%s:%d: scb_cmd timed out .. resetting i82586\n",\
- dev->name,__LINE__); \
- elmc_id_reset586(); } } }
-
-static irqreturn_t elmc_interrupt(int irq, void *dev_id);
-static int elmc_open(struct net_device *dev);
-static int elmc_close(struct net_device *dev);
-static int elmc_send_packet(struct sk_buff *, struct net_device *);
-static struct net_device_stats *elmc_get_stats(struct net_device *dev);
-static void elmc_timeout(struct net_device *dev);
-#ifdef ELMC_MULTICAST
-static void set_multicast_list(struct net_device *dev);
-#endif
-static const struct ethtool_ops netdev_ethtool_ops;
-
-/* helper-functions */
-static int init586(struct net_device *dev);
-static int check586(struct net_device *dev, unsigned long where, unsigned size);
-static void alloc586(struct net_device *dev);
-static void startrecv586(struct net_device *dev);
-static void *alloc_rfa(struct net_device *dev, void *ptr);
-static void elmc_rcv_int(struct net_device *dev);
-static void elmc_xmt_int(struct net_device *dev);
-static void elmc_rnr_int(struct net_device *dev);
-
-struct priv {
- unsigned long base;
- char *memtop;
- unsigned long mapped_start; /* Start of ioremap */
- volatile struct rfd_struct *rfd_last, *rfd_top, *rfd_first;
- volatile struct scp_struct *scp; /* volatile is important */
- volatile struct iscp_struct *iscp; /* volatile is important */
- volatile struct scb_struct *scb; /* volatile is important */
- volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
-#if (NUM_XMIT_BUFFS == 1)
- volatile struct transmit_cmd_struct *xmit_cmds[2];
- volatile struct nop_cmd_struct *nop_cmds[2];
-#else
- volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
- volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
-#endif
- volatile int nop_point, num_recv_buffs;
- volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
- volatile int xmit_count, xmit_last;
- volatile int slot;
-};
-
-#define elmc_attn586() {elmc_do_attn586(dev->base_addr,ELMC_CTRL_INTE);}
-#define elmc_reset586() {elmc_do_reset586(dev->base_addr,ELMC_CTRL_INTE);}
-
-/* with interrupts disabled - this will clear the interrupt bit in the
- 3c523 control register, and won't put it back. This effectively
- disables interrupts on the card. */
-#define elmc_id_attn586() {elmc_do_attn586(dev->base_addr,0);}
-#define elmc_id_reset586() {elmc_do_reset586(dev->base_addr,0);}
-
-/*************************************************************************/
-/*
- Do a Channel Attention on the 3c523. This is extremely board dependent.
- */
-static void elmc_do_attn586(int ioaddr, int ints)
-{
- /* the 3c523 requires a minimum of 500 ns. The delays here might be
- a little too large, and hence they may cut the performance of the
- card slightly. If someone who knows a little more about Linux
- timing would care to play with these, I'd appreciate it. */
-
- /* this bit masking stuff is crap. I'd rather have separate
- registers with strobe triggers for each of these functions. <sigh>
- Ya take what ya got. */
-
- outb(ELMC_CTRL_RST | 0x3 | ELMC_CTRL_CA | ints, ioaddr + ELMC_CTRL);
- DELAY_16(); /* > 500 ns */
- outb(ELMC_CTRL_RST | 0x3 | ints, ioaddr + ELMC_CTRL);
-}
-
-/*************************************************************************/
-/*
- Reset the 82586 on the 3c523. Also very board dependent.
- */
-static void elmc_do_reset586(int ioaddr, int ints)
-{
- /* toggle the RST bit low then high */
- outb(0x3 | ELMC_CTRL_LBK, ioaddr + ELMC_CTRL);
- DELAY_16(); /* > 500 ns */
- outb(ELMC_CTRL_RST | ELMC_CTRL_LBK | 0x3, ioaddr + ELMC_CTRL);
-
- elmc_do_attn586(ioaddr, ints);
-}
-
-/**********************************************
- * close device
- */
-
-static int elmc_close(struct net_device *dev)
-{
- netif_stop_queue(dev);
- elmc_id_reset586(); /* the hard way to stop the receiver */
- free_irq(dev->irq, dev);
- return 0;
-}
-
-/**********************************************
- * open device
- */
-
-static int elmc_open(struct net_device *dev)
-{
- int ret;
-
- elmc_id_attn586(); /* disable interrupts */
-
- ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- dev->name, dev);
- if (ret) {
- printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq);
- elmc_id_reset586();
- return ret;
- }
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- netif_start_queue(dev);
- return 0; /* most done by init */
-}
-
-/**********************************************
- * Check to see if there's an 82586 out there.
- */
-
-static int __init check586(struct net_device *dev, unsigned long where, unsigned size)
-{
- struct priv *p = (struct priv *) dev->priv;
- char *iscp_addrs[2];
- int i = 0;
-
- p->base = (unsigned long) isa_bus_to_virt((unsigned long)where) + size - 0x01000000;
- p->memtop = isa_bus_to_virt((unsigned long)where) + size;
- p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
- memset((char *) p->scp, 0, sizeof(struct scp_struct));
- p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */
-
- iscp_addrs[0] = isa_bus_to_virt((unsigned long)where);
- iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct);
-
- for (i = 0; i < 2; i++) {
- p->iscp = (struct iscp_struct *) iscp_addrs[i];
- memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
-
- p->scp->iscp = make24(p->iscp);
- p->iscp->busy = 1;
-
- elmc_id_reset586();
-
- /* reset586 does an implicit CA */
-
- /* apparently, you sometimes have to kick the 82586 twice... */
- elmc_id_attn586();
- DELAY(1);
-
- if (p->iscp->busy) { /* i82586 clears 'busy' after successful init */
- return 0;
- }
- }
- return 1;
-}
-
-/******************************************************************
- * set iscp at the right place, called by elmc_probe and open586.
- */
-
-void alloc586(struct net_device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
-
- elmc_id_reset586();
- DELAY(2);
-
- p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
- p->scb = (struct scb_struct *) isa_bus_to_virt(dev->mem_start);
- p->iscp = (struct iscp_struct *) ((char *) p->scp - sizeof(struct iscp_struct));
-
- memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
- memset((char *) p->scp, 0, sizeof(struct scp_struct));
-
- p->scp->iscp = make24(p->iscp);
- p->scp->sysbus = SYSBUSVAL;
- p->iscp->scb_offset = make16(p->scb);
-
- p->iscp->busy = 1;
- elmc_id_reset586();
- elmc_id_attn586();
-
- DELAY(2);
-
- if (p->iscp->busy) {
- printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
- }
- memset((char *) p->scb, 0, sizeof(struct scb_struct));
-}
-
-/*****************************************************************/
-
-static int elmc_getinfo(char *buf, int slot, void *d)
-{
- int len = 0;
- struct net_device *dev = d;
- DECLARE_MAC_BUF(mac);
-
- if (dev == NULL)
- return len;
-
- len += sprintf(buf + len, "Revision: 0x%x\n",
- inb(dev->base_addr + ELMC_REVISION) & 0xf);
- len += sprintf(buf + len, "IRQ: %d\n", dev->irq);
- len += sprintf(buf + len, "IO Address: %#lx-%#lx\n", dev->base_addr,
- dev->base_addr + ELMC_IO_EXTENT);
- len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
- dev->mem_end - 1);
- len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ?
- "External" : "Internal");
- len += sprintf(buf + len, "Device: %s\n", dev->name);
- len += sprintf(buf + len, "Hardware Address: %s\n",
- print_mac(mac, dev->dev_addr));
-
- return len;
-} /* elmc_getinfo() */
-
-/*****************************************************************/
-
-static int __init do_elmc_probe(struct net_device *dev)
-{
- static int slot;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
- u_char status = 0;
- u_char revision = 0;
- int i = 0;
- unsigned int size = 0;
- int retval;
- struct priv *pr = dev->priv;
- DECLARE_MAC_BUF(mac);
-
- if (MCA_bus == 0) {
- return -ENODEV;
- }
- /* search through the slots for the 3c523. */
- slot = mca_find_adapter(ELMC_MCA_ID, 0);
- while (slot != -1) {
- status = mca_read_stored_pos(slot, 2);
-
- dev->irq=irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
- dev->base_addr=csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
-
- /*
- If we're trying to match a specified irq or IO address,
- we'll reject a match unless it's what we're looking for.
- Also reject it if the card is already in use.
- */
-
- if ((irq && irq != dev->irq) ||
- (base_addr && base_addr != dev->base_addr)) {
- slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
- continue;
- }
- if (!request_region(dev->base_addr, ELMC_IO_EXTENT, DRV_NAME)) {
- slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
- continue;
- }
-
- /* found what we're looking for... */
- break;
- }
-
- /* we didn't find any 3c523 in the slots we checked for */
- if (slot == MCA_NOTFOUND)
- return ((base_addr || irq) ? -ENXIO : -ENODEV);
-
- mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
- mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
-
- /* if we get this far, adapter has been found - carry on */
- printk(KERN_INFO "%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
-
- /* Now we extract configuration info from the card.
- The 3c523 provides information in two of the POS registers, but
- the second one is only needed if we want to tell the card what IRQ
- to use. I suspect that whoever sets the thing up initially would
- prefer we don't screw with those things.
-
- Note that we read the status info when we found the card...
-
- See 3c523.h for more details.
- */
-
- /* revision is stored in the first 4 bits of the revision register */
- revision = inb(dev->base_addr + ELMC_REVISION) & 0xf;
-
- /* according to docs, we read the interrupt and write it back to
- the IRQ select register, since the POST might not configure the IRQ
- properly. */
- switch (dev->irq) {
- case 3:
- mca_write_pos(slot, 3, 0x04);
- break;
- case 7:
- mca_write_pos(slot, 3, 0x02);
- break;
- case 9:
- mca_write_pos(slot, 3, 0x08);
- break;
- case 12:
- mca_write_pos(slot, 3, 0x01);
- break;
- }
-
- memset(pr, 0, sizeof(struct priv));
- pr->slot = slot;
-
- printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
- dev->base_addr);
-
- /* Determine if we're using the on-board transceiver (i.e. coax) or
- an external one. The information is pretty much useless, but I
- guess it's worth brownie points. */
- dev->if_port = (status & ELMC_STATUS_DISABLE_THIN);
-
- /* The 3c523 has a 24K chunk of memory. The first 16K is the
- shared memory, while the last 8K is for the EtherStart BIOS ROM.
- Which we don't care much about here. We'll just tell Linux that
- we're using 16K. MCA won't permit address space conflicts caused
- by not mapping the other 8K. */
- dev->mem_start = shm_table[(status & ELMC_STATUS_MEMORY_SELECT) >> 3];
-
- /* We're using MCA, so it's a given that the information about memory
- size is correct. The Crynwr drivers do something like this. */
-
- elmc_id_reset586(); /* seems like a good idea before checking it... */
-
- size = 0x4000; /* check for 16K mem */
- if (!check586(dev, dev->mem_start, size)) {
- printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
- dev->mem_start);
- retval = -ENODEV;
- goto err_out;
- }
- dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
-
- pr->memtop = isa_bus_to_virt(dev->mem_start) + size;
- pr->base = (unsigned long) isa_bus_to_virt(dev->mem_start) + size - 0x01000000;
- alloc586(dev);
-
- elmc_id_reset586(); /* make sure it doesn't generate spurious ints */
-
- /* set number of receive-buffs according to memsize */
- pr->num_recv_buffs = NUM_RECV_BUFFS_16;
-
- /* dump all the assorted information */
- printk(KERN_INFO "%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
- dev->irq, dev->if_port ? "ex" : "in",
- dev->mem_start, dev->mem_end - 1);
-
- /* The hardware address for the 3c523 is stored in the first six
- bytes of the IO address. */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(dev->base_addr + i);
-
- printk(KERN_INFO "%s: hardware address %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
-
- dev->open = &elmc_open;
- dev->stop = &elmc_close;
- dev->get_stats = &elmc_get_stats;
- dev->hard_start_xmit = &elmc_send_packet;
- dev->tx_timeout = &elmc_timeout;
- dev->watchdog_timeo = HZ;
-#ifdef ELMC_MULTICAST
- dev->set_multicast_list = &set_multicast_list;
-#else
- dev->set_multicast_list = NULL;
-#endif
- dev->ethtool_ops = &netdev_ethtool_ops;
-
- /* note that we haven't actually requested the IRQ from the kernel.
- That gets done in elmc_open(). I'm not sure that's such a good idea,
- but it works, so I'll go with it. */
-
-#ifndef ELMC_MULTICAST
- dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */
-#endif
-
- retval = register_netdev(dev);
- if (retval)
- goto err_out;
-
- return 0;
-err_out:
- mca_set_adapter_procfn(slot, NULL, NULL);
- release_region(dev->base_addr, ELMC_IO_EXTENT);
- return retval;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot, NULL, NULL);
- release_region(dev->base_addr, ELMC_IO_EXTENT);
-}
-
-#ifndef MODULE
-struct net_device * __init elmc_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct priv));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_elmc_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-/**********************************************
- * init the chip (elmc-interrupt should be disabled?!)
- * needs a correct 'allocated' memory
- */
-
-static int init586(struct net_device *dev)
-{
- void *ptr;
- unsigned long s;
- int i, result = 0;
- struct priv *p = (struct priv *) dev->priv;
- volatile struct configure_cmd_struct *cfg_cmd;
- volatile struct iasetup_cmd_struct *ias_cmd;
- volatile struct tdr_cmd_struct *tdr_cmd;
- volatile struct mcsetup_cmd_struct *mc_cmd;
- struct dev_mc_list *dmi = dev->mc_list;
- int num_addrs = dev->mc_count;
-
- ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct));
-
- cfg_cmd = (struct configure_cmd_struct *) ptr; /* configure-command */
- cfg_cmd->cmd_status = 0;
- cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
- cfg_cmd->cmd_link = 0xffff;
-
- cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */
- cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */
- cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */
- cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
- cfg_cmd->priority = 0x00;
- cfg_cmd->ifs = 0x60;
- cfg_cmd->time_low = 0x00;
- cfg_cmd->time_high = 0xf2;
- cfg_cmd->promisc = 0;
- if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC))
- cfg_cmd->promisc = 1;
- cfg_cmd->carr_coll = 0x00;
-
- p->scb->cbl_offset = make16(cfg_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_id_attn586();
-
- s = jiffies; /* warning: only active with interrupts on !! */
- while (!(cfg_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100))
- break;
- }
-
- if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
- printk(KERN_WARNING "%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
- return 1;
- }
- /*
- * individual address setup
- */
- ias_cmd = (struct iasetup_cmd_struct *) ptr;
-
- ias_cmd->cmd_status = 0;
- ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
- ias_cmd->cmd_link = 0xffff;
-
- memcpy((char *) &ias_cmd->iaddr, (char *) dev->dev_addr, ETH_ALEN);
-
- p->scb->cbl_offset = make16(ias_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_id_attn586();
-
- s = jiffies;
- while (!(ias_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100))
- break;
- }
-
- if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
- printk(KERN_WARNING "%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status);
- return 1;
- }
- /*
- * TDR, wire check .. e.g. no resistor e.t.c
- */
- tdr_cmd = (struct tdr_cmd_struct *) ptr;
-
- tdr_cmd->cmd_status = 0;
- tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
- tdr_cmd->cmd_link = 0xffff;
- tdr_cmd->status = 0;
-
- p->scb->cbl_offset = make16(tdr_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_attn586();
-
- s = jiffies;
- while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100)) {
- printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
- result = 1;
- break;
- }
- }
-
- if (!result) {
- DELAY(2); /* wait for result */
- result = tdr_cmd->status;
-
- p->scb->cmd = p->scb->status & STAT_MASK;
- elmc_id_attn586(); /* ack the interrupts */
-
- if (result & TDR_LNK_OK) {
- /* empty */
- } else if (result & TDR_XCVR_PRB) {
- printk(KERN_WARNING "%s: TDR: Transceiver problem!\n", dev->name);
- } else if (result & TDR_ET_OPN) {
- printk(KERN_WARNING "%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
- } else if (result & TDR_ET_SRT) {
- if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
- printk(KERN_WARNING "%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
- } else {
- printk(KERN_WARNING "%s: TDR: Unknown status %04x\n", dev->name, result);
- }
- }
- /*
- * ack interrupts
- */
- p->scb->cmd = p->scb->status & STAT_MASK;
- elmc_id_attn586();
-
- /*
- * alloc nop/xmit-cmds
- */
-#if (NUM_XMIT_BUFFS == 1)
- for (i = 0; i < 2; i++) {
- p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- }
- p->xmit_cmds[0] = (struct transmit_cmd_struct *) ptr; /* transmit cmd/buff 0 */
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
-#else
- for (i = 0; i < NUM_XMIT_BUFFS; i++) {
- p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- p->xmit_cmds[i] = (struct transmit_cmd_struct *) ptr; /*transmit cmd/buff 0 */
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
- }
-#endif
-
- ptr = alloc_rfa(dev, (void *) ptr); /* init receive-frame-area */
-
- /*
- * Multicast setup
- */
-
- if (dev->mc_count) {
- /* I don't understand this: do we really need memory after the init? */
- int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
- if (len <= 0) {
- printk(KERN_ERR "%s: Ooooops, no memory for MC-Setup!\n", dev->name);
- } else {
- if (len < num_addrs) {
- num_addrs = len;
- printk(KERN_WARNING "%s: Sorry, can only apply %d MC-Address(es).\n",
- dev->name, num_addrs);
- }
- mc_cmd = (struct mcsetup_cmd_struct *) ptr;
- mc_cmd->cmd_status = 0;
- mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
- mc_cmd->cmd_link = 0xffff;
- mc_cmd->mc_cnt = num_addrs * 6;
- for (i = 0; i < num_addrs; i++) {
- memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr, 6);
- dmi = dmi->next;
- }
- p->scb->cbl_offset = make16(mc_cmd);
- p->scb->cmd = CUC_START;
- elmc_id_attn586();
- s = jiffies;
- while (!(mc_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100))
- break;
- }
- if (!(mc_cmd->cmd_status & STAT_COMPL)) {
- printk(KERN_WARNING "%s: Can't apply multicast-address-list.\n", dev->name);
- }
- }
- }
- /*
- * alloc xmit-buffs / init xmit_cmds
- */
- for (i = 0; i < NUM_XMIT_BUFFS; i++) {
- p->xmit_cbuffs[i] = (char *) ptr; /* char-buffs */
- ptr = (char *) ptr + XMIT_BUFF_SIZE;
- p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */
- ptr = (char *) ptr + sizeof(struct tbd_struct);
- if ((void *) ptr > (void *) p->iscp) {
- printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", dev->name);
- return 1;
- }
- memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
- memset((char *) (p->xmit_buffs[i]), 0, sizeof(struct tbd_struct));
- p->xmit_cmds[i]->cmd_status = STAT_COMPL;
- p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
- p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
- p->xmit_buffs[i]->next = 0xffff;
- p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
- }
-
- p->xmit_count = 0;
- p->xmit_last = 0;
-#ifndef NO_NOPCOMMANDS
- p->nop_point = 0;
-#endif
-
- /*
- * 'start transmitter' (nop-loop)
- */
-#ifndef NO_NOPCOMMANDS
- p->scb->cbl_offset = make16(p->nop_cmds[0]);
- p->scb->cmd = CUC_START;
- elmc_id_attn586();
- WAIT_4_SCB_CMD();
-#else
- p->xmit_cmds[0]->cmd_link = 0xffff;
- p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
-#endif
-
- return 0;
-}
-
-/******************************************************
- * This is a helper routine for elmc_rnr_int() and init586().
- * It sets up the Receive Frame Area (RFA).
- */
-
-static void *alloc_rfa(struct net_device *dev, void *ptr)
-{
- volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr;
- volatile struct rbd_struct *rbd;
- int i;
- struct priv *p = (struct priv *) dev->priv;
-
- memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs);
- p->rfd_first = rfd;
-
- for (i = 0; i < p->num_recv_buffs; i++) {
- rfd[i].next = make16(rfd + (i + 1) % p->num_recv_buffs);
- }
- rfd[p->num_recv_buffs - 1].last = RFD_SUSP; /* RU suspend */
-
- ptr = (void *) (rfd + p->num_recv_buffs);
-
- rbd = (struct rbd_struct *) ptr;
- ptr = (void *) (rbd + p->num_recv_buffs);
-
- /* clr descriptors */
- memset((char *) rbd, 0, sizeof(struct rbd_struct) * p->num_recv_buffs);
-
- for (i = 0; i < p->num_recv_buffs; i++) {
- rbd[i].next = make16((rbd + (i + 1) % p->num_recv_buffs));
- rbd[i].size = RECV_BUFF_SIZE;
- rbd[i].buffer = make24(ptr);
- ptr = (char *) ptr + RECV_BUFF_SIZE;
- }
-
- p->rfd_top = p->rfd_first;
- p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
-
- p->scb->rfa_offset = make16(p->rfd_first);
- p->rfd_first->rbd_offset = make16(rbd);
-
- return ptr;
-}
-
-
-/**************************************************
- * Interrupt Handler ...
- */
-
-static irqreturn_t
-elmc_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- unsigned short stat;
- struct priv *p;
-
- if (!netif_running(dev)) {
- /* The 3c523 has this habit of generating interrupts during the
- reset. I'm not sure if the ni52 has this same problem, but it's
- really annoying if we haven't finished initializing it. I was
- hoping all the elmc_id_* commands would disable this, but I
- might have missed a few. */
-
- elmc_id_attn586(); /* ack inter. and disable any more */
- return IRQ_HANDLED;
- } else if (!(ELMC_CTRL_INT & inb(dev->base_addr + ELMC_CTRL))) {
- /* wasn't this device */
- return IRQ_NONE;
- }
- /* reading ELMC_CTRL also clears the INT bit. */
-
- p = (struct priv *) dev->priv;
-
- while ((stat = p->scb->status & STAT_MASK))
- {
- p->scb->cmd = stat;
- elmc_attn586(); /* ack inter. */
-
- if (stat & STAT_CX) {
- /* command with I-bit set complete */
- elmc_xmt_int(dev);
- }
- if (stat & STAT_FR) {
- /* received a frame */
- elmc_rcv_int(dev);
- }
-#ifndef NO_NOPCOMMANDS
- if (stat & STAT_CNA) {
- /* CU went 'not ready' */
- if (netif_running(dev)) {
- printk(KERN_WARNING "%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
- }
- }
-#endif
-
- if (stat & STAT_RNR) {
- /* RU went 'not ready' */
-
- if (p->scb->status & RU_SUSPEND) {
- /* special case: RU_SUSPEND */
-
- WAIT_4_SCB_CMD();
- p->scb->cmd = RUC_RESUME;
- elmc_attn586();
- } else {
- printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
- elmc_rnr_int(dev);
- }
- }
- WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
- if (p->scb->cmd) { /* timed out? */
- break;
- }
- }
- return IRQ_HANDLED;
-}
-
-/*******************************************************
- * receive-interrupt
- */
-
-static void elmc_rcv_int(struct net_device *dev)
-{
- int status;
- unsigned short totlen;
- struct sk_buff *skb;
- struct rbd_struct *rbd;
- struct priv *p = (struct priv *) dev->priv;
-
- for (; (status = p->rfd_top->status) & STAT_COMPL;) {
- rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
-
- if (status & STAT_OK) { /* frame received without error? */
- if ((totlen = rbd->status) & RBD_LAST) { /* the first and the last buffer? */
- totlen &= RBD_MASK; /* length of this frame */
- rbd->status = 0;
- skb = (struct sk_buff *) dev_alloc_skb(totlen + 2);
- if (skb != NULL) {
- skb_reserve(skb, 2); /* 16 byte alignment */
- skb_put(skb,totlen);
- skb_copy_to_linear_data(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += totlen;
- } else {
- dev->stats.rx_dropped++;
- }
- } else {
- printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);
- dev->stats.rx_dropped++;
- }
- } else { /* frame !(ok), only with 'save-bad-frames' */
- printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);
- dev->stats.rx_errors++;
- }
- p->rfd_top->status = 0;
- p->rfd_top->last = RFD_SUSP;
- p->rfd_last->last = 0; /* delete RU_SUSP */
- p->rfd_last = p->rfd_top;
- p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
- }
-}
-
-/**********************************************************
- * handle 'Receiver went not ready'.
- */
-
-static void elmc_rnr_int(struct net_device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
-
- dev->stats.rx_errors++;
-
- WAIT_4_SCB_CMD(); /* wait for the last cmd */
- p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
- elmc_attn586();
- WAIT_4_SCB_CMD(); /* wait for accept cmd. */
-
- alloc_rfa(dev, (char *) p->rfd_first);
- startrecv586(dev); /* restart RU */
-
- printk(KERN_WARNING "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
-
-}
-
-/**********************************************************
- * handle xmit - interrupt
- */
-
-static void elmc_xmt_int(struct net_device *dev)
-{
- int status;
- struct priv *p = (struct priv *) dev->priv;
-
- status = p->xmit_cmds[p->xmit_last]->cmd_status;
- if (!(status & STAT_COMPL)) {
- printk(KERN_WARNING "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
- }
- if (status & STAT_OK) {
- dev->stats.tx_packets++;
- dev->stats.collisions += (status & TCMD_MAXCOLLMASK);
- } else {
- dev->stats.tx_errors++;
- if (status & TCMD_LATECOLL) {
- printk(KERN_WARNING "%s: late collision detected.\n", dev->name);
- dev->stats.collisions++;
- } else if (status & TCMD_NOCARRIER) {
- dev->stats.tx_carrier_errors++;
- printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);
- } else if (status & TCMD_LOSTCTS) {
- printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);
- } else if (status & TCMD_UNDERRUN) {
- dev->stats.tx_fifo_errors++;
- printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);
- } else if (status & TCMD_MAXCOLL) {
- printk(KERN_WARNING "%s: Max. collisions exceeded.\n", dev->name);
- dev->stats.collisions += 16;
- }
- }
-
-#if (NUM_XMIT_BUFFS != 1)
- if ((++p->xmit_last) == NUM_XMIT_BUFFS) {
- p->xmit_last = 0;
- }
-#endif
-
- netif_wake_queue(dev);
-}
-
-/***********************************************************
- * (re)start the receiver
- */
-
-static void startrecv586(struct net_device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
-
- p->scb->rfa_offset = make16(p->rfd_first);
- p->scb->cmd = RUC_START;
- elmc_attn586(); /* start cmd. */
- WAIT_4_SCB_CMD(); /* wait for accept cmd. (no timeout!!) */
-}
-
-/******************************************************
- * timeout
- */
-
-static void elmc_timeout(struct net_device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
- /* COMMAND-UNIT active? */
- if (p->scb->status & CU_ACTIVE) {
-#ifdef DEBUG
- printk("%s: strange ... timeout with CU active?!?\n", dev->name);
- printk("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, (int) p->xmit_cmds[0]->cmd_status, (int) p->nop_cmds[0]->cmd_status, (int) p->nop_cmds[1]->cmd_status, (int) p->nop_point);
-#endif
- p->scb->cmd = CUC_ABORT;
- elmc_attn586();
- WAIT_4_SCB_CMD();
- p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
- p->scb->cmd = CUC_START;
- elmc_attn586();
- WAIT_4_SCB_CMD();
- netif_wake_queue(dev);
- } else {
-#ifdef DEBUG
- printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);
- printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
-#endif
- elmc_close(dev);
- elmc_open(dev);
- }
-}
-
-/******************************************************
- * send frame
- */
-
-static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- int len;
- int i;
-#ifndef NO_NOPCOMMANDS
- int next_nop;
-#endif
- struct priv *p = (struct priv *) dev->priv;
-
- netif_stop_queue(dev);
-
- len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
-
- if (len != skb->len)
- memset((char *) p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN);
- skb_copy_from_linear_data(skb, (char *) p->xmit_cbuffs[p->xmit_count], skb->len);
-
-#if (NUM_XMIT_BUFFS == 1)
-#ifdef NO_NOPCOMMANDS
- p->xmit_buffs[0]->size = TBD_LAST | len;
- for (i = 0; i < 16; i++) {
- p->scb->cbl_offset = make16(p->xmit_cmds[0]);
- p->scb->cmd = CUC_START;
- p->xmit_cmds[0]->cmd_status = 0;
- elmc_attn586();
- dev->trans_start = jiffies;
- if (!i) {
- dev_kfree_skb(skb);
- }
- WAIT_4_SCB_CMD();
- if ((p->scb->status & CU_ACTIVE)) { /* test it, because CU sometimes doesn't start immediately */
- break;
- }
- if (p->xmit_cmds[0]->cmd_status) {
- break;
- }
- if (i == 15) {
- printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
- }
- }
-#else
- next_nop = (p->nop_point + 1) & 0x1;
- p->xmit_buffs[0]->size = TBD_LAST | len;
-
- p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
- dev->trans_start = jiffies;
- p->nop_point = next_nop;
- dev_kfree_skb(skb);
-#endif
-#else
- p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
- if ((next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS) {
- next_nop = 0;
- }
- p->xmit_cmds[p->xmit_count]->cmd_status = 0;
- p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->nop_cmds[next_nop]->cmd_status = 0;
- p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
- dev->trans_start = jiffies;
- p->xmit_count = next_nop;
- if (p->xmit_count != p->xmit_last)
- netif_wake_queue(dev);
- dev_kfree_skb(skb);
-#endif
- return 0;
-}
-
-/*******************************************
- * Someone wanna have the statistics
- */
-
-static struct net_device_stats *elmc_get_stats(struct net_device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
- unsigned short crc, aln, rsc, ovrn;
-
- crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
- p->scb->crc_errs -= crc;
- aln = p->scb->aln_errs;
- p->scb->aln_errs -= aln;
- rsc = p->scb->rsc_errs;
- p->scb->rsc_errs -= rsc;
- ovrn = p->scb->ovrn_errs;
- p->scb->ovrn_errs -= ovrn;
-
- dev->stats.rx_crc_errors += crc;
- dev->stats.rx_fifo_errors += ovrn;
- dev->stats.rx_frame_errors += aln;
- dev->stats.rx_dropped += rsc;
-
- return &dev->stats;
-}
-
-/********************************************************
- * Set MC list ..
- */
-
-#ifdef ELMC_MULTICAST
-static void set_multicast_list(struct net_device *dev)
-{
- if (!dev->start) {
- /* without a running interface, promiscuous doesn't work */
- return;
- }
- dev->start = 0;
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- dev->start = 1;
-}
-#endif
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr);
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
-#ifdef MODULE
-
-/* Increase if needed ;) */
-#define MAX_3C523_CARDS 4
-
-static struct net_device *dev_elmc[MAX_3C523_CARDS];
-static int irq[MAX_3C523_CARDS];
-static int io[MAX_3C523_CARDS];
-module_param_array(irq, int, NULL, 0);
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");
-MODULE_LICENSE("GPL");
-
-int __init init_module(void)
-{
- int this_dev,found = 0;
-
- /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */
- for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
- struct net_device *dev = alloc_etherdev(sizeof(struct priv));
- if (!dev)
- break;
- dev->irq=irq[this_dev];
- dev->base_addr=io[this_dev];
- if (do_elmc_probe(dev) == 0) {
- dev_elmc[this_dev] = dev;
- found++;
- continue;
- }
- free_netdev(dev);
- if (io[this_dev]==0)
- break;
- printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
- }
-
- if(found==0) {
- if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
- return -ENXIO;
- } else return 0;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
- for (this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
- struct net_device *dev = dev_elmc[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-
-#endif /* MODULE */
diff --git a/drivers/net/3c523.h b/drivers/net/3c523.h
deleted file mode 100644
index 6956441687b..00000000000
--- a/drivers/net/3c523.h
+++ /dev/null
@@ -1,355 +0,0 @@
-#ifndef _3c523_INCLUDE_
-#define _3c523_INCLUDE_
-/*
- This is basically a hacked version of ni52.h, for the 3c523
- Etherlink/MC.
-*/
-
-/*
- * Intel i82586 Ethernet definitions
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same GNU General Public License that covers that work.
- *
- * Copyright 1995 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
- *
- * See 3c523.c for details.
- *
- * $Header: /home/chrisb/linux-1.2.13-3c523/drivers/net/RCS/3c523.h,v 1.6 1996/01/20 05:09:00 chrisb Exp chrisb $
- */
-
-/*
- * where to find the System Configuration Pointer (SCP)
- */
-#define SCP_DEFAULT_ADDRESS 0xfffff4
-
-
-/*
- * System Configuration Pointer Struct
- */
-
-struct scp_struct
-{
- unsigned short zero_dum0; /* has to be zero */
- unsigned char sysbus; /* 0=16Bit,1=8Bit */
- unsigned char zero_dum1; /* has to be zero for 586 */
- unsigned short zero_dum2;
- unsigned short zero_dum3;
- char *iscp; /* pointer to the iscp-block */
-};
-
-
-/*
- * Intermediate System Configuration Pointer (ISCP)
- */
-struct iscp_struct
-{
- unsigned char busy; /* 586 clears after successful init */
- unsigned char zero_dummy; /* hast to be zero */
- unsigned short scb_offset; /* pointeroffset to the scb_base */
- char *scb_base; /* base-address of all 16-bit offsets */
-};
-
-/*
- * System Control Block (SCB)
- */
-struct scb_struct
-{
- unsigned short status; /* status word */
- unsigned short cmd; /* command word */
- unsigned short cbl_offset; /* pointeroffset, command block list */
- unsigned short rfa_offset; /* pointeroffset, receive frame area */
- unsigned short crc_errs; /* CRC-Error counter */
- unsigned short aln_errs; /* alignmenterror counter */
- unsigned short rsc_errs; /* Resourceerror counter */
- unsigned short ovrn_errs; /* OVerrunerror counter */
-};
-
-/*
- * possible command values for the command word
- */
-#define RUC_MASK 0x0070 /* mask for RU commands */
-#define RUC_NOP 0x0000 /* NOP-command */
-#define RUC_START 0x0010 /* start RU */
-#define RUC_RESUME 0x0020 /* resume RU after suspend */
-#define RUC_SUSPEND 0x0030 /* suspend RU */
-#define RUC_ABORT 0x0040 /* abort receiver operation immediately */
-
-#define CUC_MASK 0x0700 /* mask for CU command */
-#define CUC_NOP 0x0000 /* NOP-command */
-#define CUC_START 0x0100 /* start execution of 1. cmd on the CBL */
-#define CUC_RESUME 0x0200 /* resume after suspend */
-#define CUC_SUSPEND 0x0300 /* Suspend CU */
-#define CUC_ABORT 0x0400 /* abort command operation immediately */
-
-#define ACK_MASK 0xf000 /* mask for ACK command */
-#define ACK_CX 0x8000 /* acknowledges STAT_CX */
-#define ACK_FR 0x4000 /* ack. STAT_FR */
-#define ACK_CNA 0x2000 /* ack. STAT_CNA */
-#define ACK_RNR 0x1000 /* ack. STAT_RNR */
-
-/*
- * possible status values for the status word
- */
-#define STAT_MASK 0xf000 /* mask for cause of interrupt */
-#define STAT_CX 0x8000 /* CU finished cmd with its I bit set */
-#define STAT_FR 0x4000 /* RU finished receiving a frame */
-#define STAT_CNA 0x2000 /* CU left active state */
-#define STAT_RNR 0x1000 /* RU left ready state */
-
-#define CU_STATUS 0x700 /* CU status, 0=idle */
-#define CU_SUSPEND 0x100 /* CU is suspended */
-#define CU_ACTIVE 0x200 /* CU is active */
-
-#define RU_STATUS 0x70 /* RU status, 0=idle */
-#define RU_SUSPEND 0x10 /* RU suspended */
-#define RU_NOSPACE 0x20 /* RU no resources */
-#define RU_READY 0x40 /* RU is ready */
-
-/*
- * Receive Frame Descriptor (RFD)
- */
-struct rfd_struct
-{
- unsigned short status; /* status word */
- unsigned short last; /* Bit15,Last Frame on List / Bit14,suspend */
- unsigned short next; /* linkoffset to next RFD */
- unsigned short rbd_offset; /* pointeroffset to RBD-buffer */
- unsigned char dest[6]; /* ethernet-address, destination */
- unsigned char source[6]; /* ethernet-address, source */
- unsigned short length; /* 802.3 frame-length */
- unsigned short zero_dummy; /* dummy */
-};
-
-#define RFD_LAST 0x8000 /* last: last rfd in the list */
-#define RFD_SUSP 0x4000 /* last: suspend RU after */
-#define RFD_ERRMASK 0x0fe1 /* status: errormask */
-#define RFD_MATCHADD 0x0002 /* status: Destinationaddress !matches IA */
-#define RFD_RNR 0x0200 /* status: receiver out of resources */
-
-/*
- * Receive Buffer Descriptor (RBD)
- */
-struct rbd_struct
-{
- unsigned short status; /* status word,number of used bytes in buff */
- unsigned short next; /* pointeroffset to next RBD */
- char *buffer; /* receive buffer address pointer */
- unsigned short size; /* size of this buffer */
- unsigned short zero_dummy; /* dummy */
-};
-
-#define RBD_LAST 0x8000 /* last buffer */
-#define RBD_USED 0x4000 /* this buffer has data */
-#define RBD_MASK 0x3fff /* size-mask for length */
-
-/*
- * Statusvalues for Commands/RFD
- */
-#define STAT_COMPL 0x8000 /* status: frame/command is complete */
-#define STAT_BUSY 0x4000 /* status: frame/command is busy */
-#define STAT_OK 0x2000 /* status: frame/command is ok */
-
-/*
- * Action-Commands
- */
-#define CMD_NOP 0x0000 /* NOP */
-#define CMD_IASETUP 0x0001 /* initial address setup command */
-#define CMD_CONFIGURE 0x0002 /* configure command */
-#define CMD_MCSETUP 0x0003 /* MC setup command */
-#define CMD_XMIT 0x0004 /* transmit command */
-#define CMD_TDR 0x0005 /* time domain reflectometer (TDR) command */
-#define CMD_DUMP 0x0006 /* dump command */
-#define CMD_DIAGNOSE 0x0007 /* diagnose command */
-
-/*
- * Action command bits
- */
-#define CMD_LAST 0x8000 /* indicates last command in the CBL */
-#define CMD_SUSPEND 0x4000 /* suspend CU after this CB */
-#define CMD_INT 0x2000 /* generate interrupt after execution */
-
-/*
- * NOP - command
- */
-struct nop_cmd_struct
-{
- unsigned short cmd_status; /* status of this command */
- unsigned short cmd_cmd; /* the command itself (+bits) */
- unsigned short cmd_link; /* offsetpointer to next command */
-};
-
-/*
- * IA Setup command
- */
-struct iasetup_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char iaddr[6];
-};
-
-/*
- * Configure command
- */
-struct configure_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char byte_cnt; /* size of the config-cmd */
- unsigned char fifo; /* fifo/recv monitor */
- unsigned char sav_bf; /* save bad frames (bit7=1)*/
- unsigned char adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
- unsigned char priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
- unsigned char ifs; /* inter frame spacing */
- unsigned char time_low; /* slot time low */
- unsigned char time_high; /* slot time high(0-2) and max. retries(4-7) */
- unsigned char promisc; /* promisc-mode(0) , et al (1-7) */
- unsigned char carr_coll; /* carrier(0-3)/collision(4-7) stuff */
- unsigned char fram_len; /* minimal frame len */
- unsigned char dummy; /* dummy */
-};
-
-/*
- * Multicast Setup command
- */
-struct mcsetup_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short mc_cnt; /* number of bytes in the MC-List */
- unsigned char mc_list[0][6]; /* pointer to 6 bytes entries */
-};
-
-/*
- * transmit command
- */
-struct transmit_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short tbd_offset; /* pointeroffset to TBD */
- unsigned char dest[6]; /* destination address of the frame */
- unsigned short length; /* user defined: 802.3 length / Ether type */
-};
-
-#define TCMD_ERRMASK 0x0fa0
-#define TCMD_MAXCOLLMASK 0x000f
-#define TCMD_MAXCOLL 0x0020
-#define TCMD_HEARTBEAT 0x0040
-#define TCMD_DEFERRED 0x0080
-#define TCMD_UNDERRUN 0x0100
-#define TCMD_LOSTCTS 0x0200
-#define TCMD_NOCARRIER 0x0400
-#define TCMD_LATECOLL 0x0800
-
-struct tdr_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short status;
-};
-
-#define TDR_LNK_OK 0x8000 /* No link problem identified */
-#define TDR_XCVR_PRB 0x4000 /* indicates a transceiver problem */
-#define TDR_ET_OPN 0x2000 /* open, no correct termination */
-#define TDR_ET_SRT 0x1000 /* TDR detected a short circuit */
-#define TDR_TIMEMASK 0x07ff /* mask for the time field */
-
-/*
- * Transmit Buffer Descriptor (TBD)
- */
-struct tbd_struct
-{
- unsigned short size; /* size + EOF-Flag(15) */
- unsigned short next; /* pointeroffset to next TBD */
- char *buffer; /* pointer to buffer */
-};
-
-#define TBD_LAST 0x8000 /* EOF-Flag, indicates last buffer in list */
-
-/*************************************************************************/
-/*
-Verbatim from the Crynwyr stuff:
-
- The 3c523 responds with adapter code 0x6042 at slot
-registers xxx0 and xxx1. The setup register is at xxx2 and
-contains the following bits:
-
-0: card enable
-2,1: csr address select
- 00 = 0300
- 01 = 1300
- 10 = 2300
- 11 = 3300
-4,3: shared memory address select
- 00 = 0c0000
- 01 = 0c8000
- 10 = 0d0000
- 11 = 0d8000
-5: set to disable on-board thinnet
-7,6: (read-only) shows selected irq
- 00 = 12
- 01 = 7
- 10 = 3
- 11 = 9
-
-The interrupt-select register is at xxx3 and uses one bit per irq.
-
-0: int 12
-1: int 7
-2: int 3
-3: int 9
-
- Again, the documentation stresses that the setup register
-should never be written. The interrupt-select register may be
-written with the value corresponding to bits 7.6 in
-the setup register to insure corret setup.
-*/
-
-/* Offsets from the base I/O address. */
-#define ELMC_SA 0 /* first 6 bytes are IEEE network address */
-#define ELMC_CTRL 6 /* control & status register */
-#define ELMC_REVISION 7 /* revision register, first 4 bits only */
-#define ELMC_IO_EXTENT 8
-
-/* these are the bit selects for the port register 2 */
-#define ELMC_STATUS_ENABLED 0x01
-#define ELMC_STATUS_CSR_SELECT 0x06
-#define ELMC_STATUS_MEMORY_SELECT 0x18
-#define ELMC_STATUS_DISABLE_THIN 0x20
-#define ELMC_STATUS_IRQ_SELECT 0xc0
-
-/* this is the card id used in the detection code. You might recognize
-it from @6042.adf */
-#define ELMC_MCA_ID 0x6042
-
-/*
- The following define the bits for the control & status register
-
- The bank select registers can be used if more than 16K of memory is
- on the card. For some stupid reason, bank 3 is the one for the
- bottom 16K, and the card defaults to bank 0. So we have to set the
- bank to 3 before the card will even think of operating. To get bank
- 3, set BS0 and BS1 to high (of course...)
-*/
-#define ELMC_CTRL_BS0 0x01 /* RW bank select */
-#define ELMC_CTRL_BS1 0x02 /* RW bank select */
-#define ELMC_CTRL_INTE 0x04 /* RW interrupt enable, assert high */
-#define ELMC_CTRL_INT 0x08 /* R interrupt active, assert high */
-/*#define ELMC_CTRL_* 0x10*/ /* reserved */
-#define ELMC_CTRL_LBK 0x20 /* RW loopback enable, assert high */
-#define ELMC_CTRL_CA 0x40 /* RW channel attention, assert high */
-#define ELMC_CTRL_RST 0x80 /* RW 82586 reset, assert low */
-
-/* some handy compound bits */
-
-/* normal operation should have bank 3 and RST high, ints enabled */
-#define ELMC_NORMAL (ELMC_CTRL_INTE|ELMC_CTRL_RST|0x3)
-
-#endif /* _3c523_INCLUDE_ */
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
deleted file mode 100644
index abc84f76597..00000000000
--- a/drivers/net/3c527.c
+++ /dev/null
@@ -1,1661 +0,0 @@
-/* 3c527.c: 3Com Etherlink/MC32 driver for Linux 2.4 and 2.6.
- *
- * (c) Copyright 1998 Red Hat Software Inc
- * Written by Alan Cox.
- * Further debugging by Carl Drougge.
- * Initial SMP support by Felipe W Damasio <felipewd@terra.com.br>
- * Heavily modified by Richard Procter <rnp@paradise.net.nz>
- *
- * Based on skeleton.c written 1993-94 by Donald Becker and ne2.c
- * (for the MCA stuff) written by Wim Dumon.
- *
- * Thanks to 3Com for making this possible by providing me with the
- * documentation.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#define DRV_NAME "3c527"
-#define DRV_VERSION "0.7-SMP"
-#define DRV_RELDATE "2003/09/21"
-
-static const char *version =
-DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Procter <rnp@paradise.net.nz>\n";
-
-/**
- * DOC: Traps for the unwary
- *
- * The diagram (Figure 1-1) and the POS summary disagree with the
- * "Interrupt Level" section in the manual.
- *
- * The manual contradicts itself when describing the minimum number
- * buffers in the 'configure lists' command.
- * My card accepts a buffer config of 4/4.
- *
- * Setting the SAV BP bit does not save bad packets, but
- * only enables RX on-card stats collection.
- *
- * The documentation in places seems to miss things. In actual fact
- * I've always eventually found everything is documented, it just
- * requires careful study.
- *
- * DOC: Theory Of Operation
- *
- * The 3com 3c527 is a 32bit MCA bus mastering adapter with a large
- * amount of on board intelligence that housekeeps a somewhat dumber
- * Intel NIC. For performance we want to keep the transmit queue deep
- * as the card can transmit packets while fetching others from main
- * memory by bus master DMA. Transmission and reception are driven by
- * circular buffer queues.
- *
- * The mailboxes can be used for controlling how the card traverses
- * its buffer rings, but are used only for inital setup in this
- * implementation. The exec mailbox allows a variety of commands to
- * be executed. Each command must complete before the next is
- * executed. Primarily we use the exec mailbox for controlling the
- * multicast lists. We have to do a certain amount of interesting
- * hoop jumping as the multicast list changes can occur in interrupt
- * state when the card has an exec command pending. We defer such
- * events until the command completion interrupt.
- *
- * A copy break scheme (taken from 3c59x.c) is employed whereby
- * received frames exceeding a configurable length are passed
- * directly to the higher networking layers without incuring a copy,
- * in what amounts to a time/space trade-off.
- *
- * The card also keeps a large amount of statistical information
- * on-board. In a perfect world, these could be used safely at no
- * cost. However, lacking information to the contrary, processing
- * them without races would involve so much extra complexity as to
- * make it unworthwhile to do so. In the end, a hybrid SW/HW
- * implementation was made necessary --- see mc32_update_stats().
- *
- * DOC: Notes
- *
- * It should be possible to use two or more cards, but at this stage
- * only by loading two copies of the same module.
- *
- * The on-board 82586 NIC has trouble receiving multiple
- * back-to-back frames and so is likely to drop packets from fast
- * senders.
-**/
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_ether.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/mca-legacy.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/ethtool.h>
-#include <linux/completion.h>
-#include <linux/bitops.h>
-#include <linux/semaphore.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "3c527.h"
-
-MODULE_LICENSE("GPL");
-
-/*
- * The name of the card. Is used for messages and in the requests for
- * io regions, irqs and dma channels
- */
-static const char* cardname = DRV_NAME;
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-
-#undef DEBUG_IRQ
-
-static unsigned int mc32_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define MC32_IO_EXTENT 8
-
-/* As implemented, values must be a power-of-2 -- 4/8/16/32 */
-#define TX_RING_LEN 32 /* Typically the card supports 37 */
-#define RX_RING_LEN 8 /* " " " */
-
-/* Copy break point, see above for details.
- * Setting to > 1512 effectively disables this feature. */
-#define RX_COPYBREAK 200 /* Value from 3c59x.c */
-
-/* Issue the 82586 workaround command - this is for "busy lans", but
- * basically means for all lans now days - has a performance (latency)
- * cost, but best set. */
-static const int WORKAROUND_82586=1;
-
-/* Pointers to buffers and their on-card records */
-struct mc32_ring_desc
-{
- volatile struct skb_header *p;
- struct sk_buff *skb;
-};
-
-/* Information that needs to be kept for each board. */
-struct mc32_local
-{
- int slot;
-
- u32 base;
- volatile struct mc32_mailbox *rx_box;
- volatile struct mc32_mailbox *tx_box;
- volatile struct mc32_mailbox *exec_box;
- volatile struct mc32_stats *stats; /* Start of on-card statistics */
- u16 tx_chain; /* Transmit list start offset */
- u16 rx_chain; /* Receive list start offset */
- u16 tx_len; /* Transmit list count */
- u16 rx_len; /* Receive list count */
-
- u16 xceiver_desired_state; /* HALTED or RUNNING */
- u16 cmd_nonblocking; /* Thread is uninterested in command result */
- u16 mc_reload_wait; /* A multicast load request is pending */
- u32 mc_list_valid; /* True when the mclist is set */
-
- struct mc32_ring_desc tx_ring[TX_RING_LEN]; /* Host Transmit ring */
- struct mc32_ring_desc rx_ring[RX_RING_LEN]; /* Host Receive ring */
-
- atomic_t tx_count; /* buffers left */
- atomic_t tx_ring_head; /* index to tx en-queue end */
- u16 tx_ring_tail; /* index to tx de-queue end */
-
- u16 rx_ring_tail; /* index to rx de-queue end */
-
- struct semaphore cmd_mutex; /* Serialises issuing of execute commands */
- struct completion execution_cmd; /* Card has completed an execute command */
- struct completion xceiver_cmd; /* Card has completed a tx or rx command */
-};
-
-/* The station (ethernet) address prefix, used for a sanity check. */
-#define SA_ADDR0 0x02
-#define SA_ADDR1 0x60
-#define SA_ADDR2 0xAC
-
-struct mca_adapters_t {
- unsigned int id;
- char *name;
-};
-
-static const struct mca_adapters_t mc32_adapters[] = {
- { 0x0041, "3COM EtherLink MC/32" },
- { 0x8EF5, "IBM High Performance Lan Adapter" },
- { 0x0000, NULL }
-};
-
-
-/* Macros for ring index manipulations */
-static inline u16 next_rx(u16 rx) { return (rx+1)&(RX_RING_LEN-1); };
-static inline u16 prev_rx(u16 rx) { return (rx-1)&(RX_RING_LEN-1); };
-
-static inline u16 next_tx(u16 tx) { return (tx+1)&(TX_RING_LEN-1); };
-
-
-/* Index to functions, as function prototypes. */
-static int mc32_probe1(struct net_device *dev, int ioaddr);
-static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len);
-static int mc32_open(struct net_device *dev);
-static void mc32_timeout(struct net_device *dev);
-static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t mc32_interrupt(int irq, void *dev_id);
-static int mc32_close(struct net_device *dev);
-static struct net_device_stats *mc32_get_stats(struct net_device *dev);
-static void mc32_set_multicast_list(struct net_device *dev);
-static void mc32_reset_multicast_list(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-static void cleanup_card(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- unsigned slot = lp->slot;
- mca_mark_as_unused(slot);
- mca_set_adapter_name(slot, NULL);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, MC32_IO_EXTENT);
-}
-
-/**
- * mc32_probe - Search for supported boards
- * @unit: interface number to use
- *
- * Because MCA bus is a real bus and we can scan for cards we could do a
- * single scan for all boards here. Right now we use the passed in device
- * structure and scan for only one board. This needs fixing for modules
- * in particular.
- */
-
-struct net_device *__init mc32_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct mc32_local));
- static int current_mca_slot = -1;
- int i;
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- if (unit >= 0)
- sprintf(dev->name, "eth%d", unit);
-
- /* Do not check any supplied i/o locations.
- POS registers usually don't fail :) */
-
- /* MCA cards have POS registers.
- Autodetecting MCA cards is extremely simple.
- Just search for the card. */
-
- for(i = 0; (mc32_adapters[i].name != NULL); i++) {
- current_mca_slot =
- mca_find_unused_adapter(mc32_adapters[i].id, 0);
-
- if(current_mca_slot != MCA_NOTFOUND) {
- if(!mc32_probe1(dev, current_mca_slot))
- {
- mca_set_adapter_name(current_mca_slot,
- mc32_adapters[i].name);
- mca_mark_as_used(current_mca_slot);
- err = register_netdev(dev);
- if (err) {
- cleanup_card(dev);
- free_netdev(dev);
- dev = ERR_PTR(err);
- }
- return dev;
- }
-
- }
- }
- free_netdev(dev);
- return ERR_PTR(-ENODEV);
-}
-
-/**
- * mc32_probe1 - Check a given slot for a board and test the card
- * @dev: Device structure to fill in
- * @slot: The MCA bus slot being used by this card
- *
- * Decode the slot data and configure the card structures. Having done this we
- * can reset the card and configure it. The card does a full self test cycle
- * in firmware so we have to wait for it to return and post us either a
- * failure case or some addresses we use to find the board internals.
- */
-
-static int __init mc32_probe1(struct net_device *dev, int slot)
-{
- static unsigned version_printed;
- int i, err;
- u8 POS;
- u32 base;
- struct mc32_local *lp = netdev_priv(dev);
- static u16 mca_io_bases[]={
- 0x7280,0x7290,
- 0x7680,0x7690,
- 0x7A80,0x7A90,
- 0x7E80,0x7E90
- };
- static u32 mca_mem_bases[]={
- 0x00C0000,
- 0x00C4000,
- 0x00C8000,
- 0x00CC000,
- 0x00D0000,
- 0x00D4000,
- 0x00D8000,
- 0x00DC000
- };
- static char *failures[]={
- "Processor instruction",
- "Processor data bus",
- "Processor data bus",
- "Processor data bus",
- "Adapter bus",
- "ROM checksum",
- "Base RAM",
- "Extended RAM",
- "82586 internal loopback",
- "82586 initialisation failure",
- "Adapter list configuration error"
- };
- DECLARE_MAC_BUF(mac);
-
- /* Time to play MCA games */
-
- if (mc32_debug && version_printed++ == 0)
- printk(KERN_DEBUG "%s", version);
-
- printk(KERN_INFO "%s: %s found in slot %d:", dev->name, cardname, slot);
-
- POS = mca_read_stored_pos(slot, 2);
-
- if(!(POS&1))
- {
- printk(" disabled.\n");
- return -ENODEV;
- }
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = mca_io_bases[(POS>>1)&7];
- dev->mem_start = mca_mem_bases[(POS>>4)&7];
-
- POS = mca_read_stored_pos(slot, 4);
- if(!(POS&1))
- {
- printk("memory window disabled.\n");
- return -ENODEV;
- }
-
- POS = mca_read_stored_pos(slot, 5);
-
- i=(POS>>4)&3;
- if(i==3)
- {
- printk("invalid memory window.\n");
- return -ENODEV;
- }
-
- i*=16384;
- i+=16384;
-
- dev->mem_end=dev->mem_start + i;
-
- dev->irq = ((POS>>2)&3)+9;
-
- if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
- {
- printk("io 0x%3lX, which is busy.\n", dev->base_addr);
- return -EBUSY;
- }
-
- printk("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
- dev->base_addr, dev->irq, dev->mem_start, i/1024);
-
-
- /* We ought to set the cache line size here.. */
-
-
- /*
- * Go PROM browsing
- */
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- {
- mca_write_pos(slot, 6, i+12);
- mca_write_pos(slot, 7, 0);
-
- dev->dev_addr[i] = mca_read_pos(slot,3);
- }
-
- printk("%s: Address %s", dev->name, print_mac(mac, dev->dev_addr));
-
- mca_write_pos(slot, 6, 0);
- mca_write_pos(slot, 7, 0);
-
- POS = mca_read_stored_pos(slot, 4);
-
- if(POS&2)
- printk(" : BNC port selected.\n");
- else
- printk(" : AUI port selected.\n");
-
- POS=inb(dev->base_addr+HOST_CTRL);
- POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
- POS&=~HOST_CTRL_INTE;
- outb(POS, dev->base_addr+HOST_CTRL);
- /* Reset adapter */
- udelay(100);
- /* Reset off */
- POS&=~(HOST_CTRL_ATTN|HOST_CTRL_RESET);
- outb(POS, dev->base_addr+HOST_CTRL);
-
- udelay(300);
-
- /*
- * Grab the IRQ
- */
-
- err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
- if (err) {
- release_region(dev->base_addr, MC32_IO_EXTENT);
- printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
- goto err_exit_ports;
- }
-
- memset(lp, 0, sizeof(struct mc32_local));
- lp->slot = slot;
-
- i=0;
-
- base = inb(dev->base_addr);
-
- while(base == 0xFF)
- {
- i++;
- if(i == 1000)
- {
- printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
- err = -ENODEV;
- goto err_exit_irq;
- }
- udelay(1000);
- if(inb(dev->base_addr+2)&(1<<5))
- base = inb(dev->base_addr);
- }
-
- if(base>0)
- {
- if(base < 0x0C)
- printk(KERN_ERR "%s: %s%s.\n", dev->name, failures[base-1],
- base<0x0A?" test failure":"");
- else
- printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
- err = -ENODEV;
- goto err_exit_irq;
- }
-
- base=0;
- for(i=0;i<4;i++)
- {
- int n=0;
-
- while(!(inb(dev->base_addr+2)&(1<<5)))
- {
- n++;
- udelay(50);
- if(n>100)
- {
- printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
- err = -ENODEV;
- goto err_exit_irq;
- }
- }
-
- base|=(inb(dev->base_addr)<<(8*i));
- }
-
- lp->exec_box=isa_bus_to_virt(dev->mem_start+base);
-
- base=lp->exec_box->data[1]<<16|lp->exec_box->data[0];
-
- lp->base = dev->mem_start+base;
-
- lp->rx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[2]);
- lp->tx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[3]);
-
- lp->stats = isa_bus_to_virt(lp->base + lp->exec_box->data[5]);
-
- /*
- * Descriptor chains (card relative)
- */
-
- lp->tx_chain = lp->exec_box->data[8]; /* Transmit list start offset */
- lp->rx_chain = lp->exec_box->data[10]; /* Receive list start offset */
- lp->tx_len = lp->exec_box->data[9]; /* Transmit list count */
- lp->rx_len = lp->exec_box->data[11]; /* Receive list count */
-
- init_MUTEX_LOCKED(&lp->cmd_mutex);
- init_completion(&lp->execution_cmd);
- init_completion(&lp->xceiver_cmd);
-
- printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
- dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
-
- dev->open = mc32_open;
- dev->stop = mc32_close;
- dev->hard_start_xmit = mc32_send_packet;
- dev->get_stats = mc32_get_stats;
- dev->set_multicast_list = mc32_set_multicast_list;
- dev->tx_timeout = mc32_timeout;
- dev->watchdog_timeo = HZ*5; /* Board does all the work */
- dev->ethtool_ops = &netdev_ethtool_ops;
-
- return 0;
-
-err_exit_irq:
- free_irq(dev->irq, dev);
-err_exit_ports:
- release_region(dev->base_addr, MC32_IO_EXTENT);
- return err;
-}
-
-
-/**
- * mc32_ready_poll - wait until we can feed it a command
- * @dev: The device to wait for
- *
- * Wait until the card becomes ready to accept a command via the
- * command register. This tells us nothing about the completion
- * status of any pending commands and takes very little time at all.
- */
-
-static inline void mc32_ready_poll(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
-}
-
-
-/**
- * mc32_command_nowait - send a command non blocking
- * @dev: The 3c527 to issue the command to
- * @cmd: The command word to write to the mailbox
- * @data: A data block if the command expects one
- * @len: Length of the data block
- *
- * Send a command from interrupt state. If there is a command
- * currently being executed then we return an error of -1. It
- * simply isn't viable to wait around as commands may be
- * slow. This can theoretically be starved on SMP, but it's hard
- * to see a realistic situation. We do not wait for the command
- * to complete --- we rely on the interrupt handler to tidy up
- * after us.
- */
-
-static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int ret = -1;
-
- if (down_trylock(&lp->cmd_mutex) == 0)
- {
- lp->cmd_nonblocking=1;
- lp->exec_box->mbox=0;
- lp->exec_box->mbox=cmd;
- memcpy((void *)lp->exec_box->data, data, len);
- barrier(); /* the memcpy forgot the volatile so be sure */
-
- /* Send the command */
- mc32_ready_poll(dev);
- outb(1<<6, ioaddr+HOST_CMD);
-
- ret = 0;
-
- /* Interrupt handler will signal mutex on completion */
- }
-
- return ret;
-}
-
-
-/**
- * mc32_command - send a command and sleep until completion
- * @dev: The 3c527 card to issue the command to
- * @cmd: The command word to write to the mailbox
- * @data: A data block if the command expects one
- * @len: Length of the data block
- *
- * Sends exec commands in a user context. This permits us to wait around
- * for the replies and also to wait for the command buffer to complete
- * from a previous command before we execute our command. After our
- * command completes we will attempt any pending multicast reload
- * we blocked off by hogging the exec buffer.
- *
- * You feed the card a command, you wait, it interrupts you get a
- * reply. All well and good. The complication arises because you use
- * commands for filter list changes which come in at bh level from things
- * like IPV6 group stuff.
- */
-
-static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int ret = 0;
-
- down(&lp->cmd_mutex);
-
- /*
- * My Turn
- */
-
- lp->cmd_nonblocking=0;
- lp->exec_box->mbox=0;
- lp->exec_box->mbox=cmd;
- memcpy((void *)lp->exec_box->data, data, len);
- barrier(); /* the memcpy forgot the volatile so be sure */
-
- mc32_ready_poll(dev);
- outb(1<<6, ioaddr+HOST_CMD);
-
- wait_for_completion(&lp->execution_cmd);
-
- if(lp->exec_box->mbox&(1<<13))
- ret = -1;
-
- up(&lp->cmd_mutex);
-
- /*
- * A multicast set got blocked - try it now
- */
-
- if(lp->mc_reload_wait)
- {
- mc32_reset_multicast_list(dev);
- }
-
- return ret;
-}
-
-
-/**
- * mc32_start_transceiver - tell board to restart tx/rx
- * @dev: The 3c527 card to issue the command to
- *
- * This may be called from the interrupt state, where it is used
- * to restart the rx ring if the card runs out of rx buffers.
- *
- * We must first check if it's ok to (re)start the transceiver. See
- * mc32_close for details.
- */
-
-static void mc32_start_transceiver(struct net_device *dev) {
-
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Ignore RX overflow on device closure */
- if (lp->xceiver_desired_state==HALTED)
- return;
-
- /* Give the card the offset to the post-EOL-bit RX descriptor */
- mc32_ready_poll(dev);
- lp->rx_box->mbox=0;
- lp->rx_box->data[0]=lp->rx_ring[prev_rx(lp->rx_ring_tail)].p->next;
- outb(HOST_CMD_START_RX, ioaddr+HOST_CMD);
-
- mc32_ready_poll(dev);
- lp->tx_box->mbox=0;
- outb(HOST_CMD_RESTRT_TX, ioaddr+HOST_CMD); /* card ignores this on RX restart */
-
- /* We are not interrupted on start completion */
-}
-
-
-/**
- * mc32_halt_transceiver - tell board to stop tx/rx
- * @dev: The 3c527 card to issue the command to
- *
- * We issue the commands to halt the card's transceiver. In fact,
- * after some experimenting we now simply tell the card to
- * suspend. When issuing aborts occasionally odd things happened.
- *
- * We then sleep until the card has notified us that both rx and
- * tx have been suspended.
- */
-
-static void mc32_halt_transceiver(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- mc32_ready_poll(dev);
- lp->rx_box->mbox=0;
- outb(HOST_CMD_SUSPND_RX, ioaddr+HOST_CMD);
- wait_for_completion(&lp->xceiver_cmd);
-
- mc32_ready_poll(dev);
- lp->tx_box->mbox=0;
- outb(HOST_CMD_SUSPND_TX, ioaddr+HOST_CMD);
- wait_for_completion(&lp->xceiver_cmd);
-}
-
-
-/**
- * mc32_load_rx_ring - load the ring of receive buffers
- * @dev: 3c527 to build the ring for
- *
- * This initalises the on-card and driver datastructures to
- * the point where mc32_start_transceiver() can be called.
- *
- * The card sets up the receive ring for us. We are required to use the
- * ring it provides, although the size of the ring is configurable.
- *
- * We allocate an sk_buff for each ring entry in turn and
- * initalise its house-keeping info. At the same time, we read
- * each 'next' pointer in our rx_ring array. This reduces slow
- * shared-memory reads and makes it easy to access predecessor
- * descriptors.
- *
- * We then set the end-of-list bit for the last entry so that the
- * card will know when it has run out of buffers.
- */
-
-static int mc32_load_rx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int i;
- u16 rx_base;
- volatile struct skb_header *p;
-
- rx_base=lp->rx_chain;
-
- for(i=0; i<RX_RING_LEN; i++) {
- lp->rx_ring[i].skb=alloc_skb(1532, GFP_KERNEL);
- if (lp->rx_ring[i].skb==NULL) {
- for (;i>=0;i--)
- kfree_skb(lp->rx_ring[i].skb);
- return -ENOBUFS;
- }
- skb_reserve(lp->rx_ring[i].skb, 18);
-
- p=isa_bus_to_virt(lp->base+rx_base);
-
- p->control=0;
- p->data=isa_virt_to_bus(lp->rx_ring[i].skb->data);
- p->status=0;
- p->length=1532;
-
- lp->rx_ring[i].p=p;
- rx_base=p->next;
- }
-
- lp->rx_ring[i-1].p->control |= CONTROL_EOL;
-
- lp->rx_ring_tail=0;
-
- return 0;
-}
-
-
-/**
- * mc32_flush_rx_ring - free the ring of receive buffers
- * @lp: Local data of 3c527 to flush the rx ring of
- *
- * Free the buffer for each ring slot. This may be called
- * before mc32_load_rx_ring(), eg. on error in mc32_open().
- * Requires rx skb pointers to point to a valid skb, or NULL.
- */
-
-static void mc32_flush_rx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int i;
-
- for(i=0; i < RX_RING_LEN; i++)
- {
- if (lp->rx_ring[i].skb) {
- dev_kfree_skb(lp->rx_ring[i].skb);
- lp->rx_ring[i].skb = NULL;
- }
- lp->rx_ring[i].p=NULL;
- }
-}
-
-
-/**
- * mc32_load_tx_ring - load transmit ring
- * @dev: The 3c527 card to issue the command to
- *
- * This sets up the host transmit data-structures.
- *
- * First, we obtain from the card it's current postion in the tx
- * ring, so that we will know where to begin transmitting
- * packets.
- *
- * Then, we read the 'next' pointers from the on-card tx ring into
- * our tx_ring array to reduce slow shared-mem reads. Finally, we
- * intitalise the tx house keeping variables.
- *
- */
-
-static void mc32_load_tx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct skb_header *p;
- int i;
- u16 tx_base;
-
- tx_base=lp->tx_box->data[0];
-
- for(i=0 ; i<TX_RING_LEN ; i++)
- {
- p=isa_bus_to_virt(lp->base+tx_base);
- lp->tx_ring[i].p=p;
- lp->tx_ring[i].skb=NULL;
-
- tx_base=p->next;
- }
-
- /* -1 so that tx_ring_head cannot "lap" tx_ring_tail */
- /* see mc32_tx_ring */
-
- atomic_set(&lp->tx_count, TX_RING_LEN-1);
- atomic_set(&lp->tx_ring_head, 0);
- lp->tx_ring_tail=0;
-}
-
-
-/**
- * mc32_flush_tx_ring - free transmit ring
- * @lp: Local data of 3c527 to flush the tx ring of
- *
- * If the ring is non-empty, zip over the it, freeing any
- * allocated skb_buffs. The tx ring house-keeping variables are
- * then reset. Requires rx skb pointers to point to a valid skb,
- * or NULL.
- */
-
-static void mc32_flush_tx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int i;
-
- for (i=0; i < TX_RING_LEN; i++)
- {
- if (lp->tx_ring[i].skb)
- {
- dev_kfree_skb(lp->tx_ring[i].skb);
- lp->tx_ring[i].skb = NULL;
- }
- }
-
- atomic_set(&lp->tx_count, 0);
- atomic_set(&lp->tx_ring_head, 0);
- lp->tx_ring_tail=0;
-}
-
-
-/**
- * mc32_open - handle 'up' of card
- * @dev: device to open
- *
- * The user is trying to bring the card into ready state. This requires
- * a brief dialogue with the card. Firstly we enable interrupts and then
- * 'indications'. Without these enabled the card doesn't bother telling
- * us what it has done. This had me puzzled for a week.
- *
- * We configure the number of card descriptors, then load the network
- * address and multicast filters. Turn on the workaround mode. This
- * works around a bug in the 82586 - it asks the firmware to do
- * so. It has a performance (latency) hit but is needed on busy
- * [read most] lans. We load the ring with buffers then we kick it
- * all off.
- */
-
-static int mc32_open(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- struct mc32_local *lp = netdev_priv(dev);
- u8 one=1;
- u8 regs;
- u16 descnumbuffs[2] = {TX_RING_LEN, RX_RING_LEN};
-
- /*
- * Interrupts enabled
- */
-
- regs=inb(ioaddr+HOST_CTRL);
- regs|=HOST_CTRL_INTE;
- outb(regs, ioaddr+HOST_CTRL);
-
- /*
- * Allow ourselves to issue commands
- */
-
- up(&lp->cmd_mutex);
-
-
- /*
- * Send the indications on command
- */
-
- mc32_command(dev, 4, &one, 2);
-
- /*
- * Poke it to make sure it's really dead.
- */
-
- mc32_halt_transceiver(dev);
- mc32_flush_tx_ring(dev);
-
- /*
- * Ask card to set up on-card descriptors to our spec
- */
-
- if(mc32_command(dev, 8, descnumbuffs, 4)) {
- printk("%s: %s rejected our buffer configuration!\n",
- dev->name, cardname);
- mc32_close(dev);
- return -ENOBUFS;
- }
-
- /* Report new configuration */
- mc32_command(dev, 6, NULL, 0);
-
- lp->tx_chain = lp->exec_box->data[8]; /* Transmit list start offset */
- lp->rx_chain = lp->exec_box->data[10]; /* Receive list start offset */
- lp->tx_len = lp->exec_box->data[9]; /* Transmit list count */
- lp->rx_len = lp->exec_box->data[11]; /* Receive list count */
-
- /* Set Network Address */
- mc32_command(dev, 1, dev->dev_addr, 6);
-
- /* Set the filters */
- mc32_set_multicast_list(dev);
-
- if (WORKAROUND_82586) {
- u16 zero_word=0;
- mc32_command(dev, 0x0D, &zero_word, 2); /* 82586 bug workaround on */
- }
-
- mc32_load_tx_ring(dev);
-
- if(mc32_load_rx_ring(dev))
- {
- mc32_close(dev);
- return -ENOBUFS;
- }
-
- lp->xceiver_desired_state = RUNNING;
-
- /* And finally, set the ball rolling... */
- mc32_start_transceiver(dev);
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-
-/**
- * mc32_timeout - handle a timeout from the network layer
- * @dev: 3c527 that timed out
- *
- * Handle a timeout on transmit from the 3c527. This normally means
- * bad things as the hardware handles cable timeouts and mess for
- * us.
- *
- */
-
-static void mc32_timeout(struct net_device *dev)
-{
- printk(KERN_WARNING "%s: transmit timed out?\n", dev->name);
- /* Try to restart the adaptor. */
- netif_wake_queue(dev);
-}
-
-
-/**
- * mc32_send_packet - queue a frame for transmit
- * @skb: buffer to transmit
- * @dev: 3c527 to send it out of
- *
- * Transmit a buffer. This normally means throwing the buffer onto
- * the transmit queue as the queue is quite large. If the queue is
- * full then we set tx_busy and return. Once the interrupt handler
- * gets messages telling it to reclaim transmit queue entries, we will
- * clear tx_busy and the kernel will start calling this again.
- *
- * We do not disable interrupts or acquire any locks; this can
- * run concurrently with mc32_tx_ring(), and the function itself
- * is serialised at a higher layer. However, similarly for the
- * card itself, we must ensure that we update tx_ring_head only
- * after we've established a valid packet on the tx ring (and
- * before we let the card "see" it, to prevent it racing with the
- * irq handler).
- *
- */
-
-static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- u32 head = atomic_read(&lp->tx_ring_head);
-
- volatile struct skb_header *p, *np;
-
- netif_stop_queue(dev);
-
- if(atomic_read(&lp->tx_count)==0) {
- return 1;
- }
-
- if (skb_padto(skb, ETH_ZLEN)) {
- netif_wake_queue(dev);
- return 0;
- }
-
- atomic_dec(&lp->tx_count);
-
- /* P is the last sending/sent buffer as a pointer */
- p=lp->tx_ring[head].p;
-
- head = next_tx(head);
-
- /* NP is the buffer we will be loading */
- np=lp->tx_ring[head].p;
-
- /* We will need this to flush the buffer out */
- lp->tx_ring[head].skb=skb;
-
- np->length = unlikely(skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
- np->data = isa_virt_to_bus(skb->data);
- np->status = 0;
- np->control = CONTROL_EOP | CONTROL_EOL;
- wmb();
-
- /*
- * The new frame has been setup; we can now
- * let the interrupt handler and card "see" it
- */
-
- atomic_set(&lp->tx_ring_head, head);
- p->control &= ~CONTROL_EOL;
-
- netif_wake_queue(dev);
- return 0;
-}
-
-
-/**
- * mc32_update_stats - pull off the on board statistics
- * @dev: 3c527 to service
- *
- *
- * Query and reset the on-card stats. There's the small possibility
- * of a race here, which would result in an underestimation of
- * actual errors. As such, we'd prefer to keep all our stats
- * collection in software. As a rule, we do. However it can't be
- * used for rx errors and collisions as, by default, the card discards
- * bad rx packets.
- *
- * Setting the SAV BP in the rx filter command supposedly
- * stops this behaviour. However, testing shows that it only seems to
- * enable the collation of on-card rx statistics --- the driver
- * never sees an RX descriptor with an error status set.
- *
- */
-
-static void mc32_update_stats(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct mc32_stats *st = lp->stats;
-
- u32 rx_errors=0;
-
- rx_errors+=dev->stats.rx_crc_errors +=st->rx_crc_errors;
- st->rx_crc_errors=0;
- rx_errors+=dev->stats.rx_fifo_errors +=st->rx_overrun_errors;
- st->rx_overrun_errors=0;
- rx_errors+=dev->stats.rx_frame_errors +=st->rx_alignment_errors;
- st->rx_alignment_errors=0;
- rx_errors+=dev->stats.rx_length_errors+=st->rx_tooshort_errors;
- st->rx_tooshort_errors=0;
- rx_errors+=dev->stats.rx_missed_errors+=st->rx_outofresource_errors;
- st->rx_outofresource_errors=0;
- dev->stats.rx_errors=rx_errors;
-
- /* Number of packets which saw one collision */
- dev->stats.collisions+=st->dataC[10];
- st->dataC[10]=0;
-
- /* Number of packets which saw 2--15 collisions */
- dev->stats.collisions+=st->dataC[11];
- st->dataC[11]=0;
-}
-
-
-/**
- * mc32_rx_ring - process the receive ring
- * @dev: 3c527 that needs its receive ring processing
- *
- *
- * We have received one or more indications from the card that a
- * receive has completed. The buffer ring thus contains dirty
- * entries. We walk the ring by iterating over the circular rx_ring
- * array, starting at the next dirty buffer (which happens to be the
- * one we finished up at last time around).
- *
- * For each completed packet, we will either copy it and pass it up
- * the stack or, if the packet is near MTU sized, we allocate
- * another buffer and flip the old one up the stack.
- *
- * We must succeed in keeping a buffer on the ring. If necessary we
- * will toss a received packet rather than lose a ring entry. Once
- * the first uncompleted descriptor is found, we move the
- * End-Of-List bit to include the buffers just processed.
- *
- */
-
-static void mc32_rx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct skb_header *p;
- u16 rx_ring_tail;
- u16 rx_old_tail;
- int x=0;
-
- rx_old_tail = rx_ring_tail = lp->rx_ring_tail;
-
- do
- {
- p=lp->rx_ring[rx_ring_tail].p;
-
- if(!(p->status & (1<<7))) { /* Not COMPLETED */
- break;
- }
- if(p->status & (1<<6)) /* COMPLETED_OK */
- {
-
- u16 length=p->length;
- struct sk_buff *skb;
- struct sk_buff *newskb;
-
- /* Try to save time by avoiding a copy on big frames */
-
- if ((length > RX_COPYBREAK)
- && ((newskb=dev_alloc_skb(1532)) != NULL))
- {
- skb=lp->rx_ring[rx_ring_tail].skb;
- skb_put(skb, length);
-
- skb_reserve(newskb,18);
- lp->rx_ring[rx_ring_tail].skb=newskb;
- p->data=isa_virt_to_bus(newskb->data);
- }
- else
- {
- skb=dev_alloc_skb(length+2);
-
- if(skb==NULL) {
- dev->stats.rx_dropped++;
- goto dropped;
- }
-
- skb_reserve(skb,2);
- memcpy(skb_put(skb, length),
- lp->rx_ring[rx_ring_tail].skb->data, length);
- }
-
- skb->protocol=eth_type_trans(skb,dev);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += length;
- netif_rx(skb);
- }
-
- dropped:
- p->length = 1532;
- p->status = 0;
-
- rx_ring_tail=next_rx(rx_ring_tail);
- }
- while(x++<48);
-
- /* If there was actually a frame to be processed, place the EOL bit */
- /* at the descriptor prior to the one to be filled next */
-
- if (rx_ring_tail != rx_old_tail)
- {
- lp->rx_ring[prev_rx(rx_ring_tail)].p->control |= CONTROL_EOL;
- lp->rx_ring[prev_rx(rx_old_tail)].p->control &= ~CONTROL_EOL;
-
- lp->rx_ring_tail=rx_ring_tail;
- }
-}
-
-
-/**
- * mc32_tx_ring - process completed transmits
- * @dev: 3c527 that needs its transmit ring processing
- *
- *
- * This operates in a similar fashion to mc32_rx_ring. We iterate
- * over the transmit ring. For each descriptor which has been
- * processed by the card, we free its associated buffer and note
- * any errors. This continues until the transmit ring is emptied
- * or we reach a descriptor that hasn't yet been processed by the
- * card.
- *
- */
-
-static void mc32_tx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct skb_header *np;
-
- /*
- * We rely on head==tail to mean 'queue empty'.
- * This is why lp->tx_count=TX_RING_LEN-1: in order to prevent
- * tx_ring_head wrapping to tail and confusing a 'queue empty'
- * condition with 'queue full'
- */
-
- while (lp->tx_ring_tail != atomic_read(&lp->tx_ring_head))
- {
- u16 t;
-
- t=next_tx(lp->tx_ring_tail);
- np=lp->tx_ring[t].p;
-
- if(!(np->status & (1<<7)))
- {
- /* Not COMPLETED */
- break;
- }
- dev->stats.tx_packets++;
- if(!(np->status & (1<<6))) /* Not COMPLETED_OK */
- {
- dev->stats.tx_errors++;
-
- switch(np->status&0x0F)
- {
- case 1:
- dev->stats.tx_aborted_errors++;
- break; /* Max collisions */
- case 2:
- dev->stats.tx_fifo_errors++;
- break;
- case 3:
- dev->stats.tx_carrier_errors++;
- break;
- case 4:
- dev->stats.tx_window_errors++;
- break; /* CTS Lost */
- case 5:
- dev->stats.tx_aborted_errors++;
- break; /* Transmit timeout */
- }
- }
- /* Packets are sent in order - this is
- basically a FIFO queue of buffers matching
- the card ring */
- dev->stats.tx_bytes+=lp->tx_ring[t].skb->len;
- dev_kfree_skb_irq(lp->tx_ring[t].skb);
- lp->tx_ring[t].skb=NULL;
- atomic_inc(&lp->tx_count);
- netif_wake_queue(dev);
-
- lp->tx_ring_tail=t;
- }
-
-}
-
-
-/**
- * mc32_interrupt - handle an interrupt from a 3c527
- * @irq: Interrupt number
- * @dev_id: 3c527 that requires servicing
- * @regs: Registers (unused)
- *
- *
- * An interrupt is raised whenever the 3c527 writes to the command
- * register. This register contains the message it wishes to send us
- * packed into a single byte field. We keep reading status entries
- * until we have processed all the control items, but simply count
- * transmit and receive reports. When all reports are in we empty the
- * transceiver rings as appropriate. This saves the overhead of
- * multiple command requests.
- *
- * Because MCA is level-triggered, we shouldn't miss indications.
- * Therefore, we needn't ask the card to suspend interrupts within
- * this handler. The card receives an implicit acknowledgment of the
- * current interrupt when we read the command register.
- *
- */
-
-static irqreturn_t mc32_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct mc32_local *lp;
- int ioaddr, status, boguscount = 0;
- int rx_event = 0;
- int tx_event = 0;
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- /* See whats cooking */
-
- while((inb(ioaddr+HOST_STATUS)&HOST_STATUS_CWR) && boguscount++<2000)
- {
- status=inb(ioaddr+HOST_CMD);
-
-#ifdef DEBUG_IRQ
- printk("Status TX%d RX%d EX%d OV%d BC%d\n",
- (status&7), (status>>3)&7, (status>>6)&1,
- (status>>7)&1, boguscount);
-#endif
-
- switch(status&7)
- {
- case 0:
- break;
- case 6: /* TX fail */
- case 2: /* TX ok */
- tx_event = 1;
- break;
- case 3: /* Halt */
- case 4: /* Abort */
- complete(&lp->xceiver_cmd);
- break;
- default:
- printk("%s: strange tx ack %d\n", dev->name, status&7);
- }
- status>>=3;
- switch(status&7)
- {
- case 0:
- break;
- case 2: /* RX */
- rx_event=1;
- break;
- case 3: /* Halt */
- case 4: /* Abort */
- complete(&lp->xceiver_cmd);
- break;
- case 6:
- /* Out of RX buffers stat */
- /* Must restart rx */
- dev->stats.rx_dropped++;
- mc32_rx_ring(dev);
- mc32_start_transceiver(dev);
- break;
- default:
- printk("%s: strange rx ack %d\n",
- dev->name, status&7);
- }
- status>>=3;
- if(status&1)
- {
- /*
- * No thread is waiting: we need to tidy
- * up ourself.
- */
-
- if (lp->cmd_nonblocking) {
- up(&lp->cmd_mutex);
- if (lp->mc_reload_wait)
- mc32_reset_multicast_list(dev);
- }
- else complete(&lp->execution_cmd);
- }
- if(status&2)
- {
- /*
- * We get interrupted once per
- * counter that is about to overflow.
- */
-
- mc32_update_stats(dev);
- }
- }
-
-
- /*
- * Process the transmit and receive rings
- */
-
- if(tx_event)
- mc32_tx_ring(dev);
-
- if(rx_event)
- mc32_rx_ring(dev);
-
- return IRQ_HANDLED;
-}
-
-
-/**
- * mc32_close - user configuring the 3c527 down
- * @dev: 3c527 card to shut down
- *
- * The 3c527 is a bus mastering device. We must be careful how we
- * shut it down. It may also be running shared interrupt so we have
- * to be sure to silence it properly
- *
- * We indicate that the card is closing to the rest of the
- * driver. Otherwise, it is possible that the card may run out
- * of receive buffers and restart the transceiver while we're
- * trying to close it.
- *
- * We abort any receive and transmits going on and then wait until
- * any pending exec commands have completed in other code threads.
- * In theory we can't get here while that is true, in practice I am
- * paranoid
- *
- * We turn off the interrupt enable for the board to be sure it can't
- * intefere with other devices.
- */
-
-static int mc32_close(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- u8 regs;
- u16 one=1;
-
- lp->xceiver_desired_state = HALTED;
- netif_stop_queue(dev);
-
- /*
- * Send the indications on command (handy debug check)
- */
-
- mc32_command(dev, 4, &one, 2);
-
- /* Shut down the transceiver */
-
- mc32_halt_transceiver(dev);
-
- /* Ensure we issue no more commands beyond this point */
-
- down(&lp->cmd_mutex);
-
- /* Ok the card is now stopping */
-
- regs=inb(ioaddr+HOST_CTRL);
- regs&=~HOST_CTRL_INTE;
- outb(regs, ioaddr+HOST_CTRL);
-
- mc32_flush_rx_ring(dev);
- mc32_flush_tx_ring(dev);
-
- mc32_update_stats(dev);
-
- return 0;
-}
-
-
-/**
- * mc32_get_stats - hand back stats to network layer
- * @dev: The 3c527 card to handle
- *
- * We've collected all the stats we can in software already. Now
- * it's time to update those kept on-card and return the lot.
- *
- */
-
-static struct net_device_stats *mc32_get_stats(struct net_device *dev)
-{
- mc32_update_stats(dev);
- return &dev->stats;
-}
-
-
-/**
- * do_mc32_set_multicast_list - attempt to update multicasts
- * @dev: 3c527 device to load the list on
- * @retry: indicates this is not the first call.
- *
- *
- * Actually set or clear the multicast filter for this adaptor. The
- * locking issues are handled by this routine. We have to track
- * state as it may take multiple calls to get the command sequence
- * completed. We just keep trying to schedule the loads until we
- * manage to process them all.
- *
- * num_addrs == -1 Promiscuous mode, receive all packets
- *
- * num_addrs == 0 Normal mode, clear multicast list
- *
- * num_addrs > 0 Multicast mode, receive normal and MC packets,
- * and do best-effort filtering.
- *
- * See mc32_update_stats() regards setting the SAV BP bit.
- *
- */
-
-static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
-{
- struct mc32_local *lp = netdev_priv(dev);
- u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */
-
- if ((dev->flags&IFF_PROMISC) ||
- (dev->flags&IFF_ALLMULTI) ||
- dev->mc_count > 10)
- /* Enable promiscuous mode */
- filt |= 1;
- else if(dev->mc_count)
- {
- unsigned char block[62];
- unsigned char *bp;
- struct dev_mc_list *dmc=dev->mc_list;
-
- int i;
-
- if(retry==0)
- lp->mc_list_valid = 0;
- if(!lp->mc_list_valid)
- {
- block[1]=0;
- block[0]=dev->mc_count;
- bp=block+2;
-
- for(i=0;i<dev->mc_count;i++)
- {
- memcpy(bp, dmc->dmi_addr, 6);
- bp+=6;
- dmc=dmc->next;
- }
- if(mc32_command_nowait(dev, 2, block, 2+6*dev->mc_count)==-1)
- {
- lp->mc_reload_wait = 1;
- return;
- }
- lp->mc_list_valid=1;
- }
- }
-
- if(mc32_command_nowait(dev, 0, &filt, 2)==-1)
- {
- lp->mc_reload_wait = 1;
- }
- else {
- lp->mc_reload_wait = 0;
- }
-}
-
-
-/**
- * mc32_set_multicast_list - queue multicast list update
- * @dev: The 3c527 to use
- *
- * Commence loading the multicast list. This is called when the kernel
- * changes the lists. It will override any pending list we are trying to
- * load.
- */
-
-static void mc32_set_multicast_list(struct net_device *dev)
-{
- do_mc32_set_multicast_list(dev,0);
-}
-
-
-/**
- * mc32_reset_multicast_list - reset multicast list
- * @dev: The 3c527 to use
- *
- * Attempt the next step in loading the multicast lists. If this attempt
- * fails to complete then it will be scheduled and this function called
- * again later from elsewhere.
- */
-
-static void mc32_reset_multicast_list(struct net_device *dev)
-{
- do_mc32_set_multicast_list(dev,1);
-}
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return mc32_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- mc32_debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-#ifdef MODULE
-
-static struct net_device *this_device;
-
-/**
- * init_module - entry point
- *
- * Probe and locate a 3c527 card. This really should probe and locate
- * all the 3c527 cards in the machine not just one of them. Yes you can
- * insmod multiple modules for now but it's a hack.
- */
-
-int __init init_module(void)
-{
- this_device = mc32_probe(-1);
- if (IS_ERR(this_device))
- return PTR_ERR(this_device);
- return 0;
-}
-
-/**
- * cleanup_module - free resources for an unload
- *
- * Unloading time. We release the MCA bus resources and the interrupt
- * at which point everything is ready to unload. The card must be stopped
- * at this point or we would not have been called. When we unload we
- * leave the card stopped but not totally shut down. When the card is
- * initialized it must be rebooted or the rings reloaded before any
- * transmit operations are allowed to start scribbling into memory.
- */
-
-void __exit cleanup_module(void)
-{
- unregister_netdev(this_device);
- cleanup_card(this_device);
- free_netdev(this_device);
-}
-
-#endif /* MODULE */
diff --git a/drivers/net/3c527.h b/drivers/net/3c527.h
deleted file mode 100644
index 75e28fef797..00000000000
--- a/drivers/net/3c527.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 3COM "EtherLink MC/32" Descriptions
- */
-
-/*
- * Registers
- */
-
-#define HOST_CMD 0
-#define HOST_CMD_START_RX (1<<3)
-#define HOST_CMD_SUSPND_RX (3<<3)
-#define HOST_CMD_RESTRT_RX (5<<3)
-
-#define HOST_CMD_SUSPND_TX 3
-#define HOST_CMD_RESTRT_TX 5
-
-
-#define HOST_STATUS 2
-#define HOST_STATUS_CRR (1<<6)
-#define HOST_STATUS_CWR (1<<5)
-
-
-#define HOST_CTRL 6
-#define HOST_CTRL_ATTN (1<<7)
-#define HOST_CTRL_RESET (1<<6)
-#define HOST_CTRL_INTE (1<<2)
-
-#define HOST_RAMPAGE 8
-
-#define HALTED 0
-#define RUNNING 1
-
-struct mc32_mailbox
-{
- u16 mbox;
- u16 data[1];
-} __attribute((packed));
-
-struct skb_header
-{
- u8 status;
- u8 control;
- u16 next; /* Do not change! */
- u16 length;
- u32 data;
-} __attribute((packed));
-
-struct mc32_stats
-{
- /* RX Errors */
- u32 rx_crc_errors;
- u32 rx_alignment_errors;
- u32 rx_overrun_errors;
- u32 rx_tooshort_errors;
- u32 rx_toolong_errors;
- u32 rx_outofresource_errors;
-
- u32 rx_discarded; /* via card pattern match filter */
-
- /* TX Errors */
- u32 tx_max_collisions;
- u32 tx_carrier_errors;
- u32 tx_underrun_errors;
- u32 tx_cts_errors;
- u32 tx_timeout_errors;
-
- /* various cruft */
- u32 dataA[6];
- u16 dataB[5];
- u32 dataC[14];
-} __attribute((packed));
-
-#define STATUS_MASK 0x0F
-#define COMPLETED (1<<7)
-#define COMPLETED_OK (1<<6)
-#define BUFFER_BUSY (1<<5)
-
-#define CONTROL_EOP (1<<7) /* End Of Packet */
-#define CONTROL_EOL (1<<6) /* End of List */
-
-#define MCA_MC32_ID 0x0041 /* Our MCA ident */
diff --git a/drivers/net/7990.c b/drivers/net/7990.c
deleted file mode 100644
index ad6b8a5b657..00000000000
--- a/drivers/net/7990.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * 7990.c -- LANCE ethernet IC generic routines.
- * This is an attempt to separate out the bits of various ethernet
- * drivers that are common because they all use the AMD 7990 LANCE
- * (Local Area Network Controller for Ethernet) chip.
- *
- * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
- *
- * Most of this stuff was obtained by looking at other LANCE drivers,
- * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
- * NB: this was made easy by the fact that Jes Sorensen had cleaned up
- * most of a2025 and sunlance with the aim of merging them, so the
- * common code was pretty obvious.
- */
-#include <linux/crc32.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/route.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/skbuff.h>
-#include <asm/irq.h>
-/* Used for the temporal inet entries and routing */
-#include <linux/socket.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/pgtable.h>
-#ifdef CONFIG_HP300
-#include <asm/blinken.h>
-#endif
-
-#include "7990.h"
-
-#define WRITERAP(lp,x) out_be16(lp->base + LANCE_RAP, (x))
-#define WRITERDP(lp,x) out_be16(lp->base + LANCE_RDP, (x))
-#define READRDP(lp) in_be16(lp->base + LANCE_RDP)
-
-#if defined(CONFIG_HPLANCE) || defined(CONFIG_HPLANCE_MODULE)
-#include "hplance.h"
-
-#undef WRITERAP
-#undef WRITERDP
-#undef READRDP
-
-#if defined(CONFIG_MVME147_NET) || defined(CONFIG_MVME147_NET_MODULE)
-
-/* Lossage Factor Nine, Mr Sulu. */
-#define WRITERAP(lp,x) (lp->writerap(lp,x))
-#define WRITERDP(lp,x) (lp->writerdp(lp,x))
-#define READRDP(lp) (lp->readrdp(lp))
-
-#else
-
-/* These inlines can be used if only CONFIG_HPLANCE is defined */
-static inline void WRITERAP(struct lance_private *lp, __u16 value)
-{
- do {
- out_be16(lp->base + HPLANCE_REGOFF + LANCE_RAP, value);
- } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
-}
-
-static inline void WRITERDP(struct lance_private *lp, __u16 value)
-{
- do {
- out_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP, value);
- } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
-}
-
-static inline __u16 READRDP(struct lance_private *lp)
-{
- __u16 value;
- do {
- value = in_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP);
- } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
- return value;
-}
-
-#endif
-#endif /* CONFIG_HPLANCE || CONFIG_HPLANCE_MODULE */
-
-/* debugging output macros, various flavours */
-/* #define TEST_HITS */
-#ifdef UNDEF
-#define PRINT_RINGS() \
-do { \
- int t; \
- for (t=0; t < RX_RING_SIZE; t++) { \
- printk("R%d: @(%02X %04X) len %04X, mblen %04X, bits %02X\n",\
- t, ib->brx_ring[t].rmd1_hadr, ib->brx_ring[t].rmd0,\
- ib->brx_ring[t].length,\
- ib->brx_ring[t].mblength, ib->brx_ring[t].rmd1_bits);\
- }\
- for (t=0; t < TX_RING_SIZE; t++) { \
- printk("T%d: @(%02X %04X) len %04X, misc %04X, bits %02X\n",\
- t, ib->btx_ring[t].tmd1_hadr, ib->btx_ring[t].tmd0,\
- ib->btx_ring[t].length,\
- ib->btx_ring[t].misc, ib->btx_ring[t].tmd1_bits);\
- }\
-} while (0)
-#else
-#define PRINT_RINGS()
-#endif
-
-/* Load the CSR registers. The LANCE has to be STOPped when we do this! */
-static void load_csrs (struct lance_private *lp)
-{
- volatile struct lance_init_block *aib = lp->lance_init_block;
- int leptr;
-
- leptr = LANCE_ADDR (aib);
-
- WRITERAP(lp, LE_CSR1); /* load address of init block */
- WRITERDP(lp, leptr & 0xFFFF);
- WRITERAP(lp, LE_CSR2);
- WRITERDP(lp, leptr >> 16);
- WRITERAP(lp, LE_CSR3);
- WRITERDP(lp, lp->busmaster_regval); /* set byteswap/ALEctrl/byte ctrl */
-
- /* Point back to csr0 */
- WRITERAP(lp, LE_CSR0);
-}
-
-/* #define to 0 or 1 appropriately */
-#define DEBUG_IRING 0
-/* Set up the Lance Rx and Tx rings and the init block */
-static void lance_init_ring (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib = lp->init_block;
- volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */
- int leptr;
- int i;
-
- aib = lp->lance_init_block;
-
- lp->rx_new = lp->tx_new = 0;
- lp->rx_old = lp->tx_old = 0;
-
- ib->mode = LE_MO_PROM; /* normal, enable Tx & Rx */
-
- /* Copy the ethernet address to the lance init block
- * Notice that we do a byteswap if we're big endian.
- * [I think this is the right criterion; at least, sunlance,
- * a2065 and atarilance do the byteswap and lance.c (PC) doesn't.
- * However, the datasheet says that the BSWAP bit doesn't affect
- * the init block, so surely it should be low byte first for
- * everybody? Um.]
- * We could define the ib->physaddr as three 16bit values and
- * use (addr[1] << 8) | addr[0] & co, but this is more efficient.
- */
-#ifdef __BIG_ENDIAN
- ib->phys_addr [0] = dev->dev_addr [1];
- ib->phys_addr [1] = dev->dev_addr [0];
- ib->phys_addr [2] = dev->dev_addr [3];
- ib->phys_addr [3] = dev->dev_addr [2];
- ib->phys_addr [4] = dev->dev_addr [5];
- ib->phys_addr [5] = dev->dev_addr [4];
-#else
- for (i=0; i<6; i++)
- ib->phys_addr[i] = dev->dev_addr[i];
-#endif
-
- if (DEBUG_IRING)
- printk ("TX rings:\n");
-
- lp->tx_full = 0;
- /* Setup the Tx ring entries */
- for (i = 0; i < (1<<lp->lance_log_tx_bufs); i++) {
- leptr = LANCE_ADDR(&aib->tx_buf[i][0]);
- ib->btx_ring [i].tmd0 = leptr;
- ib->btx_ring [i].tmd1_hadr = leptr >> 16;
- ib->btx_ring [i].tmd1_bits = 0;
- ib->btx_ring [i].length = 0xf000; /* The ones required by tmd2 */
- ib->btx_ring [i].misc = 0;
- if (DEBUG_IRING)
- printk ("%d: 0x%8.8x\n", i, leptr);
- }
-
- /* Setup the Rx ring entries */
- if (DEBUG_IRING)
- printk ("RX rings:\n");
- for (i = 0; i < (1<<lp->lance_log_rx_bufs); i++) {
- leptr = LANCE_ADDR(&aib->rx_buf[i][0]);
-
- ib->brx_ring [i].rmd0 = leptr;
- ib->brx_ring [i].rmd1_hadr = leptr >> 16;
- ib->brx_ring [i].rmd1_bits = LE_R1_OWN;
- /* 0xf000 == bits that must be one (reserved, presumably) */
- ib->brx_ring [i].length = -RX_BUFF_SIZE | 0xf000;
- ib->brx_ring [i].mblength = 0;
- if (DEBUG_IRING)
- printk ("%d: 0x%8.8x\n", i, leptr);
- }
-
- /* Setup the initialization block */
-
- /* Setup rx descriptor pointer */
- leptr = LANCE_ADDR(&aib->brx_ring);
- ib->rx_len = (lp->lance_log_rx_bufs << 13) | (leptr >> 16);
- ib->rx_ptr = leptr;
- if (DEBUG_IRING)
- printk ("RX ptr: %8.8x\n", leptr);
-
- /* Setup tx descriptor pointer */
- leptr = LANCE_ADDR(&aib->btx_ring);
- ib->tx_len = (lp->lance_log_tx_bufs << 13) | (leptr >> 16);
- ib->tx_ptr = leptr;
- if (DEBUG_IRING)
- printk ("TX ptr: %8.8x\n", leptr);
-
- /* Clear the multicast filter */
- ib->filter [0] = 0;
- ib->filter [1] = 0;
- PRINT_RINGS();
-}
-
-/* LANCE must be STOPped before we do this, too... */
-static int init_restart_lance (struct lance_private *lp)
-{
- int i;
-
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_INIT);
-
- /* Need a hook here for sunlance ledma stuff */
-
- /* Wait for the lance to complete initialization */
- for (i = 0; (i < 100) && !(READRDP(lp) & (LE_C0_ERR | LE_C0_IDON)); i++)
- barrier();
- if ((i == 100) || (READRDP(lp) & LE_C0_ERR)) {
- printk ("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, READRDP(lp));
- return -1;
- }
-
- /* Clear IDON by writing a "1", enable interrupts and start lance */
- WRITERDP(lp, LE_C0_IDON);
- WRITERDP(lp, LE_C0_INEA | LE_C0_STRT);
-
- return 0;
-}
-
-static int lance_reset (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- int status;
-
- /* Stop the lance */
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_STOP);
-
- load_csrs (lp);
- lance_init_ring (dev);
- dev->trans_start = jiffies;
- status = init_restart_lance (lp);
-#ifdef DEBUG_DRIVER
- printk ("Lance restart=%d\n", status);
-#endif
- return status;
-}
-
-static int lance_rx (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib = lp->init_block;
- volatile struct lance_rx_desc *rd;
- unsigned char bits;
-#ifdef TEST_HITS
- int i;
-#endif
-
-#ifdef TEST_HITS
- printk ("[");
- for (i = 0; i < RX_RING_SIZE; i++) {
- if (i == lp->rx_new)
- printk ("%s",
- ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "_" : "X");
- else
- printk ("%s",
- ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "." : "1");
- }
- printk ("]");
-#endif
-#ifdef CONFIG_HP300
- blinken_leds(0x40, 0);
-#endif
- WRITERDP(lp, LE_C0_RINT | LE_C0_INEA); /* ack Rx int, reenable ints */
- for (rd = &ib->brx_ring [lp->rx_new]; /* For each Rx ring we own... */
- !((bits = rd->rmd1_bits) & LE_R1_OWN);
- rd = &ib->brx_ring [lp->rx_new]) {
-
- /* We got an incomplete frame? */
- if ((bits & LE_R1_POK) != LE_R1_POK) {
- dev->stats.rx_over_errors++;
- dev->stats.rx_errors++;
- continue;
- } else if (bits & LE_R1_ERR) {
- /* Count only the end frame as a rx error,
- * not the beginning
- */
- if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++;
- if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++;
- if (bits & LE_R1_OFL) dev->stats.rx_over_errors++;
- if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
- if (bits & LE_R1_EOP) dev->stats.rx_errors++;
- } else {
- int len = (rd->mblength & 0xfff) - 4;
- struct sk_buff *skb = dev_alloc_skb (len+2);
-
- if (!skb) {
- printk ("%s: Memory squeeze, deferring packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- rd->mblength = 0;
- rd->rmd1_bits = LE_R1_OWN;
- lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
- return 0;
- }
-
- skb_reserve (skb, 2); /* 16 byte align */
- skb_put (skb, len); /* make room */
- skb_copy_to_linear_data(skb,
- (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
- len);
- skb->protocol = eth_type_trans (skb, dev);
- netif_rx (skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += len;
- }
-
- /* Return the packet to the pool */
- rd->mblength = 0;
- rd->rmd1_bits = LE_R1_OWN;
- lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
- }
- return 0;
-}
-
-static int lance_tx (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib = lp->init_block;
- volatile struct lance_tx_desc *td;
- int i, j;
- int status;
-
-#ifdef CONFIG_HP300
- blinken_leds(0x80, 0);
-#endif
- /* csr0 is 2f3 */
- WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
- /* csr0 is 73 */
-
- j = lp->tx_old;
- for (i = j; i != lp->tx_new; i = j) {
- td = &ib->btx_ring [i];
-
- /* If we hit a packet not owned by us, stop */
- if (td->tmd1_bits & LE_T1_OWN)
- break;
-
- if (td->tmd1_bits & LE_T1_ERR) {
- status = td->misc;
-
- dev->stats.tx_errors++;
- if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++;
- if (status & LE_T3_LCOL) dev->stats.tx_window_errors++;
-
- if (status & LE_T3_CLOS) {
- dev->stats.tx_carrier_errors++;
- if (lp->auto_select) {
- lp->tpe = 1 - lp->tpe;
- printk("%s: Carrier Lost, trying %s\n",
- dev->name, lp->tpe?"TPE":"AUI");
- /* Stop the lance */
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_STOP);
- lance_init_ring (dev);
- load_csrs (lp);
- init_restart_lance (lp);
- return 0;
- }
- }
-
- /* buffer errors and underflows turn off the transmitter */
- /* Restart the adapter */
- if (status & (LE_T3_BUF|LE_T3_UFL)) {
- dev->stats.tx_fifo_errors++;
-
- printk ("%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
- dev->name);
- /* Stop the lance */
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_STOP);
- lance_init_ring (dev);
- load_csrs (lp);
- init_restart_lance (lp);
- return 0;
- }
- } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
- /*
- * So we don't count the packet more than once.
- */
- td->tmd1_bits &= ~(LE_T1_POK);
-
- /* One collision before packet was sent. */
- if (td->tmd1_bits & LE_T1_EONE)
- dev->stats.collisions++;
-
- /* More than one collision, be optimistic. */
- if (td->tmd1_bits & LE_T1_EMORE)
- dev->stats.collisions += 2;
-
- dev->stats.tx_packets++;
- }
-
- j = (j + 1) & lp->tx_ring_mod_mask;
- }
- lp->tx_old = j;
- WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
- return 0;
-}
-
-static irqreturn_t
-lance_interrupt (int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct lance_private *lp = netdev_priv(dev);
- int csr0;
-
- spin_lock (&lp->devlock);
-
- WRITERAP(lp, LE_CSR0); /* LANCE Controller Status */
- csr0 = READRDP(lp);
-
- PRINT_RINGS();
-
- if (!(csr0 & LE_C0_INTR)) { /* Check if any interrupt has */
- spin_unlock (&lp->devlock);
- return IRQ_NONE; /* been generated by the Lance. */
- }
-
- /* Acknowledge all the interrupt sources ASAP */
- WRITERDP(lp, csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT|LE_C0_INIT));
-
- if ((csr0 & LE_C0_ERR)) {
- /* Clear the error condition */
- WRITERDP(lp, LE_C0_BABL|LE_C0_ERR|LE_C0_MISS|LE_C0_INEA);
- }
-
- if (csr0 & LE_C0_RINT)
- lance_rx (dev);
-
- if (csr0 & LE_C0_TINT)
- lance_tx (dev);
-
- /* Log misc errors. */
- if (csr0 & LE_C0_BABL)
- dev->stats.tx_errors++; /* Tx babble. */
- if (csr0 & LE_C0_MISS)
- dev->stats.rx_errors++; /* Missed a Rx frame. */
- if (csr0 & LE_C0_MERR) {
- printk("%s: Bus master arbitration failure, status %4.4x.\n",
- dev->name, csr0);
- /* Restart the chip. */
- WRITERDP(lp, LE_C0_STRT);
- }
-
- if (lp->tx_full && netif_queue_stopped(dev) && (TX_BUFFS_AVAIL >= 0)) {
- lp->tx_full = 0;
- netif_wake_queue (dev);
- }
-
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR|LE_C0_IDON|LE_C0_INEA);
-
- spin_unlock (&lp->devlock);
- return IRQ_HANDLED;
-}
-
-int lance_open (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- int res;
-
- /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
- if (request_irq(lp->irq, lance_interrupt, IRQF_SHARED, lp->name, dev))
- return -EAGAIN;
-
- res = lance_reset(dev);
- spin_lock_init(&lp->devlock);
- netif_start_queue (dev);
-
- return res;
-}
-EXPORT_SYMBOL_GPL(lance_open);
-
-int lance_close (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
-
- netif_stop_queue (dev);
-
- /* Stop the LANCE */
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_STOP);
-
- free_irq(lp->irq, dev);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(lance_close);
-
-void lance_tx_timeout(struct net_device *dev)
-{
- printk("lance_tx_timeout\n");
- lance_reset(dev);
- dev->trans_start = jiffies;
- netif_wake_queue (dev);
-}
-EXPORT_SYMBOL_GPL(lance_tx_timeout);
-
-int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib = lp->init_block;
- int entry, skblen, len;
- static int outs;
- unsigned long flags;
-
- if (!TX_BUFFS_AVAIL)
- return -1;
-
- netif_stop_queue (dev);
-
- skblen = skb->len;
-
-#ifdef DEBUG_DRIVER
- /* dump the packet */
- {
- int i;
-
- for (i = 0; i < 64; i++) {
- if ((i % 16) == 0)
- printk ("\n");
- printk ("%2.2x ", skb->data [i]);
- }
- }
-#endif
- len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
- entry = lp->tx_new & lp->tx_ring_mod_mask;
- ib->btx_ring [entry].length = (-len) | 0xf000;
- ib->btx_ring [entry].misc = 0;
-
- if (skb->len < ETH_ZLEN)
- memset((void *)&ib->tx_buf[entry][0], 0, ETH_ZLEN);
- skb_copy_from_linear_data(skb, (void *)&ib->tx_buf[entry][0], skblen);
-
- /* Now, give the packet to the lance */
- ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
- lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;
-
- outs++;
- /* Kick the lance: transmit now */
- WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD);
- dev->trans_start = jiffies;
- dev_kfree_skb (skb);
-
- spin_lock_irqsave (&lp->devlock, flags);
- if (TX_BUFFS_AVAIL)
- netif_start_queue (dev);
- else
- lp->tx_full = 1;
- spin_unlock_irqrestore (&lp->devlock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(lance_start_xmit);
-
-/* taken from the depca driver via a2065.c */
-static void lance_load_multicast (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib = lp->init_block;
- volatile u16 *mcast_table = (u16 *)&ib->filter;
- struct dev_mc_list *dmi=dev->mc_list;
- char *addrs;
- int i;
- u32 crc;
-
- /* set all multicast bits */
- if (dev->flags & IFF_ALLMULTI){
- ib->filter [0] = 0xffffffff;
- ib->filter [1] = 0xffffffff;
- return;
- }
- /* clear the multicast filter */
- ib->filter [0] = 0;
- ib->filter [1] = 0;
-
- /* Add addresses */
- for (i = 0; i < dev->mc_count; i++){
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
-
- /* multicast address? */
- if (!(*addrs & 1))
- continue;
-
- crc = ether_crc_le(6, addrs);
- crc = crc >> 26;
- mcast_table [crc >> 4] |= 1 << (crc & 0xf);
- }
- return;
-}
-
-
-void lance_set_multicast (struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
- volatile struct lance_init_block *ib = lp->init_block;
- int stopped;
-
- stopped = netif_queue_stopped(dev);
- if (!stopped)
- netif_stop_queue (dev);
-
- while (lp->tx_old != lp->tx_new)
- schedule();
-
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_STOP);
- lance_init_ring (dev);
-
- if (dev->flags & IFF_PROMISC) {
- ib->mode |= LE_MO_PROM;
- } else {
- ib->mode &= ~LE_MO_PROM;
- lance_load_multicast (dev);
- }
- load_csrs (lp);
- init_restart_lance (lp);
-
- if (!stopped)
- netif_start_queue (dev);
-}
-EXPORT_SYMBOL_GPL(lance_set_multicast);
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-void lance_poll(struct net_device *dev)
-{
- struct lance_private *lp = netdev_priv(dev);
-
- spin_lock (&lp->devlock);
- WRITERAP(lp, LE_CSR0);
- WRITERDP(lp, LE_C0_STRT);
- spin_unlock (&lp->devlock);
- lance_interrupt(dev->irq, dev);
-}
-#endif
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/7990.h b/drivers/net/7990.h
deleted file mode 100644
index 0a5837b9642..00000000000
--- a/drivers/net/7990.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 7990.h -- LANCE ethernet IC generic routines.
- * This is an attempt to separate out the bits of various ethernet
- * drivers that are common because they all use the AMD 7990 LANCE
- * (Local Area Network Controller for Ethernet) chip.
- *
- * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
- *
- * Most of this stuff was obtained by looking at other LANCE drivers,
- * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
- */
-
-#ifndef _7990_H
-#define _7990_H
-
-/* The lance only has two register locations. We communicate mostly via memory. */
-#define LANCE_RDP 0 /* Register Data Port */
-#define LANCE_RAP 2 /* Register Address Port */
-
-/* Transmit/receive ring definitions.
- * We allow the specific drivers to override these defaults if they want to.
- * NB: according to lance.c, increasing the number of buffers is a waste
- * of space and reduces the chance that an upper layer will be able to
- * reorder queued Tx packets based on priority. [Clearly there is a minimum
- * limit too: too small and we drop rx packets and can't tx at full speed.]
- * 4+4 seems to be the usual setting; the atarilance driver uses 3 and 5.
- */
-
-/* Blast! This won't work. The problem is that we can't specify a default
- * setting because that would cause the lance_init_block struct to be
- * too long (and overflow the RAM on shared-memory cards like the HP LANCE.
- */
-#ifndef LANCE_LOG_TX_BUFFERS
-#define LANCE_LOG_TX_BUFFERS 1
-#define LANCE_LOG_RX_BUFFERS 3
-#endif
-
-#define TX_RING_SIZE (1<<LANCE_LOG_TX_BUFFERS)
-#define RX_RING_SIZE (1<<LANCE_LOG_RX_BUFFERS)
-#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
-#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
-#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
-#define PKT_BUFF_SIZE (1544)
-#define RX_BUFF_SIZE PKT_BUFF_SIZE
-#define TX_BUFF_SIZE PKT_BUFF_SIZE
-
-/* Each receive buffer is described by a receive message descriptor (RMD) */
-struct lance_rx_desc {
- volatile unsigned short rmd0; /* low address of packet */
- volatile unsigned char rmd1_bits; /* descriptor bits */
- volatile unsigned char rmd1_hadr; /* high address of packet */
- volatile short length; /* This length is 2s complement (negative)!
- * Buffer length
- */
- volatile unsigned short mblength; /* Actual number of bytes received */
-};
-
-/* Ditto for TMD: */
-struct lance_tx_desc {
- volatile unsigned short tmd0; /* low address of packet */
- volatile unsigned char tmd1_bits; /* descriptor bits */
- volatile unsigned char tmd1_hadr; /* high address of packet */
- volatile short length; /* Length is 2s complement (negative)! */
- volatile unsigned short misc;
-};
-
-/* There are three memory structures accessed by the LANCE:
- * the initialization block, the receive and transmit descriptor rings,
- * and the data buffers themselves. In fact we might as well put the
- * init block,the Tx and Rx rings and the buffers together in memory:
- */
-struct lance_init_block {
- volatile unsigned short mode; /* Pre-set mode (reg. 15) */
- volatile unsigned char phys_addr[6]; /* Physical ethernet address */
- volatile unsigned filter[2]; /* Multicast filter (64 bits) */
-
- /* Receive and transmit ring base, along with extra bits. */
- volatile unsigned short rx_ptr; /* receive descriptor addr */
- volatile unsigned short rx_len; /* receive len and high addr */
- volatile unsigned short tx_ptr; /* transmit descriptor addr */
- volatile unsigned short tx_len; /* transmit len and high addr */
-
- /* The Tx and Rx ring entries must be aligned on 8-byte boundaries.
- * This will be true if this whole struct is 8-byte aligned.
- */
- volatile struct lance_tx_desc btx_ring[TX_RING_SIZE];
- volatile struct lance_rx_desc brx_ring[RX_RING_SIZE];
-
- volatile char tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
- volatile char rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
- /* we use this just to make the struct big enough that we can move its startaddr
- * in order to force alignment to an eight byte boundary.
- */
-};
-
-/* This is where we keep all the stuff the driver needs to know about.
- * I'm definitely unhappy about the mechanism for allowing specific
- * drivers to add things...
- */
-struct lance_private
-{
- char *name;
- unsigned long base;
- volatile struct lance_init_block *init_block; /* CPU address of RAM */
- volatile struct lance_init_block *lance_init_block; /* LANCE address of RAM */
-
- int rx_new, tx_new;
- int rx_old, tx_old;
-
- int lance_log_rx_bufs, lance_log_tx_bufs;
- int rx_ring_mod_mask, tx_ring_mod_mask;
-
- int tpe; /* TPE is selected */
- int auto_select; /* cable-selection is by carrier */
- unsigned short busmaster_regval;
-
- unsigned int irq; /* IRQ to register */
-
- /* This is because the HP LANCE is disgusting and you have to check
- * a DIO-specific register every time you read/write the LANCE regs :-<
- * [could we get away with making these some sort of macro?]
- */
- void (*writerap)(void *, unsigned short);
- void (*writerdp)(void *, unsigned short);
- unsigned short (*readrdp)(void *);
- spinlock_t devlock;
- char tx_full;
-};
-
-/*
- * Am7990 Control and Status Registers
- */
-#define LE_CSR0 0x0000 /* LANCE Controller Status */
-#define LE_CSR1 0x0001 /* IADR[15:0] (bit0==0 ie word aligned) */
-#define LE_CSR2 0x0002 /* IADR[23:16] (high bits reserved) */
-#define LE_CSR3 0x0003 /* Misc */
-
-/*
- * Bit definitions for CSR0 (LANCE Controller Status)
- */
-#define LE_C0_ERR 0x8000 /* Error = BABL | CERR | MISS | MERR */
-#define LE_C0_BABL 0x4000 /* Babble: Transmitted too many bits */
-#define LE_C0_CERR 0x2000 /* No Heartbeat (10BASE-T) */
-#define LE_C0_MISS 0x1000 /* Missed Frame (no rx buffer to put it in) */
-#define LE_C0_MERR 0x0800 /* Memory Error */
-#define LE_C0_RINT 0x0400 /* Receive Interrupt */
-#define LE_C0_TINT 0x0200 /* Transmit Interrupt */
-#define LE_C0_IDON 0x0100 /* Initialization Done */
-#define LE_C0_INTR 0x0080 /* Interrupt Flag
- = BABL | MISS | MERR | RINT | TINT | IDON */
-#define LE_C0_INEA 0x0040 /* Interrupt Enable */
-#define LE_C0_RXON 0x0020 /* Receive On */
-#define LE_C0_TXON 0x0010 /* Transmit On */
-#define LE_C0_TDMD 0x0008 /* Transmit Demand */
-#define LE_C0_STOP 0x0004 /* Stop */
-#define LE_C0_STRT 0x0002 /* Start */
-#define LE_C0_INIT 0x0001 /* Initialize */
-
-
-/*
- * Bit definitions for CSR3
- */
-#define LE_C3_BSWP 0x0004 /* Byte Swap
- (on for big endian byte order) */
-#define LE_C3_ACON 0x0002 /* ALE Control
- (on for active low ALE) */
-#define LE_C3_BCON 0x0001 /* Byte Control */
-
-
-/*
- * Mode Flags
- */
-#define LE_MO_PROM 0x8000 /* Promiscuous Mode */
-/* these next ones 0x4000 -- 0x0080 are not available on the LANCE 7990,
- * but they are in NetBSD's am7990.h, presumably for backwards-compatible chips
- */
-#define LE_MO_DRCVBC 0x4000 /* disable receive broadcast */
-#define LE_MO_DRCVPA 0x2000 /* disable physical address detection */
-#define LE_MO_DLNKTST 0x1000 /* disable link status */
-#define LE_MO_DAPC 0x0800 /* disable automatic polarity correction */
-#define LE_MO_MENDECL 0x0400 /* MENDEC loopback mode */
-#define LE_MO_LRTTSEL 0x0200 /* lower RX threshold / TX mode selection */
-#define LE_MO_PSEL1 0x0100 /* port selection bit1 */
-#define LE_MO_PSEL0 0x0080 /* port selection bit0 */
-/* and this one is from the C-LANCE data sheet... */
-#define LE_MO_EMBA 0x0080 /* Enable Modified Backoff Algorithm
- (C-LANCE, not original LANCE) */
-#define LE_MO_INTL 0x0040 /* Internal Loopback */
-#define LE_MO_DRTY 0x0020 /* Disable Retry */
-#define LE_MO_FCOLL 0x0010 /* Force Collision */
-#define LE_MO_DXMTFCS 0x0008 /* Disable Transmit CRC */
-#define LE_MO_LOOP 0x0004 /* Loopback Enable */
-#define LE_MO_DTX 0x0002 /* Disable Transmitter */
-#define LE_MO_DRX 0x0001 /* Disable Receiver */
-
-
-/*
- * Receive Flags
- */
-#define LE_R1_OWN 0x80 /* LANCE owns the descriptor */
-#define LE_R1_ERR 0x40 /* Error */
-#define LE_R1_FRA 0x20 /* Framing Error */
-#define LE_R1_OFL 0x10 /* Overflow Error */
-#define LE_R1_CRC 0x08 /* CRC Error */
-#define LE_R1_BUF 0x04 /* Buffer Error */
-#define LE_R1_SOP 0x02 /* Start of Packet */
-#define LE_R1_EOP 0x01 /* End of Packet */
-#define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */
-
-
-/*
- * Transmit Flags
- */
-#define LE_T1_OWN 0x80 /* LANCE owns the descriptor */
-#define LE_T1_ERR 0x40 /* Error */
-#define LE_T1_RES 0x20 /* Reserved, LANCE writes this with a zero */
-#define LE_T1_EMORE 0x10 /* More than one retry needed */
-#define LE_T1_EONE 0x08 /* One retry needed */
-#define LE_T1_EDEF 0x04 /* Deferred */
-#define LE_T1_SOP 0x02 /* Start of Packet */
-#define LE_T1_EOP 0x01 /* End of Packet */
-#define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */
-
-/*
- * Error Flags
- */
-#define LE_T3_BUF 0x8000 /* Buffer Error */
-#define LE_T3_UFL 0x4000 /* Underflow Error */
-#define LE_T3_LCOL 0x1000 /* Late Collision */
-#define LE_T3_CLOS 0x0800 /* Loss of Carrier */
-#define LE_T3_RTY 0x0400 /* Retry Error */
-#define LE_T3_TDR 0x03ff /* Time Domain Reflectometry */
-
-/* Miscellaneous useful macros */
-
-#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
- lp->tx_old+lp->tx_ring_mod_mask-lp->tx_new:\
- lp->tx_old - lp->tx_new-1)
-
-/* The LANCE only uses 24 bit addresses. This does the obvious thing. */
-#define LANCE_ADDR(x) ((int)(x) & ~0xff000000)
-
-/* Now the prototypes we export */
-extern int lance_open(struct net_device *dev);
-extern int lance_close (struct net_device *dev);
-extern int lance_start_xmit (struct sk_buff *skb, struct net_device *dev);
-extern void lance_set_multicast (struct net_device *dev);
-extern void lance_tx_timeout(struct net_device *dev);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-extern void lance_poll(struct net_device *dev);
-#endif
-
-#endif /* ndef _7990_H */
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
deleted file mode 100644
index f72a2e87d56..00000000000
--- a/drivers/net/8390.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* 8390 core for usual drivers */
-
-static const char version[] =
- "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include "lib8390.c"
-
-int ei_open(struct net_device *dev)
-{
- return __ei_open(dev);
-}
-EXPORT_SYMBOL(ei_open);
-
-int ei_close(struct net_device *dev)
-{
- return __ei_close(dev);
-}
-EXPORT_SYMBOL(ei_close);
-
-irqreturn_t ei_interrupt(int irq, void *dev_id)
-{
- return __ei_interrupt(irq, dev_id);
-}
-EXPORT_SYMBOL(ei_interrupt);
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-void ei_poll(struct net_device *dev)
-{
- __ei_poll(dev);
-}
-EXPORT_SYMBOL(ei_poll);
-#endif
-
-struct net_device *__alloc_ei_netdev(int size)
-{
- return ____alloc_ei_netdev(size);
-}
-EXPORT_SYMBOL(__alloc_ei_netdev);
-
-void NS8390_init(struct net_device *dev, int startp)
-{
- __NS8390_init(dev, startp);
-}
-EXPORT_SYMBOL(NS8390_init);
-
-#if defined(MODULE)
-
-static int __init ns8390_module_init(void)
-{
- return 0;
-}
-
-static void __exit ns8390_module_exit(void)
-{
-}
-
-module_init(ns8390_module_init);
-module_exit(ns8390_module_exit);
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
deleted file mode 100644
index 4c6eea4611a..00000000000
--- a/drivers/net/8390p.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* 8390 core for ISA devices needing bus delays */
-
-static const char version[] =
- "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#define ei_inb(_p) inb(_p)
-#define ei_outb(_v, _p) outb(_v, _p)
-#define ei_inb_p(_p) inb_p(_p)
-#define ei_outb_p(_v, _p) outb_p(_v, _p)
-
-#include "lib8390.c"
-
-int eip_open(struct net_device *dev)
-{
- return __ei_open(dev);
-}
-EXPORT_SYMBOL(eip_open);
-
-int eip_close(struct net_device *dev)
-{
- return __ei_close(dev);
-}
-EXPORT_SYMBOL(eip_close);
-
-irqreturn_t eip_interrupt(int irq, void *dev_id)
-{
- return __ei_interrupt(irq, dev_id);
-}
-EXPORT_SYMBOL(eip_interrupt);
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-void eip_poll(struct net_device *dev)
-{
- __ei_poll(dev);
-}
-EXPORT_SYMBOL(eip_poll);
-#endif
-
-struct net_device *__alloc_eip_netdev(int size)
-{
- return ____alloc_ei_netdev(size);
-}
-EXPORT_SYMBOL(__alloc_eip_netdev);
-
-void NS8390p_init(struct net_device *dev, int startp)
-{
- __NS8390_init(dev, startp);
-}
-EXPORT_SYMBOL(NS8390p_init);
-
-#if defined(MODULE)
-
-int init_module(void)
-{
- return 0;
-}
-
-void cleanup_module(void)
-{
-}
-
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4a11296a951..89402c3b64f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1,4 +1,3 @@
-
#
# Network device configuration
#
@@ -26,41 +25,22 @@ menuconfig NETDEVICES
# that for each of the symbols.
if NETDEVICES
-config IFB
- tristate "Intermediate Functional Block support"
- depends on NET_CLS_ACT
- ---help---
- This is an intermediate driver that allows sharing of
- resources.
- To compile this driver as a module, choose M here: the module
- will be called ifb. If you want to use more than one ifb
- device at a time, you need to compile this driver as a module.
- Instead of 'ifb', the devices will then be called 'ifb0',
- 'ifb1' etc.
- Look at the iproute2 documentation directory for usage etc
+config MII
+ tristate
-config DUMMY
- tristate "Dummy net driver support"
+config NET_CORE
+ default y
+ bool "Network core driver support"
---help---
- This is essentially a bit-bucket device (i.e. traffic you send to
- this device is consigned into oblivion) with a configurable IP
- address. It is most commonly used in order to make your currently
- inactive SLIP address seem like a real address for local programs.
- If you use SLIP or PPP, you might want to say Y here. Since this
- thing often comes in handy, the default is Y. It won't enlarge your
- kernel either. What a deal. Read about it in the Network
- Administrator's Guide, available from
- <http://www.tldp.org/docs.html#guide>.
+ You can say N here if you do not intend to use any of the
+ networking core drivers (i.e. VLAN, bridging, bonding, etc.)
- To compile this driver as a module, choose M here: the module
- will be called dummy. If you want to use more than one dummy
- device at a time, you need to compile this driver as a module.
- Instead of 'dummy', the devices will then be called 'dummy0',
- 'dummy1' etc.
+if NET_CORE
config BONDING
tristate "Bonding driver support"
depends on INET
+ depends on IPV6 || IPV6=n
---help---
Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
Channels together. This is called 'Etherchannel' by Cisco,
@@ -75,20 +55,21 @@ config BONDING
To compile this driver as a module, choose M here: the module
will be called bonding.
-config MACVLAN
- tristate "MAC-VLAN support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+config DUMMY
+ tristate "Dummy net driver support"
---help---
- This allows one to create virtual interfaces that map packets to
- or from specific MAC addresses to a particular interface.
-
- Macvlan devices can be added using the "ip" command from the
- iproute2 package starting with the iproute2-2.6.23 release:
-
- "ip link add link <real dev> [ address MAC ] [ NAME ] type macvlan"
+ This is essentially a bit-bucket device (i.e. traffic you send to
+ this device is consigned into oblivion) with a configurable IP
+ address. It is most commonly used in order to make your currently
+ inactive SLIP address seem like a real address for local programs.
+ If you use SLIP or PPP, you might want to say Y here. Since this
+ thing often comes in handy, the default is Y. It won't enlarge your
+ kernel either. What a deal. Read about it in the Network
+ Administrator's Guide, available from
+ <http://www.tldp.org/docs.html#guide>.
To compile this driver as a module, choose M here: the module
- will be called macvlan.
+ will be called dummy.
config EQUALIZER
tristate "EQL (serial line load balancing) support"
@@ -109,2858 +90,272 @@ config EQUALIZER
To compile this driver as a module, choose M here: the module
will be called eql. If unsure, say N.
-config TUN
- tristate "Universal TUN/TAP device driver support"
- select CRC32
- ---help---
- TUN/TAP provides packet reception and transmission for user space
- programs. It can be viewed as a simple Point-to-Point or Ethernet
- device, which instead of receiving packets from a physical media,
- receives them from user space program and instead of sending packets
- via physical media writes them to the user space program.
-
- When a program opens /dev/net/tun, driver creates and registers
- corresponding net device tunX or tapX. After a program closed above
- devices, driver will automatically delete tunXX or tapXX device and
- all routes corresponding to it.
-
- Please read <file:Documentation/networking/tuntap.txt> for more
- information.
-
- To compile this driver as a module, choose M here: the module
- will be called tun.
-
- If you don't know what to use this for, you don't need it.
-
-config VETH
- tristate "Virtual ethernet pair device"
- ---help---
- This device is a local ethernet tunnel. Devices are created in pairs.
- When one end receives the packet it appears on its pair and vice
- versa.
-
-config NET_SB1000
- tristate "General Instruments Surfboard 1000"
- depends on PNP
- ---help---
- This is a driver for the General Instrument (also known as
- NextLevel) SURFboard 1000 internal
- cable modem. This is an ISA card which is used by a number of cable
- TV companies to provide cable modem access. It's a one-way
- downstream-only cable modem, meaning that your upstream net link is
- provided by your regular phone modem.
-
- At present this driver only compiles as a module, so say M here if
- you have this card. The module will be called sb1000. Then read
- <file:Documentation/networking/README.sb1000> for information on how
- to use this module, as it needs special ppp scripts for establishing
- a connection. Further documentation and the necessary scripts can be
- found at:
-
- <http://www.jacksonville.net/~fventuri/>
- <http://home.adelphia.net/~siglercm/sb1000.html>
- <http://linuxpower.cx/~cable/>
-
- If you don't have this card, of course say N.
-
-source "drivers/net/arcnet/Kconfig"
-
-source "drivers/net/phy/Kconfig"
-
-#
-# Ethernet
-#
-
-menuconfig NET_ETHERNET
- bool "Ethernet (10 or 100Mbit)"
- depends on !UML
- ---help---
- Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
- type of Local Area Network (LAN) in universities and companies.
-
- Common varieties of Ethernet are: 10BASE-2 or Thinnet (10 Mbps over
- coaxial cable, linking computers in a chain), 10BASE-T or twisted
- pair (10 Mbps over twisted pair cable, linking computers to central
- hubs), 10BASE-F (10 Mbps over optical fiber links, using hubs),
- 100BASE-TX (100 Mbps over two twisted pair cables, using hubs),
- 100BASE-T4 (100 Mbps over 4 standard voice-grade twisted pair
- cables, using hubs), 100BASE-FX (100 Mbps over optical fiber links)
- [the 100BASE varieties are also known as Fast Ethernet], and Gigabit
- Ethernet (1 Gbps over optical fiber or short copper links).
-
- If your Linux machine will be connected to an Ethernet and you have
- an Ethernet network interface card (NIC) installed in your computer,
- say Y here and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. You will then also have
- to say Y to the driver for your particular NIC.
-
- Note that the answer to this question won't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about Ethernet network cards. If unsure, say N.
-
-if NET_ETHERNET
-
-config MII
- tristate "Generic Media Independent Interface device support"
- help
- Most ethernet controllers have MII transceiver either as an external
- or internal device. It is safe to say Y or M here even if your
- ethernet card lack MII.
-
-config MACB
- tristate "Atmel MACB support"
- depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9
- select PHYLIB
- help
- The Atmel MACB ethernet interface is found on many AT32 and AT91
- parts. Say Y to include support for the MACB chip.
-
- To compile this driver as a module, choose M here: the module
- will be called macb.
-
-source "drivers/net/arm/Kconfig"
-
-config AX88796
- tristate "ASIX AX88796 NE2000 clone support"
- depends on ARM || MIPS || SUPERH
- select CRC32
- select MII
- help
- AX88796 driver, using platform bus to provide
- chip detection and resources
-
-config AX88796_93CX6
- bool "ASIX AX88796 external 93CX6 eeprom support"
- depends on AX88796
- select EEPROM_93CX6
- help
- Select this if your platform comes with an external 93CX6 eeprom.
-
-config MACE
- tristate "MACE (Power Mac ethernet) support"
- depends on PPC_PMAC && PPC32
- select CRC32
- help
- Power Macintoshes and clones with Ethernet built-in on the
- motherboard will usually use a MACE (Medium Access Control for
- Ethernet) interface. Say Y to include support for the MACE chip.
-
- To compile this driver as a module, choose M here: the module
- will be called mace.
-
-config MACE_AAUI_PORT
- bool "Use AAUI port instead of TP by default"
- depends on MACE
- help
- Some Apple machines (notably the Apple Network Server) which use the
- MACE ethernet chip have an Apple AUI port (small 15-pin connector),
- instead of an 8-pin RJ45 connector for twisted-pair ethernet. Say
- Y here if you have such a machine. If unsure, say N.
- The driver will default to AAUI on ANS anyway, and if you use it as
- a module, you can provide the port_aaui=0|1 to force the driver.
-
-config BMAC
- tristate "BMAC (G3 ethernet) support"
- depends on PPC_PMAC && PPC32
- select CRC32
- help
- Say Y for support of BMAC Ethernet interfaces. These are used on G3
- computers.
-
- To compile this driver as a module, choose M here: the module
- will be called bmac.
-
-config ARIADNE
- tristate "Ariadne support"
- depends on ZORRO
- help
- If you have a Village Tronic Ariadne Ethernet adapter, say Y.
- Otherwise, say N.
-
- To compile this driver as a module, choose M here: the module
- will be called ariadne.
-
-config A2065
- tristate "A2065 support"
- depends on ZORRO
- select CRC32
- help
- If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
- say N.
-
- To compile this driver as a module, choose M here: the module
- will be called a2065.
-
-config HYDRA
- tristate "Hydra support"
- depends on ZORRO
- select CRC32
- help
- If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
-
- To compile this driver as a module, choose M here: the module
- will be called hydra.
-
-config ZORRO8390
- tristate "Zorro NS8390-based Ethernet support"
- depends on ZORRO
- select CRC32
- help
- This driver is for Zorro Ethernet cards using an NS8390-compatible
- chipset, like the Village Tronic Ariadne II and the Individual
- Computers X-Surf Ethernet cards. If you have such a card, say Y.
- Otherwise, say N.
-
- To compile this driver as a module, choose M here: the module
- will be called zorro8390.
-
-config APNE
- tristate "PCMCIA NE2000 support"
- depends on AMIGA_PCMCIA
- select CRC32
- help
- If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
- say N.
-
- To compile this driver as a module, choose M here: the module
- will be called apne.
-
-config MAC8390
- bool "Macintosh NS 8390 based ethernet cards"
- depends on MAC
- select CRC32
- help
- If you want to include a driver to support Nubus or LC-PDS
- Ethernet cards using an NS8390 chipset or its equivalent, say Y
- and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
-config MAC89x0
- tristate "Macintosh CS89x0 based ethernet cards"
- depends on MAC
- ---help---
- Support for CS89x0 chipset based Ethernet cards. If you have a
- Nubus or LC-PDS network (Ethernet) card of this type, say Y and
- read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. This module will
- be called mac89x0.
-
-config MACSONIC
- tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
- depends on MAC
- ---help---
- Support for NatSemi SONIC based Ethernet devices. This includes
- the onboard Ethernet in many Quadras as well as some LC-PDS,
- a few Nubus and all known Comm Slot Ethernet cards. If you have
- one of these say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. This module will
- be called macsonic.
-
-config MACMACE
- bool "Macintosh (AV) onboard MACE ethernet"
- depends on MAC
- select CRC32
- help
- Support for the onboard AMD 79C940 MACE Ethernet controller used in
- the 660AV and 840AV Macintosh. If you have one of these Macintoshes
- say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
-config MVME147_NET
- tristate "MVME147 (Lance) Ethernet support"
- depends on MVME147
- select CRC32
- help
- Support for the on-board Ethernet interface on the Motorola MVME147
- single-board computer. Say Y here to include the
- driver for this chip in your kernel.
- To compile this driver as a module, choose M here.
-
-config MVME16x_NET
- tristate "MVME16x Ethernet support"
- depends on MVME16x
- help
- This is the driver for the Ethernet interface on the Motorola
- MVME162, 166, 167, 172 and 177 boards. Say Y here to include the
- driver for this chip in your kernel.
- To compile this driver as a module, choose M here.
-
-config BVME6000_NET
- tristate "BVME6000 Ethernet support"
- depends on BVME6000
- help
- This is the driver for the Ethernet interface on BVME4000 and
- BVME6000 VME boards. Say Y here to include the driver for this chip
- in your kernel.
- To compile this driver as a module, choose M here.
-
-config ATARILANCE
- tristate "Atari Lance support"
- depends on ATARI
- help
- Say Y to include support for several Atari Ethernet adapters based
- on the AMD Lance chipset: RieblCard (with or without battery), or
- PAMCard VME (also the version by Rhotron, with different addresses).
-
-config SUN3LANCE
- tristate "Sun3/Sun3x on-board LANCE support"
- depends on SUN3 || SUN3X
- help
- Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
- featured an AMD Lance 10Mbit Ethernet controller on board; say Y
- here to compile in the Linux driver for this and enable Ethernet.
- General Linux information on the Sun 3 and 3x series (now
- discontinued) is at
- <http://www.angelfire.com/ca2/tech68k/sun3.html>.
-
- If you're not building a kernel for a Sun 3, say N.
-
-config SUN3_82586
- bool "Sun3 on-board Intel 82586 support"
- depends on SUN3
- help
- This driver enables support for the on-board Intel 82586 based
- Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards. Note
- that this driver does not support 82586-based adapters on additional
- VME boards.
-
-config HPLANCE
- bool "HP on-board LANCE support"
- depends on DIO
- select CRC32
- help
- If you want to use the builtin "LANCE" Ethernet controller on an
- HP300 machine, say Y here.
-
-config LASI_82596
- tristate "Lasi ethernet"
- depends on GSC
- help
- Say Y here to support the builtin Intel 82596 ethernet controller
- found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
-
-config SNI_82596
- tristate "SNI RM ethernet"
- depends on NET_ETHERNET && SNI_RM
- help
- Say Y here to support the on-board Intel 82596 ethernet controller
- built into SNI RM machines.
-
-config KORINA
- tristate "Korina (IDT RC32434) Ethernet support"
- depends on NET_ETHERNET && MIKROTIK_RB532
- help
- If you have a Mikrotik RouterBoard 500 or IDT RC32434
- based system say Y. Otherwise say N.
-
-config MIPS_JAZZ_SONIC
- tristate "MIPS JAZZ onboard SONIC Ethernet support"
- depends on MACH_JAZZ
- help
- This is the driver for the onboard card of MIPS Magnum 4000,
- Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
-
-config MIPS_AU1X00_ENET
- bool "MIPS AU1000 Ethernet support"
- depends on SOC_AU1X00
- select PHYLIB
- select CRC32
- help
- If you have an Alchemy Semi AU1X00 based system
- say Y. Otherwise, say N.
-
-config SGI_IOC3_ETH
- bool "SGI IOC3 Ethernet"
- depends on PCI && SGI_IP27
- select CRC32
- select MII
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
-config MIPS_SIM_NET
- tristate "MIPS simulator Network device"
- depends on MIPS_SIM
- help
- The MIPSNET device is a simple Ethernet network device which is
- emulated by the MIPS Simulator.
- If you are not using a MIPSsim or are unsure, say N.
-
-config SGI_O2MACE_ETH
- tristate "SGI O2 MACE Fast Ethernet support"
- depends on SGI_IP32=y
-
-config STNIC
- tristate "National DP83902AV support"
- depends on SUPERH
- select CRC32
- help
- Support for cards based on the National Semiconductor DP83902AV
- ST-NIC Serial Network Interface Controller for Twisted Pair. This
- is a 10Mbit/sec Ethernet controller. Product overview and specs at
- <http://www.national.com/pf/DP/DP83902A.html>.
-
- If unsure, say N.
-
-config SH_ETH
- tristate "Renesas SuperH Ethernet support"
- depends on SUPERH && \
- (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763 || \
- CPU_SUBTYPE_SH7619)
- select CRC32
- select MII
- select MDIO_BITBANG
- select PHYLIB
- help
- Renesas SuperH Ethernet device driver.
- This driver support SH7710, SH7712, SH7763 and SH7619.
-
-config SUNLANCE
- tristate "Sun LANCE support"
- depends on SBUS
- select CRC32
- help
- This driver supports the "le" interface present on all 32-bit Sparc
- systems, on some older Ultra systems and as an Sbus option. These
- cards are based on the AMD Lance chipset, which is better known
- via the NE2100 cards.
-
- To compile this driver as a module, choose M here: the module
- will be called sunlance.
-
-config HAPPYMEAL
- tristate "Sun Happy Meal 10/100baseT support"
- depends on SBUS || PCI
- select CRC32
- help
- This driver supports the "hme" interface present on most Ultra
- systems and as an option on older Sbus systems. This driver supports
- both PCI and Sbus devices. This driver also supports the "qfe" quad
- 100baseT device available in both PCI and Sbus configurations.
-
- To compile this driver as a module, choose M here: the module
- will be called sunhme.
-
-config SUNBMAC
- tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
- depends on SBUS && EXPERIMENTAL
- select CRC32
- help
- This driver supports the "be" interface available as an Sbus option.
- This is Sun's older 100baseT Ethernet device.
-
- To compile this driver as a module, choose M here: the module
- will be called sunbmac.
-
-config SUNQE
- tristate "Sun QuadEthernet support"
- depends on SBUS
- select CRC32
- help
- This driver supports the "qe" 10baseT Ethernet device, available as
- an Sbus option. Note that this is not the same as Quad FastEthernet
- "qfe" which is supported by the Happy Meal driver instead.
-
- To compile this driver as a module, choose M here: the module
- will be called sunqe.
-
-config SUNGEM
- tristate "Sun GEM support"
- depends on PCI
- select CRC32
- help
- Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0. See also
- <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
-
-config CASSINI
- tristate "Sun Cassini support"
- depends on PCI
- select CRC32
- help
- Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
- <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf>
-
-config SUNVNET
- tristate "Sun Virtual Network support"
- depends on SUN_LDOMS
- help
- Support for virtual network devices under Sun Logical Domains.
-
-config NET_VENDOR_3COM
- bool "3COM cards"
- depends on ISA || EISA || MCA || PCI
- help
- If you have a network (Ethernet) card belonging to this class, say Y
- and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about 3COM cards. If you say Y, you will be asked for
- your specific card in the following questions.
-
-config EL1
- tristate "3c501 \"EtherLink\" support"
- depends on NET_VENDOR_3COM && ISA
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Also, consider buying a
- new card, since the 3c501 is slow, broken, and obsolete: you will
- have problems. Some people suggest to ping ("man ping") a nearby
- machine every minute ("man cron") when using this card.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c501.
-
-config EL2
- tristate "3c503 \"EtherLink II\" support"
- depends on NET_VENDOR_3COM && ISA
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c503.
-
-config ELPLUS
- tristate "3c505 \"EtherLink Plus\" support"
- depends on NET_VENDOR_3COM && ISA && ISA_DMA_API
- ---help---
- Information about this network (Ethernet) card can be found in
- <file:Documentation/networking/3c505.txt>. If you have a card of
- this type, say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c505.
-
-config EL16
- tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)"
- depends on NET_VENDOR_3COM && ISA && EXPERIMENTAL
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c507.
-
-config EL3
- tristate "3c509/3c529 (MCA)/3c579 \"EtherLink III\" support"
- depends on NET_VENDOR_3COM && (ISA || EISA || MCA)
- ---help---
- If you have a network (Ethernet) card belonging to the 3Com
- EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
- from <http://www.tldp.org/docs.html#howto>.
-
- If your card is not working you may need to use the DOS
- setup disk to disable Plug & Play mode, and to select the default
- media type.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c509.
-
-config 3C515
- tristate "3c515 ISA \"Fast EtherLink\""
- depends on NET_VENDOR_3COM && (ISA || EISA) && ISA_DMA_API
- help
- If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
- network card, say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c515.
-
-config ELMC
- tristate "3c523 \"EtherLink/MC\" support"
- depends on NET_VENDOR_3COM && MCA_LEGACY
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c523.
-
-config ELMC_II
- tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)"
- depends on NET_VENDOR_3COM && MCA && MCA_LEGACY
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c527.
-
-config VORTEX
- tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
- depends on NET_VENDOR_3COM && (PCI || EISA)
- select MII
- ---help---
- This option enables driver support for a large number of 10Mbps and
- 10/100Mbps EISA, PCI and PCMCIA 3Com network cards:
-
- "Vortex" (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
- "Boomerang" (EtherLink XL 3c900 or 3c905) PCI
- "Cyclone" (3c540/3c900/3c905/3c980/3c575/3c656) PCI and Cardbus
- "Tornado" (3c905) PCI
- "Hurricane" (3c555/3cSOHO) PCI
-
- If you have such a card, say Y and read the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>. More
- specific information is in
- <file:Documentation/networking/vortex.txt> and in the comments at
- the beginning of <file:drivers/net/3c59x.c>.
-
- To compile this support as a module, choose M here.
-
-config TYPHOON
- tristate "3cr990 series \"Typhoon\" support"
- depends on NET_VENDOR_3COM && PCI
- select CRC32
- ---help---
- This option enables driver support for the 3cr990 series of cards:
-
- 3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
- 3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server,
- 3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR
-
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called typhoon.
-
-config LANCE
- tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
- depends on ISA && ISA_DMA_API
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are
- of this type.
-
- To compile this driver as a module, choose M here: the module
- will be called lance. This is recommended.
-
-config NET_VENDOR_SMC
- bool "Western Digital/SMC cards"
- depends on ISA || MCA || EISA || MAC
- help
- If you have a network (Ethernet) card belonging to this class, say Y
- and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about Western Digital cards. If you say Y, you will be
- asked for your specific card in the following questions.
-
-config WD80x3
- tristate "WD80*3 support"
- depends on NET_VENDOR_SMC && ISA
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called wd.
-
-config ULTRAMCA
- tristate "SMC Ultra MCA support"
- depends on NET_VENDOR_SMC && MCA
- select CRC32
- help
- If you have a network (Ethernet) card of this type and are running
- an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called smc-mca.
-
-config ULTRA
- tristate "SMC Ultra support"
- depends on NET_VENDOR_SMC && ISA
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Important: There have been many reports that, with some motherboards
- mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
- such as some BusLogic models) causes corruption problems with many
- operating systems. The Linux smc-ultra driver has a work-around for
- this but keep it in mind if you have such a SCSI card and have
- problems.
-
- To compile this driver as a module, choose M here. The module
- will be called smc-ultra.
-
-config ULTRA32
- tristate "SMC Ultra32 EISA support"
- depends on NET_VENDOR_SMC && EISA
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called smc-ultra32.
-
-config BFIN_MAC
- tristate "Blackfin on-chip MAC support"
- depends on NET_ETHERNET && (BF526 || BF527 || BF536 || BF537)
- select CRC32
- select MII
- select PHYLIB
- select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
- help
- This is the driver for Blackfin on-chip mac device. Say Y if you want it
- compiled into the kernel. This driver is also available as a module
- ( = code which can be inserted in and removed from the running kernel
- whenever you want). The module will be called bfin_mac.
-
-config BFIN_MAC_USE_L1
- bool "Use L1 memory for rx/tx packets"
- depends on BFIN_MAC && (BF527 || BF537)
- default y
- help
- To get maximum network performance, you should use L1 memory as rx/tx buffers.
- Say N here if you want to reserve L1 memory for other uses.
-
-config BFIN_TX_DESC_NUM
- int "Number of transmit buffer packets"
- depends on BFIN_MAC
- range 6 10 if BFIN_MAC_USE_L1
- range 10 100
- default "10"
- help
- Set the number of buffer packets used in driver.
-
-config BFIN_RX_DESC_NUM
- int "Number of receive buffer packets"
- depends on BFIN_MAC
- range 20 100 if BFIN_MAC_USE_L1
- range 20 800
- default "20"
- help
- Set the number of buffer packets used in driver.
-
-config BFIN_MAC_RMII
- bool "RMII PHY Interface (EXPERIMENTAL)"
- depends on BFIN_MAC && EXPERIMENTAL
- default y if BFIN527_EZKIT
- default n if BFIN537_STAMP
- help
- Use Reduced PHY MII Interface
-
-config SMC9194
- tristate "SMC 9194 support"
- depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
- select CRC32
- ---help---
- This is support for the SMC9xxx based Ethernet cards. Choose this
- option if you have a DELL laptop with the docking station, or
- another SMC9192/9194 based chipset. Say Y if you want it compiled
- into the kernel, and read the file
- <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called smc9194.
-
-config SMC91X
- tristate "SMC 91C9x/91C1xxx support"
- select CRC32
- select MII
- depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
- SOC_AU1X00 || BLACKFIN || MN10300
- help
- This is a driver for SMC's 91x series of Ethernet chipsets,
- including the SMC91C94 and the SMC91C111. Say Y if you want it
- compiled into the kernel, and read the file
- <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
- available from <http://www.linuxdoc.org/docs.html#howto>.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you want).
- The module will be called smc91x. If you want to compile it as a
- module, say M here and read <file:Documentation/kbuild/modules.txt>.
-
-config NET_NETX
- tristate "NetX Ethernet support"
- select MII
- depends on ARCH_NETX
- help
- This is support for the Hilscher netX builtin Ethernet ports
-
- To compile this driver as a module, choose M here. The module
- will be called netx-eth.
-
-config DM9000
- tristate "DM9000 support"
- depends on ARM || BLACKFIN || MIPS
- select CRC32
- select MII
- ---help---
- Support for DM9000 chipset.
-
- To compile this driver as a module, choose M here. The module
- will be called dm9000.
-
-config DM9000_DEBUGLEVEL
- int "DM9000 maximum debug level"
- depends on DM9000
- default 4
- help
- The maximum level of debugging code compiled into the DM9000
- driver.
-
-config DM9000_FORCE_SIMPLE_PHY_POLL
- bool "Force simple NSR based PHY polling"
- depends on DM9000
- ---help---
- This configuration forces the DM9000 to use the NSR's LinkStatus
- bit to determine if the link is up or down instead of the more
- costly MII PHY reads. Note, this will not work if the chip is
- operating with an external PHY.
-
-config ENC28J60
- tristate "ENC28J60 support"
- depends on EXPERIMENTAL && SPI && NET_ETHERNET
- select CRC32
- ---help---
- Support for the Microchip EN28J60 ethernet chip.
-
- To compile this driver as a module, choose M here. The module will be
- called enc28j60.
-
-config ENC28J60_WRITEVERIFY
- bool "Enable write verify"
- depends on ENC28J60
- ---help---
- Enable the verify after the buffer write useful for debugging purpose.
- If unsure, say N.
-
-config SMC911X
- tristate "SMSC LAN911[5678] support"
- select CRC32
- select MII
- depends on ARCH_PXA || SUPERH
- help
- This is a driver for SMSC's LAN911x series of Ethernet chipsets
- including the new LAN9115, LAN9116, LAN9117, and LAN9118.
- Say Y if you want it compiled into the kernel,
- and read the Ethernet-HOWTO, available from
- <http://www.linuxdoc.org/docs.html#howto>.
-
- This driver is also available as a module. The module will be
- called smc911x. If you want to compile it as a module, say M
- here and read <file:Documentation/kbuild/modules.txt>
-
-config NET_VENDOR_RACAL
- bool "Racal-Interlan (Micom) NI cards"
- depends on ISA
- help
- If you have a network (Ethernet) card belonging to this class, such
- as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about NI cards. If you say Y, you will be asked for
- your specific card in the following questions.
-
-config NI5010
- tristate "NI5010 support (EXPERIMENTAL)"
- depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL && BROKEN_ON_SMP
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Note that this is still
- experimental code.
-
- To compile this driver as a module, choose M here. The module
- will be called ni5010.
-
-config NI52
- tristate "NI5210 support"
- depends on NET_VENDOR_RACAL && ISA
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ni52.
-
-config NI65
- tristate "NI6510 support"
- depends on NET_VENDOR_RACAL && ISA && ISA_DMA_API
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ni65.
-
-source "drivers/net/tulip/Kconfig"
-
-config AT1700
- tristate "AT1700/1720 support (EXPERIMENTAL)"
- depends on (ISA || MCA_LEGACY) && EXPERIMENTAL
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called at1700.
-
-config DEPCA
- tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
- depends on ISA || EISA || MCA
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto> as well as
- <file:drivers/net/depca.c>.
-
- To compile this driver as a module, choose M here. The module
- will be called depca.
-
-config HP100
- tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
- depends on ISA || EISA || PCI
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called hp100.
-
-config NET_ISA
- bool "Other ISA cards"
- depends on ISA
- ---help---
- If your network (Ethernet) card hasn't been mentioned yet and its
- bus system (that's the way the cards talks to the other components
- of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y.
- Make sure you know the name of your card. Read the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- If unsure, say Y.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the remaining ISA network card questions. If you say Y, you will be
- asked for your specific card in the following questions.
-
-config E2100
- tristate "Cabletron E21xx support"
- depends on NET_ISA
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called e2100.
-
-config EWRK3
- tristate "EtherWORKS 3 (DE203, DE204, DE205) support"
- depends on NET_ISA
- select CRC32
- ---help---
- This driver supports the DE203, DE204 and DE205 network (Ethernet)
- cards. If this is for you, say Y and read
- <file:Documentation/networking/ewrk3.txt> in the kernel source as
- well as the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ewrk3.
-
-config EEXPRESS
- tristate "EtherExpress 16 support"
- depends on NET_ISA
- ---help---
- If you have an EtherExpress16 network (Ethernet) card, say Y and
- read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Note that the Intel
- EtherExpress16 card used to be regarded as a very poor choice
- because the driver was very unreliable. We now have a new driver
- that should do better.
-
- To compile this driver as a module, choose M here. The module
- will be called eexpress.
-
-config EEXPRESS_PRO
- tristate "EtherExpressPro support/EtherExpress 10 (i82595) support"
- depends on NET_ISA
- ---help---
- If you have a network (Ethernet) card of this type, say Y. This
- driver supports Intel i82595{FX,TX} based boards. Note however
- that the EtherExpress PRO/100 Ethernet card has its own separate
- driver. Please read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called eepro.
-
-config HPLAN_PLUS
- tristate "HP PCLAN+ (27247B and 27252A) support"
- depends on NET_ISA
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called hp-plus.
-
-config HPLAN
- tristate "HP PCLAN (27245 and other 27xxx series) support"
- depends on NET_ISA
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called hp.
-
-config LP486E
- tristate "LP486E on board Ethernet"
- depends on NET_ISA
- help
- Say Y here to support the 82596-based on-board Ethernet controller
- for the Panther motherboard, which is one of the two shipped in the
- Intel Professional Workstation.
-
-config ETH16I
- tristate "ICL EtherTeam 16i/32 support"
- depends on NET_ISA
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called eth16i.
-
-config NE2000
- tristate "NE2000/NE1000 support"
- depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Many Ethernet cards
- without a specific driver are compatible with NE2000.
-
- If you have a PCI NE2000 card however, say N here and Y to "PCI
- NE2000 and clone support" under "EISA, VLB, PCI and on board
- controllers" below. If you have a NE2000 card and are running on
- an MCA system (a bus system used on some IBM PS/2 computers and
- laptops), say N here and Y to "NE/2 (ne2000 MCA version) support",
- below.
-
- To compile this driver as a module, choose M here. The module
- will be called ne.
-
-config ZNET
- tristate "Zenith Z-Note support (EXPERIMENTAL)"
- depends on NET_ISA && EXPERIMENTAL && ISA_DMA_API
- help
- The Zenith Z-Note notebook computer has a built-in network
- (Ethernet) card, and this is the Linux driver for it. Note that the
- IBM Thinkpad 300 is compatible with the Z-Note and is also supported
- by this driver. Read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
-config SEEQ8005
- tristate "SEEQ8005 support (EXPERIMENTAL)"
- depends on NET_ISA && EXPERIMENTAL
- help
- This is a driver for the SEEQ 8005 network (Ethernet) card. If this
- is for you, read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called seeq8005.
-
-config NE2_MCA
- tristate "NE/2 (ne2000 MCA version) support"
- depends on MCA_LEGACY
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ne2.
-
-config IBMLANA
- tristate "IBM LAN Adapter/A support"
- depends on MCA
- ---help---
- This is a Micro Channel Ethernet adapter. You need to set
- CONFIG_MCA to use this driver. It is both available as an in-kernel
- driver and as a module.
-
- To compile this driver as a module, choose M here. The only
- currently supported card is the IBM LAN Adapter/A for Ethernet. It
- will both support 16K and 32K memory windows, however a 32K window
- gives a better security against packet losses. Usage of multiple
- boards with this driver should be possible, but has not been tested
- up to now due to lack of hardware.
-
-config IBMVETH
- tristate "IBM LAN Virtual Ethernet support"
- depends on PPC_PSERIES
- ---help---
- This driver supports virtual ethernet adapters on newer IBM iSeries
- and pSeries systems.
-
- To compile this driver as a module, choose M here. The module will
- be called ibmveth.
-
-source "drivers/net/ibm_newemac/Kconfig"
-
-config NET_PCI
- bool "EISA, VLB, PCI and on board controllers"
- depends on ISA || EISA || PCI
- help
- This is another class of network cards which attach directly to the
- bus. If you have one of those, say Y and read the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about this class of network cards. If you say Y, you
- will be asked for your specific card in the following questions. If
- you are unsure, say Y.
-
-config PCNET32
- tristate "AMD PCnet32 PCI support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
- answer Y here and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called pcnet32.
-
-config AMD8111_ETH
- tristate "AMD 8111 (new PCI lance) support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- If you have an AMD 8111-based PCI lance ethernet card,
- answer Y here and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called amd8111e.
-
-config ADAPTEC_STARFIRE
- tristate "Adaptec Starfire/DuraLAN support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
- adapter. The DuraLAN chip is used on the 64 bit PCI boards from
- Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip
- driver.
-
- To compile this driver as a module, choose M here: the module
- will be called starfire. This is recommended.
-
-config AC3200
- tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
- depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ac3200.
-
-config APRICOT
- tristate "Apricot Xen-II on board Ethernet"
- depends on NET_PCI && ISA
- help
- If you have a network (Ethernet) controller of this type, say Y and
- read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called apricot.
-
-config B44
- tristate "Broadcom 440x/47xx ethernet support"
- depends on SSB_POSSIBLE && HAS_DMA
- select SSB
- select MII
- help
- If you have a network (Ethernet) controller of this type, say Y
- or M and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called b44.
-
-# Auto-select SSB PCI-HOST support, if possible
-config B44_PCI_AUTOSELECT
- bool
- depends on B44 && SSB_PCIHOST_POSSIBLE
- select SSB_PCIHOST
- default y
-
-# Auto-select SSB PCICORE driver, if possible
-config B44_PCICORE_AUTOSELECT
- bool
- depends on B44 && SSB_DRIVER_PCICORE_POSSIBLE
- select SSB_DRIVER_PCICORE
- default y
-
-config B44_PCI
- bool
- depends on B44_PCI_AUTOSELECT && B44_PCICORE_AUTOSELECT
- default y
-
-config FORCEDETH
- tristate "nForce Ethernet support"
- depends on NET_PCI && PCI
- help
- If you have a network (Ethernet) controller of this type, say Y and
- read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called forcedeth.
-
-config FORCEDETH_NAPI
- bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
- depends on FORCEDETH && EXPERIMENTAL
- help
- NAPI is a new driver API designed to reduce CPU and interrupt load
- when the driver is receiving lots of packets from the card. It is
- still somewhat experimental and thus not yet enabled by default.
-
- If your estimated Rx load is 10kpps or more, or if the card will be
- deployed on potentially unfriendly networks (e.g. in a firewall),
- then say Y here.
-
- If in doubt, say N.
-
-config CS89x0
- tristate "CS89x0 support"
- depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X)
- ---help---
- Support for CS89x0 chipset based Ethernet cards. If you have a
- network (Ethernet) card of this type, say Y and read the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto> as well as
- <file:Documentation/networking/cs89x0.txt>.
-
- To compile this driver as a module, choose M here. The module
- will be called cs89x0.
-
-config TC35815
- tristate "TOSHIBA TC35815 Ethernet support"
- depends on NET_PCI && PCI && MIPS
- select PHYLIB
-
-config EEPRO100
- tristate "EtherExpressPro/100 support (eepro100, original Becker driver)"
- depends on NET_PCI && PCI
- select MII
- help
- If you have an Intel EtherExpress PRO/100 PCI network (Ethernet)
- card, say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called eepro100.
-
-
-config E100
- tristate "Intel(R) PRO/100+ support"
- depends on NET_PCI && PCI
- select MII
- ---help---
- This driver supports Intel(R) PRO/100 family of adapters.
- To verify that your adapter is supported, find the board ID number
- on the adapter. Look for a label that has a barcode and a number
- in the format 123456-001 (six digits hyphen three digits).
-
- Use the above information and the Adapter & Driver ID Guide at:
-
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
- to identify the adapter.
-
- For the latest Intel PRO/100 network driver for Linux, see:
-
- <http://appsr.intel.com/scripts-df/support_intel.asp>
-
- More specific information on configuring the driver is in
- <file:Documentation/networking/e100.txt>.
-
- To compile this driver as a module, choose M here. The module
- will be called e100.
-
-config LNE390
- tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
- depends on NET_PCI && EISA && EXPERIMENTAL
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called lne390.
-
-config FEALNX
- tristate "Myson MTD-8xx PCI Ethernet support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- Say Y here to support the Mysom MTD-800 family of PCI-based Ethernet
- cards. Specifications and data at
- <http://www.myson.com.hk/mtd/datasheet/>.
-
-config NATSEMI
- tristate "National Semiconductor DP8381x series PCI Ethernet support"
- depends on NET_PCI && PCI
- select CRC32
- help
- This driver is for the National Semiconductor DP83810 series,
- which is used in cards from PureData, NetGear, Linksys
- and others, including the 83815 chip.
- More specific information and updates are available from
- <http://www.scyld.com/network/natsemi.html>.
-
-config NE2K_PCI
- tristate "PCI NE2000 and clones support (see help)"
- depends on NET_PCI && PCI
- select CRC32
- ---help---
- This driver is for NE2000 compatible PCI cards. It will not work
- with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
- support" below). If you have a PCI NE2000 network (Ethernet) card,
- say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- This driver also works for the following NE2000 clone cards:
- RealTek RTL-8029 Winbond 89C940 Compex RL2000 KTI ET32P2
- NetVin NV5000SC Via 86C926 SureCom NE34 Winbond
- Holtek HT80232 Holtek HT80229
-
- To compile this driver as a module, choose M here. The module
- will be called ne2k-pci.
-
-config NE3210
- tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)"
- depends on NET_PCI && EISA && EXPERIMENTAL
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>. Note that this driver
- will NOT WORK for NE3200 cards as they are completely different.
-
- To compile this driver as a module, choose M here. The module
- will be called ne3210.
-
-config ES3210
- tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)"
- depends on NET_PCI && EISA && EXPERIMENTAL
- select CRC32
- help
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called es3210.
-
-config 8139CP
- tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)"
- depends on NET_PCI && PCI && EXPERIMENTAL
- select CRC32
- select MII
- help
- This is a driver for the Fast Ethernet PCI network cards based on
- the RTL8139C+ chips. If you have one of those, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here: the module
- will be called 8139cp. This is recommended.
-
-config 8139TOO
- tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- ---help---
- This is a driver for the Fast Ethernet PCI network cards based on
- the RTL 8129/8130/8139 chips. If you have one of those, say Y and
- read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here: the module
- will be called 8139too. This is recommended.
-
-config 8139TOO_PIO
- bool "Use PIO instead of MMIO"
- default y
- depends on 8139TOO
- help
- This instructs the driver to use programmed I/O ports (PIO) instead
- of PCI shared memory (MMIO). This can possibly solve some problems
- in case your mainboard has memory consistency issues. If unsure,
- say N.
-
-config 8139TOO_TUNE_TWISTER
- bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)"
- depends on 8139TOO
- help
- This implements a function which might come in handy in case you
- are using low quality on long cabling. It is required for RealTek
- RTL-8139 revision K boards, and totally unused otherwise. It tries
- to match the transceiver to the cable characteristics. This is
- experimental since hardly documented by the manufacturer.
- If unsure, say Y.
-
-config 8139TOO_8129
- bool "Support for older RTL-8129/8130 boards"
- depends on 8139TOO
- help
- This enables support for the older and uncommon RTL-8129 and
- RTL-8130 chips, which support MII via an external transceiver,
- instead of an internal one. Disabling this option will save some
- memory by making the code size smaller. If unsure, say Y.
-
-config 8139_OLD_RX_RESET
- bool "Use older RX-reset method"
- depends on 8139TOO
- help
- The 8139too driver was recently updated to contain a more rapid
- reset sequence, in the face of severe receive errors. This "new"
- RX-reset method should be adequate for all boards. But if you
- experience problems, you can enable this option to restore the
- old RX-reset behavior. If unsure, say N.
-
-config R6040
- tristate "RDC R6040 Fast Ethernet Adapter support (EXPERIMENTAL)"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- This is a driver for the R6040 Fast Ethernet MACs found in the
- the RDC R-321x System-on-chips.
-
- To compile this driver as a module, choose M here: the module
- will be called r6040. This is recommended.
-
-config SIS900
- tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- ---help---
- This is a driver for the Fast Ethernet PCI network cards based on
- the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
- SiS 630 and SiS 540 chipsets.
-
- This driver also supports AMD 79C901 HomePNA so that you can use
- your phone line as a network cable.
-
- To compile this driver as a module, choose M here: the module
- will be called sis900. This is recommended.
-
-config EPIC100
- tristate "SMC EtherPower II"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
- which is based on the SMC83c17x (EPIC/100).
- More specific information and updates are available from
- <http://www.scyld.com/network/epic100.html>.
-
-config SUNDANCE
- tristate "Sundance Alta support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- This driver is for the Sundance "Alta" chip.
- More specific information and updates are available from
- <http://www.scyld.com/network/sundance.html>.
-
-config SUNDANCE_MMIO
- bool "Use MMIO instead of PIO"
- depends on SUNDANCE
- help
- Enable memory-mapped I/O for interaction with Sundance NIC registers.
- Do NOT enable this by default, PIO (enabled when MMIO is disabled)
- is known to solve bugs on certain chips.
-
- If unsure, say N.
-
-config TLAN
- tristate "TI ThunderLAN support"
- depends on NET_PCI && (PCI || EISA)
- ---help---
- If you have a PCI Ethernet network card based on the ThunderLAN chip
- which is supported by this driver, say Y and read the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Devices currently supported by this driver are Compaq Netelligent,
- Compaq NetFlex and Olicom cards. Please read the file
- <file:Documentation/networking/tlan.txt> for more details.
-
- To compile this driver as a module, choose M here. The module
- will be called tlan.
-
- Please email feedback to <torben.mathiasen@compaq.com>.
-
-config VIA_RHINE
- tristate "VIA Rhine support"
- depends on NET_PCI && PCI
- select CRC32
- select MII
- help
- If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
- Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type
- Ethernet functions can also be found integrated on South Bridges
- (e.g. VT8235).
-
- To compile this driver as a module, choose M here. The module
- will be called via-rhine.
-
-config VIA_RHINE_MMIO
- bool "Use MMIO instead of PIO"
- depends on VIA_RHINE
+config NET_FC
+ bool "Fibre Channel driver support"
+ depends on SCSI && PCI
help
- This instructs the driver to use PCI shared memory (MMIO) instead of
- programmed I/O ports (PIO). Enabling this gives an improvement in
- processing time in parts of the driver.
+ Fibre Channel is a high speed serial protocol mainly used to connect
+ large storage devices to the computer; it is compatible with and
+ intended to replace SCSI.
- If unsure, say Y.
+ If you intend to use Fibre Channel, you need to have a Fibre channel
+ adaptor card in your computer; say Y here and to the driver for your
+ adaptor below. You also should have said Y to "SCSI support" and
+ "SCSI generic support".
-config SC92031
- tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)"
- depends on NET_PCI && PCI && EXPERIMENTAL
- select CRC32
+config IFB
+ tristate "Intermediate Functional Block support"
+ depends on NET_CLS_ACT
---help---
- This is a driver for the Fast Ethernet PCI network cards based on
- the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you
- have one of these, say Y here.
-
+ This is an intermediate driver that allows sharing of
+ resources.
To compile this driver as a module, choose M here: the module
- will be called sc92031. This is recommended.
-
-config CPMAC
- tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
- depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN
- select PHYLIB
- help
- TI AR7 CPMAC Ethernet support
-
-config NET_POCKET
- bool "Pocket and portable adapters"
- depends on PARPORT
- ---help---
- Cute little network (Ethernet) devices which attach to the parallel
- port ("pocket adapters"), commonly used with laptops. If you have
- one of those, say Y and read the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- If you want to plug a network (or some other) card into the PCMCIA
- (or PC-card) slot of your laptop instead (PCMCIA is the standard for
- credit card size extension cards used by all modern laptops), you
- need the pcmcia-cs package (location contained in the file
- <file:Documentation/Changes>) and you can say N here.
-
- Laptop users should read the Linux Laptop home page at
- <http://www.linux-on-laptops.com/> or
- Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about this class of network devices. If you say Y, you
- will be asked for your specific device in the following questions.
-
-config ATP
- tristate "AT-LAN-TEC/RealTek pocket adapter support"
- depends on NET_POCKET && PARPORT && X86
- select CRC32
- ---help---
- This is a network (Ethernet) device which attaches to your parallel
- port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>, if you
- want to use this. If you intend to use this driver, you should have
- said N to the "Parallel printer support", because the two drivers
- don't like each other.
+ will be called ifb. If you want to use more than one ifb
+ device at a time, you need to compile this driver as a module.
+ Instead of 'ifb', the devices will then be called 'ifb0',
+ 'ifb1' etc.
+ Look at the iproute2 documentation directory for usage etc
- To compile this driver as a module, choose M here: the module
- will be called atp.
+source "drivers/net/team/Kconfig"
-config DE600
- tristate "D-Link DE600 pocket adapter support"
- depends on NET_POCKET && PARPORT
+config MACVLAN
+ tristate "MAC-VLAN support"
---help---
- This is a network (Ethernet) device which attaches to your parallel
- port. Read <file:Documentation/networking/DLINK.txt> as well as the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, if you want to use
- this. It is possible to have several devices share a single parallel
- port and it is safe to compile the corresponding drivers into the
- kernel.
+ This allows one to create virtual interfaces that map packets to
+ or from specific MAC addresses to a particular interface.
- To compile this driver as a module, choose M here: the module
- will be called de600.
+ Macvlan devices can be added using the "ip" command from the
+ iproute2 package starting with the iproute2-2.6.23 release:
-config DE620
- tristate "D-Link DE620 pocket adapter support"
- depends on NET_POCKET && PARPORT
- ---help---
- This is a network (Ethernet) device which attaches to your parallel
- port. Read <file:Documentation/networking/DLINK.txt> as well as the
- Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, if you want to use
- this. It is possible to have several devices share a single parallel
- port and it is safe to compile the corresponding drivers into the
- kernel.
+ "ip link add link <real dev> [ address MAC ] [ NAME ] type macvlan"
To compile this driver as a module, choose M here: the module
- will be called de620.
-
-config SGISEEQ
- tristate "SGI Seeq ethernet controller support"
- depends on SGI_HAS_SEEQ
- help
- Say Y here if you have an Seeq based Ethernet network card. This is
- used in many Silicon Graphics machines.
-
-config DECLANCE
- tristate "DEC LANCE ethernet controller support"
- depends on MACH_DECSTATION
- select CRC32
- help
- This driver is for the series of Ethernet controllers produced by
- DEC (now Compaq) based on the AMD Lance chipset, including the
- DEPCA series. (This chipset is better known via the NE2100 cards.)
-
-config 68360_ENET
- bool "Motorola 68360 ethernet controller"
- depends on M68360
- help
- Say Y here if you want to use the built-in ethernet controller of
- the Motorola 68360 processor.
-
-config FEC
- bool "FEC ethernet controller (of ColdFire CPUs)"
- depends on M523x || M527x || M5272 || M528x || M520x
- help
- Say Y here if you want to use the built-in 10/100 Fast ethernet
- controller on some Motorola ColdFire processors.
-
-config FEC2
- bool "Second FEC ethernet controller (on some ColdFire CPUs)"
- depends on FEC
- help
- Say Y here if you want to use the second built-in 10/100 Fast
- ethernet controller on some Motorola ColdFire processors.
-
-config FEC_MPC52xx
- tristate "MPC52xx FEC driver"
- depends on PPC_MERGE && PPC_MPC52xx && PPC_BESTCOMM_FEC
- select CRC32
- select PHYLIB
- ---help---
- This option enables support for the MPC5200's on-chip
- Fast Ethernet Controller
- If compiled as module, it will be called 'fec_mpc52xx.ko'.
-
-config FEC_MPC52xx_MDIO
- bool "MPC52xx FEC MDIO bus driver"
- depends on FEC_MPC52xx
- default y
- ---help---
- The MPC5200's FEC can connect to the Ethernet either with
- an external MII PHY chip or 10 Mbps 7-wire interface
- (Motorola? industry standard).
- If your board uses an external PHY connected to FEC, enable this.
- If not sure, enable.
- If compiled as module, it will be called 'fec_mpc52xx_phy.ko'.
-
-config NE_H8300
- tristate "NE2000 compatible support for H8/300"
- depends on H8300
- help
- Say Y here if you want to use the NE2000 compatible
- controller on the Renesas H8/300 processor.
-
-source "drivers/net/fs_enet/Kconfig"
-
-endif # NET_ETHERNET
-
-#
-# Gigabit Ethernet
-#
-
-menuconfig NETDEV_1000
- bool "Ethernet (1000 Mbit)"
- depends on !UML
- default y
- ---help---
- Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
- type of Local Area Network (LAN) in universities and companies.
-
- Say Y here to get to see options for Gigabit Ethernet drivers.
- This option alone does not add any kernel code.
- Note that drivers supporting both 100 and 1000 MBit may be listed
- under "Ethernet (10 or 100MBit)" instead.
-
- If you say N, all options in this submenu will be skipped and disabled.
-
-if NETDEV_1000
-
-config ACENIC
- tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
- depends on PCI
- ---help---
- Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
- GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
- adapter. The driver allows for using the Jumbo Frame option (9000
- bytes/frame) however it requires that your switches can handle this
- as well. To enable Jumbo Frames, add `mtu 9000' to your ifconfig
- line.
-
- To compile this driver as a module, choose M here: the
- module will be called acenic.
-
-config ACENIC_OMIT_TIGON_I
- bool "Omit support for old Tigon I based AceNICs"
- depends on ACENIC
- help
- Say Y here if you only have Tigon II based AceNICs and want to leave
- out support for the older Tigon I based cards which are no longer
- being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B
- version)). This will reduce the size of the driver object by
- app. 100KB. If you are not sure whether your card is a Tigon I or a
- Tigon II, say N here.
-
- The safe and default value for this is N.
-
-config DL2K
- tristate "DL2000/TC902x-based Gigabit Ethernet support"
- depends on PCI
- select CRC32
- help
- This driver supports DL2000/TC902x-based Gigabit ethernet cards,
- which includes
- D-Link DGE-550T Gigabit Ethernet Adapter.
- D-Link DL2000-based Gigabit Ethernet Adapter.
- Sundance/Tamarack TC902x Gigabit Ethernet Adapter.
-
- To compile this driver as a module, choose M here: the
- module will be called dl2k.
-
-config E1000
- tristate "Intel(R) PRO/1000 Gigabit Ethernet support"
- depends on PCI
- ---help---
- This driver supports Intel(R) PRO/1000 gigabit ethernet family of
- adapters. For more information on how to identify your adapter, go
- to the Adapter & Driver ID Guide at:
-
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
- For general information and support, go to the Intel support
- website at:
-
- <http://support.intel.com>
-
- More specific information on configuring the driver is in
- <file:Documentation/networking/e1000.txt>.
-
- To compile this driver as a module, choose M here. The module
- will be called e1000.
+ will be called macvlan.
-config E1000_DISABLE_PACKET_SPLIT
- bool "Disable Packet Split for PCI express adapters"
- depends on E1000
+config MACVTAP
+ tristate "MAC-VLAN based tap driver"
+ depends on MACVLAN
help
- Say Y here if you want to use the legacy receive path for PCI express
- hardware.
-
- If in doubt, say N.
-
-config E1000E
- tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
- depends on PCI && (!SPARC32 || BROKEN)
- ---help---
- This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
- ethernet family of adapters. For PCI or PCI-X e1000 adapters,
- use the regular e1000 driver For more information on how to
- identify your adapter, go to the Adapter & Driver ID Guide at:
-
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
- For general information and support, go to the Intel support
- website at:
-
- <http://support.intel.com>
-
- To compile this driver as a module, choose M here. The module
- will be called e1000e.
-
-config IP1000
- tristate "IP1000 Gigabit Ethernet support"
- depends on PCI && EXPERIMENTAL
- select MII
- ---help---
- This driver supports IP1000 gigabit Ethernet cards.
+ This adds a specialized tap character device driver that is based
+ on the MAC-VLAN network interface, called macvtap. A macvtap device
+ can be added in the same way as a macvlan device, using 'type
+ macvtap', and then be accessed through the tap user space interface.
To compile this driver as a module, choose M here: the module
- will be called ipg. This is recommended.
+ will be called macvtap.
-config IGB
- tristate "Intel(R) 82575 PCI-Express Gigabit Ethernet support"
- depends on PCI
+config VXLAN
+ tristate "Virtual eXtensible Local Area Network (VXLAN)"
+ depends on INET
+ select NET_IP_TUNNEL
---help---
- This driver supports Intel(R) 82575 gigabit ethernet family of
- adapters. For more information on how to identify your adapter, go
- to the Adapter & Driver ID Guide at:
-
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
- For general information and support, go to the Intel support
- website at:
-
- <http://support.intel.com>
-
- More specific information on configuring the driver is in
- <file:Documentation/networking/e1000.txt>.
-
- To compile this driver as a module, choose M here. The module
- will be called igb.
-
-config IGB_LRO
- bool "Use software LRO"
- depends on IGB && INET
- select INET_LRO
- ---help---
- Say Y here if you want to use large receive offload.
-
- If in doubt, say N.
-
-source "drivers/net/ixp2000/Kconfig"
-
-config MYRI_SBUS
- tristate "MyriCOM Gigabit Ethernet support"
- depends on SBUS
- help
- This driver supports MyriCOM Sbus gigabit Ethernet cards.
-
- To compile this driver as a module, choose M here: the module
- will be called myri_sbus. This is recommended.
-
-config NS83820
- tristate "National Semiconductor DP83820 support"
- depends on PCI
- help
- This is a driver for the National Semiconductor DP83820 series
- of gigabit ethernet MACs. Cards using this chipset include
- the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
- SOHO-GA2000T, SOHO-GA2500T. The driver supports the use of
- zero copy.
-
-config HAMACHI
- tristate "Packet Engines Hamachi GNIC-II support"
- depends on PCI
- select MII
- help
- If you have a Gigabit Ethernet card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module will be
- called hamachi.
-
-config YELLOWFIN
- tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)"
- depends on PCI && EXPERIMENTAL
- select CRC32
- ---help---
- Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet
- adapter or the SYM53C885 Ethernet controller. The Gigabit adapter is
- used by the Beowulf Linux cluster project. See
- <http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html> for more
- information about this driver in particular and Beowulf in general.
-
- To compile this driver as a module, choose M here: the module
- will be called yellowfin. This is recommended.
-
-config R8169
- tristate "Realtek 8169 gigabit ethernet support"
- depends on PCI
- select CRC32
- ---help---
- Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
-
- To compile this driver as a module, choose M here: the module
- will be called r8169. This is recommended.
-
-config R8169_VLAN
- bool "VLAN support"
- depends on R8169 && VLAN_8021Q
- ---help---
- Say Y here for the r8169 driver to support the functions required
- by the kernel 802.1Q code.
-
- If in doubt, say Y.
-
-config SB1250_MAC
- tristate "SB1250 Gigabit Ethernet support"
- depends on SIBYTE_SB1xxx_SOC
- select PHYLIB
- ---help---
- This driver supports Gigabit Ethernet interfaces based on the
- Broadcom SiByte family of System-On-a-Chip parts. They include
- the BCM1120, BCM1125, BCM1125H, BCM1250, BCM1255, BCM1280, BCM1455
- and BCM1480 chips.
+ This allows one to create vxlan virtual interfaces that provide
+ Layer 2 Networks over Layer 3 Networks. VXLAN is often used
+ to tunnel virtual network infrastructure in virtualized environments.
+ For more information see:
+ http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-02
To compile this driver as a module, choose M here: the module
- will be called sb1250-mac.
-
-config SIS190
- tristate "SiS190/SiS191 gigabit ethernet support"
- depends on PCI
- select CRC32
- select MII
- ---help---
- Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
- a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
- appear in lan on motherboard designs which are based on SiS 965
- and SiS 966 south bridge.
-
- To compile this driver as a module, choose M here: the module
- will be called sis190. This is recommended.
-
-config SKGE
- tristate "New SysKonnect GigaEthernet support"
- depends on PCI
- select CRC32
- ---help---
- This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
- and related Gigabit Ethernet adapters. It is a new smaller driver
- with better performance and more complete ethtool support.
-
- It does not support the link failover and network management
- features that "portable" vendor supplied sk98lin driver does.
-
- This driver supports adapters based on the original Yukon chipset:
- Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
- Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872.
-
- It does not support the newer Yukon2 chipset: a separate driver,
- sky2, is provided for Yukon2-based adapters.
+ will be called vxlan.
- To compile this driver as a module, choose M here: the module
- will be called skge. This is recommended.
-
-config SKGE_DEBUG
- bool "Debugging interface"
- depends on SKGE && DEBUG_FS
- help
- This option adds the ability to dump driver state for debugging.
- The file debugfs/skge/ethX displays the state of the internal
- transmit and receive rings.
-
- If unsure, say N.
-
-config SKY2
- tristate "SysKonnect Yukon2 support"
- depends on PCI
- select CRC32
+config NETCONSOLE
+ tristate "Network console logging support"
---help---
- This driver supports Gigabit Ethernet adapters based on the
- Marvell Yukon 2 chipset:
- Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
- 88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
-
- There is companion driver for the older Marvell Yukon and
- Genesis based adapters: skge.
-
- To compile this driver as a module, choose M here: the module
- will be called sky2. This is recommended.
-
-config SKY2_DEBUG
- bool "Debugging interface"
- depends on SKY2 && DEBUG_FS
- help
- This option adds the ability to dump driver state for debugging.
- The file debugfs/sky2/ethX displays the state of the internal
- transmit and receive rings.
-
- If unsure, say N.
+ If you want to log kernel messages over the network, enable this.
+ See <file:Documentation/networking/netconsole.txt> for details.
-config VIA_VELOCITY
- tristate "VIA Velocity support"
- depends on PCI
- select CRC32
- select CRC_CCITT
- select MII
+config NETCONSOLE_DYNAMIC
+ bool "Dynamic reconfiguration of logging targets"
+ depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \
+ !(NETCONSOLE=y && CONFIGFS_FS=m)
help
- If you have a VIA "Velocity" based network card say Y here.
-
- To compile this driver as a module, choose M here. The module
- will be called via-velocity.
+ This option enables the ability to dynamically reconfigure target
+ parameters (interface, IP addresses, port numbers, MAC addresses)
+ at runtime through a userspace interface exported using configfs.
+ See <file:Documentation/networking/netconsole.txt> for details.
-config TIGON3
- tristate "Broadcom Tigon3 support"
- depends on PCI
- select PHYLIB
- help
- This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
+config NETPOLL
+ def_bool NETCONSOLE
- To compile this driver as a module, choose M here: the module
- will be called tg3. This is recommended.
+config NET_POLL_CONTROLLER
+ def_bool NETPOLL
-config BNX2
- tristate "Broadcom NetXtremeII support"
- depends on PCI
- select CRC32
- select ZLIB_INFLATE
- help
- This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
+config NTB_NETDEV
+ tristate "Virtual Ethernet over NTB"
+ depends on NTB
- To compile this driver as a module, choose M here: the module
- will be called bnx2. This is recommended.
+config RIONET
+ tristate "RapidIO Ethernet over messaging driver support"
+ depends on RAPIDIO
-config SPIDER_NET
- tristate "Spider Gigabit Ethernet driver"
- depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
- select FW_LOADER
- help
- This driver supports the Gigabit Ethernet chips present on the
- Cell Processor-Based Blades from IBM.
-
-config TSI108_ETH
- tristate "Tundra TSI108 gigabit Ethernet support"
- depends on TSI108_BRIDGE
- help
- This driver supports Tundra TSI108 gigabit Ethernet ports.
- To compile this driver as a module, choose M here: the module
- will be called tsi108_eth.
-
-config GELIC_NET
- tristate "PS3 Gigabit Ethernet driver"
- depends on PPC_PS3
- select PS3_SYS_MANAGER
- help
- This driver supports the network device on the PS3 game
- console. This driver has built-in support for Ethernet.
+config RIONET_TX_SIZE
+ int "Number of outbound queue entries"
+ depends on RIONET
+ default "128"
- To compile this driver as a module, choose M here: the
- module will be called ps3_gelic.
+config RIONET_RX_SIZE
+ int "Number of inbound queue entries"
+ depends on RIONET
+ default "128"
-config GELIC_WIRELESS
- bool "PS3 Wireless support"
- depends on GELIC_NET
- select WIRELESS_EXT
- help
- This option adds the support for the wireless feature of PS3.
- If you have the wireless-less model of PS3 or have no plan to
- use wireless feature, disabling this option saves memory. As
- the driver automatically distinguishes the models, you can
- safely enable this option even if you have a wireless-less model.
-
-config GELIC_WIRELESS_OLD_PSK_INTERFACE
- bool "PS3 Wireless private PSK interface (OBSOLETE)"
- depends on GELIC_WIRELESS
- help
- This option retains the obsolete private interface to pass
- the PSK from user space programs to the driver. The PSK
- stands for 'Pre Shared Key' and is used for WPA[2]-PSK
- (WPA-Personal) environment.
- If WPA[2]-PSK is used and you need to use old programs that
- support only this old interface, say Y. Otherwise N.
-
- If unsure, say N.
-
-config GIANFAR
- tristate "Gianfar Ethernet"
- depends on FSL_SOC
- select PHYLIB
+config TUN
+ tristate "Universal TUN/TAP device driver support"
select CRC32
- help
- This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
- and MPC86xx family of chips, and the FEC on the 8540.
-
-config UCC_GETH
- tristate "Freescale QE Gigabit Ethernet"
- depends on QUICC_ENGINE
- select PHYLIB
- help
- This driver supports the Gigabit Ethernet mode of the QUICC Engine,
- which is available on some Freescale SOCs.
-
-config UGETH_MAGIC_PACKET
- bool "Magic Packet detection support"
- depends on UCC_GETH
-
-config UGETH_FILTERING
- bool "Mac address filtering support"
- depends on UCC_GETH
-
-config UGETH_TX_ON_DEMAND
- bool "Transmit on Demand support"
- depends on UCC_GETH
-
-config MV643XX_ETH
- tristate "Marvell Discovery (643XX) and Orion ethernet support"
- depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
- select MII
- help
- This driver supports the gigabit ethernet MACs in the
- Marvell Discovery PPC/MIPS chipset family (MV643XX) and
- in the Marvell Orion ARM SoC family.
+ ---help---
+ TUN/TAP provides packet reception and transmission for user space
+ programs. It can be viewed as a simple Point-to-Point or Ethernet
+ device, which instead of receiving packets from a physical media,
+ receives them from user space program and instead of sending packets
+ via physical media writes them to the user space program.
- Some boards that use the Discovery chipset are the Momenco
- Ocelot C and Jaguar ATX and Pegasos II.
+ When a program opens /dev/net/tun, driver creates and registers
+ corresponding net device tunX or tapX. After a program closed above
+ devices, driver will automatically delete tunXX or tapXX device and
+ all routes corresponding to it.
-config QLA3XXX
- tristate "QLogic QLA3XXX Network Driver Support"
- depends on PCI
- help
- This driver supports QLogic ISP3XXX gigabit Ethernet cards.
+ Please read <file:Documentation/networking/tuntap.txt> for more
+ information.
To compile this driver as a module, choose M here: the module
- will be called qla3xxx.
-
-config ATL1
- tristate "Attansic L1 Gigabit Ethernet support (EXPERIMENTAL)"
- depends on PCI && EXPERIMENTAL
- select CRC32
- select MII
- help
- This driver supports the Attansic L1 gigabit ethernet adapter.
-
- To compile this driver as a module, choose M here. The module
- will be called atl1.
-
-config ATL1E
- tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
- depends on PCI && EXPERIMENTAL
- select CRC32
- select MII
- help
- This driver supports the Atheros L1E gigabit ethernet adapter.
-
- To compile this driver as a module, choose M here. The module
- will be called atl1e.
-
-endif # NETDEV_1000
+ will be called tun.
-#
-# 10 Gigabit Ethernet
-#
+ If you don't know what to use this for, you don't need it.
-menuconfig NETDEV_10000
- bool "Ethernet (10000 Mbit)"
- depends on !UML
- default y
+config VETH
+ tristate "Virtual ethernet pair device"
---help---
- Say Y here to get to see options for 10 Gigabit Ethernet drivers.
- This option alone does not add any kernel code.
-
- If you say N, all options in this submenu will be skipped and disabled.
-
-if NETDEV_10000
-
-config CHELSIO_T1
- tristate "Chelsio 10Gb Ethernet support"
- depends on PCI
- select CRC32
- help
- This driver supports Chelsio gigabit and 10-gigabit
- Ethernet cards. More information about adapter features and
- performance tuning is in <file:Documentation/networking/cxgb.txt>.
-
- For general information about Chelsio and our products, visit
- our website at <http://www.chelsio.com>.
-
- For customer support, please visit our customer support page at
- <http://www.chelsio.com/support.htm>.
-
- Please send feedback to <linux-bugs@chelsio.com>.
-
- To compile this driver as a module, choose M here: the module
- will be called cxgb.
-
-config CHELSIO_T1_1G
- bool "Chelsio gigabit Ethernet support"
- depends on CHELSIO_T1
- help
- Enables support for Chelsio's gigabit Ethernet PCI cards. If you
- are using only 10G cards say 'N' here.
-
-config CHELSIO_T3
- tristate "Chelsio Communications T3 10Gb Ethernet support"
- depends on PCI && INET
- select FW_LOADER
- select INET_LRO
- help
- This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
- adapters.
-
- For general information about Chelsio and our products, visit
- our website at <http://www.chelsio.com>.
-
- For customer support, please visit our customer support page at
- <http://www.chelsio.com/support.htm>.
-
- Please send feedback to <linux-bugs@chelsio.com>.
-
- To compile this driver as a module, choose M here: the module
- will be called cxgb3.
+ This device is a local ethernet tunnel. Devices are created in pairs.
+ When one end receives the packet it appears on its pair and vice
+ versa.
-config EHEA
- tristate "eHEA Ethernet support"
- depends on IBMEBUS && INET && SPARSEMEM
- select INET_LRO
+config VIRTIO_NET
+ tristate "Virtio network driver"
+ depends on VIRTIO
+ select AVERAGE
---help---
- This driver supports the IBM pSeries eHEA ethernet adapter.
-
- To compile the driver as a module, choose M here. The module
- will be called ehea.
+ This is the virtual network driver for virtio. It can be used with
+ lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
-config IXGBE
- tristate "Intel(R) 10GbE PCI Express adapters support"
- depends on PCI && INET
- select INET_LRO
+config NLMON
+ tristate "Virtual netlink monitoring device"
---help---
- This driver supports Intel(R) 10GbE PCI Express family of
- adapters. For more information on how to identify your adapter, go
- to the Adapter & Driver ID Guide at:
+ This option enables a monitoring net device for netlink skbs. The
+ purpose of this is to analyze netlink messages with packet sockets.
+ Thus applications like tcpdump will be able to see local netlink
+ messages if they tap into the netlink device, record pcaps for further
+ diagnostics, etc. This is mostly intended for developers or support
+ to debug netlink issues. If unsure, say N.
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+endif # NET_CORE
- For general information and support, go to the Intel support
- website at:
-
- <http://support.intel.com>
-
- To compile this driver as a module, choose M here. The module
- will be called ixgbe.
+config SUNGEM_PHY
+ tristate
-config IXGB
- tristate "Intel(R) PRO/10GbE support"
- depends on PCI
- ---help---
- This driver supports Intel(R) PRO/10GbE family of adapters for
- PCI-X type cards. For PCI-E type cards, use the "ixgbe" driver
- instead. For more information on how to identify your adapter, go
- to the Adapter & Driver ID Guide at:
+source "drivers/net/arcnet/Kconfig"
- <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+source "drivers/atm/Kconfig"
- For general information and support, go to the Intel support
- website at:
+source "drivers/net/caif/Kconfig"
- <http://support.intel.com>
+source "drivers/net/dsa/Kconfig"
- More specific information on configuring the driver is in
- <file:Documentation/networking/ixgb.txt>.
+source "drivers/net/ethernet/Kconfig"
- To compile this driver as a module, choose M here. The module
- will be called ixgb.
+source "drivers/net/fddi/Kconfig"
-config S2IO
- tristate "S2IO 10Gbe XFrame NIC"
- depends on PCI
- ---help---
- This driver supports the 10Gbe XFrame NIC of S2IO.
- More specific information on configuring the driver is in
- <file:Documentation/networking/s2io.txt>.
+source "drivers/net/hippi/Kconfig"
-config MYRI10GE
- tristate "Myricom Myri-10G Ethernet support"
- depends on PCI && INET
- select FW_LOADER
- select CRC32
- select INET_LRO
+config NET_SB1000
+ tristate "General Instruments Surfboard 1000"
+ depends on PNP
---help---
- This driver supports Myricom Myri-10G Dual Protocol interface in
- Ethernet mode. If the eeprom on your board is not recent enough,
- you will need a newer firmware image.
- You may get this image or more information, at:
-
- <http://www.myri.com/scs/download-Myri10GE.html>
+ This is a driver for the General Instrument (also known as
+ NextLevel) SURFboard 1000 internal
+ cable modem. This is an ISA card which is used by a number of cable
+ TV companies to provide cable modem access. It's a one-way
+ downstream-only cable modem, meaning that your upstream net link is
+ provided by your regular phone modem.
- To compile this driver as a module, choose M here. The module
- will be called myri10ge.
+ At present this driver only compiles as a module, so say M here if
+ you have this card. The module will be called sb1000. Then read
+ <file:Documentation/networking/README.sb1000> for information on how
+ to use this module, as it needs special ppp scripts for establishing
+ a connection. Further documentation and the necessary scripts can be
+ found at:
-config NETXEN_NIC
- tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
- depends on PCI
- help
- This enables the support for NetXen's Gigabit Ethernet card.
+ <http://www.jacksonville.net/~fventuri/>
+ <http://home.adelphia.net/~siglercm/sb1000.html>
+ <http://linuxpower.cx/~cable/>
-config NIU
- tristate "Sun Neptune 10Gbit Ethernet support"
- depends on PCI
- help
- This enables support for cards based upon Sun's
- Neptune chipset.
-
-config PASEMI_MAC
- tristate "PA Semi 1/10Gbit MAC"
- depends on PPC_PASEMI && PCI
- select PHYLIB
- select INET_LRO
- help
- This driver supports the on-chip 1/10Gbit Ethernet controller on
- PA Semi's PWRficient line of chips.
+ If you don't have this card, of course say N.
-config MLX4_CORE
- tristate
- depends on PCI
- default n
+source "drivers/net/phy/Kconfig"
-config MLX4_DEBUG
- bool "Verbose debugging output" if (MLX4_CORE && EMBEDDED)
- depends on MLX4_CORE
- default y
- ---help---
- This option causes debugging code to be compiled into the
- mlx4_core driver. The output can be turned on via the
- debug_level module parameter (which can also be set after
- the driver is loaded through sysfs).
-
-config TEHUTI
- tristate "Tehuti Networks 10G Ethernet"
- depends on PCI
- help
- Tehuti Networks 10G Ethernet NIC
+source "drivers/net/plip/Kconfig"
-config BNX2X
- tristate "Broadcom NetXtremeII 10Gb support"
- depends on PCI
- select ZLIB_INFLATE
- select LIBCRC32C
- help
- This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
- To compile this driver as a module, choose M here: the module
- will be called bnx2x. This is recommended.
+source "drivers/net/ppp/Kconfig"
-source "drivers/net/sfc/Kconfig"
+source "drivers/net/slip/Kconfig"
-endif # NETDEV_10000
+source "drivers/s390/net/Kconfig"
-source "drivers/net/tokenring/Kconfig"
+source "drivers/net/usb/Kconfig"
source "drivers/net/wireless/Kconfig"
-source "drivers/net/usb/Kconfig"
-
-source "drivers/net/pcmcia/Kconfig"
+source "drivers/net/wimax/Kconfig"
source "drivers/net/wan/Kconfig"
-source "drivers/atm/Kconfig"
-
-source "drivers/s390/net/Kconfig"
+source "drivers/net/ieee802154/Kconfig"
config XEN_NETDEV_FRONTEND
tristate "Xen network device frontend driver"
depends on XEN
+ select XEN_XENBUS_FRONTEND
default y
help
- The network device frontend driver allows the kernel to
- access network devices exported exported by a virtual
- machine containing a physical network device driver. The
- frontend driver is intended for unprivileged guest domains;
- if you are compiling a kernel for a Xen guest, you almost
- certainly want to enable this.
+ This driver provides support for Xen paravirtual network
+ devices exported by a Xen network driver domain (often
+ domain 0).
-config ISERIES_VETH
- tristate "iSeries Virtual Ethernet driver support"
- depends on PPC_ISERIES
+ The corresponding Linux backend driver is enabled by the
+ CONFIG_XEN_NETDEV_BACKEND option.
-config RIONET
- tristate "RapidIO Ethernet over messaging driver support"
- depends on RAPIDIO
+ If you are compiling a kernel for use as Xen guest, you
+ should say Y here. To compile this driver as a module, chose
+ M here: the module will be called xen-netfront.
-config RIONET_TX_SIZE
- int "Number of outbound queue entries"
- depends on RIONET
- default "128"
-
-config RIONET_RX_SIZE
- int "Number of inbound queue entries"
- depends on RIONET
- default "128"
-
-config FDDI
- bool "FDDI driver support"
- depends on (PCI || EISA || TC)
+config XEN_NETDEV_BACKEND
+ tristate "Xen backend network device"
+ depends on XEN_BACKEND
help
- Fiber Distributed Data Interface is a high speed local area network
- design; essentially a replacement for high speed Ethernet. FDDI can
- run over copper or fiber. If you are connected to such a network and
- want a driver for the FDDI card in your computer, say Y here (and
- then also Y to the driver for your FDDI card, below). Most people
- will say N.
-
-config DEFXX
- tristate "Digital DEFTA/DEFEA/DEFPA adapter support"
- depends on FDDI && (PCI || EISA || TC)
- ---help---
- This is support for the DIGITAL series of TURBOchannel (DEFTA),
- EISA (DEFEA) and PCI (DEFPA) controllers which can connect you
- to a local FDDI network.
+ This driver allows the kernel to act as a Xen network driver
+ domain which exports paravirtual network devices to other
+ Xen domains. These devices can be accessed by any operating
+ system that implements a compatible front end.
- To compile this driver as a module, choose M here: the module
- will be called defxx. If unsure, say N.
+ The corresponding Linux frontend driver is enabled by the
+ CONFIG_XEN_NETDEV_FRONTEND configuration option.
-config DEFXX_MMIO
- bool
- prompt "Use MMIO instead of PIO" if PCI || EISA
- depends on DEFXX
- default n if PCI || EISA
- default y
- ---help---
- This instructs the driver to use EISA or PCI memory-mapped I/O
- (MMIO) as appropriate instead of programmed I/O ports (PIO).
- Enabling this gives an improvement in processing time in parts
- of the driver, but it may cause problems with EISA (DEFEA)
- adapters. TURBOchannel does not have the concept of I/O ports,
- so MMIO is always used for these (DEFTA) adapters.
-
- If unsure, say N.
-
-config SKFP
- tristate "SysKonnect FDDI PCI support"
- depends on FDDI && PCI
- select BITREVERSE
- ---help---
- Say Y here if you have a SysKonnect FDDI PCI adapter.
- The following adapters are supported by this driver:
- - SK-5521 (SK-NET FDDI-UP)
- - SK-5522 (SK-NET FDDI-UP DAS)
- - SK-5541 (SK-NET FDDI-FP)
- - SK-5543 (SK-NET FDDI-LP)
- - SK-5544 (SK-NET FDDI-LP DAS)
- - SK-5821 (SK-NET FDDI-UP64)
- - SK-5822 (SK-NET FDDI-UP64 DAS)
- - SK-5841 (SK-NET FDDI-FP64)
- - SK-5843 (SK-NET FDDI-LP64)
- - SK-5844 (SK-NET FDDI-LP64 DAS)
- - Netelligent 100 FDDI DAS Fibre SC
- - Netelligent 100 FDDI SAS Fibre SC
- - Netelligent 100 FDDI DAS UTP
- - Netelligent 100 FDDI SAS UTP
- - Netelligent 100 FDDI SAS Fibre MIC
-
- Read <file:Documentation/networking/skfp.txt> for information about
- the driver.
-
- Questions concerning this driver can be addressed to:
- <linux@syskonnect.de>
-
- To compile this driver as a module, choose M here: the module
- will be called skfp. This is recommended.
+ The backend driver presents a standard network device
+ endpoint for each paravirtual network device to the driver
+ domain network stack. These can then be bridged or routed
+ etc in order to provide full network connectivity.
-config HIPPI
- bool "HIPPI driver support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && INET && PCI
- help
- HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and
- 1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI
- can run over copper (25m) or fiber (300m on multi-mode or 10km on
- single-mode). HIPPI networks are commonly used for clusters and to
- connect to super computers. If you are connected to a HIPPI network
- and have a HIPPI network card in your computer that you want to use
- under Linux, say Y here (you must also remember to enable the driver
- for your HIPPI card below). Most people will say N here.
-
-config ROADRUNNER
- tristate "Essential RoadRunner HIPPI PCI adapter support (EXPERIMENTAL)"
- depends on HIPPI && PCI
- help
- Say Y here if this is your PCI HIPPI network card.
-
- To compile this driver as a module, choose M here: the module
- will be called rrunner. If unsure, say N.
+ If you are compiling a kernel to run in a Xen network driver
+ domain (often this is domain 0) you should say Y here. To
+ compile this driver as a module, chose M here: the module
+ will be called xen-netback.
-config ROADRUNNER_LARGE_RINGS
- bool "Use large TX/RX rings (EXPERIMENTAL)"
- depends on ROADRUNNER
- help
- If you say Y here, the RoadRunner driver will preallocate up to 2 MB
- of additional memory to allow for fastest operation, both for
- transmitting and receiving. This memory cannot be used by any other
- kernel code or by user space programs. Say Y here only if you have
- the memory.
-
-config PLIP
- tristate "PLIP (parallel port) support"
- depends on PARPORT
- ---help---
- PLIP (Parallel Line Internet Protocol) is used to create a
- reasonably fast mini network consisting of two (or, rarely, more)
- local machines. A PLIP link from a Linux box is a popular means to
- install a Linux distribution on a machine which doesn't have a
- CD-ROM drive (a minimal system has to be transferred with floppies
- first). The kernels on both machines need to have this PLIP option
- enabled for this to work.
-
- The PLIP driver has two modes, mode 0 and mode 1. The parallel
- ports (the connectors at the computers with 25 holes) are connected
- with "null printer" or "Turbo Laplink" cables which can transmit 4
- bits at a time (mode 0) or with special PLIP cables, to be used on
- bidirectional parallel ports only, which can transmit 8 bits at a
- time (mode 1); you can find the wiring of these cables in
- <file:Documentation/networking/PLIP.txt>. The cables can be up to
- 15m long. Mode 0 works also if one of the machines runs DOS/Windows
- and has some PLIP software installed, e.g. the Crynwr PLIP packet
- driver (<http://oak.oakland.edu/simtel.net/msdos/pktdrvr-pre.html>)
- and winsock or NCSA's telnet.
-
- If you want to use PLIP, say Y and read the PLIP mini-HOWTO as well
- as the NET-3-HOWTO, both available from
- <http://www.tldp.org/docs.html#howto>. Note that the PLIP
- protocol has been changed and this PLIP driver won't work together
- with the PLIP support in Linux versions 1.0.x. This option enlarges
- your kernel by about 8 KB.
-
- To compile this driver as a module, choose M here. The module
- will be called plip. If unsure, say Y or M, in case you buy
- a laptop later.
-
-config PPP
- tristate "PPP (point-to-point protocol) support"
- select SLHC
- ---help---
- PPP (Point to Point Protocol) is a newer and better SLIP. It serves
- the same purpose: sending Internet traffic over telephone (and other
- serial) lines. Ask your access provider if they support it, because
- otherwise you can't use it; most Internet access providers these
- days support PPP rather than SLIP.
-
- To use PPP, you need an additional program called pppd as described
- in the PPP-HOWTO, available at
- <http://www.tldp.org/docs.html#howto>. Make sure that you have
- the version of pppd recommended in <file:Documentation/Changes>.
- The PPP option enlarges your kernel by about 16 KB.
-
- There are actually two versions of PPP: the traditional PPP for
- asynchronous lines, such as regular analog phone lines, and
- synchronous PPP which can be used over digital ISDN lines for
- example. If you want to use PPP over phone lines or other
- asynchronous serial lines, you need to say Y (or M) here and also to
- the next option, "PPP support for async serial ports". For PPP over
- synchronous lines, you should say Y (or M) here and to "Support
- synchronous PPP", below.
-
- If you said Y to "Version information on all symbols" above, then
- you cannot compile the PPP driver into the kernel; you can then only
- compile it as a module. To compile this driver as a module, choose M
- here. The module will be called ppp_generic.
-
-config PPP_MULTILINK
- bool "PPP multilink support (EXPERIMENTAL)"
- depends on PPP && EXPERIMENTAL
- help
- PPP multilink is a protocol (defined in RFC 1990) which allows you
- to combine several (logical or physical) lines into one logical PPP
- connection, so that you can utilize your full bandwidth.
-
- This has to be supported at the other end as well and you need a
- version of the pppd daemon which understands the multilink protocol.
-
- If unsure, say N.
-
-config PPP_FILTER
- bool "PPP filtering"
- depends on PPP
- help
- Say Y here if you want to be able to filter the packets passing over
- PPP interfaces. This allows you to control which packets count as
- activity (i.e. which packets will reset the idle timer or bring up
- a demand-dialed link) and which packets are to be dropped entirely.
- You need to say Y here if you wish to use the pass-filter and
- active-filter options to pppd.
-
- If unsure, say N.
-
-config PPP_ASYNC
- tristate "PPP support for async serial ports"
- depends on PPP
- select CRC_CCITT
- ---help---
- Say Y (or M) here if you want to be able to use PPP over standard
- asynchronous serial ports, such as COM1 or COM2 on a PC. If you use
- a modem (not a synchronous or ISDN modem) to contact your ISP, you
- need this option.
-
- To compile this driver as a module, choose M here.
-
- If unsure, say Y.
-
-config PPP_SYNC_TTY
- tristate "PPP support for sync tty ports"
- depends on PPP
- help
- Say Y (or M) here if you want to be able to use PPP over synchronous
- (HDLC) tty devices, such as the SyncLink adapter. These devices
- are often used for high-speed leased lines like T1/E1.
-
- To compile this driver as a module, choose M here.
-
-config PPP_DEFLATE
- tristate "PPP Deflate compression"
- depends on PPP
- select ZLIB_INFLATE
- select ZLIB_DEFLATE
- ---help---
- Support for the Deflate compression method for PPP, which uses the
- Deflate algorithm (the same algorithm that gzip uses) to compress
- each PPP packet before it is sent over the wire. The machine at the
- other end of the PPP link (usually your ISP) has to support the
- Deflate compression method as well for this to be useful. Even if
- they don't support it, it is safe to say Y here.
-
- To compile this driver as a module, choose M here.
-
-config PPP_BSDCOMP
- tristate "PPP BSD-Compress compression"
- depends on PPP
- ---help---
- Support for the BSD-Compress compression method for PPP, which uses
- the LZW compression method to compress each PPP packet before it is
- sent over the wire. The machine at the other end of the PPP link
- (usually your ISP) has to support the BSD-Compress compression
- method as well for this to be useful. Even if they don't support it,
- it is safe to say Y here.
-
- The PPP Deflate compression method ("PPP Deflate compression",
- above) is preferable to BSD-Compress, because it compresses better
- and is patent-free.
-
- Note that the BSD compression code will always be compiled as a
- module; it is called bsd_comp and will show up in the directory
- modules once you have said "make modules". If unsure, say N.
-
-config PPP_MPPE
- tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
- depends on PPP && EXPERIMENTAL
- select CRYPTO
- select CRYPTO_SHA1
- select CRYPTO_ARC4
- select CRYPTO_ECB
- ---help---
- Support for the MPPE Encryption protocol, as employed by the
- Microsoft Point-to-Point Tunneling Protocol.
-
- See http://pptpclient.sourceforge.net/ for information on
- configuring PPTP clients and servers to utilize this method.
-
-config PPPOE
- tristate "PPP over Ethernet (EXPERIMENTAL)"
- depends on EXPERIMENTAL && PPP
- help
- Support for PPP over Ethernet.
-
- This driver requires the latest version of pppd from the CVS
- repository at cvs.samba.org. Alternatively, see the
- RoaringPenguin package (<http://www.roaringpenguin.com/pppoe>)
- which contains instruction on how to use this driver (under
- the heading "Kernel mode PPPoE").
-
-config PPPOATM
- tristate "PPP over ATM"
- depends on ATM && PPP
- help
- Support PPP (Point to Point Protocol) encapsulated in ATM frames.
- This implementation does not yet comply with section 8 of RFC2364,
- which can lead to bad results if the ATM peer loses state and
- changes its encapsulation unilaterally.
-
-config PPPOL2TP
- tristate "PPP over L2TP (EXPERIMENTAL)"
- depends on EXPERIMENTAL && PPP && INET
- help
- Support for PPP-over-L2TP socket family. L2TP is a protocol
- used by ISPs and enterprises to tunnel PPP traffic over UDP
- tunnels. L2TP is replacing PPTP for VPN uses.
-
- This kernel component handles only L2TP data packets: a
- userland daemon handles L2TP the control protocol (tunnel
- and session setup). One such daemon is OpenL2TP
- (http://openl2tp.sourceforge.net/).
-
-config SLIP
- tristate "SLIP (serial line) support"
- ---help---
- Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
- connect to your Internet service provider or to connect to some
- other local Unix box or if you want to configure your Linux box as a
- Slip/CSlip server for other people to dial in. SLIP (Serial Line
- Internet Protocol) is a protocol used to send Internet traffic over
- serial connections such as telephone lines or null modem cables;
- nowadays, the protocol PPP is more commonly used for this same
- purpose.
-
- Normally, your access provider has to support SLIP in order for you
- to be able to use it, but there is now a SLIP emulator called SLiRP
- around (available from
- <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
- allows you to use SLIP over a regular dial up shell connection. If
- you plan to use SLiRP, make sure to say Y to CSLIP, below. The
- NET-3-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, explains how to
- configure SLIP. Note that you don't need this option if you just
- want to run term (term is a program which gives you almost full
- Internet connectivity if you have a regular dial up shell account on
- some Internet connected Unix computer. Read
- <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>). SLIP
- support will enlarge your kernel by about 4 KB. If unsure, say N.
-
- To compile this driver as a module, choose M here. The module
- will be called slip.
-
-config SLIP_COMPRESSED
- bool "CSLIP compressed headers"
- depends on SLIP
- select SLHC
- ---help---
- This protocol is faster than SLIP because it uses compression on the
- TCP/IP headers (not on the data itself), but it has to be supported
- on both ends. Ask your access provider if you are not sure and
- answer Y, just in case. You will still be able to use plain SLIP. If
- you plan to use SLiRP, the SLIP emulator (available from
- <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
- allows you to use SLIP over a regular dial up shell connection, you
- definitely want to say Y here. The NET-3-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, explains how to configure
- CSLIP. This won't enlarge your kernel.
-
-config SLHC
- tristate
- help
- This option enables Van Jacobsen serial line header compression
- routines.
-
-config SLIP_SMART
- bool "Keepalive and linefill"
- depends on SLIP
- help
- Adds additional capabilities to the SLIP driver to support the
- RELCOM line fill and keepalive monitoring. Ideal on poor quality
- analogue lines.
-
-config SLIP_MODE_SLIP6
- bool "Six bit SLIP encapsulation"
- depends on SLIP
- help
- Just occasionally you may need to run IP over hostile serial
- networks that don't pass all control characters or are only seven
- bit. Saying Y here adds an extra mode you can use with SLIP:
- "slip6". In this mode, SLIP will only send normal ASCII symbols over
- the serial device. Naturally, this has to be supported at the other
- end of the link as well. It's good enough, for example, to run IP
- over the async ports of a Camtec JNT Pad. If unsure, say N.
-
-config NET_FC
- bool "Fibre Channel driver support"
- depends on SCSI && PCI
- help
- Fibre Channel is a high speed serial protocol mainly used to connect
- large storage devices to the computer; it is compatible with and
- intended to replace SCSI.
-
- If you intend to use Fibre Channel, you need to have a Fibre channel
- adaptor card in your computer; say Y here and to the driver for your
- adaptor below. You also should have said Y to "SCSI support" and
- "SCSI generic support".
-
-config NETCONSOLE
- tristate "Network console logging support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- ---help---
- If you want to log kernel messages over the network, enable this.
- See <file:Documentation/networking/netconsole.txt> for details.
-
-config NETCONSOLE_DYNAMIC
- bool "Dynamic reconfiguration of logging targets (EXPERIMENTAL)"
- depends on NETCONSOLE && SYSFS && EXPERIMENTAL
- select CONFIGFS_FS
+config VMXNET3
+ tristate "VMware VMXNET3 ethernet driver"
+ depends on PCI && INET
help
- This option enables the ability to dynamically reconfigure target
- parameters (interface, IP addresses, port numbers, MAC addresses)
- at runtime through a userspace interface exported using configfs.
- See <file:Documentation/networking/netconsole.txt> for details.
-
-config NETPOLL
- def_bool NETCONSOLE
-
-config NETPOLL_TRAP
- bool "Netpoll traffic trapping"
- default n
- depends on NETPOLL
-
-config NET_POLL_CONTROLLER
- def_bool NETPOLL
+ This driver supports VMware's vmxnet3 virtual ethernet NIC.
+ To compile this driver as a module, choose M here: the
+ module will be called vmxnet3.
-config VIRTIO_NET
- tristate "Virtio network driver (EXPERIMENTAL)"
- depends on EXPERIMENTAL && VIRTIO
- ---help---
- This is the virtual network driver for virtio. It can be used with
- lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
+source "drivers/net/hyperv/Kconfig"
endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 7629c901721..3fef8a81c0f 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -1,236 +1,65 @@
#
-# Makefile for the Linux network (ethercard) device drivers.
+# Makefile for the Linux network device drivers.
#
-obj-$(CONFIG_E1000) += e1000/
-obj-$(CONFIG_E1000E) += e1000e/
-obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
-obj-$(CONFIG_IGB) += igb/
-obj-$(CONFIG_IXGBE) += ixgbe/
-obj-$(CONFIG_IXGB) += ixgb/
-obj-$(CONFIG_IP1000) += ipg.o
-obj-$(CONFIG_CHELSIO_T1) += chelsio/
-obj-$(CONFIG_CHELSIO_T3) += cxgb3/
-obj-$(CONFIG_EHEA) += ehea/
-obj-$(CONFIG_CAN) += can/
-obj-$(CONFIG_BONDING) += bonding/
-obj-$(CONFIG_ATL1) += atlx/
-obj-$(CONFIG_ATL1E) += atl1e/
-obj-$(CONFIG_GIANFAR) += gianfar_driver.o
-obj-$(CONFIG_TEHUTI) += tehuti.o
-
-gianfar_driver-objs := gianfar.o \
- gianfar_ethtool.o \
- gianfar_mii.o \
- gianfar_sysfs.o
-
-obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
-ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o ucc_geth_ethtool.o
-
#
-# link order important here
+# Networking Core Drivers
#
-obj-$(CONFIG_PLIP) += plip.o
-
-obj-$(CONFIG_ROADRUNNER) += rrunner.o
-
-obj-$(CONFIG_HAPPYMEAL) += sunhme.o
-obj-$(CONFIG_SUNLANCE) += sunlance.o
-obj-$(CONFIG_SUNQE) += sunqe.o
-obj-$(CONFIG_SUNBMAC) += sunbmac.o
-obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
-obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o
-obj-$(CONFIG_CASSINI) += cassini.o
-obj-$(CONFIG_SUNVNET) += sunvnet.o
-
-obj-$(CONFIG_MACE) += mace.o
-obj-$(CONFIG_BMAC) += bmac.o
-
-obj-$(CONFIG_VORTEX) += 3c59x.o
-obj-$(CONFIG_TYPHOON) += typhoon.o
-obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
-obj-$(CONFIG_PCNET32) += pcnet32.o
-obj-$(CONFIG_EEPRO100) += eepro100.o
-obj-$(CONFIG_E100) += e100.o
-obj-$(CONFIG_TLAN) += tlan.o
-obj-$(CONFIG_EPIC100) += epic100.o
-obj-$(CONFIG_SIS190) += sis190.o
-obj-$(CONFIG_SIS900) += sis900.o
-obj-$(CONFIG_R6040) += r6040.o
-obj-$(CONFIG_YELLOWFIN) += yellowfin.o
-obj-$(CONFIG_ACENIC) += acenic.o
-obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o
-obj-$(CONFIG_NATSEMI) += natsemi.o
-obj-$(CONFIG_NS83820) += ns83820.o
-obj-$(CONFIG_STNIC) += stnic.o 8390.o
-obj-$(CONFIG_FEALNX) += fealnx.o
-obj-$(CONFIG_TIGON3) += tg3.o
-obj-$(CONFIG_BNX2) += bnx2.o
-obj-$(CONFIG_BNX2X) += bnx2x.o
-bnx2x-objs := bnx2x_main.o bnx2x_link.o
-spidernet-y += spider_net.o spider_net_ethtool.o
-obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
-obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
-gelic_wireless-$(CONFIG_GELIC_WIRELESS) += ps3_gelic_wireless.o
-ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y)
-obj-$(CONFIG_TC35815) += tc35815.o
-obj-$(CONFIG_SKGE) += skge.o
-obj-$(CONFIG_SKY2) += sky2.o
-obj-$(CONFIG_SKFP) += skfp/
-obj-$(CONFIG_VIA_RHINE) += via-rhine.o
-obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
-obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
-obj-$(CONFIG_RIONET) += rionet.o
-obj-$(CONFIG_SH_ETH) += sh_eth.o
-
-#
-# end link order section
-#
-
-obj-$(CONFIG_MII) += mii.o
-obj-$(CONFIG_PHYLIB) += phy/
-
-obj-$(CONFIG_SUNDANCE) += sundance.o
-obj-$(CONFIG_HAMACHI) += hamachi.o
-obj-$(CONFIG_NET) += Space.o loopback.o
-obj-$(CONFIG_SEEQ8005) += seeq8005.o
-obj-$(CONFIG_NET_SB1000) += sb1000.o
-obj-$(CONFIG_MAC8390) += mac8390.o
-obj-$(CONFIG_APNE) += apne.o 8390.o
-obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
-obj-$(CONFIG_HP100) += hp100.o
-obj-$(CONFIG_SMC9194) += smc9194.o
-obj-$(CONFIG_FEC) += fec.o
-obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
-ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
- obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
-endif
-obj-$(CONFIG_68360_ENET) += 68360enet.o
-obj-$(CONFIG_WD80x3) += wd.o 8390.o
-obj-$(CONFIG_EL2) += 3c503.o 8390p.o
-obj-$(CONFIG_NE2000) += ne.o 8390p.o
-obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o
-obj-$(CONFIG_HPLAN) += hp.o 8390p.o
-obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o
-obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
-obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o
-obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o
-obj-$(CONFIG_E2100) += e2100.o 8390.o
-obj-$(CONFIG_ES3210) += es3210.o 8390.o
-obj-$(CONFIG_LNE390) += lne390.o 8390.o
-obj-$(CONFIG_NE3210) += ne3210.o 8390.o
-obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
-obj-$(CONFIG_B44) += b44.o
-obj-$(CONFIG_FORCEDETH) += forcedeth.o
-obj-$(CONFIG_NE_H8300) += ne-h8300.o
-obj-$(CONFIG_AX88796) += ax88796.o
-
-obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
-obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
-obj-$(CONFIG_QLA3XXX) += qla3xxx.o
-
-obj-$(CONFIG_PPP) += ppp_generic.o
-obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
-obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
-obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
-obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
-obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
-obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
-obj-$(CONFIG_PPPOL2TP) += pppox.o pppol2tp.o
-
-obj-$(CONFIG_SLIP) += slip.o
-obj-$(CONFIG_SLHC) += slhc.o
-
-obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
-
+obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_DUMMY) += dummy.o
+obj-$(CONFIG_EQUALIZER) += eql.o
obj-$(CONFIG_IFB) += ifb.o
obj-$(CONFIG_MACVLAN) += macvlan.o
-obj-$(CONFIG_DE600) += de600.o
-obj-$(CONFIG_DE620) += de620.o
-obj-$(CONFIG_LANCE) += lance.o
-obj-$(CONFIG_SUN3_82586) += sun3_82586.o
-obj-$(CONFIG_SUN3LANCE) += sun3lance.o
-obj-$(CONFIG_DEFXX) += defxx.o
-obj-$(CONFIG_SGISEEQ) += sgiseeq.o
-obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
-obj-$(CONFIG_AT1700) += at1700.o
-obj-$(CONFIG_EL1) += 3c501.o
-obj-$(CONFIG_EL16) += 3c507.o
-obj-$(CONFIG_ELMC) += 3c523.o
-obj-$(CONFIG_IBMLANA) += ibmlana.o
-obj-$(CONFIG_ELMC_II) += 3c527.o
-obj-$(CONFIG_EL3) += 3c509.o
-obj-$(CONFIG_3C515) += 3c515.o
-obj-$(CONFIG_EEXPRESS) += eexpress.o
-obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
-obj-$(CONFIG_8139CP) += 8139cp.o
-obj-$(CONFIG_8139TOO) += 8139too.o
-obj-$(CONFIG_ZNET) += znet.o
-obj-$(CONFIG_CPMAC) += cpmac.o
-obj-$(CONFIG_DEPCA) += depca.o
-obj-$(CONFIG_EWRK3) += ewrk3.o
-obj-$(CONFIG_ATP) += atp.o
-obj-$(CONFIG_NI5010) += ni5010.o
-obj-$(CONFIG_NI52) += ni52.o
-obj-$(CONFIG_NI65) += ni65.o
-obj-$(CONFIG_ELPLUS) += 3c505.o
-obj-$(CONFIG_AC3200) += ac3200.o 8390.o
-obj-$(CONFIG_APRICOT) += 82596.o
-obj-$(CONFIG_LASI_82596) += lasi_82596.o
-obj-$(CONFIG_SNI_82596) += sni_82596.o
-obj-$(CONFIG_MVME16x_NET) += 82596.o
-obj-$(CONFIG_BVME6000_NET) += 82596.o
-obj-$(CONFIG_SC92031) += sc92031.o
-
-# This is also a 82596 and should probably be merged
-obj-$(CONFIG_LP486E) += lp486e.o
-
-obj-$(CONFIG_ETH16I) += eth16i.o
-obj-$(CONFIG_ZORRO8390) += zorro8390.o
-obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
-obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
-obj-$(CONFIG_EQUALIZER) += eql.o
-obj-$(CONFIG_KORINA) += korina.o
-obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
-obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
-obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
-obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
-obj-$(CONFIG_DECLANCE) += declance.o
-obj-$(CONFIG_ATARILANCE) += atarilance.o
-obj-$(CONFIG_A2065) += a2065.o
-obj-$(CONFIG_HYDRA) += hydra.o
-obj-$(CONFIG_ARIADNE) += ariadne.o
-obj-$(CONFIG_CS89x0) += cs89x0.o
-obj-$(CONFIG_MACSONIC) += macsonic.o
-obj-$(CONFIG_MACMACE) += macmace.o
-obj-$(CONFIG_MAC89x0) += mac89x0.o
+obj-$(CONFIG_MACVTAP) += macvtap.o
+obj-$(CONFIG_MII) += mii.o
+obj-$(CONFIG_MDIO) += mdio.o
+obj-$(CONFIG_NET) += Space.o loopback.o
+obj-$(CONFIG_NETCONSOLE) += netconsole.o
+obj-$(CONFIG_PHYLIB) += phy/
+obj-$(CONFIG_RIONET) += rionet.o
+obj-$(CONFIG_NET_TEAM) += team/
obj-$(CONFIG_TUN) += tun.o
obj-$(CONFIG_VETH) += veth.o
-obj-$(CONFIG_NET_NETX) += netx-eth.o
-obj-$(CONFIG_DL2K) += dl2k.o
-obj-$(CONFIG_R8169) += r8169.o
-obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
-obj-$(CONFIG_IBMVETH) += ibmveth.o
-obj-$(CONFIG_S2IO) += s2io.o
-obj-$(CONFIG_MYRI10GE) += myri10ge/
-obj-$(CONFIG_SMC91X) += smc91x.o
-obj-$(CONFIG_SMC911X) += smc911x.o
-obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
-obj-$(CONFIG_DM9000) += dm9000.o
-obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
-pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
-obj-$(CONFIG_MLX4_CORE) += mlx4/
-obj-$(CONFIG_ENC28J60) += enc28j60.o
-
-obj-$(CONFIG_MACB) += macb.o
+obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
+obj-$(CONFIG_VXLAN) += vxlan.o
+obj-$(CONFIG_NLMON) += nlmon.o
-obj-$(CONFIG_ARM) += arm/
+#
+# Networking Drivers
+#
+obj-$(CONFIG_ARCNET) += arcnet/
obj-$(CONFIG_DEV_APPLETALK) += appletalk/
-obj-$(CONFIG_TR) += tokenring/
+obj-$(CONFIG_CAIF) += caif/
+obj-$(CONFIG_CAN) += can/
+obj-$(CONFIG_ETRAX_ETHERNET) += cris/
+obj-$(CONFIG_NET_DSA) += dsa/
+obj-$(CONFIG_ETHERNET) += ethernet/
+obj-$(CONFIG_FDDI) += fddi/
+obj-$(CONFIG_HIPPI) += hippi/
+obj-$(CONFIG_HAMRADIO) += hamradio/
+obj-$(CONFIG_IRDA) += irda/
+obj-$(CONFIG_PLIP) += plip/
+obj-$(CONFIG_PPP) += ppp/
+obj-$(CONFIG_PPP_ASYNC) += ppp/
+obj-$(CONFIG_PPP_BSDCOMP) += ppp/
+obj-$(CONFIG_PPP_DEFLATE) += ppp/
+obj-$(CONFIG_PPP_MPPE) += ppp/
+obj-$(CONFIG_PPP_SYNC_TTY) += ppp/
+obj-$(CONFIG_PPPOE) += ppp/
+obj-$(CONFIG_PPPOL2TP) += ppp/
+obj-$(CONFIG_PPTP) += ppp/
+obj-$(CONFIG_SLIP) += slip/
+obj-$(CONFIG_SLHC) += slip/
+obj-$(CONFIG_NET_SB1000) += sb1000.o
+obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o
obj-$(CONFIG_WAN) += wan/
-obj-$(CONFIG_ARCNET) += arcnet/
-obj-$(CONFIG_NET_PCMCIA) += pcmcia/
+obj-$(CONFIG_WLAN) += wireless/
+obj-$(CONFIG_WIMAX) += wimax/
+obj-$(CONFIG_IEEE802154) += ieee802154/
+
+obj-$(CONFIG_VMXNET3) += vmxnet3/
+obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o
+obj-$(CONFIG_XEN_NETDEV_BACKEND) += xen-netback/
obj-$(CONFIG_USB_CATC) += usb/
obj-$(CONFIG_USB_KAWETH) += usb/
@@ -239,20 +68,8 @@ obj-$(CONFIG_USB_RTL8150) += usb/
obj-$(CONFIG_USB_HSO) += usb/
obj-$(CONFIG_USB_USBNET) += usb/
obj-$(CONFIG_USB_ZD1201) += usb/
+obj-$(CONFIG_USB_IPHETH) += usb/
+obj-$(CONFIG_USB_CDC_PHONET) += usb/
-obj-y += wireless/
-obj-$(CONFIG_NET_TULIP) += tulip/
-obj-$(CONFIG_HAMRADIO) += hamradio/
-obj-$(CONFIG_IRDA) += irda/
-obj-$(CONFIG_ETRAX_ETHERNET) += cris/
-obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
-
-obj-$(CONFIG_NETCONSOLE) += netconsole.o
-
-obj-$(CONFIG_FS_ENET) += fs_enet/
-
-obj-$(CONFIG_NETXEN_NIC) += netxen/
-obj-$(CONFIG_NIU) += niu.o
-obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
-obj-$(CONFIG_SFC) += sfc/
-
+obj-$(CONFIG_HYPERV_NET) += hyperv/
+obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 3b79c6cf21a..67977f15af2 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -29,73 +29,15 @@
*/
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/trdevice.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netlink.h>
+#include <net/Space.h>
/* A unified ethernet device probe. This is the easiest way to have every
ethernet adaptor have the name "eth[0123...]".
*/
-extern struct net_device *ne2_probe(int unit);
-extern struct net_device *hp100_probe(int unit);
-extern struct net_device *ultra_probe(int unit);
-extern struct net_device *ultra32_probe(int unit);
-extern struct net_device *wd_probe(int unit);
-extern struct net_device *el2_probe(int unit);
-extern struct net_device *ne_probe(int unit);
-extern struct net_device *hp_probe(int unit);
-extern struct net_device *hp_plus_probe(int unit);
-extern struct net_device *express_probe(int unit);
-extern struct net_device *eepro_probe(int unit);
-extern struct net_device *at1700_probe(int unit);
-extern struct net_device *fmv18x_probe(int unit);
-extern struct net_device *eth16i_probe(int unit);
-extern struct net_device *i82596_probe(int unit);
-extern struct net_device *ewrk3_probe(int unit);
-extern struct net_device *el1_probe(int unit);
-extern struct net_device *wavelan_probe(int unit);
-extern struct net_device *arlan_probe(int unit);
-extern struct net_device *el16_probe(int unit);
-extern struct net_device *elmc_probe(int unit);
-extern struct net_device *elplus_probe(int unit);
-extern struct net_device *ac3200_probe(int unit);
-extern struct net_device *es_probe(int unit);
-extern struct net_device *lne390_probe(int unit);
-extern struct net_device *e2100_probe(int unit);
-extern struct net_device *ni5010_probe(int unit);
-extern struct net_device *ni52_probe(int unit);
-extern struct net_device *ni65_probe(int unit);
-extern struct net_device *sonic_probe(int unit);
-extern struct net_device *SK_init(int unit);
-extern struct net_device *seeq8005_probe(int unit);
-extern struct net_device *smc_init(int unit);
-extern struct net_device *atarilance_probe(int unit);
-extern struct net_device *sun3lance_probe(int unit);
-extern struct net_device *sun3_82586_probe(int unit);
-extern struct net_device *apne_probe(int unit);
-extern struct net_device *cs89x0_probe(int unit);
-extern struct net_device *hplance_probe(int unit);
-extern struct net_device *bagetlance_probe(int unit);
-extern struct net_device *mvme147lance_probe(int unit);
-extern struct net_device *tc515_probe(int unit);
-extern struct net_device *lance_probe(int unit);
-extern struct net_device *mac8390_probe(int unit);
-extern struct net_device *mac89x0_probe(int unit);
-extern struct net_device *mc32_probe(int unit);
-extern struct net_device *cops_probe(int unit);
-extern struct net_device *ltpc_probe(void);
-
-/* Detachable devices ("pocket adaptors") */
-extern struct net_device *de620_probe(int unit);
-
-/* Fibre Channel adapters */
-extern int iph5526_probe(struct net_device *dev);
-
-/* SBNI adapters */
-extern int sbni_probe(int unit);
-
struct devprobe2 {
struct net_device *(*probe)(int unit);
int status; /* non-zero if autoprobe has failed */
@@ -117,44 +59,8 @@ static int __init probe_list2(int unit, struct devprobe2 *p, int autoprobe)
}
/*
- * This is a bit of an artificial separation as there are PCI drivers
- * that also probe for EISA cards (in the PCI group) and there are ISA
- * drivers that probe for EISA cards (in the ISA group). These are the
- * legacy EISA only driver probes, and also the legacy PCI probes
- */
-
-static struct devprobe2 eisa_probes[] __initdata = {
-#ifdef CONFIG_ULTRA32
- {ultra32_probe, 0},
-#endif
-#ifdef CONFIG_AC3200
- {ac3200_probe, 0},
-#endif
-#ifdef CONFIG_ES3210
- {es_probe, 0},
-#endif
-#ifdef CONFIG_LNE390
- {lne390_probe, 0},
-#endif
- {NULL, 0},
-};
-
-static struct devprobe2 mca_probes[] __initdata = {
-#ifdef CONFIG_NE2_MCA
- {ne2_probe, 0},
-#endif
-#ifdef CONFIG_ELMC /* 3c523 */
- {elmc_probe, 0},
-#endif
-#ifdef CONFIG_ELMC_II /* 3c527 */
- {mc32_probe, 0},
-#endif
- {NULL, 0},
-};
-
-/*
* ISA probes that touch addresses < 0x400 (including those that also
- * look for EISA/PCI/MCA cards in addition to ISA cards).
+ * look for EISA/PCI cards in addition to ISA cards).
*/
static struct devprobe2 isa_probes[] __initdata = {
#if defined(CONFIG_HP100) && defined(CONFIG_ISA) /* ISA, EISA */
@@ -169,20 +75,7 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_WD80x3
{wd_probe, 0},
#endif
-#ifdef CONFIG_EL2 /* 3c503 */
- {el2_probe, 0},
-#endif
-#ifdef CONFIG_HPLAN
- {hp_probe, 0},
-#endif
-#ifdef CONFIG_HPLAN_PLUS
- {hp_plus_probe, 0},
-#endif
-#ifdef CONFIG_E2100 /* Cabletron E21xx series. */
- {e2100_probe, 0},
-#endif
-#if defined(CONFIG_NE2000) || \
- defined(CONFIG_NE_H8300) /* ISA (use ne2k-pci for PCI cards) */
+#if defined(CONFIG_NE2000) /* ISA (use ne2k-pci for PCI cards) */
{ne_probe, 0},
#endif
#ifdef CONFIG_LANCE /* ISA/VLB (use pcnet32 for PCI cards) */
@@ -191,64 +84,20 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_SMC9194
{smc_init, 0},
#endif
-#ifdef CONFIG_SEEQ8005
- {seeq8005_probe, 0},
-#endif
#ifdef CONFIG_CS89x0
+#ifndef CONFIG_CS89x0_PLATFORM
{cs89x0_probe, 0},
#endif
-#ifdef CONFIG_AT1700
- {at1700_probe, 0},
-#endif
-#ifdef CONFIG_ETH16I
- {eth16i_probe, 0}, /* ICL EtherTeam 16i/32 */
-#endif
-#ifdef CONFIG_EEXPRESS /* Intel EtherExpress */
- {express_probe, 0},
#endif
-#ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */
- {eepro_probe, 0},
-#endif
-#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
- {ewrk3_probe, 0},
-#endif
-#if defined(CONFIG_APRICOT) || defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */
+#if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */
{i82596_probe, 0},
#endif
-#ifdef CONFIG_EL1 /* 3c501 */
- {el1_probe, 0},
-#endif
-#ifdef CONFIG_WAVELAN /* WaveLAN */
- {wavelan_probe, 0},
-#endif
-#ifdef CONFIG_ARLAN /* Aironet */
- {arlan_probe, 0},
-#endif
-#ifdef CONFIG_EL16 /* 3c507 */
- {el16_probe, 0},
-#endif
-#ifdef CONFIG_ELPLUS /* 3c505 */
- {elplus_probe, 0},
-#endif
-#ifdef CONFIG_NI5010
- {ni5010_probe, 0},
-#endif
-#ifdef CONFIG_NI52
- {ni52_probe, 0},
-#endif
#ifdef CONFIG_NI65
{ni65_probe, 0},
#endif
{NULL, 0},
};
-static struct devprobe2 parport_probes[] __initdata = {
-#ifdef CONFIG_DE620 /* D-Link DE-620 adapter */
- {de620_probe, 0},
-#endif
- {NULL, 0},
-};
-
static struct devprobe2 m68k_probes[] __initdata = {
#ifdef CONFIG_ATARILANCE /* Lance-based Atari ethernet boards */
{atarilance_probe, 0},
@@ -287,52 +136,9 @@ static void __init ethif_probe2(int unit)
return;
(void)( probe_list2(unit, m68k_probes, base_addr == 0) &&
- probe_list2(unit, eisa_probes, base_addr == 0) &&
- probe_list2(unit, mca_probes, base_addr == 0) &&
- probe_list2(unit, isa_probes, base_addr == 0) &&
- probe_list2(unit, parport_probes, base_addr == 0));
-}
-
-#ifdef CONFIG_TR
-/* Token-ring device probe */
-extern int ibmtr_probe_card(struct net_device *);
-extern struct net_device *smctr_probe(int unit);
-
-static struct devprobe2 tr_probes2[] __initdata = {
-#ifdef CONFIG_SMCTR
- {smctr_probe, 0},
-#endif
- {NULL, 0},
-};
-
-static __init int trif_probe(int unit)
-{
- int err = -ENODEV;
-#ifdef CONFIG_IBMTR
- struct net_device *dev = alloc_trdev(0);
- if (!dev)
- return -ENOMEM;
-
- sprintf(dev->name, "tr%d", unit);
- netdev_boot_setup_check(dev);
- err = ibmtr_probe_card(dev);
- if (err)
- free_netdev(dev);
-#endif
- return err;
+ probe_list2(unit, isa_probes, base_addr == 0));
}
-static void __init trif_probe2(int unit)
-{
- unsigned long base_addr = netdev_boot_base("tr", unit);
-
- if (base_addr == 1)
- return;
- probe_list2(unit, tr_probes2, base_addr == 0);
-}
-#endif
-
-
/* Statically configured drivers -- order matters here. */
static int __init net_olddevs_init(void)
{
@@ -342,11 +148,6 @@ static int __init net_olddevs_init(void)
for (num = 0; num < 8; ++num)
sbni_probe(num);
#endif
-#ifdef CONFIG_TR
- for (num = 0; num < 8; ++num)
- if (!trif_probe(num))
- trif_probe2(num);
-#endif
for (num = 0; num < 8; ++num)
ethif_probe2(num);
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
deleted file mode 100644
index b1448637107..00000000000
--- a/drivers/net/ac3200.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */
-/*
- Written 1993, 1994 by Donald Becker.
- Copyright 1993 United States Government as represented by the Director,
- National Security Agency. This software may only be used and distributed
- according to the terms of the GNU General Public License as modified by SRC,
- incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN
- Adapter. The programming information is from the users manual, as related
- by glee@ardnassak.math.clemson.edu.
-
- Changelog:
-
- Paul Gortmaker 05/98 : add support for shared mem above 1MB.
-
- */
-
-static const char version[] =
- "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-#include <linux/eisa.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "8390.h"
-
-#define DRV_NAME "ac3200"
-
-/* Offsets from the base address. */
-#define AC_NIC_BASE 0x00
-#define AC_SA_PROM 0x16 /* The station address PROM. */
-#define AC_ADDR0 0x00 /* Prefix station address values. */
-#define AC_ADDR1 0x40
-#define AC_ADDR2 0x90
-#define AC_ID_PORT 0xC80
-#define AC_EISA_ID 0x0110d305
-#define AC_RESET_PORT 0xC84
-#define AC_RESET 0x00
-#define AC_ENABLE 0x01
-#define AC_CONFIG 0xC90 /* The configuration port. */
-
-#define AC_IO_EXTENT 0x20
- /* Actually accessed is:
- * AC_NIC_BASE (0-15)
- * AC_SA_PROM (0-5)
- * AC_ID_PORT (0-3)
- * AC_RESET_PORT
- * AC_CONFIG
- */
-
-/* Decoding of the configuration register. */
-static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
-static int addrmap[8] =
-{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 };
-static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
-
-#define config2irq(configval) config2irqmap[((configval) >> 3) & 7]
-#define config2mem(configval) addrmap[(configval) & 7]
-#define config2name(configval) port_name[((configval) >> 6) & 3]
-
-/* First and last 8390 pages. */
-#define AC_START_PG 0x00 /* First page of 8390 TX buffer */
-#define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */
-
-static int ac_probe1(int ioaddr, struct net_device *dev);
-
-static int ac_open(struct net_device *dev);
-static void ac_reset_8390(struct net_device *dev);
-static void ac_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void ac_block_output(struct net_device *dev, const int count,
- const unsigned char *buf, const int start_page);
-static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-
-static int ac_close_card(struct net_device *dev);
-
-
-/* Probe for the AC3200.
-
- The AC3200 can be identified by either the EISA configuration registers,
- or the unique value in the station address PROM.
- */
-
-static int __init do_ac3200_probe(struct net_device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
- int irq = dev->irq;
- int mem_start = dev->mem_start;
-
- if (ioaddr > 0x1ff) /* Check a single specified location. */
- return ac_probe1(ioaddr, dev);
- else if (ioaddr > 0) /* Don't probe at all. */
- return -ENXIO;
-
- if ( ! EISA_bus)
- return -ENXIO;
-
- for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- if (ac_probe1(ioaddr, dev) == 0)
- return 0;
- dev->irq = irq;
- dev->mem_start = mem_start;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init ac3200_probe(int unit)
-{
- struct net_device *dev = alloc_ei_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_ac3200_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static int __init ac_probe1(int ioaddr, struct net_device *dev)
-{
- int i, retval;
- DECLARE_MAC_BUF(mac);
-
- if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
- retval = -ENODEV;
- goto out;
- }
-
- if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
- retval = -ENODEV;
- goto out;
- }
-
-#ifndef final_version
- printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x,"
- " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
- inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
- inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
-#endif
-
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
-
- printk(KERN_DEBUG "AC3200 in EISA slot %d, node %s",
- ioaddr/0x1000, print_mac(mac, dev->dev_addr));
-#if 0
- /* Check the vendor ID/prefix. Redundant after checking the EISA ID */
- if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
- || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
- || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
- printk(", not found (invalid prefix).\n");
- retval = -ENODEV;
- goto out;
- }
-#endif
-
- /* Assign and allocate the interrupt now. */
- if (dev->irq == 0) {
- dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
- printk(", using");
- } else {
- dev->irq = irq_canonicalize(dev->irq);
- printk(", assigning");
- }
-
- retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
- if (retval) {
- printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
- goto out1;
- }
-
- printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);
-
- dev->base_addr = ioaddr;
-
-#ifdef notyet
- if (dev->mem_start) { /* Override the value from the board. */
- for (i = 0; i < 7; i++)
- if (addrmap[i] == dev->mem_start)
- break;
- if (i >= 7)
- i = 0;
- outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
- }
-#endif
-
- dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
- dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
-
- printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n",
- dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);
-
- /*
- * BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
- * the card mem within the region covered by `normal' RAM !!!
- *
- * ioremap() will fail in that case.
- */
- ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100);
- if (!ei_status.mem) {
- printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
- printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
- printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
- retval = -EINVAL;
- goto out1;
- }
- printk("ac3200.c: remapped %dkB card memory to virtual address %p\n",
- AC_STOP_PG/4, ei_status.mem);
-
- dev->mem_start = (unsigned long)ei_status.mem;
- dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256;
-
- ei_status.name = "AC3200";
- ei_status.tx_start_page = AC_START_PG;
- ei_status.rx_start_page = AC_START_PG + TX_PAGES;
- ei_status.stop_page = AC_STOP_PG;
- ei_status.word16 = 1;
-
- if (ei_debug > 0)
- printk(version);
-
- ei_status.reset_8390 = &ac_reset_8390;
- ei_status.block_input = &ac_block_input;
- ei_status.block_output = &ac_block_output;
- ei_status.get_8390_hdr = &ac_get_8390_hdr;
-
- dev->open = &ac_open;
- dev->stop = &ac_close_card;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
- NS8390_init(dev, 0);
-
- retval = register_netdev(dev);
- if (retval)
- goto out2;
- return 0;
-out2:
- if (ei_status.reg0)
- iounmap(ei_status.mem);
-out1:
- free_irq(dev->irq, dev);
-out:
- release_region(ioaddr, AC_IO_EXTENT);
- return retval;
-}
-
-static int ac_open(struct net_device *dev)
-{
-#ifdef notyet
- /* Someday we may enable the IRQ and shared memory here. */
- int ioaddr = dev->base_addr;
-#endif
-
- ei_open(dev);
- return 0;
-}
-
-static void ac_reset_8390(struct net_device *dev)
-{
- ushort ioaddr = dev->base_addr;
-
- outb(AC_RESET, ioaddr + AC_RESET_PORT);
- if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
-
- ei_status.txing = 0;
- outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
- if (ei_debug > 1) printk("reset done\n");
-
- return;
-}
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
- we don't need to be concerned with ring wrap as the header will be at
- the start of a page, so we optimize accordingly. */
-
-static void
-ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- void __iomem *hdr_start = ei_status.mem + ((ring_page - AC_START_PG)<<8);
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-}
-
-/* Block input and output are easy on shared memory ethercards, the only
- complication is when the ring buffer wraps. */
-
-static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
- int ring_offset)
-{
- void __iomem *start = ei_status.mem + ring_offset - AC_START_PG*256;
-
- if (ring_offset + count > AC_STOP_PG*256) {
- /* We must wrap the input move. */
- int semi_count = AC_STOP_PG*256 - ring_offset;
- memcpy_fromio(skb->data, start, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count,
- ei_status.mem + TX_PAGES*256, count);
- } else {
- memcpy_fromio(skb->data, start, count);
- }
-}
-
-static void ac_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- void __iomem *shmem = ei_status.mem + ((start_page - AC_START_PG)<<8);
-
- memcpy_toio(shmem, buf, count);
-}
-
-static int ac_close_card(struct net_device *dev)
-{
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
-#ifdef notyet
- /* We should someday disable shared memory and interrupts. */
- outb(0x00, ioaddr + 6); /* Disable interrupts. */
- free_irq(dev->irq, dev);
-#endif
-
- ei_close(dev);
- return 0;
-}
-
-#ifdef MODULE
-#define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */
-static struct net_device *dev_ac32[MAX_AC32_CARDS];
-static int io[MAX_AC32_CARDS];
-static int irq[MAX_AC32_CARDS];
-static int mem[MAX_AC32_CARDS];
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s)");
-MODULE_PARM_DESC(mem, "Memory base address(es)");
-MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
-MODULE_LICENSE("GPL");
-
-static int __init ac3200_module_init(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
- if (io[this_dev] == 0 && this_dev != 0)
- break;
- dev = alloc_ei_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_start = mem[this_dev]; /* Currently ignored by driver */
- if (do_ac3200_probe(dev) == 0) {
- dev_ac32[found++] = dev;
- continue;
- }
- free_netdev(dev);
- printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- /* Someday free_irq may be in ac_close_card() */
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, AC_IO_EXTENT);
- iounmap(ei_status.mem);
-}
-
-static void __exit ac3200_module_exit(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
- struct net_device *dev = dev_ac32[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-module_init(ac3200_module_init);
-module_exit(ac3200_module_exit);
-#endif /* MODULE */
diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h
deleted file mode 100644
index fd41f7887e2..00000000000
--- a/drivers/net/acenic_firmware.h
+++ /dev/null
@@ -1,9456 +0,0 @@
-/*
- * Declare these here even if Tigon I support is disabled to avoid
- * the compiler complaining about undefined symbols.
- */
-#define tigonFwReleaseMajor 0xc
-#define tigonFwReleaseMinor 0x4
-#define tigonFwReleaseFix 0xb
-#define tigonFwStartAddr 0x00004000
-#define tigonFwTextAddr 0x00004000
-#define tigonFwTextLen 0x11140
-#define tigonFwRodataAddr 0x00015140
-#define tigonFwRodataLen 0xac0
-#define tigonFwDataAddr 0x00015c20
-#define tigonFwDataLen 0x170
-#define tigonFwSbssAddr 0x00015d90
-#define tigonFwSbssLen 0x38
-#define tigonFwBssAddr 0x00015dd0
-#define tigonFwBssLen 0x2080
-#ifdef CONFIG_ACENIC_OMIT_TIGON_I
-#define tigonFwText NULL
-#define tigonFwData NULL
-#define tigonFwRodata NULL
-#else
-/* Generated by genfw.c */
-static u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = {
-0x10000003,
-0x0, 0xd, 0xd, 0x3c1d0001,
-0x8fbd5c54, 0x3a0f021, 0x3c100000, 0x26104000,
-0xc00100c, 0x0, 0xd, 0x27bdffd8,
-0x3c1cc000, 0x3c1b0013, 0x377bd800, 0xd021,
-0x3c170013, 0x36f75418, 0x2e02021, 0x340583e8,
-0xafbf0024, 0xc002488, 0xafb00020, 0xc0023e8,
-0x0, 0x3c040001, 0x248451a4, 0x24050001,
-0x2e03021, 0x3821, 0x3c100001, 0x26107e50,
-0xafb00010, 0xc002403, 0xafbb0014, 0x3c02000f,
-0x3442ffff, 0x2021024, 0x362102b, 0x10400009,
-0x24050003, 0x3c040001, 0x248451b0, 0x2003021,
-0x3603821, 0x3c020010, 0xafa20010, 0xc002403,
-0xafa00014, 0x2021, 0x3405c000, 0x3c010001,
-0x370821, 0xa02083b0, 0x3c010001, 0x370821,
-0xa02083b2, 0x3c010001, 0x370821, 0xa02083b3,
-0x3c010001, 0x370821, 0xac2083b4, 0xa2e004d8,
-0x418c0, 0x24840001, 0x771021, 0xac40727c,
-0x771021, 0xac407280, 0x2e31021, 0xa445727c,
-0x2c820020, 0x1440fff7, 0x418c0, 0x2021,
-0x3405c000, 0x418c0, 0x24840001, 0x771021,
-0xac40737c, 0x771021, 0xac407380, 0x2e31021,
-0xa445737c, 0x2c820080, 0x5440fff7, 0x418c0,
-0xaf800054, 0xaf80011c, 0x8f820044, 0x34420040,
-0xaf820044, 0x8f820044, 0x34420020, 0xaf820044,
-0x8f420218, 0x30420002, 0x10400009, 0x0,
-0x8f420220, 0x3c030002, 0x34630004, 0x431025,
-0xaee204c4, 0x8f42021c, 0x8001074, 0x34420004,
-0x8f420220, 0x3c030002, 0x34630006, 0x431025,
-0xaee204c4, 0x8f42021c, 0x34420006, 0xaee204cc,
-0x8f420218, 0x30420010, 0x1040000a, 0x0,
-0x8f42021c, 0x34420004, 0xaee204c8, 0x8f420220,
-0x3c03000a, 0x34630004, 0x431025, 0x800108a,
-0xaee204c0, 0x8f420220, 0x3c03000a, 0x34630006,
-0x431025, 0xaee204c0, 0x8f42021c, 0x34420006,
-0xaee204c8, 0x8f420218, 0x30420200, 0x10400003,
-0x24020001, 0x8001091, 0xa2e27248, 0xa2e07248,
-0x24020001, 0xaf8200a0, 0xaf8200b0, 0x8f830054,
-0x8f820054, 0x8001099, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0xaf800044, 0x8f420208, 0x8f43020c, 0xaee20010,
-0xaee30014, 0x8ee40010, 0x8ee50014, 0x26e20030,
-0xaee20028, 0x24020490, 0xaee20018, 0xaf840090,
-0xaf850094, 0x8ee20028, 0xaf8200b4, 0x96e2001a,
-0xaf82009c, 0x8f8200b0, 0x8ee304cc, 0x431025,
-0xaf8200b0, 0x8f8200b0, 0x30420004, 0x1440fffd,
-0x0, 0x8ee20450, 0x8ee30454, 0xaee304fc,
-0x8ee204fc, 0x2442e000, 0x2c422001, 0x1440000d,
-0x26e40030, 0x8ee20450, 0x8ee30454, 0x3c040001,
-0x248451bc, 0x3c050001, 0xafa00010, 0xafa00014,
-0x8ee704fc, 0x34a5f000, 0xc002403, 0x603021,
-0x26e40030, 0xc002488, 0x24050400, 0x27440080,
-0xc002488, 0x24050080, 0x26e4777c, 0xc002488,
-0x24050400, 0x8f42025c, 0x26e40094, 0xaee20060,
-0x8f420260, 0x27450200, 0x24060008, 0xaee20068,
-0x24020006, 0xc00249a, 0xaee20064, 0x3c023b9a,
-0x3442ca00, 0x2021, 0x24030002, 0xaee30074,
-0xaee30070, 0xaee2006c, 0x240203e8, 0xaee20104,
-0x24020001, 0xaee30100, 0xaee2010c, 0x3c030001,
-0x641821, 0x90635c20, 0x2e41021, 0x24840001,
-0xa043009c, 0x2c82000f, 0x1440fff8, 0x0,
-0x8f820040, 0x2e41821, 0x24840001, 0x21702,
-0x24420030, 0xa062009c, 0x2e41021, 0xa040009c,
-0x96e2046a, 0x30420003, 0x14400009, 0x0,
-0x96e2047a, 0x30420003, 0x50400131, 0x3c030800,
-0x96e2046a, 0x30420003, 0x1040002a, 0x3c020700,
-0x96e2047a, 0x30420003, 0x10400026, 0x3c020700,
-0x96e3047a, 0x96e2046a, 0x14620022, 0x3c020700,
-0x8ee204c0, 0x24030001, 0xa2e34e20, 0x34420e00,
-0xaee204c0, 0x8f420218, 0x30420100, 0x10400005,
-0x0, 0x3c020001, 0x2442e168, 0x800111d,
-0x21100, 0x3c020001, 0x2442d35c, 0x21100,
-0x21182, 0x3c030800, 0x431025, 0x3c010001,
-0xac221238, 0x3c020001, 0x2442f680, 0x21100,
-0x21182, 0x3c030800, 0x431025, 0x3c010001,
-0xac221278, 0x8ee20000, 0x34424000, 0x8001238,
-0xaee20000, 0x34423000, 0xafa20018, 0x8ee20608,
-0x8f430228, 0x24420001, 0x304900ff, 0x512300e2,
-0xafa00010, 0x8ee20608, 0x210c0, 0x571021,
-0x8fa30018, 0x8fa4001c, 0xac43060c, 0xac440610,
-0x8f870120, 0x27623800, 0x24e80020, 0x102102b,
-0x50400001, 0x27683000, 0x8f820128, 0x11020004,
-0x0, 0x8f820124, 0x15020007, 0x1021,
-0x8ee201a4, 0x3021, 0x24420001, 0xaee201a4,
-0x80011a0, 0x8ee201a4, 0x8ee40608, 0x420c0,
-0x801821, 0x8ee40430, 0x8ee50434, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xace40000,
-0xace50004, 0x8ee30608, 0x24020008, 0xa4e2000e,
-0x2402000d, 0xace20018, 0xace9001c, 0x318c0,
-0x2463060c, 0x2e31021, 0xace20008, 0x8ee204c4,
-0xace20010, 0xaf880120, 0x92e24e20, 0x14400037,
-0x24060001, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x24030040, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee54e30, 0x24420001, 0x10430007,
-0x0, 0x8ee24e34, 0x24420001, 0x10a20005,
-0x0, 0x800118a, 0x0, 0x14a00005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
-0xac800000, 0x80011a0, 0x0, 0x8ee24e30,
-0x24030040, 0x24420001, 0x50430003, 0x1021,
-0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x24020007,
-0xac820000, 0x24020001, 0xac820004, 0x54c0000c,
-0xaee90608, 0x3c040001, 0x248451c8, 0xafa00010,
-0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
-0xc002403, 0x34a5f000, 0x8001223, 0x0,
-0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
-0x50400001, 0x27663000, 0x8f820128, 0x10c20004,
-0x0, 0x8f820124, 0x14c20007, 0x0,
-0x8ee201a4, 0x3021, 0x24420001, 0xaee201a4,
-0x8001207, 0x8ee201a4, 0x8ee20608, 0xac62001c,
-0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008,
-0x24020008, 0xa462000e, 0x24020011, 0xac620018,
-0xac640000, 0xac650004, 0x8ee204c4, 0xac620010,
-0xaf860120, 0x92e24e20, 0x14400037, 0x24060001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c830000, 0x24020012, 0x1462001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x24030040,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee54e30, 0x24420001, 0x10430007, 0x0,
-0x8ee24e34, 0x24420001, 0x10a20005, 0x0,
-0x80011f1, 0x0, 0x14a00005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x8001207, 0x0, 0x8ee24e30, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020012, 0xac820000,
-0x24020001, 0xac820004, 0x14c0001b, 0x0,
-0x3c040001, 0x248451d0, 0xafa00010, 0xafa00014,
-0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
-0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0,
-0x8001223, 0x8ee201b0, 0x3c040001, 0x248451dc,
-0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
-0xc002403, 0x34a5f005, 0x8ee201ac, 0x24420001,
-0xaee201ac, 0x8ee201ac, 0x8ee20160, 0x3c040001,
-0x248451e8, 0x3405f001, 0x24420001, 0xaee20160,
-0x8ee20160, 0x3021, 0x3821, 0xafa00010,
-0xc002403, 0xafa00014, 0x8001238, 0x0,
-0x3c020001, 0x2442f5a8, 0x21100, 0x21182,
-0x431025, 0x3c010001, 0xac221278, 0x96e2045a,
-0x30420003, 0x10400025, 0x3c050fff, 0x8ee204c8,
-0x34a5ffff, 0x34420a00, 0xaee204c8, 0x8ee304c8,
-0x3c040001, 0x248451f4, 0x24020001, 0xa2e204ec,
-0xa2e204ed, 0x3c020002, 0x621825, 0x3c020001,
-0x2442a390, 0x451024, 0x21082, 0xaee304c8,
-0x3c030800, 0x431025, 0x3c010001, 0xac221220,
-0x3c020001, 0x2442add4, 0x451024, 0x21082,
-0x431025, 0x3c010001, 0xac221280, 0x96e6045a,
-0x3821, 0x24050011, 0xafa00010, 0xc002403,
-0xafa00014, 0x8001268, 0x0, 0x3c020001,
-0x2442a9d4, 0x21100, 0x21182, 0x3c030800,
-0x431025, 0x3c010001, 0xac221280, 0x96e2046a,
-0x30420010, 0x14400009, 0x0, 0x96e2047a,
-0x30420010, 0x10400112, 0x0, 0x96e2046a,
-0x30420010, 0x10400005, 0x3c020700, 0x96e2047a,
-0x30420010, 0x14400102, 0x3c020700, 0x34423000,
-0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001,
-0x304900ff, 0x512300e2, 0xafa00010, 0x8ee20608,
-0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c,
-0xac43060c, 0xac440610, 0x8f870120, 0x27623800,
-0x24e80020, 0x102102b, 0x50400001, 0x27683000,
-0x8f820128, 0x11020004, 0x0, 0x8f820124,
-0x15020007, 0x1021, 0x8ee201a4, 0x3021,
-0x24420001, 0xaee201a4, 0x80012ea, 0x8ee201a4,
-0x8ee40608, 0x420c0, 0x801821, 0x8ee40430,
-0x8ee50434, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xace40000, 0xace50004, 0x8ee30608,
-0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018,
-0xace9001c, 0x318c0, 0x2463060c, 0x2e31021,
-0xace20008, 0x8ee204c4, 0xace20010, 0xaf880120,
-0x92e24e20, 0x14400037, 0x24060001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c830000,
-0x24020007, 0x1462001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30,
-0x24420001, 0x10430007, 0x0, 0x8ee24e34,
-0x24420001, 0x10a20005, 0x0, 0x80012d4,
-0x0, 0x14a00005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x80012ea,
-0x0, 0x8ee24e30, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x24020007, 0xac820000, 0x24020001,
-0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001,
-0x248451c8, 0xafa00010, 0xafa00014, 0x8ee60608,
-0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000,
-0x800136d, 0x0, 0x8f830120, 0x27623800,
-0x24660020, 0xc2102b, 0x50400001, 0x27663000,
-0x8f820128, 0x10c20004, 0x0, 0x8f820124,
-0x14c20007, 0x0, 0x8ee201a4, 0x3021,
-0x24420001, 0xaee201a4, 0x8001351, 0x8ee201a4,
-0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4,
-0x2462001c, 0xac620008, 0x24020008, 0xa462000e,
-0x24020011, 0xac620018, 0xac640000, 0xac650004,
-0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20,
-0x14400037, 0x24060001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c830000, 0x24020012,
-0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34,
-0x1062001b, 0x24030040, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001,
-0x10430007, 0x0, 0x8ee24e34, 0x24420001,
-0x10a20005, 0x0, 0x800133b, 0x0,
-0x14a00005, 0x0, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
-0x50400013, 0xac800000, 0x8001351, 0x0,
-0x8ee24e30, 0x24030040, 0x24420001, 0x50430003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x24020012, 0xac820000, 0x24020001, 0xac820004,
-0x14c0001b, 0x0, 0x3c040001, 0x248451d0,
-0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228,
-0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0,
-0x24420001, 0xaee201b0, 0x800136d, 0x8ee201b0,
-0x3c040001, 0x248451dc, 0xafa00014, 0x8ee60608,
-0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005,
-0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac,
-0x8ee20160, 0x3c040001, 0x248451e8, 0x3405f002,
-0x24420001, 0xaee20160, 0x8ee20160, 0x3021,
-0x3821, 0xafa00010, 0xc002403, 0xafa00014,
-0x96e6047a, 0x96e7046a, 0x3c040001, 0x24845200,
-0x24050012, 0xafa00010, 0xc002403, 0xafa00014,
-0xc004500, 0x0, 0xc002318, 0x0,
-0x3c060001, 0x34c63800, 0xaee00608, 0xaf400228,
-0xaf40022c, 0x96e30458, 0x8ee40000, 0x3c0512d8,
-0x34a5c358, 0x27623800, 0xaee27258, 0x27623800,
-0xaee27260, 0x27623800, 0xaee27264, 0x3661021,
-0xaee27270, 0x2402ffff, 0xaee004d4, 0xaee004e0,
-0xaee004e4, 0xaee004f0, 0xa2e004f4, 0xaee00e0c,
-0xaee00e18, 0xaee00e10, 0xaee00e14, 0xaee00e1c,
-0xaee0724c, 0xaee05244, 0xaee05240, 0xaee0523c,
-0xaee07250, 0xaee07254, 0xaee0725c, 0xaee07268,
-0xaee004d0, 0x2463ffff, 0x852025, 0xaee304f8,
-0xaee40000, 0xaf800060, 0xaf820064, 0x3c020100,
-0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001,
-0x304900ff, 0x512300e2, 0xafa00010, 0x8ee20608,
-0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c,
-0xac43060c, 0xac440610, 0x8f870120, 0x27623800,
-0x24e80020, 0x102102b, 0x50400001, 0x27683000,
-0x8f820128, 0x11020004, 0x0, 0x8f820124,
-0x15020007, 0x1021, 0x8ee201a4, 0x3021,
-0x24420001, 0xaee201a4, 0x8001422, 0x8ee201a4,
-0x8ee40608, 0x420c0, 0x801821, 0x8ee40430,
-0x8ee50434, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xace40000, 0xace50004, 0x8ee30608,
-0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018,
-0xace9001c, 0x318c0, 0x2463060c, 0x2e31021,
-0xace20008, 0x8ee204c4, 0xace20010, 0xaf880120,
-0x92e24e20, 0x14400037, 0x24060001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c830000,
-0x24020007, 0x1462001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30,
-0x24420001, 0x10430007, 0x0, 0x8ee24e34,
-0x24420001, 0x10a20005, 0x0, 0x800140c,
-0x0, 0x14a00005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x8001422,
-0x0, 0x8ee24e30, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x24020007, 0xac820000, 0x24020001,
-0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001,
-0x248451c8, 0xafa00010, 0xafa00014, 0x8ee60608,
-0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000,
-0x80014a5, 0x0, 0x8f830120, 0x27623800,
-0x24660020, 0xc2102b, 0x50400001, 0x27663000,
-0x8f820128, 0x10c20004, 0x0, 0x8f820124,
-0x14c20007, 0x0, 0x8ee201a4, 0x3021,
-0x24420001, 0xaee201a4, 0x8001489, 0x8ee201a4,
-0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4,
-0x2462001c, 0xac620008, 0x24020008, 0xa462000e,
-0x24020011, 0xac620018, 0xac640000, 0xac650004,
-0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20,
-0x14400037, 0x24060001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c830000, 0x24020012,
-0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34,
-0x1062001b, 0x24030040, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001,
-0x10430007, 0x0, 0x8ee24e34, 0x24420001,
-0x10a20005, 0x0, 0x8001473, 0x0,
-0x14a00005, 0x0, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
-0x50400013, 0xac800000, 0x8001489, 0x0,
-0x8ee24e30, 0x24030040, 0x24420001, 0x50430003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x24020012, 0xac820000, 0x24020001, 0xac820004,
-0x14c0001b, 0x0, 0x3c040001, 0x248451d0,
-0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228,
-0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0,
-0x24420001, 0xaee201b0, 0x80014a5, 0x8ee201b0,
-0x3c040001, 0x248451dc, 0xafa00014, 0x8ee60608,
-0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005,
-0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac,
-0x8ee20154, 0x24420001, 0xaee20154, 0xc0014dc,
-0x8ee20154, 0x8f8200a0, 0x30420004, 0x1440fffd,
-0x0, 0x8f820040, 0x30420001, 0x14400008,
-0x0, 0x8f430104, 0x24020001, 0x10620004,
-0x0, 0x8f420264, 0x10400006, 0x0,
-0x8ee2017c, 0x24420001, 0xaee2017c, 0x80014c5,
-0x8ee2017c, 0x8f820044, 0x34420004, 0xaf820044,
-0x8ee20178, 0x24420001, 0xaee20178, 0x8ee20178,
-0x8f8200d8, 0x8f8300d4, 0x431023, 0xaee2726c,
-0x8ee2726c, 0x1c400003, 0x3c030001, 0x431021,
-0xaee2726c, 0xc004064, 0x0, 0xc004440,
-0xaf800228, 0x8fbf0024, 0x8fb00020, 0x3e00008,
-0x27bd0028, 0x3e00008, 0x0, 0x3e00008,
-0x0, 0x0, 0x0, 0x2402002c,
-0xaf820050, 0xaee07274, 0x8f420238, 0xaee27278,
-0x8f820054, 0x24420067, 0xaf820058, 0xaee07b88,
-0xaee07b8c, 0xaee07b84, 0x3c010001, 0x370821,
-0xac2083bc, 0x3c010001, 0x370821, 0x3e00008,
-0xa02083b9, 0x27bdffd8, 0xafbf0024, 0xafb00020,
-0x8f820054, 0x3c030001, 0x8c635cd8, 0x24420067,
-0x1060000d, 0xaf820058, 0x3c020001, 0x571021,
-0x904283b8, 0x10400005, 0x3c030200, 0x3c010001,
-0x370821, 0x8001503, 0xa02083b8, 0x8ee20000,
-0x431025, 0xaee20000, 0x8f420218, 0x30420100,
-0x104000c6, 0x0, 0x8f8200b0, 0x30420004,
-0x104000c2, 0x0, 0x3c030001, 0x771821,
-0x8c6383d0, 0x8f820104, 0x146200b4, 0x0,
-0x3c030001, 0x771821, 0x8c6383d4, 0x8f8200b4,
-0x146200ae, 0x0, 0x8f8200b0, 0x3c030080,
-0x431024, 0x1040000d, 0x0, 0x8f82011c,
-0x34420002, 0xaf82011c, 0x8f8200b0, 0x2403fffb,
-0x431024, 0xaf8200b0, 0x8f82011c, 0x2403fffd,
-0x431024, 0x80015cc, 0xaf82011c, 0x3c030001,
-0x771821, 0x8c6383d0, 0x8f820104, 0x14620082,
-0x0, 0x3c030001, 0x771821, 0x8c6383d4,
-0x8f8200b4, 0x1462007c, 0x0, 0x3c070001,
-0xf73821, 0x8ce783d0, 0x8f8200b0, 0x3c040001,
-0x24845270, 0xafa00014, 0xafa20010, 0x8f8600b0,
-0x3c050005, 0xc002403, 0x34a50900, 0x8f82011c,
-0x34420002, 0xaf82011c, 0x8f830104, 0x8f8200b0,
-0x34420001, 0xaf8200b0, 0xaf830104, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20006, 0x0, 0x8ee201a4,
-0x24420001, 0xaee201a4, 0x80015a0, 0x8ee201a4,
-0x8f440208, 0x8f45020c, 0x26e20030, 0xac620008,
-0x24020400, 0xa462000e, 0x2402000f, 0xac620018,
-0xac60001c, 0xac640000, 0xac650004, 0x8ee204c4,
-0xac620010, 0xaf860120, 0x92e24e20, 0x14400037,
-0x0, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x24030040, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee54e30, 0x24420001, 0x10430007,
-0x0, 0x8ee24e34, 0x24420001, 0x10a20005,
-0x0, 0x800158a, 0x0, 0x14a00005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
-0xac800000, 0x80015a0, 0x0, 0x8ee24e30,
-0x24030040, 0x24420001, 0x50430003, 0x1021,
-0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x24020007,
-0xac820000, 0x24020001, 0xac820004, 0x8f82011c,
-0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201e4,
-0x3c070001, 0xf73821, 0x8ce783d0, 0x24420001,
-0xaee201e4, 0x8ee201e4, 0x3c040001, 0x2484527c,
-0x80015bd, 0xafa00010, 0x8f820104, 0x3c010001,
-0x370821, 0xac2283d0, 0x8f8200b4, 0x3c070001,
-0xf73821, 0x8ce783d0, 0x3c040001, 0x24845284,
-0x3c010001, 0x370821, 0xac2283d4, 0xafa00010,
-0xafa00014, 0x8f8600b0, 0x3c050005, 0xc002403,
-0x34a50900, 0x80015cc, 0x0, 0x8f820104,
-0x3c010001, 0x370821, 0xac2283d0, 0x8f8200b4,
-0x3c010001, 0x370821, 0xac2283d4, 0x8ee27274,
-0x92e304f4, 0x24420067, 0x14600006, 0xaee27274,
-0x8ee27274, 0x8f430234, 0x43102b, 0x1440007b,
-0x0, 0x8ee304e4, 0x8ee204f8, 0x14620004,
-0x0, 0x92e204f4, 0x50400074, 0xa2e004f4,
-0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
-0x50400001, 0x27663000, 0x8f820128, 0x10c20004,
-0x0, 0x8f820124, 0x14c20007, 0x0,
-0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4,
-0x8001637, 0x8ee201a4, 0x8ee204e4, 0xac62001c,
-0x8ee404b0, 0x8ee504b4, 0x2462001c, 0xac620008,
-0x24020008, 0xa462000e, 0x24020011, 0xac620018,
-0xac640000, 0xac650004, 0x8ee204c4, 0xac620010,
-0xaf860120, 0x92e24e20, 0x14400037, 0x24100001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c830000, 0x24020012, 0x1462001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x24030040,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee54e30, 0x24420001, 0x10430007, 0x0,
-0x8ee24e34, 0x24420001, 0x10a20005, 0x0,
-0x8001621, 0x0, 0x14a00005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x8001637, 0x0, 0x8ee24e30, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020012, 0xac820000,
-0x24020001, 0xac820004, 0x5600000b, 0x24100001,
-0x8ee204e4, 0x3c040001, 0x2484528c, 0xafa00014,
-0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009,
-0xc002403, 0x34a5f006, 0x16000003, 0x24020001,
-0x8001650, 0xa2e204f4, 0x8ee20170, 0x24420001,
-0xaee20170, 0x8ee20170, 0x8ee204e4, 0xa2e004f4,
-0xaee004f0, 0xaee07274, 0xaee204f8, 0x8ee20e1c,
-0x1040006d, 0x0, 0x8f830120, 0x27623800,
-0x24660020, 0xc2102b, 0x50400001, 0x27663000,
-0x8f820128, 0x10c20004, 0x0, 0x8f820124,
-0x14c20007, 0x0, 0x8ee201a4, 0x8021,
-0x24420001, 0xaee201a4, 0x80016ad, 0x8ee201a4,
-0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac,
-0x2462001c, 0xac620008, 0x24020008, 0xa462000e,
-0x24020011, 0xac620018, 0xac640000, 0xac650004,
-0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20,
-0x14400037, 0x24100001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c830000, 0x24020012,
-0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34,
-0x1062001b, 0x24030040, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001,
-0x10430007, 0x0, 0x8ee24e34, 0x24420001,
-0x10a20005, 0x0, 0x8001697, 0x0,
-0x14a00005, 0x0, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
-0x50400013, 0xac800000, 0x80016ad, 0x0,
-0x8ee24e30, 0x24030040, 0x24420001, 0x50430003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x24020012, 0xac820000, 0x24020001, 0xac820004,
-0x5600000b, 0x24100001, 0x8ee2724c, 0x3c040001,
-0x24845298, 0xafa00014, 0xafa20010, 0x8ee6724c,
-0x8f470280, 0x3c050009, 0xc002403, 0x34a5f008,
-0x56000001, 0xaee00e1c, 0x8ee20174, 0x24420001,
-0xaee20174, 0x8ee20174, 0x8ee24e24, 0x10400019,
-0x0, 0xaee04e24, 0x8f820040, 0x30420001,
-0x14400008, 0x0, 0x8f430104, 0x24020001,
-0x10620004, 0x0, 0x8f420264, 0x10400006,
-0x0, 0x8ee2017c, 0x24420001, 0xaee2017c,
-0x80016da, 0x8ee2017c, 0x8f820044, 0x34420004,
-0xaf820044, 0x8ee20178, 0x24420001, 0xaee20178,
-0x8ee20178, 0x8ee27278, 0x2442ff99, 0xaee27278,
-0x8ee27278, 0x1c4002ad, 0x0, 0x8f420238,
-0x104002aa, 0x0, 0x3c020001, 0x571021,
-0x904283e0, 0x144002a5, 0x0, 0x8f420080,
-0xaee2004c, 0x8f4200c0, 0xaee20048, 0x8f420084,
-0xaee20038, 0x8f420084, 0xaee20244, 0x8f420088,
-0xaee20248, 0x8f42008c, 0xaee2024c, 0x8f420090,
-0xaee20250, 0x8f420094, 0xaee20254, 0x8f420098,
-0xaee20258, 0x8f42009c, 0xaee2025c, 0x8f4200a0,
-0xaee20260, 0x8f4200a4, 0xaee20264, 0x8f4200a8,
-0xaee20268, 0x8f4200ac, 0xaee2026c, 0x8f4200b0,
-0xaee20270, 0x8f4200b4, 0xaee20274, 0x8f4200b8,
-0xaee20278, 0x8f4200bc, 0x24040001, 0xaee2027c,
-0xaee0003c, 0x41080, 0x571021, 0x8ee3003c,
-0x8c420244, 0x24840001, 0x621821, 0x2c82000f,
-0xaee3003c, 0x1440fff8, 0x41080, 0x8f4200cc,
-0xaee20050, 0x8f4200d0, 0xaee20054, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20007, 0x0, 0x8ee201a4,
-0x8021, 0x24420001, 0xaee201a4, 0x8001775,
-0x8ee201a4, 0x8f440208, 0x8f45020c, 0x26e20030,
-0xac620008, 0x24020400, 0xa462000e, 0x2402000f,
-0xac620018, 0xac60001c, 0xac640000, 0xac650004,
-0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20,
-0x14400037, 0x24100001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c830000, 0x24020007,
-0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34,
-0x1062001b, 0x24030040, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001,
-0x10430007, 0x0, 0x8ee24e34, 0x24420001,
-0x10a20005, 0x0, 0x800175f, 0x0,
-0x14a00005, 0x0, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
-0x50400013, 0xac800000, 0x8001775, 0x0,
-0x8ee24e30, 0x24030040, 0x24420001, 0x50430003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x24020007, 0xac820000, 0x24020001, 0xac820004,
-0x12000212, 0x3c020400, 0xafa20018, 0x3c020001,
-0x571021, 0x904283b0, 0x1040010b, 0x0,
-0x8ee20608, 0x8f430228, 0x24420001, 0x304a00ff,
-0x514300fd, 0xafa00010, 0x8ee20608, 0x210c0,
-0x571021, 0x8fa30018, 0x8fa4001c, 0xac43060c,
-0xac440610, 0x8f830054, 0x8f820054, 0x24690032,
-0x1221023, 0x2c420033, 0x1040006a, 0x5821,
-0x24180008, 0x240f000d, 0x240d0007, 0x240c0040,
-0x240e0001, 0x8f870120, 0x27623800, 0x24e80020,
-0x102102b, 0x50400001, 0x27683000, 0x8f820128,
-0x11020004, 0x0, 0x8f820124, 0x15020007,
-0x1021, 0x8ee201a4, 0x8021, 0x24420001,
-0xaee201a4, 0x80017f3, 0x8ee201a4, 0x8ee40608,
-0x420c0, 0x801821, 0x8ee40430, 0x8ee50434,
-0xa32821, 0xa3302b, 0x822021, 0x862021,
-0xace40000, 0xace50004, 0x8ee20608, 0xa4f8000e,
-0xacef0018, 0xacea001c, 0x210c0, 0x2442060c,
-0x2e21021, 0xace20008, 0x8ee204c4, 0xace20010,
-0xaf880120, 0x92e24e20, 0x14400033, 0x24100001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c820000, 0x144d001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x104c0007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x80017e0,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400010, 0xac800000, 0x80017f3,
-0x0, 0x8ee24e30, 0x24420001, 0x504c0003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0xac8d0000, 0xac8e0004, 0x56000006, 0x240b0001,
-0x8f820054, 0x1221023, 0x2c420033, 0x1440ff9d,
-0x0, 0x316300ff, 0x24020001, 0x14620077,
-0x3c050009, 0xaeea0608, 0x8f830054, 0x8f820054,
-0x24690032, 0x1221023, 0x2c420033, 0x10400061,
-0x5821, 0x240d0008, 0x240c0011, 0x24080012,
-0x24070040, 0x240a0001, 0x8f830120, 0x27623800,
-0x24660020, 0xc2102b, 0x50400001, 0x27663000,
-0x8f820128, 0x10c20004, 0x0, 0x8f820124,
-0x14c20007, 0x0, 0x8ee201a4, 0x8021,
-0x24420001, 0xaee201a4, 0x800185f, 0x8ee201a4,
-0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4,
-0x2462001c, 0xac620008, 0xa46d000e, 0xac6c0018,
-0xac640000, 0xac650004, 0x8ee204c4, 0xac620010,
-0xaf860120, 0x92e24e20, 0x14400033, 0x24100001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c820000, 0x1448001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x10470007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x800184c,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400010, 0xac800000, 0x800185f,
-0x0, 0x8ee24e30, 0x24420001, 0x50470003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0xac880000, 0xac8a0004, 0x56000006, 0x240b0001,
-0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6,
-0x0, 0x316300ff, 0x24020001, 0x14620003,
-0x3c050009, 0x800197c, 0x24100001, 0x3c040001,
-0x248452a4, 0xafa00010, 0xafa00014, 0x8f860120,
-0x8f870124, 0x800187b, 0x34a5f011, 0x3c040001,
-0x248452b0, 0xafa00010, 0xafa00014, 0x8f860120,
-0x8f870124, 0x34a5f010, 0xc002403, 0x8021,
-0x800197c, 0x0, 0x3c040001, 0x248452bc,
-0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
-0x8001975, 0x34a5f00f, 0x8ee20608, 0x8f430228,
-0x24420001, 0x304900ff, 0x512300e2, 0xafa00010,
-0x8ee20608, 0x210c0, 0x571021, 0x8fa30018,
-0x8fa4001c, 0xac43060c, 0xac440610, 0x8f870120,
-0x27623800, 0x24e80020, 0x102102b, 0x50400001,
-0x27683000, 0x8f820128, 0x11020004, 0x0,
-0x8f820124, 0x15020007, 0x1021, 0x8ee201a4,
-0x8021, 0x24420001, 0xaee201a4, 0x80018f7,
-0x8ee201a4, 0x8ee40608, 0x420c0, 0x801821,
-0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0xace40000, 0xace50004,
-0x8ee30608, 0x24020008, 0xa4e2000e, 0x2402000d,
-0xace20018, 0xace9001c, 0x318c0, 0x2463060c,
-0x2e31021, 0xace20008, 0x8ee204c4, 0xace20010,
-0xaf880120, 0x92e24e20, 0x14400037, 0x24100001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c830000, 0x24020007, 0x1462001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x24030040,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee54e30, 0x24420001, 0x10430007, 0x0,
-0x8ee24e34, 0x24420001, 0x10a20005, 0x0,
-0x80018e1, 0x0, 0x14a00005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x80018f7, 0x0, 0x8ee24e30, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020007, 0xac820000,
-0x24020001, 0xac820004, 0x5600000c, 0xaee90608,
-0x3c040001, 0x248452c8, 0xafa00010, 0xafa00014,
-0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
-0x34a5f000, 0x800197c, 0x0, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20007, 0x0, 0x8ee201a4,
-0x8021, 0x24420001, 0xaee201a4, 0x800195e,
-0x8ee201a4, 0x8ee20608, 0xac62001c, 0x8ee404a0,
-0x8ee504a4, 0x2462001c, 0xac620008, 0x24020008,
-0xa462000e, 0x24020011, 0xac620018, 0xac640000,
-0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120,
-0x92e24e20, 0x14400037, 0x24100001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c830000,
-0x24020012, 0x1462001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30,
-0x24420001, 0x10430007, 0x0, 0x8ee24e34,
-0x24420001, 0x10a20005, 0x0, 0x8001948,
-0x0, 0x14a00005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x800195e,
-0x0, 0x8ee24e30, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x24020012, 0xac820000, 0x24020001,
-0xac820004, 0x5600001d, 0x24100001, 0x3c040001,
-0x248452d0, 0xafa00010, 0xafa00014, 0x8ee60608,
-0x8f470228, 0x3c050009, 0xc002403, 0x34a5f001,
-0x8ee201b0, 0x24420001, 0xaee201b0, 0x800197c,
-0x8ee201b0, 0x3c040001, 0x248452dc, 0xafa00014,
-0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f005,
-0xc002403, 0x0, 0x8ee201ac, 0x8021,
-0x24420001, 0xaee201ac, 0x8ee201ac, 0x1200000c,
-0x24020001, 0x3c010001, 0x370821, 0xa02083b0,
-0x8f420238, 0x8ee30158, 0x24630001, 0xaee30158,
-0x8ee30158, 0x800198c, 0xaee27278, 0x24020001,
-0x3c010001, 0x370821, 0xa02283b0, 0x3c020001,
-0x8c425cd8, 0x10400187, 0x0, 0x8ee27b84,
-0x24430001, 0x284200c9, 0x144001a4, 0xaee37b84,
-0x8ee204d4, 0x30420002, 0x14400119, 0xaee07b84,
-0x8ee204d4, 0x3c030600, 0x34631000, 0x34420002,
-0xaee204d4, 0xafa30018, 0x8ee20608, 0x8f430228,
-0x24420001, 0x304a00ff, 0x514300fd, 0xafa00010,
-0x8ee20608, 0x210c0, 0x571021, 0x8fa30018,
-0x8fa4001c, 0xac43060c, 0xac440610, 0x8f830054,
-0x8f820054, 0x24690032, 0x1221023, 0x2c420033,
-0x1040006a, 0x5821, 0x24180008, 0x240f000d,
-0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120,
-0x27623800, 0x24e80020, 0x102102b, 0x50400001,
-0x27683000, 0x8f820128, 0x11020004, 0x0,
-0x8f820124, 0x15020007, 0x1021, 0x8ee201a4,
-0x8021, 0x24420001, 0xaee201a4, 0x8001a15,
-0x8ee201a4, 0x8ee40608, 0x420c0, 0x801821,
-0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0xace40000, 0xace50004,
-0x8ee20608, 0xa4f8000e, 0xacef0018, 0xacea001c,
-0x210c0, 0x2442060c, 0x2e21021, 0xace20008,
-0x8ee204c4, 0xace20010, 0xaf880120, 0x92e24e20,
-0x14400033, 0x24100001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c820000, 0x144d001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x0, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee34e30, 0x24420001, 0x104c0007,
-0x0, 0x8ee24e34, 0x24420001, 0x10620005,
-0x0, 0x8001a02, 0x0, 0x14600005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
-0xac800000, 0x8001a15, 0x0, 0x8ee24e30,
-0x24420001, 0x504c0003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0xac8d0000, 0xac8e0004,
-0x56000006, 0x240b0001, 0x8f820054, 0x1221023,
-0x2c420033, 0x1440ff9d, 0x0, 0x316300ff,
-0x24020001, 0x54620078, 0xafa00010, 0xaeea0608,
-0x8f830054, 0x8f820054, 0x24690032, 0x1221023,
-0x2c420033, 0x10400061, 0x5821, 0x240d0008,
-0x240c0011, 0x24080012, 0x24070040, 0x240a0001,
-0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
-0x50400001, 0x27663000, 0x8f820128, 0x10c20004,
-0x0, 0x8f820124, 0x14c20007, 0x0,
-0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4,
-0x8001a81, 0x8ee201a4, 0x8ee20608, 0xac62001c,
-0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008,
-0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004,
-0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20,
-0x14400033, 0x24100001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c820000, 0x1448001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x0, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10470007,
-0x0, 0x8ee24e34, 0x24420001, 0x10620005,
-0x0, 0x8001a6e, 0x0, 0x14600005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
-0xac800000, 0x8001a81, 0x0, 0x8ee24e30,
-0x24420001, 0x50470003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0xac880000, 0xac8a0004,
-0x56000006, 0x240b0001, 0x8f820054, 0x1221023,
-0x2c420033, 0x1440ffa6, 0x0, 0x316300ff,
-0x24020001, 0x10620022, 0x0, 0x3c040001,
-0x248452a4, 0xafa00010, 0xafa00014, 0x8f860120,
-0x8f870124, 0x3c050009, 0xc002403, 0x34a5f011,
-0x8001aad, 0x0, 0x3c040001, 0x248452b0,
-0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009,
-0xc002403, 0x34a5f010, 0x8001aad, 0x0,
-0x3c040001, 0x248452bc, 0xafa00014, 0x8ee60608,
-0x8f470228, 0x3c050009, 0xc002403, 0x34a5f00f,
-0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac,
-0x8ee2015c, 0x24420001, 0xaee2015c, 0x8ee2015c,
-0x8ee204d4, 0x30420001, 0x10400055, 0x0,
-0x8f420218, 0x30420080, 0x10400029, 0x0,
-0x8f820044, 0x34420040, 0xaf820044, 0x8ee27b7c,
-0x402821, 0x8ee200c0, 0x8ee300c4, 0x24060000,
-0x2407ffff, 0x2021, 0x461024, 0x1444000d,
-0x671824, 0x1465000b, 0x0, 0x8ee27b80,
-0x402821, 0x8ee200e0, 0x8ee300e4, 0x2021,
-0x461024, 0x14440003, 0x671824, 0x1065000b,
-0x0, 0x8ee200c0, 0x8ee300c4, 0x8ee400e0,
-0x8ee500e4, 0xaee37b7c, 0xaee57b80, 0x8f820044,
-0x38420020, 0x8001b38, 0xaf820044, 0x8f820044,
-0x2403ffdf, 0x431024, 0x8001b38, 0xaf820044,
-0x8f820044, 0x2403ffdf, 0x431024, 0xaf820044,
-0x8ee27b7c, 0x402821, 0x8ee200c0, 0x8ee300c4,
-0x24060000, 0x2407ffff, 0x2021, 0x461024,
-0x1444000d, 0x671824, 0x1465000b, 0x0,
-0x8ee27b80, 0x402821, 0x8ee200e0, 0x8ee300e4,
-0x2021, 0x461024, 0x14440003, 0x671824,
-0x1065000b, 0x0, 0x8ee200c0, 0x8ee300c4,
-0x8ee400e0, 0x8ee500e4, 0xaee37b7c, 0xaee57b80,
-0x8f820044, 0x38420040, 0x8001b38, 0xaf820044,
-0x8f820044, 0x34420040, 0x8001b38, 0xaf820044,
-0x8f820044, 0x34420040, 0xaf820044, 0x8ee27b8c,
-0x24430001, 0x28420015, 0x14400028, 0xaee37b8c,
-0x8f820044, 0x38420020, 0xaf820044, 0x8001b38,
-0xaee07b8c, 0x8ee204d4, 0x30420001, 0x10400011,
-0x0, 0x8f420218, 0x30420080, 0x10400009,
-0x0, 0x8f820044, 0x34420020, 0xaf820044,
-0x8f820044, 0x2403ffbf, 0x431024, 0x8001b36,
-0xaf820044, 0x8f820044, 0x34420060, 0x8001b36,
-0xaf820044, 0x8f820044, 0x34420040, 0xaf820044,
-0x8ee27b88, 0x24430001, 0x28421389, 0x14400005,
-0xaee37b88, 0x8f820044, 0x38420020, 0xaf820044,
-0xaee07b88, 0xc004603, 0x0, 0x8fbf0024,
-0x8fb00020, 0x3e00008, 0x27bd0028, 0x27bdffb8,
-0xafbf0044, 0xafb60040, 0xafb5003c, 0xafb40038,
-0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028,
-0x8f960064, 0x32c20004, 0x1040000c, 0x24020004,
-0xaf820064, 0x8f420114, 0xaee204e0, 0x8f820060,
-0x34420008, 0xaf820060, 0x8ee2016c, 0x24420001,
-0xaee2016c, 0x80022f4, 0x8ee2016c, 0x32c20001,
-0x10400004, 0x24020001, 0xaf820064, 0x80022f4,
-0x0, 0x32c20002, 0x1440000c, 0x3c050003,
-0x3c040001, 0x24845354, 0x34a50001, 0x2c03021,
-0x3821, 0xafa00010, 0xc002403, 0xafa00014,
-0x2402fff8, 0x80022f4, 0xaf820064, 0x8f43022c,
-0x8f42010c, 0x5062000c, 0xafa00010, 0x8f42022c,
-0x21080, 0x5a1021, 0x8c420300, 0xafa20020,
-0x8f42022c, 0x24070001, 0x24420001, 0x3042003f,
-0x8001b80, 0xaf42022c, 0x3c040001, 0x24845360,
-0xafa00014, 0x8f46022c, 0x8f47010c, 0x3c050003,
-0xc002403, 0x34a5f01f, 0x3821, 0x14e00003,
-0x0, 0x80022ed, 0xaf960064, 0x93a20020,
-0x2443ffff, 0x2c620011, 0x10400658, 0x31080,
-0x3c010001, 0x220821, 0x8c225418, 0x400008,
-0x0, 0x8fa20020, 0x30420fff, 0xaee20e0c,
-0x8f820060, 0x34420200, 0xaf820060, 0x8ee20118,
-0x24420001, 0xaee20118, 0x80022e8, 0x8ee20118,
-0x8fa20020, 0x24030001, 0x3c010001, 0x370821,
-0xa02383b1, 0x30420fff, 0xaee25238, 0x8f820060,
-0x34420100, 0xaf820060, 0x8ee20144, 0x24420001,
-0xaee20144, 0x80022e8, 0x8ee20144, 0x8fa20020,
-0x21200, 0x22502, 0x24020001, 0x10820005,
-0x24020002, 0x10820009, 0x2402fffe, 0x8001bc9,
-0xafa00010, 0x8ee204d4, 0xaee40070, 0xaee40074,
-0x34420001, 0x8001bbd, 0xaee204d4, 0x8ee304d4,
-0xaee40070, 0xaee40074, 0x621824, 0xaee304d4,
-0x8f840054, 0x41442, 0x41c82, 0x431021,
-0x41cc2, 0x431023, 0x41d02, 0x431021,
-0x41d42, 0x431023, 0x8001bd0, 0xaee20078,
-0x3c040001, 0x2484536c, 0xafa00014, 0x8fa60020,
-0x3c050003, 0xc002403, 0x34a50004, 0x8ee20110,
-0x24420001, 0xaee20110, 0x80022e8, 0x8ee20110,
-0x27440212, 0xc0022fe, 0x24050006, 0x3049001f,
-0x920c0, 0x2e41021, 0x9442727c, 0x30424000,
-0x1040000a, 0x971021, 0x97430212, 0xa443727e,
-0x8f430214, 0x971021, 0xac437280, 0x2e41821,
-0x34028000, 0x8001c79, 0xa462727c, 0x9443727e,
-0x97420212, 0x14620006, 0x2e41021, 0x971021,
-0x8c437280, 0x8f420214, 0x1062009f, 0x2e41021,
-0x9442727c, 0x30428000, 0x1040002a, 0x2406ffff,
-0x2021, 0x410c0, 0x2e21021, 0x9442737c,
-0x30424000, 0x54400005, 0x803021, 0x24840001,
-0x2c820080, 0x1440fff8, 0x410c0, 0x4c10010,
-0x618c0, 0x610c0, 0x571821, 0x8c63737c,
-0x571021, 0xafa30010, 0x8c427380, 0x3c040001,
-0x24845378, 0xafa20014, 0x8f470214, 0x3c050003,
-0xc002403, 0x34a50013, 0x8001c90, 0x3c020800,
-0x97440212, 0x771021, 0xa444737e, 0x8f440214,
-0x771021, 0x2e31821, 0xac447380, 0x34028000,
-0xa462737c, 0x910c0, 0x2e21021, 0x8001c79,
-0xa446727c, 0x2e41021, 0x9445727c, 0x8001c2e,
-0x510c0, 0x9443737e, 0x97420212, 0x14620006,
-0x510c0, 0x971021, 0x8c437380, 0x8f420214,
-0x10620065, 0x510c0, 0x2e21021, 0x9445737c,
-0x510c0, 0x2e21021, 0x9442737c, 0x30428000,
-0x1040fff0, 0x971021, 0x520c0, 0x971021,
-0x9443737e, 0x97420212, 0x14620006, 0x2406ffff,
-0x971021, 0x8c437380, 0x8f420214, 0x10620053,
-0x3c020800, 0x2021, 0x410c0, 0x2e21021,
-0x9442737c, 0x30424000, 0x54400005, 0x803021,
-0x24840001, 0x2c820080, 0x1440fff8, 0x410c0,
-0x4c10023, 0x618c0, 0x910c0, 0x571821,
-0x8c63727c, 0x571021, 0xafa30010, 0x8c427280,
-0x3c040001, 0x24845384, 0xafa20014, 0x8f470214,
-0x3c050003, 0xc002403, 0x34a5f017, 0x8001c90,
-0x3c020800, 0x8f430210, 0xb71021, 0xac43777c,
-0x8f430214, 0xb71021, 0xac437780, 0x3c020001,
-0x571021, 0x8c4283b4, 0x24420001, 0x3c010001,
-0x370821, 0xac2283b4, 0x3c030001, 0x771821,
-0x8c6383b4, 0x2e51021, 0x8001c82, 0xa443777c,
-0x97440212, 0x771021, 0xa444737e, 0x8f440214,
-0x771021, 0x2e31821, 0xac447380, 0x34028000,
-0xa462737c, 0x510c0, 0x2e21021, 0xa446737c,
-0x2021, 0x428c0, 0x2e51021, 0x9442777c,
-0x1040ffdc, 0x24840001, 0x2c820080, 0x5440fffa,
-0x428c0, 0x92e204d8, 0x10400006, 0x24020001,
-0x8ee304dc, 0x1221004, 0x621825, 0x8001c8f,
-0xaee304dc, 0x8f830228, 0x24020001, 0x1221004,
-0x621825, 0xaf830228, 0x3c020800, 0x34421000,
-0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001,
-0x304a00ff, 0x514300fd, 0xafa00010, 0x8ee20608,
-0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c,
-0xac43060c, 0xac440610, 0x8f830054, 0x8f820054,
-0x24690032, 0x1221023, 0x2c420033, 0x1040006a,
-0x5821, 0x24100008, 0x240f000d, 0x240d0007,
-0x240c0040, 0x240e0001, 0x8f870120, 0x27623800,
-0x24e80020, 0x102102b, 0x50400001, 0x27683000,
-0x8f820128, 0x11020004, 0x0, 0x8f820124,
-0x15020007, 0x1021, 0x8ee201a4, 0x3821,
-0x24420001, 0xaee201a4, 0x8001d08, 0x8ee201a4,
-0x8ee40608, 0x420c0, 0x801821, 0x8ee40430,
-0x8ee50434, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xace40000, 0xace50004, 0x8ee20608,
-0xa4f0000e, 0xacef0018, 0xacea001c, 0x210c0,
-0x2442060c, 0x2e21021, 0xace20008, 0x8ee204c4,
-0xace20010, 0xaf880120, 0x92e24e20, 0x14400033,
-0x24070001, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c820000, 0x144d001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee34e30, 0x24420001, 0x104c0007, 0x0,
-0x8ee24e34, 0x24420001, 0x10620005, 0x0,
-0x8001cf5, 0x0, 0x14600005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
-0x8001d08, 0x0, 0x8ee24e30, 0x24420001,
-0x504c0003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0xac8d0000, 0xac8e0004, 0x54e00006,
-0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
-0x1440ff9d, 0x0, 0x316300ff, 0x24020001,
-0x54620078, 0xafa00010, 0xaeea0608, 0x8f830054,
-0x8f820054, 0x24690032, 0x1221023, 0x2c420033,
-0x10400061, 0x5821, 0x240e0008, 0x240d0011,
-0x240a0012, 0x24080040, 0x240c0001, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20007, 0x0, 0x8ee201a4,
-0x3821, 0x24420001, 0xaee201a4, 0x8001d74,
-0x8ee201a4, 0x8ee20608, 0xac62001c, 0x8ee404a0,
-0x8ee504a4, 0x2462001c, 0xac620008, 0xa46e000e,
-0xac6d0018, 0xac640000, 0xac650004, 0x8ee204c4,
-0xac620010, 0xaf860120, 0x92e24e20, 0x14400033,
-0x24070001, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c820000, 0x144a001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee34e30, 0x24420001, 0x10480007, 0x0,
-0x8ee24e34, 0x24420001, 0x10620005, 0x0,
-0x8001d61, 0x0, 0x14600005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
-0x8001d74, 0x0, 0x8ee24e30, 0x24420001,
-0x50480003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006,
-0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
-0x1440ffa6, 0x0, 0x316300ff, 0x24020001,
-0x10620022, 0x0, 0x3c040001, 0x24845390,
-0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
-0x3c050009, 0xc002403, 0x34a5f011, 0x8001da0,
-0x0, 0x3c040001, 0x2484539c, 0xafa00014,
-0x8f860120, 0x8f870124, 0x3c050009, 0xc002403,
-0x34a5f010, 0x8001da0, 0x0, 0x3c040001,
-0x248453a8, 0xafa00014, 0x8ee60608, 0x8f470228,
-0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac,
-0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20124,
-0x24420001, 0xaee20124, 0x8001f97, 0x8ee20124,
-0x27440212, 0xc0022fe, 0x24050006, 0x3049001f,
-0x928c0, 0x2e51021, 0x9442727c, 0x30428000,
-0x1040002f, 0x2e51021, 0x9442727c, 0x30424000,
-0x1440001c, 0xb71021, 0x9443727e, 0x97420212,
-0x14620018, 0xb71021, 0x8c437280, 0x8f420214,
-0x54620016, 0xafa20010, 0x92e204d8, 0x10400007,
-0x24020001, 0x8ee304dc, 0x1221004, 0x21027,
-0x621824, 0x8001dc9, 0xaee304dc, 0x8f830228,
-0x1221004, 0x21027, 0x621824, 0xaf830228,
-0x910c0, 0x2e21821, 0x3402c000, 0x8001e4e,
-0xa462727c, 0x8f420214, 0xafa20010, 0x910c0,
-0x571021, 0x8c42727c, 0x3c040001, 0x248453b4,
-0x3c050003, 0xafa20014, 0x8f470210, 0x34a5f01c,
-0xc002403, 0x1203021, 0x8001e83, 0x3c020800,
-0xb71021, 0x9443727e, 0x97420212, 0x14620019,
-0x918c0, 0xb71021, 0x8c437280, 0x8f420214,
-0x14620014, 0x918c0, 0x2e51021, 0x9447727c,
-0x720c0, 0x971021, 0x9443737e, 0xb71021,
-0xa443727e, 0x971021, 0x8c437380, 0xb71021,
-0xac437280, 0x2e41021, 0x9443737c, 0x2e51021,
-0xa443727c, 0x2e41821, 0x3402c000, 0x8001e4e,
-0xa462737c, 0x2e31021, 0x9447727c, 0x3021,
-0x720c0, 0x2e41021, 0x9442737c, 0x4021,
-0x30428000, 0x14400025, 0xe02821, 0x605021,
-0x340bc000, 0x971021, 0x9443737e, 0x97420212,
-0x54620015, 0xe02821, 0x971021, 0x8c437380,
-0x8f420214, 0x54620010, 0xe02821, 0x11000006,
-0x2e41021, 0x9443737c, 0x510c0, 0x2e21021,
-0x8001e1a, 0xa443737c, 0x9443737c, 0x2ea1021,
-0xa443727c, 0x710c0, 0x2e21021, 0xa44b737c,
-0x8001e28, 0x24060001, 0x510c0, 0x2e21021,
-0x9447737c, 0x720c0, 0x2e41021, 0x9442737c,
-0x30428000, 0x1040ffdf, 0x25080001, 0x30c200ff,
-0x14400025, 0x2021, 0x720c0, 0x971021,
-0x9443737e, 0x97420212, 0x1462000f, 0x910c0,
-0x971021, 0x8c437380, 0x8f420214, 0x1462000a,
-0x910c0, 0x2e41821, 0x3402c000, 0x15000015,
-0xa462737c, 0x910c0, 0x2e21821, 0x34028000,
-0x8001e4e, 0xa462727c, 0x571021, 0x8c42727c,
-0x3c040001, 0x248453c0, 0x3c050003, 0xafa20010,
-0x710c0, 0x571021, 0x8c42737c, 0x34a5001e,
-0x1203021, 0xc002403, 0xafa20014, 0x8001e83,
-0x3c020800, 0x2021, 0x428c0, 0xb71021,
-0x9443777e, 0x97420212, 0x5462002b, 0x24840001,
-0xb71021, 0x8c437780, 0x8f420214, 0x54620026,
-0x24840001, 0x3c020001, 0x571021, 0x8c4283b4,
-0x2442ffff, 0x3c010001, 0x370821, 0xac2283b4,
-0x3c020001, 0x571021, 0x8c4283b4, 0x809021,
-0x242102b, 0x1040000e, 0x24b1777c, 0x24b07784,
-0x2f02021, 0x2f12821, 0xc002490, 0x24060008,
-0x26310008, 0x3c020001, 0x571021, 0x8c4283b4,
-0x26520001, 0x242102b, 0x1440fff5, 0x26100008,
-0x3c040001, 0x972021, 0x8c8483b4, 0x24050008,
-0x420c0, 0x2484777c, 0xc002488, 0x2e42021,
-0x8001e83, 0x3c020800, 0x2c820080, 0x1440ffcf,
-0x428c0, 0x3c020800, 0x34422000, 0xafa20018,
-0x8ee20608, 0x8f430228, 0x24420001, 0x304a00ff,
-0x514300fd, 0xafa00010, 0x8ee20608, 0x210c0,
-0x571021, 0x8fa30018, 0x8fa4001c, 0xac43060c,
-0xac440610, 0x8f830054, 0x8f820054, 0x24690032,
-0x1221023, 0x2c420033, 0x1040006a, 0x5821,
-0x24100008, 0x240f000d, 0x240d0007, 0x240c0040,
-0x240e0001, 0x8f870120, 0x27623800, 0x24e80020,
-0x102102b, 0x50400001, 0x27683000, 0x8f820128,
-0x11020004, 0x0, 0x8f820124, 0x15020007,
-0x1021, 0x8ee201a4, 0x3821, 0x24420001,
-0xaee201a4, 0x8001efb, 0x8ee201a4, 0x8ee40608,
-0x420c0, 0x801821, 0x8ee40430, 0x8ee50434,
-0xa32821, 0xa3302b, 0x822021, 0x862021,
-0xace40000, 0xace50004, 0x8ee20608, 0xa4f0000e,
-0xacef0018, 0xacea001c, 0x210c0, 0x2442060c,
-0x2e21021, 0xace20008, 0x8ee204c4, 0xace20010,
-0xaf880120, 0x92e24e20, 0x14400033, 0x24070001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c820000, 0x144d001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x104c0007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x8001ee8,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400010, 0xac800000, 0x8001efb,
-0x0, 0x8ee24e30, 0x24420001, 0x504c0003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0xac8d0000, 0xac8e0004, 0x54e00006, 0x240b0001,
-0x8f820054, 0x1221023, 0x2c420033, 0x1440ff9d,
-0x0, 0x316300ff, 0x24020001, 0x54620078,
-0xafa00010, 0xaeea0608, 0x8f830054, 0x8f820054,
-0x24690032, 0x1221023, 0x2c420033, 0x10400061,
-0x5821, 0x240e0008, 0x240d0011, 0x240a0012,
-0x24080040, 0x240c0001, 0x8f830120, 0x27623800,
-0x24660020, 0xc2102b, 0x50400001, 0x27663000,
-0x8f820128, 0x10c20004, 0x0, 0x8f820124,
-0x14c20007, 0x0, 0x8ee201a4, 0x3821,
-0x24420001, 0xaee201a4, 0x8001f67, 0x8ee201a4,
-0x8ee20608, 0xac62001c, 0x8ee404a0, 0x8ee504a4,
-0x2462001c, 0xac620008, 0xa46e000e, 0xac6d0018,
-0xac640000, 0xac650004, 0x8ee204c4, 0xac620010,
-0xaf860120, 0x92e24e20, 0x14400033, 0x24070001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c820000, 0x144a001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x10480007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x8001f54,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400010, 0xac800000, 0x8001f67,
-0x0, 0x8ee24e30, 0x24420001, 0x50480003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0xac8a0000, 0xac8c0004, 0x54e00006, 0x240b0001,
-0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6,
-0x0, 0x316300ff, 0x24020001, 0x10620022,
-0x0, 0x3c040001, 0x24845390, 0xafa00010,
-0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009,
-0xc002403, 0x34a5f011, 0x8001f93, 0x0,
-0x3c040001, 0x2484539c, 0xafa00014, 0x8f860120,
-0x8f870124, 0x3c050009, 0xc002403, 0x34a5f010,
-0x8001f93, 0x0, 0x3c040001, 0x248453a8,
-0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
-0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001,
-0xaee201ac, 0x8ee201ac, 0x8ee20128, 0x24420001,
-0xaee20128, 0x8ee20128, 0x8ee20164, 0x24420001,
-0xaee20164, 0x80022e8, 0x8ee20164, 0x8fa20020,
-0x21200, 0x21d02, 0x24020001, 0x10620005,
-0x24020002, 0x1062000d, 0x0, 0x8001fb7,
-0xafa00010, 0x92e204d8, 0x14400006, 0x24020001,
-0x8f820228, 0xaee204dc, 0x2402ffff, 0xaf820228,
-0x24020001, 0x8001fbe, 0xa2e204d8, 0x92e204d8,
-0x5040000c, 0xa2e004d8, 0x8ee204dc, 0xaf820228,
-0x8001fbe, 0xa2e004d8, 0x3c040001, 0x248453c8,
-0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403,
-0x34a5f009, 0x8ee2013c, 0x24420001, 0xaee2013c,
-0x80022e8, 0x8ee2013c, 0x8fa20020, 0x21200,
-0x22502, 0x24020001, 0x10820005, 0x24020002,
-0x1082000f, 0x0, 0x8001fe3, 0xafa00010,
-0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024,
-0x34420008, 0xaf820220, 0x24020001, 0x3c010001,
-0x370821, 0xa02283b2, 0x8001fea, 0xaee40108,
-0x8f820220, 0x3c0308ff, 0x3463fff7, 0x431024,
-0xaf820220, 0x3c010001, 0x370821, 0xa02083b2,
-0x8001fea, 0xaee40108, 0x3c040001, 0x248453d4,
-0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403,
-0x34a5f00a, 0x8ee2012c, 0x24420001, 0xaee2012c,
-0x80022e8, 0x8ee2012c, 0x8fa20020, 0x21200,
-0x21d02, 0x24020001, 0x10620005, 0x24020002,
-0x1062000e, 0x0, 0x8002011, 0xafa00010,
-0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024,
-0x34420008, 0xaf820220, 0x24020001, 0x3c010001,
-0x370821, 0x8002018, 0xa02283b3, 0x3c020001,
-0x571021, 0x904283b2, 0x3c010001, 0x370821,
-0x1440000e, 0xa02083b3, 0x8f820220, 0x3c0308ff,
-0x3463fff7, 0x431024, 0x8002018, 0xaf820220,
-0x3c040001, 0x248453e0, 0xafa00014, 0x8fa60020,
-0x3c050003, 0xc002403, 0x34a5f00b, 0x8ee20114,
-0x24420001, 0xaee20114, 0x80022e8, 0x8ee20114,
-0x27840208, 0x27450200, 0xc00249a, 0x24060008,
-0x26e40094, 0x27450200, 0xc00249a, 0x24060008,
-0x8ee20134, 0x24420001, 0xaee20134, 0x80022e8,
-0x8ee20134, 0x8f460248, 0x2021, 0xc005108,
-0x24050004, 0x8ee20130, 0x24420001, 0xaee20130,
-0x80022e8, 0x8ee20130, 0x8ef301cc, 0x8ef401d0,
-0x8ef501d8, 0x8ee20140, 0x26e40030, 0x24420001,
-0xaee20140, 0x8ef00140, 0x8ef10074, 0x8ef20070,
-0xc002488, 0x24050400, 0xaef301cc, 0xaef401d0,
-0xaef501d8, 0xaef00140, 0xaef10074, 0xaef20070,
-0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260,
-0x27450200, 0x24060008, 0xaee20068, 0x24020006,
-0xc00249a, 0xaee20064, 0x3c023b9a, 0x3442ca00,
-0xaee2006c, 0x240203e8, 0x24040002, 0x24030001,
-0xaee20104, 0xaee40100, 0xaee3010c, 0x8f820220,
-0x30420008, 0x10400004, 0x0, 0xaee30108,
-0x8002061, 0x2021, 0xaee40108, 0x2021,
-0x3c030001, 0x641821, 0x90635c30, 0x2e41021,
-0x24840001, 0xa043009c, 0x2c82000f, 0x1440fff8,
-0x0, 0x8f820040, 0x2e41821, 0x24840001,
-0x21702, 0x24420030, 0xa062009c, 0x2e41021,
-0x80022e8, 0xa040009c, 0x24020001, 0x3c010001,
-0x370821, 0xa02283e0, 0x240b0400, 0x24080014,
-0x240a0040, 0x24090001, 0x8f830100, 0x27623000,
-0x24660020, 0xc2102b, 0x50400001, 0x27662800,
-0x8f820108, 0x10c20004, 0x0, 0x8f820104,
-0x14c20007, 0x26e20030, 0x8ee201a8, 0x3821,
-0x24420001, 0xaee201a8, 0x80020a8, 0x8ee201a8,
-0x8ee404b8, 0x8ee504bc, 0xac620008, 0xa46b000e,
-0xac680018, 0xac60001c, 0xac640000, 0xac650004,
-0x8ee204cc, 0xac620010, 0xaf860100, 0x92e204ec,
-0x1440000e, 0x24070001, 0x8ee24e28, 0x24420001,
-0x504a0003, 0x1021, 0x8ee24e28, 0x24420001,
-0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
-0x2e21021, 0xac480000, 0xac490004, 0x10e0ffd2,
-0x0, 0x80022e8, 0x0, 0x3c020900,
-0xaee05238, 0xaee0523c, 0xaee05240, 0xaee05244,
-0xaee001d0, 0x3c010001, 0x370821, 0xa02083b1,
-0xafa20018, 0x8ee20608, 0x8f430228, 0x24420001,
-0x304a00ff, 0x514300fd, 0xafa00010, 0x8ee20608,
-0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c,
-0xac43060c, 0xac440610, 0x8f830054, 0x8f820054,
-0x24690032, 0x1221023, 0x2c420033, 0x1040006a,
-0x5821, 0x24100008, 0x240f000d, 0x240d0007,
-0x240c0040, 0x240e0001, 0x8f870120, 0x27623800,
-0x24e80020, 0x102102b, 0x50400001, 0x27683000,
-0x8f820128, 0x11020004, 0x0, 0x8f820124,
-0x15020007, 0x1021, 0x8ee201a4, 0x3821,
-0x24420001, 0xaee201a4, 0x800212c, 0x8ee201a4,
-0x8ee40608, 0x420c0, 0x801821, 0x8ee40430,
-0x8ee50434, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xace40000, 0xace50004, 0x8ee20608,
-0xa4f0000e, 0xacef0018, 0xacea001c, 0x210c0,
-0x2442060c, 0x2e21021, 0xace20008, 0x8ee204c4,
-0xace20010, 0xaf880120, 0x92e24e20, 0x14400033,
-0x24070001, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c820000, 0x144d001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee34e30, 0x24420001, 0x104c0007, 0x0,
-0x8ee24e34, 0x24420001, 0x10620005, 0x0,
-0x8002119, 0x0, 0x14600005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
-0x800212c, 0x0, 0x8ee24e30, 0x24420001,
-0x504c0003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0xac8d0000, 0xac8e0004, 0x54e00006,
-0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
-0x1440ff9d, 0x0, 0x316300ff, 0x24020001,
-0x54620078, 0xafa00010, 0xaeea0608, 0x8f830054,
-0x8f820054, 0x24690032, 0x1221023, 0x2c420033,
-0x10400061, 0x5821, 0x240e0008, 0x240d0011,
-0x240a0012, 0x24080040, 0x240c0001, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20007, 0x0, 0x8ee201a4,
-0x3821, 0x24420001, 0xaee201a4, 0x8002198,
-0x8ee201a4, 0x8ee20608, 0xac62001c, 0x8ee404a0,
-0x8ee504a4, 0x2462001c, 0xac620008, 0xa46e000e,
-0xac6d0018, 0xac640000, 0xac650004, 0x8ee204c4,
-0xac620010, 0xaf860120, 0x92e24e20, 0x14400033,
-0x24070001, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c820000, 0x144a001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee34e30, 0x24420001, 0x10480007, 0x0,
-0x8ee24e34, 0x24420001, 0x10620005, 0x0,
-0x8002185, 0x0, 0x14600005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
-0x8002198, 0x0, 0x8ee24e30, 0x24420001,
-0x50480003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006,
-0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
-0x1440ffa6, 0x0, 0x316300ff, 0x24020001,
-0x10620022, 0x0, 0x3c040001, 0x24845390,
-0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
-0x3c050009, 0xc002403, 0x34a5f011, 0x80021c4,
-0x0, 0x3c040001, 0x2484539c, 0xafa00014,
-0x8f860120, 0x8f870124, 0x3c050009, 0xc002403,
-0x34a5f010, 0x80021c4, 0x0, 0x3c040001,
-0x248453a8, 0xafa00014, 0x8ee60608, 0x8f470228,
-0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac,
-0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20120,
-0x24420001, 0xaee20120, 0x8ee20120, 0x8ee20168,
-0x24420001, 0xaee20168, 0x80022e8, 0x8ee20168,
-0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260,
-0x27450200, 0x24060008, 0xc00249a, 0xaee20068,
-0x8f820220, 0x30420008, 0x14400002, 0x24020001,
-0x24020002, 0xaee20108, 0x8ee2011c, 0x24420001,
-0xaee2011c, 0x80022e8, 0x8ee2011c, 0x3c040001,
-0x248453ec, 0xafa00010, 0xafa00014, 0x8fa60020,
-0x3c050003, 0xc002403, 0x34a5f00f, 0x93a20020,
-0x3c030700, 0x34631000, 0x431025, 0xafa20018,
-0x8ee20608, 0x8f430228, 0x24420001, 0x304900ff,
-0x512300e2, 0xafa00010, 0x8ee20608, 0x210c0,
-0x571021, 0x8fa30018, 0x8fa4001c, 0xac43060c,
-0xac440610, 0x8f870120, 0x27623800, 0x24e80020,
-0x102102b, 0x50400001, 0x27683000, 0x8f820128,
-0x11020004, 0x0, 0x8f820124, 0x15020007,
-0x1021, 0x8ee201a4, 0x3821, 0x24420001,
-0xaee201a4, 0x800225d, 0x8ee201a4, 0x8ee40608,
-0x420c0, 0x801821, 0x8ee40430, 0x8ee50434,
-0xa32821, 0xa3302b, 0x822021, 0x862021,
-0xace40000, 0xace50004, 0x8ee30608, 0x24020008,
-0xa4e2000e, 0x2402000d, 0xace20018, 0xace9001c,
-0x318c0, 0x2463060c, 0x2e31021, 0xace20008,
-0x8ee204c4, 0xace20010, 0xaf880120, 0x92e24e20,
-0x14400037, 0x24070001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c830000, 0x24020007,
-0x1462001f, 0x0, 0x8ee34e30, 0x8ee24e34,
-0x1062001b, 0x24030040, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e34, 0x8ee54e30, 0x24420001,
-0x10430007, 0x0, 0x8ee24e34, 0x24420001,
-0x10a20005, 0x0, 0x8002247, 0x0,
-0x14a00005, 0x0, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
-0x50400013, 0xac800000, 0x800225d, 0x0,
-0x8ee24e30, 0x24030040, 0x24420001, 0x50430003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x24020007, 0xac820000, 0x24020001, 0xac820004,
-0x54e0000c, 0xaee90608, 0x3c040001, 0x248453f4,
-0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228,
-0x3c050009, 0xc002403, 0x34a5f000, 0x80022e0,
-0x0, 0x8f830120, 0x27623800, 0x24660020,
-0xc2102b, 0x50400001, 0x27663000, 0x8f820128,
-0x10c20004, 0x0, 0x8f820124, 0x14c20007,
-0x0, 0x8ee201a4, 0x3821, 0x24420001,
-0xaee201a4, 0x80022c4, 0x8ee201a4, 0x8ee20608,
-0xac62001c, 0x8ee404a0, 0x8ee504a4, 0x2462001c,
-0xac620008, 0x24020008, 0xa462000e, 0x24020011,
-0xac620018, 0xac640000, 0xac650004, 0x8ee204c4,
-0xac620010, 0xaf860120, 0x92e24e20, 0x14400037,
-0x24070001, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c830000, 0x24020012, 0x1462001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x24030040, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee54e30, 0x24420001, 0x10430007,
-0x0, 0x8ee24e34, 0x24420001, 0x10a20005,
-0x0, 0x80022ae, 0x0, 0x14a00005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
-0xac800000, 0x80022c4, 0x0, 0x8ee24e30,
-0x24030040, 0x24420001, 0x50430003, 0x1021,
-0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x24020012,
-0xac820000, 0x24020001, 0xac820004, 0x14e0001b,
-0x0, 0x3c040001, 0x248453fc, 0xafa00010,
-0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
-0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001,
-0xaee201b0, 0x80022e0, 0x8ee201b0, 0x3c040001,
-0x24845408, 0xafa00014, 0x8ee60608, 0x8f470228,
-0x3c050009, 0xc002403, 0x34a5f005, 0x8ee201ac,
-0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20150,
-0x24420001, 0xaee20150, 0x8ee20150, 0x8ee20160,
-0x24420001, 0xaee20160, 0x8ee20160, 0x8f43022c,
-0x8f42010c, 0x14620009, 0x24020002, 0xaf820064,
-0x8f820064, 0x14400005, 0x0, 0x8f43022c,
-0x8f42010c, 0x1462f875, 0x0, 0x8fbf0044,
-0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034,
-0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x3e00008,
-0x27bd0048, 0x27bdfff8, 0x2408ffff, 0x10a00014,
-0x4821, 0x3c0aedb8, 0x354a8320, 0x90870000,
-0x24840001, 0x3021, 0x1071026, 0x30420001,
-0x10400002, 0x81842, 0x6a1826, 0x604021,
-0x24c60001, 0x2cc20008, 0x1440fff7, 0x73842,
-0x25290001, 0x125102b, 0x1440fff0, 0x0,
-0x1001021, 0x3e00008, 0x27bd0008, 0x27bdffe8,
-0x27642800, 0xafbf0010, 0xc002488, 0x24051000,
-0x24020021, 0xaf800100, 0xaf800104, 0xaf800108,
-0xaf800110, 0xaf800114, 0xaf800118, 0xaf800120,
-0xaf800124, 0xaf800128, 0xaf800130, 0xaf800134,
-0xaf800138, 0xaee04e28, 0xaee04e2c, 0xaee04e30,
-0xaee04e34, 0xaf82011c, 0x8f420218, 0x30420040,
-0x10400004, 0x0, 0x8f82011c, 0x34420004,
-0xaf82011c, 0x8fbf0010, 0x3e00008, 0x27bd0018,
-0x27bdffe0, 0xafbf0018, 0x8f820104, 0xafa20010,
-0x8f820100, 0x3c050002, 0xafa20014, 0x8f8600b0,
-0x8f87011c, 0x3c040001, 0x248454c0, 0xc002403,
-0x34a5f000, 0x8f8300b0, 0x3c027f00, 0x621824,
-0x3c020400, 0x10620029, 0x43102b, 0x14400008,
-0x3c022000, 0x3c020100, 0x10620024, 0x3c020200,
-0x10620011, 0x0, 0x8002374, 0x0,
-0x10620008, 0x3c024000, 0x1462001c, 0x0,
-0x8ee20190, 0x24420001, 0xaee20190, 0x8002374,
-0x8ee20190, 0x8ee2018c, 0x24420001, 0xaee2018c,
-0x8002374, 0x8ee2018c, 0x8f82011c, 0x34420002,
-0xaf82011c, 0x8f830104, 0x8f8200b0, 0x34420001,
-0xaf8200b0, 0xaf830104, 0x8f82011c, 0x2403fffd,
-0x431024, 0xaf82011c, 0x8ee201a0, 0x24420001,
-0xaee201a0, 0x8002377, 0x8ee201a0, 0x8f8200b0,
-0x34420001, 0xaf8200b0, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x27bdffe0, 0xafbf001c, 0xafb00018,
-0x8f820120, 0xafa20010, 0x8f820124, 0x3c050001,
-0xafa20014, 0x8f8600a0, 0x8f87011c, 0x3c040001,
-0x248454cc, 0xc002403, 0x34a5f000, 0x8f8300a0,
-0x3c027f00, 0x621824, 0x3c020400, 0x10620053,
-0x8021, 0x43102b, 0x14400008, 0x3c042000,
-0x3c020100, 0x1062004d, 0x3c020200, 0x1062003a,
-0x0, 0x80023e0, 0x0, 0x10640003,
-0x3c024000, 0x14620045, 0x0, 0x8f8200a0,
-0x441024, 0x10400006, 0x0, 0x8ee20194,
-0x24420001, 0xaee20194, 0x80023a9, 0x8ee20194,
-0x8ee20198, 0x24420001, 0xaee20198, 0x8ee20198,
-0x8f82011c, 0x34420002, 0xaf82011c, 0x8f82011c,
-0x30420200, 0x1040001b, 0x0, 0x8f8300a0,
-0x8f840124, 0x8f8200ac, 0x14400007, 0x24020001,
-0x3c020001, 0x3442f000, 0x621024, 0x50400001,
-0x24100001, 0x24020001, 0x1200000d, 0xaf8200a0,
-0x8f820124, 0x2442ffe0, 0xaf820124, 0x8f820124,
-0x8f820124, 0x27633000, 0x43102b, 0x10400005,
-0x276237e0, 0xaf820124, 0x80023ca, 0x0,
-0xaf840124, 0x8f82011c, 0x2403fffd, 0x431024,
-0x80023e3, 0xaf82011c, 0x8f82011c, 0x34420002,
-0xaf82011c, 0x8f830124, 0x8f8200a0, 0x34420001,
-0xaf8200a0, 0xaf830124, 0x8f82011c, 0x2403fffd,
-0x431024, 0xaf82011c, 0x8ee2019c, 0x24420001,
-0xaee2019c, 0x80023e3, 0x8ee2019c, 0x8f8200a0,
-0x34420001, 0xaf8200a0, 0x8fbf001c, 0x8fb00018,
-0x3e00008, 0x27bd0020, 0x0, 0x3c020001,
-0x8c425c58, 0x27bdffe8, 0xafbf0014, 0x14400012,
-0xafb00010, 0x3c100001, 0x26105dd0, 0x2002021,
-0xc002488, 0x24052000, 0x26021fe0, 0x3c010001,
-0xac225d94, 0x3c010001, 0xac225d90, 0xaf420250,
-0x24022000, 0xaf500254, 0xaf420258, 0x24020001,
-0x3c010001, 0xac225c58, 0x8fbf0014, 0x8fb00010,
-0x3e00008, 0x27bd0018, 0x3c030001, 0x8c635d94,
-0x8c820000, 0x8fa80010, 0x8fa90014, 0xac620000,
-0x3c020001, 0x8c425d94, 0x8c830004, 0xac430004,
-0xac450008, 0x8f840054, 0x2443ffe0, 0xac460010,
-0xac470014, 0xac480018, 0xac49001c, 0x3c010001,
-0xac235d94, 0xac44000c, 0x3c020001, 0x24425dd0,
-0x62182b, 0x10600005, 0x0, 0x3c020001,
-0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001,
-0x8c635d94, 0x3c020001, 0x8c425c40, 0xac620000,
-0x3c030001, 0x8c635d94, 0x3c020001, 0x8c425c40,
-0xac620004, 0x3e00008, 0xaf430250, 0x3c030001,
-0x8c635d94, 0x3c020001, 0x8c425c40, 0x27bdffd0,
-0xafb40020, 0x8fb40040, 0xafb00010, 0x808021,
-0xafb50024, 0x8fb50044, 0x8fa40048, 0xafb10014,
-0xa08821, 0xafbf0028, 0xafb3001c, 0xafb20018,
-0xac620000, 0x3c050001, 0x8ca55d94, 0x3c020001,
-0x8c425c40, 0xc09021, 0xe09821, 0x10800006,
-0xaca20004, 0x24a50008, 0xc002490, 0x24060018,
-0x800244e, 0x0, 0x24a40008, 0xc002488,
-0x24050018, 0x3c020001, 0x8c425d94, 0x3c050001,
-0x24a55dd0, 0x2442ffe0, 0x3c010001, 0xac225d94,
-0x45102b, 0x10400005, 0x0, 0x3c020001,
-0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001,
-0x8c635d94, 0x8e020000, 0xac620000, 0x3c030001,
-0x8c635d94, 0x8e020004, 0xac620004, 0xac710008,
-0x8f840054, 0x2462ffe0, 0x3c010001, 0xac225d94,
-0x45102b, 0xac720010, 0xac730014, 0xac740018,
-0xac75001c, 0x10400005, 0xac64000c, 0x3c020001,
-0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001,
-0x8c635d94, 0x3c020001, 0x8c425c40, 0xac620000,
-0x3c030001, 0x8c635d94, 0x3c020001, 0x8c425c40,
-0xac620004, 0xaf430250, 0x8fbf0028, 0x8fb50024,
-0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
-0x8fb00010, 0x3e00008, 0x27bd0030, 0x10a00005,
-0x0, 0xac800000, 0x24a5fffc, 0x14a0fffd,
-0x24840004, 0x3e00008, 0x0, 0x10c00007,
-0x0, 0x8c820000, 0x24840004, 0x24c6fffc,
-0xaca20000, 0x14c0fffb, 0x24a50004, 0x3e00008,
-0x0, 0x10c00007, 0x0, 0x8ca20000,
-0x24a50004, 0x24c6fffc, 0xac820000, 0x14c0fffb,
-0x24840004, 0x3e00008, 0x0, 0x3e00008,
-0x0, 0x27bdffd8, 0xafbf0020, 0x8ee304e4,
-0x8ee204e0, 0x10620436, 0x0, 0x8ee204e4,
-0x8ee304fc, 0x21100, 0x626021, 0x95870008,
-0x8d8a0000, 0x8d8b0004, 0x958d000a, 0x8ee2725c,
-0x8ee3726c, 0x30e4ffff, 0x441021, 0x62182b,
-0x10600015, 0x31a20004, 0x8f8200d8, 0x8ee37258,
-0x431023, 0xaee2726c, 0x8ee2726c, 0x1c400003,
-0x3c030001, 0x431021, 0xaee2726c, 0x8ee2725c,
-0x8ee3726c, 0x441021, 0x62182b, 0x10600006,
-0x31a20004, 0x8ee201b8, 0x24420001, 0xaee201b8,
-0x80028e1, 0x8ee201b8, 0x10400240, 0x31a20200,
-0x1040014d, 0x4821, 0x96e2045a, 0x30420010,
-0x10400149, 0x0, 0x8f840100, 0x27623000,
-0x24850020, 0xa2102b, 0x50400001, 0x27652800,
-0x8f820108, 0x10a20004, 0x0, 0x8f820104,
-0x14a20006, 0x2402000c, 0x8ee201a8, 0x24420001,
-0xaee201a8, 0x800252c, 0x8ee201a8, 0xac8a0000,
-0xac8b0004, 0x8ee37264, 0x24060005, 0xa482000e,
-0xac860018, 0xac830008, 0x8ee204e4, 0xac82001c,
-0x8ee204c8, 0xac820010, 0xaf850100, 0x92e204ec,
-0x14400036, 0x24090001, 0x8ee24e28, 0x210c0,
-0x24424e38, 0x2e22021, 0x8c820000, 0x1446001f,
-0x0, 0x8ee34e28, 0x8ee24e2c, 0x1062001b,
-0x24030040, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007,
-0x0, 0x8ee24e2c, 0x24420001, 0x10a20005,
-0x0, 0x8002516, 0x0, 0x14a00005,
-0x0, 0x8f820108, 0x24420020, 0xaf820108,
-0x8f820108, 0x8c820004, 0x2c420011, 0x50400013,
-0xac800000, 0x800252c, 0x0, 0x8ee24e28,
-0x24030040, 0x24420001, 0x50430003, 0x1021,
-0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28,
-0x210c0, 0x24424e38, 0x2e22021, 0x24020005,
-0xac820000, 0x24020001, 0xac820004, 0x1520000a,
-0x3c040001, 0xafab0010, 0x8ee27264, 0x3c040001,
-0x24845730, 0x3c050004, 0xafa20014, 0x8ee604e4,
-0x80028be, 0x34a5f114, 0x8ee27264, 0x34843800,
-0x3641821, 0x24420010, 0x43102b, 0x14400073,
-0x0, 0x8ee27264, 0x24480010, 0x3641021,
-0x102102b, 0x14400002, 0x3c02ffff, 0x1024021,
-0x8f850100, 0x27623000, 0x24a60020, 0xc2102b,
-0x50400001, 0x27662800, 0x8f820108, 0x10c20004,
-0x0, 0x8f820104, 0x14c20007, 0x2563000c,
-0x8ee201a8, 0x4821, 0x24420001, 0xaee201a8,
-0x80025a0, 0x8ee201a8, 0x2c64000c, 0x1441021,
-0xaca20000, 0xaca30004, 0x24e2fff4, 0xa4a2000e,
-0x24020006, 0xaca80008, 0xaca20018, 0x8ee204e4,
-0xaca2001c, 0x8ee204c8, 0x3c030002, 0x431025,
-0xaca20010, 0xaf860100, 0x92e204ec, 0x14400037,
-0x24090001, 0x8ee24e28, 0x210c0, 0x24424e38,
-0x2e22021, 0x8c830000, 0x24020005, 0x1462001f,
-0x0, 0x8ee34e28, 0x8ee24e2c, 0x1062001b,
-0x24030040, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e2c, 0x8ee54e28, 0x24420001, 0x10430007,
-0x0, 0x8ee24e2c, 0x24420001, 0x10a20005,
-0x0, 0x800258a, 0x0, 0x14a00005,
-0x0, 0x8f820108, 0x24420020, 0xaf820108,
-0x8f820108, 0x8c820004, 0x2c420011, 0x50400013,
-0xac800000, 0x80025a0, 0x0, 0x8ee24e28,
-0x24030040, 0x24420001, 0x50430003, 0x1021,
-0x8ee24e28, 0x24420001, 0xaee24e28, 0x8ee24e28,
-0x210c0, 0x24424e38, 0x2e22021, 0x24020005,
-0xac820000, 0x24020001, 0xac820004, 0x1520000a,
-0x2508fffc, 0xafab0010, 0x8ee27264, 0x3c040001,
-0x24845730, 0x3c050004, 0xafa20014, 0x8ee604e4,
-0x80028be, 0x34a5f125, 0x34028100, 0xa5020000,
-0x9582000e, 0x800261d, 0xa5020002, 0x8f850100,
-0x27623000, 0x24a60020, 0xc2102b, 0x50400001,
-0x27662800, 0x8f820108, 0x10c20004, 0x0,
-0x8f820104, 0x14c20007, 0x2563000c, 0x8ee201a8,
-0x4821, 0x24420001, 0xaee201a8, 0x800260d,
-0x8ee201a8, 0x2c64000c, 0x1441021, 0xaca20000,
-0xaca30004, 0x8ee37264, 0x24e2fff4, 0xa4a2000e,
-0x24020006, 0xaca20018, 0x24630010, 0xaca30008,
-0x8ee204e4, 0xaca2001c, 0x8ee204c8, 0x3c030002,
-0x431025, 0xaca20010, 0xaf860100, 0x92e204ec,
-0x14400037, 0x24090001, 0x8ee24e28, 0x210c0,
-0x24424e38, 0x2e22021, 0x8c830000, 0x24020005,
-0x1462001f, 0x0, 0x8ee34e28, 0x8ee24e2c,
-0x1062001b, 0x24030040, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e2c, 0x8ee54e28, 0x24420001,
-0x10430007, 0x0, 0x8ee24e2c, 0x24420001,
-0x10a20005, 0x0, 0x80025f7, 0x0,
-0x14a00005, 0x0, 0x8f820108, 0x24420020,
-0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011,
-0x50400013, 0xac800000, 0x800260d, 0x0,
-0x8ee24e28, 0x24030040, 0x24420001, 0x50430003,
-0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
-0x24020005, 0xac820000, 0x24020001, 0xac820004,
-0x1520000a, 0x34028100, 0xafab0010, 0x8ee27264,
-0x3c040001, 0x24845730, 0x3c050004, 0xafa20014,
-0x8ee604e4, 0x80028be, 0x34a5f015, 0x8ee37264,
-0xa462000c, 0x8ee37264, 0x9582000e, 0xa462000e,
-0x8002681, 0x24e70004, 0x8f840100, 0x27623000,
-0x24850020, 0xa2102b, 0x50400001, 0x27652800,
-0x8f820108, 0x10a20004, 0x0, 0x8f820104,
-0x14a20007, 0x24020006, 0x8ee201a8, 0x4821,
-0x24420001, 0xaee201a8, 0x8002677, 0x8ee201a8,
-0xac8a0000, 0xac8b0004, 0x8ee37264, 0xa487000e,
-0xac820018, 0xac830008, 0x8ee204e4, 0xac82001c,
-0x8ee204c8, 0x3c030002, 0x431025, 0xac820010,
-0xaf850100, 0x92e204ec, 0x14400037, 0x24090001,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
-0x8c830000, 0x24020005, 0x1462001f, 0x0,
-0x8ee34e28, 0x8ee24e2c, 0x1062001b, 0x24030040,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c,
-0x8ee54e28, 0x24420001, 0x10430007, 0x0,
-0x8ee24e2c, 0x24420001, 0x10a20005, 0x0,
-0x8002661, 0x0, 0x14a00005, 0x0,
-0x8f820108, 0x24420020, 0xaf820108, 0x8f820108,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x8002677, 0x0, 0x8ee24e28, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e28,
-0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0,
-0x24424e38, 0x2e22021, 0x24020005, 0xac820000,
-0x24020001, 0xac820004, 0x15200009, 0x3c050004,
-0xafab0010, 0x8ee27264, 0x3c040001, 0x24845730,
-0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f004,
-0x8ee2725c, 0x30e7ffff, 0x471021, 0xaee2725c,
-0x8ee204e4, 0x8ee304fc, 0x8ee47258, 0x21100,
-0x431021, 0xac44000c, 0x8ee27258, 0xafa20018,
-0x8ee3725c, 0xafa3001c, 0x8ee2725c, 0x2c42003c,
-0x10400004, 0x24620001, 0x2403fffe, 0x431024,
-0xafa2001c, 0x8ee27264, 0x3c060001, 0x34c63800,
-0x8ee3725c, 0x2405fff8, 0x471021, 0x24420007,
-0x451024, 0x24630007, 0xaee27258, 0x8ee2726c,
-0x8ee47258, 0x651824, 0x431023, 0xaee2726c,
-0x3661021, 0x82202b, 0x14800004, 0x3c03ffff,
-0x8ee27258, 0x431021, 0xaee27258, 0x8ee27258,
-0xaee27264, 0x8f8200f0, 0x24470008, 0x27621800,
-0xe2102b, 0x50400001, 0x27671000, 0x8f8200f4,
-0x14e20007, 0x0, 0x8ee201b4, 0x4821,
-0x24420001, 0xaee201b4, 0x80026c4, 0x8ee201b4,
-0x8f8200f0, 0x24090001, 0x8fa30018, 0x8fa4001c,
-0xac430000, 0xac440004, 0xaf8700f0, 0x15200012,
-0xd1142, 0x8f8200f0, 0xafa20010, 0x8f8200f4,
-0x3c040001, 0x2484573c, 0xafa20014, 0x8fa60018,
-0x8fa7001c, 0x3c050004, 0xc002403, 0x34a5f005,
-0x8ee20088, 0x24420001, 0xaee20088, 0x8ee20088,
-0x80028d3, 0xaee0725c, 0x30430003, 0x24020002,
-0x10620016, 0x28620003, 0x10400005, 0x24020001,
-0x10620008, 0x0, 0x8002703, 0x0,
-0x24020003, 0x10620017, 0x0, 0x8002703,
-0x0, 0x8ee200e8, 0x8ee300ec, 0x24630001,
-0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec,
-0x8ee200e8, 0x8002703, 0x8ee300ec, 0x8ee200f0,
-0x8ee300f4, 0x24630001, 0x2c640001, 0x441021,
-0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002703,
-0x8ee300f4, 0x8ee200f8, 0x8ee300fc, 0x24630001,
-0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc,
-0x8ee200f8, 0x8ee300fc, 0x8ee2725c, 0x8ee400e0,
-0x8ee500e4, 0x401821, 0x1021, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xaee400e0,
-0xaee500e4, 0x80028d3, 0xaee0725c, 0x30e2ffff,
-0x104001c1, 0x31a20200, 0x1040014d, 0x4821,
-0x96e2045a, 0x30420010, 0x10400149, 0x0,
-0x8f840100, 0x27623000, 0x24850020, 0xa2102b,
-0x50400001, 0x27652800, 0x8f820108, 0x10a20004,
-0x0, 0x8f820104, 0x14a20006, 0x2402000c,
-0x8ee201a8, 0x24420001, 0xaee201a8, 0x800276e,
-0x8ee201a8, 0xac8a0000, 0xac8b0004, 0x8ee37264,
-0x24060005, 0xa482000e, 0xac860018, 0xac830008,
-0x8ee204e4, 0xac82001c, 0x8ee204c8, 0xac820010,
-0xaf850100, 0x92e204ec, 0x14400036, 0x24090001,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
-0x8c820000, 0x1446001f, 0x0, 0x8ee34e28,
-0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28,
-0x24420001, 0x10430007, 0x0, 0x8ee24e2c,
-0x24420001, 0x10a20005, 0x0, 0x8002758,
-0x0, 0x14a00005, 0x0, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x800276e,
-0x0, 0x8ee24e28, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e28, 0x24420001,
-0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
-0x2e22021, 0x24020005, 0xac820000, 0x24020001,
-0xac820004, 0x1520000a, 0x3c040001, 0xafab0010,
-0x8ee27264, 0x3c040001, 0x24845730, 0x3c050004,
-0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f014,
-0x8ee27264, 0x34843800, 0x3641821, 0x24420010,
-0x43102b, 0x14400073, 0x0, 0x8ee27264,
-0x24480010, 0x3641021, 0x102102b, 0x14400002,
-0x3c02ffff, 0x1024021, 0x8f850100, 0x27623000,
-0x24a60020, 0xc2102b, 0x50400001, 0x27662800,
-0x8f820108, 0x10c20004, 0x0, 0x8f820104,
-0x14c20007, 0x2563000c, 0x8ee201a8, 0x4821,
-0x24420001, 0xaee201a8, 0x80027e2, 0x8ee201a8,
-0x2c64000c, 0x1441021, 0xaca20000, 0xaca30004,
-0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca80008,
-0xaca20018, 0x8ee204e4, 0xaca2001c, 0x8ee204c8,
-0x3c030002, 0x431025, 0xaca20010, 0xaf860100,
-0x92e204ec, 0x14400037, 0x24090001, 0x8ee24e28,
-0x210c0, 0x24424e38, 0x2e22021, 0x8c830000,
-0x24020005, 0x1462001f, 0x0, 0x8ee34e28,
-0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28,
-0x24420001, 0x10430007, 0x0, 0x8ee24e2c,
-0x24420001, 0x10a20005, 0x0, 0x80027cc,
-0x0, 0x14a00005, 0x0, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x80027e2,
-0x0, 0x8ee24e28, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e28, 0x24420001,
-0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
-0x2e22021, 0x24020005, 0xac820000, 0x24020001,
-0xac820004, 0x1520000a, 0x2508fffc, 0xafab0010,
-0x8ee27264, 0x3c040001, 0x24845730, 0x3c050004,
-0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f015,
-0x34028100, 0xa5020000, 0x9582000e, 0x800285f,
-0xa5020002, 0x8f850100, 0x27623000, 0x24a60020,
-0xc2102b, 0x50400001, 0x27662800, 0x8f820108,
-0x10c20004, 0x0, 0x8f820104, 0x14c20007,
-0x2563000c, 0x8ee201a8, 0x4821, 0x24420001,
-0xaee201a8, 0x800284f, 0x8ee201a8, 0x2c64000c,
-0x1441021, 0xaca20000, 0xaca30004, 0x8ee37264,
-0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca20018,
-0x24630010, 0xaca30008, 0x8ee204e4, 0xaca2001c,
-0x8ee204c8, 0x3c030002, 0x431025, 0xaca20010,
-0xaf860100, 0x92e204ec, 0x14400037, 0x24090001,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
-0x8c830000, 0x24020005, 0x1462001f, 0x0,
-0x8ee34e28, 0x8ee24e2c, 0x1062001b, 0x24030040,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c,
-0x8ee54e28, 0x24420001, 0x10430007, 0x0,
-0x8ee24e2c, 0x24420001, 0x10a20005, 0x0,
-0x8002839, 0x0, 0x14a00005, 0x0,
-0x8f820108, 0x24420020, 0xaf820108, 0x8f820108,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x800284f, 0x0, 0x8ee24e28, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e28,
-0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0,
-0x24424e38, 0x2e22021, 0x24020005, 0xac820000,
-0x24020001, 0xac820004, 0x1520000a, 0x34028100,
-0xafab0010, 0x8ee27264, 0x3c040001, 0x24845730,
-0x3c050004, 0xafa20014, 0x8ee604e4, 0x80028be,
-0x34a5f016, 0x8ee37264, 0xa462000c, 0x8ee37264,
-0x9582000e, 0xa462000e, 0x80028c2, 0x24e70004,
-0x8f830100, 0x27623000, 0x24640020, 0x82102b,
-0x50400001, 0x27642800, 0x8f820108, 0x10820004,
-0x0, 0x8f820104, 0x14820007, 0x24050005,
-0x8ee201a8, 0x4821, 0x24420001, 0xaee201a8,
-0x80028b6, 0x8ee201a8, 0xac6a0000, 0xac6b0004,
-0x8ee27264, 0xa467000e, 0xac650018, 0xac620008,
-0x8ee204e4, 0xac62001c, 0x8ee204c8, 0xac620010,
-0xaf840100, 0x92e204ec, 0x14400036, 0x24090001,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
-0x8c820000, 0x1445001f, 0x0, 0x8ee34e28,
-0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28,
-0x24420001, 0x10430007, 0x0, 0x8ee24e2c,
-0x24420001, 0x10a20005, 0x0, 0x80028a0,
-0x0, 0x14a00005, 0x0, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x80028b6,
-0x0, 0x8ee24e28, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e28, 0x24420001,
-0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
-0x2e22021, 0x24020005, 0xac820000, 0x24020001,
-0xac820004, 0x1520000b, 0x3c050004, 0x3c040001,
-0x24845748, 0xafab0010, 0xafa00014, 0x8ee604e4,
-0x34a5f017, 0xc002403, 0x30e7ffff, 0x80028e1,
-0x0, 0x8ee27264, 0x3c050001, 0x30e4ffff,
-0x441021, 0xaee27264, 0x8ee2725c, 0x8ee37264,
-0x34a53800, 0x441021, 0xaee2725c, 0x3651021,
-0x62182b, 0x14600004, 0x3c03ffff, 0x8ee27264,
-0x431021, 0xaee27264, 0x8ee304e4, 0x96e20458,
-0x24630001, 0x2442ffff, 0x621824, 0xaee304e4,
-0x8ee304e4, 0x8ee204e0, 0x14620005, 0x0,
-0x8f820060, 0x2403fff7, 0x431024, 0xaf820060,
-0x8fbf0020, 0x3e00008, 0x27bd0028, 0x27bdffe0,
-0xafbf0018, 0x8ee304e8, 0x8ee204e0, 0x10620189,
-0x0, 0x8ee204e8, 0x8ee304fc, 0x21100,
-0x621821, 0x94670008, 0x92e204ed, 0x8c680000,
-0x8c690004, 0x10400023, 0x946a000a, 0x8ee204c8,
-0x34460400, 0x31420200, 0x1040001f, 0x0,
-0x96e2045a, 0x30420010, 0x1040001b, 0x3c028000,
-0x3c010001, 0x370821, 0xac2283d8, 0x8ee27264,
-0x9464000e, 0x3c050001, 0x34a53800, 0x24420004,
-0xaee27264, 0x8ee37264, 0x42400, 0x3651021,
-0x3c010001, 0x370821, 0xac2483dc, 0x62182b,
-0x14600005, 0x24e70004, 0x8ee27264, 0x3c03ffff,
-0x431021, 0xaee27264, 0x8ee27264, 0x8002917,
-0xaee27258, 0x8ee604c8, 0x8ee2726c, 0x30e4ffff,
-0x44102a, 0x10400015, 0x0, 0x8f8200d8,
-0x8ee37258, 0x431023, 0xaee2726c, 0x8ee2726c,
-0x1c400007, 0x44102a, 0x8ee2726c, 0x3c030001,
-0x431021, 0xaee2726c, 0x8ee2726c, 0x44102a,
-0x10400006, 0x0, 0x8ee201b8, 0x24420001,
-0xaee201b8, 0x8002a72, 0x8ee201b8, 0x3c020001,
-0x571021, 0x8c4283d8, 0x54400001, 0x24e7fffc,
-0x31420004, 0x104000b9, 0x30e2ffff, 0x3c020001,
-0x571021, 0x8c4283d8, 0x1040002f, 0x5021,
-0x8f840100, 0x27623000, 0x24850020, 0xa2102b,
-0x50400001, 0x27652800, 0x8f820108, 0x10a20032,
-0x0, 0x8f820104, 0x10a2002f, 0x24020015,
-0xac880000, 0xac890004, 0x8ee37264, 0xa487000e,
-0xac820018, 0xac830008, 0x8ee204e8, 0x3c030001,
-0x771821, 0x8c6383dc, 0xac860010, 0x431025,
-0xac82001c, 0xaf850100, 0x92e204ec, 0x14400066,
-0x240a0001, 0x8ee24e28, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e28, 0x24420001,
-0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
-0x2e21821, 0x24020015, 0xac620000, 0x24020001,
-0x80029bf, 0xac620004, 0x8f840100, 0x27623000,
-0x24850020, 0xa2102b, 0x50400001, 0x27652800,
-0x8f820108, 0x10a20004, 0x0, 0x8f820104,
-0x14a20006, 0x24020006, 0x8ee201a8, 0x24420001,
-0xaee201a8, 0x80029bf, 0x8ee201a8, 0xac880000,
-0xac890004, 0x8ee37264, 0xa487000e, 0xac820018,
-0xac830008, 0x8ee204e8, 0xac860010, 0xac82001c,
-0xaf850100, 0x92e204ec, 0x14400037, 0x240a0001,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
-0x8c830000, 0x24020005, 0x1462001f, 0x0,
-0x8ee34e28, 0x8ee24e2c, 0x1062001b, 0x24030040,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e2c,
-0x8ee54e28, 0x24420001, 0x10430007, 0x0,
-0x8ee24e2c, 0x24420001, 0x10a20005, 0x0,
-0x80029a9, 0x0, 0x14a00005, 0x0,
-0x8f820108, 0x24420020, 0xaf820108, 0x8f820108,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x80029bf, 0x0, 0x8ee24e28, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e28,
-0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0,
-0x24424e38, 0x2e22021, 0x24020005, 0xac820000,
-0x24020001, 0xac820004, 0x1540000a, 0x24020001,
-0xafa90010, 0x8ee27264, 0x3c040001, 0x24845730,
-0x3c050004, 0xafa20014, 0x8ee604e4, 0x8002a4f,
-0x34a5f204, 0xa2e204ed, 0x8ee204e8, 0x8ee304fc,
-0x8ee47258, 0x3c060001, 0x34c63800, 0x3c010001,
-0x370821, 0xac2083d8, 0x3c010001, 0x370821,
-0xac2083dc, 0x21100, 0x431021, 0xac44000c,
-0x8ee27264, 0x2405fff8, 0x30e3ffff, 0x431021,
-0x24420007, 0x451024, 0x24630007, 0xaee27258,
-0x8ee2726c, 0x8ee47258, 0x651824, 0x431023,
-0xaee2726c, 0x3661021, 0x82202b, 0x14800004,
-0x3c03ffff, 0x8ee27258, 0x431021, 0xaee27258,
-0x8ee27258, 0x8002a64, 0xaee27264, 0x10400073,
-0x0, 0x8f830100, 0x27623000, 0x24640020,
-0x82102b, 0x14400002, 0x5021, 0x27642800,
-0x8f820108, 0x10820004, 0x0, 0x8f820104,
-0x14820006, 0x24050005, 0x8ee201a8, 0x24420001,
-0xaee201a8, 0x8002a46, 0x8ee201a8, 0xac680000,
-0xac690004, 0x8ee27264, 0xa467000e, 0xac650018,
-0xac620008, 0x8ee204e8, 0xac660010, 0xac62001c,
-0xaf840100, 0x92e204ec, 0x14400036, 0x240a0001,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
-0x8c820000, 0x1445001f, 0x0, 0x8ee34e28,
-0x8ee24e2c, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e2c, 0x8ee54e28,
-0x24420001, 0x10430007, 0x0, 0x8ee24e2c,
-0x24420001, 0x10a20005, 0x0, 0x8002a30,
-0x0, 0x14a00005, 0x0, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x8002a46,
-0x0, 0x8ee24e28, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e28, 0x24420001,
-0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
-0x2e22021, 0x24020005, 0xac820000, 0x24020001,
-0xac820004, 0x1540000c, 0x30e5ffff, 0x3c040001,
-0x24845748, 0x3c050004, 0xafa90010, 0xafa00014,
-0x8ee604e4, 0x34a5f237, 0xc002403, 0x30e7ffff,
-0x8002a72, 0x0, 0x8ee27264, 0x451021,
-0xaee27264, 0x8ee2726c, 0x8ee37264, 0x3c040001,
-0x34843800, 0xa2e004ed, 0x451023, 0xaee2726c,
-0x3641021, 0x62182b, 0x14600004, 0x3c03ffff,
-0x8ee27264, 0x431021, 0xaee27264, 0x8ee304e8,
-0x96e20458, 0x24630001, 0x2442ffff, 0x621824,
-0xaee304e8, 0x8ee304e8, 0x8ee204e0, 0x14620005,
-0x0, 0x8f820060, 0x2403fff7, 0x431024,
-0xaf820060, 0x8fbf0018, 0x3e00008, 0x27bd0020,
-0x27bdffe0, 0xafbf001c, 0xafb00018, 0x8f820100,
-0x8ee34e2c, 0x8f820104, 0x8f850108, 0x24020040,
-0x24630001, 0x50620003, 0x1021, 0x8ee24e2c,
-0x24420001, 0xaee24e2c, 0x8ee24e2c, 0x8ee34e2c,
-0x210c0, 0x24424e38, 0x2e22021, 0x8ee24e28,
-0x8c870004, 0x14620007, 0xa03021, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x8002aa2,
-0xac800000, 0x8ee24e2c, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e2c, 0x24420001,
-0x210c0, 0x24424e38, 0x2e22021, 0x8c820004,
-0x8f830108, 0x21140, 0x621821, 0xaf830108,
-0xac800000, 0x8cc20018, 0x2443fffe, 0x2c620013,
-0x104000c1, 0x31080, 0x3c010001, 0x220821,
-0x8c225770, 0x400008, 0x0, 0x8ee204f0,
-0x471021, 0xaee204f0, 0x8ee204f0, 0x8f43023c,
-0x43102b, 0x144000be, 0x0, 0x8ee304e4,
-0x8ee204f8, 0x506200ba, 0xa2e004f4, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20007, 0x0, 0x8ee201a4,
-0x8021, 0x24420001, 0xaee201a4, 0x8002b12,
-0x8ee201a4, 0x8ee204e4, 0xac62001c, 0x8ee404b0,
-0x8ee504b4, 0x2462001c, 0xac620008, 0x24020008,
-0xa462000e, 0x24020011, 0xac620018, 0xac640000,
-0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120,
-0x92e24e20, 0x14400037, 0x24100001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c830000,
-0x24020012, 0x1462001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x24030040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee54e30,
-0x24420001, 0x10430007, 0x0, 0x8ee24e34,
-0x24420001, 0x10a20005, 0x0, 0x8002afc,
-0x0, 0x14a00005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x8002b12,
-0x0, 0x8ee24e30, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x24020012, 0xac820000, 0x24020001,
-0xac820004, 0x5600000b, 0x24100001, 0x8ee204e4,
-0x3c040001, 0x24845754, 0xafa00014, 0xafa20010,
-0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
-0x34a5f006, 0x16000003, 0x24020001, 0x8002b71,
-0xa2e204f4, 0x8ee20170, 0x24420001, 0xaee20170,
-0x8ee20170, 0x8ee204e4, 0xa2e004f4, 0xaee004f0,
-0xaee204f8, 0x8f42023c, 0x50400045, 0xaee07274,
-0x8ee20184, 0x24420001, 0xaee20184, 0x8ee20184,
-0x8002b71, 0xaee07274, 0x8ee20504, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee20504,
-0x24420001, 0xaee20504, 0x8ee20504, 0x8cc30018,
-0x21080, 0x571021, 0x8c440508, 0x24020003,
-0x1462000f, 0x0, 0x3c020001, 0x571021,
-0x904283b1, 0x10400014, 0x0, 0x8ee201d0,
-0x8ee35240, 0x441021, 0xaee201d0, 0x8ee201d8,
-0x641821, 0x306300ff, 0x8002b59, 0xaee35240,
-0x8ee201cc, 0x8ee30e10, 0x441021, 0xaee201cc,
-0x8ee201d8, 0x641821, 0x306301ff, 0xaee30e10,
-0x441021, 0xaee201d8, 0x8ee20000, 0x34420040,
-0x8002b71, 0xaee20000, 0x8ee2014c, 0x3c010001,
-0x370821, 0xa02083e0, 0x24420001, 0xaee2014c,
-0x8002b71, 0x8ee2014c, 0x94c7000e, 0x8cc2001c,
-0x3c040001, 0x24845760, 0xafa60014, 0xafa20010,
-0x8cc60018, 0x3c050008, 0xc002403, 0x34a50910,
-0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
-0x27bdff98, 0xafbf0060, 0xafbe005c, 0xafb60058,
-0xafb50054, 0xafb40050, 0xafb3004c, 0xafb20048,
-0xafb10044, 0xafb00040, 0x8f830108, 0x8f820104,
-0xafa00024, 0x106203e7, 0xafa0002c, 0x3c1e0001,
-0x37de3800, 0x3c0bffff, 0x8f930108, 0x8e620018,
-0x8f830104, 0x2443fffe, 0x2c620014, 0x104003cf,
-0x31080, 0x3c010001, 0x220821, 0x8c2257c0,
-0x400008, 0x0, 0x9663000e, 0x8ee2725c,
-0x8ee404f0, 0x431021, 0xaee2725c, 0x8e63001c,
-0x96e20458, 0x24840001, 0xaee404f0, 0x24630001,
-0x2442ffff, 0x621824, 0xaee304e4, 0x8f42023c,
-0x82202b, 0x148003b9, 0x0, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20007, 0x0, 0x8ee201a4,
-0x8021, 0x24420001, 0xaee201a4, 0x8002bfe,
-0x8ee201a4, 0x8ee204e4, 0xac62001c, 0x8ee404b0,
-0x8ee504b4, 0x2462001c, 0xac620008, 0x24020008,
-0xa462000e, 0x24020011, 0xac620018, 0xac640000,
-0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120,
-0x92e24e20, 0x14400037, 0x24100001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c830000,
-0x24020012, 0x1462001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x240c0040, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x104c0007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x8002be8,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400013, 0xac800000, 0x8002bfe,
-0x0, 0x8ee24e30, 0x240c0040, 0x24420001,
-0x504c0003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x24020012, 0x240c0001, 0xac820000,
-0xac8c0004, 0x5600000d, 0x24100001, 0x8ee204e4,
-0x3c040001, 0x24845754, 0xafa00014, 0xafa20010,
-0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f006,
-0xc002403, 0xafab0038, 0x8fab0038, 0x1200030a,
-0x240c0001, 0x8002f19, 0x0, 0x966c001c,
-0xafac002c, 0x9662001e, 0x3c0c8000, 0xafac0024,
-0xae62001c, 0x8e75001c, 0x8ee204fc, 0x8ee404fc,
-0x151900, 0x621021, 0x8c52000c, 0x92e27b98,
-0x641821, 0x9476000a, 0x14400003, 0x32c20002,
-0xaef27ba4, 0xaef57b9c, 0x1040004b, 0x8021,
-0x96e2045a, 0x30420002, 0x10400047, 0x0,
-0x8e63001c, 0x8ee204fc, 0x32100, 0x821021,
-0x8c42000c, 0x37e1821, 0x24420022, 0x43102b,
-0x1440000a, 0x24050014, 0x8ee204fc, 0x821021,
-0x8c44000c, 0xafab0038, 0xc002f75, 0x2484000e,
-0x8fab0038, 0x8002c52, 0x3050ffff, 0x8ee204fc,
-0x821021, 0x8c42000c, 0x9450000e, 0x94430010,
-0x94440012, 0x94450014, 0x2038021, 0x2048021,
-0x2058021, 0x94430016, 0x94440018, 0x9445001a,
-0x2038021, 0x2048021, 0x2058021, 0x9443001c,
-0x9444001e, 0x94420020, 0x2038021, 0x2048021,
-0x2028021, 0x101c02, 0x3202ffff, 0x628021,
-0x8e63001c, 0x8ee204fc, 0x102402, 0x32900,
-0xa21021, 0x8c43000c, 0x3202ffff, 0x828021,
-0x37e1021, 0x24630018, 0x62182b, 0x14600009,
-0x0, 0x8ee204fc, 0xa21021, 0x8c43000c,
-0x101027, 0x3c01ffff, 0x230821, 0x8002c6f,
-0xa4220018, 0x8ee204fc, 0xa21021, 0x8c43000c,
-0x101027, 0xa4620018, 0x96e2045a, 0x8821,
-0x30420008, 0x14400063, 0xa021, 0x8e63001c,
-0x8ee204fc, 0x33100, 0xc21021, 0x8c42000c,
-0x37e1821, 0x24420022, 0x43102b, 0x14400035,
-0x0, 0x8ee204fc, 0xc21021, 0x8c42000c,
-0x24470010, 0x37e1021, 0xe2102b, 0x50400001,
-0xeb3821, 0x8ee204fc, 0x94f10000, 0xc21021,
-0x8c42000c, 0x24470016, 0x37e1021, 0xe2102b,
-0x14400002, 0x2634ffec, 0xeb3821, 0x8ee204fc,
-0x90e30001, 0xc21021, 0x8c42000c, 0x2447001a,
-0x37e1021, 0xe2102b, 0x14400002, 0x2838821,
-0xeb3821, 0x94e20000, 0x24e70002, 0x2228821,
-0x37e1021, 0xe2102b, 0x50400001, 0xeb3821,
-0x94e20000, 0x24e70002, 0x2228821, 0x37e1021,
-0xe2102b, 0x50400001, 0xeb3821, 0x94e20000,
-0x24e70002, 0x2228821, 0x37e1021, 0xe2102b,
-0x50400001, 0xeb3821, 0x94e20000, 0x8002cd0,
-0x2228821, 0x8ee204fc, 0xc21021, 0x8c43000c,
-0x8ee204fc, 0x94710010, 0x8ee304fc, 0xc21021,
-0x8c44000c, 0xc31821, 0x8c62000c, 0x2634ffec,
-0x90840017, 0x8ee304fc, 0x9442001a, 0x2848821,
-0xc31821, 0x8c65000c, 0x8ee304fc, 0x2228821,
-0x8ee204fc, 0xc31821, 0xc21021, 0x8c44000c,
-0x8c62000c, 0x94a3001c, 0x9484001e, 0x94420020,
-0x2238821, 0x2248821, 0x2228821, 0x111c02,
-0x3222ffff, 0x628821, 0x111c02, 0x3222ffff,
-0x628821, 0x32c20001, 0x104000b2, 0x0,
-0x96e2045a, 0x30420001, 0x104000ae, 0x32c20080,
-0x10400008, 0x0, 0x92e27b98, 0x14400005,
-0x0, 0x240c0001, 0xa2ec7b98, 0xaef57b9c,
-0xaef27ba4, 0x8ee304fc, 0x151100, 0x431021,
-0x8c47000c, 0x37e1821, 0x24e2000e, 0x43102b,
-0x14400008, 0xe02021, 0x2405000e, 0xc002f75,
-0xafab0038, 0x3042ffff, 0x8fab0038, 0x8002d09,
-0x2028021, 0x94e60000, 0x24e70002, 0x94e50000,
-0x24e70002, 0x94e30000, 0x24e70002, 0x94e20000,
-0x24e70002, 0x94e40000, 0x24e70002, 0x2068021,
-0x2058021, 0x2038021, 0x2028021, 0x94e20000,
-0x94e30002, 0x2048021, 0x2028021, 0x2038021,
-0x101c02, 0x3202ffff, 0x628021, 0x101c02,
-0x3202ffff, 0x8ee47b9c, 0x628021, 0x14950004,
-0x3205ffff, 0x96620016, 0x8002d17, 0x512021,
-0x96620016, 0x542021, 0x41402, 0x3083ffff,
-0x432021, 0x852023, 0x41402, 0x822021,
-0x3084ffff, 0x50800001, 0x3404ffff, 0x8ee27ba4,
-0x24430017, 0x37e1021, 0x62102b, 0x50400001,
-0x6b1821, 0x90630000, 0x24020011, 0x14620031,
-0x24020006, 0x8ee27ba4, 0x37e1821, 0x24420028,
-0x43102b, 0x14400018, 0x0, 0x8ee27b9c,
-0x12a2000a, 0x32c20100, 0x8ee27ba4, 0x3c01ffff,
-0x220821, 0x94220028, 0x822021, 0x41c02,
-0x3082ffff, 0x622021, 0x32c20100, 0x14400004,
-0x41027, 0x92e27b98, 0x14400002, 0x41027,
-0x3044ffff, 0x8ee27ba4, 0x3c01ffff, 0x220821,
-0x8002d8a, 0xa4240028, 0x8ee27b9c, 0x12a20008,
-0x32c20100, 0x8ee27ba4, 0x94420028, 0x822021,
-0x41c02, 0x3082ffff, 0x622021, 0x32c20100,
-0x14400004, 0x41027, 0x92e27b98, 0x14400002,
-0x41027, 0x3044ffff, 0x8ee27ba4, 0x8002d8a,
-0xa4440028, 0x1462002f, 0x37e1821, 0x8ee27ba4,
-0x24420032, 0x43102b, 0x14400018, 0x0,
-0x8ee27b9c, 0x12a2000a, 0x32c20100, 0x8ee27ba4,
-0x3c01ffff, 0x220821, 0x94220032, 0x822021,
-0x41c02, 0x3082ffff, 0x622021, 0x32c20100,
-0x14400004, 0x41027, 0x92e27b98, 0x14400002,
-0x41027, 0x3044ffff, 0x8ee27ba4, 0x3c01ffff,
-0x220821, 0x8002d8a, 0xa4240032, 0x8ee27b9c,
-0x12a20008, 0x32c20100, 0x8ee27ba4, 0x94420032,
-0x822021, 0x41c02, 0x3082ffff, 0x622021,
-0x32c20100, 0x14400004, 0x41027, 0x92e27b98,
-0x14400002, 0x41027, 0x3044ffff, 0x8ee27ba4,
-0xa4440032, 0x8fac0024, 0x1180002c, 0x37e1821,
-0x8e420000, 0xae42fffc, 0x2642000a, 0x43102b,
-0x1440001b, 0x34038100, 0x26430004, 0x37e1021,
-0x62102b, 0x14400003, 0x602021, 0x6b1821,
-0x602021, 0x8c620000, 0x24630004, 0xae420000,
-0x37e1021, 0x62102b, 0x50400001, 0x6b1821,
-0x8c620000, 0xac820000, 0x34028100, 0xa4620000,
-0x24630002, 0x37e1021, 0x62102b, 0x50400001,
-0x6b1821, 0x97ac002e, 0x8002db4, 0xa46c0000,
-0x8e420004, 0x8e440008, 0xa6430008, 0x97ac002e,
-0xa64c000a, 0xae420000, 0xae440004, 0x9662000e,
-0x2652fffc, 0x24420004, 0xa662000e, 0x9662000e,
-0x8ee3725c, 0x621821, 0xaee3725c, 0xafb20018,
-0x8ee3725c, 0xafa3001c, 0x8ee2725c, 0x2c42003c,
-0x10400004, 0x24620001, 0x2403fffe, 0x431024,
-0xafa2001c, 0x32c20080, 0x1040000c, 0x32c20100,
-0x8ee27ba8, 0x24430001, 0x210c0, 0x571021,
-0xaee37ba8, 0x8fa30018, 0x8fa4001c, 0xac437bac,
-0xac447bb0, 0x8002ea0, 0xaee0725c, 0x10400072,
-0x0, 0x8ee27ba8, 0x24430001, 0x210c0,
-0x571021, 0xaee37ba8, 0x8fa30018, 0x8fa4001c,
-0xac437bac, 0xac447bb0, 0x8ee27ba8, 0x10400063,
-0x4821, 0x5021, 0x8f8200f0, 0x24480008,
-0x27621800, 0x102102b, 0x50400001, 0x27681000,
-0x8f8200f4, 0x15020007, 0x0, 0x8ee201b4,
-0x8021, 0x24420001, 0xaee201b4, 0x8002dfa,
-0x8ee201b4, 0x8f8300f0, 0x24100001, 0x1571021,
-0x8c447bac, 0x8c457bb0, 0xac640000, 0xac650004,
-0xaf8800f0, 0x16000006, 0x2ea1021, 0x8ee20088,
-0x24420001, 0xaee20088, 0x8002e3f, 0x8ee20088,
-0x8c427bb0, 0x8ee400e0, 0x8ee500e4, 0x8ee67b9c,
-0x401821, 0x1021, 0xa32821, 0xa3382b,
-0x822021, 0x872021, 0x8ee204fc, 0xc93021,
-0x63100, 0xaee400e0, 0xaee500e4, 0xc23021,
-0x94c2000a, 0x240c0002, 0x21142, 0x30430003,
-0x106c0016, 0x28620003, 0x10400005, 0x240c0001,
-0x106c0008, 0x0, 0x8002e3f, 0x0,
-0x240c0003, 0x106c0017, 0x0, 0x8002e3f,
-0x0, 0x8ee200e8, 0x8ee300ec, 0x24630001,
-0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec,
-0x8ee200e8, 0x8002e3f, 0x8ee300ec, 0x8ee200f0,
-0x8ee300f4, 0x24630001, 0x2c640001, 0x441021,
-0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002e3f,
-0x8ee300f4, 0x8ee200f8, 0x8ee300fc, 0x24630001,
-0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc,
-0x8ee200f8, 0x8ee300fc, 0x8ee27ba8, 0x25290001,
-0x122102b, 0x1440ffa0, 0x254a0008, 0xa2e07b98,
-0x8002e9f, 0xaee07ba8, 0x8f8200f0, 0x24470008,
-0x27621800, 0xe2102b, 0x50400001, 0x27671000,
-0x8f8200f4, 0x14e20007, 0x0, 0x8ee201b4,
-0x8021, 0x24420001, 0xaee201b4, 0x8002e5d,
-0x8ee201b4, 0x8f8200f0, 0x24100001, 0x8fa30018,
-0x8fa4001c, 0xac430000, 0xac440004, 0xaf8700f0,
-0x16000007, 0x0, 0x8ee20088, 0x24420001,
-0xaee20088, 0x8ee20088, 0x8002ea0, 0xaee0725c,
-0x8ee2725c, 0x8ee400e0, 0x8ee500e4, 0x240c0002,
-0x401821, 0x1021, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0x161142, 0x30430003,
-0xaee400e0, 0xaee500e4, 0x106c0017, 0x2c620003,
-0x10400005, 0x240c0001, 0x106c0008, 0x0,
-0x8002ea0, 0xaee0725c, 0x240c0003, 0x106c0019,
-0x0, 0x8002ea0, 0xaee0725c, 0x8ee200e8,
-0x8ee300ec, 0x24630001, 0x2c640001, 0x441021,
-0xaee200e8, 0xaee300ec, 0x8ee200e8, 0x8ee300ec,
-0x8002ea0, 0xaee0725c, 0x8ee200f0, 0x8ee300f4,
-0x24630001, 0x2c640001, 0x441021, 0xaee200f0,
-0xaee300f4, 0x8ee200f0, 0x8ee300f4, 0x8002ea0,
-0xaee0725c, 0x8ee200f8, 0x8ee300fc, 0x24630001,
-0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc,
-0x8ee200f8, 0x8ee300fc, 0xaee0725c, 0x8e62001c,
-0x96e30458, 0x8ee404f0, 0x24420001, 0x2463ffff,
-0x431024, 0x24840001, 0xaee204e4, 0xaee404f0,
-0x8f42023c, 0x82202b, 0x148000b0, 0x0,
-0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
-0x50400001, 0x27663000, 0x8f820128, 0x10c20004,
-0x0, 0x8f820124, 0x14c20007, 0x0,
-0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4,
-0x8002f07, 0x8ee201a4, 0x8ee204e4, 0xac62001c,
-0x8ee404b0, 0x8ee504b4, 0x2462001c, 0xac620008,
-0x24020008, 0xa462000e, 0x24020011, 0xac620018,
-0xac640000, 0xac650004, 0x8ee204c4, 0xac620010,
-0xaf860120, 0x92e24e20, 0x14400037, 0x24100001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c830000, 0x24020012, 0x1462001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x240c0040,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee34e30, 0x24420001, 0x104c0007, 0x0,
-0x8ee24e34, 0x24420001, 0x10620005, 0x0,
-0x8002ef1, 0x0, 0x14600005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x8002f07, 0x0, 0x8ee24e30, 0x240c0040,
-0x24420001, 0x504c0003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020012, 0x240c0001,
-0xac820000, 0xac8c0004, 0x5600000d, 0x24100001,
-0x8ee204e4, 0x3c040001, 0x24845754, 0xafa00014,
-0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009,
-0x34a5f006, 0xc002403, 0xafab0038, 0x8fab0038,
-0x16000003, 0x240c0001, 0x8002f5c, 0xa2ec04f4,
-0x8ee20170, 0x24420001, 0xaee20170, 0x8ee20170,
-0x8ee204e4, 0xa2e004f4, 0xaee004f0, 0xaee07274,
-0xaee204f8, 0x8f42023c, 0x10400038, 0x0,
-0x8ee20184, 0x24420001, 0xaee20184, 0x8002f5c,
-0x8ee20184, 0x8ee20504, 0x240c0040, 0x24420001,
-0x504c0003, 0x1021, 0x8ee20504, 0x24420001,
-0xaee20504, 0x8ee20504, 0x8e630018, 0x240c0003,
-0x21080, 0x571021, 0x146c000f, 0x8c440508,
-0x3c020001, 0x571021, 0x904283b1, 0x10400014,
-0x0, 0x8ee201d0, 0x8ee35240, 0x441021,
-0xaee201d0, 0x8ee201d8, 0x641821, 0x306300ff,
-0x8002f4f, 0xaee35240, 0x8ee201cc, 0x8ee30e10,
-0x441021, 0xaee201cc, 0x8ee201d8, 0x641821,
-0x306301ff, 0xaee30e10, 0x441021, 0xaee201d8,
-0x8ee20000, 0x34420040, 0x8002f5c, 0xaee20000,
-0x8ee2014c, 0x3c010001, 0x370821, 0xa02083e0,
-0x24420001, 0xaee2014c, 0x8ee2014c, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x8f820108,
-0x27633000, 0x43102b, 0x14400002, 0x27622800,
-0xaf820108, 0x8f830108, 0x8f820104, 0x1462fc1e,
-0x0, 0x8fbf0060, 0x8fbe005c, 0x8fb60058,
-0x8fb50054, 0x8fb40050, 0x8fb3004c, 0x8fb20048,
-0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0068,
-0x52843, 0x10a0000d, 0x3021, 0x3c030001,
-0x34633800, 0x3c07ffff, 0x3631021, 0x82102b,
-0x50400001, 0x872021, 0x94820000, 0x24840002,
-0x24a5ffff, 0x14a0fff8, 0xc23021, 0x61c02,
-0x30c2ffff, 0x623021, 0x61c02, 0x30c2ffff,
-0x623021, 0x3e00008, 0x30c2ffff, 0x27bdff88,
-0x240f0001, 0xafbf0070, 0xafbe006c, 0xafb60068,
-0xafb50064, 0xafb40060, 0xafb3005c, 0xafb20058,
-0xafb10054, 0xafb00050, 0xa3a00027, 0xafaf002c,
-0x8ee204d4, 0x8021, 0x30420001, 0x1440002a,
-0xa3a00037, 0x8f8700e0, 0x8f8800c4, 0x8f8200e8,
-0xe22023, 0x2c821000, 0x50400001, 0x24841000,
-0x420c2, 0x801821, 0x8ee400c8, 0x8ee500cc,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaee400c8, 0xaee500cc, 0x8f8300c8,
-0x3c02000a, 0x3442efff, 0x1032023, 0x44102b,
-0x10400003, 0x3c02000a, 0x3442f000, 0x822021,
-0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021,
-0xa32821, 0xa3302b, 0x822021, 0x862021,
-0xaee400c0, 0xaee500c4, 0xaf8800c8, 0xaf8700e4,
-0x80034cc, 0xaf8700e8, 0x3c020001, 0x571021,
-0x904283c0, 0x1040000b, 0x0, 0x3c140001,
-0x297a021, 0x8e9483c4, 0x3c130001, 0x2779821,
-0x8e7383c8, 0x3c120001, 0x2579021, 0x8003193,
-0x8e5283cc, 0x8f8300e0, 0x8f8200e4, 0x10430007,
-0x8821, 0x8f8200e4, 0x24110001, 0x8c430000,
-0x8c440004, 0xafa30018, 0xafa4001c, 0x1620000e,
-0x3c02ffff, 0x8f8200c4, 0xafa20010, 0x8f8200c8,
-0x3c040001, 0x24845870, 0xafa20014, 0x8f8600e0,
-0x8f8700e4, 0x3c050006, 0xc002403, 0x34a5f000,
-0x80034cc, 0x0, 0x8fa3001c, 0x8fb20018,
-0x3074ffff, 0x2694fffc, 0x621024, 0x10400058,
-0x2409821, 0x3c020080, 0x621024, 0x1040000a,
-0x3c040040, 0x8ee2007c, 0x24420001, 0xaee2007c,
-0x8ee2007c, 0x8ee201fc, 0x24420001, 0xaee201fc,
-0x80034c6, 0x8ee201fc, 0x3c060004, 0x3c0b0001,
-0x3c0a0002, 0x3c050010, 0x3c090008, 0x8ee20080,
-0x3c080020, 0x34078000, 0x24420001, 0xaee20080,
-0x8ee20080, 0x8fa2001c, 0x441824, 0x10660021,
-0xc3102b, 0x14400007, 0x0, 0x106b0011,
-0x0, 0x106a0015, 0x0, 0x8003049,
-0x42042, 0x10650023, 0xa3102b, 0x14400005,
-0x0, 0x10690019, 0x0, 0x8003049,
-0x42042, 0x10680021, 0x0, 0x8003049,
-0x42042, 0x8ee20034, 0x24420001, 0xaee20034,
-0x8ee20034, 0x8003049, 0x42042, 0x8ee201ec,
-0x24420001, 0xaee201ec, 0x8ee201ec, 0x8003049,
-0x42042, 0x8ee201f0, 0x24420001, 0xaee201f0,
-0x8ee201f0, 0x8003049, 0x42042, 0x8ee201f4,
-0x24420001, 0xaee201f4, 0x8ee201f4, 0x8003049,
-0x42042, 0x8ee20030, 0x24420001, 0xaee20030,
-0x8ee20030, 0x8003049, 0x42042, 0x8ee201f8,
-0x24420001, 0xaee201f8, 0x8ee201f8, 0x42042,
-0x1087047c, 0x0, 0x800300e, 0x0,
-0x3c020001, 0x571021, 0x904283b2, 0x14400084,
-0x24020001, 0x3c030001, 0x771821, 0x906383b3,
-0x1462007f, 0x3c020100, 0x8e430000, 0x621024,
-0x1040006f, 0x2402ffff, 0x14620005, 0x24100001,
-0x96430004, 0x3402ffff, 0x10620075, 0x0,
-0x92e204d8, 0x14400072, 0x0, 0x3c020001,
-0x571021, 0x8c4283b4, 0x28420005, 0x10400020,
-0x3821, 0x3c020001, 0x571021, 0x8c4283b4,
-0x18400016, 0x2821, 0x96660000, 0x520c0,
-0x971021, 0x9442777e, 0x14460009, 0x971021,
-0x94437780, 0x96620002, 0x14620005, 0x971021,
-0x94437782, 0x96620004, 0x50620008, 0x24070001,
-0x3c020001, 0x571021, 0x8c4283b4, 0x24a50001,
-0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff,
-0x10400440, 0x0, 0x80030d5, 0x0,
-0x2402021, 0xc0022fe, 0x24050006, 0x3044001f,
-0x428c0, 0x2e51021, 0x9442727c, 0x30424000,
-0x14400434, 0xb71021, 0x9443727e, 0x96620000,
-0x1462000b, 0x418c0, 0xb71021, 0x94437280,
-0x96620002, 0x14620006, 0x418c0, 0xb71021,
-0x94437282, 0x96620004, 0x10620035, 0x418c0,
-0x2e31021, 0x9442727c, 0x30428000, 0x14400421,
-0x2e31021, 0x944b727c, 0x96670000, 0xb28c0,
-0xb71021, 0x9442737e, 0x80030b7, 0x3021,
-0x420c0, 0x2e41021, 0x9443737c, 0x2e41021,
-0x944b737c, 0x30638000, 0x14600010, 0xb28c0,
-0xb71021, 0x9442737e, 0x1447fff5, 0x1602021,
-0xb71021, 0x94437380, 0x96620002, 0x5462fff1,
-0x420c0, 0xb71021, 0x94437382, 0x96620004,
-0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff,
-0x10400400, 0x0, 0x80030d5, 0x0,
-0x97430202, 0x96420000, 0x146203fa, 0x0,
-0x97430204, 0x96420002, 0x146203f6, 0x0,
-0x97430206, 0x96420004, 0x146203f2, 0x0,
-0x92420000, 0x3a030001, 0x30420001, 0x431024,
-0x10400074, 0x2402ffff, 0x8e630000, 0x14620004,
-0x3402ffff, 0x96630004, 0x1062006f, 0x240f0002,
-0x3c020001, 0x571021, 0x904283b2, 0x1440006a,
-0x240f0003, 0x92e204d8, 0x54400068, 0xafaf002c,
-0x3c020001, 0x571021, 0x8c4283b4, 0x28420005,
-0x10400020, 0x3821, 0x3c020001, 0x571021,
-0x8c4283b4, 0x18400016, 0x2821, 0x96660000,
-0x520c0, 0x971021, 0x9442777e, 0x14460009,
-0x971021, 0x94437780, 0x96620002, 0x14620005,
-0x971021, 0x94437782, 0x96620004, 0x50620008,
-0x24070001, 0x3c020001, 0x571021, 0x8c4283b4,
-0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0,
-0x30e200ff, 0x14400044, 0x240f0003, 0x80034c6,
-0x0, 0x2402021, 0xc0022fe, 0x24050006,
-0x3044001f, 0x428c0, 0x2e51021, 0x9442727c,
-0x30424000, 0x144003af, 0xb71021, 0x9443727e,
-0x96620000, 0x1462000b, 0x418c0, 0xb71021,
-0x94437280, 0x96620002, 0x14620006, 0x418c0,
-0xb71021, 0x94437282, 0x96620004, 0x10620027,
-0x418c0, 0x2e31021, 0x9442727c, 0x30428000,
-0x1440039c, 0x2e31021, 0x944b727c, 0x96670000,
-0xb28c0, 0xb71021, 0x9442737e, 0x800313c,
-0x3021, 0x420c0, 0x2e41021, 0x9443737c,
-0x2e41021, 0x944b737c, 0x30638000, 0x14600010,
-0xb28c0, 0xb71021, 0x9442737e, 0x1447fff5,
-0x1602021, 0xb71021, 0x94437380, 0x96620002,
-0x5462fff1, 0x420c0, 0xb71021, 0x94437382,
-0x96620004, 0x5462ffec, 0x420c0, 0x24060001,
-0x30c200ff, 0x1040037b, 0x0, 0x800314f,
-0x240f0003, 0x240f0001, 0xafaf002c, 0x8f420260,
-0x54102b, 0x1040003a, 0x0, 0x8f8300e4,
-0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4,
-0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2801821,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058,
-0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c,
-0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0,
-0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845878,
-0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006,
-0xc002403, 0x34a5f003, 0x80034cc, 0x0,
-0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001,
-0x24845884, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
-0x3c050006, 0xc002403, 0x34a5f002, 0x8ee201c0,
-0x24420001, 0xaee201c0, 0x8ee20000, 0x8ee301c0,
-0x2403ffbf, 0x431024, 0x8003470, 0xaee20000,
-0x96e20468, 0x54102b, 0x10400003, 0x0,
-0x240f0001, 0xa3af0027, 0x12800301, 0x24160007,
-0x24150040, 0x241e0001, 0x240e0012, 0x8ee2724c,
-0x8f430280, 0x24420001, 0x304207ff, 0x106202d3,
-0x0, 0x93a20027, 0x10400014, 0x0,
-0x8ee35240, 0x8ee25244, 0x10620009, 0x26ed5244,
-0x8ee65244, 0x8ee35244, 0x21140, 0x24425248,
-0x2e28021, 0x24630001, 0x80031bf, 0x306b00ff,
-0x92e27248, 0x1440ffca, 0x0, 0x8ee201e0,
-0x24420001, 0xaee201e0, 0x8ee201e0, 0x8ee30e10,
-0x8ee20e18, 0x1062ffc2, 0x26ed0e18, 0x8ee60e18,
-0x8ee30e18, 0x21140, 0x24420e20, 0x2e28021,
-0x24630001, 0x306b01ff, 0x96e2046a, 0x30420010,
-0x10400019, 0x0, 0x9642000c, 0x340f8100,
-0x144f0015, 0x0, 0x3c020001, 0x571021,
-0x904283c0, 0x14400010, 0x0, 0x9642000e,
-0xa6020016, 0x8e420008, 0x8e430004, 0x8e440000,
-0x2694fffc, 0xae42000c, 0xae430008, 0xae440004,
-0x9602000e, 0x26730004, 0x240f0001, 0xa3af0037,
-0x34420200, 0xa602000e, 0x8e020000, 0x8e030004,
-0x3c040001, 0x34843800, 0x306a0007, 0x26a9823,
-0x3641021, 0x262102b, 0x10400005, 0x28aa021,
-0x2641023, 0x3621823, 0x3c020020, 0x439823,
-0x26820007, 0x2404fff8, 0x9603000a, 0x446024,
-0x6a1821, 0x6c102b, 0x10400002, 0x1803821,
-0x603821, 0xae130018, 0x8f880120, 0x24e20007,
-0x443824, 0x27623800, 0x25090020, 0x122102b,
-0x50400001, 0x27693000, 0x8f820128, 0x11220004,
-0x0, 0x8f820124, 0x15220007, 0x1401821,
-0x8ee201a4, 0x8821, 0x24420001, 0xaee201a4,
-0x800324c, 0x8ee201a4, 0x8e040000, 0x8e050004,
-0x1021, 0xad130008, 0xa507000e, 0xad160018,
-0xad06001c, 0xa3302b, 0xa32823, 0x822023,
-0x862023, 0xad040000, 0xad050004, 0x8ee204c0,
-0xad020010, 0xaf890120, 0x92e24e20, 0x14400033,
-0x24110001, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c820000, 0x1456001f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062001b, 0x0,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee34e30, 0x24420001, 0x10550007, 0x0,
-0x8ee24e34, 0x24420001, 0x10620005, 0x0,
-0x8003239, 0x0, 0x14600005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
-0x800324c, 0x0, 0x8ee24e30, 0x24420001,
-0x50550003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0xac960000, 0xac9e0004, 0x16200018,
-0x3c050006, 0x8e020018, 0x3c040001, 0x24845890,
-0xafa20010, 0x8e020000, 0x8e030004, 0x34a5f009,
-0x2003021, 0xc002403, 0xafa30014, 0x93a20037,
-0x10400216, 0x340f8100, 0x8e420004, 0x8e430008,
-0x8e44000c, 0xa64f000c, 0xae420000, 0xae430004,
-0xae440008, 0x96020016, 0x8003470, 0xa642000e,
-0x14ec0168, 0x28a1823, 0x960c000a, 0x9603000e,
-0x28a1023, 0xa602000a, 0x34620004, 0xa602000e,
-0x8f880120, 0x27623800, 0x25090020, 0x122102b,
-0x14400002, 0x306affff, 0x27693000, 0x8f820128,
-0x11220004, 0x0, 0x8f820124, 0x15220007,
-0x24040020, 0x8ee201a4, 0x8821, 0x24420001,
-0xaee201a4, 0x80032ca, 0x8ee201a4, 0x8ee5724c,
-0x8ee60490, 0x8ee70494, 0xa504000e, 0x24040004,
-0xad100008, 0xad040018, 0x52940, 0xa01821,
-0x1021, 0xe33821, 0xe3202b, 0xc23021,
-0xc43021, 0xad060000, 0xad070004, 0x8ee2724c,
-0xad02001c, 0x8ee204c4, 0xad020010, 0xaf890120,
-0x92e24e20, 0x14400033, 0x24110001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c820000,
-0x1456001f, 0x0, 0x8ee34e30, 0x8ee24e34,
-0x1062001b, 0x0, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001,
-0x10550007, 0x0, 0x8ee24e34, 0x24420001,
-0x10620005, 0x0, 0x80032b7, 0x0,
-0x14600005, 0x0, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
-0x50400010, 0xac800000, 0x80032ca, 0x0,
-0x8ee24e30, 0x24420001, 0x50550003, 0x1021,
-0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0xac960000,
-0xac9e0004, 0x1620000d, 0x0, 0xa60c000a,
-0xa60a000e, 0x8f820100, 0xafa20010, 0x8f820104,
-0x3c040001, 0x2484589c, 0x3c050006, 0xafa20014,
-0x8ee6724c, 0x800343b, 0x34a5f00b, 0x3c010001,
-0x370821, 0xa02083c0, 0xadab0000, 0x8ee201d8,
-0x8ee3724c, 0x2442ffff, 0xaee201d8, 0x8ee201d8,
-0x24630001, 0x306307ff, 0x26e25244, 0x15a20006,
-0xaee3724c, 0x8ee201d0, 0x2442ffff, 0xaee201d0,
-0x80032ef, 0x8ee201d0, 0x8ee201cc, 0x2442ffff,
-0xaee201cc, 0x8ee201cc, 0x8f420240, 0x10400073,
-0x0, 0x8ee20e1c, 0x24420001, 0xaee20e1c,
-0x8f430240, 0x43102b, 0x14400176, 0xa021,
-0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
-0x50400001, 0x27663000, 0x8f820128, 0x10c20004,
-0x0, 0x8f820124, 0x14c20007, 0x0,
-0x8ee201a4, 0x8821, 0x24420001, 0xaee201a4,
-0x800334f, 0x8ee201a4, 0x8ee2724c, 0xac62001c,
-0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008,
-0x24020008, 0xa462000e, 0x24020011, 0xac620018,
-0xac640000, 0xac650004, 0x8ee204c4, 0xac620010,
-0xaf860120, 0x92e24e20, 0x14400033, 0x24110001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c820000, 0x144e001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x10550007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x800333c,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400010, 0xac800000, 0x800334f,
-0x0, 0x8ee24e30, 0x24420001, 0x50550003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0xac8e0000, 0xac9e0004, 0x5620000d, 0x24110001,
-0x8ee2724c, 0x3c040001, 0x248458a8, 0xafa00014,
-0xafa20010, 0x8ee6724c, 0x8f470280, 0x3c050009,
-0x34a5f008, 0xc002403, 0xafae0048, 0x8fae0048,
-0x56200001, 0xaee00e1c, 0x8ee20188, 0x24420001,
-0xaee20188, 0x80033c8, 0x8ee20188, 0x8f830120,
-0x27623800, 0x24660020, 0xc2102b, 0x50400001,
-0x27663000, 0x8f820128, 0x10c20004, 0x0,
-0x8f820124, 0x14c20007, 0x0, 0x8ee201a4,
-0x8821, 0x24420001, 0xaee201a4, 0x80033ba,
-0x8ee201a4, 0x8ee2724c, 0xac62001c, 0x8ee404a8,
-0x8ee504ac, 0x2462001c, 0xac620008, 0x24020008,
-0xa462000e, 0x24020011, 0xac620018, 0xac640000,
-0xac650004, 0x8ee204c4, 0xac620010, 0xaf860120,
-0x92e24e20, 0x14400033, 0x24110001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c820000,
-0x144e001f, 0x0, 0x8ee34e30, 0x8ee24e34,
-0x1062001b, 0x0, 0x8c820004, 0x24420001,
-0xac820004, 0x8ee24e34, 0x8ee34e30, 0x24420001,
-0x10550007, 0x0, 0x8ee24e34, 0x24420001,
-0x10620005, 0x0, 0x80033a7, 0x0,
-0x14600005, 0x0, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
-0x50400010, 0xac800000, 0x80033ba, 0x0,
-0x8ee24e30, 0x24420001, 0x50550003, 0x1021,
-0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0xac8e0000,
-0xac9e0004, 0x1620000d, 0x0, 0x8ee2724c,
-0x3c040001, 0x248458a8, 0xafa00014, 0xafa20010,
-0x8ee6724c, 0x8f470280, 0x3c050009, 0x34a5f008,
-0xc002403, 0xafae0048, 0x8fae0048, 0x8ee20174,
-0x24420001, 0xaee20174, 0x8ee20174, 0x800346e,
-0xa021, 0x960c000a, 0x183102b, 0x54400001,
-0x1801821, 0xa603000a, 0x8f880120, 0x27623800,
-0x25090020, 0x122102b, 0x50400001, 0x27693000,
-0x8f820128, 0x11220004, 0x0, 0x8f820124,
-0x15220007, 0x24040020, 0x8ee201a4, 0x8821,
-0x24420001, 0xaee201a4, 0x800342f, 0x8ee201a4,
-0x8ee5724c, 0x8ee60490, 0x8ee70494, 0xa504000e,
-0x24040004, 0xad100008, 0xad040018, 0x52940,
-0xa01821, 0x1021, 0xe33821, 0xe3202b,
-0xc23021, 0xc43021, 0xad060000, 0xad070004,
-0x8ee2724c, 0xad02001c, 0x8ee204c4, 0xad020010,
-0xaf890120, 0x92e24e20, 0x14400033, 0x24110001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c820000, 0x1456001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x10550007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x800341c,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400010, 0xac800000, 0x800342f,
-0x0, 0x8ee24e30, 0x24420001, 0x50550003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0xac960000, 0xac9e0004, 0x1620001d, 0x0,
-0xa60c000a, 0x8f820100, 0xafa20010, 0x8f820104,
-0x3c040001, 0x2484589c, 0x3c050006, 0xafa20014,
-0x8ee6724c, 0x34a5f00d, 0xc002403, 0x2003821,
-0x93a20037, 0x10400031, 0x340f8100, 0x8e420004,
-0x8e430008, 0x8e44000c, 0xa64f000c, 0xae420000,
-0xae430004, 0xae440008, 0x96020016, 0xa642000e,
-0x9602000e, 0x3042fdff, 0x8003470, 0xa602000e,
-0x8ee201d8, 0x2442ffff, 0xaee201d8, 0x8ee201d8,
-0x8ee201cc, 0x3c04001f, 0x3c010001, 0x370821,
-0xa03e83c0, 0x2442ffff, 0xaee201cc, 0x9603000a,
-0x3484ffff, 0x8ee201cc, 0x6a1821, 0x2639821,
-0x93202b, 0x10800003, 0x3c02fff5, 0x34421000,
-0x2629821, 0xadab0000, 0x8ee2724c, 0x24420001,
-0x304207ff, 0xaee2724c, 0x8f420240, 0x10400004,
-0x283a023, 0x8ee20e1c, 0x24420001, 0xaee20e1c,
-0xa3a00027, 0x1680fd29, 0x0, 0x12800024,
-0x0, 0x3c010001, 0x370821, 0xac3483c4,
-0x3c010001, 0x370821, 0xac3383c8, 0x3c010001,
-0x370821, 0xac3283cc, 0x93a20037, 0x10400008,
-0x0, 0x3c020001, 0x571021, 0x8c4283cc,
-0x24420004, 0x3c010001, 0x370821, 0xac2283cc,
-0x8ee2724c, 0x8f430280, 0x24420001, 0x304207ff,
-0x14620006, 0x0, 0x8ee201c4, 0x24420001,
-0xaee201c4, 0x80034cc, 0x8ee201c4, 0x8ee201bc,
-0x24420001, 0xaee201bc, 0x80034cc, 0x8ee201bc,
-0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0,
-0x8ee500c4, 0x1021, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0xaee400c0, 0xaee500c4,
-0x8faf002c, 0x24020002, 0x11e2000f, 0x29e20003,
-0x14400017, 0x24020003, 0x15e20015, 0x0,
-0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001,
-0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0,
-0x80034c6, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc,
-0x24630001, 0x2c640001, 0x441021, 0xaee200d8,
-0xaee300dc, 0x8ee200d8, 0x80034c6, 0x8ee300dc,
-0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001,
-0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8,
-0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003,
-0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8fbf0070,
-0x8fbe006c, 0x8fb60068, 0x8fb50064, 0x8fb40060,
-0x8fb3005c, 0x8fb20058, 0x8fb10054, 0x8fb00050,
-0x3e00008, 0x27bd0078, 0x27bdffb0, 0xafb50044,
-0xa821, 0xafb00030, 0x8021, 0xafbf004c,
-0xafb60048, 0xafb40040, 0xafb3003c, 0xafb20038,
-0xafb10034, 0x8ee204d4, 0x24140001, 0x30420001,
-0x1440002a, 0xb021, 0x8f8700e0, 0x8f8800c4,
-0x8f8200e8, 0xe22023, 0x2c821000, 0x50400001,
-0x24841000, 0x420c2, 0x801821, 0x8ee400c8,
-0x8ee500cc, 0x1021, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0xaee400c8, 0xaee500cc,
-0x8f8300c8, 0x3c02000a, 0x3442efff, 0x1032023,
-0x44102b, 0x10400003, 0x3c02000a, 0x3442f000,
-0x822021, 0x801821, 0x8ee400c0, 0x8ee500c4,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8,
-0xaf8700e4, 0x8003850, 0xaf8700e8, 0x3c020001,
-0x571021, 0x904283c0, 0x1040000b, 0x0,
-0x3c130001, 0x2779821, 0x8e7383c4, 0x3c110001,
-0x2378821, 0x8e3183c8, 0x3c120001, 0x2579021,
-0x80036e8, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4,
-0x10430007, 0x4821, 0x8f8200e4, 0x24090001,
-0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c,
-0x1520000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010,
-0x8f8200c8, 0x3c040001, 0x24845870, 0xafa20014,
-0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403,
-0x34a5f000, 0x8003850, 0x0, 0x8fa3001c,
-0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024,
-0x10400058, 0x2408821, 0x3c020080, 0x621024,
-0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001,
-0xaee2007c, 0x8ee2007c, 0x8ee201fc, 0x24420001,
-0xaee201fc, 0x800384a, 0x8ee201fc, 0x3c060004,
-0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008,
-0x8ee20080, 0x3c080020, 0x34078000, 0x24420001,
-0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824,
-0x10660021, 0xc3102b, 0x14400007, 0x0,
-0x106b0011, 0x0, 0x106a0015, 0x0,
-0x8003592, 0x42042, 0x10650023, 0xa3102b,
-0x14400005, 0x0, 0x10690019, 0x0,
-0x8003592, 0x42042, 0x10680021, 0x0,
-0x8003592, 0x42042, 0x8ee20034, 0x24420001,
-0xaee20034, 0x8ee20034, 0x8003592, 0x42042,
-0x8ee201ec, 0x24420001, 0xaee201ec, 0x8ee201ec,
-0x8003592, 0x42042, 0x8ee201f0, 0x24420001,
-0xaee201f0, 0x8ee201f0, 0x8003592, 0x42042,
-0x8ee201f4, 0x24420001, 0xaee201f4, 0x8ee201f4,
-0x8003592, 0x42042, 0x8ee20030, 0x24420001,
-0xaee20030, 0x8ee20030, 0x8003592, 0x42042,
-0x8ee201f8, 0x24420001, 0xaee201f8, 0x8ee201f8,
-0x42042, 0x108702b7, 0x0, 0x8003557,
-0x0, 0x3c020001, 0x571021, 0x904283b2,
-0x14400084, 0x24020001, 0x3c030001, 0x771821,
-0x906383b3, 0x1462007f, 0x3c020100, 0x8e430000,
-0x621024, 0x1040006f, 0x2402ffff, 0x14620005,
-0x24100001, 0x96430004, 0x3402ffff, 0x10620075,
-0x0, 0x92e204d8, 0x14400072, 0x0,
-0x3c020001, 0x571021, 0x8c4283b4, 0x28420005,
-0x10400020, 0x3821, 0x3c020001, 0x571021,
-0x8c4283b4, 0x18400016, 0x2821, 0x96260000,
-0x520c0, 0x971021, 0x9442777e, 0x14460009,
-0x971021, 0x94437780, 0x96220002, 0x14620005,
-0x971021, 0x94437782, 0x96220004, 0x50620008,
-0x24070001, 0x3c020001, 0x571021, 0x8c4283b4,
-0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0,
-0x30e200ff, 0x1040027b, 0x0, 0x800361e,
-0x0, 0x2402021, 0xc0022fe, 0x24050006,
-0x3044001f, 0x428c0, 0x2e51021, 0x9442727c,
-0x30424000, 0x1440026f, 0xb71021, 0x9443727e,
-0x96220000, 0x1462000b, 0x418c0, 0xb71021,
-0x94437280, 0x96220002, 0x14620006, 0x418c0,
-0xb71021, 0x94437282, 0x96220004, 0x10620035,
-0x418c0, 0x2e31021, 0x9442727c, 0x30428000,
-0x1440025c, 0x2e31021, 0x9448727c, 0x96270000,
-0x828c0, 0xb71021, 0x9442737e, 0x8003600,
-0x3021, 0x420c0, 0x2e41021, 0x9443737c,
-0x2e41021, 0x9448737c, 0x30638000, 0x14600010,
-0x828c0, 0xb71021, 0x9442737e, 0x1447fff5,
-0x1002021, 0xb71021, 0x94437380, 0x96220002,
-0x5462fff1, 0x420c0, 0xb71021, 0x94437382,
-0x96220004, 0x5462ffec, 0x420c0, 0x24060001,
-0x30c200ff, 0x1040023b, 0x0, 0x800361e,
-0x0, 0x97430202, 0x96420000, 0x14620235,
-0x0, 0x97430204, 0x96420002, 0x14620231,
-0x0, 0x97430206, 0x96420004, 0x1462022d,
-0x0, 0x92420000, 0x3a030001, 0x30420001,
-0x431024, 0x10400074, 0x2402ffff, 0x8e230000,
-0x14620004, 0x3402ffff, 0x96230004, 0x1062006f,
-0x24140002, 0x3c020001, 0x571021, 0x904283b2,
-0x1440006a, 0x24140003, 0x92e204d8, 0x14400067,
-0x0, 0x3c020001, 0x571021, 0x8c4283b4,
-0x28420005, 0x10400020, 0x3821, 0x3c020001,
-0x571021, 0x8c4283b4, 0x18400016, 0x2821,
-0x96260000, 0x520c0, 0x971021, 0x9442777e,
-0x14460009, 0x971021, 0x94437780, 0x96220002,
-0x14620005, 0x971021, 0x94437782, 0x96220004,
-0x50620008, 0x24070001, 0x3c020001, 0x571021,
-0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee,
-0x520c0, 0x30e200ff, 0x14400044, 0x24140003,
-0x800384a, 0x0, 0x2402021, 0xc0022fe,
-0x24050006, 0x3044001f, 0x428c0, 0x2e51021,
-0x9442727c, 0x30424000, 0x144001ea, 0xb71021,
-0x9443727e, 0x96220000, 0x1462000b, 0x418c0,
-0xb71021, 0x94437280, 0x96220002, 0x14620006,
-0x418c0, 0xb71021, 0x94437282, 0x96220004,
-0x10620027, 0x418c0, 0x2e31021, 0x9442727c,
-0x30428000, 0x144001d7, 0x2e31021, 0x9448727c,
-0x96270000, 0x828c0, 0xb71021, 0x9442737e,
-0x8003685, 0x3021, 0x420c0, 0x2e41021,
-0x9443737c, 0x2e41021, 0x9448737c, 0x30638000,
-0x14600010, 0x828c0, 0xb71021, 0x9442737e,
-0x1447fff5, 0x1002021, 0xb71021, 0x94437380,
-0x96220002, 0x5462fff1, 0x420c0, 0xb71021,
-0x94437382, 0x96220004, 0x5462ffec, 0x420c0,
-0x24060001, 0x30c200ff, 0x104001b6, 0x0,
-0x8003698, 0x24140003, 0x24140001, 0x8f420260,
-0x53102b, 0x10400049, 0x0, 0x8f8300e4,
-0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4,
-0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2601821,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058,
-0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c,
-0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0,
-0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845878,
-0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006,
-0xc002403, 0x34a5f003, 0x8003850, 0x0,
-0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001,
-0x24845884, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
-0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001,
-0xaee201c0, 0x8ee20000, 0x8ee301c0, 0x2403ffbf,
-0x431024, 0x80037f8, 0xaee20000, 0x8ee25240,
-0xafa20010, 0x8ee25244, 0x3c040001, 0x24845884,
-0xafa20014, 0x8ee60e10, 0x8ee70e18, 0x3c050006,
-0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001,
-0xaee201c0, 0x80037f8, 0x8ee201c0, 0x96e20468,
-0x53102b, 0x54400001, 0x3c158000, 0x12600131,
-0x3c0c001f, 0x358cffff, 0x8ee2724c, 0x8f430280,
-0x24420001, 0x304207ff, 0x10620108, 0x0,
-0x12a00014, 0x0, 0x8ee35240, 0x8ee25244,
-0x10620009, 0x26ee5244, 0x8eeb5244, 0x8ee35244,
-0x21140, 0x24425248, 0x2e28021, 0x24630001,
-0x8003712, 0x306800ff, 0x92e27248, 0x1440ffc0,
-0x3c050006, 0x8ee201e0, 0x24420001, 0xaee201e0,
-0x8ee201e0, 0x8ee30e10, 0x8ee20e18, 0x1062ffcb,
-0x26ee0e18, 0x8eeb0e18, 0xa821, 0x8ee30e18,
-0x21140, 0x24420e20, 0x2e28021, 0x24630001,
-0x306801ff, 0x96e2046a, 0x30420010, 0x10400017,
-0x34028100, 0x9643000c, 0x14620014, 0x0,
-0x3c020001, 0x571021, 0x904283c0, 0x1440000f,
-0x0, 0x9642000e, 0xa6020016, 0x8e420008,
-0x8e430004, 0x8e440000, 0x2673fffc, 0xae42000c,
-0xae430008, 0xae440004, 0x9602000e, 0x26310004,
-0x24160001, 0x34420200, 0xa602000e, 0x9603000a,
-0x2605021, 0x73102b, 0x10400002, 0x2606821,
-0x605021, 0x2d42003d, 0x1040002a, 0x3821,
-0x9623000c, 0x24020800, 0x54620027, 0xae110018,
-0x3c020001, 0x571021, 0x904283c0, 0x54400022,
-0xae110018, 0x26220017, 0x182102b, 0x10400013,
-0x0, 0x3c02fff5, 0x511021, 0x90421017,
-0x38430006, 0x2c630001, 0x38420011, 0x2c420001,
-0x621825, 0x10600013, 0x26220010, 0x182102b,
-0x1040000e, 0x0, 0x3c07fff5, 0xf13821,
-0x94e71010, 0x800375e, 0x24e7000e, 0x92220017,
-0x38430006, 0x2c630001, 0x38420011, 0x2c420001,
-0x621825, 0x50600004, 0xae110018, 0x96270010,
-0x24e7000e, 0xae110018, 0x3c020001, 0x571021,
-0x904283c0, 0x2102b, 0x14e00002, 0x24ec0,
-0x1403821, 0x8f830120, 0x27623800, 0x24660020,
-0xc2102b, 0x50400001, 0x27663000, 0x8f820128,
-0x10c20004, 0x0, 0x8f820124, 0x14c20007,
-0x2402000b, 0x8ee201a4, 0x4821, 0x24420001,
-0xaee201a4, 0x80037bf, 0x8ee201a4, 0x8e040000,
-0x8e050004, 0xac620018, 0x1751025, 0x491025,
-0xac710008, 0xa467000e, 0xac62001c, 0xac640000,
-0xac650004, 0x8ee204c0, 0xac620010, 0xaf860120,
-0x92e24e20, 0x14400038, 0x24090001, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c830000,
-0x24020007, 0x14620020, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001c, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee34e34, 0x8ee54e30,
-0x24020040, 0x24630001, 0x10620007, 0x0,
-0x8ee24e34, 0x24420001, 0x10a20005, 0x0,
-0x80037a9, 0x0, 0x14a00005, 0x0,
-0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
-0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
-0x80037bf, 0x0, 0x8ee24e30, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020007, 0xac820000,
-0x24020001, 0xac820004, 0x15200018, 0x3c050006,
-0x8e020018, 0x3c040001, 0x24845890, 0xafa20010,
-0x8e020000, 0x8e030004, 0x34a5f009, 0x2003021,
-0xc002403, 0xafa30014, 0x32c200ff, 0x1040002b,
-0x34028100, 0x8e430004, 0x8e440008, 0x8e45000c,
-0xa642000c, 0xae430000, 0xae440004, 0xae450008,
-0x96020016, 0x80037f8, 0xa642000e, 0x154d000a,
-0x0, 0x9602000e, 0xa613000a, 0x34420004,
-0xa602000e, 0x3c010001, 0x370821, 0xa02083c0,
-0x80037f6, 0x9821, 0x9604000a, 0x93102b,
-0x10400002, 0x2601821, 0x801821, 0x24020001,
-0xa603000a, 0x3c010001, 0x370821, 0xa02283c0,
-0x9604000a, 0x2248821, 0x191102b, 0x10400003,
-0x3c02fff5, 0x34421000, 0x2228821, 0x2649823,
-0xa821, 0x1660fef4, 0xadc80000, 0x12600021,
-0x32c200ff, 0x3c010001, 0x370821, 0xac3383c4,
-0x3c010001, 0x370821, 0xac3183c8, 0x3c010001,
-0x370821, 0x10400008, 0xac3283cc, 0x3c020001,
-0x571021, 0x8c4283cc, 0x24420004, 0x3c010001,
-0x370821, 0xac2283cc, 0x8ee2724c, 0x8f430280,
-0x24420001, 0x14620006, 0x0, 0x8ee201c4,
-0x24420001, 0xaee201c4, 0x8003850, 0x8ee201c4,
-0x8ee201bc, 0x24420001, 0xaee201bc, 0x8003850,
-0x8ee201bc, 0x97a4001e, 0x2484fffc, 0x801821,
-0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0x24020002,
-0xaee400c0, 0xaee500c4, 0x1282000f, 0x2a820003,
-0x14400017, 0x24020003, 0x16820015, 0x0,
-0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001,
-0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0,
-0x800384a, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc,
-0x24630001, 0x2c640001, 0x441021, 0xaee200d8,
-0xaee300dc, 0x8ee200d8, 0x800384a, 0x8ee300dc,
-0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001,
-0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8,
-0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003,
-0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8fbf004c,
-0x8fb60048, 0x8fb50044, 0x8fb40040, 0x8fb3003c,
-0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
-0x27bd0050, 0x27bdff90, 0xafb60060, 0xb021,
-0xafbf0068, 0xafbe0064, 0xafb5005c, 0xafb40058,
-0xafb30054, 0xafb20050, 0xafb1004c, 0xafb00048,
-0x8ee204d4, 0x8821, 0x24150001, 0x30420001,
-0x1440002a, 0xa3a0002f, 0x8f8700e0, 0x8f8800c4,
-0x8f8200e8, 0xe22023, 0x2c821000, 0x50400001,
-0x24841000, 0x420c2, 0x801821, 0x8ee400c8,
-0x8ee500cc, 0x1021, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0xaee400c8, 0xaee500cc,
-0x8f8300c8, 0x3c02000a, 0x3442efff, 0x1032023,
-0x44102b, 0x10400003, 0x3c02000a, 0x3442f000,
-0x822021, 0x801821, 0x8ee400c0, 0x8ee500c4,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8,
-0xaf8700e4, 0x8003c5b, 0xaf8700e8, 0x3c020001,
-0x571021, 0x904283c0, 0x1040000b, 0x0,
-0x3c130001, 0x2779821, 0x8e7383c4, 0x3c100001,
-0x2178021, 0x8e1083c8, 0x3c120001, 0x2579021,
-0x8003a59, 0x8e5283cc, 0x8f8300e0, 0x8f8200e4,
-0x10430007, 0x3821, 0x8f8200e4, 0x24070001,
-0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c,
-0x14e0000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010,
-0x8f8200c8, 0x3c040001, 0x248458b4, 0xafa20014,
-0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403,
-0x34a5f200, 0x8003c5b, 0x0, 0x8fa3001c,
-0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024,
-0x10400058, 0x2408021, 0x3c020080, 0x621024,
-0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001,
-0xaee2007c, 0x8ee2007c, 0x8ee201fc, 0x24420001,
-0xaee201fc, 0x8003c55, 0x8ee201fc, 0x3c060004,
-0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008,
-0x8ee20080, 0x3c080020, 0x34078000, 0x24420001,
-0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824,
-0x10660021, 0xc3102b, 0x14400007, 0x0,
-0x106b0011, 0x0, 0x106a0015, 0x0,
-0x8003916, 0x42042, 0x10650023, 0xa3102b,
-0x14400005, 0x0, 0x10690019, 0x0,
-0x8003916, 0x42042, 0x10680021, 0x0,
-0x8003916, 0x42042, 0x8ee20034, 0x24420001,
-0xaee20034, 0x8ee20034, 0x8003916, 0x42042,
-0x8ee201ec, 0x24420001, 0xaee201ec, 0x8ee201ec,
-0x8003916, 0x42042, 0x8ee201f0, 0x24420001,
-0xaee201f0, 0x8ee201f0, 0x8003916, 0x42042,
-0x8ee201f4, 0x24420001, 0xaee201f4, 0x8ee201f4,
-0x8003916, 0x42042, 0x8ee20030, 0x24420001,
-0xaee20030, 0x8ee20030, 0x8003916, 0x42042,
-0x8ee201f8, 0x24420001, 0xaee201f8, 0x8ee201f8,
-0x42042, 0x1087033e, 0x0, 0x80038db,
-0x0, 0x3c020001, 0x571021, 0x904283b2,
-0x14400084, 0x24020001, 0x3c030001, 0x771821,
-0x906383b3, 0x1462007f, 0x3c020100, 0x8e430000,
-0x621024, 0x1040006f, 0x2402ffff, 0x14620005,
-0x24110001, 0x96430004, 0x3402ffff, 0x10620075,
-0x0, 0x92e204d8, 0x14400072, 0x0,
-0x3c020001, 0x571021, 0x8c4283b4, 0x28420005,
-0x10400020, 0x3821, 0x3c020001, 0x571021,
-0x8c4283b4, 0x18400016, 0x2821, 0x96060000,
-0x520c0, 0x971021, 0x9442777e, 0x14460009,
-0x971021, 0x94437780, 0x96020002, 0x14620005,
-0x971021, 0x94437782, 0x96020004, 0x50620008,
-0x24070001, 0x3c020001, 0x571021, 0x8c4283b4,
-0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0,
-0x30e200ff, 0x10400302, 0x0, 0x80039a2,
-0x0, 0x2402021, 0xc0022fe, 0x24050006,
-0x3044001f, 0x428c0, 0x2e51021, 0x9442727c,
-0x30424000, 0x144002f6, 0xb71021, 0x9443727e,
-0x96020000, 0x1462000b, 0x418c0, 0xb71021,
-0x94437280, 0x96020002, 0x14620006, 0x418c0,
-0xb71021, 0x94437282, 0x96020004, 0x10620035,
-0x418c0, 0x2e31021, 0x9442727c, 0x30428000,
-0x144002e3, 0x2e31021, 0x944d727c, 0x96070000,
-0xd28c0, 0xb71021, 0x9442737e, 0x8003984,
-0x3021, 0x420c0, 0x2e41021, 0x9443737c,
-0x2e41021, 0x944d737c, 0x30638000, 0x14600010,
-0xd28c0, 0xb71021, 0x9442737e, 0x1447fff5,
-0x1a02021, 0xb71021, 0x94437380, 0x96020002,
-0x5462fff1, 0x420c0, 0xb71021, 0x94437382,
-0x96020004, 0x5462ffec, 0x420c0, 0x24060001,
-0x30c200ff, 0x104002c2, 0x0, 0x80039a2,
-0x0, 0x97430202, 0x96420000, 0x146202bc,
-0x0, 0x97430204, 0x96420002, 0x146202b8,
-0x0, 0x97430206, 0x96420004, 0x146202b4,
-0x0, 0x92420000, 0x3a230001, 0x30420001,
-0x431024, 0x10400074, 0x2402ffff, 0x8e030000,
-0x14620004, 0x3402ffff, 0x96030004, 0x1062006f,
-0x24150002, 0x3c020001, 0x571021, 0x904283b2,
-0x1440006a, 0x24150003, 0x92e204d8, 0x14400067,
-0x0, 0x3c020001, 0x571021, 0x8c4283b4,
-0x28420005, 0x10400020, 0x3821, 0x3c020001,
-0x571021, 0x8c4283b4, 0x18400016, 0x2821,
-0x96060000, 0x520c0, 0x971021, 0x9442777e,
-0x14460009, 0x971021, 0x94437780, 0x96020002,
-0x14620005, 0x971021, 0x94437782, 0x96020004,
-0x50620008, 0x24070001, 0x3c020001, 0x571021,
-0x8c4283b4, 0x24a50001, 0xa2102a, 0x5440ffee,
-0x520c0, 0x30e200ff, 0x14400044, 0x24150003,
-0x8003c55, 0x0, 0x2402021, 0xc0022fe,
-0x24050006, 0x3044001f, 0x428c0, 0x2e51021,
-0x9442727c, 0x30424000, 0x14400271, 0xb71021,
-0x9443727e, 0x96020000, 0x1462000b, 0x418c0,
-0xb71021, 0x94437280, 0x96020002, 0x14620006,
-0x418c0, 0xb71021, 0x94437282, 0x96020004,
-0x10620027, 0x418c0, 0x2e31021, 0x9442727c,
-0x30428000, 0x1440025e, 0x2e31021, 0x944d727c,
-0x96070000, 0xd28c0, 0xb71021, 0x9442737e,
-0x8003a09, 0x3021, 0x420c0, 0x2e41021,
-0x9443737c, 0x2e41021, 0x944d737c, 0x30638000,
-0x14600010, 0xd28c0, 0xb71021, 0x9442737e,
-0x1447fff5, 0x1a02021, 0xb71021, 0x94437380,
-0x96020002, 0x5462fff1, 0x420c0, 0xb71021,
-0x94437382, 0x96020004, 0x5462ffec, 0x420c0,
-0x24060001, 0x30c200ff, 0x1040023d, 0x0,
-0x8003a1c, 0x24150003, 0x24150001, 0x8f420260,
-0x53102b, 0x10400036, 0x0, 0x8f8300e4,
-0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4,
-0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2601821,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058,
-0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c,
-0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0,
-0xafa20010, 0x8f8200e4, 0x3c040001, 0x248458c0,
-0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006,
-0xc002403, 0x34a5f203, 0x8003c5b, 0x0,
-0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001,
-0x248458cc, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
-0x3c050006, 0xc002403, 0x34a5f202, 0x8ee201c0,
-0x24420001, 0xaee201c0, 0x8003c02, 0x8ee201c0,
-0x96e20468, 0x53102b, 0x54400001, 0x3c168000,
-0x126001cb, 0x3c0e001f, 0x35ceffff, 0x3c0ffff5,
-0x35ef1000, 0x241e0040, 0x8ee2724c, 0x8f430280,
-0x24420001, 0x304207ff, 0x1062019e, 0x0,
-0x12c00012, 0x0, 0x8ee35240, 0x8ee25244,
-0x1062000a, 0x26f85244, 0x8ef45244, 0xafb80024,
-0x8ee35244, 0x21140, 0x24425248, 0x2e28821,
-0x24630001, 0x8003a85, 0x306d00ff, 0x8ee201e0,
-0x24420001, 0xaee201e0, 0x8ee201e0, 0x8ee30e10,
-0x8ee20e18, 0x1062ffca, 0x26f80e18, 0x8ef40e18,
-0xb021, 0xafb80024, 0x8ee30e18, 0x21140,
-0x24420e20, 0x2e28821, 0x24630001, 0x306d01ff,
-0x96e2046a, 0x30420010, 0x10400018, 0x34028100,
-0x9643000c, 0x14620015, 0x0, 0x3c020001,
-0x571021, 0x904283c0, 0x14400010, 0x0,
-0x9642000e, 0xa6220016, 0x8e420008, 0x8e430004,
-0x8e440000, 0x2673fffc, 0xae42000c, 0xae430008,
-0xae440004, 0x9622000e, 0x26100004, 0x24180001,
-0xa3b8002f, 0x34420200, 0xa622000e, 0x8e220000,
-0x8e230004, 0x3c040001, 0x34843800, 0x2003021,
-0x306a0007, 0x20a8023, 0x3641021, 0x202102b,
-0x10400005, 0x26a9821, 0x2041023, 0x3621823,
-0x3c020020, 0x438023, 0x26620007, 0x9623000a,
-0x2418fff8, 0x58c824, 0x6a1821, 0x79102b,
-0x10400002, 0x3206021, 0x606021, 0x1801821,
-0x24620007, 0x2418fff8, 0x586024, 0x26c102b,
-0x14400004, 0x1932823, 0x1832823, 0x8003ac3,
-0xc31021, 0xd31021, 0x4a2023, 0x1c4102b,
-0x54400001, 0x8f2021, 0x25420040, 0x4c102b,
-0x14400035, 0x5821, 0x94c3000c, 0x24020800,
-0x54620032, 0xae260018, 0x3c020001, 0x571021,
-0x904283c0, 0x5440002d, 0xae260018, 0x24c20017,
-0x1c2102b, 0x10400013, 0x0, 0x3c02fff5,
-0x461021, 0x90421017, 0x38430006, 0x2c630001,
-0x38420011, 0x2c420001, 0x621825, 0x10600014,
-0x24c20010, 0x1c2102b, 0x1040000e, 0x0,
-0x3c0bfff5, 0x1665821, 0x956b1010, 0x8003af4,
-0x2562000e, 0x90c20017, 0x38430006, 0x2c630001,
-0x38420011, 0x2c420001, 0x621825, 0x10600005,
-0x1601821, 0x94cb0010, 0x2562000e, 0x4a5821,
-0x1601821, 0x24620007, 0x2418fff8, 0x585824,
-0xc31021, 0x4a2023, 0x1c4102b, 0x10400002,
-0x1632823, 0x8f2021, 0xae260018, 0x3c020001,
-0x571021, 0x904283c0, 0x2102b, 0x216c0,
-0x15600002, 0xafa20044, 0x1805821, 0x30820001,
-0x10400007, 0x4021, 0x90880000, 0x24840001,
-0x1c4102b, 0x10400002, 0x24a5ffff, 0x8f2021,
-0x50a00012, 0x81c02, 0x2ca20002, 0x54400009,
-0x24a5ffff, 0x94820000, 0x24840002, 0x1024021,
-0x1c4102b, 0x10400006, 0x24a5fffe, 0x8003b21,
-0x8f2021, 0x90820000, 0x21200, 0x1024021,
-0x14a0fff2, 0x2ca20002, 0x81c02, 0x3102ffff,
-0x624021, 0x3108ffff, 0x1402821, 0x11400011,
-0x2002021, 0x2ca20002, 0x54400009, 0x24a5ffff,
-0x94820000, 0x24840002, 0x1024021, 0x1c4102b,
-0x10400006, 0x24a5fffe, 0x8003b38, 0x8f2021,
-0x90820000, 0x21200, 0x1024021, 0x14a0fff2,
-0x2ca20002, 0x81c02, 0x3102ffff, 0x624021,
-0x81c02, 0x3102ffff, 0x8f890120, 0x624021,
-0x27623800, 0x25230020, 0x62102b, 0x14400002,
-0x3108ffff, 0x27633000, 0x8f820128, 0x10620004,
-0x0, 0x8f820124, 0x14620007, 0x1402821,
-0x8ee201a4, 0x3821, 0x24420001, 0xaee201a4,
-0x8003bc9, 0x8ee201a4, 0x8e260000, 0x8e270004,
-0x81400, 0x3448000b, 0xad300008, 0xa52b000e,
-0xad280018, 0x8fb80044, 0x2021, 0x2961025,
-0x581025, 0xad22001c, 0xe5102b, 0xe53823,
-0xc43023, 0xc23023, 0xad260000, 0xad270004,
-0x8ee204c0, 0xad220010, 0xaf830120, 0x92e24e20,
-0x1440005f, 0x24070001, 0x2502ffee, 0x2c420002,
-0x14400003, 0x24020011, 0x15020024, 0x0,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c830000, 0x24020012, 0x1462000f, 0x0,
-0x8ee34e30, 0x8ee24e34, 0x1062000b, 0x0,
-0x8c820004, 0x24420001, 0xac820004, 0x8ee24e34,
-0x8ee34e30, 0x24420001, 0x105e002a, 0x0,
-0x8003ba8, 0x0, 0x8ee24e30, 0x24420001,
-0x505e0003, 0x1021, 0x8ee24e30, 0x24420001,
-0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8003bc6, 0x24020012, 0x8ee24e30,
-0x210c0, 0x24425038, 0x2e22021, 0x8c830000,
-0x24020007, 0x1462001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x105e0007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x8003bb4,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400012, 0xac800000, 0x8003bc9,
-0x0, 0x8ee24e30, 0x24420001, 0x505e0003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x24020007, 0xac820000, 0x24020001, 0xac820004,
-0x14e00019, 0x3c050006, 0x3c040001, 0x24845890,
-0x8e220018, 0x34a5f209, 0xafa20010, 0x8e220000,
-0x8e230004, 0x2203021, 0x1603821, 0xc002403,
-0xafa30014, 0x93a2002f, 0x1040002a, 0x34028100,
-0x8e430004, 0x8e440008, 0x8e45000c, 0xa642000c,
-0xae430000, 0xae440004, 0xae450008, 0x96220016,
-0x8003c02, 0xa642000e, 0x1599000a, 0x26a1823,
-0x9622000e, 0xa623000a, 0x34420004, 0xa622000e,
-0x3c010001, 0x370821, 0xa02083c0, 0x8003bff,
-0x9821, 0x9624000a, 0x83102b, 0x54400001,
-0x801821, 0x24020001, 0xa623000a, 0x3c010001,
-0x370821, 0xa02283c0, 0x9622000a, 0x4a1821,
-0x2038021, 0x1d0102b, 0x54400001, 0x20f8021,
-0x2639823, 0xb021, 0x8fb80024, 0x1660fe5e,
-0xaf0d0000, 0x12600022, 0x0, 0x3c010001,
-0x370821, 0xac3383c4, 0x3c010001, 0x370821,
-0xac3083c8, 0x3c010001, 0x370821, 0xac3283cc,
-0x93a2002f, 0x10400008, 0x0, 0x3c020001,
-0x571021, 0x8c4283cc, 0x24420004, 0x3c010001,
-0x370821, 0xac2283cc, 0x8f430280, 0x8ee2724c,
-0x14620006, 0x0, 0x8ee201c4, 0x24420001,
-0xaee201c4, 0x8003c5b, 0x8ee201c4, 0x8ee201bc,
-0x24420001, 0xaee201bc, 0x8003c5b, 0x8ee201bc,
-0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0,
-0x8ee500c4, 0x1021, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0x24020002, 0xaee400c0,
-0xaee500c4, 0x12a2000f, 0x2aa20003, 0x14400017,
-0x24020003, 0x16a20015, 0x0, 0x8ee200d0,
-0x8ee300d4, 0x24630001, 0x2c640001, 0x441021,
-0xaee200d0, 0xaee300d4, 0x8ee200d0, 0x8003c55,
-0x8ee300d4, 0x8ee200d8, 0x8ee300dc, 0x24630001,
-0x2c640001, 0x441021, 0xaee200d8, 0xaee300dc,
-0x8ee200d8, 0x8003c55, 0x8ee300dc, 0x8ee200c8,
-0x8ee300cc, 0x24630001, 0x2c640001, 0x441021,
-0xaee200c8, 0xaee300cc, 0x8ee200c8, 0x8ee300cc,
-0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008,
-0xaf8300e4, 0xaf8300e8, 0x8fbf0068, 0x8fbe0064,
-0x8fb60060, 0x8fb5005c, 0x8fb40058, 0x8fb30054,
-0x8fb20050, 0x8fb1004c, 0x8fb00048, 0x3e00008,
-0x27bd0070, 0x27bdffe0, 0xafbf0018, 0x8ee30e14,
-0x8ee20e0c, 0x10620074, 0x0, 0x8ee30e0c,
-0x8ee20e14, 0x622023, 0x4820001, 0x24840200,
-0x8ee30e18, 0x8ee20e14, 0x43102b, 0x14400004,
-0x24020200, 0x8ee30e14, 0x8003c7d, 0x431823,
-0x8ee20e18, 0x8ee30e14, 0x431023, 0x2443ffff,
-0x804821, 0x69102a, 0x54400001, 0x604821,
-0x8f870100, 0x27623000, 0x24e80020, 0x102102b,
-0x50400001, 0x27682800, 0x8f820108, 0x11020004,
-0x0, 0x8f820104, 0x15020007, 0x1021,
-0x8ee201a8, 0x2021, 0x24420001, 0xaee201a8,
-0x8003cbf, 0x8ee201a8, 0x8ee40e14, 0x42140,
-0x801821, 0x8ee40460, 0x8ee50464, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xace40000,
-0xace50004, 0x8ee30e14, 0x91140, 0xa4e2000e,
-0x24020002, 0xace20018, 0x31940, 0x24630e20,
-0x2e31021, 0xace20008, 0x8ee20e14, 0xace2001c,
-0x8ee204cc, 0xace20010, 0xaf880100, 0x92e204ec,
-0x14400011, 0x24040001, 0x8ee24e28, 0x24030040,
-0x24420001, 0x50430003, 0x1021, 0x8ee24e28,
-0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0,
-0x24424e38, 0x2e21821, 0x24020002, 0xac620000,
-0x24020001, 0xac620004, 0x1480000e, 0x24030040,
-0x8ee20e14, 0xafa20010, 0x8ee20e18, 0x3c050007,
-0xafa20014, 0x8ee60e0c, 0x8ee70e10, 0x3c040001,
-0x248458d4, 0xc002403, 0x34a5f001, 0x8003cdd,
-0x0, 0x8ee20500, 0x24420001, 0x50430003,
-0x1021, 0x8ee20500, 0x24420001, 0xaee20500,
-0x8ee20500, 0x21080, 0x571021, 0xac490508,
-0x8ee20e14, 0x491021, 0x304201ff, 0xaee20e14,
-0x8ee30e14, 0x8ee20e0c, 0x14620005, 0x0,
-0x8f820060, 0x2403fdff, 0x431024, 0xaf820060,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0,
-0xafbf0018, 0x8ee3523c, 0x8ee25238, 0x10620074,
-0x0, 0x8ee35238, 0x8ee2523c, 0x622023,
-0x4820001, 0x24840100, 0x8ee35244, 0x8ee2523c,
-0x43102b, 0x14400004, 0x24020100, 0x8ee3523c,
-0x8003cff, 0x431823, 0x8ee25244, 0x8ee3523c,
-0x431023, 0x2443ffff, 0x804821, 0x69102a,
-0x54400001, 0x604821, 0x8f870100, 0x27623000,
-0x24e80020, 0x102102b, 0x50400001, 0x27682800,
-0x8f820108, 0x11020004, 0x0, 0x8f820104,
-0x15020007, 0x1021, 0x8ee201a8, 0x2021,
-0x24420001, 0xaee201a8, 0x8003d41, 0x8ee201a8,
-0x8ee4523c, 0x42140, 0x801821, 0x8ee40470,
-0x8ee50474, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xace40000, 0xace50004, 0x8ee3523c,
-0x91140, 0xa4e2000e, 0x24020003, 0xace20018,
-0x31940, 0x24635248, 0x2e31021, 0xace20008,
-0x8ee2523c, 0xace2001c, 0x8ee204cc, 0xace20010,
-0xaf880100, 0x92e204ec, 0x14400011, 0x24040001,
-0x8ee24e28, 0x24030040, 0x24420001, 0x50430003,
-0x1021, 0x8ee24e28, 0x24420001, 0xaee24e28,
-0x8ee24e28, 0x210c0, 0x24424e38, 0x2e21821,
-0x24020003, 0xac620000, 0x24020001, 0xac620004,
-0x1480000e, 0x24030040, 0x8ee2523c, 0xafa20010,
-0x8ee25244, 0x3c050007, 0xafa20014, 0x8ee65238,
-0x8ee75240, 0x3c040001, 0x248458e0, 0xc002403,
-0x34a5f010, 0x8003d5f, 0x0, 0x8ee20500,
-0x24420001, 0x50430003, 0x1021, 0x8ee20500,
-0x24420001, 0xaee20500, 0x8ee20500, 0x21080,
-0x571021, 0xac490508, 0x8ee2523c, 0x491021,
-0x304200ff, 0xaee2523c, 0x8ee3523c, 0x8ee25238,
-0x14620005, 0x0, 0x8f820060, 0x2403feff,
-0x431024, 0xaf820060, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x8f820120, 0x8ee34e34, 0x8f820124,
-0x8f860128, 0x24020040, 0x24630001, 0x50620003,
-0x1021, 0x8ee24e34, 0x24420001, 0xaee24e34,
-0x8ee24e34, 0x8ee44e34, 0x8ee34e30, 0x210c0,
-0x24425038, 0x14830007, 0x2e22821, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8003d92,
-0xaca00000, 0x8ee24e34, 0x24030040, 0x24420001,
-0x50430003, 0x1021, 0x8ee24e34, 0x24420001,
-0x210c0, 0x24425038, 0x2e22821, 0x8ca20004,
-0x8f830128, 0x21140, 0x621821, 0xaf830128,
-0xaca00000, 0x8cc20018, 0x2443fffe, 0x2c620012,
-0x10400008, 0x31080, 0x3c010001, 0x220821,
-0x8c2258f0, 0x400008, 0x0, 0x24020001,
-0xaee24e24, 0x3e00008, 0x0, 0x27bdffc8,
-0xafbf0030, 0xafb5002c, 0xafb40028, 0xafb30024,
-0xafb20020, 0xafb1001c, 0xafb00018, 0x8f830128,
-0x8f820124, 0x106202b0, 0x9821, 0x3c11001f,
-0x3631ffff, 0x3c12fff5, 0x36521000, 0x24150012,
-0x24140040, 0x8f8c0128, 0x8f820128, 0x24420020,
-0xaf820128, 0x9182001b, 0x8f830128, 0x2443fffe,
-0x2c620012, 0x1040029c, 0x31080, 0x3c010001,
-0x220821, 0x8c225948, 0x400008, 0x0,
-0x8f420218, 0x30420100, 0x10400007, 0x0,
-0x95830016, 0x95820018, 0x621823, 0x31402,
-0x431021, 0xa5820016, 0x8d82001c, 0x3c038000,
-0x3044ffff, 0x436824, 0x3c030800, 0x431824,
-0x11a00004, 0xad84001c, 0x41140, 0x8003dd8,
-0x24425248, 0x41140, 0x24420e20, 0x2e25821,
-0x9562000e, 0x3042fffc, 0x10600004, 0xa562000e,
-0x95840016, 0x8003ec0, 0x0, 0x8d690018,
-0x4021, 0x952a0000, 0x25290002, 0x95270000,
-0x25290002, 0x95260000, 0x25290002, 0x95250000,
-0x25290002, 0x95240000, 0x25290002, 0x95230000,
-0x25290002, 0x95220000, 0x25290002, 0x1475021,
-0x1465021, 0x1455021, 0x1445021, 0x1435021,
-0x1425021, 0xa1c02, 0x3142ffff, 0x625021,
-0xa1c02, 0x3142ffff, 0x625021, 0x96e2046a,
-0x314effff, 0x30420002, 0x10400044, 0x5021,
-0x25220014, 0x222102b, 0x10400014, 0x1201821,
-0x2405000a, 0x2021, 0x223102b, 0x54400001,
-0x721821, 0x94620000, 0x24630002, 0x24a5ffff,
-0x14a0fff9, 0x822021, 0x41c02, 0x3082ffff,
-0x622021, 0x41402, 0x3083ffff, 0x431021,
-0x3042ffff, 0x8003e33, 0x1425021, 0x952a0000,
-0x25290002, 0x95280000, 0x25290002, 0x95270000,
-0x25290002, 0x95260000, 0x25290002, 0x95250000,
-0x25290002, 0x95230000, 0x25290002, 0x95220000,
-0x25290002, 0x95240000, 0x25290002, 0x1485021,
-0x1475021, 0x1465021, 0x1455021, 0x1435021,
-0x1425021, 0x95220000, 0x95230002, 0x1445021,
-0x1425021, 0x1435021, 0xa1c02, 0x3142ffff,
-0x625021, 0xa1c02, 0x3142ffff, 0x625021,
-0x3148ffff, 0x51000001, 0x3408ffff, 0x8d620018,
-0x9443000c, 0x24020800, 0x54620005, 0xa5680010,
-0x9562000e, 0x34420002, 0xa562000e, 0xa5680010,
-0x96e2046a, 0x2821, 0x30420008, 0x14400056,
-0x3021, 0x8d630018, 0x24620024, 0x222102b,
-0x10400034, 0x24690010, 0x229102b, 0x54400001,
-0x1324821, 0x95250000, 0x24690014, 0x229102b,
-0x10400002, 0x24a5ffec, 0x1324821, 0x95220000,
-0x30420fff, 0x14400003, 0x25290002, 0x8003e60,
-0x24130001, 0x9821, 0xa03021, 0x229102b,
-0x54400001, 0x1324821, 0x91220001, 0x25290002,
-0xa22821, 0x229102b, 0x54400001, 0x1324821,
-0x25290002, 0x229102b, 0x54400001, 0x1324821,
-0x95220000, 0x25290002, 0xa22821, 0x229102b,
-0x54400001, 0x1324821, 0x95220000, 0x25290002,
-0xa22821, 0x229102b, 0x54400001, 0x1324821,
-0x95220000, 0x25290002, 0xa22821, 0x229102b,
-0x54400001, 0x1324821, 0x95220000, 0x8003e99,
-0xa22821, 0x94650010, 0x94620014, 0x24690016,
-0x30420fff, 0x14400003, 0x24a5ffec, 0x8003e8c,
-0x24130001, 0x9821, 0xa03021, 0x91230001,
-0x25290004, 0x95220000, 0x25290002, 0x95240000,
-0x25290002, 0xa32821, 0xa22821, 0x95220000,
-0x95230002, 0xa42821, 0xa22821, 0xa32821,
-0x51c02, 0x30a2ffff, 0x622821, 0x51c02,
-0x30a2ffff, 0x622821, 0x96e2046a, 0x30420001,
-0x1040001e, 0x2021, 0x95820016, 0x4e2023,
-0x41402, 0x822021, 0x326200ff, 0x50400002,
-0x862021, 0x852021, 0x41402, 0x822021,
-0x3084ffff, 0x50800001, 0x3404ffff, 0x8d620018,
-0x24430017, 0x223102b, 0x54400001, 0x721821,
-0x90620000, 0x38430011, 0x2c630001, 0x38420006,
-0x2c420001, 0x621825, 0x10600004, 0x0,
-0x9562000e, 0x34420001, 0xa562000e, 0x9562000e,
-0x240a0002, 0x30420004, 0x10400002, 0xa5640012,
-0x240a0004, 0x8f880120, 0x27623800, 0x25090020,
-0x122102b, 0x50400001, 0x27693000, 0x8f820128,
-0x11220004, 0x0, 0x8f820124, 0x15220007,
-0x24040020, 0x8ee201a4, 0x8021, 0x24420001,
-0xaee201a4, 0x8003f4f, 0x8ee201a4, 0x8ee5724c,
-0x8ee60490, 0x8ee70494, 0xad0b0008, 0xa504000e,
-0xad0a0018, 0x52940, 0xa01821, 0x1021,
-0xe33821, 0xe3202b, 0xc23021, 0xc43021,
-0xad060000, 0xad070004, 0x8ee2724c, 0x4d1025,
-0xad02001c, 0x8ee204c4, 0xad020010, 0xaf890120,
-0x92e24e20, 0x14400060, 0x24100001, 0x2543ffee,
-0x2c630002, 0x39420011, 0x2c420001, 0x621825,
-0x10600024, 0x0, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c820000, 0x1455000f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062000b,
-0x0, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee34e30, 0x24420001, 0x1054002b,
-0x0, 0x8003f2e, 0x0, 0x8ee24e30,
-0x24420001, 0x50540003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020001, 0x8003f4e,
-0xac950000, 0x8ee24e30, 0x210c0, 0x24425038,
-0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x0, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10540007,
-0x0, 0x8ee24e34, 0x24420001, 0x10620005,
-0x0, 0x8003f3a, 0x0, 0x14600005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400012,
-0xac800000, 0x8003f4f, 0x0, 0x8ee24e30,
-0x24420001, 0x50540003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020007, 0xac820000,
-0x24020001, 0xac820004, 0x1600000d, 0x0,
-0x8f820120, 0x3c040001, 0x24845938, 0xafa00014,
-0xafa20010, 0x8d86001c, 0x8f870124, 0x3c050008,
-0xc002403, 0x34a50001, 0x8004057, 0x0,
-0x8ee2724c, 0x24420001, 0x304207ff, 0x11a00006,
-0xaee2724c, 0x8ee201d0, 0x2442ffff, 0xaee201d0,
-0x8003f6b, 0x8ee201d0, 0x8ee201cc, 0x2442ffff,
-0xaee201cc, 0x8ee201cc, 0x8ee201d8, 0x2442ffff,
-0xaee201d8, 0x8004057, 0x8ee201d8, 0x8f420240,
-0x104000e5, 0x0, 0x8ee20e1c, 0x24420001,
-0x8004057, 0xaee20e1c, 0x9582001e, 0xad82001c,
-0x8f420240, 0x10400072, 0x0, 0x8ee20e1c,
-0x24420001, 0xaee20e1c, 0x8f430240, 0x43102b,
-0x144000d5, 0x0, 0x8f830120, 0x27623800,
-0x24660020, 0xc2102b, 0x50400001, 0x27663000,
-0x8f820128, 0x10c20004, 0x0, 0x8f820124,
-0x14c20007, 0x0, 0x8ee201a4, 0x8021,
-0x24420001, 0xaee201a4, 0x8003fda, 0x8ee201a4,
-0x8ee2724c, 0xac62001c, 0x8ee404a8, 0x8ee504ac,
-0x2462001c, 0xac620008, 0x24020008, 0xa462000e,
-0x24020011, 0xac620018, 0xac640000, 0xac650004,
-0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20,
-0x14400034, 0x24100001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c820000, 0x1455001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x0, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10540007,
-0x0, 0x8ee24e34, 0x24420001, 0x10620005,
-0x0, 0x8003fc6, 0x0, 0x14600005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400011,
-0xac800000, 0x8003fda, 0x0, 0x8ee24e30,
-0x24420001, 0x50540003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x24020001, 0xac950000,
-0xac820004, 0x5600000b, 0x24100001, 0x8ee2724c,
-0x3c040001, 0x248458a8, 0xafa00014, 0xafa20010,
-0x8ee6724c, 0x8f470280, 0x3c050009, 0xc002403,
-0x34a5f008, 0x56000001, 0xaee00e1c, 0x8ee20188,
-0x24420001, 0xaee20188, 0x8004050, 0x8ee20188,
-0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
-0x50400001, 0x27663000, 0x8f820128, 0x10c20004,
-0x0, 0x8f820124, 0x14c20007, 0x0,
-0x8ee201a4, 0x8021, 0x24420001, 0xaee201a4,
-0x8004044, 0x8ee201a4, 0x8ee2724c, 0xac62001c,
-0x8ee404a8, 0x8ee504ac, 0x2462001c, 0xac620008,
-0x24020008, 0xa462000e, 0x24020011, 0xac620018,
-0xac640000, 0xac650004, 0x8ee204c4, 0xac620010,
-0xaf860120, 0x92e24e20, 0x14400034, 0x24100001,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x8c820000, 0x1455001f, 0x0, 0x8ee34e30,
-0x8ee24e34, 0x1062001b, 0x0, 0x8c820004,
-0x24420001, 0xac820004, 0x8ee24e34, 0x8ee34e30,
-0x24420001, 0x10540007, 0x0, 0x8ee24e34,
-0x24420001, 0x10620005, 0x0, 0x8004030,
-0x0, 0x14600005, 0x0, 0x8f820128,
-0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
-0x2c420011, 0x50400011, 0xac800000, 0x8004044,
-0x0, 0x8ee24e30, 0x24420001, 0x50540003,
-0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
-0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
-0x24020001, 0xac950000, 0xac820004, 0x1600000b,
-0x0, 0x8ee2724c, 0x3c040001, 0x248458a8,
-0xafa00014, 0xafa20010, 0x8ee6724c, 0x8f470280,
-0x3c050009, 0xc002403, 0x34a5f008, 0x8ee20174,
-0x24420001, 0xaee20174, 0x8004057, 0x8ee20174,
-0x24020001, 0xaee24e24, 0x8f830128, 0x8f820124,
-0x1462fd58, 0x0, 0x8fbf0030, 0x8fb5002c,
-0x8fb40028, 0x8fb30024, 0x8fb20020, 0x8fb1001c,
-0x8fb00018, 0x3e00008, 0x27bd0038, 0x27bdffe8,
-0x27840208, 0x27450200, 0x24060008, 0xafbf0014,
-0xc00249a, 0xafb00010, 0x2021, 0x24100001,
-0x2402241f, 0xaf900210, 0xaf900200, 0xaf800204,
-0xaf820214, 0x8f460248, 0x24030004, 0x3c020040,
-0x3c010001, 0xac235cc4, 0x3c010001, 0xac235cc8,
-0x3c010001, 0xac205d9c, 0x3c010001, 0xac225cc0,
-0x3c010001, 0xac235cc8, 0xc005108, 0x24050004,
-0xc004822, 0x0, 0x8ee20000, 0x3c03feff,
-0x3463fffd, 0x431024, 0xaee20000, 0x3c023c00,
-0xaf82021c, 0x3c010001, 0x370821, 0xac3083ac,
-0x8fbf0014, 0x8fb00010, 0x3e00008, 0x27bd0018,
-0x27bdffe0, 0x3c050008, 0x34a50400, 0xafbf0018,
-0xafa00010, 0xafa00014, 0x8f860200, 0x3c040001,
-0x248459f0, 0xc002403, 0x3821, 0x8ee20280,
-0x24420001, 0xaee20280, 0x8ee20280, 0x8f830200,
-0x3c023f00, 0x621824, 0x8fbf0018, 0x3c020400,
-0x3e00008, 0x27bd0020, 0x27bdffd8, 0xafbf0020,
-0xafb1001c, 0xafb00018, 0x8f900220, 0x8ee20214,
-0x3821, 0x24420001, 0xaee20214, 0x8ee20214,
-0x3c020300, 0x2021024, 0x10400027, 0x3c110400,
-0xc00429b, 0x0, 0x3c020100, 0x2021024,
-0x10400007, 0x0, 0x8ee20218, 0x24420001,
-0xaee20218, 0x8ee20218, 0x80040c6, 0x3c03fdff,
-0x8ee2021c, 0x24420001, 0xaee2021c, 0x8ee2021c,
-0x3c03fdff, 0x3463ffff, 0x3c0808ff, 0x3508ffff,
-0x8ee20000, 0x3c040001, 0x248459fc, 0x3c050008,
-0x2003021, 0x431024, 0xaee20000, 0x8f820220,
-0x3821, 0x3c030300, 0x481024, 0x431025,
-0xaf820220, 0xafa00010, 0xc002403, 0xafa00014,
-0x8004296, 0x0, 0x2111024, 0x1040001f,
-0x3c024000, 0x8f830224, 0x24021402, 0x1462000b,
-0x3c03fdff, 0x3c040001, 0x24845a08, 0x3c050008,
-0xafa00010, 0xafa00014, 0x8f860224, 0x34a5ffff,
-0xc002403, 0x3821, 0x3c03fdff, 0x8ee20000,
-0x3463ffff, 0x2002021, 0x431024, 0xc004e54,
-0xaee20000, 0x8ee20220, 0x24420001, 0xaee20220,
-0x8ee20220, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x8004295, 0x511025, 0x2021024,
-0x10400142, 0x0, 0x8ee2022c, 0x24420001,
-0xaee2022c, 0x8ee2022c, 0x8f820220, 0x3c0308ff,
-0x3463ffff, 0x431024, 0x34420004, 0xaf820220,
-0x8f830054, 0x8f820054, 0x800410e, 0x24630002,
-0x8f820054, 0x621023, 0x2c420003, 0x1440fffc,
-0x0, 0x8f8600e0, 0x8f8400e4, 0x30c20007,
-0x10400012, 0x0, 0x8f8300e4, 0x2402fff8,
-0xc21024, 0x1043000d, 0x0, 0x8f820054,
-0x8f8300e0, 0x14c30009, 0x24440050, 0x8f820054,
-0x821023, 0x2c420051, 0x10400004, 0x0,
-0x8f8200e0, 0x10c2fff9, 0x0, 0x8f820220,
-0x3c0308ff, 0x3463fffd, 0x431024, 0xaf820220,
-0x8f8600e0, 0x30c20007, 0x10400003, 0x2402fff8,
-0xc23024, 0xaf8600e0, 0x8f8300c4, 0x3c02001f,
-0x3442ffff, 0x24680008, 0x48102b, 0x10400003,
-0x3c02fff5, 0x34421000, 0x1024021, 0x8f8b00c8,
-0x8f850120, 0x8f840124, 0x8004145, 0x6021,
-0x27623800, 0x82102b, 0x50400001, 0x27643000,
-0x10a40010, 0x318200ff, 0x8c820018, 0x38430007,
-0x2c630001, 0x3842000b, 0x2c420001, 0x621825,
-0x5060fff3, 0x24840020, 0x8ee20240, 0x240c0001,
-0x24420001, 0xaee20240, 0x8ee20240, 0x8c8b0008,
-0x318200ff, 0x14400065, 0x0, 0x3c020001,
-0x571021, 0x904283c0, 0x14400060, 0x0,
-0x8f8400e4, 0xc41023, 0x218c3, 0x4620001,
-0x24630200, 0x8f8900c4, 0x10600005, 0x24020001,
-0x10620009, 0x0, 0x8004187, 0x0,
-0x8ee20230, 0x1205821, 0x24420001, 0xaee20230,
-0x80041bc, 0x8ee20230, 0x8ee20234, 0x3c05000a,
-0x24420001, 0xaee20234, 0x8c8b0000, 0x34a5f000,
-0x8ee20234, 0x12b1823, 0xa3102b, 0x54400001,
-0x651821, 0x2c62233f, 0x14400040, 0x0,
-0x8f8200e8, 0x24420008, 0xaf8200e8, 0x8f8200e8,
-0x8f8200e4, 0x1205821, 0x24420008, 0xaf8200e4,
-0x80041bc, 0x8f8200e4, 0x8ee20238, 0x3c03000a,
-0x24420001, 0xaee20238, 0x8c840000, 0x3463f000,
-0x8ee20238, 0x883823, 0x67102b, 0x54400001,
-0xe33821, 0x3c020003, 0x34420d40, 0x47102b,
-0x10400003, 0x0, 0x80041bc, 0x805821,
-0x8f8200e4, 0x24440008, 0xaf8400e4, 0x8f8400e4,
-0x10860018, 0x3c05000a, 0x34a5f000, 0x3c0a0003,
-0x354a0d40, 0x8ee2007c, 0x24420001, 0xaee2007c,
-0x8c830000, 0x8ee2007c, 0x683823, 0xa7102b,
-0x54400001, 0xe53821, 0x147102b, 0x54400007,
-0x605821, 0x8f8200e4, 0x24440008, 0xaf8400e4,
-0x8f8400e4, 0x1486ffef, 0x0, 0x14860005,
-0x0, 0x1205821, 0xaf8600e4, 0x80041bc,
-0xaf8600e8, 0xaf8400e4, 0xaf8400e8, 0x8f8200c8,
-0x3c03000a, 0x3463f000, 0x483823, 0x67102b,
-0x54400001, 0xe33821, 0x3c020003, 0x34420d3f,
-0x47102b, 0x54400007, 0x6021, 0x1683823,
-0x67102b, 0x54400003, 0xe33821, 0x80041cf,
-0x3c020003, 0x3c020003, 0x34420d3f, 0x47102b,
-0x14400016, 0x318200ff, 0x14400006, 0x0,
-0x3c020001, 0x571021, 0x904283c0, 0x1040000f,
-0x0, 0x8ee2023c, 0x3c04fdff, 0x8ee30000,
-0x3484ffff, 0x24420001, 0xaee2023c, 0x8ee2023c,
-0x24020001, 0x641824, 0x3c010001, 0x370821,
-0xa02283b8, 0x800422c, 0xaee30000, 0xaf8b00c8,
-0x8f8300c8, 0x8f8200c4, 0x3c04000a, 0x3484f000,
-0x623823, 0x87102b, 0x54400001, 0xe43821,
-0x3c020003, 0x34420d40, 0x47102b, 0x2ce30001,
-0x431025, 0x10400008, 0x0, 0x8f820220,
-0x3c0308ff, 0x3463ffff, 0x431024, 0x3c034000,
-0x431025, 0xaf820220, 0x8f8600e0, 0x8f8400e4,
-0x10c4002a, 0x0, 0x8ee2007c, 0x24420001,
-0xaee2007c, 0x8ee2007c, 0x24c2fff8, 0xaf8200e0,
-0x3c020001, 0x8c427e30, 0x3c030008, 0x8f8600e0,
-0x431024, 0x1040001d, 0x0, 0x10c4001b,
-0x240dfff8, 0x3c0a000a, 0x354af000, 0x3c0c0080,
-0x24850008, 0x27622800, 0x50a20001, 0x27651800,
-0x8c880004, 0x8c820000, 0x8ca90000, 0x3103ffff,
-0x431021, 0x4d1024, 0x24430010, 0x6b102b,
-0x54400001, 0x6a1821, 0x12b102b, 0x54400001,
-0x12a4821, 0x10690002, 0x10c1025, 0xac820004,
-0xa02021, 0x14c4ffeb, 0x24850008, 0x8f820220,
-0x3c0308ff, 0x3463ffff, 0x431024, 0x34420002,
-0xaf820220, 0x8f830054, 0x8f820054, 0x8004237,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820220, 0x3c0308ff,
-0x3463fffb, 0x431024, 0xaf820220, 0x6010055,
-0x0, 0x8ee20228, 0x24420001, 0xaee20228,
-0x8ee20228, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x34420004, 0xaf820220, 0x8f830054,
-0x8f820054, 0x8004251, 0x24630002, 0x8f820054,
-0x621023, 0x2c420003, 0x1440fffc, 0x0,
-0x8f8600e0, 0x30c20007, 0x10400012, 0x0,
-0x8f8300e4, 0x2402fff8, 0xc21024, 0x1043000d,
-0x0, 0x8f820054, 0x8f8300e0, 0x14c30009,
-0x24440032, 0x8f820054, 0x821023, 0x2c420033,
-0x10400004, 0x0, 0x8f8200e0, 0x10c2fff9,
-0x0, 0x8f820220, 0x3c0308ff, 0x3463fffd,
-0x431024, 0xaf820220, 0x8f8600e0, 0x30c20007,
-0x10400003, 0x2402fff8, 0xc23024, 0xaf8600e0,
-0x240301f5, 0x8f8200e8, 0x673823, 0x718c0,
-0x431021, 0xaf8200e8, 0x8f8200e8, 0xaf8200e4,
-0x8ee2007c, 0x3c0408ff, 0x3484ffff, 0x471021,
-0xaee2007c, 0x8f820220, 0x3c038000, 0x34630002,
-0x441024, 0x431025, 0xaf820220, 0x8f830054,
-0x8f820054, 0x800428d, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024,
-0xaf820220, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x3c020001, 0x8c425cd8,
-0x27bdffd8, 0x10400012, 0xafbf0020, 0x3c040001,
-0x24845a14, 0x3c050008, 0x24020001, 0x3c010001,
-0x370821, 0xac2283ac, 0xafa00010, 0xafa00014,
-0x8f860220, 0x34a50498, 0x3c010001, 0xac205cd8,
-0x3c010001, 0xac225ccc, 0xc002403, 0x3821,
-0x8f420268, 0x3c037fff, 0x3463ffff, 0x431024,
-0xaf420268, 0x8ee204d0, 0x8ee404d4, 0x2403fffe,
-0x431024, 0x30840002, 0x1080011e, 0xaee204d0,
-0x8ee204d4, 0x2403fffd, 0x431024, 0xaee204d4,
-0x8f820044, 0x3c030600, 0x34632000, 0x34420020,
-0xaf820044, 0xafa30018, 0x8ee20608, 0x8f430228,
-0x24420001, 0x304a00ff, 0x514300fe, 0xafa00010,
-0x8ee20608, 0x210c0, 0x571021, 0x8fa30018,
-0x8fa4001c, 0xac43060c, 0xac440610, 0x8f830054,
-0x8f820054, 0x24690032, 0x1221023, 0x2c420033,
-0x1040006a, 0x5821, 0x24180008, 0x240f000d,
-0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120,
-0x27623800, 0x24e80020, 0x102102b, 0x50400001,
-0x27683000, 0x8f820128, 0x11020004, 0x0,
-0x8f820124, 0x15020007, 0x1021, 0x8ee201a4,
-0x2821, 0x24420001, 0xaee201a4, 0x800433d,
-0x8ee201a4, 0x8ee40608, 0x420c0, 0x801821,
-0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b,
-0x822021, 0x862021, 0xace40000, 0xace50004,
-0x8ee20608, 0xa4f8000e, 0xacef0018, 0xacea001c,
-0x210c0, 0x2442060c, 0x2e21021, 0xace20008,
-0x8ee204c4, 0xace20010, 0xaf880120, 0x92e24e20,
-0x14400033, 0x24050001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c820000, 0x144d001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x0, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee34e30, 0x24420001, 0x104c0007,
-0x0, 0x8ee24e34, 0x24420001, 0x10620005,
-0x0, 0x800432a, 0x0, 0x14600005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
-0xac800000, 0x800433d, 0x0, 0x8ee24e30,
-0x24420001, 0x504c0003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0xac8d0000, 0xac8e0004,
-0x54a00006, 0x240b0001, 0x8f820054, 0x1221023,
-0x2c420033, 0x1440ff9d, 0x0, 0x316300ff,
-0x24020001, 0x54620079, 0xafa00010, 0xaeea0608,
-0x8f830054, 0x8f820054, 0x24690032, 0x1221023,
-0x2c420033, 0x10400061, 0x5821, 0x240d0008,
-0x240c0011, 0x24080012, 0x24070040, 0x240a0001,
-0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
-0x50400001, 0x27663000, 0x8f820128, 0x10c20004,
-0x0, 0x8f820124, 0x14c20007, 0x0,
-0x8ee201a4, 0x2821, 0x24420001, 0xaee201a4,
-0x80043a9, 0x8ee201a4, 0x8ee20608, 0xac62001c,
-0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008,
-0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004,
-0x8ee204c4, 0xac620010, 0xaf860120, 0x92e24e20,
-0x14400033, 0x24050001, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0x8c820000, 0x1448001f,
-0x0, 0x8ee34e30, 0x8ee24e34, 0x1062001b,
-0x0, 0x8c820004, 0x24420001, 0xac820004,
-0x8ee24e34, 0x8ee34e30, 0x24420001, 0x10470007,
-0x0, 0x8ee24e34, 0x24420001, 0x10620005,
-0x0, 0x8004396, 0x0, 0x14600005,
-0x0, 0x8f820128, 0x24420020, 0xaf820128,
-0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
-0xac800000, 0x80043a9, 0x0, 0x8ee24e30,
-0x24420001, 0x50470003, 0x1021, 0x8ee24e30,
-0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
-0x24425038, 0x2e22021, 0xac880000, 0xac8a0004,
-0x54a00006, 0x240b0001, 0x8f820054, 0x1221023,
-0x2c420033, 0x1440ffa6, 0x0, 0x316300ff,
-0x24020001, 0x54620003, 0xafa00010, 0x80043d6,
-0x0, 0x3c040001, 0x24845a20, 0xafa00014,
-0x8f860120, 0x8f870124, 0x3c050009, 0xc002403,
-0x34a5f011, 0x80043d6, 0x0, 0x3c040001,
-0x24845a2c, 0xafa00014, 0x8f860120, 0x8f870124,
-0x3c050009, 0xc002403, 0x34a5f010, 0x80043d6,
-0x0, 0x3c040001, 0x24845a38, 0xafa00014,
-0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
-0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac,
-0x8ee201ac, 0x8ee2015c, 0x24420001, 0xaee2015c,
-0x8ee2015c, 0x8fbf0020, 0x3e00008, 0x27bd0028,
-0x3c020001, 0x8c425cd8, 0x27bdffe0, 0x1440000d,
-0xafbf0018, 0x3c040001, 0x24845a44, 0x3c050008,
-0xafa00010, 0xafa00014, 0x8f860220, 0x34a50499,
-0x24020001, 0x3c010001, 0xac225cd8, 0xc002403,
-0x3821, 0x8ee204d0, 0x3c030001, 0x771821,
-0x946383b2, 0x34420001, 0x10600007, 0xaee204d0,
-0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024,
-0x34420008, 0xaf820220, 0x2021, 0xc0052a2,
-0x24050004, 0xaf420268, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x3c120001,
-0x26521200, 0x3c140001, 0x8e945c50, 0x3c100001,
-0x26101120, 0x3c15c000, 0x36b50060, 0x8e8a0000,
-0x8eb30000, 0x26a400b, 0x248000a, 0x200f821,
-0x0, 0xd, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x80014d6,
-0x0, 0x80014d8, 0x3c0a0001, 0x80014d8,
-0x3c0a0002, 0x80014d8, 0x0, 0x80024a6,
-0x0, 0x80014d8, 0x3c0a0003, 0x80014d8,
-0x3c0a0004, 0x8002f8c, 0x0, 0x80014d8,
-0x3c0a0005, 0x8003ce8, 0x0, 0x8003c66,
-0x0, 0x80014d8, 0x3c0a0006, 0x80014d8,
-0x3c0a0007, 0x80014d8, 0x0, 0x80014d8,
-0x0, 0x80014d8, 0x0, 0x8002a75,
-0x0, 0x80014d8, 0x3c0a000b, 0x80014d8,
-0x3c0a000c, 0x80014d8, 0x3c0a000d, 0x800237a,
-0x0, 0x8002339, 0x0, 0x80014d8,
-0x3c0a000e, 0x8001b3c, 0x0, 0x80024a4,
-0x0, 0x80014d8, 0x3c0a000f, 0x80040a7,
-0x0, 0x8004091, 0x0, 0x80014d8,
-0x3c0a0010, 0x80014ee, 0x0, 0x80014d8,
-0x3c0a0011, 0x80014d8, 0x3c0a0012, 0x80014d8,
-0x3c0a0013, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x3c030001,
-0x34633800, 0x24050080, 0x2404001f, 0x2406ffff,
-0x24020001, 0xaf80021c, 0xaf820200, 0xaf820220,
-0x3631021, 0xaf8200c0, 0x3631021, 0xaf8200c4,
-0x3631021, 0xaf8200c8, 0x27623800, 0xaf8200d0,
-0x27623800, 0xaf8200d4, 0x27623800, 0xaf8200d8,
-0x27621800, 0xaf8200e0, 0x27621800, 0xaf8200e4,
-0x27621800, 0xaf8200e8, 0x27621000, 0xaf8200f0,
-0x27621000, 0xaf8200f4, 0x27621000, 0xaf8200f8,
-0xaca00000, 0x2484ffff, 0x1486fffd, 0x24a50004,
-0x8f830040, 0x3c02f000, 0x621824, 0x3c025000,
-0x1062000c, 0x43102b, 0x14400006, 0x3c026000,
-0x3c024000, 0x10620008, 0x24020800, 0x8004539,
-0x0, 0x10620004, 0x24020800, 0x8004539,
-0x0, 0x24020700, 0x3c010001, 0xac225cdc,
-0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
-0xafb00020, 0x8f830054, 0x8f820054, 0x3c010001,
-0xac205cc4, 0x8004545, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0xc004d71, 0x0, 0x24040001, 0x2821,
-0x27a60018, 0x34028000, 0xc00498e, 0xa7a20018,
-0x8f830054, 0x8f820054, 0x8004556, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc00494c, 0x27a60018,
-0x8f830054, 0x8f820054, 0x8004562, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc00494c, 0x27a60018,
-0x8f830054, 0x8f820054, 0x800456e, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x3c060001, 0x24c65da0, 0xc00494c,
-0x24050002, 0x8f830054, 0x8f820054, 0x800457b,
-0x24630064, 0x8f820054, 0x621023, 0x2c420065,
-0x1440fffc, 0x24040001, 0x24050003, 0x3c100001,
-0x26105da2, 0xc00494c, 0x2003021, 0x97a60018,
-0x3c070001, 0x94e75da0, 0x3c040001, 0x24845ab0,
-0xafa00014, 0x96020000, 0x3c05000d, 0x34a50100,
-0xc002403, 0xafa20010, 0x97a20018, 0x1040004c,
-0x24036040, 0x96020000, 0x3042fff0, 0x1443000a,
-0x24020020, 0x3c030001, 0x94635da0, 0x54620009,
-0x24027830, 0x24020003, 0x3c010001, 0xac225cc4,
-0x80045ac, 0x24020005, 0x3c030001, 0x94635da0,
-0x24027830, 0x1462000f, 0x24030010, 0x3c020001,
-0x94425da2, 0x3042fff0, 0x1443000a, 0x24020003,
-0x3c010001, 0xac225cc4, 0x24020006, 0x3c010001,
-0xac225db0, 0x3c010001, 0xac225dbc, 0x80045e6,
-0x3c09fff0, 0x3c020001, 0x8c425cc4, 0x3c030001,
-0x94635da0, 0x34420001, 0x3c010001, 0xac225cc4,
-0x24020015, 0x1462000f, 0x0, 0x3c020001,
-0x94425da2, 0x3042fff0, 0x3843f420, 0x2c630001,
-0x3842f430, 0x2c420001, 0x621825, 0x10600005,
-0x24020003, 0x3c010001, 0xac225dbc, 0x80045e6,
-0x3c09fff0, 0x3c030001, 0x94635da0, 0x24027810,
-0x1462000b, 0x24020002, 0x3c020001, 0x94425da2,
-0x3042fff0, 0x14400006, 0x24020002, 0x24020004,
-0x3c010001, 0xac225dbc, 0x80045e6, 0x3c09fff0,
-0x3c010001, 0xac225dbc, 0x80045e6, 0x3c09fff0,
-0x3c020001, 0x8c425cc4, 0x24030001, 0x3c010001,
-0xac235dbc, 0x34420004, 0x3c010001, 0xac225cc4,
-0x3c09fff0, 0x3529bdc0, 0x3c060001, 0x8cc65cc4,
-0x3c040001, 0x24845ab0, 0x24020001, 0x3c010001,
-0xac225ccc, 0x8f820054, 0x3c070001, 0x8ce75dbc,
-0x3c030001, 0x94635da0, 0x3c080001, 0x95085da2,
-0x3c05000d, 0x34a50100, 0x3c010001, 0xac205cc8,
-0x491021, 0x3c010001, 0xac225dac, 0xafa30010,
-0xc002403, 0xafa80014, 0x8fbf0024, 0x8fb00020,
-0x3e00008, 0x27bd0028, 0x27bdffe8, 0x3c050001,
-0x8ca55cc8, 0x24060004, 0x24020001, 0x14a20014,
-0xafbf0010, 0x3c020001, 0x8c427e3c, 0x30428000,
-0x10400005, 0x3c04000f, 0x3c030001, 0x8c635dbc,
-0x8004617, 0x34844240, 0x3c040004, 0x3c030001,
-0x8c635dbc, 0x348493e0, 0x24020005, 0x14620016,
-0x0, 0x3c04003d, 0x800462f, 0x34840900,
-0x3c020001, 0x8c427e38, 0x30428000, 0x10400005,
-0x3c04001e, 0x3c030001, 0x8c635dbc, 0x800462a,
-0x34848480, 0x3c04000f, 0x3c030001, 0x8c635dbc,
-0x34844240, 0x24020005, 0x14620003, 0x0,
-0x3c04007a, 0x34841200, 0x3c020001, 0x8c425dac,
-0x8f830054, 0x441021, 0x431023, 0x44102b,
-0x14400037, 0x0, 0x3c020001, 0x8c425cd0,
-0x14400033, 0x0, 0x3c010001, 0x10c00025,
-0xac205ce0, 0x3c090001, 0x8d295cc4, 0x24070001,
-0x3c044000, 0x3c080001, 0x25087e3c, 0x250afffc,
-0x52842, 0x14a00002, 0x24c6ffff, 0x24050008,
-0xa91024, 0x10400010, 0x0, 0x14a70008,
-0x0, 0x8d020000, 0x441024, 0x1040000a,
-0x0, 0x3c010001, 0x800465b, 0xac255ce0,
-0x8d420000, 0x441024, 0x10400003, 0x0,
-0x3c010001, 0xac275ce0, 0x3c020001, 0x8c425ce0,
-0x6182b, 0x2c420001, 0x431024, 0x5440ffe5,
-0x52842, 0x8f820054, 0x3c030001, 0x8c635ce0,
-0x3c010001, 0xac225dac, 0x1060002a, 0x24020001,
-0x3c010001, 0xac255cc8, 0x3c010001, 0xac225ccc,
-0x3c020001, 0x8c425ce0, 0x10400022, 0x0,
-0x3c020001, 0x8c425ccc, 0x1040000a, 0x24020001,
-0x3c010001, 0xac205ccc, 0x3c010001, 0x370821,
-0xac2283ac, 0x3c010001, 0xac205d4c, 0x3c010001,
-0xac225d04, 0x3c030001, 0x771821, 0x8c6383ac,
-0x24020008, 0x10620005, 0x24020001, 0xc004695,
-0x0, 0x8004692, 0x0, 0x3c030001,
-0x8c635cc8, 0x10620007, 0x2402000e, 0x3c030001,
-0x8c637dd0, 0x10620003, 0x0, 0xc004e54,
-0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018,
-0x27bdffe0, 0x3c02fdff, 0xafbf0018, 0x8ee30000,
-0x3c050001, 0x8ca55cc8, 0x3c040001, 0x8c845cf0,
-0x3442ffff, 0x621824, 0x14a40008, 0xaee30000,
-0x3c030001, 0x771821, 0x8c6383ac, 0x3c020001,
-0x8c425cf4, 0x10620008, 0x0, 0x3c020001,
-0x571021, 0x8c4283ac, 0x3c010001, 0xac255cf0,
-0x3c010001, 0xac225cf4, 0x3c030001, 0x8c635cc8,
-0x24020002, 0x10620169, 0x2c620003, 0x10400005,
-0x24020001, 0x10620008, 0x0, 0x800481c,
-0x0, 0x24020004, 0x106200b1, 0x24020001,
-0x800481d, 0x0, 0x3c020001, 0x571021,
-0x8c4283ac, 0x2443ffff, 0x2c620008, 0x1040015a,
-0x31080, 0x3c010001, 0x220821, 0x8c225ac8,
-0x400008, 0x0, 0x3c030001, 0x8c635dbc,
-0x24020005, 0x14620014, 0x0, 0x3c020001,
-0x8c425cd4, 0x1040000a, 0x24020003, 0xc004822,
-0x0, 0x24020002, 0x3c010001, 0x370821,
-0xac2283ac, 0x3c010001, 0x80046e0, 0xac205cd4,
-0x3c010001, 0x370821, 0xac2283ac, 0x3c010001,
-0x800481f, 0xac205c60, 0xc004822, 0x0,
-0x3c020001, 0x8c425cd4, 0x3c010001, 0xac205c60,
-0x104000dd, 0x24020002, 0x3c010001, 0x370821,
-0xac2283ac, 0x3c010001, 0x800481f, 0xac205cd4,
-0x3c030001, 0x8c635dbc, 0x24020005, 0x14620003,
-0x24020001, 0x3c010001, 0xac225d00, 0xc0049cf,
-0x0, 0x3c030001, 0x8c635d00, 0x800478e,
-0x24020011, 0x3c050001, 0x8ca55cc8, 0x3c060001,
-0x8cc67e3c, 0xc005108, 0x2021, 0x24020005,
-0x3c010001, 0xac205cd4, 0x3c010001, 0x370821,
-0x800481f, 0xac2283ac, 0x3c040001, 0x24845abc,
-0x3c05000f, 0x34a50100, 0x3021, 0x3821,
-0xafa00010, 0xc002403, 0xafa00014, 0x800481f,
-0x0, 0x8f820220, 0x3c03f700, 0x431025,
-0x80047b7, 0xaf820220, 0x8f820220, 0x3c030004,
-0x431024, 0x144000a9, 0x24020007, 0x8f830054,
-0x3c020001, 0x8c425da4, 0x2463d8f0, 0x431023,
-0x2c422710, 0x144000f8, 0x24020001, 0x800481d,
-0x0, 0x3c050001, 0x8ca55cc8, 0xc0052a2,
-0x2021, 0xc005386, 0x2021, 0x3c030001,
-0x8c637e34, 0x46100ea, 0x24020001, 0x3c020008,
-0x621024, 0x10400006, 0x0, 0x8f820214,
-0x3c03ffff, 0x431024, 0x8004741, 0x3442251f,
-0x8f820214, 0x3c03ffff, 0x431024, 0x3442241f,
-0xaf820214, 0x8ee20000, 0x3c030200, 0x431025,
-0xaee20000, 0x8f820220, 0x2403fffb, 0x431024,
-0xaf820220, 0x8f820220, 0x34420002, 0xaf820220,
-0x24020008, 0x3c010001, 0x370821, 0xac2283ac,
-0x8f820220, 0x3c030004, 0x431024, 0x14400005,
-0x0, 0x8f820220, 0x3c03f700, 0x431025,
-0xaf820220, 0x3c030001, 0x8c635dbc, 0x24020005,
-0x1462000a, 0x0, 0x3c020001, 0x94425da2,
-0x24429fbc, 0x2c420004, 0x10400004, 0x24040018,
-0x24050002, 0xc004d93, 0x24060020, 0xc0043dd,
-0x0, 0x3c010001, 0x800481f, 0xac205d50,
-0x3c020001, 0x571021, 0x8c4283ac, 0x2443ffff,
-0x2c620008, 0x104000ac, 0x31080, 0x3c010001,
-0x220821, 0x8c225ae8, 0x400008, 0x0,
-0xc00429b, 0x0, 0x3c010001, 0xac205ccc,
-0xaf800204, 0x3c010001, 0xc004822, 0xac207e20,
-0x24020001, 0x3c010001, 0xac225ce4, 0x24020002,
-0x3c010001, 0x370821, 0x800481f, 0xac2283ac,
-0xc00489f, 0x0, 0x3c030001, 0x8c635ce4,
-0x24020009, 0x14620090, 0x24020003, 0x3c010001,
-0x370821, 0x800481f, 0xac2283ac, 0x3c020001,
-0x8c427e38, 0x30424000, 0x10400005, 0x0,
-0x8f820044, 0x3c03ffff, 0x800479f, 0x34637fff,
-0x8f820044, 0x2403ff7f, 0x431024, 0xaf820044,
-0x8f830054, 0x80047b9, 0x24020004, 0x8f830054,
-0x3c020001, 0x8c425da4, 0x2463d8f0, 0x431023,
-0x2c422710, 0x14400074, 0x24020005, 0x3c010001,
-0x370821, 0x800481f, 0xac2283ac, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0xaf800204,
-0x3c010001, 0xac207e20, 0x8f830054, 0x24020006,
-0x3c010001, 0x370821, 0xac2283ac, 0x3c010001,
-0x800481f, 0xac235da4, 0x8f830054, 0x3c020001,
-0x8c425da4, 0x2463fff6, 0x431023, 0x2c42000a,
-0x14400059, 0x0, 0x24020007, 0x3c010001,
-0x370821, 0x800481f, 0xac2283ac, 0x8f820220,
-0x3c04f700, 0x441025, 0xaf820220, 0x8f820220,
-0x3c030300, 0x431024, 0x14400005, 0x1821,
-0x8f820220, 0x24030001, 0x441025, 0xaf820220,
-0x10600043, 0x24020001, 0x8f820214, 0x3c03ffff,
-0x3c040001, 0x8c845d98, 0x431024, 0x3442251f,
-0xaf820214, 0x24020008, 0x3c010001, 0x370821,
-0x1080000b, 0xac2283ac, 0x3c020001, 0x8c425d74,
-0x14400007, 0x24020001, 0x3c010001, 0xac227dd0,
-0xc004e54, 0x8f840220, 0x800480c, 0x0,
-0x8f820220, 0x3c030008, 0x431024, 0x14400017,
-0x2402000e, 0x3c010001, 0xac227dd0, 0x8ee20000,
-0x2021, 0x3c030200, 0x431025, 0xc005386,
-0xaee20000, 0x8f820220, 0x2403fffb, 0x431024,
-0xaf820220, 0x8f820220, 0x34420002, 0xc0043dd,
-0xaf820220, 0x3c050001, 0x8ca55cc8, 0xc0052a2,
-0x2021, 0x800481f, 0x0, 0x3c020001,
-0x8c425d74, 0x10400010, 0x0, 0x3c020001,
-0x8c425d70, 0x2442ffff, 0x3c010001, 0xac225d70,
-0x14400009, 0x24020002, 0x3c010001, 0xac205d74,
-0x3c010001, 0x800481f, 0xac225d70, 0x24020001,
-0x3c010001, 0xac225ccc, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220,
-0x34420004, 0xaf820220, 0x8f820200, 0x3c060001,
-0x8cc65cc8, 0x34420004, 0xaf820200, 0x24020002,
-0x10c2003a, 0x2cc20003, 0x10400005, 0x24020001,
-0x10c20008, 0x0, 0x8004868, 0x0,
-0x24020004, 0x10c20013, 0x24020001, 0x8004868,
-0x0, 0x3c030001, 0x8c635cb8, 0x3c020001,
-0x8c425cc0, 0x3c040001, 0x8c845cdc, 0x3c050001,
-0x8ca55cbc, 0xaf860200, 0xaf860220, 0x34630022,
-0x441025, 0x451025, 0x34420002, 0x8004867,
-0xaf830200, 0x3c030001, 0x8c635d98, 0xaf820200,
-0x10600009, 0xaf820220, 0x3c020001, 0x8c425d74,
-0x14400005, 0x3c033f00, 0x3c020001, 0x8c425cb0,
-0x800485b, 0x346300e0, 0x3c020001, 0x8c425cb0,
-0x3c033f00, 0x346300e2, 0x431025, 0xaf820200,
-0x3c030001, 0x8c635cb4, 0x3c04f700, 0x3c020001,
-0x8c425cc0, 0x3c050001, 0x8ca55cdc, 0x641825,
-0x431025, 0x451025, 0xaf820220, 0x3e00008,
-0x0, 0x8f820220, 0x3c030001, 0x8c635cc8,
-0x34420004, 0xaf820220, 0x24020001, 0x1062000f,
-0x0, 0x8f830054, 0x8f820054, 0x24630002,
-0x621023, 0x2c420003, 0x10400011, 0x0,
-0x8f820054, 0x621023, 0x2c420003, 0x1040000c,
-0x0, 0x8004879, 0x0, 0x8f830054,
-0x8f820054, 0x8004885, 0x24630007, 0x8f820054,
-0x621023, 0x2c420008, 0x1440fffc, 0x0,
-0x8f8400e0, 0x30820007, 0x1040000d, 0x0,
-0x8f820054, 0x8f8300e0, 0x14830009, 0x24450032,
-0x8f820054, 0xa21023, 0x2c420033, 0x10400004,
-0x0, 0x8f8200e0, 0x1082fff9, 0x0,
-0x8f820220, 0x2403fffd, 0x431024, 0xaf820220,
-0x3e00008, 0x0, 0x3c030001, 0x8c635ce4,
-0x3c020001, 0x8c425ce8, 0x50620004, 0x2463ffff,
-0x3c010001, 0xac235ce8, 0x2463ffff, 0x2c620009,
-0x1040009d, 0x31080, 0x3c010001, 0x220821,
-0x8c225b08, 0x400008, 0x0, 0x8f820044,
-0x34428080, 0xaf820044, 0x8f830054, 0x8004938,
-0x24020002, 0x8f830054, 0x3c020001, 0x8c425da8,
-0x2463d8f0, 0x431023, 0x2c422710, 0x1440008a,
-0x24020003, 0x8004945, 0x0, 0x8f820044,
-0x3c03ffff, 0x34637fff, 0x431024, 0xaf820044,
-0x8f830054, 0x8004938, 0x24020004, 0x8f830054,
-0x3c020001, 0x8c425da8, 0x2463fff6, 0x431023,
-0x2c42000a, 0x14400078, 0x24020005, 0x8004945,
-0x0, 0x8f820220, 0x3c03f700, 0x431025,
-0xaf820220, 0x8f820220, 0x2403fffb, 0x431024,
-0xaf820220, 0x8f820220, 0x34420002, 0xaf820220,
-0x3c023f00, 0x344200e0, 0xaf820200, 0x8f820200,
-0x2403fffd, 0x431024, 0xaf820200, 0x24040001,
-0x3405ffff, 0xaf840204, 0x8f830054, 0x8f820054,
-0x80048ec, 0x24630001, 0x8f820054, 0x621023,
-0x2c420002, 0x1440fffc, 0x0, 0x8f820224,
-0x42040, 0xa4102b, 0x1040fff2, 0x0,
-0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0x8f820214, 0x3c03ffff, 0x431024, 0x3442251f,
-0xaf820214, 0x8f820220, 0x2403fffb, 0x431024,
-0xaf820220, 0x8f820220, 0x3c04f700, 0x34840008,
-0x34420002, 0xaf820220, 0x8f820220, 0x3c033f00,
-0x346300e2, 0x441025, 0xaf820220, 0xaf830200,
-0x8f8400f0, 0x276217f8, 0x14820002, 0x24850008,
-0x27651000, 0x8f8200f4, 0x10a20007, 0x3c038000,
-0x34630040, 0x3c020001, 0x24425c70, 0xac820000,
-0xac830004, 0xaf8500f0, 0x8f830054, 0x8004938,
-0x24020006, 0x8f830054, 0x3c020001, 0x8c425da8,
-0x2463fff6, 0x431023, 0x2c42000a, 0x14400022,
-0x24020007, 0x8004945, 0x0, 0x8f8200e0,
-0xaf8200e4, 0x8f8200e0, 0xaf8200e8, 0x8f820220,
-0x34420004, 0xaf820220, 0x8f820220, 0x2403fff7,
-0x431024, 0xaf820220, 0x8f820044, 0x34428080,
-0xaf820044, 0x8f830054, 0x24020008, 0x3c010001,
-0xac225ce4, 0x3c010001, 0x8004947, 0xac235da8,
-0x8f830054, 0x3c020001, 0x8c425da8, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400003, 0x24020009,
-0x3c010001, 0xac225ce4, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x27bdffd8,
-0xafb20018, 0x809021, 0xafb3001c, 0xa09821,
-0xafb10014, 0xc08821, 0xafb00010, 0x8021,
-0xafbf0020, 0xa6200000, 0xc004d4b, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d4b, 0x2021, 0xc004d4b, 0x24040001,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0x24100010, 0x2501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d4b, 0x108042, 0x1600fffa,
-0x2501024, 0x24100010, 0x2701024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x2701024, 0xc004d71, 0x34108000,
-0xc004d71, 0x0, 0xc004d2b, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004d71, 0x0, 0x8fbf0020, 0x8fb3001c,
-0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008,
-0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821,
-0xafb20018, 0xa09021, 0xafb3001c, 0xc09821,
-0xafb00010, 0x8021, 0xafbf0020, 0xc004d4b,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0x24100010, 0x2301024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x2301024, 0x24100010, 0x2501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x2501024, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0x34108000,
-0x96620000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
-0x0, 0xc004d71, 0x0, 0x8fbf0020,
-0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
-0x3e00008, 0x27bd0028, 0x3c030001, 0x8c635d00,
-0x3c020001, 0x8c425d48, 0x27bdffd8, 0xafbf0020,
-0xafb1001c, 0x10620003, 0xafb00018, 0x3c010001,
-0xac235d48, 0x2463ffff, 0x2c620013, 0x10400349,
-0x31080, 0x3c010001, 0x220821, 0x8c225b30,
-0x400008, 0x0, 0xc004d71, 0x8021,
-0x34028000, 0xa7a20010, 0x27b10010, 0xc004d4b,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004d4b,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fff8, 0x0, 0xc004d71, 0x0,
-0x8004d24, 0x24020002, 0x27b10010, 0xa7a00010,
-0x8021, 0xc004d4b, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d4b,
-0x2021, 0xc004d4b, 0x24040001, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004d4b, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004d71, 0x34108000,
-0xc004d71, 0x0, 0xc004d2b, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004d71, 0x0, 0x97a20010, 0x30428000,
-0x144002dc, 0x24020003, 0x8004d24, 0x0,
-0x24021200, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0xc004d4b, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0xc004d4b, 0x24040001, 0xc004d4b,
-0x2021, 0x34108000, 0x96220000, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fff8, 0x0, 0xc004d71,
-0x0, 0x8f830054, 0x8004d16, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c425db8, 0x2463ff9c,
-0x431023, 0x2c420064, 0x1440029e, 0x24020002,
-0x3c030001, 0x8c635dbc, 0x10620297, 0x2c620003,
-0x14400296, 0x24020011, 0x24020003, 0x10620005,
-0x24020004, 0x10620291, 0x2402000f, 0x8004d24,
-0x24020011, 0x8004d24, 0x24020005, 0x24020014,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d4b,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020012,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020012, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0x34108000,
-0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
-0x0, 0xc004d71, 0x0, 0x8f830054,
-0x8004d16, 0x24020006, 0x8f830054, 0x3c020001,
-0x8c425db8, 0x2463ff9c, 0x431023, 0x2c420064,
-0x14400250, 0x24020007, 0x8004d24, 0x0,
-0x24020006, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020013, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020013,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fff8, 0x0, 0xc004d71, 0x0,
-0x8f830054, 0x8004d16, 0x24020008, 0x8f830054,
-0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440020f, 0x24020009, 0x8004d24,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
-0xc004d4b, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d71, 0x34108000, 0xc004d71, 0x0,
-0xc004d2b, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d71, 0x8021,
-0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fff8, 0x0, 0xc004d71, 0x0,
-0x8f830054, 0x8004d16, 0x2402000a, 0x8f830054,
-0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440019b, 0x2402000b, 0x8004d24,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
-0xc004d4b, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020017,
-0xc004d71, 0x34108000, 0xc004d71, 0x0,
-0xc004d2b, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d71, 0x8021,
-0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020017,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fff8, 0x0, 0xc004d71, 0x0,
-0x8f830054, 0x8004d16, 0x2402000c, 0x8f830054,
-0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
-0x2c420064, 0x14400127, 0x24020012, 0x8004d24,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
-0xc004d4b, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020014,
-0xc004d71, 0x34108000, 0xc004d71, 0x0,
-0xc004d2b, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d71, 0x8021,
-0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020014,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fff8, 0x0, 0xc004d71, 0x0,
-0x8f830054, 0x8004d16, 0x24020013, 0x8f830054,
-0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
-0x2c420064, 0x144000b3, 0x2402000d, 0x8004d24,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
-0xc004d4b, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d71, 0x34108000, 0xc004d71, 0x0,
-0xc004d2b, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d71, 0x8021,
-0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010,
-0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fff8, 0x0, 0xc004d71, 0x0,
-0x8f830054, 0x8004d16, 0x2402000e, 0x24020840,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d4b,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020013,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x32020013, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0x34108000,
-0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
-0x0, 0xc004d71, 0x0, 0x8f830054,
-0x24020010, 0x3c010001, 0xac225d00, 0x3c010001,
-0x8004d26, 0xac235db8, 0x8f830054, 0x3c020001,
-0x8c425db8, 0x2463ff9c, 0x431023, 0x2c420064,
-0x14400004, 0x0, 0x24020011, 0x3c010001,
-0xac225d00, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x8f850044, 0x8f820044,
-0x3c030001, 0x431025, 0x3c030008, 0xaf820044,
-0x8f840054, 0x8f820054, 0xa32824, 0x8004d37,
-0x24840001, 0x8f820054, 0x821023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
-0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
-0x8f820054, 0x8004d45, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x3e00008, 0xa01021, 0x8f830044, 0x3c02fff0,
-0x3442ffff, 0x42480, 0x621824, 0x3c020002,
-0x822025, 0x641825, 0xaf830044, 0x8f820044,
-0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
-0x8f830054, 0x8f820054, 0x8004d5e, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820044, 0x3c030001, 0x431025,
-0xaf820044, 0x8f830054, 0x8f820054, 0x8004d6b,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x3e00008, 0x0,
-0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024,
-0xaf820044, 0x8f820044, 0x3c030001, 0x431025,
-0xaf820044, 0x8f830054, 0x8f820054, 0x8004d7f,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
-0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
-0x8f820054, 0x8004d8d, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x3e00008, 0x0, 0x27bdffc8, 0xafb30024,
-0x809821, 0xafb5002c, 0xa0a821, 0xafb20020,
-0xc09021, 0x32a2ffff, 0xafbf0030, 0xafb40028,
-0xafb1001c, 0xafb00018, 0x14400034, 0xa7b20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d4b,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0x34108000,
-0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d4b, 0x108042, 0x12000075,
-0x0, 0x8004dc9, 0x0, 0x3274ffff,
-0x27b10010, 0xa7a00010, 0x8021, 0xc004d4b,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x24040001, 0xc004d4b,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2901024,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x2901024, 0xc004d71,
-0x34108000, 0xc004d71, 0x0, 0xc004d2b,
-0x0, 0x50400005, 0x108042, 0x96220000,
-0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004d71, 0x0, 0x32a5ffff,
-0x24020001, 0x54a20004, 0x24020002, 0x97a20010,
-0x8004e14, 0x521025, 0x14a20006, 0x3271ffff,
-0x97a20010, 0x121827, 0x431024, 0xa7a20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d4b,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d4b, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d4b,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d4b,
-0x24040001, 0xc004d4b, 0x2021, 0x34108000,
-0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
-0x0, 0xc004d71, 0x0, 0x8fbf0030,
-0x8fb5002c, 0x8fb40028, 0x8fb30024, 0x8fb20020,
-0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038,
-0x0, 0x0, 0x0, 0x27bdffe8,
-0xafbf0010, 0x3c030001, 0x771821, 0x8c6383ac,
-0x24020008, 0x1462022c, 0x803021, 0x3c020001,
-0x8c425d98, 0x14400033, 0x0, 0x8f850224,
-0x38a30020, 0x2c630001, 0x38a20010, 0x2c420001,
-0x621825, 0x1460000d, 0x38a30030, 0x2c630001,
-0x38a20400, 0x2c420001, 0x621825, 0x14600007,
-0x38a30402, 0x2c630001, 0x38a20404, 0x2c420001,
-0x621825, 0x10600005, 0x0, 0xc00429b,
-0x0, 0x8004e8d, 0x2402000e, 0xc0043dd,
-0x0, 0x3c050001, 0x8ca55cc8, 0xc0052a2,
-0x2021, 0x3c030001, 0x8c635cc8, 0x24020004,
-0x14620005, 0x2403fffb, 0x3c020001, 0x8c425cc4,
-0x8004e89, 0x2403fff7, 0x3c020001, 0x8c425cc4,
-0x431024, 0x3c010001, 0xac225cc4, 0x2402000e,
-0x3c010001, 0xc00429b, 0xac227dd0, 0x8005087,
-0x0, 0x8f820220, 0x3c030400, 0x431024,
-0x10400027, 0x2403ffbf, 0x8f850224, 0x3c020001,
-0x8c427ddc, 0xa32024, 0x431024, 0x1482000c,
-0x0, 0x3c020001, 0x8c427de0, 0x24420001,
-0x3c010001, 0xac227de0, 0x2c420002, 0x14400008,
-0x24020001, 0x3c010001, 0x8004ead, 0xac227e00,
-0x3c010001, 0xac207de0, 0x3c010001, 0xac207e00,
-0x3c020001, 0x8c427e00, 0x10400006, 0x30a20040,
-0x10400004, 0x24020001, 0x3c010001, 0x8004eb8,
-0xac227e04, 0x3c010001, 0xac207e04, 0x3c010001,
-0xac257ddc, 0x3c010001, 0x8004ec8, 0xac207e10,
-0x24020001, 0x3c010001, 0xac227e10, 0x3c010001,
-0xac207e00, 0x3c010001, 0xac207de0, 0x3c010001,
-0xac207e04, 0x3c010001, 0xac207ddc, 0x3c030001,
-0x8c637dd0, 0x3c020001, 0x8c427dd4, 0x10620003,
-0x3c020200, 0x3c010001, 0xac237dd4, 0xc21024,
-0x10400007, 0x2463ffff, 0x8f820220, 0x24030001,
-0x3c010001, 0xac235ccc, 0x8005085, 0x3c03f700,
-0x2c62000e, 0x104001a8, 0x31080, 0x3c010001,
-0x220821, 0x8c225b80, 0x400008, 0x0,
-0x3c010001, 0xac207e00, 0x3c010001, 0xac207de0,
-0x3c010001, 0xac207ddc, 0x3c010001, 0xac207e04,
-0x3c010001, 0xac207df8, 0x3c010001, 0xac207df0,
-0xc00486a, 0xaf800224, 0x24020002, 0x3c010001,
-0xac227dd0, 0x3c020001, 0x8c427e10, 0x14400056,
-0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024,
-0xc00429b, 0xaee20000, 0xaf800204, 0x8f820200,
-0x2403fffd, 0x431024, 0xaf820200, 0x3c010001,
-0xac207e20, 0x8f830054, 0x3c020001, 0x8c427df8,
-0x24040001, 0x3c010001, 0xac247e0c, 0x24420001,
-0x3c010001, 0xac227df8, 0x2c420004, 0x3c010001,
-0xac237df4, 0x14400006, 0x24020003, 0x3c010001,
-0xac245ccc, 0x3c010001, 0x8005083, 0xac207df8,
-0x3c010001, 0x8005083, 0xac227dd0, 0x8f830054,
-0x3c020001, 0x8c427df4, 0x2463d8f0, 0x431023,
-0x2c422710, 0x14400003, 0x24020004, 0x3c010001,
-0xac227dd0, 0x3c020001, 0x8c427e10, 0x14400026,
-0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024,
-0x8005083, 0xaee20000, 0x3c040001, 0x8c845d9c,
-0x3c010001, 0xc00508a, 0xac207de8, 0x3c020001,
-0x8c427e1c, 0xaf820204, 0x3c020001, 0x8c427e10,
-0x14400015, 0x3c03fdff, 0x8ee20000, 0x3463ffff,
-0x431024, 0xaee20000, 0x8f820204, 0x30420030,
-0x1440013c, 0x24020002, 0x3c030001, 0x8c637e1c,
-0x24020005, 0x3c010001, 0xac227dd0, 0x3c010001,
-0x8005083, 0xac237e20, 0x3c020001, 0x8c427e10,
-0x10400010, 0x3c03fdff, 0x3c020001, 0x8c425d6c,
-0x24420001, 0x3c010001, 0xac225d6c, 0x2c420002,
-0x14400131, 0x24020001, 0x3c010001, 0xac225d74,
-0x3c010001, 0xac205d6c, 0x3c010001, 0x8005083,
-0xac225ccc, 0x8ee20000, 0x3463ffff, 0x431024,
-0xaee20000, 0x3c020001, 0x8c427e00, 0x10400122,
-0x0, 0x3c020001, 0x8c427ddc, 0x1040011e,
-0x0, 0x3c010001, 0xac227e08, 0x24020003,
-0x3c010001, 0xac227de0, 0x8005024, 0x24020006,
-0x3c010001, 0xac207de8, 0x8f820204, 0x34420040,
-0xaf820204, 0x3c020001, 0x8c427e20, 0x24030007,
-0x3c010001, 0xac237dd0, 0x34420040, 0x3c010001,
-0xac227e20, 0x3c020001, 0x8c427e00, 0x10400005,
-0x0, 0x3c020001, 0x8c427ddc, 0x104000f9,
-0x24020002, 0x3c050001, 0x24a57de0, 0x8ca20000,
-0x2c424e21, 0x104000f3, 0x24020002, 0x3c020001,
-0x8c427e04, 0x104000f8, 0x2404ffbf, 0x3c020001,
-0x8c427ddc, 0x3c030001, 0x8c637e08, 0x441024,
-0x641824, 0x10430004, 0x24020001, 0x3c010001,
-0x8005083, 0xac227dd0, 0x24020003, 0xaca20000,
-0x24020008, 0x3c010001, 0xac227dd0, 0x3c020001,
-0x8c427e0c, 0x1040000c, 0x24020001, 0x3c040001,
-0xc005097, 0x8c847ddc, 0x3c020001, 0x8c427e28,
-0x14400005, 0x24020001, 0x3c020001, 0x8c427e24,
-0x10400006, 0x24020001, 0x3c010001, 0xac225ccc,
-0x3c010001, 0x8005083, 0xac207df8, 0x3c020001,
-0x8c427df0, 0x3c030001, 0x8c637ddc, 0x2c420001,
-0x210c0, 0x30630008, 0x3c010001, 0xac227df0,
-0x3c010001, 0xac237dec, 0x8f830054, 0x24020009,
-0x3c010001, 0xac227dd0, 0x3c010001, 0x8005083,
-0xac237df4, 0x8f830054, 0x3c020001, 0x8c427df4,
-0x2463d8f0, 0x431023, 0x2c422710, 0x144000a8,
-0x0, 0x3c020001, 0x8c427e00, 0x10400005,
-0x0, 0x3c020001, 0x8c427ddc, 0x104000a9,
-0x24020002, 0x3c030001, 0x24637de0, 0x8c620000,
-0x2c424e21, 0x104000a3, 0x24020002, 0x3c020001,
-0x8c427e0c, 0x1040000e, 0x0, 0x3c020001,
-0x8c427ddc, 0x3c010001, 0xac207e0c, 0x30420080,
-0x1040002f, 0x2402000c, 0x8f820204, 0x30420080,
-0x1440000c, 0x24020003, 0x8005011, 0x2402000c,
-0x3c020001, 0x8c427ddc, 0x30420080, 0x14400005,
-0x24020003, 0x8f820204, 0x30420080, 0x1040001f,
-0x24020003, 0xac620000, 0x2402000a, 0x3c010001,
-0xac227dd0, 0x3c040001, 0x24847e18, 0x8c820000,
-0x3c030001, 0x8c637df0, 0x431025, 0xaf820204,
-0x8c830000, 0x3c040001, 0x8c847df0, 0x2402000b,
-0x3c010001, 0xac227dd0, 0x641825, 0x3c010001,
-0xac237e20, 0x3c050001, 0x24a57de0, 0x8ca20000,
-0x2c424e21, 0x1040006f, 0x24020002, 0x3c020001,
-0x8c427e10, 0x10400005, 0x0, 0x2402000c,
-0x3c010001, 0x8005083, 0xac227dd0, 0x3c020001,
-0x8c427e00, 0x1040006c, 0x0, 0x3c040001,
-0x8c847ddc, 0x1080005e, 0x30820008, 0x3c030001,
-0x8c637dec, 0x10620064, 0x24020003, 0x3c010001,
-0xac247e08, 0xaca20000, 0x24020006, 0x3c010001,
-0x8005083, 0xac227dd0, 0x8f820200, 0x34420002,
-0xaf820200, 0x8f830054, 0x2402000d, 0x3c010001,
-0xac227dd0, 0x3c010001, 0xac237df4, 0x8f830054,
-0x3c020001, 0x8c427df4, 0x2463d8f0, 0x431023,
-0x2c422710, 0x1440003a, 0x0, 0x3c020001,
-0x8c427e10, 0x10400029, 0x2402000e, 0x3c030001,
-0x8c637e24, 0x3c010001, 0x14600015, 0xac227dd0,
-0xc0043dd, 0x0, 0x3c050001, 0x8ca55cc8,
-0xc0052a2, 0x2021, 0x3c030001, 0x8c635cc8,
-0x24020004, 0x14620005, 0x2403fffb, 0x3c020001,
-0x8c425cc4, 0x8005052, 0x2403fff7, 0x3c020001,
-0x8c425cc4, 0x431024, 0x3c010001, 0xac225cc4,
-0x8ee20000, 0x3c030200, 0x431025, 0xaee20000,
-0x8f820224, 0x3c010001, 0xac227e2c, 0x8f820220,
-0x2403fffb, 0x431024, 0xaf820220, 0x8f820220,
-0x34420002, 0x8005083, 0xaf820220, 0x3c020001,
-0x8c427e00, 0x10400005, 0x0, 0x3c020001,
-0x8c427ddc, 0x1040000f, 0x24020002, 0x3c020001,
-0x8c427de0, 0x2c424e21, 0x1040000a, 0x24020002,
-0x3c020001, 0x8c427e00, 0x1040000f, 0x0,
-0x3c020001, 0x8c427ddc, 0x1440000b, 0x0,
-0x24020002, 0x3c010001, 0x8005083, 0xac227dd0,
-0x3c020001, 0x8c427e00, 0x10400003, 0x0,
-0xc00429b, 0x0, 0x8f820220, 0x3c03f700,
-0x431025, 0xaf820220, 0x8fbf0010, 0x3e00008,
-0x27bd0018, 0x3c030001, 0x24637e28, 0x8c620000,
-0x10400005, 0x34422000, 0x3c010001, 0xac227e1c,
-0x8005095, 0xac600000, 0x3c010001, 0xac247e1c,
-0x3e00008, 0x0, 0x27bdffe0, 0x30820030,
-0xafbf0018, 0x3c010001, 0xac227e24, 0x14400067,
-0x3c02ffff, 0x34421f0e, 0x821024, 0x14400061,
-0x24020030, 0x30822000, 0x1040005d, 0x30838000,
-0x31a02, 0x30820001, 0x21200, 0x3c040001,
-0x8c845d9c, 0x621825, 0x331c2, 0x3c030001,
-0x24635d78, 0x30828000, 0x21202, 0x30840001,
-0x42200, 0x441025, 0x239c2, 0x61080,
-0x431021, 0x471021, 0x90430000, 0x24020001,
-0x10620025, 0x0, 0x10600007, 0x24020002,
-0x10620013, 0x24020003, 0x1062002c, 0x3c05000f,
-0x80050f9, 0x0, 0x8f820200, 0x2403feff,
-0x431024, 0xaf820200, 0x8f820220, 0x3c03fffe,
-0x3463ffff, 0x431024, 0xaf820220, 0x3c010001,
-0xac207e44, 0x3c010001, 0x8005104, 0xac207e4c,
-0x8f820200, 0x34420100, 0xaf820200, 0x8f820220,
-0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220,
-0x24020100, 0x3c010001, 0xac227e44, 0x3c010001,
-0x8005104, 0xac207e4c, 0x8f820200, 0x2403feff,
-0x431024, 0xaf820200, 0x8f820220, 0x3c030001,
-0x431025, 0xaf820220, 0x3c010001, 0xac207e44,
-0x3c010001, 0x8005104, 0xac237e4c, 0x8f820200,
-0x34420100, 0xaf820200, 0x8f820220, 0x3c030001,
-0x431025, 0xaf820220, 0x24020100, 0x3c010001,
-0xac227e44, 0x3c010001, 0x8005104, 0xac237e4c,
-0x34a5ffff, 0x3c040001, 0x24845bb8, 0xafa30010,
-0xc002403, 0xafa00014, 0x8005104, 0x0,
-0x24020030, 0x3c010001, 0xac227e28, 0x8fbf0018,
-0x3e00008, 0x27bd0020, 0x0, 0x27bdffc8,
-0xafb20028, 0x809021, 0xafb3002c, 0xa09821,
-0xafb00020, 0xc08021, 0x3c040001, 0x24845bd0,
-0x3c050009, 0x3c020001, 0x8c425cc8, 0x34a59001,
-0x2403021, 0x2603821, 0xafbf0030, 0xafb10024,
-0xa7a0001a, 0xafb00014, 0xc002403, 0xafa20010,
-0x24020002, 0x12620083, 0x2e620003, 0x10400005,
-0x24020001, 0x1262000a, 0x0, 0x800529b,
-0x0, 0x24020004, 0x126200fa, 0x24020008,
-0x126200f9, 0x3c02ffec, 0x800529b, 0x0,
-0x3c020001, 0x8c425cc4, 0x30420002, 0x14400004,
-0x128940, 0x3c02fffb, 0x3442ffff, 0x2028024,
-0x3c010001, 0x310821, 0xac307e3c, 0x3c024000,
-0x2021024, 0x1040004e, 0x1023c2, 0x30840030,
-0x101382, 0x3042001c, 0x3c030001, 0x24635d08,
-0x431021, 0x823821, 0x3c020020, 0x2021024,
-0x10400006, 0x24020100, 0x3c010001, 0x310821,
-0xac227e40, 0x8005150, 0x3c020080, 0x3c010001,
-0x310821, 0xac207e40, 0x3c020080, 0x2021024,
-0x10400006, 0x121940, 0x3c020001, 0x3c010001,
-0x230821, 0x800515c, 0xac227e48, 0x121140,
-0x3c010001, 0x220821, 0xac207e48, 0x94e40000,
-0x3c030001, 0x8c635dbc, 0x24020005, 0x10620010,
-0xa7a40018, 0x32024000, 0x10400002, 0x34824000,
-0xa7a20018, 0x24040001, 0x94e20002, 0x24050004,
-0x24e60002, 0x34420001, 0xc00498e, 0xa4e20002,
-0x24040001, 0x2821, 0xc00498e, 0x27a60018,
-0x3c020001, 0x8c425cc8, 0x24110001, 0x3c010001,
-0xac315cd4, 0x14530004, 0x32028000, 0xc00429b,
-0x0, 0x32028000, 0x1040011f, 0x0,
-0xc00429b, 0x0, 0x3c030001, 0x8c635dbc,
-0x24020005, 0x10620118, 0x24020002, 0x3c010001,
-0xac315ccc, 0x3c010001, 0x800529b, 0xac225cc8,
-0x24040001, 0x24050004, 0x27b0001a, 0xc00498e,
-0x2003021, 0x24040001, 0x2821, 0xc00498e,
-0x2003021, 0x3c020001, 0x511021, 0x8c427e34,
-0x3c040001, 0x8c845cc8, 0x3c03bfff, 0x3463ffff,
-0x3c010001, 0xac335cd4, 0x431024, 0x3c010001,
-0x310821, 0x109300fa, 0xac227e34, 0x800529b,
-0x0, 0x3c022000, 0x2021024, 0x10400005,
-0x24020001, 0x3c010001, 0xac225d98, 0x80051ad,
-0x128940, 0x3c010001, 0xac205d98, 0x128940,
-0x3c010001, 0x310821, 0xac307e38, 0x3c024000,
-0x2021024, 0x14400016, 0x0, 0x3c020001,
-0x8c425d98, 0x10400008, 0x24040004, 0x24050001,
-0xc004d93, 0x24062000, 0x24020001, 0x3c010001,
-0x370821, 0xac2283ac, 0x3c020001, 0x511021,
-0x8c427e30, 0x3c03bfff, 0x3463ffff, 0x431024,
-0x3c010001, 0x310821, 0x8005299, 0xac227e30,
-0x3c020001, 0x8c425d98, 0x10400028, 0x3c0300a0,
-0x2031024, 0x5443000d, 0x3c020020, 0x3c020001,
-0x8c425d9c, 0x24030100, 0x3c010001, 0x310821,
-0xac237e44, 0x3c030001, 0x3c010001, 0x310821,
-0xac237e4c, 0x80051f0, 0x34420400, 0x2021024,
-0x10400008, 0x24030100, 0x3c020001, 0x8c425d9c,
-0x3c010001, 0x310821, 0xac237e44, 0x80051f0,
-0x34420800, 0x3c020080, 0x2021024, 0x1040002e,
-0x3c030001, 0x3c020001, 0x8c425d9c, 0x3c010001,
-0x310821, 0xac237e4c, 0x34420c00, 0x3c010001,
-0xac225d9c, 0x8005218, 0x24040001, 0x3c020020,
-0x2021024, 0x10400006, 0x24020100, 0x3c010001,
-0x310821, 0xac227e44, 0x8005201, 0x3c020080,
-0x3c010001, 0x310821, 0xac207e44, 0x3c020080,
-0x2021024, 0x10400007, 0x121940, 0x3c020001,
-0x3c010001, 0x230821, 0xac227e4c, 0x800520f,
-0x24040001, 0x121140, 0x3c010001, 0x220821,
-0xac207e4c, 0x24040001, 0x2821, 0x27b0001e,
-0xc00494c, 0x2003021, 0x24040001, 0x2821,
-0xc00494c, 0x2003021, 0x24040001, 0x24050001,
-0x27b0001c, 0xc00494c, 0x2003021, 0x24040001,
-0x24050001, 0xc00494c, 0x2003021, 0x8005299,
-0x0, 0x3c02ffec, 0x3442ffff, 0x2028024,
-0x3c020008, 0x2028025, 0x121140, 0x3c010001,
-0x220821, 0xac307e38, 0x3c022000, 0x2021024,
-0x10400009, 0x0, 0x3c020001, 0x8c425d74,
-0x14400005, 0x24020001, 0x3c010001, 0xac225d98,
-0x800523a, 0x3c024000, 0x3c010001, 0xac205d98,
-0x3c024000, 0x2021024, 0x1440001e, 0x0,
-0x3c020001, 0x8c425d98, 0x3c010001, 0xac205ce0,
-0x10400007, 0x24022020, 0x3c010001, 0xac225d9c,
-0x24020001, 0x3c010001, 0x370821, 0xac2283ac,
-0x3c04bfff, 0x121940, 0x3c020001, 0x431021,
-0x8c427e30, 0x3c050001, 0x8ca55cc8, 0x3484ffff,
-0x441024, 0x3c010001, 0x230821, 0xac227e30,
-0x24020001, 0x10a20044, 0x0, 0x8005299,
-0x0, 0x3c020001, 0x8c425d98, 0x1040001c,
-0x24022000, 0x3c010001, 0xac225d9c, 0x3c0300a0,
-0x2031024, 0x14430005, 0x121140, 0x3402a000,
-0x3c010001, 0x8005294, 0xac225d9c, 0x3c030001,
-0x621821, 0x8c637e38, 0x3c020020, 0x621024,
-0x10400004, 0x24022001, 0x3c010001, 0x8005294,
-0xac225d9c, 0x3c020080, 0x621024, 0x1040001f,
-0x3402a001, 0x3c010001, 0x8005294, 0xac225d9c,
-0x3c020020, 0x2021024, 0x10400007, 0x121940,
-0x24020100, 0x3c010001, 0x230821, 0xac227e44,
-0x8005288, 0x3c020080, 0x121140, 0x3c010001,
-0x220821, 0xac207e44, 0x3c020080, 0x2021024,
-0x10400006, 0x121940, 0x3c020001, 0x3c010001,
-0x230821, 0x8005294, 0xac227e4c, 0x121140,
-0x3c010001, 0x220821, 0xac207e4c, 0x3c030001,
-0x8c635cc8, 0x24020001, 0x10620003, 0x0,
-0xc00429b, 0x0, 0x8fbf0030, 0x8fb3002c,
-0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
-0x27bd0038, 0x27bdffd8, 0xafb20020, 0x809021,
-0xafb1001c, 0x8821, 0x24020002, 0xafbf0024,
-0xafb00018, 0xa7a00012, 0x10a200d3, 0xa7a00010,
-0x2ca20003, 0x10400005, 0x24020001, 0x10a2000a,
-0x128140, 0x8005380, 0x2201021, 0x24020004,
-0x10a2007d, 0x24020008, 0x10a2007c, 0x122940,
-0x8005380, 0x2201021, 0x3c030001, 0x701821,
-0x8c637e3c, 0x3c024000, 0x621024, 0x14400009,
-0x24040001, 0x3c027fff, 0x3442ffff, 0x628824,
-0x3c010001, 0x300821, 0xac317e34, 0x8005380,
-0x2201021, 0x24050001, 0xc00494c, 0x27a60010,
-0x24040001, 0x24050001, 0xc00494c, 0x27a60010,
-0x97a20010, 0x30420004, 0x10400034, 0x3c114000,
-0x3c020001, 0x8c425dbc, 0x2443ffff, 0x2c620006,
-0x10400034, 0x31080, 0x3c010001, 0x220821,
-0x8c225be0, 0x400008, 0x0, 0x24040001,
-0x24050011, 0x27b00012, 0xc00494c, 0x2003021,
-0x24040001, 0x24050011, 0xc00494c, 0x2003021,
-0x97a50012, 0x30a24000, 0x10400002, 0x3c040010,
-0x3c040008, 0x3c030001, 0x8005301, 0x30a28000,
-0x24040001, 0x24050014, 0x27b00012, 0xc00494c,
-0x2003021, 0x24040001, 0x24050014, 0xc00494c,
-0x2003021, 0x97a50012, 0x30a21000, 0x10400002,
-0x3c040010, 0x3c040008, 0x3c030001, 0x30a20800,
-0x54400001, 0x3c030002, 0x3c028000, 0x2221025,
-0x641825, 0x800530e, 0x438825, 0x3c110001,
-0x2308821, 0x8e317e3c, 0x3c027fff, 0x3442ffff,
-0x2228824, 0x3c020001, 0x8c425cd8, 0x1040001d,
-0x121140, 0x3c020001, 0x8c425d98, 0x10400002,
-0x3c022000, 0x2228825, 0x121140, 0x3c010001,
-0x220821, 0x8c227e40, 0x10400003, 0x3c020020,
-0x8005322, 0x2228825, 0x3c02ffdf, 0x3442ffff,
-0x2228824, 0x121140, 0x3c010001, 0x220821,
-0x8c227e48, 0x10400003, 0x3c020080, 0x800532d,
-0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824,
-0x121140, 0x3c010001, 0x220821, 0xac317e34,
-0x8005380, 0x2201021, 0x122940, 0x3c030001,
-0x651821, 0x8c637e38, 0x3c024000, 0x621024,
-0x14400008, 0x3c027fff, 0x3442ffff, 0x628824,
-0x3c010001, 0x250821, 0xac317e30, 0x8005380,
-0x2201021, 0x3c020001, 0x8c425cd8, 0x10400033,
-0x3c11c00c, 0x3c020001, 0x8c425d74, 0x3c04c00c,
-0x34842000, 0x3c030001, 0x8c635d98, 0x2102b,
-0x21023, 0x441024, 0x10600003, 0x518825,
-0x3c022000, 0x2228825, 0x3c020001, 0x451021,
-0x8c427e44, 0x10400003, 0x3c020020, 0x800535d,
-0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x121140, 0x3c010001, 0x220821, 0x8c227e4c,
-0x10400003, 0x3c020080, 0x8005368, 0x2228825,
-0x3c02ff7f, 0x3442ffff, 0x2228824, 0x3c020001,
-0x8c425d60, 0x10400002, 0x3c020800, 0x2228825,
-0x3c020001, 0x8c425d64, 0x10400002, 0x3c020400,
-0x2228825, 0x3c020001, 0x8c425d68, 0x10400006,
-0x3c020100, 0x800537b, 0x2228825, 0x3c027fff,
-0x3442ffff, 0x628824, 0x121140, 0x3c010001,
-0x220821, 0xac317e30, 0x2201021, 0x8fbf0024,
-0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008,
-0x27bd0028, 0x27bdffd8, 0xafb40020, 0x80a021,
-0xafbf0024, 0xafb3001c, 0xafb20018, 0xafb10014,
-0xafb00010, 0x8f900200, 0x3c030001, 0x8c635cc8,
-0x8f930220, 0x24020002, 0x10620063, 0x2c620003,
-0x10400005, 0x24020001, 0x1062000a, 0x141940,
-0x8005448, 0x0, 0x24020004, 0x1062005a,
-0x24020008, 0x10620059, 0x149140, 0x8005448,
-0x0, 0x3c040001, 0x832021, 0x8c847e3c,
-0x3c110001, 0x2238821, 0x8e317e34, 0x3c024000,
-0x821024, 0x1040003e, 0x3c020008, 0x2221024,
-0x10400020, 0x36100002, 0x3c020001, 0x431021,
-0x8c427e40, 0x10400005, 0x36100020, 0x36100100,
-0x3c020020, 0x80053bd, 0x2228825, 0x2402feff,
-0x2028024, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x141140, 0x3c010001, 0x220821, 0x8c227e48,
-0x10400005, 0x3c020001, 0x2629825, 0x3c020080,
-0x80053dc, 0x2228825, 0x3c02fffe, 0x3442ffff,
-0x2629824, 0x3c02ff7f, 0x3442ffff, 0x80053dc,
-0x2228824, 0x2402fedf, 0x2028024, 0x3c02fffe,
-0x3442ffff, 0x2629824, 0x3c02ff5f, 0x3442ffff,
-0x2228824, 0x3c010001, 0x230821, 0xac207e40,
-0x3c010001, 0x230821, 0xac207e48, 0xc00486a,
-0x0, 0xaf900200, 0xaf930220, 0x8f820220,
-0x2403fffb, 0x431024, 0xaf820220, 0x8f820220,
-0x34420002, 0xaf820220, 0x80053f3, 0x141140,
-0x8f820200, 0x2403fffd, 0x431024, 0xc00486a,
-0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b,
-0x2228824, 0x141140, 0x3c010001, 0x220821,
-0x8005448, 0xac317e34, 0x149140, 0x3c040001,
-0x922021, 0x8c847e38, 0x3c110001, 0x2328821,
-0x8e317e30, 0x3c024000, 0x821024, 0x14400011,
-0x0, 0x3c020001, 0x8c425d98, 0x14400006,
-0x3c02bfff, 0x8f820200, 0x34420002, 0xc00486a,
-0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b,
-0x2228824, 0x3c010001, 0x320821, 0x8005448,
-0xac317e30, 0x3c020001, 0x8c425d98, 0x10400005,
-0x3c020020, 0x3c020001, 0x8c425d74, 0x1040002b,
-0x3c020020, 0x821024, 0x10400007, 0x36100020,
-0x24020100, 0x3c010001, 0x320821, 0xac227e44,
-0x8005428, 0x36100100, 0x3c010001, 0x320821,
-0xac207e44, 0x2402feff, 0x2028024, 0x3c020080,
-0x821024, 0x10400007, 0x141940, 0x3c020001,
-0x3c010001, 0x230821, 0xac227e4c, 0x8005439,
-0x2629825, 0x141140, 0x3c010001, 0x220821,
-0xac207e4c, 0x3c02fffe, 0x3442ffff, 0x2629824,
-0xc00486a, 0x0, 0xaf900200, 0xaf930220,
-0x8f820220, 0x2403fffb, 0x431024, 0xaf820220,
-0x8f820220, 0x34420002, 0xaf820220, 0x141140,
-0x3c010001, 0x220821, 0xac317e30, 0x8fbf0024,
-0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
-0x8fb00010, 0x3e00008, 0x27bd0028, 0x0 };
-static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = {
-0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f66776d, 0x61696e2e, 0x632c7620, 0x312e312e,
-0x322e3131, 0x20313939, 0x382f3034, 0x2f323720,
-0x32323a31, 0x333a3432, 0x20736875, 0x616e6720,
-0x45787020, 0x24000000, 0x7468655f, 0x4441574e,
-0x0, 0x53544143, 0x4b5f3120, 0x0,
-0x42616453, 0x6e64526e, 0x67000000, 0x3f456e71,
-0x45767400, 0x3f6e6f51, 0x64457650, 0x0,
-0x6576526e, 0x6746756c, 0x6c000000, 0x496c6c43,
-0x6f6e6652, 0x78000000, 0x53656e64, 0x436b5375,
-0x6d000000, 0x52656376, 0x566c616e, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f74696d, 0x65722e63, 0x2c762031, 0x2e312e32,
-0x2e382031, 0x3939382f, 0x30372f33, 0x31203137,
-0x3a35383a, 0x34352073, 0x6875616e, 0x67204578,
-0x70202400, 0x542d446d, 0x61526431, 0x0,
-0x542d446d, 0x61424200, 0x542d446d, 0x61320000,
-0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51,
-0x64527845, 0x0, 0x656e714d, 0x45765046,
-0x61696c00, 0x656e714d, 0x45764661, 0x696c0000,
-0x6661696c, 0x456e454d, 0x0, 0x3f456e71,
-0x45767400, 0x3f6e6f51, 0x64457650, 0x0,
-0x6576526e, 0x6746756c, 0x6c000000, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f636f6d, 0x6d616e64, 0x2e632c76, 0x20312e31,
-0x2e322e31, 0x30203139, 0x39382f31, 0x312f3138,
-0x2031373a, 0x31313a31, 0x38207368, 0x75616e67,
-0x20457870, 0x20240000, 0x3f4d626f, 0x78457674,
-0x0, 0x4e4f636f, 0x6d616e64, 0x0,
-0x68737465, 0x5f455252, 0x0, 0x412d4572,
-0x72427563, 0x0, 0x4552524f, 0x522d4164,
-0x64000000, 0x656e714d, 0x45765046, 0x61696c00,
-0x656e714d, 0x45764661, 0x696c0000, 0x6661696c,
-0x456e454d, 0x0, 0x442d4572, 0x724c6173,
-0x74000000, 0x442d4572, 0x72320000, 0x6d437374,
-0x4d644552, 0x52000000, 0x70726f6d, 0x4d644552,
-0x52000000, 0x46696c74, 0x4d644552, 0x52000000,
-0x636d645f, 0x45525200, 0x3f456e71, 0x45767400,
-0x3f6e6f51, 0x64457650, 0x0, 0x6576526e,
-0x6746756c, 0x6c000000, 0x0, 0x6ea0,
-0x7fbc, 0x6e38, 0x8734, 0x82b0,
-0x8780, 0x8780, 0x6f54, 0x7694,
-0x7f0c, 0x80a8, 0x8074, 0x8780,
-0x7e70, 0x80cc, 0x6e64, 0x81cc,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f646d61, 0x2e632c76, 0x20312e31, 0x2e322e33,
-0x20313939, 0x382f3034, 0x2f323720, 0x32323a31,
-0x333a3431, 0x20736875, 0x616e6720, 0x45787020,
-0x24000000, 0x646d6172, 0x6441544e, 0x0,
-0x646d6177, 0x7241544e, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f747261, 0x63652e63, 0x2c762031, 0x2e312e32,
-0x2e322031, 0x3939382f, 0x30342f32, 0x37203232,
-0x3a31333a, 0x35302073, 0x6875616e, 0x67204578,
-0x70202400, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f646174, 0x612e632c, 0x7620312e, 0x312e322e,
-0x32203139, 0x39382f30, 0x342f3237, 0x2032323a,
-0x31333a34, 0x30207368, 0x75616e67, 0x20457870,
-0x20240000, 0x46575f56, 0x45525349, 0x4f4e3a20,
-0x23312046, 0x72692041, 0x70722037, 0x2031373a,
-0x35353a34, 0x38205044, 0x54203230, 0x30300000,
-0x46575f43, 0x4f4d5049, 0x4c455f54, 0x494d453a,
-0x2031373a, 0x35353a34, 0x38000000, 0x46575f43,
-0x4f4d5049, 0x4c455f42, 0x593a2064, 0x65767263,
-0x73000000, 0x46575f43, 0x4f4d5049, 0x4c455f48,
-0x4f53543a, 0x20636f6d, 0x70757465, 0x0,
-0x46575f43, 0x4f4d5049, 0x4c455f44, 0x4f4d4149,
-0x4e3a2065, 0x6e672e61, 0x6374656f, 0x6e2e636f,
-0x6d000000, 0x46575f43, 0x4f4d5049, 0x4c45523a,
-0x20676363, 0x20766572, 0x73696f6e, 0x20322e37,
-0x2e320000, 0x0, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f6d656d, 0x2e632c76, 0x20312e31, 0x2e322e32,
-0x20313939, 0x382f3034, 0x2f323720, 0x32323a31,
-0x333a3434, 0x20736875, 0x616e6720, 0x45787020,
-0x24000000, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f73656e, 0x642e632c, 0x7620312e, 0x312e322e,
-0x31312031, 0x3939382f, 0x31322f32, 0x32203137,
-0x3a31373a, 0x35352073, 0x6875616e, 0x67204578,
-0x70202400, 0x736e6464, 0x654e6f51, 0x20000000,
-0x6e6f454e, 0x515f5458, 0x0, 0x736e6464,
-0x744e6f51, 0x20000000, 0x3f6e6f51, 0x64547845,
-0x0, 0x756e6b72, 0x64747970, 0x65000000,
-0x0, 0xaccc, 0xaccc, 0xad9c,
-0xaab0, 0xaab0, 0xad9c, 0xad9c,
-0xad9c, 0xad9c, 0xad9c, 0xad9c,
-0xad9c, 0xad9c, 0xad9c, 0xad9c,
-0xad9c, 0xad9c, 0xad9c, 0xad7c,
-0x0, 0xbca8, 0xbca8, 0xbd70,
-0xae4c, 0xb058, 0xbd70, 0xbd70,
-0xbd70, 0xbd70, 0xbd70, 0xbd70,
-0xbd70, 0xbd70, 0xbd70, 0xbd70,
-0xbd70, 0xbd70, 0xbd70, 0xbd54,
-0xb040, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f726563, 0x762e632c, 0x7620312e, 0x312e322e,
-0x31392031, 0x3939382f, 0x30372f32, 0x34203231,
-0x3a33303a, 0x30352073, 0x6875616e, 0x67204578,
-0x70202400, 0x706b5278, 0x45525200, 0x66726d32,
-0x4c617267, 0x65000000, 0x72784e6f, 0x52784264,
-0x0, 0x72785144, 0x6d614446, 0x0,
-0x72785144, 0x6d614246, 0x0, 0x3f6e6f51,
-0x64527845, 0x0, 0x706b5278, 0x45525273,
-0x0, 0x66726d32, 0x4c726753, 0x0,
-0x72784e6f, 0x42645300, 0x3f724264, 0x446d6146,
-0x0, 0x3f724a42, 0x64446d46, 0x0,
-0x0, 0xf678, 0xf678, 0xf678,
-0xf678, 0xf678, 0xf678, 0xf678,
-0xf678, 0xf678, 0xf678, 0xf678,
-0xf678, 0xf678, 0xf678, 0xf678,
-0xf670, 0xf670, 0xf670, 0x572d444d,
-0x41456e46, 0x0, 0x0, 0xfdc0,
-0x1015c, 0xfddc, 0x1015c, 0x1015c,
-0x1015c, 0x1015c, 0x1015c, 0x1015c,
-0xf704, 0x1015c, 0x1015c, 0x1015c,
-0x1015c, 0x1015c, 0x10154, 0x10154,
-0x10154, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f6d6163, 0x2e632c76, 0x20312e31, 0x2e322e31,
-0x32203139, 0x39382f30, 0x342f3237, 0x2032323a,
-0x31333a34, 0x32207368, 0x75616e67, 0x20457870,
-0x20240000, 0x6d616374, 0x7841544e, 0x0,
-0x4e745379, 0x6e264c6b, 0x0, 0x72656d61,
-0x73737274, 0x0, 0x6c696e6b, 0x444f574e,
-0x0, 0x656e714d, 0x45765046, 0x61696c00,
-0x656e714d, 0x45764661, 0x696c0000, 0x6661696c,
-0x456e454d, 0x0, 0x6c696e6b, 0x55500000,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
-0x2f636b73, 0x756d2e63, 0x2c762031, 0x2e312e32,
-0x2e322031, 0x3939382f, 0x30342f32, 0x37203232,
-0x3a31333a, 0x33392073, 0x6875616e, 0x67204578,
-0x70202400, 0x50726f62, 0x65506879, 0x0,
-0x6c6e6b41, 0x53535254, 0x0, 0x11b2c,
-0x11bc4, 0x11bf8, 0x11c2c, 0x11c58,
-0x11c6c, 0x11ca8, 0x1207c, 0x11de4,
-0x11e24, 0x11e50, 0x11e90, 0x11ec0,
-0x11efc, 0x11f30, 0x1207c, 0x122c0,
-0x122d8, 0x12300, 0x12320, 0x12348,
-0x12478, 0x124a0, 0x124f4, 0x1251c,
-0x0, 0x1278c, 0x1285c, 0x12934,
-0x12a04, 0x12a60, 0x12b3c, 0x12b64,
-0x12c40, 0x12c68, 0x12e10, 0x12e38,
-0x12fe0, 0x131d8, 0x1346c, 0x13380,
-0x1346c, 0x13498, 0x13008, 0x131b0,
-0x0, 0x13b84, 0x13bc8, 0x13c60,
-0x13cac, 0x13d1c, 0x13db4, 0x13de8,
-0x13e70, 0x13f08, 0x13fd8, 0x14018,
-0x1409c, 0x140c0, 0x141f4, 0x646f4261,
-0x73655067, 0x0, 0x0, 0x0,
-0x0, 0x73746d61, 0x634c4e4b, 0x0,
-0x0, 0x14c38, 0x14c38, 0x14b80,
-0x14bc4, 0x14c38, 0x14c38, 0x0,
-0x0, 0x0 };
-static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __devinitdata = {
-0x416c7465,
-0x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465,
-0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242,
-0x0, 0x0, 0x0, 0x135418,
-0x13e7fc, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x60cf00,
-0x60, 0xcf000000, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x3, 0x0,
-0x1, 0x0, 0x0, 0x0,
-0x1, 0x0, 0x1, 0x0,
-0x0, 0x0, 0x0, 0x1,
-0x1, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x1000000, 0x21000000,
-0x12000140, 0x0, 0x0, 0x20000000,
-0x120000a0, 0x0, 0x12000060, 0x12000180,
-0x120001e0, 0x0, 0x0, 0x0,
-0x1, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x2,
-0x0, 0x0, 0x30001, 0x1,
-0x30201, 0x0, 0x0, 0x0 };
-#endif
-/* Generated by genfw.c */
-#define tigon2FwReleaseMajor 0xc
-#define tigon2FwReleaseMinor 0x4
-#define tigon2FwReleaseFix 0xb
-#define tigon2FwStartAddr 0x00004000
-#define tigon2FwTextAddr 0x00004000
-#define tigon2FwTextLen 0x11bc0
-#define tigon2FwRodataAddr 0x00015bc0
-#define tigon2FwRodataLen 0x10d0
-#define tigon2FwDataAddr 0x00016cc0
-#define tigon2FwDataLen 0x1c0
-#define tigon2FwSbssAddr 0x00016e80
-#define tigon2FwSbssLen 0xcc
-#define tigon2FwBssAddr 0x00016f50
-#define tigon2FwBssLen 0x20c0
-static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = {
-0x0,
-0x10000003, 0x0, 0xd, 0xd,
-0x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000,
-0x26104000, 0xc0010c0, 0x0, 0xd,
-0x3c1d0001, 0x8fbd6d24, 0x3a0f021, 0x3c100000,
-0x26104000, 0xc0017e0, 0x0, 0xd,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x2000008,
-0x0, 0x800172f, 0x3c0a0001, 0x800172f,
-0x3c0a0002, 0x800172f, 0x0, 0x8002cac,
-0x0, 0x8002c4f, 0x0, 0x800172f,
-0x3c0a0004, 0x800328a, 0x0, 0x8001a52,
-0x0, 0x800394d, 0x0, 0x80038f4,
-0x0, 0x800172f, 0x3c0a0006, 0x80039bb,
-0x3c0a0007, 0x800172f, 0x3c0a0008, 0x800172f,
-0x3c0a0009, 0x8003a13, 0x0, 0x8002ea6,
-0x0, 0x800172f, 0x3c0a000b, 0x800172f,
-0x3c0a000c, 0x800172f, 0x3c0a000d, 0x80028fb,
-0x0, 0x8002890, 0x0, 0x800172f,
-0x3c0a000e, 0x800208c, 0x0, 0x8001964,
-0x0, 0x8001a04, 0x0, 0x8003ca6,
-0x0, 0x8003c94, 0x0, 0x800172f,
-0x0, 0x800191a, 0x0, 0x800172f,
-0x0, 0x800172f, 0x3c0a0013, 0x800172f,
-0x3c0a0014, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0x3c1cc000, 0xafbf001c, 0xafb00018, 0x8f820140,
-0x24030003, 0xaf8300ec, 0x34420004, 0xc002b20,
-0xaf820140, 0x3c0100c0, 0xc001763, 0xac203ffc,
-0x401821, 0x3c020010, 0x3c010001, 0xac236e9c,
-0x10620011, 0x43102b, 0x14400002, 0x3c020020,
-0x3c020008, 0x1062000c, 0x24050100, 0x3c060001,
-0x8cc66e9c, 0x3c040001, 0x24845c74, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020020,
-0x3c010001, 0xac226e9c, 0x24020008, 0x3c010001,
-0xac226eb4, 0x2402001f, 0x3c010001, 0xac226ec4,
-0x24020016, 0x3c010001, 0xac226e98, 0x3c05fffe,
-0x34a56f08, 0x3c020001, 0x8c426e9c, 0x3c030002,
-0x24639010, 0x3c040001, 0x8c846cc4, 0x431023,
-0x14800002, 0x458021, 0x2610fa38, 0x2402f000,
-0x2028024, 0xc001785, 0x2002021, 0x2022823,
-0x3c040020, 0x821823, 0x651823, 0x247bb000,
-0x3c03fffe, 0x3463bf08, 0x363b821, 0x3c0600bf,
-0x34c6f000, 0x3c070001, 0x8ce76cc0, 0x3c0300bf,
-0x3463e000, 0x852023, 0x3c010001, 0xac246ea8,
-0x822023, 0x3c010001, 0xac256e90, 0x52842,
-0x3c010001, 0xac226e84, 0x27620ffc, 0x3c010001,
-0xac226d20, 0x27621ffc, 0xdb3023, 0x7b1823,
-0x3c010001, 0xac246e88, 0x3c010001, 0xac256eac,
-0x3c010001, 0xac226d24, 0xaf860150, 0x10e00011,
-0xaf830250, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021,
-0xc001749, 0x0, 0x3c020001, 0x8c426cd0,
-0x3c030001, 0x8c636cd4, 0x2442fe00, 0x24630200,
-0x3c010001, 0xac226cd0, 0x3c010001, 0x10000004,
-0xac236cd4, 0x3c1d0001, 0x8fbd6d20, 0x3a0f021,
-0x3c020001, 0x8c426cc4, 0x1040000d, 0x26fafa38,
-0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
-0x3c1a0001, 0x8f5a6cd4, 0x2442fa38, 0x246305c8,
-0x3c010001, 0xac226cd0, 0x3c010001, 0xac236cd4,
-0x3c020001, 0x8c426cc8, 0x14400003, 0x0,
-0x3c010001, 0xac206cd0, 0xc001151, 0x0,
-0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
-0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
-0x27bdff98, 0xafb00048, 0x3c100001, 0x8e1066b8,
-0xafb20050, 0x3c120000, 0x26524100, 0xafbf0060,
-0xafbe005c, 0xafb50058, 0xafb30054, 0xafb1004c,
-0xafa20034, 0xafa30030, 0xafa00010, 0xafa00014,
-0x8f860040, 0x3c040001, 0x24845c80, 0x24050200,
-0x3c010001, 0xac326e80, 0xc002b3b, 0x2003821,
-0x8f830040, 0x3c02f000, 0x621824, 0x3c026000,
-0x1062000b, 0xa3a0003f, 0x240e0001, 0x3c040001,
-0x24845c88, 0xa3ae003f, 0xafa00010, 0xafa00014,
-0x8f860040, 0x24050300, 0xc002b3b, 0x2003821,
-0x8f820240, 0x3c030001, 0x431025, 0xaf820240,
-0xaf800048, 0x8f820048, 0x14400005, 0x0,
-0xaf800048, 0x8f820048, 0x10400004, 0x0,
-0xaf800048, 0x10000003, 0x2e02021, 0xaf80004c,
-0x2e02021, 0x3c050001, 0xc002ba8, 0x34a540f8,
-0x3402021, 0xc002ba8, 0x240505c8, 0x3c020001,
-0x8c426ea8, 0x3c0d0001, 0x8dad6e88, 0x3c030001,
-0x8c636e84, 0x3c080001, 0x8d086e90, 0x3c090001,
-0x8d296eac, 0x3c0a0001, 0x8d4a6eb4, 0x3c0b0001,
-0x8d6b6ec4, 0x3c0c0001, 0x8d8c6e98, 0x3c040001,
-0x24845c94, 0x24050400, 0xaf42013c, 0x8f42013c,
-0x24060001, 0x24070001, 0xaf400000, 0xaf4d0138,
-0xaf430144, 0xaf480148, 0xaf49014c, 0xaf4a0150,
-0xaf4b0154, 0xaf4c0158, 0x2442ff80, 0xaf420140,
-0x24020001, 0xafa20010, 0xc002b3b, 0xafa00014,
-0x8f420138, 0xafa20010, 0x8f42013c, 0xafa20014,
-0x8f460144, 0x8f470148, 0x3c040001, 0x24845ca0,
-0xc002b3b, 0x24050500, 0xafb70010, 0xafba0014,
-0x8f46014c, 0x8f470150, 0x3c040001, 0x24845cac,
-0xc002b3b, 0x24050600, 0x3c020001, 0x8c426e9c,
-0x3603821, 0x3c060002, 0x24c69010, 0x2448ffff,
-0x1061824, 0xe81024, 0x43102b, 0x10400006,
-0x24050900, 0x3c040001, 0x24845cb8, 0xafa80010,
-0xc002b3b, 0xafa00014, 0x8f82000c, 0xafa20010,
-0x8f82003c, 0xafa20014, 0x8f860000, 0x8f870004,
-0x3c040001, 0x24845cc4, 0xc002b3b, 0x24051000,
-0x8c020220, 0x8c030224, 0x8c060218, 0x8c07021c,
-0x3c040001, 0x24845ccc, 0x24051100, 0xafa20010,
-0xc002b3b, 0xafa30014, 0xaf800054, 0xaf80011c,
-0x8c020218, 0x30420002, 0x10400009, 0x0,
-0x8c020220, 0x3c030002, 0x34630004, 0x431025,
-0xaf42000c, 0x8c02021c, 0x10000008, 0x34420004,
-0x8c020220, 0x3c030002, 0x34630006, 0x431025,
-0xaf42000c, 0x8c02021c, 0x34420006, 0xaf420014,
-0x8c020218, 0x30420010, 0x1040000a, 0x0,
-0x8c02021c, 0x34420004, 0xaf420010, 0x8c020220,
-0x3c03000a, 0x34630004, 0x431025, 0x10000009,
-0xaf420008, 0x8c020220, 0x3c03000a, 0x34630006,
-0x431025, 0xaf420008, 0x8c02021c, 0x34420006,
-0xaf420010, 0x24020001, 0xaf8200a0, 0xaf8200b0,
-0x8f830054, 0x8f820054, 0xaf8000d0, 0xaf8000c0,
-0x10000002, 0x24630064, 0x8f820054, 0x621023,
-0x2c420065, 0x1440fffc, 0x0, 0x8c040208,
-0x8c05020c, 0x26e20028, 0xaee20020, 0x24020490,
-0xaee20010, 0xaee40008, 0xaee5000c, 0x26e40008,
-0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094,
-0x8c820018, 0xaf8200b4, 0x9482000a, 0xaf82009c,
-0x8f420014, 0xaf8200b0, 0x8f8200b0, 0x30420004,
-0x1440fffd, 0x0, 0x8f8200b0, 0x3c03ef00,
-0x431024, 0x10400021, 0x0, 0x8f8200b4,
-0xafa20010, 0x8f820090, 0x8f830094, 0x3c040001,
-0x24845cd4, 0xafa30014, 0x8f8600b0, 0x8f87009c,
-0x3c050001, 0xc002b3b, 0x34a5200d, 0x3c040001,
-0x24845ce0, 0x240203c0, 0xafa20010, 0xafa00014,
-0x8f860144, 0x3c070001, 0x24e75ce8, 0xc002b3b,
-0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c,
-0x8f820220, 0x34420004, 0xaf820220, 0x8f820140,
-0x3c030001, 0x431025, 0xaf820140, 0x96e20472,
-0x96e60452, 0x96e70462, 0xafa20010, 0x96e20482,
-0x3c040001, 0x24845d14, 0x24051200, 0xc002b3b,
-0xafa20014, 0x96f00452, 0x32020001, 0x10400002,
-0xb021, 0x24160001, 0x32020002, 0x54400001,
-0x36d60002, 0x32020008, 0x54400001, 0x36d60004,
-0x32020010, 0x54400001, 0x36d60008, 0x32020020,
-0x54400001, 0x36d60010, 0x32020040, 0x54400001,
-0x36d60020, 0x32020080, 0x54400001, 0x36d60040,
-0x96e60482, 0x30c20200, 0x54400001, 0x36d64000,
-0x96e30472, 0x30620200, 0x10400003, 0x30620100,
-0x10000003, 0x36d62000, 0x54400001, 0x36d61000,
-0x96f00462, 0x32c24000, 0x14400004, 0x3207009b,
-0x30c2009b, 0x14e20007, 0x240e0001, 0x32c22000,
-0x1440000d, 0x32020001, 0x3062009b, 0x10e20009,
-0x240e0001, 0x3c040001, 0x24845d20, 0x24051300,
-0x2003821, 0xa3ae003f, 0xafa30010, 0xc002b3b,
-0xafa00014, 0x32020001, 0x54400001, 0x36d60080,
-0x32020002, 0x54400001, 0x36d60100, 0x32020008,
-0x54400001, 0x36d60200, 0x32020010, 0x54400001,
-0x36d60400, 0x32020080, 0x54400001, 0x36d60800,
-0x8c020218, 0x30420200, 0x10400002, 0x3c020008,
-0x2c2b025, 0x8c020218, 0x30420800, 0x10400002,
-0x3c020080, 0x2c2b025, 0x8c020218, 0x30420400,
-0x10400002, 0x3c020100, 0x2c2b025, 0x8c020218,
-0x30420100, 0x10400002, 0x3c020200, 0x2c2b025,
-0x8c020218, 0x30420080, 0x10400002, 0x3c020400,
-0x2c2b025, 0x8c020218, 0x30422000, 0x10400002,
-0x3c020010, 0x2c2b025, 0x8c020218, 0x30424000,
-0x10400002, 0x3c020020, 0x2c2b025, 0x8c020218,
-0x30421000, 0x10400002, 0x3c020040, 0x2c2b025,
-0x8ee20498, 0x8ee3049c, 0xaf420160, 0xaf430164,
-0x8ee204a0, 0x8ee304a4, 0xaf420168, 0xaf43016c,
-0x8ee204a8, 0x8ee304ac, 0xaf420170, 0xaf430174,
-0x8ee20428, 0x8ee3042c, 0xaf420178, 0xaf43017c,
-0x8ee20448, 0x8ee3044c, 0xaf420180, 0xaf430184,
-0x8ee20458, 0x8ee3045c, 0xaf420188, 0xaf43018c,
-0x8ee20468, 0x8ee3046c, 0xaf420190, 0xaf430194,
-0x8ee20478, 0x8ee3047c, 0xaf420198, 0xaf43019c,
-0x8ee20488, 0x8ee3048c, 0xaf4201a0, 0xaf4301a4,
-0x8ee204b0, 0x8ee304b4, 0x24040080, 0xaf4201a8,
-0xaf4301ac, 0xc002ba8, 0x24050080, 0x8c02025c,
-0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200,
-0x24060008, 0xc002bbf, 0xaf4201f8, 0x3c043b9a,
-0x3484ca00, 0x3821, 0x24020006, 0x24030002,
-0xaf4201f4, 0x240203e8, 0xaf430204, 0xaf430200,
-0xaf4401fc, 0xaf420294, 0x24020001, 0xaf430290,
-0xaf42029c, 0x3c030001, 0x671821, 0x90636cd8,
-0x3471021, 0x24e70001, 0xa043022c, 0x2ce2000f,
-0x1440fff8, 0x3471821, 0x24e70001, 0x3c080001,
-0x350840f8, 0x8f820040, 0x3c040001, 0x24845d2c,
-0x24051400, 0x21702, 0x24420030, 0xa062022c,
-0x3471021, 0xa040022c, 0x8c070218, 0x2c03021,
-0x240205c8, 0xafa20010, 0xc002b3b, 0xafa80014,
-0x3c040001, 0x24845d38, 0x3c050000, 0x24a55c80,
-0x24060010, 0x27b10030, 0x2203821, 0x27b30034,
-0xc0017a3, 0xafb30010, 0x3c030001, 0x8c636cc8,
-0x1060000a, 0x408021, 0x8fa30030, 0x2405ff00,
-0x8fa20034, 0x246400ff, 0x852024, 0x831823,
-0x431023, 0xafa20034, 0xafa40030, 0x3c040001,
-0x24845d44, 0x3c050000, 0x24a54100, 0x24060108,
-0x2203821, 0xc0017a3, 0xafb30010, 0x409021,
-0x32c20003, 0x3c010001, 0xac326e80, 0x10400045,
-0x2203821, 0x8f820050, 0x3c030010, 0x431024,
-0x10400016, 0x0, 0x8c020218, 0x30420040,
-0x1040000f, 0x24020001, 0x8f820050, 0x8c030218,
-0x240e0001, 0x3c040001, 0x24845d50, 0xa3ae003f,
-0xafa20010, 0xafa30014, 0x8f870040, 0x24051500,
-0xc002b3b, 0x2c03021, 0x10000004, 0x0,
-0x3c010001, 0x370821, 0xa02240f4, 0x3c040001,
-0x24845d5c, 0x3c050001, 0x24a55b40, 0x3c060001,
-0x24c65bac, 0xc53023, 0x8f420010, 0x27b30030,
-0x2603821, 0x27b10034, 0x34420a00, 0xaf420010,
-0xc0017a3, 0xafb10010, 0x3c040001, 0x24845d70,
-0x3c050001, 0x24a5b714, 0x3c060001, 0x24c6ba90,
-0xc53023, 0x2603821, 0xaf420108, 0xc0017a3,
-0xafb10010, 0x3c040001, 0x24845d8c, 0x3c050001,
-0x24a5be58, 0x3c060001, 0x24c6c900, 0xc53023,
-0x2603821, 0x3c010001, 0xac226ef4, 0xc0017a3,
-0xafb10010, 0x3c040001, 0x24845da4, 0x10000024,
-0x24051600, 0x3c040001, 0x24845dac, 0x3c050001,
-0x24a5a10c, 0x3c060001, 0x24c6a238, 0xc53023,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845dbc,
-0x3c050001, 0x24a5b2b0, 0x3c060001, 0x24c6b70c,
-0xc53023, 0x2203821, 0xaf420108, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845dd0, 0x3c050001,
-0x24a5ba98, 0x3c060001, 0x24c6be50, 0xc53023,
-0x2203821, 0x3c010001, 0xac226ef4, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845de4, 0x24051650,
-0x2c03021, 0x3821, 0x3c010001, 0xac226ef8,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x32c20020,
-0x10400021, 0x27a70030, 0x3c040001, 0x24845df0,
-0x3c050001, 0x24a5b13c, 0x3c060001, 0x24c6b2a8,
-0xc53023, 0x24022000, 0xaf42001c, 0x27a20034,
-0xc0017a3, 0xafa20010, 0x21900, 0x31982,
-0x3c040800, 0x641825, 0xae430028, 0x24030010,
-0xaf43003c, 0x96e30450, 0xaf430040, 0x8f430040,
-0x3c040001, 0x24845e04, 0xafa00014, 0xafa30010,
-0x8f47001c, 0x24051660, 0x3c010001, 0xac226ef0,
-0x10000025, 0x32c60020, 0x8ee20448, 0x8ee3044c,
-0xaf43001c, 0x8f42001c, 0x2442e000, 0x2c422001,
-0x1440000a, 0x240e0001, 0x3c040001, 0x24845e10,
-0xa3ae003f, 0xafa00010, 0xafa00014, 0x8f46001c,
-0x24051700, 0xc002b3b, 0x3821, 0x3c020000,
-0x24425cbc, 0x21100, 0x21182, 0x3c030800,
-0x431025, 0xae420028, 0x24020008, 0xaf42003c,
-0x96e20450, 0xaf420040, 0x8f420040, 0x3c040001,
-0x24845e1c, 0xafa00014, 0xafa20010, 0x8f47001c,
-0x24051800, 0x32c60020, 0xc002b3b, 0x0,
-0x3c050fff, 0x3c030001, 0x8c636ef4, 0x34a5ffff,
-0x2403021, 0x3c020001, 0x8c426ef8, 0x3c040800,
-0x651824, 0x31882, 0x641825, 0x451024,
-0x21082, 0x441025, 0xacc20080, 0x32c20180,
-0x10400056, 0xacc30020, 0x8f82005c, 0x3c030080,
-0x431024, 0x1040000d, 0x0, 0x8f820050,
-0xafa20010, 0x8f82005c, 0x240e0001, 0x3c040001,
-0x24845e28, 0xa3ae003f, 0xafa20014, 0x8f870040,
-0x24051900, 0xc002b3b, 0x2c03021, 0x8f820050,
-0x3c030010, 0x431024, 0x10400016, 0x0,
-0x8c020218, 0x30420040, 0x1040000f, 0x24020001,
-0x8f820050, 0x8c030218, 0x240e0001, 0x3c040001,
-0x24845d50, 0xa3ae003f, 0xafa20010, 0xafa30014,
-0x8f870040, 0x24052000, 0xc002b3b, 0x2c03021,
-0x10000004, 0x0, 0x3c010001, 0x370821,
-0xa02240f4, 0x3c040001, 0x24845e34, 0x3c050001,
-0x24a55ac0, 0x3c060001, 0x24c65b38, 0xc53023,
-0x8f420008, 0x27b30030, 0x2603821, 0x27b10034,
-0x34420e00, 0xaf420008, 0xc0017a3, 0xafb10010,
-0x3c040001, 0x24845e4c, 0x3c050001, 0x24a5d8b4,
-0x3c060001, 0x24c6e3c8, 0xc53023, 0x2603821,
-0xaf42010c, 0xc0017a3, 0xafb10010, 0x3c040001,
-0x24845e64, 0x3c050001, 0x24a5e9ac, 0x3c060001,
-0x24c6f0f0, 0xc53023, 0x2603821, 0x3c010001,
-0xac226f04, 0xc0017a3, 0xafb10010, 0x3c040001,
-0x24845e7c, 0x10000027, 0x24052100, 0x3c040001,
-0x24845e84, 0x3c050001, 0x24a59fc8, 0x3c060001,
-0x24c6a104, 0xc53023, 0x27b10030, 0x2203821,
-0x27b30034, 0xc0017a3, 0xafb30010, 0x3c040001,
-0x24845e94, 0x3c050001, 0x24a5cad4, 0x3c060001,
-0x24c6d8ac, 0xc53023, 0x2203821, 0xaf42010c,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845ea4,
-0x3c050001, 0x24a5e84c, 0x3c060001, 0x24c6e9a4,
-0xc53023, 0x2203821, 0x3c010001, 0xac226f04,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845eb8,
-0x24052150, 0x2c03021, 0x3821, 0x3c010001,
-0xac226f10, 0xafa00010, 0xc002b3b, 0xafa00014,
-0x3c110fff, 0x3c030001, 0x8c636f04, 0x3631ffff,
-0x2409821, 0x3c020001, 0x8c426f10, 0x3c0e0800,
-0x711824, 0x31882, 0x6e1825, 0x511024,
-0x21082, 0x4e1025, 0xae630038, 0xae620078,
-0x8c020218, 0x30420040, 0x14400004, 0x24020001,
-0x3c010001, 0x370821, 0xa02240f4, 0x3c040001,
-0x24845ec4, 0x3c050001, 0x24a5e3d0, 0x3c060001,
-0x24c6e52c, 0xc53023, 0x27be0030, 0x3c03821,
-0x27b50034, 0xc0017a3, 0xafb50010, 0x3c010001,
-0xac226efc, 0x511024, 0x21082, 0x3c0e0800,
-0x4e1025, 0xae620050, 0x32c22000, 0x10400006,
-0x3c03821, 0x3c020000, 0x24425cbc, 0x2221024,
-0x1000000f, 0x21082, 0x3c040001, 0x24845ed8,
-0x3c050001, 0x24a5e534, 0x3c060001, 0x24c6e6e4,
-0xc53023, 0xc0017a3, 0xafb50010, 0x3c010001,
-0xac226f14, 0x511024, 0x21082, 0x3c0e0800,
-0x4e1025, 0xae620048, 0x32c24000, 0x10400005,
-0x27a70030, 0x3c020000, 0x24425cbc, 0x1000000e,
-0x21100, 0x3c040001, 0x24845ef0, 0x3c050001,
-0x24a5e6ec, 0x3c060001, 0x24c6e844, 0xc53023,
-0x27a20034, 0xc0017a3, 0xafa20010, 0x3c010001,
-0xac226f08, 0x21100, 0x21182, 0x3c030800,
-0x431025, 0xae420060, 0x3c040001, 0x24845f08,
-0x3c050001, 0x24a58230, 0x3c060001, 0x24c68650,
-0xc53023, 0x27b10030, 0x2203821, 0x27b30034,
-0xc0017a3, 0xafb30010, 0x3c0e0fff, 0x35ceffff,
-0x3c040001, 0x24845f14, 0x3c050000, 0x24a56468,
-0x3c060000, 0x24c66588, 0xc53023, 0x2203821,
-0x240f021, 0x3c010001, 0xac226edc, 0x4e1024,
-0x21082, 0x3c150800, 0x551025, 0xafae0044,
-0xafc200b8, 0xc0017a3, 0xafb30010, 0x3c040001,
-0x24845f20, 0x3c050000, 0x24a56590, 0x3c060000,
-0x24c66808, 0x8fae0044, 0xc53023, 0x2203821,
-0x3c010001, 0xac226ed0, 0x4e1024, 0x21082,
-0x551025, 0xafc200e8, 0xc0017a3, 0xafb30010,
-0x3c040001, 0x24845f38, 0x3c050000, 0x24a56810,
-0x3c060000, 0x24c66940, 0x8fae0044, 0xc53023,
-0x2203821, 0x3c010001, 0xac226ec8, 0x4e1024,
-0x21082, 0x551025, 0xafc200c0, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845f50, 0x3c050001,
-0x24a5fad0, 0x3c060001, 0x24c6fba8, 0x8fae0044,
-0xc53023, 0x2203821, 0x3c010001, 0xac226ed4,
-0x4e1024, 0x21082, 0x551025, 0xafc200c8,
-0xc0017a3, 0xafb30010, 0x3c040001, 0x24845f5c,
-0x3c050001, 0x24a5c93c, 0x3c060001, 0x24c6ca20,
-0xc53023, 0x2203821, 0xaf420110, 0xc0017a3,
-0xafb30010, 0x3c040001, 0x24845f6c, 0x3c050001,
-0x24a5c910, 0x3c060001, 0x24c6c934, 0xc53023,
-0x2203821, 0xaf420124, 0xc0017a3, 0xafb30010,
-0x3c040001, 0x24845f7c, 0x3c050001, 0x24a55a80,
-0x3c060001, 0x24c65aac, 0xc53023, 0x2203821,
-0xaf420120, 0xaf420114, 0xc0017a3, 0xafb30010,
-0x3c040001, 0x24845f88, 0x3c050001, 0x24a5f298,
-0x3c060001, 0x24c6f6b4, 0xc53023, 0x2203821,
-0xaf420118, 0xc0017a3, 0xafb30010, 0x8fae0044,
-0x3c010001, 0xac226f18, 0x4e1024, 0x21082,
-0x551025, 0xc003fc3, 0xafc200d0, 0xc003c40,
-0x0, 0xc0027a8, 0x0, 0xac000228,
-0xac00022c, 0x96e20450, 0x2442ffff, 0xaf420038,
-0x96e20460, 0xaf420080, 0x32c24000, 0x14400003,
-0x0, 0x96e20480, 0xaf420084, 0x96e70490,
-0x50e00001, 0x24070800, 0x24e2ffff, 0xaf420088,
-0xaf42007c, 0x24020800, 0x10e2000f, 0x32c24000,
-0x10400003, 0x24020400, 0x10e2000b, 0x0,
-0x240e0001, 0x3c040001, 0x24845f98, 0xa3ae003f,
-0x96e60490, 0x24052170, 0x2c03821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8f430138, 0x8f440138,
-0x24020001, 0xa34205c2, 0xaf430094, 0xaf440098,
-0xafa00010, 0xafa00014, 0x8f460080, 0x8f470084,
-0x3c040001, 0x24845fa4, 0xc002b3b, 0x24052200,
-0xc0024a4, 0x3c110800, 0x3c1433d8, 0x3694cb58,
-0x3c020800, 0x34420080, 0x3c040001, 0x24845fb0,
-0x3c050000, 0x24a55d00, 0x3c060000, 0x24c65d1c,
-0xc53023, 0x27a70030, 0xaf820060, 0x2402ffff,
-0xaf820064, 0x27a20034, 0xc0017a3, 0xafa20010,
-0x3c010001, 0xac226eb8, 0x21100, 0x21182,
-0x511025, 0xc0018fc, 0xae420000, 0x8f820240,
-0x3c030001, 0x431025, 0xaf820240, 0x3c020000,
-0x24424034, 0xaf820244, 0xaf800240, 0x8f820060,
-0x511024, 0x14400005, 0x3c030800, 0x8f820060,
-0x431024, 0x1040fffd, 0x0, 0xc003c4d,
-0x8821, 0x3c020100, 0xafa20020, 0x8f530018,
-0x240200ff, 0x56620001, 0x26710001, 0x8c020228,
-0x1622000e, 0x1330c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x24845c24, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000003f, 0x34a50100, 0xd71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0xc01821, 0x8f440178, 0x8f45017c, 0x1021,
-0x24070004, 0xafa70010, 0xafb10014, 0x8f48000c,
-0x24c604c0, 0x2e63021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x1440000b, 0x24070008,
-0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24845c2c, 0x3c050009, 0xafa20014, 0x8fa60020,
-0x1000001c, 0x34a50200, 0x8f440160, 0x8f450164,
-0x8f43000c, 0xaf510018, 0x8f860120, 0x24020010,
-0xafa20010, 0xafb10014, 0xafa30018, 0x8f42010c,
-0x40f809, 0x24c6001c, 0x14400010, 0x0,
-0x8f420340, 0x24420001, 0xaf420340, 0x8f420340,
-0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24845c34, 0x3c050009, 0xafa20014, 0x8fa60020,
-0x34a50300, 0xc002b3b, 0x2603821, 0x8f4202e4,
-0x24420001, 0xaf4202e4, 0x8f4202e4, 0x93a2003f,
-0x10400069, 0x3c020700, 0x34423000, 0xafa20028,
-0x8f530018, 0x240200ff, 0x12620002, 0x8821,
-0x26710001, 0x8c020228, 0x1622000e, 0x1330c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x24845c24, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60028, 0x1000003f,
-0x34a50100, 0xd71021, 0x8fa30028, 0x8fa4002c,
-0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
-0x8f45017c, 0x1021, 0x24070004, 0xafa70010,
-0xafb10014, 0x8f48000c, 0x24c604c0, 0x2e63021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24845c2c, 0x3c050009,
-0xafa20014, 0x8fa60028, 0x1000001c, 0x34a50200,
-0x8f440160, 0x8f450164, 0x8f43000c, 0xaf510018,
-0x8f860120, 0x24020010, 0xafa20010, 0xafb10014,
-0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400010, 0x0, 0x8f420340, 0x24420001,
-0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24845c34, 0x3c050009,
-0xafa20014, 0x8fa60028, 0x34a50300, 0xc002b3b,
-0x2603821, 0x8f4202f0, 0x24420001, 0xaf4202f0,
-0x8f4202f0, 0x3c040001, 0x24845fc0, 0xafa00010,
-0xafa00014, 0x8fa60028, 0x24052300, 0xc002b3b,
-0x3821, 0x10000004, 0x0, 0x8c020264,
-0x10400005, 0x0, 0x8f8200a0, 0x30420004,
-0x1440fffa, 0x0, 0x8f820044, 0x34420004,
-0xaf820044, 0x8f420308, 0x24420001, 0xaf420308,
-0x8f420308, 0x8f8200d8, 0x8f8300d4, 0x431023,
-0x2442ff80, 0xaf420090, 0x8f420090, 0x2842ff81,
-0x10400006, 0x24020001, 0x8f420090, 0x8f430144,
-0x431021, 0xaf420090, 0x24020001, 0xaf42008c,
-0x32c20008, 0x10400006, 0x0, 0x8f820214,
-0x3c038100, 0x3042ffff, 0x431025, 0xaf820214,
-0x3c030001, 0x8c636d94, 0x30620002, 0x10400009,
-0x30620001, 0x3c040001, 0x24845fcc, 0x3c050000,
-0x24a56d50, 0x3c060000, 0x24c671c8, 0x10000012,
-0xc53023, 0x10400009, 0x0, 0x3c040001,
-0x24845fdc, 0x3c050000, 0x24a571d0, 0x3c060000,
-0x24c67678, 0x10000008, 0xc53023, 0x3c040001,
-0x24845fec, 0x3c050000, 0x24a56948, 0x3c060000,
-0x24c66d48, 0xc53023, 0x27a70030, 0x27a20034,
-0xc0017a3, 0xafa20010, 0x3c010001, 0xac226ecc,
-0x3c020001, 0x8c426ecc, 0x3c030800, 0x21100,
-0x21182, 0x431025, 0xae420040, 0x8f8200a0,
-0xafa20010, 0x8f8200b0, 0xafa20014, 0x8f86005c,
-0x8f87011c, 0x3c040001, 0x24845ffc, 0x3c010001,
-0xac366ea4, 0x3c010001, 0xac206e94, 0x3c010001,
-0xac3c6e8c, 0x3c010001, 0xac3b6ebc, 0x3c010001,
-0xac376ec0, 0x3c010001, 0xac3a6ea0, 0xc002b3b,
-0x24052400, 0x8f820200, 0xafa20010, 0x8f820220,
-0xafa20014, 0x8f860044, 0x8f870050, 0x3c040001,
-0x24846008, 0xc002b3b, 0x24052500, 0x8f830060,
-0x74100b, 0x242000a, 0x200f821, 0x0,
-0xd, 0x8fbf0060, 0x8fbe005c, 0x8fb50058,
-0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048,
-0x3e00008, 0x27bd0068, 0x27bdffe0, 0x3c040001,
-0x24846014, 0x24052600, 0x3021, 0x3821,
-0xafbf0018, 0xafa00010, 0xc002b3b, 0xafa00014,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x3e00008,
-0x0, 0x3e00008, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x3e00008, 0x0, 0x3e00008, 0x0,
-0x27bdfde0, 0x27a50018, 0x3c04dead, 0x3484beef,
-0xafbf0218, 0x8f820150, 0x3c03001f, 0x3463ffff,
-0xafa40018, 0xa22823, 0xa32824, 0x8ca20000,
-0x1044000a, 0x0, 0xafa50010, 0x8ca20000,
-0xafa20014, 0x8f860150, 0x8f870250, 0x3c040001,
-0x2484601c, 0xc002b3b, 0x24052700, 0x8fbf0218,
-0x3e00008, 0x27bd0220, 0x27bdffe0, 0x3c06abba,
-0x34c6babe, 0xafb00018, 0x3c100004, 0x3c07007f,
-0x34e7ffff, 0xafbf001c, 0x102840, 0x8e040000,
-0x8ca30000, 0xaca00000, 0xae060000, 0x8ca20000,
-0xaca30000, 0x10460005, 0xae040000, 0xa08021,
-0xf0102b, 0x1040fff5, 0x102840, 0x3c040001,
-0x24846028, 0x24052800, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x2001021,
-0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
-0x8c020224, 0x3047003f, 0x10e00010, 0x803021,
-0x2821, 0x24030020, 0xe31024, 0x10400002,
-0x63042, 0xa62821, 0x31842, 0x1460fffb,
-0xe31024, 0x2402f000, 0xa22824, 0x3402ffff,
-0x45102b, 0x14400003, 0x3c020001, 0x10000008,
-0x3c020001, 0x3442ffff, 0x851823, 0x43102b,
-0x14400003, 0xa01021, 0x3c02fffe, 0x821021,
-0x3e00008, 0x0, 0x27bdffd0, 0xafb50028,
-0x8fb50040, 0xafb20020, 0xa09021, 0xafb1001c,
-0x24c60003, 0xafbf002c, 0xafb30024, 0xafb00018,
-0x8ea20000, 0x2403fffc, 0xc38024, 0x50102b,
-0x1440001b, 0xe08821, 0x8e330000, 0xafb00010,
-0x8ea20000, 0xafa20014, 0x8e270000, 0x24053000,
-0xc002b3b, 0x2403021, 0x8e230000, 0x702021,
-0x64102b, 0x10400007, 0x2402821, 0x8ca20000,
-0xac620000, 0x24630004, 0x64102b, 0x1440fffb,
-0x24a50004, 0x8ea20000, 0x501023, 0xaea20000,
-0x8e220000, 0x501021, 0x1000000b, 0xae220000,
-0x2402002d, 0xa0820000, 0xafb00010, 0x8ea20000,
-0x2409821, 0xafa20014, 0x8e270000, 0x24053100,
-0xc002b3b, 0x2603021, 0x2601021, 0x8fbf002c,
-0x8fb50028, 0x8fb30024, 0x8fb20020, 0x8fb1001c,
-0x8fb00018, 0x3e00008, 0x27bd0030, 0x27bdffe8,
-0x3c1cc000, 0x3c05fffe, 0x3c030001, 0x8c636e84,
-0x3c040001, 0x8c846e90, 0x34a5bf08, 0x24021ffc,
-0x3c010001, 0xac226cd0, 0x3c0200c0, 0x3c010001,
-0xac226cd4, 0x3c020020, 0xafbf0010, 0x3c0100c0,
-0xac201ffc, 0x431023, 0x441023, 0x245bb000,
-0x365b821, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021,
-0x3c0400c0, 0x34840200, 0x3c1a00c0, 0x3c0300c0,
-0x346307c8, 0x24021dfc, 0x3c010001, 0xac226cd0,
-0x24021834, 0x3c010001, 0xac246cd4, 0x3c010001,
-0xac226cd0, 0x3c010001, 0xac236cd4, 0xc00180d,
-0x375a0200, 0x8fbf0010, 0x3e00008, 0x27bd0018,
-0x27bdffc8, 0x3c040001, 0x24846034, 0x24053200,
-0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
-0x3021, 0x3603821, 0xafbf0030, 0xafb3002c,
-0xafb20028, 0xafb10024, 0xafb00020, 0xafa2001c,
-0xafa30018, 0xafb70010, 0xc002b3b, 0xafba0014,
-0xc001916, 0x0, 0x8f820240, 0x34420004,
-0xaf820240, 0x24020001, 0xaf420000, 0x3c020001,
-0x571021, 0x904240f4, 0x10400092, 0x2403fffc,
-0x3c100001, 0x2610ac73, 0x3c120001, 0x2652a84c,
-0x2121023, 0x438024, 0x8fa3001c, 0x3c040001,
-0x24846040, 0x70102b, 0x1440001a, 0x27b30018,
-0x8fb10018, 0x24053000, 0x2403021, 0xafb00010,
-0xafa30014, 0xc002b3b, 0x2203821, 0x8fa30018,
-0x702021, 0x64102b, 0x10400007, 0x2403021,
-0x8cc20000, 0xac620000, 0x24630004, 0x64102b,
-0x1440fffb, 0x24c60004, 0x8fa2001c, 0x501023,
-0xafa2001c, 0x8e620000, 0x501021, 0x1000000a,
-0xae620000, 0x2408821, 0x24053100, 0xafb00010,
-0xafa30014, 0x8fa70018, 0x2203021, 0x2402002d,
-0xc002b3b, 0xa0820000, 0x24070020, 0x8fa3001c,
-0x3c040001, 0x2484605c, 0x24120020, 0x3c010001,
-0xac316eb0, 0x2c620020, 0x1440001d, 0x27b10018,
-0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f50,
-0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821,
-0x8fa30018, 0x3c040001, 0x24846f50, 0x24650020,
-0x65102b, 0x10400007, 0x0, 0x8c820000,
-0xac620000, 0x24630004, 0x65102b, 0x1440fffb,
-0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c,
-0x8e220000, 0x521021, 0x1000000b, 0xae220000,
-0x3c100001, 0x26106f50, 0x24053100, 0xafa70010,
-0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d,
-0xc002b3b, 0xa0820000, 0x24070020, 0x3c040001,
-0x24846070, 0x8fa3001c, 0x24120020, 0x3c010001,
-0xac306ee4, 0x2c620020, 0x1440001d, 0x27b10018,
-0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f70,
-0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821,
-0x8fa30018, 0x3c040001, 0x24846f70, 0x24650020,
-0x65102b, 0x10400007, 0x0, 0x8c820000,
-0xac620000, 0x24630004, 0x65102b, 0x1440fffb,
-0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c,
-0x8e220000, 0x521021, 0x1000000b, 0xae220000,
-0x3c100001, 0x26106f70, 0x24053100, 0xafa70010,
-0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d,
-0xc002b3b, 0xa0820000, 0x3c010001, 0x10000031,
-0xac306ee0, 0x3c100001, 0x2610821f, 0x3c120001,
-0x2652809c, 0x2121023, 0x438024, 0x8fa3001c,
-0x3c040001, 0x24846084, 0x70102b, 0x1440001a,
-0x27b30018, 0x8fb10018, 0x24053000, 0x2403021,
-0xafb00010, 0xafa30014, 0xc002b3b, 0x2203821,
-0x8fa30018, 0x702021, 0x64102b, 0x10400007,
-0x2403021, 0x8cc20000, 0xac620000, 0x24630004,
-0x64102b, 0x1440fffb, 0x24c60004, 0x8fa2001c,
-0x501023, 0xafa2001c, 0x8e620000, 0x501021,
-0x1000000a, 0xae620000, 0x2408821, 0x24053100,
-0xafb00010, 0xafa30014, 0x8fa70018, 0x2203021,
-0x2402002d, 0xc002b3b, 0xa0820000, 0x3c010001,
-0xac316eb0, 0x3c030001, 0x8c636eb0, 0x24020400,
-0x60f809, 0xaf820070, 0x8fbf0030, 0x8fb3002c,
-0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
-0x27bd0038, 0x0, 0x0, 0x8f820040,
-0x3c03f000, 0x431024, 0x3c036000, 0x14430006,
-0x0, 0x8f820050, 0x2403ff80, 0x431024,
-0x34420055, 0xaf820050, 0x8f820054, 0x244203e8,
-0xaf820058, 0x240201f4, 0xaf4200e0, 0x24020004,
-0xaf4200e8, 0x24020002, 0xaf4001b0, 0xaf4000e4,
-0xaf4200dc, 0xaf4000d8, 0xaf4000d4, 0x3e00008,
-0xaf4000d0, 0x8f820054, 0x24420005, 0x3e00008,
-0xaf820078, 0x27bdffe8, 0xafbf0010, 0x8f820054,
-0x244203e8, 0xaf820058, 0x3c020800, 0x2c21024,
-0x10400004, 0x3c02f7ff, 0x3442ffff, 0x2c2b024,
-0x36940040, 0x3c020001, 0x8c426da8, 0x10400017,
-0x3c020200, 0x3c030001, 0x8c636f1c, 0x10600016,
-0x282a025, 0x3c020001, 0x8c426e44, 0x14400012,
-0x3c020200, 0x3c020001, 0x8c426d94, 0x30420003,
-0x1440000d, 0x3c020200, 0x8f830224, 0x3c020002,
-0x8c428fec, 0x10620008, 0x3c020200, 0xc003daf,
-0x0, 0x10000004, 0x3c020200, 0xc004196,
-0x0, 0x3c020200, 0x2c21024, 0x10400003,
-0x0, 0xc001f4b, 0x0, 0x8f4200d8,
-0x8f4300dc, 0x24420001, 0xaf4200d8, 0x43102b,
-0x14400003, 0x0, 0xaf4000d8, 0x36940080,
-0x8c030238, 0x1060000c, 0x0, 0x8f4201b0,
-0x244203e8, 0xaf4201b0, 0x43102b, 0x14400006,
-0x0, 0x934205c5, 0x14400003, 0x0,
-0xc001da0, 0x0, 0x8fbf0010, 0x3e00008,
-0x27bd0018, 0x3e00008, 0x0, 0x27bdffd8,
-0xafbf0020, 0x8f43002c, 0x8f420038, 0x10620059,
-0x0, 0x3c020001, 0x571021, 0x904240f0,
-0x10400026, 0x24070008, 0x8f440170, 0x8f450174,
-0x8f48000c, 0x8f860120, 0x24020020, 0xafa20010,
-0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809,
-0x24c6001c, 0x14400011, 0x24020001, 0x3c010001,
-0x370821, 0xa02240f0, 0x8f820124, 0xafa20010,
-0x8f820128, 0x3c040001, 0x24846128, 0xafa20014,
-0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b,
-0x34a50900, 0x1000005c, 0x0, 0x8f420300,
-0x24420001, 0xaf420300, 0x8f420300, 0x8f42002c,
-0xa34005c1, 0x10000027, 0xaf420038, 0x8f440170,
-0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
-0x24020080, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
-0x24020001, 0x3c010001, 0x370821, 0xa02240f1,
-0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x24846134, 0xafa20014, 0x8f46002c, 0x8f870120,
-0x3c050009, 0xc002b3b, 0x34a51100, 0x10000036,
-0x0, 0x8f420300, 0x8f43002c, 0x24420001,
-0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1,
-0xaf430038, 0x3c010001, 0x370821, 0xa02040f1,
-0x3c010001, 0x370821, 0xa02040f0, 0x10000026,
-0xaf400034, 0x934205c1, 0x1040001d, 0x0,
-0xa34005c1, 0x8f820040, 0x30420001, 0x14400008,
-0x2021, 0x8c030104, 0x24020001, 0x50620005,
-0x24040001, 0x8c020264, 0x10400003, 0x801021,
-0x24040001, 0x801021, 0x10400006, 0x0,
-0x8f42030c, 0x24420001, 0xaf42030c, 0x10000008,
-0x8f42030c, 0x8f820044, 0x34420004, 0xaf820044,
-0x8f420308, 0x24420001, 0xaf420308, 0x8f420308,
-0x3c010001, 0x370821, 0xa02040f0, 0x3c010001,
-0x370821, 0xa02040f1, 0x8f420000, 0x10400007,
-0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd,
-0x0, 0x10000005, 0x0, 0xaf800048,
-0x8f820048, 0x1040fffd, 0x0, 0x8f820060,
-0x3c03ff7f, 0x3463ffff, 0x431024, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x10000002,
-0xaf80004c, 0xaf800048, 0x8fbf0020, 0x3e00008,
-0x27bd0028, 0x3e00008, 0x0, 0x27bdffd8,
-0xafbf0020, 0x8f430044, 0x8f42007c, 0x10620029,
-0x24070008, 0x8f440168, 0x8f45016c, 0x8f48000c,
-0x8f860120, 0x24020040, 0xafa20010, 0xafa30014,
-0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400011, 0x24020001, 0x3c010001, 0x370821,
-0xa02240f2, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x2484613c, 0xafa20014, 0x8f460044,
-0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51300,
-0x1000000f, 0x0, 0x8f420304, 0x24420001,
-0xaf420304, 0x8f420304, 0x8f420044, 0xaf42007c,
-0x3c010001, 0x370821, 0xa02040f2, 0x10000004,
-0xaf400078, 0x3c010001, 0x370821, 0xa02040f2,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x3c03feff, 0x3463ffff,
-0x431024, 0xaf820060, 0x8f420000, 0x10400003,
-0x0, 0x10000002, 0xaf80004c, 0xaf800048,
-0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008,
-0x0, 0x3c020001, 0x8c426da8, 0x27bdffa8,
-0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044,
-0xafb20040, 0xafb1003c, 0xafb00038, 0x104000d5,
-0x8f900044, 0x8f4200d0, 0x24430001, 0x2842000b,
-0x144000e4, 0xaf4300d0, 0x8f420004, 0x30420002,
-0x1440009c, 0xaf4000d0, 0x8f420004, 0x3c030001,
-0x8c636d98, 0x34420002, 0xaf420004, 0x24020001,
-0x14620003, 0x3c020600, 0x10000002, 0x34423000,
-0x34421000, 0xafa20020, 0x8f4a0018, 0xafaa0034,
-0x27aa0020, 0xafaa002c, 0x8faa0034, 0x240200ff,
-0x11420002, 0x1821, 0x25430001, 0x8c020228,
-0x609821, 0x1662000e, 0x3c050009, 0x8f42033c,
-0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228,
-0x8fa70034, 0x3c040001, 0x2484610c, 0xafa00014,
-0xafa20010, 0x8fa60020, 0x10000070, 0x34a50500,
-0x8faa0034, 0xa38c0, 0xf71021, 0x8fa30020,
-0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054,
-0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9,
-0x1040001b, 0xa821, 0xe09021, 0x265e04c0,
-0x8f440178, 0x8f45017c, 0x2401821, 0x240a0004,
-0xafaa0010, 0xafb30014, 0x8f48000c, 0x1021,
-0x2fe3021, 0xafa80018, 0x8f48010c, 0x24070008,
-0xa32821, 0xa3482b, 0x822021, 0x100f809,
-0x892021, 0x54400006, 0x24150001, 0x8f820054,
-0x2221023, 0x2c4203e9, 0x1440ffe9, 0x0,
-0x32a200ff, 0x54400018, 0xaf530018, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa002c, 0x8fa70034, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846118, 0xafa20014, 0x8d460000,
-0x3c050009, 0x10000035, 0x34a50600, 0x8f420308,
-0x24150001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001e, 0x32a200ff, 0x8f830054, 0x8f820054,
-0x247103e8, 0x2221023, 0x2c4203e9, 0x10400016,
-0xa821, 0x3c1e0020, 0x24120010, 0x8f42000c,
-0x8f440160, 0x8f450164, 0x8f860120, 0xafb20010,
-0xafb30014, 0x5e1025, 0xafa20018, 0x8f42010c,
-0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3,
-0x0, 0x8f820054, 0x2221023, 0x2c4203e9,
-0x1440ffee, 0x0, 0x32a200ff, 0x14400011,
-0x3c050009, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0x8fa70034,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846120,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
-0x0, 0x8f4202ec, 0x24420001, 0xaf4202ec,
-0x8f4202ec, 0x8f420004, 0x30420001, 0x50400029,
-0x36100040, 0x3c020400, 0x2c21024, 0x10400013,
-0x2404ffdf, 0x8f420250, 0x8f430254, 0x8f4401b4,
-0x14640006, 0x36100040, 0x8f420270, 0x8f430274,
-0x8f4401b8, 0x10640007, 0x2402ffdf, 0x8f420250,
-0x8f430254, 0x8f440270, 0x8f450274, 0x10000012,
-0x3a100020, 0x1000002b, 0x2028024, 0x8f420250,
-0x8f430254, 0x8f4501b4, 0x14650006, 0x2048024,
-0x8f420270, 0x8f430274, 0x8f4401b8, 0x50640021,
-0x36100040, 0x8f420250, 0x8f430254, 0x8f440270,
-0x8f450274, 0x3a100040, 0xaf4301b4, 0x10000019,
-0xaf4501b8, 0x8f4200d4, 0x24430001, 0x10000011,
-0x28420033, 0x8f420004, 0x30420001, 0x10400009,
-0x3c020400, 0x2c21024, 0x10400004, 0x2402ffdf,
-0x2028024, 0x1000000b, 0x36100040, 0x10000009,
-0x36100060, 0x8f4200d4, 0x36100040, 0x24430001,
-0x284201f5, 0x14400003, 0xaf4300d4, 0xaf4000d4,
-0x3a100020, 0xaf900044, 0x2402ff7f, 0x282a024,
-0x8fbf0050, 0x8fbe004c, 0x8fb50048, 0x8fb30044,
-0x8fb20040, 0x8fb1003c, 0x8fb00038, 0x3e00008,
-0x27bd0058, 0x3e00008, 0x0, 0x3c020001,
-0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
-0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
-0x104000c7, 0xafb00030, 0x8f4200d0, 0x24430001,
-0x2842000b, 0x144000da, 0xaf4300d0, 0x8f420004,
-0x30420002, 0x14400097, 0xaf4000d0, 0x8f420004,
-0x3c030001, 0x8c636d98, 0x34420002, 0xaf420004,
-0x24020001, 0x14620003, 0x3c020600, 0x10000002,
-0x34423000, 0x34421000, 0xafa20020, 0x1821,
-0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
-0xafaa002c, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006d, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846118, 0x3c050009, 0xafa20014,
-0x8d460000, 0x10000035, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001e, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400016,
-0x9821, 0x3c150020, 0x24110010, 0x8f42000c,
-0x8f440160, 0x8f450164, 0x8f860120, 0xafb10010,
-0xafb20014, 0x551025, 0xafa20018, 0x8f42010c,
-0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe3,
-0x0, 0x8f820054, 0x2021023, 0x2c4203e9,
-0x1440ffee, 0x0, 0x326200ff, 0x14400011,
-0x0, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846120, 0x3c050009,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
-0x3c03821, 0x8f4202ec, 0x24420001, 0xaf4202ec,
-0x8f4202ec, 0x8f420004, 0x30420001, 0x10400018,
-0x24040001, 0x8f420250, 0x8f430254, 0x8f4501b4,
-0x3c010001, 0x14650006, 0xa0246cf1, 0x8f420270,
-0x8f430274, 0x8f4401b8, 0x10640021, 0x0,
-0x8f420250, 0x8f430254, 0x3c040001, 0x90846cf0,
-0x8f460270, 0x8f470274, 0x38840001, 0xaf4301b4,
-0xaf4701b8, 0x3c010001, 0x10000025, 0xa0246cf0,
-0x8f4200d4, 0x3c010001, 0xa0206cf0, 0x24430001,
-0x28420033, 0x1440001e, 0xaf4300d4, 0x3c020001,
-0x90426cf1, 0xaf4000d4, 0x10000017, 0x38420001,
-0x8f420004, 0x30420001, 0x10400008, 0x0,
-0xc00565a, 0x2021, 0x3c010001, 0xa0206cf1,
-0x3c010001, 0x1000000e, 0xa0206cf0, 0x8f4200d4,
-0x3c010001, 0xa0206cf0, 0x24430001, 0x284201f5,
-0x14400007, 0xaf4300d4, 0x3c020001, 0x90426cf1,
-0xaf4000d4, 0x421026, 0x3c010001, 0xa0226cf1,
-0x3c030001, 0x8c636d98, 0x24020002, 0x1462000c,
-0x3c030002, 0x3c030001, 0x90636cf1, 0x24020001,
-0x5462001f, 0x2021, 0x3c020001, 0x90426cf0,
-0x1443001b, 0x24040005, 0x10000019, 0x24040006,
-0x3c020002, 0x8c428ff4, 0x431024, 0x1040000b,
-0x24020001, 0x3c030001, 0x90636cf1, 0x54620010,
-0x2021, 0x3c020001, 0x90426cf0, 0x1443000c,
-0x24040003, 0x1000000a, 0x24040004, 0x3c030001,
-0x90636cf1, 0x14620006, 0x2021, 0x3c020001,
-0x90426cf0, 0x24040001, 0x50440001, 0x24040002,
-0xc00565a, 0x0, 0x2402ff7f, 0x282a024,
-0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
-0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
-0x27bd0050, 0x3e00008, 0x0, 0x3c020001,
-0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
-0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
-0x104000de, 0xafb00030, 0x8f4200d0, 0x3c040001,
-0x8c846d98, 0x24430001, 0x2842000b, 0xaf4400e8,
-0x144000fe, 0xaf4300d0, 0x8f420004, 0x30420002,
-0x14400095, 0xaf4000d0, 0x8f420004, 0x34420002,
-0xaf420004, 0x24020001, 0x14820003, 0x3c020600,
-0x10000002, 0x34423000, 0x34421000, 0xafa20020,
-0x1821, 0x8f5e0018, 0x27aa0020, 0x240200ff,
-0x13c20002, 0xafaa002c, 0x27c30001, 0x8c020228,
-0x609021, 0x1642000e, 0x1e38c0, 0x8f42033c,
-0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228,
-0x3c040001, 0x2484610c, 0x3c050009, 0xafa00014,
-0xafa20010, 0x8fa60020, 0x1000006d, 0x34a50500,
-0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0,
-0xac4404c4, 0x8f830054, 0x8f820054, 0x247003e8,
-0x2021023, 0x2c4203e9, 0x1040001b, 0x9821,
-0xe08821, 0x263504c0, 0x8f440178, 0x8f45017c,
-0x2201821, 0x240a0004, 0xafaa0010, 0xafb20014,
-0x8f48000c, 0x1021, 0x2f53021, 0xafa80018,
-0x8f48010c, 0x24070008, 0xa32821, 0xa3482b,
-0x822021, 0x100f809, 0x892021, 0x54400006,
-0x24130001, 0x8f820054, 0x2021023, 0x2c4203e9,
-0x1440ffe9, 0x0, 0x326200ff, 0x54400017,
-0xaf520018, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846118, 0x3c050009,
-0xafa20014, 0x8d460000, 0x10000035, 0x34a50600,
-0x8f420308, 0x24130001, 0x24420001, 0xaf420308,
-0x8f420308, 0x1000001e, 0x326200ff, 0x8f830054,
-0x8f820054, 0x247003e8, 0x2021023, 0x2c4203e9,
-0x10400016, 0x9821, 0x3c150020, 0x24110010,
-0x8f42000c, 0x8f440160, 0x8f450164, 0x8f860120,
-0xafb10010, 0xafb20014, 0x551025, 0xafa20018,
-0x8f42010c, 0x24070008, 0x40f809, 0x24c6001c,
-0x1440ffe3, 0x0, 0x8f820054, 0x2021023,
-0x2c4203e9, 0x1440ffee, 0x0, 0x326200ff,
-0x14400011, 0x0, 0x8f420378, 0x24420001,
-0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846120,
-0x3c050009, 0xafa20014, 0x8d460000, 0x34a50700,
-0xc002b3b, 0x3c03821, 0x8f4202ec, 0x24420001,
-0xaf4202ec, 0x8f4202ec, 0x8f420004, 0x30420001,
-0x10400033, 0x3c020400, 0x2c21024, 0x10400017,
-0x0, 0x934205c0, 0x8f440250, 0x8f450254,
-0x8f4301b4, 0x34420020, 0x14a30006, 0xa34205c0,
-0x8f420270, 0x8f430274, 0x8f4401b8, 0x10640008,
-0x0, 0x8f420250, 0x8f430254, 0x934405c0,
-0x8f460270, 0x8f470274, 0x10000016, 0x38840040,
-0x934205c0, 0x10000048, 0x304200bf, 0x934205c0,
-0x8f440250, 0x8f450254, 0x8f4301b4, 0x304200bf,
-0x14a30006, 0xa34205c0, 0x8f420270, 0x8f430274,
-0x8f4401b8, 0x1064000b, 0x0, 0x8f420250,
-0x8f430254, 0x934405c0, 0x8f460270, 0x8f470274,
-0x38840020, 0xaf4301b4, 0xaf4701b8, 0x10000033,
-0xa34405c0, 0x934205c0, 0x1000002f, 0x34420020,
-0x934205c0, 0x8f4300d4, 0x34420020, 0xa34205c0,
-0x24620001, 0x10000023, 0x28630033, 0x8f4200e4,
-0x8f4300e0, 0x24420001, 0xaf4200e4, 0x43102a,
-0x14400006, 0x24030001, 0x8f4200e8, 0x14430002,
-0xaf4000e4, 0x24030004, 0xaf4300e8, 0x8f420004,
-0x30420001, 0x1040000d, 0x3c020400, 0x2c21024,
-0x10400007, 0x0, 0x934205c0, 0x34420040,
-0xa34205c0, 0x934205c0, 0x1000000f, 0x304200df,
-0x934205c0, 0x1000000c, 0x34420060, 0x934205c0,
-0x8f4300d4, 0x34420020, 0xa34205c0, 0x24620001,
-0x286300fb, 0x14600005, 0xaf4200d4, 0x934205c0,
-0xaf4000d4, 0x38420040, 0xa34205c0, 0x934205c0,
-0x8f4300e8, 0x3042007f, 0xa34205c0, 0x24020001,
-0x14620005, 0x0, 0x934405c0, 0x42102,
-0x10000003, 0x348400f0, 0x934405c0, 0x3484000f,
-0xc005640, 0x0, 0x2402ff7f, 0x282a024,
-0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
-0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
-0x27bd0050, 0x3e00008, 0x0, 0x27bdffb0,
-0x274401c0, 0x26e30028, 0x24650400, 0x65102b,
-0xafbf0048, 0xafbe0044, 0xafb50040, 0xafb3003c,
-0xafb20038, 0xafb10034, 0x10400007, 0xafb00030,
-0x8c820000, 0xac620000, 0x24630004, 0x65102b,
-0x1440fffb, 0x24840004, 0x8c020080, 0xaee20044,
-0x8c0200c0, 0xaee20040, 0x8c020084, 0xaee20030,
-0x8c020084, 0xaee2023c, 0x8c020088, 0xaee20240,
-0x8c02008c, 0xaee20244, 0x8c020090, 0xaee20248,
-0x8c020094, 0xaee2024c, 0x8c020098, 0xaee20250,
-0x8c02009c, 0xaee20254, 0x8c0200a0, 0xaee20258,
-0x8c0200a4, 0xaee2025c, 0x8c0200a8, 0xaee20260,
-0x8c0200ac, 0xaee20264, 0x8c0200b0, 0xaee20268,
-0x8c0200b4, 0xaee2026c, 0x8c0200b8, 0xaee20270,
-0x8c0200bc, 0x24040001, 0xaee20274, 0xaee00034,
-0x41080, 0x571021, 0x8ee30034, 0x8c42023c,
-0x24840001, 0x621821, 0x2c82000f, 0xaee30034,
-0x1440fff8, 0x41080, 0x8c0200cc, 0xaee20048,
-0x8c0200d0, 0xaee2004c, 0x8c0200e0, 0xaee201f8,
-0x8c0200e4, 0xaee201fc, 0x8c0200e8, 0xaee20200,
-0x8c0200ec, 0xaee20204, 0x8c0200f0, 0xaee20208,
-0x8ee400c0, 0x8ee500c4, 0x8c0200fc, 0x45102b,
-0x1040000b, 0x0, 0x8ee200c0, 0x8ee300c4,
-0x24040001, 0x24050000, 0x651821, 0x65302b,
-0x441021, 0x461021, 0xaee200c0, 0xaee300c4,
-0x8c0200fc, 0x8ee400c0, 0x8ee500c4, 0x2408ffff,
-0x24090000, 0x401821, 0x1021, 0x882024,
-0xa92824, 0x822025, 0xa32825, 0xaee400c0,
-0xaee500c4, 0x8ee400d0, 0x8ee500d4, 0x8c0200f4,
-0x45102b, 0x1040000b, 0x0, 0x8ee200d0,
-0x8ee300d4, 0x24040001, 0x24050000, 0x651821,
-0x65302b, 0x441021, 0x461021, 0xaee200d0,
-0xaee300d4, 0x8c0200f4, 0x8ee400d0, 0x8ee500d4,
-0x401821, 0x1021, 0x882024, 0xa92824,
-0x822025, 0xa32825, 0xaee400d0, 0xaee500d4,
-0x8ee400c8, 0x8ee500cc, 0x8c0200f8, 0x45102b,
-0x1040000b, 0x0, 0x8ee200c8, 0x8ee300cc,
-0x24040001, 0x24050000, 0x651821, 0x65302b,
-0x441021, 0x461021, 0xaee200c8, 0xaee300cc,
-0x8c0200f8, 0x8ee400c8, 0x8ee500cc, 0x401821,
-0x1021, 0x882024, 0xa92824, 0x822025,
-0xa32825, 0x24020008, 0xaee400c8, 0xaee500cc,
-0xafa20010, 0xafa00014, 0x8f42000c, 0x8c040208,
-0x8c05020c, 0xafa20018, 0x8f42010c, 0x26e60028,
-0x40f809, 0x24070400, 0x104000f0, 0x3c020400,
-0xafa20020, 0x934205c6, 0x10400089, 0x1821,
-0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
-0xafaa002c, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846118, 0x3c050009, 0xafa20014,
-0x8d460000, 0x10000033, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014,
-0x9821, 0x24110010, 0x8f42000c, 0x8f440160,
-0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffef, 0x0,
-0x326200ff, 0x54400012, 0x24020001, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846120, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x1021,
-0x1440005b, 0x24020001, 0x10000065, 0x0,
-0x8f510018, 0x240200ff, 0x12220002, 0x8021,
-0x26300001, 0x8c020228, 0x1602000e, 0x1130c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x248460f4, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f,
-0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
-0x8f45017c, 0x1021, 0x24070004, 0xafa70010,
-0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x248460fc, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200,
-0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018,
-0x8f860120, 0x24020010, 0xafa20010, 0xafb00014,
-0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x54400011, 0x24020001, 0x8f420340, 0x24420001,
-0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846104, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b,
-0x2203821, 0x1021, 0x1040000d, 0x24020001,
-0x8f4202e8, 0xa34005c6, 0xaf4001b0, 0x24420001,
-0xaf4202e8, 0x8f4202e8, 0x8ee20150, 0x24420001,
-0xaee20150, 0x10000003, 0x8ee20150, 0x24020001,
-0xa34205c6, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
-0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
-0x3e00008, 0x27bd0050, 0x27bdffd8, 0xafbf0020,
-0x8f8200b0, 0x30420004, 0x10400068, 0x0,
-0x8f430128, 0x8f820104, 0x14620005, 0x0,
-0x8f430130, 0x8f8200b4, 0x10620006, 0x0,
-0x8f820104, 0xaf420128, 0x8f8200b4, 0x1000005b,
-0xaf420130, 0x8f8200b0, 0x3c030080, 0x431024,
-0x1040000d, 0x0, 0x8f82011c, 0x34420002,
-0xaf82011c, 0x8f8200b0, 0x2403fffb, 0x431024,
-0xaf8200b0, 0x8f82011c, 0x2403fffd, 0x431024,
-0x1000004a, 0xaf82011c, 0x8f430128, 0x8f820104,
-0x14620005, 0x0, 0x8f430130, 0x8f8200b4,
-0x10620010, 0x0, 0x8f820104, 0xaf420128,
-0x8f8200b4, 0x8f430128, 0xaf420130, 0xafa30010,
-0x8f420130, 0x3c040001, 0x24846144, 0xafa20014,
-0x8f86011c, 0x8f8700b0, 0x3c050005, 0x10000031,
-0x34a50900, 0x8f420128, 0xafa20010, 0x8f420130,
-0x3c040001, 0x24846150, 0xafa20014, 0x8f86011c,
-0x8f8700b0, 0x3c050005, 0xc002b3b, 0x34a51000,
-0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104,
-0x8f8200b0, 0x34420001, 0xaf8200b0, 0x24020008,
-0xaf830104, 0xafa20010, 0xafa00014, 0x8f42000c,
-0x8c040208, 0x8c05020c, 0xafa20018, 0x8f42010c,
-0x26e60028, 0x40f809, 0x24070400, 0x8f82011c,
-0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc,
-0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f420128,
-0xafa20010, 0x8f420130, 0x3c040001, 0x2484615c,
-0xafa20014, 0x8f86011c, 0x8f8700b0, 0x3c050005,
-0x34a51100, 0xc002b3b, 0x0, 0x8f8200a0,
-0x30420004, 0x10400069, 0x0, 0x8f43012c,
-0x8f820124, 0x14620005, 0x0, 0x8f430134,
-0x8f8200a4, 0x10620006, 0x0, 0x8f820124,
-0xaf42012c, 0x8f8200a4, 0x1000005c, 0xaf420134,
-0x8f8200a0, 0x3c030080, 0x431024, 0x1040000d,
-0x0, 0x8f82011c, 0x34420002, 0xaf82011c,
-0x8f8200a0, 0x2403fffb, 0x431024, 0xaf8200a0,
-0x8f82011c, 0x2403fffd, 0x431024, 0x1000004b,
-0xaf82011c, 0x8f43012c, 0x8f820124, 0x14620005,
-0x0, 0x8f430134, 0x8f8200a4, 0x10620010,
-0x0, 0x8f820124, 0xaf42012c, 0x8f8200a4,
-0x8f43012c, 0xaf420134, 0xafa30010, 0x8f420134,
-0x3c040001, 0x24846168, 0xafa20014, 0x8f86011c,
-0x8f8700a0, 0x3c050005, 0x10000032, 0x34a51200,
-0x8f42012c, 0xafa20010, 0x8f420134, 0x3c040001,
-0x24846174, 0xafa20014, 0x8f86011c, 0x8f8700a0,
-0x3c050005, 0xc002b3b, 0x34a51300, 0x8f82011c,
-0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0,
-0x34420001, 0xaf8200a0, 0x24020080, 0xaf830124,
-0xafa20010, 0xafa00014, 0x8f420014, 0x8c040208,
-0x8c05020c, 0xafa20018, 0x8f420108, 0x3c060001,
-0x24c66ed8, 0x40f809, 0x24070004, 0x8f82011c,
-0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc,
-0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f42012c,
-0xafa20010, 0x8f420134, 0x3c040001, 0x24846180,
-0xafa20014, 0x8f86011c, 0x8f8700a0, 0x3c050005,
-0x34a51400, 0xc002b3b, 0x0, 0x8fbf0020,
-0x3e00008, 0x27bd0028, 0x3c081000, 0x24070001,
-0x3c060080, 0x3c050100, 0x8f820070, 0x481024,
-0x1040fffd, 0x0, 0x8f820054, 0x24420005,
-0xaf820078, 0x8c040234, 0x10800016, 0x1821,
-0x3c020001, 0x571021, 0x8c4240e8, 0x24420005,
-0x3c010001, 0x370821, 0xac2240e8, 0x3c020001,
-0x571021, 0x8c4240e8, 0x44102b, 0x14400009,
-0x0, 0x3c030080, 0x3c010001, 0x370821,
-0xac2040e8, 0x3c010001, 0x370821, 0x1000000b,
-0xa02740f0, 0x3c020001, 0x571021, 0x904240f0,
-0x54400006, 0x661825, 0x3c020001, 0x571021,
-0x904240f1, 0x54400001, 0x661825, 0x8c040230,
-0x10800013, 0x0, 0x3c020001, 0x571021,
-0x8c4240ec, 0x24420005, 0x3c010001, 0x370821,
-0xac2240ec, 0x3c020001, 0x571021, 0x8c4240ec,
-0x44102b, 0x14400006, 0x0, 0x3c010001,
-0x370821, 0xac2040ec, 0x10000006, 0x651825,
-0x3c020001, 0x571021, 0x904240f2, 0x54400001,
-0x651825, 0x1060ffbc, 0x0, 0x8f420000,
-0x10400007, 0x0, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x431025, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x1000ffa7, 0xaf80004c,
-0x1000ffa5, 0xaf800048, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0xafbf0018, 0x8f860064, 0x30c20004, 0x10400025,
-0x24040004, 0x8c020114, 0xaf420020, 0xaf840064,
-0x8f4202fc, 0x24420001, 0xaf4202fc, 0x8f4202fc,
-0x8f820064, 0x30420004, 0x14400005, 0x0,
-0x8c030114, 0x8f420020, 0x1462fff2, 0x0,
-0x8f420000, 0x10400007, 0x8f43003c, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x431025, 0xaf820060,
-0x8f420000, 0x10400073, 0x0, 0x1000006f,
-0x0, 0x30c20008, 0x10400020, 0x24040008,
-0x8c02011c, 0xaf420048, 0xaf840064, 0x8f4202a8,
-0x24420001, 0xaf4202a8, 0x8f4202a8, 0x8f820064,
-0x30420008, 0x14400005, 0x0, 0x8c03011c,
-0x8f420048, 0x1462fff2, 0x0, 0x8f420000,
-0x10400007, 0x0, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x1000ffd9, 0x34420200, 0x30c20020,
-0x10400023, 0x24040020, 0x8c02012c, 0xaf420068,
-0xaf840064, 0x8f4202d8, 0x24420001, 0xaf4202d8,
-0x8f4202d8, 0x8f820064, 0x30420020, 0x14400005,
-0x32c24000, 0x8c03012c, 0x8f420068, 0x1462fff2,
-0x32c24000, 0x14400002, 0x3c020001, 0x2c2b025,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x1000ffb4, 0x34420800,
-0x30c20010, 0x10400029, 0x24040010, 0x8c020124,
-0xaf420058, 0xaf840064, 0x8f4202d4, 0x24420001,
-0xaf4202d4, 0x8f4202d4, 0x8f820064, 0x30420010,
-0x14400005, 0x32c22000, 0x8c030124, 0x8f420058,
-0x1462fff2, 0x32c22000, 0x50400001, 0x36d68000,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x34420100, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x1000006c,
-0xaf80004c, 0x1000006a, 0xaf800048, 0x30c20001,
-0x10400004, 0x24020001, 0xaf820064, 0x10000064,
-0x0, 0x30c20002, 0x1440000b, 0x3c050003,
-0x3c040001, 0x24846244, 0x34a50500, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x2402ffc0,
-0x10000057, 0xaf820064, 0x8c05022c, 0x8c02010c,
-0x10a20048, 0x51080, 0x8c460300, 0x24a20001,
-0x3045003f, 0x24020003, 0xac05022c, 0x61e02,
-0x10620005, 0x24020010, 0x1062001d, 0x30c20fff,
-0x10000039, 0x0, 0x8f4302a8, 0x8f440000,
-0x30c20fff, 0xaf420048, 0x24630001, 0xaf4302a8,
-0x10800007, 0x8f4202a8, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x34420200, 0xaf820060, 0x8f420000,
-0x1040001f, 0x0, 0x1000001b, 0x0,
-0xaf420058, 0x32c22000, 0x50400001, 0x36d68000,
-0x8f4202d4, 0x8f430000, 0x24420001, 0xaf4202d4,
-0x10600007, 0x8f4202d4, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x34420100, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x10000006, 0xaf80004c,
-0x10000004, 0xaf800048, 0xc002196, 0xc02021,
-0x402821, 0x8c02010c, 0x14a20002, 0x24020002,
-0xaf820064, 0x8f820064, 0x30420002, 0x14400004,
-0x0, 0x8c02010c, 0x14a2ffac, 0x0,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x3e00008,
-0x0, 0x27bdffa0, 0xafb00040, 0x808021,
-0x101602, 0x2442ffff, 0x304300ff, 0x2c620013,
-0xafbf0058, 0xafbe0054, 0xafb50050, 0xafb3004c,
-0xafb20048, 0xafb10044, 0x104001f3, 0xafa50034,
-0x31080, 0x3c010001, 0x220821, 0x8c226288,
-0x400008, 0x0, 0x101302, 0x30440fff,
-0x24020001, 0x10820005, 0x24020002, 0x1082000c,
-0x2402fffe, 0x10000024, 0x3c050003, 0x8f430004,
-0x3c020001, 0x8c426f04, 0xaf440200, 0xaf440204,
-0x3c040001, 0x8c846e80, 0x10000009, 0x34630001,
-0x8f430004, 0xaf440200, 0xaf440204, 0x3c040001,
-0x8c846e80, 0x621824, 0x3c020001, 0x2442ca28,
-0x21100, 0x21182, 0xaf430004, 0x3c030800,
-0x431025, 0xac820038, 0x8f840054, 0x41442,
-0x41c82, 0x431021, 0x41cc2, 0x431023,
-0x41d02, 0x431021, 0x41d42, 0x431023,
-0x10000009, 0xaf420208, 0x3c040001, 0x24846250,
-0x34a51000, 0x2003021, 0x3821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8f4202a0, 0x24420001,
-0xaf4202a0, 0x1000021f, 0x8f4202a0, 0x27b00028,
-0x2002021, 0x24050210, 0xc002bbf, 0x24060008,
-0xc002518, 0x2002021, 0x10000216, 0x0,
-0x8faa0034, 0x27a40028, 0xa1880, 0x25420001,
-0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034,
-0x21080, 0x8c430300, 0x25420001, 0x3042003f,
-0xafa20034, 0xac02022c, 0xafa50028, 0xc002518,
-0xafa3002c, 0x10000203, 0x0, 0x27b00028,
-0x2002021, 0x24050210, 0xc002bbf, 0x24060008,
-0xc002657, 0x2002021, 0x100001fa, 0x0,
-0x8faa0034, 0x27a40028, 0xa1880, 0x25420001,
-0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034,
-0x21080, 0x8c430300, 0x25420001, 0x3042003f,
-0xafa20034, 0xac02022c, 0xafa50028, 0xc002657,
-0xafa3002c, 0x100001e7, 0x0, 0x101302,
-0x30430fff, 0x24020001, 0x10620005, 0x24020002,
-0x1062001e, 0x3c020002, 0x10000033, 0x3c050003,
-0x3c030002, 0x2c31024, 0x54400037, 0x2c3b025,
-0x8f820228, 0x3c010001, 0x370821, 0xac2238d8,
-0x8f82022c, 0x3c010001, 0x370821, 0xac2238dc,
-0x8f820230, 0x3c010001, 0x370821, 0xac2238e0,
-0x8f820234, 0x3c010001, 0x370821, 0xac2238e4,
-0x2402ffff, 0xaf820228, 0xaf82022c, 0xaf820230,
-0xaf820234, 0x10000020, 0x2c3b025, 0x2c21024,
-0x10400012, 0x3c02fffd, 0x3c020001, 0x571021,
-0x8c4238d8, 0xaf820228, 0x3c020001, 0x571021,
-0x8c4238dc, 0xaf82022c, 0x3c020001, 0x571021,
-0x8c4238e0, 0xaf820230, 0x3c020001, 0x571021,
-0x8c4238e4, 0xaf820234, 0x3c02fffd, 0x3442ffff,
-0x10000009, 0x2c2b024, 0x3c040001, 0x2484625c,
-0x34a51100, 0x2003021, 0x3821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8f4202cc, 0x24420001,
-0xaf4202cc, 0x1000019f, 0x8f4202cc, 0x101302,
-0x30450fff, 0x24020001, 0x10a20005, 0x24020002,
-0x10a2000d, 0x3c0408ff, 0x10000014, 0x3c050003,
-0x3c0208ff, 0x3442ffff, 0x8f830220, 0x3c040004,
-0x2c4b025, 0x621824, 0x34630008, 0xaf830220,
-0x10000012, 0xaf450298, 0x3484fff7, 0x3c03fffb,
-0x8f820220, 0x3463ffff, 0x2c3b024, 0x441024,
-0xaf820220, 0x10000009, 0xaf450298, 0x3c040001,
-0x24846268, 0x34a51200, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202bc,
-0x24420001, 0xaf4202bc, 0x10000176, 0x8f4202bc,
-0x27840208, 0x24050200, 0xc002bbf, 0x24060008,
-0x27440224, 0x24050200, 0xc002bbf, 0x24060008,
-0x8f4202c4, 0x24420001, 0xaf4202c4, 0x10000169,
-0x8f4202c4, 0x101302, 0x30430fff, 0x24020001,
-0x10620011, 0x28620002, 0x50400005, 0x24020002,
-0x10600007, 0x0, 0x10000017, 0x0,
-0x1062000f, 0x0, 0x10000013, 0x0,
-0x8c060248, 0x2021, 0xc005104, 0x24050004,
-0x10000007, 0x0, 0x8c060248, 0x2021,
-0xc005104, 0x24050004, 0x10000010, 0x0,
-0x8c06024c, 0x2021, 0xc005104, 0x24050001,
-0x1000000a, 0x0, 0x3c040001, 0x24846274,
-0x3c050003, 0x34a51300, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202c0,
-0x24420001, 0xaf4202c0, 0x1000013a, 0x8f4202c0,
-0xc002426, 0x0, 0x10000136, 0x0,
-0x24020001, 0xa34205c5, 0x24100100, 0x8f4401a8,
-0x8f4501ac, 0xafb00010, 0xafa00014, 0x8f420014,
-0xafa20018, 0x8f420108, 0x26e60028, 0x40f809,
-0x24070400, 0x1040fff5, 0x0, 0x10000125,
-0x0, 0x3c03ffff, 0x34637fff, 0x8f420368,
-0x8f440360, 0x2c3b024, 0x1821, 0xaf400058,
-0xaf40005c, 0xaf400060, 0xaf400064, 0x441023,
-0xaf420368, 0x3c020900, 0xaf400360, 0xafa20020,
-0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
-0xafaa003c, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484620c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8faa003c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846218, 0x3c050009, 0xafa20014,
-0x8d460000, 0x10000033, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014,
-0x9821, 0x24110010, 0x8f42000c, 0x8f440160,
-0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffef, 0x0,
-0x326200ff, 0x14400011, 0x0, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa003c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846220, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b0,
-0x24420001, 0xaf4202b0, 0x8f4202b0, 0x8f4202f8,
-0x24420001, 0xaf4202f8, 0x1000008a, 0x8f4202f8,
-0x8c02025c, 0x27440224, 0xaf4201f0, 0x8c020260,
-0x24050200, 0x24060008, 0xc002bbf, 0xaf4201f8,
-0x8f820220, 0x30420008, 0x14400002, 0x24020001,
-0x24020002, 0xaf420298, 0x8f4202ac, 0x24420001,
-0xaf4202ac, 0x10000077, 0x8f4202ac, 0x3c0200ff,
-0x3442ffff, 0x2021824, 0x32c20180, 0x14400006,
-0x3402fffb, 0x43102b, 0x14400003, 0x0,
-0x1000006c, 0xaf4300bc, 0x3c040001, 0x24846280,
-0x3c050003, 0x34a51500, 0x2003021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020700,
-0x34421000, 0x101e02, 0x621825, 0xafa30020,
-0x8f510018, 0x240200ff, 0x12220002, 0x8021,
-0x26300001, 0x8c020228, 0x1602000e, 0x1130c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x248461f4, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f,
-0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
-0x8f45017c, 0x1021, 0x24070004, 0xafa70010,
-0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x248461fc, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200,
-0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018,
-0x8f860120, 0x24020010, 0xafa20010, 0xafb00014,
-0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400010, 0x0, 0x8f420340, 0x24420001,
-0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846204, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b,
-0x2203821, 0x8f4202e0, 0x24420001, 0xaf4202e0,
-0x8f4202e0, 0x8f4202f0, 0x24420001, 0xaf4202f0,
-0x8f4202f0, 0x8fa20034, 0x8fbf0058, 0x8fbe0054,
-0x8fb50050, 0x8fb3004c, 0x8fb20048, 0x8fb10044,
-0x8fb00040, 0x3e00008, 0x27bd0060, 0x27bdfff8,
-0x2408ffff, 0x10a00014, 0x4821, 0x3c0aedb8,
-0x354a8320, 0x90870000, 0x24840001, 0x3021,
-0x1071026, 0x30420001, 0x10400002, 0x81842,
-0x6a1826, 0x604021, 0x24c60001, 0x2cc20008,
-0x1440fff7, 0x73842, 0x25290001, 0x125102b,
-0x1440fff0, 0x0, 0x1001021, 0x3e00008,
-0x27bd0008, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
-0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
-0xafb00030, 0x8f870220, 0xafa70024, 0x8f870200,
-0xafa7002c, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x34420004, 0xaf820220, 0x8f820200,
-0x3c03c0ff, 0x3463ffff, 0x431024, 0x34420004,
-0xaf820200, 0x8f530358, 0x8f55035c, 0x8f5e0360,
-0x8f470364, 0xafa70014, 0x8f470368, 0xafa7001c,
-0x8f4202d0, 0x274401c0, 0x24420001, 0xaf4202d0,
-0x8f5002d0, 0x8f510204, 0x8f520200, 0xc002ba8,
-0x24050400, 0xaf530358, 0xaf55035c, 0xaf5e0360,
-0x8fa70014, 0xaf470364, 0x8fa7001c, 0xaf470368,
-0xaf5002d0, 0xaf510204, 0xaf520200, 0x8c02025c,
-0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200,
-0x24060008, 0xaf4201f8, 0x24020006, 0xc002bbf,
-0xaf4201f4, 0x3c023b9a, 0x3442ca00, 0xaf4201fc,
-0x240203e8, 0x24040002, 0x24030001, 0xaf420294,
-0xaf440290, 0xaf43029c, 0x8f820220, 0x30420008,
-0x10400004, 0x0, 0xaf430298, 0x10000003,
-0x3021, 0xaf440298, 0x3021, 0x3c030001,
-0x661821, 0x90636d00, 0x3461021, 0x24c60001,
-0xa043022c, 0x2cc2000f, 0x1440fff8, 0x3461821,
-0x24c60001, 0x8f820040, 0x24040080, 0x24050080,
-0x21702, 0x24420030, 0xa062022c, 0x3461021,
-0xc002ba8, 0xa040022c, 0x8fa70024, 0x30e20004,
-0x14400006, 0x0, 0x8f820220, 0x3c0308ff,
-0x3463fffb, 0x431024, 0xaf820220, 0x8fa7002c,
-0x30e20004, 0x14400006, 0x0, 0x8f820200,
-0x3c03c0ff, 0x3463fffb, 0x431024, 0xaf820200,
-0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
-0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
-0x27bd0050, 0x0, 0x0, 0xaf400104,
-0x24040001, 0x410c0, 0x2e21821, 0x24820001,
-0x3c010001, 0x230821, 0xa42234d0, 0x402021,
-0x2c820080, 0x1440fff8, 0x410c0, 0x24020001,
-0x3c010001, 0x370821, 0xa42038d0, 0xaf420100,
-0xaf800228, 0xaf80022c, 0xaf800230, 0xaf800234,
-0x3e00008, 0x0, 0x27bdffe8, 0xafbf0014,
-0xafb00010, 0x8f420104, 0x28420005, 0x10400026,
-0x808021, 0x3c020001, 0x8f430104, 0x344230d0,
-0x2e22021, 0x318c0, 0x621821, 0x2e31821,
-0x83102b, 0x10400015, 0x1021, 0x96070000,
-0x24840006, 0x24660006, 0x9482fffc, 0x14470009,
-0x2821, 0x9483fffe, 0x96020002, 0x14620006,
-0xa01021, 0x94820000, 0x96030004, 0x431026,
-0x2c450001, 0xa01021, 0x14400009, 0x24840008,
-0x86102b, 0x1440fff0, 0x1021, 0x304200ff,
-0x14400030, 0x24020001, 0x1000002e, 0x1021,
-0x1000fffa, 0x24020001, 0x2002021, 0xc00240c,
-0x24050006, 0x3042007f, 0x218c0, 0x2e31021,
-0x3c010001, 0x220821, 0x942230d0, 0x1040fff2,
-0x2e31021, 0x3c060001, 0xc23021, 0x94c630d0,
-0x10c0ffed, 0x3c080001, 0x350834d2, 0x96070000,
-0x610c0, 0x572021, 0x882021, 0x94820000,
-0x14470009, 0x2821, 0x94830002, 0x96020002,
-0x14620006, 0xa01021, 0x94820004, 0x96030004,
-0x431026, 0x2c450001, 0xa01021, 0x14400007,
-0x610c0, 0x2e21021, 0x3c060001, 0xc23021,
-0x94c634d0, 0x14c0ffeb, 0x610c0, 0x10c0ffd2,
-0x24020001, 0x8fbf0014, 0x8fb00010, 0x3e00008,
-0x27bd0018, 0x3e00008, 0x0, 0x27bdffb0,
-0x801021, 0xafb00030, 0x24500002, 0x2002021,
-0x24050006, 0xafb10034, 0x408821, 0xafbf0048,
-0xafbe0044, 0xafb50040, 0xafb3003c, 0xc00240c,
-0xafb20038, 0x3047007f, 0x710c0, 0x2e21021,
-0x3c050001, 0xa22821, 0x94a530d0, 0x50a0001c,
-0xa03021, 0x3c090001, 0x352934d2, 0x96280002,
-0x510c0, 0x572021, 0x892021, 0x94820000,
-0x14480009, 0x3021, 0x94830002, 0x96020002,
-0x14620006, 0xc01021, 0x94820004, 0x96030004,
-0x431026, 0x2c460001, 0xc01021, 0x14400007,
-0x510c0, 0x2e21021, 0x3c050001, 0xa22821,
-0x94a534d0, 0x14a0ffeb, 0x510c0, 0xa03021,
-0x10c00014, 0x610c0, 0x571821, 0x3c010001,
-0x230821, 0x8c2334d0, 0x571021, 0xafa30010,
-0x3c010001, 0x220821, 0x8c2234d4, 0x3c040001,
-0x24846394, 0xafa20014, 0x8e260000, 0x8e270004,
-0x3c050004, 0xc002b3b, 0x34a50400, 0x10000063,
-0x3c020800, 0x8f450100, 0x10a00006, 0x510c0,
-0x2e21021, 0x3c010001, 0x220821, 0x942234d0,
-0xaf420100, 0xa03021, 0x14c00011, 0x628c0,
-0x710c0, 0x2e21021, 0xafa70010, 0x3c010001,
-0x220821, 0x942230d0, 0x3c040001, 0x248463a0,
-0xafa20014, 0x8e260000, 0x8e270004, 0x3c050004,
-0xc002b3b, 0x34a50500, 0x10000048, 0x3c020800,
-0xb71821, 0x3c020001, 0x96040000, 0x344234d2,
-0x621821, 0xa4640000, 0x8e020002, 0x720c0,
-0xac620002, 0x2e41021, 0x3c030001, 0x621821,
-0x946330d0, 0x2e51021, 0x3c010001, 0x220821,
-0xa42334d0, 0x2e41021, 0x3c010001, 0x220821,
-0xa42630d0, 0x8f420104, 0x24420001, 0x28420080,
-0x1040000f, 0x3c020002, 0x8f420104, 0x3c040001,
-0x348430d2, 0x96030000, 0x210c0, 0x571021,
-0x441021, 0xa4430000, 0x8e030002, 0xac430002,
-0x8f420104, 0x24420001, 0xaf420104, 0x3c020002,
-0x2c21024, 0x10400011, 0x72142, 0x3c030001,
-0x346338d8, 0x24020003, 0x441023, 0x21080,
-0x572021, 0x832021, 0x571021, 0x431021,
-0x30e5001f, 0x8c430000, 0x24020001, 0xa21004,
-0x621825, 0x1000000c, 0xac830000, 0x24020003,
-0x441023, 0x21080, 0x5c2821, 0x5c1021,
-0x30e4001f, 0x8c430228, 0x24020001, 0x821004,
-0x621825, 0xaca30228, 0x3c020800, 0x34421000,
-0x1821, 0xafa20020, 0x8f5e0018, 0x27aa0020,
-0x240200ff, 0x13c20002, 0xafaa002c, 0x27c30001,
-0x8c020228, 0x609021, 0x1642000e, 0x1e38c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x2484635c, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006b,
-0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b,
-0x9821, 0xe08821, 0x263504c0, 0x8f440178,
-0x8f45017c, 0x2201821, 0x240a0004, 0xafaa0010,
-0xafb20014, 0x8f48000c, 0x1021, 0x2f53021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x54400006, 0x24130001, 0x8f820054, 0x2021023,
-0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff,
-0x54400017, 0xaf520018, 0x8f420378, 0x24420001,
-0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846368,
-0x3c050009, 0xafa20014, 0x8d460000, 0x10000033,
-0x34a50600, 0x8f420308, 0x24130001, 0x24420001,
-0xaf420308, 0x8f420308, 0x1000001c, 0x326200ff,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x10400014, 0x9821, 0x24110010,
-0x8f42000c, 0x8f440160, 0x8f450164, 0x8f860120,
-0xafb10010, 0xafb20014, 0xafa20018, 0x8f42010c,
-0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe5,
-0x0, 0x8f820054, 0x2021023, 0x2c4203e9,
-0x1440ffef, 0x0, 0x326200ff, 0x14400011,
-0x0, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846370, 0x3c050009,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
-0x3c03821, 0x8f4202b4, 0x24420001, 0xaf4202b4,
-0x8f4202b4, 0x8f4202f4, 0x24420001, 0xaf4202f4,
-0x8f4202f4, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
-0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
-0x3e00008, 0x27bd0050, 0x27bdffa0, 0x801021,
-0xafb00040, 0x24500002, 0x2002021, 0x24050006,
-0xafb10044, 0x408821, 0xafbf0058, 0xafbe0054,
-0xafb50050, 0xafb3004c, 0xc00240c, 0xafb20048,
-0x3048007f, 0x810c0, 0x2e21021, 0x3c060001,
-0xc23021, 0x94c630d0, 0x10c0001c, 0x3821,
-0x3c0a0001, 0x354a34d2, 0x96290002, 0x610c0,
-0x572021, 0x8a2021, 0x94820000, 0x14490009,
-0x2821, 0x94830002, 0x96020002, 0x14620006,
-0xa01021, 0x94820004, 0x96030004, 0x431026,
-0x2c450001, 0xa01021, 0x14400008, 0x610c0,
-0xc03821, 0x2e21021, 0x3c060001, 0xc23021,
-0x94c634d0, 0x14c0ffea, 0x610c0, 0x14c00011,
-0xafa70028, 0x810c0, 0x2e21021, 0xafa80010,
-0x3c010001, 0x220821, 0x942230d0, 0x3c040001,
-0x248463ac, 0xafa20014, 0x8e260000, 0x8e270004,
-0x3c050004, 0xc002b3b, 0x34a50900, 0x10000075,
-0x3c020800, 0x10e0000c, 0x610c0, 0x2e21021,
-0x3c030001, 0x621821, 0x946334d0, 0x710c0,
-0x2e21021, 0x3c010001, 0x220821, 0xa42334d0,
-0x1000000b, 0x3c040001, 0x2e21021, 0x3c030001,
-0x621821, 0x946334d0, 0x810c0, 0x2e21021,
-0x3c010001, 0x220821, 0xa42330d0, 0x3c040001,
-0x348430d0, 0x8f430100, 0x610c0, 0x2e21021,
-0x3c010001, 0x220821, 0xa42334d0, 0x8f420104,
-0x2e43821, 0x2821, 0x18400029, 0xaf460100,
-0x24e60006, 0x94c3fffc, 0x96020000, 0x14620009,
-0x2021, 0x94c3fffe, 0x96020002, 0x14620006,
-0x801021, 0x94c20000, 0x96030004, 0x431026,
-0x2c440001, 0x801021, 0x50400014, 0x24a50001,
-0x8f420104, 0x2442ffff, 0xa2102a, 0x1040000b,
-0x24e40004, 0x94820006, 0x8c830008, 0xa482fffe,
-0xac830000, 0x8f420104, 0x24a50001, 0x2442ffff,
-0xa2102a, 0x1440fff7, 0x24840008, 0x8f420104,
-0x2442ffff, 0x10000006, 0xaf420104, 0x8f420104,
-0x24c60008, 0xa2102a, 0x1440ffda, 0x24e70008,
-0x810c0, 0x2e21021, 0x3c010001, 0x220821,
-0x942230d0, 0x14400023, 0x3c020800, 0x3c020002,
-0x2c21024, 0x10400012, 0x82142, 0x3c030001,
-0x346338d8, 0x24020003, 0x441023, 0x21080,
-0x572021, 0x832021, 0x571021, 0x431021,
-0x3105001f, 0x24030001, 0x8c420000, 0xa31804,
-0x31827, 0x431024, 0x1000000d, 0xac820000,
-0x24020003, 0x441023, 0x21080, 0x5c2821,
-0x5c1021, 0x3104001f, 0x24030001, 0x8c420228,
-0x831804, 0x31827, 0x431024, 0xaca20228,
-0x3c020800, 0x34422000, 0x1821, 0xafa20020,
-0x8f5e0018, 0x27ab0020, 0x240200ff, 0x13c20002,
-0xafab0034, 0x27c30001, 0x8c020228, 0x609021,
-0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
-0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484635c, 0x3c050009, 0xafa00014, 0xafa20010,
-0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
-0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
-0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
-0x240b0004, 0xafab0010, 0xafb20014, 0x8f48000c,
-0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
-0x24070008, 0xa32821, 0xa3482b, 0x822021,
-0x100f809, 0x892021, 0x54400006, 0x24130001,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
-0x0, 0x326200ff, 0x54400017, 0xaf520018,
-0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
-0x8f820120, 0x8fab0034, 0xafa20010, 0x8f820124,
-0x3c040001, 0x24846368, 0x3c050009, 0xafa20014,
-0x8d660000, 0x10000033, 0x34a50600, 0x8f420308,
-0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
-0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014,
-0x9821, 0x24110010, 0x8f42000c, 0x8f440160,
-0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffef, 0x0,
-0x326200ff, 0x14400011, 0x0, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8fab0034, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846370, 0x3c050009, 0xafa20014, 0x8d660000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b8,
-0x24420001, 0xaf4202b8, 0x8f4202b8, 0x8f4202f4,
-0x24420001, 0xaf4202f4, 0x8f4202f4, 0x8fbf0058,
-0x8fbe0054, 0x8fb50050, 0x8fb3004c, 0x8fb20048,
-0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0060,
-0x0, 0x0, 0x0, 0x27bdffe0,
-0x27644000, 0xafbf0018, 0xc002ba8, 0x24051000,
-0x3c030001, 0x34632cc0, 0x3c040001, 0x34842ec8,
-0x24020020, 0xaf82011c, 0x2e31021, 0xaf800100,
-0xaf800104, 0xaf800108, 0xaf800110, 0xaf800114,
-0xaf800118, 0xaf800120, 0xaf800124, 0xaf800128,
-0xaf800130, 0xaf800134, 0xaf800138, 0xaf4200ec,
-0x2e31021, 0xaf4200f0, 0x2e41021, 0xaf4200f4,
-0x2e41021, 0xaf4200f8, 0x3c020001, 0x571021,
-0x904240f4, 0x1440001c, 0x3c050001, 0x8f82011c,
-0x3c040001, 0x24846470, 0x3c050001, 0x34420001,
-0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c,
-0x34a50100, 0xc002b3b, 0x3821, 0x8c020218,
-0x30420040, 0x10400014, 0x0, 0x8f82011c,
-0x3c040001, 0x2484647c, 0x3c050001, 0x34420004,
-0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c,
-0x10000007, 0x34a50200, 0x3c040001, 0x24846484,
-0xafa00010, 0xafa00014, 0x8f86011c, 0x34a50300,
-0xc002b3b, 0x3821, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x8fa90010, 0x8f83012c, 0x8faa0014,
-0x8fab0018, 0x1060000a, 0x27624fe0, 0x14620002,
-0x24680020, 0x27684800, 0x8f820128, 0x11020004,
-0x0, 0x8f820124, 0x15020007, 0x0,
-0x8f430334, 0x1021, 0x24630001, 0xaf430334,
-0x10000039, 0x8f430334, 0xac640000, 0xac650004,
-0xac660008, 0xa467000e, 0xac690018, 0xac6a001c,
-0xac6b0010, 0xac620014, 0xaf880120, 0x8f4200fc,
-0x8f4400f4, 0x2442ffff, 0xaf4200fc, 0x8c820000,
-0x10490005, 0x3042ff8f, 0x10400019, 0x3122ff8f,
-0x10400018, 0x3c020001, 0x8c830004, 0x2c620010,
-0x10400013, 0x3c020001, 0x24630001, 0xac830004,
-0x8f4300f8, 0x344230c8, 0x2e21021, 0x54620004,
-0x24620008, 0x3c020001, 0x34422ec8, 0x2e21021,
-0x14440015, 0x24020001, 0x8f820128, 0x24420020,
-0xaf820128, 0x8f820128, 0x1000000f, 0x24020001,
-0x3c020001, 0x344230c8, 0x2e21021, 0x54820004,
-0x24820008, 0x3c020001, 0x34422ec8, 0x2e21021,
-0x402021, 0x24020001, 0xaf4400f4, 0xac890000,
-0xac820004, 0x24020001, 0x3e00008, 0x0,
-0x3e00008, 0x0, 0x8fa90010, 0x8f83010c,
-0x8faa0014, 0x8fab0018, 0x1060000a, 0x276247e0,
-0x14620002, 0x24680020, 0x27684000, 0x8f820108,
-0x11020004, 0x0, 0x8f820104, 0x15020007,
-0x0, 0x8f430338, 0x1021, 0x24630001,
-0xaf430338, 0x10000035, 0x8f430338, 0xac640000,
-0xac650004, 0xac660008, 0xa467000e, 0xac690018,
-0xac6a001c, 0xac6b0010, 0xac620014, 0xaf880100,
-0x8f4400ec, 0x8c820000, 0x30420006, 0x10400019,
-0x31220006, 0x10400018, 0x3c020001, 0x8c830004,
-0x2c620010, 0x10400013, 0x3c020001, 0x24630001,
-0xac830004, 0x8f4300f0, 0x34422ec0, 0x2e21021,
-0x54620004, 0x24620008, 0x3c020001, 0x34422cc0,
-0x2e21021, 0x14440015, 0x24020001, 0x8f820108,
-0x24420020, 0xaf820108, 0x8f820108, 0x1000000f,
-0x24020001, 0x3c020001, 0x34422ec0, 0x2e21021,
-0x54820004, 0x24820008, 0x3c020001, 0x34422cc0,
-0x2e21021, 0x402021, 0x24020001, 0xaf4400ec,
-0xac890000, 0xac820004, 0x24020001, 0x3e00008,
-0x0, 0x3e00008, 0x0, 0x27bdffd8,
-0x3c040001, 0x2484648c, 0x3c050001, 0xafbf0024,
-0xafb20020, 0xafb1001c, 0xafb00018, 0x8f900104,
-0x8f9100b0, 0x8f92011c, 0x34a52500, 0x8f820100,
-0x2403021, 0x2203821, 0xafa20010, 0xc002b3b,
-0xafb00014, 0x8e020008, 0xafa20010, 0x8e02000c,
-0x3c040001, 0x24846498, 0xafa20014, 0x8e060000,
-0x8e070004, 0x3c050001, 0xc002b3b, 0x34a52510,
-0x8e020018, 0xafa20010, 0x8e02001c, 0x3c040001,
-0x248464a4, 0xafa20014, 0x8e060010, 0x8e070014,
-0x3c050001, 0xc002b3b, 0x34a52520, 0x3c027f00,
-0x2221024, 0x3c030800, 0x54430016, 0x3c030200,
-0x8f82009c, 0x3042ffff, 0x14400012, 0x3c030200,
-0x3c040001, 0x248464b0, 0x3c050002, 0x34a5f030,
-0x3021, 0x3821, 0x36420002, 0xaf82011c,
-0x36220001, 0xaf8200b0, 0xaf900104, 0xaf92011c,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x10000024,
-0x0, 0x2c31024, 0x1040000d, 0x2231024,
-0x1040000b, 0x36420002, 0xaf82011c, 0x36220001,
-0xaf8200b0, 0xaf900104, 0xaf92011c, 0x8f420330,
-0x24420001, 0xaf420330, 0x10000015, 0x8f420330,
-0x3c040001, 0x248464b8, 0x240202a9, 0xafa20010,
-0xafa00014, 0x8f860144, 0x3c070001, 0x24e764c0,
-0xc002b3b, 0x3405dead, 0x8f82011c, 0x34420002,
-0xaf82011c, 0x8f820220, 0x34420004, 0xaf820220,
-0x8f820140, 0x3c030001, 0x431025, 0xaf820140,
-0x8fbf0024, 0x8fb20020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x27bdffd8, 0x3c040001,
-0x248464e8, 0x3c050001, 0xafbf0024, 0xafb20020,
-0xafb1001c, 0xafb00018, 0x8f900124, 0x8f9100a0,
-0x8f92011c, 0x34a52600, 0x8f820120, 0x2403021,
-0x2203821, 0xafa20010, 0xc002b3b, 0xafb00014,
-0x8e020008, 0xafa20010, 0x8e02000c, 0x3c040001,
-0x248464f4, 0xafa20014, 0x8e060000, 0x8e070004,
-0x3c050001, 0xc002b3b, 0x34a52610, 0x8e020018,
-0xafa20010, 0x8e02001c, 0x3c040001, 0x24846500,
-0xafa20014, 0x8e060010, 0x8e070014, 0x3c050001,
-0xc002b3b, 0x34a52620, 0x3c027f00, 0x2221024,
-0x3c030800, 0x54430016, 0x3c030200, 0x8f8200ac,
-0x3042ffff, 0x14400012, 0x3c030200, 0x3c040001,
-0x2484650c, 0x3c050001, 0x34a5f030, 0x3021,
-0x3821, 0x36420002, 0xaf82011c, 0x36220001,
-0xaf8200a0, 0xaf900124, 0xaf92011c, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x10000024, 0x0,
-0x2c31024, 0x1040000d, 0x2231024, 0x1040000b,
-0x36420002, 0xaf82011c, 0x36220001, 0xaf8200a0,
-0xaf900124, 0xaf92011c, 0x8f42032c, 0x24420001,
-0xaf42032c, 0x10000015, 0x8f42032c, 0x3c040001,
-0x248464b8, 0x240202e2, 0xafa20010, 0xafa00014,
-0x8f860144, 0x3c070001, 0x24e764c0, 0xc002b3b,
-0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c,
-0x8f820220, 0x34420004, 0xaf820220, 0x8f820140,
-0x3c030001, 0x431025, 0xaf820140, 0x8fbf0024,
-0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008,
-0x27bd0028, 0x6021, 0x5021, 0x3021,
-0x2821, 0x6821, 0x4821, 0x7821,
-0x7021, 0x8f880124, 0x8f870104, 0x1580002e,
-0x8f8b011c, 0x11a00014, 0x31620800, 0x8f820120,
-0x10460029, 0x0, 0x3c040001, 0x8c846ee4,
-0x8cc20000, 0x8cc30004, 0xac820000, 0xac830004,
-0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e,
-0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014,
-0x10000012, 0x24c60020, 0x10400017, 0x0,
-0x3c040001, 0x8c846ee4, 0x8d020000, 0x8d030004,
-0xac820000, 0xac830004, 0x8d020008, 0xac820008,
-0x9502000e, 0xa482000e, 0x8d020010, 0x25060020,
-0xac820010, 0x8d020014, 0x240c0001, 0xc01821,
-0xac820014, 0x27624fe0, 0x43102b, 0x54400001,
-0x27634800, 0x603021, 0x1540002f, 0x31620100,
-0x11200014, 0x31628000, 0x8f820100, 0x1045002a,
-0x31620100, 0x3c040001, 0x8c846ee0, 0x8ca20000,
-0x8ca30004, 0xac820000, 0xac830004, 0x8ca20008,
-0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010,
-0x240a0001, 0xac820010, 0x8ca20014, 0x10000012,
-0x24a50020, 0x10400018, 0x31620100, 0x3c040001,
-0x8c846ee0, 0x8ce20000, 0x8ce30004, 0xac820000,
-0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e,
-0xa482000e, 0x8ce20010, 0x24e50020, 0xac820010,
-0x8ce20014, 0x240a0001, 0xa01821, 0xac820014,
-0x276247e0, 0x43102b, 0x54400001, 0x27634000,
-0x602821, 0x31620100, 0x5440001d, 0x31621000,
-0x11a00009, 0x31a20800, 0x10400004, 0x25020020,
-0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124,
-0x8f880124, 0x6821, 0x11800011, 0x31621000,
-0x3c040001, 0x8c846ee4, 0x8c820000, 0x8c830004,
-0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4,
-0x9482000e, 0xaf8200ac, 0x8c820010, 0x6021,
-0xaf8200a0, 0x8c8d0010, 0x8c8f0014, 0x31621000,
-0x1440ff82, 0x0, 0x1120000f, 0x31220800,
-0x10400004, 0x3c020002, 0x8f8200b8, 0xa5c20000,
-0x3c020002, 0x1221024, 0x10400004, 0x24e20020,
-0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104,
-0x8f870104, 0x4821, 0x1140ff70, 0x0,
-0x3c040001, 0x8c846ee0, 0x8c820000, 0x8c830004,
-0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4,
-0x9482000e, 0xaf82009c, 0x8c820010, 0x5021,
-0xaf8200b0, 0x8c890010, 0x1000ff60, 0x8c8e0014,
-0x3e00008, 0x0, 0x6021, 0x5821,
-0x3021, 0x2821, 0x6821, 0x5021,
-0x7821, 0x7021, 0x8f880124, 0x8f870104,
-0x3c180100, 0x1580002e, 0x8f89011c, 0x11a00014,
-0x31220800, 0x8f820120, 0x10460029, 0x0,
-0x3c040001, 0x8c846ee4, 0x8cc20000, 0x8cc30004,
-0xac820000, 0xac830004, 0x8cc20008, 0xac820008,
-0x94c2000e, 0xa482000e, 0x8cc20010, 0x240c0001,
-0xac820010, 0x8cc20014, 0x10000012, 0x24c60020,
-0x10400017, 0x0, 0x3c040001, 0x8c846ee4,
-0x8d020000, 0x8d030004, 0xac820000, 0xac830004,
-0x8d020008, 0xac820008, 0x9502000e, 0xa482000e,
-0x8d020010, 0x25060020, 0xac820010, 0x8d020014,
-0x240c0001, 0xc01821, 0xac820014, 0x27624fe0,
-0x43102b, 0x54400001, 0x27634800, 0x603021,
-0x1560002f, 0x31220100, 0x11400014, 0x31228000,
-0x8f820100, 0x1045002a, 0x31220100, 0x3c040001,
-0x8c846ee0, 0x8ca20000, 0x8ca30004, 0xac820000,
-0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e,
-0xa482000e, 0x8ca20010, 0x240b0001, 0xac820010,
-0x8ca20014, 0x10000012, 0x24a50020, 0x10400018,
-0x31220100, 0x3c040001, 0x8c846ee0, 0x8ce20000,
-0x8ce30004, 0xac820000, 0xac830004, 0x8ce20008,
-0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010,
-0x24e50020, 0xac820010, 0x8ce20014, 0x240b0001,
-0xa01821, 0xac820014, 0x276247e0, 0x43102b,
-0x54400001, 0x27634000, 0x602821, 0x31220100,
-0x5440001d, 0x31221000, 0x11a00009, 0x31a20800,
-0x10400004, 0x25020020, 0x8f8200a8, 0xa5e20000,
-0x25020020, 0xaf820124, 0x8f880124, 0x6821,
-0x11800011, 0x31221000, 0x3c040001, 0x8c846ee4,
-0x8c820000, 0x8c830004, 0xaf820080, 0xaf830084,
-0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac,
-0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010,
-0x8c8f0014, 0x31221000, 0x14400022, 0x0,
-0x1140000f, 0x31420800, 0x10400004, 0x3c020002,
-0x8f8200b8, 0xa5c20000, 0x3c020002, 0x1421024,
-0x10400004, 0x24e20020, 0x8f8200b4, 0xaf8200d4,
-0x24e20020, 0xaf820104, 0x8f870104, 0x5021,
-0x11600010, 0x0, 0x3c040001, 0x8c846ee0,
-0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094,
-0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c,
-0x8c820010, 0x5821, 0xaf8200b0, 0x8c8a0010,
-0x8c8e0014, 0x8f820070, 0x3c031000, 0x431024,
-0x1040ff5c, 0x0, 0x8f820054, 0x24420005,
-0xaf820078, 0x8c040234, 0x10800016, 0x1821,
-0x3c020001, 0x571021, 0x8c4240e8, 0x24420005,
-0x3c010001, 0x370821, 0xac2240e8, 0x3c020001,
-0x571021, 0x8c4240e8, 0x44102b, 0x14400009,
-0x24020001, 0x3c030080, 0x3c010001, 0x370821,
-0xac2040e8, 0x3c010001, 0x370821, 0x1000000c,
-0xa02240f0, 0x3c020001, 0x571021, 0x904240f0,
-0x14400006, 0x3c020080, 0x3c020001, 0x571021,
-0x904240f1, 0x10400002, 0x3c020080, 0x621825,
-0x8c040230, 0x10800013, 0x0, 0x3c020001,
-0x571021, 0x8c4240ec, 0x24420005, 0x3c010001,
-0x370821, 0xac2240ec, 0x3c020001, 0x571021,
-0x8c4240ec, 0x44102b, 0x14400006, 0x0,
-0x3c010001, 0x370821, 0xac2040ec, 0x10000006,
-0x781825, 0x3c020001, 0x571021, 0x904240f2,
-0x54400001, 0x781825, 0x1060ff1a, 0x0,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x431025, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x1000ff05,
-0xaf80004c, 0x1000ff03, 0xaf800048, 0x3e00008,
-0x0, 0x0, 0x0, 0x3c020001,
-0x8c426d28, 0x27bdffe8, 0xafbf0014, 0x14400012,
-0xafb00010, 0x3c100001, 0x26106f90, 0x2002021,
-0xc002ba8, 0x24052000, 0x26021fe0, 0x3c010001,
-0xac226eec, 0x3c010001, 0xac226ee8, 0xac020250,
-0x24022000, 0xac100254, 0xac020258, 0x24020001,
-0x3c010001, 0xac226d28, 0x8fbf0014, 0x8fb00010,
-0x3e00008, 0x27bd0018, 0x3c090001, 0x8d296eec,
-0x8c820000, 0x8fa30010, 0x8fa80014, 0xad220000,
-0x8c820004, 0xad250008, 0xad220004, 0x8f820054,
-0xad260010, 0xad270014, 0xad230018, 0xad28001c,
-0xad22000c, 0x2529ffe0, 0x3c020001, 0x24426f90,
-0x122102b, 0x10400003, 0x0, 0x3c090001,
-0x8d296ee8, 0x3c020001, 0x8c426d10, 0xad220000,
-0x3c020001, 0x8c426d10, 0x3c010001, 0xac296eec,
-0xad220004, 0xac090250, 0x3e00008, 0x0,
-0x27bdffd0, 0xafb00010, 0x3c100001, 0x8e106eec,
-0x3c020001, 0x8c426d10, 0xafb10014, 0x808821,
-0xafbe0024, 0x8fbe0040, 0x8fa40048, 0xafb20018,
-0xa09021, 0xafbf0028, 0xafb50020, 0xafb3001c,
-0xae020000, 0x3c020001, 0x8c426d10, 0xc09821,
-0xe0a821, 0x10800006, 0xae020004, 0x26050008,
-0xc002bb3, 0x24060018, 0x10000005, 0x2610ffe0,
-0x26040008, 0xc002ba8, 0x24050018, 0x2610ffe0,
-0x3c030001, 0x24636f90, 0x203102b, 0x10400003,
-0x0, 0x3c100001, 0x8e106ee8, 0x8e220000,
-0xae020000, 0x8e220004, 0xae120008, 0xae020004,
-0x8f820054, 0xae130010, 0xae150014, 0xae1e0018,
-0x8fa80044, 0xae08001c, 0xae02000c, 0x2610ffe0,
-0x203102b, 0x10400003, 0x0, 0x3c100001,
-0x8e106ee8, 0x3c020001, 0x8c426d10, 0xae020000,
-0x3c020001, 0x8c426d10, 0x3c010001, 0xac306eec,
-0xae020004, 0xac100250, 0x8fbf0028, 0x8fbe0024,
-0x8fb50020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
-0x8fb00010, 0x3e00008, 0x27bd0030, 0x851821,
-0x83102b, 0x10400006, 0x0, 0xac800000,
-0x24840004, 0x83102b, 0x5440fffd, 0xac800000,
-0x3e00008, 0x0, 0xa61821, 0xa3102b,
-0x10400007, 0x0, 0x8c820000, 0xaca20000,
-0x24a50004, 0xa3102b, 0x1440fffb, 0x24840004,
-0x3e00008, 0x0, 0x861821, 0x83102b,
-0x10400007, 0x0, 0x8ca20000, 0xac820000,
-0x24840004, 0x83102b, 0x1440fffb, 0x24a50004,
-0x3e00008, 0x0, 0x63080, 0x861821,
-0x83102b, 0x10400006, 0x0, 0xac850000,
-0x24840004, 0x83102b, 0x5440fffd, 0xac850000,
-0x3e00008, 0x0, 0x0, 0x26e50028,
-0xa03021, 0x274301c0, 0x8f4d0358, 0x8f47035c,
-0x8f480360, 0x8f490364, 0x8f4a0368, 0x8f4b0204,
-0x8f4c0200, 0x24640400, 0x64102b, 0x10400008,
-0x3c0208ff, 0x8cc20000, 0xac620000, 0x24630004,
-0x64102b, 0x1440fffb, 0x24c60004, 0x3c0208ff,
-0x3442ffff, 0x3c03c0ff, 0xaf4d0358, 0xaf47035c,
-0xaf480360, 0xaf490364, 0xaf4a0368, 0xaf4b0204,
-0xaf4c0200, 0x8f840220, 0x3463ffff, 0x8f860200,
-0x821024, 0x34420004, 0xc31824, 0x34630004,
-0xaf820220, 0xaf830200, 0x8ca20214, 0xac020084,
-0x8ca20218, 0xac020088, 0x8ca2021c, 0xac02008c,
-0x8ca20220, 0xac020090, 0x8ca20224, 0xac020094,
-0x8ca20228, 0xac020098, 0x8ca2022c, 0xac02009c,
-0x8ca20230, 0xac0200a0, 0x8ca20234, 0xac0200a4,
-0x8ca20238, 0xac0200a8, 0x8ca2023c, 0xac0200ac,
-0x8ca20240, 0xac0200b0, 0x8ca20244, 0xac0200b4,
-0x8ca20248, 0xac0200b8, 0x8ca2024c, 0xac0200bc,
-0x8ca2001c, 0xac020080, 0x8ca20018, 0xac0200c0,
-0x8ca20020, 0xac0200cc, 0x8ca20024, 0xac0200d0,
-0x8ca201d0, 0xac0200e0, 0x8ca201d4, 0xac0200e4,
-0x8ca201d8, 0xac0200e8, 0x8ca201dc, 0xac0200ec,
-0x8ca201e0, 0xac0200f0, 0x8ca20098, 0x8ca3009c,
-0xac0300fc, 0x8ca200a8, 0x8ca300ac, 0xac0300f4,
-0x8ca200a0, 0x8ca300a4, 0x30840004, 0xac0300f8,
-0x14800007, 0x30c20004, 0x8f820220, 0x3c0308ff,
-0x3463fffb, 0x431024, 0xaf820220, 0x30c20004,
-0x14400006, 0x0, 0x8f820200, 0x3c03c0ff,
-0x3463fffb, 0x431024, 0xaf820200, 0x8f4202dc,
-0xa34005c5, 0x24420001, 0xaf4202dc, 0x8f4202dc,
-0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
-0xafb00020, 0x8f430024, 0x8f420020, 0x10620038,
-0x0, 0x8f430020, 0x8f420024, 0x622023,
-0x4810003, 0x0, 0x8f420040, 0x822021,
-0x8f430030, 0x8f420024, 0x43102b, 0x14400005,
-0x0, 0x8f430040, 0x8f420024, 0x10000005,
-0x621023, 0x8f420030, 0x8f430024, 0x431023,
-0x2442ffff, 0x406021, 0x8c102a, 0x54400001,
-0x806021, 0x8f4a0024, 0x8f490040, 0x8f480024,
-0x8f440180, 0x8f450184, 0x8f460024, 0x8f4b001c,
-0x24070001, 0xafa70010, 0x84100, 0x1001821,
-0x14c5021, 0x2529ffff, 0x1498024, 0xafb00014,
-0x8f470014, 0x1021, 0x63100, 0xafa70018,
-0xa32821, 0xa3382b, 0x822021, 0x872021,
-0x8f420108, 0x1663021, 0x40f809, 0xc3900,
-0x54400001, 0xaf500024, 0x8f430024, 0x8f420020,
-0x14620018, 0x0, 0x8f420000, 0x10400007,
-0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd,
-0x0, 0x10000005, 0x0, 0xaf800048,
-0x8f820048, 0x1040fffd, 0x0, 0x8f820060,
-0x2403ffef, 0x431024, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x10000002, 0xaf80004c,
-0xaf800048, 0x8fbf0024, 0x8fb00020, 0x3e00008,
-0x27bd0028, 0x3e00008, 0x0, 0x27bdffc0,
-0x32c20020, 0xafbf0038, 0xafb30034, 0xafb20030,
-0xafb1002c, 0x10400004, 0xafb00028, 0x8f530028,
-0x10000002, 0x0, 0x8f530020, 0x8f420030,
-0x105300eb, 0x21100, 0x8f43001c, 0x628021,
-0x8e040000, 0x8e050004, 0x96120008, 0x8f420090,
-0x9611000a, 0x3246ffff, 0x46102a, 0x10400017,
-0x0, 0x8f8200d8, 0x8f430098, 0x431023,
-0x2442dcbe, 0xaf420090, 0x8f420090, 0x2842dcbf,
-0x10400005, 0x0, 0x8f420090, 0x8f430144,
-0x431021, 0xaf420090, 0x8f420090, 0x46102a,
-0x10400006, 0x0, 0x8f420348, 0x24420001,
-0xaf420348, 0x100000e1, 0x8f420348, 0x8f8200fc,
-0x14400006, 0x0, 0x8f420344, 0x24420001,
-0xaf420344, 0x100000d9, 0x8f420344, 0x934205c2,
-0x1040000b, 0x32c20008, 0x10400008, 0x32220200,
-0x10400006, 0x3c034000, 0x9602000e, 0xaf4300ac,
-0x21400, 0x10000002, 0xaf4200b0, 0xaf4000ac,
-0x32220004, 0x1040007f, 0x32220800, 0x10400003,
-0x3247ffff, 0x10000002, 0x24020020, 0x24020004,
-0xafa20010, 0x8f420030, 0xafa20014, 0x8f420010,
-0x3c030002, 0x431025, 0xafa20018, 0x8f460098,
-0x8f420108, 0x40f809, 0x0, 0x104000b7,
-0x0, 0x8f42009c, 0x8f430094, 0x2421021,
-0xaf42009c, 0xae03000c, 0x8f4200ac, 0x10400008,
-0x3c034000, 0x8f420094, 0x431025, 0xafa20020,
-0x8f42009c, 0x8f4300b0, 0x10000004, 0x431025,
-0x8f420094, 0xafa20020, 0x8f42009c, 0xafa20024,
-0x8f8200fc, 0x8fa30020, 0x8fa40024, 0xac430000,
-0xac440004, 0x24420008, 0xaf8200f0, 0x8f42009c,
-0x8f440270, 0x8f450274, 0x401821, 0x1021,
-0xa32821, 0xa3302b, 0x822021, 0x862021,
-0x32230060, 0x24020040, 0xaf440270, 0xaf450274,
-0x10620017, 0x2c620041, 0x10400005, 0x24020020,
-0x10620008, 0x24020001, 0x10000026, 0x0,
-0x24020060, 0x10620019, 0x24020001, 0x10000021,
-0x0, 0x8f420278, 0x8f43027c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
-0x8f420278, 0x8f43027c, 0x10000016, 0x24020001,
-0x8f420280, 0x8f430284, 0x24630001, 0x2c640001,
-0x441021, 0xaf420280, 0xaf430284, 0x8f420280,
-0x8f430284, 0x1000000b, 0x24020001, 0x8f420288,
-0x8f43028c, 0x24630001, 0x2c640001, 0x441021,
-0xaf420288, 0xaf43028c, 0x8f420288, 0x8f43028c,
-0x24020001, 0xa34205c2, 0x8f420098, 0x3244ffff,
-0x2406fff8, 0x8f45013c, 0x441021, 0x24420007,
-0x461024, 0x24840007, 0xaf420094, 0x8f420090,
-0x8f430094, 0x862024, 0x441023, 0x65182b,
-0x14600005, 0xaf420090, 0x8f420094, 0x8f430144,
-0x431023, 0xaf420094, 0x8f420094, 0x10000023,
-0xaf40009c, 0x3247ffff, 0x50e00022, 0x32c20020,
-0x14400002, 0x24020010, 0x24020002, 0xafa20010,
-0x8f420030, 0xafa20014, 0x8f420010, 0xafa20018,
-0x8f460098, 0x8f420108, 0x40f809, 0x0,
-0x1040003a, 0x3245ffff, 0x8f420098, 0x8f430090,
-0x8f46013c, 0x451021, 0xaf420098, 0x8f42009c,
-0x8f440098, 0xa34005c2, 0x651823, 0xaf430090,
-0x451021, 0x86202b, 0x14800005, 0xaf42009c,
-0x8f420098, 0x8f430144, 0x431023, 0xaf420098,
-0x32c20020, 0x10400005, 0x0, 0x8f420358,
-0x2442ffff, 0xaf420358, 0x8f420358, 0x8f420030,
-0x8f430040, 0x24420001, 0x2463ffff, 0x431024,
-0xaf420030, 0x8f420030, 0x14530018, 0x0,
-0x8f420000, 0x10400007, 0x0, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x2403fff7, 0x431024,
-0xaf820060, 0x8f420000, 0x10400003, 0x0,
-0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf0038,
-0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028,
-0x3e00008, 0x27bd0040, 0x3e00008, 0x0,
-0x27bdffd0, 0x32c20020, 0xafbf002c, 0xafb20028,
-0xafb10024, 0x10400004, 0xafb00020, 0x8f520028,
-0x10000002, 0x0, 0x8f520020, 0x8f420030,
-0x105200b5, 0x21100, 0x8f43001c, 0x628021,
-0x8e040000, 0x8e050004, 0x96110008, 0x8f420090,
-0x9607000a, 0x3226ffff, 0x46102a, 0x10400017,
-0x0, 0x8f8200d8, 0x8f430098, 0x431023,
-0x2442dc46, 0xaf420090, 0x8f420090, 0x2842dc47,
-0x10400005, 0x0, 0x8f420090, 0x8f430144,
-0x431021, 0xaf420090, 0x8f420090, 0x46102a,
-0x10400006, 0x0, 0x8f420348, 0x24420001,
-0xaf420348, 0x100000ab, 0x8f420348, 0x8f8600fc,
-0x10c0000c, 0x0, 0x8f8200f4, 0x2403fff8,
-0x431024, 0x461023, 0x218c3, 0x58600001,
-0x24630100, 0x8f42008c, 0x43102b, 0x14400006,
-0x712c2, 0x8f420344, 0x24420001, 0xaf420344,
-0x10000098, 0x8f420344, 0x934305c2, 0x1060000f,
-0x30460001, 0x8f420010, 0x34480400, 0x32c20008,
-0x10400008, 0x30e20200, 0x10400006, 0x3c034000,
-0x9602000e, 0xaf4300ac, 0x21400, 0x10000004,
-0xaf4200b0, 0x10000002, 0xaf4000ac, 0x8f480010,
-0x30e20004, 0x10400045, 0x3227ffff, 0x8f4900ac,
-0x11200005, 0x30c200ff, 0x14400006, 0x24020040,
-0x10000004, 0x24020008, 0x14400002, 0x24020020,
-0x24020004, 0xafa20010, 0x8f430030, 0x11200004,
-0xafa30014, 0x8f4200b0, 0x621025, 0xafa20014,
-0x3c020002, 0x1021025, 0xafa20018, 0x8f460098,
-0x8f420108, 0x40f809, 0x0, 0x10400069,
-0x3224ffff, 0x8f42008c, 0x8f430094, 0x24420001,
-0xaf42008c, 0x24020001, 0xae03000c, 0xa34205c2,
-0x8f420098, 0x2406fff8, 0x8f45013c, 0x441021,
-0x24420007, 0x461024, 0x24840007, 0xaf420094,
-0x8f420090, 0x8f430094, 0x862024, 0x441023,
-0x65182b, 0x14600005, 0xaf420090, 0x8f420094,
-0x8f430144, 0x431023, 0xaf420094, 0x8f430094,
-0x8f420140, 0x43102b, 0x10400009, 0x0,
-0x8f43013c, 0x8f440094, 0x8f420090, 0x8f450138,
-0x641823, 0x431023, 0xaf420090, 0xaf450094,
-0x8f420094, 0x1000001f, 0xaf420098, 0x10e0001d,
-0x30c200ff, 0x14400002, 0x24020010, 0x24020002,
-0xafa20010, 0x8f420030, 0xafa80018, 0xafa20014,
-0x8f460098, 0x8f420108, 0x40f809, 0x0,
-0x10400030, 0x3225ffff, 0x8f420098, 0x8f44013c,
-0x451021, 0xaf420098, 0x8f420090, 0x8f430098,
-0xa34005c2, 0x451023, 0x64182b, 0x14600005,
-0xaf420090, 0x8f420098, 0x8f430144, 0x431023,
-0xaf420098, 0x8f420030, 0x8f430040, 0x24420001,
-0x2463ffff, 0x431024, 0xaf420030, 0x8f420030,
-0x14520018, 0x0, 0x8f420000, 0x10400007,
-0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd,
-0x0, 0x10000005, 0x0, 0xaf800048,
-0x8f820048, 0x1040fffd, 0x0, 0x8f820060,
-0x2403fff7, 0x431024, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x10000002, 0xaf80004c,
-0xaf800048, 0x8fbf002c, 0x8fb20028, 0x8fb10024,
-0x8fb00020, 0x3e00008, 0x27bd0030, 0x3e00008,
-0x0, 0x27bdffd8, 0x3c020001, 0x34422ec0,
-0xafbf0020, 0x8f4300f0, 0x8f840108, 0x2e21021,
-0x54620004, 0x24620008, 0x3c020001, 0x34422cc0,
-0x2e21021, 0x401821, 0xaf4300f0, 0xac600000,
-0x8f4200ec, 0x8c660004, 0x14620004, 0x3c020001,
-0x24820020, 0x1000000f, 0xaf820108, 0x8f4300f0,
-0x34422ec0, 0x2e21021, 0x54620004, 0x24620008,
-0x3c020001, 0x34422cc0, 0x2e21021, 0x401821,
-0x8c620004, 0x21140, 0x821021, 0xaf820108,
-0xac600000, 0x8c850018, 0x30a20036, 0x1040006c,
-0x30a20001, 0x8c82001c, 0x8f430040, 0x8f440034,
-0x24420001, 0x2463ffff, 0x431024, 0x862021,
-0xaf42002c, 0x30a20030, 0x14400006, 0xaf440034,
-0x8f420034, 0x8c03023c, 0x43102b, 0x144000b4,
-0x0, 0x32c20010, 0x10400028, 0x24070008,
-0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c,
-0x8f860120, 0x24020080, 0xafa20010, 0xafa30014,
-0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400011, 0x24020001, 0x3c010001, 0x370821,
-0xa02240f1, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x248467c4, 0xafa20014, 0x8f46002c,
-0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51100,
-0x10000036, 0x0, 0x8f420300, 0x8f43002c,
-0x24420001, 0xaf420300, 0x8f420300, 0x24020001,
-0xa34205c1, 0x10000026, 0xaf430038, 0x8f440170,
-0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
-0x24020020, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
-0x24020001, 0x3c010001, 0x370821, 0xa02240f0,
-0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x248467b8, 0xafa20014, 0x8f46002c, 0x8f870120,
-0x3c050009, 0xc002b3b, 0x34a50900, 0x1000000f,
-0x0, 0x8f420300, 0x24420001, 0xaf420300,
-0x8f420300, 0x8f42002c, 0xa34005c1, 0xaf420038,
-0x3c010001, 0x370821, 0xa02040f1, 0x3c010001,
-0x370821, 0xa02040f0, 0xaf400034, 0x8f420314,
-0x24420001, 0xaf420314, 0x10000059, 0x8f420314,
-0x10400022, 0x30a27000, 0x8c85001c, 0x8f420028,
-0xa22023, 0x4810003, 0x0, 0x8f420040,
-0x822021, 0x8f420358, 0x8f430000, 0xaf450028,
-0x441021, 0x10600007, 0xaf420358, 0xaf80004c,
-0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
-0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
-0x0, 0x8f820060, 0x34420008, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x10000038,
-0xaf80004c, 0x10000036, 0xaf800048, 0x1040002f,
-0x30a21000, 0x1040000c, 0x30a24000, 0x8c83001c,
-0x8f420050, 0x622023, 0x4820001, 0x24840200,
-0x8f42035c, 0x441021, 0xaf42035c, 0x8f420368,
-0x1000001a, 0xaf430050, 0x1040000c, 0x32c28000,
-0x8c83001c, 0x8f420070, 0x622023, 0x4820001,
-0x24840400, 0x8f420364, 0x441021, 0xaf420364,
-0x8f420368, 0x1000000d, 0xaf430070, 0x1040000e,
-0x3c020800, 0x8c83001c, 0x8f420060, 0x622023,
-0x4820001, 0x24840100, 0x8f420360, 0x441021,
-0xaf420360, 0x8f420368, 0xaf430060, 0x441021,
-0xaf420368, 0x3c020800, 0x2c21024, 0x50400008,
-0x36940040, 0x10000006, 0x0, 0x30a20100,
-0x10400003, 0x0, 0xc002bd8, 0x0,
-0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008,
-0x0, 0x27bdffa8, 0xafbf0050, 0xafbe004c,
-0xafb50048, 0xafb30044, 0xafb20040, 0xafb1003c,
-0xafb00038, 0x8f910108, 0x26220020, 0xaf820108,
-0x8e320018, 0xa821, 0x32420024, 0x104001ba,
-0xf021, 0x8e26001c, 0x8f43001c, 0x61100,
-0x621821, 0x8c70000c, 0x9604000c, 0x962d0016,
-0x9473000a, 0x2c8305dd, 0x38828870, 0x2c420001,
-0x621825, 0x10600015, 0x2821, 0x32c20040,
-0x10400015, 0x24020800, 0x96030014, 0x14620012,
-0x3402aaaa, 0x9603000e, 0x14620007, 0x2021,
-0x96030010, 0x24020300, 0x14620004, 0x801021,
-0x96020012, 0x2c440001, 0x801021, 0x54400006,
-0x24050016, 0x10000004, 0x0, 0x24020800,
-0x50820001, 0x2405000e, 0x934205c3, 0x14400008,
-0x5821, 0x240b0001, 0x32620180, 0xaf4500a8,
-0xaf5000a0, 0x10400002, 0xaf4600a4, 0xa34b05c3,
-0x10a00085, 0x2054021, 0x91020000, 0x3821,
-0x3042000f, 0x25080, 0x32c20002, 0x10400012,
-0x10a1821, 0x32620002, 0x10400010, 0x32c20001,
-0x1002021, 0x94820000, 0x24840002, 0xe23821,
-0x83102b, 0x1440fffb, 0x30e2ffff, 0x71c02,
-0x623821, 0x71c02, 0x30e2ffff, 0x623821,
-0x71027, 0xa502000a, 0x32c20001, 0x1040006a,
-0x32620001, 0x10400068, 0x0, 0x8f4200a8,
-0x10400065, 0x0, 0x8f4200a0, 0x8f4300a8,
-0x431021, 0x904c0009, 0x318900ff, 0x39230006,
-0x3182b, 0x39220011, 0x2102b, 0x621824,
-0x1060000c, 0x3c050006, 0x8f4200a4, 0x3c040001,
-0x248467d4, 0xafa20010, 0x8f4200a0, 0x34a54600,
-0x1203821, 0xc002b3b, 0xafa20014, 0x1000004e,
-0x0, 0x32c20004, 0x14400013, 0x2821,
-0x316200ff, 0x14400004, 0x0, 0x95020002,
-0x1000000d, 0x4a2823, 0x9505000c, 0x9502000e,
-0x95030010, 0xa22821, 0xa32821, 0x95030012,
-0x91040009, 0x95020002, 0xa32821, 0xa42821,
-0x4a1023, 0xa22821, 0x2002021, 0x94820000,
-0x24840002, 0xe23821, 0x88102b, 0x1440fffb,
-0x71c02, 0x30e2ffff, 0x623821, 0x71c02,
-0x30e2ffff, 0x623821, 0x1a52821, 0x51c02,
-0x30a2ffff, 0x622821, 0x51c02, 0x30a2ffff,
-0x622821, 0xa72823, 0x51402, 0xa22821,
-0x30a5ffff, 0x50a00001, 0x3405ffff, 0x316200ff,
-0x14400008, 0x318300ff, 0x8f4300a0, 0x8f4200a8,
-0x624021, 0x91020000, 0x3042000f, 0x25080,
-0x318300ff, 0x24020006, 0x14620003, 0x10a1021,
-0x10000002, 0x24440010, 0x24440006, 0x316200ff,
-0x14400006, 0x0, 0x94820000, 0xa22821,
-0x51c02, 0x30a2ffff, 0x622821, 0x934205c3,
-0x10400003, 0x32620100, 0x50400003, 0xa4850000,
-0x52827, 0xa4850000, 0x9622000e, 0x8f43009c,
-0x621821, 0x32a200ff, 0x10400007, 0xaf43009c,
-0x3c024000, 0x2021025, 0xafa20020, 0x8f42009c,
-0x10000003, 0x5e1025, 0xafb00020, 0x8f42009c,
-0xafa20024, 0x32620080, 0x10400010, 0x32620100,
-0x8f4200b4, 0x24430001, 0x210c0, 0x571021,
-0xaf4300b4, 0x8fa30020, 0x8fa40024, 0x3c010001,
-0x220821, 0xac2338e8, 0x3c010001, 0x220821,
-0xac2438ec, 0x100000a5, 0x32c20020, 0x10400064,
-0x0, 0x8f4200b4, 0x24430001, 0x210c0,
-0x571021, 0xaf4300b4, 0x8fa30020, 0x8fa40024,
-0x3c010001, 0x220821, 0xac2338e8, 0x3c010001,
-0x220821, 0xac2438ec, 0x8f4200b4, 0x10400051,
-0x3821, 0x3c090001, 0x352938e8, 0x3c08001f,
-0x3508ffff, 0x240bffff, 0x340affff, 0x710c0,
-0x571021, 0x491021, 0x8c430000, 0x8c440004,
-0xafa30028, 0xafa4002c, 0x8f8200fc, 0x8fa30028,
-0x8fa4002c, 0xac430000, 0xac440004, 0x24420008,
-0xaf8200f0, 0x8f42008c, 0x2442ffff, 0xaf42008c,
-0x97a2002e, 0x8f440270, 0x8f450274, 0x401821,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaf440270, 0xaf450274, 0x8fa20028,
-0x481024, 0x90430000, 0x30630001, 0x1460000b,
-0x402021, 0x8f420278, 0x8f43027c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
-0x8f420278, 0x1000001a, 0x8f43027c, 0x8c820000,
-0x144b000e, 0x0, 0x94820004, 0x144a000b,
-0x0, 0x8f420288, 0x8f43028c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420288, 0xaf43028c,
-0x8f420288, 0x1000000a, 0x8f43028c, 0x8f420280,
-0x8f430284, 0x24630001, 0x2c640001, 0x441021,
-0xaf420280, 0xaf430284, 0x8f420280, 0x8f430284,
-0x8f4200b4, 0x24e70001, 0xe2102b, 0x1440ffb8,
-0x710c0, 0xa34005c3, 0x1000003f, 0xaf4000b4,
-0x8f8200fc, 0x8fa30020, 0x8fa40024, 0xac430000,
-0xac440004, 0x24420008, 0xaf8200f0, 0x8f42009c,
-0x8f46008c, 0x8f440270, 0x8f450274, 0x401821,
-0x1021, 0x24c6ffff, 0xaf46008c, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xaf440270,
-0xaf450274, 0x92020000, 0x30420001, 0x1440000c,
-0x2402ffff, 0x8f420278, 0x8f43027c, 0x24630001,
-0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
-0x8f420278, 0x8f43027c, 0x1000001c, 0x32c20020,
-0x8e030000, 0x1462000f, 0x3402ffff, 0x96030004,
-0x1462000c, 0x0, 0x8f420288, 0x8f43028c,
-0x24630001, 0x2c640001, 0x441021, 0xaf420288,
-0xaf43028c, 0x8f420288, 0x8f43028c, 0x1000000b,
-0x32c20020, 0x8f420280, 0x8f430284, 0x24630001,
-0x2c640001, 0x441021, 0xaf420280, 0xaf430284,
-0x8f420280, 0x8f430284, 0x32c20020, 0x10400005,
-0xaf40009c, 0x8f420358, 0x2442ffff, 0xaf420358,
-0x8f420358, 0x8e22001c, 0x8f430040, 0x24420001,
-0x2463ffff, 0x431024, 0xaf42002c, 0x32420060,
-0x14400008, 0x32c20010, 0x8f420034, 0x24420001,
-0xaf420034, 0x8c03023c, 0x43102b, 0x14400102,
-0x32c20010, 0x10400018, 0x24070008, 0x8f440170,
-0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
-0x24020080, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x10400047,
-0x24020001, 0x8f420300, 0x8f43002c, 0x24420001,
-0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1,
-0x1000007c, 0xaf430038, 0x8f440170, 0x8f450174,
-0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020020,
-0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c,
-0x40f809, 0x24c6001c, 0x10400057, 0x24020001,
-0x10000065, 0x0, 0x32420012, 0x10400075,
-0x32420001, 0x9622000e, 0x8f43009c, 0x621821,
-0x32c20020, 0x10400005, 0xaf43009c, 0x8f420358,
-0x2442ffff, 0xaf420358, 0x8f420358, 0x8e22001c,
-0x8f430040, 0x24420001, 0x2463ffff, 0x431024,
-0xaf42002c, 0x32420010, 0x14400008, 0x32c20010,
-0x8f420034, 0x24420001, 0xaf420034, 0x8c03023c,
-0x43102b, 0x144000bc, 0x32c20010, 0x10400028,
-0x24070008, 0x8f440170, 0x8f450174, 0x8f43002c,
-0x8f48000c, 0x8f860120, 0x24020080, 0xafa20010,
-0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809,
-0x24c6001c, 0x14400011, 0x24020001, 0x3c010001,
-0x370821, 0xa02240f1, 0x8f820124, 0xafa20010,
-0x8f820128, 0x3c040001, 0x248467c4, 0xafa20014,
-0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b,
-0x34a51100, 0x10000036, 0x0, 0x8f420300,
-0x8f43002c, 0x24420001, 0xaf420300, 0x8f420300,
-0x24020001, 0xa34205c1, 0x10000026, 0xaf430038,
-0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c,
-0x8f860120, 0x24020020, 0xafa20010, 0xafa30014,
-0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x14400011, 0x24020001, 0x3c010001, 0x370821,
-0xa02240f0, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x248467b8, 0xafa20014, 0x8f46002c,
-0x8f870120, 0x3c050009, 0xc002b3b, 0x34a50900,
-0x1000000f, 0x0, 0x8f420300, 0x24420001,
-0xaf420300, 0x8f420300, 0x8f42002c, 0xa34005c1,
-0xaf420038, 0x3c010001, 0x370821, 0xa02040f1,
-0x3c010001, 0x370821, 0xa02040f0, 0xaf400034,
-0x8f420314, 0x24420001, 0xaf420314, 0x10000062,
-0x8f420314, 0x10400022, 0x32427000, 0x8e25001c,
-0x8f420028, 0xa22023, 0x4810003, 0x0,
-0x8f420040, 0x822021, 0x8f420358, 0x8f430000,
-0xaf450028, 0x441021, 0x10600007, 0xaf420358,
-0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
-0x10000005, 0x0, 0xaf800048, 0x8f820048,
-0x1040fffd, 0x0, 0x8f820060, 0x34420008,
-0xaf820060, 0x8f420000, 0x10400003, 0x0,
-0x10000041, 0xaf80004c, 0x1000003f, 0xaf800048,
-0x1040002f, 0x32421000, 0x1040000c, 0x32424000,
-0x8e23001c, 0x8f420050, 0x622023, 0x4820001,
-0x24840200, 0x8f42035c, 0x441021, 0xaf42035c,
-0x8f420368, 0x1000001a, 0xaf430050, 0x1040000c,
-0x32c28000, 0x8e23001c, 0x8f420070, 0x622023,
-0x4820001, 0x24840400, 0x8f420364, 0x441021,
-0xaf420364, 0x8f420368, 0x1000000d, 0xaf430070,
-0x1040000e, 0x3c020800, 0x8e23001c, 0x8f420060,
-0x622023, 0x4820001, 0x24840100, 0x8f420360,
-0x441021, 0xaf420360, 0x8f420368, 0xaf430060,
-0x441021, 0xaf420368, 0x3c020800, 0x2c21024,
-0x50400011, 0x36940040, 0x1000000f, 0x0,
-0x32420048, 0x10400007, 0x24150001, 0x8e22001c,
-0x3c03ffff, 0x43f024, 0x3042ffff, 0x1000fd75,
-0xae22001c, 0x32420100, 0x10400003, 0x0,
-0xc002bd8, 0x0, 0x8fbf0050, 0x8fbe004c,
-0x8fb50048, 0x8fb30044, 0x8fb20040, 0x8fb1003c,
-0x8fb00038, 0x3e00008, 0x27bd0058, 0x3e00008,
-0x0, 0x0, 0x0, 0x8f8300e4,
-0x8f8200e0, 0x2404fff8, 0x441024, 0x621026,
-0x2102b, 0x21023, 0x3e00008, 0x621024,
-0x3e00008, 0x0, 0x27bdffe0, 0xafbf001c,
-0xafb00018, 0x8f8600c4, 0x8f8400e0, 0x8f8500e4,
-0x2402fff8, 0x821824, 0x10a30009, 0x27623ff8,
-0x14a20002, 0x24a20008, 0x27623000, 0x408021,
-0x16030005, 0x30820004, 0x10400004, 0xc02021,
-0x10000022, 0x1021, 0x8e040000, 0x8f42011c,
-0x14a20003, 0x0, 0x8f420120, 0xaf420114,
-0x8ca30000, 0x8f420148, 0x831823, 0x43102b,
-0x10400003, 0x0, 0x8f420148, 0x621821,
-0x94a20006, 0x24420050, 0x62102b, 0x1440000f,
-0xa01021, 0xafa40010, 0xafa30014, 0x8ca60000,
-0x8ca70004, 0x3c040001, 0xc002b3b, 0x24846894,
-0x8f42020c, 0x24420001, 0xaf42020c, 0x8f42020c,
-0x1021, 0xaf9000e8, 0xaf9000e4, 0x8fbf001c,
-0x8fb00018, 0x3e00008, 0x27bd0020, 0x3e00008,
-0x0, 0x8f8400e0, 0x8f8800c4, 0x8f8300e8,
-0x2402fff8, 0x823824, 0xe32023, 0x2c821000,
-0x50400001, 0x24841000, 0x420c2, 0x801821,
-0x8f440258, 0x8f45025c, 0x1021, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xaf440258,
-0xaf45025c, 0x8f8300c8, 0x8f420148, 0x1032023,
-0x82102b, 0x14400004, 0x801821, 0x8f420148,
-0x822021, 0x801821, 0x8f440250, 0x8f450254,
-0x1021, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaf440250, 0xaf450254, 0xaf8800c8,
-0xaf8700e4, 0xaf8700e8, 0x3e00008, 0x0,
-0x27bdff30, 0x240a0001, 0xafbf00c8, 0xafbe00c4,
-0xafb500c0, 0xafb300bc, 0xafb200b8, 0xafb100b4,
-0xafb000b0, 0xa3a00097, 0xafa00044, 0xafaa005c,
-0x934205c4, 0xa7a0008e, 0x1040000a, 0xa7a00086,
-0x8f4b00c4, 0xafab0064, 0x8f4a00c0, 0xafaa006c,
-0x8f4b00cc, 0xafab0074, 0x8f4a00c8, 0x10000129,
-0xafaa007c, 0x8f420114, 0x40f809, 0x0,
-0x403021, 0x10c0034f, 0x0, 0x8cc20000,
-0x8cc30004, 0xafa20020, 0xafa30024, 0x8fab0024,
-0x8faa0020, 0x3162ffff, 0x2442fffc, 0xafa2006c,
-0x3c020006, 0x2c21024, 0xafab007c, 0x14400015,
-0xafaa0064, 0x91420000, 0x30420001, 0x10400011,
-0x2402ffff, 0x8d430000, 0x14620004, 0x3402ffff,
-0x95430004, 0x1062000b, 0x0, 0xc0024bb,
-0x8fa40064, 0x304200ff, 0x14400006, 0x0,
-0x8f420118, 0x40f809, 0x0, 0x1000032d,
-0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
-0x431024, 0x3c03ffff, 0x431824, 0x14600003,
-0xafa20024, 0x10000040, 0x1821, 0x3c020080,
-0x621024, 0x10400007, 0x0, 0x8f42038c,
-0x24420001, 0xaf42038c, 0x8f42038c, 0x10000036,
-0x24030001, 0x8f420210, 0x24420001, 0xaf420210,
-0x8f420210, 0x3c020001, 0x621024, 0x10400006,
-0x3c020002, 0x8f4201c4, 0x24420001, 0xaf4201c4,
-0x8f4201c4, 0x3c020002, 0x621024, 0x10400006,
-0x3c020004, 0x8f42037c, 0x24420001, 0xaf42037c,
-0x8f42037c, 0x3c020004, 0x621024, 0x10400006,
-0x3c020008, 0x8f420380, 0x24420001, 0xaf420380,
-0x8f420380, 0x3c020008, 0x621024, 0x10400006,
-0x3c020010, 0x8f420384, 0x24420001, 0xaf420384,
-0x8f420384, 0x3c020010, 0x621024, 0x10400006,
-0x3c020020, 0x8f4201c0, 0x24420001, 0xaf4201c0,
-0x8f4201c0, 0x3c020020, 0x621024, 0x10400006,
-0x24030001, 0x8f420388, 0x24420001, 0xaf420388,
-0x8f420388, 0x24030001, 0x8c020260, 0x8fab006c,
-0x4b102b, 0x10400014, 0x307000ff, 0x8f4201e8,
-0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8faa007c,
-0x8f8200e0, 0x354a0100, 0xafaa007c, 0xafa20010,
-0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0,
-0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007,
-0xc002b3b, 0x34a50800, 0x12000010, 0x3c020080,
-0x2c21024, 0x1440000e, 0x32c20400, 0x8fab007c,
-0x3c020080, 0x34420100, 0x1621024, 0x10400005,
-0x0, 0x8f42020c, 0x24420001, 0xaf42020c,
-0x8f42020c, 0x100002b0, 0x8fa3006c, 0x32c20400,
-0x10400015, 0x34028100, 0x8faa0064, 0x9543000c,
-0x14620012, 0x3c020100, 0x240b0200, 0xa7ab008e,
-0x9542000e, 0x8d430008, 0x8d440004, 0x8d450000,
-0x8faa006c, 0x8fab0064, 0x254afffc, 0xafaa006c,
-0xa7a20086, 0xad63000c, 0xad640008, 0xad650004,
-0x256b0004, 0xafab0064, 0x3c020100, 0x2c21024,
-0x10400004, 0x0, 0x8faa006c, 0x254a0004,
-0xafaa006c, 0x8f4200bc, 0x5040000a, 0xafa00074,
-0x8fab006c, 0x4b102b, 0x50400006, 0xafa00074,
-0x8f4200bc, 0x1621023, 0xafa20074, 0x8f4a00bc,
-0xafaa006c, 0x8f420080, 0x8fab006c, 0x4b102b,
-0x10400056, 0x32c28000, 0x1040005e, 0x240a0003,
-0x32c21000, 0x1040005b, 0xafaa005c, 0x10000058,
-0x240b0004, 0x8f420350, 0x2403ffbf, 0x283a024,
-0x24420001, 0xaf420350, 0x1000024f, 0x8f420350,
-0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128,
-0x3c040001, 0x248468d0, 0x26620001, 0xafa20014,
-0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007,
-0xc002b3b, 0x34a52250, 0x1000023f, 0x0,
-0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128,
-0x3c040001, 0x248468d0, 0x24020002, 0xafa20014,
-0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007,
-0xc002b3b, 0x34a52450, 0x1000022f, 0x0,
-0x8ea20000, 0x8ea30004, 0x3c040001, 0x248468e8,
-0xafb00010, 0xafbe0014, 0x8ea70018, 0x34a52800,
-0xc002b3b, 0x603021, 0x10000223, 0x0,
-0xa6b1000a, 0x8f820124, 0x3c040001, 0x248468f0,
-0xafbe0014, 0xafa20010, 0x8f460044, 0x8f870120,
-0x3c050007, 0xc002b3b, 0x34a53000, 0x10000216,
-0x0, 0xa6b1000a, 0xa6b2000e, 0x8f820124,
-0x3c040001, 0x248468fc, 0xafbe0014, 0xafa20010,
-0x8f460044, 0x8f870120, 0x3c050007, 0xc002b3b,
-0x34a53200, 0x10000208, 0x0, 0x8f420084,
-0x8faa006c, 0x4a102b, 0x14400007, 0x3c020001,
-0x2c21024, 0x10400004, 0x0, 0x240b0002,
-0xafab005c, 0x8faa006c, 0x1140021b, 0x27ab0020,
-0xafab00a4, 0x3c0a001f, 0x354affff, 0xafaa009c,
-0x8fab005c, 0x240a0001, 0x556a0021, 0x240a0002,
-0x8f430054, 0x8f420050, 0x1062000b, 0x274b0054,
-0x8f5e0054, 0x3403ecc0, 0xafab004c, 0x27c20001,
-0x304201ff, 0xafa20054, 0x1e1140, 0x431021,
-0x1000006b, 0x2e2a821, 0x8f420044, 0x8faa006c,
-0x3c040001, 0x248468ac, 0xafaa0014, 0xafa20010,
-0x8f460054, 0x8f470050, 0x3c050007, 0xc002b3b,
-0x34a51300, 0x8f430350, 0x2402ffbf, 0x282a024,
-0x24630001, 0xaf430350, 0x100001d3, 0x8f420350,
-0x156a001d, 0x0, 0x8f430074, 0x8f420070,
-0x1062000a, 0x274b0074, 0x8f5e0074, 0xafab004c,
-0x27c20001, 0x304203ff, 0xafa20054, 0x1e1140,
-0x24426cc0, 0x1000004a, 0x2e2a821, 0x8f420044,
-0x8faa006c, 0x3c040001, 0x248468b8, 0x3c050007,
-0xafaa0014, 0xafa20010, 0x8f460074, 0x8f470070,
-0x34a51500, 0x240b0001, 0xc002b3b, 0xafab005c,
-0x1000ffc3, 0x0, 0x8f430064, 0x8f420060,
-0x1062001a, 0x274a0064, 0x8f5e0064, 0x8fab005c,
-0xafaa004c, 0x27c20001, 0x304200ff, 0xafa20054,
-0x24020004, 0x1562000e, 0x1e1140, 0x1e1180,
-0x24420cc0, 0x2e21021, 0xafa20044, 0x9442002a,
-0x8faa0044, 0x8fab006c, 0x4b102b, 0x10400024,
-0x25550020, 0x240a0001, 0x10000021, 0xa3aa0097,
-0x24424cc0, 0x1000001e, 0x2e2a821, 0x8f420044,
-0x8fab006c, 0x3c040001, 0x248468c4, 0xafab0014,
-0xafa20010, 0x8f460064, 0x8f470060, 0x3c050007,
-0xc002b3b, 0x34a51800, 0x3c020008, 0x2c21024,
-0x1440ff34, 0x0, 0x8f420370, 0x240a0001,
-0xafaa005c, 0x24420001, 0xaf420370, 0x1000ff90,
-0x8f420370, 0x27a30036, 0x131040, 0x621821,
-0x94620000, 0x441021, 0x10000020, 0xa4620000,
-0x8fab0064, 0xaeab0018, 0x93a20097, 0x10400072,
-0x9821, 0x8faa0044, 0x8fa4006c, 0x8fa300a4,
-0x25420020, 0xafa20028, 0x25420008, 0xafa20030,
-0x25420010, 0xafaa002c, 0xafa20034, 0x9542002a,
-0xa7a20038, 0x95420018, 0xa7a2003a, 0x9542001a,
-0xa7a2003c, 0x9542001c, 0xa7a2003e, 0x94620018,
-0x24630002, 0x822023, 0x1880ffde, 0x26730001,
-0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc,
-0x26650001, 0xa2102a, 0x1440002b, 0x24030001,
-0x8f83012c, 0x10600023, 0x0, 0x8f820124,
-0x431023, 0x22143, 0x58800001, 0x24840040,
-0x8f820128, 0x431023, 0x21943, 0x58600001,
-0x24630040, 0x64102a, 0x54400001, 0x602021,
-0xaf4400fc, 0x8f4200fc, 0xa2102a, 0x10400011,
-0x24030001, 0x10000015, 0x306200ff, 0x8fab0064,
-0x96070018, 0xafab0010, 0x8e220008, 0x3c040001,
-0x248468dc, 0x8c430004, 0x8c420000, 0x34a52400,
-0x2403021, 0xc002b3b, 0xafa30014, 0x1000002b,
-0x0, 0x8f420334, 0x1821, 0x24420001,
-0xaf420334, 0x8f420334, 0x306200ff, 0x5040fedc,
-0x3c020800, 0x12600021, 0x9021, 0x8fb100a4,
-0x2208021, 0x8e220008, 0x96070018, 0x8fa60064,
-0x8c440000, 0x8c450004, 0x240a0001, 0xafaa0010,
-0xafbe0014, 0x8f420008, 0xafa20018, 0x8f42010c,
-0x40f809, 0x0, 0x1040ffd8, 0x3c050007,
-0x96020018, 0x8fab0064, 0x8faa009c, 0x1625821,
-0x14b102b, 0x10400004, 0xafab0064, 0x8f420148,
-0x1625823, 0xafab0064, 0x26100002, 0x26520001,
-0x253102b, 0x1440ffe3, 0x26310004, 0x8fb0006c,
-0x10000036, 0x97b10038, 0x8f4200fc, 0x24050002,
-0xa2102a, 0x1440001b, 0x24030001, 0x8f83012c,
-0x10600013, 0x0, 0x8f820124, 0x431023,
-0x22143, 0x58800001, 0x24840040, 0x8f820128,
-0x431023, 0x21943, 0x58600001, 0x24630040,
-0x64102a, 0x54400001, 0x602021, 0xaf4400fc,
-0x8f4200fc, 0xa2102a, 0x14400006, 0x24030001,
-0x8f420334, 0x1821, 0x24420001, 0xaf420334,
-0x8f420334, 0x306200ff, 0x1040fea5, 0x3c020800,
-0x96b1000a, 0x8fb0006c, 0x3223ffff, 0x70102b,
-0x54400001, 0x608021, 0x8ea40000, 0x8ea50004,
-0x240b0001, 0xafab0010, 0xafbe0014, 0x8f420008,
-0x8fa60064, 0xafa20018, 0x8f42010c, 0x40f809,
-0x2003821, 0x1040fea2, 0x3c050007, 0x96a3000e,
-0x97aa008e, 0x11400007, 0x609021, 0x934205c4,
-0x14400004, 0x0, 0x97ab0086, 0x6a1825,
-0xa6ab0016, 0x8faa007c, 0x3c02ffff, 0x1421024,
-0x10400003, 0xa1402, 0x34630400, 0xa6a20014,
-0x8fab006c, 0x560b0072, 0xa6a3000e, 0x34620004,
-0xa6a2000e, 0x8faa0074, 0x16a1021, 0xa6a2000a,
-0x8f430044, 0x8f4401a0, 0x8f4501a4, 0x34028000,
-0xafa20010, 0x8f420044, 0x2a03021, 0x24070020,
-0xafa20014, 0x8f42000c, 0x31940, 0x604821,
-0xafa20018, 0x8f42010c, 0x4021, 0xa92821,
-0xa9182b, 0x882021, 0x40f809, 0x832021,
-0x5040fe7f, 0xa6b2000e, 0x8f420368, 0xafa0006c,
-0xa34005c4, 0x2442ffff, 0xaf420368, 0x8fab005c,
-0x240a0001, 0x8f420368, 0x156a0006, 0x240a0002,
-0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c,
-0x8f42035c, 0x156a0006, 0x0, 0x8f420364,
-0x2442ffff, 0xaf420364, 0x10000005, 0x8f420364,
-0x8f420360, 0x2442ffff, 0xaf420360, 0x8f420360,
-0x8faa0054, 0x8fab004c, 0xad6a0000, 0x8f420044,
-0x8f440088, 0x8f430078, 0x24420001, 0x441024,
-0x24630001, 0xaf420044, 0xaf430078, 0x8c020240,
-0x62182b, 0x14600075, 0x24070008, 0x8f440168,
-0x8f45016c, 0x8f430044, 0x8f48000c, 0x8f860120,
-0x24020040, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
-0x240b0001, 0x3c010001, 0x370821, 0xa02b40f2,
-0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x2484688c, 0xafa20014, 0x8f460044, 0x8f870120,
-0x3c050009, 0xc002b3b, 0x34a51300, 0x1000000b,
-0x0, 0x8f420304, 0x24420001, 0xaf420304,
-0x8f420304, 0x8f420044, 0xaf42007c, 0x3c010001,
-0x370821, 0xa02040f2, 0xaf400078, 0x8f420318,
-0x24420001, 0xaf420318, 0x10000048, 0x8f420318,
-0xa6b0000a, 0x8f430044, 0x8f4401a0, 0x8f4501a4,
-0x34028000, 0xafa20010, 0x8f420044, 0x2a03021,
-0x24070020, 0xafa20014, 0x8f42000c, 0x31940,
-0x604821, 0xafa20018, 0x8f42010c, 0x4021,
-0xa92821, 0xa9182b, 0x882021, 0x40f809,
-0x832021, 0x1040fe1f, 0x240a0001, 0xa34a05c4,
-0x8fab006c, 0x8faa0064, 0x1705823, 0xafab006c,
-0x8fab009c, 0x1505021, 0x16a102b, 0x10400004,
-0xafaa0064, 0x8f420148, 0x1425023, 0xafaa0064,
-0x8f420368, 0x2442ffff, 0xaf420368, 0x8faa005c,
-0x240b0001, 0x8f420368, 0x154b0006, 0x240b0002,
-0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c,
-0x8f42035c, 0x114b0006, 0x0, 0x8f420360,
-0x2442ffff, 0xaf420360, 0x10000005, 0x8f420360,
-0x8f420364, 0x2442ffff, 0xaf420364, 0x8f420364,
-0x8fab0054, 0x8faa004c, 0xad4b0000, 0x8f420044,
-0x8f440088, 0x8f430078, 0x24420001, 0x441024,
-0x24630001, 0xaf420044, 0xaf430078, 0x8faa006c,
-0x1540fe0b, 0x0, 0x8fab006c, 0x1160001e,
-0x0, 0x934205c4, 0x10400009, 0x0,
-0x8faa0064, 0xaf4a00c4, 0xaf4b00c0, 0x8fab007c,
-0xaf4b00c8, 0x8faa0074, 0x1000000e, 0xaf4a00cc,
-0x97ab008e, 0x1160000b, 0x34038100, 0x8fa20020,
-0x8c46000c, 0xa443000c, 0x97aa0086, 0x8c440004,
-0x8c450008, 0xa44a000e, 0xac440000, 0xac450004,
-0xac460008, 0x8f42034c, 0x24420001, 0xaf42034c,
-0x10000010, 0x8f42034c, 0x8fab007c, 0x3164ffff,
-0x2484fffc, 0x801821, 0x8f440250, 0x8f450254,
-0x8f460118, 0x1021, 0xa32821, 0xa3382b,
-0x822021, 0x872021, 0xaf440250, 0xc0f809,
-0xaf450254, 0x8fbf00c8, 0x8fbe00c4, 0x8fb500c0,
-0x8fb300bc, 0x8fb200b8, 0x8fb100b4, 0x8fb000b0,
-0x3e00008, 0x27bd00d0, 0x3e00008, 0x0,
-0x27bdff38, 0x240b0001, 0xafbf00c0, 0xafbe00bc,
-0xafb500b8, 0xafb300b4, 0xafb200b0, 0xafb100ac,
-0xafb000a8, 0xa3a00087, 0xafa00044, 0xafab005c,
-0x934205c4, 0xa7a00076, 0x10400007, 0xa7a0007e,
-0x8f4c00c0, 0xafac0064, 0x8f4b00c8, 0x8f5e00c4,
-0x10000130, 0xafab006c, 0x8f420114, 0x40f809,
-0x0, 0x403021, 0x10c002a1, 0x0,
-0x8cc20000, 0x8cc30004, 0xafa20020, 0xafa30024,
-0x8fac0024, 0x8fbe0020, 0x3182ffff, 0x2442fffc,
-0xafa20064, 0x3c020006, 0x2c21024, 0x14400015,
-0xafac006c, 0x93c20000, 0x30420001, 0x10400011,
-0x2402ffff, 0x8fc30000, 0x14620004, 0x3402ffff,
-0x97c30004, 0x1062000b, 0x0, 0xc0024bb,
-0x3c02021, 0x304200ff, 0x14400006, 0x0,
-0x8f420118, 0x40f809, 0x0, 0x10000280,
-0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
-0x431024, 0x3c03ffff, 0x431824, 0x14600003,
-0xafa20024, 0x10000040, 0x8021, 0x3c020080,
-0x621024, 0x10400007, 0x0, 0x8f42038c,
-0x24420001, 0xaf42038c, 0x8f42038c, 0x10000036,
-0x24100001, 0x8f420210, 0x24420001, 0xaf420210,
-0x8f420210, 0x3c020001, 0x621024, 0x10400006,
-0x3c020002, 0x8f4201c4, 0x24420001, 0xaf4201c4,
-0x8f4201c4, 0x3c020002, 0x621024, 0x10400006,
-0x3c020004, 0x8f42037c, 0x24420001, 0xaf42037c,
-0x8f42037c, 0x3c020004, 0x621024, 0x10400006,
-0x3c020008, 0x8f420380, 0x24420001, 0xaf420380,
-0x8f420380, 0x3c020008, 0x621024, 0x10400006,
-0x3c020010, 0x8f420384, 0x24420001, 0xaf420384,
-0x8f420384, 0x3c020010, 0x621024, 0x10400006,
-0x3c020020, 0x8f4201c0, 0x24420001, 0xaf4201c0,
-0x8f4201c0, 0x3c020020, 0x621024, 0x10400006,
-0x24100001, 0x8f420388, 0x24420001, 0xaf420388,
-0x8f420388, 0x24100001, 0x8c020260, 0x8fab0064,
-0x4b102b, 0x10400015, 0x320200ff, 0x8f4201e8,
-0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8fac006c,
-0x8f8200e0, 0x358c0100, 0xafac006c, 0xafa20010,
-0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0,
-0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007,
-0xc002b3b, 0x34a53600, 0x320200ff, 0x10400010,
-0x3c020080, 0x2c21024, 0x1440000e, 0x32c20400,
-0x8fab006c, 0x3c020080, 0x34420100, 0x1621024,
-0x10400005, 0x0, 0x8f42020c, 0x24420001,
-0xaf42020c, 0x8f42020c, 0x10000202, 0x8fa30064,
-0x32c20400, 0x10400012, 0x34028100, 0x97c3000c,
-0x1462000f, 0x0, 0x240c0200, 0xa7ac0076,
-0x97c2000e, 0x8fc30008, 0x8fc40004, 0x8fab0064,
-0x8fc50000, 0x256bfffc, 0xafab0064, 0xa7a2007e,
-0xafc3000c, 0xafc40008, 0xafc50004, 0x27de0004,
-0x8fa70064, 0x320200ff, 0x14400034, 0x3c020100,
-0x97c4000c, 0x2c8305dd, 0x38828870, 0x2c420001,
-0x621825, 0x10600015, 0x2821, 0x32c20800,
-0x10400015, 0x24020800, 0x97c30014, 0x14620012,
-0x3402aaaa, 0x97c3000e, 0x14620007, 0x2021,
-0x97c30010, 0x24020300, 0x14620004, 0x801021,
-0x97c20012, 0x2c440001, 0x801021, 0x54400006,
-0x24050016, 0x10000004, 0x0, 0x24020800,
-0x50820001, 0x2405000e, 0x10a00013, 0x3c52021,
-0x24830009, 0x3c02001f, 0x3442ffff, 0x43102b,
-0x10400003, 0x0, 0x8f420148, 0x621823,
-0x90620000, 0x38430006, 0x2c630001, 0x38420011,
-0x2c420001, 0x621825, 0x10600004, 0x3c020100,
-0x94820002, 0x453821, 0x3c020100, 0x2c21024,
-0x5040000e, 0xafa70064, 0x8fac0064, 0x10ec0008,
-0x3c050007, 0x3c040001, 0x24846908, 0x8fa60064,
-0x34a54000, 0xafa00010, 0xc002b3b, 0xafa00014,
-0x8fab0064, 0x256b0004, 0xafab0064, 0x8f420080,
-0x8fac0064, 0x4c102b, 0x1040002c, 0x32c28000,
-0x10400034, 0x240b0003, 0x32c21000, 0x10400031,
-0xafab005c, 0x1000002e, 0x240c0004, 0x8f420350,
-0x2403ffbf, 0x283a024, 0x24420001, 0xaf420350,
-0x10000173, 0x8f420350, 0x3c020800, 0x2c2b025,
-0x2402ffbf, 0x282a024, 0x8f830128, 0x3c040001,
-0x248468d0, 0x26620001, 0xafa20014, 0xafa30010,
-0x8f860120, 0x8f870124, 0x3c050007, 0xc002b3b,
-0x34a55300, 0x10000162, 0x0, 0x8ea20000,
-0x8ea30004, 0x3c040001, 0x248468e8, 0xafb00010,
-0xafb10014, 0x8ea70018, 0x34a55900, 0xc002b3b,
-0x603021, 0x10000156, 0x0, 0x8f420084,
-0x8fab0064, 0x4b102b, 0x14400007, 0x3c020001,
-0x2c21024, 0x10400004, 0x0, 0x240c0002,
-0xafac005c, 0x8fab0064, 0x11600166, 0x27ac0020,
-0xafac008c, 0x8fab005c, 0x240c0001, 0x556c0021,
-0x240c0002, 0x8f430054, 0x8f420050, 0x1062000b,
-0x274b0054, 0x8f510054, 0x3403ecc0, 0xafab004c,
-0x26220001, 0x304201ff, 0xafa20054, 0x111140,
-0x431021, 0x1000006b, 0x2e2a821, 0x8f420044,
-0x8fac0064, 0x3c040001, 0x248468ac, 0xafac0014,
-0xafa20010, 0x8f460054, 0x8f470050, 0x3c050007,
-0xc002b3b, 0x34a54300, 0x8f430350, 0x2402ffbf,
-0x282a024, 0x24630001, 0xaf430350, 0x10000124,
-0x8f420350, 0x156c001d, 0x0, 0x8f430074,
-0x8f420070, 0x1062000a, 0x274b0074, 0x8f510074,
-0xafab004c, 0x26220001, 0x304203ff, 0xafa20054,
-0x111140, 0x24426cc0, 0x1000004a, 0x2e2a821,
-0x8f420044, 0x8fac0064, 0x3c040001, 0x248468b8,
-0x3c050007, 0xafac0014, 0xafa20010, 0x8f460074,
-0x8f470070, 0x34a54500, 0x240b0001, 0xc002b3b,
-0xafab005c, 0x1000ffc3, 0x0, 0x8f430064,
-0x8f420060, 0x1062001a, 0x274c0064, 0x8f510064,
-0x8fab005c, 0xafac004c, 0x26220001, 0x304200ff,
-0xafa20054, 0x24020004, 0x1562000e, 0x111140,
-0x111180, 0x24420cc0, 0x2e21021, 0xafa20044,
-0x9442002a, 0x8fac0044, 0x8fab0064, 0x4b102b,
-0x10400024, 0x25950020, 0x240c0001, 0x10000021,
-0xa3ac0087, 0x24424cc0, 0x1000001e, 0x2e2a821,
-0x8f420044, 0x8fab0064, 0x3c040001, 0x248468c4,
-0xafab0014, 0xafa20010, 0x8f460064, 0x8f470060,
-0x3c050007, 0xc002b3b, 0x34a54800, 0x3c020008,
-0x2c21024, 0x1440ff61, 0x0, 0x8f420370,
-0x240c0001, 0xafac005c, 0x24420001, 0xaf420370,
-0x1000ff90, 0x8f420370, 0x27a30036, 0x131040,
-0x621821, 0x94620000, 0x441021, 0x1000001f,
-0xa4620000, 0xaebe0018, 0x93a20087, 0x10400084,
-0x9821, 0x8fab0044, 0x8fa40064, 0x8fa3008c,
-0x25620020, 0xafa20028, 0x25620008, 0xafa20030,
-0x25620010, 0xafab002c, 0xafa20034, 0x9562002a,
-0xa7a20038, 0x95620018, 0xa7a2003a, 0x9562001a,
-0xa7a2003c, 0x9562001c, 0xa7a2003e, 0x94620018,
-0x24630002, 0x822023, 0x1880ffdf, 0x26730001,
-0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc,
-0x262102a, 0x14400030, 0x24030001, 0x8f83012c,
-0x10600028, 0x0, 0x8f820124, 0x431023,
-0x22143, 0x58800001, 0x24840040, 0x8f820128,
-0x431023, 0x21943, 0x58600001, 0x24630040,
-0x64102a, 0x54400001, 0x602021, 0xaf4400fc,
-0x8f4200fc, 0x262102a, 0x10400016, 0x24030001,
-0x1000001a, 0x306200ff, 0x8fac008c, 0x101040,
-0x4c1021, 0x94470018, 0x101080, 0x4c1021,
-0xafbe0010, 0x8c420008, 0x3c040001, 0x248468dc,
-0x3c050007, 0x8c430004, 0x8c420000, 0x34a55500,
-0x2003021, 0xc002b3b, 0xafa30014, 0x10000039,
-0x0, 0x8f420334, 0x1821, 0x24420001,
-0xaf420334, 0x8f420334, 0x306200ff, 0x1040ff06,
-0x8021, 0x8f430008, 0x2402fbff, 0x1260002d,
-0x625024, 0x3c0b4000, 0x22b4025, 0x8fb1008c,
-0x2669ffff, 0x2209021, 0x8e420008, 0x96270018,
-0x8c440000, 0x8c450004, 0x56090004, 0x240b0001,
-0x240c0002, 0x10000002, 0xafac0010, 0xafab0010,
-0x16000004, 0xafa80014, 0x8f420008, 0x10000002,
-0xafa20018, 0xafaa0018, 0x8f42010c, 0x3c03021,
-0xafa80098, 0xafa9009c, 0x40f809, 0xafaa00a0,
-0x8fa80098, 0x8fa9009c, 0x8faa00a0, 0x1040ffc2,
-0x3c02001f, 0x96230018, 0x3442ffff, 0x3c3f021,
-0x5e102b, 0x10400003, 0x26310002, 0x8f420148,
-0x3c2f023, 0x26100001, 0x213102b, 0x1440ffda,
-0x26520004, 0x8fb00064, 0x1000001a, 0x0,
-0x96a3000a, 0x8fb00064, 0x70102b, 0x54400001,
-0x608021, 0x8ea40000, 0x8ea50004, 0x8fab005c,
-0x240c0002, 0xafac0010, 0x934305c4, 0xb1700,
-0x10600003, 0x2223025, 0x3c020800, 0xc23025,
-0xafa60014, 0x8f420008, 0xafa20018, 0x8f42010c,
-0x3c03021, 0x40f809, 0x2003821, 0x1040fecb,
-0x3c050007, 0x97ac0076, 0x11800007, 0x96a3000e,
-0x934205c4, 0x14400004, 0x0, 0x97ab007e,
-0x6c1825, 0xa6ab0016, 0x8fac006c, 0x3c02ffff,
-0x1821024, 0x10400003, 0xc1402, 0x34630400,
-0xa6a20014, 0xa6b0000a, 0x8fab0064, 0x560b0006,
-0x3d0f021, 0x34620004, 0xafa00064, 0xa6a2000e,
-0x1000000d, 0xa34005c4, 0x8fac0064, 0x3c02001f,
-0x3442ffff, 0x5e102b, 0x1906023, 0xafac0064,
-0xa6a3000e, 0x240b0001, 0x10400003, 0xa34b05c4,
-0x8f420148, 0x3c2f023, 0x8fab0054, 0x8fac004c,
-0xad8b0000, 0x8fac0064, 0x1580feba, 0x0,
-0x8fab0064, 0x1160001b, 0x0, 0x934205c4,
-0x10400006, 0x0, 0xaf5e00c4, 0xaf4b00c0,
-0x8fac006c, 0x1000000e, 0xaf4c00c8, 0x97ab0076,
-0x1160000b, 0x34038100, 0x8fa20020, 0x8c46000c,
-0xa443000c, 0x97ac007e, 0x8c440004, 0x8c450008,
-0xa44c000e, 0xac440000, 0xac450004, 0xac460008,
-0x8f42034c, 0x24420001, 0xaf42034c, 0x10000010,
-0x8f42034c, 0x8fab006c, 0x3164ffff, 0x2484fffc,
-0x801821, 0x8f440250, 0x8f450254, 0x8f460118,
-0x1021, 0xa32821, 0xa3382b, 0x822021,
-0x872021, 0xaf440250, 0xc0f809, 0xaf450254,
-0x8fbf00c0, 0x8fbe00bc, 0x8fb500b8, 0x8fb300b4,
-0x8fb200b0, 0x8fb100ac, 0x8fb000a8, 0x3e00008,
-0x27bd00c8, 0x3e00008, 0x0, 0x27bdffd8,
-0xafbf0024, 0xafb00020, 0x8f43004c, 0x8f420048,
-0x10620034, 0x0, 0x8f430048, 0x8f42004c,
-0x622023, 0x4820001, 0x24840200, 0x8f430054,
-0x8f42004c, 0x43102b, 0x14400004, 0x24020200,
-0x8f43004c, 0x10000005, 0x431023, 0x8f420054,
-0x8f43004c, 0x431023, 0x2442ffff, 0x405021,
-0x8a102a, 0x54400001, 0x805021, 0x8f49004c,
-0x8f48004c, 0x8f440188, 0x8f45018c, 0x8f46004c,
-0x24071000, 0xafa70010, 0x84140, 0x1001821,
-0x12a4821, 0x313001ff, 0xafb00014, 0x8f470014,
-0x1021, 0x63140, 0xafa70018, 0xa32821,
-0xa3382b, 0x822021, 0x872021, 0x3402ecc0,
-0xc23021, 0x8f420108, 0x2e63021, 0x40f809,
-0xa3940, 0x54400001, 0xaf50004c, 0x8f43004c,
-0x8f420048, 0x14620018, 0x0, 0x8f420000,
-0x10400007, 0x0, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x2403fdff, 0x431024, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x10000002,
-0xaf80004c, 0xaf800048, 0x8fbf0024, 0x8fb00020,
-0x3e00008, 0x27bd0028, 0x3e00008, 0x0,
-0x27bdffd8, 0xafbf0024, 0xafb00020, 0x8f43005c,
-0x8f420058, 0x10620049, 0x0, 0x8f430058,
-0x8f42005c, 0x622023, 0x4820001, 0x24840100,
-0x8f430064, 0x8f42005c, 0x43102b, 0x14400004,
-0x24020100, 0x8f43005c, 0x10000005, 0x431023,
-0x8f420064, 0x8f43005c, 0x431023, 0x2442ffff,
-0x403821, 0x87102a, 0x54400001, 0x803821,
-0x8f42005c, 0x471021, 0x305000ff, 0x32c21000,
-0x10400015, 0x24082000, 0x8f49005c, 0x8f440190,
-0x8f450194, 0x8f46005c, 0x73980, 0xafa80010,
-0xafb00014, 0x8f480014, 0x94980, 0x1201821,
-0x1021, 0xa32821, 0xa3482b, 0x822021,
-0x892021, 0x63180, 0xafa80018, 0x8f420108,
-0x10000014, 0x24c60cc0, 0x8f49005c, 0x8f440190,
-0x8f450194, 0x8f46005c, 0x73940, 0xafa80010,
-0xafb00014, 0x8f480014, 0x94940, 0x1201821,
-0x1021, 0xa32821, 0xa3482b, 0x822021,
-0x892021, 0x63140, 0xafa80018, 0x8f420108,
-0x24c64cc0, 0x40f809, 0x2e63021, 0x54400001,
-0xaf50005c, 0x8f43005c, 0x8f420058, 0x14620018,
-0x0, 0x8f420000, 0x10400007, 0x0,
-0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
-0x10000005, 0x0, 0xaf800048, 0x8f820048,
-0x1040fffd, 0x0, 0x8f820060, 0x2403feff,
-0x431024, 0xaf820060, 0x8f420000, 0x10400003,
-0x0, 0x10000002, 0xaf80004c, 0xaf800048,
-0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028,
-0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
-0xafb00020, 0x8f43006c, 0x8f420068, 0x10620033,
-0x0, 0x8f430068, 0x8f42006c, 0x622023,
-0x4820001, 0x24840400, 0x8f430074, 0x8f42006c,
-0x43102b, 0x14400004, 0x24020400, 0x8f43006c,
-0x10000005, 0x431023, 0x8f420074, 0x8f43006c,
-0x431023, 0x2442ffff, 0x405021, 0x8a102a,
-0x54400001, 0x805021, 0x8f49006c, 0x8f48006c,
-0x8f440198, 0x8f45019c, 0x8f46006c, 0x24074000,
-0xafa70010, 0x84140, 0x1001821, 0x12a4821,
-0x313003ff, 0xafb00014, 0x8f470014, 0x1021,
-0x63140, 0x24c66cc0, 0xafa70018, 0xa32821,
-0xa3382b, 0x822021, 0x872021, 0x8f420108,
-0x2e63021, 0x40f809, 0xa3940, 0x54400001,
-0xaf50006c, 0x8f43006c, 0x8f420068, 0x14620018,
-0x0, 0x8f420000, 0x10400007, 0x0,
-0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
-0x10000005, 0x0, 0xaf800048, 0x8f820048,
-0x1040fffd, 0x0, 0x8f820060, 0x2403f7ff,
-0x431024, 0xaf820060, 0x8f420000, 0x10400003,
-0x0, 0x10000002, 0xaf80004c, 0xaf800048,
-0x8fbf0024, 0x8fb00020, 0x3e00008, 0x27bd0028,
-0x3e00008, 0x0, 0x8f4200fc, 0x3c030001,
-0x8f4400f8, 0x346330c8, 0x24420001, 0xaf4200fc,
-0x8f850128, 0x2e31021, 0x54820004, 0x24820008,
-0x3c020001, 0x34422ec8, 0x2e21021, 0x401821,
-0xaf4300f8, 0xac600000, 0x8f4200f4, 0x14620004,
-0x3c020001, 0x24a20020, 0x1000000f, 0xaf820128,
-0x8f4300f8, 0x344230c8, 0x2e21021, 0x54620004,
-0x24620008, 0x3c020001, 0x34422ec8, 0x2e21021,
-0x401821, 0x8c620004, 0x21140, 0xa21021,
-0xaf820128, 0xac600000, 0x8ca30018, 0x30620070,
-0x1040002d, 0x30620020, 0x10400004, 0x3c020010,
-0x2c21024, 0x1040000d, 0x0, 0x30620040,
-0x10400004, 0x3c020020, 0x2c21024, 0x10400007,
-0x0, 0x30620010, 0x1040001f, 0x3c020040,
-0x2c21024, 0x1440001c, 0x0, 0x8f820040,
-0x30420001, 0x14400008, 0x2021, 0x8c030104,
-0x24020001, 0x50620005, 0x24040001, 0x8c020264,
-0x10400003, 0x801021, 0x24040001, 0x801021,
-0x10400006, 0x0, 0x8f42030c, 0x24420001,
-0xaf42030c, 0x10000008, 0x8f42030c, 0x8f820044,
-0x34420004, 0xaf820044, 0x8f420308, 0x24420001,
-0xaf420308, 0x8f420308, 0x3e00008, 0x0,
-0x3e00008, 0x0, 0x27bdff98, 0xafbf0060,
-0xafbe005c, 0xafb50058, 0xafb30054, 0xafb20050,
-0xafb1004c, 0xafb00048, 0x8f4200fc, 0x24420001,
-0xaf4200fc, 0x8f880128, 0x25020020, 0xaf820128,
-0x8d030018, 0x30620070, 0x1040002e, 0x30620020,
-0x10400004, 0x3c020010, 0x2c21024, 0x1040000d,
-0x0, 0x30620040, 0x10400004, 0x3c020020,
-0x2c21024, 0x10400007, 0x0, 0x30620010,
-0x104001a9, 0x3c020040, 0x2c21024, 0x144001a6,
-0x0, 0x8f820040, 0x30420001, 0x14400008,
-0x2021, 0x8c030104, 0x24020001, 0x50620005,
-0x24040001, 0x8c020264, 0x10400003, 0x801021,
-0x24040001, 0x801021, 0x10400006, 0x0,
-0x8f42030c, 0x24420001, 0xaf42030c, 0x10000192,
-0x8f42030c, 0x8f820044, 0x34420004, 0xaf820044,
-0x8f420308, 0x24420001, 0xaf420308, 0x1000018a,
-0x8f420308, 0x30620002, 0x1040014b, 0x3c020800,
-0x8d1e001c, 0x1e5702, 0xafaa0034, 0x950a0016,
-0x3c22024, 0xafaa0024, 0x8faa0034, 0x24020001,
-0x15420006, 0x33deffff, 0x1e1140, 0x3403ecc0,
-0x431021, 0x10000010, 0x2e2a821, 0x24020002,
-0x15420005, 0x24020003, 0x1e1140, 0x24426cc0,
-0x10000009, 0x2e2a821, 0x15420005, 0x1e1180,
-0x1e1140, 0x24424cc0, 0x10000003, 0x2e2a821,
-0x571021, 0x24550ce0, 0x96a2000e, 0x304afffc,
-0x30420400, 0x10400003, 0xafaa002c, 0x100000e1,
-0x8821, 0x10800004, 0x8821, 0x97b10026,
-0x100000dd, 0xa6b10012, 0x8eb30018, 0x966a000c,
-0xa7aa003e, 0x97a5003e, 0x2ca305dd, 0x38a28870,
-0x2c420001, 0x621825, 0x10600015, 0x2021,
-0x32c20800, 0x10400015, 0x24020800, 0x96630014,
-0x14620012, 0x3402aaaa, 0x9663000e, 0x14620007,
-0x2821, 0x96630010, 0x24020300, 0x14620004,
-0xa01021, 0x96620012, 0x2c450001, 0xa01021,
-0x54400006, 0x24040016, 0x10000004, 0x0,
-0x24020800, 0x50a20001, 0x2404000e, 0x108000b9,
-0x2649021, 0x92420000, 0x3042000f, 0x28080,
-0x32c20100, 0x10400020, 0x2501821, 0x3c020020,
-0x43102b, 0x1440000e, 0x2402021, 0x2821,
-0x94820000, 0x24840002, 0xa22821, 0x83102b,
-0x1440fffb, 0x30a2ffff, 0x51c02, 0x622821,
-0x51c02, 0x30a2ffff, 0x10000009, 0x622821,
-0x8f470148, 0x8f420110, 0x102842, 0x3c060020,
-0x40f809, 0xafa80040, 0x3045ffff, 0x8fa80040,
-0x50a00001, 0x3405ffff, 0x8faa002c, 0x354a0002,
-0x10000002, 0xafaa002c, 0x2821, 0x32c20080,
-0x10400090, 0xa6a50010, 0x26430009, 0x3c02001f,
-0x3442ffff, 0x43102b, 0x10400003, 0x0,
-0x8f420148, 0x621823, 0x90660000, 0x30c200ff,
-0x38430006, 0x2c630001, 0x38420011, 0x2c420001,
-0x621825, 0x1060007f, 0x24020800, 0x8821,
-0x97a3003e, 0x1462000f, 0x2602021, 0x96710000,
-0x96620002, 0x96630004, 0x96640006, 0x2228821,
-0x2238821, 0x2248821, 0x96620008, 0x9663000a,
-0x9664000c, 0x2228821, 0x2238821, 0x10000007,
-0x2248821, 0x94820000, 0x24840002, 0x2228821,
-0x92102b, 0x1440fffb, 0x0, 0x111c02,
-0x3222ffff, 0x628821, 0x111c02, 0x3222ffff,
-0x628821, 0x32c20200, 0x10400003, 0x26440006,
-0x1000003e, 0x8021, 0x3c05001f, 0x34a5ffff,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x30421fff, 0x10400004,
-0x2644000c, 0x96420002, 0x10000030, 0x508023,
-0x96420002, 0x26430014, 0x508023, 0x3c020020,
-0x43102b, 0x1440000a, 0xd08021, 0x9642000c,
-0x2028021, 0x9642000e, 0x96430010, 0x96440012,
-0x2028021, 0x2038021, 0x10000020, 0x2048021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x24840002, 0x2028021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x24840002, 0x2028021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x24840002, 0x2028021,
-0xa4102b, 0x10400003, 0x0, 0x8f420148,
-0x822023, 0x94820000, 0x2028021, 0x3c020100,
-0x2c21024, 0x1040000e, 0x0, 0x8faa002c,
-0x31420004, 0x1040000a, 0x0, 0x9504000e,
-0x2642021, 0xc003eec, 0x2484fffc, 0x3042ffff,
-0x2228821, 0x111c02, 0x3222ffff, 0x628821,
-0x8faa0024, 0x1518823, 0x111402, 0x2228821,
-0x2308821, 0x111402, 0x2228821, 0x3231ffff,
-0x52200001, 0x3411ffff, 0x8faa002c, 0x354a0001,
-0xafaa002c, 0xa6b10012, 0x97aa002e, 0xa6aa000e,
-0x8faa002c, 0x31420004, 0x10400002, 0x24091000,
-0x34098000, 0x8f480044, 0x8f4401a0, 0x8f4501a4,
-0xafa90010, 0x8f490044, 0x84140, 0x1001821,
-0xafa90014, 0x8f48000c, 0x2a03021, 0x24070020,
-0xafa80018, 0x8f48010c, 0x1021, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x1440000b, 0x0, 0x8f820128, 0x3c040001,
-0x24846914, 0xafbe0014, 0xafa20010, 0x8f860124,
-0x8f870120, 0x3c050007, 0xc002b3b, 0x34a59920,
-0x8f420368, 0x2442ffff, 0xaf420368, 0x8f420044,
-0x8f430088, 0x24420001, 0x431024, 0xaf420044,
-0x8faa0034, 0x8f440368, 0x24020001, 0x15420006,
-0x24020002, 0x8f42035c, 0x2442ffff, 0xaf42035c,
-0x10000049, 0x8f42035c, 0x15420006, 0x0,
-0x8f420364, 0x2442ffff, 0xaf420364, 0x10000042,
-0x8f420364, 0x8f420360, 0x2442ffff, 0xaf420360,
-0x1000003d, 0x8f420360, 0x30621000, 0x10400005,
-0x30628000, 0x8f420078, 0x24420001, 0x10000036,
-0xaf420078, 0x10400034, 0x0, 0x8f420078,
-0x24420001, 0xaf420078, 0x8c030240, 0x43102b,
-0x1440002d, 0x24070008, 0x8f440168, 0x8f45016c,
-0x8f430044, 0x8f48000c, 0x8f860120, 0x24020040,
-0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c,
-0x40f809, 0x24c6001c, 0x14400011, 0x24020001,
-0x3c010001, 0x370821, 0xa02240f2, 0x8f820124,
-0xafa20010, 0x8f820128, 0x3c040001, 0x2484688c,
-0xafa20014, 0x8f460044, 0x8f870120, 0x3c050009,
-0xc002b3b, 0x34a51300, 0x1000000b, 0x0,
-0x8f420304, 0x24420001, 0xaf420304, 0x8f420304,
-0x8f420044, 0xaf42007c, 0x3c010001, 0x370821,
-0xa02040f2, 0xaf400078, 0x8f420318, 0x24420001,
-0xaf420318, 0x8f420318, 0x8fbf0060, 0x8fbe005c,
-0x8fb50058, 0x8fb30054, 0x8fb20050, 0x8fb1004c,
-0x8fb00048, 0x3e00008, 0x27bd0068, 0x3e00008,
-0x0, 0x0, 0x0, 0x8f42013c,
-0xaf8200c0, 0x8f42013c, 0xaf8200c4, 0x8f42013c,
-0xaf8200c8, 0x8f420138, 0xaf8200d0, 0x8f420138,
-0xaf8200d4, 0x8f420138, 0x3e00008, 0xaf8200d8,
-0x27bdffe0, 0x27840208, 0x24050200, 0xafbf0018,
-0xc002bbf, 0x24060008, 0x8c020204, 0xc004012,
-0xaf820210, 0x3c020001, 0x8c426d94, 0x30420002,
-0x1040000e, 0x2021, 0x8c060248, 0x24020002,
-0x3c010001, 0xac226d98, 0xc005104, 0x24050002,
-0x2021, 0x8c060248, 0x24020001, 0x3c010001,
-0xac226d98, 0x10000011, 0x24050001, 0x8c060248,
-0x24020004, 0x3c010001, 0xac226d98, 0xc005104,
-0x24050004, 0x3c020001, 0x8c426d94, 0x30420001,
-0x10400008, 0x24020001, 0x3c010001, 0xac226d98,
-0x2021, 0x24050001, 0x3c06601b, 0xc005104,
-0x0, 0x3c040001, 0x248469d0, 0x8f420150,
-0x8f430154, 0x3c050008, 0x8f460158, 0x21640,
-0x31940, 0x34630403, 0x431025, 0x633c0,
-0x461025, 0xaf82021c, 0xafa00010, 0xafa00014,
-0x8f86021c, 0x34a50200, 0xc002b3b, 0x3821,
-0x3c010001, 0xac206d90, 0x3c010001, 0xac206da8,
-0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0,
-0x3c050008, 0x34a50300, 0xafbf0018, 0xafa00010,
-0xafa00014, 0x8f860200, 0x3c040001, 0x248469dc,
-0xc002b3b, 0x3821, 0x8f420410, 0x24420001,
-0xaf420410, 0x8f420410, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x27bdffd8, 0xafbf0020, 0xafb1001c,
-0xafb00018, 0x8f4203a4, 0x24420001, 0xaf4203a4,
-0x8f4203a4, 0x8f900220, 0x8f8200e0, 0xafa20010,
-0x8f8200e4, 0xafa20014, 0x8f8600c4, 0x8f8700c8,
-0x3c040001, 0x248469e8, 0xc002b3b, 0x2002821,
-0x3c044000, 0x2041024, 0x504000b4, 0x3c040100,
-0x8f4203bc, 0x24420001, 0xaf4203bc, 0x8f4203bc,
-0x8f8700c4, 0x8f8300c8, 0x8f420148, 0x671823,
-0x43102b, 0x10400003, 0x0, 0x8f420148,
-0x621821, 0x10600005, 0x0, 0x8f42014c,
-0x43102b, 0x1040000b, 0x0, 0x8f8200e0,
-0x8f430124, 0xaf42011c, 0xaf430114, 0x8f820220,
-0x3c0308ff, 0x3463fffb, 0x431024, 0x100000ce,
-0x441025, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x34420004, 0xaf820220, 0x8f8200e0,
-0x8f430124, 0xaf42011c, 0xaf430114, 0x8f8600c8,
-0x8f840120, 0x8f830124, 0x10000005, 0x2821,
-0x14620002, 0x24620020, 0x27624800, 0x401821,
-0x1064000c, 0x30a200ff, 0x8c620018, 0x30420003,
-0x1040fff7, 0x27624fe0, 0x8f4203d0, 0x24050001,
-0x24420001, 0xaf4203d0, 0x8f4203d0, 0x8c660008,
-0x30a200ff, 0x14400058, 0x0, 0x934205c4,
-0x14400055, 0x0, 0x8f8700c4, 0x8f8800e0,
-0x8f8400e4, 0x2402fff8, 0x1024024, 0x1041023,
-0x218c3, 0x4620001, 0x24630200, 0x10600005,
-0x24020001, 0x10620009, 0x0, 0x1000001f,
-0x0, 0x8f4203c0, 0xe03021, 0x24420001,
-0xaf4203c0, 0x10000040, 0x8f4203c0, 0x8f4203c4,
-0x24420001, 0xaf4203c4, 0x8c860000, 0x8f420148,
-0x8f4303c4, 0xe61823, 0x43102b, 0x10400004,
-0x2c62233f, 0x8f420148, 0x621821, 0x2c62233f,
-0x14400031, 0x0, 0x8f42020c, 0x24420001,
-0xaf42020c, 0x8f42020c, 0xe03021, 0x24820008,
-0xaf8200e4, 0x10000028, 0xaf8200e8, 0x8f4203c8,
-0x24420001, 0xaf4203c8, 0x8f4203c8, 0x8c850000,
-0x8f420148, 0xa71823, 0x43102b, 0x10400003,
-0x0, 0x8f420148, 0x621821, 0x8f42014c,
-0x43102b, 0x5440000a, 0xa03021, 0x8f42020c,
-0x24420001, 0xaf42020c, 0x8f42020c, 0x24820008,
-0xaf8200e4, 0x8f8400e4, 0x1488ffec, 0xaf8400e8,
-0x1488000d, 0x27623000, 0x14820002, 0x2482fff8,
-0x27623ff8, 0x94430006, 0x3c02001f, 0x3442ffff,
-0xc33021, 0x46102b, 0x10400003, 0x0,
-0x8f420148, 0xc23023, 0xaf8600c8, 0x8f8300c4,
-0x8f420148, 0xc31823, 0x43102b, 0x10400003,
-0x0, 0x8f420148, 0x621821, 0x10600005,
-0x0, 0x8f42014c, 0x43102b, 0x50400008,
-0x3c02fdff, 0x8f820220, 0x3c0308ff, 0x3463fffb,
-0x431024, 0x3c034000, 0x1000003f, 0x431025,
-0x8f4303cc, 0x3442ffff, 0x282a024, 0x24630001,
-0xaf4303cc, 0x10000039, 0x8f4203cc, 0x2041024,
-0x1040000e, 0x3c110200, 0x8f4203a8, 0x24420001,
-0xaf4203a8, 0x8f4203a8, 0x8f820220, 0x3c0308ff,
-0x3463ffff, 0x431024, 0x441025, 0xc003daf,
-0xaf820220, 0x10000029, 0x0, 0x2111024,
-0x50400008, 0x3c110400, 0x8f4203ac, 0x24420001,
-0xaf4203ac, 0xc003daf, 0x8f4203ac, 0x10000019,
-0x0, 0x2111024, 0x1040001c, 0x0,
-0x8f830224, 0x24021402, 0x14620009, 0x3c050008,
-0x3c040001, 0x248469f4, 0xafa00010, 0xafa00014,
-0x8f860224, 0x34a50500, 0xc002b3b, 0x3821,
-0x8f4203b0, 0x24420001, 0xaf4203b0, 0x8f4203b0,
-0x8f820220, 0x2002021, 0x34420002, 0xc004e9c,
-0xaf820220, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x511025, 0xaf820220, 0x8fbf0020,
-0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0028,
-0x3e00008, 0x0, 0x3c020001, 0x8c426da8,
-0x27bdffb0, 0xafbf0048, 0xafbe0044, 0xafb50040,
-0xafb3003c, 0xafb20038, 0xafb10034, 0x1040000f,
-0xafb00030, 0x3c040001, 0x24846a00, 0x3c050008,
-0xafa00010, 0xafa00014, 0x8f860220, 0x34a50600,
-0x24020001, 0x3c010001, 0xac206da8, 0x3c010001,
-0xac226d9c, 0xc002b3b, 0x3821, 0x3c037fff,
-0x8c020268, 0x3463ffff, 0x3c04fdff, 0x431024,
-0xac020268, 0x8f420004, 0x3484ffff, 0x30420002,
-0x10400092, 0x284a024, 0x3c040600, 0x34842000,
-0x8f420004, 0x2821, 0x2403fffd, 0x431024,
-0xaf420004, 0xafa40020, 0x8f5e0018, 0x27aa0020,
-0x240200ff, 0x13c20002, 0xafaa002c, 0x27c50001,
-0x8c020228, 0xa09021, 0x1642000e, 0x1e38c0,
-0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x24846998, 0x3c050009,
-0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006d,
-0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024,
-0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054,
-0x247003e8, 0x2021023, 0x2c4203e9, 0x1040001b,
-0x9821, 0xe08821, 0x263504c0, 0x8f440178,
-0x8f45017c, 0x2201821, 0x240a0004, 0xafaa0010,
-0xafb20014, 0x8f48000c, 0x1021, 0x2f53021,
-0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
-0xa3482b, 0x822021, 0x100f809, 0x892021,
-0x54400006, 0x24130001, 0x8f820054, 0x2021023,
-0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff,
-0x54400017, 0xaf520018, 0x8f420378, 0x24420001,
-0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x248469a4,
-0x3c050009, 0xafa20014, 0x8d460000, 0x10000035,
-0x34a50600, 0x8f420308, 0x24130001, 0x24420001,
-0xaf420308, 0x8f420308, 0x1000001e, 0x326200ff,
-0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
-0x2c4203e9, 0x10400016, 0x9821, 0x3c150020,
-0x24110010, 0x8f42000c, 0x8f440160, 0x8f450164,
-0x8f860120, 0xafb10010, 0xafb20014, 0x551025,
-0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
-0x24c6001c, 0x1440ffe3, 0x0, 0x8f820054,
-0x2021023, 0x2c4203e9, 0x1440ffee, 0x0,
-0x326200ff, 0x14400011, 0x0, 0x8f420378,
-0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
-0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x248469ac, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202ec,
-0x24420001, 0xaf4202ec, 0x8f4202ec, 0x8fbf0048,
-0x8fbe0044, 0x8fb50040, 0x8fb3003c, 0x8fb20038,
-0x8fb10034, 0x8fb00030, 0x3e00008, 0x27bd0050,
-0x3c020001, 0x8c426da8, 0x27bdffe0, 0x1440000d,
-0xafbf0018, 0x3c040001, 0x24846a0c, 0x3c050008,
-0xafa00010, 0xafa00014, 0x8f860220, 0x34a50700,
-0x24020001, 0x3c010001, 0xac226da8, 0xc002b3b,
-0x3821, 0x3c020004, 0x2c21024, 0x10400007,
-0x0, 0x8f820220, 0x3c0308ff, 0x3463ffff,
-0x431024, 0x34420008, 0xaf820220, 0x3c050001,
-0x8ca56d98, 0x24020001, 0x14a20007, 0x2021,
-0xc00529b, 0x24050001, 0xac02026c, 0x8c03026c,
-0x10000006, 0x3c020007, 0xc00529b, 0x2021,
-0xac020268, 0x8c030268, 0x3c020007, 0x621824,
-0x3c020002, 0x5062000d, 0x3c0205f5, 0x43102b,
-0x14400006, 0x3c020004, 0x3c020001, 0x10620009,
-0x3c020098, 0x1000000b, 0x0, 0x14620009,
-0x3c023b9a, 0x10000004, 0x3442ca00, 0x10000002,
-0x3442e100, 0x34429680, 0xaf4201fc, 0x8f4201fc,
-0xaee20064, 0x8fbf0018, 0x3e00008, 0x27bd0020,
-0x0, 0x0, 0x0, 0x86102b,
-0x50400001, 0x872023, 0xc41023, 0x24843,
-0x125102b, 0x1040001b, 0x91040, 0x824021,
-0x88102b, 0x10400007, 0x1821, 0x94820000,
-0x24840002, 0x621821, 0x88102b, 0x1440fffb,
-0x0, 0x602021, 0xc73023, 0xa91023,
-0x21040, 0xc22821, 0xc5102b, 0x10400007,
-0x1821, 0x94c20000, 0x24c60002, 0x621821,
-0xc5102b, 0x1440fffb, 0x0, 0x1000000d,
-0x832021, 0x51040, 0x822821, 0x85102b,
-0x10400007, 0x1821, 0x94820000, 0x24840002,
-0x621821, 0x85102b, 0x1440fffb, 0x0,
-0x602021, 0x41c02, 0x3082ffff, 0x622021,
-0x41c02, 0x3082ffff, 0x622021, 0x3e00008,
-0x3082ffff, 0x3e00008, 0x0, 0x802821,
-0x30a20001, 0x1040002b, 0x3c03001f, 0x3463ffff,
-0x24a20004, 0x62102b, 0x54400007, 0x65102b,
-0x90a20001, 0x90a40003, 0x90a30000, 0x90a50002,
-0x1000002a, 0x441021, 0x10400003, 0x0,
-0x8f420148, 0xa22823, 0x90a40000, 0x24a50001,
-0x65102b, 0x10400003, 0x0, 0x8f420148,
-0xa22823, 0x90a20000, 0x24a50001, 0x21200,
-0x822021, 0x65102b, 0x10400003, 0x0,
-0x8f420148, 0xa22823, 0x90a20000, 0x24a50001,
-0x822021, 0x65102b, 0x10400003, 0x0,
-0x8f420148, 0xa22823, 0x90a20000, 0x1000002d,
-0x21200, 0x3463ffff, 0x24a20004, 0x62102b,
-0x5440000a, 0x65102b, 0x90a20000, 0x90a40002,
-0x90a30001, 0x90a50003, 0x441021, 0x21200,
-0x651821, 0x10000020, 0x432021, 0x10400003,
-0x0, 0x8f420148, 0xa22823, 0x90a20000,
-0x24a50001, 0x22200, 0x65102b, 0x10400003,
-0x0, 0x8f420148, 0xa22823, 0x90a20000,
-0x24a50001, 0x822021, 0x65102b, 0x10400003,
-0x0, 0x8f420148, 0xa22823, 0x90a20000,
-0x24a50001, 0x21200, 0x822021, 0x65102b,
-0x10400003, 0x0, 0x8f420148, 0xa22823,
-0x90a20000, 0x822021, 0x41c02, 0x3082ffff,
-0x622021, 0x41c02, 0x3082ffff, 0x622021,
-0x3e00008, 0x3082ffff, 0x0, 0x8f820220,
-0x34420002, 0xaf820220, 0x3c020002, 0x8c428ff8,
-0x30424000, 0x10400054, 0x24040001, 0x8f820200,
-0x24067fff, 0x8f830200, 0x30450002, 0x2402fffd,
-0x621824, 0xaf830200, 0xaf840204, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x8f820224, 0x1444004d, 0x42040, 0xc4102b,
-0x1040fff1, 0x0, 0x8f820200, 0x451025,
-0xaf820200, 0x8f820220, 0x34428000, 0xaf820220,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820220, 0x3c030004, 0x431024,
-0x1440000f, 0x0, 0x8f820220, 0x3c03ffff,
-0x34637fff, 0x431024, 0xaf820220, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x8f820220, 0x3c030004, 0x431024, 0x1440000d,
-0x0, 0x8f820220, 0x34428000, 0xaf820220,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820220, 0x3c030004, 0x431024,
-0x1040001b, 0x1021, 0x8f830220, 0x24020001,
-0x10000015, 0x3c04f700, 0x8f820220, 0x3c04f700,
-0x441025, 0xaf820220, 0x8f820220, 0x2403fffd,
-0x431024, 0xaf820220, 0x8f820220, 0x3c030300,
-0x431024, 0x14400003, 0x0, 0x10000008,
-0x1021, 0x8f820220, 0x34420002, 0xaf820220,
-0x8f830220, 0x24020001, 0x641825, 0xaf830220,
-0x3e00008, 0x0, 0x2021, 0x3c050100,
-0x24020001, 0xaf80021c, 0xaf820200, 0xaf820220,
-0x27625000, 0xaf8200c0, 0x27625000, 0xaf8200c4,
-0x27625000, 0xaf8200c8, 0x27625000, 0xaf8200d0,
-0x27625000, 0xaf8200d4, 0x27625000, 0xaf8200d8,
-0x27623000, 0xaf8200e0, 0x27623000, 0xaf8200e4,
-0x27623000, 0xaf8200e8, 0x27622800, 0xaf8200f0,
-0x27622800, 0xaf8200f4, 0x27622800, 0xaf8200f8,
-0x418c0, 0x24840001, 0x3631021, 0xac453004,
-0x3631021, 0xac403000, 0x28820200, 0x1440fff9,
-0x418c0, 0x2021, 0x418c0, 0x24840001,
-0x3631021, 0xac402804, 0x3631021, 0xac402800,
-0x28820100, 0x1440fff9, 0x418c0, 0xaf80023c,
-0x24030080, 0x24040100, 0xac600000, 0x24630004,
-0x64102b, 0x5440fffd, 0xac600000, 0x8f830040,
-0x3c02f000, 0x621824, 0x3c025000, 0x1062000c,
-0x43102b, 0x14400006, 0x3c026000, 0x3c024000,
-0x10620008, 0x24020800, 0x10000008, 0x0,
-0x10620004, 0x24020800, 0x10000004, 0x0,
-0x24020700, 0x3c010001, 0xac226dac, 0x3e00008,
-0x0, 0x3c020001, 0x8c426dbc, 0x27bdffd0,
-0xafbf002c, 0xafb20028, 0xafb10024, 0xafb00020,
-0x3c010001, 0x10400005, 0xac206d94, 0xc004d9e,
-0x0, 0x3c010001, 0xac206dbc, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0xc004db9, 0x0, 0x24040001, 0x2821,
-0x27a60018, 0x34028000, 0xc0045be, 0xa7a20018,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x3c060001, 0x24c66f24, 0xc00457c,
-0x24050002, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630064, 0x8f820054, 0x621023, 0x2c420065,
-0x1440fffc, 0x24040001, 0x24050003, 0x3c100001,
-0x26106f26, 0xc00457c, 0x2003021, 0x97a60018,
-0x3c070001, 0x94e76f24, 0x3c040001, 0x24846ae0,
-0xafa00014, 0x96020000, 0x3c05000d, 0x34a50100,
-0xc002b3b, 0xafa20010, 0x97a20018, 0x1040004d,
-0x24036040, 0x96020000, 0x3042fff0, 0x1443000c,
-0x24020020, 0x3c030001, 0x94636f24, 0x1462000b,
-0x24027830, 0x24020003, 0x3c010001, 0xac226d94,
-0x24020005, 0x3c010001, 0x1000003f, 0xac226f34,
-0x3c030001, 0x94636f24, 0x24027830, 0x1462000c,
-0x24030010, 0x3c020001, 0x94426f26, 0x3042fff0,
-0x14430007, 0x24020003, 0x3c010001, 0xac226d94,
-0x24020006, 0x3c010001, 0x1000002f, 0xac226f34,
-0x3c020001, 0x8c426d94, 0x3c030001, 0x94636f24,
-0x34420001, 0x3c010001, 0xac226d94, 0x24020015,
-0x1462000b, 0x0, 0x3c020001, 0x94426f26,
-0x3042fff0, 0x3843f420, 0x2c630001, 0x3842f430,
-0x2c420001, 0x621825, 0x1460001b, 0x24020003,
-0x3c030001, 0x94636f24, 0x24027810, 0x14620016,
-0x24020002, 0x3c020001, 0x94426f26, 0x3042fff0,
-0x14400011, 0x24020002, 0x1000000f, 0x24020004,
-0x3c020001, 0x8c426d94, 0x34420008, 0x3c010001,
-0xac226d94, 0x1000005e, 0x24020004, 0x3c020001,
-0x8c426d94, 0x34420004, 0x3c010001, 0x100000af,
-0xac226d94, 0x24020001, 0x3c010001, 0xac226f40,
-0x3c020001, 0x8c426d94, 0x30420002, 0x144000b2,
-0x3c09fff0, 0x24020e00, 0xaf820238, 0x8f840054,
-0x8f820054, 0x24030008, 0x3c010001, 0xac236d98,
-0x10000002, 0x248401f4, 0x8f820054, 0x821023,
-0x2c4201f5, 0x1440fffc, 0x3c0200c8, 0x344201fb,
-0xaf820238, 0x8f830054, 0x8f820054, 0x10000002,
-0x246301f4, 0x8f820054, 0x621023, 0x2c4201f5,
-0x1440fffc, 0x8021, 0x24120001, 0x24110009,
-0xc004482, 0x0, 0x3c010001, 0xac326db4,
-0xc004547, 0x0, 0x3c020001, 0x8c426db4,
-0x1451fffb, 0x3c0200c8, 0x344201f6, 0xaf820238,
-0x8f830054, 0x8f820054, 0x10000002, 0x2463000a,
-0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc,
-0x0, 0x8f820220, 0x24040001, 0x34420002,
-0xaf820220, 0x8f830200, 0x24057fff, 0x2402fffd,
-0x621824, 0xaf830200, 0xaf840204, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x8f820224, 0x14440005, 0x34028000, 0x42040,
-0xa4102b, 0x1040fff0, 0x34028000, 0x1082ffa0,
-0x26100001, 0x2e020014, 0x1440ffcd, 0x24020004,
-0x3c010001, 0xac226d98, 0x8021, 0x24120009,
-0x3c11ffff, 0x36313f7f, 0xc004482, 0x0,
-0x24020001, 0x3c010001, 0xac226db4, 0xc004547,
-0x0, 0x3c020001, 0x8c426db4, 0x1452fffb,
-0x0, 0x8f820044, 0x511024, 0x34425080,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x2463000a, 0x8f820054, 0x621023, 0x2c42000b,
-0x1440fffc, 0x0, 0x8f820044, 0x511024,
-0x3442f080, 0xaf820044, 0x8f830054, 0x8f820054,
-0x10000002, 0x2463000a, 0x8f820054, 0x621023,
-0x2c42000b, 0x1440fffc, 0x0, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0x8f820220, 0x24040001, 0x34420002, 0xaf820220,
-0x8f830200, 0x24057fff, 0x2402fffd, 0x621824,
-0xaf830200, 0xaf840204, 0x8f830054, 0x8f820054,
-0x10000002, 0x24630001, 0x8f820054, 0x621023,
-0x2c420002, 0x1440fffc, 0x0, 0x8f820224,
-0x14440005, 0x34028000, 0x42040, 0xa4102b,
-0x1040fff0, 0x34028000, 0x1082ff50, 0x26100001,
-0x2e020064, 0x1440ffb0, 0x0, 0x3c020001,
-0x8c426d94, 0x30420004, 0x14400007, 0x3c09fff0,
-0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024,
-0xaf820044, 0x3c09fff0, 0x3529bdc0, 0x3c060001,
-0x8cc66d94, 0x3c040001, 0x24846ae0, 0x24020001,
-0x3c010001, 0xac226d9c, 0x8f820054, 0x3c070001,
-0x8ce76f40, 0x3c030001, 0x94636f24, 0x3c080001,
-0x95086f26, 0x3c05000d, 0x34a50100, 0x3c010001,
-0xac206d98, 0x491021, 0x3c010001, 0xac226f30,
-0xafa30010, 0xc002b3b, 0xafa80014, 0x8fbf002c,
-0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
-0x27bd0030, 0x27bdffe8, 0x3c050001, 0x8ca56d98,
-0x24060004, 0x24020001, 0x14a20014, 0xafbf0010,
-0x3c020002, 0x8c428ffc, 0x30428000, 0x10400005,
-0x3c04000f, 0x3c030001, 0x8c636f40, 0x10000005,
-0x34844240, 0x3c040004, 0x3c030001, 0x8c636f40,
-0x348493e0, 0x24020005, 0x14620016, 0x0,
-0x3c04003d, 0x10000013, 0x34840900, 0x3c020002,
-0x8c428ff8, 0x30428000, 0x10400005, 0x3c04001e,
-0x3c030001, 0x8c636f40, 0x10000005, 0x34848480,
-0x3c04000f, 0x3c030001, 0x8c636f40, 0x34844240,
-0x24020005, 0x14620003, 0x0, 0x3c04007a,
-0x34841200, 0x3c020001, 0x8c426f30, 0x8f830054,
-0x441021, 0x431023, 0x44102b, 0x1440004c,
-0x0, 0x3c020001, 0x8c426da0, 0x14400048,
-0x0, 0x3c010001, 0x10c00025, 0xac206db0,
-0x3c090001, 0x8d296d94, 0x24070001, 0x3c044000,
-0x3c080002, 0x25088ffc, 0x250afffc, 0x52842,
-0x14a00002, 0x24c6ffff, 0x24050008, 0xa91024,
-0x10400010, 0x0, 0x14a70008, 0x0,
-0x8d020000, 0x441024, 0x1040000a, 0x0,
-0x3c010001, 0x10000007, 0xac256db0, 0x8d420000,
-0x441024, 0x10400003, 0x0, 0x3c010001,
-0xac276db0, 0x3c020001, 0x8c426db0, 0x6182b,
-0x2c420001, 0x431024, 0x5440ffe5, 0x52842,
-0x8f820054, 0x3c030001, 0x8c636db0, 0x3c010001,
-0xac226f30, 0x1060003b, 0x24020005, 0x3c030001,
-0x8c636f40, 0x3c010001, 0xac256d98, 0x14620012,
-0x24020001, 0x3c020002, 0x8c428ff8, 0x3c032000,
-0x34635000, 0x431024, 0x14400006, 0x24020001,
-0x3c010001, 0xac206f1c, 0x3c010001, 0xac226d98,
-0x24020001, 0x3c010001, 0xac226e24, 0x3c010001,
-0xac226da4, 0x24020001, 0x3c010001, 0xac226d9c,
-0x3c020001, 0x8c426db0, 0x1040001e, 0x0,
-0x3c020001, 0x8c426d9c, 0x10400008, 0x24020001,
-0x3c010001, 0xac206d9c, 0xaee204b8, 0x3c010001,
-0xac206e1c, 0x3c010001, 0xac226dd4, 0x8ee304b8,
-0x24020008, 0x10620005, 0x24020001, 0xc004239,
-0x0, 0x1000000b, 0x0, 0x3c030001,
-0x8c636d98, 0x10620007, 0x2402000e, 0x3c030002,
-0x8c638f90, 0x10620003, 0x0, 0xc004e9c,
-0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018,
-0x27bdffe0, 0x3c03fdff, 0x3c040001, 0x8c846d98,
-0x3c020001, 0x8c426dc0, 0x3463ffff, 0x283a024,
-0x14820006, 0xafbf0018, 0x8ee304b8, 0x3c020001,
-0x8c426dc4, 0x10620006, 0x0, 0x8ee204b8,
-0x3c010001, 0xac246dc0, 0x3c010001, 0xac226dc4,
-0x3c030001, 0x8c636d98, 0x24020002, 0x1062019c,
-0x2c620003, 0x10400005, 0x24020001, 0x1062000a,
-0x0, 0x10000226, 0x0, 0x24020004,
-0x106200b6, 0x24020008, 0x1062010a, 0x24020001,
-0x1000021f, 0x0, 0x8ee204b8, 0x2443ffff,
-0x2c620008, 0x1040021c, 0x31080, 0x3c010001,
-0x220821, 0x8c226af8, 0x400008, 0x0,
-0x3c030001, 0x8c636f40, 0x24020005, 0x14620010,
-0x0, 0x3c020001, 0x8c426da4, 0x10400008,
-0x24020003, 0xc004482, 0x0, 0x24020002,
-0xaee204b8, 0x3c010001, 0x10000002, 0xac206da4,
-0xaee204b8, 0x3c010001, 0x10000203, 0xac206d30,
-0xc004482, 0x0, 0x3c020001, 0x8c426da4,
-0x3c010001, 0xac206d30, 0x1440017a, 0x24020002,
-0x1000019d, 0x24020007, 0x3c030001, 0x8c636f40,
-0x24020005, 0x14620003, 0x24020001, 0x3c010001,
-0xac226dd0, 0xc0045ff, 0x0, 0x3c030001,
-0x8c636dd0, 0x10000174, 0x24020011, 0x3c050001,
-0x8ca56d98, 0x3c060002, 0x8cc68ffc, 0xc005104,
-0x2021, 0x24020005, 0x3c010001, 0xac206da4,
-0x100001e1, 0xaee204b8, 0x3c040001, 0x24846aec,
-0x3c05000f, 0x34a50100, 0x3021, 0x3821,
-0xafa00010, 0xc002b3b, 0xafa00014, 0x100001d6,
-0x0, 0x8f820220, 0x3c030004, 0x431024,
-0x14400175, 0x24020007, 0x8f830054, 0x3c020001,
-0x8c426f28, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400003, 0x24020001, 0x3c010001, 0xac226d9c,
-0x3c020002, 0x8c428ffc, 0x30425000, 0x104001c2,
-0x0, 0x8f820220, 0x30428000, 0x1040017d,
-0x0, 0x10000175, 0x0, 0x3c050001,
-0x8ca56d98, 0xc00529b, 0x2021, 0xc00551b,
-0x2021, 0x3c030002, 0x8c638ff4, 0x46101b0,
-0x24020001, 0x3c020008, 0x621024, 0x10400006,
-0x0, 0x8f820214, 0x3c03ffff, 0x431024,
-0x10000005, 0x3442251f, 0x8f820214, 0x3c03ffff,
-0x431024, 0x3442241f, 0xaf820214, 0x8f820220,
-0x3c030200, 0x34420002, 0xaf820220, 0x24020008,
-0xaee204b8, 0x8f820220, 0x283a025, 0x3c030004,
-0x431024, 0x14400016, 0x0, 0x3c020002,
-0x8c428ffc, 0x30425000, 0x1040000d, 0x0,
-0x8f820220, 0x30428000, 0x10400006, 0x0,
-0x8f820220, 0x3c03ffff, 0x34637fff, 0x10000003,
-0x431024, 0x8f820220, 0x34428000, 0xaf820220,
-0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0x3c030001, 0x8c636f40, 0x24020005, 0x1462000a,
-0x0, 0x3c020001, 0x94426f26, 0x24429fbc,
-0x2c420004, 0x10400004, 0x24040018, 0x24050002,
-0xc004ddb, 0x24060020, 0xc003e6d, 0x0,
-0x3c010001, 0x10000170, 0xac206e20, 0x8ee204b8,
-0x2443ffff, 0x2c620008, 0x1040016b, 0x31080,
-0x3c010001, 0x220821, 0x8c226b18, 0x400008,
-0x0, 0xc004547, 0x0, 0x3c030001,
-0x8c636db4, 0x100000e8, 0x24020009, 0x3c020002,
-0x8c428ff8, 0x30424000, 0x10400004, 0x0,
-0x8f820044, 0x10000006, 0x3442f080, 0x8f820044,
-0x3c03ffff, 0x34633f7f, 0x431024, 0x3442a080,
-0xaf820044, 0x8f830054, 0x100000ea, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400147, 0x24020005,
-0x100000d8, 0x0, 0x8f820220, 0x3c03f700,
-0x431025, 0xaf820220, 0xaf800204, 0x3c010002,
-0x100000d6, 0xac208fe0, 0x8f830054, 0x3c020001,
-0x8c426f28, 0x2463fff6, 0x431023, 0x2c42000a,
-0x14400135, 0x24020007, 0x100000d7, 0x0,
-0xc003f50, 0x0, 0x1040012d, 0x24020001,
-0x8f820214, 0x3c03ffff, 0x3c040001, 0x8c846f1c,
-0x431024, 0x3442251f, 0xaf820214, 0x24020008,
-0x10800005, 0xaee204b8, 0x3c020001, 0x8c426e44,
-0x10400064, 0x24020001, 0x8f820220, 0x3c030008,
-0x431024, 0x1040006a, 0x3c020200, 0x10000078,
-0x0, 0x8ee204b8, 0x2443ffff, 0x2c620007,
-0x10400115, 0x31080, 0x3c010001, 0x220821,
-0x8c226b38, 0x400008, 0x0, 0xc003daf,
-0x0, 0x3c010001, 0xac206d9c, 0xaf800204,
-0x3c010002, 0xc004482, 0xac208fe0, 0x24020001,
-0x3c010001, 0xac226db4, 0x24020002, 0x10000102,
-0xaee204b8, 0xc004547, 0x0, 0x3c030001,
-0x8c636db4, 0x10000084, 0x24020009, 0x3c020002,
-0x8c428ff8, 0x30424000, 0x10400003, 0x3c0200c8,
-0x10000002, 0x344201f6, 0x344201fe, 0xaf820238,
-0x8f830054, 0x1000008b, 0x24020004, 0x8f830054,
-0x3c020001, 0x8c426f28, 0x2463d8f0, 0x431023,
-0x2c422710, 0x144000e8, 0x24020005, 0x10000079,
-0x0, 0x8f820220, 0x3c03f700, 0x431025,
-0xaf820220, 0xaf800204, 0x3c010002, 0x10000077,
-0xac208fe0, 0x8f830054, 0x3c020001, 0x8c426f28,
-0x2463fff6, 0x431023, 0x2c42000a, 0x144000d6,
-0x24020007, 0x10000078, 0x0, 0xc003f50,
-0x0, 0x104000ce, 0x24020001, 0x8f820214,
-0x3c03ffff, 0x3c040001, 0x8c846f1c, 0x431024,
-0x3442251f, 0xaf820214, 0x24020008, 0x1080000f,
-0xaee204b8, 0x3c020001, 0x8c426e44, 0x1440000b,
-0x0, 0x8f820220, 0x34420002, 0xaf820220,
-0x24020001, 0x3c010002, 0xac228f90, 0xc004e9c,
-0x8f840220, 0x10000016, 0x0, 0x8f820220,
-0x3c030008, 0x431024, 0x14400011, 0x3c020200,
-0x282a025, 0x2402000e, 0x3c010002, 0xac228f90,
-0xc00551b, 0x2021, 0x8f820220, 0x34420002,
-0xc003e6d, 0xaf820220, 0x3c050001, 0x8ca56d98,
-0xc00529b, 0x2021, 0x100000a3, 0x0,
-0x3c020001, 0x8c426e44, 0x1040009f, 0x0,
-0x3c020001, 0x8c426e40, 0x2442ffff, 0x3c010001,
-0xac226e40, 0x14400098, 0x24020002, 0x3c010001,
-0xac206e44, 0x3c010001, 0x10000093, 0xac226e40,
-0x8ee204b8, 0x2443ffff, 0x2c620007, 0x1040008e,
-0x31080, 0x3c010001, 0x220821, 0x8c226b58,
-0x400008, 0x0, 0x3c020001, 0x8c426da4,
-0x10400018, 0x24020005, 0xc004482, 0x0,
-0x24020002, 0xaee204b8, 0x3c010001, 0x1000007e,
-0xac206da4, 0xc004963, 0x0, 0x3c030001,
-0x8c636dd4, 0x24020006, 0x14620077, 0x24020003,
-0x10000075, 0xaee204b8, 0x3c050001, 0x8ca56d98,
-0x3c060002, 0x8cc68ff8, 0xc005104, 0x2021,
-0x24020005, 0x1000006c, 0xaee204b8, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0x8f830054,
-0x24020006, 0xaee204b8, 0x3c010001, 0x10000062,
-0xac236f28, 0x8f820220, 0x3c030004, 0x431024,
-0x10400003, 0x24020007, 0x1000005b, 0xaee204b8,
-0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400003, 0x24020001,
-0x3c010001, 0xac226d9c, 0x3c020002, 0x8c428ff8,
-0x30425000, 0x1040004c, 0x0, 0x8f820220,
-0x30428000, 0x10400007, 0x0, 0x8f820220,
-0x3c03ffff, 0x34637fff, 0x431024, 0x10000042,
-0xaf820220, 0x8f820220, 0x34428000, 0x1000003e,
-0xaf820220, 0x3c050001, 0x8ca56d98, 0xc00529b,
-0x2021, 0xc00551b, 0x2021, 0x3c020002,
-0x8c428ff0, 0x4410032, 0x24020001, 0x8f820214,
-0x3c03ffff, 0x431024, 0x3442251f, 0xaf820214,
-0x24020008, 0xaee204b8, 0x8f820220, 0x34420002,
-0xaf820220, 0x8f820220, 0x3c030004, 0x431024,
-0x14400016, 0x0, 0x3c020002, 0x8c428ff8,
-0x30425000, 0x1040000d, 0x0, 0x8f820220,
-0x30428000, 0x10400006, 0x0, 0x8f820220,
-0x3c03ffff, 0x34637fff, 0x10000003, 0x431024,
-0x8f820220, 0x34428000, 0xaf820220, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0x3c020001,
-0x94426f26, 0x24429fbc, 0x2c420004, 0x10400004,
-0x24040018, 0x24050002, 0xc004ddb, 0x24060020,
-0xc003e6d, 0x0, 0x10000003, 0x0,
-0x3c010001, 0xac226d9c, 0x8fbf0018, 0x3e00008,
-0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220,
-0x34420004, 0xaf820220, 0x8f820200, 0x3c050001,
-0x8ca56d98, 0x34420004, 0xaf820200, 0x24020002,
-0x10a2004b, 0x2ca20003, 0x10400005, 0x24020001,
-0x10a2000a, 0x0, 0x100000b1, 0x0,
-0x24020004, 0x10a20072, 0x24020008, 0x10a20085,
-0x3c02f0ff, 0x100000aa, 0x0, 0x8f830050,
-0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c846f40,
-0x621824, 0x3c020700, 0x621825, 0x24020e00,
-0x2484fffb, 0x2c840002, 0xaf830050, 0xaf850200,
-0xaf850220, 0x14800006, 0xaf820238, 0x8f820044,
-0x3c03ffff, 0x34633f7f, 0x431024, 0xaf820044,
-0x3c030001, 0x8c636f40, 0x24020005, 0x14620004,
-0x0, 0x8f820044, 0x34425000, 0xaf820044,
-0x3c020001, 0x8c426d88, 0x3c030001, 0x8c636f40,
-0x34420022, 0x2463fffc, 0x2c630002, 0x1460000c,
-0xaf820200, 0x3c020001, 0x8c426dac, 0x3c030001,
-0x8c636d90, 0x3c040001, 0x8c846d8c, 0x34428000,
-0x621825, 0x641825, 0x1000000a, 0x34620002,
-0x3c020001, 0x8c426d90, 0x3c030001, 0x8c636dac,
-0x3c040001, 0x8c846d8c, 0x431025, 0x441025,
-0x34420002, 0xaf820220, 0x1000002f, 0x24020001,
-0x24020e01, 0xaf820238, 0x8f830050, 0x3c02f0ff,
-0x3442ffff, 0x3c040001, 0x8c846f1c, 0x621824,
-0x3c020d00, 0x621825, 0x24020001, 0xaf830050,
-0xaf820200, 0xaf820220, 0x10800005, 0x3c033f00,
-0x3c020001, 0x8c426d80, 0x10000004, 0x34630070,
-0x3c020001, 0x8c426d80, 0x34630072, 0x431025,
-0xaf820200, 0x3c030001, 0x8c636d84, 0x3c02f700,
-0x621825, 0x3c020001, 0x8c426d90, 0x3c040001,
-0x8c846dac, 0x3c050001, 0x8ca56f40, 0x431025,
-0x441025, 0xaf820220, 0x24020005, 0x14a20006,
-0x24020001, 0x8f820044, 0x2403afff, 0x431024,
-0xaf820044, 0x24020001, 0x1000003d, 0xaf820238,
-0x8f830050, 0x3c02f0ff, 0x3442ffff, 0x3c040001,
-0x8c846f1c, 0x621824, 0x3c020a00, 0x621825,
-0x24020001, 0xaf830050, 0xaf820200, 0x1080001e,
-0xaf820220, 0x3c020001, 0x8c426e44, 0x1440001a,
-0x3c033f00, 0x3c020001, 0x8c426d80, 0x1000001a,
-0x346300e0, 0x8f830050, 0x3c040001, 0x8c846f1c,
-0x3442ffff, 0x621824, 0x1080000f, 0xaf830050,
-0x3c020001, 0x8c426e44, 0x1440000b, 0x3c043f00,
-0x3c030001, 0x8c636d80, 0x348400e0, 0x24020001,
-0xaf820200, 0xaf820220, 0x641825, 0xaf830200,
-0x10000008, 0x3c05f700, 0x3c020001, 0x8c426d80,
-0x3c033f00, 0x346300e2, 0x431025, 0xaf820200,
-0x3c05f700, 0x34a58000, 0x3c030001, 0x8c636d84,
-0x3c020001, 0x8c426d90, 0x3c040001, 0x8c846dac,
-0x651825, 0x431025, 0x441025, 0xaf820220,
-0x3e00008, 0x0, 0x3c030001, 0x8c636db4,
-0x3c020001, 0x8c426db8, 0x10620003, 0x24020002,
-0x3c010001, 0xac236db8, 0x1062001d, 0x2c620003,
-0x10400025, 0x24020001, 0x14620023, 0x24020004,
-0x3c030001, 0x8c636d98, 0x10620006, 0x24020008,
-0x1462000c, 0x3c0200c8, 0x344201fb, 0x10000009,
-0xaf820238, 0x24020e01, 0xaf820238, 0x8f820044,
-0x3c03ffff, 0x34633f7f, 0x431024, 0x34420080,
-0xaf820044, 0x8f830054, 0x24020002, 0x3c010001,
-0xac226db4, 0x3c010001, 0x1000000b, 0xac236f2c,
-0x8f830054, 0x3c020001, 0x8c426f2c, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400003, 0x24020009,
-0x3c010001, 0xac226db4, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x27bdffd8,
-0xafb20018, 0x809021, 0xafb3001c, 0xa09821,
-0xafb10014, 0xc08821, 0xafb00010, 0x8021,
-0xafbf0020, 0xa6200000, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x2501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x2501024, 0x24100010, 0x2701024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x2701024, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x0, 0x8fbf0020, 0x8fb3001c,
-0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008,
-0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821,
-0xafb20018, 0xa09021, 0xafb3001c, 0xc09821,
-0xafb00010, 0x8021, 0xafbf0020, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x2301024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x2301024, 0x24100010, 0x2501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2501024, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96620000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8fbf0020,
-0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
-0x3e00008, 0x27bd0028, 0x3c040001, 0x8c846dd0,
-0x3c020001, 0x8c426e18, 0x27bdffd8, 0xafbf0020,
-0xafb1001c, 0x10820003, 0xafb00018, 0x3c010001,
-0xac246e18, 0x3c030001, 0x8c636f40, 0x24020005,
-0x14620005, 0x2483ffff, 0xc004963, 0x0,
-0x1000034c, 0x0, 0x2c620013, 0x10400349,
-0x31080, 0x3c010001, 0x220821, 0x8c226b80,
-0x400008, 0x0, 0xc004db9, 0x8021,
-0x34028000, 0xa7a20010, 0x27b10010, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x1000030e, 0x24020002, 0x27b10010, 0xa7a00010,
-0x8021, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x0, 0x97a20010, 0x30428000,
-0x144002dc, 0x24020003, 0x100002d8, 0x0,
-0x24021200, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0xc004d78, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x34108000, 0x96220000, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fff8, 0x0, 0xc004db9,
-0x0, 0x8f830054, 0x10000296, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c426f3c, 0x2463ff9c,
-0x431023, 0x2c420064, 0x1440029e, 0x24020002,
-0x3c030001, 0x8c636f40, 0x10620297, 0x2c620003,
-0x14400296, 0x24020011, 0x24020003, 0x10620005,
-0x24020004, 0x10620291, 0x2402000f, 0x1000028f,
-0x24020011, 0x1000028d, 0x24020005, 0x24020014,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020012,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020012, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8f830054,
-0x10000248, 0x24020006, 0x8f830054, 0x3c020001,
-0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064,
-0x14400250, 0x24020007, 0x1000024c, 0x0,
-0x24020006, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020013, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020013,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x10000207, 0x24020008, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440020f, 0x24020009, 0x1000020b,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x10000193, 0x2402000a, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440019b, 0x2402000b, 0x10000197,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020017,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020017,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x1000011f, 0x2402000c, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x14400127, 0x24020012, 0x10000123,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020014,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020014,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x100000ab, 0x24020013, 0x8f830054,
-0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
-0x2c420064, 0x144000b3, 0x2402000d, 0x100000af,
-0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x8f830054, 0x10000037, 0x2402000e, 0x24020840,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020013,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020013, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8f830054,
-0x24020010, 0x3c010001, 0xac226dd0, 0x3c010001,
-0x1000000c, 0xac236f3c, 0x8f830054, 0x3c020001,
-0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064,
-0x14400004, 0x0, 0x24020011, 0x3c010001,
-0xac226dd0, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x3c030001, 0x8c636d98,
-0x27bdffc8, 0x24020002, 0xafbf0034, 0xafb20030,
-0xafb1002c, 0x14620004, 0xafb00028, 0x3c120002,
-0x10000003, 0x8e528ff8, 0x3c120002, 0x8e528ffc,
-0x3c030001, 0x8c636dd4, 0x3c020001, 0x8c426e1c,
-0x50620004, 0x2463ffff, 0x3c010001, 0xac236e1c,
-0x2463ffff, 0x2c620006, 0x10400377, 0x31080,
-0x3c010001, 0x220821, 0x8c226bd8, 0x400008,
-0x0, 0x2021, 0x2821, 0xc004ddb,
-0x34068000, 0x24040010, 0x24050002, 0x24060002,
-0x24020002, 0xc004ddb, 0xa7a20018, 0x24020002,
-0x3c010001, 0x10000364, 0xac226dd4, 0x27b10018,
-0xa7a00018, 0x8021, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0xc004d78, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0xc004db9,
-0x34108000, 0xc004db9, 0x0, 0xc004d58,
-0x0, 0x50400005, 0x108042, 0x96220000,
-0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004db9, 0x0, 0x97a20018,
-0x30428000, 0x14400004, 0x24020003, 0x3c010001,
-0xac226dd4, 0x24020003, 0x3c010001, 0x1000032a,
-0xac226dd4, 0x24040010, 0x24050002, 0x24060002,
-0x24020002, 0xc004ddb, 0xa7a20018, 0x3c030001,
-0x8c636e20, 0x24020001, 0x146201e1, 0x8021,
-0x27b10018, 0xa7a00018, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x32020018, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020018, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0x27b10018, 0xa7a00018,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0x24040018, 0x2821, 0xc004ddb, 0x24060404,
-0xa7a0001a, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0x32020018, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020018, 0xc004db9, 0x34108000, 0xc004db9,
-0x0, 0xc004d58, 0x0, 0x50400005,
-0x108042, 0x97a2001a, 0x501025, 0xa7a2001a,
-0x108042, 0x1600fff7, 0x0, 0xc004db9,
-0x8021, 0xa7a0001a, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x32020018, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020018, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x97a2001a, 0x501025,
-0xa7a2001a, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0xa7a0001c, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x24100010, 0xc004d78, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0x24100010,
-0x3202001e, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x3202001e,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x97a2001c, 0x501025, 0xa7a2001c, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x8021,
-0xa7a0001c, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0xc004d78, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0x24100010, 0x3202001e, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x3202001e, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x97a2001c, 0x501025,
-0xa7a2001c, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0x24020002, 0xa7a2001e,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0x24100010, 0x3202001e, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x3202001e, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x34108000, 0x97a2001e, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fff8, 0x0, 0xc004db9,
-0x8021, 0xa7a00020, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0x24100010, 0x3202001e,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x3202001e, 0xc004db9,
-0x34108000, 0xc004db9, 0x0, 0xc004d58,
-0x0, 0x50400005, 0x108042, 0x97a20020,
-0x501025, 0xa7a20020, 0x108042, 0x1600fff7,
-0x0, 0xc004db9, 0x8021, 0xa7a00020,
-0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d78, 0x2021,
-0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0x24100010, 0x3202001e, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
-0x3202001e, 0xc004db9, 0x34108000, 0xc004db9,
-0x0, 0xc004d58, 0x0, 0x50400005,
-0x108042, 0x97a20020, 0x501025, 0xa7a20020,
-0x108042, 0x1600fff7, 0x0, 0xc004db9,
-0x8021, 0xa7a00022, 0xc004d78, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0xc004d78, 0x2021, 0xc004d78, 0x24040001,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004d78, 0x24040001, 0xc004d78, 0x2021,
-0x34108000, 0x97a20022, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fff8, 0x0, 0xc004db9, 0x0,
-0x24040018, 0x24050002, 0xc004ddb, 0x24060004,
-0x3c100001, 0x8e106e24, 0x24020001, 0x1602011d,
-0x0, 0x3c020001, 0x94426f26, 0x3c010001,
-0xac206e24, 0x24429fbc, 0x2c420004, 0x1040000c,
-0x24040009, 0x24050001, 0xc004ddb, 0x24060400,
-0x24040018, 0x24050001, 0xc004ddb, 0x24060020,
-0x24040018, 0x24050001, 0xc004ddb, 0x24062000,
-0x3c024000, 0x2421024, 0x10400123, 0x3c022000,
-0x2421024, 0x10400004, 0x0, 0x3c010001,
-0x10000003, 0xac306f1c, 0x3c010001, 0xac206f1c,
-0x3c030001, 0x8c636f34, 0x24020005, 0x146200f9,
-0x0, 0x3c020001, 0x8c426f1c, 0x10400067,
-0x3c020004, 0x2421024, 0x10400011, 0xa7a00018,
-0x3c020008, 0x2421024, 0x10400002, 0x24020200,
-0xa7a20018, 0x3c020010, 0x2421024, 0x10400004,
-0x0, 0x97a20018, 0x34420100, 0xa7a20018,
-0x97a60018, 0x24040009, 0x10000004, 0x2821,
-0x24040009, 0x2821, 0x3021, 0xc004ddb,
-0x0, 0x24020001, 0xa7a2001a, 0x3c020008,
-0x2421024, 0x1040000c, 0x3c020002, 0x2421024,
-0x10400002, 0x24020101, 0xa7a2001a, 0x3c020001,
-0x2421024, 0x10400005, 0x3c020010, 0x97a2001a,
-0x34420040, 0xa7a2001a, 0x3c020010, 0x2421024,
-0x1040000e, 0x3c020002, 0x2421024, 0x10400005,
-0x3c020001, 0x97a2001a, 0x34420080, 0xa7a2001a,
-0x3c020001, 0x2421024, 0x10400005, 0x3c0300a0,
-0x97a2001a, 0x34420020, 0xa7a2001a, 0x3c0300a0,
-0x2431024, 0x54430004, 0x3c020020, 0x97a2001a,
-0x1000000c, 0x34420400, 0x2421024, 0x50400004,
-0x3c020080, 0x97a2001a, 0x10000006, 0x34420800,
-0x2421024, 0x10400004, 0x0, 0x97a2001a,
-0x34420c00, 0xa7a2001a, 0x97a6001a, 0x24040004,
-0xc004ddb, 0x2821, 0x3c020004, 0x2421024,
-0x10400004, 0xa7a0001c, 0x32425000, 0x14400004,
-0x0, 0x32424000, 0x10400005, 0x2021,
-0xc004cf9, 0x2402021, 0x10000096, 0x0,
-0x97a6001c, 0x2821, 0x34c61200, 0xc004ddb,
-0xa7a6001c, 0x1000008f, 0x0, 0x2421024,
-0x10400004, 0xa7a00018, 0x32425000, 0x14400004,
-0x0, 0x32424000, 0x10400005, 0x3c020010,
-0xc004cf9, 0x2402021, 0x10000019, 0xa7a0001a,
-0x2421024, 0x10400004, 0x0, 0x97a20018,
-0x10000004, 0xa7a20018, 0x97a20018, 0x34420100,
-0xa7a20018, 0x3c020001, 0x2421024, 0x10400004,
-0x0, 0x97a20018, 0x10000004, 0xa7a20018,
-0x97a20018, 0x34422000, 0xa7a20018, 0x97a60018,
-0x2021, 0xc004ddb, 0x2821, 0xa7a0001a,
-0x8021, 0xc004d78, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
-0x2021, 0xc004d78, 0x24040001, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004d78, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004db9, 0x34108000,
-0xc004db9, 0x0, 0xc004d58, 0x0,
-0x50400005, 0x108042, 0x97a2001a, 0x501025,
-0xa7a2001a, 0x108042, 0x1600fff7, 0x0,
-0xc004db9, 0x8021, 0xa7a0001a, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004d78,
-0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004db9, 0x34108000, 0xc004db9, 0x0,
-0xc004d58, 0x0, 0x50400005, 0x108042,
-0x97a2001a, 0x501025, 0xa7a2001a, 0x108042,
-0x1600fff7, 0x0, 0xc004db9, 0x0,
-0x3c040001, 0x24846bcc, 0x97a60018, 0x97a7001a,
-0x3c020001, 0x8c426d98, 0x3c030001, 0x8c636f1c,
-0x3c05000d, 0x34a50205, 0xafa20010, 0xc002b3b,
-0xafa30014, 0x8f830054, 0x24020004, 0x3c010001,
-0xac226dd4, 0x3c010001, 0x10000017, 0xac236f38,
-0x8f830054, 0x3c020001, 0x8c426f38, 0x2463ff9c,
-0x431023, 0x2c420064, 0x1440000f, 0x0,
-0x8f820220, 0x24030005, 0x3c010001, 0xac236dd4,
-0x3c03f700, 0x431025, 0x10000007, 0xaf820220,
-0x24020006, 0x3c010001, 0xac226dd4, 0x24020011,
-0x3c010001, 0xac226dd0, 0x8fbf0034, 0x8fb20030,
-0x8fb1002c, 0x8fb00028, 0x3e00008, 0x27bd0038,
-0x27bdffd8, 0xafb00018, 0x808021, 0xafb1001c,
-0x8821, 0x32024000, 0x10400013, 0xafbf0020,
-0x3c020010, 0x2021024, 0x2c420001, 0x21023,
-0x30434100, 0x3c020001, 0x2021024, 0x14400006,
-0x34714000, 0x3c020002, 0x2021024, 0x14400002,
-0x34716000, 0x34714040, 0x2021, 0x2821,
-0x10000036, 0x2203021, 0x32021000, 0x10400035,
-0x2021, 0x2821, 0xc004ddb, 0x24060040,
-0x24040018, 0x2821, 0xc004ddb, 0x24060c00,
-0x24040017, 0x2821, 0xc004ddb, 0x24060400,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x24040017, 0x2821, 0xc004ddb, 0x24062500,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x24040017, 0x2821, 0xc004ddb, 0x24064600,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x24040017, 0x2821, 0xc004ddb, 0x24066700,
-0x24040016, 0x2821, 0xc004ddb, 0x24060006,
-0x2404001f, 0x2821, 0xc004ddb, 0x24060010,
-0x24040009, 0x2821, 0xc004ddb, 0x24061500,
-0x24040009, 0x2821, 0x24061d00, 0xc004ddb,
-0x0, 0x3c040001, 0x24846bf0, 0x3c05000e,
-0x34a50100, 0x2003021, 0x2203821, 0xafa00010,
-0xc002b3b, 0xafa00014, 0x8fbf0020, 0x8fb1001c,
-0x8fb00018, 0x3e00008, 0x27bd0028, 0x8f850044,
-0x8f820044, 0x3c030001, 0x431025, 0x3c030008,
-0xaf820044, 0x8f840054, 0x8f820054, 0xa32824,
-0x10000002, 0x24840001, 0x8f820054, 0x821023,
-0x2c420002, 0x1440fffc, 0x0, 0x8f820044,
-0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x3e00008, 0xa01021, 0x8f830044,
-0x3c02fff0, 0x3442ffff, 0x42480, 0x621824,
-0x3c020002, 0x822025, 0x641825, 0xaf830044,
-0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x3c030001,
-0x431025, 0xaf820044, 0x8f830054, 0x8f820054,
-0x10000002, 0x24630001, 0x8f820054, 0x621023,
-0x2c420002, 0x1440fffc, 0x0, 0x3e00008,
-0x0, 0x8f820044, 0x2403ff7f, 0x431024,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x34420080,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x3e00008, 0x0,
-0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024,
-0xaf820044, 0x8f820044, 0x3c030001, 0x431025,
-0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
-0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
-0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x3e00008, 0x0, 0x27bdffc8, 0xafb30024,
-0x809821, 0xafbe002c, 0xa0f021, 0xafb20020,
-0xc09021, 0x33c2ffff, 0xafbf0030, 0xafb50028,
-0xafb1001c, 0xafb00018, 0x14400034, 0xa7b20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x12000075,
-0x0, 0x1000fff6, 0x0, 0x3275ffff,
-0x27b10010, 0xa7a00010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2b01024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2b01024, 0xc004db9,
-0x34108000, 0xc004db9, 0x0, 0xc004d58,
-0x0, 0x50400005, 0x108042, 0x96220000,
-0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004db9, 0x0, 0x33c5ffff,
-0x24020001, 0x54a20004, 0x24020002, 0x97a20010,
-0x10000006, 0x521025, 0x14a20006, 0x3271ffff,
-0x97a20010, 0x121827, 0x431024, 0xa7a20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d78,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0xc004d78,
-0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d78, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d78,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d78,
-0x24040001, 0xc004d78, 0x2021, 0x34108000,
-0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
-0x0, 0xc004db9, 0x0, 0x8fbf0030,
-0x8fbe002c, 0x8fb50028, 0x8fb30024, 0x8fb20020,
-0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038,
-0x0, 0x0, 0x0, 0x27bdffe8,
-0xafbf0010, 0x8ee304b8, 0x24020008, 0x146201e0,
-0x0, 0x3c020001, 0x8c426f1c, 0x14400005,
-0x0, 0xc003daf, 0x8f840224, 0x100001d8,
-0x0, 0x8f820220, 0x3c030008, 0x431024,
-0x10400026, 0x24020001, 0x8f840224, 0x8f820220,
-0x3c030400, 0x431024, 0x10400006, 0x0,
-0x3c010002, 0xac208fa0, 0x3c010002, 0x1000000b,
-0xac208fc0, 0x3c030002, 0x24638fa0, 0x8c620000,
-0x24420001, 0xac620000, 0x2c420002, 0x14400003,
-0x24020001, 0x3c010002, 0xac228fc0, 0x3c020002,
-0x8c428fc0, 0x10400006, 0x30820040, 0x10400004,
-0x24020001, 0x3c010002, 0x10000003, 0xac228fc4,
-0x3c010002, 0xac208fc4, 0x3c010002, 0xac248f9c,
-0x3c010002, 0x1000000b, 0xac208fd0, 0x3c010002,
-0xac228fd0, 0x3c010002, 0xac208fc0, 0x3c010002,
-0xac208fa0, 0x3c010002, 0xac208fc4, 0x3c010002,
-0xac208f9c, 0x3c030002, 0x8c638f90, 0x3c020002,
-0x8c428f94, 0x50620004, 0x2463ffff, 0x3c010002,
-0xac238f94, 0x2463ffff, 0x2c62000e, 0x10400194,
-0x31080, 0x3c010001, 0x220821, 0x8c226c00,
-0x400008, 0x0, 0x24020002, 0x3c010002,
-0xac208fc0, 0x3c010002, 0xac208fa0, 0x3c010002,
-0xac208f9c, 0x3c010002, 0xac208fc4, 0x3c010002,
-0xac208fb8, 0x3c010002, 0xac208fb0, 0xaf800224,
-0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fd0,
-0x1440004f, 0x3c02fdff, 0x3442ffff, 0xc003daf,
-0x282a024, 0xaf800204, 0x8f820200, 0x2403fffd,
-0x431024, 0xaf820200, 0x3c010002, 0xac208fe0,
-0x8f830054, 0x3c020002, 0x8c428fb8, 0x24040001,
-0x3c010002, 0xac248fcc, 0x24420001, 0x3c010002,
-0xac228fb8, 0x2c420004, 0x3c010002, 0xac238fb4,
-0x14400006, 0x24020003, 0x3c010001, 0xac246d9c,
-0x3c010002, 0x1000015e, 0xac208fb8, 0x3c010002,
-0x1000015b, 0xac228f90, 0x8f830054, 0x3c020002,
-0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400003, 0x24020004, 0x3c010002, 0xac228f90,
-0x3c020002, 0x8c428fd0, 0x14400021, 0x3c02fdff,
-0x3442ffff, 0x1000014a, 0x282a024, 0x3c040001,
-0x8c846f20, 0x3c010002, 0xc005084, 0xac208fa8,
-0x3c020002, 0x8c428fdc, 0xaf820204, 0x3c020002,
-0x8c428fd0, 0x14400012, 0x3c03fdff, 0x8f820204,
-0x3463ffff, 0x30420030, 0x1440012f, 0x283a024,
-0x3c030002, 0x8c638fdc, 0x24020005, 0x3c010002,
-0xac228f90, 0x3c010002, 0x10000131, 0xac238fe0,
-0x3c020002, 0x8c428fd0, 0x10400010, 0x3c02fdff,
-0x3c020001, 0x8c426e3c, 0x24420001, 0x3c010001,
-0xac226e3c, 0x2c420002, 0x14400125, 0x24020001,
-0x3c010001, 0xac226e44, 0x3c010001, 0xac206e3c,
-0x3c010001, 0x1000011e, 0xac226d9c, 0x3c030002,
-0x8c638fc0, 0x3442ffff, 0x10600119, 0x282a024,
-0x3c020002, 0x8c428f9c, 0x10400115, 0x0,
-0x3c010002, 0xac228fc8, 0x24020003, 0x3c010002,
-0xac228fa0, 0x100000b8, 0x24020006, 0x3c010002,
-0xac208fa8, 0x8f820204, 0x34420040, 0xaf820204,
-0x3c020002, 0x8c428fe0, 0x24030007, 0x3c010002,
-0xac238f90, 0x34420040, 0x3c010002, 0xac228fe0,
-0x3c020002, 0x8c428fc0, 0x10400005, 0x0,
-0x3c020002, 0x8c428f9c, 0x104000f0, 0x24020002,
-0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21,
-0x104000ea, 0x24020002, 0x3c020002, 0x8c428fc4,
-0x104000ef, 0x2404ffbf, 0x3c020002, 0x8c428f9c,
-0x3c030002, 0x8c638fc8, 0x441024, 0x641824,
-0x10430004, 0x24020001, 0x3c010002, 0x100000e4,
-0xac228f90, 0x24020003, 0xaca20000, 0x24020008,
-0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fcc,
-0x1040000c, 0x24020001, 0x3c040002, 0xc005091,
-0x8c848f9c, 0x3c020002, 0x8c428fe8, 0x14400005,
-0x24020001, 0x3c020002, 0x8c428fe4, 0x10400006,
-0x24020001, 0x3c010001, 0xac226d9c, 0x3c010002,
-0x100000cb, 0xac208fb8, 0x3c020002, 0x8c428fb0,
-0x3c030002, 0x8c638f9c, 0x2c420001, 0x210c0,
-0x30630008, 0x3c010002, 0xac228fb0, 0x3c010002,
-0xac238fac, 0x8f830054, 0x24020009, 0x3c010002,
-0xac228f90, 0x3c010002, 0x100000b9, 0xac238fb4,
-0x8f830054, 0x3c020002, 0x8c428fb4, 0x2463d8f0,
-0x431023, 0x2c422710, 0x1440009f, 0x0,
-0x3c020002, 0x8c428fc0, 0x10400005, 0x0,
-0x3c020002, 0x8c428f9c, 0x104000a0, 0x24020002,
-0x3c030002, 0x24638fa0, 0x8c620000, 0x2c424e21,
-0x1040009a, 0x24020002, 0x3c020002, 0x8c428fcc,
-0x1040000e, 0x0, 0x3c020002, 0x8c428f9c,
-0x3c010002, 0xac208fcc, 0x30420080, 0x1040002f,
-0x2402000c, 0x8f820204, 0x30420080, 0x1440000c,
-0x24020003, 0x10000029, 0x2402000c, 0x3c020002,
-0x8c428f9c, 0x30420080, 0x14400005, 0x24020003,
-0x8f820204, 0x30420080, 0x1040001f, 0x24020003,
-0xac620000, 0x2402000a, 0x3c010002, 0xac228f90,
-0x3c040002, 0x24848fd8, 0x8c820000, 0x3c030002,
-0x8c638fb0, 0x431025, 0xaf820204, 0x8c830000,
-0x3c040002, 0x8c848fb0, 0x2402000b, 0x3c010002,
-0xac228f90, 0x641825, 0x3c010002, 0xac238fe0,
-0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21,
-0x10400066, 0x24020002, 0x3c020002, 0x8c428fd0,
-0x10400005, 0x0, 0x2402000c, 0x3c010002,
-0x10000067, 0xac228f90, 0x3c020002, 0x8c428fc0,
-0x10400063, 0x0, 0x3c040002, 0x8c848f9c,
-0x10800055, 0x30820008, 0x3c030002, 0x8c638fac,
-0x1062005b, 0x24020003, 0x3c010002, 0xac248fc8,
-0xaca20000, 0x24020006, 0x3c010002, 0x10000054,
-0xac228f90, 0x8f820200, 0x34420002, 0xaf820200,
-0x8f830054, 0x2402000d, 0x3c010002, 0xac228f90,
-0x3c010002, 0xac238fb4, 0x8f830054, 0x3c020002,
-0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400031, 0x0, 0x3c020002, 0x8c428fd0,
-0x10400020, 0x2402000e, 0x3c030002, 0x8c638fe4,
-0x3c010002, 0x14600015, 0xac228f90, 0xc003e6d,
-0x0, 0x3c050001, 0x8ca56d98, 0xc00529b,
-0x2021, 0x3c030001, 0x8c636d98, 0x24020004,
-0x14620005, 0x2403fffb, 0x3c020001, 0x8c426d94,
-0x10000003, 0x2403fff7, 0x3c020001, 0x8c426d94,
-0x431024, 0x3c010001, 0xac226d94, 0x8f830224,
-0x3c020200, 0x3c010002, 0xac238fec, 0x10000020,
-0x282a025, 0x3c020002, 0x8c428fc0, 0x10400005,
-0x0, 0x3c020002, 0x8c428f9c, 0x1040000f,
-0x24020002, 0x3c020002, 0x8c428fa0, 0x2c424e21,
-0x1040000a, 0x24020002, 0x3c020002, 0x8c428fc0,
-0x1040000f, 0x0, 0x3c020002, 0x8c428f9c,
-0x1440000b, 0x0, 0x24020002, 0x3c010002,
-0x10000007, 0xac228f90, 0x3c020002, 0x8c428fc0,
-0x10400003, 0x0, 0xc003daf, 0x0,
-0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0x8fbf0010, 0x3e00008, 0x27bd0018, 0x3c030002,
-0x24638fe8, 0x8c620000, 0x10400005, 0x34422000,
-0x3c010002, 0xac228fdc, 0x10000003, 0xac600000,
-0x3c010002, 0xac248fdc, 0x3e00008, 0x0,
-0x27bdffe0, 0x30820030, 0xafbf0018, 0x3c010002,
-0xac228fe4, 0x14400067, 0x3c02ffff, 0x34421f0e,
-0x821024, 0x14400061, 0x24020030, 0x30822000,
-0x1040005d, 0x30838000, 0x31a02, 0x30820001,
-0x21200, 0x3c040001, 0x8c846f20, 0x621825,
-0x331c2, 0x3c030001, 0x24636e48, 0x30828000,
-0x21202, 0x30840001, 0x42200, 0x441025,
-0x239c2, 0x61080, 0x431021, 0x471021,
-0x90430000, 0x24020001, 0x10620025, 0x0,
-0x10600007, 0x24020002, 0x10620013, 0x24020003,
-0x1062002c, 0x3c05000f, 0x10000037, 0x0,
-0x8f820200, 0x2403feff, 0x431024, 0xaf820200,
-0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024,
-0xaf820220, 0x3c010002, 0xac209004, 0x3c010002,
-0x10000034, 0xac20900c, 0x8f820200, 0x34420100,
-0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff,
-0x431024, 0xaf820220, 0x24020100, 0x3c010002,
-0xac229004, 0x3c010002, 0x10000026, 0xac20900c,
-0x8f820200, 0x2403feff, 0x431024, 0xaf820200,
-0x8f820220, 0x3c030001, 0x431025, 0xaf820220,
-0x3c010002, 0xac209004, 0x3c010002, 0x10000019,
-0xac23900c, 0x8f820200, 0x34420100, 0xaf820200,
-0x8f820220, 0x3c030001, 0x431025, 0xaf820220,
-0x24020100, 0x3c010002, 0xac229004, 0x3c010002,
-0x1000000c, 0xac23900c, 0x34a5ffff, 0x3c040001,
-0x24846c38, 0xafa30010, 0xc002b3b, 0xafa00014,
-0x10000004, 0x0, 0x24020030, 0x3c010002,
-0xac228fe8, 0x8fbf0018, 0x3e00008, 0x27bd0020,
-0x0, 0x0, 0x0, 0x27bdffc8,
-0xafb20028, 0x809021, 0xafb3002c, 0xa09821,
-0xafb00020, 0xc08021, 0x3c040001, 0x24846c50,
-0x3c050009, 0x3c020001, 0x8c426d98, 0x34a59001,
-0x2403021, 0x2603821, 0xafbf0030, 0xafb10024,
-0xa7a0001a, 0xafb00014, 0xc002b3b, 0xafa20010,
-0x24020002, 0x12620083, 0x2e620003, 0x10400005,
-0x24020001, 0x1262000a, 0x0, 0x10000173,
-0x0, 0x24020004, 0x126200f8, 0x24020008,
-0x126200f7, 0x3c02ffec, 0x1000016c, 0x0,
-0x3c020001, 0x8c426d94, 0x30420002, 0x14400004,
-0x128940, 0x3c02fffb, 0x3442ffff, 0x2028024,
-0x3c010002, 0x310821, 0xac308ffc, 0x3c024000,
-0x2021024, 0x1040004e, 0x1023c2, 0x30840030,
-0x101382, 0x3042001c, 0x3c030001, 0x24636dd8,
-0x431021, 0x823821, 0x3c020020, 0x2021024,
-0x10400006, 0x24020100, 0x3c010002, 0x310821,
-0xac229000, 0x10000005, 0x3c020080, 0x3c010002,
-0x310821, 0xac209000, 0x3c020080, 0x2021024,
-0x10400006, 0x121940, 0x3c020001, 0x3c010002,
-0x230821, 0x10000005, 0xac229008, 0x121140,
-0x3c010002, 0x220821, 0xac209008, 0x94e40000,
-0x3c030001, 0x8c636f40, 0x24020005, 0x10620010,
-0xa7a40018, 0x32024000, 0x10400002, 0x34824000,
-0xa7a20018, 0x24040001, 0x94e20002, 0x24050004,
-0x24e60002, 0x34420001, 0xc0045be, 0xa4e20002,
-0x24040001, 0x2821, 0xc0045be, 0x27a60018,
-0x3c020001, 0x8c426d98, 0x24110001, 0x3c010001,
-0xac316da4, 0x14530004, 0x32028000, 0xc003daf,
-0x0, 0x32028000, 0x1040011c, 0x0,
-0xc003daf, 0x0, 0x3c030001, 0x8c636f40,
-0x24020005, 0x10620115, 0x24020002, 0x3c010001,
-0xac316d9c, 0x3c010001, 0x10000110, 0xac226d98,
-0x24040001, 0x24050004, 0x27b0001a, 0xc0045be,
-0x2003021, 0x24040001, 0x2821, 0xc0045be,
-0x2003021, 0x3c020002, 0x511021, 0x8c428ff4,
-0x3c040001, 0x8c846d98, 0x3c03bfff, 0x3463ffff,
-0x3c010001, 0xac336da4, 0x431024, 0x3c010002,
-0x310821, 0x109300f7, 0xac228ff4, 0x100000f7,
-0x0, 0x3c022000, 0x2021024, 0x10400005,
-0x24020001, 0x3c010001, 0xac226f1c, 0x10000004,
-0x128940, 0x3c010001, 0xac206f1c, 0x128940,
-0x3c010002, 0x310821, 0xac308ff8, 0x3c024000,
-0x2021024, 0x14400014, 0x0, 0x3c020001,
-0x8c426f1c, 0x10400006, 0x24040004, 0x24050001,
-0xc004ddb, 0x24062000, 0x24020001, 0xaee204b8,
-0x3c020002, 0x511021, 0x8c428ff0, 0x3c03bfff,
-0x3463ffff, 0x431024, 0x3c010002, 0x310821,
-0x100000d0, 0xac228ff0, 0x3c020001, 0x8c426f1c,
-0x10400028, 0x3c0300a0, 0x2031024, 0x5443000d,
-0x3c020020, 0x3c020001, 0x8c426f20, 0x24030100,
-0x3c010002, 0x310821, 0xac239004, 0x3c030001,
-0x3c010002, 0x310821, 0xac23900c, 0x10000015,
-0x34420400, 0x2021024, 0x10400008, 0x24030100,
-0x3c020001, 0x8c426f20, 0x3c010002, 0x310821,
-0xac239004, 0x1000000b, 0x34420800, 0x3c020080,
-0x2021024, 0x1040002e, 0x3c030001, 0x3c020001,
-0x8c426f20, 0x3c010002, 0x310821, 0xac23900c,
-0x34420c00, 0x3c010001, 0xac226f20, 0x10000025,
-0x24040001, 0x3c020020, 0x2021024, 0x10400006,
-0x24020100, 0x3c010002, 0x310821, 0xac229004,
-0x10000005, 0x3c020080, 0x3c010002, 0x310821,
-0xac209004, 0x3c020080, 0x2021024, 0x10400007,
-0x121940, 0x3c020001, 0x3c010002, 0x230821,
-0xac22900c, 0x10000006, 0x24040001, 0x121140,
-0x3c010002, 0x220821, 0xac20900c, 0x24040001,
-0x2821, 0x27b0001e, 0xc00457c, 0x2003021,
-0x24040001, 0x2821, 0xc00457c, 0x2003021,
-0x24040001, 0x24050001, 0x27b0001c, 0xc00457c,
-0x2003021, 0x24040001, 0x24050001, 0xc00457c,
-0x2003021, 0x10000077, 0x0, 0x3c02ffec,
-0x3442ffff, 0x2028024, 0x3c020008, 0x2028025,
-0x121140, 0x3c010002, 0x220821, 0xac308ff8,
-0x3c022000, 0x2021024, 0x10400009, 0x0,
-0x3c020001, 0x8c426e44, 0x14400005, 0x24020001,
-0x3c010001, 0xac226f1c, 0x10000004, 0x3c024000,
-0x3c010001, 0xac206f1c, 0x3c024000, 0x2021024,
-0x1440001d, 0x24020e01, 0x3c030001, 0x8c636f1c,
-0xaf820238, 0x3c010001, 0xac206db0, 0x10600005,
-0x24022020, 0x3c010001, 0xac226f20, 0x24020001,
-0xaee204b8, 0x3c04bfff, 0x121940, 0x3c020002,
-0x431021, 0x8c428ff0, 0x3c050001, 0x8ca56d98,
-0x3484ffff, 0x441024, 0x3c010002, 0x230821,
-0xac228ff0, 0x24020001, 0x10a20044, 0x0,
-0x10000040, 0x0, 0x3c020001, 0x8c426f1c,
-0x1040001c, 0x24022000, 0x3c010001, 0xac226f20,
-0x3c0300a0, 0x2031024, 0x14430005, 0x121140,
-0x3402a000, 0x3c010001, 0x1000002d, 0xac226f20,
-0x3c030002, 0x621821, 0x8c638ff8, 0x3c020020,
-0x621024, 0x10400004, 0x24022001, 0x3c010001,
-0x10000023, 0xac226f20, 0x3c020080, 0x621024,
-0x1040001f, 0x3402a001, 0x3c010001, 0x1000001c,
-0xac226f20, 0x3c020020, 0x2021024, 0x10400007,
-0x121940, 0x24020100, 0x3c010002, 0x230821,
-0xac229004, 0x10000006, 0x3c020080, 0x121140,
-0x3c010002, 0x220821, 0xac209004, 0x3c020080,
-0x2021024, 0x10400006, 0x121940, 0x3c020001,
-0x3c010002, 0x230821, 0x10000005, 0xac22900c,
-0x121140, 0x3c010002, 0x220821, 0xac20900c,
-0x3c030001, 0x8c636d98, 0x24020001, 0x10620003,
-0x0, 0xc003daf, 0x0, 0x8fbf0030,
-0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
-0x3e00008, 0x27bd0038, 0x27bdffb0, 0xafb3003c,
-0x9821, 0xafb50040, 0xa821, 0xafb10034,
-0x8821, 0x24020002, 0xafbf0048, 0xafbe0044,
-0xafb20038, 0xafb00030, 0xafa4002c, 0xa7a0001a,
-0xa7a00018, 0xa7a00020, 0xa7a0001e, 0xa7a00022,
-0x10a20130, 0xa7a0001c, 0x2ca20003, 0x10400005,
-0x24020001, 0x10a2000a, 0x3c024000, 0x1000025d,
-0x2201021, 0x24020004, 0x10a2020a, 0x24020008,
-0x10a20208, 0x2201021, 0x10000256, 0x0,
-0x8fa8002c, 0x88140, 0x3c030002, 0x701821,
-0x8c638ffc, 0x621024, 0x14400009, 0x24040001,
-0x3c027fff, 0x3442ffff, 0x628824, 0x3c010002,
-0x300821, 0xac318ff4, 0x10000246, 0x2201021,
-0x24050001, 0xc00457c, 0x27a60018, 0x24040001,
-0x24050001, 0xc00457c, 0x27a60018, 0x97a20018,
-0x30420004, 0x104000d9, 0x3c114000, 0x3c020001,
-0x8c426f40, 0x2443ffff, 0x2c620006, 0x104000d9,
-0x31080, 0x3c010001, 0x220821, 0x8c226c68,
-0x400008, 0x0, 0x24040001, 0x24050011,
-0x27b0001a, 0xc00457c, 0x2003021, 0x24040001,
-0x24050011, 0xc00457c, 0x2003021, 0x97a3001a,
-0x30624000, 0x10400002, 0x3c150010, 0x3c150008,
-0x30628000, 0x104000aa, 0x3c130001, 0x100000a8,
-0x3c130002, 0x24040001, 0x24050014, 0x27b0001a,
-0xc00457c, 0x2003021, 0x24040001, 0x24050014,
-0xc00457c, 0x2003021, 0x97a3001a, 0x30621000,
-0x10400002, 0x3c150010, 0x3c150008, 0x30620800,
-0x10400097, 0x3c130001, 0x10000095, 0x3c130002,
-0x24040001, 0x24050019, 0x27b0001c, 0xc00457c,
-0x2003021, 0x24040001, 0x24050019, 0xc00457c,
-0x2003021, 0x97a2001c, 0x30430700, 0x24020400,
-0x10620027, 0x28620401, 0x1040000e, 0x24020200,
-0x1062001f, 0x28620201, 0x10400005, 0x24020100,
-0x5062001e, 0x3c130001, 0x1000001e, 0x24040001,
-0x24020300, 0x50620019, 0x3c130002, 0x10000019,
-0x24040001, 0x24020600, 0x1062000d, 0x28620601,
-0x10400005, 0x24020500, 0x5062000b, 0x3c130002,
-0x10000010, 0x24040001, 0x24020700, 0x1462000d,
-0x24040001, 0x3c130004, 0x1000000a, 0x3c150008,
-0x10000006, 0x3c130004, 0x10000005, 0x3c150008,
-0x3c130001, 0x10000002, 0x3c150008, 0x3c150010,
-0x24040001, 0x24050018, 0x27b0001e, 0xc00457c,
-0x2003021, 0x24040001, 0x24050018, 0xc00457c,
-0x2003021, 0x8fa8002c, 0x97a7001e, 0x81140,
-0x3c060002, 0xc23021, 0x8cc68ff4, 0x97a20022,
-0x3c100001, 0x26106c5c, 0x2002021, 0xafa20010,
-0x97a2001c, 0x3c05000c, 0x34a50303, 0xc002b3b,
-0xafa20014, 0x3c020004, 0x16620010, 0x3c020001,
-0x8f840054, 0x24030001, 0x24020002, 0x3c010001,
-0xac236d9c, 0x3c010001, 0xac226d98, 0x3c010001,
-0xac236da4, 0x3c010001, 0xac236e24, 0x3c010001,
-0xac246f30, 0x1000004f, 0x2b38825, 0x16620039,
-0x3c028000, 0x3c020001, 0x8c426e20, 0x1440001e,
-0x24040018, 0x2021, 0x2821, 0xc004ddb,
-0x34068000, 0x8f830054, 0x8f820054, 0x2b38825,
-0x10000002, 0x24630032, 0x8f820054, 0x621023,
-0x2c420033, 0x1440fffc, 0x0, 0x8f830054,
-0x24020001, 0x3c010001, 0xac226e20, 0x3c010001,
-0xac226d9c, 0x3c010001, 0xac226d98, 0x3c010001,
-0xac226da4, 0x3c010001, 0xac226e24, 0x3c010001,
-0x1000002c, 0xac236f30, 0x2821, 0xc004ddb,
-0x24060404, 0x2021, 0x2405001e, 0x27a60018,
-0x24020002, 0xc0045be, 0xa7a20018, 0x2021,
-0x2821, 0x27a60018, 0xc0045be, 0xa7a00018,
-0x24040018, 0x24050002, 0xc004ddb, 0x24060004,
-0x3c028000, 0x2221025, 0x2b31825, 0x10000015,
-0x438825, 0x2221025, 0x2751825, 0x438825,
-0x2002021, 0x97a6001c, 0x3c070001, 0x8ce76d98,
-0x3c05000c, 0x34a50326, 0xafb30010, 0xc002b3b,
-0xafb10014, 0x10000007, 0x0, 0x3c110002,
-0x2308821, 0x8e318ffc, 0x3c027fff, 0x3442ffff,
-0x2228824, 0x3c020001, 0x8c426da8, 0x1040001e,
-0x0, 0x3c020001, 0x8c426f1c, 0x10400002,
-0x3c022000, 0x2228825, 0x8fa8002c, 0x81140,
-0x3c010002, 0x220821, 0x8c229000, 0x10400003,
-0x3c020020, 0x10000005, 0x2228825, 0x3c02ffdf,
-0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140,
-0x3c010002, 0x220821, 0x8c229008, 0x10400003,
-0x3c020080, 0x10000004, 0x2228825, 0x3c02ff7f,
-0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140,
-0x3c010002, 0x220821, 0xac318ff4, 0x10000135,
-0x2201021, 0x8fa8002c, 0x8f140, 0x3c030002,
-0x7e1821, 0x8c638ff8, 0x3c024000, 0x621024,
-0x14400009, 0x24040001, 0x3c027fff, 0x3442ffff,
-0x628824, 0x3c010002, 0x3e0821, 0xac318ff0,
-0x10000124, 0x2201021, 0x2821, 0xc00457c,
-0x27a60018, 0x24040001, 0x2821, 0xc00457c,
-0x27a60018, 0x24040001, 0x24050001, 0x27b20020,
-0xc00457c, 0x2403021, 0x24040001, 0x24050001,
-0xc00457c, 0x2403021, 0x24040001, 0x24050004,
-0x27b1001e, 0xc00457c, 0x2203021, 0x24040001,
-0x24050004, 0xc00457c, 0x2203021, 0x24040001,
-0x24050005, 0x27b00022, 0xc00457c, 0x2003021,
-0x24040001, 0x24050005, 0xc00457c, 0x2003021,
-0x24040001, 0x24050010, 0xc00457c, 0x27a60018,
-0x24040001, 0x24050010, 0xc00457c, 0x27a60018,
-0x24040001, 0x2405000a, 0xc00457c, 0x2403021,
-0x24040001, 0x2405000a, 0xc00457c, 0x2403021,
-0x24040001, 0x24050018, 0xc00457c, 0x2203021,
-0x24040001, 0x24050018, 0xc00457c, 0x2203021,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
-0x97a20018, 0x30420004, 0x10400066, 0x3c114000,
-0x3c030001, 0x8c636f34, 0x24020005, 0x14620067,
-0x24040001, 0x24050019, 0x27b0001c, 0xc00457c,
-0x2003021, 0x24040001, 0x24050019, 0xc00457c,
-0x2003021, 0x97a2001c, 0x30430700, 0x24020400,
-0x10620027, 0x28620401, 0x1040000e, 0x24020200,
-0x1062001f, 0x28620201, 0x10400005, 0x24020100,
-0x5062001e, 0x3c130001, 0x1000001e, 0x3c020004,
-0x24020300, 0x50620019, 0x3c130002, 0x10000019,
-0x3c020004, 0x24020600, 0x1062000d, 0x28620601,
-0x10400005, 0x24020500, 0x5062000b, 0x3c130002,
-0x10000010, 0x3c020004, 0x24020700, 0x1462000d,
-0x3c020004, 0x3c130004, 0x1000000a, 0x3c150008,
-0x10000006, 0x3c130004, 0x10000005, 0x3c150008,
-0x3c130001, 0x10000002, 0x3c150008, 0x3c150010,
-0x3c020004, 0x12620017, 0x3c028000, 0x8f820054,
-0x24100001, 0x3c010001, 0xac306d9c, 0x3c010001,
-0xac306d98, 0x3c010001, 0xac306da4, 0x3c010001,
-0xac306e24, 0x3c010001, 0xac226f30, 0x3c020001,
-0x16620022, 0x2758825, 0x2021, 0x2821,
-0xc004ddb, 0x34068000, 0x3c010001, 0x1000001b,
-0xac306e20, 0x2221025, 0x2b31825, 0x438825,
-0x97a6001c, 0x3c020001, 0x8c426f1c, 0x3c070001,
-0x8ce76d98, 0x3c040001, 0x24846c5c, 0xafa20010,
-0x97a2001e, 0x3c05000c, 0x34a50323, 0x3c010001,
-0xac206e20, 0xc002b3b, 0xafa20014, 0x10000007,
-0x0, 0x3c110002, 0x23e8821, 0x8e318ff0,
-0x3c027fff, 0x3442ffff, 0x2228824, 0x3c020001,
-0x8c426da8, 0x10400069, 0x0, 0x3c020001,
-0x8c426f1c, 0x10400002, 0x3c022000, 0x2228825,
-0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
-0x8c229004, 0x10400003, 0x3c020020, 0x10000005,
-0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
-0x8c22900c, 0x10400003, 0x3c020080, 0x1000004f,
-0x2228825, 0x3c02ff7f, 0x3442ffff, 0x1000004b,
-0x2228824, 0x8fa8002c, 0x82940, 0x3c030002,
-0x651821, 0x8c638ff8, 0x3c024000, 0x621024,
-0x14400008, 0x3c027fff, 0x3442ffff, 0x628824,
-0x3c010002, 0x250821, 0xac318ff0, 0x10000041,
-0x2201021, 0x3c020001, 0x8c426da8, 0x10400034,
-0x3c11c00c, 0x3c020001, 0x8c426e44, 0x3c04c00c,
-0x34842000, 0x3c030001, 0x8c636f1c, 0x2102b,
-0x21023, 0x441024, 0x10600003, 0x518825,
-0x3c022000, 0x2228825, 0x3c020002, 0x451021,
-0x8c429004, 0x10400003, 0x3c020020, 0x10000004,
-0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
-0x8c22900c, 0x10400003, 0x3c020080, 0x10000004,
-0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824,
-0x3c020001, 0x8c426e30, 0x10400002, 0x3c020800,
-0x2228825, 0x3c020001, 0x8c426e34, 0x10400002,
-0x3c020400, 0x2228825, 0x3c020001, 0x8c426e38,
-0x10400006, 0x3c020100, 0x10000004, 0x2228825,
-0x3c027fff, 0x3442ffff, 0x628824, 0x8fa8002c,
-0x81140, 0x3c010002, 0x220821, 0xac318ff0,
-0x2201021, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
-0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
-0x3e00008, 0x27bd0050, 0x27bdffd0, 0xafb20028,
-0x809021, 0xafbf002c, 0xafb10024, 0xafb00020,
-0x8f840200, 0x3c100001, 0x8e106d98, 0x8f860220,
-0x24020002, 0x1202005c, 0x2e020003, 0x10400005,
-0x24020001, 0x1202000a, 0x121940, 0x1000010c,
-0x0, 0x24020004, 0x120200bf, 0x24020008,
-0x120200be, 0x128940, 0x10000105, 0x0,
-0x3c050002, 0xa32821, 0x8ca58ffc, 0x3c100002,
-0x2038021, 0x8e108ff4, 0x3c024000, 0xa21024,
-0x10400038, 0x3c020008, 0x2021024, 0x10400020,
-0x34840002, 0x3c020002, 0x431021, 0x8c429000,
-0x10400005, 0x34840020, 0x34840100, 0x3c020020,
-0x10000006, 0x2028025, 0x2402feff, 0x822024,
-0x3c02ffdf, 0x3442ffff, 0x2028024, 0x121140,
-0x3c010002, 0x220821, 0x8c229008, 0x10400005,
-0x3c020001, 0xc23025, 0x3c020080, 0x10000016,
-0x2028025, 0x3c02fffe, 0x3442ffff, 0xc23024,
-0x3c02ff7f, 0x3442ffff, 0x1000000f, 0x2028024,
-0x2402fedf, 0x822024, 0x3c02fffe, 0x3442ffff,
-0xc23024, 0x3c02ff5f, 0x3442ffff, 0x2028024,
-0x3c010002, 0x230821, 0xac209000, 0x3c010002,
-0x230821, 0xac209008, 0xaf840200, 0xaf860220,
-0x8f820220, 0x34420002, 0xaf820220, 0x1000000a,
-0x121140, 0x3c02bfff, 0x3442ffff, 0x8f830200,
-0x2028024, 0x2402fffd, 0x621824, 0xc003daf,
-0xaf830200, 0x121140, 0x3c010002, 0x220821,
-0x100000b7, 0xac308ff4, 0x3c020001, 0x8c426f1c,
-0x10400069, 0x24050004, 0x24040001, 0xc00457c,
-0x27a60018, 0x24040001, 0x24050005, 0xc00457c,
-0x27a6001a, 0x97a30018, 0x97a2001a, 0x3c040001,
-0x24846e48, 0x30630c00, 0x31a82, 0x30420c00,
-0x21282, 0xa7a2001a, 0x21080, 0x441021,
-0x431021, 0xa7a30018, 0x90480000, 0x24020001,
-0x3103ffff, 0x10620029, 0x28620002, 0x10400005,
-0x0, 0x10600009, 0x0, 0x1000003d,
-0x0, 0x10700013, 0x24020003, 0x1062002c,
-0x0, 0x10000037, 0x0, 0x8f820200,
-0x2403feff, 0x431024, 0xaf820200, 0x8f820220,
-0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220,
-0x3c010002, 0xac209004, 0x3c010002, 0x10000032,
-0xac20900c, 0x8f820200, 0x34420100, 0xaf820200,
-0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024,
-0xaf820220, 0x24020100, 0x3c010002, 0xac229004,
-0x3c010002, 0x10000024, 0xac20900c, 0x8f820200,
-0x2403feff, 0x431024, 0xaf820200, 0x8f820220,
-0x3c030001, 0x431025, 0xaf820220, 0x3c010002,
-0xac209004, 0x3c010002, 0x10000017, 0xac23900c,
-0x8f820200, 0x34420100, 0xaf820200, 0x8f820220,
-0x3c030001, 0x431025, 0xaf820220, 0x24020100,
-0x3c010002, 0xac229004, 0x3c010002, 0x1000000a,
-0xac23900c, 0x3c040001, 0x24846c80, 0x97a6001a,
-0x97a70018, 0x3c050001, 0x34a5ffff, 0xafa80010,
-0xc002b3b, 0xafa00014, 0x8f820200, 0x34420002,
-0x1000004b, 0xaf820200, 0x128940, 0x3c050002,
-0xb12821, 0x8ca58ff8, 0x3c100002, 0x2118021,
-0x8e108ff0, 0x3c024000, 0xa21024, 0x14400010,
-0x0, 0x3c020001, 0x8c426f1c, 0x14400005,
-0x3c02bfff, 0x8f820200, 0x34420002, 0xaf820200,
-0x3c02bfff, 0x3442ffff, 0xc003daf, 0x2028024,
-0x3c010002, 0x310821, 0x10000031, 0xac308ff0,
-0x3c020001, 0x8c426f1c, 0x10400005, 0x3c020020,
-0x3c020001, 0x8c426e44, 0x10400025, 0x3c020020,
-0xa21024, 0x10400007, 0x34840020, 0x24020100,
-0x3c010002, 0x310821, 0xac229004, 0x10000006,
-0x34840100, 0x3c010002, 0x310821, 0xac209004,
-0x2402feff, 0x822024, 0x3c020080, 0xa21024,
-0x10400007, 0x121940, 0x3c020001, 0x3c010002,
-0x230821, 0xac22900c, 0x10000008, 0xc23025,
-0x121140, 0x3c010002, 0x220821, 0xac20900c,
-0x3c02fffe, 0x3442ffff, 0xc23024, 0xaf840200,
-0xaf860220, 0x8f820220, 0x34420002, 0xaf820220,
-0x121140, 0x3c010002, 0x220821, 0xac308ff0,
-0x8fbf002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
-0x3e00008, 0x27bd0030, 0x0, 0x1821,
-0x308400ff, 0x2405ffdf, 0x2406ffbf, 0x641007,
-0x30420001, 0x10400004, 0x0, 0x8f820044,
-0x10000003, 0x34420040, 0x8f820044, 0x461024,
-0xaf820044, 0x8f820044, 0x34420020, 0xaf820044,
-0x8f820044, 0x451024, 0xaf820044, 0x24630001,
-0x28620008, 0x5440ffee, 0x641007, 0x3e00008,
-0x0, 0x2c820008, 0x1040001b, 0x0,
-0x2405ffdf, 0x2406ffbf, 0x41880, 0x3c020001,
-0x24426e60, 0x621821, 0x24640004, 0x90620000,
-0x10400004, 0x0, 0x8f820044, 0x10000003,
-0x34420040, 0x8f820044, 0x461024, 0xaf820044,
-0x8f820044, 0x34420020, 0xaf820044, 0x8f820044,
-0x451024, 0xaf820044, 0x24630001, 0x64102b,
-0x1440ffee, 0x0, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x8f8400c4,
-0x8f8600e0, 0x8f8700e4, 0x2402fff8, 0xc22824,
-0x10e5001a, 0x27623ff8, 0x14e20002, 0x24e80008,
-0x27683000, 0x55050004, 0x8d0a0000, 0x30c20004,
-0x14400012, 0x805021, 0x8ce90000, 0x8f42013c,
-0x1494823, 0x49182b, 0x94eb0006, 0x10600002,
-0x25630050, 0x494821, 0x123182b, 0x50400003,
-0x8f4201fc, 0x3e00008, 0xe01021, 0xaf8800e8,
-0x24420001, 0xaf4201fc, 0xaf8800e4, 0x3e00008,
-0x1021, 0x3e00008, 0x0, 0x8f8300e4,
-0x27623ff8, 0x10620004, 0x24620008, 0xaf8200e8,
-0x3e00008, 0xaf8200e4, 0x27623000, 0xaf8200e8,
-0x3e00008, 0xaf8200e4, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x8f880120,
-0x27624fe0, 0x8f830128, 0x15020002, 0x25090020,
-0x27694800, 0x11230012, 0x8fa20010, 0xad040000,
-0xad050004, 0xad060008, 0xa507000e, 0x8fa30014,
-0xad020018, 0x8fa20018, 0xad03001c, 0x25030016,
-0xad020010, 0xad030014, 0xaf890120, 0x8f4300fc,
-0x24020001, 0x2463ffff, 0x3e00008, 0xaf4300fc,
-0x8f430324, 0x1021, 0x24630001, 0x3e00008,
-0xaf430324, 0x3e00008, 0x0, 0x8f880100,
-0x276247e0, 0x8f830108, 0x15020002, 0x25090020,
-0x27694000, 0x1123000f, 0x8fa20010, 0xad040000,
-0xad050004, 0xad060008, 0xa507000e, 0x8fa30014,
-0xad020018, 0x8fa20018, 0xad03001c, 0x25030016,
-0xad020010, 0xad030014, 0xaf890100, 0x3e00008,
-0x24020001, 0x8f430328, 0x1021, 0x24630001,
-0x3e00008, 0xaf430328, 0x3e00008, 0x0,
-0x0, 0x0, 0x0, 0x0 };
-static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = {
-0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6677, 0x6d61696e, 0x2e632c76, 0x20312e31,
-0x2e322e34, 0x35203139, 0x39392f30, 0x312f3234,
-0x2030303a, 0x31303a35, 0x35207368, 0x75616e67,
-0x20457870, 0x20240000, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x6261644d, 0x656d537a,
-0x0, 0x68775665, 0x72000000, 0x62616448,
-0x77566572, 0x0, 0x2a2a4441, 0x574e5f41,
-0x0, 0x74785278, 0x4266537a, 0x0,
-0x62664174, 0x6e4d726b, 0x0, 0x7265645a,
-0x6f6e6531, 0x0, 0x70636943, 0x6f6e6600,
-0x67656e43, 0x6f6e6600, 0x2a646d61, 0x5244666c,
-0x0, 0x2a50414e, 0x49432a00, 0x2e2e2f2e,
-0x2e2f2e2e, 0x2f2e2e2f, 0x2e2e2f73, 0x72632f6e,
-0x69632f66, 0x77322f63, 0x6f6d6d6f, 0x6e2f6677,
-0x6d61696e, 0x2e630000, 0x72636246, 0x6c616773,
-0x0, 0x62616452, 0x78526362, 0x0,
-0x676c6f62, 0x466c6773, 0x0, 0x2b5f6469,
-0x73705f6c, 0x6f6f7000, 0x2b65765f, 0x68616e64,
-0x6c657200, 0x63616e74, 0x31446d61, 0x0,
-0x2b715f64, 0x6d615f74, 0x6f5f6e69, 0x635f636b,
-0x73756d00, 0x2b685f73, 0x656e645f, 0x64617461,
-0x5f726561, 0x64795f63, 0x6b73756d, 0x0,
-0x2b685f64, 0x6d615f72, 0x645f6173, 0x73697374,
-0x5f636b73, 0x756d0000, 0x74436b73, 0x6d4f6e00,
-0x2b715f64, 0x6d615f74, 0x6f5f6e69, 0x63000000,
-0x2b685f73, 0x656e645f, 0x64617461, 0x5f726561,
-0x64790000, 0x2b685f64, 0x6d615f72, 0x645f6173,
-0x73697374, 0x0, 0x74436b73, 0x6d4f6666,
-0x0, 0x2b685f73, 0x656e645f, 0x62645f72,
-0x65616479, 0x0, 0x68737453, 0x52696e67,
-0x0, 0x62616453, 0x52696e67, 0x0,
-0x6e696353, 0x52696e67, 0x0, 0x77446d61,
-0x416c6c41, 0x0, 0x2b715f64, 0x6d615f74,
-0x6f5f686f, 0x73745f63, 0x6b73756d, 0x0,
-0x2b685f6d, 0x61635f72, 0x785f636f, 0x6d705f63,
-0x6b73756d, 0x0, 0x2b685f64, 0x6d615f77,
-0x725f6173, 0x73697374, 0x5f636b73, 0x756d0000,
-0x72436b73, 0x6d4f6e00, 0x2b715f64, 0x6d615f74,
-0x6f5f686f, 0x73740000, 0x2b685f6d, 0x61635f72,
-0x785f636f, 0x6d700000, 0x2b685f64, 0x6d615f77,
-0x725f6173, 0x73697374, 0x0, 0x72436b73,
-0x6d4f6666, 0x0, 0x2b685f72, 0x6563765f,
-0x62645f72, 0x65616479, 0x0, 0x2b685f72,
-0x6563765f, 0x6a756d62, 0x6f5f6264, 0x5f726561,
-0x64790000, 0x2b685f72, 0x6563765f, 0x6d696e69,
-0x5f62645f, 0x72656164, 0x79000000, 0x2b6d685f,
-0x636f6d6d, 0x616e6400, 0x2b685f74, 0x696d6572,
-0x0, 0x2b685f64, 0x6f5f7570, 0x64617465,
-0x5f74785f, 0x636f6e73, 0x0, 0x2b685f64,
-0x6f5f7570, 0x64617465, 0x5f72785f, 0x70726f64,
-0x0, 0x2b636b73, 0x756d3136, 0x0,
-0x2b706565, 0x6b5f6d61, 0x635f7278, 0x5f776100,
-0x2b706565, 0x6b5f6d61, 0x635f7278, 0x0,
-0x2b646571, 0x5f6d6163, 0x5f727800, 0x2b685f6d,
-0x61635f72, 0x785f6174, 0x746e0000, 0x62616452,
-0x6574537a, 0x0, 0x72784264, 0x4266537a,
-0x0, 0x2b6e756c, 0x6c5f6861, 0x6e646c65,
-0x72000000, 0x66774f70, 0x4661696c, 0x0,
-0x2b685f75, 0x70646174, 0x655f6c65, 0x64340000,
-0x2b685f75, 0x70646174, 0x655f6c65, 0x64360000,
-0x2b685f75, 0x70646174, 0x655f6c65, 0x64320000,
-0x696e7453, 0x74617465, 0x0, 0x2a2a696e,
-0x69744370, 0x0, 0x23736372, 0x65616d00,
-0x69537461, 0x636b4572, 0x0, 0x70726f62,
-0x654d656d, 0x0, 0x2a2a4441, 0x574e5f42,
-0x0, 0x2b73775f, 0x646d615f, 0x61737369,
-0x73745f70, 0x6c75735f, 0x74696d65, 0x72000000,
-0x2b267072, 0x656c6f61, 0x645f7772, 0x5f646573,
-0x63720000, 0x2b267072, 0x656c6f61, 0x645f7264,
-0x5f646573, 0x63720000, 0x2b685f68, 0x665f7469,
-0x6d657200, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7469, 0x6d65722e, 0x632c7620, 0x312e312e,
-0x322e3335, 0x20313939, 0x392f3031, 0x2f323720,
-0x31393a30, 0x393a3530, 0x20686179, 0x65732045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x542d446d, 0x61526432,
-0x0, 0x542d446d, 0x61526431, 0x0,
-0x542d446d, 0x61526442, 0x0, 0x542d446d,
-0x61577232, 0x0, 0x542d446d, 0x61577231,
-0x0, 0x542d446d, 0x61577242, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f636f, 0x6d6d616e, 0x642e632c, 0x7620312e,
-0x312e322e, 0x32382031, 0x3939392f, 0x30312f32,
-0x30203139, 0x3a34393a, 0x34392073, 0x6875616e,
-0x67204578, 0x70202400, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x3f48636d, 0x644d6278,
-0x0, 0x3f636d64, 0x48737453, 0x0,
-0x3f636d64, 0x4d634d64, 0x0, 0x3f636d64,
-0x50726f6d, 0x0, 0x3f636d64, 0x4c696e6b,
-0x0, 0x3f636d64, 0x45727200, 0x86ac,
-0x8e5c, 0x8e5c, 0x8de4, 0x8b78,
-0x8e30, 0x8e5c, 0x8790, 0x8800,
-0x8990, 0x8a68, 0x8a34, 0x8e5c,
-0x8870, 0x8b24, 0x8e5c, 0x8b34,
-0x87b4, 0x8824, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6d63, 0x6173742e, 0x632c7620, 0x312e312e,
-0x322e3820, 0x31393938, 0x2f31322f, 0x30382030,
-0x323a3336, 0x3a333620, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x6164644d, 0x63447570,
-0x0, 0x6164644d, 0x6346756c, 0x0,
-0x64656c4d, 0x634e6f45, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f646d, 0x612e632c, 0x7620312e, 0x312e322e,
-0x32342031, 0x3939382f, 0x31322f32, 0x31203030,
-0x3a33333a, 0x30392073, 0x6875616e, 0x67204578,
-0x70202400, 0x65767452, 0x6e674600, 0x51657674,
-0x46000000, 0x51657674, 0x505f4600, 0x4d657674,
-0x526e6746, 0x0, 0x4d516576, 0x74460000,
-0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46,
-0x0, 0x5173436f, 0x6e734600, 0x51725072,
-0x6f644600, 0x7377446d, 0x614f6666, 0x0,
-0x31446d61, 0x4f6e0000, 0x7377446d, 0x614f6e00,
-0x2372446d, 0x6141544e, 0x0, 0x72446d61,
-0x41544e30, 0x0, 0x72446d61, 0x41544e31,
-0x0, 0x72446d61, 0x34476200, 0x2a50414e,
-0x49432a00, 0x2e2e2f2e, 0x2e2f2e2e, 0x2f2e2e2f,
-0x2e2e2f73, 0x72632f6e, 0x69632f66, 0x77322f63,
-0x6f6d6d6f, 0x6e2f646d, 0x612e6300, 0x2377446d,
-0x6141544e, 0x0, 0x77446d61, 0x41544e30,
-0x0, 0x77446d61, 0x41544e31, 0x0,
-0x77446d61, 0x34476200, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7472, 0x6163652e, 0x632c7620, 0x312e312e,
-0x322e3520, 0x31393938, 0x2f30392f, 0x33302031,
-0x383a3530, 0x3a323820, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6461, 0x74612e63, 0x2c762031, 0x2e312e32,
-0x2e313220, 0x31393939, 0x2f30312f, 0x32302031,
-0x393a3439, 0x3a353120, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x46575f56, 0x45525349,
-0x4f4e3a20, 0x23312046, 0x72692041, 0x70722037,
-0x2031373a, 0x35373a35, 0x32205044, 0x54203230,
-0x30300000, 0x46575f43, 0x4f4d5049, 0x4c455f54,
-0x494d453a, 0x2031373a, 0x35373a35, 0x32000000,
-0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064,
-0x65767263, 0x73000000, 0x46575f43, 0x4f4d5049,
-0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465,
-0x0, 0x46575f43, 0x4f4d5049, 0x4c455f44,
-0x4f4d4149, 0x4e3a2065, 0x6e672e61, 0x6374656f,
-0x6e2e636f, 0x6d000000, 0x46575f43, 0x4f4d5049,
-0x4c45523a, 0x20676363, 0x20766572, 0x73696f6e,
-0x20322e37, 0x2e320000, 0x0, 0x12041100,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6d65, 0x6d2e632c, 0x7620312e, 0x312e322e,
-0x35203139, 0x39382f30, 0x392f3330, 0x2031383a,
-0x35303a30, 0x38207368, 0x75616e67, 0x20457870,
-0x20240000, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7365, 0x6e642e63, 0x2c762031, 0x2e312e32,
-0x2e343420, 0x31393938, 0x2f31322f, 0x32312030,
-0x303a3333, 0x3a313820, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x69736e74, 0x54637055,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f7265, 0x63762e63, 0x2c762031, 0x2e312e32,
-0x2e353320, 0x31393939, 0x2f30312f, 0x31362030,
-0x323a3535, 0x3a343320, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x724d6163, 0x43686b30,
-0x0, 0x72784672, 0x6d324c67, 0x0,
-0x72784e6f, 0x53744264, 0x0, 0x72784e6f,
-0x4d694264, 0x0, 0x72784e6f, 0x4a6d4264,
-0x0, 0x7278436b, 0x446d6146, 0x0,
-0x72785144, 0x6d457846, 0x0, 0x72785144,
-0x6d614600, 0x72785144, 0x4c426446, 0x0,
-0x72785144, 0x6d426446, 0x0, 0x72784372,
-0x63506164, 0x0, 0x72536d51, 0x446d6146,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f6d61, 0x632e632c, 0x7620312e, 0x312e322e,
-0x32322031, 0x3939382f, 0x31322f30, 0x38203032,
-0x3a33363a, 0x33302073, 0x6875616e, 0x67204578,
-0x70202400, 0x65767452, 0x6e674600, 0x51657674,
-0x46000000, 0x51657674, 0x505f4600, 0x4d657674,
-0x526e6746, 0x0, 0x4d516576, 0x74460000,
-0x4d516576, 0x505f4600, 0x5173436f, 0x6e495f46,
-0x0, 0x5173436f, 0x6e734600, 0x51725072,
-0x6f644600, 0x6d616354, 0x68726573, 0x0,
-0x23744d61, 0x6341544e, 0x0, 0x23724d61,
-0x6341544e, 0x0, 0x72656d41, 0x73737274,
-0x0, 0x6c696e6b, 0x444f574e, 0x0,
-0x6c696e6b, 0x55500000, 0x0, 0x0,
-0x0, 0x24486561, 0x6465723a, 0x202f7072,
-0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
-0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
-0x6e2f636b, 0x73756d2e, 0x632c7620, 0x312e312e,
-0x322e3920, 0x31393939, 0x2f30312f, 0x31342030,
-0x303a3033, 0x3a343820, 0x73687561, 0x6e672045,
-0x78702024, 0x0, 0x65767452, 0x6e674600,
-0x51657674, 0x46000000, 0x51657674, 0x505f4600,
-0x4d657674, 0x526e6746, 0x0, 0x4d516576,
-0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
-0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
-0x51725072, 0x6f644600, 0x0, 0x0,
-0x0, 0x50726f62, 0x65506879, 0x0,
-0x6c6e6b41, 0x53535254, 0x0, 0x109a4,
-0x10a1c, 0x10a50, 0x10a7c, 0x11050,
-0x10aa8, 0x10b10, 0x111fc, 0x10dc0,
-0x10c68, 0x10c80, 0x10cc4, 0x10cec,
-0x10d0c, 0x10d34, 0x111fc, 0x10dc0,
-0x10df8, 0x10e10, 0x10e40, 0x10e68,
-0x10e88, 0x10eb0, 0x0, 0x10fdc,
-0x11008, 0x1102c, 0x111fc, 0x11050,
-0x11078, 0x11108, 0x0, 0x0,
-0x0, 0x1186c, 0x1193c, 0x11a14,
-0x11ae4, 0x11b40, 0x11c1c, 0x11c44,
-0x11d20, 0x11d48, 0x11ef0, 0x11f18,
-0x120c0, 0x122b8, 0x1254c, 0x12460,
-0x1254c, 0x12578, 0x120e8, 0x12290,
-0x7273745f, 0x676d6969, 0x0, 0x12608,
-0x12640, 0x12728, 0x13374, 0x133b4,
-0x133cc, 0x7365746c, 0x6f6f7000, 0x0,
-0x0, 0x13bbc, 0x13bfc, 0x13c8c,
-0x13cd0, 0x13d34, 0x13dc0, 0x13df4,
-0x13e7c, 0x13f14, 0x13fe4, 0x14024,
-0x140a8, 0x140cc, 0x141dc, 0x646f4261,
-0x73655067, 0x0, 0x0, 0x0,
-0x0, 0x73746d61, 0x634c4e4b, 0x0,
-0x6765746d, 0x636c6e6b, 0x0, 0x14ed8,
-0x14ed8, 0x14b8c, 0x14bd8, 0x14c24,
-0x14ed8, 0x7365746d, 0x61636163, 0x74000000,
-0x0, 0x0 };
-static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __devinitdata = {
-0x1,
-0x1, 0x1, 0xc001fc, 0x3ffc,
-0xc00000, 0x416c7465, 0x6f6e2041, 0x63654e49,
-0x43205600, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x416c7465,
-0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242,
-0x0, 0x0, 0x0, 0x1ffffc,
-0x1fff7c, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x60cf00,
-0x60, 0xcf000000, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x3, 0x0,
-0x1, 0x0, 0x0, 0x0,
-0x1, 0x0, 0x1, 0x0,
-0x0, 0x0, 0x0, 0x1,
-0x1, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x1000000, 0x21000000,
-0x12000140, 0x0, 0x0, 0x20000000,
-0x120000a0, 0x0, 0x12000060, 0x12000180,
-0x120001e0, 0x0, 0x0, 0x0,
-0x1, 0x0, 0x0, 0x0,
-0x0, 0x0, 0x0, 0x2,
-0x0, 0x0, 0x30001, 0x1,
-0x30201, 0x0, 0x0, 0x1010101,
-0x1010100, 0x10100, 0x1010001, 0x10001,
-0x1000101, 0x101, 0x0, 0x0 };
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
index 0a0e0cd81a2..4ce6ca5f3d3 100644
--- a/drivers/net/appletalk/Kconfig
+++ b/drivers/net/appletalk/Kconfig
@@ -18,7 +18,7 @@ config ATALK
General information about how to connect Linux, Windows machines and
Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>. The
- NET-3-HOWTO, available from
+ NET3-4-HOWTO, available from
<http://www.tldp.org/docs.html#howto>, contains valuable
information as well.
@@ -106,20 +106,4 @@ config IPDDP_ENCAP
IP packets inside AppleTalk frames; this is useful if your Linux box
is stuck on an AppleTalk network (which hopefully contains a
decapsulator somewhere). Please see
- <file:Documentation/networking/ipddp.txt> for more information. If
- you said Y to "AppleTalk-IP driver support" above and you say Y
- here, then you cannot say Y to "AppleTalk-IP to IP Decapsulation
- support", below.
-
-config IPDDP_DECAP
- bool "Appletalk-IP to IP Decapsulation support"
- depends on IPDDP
- help
- If you say Y here, the AppleTalk-IP code will be able to decapsulate
- AppleTalk-IP frames to IP packets; this is useful if you want your
- Linux box to act as an Internet gateway for an AppleTalk network.
- Please see <file:Documentation/networking/ipddp.txt> for more
- information. If you said Y to "AppleTalk-IP driver support" above
- and you say Y here, then you cannot say Y to "IP to AppleTalk-IP
- Encapsulation support", above.
-
+ <file:Documentation/networking/ipddp.txt> for more information.
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index a0b4c851607..7f2a032c354 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -4,7 +4,7 @@
* - Jay Schulist <jschlst@samba.org>
*
* With more than a little help from;
- * - Alan Cox <Alan.Cox@linux.org>
+ * - Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* Derived from:
* - skeleton.c: A network driver outline for linux.
@@ -56,7 +56,6 @@ static const char *version =
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -71,7 +70,6 @@ static const char *version =
#include <linux/bitops.h>
#include <linux/jiffies.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -120,7 +118,7 @@ static int irq = 5; /* Default IRQ */
* DAYNA driver mode:
* Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95,
* Farallon PhoneNET PC III, Farallon PhoneNET PC II
- * Other cards possibly supported mode unkown though:
+ * Other cards possibly supported mode unknown though:
* Dayna DL2000 (Full length), COPS LT/M (Micro-Channel)
*
* Cards NOT supported by this driver but supported by the ltpc.c
@@ -171,7 +169,6 @@ static unsigned int cops_debug = COPS_DEBUG;
struct cops_local
{
- struct net_device_stats stats;
int board; /* Holds what board type is. */
int nodeid; /* Set to 1 once have nodeid. */
unsigned char node_acquire; /* Node ID when acquired. */
@@ -193,11 +190,11 @@ static irqreturn_t cops_interrupt (int irq, void *dev_id);
static void cops_poll (unsigned long ltdev);
static void cops_timeout(struct net_device *dev);
static void cops_rx (struct net_device *dev);
-static int cops_send_packet (struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t cops_send_packet (struct sk_buff *skb,
+ struct net_device *dev);
static void set_multicast_list (struct net_device *dev);
static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int cops_close (struct net_device *dev);
-static struct net_device_stats *cops_get_stats (struct net_device *dev);
static void cleanup_card(struct net_device *dev)
{
@@ -260,6 +257,15 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops cops_netdev_ops = {
+ .ndo_open = cops_open,
+ .ndo_stop = cops_close,
+ .ndo_start_xmit = cops_send_packet,
+ .ndo_tx_timeout = cops_timeout,
+ .ndo_do_ioctl = cops_ioctl,
+ .ndo_set_rx_mode = set_multicast_list,
+};
+
/*
* This is the real probe routine. Linux has a history of friendly device
* probes on the ISA bus. A good device probes avoids doing writes, and
@@ -320,7 +326,7 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
/* Reserve any actual interrupt. */
if (dev->irq) {
- retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev);
+ retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev);
if (retval)
goto err_out;
}
@@ -333,16 +339,9 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
/* Copy local board variable to lp struct. */
lp->board = board;
- dev->hard_start_xmit = cops_send_packet;
- dev->tx_timeout = cops_timeout;
+ dev->netdev_ops = &cops_netdev_ops;
dev->watchdog_timeo = HZ * 2;
- dev->get_stats = cops_get_stats;
- dev->open = cops_open;
- dev->stop = cops_close;
- dev->do_ioctl = cops_ioctl;
- dev->set_multicast_list = set_multicast_list;
- dev->mc_list = NULL;
/* Tell the user where the card is and what mode we're in. */
if(board==DAYNA)
@@ -593,8 +592,6 @@ static void cops_load (struct net_device *dev)
tangent_wait_reset(ioaddr);
inb(ioaddr); /* Clear initial ready signal. */
}
-
- return;
}
/*
@@ -701,8 +698,6 @@ static void cops_poll(unsigned long ltdev)
/* poll 20 times per second */
cops_timer.expires = jiffies + HZ/20;
add_timer(&cops_timer);
-
- return;
}
/*
@@ -797,7 +792,7 @@ static void cops_rx(struct net_device *dev)
{
printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
dev->name);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
while(pkt_len--) /* Discard packet */
inb(ioaddr);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -819,7 +814,7 @@ static void cops_rx(struct net_device *dev)
{
printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n",
dev->name, pkt_len);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb_any(skb);
return;
}
@@ -836,7 +831,7 @@ static void cops_rx(struct net_device *dev)
if(rsp_type != LAP_RESPONSE)
{
printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb_any(skb);
return;
}
@@ -846,12 +841,11 @@ static void cops_rx(struct net_device *dev)
skb_reset_transport_header(skb); /* Point to data (Skip header). */
/* Update the counters. */
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
/* Send packet to a higher place. */
netif_rx(skb);
- dev->last_rx = jiffies;
}
static void cops_timeout(struct net_device *dev)
@@ -859,7 +853,7 @@ static void cops_timeout(struct net_device *dev)
struct cops_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if(lp->board==TANGENT)
{
if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
@@ -867,7 +861,7 @@ static void cops_timeout(struct net_device *dev)
}
printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
cops_jumpstart(dev); /* Restart the card. */
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue(dev);
}
@@ -876,7 +870,8 @@ static void cops_timeout(struct net_device *dev)
* Make the card transmit a LocalTalk packet.
*/
-static int cops_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t cops_send_packet(struct sk_buff *skb,
+ struct net_device *dev)
{
struct cops_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
@@ -917,11 +912,10 @@ static int cops_send_packet(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */
/* Done sending packet, update counters and cleanup. */
- lp->stats.tx_packets++;
- lp->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev_kfree_skb (skb);
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -942,7 +936,7 @@ static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct cops_local *lp = netdev_priv(dev);
struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr;
- struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr;
+ struct atalk_addr *aa = &lp->node_addr;
switch(cmd)
{
@@ -987,15 +981,6 @@ static int cops_close(struct net_device *dev)
return 0;
}
-/*
- * Get the current statistics.
- * This may be called with the card open or closed.
- */
-static struct net_device_stats *cops_get_stats(struct net_device *dev)
-{
- struct cops_local *lp = netdev_priv(dev);
- return &lp->stats;
-}
#ifdef MODULE
static struct net_device *cops_dev;
@@ -1011,9 +996,7 @@ static int __init cops_module_init(void)
printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
cardname);
cops_dev = cops_probe(-1);
- if (IS_ERR(cops_dev))
- return PTR_ERR(cops_dev);
- return 0;
+ return PTR_ERR_OR_ZERO(cops_dev);
}
static void __exit cops_module_exit(void)
@@ -1025,11 +1008,3 @@ static void __exit cops_module_exit(void)
module_init(cops_module_init);
module_exit(cops_module_exit);
#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -c cops.c"
- * c-basic-offset: 4
- * c-file-offsets: ((substatement-open . 0))
- * End:
- */
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index 1071144edd6..10d0dba572c 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -31,6 +31,7 @@
#include <linux/ip.h>
#include <linux/atalk.h>
#include <linux/if_arp.h>
+#include <linux/slab.h>
#include <net/route.h>
#include <asm/uaccess.h>
@@ -39,6 +40,7 @@
static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n";
static struct ipddp_route *ipddp_route_list;
+static DEFINE_SPINLOCK(ipddp_route_lock);
#ifdef CONFIG_IPDDP_ENCAP
static int ipddp_mode = IPDDP_ENCAP;
@@ -47,13 +49,20 @@ static int ipddp_mode = IPDDP_DECAP;
#endif
/* Index to functions, as function prototypes. */
-static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *ipddp_get_stats(struct net_device *dev);
+static netdev_tx_t ipddp_xmit(struct sk_buff *skb,
+ struct net_device *dev);
static int ipddp_create(struct ipddp_route *new_rt);
static int ipddp_delete(struct ipddp_route *rt);
-static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt);
+static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt);
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+static const struct net_device_ops ipddp_netdev_ops = {
+ .ndo_start_xmit = ipddp_xmit,
+ .ndo_do_ioctl = ipddp_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static struct net_device * __init ipddp_init(void)
{
@@ -61,19 +70,18 @@ static struct net_device * __init ipddp_init(void)
struct net_device *dev;
int err;
- dev = alloc_etherdev(sizeof(struct net_device_stats));
+ dev = alloc_etherdev(0);
if (!dev)
return ERR_PTR(-ENOMEM);
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
strcpy(dev->name, "ipddp%d");
if (version_printed++ == 0)
printk(version);
- /* Initalize the device structure. */
- dev->hard_start_xmit = ipddp_xmit;
- dev->get_stats = ipddp_get_stats;
- dev->do_ioctl = ipddp_ioctl;
+ /* Initialize the device structure. */
+ dev->netdev_ops = &ipddp_netdev_ops;
dev->type = ARPHRD_IPDDP; /* IP over DDP tunnel */
dev->mtu = 585;
@@ -103,24 +111,19 @@ static struct net_device * __init ipddp_init(void)
return dev;
}
-/*
- * Get the current statistics. This may be called with the card open or closed.
- */
-static struct net_device_stats *ipddp_get_stats(struct net_device *dev)
-{
- return dev->priv;
-}
/*
* Transmit LLAP/ELAP frame using aarp_send_ddp.
*/
-static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
{
- __be32 paddr = ((struct rtable*)skb->dst)->rt_gateway;
+ __be32 paddr = skb_rtable(skb)->rt_gateway;
struct ddpehdr *ddp;
struct ipddp_route *rt;
struct atalk_addr *our_addr;
+ spin_lock(&ipddp_route_lock);
+
/*
* Find appropriate route to use, based only on IP number.
*/
@@ -129,8 +132,10 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
if(rt->ip == paddr)
break;
}
- if(rt == NULL)
- return 0;
+ if(rt == NULL) {
+ spin_unlock(&ipddp_route_lock);
+ return NETDEV_TX_OK;
+ }
our_addr = atalk_find_dev_addr(rt->dev);
@@ -170,13 +175,14 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */
- ((struct net_device_stats *) dev->priv)->tx_packets++;
- ((struct net_device_stats *) dev->priv)->tx_bytes+=skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
- if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0)
- dev_kfree_skb(skb);
+ aarp_send_ddp(rt->dev, skb, &rt->at, NULL);
- return 0;
+ spin_unlock(&ipddp_route_lock);
+
+ return NETDEV_TX_OK;
}
/*
@@ -198,7 +204,9 @@ static int ipddp_create(struct ipddp_route *new_rt)
return -ENETUNREACH;
}
- if (ipddp_find_route(rt)) {
+ spin_lock_bh(&ipddp_route_lock);
+ if (__ipddp_find_route(rt)) {
+ spin_unlock_bh(&ipddp_route_lock);
kfree(rt);
return -EEXIST;
}
@@ -206,6 +214,8 @@ static int ipddp_create(struct ipddp_route *new_rt)
rt->next = ipddp_route_list;
ipddp_route_list = rt;
+ spin_unlock_bh(&ipddp_route_lock);
+
return 0;
}
@@ -218,44 +228,47 @@ static int ipddp_delete(struct ipddp_route *rt)
struct ipddp_route **r = &ipddp_route_list;
struct ipddp_route *tmp;
+ spin_lock_bh(&ipddp_route_lock);
while((tmp = *r) != NULL)
{
- if(tmp->ip == rt->ip
- && tmp->at.s_net == rt->at.s_net
- && tmp->at.s_node == rt->at.s_node)
+ if(tmp->ip == rt->ip &&
+ tmp->at.s_net == rt->at.s_net &&
+ tmp->at.s_node == rt->at.s_node)
{
*r = tmp->next;
+ spin_unlock_bh(&ipddp_route_lock);
kfree(tmp);
return 0;
}
r = &tmp->next;
}
- return (-ENOENT);
+ spin_unlock_bh(&ipddp_route_lock);
+ return -ENOENT;
}
/*
* Find a routing entry, we only return a FULL match
*/
-static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
+static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt)
{
struct ipddp_route *f;
for(f = ipddp_route_list; f != NULL; f = f->next)
{
- if(f->ip == rt->ip
- && f->at.s_net == rt->at.s_net
- && f->at.s_node == rt->at.s_node)
- return (f);
+ if(f->ip == rt->ip &&
+ f->at.s_net == rt->at.s_net &&
+ f->at.s_node == rt->at.s_node)
+ return f;
}
- return (NULL);
+ return NULL;
}
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct ipddp_route __user *rt = ifr->ifr_data;
- struct ipddp_route rcp;
+ struct ipddp_route rcp, rcp2, *rp;
if(!capable(CAP_NET_ADMIN))
return -EPERM;
@@ -266,15 +279,25 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch(cmd)
{
case SIOCADDIPDDPRT:
- return (ipddp_create(&rcp));
+ return ipddp_create(&rcp);
case SIOCFINDIPDDPRT:
- if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route)))
- return -EFAULT;
- return 0;
+ spin_lock_bh(&ipddp_route_lock);
+ rp = __ipddp_find_route(&rcp);
+ if (rp)
+ memcpy(&rcp2, rp, sizeof(rcp2));
+ spin_unlock_bh(&ipddp_route_lock);
+
+ if (rp) {
+ if (copy_to_user(rt, &rcp2,
+ sizeof(struct ipddp_route)))
+ return -EFAULT;
+ return 0;
+ } else
+ return -ENOENT;
case SIOCDELIPDDPRT:
- return (ipddp_delete(&rcp));
+ return ipddp_delete(&rcp);
default:
return -EINVAL;
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index fef5560bc7a..01e2ac55c13 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -215,7 +215,6 @@ static int dma;
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -228,8 +227,8 @@ static int dma;
#include <linux/timer.h>
#include <linux/atalk.h>
#include <linux/bitops.h>
+#include <linux/gfp.h>
-#include <asm/system.h>
#include <asm/dma.h>
#include <asm/io.h>
@@ -261,7 +260,6 @@ static unsigned char *ltdmacbuf;
struct ltpc_private
{
- struct net_device_stats stats;
struct atalk_addr my_addr;
};
@@ -642,7 +640,6 @@ done:
inb_p(base+7);
inb_p(base+7);
}
- return;
}
@@ -654,9 +651,9 @@ static int do_write(struct net_device *dev, void *cbuf, int cbuflen,
int ret;
if(i) {
- qels[i].cbuf = (unsigned char *) cbuf;
+ qels[i].cbuf = cbuf;
qels[i].cbuflen = cbuflen;
- qels[i].dbuf = (unsigned char *) dbuf;
+ qels[i].dbuf = dbuf;
qels[i].dbuflen = dbuflen;
qels[i].QWrite = 1;
qels[i].mailbox = i; /* this should be initted rather */
@@ -678,9 +675,9 @@ static int do_read(struct net_device *dev, void *cbuf, int cbuflen,
int ret;
if(i) {
- qels[i].cbuf = (unsigned char *) cbuf;
+ qels[i].cbuf = cbuf;
qels[i].cbuflen = cbuflen;
- qels[i].dbuf = (unsigned char *) dbuf;
+ qels[i].dbuf = dbuf;
qels[i].dbuflen = dbuflen;
qels[i].QWrite = 0;
qels[i].mailbox = i; /* this should be initted rather */
@@ -698,8 +695,7 @@ static int do_read(struct net_device *dev, void *cbuf, int cbuflen,
static struct timer_list ltpc_timer;
-static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *ltpc_get_stats(struct net_device *dev);
+static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev);
static int read_30 ( struct net_device *dev)
{
@@ -726,12 +722,11 @@ static int sendup_buffer (struct net_device *dev)
int dnode, snode, llaptype, len;
int sklen;
struct sk_buff *skb;
- struct net_device_stats *stats = &((struct ltpc_private *)dev->priv)->stats;
struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf;
if (ltc->command != LT_RCVLAP) {
printk("unknown command 0x%02x from ltpc card\n",ltc->command);
- return(-1);
+ return -1;
}
dnode = ltc->dnode;
snode = ltc->snode;
@@ -778,12 +773,11 @@ static int sendup_buffer (struct net_device *dev)
skb_reset_transport_header(skb);
- stats->rx_packets++;
- stats->rx_bytes+=skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
/* toss it onwards */
netif_rx(skb);
- dev->last_rx = jiffies;
return 0;
}
@@ -823,7 +817,8 @@ static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr;
/* we'll keep the localtalk node address in dev->pa_addr */
- struct atalk_addr *aa = &((struct ltpc_private *)dev->priv)->my_addr;
+ struct ltpc_private *ltpc_priv = netdev_priv(dev);
+ struct atalk_addr *aa = &ltpc_priv->my_addr;
struct lt_init c;
int ltflags;
@@ -898,14 +893,11 @@ static void ltpc_poll(unsigned long l)
/* DDP to LLAP translation */
-static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
{
/* in kernel 1.3.xx, on entry skb->data points to ddp header,
* and skb->len is the length of the ddp data + ddp header
*/
-
- struct net_device_stats *stats = &((struct ltpc_private *)dev->priv)->stats;
-
int i;
struct lt_sendlap cbuf;
unsigned char *hdr;
@@ -934,17 +926,11 @@ static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
printk("\n");
}
- stats->tx_packets++;
- stats->tx_bytes+=skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev_kfree_skb(skb);
- return 0;
-}
-
-static struct net_device_stats *ltpc_get_stats(struct net_device *dev)
-{
- struct net_device_stats *stats = &((struct ltpc_private *) dev->priv)->stats;
- return stats;
+ return NETDEV_TX_OK;
}
/* initialization stuff */
@@ -1024,6 +1010,12 @@ static int __init ltpc_probe_dma(int base, int dma)
return (want & 2) ? 3 : 1;
}
+static const struct net_device_ops ltpc_netdev = {
+ .ndo_start_xmit = ltpc_xmit,
+ .ndo_do_ioctl = ltpc_ioctl,
+ .ndo_set_rx_mode = set_multicast_list,
+};
+
struct net_device * __init ltpc_probe(void)
{
struct net_device *dev;
@@ -1130,15 +1122,7 @@ struct net_device * __init ltpc_probe(void)
else
printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma);
- /* Fill in the fields of the device structure with ethernet-generic values. */
- dev->hard_start_xmit = ltpc_xmit;
- dev->get_stats = ltpc_get_stats;
-
- /* add the ltpc-specific things */
- dev->do_ioctl = &ltpc_ioctl;
-
- dev->set_multicast_list = &set_multicast_list;
- dev->mc_list = NULL;
+ dev->netdev_ops = &ltpc_netdev;
dev->base_addr = io;
dev->irq = irq;
dev->dma = dma;
@@ -1171,7 +1155,7 @@ struct net_device * __init ltpc_probe(void)
}
/* grab it and don't let go :-) */
- if (irq && request_irq( irq, &ltpc_interrupt, 0, "ltpc", dev) >= 0)
+ if (irq && request_irq( irq, ltpc_interrupt, 0, "ltpc", dev) >= 0)
{
(void) inb_p(io+7); /* enable interrupts from board */
(void) inb_p(io+7); /* and reset irq line */
@@ -1233,7 +1217,7 @@ static int __init ltpc_setup(char *str)
if (ints[0] > 2) {
dma = ints[3];
}
- /* ignore any other paramters */
+ /* ignore any other parameters */
}
return 1;
}
@@ -1259,9 +1243,7 @@ static int __init ltpc_module_init(void)
"ltpc: Autoprobing is not recommended for modules\n");
dev_ltpc = ltpc_probe();
- if (IS_ERR(dev_ltpc))
- return PTR_ERR(dev_ltpc);
- return 0;
+ return PTR_ERR_OR_ZERO(dev_ltpc);
}
module_init(ltpc_module_init);
#endif
diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
index 3b2f7f11546..84fb6349a59 100644
--- a/drivers/net/arcnet/Kconfig
+++ b/drivers/net/arcnet/Kconfig
@@ -3,7 +3,7 @@
#
menuconfig ARCNET
- depends on NETDEVICES && (ISA || PCI)
+ depends on NETDEVICES && (ISA || PCI || PCMCIA)
tristate "ARCnet support"
---help---
If you have a network card of this type, say Y and check out the
@@ -123,4 +123,14 @@ config ARCNET_COM20020_PCI
tristate "Support for COM20020 on PCI"
depends on ARCNET_COM20020 && PCI
+config ARCNET_COM20020_CS
+ tristate "COM20020 ARCnet PCMCIA support"
+ depends on ARCNET_COM20020 && PCMCIA
+ help
+ Say Y here if you intend to attach this type of ARCnet PCMCIA card
+ to your computer.
+
+ To compile this driver as a module, choose M here: the module will be
+ called com20020_cs. If unsure, say N.
+
endif # ARCNET
diff --git a/drivers/net/arcnet/Makefile b/drivers/net/arcnet/Makefile
index 5861af543d4..5ce8ee63e43 100644
--- a/drivers/net/arcnet/Makefile
+++ b/drivers/net/arcnet/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_ARCNET_RIM_I) += arc-rimi.o
obj-$(CONFIG_ARCNET_COM20020) += com20020.o
obj-$(CONFIG_ARCNET_COM20020_ISA) += com20020-isa.o
obj-$(CONFIG_ARCNET_COM20020_PCI) += com20020-pci.o
+obj-$(CONFIG_ARCNET_COM20020_CS) += com20020_cs.o
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
index e0a18e7c73c..705e6ce2eb9 100644
--- a/drivers/net/arcnet/arc-rawmode.c
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -25,6 +25,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
@@ -87,7 +88,7 @@ MODULE_LICENSE("GPL");
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct sk_buff *skb;
struct archdr *pkt = pkthdr;
int ofs;
@@ -102,7 +103,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -122,10 +123,8 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- skb->protocol = __constant_htons(ETH_P_ARCNET);
-;
+ skb->protocol = cpu_to_be16(ETH_P_ARCNET);
netif_rx(skb);
- dev->last_rx = jiffies;
}
@@ -168,7 +167,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct arc_hardware *hard = &pkt->hard;
int ofs;
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
index 8c8d6c453c4..b8b4c7ba884 100644
--- a/drivers/net/arcnet/arc-rimi.c
+++ b/drivers/net/arcnet/arc-rimi.c
@@ -28,11 +28,11 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/bootmem.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
#include <linux/arcdevice.h>
@@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev)
BUGLVL(D_NORMAL) printk(VERSION);
BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
- BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n",
+ BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n",
dev->dev_addr[0], dev->mem_start, dev->irq);
if (dev->mem_start <= 0 || dev->irq <= 0) {
- BUGMSG(D_NORMAL, "No autoprobe for RIM I; you "
+ BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you "
"must specify the shmem and irq!\n");
return -ENODEV;
}
if (dev->dev_addr[0] == 0) {
- BUGMSG(D_NORMAL, "You need to specify your card's station "
+ BUGLVL(D_NORMAL) printk("You need to specify your card's station "
"ID!\n");
return -ENODEV;
}
@@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev)
* will be taken.
*/
if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) {
- BUGMSG(D_NORMAL, "Card memory already allocated\n");
+ BUGLVL(D_NORMAL) printk("Card memory already allocated\n");
return -ENODEV;
}
return arcrimi_found(dev);
@@ -156,7 +156,7 @@ static int __init arcrimi_found(struct net_device *dev)
}
/* reserve the irq */
- if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
+ if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
iounmap(p);
release_mem_region(dev->mem_start, MIRROR_SIZE);
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
@@ -174,9 +174,9 @@ static int __init arcrimi_found(struct net_device *dev)
* 2k (or there are no mirrors at all) but on some, it's 4k.
*/
mirror_size = MIRROR_SIZE;
- if (readb(p) == TESTvalue
- && check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0
- && check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
+ if (readb(p) == TESTvalue &&
+ check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
+ check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
mirror_size = 2 * MIRROR_SIZE;
first_mirror = shmem - mirror_size;
@@ -194,7 +194,7 @@ static int __init arcrimi_found(struct net_device *dev)
/* initialize the rest of the device structure. */
- lp = dev->priv;
+ lp = netdev_priv(dev);
lp->card_name = "RIM I";
lp->hw.command = arcrimi_command;
lp->hw.status = arcrimi_status;
@@ -260,7 +260,7 @@ err_free_irq:
*/
static int arcrimi_reset(struct net_device *dev, int really_reset)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->mem_start + 0x800;
BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
@@ -281,7 +281,7 @@ static int arcrimi_reset(struct net_device *dev, int really_reset)
static void arcrimi_setmask(struct net_device *dev, int mask)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->mem_start + 0x800;
AINTMASK(mask);
@@ -289,7 +289,7 @@ static void arcrimi_setmask(struct net_device *dev, int mask)
static int arcrimi_status(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->mem_start + 0x800;
return ASTATUS();
@@ -297,7 +297,7 @@ static int arcrimi_status(struct net_device *dev)
static void arcrimi_command(struct net_device *dev, int cmd)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *ioaddr = lp->mem_start + 0x800;
ACOMMAND(cmd);
@@ -306,7 +306,7 @@ static void arcrimi_command(struct net_device *dev, int cmd)
static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
}
@@ -315,7 +315,7 @@ static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
}
@@ -361,7 +361,7 @@ static int __init arc_rimi_init(void)
static void __exit arc_rimi_exit(void)
{
struct net_device *dev = my_dev;
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
unregister_netdev(dev);
iounmap(lp->mem_start);
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index bdc4c0bb56d..a956053608f 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -95,17 +95,16 @@ EXPORT_SYMBOL(arcnet_unregister_proto);
EXPORT_SYMBOL(arcnet_debug);
EXPORT_SYMBOL(alloc_arcdev);
EXPORT_SYMBOL(arcnet_interrupt);
+EXPORT_SYMBOL(arcnet_open);
+EXPORT_SYMBOL(arcnet_close);
+EXPORT_SYMBOL(arcnet_send_packet);
+EXPORT_SYMBOL(arcnet_timeout);
/* Internal function prototypes */
-static int arcnet_open(struct net_device *dev);
-static int arcnet_close(struct net_device *dev);
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev);
-static void arcnet_timeout(struct net_device *dev);
static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned len);
static int arcnet_rebuild_header(struct sk_buff *skb);
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
static int go_tx(struct net_device *dev);
static int debug = ARCNET_DEBUG;
@@ -159,15 +158,12 @@ module_exit(arcnet_exit);
void arcnet_dump_skb(struct net_device *dev,
struct sk_buff *skb, char *desc)
{
- int i;
+ char hdr[32];
- printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc);
- for (i = 0; i < skb->len; i++) {
- if (i % 16 == 0)
- printk("\n" KERN_DEBUG "[%04X] ", i);
- printk("%02X ", ((u_char *) skb->data)[i]);
- }
- printk("\n");
+ /* dump the packet */
+ snprintf(hdr, sizeof(hdr), "%6s:%s skb->data:", dev->name, desc);
+ print_hex_dump(KERN_DEBUG, hdr, DUMP_PREFIX_OFFSET,
+ 16, 1, skb->data, skb->len, true);
}
EXPORT_SYMBOL(arcnet_dump_skb);
@@ -181,10 +177,11 @@ EXPORT_SYMBOL(arcnet_dump_skb);
static void arcnet_dump_packet(struct net_device *dev, int bufnum,
char *desc, int take_arcnet_lock)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int i, length;
unsigned long flags = 0;
static uint8_t buf[512];
+ char hdr[32];
/* hw.copy_from_card expects IRQ context so take the IRQ lock
to keep it single threaded */
@@ -198,14 +195,10 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum,
/* if the offset[0] byte is nonzero, this is a 256-byte packet */
length = (buf[2] ? 256 : 512);
- printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc);
- for (i = 0; i < length; i++) {
- if (i % 16 == 0)
- printk("\n" KERN_DEBUG "[%04X] ", i);
- printk("%02X ", buf[i]);
- }
- printk("\n");
-
+ /* dump the packet */
+ snprintf(hdr, sizeof(hdr), "%6s:%s packet dump:", dev->name, desc);
+ print_hex_dump(KERN_DEBUG, hdr, DUMP_PREFIX_OFFSET,
+ 16, 1, buf, length, true);
}
#else
@@ -247,7 +240,7 @@ void arcnet_unregister_proto(struct ArcProto *proto)
*/
static void release_arcbuf(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int i;
lp->buf_queue[lp->first_free_buf++] = bufnum;
@@ -269,7 +262,7 @@ static void release_arcbuf(struct net_device *dev, int bufnum)
*/
static int get_arcbuf(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int buf = -1, i;
if (!atomic_dec_and_test(&lp->buf_lock)) {
@@ -308,8 +301,8 @@ static int choose_mtu(void)
/* choose the smallest MTU of all available encaps */
for (count = 0; count < 256; count++) {
- if (arc_proto_map[count] != &arc_proto_null
- && arc_proto_map[count]->mtu < mtu) {
+ if (arc_proto_map[count] != &arc_proto_null &&
+ arc_proto_map[count]->mtu < mtu) {
mtu = arc_proto_map[count]->mtu;
}
}
@@ -322,11 +315,18 @@ static const struct header_ops arcnet_header_ops = {
.rebuild = arcnet_rebuild_header,
};
+static const struct net_device_ops arcnet_netdev_ops = {
+ .ndo_open = arcnet_open,
+ .ndo_stop = arcnet_close,
+ .ndo_start_xmit = arcnet_send_packet,
+ .ndo_tx_timeout = arcnet_timeout,
+};
/* Setup a struct device for ARCnet. */
static void arcdev_setup(struct net_device *dev)
{
dev->type = ARPHRD_ARCNET;
+ dev->netdev_ops = &arcnet_netdev_ops;
dev->header_ops = &arcnet_header_ops;
dev->hard_header_len = sizeof(struct archdr);
dev->mtu = choose_mtu();
@@ -339,25 +339,16 @@ static void arcdev_setup(struct net_device *dev)
/* New-style flags. */
dev->flags = IFF_BROADCAST;
- /*
- * Put in this stuff here, so we don't have to export the symbols to
- * the chipset drivers.
- */
- dev->open = arcnet_open;
- dev->stop = arcnet_close;
- dev->hard_start_xmit = arcnet_send_packet;
- dev->tx_timeout = arcnet_timeout;
- dev->get_stats = arcnet_get_stats;
}
-struct net_device *alloc_arcdev(char *name)
+struct net_device *alloc_arcdev(const char *name)
{
struct net_device *dev;
dev = alloc_netdev(sizeof(struct arcnet_local),
name && *name ? name : "arc%d", arcdev_setup);
if(dev) {
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
spin_lock_init(&lp->lock);
}
@@ -372,9 +363,9 @@ struct net_device *alloc_arcdev(char *name)
* that "should" only need to be set once at boot, so that there is
* non-reboot way to recover if something goes wrong.
*/
-static int arcnet_open(struct net_device *dev)
+int arcnet_open(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int count, newmtu, error;
BUGMSG(D_INIT,"opened.");
@@ -383,7 +374,6 @@ static int arcnet_open(struct net_device *dev)
return -ENODEV;
BUGLVL(D_PROTO) {
- int count;
BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
arc_proto_default->suffix);
for (count = 0; count < 256; count++)
@@ -442,24 +432,24 @@ static int arcnet_open(struct net_device *dev)
BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse "
"DOS networking programs!\n");
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (ASTATUS() & RESETflag) {
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
ACOMMAND(CFLAGScmd | RESETclear);
}
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
/* make sure we're ready to receive IRQ's. */
AINTMASK(0);
udelay(1); /* give it time to set the mask before
* we reset it again. (may not even be
* necessary)
*/
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->intmask = NORXflag | RECONflag;
AINTMASK(lp->intmask);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
netif_start_queue(dev);
@@ -472,9 +462,9 @@ static int arcnet_open(struct net_device *dev)
/* The inverse routine to arcnet_open - shuts down the card. */
-static int arcnet_close(struct net_device *dev)
+int arcnet_close(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
netif_stop_queue(dev);
@@ -556,7 +546,7 @@ static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
static int arcnet_rebuild_header(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int status = 0; /* default is failure */
unsigned short type;
uint8_t daddr=0;
@@ -583,8 +573,8 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
} else {
BUGMSG(D_NORMAL,
"I don't understand ethernet protocol %Xh addresses!\n", type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
}
/* if we couldn't resolve the address... give up. */
@@ -601,9 +591,10 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
/* Called by the kernel in order to transmit a packet. */
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
+ struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct archdr *pkt;
struct arc_rfc1201 *soft;
struct ArcProto *proto;
@@ -645,7 +636,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
!proto->ack_tx) {
/* done right away and we don't want to acknowledge
the package later - forget about it now */
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
freeskb = 1;
} else {
/* do it the 'split' way */
@@ -663,21 +654,20 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
}
}
retval = NETDEV_TX_OK;
- dev->trans_start = jiffies;
lp->next_tx = txbuf;
} else {
retval = NETDEV_TX_BUSY;
freeskb = 0;
}
- BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
/* make sure we didn't ignore a TX IRQ while we were in here */
AINTMASK(0);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->intmask |= TXFREEflag|EXCNAKflag;
AINTMASK(lp->intmask);
- BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+ BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
spin_unlock_irqrestore(&lp->lock, flags);
if (freeskb) {
@@ -693,7 +683,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
*/
static int go_tx(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
@@ -709,7 +699,7 @@ static int go_tx(struct net_device *dev)
/* start sending */
ACOMMAND(TXcmd | (lp->cur_tx << 3));
- lp->stats.tx_packets++;
+ dev->stats.tx_packets++;
lp->lasttrans_dest = lp->lastload_dest;
lp->lastload_dest = 0;
lp->excnak_pending = 0;
@@ -720,10 +710,10 @@ static int go_tx(struct net_device *dev)
/* Called by the kernel when transmit times out */
-static void arcnet_timeout(struct net_device *dev)
+void arcnet_timeout(struct net_device *dev)
{
unsigned long flags;
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int status = ASTATUS();
char *msg;
@@ -732,11 +722,11 @@ static void arcnet_timeout(struct net_device *dev)
msg = " - missed IRQ?";
} else {
msg = "";
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
lp->timed_out = 1;
ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
}
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* make sure we didn't miss a TX or a EXC NAK IRQ */
AINTMASK(0);
@@ -771,8 +761,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
BUGMSG(D_DURING, "\n");
BUGMSG(D_DURING, "in arcnet_interrupt\n");
-
- lp = dev->priv;
+
+ lp = netdev_priv(dev);
BUG_ON(!lp);
spin_lock(&lp->lock);
@@ -798,7 +788,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
diagstatus = (status >> 8) & 0xFF;
BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
- __FILE__,__LINE__,__FUNCTION__,status);
+ __FILE__,__LINE__,__func__,status);
didsomething = 0;
/*
@@ -865,8 +855,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
"transmit was not acknowledged! "
"(status=%Xh, dest=%02Xh)\n",
status, lp->lasttrans_dest);
- lp->stats.tx_errors++;
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
} else {
BUGMSG(D_DURING,
"broadcast was not acknowledged; that's normal "
@@ -905,7 +895,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
if (txbuf != -1) {
if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
/* that was the last segment */
- lp->stats.tx_bytes += lp->outgoing.skb->len;
+ dev->stats.tx_bytes += lp->outgoing.skb->len;
if(!lp->outgoing.proto->ack_tx)
{
dev_kfree_skb_irq(lp->outgoing.skb);
@@ -930,7 +920,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
}
if (status & lp->intmask & RECONflag) {
ACOMMAND(CFLAGScmd | CONFIGclear);
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
status);
@@ -962,13 +952,13 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
* > RECON_THRESHOLD/min;
* then print a warning message.
*/
- if (!lp->network_down
- && (lp->last_recon - lp->first_recon) <= HZ * 60
- && lp->num_recons >= RECON_THRESHOLD) {
+ if (!lp->network_down &&
+ (lp->last_recon - lp->first_recon) <= HZ * 60 &&
+ lp->num_recons >= RECON_THRESHOLD) {
lp->network_down = 1;
BUGMSG(D_NORMAL, "many reconfigurations detected: cabling problem?\n");
- } else if (!lp->network_down
- && lp->last_recon - lp->first_recon > HZ * 60) {
+ } else if (!lp->network_down &&
+ lp->last_recon - lp->first_recon > HZ * 60) {
/* reset counters if we've gone for over a minute. */
lp->first_recon = lp->last_recon;
lp->num_recons = 1;
@@ -1010,14 +1000,14 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
*/
static void arcnet_rx(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct archdr pkt;
struct arc_rfc1201 *soft;
int length, ofs;
soft = &pkt.soft.rfc1201;
- lp->hw.copy_from_card(dev, bufnum, 0, &pkt, sizeof(ARC_HDR_SIZE));
+ lp->hw.copy_from_card(dev, bufnum, 0, &pkt, ARC_HDR_SIZE);
if (pkt.hard.offset[0]) {
ofs = pkt.hard.offset[0];
length = 256 - ofs;
@@ -1038,8 +1028,8 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
"(%d+4 bytes)\n",
bufnum, pkt.hard.source, pkt.hard.dest, length);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += length + ARC_HDR_SIZE;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length + ARC_HDR_SIZE;
/* call the right receiver for the protocol */
if (arc_proto_map[soft->proto]->is_ip) {
@@ -1067,18 +1057,6 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
}
-
-/*
- * Get the current statistics. This may be called with the card open or
- * closed.
- */
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
-{
- struct arcnet_local *lp = dev->priv;
- return &lp->stats;
-}
-
-
static void null_rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
@@ -1091,7 +1069,7 @@ static void null_rx(struct net_device *dev, int bufnum,
static int null_build_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, uint8_t daddr)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
BUGMSG(D_PROTO,
"tx: can't build header for encap %02Xh; load a protocol driver.\n",
@@ -1106,7 +1084,7 @@ static int null_build_header(struct sk_buff *skb, struct net_device *dev,
static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
int length, int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct arc_hardware newpkt;
BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 02cb8f1c114..42fce91b71f 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -27,6 +27,7 @@
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
@@ -36,74 +37,11 @@
#define VERSION "arcnet: cap mode (`c') encapsulation support loaded.\n"
-
-static void rx(struct net_device *dev, int bufnum,
- struct archdr *pkthdr, int length);
-static int build_header(struct sk_buff *skb,
- struct net_device *dev,
- unsigned short type,
- uint8_t daddr);
-static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
- int bufnum);
-static int ack_tx(struct net_device *dev, int acked);
-
-
-static struct ArcProto capmode_proto =
-{
- 'r',
- XMTU,
- 0,
- rx,
- build_header,
- prepare_tx,
- NULL,
- ack_tx
-};
-
-
-void arcnet_cap_init(void)
-{
- int count;
-
- for (count = 1; count <= 8; count++)
- if (arc_proto_map[count] == arc_proto_default)
- arc_proto_map[count] = &capmode_proto;
-
- /* for cap mode, we only set the bcast proto if there's no better one */
- if (arc_bcast_proto == arc_proto_default)
- arc_bcast_proto = &capmode_proto;
-
- arc_proto_default = &capmode_proto;
- arc_raw_proto = &capmode_proto;
-}
-
-
-#ifdef MODULE
-
-static int __init capmode_module_init(void)
-{
- printk(VERSION);
- arcnet_cap_init();
- return 0;
-}
-
-static void __exit capmode_module_exit(void)
-{
- arcnet_unregister_proto(&capmode_proto);
-}
-module_init(capmode_module_init);
-module_exit(capmode_module_exit);
-
-MODULE_LICENSE("GPL");
-#endif /* MODULE */
-
-
-
/* packet receiver */
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct sk_buff *skb;
struct archdr *pkt = pkthdr;
char *pktbuf, *pkthdrbuf;
@@ -119,7 +57,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
@@ -148,10 +86,8 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- skb->protocol = __constant_htons(ETH_P_ARCNET);
-;
+ skb->protocol = cpu_to_be16(ETH_P_ARCNET);
netif_rx(skb);
- dev->last_rx = jiffies;
}
@@ -198,7 +134,7 @@ static int build_header(struct sk_buff *skb,
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
int bufnum)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct arc_hardware *hard = &pkt->hard;
int ofs;
@@ -232,65 +168,107 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n",
length,ofs);
- // Copy the arcnet-header + the protocol byte down:
+ /* Copy the arcnet-header + the protocol byte down: */
lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft.cap.proto,
sizeof(pkt->soft.cap.proto));
- // Skip the extra integer we have written into it as a cookie
- // but write the rest of the message:
+ /* Skip the extra integer we have written into it as a cookie
+ but write the rest of the message: */
lp->hw.copy_to_card(dev, bufnum, ofs+1,
((unsigned char*)&pkt->soft.cap.mes),length-1);
lp->lastload_dest = hard->dest;
- return 1; /* done */
+ return 1; /* done */
}
-
static int ack_tx(struct net_device *dev, int acked)
{
- struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
- struct sk_buff *ackskb;
- struct archdr *ackpkt;
- int length=sizeof(struct arc_cap);
+ struct arcnet_local *lp = netdev_priv(dev);
+ struct sk_buff *ackskb;
+ struct archdr *ackpkt;
+ int length=sizeof(struct arc_cap);
- BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n",
- lp->outgoing.skb->protocol, acked);
+ BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n",
+ lp->outgoing.skb->protocol, acked);
- BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");
+ BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");
- /* Now alloc a skb to send back up through the layers: */
- ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC);
- if (ackskb == NULL) {
- BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n");
- goto free_outskb;
- }
+ /* Now alloc a skb to send back up through the layers: */
+ ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC);
+ if (ackskb == NULL) {
+ BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n");
+ goto free_outskb;
+ }
- skb_put(ackskb, length + ARC_HDR_SIZE );
- ackskb->dev = dev;
+ skb_put(ackskb, length + ARC_HDR_SIZE );
+ ackskb->dev = dev;
- skb_reset_mac_header(ackskb);
- ackpkt = (struct archdr *)skb_mac_header(ackskb);
- /* skb_pull(ackskb, ARC_HDR_SIZE); */
+ skb_reset_mac_header(ackskb);
+ ackpkt = (struct archdr *)skb_mac_header(ackskb);
+ /* skb_pull(ackskb, ARC_HDR_SIZE); */
+ skb_copy_from_linear_data(lp->outgoing.skb, ackpkt,
+ ARC_HDR_SIZE + sizeof(struct arc_cap));
+ ackpkt->soft.cap.proto = 0; /* using protocol 0 for acknowledge */
+ ackpkt->soft.cap.mes.ack=acked;
- skb_copy_from_linear_data(lp->outgoing.skb, ackpkt,
- ARC_HDR_SIZE + sizeof(struct arc_cap));
- ackpkt->soft.cap.proto=0; /* using protocol 0 for acknowledge */
- ackpkt->soft.cap.mes.ack=acked;
+ BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
+ *((int*)&ackpkt->soft.cap.cookie[0]));
- BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
- *((int*)&ackpkt->soft.cap.cookie[0]));
+ ackskb->protocol = cpu_to_be16(ETH_P_ARCNET);
- ackskb->protocol = __constant_htons(ETH_P_ARCNET);
+ BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
+ netif_rx(ackskb);
- BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
- netif_rx(ackskb);
+free_outskb:
+ dev_kfree_skb_irq(lp->outgoing.skb);
+ lp->outgoing.proto = NULL; /* We are always finished when in this protocol */
- free_outskb:
- dev_kfree_skb_irq(lp->outgoing.skb);
- lp->outgoing.proto = NULL; /* We are always finished when in this protocol */
+ return 0;
+}
- return 0;
+static struct ArcProto capmode_proto =
+{
+ 'r',
+ XMTU,
+ 0,
+ rx,
+ build_header,
+ prepare_tx,
+ NULL,
+ ack_tx
+};
+
+static void arcnet_cap_init(void)
+{
+ int count;
+
+ for (count = 1; count <= 8; count++)
+ if (arc_proto_map[count] == arc_proto_default)
+ arc_proto_map[count] = &capmode_proto;
+
+ /* for cap mode, we only set the bcast proto if there's no better one */
+ if (arc_bcast_proto == arc_proto_default)
+ arc_bcast_proto = &capmode_proto;
+
+ arc_proto_default = &capmode_proto;
+ arc_raw_proto = &capmode_proto;
+}
+
+static int __init capmode_module_init(void)
+{
+ printk(VERSION);
+ arcnet_cap_init();
+ return 0;
+}
+
+static void __exit capmode_module_exit(void)
+{
+ arcnet_unregister_proto(&capmode_proto);
}
+module_init(capmode_module_init);
+module_exit(capmode_module_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index 9289e6103de..45c61a2c5fb 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -30,11 +30,11 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/bootmem.h>
#include <linux/arcdevice.h>
#include <linux/com20020.h>
@@ -52,7 +52,7 @@ static int __init com20020isa_probe(struct net_device *dev)
{
int ioaddr;
unsigned long airqmask;
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int err;
BUGLVL(D_NORMAL) printk(VERSION);
@@ -91,14 +91,14 @@ static int __init com20020isa_probe(struct net_device *dev)
outb(0, _INTMASK);
dev->irq = probe_irq_off(airqmask);
- if (dev->irq <= 0) {
+ if ((int)dev->irq <= 0) {
BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n");
airqmask = probe_irq_on();
outb(NORXflag, _INTMASK);
udelay(5);
outb(0, _INTMASK);
dev->irq = probe_irq_off(airqmask);
- if (dev->irq <= 0) {
+ if ((int)dev->irq <= 0) {
BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
err = -ENODEV;
goto out;
@@ -151,7 +151,9 @@ static int __init com20020_init(void)
if (node && node != 0xff)
dev->dev_addr[0] = node;
- lp = dev->priv;
+ dev->netdev_ops = &com20020_netdev_ops;
+
+ lp = netdev_priv(dev);
lp->backplane = backplane;
lp->clockp = clockp & 7;
lp->clockm = clockm & 3;
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index b8c0fa6d401..cbc44f53755 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -31,10 +31,10 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/arcdevice.h>
#include <linux/com20020.h>
@@ -61,7 +61,7 @@ module_param(clockp, int, 0);
module_param(clockm, int, 0);
MODULE_LICENSE("GPL");
-static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct net_device *dev;
struct arcnet_local *lp;
@@ -72,7 +72,10 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
dev = alloc_arcdev(device);
if (!dev)
return -ENOMEM;
- lp = dev->priv;
+
+ dev->netdev_ops = &com20020_netdev_ops;
+
+ lp = netdev_priv(dev);
pci_set_drvdata(pdev, dev);
@@ -132,7 +135,7 @@ out_dev:
return err;
}
-static void __devexit com20020pci_remove(struct pci_dev *pdev)
+static void com20020pci_remove(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
unregister_netdev(dev);
@@ -141,7 +144,7 @@ static void __devexit com20020pci_remove(struct pci_dev *pdev)
free_netdev(dev);
}
-static struct pci_device_id com20020pci_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(com20020pci_id_table) = {
{ 0x1571, 0xa001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0x1571, 0xa002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0x1571, 0xa003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
@@ -162,8 +165,8 @@ static struct pci_device_id com20020pci_id_table[] = {
{ 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{ 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{ 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
- { 0x10B5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
- { 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+ { 0x10B5, 0x9030, 0x10B5, 0x2978, 0, 0, ARC_CAN_10MBIT },
+ { 0x10B5, 0x9050, 0x10B5, 0x2273, 0, 0, ARC_CAN_10MBIT },
{ 0x14BA, 0x6000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{ 0x10B5, 0x2200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
{0,}
@@ -175,7 +178,7 @@ static struct pci_driver com20020pci_driver = {
.name = "com20020",
.id_table = com20020pci_id_table,
.probe = com20020pci_probe,
- .remove = __devexit_p(com20020pci_remove),
+ .remove = com20020pci_remove,
};
static int __init com20020pci_init(void)
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 8b51313b130..7b96c5f47e8 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -29,11 +29,11 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/arcdevice.h>
#include <linux/com20020.h>
@@ -89,7 +89,7 @@ static void com20020_copy_to_card(struct net_device *dev, int bufnum,
int com20020_check(struct net_device *dev)
{
int ioaddr = dev->base_addr, status;
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
ARCRESET0;
mdelay(RESETtime);
@@ -149,6 +149,14 @@ int com20020_check(struct net_device *dev)
return 0;
}
+const struct net_device_ops com20020_netdev_ops = {
+ .ndo_open = arcnet_open,
+ .ndo_stop = arcnet_close,
+ .ndo_start_xmit = arcnet_send_packet,
+ .ndo_tx_timeout = arcnet_timeout,
+ .ndo_set_rx_mode = com20020_set_mc_list,
+};
+
/* Set up the struct net_device associated with this card. Called after
* probing succeeds.
*/
@@ -159,7 +167,7 @@ int com20020_found(struct net_device *dev, int shared)
/* Initialize the rest of the device structure. */
- lp = dev->priv;
+ lp = netdev_priv(dev);
lp->hw.owner = THIS_MODULE;
lp->hw.command = com20020_command;
@@ -170,8 +178,6 @@ int com20020_found(struct net_device *dev, int shared)
lp->hw.copy_from_card = com20020_copy_from_card;
lp->hw.close = com20020_close;
- dev->set_multicast_list = com20020_set_mc_list;
-
if (!dev->dev_addr[0])
dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this some other way! */
@@ -194,7 +200,7 @@ int com20020_found(struct net_device *dev, int shared)
outb(dev->dev_addr[0], _XREG);
/* reserve the irq */
- if (request_irq(dev->irq, &arcnet_interrupt, shared,
+ if (request_irq(dev->irq, arcnet_interrupt, shared,
"arcnet (COM20020)", dev)) {
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
@@ -233,20 +239,20 @@ int com20020_found(struct net_device *dev, int shared)
*/
static int com20020_reset(struct net_device *dev, int really_reset)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
u_int ioaddr = dev->base_addr;
u_char inbyte;
BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
- __FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name);
+ __FILE__,__LINE__,__func__,dev,lp,dev->name);
BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
dev->name, ASTATUS());
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
/* power-up defaults */
SETCONF;
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (really_reset) {
/* reset the card */
@@ -254,22 +260,22 @@ static int com20020_reset(struct net_device *dev, int really_reset)
mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */
}
/* clear flags & end reset */
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
/* verify that the ARCnet signature byte is present */
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
if (inbyte != TESTvalue) {
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
return 1;
}
/* enable extended (512-byte) packets */
ACOMMAND(CONFIGcmd | EXTconf);
- BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+ BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
/* done! return success. */
return 0;
@@ -300,7 +306,7 @@ static int com20020_status(struct net_device *dev)
static void com20020_close(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
/* disable transmitter */
@@ -317,7 +323,7 @@ static void com20020_close(struct net_device *dev)
*/
static void com20020_set_mc_list(struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) { /* Enable promiscuous mode */
@@ -342,6 +348,7 @@ static void com20020_set_mc_list(struct net_device *dev)
defined(CONFIG_ARCNET_COM20020_CS_MODULE)
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
+EXPORT_SYMBOL(com20020_netdev_ops);
#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
index ea9414c4d90..326a612a273 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/arcnet/com20020_cs.c
@@ -32,7 +32,6 @@
* **********************
*/
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -43,37 +42,30 @@
#include <linux/arcdevice.h>
#include <linux/com20020.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <asm/io.h>
-#include <asm/system.h>
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
-#ifdef PCMCIA_DEBUG
-
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static void regdump(struct net_device *dev)
{
+#ifdef DEBUG
int ioaddr = dev->base_addr;
int count;
- printk("com20020 register dump:\n");
+ netdev_dbg(dev, "register dump:\n");
for (count = ioaddr; count < ioaddr + 16; count++)
{
if (!(count % 16))
- printk("\n%04X: ", count);
- printk("%02X ", inb(count));
+ pr_cont("%04X:", count);
+ pr_cont(" %02X", inb(count));
}
- printk("\n");
+ pr_cont("\n");
- printk("buffer0 dump:\n");
+ netdev_dbg(dev, "buffer0 dump:\n");
/* set up the address register */
count = 0;
outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
@@ -82,20 +74,15 @@ static void regdump(struct net_device *dev)
for (count = 0; count < 256+32; count++)
{
if (!(count % 16))
- printk("\n%04X: ", count);
+ pr_cont("%04X:", count);
/* copy the data */
- printk("%02X ", inb(_MEMDATA));
+ pr_cont(" %02X", inb(_MEMDATA));
}
- printk("\n");
+ pr_cont("\n");
+#endif
}
-#else
-
-#define DEBUG(n, args...) do { } while (0)
-static inline void regdump(struct net_device *dev) { }
-
-#endif
/*====================================================================*/
@@ -127,24 +114,15 @@ static void com20020_detach(struct pcmcia_device *p_dev);
typedef struct com20020_dev_t {
struct net_device *dev;
- dev_node_t node;
} com20020_dev_t;
-/*======================================================================
-
- com20020_attach() creates an "instance" of the driver, allocating
- local data structures for one device. The device is registered
- with Card Services.
-
-======================================================================*/
-
static int com20020_probe(struct pcmcia_device *p_dev)
{
com20020_dev_t *info;
struct net_device *dev;
struct arcnet_local *lp;
- DEBUG(0, "com20020_attach()\n");
+ dev_dbg(&p_dev->dev, "com20020_attach()\n");
/* Create new network device */
info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
@@ -155,7 +133,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
if (!dev)
goto fail_alloc_dev;
- lp = dev->priv;
+ lp = netdev_priv(dev);
lp->timeout = timeout;
lp->backplane = backplane;
lp->clockp = clockp;
@@ -165,15 +143,11 @@ static int com20020_probe(struct pcmcia_device *p_dev)
/* fill in our module parameters as defaults */
dev->dev_addr[0] = node;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.NumPorts1 = 16;
- p_dev->io.IOAddrLines = 16;
- p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
- p_dev->conf.Attributes = CONF_ENABLE_IRQ;
- p_dev->conf.IntType = INT_MEMORY_AND_IO;
+ p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ p_dev->resource[0]->end = 16;
+ p_dev->config_flags |= CONF_ENABLE_IRQ;
- p_dev->irq.Instance = info->dev = dev;
+ info->dev = dev;
p_dev->priv = info;
return com20020_config(p_dev);
@@ -184,118 +158,100 @@ fail_alloc_info:
return -ENOMEM;
} /* com20020_attach */
-/*======================================================================
-
- This deletes a driver "instance". The device is de-registered
- with Card Services. If it has been released, all local data
- structures are freed. Otherwise, the structures will be freed
- when the device is released.
-
-======================================================================*/
-
static void com20020_detach(struct pcmcia_device *link)
{
struct com20020_dev_t *info = link->priv;
struct net_device *dev = info->dev;
- DEBUG(1,"detach...\n");
+ dev_dbg(&link->dev, "detach...\n");
- DEBUG(0, "com20020_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "com20020_detach\n");
- if (link->dev_node) {
- DEBUG(1,"unregister...\n");
+ dev_dbg(&link->dev, "unregister...\n");
- unregister_netdev(dev);
+ unregister_netdev(dev);
- /*
- * this is necessary because we register our IRQ separately
- * from card services.
- */
- if (dev->irq)
+ /*
+ * this is necessary because we register our IRQ separately
+ * from card services.
+ */
+ if (dev->irq)
free_irq(dev->irq, dev);
- }
com20020_release(link);
/* Unlink device structure, free bits */
- DEBUG(1,"unlinking...\n");
+ dev_dbg(&link->dev, "unlinking...\n");
if (link->priv)
{
dev = info->dev;
if (dev)
{
- DEBUG(1,"kfree...\n");
+ dev_dbg(&link->dev, "kfree...\n");
free_netdev(dev);
}
- DEBUG(1,"kfree2...\n");
+ dev_dbg(&link->dev, "kfree2...\n");
kfree(info);
}
} /* com20020_detach */
-/*======================================================================
-
- com20020_config() is scheduled to run after a CARD_INSERTION event
- is received, to configure the PCMCIA socket, and to make the
- device available to the system.
-
-======================================================================*/
-
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int com20020_config(struct pcmcia_device *link)
{
struct arcnet_local *lp;
com20020_dev_t *info;
struct net_device *dev;
- int i, last_ret, last_fn;
+ int i, ret;
int ioaddr;
info = link->priv;
dev = info->dev;
- DEBUG(1,"config...\n");
+ dev_dbg(&link->dev, "config...\n");
+
+ dev_dbg(&link->dev, "com20020_config\n");
- DEBUG(0, "com20020_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "baseport1 is %Xh\n",
+ (unsigned int) link->resource[0]->start);
- DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
- i = !CS_SUCCESS;
- if (!link->io.BasePort1)
+ i = -ENODEV;
+ link->io_lines = 16;
+
+ if (!link->resource[0]->start)
{
for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
{
- link->io.BasePort1 = ioaddr;
- i = pcmcia_request_io(link, &link->io);
- if (i == CS_SUCCESS)
+ link->resource[0]->start = ioaddr;
+ i = pcmcia_request_io(link);
+ if (i == 0)
break;
}
}
else
- i = pcmcia_request_io(link, &link->io);
+ i = pcmcia_request_io(link);
- if (i != CS_SUCCESS)
+ if (i != 0)
{
- DEBUG(1,"arcnet: requestIO failed totally!\n");
+ dev_dbg(&link->dev, "requestIO failed totally!\n");
goto failed;
}
- ioaddr = dev->base_addr = link->io.BasePort1;
- DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);
-
- DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
- link->irq.AssignedIRQ,
- link->irq.IRQInfo1, link->irq.IRQInfo2);
- i = pcmcia_request_irq(link, &link->irq);
- if (i != CS_SUCCESS)
+ ioaddr = dev->base_addr = link->resource[0]->start;
+ dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
+
+ dev_dbg(&link->dev, "request IRQ %d\n",
+ link->irq);
+ if (!link->irq)
{
- DEBUG(1,"arcnet: requestIRQ failed totally!\n");
+ dev_dbg(&link->dev, "requestIRQ failed totally!\n");
goto failed;
}
- dev->irq = link->irq.AssignedIRQ;
+ dev->irq = link->irq;
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_enable_device(link);
+ if (ret)
+ goto failed;
if (com20020_check(dev))
{
@@ -303,46 +259,33 @@ static int com20020_config(struct pcmcia_device *link)
goto failed;
}
- lp = dev->priv;
+ lp = netdev_priv(dev);
lp->card_name = "PCMCIA COM20020";
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
- link->dev_node = &info->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
i = com20020_found(dev, 0); /* calls register_netdev */
if (i != 0) {
- DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
- link->dev_node = NULL;
+ dev_notice(&link->dev,
+ "com20020_found() failed\n");
goto failed;
}
- strcpy(info->node.dev_name, dev->name);
-
- DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
- dev->name, dev->base_addr, dev->irq);
+ netdev_dbg(dev, "port %#3lx, irq %d\n",
+ dev->base_addr, dev->irq);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
- DEBUG(1,"com20020_config failed...\n");
+ dev_dbg(&link->dev, "com20020_config failed...\n");
com20020_release(link);
return -ENODEV;
} /* com20020_config */
-/*======================================================================
-
- After a card is removed, com20020_release() will unregister the net
- device, and release the PCMCIA configuration. If the device is
- still open, this will be postponed until it is closed.
-
-======================================================================*/
-
static void com20020_release(struct pcmcia_device *link)
{
- DEBUG(0, "com20020_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "com20020_release\n");
pcmcia_disable_device(link);
}
@@ -364,14 +307,14 @@ static int com20020_resume(struct pcmcia_device *link)
if (link->open) {
int ioaddr = dev->base_addr;
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
ARCRESET;
}
return 0;
}
-static struct pcmcia_device_id com20020_ids[] = {
+static const struct pcmcia_device_id com20020_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
"PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
PCMCIA_DEVICE_PROD_ID12("SoHard AG",
@@ -382,25 +325,11 @@ MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
static struct pcmcia_driver com20020_cs_driver = {
.owner = THIS_MODULE,
- .drv = {
- .name = "com20020_cs",
- },
+ .name = "com20020_cs",
.probe = com20020_probe,
.remove = com20020_detach,
.id_table = com20020_ids,
.suspend = com20020_suspend,
.resume = com20020_resume,
};
-
-static int __init init_com20020_cs(void)
-{
- return pcmcia_register_driver(&com20020_cs_driver);
-}
-
-static void __exit exit_com20020_cs(void)
-{
- pcmcia_unregister_driver(&com20020_cs_driver);
-}
-
-module_init(init_com20020_cs);
-module_exit(exit_com20020_cs);
+module_pcmcia_driver(com20020_cs_driver);
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index 6599f1046c7..487d780ebbd 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -29,11 +29,11 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/bootmem.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
#include <linux/arcdevice.h>
@@ -214,7 +214,7 @@ static int __init com90io_probe(struct net_device *dev)
outb(0, _INTMASK);
dev->irq = probe_irq_off(airqmask);
- if (dev->irq <= 0) {
+ if ((int)dev->irq <= 0) {
BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed\n");
goto err_out;
}
@@ -238,7 +238,7 @@ static int __init com90io_found(struct net_device *dev)
int err;
/* Reserve the irq */
- if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
+ if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
return -ENODEV;
}
@@ -248,7 +248,7 @@ static int __init com90io_found(struct net_device *dev)
return -EBUSY;
}
- lp = dev->priv;
+ lp = netdev_priv(dev);
lp->card_name = "COM90xx I/O";
lp->hw.command = com90io_command;
lp->hw.status = com90io_status;
@@ -290,7 +290,7 @@ static int __init com90io_found(struct net_device *dev)
*/
static int com90io_reset(struct net_device *dev, int really_reset)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
short ioaddr = dev->base_addr;
BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
index 0d45553ff75..b80fbe40aa0 100644
--- a/drivers/net/arcnet/com90xx.c
+++ b/drivers/net/arcnet/com90xx.c
@@ -27,9 +27,11 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
+#include <linux/slab.h>
#include <asm/io.h>
#include <linux/arcdevice.h>
@@ -468,7 +470,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem
release_mem_region(shmem, MIRROR_SIZE);
return -ENOMEM;
}
- lp = dev->priv;
+ lp = netdev_priv(dev);
/* find the real shared memory start/end points, including mirrors */
/* guess the actual size of one "memory mirror" - the number of
@@ -501,7 +503,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem
goto err_free_dev;
/* reserve the irq */
- if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
+ if (request_irq(airq, arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
goto err_release_mem;
}
@@ -583,9 +585,9 @@ static void com90xx_setmask(struct net_device *dev, int mask)
*
* However, it does make sure the card is in a defined state.
*/
-int com90xx_reset(struct net_device *dev, int really_reset)
+static int com90xx_reset(struct net_device *dev, int really_reset)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
short ioaddr = dev->base_addr;
BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
@@ -621,7 +623,7 @@ int com90xx_reset(struct net_device *dev, int really_reset)
static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
}
@@ -630,7 +632,7 @@ static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
void *buf, int count)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
}
@@ -656,7 +658,7 @@ static void __exit com90xx_exit(void)
for (count = 0; count < numcards; count++) {
dev = cards[count];
- lp = dev->priv;
+ lp = netdev_priv(dev);
unregister_netdev(dev);
free_irq(dev->irq, dev);
diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
index dab185bc51f..f81db4070a5 100644
--- a/drivers/net/arcnet/rfc1051.c
+++ b/drivers/net/arcnet/rfc1051.c
@@ -24,6 +24,7 @@
* **********************
*/
#include <linux/module.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/if_arp.h>
#include <net/arp.h>
@@ -88,7 +89,6 @@ MODULE_LICENSE("GPL");
*/
static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
{
- struct arcnet_local *lp = dev->priv;
struct archdr *pkt = (struct archdr *) skb->data;
struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
@@ -112,8 +112,8 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
return htons(ETH_P_ARP);
default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
return 0;
}
@@ -125,7 +125,7 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct sk_buff *skb;
struct archdr *pkt = pkthdr;
int ofs;
@@ -140,7 +140,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -159,7 +159,6 @@ static void rx(struct net_device *dev, int bufnum,
skb->protocol = type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
}
@@ -169,7 +168,6 @@ static void rx(struct net_device *dev, int bufnum,
static int build_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, uint8_t daddr)
{
- struct arcnet_local *lp = dev->priv;
int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
@@ -185,8 +183,8 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
default:
BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
return 0;
}
@@ -220,7 +218,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct arc_hardware *hard = &pkt->hard;
int ofs;
diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
index 6d6d95cc440..b71431aae08 100644
--- a/drivers/net/arcnet/rfc1201.c
+++ b/drivers/net/arcnet/rfc1201.c
@@ -23,6 +23,7 @@
*
* **********************
*/
+#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/if_arp.h>
@@ -92,7 +93,6 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct archdr *pkt = (struct archdr *) skb->data;
struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
- struct arcnet_local *lp = dev->priv;
int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
/* Pull off the arcnet header. */
@@ -121,8 +121,8 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
case ARC_P_NOVELL_EC:
return htons(ETH_P_802_3);
default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
return 0;
}
@@ -134,7 +134,7 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
static void rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct sk_buff *skb;
struct archdr *pkt = pkthdr;
struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
@@ -172,8 +172,8 @@ static void rx(struct net_device *dev, int bufnum,
in->sequence, soft->split_flag, soft->sequence);
lp->rfc1201.aborted_seq = soft->sequence;
dev_kfree_skb_irq(in->skb);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->skb = NULL;
}
in->sequence = soft->sequence;
@@ -181,7 +181,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -213,7 +213,7 @@ static void rx(struct net_device *dev, int bufnum,
BUGMSG(D_EXTRA,
"ARP source address was 00h, set to %02Xh.\n",
saddr);
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
*cptr = saddr;
} else {
BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
@@ -222,15 +222,14 @@ static void rx(struct net_device *dev, int bufnum,
} else {
BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
arp->ar_hln, arp->ar_pln);
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
}
}
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
skb->protocol = type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
} else { /* split packet */
/*
* NOTE: MSDOS ARP packet correction should only need to apply to
@@ -258,8 +257,8 @@ static void rx(struct net_device *dev, int bufnum,
soft->split_flag);
dev_kfree_skb_irq(in->skb);
in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->lastpacket = in->numpackets = 0;
}
if (soft->split_flag & 1) { /* first packet in split */
@@ -270,8 +269,8 @@ static void rx(struct net_device *dev, int bufnum,
"(splitflag=%d, seq=%d)\n",
in->sequence, soft->split_flag,
soft->sequence);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
dev_kfree_skb_irq(in->skb);
}
in->sequence = soft->sequence;
@@ -282,8 +281,8 @@ static void rx(struct net_device *dev, int bufnum,
BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
soft->split_flag);
lp->rfc1201.aborted_seq = soft->sequence;
- lp->stats.rx_errors++;
- lp->stats.rx_length_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
return;
}
in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
@@ -291,7 +290,7 @@ static void rx(struct net_device *dev, int bufnum,
if (skb == NULL) {
BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
lp->rfc1201.aborted_seq = soft->sequence;
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb->dev = dev;
@@ -315,8 +314,8 @@ static void rx(struct net_device *dev, int bufnum,
"first! (splitflag=%d, seq=%d, aborted=%d)\n",
soft->split_flag, soft->sequence,
lp->rfc1201.aborted_seq);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
}
return;
}
@@ -326,8 +325,8 @@ static void rx(struct net_device *dev, int bufnum,
if (packetnum <= in->lastpacket - 1) {
BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
soft->split_flag);
- lp->stats.rx_errors++;
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_frame_errors++;
return;
}
/* "bad" duplicate, kill reassembly */
@@ -337,8 +336,8 @@ static void rx(struct net_device *dev, int bufnum,
lp->rfc1201.aborted_seq = soft->sequence;
dev_kfree_skb_irq(in->skb);
in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->lastpacket = in->numpackets = 0;
return;
}
@@ -366,7 +365,6 @@ static void rx(struct net_device *dev, int bufnum,
skb->protocol = type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
}
}
}
@@ -376,7 +374,7 @@ static void rx(struct net_device *dev, int bufnum,
static int build_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, uint8_t daddr)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
@@ -406,8 +404,8 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
default:
BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
return 0;
}
@@ -443,7 +441,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
struct arc_rfc1201 *soft, int softlen, int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
int ofs;
/* assume length <= XMTU: someone should have handled that by now. */
@@ -476,7 +474,7 @@ static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
struct Outgoing *out;
@@ -511,7 +509,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
static int continue_tx(struct net_device *dev, int bufnum)
{
- struct arcnet_local *lp = dev->priv;
+ struct arcnet_local *lp = netdev_priv(dev);
struct Outgoing *out = &lp->outgoing;
struct arc_hardware *hard = &out->pkt->hard;
struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
deleted file mode 100644
index 29e53eb71c7..00000000000
--- a/drivers/net/ariadne.c
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * Amiga Linux/m68k Ariadne Ethernet Driver
- *
- * © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
- * Peter De Schrijver (p2@mind.be)
- *
- * ---------------------------------------------------------------------------
- *
- * This program is based on
- *
- * lance.c: An AMD LANCE ethernet driver for linux.
- * Written 1993-94 by Donald Becker.
- *
- * Am79C960: PCnet(tm)-ISA Single-Chip Ethernet Controller
- * Advanced Micro Devices
- * Publication #16907, Rev. B, Amendment/0, May 1994
- *
- * MC68230: Parallel Interface/Timer (PI/T)
- * Motorola Semiconductors, December, 1983
- *
- * ---------------------------------------------------------------------------
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of the Linux
- * distribution for more details.
- *
- * ---------------------------------------------------------------------------
- *
- * The Ariadne is a Zorro-II board made by Village Tronic. It contains:
- *
- * - an Am79C960 PCnet-ISA Single-Chip Ethernet Controller with both
- * 10BASE-2 (thin coax) and 10BASE-T (UTP) connectors
- *
- * - an MC68230 Parallel Interface/Timer configured as 2 parallel ports
- */
-
-#include <linux/module.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/interrupt.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <linux/zorro.h>
-#include <linux/bitops.h>
-
-#include <asm/amigaints.h>
-#include <asm/amigahw.h>
-#include <asm/irq.h>
-
-#include "ariadne.h"
-
-
-#ifdef ARIADNE_DEBUG
-int ariadne_debug = ARIADNE_DEBUG;
-#else
-int ariadne_debug = 1;
-#endif
-
-
- /*
- * Macros to Fix Endianness problems
- */
-
- /* Swap the Bytes in a WORD */
-#define swapw(x) (((x>>8)&0x00ff)|((x<<8)&0xff00))
- /* Get the Low BYTE in a WORD */
-#define lowb(x) (x&0xff)
- /* Get the Swapped High WORD in a LONG */
-#define swhighw(x) ((((x)>>8)&0xff00)|(((x)>>24)&0x00ff))
- /* Get the Swapped Low WORD in a LONG */
-#define swloww(x) ((((x)<<8)&0xff00)|(((x)>>8)&0x00ff))
-
-
- /*
- * Transmit/Receive Ring Definitions
- */
-
-#define TX_RING_SIZE 5
-#define RX_RING_SIZE 16
-
-#define PKT_BUF_SIZE 1520
-
-
- /*
- * Private Device Data
- */
-
-struct ariadne_private {
- volatile struct TDRE *tx_ring[TX_RING_SIZE];
- volatile struct RDRE *rx_ring[RX_RING_SIZE];
- volatile u_short *tx_buff[TX_RING_SIZE];
- volatile u_short *rx_buff[RX_RING_SIZE];
- int cur_tx, cur_rx; /* The next free ring entry */
- int dirty_tx; /* The ring entries to be free()ed. */
- char tx_full;
-};
-
-
- /*
- * Structure Created in the Ariadne's RAM Buffer
- */
-
-struct lancedata {
- struct TDRE tx_ring[TX_RING_SIZE];
- struct RDRE rx_ring[RX_RING_SIZE];
- u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)];
- u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE/sizeof(u_short)];
-};
-
-static int ariadne_open(struct net_device *dev);
-static void ariadne_init_ring(struct net_device *dev);
-static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static void ariadne_tx_timeout(struct net_device *dev);
-static int ariadne_rx(struct net_device *dev);
-static void ariadne_reset(struct net_device *dev);
-static irqreturn_t ariadne_interrupt(int irq, void *data);
-static int ariadne_close(struct net_device *dev);
-static struct net_device_stats *ariadne_get_stats(struct net_device *dev);
-#ifdef HAVE_MULTICAST
-static void set_multicast_list(struct net_device *dev);
-#endif
-
-
-static void memcpyw(volatile u_short *dest, u_short *src, int len)
-{
- while (len >= 2) {
- *(dest++) = *(src++);
- len -= 2;
- }
- if (len == 1)
- *dest = (*(u_char *)src)<<8;
-}
-
-
-static int __devinit ariadne_init_one(struct zorro_dev *z,
- const struct zorro_device_id *ent);
-static void __devexit ariadne_remove_one(struct zorro_dev *z);
-
-
-static struct zorro_device_id ariadne_zorro_tbl[] __devinitdata = {
- { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE },
- { 0 }
-};
-
-static struct zorro_driver ariadne_driver = {
- .name = "ariadne",
- .id_table = ariadne_zorro_tbl,
- .probe = ariadne_init_one,
- .remove = __devexit_p(ariadne_remove_one),
-};
-
-static int __devinit ariadne_init_one(struct zorro_dev *z,
- const struct zorro_device_id *ent)
-{
- unsigned long board = z->resource.start;
- unsigned long base_addr = board+ARIADNE_LANCE;
- unsigned long mem_start = board+ARIADNE_RAM;
- struct resource *r1, *r2;
- struct net_device *dev;
- struct ariadne_private *priv;
- int err;
- DECLARE_MAC_BUF(mac);
-
- r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960");
- if (!r1)
- return -EBUSY;
- r2 = request_mem_region(mem_start, ARIADNE_RAM_SIZE, "RAM");
- if (!r2) {
- release_resource(r1);
- return -EBUSY;
- }
-
- dev = alloc_etherdev(sizeof(struct ariadne_private));
- if (dev == NULL) {
- release_resource(r1);
- release_resource(r2);
- return -ENOMEM;
- }
-
- priv = netdev_priv(dev);
-
- r1->name = dev->name;
- r2->name = dev->name;
-
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x60;
- dev->dev_addr[2] = 0x30;
- dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff;
- dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff;
- dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff;
- dev->base_addr = ZTWO_VADDR(base_addr);
- dev->mem_start = ZTWO_VADDR(mem_start);
- dev->mem_end = dev->mem_start+ARIADNE_RAM_SIZE;
-
- dev->open = &ariadne_open;
- dev->stop = &ariadne_close;
- dev->hard_start_xmit = &ariadne_start_xmit;
- dev->tx_timeout = &ariadne_tx_timeout;
- dev->watchdog_timeo = 5*HZ;
- dev->get_stats = &ariadne_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- err = register_netdev(dev);
- if (err) {
- release_resource(r1);
- release_resource(r2);
- free_netdev(dev);
- return err;
- }
- zorro_set_drvdata(z, dev);
-
- printk(KERN_INFO "%s: Ariadne at 0x%08lx, Ethernet Address "
- "%s\n", dev->name, board,
- print_mac(mac, dev->dev_addr));
-
- return 0;
-}
-
-
-static int ariadne_open(struct net_device *dev)
-{
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
- u_short in;
- u_long version;
- int i;
-
- /* Reset the LANCE */
- in = lance->Reset;
-
- /* Stop the LANCE */
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- lance->RDP = STOP;
-
- /* Check the LANCE version */
- lance->RAP = CSR88; /* Chip ID */
- version = swapw(lance->RDP);
- lance->RAP = CSR89; /* Chip ID */
- version |= swapw(lance->RDP)<<16;
- if ((version & 0x00000fff) != 0x00000003) {
- printk(KERN_WARNING "ariadne_open: Couldn't find AMD Ethernet Chip\n");
- return -EAGAIN;
- }
- if ((version & 0x0ffff000) != 0x00003000) {
- printk(KERN_WARNING "ariadne_open: Couldn't find Am79C960 (Wrong part "
- "number = %ld)\n", (version & 0x0ffff000)>>12);
- return -EAGAIN;
- }
-#if 0
- printk(KERN_DEBUG "ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n",
- (version & 0xf0000000)>>28);
-#endif
-
- ariadne_init_ring(dev);
-
- /* Miscellaneous Stuff */
- lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */
- lance->RDP = 0x0000;
- lance->RAP = CSR4; /* Test and Features Control */
- lance->RDP = DPOLL|APAD_XMT|MFCOM|RCVCCOM|TXSTRTM|JABM;
-
- /* Set the Multicast Table */
- lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */
- lance->RDP = 0x0000;
- lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */
- lance->RDP = 0x0000;
- lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */
- lance->RDP = 0x0000;
- lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */
- lance->RDP = 0x0000;
-
- /* Set the Ethernet Hardware Address */
- lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */
- lance->RDP = ((u_short *)&dev->dev_addr[0])[0];
- lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */
- lance->RDP = ((u_short *)&dev->dev_addr[0])[1];
- lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */
- lance->RDP = ((u_short *)&dev->dev_addr[0])[2];
-
- /* Set the Init Block Mode */
- lance->RAP = CSR15; /* Mode Register */
- lance->RDP = 0x0000;
-
- /* Set the Transmit Descriptor Ring Pointer */
- lance->RAP = CSR30; /* Base Address of Transmit Ring */
- lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_ring));
- lance->RAP = CSR31; /* Base Address of transmit Ring */
- lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_ring));
-
- /* Set the Receive Descriptor Ring Pointer */
- lance->RAP = CSR24; /* Base Address of Receive Ring */
- lance->RDP = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_ring));
- lance->RAP = CSR25; /* Base Address of Receive Ring */
- lance->RDP = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_ring));
-
- /* Set the Number of RX and TX Ring Entries */
- lance->RAP = CSR76; /* Receive Ring Length */
- lance->RDP = swapw(((u_short)-RX_RING_SIZE));
- lance->RAP = CSR78; /* Transmit Ring Length */
- lance->RDP = swapw(((u_short)-TX_RING_SIZE));
-
- /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */
- lance->RAP = ISACSR2; /* Miscellaneous Configuration */
- lance->IDP = ASEL;
-
- /* LED Control */
- lance->RAP = ISACSR5; /* LED1 Status */
- lance->IDP = PSE|XMTE;
- lance->RAP = ISACSR6; /* LED2 Status */
- lance->IDP = PSE|COLE;
- lance->RAP = ISACSR7; /* LED3 Status */
- lance->IDP = PSE|RCVE;
-
- netif_start_queue(dev);
-
- i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED,
- dev->name, dev);
- if (i) return i;
-
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- lance->RDP = INEA|STRT;
-
- return 0;
-}
-
-
-static void ariadne_init_ring(struct net_device *dev)
-{
- struct ariadne_private *priv = netdev_priv(dev);
- volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start;
- int i;
-
- netif_stop_queue(dev);
-
- priv->tx_full = 0;
- priv->cur_rx = priv->cur_tx = 0;
- priv->dirty_tx = 0;
-
- /* Set up TX Ring */
- for (i = 0; i < TX_RING_SIZE; i++) {
- volatile struct TDRE *t = &lancedata->tx_ring[i];
- t->TMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i]));
- t->TMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, tx_buff[i])) |
- TF_STP | TF_ENP;
- t->TMD2 = swapw((u_short)-PKT_BUF_SIZE);
- t->TMD3 = 0;
- priv->tx_ring[i] = &lancedata->tx_ring[i];
- priv->tx_buff[i] = lancedata->tx_buff[i];
-#if 0
- printk(KERN_DEBUG "TX Entry %2d at %p, Buf at %p\n", i,
- &lancedata->tx_ring[i], lancedata->tx_buff[i]);
-#endif
- }
-
- /* Set up RX Ring */
- for (i = 0; i < RX_RING_SIZE; i++) {
- volatile struct RDRE *r = &lancedata->rx_ring[i];
- r->RMD0 = swloww(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i]));
- r->RMD1 = swhighw(ARIADNE_RAM+offsetof(struct lancedata, rx_buff[i])) |
- RF_OWN;
- r->RMD2 = swapw((u_short)-PKT_BUF_SIZE);
- r->RMD3 = 0x0000;
- priv->rx_ring[i] = &lancedata->rx_ring[i];
- priv->rx_buff[i] = lancedata->rx_buff[i];
-#if 0
- printk(KERN_DEBUG "RX Entry %2d at %p, Buf at %p\n", i,
- &lancedata->rx_ring[i], lancedata->rx_buff[i]);
-#endif
- }
-}
-
-
-static int ariadne_close(struct net_device *dev)
-{
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
-
- netif_stop_queue(dev);
-
- lance->RAP = CSR112; /* Missed Frame Count */
- dev->stats.rx_missed_errors = swapw(lance->RDP);
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
-
- if (ariadne_debug > 1) {
- printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, lance->RDP);
- printk(KERN_DEBUG "%s: %lu packets missed\n", dev->name,
- dev->stats.rx_missed_errors);
- }
-
- /* We stop the LANCE here -- it occasionally polls memory if we don't. */
- lance->RDP = STOP;
-
- free_irq(IRQ_AMIGA_PORTS, dev);
-
- return 0;
-}
-
-
-static inline void ariadne_reset(struct net_device *dev)
-{
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
-
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- lance->RDP = STOP;
- ariadne_init_ring(dev);
- lance->RDP = INEA|STRT;
- netif_start_queue(dev);
-}
-
-
-static irqreturn_t ariadne_interrupt(int irq, void *data)
-{
- struct net_device *dev = (struct net_device *)data;
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
- struct ariadne_private *priv;
- int csr0, boguscnt;
- int handled = 0;
-
- if (dev == NULL) {
- printk(KERN_WARNING "ariadne_interrupt(): irq for unknown device.\n");
- return IRQ_NONE;
- }
-
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
-
- if (!(lance->RDP & INTR)) /* Check if any interrupt has been */
- return IRQ_NONE; /* generated by the board. */
-
- priv = netdev_priv(dev);
-
- boguscnt = 10;
- while ((csr0 = lance->RDP) & (ERR|RINT|TINT) && --boguscnt >= 0) {
- /* Acknowledge all of the current interrupt sources ASAP. */
- lance->RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT);
-
-#if 0
- if (ariadne_debug > 5) {
- printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.",
- dev->name, csr0, lance->RDP);
- printk("[");
- if (csr0 & INTR)
- printk(" INTR");
- if (csr0 & INEA)
- printk(" INEA");
- if (csr0 & RXON)
- printk(" RXON");
- if (csr0 & TXON)
- printk(" TXON");
- if (csr0 & TDMD)
- printk(" TDMD");
- if (csr0 & STOP)
- printk(" STOP");
- if (csr0 & STRT)
- printk(" STRT");
- if (csr0 & INIT)
- printk(" INIT");
- if (csr0 & ERR)
- printk(" ERR");
- if (csr0 & BABL)
- printk(" BABL");
- if (csr0 & CERR)
- printk(" CERR");
- if (csr0 & MISS)
- printk(" MISS");
- if (csr0 & MERR)
- printk(" MERR");
- if (csr0 & RINT)
- printk(" RINT");
- if (csr0 & TINT)
- printk(" TINT");
- if (csr0 & IDON)
- printk(" IDON");
- printk(" ]\n");
- }
-#endif
-
- if (csr0 & RINT) { /* Rx interrupt */
- handled = 1;
- ariadne_rx(dev);
- }
-
- if (csr0 & TINT) { /* Tx-done interrupt */
- int dirty_tx = priv->dirty_tx;
-
- handled = 1;
- while (dirty_tx < priv->cur_tx) {
- int entry = dirty_tx % TX_RING_SIZE;
- int status = lowb(priv->tx_ring[entry]->TMD1);
-
- if (status & TF_OWN)
- break; /* It still hasn't been Txed */
-
- priv->tx_ring[entry]->TMD1 &= 0xff00;
-
- if (status & TF_ERR) {
- /* There was an major error, log it. */
- int err_status = priv->tx_ring[entry]->TMD3;
- dev->stats.tx_errors++;
- if (err_status & EF_RTRY)
- dev->stats.tx_aborted_errors++;
- if (err_status & EF_LCAR)
- dev->stats.tx_carrier_errors++;
- if (err_status & EF_LCOL)
- dev->stats.tx_window_errors++;
- if (err_status & EF_UFLO) {
- /* Ackk! On FIFO errors the Tx unit is turned off! */
- dev->stats.tx_fifo_errors++;
- /* Remove this verbosity later! */
- printk(KERN_ERR "%s: Tx FIFO error! Status %4.4x.\n",
- dev->name, csr0);
- /* Restart the chip. */
- lance->RDP = STRT;
- }
- } else {
- if (status & (TF_MORE|TF_ONE))
- dev->stats.collisions++;
- dev->stats.tx_packets++;
- }
- dirty_tx++;
- }
-
-#ifndef final_version
- if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) {
- printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d, "
- "full=%d.\n", dirty_tx, priv->cur_tx, priv->tx_full);
- dirty_tx += TX_RING_SIZE;
- }
-#endif
-
- if (priv->tx_full && netif_queue_stopped(dev) &&
- dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) {
- /* The ring is no longer full. */
- priv->tx_full = 0;
- netif_wake_queue(dev);
- }
-
- priv->dirty_tx = dirty_tx;
- }
-
- /* Log misc errors. */
- if (csr0 & BABL) {
- handled = 1;
- dev->stats.tx_errors++; /* Tx babble. */
- }
- if (csr0 & MISS) {
- handled = 1;
- dev->stats.rx_errors++; /* Missed a Rx frame. */
- }
- if (csr0 & MERR) {
- handled = 1;
- printk(KERN_ERR "%s: Bus master arbitration failure, status "
- "%4.4x.\n", dev->name, csr0);
- /* Restart the chip. */
- lance->RDP = STRT;
- }
- }
-
- /* Clear any other interrupt, and set interrupt enable. */
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- lance->RDP = INEA|BABL|CERR|MISS|MERR|IDON;
-
-#if 0
- if (ariadne_debug > 4)
- printk(KERN_DEBUG "%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name,
- lance->RAP, lance->RDP);
-#endif
- return IRQ_RETVAL(handled);
-}
-
-
-static void ariadne_tx_timeout(struct net_device *dev)
-{
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
-
- printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n",
- dev->name, lance->RDP);
- ariadne_reset(dev);
- netif_wake_queue(dev);
-}
-
-
-static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ariadne_private *priv = netdev_priv(dev);
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
- int entry;
- unsigned long flags;
- int len = skb->len;
-
-#if 0
- if (ariadne_debug > 3) {
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- printk(KERN_DEBUG "%s: ariadne_start_xmit() called, csr0 %4.4x.\n",
- dev->name, lance->RDP);
- lance->RDP = 0x0000;
- }
-#endif
-
- /* FIXME: is the 79C960 new enough to do its own padding right ? */
- if (skb->len < ETH_ZLEN)
- {
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- len = ETH_ZLEN;
- }
-
- /* Fill in a Tx ring entry */
-
-#if 0
-{
- DECLARE_MAC_BUF(mac);
- DECLARE_MAC_BUF(mac2);
-
- printk(KERN_DEBUG "TX pkt type 0x%04x from %s to %s "
- " data 0x%08x len %d\n",
- ((u_short *)skb->data)[6],
- print_mac(mac, ((const u8 *)skb->data)+6),
- print_mac(mac, (const u8 *)skb->data),
- (int)skb->data, (int)skb->len);
-}
-#endif
-
- local_irq_save(flags);
-
- entry = priv->cur_tx % TX_RING_SIZE;
-
- /* Caution: the write order is important here, set the base address with
- the "ownership" bits last. */
-
- priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len);
- priv->tx_ring[entry]->TMD3 = 0x0000;
- memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len);
-
-#if 0
- {
- int i, len;
-
- len = skb->len > 64 ? 64 : skb->len;
- len >>= 1;
- for (i = 0; i < len; i += 8) {
- int j;
- printk(KERN_DEBUG "%04x:", i);
- for (j = 0; (j < 8) && ((i+j) < len); j++) {
- if (!(j & 1))
- printk(" ");
- printk("%04x", priv->tx_buff[entry][i+j]);
- }
- printk("\n");
- }
- }
-#endif
-
- priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1&0xff00)|TF_OWN|TF_STP|TF_ENP;
-
- dev_kfree_skb(skb);
-
- priv->cur_tx++;
- if ((priv->cur_tx >= TX_RING_SIZE) && (priv->dirty_tx >= TX_RING_SIZE)) {
-
-#if 0
- printk(KERN_DEBUG "*** Subtracting TX_RING_SIZE from cur_tx (%d) and "
- "dirty_tx (%d)\n", priv->cur_tx, priv->dirty_tx);
-#endif
-
- priv->cur_tx -= TX_RING_SIZE;
- priv->dirty_tx -= TX_RING_SIZE;
- }
- dev->stats.tx_bytes += len;
-
- /* Trigger an immediate send poll. */
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- lance->RDP = INEA|TDMD;
-
- dev->trans_start = jiffies;
-
- if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) != 0) {
- netif_stop_queue(dev);
- priv->tx_full = 1;
- }
- local_irq_restore(flags);
-
- return 0;
-}
-
-
-static int ariadne_rx(struct net_device *dev)
-{
- struct ariadne_private *priv = netdev_priv(dev);
- int entry = priv->cur_rx % RX_RING_SIZE;
- int i;
-
- /* If we own the next entry, it's a new packet. Send it up. */
- while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) {
- int status = lowb(priv->rx_ring[entry]->RMD1);
-
- if (status != (RF_STP|RF_ENP)) { /* There was an error. */
- /* There is a tricky error noted by John Murphy,
- <murf@perftech.com> to Russ Nelson: Even with full-sized
- buffers it's possible for a jabber packet to use two
- buffers, with only the last correctly noting the error. */
- if (status & RF_ENP)
- /* Only count a general error at the end of a packet.*/
- dev->stats.rx_errors++;
- if (status & RF_FRAM)
- dev->stats.rx_frame_errors++;
- if (status & RF_OFLO)
- dev->stats.rx_over_errors++;
- if (status & RF_CRC)
- dev->stats.rx_crc_errors++;
- if (status & RF_BUFF)
- dev->stats.rx_fifo_errors++;
- priv->rx_ring[entry]->RMD1 &= 0xff00|RF_STP|RF_ENP;
- } else {
- /* Malloc up new buffer, compatible with net-3. */
- short pkt_len = swapw(priv->rx_ring[entry]->RMD3);
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL) {
- printk(KERN_WARNING "%s: Memory squeeze, deferring packet.\n",
- dev->name);
- for (i = 0; i < RX_RING_SIZE; i++)
- if (lowb(priv->rx_ring[(entry+i) % RX_RING_SIZE]->RMD1) & RF_OWN)
- break;
-
- if (i > RX_RING_SIZE-2) {
- dev->stats.rx_dropped++;
- priv->rx_ring[entry]->RMD1 |= RF_OWN;
- priv->cur_rx++;
- }
- break;
- }
-
-
- skb_reserve(skb,2); /* 16 byte align */
- skb_put(skb,pkt_len); /* Make room */
- skb_copy_to_linear_data(skb, (char *)priv->rx_buff[entry], pkt_len);
- skb->protocol=eth_type_trans(skb,dev);
-#if 0
-{
- DECLARE_MAC_BUF(mac);
-
- printk(KERN_DEBUG "RX pkt type 0x%04x from ",
- ((u_short *)skb->data)[6]);
- {
- u_char *ptr = &((u_char *)skb->data)[6];
- printk("%s", print_mac(mac, ptr));
- }
- printk(" to ");
- {
- u_char *ptr = (u_char *)skb->data;
- printk("%s", print_mac(mac, ptr));
- }
- printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
-}
-#endif
-
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
-
- priv->rx_ring[entry]->RMD1 |= RF_OWN;
- entry = (++priv->cur_rx) % RX_RING_SIZE;
- }
-
- priv->cur_rx = priv->cur_rx % RX_RING_SIZE;
-
- /* We should check that at least two ring entries are free. If not,
- we should free one and mark stats->rx_dropped++. */
-
- return 0;
-}
-
-
-static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
-{
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
- short saved_addr;
- unsigned long flags;
-
- local_irq_save(flags);
- saved_addr = lance->RAP;
- lance->RAP = CSR112; /* Missed Frame Count */
- dev->stats.rx_missed_errors = swapw(lance->RDP);
- lance->RAP = saved_addr;
- local_irq_restore(flags);
-
- return &dev->stats;
-}
-
-
-/* Set or clear the multicast filter for this adaptor.
- num_addrs == -1 Promiscuous mode, receive all packets
- num_addrs == 0 Normal mode, clear multicast list
- num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- best-effort filtering.
- */
-static void set_multicast_list(struct net_device *dev)
-{
- volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
-
- if (!netif_running(dev))
- return;
-
- netif_stop_queue(dev);
-
- /* We take the simple way out and always enable promiscuous mode. */
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- lance->RDP = STOP; /* Temporarily stop the lance. */
- ariadne_init_ring(dev);
-
- if (dev->flags & IFF_PROMISC) {
- lance->RAP = CSR15; /* Mode Register */
- lance->RDP = PROM; /* Set promiscuous mode */
- } else {
- short multicast_table[4];
- int num_addrs = dev->mc_count;
- int i;
- /* We don't use the multicast table, but rely on upper-layer filtering. */
- memset(multicast_table, (num_addrs == 0) ? 0 : -1,
- sizeof(multicast_table));
- for (i = 0; i < 4; i++) {
- lance->RAP = CSR8+(i<<8); /* Logical Address Filter */
- lance->RDP = swapw(multicast_table[i]);
- }
- lance->RAP = CSR15; /* Mode Register */
- lance->RDP = 0x0000; /* Unset promiscuous mode */
- }
-
- lance->RAP = CSR0; /* PCnet-ISA Controller Status */
- lance->RDP = INEA|STRT|IDON; /* Resume normal operation. */
-
- netif_wake_queue(dev);
-}
-
-
-static void __devexit ariadne_remove_one(struct zorro_dev *z)
-{
- struct net_device *dev = zorro_get_drvdata(z);
-
- unregister_netdev(dev);
- release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960));
- release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE);
- free_netdev(dev);
-}
-
-static int __init ariadne_init_module(void)
-{
- return zorro_register_driver(&ariadne_driver);
-}
-
-static void __exit ariadne_cleanup_module(void)
-{
- zorro_unregister_driver(&ariadne_driver);
-}
-
-module_init(ariadne_init_module);
-module_exit(ariadne_cleanup_module);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig
deleted file mode 100644
index 8eda6eeb43b..00000000000
--- a/drivers/net/arm/Kconfig
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# Acorn Network device configuration
-# These are for Acorn's Expansion card network interfaces
-#
-config ARM_AM79C961A
- bool "ARM EBSA110 AM79C961A support"
- depends on ARM && ARCH_EBSA110
- select CRC32
- help
- If you wish to compile a kernel for the EBSA-110, then you should
- always answer Y to this.
-
-config ARM_ETHER1
- tristate "Acorn Ether1 support"
- depends on ARM && ARCH_ACORN
- help
- If you have an Acorn system with one of these (AKA25) network cards,
- you should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHER3
- tristate "Acorn/ANT Ether3 support"
- depends on ARM && ARCH_ACORN
- help
- If you have an Acorn system with one of these network cards, you
- should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHERH
- tristate "I-cubed EtherH/ANT EtherM support"
- depends on ARM && ARCH_ACORN
- select CRC32
- help
- If you have an Acorn system with one of these network cards, you
- should say Y to this option if you wish to use it with Linux.
-
-config ARM_AT91_ETHER
- tristate "AT91RM9200 Ethernet support"
- depends on ARM && ARCH_AT91RM9200
- select MII
- help
- If you wish to compile a kernel for the AT91RM9200 and enable
- ethernet support, then you should always answer Y to this.
-
-config EP93XX_ETH
- tristate "EP93xx Ethernet support"
- depends on ARM && ARCH_EP93XX
- select MII
- help
- This is a driver for the ethernet hardware included in EP93xx CPUs.
- Say Y if you are building a kernel for EP93xx based devices.
-
-config IXP4XX_ETH
- tristate "Intel IXP4xx Ethernet support"
- depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
- select MII
- help
- Say Y here if you want to use built-in Ethernet ports
- on IXP4xx processor.
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile
deleted file mode 100644
index 7c812ac2b6a..00000000000
--- a/drivers/net/arm/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# File: drivers/net/arm/Makefile
-#
-# Makefile for the ARM network device drivers
-#
-
-obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
-obj-$(CONFIG_ARM_ETHERH) += etherh.o
-obj-$(CONFIG_ARM_ETHER3) += ether3.o
-obj-$(CONFIG_ARM_ETHER1) += ether1.o
-obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o
-obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o
-obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
deleted file mode 100644
index 0fa53464efb..00000000000
--- a/drivers/net/arm/at91_ether.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-/*
- * Ethernet driver for the Atmel AT91RM9200 (Thunder)
- *
- * Copyright (C) 2003 SAN People (Pty) Ltd
- *
- * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
- * Initial version by Rick Bronson 01/11/2003
- *
- * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker
- * (Polaroid Corporation)
- *
- * Realtek RTL8201(B)L PHY support by Roman Avramenko <roman@imsystems.ru>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/mii.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/dma-mapping.h>
-#include <linux/ethtool.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/mach-types.h>
-
-#include <mach/at91rm9200_emac.h>
-#include <mach/gpio.h>
-#include <mach/board.h>
-
-#include "at91_ether.h"
-
-#define DRV_NAME "at91_ether"
-#define DRV_VERSION "1.0"
-
-#define LINK_POLL_INTERVAL (HZ)
-
-/* ..................................................................... */
-
-/*
- * Read from a EMAC register.
- */
-static inline unsigned long at91_emac_read(unsigned int reg)
-{
- void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC;
-
- return __raw_readl(emac_base + reg);
-}
-
-/*
- * Write to a EMAC register.
- */
-static inline void at91_emac_write(unsigned int reg, unsigned long value)
-{
- void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC;
-
- __raw_writel(value, emac_base + reg);
-}
-
-/* ........................... PHY INTERFACE ........................... */
-
-/*
- * Enable the MDIO bit in MAC control register
- * When not called from an interrupt-handler, access to the PHY must be
- * protected by a spinlock.
- */
-static void enable_mdi(void)
-{
- unsigned long ctl;
-
- ctl = at91_emac_read(AT91_EMAC_CTL);
- at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_MPE); /* enable management port */
-}
-
-/*
- * Disable the MDIO bit in the MAC control register
- */
-static void disable_mdi(void)
-{
- unsigned long ctl;
-
- ctl = at91_emac_read(AT91_EMAC_CTL);
- at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_MPE); /* disable management port */
-}
-
-/*
- * Wait until the PHY operation is complete.
- */
-static inline void at91_phy_wait(void) {
- unsigned long timeout = jiffies + 2;
-
- while (!(at91_emac_read(AT91_EMAC_SR) & AT91_EMAC_SR_IDLE)) {
- if (time_after(jiffies, timeout)) {
- printk("at91_ether: MIO timeout\n");
- break;
- }
- cpu_relax();
- }
-}
-
-/*
- * Write value to the a PHY register
- * Note: MDI interface is assumed to already have been enabled.
- */
-static void write_phy(unsigned char phy_addr, unsigned char address, unsigned int value)
-{
- at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_W
- | ((phy_addr & 0x1f) << 23) | (address << 18) | (value & AT91_EMAC_DATA));
-
- /* Wait until IDLE bit in Network Status register is cleared */
- at91_phy_wait();
-}
-
-/*
- * Read value stored in a PHY register.
- * Note: MDI interface is assumed to already have been enabled.
- */
-static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int *value)
-{
- at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_R
- | ((phy_addr & 0x1f) << 23) | (address << 18));
-
- /* Wait until IDLE bit in Network Status register is cleared */
- at91_phy_wait();
-
- *value = at91_emac_read(AT91_EMAC_MAN) & AT91_EMAC_DATA;
-}
-
-/* ........................... PHY MANAGEMENT .......................... */
-
-/*
- * Access the PHY to determine the current link speed and mode, and update the
- * MAC accordingly.
- * If no link or auto-negotiation is busy, then no changes are made.
- */
-static void update_linkspeed(struct net_device *dev, int silent)
-{
- struct at91_private *lp = netdev_priv(dev);
- unsigned int bmsr, bmcr, lpa, mac_cfg;
- unsigned int speed, duplex;
-
- if (!mii_link_ok(&lp->mii)) { /* no link */
- netif_carrier_off(dev);
- if (!silent)
- printk(KERN_INFO "%s: Link down.\n", dev->name);
- return;
- }
-
- /* Link up, or auto-negotiation still in progress */
- read_phy(lp->phy_address, MII_BMSR, &bmsr);
- read_phy(lp->phy_address, MII_BMCR, &bmcr);
- if (bmcr & BMCR_ANENABLE) { /* AutoNegotiation is enabled */
- if (!(bmsr & BMSR_ANEGCOMPLETE))
- return; /* Do nothing - another interrupt generated when negotiation complete */
-
- read_phy(lp->phy_address, MII_LPA, &lpa);
- if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100;
- else speed = SPEED_10;
- if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL;
- else duplex = DUPLEX_HALF;
- } else {
- speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
- duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
- }
-
- /* Update the MAC */
- mac_cfg = at91_emac_read(AT91_EMAC_CFG) & ~(AT91_EMAC_SPD | AT91_EMAC_FD);
- if (speed == SPEED_100) {
- if (duplex == DUPLEX_FULL) /* 100 Full Duplex */
- mac_cfg |= AT91_EMAC_SPD | AT91_EMAC_FD;
- else /* 100 Half Duplex */
- mac_cfg |= AT91_EMAC_SPD;
- } else {
- if (duplex == DUPLEX_FULL) /* 10 Full Duplex */
- mac_cfg |= AT91_EMAC_FD;
- else {} /* 10 Half Duplex */
- }
- at91_emac_write(AT91_EMAC_CFG, mac_cfg);
-
- if (!silent)
- printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
- netif_carrier_on(dev);
-}
-
-/*
- * Handle interrupts from the PHY
- */
-static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct at91_private *lp = netdev_priv(dev);
- unsigned int phy;
-
- /*
- * This hander is triggered on both edges, but the PHY chips expect
- * level-triggering. We therefore have to check if the PHY actually has
- * an IRQ pending.
- */
- enable_mdi();
- if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {
- read_phy(lp->phy_address, MII_DSINTR_REG, &phy); /* ack interrupt in Davicom PHY */
- if (!(phy & (1 << 0)))
- goto done;
- }
- else if (lp->phy_type == MII_LXT971A_ID) {
- read_phy(lp->phy_address, MII_ISINTS_REG, &phy); /* ack interrupt in Intel PHY */
- if (!(phy & (1 << 2)))
- goto done;
- }
- else if (lp->phy_type == MII_BCM5221_ID) {
- read_phy(lp->phy_address, MII_BCMINTR_REG, &phy); /* ack interrupt in Broadcom PHY */
- if (!(phy & (1 << 0)))
- goto done;
- }
- else if (lp->phy_type == MII_KS8721_ID) {
- read_phy(lp->phy_address, MII_TPISTATUS, &phy); /* ack interrupt in Micrel PHY */
- if (!(phy & ((1 << 2) | 1)))
- goto done;
- }
- else if (lp->phy_type == MII_T78Q21x3_ID) { /* ack interrupt in Teridian PHY */
- read_phy(lp->phy_address, MII_T78Q21INT_REG, &phy);
- if (!(phy & ((1 << 2) | 1)))
- goto done;
- }
- else if (lp->phy_type == MII_DP83848_ID) {
- read_phy(lp->phy_address, MII_DPPHYSTS_REG, &phy); /* ack interrupt in DP83848 PHY */
- if (!(phy & (1 << 7)))
- goto done;
- }
-
- update_linkspeed(dev, 0);
-
-done:
- disable_mdi();
-
- return IRQ_HANDLED;
-}
-
-/*
- * Initialize and enable the PHY interrupt for link-state changes
- */
-static void enable_phyirq(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- unsigned int dsintr, irq_number;
- int status;
-
- irq_number = lp->board_data.phy_irq_pin;
- if (!irq_number) {
- /*
- * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L),
- * or board does not have it connected.
- */
- mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL);
- return;
- }
-
- status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev);
- if (status) {
- printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status);
- return;
- }
-
- spin_lock_irq(&lp->lock);
- enable_mdi();
-
- if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { /* for Davicom PHY */
- read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr);
- dsintr = dsintr & ~0xf00; /* clear bits 8..11 */
- write_phy(lp->phy_address, MII_DSINTR_REG, dsintr);
- }
- else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */
- read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr);
- dsintr = dsintr | 0xf2; /* set bits 1, 4..7 */
- write_phy(lp->phy_address, MII_ISINTE_REG, dsintr);
- }
- else if (lp->phy_type == MII_BCM5221_ID) { /* for Broadcom PHY */
- dsintr = (1 << 15) | ( 1 << 14);
- write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr);
- }
- else if (lp->phy_type == MII_KS8721_ID) { /* for Micrel PHY */
- dsintr = (1 << 10) | ( 1 << 8);
- write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
- }
- else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */
- read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
- dsintr = dsintr | 0x500; /* set bits 8, 10 */
- write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
- }
- else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */
- read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
- dsintr = dsintr | 0x3c; /* set bits 2..5 */
- write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
- read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
- dsintr = dsintr | 0x3; /* set bits 0,1 */
- write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
- }
-
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-}
-
-/*
- * Disable the PHY interrupt
- */
-static void disable_phyirq(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- unsigned int dsintr;
- unsigned int irq_number;
-
- irq_number = lp->board_data.phy_irq_pin;
- if (!irq_number) {
- del_timer_sync(&lp->check_timer);
- return;
- }
-
- spin_lock_irq(&lp->lock);
- enable_mdi();
-
- if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) { /* for Davicom PHY */
- read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr);
- dsintr = dsintr | 0xf00; /* set bits 8..11 */
- write_phy(lp->phy_address, MII_DSINTR_REG, dsintr);
- }
- else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */
- read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr);
- dsintr = dsintr & ~0xf2; /* clear bits 1, 4..7 */
- write_phy(lp->phy_address, MII_ISINTE_REG, dsintr);
- }
- else if (lp->phy_type == MII_BCM5221_ID) { /* for Broadcom PHY */
- read_phy(lp->phy_address, MII_BCMINTR_REG, &dsintr);
- dsintr = ~(1 << 14);
- write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr);
- }
- else if (lp->phy_type == MII_KS8721_ID) { /* for Micrel PHY */
- read_phy(lp->phy_address, MII_TPISTATUS, &dsintr);
- dsintr = ~((1 << 10) | (1 << 8));
- write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
- }
- else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */
- read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
- dsintr = dsintr & ~0x500; /* clear bits 8, 10 */
- write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
- }
- else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */
- read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
- dsintr = dsintr & ~0x3; /* clear bits 0, 1 */
- write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
- read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
- dsintr = dsintr & ~0x3c; /* clear bits 2..5 */
- write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
- }
-
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-
- free_irq(irq_number, dev); /* Free interrupt handler */
-}
-
-/*
- * Perform a software reset of the PHY.
- */
-#if 0
-static void reset_phy(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- unsigned int bmcr;
-
- spin_lock_irq(&lp->lock);
- enable_mdi();
-
- /* Perform PHY reset */
- write_phy(lp->phy_address, MII_BMCR, BMCR_RESET);
-
- /* Wait until PHY reset is complete */
- do {
- read_phy(lp->phy_address, MII_BMCR, &bmcr);
- } while (!(bmcr & BMCR_RESET));
-
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-}
-#endif
-
-static void at91ether_check_link(unsigned long dev_id)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct at91_private *lp = netdev_priv(dev);
-
- enable_mdi();
- update_linkspeed(dev, 1);
- disable_mdi();
-
- mod_timer(&lp->check_timer, jiffies + LINK_POLL_INTERVAL);
-}
-
-/* ......................... ADDRESS MANAGEMENT ........................ */
-
-/*
- * NOTE: Your bootloader must always set the MAC address correctly before
- * booting into Linux.
- *
- * - It must always set the MAC address after reset, even if it doesn't
- * happen to access the Ethernet while it's booting. Some versions of
- * U-Boot on the AT91RM9200-DK do not do this.
- *
- * - Likewise it must store the addresses in the correct byte order.
- * MicroMonitor (uMon) on the CSB337 does this incorrectly (and
- * continues to do so, for bug-compatibility).
- */
-
-static short __init unpack_mac_address(struct net_device *dev, unsigned int hi, unsigned int lo)
-{
- char addr[6];
-
- if (machine_is_csb337()) {
- addr[5] = (lo & 0xff); /* The CSB337 bootloader stores the MAC the wrong-way around */
- addr[4] = (lo & 0xff00) >> 8;
- addr[3] = (lo & 0xff0000) >> 16;
- addr[2] = (lo & 0xff000000) >> 24;
- addr[1] = (hi & 0xff);
- addr[0] = (hi & 0xff00) >> 8;
- }
- else {
- addr[0] = (lo & 0xff);
- addr[1] = (lo & 0xff00) >> 8;
- addr[2] = (lo & 0xff0000) >> 16;
- addr[3] = (lo & 0xff000000) >> 24;
- addr[4] = (hi & 0xff);
- addr[5] = (hi & 0xff00) >> 8;
- }
-
- if (is_valid_ether_addr(addr)) {
- memcpy(dev->dev_addr, &addr, 6);
- return 1;
- }
- return 0;
-}
-
-/*
- * Set the ethernet MAC address in dev->dev_addr
- */
-static void __init get_mac_address(struct net_device *dev)
-{
- /* Check Specific-Address 1 */
- if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA1H), at91_emac_read(AT91_EMAC_SA1L)))
- return;
- /* Check Specific-Address 2 */
- if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA2H), at91_emac_read(AT91_EMAC_SA2L)))
- return;
- /* Check Specific-Address 3 */
- if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA3H), at91_emac_read(AT91_EMAC_SA3L)))
- return;
- /* Check Specific-Address 4 */
- if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA4H), at91_emac_read(AT91_EMAC_SA4L)))
- return;
-
- printk(KERN_ERR "at91_ether: Your bootloader did not configure a MAC address.\n");
-}
-
-/*
- * Program the hardware MAC address from dev->dev_addr.
- */
-static void update_mac_address(struct net_device *dev)
-{
- at91_emac_write(AT91_EMAC_SA1L, (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) | (dev->dev_addr[1] << 8) | (dev->dev_addr[0]));
- at91_emac_write(AT91_EMAC_SA1H, (dev->dev_addr[5] << 8) | (dev->dev_addr[4]));
-
- at91_emac_write(AT91_EMAC_SA2L, 0);
- at91_emac_write(AT91_EMAC_SA2H, 0);
-}
-
-/*
- * Store the new hardware address in dev->dev_addr, and update the MAC.
- */
-static int set_mac_address(struct net_device *dev, void* addr)
-{
- struct sockaddr *address = addr;
- DECLARE_MAC_BUF(mac);
-
- if (!is_valid_ether_addr(address->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
- update_mac_address(dev);
-
- printk("%s: Setting MAC address to %s\n", dev->name,
- print_mac(mac, dev->dev_addr));
-
- return 0;
-}
-
-static int inline hash_bit_value(int bitnr, __u8 *addr)
-{
- if (addr[bitnr / 8] & (1 << (bitnr % 8)))
- return 1;
- return 0;
-}
-
-/*
- * The hash address register is 64 bits long and takes up two locations in the memory map.
- * The least significant bits are stored in EMAC_HSL and the most significant
- * bits in EMAC_HSH.
- *
- * The unicast hash enable and the multicast hash enable bits in the network configuration
- * register enable the reception of hash matched frames. The destination address is
- * reduced to a 6 bit index into the 64 bit hash register using the following hash function.
- * The hash function is an exclusive or of every sixth bit of the destination address.
- * hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
- * hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
- * hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
- * hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
- * hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
- * hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
- * da[0] represents the least significant bit of the first byte received, that is, the multicast/
- * unicast indicator, and da[47] represents the most significant bit of the last byte
- * received.
- * If the hash index points to a bit that is set in the hash register then the frame will be
- * matched according to whether the frame is multicast or unicast.
- * A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and
- * the hash index points to a bit set in the hash register.
- * A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the
- * hash index points to a bit set in the hash register.
- * To receive all multicast frames, the hash register should be set with all ones and the
- * multicast hash enable bit should be set in the network configuration register.
- */
-
-/*
- * Return the hash index value for the specified address.
- */
-static int hash_get_index(__u8 *addr)
-{
- int i, j, bitval;
- int hash_index = 0;
-
- for (j = 0; j < 6; j++) {
- for (i = 0, bitval = 0; i < 8; i++)
- bitval ^= hash_bit_value(i*6 + j, addr);
-
- hash_index |= (bitval << j);
- }
-
- return hash_index;
-}
-
-/*
- * Add multicast addresses to the internal multicast-hash table.
- */
-static void at91ether_sethashtable(struct net_device *dev)
-{
- struct dev_mc_list *curr;
- unsigned long mc_filter[2];
- unsigned int i, bitnr;
-
- mc_filter[0] = mc_filter[1] = 0;
-
- curr = dev->mc_list;
- for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
- if (!curr) break; /* unexpected end of list */
-
- bitnr = hash_get_index(curr->dmi_addr);
- mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
- }
-
- at91_emac_write(AT91_EMAC_HSL, mc_filter[0]);
- at91_emac_write(AT91_EMAC_HSH, mc_filter[1]);
-}
-
-/*
- * Enable/Disable promiscuous and multicast modes.
- */
-static void at91ether_set_rx_mode(struct net_device *dev)
-{
- unsigned long cfg;
-
- cfg = at91_emac_read(AT91_EMAC_CFG);
-
- if (dev->flags & IFF_PROMISC) /* Enable promiscuous mode */
- cfg |= AT91_EMAC_CAF;
- else if (dev->flags & (~IFF_PROMISC)) /* Disable promiscuous mode */
- cfg &= ~AT91_EMAC_CAF;
-
- if (dev->flags & IFF_ALLMULTI) { /* Enable all multicast mode */
- at91_emac_write(AT91_EMAC_HSH, -1);
- at91_emac_write(AT91_EMAC_HSL, -1);
- cfg |= AT91_EMAC_MTI;
- } else if (dev->mc_count > 0) { /* Enable specific multicasts */
- at91ether_sethashtable(dev);
- cfg |= AT91_EMAC_MTI;
- } else if (dev->flags & (~IFF_ALLMULTI)) { /* Disable all multicast mode */
- at91_emac_write(AT91_EMAC_HSH, 0);
- at91_emac_write(AT91_EMAC_HSL, 0);
- cfg &= ~AT91_EMAC_MTI;
- }
-
- at91_emac_write(AT91_EMAC_CFG, cfg);
-}
-
-/* ......................... ETHTOOL SUPPORT ........................... */
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
- unsigned int value;
-
- read_phy(phy_id, location, &value);
- return value;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-{
- write_phy(phy_id, location, value);
-}
-
-static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct at91_private *lp = netdev_priv(dev);
- int ret;
-
- spin_lock_irq(&lp->lock);
- enable_mdi();
-
- ret = mii_ethtool_gset(&lp->mii, cmd);
-
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-
- if (lp->phy_media == PORT_FIBRE) { /* override media type since mii.c doesn't know */
- cmd->supported = SUPPORTED_FIBRE;
- cmd->port = PORT_FIBRE;
- }
-
- return ret;
-}
-
-static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct at91_private *lp = netdev_priv(dev);
- int ret;
-
- spin_lock_irq(&lp->lock);
- enable_mdi();
-
- ret = mii_ethtool_sset(&lp->mii, cmd);
-
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-
- return ret;
-}
-
-static int at91ether_nwayreset(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- int ret;
-
- spin_lock_irq(&lp->lock);
- enable_mdi();
-
- ret = mii_nway_restart(&lp->mii);
-
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-
- return ret;
-}
-
-static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
- strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
-}
-
-static const struct ethtool_ops at91ether_ethtool_ops = {
- .get_settings = at91ether_get_settings,
- .set_settings = at91ether_set_settings,
- .get_drvinfo = at91ether_get_drvinfo,
- .nway_reset = at91ether_nwayreset,
- .get_link = ethtool_op_get_link,
-};
-
-static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct at91_private *lp = netdev_priv(dev);
- int res;
-
- if (!netif_running(dev))
- return -EINVAL;
-
- spin_lock_irq(&lp->lock);
- enable_mdi();
- res = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL);
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-
- return res;
-}
-
-/* ................................ MAC ................................ */
-
-/*
- * Initialize and start the Receiver and Transmit subsystems
- */
-static void at91ether_start(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- struct recv_desc_bufs *dlist, *dlist_phys;
- int i;
- unsigned long ctl;
-
- dlist = lp->dlist;
- dlist_phys = lp->dlist_phys;
-
- for (i = 0; i < MAX_RX_DESCR; i++) {
- dlist->descriptors[i].addr = (unsigned int) &dlist_phys->recv_buf[i][0];
- dlist->descriptors[i].size = 0;
- }
-
- /* Set the Wrap bit on the last descriptor */
- dlist->descriptors[i-1].addr |= EMAC_DESC_WRAP;
-
- /* Reset buffer index */
- lp->rxBuffIndex = 0;
-
- /* Program address of descriptor list in Rx Buffer Queue register */
- at91_emac_write(AT91_EMAC_RBQP, (unsigned long) dlist_phys);
-
- /* Enable Receive and Transmit */
- ctl = at91_emac_read(AT91_EMAC_CTL);
- at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE | AT91_EMAC_TE);
-}
-
-/*
- * Open the ethernet interface
- */
-static int at91ether_open(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- unsigned long ctl;
-
- if (!is_valid_ether_addr(dev->dev_addr))
- return -EADDRNOTAVAIL;
-
- clk_enable(lp->ether_clk); /* Re-enable Peripheral clock */
-
- /* Clear internal statistics */
- ctl = at91_emac_read(AT91_EMAC_CTL);
- at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_CSR);
-
- /* Update the MAC address (incase user has changed it) */
- update_mac_address(dev);
-
- /* Enable PHY interrupt */
- enable_phyirq(dev);
-
- /* Enable MAC interrupts */
- at91_emac_write(AT91_EMAC_IER, AT91_EMAC_RCOM | AT91_EMAC_RBNA
- | AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM
- | AT91_EMAC_ROVR | AT91_EMAC_ABT);
-
- /* Determine current link speed */
- spin_lock_irq(&lp->lock);
- enable_mdi();
- update_linkspeed(dev, 0);
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-
- at91ether_start(dev);
- netif_start_queue(dev);
- return 0;
-}
-
-/*
- * Close the interface
- */
-static int at91ether_close(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- unsigned long ctl;
-
- /* Disable Receiver and Transmitter */
- ctl = at91_emac_read(AT91_EMAC_CTL);
- at91_emac_write(AT91_EMAC_CTL, ctl & ~(AT91_EMAC_TE | AT91_EMAC_RE));
-
- /* Disable PHY interrupt */
- disable_phyirq(dev);
-
- /* Disable MAC interrupts */
- at91_emac_write(AT91_EMAC_IDR, AT91_EMAC_RCOM | AT91_EMAC_RBNA
- | AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM
- | AT91_EMAC_ROVR | AT91_EMAC_ABT);
-
- netif_stop_queue(dev);
-
- clk_disable(lp->ether_clk); /* Disable Peripheral clock */
-
- return 0;
-}
-
-/*
- * Transmit packet.
- */
-static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
-
- if (at91_emac_read(AT91_EMAC_TSR) & AT91_EMAC_TSR_BNQ) {
- netif_stop_queue(dev);
-
- /* Store packet information (to free when Tx completed) */
- lp->skb = skb;
- lp->skb_length = skb->len;
- lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
- dev->stats.tx_bytes += skb->len;
-
- /* Set address of the data in the Transmit Address register */
- at91_emac_write(AT91_EMAC_TAR, lp->skb_physaddr);
- /* Set length of the packet in the Transmit Control register */
- at91_emac_write(AT91_EMAC_TCR, skb->len);
-
- dev->trans_start = jiffies;
- } else {
- printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n");
- return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
- on this skb, he also reports -ENETDOWN and printk's, so either
- we free and return(0) or don't free and return 1 */
- }
-
- return 0;
-}
-
-/*
- * Update the current statistics from the internal statistics registers.
- */
-static struct net_device_stats *at91ether_stats(struct net_device *dev)
-{
- int ale, lenerr, seqe, lcol, ecol;
-
- if (netif_running(dev)) {
- dev->stats.rx_packets += at91_emac_read(AT91_EMAC_OK); /* Good frames received */
- ale = at91_emac_read(AT91_EMAC_ALE);
- dev->stats.rx_frame_errors += ale; /* Alignment errors */
- lenerr = at91_emac_read(AT91_EMAC_ELR) + at91_emac_read(AT91_EMAC_USF);
- dev->stats.rx_length_errors += lenerr; /* Excessive Length or Undersize Frame error */
- seqe = at91_emac_read(AT91_EMAC_SEQE);
- dev->stats.rx_crc_errors += seqe; /* CRC error */
- dev->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC); /* Receive buffer not available */
- dev->stats.rx_errors += (ale + lenerr + seqe
- + at91_emac_read(AT91_EMAC_CDE) + at91_emac_read(AT91_EMAC_RJB));
-
- dev->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA); /* Frames successfully transmitted */
- dev->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE); /* Transmit FIFO underruns */
- dev->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE); /* Carrier Sense errors */
- dev->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */
-
- lcol = at91_emac_read(AT91_EMAC_LCOL);
- ecol = at91_emac_read(AT91_EMAC_ECOL);
- dev->stats.tx_window_errors += lcol; /* Late collisions */
- dev->stats.tx_aborted_errors += ecol; /* 16 collisions */
-
- dev->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol);
- }
- return &dev->stats;
-}
-
-/*
- * Extract received frame from buffer descriptors and sent to upper layers.
- * (Called from interrupt context)
- */
-static void at91ether_rx(struct net_device *dev)
-{
- struct at91_private *lp = netdev_priv(dev);
- struct recv_desc_bufs *dlist;
- unsigned char *p_recv;
- struct sk_buff *skb;
- unsigned int pktlen;
-
- dlist = lp->dlist;
- while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) {
- p_recv = dlist->recv_buf[lp->rxBuffIndex];
- pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff; /* Length of frame including FCS */
- skb = dev_alloc_skb(pktlen + 2);
- if (skb != NULL) {
- skb_reserve(skb, 2);
- memcpy(skb_put(skb, pktlen), p_recv, pktlen);
-
- skb->protocol = eth_type_trans(skb, dev);
- dev->last_rx = jiffies;
- dev->stats.rx_bytes += pktlen;
- netif_rx(skb);
- }
- else {
- dev->stats.rx_dropped += 1;
- printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
- }
-
- if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST)
- dev->stats.multicast++;
-
- dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE; /* reset ownership bit */
- if (lp->rxBuffIndex == MAX_RX_DESCR-1) /* wrap after last buffer */
- lp->rxBuffIndex = 0;
- else
- lp->rxBuffIndex++;
- }
-}
-
-/*
- * MAC interrupt handler
- */
-static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct at91_private *lp = netdev_priv(dev);
- unsigned long intstatus, ctl;
-
- /* MAC Interrupt Status register indicates what interrupts are pending.
- It is automatically cleared once read. */
- intstatus = at91_emac_read(AT91_EMAC_ISR);
-
- if (intstatus & AT91_EMAC_RCOM) /* Receive complete */
- at91ether_rx(dev);
-
- if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */
- /* The TCOM bit is set even if the transmission failed. */
- if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY))
- dev->stats.tx_errors += 1;
-
- if (lp->skb) {
- dev_kfree_skb_irq(lp->skb);
- lp->skb = NULL;
- dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE);
- }
- netif_wake_queue(dev);
- }
-
- /* Work-around for Errata #11 */
- if (intstatus & AT91_EMAC_RBNA) {
- ctl = at91_emac_read(AT91_EMAC_CTL);
- at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_RE);
- at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE);
- }
-
- if (intstatus & AT91_EMAC_ROVR)
- printk("%s: ROVR error\n", dev->name);
-
- return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void at91ether_poll_controller(struct net_device *dev)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- at91ether_interrupt(dev->irq, dev);
- local_irq_restore(flags);
-}
-#endif
-
-/*
- * Initialize the ethernet interface
- */
-static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address,
- struct platform_device *pdev, struct clk *ether_clk)
-{
- struct at91_eth_data *board_data = pdev->dev.platform_data;
- struct net_device *dev;
- struct at91_private *lp;
- unsigned int val;
- int res;
- DECLARE_MAC_BUF(mac);
-
- dev = alloc_etherdev(sizeof(struct at91_private));
- if (!dev)
- return -ENOMEM;
-
- dev->base_addr = AT91_VA_BASE_EMAC;
- dev->irq = AT91RM9200_ID_EMAC;
-
- /* Install the interrupt handler */
- if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev)) {
- free_netdev(dev);
- return -EBUSY;
- }
-
- /* Allocate memory for DMA Receive descriptors */
- lp = netdev_priv(dev);
- lp->dlist = (struct recv_desc_bufs *) dma_alloc_coherent(NULL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys, GFP_KERNEL);
- if (lp->dlist == NULL) {
- free_irq(dev->irq, dev);
- free_netdev(dev);
- return -ENOMEM;
- }
- lp->board_data = *board_data;
- lp->ether_clk = ether_clk;
- platform_set_drvdata(pdev, dev);
-
- spin_lock_init(&lp->lock);
-
- ether_setup(dev);
- dev->open = at91ether_open;
- dev->stop = at91ether_close;
- dev->hard_start_xmit = at91ether_tx;
- dev->get_stats = at91ether_stats;
- dev->set_multicast_list = at91ether_set_rx_mode;
- dev->set_mac_address = set_mac_address;
- dev->ethtool_ops = &at91ether_ethtool_ops;
- dev->do_ioctl = at91ether_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = at91ether_poll_controller;
-#endif
-
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */
- update_mac_address(dev); /* Program ethernet address into MAC */
-
- at91_emac_write(AT91_EMAC_CTL, 0);
-
- if (lp->board_data.is_rmii)
- at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG | AT91_EMAC_RMII);
- else
- at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG);
-
- /* Perform PHY-specific initialization */
- spin_lock_irq(&lp->lock);
- enable_mdi();
- if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {
- read_phy(phy_address, MII_DSCR_REG, &val);
- if ((val & (1 << 10)) == 0) /* DSCR bit 10 is 0 -- fiber mode */
- lp->phy_media = PORT_FIBRE;
- } else if (machine_is_csb337()) {
- /* mix link activity status into LED2 link state */
- write_phy(phy_address, MII_LEDCTRL_REG, 0x0d22);
- } else if (machine_is_ecbat91())
- write_phy(phy_address, MII_LEDCTRL_REG, 0x156A);
-
- disable_mdi();
- spin_unlock_irq(&lp->lock);
-
- lp->mii.dev = dev; /* Support for ethtool */
- lp->mii.mdio_read = mdio_read;
- lp->mii.mdio_write = mdio_write;
- lp->mii.phy_id = phy_address;
- lp->mii.phy_id_mask = 0x1f;
- lp->mii.reg_num_mask = 0x1f;
-
- lp->phy_type = phy_type; /* Type of PHY connected */
- lp->phy_address = phy_address; /* MDI address of PHY */
-
- /* Register the network interface */
- res = register_netdev(dev);
- if (res) {
- free_irq(dev->irq, dev);
- free_netdev(dev);
- dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
- return res;
- }
-
- /* Determine current link speed */
- spin_lock_irq(&lp->lock);
- enable_mdi();
- update_linkspeed(dev, 0);
- disable_mdi();
- spin_unlock_irq(&lp->lock);
- netif_carrier_off(dev); /* will be enabled in open() */
-
- /* If board has no PHY IRQ, use a timer to poll the PHY */
- if (!lp->board_data.phy_irq_pin) {
- init_timer(&lp->check_timer);
- lp->check_timer.data = (unsigned long)dev;
- lp->check_timer.function = at91ether_check_link;
- }
-
- /* Display ethernet banner */
- printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%s)\n",
- dev->name, (uint) dev->base_addr, dev->irq,
- at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-",
- at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex",
- print_mac(mac, dev->dev_addr));
- if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID))
- printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)");
- else if (phy_type == MII_LXT971A_ID)
- printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name);
- else if (phy_type == MII_RTL8201_ID)
- printk(KERN_INFO "%s: Realtek RTL8201(B)L PHY\n", dev->name);
- else if (phy_type == MII_BCM5221_ID)
- printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name);
- else if (phy_type == MII_DP83847_ID)
- printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name);
- else if (phy_type == MII_DP83848_ID)
- printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name);
- else if (phy_type == MII_AC101L_ID)
- printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name);
- else if (phy_type == MII_KS8721_ID)
- printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name);
- else if (phy_type == MII_T78Q21x3_ID)
- printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name);
- else if (phy_type == MII_LAN83C185_ID)
- printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name);
-
- return 0;
-}
-
-/*
- * Detect MAC and PHY and perform initialization
- */
-static int __init at91ether_probe(struct platform_device *pdev)
-{
- unsigned int phyid1, phyid2;
- int detected = -1;
- unsigned long phy_id;
- unsigned short phy_address = 0;
- struct clk *ether_clk;
-
- ether_clk = clk_get(&pdev->dev, "ether_clk");
- if (IS_ERR(ether_clk)) {
- printk(KERN_ERR "at91_ether: no clock defined\n");
- return -ENODEV;
- }
- clk_enable(ether_clk); /* Enable Peripheral clock */
-
- while ((detected != 0) && (phy_address < 32)) {
- /* Read the PHY ID registers */
- enable_mdi();
- read_phy(phy_address, MII_PHYSID1, &phyid1);
- read_phy(phy_address, MII_PHYSID2, &phyid2);
- disable_mdi();
-
- phy_id = (phyid1 << 16) | (phyid2 & 0xfff0);
- switch (phy_id) {
- case MII_DM9161_ID: /* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */
- case MII_DM9161A_ID: /* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */
- case MII_LXT971A_ID: /* Intel LXT971A: PHY_ID1 = 0x13, PHY_ID2 = 78E0 */
- case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
- case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
- case MII_DP83847_ID: /* National Semiconductor DP83847: */
- case MII_DP83848_ID: /* National Semiconductor DP83848: */
- case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
- case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
- case MII_T78Q21x3_ID: /* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */
- case MII_LAN83C185_ID: /* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */
- detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk);
- break;
- }
-
- phy_address++;
- }
-
- clk_disable(ether_clk); /* Disable Peripheral clock */
-
- return detected;
-}
-
-static int __devexit at91ether_remove(struct platform_device *pdev)
-{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct at91_private *lp = netdev_priv(dev);
-
- unregister_netdev(dev);
- free_irq(dev->irq, dev);
- dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
- clk_put(lp->ether_clk);
-
- platform_set_drvdata(pdev, NULL);
- free_netdev(dev);
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
- struct net_device *net_dev = platform_get_drvdata(pdev);
- struct at91_private *lp = netdev_priv(net_dev);
- int phy_irq = lp->board_data.phy_irq_pin;
-
- if (netif_running(net_dev)) {
- if (phy_irq)
- disable_irq(phy_irq);
-
- netif_stop_queue(net_dev);
- netif_device_detach(net_dev);
-
- clk_disable(lp->ether_clk);
- }
- return 0;
-}
-
-static int at91ether_resume(struct platform_device *pdev)
-{
- struct net_device *net_dev = platform_get_drvdata(pdev);
- struct at91_private *lp = netdev_priv(net_dev);
- int phy_irq = lp->board_data.phy_irq_pin;
-
- if (netif_running(net_dev)) {
- clk_enable(lp->ether_clk);
-
- netif_device_attach(net_dev);
- netif_start_queue(net_dev);
-
- if (phy_irq)
- enable_irq(phy_irq);
- }
- return 0;
-}
-
-#else
-#define at91ether_suspend NULL
-#define at91ether_resume NULL
-#endif
-
-static struct platform_driver at91ether_driver = {
- .probe = at91ether_probe,
- .remove = __devexit_p(at91ether_remove),
- .suspend = at91ether_suspend,
- .resume = at91ether_resume,
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-static int __init at91ether_init(void)
-{
- return platform_driver_register(&at91ether_driver);
-}
-
-static void __exit at91ether_exit(void)
-{
- platform_driver_unregister(&at91ether_driver);
-}
-
-module_init(at91ether_init)
-module_exit(at91ether_exit)
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver");
-MODULE_AUTHOR("Andrew Victor");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h
deleted file mode 100644
index 353f4dab62b..00000000000
--- a/drivers/net/arm/at91_ether.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Ethernet driver for the Atmel AT91RM9200 (Thunder)
- *
- * Copyright (C) SAN People (Pty) Ltd
- *
- * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
- * Initial version by Rick Bronson.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef AT91_ETHERNET
-#define AT91_ETHERNET
-
-
-/* Davicom 9161 PHY */
-#define MII_DM9161_ID 0x0181b880
-#define MII_DM9161A_ID 0x0181b8a0
-#define MII_DSCR_REG 16
-#define MII_DSCSR_REG 17
-#define MII_DSINTR_REG 21
-
-/* Intel LXT971A PHY */
-#define MII_LXT971A_ID 0x001378E0
-#define MII_ISINTE_REG 18
-#define MII_ISINTS_REG 19
-#define MII_LEDCTRL_REG 20
-
-/* Realtek RTL8201 PHY */
-#define MII_RTL8201_ID 0x00008200
-
-/* Broadcom BCM5221 PHY */
-#define MII_BCM5221_ID 0x004061e0
-#define MII_BCMINTR_REG 26
-
-/* National Semiconductor DP83847 */
-#define MII_DP83847_ID 0x20005c30
-
-/* National Semiconductor DP83848 */
-#define MII_DP83848_ID 0x20005c90
-#define MII_DPPHYSTS_REG 16
-#define MII_DPMICR_REG 17
-#define MII_DPMISR_REG 18
-
-/* Altima AC101L PHY */
-#define MII_AC101L_ID 0x00225520
-
-/* Micrel KS8721 PHY */
-#define MII_KS8721_ID 0x00221610
-
-/* Teridian 78Q2123/78Q2133 */
-#define MII_T78Q21x3_ID 0x000e7230
-#define MII_T78Q21INT_REG 17
-
-/* SMSC LAN83C185 */
-#define MII_LAN83C185_ID 0x0007C0A0
-
-/* ........................................................................ */
-
-#define MAX_RBUFF_SZ 0x600 /* 1518 rounded up */
-#define MAX_RX_DESCR 9 /* max number of receive buffers */
-
-#define EMAC_DESC_DONE 0x00000001 /* bit for if DMA is done */
-#define EMAC_DESC_WRAP 0x00000002 /* bit for wrap */
-
-#define EMAC_BROADCAST 0x80000000 /* broadcast address */
-#define EMAC_MULTICAST 0x40000000 /* multicast address */
-#define EMAC_UNICAST 0x20000000 /* unicast address */
-
-struct rbf_t
-{
- unsigned int addr;
- unsigned long size;
-};
-
-struct recv_desc_bufs
-{
- struct rbf_t descriptors[MAX_RX_DESCR]; /* must be on sizeof (rbf_t) boundary */
- char recv_buf[MAX_RX_DESCR][MAX_RBUFF_SZ]; /* must be on long boundary */
-};
-
-struct at91_private
-{
- struct mii_if_info mii; /* ethtool support */
- struct at91_eth_data board_data; /* board-specific configuration */
- struct clk *ether_clk; /* clock */
-
- /* PHY */
- unsigned long phy_type; /* type of PHY (PHY_ID) */
- spinlock_t lock; /* lock for MDI interface */
- short phy_media; /* media interface type */
- unsigned short phy_address; /* 5-bit MDI address of PHY (0..31) */
- struct timer_list check_timer; /* Poll link status */
-
- /* Transmit */
- struct sk_buff *skb; /* holds skb until xmit interrupt completes */
- dma_addr_t skb_physaddr; /* phys addr from pci_map_single */
- int skb_length; /* saved skb length for pci_unmap_single */
-
- /* Receive */
- int rxBuffIndex; /* index into receive descriptor list */
- struct recv_desc_bufs *dlist; /* descriptor list address */
- struct recv_desc_bufs *dlist_phys; /* descriptor list physical address */
-};
-
-#endif
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
deleted file mode 100644
index 7e874d485d2..00000000000
--- a/drivers/net/at1700.c
+++ /dev/null
@@ -1,915 +0,0 @@
-/* at1700.c: A network device driver for the Allied Telesis AT1700.
-
- Written 1993-98 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- This is a device driver for the Allied Telesis AT1700, and
- Fujitsu FMV-181/182/181A/182A/183/184/183A/184A, which are
- straight-forward Fujitsu MB86965 implementations.
-
- Modification for Fujitsu FMV-18X cards is done by Yutaka Tamiya
- (tamy@flab.fujitsu.co.jp).
-
- Sources:
- The Fujitsu MB86965 datasheet.
-
- After the initial version of this driver was written Gerry Sawkins of
- ATI provided their EEPROM configuration code header file.
- Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes.
-
- MCA bus (AT1720) support by Rene Schmit <rene@bss.lu>
-
- Bugs:
- The MB86965 has a design flaw that makes all probes unreliable. Not
- only is it difficult to detect, it also moves around in I/O space in
- response to inb()s from other device probes!
-*/
-
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/mca-legacy.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-static char version[] __initdata =
- "at1700.c:v1.16 9/11/06 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#define DRV_NAME "at1700"
-
-/* Tunable parameters. */
-
-/* When to switch from the 64-entry multicast filter to Rx-all-multicast. */
-#define MC_FILTERBREAK 64
-
-/* These unusual address orders are used to verify the CONFIG register. */
-
-static int fmv18x_probe_list[] __initdata = {
- 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
-};
-
-/*
- * ISA
- */
-
-static unsigned at1700_probe_list[] __initdata = {
- 0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
-};
-
-/*
- * MCA
- */
-#ifdef CONFIG_MCA_LEGACY
-static int at1700_ioaddr_pattern[] __initdata = {
- 0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07
-};
-
-static int at1700_mca_probe_list[] __initdata = {
- 0x400, 0x1400, 0x2400, 0x3400, 0x4400, 0x5400, 0x6400, 0x7400, 0
-};
-
-static int at1700_irq_pattern[] __initdata = {
- 0x00, 0x00, 0x00, 0x30, 0x70, 0xb0, 0x00, 0x00,
- 0x00, 0xf0, 0x34, 0x74, 0xb4, 0x00, 0x00, 0xf4, 0x00
-};
-#endif
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-typedef unsigned char uchar;
-
-/* Information that need to be kept for each board. */
-struct net_local {
- spinlock_t lock;
- unsigned char mc_filter[8];
- uint jumpered:1; /* Set iff the board has jumper config. */
- uint tx_started:1; /* Packets are on the Tx queue. */
- uint tx_queue_ready:1; /* Tx queue is ready to be sent. */
- uint rx_started:1; /* Packets are Rxing. */
- uchar tx_queue; /* Number of packet on the Tx queue. */
- char mca_slot; /* -1 means ISA */
- ushort tx_queue_len; /* Current length of the Tx queue. */
-};
-
-
-/* Offsets from the base address. */
-#define STATUS 0
-#define TX_STATUS 0
-#define RX_STATUS 1
-#define TX_INTR 2 /* Bit-mapped interrupt enable registers. */
-#define RX_INTR 3
-#define TX_MODE 4
-#define RX_MODE 5
-#define CONFIG_0 6 /* Misc. configuration settings. */
-#define CONFIG_1 7
-/* Run-time register bank 2 definitions. */
-#define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
-#define TX_START 10
-#define COL16CNTL 11 /* Controll Reg for 16 collisions */
-#define MODE13 13
-#define RX_CTRL 14
-/* Configuration registers only on the '865A/B chips. */
-#define EEPROM_Ctrl 16
-#define EEPROM_Data 17
-#define CARDSTATUS 16 /* FMV-18x Card Status */
-#define CARDSTATUS1 17 /* FMV-18x Card Status */
-#define IOCONFIG 18 /* Either read the jumper, or move the I/O. */
-#define IOCONFIG1 19
-#define SAPROM 20 /* The station address PROM, if no EEPROM. */
-#define MODE24 24
-#define RESET 31 /* Write to reset some parts of the chip. */
-#define AT1700_IO_EXTENT 32
-#define PORT_OFFSET(o) (o)
-
-
-#define TX_TIMEOUT 10
-
-
-/* Index to functions, as function prototypes. */
-
-static int at1700_probe1(struct net_device *dev, int ioaddr);
-static int read_eeprom(long ioaddr, int location);
-static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id);
-static void net_rx(struct net_device *dev);
-static int net_close(struct net_device *dev);
-static void set_rx_mode(struct net_device *dev);
-static void net_tx_timeout (struct net_device *dev);
-
-
-#ifdef CONFIG_MCA_LEGACY
-struct at1720_mca_adapters_struct {
- char* name;
- int id;
-};
-/* rEnE : maybe there are others I don't know off... */
-
-static struct at1720_mca_adapters_struct at1720_mca_adapters[] __initdata = {
- { "Allied Telesys AT1720AT", 0x6410 },
- { "Allied Telesys AT1720BT", 0x6413 },
- { "Allied Telesys AT1720T", 0x6416 },
- { NULL, 0 },
-};
-#endif
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-
-static int io = 0x260;
-
-static int irq;
-
-static void cleanup_card(struct net_device *dev)
-{
-#ifdef CONFIG_MCA_LEGACY
- struct net_local *lp = netdev_priv(dev);
- if (lp->mca_slot >= 0)
- mca_mark_as_unused(lp->mca_slot);
-#endif
- free_irq(dev->irq, NULL);
- release_region(dev->base_addr, AT1700_IO_EXTENT);
-}
-
-struct net_device * __init at1700_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- unsigned *port;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
- } else {
- dev->base_addr = io;
- dev->irq = irq;
- }
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = at1700_probe1(dev, io);
- } else if (io != 0) { /* Don't probe at all. */
- err = -ENXIO;
- } else {
- for (port = at1700_probe_list; *port; port++) {
- if (at1700_probe1(dev, *port) == 0)
- break;
- dev->irq = irq;
- }
- if (!*port)
- err = -ENODEV;
- }
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
- cleanup_card(dev);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
- "signature", the default bit pattern after a reset. This *doesn't* work --
- there is no way to reset the bus interface without a complete power-cycle!
-
- It turns out that ATI came to the same conclusion I did: the only thing
- that can be done is checking a few bits and then diving right into an
- EEPROM read. */
-
-static int __init at1700_probe1(struct net_device *dev, int ioaddr)
-{
- char fmv_irqmap[4] = {3, 7, 10, 15};
- char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
- char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
- unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
- int slot, ret = -ENODEV;
- struct net_local *lp = netdev_priv(dev);
- DECLARE_MAC_BUF(mac);
-
- if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- /* Resetting the chip doesn't reset the ISA interface, so don't bother.
- That means we have to be careful with the register values we probe
- for.
- */
-#ifdef notdef
- printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
- ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
- read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
-#endif
-
-#ifdef CONFIG_MCA_LEGACY
- /* rEnE (rene@bss.lu): got this from 3c509 driver source , adapted for AT1720 */
-
- /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
- modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
- to support standard MCA probing. */
-
- /* redone for multi-card detection by ZP Gu (zpg@castle.net) */
- /* now works as a module */
-
- if (MCA_bus) {
- int j;
- int l_i;
- u_char pos3, pos4;
-
- for (j = 0; at1720_mca_adapters[j].name != NULL; j ++) {
- slot = 0;
- while (slot != MCA_NOTFOUND) {
-
- slot = mca_find_unused_adapter( at1720_mca_adapters[j].id, slot );
- if (slot == MCA_NOTFOUND) break;
-
- /* if we get this far, an adapter has been detected and is
- enabled */
-
- pos3 = mca_read_stored_pos( slot, 3 );
- pos4 = mca_read_stored_pos( slot, 4 );
-
- for (l_i = 0; l_i < 0x09; l_i++)
- if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i])
- break;
- ioaddr = at1700_mca_probe_list[l_i];
-
- for (irq = 0; irq < 0x10; irq++)
- if (((((pos4>>4) & 0x0f) | (pos3 & 0xf0)) & 0xff) == at1700_irq_pattern[irq])
- break;
-
- /* probing for a card at a particular IO/IRQ */
- if ((dev->irq && dev->irq != irq) ||
- (dev->base_addr && dev->base_addr != ioaddr)) {
- slot++; /* probing next slot */
- continue;
- }
-
- dev->irq = irq;
-
- /* claim the slot */
- mca_set_adapter_name( slot, at1720_mca_adapters[j].name );
- mca_mark_as_used(slot);
-
- goto found;
- }
- }
- /* if we get here, we didn't find an MCA adapter - try ISA */
- }
-#endif
- slot = -1;
- /* We must check for the EEPROM-config boards first, else accessing
- IOCONFIG0 will move the board! */
- if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr
- && read_eeprom(ioaddr, 4) == 0x0000
- && (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
- is_at1700 = 1;
- else if (inb(ioaddr + SAPROM ) == 0x00
- && inb(ioaddr + SAPROM + 1) == 0x00
- && inb(ioaddr + SAPROM + 2) == 0x0e)
- is_fmv18x = 1;
- else {
- goto err_out;
- }
-
-#ifdef CONFIG_MCA_LEGACY
-found:
-#endif
-
- /* Reset the internal state machines. */
- outb(0, ioaddr + RESET);
-
- if (is_at1700) {
- irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
- | (read_eeprom(ioaddr, 0)>>14)];
- } else {
- /* Check PnP mode for FMV-183/184/183A/184A. */
- /* This PnP routine is very poor. IO and IRQ should be known. */
- if (inb(ioaddr + CARDSTATUS1) & 0x20) {
- irq = dev->irq;
- for (i = 0; i < 8; i++) {
- if (irq == fmv_irqmap_pnp[i])
- break;
- }
- if (i == 8) {
- goto err_mca;
- }
- } else {
- if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
- goto err_mca;
- irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
- }
- }
-
- printk("%s: %s found at %#3x, IRQ %d, address ", dev->name,
- is_at1700 ? "AT1700" : "FMV-18X", ioaddr, irq);
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
-
- if (is_at1700) {
- for(i = 0; i < 3; i++) {
- unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
- ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
- }
- } else {
- for(i = 0; i < 6; i++) {
- unsigned char val = inb(ioaddr + SAPROM + i);
- dev->dev_addr[i] = val;
- }
- }
- printk("%s", print_mac(mac, dev->dev_addr));
-
- /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
- rather than 150 ohm shielded twisted pair compensation.
- 0x0000 == auto-sense the interface
- 0x0800 == use TP interface
- 0x1800 == use coax interface
- */
- {
- const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
- if (is_at1700) {
- ushort setup_value = read_eeprom(ioaddr, 12);
- dev->if_port = setup_value >> 8;
- } else {
- ushort setup_value = inb(ioaddr + CARDSTATUS);
- switch (setup_value & 0x07) {
- case 0x01: /* 10base5 */
- case 0x02: /* 10base2 */
- dev->if_port = 0x18; break;
- case 0x04: /* 10baseT */
- dev->if_port = 0x08; break;
- default: /* auto-sense */
- dev->if_port = 0x00; break;
- }
- }
- printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
- }
-
- /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
- bus access, two 4K Tx queues, and disabled Tx and Rx. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* Set the station address in bank zero. */
- outb(0x00, ioaddr + CONFIG_1);
- for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + PORT_OFFSET(8 + i));
-
- /* Switch to bank 1 and set the multicast table to accept none. */
- outb(0x04, ioaddr + CONFIG_1);
- for (i = 0; i < 8; i++)
- outb(0x00, ioaddr + PORT_OFFSET(8 + i));
-
-
- /* Switch to bank 2 */
- /* Lock our I/O address, and set manual processing mode for 16 collisions. */
- outb(0x08, ioaddr + CONFIG_1);
- outb(dev->if_port, ioaddr + MODE13);
- outb(0x00, ioaddr + COL16CNTL);
-
- if (net_debug)
- printk(version);
-
- memset(lp, 0, sizeof(struct net_local));
-
- dev->open = net_open;
- dev->stop = net_close;
- dev->hard_start_xmit = net_send_packet;
- dev->set_multicast_list = &set_rx_mode;
- dev->tx_timeout = net_tx_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
-
- spin_lock_init(&lp->lock);
-
- lp->jumpered = is_fmv18x;
- lp->mca_slot = slot;
- /* Snarf the interrupt vector now. */
- ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev);
- if (ret) {
- printk(KERN_ERR "AT1700 at %#3x is unusable due to a "
- "conflict on IRQ %d.\n",
- ioaddr, irq);
- goto err_mca;
- }
-
- return 0;
-
-err_mca:
-#ifdef CONFIG_MCA_LEGACY
- if (slot >= 0)
- mca_mark_as_unused(slot);
-#endif
-err_out:
- release_region(ioaddr, AT1700_IO_EXTENT);
- return ret;
-}
-
-
-/* EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK 0x40 /* EEPROM shift clock, in reg. 16. */
-#define EE_CS 0x20 /* EEPROM chip select, in reg. 16. */
-#define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
-#define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD (5 << 6)
-#define EE_READ_CMD (6 << 6)
-#define EE_ERASE_CMD (7 << 6)
-
-static int __init read_eeprom(long ioaddr, int location)
-{
- int i;
- unsigned short retval = 0;
- long ee_addr = ioaddr + EEPROM_Ctrl;
- long ee_daddr = ioaddr + EEPROM_Data;
- int read_cmd = location | EE_READ_CMD;
-
- /* Shift the read command bits out. */
- for (i = 9; i >= 0; i--) {
- short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
- outb(EE_CS, ee_addr);
- outb(dataval, ee_daddr);
- outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
- }
- outb(EE_DATA_WRITE, ee_daddr);
- for (i = 16; i > 0; i--) {
- outb(EE_CS, ee_addr);
- outb(EE_CS | EE_SHIFT_CLK, ee_addr);
- retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
- }
-
- /* Terminate the EEPROM access. */
- outb(EE_CS, ee_addr);
- outb(EE_SHIFT_CLK, ee_addr);
- outb(0, ee_addr);
- return retval;
-}
-
-
-
-static int net_open(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
- bus access, and two 4K Tx queues. */
- outb(0x5a, ioaddr + CONFIG_0);
-
- /* Powerup, switch to register bank 2, and enable the Rx and Tx. */
- outb(0xe8, ioaddr + CONFIG_1);
-
- lp->tx_started = 0;
- lp->tx_queue_ready = 1;
- lp->rx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- /* Turn on hardware Tx and Rx interrupts. */
- outb(0x82, ioaddr + TX_INTR);
- outb(0x81, ioaddr + RX_INTR);
-
- /* Enable the IRQ on boards of fmv18x it is feasible. */
- if (lp->jumpered) {
- outb(0x80, ioaddr + IOCONFIG1);
- }
-
- netif_start_queue(dev);
- return 0;
-}
-
-static void net_tx_timeout (struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- printk ("%s: transmit timed out with status %04x, %s?\n", dev->name,
- inw (ioaddr + STATUS), inb (ioaddr + TX_STATUS) & 0x80
- ? "IRQ conflict" : "network cable problem");
- printk ("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
- dev->name, inw(ioaddr + TX_STATUS), inw(ioaddr + TX_INTR), inw(ioaddr + TX_MODE),
- inw(ioaddr + CONFIG_0), inw(ioaddr + DATAPORT), inw(ioaddr + TX_START),
- inw(ioaddr + MODE13 - 1), inw(ioaddr + RX_CTRL));
- dev->stats.tx_errors++;
- /* ToDo: We should try to restart the adaptor... */
- outw(0xffff, ioaddr + MODE24);
- outw (0xffff, ioaddr + TX_STATUS);
- outb (0x5a, ioaddr + CONFIG_0);
- outb (0xe8, ioaddr + CONFIG_1);
- outw (0x8182, ioaddr + TX_INTR);
- outb (0x00, ioaddr + TX_START);
- outb (0x03, ioaddr + COL16CNTL);
-
- dev->trans_start = jiffies;
-
- lp->tx_started = 0;
- lp->tx_queue_ready = 1;
- lp->rx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- netif_wake_queue(dev);
-}
-
-
-static int net_send_packet (struct sk_buff *skb, struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- short len = skb->len;
- unsigned char *buf = skb->data;
- static u8 pad[ETH_ZLEN];
-
- netif_stop_queue (dev);
-
- /* We may not start transmitting unless we finish transferring
- a packet into the Tx queue. During executing the following
- codes we possibly catch a Tx interrupt. Thus we flag off
- tx_queue_ready, so that we prevent the interrupt routine
- (net_interrupt) to start transmitting. */
- lp->tx_queue_ready = 0;
- {
- outw (length, ioaddr + DATAPORT);
- /* Packet data */
- outsw (ioaddr + DATAPORT, buf, len >> 1);
- /* Check for dribble byte */
- if (len & 1) {
- outw(skb->data[skb->len-1], ioaddr + DATAPORT);
- len++;
- }
- /* Check for packet padding */
- if (length != skb->len)
- outsw(ioaddr + DATAPORT, pad, (length - len + 1) >> 1);
-
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
- }
- lp->tx_queue_ready = 1;
-
- if (lp->tx_started == 0) {
- /* If the Tx is idle, always trigger a transmit. */
- outb (0x80 | lp->tx_queue, ioaddr + TX_START);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- lp->tx_started = 1;
- netif_start_queue (dev);
- } else if (lp->tx_queue_len < 4096 - 1502)
- /* Yes, there is room for one more packet. */
- netif_start_queue (dev);
- dev_kfree_skb (skb);
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static irqreturn_t net_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr, status;
- int handled = 0;
-
- if (dev == NULL) {
- printk ("at1700_interrupt(): irq %d for unknown device.\n", irq);
- return IRQ_NONE;
- }
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- spin_lock (&lp->lock);
-
- status = inw(ioaddr + TX_STATUS);
- outw(status, ioaddr + TX_STATUS);
-
- if (net_debug > 4)
- printk("%s: Interrupt with status %04x.\n", dev->name, status);
- if (lp->rx_started == 0 &&
- (status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
- /* Got a packet(s).
- We cannot execute net_rx more than once at the same time for
- the same device. During executing net_rx, we possibly catch a
- Tx interrupt. Thus we flag on rx_started, so that we prevent
- the interrupt routine (net_interrupt) to dive into net_rx
- again. */
- handled = 1;
- lp->rx_started = 1;
- outb(0x00, ioaddr + RX_INTR); /* Disable RX intr. */
- net_rx(dev);
- outb(0x81, ioaddr + RX_INTR); /* Enable RX intr. */
- lp->rx_started = 0;
- }
- if (status & 0x00ff) {
- handled = 1;
- if (status & 0x02) {
- /* More than 16 collisions occurred */
- if (net_debug > 4)
- printk("%s: 16 Collision occur during Txing.\n", dev->name);
- /* Cancel sending a packet. */
- outb(0x03, ioaddr + COL16CNTL);
- dev->stats.collisions++;
- }
- if (status & 0x82) {
- dev->stats.tx_packets++;
- /* The Tx queue has any packets and is not being
- transferred a packet from the host, start
- transmitting. */
- if (lp->tx_queue && lp->tx_queue_ready) {
- outb(0x80 | lp->tx_queue, ioaddr + TX_START);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- netif_wake_queue (dev);
- } else {
- lp->tx_started = 0;
- netif_wake_queue (dev);
- }
- }
- }
-
- spin_unlock (&lp->lock);
- return IRQ_RETVAL(handled);
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-net_rx(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- int boguscount = 5;
-
- while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
- ushort status = inw(ioaddr + DATAPORT);
- ushort pkt_len = inw(ioaddr + DATAPORT);
-
- if (net_debug > 4)
- printk("%s: Rxing packet mode %02x status %04x.\n",
- dev->name, inb(ioaddr + RX_MODE), status);
-#ifndef final_version
- if (status == 0) {
- outb(0x05, ioaddr + RX_CTRL);
- break;
- }
-#endif
-
- if ((status & 0xF0) != 0x20) { /* There was an error. */
- dev->stats.rx_errors++;
- if (status & 0x08) dev->stats.rx_length_errors++;
- if (status & 0x04) dev->stats.rx_frame_errors++;
- if (status & 0x02) dev->stats.rx_crc_errors++;
- if (status & 0x01) dev->stats.rx_over_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- if (pkt_len > 1550) {
- printk("%s: The AT1700 claimed a very large packet, size %d.\n",
- dev->name, pkt_len);
- /* Prime the FIFO and then flush the packet. */
- inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
- outb(0x05, ioaddr + RX_CTRL);
- dev->stats.rx_errors++;
- break;
- }
- skb = dev_alloc_skb(pkt_len+3);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet (len %d).\n",
- dev->name, pkt_len);
- /* Prime the FIFO and then flush the packet. */
- inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
- outb(0x05, ioaddr + RX_CTRL);
- dev->stats.rx_dropped++;
- break;
- }
- skb_reserve(skb,2);
-
- insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
- skb->protocol=eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
- if (--boguscount <= 0)
- break;
- }
-
- /* If any worth-while packets have been received, dev_rint()
- has done a mark_bh(NET_BH) for us and will work on them
- when we get to the bottom-half routine. */
- {
- int i;
- for (i = 0; i < 20; i++) {
- if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
- break;
- inw(ioaddr + DATAPORT); /* dummy status read */
- outb(0x05, ioaddr + RX_CTRL);
- }
-
- if (net_debug > 5)
- printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
- dev->name, inb(ioaddr + RX_MODE), i);
- }
- return;
-}
-
-/* The inverse routine to net_open(). */
-static int net_close(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- netif_stop_queue(dev);
-
- /* Set configuration register 0 to disable Tx and Rx. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* No statistic counters on the chip to update. */
-
- /* Disable the IRQ on boards of fmv18x where it is feasible. */
- if (lp->jumpered) {
- outb(0x00, ioaddr + IOCONFIG1);
- free_irq(dev->irq, dev);
- }
-
- /* Power-down the chip. Green, green, green! */
- outb(0x00, ioaddr + CONFIG_1);
- return 0;
-}
-
-/*
- Set the multicast/promiscuous mode for this adaptor.
-*/
-
-static void
-set_rx_mode(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
- unsigned char mc_filter[8]; /* Multicast hash filter */
- unsigned long flags;
- int i;
-
- if (dev->flags & IFF_PROMISC) {
- memset(mc_filter, 0xff, sizeof(mc_filter));
- outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
- } else if (dev->mc_count > MC_FILTERBREAK
- || (dev->flags & IFF_ALLMULTI)) {
- /* Too many to filter perfectly -- accept all multicasts. */
- memset(mc_filter, 0xff, sizeof(mc_filter));
- outb(2, ioaddr + RX_MODE); /* Use normal mode. */
- } else if (dev->mc_count == 0) {
- memset(mc_filter, 0x00, sizeof(mc_filter));
- outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */
- } else {
- struct dev_mc_list *mclist;
- int i;
-
- memset(mc_filter, 0, sizeof(mc_filter));
- for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
- i++, mclist = mclist->next) {
- unsigned int bit =
- ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26;
- mc_filter[bit >> 3] |= (1 << bit);
- }
- outb(0x02, ioaddr + RX_MODE); /* Use normal mode. */
- }
-
- spin_lock_irqsave (&lp->lock, flags);
- if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
- int saved_bank = inw(ioaddr + CONFIG_0);
- /* Switch to bank 1 and set the multicast table. */
- outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
- for (i = 0; i < 8; i++)
- outb(mc_filter[i], ioaddr + PORT_OFFSET(8 + i));
- memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
- outw(saved_bank, ioaddr + CONFIG_0);
- }
- spin_unlock_irqrestore (&lp->lock, flags);
- return;
-}
-
-#ifdef MODULE
-static struct net_device *dev_at1700;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(net_debug, int, 0);
-MODULE_PARM_DESC(io, "AT1700/FMV18X I/O base address");
-MODULE_PARM_DESC(irq, "AT1700/FMV18X IRQ number");
-MODULE_PARM_DESC(net_debug, "AT1700/FMV18X debug level (0-6)");
-
-static int __init at1700_module_init(void)
-{
- if (io == 0)
- printk("at1700: You should not use auto-probing with insmod!\n");
- dev_at1700 = at1700_probe(-1);
- if (IS_ERR(dev_at1700))
- return PTR_ERR(dev_at1700);
- return 0;
-}
-
-static void __exit at1700_module_exit(void)
-{
- unregister_netdev(dev_at1700);
- cleanup_card(dev_at1700);
- free_netdev(dev_at1700);
-}
-module_init(at1700_module_init);
-module_exit(at1700_module_exit);
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
-
-
-/*
- * Local variables:
- * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
- * alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
- * tab-width: 4
- * c-basic-offset: 4
- * c-indent-level: 4
- * End:
- */
-
diff --git a/drivers/net/atlx/Makefile b/drivers/net/atlx/Makefile
deleted file mode 100644
index ca45553a040..00000000000
--- a/drivers/net/atlx/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_ATL1) += atl1.o
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
deleted file mode 100644
index 5ee1b0557a0..00000000000
--- a/drivers/net/au1000_eth.c
+++ /dev/null
@@ -1,1308 +0,0 @@
-/*
- *
- * Alchemy Au1x00 ethernet driver
- *
- * Copyright 2001-2003, 2006 MontaVista Software Inc.
- * Copyright 2002 TimeSys Corp.
- * Added ethtool/mii-tool support,
- * Copyright 2004 Matt Porter <mporter@kernel.crashing.org>
- * Update: 2004 Bjoern Riemer, riemer@fokus.fraunhofer.de
- * or riemer@riemer-nt.de: fixed the link beat detection with
- * ioctls (SIOCGMIIPHY)
- * Copyright 2006 Herbert Valerio Riedel <hvr@gnu.org>
- * converted to use linux-2.6.x's PHY framework
- *
- * Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/crc32.h>
-#include <linux/phy.h>
-
-#include <asm/cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-
-#include <au1000.h>
-#include <prom.h>
-
-#include "au1000_eth.h"
-
-#ifdef AU1000_ETH_DEBUG
-static int au1000_debug = 5;
-#else
-static int au1000_debug = 3;
-#endif
-
-#define DRV_NAME "au1000_eth"
-#define DRV_VERSION "1.6"
-#define DRV_AUTHOR "Pete Popov <ppopov@embeddedalley.com>"
-#define DRV_DESC "Au1xxx on-chip Ethernet driver"
-
-MODULE_AUTHOR(DRV_AUTHOR);
-MODULE_DESCRIPTION(DRV_DESC);
-MODULE_LICENSE("GPL");
-
-// prototypes
-static void hard_stop(struct net_device *);
-static void enable_rx_tx(struct net_device *dev);
-static struct net_device * au1000_probe(int port_num);
-static int au1000_init(struct net_device *);
-static int au1000_open(struct net_device *);
-static int au1000_close(struct net_device *);
-static int au1000_tx(struct sk_buff *, struct net_device *);
-static int au1000_rx(struct net_device *);
-static irqreturn_t au1000_interrupt(int, void *);
-static void au1000_tx_timeout(struct net_device *);
-static void set_rx_mode(struct net_device *);
-static int au1000_ioctl(struct net_device *, struct ifreq *, int);
-static int mdio_read(struct net_device *, int, int);
-static void mdio_write(struct net_device *, int, int, u16);
-static void au1000_adjust_link(struct net_device *);
-static void enable_mac(struct net_device *, int);
-
-/*
- * Theory of operation
- *
- * The Au1000 MACs use a simple rx and tx descriptor ring scheme.
- * There are four receive and four transmit descriptors. These
- * descriptors are not in memory; rather, they are just a set of
- * hardware registers.
- *
- * Since the Au1000 has a coherent data cache, the receive and
- * transmit buffers are allocated from the KSEG0 segment. The
- * hardware registers, however, are still mapped at KSEG1 to
- * make sure there's no out-of-order writes, and that all writes
- * complete immediately.
- */
-
-/* These addresses are only used if yamon doesn't tell us what
- * the mac address is, and the mac address is not passed on the
- * command line.
- */
-static unsigned char au1000_mac_addr[6] __devinitdata = {
- 0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00
-};
-
-struct au1000_private *au_macs[NUM_ETH_INTERFACES];
-
-/*
- * board-specific configurations
- *
- * PHY detection algorithm
- *
- * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is
- * autodetected:
- *
- * mii_probe() first searches the current MAC's MII bus for a PHY,
- * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is
- * defined) PHY address not already claimed by another netdev.
- *
- * If nothing was found that way when searching for the 2nd ethernet
- * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then
- * the first MII bus is searched as well for an unclaimed PHY; this is
- * needed in case of a dual-PHY accessible only through the MAC0's MII
- * bus.
- *
- * Finally, if no PHY is found, then the corresponding ethernet
- * controller is not registered to the network subsystem.
- */
-
-/* autodetection defaults */
-#undef AU1XXX_PHY_SEARCH_HIGHEST_ADDR
-#define AU1XXX_PHY1_SEARCH_ON_MAC0
-
-/* static PHY setup
- *
- * most boards PHY setup should be detectable properly with the
- * autodetection algorithm in mii_probe(), but in some cases (e.g. if
- * you have a switch attached, or want to use the PHY's interrupt
- * notification capabilities) you can provide a static PHY
- * configuration here
- *
- * IRQs may only be set, if a PHY address was configured
- * If a PHY address is given, also a bus id is required to be set
- *
- * ps: make sure the used irqs are configured properly in the board
- * specific irq-map
- */
-
-#if defined(CONFIG_MIPS_BOSPORUS)
-/*
- * Micrel/Kendin 5 port switch attached to MAC0,
- * MAC0 is associated with PHY address 5 (== WAN port)
- * MAC1 is not associated with any PHY, since it's connected directly
- * to the switch.
- * no interrupts are used
- */
-# define AU1XXX_PHY_STATIC_CONFIG
-
-# define AU1XXX_PHY0_ADDR 5
-# define AU1XXX_PHY0_BUSID 0
-# undef AU1XXX_PHY0_IRQ
-
-# undef AU1XXX_PHY1_ADDR
-# undef AU1XXX_PHY1_BUSID
-# undef AU1XXX_PHY1_IRQ
-#endif
-
-#if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0)
-# error MAC0-associated PHY attached 2nd MACs MII bus not supported yet
-#endif
-
-/*
- * MII operations
- */
-static int mdio_read(struct net_device *dev, int phy_addr, int reg)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- volatile u32 *const mii_control_reg = &aup->mac->mii_control;
- volatile u32 *const mii_data_reg = &aup->mac->mii_data;
- u32 timedout = 20;
- u32 mii_control;
-
- while (*mii_control_reg & MAC_MII_BUSY) {
- mdelay(1);
- if (--timedout == 0) {
- printk(KERN_ERR "%s: read_MII busy timeout!!\n",
- dev->name);
- return -1;
- }
- }
-
- mii_control = MAC_SET_MII_SELECT_REG(reg) |
- MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ;
-
- *mii_control_reg = mii_control;
-
- timedout = 20;
- while (*mii_control_reg & MAC_MII_BUSY) {
- mdelay(1);
- if (--timedout == 0) {
- printk(KERN_ERR "%s: mdio_read busy timeout!!\n",
- dev->name);
- return -1;
- }
- }
- return (int)*mii_data_reg;
-}
-
-static void mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- volatile u32 *const mii_control_reg = &aup->mac->mii_control;
- volatile u32 *const mii_data_reg = &aup->mac->mii_data;
- u32 timedout = 20;
- u32 mii_control;
-
- while (*mii_control_reg & MAC_MII_BUSY) {
- mdelay(1);
- if (--timedout == 0) {
- printk(KERN_ERR "%s: mdio_write busy timeout!!\n",
- dev->name);
- return;
- }
- }
-
- mii_control = MAC_SET_MII_SELECT_REG(reg) |
- MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE;
-
- *mii_data_reg = value;
- *mii_control_reg = mii_control;
-}
-
-static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
-{
- /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does
- * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
- struct net_device *const dev = bus->priv;
-
- enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
- return mdio_read(dev, phy_addr, regnum);
-}
-
-static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
- u16 value)
-{
- struct net_device *const dev = bus->priv;
-
- enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
- mdio_write(dev, phy_addr, regnum, value);
- return 0;
-}
-
-static int mdiobus_reset(struct mii_bus *bus)
-{
- struct net_device *const dev = bus->priv;
-
- enable_mac(dev, 0); /* make sure the MAC associated with this
- * mii_bus is enabled */
- return 0;
-}
-
-static int mii_probe (struct net_device *dev)
-{
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
- struct phy_device *phydev = NULL;
-
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
- BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
-
- if(aup->mac_id == 0) { /* get PHY0 */
-# if defined(AU1XXX_PHY0_ADDR)
- phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus.phy_map[AU1XXX_PHY0_ADDR];
-# else
- printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
- dev->name);
- return 0;
-# endif /* defined(AU1XXX_PHY0_ADDR) */
- } else if (aup->mac_id == 1) { /* get PHY1 */
-# if defined(AU1XXX_PHY1_ADDR)
- phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus.phy_map[AU1XXX_PHY1_ADDR];
-# else
- printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n",
- dev->name);
- return 0;
-# endif /* defined(AU1XXX_PHY1_ADDR) */
- }
-
-#else /* defined(AU1XXX_PHY_STATIC_CONFIG) */
- int phy_addr;
-
- /* find the first (lowest address) PHY on the current MAC's MII bus */
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
- if (aup->mii_bus.phy_map[phy_addr]) {
- phydev = aup->mii_bus.phy_map[phy_addr];
-# if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR)
- break; /* break out with first one found */
-# endif
- }
-
-# if defined(AU1XXX_PHY1_SEARCH_ON_MAC0)
- /* try harder to find a PHY */
- if (!phydev && (aup->mac_id == 1)) {
- /* no PHY found, maybe we have a dual PHY? */
- printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, "
- "let's see if it's attached to MAC0...\n");
-
- BUG_ON(!au_macs[0]);
-
- /* find the first (lowest address) non-attached PHY on
- * the MAC0 MII bus */
- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
- struct phy_device *const tmp_phydev =
- au_macs[0]->mii_bus.phy_map[phy_addr];
-
- if (!tmp_phydev)
- continue; /* no PHY here... */
-
- if (tmp_phydev->attached_dev)
- continue; /* already claimed by MAC0 */
-
- phydev = tmp_phydev;
- break; /* found it */
- }
- }
-# endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */
-
-#endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */
- if (!phydev) {
- printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name);
- return -1;
- }
-
- /* now we are supposed to have a proper phydev, to attach to... */
- BUG_ON(!phydev);
- BUG_ON(phydev->attached_dev);
-
- phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
-
- if (IS_ERR(phydev)) {
- printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
- return PTR_ERR(phydev);
- }
-
- /* mask with MAC supported features */
- phydev->supported &= (SUPPORTED_10baseT_Half
- | SUPPORTED_10baseT_Full
- | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full
- | SUPPORTED_Autoneg
- /* | SUPPORTED_Pause | SUPPORTED_Asym_Pause */
- | SUPPORTED_MII
- | SUPPORTED_TP);
-
- phydev->advertising = phydev->supported;
-
- aup->old_link = 0;
- aup->old_speed = 0;
- aup->old_duplex = -1;
- aup->phy_dev = phydev;
-
- printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
-
- return 0;
-}
-
-
-/*
- * Buffer allocation/deallocation routines. The buffer descriptor returned
- * has the virtual and dma address of a buffer suitable for
- * both, receive and transmit operations.
- */
-static db_dest_t *GetFreeDB(struct au1000_private *aup)
-{
- db_dest_t *pDB;
- pDB = aup->pDBfree;
-
- if (pDB) {
- aup->pDBfree = pDB->pnext;
- }
- return pDB;
-}
-
-void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
-{
- db_dest_t *pDBfree = aup->pDBfree;
- if (pDBfree)
- pDBfree->pnext = pDB;
- aup->pDBfree = pDB;
-}
-
-static void enable_rx_tx(struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
-
- if (au1000_debug > 4)
- printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
-
- aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
- au_sync_delay(10);
-}
-
-static void hard_stop(struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
-
- if (au1000_debug > 4)
- printk(KERN_INFO "%s: hard stop\n", dev->name);
-
- aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
- au_sync_delay(10);
-}
-
-static void enable_mac(struct net_device *dev, int force_reset)
-{
- unsigned long flags;
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
-
- spin_lock_irqsave(&aup->lock, flags);
-
- if(force_reset || (!aup->mac_enabled)) {
- *aup->enable = MAC_EN_CLOCK_ENABLE;
- au_sync_delay(2);
- *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
- | MAC_EN_CLOCK_ENABLE);
- au_sync_delay(2);
-
- aup->mac_enabled = 1;
- }
-
- spin_unlock_irqrestore(&aup->lock, flags);
-}
-
-static void reset_mac_unlocked(struct net_device *dev)
-{
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
- int i;
-
- hard_stop(dev);
-
- *aup->enable = MAC_EN_CLOCK_ENABLE;
- au_sync_delay(2);
- *aup->enable = 0;
- au_sync_delay(2);
-
- aup->tx_full = 0;
- for (i = 0; i < NUM_RX_DMA; i++) {
- /* reset control bits */
- aup->rx_dma_ring[i]->buff_stat &= ~0xf;
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- /* reset control bits */
- aup->tx_dma_ring[i]->buff_stat &= ~0xf;
- }
-
- aup->mac_enabled = 0;
-
-}
-
-static void reset_mac(struct net_device *dev)
-{
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
- unsigned long flags;
-
- if (au1000_debug > 4)
- printk(KERN_INFO "%s: reset mac, aup %x\n",
- dev->name, (unsigned)aup);
-
- spin_lock_irqsave(&aup->lock, flags);
-
- reset_mac_unlocked (dev);
-
- spin_unlock_irqrestore(&aup->lock, flags);
-}
-
-/*
- * Setup the receive and transmit "rings". These pointers are the addresses
- * of the rx and tx MAC DMA registers so they are fixed by the hardware --
- * these are not descriptors sitting in memory.
- */
-static void
-setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base)
-{
- int i;
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- aup->rx_dma_ring[i] =
- (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- aup->tx_dma_ring[i] =
- (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
- }
-}
-
-static struct {
- u32 base_addr;
- u32 macen_addr;
- int irq;
- struct net_device *dev;
-} iflist[2] = {
-#ifdef CONFIG_SOC_AU1000
- {AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT},
- {AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1100
- {AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1500
- {AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT},
- {AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT}
-#endif
-#ifdef CONFIG_SOC_AU1550
- {AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT},
- {AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT}
-#endif
-};
-
-static int num_ifs;
-
-/*
- * Setup the base address and interrupt of the Au1xxx ethernet macs
- * based on cpu type and whether the interface is enabled in sys_pinfunc
- * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
- */
-static int __init au1000_init_module(void)
-{
- int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
- struct net_device *dev;
- int i, found_one = 0;
-
- num_ifs = NUM_ETH_INTERFACES - ni;
-
- for(i = 0; i < num_ifs; i++) {
- dev = au1000_probe(i);
- iflist[i].dev = dev;
- if (dev)
- found_one++;
- }
- if (!found_one)
- return -ENODEV;
- return 0;
-}
-
-/*
- * ethtool operations
- */
-
-static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
-
- if (aup->phy_dev)
- return phy_ethtool_gset(aup->phy_dev, cmd);
-
- return -EINVAL;
-}
-
-static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (aup->phy_dev)
- return phy_ethtool_sset(aup->phy_dev, cmd);
-
- return -EINVAL;
-}
-
-static void
-au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
-
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- info->fw_version[0] = '\0';
- sprintf(info->bus_info, "%s %d", DRV_NAME, aup->mac_id);
- info->regdump_len = 0;
-}
-
-static const struct ethtool_ops au1000_ethtool_ops = {
- .get_settings = au1000_get_settings,
- .set_settings = au1000_set_settings,
- .get_drvinfo = au1000_get_drvinfo,
- .get_link = ethtool_op_get_link,
-};
-
-static struct net_device * au1000_probe(int port_num)
-{
- static unsigned version_printed = 0;
- struct au1000_private *aup = NULL;
- struct net_device *dev = NULL;
- db_dest_t *pDB, *pDBfree;
- char ethaddr[6];
- int irq, i, err;
- u32 base, macen;
-
- if (port_num >= NUM_ETH_INTERFACES)
- return NULL;
-
- base = CPHYSADDR(iflist[port_num].base_addr );
- macen = CPHYSADDR(iflist[port_num].macen_addr);
- irq = iflist[port_num].irq;
-
- if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
- !request_mem_region(macen, 4, "Au1x00 ENET"))
- return NULL;
-
- if (version_printed++ == 0)
- printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
-
- dev = alloc_etherdev(sizeof(struct au1000_private));
- if (!dev) {
- printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
- return NULL;
- }
-
- if ((err = register_netdev(dev)) != 0) {
- printk(KERN_ERR "%s: Cannot register net device, error %d\n",
- DRV_NAME, err);
- free_netdev(dev);
- return NULL;
- }
-
- printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
- dev->name, base, irq);
-
- aup = dev->priv;
-
- /* Allocate the data buffers */
- /* Snooping works fine with eth on all au1xxx */
- aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- &aup->dma_addr, 0);
- if (!aup->vaddr) {
- free_netdev(dev);
- release_mem_region( base, MAC_IOSIZE);
- release_mem_region(macen, 4);
- return NULL;
- }
-
- /* aup->mac is the base address of the MAC's registers */
- aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
-
- /* Setup some variables for quick register address access */
- aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
- aup->mac_id = port_num;
- au_macs[port_num] = aup;
-
- if (port_num == 0) {
- if (prom_get_ethernet_addr(ethaddr) == 0)
- memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
- else {
- printk(KERN_INFO "%s: No MAC address found\n",
- dev->name);
- /* Use the hard coded MAC addresses */
- }
-
- setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
- } else if (port_num == 1)
- setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
-
- /*
- * Assign to the Ethernet ports two consecutive MAC addresses
- * to match those that are printed on their stickers
- */
- memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
- dev->dev_addr[5] += port_num;
-
- *aup->enable = 0;
- aup->mac_enabled = 0;
-
- aup->mii_bus.priv = dev;
- aup->mii_bus.read = mdiobus_read;
- aup->mii_bus.write = mdiobus_write;
- aup->mii_bus.reset = mdiobus_reset;
- aup->mii_bus.name = "au1000_eth_mii";
- snprintf(aup->mii_bus.id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
- aup->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
- for(i = 0; i < PHY_MAX_ADDR; ++i)
- aup->mii_bus.irq[i] = PHY_POLL;
-
- /* if known, set corresponding PHY IRQs */
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
-# if defined(AU1XXX_PHY0_IRQ)
- if (AU1XXX_PHY0_BUSID == aup->mac_id)
- aup->mii_bus.irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
-# endif
-# if defined(AU1XXX_PHY1_IRQ)
- if (AU1XXX_PHY1_BUSID == aup->mac_id)
- aup->mii_bus.irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
-# endif
-#endif
- mdiobus_register(&aup->mii_bus);
-
- if (mii_probe(dev) != 0) {
- goto err_out;
- }
-
- pDBfree = NULL;
- /* setup the data buffer descriptors and attach a buffer to each one */
- pDB = aup->db;
- for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
- pDB->pnext = pDBfree;
- pDBfree = pDB;
- pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
- pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
- pDB++;
- }
- aup->pDBfree = pDBfree;
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) {
- goto err_out;
- }
- aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
- aup->rx_db_inuse[i] = pDB;
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) {
- goto err_out;
- }
- aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
- aup->tx_dma_ring[i]->len = 0;
- aup->tx_db_inuse[i] = pDB;
- }
-
- spin_lock_init(&aup->lock);
- dev->base_addr = base;
- dev->irq = irq;
- dev->open = au1000_open;
- dev->hard_start_xmit = au1000_tx;
- dev->stop = au1000_close;
- dev->set_multicast_list = &set_rx_mode;
- dev->do_ioctl = &au1000_ioctl;
- SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
- dev->tx_timeout = au1000_tx_timeout;
- dev->watchdog_timeo = ETH_TX_TIMEOUT;
-
- /*
- * The boot code uses the ethernet controller, so reset it to start
- * fresh. au1000_init() expects that the device is in reset state.
- */
- reset_mac(dev);
-
- return dev;
-
-err_out:
- /* here we should have a valid dev plus aup-> register addresses
- * so we can reset the mac properly.*/
- reset_mac(dev);
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- if (aup->rx_db_inuse[i])
- ReleaseDB(aup, aup->rx_db_inuse[i]);
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- if (aup->tx_db_inuse[i])
- ReleaseDB(aup, aup->tx_db_inuse[i]);
- }
- dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
- unregister_netdev(dev);
- free_netdev(dev);
- release_mem_region( base, MAC_IOSIZE);
- release_mem_region(macen, 4);
- return NULL;
-}
-
-/*
- * Initialize the interface.
- *
- * When the device powers up, the clocks are disabled and the
- * mac is in reset state. When the interface is closed, we
- * do the same -- reset the device and disable the clocks to
- * conserve power. Thus, whenever au1000_init() is called,
- * the device should already be in reset state.
- */
-static int au1000_init(struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- unsigned long flags;
- int i;
- u32 control;
-
- if (au1000_debug > 4)
- printk("%s: au1000_init\n", dev->name);
-
- /* bring the device out of reset */
- enable_mac(dev, 1);
-
- spin_lock_irqsave(&aup->lock, flags);
-
- aup->mac->control = 0;
- aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
- aup->tx_tail = aup->tx_head;
- aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;
-
- aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4];
- aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
- dev->dev_addr[1]<<8 | dev->dev_addr[0];
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
- }
- au_sync();
-
- control = MAC_RX_ENABLE | MAC_TX_ENABLE;
-#ifndef CONFIG_CPU_LITTLE_ENDIAN
- control |= MAC_BIG_ENDIAN;
-#endif
- if (aup->phy_dev) {
- if (aup->phy_dev->link && (DUPLEX_FULL == aup->phy_dev->duplex))
- control |= MAC_FULL_DUPLEX;
- else
- control |= MAC_DISABLE_RX_OWN;
- } else { /* PHY-less op, assume full-duplex */
- control |= MAC_FULL_DUPLEX;
- }
-
- aup->mac->control = control;
- aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
- au_sync();
-
- spin_unlock_irqrestore(&aup->lock, flags);
- return 0;
-}
-
-static void
-au1000_adjust_link(struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- struct phy_device *phydev = aup->phy_dev;
- unsigned long flags;
-
- int status_change = 0;
-
- BUG_ON(!aup->phy_dev);
-
- spin_lock_irqsave(&aup->lock, flags);
-
- if (phydev->link && (aup->old_speed != phydev->speed)) {
- // speed changed
-
- switch(phydev->speed) {
- case SPEED_10:
- case SPEED_100:
- break;
- default:
- printk(KERN_WARNING
- "%s: Speed (%d) is not 10/100 ???\n",
- dev->name, phydev->speed);
- break;
- }
-
- aup->old_speed = phydev->speed;
-
- status_change = 1;
- }
-
- if (phydev->link && (aup->old_duplex != phydev->duplex)) {
- // duplex mode changed
-
- /* switching duplex mode requires to disable rx and tx! */
- hard_stop(dev);
-
- if (DUPLEX_FULL == phydev->duplex)
- aup->mac->control = ((aup->mac->control
- | MAC_FULL_DUPLEX)
- & ~MAC_DISABLE_RX_OWN);
- else
- aup->mac->control = ((aup->mac->control
- & ~MAC_FULL_DUPLEX)
- | MAC_DISABLE_RX_OWN);
- au_sync_delay(1);
-
- enable_rx_tx(dev);
- aup->old_duplex = phydev->duplex;
-
- status_change = 1;
- }
-
- if(phydev->link != aup->old_link) {
- // link state changed
-
- if (!phydev->link) {
- /* link went down */
- aup->old_speed = 0;
- aup->old_duplex = -1;
- }
-
- aup->old_link = phydev->link;
- status_change = 1;
- }
-
- spin_unlock_irqrestore(&aup->lock, flags);
-
- if (status_change) {
- if (phydev->link)
- printk(KERN_INFO "%s: link up (%d/%s)\n",
- dev->name, phydev->speed,
- DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
- else
- printk(KERN_INFO "%s: link down\n", dev->name);
- }
-}
-
-static int au1000_open(struct net_device *dev)
-{
- int retval;
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
-
- if (au1000_debug > 4)
- printk("%s: open: dev=%p\n", dev->name, dev);
-
- if ((retval = request_irq(dev->irq, &au1000_interrupt, 0,
- dev->name, dev))) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
- dev->name, dev->irq);
- return retval;
- }
-
- if ((retval = au1000_init(dev))) {
- printk(KERN_ERR "%s: error in au1000_init\n", dev->name);
- free_irq(dev->irq, dev);
- return retval;
- }
-
- if (aup->phy_dev) {
- /* cause the PHY state machine to schedule a link state check */
- aup->phy_dev->state = PHY_CHANGELINK;
- phy_start(aup->phy_dev);
- }
-
- netif_start_queue(dev);
-
- if (au1000_debug > 4)
- printk("%s: open: Initialization done.\n", dev->name);
-
- return 0;
-}
-
-static int au1000_close(struct net_device *dev)
-{
- unsigned long flags;
- struct au1000_private *const aup = (struct au1000_private *) dev->priv;
-
- if (au1000_debug > 4)
- printk("%s: close: dev=%p\n", dev->name, dev);
-
- if (aup->phy_dev)
- phy_stop(aup->phy_dev);
-
- spin_lock_irqsave(&aup->lock, flags);
-
- reset_mac_unlocked (dev);
-
- /* stop the device */
- netif_stop_queue(dev);
-
- /* disable the interrupt */
- free_irq(dev->irq, dev);
- spin_unlock_irqrestore(&aup->lock, flags);
-
- return 0;
-}
-
-static void __exit au1000_cleanup_module(void)
-{
- int i, j;
- struct net_device *dev;
- struct au1000_private *aup;
-
- for (i = 0; i < num_ifs; i++) {
- dev = iflist[i].dev;
- if (dev) {
- aup = (struct au1000_private *) dev->priv;
- unregister_netdev(dev);
- for (j = 0; j < NUM_RX_DMA; j++)
- if (aup->rx_db_inuse[j])
- ReleaseDB(aup, aup->rx_db_inuse[j]);
- for (j = 0; j < NUM_TX_DMA; j++)
- if (aup->tx_db_inuse[j])
- ReleaseDB(aup, aup->tx_db_inuse[j]);
- dma_free_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
- release_mem_region(dev->base_addr, MAC_IOSIZE);
- release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
- free_netdev(dev);
- }
- }
-}
-
-static void update_tx_stats(struct net_device *dev, u32 status)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- struct net_device_stats *ps = &dev->stats;
-
- if (status & TX_FRAME_ABORTED) {
- if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
- if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
- /* any other tx errors are only valid
- * in half duplex mode */
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- }
- }
- else {
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
- ps->tx_carrier_errors++;
- }
- }
-}
-
-
-/*
- * Called from the interrupt service routine to acknowledge
- * the TX DONE bits. This is a must if the irq is setup as
- * edge triggered.
- */
-static void au1000_tx_ack(struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- volatile tx_dma_t *ptxd;
-
- ptxd = aup->tx_dma_ring[aup->tx_tail];
-
- while (ptxd->buff_stat & TX_T_DONE) {
- update_tx_stats(dev, ptxd->status);
- ptxd->buff_stat &= ~TX_T_DONE;
- ptxd->len = 0;
- au_sync();
-
- aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
- ptxd = aup->tx_dma_ring[aup->tx_tail];
-
- if (aup->tx_full) {
- aup->tx_full = 0;
- netif_wake_queue(dev);
- }
- }
-}
-
-
-/*
- * Au1000 transmit routine.
- */
-static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- struct net_device_stats *ps = &dev->stats;
- volatile tx_dma_t *ptxd;
- u32 buff_stat;
- db_dest_t *pDB;
- int i;
-
- if (au1000_debug > 5)
- printk("%s: tx: aup %x len=%d, data=%p, head %d\n",
- dev->name, (unsigned)aup, skb->len,
- skb->data, aup->tx_head);
-
- ptxd = aup->tx_dma_ring[aup->tx_head];
- buff_stat = ptxd->buff_stat;
- if (buff_stat & TX_DMA_ENABLE) {
- /* We've wrapped around and the transmitter is still busy */
- netif_stop_queue(dev);
- aup->tx_full = 1;
- return 1;
- }
- else if (buff_stat & TX_T_DONE) {
- update_tx_stats(dev, ptxd->status);
- ptxd->len = 0;
- }
-
- if (aup->tx_full) {
- aup->tx_full = 0;
- netif_wake_queue(dev);
- }
-
- pDB = aup->tx_db_inuse[aup->tx_head];
- skb_copy_from_linear_data(skb, pDB->vaddr, skb->len);
- if (skb->len < ETH_ZLEN) {
- for (i=skb->len; i<ETH_ZLEN; i++) {
- ((char *)pDB->vaddr)[i] = 0;
- }
- ptxd->len = ETH_ZLEN;
- }
- else
- ptxd->len = skb->len;
-
- ps->tx_packets++;
- ps->tx_bytes += ptxd->len;
-
- ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
- au_sync();
- dev_kfree_skb(skb);
- aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
- dev->trans_start = jiffies;
- return 0;
-}
-
-static inline void update_rx_stats(struct net_device *dev, u32 status)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- struct net_device_stats *ps = &dev->stats;
-
- ps->rx_packets++;
- if (status & RX_MCAST_FRAME)
- ps->multicast++;
-
- if (status & RX_ERROR) {
- ps->rx_errors++;
- if (status & RX_MISSED_FRAME)
- ps->rx_missed_errors++;
- if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
- ps->rx_length_errors++;
- if (status & RX_CRC_ERROR)
- ps->rx_crc_errors++;
- if (status & RX_COLL)
- ps->collisions++;
- }
- else
- ps->rx_bytes += status & RX_FRAME_LEN_MASK;
-
-}
-
-/*
- * Au1000 receive routine.
- */
-static int au1000_rx(struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
- struct sk_buff *skb;
- volatile rx_dma_t *prxd;
- u32 buff_stat, status;
- db_dest_t *pDB;
- u32 frmlen;
-
- if (au1000_debug > 5)
- printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
-
- prxd = aup->rx_dma_ring[aup->rx_head];
- buff_stat = prxd->buff_stat;
- while (buff_stat & RX_T_DONE) {
- status = prxd->status;
- pDB = aup->rx_db_inuse[aup->rx_head];
- update_rx_stats(dev, status);
- if (!(status & RX_ERROR)) {
-
- /* good frame */
- frmlen = (status & RX_FRAME_LEN_MASK);
- frmlen -= 4; /* Remove FCS */
- skb = dev_alloc_skb(frmlen + 2);
- if (skb == NULL) {
- printk(KERN_ERR
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- continue;
- }
- skb_reserve(skb, 2); /* 16 byte IP header align */
- skb_copy_to_linear_data(skb,
- (unsigned char *)pDB->vaddr, frmlen);
- skb_put(skb, frmlen);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb); /* pass the packet to upper layers */
- }
- else {
- if (au1000_debug > 4) {
- if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
- if (status & RX_WDOG_TIMER)
- printk("rx wdog\n");
- if (status & RX_RUNT)
- printk("rx runt\n");
- if (status & RX_OVERLEN)
- printk("rx overlen\n");
- if (status & RX_COLL)
- printk("rx coll\n");
- if (status & RX_MII_ERROR)
- printk("rx mii error\n");
- if (status & RX_CRC_ERROR)
- printk("rx crc error\n");
- if (status & RX_LEN_ERROR)
- printk("rx len error\n");
- if (status & RX_U_CNTRL_FRAME)
- printk("rx u control frame\n");
- if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
- }
- }
- prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
- aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
- au_sync();
-
- /* next descriptor */
- prxd = aup->rx_dma_ring[aup->rx_head];
- buff_stat = prxd->buff_stat;
- dev->last_rx = jiffies;
- }
- return 0;
-}
-
-
-/*
- * Au1000 interrupt service routine.
- */
-static irqreturn_t au1000_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
-
- /* Handle RX interrupts first to minimize chance of overrun */
-
- au1000_rx(dev);
- au1000_tx_ack(dev);
- return IRQ_RETVAL(1);
-}
-
-
-/*
- * The Tx ring has been full longer than the watchdog timeout
- * value. The transmitter must be hung?
- */
-static void au1000_tx_timeout(struct net_device *dev)
-{
- printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev);
- reset_mac(dev);
- au1000_init(dev);
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
-}
-
-static void set_rx_mode(struct net_device *dev)
-{
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
-
- if (au1000_debug > 4)
- printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
-
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
- aup->mac->control |= MAC_PROMISCUOUS;
- } else if ((dev->flags & IFF_ALLMULTI) ||
- dev->mc_count > MULTICAST_FILTER_LIMIT) {
- aup->mac->control |= MAC_PASS_ALL_MULTI;
- aup->mac->control &= ~MAC_PROMISCUOUS;
- printk(KERN_INFO "%s: Pass all multicast\n", dev->name);
- } else {
- int i;
- struct dev_mc_list *mclist;
- u32 mc_filter[2]; /* Multicast hash filter */
-
- mc_filter[1] = mc_filter[0] = 0;
- for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
- i++, mclist = mclist->next) {
- set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26,
- (long *)mc_filter);
- }
- aup->mac->multi_hash_high = mc_filter[1];
- aup->mac->multi_hash_low = mc_filter[0];
- aup->mac->control &= ~MAC_PROMISCUOUS;
- aup->mac->control |= MAC_HASH_MODE;
- }
-}
-
-static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
-
- if (!netif_running(dev)) return -EINVAL;
-
- if (!aup->phy_dev) return -EINVAL; // PHY not controllable
-
- return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
-}
-
-module_init(au1000_init_module);
-module_exit(au1000_cleanup_module);
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
deleted file mode 100644
index a886a4b9f7e..00000000000
--- a/drivers/net/ax88796.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-/* drivers/net/ax88796.c
- *
- * Copyright 2005,2007 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Asix AX88796 10/100 Ethernet controller support
- * Based on ne.c, by Donald Becker, et-al.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/isapnp.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/eeprom_93cx6.h>
-
-#include <net/ax88796.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-static int phy_debug = 0;
-
-/* Rename the lib8390.c functions to show that they are in this driver */
-#define __ei_open ax_ei_open
-#define __ei_close ax_ei_close
-#define __ei_poll ax_ei_poll
-#define __ei_tx_timeout ax_ei_tx_timeout
-#define __ei_interrupt ax_ei_interrupt
-#define ____alloc_ei_netdev ax__alloc_ei_netdev
-#define __NS8390_init ax_NS8390_init
-
-/* force unsigned long back to 'void __iomem *' */
-#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
-
-#define ei_inb(_a) readb(ax_convert_addr(_a))
-#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))
-
-#define ei_inb_p(_a) ei_inb(_a)
-#define ei_outb_p(_v, _a) ei_outb(_v, _a)
-
-/* define EI_SHIFT() to take into account our register offsets */
-#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
-
-/* Ensure we have our RCR base value */
-#define AX88796_PLATFORM
-
-static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
-
-#include "lib8390.c"
-
-#define DRV_NAME "ax88796"
-#define DRV_VERSION "1.00"
-
-/* from ne.c */
-#define NE_CMD EI_SHIFT(0x00)
-#define NE_RESET EI_SHIFT(0x1f)
-#define NE_DATAPORT EI_SHIFT(0x10)
-
-#define NE1SM_START_PG 0x20 /* First page of TX buffer */
-#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
-#define NESM_START_PG 0x40 /* First page of TX buffer */
-#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
-
-/* device private data */
-
-struct ax_device {
- struct timer_list mii_timer;
- spinlock_t mii_lock;
- struct mii_if_info mii;
-
- u32 msg_enable;
- void __iomem *map2;
- struct platform_device *dev;
- struct resource *mem;
- struct resource *mem2;
- struct ax_plat_data *plat;
-
- unsigned char running;
- unsigned char resume_open;
-
- u32 reg_offsets[0x20];
-};
-
-static inline struct ax_device *to_ax_dev(struct net_device *dev)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- return (struct ax_device *)(ei_local+1);
-}
-
-/* ax_initial_check
- *
- * do an initial probe for the card to check wether it exists
- * and is functional
- */
-
-static int ax_initial_check(struct net_device *dev)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- void __iomem *ioaddr = ei_local->mem;
- int reg0;
- int regd;
-
- reg0 = ei_inb(ioaddr);
- if (reg0 == 0xFF)
- return -ENODEV;
-
- ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
- regd = ei_inb(ioaddr + 0x0d);
- ei_outb(0xff, ioaddr + 0x0d);
- ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
- ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
- if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
- ei_outb(reg0, ioaddr);
- ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */
- return -ENODEV;
- }
-
- return 0;
-}
-
-/* Hard reset the card. This used to pause for the same period that a
- 8390 reset command required, but that shouldn't be necessary. */
-
-static void ax_reset_8390(struct net_device *dev)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- struct ax_device *ax = to_ax_dev(dev);
- unsigned long reset_start_time = jiffies;
- void __iomem *addr = (void __iomem *)dev->base_addr;
-
- if (ei_debug > 1)
- dev_dbg(&ax->dev->dev, "resetting the 8390 t=%ld\n", jiffies);
-
- ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
-
- ei_status.txing = 0;
- ei_status.dmaing = 0;
-
- /* This check _should_not_ be necessary, omit eventually. */
- while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
- if (jiffies - reset_start_time > 2*HZ/100) {
- dev_warn(&ax->dev->dev, "%s: %s did not complete.\n",
- __FUNCTION__, dev->name);
- break;
- }
- }
-
- ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */
-}
-
-
-static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- struct ax_device *ax = to_ax_dev(dev);
- void __iomem *nic_base = ei_local->mem;
-
- /* This *shouldn't* happen. If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- dev_err(&ax->dev->dev, "%s: DMAing conflict in %s "
- "[DMAstat:%d][irqlock:%d].\n",
- dev->name, __FUNCTION__,
- ei_status.dmaing, ei_status.irqlock);
- return;
- }
-
- ei_status.dmaing |= 0x01;
- ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
- ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
- ei_outb(0, nic_base + EN0_RCNTHI);
- ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */
- ei_outb(ring_page, nic_base + EN0_RSARHI);
- ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
-
- if (ei_status.word16)
- readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
- else
- readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
-
- ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
-
- le16_to_cpus(&hdr->count);
-}
-
-
-/* Block input and output, similar to the Crynwr packet driver. If you
- are porting to a new ethercard, look at the packet driver source for hints.
- The NEx000 doesn't share the on-board packet memory -- you have to put
- the packet out through the "remote DMA" dataport using ei_outb. */
-
-static void ax_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- struct ax_device *ax = to_ax_dev(dev);
- void __iomem *nic_base = ei_local->mem;
- char *buf = skb->data;
-
- if (ei_status.dmaing) {
- dev_err(&ax->dev->dev,
- "%s: DMAing conflict in %s "
- "[DMAstat:%d][irqlock:%d].\n",
- dev->name, __FUNCTION__,
- ei_status.dmaing, ei_status.irqlock);
- return;
- }
-
- ei_status.dmaing |= 0x01;
-
- ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
- ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
- ei_outb(count >> 8, nic_base + EN0_RCNTHI);
- ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
- ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
- ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
-
- if (ei_status.word16) {
- readsw(nic_base + NE_DATAPORT, buf, count >> 1);
- if (count & 0x01)
- buf[count-1] = ei_inb(nic_base + NE_DATAPORT);
-
- } else {
- readsb(nic_base + NE_DATAPORT, buf, count);
- }
-
- ei_status.dmaing &= ~1;
-}
-
-static void ax_block_output(struct net_device *dev, int count,
- const unsigned char *buf, const int start_page)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- struct ax_device *ax = to_ax_dev(dev);
- void __iomem *nic_base = ei_local->mem;
- unsigned long dma_start;
-
- /* Round the count up for word writes. Do we need to do this?
- What effect will an odd byte count have on the 8390?
- I should check someday. */
-
- if (ei_status.word16 && (count & 0x01))
- count++;
-
- /* This *shouldn't* happen. If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- dev_err(&ax->dev->dev, "%s: DMAing conflict in %s."
- "[DMAstat:%d][irqlock:%d]\n",
- dev->name, __FUNCTION__,
- ei_status.dmaing, ei_status.irqlock);
- return;
- }
-
- ei_status.dmaing |= 0x01;
- /* We should already be in page 0, but to be safe... */
- ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
-
- ei_outb(ENISR_RDC, nic_base + EN0_ISR);
-
- /* Now the normal output. */
- ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
- ei_outb(count >> 8, nic_base + EN0_RCNTHI);
- ei_outb(0x00, nic_base + EN0_RSARLO);
- ei_outb(start_page, nic_base + EN0_RSARHI);
-
- ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
- if (ei_status.word16) {
- writesw(nic_base + NE_DATAPORT, buf, count>>1);
- } else {
- writesb(nic_base + NE_DATAPORT, buf, count);
- }
-
- dma_start = jiffies;
-
- while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
- if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
- dev_warn(&ax->dev->dev,
- "%s: timeout waiting for Tx RDC.\n", dev->name);
- ax_reset_8390(dev);
- ax_NS8390_init(dev,1);
- break;
- }
- }
-
- ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
- return;
-}
-
-/* definitions for accessing MII/EEPROM interface */
-
-#define AX_MEMR EI_SHIFT(0x14)
-#define AX_MEMR_MDC (1<<0)
-#define AX_MEMR_MDIR (1<<1)
-#define AX_MEMR_MDI (1<<2)
-#define AX_MEMR_MDO (1<<3)
-#define AX_MEMR_EECS (1<<4)
-#define AX_MEMR_EEI (1<<5)
-#define AX_MEMR_EEO (1<<6)
-#define AX_MEMR_EECLK (1<<7)
-
-/* ax_mii_ei_outbits
- *
- * write the specified set of bits to the phy
-*/
-
-static void
-ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
-{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
- void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
- unsigned int memr;
-
- /* clock low, data to output mode */
- memr = ei_inb(memr_addr);
- memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR);
- ei_outb(memr, memr_addr);
-
- for (len--; len >= 0; len--) {
- if (bits & (1 << len))
- memr |= AX_MEMR_MDO;
- else
- memr &= ~AX_MEMR_MDO;
-
- ei_outb(memr, memr_addr);
-
- /* clock high */
-
- ei_outb(memr | AX_MEMR_MDC, memr_addr);
- udelay(1);
-
- /* clock low */
- ei_outb(memr, memr_addr);
- }
-
- /* leaves the clock line low, mdir input */
- memr |= AX_MEMR_MDIR;
- ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR);
-}
-
-/* ax_phy_ei_inbits
- *
- * read a specified number of bits from the phy
-*/
-
-static unsigned int
-ax_phy_ei_inbits(struct net_device *dev, int no)
-{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
- void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
- unsigned int memr;
- unsigned int result = 0;
-
- /* clock low, data to input mode */
- memr = ei_inb(memr_addr);
- memr &= ~AX_MEMR_MDC;
- memr |= AX_MEMR_MDIR;
- ei_outb(memr, memr_addr);
-
- for (no--; no >= 0; no--) {
- ei_outb(memr | AX_MEMR_MDC, memr_addr);
-
- udelay(1);
-
- if (ei_inb(memr_addr) & AX_MEMR_MDI)
- result |= (1<<no);
-
- ei_outb(memr, memr_addr);
- }
-
- return result;
-}
-
-/* ax_phy_issueaddr
- *
- * use the low level bit shifting routines to send the address
- * and command to the specified phy
-*/
-
-static void
-ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
-{
- if (phy_debug)
- pr_debug("%s: dev %p, %04x, %04x, %d\n",
- __FUNCTION__, dev, phy_addr, reg, opc);
-
- ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */
- ax_mii_ei_outbits(dev, 1, 2); /* frame-start */
- ax_mii_ei_outbits(dev, opc, 2); /* op code */
- ax_mii_ei_outbits(dev, phy_addr, 5); /* phy address */
- ax_mii_ei_outbits(dev, reg, 5); /* reg address */
-}
-
-static int
-ax_phy_read(struct net_device *dev, int phy_addr, int reg)
-{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
- unsigned long flags;
- unsigned int result;
-
- spin_lock_irqsave(&ei_local->page_lock, flags);
-
- ax_phy_issueaddr(dev, phy_addr, reg, 2);
-
- result = ax_phy_ei_inbits(dev, 17);
- result &= ~(3<<16);
-
- spin_unlock_irqrestore(&ei_local->page_lock, flags);
-
- if (phy_debug)
- pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
- phy_addr, reg, result);
-
- return result;
-}
-
-static void
-ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
-{
- struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
- struct ax_device *ax = to_ax_dev(dev);
- unsigned long flags;
-
- dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n",
- __FUNCTION__, dev, phy_addr, reg, value);
-
- spin_lock_irqsave(&ei->page_lock, flags);
-
- ax_phy_issueaddr(dev, phy_addr, reg, 1);
- ax_mii_ei_outbits(dev, 2, 2); /* send TA */
- ax_mii_ei_outbits(dev, value, 16);
-
- spin_unlock_irqrestore(&ei->page_lock, flags);
-}
-
-static void ax_mii_expiry(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct ax_device *ax = to_ax_dev(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&ax->mii_lock, flags);
- mii_check_media(&ax->mii, netif_msg_link(ax), 0);
- spin_unlock_irqrestore(&ax->mii_lock, flags);
-
- if (ax->running) {
- ax->mii_timer.expires = jiffies + HZ*2;
- add_timer(&ax->mii_timer);
- }
-}
-
-static int ax_open(struct net_device *dev)
-{
- struct ax_device *ax = to_ax_dev(dev);
- struct ei_device *ei_local = netdev_priv(dev);
- int ret;
-
- dev_dbg(&ax->dev->dev, "%s: open\n", dev->name);
-
- ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
- if (ret)
- return ret;
-
- ret = ax_ei_open(dev);
- if (ret)
- return ret;
-
- /* turn the phy on (if turned off) */
-
- ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17));
- ax->running = 1;
-
- /* start the MII timer */
-
- init_timer(&ax->mii_timer);
-
- ax->mii_timer.expires = jiffies+1;
- ax->mii_timer.data = (unsigned long) dev;
- ax->mii_timer.function = ax_mii_expiry;
-
- add_timer(&ax->mii_timer);
-
- return 0;
-}
-
-static int ax_close(struct net_device *dev)
-{
- struct ax_device *ax = to_ax_dev(dev);
- struct ei_device *ei_local = netdev_priv(dev);
-
- dev_dbg(&ax->dev->dev, "%s: close\n", dev->name);
-
- /* turn the phy off */
-
- ei_outb(ax->plat->gpoc_val | (1<<6),
- ei_local->mem + EI_SHIFT(0x17));
-
- ax->running = 0;
- wmb();
-
- del_timer_sync(&ax->mii_timer);
- ax_ei_close(dev);
-
- free_irq(dev->irq, dev);
- return 0;
-}
-
-static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
-{
- struct ax_device *ax = to_ax_dev(dev);
- unsigned long flags;
- int rc;
-
- if (!netif_running(dev))
- return -EINVAL;
-
- spin_lock_irqsave(&ax->mii_lock, flags);
- rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL);
- spin_unlock_irqrestore(&ax->mii_lock, flags);
-
- return rc;
-}
-
-/* ethtool ops */
-
-static void ax_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct ax_device *ax = to_ax_dev(dev);
-
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- strcpy(info->bus_info, ax->dev->name);
-}
-
-static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct ax_device *ax = to_ax_dev(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&ax->mii_lock, flags);
- mii_ethtool_gset(&ax->mii, cmd);
- spin_unlock_irqrestore(&ax->mii_lock, flags);
-
- return 0;
-}
-
-static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct ax_device *ax = to_ax_dev(dev);
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(&ax->mii_lock, flags);
- rc = mii_ethtool_sset(&ax->mii, cmd);
- spin_unlock_irqrestore(&ax->mii_lock, flags);
-
- return rc;
-}
-
-static int ax_nway_reset(struct net_device *dev)
-{
- struct ax_device *ax = to_ax_dev(dev);
- return mii_nway_restart(&ax->mii);
-}
-
-static u32 ax_get_link(struct net_device *dev)
-{
- struct ax_device *ax = to_ax_dev(dev);
- return mii_link_ok(&ax->mii);
-}
-
-static const struct ethtool_ops ax_ethtool_ops = {
- .get_drvinfo = ax_get_drvinfo,
- .get_settings = ax_get_settings,
- .set_settings = ax_set_settings,
- .nway_reset = ax_nway_reset,
- .get_link = ax_get_link,
-};
-
-#ifdef CONFIG_AX88796_93CX6
-static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom)
-{
- struct ei_device *ei_local = eeprom->data;
- u8 reg = ei_inb(ei_local->mem + AX_MEMR);
-
- eeprom->reg_data_in = reg & AX_MEMR_EEI;
- eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */
- eeprom->reg_data_clock = reg & AX_MEMR_EECLK;
- eeprom->reg_chip_select = reg & AX_MEMR_EECS;
-}
-
-static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom)
-{
- struct ei_device *ei_local = eeprom->data;
- u8 reg = ei_inb(ei_local->mem + AX_MEMR);
-
- reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS);
-
- if (eeprom->reg_data_in)
- reg |= AX_MEMR_EEI;
- if (eeprom->reg_data_clock)
- reg |= AX_MEMR_EECLK;
- if (eeprom->reg_chip_select)
- reg |= AX_MEMR_EECS;
-
- ei_outb(reg, ei_local->mem + AX_MEMR);
- udelay(10);
-}
-#endif
-
-/* setup code */
-
-static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
-{
- void __iomem *ioaddr = ei_local->mem;
- struct ax_device *ax = to_ax_dev(dev);
-
- /* Select page 0*/
- ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD);
-
- /* set to byte access */
- ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
- ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
-}
-
-/* ax_init_dev
- *
- * initialise the specified device, taking care to note the MAC
- * address it may already have (if configured), ensure
- * the device is ready to be used by lib8390.c and registerd with
- * the network layer.
- */
-
-static int ax_init_dev(struct net_device *dev, int first_init)
-{
- struct ei_device *ei_local = netdev_priv(dev);
- struct ax_device *ax = to_ax_dev(dev);
- void __iomem *ioaddr = ei_local->mem;
- unsigned int start_page;
- unsigned int stop_page;
- int ret;
- int i;
-
- ret = ax_initial_check(dev);
- if (ret)
- goto err_out;
-
- /* setup goes here */
-
- ax_initial_setup(dev, ei_local);
-
- /* read the mac from the card prom if we need it */
-
- if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) {
- unsigned char SA_prom[32];
-
- for(i = 0; i < sizeof(SA_prom); i+=2) {
- SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
- SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT);
- }
-
- if (ax->plat->wordlength == 2)
- for (i = 0; i < 16; i++)
- SA_prom[i] = SA_prom[i+i];
-
- memcpy(dev->dev_addr, SA_prom, 6);
- }
-
-#ifdef CONFIG_AX88796_93CX6
- if (first_init && ax->plat->flags & AXFLG_HAS_93CX6) {
- unsigned char mac_addr[6];
- struct eeprom_93cx6 eeprom;
-
- eeprom.data = ei_local;
- eeprom.register_read = ax_eeprom_register_read;
- eeprom.register_write = ax_eeprom_register_write;
- eeprom.width = PCI_EEPROM_WIDTH_93C56;
-
- eeprom_93cx6_multiread(&eeprom, 0,
- (__le16 __force *)mac_addr,
- sizeof(mac_addr) >> 1);
-
- memcpy(dev->dev_addr, mac_addr, 6);
- }
-#endif
- if (ax->plat->wordlength == 2) {
- /* We must set the 8390 for word mode. */
- ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
- start_page = NESM_START_PG;
- stop_page = NESM_STOP_PG;
- } else {
- start_page = NE1SM_START_PG;
- stop_page = NE1SM_STOP_PG;
- }
-
- /* load the mac-address from the device if this is the
- * first time we've initialised */
-
- if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
- ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
- ei_local->mem + E8390_CMD); /* 0x61 */
-
- for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
- dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
- }
-
- ax_reset_8390(dev);
-
- ei_status.name = "AX88796";
- ei_status.tx_start_page = start_page;
- ei_status.stop_page = stop_page;
- ei_status.word16 = (ax->plat->wordlength == 2);
- ei_status.rx_start_page = start_page + TX_PAGES;
-
-#ifdef PACKETBUF_MEMSIZE
- /* Allow the packet buffer size to be overridden by know-it-alls. */
- ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
-#endif
-
- ei_status.reset_8390 = &ax_reset_8390;
- ei_status.block_input = &ax_block_input;
- ei_status.block_output = &ax_block_output;
- ei_status.get_8390_hdr = &ax_get_8390_hdr;
- ei_status.priv = 0;
-
- dev->open = ax_open;
- dev->stop = ax_close;
- dev->do_ioctl = ax_ioctl;
- dev->ethtool_ops = &ax_ethtool_ops;
-
- ax->msg_enable = NETIF_MSG_LINK;
- ax->mii.phy_id_mask = 0x1f;
- ax->mii.reg_num_mask = 0x1f;
- ax->mii.phy_id = 0x10; /* onboard phy */
- ax->mii.force_media = 0;
- ax->mii.full_duplex = 0;
- ax->mii.mdio_read = ax_phy_read;
- ax->mii.mdio_write = ax_phy_write;
- ax->mii.dev = dev;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ax_ei_poll;
-#endif
- ax_NS8390_init(dev, 0);
-
- if (first_init) {
- DECLARE_MAC_BUF(mac);
-
- dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %s\n",
- ei_status.word16 ? 16:8, dev->irq, dev->base_addr,
- print_mac(mac, dev->dev_addr));
- }
-
- ret = register_netdev(dev);
- if (ret)
- goto out_irq;
-
- return 0;
-
- out_irq:
- /* cleanup irq */
- free_irq(dev->irq, dev);
- err_out:
- return ret;
-}
-
-static int ax_remove(struct platform_device *_dev)
-{
- struct net_device *dev = platform_get_drvdata(_dev);
- struct ax_device *ax;
-
- ax = to_ax_dev(dev);
-
- unregister_netdev(dev);
- free_irq(dev->irq, dev);
-
- iounmap(ei_status.mem);
- release_resource(ax->mem);
- kfree(ax->mem);
-
- if (ax->map2) {
- iounmap(ax->map2);
- release_resource(ax->mem2);
- kfree(ax->mem2);
- }
-
- free_netdev(dev);
-
- return 0;
-}
-
-/* ax_probe
- *
- * This is the entry point when the platform device system uses to
- * notify us of a new device to attach to. Allocate memory, find
- * the resources and information passed, and map the necessary registers.
-*/
-
-static int ax_probe(struct platform_device *pdev)
-{
- struct net_device *dev;
- struct ax_device *ax;
- struct resource *res;
- size_t size;
- int ret;
-
- dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
- if (dev == NULL)
- return -ENOMEM;
-
- /* ok, let's setup our device */
- ax = to_ax_dev(dev);
-
- memset(ax, 0, sizeof(struct ax_device));
-
- spin_lock_init(&ax->mii_lock);
-
- ax->dev = pdev;
- ax->plat = pdev->dev.platform_data;
- platform_set_drvdata(pdev, dev);
-
- ei_status.rxcr_base = ax->plat->rcr_val;
-
- /* find the platform resources */
-
- dev->irq = platform_get_irq(pdev, 0);
- if (dev->irq < 0) {
- dev_err(&pdev->dev, "no IRQ specified\n");
- ret = -ENXIO;
- goto exit_mem;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "no MEM specified\n");
- ret = -ENXIO;
- goto exit_mem;
- }
-
- size = (res->end - res->start) + 1;
-
- /* setup the register offsets from either the platform data
- * or by using the size of the resource provided */
-
- if (ax->plat->reg_offsets)
- ei_status.reg_offset = ax->plat->reg_offsets;
- else {
- ei_status.reg_offset = ax->reg_offsets;
- for (ret = 0; ret < 0x18; ret++)
- ax->reg_offsets[ret] = (size / 0x18) * ret;
- }
-
- ax->mem = request_mem_region(res->start, size, pdev->name);
- if (ax->mem == NULL) {
- dev_err(&pdev->dev, "cannot reserve registers\n");
- ret = -ENXIO;
- goto exit_mem;
- }
-
- ei_status.mem = ioremap(res->start, size);
- dev->base_addr = (unsigned long)ei_status.mem;
-
- if (ei_status.mem == NULL) {
- dev_err(&pdev->dev, "Cannot ioremap area (%08llx,%08llx)\n",
- (unsigned long long)res->start,
- (unsigned long long)res->end);
-
- ret = -ENXIO;
- goto exit_req;
- }
-
- /* look for reset area */
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (res == NULL) {
- if (!ax->plat->reg_offsets) {
- for (ret = 0; ret < 0x20; ret++)
- ax->reg_offsets[ret] = (size / 0x20) * ret;
- }
-
- ax->map2 = NULL;
- } else {
- size = (res->end - res->start) + 1;
-
- ax->mem2 = request_mem_region(res->start, size, pdev->name);
- if (ax->mem == NULL) {
- dev_err(&pdev->dev, "cannot reserve registers\n");
- ret = -ENXIO;
- goto exit_mem1;
- }
-
- ax->map2 = ioremap(res->start, size);
- if (ax->map2 == NULL) {
- dev_err(&pdev->dev, "cannot map reset register\n");
- ret = -ENXIO;
- goto exit_mem2;
- }
-
- ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
- }
-
- /* got resources, now initialise and register device */
-
- ret = ax_init_dev(dev, 1);
- if (!ret)
- return 0;
-
- if (ax->map2 == NULL)
- goto exit_mem1;
-
- iounmap(ax->map2);
-
- exit_mem2:
- release_resource(ax->mem2);
- kfree(ax->mem2);
-
- exit_mem1:
- iounmap(ei_status.mem);
-
- exit_req:
- release_resource(ax->mem);
- kfree(ax->mem);
-
- exit_mem:
- free_netdev(dev);
-
- return ret;
-}
-
-/* suspend and resume */
-
-#ifdef CONFIG_PM
-static int ax_suspend(struct platform_device *dev, pm_message_t state)
-{
- struct net_device *ndev = platform_get_drvdata(dev);
- struct ax_device *ax = to_ax_dev(ndev);
-
- ax->resume_open = ax->running;
-
- netif_device_detach(ndev);
- ax_close(ndev);
-
- return 0;
-}
-
-static int ax_resume(struct platform_device *pdev)
-{
- struct net_device *ndev = platform_get_drvdata(pdev);
- struct ax_device *ax = to_ax_dev(ndev);
-
- ax_initial_setup(ndev, netdev_priv(ndev));
- ax_NS8390_init(ndev, ax->resume_open);
- netif_device_attach(ndev);
-
- if (ax->resume_open)
- ax_open(ndev);
-
- return 0;
-}
-
-#else
-#define ax_suspend NULL
-#define ax_resume NULL
-#endif
-
-static struct platform_driver axdrv = {
- .driver = {
- .name = "ax88796",
- .owner = THIS_MODULE,
- },
- .probe = ax_probe,
- .remove = ax_remove,
- .suspend = ax_suspend,
- .resume = ax_resume,
-};
-
-static int __init axdrv_init(void)
-{
- return platform_driver_register(&axdrv);
-}
-
-static void __exit axdrv_exit(void)
-{
- platform_driver_unregister(&axdrv);
-}
-
-module_init(axdrv_init);
-module_exit(axdrv_exit);
-
-MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
-MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:ax88796");
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
deleted file mode 100644
index 3db7db1828e..00000000000
--- a/drivers/net/bfin_mac.c
+++ /dev/null
@@ -1,1204 +0,0 @@
-/*
- * Blackfin On-Chip MAC Driver
- *
- * Copyright 2004-2007 Analog Devices Inc.
- *
- * Enter bugs at http://blackfin.uclinux.org/
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/crc32.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/skbuff.h>
-#include <linux/platform_device.h>
-
-#include <asm/dma.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/blackfin.h>
-#include <asm/cacheflush.h>
-#include <asm/portmux.h>
-
-#include "bfin_mac.h"
-
-#define DRV_NAME "bfin_mac"
-#define DRV_VERSION "1.1"
-#define DRV_AUTHOR "Bryan Wu, Luke Yang"
-#define DRV_DESC "Blackfin on-chip Ethernet MAC driver"
-
-MODULE_AUTHOR(DRV_AUTHOR);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(DRV_DESC);
-MODULE_ALIAS("platform:bfin_mac");
-
-#if defined(CONFIG_BFIN_MAC_USE_L1)
-# define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size)
-# define bfin_mac_free(dma_handle, ptr) l1_data_sram_free(ptr)
-#else
-# define bfin_mac_alloc(dma_handle, size) \
- dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL)
-# define bfin_mac_free(dma_handle, ptr) \
- dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle)
-#endif
-
-#define PKT_BUF_SZ 1580
-
-#define MAX_TIMEOUT_CNT 500
-
-/* pointers to maintain transmit list */
-static struct net_dma_desc_tx *tx_list_head;
-static struct net_dma_desc_tx *tx_list_tail;
-static struct net_dma_desc_rx *rx_list_head;
-static struct net_dma_desc_rx *rx_list_tail;
-static struct net_dma_desc_rx *current_rx_ptr;
-static struct net_dma_desc_tx *current_tx_ptr;
-static struct net_dma_desc_tx *tx_desc;
-static struct net_dma_desc_rx *rx_desc;
-
-#if defined(CONFIG_BFIN_MAC_RMII)
-static u16 pin_req[] = P_RMII0;
-#else
-static u16 pin_req[] = P_MII0;
-#endif
-
-static void bfin_mac_disable(void);
-static void bfin_mac_enable(void);
-
-static void desc_list_free(void)
-{
- struct net_dma_desc_rx *r;
- struct net_dma_desc_tx *t;
- int i;
-#if !defined(CONFIG_BFIN_MAC_USE_L1)
- dma_addr_t dma_handle = 0;
-#endif
-
- if (tx_desc) {
- t = tx_list_head;
- for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
- if (t) {
- if (t->skb) {
- dev_kfree_skb(t->skb);
- t->skb = NULL;
- }
- t = t->next;
- }
- }
- bfin_mac_free(dma_handle, tx_desc);
- }
-
- if (rx_desc) {
- r = rx_list_head;
- for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
- if (r) {
- if (r->skb) {
- dev_kfree_skb(r->skb);
- r->skb = NULL;
- }
- r = r->next;
- }
- }
- bfin_mac_free(dma_handle, rx_desc);
- }
-}
-
-static int desc_list_init(void)
-{
- int i;
- struct sk_buff *new_skb;
-#if !defined(CONFIG_BFIN_MAC_USE_L1)
- /*
- * This dma_handle is useless in Blackfin dma_alloc_coherent().
- * The real dma handler is the return value of dma_alloc_coherent().
- */
- dma_addr_t dma_handle;
-#endif
-
- tx_desc = bfin_mac_alloc(&dma_handle,
- sizeof(struct net_dma_desc_tx) *
- CONFIG_BFIN_TX_DESC_NUM);
- if (tx_desc == NULL)
- goto init_error;
-
- rx_desc = bfin_mac_alloc(&dma_handle,
- sizeof(struct net_dma_desc_rx) *
- CONFIG_BFIN_RX_DESC_NUM);
- if (rx_desc == NULL)
- goto init_error;
-
- /* init tx_list */
- tx_list_head = tx_list_tail = tx_desc;
-
- for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
- struct net_dma_desc_tx *t = tx_desc + i;
- struct dma_descriptor *a = &(t->desc_a);
- struct dma_descriptor *b = &(t->desc_b);
-
- /*
- * disable DMA
- * read from memory WNR = 0
- * wordsize is 32 bits
- * 6 half words is desc size
- * large desc flow
- */
- a->config = WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
- a->start_addr = (unsigned long)t->packet;
- a->x_count = 0;
- a->next_dma_desc = b;
-
- /*
- * enabled DMA
- * write to memory WNR = 1
- * wordsize is 32 bits
- * disable interrupt
- * 6 half words is desc size
- * large desc flow
- */
- b->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
- b->start_addr = (unsigned long)(&(t->status));
- b->x_count = 0;
-
- t->skb = NULL;
- tx_list_tail->desc_b.next_dma_desc = a;
- tx_list_tail->next = t;
- tx_list_tail = t;
- }
- tx_list_tail->next = tx_list_head; /* tx_list is a circle */
- tx_list_tail->desc_b.next_dma_desc = &(tx_list_head->desc_a);
- current_tx_ptr = tx_list_head;
-
- /* init rx_list */
- rx_list_head = rx_list_tail = rx_desc;
-
- for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
- struct net_dma_desc_rx *r = rx_desc + i;
- struct dma_descriptor *a = &(r->desc_a);
- struct dma_descriptor *b = &(r->desc_b);
-
- /* allocate a new skb for next time receive */
- new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
- if (!new_skb) {
- printk(KERN_NOTICE DRV_NAME
- ": init: low on mem - packet dropped\n");
- goto init_error;
- }
- skb_reserve(new_skb, 2);
- r->skb = new_skb;
-
- /*
- * enabled DMA
- * write to memory WNR = 1
- * wordsize is 32 bits
- * disable interrupt
- * 6 half words is desc size
- * large desc flow
- */
- a->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
- /* since RXDWA is enabled */
- a->start_addr = (unsigned long)new_skb->data - 2;
- a->x_count = 0;
- a->next_dma_desc = b;
-
- /*
- * enabled DMA
- * write to memory WNR = 1
- * wordsize is 32 bits
- * enable interrupt
- * 6 half words is desc size
- * large desc flow
- */
- b->config = DMAEN | WNR | WDSIZE_32 | DI_EN |
- NDSIZE_6 | DMAFLOW_LARGE;
- b->start_addr = (unsigned long)(&(r->status));
- b->x_count = 0;
-
- rx_list_tail->desc_b.next_dma_desc = a;
- rx_list_tail->next = r;
- rx_list_tail = r;
- }
- rx_list_tail->next = rx_list_head; /* rx_list is a circle */
- rx_list_tail->desc_b.next_dma_desc = &(rx_list_head->desc_a);
- current_rx_ptr = rx_list_head;
-
- return 0;
-
-init_error:
- desc_list_free();
- printk(KERN_ERR DRV_NAME ": kmalloc failed\n");
- return -ENOMEM;
-}
-
-
-/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
-
-/*
- * MII operations
- */
-/* Wait until the previous MDC/MDIO transaction has completed */
-static void mdio_poll(void)
-{
- int timeout_cnt = MAX_TIMEOUT_CNT;
-
- /* poll the STABUSY bit */
- while ((bfin_read_EMAC_STAADD()) & STABUSY) {
- udelay(1);
- if (timeout_cnt-- < 0) {
- printk(KERN_ERR DRV_NAME
- ": wait MDC/MDIO transaction to complete timeout\n");
- break;
- }
- }
-}
-
-/* Read an off-chip register in a PHY through the MDC/MDIO port */
-static int mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
-{
- mdio_poll();
-
- /* read mode */
- bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
- SET_REGAD((u16) regnum) |
- STABUSY);
-
- mdio_poll();
-
- return (int) bfin_read_EMAC_STADAT();
-}
-
-/* Write an off-chip register in a PHY through the MDC/MDIO port */
-static int mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
- u16 value)
-{
- mdio_poll();
-
- bfin_write_EMAC_STADAT((u32) value);
-
- /* write mode */
- bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
- SET_REGAD((u16) regnum) |
- STAOP |
- STABUSY);
-
- mdio_poll();
-
- return 0;
-}
-
-static int mdiobus_reset(struct mii_bus *bus)
-{
- return 0;
-}
-
-static void bfin_mac_adjust_link(struct net_device *dev)
-{
- struct bfin_mac_local *lp = netdev_priv(dev);
- struct phy_device *phydev = lp->phydev;
- unsigned long flags;
- int new_state = 0;
-
- spin_lock_irqsave(&lp->lock, flags);
- if (phydev->link) {
- /* Now we make sure that we can be in full duplex mode.
- * If not, we operate in half-duplex mode. */
- if (phydev->duplex != lp->old_duplex) {
- u32 opmode = bfin_read_EMAC_OPMODE();
- new_state = 1;
-
- if (phydev->duplex)
- opmode |= FDMODE;
- else
- opmode &= ~(FDMODE);
-
- bfin_write_EMAC_OPMODE(opmode);
- lp->old_duplex = phydev->duplex;
- }
-
- if (phydev->speed != lp->old_speed) {
-#if defined(CONFIG_BFIN_MAC_RMII)
- u32 opmode = bfin_read_EMAC_OPMODE();
- switch (phydev->speed) {
- case 10:
- opmode |= RMII_10;
- break;
- case 100:
- opmode &= ~(RMII_10);
- break;
- default:
- printk(KERN_WARNING
- "%s: Ack! Speed (%d) is not 10/100!\n",
- DRV_NAME, phydev->speed);
- break;
- }
- bfin_write_EMAC_OPMODE(opmode);
-#endif
-
- new_state = 1;
- lp->old_speed = phydev->speed;
- }
-
- if (!lp->old_link) {
- new_state = 1;
- lp->old_link = 1;
- }
- } else if (lp->old_link) {
- new_state = 1;
- lp->old_link = 0;
- lp->old_speed = 0;
- lp->old_duplex = -1;
- }
-
- if (new_state) {
- u32 opmode = bfin_read_EMAC_OPMODE();
- phy_print_status(phydev);
- pr_debug("EMAC_OPMODE = 0x%08x\n", opmode);
- }
-
- spin_unlock_irqrestore(&lp->lock, flags);
-}
-
-/* MDC = 2.5 MHz */
-#define MDC_CLK 2500000
-
-static int mii_probe(struct net_device *dev)
-{
- struct bfin_mac_local *lp = netdev_priv(dev);
- struct phy_device *phydev = NULL;
- unsigned short sysctl;
- int i;
- u32 sclk, mdc_div;
-
- /* Enable PHY output early */
- if (!(bfin_read_VR_CTL() & PHYCLKOE))
- bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
-
- sclk = get_sclk();
- mdc_div = ((sclk / MDC_CLK) / 2) - 1;
-
- sysctl = bfin_read_EMAC_SYSCTL();
- sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div);
- bfin_write_EMAC_SYSCTL(sysctl);
-
- /* search for connect PHY device */
- for (i = 0; i < PHY_MAX_ADDR; i++) {
- struct phy_device *const tmp_phydev = lp->mii_bus.phy_map[i];
-
- if (!tmp_phydev)
- continue; /* no PHY here... */
-
- phydev = tmp_phydev;
- break; /* found it */
- }
-
- /* now we are supposed to have a proper phydev, to attach to... */
- if (!phydev) {
- printk(KERN_INFO "%s: Don't found any phy device at all\n",
- dev->name);
- return -ENODEV;
- }
-
-#if defined(CONFIG_BFIN_MAC_RMII)
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_RMII);
-#else
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
-#endif
-
- if (IS_ERR(phydev)) {
- printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
- return PTR_ERR(phydev);
- }
-
- /* mask with MAC supported features */
- phydev->supported &= (SUPPORTED_10baseT_Half
- | SUPPORTED_10baseT_Full
- | SUPPORTED_100baseT_Half
- | SUPPORTED_100baseT_Full
- | SUPPORTED_Autoneg
- | SUPPORTED_Pause | SUPPORTED_Asym_Pause
- | SUPPORTED_MII
- | SUPPORTED_TP);
-
- phydev->advertising = phydev->supported;
-
- lp->old_link = 0;
- lp->old_speed = 0;
- lp->old_duplex = -1;
- lp->phydev = phydev;
-
- printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)"
- "@sclk=%dMHz)\n",
- DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq,
- MDC_CLK, mdc_div, sclk/1000000);
-
- return 0;
-}
-
-/*
- * Ethtool support
- */
-
-static int
-bfin_mac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct bfin_mac_local *lp = netdev_priv(dev);
-
- if (lp->phydev)
- return phy_ethtool_gset(lp->phydev, cmd);
-
- return -EINVAL;
-}
-
-static int
-bfin_mac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct bfin_mac_local *lp = netdev_priv(dev);
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (lp->phydev)
- return phy_ethtool_sset(lp->phydev, cmd);
-
- return -EINVAL;
-}
-
-static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- strcpy(info->fw_version, "N/A");
- strcpy(info->bus_info, dev->dev.bus_id);
-}
-
-static struct ethtool_ops bfin_mac_ethtool_ops = {
- .get_settings = bfin_mac_ethtool_getsettings,
- .set_settings = bfin_mac_ethtool_setsettings,
- .get_link = ethtool_op_get_link,
- .get_drvinfo = bfin_mac_ethtool_getdrvinfo,
-};
-
-/**************************************************************************/
-void setup_system_regs(struct net_device *dev)
-{
- unsigned short sysctl;
-
- /*
- * Odd word alignment for Receive Frame DMA word
- * Configure checksum support and rcve frame word alignment
- */
- sysctl = bfin_read_EMAC_SYSCTL();
-#if defined(BFIN_MAC_CSUM_OFFLOAD)
- sysctl |= RXDWA | RXCKS;
-#else
- sysctl |= RXDWA;
-#endif
- bfin_write_EMAC_SYSCTL(sysctl);
-
- bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
-
- /* Initialize the TX DMA channel registers */
- bfin_write_DMA2_X_COUNT(0);
- bfin_write_DMA2_X_MODIFY(4);
- bfin_write_DMA2_Y_COUNT(0);
- bfin_write_DMA2_Y_MODIFY(0);
-
- /* Initialize the RX DMA channel registers */
- bfin_write_DMA1_X_COUNT(0);
- bfin_write_DMA1_X_MODIFY(4);
- bfin_write_DMA1_Y_COUNT(0);
- bfin_write_DMA1_Y_MODIFY(0);
-}
-
-static void setup_mac_addr(u8 *mac_addr)
-{
- u32 addr_low = le32_to_cpu(*(__le32 *) & mac_addr[0]);
- u16 addr_hi = le16_to_cpu(*(__le16 *) & mac_addr[4]);
-
- /* this depends on a little-endian machine */
- bfin_write_EMAC_ADDRLO(addr_low);
- bfin_write_EMAC_ADDRHI(addr_hi);
-}
-
-static int bfin_mac_set_mac_address(struct net_device *dev, void *p)
-{
- struct sockaddr *addr = p;
- if (netif_running(dev))
- return -EBUSY;
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- setup_mac_addr(dev->dev_addr);
- return 0;
-}
-
-static void adjust_tx_list(void)
-{
- int timeout_cnt = MAX_TIMEOUT_CNT;
-
- if (tx_list_head->status.status_word != 0
- && current_tx_ptr != tx_list_head) {
- goto adjust_head; /* released something, just return; */
- }
-
- /*
- * if nothing released, check wait condition
- * current's next can not be the head,
- * otherwise the dma will not stop as we want
- */
- if (current_tx_ptr->next->next == tx_list_head) {
- while (tx_list_head->status.status_word == 0) {
- mdelay(1);
- if (tx_list_head->status.status_word != 0
- || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
- goto adjust_head;
- }
- if (timeout_cnt-- < 0) {
- printk(KERN_ERR DRV_NAME
- ": wait for adjust tx list head timeout\n");
- break;
- }
- }
- if (tx_list_head->status.status_word != 0) {
- goto adjust_head;
- }
- }
-
- return;
-
-adjust_head:
- do {
- tx_list_head->desc_a.config &= ~DMAEN;
- tx_list_head->status.status_word = 0;
- if (tx_list_head->skb) {
- dev_kfree_skb(tx_list_head->skb);
- tx_list_head->skb = NULL;
- } else {
- printk(KERN_ERR DRV_NAME
- ": no sk_buff in a transmitted frame!\n");
- }
- tx_list_head = tx_list_head->next;
- } while (tx_list_head->status.status_word != 0
- && current_tx_ptr != tx_list_head);
- return;
-
-}
-
-static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- u16 *data;
-
- current_tx_ptr->skb = skb;
-
- if (ANOMALY_05000285) {
- /*
- * TXDWA feature is not avaible to older revision < 0.3 silicon
- * of BF537
- *
- * Only if data buffer is ODD WORD alignment, we do not
- * need to memcpy
- */
- u32 data_align = (u32)(skb->data) & 0x3;
- if (data_align == 0x2) {
- /* move skb->data to current_tx_ptr payload */
- data = (u16 *)(skb->data) - 1;
- *data = (u16)(skb->len);
- current_tx_ptr->desc_a.start_addr = (u32)data;
- /* this is important! */
- blackfin_dcache_flush_range((u32)data,
- (u32)((u8 *)data + skb->len + 4));
- } else {
- *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
- memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
- skb->len);
- current_tx_ptr->desc_a.start_addr =
- (u32)current_tx_ptr->packet;
- if (current_tx_ptr->status.status_word != 0)
- current_tx_ptr->status.status_word = 0;
- blackfin_dcache_flush_range(
- (u32)current_tx_ptr->packet,
- (u32)(current_tx_ptr->packet + skb->len + 2));
- }
- } else {
- /*
- * TXDWA feature is avaible to revision < 0.3 silicon of
- * BF537 and always avaible to BF52x
- */
- u32 data_align = (u32)(skb->data) & 0x3;
- if (data_align == 0x0) {
- u16 sysctl = bfin_read_EMAC_SYSCTL();
- sysctl |= TXDWA;
- bfin_write_EMAC_SYSCTL(sysctl);
-
- /* move skb->data to current_tx_ptr payload */
- data = (u16 *)(skb->data) - 2;
- *data = (u16)(skb->len);
- current_tx_ptr->desc_a.start_addr = (u32)data;
- /* this is important! */
- blackfin_dcache_flush_range(
- (u32)data,
- (u32)((u8 *)data + skb->len + 4));
- } else if (data_align == 0x2) {
- u16 sysctl = bfin_read_EMAC_SYSCTL();
- sysctl &= ~TXDWA;
- bfin_write_EMAC_SYSCTL(sysctl);
-
- /* move skb->data to current_tx_ptr payload */
- data = (u16 *)(skb->data) - 1;
- *data = (u16)(skb->len);
- current_tx_ptr->desc_a.start_addr = (u32)data;
- /* this is important! */
- blackfin_dcache_flush_range(
- (u32)data,
- (u32)((u8 *)data + skb->len + 4));
- } else {
- u16 sysctl = bfin_read_EMAC_SYSCTL();
- sysctl &= ~TXDWA;
- bfin_write_EMAC_SYSCTL(sysctl);
-
- *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
- memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
- skb->len);
- current_tx_ptr->desc_a.start_addr =
- (u32)current_tx_ptr->packet;
- if (current_tx_ptr->status.status_word != 0)
- current_tx_ptr->status.status_word = 0;
- blackfin_dcache_flush_range(
- (u32)current_tx_ptr->packet,
- (u32)(current_tx_ptr->packet + skb->len + 2));
- }
- }
-
- /* enable this packet's dma */
- current_tx_ptr->desc_a.config |= DMAEN;
-
- /* tx dma is running, just return */
- if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
- goto out;
-
- /* tx dma is not running */
- bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
- /* dma enabled, read from memory, size is 6 */
- bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
- /* Turn on the EMAC tx */
- bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
-
-out:
- adjust_tx_list();
- current_tx_ptr = current_tx_ptr->next;
- dev->trans_start = jiffies;
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += (skb->len);
- return 0;
-}
-
-static void bfin_mac_rx(struct net_device *dev)
-{
- struct sk_buff *skb, *new_skb;
- unsigned short len;
-
- /* allocate a new skb for next time receive */
- skb = current_rx_ptr->skb;
- new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
- if (!new_skb) {
- printk(KERN_NOTICE DRV_NAME
- ": rx: low on mem - packet dropped\n");
- dev->stats.rx_dropped++;
- goto out;
- }
- /* reserve 2 bytes for RXDWA padding */
- skb_reserve(new_skb, 2);
- current_rx_ptr->skb = new_skb;
- current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
-
- /* Invidate the data cache of skb->data range when it is write back
- * cache. It will prevent overwritting the new data from DMA
- */
- blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
- (unsigned long)new_skb->end);
-
- len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
- skb_put(skb, len);
- blackfin_dcache_invalidate_range((unsigned long)skb->head,
- (unsigned long)skb->tail);
-
- dev->last_rx = jiffies;
- skb->protocol = eth_type_trans(skb, dev);
-#if defined(BFIN_MAC_CSUM_OFFLOAD)
- skb->csum = current_rx_ptr->status.ip_payload_csum;
- skb->ip_summed = CHECKSUM_COMPLETE;
-#endif
-
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += len;
- current_rx_ptr->status.status_word = 0x00000000;
- current_rx_ptr = current_rx_ptr->next;
-
-out:
- return;
-}
-
-/* interrupt routine to handle rx and error signal */
-static irqreturn_t bfin_mac_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- int number = 0;
-
-get_one_packet:
- if (current_rx_ptr->status.status_word == 0) {
- /* no more new packet received */
- if (number == 0) {
- if (current_rx_ptr->next->status.status_word != 0) {
- current_rx_ptr = current_rx_ptr->next;
- goto real_rx;
- }
- }
- bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() |
- DMA_DONE | DMA_ERR);
- return IRQ_HANDLED;
- }
-
-real_rx:
- bfin_mac_rx(dev);
- number++;
- goto get_one_packet;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void bfin_mac_poll(struct net_device *dev)
-{
- disable_irq(IRQ_MAC_RX);
- bfin_mac_interrupt(IRQ_MAC_RX, dev);
- enable_irq(IRQ_MAC_RX);
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
-static void bfin_mac_disable(void)
-{
- unsigned int opmode;
-
- opmode = bfin_read_EMAC_OPMODE();
- opmode &= (~RE);
- opmode &= (~TE);
- /* Turn off the EMAC */
- bfin_write_EMAC_OPMODE(opmode);
-}
-
-/*
- * Enable Interrupts, Receive, and Transmit
- */
-static void bfin_mac_enable(void)
-{
- u32 opmode;
-
- pr_debug("%s: %s\n", DRV_NAME, __FUNCTION__);
-
- /* Set RX DMA */
- bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
- bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config);
-
- /* Wait MII done */
- mdio_poll();
-
- /* We enable only RX here */
- /* ASTP : Enable Automatic Pad Stripping
- PR : Promiscuous Mode for test
- PSF : Receive frames with total length less than 64 bytes.
- FDMODE : Full Duplex Mode
- LB : Internal Loopback for test
- RE : Receiver Enable */
- opmode = bfin_read_EMAC_OPMODE();
- if (opmode & FDMODE)
- opmode |= PSF;
- else
- opmode |= DRO | DC | PSF;
- opmode |= RE;
-
-#if defined(CONFIG_BFIN_MAC_RMII)
- opmode |= RMII; /* For Now only 100MBit are supported */
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2
- opmode |= TE;
-#endif
-#endif
- /* Turn on the EMAC rx */
- bfin_write_EMAC_OPMODE(opmode);
-}
-
-/* Our watchdog timed out. Called by the networking layer */
-static void bfin_mac_timeout(struct net_device *dev)
-{
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
-
- bfin_mac_disable();
-
- /* reset tx queue */
- tx_list_tail = tx_list_head->next;
-
- bfin_mac_enable();
-
- /* We can accept TX packets again */
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
-}
-
-static void bfin_mac_multicast_hash(struct net_device *dev)
-{
- u32 emac_hashhi, emac_hashlo;
- struct dev_mc_list *dmi = dev->mc_list;
- char *addrs;
- int i;
- u32 crc;
-
- emac_hashhi = emac_hashlo = 0;
-
- for (i = 0; i < dev->mc_count; i++) {
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
-
- /* skip non-multicast addresses */
- if (!(*addrs & 1))
- continue;
-
- crc = ether_crc(ETH_ALEN, addrs);
- crc >>= 26;
-
- if (crc & 0x20)
- emac_hashhi |= 1 << (crc & 0x1f);
- else
- emac_hashlo |= 1 << (crc & 0x1f);
- }
-
- bfin_write_EMAC_HASHHI(emac_hashhi);
- bfin_write_EMAC_HASHLO(emac_hashlo);
-
- return;
-}
-
-/*
- * This routine will, depending on the values passed to it,
- * either make it accept multicast packets, go into
- * promiscuous mode (for TCPDUMP and cousins) or accept
- * a select set of multicast packets
- */
-static void bfin_mac_set_multicast_list(struct net_device *dev)
-{
- u32 sysctl;
-
- if (dev->flags & IFF_PROMISC) {
- printk(KERN_INFO "%s: set to promisc mode\n", dev->name);
- sysctl = bfin_read_EMAC_OPMODE();
- sysctl |= RAF;
- bfin_write_EMAC_OPMODE(sysctl);
- } else if (dev->flags & IFF_ALLMULTI) {
- /* accept all multicast */
- sysctl = bfin_read_EMAC_OPMODE();
- sysctl |= PAM;
- bfin_write_EMAC_OPMODE(sysctl);
- } else if (dev->mc_count) {
- /* set up multicast hash table */
- sysctl = bfin_read_EMAC_OPMODE();
- sysctl |= HM;
- bfin_write_EMAC_OPMODE(sysctl);
- bfin_mac_multicast_hash(dev);
- } else {
- /* clear promisc or multicast mode */
- sysctl = bfin_read_EMAC_OPMODE();
- sysctl &= ~(RAF | PAM);
- bfin_write_EMAC_OPMODE(sysctl);
- }
-}
-
-/*
- * this puts the device in an inactive state
- */
-static void bfin_mac_shutdown(struct net_device *dev)
-{
- /* Turn off the EMAC */
- bfin_write_EMAC_OPMODE(0x00000000);
- /* Turn off the EMAC RX DMA */
- bfin_write_DMA1_CONFIG(0x0000);
- bfin_write_DMA2_CONFIG(0x0000);
-}
-
-/*
- * Open and Initialize the interface
- *
- * Set up everything, reset the card, etc..
- */
-static int bfin_mac_open(struct net_device *dev)
-{
- struct bfin_mac_local *lp = netdev_priv(dev);
- int retval;
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
-
- /*
- * Check that the address is valid. If its not, refuse
- * to bring the device up. The user must specify an
- * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
- */
- if (!is_valid_ether_addr(dev->dev_addr)) {
- printk(KERN_WARNING DRV_NAME ": no valid ethernet hw addr\n");
- return -EINVAL;
- }
-
- /* initial rx and tx list */
- retval = desc_list_init();
-
- if (retval)
- return retval;
-
- phy_start(lp->phydev);
- phy_write(lp->phydev, MII_BMCR, BMCR_RESET);
- setup_system_regs(dev);
- setup_mac_addr(dev->dev_addr);
- bfin_mac_disable();
- bfin_mac_enable();
- pr_debug("hardware init finished\n");
- netif_start_queue(dev);
- netif_carrier_on(dev);
-
- return 0;
-}
-
-/*
- *
- * this makes the board clean up everything that it can
- * and not talk to the outside world. Caused by
- * an 'ifconfig ethX down'
- */
-static int bfin_mac_close(struct net_device *dev)
-{
- struct bfin_mac_local *lp = netdev_priv(dev);
- pr_debug("%s: %s\n", dev->name, __FUNCTION__);
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
-
- phy_stop(lp->phydev);
- phy_write(lp->phydev, MII_BMCR, BMCR_PDOWN);
-
- /* clear everything */
- bfin_mac_shutdown(dev);
-
- /* free the rx/tx buffers */
- desc_list_free();
-
- return 0;
-}
-
-static int __devinit bfin_mac_probe(struct platform_device *pdev)
-{
- struct net_device *ndev;
- struct bfin_mac_local *lp;
- int rc, i;
-
- ndev = alloc_etherdev(sizeof(struct bfin_mac_local));
- if (!ndev) {
- dev_err(&pdev->dev, "Cannot allocate net device!\n");
- return -ENOMEM;
- }
-
- SET_NETDEV_DEV(ndev, &pdev->dev);
- platform_set_drvdata(pdev, ndev);
- lp = netdev_priv(ndev);
-
- /* Grab the MAC address in the MAC */
- *(__le32 *) (&(ndev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
- *(__le16 *) (&(ndev->dev_addr[4])) = cpu_to_le16((u16) bfin_read_EMAC_ADDRHI());
-
- /* probe mac */
- /*todo: how to proble? which is revision_register */
- bfin_write_EMAC_ADDRLO(0x12345678);
- if (bfin_read_EMAC_ADDRLO() != 0x12345678) {
- dev_err(&pdev->dev, "Cannot detect Blackfin on-chip ethernet MAC controller!\n");
- rc = -ENODEV;
- goto out_err_probe_mac;
- }
-
- /* set the GPIO pins to Ethernet mode */
- rc = peripheral_request_list(pin_req, DRV_NAME);
- if (rc) {
- dev_err(&pdev->dev, "Requesting peripherals failed!\n");
- rc = -EFAULT;
- goto out_err_setup_pin_mux;
- }
-
- /*
- * Is it valid? (Did bootloader initialize it?)
- * Grab the MAC from the board somehow
- * this is done in the arch/blackfin/mach-bfxxx/boards/eth_mac.c
- */
- if (!is_valid_ether_addr(ndev->dev_addr))
- bfin_get_ether_addr(ndev->dev_addr);
-
- /* If still not valid, get a random one */
- if (!is_valid_ether_addr(ndev->dev_addr))
- random_ether_addr(ndev->dev_addr);
-
- setup_mac_addr(ndev->dev_addr);
-
- /* MDIO bus initial */
- lp->mii_bus.priv = ndev;
- lp->mii_bus.read = mdiobus_read;
- lp->mii_bus.write = mdiobus_write;
- lp->mii_bus.reset = mdiobus_reset;
- lp->mii_bus.name = "bfin_mac_mdio";
- snprintf(lp->mii_bus.id, MII_BUS_ID_SIZE, "0");
- lp->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
- for (i = 0; i < PHY_MAX_ADDR; ++i)
- lp->mii_bus.irq[i] = PHY_POLL;
-
- rc = mdiobus_register(&lp->mii_bus);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
- goto out_err_mdiobus_register;
- }
-
- rc = mii_probe(ndev);
- if (rc) {
- dev_err(&pdev->dev, "MII Probe failed!\n");
- goto out_err_mii_probe;
- }
-
- /* Fill in the fields of the device structure with ethernet values. */
- ether_setup(ndev);
-
- ndev->open = bfin_mac_open;
- ndev->stop = bfin_mac_close;
- ndev->hard_start_xmit = bfin_mac_hard_start_xmit;
- ndev->set_mac_address = bfin_mac_set_mac_address;
- ndev->tx_timeout = bfin_mac_timeout;
- ndev->set_multicast_list = bfin_mac_set_multicast_list;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = bfin_mac_poll;
-#endif
- ndev->ethtool_ops = &bfin_mac_ethtool_ops;
-
- spin_lock_init(&lp->lock);
-
- /* now, enable interrupts */
- /* register irq handler */
- rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt,
- IRQF_DISABLED | IRQF_SHARED, "EMAC_RX", ndev);
- if (rc) {
- dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n");
- rc = -EBUSY;
- goto out_err_request_irq;
- }
-
- rc = register_netdev(ndev);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register net device!\n");
- goto out_err_reg_ndev;
- }
-
- /* now, print out the card info, in a short format.. */
- dev_info(&pdev->dev, "%s, Version %s\n", DRV_DESC, DRV_VERSION);
-
- return 0;
-
-out_err_reg_ndev:
- free_irq(IRQ_MAC_RX, ndev);
-out_err_request_irq:
-out_err_mii_probe:
- mdiobus_unregister(&lp->mii_bus);
-out_err_mdiobus_register:
- peripheral_free_list(pin_req);
-out_err_setup_pin_mux:
-out_err_probe_mac:
- platform_set_drvdata(pdev, NULL);
- free_netdev(ndev);
-
- return rc;
-}
-
-static int __devexit bfin_mac_remove(struct platform_device *pdev)
-{
- struct net_device *ndev = platform_get_drvdata(pdev);
- struct bfin_mac_local *lp = netdev_priv(ndev);
-
- platform_set_drvdata(pdev, NULL);
-
- mdiobus_unregister(&lp->mii_bus);
-
- unregister_netdev(ndev);
-
- free_irq(IRQ_MAC_RX, ndev);
-
- free_netdev(ndev);
-
- peripheral_free_list(pin_req);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
- struct net_device *net_dev = platform_get_drvdata(pdev);
-
- if (netif_running(net_dev))
- bfin_mac_close(net_dev);
-
- return 0;
-}
-
-static int bfin_mac_resume(struct platform_device *pdev)
-{
- struct net_device *net_dev = platform_get_drvdata(pdev);
-
- if (netif_running(net_dev))
- bfin_mac_open(net_dev);
-
- return 0;
-}
-#else
-#define bfin_mac_suspend NULL
-#define bfin_mac_resume NULL
-#endif /* CONFIG_PM */
-
-static struct platform_driver bfin_mac_driver = {
- .probe = bfin_mac_probe,
- .remove = __devexit_p(bfin_mac_remove),
- .resume = bfin_mac_resume,
- .suspend = bfin_mac_suspend,
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
-};
-
-static int __init bfin_mac_init(void)
-{
- return platform_driver_register(&bfin_mac_driver);
-}
-
-module_init(bfin_mac_init);
-
-static void __exit bfin_mac_cleanup(void)
-{
- platform_driver_unregister(&bfin_mac_driver);
-}
-
-module_exit(bfin_mac_cleanup);
-
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
deleted file mode 100644
index e4b1de43556..00000000000
--- a/drivers/net/bnx2_fw.h
+++ /dev/null
@@ -1,4613 +0,0 @@
-/* bnx2_fw.h: Broadcom NX2 network driver.
- *
- * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, except as noted below.
- *
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
-
-static u8 bnx2_COM_b06FwText[] = {
- 0xcd, 0x7c, 0x0d, 0x70, 0x5c, 0xd5, 0x95, 0xe6, 0xe9, 0xd7, 0xdd, 0x52,
- 0x4b, 0x96, 0xe5, 0x27, 0xb9, 0x51, 0x1a, 0xa2, 0x24, 0xef, 0xa9, 0x9f,
- 0xa4, 0x06, 0x29, 0xe4, 0xd9, 0x08, 0x10, 0x49, 0x0f, 0x34, 0xdd, 0x92,
- 0x11, 0x89, 0x77, 0x24, 0x40, 0x61, 0xbc, 0x3b, 0xae, 0xac, 0xa6, 0x2d,
- 0x13, 0x42, 0x31, 0x35, 0xae, 0x0a, 0x3b, 0x71, 0xb2, 0x04, 0x37, 0x2d,
- 0x99, 0x38, 0x8c, 0xec, 0x56, 0x64, 0x59, 0x66, 0x67, 0xd8, 0xd9, 0x4e,
- 0x4b, 0xb2, 0x19, 0xa6, 0xed, 0xc6, 0x90, 0x1f, 0xa6, 0x92, 0x0c, 0x5a,
- 0xe3, 0x00, 0x93, 0xcd, 0x56, 0x41, 0x2a, 0xb5, 0xcb, 0x6c, 0x51, 0xbb,
- 0x5e, 0x27, 0x4c, 0xb2, 0xa9, 0xda, 0x0a, 0x3b, 0x93, 0xda, 0x65, 0xf2,
- 0x33, 0x6f, 0xbf, 0xef, 0xbe, 0xfb, 0xa4, 0x96, 0xac, 0x38, 0x4c, 0xa6,
- 0x52, 0x35, 0xaa, 0xea, 0xba, 0xef, 0xde, 0x77, 0x7f, 0xce, 0x3d, 0xf7,
- 0xdc, 0x73, 0xbe, 0x73, 0xee, 0x7d, 0xba, 0x55, 0xa4, 0x59, 0xf4, 0xdf,
- 0x56, 0xfc, 0x06, 0x7e, 0xff, 0x0f, 0xf6, 0xdd, 0x78, 0xbd, 0x7b, 0x3d,
- 0xf3, 0x46, 0x54, 0x22, 0x4c, 0xc3, 0xf8, 0xc5, 0xf1, 0xdb, 0xa9, 0x9f,
- 0x37, 0xfb, 0x33, 0xf1, 0xbb, 0x29, 0x24, 0x32, 0xf1, 0x23, 0x91, 0xd0,
- 0x86, 0x77, 0xb1, 0x4d, 0xea, 0x7b, 0xde, 0x2f, 0xe9, 0x48, 0xff, 0x19,
- 0xf8, 0x59, 0x57, 0xae, 0xb2, 0x3a, 0xee, 0xaf, 0xfb, 0x17, 0xd6, 0xcd,
- 0xb7, 0xea, 0x9f, 0xc4, 0x8c, 0xf4, 0xc5, 0xdf, 0xce, 0x3a, 0x12, 0x0b,
- 0xa7, 0xbf, 0x3b, 0xba, 0xcf, 0x11, 0xc9, 0x54, 0xfb, 0xac, 0x9c, 0xfc,
- 0xc2, 0x2b, 0xc4, 0x23, 0xc2, 0xf2, 0xf7, 0xa4, 0x7f, 0x7e, 0xe8, 0x1b,
- 0x37, 0xdb, 0x6f, 0x95, 0xc3, 0x12, 0x33, 0xd3, 0x6f, 0x8b, 0xd9, 0x23,
- 0xb1, 0x4e, 0xb4, 0x79, 0xb2, 0xf7, 0x29, 0x43, 0x5a, 0x83, 0xbe, 0xcc,
- 0x89, 0x70, 0x5a, 0xc6, 0x26, 0x67, 0x0e, 0x79, 0x86, 0x23, 0x85, 0x6b,
- 0xd2, 0x8e, 0x55, 0x94, 0x96, 0xc1, 0xe9, 0x81, 0x9b, 0x05, 0xf9, 0xb1,
- 0xc9, 0x6a, 0x4c, 0xb2, 0xb5, 0x42, 0x8b, 0xe1, 0x38, 0x48, 0x63, 0x85,
- 0x77, 0xa7, 0x25, 0xd6, 0x90, 0x9e, 0x6f, 0x7c, 0xc9, 0xe1, 0xf8, 0x89,
- 0xd1, 0xac, 0xf3, 0x6e, 0x89, 0x38, 0x9e, 0x37, 0x8d, 0xf1, 0x77, 0x55,
- 0x7f, 0xe1, 0x3d, 0x1a, 0xf1, 0xc7, 0x36, 0xd2, 0x07, 0xc3, 0x4c, 0x43,
- 0x69, 0x6b, 0xb4, 0xab, 0xaa, 0xf2, 0x0d, 0x7e, 0xde, 0xd1, 0xf9, 0x58,
- 0xb3, 0x4f, 0xbb, 0x34, 0x81, 0xf6, 0x58, 0x24, 0x9d, 0x6e, 0x42, 0x1f,
- 0xb1, 0x68, 0xfa, 0x99, 0xdf, 0x5a, 0x56, 0xf5, 0xee, 0xd7, 0xf5, 0xee,
- 0x8f, 0xfa, 0xed, 0x26, 0x47, 0x7b, 0xaa, 0x4c, 0x1f, 0x1a, 0xed, 0x56,
- 0xe9, 0xc3, 0xa3, 0x49, 0x95, 0x16, 0x54, 0xbd, 0x50, 0x7a, 0x7a, 0xd4,
- 0x51, 0x69, 0xa7, 0x2e, 0x4f, 0x8d, 0x5a, 0x2a, 0xed, 0xd7, 0xa9, 0xab,
- 0xd3, 0x01, 0x9d, 0x0e, 0xea, 0x34, 0xad, 0xd3, 0x8c, 0x4e, 0x87, 0x74,
- 0x3f, 0x23, 0x3a, 0xbf, 0x5b, 0xa7, 0x63, 0x3a, 0x1d, 0xd7, 0xe9, 0x1e,
- 0x9d, 0xee, 0xd5, 0x74, 0x4d, 0xe8, 0xf4, 0x41, 0x5d, 0x7e, 0x40, 0xd3,
- 0x79, 0x10, 0xf4, 0x7c, 0xa6, 0x51, 0xcb, 0x2d, 0xe6, 0x6b, 0xc9, 0xbe,
- 0x99, 0x98, 0x14, 0x4b, 0x61, 0xc9, 0xa9, 0xf5, 0xfc, 0x7c, 0x54, 0x9a,
- 0x63, 0x32, 0x55, 0x8b, 0xc9, 0x45, 0x25, 0xae, 0x3f, 0xf4, 0xbe, 0xd1,
- 0x6b, 0xca, 0x33, 0xb5, 0xb8, 0xbc, 0x50, 0x93, 0xd0, 0x58, 0x6f, 0x93,
- 0x18, 0x73, 0xd7, 0x48, 0xc6, 0x0c, 0x49, 0x58, 0xf1, 0xd5, 0x92, 0xec,
- 0x4c, 0x07, 0xf2, 0x76, 0x42, 0xe4, 0xe5, 0xa8, 0xbf, 0x8e, 0x31, 0x09,
- 0x2f, 0x70, 0x5d, 0x16, 0x46, 0x5f, 0x9a, 0x4f, 0x48, 0xe4, 0x98, 0x85,
- 0xfe, 0x5b, 0x24, 0xba, 0x20, 0x9d, 0x61, 0xe9, 0x4e, 0xdc, 0x87, 0x1a,
- 0x43, 0xd5, 0x88, 0x0c, 0x57, 0x43, 0x58, 0xab, 0x18, 0xe4, 0xa4, 0x05,
- 0x3f, 0x13, 0xbf, 0x38, 0x7e, 0x09, 0xfc, 0x3c, 0xf4, 0xd3, 0x29, 0xb9,
- 0x2a, 0xfb, 0xc4, 0xb8, 0x25, 0x8c, 0x5f, 0xb2, 0xcd, 0x09, 0x21, 0x4d,
- 0x09, 0xf9, 0x46, 0xaf, 0x4f, 0xd3, 0x0b, 0xb5, 0x58, 0x28, 0x7b, 0x52,
- 0x0e, 0xe4, 0x5c, 0xb1, 0x0c, 0xa7, 0x59, 0xf2, 0x66, 0xc8, 0x9a, 0x4c,
- 0xb5, 0x4b, 0x61, 0x1c, 0xef, 0x4a, 0x92, 0x31, 0xd0, 0x77, 0xde, 0x94,
- 0x09, 0xff, 0x1d, 0xcb, 0xfe, 0x1e, 0xfb, 0xd5, 0x36, 0x29, 0xb8, 0x2f,
- 0x94, 0xfe, 0x02, 0xcf, 0xec, 0xeb, 0xcd, 0x88, 0x4f, 0xf3, 0xdb, 0xc8,
- 0xb3, 0xfc, 0x67, 0xdb, 0xfc, 0x3c, 0x9f, 0x59, 0x37, 0x18, 0x33, 0x98,
- 0x2b, 0xc7, 0xee, 0xc5, 0x7c, 0x39, 0xfe, 0xea, 0x7c, 0x41, 0x47, 0x4b,
- 0x28, 0x77, 0xd2, 0x92, 0xc3, 0xa5, 0x5b, 0x25, 0xeb, 0x7a, 0xde, 0x3e,
- 0x57, 0xe2, 0x86, 0x74, 0x9b, 0x39, 0xbc, 0xad, 0x54, 0x25, 0x94, 0x2d,
- 0x05, 0xfc, 0x60, 0xbf, 0x11, 0x94, 0x75, 0xa0, 0x7e, 0x6b, 0x68, 0xe8,
- 0x24, 0x68, 0x4f, 0x93, 0x2f, 0x90, 0x59, 0xb7, 0x3b, 0x31, 0x89, 0xf1,
- 0x16, 0xab, 0xdd, 0xee, 0x79, 0x31, 0xd1, 0x67, 0x3b, 0xea, 0x90, 0x47,
- 0xec, 0x8b, 0x7d, 0xb2, 0xbf, 0x16, 0xb4, 0x8d, 0xe3, 0x1d, 0x69, 0xf2,
- 0xbc, 0xac, 0x6b, 0x32, 0x2f, 0x65, 0xf0, 0xad, 0x4c, 0xbe, 0x35, 0x77,
- 0xca, 0xa9, 0x2a, 0xc7, 0xd8, 0x8c, 0xee, 0xeb, 0xfe, 0x99, 0xd1, 0x9d,
- 0x40, 0xff, 0x71, 0xa4, 0x5b, 0x42, 0xd9, 0xe3, 0x1e, 0xc6, 0x4f, 0xe0,
- 0x79, 0xb3, 0x39, 0x5c, 0xd4, 0x32, 0x98, 0x00, 0xed, 0x71, 0x39, 0xa7,
- 0xe4, 0x70, 0x8b, 0x84, 0x21, 0x87, 0x5c, 0xe3, 0xb6, 0x85, 0x1b, 0x25,
- 0x1f, 0xb7, 0x2d, 0xea, 0xce, 0xae, 0x9d, 0x4d, 0x98, 0xa3, 0xd6, 0x82,
- 0xc7, 0xe2, 0x90, 0xc3, 0xf3, 0x6d, 0x06, 0x4a, 0x0c, 0xb1, 0xcd, 0x7f,
- 0x25, 0x05, 0xc9, 0x2d, 0x7d, 0x2a, 0x24, 0xcd, 0x06, 0xea, 0x5d, 0x1b,
- 0xf2, 0x79, 0x40, 0xfe, 0x64, 0xc0, 0x9f, 0x90, 0xf8, 0xfb, 0x3a, 0x23,
- 0x5d, 0x55, 0xbe, 0xef, 0xb3, 0x0c, 0xf5, 0x6e, 0x08, 0xef, 0x22, 0x92,
- 0xdc, 0x19, 0xbc, 0x1f, 0xc2, 0xfb, 0x6b, 0x64, 0xc2, 0x04, 0x2d, 0xa5,
- 0xe7, 0x8d, 0x2c, 0x68, 0xbc, 0x3d, 0xa2, 0xe6, 0x8a, 0xba, 0x13, 0x75,
- 0xfd, 0x4c, 0xa0, 0xde, 0x1f, 0x63, 0x2c, 0xd0, 0x5b, 0xb2, 0x40, 0x4b,
- 0x07, 0x68, 0x21, 0x8d, 0x05, 0x23, 0x5b, 0x8b, 0x20, 0x3f, 0x6d, 0xe4,
- 0x4e, 0x1f, 0xc1, 0xb3, 0x98, 0x46, 0xfa, 0x79, 0xa6, 0x68, 0xbf, 0xb7,
- 0xae, 0xfd, 0x5e, 0xb4, 0xe7, 0x18, 0x6c, 0xef, 0xcb, 0x7f, 0x41, 0xc9,
- 0xa2, 0x75, 0x05, 0x7e, 0x84, 0x7f, 0x0d, 0x7e, 0x7c, 0x4d, 0xf3, 0xe3,
- 0x67, 0xf2, 0x9b, 0xe7, 0xc7, 0x7f, 0xff, 0x0d, 0xf1, 0x43, 0x24, 0x7f,
- 0x9c, 0xcf, 0x11, 0x29, 0x28, 0xbd, 0xc5, 0x7d, 0x4b, 0x79, 0xa7, 0xce,
- 0x22, 0x9f, 0x28, 0xc7, 0xd8, 0x03, 0xb5, 0x08, 0xd2, 0xa7, 0x90, 0x6e,
- 0x09, 0x8d, 0x1d, 0xbf, 0x84, 0xf5, 0xf7, 0xc4, 0xdc, 0x19, 0xd8, 0x8d,
- 0x42, 0xc2, 0x94, 0x4e, 0x31, 0xaf, 0x87, 0xd1, 0xee, 0xb0, 0xcd, 0xbc,
- 0xbc, 0x89, 0xf7, 0xbf, 0x08, 0x05, 0xf6, 0x3d, 0x3b, 0xd3, 0xf4, 0x76,
- 0x46, 0x3d, 0x45, 0xc9, 0xcf, 0x8c, 0x91, 0x8e, 0x84, 0x72, 0x25, 0x6b,
- 0xc2, 0x48, 0xc7, 0xa1, 0xa7, 0x98, 0x1f, 0x0c, 0xf9, 0x34, 0x0f, 0xa0,
- 0x6e, 0xa0, 0xb3, 0x02, 0xda, 0x07, 0x40, 0xfb, 0x46, 0xdd, 0x95, 0x01,
- 0x2d, 0xa4, 0x81, 0x74, 0x55, 0xc2, 0x9a, 0xf7, 0xe8, 0xe7, 0xa0, 0xea,
- 0x27, 0x9c, 0x1e, 0x14, 0xda, 0xd0, 0xfc, 0x0c, 0xf7, 0x01, 0xdb, 0xb1,
- 0x2f, 0x5f, 0x27, 0xe7, 0xab, 0x41, 0x1f, 0x85, 0xba, 0x3e, 0x0a, 0xa0,
- 0x47, 0xb6, 0x19, 0x4e, 0x14, 0x6b, 0xcf, 0xae, 0x8e, 0xe0, 0xdd, 0x93,
- 0x92, 0x3d, 0x7d, 0xb3, 0x81, 0x39, 0xa0, 0x5f, 0xf2, 0x68, 0x0c, 0x3a,
- 0x9b, 0xfb, 0x2c, 0x26, 0xb9, 0x38, 0xcb, 0x3e, 0xa6, 0xc7, 0x8d, 0x48,
- 0x46, 0xe5, 0x5f, 0x69, 0x5d, 0xa3, 0xe3, 0x79, 0x3d, 0x9f, 0x34, 0xe6,
- 0x43, 0x1a, 0x82, 0xb9, 0xa4, 0xeb, 0xe6, 0x12, 0xf0, 0x9a, 0xbc, 0x30,
- 0xa1, 0xe3, 0x63, 0xda, 0x86, 0xb0, 0xdd, 0x74, 0xdd, 0xda, 0x4d, 0xa3,
- 0x0d, 0x79, 0x8f, 0x3a, 0x1b, 0xec, 0x0a, 0x6d, 0xca, 0x10, 0xfa, 0x29,
- 0xce, 0x1b, 0x92, 0x73, 0x61, 0xab, 0xdd, 0x77, 0x6b, 0x79, 0x5d, 0x93,
- 0xa5, 0xe8, 0xa6, 0xb2, 0x74, 0xc8, 0xf0, 0xf5, 0x35, 0x6c, 0x0b, 0xec,
- 0xcf, 0xd4, 0xbc, 0x9d, 0x0a, 0x64, 0xa9, 0x38, 0xf3, 0x4e, 0x64, 0x29,
- 0x68, 0x1f, 0x83, 0xec, 0x06, 0x63, 0x6c, 0xa4, 0x39, 0xa8, 0x03, 0x1a,
- 0x4b, 0x59, 0x8d, 0x51, 0x38, 0x8e, 0x6f, 0x1b, 0xca, 0xeb, 0x6c, 0xc3,
- 0x11, 0xb4, 0x95, 0x50, 0xae, 0xb7, 0x45, 0xf6, 0xcf, 0x07, 0x7d, 0x1c,
- 0x51, 0x32, 0x3b, 0x39, 0x63, 0x9b, 0xc3, 0x61, 0xc9, 0x0c, 0xcf, 0x0e,
- 0xca, 0x50, 0xad, 0x13, 0x6b, 0xfa, 0xb6, 0x07, 0xdb, 0x79, 0x7d, 0x54,
- 0x1c, 0xe8, 0x45, 0xcc, 0x79, 0x00, 0x3c, 0xae, 0x45, 0xc5, 0x48, 0xbb,
- 0x48, 0xeb, 0x31, 0x56, 0x24, 0x32, 0xbc, 0x2e, 0xdf, 0x80, 0x3a, 0xe8,
- 0x7b, 0x60, 0x63, 0x3d, 0xc8, 0x27, 0x78, 0x9b, 0x75, 0x7f, 0xe1, 0xc1,
- 0x0e, 0x6b, 0x9b, 0xc5, 0x52, 0xea, 0x89, 0x40, 0x47, 0x7c, 0x14, 0xfb,
- 0x5b, 0xed, 0x85, 0x82, 0x91, 0x3e, 0x80, 0x3e, 0x44, 0xc9, 0x69, 0xb1,
- 0xf6, 0x4c, 0xb0, 0xef, 0x55, 0xf9, 0xae, 0x01, 0xca, 0x5e, 0x19, 0x98,
- 0x80, 0x73, 0x5a, 0x52, 0x7b, 0x3d, 0x67, 0xc6, 0x65, 0xba, 0xc4, 0xf9,
- 0x2c, 0x49, 0xb2, 0xfa, 0xa7, 0x92, 0x3b, 0x2d, 0xf2, 0xad, 0x19, 0xd6,
- 0xfb, 0xba, 0xae, 0xf7, 0x3c, 0xea, 0x25, 0xad, 0xa1, 0x90, 0x0d, 0x3b,
- 0x60, 0x63, 0x9b, 0xf4, 0x59, 0x48, 0xcd, 0x11, 0xfc, 0x86, 0x68, 0x64,
- 0x50, 0xcf, 0xc7, 0x40, 0xcf, 0x83, 0x1f, 0x22, 0x77, 0x95, 0x1a, 0xa1,
- 0x4f, 0xfe, 0x27, 0x68, 0x8d, 0xcb, 0xe3, 0x98, 0xc7, 0x4b, 0x33, 0xc4,
- 0x59, 0x5f, 0x97, 0xe5, 0x19, 0xe2, 0xae, 0xe7, 0x65, 0x7a, 0x26, 0xe9,
- 0x7e, 0x0b, 0x7c, 0x3e, 0x25, 0x9c, 0x4b, 0x9f, 0x8b, 0x14, 0x18, 0xd0,
- 0xb6, 0x1e, 0x83, 0x3e, 0xeb, 0xdd, 0xe9, 0xf7, 0xd7, 0xad, 0xfb, 0x73,
- 0xaa, 0xb6, 0x5c, 0x34, 0xa9, 0x9f, 0x2e, 0xdf, 0xe3, 0x59, 0xbd, 0xc7,
- 0xc7, 0xdc, 0x4e, 0x31, 0xb0, 0xaf, 0x33, 0xe3, 0x05, 0x58, 0x3f, 0xee,
- 0xeb, 0xff, 0x6b, 0xac, 0xe1, 0x9f, 0x04, 0xb0, 0xaa, 0xad, 0xec, 0xdd,
- 0x3f, 0x6e, 0x8f, 0xd7, 0xef, 0x6d, 0x8e, 0xdf, 0x8a, 0x36, 0x11, 0xa4,
- 0x57, 0xde, 0xd7, 0xe8, 0xa3, 0xae, 0xed, 0x20, 0xf7, 0x05, 0xda, 0xfc,
- 0x09, 0x78, 0x41, 0xfe, 0xbf, 0x93, 0xfd, 0xdc, 0x17, 0x7e, 0x47, 0xfb,
- 0x79, 0xfc, 0x4a, 0xfb, 0xb9, 0x7e, 0x2f, 0x9f, 0x25, 0x2f, 0x30, 0xb6,
- 0xcc, 0xfa, 0xb2, 0xd5, 0x0d, 0x5e, 0x5b, 0x90, 0x53, 0xd0, 0x50, 0xfa,
- 0x07, 0x2f, 0x13, 0xf1, 0xf1, 0x9c, 0x2f, 0x4f, 0xac, 0x17, 0xd4, 0xf1,
- 0x75, 0xef, 0x50, 0xed, 0xa2, 0xd2, 0xb3, 0xe7, 0x94, 0x9e, 0xb5, 0x8f,
- 0x14, 0x84, 0xf2, 0x76, 0x43, 0x98, 0x7c, 0x7f, 0xc6, 0xfd, 0x2c, 0x68,
- 0xb4, 0x2d, 0xcb, 0xe8, 0x2e, 0x18, 0xc6, 0x67, 0xe5, 0xc0, 0xe2, 0x43,
- 0x72, 0xa0, 0xc4, 0x3e, 0xd2, 0x78, 0xef, 0xa0, 0xac, 0x09, 0xba, 0x96,
- 0x3a, 0xfd, 0xed, 0x90, 0x3f, 0x96, 0x01, 0xfb, 0xb5, 0x12, 0xba, 0xab,
- 0x76, 0x21, 0x94, 0x5d, 0xe4, 0xde, 0x45, 0x79, 0xad, 0x5e, 0xe7, 0x07,
- 0xfa, 0xbe, 0x5e, 0xb7, 0x17, 0x42, 0x63, 0xa5, 0x69, 0xe2, 0x40, 0x23,
- 0xeb, 0x46, 0xb5, 0xee, 0xf8, 0x9a, 0x29, 0xad, 0xb0, 0x2d, 0xc6, 0x3c,
- 0x78, 0x45, 0x9c, 0x4a, 0xde, 0xa5, 0x24, 0x13, 0x21, 0x9e, 0xe4, 0xb3,
- 0x78, 0xe1, 0x34, 0xf7, 0x9e, 0x44, 0xc2, 0xe9, 0x2e, 0xf0, 0x8e, 0x75,
- 0x6e, 0x05, 0xad, 0xb0, 0x7b, 0xee, 0xfb, 0x84, 0x72, 0xf9, 0x42, 0xe9,
- 0x36, 0xe4, 0x23, 0x9a, 0xbf, 0x51, 0xd4, 0x61, 0x7f, 0x3f, 0x6d, 0x90,
- 0xd6, 0xe3, 0xd0, 0x15, 0x41, 0xbf, 0xac, 0x93, 0xd0, 0x75, 0x5a, 0x74,
- 0x9d, 0x5b, 0xf0, 0x7e, 0x0e, 0xf5, 0x6c, 0x57, 0x84, 0x7c, 0x60, 0x59,
- 0x3b, 0xe6, 0x85, 0xba, 0x8b, 0xe9, 0xf0, 0x7a, 0xba, 0x6e, 0xaa, 0xab,
- 0xcb, 0xfc, 0x66, 0x58, 0x97, 0xf2, 0x24, 0x5a, 0x97, 0xb1, 0x6c, 0x10,
- 0xcf, 0x5d, 0x32, 0xb1, 0x98, 0x81, 0x4e, 0xba, 0x5d, 0xf5, 0x13, 0x75,
- 0xd6, 0xd9, 0x3a, 0xd0, 0x64, 0x69, 0x9a, 0xb6, 0x04, 0xfa, 0x18, 0x65,
- 0xae, 0x2e, 0x6b, 0xa8, 0x2b, 0x0b, 0xe4, 0xe7, 0x5f, 0x83, 0x76, 0x8e,
- 0x3d, 0xa2, 0x71, 0x98, 0xe7, 0xe5, 0x28, 0x77, 0xfd, 0xff, 0x52, 0xf3,
- 0xa2, 0x60, 0x86, 0xd5, 0x5e, 0xa9, 0xfe, 0xf6, 0xda, 0x5e, 0x01, 0x6e,
- 0x57, 0xbd, 0x70, 0x8e, 0xa4, 0xa5, 0x05, 0x6b, 0x3b, 0x04, 0x5a, 0xb1,
- 0x86, 0x1d, 0x21, 0xcc, 0xb7, 0x45, 0xf2, 0xb5, 0xb4, 0x7e, 0xc7, 0xf2,
- 0x88, 0x8c, 0xc5, 0x83, 0xf9, 0x7d, 0xc0, 0xf4, 0xb1, 0x37, 0xea, 0x94,
- 0xb6, 0x44, 0xfc, 0xbd, 0x68, 0x4a, 0xfe, 0xe4, 0x10, 0x64, 0x9e, 0xd8,
- 0xb0, 0x01, 0x32, 0x1f, 0x57, 0x36, 0xc7, 0x70, 0x58, 0x1f, 0xef, 0x4e,
- 0xff, 0xbb, 0xb0, 0xdf, 0x86, 0xf5, 0x82, 0x36, 0xc1, 0xd8, 0xed, 0xab,
- 0x6d, 0xc7, 0x5c, 0x43, 0xc2, 0x6a, 0x7c, 0x94, 0x9d, 0x5e, 0x3f, 0xbe,
- 0xd1, 0x11, 0x8c, 0xff, 0xa7, 0xba, 0xaf, 0xf6, 0xba, 0xbe, 0xe2, 0x57,
- 0x18, 0x1f, 0xef, 0x4e, 0xff, 0xee, 0x76, 0xbf, 0x4d, 0xbc, 0xae, 0x4d,
- 0xc7, 0x86, 0x36, 0xac, 0x1f, 0x8c, 0x81, 0x77, 0xa7, 0xef, 0x6b, 0xf1,
- 0xdb, 0xb0, 0x5e, 0x03, 0x6c, 0x2c, 0xdf, 0x71, 0x0f, 0x1e, 0xa8, 0xdb,
- 0x83, 0x07, 0xb0, 0x07, 0x03, 0xd9, 0xde, 0x88, 0xd7, 0x03, 0xbf, 0x8b,
- 0xfe, 0x16, 0x31, 0xde, 0x9a, 0x7f, 0x15, 0x59, 0x68, 0x01, 0x7e, 0x6a,
- 0xa5, 0x4f, 0xa5, 0xf1, 0x39, 0x7d, 0x2c, 0xe2, 0x71, 0x71, 0x22, 0xd2,
- 0x0d, 0x5d, 0xd9, 0x9d, 0xd8, 0xcf, 0x8d, 0x5f, 0x8d, 0x2b, 0xdc, 0x9e,
- 0xd1, 0x63, 0xd0, 0xbf, 0x22, 0xdf, 0x99, 0xcf, 0xad, 0xfa, 0x5b, 0x9d,
- 0xf0, 0xc7, 0x88, 0xbb, 0x89, 0xdb, 0x02, 0xfa, 0x03, 0x7a, 0x0e, 0x1a,
- 0x6b, 0x7b, 0x33, 0x63, 0x0c, 0xd5, 0x86, 0x0c, 0x7f, 0x6f, 0xf2, 0xfd,
- 0x41, 0x6d, 0x5b, 0x37, 0xd2, 0xfb, 0x9e, 0x0d, 0xf4, 0x12, 0xdf, 0x59,
- 0x32, 0x05, 0x19, 0x89, 0x2c, 0x50, 0xd7, 0x2f, 0x8c, 0x2e, 0xcf, 0x13,
- 0xc7, 0xf4, 0x83, 0x2f, 0xa4, 0x97, 0xfc, 0xa3, 0x4e, 0x69, 0x85, 0x9e,
- 0xea, 0x4e, 0x55, 0x50, 0x9f, 0x7e, 0xfe, 0x84, 0xf2, 0x0f, 0x5b, 0x90,
- 0xc2, 0x89, 0x03, 0xad, 0x13, 0xa0, 0x75, 0x42, 0xfb, 0x86, 0xfb, 0x61,
- 0x47, 0x22, 0xc7, 0x02, 0x5a, 0x6f, 0x89, 0x04, 0x6b, 0xb3, 0x9e, 0xf6,
- 0x7a, 0xfb, 0xe7, 0xe3, 0xc0, 0xbb, 0x7a, 0xd5, 0x9e, 0x2c, 0x10, 0x3b,
- 0x4e, 0x9c, 0x0e, 0xf6, 0xa3, 0xf8, 0x7b, 0xa9, 0x35, 0xc0, 0x01, 0x9c,
- 0x0f, 0x71, 0x08, 0x75, 0x4f, 0x30, 0x87, 0x16, 0xe9, 0x5a, 0xe0, 0x1c,
- 0x56, 0xe9, 0x8f, 0x33, 0xca, 0x72, 0x00, 0xfa, 0x3b, 0xaf, 0x68, 0xdd,
- 0x2d, 0x93, 0xa5, 0xf7, 0x69, 0xfa, 0x5b, 0x40, 0xff, 0x18, 0x64, 0x7b,
- 0x4d, 0x77, 0xe5, 0xab, 0xe3, 0xc8, 0xfb, 0x98, 0x90, 0x3c, 0xce, 0x57,
- 0xa9, 0xc7, 0xf4, 0x7c, 0x9a, 0x39, 0x9f, 0x8d, 0x3a, 0x6e, 0x33, 0xbe,
- 0xbe, 0x77, 0x03, 0x5f, 0x45, 0xf3, 0x35, 0x26, 0x0d, 0x0b, 0xca, 0xbf,
- 0x46, 0xbf, 0xe4, 0x35, 0xed, 0xe8, 0xc2, 0xe8, 0xf4, 0xbc, 0xf4, 0x33,
- 0x08, 0x95, 0x07, 0xdf, 0x50, 0x36, 0xd0, 0x20, 0xdd, 0xee, 0x05, 0xcc,
- 0x3b, 0x8f, 0xf5, 0x36, 0x8e, 0xf9, 0xf2, 0x4d, 0xfe, 0xe6, 0xab, 0xcd,
- 0xf0, 0xe9, 0x39, 0x36, 0x79, 0x46, 0xfa, 0x4d, 0x45, 0xcf, 0x2a, 0xbf,
- 0x41, 0xdf, 0x7d, 0xd5, 0x8d, 0xbc, 0xad, 0xd7, 0x33, 0x41, 0xec, 0xe0,
- 0x35, 0xd3, 0xdf, 0x17, 0x9b, 0xc5, 0x0e, 0x5a, 0xa0, 0xa3, 0x23, 0x8c,
- 0x13, 0x80, 0xf7, 0x8c, 0xf3, 0x5c, 0x8a, 0xd0, 0x17, 0x78, 0xa1, 0x04,
- 0x3d, 0x73, 0x9c, 0xd8, 0xa5, 0x55, 0xef, 0x8f, 0x1b, 0xb4, 0x0d, 0x8b,
- 0x2a, 0xdb, 0x21, 0x86, 0x49, 0x7c, 0x84, 0x32, 0xe4, 0x17, 0x99, 0x0f,
- 0xe8, 0xb8, 0x7b, 0x4f, 0xd4, 0x79, 0x21, 0x12, 0xe8, 0x84, 0x35, 0xba,
- 0xea, 0x63, 0x03, 0x1e, 0x30, 0xe5, 0xfb, 0x20, 0xb7, 0xb7, 0xc3, 0xff,
- 0xb7, 0x24, 0x9f, 0xe2, 0x3e, 0x1a, 0x54, 0x3e, 0x92, 0xe1, 0xec, 0x47,
- 0x59, 0x13, 0xca, 0x60, 0x4c, 0x4d, 0xcc, 0xdf, 0xf9, 0x3d, 0x99, 0x80,
- 0x8c, 0xe7, 0x53, 0x7d, 0xa0, 0x83, 0xf8, 0x0e, 0x58, 0xcb, 0x49, 0x31,
- 0x7e, 0x80, 0xbf, 0x7b, 0xa3, 0xfe, 0xbc, 0xf6, 0x20, 0xdf, 0x8c, 0x3a,
- 0x5d, 0xba, 0xce, 0x16, 0x61, 0x1c, 0x2a, 0x6f, 0xb6, 0x22, 0xed, 0xd9,
- 0x50, 0xf7, 0x43, 0xc8, 0xdf, 0xa2, 0xfb, 0x2f, 0xe0, 0xfd, 0x4d, 0xf8,
- 0x0d, 0xa1, 0xec, 0x66, 0x94, 0xb9, 0x28, 0xbb, 0x11, 0xf9, 0x0f, 0xe9,
- 0xb8, 0x44, 0xd0, 0xa6, 0x15, 0xf9, 0x47, 0xf1, 0x1e, 0xba, 0xc2, 0x7c,
- 0x05, 0xef, 0x6f, 0xc1, 0xef, 0xfa, 0x0d, 0x75, 0xda, 0x37, 0xe4, 0x4f,
- 0xae, 0xf2, 0xe0, 0x85, 0xd2, 0x55, 0xfa, 0x99, 0xf2, 0xcc, 0xfc, 0x2b,
- 0x3a, 0x7f, 0xfb, 0x86, 0xf2, 0xfb, 0x83, 0x7c, 0xdd, 0x1a, 0xc2, 0x0e,
- 0x9a, 0x01, 0xd6, 0xbd, 0xda, 0xf4, 0xd7, 0xe0, 0x3d, 0x7e, 0xbc, 0xa0,
- 0x14, 0xb4, 0x23, 0xf6, 0xbd, 0x3d, 0xbc, 0xbe, 0xaf, 0xff, 0xd6, 0xb0,
- 0x96, 0x6f, 0x09, 0x0d, 0x9f, 0x64, 0xd9, 0x4f, 0x1b, 0xd6, 0xd7, 0x79,
- 0x5f, 0xe3, 0x5a, 0x7e, 0x6b, 0x68, 0xf8, 0x38, 0xcb, 0xee, 0x6b, 0x5c,
- 0x5f, 0x67, 0xb8, 0x71, 0x6d, 0x1e, 0x6b, 0xba, 0x30, 0x92, 0xae, 0x50,
- 0x8e, 0xb1, 0x17, 0xaa, 0xa3, 0xd9, 0x19, 0xcf, 0x9b, 0x72, 0x57, 0x12,
- 0x61, 0xa1, 0x0d, 0x22, 0x66, 0x66, 0xf9, 0x53, 0x28, 0x07, 0xa6, 0xaa,
- 0x8d, 0x09, 0x75, 0xd2, 0xe6, 0xd8, 0xd8, 0xd2, 0xd8, 0x58, 0x65, 0x23,
- 0x59, 0x85, 0x65, 0x9f, 0x18, 0x05, 0xf6, 0xd2, 0xcf, 0x4f, 0xe2, 0xd9,
- 0xaa, 0xc7, 0xdf, 0xe8, 0xb7, 0x3c, 0x9a, 0x9d, 0xa7, 0xcd, 0x5b, 0x1a,
- 0xdd, 0x37, 0xcf, 0x3d, 0x7f, 0x0a, 0x7b, 0x3e, 0x24, 0xd3, 0xca, 0xfe,
- 0x91, 0x0e, 0xb6, 0x2b, 0x8f, 0x76, 0x2d, 0x31, 0xad, 0x8c, 0x3a, 0x4b,
- 0x61, 0xd9, 0x1f, 0xf7, 0xdb, 0x32, 0x6f, 0x2d, 0x05, 0x7b, 0xa0, 0x59,
- 0xa2, 0x69, 0xca, 0xa4, 0x9d, 0x82, 0x0f, 0x80, 0xf9, 0x1c, 0x19, 0x9d,
- 0x76, 0x28, 0x9f, 0x9f, 0x82, 0xdd, 0x6f, 0x96, 0x06, 0xa5, 0x6f, 0x1e,
- 0xd7, 0x63, 0x9d, 0xc2, 0x58, 0xdb, 0xd4, 0x7e, 0xca, 0x3a, 0x91, 0x04,
- 0xc6, 0x39, 0x64, 0x38, 0x7d, 0x18, 0x8f, 0x1e, 0x7b, 0xa7, 0x4c, 0xd5,
- 0xb8, 0x6f, 0xf6, 0x44, 0xd7, 0xfc, 0xf4, 0x39, 0xb4, 0x0b, 0xfc, 0x43,
- 0x8e, 0x57, 0x01, 0x3e, 0x84, 0x2c, 0xa7, 0x6d, 0x33, 0x1b, 0x86, 0x9d,
- 0x9f, 0x0f, 0xea, 0x90, 0xa6, 0x63, 0xa3, 0xc9, 0xa5, 0x24, 0xfa, 0xea,
- 0xa4, 0x0e, 0x83, 0xee, 0x0a, 0xe3, 0xc7, 0xbe, 0xd9, 0x0e, 0xb6, 0x68,
- 0x90, 0x76, 0x64, 0x0e, 0x76, 0xa4, 0x53, 0x0e, 0x97, 0x54, 0x1f, 0x16,
- 0xfb, 0x28, 0xea, 0xb6, 0x5d, 0x4b, 0x0d, 0xf0, 0xb1, 0x92, 0xe6, 0x8b,
- 0xb2, 0xd6, 0x76, 0x58, 0xfc, 0x76, 0x7e, 0xdf, 0x3f, 0xf1, 0x32, 0xf1,
- 0xfa, 0xbd, 0xdf, 0x2c, 0x61, 0xd0, 0x91, 0x43, 0x1f, 0x1c, 0x7f, 0xad,
- 0xef, 0xa0, 0xbf, 0xa4, 0x79, 0xfe, 0xb2, 0xbe, 0xb6, 0x69, 0xfc, 0x66,
- 0x5b, 0xb9, 0x5f, 0x6b, 0x6c, 0xce, 0xf7, 0x09, 0xc8, 0x83, 0x44, 0x72,
- 0xbd, 0xd0, 0x8b, 0xb5, 0x41, 0x2d, 0x23, 0x4f, 0xa2, 0xac, 0xde, 0xc7,
- 0xf2, 0xe5, 0xab, 0x00, 0x6c, 0x59, 0xc4, 0x3e, 0x0f, 0xa7, 0x33, 0x6d,
- 0x7e, 0xcc, 0xeb, 0x4a, 0x7e, 0x15, 0xe4, 0x06, 0x7d, 0x16, 0x57, 0xdb,
- 0x72, 0x4e, 0x4f, 0x8e, 0xbe, 0x34, 0x93, 0xc0, 0x9c, 0x7c, 0xbb, 0xe0,
- 0xf3, 0x9a, 0x36, 0x27, 0x24, 0xcb, 0x8e, 0x05, 0xff, 0x9d, 0x36, 0xde,
- 0x92, 0x97, 0x9d, 0xc0, 0xfe, 0xd0, 0x16, 0xa1, 0x7e, 0x8d, 0xb4, 0x91,
- 0xf6, 0x39, 0xcc, 0xcd, 0x93, 0x59, 0xd7, 0x97, 0xc1, 0x5e, 0xd8, 0x91,
- 0xff, 0x18, 0xb1, 0x8f, 0xd0, 0xcf, 0xbb, 0x18, 0xa9, 0x9f, 0x4f, 0x80,
- 0x15, 0x9e, 0xd0, 0x31, 0xe8, 0x39, 0x2d, 0x2f, 0x65, 0xc8, 0x4b, 0x9f,
- 0x65, 0x4a, 0x0f, 0x68, 0x47, 0x9d, 0xfe, 0x6e, 0xf8, 0x5b, 0xf4, 0xe5,
- 0x13, 0xa0, 0xc7, 0x84, 0xee, 0xd8, 0xa6, 0x7d, 0x87, 0xb7, 0xa2, 0xb4,
- 0x6d, 0x6d, 0x2a, 0xbe, 0x3d, 0xa7, 0xe4, 0xd9, 0x97, 0xef, 0xb0, 0x7e,
- 0x1f, 0xc8, 0x54, 0x98, 0x90, 0x46, 0xd6, 0xe2, 0xb8, 0xac, 0xbf, 0xa0,
- 0xeb, 0xcf, 0xa3, 0x7e, 0x08, 0x73, 0xf2, 0xbc, 0x49, 0x45, 0xef, 0x02,
- 0xf8, 0x1e, 0x96, 0xe2, 0xaa, 0xcc, 0x2f, 0x40, 0xe6, 0x29, 0xdf, 0x73,
- 0xd8, 0xaf, 0x20, 0xfe, 0x6e, 0xca, 0x7d, 0x45, 0x86, 0x4e, 0xef, 0x6f,
- 0x60, 0xcc, 0xd5, 0x32, 0xe8, 0x03, 0x53, 0x26, 0x3b, 0xe5, 0xb1, 0x52,
- 0xd2, 0x9c, 0xaa, 0x5b, 0xcb, 0x5d, 0xeb, 0xd6, 0x92, 0x32, 0xa0, 0xea,
- 0xa7, 0x58, 0xbf, 0x52, 0x27, 0x03, 0x8b, 0xf3, 0x57, 0x6a, 0x47, 0x19,
- 0x60, 0xbb, 0xcd, 0xfc, 0x05, 0xc6, 0x28, 0x3d, 0x6f, 0xd9, 0x25, 0xfe,
- 0x6f, 0x94, 0x82, 0x92, 0xb1, 0x90, 0x14, 0x5d, 0xee, 0xab, 0xac, 0x15,
- 0x11, 0x1b, 0x58, 0xe9, 0xf7, 0x41, 0x67, 0x26, 0x15, 0x15, 0x3f, 0xa6,
- 0x31, 0x81, 0x35, 0x58, 0x31, 0x3d, 0xef, 0x25, 0x47, 0xa4, 0x02, 0x1f,
- 0x78, 0x19, 0x69, 0xb1, 0x8a, 0x3d, 0xdb, 0x1c, 0x81, 0x0e, 0x08, 0x64,
- 0x3c, 0x26, 0x65, 0xd4, 0x59, 0xc4, 0xbb, 0xc7, 0xaa, 0x81, 0xc4, 0x78,
- 0x9e, 0x01, 0x1e, 0xed, 0x73, 0x7e, 0xea, 0xe5, 0xe3, 0xf5, 0x75, 0x03,
- 0x4c, 0x4c, 0x2c, 0x4b, 0x6c, 0x4a, 0x4c, 0xc9, 0x77, 0xc4, 0x89, 0x87,
- 0x40, 0x0b, 0xf7, 0x6c, 0xab, 0xc4, 0xd2, 0x76, 0x62, 0x44, 0x02, 0xdb,
- 0xff, 0x3a, 0x64, 0xa9, 0xe0, 0x35, 0x3a, 0x9d, 0xf2, 0x1c, 0xe4, 0xe6,
- 0xd9, 0x55, 0x1c, 0x63, 0x41, 0x8e, 0x68, 0x47, 0x3d, 0x39, 0xe7, 0x3a,
- 0xd6, 0xe7, 0x90, 0x7e, 0xc7, 0xfd, 0x00, 0xf9, 0xf6, 0x84, 0x48, 0x3f,
- 0x7c, 0x32, 0xe8, 0xf5, 0xd9, 0x00, 0xdb, 0xb7, 0xd2, 0x37, 0xd4, 0xb2,
- 0x74, 0x11, 0x7d, 0xda, 0xa6, 0x01, 0x50, 0x7b, 0x07, 0xea, 0xf9, 0x7b,
- 0x23, 0x28, 0x3b, 0x84, 0xba, 0xa4, 0x81, 0x7e, 0xfb, 0x77, 0xb1, 0x67,
- 0x3d, 0xef, 0x1e, 0xf7, 0xe5, 0x3a, 0x5d, 0xb3, 0x80, 0xf5, 0x57, 0x72,
- 0x3e, 0xd0, 0x26, 0x8c, 0xf3, 0x4a, 0x7f, 0xbb, 0xf2, 0x2b, 0xf9, 0x0c,
- 0x79, 0x1f, 0x20, 0x16, 0xb2, 0x14, 0xd6, 0x24, 0x6e, 0x78, 0x16, 0xbc,
- 0xff, 0xa4, 0xc2, 0x34, 0xc4, 0x6f, 0xa0, 0xbf, 0x44, 0x4c, 0xe1, 0x63,
- 0x69, 0x1f, 0xd7, 0x11, 0x5b, 0xa4, 0xb8, 0x36, 0x1a, 0x5f, 0xb0, 0x2d,
- 0xeb, 0xb1, 0x6d, 0xfd, 0xfa, 0xb1, 0xce, 0xb6, 0x50, 0xee, 0x38, 0xe5,
- 0x99, 0xf6, 0xb1, 0x4d, 0xf6, 0xa7, 0x1a, 0xc1, 0xf7, 0x76, 0x6d, 0xc7,
- 0x3f, 0x08, 0xcc, 0x06, 0xec, 0x6d, 0xd2, 0x87, 0x0a, 0x78, 0x7d, 0x23,
- 0xca, 0x7e, 0x0e, 0xfe, 0xb3, 0x0c, 0xfe, 0x95, 0xb2, 0x93, 0x0f, 0x61,
- 0x2f, 0x97, 0xb7, 0xf9, 0x31, 0x34, 0xae, 0x43, 0x80, 0x13, 0x02, 0xdc,
- 0x67, 0x6a, 0xbc, 0xcf, 0xb5, 0xf1, 0xe3, 0x6d, 0x86, 0xaa, 0x4b, 0x5f,
- 0xab, 0xde, 0xc7, 0xe5, 0x1e, 0xf6, 0xbc, 0x73, 0x6e, 0x80, 0x23, 0xeb,
- 0xfd, 0xc4, 0xc0, 0x07, 0x8c, 0x89, 0xd5, 0x4e, 0x4c, 0xf1, 0x47, 0x0d,
- 0x6b, 0x58, 0xe6, 0x1f, 0xbc, 0xb0, 0x43, 0x9f, 0x93, 0x38, 0x26, 0xf0,
- 0x07, 0x59, 0x97, 0xd8, 0xe6, 0x51, 0x8c, 0x11, 0x16, 0xab, 0x83, 0xf9,
- 0x1f, 0xeb, 0x36, 0x7c, 0xf6, 0xa4, 0x67, 0x67, 0xbd, 0x3c, 0x0f, 0xfa,
- 0xfe, 0x62, 0x73, 0x10, 0x03, 0xee, 0x54, 0xfa, 0x64, 0x4d, 0x2e, 0x02,
- 0x9a, 0x82, 0x71, 0x7d, 0xff, 0xb4, 0x1d, 0xb4, 0xdd, 0x05, 0x9b, 0xb2,
- 0xb3, 0xdd, 0xae, 0xf3, 0x45, 0xeb, 0x69, 0xaa, 0xc7, 0x57, 0x16, 0xc6,
- 0x68, 0x94, 0x9d, 0x1d, 0xe4, 0x5d, 0xa7, 0xb2, 0x2d, 0x6b, 0xeb, 0x41,
- 0xdb, 0xcf, 0xb1, 0x37, 0x96, 0xdf, 0x52, 0x47, 0xd7, 0x46, 0xcc, 0x47,
- 0x1f, 0xd7, 0xc7, 0x7c, 0x99, 0xb8, 0x27, 0xbb, 0xdc, 0x00, 0xdf, 0xd5,
- 0xd3, 0x41, 0x8c, 0x47, 0x9a, 0xa3, 0x75, 0x3e, 0xf2, 0xef, 0xea, 0x33,
- 0xaa, 0x39, 0x3d, 0x97, 0xc0, 0x97, 0x4e, 0xa2, 0xfe, 0x7f, 0x00, 0xdd,
- 0x7c, 0x26, 0xed, 0x01, 0x1e, 0x4c, 0xfa, 0x6d, 0x9b, 0x37, 0xc3, 0xfd,
- 0xdc, 0x27, 0x01, 0x6f, 0xda, 0xf5, 0xba, 0xd4, 0xfb, 0xe3, 0xea, 0xe7,
- 0xae, 0xd7, 0x1d, 0x37, 0xd6, 0xcd, 0xa9, 0x5f, 0x0a, 0x8b, 0x94, 0x85,
- 0xf7, 0x23, 0x0d, 0xfc, 0xa1, 0x01, 0xd8, 0x8e, 0x0c, 0xfc, 0x1f, 0xfa,
- 0x45, 0x97, 0xf9, 0x44, 0x3c, 0xc3, 0x1c, 0xcf, 0xc3, 0x47, 0x56, 0xb6,
- 0xc3, 0xb7, 0x8b, 0xc8, 0x43, 0x87, 0xd4, 0xee, 0xa6, 0x5c, 0x8d, 0x4f,
- 0x54, 0xdd, 0xf1, 0xc9, 0xea, 0xc0, 0x38, 0x7d, 0x07, 0x5f, 0xce, 0x50,
- 0xbf, 0x2a, 0x13, 0x06, 0xda, 0x65, 0x55, 0x3b, 0x15, 0xcb, 0xd8, 0xa4,
- 0x1f, 0xe1, 0x1e, 0x9c, 0xf0, 0xc7, 0x8a, 0x8d, 0xe7, 0xa0, 0x77, 0x16,
- 0x67, 0x61, 0xd7, 0x1c, 0x3b, 0x43, 0x59, 0xdc, 0xe7, 0xda, 0x23, 0x4a,
- 0xde, 0xe2, 0xf6, 0x18, 0xd7, 0xaf, 0x32, 0xfb, 0x5e, 0xe8, 0x4d, 0x4f,
- 0xee, 0x84, 0xfe, 0x7b, 0x00, 0xf2, 0x29, 0x67, 0xa0, 0xfc, 0xce, 0x40,
- 0x61, 0x9d, 0x89, 0x8b, 0x71, 0xa2, 0x53, 0xa2, 0x47, 0x13, 0x12, 0x39,
- 0x4a, 0xff, 0x2b, 0x69, 0xde, 0x29, 0x02, 0x3b, 0xf8, 0xe2, 0xcd, 0x86,
- 0xd8, 0x83, 0x19, 0x49, 0xc2, 0x87, 0xec, 0x33, 0x2b, 0x48, 0x8b, 0x92,
- 0x4c, 0x9d, 0x46, 0x5f, 0xd1, 0x33, 0xa8, 0x8b, 0x76, 0x4d, 0xcb, 0x16,
- 0x7e, 0x1d, 0xd2, 0xbc, 0xec, 0xef, 0x8f, 0xe6, 0xe5, 0xf5, 0xf1, 0x9b,
- 0xa1, 0xd5, 0xf8, 0x0d, 0xdf, 0xbf, 0xad, 0xe3, 0x4e, 0x5f, 0xd2, 0xbe,
- 0x0c, 0xe5, 0x82, 0xf6, 0x4c, 0xf9, 0x63, 0xd0, 0xdd, 0x5f, 0x82, 0xff,
- 0xeb, 0x48, 0xae, 0x04, 0x9c, 0x9e, 0xf6, 0xe4, 0x69, 0xb7, 0xe0, 0x65,
- 0x07, 0x3c, 0x79, 0xdd, 0x75, 0x0a, 0x79, 0xb1, 0xdf, 0xa6, 0x8e, 0xfb,
- 0xb1, 0xfb, 0x21, 0xd9, 0xd3, 0x66, 0xef, 0xc9, 0x84, 0x0a, 0x5e, 0x8b,
- 0xd3, 0x2c, 0x57, 0xa7, 0x0f, 0xc9, 0xbe, 0x1d, 0x2b, 0x66, 0x58, 0x32,
- 0x57, 0x03, 0x0b, 0x26, 0xf2, 0x4a, 0x3f, 0xbd, 0xa1, 0x7c, 0xea, 0xfb,
- 0xbb, 0x0f, 0xc9, 0xd6, 0x1d, 0xb6, 0x79, 0x29, 0x4c, 0x9c, 0x76, 0x08,
- 0xf8, 0xdf, 0x4e, 0xe4, 0xc2, 0x8e, 0xb9, 0x5b, 0xec, 0x91, 0x4f, 0x0b,
- 0xcf, 0x8c, 0x1d, 0xe9, 0x3a, 0xea, 0x24, 0x1e, 0x0c, 0xf5, 0x1c, 0x78,
- 0x90, 0x3e, 0xdd, 0x19, 0xe6, 0x3d, 0x89, 0xed, 0x30, 0xf1, 0x1c, 0x97,
- 0xae, 0x13, 0x96, 0x24, 0xc1, 0x97, 0x5e, 0xc5, 0x13, 0x9e, 0x5d, 0x25,
- 0xa4, 0xe7, 0x28, 0x71, 0x93, 0xe2, 0x4d, 0x2f, 0x78, 0x93, 0x02, 0x6f,
- 0xe0, 0x47, 0xf5, 0x99, 0x97, 0x90, 0x9e, 0x97, 0xe4, 0xe0, 0x9b, 0xe0,
- 0x4d, 0x2f, 0x78, 0xd3, 0x73, 0xc6, 0x42, 0x7b, 0xf4, 0xb1, 0xdc, 0x85,
- 0xb4, 0x59, 0x3e, 0x72, 0x55, 0x07, 0x9e, 0x1d, 0x49, 0x1e, 0x8d, 0x61,
- 0x8c, 0x90, 0xec, 0xea, 0x2e, 0xc8, 0xf0, 0x0e, 0xf8, 0x63, 0xf1, 0x43,
- 0x72, 0x01, 0xb6, 0xa7, 0x04, 0xbf, 0xe0, 0xe9, 0x41, 0x7b, 0x6c, 0x05,
- 0xfa, 0xb3, 0x76, 0x97, 0x27, 0xaf, 0xec, 0xf8, 0x2b, 0x2f, 0x71, 0x95,
- 0xbd, 0x47, 0x42, 0x03, 0x32, 0x5d, 0x52, 0x36, 0x21, 0x91, 0x0d, 0x2b,
- 0x2c, 0x86, 0x39, 0x16, 0x60, 0x57, 0x78, 0x16, 0xee, 0x40, 0xbf, 0x7f,
- 0x5a, 0x1e, 0x28, 0x4f, 0xe1, 0x07, 0x1f, 0x73, 0x86, 0x75, 0x0f, 0xc0,
- 0x87, 0x7b, 0x48, 0xf6, 0xcf, 0x00, 0x2f, 0xa6, 0x41, 0xf7, 0x80, 0x03,
- 0x1f, 0xee, 0x7c, 0xa3, 0xb4, 0xa2, 0x0c, 0xbc, 0x1d, 0xab, 0x6d, 0xf4,
- 0xdd, 0x56, 0xb0, 0x0e, 0x83, 0xf2, 0x97, 0xb5, 0x01, 0xf9, 0x6a, 0xad,
- 0x5f, 0xbe, 0x0c, 0x7b, 0xf2, 0x6c, 0xad, 0x13, 0x7b, 0x25, 0x81, 0x35,
- 0x49, 0x63, 0x7d, 0x5c, 0xf9, 0x4a, 0x2d, 0x25, 0x5f, 0x02, 0xaf, 0x9e,
- 0xc3, 0x6f, 0xb8, 0x94, 0x92, 0x5d, 0xa5, 0x7e, 0xbd, 0x46, 0x5c, 0x1f,
- 0x07, 0xf4, 0x38, 0x98, 0xbb, 0xfd, 0x54, 0x01, 0xfb, 0x6f, 0xb1, 0xe6,
- 0xbc, 0x55, 0x91, 0xc7, 0x1a, 0x19, 0x5f, 0x3e, 0xb5, 0x6a, 0x53, 0x0a,
- 0x9e, 0xe9, 0xd8, 0x47, 0x26, 0xb0, 0x0e, 0x15, 0xec, 0xd3, 0x31, 0xc5,
- 0xfb, 0x35, 0x7b, 0x53, 0xf1, 0xed, 0x4d, 0x30, 0xbf, 0xd9, 0xbc, 0x7c,
- 0x47, 0xb2, 0x73, 0xd3, 0xb2, 0xef, 0xb8, 0x27, 0xbf, 0xe3, 0x7a, 0x90,
- 0x63, 0xea, 0xdf, 0x01, 0xea, 0x75, 0x6b, 0x22, 0x6c, 0x28, 0xff, 0xc9,
- 0xc7, 0x2a, 0xbd, 0xdb, 0xb1, 0x67, 0x53, 0x19, 0x63, 0x4a, 0x92, 0x73,
- 0x53, 0xd2, 0x35, 0x07, 0x59, 0x70, 0xd9, 0xd7, 0x8a, 0x69, 0x5c, 0x26,
- 0x0f, 0x1c, 0xc7, 0x1e, 0xcc, 0x89, 0x63, 0xbe, 0x25, 0x29, 0x8c, 0x7f,
- 0x50, 0xba, 0xd1, 0xc6, 0x41, 0x9b, 0x4b, 0x6a, 0xec, 0x16, 0x8c, 0xdd,
- 0x28, 0x87, 0xe3, 0x36, 0x64, 0x8d, 0x76, 0xfb, 0xff, 0x48, 0xb6, 0xc2,
- 0xf4, 0x6f, 0x25, 0x7b, 0xea, 0x91, 0x98, 0x34, 0xf3, 0x19, 0xaa, 0x61,
- 0x81, 0xe5, 0x5d, 0x48, 0x59, 0xee, 0xc0, 0x77, 0xfe, 0x89, 0x64, 0xcf,
- 0x72, 0xec, 0xb7, 0x50, 0xfe, 0x8a, 0x64, 0x8f, 0xfd, 0x1c, 0xf9, 0x0b,
- 0x48, 0xdf, 0x46, 0x3a, 0x26, 0x5d, 0xc7, 0x24, 0x94, 0x3d, 0xfb, 0x6d,
- 0xe4, 0x23, 0x48, 0x0f, 0xa3, 0xde, 0x6d, 0xa0, 0xef, 0xaf, 0xd1, 0x5f,
- 0x06, 0x7a, 0xee, 0xc3, 0x9a, 0x7e, 0x96, 0xb3, 0x8c, 0xef, 0x0e, 0x43,
- 0xa7, 0xfd, 0x0f, 0x8f, 0xf1, 0x44, 0xf5, 0xbc, 0xc8, 0x3c, 0x75, 0x1b,
- 0x9f, 0xa7, 0xc0, 0x93, 0x83, 0xc8, 0x7b, 0xf2, 0x90, 0x4b, 0x1b, 0x73,
- 0x93, 0x8c, 0x9b, 0x05, 0xaf, 0x19, 0x58, 0xa2, 0x05, 0xfb, 0x60, 0x6a,
- 0xe7, 0xe6, 0xfb, 0xe0, 0x48, 0xcf, 0x21, 0x69, 0xda, 0x11, 0xcc, 0x3f,
- 0x98, 0xaf, 0x63, 0xfe, 0x48, 0xf1, 0xc1, 0x2e, 0x3c, 0x28, 0x9c, 0x87,
- 0x93, 0x78, 0xdc, 0xe8, 0xd9, 0xf3, 0x00, 0xf6, 0x81, 0x71, 0x96, 0x79,
- 0x7f, 0x1f, 0x18, 0x67, 0xa1, 0x1b, 0x16, 0xe0, 0x17, 0x2e, 0x74, 0x4a,
- 0xe3, 0xb1, 0xb5, 0x7d, 0xd0, 0x70, 0xec, 0x57, 0xef, 0x83, 0xc6, 0xb3,
- 0xa8, 0x77, 0x96, 0x3c, 0x43, 0x1f, 0xa7, 0xc8, 0xb3, 0x0e, 0xa4, 0x9f,
- 0xc6, 0x5c, 0x49, 0x7b, 0x23, 0x68, 0xf7, 0xb1, 0xd0, 0xcd, 0x90, 0xf7,
- 0xfb, 0x77, 0x1c, 0xd4, 0xe5, 0xff, 0xd9, 0x1b, 0x89, 0xdb, 0x65, 0x09,
- 0x91, 0xa7, 0xa8, 0x5b, 0x21, 0x0f, 0x6f, 0x69, 0x92, 0xe6, 0x03, 0xd2,
- 0x45, 0xfe, 0x55, 0x76, 0x23, 0x5f, 0xf0, 0xa2, 0x4e, 0x8b, 0xe6, 0x27,
- 0xb0, 0xd1, 0x00, 0xcb, 0x5f, 0x83, 0xcc, 0x10, 0xa3, 0xbe, 0x21, 0xfb,
- 0x66, 0x3c, 0x19, 0x77, 0x39, 0xff, 0xef, 0x63, 0xfe, 0x99, 0x1d, 0x71,
- 0x59, 0xb1, 0xe2, 0xe0, 0xc9, 0x22, 0x74, 0xfb, 0x05, 0xf1, 0xf9, 0xc0,
- 0x33, 0x89, 0x5d, 0xe2, 0x24, 0x86, 0xc5, 0x49, 0xbd, 0x09, 0x3e, 0x0c,
- 0x43, 0xf6, 0x73, 0x35, 0xca, 0xce, 0xab, 0x32, 0x04, 0x99, 0xf8, 0x9e,
- 0x6b, 0xa7, 0x80, 0x7f, 0xa0, 0x2f, 0x28, 0x17, 0x94, 0x89, 0x56, 0xa5,
- 0x93, 0x16, 0x5c, 0xfb, 0x89, 0x8a, 0x5c, 0x27, 0x0b, 0xed, 0xa4, 0x1d,
- 0xef, 0x8e, 0x29, 0x7b, 0x91, 0x9a, 0x30, 0xba, 0xa1, 0xa3, 0x53, 0x62,
- 0xf6, 0x7c, 0xb1, 0x31, 0xb8, 0xbf, 0x92, 0x9f, 0x0b, 0xc9, 0x54, 0x0f,
- 0xd7, 0x8a, 0xfd, 0x22, 0x5f, 0x29, 0x78, 0x11, 0xe7, 0x2d, 0xef, 0x64,
- 0x87, 0x25, 0x9f, 0xec, 0x59, 0x95, 0xcb, 0xb2, 0x88, 0xbf, 0x2f, 0x86,
- 0xd4, 0x7a, 0x04, 0x74, 0x07, 0x73, 0x09, 0xde, 0xf5, 0xd7, 0xbd, 0xe3,
- 0x5c, 0x28, 0xeb, 0xab, 0x7b, 0xc7, 0xba, 0x9c, 0xd6, 0x9f, 0x41, 0x9e,
- 0xec, 0x27, 0x8a, 0xf2, 0x3a, 0x64, 0x0f, 0x3c, 0x3c, 0xcb, 0x94, 0x3c,
- 0x9c, 0x82, 0xdc, 0xbf, 0x26, 0xbb, 0xe6, 0xb8, 0x67, 0x5e, 0xc3, 0x5c,
- 0x95, 0x2e, 0x81, 0x8e, 0x60, 0x7f, 0x9e, 0x4c, 0xbb, 0xdd, 0xa9, 0x53,
- 0x72, 0x5d, 0x62, 0x12, 0x7e, 0xe6, 0x84, 0xe9, 0xc9, 0xb2, 0x5b, 0x90,
- 0xe5, 0x41, 0xb4, 0xa9, 0x7c, 0x1a, 0xbf, 0x79, 0x3d, 0xb7, 0x47, 0xc0,
- 0x77, 0xdb, 0x2a, 0x1b, 0x9f, 0x01, 0xdf, 0x1f, 0x92, 0xe4, 0xb1, 0x55,
- 0x5d, 0x03, 0xb9, 0xf3, 0x75, 0x4d, 0xf2, 0xac, 0x29, 0x95, 0x92, 0x23,
- 0x1f, 0xa3, 0x0e, 0x29, 0x71, 0x5e, 0xd0, 0x31, 0x3c, 0xdf, 0x2f, 0x41,
- 0xcf, 0x94, 0xa0, 0x53, 0xa0, 0x43, 0xbe, 0x8c, 0xf2, 0x2f, 0xa1, 0xce,
- 0x73, 0xf0, 0x99, 0x9e, 0x05, 0xde, 0x3b, 0x07, 0x1c, 0xf1, 0x4c, 0x29,
- 0xa3, 0xfd, 0x57, 0x35, 0x5f, 0xd8, 0x2c, 0xe5, 0xef, 0x48, 0xa5, 0x4c,
- 0x7e, 0xfc, 0x44, 0xad, 0x6d, 0xd6, 0xdd, 0x46, 0x6c, 0x05, 0xca, 0x44,
- 0xca, 0xe5, 0x80, 0x27, 0xd4, 0x7d, 0x3c, 0x1b, 0x0a, 0x74, 0x65, 0xcb,
- 0x06, 0x5d, 0x29, 0xf2, 0x62, 0xd5, 0xc7, 0x90, 0xc4, 0xc4, 0xc5, 0x19,
- 0x6b, 0xf5, 0x0c, 0xb5, 0x08, 0xbb, 0x79, 0x1e, 0xbe, 0x45, 0x2c, 0xfd,
- 0x2d, 0x89, 0x9d, 0xf0, 0xbc, 0x1f, 0xc0, 0x6e, 0x16, 0xb0, 0x26, 0x46,
- 0x08, 0xe5, 0x4b, 0x7c, 0x47, 0xb9, 0xa7, 0x6c, 0x87, 0x78, 0x96, 0x22,
- 0x2f, 0xa3, 0xac, 0xa2, 0x7c, 0xae, 0x6f, 0x83, 0x1e, 0x4d, 0x9f, 0x2a,
- 0x63, 0xbd, 0x46, 0xc9, 0x8d, 0xa7, 0xe0, 0xd7, 0xf4, 0x99, 0x8d, 0x68,
- 0x5f, 0x5e, 0x62, 0x1b, 0x7b, 0x90, 0x57, 0xb9, 0x5e, 0x5e, 0x62, 0x79,
- 0xa7, 0x5c, 0x80, 0xff, 0x49, 0x1a, 0x2a, 0xf3, 0x69, 0xf1, 0xe3, 0xc5,
- 0xd4, 0x57, 0xa4, 0x15, 0x79, 0xf0, 0x2b, 0x5b, 0xa2, 0x9d, 0x8d, 0x48,
- 0x21, 0x41, 0x5e, 0x27, 0xe4, 0xfc, 0xcc, 0x1f, 0x37, 0x31, 0x1e, 0x9b,
- 0x75, 0xf8, 0x1c, 0xc4, 0x37, 0xcc, 0x77, 0x10, 0xdf, 0x60, 0x4c, 0x23,
- 0x02, 0x5b, 0xa6, 0xe2, 0x1c, 0x48, 0xad, 0x3a, 0x9f, 0x97, 0xef, 0x7d,
- 0x6c, 0xb4, 0x86, 0x19, 0x89, 0x21, 0x39, 0x5f, 0xbb, 0xb0, 0x02, 0xfd,
- 0xd1, 0x9e, 0x7e, 0x49, 0xee, 0x5e, 0xf0, 0xe7, 0x67, 0x9c, 0x12, 0xde,
- 0xe3, 0x91, 0x4b, 0xf3, 0xb6, 0x7b, 0x51, 0x78, 0x06, 0xe2, 0x62, 0xbd,
- 0xfe, 0xa0, 0x09, 0xfa, 0x6b, 0x30, 0x63, 0x7c, 0xbb, 0xc9, 0xc7, 0x67,
- 0x11, 0x99, 0x9a, 0xe1, 0x99, 0x2b, 0x74, 0x1b, 0x70, 0xe3, 0xef, 0x45,
- 0xf0, 0x5c, 0x65, 0x1e, 0x7e, 0xa8, 0xef, 0xc3, 0xe2, 0xd9, 0xef, 0x8f,
- 0x3c, 0x37, 0x16, 0x38, 0xf7, 0x90, 0xdc, 0x0d, 0x74, 0x22, 0xe8, 0xbf,
- 0x4b, 0x8f, 0xd5, 0x75, 0x2a, 0xc5, 0xf8, 0xb5, 0x24, 0xa1, 0x2f, 0xb2,
- 0xf0, 0x1f, 0x73, 0xf1, 0x4e, 0x8d, 0xc7, 0xf9, 0x6e, 0x23, 0xde, 0x0c,
- 0xfc, 0xba, 0x94, 0x7c, 0xbe, 0x14, 0x60, 0xbd, 0x14, 0x6c, 0xac, 0x44,
- 0x46, 0x7a, 0x3d, 0xf9, 0x81, 0x4b, 0x7e, 0xf5, 0x23, 0xef, 0xca, 0x91,
- 0xda, 0x2f, 0x3b, 0x5b, 0xad, 0xff, 0x6b, 0x01, 0x8d, 0xfc, 0x81, 0x3e,
- 0xe0, 0x23, 0xd2, 0x6e, 0xc0, 0x9e, 0x17, 0x81, 0xbb, 0x8c, 0x33, 0x9d,
- 0xea, 0x9d, 0x01, 0x6c, 0x50, 0x99, 0x81, 0x6e, 0x3c, 0xc3, 0xf3, 0x66,
- 0xe8, 0xb6, 0x33, 0x51, 0x29, 0xce, 0x52, 0x2e, 0xa5, 0xdd, 0xc0, 0x7a,
- 0xb1, 0x7e, 0x65, 0xa6, 0x13, 0x69, 0x0b, 0x52, 0x4b, 0xf5, 0x53, 0x99,
- 0x71, 0x54, 0xfb, 0xca, 0x4c, 0x4a, 0xb5, 0xab, 0xcc, 0xf4, 0x23, 0x75,
- 0xa5, 0xe1, 0x0c, 0x9c, 0xa5, 0x33, 0x3d, 0x32, 0x75, 0x12, 0xf6, 0x65,
- 0xc0, 0x50, 0x77, 0x35, 0x26, 0x60, 0x7f, 0x22, 0xf0, 0xac, 0x2e, 0x9a,
- 0x83, 0xc0, 0x58, 0x37, 0x01, 0x83, 0xdc, 0x24, 0xce, 0x09, 0xce, 0x9f,
- 0xba, 0xf7, 0x3c, 0x63, 0x5e, 0x89, 0x4f, 0x48, 0x46, 0xf6, 0xcf, 0x36,
- 0x62, 0xbf, 0x46, 0xcc, 0xa2, 0x74, 0x9b, 0xc3, 0xc8, 0xe7, 0xcb, 0xe4,
- 0xdb, 0xbd, 0xca, 0x5f, 0xcb, 0xba, 0x37, 0x34, 0x4b, 0x73, 0x1a, 0x63,
- 0xbc, 0x93, 0xf6, 0xbd, 0x90, 0x3f, 0x47, 0xf7, 0x91, 0x06, 0x3d, 0xf5,
- 0xfc, 0xe0, 0x39, 0x73, 0xe6, 0x57, 0x9c, 0x33, 0x53, 0xae, 0xc9, 0xdf,
- 0x7b, 0xe5, 0xbc, 0x93, 0x96, 0x97, 0x9d, 0x94, 0x5c, 0x70, 0x76, 0xca,
- 0x37, 0x61, 0xa7, 0x5f, 0x72, 0xce, 0x34, 0x11, 0x0b, 0x54, 0xd4, 0xd9,
- 0x5d, 0xb0, 0x56, 0x8e, 0x8e, 0x9d, 0xff, 0x50, 0x96, 0x67, 0x88, 0x9d,
- 0xbd, 0xdb, 0xf6, 0xb9, 0x05, 0xda, 0x2d, 0xd0, 0x40, 0xac, 0x56, 0x80,
- 0xfd, 0x3b, 0x24, 0xc3, 0x2e, 0xed, 0x9e, 0xb2, 0x51, 0x89, 0x61, 0x7f,
- 0x3f, 0xbb, 0x79, 0xe8, 0xd5, 0xf3, 0xb3, 0xd8, 0x4f, 0x42, 0xf9, 0xc7,
- 0x73, 0x99, 0xeb, 0xee, 0xc8, 0xe3, 0x25, 0xce, 0xb3, 0xb8, 0xbd, 0x59,
- 0xc2, 0x32, 0xa2, 0xf0, 0x42, 0xab, 0xbc, 0xb8, 0xb4, 0x45, 0x0c, 0x58,
- 0x28, 0xe3, 0xda, 0xa8, 0xba, 0xe5, 0x42, 0x9f, 0x5b, 0xda, 0x78, 0xb6,
- 0xf6, 0x87, 0xe0, 0x0d, 0xfd, 0x7f, 0xcc, 0xad, 0x8d, 0x33, 0x09, 0xf2,
- 0xfd, 0xd8, 0x5f, 0x7c, 0x0e, 0x49, 0xce, 0x89, 0xe3, 0x99, 0x29, 0xf7,
- 0x1c, 0x63, 0x63, 0x61, 0xf1, 0x31, 0xf7, 0x21, 0xf5, 0xbe, 0xd1, 0xb9,
- 0x15, 0xb8, 0x8e, 0xf2, 0x8a, 0x74, 0xd9, 0x1f, 0x37, 0x07, 0x1c, 0x97,
- 0xef, 0xe7, 0x1d, 0x1b, 0x3b, 0x55, 0xc0, 0x5e, 0x98, 0x50, 0xf5, 0x07,
- 0xe4, 0xa5, 0x99, 0x52, 0xb3, 0xbf, 0x3f, 0x06, 0xf5, 0x33, 0xdf, 0xd3,
- 0xa7, 0x62, 0x8c, 0xe4, 0x99, 0xd1, 0x69, 0xe7, 0xa2, 0xde, 0x3f, 0x12,
- 0xba, 0xb3, 0x17, 0x38, 0xf4, 0x68, 0x03, 0xe6, 0x62, 0x5b, 0x56, 0xc8,
- 0xe8, 0x30, 0x80, 0xe3, 0x87, 0x95, 0xcd, 0xed, 0x55, 0x31, 0xe8, 0x53,
- 0xa9, 0x56, 0xa9, 0x98, 0x8e, 0xba, 0x93, 0xb7, 0x62, 0xee, 0x20, 0xd6,
- 0xc7, 0xaf, 0x09, 0x65, 0xdd, 0x48, 0x1b, 0x91, 0xbe, 0x5f, 0x8a, 0xc7,
- 0xcf, 0xe8, 0xf1, 0xa2, 0x1b, 0xf2, 0x1f, 0xd1, 0xe9, 0x67, 0xb5, 0x3f,
- 0xc5, 0x71, 0xa2, 0xe2, 0x7c, 0xa1, 0x45, 0xba, 0x8f, 0x9a, 0xc0, 0xb6,
- 0x09, 0x60, 0xdd, 0x4e, 0x49, 0x1d, 0xb5, 0xe4, 0xda, 0xa3, 0x41, 0x9c,
- 0xe9, 0x2b, 0xa3, 0x49, 0x15, 0xd7, 0xfc, 0xf2, 0xa8, 0x53, 0x56, 0xe7,
- 0xed, 0xfa, 0xee, 0xe0, 0x8a, 0xbe, 0x53, 0xf8, 0xca, 0x68, 0xaf, 0x4a,
- 0xbf, 0x3d, 0x9a, 0x52, 0xe9, 0xab, 0xa3, 0xd7, 0x56, 0x7d, 0xff, 0xa8,
- 0xb8, 0x98, 0x92, 0xcf, 0x95, 0x88, 0x2f, 0x07, 0x80, 0x1d, 0x5d, 0xe8,
- 0x99, 0x7e, 0xe8, 0x99, 0x14, 0xf4, 0xcc, 0x20, 0xf5, 0x0c, 0xf4, 0xf6,
- 0xab, 0xd0, 0xdb, 0xae, 0x7c, 0x0f, 0xf2, 0xfa, 0x8c, 0xdb, 0x08, 0x5c,
- 0xe8, 0x79, 0xfe, 0x5c, 0xed, 0x27, 0x56, 0xb0, 0xbe, 0x95, 0xd3, 0x12,
- 0x6b, 0x83, 0x0e, 0xda, 0xb1, 0xd0, 0x20, 0x8b, 0x71, 0xcf, 0x9b, 0x73,
- 0x1d, 0xb9, 0x84, 0xfa, 0x59, 0x87, 0xfb, 0xf8, 0x6f, 0x9a, 0xe9, 0x8f,
- 0x5d, 0x9a, 0xd9, 0x09, 0x9d, 0x44, 0x79, 0x8f, 0x49, 0x65, 0x3c, 0x21,
- 0x4b, 0xf0, 0xcf, 0xd6, 0xea, 0xa4, 0xf0, 0xcc, 0xfd, 0xff, 0x13, 0xd4,
- 0x4d, 0xc1, 0x3e, 0x98, 0xb2, 0xdc, 0x6b, 0xc9, 0xa9, 0x5e, 0x7b, 0xd0,
- 0x32, 0xa8, 0xbb, 0x2c, 0x29, 0xc3, 0xbf, 0xaf, 0x94, 0x58, 0x9f, 0xf5,
- 0xb0, 0x3f, 0x4b, 0x7e, 0xbb, 0xe9, 0x52, 0xa0, 0x27, 0x06, 0x18, 0x7b,
- 0x8c, 0xe4, 0x7a, 0x7d, 0x1b, 0x60, 0x18, 0x8d, 0x90, 0x03, 0x17, 0xfc,
- 0x1f, 0x47, 0xf9, 0x00, 0xef, 0x9a, 0xa0, 0x8c, 0x58, 0x28, 0xb6, 0x85,
- 0x18, 0x31, 0xe7, 0x8e, 0xa3, 0x8c, 0x6d, 0xec, 0x44, 0x12, 0xe5, 0x63,
- 0x92, 0x4c, 0xe4, 0xd5, 0xbd, 0xb7, 0x0e, 0x94, 0xb1, 0x8f, 0xb0, 0x8e,
- 0xc1, 0x74, 0x6c, 0xf1, 0xcf, 0x7d, 0x83, 0xf2, 0x3e, 0x15, 0x0f, 0xc8,
- 0x98, 0x2e, 0xf6, 0x03, 0xcb, 0x92, 0x26, 0xdb, 0xe5, 0x5c, 0x57, 0xe9,
- 0xc2, 0x7b, 0xaa, 0x3c, 0xb7, 0x8b, 0xc9, 0xdd, 0xd5, 0x16, 0xc9, 0x55,
- 0x1b, 0xae, 0xa0, 0xff, 0x83, 0x3d, 0x79, 0x3e, 0x61, 0x0a, 0xef, 0x60,
- 0xf8, 0xfb, 0x3c, 0xb2, 0x93, 0x7b, 0x02, 0x7c, 0x87, 0xfd, 0x7d, 0x0e,
- 0xf3, 0x7d, 0x16, 0xf6, 0xf7, 0x1c, 0xec, 0xef, 0x33, 0xa5, 0x35, 0xfd,
- 0xe1, 0xdb, 0x5d, 0xea, 0x80, 0xa7, 0xb0, 0x66, 0x63, 0xc0, 0xfd, 0xbb,
- 0xe1, 0x0f, 0x8c, 0x00, 0xfb, 0x0f, 0x61, 0xfd, 0xd2, 0x58, 0xbb, 0x71,
- 0xde, 0x55, 0xc2, 0x3a, 0x0e, 0xaa, 0xb3, 0xe5, 0x59, 0x75, 0xdf, 0xe3,
- 0x87, 0xca, 0xf6, 0x3e, 0x56, 0x32, 0x60, 0x1f, 0x0a, 0xde, 0x76, 0xc7,
- 0x06, 0xfe, 0x5b, 0xdd, 0xcf, 0x83, 0x2f, 0x42, 0xaf, 0xfc, 0x1d, 0xe8,
- 0x7a, 0x76, 0x96, 0xf6, 0x1c, 0x75, 0x7c, 0xbc, 0xed, 0x32, 0xbe, 0x85,
- 0xfd, 0x7c, 0xe4, 0xbc, 0xac, 0x00, 0x77, 0x64, 0x28, 0xc7, 0xf0, 0x1f,
- 0xec, 0x67, 0xca, 0xd2, 0x43, 0x1d, 0x58, 0xe6, 0x5e, 0x19, 0x38, 0x96,
- 0x00, 0xd6, 0x03, 0x92, 0x57, 0x67, 0xa9, 0x78, 0x3e, 0xbb, 0x55, 0x0c,
- 0xe2, 0x3d, 0xf7, 0x2a, 0x94, 0x51, 0x6f, 0x04, 0x18, 0x69, 0x65, 0xb0,
- 0x5d, 0x32, 0x3b, 0xda, 0x95, 0xee, 0xb0, 0xdd, 0x97, 0x31, 0xee, 0x2e,
- 0x69, 0x04, 0x86, 0x2b, 0x60, 0x8c, 0x83, 0xf2, 0x37, 0x2e, 0xe3, 0x52,
- 0xbe, 0xef, 0x07, 0x5a, 0x62, 0xe0, 0x59, 0xd3, 0x3e, 0xc7, 0x8c, 0xed,
- 0xaa, 0xb1, 0xff, 0x98, 0xc2, 0x58, 0x39, 0x61, 0xff, 0xb0, 0x13, 0x18,
- 0x33, 0x79, 0x8c, 0xb2, 0xdf, 0x87, 0x75, 0xfb, 0x2d, 0x60, 0x20, 0x72,
- 0xf5, 0x5b, 0x5b, 0xfc, 0xfd, 0x42, 0xfa, 0x57, 0x88, 0x27, 0x18, 0xf7,
- 0xf7, 0xfd, 0xf2, 0x55, 0xda, 0x06, 0x40, 0xef, 0x73, 0x5b, 0x82, 0xf3,
- 0xe3, 0xae, 0x63, 0xbe, 0xbd, 0xee, 0x3a, 0x8b, 0x56, 0x73, 0xd2, 0xc1,
- 0x93, 0x68, 0x43, 0xae, 0x95, 0xdb, 0x23, 0x7e, 0x3f, 0xc6, 0x82, 0x09,
- 0x59, 0xa5, 0x1e, 0xe8, 0x80, 0x9c, 0x33, 0x4f, 0x9d, 0x42, 0x9d, 0x40,
- 0x59, 0x70, 0xa4, 0x58, 0x83, 0x4e, 0x68, 0xed, 0x94, 0x32, 0x79, 0xb6,
- 0x40, 0x3d, 0xf1, 0x43, 0x99, 0xde, 0xa0, 0x2b, 0x87, 0x24, 0xf0, 0x6b,
- 0x5b, 0x24, 0x9a, 0x76, 0xcc, 0x7b, 0xd4, 0x1c, 0x7d, 0x7d, 0xb9, 0x9f,
- 0xf8, 0x73, 0x36, 0x63, 0xb7, 0x8b, 0xc6, 0x9e, 0x0a, 0x3f, 0x7d, 0x1f,
- 0x73, 0x65, 0x1f, 0x8a, 0x4f, 0x83, 0x43, 0xbe, 0x2f, 0xa0, 0xe2, 0x7c,
- 0xc0, 0xc1, 0x89, 0xbf, 0x83, 0xae, 0xcd, 0x11, 0x97, 0x80, 0xcf, 0x5d,
- 0x73, 0x94, 0xa3, 0xed, 0xd4, 0x65, 0xc0, 0x79, 0x29, 0xea, 0x6b, 0x59,
- 0x3a, 0x06, 0xcc, 0x65, 0xdc, 0x2a, 0x79, 0xca, 0x2b, 0xef, 0x48, 0x2c,
- 0x19, 0x32, 0x3d, 0xdf, 0x2a, 0xdd, 0x0b, 0x8c, 0xa9, 0x7e, 0xb3, 0x59,
- 0x5a, 0x19, 0x57, 0xa5, 0x0d, 0x1a, 0x90, 0x1c, 0xca, 0xbb, 0x16, 0xc2,
- 0x2a, 0x06, 0x56, 0x36, 0xc8, 0xa3, 0x7e, 0xe8, 0x03, 0x3b, 0xb5, 0x62,
- 0x7c, 0xb4, 0xc9, 0xc7, 0x90, 0x90, 0xa5, 0x12, 0x64, 0xac, 0x04, 0x19,
- 0x2b, 0x41, 0xc6, 0x4a, 0x90, 0x31, 0x60, 0xbf, 0x67, 0xb1, 0xff, 0xce,
- 0x95, 0x06, 0xb5, 0x5d, 0xdf, 0xa3, 0xec, 0xfa, 0xe1, 0xd2, 0xab, 0x1e,
- 0xd3, 0x2f, 0x29, 0xdf, 0xb4, 0x1f, 0x32, 0x48, 0x5f, 0x34, 0xf0, 0x51,
- 0x5f, 0x95, 0xa7, 0x66, 0x5f, 0x93, 0x53, 0xb3, 0x6b, 0x38, 0x70, 0xaa,
- 0xe4, 0xc9, 0xcb, 0x2e, 0xfc, 0xcf, 0x45, 0x62, 0xaa, 0x4c, 0x5b, 0xa3,
- 0xc2, 0x56, 0x87, 0x24, 0xaf, 0x70, 0xb2, 0xb2, 0x23, 0xc0, 0x57, 0x0a,
- 0x17, 0x72, 0x6f, 0x4a, 0xfb, 0x8e, 0xd7, 0xe5, 0x1c, 0xec, 0xf8, 0x52,
- 0xed, 0x0d, 0x79, 0x4e, 0xe1, 0x71, 0xf2, 0xe1, 0x7d, 0xf2, 0xb7, 0xa6,
- 0x7f, 0x86, 0x7f, 0x0a, 0x58, 0x63, 0xa9, 0x97, 0xba, 0x23, 0x02, 0x5b,
- 0x60, 0x17, 0xba, 0xb0, 0xaf, 0x0f, 0x18, 0xef, 0x02, 0xa6, 0xe1, 0xfb,
- 0xad, 0xf2, 0xe2, 0x6c, 0xa1, 0x4e, 0x26, 0xa8, 0x1f, 0xec, 0x23, 0x62,
- 0xd0, 0x4e, 0xd1, 0x6e, 0x72, 0xbe, 0xb4, 0x53, 0x6d, 0x2d, 0xbc, 0x3f,
- 0x56, 0x39, 0x7e, 0xc3, 0x16, 0xc6, 0x18, 0xe3, 0x0e, 0x79, 0xfa, 0xba,
- 0x1c, 0xa8, 0xb2, 0xec, 0x35, 0xac, 0x0f, 0xd3, 0x37, 0xbd, 0xbb, 0xe3,
- 0x1c, 0x8f, 0xfd, 0x02, 0x37, 0x75, 0x60, 0xae, 0xa5, 0xcf, 0x6a, 0xcc,
- 0xdd, 0xaf, 0x70, 0xf4, 0xe5, 0x78, 0x99, 0x7c, 0x72, 0xc1, 0xa7, 0xd7,
- 0x55, 0x0c, 0x70, 0x93, 0xd8, 0xf0, 0x13, 0xd8, 0x57, 0x85, 0x8b, 0xc2,
- 0x38, 0x25, 0x63, 0xb8, 0x8c, 0x0f, 0xd7, 0x6b, 0x0c, 0x75, 0x57, 0x40,
- 0xee, 0x82, 0x7e, 0xb9, 0x1b, 0xfa, 0xe5, 0x9e, 0xcb, 0xee, 0x5f, 0x07,
- 0x71, 0xff, 0xee, 0x42, 0xd8, 0xe8, 0x94, 0xb1, 0x6a, 0x7d, 0x5b, 0xc6,
- 0x6e, 0x37, 0x8b, 0xd5, 0x32, 0x8e, 0x9b, 0xda, 0x10, 0xff, 0xa3, 0x6c,
- 0x78, 0xf2, 0x92, 0xcb, 0xb8, 0x5b, 0x70, 0x67, 0x7f, 0x33, 0xfc, 0x65,
- 0xb5, 0x04, 0x71, 0xe6, 0x48, 0xfa, 0xa2, 0xf0, 0xee, 0x7e, 0x71, 0x86,
- 0x78, 0x20, 0xae, 0xee, 0xd9, 0x19, 0x2a, 0xce, 0xe7, 0xb7, 0x2d, 0xce,
- 0xa8, 0x73, 0xa5, 0x02, 0xe3, 0xd5, 0xe6, 0x4e, 0xdb, 0x1c, 0x0b, 0xfb,
- 0xf7, 0x65, 0xb8, 0x97, 0x7d, 0x5d, 0x06, 0x59, 0xac, 0xad, 0xdd, 0xb1,
- 0x1c, 0x52, 0xfa, 0xe2, 0x22, 0xf6, 0x00, 0xd7, 0x0b, 0xfe, 0x02, 0xf6,
- 0xc9, 0x14, 0xf4, 0x53, 0x5e, 0xf5, 0x17, 0xa3, 0x5c, 0x64, 0xb2, 0x61,
- 0x43, 0xa2, 0x27, 0xe8, 0x0b, 0xf9, 0xb1, 0x96, 0x5c, 0xd8, 0x56, 0xfa,
- 0x1b, 0xb4, 0x03, 0x9f, 0x71, 0x7f, 0x5a, 0x13, 0x8d, 0xe9, 0x06, 0xd8,
- 0x55, 0xac, 0x5f, 0x8d, 0x31, 0x01, 0xec, 0xdd, 0xe5, 0xef, 0xca, 0xfe,
- 0xf9, 0xe1, 0x16, 0x5f, 0xfe, 0x19, 0x3b, 0xe6, 0xfc, 0x02, 0x1a, 0xd6,
- 0xf7, 0x6d, 0x9c, 0x90, 0x58, 0x33, 0x6c, 0xda, 0x87, 0xe1, 0x67, 0xec,
- 0x82, 0xac, 0xac, 0xc4, 0xd9, 0xaf, 0xbf, 0x67, 0xa6, 0x4b, 0xec, 0xfb,
- 0xbb, 0x32, 0x3c, 0x7f, 0xb6, 0x85, 0xb6, 0x64, 0x19, 0x7a, 0xe0, 0xbc,
- 0x49, 0x1b, 0x3a, 0x0e, 0x1b, 0xd7, 0x21, 0xdf, 0x9f, 0xa7, 0x7d, 0x4c,
- 0x9a, 0xa7, 0xa4, 0x2f, 0x71, 0x0a, 0x34, 0x7d, 0xde, 0x8d, 0xd0, 0x47,
- 0xf3, 0x86, 0x50, 0xf6, 0x4d, 0x49, 0x9a, 0x5d, 0x21, 0x3e, 0xf7, 0x99,
- 0x8f, 0x03, 0xc3, 0x66, 0xcc, 0xa4, 0x79, 0x5d, 0x88, 0x72, 0x04, 0x9f,
- 0x7b, 0x79, 0x8d, 0xce, 0x37, 0xe7, 0x95, 0x9f, 0xa4, 0xf4, 0xcc, 0xb2,
- 0xcb, 0xf1, 0x40, 0xb7, 0xd2, 0x59, 0xd7, 0x41, 0x9f, 0xc4, 0xf4, 0x99,
- 0x1b, 0xda, 0x10, 0xdb, 0xb8, 0x11, 0x9d, 0x7f, 0x44, 0xb2, 0x27, 0xe3,
- 0xd0, 0x67, 0xec, 0x2b, 0xf0, 0x1d, 0x68, 0x23, 0x03, 0xbc, 0x4d, 0x7b,
- 0x77, 0x2b, 0xec, 0xde, 0x35, 0x8a, 0x9e, 0x11, 0xb7, 0x5f, 0xa6, 0x8e,
- 0x73, 0xec, 0x5e, 0xe8, 0xf2, 0x84, 0x92, 0xdb, 0x62, 0xe9, 0x7c, 0x22,
- 0x06, 0x9d, 0x1c, 0xdb, 0x41, 0x7e, 0x7e, 0x50, 0xee, 0x70, 0xc6, 0xe5,
- 0x4e, 0xc8, 0xce, 0x90, 0xe3, 0xca, 0x30, 0xd6, 0x62, 0x97, 0x03, 0xbb,
- 0xa3, 0x30, 0x74, 0x23, 0xfc, 0x2e, 0x8e, 0xdd, 0xa1, 0xef, 0x5c, 0xf8,
- 0xf8, 0xf1, 0xcf, 0x6a, 0x3e, 0x8f, 0xb2, 0xf3, 0x2f, 0x2b, 0xde, 0x8c,
- 0xb8, 0x37, 0x69, 0x3b, 0xdb, 0x2a, 0x39, 0x55, 0xef, 0x26, 0x65, 0x8f,
- 0x8b, 0x4b, 0xf7, 0x22, 0x85, 0x6d, 0x5e, 0x82, 0xbe, 0x01, 0xe6, 0x2e,
- 0x56, 0x77, 0x22, 0x0f, 0x1b, 0xba, 0x94, 0x46, 0xfa, 0x41, 0xa4, 0xac,
- 0xfb, 0xb9, 0x16, 0x3f, 0x96, 0x5b, 0x7f, 0x87, 0xcc, 0xbf, 0x7f, 0xfa,
- 0x61, 0x85, 0x4b, 0x2f, 0xaa, 0xfb, 0x87, 0x06, 0xb0, 0x4e, 0x16, 0x7a,
- 0xa5, 0x05, 0x18, 0x68, 0xe6, 0x84, 0x9d, 0x1a, 0x0e, 0xdd, 0x26, 0x1f,
- 0x81, 0x2f, 0x5f, 0x71, 0xb9, 0x96, 0x3b, 0xe5, 0x13, 0xb7, 0x50, 0x46,
- 0x6e, 0x93, 0x7d, 0xb7, 0x84, 0x64, 0x5f, 0xbf, 0x9d, 0x21, 0xdd, 0xd7,
- 0xbe, 0x3f, 0xf0, 0xa7, 0xbb, 0x47, 0x92, 0xa1, 0x01, 0x79, 0x1c, 0x32,
- 0x56, 0x80, 0x7c, 0x0d, 0xd7, 0xc8, 0x73, 0xea, 0x7b, 0xea, 0xf9, 0x14,
- 0xb0, 0x72, 0x80, 0xfd, 0x1c, 0x99, 0xa9, 0x35, 0x88, 0x75, 0x15, 0xe3,
- 0xc9, 0x96, 0x7f, 0xae, 0x71, 0x15, 0x65, 0x02, 0x3e, 0xc8, 0x55, 0xfe,
- 0xfe, 0x54, 0xf7, 0xfe, 0xae, 0xf2, 0xed, 0x0a, 0xfc, 0x5f, 0x8f, 0x38,
- 0xcf, 0xbf, 0x5f, 0x70, 0x51, 0xeb, 0xd2, 0xe4, 0xd6, 0x55, 0x7c, 0xd7,
- 0x4a, 0xff, 0xe1, 0xeb, 0x2d, 0x6b, 0xdf, 0x2d, 0x6c, 0x94, 0xc5, 0x20,
- 0xee, 0x56, 0xc6, 0x9c, 0x69, 0xd3, 0x6d, 0x93, 0xba, 0xb0, 0xcd, 0xd9,
- 0x23, 0x7f, 0x09, 0xfb, 0xfe, 0xd5, 0x55, 0xfb, 0xbe, 0x17, 0xfc, 0xd8,
- 0x88, 0x01, 0x1c, 0xf3, 0x2e, 0xcc, 0x65, 0x04, 0xeb, 0x79, 0x27, 0x7e,
- 0x77, 0x94, 0xd6, 0xc5, 0xf1, 0x66, 0x0b, 0xc0, 0x93, 0x0d, 0x0e, 0xfb,
- 0x5b, 0x17, 0xcf, 0x2b, 0xe4, 0x65, 0x35, 0x56, 0x38, 0x78, 0x49, 0x68,
- 0xf7, 0xde, 0x92, 0x68, 0x8f, 0xf3, 0x56, 0x57, 0xc8, 0x79, 0xde, 0x08,
- 0xf1, 0xec, 0xdb, 0x95, 0xd3, 0x35, 0xe2, 0xb0, 0x0b, 0x62, 0x9c, 0x25,
- 0x06, 0x7b, 0x45, 0xc5, 0xa0, 0x2a, 0xa5, 0x6f, 0x23, 0x45, 0x7d, 0xe8,
- 0xc7, 0xb0, 0x1f, 0xa7, 0x50, 0x58, 0x85, 0x7a, 0xf6, 0x4e, 0xac, 0xc3,
- 0x14, 0x7e, 0x5d, 0x3b, 0xae, 0xc3, 0xfe, 0xa5, 0x9c, 0x32, 0xf6, 0xd5,
- 0x63, 0xee, 0x08, 0xf1, 0xdd, 0x66, 0x71, 0xb0, 0xef, 0x48, 0x64, 0x0e,
- 0xb6, 0xce, 0xa0, 0x7e, 0xe0, 0x3c, 0x68, 0x27, 0x4d, 0x59, 0x3c, 0xce,
- 0xbd, 0xbe, 0x59, 0xfd, 0xa0, 0x6e, 0x30, 0x17, 0x65, 0x37, 0x32, 0x79,
- 0xc6, 0x38, 0x4b, 0x5c, 0x03, 0x17, 0x6b, 0xe0, 0xc9, 0x09, 0xb7, 0x0d,
- 0x7a, 0x3b, 0x2e, 0xe1, 0x13, 0x9e, 0x0c, 0x29, 0xec, 0xda, 0x07, 0xcc,
- 0xb5, 0x55, 0xe3, 0x86, 0xb8, 0x44, 0x4e, 0x74, 0x4a, 0x23, 0x70, 0x75,
- 0xc3, 0x51, 0xda, 0xc8, 0xa4, 0x35, 0x04, 0x21, 0x88, 0xa8, 0xbb, 0xac,
- 0xf6, 0xe0, 0xf7, 0xa5, 0xcf, 0xfa, 0xbe, 0x10, 0x2f, 0xfd, 0x7b, 0xac,
- 0x9f, 0xed, 0x5e, 0xd8, 0xa4, 0x7e, 0x71, 0xad, 0x3e, 0xe4, 0x88, 0xb1,
- 0x35, 0xb6, 0x61, 0xac, 0x2d, 0x39, 0xf8, 0x3d, 0xc6, 0xd8, 0xe0, 0x6b,
- 0x36, 0x9c, 0xf1, 0x69, 0x30, 0x96, 0xdb, 0xa5, 0x72, 0x92, 0x7b, 0x94,
- 0x71, 0x16, 0xd3, 0xf7, 0x53, 0x4b, 0xf4, 0x57, 0xf9, 0xde, 0xd2, 0xef,
- 0xbb, 0xf4, 0x7b, 0xfa, 0xa3, 0x05, 0xaf, 0x01, 0x3c, 0xdd, 0x05, 0xfd,
- 0x79, 0xef, 0x4e, 0x47, 0xe1, 0x86, 0x7b, 0x57, 0xd7, 0x6c, 0xb7, 0xba,
- 0x4f, 0x54, 0x29, 0x1d, 0x12, 0x67, 0xc7, 0x4a, 0x2a, 0x22, 0x63, 0x58,
- 0x0b, 0xe6, 0x33, 0xa4, 0x27, 0x75, 0x58, 0x0e, 0xa8, 0xb5, 0xa9, 0x1c,
- 0xb7, 0x8f, 0x58, 0xa1, 0x29, 0x31, 0x2a, 0x7c, 0xfe, 0x34, 0xd2, 0xc3,
- 0xc0, 0x3b, 0x7e, 0xec, 0xd2, 0xa8, 0xac, 0xe7, 0x25, 0x30, 0x86, 0xb9,
- 0x6b, 0x5d, 0x1c, 0x6b, 0x2d, 0xc6, 0xc5, 0xf7, 0x43, 0xea, 0x7d, 0x6a,
- 0x5d, 0x9c, 0x2b, 0x67, 0x10, 0xcb, 0x04, 0xef, 0xb9, 0x16, 0x5c, 0x2f,
- 0xd8, 0xe2, 0xe3, 0x41, 0xcc, 0xab, 0x55, 0xaf, 0x0b, 0xd7, 0x67, 0x46,
- 0xce, 0x99, 0xf6, 0x08, 0xe5, 0xef, 0x86, 0x9d, 0x57, 0xcb, 0x44, 0x07,
- 0xe3, 0x6d, 0xf5, 0x34, 0x6c, 0x8c, 0xa3, 0xd5, 0x8f, 0xbf, 0x31, 0xfe,
- 0xc6, 0xb1, 0xfd, 0x18, 0x5b, 0x76, 0x5d, 0x8c, 0xad, 0x7e, 0x3c, 0x8e,
- 0xb5, 0x15, 0xfe, 0x53, 0xc1, 0x8b, 0x3b, 0x5c, 0xa3, 0x6e, 0x6b, 0x9e,
- 0xf9, 0x2f, 0x1a, 0x58, 0xc7, 0x38, 0xec, 0x08, 0xd7, 0x32, 0x38, 0x6f,
- 0xe6, 0x9a, 0x26, 0xad, 0xc3, 0xfe, 0x7a, 0x0e, 0xfa, 0xeb, 0xee, 0xaf,
- 0xff, 0x85, 0xd5, 0x75, 0xa4, 0x7d, 0xe0, 0x3a, 0x76, 0x88, 0x40, 0xcf,
- 0x1a, 0x47, 0xb9, 0x86, 0x4c, 0xb9, 0x86, 0x7c, 0xc7, 0x35, 0xec, 0xd2,
- 0xef, 0xb8, 0x7e, 0xc0, 0x69, 0x5f, 0xe0, 0x3d, 0xd5, 0xac, 0xfa, 0x06,
- 0xab, 0xab, 0x27, 0xd8, 0x8b, 0x29, 0x79, 0x6e, 0xb1, 0x59, 0xcc, 0xb4,
- 0x3f, 0xaf, 0xf1, 0x75, 0xf1, 0x76, 0x9e, 0x5f, 0xf5, 0x13, 0x7b, 0x06,
- 0xf3, 0x4a, 0x70, 0x5e, 0x07, 0xe4, 0x75, 0xc9, 0xcf, 0x44, 0xe0, 0x03,
- 0xa6, 0x80, 0x73, 0xfa, 0xa1, 0x6f, 0x19, 0x1f, 0x45, 0x59, 0x95, 0x78,
- 0x85, 0xb6, 0x2e, 0x85, 0xbd, 0x42, 0x1d, 0x4c, 0x3c, 0xf2, 0x9a, 0xe4,
- 0xca, 0x81, 0x8e, 0x41, 0xff, 0x46, 0xd0, 0x3f, 0xf9, 0x9c, 0xb9, 0x76,
- 0xbb, 0xac, 0x58, 0xdb, 0xc5, 0xb6, 0x96, 0x64, 0x6d, 0x5d, 0xc7, 0x37,
- 0xe7, 0xbb, 0x7b, 0x6f, 0x78, 0x4d, 0x36, 0xc6, 0x37, 0x59, 0xfb, 0x49,
- 0x09, 0xde, 0x07, 0x6b, 0xbf, 0xe9, 0x3a, 0x14, 0x5e, 0x15, 0xae, 0x05,
- 0x79, 0x40, 0x3c, 0x1c, 0x95, 0x7f, 0x13, 0xe7, 0x7e, 0x2c, 0xa8, 0x33,
- 0xcd, 0xa4, 0xd1, 0xa3, 0x74, 0xc6, 0x90, 0xeb, 0xcb, 0x6b, 0x01, 0xe3,
- 0xc4, 0xba, 0xff, 0xd0, 0x1b, 0x8a, 0xc3, 0xcf, 0xed, 0xa6, 0x7e, 0x09,
- 0xf6, 0x74, 0xb3, 0xda, 0xd3, 0x9f, 0x77, 0x43, 0x52, 0x74, 0x42, 0x32,
- 0xe5, 0x1c, 0x52, 0x18, 0xff, 0xa3, 0xe8, 0xeb, 0x13, 0xba, 0xaf, 0x29,
- 0xe9, 0xd1, 0xfa, 0xe7, 0x20, 0xe4, 0xdc, 0x93, 0x7b, 0xdc, 0x9d, 0x72,
- 0x43, 0x1b, 0xf7, 0x40, 0x30, 0xff, 0x43, 0xd2, 0xbd, 0x73, 0xc5, 0x82,
- 0x67, 0x70, 0x6d, 0x74, 0x95, 0x07, 0xdc, 0x67, 0x81, 0x7c, 0xfb, 0x7c,
- 0xf0, 0xe7, 0xbf, 0x6e, 0xae, 0x7a, 0x9e, 0x9c, 0x33, 0xeb, 0x71, 0xae,
- 0x3e, 0x96, 0x5f, 0x9b, 0x6b, 0x50, 0xbf, 0x05, 0xb2, 0x64, 0x5b, 0x12,
- 0xaa, 0xe7, 0xcd, 0xaa, 0x8e, 0x1a, 0x61, 0x8c, 0x64, 0xc5, 0xb4, 0x53,
- 0x56, 0x28, 0x88, 0x45, 0xfb, 0x58, 0xb7, 0x0b, 0x38, 0xdc, 0xe9, 0xe9,
- 0x49, 0xe5, 0x55, 0x8c, 0xd4, 0x50, 0xf3, 0x9a, 0x02, 0x26, 0x5b, 0x74,
- 0x5f, 0xf5, 0x3e, 0x09, 0xcc, 0x3a, 0x21, 0x0f, 0x49, 0x78, 0x5d, 0x2c,
- 0x17, 0xf9, 0xb3, 0x8c, 0xe7, 0xda, 0x56, 0x06, 0x6b, 0xfc, 0x3b, 0xf0,
- 0xe1, 0x2b, 0xd0, 0xfb, 0x1f, 0xa3, 0x6d, 0x28, 0xc1, 0x5e, 0x00, 0x97,
- 0x7c, 0xf5, 0x8a, 0x18, 0x7e, 0xa2, 0x2e, 0x96, 0xeb, 0xe3, 0xd3, 0x73,
- 0x0a, 0x93, 0x12, 0xb7, 0x1f, 0x09, 0xdd, 0xd5, 0x1b, 0x86, 0x9f, 0x51,
- 0xf0, 0x62, 0x0e, 0x71, 0xdc, 0x21, 0xb9, 0x03, 0xeb, 0x73, 0x7a, 0xb1,
- 0x10, 0xda, 0x55, 0x0a, 0x64, 0x15, 0x7e, 0x65, 0xcd, 0x4e, 0x9d, 0x07,
- 0x3f, 0x9e, 0xd2, 0x98, 0x8f, 0xe7, 0x35, 0x15, 0xed, 0xb3, 0x30, 0x36,
- 0x54, 0xac, 0x1d, 0x92, 0x69, 0x97, 0xb1, 0x9d, 0x6e, 0x29, 0xc6, 0x33,
- 0x57, 0x37, 0xae, 0xf2, 0xc8, 0x36, 0xe1, 0xf3, 0xa5, 0xa8, 0xbf, 0x2b,
- 0xfa, 0xbc, 0xe3, 0x29, 0x25, 0x5f, 0x41, 0x5c, 0x98, 0xfe, 0x11, 0xcf,
- 0xab, 0xba, 0xcd, 0x11, 0x3e, 0x97, 0x29, 0x03, 0xca, 0x67, 0x02, 0x2f,
- 0xef, 0x90, 0xcc, 0x98, 0xa5, 0x70, 0xcb, 0x63, 0x25, 0xee, 0x17, 0xe2,
- 0xff, 0xd7, 0x81, 0xfd, 0x23, 0x58, 0x33, 0xfa, 0x01, 0x1c, 0x9b, 0xfb,
- 0x02, 0x65, 0x55, 0xf3, 0x97, 0xec, 0x8b, 0x0f, 0x6d, 0x23, 0xc6, 0x78,
- 0xa1, 0xf4, 0x98, 0xe2, 0xdf, 0x8a, 0x04, 0xb1, 0x73, 0x85, 0x05, 0x0b,
- 0xd9, 0x70, 0x48, 0x92, 0x73, 0xff, 0x16, 0x32, 0xd4, 0x0f, 0x1f, 0x89,
- 0xf5, 0x44, 0x9d, 0x5f, 0x0d, 0x01, 0x73, 0x19, 0xce, 0xbb, 0xa4, 0x68,
- 0x46, 0xa5, 0xa8, 0xee, 0xfe, 0xf1, 0x3c, 0x37, 0xac, 0x62, 0x3b, 0x45,
- 0x93, 0x98, 0x3f, 0xbd, 0x2d, 0xb8, 0xfb, 0x57, 0x34, 0xd9, 0x8e, 0x79,
- 0x96, 0x4f, 0x49, 0x74, 0xee, 0xa0, 0x34, 0xcc, 0x3d, 0x24, 0x8d, 0xc7,
- 0x88, 0xf1, 0x18, 0xbb, 0x37, 0x6e, 0x6d, 0x14, 0x62, 0xee, 0x6f, 0x61,
- 0xec, 0x43, 0xf2, 0x03, 0x37, 0xa0, 0xe9, 0xba, 0xad, 0xd2, 0xca, 0x3a,
- 0x41, 0x9e, 0xcf, 0xc4, 0x09, 0x3c, 0x17, 0x77, 0xfc, 0x18, 0xa9, 0x3a,
- 0x57, 0x41, 0x5a, 0xe1, 0xb9, 0x38, 0xdf, 0xbf, 0x66, 0xfa, 0xa9, 0x8f,
- 0xf7, 0x7d, 0xdf, 0x83, 0x6d, 0x52, 0x75, 0xd8, 0x62, 0xfd, 0xf7, 0xa1,
- 0x39, 0x94, 0xe7, 0xe7, 0x83, 0x3b, 0x3a, 0x06, 0x7c, 0x5f, 0xbb, 0x40,
- 0x9f, 0xc1, 0xe4, 0xb7, 0x98, 0xf3, 0x05, 0xf0, 0xf9, 0x1a, 0x75, 0xbf,
- 0x87, 0x77, 0x24, 0x50, 0xcf, 0xf2, 0x31, 0x1f, 0xf3, 0x09, 0xf0, 0xf9,
- 0xfd, 0x9d, 0x46, 0xfa, 0x7f, 0x5f, 0x9d, 0x1d, 0x20, 0xa6, 0xd8, 0xc6,
- 0xb3, 0x3f, 0x60, 0x55, 0xae, 0xed, 0x77, 0xb1, 0xb6, 0x8d, 0xea, 0xac,
- 0xa5, 0x58, 0xa2, 0x0f, 0x95, 0xc7, 0x9a, 0xf1, 0x9e, 0x1c, 0x7d, 0xad,
- 0xbc, 0x8e, 0x81, 0x92, 0x4e, 0xe2, 0xe8, 0x00, 0x93, 0xb3, 0xcf, 0xcd,
- 0xee, 0x03, 0x07, 0x7e, 0x12, 0xd7, 0x38, 0xa1, 0x68, 0x1e, 0xde, 0xe0,
- 0x23, 0x1c, 0xc6, 0xfe, 0x5b, 0x84, 0x0c, 0x4d, 0x42, 0xef, 0x0c, 0x85,
- 0xb9, 0x27, 0x9a, 0xb5, 0xff, 0xe8, 0xd0, 0x57, 0x0e, 0x8d, 0xa1, 0x0f,
- 0xe3, 0xd8, 0x1b, 0x32, 0x05, 0x9d, 0x3b, 0x5d, 0x4b, 0xaa, 0x6f, 0x78,
- 0x32, 0x09, 0xde, 0xdb, 0x62, 0xf9, 0x7f, 0x81, 0x8c, 0xbc, 0x01, 0x0c,
- 0xba, 0x05, 0xfc, 0x34, 0xf4, 0xbd, 0x90, 0x0f, 0xe8, 0xf8, 0x4f, 0x8c,
- 0xf1, 0x6f, 0xe8, 0xaa, 0xa2, 0x8f, 0xef, 0xe2, 0xd3, 0x48, 0xbf, 0xd0,
- 0xec, 0xcb, 0xc8, 0xcb, 0x7a, 0x8d, 0x9b, 0x50, 0xfe, 0xa8, 0x8a, 0xfb,
- 0xf9, 0x73, 0xb2, 0xb5, 0x7f, 0x10, 0xc5, 0x3a, 0x73, 0x5e, 0x5f, 0x41,
- 0x3d, 0xae, 0x6f, 0xaf, 0x3e, 0x0f, 0x6d, 0x56, 0x3a, 0x29, 0xe7, 0x5a,
- 0xf0, 0x75, 0x89, 0x89, 0x80, 0xa9, 0x5d, 0xb6, 0x7b, 0x76, 0x1b, 0xcf,
- 0x1b, 0x1b, 0x1c, 0x85, 0xe7, 0x3b, 0xc2, 0x12, 0x94, 0xdd, 0x8e, 0x32,
- 0xc6, 0x25, 0xde, 0x85, 0xb5, 0x61, 0x59, 0x16, 0x79, 0x8e, 0x75, 0xb5,
- 0x1e, 0x87, 0x63, 0x0c, 0xb7, 0xac, 0xa7, 0x89, 0x73, 0xe9, 0xd8, 0xf0,
- 0xfd, 0x00, 0xcb, 0xde, 0xa5, 0xcb, 0x22, 0x7a, 0x7e, 0xb7, 0xeb, 0x6f,
- 0x67, 0xed, 0x23, 0x99, 0x55, 0x3c, 0x4a, 0xfa, 0x62, 0xaa, 0x5d, 0xc6,
- 0xf4, 0x65, 0xe7, 0x30, 0xd6, 0x23, 0x92, 0xf6, 0xda, 0xb9, 0x47, 0x86,
- 0xc2, 0x81, 0x5f, 0x98, 0x50, 0xbe, 0x9e, 0x65, 0xf8, 0x77, 0x84, 0xce,
- 0x5d, 0x76, 0x0f, 0xda, 0xbf, 0x53, 0x3e, 0xdc, 0xdb, 0x24, 0x8b, 0xb3,
- 0x31, 0x7d, 0x3f, 0x31, 0xa1, 0xf6, 0x49, 0x7e, 0x9c, 0xf9, 0x1f, 0x6d,
- 0xe3, 0x77, 0xcb, 0x86, 0xc3, 0xf2, 0x0e, 0xcd, 0xdf, 0x77, 0xa9, 0xfb,
- 0x3c, 0xbc, 0x67, 0x52, 0x2c, 0xff, 0x44, 0xbd, 0x3f, 0x3d, 0xdf, 0xa0,
- 0xea, 0x9f, 0x9e, 0xdf, 0x78, 0x27, 0x87, 0x65, 0xef, 0x66, 0x4c, 0x41,
- 0x96, 0x66, 0x1a, 0x64, 0x79, 0xde, 0xa2, 0x8f, 0x94, 0x6e, 0x5c, 0xfb,
- 0xf6, 0x45, 0x7f, 0xa7, 0xe6, 0xc9, 0x30, 0xd6, 0x6f, 0x71, 0x70, 0x5a,
- 0x2a, 0x83, 0xf4, 0x01, 0xd4, 0xbd, 0x3b, 0xc8, 0x48, 0x03, 0xf0, 0x5f,
- 0xc1, 0xab, 0x38, 0x8c, 0xbd, 0xb6, 0x6a, 0x1f, 0xea, 0xc7, 0xda, 0xcf,
- 0x22, 0x8f, 0x0c, 0xc9, 0xf5, 0x4f, 0x29, 0xba, 0x2a, 0x8a, 0x57, 0xc1,
- 0xb7, 0x45, 0xec, 0x9f, 0xdf, 0x17, 0x85, 0x35, 0x7e, 0x7c, 0x50, 0xf3,
- 0xfc, 0xaf, 0x75, 0xfa, 0x88, 0xec, 0x3b, 0xfe, 0x19, 0xd0, 0xda, 0xe4,
- 0xdf, 0x2d, 0x92, 0xfa, 0xef, 0x36, 0x22, 0xea, 0xdb, 0x95, 0x88, 0xf3,
- 0x08, 0xca, 0x18, 0x7b, 0x7a, 0x44, 0xcd, 0x83, 0xf7, 0xd7, 0x0a, 0xf2,
- 0xab, 0xee, 0x64, 0x04, 0xfe, 0x0f, 0xef, 0x08, 0x35, 0xeb, 0xfe, 0x76,
- 0xe9, 0x75, 0x1c, 0x97, 0x7d, 0xd0, 0xef, 0x79, 0xe0, 0x40, 0xde, 0xab,
- 0x9a, 0x08, 0xd7, 0x8f, 0x19, 0xc8, 0xb2, 0xef, 0x5b, 0x07, 0x67, 0xfd,
- 0x61, 0xe5, 0x03, 0xac, 0xfa, 0xe9, 0xba, 0x7c, 0x5c, 0xf6, 0x97, 0x94,
- 0xbf, 0xae, 0xce, 0xe8, 0xa6, 0xb1, 0x27, 0x87, 0x94, 0x0e, 0x8f, 0x85,
- 0x86, 0xab, 0x69, 0xc9, 0x9f, 0xdc, 0x8d, 0x71, 0x18, 0xfb, 0xca, 0xe8,
- 0xb3, 0xb0, 0xbd, 0xb2, 0xaf, 0xe6, 0x8f, 0x3d, 0x59, 0xe2, 0xfb, 0x24,
- 0xec, 0x22, 0xdf, 0xe7, 0x12, 0x61, 0x15, 0xcd, 0xbf, 0x0e, 0x6d, 0x1b,
- 0x34, 0x6f, 0x79, 0x9f, 0x9e, 0xed, 0xb9, 0xff, 0x3e, 0x6e, 0x4a, 0x73,
- 0x0e, 0xef, 0xd9, 0x26, 0xe8, 0x6f, 0x12, 0x7a, 0x9a, 0xfe, 0xe8, 0xc3,
- 0xb2, 0x52, 0x9e, 0x96, 0xf3, 0xe5, 0x40, 0xce, 0x78, 0xb7, 0x99, 0xb4,
- 0xdf, 0xa9, 0xef, 0x36, 0x67, 0xb0, 0x0e, 0xeb, 0x79, 0x95, 0x5b, 0xf7,
- 0xfd, 0xd1, 0x5f, 0x98, 0xfe, 0x37, 0x80, 0xb7, 0xa9, 0x7b, 0x4a, 0xeb,
- 0xe5, 0x9d, 0xfd, 0x2c, 0x9b, 0x8c, 0xed, 0xfb, 0x77, 0xad, 0x3a, 0xea,
- 0xde, 0xc7, 0xf5, 0xfd, 0xa6, 0xe7, 0xf4, 0x9d, 0x78, 0xf2, 0x73, 0x4c,
- 0xd3, 0x7b, 0x1d, 0xf6, 0x1e, 0xfb, 0x7c, 0x54, 0xaf, 0x1b, 0xd2, 0x45,
- 0x3e, 0x53, 0x0f, 0xad, 0xe8, 0xf3, 0x4e, 0x53, 0x8f, 0x51, 0x7f, 0xbf,
- 0xac, 0xa1, 0x6e, 0x5c, 0xb6, 0xe7, 0xb7, 0x48, 0xc1, 0x5d, 0x6b, 0x96,
- 0x1d, 0xd7, 0xf7, 0xd8, 0x82, 0xbb, 0xd5, 0x2c, 0x0b, 0xee, 0x5b, 0x91,
- 0x5f, 0x8c, 0xe1, 0x21, 0xad, 0x8d, 0xe9, 0xe7, 0xb1, 0xba, 0x6f, 0x74,
- 0x82, 0x3e, 0x23, 0xe8, 0xe3, 0xf6, 0xf0, 0xe5, 0x77, 0xb1, 0xf9, 0xdd,
- 0x14, 0x65, 0xd1, 0xe0, 0x37, 0xdd, 0xf4, 0x7b, 0x80, 0x55, 0xb6, 0xca,
- 0xa4, 0xa2, 0xa7, 0xa0, 0xee, 0x27, 0x64, 0xdd, 0x26, 0x19, 0x32, 0xfd,
- 0xfc, 0xe4, 0xe2, 0x46, 0x39, 0x65, 0xf9, 0xf5, 0x31, 0x69, 0x2e, 0x60,
- 0x1c, 0xbe, 0xdf, 0xec, 0x1b, 0x81, 0xa8, 0xfe, 0x4e, 0xc9, 0x45, 0x9b,
- 0xcf, 0x53, 0xde, 0x0b, 0x85, 0xd5, 0xbb, 0x90, 0x05, 0x15, 0x97, 0x14,
- 0x23, 0xb8, 0x93, 0xc8, 0x6f, 0xd6, 0x45, 0x9e, 0xa9, 0xf2, 0xbb, 0xad,
- 0xdb, 0xd4, 0xbd, 0x11, 0xff, 0x2c, 0x8e, 0x74, 0x75, 0x2b, 0x9d, 0x5c,
- 0xa9, 0x16, 0xc9, 0x53, 0x1d, 0x87, 0x8d, 0xea, 0x38, 0x2c, 0x79, 0x3c,
- 0x02, 0x1e, 0xff, 0x3f, 0xbd, 0x2e, 0xc1, 0x77, 0x5f, 0x3c, 0xeb, 0xe1,
- 0x79, 0xd0, 0xa3, 0x6a, 0x2e, 0xd4, 0xd1, 0x68, 0xfb, 0xde, 0xb0, 0xda,
- 0xbb, 0xea, 0x9b, 0x78, 0xc8, 0x27, 0xbf, 0x71, 0x87, 0x7e, 0x2d, 0xf1,
- 0x5b, 0xf6, 0x11, 0xf5, 0x3d, 0x47, 0xa5, 0xca, 0x75, 0xe5, 0x37, 0xec,
- 0x63, 0x75, 0xf2, 0x18, 0xd6, 0x63, 0x6d, 0x69, 0x93, 0x66, 0x7f, 0xdd,
- 0xf9, 0x2d, 0x48, 0xa5, 0x1a, 0xdc, 0xa3, 0xdc, 0xb2, 0xc2, 0x3d, 0x21,
- 0xbe, 0x5f, 0xab, 0xbe, 0x67, 0xa9, 0xa8, 0xef, 0x43, 0x2c, 0x7e, 0x67,
- 0x09, 0xdb, 0xb1, 0x07, 0xcf, 0x3c, 0x47, 0xdd, 0x8b, 0x14, 0x3a, 0xa7,
- 0x3a, 0x81, 0xf4, 0x21, 0xc9, 0xa9, 0x38, 0x57, 0x0b, 0xf2, 0x93, 0x6a,
- 0xec, 0x62, 0xf5, 0x7e, 0xd9, 0x77, 0xf2, 0x01, 0x7e, 0x43, 0xa3, 0xbe,
- 0xc3, 0xcf, 0xba, 0xa4, 0x31, 0x2e, 0x53, 0x6a, 0xde, 0x85, 0xb5, 0x6f,
- 0x33, 0x7c, 0x39, 0x6a, 0xe3, 0x9a, 0x16, 0xaa, 0x2d, 0xa0, 0x31, 0xa4,
- 0xef, 0x52, 0x12, 0xff, 0x06, 0xf3, 0x6f, 0xe6, 0xfd, 0x3c, 0x8f, 0xe7,
- 0x65, 0xfb, 0x4a, 0xbc, 0x2b, 0x99, 0xd4, 0x7e, 0x31, 0x63, 0x65, 0x8c,
- 0xc7, 0x53, 0xc6, 0xed, 0xd4, 0x04, 0xb4, 0x7f, 0x54, 0x12, 0x3c, 0xcb,
- 0xd5, 0x73, 0x69, 0xa9, 0x9b, 0x0b, 0xef, 0x87, 0xfa, 0xf3, 0xe1, 0x37,
- 0x27, 0xf9, 0x52, 0xfd, 0xf7, 0x32, 0xea, 0x9b, 0x70, 0xf5, 0x7d, 0xca,
- 0x44, 0xf5, 0x41, 0xb9, 0xaf, 0xb4, 0x55, 0x7f, 0x2b, 0x13, 0x93, 0xfb,
- 0xaa, 0x6f, 0x28, 0x9e, 0xe6, 0xd5, 0x77, 0x3e, 0x51, 0xbd, 0x66, 0x71,
- 0xd5, 0xc7, 0xda, 0xf7, 0x3e, 0x76, 0xdd, 0xb7, 0x1f, 0x51, 0x99, 0x58,
- 0xfc, 0x65, 0xdf, 0xfc, 0x3c, 0x2c, 0xfc, 0xee, 0xe3, 0x25, 0x77, 0x5a,
- 0x1e, 0x2b, 0x7b, 0xde, 0x1d, 0x2e, 0xb1, 0xd4, 0x16, 0x39, 0x1f, 0xcf,
- 0x0c, 0x7e, 0xcf, 0x69, 0x0f, 0x55, 0x66, 0x1b, 0xa1, 0xaf, 0x1b, 0x95,
- 0x2d, 0x61, 0x7e, 0x71, 0x96, 0x7b, 0x3e, 0x82, 0x39, 0xda, 0xe6, 0x25,
- 0xf9, 0x54, 0x1b, 0xe3, 0x4c, 0x77, 0xc0, 0x77, 0xfb, 0xb8, 0xeb, 0xeb,
- 0xe5, 0xcf, 0x2d, 0xed, 0x96, 0xcf, 0x55, 0x63, 0xa1, 0xca, 0x0c, 0xef,
- 0xd7, 0xd9, 0x23, 0x65, 0x49, 0xa2, 0x1e, 0xfb, 0x87, 0xbc, 0x24, 0xb6,
- 0xcb, 0xd3, 0xc7, 0x7f, 0xee, 0x5d, 0x72, 0xf0, 0x1e, 0xba, 0xe6, 0xbc,
- 0x1b, 0xc4, 0xd2, 0xe0, 0x37, 0x1f, 0x65, 0xbd, 0xed, 0x90, 0x03, 0xd8,
- 0x6d, 0xec, 0x39, 0xfa, 0x75, 0x97, 0xb4, 0xde, 0x32, 0x8e, 0x5e, 0x23,
- 0x97, 0x56, 0xef, 0xe4, 0xbe, 0x0e, 0xd9, 0xb6, 0x7c, 0xfe, 0xab, 0xd8,
- 0xf3, 0x41, 0x09, 0x7f, 0x01, 0x76, 0xe2, 0x0b, 0x0d, 0x4a, 0xb7, 0xd3,
- 0x9e, 0x01, 0xf3, 0x03, 0xd7, 0x47, 0xd0, 0xcf, 0xfe, 0x36, 0x5f, 0x66,
- 0xa7, 0x45, 0xbe, 0xd8, 0x24, 0x99, 0x36, 0xfa, 0x8d, 0xf2, 0x2b, 0xf4,
- 0x57, 0xfd, 0x3e, 0x4b, 0xc9, 0x9f, 0x71, 0x8f, 0xd7, 0x38, 0x97, 0x64,
- 0xe2, 0x7f, 0xc9, 0x27, 0x65, 0x22, 0xc1, 0xb9, 0x3c, 0x2c, 0x85, 0xf2,
- 0xa3, 0xf8, 0x71, 0x9e, 0xa4, 0xfb, 0x5f, 0xe8, 0xb3, 0xfb, 0x31, 0x29,
- 0xce, 0xa4, 0x65, 0x6a, 0x7e, 0x92, 0xdf, 0xe4, 0x8e, 0xdc, 0xa1, 0xce,
- 0xb4, 0xec, 0x44, 0x32, 0xd4, 0x67, 0x4d, 0xf1, 0xae, 0x82, 0x9a, 0xcf,
- 0x24, 0xe6, 0xf3, 0x4a, 0x1b, 0xef, 0x78, 0x5f, 0x82, 0xfe, 0x35, 0x4e,
- 0x50, 0x0e, 0x6d, 0xb3, 0x2b, 0xc4, 0xfc, 0x5e, 0xf8, 0xab, 0x2c, 0xdb,
- 0x2b, 0xe1, 0xa3, 0xab, 0x7a, 0x1e, 0xe5, 0xfa, 0x6c, 0x55, 0xb5, 0xff,
- 0xaf, 0x68, 0x8b, 0x7a, 0x47, 0x83, 0xb6, 0x41, 0x1d, 0xb6, 0xe5, 0x3c,
- 0x77, 0xc3, 0x4f, 0x0e, 0xe8, 0x82, 0x1c, 0x26, 0xea, 0xf9, 0xdd, 0xbc,
- 0x81, 0xdf, 0x11, 0xe2, 0x4d, 0xf0, 0x8b, 0x3c, 0x0e, 0x6b, 0x1e, 0xff,
- 0x3d, 0xfa, 0x0f, 0xd6, 0xe0, 0x0e, 0x94, 0x99, 0xfa, 0x1b, 0xbc, 0x77,
- 0xc2, 0x77, 0xf2, 0x9c, 0xf5, 0xf7, 0xb7, 0xf9, 0xb2, 0x46, 0x7a, 0x36,
- 0xe3, 0xf9, 0x7b, 0xdb, 0xfd, 0x75, 0xd9, 0x0b, 0x7e, 0xf1, 0x1e, 0x65,
- 0x9f, 0xba, 0x8f, 0x9f, 0x19, 0xdf, 0x0b, 0xd9, 0x09, 0xe6, 0xd5, 0x07,
- 0x19, 0xe3, 0x39, 0x01, 0xeb, 0xd7, 0xf3, 0xc4, 0xb7, 0x7b, 0x61, 0xfa,
- 0xfa, 0x0e, 0xe7, 0x0a, 0x4c, 0xf8, 0x45, 0xf5, 0xfd, 0x0d, 0xf4, 0xe4,
- 0xbb, 0x57, 0xbf, 0xbf, 0xb9, 0xf2, 0x1a, 0x0f, 0xb4, 0xfb, 0x36, 0xca,
- 0x04, 0x4f, 0x5a, 0x75, 0x9b, 0xbd, 0xc0, 0xa7, 0x8c, 0x7f, 0x26, 0x13,
- 0x9f, 0x90, 0x60, 0x1c, 0xef, 0x36, 0xfa, 0x79, 0x43, 0x03, 0x7d, 0xf0,
- 0x69, 0xd5, 0x1d, 0x95, 0x04, 0xef, 0xbc, 0x24, 0x43, 0x7b, 0xd5, 0x7d,
- 0x85, 0x17, 0xd6, 0x7d, 0x43, 0x95, 0x92, 0xa7, 0xd7, 0x64, 0x65, 0xe4,
- 0x47, 0x62, 0x8b, 0x75, 0x35, 0x65, 0x85, 0xfd, 0x4e, 0x72, 0x9e, 0x89,
- 0x07, 0xd4, 0x3c, 0x4d, 0xf8, 0x4d, 0xbc, 0x5b, 0x60, 0x86, 0x2a, 0xf3,
- 0x5c, 0x77, 0xa4, 0x4b, 0x7c, 0x0e, 0xce, 0x37, 0x95, 0x5e, 0xc1, 0xb8,
- 0x2c, 0xa3, 0x6e, 0xe4, 0xfb, 0xb4, 0x3e, 0xff, 0xbc, 0xa7, 0x9d, 0x67,
- 0xf0, 0x79, 0x94, 0x95, 0x97, 0x36, 0xa7, 0xed, 0xe3, 0x4a, 0x0e, 0x1e,
- 0x06, 0xdf, 0xff, 0x04, 0x75, 0x1f, 0x45, 0xca, 0x39, 0xa6, 0x57, 0xd7,
- 0x9d, 0xfc, 0xfe, 0xb0, 0x0c, 0x42, 0x2e, 0x98, 0x7f, 0x58, 0x8a, 0xea,
- 0xee, 0x10, 0xd2, 0x32, 0x9f, 0xa9, 0xeb, 0x1d, 0x6d, 0x4f, 0x49, 0xcb,
- 0x5e, 0xfd, 0xdd, 0x56, 0x20, 0x4f, 0x7b, 0x74, 0xbb, 0xf1, 0x55, 0x5e,
- 0x3d, 0x70, 0x19, 0xde, 0x88, 0xae, 0xe2, 0x0d, 0x7f, 0xac, 0x62, 0x7b,
- 0x80, 0x35, 0xfc, 0x39, 0xf8, 0x58, 0xc3, 0x97, 0xf3, 0x49, 0x89, 0x40,
- 0x8e, 0xc3, 0x6b, 0x72, 0x0c, 0xdc, 0xe3, 0xef, 0x99, 0x29, 0x9e, 0xdb,
- 0x29, 0x3e, 0x53, 0x0e, 0x29, 0xbf, 0x5c, 0xc7, 0xfa, 0xb5, 0xbe, 0xf1,
- 0x97, 0xac, 0xf5, 0x85, 0xf6, 0x00, 0x3f, 0xfc, 0xd3, 0xf6, 0xc1, 0xd7,
- 0xda, 0xd7, 0xf6, 0xc1, 0x35, 0xbf, 0xa1, 0x7d, 0xb0, 0x51, 0x2e, 0xeb,
- 0x65, 0xca, 0x84, 0x3c, 0x71, 0xbd, 0x28, 0x4f, 0x94, 0x23, 0xf2, 0x92,
- 0xfa, 0xb4, 0x91, 0xbe, 0x53, 0xe2, 0xa2, 0xfa, 0x3e, 0x62, 0x1a, 0x3a,
- 0xa8, 0x3d, 0x54, 0x86, 0x5f, 0x5e, 0x5c, 0xba, 0x49, 0xc9, 0xf4, 0xd3,
- 0x35, 0xea, 0xa5, 0x2b, 0xcd, 0x7d, 0xbd, 0xce, 0xcd, 0x6f, 0xd0, 0xb9,
- 0xf9, 0x55, 0x9d, 0xdb, 0xa6, 0xfd, 0xa5, 0x7f, 0x8a, 0xce, 0x8d, 0xd7,
- 0x9d, 0x85, 0x04, 0xe7, 0x20, 0x12, 0xca, 0xf6, 0x36, 0xcb, 0xae, 0xd9,
- 0xb8, 0x8c, 0xcc, 0xec, 0x96, 0x3f, 0x9a, 0x99, 0x56, 0xf7, 0x82, 0xfe,
- 0xca, 0x4d, 0x26, 0xee, 0x0f, 0x79, 0xf2, 0x61, 0xf8, 0xbb, 0x13, 0x9d,
- 0x0d, 0xb2, 0xeb, 0xfd, 0xea, 0x7c, 0xcf, 0xcc, 0x86, 0x3a, 0x84, 0x91,
- 0xe7, 0x9c, 0x6b, 0xbb, 0x56, 0x88, 0x77, 0xc4, 0x1a, 0x65, 0x22, 0xde,
- 0x22, 0xbb, 0x81, 0x9d, 0x0a, 0x57, 0xb9, 0xea, 0x9b, 0xed, 0x8c, 0x3a,
- 0x3f, 0xe9, 0xde, 0xee, 0x8f, 0x0b, 0x3e, 0xb4, 0x9a, 0xf2, 0xe7, 0xb5,
- 0x6e, 0xf5, 0xfd, 0xf1, 0x0b, 0xa5, 0x3f, 0x6f, 0x5b, 0x9f, 0xe7, 0xf3,
- 0x7f, 0x42, 0x9d, 0x38, 0x78, 0x55, 0x7f, 0xdf, 0x26, 0xac, 0xf8, 0x59,
- 0x2c, 0x8f, 0xab, 0x7b, 0x4c, 0x17, 0xc3, 0xe4, 0x97, 0xf2, 0x9b, 0x12,
- 0xd9, 0x30, 0x30, 0xce, 0x2c, 0x90, 0xb4, 0x43, 0x9f, 0x4f, 0xe3, 0x4f,
- 0xe8, 0xff, 0x7d, 0xea, 0x3c, 0x75, 0x05, 0xbc, 0xf1, 0x54, 0xbc, 0x35,
- 0x1f, 0x27, 0xae, 0x5f, 0xbb, 0xb3, 0x7b, 0x39, 0xbe, 0xf7, 0xbf, 0xf1,
- 0xd2, 0xb1, 0x7f, 0x1d, 0x9f, 0xd1, 0x3e, 0xb8, 0x3a, 0xcb, 0xda, 0xec,
- 0xff, 0x50, 0xf8, 0xdf, 0xec, 0x67, 0x4b, 0xc4, 0x76, 0xf6, 0x91, 0xb2,
- 0xf4, 0x6f, 0x57, 0xb1, 0x26, 0xf2, 0xb7, 0x82, 0x75, 0x3a, 0x96, 0x08,
- 0xec, 0x79, 0xa8, 0xeb, 0x6c, 0xbd, 0x1f, 0xc8, 0x3e, 0x62, 0xea, 0x0e,
- 0xc4, 0xda, 0xff, 0xbd, 0x61, 0x4c, 0x25, 0x13, 0xba, 0xab, 0x34, 0x2d,
- 0xe1, 0xb9, 0x31, 0x89, 0x1c, 0x63, 0xfc, 0x3a, 0x23, 0xc5, 0xb8, 0x27,
- 0xf7, 0xb9, 0xeb, 0x7d, 0x93, 0x2e, 0x63, 0x23, 0xed, 0x0f, 0xcb, 0xd0,
- 0xc9, 0x47, 0x25, 0x3a, 0xc7, 0x77, 0xeb, 0xce, 0x2e, 0xa0, 0x8f, 0xb6,
- 0x48, 0x39, 0xce, 0x18, 0x6e, 0x54, 0x9d, 0x05, 0x9f, 0x1f, 0x5f, 0x90,
- 0x22, 0xb0, 0x42, 0x5e, 0xe9, 0x16, 0xa4, 0xab, 0xbe, 0xc4, 0xf4, 0x76,
- 0xee, 0x29, 0xf8, 0x98, 0xa1, 0x89, 0x72, 0x54, 0xdd, 0xc9, 0x39, 0x1f,
- 0x67, 0x5d, 0xf8, 0xef, 0x73, 0xc4, 0x19, 0xd0, 0x1d, 0x63, 0x12, 0x62,
- 0x3e, 0x3c, 0xb7, 0x86, 0x33, 0xa8, 0x13, 0x86, 0xdc, 0xb8, 0x44, 0x4e,
- 0xf9, 0x73, 0xe7, 0x3f, 0x52, 0x32, 0x16, 0x76, 0x4b, 0xf8, 0x18, 0x9f,
- 0xeb, 0xfd, 0x21, 0x62, 0x77, 0xd8, 0x86, 0xb3, 0x9f, 0x45, 0x7f, 0x7c,
- 0x97, 0xd1, 0xdf, 0xc2, 0x22, 0x5f, 0xf9, 0xc7, 0xfe, 0xcf, 0x04, 0xca,
- 0xfe, 0xff, 0x07, 0x3b, 0x97, 0x22, 0x9a, 0xb0, 0x4e, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = {
- 0x08000f04, 0x08000f4c, 0x08000f80, 0x08000fcc, 0x08001000, 0x00000000
-};
-
-static struct fw_info bnx2_com_fw_06 = {
- /* Firmware version: 4.0.5 */
- .ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
-
- .start_addr = 0x080000f8,
-
- .text_addr = 0x08000000,
- .text_len = 0x4eac,
- .text_index = 0x0,
- .gz_text = bnx2_COM_b06FwText,
- .gz_text_len = sizeof(bnx2_COM_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_COM_b06FwData,
-
- .sbss_addr = 0x08004ee0,
- .sbss_len = 0x38,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08004f18,
- .bss_len = 0xbc,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08004eac,
- .rodata_len = 0x14,
- .rodata_index = 0x0,
- .rodata = bnx2_COM_b06FwRodata,
-};
-
-/* Initialized Values for the Completion Processor. */
-static const struct cpu_reg cpu_reg_com = {
- .mode = BNX2_COM_CPU_MODE,
- .mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT,
- .mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA,
- .state = BNX2_COM_CPU_STATE,
- .state_value_clear = 0xffffff,
- .gpr0 = BNX2_COM_CPU_REG_FILE,
- .evmask = BNX2_COM_CPU_EVENT_MASK,
- .pc = BNX2_COM_CPU_PROGRAM_COUNTER,
- .inst = BNX2_COM_CPU_INSTRUCTION,
- .bp = BNX2_COM_CPU_HW_BREAKPOINT,
- .spad_base = BNX2_COM_SCRATCH,
- .mips_view_base = 0x8000000,
-};
-
-
-static u8 bnx2_CP_b06FwText[] = {
- 0x9d, 0xbc, 0x0d, 0x78, 0x13, 0xe7, 0x99, 0x2e, 0x7c, 0xcf, 0x48, 0xb2,
- 0x65, 0x5b, 0xb6, 0xc7, 0xb6, 0x0c, 0x22, 0x65, 0x41, 0x83, 0x47, 0x20,
- 0x62, 0x27, 0x1d, 0x81, 0x49, 0x94, 0xac, 0x36, 0xa8, 0xc6, 0x01, 0x93,
- 0x90, 0xc6, 0x34, 0xb4, 0x75, 0x7a, 0xd2, 0x8d, 0x62, 0x0c, 0x21, 0x84,
- 0x10, 0x67, 0x9b, 0x9e, 0xe3, 0x7c, 0x5f, 0xce, 0x5a, 0x35, 0x06, 0x0c,
- 0xc8, 0x96, 0x31, 0x0e, 0x90, 0xfd, 0x7a, 0x9d, 0x18, 0x6c, 0x30, 0x49,
- 0x65, 0x8b, 0x34, 0x74, 0x97, 0xf4, 0xa3, 0x45, 0x07, 0xf2, 0xe3, 0xfc,
- 0x35, 0xa4, 0xed, 0x76, 0xdb, 0x3d, 0x39, 0x89, 0x0f, 0x25, 0x84, 0xb4,
- 0xdd, 0xfc, 0xb4, 0xdd, 0x2d, 0x69, 0x9b, 0xcc, 0x77, 0x3f, 0x23, 0x09,
- 0x0c, 0x4d, 0x7f, 0xf6, 0xf3, 0x75, 0xcd, 0x65, 0xcd, 0xcc, 0xfb, 0xf3,
- 0xbc, 0xcf, 0xfb, 0x3c, 0xf7, 0x73, 0x3f, 0xef, 0xbc, 0x33, 0xb3, 0x80,
- 0x62, 0xe4, 0xfe, 0x4a, 0x79, 0x5c, 0x5d, 0xdf, 0xbe, 0x1a, 0x8b, 0xae,
- 0x36, 0xe5, 0xdc, 0xe9, 0x82, 0x13, 0x7f, 0xe1, 0x9f, 0xff, 0x2f, 0x2d,
- 0x38, 0xe5, 0xcf, 0x01, 0x68, 0xf9, 0x7e, 0xe5, 0x80, 0x5b, 0x8d, 0x3c,
- 0xf3, 0x5f, 0x1a, 0x0c, 0xb8, 0x1d, 0x91, 0x9e, 0xd6, 0xd5, 0x06, 0x10,
- 0x4d, 0xd5, 0xfa, 0x97, 0xe0, 0x23, 0x2b, 0xee, 0x75, 0x42, 0xae, 0xff,
- 0x55, 0xe4, 0xf7, 0x9d, 0xdf, 0xb9, 0x56, 0x7f, 0x7f, 0xc8, 0x01, 0xb7,
- 0x16, 0xe9, 0x80, 0x36, 0x17, 0xee, 0x99, 0xac, 0xf3, 0xf5, 0x79, 0xdb,
- 0x15, 0x94, 0xe5, 0xdb, 0x3a, 0x67, 0x7d, 0x67, 0x9e, 0x2f, 0x56, 0x14,
- 0xd1, 0x70, 0x3c, 0x8d, 0xe6, 0xba, 0xde, 0x4e, 0xab, 0xd4, 0x08, 0xc1,
- 0x6d, 0x18, 0x2d, 0xbd, 0x8a, 0x27, 0xbc, 0x7e, 0x11, 0x3c, 0x85, 0x06,
- 0xe2, 0x57, 0x44, 0xd0, 0x7c, 0xe5, 0x58, 0x71, 0xdc, 0x19, 0x71, 0xa3,
- 0x29, 0xed, 0x8e, 0x7f, 0x2a, 0x62, 0x60, 0x59, 0xfa, 0xfa, 0x62, 0x94,
- 0xb9, 0xd1, 0x9d, 0xfe, 0xa8, 0x28, 0xdb, 0x5e, 0x73, 0xee, 0xff, 0xec,
- 0xaa, 0xec, 0xff, 0x69, 0x31, 0x67, 0x04, 0xd8, 0x9c, 0xb0, 0xac, 0x82,
- 0xc8, 0x6d, 0xb7, 0xa9, 0x11, 0xc3, 0x77, 0x10, 0x8b, 0xd1, 0xaa, 0xe1,
- 0xe1, 0x2d, 0xf5, 0xbf, 0x54, 0x4e, 0x0c, 0xb2, 0xe1, 0x51, 0x07, 0xa2,
- 0xda, 0x33, 0xfc, 0x3f, 0x6b, 0x56, 0x4b, 0xd8, 0xc0, 0xde, 0xd1, 0xf3,
- 0xbc, 0xee, 0xb4, 0xaf, 0x6d, 0xda, 0x33, 0x6b, 0xd6, 0xed, 0xe1, 0x67,
- 0xf0, 0xe8, 0xa8, 0xfc, 0xbe, 0x1b, 0x9d, 0x75, 0x0a, 0x26, 0x6f, 0x5b,
- 0x0b, 0x87, 0x61, 0xa0, 0x7b, 0x8f, 0xe2, 0xec, 0xaa, 0x53, 0x11, 0xf5,
- 0xea, 0xc1, 0x18, 0x95, 0xef, 0x34, 0x10, 0x2b, 0x8c, 0x84, 0x9d, 0xef,
- 0x24, 0x22, 0x9a, 0xc3, 0xb0, 0xac, 0x60, 0x68, 0x3a, 0x1c, 0x15, 0x96,
- 0xf5, 0xb4, 0xe9, 0x81, 0xff, 0x8b, 0xcf, 0x21, 0x3e, 0xdc, 0x0c, 0xd5,
- 0x78, 0x0e, 0x5d, 0xc3, 0xcf, 0xe1, 0xb1, 0x5d, 0xc5, 0x98, 0xac, 0xe2,
- 0x78, 0x93, 0x3e, 0x7c, 0x67, 0x9e, 0xf4, 0x2d, 0x72, 0xd4, 0xf1, 0x70,
- 0x63, 0xd2, 0xf1, 0x06, 0xff, 0x4b, 0x99, 0xf3, 0xd6, 0xe4, 0xf4, 0x8b,
- 0x65, 0x36, 0xb3, 0x4c, 0xf7, 0x65, 0x65, 0xe2, 0xc3, 0x11, 0xbc, 0x94,
- 0x50, 0xb0, 0x3e, 0x54, 0x86, 0x68, 0x85, 0x8c, 0xd7, 0xb2, 0x46, 0xcd,
- 0xb3, 0xd6, 0xa4, 0x26, 0x7d, 0x4d, 0xe0, 0x65, 0xde, 0xdb, 0x12, 0x3a,
- 0x63, 0x65, 0xbc, 0xd2, 0x5e, 0x3b, 0x6d, 0x67, 0x25, 0xaf, 0x3b, 0x91,
- 0x4c, 0x20, 0x56, 0x16, 0xb9, 0x8d, 0xe7, 0xba, 0xf9, 0xae, 0xe2, 0x76,
- 0xbf, 0x97, 0x70, 0x7f, 0xb1, 0xd4, 0x50, 0x1f, 0x2c, 0xa7, 0x01, 0xbd,
- 0x42, 0x99, 0x8f, 0x9a, 0x6b, 0xe1, 0x32, 0x1e, 0x10, 0x5b, 0xe3, 0xb8,
- 0x7e, 0x68, 0x61, 0x7a, 0xbe, 0xbe, 0xb4, 0xeb, 0xc6, 0x96, 0xa4, 0x65,
- 0x6d, 0x33, 0xa3, 0xd7, 0x15, 0xd1, 0x20, 0x4e, 0x26, 0x9a, 0xe1, 0x8e,
- 0x04, 0xfc, 0xe7, 0x10, 0xc6, 0x92, 0xb4, 0x17, 0xcf, 0x26, 0xe0, 0x6c,
- 0x98, 0xe7, 0x45, 0x57, 0x3a, 0x82, 0x1b, 0xd3, 0x26, 0x1a, 0xd3, 0x7f,
- 0xde, 0xb2, 0x6e, 0x4e, 0xfa, 0x39, 0x86, 0x8f, 0xac, 0xec, 0x18, 0x64,
- 0x7c, 0xd9, 0xff, 0xdd, 0xc9, 0x2b, 0xb0, 0x9d, 0x73, 0xb4, 0x95, 0xf3,
- 0xb7, 0x3c, 0x94, 0x89, 0x16, 0x41, 0x37, 0xcf, 0x21, 0x82, 0xa5, 0x69,
- 0x83, 0x73, 0x1a, 0xc1, 0x92, 0x64, 0x8d, 0x36, 0x8c, 0xf9, 0x88, 0xfa,
- 0xb2, 0x36, 0xbd, 0x83, 0xe3, 0x6d, 0x0d, 0x34, 0xa3, 0x94, 0x36, 0x92,
- 0x5a, 0x14, 0x46, 0x03, 0xfb, 0x5f, 0xf1, 0x17, 0xf4, 0x7f, 0x2b, 0xfb,
- 0x7f, 0x97, 0xfd, 0x67, 0xec, 0xfe, 0xe1, 0xbc, 0x89, 0xe7, 0x6e, 0xda,
- 0xe3, 0xf6, 0x94, 0xd3, 0xb9, 0x3c, 0xe9, 0xc5, 0xb6, 0x94, 0x49, 0x9b,
- 0x93, 0x5b, 0x3e, 0x6c, 0x19, 0x9c, 0x89, 0xad, 0x83, 0xba, 0xef, 0x79,
- 0xfe, 0xde, 0x34, 0x72, 0x05, 0x36, 0x0f, 0x2a, 0xd8, 0x6f, 0x5c, 0x81,
- 0x2e, 0xfe, 0xde, 0x3b, 0x38, 0x0b, 0x8f, 0x0e, 0x3a, 0x10, 0xae, 0xba,
- 0x74, 0x1c, 0x93, 0x8e, 0x2b, 0x10, 0x1f, 0xf1, 0xa3, 0x2b, 0xf1, 0xa2,
- 0xad, 0xc3, 0xd2, 0xc8, 0xff, 0x9b, 0xf7, 0x63, 0xfa, 0x8e, 0x1f, 0xab,
- 0x13, 0x1a, 0xba, 0x92, 0x0e, 0xb1, 0x4b, 0xfe, 0xfd, 0x92, 0xf7, 0x34,
- 0x6c, 0x4a, 0xe7, 0xeb, 0x8b, 0x9f, 0xf9, 0xd1, 0x90, 0x98, 0xa0, 0x9f,
- 0xd4, 0xd3, 0x47, 0x4c, 0x7c, 0x37, 0x5d, 0x87, 0x7f, 0x4a, 0x07, 0xf1,
- 0x8f, 0xd4, 0xc3, 0xb7, 0xd2, 0x7e, 0x1c, 0x49, 0xcf, 0xc4, 0x53, 0x69,
- 0x1f, 0xbe, 0x49, 0xfd, 0x3f, 0x99, 0x6e, 0xa6, 0xed, 0x6a, 0x38, 0x9c,
- 0x16, 0xfd, 0x15, 0x50, 0xde, 0x62, 0x6c, 0x1a, 0xac, 0x09, 0x9e, 0xa4,
- 0x6d, 0xfc, 0xa3, 0x79, 0x13, 0x32, 0x95, 0xf5, 0xb6, 0x4d, 0x6d, 0xe3,
- 0xf5, 0xed, 0x83, 0x35, 0xd1, 0x2b, 0x15, 0xcb, 0x52, 0x43, 0xb5, 0xe1,
- 0x13, 0xaa, 0x8a, 0x49, 0xaf, 0xee, 0xcf, 0xa8, 0xba, 0x3f, 0x0a, 0x17,
- 0x12, 0xb4, 0xed, 0x78, 0xb5, 0x3e, 0x14, 0xa7, 0x4d, 0x78, 0x8d, 0x7d,
- 0x40, 0x99, 0xee, 0x8f, 0xab, 0x6e, 0x6c, 0x4d, 0xea, 0x7b, 0xe3, 0xaa,
- 0x07, 0xf1, 0x74, 0x31, 0xfe, 0x6d, 0x50, 0xef, 0x89, 0xab, 0x9f, 0x45,
- 0xbc, 0xd2, 0xb2, 0xbe, 0x19, 0x42, 0xfb, 0xf4, 0x08, 0xa2, 0xd5, 0x11,
- 0xc4, 0x66, 0x45, 0xbc, 0x48, 0x26, 0x81, 0x77, 0x7b, 0x0d, 0xdf, 0xbf,
- 0x28, 0xcd, 0xf8, 0x6a, 0xb3, 0xee, 0xf7, 0xab, 0xb5, 0xf1, 0x61, 0x75,
- 0x11, 0x5d, 0x12, 0x7e, 0x5f, 0x64, 0x19, 0x3a, 0xec, 0x6b, 0x0a, 0x34,
- 0xc3, 0x83, 0x4d, 0xc9, 0xeb, 0x10, 0xf3, 0xd6, 0xb4, 0xec, 0x54, 0x6b,
- 0xce, 0x9b, 0xaa, 0x3e, 0xd1, 0xac, 0x5a, 0xd6, 0x07, 0x0b, 0xdf, 0xb5,
- 0xfc, 0xd3, 0x2c, 0x6b, 0xc1, 0x42, 0xe9, 0xd3, 0x8f, 0x8a, 0x88, 0x89,
- 0x95, 0xf6, 0x1c, 0x14, 0xe3, 0xec, 0x60, 0x25, 0xfb, 0xd0, 0xf0, 0xcf,
- 0xd7, 0xea, 0xc1, 0xb5, 0x6a, 0x31, 0xde, 0x1a, 0x29, 0xc6, 0x69, 0x8e,
- 0xe7, 0x97, 0x83, 0x3e, 0xfc, 0x7a, 0xd0, 0xb2, 0xbe, 0x68, 0xfe, 0x35,
- 0x06, 0x2a, 0xfb, 0xf1, 0x4f, 0xe3, 0x5e, 0xfc, 0x1b, 0x75, 0x7b, 0x26,
- 0x11, 0x7d, 0xa0, 0x0a, 0x7a, 0x74, 0x5c, 0x39, 0x79, 0x67, 0x19, 0x6a,
- 0x9b, 0xcb, 0x14, 0xbd, 0x69, 0x07, 0x74, 0xdf, 0x95, 0x8a, 0x17, 0xe7,
- 0x52, 0x1a, 0x7e, 0x9a, 0xaa, 0x09, 0xff, 0x80, 0x7d, 0xfe, 0x87, 0xf9,
- 0xb4, 0x95, 0x99, 0x26, 0x7a, 0x13, 0x1d, 0x51, 0xcf, 0x49, 0xea, 0x39,
- 0x49, 0x3d, 0x27, 0xa9, 0x67, 0xca, 0x70, 0x24, 0x49, 0x3d, 0x53, 0x77,
- 0xdf, 0xa4, 0x4d, 0x3c, 0x99, 0xa4, 0x8e, 0x93, 0x32, 0x47, 0x61, 0xfa,
- 0xe7, 0xa7, 0xf0, 0xf7, 0xf6, 0xdc, 0xbd, 0x6c, 0xfd, 0x37, 0xaf, 0x8c,
- 0xe9, 0xfe, 0x69, 0x59, 0xfc, 0x91, 0xb1, 0xbd, 0x64, 0xc5, 0x34, 0x19,
- 0x97, 0x8c, 0xcf, 0xd6, 0x9f, 0xbf, 0x5d, 0xf9, 0xaa, 0x82, 0x62, 0xcb,
- 0xda, 0x65, 0xe6, 0xee, 0x7b, 0xf3, 0xe3, 0xfb, 0x8c, 0x92, 0xb5, 0x8b,
- 0x7f, 0x72, 0x53, 0xdf, 0xc1, 0xa8, 0xba, 0x88, 0xe7, 0x7a, 0x3c, 0x8a,
- 0x9b, 0x0a, 0x2f, 0x3d, 0xbf, 0xb6, 0x5a, 0xe6, 0xc3, 0x7f, 0xe1, 0x9c,
- 0xf6, 0x64, 0xf7, 0xf7, 0x45, 0x9e, 0xcb, 0x58, 0x04, 0x53, 0xc5, 0x06,
- 0xbc, 0xb4, 0x97, 0x45, 0xb9, 0x7b, 0x88, 0xab, 0x91, 0x76, 0x34, 0xd7,
- 0xef, 0xb5, 0xfb, 0x28, 0xe8, 0x13, 0xbb, 0x57, 0xf0, 0xee, 0x75, 0x0a,
- 0x4e, 0x84, 0x0c, 0xda, 0xcc, 0x10, 0xfd, 0x1a, 0x28, 0xec, 0x83, 0xdb,
- 0x13, 0x89, 0x20, 0xd1, 0x0b, 0x77, 0x51, 0x24, 0x8c, 0xf9, 0xbd, 0x35,
- 0xeb, 0xce, 0x42, 0x0f, 0xf6, 0x2a, 0x7a, 0x33, 0x50, 0x6b, 0x8e, 0x51,
- 0x8f, 0x57, 0x2a, 0xba, 0xbf, 0x40, 0x81, 0x5b, 0x61, 0xb9, 0x40, 0x6a,
- 0x08, 0x5b, 0xd3, 0xf2, 0x3b, 0x0c, 0x23, 0xf5, 0xeb, 0x7c, 0x5f, 0xb4,
- 0xeb, 0x76, 0xda, 0xf5, 0x59, 0x8e, 0x5d, 0xf7, 0x13, 0x1f, 0xdd, 0xae,
- 0xc8, 0x3a, 0x1c, 0x48, 0xc0, 0x5d, 0x10, 0xd9, 0x80, 0xe7, 0x12, 0x1f,
- 0x57, 0xe7, 0xcb, 0x29, 0x2c, 0xe7, 0x4f, 0x4d, 0x95, 0xe5, 0x0d, 0x2b,
- 0xea, 0xcd, 0xca, 0x52, 0xdc, 0x37, 0x84, 0x1d, 0x49, 0xa9, 0x1b, 0xb1,
- 0xeb, 0x3a, 0xd9, 0x47, 0x77, 0xa2, 0xa6, 0xe9, 0x66, 0x45, 0x0f, 0x3f,
- 0x8e, 0xda, 0xe8, 0x3b, 0x9c, 0xc3, 0x2e, 0xe8, 0xe7, 0xd7, 0x21, 0x2b,
- 0xcb, 0xbc, 0x54, 0x56, 0x8e, 0xc5, 0x29, 0x28, 0xb7, 0x27, 0xe1, 0xf1,
- 0x19, 0x55, 0x39, 0x5f, 0x84, 0x72, 0x0b, 0xe7, 0x4f, 0x35, 0xfc, 0xb8,
- 0x85, 0x36, 0xb4, 0x61, 0x97, 0x85, 0x4d, 0xa1, 0x4a, 0xfa, 0x5b, 0x33,
- 0xca, 0x88, 0x87, 0x1b, 0x35, 0x44, 0xcb, 0x23, 0x61, 0xe5, 0xd6, 0xf4,
- 0xce, 0x9c, 0xfe, 0x9f, 0xae, 0xa4, 0x7c, 0x4a, 0x63, 0xf2, 0xf2, 0xeb,
- 0x1f, 0xe5, 0xc7, 0x77, 0xd9, 0xf5, 0xb9, 0x05, 0x9f, 0x5c, 0xbe, 0x56,
- 0x1b, 0x81, 0xc2, 0x78, 0x51, 0x44, 0xfd, 0xea, 0x8c, 0xd2, 0xd1, 0xa0,
- 0xcb, 0xbe, 0xe6, 0xc0, 0x90, 0x33, 0xea, 0x73, 0xe0, 0xf7, 0x56, 0x74,
- 0x95, 0x5c, 0x2b, 0x46, 0xac, 0xb9, 0xd6, 0xe7, 0x44, 0x6d, 0x78, 0x33,
- 0xfd, 0x6d, 0x72, 0x55, 0x03, 0xef, 0x05, 0xcc, 0x93, 0xa8, 0xf1, 0x6f,
- 0x86, 0xfc, 0xfe, 0x90, 0x36, 0xd2, 0x20, 0x75, 0x59, 0x46, 0x6c, 0x4e,
- 0xd7, 0x4e, 0xc2, 0x8b, 0xcd, 0xb4, 0xbf, 0xc2, 0x88, 0x6e, 0x2e, 0x73,
- 0x38, 0x71, 0x88, 0x38, 0xec, 0x30, 0x7a, 0x50, 0xc8, 0x31, 0x32, 0x3e,
- 0xe2, 0xf1, 0x04, 0xf0, 0x62, 0xbf, 0x85, 0x86, 0x90, 0x07, 0x4b, 0x6c,
- 0xdb, 0x3c, 0xaa, 0xdc, 0x98, 0xfc, 0xd8, 0x1a, 0x72, 0x16, 0x45, 0xd5,
- 0x48, 0xc0, 0x77, 0x9a, 0xd1, 0xbc, 0x20, 0x52, 0xab, 0x39, 0x11, 0x57,
- 0x9a, 0xd2, 0xdd, 0xca, 0xf2, 0x74, 0x8f, 0xb2, 0xc4, 0xc6, 0x9c, 0xa3,
- 0xca, 0xd2, 0xb4, 0x07, 0xa9, 0x7e, 0x05, 0x3b, 0x42, 0x94, 0xab, 0x3a,
- 0x6b, 0xc7, 0xe9, 0x7e, 0x95, 0x18, 0xf9, 0x2e, 0x31, 0x52, 0x0f, 0x83,
- 0x7d, 0x3f, 0x9d, 0xa8, 0xc4, 0x51, 0x62, 0xe1, 0x4f, 0x52, 0xe5, 0x2a,
- 0x8a, 0xaf, 0xc0, 0x8f, 0x47, 0xca, 0x30, 0x36, 0x38, 0x8b, 0xbf, 0xeb,
- 0xf0, 0xca, 0x88, 0x65, 0x75, 0x9b, 0x96, 0x75, 0xc0, 0x3c, 0xaa, 0x34,
- 0xb0, 0xcf, 0xa8, 0x33, 0x1e, 0x2d, 0x8c, 0x04, 0xcc, 0xad, 0xec, 0xd3,
- 0x11, 0x89, 0x2b, 0x51, 0xf6, 0x77, 0x23, 0xfb, 0x5b, 0x9a, 0xeb, 0x2f,
- 0xdb, 0xaf, 0xc8, 0x22, 0xf5, 0xf2, 0x75, 0xc2, 0xac, 0x03, 0x1c, 0x4c,
- 0x04, 0x82, 0xf9, 0x7a, 0x4b, 0x59, 0xe7, 0xc6, 0x0b, 0x75, 0x80, 0xe1,
- 0x44, 0x90, 0x73, 0x2a, 0xb6, 0xee, 0x67, 0xec, 0xf9, 0x1a, 0x9c, 0x46,
- 0x3d, 0x5a, 0x87, 0x85, 0x47, 0x84, 0xd5, 0xec, 0x3c, 0x49, 0xfc, 0x74,
- 0xdb, 0x31, 0x6b, 0xd2, 0x21, 0x71, 0x34, 0x88, 0x5e, 0xfa, 0x75, 0x57,
- 0x52, 0x6c, 0xbc, 0xfe, 0xcb, 0x89, 0x80, 0x82, 0x6f, 0x04, 0x32, 0xcd,
- 0xa5, 0x28, 0xc7, 0xba, 0x90, 0xd8, 0xa6, 0xf9, 0xe5, 0xe7, 0x0c, 0x3d,
- 0xbc, 0x42, 0xe1, 0x9c, 0x05, 0xf4, 0xa6, 0xa5, 0x0a, 0x10, 0x18, 0x03,
- 0xce, 0xa4, 0xca, 0xb1, 0xda, 0x74, 0x40, 0xad, 0x08, 0xa2, 0x27, 0x3d,
- 0x15, 0xd7, 0x4d, 0xe2, 0xb4, 0xb4, 0x17, 0xa4, 0x5f, 0x97, 0x60, 0x99,
- 0x96, 0xb5, 0x69, 0x37, 0xdb, 0x76, 0x07, 0x32, 0x41, 0x95, 0xf1, 0xea,
- 0x10, 0x2f, 0x9c, 0x64, 0x5c, 0x6a, 0x30, 0x5c, 0x68, 0xd3, 0xca, 0xd1,
- 0x60, 0xfe, 0xd6, 0x5a, 0xb6, 0x4a, 0xee, 0x5d, 0xc4, 0xf7, 0x42, 0xf6,
- 0xfb, 0xb6, 0xa1, 0xfb, 0x47, 0x79, 0x92, 0x49, 0x65, 0xaf, 0xc7, 0x19,
- 0x73, 0x36, 0xb1, 0xdd, 0x2d, 0x6c, 0x77, 0xad, 0xa6, 0x47, 0xe3, 0x17,
- 0xca, 0x65, 0x82, 0x0e, 0xe8, 0x9a, 0x94, 0x6d, 0x64, 0xbb, 0xab, 0xd9,
- 0x6e, 0x8f, 0x26, 0xf2, 0xfd, 0xd6, 0x5a, 0xbb, 0x4a, 0xee, 0x65, 0xed,
- 0x23, 0xdb, 0x6e, 0xbd, 0xb4, 0x6b, 0x8e, 0xe6, 0xfa, 0x3a, 0x91, 0x40,
- 0xbf, 0x23, 0xc2, 0x18, 0x59, 0x1f, 0xf0, 0x77, 0x31, 0x5e, 0x36, 0x32,
- 0x76, 0x64, 0x6d, 0x62, 0x6a, 0xbc, 0x42, 0xfc, 0x62, 0x19, 0xb9, 0x26,
- 0xe5, 0xc4, 0xd6, 0x26, 0xa9, 0x67, 0x89, 0x2f, 0x3e, 0xea, 0x57, 0xb0,
- 0xc5, 0x89, 0xc3, 0x09, 0xe2, 0x3f, 0xbe, 0x46, 0xbb, 0xf3, 0xa3, 0x39,
- 0x5d, 0x83, 0xb6, 0x5d, 0x8c, 0x63, 0x66, 0x05, 0x6d, 0x3d, 0x6b, 0x6f,
- 0xcb, 0xd8, 0xf6, 0xa4, 0xdd, 0x76, 0x5c, 0x69, 0x4e, 0xd7, 0x6a, 0x15,
- 0x8c, 0x99, 0xc7, 0x2f, 0x60, 0xe7, 0xec, 0x68, 0x71, 0x24, 0xd0, 0xb4,
- 0x9e, 0x93, 0xe4, 0x66, 0x7c, 0xfb, 0xce, 0xbc, 0x6e, 0xda, 0x45, 0x0f,
- 0xed, 0x30, 0x3b, 0xbf, 0x4d, 0x62, 0x70, 0xc4, 0x38, 0xa8, 0x35, 0x58,
- 0xbb, 0x4b, 0xfe, 0x93, 0x6b, 0xd4, 0x3f, 0xca, 0x6b, 0x35, 0x58, 0x3d,
- 0xfc, 0x0d, 0xda, 0x99, 0xee, 0x13, 0x3b, 0xec, 0xba, 0x20, 0x97, 0xc8,
- 0x24, 0xb2, 0x89, 0x4c, 0xff, 0x37, 0xcb, 0xcd, 0xa4, 0x7e, 0x04, 0x1b,
- 0x2b, 0x29, 0xcf, 0x36, 0xf2, 0x99, 0xa3, 0xca, 0x67, 0x29, 0x4f, 0xc6,
- 0xe5, 0xc5, 0x63, 0x49, 0x91, 0x47, 0x89, 0xce, 0x88, 0xcc, 0xc4, 0xf9,
- 0x64, 0x20, 0xfe, 0x34, 0x44, 0xb6, 0x6e, 0xa5, 0x45, 0xea, 0x27, 0x7b,
- 0x78, 0x2f, 0x2f, 0x23, 0xb4, 0x72, 0x5b, 0xb6, 0xac, 0x4c, 0xb7, 0x72,
- 0xae, 0x5d, 0xc6, 0xfd, 0xa5, 0x28, 0x73, 0xd2, 0xd6, 0xa4, 0xed, 0x9f,
- 0x59, 0x51, 0x6d, 0x13, 0xaf, 0x79, 0x39, 0x4f, 0x6e, 0xc6, 0x75, 0x3d,
- 0x78, 0x8b, 0x43, 0x69, 0xf6, 0x48, 0xbc, 0xa6, 0x7d, 0xa6, 0x52, 0x4e,
- 0x3c, 0x93, 0x58, 0xba, 0xb4, 0xc4, 0xb8, 0x1a, 0xdf, 0x18, 0xf1, 0x61,
- 0x84, 0x73, 0xfb, 0x62, 0x42, 0xe2, 0xeb, 0x4c, 0x3c, 0x91, 0xf2, 0xe0,
- 0x85, 0x84, 0x1f, 0x8f, 0x33, 0xfe, 0x4c, 0x24, 0x0c, 0x1c, 0x4a, 0x79,
- 0xf1, 0x3c, 0xed, 0x79, 0x34, 0xe5, 0xa3, 0xbd, 0xd4, 0x61, 0x38, 0xd5,
- 0x6c, 0x8f, 0xe1, 0xd9, 0xc4, 0xab, 0x32, 0xd6, 0xa0, 0x8c, 0x75, 0x8b,
- 0x3d, 0xd6, 0x7c, 0x9c, 0x9f, 0x79, 0x61, 0x1e, 0x4e, 0x25, 0x6c, 0x1c,
- 0xe8, 0x59, 0xe6, 0x90, 0x79, 0xa0, 0xcd, 0x0e, 0x08, 0x16, 0xe8, 0xfd,
- 0x71, 0x58, 0xd8, 0x6f, 0xce, 0xa0, 0xff, 0xf7, 0x50, 0x5e, 0xea, 0x94,
- 0xe3, 0x87, 0xab, 0x2c, 0x5a, 0x1a, 0x09, 0xc4, 0x7a, 0xa9, 0x77, 0x67,
- 0x44, 0xf4, 0x90, 0xd5, 0xfb, 0x8a, 0xf4, 0x51, 0x45, 0xb8, 0xda, 0x95,
- 0x03, 0x71, 0xab, 0xc4, 0x10, 0x7d, 0x07, 0x88, 0xb3, 0xc0, 0xfc, 0xfd,
- 0x4e, 0x8e, 0x6f, 0x25, 0xc7, 0x6c, 0xa2, 0xc0, 0xa8, 0xd5, 0x2a, 0x29,
- 0xfb, 0xf1, 0x3f, 0x88, 0x81, 0xa2, 0xa3, 0x35, 0xb9, 0xf9, 0x2a, 0x77,
- 0x50, 0x5e, 0x3f, 0x90, 0x9f, 0x17, 0xcb, 0xda, 0x69, 0xe6, 0xe7, 0xa6,
- 0x1a, 0xfe, 0x4a, 0x3d, 0x3e, 0x44, 0x8b, 0x18, 0x49, 0x54, 0x21, 0xae,
- 0xa9, 0xb9, 0xb6, 0xa3, 0x4a, 0x01, 0xf3, 0x07, 0x8c, 0x8b, 0xef, 0x97,
- 0x22, 0xea, 0x94, 0xfa, 0x88, 0x16, 0x44, 0x02, 0xc1, 0xb9, 0xea, 0x54,
- 0x9b, 0x11, 0x1c, 0x90, 0xbe, 0xe2, 0x94, 0xf5, 0x52, 0x2c, 0x18, 0x49,
- 0xe4, 0x71, 0xe3, 0x3f, 0x53, 0xcf, 0x4b, 0x1f, 0x9b, 0xaa, 0x53, 0x91,
- 0x53, 0xf4, 0xaa, 0xa2, 0x75, 0x50, 0xf4, 0xe7, 0xc4, 0x4a, 0x73, 0x51,
- 0x4e, 0xe6, 0x99, 0x68, 0x4b, 0xa8, 0xd8, 0x30, 0xc8, 0xbe, 0x52, 0x0a,
- 0x36, 0x87, 0x96, 0x60, 0xc8, 0x6b, 0xd3, 0x45, 0xb4, 0x26, 0x1a, 0x69,
- 0x63, 0xc4, 0x99, 0x71, 0x3b, 0x7e, 0xda, 0xfe, 0x33, 0x9b, 0x3e, 0xb1,
- 0x2c, 0xfd, 0x20, 0xd6, 0x26, 0x03, 0xfe, 0x93, 0x78, 0x10, 0x6d, 0x69,
- 0x17, 0x62, 0xc3, 0x1e, 0x74, 0xb2, 0x6f, 0xb5, 0x4f, 0xfc, 0x49, 0x43,
- 0xe7, 0xe8, 0x89, 0x17, 0x54, 0xda, 0x67, 0xe7, 0xa8, 0x97, 0xc7, 0x34,
- 0x1e, 0x6e, 0x3c, 0xc4, 0xe3, 0x28, 0xe7, 0xbf, 0x83, 0x18, 0x9c, 0x4e,
- 0x98, 0xb8, 0x9f, 0x32, 0x8d, 0x27, 0xea, 0xb1, 0x91, 0xf2, 0x8d, 0x25,
- 0x1c, 0xf0, 0x4f, 0x0b, 0xe3, 0x3e, 0xea, 0xf2, 0xc9, 0x44, 0x58, 0x79,
- 0x80, 0xff, 0x0f, 0x51, 0x26, 0xc9, 0x47, 0xd6, 0xd1, 0x0e, 0xa2, 0xd3,
- 0x68, 0x27, 0x6a, 0xad, 0xc3, 0x9e, 0x07, 0x88, 0x7f, 0x5c, 0x3e, 0x57,
- 0xba, 0x16, 0x43, 0x7e, 0xbe, 0x80, 0xa1, 0x14, 0x62, 0xee, 0x48, 0x5d,
- 0x63, 0x41, 0x6f, 0xeb, 0x86, 0xc2, 0x48, 0xfb, 0x43, 0x3f, 0xad, 0x9f,
- 0x85, 0x93, 0x9c, 0x13, 0xa7, 0x6d, 0xe3, 0x51, 0xc5, 0x65, 0x18, 0xb6,
- 0x2f, 0xab, 0xe3, 0xed, 0xb9, 0xbc, 0x4a, 0x97, 0x38, 0xc6, 0x3e, 0x44,
- 0x6f, 0xa2, 0x0b, 0xd1, 0xc3, 0x71, 0x6b, 0xc8, 0xf6, 0x77, 0xf1, 0x39,
- 0x27, 0x75, 0xf4, 0x5d, 0xc6, 0x6f, 0xd1, 0x85, 0x94, 0xdb, 0xca, 0xb6,
- 0x44, 0x1e, 0x3b, 0x16, 0xfa, 0xfe, 0xd0, 0x76, 0xa6, 0xca, 0x53, 0x87,
- 0xed, 0x7b, 0x0c, 0xec, 0xd8, 0x53, 0x4b, 0xbb, 0xfb, 0xa5, 0xe5, 0xaf,
- 0x18, 0x60, 0xdd, 0xa9, 0xb2, 0x08, 0x2f, 0x40, 0xae, 0x5d, 0x69, 0x73,
- 0x13, 0xef, 0x1d, 0xa6, 0xad, 0x49, 0xbb, 0x96, 0xb5, 0xe5, 0x42, 0xdc,
- 0x28, 0x88, 0x16, 0x31, 0x6e, 0x1c, 0x4a, 0x04, 0xc2, 0x2f, 0xd8, 0xb1,
- 0xcd, 0x49, 0xdb, 0x90, 0xf9, 0xef, 0xb6, 0xe7, 0x7e, 0xd9, 0x85, 0xb9,
- 0x9f, 0xbc, 0xc0, 0x91, 0xfa, 0x93, 0x53, 0x7d, 0x2a, 0x3b, 0xef, 0xce,
- 0x3e, 0xbd, 0xc7, 0xb6, 0xd3, 0x94, 0xe0, 0x9f, 0x03, 0x8e, 0x01, 0xce,
- 0xb3, 0x79, 0x15, 0xc7, 0x5f, 0xc9, 0x78, 0x52, 0xc0, 0x83, 0x79, 0xe4,
- 0xf0, 0xa7, 0x50, 0x3c, 0x90, 0xb1, 0x8a, 0xf8, 0xbb, 0x29, 0x14, 0x08,
- 0x17, 0x29, 0x37, 0xe0, 0xee, 0x61, 0x07, 0x0a, 0x06, 0x14, 0x3c, 0x6b,
- 0xd6, 0xe5, 0xec, 0x43, 0xe6, 0xfb, 0x2a, 0xdb, 0x3e, 0xe6, 0x8c, 0xcb,
- 0x7c, 0xcb, 0x1c, 0x7b, 0xe0, 0xeb, 0x53, 0xe0, 0x21, 0x6e, 0x94, 0x18,
- 0x32, 0xd7, 0x1a, 0xca, 0xfb, 0x64, 0xae, 0x49, 0x1b, 0x77, 0x87, 0xb1,
- 0x91, 0xf6, 0x50, 0xba, 0xfb, 0x7a, 0xdc, 0xc7, 0x72, 0x1b, 0x78, 0x6f,
- 0xc3, 0x68, 0x25, 0x0f, 0x2f, 0x8f, 0x69, 0x3c, 0xea, 0x71, 0xef, 0x70,
- 0x0d, 0xa2, 0x95, 0x7a, 0xd0, 0xaf, 0x3a, 0x50, 0x39, 0x20, 0x3a, 0x55,
- 0xb1, 0x72, 0x81, 0x02, 0xf3, 0xea, 0x42, 0xa8, 0x73, 0x3f, 0xc9, 0x37,
- 0xff, 0x9c, 0xac, 0x3f, 0x9a, 0x32, 0x87, 0x6e, 0x8e, 0xfd, 0x9f, 0xed,
- 0x39, 0x9c, 0x33, 0x2e, 0x7d, 0x48, 0x2c, 0xb5, 0xe7, 0xf1, 0x4f, 0xf8,
- 0xfe, 0x73, 0x9c, 0x8f, 0x2e, 0x96, 0xf9, 0xc3, 0xf9, 0xc5, 0x85, 0xf9,
- 0x9d, 0xca, 0x49, 0x25, 0xae, 0xeb, 0xe1, 0x21, 0x9b, 0xc3, 0xf8, 0x99,
- 0xcf, 0xe9, 0x71, 0xd1, 0x39, 0x39, 0x8b, 0x5b, 0x35, 0xe0, 0x2f, 0x30,
- 0xee, 0xc0, 0x3d, 0x9c, 0xa7, 0x03, 0x09, 0x75, 0xa9, 0x0b, 0xea, 0x4c,
- 0x17, 0x13, 0xdb, 0x11, 0x53, 0xc7, 0xba, 0x61, 0xe6, 0x4a, 0xc3, 0xa5,
- 0xe8, 0xd2, 0x14, 0xf7, 0xf6, 0xba, 0x45, 0x92, 0xf3, 0xfa, 0xcb, 0x0d,
- 0xa8, 0x25, 0x8c, 0xef, 0x3b, 0x34, 0x38, 0x0b, 0x0c, 0x45, 0x4d, 0xd4,
- 0x35, 0x22, 0x5e, 0x01, 0x67, 0x99, 0x01, 0x85, 0x39, 0x2d, 0x7a, 0x35,
- 0x08, 0xb6, 0x44, 0x0b, 0x8c, 0x07, 0x71, 0x4f, 0x12, 0x56, 0x71, 0x84,
- 0xf9, 0x4e, 0xc4, 0x20, 0x87, 0x0d, 0xf8, 0x0a, 0x94, 0x07, 0xb1, 0x9a,
- 0xbc, 0x61, 0xcd, 0xb0, 0xc8, 0xe1, 0x21, 0x9f, 0x30, 0xfc, 0xad, 0x60,
- 0x8e, 0xdd, 0xac, 0x07, 0x27, 0x99, 0x67, 0xae, 0xa6, 0xee, 0x47, 0x12,
- 0x0f, 0xa2, 0x21, 0x79, 0xdc, 0xf2, 0x90, 0x27, 0x16, 0x18, 0x35, 0xe7,
- 0xbb, 0x10, 0xa3, 0x0f, 0x0b, 0xff, 0x69, 0xc3, 0x43, 0xf4, 0xbf, 0x74,
- 0x42, 0x7d, 0x86, 0xec, 0x01, 0x1d, 0xa3, 0xeb, 0x71, 0xff, 0xe8, 0x4c,
- 0xfa, 0xea, 0x06, 0xfa, 0x2a, 0xb9, 0x50, 0xff, 0x0d, 0xb8, 0x6f, 0xf8,
- 0x06, 0xdc, 0xbb, 0xcb, 0x08, 0x6e, 0xa0, 0xae, 0xd7, 0x0c, 0x33, 0x10,
- 0x4e, 0x93, 0x76, 0xf3, 0xba, 0x12, 0x3e, 0x48, 0x5d, 0xe4, 0xf4, 0x94,
- 0x41, 0x9e, 0xa3, 0xfc, 0xb3, 0xc5, 0x4b, 0xf1, 0x82, 0x7a, 0xc5, 0xbf,
- 0xb7, 0xee, 0xfb, 0xcc, 0xbd, 0x45, 0x76, 0x44, 0x67, 0x18, 0xaf, 0x5a,
- 0x8f, 0x6a, 0x0a, 0x0a, 0x22, 0x88, 0xcf, 0xae, 0x7f, 0xd9, 0x7a, 0x6c,
- 0x95, 0x5c, 0xbf, 0xd5, 0x89, 0x62, 0x95, 0xd7, 0xa4, 0xcd, 0x1d, 0x32,
- 0x47, 0x44, 0xda, 0x4f, 0x6a, 0x33, 0x63, 0xf5, 0x5d, 0x28, 0x4f, 0xde,
- 0x47, 0xac, 0x7d, 0x3a, 0xe1, 0x45, 0x4f, 0x32, 0xcb, 0x9d, 0x6e, 0x4f,
- 0x0b, 0x67, 0x72, 0xa3, 0xb8, 0x57, 0xe2, 0x46, 0x14, 0xeb, 0xf9, 0xbb,
- 0xa8, 0x57, 0x6f, 0x8e, 0x83, 0xc9, 0xbc, 0xd1, 0xc8, 0xb9, 0xa0, 0xbd,
- 0xf6, 0x3a, 0x50, 0x64, 0x34, 0x65, 0x6d, 0xb5, 0x77, 0x85, 0x8d, 0x4b,
- 0x65, 0xbd, 0xdd, 0x36, 0x2e, 0x95, 0xb2, 0x9e, 0x60, 0x92, 0xa7, 0x77,
- 0x15, 0xed, 0x75, 0x26, 0x4a, 0x7a, 0x5b, 0x70, 0x2f, 0xe7, 0x78, 0x2d,
- 0x79, 0xf6, 0x09, 0xb3, 0x3c, 0xc7, 0x3f, 0x9b, 0x70, 0x77, 0x32, 0x8a,
- 0xd6, 0x64, 0x4d, 0xf4, 0xb4, 0xac, 0x25, 0xb9, 0xb2, 0xd8, 0x19, 0xad,
- 0x16, 0x5d, 0x3c, 0x97, 0xc3, 0x08, 0xbd, 0x29, 0xcb, 0xd9, 0x74, 0xcd,
- 0xaf, 0xe4, 0x65, 0xef, 0x46, 0x8c, 0xf9, 0xc5, 0xec, 0x48, 0x33, 0xac,
- 0xa4, 0xc8, 0x1d, 0xb7, 0x7c, 0xcc, 0x19, 0x3d, 0x11, 0xbd, 0x7d, 0xb1,
- 0xc3, 0xe8, 0xf8, 0xb1, 0x12, 0xc4, 0xad, 0x94, 0xa1, 0xa4, 0xb7, 0x13,
- 0xaf, 0x84, 0x74, 0xdf, 0xb7, 0x15, 0xfd, 0xfc, 0x06, 0xfc, 0x18, 0x3f,
- 0xe7, 0xb5, 0x82, 0xde, 0x09, 0x3c, 0x96, 0x7e, 0x1d, 0x67, 0x29, 0xab,
- 0xda, 0xfb, 0xb1, 0xb5, 0xcc, 0x20, 0x18, 0x14, 0xbb, 0x95, 0xb7, 0xd3,
- 0x53, 0x6d, 0xf1, 0x06, 0xac, 0xde, 0x25, 0xf6, 0xa7, 0x07, 0xe3, 0xa0,
- 0x7c, 0x66, 0x99, 0x60, 0x9c, 0xc4, 0x1f, 0xca, 0xdf, 0x4c, 0xd9, 0x2c,
- 0xfa, 0x07, 0xed, 0xc0, 0x1e, 0xc3, 0x43, 0x36, 0x0e, 0x3a, 0xfb, 0xe4,
- 0xc8, 0xeb, 0x39, 0xa2, 0xb4, 0x8e, 0x5e, 0x53, 0x8c, 0x62, 0x5f, 0xce,
- 0x0f, 0xb2, 0x6b, 0x0a, 0x17, 0xeb, 0xfe, 0xd2, 0x1a, 0xf1, 0x5e, 0x5a,
- 0xb7, 0x8c, 0x39, 0x56, 0x39, 0xc7, 0xf3, 0x5e, 0x6f, 0xdc, 0x2a, 0xce,
- 0x8e, 0xa5, 0xe9, 0x55, 0x45, 0x6c, 0x32, 0x48, 0xee, 0xde, 0x89, 0xab,
- 0x42, 0x7a, 0xcb, 0xb7, 0x15, 0x29, 0xab, 0x87, 0x37, 0x28, 0xf9, 0x7e,
- 0x7e, 0x84, 0xd3, 0x23, 0xd2, 0x87, 0xf4, 0x35, 0xc1, 0x9c, 0xeb, 0x52,
- 0x7f, 0x4a, 0xd9, 0xf3, 0xa9, 0x9b, 0x43, 0xe4, 0x75, 0x2b, 0x38, 0xcc,
- 0x92, 0x5e, 0x19, 0x93, 0xa9, 0xdc, 0x3b, 0x2a, 0xf3, 0xba, 0x40, 0x59,
- 0x4f, 0x2c, 0x29, 0xea, 0xad, 0x57, 0xee, 0x21, 0x96, 0x14, 0xee, 0xac,
- 0x51, 0xee, 0xb6, 0x6d, 0xbe, 0x0a, 0x23, 0xfd, 0xd7, 0x28, 0x6d, 0xc3,
- 0xa2, 0x03, 0x37, 0xc7, 0x3e, 0x8d, 0x63, 0xf7, 0xa2, 0x8f, 0xfe, 0xfb,
- 0x4a, 0x6f, 0x9d, 0x72, 0x1f, 0x7d, 0xa3, 0x73, 0x97, 0x8a, 0xc9, 0x2a,
- 0x85, 0x78, 0x47, 0xfe, 0x6b, 0xf8, 0x94, 0xd6, 0xe1, 0xef, 0x3b, 0x25,
- 0xbe, 0x64, 0x70, 0x03, 0x5a, 0x79, 0x6f, 0xa9, 0xe9, 0x42, 0x46, 0xab,
- 0xd5, 0x34, 0xac, 0xc0, 0xea, 0xe4, 0x2a, 0xb4, 0x25, 0x8b, 0xc9, 0x73,
- 0x65, 0xbc, 0x79, 0xb9, 0xf3, 0xf3, 0xf8, 0x20, 0x5a, 0x92, 0x88, 0xcf,
- 0x88, 0x04, 0x3a, 0x66, 0x38, 0xe8, 0xd2, 0xc5, 0x75, 0xca, 0xfd, 0xe9,
- 0x1a, 0x65, 0xcd, 0xae, 0x72, 0x64, 0xb1, 0xe7, 0x61, 0x34, 0xed, 0xa9,
- 0x57, 0xee, 0xde, 0x53, 0x85, 0x49, 0xcd, 0xb2, 0x9c, 0xa1, 0x7a, 0xa5,
- 0x75, 0x8f, 0x65, 0xdd, 0x64, 0x46, 0x9b, 0x8a, 0xc9, 0x77, 0xb7, 0xb1,
- 0xbd, 0xd6, 0x51, 0xe9, 0xe7, 0xf2, 0x76, 0x4d, 0x65, 0xe3, 0x9e, 0x87,
- 0xb1, 0x82, 0x65, 0x5f, 0x09, 0x45, 0x5b, 0x4a, 0x59, 0x56, 0x74, 0xd6,
- 0x3a, 0xfa, 0x19, 0xf6, 0x21, 0xe5, 0x17, 0x4c, 0x69, 0x67, 0x31, 0xaf,
- 0x49, 0x5b, 0x59, 0xdd, 0x89, 0xde, 0x1e, 0xcf, 0xea, 0x2d, 0x2c, 0x7a,
- 0x5b, 0x4e, 0x5d, 0xba, 0x7a, 0x7d, 0x3c, 0x5c, 0xf4, 0x75, 0x1f, 0xd6,
- 0xa4, 0x65, 0x4c, 0x33, 0x89, 0x03, 0xcd, 0xb4, 0xdb, 0x76, 0xb4, 0x52,
- 0xaf, 0x71, 0x2d, 0x6b, 0x9f, 0x17, 0x7d, 0x4b, 0xf7, 0x4f, 0x72, 0xec,
- 0xad, 0x49, 0xd1, 0x4b, 0x33, 0xcb, 0xdb, 0xf7, 0xe9, 0xdb, 0x53, 0xcb,
- 0x5c, 0x3a, 0x57, 0xfb, 0x13, 0xc2, 0x27, 0x0a, 0xc8, 0x7d, 0x0a, 0xd8,
- 0x5e, 0x96, 0x2b, 0x8a, 0xbd, 0x38, 0x68, 0x2f, 0xcf, 0x98, 0xc5, 0xd8,
- 0xe4, 0x95, 0x31, 0x66, 0xf5, 0x0c, 0x15, 0x58, 0xc7, 0x7b, 0x2e, 0xde,
- 0x2b, 0x0c, 0x15, 0xe2, 0x2d, 0x5b, 0x57, 0x59, 0x3e, 0x98, 0xf7, 0xf3,
- 0xa1, 0x0b, 0xfd, 0x1c, 0xab, 0xce, 0xda, 0xd8, 0x26, 0x57, 0x96, 0x33,
- 0xe6, 0xb9, 0x8d, 0x65, 0x0d, 0x98, 0x79, 0x6e, 0x23, 0x71, 0xee, 0x53,
- 0xc2, 0x15, 0x6c, 0x1e, 0xd6, 0x96, 0xeb, 0xb7, 0xcb, 0x0c, 0xd0, 0x4f,
- 0x85, 0xfb, 0x45, 0x94, 0xb6, 0x3d, 0xa7, 0x68, 0xab, 0x92, 0x8b, 0x01,
- 0x1b, 0x79, 0xbf, 0x94, 0xf7, 0x5f, 0x0b, 0xb9, 0x70, 0xd5, 0x34, 0xe9,
- 0xfb, 0x06, 0x74, 0xec, 0x8a, 0xa2, 0x7c, 0x61, 0x00, 0x93, 0xf6, 0x7a,
- 0x59, 0x9e, 0xa7, 0xbb, 0x70, 0xdf, 0xae, 0x8f, 0xad, 0x32, 0x9b, 0x3b,
- 0x1a, 0xb1, 0x71, 0x45, 0xc5, 0x8e, 0x45, 0xc2, 0xd7, 0x5d, 0x8c, 0x57,
- 0xe4, 0xce, 0x92, 0x0b, 0xb8, 0x4a, 0xc8, 0xb9, 0x85, 0x73, 0x06, 0x32,
- 0xb7, 0xab, 0xd0, 0xb4, 0x88, 0x70, 0xcf, 0x99, 0x36, 0xe7, 0x16, 0xee,
- 0xfd, 0xcd, 0xe4, 0xd1, 0x29, 0xdc, 0xfb, 0x02, 0x4f, 0x61, 0xae, 0xd6,
- 0x8c, 0x44, 0xaf, 0x07, 0xee, 0x88, 0xde, 0xbc, 0x59, 0xe9, 0xc4, 0xf2,
- 0x90, 0x61, 0xca, 0x1a, 0xc0, 0xf5, 0x8a, 0x1e, 0x3c, 0x87, 0x20, 0xe3,
- 0xc7, 0x8f, 0x30, 0x32, 0xf8, 0x0f, 0x2e, 0xf1, 0x8b, 0xcd, 0xe9, 0x8b,
- 0xf2, 0xdc, 0x4d, 0x79, 0xdc, 0x59, 0x79, 0xcc, 0x73, 0x54, 0xe4, 0xb3,
- 0xf5, 0x2e, 0xe2, 0xf0, 0x7f, 0xb7, 0xed, 0x76, 0x89, 0x9d, 0x4b, 0xfc,
- 0x77, 0xc6, 0x93, 0x70, 0x71, 0x5e, 0xcf, 0x9d, 0xc4, 0xab, 0x0f, 0x17,
- 0x16, 0x21, 0x44, 0x7b, 0xaf, 0x30, 0x3a, 0x98, 0xcf, 0x7f, 0x6c, 0xc5,
- 0x9d, 0xa4, 0xdf, 0x06, 0xb4, 0xa2, 0x48, 0x94, 0xb2, 0x35, 0x2a, 0x37,
- 0x0d, 0x8f, 0xb3, 0x9f, 0x0e, 0xe6, 0x29, 0x1e, 0x3c, 0x40, 0x5c, 0x79,
- 0x80, 0xfe, 0xf4, 0x00, 0x63, 0xf3, 0x03, 0xa3, 0xff, 0x8b, 0xd7, 0xa7,
- 0xd9, 0xbf, 0x37, 0x27, 0xf3, 0xf6, 0xe5, 0x64, 0x9c, 0x13, 0xfd, 0x6e,
- 0x21, 0x16, 0x48, 0x9c, 0x03, 0x65, 0xb2, 0x70, 0xda, 0x2c, 0xa4, 0xae,
- 0xf5, 0x60, 0x06, 0x09, 0xd7, 0xc5, 0x3c, 0x35, 0x1f, 0x2b, 0x65, 0x1e,
- 0x5d, 0xb8, 0x87, 0x32, 0x06, 0x43, 0xbf, 0xb1, 0x50, 0x21, 0x58, 0x74,
- 0xf9, 0xfd, 0xec, 0xbc, 0x1e, 0xbf, 0xc0, 0x59, 0x15, 0xc9, 0x91, 0xe8,
- 0xef, 0xfd, 0x36, 0x07, 0x7b, 0x8d, 0x3e, 0xd9, 0xb6, 0xeb, 0xc4, 0x7c,
- 0x31, 0x95, 0x35, 0xa3, 0x51, 0x6c, 0xe2, 0xb8, 0x57, 0x0f, 0x3f, 0x9a,
- 0xd3, 0x4b, 0x7e, 0xbc, 0xe2, 0xd3, 0x1e, 0xda, 0x74, 0x36, 0xb7, 0x6a,
- 0x1d, 0x15, 0x2e, 0x5e, 0xc9, 0xff, 0xc2, 0xc5, 0xc5, 0x7f, 0x84, 0x97,
- 0x4f, 0xe3, 0x7f, 0x27, 0x39, 0xa7, 0x70, 0xe9, 0x3a, 0xf4, 0xd0, 0x8f,
- 0x0a, 0x03, 0x75, 0xd8, 0x3a, 0x7a, 0xf9, 0x1c, 0x5d, 0x2e, 0x8f, 0x3d,
- 0x07, 0xcc, 0xc3, 0x5c, 0x82, 0xad, 0x7e, 0xbf, 0x2a, 0x7d, 0x5b, 0x68,
- 0x37, 0x6f, 0xc8, 0x72, 0xa7, 0x4a, 0xb9, 0x36, 0x95, 0x9f, 0xe7, 0xdb,
- 0x99, 0x7a, 0x4d, 0x2d, 0x40, 0x71, 0x9e, 0x37, 0x78, 0x73, 0xb9, 0x0e,
- 0xf3, 0x9b, 0xa4, 0xe8, 0x4b, 0xc6, 0x90, 0xcd, 0x5f, 0xc5, 0x5e, 0x2e,
- 0xc5, 0x83, 0xf8, 0xb4, 0x22, 0x43, 0x6c, 0x25, 0x48, 0x7f, 0xd6, 0xc3,
- 0x4d, 0x0c, 0x35, 0x67, 0x13, 0x88, 0x39, 0x22, 0x4d, 0x8d, 0x6b, 0x12,
- 0x73, 0xb5, 0x67, 0x72, 0xf9, 0xf1, 0x7e, 0xc6, 0x1e, 0xd5, 0x90, 0xb5,
- 0x19, 0xda, 0xc3, 0xb0, 0xe8, 0xa7, 0x43, 0xb9, 0x98, 0x0b, 0x47, 0xc9,
- 0x15, 0x19, 0x57, 0x0d, 0xc9, 0x91, 0x1a, 0x95, 0xa5, 0xc3, 0x52, 0x87,
- 0xf6, 0x70, 0x19, 0x67, 0xcc, 0x8e, 0xb7, 0x0c, 0x9e, 0x01, 0xe1, 0x8a,
- 0x3a, 0x36, 0x90, 0x9b, 0x94, 0x0c, 0xf8, 0x69, 0xef, 0x95, 0x28, 0xde,
- 0x1d, 0xc1, 0xfa, 0x51, 0x0d, 0x45, 0xbb, 0x2d, 0x6b, 0x6e, 0xa8, 0x1b,
- 0x6b, 0xd3, 0xcb, 0x0b, 0x24, 0x9f, 0x73, 0xf6, 0x11, 0x2b, 0x88, 0x2b,
- 0xeb, 0x92, 0x0a, 0x6e, 0x24, 0x07, 0x88, 0xa2, 0x99, 0xdc, 0x5d, 0xf0,
- 0xc5, 0xea, 0x9c, 0x1d, 0x71, 0xd1, 0x4e, 0x56, 0xf1, 0x7e, 0x0b, 0xb1,
- 0xa7, 0x85, 0x58, 0x62, 0x59, 0x1f, 0x5e, 0x8b, 0xce, 0x92, 0xc8, 0x1d,
- 0xc4, 0xa0, 0x1a, 0xe6, 0x0f, 0xc2, 0x39, 0xae, 0x45, 0x1b, 0xb1, 0xbb,
- 0xb0, 0xcf, 0xce, 0xf1, 0xa8, 0x47, 0xc6, 0xd5, 0x34, 0xe3, 0x32, 0x65,
- 0x7f, 0x9e, 0x7c, 0xbd, 0x83, 0x7e, 0x54, 0xde, 0xb7, 0x81, 0xf1, 0xd9,
- 0x83, 0xb2, 0x81, 0x6b, 0xb0, 0x91, 0xd8, 0x7e, 0xdf, 0x2e, 0x3f, 0x52,
- 0x8b, 0x6e, 0xa0, 0x7c, 0x0f, 0x62, 0x7d, 0xd2, 0x90, 0xbc, 0x2e, 0x1a,
- 0x5c, 0xf4, 0x20, 0xfb, 0xa5, 0x7d, 0xec, 0x92, 0x1c, 0xb1, 0x04, 0x4b,
- 0x9a, 0x81, 0x60, 0x9f, 0x60, 0x8e, 0x8c, 0xff, 0x36, 0x59, 0xcf, 0x82,
- 0xd1, 0x37, 0x75, 0x3e, 0xa6, 0x72, 0x39, 0x59, 0x1b, 0x6c, 0xc6, 0x7c,
- 0xc6, 0x2f, 0xb1, 0x21, 0x8d, 0x79, 0x6f, 0x91, 0x62, 0xf8, 0xf6, 0xd3,
- 0x17, 0x25, 0x17, 0xbb, 0xae, 0x2f, 0x1f, 0xaf, 0xf5, 0xcc, 0x62, 0x47,
- 0x27, 0xb1, 0x42, 0x6f, 0xff, 0xad, 0xa2, 0xaf, 0x3b, 0xa5, 0xfc, 0x18,
- 0x07, 0xc7, 0x5e, 0xc7, 0xd0, 0x98, 0x5b, 0x19, 0x1d, 0x93, 0xbe, 0x26,
- 0xd0, 0x9b, 0xfe, 0x73, 0x7d, 0x4d, 0x5d, 0x13, 0x5a, 0x74, 0xc9, 0x3a,
- 0xd2, 0x8d, 0xb9, 0xdc, 0x75, 0xe9, 0x25, 0x9c, 0x5e, 0xe6, 0x44, 0x6c,
- 0xcf, 0x8b, 0xee, 0xe4, 0xc5, 0xb5, 0x8a, 0xfe, 0xc4, 0x76, 0xdb, 0x07,
- 0x9b, 0xd3, 0x62, 0x93, 0xcc, 0xef, 0xcc, 0x39, 0xf6, 0xb3, 0x1b, 0x59,
- 0x5f, 0x58, 0xb3, 0xab, 0xd7, 0xbe, 0x77, 0xd0, 0xfc, 0x2b, 0x64, 0xec,
- 0x6b, 0x8b, 0xe9, 0x7f, 0x8c, 0x93, 0xc4, 0xbd, 0x60, 0xc8, 0x87, 0xc2,
- 0x0a, 0x59, 0x5b, 0xba, 0xb8, 0x1e, 0xb1, 0x61, 0x17, 0x69, 0x84, 0x8d,
- 0x2b, 0x0d, 0xc4, 0xb8, 0x1a, 0xce, 0x77, 0x16, 0x4b, 0xd6, 0xd3, 0x86,
- 0x6e, 0x11, 0x1b, 0x72, 0x65, 0x6d, 0xe8, 0x0f, 0xd7, 0x3c, 0x54, 0x90,
- 0xaf, 0x6a, 0x65, 0x76, 0x2e, 0xda, 0xa8, 0xdc, 0x9a, 0xb3, 0xab, 0xcf,
- 0xa6, 0xbf, 0x53, 0x90, 0xcb, 0x91, 0x2e, 0x2b, 0xff, 0x49, 0x3a, 0xb8,
- 0xe6, 0x2f, 0xd0, 0x81, 0x60, 0xbe, 0xe4, 0x31, 0xa2, 0x83, 0x99, 0x53,
- 0xfc, 0xf2, 0x93, 0xf4, 0x50, 0x9b, 0xd3, 0xc3, 0x62, 0x62, 0x48, 0x25,
- 0x71, 0x4f, 0x38, 0x4b, 0x00, 0x4f, 0x6a, 0x79, 0x3d, 0x38, 0x73, 0x7a,
- 0xd0, 0xff, 0x40, 0x0f, 0xf7, 0x13, 0x5f, 0x4b, 0xd9, 0x56, 0x31, 0x8f,
- 0x77, 0xa9, 0x87, 0x8d, 0xc3, 0x8b, 0xf1, 0x00, 0x7d, 0x69, 0x83, 0xbd,
- 0x5e, 0x23, 0xcf, 0xef, 0x5c, 0x97, 0xe8, 0x66, 0x25, 0xe5, 0xf7, 0x17,
- 0xa8, 0x98, 0x41, 0x1d, 0xf8, 0x6c, 0x3c, 0x95, 0x3e, 0x1a, 0x95, 0xdb,
- 0x87, 0x05, 0xe3, 0x3e, 0xa6, 0x0e, 0x3a, 0x18, 0x07, 0xfe, 0x54, 0x9e,
- 0x21, 0xfd, 0x7f, 0x7c, 0x41, 0x57, 0x7f, 0xbc, 0xdc, 0x8f, 0xa9, 0x03,
- 0x79, 0x26, 0x22, 0x6b, 0xec, 0xf2, 0x7c, 0x44, 0xf4, 0x61, 0x4c, 0xd1,
- 0x83, 0x65, 0x1d, 0x31, 0xe7, 0x21, 0x56, 0xa9, 0xf7, 0x4b, 0x1c, 0xed,
- 0x27, 0xa6, 0x38, 0x98, 0xb7, 0x17, 0x44, 0xa2, 0x14, 0x5b, 0xbd, 0x81,
- 0x4c, 0xa7, 0xce, 0x81, 0x4e, 0x9c, 0x31, 0x8d, 0x9e, 0xb5, 0xf8, 0x2b,
- 0x74, 0x79, 0x2d, 0x1c, 0x60, 0x3b, 0x9b, 0x92, 0x45, 0x58, 0x57, 0x47,
- 0xd3, 0x5c, 0xe9, 0xc1, 0xce, 0x64, 0xbc, 0x85, 0xd0, 0xc2, 0xd8, 0x74,
- 0xe6, 0xf6, 0x44, 0x40, 0x6f, 0xde, 0x40, 0xbe, 0xb6, 0xbc, 0xd7, 0x0d,
- 0xbf, 0x92, 0x8d, 0xcf, 0x03, 0xaa, 0xac, 0x7f, 0x5e, 0xc9, 0xb1, 0x77,
- 0xdb, 0x79, 0xac, 0x7f, 0x9a, 0xf4, 0xe3, 0x47, 0x3c, 0x2d, 0x75, 0xa9,
- 0xb3, 0xb9, 0x0a, 0x96, 0xcf, 0xd5, 0xe3, 0x51, 0xc5, 0xb2, 0x16, 0x84,
- 0x9c, 0xf6, 0xfd, 0xed, 0xe9, 0xda, 0x96, 0xdb, 0xd4, 0xd7, 0xad, 0xec,
- 0x9a, 0xab, 0xae, 0x45, 0x99, 0x0c, 0x1d, 0xff, 0xa3, 0xcf, 0x1d, 0x82,
- 0x90, 0xe7, 0x41, 0x6e, 0x63, 0x25, 0x0e, 0xe5, 0xd6, 0x1d, 0x5d, 0x91,
- 0xc3, 0x5f, 0x3e, 0x60, 0x48, 0xbe, 0x26, 0x7a, 0x92, 0xfe, 0xc4, 0x9e,
- 0x1e, 0x28, 0x14, 0x1c, 0xed, 0x4a, 0x2f, 0xe4, 0x3c, 0xfe, 0x87, 0x35,
- 0xea, 0x9d, 0x5a, 0x76, 0x89, 0x9a, 0x7d, 0x8e, 0x20, 0x65, 0xf3, 0xe5,
- 0xe6, 0x10, 0x57, 0x1a, 0x30, 0x7c, 0x49, 0x9b, 0x92, 0x6f, 0xe7, 0xdb,
- 0xec, 0x2d, 0x14, 0x5e, 0x55, 0x81, 0x42, 0xe2, 0xe3, 0x6f, 0xac, 0x83,
- 0x97, 0xb4, 0xb7, 0xd1, 0x95, 0x6d, 0x6f, 0x0f, 0xcb, 0x48, 0xd9, 0x02,
- 0xd6, 0x79, 0x37, 0xc7, 0x7f, 0xf3, 0x65, 0x3e, 0x77, 0x59, 0x19, 0x66,
- 0x78, 0xc6, 0x5b, 0xd6, 0xfe, 0x4b, 0xca, 0x7c, 0xda, 0x79, 0x69, 0x19,
- 0x27, 0x66, 0x1b, 0xaf, 0x5b, 0xc7, 0x2f, 0x29, 0x33, 0x70, 0x59, 0x99,
- 0x6b, 0x31, 0x56, 0xf7, 0xb8, 0x35, 0x94, 0x9d, 0x9b, 0x0c, 0x5d, 0xd0,
- 0x3d, 0x23, 0xe2, 0xfe, 0xd2, 0x75, 0xf3, 0x74, 0xf2, 0x4d, 0x79, 0x16,
- 0xe5, 0x46, 0x26, 0x3b, 0x37, 0x71, 0x99, 0x1b, 0xd7, 0x82, 0xfc, 0xdc,
- 0x3c, 0x90, 0xab, 0x9f, 0x6f, 0x37, 0x56, 0x70, 0x69, 0xbb, 0xf9, 0xeb,
- 0x8e, 0xcb, 0xe4, 0x9e, 0xb8, 0xac, 0x5c, 0x51, 0xe1, 0x27, 0xd7, 0xfb,
- 0x81, 0xe3, 0xd2, 0xeb, 0xff, 0x43, 0xbd, 0xf4, 0xfc, 0x9a, 0xdc, 0x79,
- 0x5e, 0xff, 0xd6, 0x65, 0xf7, 0x1d, 0x97, 0x9d, 0x3f, 0xa3, 0x7e, 0x72,
- 0x3f, 0xab, 0x2e, 0xeb, 0xc7, 0x5e, 0x83, 0xc7, 0x73, 0x17, 0x70, 0x03,
- 0x8d, 0x05, 0x08, 0x98, 0x4e, 0x05, 0x7e, 0xe2, 0x87, 0xff, 0xf9, 0xcb,
- 0xd6, 0xe2, 0x1b, 0x2f, 0xe0, 0xc7, 0x25, 0x5c, 0x35, 0x56, 0x18, 0x91,
- 0x38, 0x28, 0x3c, 0x55, 0xf8, 0xe2, 0x27, 0xf1, 0xef, 0xb2, 0x58, 0x51,
- 0xa4, 0x1e, 0xfe, 0xb1, 0x99, 0xfe, 0xb7, 0x12, 0xb2, 0x1e, 0xfb, 0x7b,
- 0x72, 0x2e, 0xc3, 0x77, 0x08, 0x33, 0xfd, 0x3f, 0x4d, 0x95, 0xb8, 0x51,
- 0xe6, 0xc1, 0x8d, 0x89, 0x4f, 0xae, 0xa7, 0x46, 0xa0, 0x2c, 0xab, 0xf7,
- 0x31, 0xaf, 0x84, 0xf3, 0xa6, 0x79, 0x98, 0xf2, 0xd7, 0x2c, 0x79, 0xae,
- 0x7a, 0xb2, 0x3e, 0xcc, 0x18, 0x9f, 0x7d, 0x8e, 0xbc, 0x24, 0xad, 0xfb,
- 0xa2, 0x4a, 0xf6, 0x59, 0xf1, 0xba, 0xd0, 0x47, 0xe4, 0x45, 0x9d, 0x94,
- 0xcb, 0x62, 0x5f, 0xc0, 0x86, 0x84, 0x65, 0x3d, 0xc7, 0xfc, 0x5c, 0xf6,
- 0x20, 0xfc, 0x22, 0xf5, 0x3b, 0x6b, 0xc2, 0xeb, 0xc4, 0xdb, 0xc6, 0xd4,
- 0xf6, 0xfc, 0x28, 0x8f, 0x98, 0xcc, 0x13, 0xed, 0x13, 0x75, 0xcc, 0xa8,
- 0x6d, 0x3f, 0x40, 0xbf, 0x9b, 0x1f, 0xd0, 0xfd, 0x7d, 0xf8, 0x3f, 0x96,
- 0xbf, 0x5a, 0x0f, 0x0e, 0x29, 0xf9, 0xf5, 0xef, 0xcb, 0xd7, 0xb9, 0xcb,
- 0x62, 0x2e, 0x8e, 0x6f, 0xbf, 0xbd, 0xd6, 0x5d, 0x40, 0xac, 0x44, 0xcc,
- 0x19, 0x99, 0xe9, 0xdf, 0x9a, 0xb0, 0xc7, 0x49, 0x5e, 0xa9, 0xe0, 0x64,
- 0xfd, 0x4c, 0xff, 0xa6, 0x94, 0x17, 0x3b, 0x18, 0xd3, 0x8b, 0x8c, 0x7a,
- 0x3c, 0x9e, 0x52, 0x71, 0xcf, 0x23, 0x5e, 0xac, 0x21, 0x67, 0x6d, 0xef,
- 0xfd, 0x1a, 0x8c, 0xab, 0x9c, 0xb8, 0x9b, 0xf6, 0xb7, 0x96, 0xae, 0x23,
- 0xf9, 0xc3, 0xfa, 0x5e, 0x27, 0xea, 0xae, 0x2a, 0x43, 0xbc, 0xba, 0x10,
- 0xdf, 0x33, 0x1d, 0xcc, 0xf7, 0x4a, 0x30, 0x64, 0x73, 0x69, 0xc9, 0xe1,
- 0x05, 0x13, 0x45, 0x6f, 0x0e, 0x7b, 0xbd, 0xf5, 0x93, 0xe3, 0xc1, 0x7f,
- 0x58, 0x99, 0xea, 0x1d, 0x36, 0x8e, 0x3b, 0x22, 0xa6, 0x1d, 0x73, 0x81,
- 0x2c, 0x9f, 0xeb, 0xba, 0xe4, 0x79, 0x77, 0xb3, 0x32, 0x3b, 0x12, 0x98,
- 0x58, 0xac, 0x38, 0x10, 0x0e, 0x94, 0xc5, 0xca, 0x23, 0x61, 0x2c, 0x4b,
- 0x77, 0xf9, 0x7c, 0xf6, 0x33, 0xf4, 0x08, 0xce, 0x2d, 0x32, 0x99, 0xfb,
- 0xc3, 0xb9, 0x8c, 0xba, 0x6f, 0xa4, 0x5e, 0xb7, 0x98, 0x1f, 0x59, 0x19,
- 0xdb, 0xef, 0xdd, 0x88, 0x31, 0x07, 0x5b, 0x4b, 0xfd, 0x3a, 0xa8, 0xc7,
- 0x9f, 0xe7, 0xf4, 0x2b, 0x3a, 0x2d, 0x19, 0xfb, 0x9d, 0x75, 0x92, 0xfa,
- 0x75, 0xb3, 0x3d, 0x37, 0xdb, 0x2b, 0x1a, 0xbb, 0x54, 0xcf, 0x85, 0x94,
- 0x67, 0x99, 0x2d, 0xc3, 0x42, 0x79, 0x86, 0xe9, 0x8f, 0x2a, 0x32, 0x1e,
- 0xc1, 0xf7, 0x3f, 0x37, 0xa6, 0x1f, 0x4f, 0xc9, 0x55, 0x44, 0xff, 0x7e,
- 0xea, 0x5f, 0x30, 0x5c, 0xe6, 0xa0, 0x4e, 0xd6, 0xbb, 0x7a, 0x80, 0x97,
- 0x98, 0xcc, 0x2a, 0xa8, 0x32, 0x22, 0x78, 0xaa, 0xd9, 0x83, 0xb7, 0x12,
- 0xa5, 0xf6, 0xb8, 0xaf, 0x9a, 0x6b, 0x59, 0x4f, 0x86, 0xfc, 0xf8, 0x85,
- 0x51, 0x1b, 0x5e, 0xa0, 0xea, 0xcc, 0x1f, 0xbd, 0x48, 0x10, 0x67, 0xbb,
- 0x92, 0xb3, 0x38, 0x5f, 0x5e, 0x6c, 0x4d, 0xa2, 0x9d, 0xf6, 0xe4, 0x77,
- 0x44, 0x80, 0x33, 0x09, 0x23, 0xb8, 0x85, 0xfd, 0x0f, 0x7b, 0xeb, 0xc9,
- 0xd3, 0xd5, 0x46, 0xd2, 0xbd, 0x78, 0x51, 0xc4, 0x88, 0x6f, 0xc3, 0xcf,
- 0xac, 0x21, 0xe2, 0x7c, 0x41, 0x48, 0xd6, 0x1c, 0x67, 0xe3, 0x19, 0xcd,
- 0x81, 0x17, 0x83, 0xcc, 0x87, 0x2b, 0x1c, 0x28, 0x31, 0xde, 0xb6, 0x7e,
- 0xe0, 0x95, 0x7e, 0x64, 0x2c, 0x33, 0x38, 0x0e, 0xc5, 0xc6, 0xc2, 0xad,
- 0xc9, 0x7a, 0xea, 0xfb, 0xf2, 0xfe, 0xff, 0x8f, 0x35, 0xe9, 0x95, 0xfe,
- 0x75, 0xcd, 0xaf, 0x72, 0x0c, 0x7f, 0x14, 0xbb, 0xbf, 0x6f, 0xbd, 0x64,
- 0xb7, 0x79, 0xbb, 0x3b, 0x1b, 0x4f, 0xa5, 0xbd, 0xb7, 0x38, 0x3e, 0x69,
- 0x33, 0xdf, 0x8f, 0xe8, 0xed, 0x8c, 0x5b, 0xfc, 0x79, 0x6b, 0x52, 0xf4,
- 0x27, 0x78, 0x75, 0xd2, 0xc2, 0x34, 0x39, 0x7f, 0xd6, 0x2e, 0x1b, 0xa7,
- 0xbe, 0xba, 0x68, 0x43, 0x8c, 0xe1, 0x3e, 0xd8, 0xbb, 0x3b, 0x34, 0x3b,
- 0x9f, 0xdb, 0xcc, 0x1c, 0x60, 0xc8, 0x5b, 0x8e, 0xad, 0x26, 0xed, 0xce,
- 0x50, 0xe7, 0x38, 0x61, 0xe1, 0xa4, 0x29, 0xe7, 0x2e, 0x4c, 0x7a, 0x1d,
- 0xd8, 0x66, 0x3a, 0xb1, 0xce, 0x50, 0x75, 0xb9, 0xee, 0x08, 0xc9, 0xb9,
- 0x0b, 0xfe, 0x6a, 0x05, 0x3b, 0x18, 0x3e, 0xd6, 0x1b, 0x5d, 0x7e, 0xb9,
- 0xbe, 0x24, 0x24, 0xe7, 0x0a, 0xda, 0xa8, 0x93, 0xb8, 0xa6, 0x60, 0x83,
- 0x21, 0xcf, 0x4d, 0xb3, 0xfc, 0x39, 0x06, 0xcb, 0xda, 0x61, 0x36, 0x5c,
- 0x57, 0xc2, 0x72, 0x67, 0x4d, 0xe1, 0x83, 0x87, 0xef, 0x98, 0x1f, 0x88,
- 0x47, 0x0b, 0xa0, 0xc7, 0x8a, 0xe8, 0xa7, 0x5b, 0x7b, 0x67, 0xb3, 0x9e,
- 0x42, 0x6e, 0xe0, 0xf4, 0x6d, 0x87, 0xc4, 0xcf, 0x80, 0xff, 0xa7, 0x4c,
- 0xb2, 0x86, 0xbc, 0xf3, 0xa8, 0x59, 0xc3, 0x7f, 0x9a, 0xf3, 0x56, 0x6e,
- 0x38, 0xdb, 0x5f, 0x85, 0xbe, 0xae, 0x48, 0x99, 0x17, 0x2c, 0x63, 0xae,
- 0x10, 0x27, 0xbe, 0x8f, 0x8c, 0x39, 0xb1, 0x25, 0x69, 0x68, 0x07, 0x6d,
- 0xfe, 0xe7, 0xa4, 0x2e, 0x9c, 0xcc, 0xcf, 0x03, 0xda, 0x84, 0x92, 0x3f,
- 0x9f, 0x2d, 0xd8, 0x40, 0x3e, 0x2f, 0xf8, 0x16, 0xb7, 0x9e, 0xad, 0x17,
- 0xaa, 0xe1, 0xf6, 0xc7, 0x52, 0x1e, 0x1e, 0x1a, 0x0f, 0xaf, 0x7f, 0x4d,
- 0xca, 0xe7, 0x6f, 0x4b, 0xc1, 0xdf, 0x9a, 0xca, 0xdb, 0x65, 0xde, 0xb7,
- 0x05, 0xdb, 0x2c, 0x72, 0xd6, 0x6c, 0x6e, 0xd6, 0x25, 0xb9, 0x0f, 0xe4,
- 0xb9, 0xdf, 0xe1, 0x3b, 0x9e, 0xa3, 0xad, 0xbb, 0x98, 0x0f, 0x6c, 0x33,
- 0xe2, 0x51, 0x79, 0x0e, 0x69, 0x84, 0x74, 0x5f, 0x81, 0xe2, 0xc7, 0xd6,
- 0xba, 0xdf, 0x72, 0x3e, 0xc9, 0x93, 0x53, 0x9f, 0x29, 0xca, 0xce, 0x87,
- 0xf8, 0x99, 0x60, 0x80, 0x9f, 0xf9, 0x92, 0xcf, 0xdf, 0xc5, 0x7e, 0x36,
- 0xa7, 0xa6, 0xfa, 0x80, 0x82, 0x9b, 0xd8, 0x56, 0x43, 0x08, 0xce, 0xa5,
- 0x75, 0xbf, 0xb1, 0x32, 0xde, 0xec, 0x33, 0xc8, 0x2c, 0xe6, 0x81, 0x36,
- 0x67, 0xf7, 0xe9, 0xdc, 0x5f, 0x27, 0xfb, 0x8e, 0x14, 0x0c, 0xd3, 0xa7,
- 0x36, 0xa5, 0xc5, 0x9e, 0xb2, 0x7a, 0x8d, 0xff, 0x01, 0xfe, 0x98, 0xb8,
- 0x37, 0x89, 0x58, 0x41, 0x44, 0xf0, 0xc7, 0xed, 0x7f, 0x29, 0x55, 0x47,
- 0x0e, 0x2f, 0xcf, 0xf2, 0xdd, 0x9c, 0x67, 0x8f, 0xff, 0xc5, 0xd4, 0xf5,
- 0xb8, 0x67, 0x4f, 0x18, 0xeb, 0xf6, 0xa0, 0xae, 0x88, 0x72, 0x17, 0x86,
- 0x02, 0xfe, 0x51, 0x68, 0xfe, 0x67, 0xa8, 0x87, 0x13, 0x94, 0xed, 0xe4,
- 0x25, 0xb2, 0x89, 0xde, 0xe0, 0xbf, 0x2f, 0xe1, 0x46, 0x2a, 0xf4, 0xa1,
- 0x15, 0xb7, 0x79, 0x86, 0xd7, 0xbf, 0x31, 0xe1, 0x47, 0xc6, 0xe6, 0xac,
- 0xae, 0x22, 0xc9, 0x1f, 0xbb, 0x93, 0xf1, 0x28, 0xd3, 0xe1, 0xdc, 0x9c,
- 0xea, 0x61, 0x99, 0xcf, 0x33, 0x09, 0xb9, 0x17, 0xfd, 0x9a, 0x0a, 0xdd,
- 0xaf, 0x32, 0x7e, 0xf6, 0x9b, 0x62, 0xb3, 0x35, 0xa2, 0x93, 0x20, 0x2b,
- 0xc6, 0x3d, 0x91, 0x40, 0x4b, 0x1d, 0xaf, 0x6b, 0x0b, 0x10, 0xab, 0x88,
- 0x08, 0x27, 0xf4, 0xfa, 0x6b, 0xc7, 0x7d, 0x7e, 0x73, 0x1c, 0xfe, 0x2b,
- 0xc7, 0xa7, 0x8a, 0x40, 0x6e, 0xff, 0x89, 0xb9, 0x9f, 0xd7, 0xbf, 0x36,
- 0x31, 0x1b, 0x6a, 0x24, 0x6e, 0x2d, 0xa9, 0x3f, 0x67, 0xcd, 0x8e, 0x18,
- 0x99, 0x93, 0x94, 0xe1, 0xc3, 0x6b, 0xf5, 0xf8, 0x0c, 0xc7, 0x89, 0x87,
- 0xb4, 0x29, 0x7d, 0xbc, 0x1f, 0xfa, 0xff, 0xdb, 0x47, 0x3e, 0xb6, 0x89,
- 0xfc, 0x12, 0xdf, 0x72, 0x73, 0xaa, 0xe6, 0xc7, 0xa2, 0x70, 0x4e, 0x39,
- 0x1f, 0xc9, 0x7c, 0xac, 0xb2, 0xac, 0x56, 0xc3, 0x97, 0x7b, 0xfe, 0x07,
- 0xda, 0xcb, 0x89, 0xeb, 0x9c, 0x58, 0x4c, 0x7b, 0x6f, 0xf8, 0x6b, 0x27,
- 0xa2, 0xbe, 0x42, 0xc6, 0x50, 0xd9, 0x53, 0xf0, 0x4c, 0xdd, 0xa4, 0x35,
- 0x61, 0xd4, 0xa1, 0x21, 0x2d, 0xcf, 0x63, 0x1d, 0xb4, 0x63, 0x0b, 0x8f,
- 0x9b, 0x72, 0x5f, 0xf0, 0x24, 0x1e, 0x73, 0xd0, 0x26, 0xdc, 0x86, 0xde,
- 0xf2, 0x0f, 0x4a, 0x19, 0x8a, 0x23, 0xce, 0xe0, 0x04, 0xf4, 0xf0, 0x7a,
- 0x72, 0x63, 0x7f, 0xc5, 0x3c, 0x53, 0xd4, 0xfe, 0x4e, 0x22, 0x60, 0x06,
- 0x72, 0xf1, 0xe7, 0x2c, 0xe7, 0xeb, 0xdd, 0x84, 0xb1, 0xee, 0xb9, 0xdc,
- 0xf9, 0xbf, 0xa5, 0xa6, 0xe6, 0xbf, 0x62, 0x77, 0x6e, 0xf7, 0xe6, 0x04,
- 0xde, 0x77, 0xd4, 0xe3, 0xfd, 0xfd, 0x66, 0x01, 0xf3, 0x36, 0xb1, 0x47,
- 0xb7, 0x7b, 0x6b, 0x02, 0x93, 0x4e, 0x5e, 0x3b, 0x6b, 0xce, 0x22, 0x76,
- 0xa9, 0xbc, 0x16, 0x96, 0x58, 0x10, 0xd3, 0x18, 0x47, 0x8b, 0x23, 0x5e,
- 0x77, 0xf1, 0x38, 0xb4, 0x22, 0xa3, 0x8c, 0x79, 0x31, 0x1a, 0x1d, 0x7d,
- 0xba, 0xbf, 0xc9, 0x51, 0xc7, 0xfc, 0xd8, 0xaf, 0xb8, 0x8c, 0x6f, 0x31,
- 0xcf, 0x97, 0xf5, 0xaa, 0x30, 0xc7, 0xed, 0x64, 0x85, 0x9d, 0xd3, 0xd4,
- 0x88, 0x42, 0xcc, 0x2b, 0xc3, 0xbd, 0xda, 0x86, 0xc5, 0x6a, 0xa4, 0x1f,
- 0xb7, 0xd6, 0xbb, 0x1b, 0xcb, 0xc7, 0xf3, 0x3a, 0x41, 0xcc, 0x13, 0x61,
- 0x0e, 0x63, 0x40, 0x2d, 0x8d, 0x88, 0x6e, 0xfc, 0x8d, 0x7d, 0x63, 0x22,
- 0xab, 0xe6, 0xee, 0x1d, 0xf3, 0x14, 0xa3, 0x38, 0x4c, 0x4c, 0xfa, 0x57,
- 0xdf, 0x7f, 0xae, 0xde, 0x64, 0x91, 0xe0, 0xba, 0xcb, 0x90, 0xff, 0xb6,
- 0x3d, 0xb9, 0xdd, 0x91, 0x63, 0x31, 0x77, 0xc0, 0xb2, 0x18, 0x0f, 0x7d,
- 0x50, 0x66, 0x71, 0x3c, 0xf4, 0x29, 0xce, 0x4d, 0x5b, 0xea, 0x23, 0xeb,
- 0x33, 0x4e, 0x3b, 0xd6, 0xbb, 0x0b, 0x23, 0xe1, 0xbb, 0xde, 0x36, 0x7e,
- 0x6f, 0xbd, 0x95, 0x60, 0x5e, 0x4d, 0xdf, 0x2d, 0x20, 0x6e, 0x6f, 0x37,
- 0x9d, 0x4d, 0x4b, 0x15, 0x05, 0xdd, 0xc6, 0x3c, 0xad, 0x88, 0xf1, 0x68,
- 0x13, 0xfd, 0x37, 0xe6, 0x35, 0x82, 0xfb, 0xc1, 0x72, 0xa9, 0xb5, 0x6b,
- 0x5d, 0x91, 0x8d, 0x77, 0x8d, 0xd4, 0x8b, 0xcf, 0x9f, 0xbf, 0xeb, 0x39,
- 0xa3, 0x19, 0xdd, 0xe9, 0x41, 0xf4, 0xa4, 0xb3, 0xfd, 0x64, 0x30, 0xfb,
- 0x13, 0xfa, 0x59, 0xbb, 0xb6, 0x30, 0x22, 0x1c, 0xeb, 0xe8, 0x5d, 0x07,
- 0x8c, 0x28, 0xb6, 0xa4, 0x37, 0xde, 0x75, 0xb6, 0xbe, 0x9f, 0xff, 0xb3,
- 0x75, 0x86, 0x50, 0xfe, 0x89, 0x75, 0x4a, 0x22, 0xd2, 0x47, 0x98, 0x7d,
- 0x6c, 0xbc, 0x6b, 0xdd, 0xa2, 0xaf, 0x63, 0x73, 0x7a, 0xdd, 0x9f, 0xed,
- 0xa7, 0x94, 0x75, 0x8a, 0x23, 0x1d, 0xad, 0x37, 0x05, 0x36, 0xde, 0x95,
- 0x5a, 0xd4, 0xc3, 0x3e, 0x56, 0x31, 0x8e, 0x64, 0xeb, 0x44, 0x15, 0xc7,
- 0x27, 0xea, 0xa0, 0x28, 0xd2, 0xd3, 0x3a, 0x3f, 0xf0, 0x7b, 0x6b, 0x5e,
- 0x6f, 0x81, 0xad, 0x03, 0x17, 0x75, 0xf0, 0xa8, 0xe9, 0xcc, 0x04, 0x1c,
- 0xb6, 0x0e, 0x3a, 0x7c, 0xd4, 0x41, 0x1f, 0x75, 0x90, 0xa9, 0x36, 0xc2,
- 0xef, 0x51, 0x07, 0xf3, 0xc6, 0xd6, 0xae, 0x2d, 0x8a, 0xc0, 0xe9, 0x30,
- 0x5e, 0x77, 0x38, 0x39, 0x17, 0x2e, 0x63, 0x2d, 0xf5, 0xb6, 0xf1, 0xae,
- 0x39, 0x8b, 0x6c, 0x9d, 0x7f, 0xd9, 0x1d, 0xd8, 0x60, 0xef, 0xdd, 0xdb,
- 0x94, 0x6e, 0xe3, 0xd1, 0xc4, 0xe3, 0x61, 0x1e, 0xdd, 0xcc, 0x4d, 0xee,
- 0xa0, 0xae, 0x1a, 0x39, 0x8e, 0x15, 0x94, 0xab, 0x9d, 0xbf, 0x5b, 0xf8,
- 0xbb, 0x83, 0xbf, 0x65, 0x7e, 0xd4, 0x0b, 0xb2, 0xc5, 0x2e, 0xc8, 0xe6,
- 0xa0, 0x3c, 0x1e, 0x62, 0x94, 0x8c, 0x69, 0xe2, 0xcb, 0x37, 0x05, 0x62,
- 0x6c, 0xe3, 0xa9, 0x62, 0xd9, 0xf7, 0xe4, 0x32, 0xe2, 0x3e, 0x27, 0x44,
- 0x3e, 0xbd, 0x65, 0x1d, 0x32, 0xc4, 0xd8, 0xdf, 0x65, 0x31, 0x96, 0xb2,
- 0x95, 0x71, 0x7e, 0x5e, 0x59, 0x34, 0x34, 0xdd, 0x63, 0xc0, 0xe7, 0x36,
- 0xe2, 0xe8, 0x4d, 0x27, 0xa8, 0x03, 0xb1, 0x93, 0x07, 0xa9, 0xbf, 0x4e,
- 0x74, 0x19, 0x27, 0xf4, 0xec, 0xde, 0x89, 0xbd, 0x94, 0x21, 0x48, 0x7e,
- 0xe8, 0x81, 0x33, 0xa2, 0xfb, 0x1b, 0x1d, 0x5d, 0x41, 0x17, 0x68, 0xcb,
- 0xc5, 0x62, 0xcb, 0x71, 0xc6, 0x35, 0xc1, 0x3a, 0xb7, 0xd6, 0x66, 0xe3,
- 0x5f, 0x7c, 0xbe, 0x0b, 0x1e, 0x6d, 0x4d, 0x2a, 0x1f, 0x0b, 0x3c, 0x5a,
- 0x6b, 0x42, 0xfc, 0x4a, 0xd6, 0xfc, 0xc3, 0x76, 0x2c, 0x3f, 0x9e, 0x7e,
- 0xb1, 0x18, 0x65, 0xb6, 0x8f, 0x95, 0x39, 0x8d, 0x6c, 0xbb, 0x1a, 0xdb,
- 0x6d, 0x76, 0x68, 0xb8, 0xe8, 0x23, 0xba, 0xd6, 0xec, 0x90, 0x7d, 0xae,
- 0xf4, 0xfe, 0x54, 0xae, 0x5e, 0x16, 0x27, 0x16, 0xbb, 0x6c, 0x9c, 0x60,
- 0x1b, 0xc5, 0xc0, 0x92, 0xc4, 0xe5, 0xfd, 0x4b, 0x7f, 0xd2, 0x6f, 0x57,
- 0x85, 0x8a, 0x09, 0xfb, 0x99, 0xcb, 0x91, 0x74, 0x0c, 0x83, 0xc9, 0xa9,
- 0x7b, 0xf9, 0xf4, 0xa3, 0x6c, 0xff, 0x70, 0x9c, 0xfa, 0x98, 0x65, 0xc8,
- 0x3e, 0x3f, 0xd9, 0xdb, 0x37, 0x75, 0x5f, 0x9f, 0xc8, 0x56, 0x58, 0x42,
- 0x00, 0xc1, 0x01, 0xe2, 0x4c, 0xb4, 0x59, 0xea, 0x5b, 0xd6, 0x1b, 0xf3,
- 0x82, 0xc8, 0x54, 0x39, 0x31, 0x38, 0x17, 0x18, 0xe8, 0x93, 0x7d, 0x57,
- 0x47, 0x63, 0xab, 0x99, 0x97, 0x45, 0x2b, 0x6b, 0xb5, 0x4d, 0xaa, 0xec,
- 0x99, 0x3a, 0xf6, 0xe5, 0x6e, 0xa3, 0x46, 0xeb, 0x56, 0x33, 0x87, 0x88,
- 0xdd, 0x7b, 0x81, 0x69, 0x25, 0xe2, 0x6b, 0x15, 0x46, 0xb4, 0xa7, 0x02,
- 0x73, 0xe1, 0xaf, 0xb4, 0xf1, 0x32, 0xfe, 0x94, 0x6a, 0x04, 0x57, 0xda,
- 0x38, 0xf8, 0xa1, 0x35, 0xc4, 0xb8, 0xf4, 0x95, 0xb9, 0x3f, 0x28, 0xce,
- 0xe6, 0xd9, 0xd1, 0x75, 0xd3, 0x38, 0x57, 0xbf, 0x58, 0xa0, 0xfb, 0x53,
- 0x8a, 0xe8, 0x48, 0xb8, 0x49, 0x02, 0xdb, 0xc8, 0x75, 0x7f, 0x33, 0x37,
- 0x82, 0x83, 0xfc, 0xff, 0xf3, 0xeb, 0x65, 0x0f, 0xaa, 0x65, 0x05, 0x03,
- 0xf3, 0xc2, 0x15, 0x1c, 0xc3, 0x8b, 0xbc, 0xdf, 0x93, 0x7e, 0xdb, 0x3a,
- 0x3b, 0xcd, 0xe8, 0x5f, 0xc6, 0x40, 0x32, 0x30, 0xae, 0x6b, 0x93, 0xea,
- 0x7f, 0x76, 0x4f, 0x1d, 0xdc, 0x65, 0x1c, 0xcb, 0xf7, 0x02, 0xb5, 0x5a,
- 0x9f, 0xaa, 0x96, 0x88, 0x5e, 0x07, 0xc6, 0x7f, 0x3c, 0x65, 0xaf, 0x47,
- 0x9e, 0x1f, 0xda, 0x6b, 0x1d, 0x3d, 0x43, 0xf4, 0xa9, 0x21, 0x2d, 0x1a,
- 0xa7, 0xde, 0xdd, 0x55, 0x1c, 0xf3, 0x57, 0xe6, 0xde, 0x6a, 0x8f, 0xb3,
- 0xd2, 0x98, 0xc1, 0x31, 0x2a, 0xd0, 0xe6, 0xfe, 0x2c, 0xb7, 0xee, 0xd9,
- 0x40, 0x36, 0x33, 0x64, 0x35, 0xd2, 0x06, 0x0b, 0x58, 0xe7, 0x46, 0x73,
- 0xdf, 0xf4, 0xae, 0x3a, 0xdd, 0xf7, 0x15, 0xc6, 0xce, 0xd0, 0xdc, 0x5f,
- 0x5b, 0x51, 0xcd, 0x69, 0x7e, 0x93, 0xa3, 0xbe, 0x27, 0x21, 0x65, 0x65,
- 0x5e, 0x8d, 0xe8, 0x5c, 0xe5, 0x5d, 0x0b, 0xd5, 0x81, 0xf0, 0x5c, 0x7b,
- 0xfc, 0xc0, 0xdd, 0xa9, 0x04, 0xb6, 0x27, 0xa5, 0x4d, 0x05, 0xcb, 0x02,
- 0xef, 0x58, 0xfe, 0x69, 0x09, 0x6c, 0x4d, 0xff, 0x29, 0xae, 0x37, 0x28,
- 0x71, 0xbf, 0x25, 0x0e, 0x3d, 0x9a, 0x7d, 0xc6, 0x35, 0x5b, 0xd6, 0x94,
- 0x65, 0x0f, 0xd2, 0x5d, 0x89, 0x00, 0xdc, 0xa5, 0xc4, 0xba, 0xb1, 0x80,
- 0x3c, 0x13, 0xf5, 0x22, 0xd3, 0x2c, 0x65, 0x6a, 0xb4, 0x31, 0x64, 0xc8,
- 0xc4, 0x64, 0x7d, 0xb2, 0xa7, 0x24, 0xbb, 0x9f, 0x82, 0x86, 0x57, 0xad,
- 0x6b, 0x67, 0xc8, 0x9d, 0x9a, 0x0c, 0x69, 0x43, 0xc1, 0xfc, 0x40, 0x15,
- 0x6a, 0x57, 0xbe, 0xfe, 0x66, 0x41, 0xa0, 0x80, 0xb8, 0x2d, 0xfe, 0x64,
- 0xb4, 0x9f, 0xc4, 0xbf, 0xd3, 0xd7, 0x65, 0x6f, 0xd9, 0x16, 0xa9, 0xc7,
- 0xb6, 0xe6, 0x22, 0xa5, 0x39, 0xc9, 0x33, 0x64, 0x9f, 0xb2, 0x65, 0xdd,
- 0x14, 0x78, 0xcb, 0x8a, 0x56, 0x53, 0x1e, 0xf2, 0x9f, 0x6c, 0x5d, 0x29,
- 0x93, 0xdb, 0x33, 0xa4, 0x34, 0xdc, 0x25, 0x3a, 0x79, 0xd6, 0x8c, 0x93,
- 0x5d, 0x0b, 0xbe, 0x1e, 0x8b, 0xbd, 0x6d, 0x28, 0xf6, 0xb3, 0xca, 0x65,
- 0x4a, 0x39, 0xe3, 0x95, 0xd3, 0x3f, 0x62, 0xe7, 0xdf, 0x61, 0x62, 0xa1,
- 0xf0, 0x35, 0xc9, 0xa1, 0x9c, 0x78, 0xce, 0xa8, 0xc0, 0xb3, 0x5a, 0x96,
- 0xfb, 0x10, 0x53, 0xf0, 0x6a, 0x62, 0x5e, 0x86, 0x1e, 0x42, 0x0e, 0x69,
- 0xac, 0x3b, 0xaf, 0xfc, 0x3b, 0xf3, 0x2b, 0xe0, 0x95, 0x54, 0x3b, 0x1e,
- 0x95, 0x75, 0x3d, 0xa5, 0xa6, 0xa9, 0xd6, 0x21, 0xfd, 0xb5, 0x63, 0x5b,
- 0x5a, 0xda, 0x3a, 0x16, 0x3b, 0x60, 0xf4, 0xe7, 0x64, 0x15, 0xcc, 0x3c,
- 0x16, 0x7b, 0xce, 0x78, 0xdc, 0x9e, 0x3b, 0x79, 0x7e, 0xd6, 0x63, 0x0a,
- 0xb6, 0x14, 0x43, 0x25, 0x0f, 0x77, 0x18, 0x77, 0xc0, 0x51, 0xf1, 0x75,
- 0xda, 0x9e, 0xec, 0xbf, 0xb9, 0x13, 0xce, 0x0a, 0x17, 0x7d, 0xf3, 0x6e,
- 0xb8, 0x2a, 0x84, 0xfb, 0xe6, 0x79, 0x69, 0x94, 0xf7, 0x45, 0xb7, 0xe7,
- 0x6d, 0xdd, 0x3a, 0x89, 0xa7, 0xdd, 0x92, 0x27, 0x19, 0xe5, 0xd4, 0x91,
- 0xde, 0x42, 0x8e, 0x8c, 0x52, 0x62, 0x13, 0xe3, 0x90, 0xbb, 0x9c, 0x65,
- 0xde, 0xa3, 0xde, 0xe7, 0xf5, 0x96, 0x90, 0x13, 0x5b, 0xd6, 0x87, 0xe4,
- 0xc4, 0xf3, 0x03, 0xb5, 0x19, 0x83, 0xf1, 0x03, 0xb7, 0xe9, 0x4d, 0x71,
- 0xe6, 0x88, 0xab, 0x8d, 0xf3, 0x56, 0x6c, 0x95, 0x94, 0xd1, 0x7d, 0x31,
- 0x25, 0xdf, 0xc7, 0x02, 0xf8, 0xab, 0x2c, 0xb8, 0x22, 0xb2, 0x96, 0x2f,
- 0x6b, 0xb8, 0x0d, 0xf2, 0xcc, 0xb0, 0x59, 0xc6, 0xef, 0x92, 0x75, 0x41,
- 0x44, 0x27, 0x5c, 0x30, 0x32, 0x07, 0x65, 0xce, 0xa6, 0x5b, 0x08, 0x2c,
- 0xfc, 0x1d, 0x73, 0x0b, 0x99, 0x9f, 0x9a, 0x4c, 0x9d, 0x92, 0x09, 0xfa,
- 0xc8, 0x91, 0x9f, 0x80, 0xde, 0x9c, 0xa0, 0xae, 0x1b, 0x43, 0xb2, 0x0f,
- 0xc0, 0xe9, 0x4b, 0xc0, 0xe6, 0xc5, 0xe6, 0x69, 0x7c, 0x06, 0xa5, 0xcc,
- 0x05, 0xe7, 0x8e, 0xad, 0x40, 0x59, 0x45, 0xd4, 0x57, 0x8c, 0x6b, 0x78,
- 0xde, 0x46, 0xbe, 0xff, 0x05, 0x94, 0xad, 0x6c, 0x41, 0x82, 0x63, 0x2f,
- 0x35, 0xbe, 0xc4, 0x6b, 0x0f, 0xa3, 0x2f, 0xe9, 0xe2, 0x38, 0xfe, 0xd5,
- 0x2a, 0xab, 0x16, 0xd9, 0x4c, 0x6f, 0x09, 0xf3, 0xf4, 0xa8, 0xad, 0x0b,
- 0x62, 0x63, 0x52, 0xb8, 0x48, 0x6d, 0x74, 0x3d, 0x98, 0x2b, 0x57, 0xeb,
- 0x2d, 0x6d, 0x4a, 0x07, 0x6d, 0xb6, 0x9b, 0x3a, 0x97, 0xb2, 0x96, 0xb5,
- 0x3c, 0x30, 0x49, 0x1d, 0x77, 0xf0, 0xdc, 0xf0, 0xbf, 0x05, 0xf5, 0x9a,
- 0x42, 0x9c, 0xb2, 0xe2, 0x9a, 0x8f, 0x76, 0xa9, 0xae, 0x12, 0xde, 0xb2,
- 0x34, 0x74, 0xae, 0x44, 0xf6, 0x21, 0x67, 0xed, 0xf4, 0x68, 0x4e, 0x97,
- 0xe7, 0xef, 0xea, 0x36, 0x5e, 0xb5, 0xaf, 0x3b, 0xec, 0xeb, 0xe1, 0xdc,
- 0xf5, 0xa3, 0xbc, 0xfe, 0x3d, 0x5e, 0xef, 0xa1, 0xee, 0xd5, 0x2b, 0xa4,
- 0xfe, 0x5a, 0x53, 0xea, 0x33, 0x45, 0x31, 0xba, 0x73, 0xf3, 0xd1, 0xd1,
- 0x9a, 0x2d, 0xdb, 0xd3, 0x9a, 0x6d, 0xc3, 0xc9, 0x36, 0xe2, 0xd1, 0x62,
- 0x98, 0x28, 0x61, 0x9c, 0x3f, 0x6b, 0x88, 0x5c, 0x9c, 0xbb, 0xb4, 0xc8,
- 0xd5, 0xc6, 0xb8, 0xd2, 0xf5, 0x42, 0x31, 0xe2, 0x1d, 0x33, 0x6c, 0x3b,
- 0x3c, 0x7a, 0x97, 0xec, 0x8f, 0x7b, 0x5b, 0x69, 0xf0, 0xc9, 0xb6, 0xca,
- 0x24, 0x79, 0xe2, 0x43, 0xa6, 0x33, 0x5c, 0xe7, 0x98, 0x97, 0x29, 0x84,
- 0x11, 0x3b, 0xaf, 0x7c, 0x64, 0xe3, 0x43, 0x22, 0xd5, 0xc0, 0x4c, 0x26,
- 0x1e, 0x64, 0x0e, 0x12, 0x4c, 0x53, 0xb7, 0xad, 0x44, 0xec, 0xa3, 0xf6,
- 0x1e, 0x39, 0xe7, 0xc4, 0x0a, 0x34, 0xe8, 0x0e, 0xcc, 0x0b, 0xcf, 0x60,
- 0x26, 0x43, 0xbb, 0x34, 0x0b, 0x1d, 0xba, 0xff, 0x56, 0x7c, 0xc6, 0x23,
- 0xf5, 0x0e, 0xa6, 0x32, 0xeb, 0x8a, 0x39, 0xa7, 0xdf, 0xa0, 0x1c, 0xdb,
- 0x03, 0x22, 0xc7, 0xd7, 0x73, 0x72, 0xb4, 0x30, 0x66, 0x99, 0xda, 0xcd,
- 0x81, 0x9e, 0x0b, 0x7a, 0x7b, 0xc1, 0xd6, 0xdb, 0xc3, 0x3c, 0x2f, 0x64,
- 0xbe, 0x5c, 0x80, 0x13, 0x75, 0xde, 0xdc, 0x7e, 0x37, 0xc9, 0x7d, 0x04,
- 0x7f, 0xcf, 0x7c, 0x69, 0xb5, 0xa1, 0x87, 0x1d, 0x36, 0x67, 0x76, 0x23,
- 0x6e, 0xf3, 0x51, 0x79, 0x76, 0x5e, 0x86, 0xc7, 0xed, 0x72, 0x2e, 0xea,
- 0xa4, 0x04, 0x4f, 0xe4, 0xfc, 0x45, 0xf6, 0x2e, 0x7c, 0xc3, 0xfe, 0xbd,
- 0x97, 0x73, 0xeb, 0xa2, 0xaf, 0xe6, 0x63, 0x94, 0xac, 0x81, 0x6f, 0xb4,
- 0x7d, 0x7f, 0x08, 0xc7, 0xec, 0xff, 0x99, 0x6c, 0xfe, 0x82, 0x6e, 0x53,
- 0xf6, 0xfc, 0x94, 0x60, 0x93, 0x3c, 0x8b, 0x4c, 0x4b, 0x4e, 0x7d, 0x3d,
- 0xb6, 0x70, 0x54, 0x6e, 0x83, 0x1c, 0x43, 0x13, 0x9b, 0xe8, 0x44, 0x9f,
- 0x66, 0x7a, 0xd3, 0x75, 0x53, 0x73, 0x0f, 0x13, 0xfb, 0xeb, 0x7e, 0x6f,
- 0x45, 0xed, 0x7c, 0xe4, 0x94, 0x75, 0xc0, 0x38, 0x11, 0xa2, 0x07, 0xaf,
- 0x2b, 0xb0, 0xf5, 0x7b, 0xfe, 0x2e, 0x7b, 0x9f, 0x20, 0x65, 0x7e, 0x21,
- 0x21, 0x71, 0x74, 0x36, 0x52, 0xa6, 0xc8, 0xe6, 0x6c, 0xde, 0xc1, 0x39,
- 0xe9, 0x4e, 0x06, 0xa2, 0x57, 0xf2, 0xde, 0x04, 0x63, 0xd9, 0x26, 0xea,
- 0x33, 0xd6, 0x2c, 0x3c, 0xa8, 0x0d, 0x7b, 0x69, 0x63, 0xe3, 0xa6, 0x65,
- 0x1d, 0x24, 0x46, 0x94, 0xcf, 0x53, 0x91, 0xa9, 0x6e, 0x43, 0x92, 0xb1,
- 0xe9, 0xa0, 0xd1, 0xf0, 0x99, 0x02, 0xc4, 0xfd, 0x6e, 0xe8, 0xbe, 0xad,
- 0x1c, 0xcd, 0x43, 0x9c, 0xaf, 0x13, 0xa6, 0xf0, 0x33, 0xe7, 0xf9, 0xa5,
- 0x30, 0xc2, 0x8b, 0x1d, 0xff, 0x6a, 0x4d, 0xda, 0xcf, 0x51, 0xbb, 0xfe,
- 0x27, 0x65, 0x68, 0x17, 0xe7, 0x2d, 0xe7, 0x1c, 0xbf, 0x17, 0x90, 0xe7,
- 0xe0, 0x40, 0x6d, 0x6f, 0xc3, 0x3a, 0x91, 0xe1, 0x40, 0xc8, 0x19, 0x3b,
- 0x88, 0x40, 0xf3, 0x06, 0xe5, 0x22, 0x07, 0xbf, 0x72, 0xcc, 0xc4, 0x68,
- 0xdd, 0x8b, 0xe4, 0x0b, 0x52, 0xbf, 0x10, 0x4f, 0x9b, 0xcf, 0x5b, 0x35,
- 0xd3, 0xbf, 0x67, 0x1d, 0x32, 0xd4, 0xf5, 0xd4, 0x76, 0xac, 0x94, 0x6d,
- 0x95, 0xb0, 0xad, 0x7b, 0x03, 0xba, 0xb9, 0x83, 0x6d, 0x3d, 0x93, 0x38,
- 0x11, 0x74, 0xb3, 0xad, 0x27, 0x4c, 0xe1, 0xe0, 0xce, 0xa6, 0x26, 0xce,
- 0x6d, 0x57, 0x32, 0xe0, 0xdb, 0x46, 0xb9, 0x24, 0x37, 0xba, 0x33, 0x21,
- 0xef, 0x74, 0x7c, 0x9d, 0xe3, 0x89, 0xb6, 0xbb, 0xd0, 0xf0, 0x50, 0x19,
- 0xed, 0xa7, 0x1c, 0x79, 0x5b, 0xd7, 0x7d, 0xc4, 0x3b, 0xdc, 0xcb, 0x32,
- 0x6f, 0x06, 0x66, 0xe3, 0x95, 0x50, 0xc3, 0xca, 0xd9, 0x70, 0xc6, 0x0e,
- 0x29, 0x81, 0xa6, 0x0d, 0x4a, 0x5c, 0x13, 0x5b, 0xbc, 0x27, 0xa5, 0x07,
- 0x1b, 0x21, 0xd8, 0xdd, 0x42, 0x7d, 0xcc, 0xc6, 0x87, 0x0b, 0x45, 0x2e,
- 0x67, 0x38, 0xe8, 0x08, 0x74, 0x3c, 0xcf, 0xf9, 0x2d, 0x9b, 0x97, 0xcd,
- 0xfb, 0xd2, 0xf6, 0xbe, 0xce, 0x16, 0xf4, 0xa5, 0x4f, 0xbd, 0x77, 0xc0,
- 0x80, 0xf3, 0x68, 0xdd, 0xa3, 0x16, 0xec, 0x77, 0x40, 0x1a, 0x64, 0x1e,
- 0x5a, 0x64, 0x1e, 0x8a, 0xe9, 0x4f, 0x37, 0x51, 0xee, 0xf5, 0xb6, 0xdc,
- 0xb3, 0x31, 0x6c, 0xca, 0x7a, 0x92, 0x53, 0xbb, 0x07, 0x3d, 0xc4, 0xce,
- 0xc0, 0xf9, 0x2e, 0xf6, 0xf3, 0x26, 0x65, 0x9e, 0x47, 0xbd, 0x4f, 0x36,
- 0x0b, 0x3f, 0x7c, 0x18, 0xbd, 0xc9, 0xfc, 0x3b, 0x22, 0x0a, 0x52, 0x01,
- 0xe9, 0xe3, 0x61, 0xf2, 0xa5, 0x2e, 0x6b, 0xb2, 0x5a, 0xae, 0xef, 0x65,
- 0x2e, 0x1d, 0xd5, 0xe8, 0x0f, 0xd4, 0x3b, 0xf4, 0xd9, 0xd0, 0x27, 0xce,
- 0x38, 0xa2, 0xf4, 0x01, 0xd3, 0x7b, 0x9e, 0xd8, 0x70, 0x14, 0x1d, 0x16,
- 0x2a, 0x6c, 0x7b, 0xf8, 0xf9, 0x88, 0xf1, 0x0b, 0x45, 0x62, 0x7b, 0x86,
- 0x3a, 0x60, 0xb6, 0xdf, 0x2e, 0x3a, 0x28, 0xa5, 0xcf, 0x8e, 0x05, 0x74,
- 0xff, 0x2b, 0x94, 0x67, 0x07, 0xe5, 0x59, 0x91, 0x9d, 0x43, 0xdf, 0x16,
- 0x45, 0x7c, 0x3a, 0xd0, 0xbc, 0x9a, 0xd7, 0xb7, 0x53, 0x9e, 0x40, 0xaf,
- 0x82, 0xa1, 0xe6, 0x6e, 0xf2, 0xb1, 0x0e, 0xea, 0xe0, 0xa2, 0x3c, 0x6e,
- 0x7b, 0xce, 0x3a, 0xc8, 0x05, 0x0a, 0x99, 0xff, 0x0b, 0x7e, 0x6b, 0x18,
- 0xa6, 0x9d, 0xee, 0xe7, 0x8c, 0x44, 0xbd, 0x2a, 0x0a, 0x0d, 0xc1, 0x80,
- 0x6a, 0x5e, 0x73, 0x71, 0x6e, 0xca, 0x71, 0x48, 0xdb, 0x6b, 0xef, 0x69,
- 0xce, 0xe6, 0xea, 0x1f, 0x59, 0xa3, 0x5e, 0xe1, 0x67, 0xb2, 0xde, 0x24,
- 0x6b, 0x32, 0x71, 0x4f, 0x76, 0x4f, 0xb5, 0x8b, 0x3a, 0xc9, 0x5e, 0x7f,
- 0x41, 0x73, 0xe4, 0xf2, 0x66, 0xb9, 0xfe, 0x81, 0xf5, 0xac, 0x5d, 0x5e,
- 0xca, 0xb9, 0x6c, 0x2e, 0x5c, 0x6c, 0x97, 0xfb, 0xc0, 0x7a, 0x51, 0x73,
- 0x4e, 0x29, 0x97, 0x7f, 0x86, 0x77, 0xe2, 0x6b, 0x4e, 0x62, 0x5e, 0xe1,
- 0xdc, 0xc5, 0x38, 0x69, 0x9c, 0xaa, 0x39, 0x5d, 0xd7, 0xc9, 0x38, 0x36,
- 0x75, 0x1f, 0x98, 0x85, 0x27, 0xed, 0x1c, 0xb7, 0x6b, 0xbe, 0x03, 0x27,
- 0x76, 0x16, 0xd0, 0x27, 0xa3, 0x9a, 0xac, 0x87, 0x45, 0x4b, 0x72, 0x7b,
- 0x55, 0x24, 0x6f, 0x0c, 0xfa, 0xd5, 0xab, 0x6d, 0x6e, 0x18, 0x55, 0xff,
- 0xdc, 0x7e, 0x3b, 0xe1, 0x2e, 0x9d, 0xd8, 0x6f, 0xe4, 0x39, 0xcb, 0x89,
- 0x47, 0x55, 0xe2, 0xe4, 0x80, 0xb9, 0x58, 0x62, 0xb3, 0x9f, 0xf5, 0x83,
- 0x31, 0x75, 0x2a, 0xb7, 0x59, 0xed, 0x41, 0x59, 0xd7, 0x36, 0x07, 0x64,
- 0x9f, 0xa9, 0xec, 0x19, 0x95, 0xbe, 0x8a, 0x72, 0xeb, 0x3c, 0x9f, 0xc4,
- 0x35, 0xf2, 0x7d, 0x09, 0xdf, 0xf8, 0x20, 0xc7, 0xdd, 0xf4, 0x60, 0xd4,
- 0x96, 0xf3, 0x57, 0xd6, 0x4a, 0x2d, 0x33, 0x43, 0xc3, 0xa5, 0xb2, 0x47,
- 0x73, 0xb2, 0xc7, 0x3e, 0x71, 0x9d, 0x4a, 0xfa, 0x99, 0xda, 0x66, 0x7e,
- 0x4f, 0xb7, 0xac, 0x61, 0xca, 0x3d, 0x05, 0x5d, 0xc4, 0xa1, 0xa8, 0xd6,
- 0xc0, 0x38, 0xaf, 0xfb, 0xd6, 0x70, 0x3e, 0xe2, 0x5e, 0xd9, 0xcb, 0x9e,
- 0x8f, 0x91, 0x85, 0xc8, 0xae, 0x25, 0xca, 0x7e, 0x87, 0xec, 0xfa, 0x21,
- 0xed, 0x1e, 0x5d, 0xa9, 0xdf, 0x59, 0x19, 0xaf, 0x93, 0xb1, 0xf0, 0xe2,
- 0x3e, 0xea, 0x21, 0xea, 0x55, 0xd6, 0x41, 0xb6, 0x5c, 0x58, 0xab, 0x90,
- 0x35, 0x1a, 0x89, 0xbd, 0xbf, 0xb5, 0x5a, 0x2f, 0x29, 0x3b, 0x75, 0x4f,
- 0x79, 0x75, 0x4c, 0x9e, 0x83, 0x8d, 0xe6, 0xd6, 0xb1, 0x1b, 0xff, 0xe0,
- 0x39, 0xd8, 0x04, 0x6d, 0x09, 0xd1, 0x2d, 0xe4, 0x76, 0x71, 0x74, 0x63,
- 0x34, 0x51, 0xab, 0x6d, 0x85, 0x26, 0xeb, 0xb7, 0xfc, 0xeb, 0xc6, 0xa1,
- 0x04, 0xa2, 0x05, 0x57, 0x95, 0x93, 0x6f, 0x21, 0xea, 0x60, 0x8c, 0x7a,
- 0x22, 0x51, 0xdb, 0xb4, 0x9d, 0x63, 0xf2, 0xaf, 0xec, 0xc6, 0x70, 0xa2,
- 0xe1, 0x4b, 0x8c, 0x23, 0xfe, 0x12, 0x9b, 0xeb, 0x44, 0xff, 0xcb, 0x01,
- 0xe2, 0xc0, 0xe6, 0xdc, 0x1a, 0x52, 0x6b, 0xe2, 0xd7, 0x94, 0xdf, 0x16,
- 0x92, 0xf5, 0xfe, 0x54, 0xb9, 0x09, 0xe6, 0xd3, 0xa7, 0xb0, 0xb6, 0x5f,
- 0xc1, 0xb3, 0xc6, 0x29, 0xac, 0x19, 0x12, 0x79, 0x4e, 0xa1, 0xad, 0xff,
- 0xfb, 0xd8, 0xdf, 0x3f, 0x1d, 0x8d, 0xb6, 0x6e, 0x3a, 0xb0, 0x61, 0xd7,
- 0x11, 0xec, 0x48, 0x5a, 0xd8, 0x1e, 0xf2, 0x60, 0xfd, 0x3e, 0x05, 0xcb,
- 0x03, 0xc7, 0xb0, 0x75, 0x97, 0x85, 0x39, 0xa1, 0x4e, 0x34, 0x99, 0x25,
- 0x28, 0xac, 0x98, 0xb7, 0x4e, 0x65, 0xb9, 0xd6, 0xe1, 0x8e, 0xdc, 0xfe,
- 0xe5, 0x43, 0xc4, 0x02, 0x15, 0x3e, 0x43, 0xf6, 0x26, 0x47, 0x95, 0xdb,
- 0xd3, 0x8d, 0x4a, 0x4b, 0xee, 0x39, 0xe2, 0xad, 0xe9, 0x8f, 0x99, 0xff,
- 0xc4, 0xb1, 0x3f, 0x74, 0x0a, 0x43, 0x43, 0xbf, 0x2e, 0xcd, 0xfa, 0xcb,
- 0x04, 0xb9, 0x83, 0xe4, 0x1c, 0x26, 0x6d, 0xea, 0x4f, 0xbd, 0x37, 0x24,
- 0x76, 0x37, 0x89, 0x9f, 0x0e, 0x9e, 0xc6, 0xe9, 0xc1, 0x7f, 0xc1, 0x12,
- 0x4d, 0xf2, 0x34, 0xab, 0xd3, 0x19, 0xb1, 0xac, 0x3d, 0xf5, 0x71, 0xab,
- 0xda, 0x78, 0xab, 0x0c, 0xc5, 0x65, 0x98, 0x16, 0x79, 0x0d, 0xdb, 0x35,
- 0xb6, 0x95, 0x3c, 0x84, 0x9d, 0x8c, 0xeb, 0xbe, 0xc8, 0x1d, 0xf0, 0x25,
- 0x33, 0x66, 0x25, 0xa2, 0x3b, 0x2b, 0xa1, 0xb7, 0x57, 0x38, 0x8c, 0x8e,
- 0x7f, 0x56, 0xea, 0x70, 0x6b, 0xfa, 0x34, 0x7e, 0x31, 0x68, 0xef, 0xc9,
- 0x6a, 0xf9, 0xb6, 0x62, 0x75, 0x6e, 0x0f, 0xe9, 0x4d, 0xff, 0x55, 0x89,
- 0xc6, 0x65, 0x2f, 0x4f, 0x11, 0x73, 0x82, 0xdb, 0x06, 0x25, 0xdf, 0x6c,
- 0x81, 0xbb, 0x57, 0xcf, 0x2c, 0x25, 0xcf, 0xfe, 0xca, 0x82, 0xf8, 0x8c,
- 0x2a, 0xda, 0xa5, 0x43, 0xd1, 0x83, 0x86, 0xda, 0x89, 0xe3, 0xa6, 0x3e,
- 0xf1, 0x5b, 0x87, 0x31, 0xf4, 0x2d, 0xd4, 0x61, 0x55, 0x5a, 0x1f, 0xba,
- 0x86, 0x79, 0xd8, 0xd6, 0x3e, 0x13, 0xc9, 0x3e, 0xbd, 0xa5, 0xc3, 0xd1,
- 0x83, 0xfb, 0x02, 0x35, 0xed, 0xef, 0x91, 0xcb, 0x79, 0x88, 0x29, 0x7d,
- 0xe3, 0x23, 0xcc, 0x13, 0x7b, 0xb0, 0x61, 0x5f, 0x04, 0xeb, 0xf7, 0x98,
- 0xe8, 0xee, 0x1b, 0xa1, 0x6c, 0x2f, 0x95, 0xca, 0x1e, 0x96, 0xe6, 0x50,
- 0xfc, 0x66, 0x15, 0x81, 0x28, 0xfb, 0x6c, 0x50, 0x23, 0x01, 0xbf, 0xaa,
- 0x30, 0xfa, 0x8f, 0x3b, 0xb1, 0x89, 0x65, 0x7a, 0x93, 0xb4, 0xb9, 0x3e,
- 0x37, 0xe3, 0xe5, 0x4c, 0x0c, 0x8f, 0xf9, 0x70, 0x70, 0xcc, 0x83, 0xa1,
- 0x31, 0x8d, 0x47, 0x31, 0x1e, 0x1b, 0x90, 0xbd, 0x20, 0x5e, 0x3c, 0x7d,
- 0xc0, 0x8d, 0xcd, 0xbb, 0x3d, 0x98, 0x1d, 0x99, 0x86, 0x03, 0x07, 0x8a,
- 0xb1, 0x97, 0xd7, 0x2b, 0x16, 0xfa, 0xf1, 0x24, 0xaf, 0xf7, 0xef, 0x76,
- 0x71, 0x1e, 0xe6, 0xe0, 0x30, 0x0d, 0x7b, 0x68, 0xac, 0x04, 0xc9, 0x01,
- 0x9a, 0x3c, 0x39, 0xeb, 0xdb, 0xcc, 0x30, 0x46, 0x0f, 0x30, 0x36, 0xee,
- 0x33, 0x91, 0x60, 0x3f, 0x3b, 0xa8, 0xab, 0x6e, 0xe2, 0xda, 0x86, 0x31,
- 0xc1, 0xf8, 0x55, 0xb8, 0xa9, 0x57, 0x6f, 0x6a, 0x54, 0x8c, 0xe8, 0x22,
- 0x7b, 0xbf, 0x97, 0xbc, 0xdf, 0xb5, 0x0a, 0x0d, 0x09, 0xdd, 0x6c, 0x44,
- 0x27, 0x4e, 0x72, 0xdc, 0xff, 0x17, 0xfd, 0x76, 0xb1, 0x43, 0xef, 0xb9,
- 0x51, 0x3d, 0x82, 0x9d, 0xe9, 0xa3, 0xe4, 0xea, 0x40, 0x78, 0xff, 0x11,
- 0xf2, 0xb7, 0xe3, 0xc4, 0x9f, 0x37, 0x2d, 0x9f, 0xa1, 0xe2, 0xd6, 0x47,
- 0x8c, 0xf0, 0xfb, 0x4a, 0xa0, 0xfd, 0x57, 0xd4, 0xc1, 0x67, 0x0f, 0xa8,
- 0xb8, 0x65, 0xe7, 0x62, 0xa4, 0x42, 0x51, 0xec, 0x58, 0xa4, 0xe2, 0xe6,
- 0x7d, 0x47, 0x88, 0xfb, 0x13, 0x36, 0x4f, 0xce, 0xa4, 0x1e, 0x46, 0xb0,
- 0x57, 0xd6, 0xb8, 0xdd, 0x8c, 0xdf, 0xa5, 0x78, 0xa6, 0x9f, 0x39, 0xb4,
- 0x59, 0x8a, 0x13, 0x43, 0x47, 0x68, 0x8f, 0xa5, 0x38, 0xde, 0x6f, 0x4c,
- 0xfc, 0xd4, 0x51, 0x8a, 0xa7, 0x79, 0xbe, 0x93, 0xe7, 0x0b, 0x07, 0x8c,
- 0xfe, 0x0e, 0xb5, 0x14, 0x0b, 0xf6, 0xd7, 0xa3, 0xbf, 0x4f, 0x6c, 0x53,
- 0x43, 0xfb, 0x58, 0x5d, 0x4e, 0xf7, 0xa2, 0x73, 0x2f, 0x36, 0x52, 0x57,
- 0xf7, 0xed, 0xec, 0x64, 0x7f, 0x3e, 0xea, 0xfc, 0x08, 0x1e, 0x63, 0x5e,
- 0xb7, 0xbd, 0xcf, 0x87, 0x73, 0x49, 0xc3, 0xff, 0x45, 0xc5, 0x30, 0x8b,
- 0x94, 0x80, 0xf6, 0x0c, 0x7c, 0x38, 0x9d, 0x2e, 0xc6, 0xa6, 0x81, 0x99,
- 0xf8, 0x29, 0xed, 0xf3, 0xd1, 0xdd, 0xd2, 0xdf, 0x04, 0xe3, 0xc3, 0x2c,
- 0x3c, 0x3d, 0x62, 0xb2, 0x6d, 0x99, 0x27, 0x89, 0x39, 0xdd, 0x70, 0x25,
- 0xc5, 0x37, 0xa2, 0x3b, 0x69, 0x16, 0xc4, 0xc4, 0x63, 0x48, 0xf7, 0xeb,
- 0x3d, 0xb7, 0xa9, 0xc2, 0xab, 0x55, 0xea, 0xd2, 0x81, 0x49, 0x4d, 0x8f,
- 0x57, 0xa8, 0xf1, 0x7e, 0xe6, 0xaf, 0xf1, 0x4a, 0xf5, 0x18, 0x9e, 0xee,
- 0x77, 0x62, 0xde, 0x42, 0x95, 0xd7, 0xe3, 0xe7, 0x19, 0xdb, 0xe2, 0xb3,
- 0x55, 0x13, 0x7b, 0x6d, 0x59, 0x11, 0x2f, 0x20, 0xb7, 0x2f, 0x5f, 0x58,
- 0xc3, 0xf8, 0xe5, 0x10, 0xdb, 0x8b, 0x95, 0xaa, 0x4e, 0xea, 0xfd, 0x34,
- 0x46, 0x68, 0xd7, 0x4f, 0xf0, 0x38, 0x3c, 0x68, 0x75, 0x2e, 0x27, 0xe7,
- 0x9e, 0x13, 0xb0, 0x3a, 0x6f, 0x33, 0x0d, 0x5f, 0x81, 0x1a, 0x88, 0x7e,
- 0x05, 0xa7, 0x71, 0x68, 0x44, 0xca, 0xc0, 0xed, 0x8d, 0x30, 0xaf, 0xee,
- 0xb3, 0x3a, 0x77, 0x9a, 0x73, 0x50, 0x6f, 0xe7, 0xc6, 0x3f, 0x2f, 0xcd,
- 0x62, 0xa6, 0xf8, 0x91, 0xbd, 0xa7, 0x0a, 0xbf, 0x62, 0x3b, 0xef, 0x0f,
- 0x96, 0xa3, 0xaa, 0x52, 0xfc, 0xe0, 0x14, 0xde, 0xe9, 0x7f, 0x0d, 0xe7,
- 0xfa, 0x2d, 0x2c, 0x08, 0x59, 0x70, 0x86, 0x6a, 0xcd, 0x46, 0xf5, 0x1a,
- 0x62, 0x84, 0x82, 0x9b, 0xe6, 0x7e, 0x1f, 0xef, 0xd2, 0xff, 0x6f, 0x9e,
- 0x6b, 0xd9, 0xb2, 0xf4, 0x62, 0xa1, 0xb5, 0xa3, 0x5a, 0xfc, 0xc6, 0xb4,
- 0xf7, 0xd3, 0xfc, 0xe9, 0x3c, 0x38, 0xbf, 0xaf, 0x4b, 0x72, 0xe1, 0xd3,
- 0x18, 0x1e, 0x34, 0xa2, 0x6b, 0xf3, 0x72, 0xf6, 0x9f, 0xa6, 0x0e, 0x2c,
- 0xec, 0x34, 0x4f, 0xec, 0xab, 0xc0, 0xbc, 0xf3, 0xcc, 0x1a, 0xaf, 0x9b,
- 0x4d, 0xdb, 0x59, 0xb0, 0x30, 0x60, 0x2e, 0x53, 0xff, 0x37, 0xfd, 0xf4,
- 0x34, 0x0e, 0x0e, 0xe5, 0xf1, 0xda, 0x87, 0x46, 0xfa, 0x79, 0x76, 0xcf,
- 0xbb, 0x17, 0x0d, 0xc9, 0xa3, 0xf6, 0xfa, 0xc3, 0x61, 0xe2, 0x63, 0xf6,
- 0x19, 0xa1, 0x86, 0x91, 0x74, 0x23, 0xb1, 0x21, 0x8a, 0xef, 0xa6, 0x23,
- 0xc4, 0x87, 0x30, 0xf1, 0xa1, 0x9e, 0xf8, 0x60, 0x12, 0x1f, 0xea, 0x88,
- 0x0f, 0x41, 0xfb, 0xd9, 0xb9, 0xac, 0x47, 0x0f, 0x8d, 0xbe, 0x86, 0x82,
- 0x81, 0x53, 0x70, 0x0d, 0xc8, 0x3e, 0x35, 0x8b, 0xfc, 0xa4, 0x56, 0x6b,
- 0xc3, 0x1c, 0x45, 0xf6, 0x0c, 0x0e, 0xa5, 0x4f, 0xa1, 0x68, 0x40, 0xe3,
- 0x58, 0x64, 0xaf, 0x40, 0x4d, 0xb8, 0x87, 0x58, 0xfd, 0x6b, 0xa3, 0xb6,
- 0xc7, 0x8b, 0xda, 0xbd, 0xd5, 0x30, 0xfa, 0x17, 0xaa, 0x73, 0x95, 0xe8,
- 0xe7, 0xbc, 0x1c, 0x67, 0x25, 0x66, 0xed, 0xd6, 0x30, 0x9b, 0xc7, 0x3f,
- 0x25, 0x6b, 0x26, 0xde, 0x74, 0xc0, 0x3b, 0x9d, 0x74, 0x67, 0x06, 0x99,
- 0x00, 0x59, 0xad, 0xd7, 0x87, 0x2b, 0x0f, 0x9f, 0x56, 0x15, 0x64, 0x3e,
- 0x27, 0x31, 0xaf, 0x36, 0xd8, 0xad, 0x32, 0x5b, 0xd7, 0x04, 0xc3, 0x79,
- 0xa8, 0x88, 0x90, 0x45, 0xcc, 0x64, 0x7e, 0x61, 0xb5, 0x99, 0x45, 0xd8,
- 0x52, 0xa7, 0xca, 0x7e, 0x8d, 0xa3, 0x12, 0xa3, 0xa6, 0x33, 0x46, 0x14,
- 0xf7, 0xc5, 0xef, 0x99, 0x0e, 0x0f, 0x8a, 0xfa, 0x2c, 0xeb, 0x1b, 0x21,
- 0x0d, 0x9e, 0x48, 0x20, 0xba, 0x81, 0x69, 0xe4, 0xe7, 0xe6, 0x85, 0x71,
- 0x53, 0xfa, 0x30, 0x06, 0x38, 0xbe, 0xe5, 0xe9, 0xfc, 0xbb, 0x9c, 0x7f,
- 0xfa, 0xef, 0xe2, 0x3b, 0xa1, 0x57, 0xee, 0x9d, 0x0e, 0x43, 0x7b, 0x40,
- 0xed, 0x28, 0x27, 0x07, 0x3f, 0xcc, 0xb8, 0xa7, 0x4c, 0x7e, 0x5e, 0x41,
- 0xcb, 0x40, 0x1c, 0x55, 0xa1, 0x53, 0x4a, 0x4c, 0xf6, 0x32, 0x29, 0x95,
- 0xf8, 0xfc, 0x6e, 0xea, 0x7a, 0x41, 0x86, 0xb6, 0xe2, 0xc3, 0xb7, 0x46,
- 0x45, 0xb7, 0x35, 0x43, 0x3b, 0x39, 0x8e, 0x37, 0xe6, 0x1e, 0x16, 0x9c,
- 0x3c, 0x32, 0x0b, 0x8e, 0x23, 0xd3, 0x98, 0x9b, 0xd6, 0xcc, 0xbd, 0xf2,
- 0xfc, 0xbf, 0xa8, 0xa2, 0x17, 0x85, 0xd8, 0xa1, 0xf7, 0xc7, 0xd8, 0xf6,
- 0x07, 0x8e, 0xc3, 0xd8, 0x44, 0x0c, 0x3e, 0x9a, 0xfe, 0x0e, 0x75, 0x79,
- 0x28, 0x97, 0x2f, 0xad, 0x42, 0xa2, 0x57, 0xf6, 0xe3, 0x9d, 0xc2, 0xac,
- 0x01, 0xbd, 0x79, 0x9b, 0x62, 0x04, 0x6f, 0x56, 0x4e, 0x61, 0xc6, 0x40,
- 0x90, 0x73, 0xa9, 0x61, 0x59, 0x5f, 0x1e, 0x3f, 0x05, 0x83, 0x57, 0x11,
- 0x83, 0xad, 0xc5, 0x3f, 0x35, 0xe3, 0xcc, 0x71, 0x74, 0xd3, 0xa9, 0xe8,
- 0x2d, 0x73, 0x15, 0xd9, 0x9b, 0x63, 0x9c, 0x6f, 0x65, 0x1d, 0xcf, 0x40,
- 0x1d, 0xee, 0xe4, 0x98, 0x9b, 0x38, 0x6f, 0xaf, 0x2d, 0xb4, 0xb0, 0x68,
- 0xa1, 0xbe, 0xb7, 0xc8, 0x11, 0x7d, 0xa0, 0x02, 0x99, 0x8e, 0x6a, 0xda,
- 0xcd, 0x7d, 0x0b, 0xf4, 0xf0, 0xab, 0xc4, 0x5d, 0xe2, 0x34, 0x36, 0x31,
- 0xee, 0xb4, 0x31, 0x16, 0x15, 0x47, 0xf4, 0x1e, 0xe6, 0xa8, 0xef, 0xdf,
- 0xed, 0x88, 0x86, 0xe4, 0x7d, 0xa3, 0x7f, 0xc0, 0x62, 0xb8, 0x43, 0x65,
- 0xc4, 0x41, 0x3d, 0xf3, 0x1a, 0xf4, 0xbd, 0x77, 0x92, 0x93, 0xfe, 0x84,
- 0xfc, 0xae, 0xfa, 0xaa, 0xa3, 0xc4, 0xa8, 0x11, 0x3c, 0x9a, 0x3e, 0x82,
- 0xbd, 0xe9, 0x14, 0x76, 0xa5, 0x77, 0x28, 0x43, 0xf6, 0xb3, 0x3a, 0x45,
- 0xde, 0xad, 0x8b, 0x96, 0x29, 0x5f, 0x46, 0x69, 0xe8, 0x9b, 0xd6, 0x50,
- 0x85, 0x8a, 0xf2, 0x50, 0x10, 0x37, 0xf5, 0xc5, 0xe1, 0x88, 0xbc, 0x67,
- 0xc9, 0x7b, 0xd9, 0xeb, 0xc7, 0x0d, 0xdc, 0xd8, 0x57, 0x8c, 0xd8, 0x7e,
- 0xcb, 0xea, 0xa9, 0x77, 0x62, 0xcd, 0x78, 0x1d, 0x96, 0x0d, 0x3c, 0x66,
- 0xcd, 0x66, 0xcc, 0xf9, 0xf8, 0x5a, 0x0f, 0xee, 0xde, 0xef, 0x41, 0x6b,
- 0x5f, 0x14, 0xbe, 0x48, 0x09, 0x7f, 0x07, 0xcc, 0x25, 0x30, 0x26, 0x26,
- 0x60, 0xf4, 0xdc, 0xe0, 0x08, 0x1c, 0x0a, 0xab, 0x1e, 0x7c, 0x95, 0x38,
- 0xbe, 0x9c, 0xb8, 0x13, 0x1b, 0xb7, 0x50, 0x1e, 0xf1, 0xe2, 0x1e, 0xd6,
- 0xbf, 0x85, 0x73, 0xff, 0xee, 0xa2, 0x43, 0xc4, 0x02, 0xd9, 0x83, 0xa8,
- 0x61, 0xc3, 0xb8, 0x9b, 0xba, 0x72, 0x23, 0x76, 0xb0, 0x12, 0x37, 0xee,
- 0xf6, 0xe3, 0xee, 0x71, 0x0f, 0x1a, 0xfa, 0xac, 0xc5, 0x87, 0xcd, 0xf8,
- 0x4a, 0x0d, 0x06, 0x5a, 0xc7, 0xbd, 0xf8, 0xdb, 0x3e, 0xdd, 0x77, 0x33,
- 0x73, 0xfe, 0x11, 0x33, 0x88, 0xbf, 0x1f, 0xf7, 0xe1, 0xf6, 0xbe, 0x13,
- 0x92, 0x47, 0x2e, 0x71, 0x32, 0xf6, 0x3c, 0x34, 0x3e, 0x13, 0x2b, 0xfb,
- 0xf4, 0xf3, 0x13, 0xe4, 0x76, 0x9d, 0x07, 0x4d, 0x3c, 0x30, 0xae, 0xa2,
- 0x85, 0xed, 0x7c, 0xbe, 0x6f, 0x16, 0x3a, 0x0e, 0xd6, 0x53, 0x86, 0x85,
- 0x58, 0x3e, 0xe0, 0x84, 0x49, 0x16, 0x8f, 0x2f, 0x00, 0xcd, 0x03, 0x13,
- 0xcc, 0xe3, 0x1e, 0xc6, 0x8e, 0x5e, 0x13, 0xf7, 0x8e, 0xcb, 0xf9, 0x11,
- 0xfb, 0x5d, 0xd8, 0xf7, 0xf7, 0x2d, 0xc4, 0x67, 0x07, 0x54, 0xe2, 0x40,
- 0x21, 0x86, 0x56, 0x2a, 0xf8, 0x5b, 0x5e, 0xdf, 0x96, 0x94, 0xbd, 0xcc,
- 0x40, 0x68, 0x67, 0xe0, 0x50, 0x05, 0x39, 0xc3, 0xa2, 0x7d, 0xd9, 0xeb,
- 0x8f, 0x12, 0xe7, 0x8b, 0x88, 0xf3, 0x25, 0xe4, 0xb0, 0x37, 0x0c, 0x1f,
- 0xc1, 0x23, 0xc4, 0xe5, 0xa3, 0x03, 0x9d, 0x8c, 0x3b, 0xa5, 0x78, 0x92,
- 0x71, 0xa0, 0x8f, 0xe7, 0xa7, 0x76, 0x1a, 0x1d, 0x45, 0xc4, 0xe9, 0x57,
- 0x89, 0xbf, 0x3d, 0xc4, 0x8c, 0xfb, 0xfa, 0x18, 0xee, 0x77, 0x32, 0x07,
- 0xb8, 0x2a, 0x3a, 0xdf, 0xc3, 0x1c, 0xeb, 0x66, 0x25, 0xe0, 0x7b, 0x0b,
- 0xa5, 0x70, 0xec, 0xab, 0x44, 0xc3, 0x6e, 0x29, 0x23, 0xf8, 0xa5, 0x42,
- 0x3d, 0xe0, 0xa4, 0xce, 0x8f, 0xc1, 0xea, 0x77, 0x70, 0xbc, 0x35, 0x26,
- 0x19, 0x38, 0xde, 0x30, 0x75, 0xed, 0xbb, 0xc4, 0xda, 0x0f, 0x89, 0xa9,
- 0xfe, 0xe9, 0xf5, 0x68, 0x34, 0x4c, 0x1e, 0xc7, 0x70, 0xba, 0xdf, 0x30,
- 0x65, 0x9f, 0xdc, 0x9b, 0xe4, 0x79, 0x93, 0xd3, 0x19, 0x33, 0x0d, 0xf1,
- 0xc3, 0x11, 0x8e, 0x47, 0x95, 0xbc, 0x04, 0x8e, 0x31, 0xe0, 0x9d, 0x7d,
- 0x8b, 0x39, 0x2e, 0x89, 0xa5, 0x12, 0xef, 0x46, 0x28, 0xeb, 0x62, 0xac,
- 0xa0, 0x3e, 0x1a, 0xfb, 0x54, 0xa4, 0x0e, 0x46, 0x70, 0xef, 0x9e, 0x6c,
- 0x1c, 0x6e, 0x0f, 0xc5, 0x6f, 0x63, 0x1c, 0x0e, 0x17, 0x33, 0x0e, 0xbb,
- 0x22, 0x22, 0x9b, 0x13, 0xc3, 0x8c, 0xdb, 0x5b, 0x92, 0x61, 0x34, 0x71,
- 0x0e, 0x27, 0x52, 0xec, 0xb7, 0x6f, 0x26, 0x9e, 0x49, 0x79, 0x18, 0xb3,
- 0x34, 0x1e, 0x44, 0xb5, 0x91, 0x69, 0x3c, 0xfc, 0x3c, 0xe6, 0xf0, 0x30,
- 0xec, 0x6b, 0x6d, 0x7d, 0x0a, 0xe2, 0xcd, 0xd9, 0xe7, 0x65, 0xcf, 0xa4,
- 0x04, 0x9b, 0x65, 0x2d, 0xf3, 0xde, 0x72, 0xd9, 0xfb, 0xd9, 0x9f, 0xfc,
- 0x3e, 0xca, 0x89, 0x4f, 0x65, 0x39, 0x1c, 0xfa, 0x79, 0x48, 0x70, 0xb7,
- 0x86, 0xb8, 0x2b, 0xfb, 0x73, 0x2c, 0x6b, 0x55, 0x60, 0x2a, 0x1e, 0xfd,
- 0xef, 0x8f, 0xa3, 0xf6, 0x7e, 0x56, 0xc1, 0x24, 0xe2, 0x5f, 0x92, 0xf8,
- 0xc7, 0x31, 0x74, 0x5d, 0x4f, 0x0c, 0xa4, 0x4c, 0xff, 0x98, 0x24, 0x06,
- 0x12, 0xa7, 0x8f, 0x10, 0xa7, 0x9f, 0x22, 0x4e, 0x7f, 0x93, 0x38, 0xfd,
- 0x24, 0x31, 0x21, 0xbb, 0xa6, 0xd7, 0x24, 0xcf, 0x2f, 0x38, 0x1f, 0xef,
- 0xd9, 0x6b, 0x8b, 0xd5, 0xd4, 0xd5, 0xac, 0x01, 0x79, 0xe7, 0x47, 0x3f,
- 0x24, 0x76, 0xff, 0x13, 0xce, 0x93, 0xbf, 0x2a, 0xbb, 0xef, 0xaa, 0xb1,
- 0xaf, 0x1b, 0xee, 0xbe, 0x5a, 0xad, 0x07, 0xf6, 0xb7, 0x02, 0x4c, 0xe1,
- 0xa2, 0x05, 0x7d, 0x6d, 0x70, 0xf4, 0xd5, 0x1e, 0x3a, 0x29, 0xcf, 0x43,
- 0xa7, 0x49, 0x5e, 0xdf, 0x26, 0x7b, 0xbd, 0x0f, 0xc9, 0x7e, 0xad, 0x65,
- 0xbc, 0xe7, 0xea, 0xab, 0x35, 0xdf, 0x82, 0x8d, 0x6d, 0xfe, 0x49, 0xfb,
- 0x5e, 0xcd, 0xfb, 0x8f, 0x50, 0x5f, 0x19, 0xb6, 0x99, 0x4a, 0xca, 0x7e,
- 0xd4, 0x99, 0x78, 0x22, 0x2d, 0xbf, 0x6b, 0x5b, 0x12, 0xea, 0xe3, 0x88,
- 0x55, 0x0b, 0x1f, 0x0f, 0xe3, 0xd6, 0x3e, 0x0f, 0xed, 0x20, 0x8e, 0x32,
- 0xfa, 0xd6, 0xfd, 0xe3, 0xf5, 0xf4, 0xb5, 0xc7, 0x2c, 0x2d, 0x12, 0x68,
- 0x19, 0x27, 0xe7, 0x59, 0x3f, 0xbe, 0x18, 0x4b, 0x07, 0x2c, 0xcb, 0x73,
- 0x8d, 0x11, 0xde, 0xa0, 0xf8, 0xe1, 0xa2, 0x0f, 0x3a, 0xe8, 0x57, 0x6b,
- 0xf7, 0x07, 0xb4, 0xb7, 0x88, 0xa7, 0xeb, 0xea, 0x0f, 0xd3, 0x3e, 0x8c,
- 0xf3, 0x4d, 0xc4, 0x52, 0x67, 0x24, 0xc0, 0x3c, 0xd1, 0x43, 0xdb, 0xf7,
- 0xe2, 0x7c, 0x42, 0xfc, 0x4b, 0xef, 0xf8, 0x2e, 0x73, 0x93, 0x0e, 0xfa,
- 0xc6, 0x07, 0x89, 0xeb, 0xe9, 0x4b, 0x61, 0x1e, 0x33, 0xe9, 0x0b, 0x6e,
- 0xbc, 0x93, 0x30, 0xe8, 0x77, 0x1e, 0xbc, 0x9b, 0xa8, 0x63, 0x9f, 0x41,
- 0x96, 0xf5, 0x63, 0xa3, 0xfd, 0xde, 0x75, 0x4d, 0xfc, 0x5b, 0x4a, 0x4d,
- 0xff, 0x2c, 0xb5, 0x02, 0xd1, 0x4a, 0x0d, 0x7f, 0x37, 0xfe, 0x37, 0xf8,
- 0x19, 0xe3, 0xf6, 0x9a, 0x3e, 0x70, 0x0e, 0x11, 0x22, 0x0f, 0x9c, 0x38,
- 0x28, 0xcf, 0xe9, 0x50, 0x1b, 0x9d, 0xeb, 0xd0, 0x99, 0xdb, 0xea, 0x99,
- 0x73, 0x0e, 0x27, 0xfb, 0x24, 0x2b, 0x66, 0xd9, 0x0f, 0xfa, 0x8b, 0xf1,
- 0xc0, 0xfe, 0xc3, 0xf4, 0x91, 0x02, 0x2c, 0x78, 0xc4, 0x8d, 0xbf, 0x3b,
- 0x38, 0x22, 0x6b, 0x4b, 0x82, 0x99, 0xfe, 0x21, 0x12, 0x85, 0x30, 0xb9,
- 0xde, 0xfd, 0x7b, 0x46, 0x30, 0x90, 0xe3, 0x79, 0x1f, 0x84, 0xe2, 0x5f,
- 0x51, 0x71, 0x98, 0x3c, 0x22, 0x10, 0xbf, 0x9a, 0x36, 0x26, 0xef, 0xb8,
- 0x49, 0xec, 0x5f, 0x41, 0x1b, 0xeb, 0xe6, 0x7c, 0x7e, 0x83, 0xe3, 0xd8,
- 0x41, 0x1b, 0x1b, 0x4d, 0xcc, 0xc4, 0x56, 0xda, 0x58, 0x9c, 0x36, 0x16,
- 0xa7, 0x3d, 0xc5, 0x69, 0x63, 0xf2, 0x6e, 0x7e, 0x9c, 0x36, 0x16, 0xa7,
- 0x8d, 0xc5, 0x53, 0x8b, 0xf1, 0x14, 0x99, 0xc6, 0xae, 0x91, 0x45, 0xc4,
- 0x31, 0x79, 0xb6, 0xc6, 0x79, 0xb8, 0xed, 0x6f, 0xc8, 0xd9, 0x6f, 0xe0,
- 0xa1, 0xe0, 0x4e, 0xfa, 0xe4, 0x63, 0x43, 0xc4, 0x3b, 0xda, 0xc1, 0xa2,
- 0xb4, 0x70, 0xfc, 0x7a, 0xe6, 0xb1, 0xc7, 0xc8, 0xf3, 0x55, 0x3c, 0x6b,
- 0x4a, 0x1e, 0x6c, 0xf2, 0x9c, 0xb1, 0x26, 0x29, 0x1c, 0xec, 0x18, 0x36,
- 0xf4, 0x03, 0x37, 0x91, 0x17, 0x56, 0x92, 0x97, 0x8c, 0x2c, 0x00, 0x5e,
- 0x1c, 0x12, 0x19, 0xc5, 0xc7, 0xb3, 0xfb, 0x4f, 0x8f, 0xf7, 0xd7, 0x44,
- 0x1b, 0x65, 0x7d, 0x88, 0x9c, 0x64, 0xf1, 0xb0, 0x70, 0xbc, 0xc3, 0xe4,
- 0x48, 0x7a, 0xf8, 0xdf, 0x21, 0x1c, 0xaf, 0x12, 0x65, 0x7b, 0xf4, 0xf0,
- 0x3b, 0x30, 0xd6, 0xfd, 0x52, 0xb1, 0x16, 0xbf, 0x16, 0x0a, 0xc4, 0x9f,
- 0x54, 0x54, 0x34, 0x93, 0xef, 0xdd, 0xbc, 0xd3, 0x89, 0x9e, 0xd0, 0x62,
- 0x7c, 0x85, 0x9c, 0x6f, 0xf5, 0x35, 0x2a, 0x96, 0xec, 0xa3, 0x2d, 0x55,
- 0x0a, 0xc7, 0xd2, 0xc3, 0xe7, 0x30, 0x61, 0xaf, 0x13, 0x8e, 0xa6, 0x8e,
- 0x5b, 0x55, 0x86, 0x60, 0x11, 0xb1, 0xed, 0xea, 0x37, 0x2d, 0xb7, 0xac,
- 0x35, 0x91, 0x03, 0x0e, 0xf7, 0x47, 0x5f, 0x70, 0x12, 0xf7, 0xd7, 0x93,
- 0x07, 0x3e, 0x91, 0xe3, 0x81, 0x07, 0xfb, 0x0d, 0xed, 0x07, 0xc4, 0x8b,
- 0xfd, 0x3c, 0xdf, 0xca, 0x73, 0xab, 0xdf, 0xe0, 0x7c, 0x04, 0x9a, 0x66,
- 0x90, 0x1b, 0xbe, 0x43, 0x99, 0x7b, 0x29, 0x73, 0x82, 0xf6, 0x9f, 0xee,
- 0xd5, 0x90, 0x1c, 0x33, 0x30, 0xde, 0xeb, 0x45, 0xdf, 0x58, 0x10, 0x4f,
- 0xf6, 0xfa, 0xb0, 0x93, 0xfc, 0xf0, 0x70, 0xaf, 0xf8, 0xe2, 0x4c, 0xf4,
- 0x8f, 0xcd, 0xc4, 0x37, 0x92, 0xb2, 0x3e, 0xf5, 0x2e, 0x56, 0x57, 0x88,
- 0x7e, 0xc4, 0x2f, 0xc9, 0xaf, 0x93, 0x7a, 0x4f, 0x8c, 0x63, 0x8a, 0x79,
- 0xf5, 0x43, 0x31, 0xe8, 0x43, 0x9c, 0xc1, 0x8f, 0x87, 0xbe, 0x20, 0x31,
- 0x52, 0x7c, 0x52, 0xc3, 0x13, 0xe4, 0x3c, 0xa5, 0xc4, 0xd5, 0x92, 0x48,
- 0x4d, 0xf4, 0x0b, 0x8a, 0x1e, 0x7b, 0x45, 0xb5, 0xac, 0x4a, 0x89, 0xe1,
- 0x07, 0x35, 0xf2, 0x0f, 0x13, 0x37, 0xdb, 0x31, 0x5b, 0xc3, 0xf4, 0xdd,
- 0x95, 0xa8, 0xda, 0xdd, 0x87, 0xff, 0x56, 0x19, 0xff, 0x60, 0x1a, 0x63,
- 0xfd, 0x34, 0x62, 0xfb, 0xec, 0xbe, 0x93, 0xd3, 0x67, 0x91, 0x33, 0xbf,
- 0xa1, 0xd6, 0x66, 0xbe, 0x0b, 0xfd, 0xd0, 0x69, 0x87, 0x3e, 0x71, 0x94,
- 0xf1, 0xc1, 0x45, 0xfb, 0x9c, 0x31, 0xae, 0xd1, 0x7f, 0x6b, 0x8f, 0x56,
- 0xc1, 0x88, 0x5f, 0xab, 0x3a, 0x2d, 0x54, 0x8a, 0x3c, 0xa1, 0xf2, 0x6c,
- 0x6e, 0x14, 0x26, 0xf6, 0x4b, 0x6c, 0x70, 0x40, 0x23, 0x0e, 0xff, 0x3d,
- 0x7d, 0xe6, 0x4e, 0x3b, 0x1e, 0x1d, 0xb6, 0x9f, 0x85, 0x76, 0x8e, 0xc7,
- 0xe9, 0x27, 0x8b, 0xd1, 0xd1, 0xef, 0x41, 0xbb, 0x1d, 0x8b, 0x1e, 0xb3,
- 0x2a, 0xe8, 0x33, 0x1d, 0xfb, 0x03, 0x4d, 0x37, 0xd2, 0x67, 0xae, 0xbb,
- 0x46, 0xe2, 0xd8, 0x61, 0xf2, 0x5f, 0xc3, 0xbc, 0x8e, 0xf8, 0xb2, 0xb5,
- 0xde, 0xe8, 0x78, 0x9e, 0x32, 0xdd, 0x4f, 0xfb, 0x7f, 0x97, 0x3c, 0xe7,
- 0xdc, 0x9e, 0x43, 0xd4, 0x99, 0x66, 0xfb, 0xc3, 0xcf, 0x92, 0x3e, 0xdb,
- 0x37, 0x62, 0xfc, 0x2d, 0x71, 0x2f, 0x46, 0x5f, 0xfa, 0x37, 0xc6, 0xec,
- 0xe2, 0x50, 0xfc, 0xf6, 0x62, 0x04, 0x71, 0x1f, 0x65, 0xfd, 0x38, 0xa9,
- 0xf7, 0x6f, 0x90, 0x77, 0x8f, 0x43, 0x26, 0x65, 0xf1, 0xe0, 0x83, 0xa4,
- 0xd8, 0xd9, 0x89, 0xff, 0x59, 0x89, 0xf8, 0x26, 0xc6, 0xe0, 0xa0, 0xe6,
- 0x90, 0xb5, 0xf0, 0x99, 0x58, 0x73, 0xf0, 0x1a, 0xca, 0x5c, 0x47, 0xff,
- 0x03, 0xe6, 0x0c, 0x47, 0x70, 0xcf, 0x1e, 0xc9, 0x31, 0xd0, 0x20, 0xb9,
- 0xda, 0xbc, 0x50, 0xc0, 0x3c, 0x43, 0xac, 0x58, 0x3b, 0x76, 0x98, 0x71,
- 0x42, 0xd6, 0x96, 0x91, 0xf1, 0x19, 0x61, 0xbc, 0xda, 0x5b, 0x6f, 0xbf,
- 0xd3, 0x70, 0xff, 0x58, 0x3d, 0x5e, 0xe9, 0x9d, 0x89, 0xfb, 0x98, 0xeb,
- 0xc4, 0x98, 0xeb, 0xc4, 0xc6, 0xbc, 0x88, 0x1d, 0x98, 0xc6, 0x83, 0xb2,
- 0x1d, 0x98, 0xc3, 0x83, 0xb2, 0x8d, 0xa9, 0xf8, 0x2a, 0xf3, 0x97, 0x0d,
- 0xc4, 0xf3, 0x1e, 0xda, 0xe3, 0xff, 0xe0, 0xdc, 0x0f, 0xd0, 0xde, 0xab,
- 0x89, 0xf7, 0x6f, 0xee, 0x02, 0xee, 0xb4, 0xf5, 0x73, 0x84, 0x7a, 0x54,
- 0xf0, 0x15, 0xfa, 0x44, 0x15, 0x63, 0x52, 0x37, 0xe7, 0x7c, 0xe7, 0xa0,
- 0x11, 0x0c, 0xab, 0x01, 0xed, 0x09, 0xce, 0x73, 0xd7, 0x88, 0x8a, 0x47,
- 0xfb, 0x17, 0x63, 0x3e, 0x63, 0xca, 0xb6, 0xa1, 0x09, 0xbb, 0x7c, 0x37,
- 0xfd, 0xe1, 0x6e, 0xfa, 0xc9, 0x7b, 0xf4, 0x93, 0xc9, 0x95, 0xf2, 0x3e,
- 0xa9, 0x93, 0x39, 0xff, 0xc3, 0x58, 0x93, 0x90, 0x78, 0xa7, 0xf7, 0x0c,
- 0xa9, 0xcc, 0xb5, 0x68, 0x9f, 0x5d, 0xcc, 0x51, 0x6e, 0xa7, 0x6d, 0x3e,
- 0x3a, 0x24, 0x3e, 0x24, 0x39, 0x8b, 0x11, 0xde, 0x46, 0xdb, 0x7c, 0x7e,
- 0x48, 0xfc, 0xa3, 0x14, 0xb7, 0xee, 0x94, 0xfd, 0xa6, 0xa5, 0xf8, 0xec,
- 0xbe, 0xc3, 0x94, 0xef, 0x08, 0x76, 0xd1, 0x2e, 0x4b, 0x69, 0x97, 0xf7,
- 0x51, 0xaf, 0x1e, 0xda, 0xe5, 0x06, 0xe2, 0x50, 0x09, 0xed, 0xf2, 0x5e,
- 0xf2, 0x81, 0xca, 0x9c, 0x5d, 0xfe, 0xdd, 0xf8, 0xc2, 0x8a, 0x6c, 0x8c,
- 0xf0, 0x42, 0xdd, 0x2d, 0xef, 0xf7, 0x59, 0xd6, 0xed, 0x66, 0xa6, 0x69,
- 0x06, 0x74, 0xb6, 0x1d, 0xc1, 0xb2, 0xb4, 0x13, 0xe5, 0x7d, 0x11, 0x2c,
- 0x4d, 0xd6, 0xb4, 0x9f, 0x55, 0x22, 0xc8, 0xcc, 0xc8, 0xf2, 0x40, 0x57,
- 0x9f, 0x7c, 0xdf, 0x43, 0x23, 0x07, 0xe1, 0xf8, 0xaf, 0xcd, 0x7e, 0x53,
- 0xe4, 0xf3, 0x7f, 0x01, 0x7f, 0x5c, 0x42, 0x99, 0x3a, 0xcd, 0x8f, 0xac,
- 0xc9, 0xec, 0xf7, 0x07, 0x9c, 0xb7, 0xf1, 0x7c, 0x16, 0xdb, 0xa8, 0x1a,
- 0x77, 0x3a, 0xbf, 0x98, 0xf4, 0x60, 0xfa, 0xb8, 0x89, 0xbf, 0xcd, 0xb6,
- 0xe3, 0x2e, 0x88, 0x34, 0xe2, 0xb9, 0x84, 0x82, 0x69, 0xc6, 0xd3, 0xf8,
- 0x91, 0xbd, 0x2e, 0x50, 0x89, 0xf2, 0xdd, 0xf6, 0x9a, 0x02, 0x0e, 0x24,
- 0xf4, 0xf6, 0x34, 0xcf, 0xcb, 0x0e, 0x7a, 0x51, 0xbc, 0x5b, 0xc1, 0x2d,
- 0x01, 0x2f, 0x4a, 0xf9, 0xdb, 0x43, 0xbe, 0xd9, 0x1d, 0x5a, 0x6e, 0x6d,
- 0x59, 0x25, 0xf6, 0xed, 0x05, 0x0e, 0x96, 0x94, 0x0b, 0x0e, 0x1e, 0x30,
- 0x65, 0xed, 0xd2, 0x40, 0x77, 0xa2, 0x12, 0x85, 0xbb, 0x6b, 0x9a, 0x1a,
- 0x51, 0x63, 0xbe, 0xc3, 0xfa, 0x05, 0x07, 0x3f, 0x5b, 0x21, 0xeb, 0xf6,
- 0x4f, 0x49, 0x8c, 0x1b, 0x92, 0x79, 0xcd, 0xc6, 0x50, 0xe7, 0xd8, 0x5b,
- 0x9a, 0xe8, 0x65, 0x13, 0x39, 0x8a, 0xda, 0xf7, 0xa6, 0x5d, 0xc6, 0x17,
- 0x39, 0x4a, 0x0c, 0x90, 0xf8, 0x72, 0x0a, 0xed, 0xfd, 0xa7, 0x68, 0xff,
- 0xb2, 0x8e, 0xc1, 0xbc, 0x77, 0x81, 0x85, 0xe2, 0x85, 0x99, 0x60, 0x31,
- 0xa2, 0x15, 0x15, 0xc4, 0x6f, 0xfa, 0x00, 0x5e, 0x30, 0xf5, 0x96, 0x87,
- 0x1c, 0xd1, 0x87, 0x8a, 0xa0, 0xaf, 0x7b, 0x5b, 0xe9, 0xc1, 0xc6, 0xc0,
- 0x08, 0xfa, 0xc8, 0x05, 0xf3, 0xf9, 0xf8, 0xba, 0x3d, 0x8c, 0x6f, 0x8e,
- 0x8b, 0xf9, 0xb8, 0x16, 0x8a, 0xff, 0x8e, 0x3c, 0xc0, 0x3f, 0x9b, 0x18,
- 0xed, 0xb0, 0x7d, 0x27, 0x90, 0xd9, 0x44, 0x7b, 0x0d, 0x8f, 0x87, 0xe9,
- 0x23, 0x23, 0x82, 0x7d, 0xf2, 0x35, 0xa3, 0x17, 0x0a, 0x98, 0x3f, 0x16,
- 0x33, 0x0f, 0x39, 0x9d, 0xb4, 0x3a, 0xdd, 0xb4, 0x6b, 0xe7, 0xa2, 0x99,
- 0x50, 0xd3, 0x37, 0xe0, 0x9d, 0x5d, 0x33, 0x51, 0x48, 0x5f, 0xaa, 0x48,
- 0xca, 0x0b, 0x55, 0xea, 0xa7, 0xd9, 0x6f, 0xec, 0x3d, 0x04, 0xda, 0x03,
- 0x8e, 0xda, 0x75, 0x49, 0x45, 0x27, 0xf6, 0xeb, 0x2d, 0xa5, 0xea, 0x4c,
- 0x78, 0x98, 0xaf, 0x94, 0xa4, 0x3d, 0x00, 0xb9, 0x32, 0x58, 0xef, 0xa7,
- 0xbb, 0x5c, 0x28, 0x37, 0x8c, 0xe8, 0x33, 0xcc, 0x81, 0x1c, 0xa3, 0x4e,
- 0xfc, 0xcc, 0x96, 0x6b, 0x1a, 0x8a, 0x47, 0x6f, 0xc0, 0xe9, 0x5d, 0x7e,
- 0xa8, 0xbc, 0x76, 0x76, 0xcf, 0x1c, 0x14, 0x8c, 0x12, 0x08, 0xd2, 0x8b,
- 0xf1, 0xd6, 0x2e, 0x15, 0xae, 0xd1, 0xbf, 0xc1, 0x87, 0xbb, 0x14, 0xcc,
- 0x9f, 0xa7, 0xa0, 0x68, 0x78, 0x84, 0x3a, 0x11, 0xee, 0x45, 0x3f, 0x4d,
- 0xc1, 0xe6, 0x5d, 0x5b, 0x92, 0xc2, 0xed, 0xc9, 0xe9, 0x06, 0x2b, 0x61,
- 0xee, 0x7e, 0xd3, 0xaa, 0x30, 0x8c, 0xd8, 0x2d, 0xaa, 0xb5, 0xb8, 0x72,
- 0x41, 0xa0, 0x65, 0x80, 0x38, 0xfd, 0x12, 0x7d, 0xe0, 0x64, 0x7f, 0xdc,
- 0xf2, 0x18, 0x8b, 0x89, 0xb5, 0x51, 0x34, 0x30, 0x37, 0x97, 0xbc, 0x7b,
- 0x9b, 0x9d, 0xef, 0xca, 0x7e, 0x63, 0x27, 0xfc, 0x63, 0x0f, 0xe3, 0x78,
- 0xc2, 0x8d, 0xc5, 0x63, 0xa5, 0xb8, 0x8e, 0x39, 0x75, 0x98, 0xdc, 0x21,
- 0xbc, 0x2f, 0xcb, 0xf1, 0x9e, 0x27, 0xc7, 0xfb, 0x15, 0xb2, 0x1c, 0x6f,
- 0x80, 0xb9, 0x5a, 0x95, 0x51, 0x8a, 0x5b, 0x06, 0x0c, 0xc6, 0x80, 0x52,
- 0x34, 0xdb, 0xeb, 0x01, 0x1a, 0x6e, 0xa3, 0xff, 0x7e, 0x9e, 0xf9, 0xf8,
- 0xcd, 0x3b, 0x03, 0xbe, 0x1d, 0x8a, 0x8f, 0x71, 0x40, 0xda, 0x3f, 0x4c,
- 0xdc, 0xf0, 0x61, 0x4e, 0xaf, 0x11, 0x5c, 0x8a, 0xc0, 0xf9, 0x43, 0xd4,
- 0xe5, 0xe2, 0xb1, 0x1b, 0x10, 0xa6, 0xee, 0xc2, 0xfb, 0x0e, 0xe7, 0xc6,
- 0x31, 0x41, 0xd9, 0x9d, 0x78, 0x6f, 0x70, 0x16, 0x5e, 0x3d, 0x90, 0xcd,
- 0xc3, 0x03, 0x7d, 0x13, 0xb2, 0x5e, 0xfc, 0x35, 0x86, 0xd7, 0x7b, 0x24,
- 0x0f, 0xff, 0x41, 0xbf, 0xde, 0x5f, 0x2a, 0xeb, 0x84, 0xf4, 0xe7, 0xaf,
- 0x2e, 0x70, 0x30, 0xbe, 0xe8, 0xfe, 0xef, 0x3b, 0xe2, 0xf2, 0x1c, 0xd9,
- 0xff, 0x08, 0xef, 0x7f, 0x9f, 0xf1, 0xfc, 0x36, 0x5e, 0x8f, 0x55, 0x32,
- 0xd7, 0x5e, 0x18, 0x3f, 0xef, 0xe2, 0xf5, 0xc7, 0x38, 0x97, 0x65, 0x46,
- 0x4d, 0xec, 0x15, 0xe5, 0x08, 0x71, 0xc3, 0x81, 0x1d, 0x21, 0x3d, 0xba,
- 0xc3, 0xce, 0xa1, 0x9d, 0x98, 0x48, 0x5f, 0x9d, 0xf3, 0xc1, 0x4a, 0x94,
- 0xec, 0x96, 0xfc, 0xc5, 0x90, 0xf5, 0x9f, 0xfe, 0x12, 0xe6, 0x4f, 0x95,
- 0x17, 0xec, 0x33, 0xbf, 0xff, 0x09, 0xee, 0x8a, 0x48, 0x33, 0x42, 0x7d,
- 0xf9, 0x7d, 0x50, 0x87, 0xd0, 0x9d, 0x7e, 0x10, 0xed, 0xbb, 0xf4, 0x76,
- 0x59, 0x1f, 0x7a, 0x25, 0x14, 0xb7, 0xca, 0x8d, 0x4e, 0xb8, 0x16, 0x18,
- 0xcd, 0xcc, 0x5d, 0x62, 0xdf, 0x56, 0x8a, 0x19, 0x3b, 0x8e, 0x61, 0xf3,
- 0xb0, 0x1e, 0xdc, 0xa1, 0x18, 0xcc, 0xf7, 0x34, 0x1c, 0x1a, 0x2c, 0xc0,
- 0xdd, 0x7b, 0x5a, 0x19, 0xdb, 0x4c, 0xe2, 0x66, 0x8d, 0xff, 0x1c, 0xde,
- 0xc7, 0x49, 0x53, 0xde, 0x11, 0x2a, 0x42, 0xab, 0x26, 0x7b, 0x80, 0x98,
- 0x79, 0x4e, 0xbb, 0xe4, 0x3d, 0x71, 0x4f, 0x91, 0x91, 0x7f, 0xdf, 0xdf,
- 0x60, 0xae, 0x38, 0x89, 0xfd, 0x83, 0xb2, 0x2e, 0x50, 0xa5, 0x1c, 0xef,
- 0x9f, 0xeb, 0xeb, 0x22, 0xe6, 0x3f, 0x64, 0x66, 0x70, 0x7e, 0x61, 0x25,
- 0x30, 0x5d, 0x41, 0xe8, 0xd3, 0x01, 0xf9, 0x9e, 0x0d, 0xff, 0xde, 0xb3,
- 0xfc, 0x5f, 0x90, 0x76, 0x4a, 0xcb, 0xb2, 0x6b, 0x05, 0x3f, 0xaa, 0x94,
- 0xf7, 0x01, 0x8f, 0x27, 0x2b, 0xca, 0xb3, 0xcf, 0x9c, 0xff, 0x54, 0x1f,
- 0x6f, 0x58, 0x7e, 0xbb, 0x8d, 0x7c, 0xdd, 0xd7, 0xad, 0xa8, 0x57, 0xca,
- 0x17, 0xb0, 0x6d, 0xf1, 0xcb, 0x2a, 0x65, 0x1d, 0x71, 0x54, 0x0d, 0x55,
- 0x29, 0xad, 0x43, 0x97, 0xb7, 0xfb, 0x9a, 0x15, 0x6d, 0x96, 0xf3, 0x7c,
- 0x39, 0x8b, 0xf7, 0xa5, 0x6c, 0xfe, 0xfe, 0x0b, 0xb9, 0xb6, 0x0a, 0xc9,
- 0x53, 0xb3, 0x65, 0xee, 0xee, 0x97, 0xfd, 0x4b, 0x51, 0x9c, 0xa8, 0x9f,
- 0xda, 0x5e, 0xbe, 0xef, 0xef, 0x5c, 0xd2, 0x5e, 0xb6, 0x6c, 0x55, 0x15,
- 0x8a, 0xa5, 0x7c, 0x06, 0xff, 0x8f, 0xbd, 0x86, 0x70, 0xc6, 0xde, 0x73,
- 0xb8, 0xcd, 0x6c, 0x88, 0x16, 0xe1, 0x33, 0x50, 0xaf, 0x8a, 0xcf, 0x2f,
- 0xb2, 0xb9, 0x6d, 0xb4, 0xb9, 0x88, 0xf9, 0xad, 0xdb, 0x88, 0x3e, 0xe4,
- 0x46, 0x26, 0xe3, 0x86, 0xde, 0x72, 0x5e, 0x39, 0xa4, 0xdc, 0x1d, 0xd0,
- 0xdb, 0xdf, 0x23, 0xd7, 0x78, 0x39, 0x10, 0xb7, 0x4a, 0x0d, 0xc3, 0xd7,
- 0xab, 0xe8, 0xe6, 0x1a, 0xc6, 0xb2, 0x17, 0x99, 0x3f, 0xb6, 0x05, 0x7a,
- 0xec, 0xe7, 0x8b, 0x4a, 0x64, 0x05, 0xae, 0xb4, 0xbf, 0xdd, 0xd2, 0x0c,
- 0x23, 0xf5, 0xb2, 0xac, 0x77, 0xf1, 0x77, 0x0c, 0xf3, 0xed, 0x6b, 0x6d,
- 0x08, 0xda, 0xff, 0x57, 0xe5, 0xbe, 0xef, 0xd2, 0x82, 0x1a, 0xfb, 0xff,
- 0x1d, 0x98, 0x9b, 0xba, 0xb0, 0x2e, 0x8c, 0x4d, 0xa6, 0x65, 0x3d, 0x67,
- 0x5a, 0x38, 0x73, 0x71, 0xbf, 0xf3, 0x0a, 0x07, 0xf3, 0x0d, 0x52, 0xac,
- 0x58, 0xf6, 0xfb, 0x54, 0x17, 0xdf, 0x97, 0x58, 0x7a, 0xc9, 0x7e, 0x67,
- 0xf9, 0xae, 0x42, 0xa5, 0xfd, 0xfd, 0xb1, 0x79, 0x8b, 0x9c, 0x78, 0x29,
- 0x51, 0x16, 0xf3, 0xf0, 0xf7, 0xe6, 0x45, 0x05, 0x58, 0x4f, 0x4e, 0xd6,
- 0x74, 0xd5, 0x33, 0x38, 0x67, 0x7f, 0xc7, 0x21, 0x1e, 0x92, 0xef, 0x37,
- 0x9c, 0x48, 0xd0, 0xa7, 0x07, 0xbb, 0x43, 0xfb, 0xed, 0xbe, 0x5f, 0xc7,
- 0xa6, 0x51, 0x79, 0xe6, 0xd7, 0x8c, 0xd5, 0x89, 0x49, 0xc6, 0x37, 0x69,
- 0x4b, 0xf2, 0x6e, 0x3d, 0xd3, 0xc6, 0x5c, 0x55, 0x75, 0x04, 0x71, 0x3b,
- 0xe3, 0xca, 0x2b, 0x09, 0xda, 0xe9, 0x42, 0xbd, 0xe3, 0xdb, 0xe4, 0x06,
- 0x65, 0x11, 0x3d, 0xf8, 0xae, 0xd2, 0x82, 0x31, 0xd6, 0x9f, 0x48, 0x88,
- 0x2d, 0x56, 0xc6, 0x0a, 0x39, 0x96, 0x43, 0xe4, 0xa3, 0x2f, 0x27, 0x34,
- 0x9c, 0xab, 0xf7, 0x20, 0x45, 0x7e, 0xfa, 0x52, 0x42, 0xb8, 0x9a, 0x17,
- 0x4f, 0x0c, 0xca, 0xfa, 0x60, 0x23, 0x1a, 0x12, 0xb2, 0x36, 0xec, 0xc5,
- 0xe3, 0x23, 0x5e, 0xda, 0xa3, 0x65, 0x6d, 0xa2, 0xed, 0xb6, 0x6a, 0x13,
- 0xec, 0x53, 0xd6, 0x14, 0xa3, 0xb8, 0xa9, 0xb7, 0x12, 0x4f, 0x8c, 0xf8,
- 0xf0, 0x3d, 0xf2, 0xf1, 0x3e, 0xd6, 0x7b, 0x25, 0xe1, 0x47, 0x6f, 0xca,
- 0x87, 0xe7, 0xc9, 0xcb, 0xb7, 0xf2, 0x5c, 0xbe, 0x05, 0x56, 0x60, 0x04,
- 0x91, 0x48, 0x1d, 0x63, 0x6c, 0xbc, 0x02, 0x6b, 0x57, 0x1e, 0x81, 0xda,
- 0x7b, 0x94, 0xc7, 0xf5, 0x8c, 0xd5, 0xd7, 0x23, 0x39, 0x18, 0x41, 0x72,
- 0xe4, 0x87, 0xe8, 0x19, 0x94, 0x71, 0xc9, 0x37, 0xa1, 0x64, 0x6f, 0x91,
- 0x81, 0xf9, 0x8c, 0xa7, 0x43, 0x23, 0xd2, 0x4f, 0x25, 0xfb, 0xfe, 0x4b,
- 0xdb, 0xff, 0x99, 0xb5, 0xf6, 0xf3, 0xd2, 0xf6, 0x91, 0x3f, 0xd1, 0xbe,
- 0xe8, 0x2a, 0xff, 0x6e, 0x9f, 0xac, 0x73, 0xb8, 0xd9, 0xa6, 0x07, 0x8e,
- 0x48, 0x66, 0x65, 0x29, 0xf4, 0xe8, 0x76, 0xc5, 0x68, 0x2a, 0x51, 0x26,
- 0xb1, 0x3d, 0x2d, 0xef, 0x71, 0x15, 0xe2, 0x79, 0x72, 0x02, 0x57, 0x48,
- 0xd7, 0xbe, 0x4d, 0xdb, 0x59, 0x42, 0x8c, 0x39, 0x63, 0x7e, 0x1a, 0x71,
- 0x4d, 0xf4, 0x57, 0x88, 0x57, 0xfb, 0xdd, 0x78, 0x37, 0xc4, 0x98, 0x6d,
- 0xef, 0xa1, 0xf6, 0xe0, 0x27, 0x09, 0x2f, 0xe7, 0xab, 0x36, 0x63, 0x38,
- 0xe6, 0x02, 0x55, 0xd9, 0x6b, 0x27, 0x12, 0x6d, 0xd8, 0x4f, 0x79, 0x5f,
- 0x49, 0x9c, 0xe7, 0xfc, 0xac, 0xa3, 0xfe, 0x45, 0xdf, 0xf1, 0x9c, 0xae,
- 0xbb, 0xa9, 0xeb, 0x99, 0x78, 0x31, 0xf1, 0x30, 0x9e, 0xa0, 0xfc, 0x8f,
- 0xf7, 0x1b, 0xd1, 0x39, 0xca, 0x31, 0x1c, 0x1a, 0x2a, 0x24, 0x7e, 0xbb,
- 0x71, 0x37, 0xb3, 0xe4, 0x49, 0xe9, 0x2b, 0x29, 0x6b, 0x93, 0x0a, 0xb9,
- 0xc7, 0x31, 0x8c, 0xf3, 0xde, 0x4f, 0xf8, 0x3b, 0xbc, 0xb0, 0x9c, 0x7d,
- 0x88, 0x7e, 0xfc, 0x76, 0x1e, 0xd0, 0x45, 0x7e, 0xb3, 0xbc, 0xfe, 0x98,
- 0xcd, 0x79, 0xba, 0x93, 0xad, 0xe8, 0xe9, 0x7f, 0x9f, 0x7c, 0x8e, 0x38,
- 0xe4, 0xad, 0xa7, 0xad, 0x67, 0xb0, 0x3d, 0xf5, 0xef, 0x55, 0x59, 0xee,
- 0xf9, 0x6a, 0x95, 0xec, 0xeb, 0x3d, 0x91, 0x28, 0xc4, 0x4b, 0xac, 0xb3,
- 0x36, 0xe4, 0xca, 0x3d, 0x2f, 0x39, 0x86, 0x5e, 0xe2, 0x6a, 0x8a, 0x7d,
- 0x24, 0xec, 0x36, 0xaa, 0x94, 0xbd, 0xf4, 0xc3, 0xf2, 0x85, 0x55, 0x4a,
- 0x92, 0xe7, 0x7d, 0xc9, 0x1f, 0xe2, 0xd9, 0x47, 0xb2, 0x3a, 0xdc, 0x6f,
- 0xb6, 0x61, 0x28, 0x75, 0x2a, 0xd7, 0xde, 0x8f, 0xa7, 0xbc, 0x9b, 0x26,
- 0xef, 0xba, 0xe4, 0xdf, 0x7b, 0xc9, 0x3e, 0xcf, 0x7a, 0x2a, 0x5d, 0x46,
- 0xde, 0x5c, 0x4c, 0x5b, 0x2b, 0x88, 0x79, 0x19, 0x4f, 0xdb, 0x16, 0x68,
- 0xd8, 0x75, 0xcd, 0x9c, 0x2a, 0x94, 0x69, 0xee, 0x5f, 0xd7, 0xbf, 0xcc,
- 0x7e, 0xca, 0x62, 0x15, 0x91, 0x8c, 0xbd, 0x07, 0x2a, 0x74, 0x4d, 0x35,
- 0x73, 0x68, 0x79, 0x2e, 0x1c, 0xc3, 0xdb, 0x89, 0xca, 0x58, 0x65, 0xa4,
- 0x9c, 0x78, 0x7b, 0x0e, 0xbd, 0xc3, 0xc4, 0x76, 0xf2, 0xe5, 0xd2, 0xbe,
- 0x4a, 0xb8, 0xed, 0x35, 0xbc, 0x2b, 0x30, 0x63, 0xf7, 0x2c, 0xf8, 0x76,
- 0xcf, 0x24, 0x5f, 0x61, 0x6e, 0x19, 0xb2, 0xac, 0x9f, 0x2f, 0xb4, 0xac,
- 0x2b, 0x79, 0x14, 0xf1, 0x38, 0x1b, 0x12, 0x3f, 0x8d, 0xa2, 0xd6, 0xf6,
- 0x57, 0x03, 0x75, 0xf6, 0xff, 0x46, 0xfa, 0x7a, 0x47, 0x68, 0xfe, 0xf8,
- 0xc3, 0xa1, 0xb9, 0xe3, 0xd5, 0x50, 0x07, 0xa6, 0xc1, 0xc1, 0xb6, 0x3e,
- 0x77, 0x8d, 0x85, 0x46, 0xfa, 0xf0, 0x1a, 0x53, 0xf8, 0x50, 0x1b, 0xf9,
- 0x50, 0x4f, 0xc8, 0x18, 0x3f, 0x82, 0x1b, 0xc9, 0x97, 0xdd, 0x03, 0x3e,
- 0xf6, 0x23, 0xf9, 0xb5, 0x33, 0x33, 0x9b, 0x3c, 0xfb, 0xd3, 0x0b, 0x85,
- 0x1b, 0xb5, 0x90, 0x1b, 0x1d, 0x45, 0xcb, 0xf8, 0x31, 0xdc, 0xca, 0x32,
- 0x1e, 0xe6, 0xfd, 0x7d, 0xe9, 0x1f, 0x92, 0x77, 0x58, 0x8c, 0x39, 0x19,
- 0xdc, 0xcc, 0xb6, 0x8b, 0x07, 0x9a, 0x70, 0xf7, 0xf8, 0x0a, 0xac, 0x1d,
- 0xb7, 0xb0, 0x3c, 0x34, 0x81, 0xe5, 0xe3, 0xe4, 0x9a, 0xe3, 0x79, 0x7f,
- 0x15, 0x9e, 0xb4, 0x82, 0x3c, 0x49, 0xe2, 0xd0, 0x2a, 0x7b, 0x1d, 0x4d,
- 0xa5, 0x1f, 0x36, 0x24, 0xe4, 0x9d, 0x9b, 0x38, 0x56, 0x8f, 0x0b, 0x56,
- 0x3f, 0x88, 0x4d, 0xe3, 0xb2, 0x2e, 0xfb, 0xf5, 0xd0, 0x9c, 0xf1, 0xd7,
- 0xd1, 0x30, 0x3e, 0x14, 0x9a, 0x37, 0x3e, 0x42, 0xb9, 0x13, 0x94, 0xad,
- 0x3f, 0x54, 0x33, 0x3e, 0x18, 0x0a, 0x8e, 0xef, 0x0d, 0x05, 0xc6, 0x9b,
- 0xb1, 0x75, 0x7c, 0x15, 0xb6, 0x8c, 0xb7, 0x63, 0xf3, 0xb8, 0xe0, 0xfc,
- 0x24, 0x96, 0x8d, 0x9f, 0xc1, 0xd2, 0xf1, 0x97, 0xd1, 0x38, 0x7e, 0x0a,
- 0x4b, 0xc6, 0x7f, 0x88, 0xa6, 0xf1, 0x1f, 0x73, 0x2c, 0xb2, 0xce, 0x2b,
- 0x6b, 0xbc, 0xf9, 0x67, 0x6a, 0xf9, 0xf7, 0x44, 0xf3, 0xdf, 0xd7, 0x70,
- 0x21, 0xaa, 0xbd, 0x81, 0xee, 0x3d, 0xf2, 0xbd, 0xc1, 0x5a, 0x6d, 0x93,
- 0xfd, 0xbe, 0xc1, 0xcb, 0xb2, 0x4f, 0x1d, 0x45, 0xc6, 0xe5, 0xef, 0xc5,
- 0xcb, 0x77, 0x31, 0xe4, 0x39, 0xe7, 0x24, 0xba, 0xd2, 0xe7, 0xad, 0xa8,
- 0x26, 0x65, 0xde, 0xc0, 0xe6, 0x3d, 0xf2, 0x3e, 0x71, 0x06, 0x5d, 0x49,
- 0x79, 0x0e, 0x2f, 0xef, 0xa0, 0xbf, 0x81, 0x2d, 0xa3, 0xb6, 0xaf, 0xa1,
- 0x71, 0x48, 0xde, 0x89, 0x69, 0xc3, 0x75, 0xc9, 0x8c, 0xbd, 0x56, 0x5e,
- 0x66, 0xe0, 0xef, 0x67, 0xe0, 0x41, 0xe6, 0x04, 0x05, 0xe4, 0xfd, 0xc5,
- 0xe8, 0x7c, 0x24, 0x6e, 0x15, 0x1a, 0x1e, 0xcc, 0x88, 0x18, 0x99, 0x77,
- 0x1d, 0xc5, 0xe8, 0xe0, 0xb5, 0xfb, 0x76, 0xc2, 0xef, 0x33, 0x44, 0xf7,
- 0x81, 0xd8, 0x28, 0x63, 0xec, 0x86, 0x7d, 0x19, 0xf2, 0x8b, 0x0e, 0xf8,
- 0xf9, 0x7f, 0x7b, 0x52, 0xf6, 0x21, 0x6d, 0x42, 0x74, 0x9f, 0xe8, 0xb0,
- 0x99, 0x3a, 0x9c, 0x64, 0xdc, 0x90, 0x67, 0x38, 0x46, 0x70, 0x2b, 0x64,
- 0x9d, 0x52, 0xc5, 0xf7, 0x06, 0xe5, 0x79, 0x83, 0xde, 0xf1, 0x25, 0xfa,
- 0xf4, 0x87, 0xca, 0x0f, 0x51, 0x76, 0x40, 0xf8, 0xd2, 0x04, 0x7a, 0x84,
- 0x6f, 0x47, 0x14, 0x23, 0x15, 0x38, 0x0b, 0xcf, 0x01, 0xc1, 0x5d, 0x27,
- 0x4a, 0xc6, 0xe4, 0xfb, 0x38, 0x40, 0x31, 0xf3, 0x12, 0x1c, 0x20, 0xa7,
- 0x3d, 0x70, 0x0a, 0xd8, 0x27, 0xeb, 0x56, 0xaf, 0x61, 0x72, 0x48, 0xe6,
- 0xad, 0x8d, 0xf3, 0x26, 0x7e, 0xf8, 0x7d, 0x0c, 0x0f, 0x79, 0xe8, 0xe3,
- 0x13, 0x1c, 0xc7, 0xeb, 0x78, 0x74, 0x8f, 0x3c, 0x17, 0x99, 0x89, 0x36,
- 0xd6, 0x3b, 0xc1, 0x3c, 0xbf, 0x75, 0xcc, 0xe4, 0x78, 0x56, 0xa1, 0xf3,
- 0xc0, 0x17, 0x78, 0x4c, 0xc3, 0x43, 0x07, 0xd6, 0x71, 0x8c, 0x71, 0x74,
- 0x8c, 0x75, 0xf3, 0x68, 0xc5, 0xc6, 0x9d, 0x26, 0xb9, 0xa0, 0xd8, 0xb4,
- 0x46, 0x3f, 0x6b, 0xe5, 0x98, 0xa4, 0x8f, 0xd5, 0xf8, 0x19, 0x31, 0xa6,
- 0x29, 0xb4, 0x1a, 0xe7, 0x6c, 0xbf, 0x5b, 0x8d, 0x2d, 0xfd, 0x46, 0xf0,
- 0x24, 0x56, 0x63, 0x33, 0xcf, 0x1f, 0xa5, 0xef, 0xcf, 0x21, 0x17, 0xbc,
- 0x93, 0xbe, 0xbd, 0x78, 0x78, 0x42, 0xbe, 0x9d, 0x80, 0xbe, 0x5d, 0x32,
- 0x1f, 0x6d, 0xf0, 0x8d, 0x65, 0x50, 0x3e, 0xc6, 0xec, 0x79, 0x27, 0xee,
- 0x2a, 0x43, 0x39, 0xbe, 0x11, 0x92, 0x3d, 0x0b, 0x3f, 0x40, 0xf1, 0x3e,
- 0x91, 0xf5, 0x87, 0x6c, 0xfb, 0x1c, 0x73, 0xf1, 0x53, 0x9c, 0x83, 0xfc,
- 0xb3, 0xf1, 0x5f, 0xe0, 0x60, 0x6a, 0x92, 0xb8, 0x7a, 0x9a, 0xc7, 0xe5,
- 0xcf, 0xa5, 0xbd, 0x76, 0x8e, 0x92, 0xdd, 0xff, 0xed, 0xc4, 0x8c, 0x3e,
- 0x59, 0xdf, 0x6d, 0x86, 0x2f, 0x29, 0x7c, 0x27, 0xb3, 0x8d, 0xf9, 0x4a,
- 0x7b, 0xd8, 0xe6, 0x3f, 0x46, 0x8c, 0xbc, 0xa7, 0xf9, 0xdb, 0x8a, 0x87,
- 0xbc, 0x27, 0x88, 0x15, 0x69, 0x3d, 0x7a, 0x33, 0xf5, 0x5b, 0xf4, 0xc8,
- 0x8f, 0xe0, 0x7c, 0xc4, 0x89, 0x42, 0xe6, 0x37, 0xa1, 0x90, 0xe8, 0x59,
- 0xde, 0x95, 0xcd, 0xe8, 0x85, 0xc4, 0xcc, 0x82, 0xbe, 0x0c, 0xe7, 0x27,
- 0x33, 0xbf, 0x00, 0x7e, 0xce, 0xcd, 0x0d, 0x68, 0xeb, 0x8f, 0x72, 0x6e,
- 0x3e, 0x45, 0x1b, 0x9b, 0xa0, 0xbd, 0x48, 0x4e, 0xf4, 0x32, 0x65, 0x74,
- 0xe5, 0xbe, 0xc9, 0x93, 0xd1, 0x9d, 0xd0, 0x4d, 0xbf, 0x5a, 0x95, 0x7d,
- 0x27, 0x05, 0xf6, 0xb3, 0xe7, 0x30, 0xf0, 0x06, 0x6d, 0x33, 0xcf, 0x67,
- 0x2c, 0xab, 0x9d, 0xf6, 0xd5, 0x3f, 0x2a, 0xbe, 0xb2, 0xb4, 0x2a, 0xfb,
- 0xbe, 0xee, 0x54, 0xae, 0x93, 0xaf, 0xeb, 0x20, 0x36, 0xe6, 0xef, 0xff,
- 0x08, 0x77, 0x32, 0x7e, 0x9d, 0x59, 0x78, 0x2a, 0x67, 0xf3, 0xd3, 0xab,
- 0xb3, 0xf8, 0xf5, 0x49, 0xdf, 0x0b, 0xfa, 0x2b, 0xfb, 0xdb, 0x3b, 0xd9,
- 0x6f, 0x1f, 0x01, 0xcf, 0x26, 0x0a, 0xe4, 0x29, 0xc1, 0x62, 0x17, 0x54,
- 0xaf, 0x0b, 0x85, 0x8c, 0x01, 0xd5, 0xd8, 0xe4, 0xb5, 0x70, 0xa3, 0x59,
- 0x80, 0x43, 0x75, 0xb7, 0x00, 0x15, 0xf1, 0x16, 0x97, 0xfd, 0x4e, 0xde,
- 0xef, 0xbf, 0xf4, 0x87, 0xef, 0xe4, 0x9d, 0xb1, 0xf3, 0xe1, 0x52, 0xe3,
- 0x76, 0xbc, 0x62, 0xc7, 0x09, 0x05, 0x25, 0x73, 0x65, 0x5d, 0xd2, 0x8f,
- 0x17, 0x8d, 0x5a, 0x7f, 0x85, 0x3c, 0x6f, 0x52, 0xce, 0x5a, 0x71, 0xaf,
- 0xbc, 0x87, 0xf7, 0xc7, 0xf6, 0x8f, 0x3f, 0x87, 0xad, 0xbb, 0xc2, 0x90,
- 0xf7, 0x3b, 0x9c, 0x46, 0xa1, 0x37, 0x2b, 0xbf, 0xc8, 0x26, 0xeb, 0x44,
- 0xb7, 0x71, 0x1c, 0x67, 0xe8, 0x8b, 0x67, 0xec, 0x75, 0x2a, 0xb7, 0xf1,
- 0xd7, 0x08, 0x56, 0xe4, 0xc7, 0x2f, 0x39, 0x8d, 0x92, 0xd5, 0x41, 0xf6,
- 0xfd, 0xda, 0x6a, 0xc1, 0xfe, 0x2d, 0xc9, 0x33, 0xf6, 0x9a, 0xac, 0xcb,
- 0xf8, 0x0f, 0xeb, 0x2d, 0x6f, 0x25, 0xcb, 0x3e, 0x95, 0xbb, 0x3f, 0x29,
- 0xeb, 0x38, 0xa6, 0x7c, 0xbb, 0xca, 0x69, 0xd7, 0x11, 0xbd, 0x5f, 0xac,
- 0xb3, 0x89, 0xbc, 0x7a, 0xb6, 0x71, 0xca, 0xea, 0xf4, 0xca, 0x18, 0xd6,
- 0x5c, 0x56, 0x47, 0xd6, 0x08, 0x34, 0xe9, 0x37, 0x2c, 0x63, 0xee, 0x4a,
- 0xff, 0x61, 0x9f, 0xb2, 0x7e, 0x5b, 0x60, 0x94, 0xe0, 0x6c, 0x45, 0x76,
- 0x4d, 0xe5, 0xa2, 0x8c, 0xed, 0xd5, 0xb2, 0xef, 0xae, 0xd0, 0x3e, 0xb7,
- 0xfb, 0x35, 0x2f, 0xd6, 0x7b, 0x30, 0x37, 0xde, 0x4a, 0xfb, 0x9d, 0x9a,
- 0x47, 0x6d, 0xae, 0xe3, 0x98, 0x32, 0xee, 0xdf, 0x78, 0x2f, 0xed, 0xe7,
- 0xf3, 0xb9, 0x7e, 0x45, 0x1e, 0xef, 0x94, 0x3e, 0x44, 0xae, 0xde, 0x5c,
- 0x1d, 0x3d, 0x1c, 0xb5, 0xfb, 0x57, 0x11, 0xde, 0x93, 0xef, 0xd3, 0xb2,
- 0x0a, 0x16, 0xe6, 0xdb, 0xc8, 0xd0, 0x0f, 0xad, 0xce, 0x42, 0xc6, 0xab,
- 0xb3, 0xf5, 0x0f, 0x62, 0x73, 0x42, 0xf4, 0x2c, 0xdf, 0x70, 0x25, 0x2e,
- 0xdb, 0xfc, 0xcb, 0xc5, 0x5c, 0xf6, 0x1a, 0x0c, 0x69, 0x71, 0xec, 0xaf,
- 0x93, 0x77, 0xc8, 0x5c, 0xf4, 0x85, 0x38, 0x71, 0xb0, 0x90, 0x38, 0x1a,
- 0xb7, 0xf7, 0x94, 0x1c, 0x34, 0xf5, 0xe8, 0xb3, 0xf2, 0x8d, 0xb2, 0xab,
- 0xec, 0xb5, 0xa7, 0xa6, 0x21, 0xc8, 0xf5, 0xfc, 0x7a, 0x52, 0xfe, 0xaf,
- 0x88, 0xb6, 0x23, 0x72, 0x89, 0x0d, 0x50, 0xba, 0x84, 0xbc, 0xeb, 0x54,
- 0x1b, 0x23, 0x67, 0xc4, 0x2b, 0x29, 0xd9, 0x7f, 0xf0, 0x5b, 0x2b, 0x5e,
- 0x2d, 0xfb, 0x1c, 0xa7, 0xd6, 0x29, 0x20, 0x97, 0x0b, 0x84, 0xcb, 0x94,
- 0xfc, 0xfb, 0x4e, 0x17, 0xff, 0x6e, 0xa5, 0xcd, 0x9c, 0xb3, 0xdf, 0x51,
- 0x93, 0xb3, 0x08, 0x1a, 0x92, 0xf2, 0xad, 0x52, 0x7d, 0x62, 0x39, 0x6a,
- 0x33, 0x35, 0x0e, 0x67, 0x8e, 0x93, 0x84, 0xb1, 0x82, 0x76, 0xb3, 0x25,
- 0x10, 0xb6, 0xdf, 0xc5, 0x5a, 0x96, 0xac, 0x09, 0x3e, 0xce, 0x1c, 0xfa,
- 0x1d, 0x96, 0xbf, 0x25, 0xfd, 0x3d, 0x6b, 0xc8, 0x2b, 0x63, 0xca, 0x63,
- 0xc3, 0x29, 0xfa, 0x06, 0xf5, 0x18, 0x11, 0xff, 0xf0, 0xa0, 0x22, 0x12,
- 0xa6, 0xff, 0x4a, 0x4c, 0x97, 0xf7, 0xb8, 0xf4, 0xbd, 0x71, 0x98, 0xc4,
- 0xfc, 0x1e, 0xda, 0x91, 0xec, 0x5b, 0xd6, 0xfd, 0x2b, 0x19, 0x5b, 0x8e,
- 0x5f, 0x78, 0xc6, 0x2f, 0x1c, 0xe0, 0xd9, 0xea, 0xdc, 0xde, 0x66, 0xf7,
- 0x6c, 0xc6, 0x3c, 0xcb, 0x7e, 0x6e, 0xdf, 0x66, 0x63, 0x8a, 0x66, 0xe8,
- 0x87, 0x7e, 0xe5, 0xe8, 0xc4, 0xd3, 0x0b, 0x8c, 0x8e, 0xc3, 0x6a, 0x66,
- 0xc8, 0x47, 0x7c, 0xb9, 0xde, 0x11, 0xdd, 0xc9, 0xff, 0xfe, 0xd7, 0xec,
- 0x6f, 0xab, 0x48, 0x5d, 0x3d, 0xb8, 0x4a, 0x95, 0xfd, 0x40, 0xcd, 0x18,
- 0xeb, 0x95, 0x77, 0x06, 0xf4, 0x96, 0xa7, 0x94, 0x4e, 0x6c, 0x08, 0x19,
- 0xcd, 0xed, 0x8a, 0xde, 0xf4, 0x0f, 0x8a, 0xee, 0x0f, 0x29, 0x52, 0x2e,
- 0xc8, 0xbc, 0xeb, 0x62, 0x3c, 0x75, 0xb1, 0x8f, 0x03, 0x09, 0x3d, 0x5c,
- 0xc5, 0xb2, 0x67, 0x4d, 0xc3, 0xf7, 0x3e, 0xdb, 0xfc, 0x57, 0x1e, 0x3b,
- 0xed, 0xf7, 0xc4, 0xa5, 0x7c, 0x74, 0xbe, 0xcb, 0xfe, 0xbe, 0x69, 0x0b,
- 0xe3, 0xae, 0x7c, 0x23, 0x38, 0x06, 0xad, 0x6f, 0x26, 0x4d, 0x4c, 0xef,
- 0xb9, 0x0d, 0xb2, 0xe7, 0xa0, 0x89, 0x09, 0xba, 0x07, 0xde, 0x48, 0x27,
- 0xe6, 0x2e, 0x30, 0x7c, 0x8b, 0x54, 0xbb, 0x7e, 0x30, 0xaa, 0x4a, 0x7d,
- 0xdd, 0x3f, 0x08, 0x69, 0x23, 0x63, 0x69, 0x73, 0xcb, 0xed, 0x3a, 0x0b,
- 0xd4, 0xcf, 0xc0, 0x75, 0xf5, 0xaf, 0xe5, 0x5b, 0x46, 0x5a, 0xa5, 0x21,
- 0x75, 0xe2, 0x3b, 0x35, 0xfc, 0xb1, 0x7a, 0x82, 0x2b, 0xbf, 0xb2, 0x30,
- 0x4d, 0xea, 0xc9, 0x9e, 0xb1, 0x3b, 0x70, 0xaf, 0xfd, 0x3d, 0x16, 0xf1,
- 0x47, 0x3d, 0xfa, 0x15, 0xf2, 0xcf, 0x62, 0x45, 0xb8, 0xa7, 0xf0, 0x84,
- 0x56, 0x74, 0x33, 0x8e, 0x69, 0x21, 0xbd, 0xe7, 0x0a, 0xd5, 0x83, 0xc2,
- 0xc8, 0x63, 0xb2, 0x6f, 0x66, 0xef, 0x3c, 0x35, 0xbb, 0xbf, 0x26, 0xc6,
- 0x76, 0x8f, 0xff, 0xd1, 0xe7, 0xb8, 0xec, 0xab, 0xd8, 0x94, 0xf7, 0x5b,
- 0xec, 0x35, 0xc5, 0xd6, 0x84, 0x23, 0xb7, 0x5f, 0x30, 0x3f, 0xb7, 0x1a,
- 0xda, 0xc8, 0xf5, 0xd7, 0xc8, 0x37, 0x31, 0x39, 0xd6, 0xb5, 0x09, 0x59,
- 0x4d, 0xfa, 0xff, 0x00, 0x85, 0x57, 0x0f, 0xe7, 0xe8, 0x59, 0x00, 0x00,
- 0x00 };
-
-static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
- 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
- 0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
- 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000001, 0x00000001, 0x00000001, 0x00000000 };
-static const u32 bnx2_CP_b06FwRodata[(0x130/4) + 1] = {
- 0x08001f1c, 0x08001da8, 0x08001ef8, 0x08001ed4, 0x08001eb0, 0x08001e8c,
- 0x08001e64, 0x08001e3c, 0x08001e10, 0x08002014, 0x08002004, 0x08001dc4,
- 0x08001dc4, 0x08001dc4, 0x08001f44, 0x08001f44, 0x08001dc4, 0x08001dc4,
- 0x08001ff4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001fe4,
- 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
- 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
- 0x08001dc4, 0x08001dc4, 0x08001fd4, 0x08001dc4, 0x08001dc4, 0x08001fc4,
- 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
- 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
- 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001fac,
- 0x08001dc4, 0x08001dc4, 0x08001f9c, 0x08001f8c, 0x080031e8, 0x080031f0,
- 0x080031b8, 0x080031c4, 0x080031d0, 0x080031dc, 0x08005644, 0x08005604,
- 0x080055d0, 0x080055a4, 0x08005580, 0x0800553c, 0x00000000 };
-
-static struct fw_info bnx2_cp_fw_06 = {
- /* Firmware version: 4.0.5 */
- .ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
-
- .start_addr = 0x08000078,
-
- .text_addr = 0x08000000,
- .text_len = 0x59e4,
- .text_index = 0x0,
- .gz_text = bnx2_CP_b06FwText,
- .gz_text_len = sizeof(bnx2_CP_b06FwText),
-
- .data_addr = 0x08005b40,
- .data_len = 0x84,
- .data_index = 0x0,
- .data = bnx2_CP_b06FwData,
-
- .sbss_addr = 0x08005bc4,
- .sbss_len = 0xe9,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08005cb0,
- .bss_len = 0x5d8,
- .bss_index = 0x0,
-
- .rodata_addr = 0x080059e4,
- .rodata_len = 0x130,
- .rodata_index = 0x0,
- .rodata = bnx2_CP_b06FwRodata,
-};
-
-/* Initialized Values the Command Processor. */
-static const struct cpu_reg cpu_reg_cp = {
- .mode = BNX2_CP_CPU_MODE,
- .mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT,
- .mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA,
- .state = BNX2_CP_CPU_STATE,
- .state_value_clear = 0xffffff,
- .gpr0 = BNX2_CP_CPU_REG_FILE,
- .evmask = BNX2_CP_CPU_EVENT_MASK,
- .pc = BNX2_CP_CPU_PROGRAM_COUNTER,
- .inst = BNX2_CP_CPU_INSTRUCTION,
- .bp = BNX2_CP_CPU_HW_BREAKPOINT,
- .spad_base = BNX2_CP_SCRATCH,
- .mips_view_base = 0x8000000,
-};
-
-static u8 bnx2_RXP_b06FwText[] = {
- 0xec, 0x5b, 0x5d, 0x70, 0x5c, 0xd7, 0x5d, 0xff, 0xdf, 0xb3, 0x2b, 0x69,
- 0x2d, 0x4b, 0xf2, 0x95, 0xbc, 0x71, 0x56, 0xa9, 0x92, 0xec, 0x5a, 0x57,
- 0xd2, 0xa6, 0x12, 0xe1, 0xca, 0x6c, 0x12, 0x75, 0xd8, 0x69, 0xb6, 0xbb,
- 0xb2, 0xa3, 0xb4, 0x66, 0x46, 0x49, 0x0d, 0xcd, 0xb4, 0x65, 0x10, 0xbb,
- 0x0e, 0xa4, 0x0f, 0x0c, 0xc6, 0x40, 0x26, 0x80, 0xc1, 0xcb, 0x4a, 0x71,
- 0x94, 0x74, 0xad, 0xdd, 0xda, 0x0a, 0x86, 0x69, 0x61, 0x94, 0xd5, 0x87,
- 0x53, 0x66, 0xad, 0x4d, 0xcb, 0x4b, 0x99, 0xd6, 0xb1, 0xea, 0xb8, 0x26,
- 0x0f, 0x3c, 0xa4, 0x94, 0xce, 0x64, 0x20, 0x33, 0x35, 0xb2, 0x63, 0xfb,
- 0x81, 0x8f, 0xc0, 0x4c, 0x49, 0x20, 0x6e, 0x2e, 0xbf, 0xdf, 0xb9, 0xf7,
- 0xca, 0x2b, 0x45, 0xd0, 0x3c, 0xf0, 0x78, 0xcf, 0x8c, 0xe6, 0xde, 0x7b,
- 0xce, 0xff, 0xfc, 0xcf, 0xff, 0xfb, 0xe3, 0xac, 0xfd, 0x3b, 0x1d, 0xd2,
- 0x2e, 0xde, 0xe8, 0xc4, 0x5f, 0xea, 0xc8, 0x33, 0x47, 0x47, 0xef, 0x1f,
- 0xbd, 0x9f, 0xdf, 0x21, 0xc3, 0x08, 0xf3, 0x69, 0x48, 0x30, 0x82, 0x11,
- 0x8c, 0x60, 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c,
- 0x60, 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60,
- 0x04, 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04,
- 0x23, 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04, 0x23,
- 0x18, 0xc1, 0x08, 0x46, 0x30, 0x82, 0x11, 0x8c, 0x60, 0x04, 0x23, 0x18,
- 0xc1, 0x08, 0x46, 0x30, 0xfe, 0x3f, 0x47, 0x48, 0xc4, 0xe4, 0xb3, 0xd3,
- 0xfb, 0x93, 0x88, 0x4a, 0xc7, 0x8f, 0x66, 0x2d, 0x89, 0x84, 0xd2, 0x97,
- 0x9e, 0x2e, 0x58, 0x22, 0x99, 0xfa, 0x70, 0x3c, 0x27, 0x3f, 0x71, 0x8a,
- 0xd1, 0xb0, 0x70, 0xfe, 0xee, 0xf4, 0xad, 0xe3, 0xe7, 0x1f, 0x4a, 0xbc,
- 0xb3, 0x10, 0x92, 0x88, 0x99, 0x7e, 0x63, 0xd4, 0x1c, 0x94, 0x48, 0x1f,
- 0xf6, 0x7c, 0x6d, 0x68, 0x6d, 0x97, 0x74, 0xf9, 0xb8, 0x44, 0x6a, 0xe5,
- 0x84, 0x7d, 0x40, 0x86, 0xcd, 0x8b, 0x12, 0x96, 0x0c, 0xce, 0x58, 0xa9,
- 0x8b, 0x94, 0xca, 0x06, 0x71, 0x48, 0xa9, 0x1e, 0x91, 0x2b, 0x21, 0x42,
- 0x7d, 0xcb, 0xc8, 0x56, 0x3e, 0x70, 0x32, 0x61, 0x9c, 0x6b, 0xe1, 0xbd,
- 0xe1, 0xcf, 0x47, 0x44, 0xa5, 0x13, 0xc9, 0x6c, 0x68, 0x42, 0x6a, 0xf3,
- 0x8e, 0x33, 0x63, 0x7f, 0x0c, 0x38, 0x7a, 0x64, 0xc6, 0x72, 0xbf, 0xb3,
- 0xf6, 0xc7, 0xcd, 0x71, 0xb9, 0x13, 0x73, 0x21, 0x51, 0xd6, 0x5d, 0xf8,
- 0x8b, 0x1b, 0xb9, 0xd3, 0x5f, 0x36, 0xb2, 0x8b, 0x1d, 0x52, 0xaa, 0x38,
- 0x52, 0xb0, 0x25, 0x93, 0xb5, 0x77, 0x60, 0xfd, 0x03, 0xa7, 0xb0, 0xb1,
- 0x67, 0xd8, 0xcc, 0x49, 0x8b, 0x64, 0xa2, 0x31, 0xc0, 0xcc, 0x1b, 0xb9,
- 0xb3, 0x7f, 0xdd, 0x21, 0xed, 0xa0, 0x27, 0xc5, 0xef, 0x0f, 0x9c, 0x90,
- 0x65, 0x61, 0x9d, 0xe7, 0xe3, 0xbb, 0x41, 0xbc, 0x7c, 0x27, 0xce, 0x2b,
- 0xce, 0xf9, 0xa1, 0x98, 0x7c, 0xb3, 0x11, 0x95, 0x6f, 0x34, 0x4c, 0x79,
- 0xa5, 0xd1, 0x27, 0x17, 0x1a, 0x8e, 0xf3, 0x0d, 0xdb, 0x71, 0xde, 0xc0,
- 0xdf, 0x7f, 0xd8, 0x1b, 0x3c, 0x60, 0x14, 0x8d, 0xf1, 0xc6, 0x57, 0x3b,
- 0xa4, 0x2b, 0x11, 0x17, 0xd5, 0x21, 0xd3, 0x95, 0x98, 0xcc, 0x54, 0xca,
- 0xc6, 0x63, 0x67, 0xe7, 0x8c, 0xc9, 0xb3, 0x55, 0x9c, 0x19, 0xc6, 0x9c,
- 0x14, 0x4b, 0xf6, 0xcb, 0x46, 0xae, 0x31, 0x6b, 0x3c, 0x7e, 0xb6, 0x0b,
- 0x34, 0xf2, 0xfc, 0x3d, 0x46, 0xf6, 0xf4, 0x2d, 0xc9, 0xda, 0x94, 0x71,
- 0xc2, 0xfc, 0x3c, 0xc4, 0x9e, 0x2d, 0x93, 0xe6, 0x56, 0x8f, 0x5e, 0xc7,
- 0x51, 0x69, 0xe7, 0x78, 0x36, 0x65, 0x99, 0x25, 0x21, 0x7d, 0x7a, 0xee,
- 0x82, 0x4b, 0xf3, 0x8a, 0x91, 0x3d, 0xdb, 0x61, 0xe4, 0xce, 0x84, 0x41,
- 0x87, 0xf4, 0x85, 0x84, 0xfb, 0x06, 0x62, 0x79, 0xa9, 0xe3, 0x0c, 0x31,
- 0x55, 0x9a, 0x72, 0x05, 0xcd, 0xa0, 0xe5, 0x9b, 0x15, 0xf0, 0x50, 0x01,
- 0x0f, 0x15, 0xf2, 0x16, 0x97, 0xf3, 0x43, 0x3e, 0x6f, 0x8e, 0xf3, 0x77,
- 0x36, 0x69, 0x4f, 0xc4, 0x33, 0xca, 0xe7, 0xd3, 0x71, 0xfe, 0xdd, 0x26,
- 0xaf, 0xe4, 0xc7, 0x71, 0x5e, 0xb1, 0x63, 0xa0, 0xdd, 0xb9, 0xa0, 0xac,
- 0x32, 0x78, 0xb1, 0x80, 0x9f, 0xb2, 0x9e, 0x03, 0x0f, 0xb3, 0xe0, 0x6f,
- 0x05, 0xbc, 0x55, 0x41, 0xc7, 0x4f, 0x3b, 0xaf, 0x68, 0xe4, 0x86, 0x36,
- 0xe4, 0x15, 0xa7, 0x8c, 0xf3, 0x4b, 0x0a, 0xb2, 0xde, 0x29, 0xf9, 0x05,
- 0x53, 0xa6, 0x96, 0xfc, 0xfd, 0xbe, 0x1d, 0x1c, 0x91, 0x83, 0x95, 0x1e,
- 0xc8, 0x86, 0xb2, 0x4c, 0xd8, 0x22, 0x0e, 0x64, 0x54, 0x4a, 0x2a, 0x11,
- 0x23, 0x6f, 0x1f, 0xd7, 0xfa, 0x5f, 0xb2, 0x24, 0x93, 0xb7, 0x29, 0x47,
- 0x89, 0xe7, 0xed, 0x62, 0x2c, 0x0c, 0x7b, 0x5b, 0xb2, 0x8a, 0x66, 0x58,
- 0x28, 0xc7, 0x44, 0xec, 0xf7, 0x21, 0xcb, 0x27, 0xcb, 0x92, 0xf9, 0x74,
- 0xd9, 0x97, 0xb1, 0x2b, 0xdf, 0xcf, 0x94, 0x3f, 0xd5, 0x29, 0xed, 0xea,
- 0x9e, 0x16, 0xf9, 0x0d, 0xec, 0x25, 0xee, 0x4d, 0x7b, 0xb1, 0xcf, 0x85,
- 0x73, 0xf7, 0x26, 0x9e, 0x10, 0x21, 0x6c, 0xa9, 0xbf, 0x45, 0xfb, 0x88,
- 0x18, 0x59, 0xab, 0x18, 0x0b, 0x01, 0x2e, 0x2f, 0xa5, 0x51, 0x6f, 0xae,
- 0x25, 0x6b, 0xdd, 0x0a, 0xcd, 0xd8, 0x89, 0x78, 0x49, 0x6e, 0x85, 0x2e,
- 0xdb, 0x7a, 0x6e, 0x47, 0xd6, 0x72, 0x64, 0x19, 0xd8, 0x9f, 0x83, 0x3f,
- 0x5c, 0x04, 0x47, 0x5f, 0x2a, 0xeb, 0xf9, 0x4e, 0xec, 0x4f, 0xb6, 0x00,
- 0x67, 0xbb, 0x24, 0x92, 0x35, 0xcc, 0x5f, 0x76, 0xe7, 0xbb, 0x5d, 0xbc,
- 0xa5, 0xfe, 0x76, 0x8d, 0x5b, 0xe4, 0x65, 0x77, 0xfe, 0x0e, 0x17, 0x77,
- 0xe9, 0x3e, 0xcc, 0x03, 0xff, 0xe0, 0xc4, 0x90, 0xa1, 0xe7, 0x7b, 0xe9,
- 0x4f, 0xbf, 0x5e, 0xbe, 0x15, 0x5a, 0xb6, 0x1d, 0xc9, 0x8d, 0x0e, 0x4e,
- 0x0c, 0x1a, 0x2e, 0xbe, 0x13, 0xee, 0xbe, 0xbb, 0x5d, 0x7c, 0x83, 0x13,
- 0x49, 0xc3, 0xc5, 0xb7, 0x54, 0xd6, 0x7b, 0x25, 0x5f, 0x26, 0xec, 0xe0,
- 0x84, 0x65, 0xdc, 0x2d, 0x53, 0xdd, 0x83, 0x13, 0x7b, 0x0d, 0x75, 0xcf,
- 0x4e, 0x97, 0x8f, 0x84, 0x4f, 0xc3, 0x4e, 0x4d, 0x03, 0xcf, 0xd5, 0xf3,
- 0x03, 0x59, 0xab, 0x74, 0xdf, 0x4e, 0x7d, 0x3e, 0xcf, 0xd4, 0x73, 0xf7,
- 0x91, 0x2e, 0x9e, 0x5d, 0x18, 0xdd, 0x74, 0xee, 0xcf, 0xdc, 0x96, 0xcf,
- 0x76, 0x67, 0xf2, 0x3c, 0x89, 0x84, 0xd3, 0xe1, 0xd1, 0x99, 0xf2, 0x11,
- 0xc9, 0x56, 0xe2, 0x32, 0x3d, 0xb2, 0x43, 0xa6, 0xcc, 0xfe, 0xa9, 0x83,
- 0xc2, 0xd8, 0x13, 0x19, 0x2d, 0x78, 0x3a, 0xcc, 0x89, 0x21, 0xd3, 0xe0,
- 0xf1, 0x60, 0x5d, 0x22, 0x06, 0xe0, 0xfb, 0xeb, 0x61, 0x79, 0xbe, 0x61,
- 0x48, 0xab, 0xf6, 0xcf, 0x84, 0xb9, 0x06, 0x3b, 0x7c, 0xb6, 0x42, 0x3b,
- 0xa6, 0xcd, 0x4a, 0xa6, 0x06, 0x3b, 0xbd, 0xa0, 0x7d, 0xb5, 0x9d, 0x7a,
- 0x2d, 0x16, 0x05, 0xae, 0x98, 0xb6, 0xcc, 0x9a, 0xb4, 0x49, 0x66, 0x52,
- 0x8a, 0x5c, 0xf7, 0x7c, 0x27, 0xb6, 0x28, 0xdf, 0x85, 0x0d, 0x88, 0x99,
- 0x4d, 0x71, 0x9e, 0xf0, 0x4d, 0xb0, 0xa6, 0xeb, 0x77, 0x21, 0xf8, 0x5d,
- 0x21, 0x45, 0x58, 0x29, 0xea, 0x58, 0xd1, 0x80, 0x2d, 0x36, 0xee, 0xee,
- 0x74, 0x63, 0x5d, 0x04, 0xfe, 0xd9, 0x01, 0x1f, 0xbf, 0x07, 0xfe, 0xd7,
- 0x67, 0x64, 0xcf, 0x38, 0x0e, 0x62, 0x4f, 0x54, 0x09, 0xfd, 0x0f, 0xbe,
- 0xde, 0xe0, 0x5a, 0x07, 0xe6, 0xc5, 0x9c, 0xb6, 0xbb, 0xc1, 0x9f, 0xe3,
- 0x4c, 0xd8, 0x71, 0x29, 0xd9, 0xbb, 0xb0, 0xaf, 0x45, 0xba, 0x2d, 0xda,
- 0x3b, 0x7d, 0x7a, 0x27, 0xce, 0x33, 0xf8, 0xdd, 0x85, 0xf3, 0x3a, 0x31,
- 0x17, 0x9b, 0xa6, 0x1f, 0xa7, 0x18, 0xb3, 0xdc, 0xf8, 0x29, 0x72, 0x15,
- 0xb4, 0x72, 0x8f, 0x86, 0x8b, 0xb4, 0xa5, 0x53, 0x72, 0xa3, 0xdc, 0x2b,
- 0x57, 0xa2, 0xe4, 0x1f, 0x38, 0x2b, 0x88, 0x87, 0x51, 0x03, 0xf4, 0x93,
- 0x6e, 0xc6, 0xbf, 0xdd, 0xde, 0xb7, 0x71, 0xaf, 0x7b, 0x86, 0x98, 0xa1,
- 0x74, 0x97, 0xe4, 0xf4, 0x9c, 0x28, 0x35, 0xba, 0xd3, 0x5b, 0xef, 0x32,
- 0x0e, 0x9c, 0x51, 0x32, 0xf4, 0x20, 0x62, 0x16, 0xce, 0xba, 0x6c, 0x39,
- 0xce, 0x65, 0xfb, 0xc7, 0xf0, 0x79, 0x25, 0x2d, 0xd6, 0x7a, 0x97, 0xb4,
- 0x43, 0x9e, 0x15, 0xa3, 0x49, 0x86, 0x31, 0x39, 0x51, 0xe1, 0x9e, 0xa2,
- 0x84, 0x2d, 0xc2, 0x10, 0xfe, 0x47, 0x80, 0x0b, 0x49, 0x1b, 0x7c, 0xf1,
- 0xa2, 0x1d, 0x25, 0xbd, 0xbb, 0x5c, 0xf8, 0x6e, 0x9c, 0x41, 0xda, 0xe9,
- 0x7b, 0x8e, 0xf6, 0xbd, 0x6c, 0x48, 0x65, 0xc6, 0xe7, 0xe1, 0x49, 0x23,
- 0x94, 0x77, 0xb6, 0x1b, 0xa1, 0x5f, 0xa6, 0x87, 0x8a, 0xa6, 0xd2, 0xba,
- 0x16, 0xc9, 0x95, 0xef, 0x95, 0x19, 0x1b, 0xe7, 0x59, 0x61, 0xd0, 0xcc,
- 0x38, 0x33, 0x50, 0x0c, 0x29, 0x78, 0x58, 0x0f, 0x65, 0xe5, 0xd3, 0xfa,
- 0x16, 0xce, 0x2b, 0x1a, 0x61, 0x8b, 0x67, 0xfc, 0xb2, 0x27, 0x1f, 0xda,
- 0x9d, 0x2d, 0xd9, 0x72, 0x07, 0xbf, 0x41, 0x47, 0xbb, 0xa6, 0x23, 0x94,
- 0xd6, 0xba, 0x33, 0x54, 0xda, 0x8f, 0xff, 0x04, 0xdd, 0x84, 0x07, 0x7c,
- 0x70, 0xaf, 0x85, 0xbd, 0x11, 0xd0, 0xd8, 0xd9, 0x44, 0x7f, 0x3b, 0xe1,
- 0x21, 0xab, 0x88, 0x77, 0x86, 0xe6, 0xdb, 0x70, 0xf9, 0xf6, 0x65, 0xf5,
- 0x2a, 0x64, 0xf5, 0xbe, 0x33, 0xb4, 0x8f, 0x38, 0x52, 0xc0, 0x01, 0xb9,
- 0x9b, 0x8c, 0x57, 0x8c, 0x51, 0xe6, 0x06, 0x2e, 0xf8, 0x81, 0x0a, 0xa5,
- 0x3b, 0x24, 0x67, 0xea, 0x1c, 0x00, 0xd8, 0x31, 0xd1, 0x31, 0xde, 0x22,
- 0x8f, 0xde, 0xb7, 0x95, 0xd0, 0x76, 0x93, 0xaf, 0x32, 0x0f, 0xfc, 0x31,
- 0x68, 0x5b, 0x4b, 0x28, 0xcd, 0x5a, 0x07, 0x64, 0x2e, 0x91, 0x96, 0xf4,
- 0x1b, 0xb2, 0x5c, 0x56, 0x7b, 0x5a, 0x65, 0x97, 0x4c, 0x42, 0x46, 0xb5,
- 0x31, 0xe4, 0xaf, 0x91, 0x0e, 0x09, 0xdd, 0xcf, 0x3c, 0x10, 0x03, 0xad,
- 0x6b, 0x09, 0x53, 0x6e, 0x39, 0x6a, 0x10, 0xfb, 0x47, 0xa0, 0x87, 0x43,
- 0xd4, 0xa9, 0xf2, 0xe0, 0x08, 0x13, 0xa2, 0xcc, 0x7b, 0x5a, 0x85, 0xb8,
- 0xb9, 0x36, 0x1c, 0x33, 0x85, 0xf3, 0xc8, 0x95, 0x93, 0xdc, 0x4b, 0xfe,
- 0xdc, 0x3d, 0x1f, 0xe6, 0xcf, 0x5f, 0xa7, 0xcc, 0x28, 0x3b, 0xd8, 0x18,
- 0x78, 0xcc, 0xda, 0xbf, 0xe0, 0xc9, 0xe6, 0x4e, 0xb9, 0x62, 0x8a, 0x51,
- 0xb3, 0xef, 0x68, 0x92, 0x1f, 0x79, 0xee, 0xde, 0xc2, 0x33, 0x71, 0x6c,
- 0xcf, 0xf7, 0xe1, 0x2a, 0xcf, 0x74, 0xcf, 0x9e, 0xb1, 0xd6, 0x12, 0x61,
- 0xd9, 0x2c, 0x5f, 0xe8, 0x52, 0x0a, 0x65, 0xda, 0x46, 0xab, 0xe4, 0x51,
- 0x8f, 0xd8, 0xfb, 0x10, 0x54, 0x1e, 0x57, 0x32, 0xfa, 0x20, 0x71, 0xfe,
- 0x23, 0x79, 0x1a, 0x8b, 0x2b, 0x43, 0xf2, 0x3a, 0xf7, 0xfb, 0xfa, 0xe2,
- 0x5c, 0xb3, 0x6d, 0xbf, 0xea, 0xd9, 0xf6, 0xfb, 0xce, 0xe8, 0x3e, 0x5f,
- 0xef, 0x90, 0xd7, 0x87, 0xf6, 0x08, 0xf4, 0xfc, 0x7f, 0xed, 0xa1, 0xad,
- 0x44, 0xb6, 0xec, 0x29, 0x6e, 0xb3, 0x67, 0xb7, 0xc8, 0x2f, 0xd1, 0x87,
- 0xba, 0xbd, 0x98, 0xe1, 0xfb, 0x94, 0x8f, 0x07, 0xba, 0xd1, 0xb6, 0xca,
- 0xb9, 0xed, 0x7c, 0x91, 0x38, 0x88, 0x8b, 0x7b, 0x09, 0xe3, 0xe7, 0x54,
- 0xa8, 0x43, 0xb6, 0xcd, 0xab, 0x18, 0x13, 0x78, 0x57, 0x88, 0x43, 0xcd,
- 0xf9, 0x95, 0x73, 0x26, 0xbe, 0xc7, 0xf1, 0xb4, 0x24, 0x5f, 0xa7, 0x3f,
- 0x71, 0x3f, 0xf3, 0xed, 0x4d, 0x2f, 0x7e, 0x76, 0x4c, 0x85, 0xd3, 0x51,
- 0xc4, 0x4f, 0x99, 0x2c, 0x95, 0x8f, 0xa3, 0x26, 0x92, 0xe2, 0x5d, 0x69,
- 0xda, 0x47, 0xc7, 0x18, 0x62, 0xe4, 0x64, 0xa9, 0xce, 0xba, 0x08, 0x61,
- 0x0c, 0xfb, 0x90, 0xa3, 0x23, 0x6a, 0x2e, 0x52, 0xfc, 0x58, 0x9a, 0x71,
- 0x39, 0x2e, 0xf1, 0xfa, 0x3b, 0xa8, 0x3b, 0x4c, 0xc9, 0x6a, 0x5b, 0xfb,
- 0xb3, 0x5e, 0xd2, 0x5b, 0x42, 0x0d, 0x11, 0x4e, 0x4b, 0x58, 0xa5, 0x5b,
- 0x23, 0xd3, 0xa9, 0x0e, 0xd4, 0x5a, 0x13, 0xbd, 0x6a, 0xf5, 0x60, 0x6f,
- 0x68, 0x75, 0xcf, 0x54, 0x4b, 0xba, 0xd8, 0xab, 0xe6, 0x44, 0x16, 0xcb,
- 0xa2, 0x50, 0xd7, 0xc4, 0x0e, 0x0b, 0xbe, 0x57, 0x3f, 0xfb, 0x59, 0x95,
- 0x0e, 0x41, 0xb7, 0x72, 0x6c, 0x29, 0x15, 0x66, 0x0d, 0x19, 0x9f, 0x94,
- 0x63, 0xa8, 0x1b, 0x9f, 0x91, 0xe9, 0x32, 0xe8, 0xd2, 0x7c, 0xc7, 0xc0,
- 0x6f, 0x1f, 0x70, 0x93, 0xf6, 0x28, 0x62, 0xac, 0x4b, 0x3b, 0x68, 0xce,
- 0xe4, 0x58, 0x27, 0xa5, 0x98, 0x57, 0xde, 0x81, 0xfd, 0xd0, 0x5f, 0xfe,
- 0x59, 0x96, 0xad, 0x1d, 0x92, 0x77, 0xe3, 0x03, 0xed, 0x15, 0x6b, 0x37,
- 0xbd, 0xb5, 0x6b, 0x58, 0xa3, 0xfd, 0xee, 0x6c, 0xd2, 0xe1, 0x97, 0x75,
- 0xad, 0x73, 0xd9, 0xe6, 0x3b, 0x61, 0xff, 0x76, 0xd4, 0x85, 0x7d, 0x7d,
- 0x74, 0xd9, 0xfa, 0xdc, 0x2e, 0x69, 0x37, 0xa9, 0x37, 0x9c, 0x13, 0x65,
- 0x8c, 0xc5, 0xfa, 0x15, 0x0f, 0xd7, 0x5b, 0xc0, 0xd5, 0x41, 0xba, 0x31,
- 0xc2, 0x58, 0x07, 0x7d, 0xa8, 0x79, 0xf2, 0x1b, 0xb1, 0x86, 0xb0, 0xdf,
- 0xf1, 0x70, 0x7d, 0xab, 0x09, 0x17, 0xd7, 0xf8, 0xe4, 0x99, 0x38, 0xbb,
- 0x9d, 0xbc, 0x91, 0x1f, 0xea, 0x80, 0xfa, 0x48, 0x1a, 0x93, 0x88, 0xed,
- 0x93, 0x0d, 0x5d, 0xdb, 0x19, 0xb9, 0x0a, 0x6a, 0xae, 0xc6, 0x8b, 0xa0,
- 0x11, 0xb5, 0x58, 0x63, 0xd0, 0xab, 0xb7, 0x69, 0x47, 0x6b, 0xda, 0x1e,
- 0x19, 0x77, 0x4a, 0xda, 0xae, 0x2e, 0xb9, 0x76, 0x65, 0x51, 0x37, 0x97,
- 0x64, 0x6f, 0xbd, 0xba, 0xcb, 0xfd, 0xbf, 0xdb, 0xa6, 0x84, 0xb4, 0x3e,
- 0x99, 0xdf, 0x68, 0x63, 0x77, 0x22, 0xae, 0x3b, 0xef, 0x32, 0xcf, 0x4c,
- 0x32, 0x07, 0x4d, 0x32, 0x77, 0x18, 0x5e, 0x3c, 0x8c, 0x37, 0xe1, 0x88,
- 0x03, 0xc7, 0x8a, 0x67, 0xbf, 0x73, 0x1e, 0x2e, 0xbf, 0xfe, 0xf4, 0x63,
- 0xea, 0x9f, 0xdf, 0xb5, 0x79, 0x5d, 0x99, 0xee, 0x77, 0xab, 0x8e, 0xc7,
- 0xb0, 0x75, 0xd0, 0x1f, 0x9f, 0x52, 0xb0, 0xaf, 0x5c, 0xdd, 0xd5, 0x07,
- 0x7c, 0x1f, 0xb6, 0xc7, 0x57, 0x5f, 0xb7, 0x6e, 0xfd, 0xed, 0xca, 0x80,
- 0x3a, 0xcd, 0x90, 0xef, 0x4c, 0x98, 0xb4, 0x34, 0x26, 0xb0, 0x5f, 0x8e,
- 0x30, 0x37, 0xe6, 0xc1, 0xc7, 0x61, 0x73, 0xd8, 0x9c, 0x26, 0xee, 0xa8,
- 0x00, 0x27, 0x6a, 0xc9, 0x74, 0x9b, 0xa7, 0xe7, 0x6f, 0xf3, 0x7c, 0xe0,
- 0xde, 0xc9, 0x6f, 0x3c, 0xbf, 0xed, 0xd1, 0x73, 0xa3, 0xcb, 0xa5, 0xc7,
- 0x5f, 0x1f, 0x34, 0x37, 0x7f, 0xaf, 0xf4, 0x7a, 0xf2, 0xc4, 0xfb, 0x33,
- 0x1e, 0x5d, 0xd4, 0x4d, 0x33, 0x4d, 0xd4, 0xcb, 0xbb, 0xc0, 0xa3, 0x6b,
- 0x8d, 0xa2, 0x4a, 0xa3, 0x76, 0x49, 0x31, 0x67, 0x25, 0xc6, 0x32, 0x62,
- 0x41, 0x27, 0x09, 0x7b, 0x0a, 0xbb, 0x6e, 0x96, 0xa9, 0xe7, 0x5b, 0x88,
- 0xd5, 0xd4, 0xfb, 0x7b, 0x32, 0x53, 0xee, 0xb7, 0x5b, 0x0d, 0xfa, 0x6b,
- 0x22, 0xb9, 0x22, 0xc3, 0xf6, 0x8a, 0xae, 0xa1, 0x12, 0xf1, 0x13, 0x42,
- 0xd9, 0xde, 0x92, 0x01, 0x5d, 0xdb, 0xbc, 0x27, 0x16, 0xe4, 0x32, 0x59,
- 0x81, 0x8f, 0xed, 0xfb, 0x57, 0x47, 0xd7, 0xa4, 0x08, 0x6f, 0xd7, 0xb7,
- 0xc1, 0xf5, 0xba, 0xc6, 0x43, 0x7c, 0xcd, 0xb8, 0x0c, 0x69, 0xdb, 0xe7,
- 0xe3, 0xb3, 0x64, 0xb6, 0xe1, 0xe3, 0x0c, 0x23, 0x2e, 0x23, 0x06, 0xec,
- 0xfb, 0xbc, 0x67, 0x2f, 0x7c, 0xff, 0xbe, 0xc3, 0x5a, 0x48, 0xa5, 0xbf,
- 0xea, 0xcd, 0x7d, 0x8f, 0x32, 0xc0, 0xb7, 0x2f, 0xf7, 0x17, 0xbd, 0x78,
- 0x53, 0x34, 0x32, 0x0d, 0xca, 0x80, 0xb6, 0x02, 0xfd, 0x6b, 0xfb, 0x84,
- 0xcf, 0x54, 0x3e, 0x89, 0x98, 0xd5, 0xed, 0xd6, 0x0f, 0xe8, 0xaf, 0x32,
- 0x0d, 0xce, 0xad, 0xb5, 0x65, 0xed, 0x16, 0xcf, 0x97, 0x0e, 0x62, 0x6e,
- 0x12, 0x7f, 0x94, 0x1d, 0x61, 0x0e, 0xe1, 0x3d, 0xe3, 0xc1, 0xc9, 0x58,
- 0x16, 0xb9, 0x2b, 0x73, 0x68, 0x1c, 0xdf, 0x86, 0xd7, 0x67, 0x69, 0xb9,
- 0x57, 0x51, 0xab, 0x40, 0x9e, 0x03, 0xe0, 0x27, 0x2e, 0xe3, 0x0d, 0xe8,
- 0x7c, 0x23, 0x9e, 0x6d, 0xc0, 0x14, 0x6f, 0xc3, 0xb8, 0xb1, 0x6f, 0xbc,
- 0xf1, 0xa6, 0xc3, 0x78, 0xf0, 0x57, 0xda, 0x5f, 0xe2, 0xa0, 0xdd, 0xef,
- 0xd5, 0x32, 0xc6, 0x63, 0x95, 0x09, 0xe3, 0xf1, 0x0a, 0xf7, 0xa8, 0xaf,
- 0xf5, 0x88, 0x15, 0xcf, 0x2a, 0xd4, 0xa9, 0xfb, 0xba, 0x70, 0xe6, 0x09,
- 0xd8, 0x46, 0xd1, 0x98, 0x1c, 0xda, 0x25, 0xf9, 0x64, 0x0f, 0x68, 0x7e,
- 0x08, 0xcf, 0x56, 0xcc, 0xff, 0x3c, 0xe6, 0x61, 0x47, 0x49, 0xfa, 0xc7,
- 0x0e, 0xdd, 0x5b, 0x4e, 0x99, 0xa4, 0x71, 0xc0, 0xb3, 0xad, 0x37, 0x4d,
- 0xd7, 0x96, 0x9e, 0xc6, 0xf7, 0x4e, 0xcc, 0x7f, 0x01, 0x4f, 0xe4, 0xb2,
- 0x7d, 0xfe, 0x3c, 0x7d, 0x70, 0x0c, 0xf3, 0x0f, 0x00, 0xc7, 0x1f, 0xe0,
- 0xfd, 0x5e, 0xbc, 0xff, 0xde, 0x96, 0xbd, 0xbf, 0xcb, 0xb3, 0x31, 0x9f,
- 0xdd, 0x32, 0xef, 0xc7, 0x6f, 0x9e, 0x27, 0xd2, 0xbd, 0x0a, 0xc6, 0x57,
- 0x23, 0xb2, 0x7b, 0xa5, 0x5d, 0x54, 0xcd, 0x8d, 0xe1, 0xaa, 0x66, 0x4a,
- 0xcf, 0x0a, 0xe3, 0xf7, 0x0f, 0xb0, 0xc7, 0x12, 0xb5, 0x0a, 0xa5, 0x51,
- 0xb7, 0xda, 0x47, 0x9f, 0x39, 0xba, 0x77, 0x81, 0xcf, 0xe2, 0xd1, 0xd1,
- 0x3a, 0x61, 0xf8, 0x7e, 0xec, 0xe8, 0xde, 0xfa, 0x3f, 0x00, 0x16, 0x72,
- 0xa9, 0xf8, 0xf8, 0x09, 0x7f, 0x7e, 0xcb, 0x99, 0x5a, 0xb6, 0x38, 0x93,
- 0x7e, 0xff, 0xcc, 0xd1, 0x6c, 0x95, 0x75, 0x42, 0x22, 0x26, 0xba, 0x16,
- 0x2f, 0x1e, 0x2d, 0x20, 0x3f, 0x86, 0x34, 0x2d, 0xfe, 0x3a, 0xd7, 0xa8,
- 0x87, 0xed, 0x68, 0x23, 0x5d, 0xcd, 0x78, 0x98, 0x67, 0x88, 0xe7, 0x18,
- 0xf0, 0x24, 0x81, 0x87, 0xf9, 0xc6, 0xa5, 0x37, 0xbe, 0xb0, 0x1d, 0x6d,
- 0xc4, 0xc5, 0xb3, 0x7c, 0x7c, 0x3d, 0xa2, 0x56, 0x7e, 0x48, 0x7a, 0x4d,
- 0xd6, 0xb6, 0x6e, 0xac, 0x69, 0x91, 0xfc, 0x69, 0xe6, 0xec, 0x7d, 0xde,
- 0x37, 0xca, 0x18, 0xf4, 0xdc, 0x71, 0xc5, 0x79, 0x3e, 0xb1, 0x96, 0x62,
- 0xb9, 0x82, 0xef, 0x45, 0x1f, 0x56, 0x79, 0xb0, 0x9d, 0x4d, 0x7c, 0xb7,
- 0x78, 0xb2, 0xe6, 0x99, 0x7e, 0xef, 0xd9, 0x4c, 0x0b, 0x40, 0xa1, 0x87,
- 0xee, 0x0d, 0x3d, 0xf8, 0x7c, 0x62, 0x61, 0x95, 0xb4, 0x25, 0xc1, 0xab,
- 0x4f, 0xdb, 0x47, 0xd5, 0x1f, 0xf7, 0x26, 0xf1, 0xe7, 0x9f, 0xe7, 0xcb,
- 0x80, 0x74, 0xf1, 0x09, 0x5b, 0xfe, 0x50, 0xef, 0x9c, 0x84, 0xdf, 0xf1,
- 0x1e, 0xc4, 0x71, 0x96, 0x6d, 0xca, 0xbe, 0x0d, 0x7a, 0x27, 0x2f, 0x06,
- 0x7a, 0x09, 0xc5, 0x9a, 0x2e, 0xce, 0x9e, 0xf5, 0x49, 0xb9, 0x0a, 0x5c,
- 0x19, 0xf4, 0x95, 0x6e, 0x6f, 0x34, 0x85, 0xf8, 0xb8, 0x06, 0xfb, 0xbc,
- 0x6c, 0xf1, 0x3e, 0x26, 0xcc, 0x7c, 0x27, 0xa5, 0xfa, 0xbf, 0x00, 0x86,
- 0xf5, 0xd5, 0xed, 0xbb, 0x96, 0x05, 0xc0, 0x2c, 0x62, 0xed, 0x84, 0x1b,
- 0x97, 0x19, 0xdb, 0x1d, 0x85, 0xda, 0xa3, 0x60, 0xfd, 0xb7, 0xc3, 0x3a,
- 0xeb, 0x36, 0xec, 0x76, 0x77, 0x21, 0xc8, 0x39, 0xf3, 0x89, 0xd9, 0x05,
- 0xc4, 0xf0, 0xaa, 0xa5, 0x76, 0x2b, 0x6d, 0x91, 0x89, 0x2a, 0x62, 0x12,
- 0xba, 0xde, 0x44, 0x7c, 0x41, 0xfe, 0x53, 0xeb, 0xa1, 0xc5, 0x1a, 0x36,
- 0x7b, 0xd4, 0xe7, 0x68, 0x57, 0x9a, 0xf2, 0xd0, 0x29, 0xe4, 0xe5, 0x91,
- 0xc7, 0x90, 0x73, 0x20, 0xaf, 0x53, 0x45, 0x74, 0xf2, 0xb4, 0x91, 0x37,
- 0x7e, 0xab, 0x60, 0xb9, 0x7d, 0x80, 0xce, 0x67, 0xe2, 0xf2, 0x18, 0x3a,
- 0xd5, 0xa1, 0xe3, 0x4c, 0x5e, 0xc7, 0x9b, 0x7e, 0x73, 0x52, 0xb5, 0xa3,
- 0xc6, 0x40, 0x01, 0x8a, 0x0a, 0xc7, 0x1c, 0x14, 0xd9, 0x3b, 0x87, 0xb8,
- 0x82, 0x38, 0xbc, 0x77, 0x15, 0xd1, 0xed, 0x14, 0xe1, 0x95, 0x84, 0x4f,
- 0x85, 0xa4, 0xe5, 0x14, 0xef, 0x43, 0x64, 0x0f, 0xfa, 0x31, 0xe2, 0xdc,
- 0x1b, 0xc6, 0x73, 0x1c, 0x7f, 0xfb, 0x51, 0x5b, 0x99, 0xa8, 0x91, 0xb7,
- 0x81, 0x07, 0x2c, 0xf7, 0x6c, 0x07, 0x6f, 0x76, 0x4b, 0x7b, 0x04, 0x7b,
- 0x08, 0x1f, 0x06, 0x1d, 0x7b, 0x40, 0x8f, 0x7b, 0x3e, 0x71, 0x84, 0x4f,
- 0x89, 0xf4, 0xcf, 0x49, 0x8f, 0xd2, 0x7b, 0xc2, 0x52, 0x48, 0x71, 0xad,
- 0x03, 0xf0, 0xdc, 0x87, 0x35, 0xbd, 0xcf, 0xbd, 0x57, 0xca, 0xdf, 0xa6,
- 0x1b, 0x73, 0x06, 0xde, 0x51, 0x4f, 0xa5, 0x4c, 0xe9, 0xaf, 0xb9, 0xb0,
- 0x7b, 0x57, 0xbf, 0xd4, 0xcd, 0xbb, 0x29, 0x65, 0xb9, 0xb4, 0x29, 0xd4,
- 0xc4, 0x79, 0x48, 0x35, 0x3c, 0xc8, 0xfb, 0x19, 0xc2, 0xb0, 0xaf, 0x35,
- 0x35, 0x8c, 0x39, 0x48, 0xf9, 0xb9, 0x73, 0x4a, 0xfd, 0x6f, 0xf7, 0x2e,
- 0xcd, 0x35, 0x85, 0xf6, 0x15, 0xec, 0xff, 0x43, 0xed, 0x2b, 0xa2, 0xe2,
- 0x9e, 0xaf, 0xe0, 0x7b, 0x91, 0xdf, 0x7e, 0x2e, 0xfe, 0xed, 0xbb, 0xdc,
- 0x78, 0xef, 0xc8, 0xb4, 0xcd, 0x3b, 0x0c, 0x47, 0x2e, 0xdb, 0x45, 0xe3,
- 0x91, 0x4d, 0x75, 0x66, 0x52, 0xe7, 0xe7, 0x02, 0x64, 0xbf, 0x5e, 0xd7,
- 0x3d, 0x9b, 0x5c, 0xa9, 0x47, 0xe4, 0xea, 0x52, 0xbb, 0xac, 0x2f, 0xb8,
- 0x36, 0xbf, 0xbe, 0x40, 0x3b, 0x37, 0xe5, 0xed, 0x25, 0x0b, 0x6b, 0x49,
- 0xfc, 0xf5, 0xc8, 0xf5, 0xa5, 0xcd, 0x75, 0xe7, 0x85, 0xc6, 0xc3, 0xa0,
- 0xa5, 0x47, 0x42, 0x96, 0xa3, 0xfb, 0xaf, 0x1c, 0x72, 0x5f, 0x51, 0xc6,
- 0x25, 0x5f, 0xe9, 0x47, 0x0f, 0x88, 0xe4, 0x1c, 0x66, 0x0e, 0x82, 0xfe,
- 0x2b, 0x9f, 0x40, 0x6d, 0x92, 0x80, 0xf3, 0xf4, 0xeb, 0x7b, 0xc5, 0x4f,
- 0x85, 0x7b, 0xa4, 0xd5, 0xfa, 0xa3, 0x6e, 0x37, 0x57, 0x99, 0x6e, 0x9f,
- 0x6a, 0xf9, 0xf9, 0xfa, 0x75, 0xe0, 0x1e, 0x81, 0x9d, 0xd2, 0x36, 0x6d,
- 0xd8, 0xac, 0x29, 0xcb, 0x43, 0x89, 0x6a, 0x51, 0x18, 0x1f, 0x52, 0x38,
- 0xd3, 0xc0, 0xbe, 0x24, 0xe4, 0xb1, 0x43, 0xd7, 0x42, 0x19, 0x05, 0xdd,
- 0xce, 0xcd, 0x48, 0xbe, 0xf1, 0x9b, 0x98, 0xcf, 0xc8, 0x54, 0x63, 0x0c,
- 0x67, 0x9d, 0xa4, 0xdd, 0xf6, 0x48, 0x3b, 0xcf, 0x49, 0x81, 0xc6, 0x87,
- 0xa4, 0x70, 0x7a, 0x46, 0x0e, 0x57, 0x48, 0x27, 0xef, 0x19, 0x13, 0xc9,
- 0x9c, 0x0c, 0xc7, 0x97, 0x50, 0x3b, 0xb9, 0xfe, 0x98, 0x96, 0xc2, 0x19,
- 0xe0, 0xa8, 0xf0, 0x1e, 0xa0, 0x1f, 0x76, 0x33, 0xac, 0xfb, 0x9a, 0x29,
- 0x1d, 0x77, 0x38, 0xff, 0x43, 0xe8, 0xa9, 0xbf, 0xb8, 0x1f, 0x70, 0x79,
- 0xf4, 0x40, 0x93, 0xa8, 0x97, 0x17, 0x2b, 0xe8, 0xf7, 0xec, 0x10, 0x6b,
- 0x2f, 0xa5, 0xee, 0xef, 0x93, 0x5a, 0x65, 0xd8, 0x54, 0x8a, 0x35, 0x15,
- 0x75, 0xc1, 0x35, 0xfa, 0x77, 0x4c, 0x85, 0xad, 0x3e, 0x59, 0xaa, 0x14,
- 0xd1, 0x37, 0x2b, 0xef, 0x5e, 0x03, 0x16, 0x60, 0xb9, 0x71, 0x2f, 0xa3,
- 0xc8, 0x37, 0xea, 0xcf, 0xc6, 0x27, 0x41, 0x63, 0x26, 0x6e, 0xca, 0x71,
- 0xd0, 0x87, 0xf7, 0x45, 0xd8, 0xf8, 0x1c, 0x6b, 0xb8, 0x0c, 0xd6, 0xd2,
- 0x72, 0xe4, 0xec, 0x24, 0x68, 0xe8, 0x92, 0xfe, 0x3f, 0xa1, 0x8f, 0x3d,
- 0x81, 0x39, 0x7e, 0x27, 0x60, 0xaf, 0x5f, 0xc4, 0x3b, 0x61, 0x63, 0x78,
- 0x52, 0x0e, 0x7d, 0x78, 0x9a, 0xa0, 0x25, 0xe2, 0xf6, 0x26, 0x87, 0xe2,
- 0x52, 0x3b, 0xfd, 0xa0, 0x4c, 0x2d, 0x3e, 0x08, 0xfc, 0x3f, 0x42, 0x5f,
- 0x80, 0xfc, 0xb6, 0xc8, 0xb3, 0x58, 0xff, 0xf1, 0x9c, 0x9d, 0x3d, 0xda,
- 0x37, 0xe6, 0x38, 0xcf, 0xe7, 0x41, 0xec, 0x47, 0x8f, 0x51, 0xc9, 0x48,
- 0xa1, 0xc2, 0xb3, 0xa0, 0x3b, 0xd4, 0x53, 0xf9, 0xd3, 0x93, 0x9e, 0x8e,
- 0x7b, 0x24, 0x17, 0x2d, 0xb2, 0xbf, 0x40, 0x9e, 0x58, 0x18, 0xcd, 0x96,
- 0x13, 0x66, 0x56, 0x11, 0x57, 0x52, 0x98, 0x1b, 0xdc, 0xb9, 0x88, 0x58,
- 0x73, 0xe8, 0x6d, 0xd3, 0x5c, 0x3b, 0xee, 0xdd, 0x1d, 0x10, 0xd7, 0x9b,
- 0x32, 0x0e, 0x1b, 0xeb, 0x9f, 0x1b, 0x41, 0x2d, 0xfc, 0x16, 0x6a, 0xc9,
- 0x84, 0x27, 0x83, 0x31, 0xcf, 0x36, 0xda, 0x9b, 0x6c, 0x02, 0x7a, 0xae,
- 0x40, 0xf7, 0x15, 0xd8, 0x01, 0x62, 0xf5, 0x2b, 0x1b, 0xf6, 0x31, 0xd6,
- 0x54, 0x63, 0x76, 0xca, 0xdf, 0x54, 0x13, 0xc9, 0x35, 0xd8, 0xcf, 0x75,
- 0xf4, 0x02, 0x6b, 0xe8, 0x55, 0xd7, 0xd1, 0xd7, 0x2d, 0x96, 0x0f, 0x81,
- 0x7e, 0xd6, 0x94, 0xfc, 0x8e, 0xe9, 0x5a, 0xa7, 0xcd, 0x7a, 0xe1, 0x2e,
- 0x7d, 0xb7, 0x2b, 0x4f, 0xf4, 0xb0, 0xd7, 0x64, 0x5f, 0xce, 0x7b, 0xe9,
- 0xab, 0xd0, 0xe3, 0x9a, 0xc9, 0x75, 0x7f, 0x1f, 0x7b, 0x01, 0xdf, 0x7e,
- 0x48, 0x0b, 0xed, 0x87, 0x7b, 0x08, 0xd3, 0xa3, 0xfd, 0x24, 0xaf, 0xf1,
- 0xd1, 0x66, 0xeb, 0xdd, 0xae, 0x9f, 0xe9, 0x3a, 0xcb, 0xbc, 0x22, 0xbe,
- 0xfd, 0xbe, 0xe7, 0xb0, 0xaf, 0xcb, 0x0e, 0x21, 0x76, 0x37, 0x1c, 0x79,
- 0xc1, 0xde, 0xec, 0x77, 0x07, 0x2a, 0xbe, 0x9c, 0x28, 0xc7, 0x43, 0x72,
- 0xa2, 0x91, 0x80, 0x4f, 0x50, 0x86, 0x56, 0x93, 0x0c, 0x45, 0xbe, 0x5e,
- 0x11, 0x79, 0xb9, 0xc2, 0x35, 0x2d, 0xc3, 0x58, 0x36, 0xd4, 0xce, 0xbb,
- 0x75, 0xd8, 0xe5, 0xdf, 0xcb, 0xe1, 0x79, 0x91, 0xb3, 0x58, 0x5f, 0xae,
- 0xd0, 0x57, 0x47, 0x50, 0xbf, 0xee, 0x94, 0xda, 0x02, 0x7a, 0xb2, 0x8a,
- 0x4c, 0x65, 0x1f, 0x60, 0xbe, 0x89, 0xc8, 0xba, 0xbe, 0x93, 0x15, 0x19,
- 0x3c, 0x17, 0x96, 0xf0, 0x39, 0x34, 0x7f, 0x90, 0xfd, 0xf9, 0x21, 0xff,
- 0x8e, 0xd6, 0xf5, 0xf9, 0x52, 0x19, 0x7b, 0x2b, 0xfd, 0x3a, 0x4e, 0x96,
- 0xea, 0x05, 0xc9, 0x57, 0x79, 0x16, 0x9e, 0x0b, 0x71, 0xac, 0xa5, 0x64,
- 0xfa, 0xf4, 0x88, 0x3c, 0x8b, 0x33, 0xd0, 0xff, 0xe1, 0x8c, 0x71, 0x29,
- 0x9e, 0xc5, 0x7c, 0xfd, 0x9a, 0x2c, 0x2c, 0x15, 0xa4, 0x56, 0xbd, 0xd0,
- 0x74, 0xf7, 0x8e, 0xef, 0x85, 0xe6, 0x5e, 0xf6, 0x10, 0xfb, 0x19, 0xf4,
- 0xaa, 0x16, 0xbe, 0x21, 0xb3, 0xfa, 0xf4, 0xd4, 0xe6, 0x3b, 0xe3, 0xe6,
- 0x1e, 0x76, 0x42, 0x66, 0x2b, 0x29, 0x29, 0x9d, 0x1e, 0xd1, 0x77, 0x0d,
- 0x6d, 0xe9, 0xea, 0xd3, 0x37, 0x90, 0x2b, 0x26, 0xf4, 0x9d, 0xf1, 0x2d,
- 0x79, 0xd4, 0x9e, 0x95, 0x27, 0xad, 0x83, 0x72, 0x02, 0xf5, 0xf5, 0xa7,
- 0xd1, 0xeb, 0xc7, 0xbb, 0xa9, 0x47, 0xd0, 0x6b, 0xb1, 0x07, 0x75, 0x64,
- 0xdc, 0xfe, 0xb8, 0xf9, 0x3c, 0x24, 0x7b, 0xb5, 0xce, 0x3c, 0xf9, 0x5f,
- 0x4e, 0x06, 0x79, 0xef, 0x06, 0x7a, 0xc7, 0x8c, 0x86, 0x33, 0x5c, 0xb8,
- 0x2a, 0xe1, 0x86, 0xcd, 0x17, 0x08, 0xb7, 0x60, 0x78, 0x70, 0x06, 0xe0,
- 0x42, 0x72, 0xd1, 0x0e, 0xc3, 0x46, 0x26, 0xc0, 0x27, 0x62, 0xfc, 0x68,
- 0xa7, 0x57, 0x07, 0xef, 0x40, 0x6e, 0xbd, 0xbd, 0xff, 0x35, 0x6f, 0xff,
- 0xb3, 0xde, 0xfe, 0xcb, 0x1b, 0xfb, 0xfd, 0xfc, 0xfa, 0x13, 0x47, 0x9a,
- 0xe8, 0x7a, 0xad, 0xec, 0xc2, 0xcf, 0x7a, 0x74, 0x5d, 0xde, 0xa0, 0xcb,
- 0x87, 0x87, 0x3c, 0x35, 0xcf, 0x8c, 0xcd, 0x8c, 0xd1, 0xfd, 0x90, 0xa3,
- 0x23, 0x39, 0x1b, 0xbe, 0x51, 0x49, 0x8c, 0x15, 0xf5, 0x9d, 0x9a, 0x92,
- 0xb5, 0xe8, 0xac, 0x4c, 0x58, 0x89, 0xb1, 0x69, 0x09, 0xc1, 0x96, 0x19,
- 0x5b, 0x42, 0x52, 0x63, 0xcc, 0xc1, 0x33, 0x6f, 0x6f, 0x4f, 0xeb, 0xd5,
- 0x26, 0x5a, 0x43, 0x2f, 0x91, 0x46, 0x97, 0xd6, 0xc8, 0xc0, 0x6d, 0x5a,
- 0x5d, 0x78, 0x97, 0xd6, 0xab, 0xe5, 0x26, 0xf8, 0x73, 0x61, 0x0f, 0x3e,
- 0xdc, 0x04, 0x4f, 0x7b, 0x66, 0x5d, 0x41, 0x7b, 0x26, 0x6d, 0x3f, 0x0b,
- 0xdf, 0x90, 0xc8, 0x8e, 0x74, 0xf5, 0xe8, 0x7d, 0x03, 0x8e, 0x44, 0x50,
- 0x6f, 0xb4, 0x62, 0x6d, 0xbd, 0xca, 0x5a, 0x44, 0xed, 0x6d, 0x95, 0x41,
- 0xd8, 0x2c, 0x75, 0xe7, 0xde, 0x0d, 0x3e, 0xaa, 0x6b, 0x02, 0x47, 0x9e,
- 0xb4, 0x49, 0xcb, 0x8f, 0x9d, 0x97, 0xa3, 0x83, 0x76, 0x49, 0x86, 0xcc,
- 0x56, 0x9c, 0x5f, 0x6b, 0x68, 0x9c, 0x49, 0xd2, 0xb2, 0x32, 0xd4, 0x6f,
- 0x7e, 0x0f, 0x7c, 0x8e, 0x57, 0x0d, 0xa9, 0x59, 0x89, 0xd8, 0x79, 0xe0,
- 0xd8, 0x0f, 0xdd, 0xd4, 0x46, 0x48, 0x8f, 0xc8, 0x61, 0xd8, 0x77, 0x4d,
- 0xe7, 0x45, 0xda, 0x71, 0x62, 0xa2, 0x88, 0x5a, 0xe7, 0x2f, 0x75, 0x6e,
- 0x73, 0x9c, 0x1b, 0xc8, 0x6f, 0x13, 0x5b, 0x6c, 0x4f, 0x9d, 0x73, 0x6d,
- 0x4f, 0x9d, 0x43, 0x0f, 0x7c, 0x32, 0x22, 0x6d, 0xcb, 0xf0, 0x9f, 0x97,
- 0xf6, 0xb8, 0xf5, 0xdc, 0x4b, 0xfc, 0xdd, 0x09, 0xf1, 0xee, 0x64, 0x58,
- 0xac, 0x93, 0x3a, 0x1f, 0x40, 0xde, 0xe3, 0x32, 0x7d, 0x86, 0x31, 0xd5,
- 0x92, 0x81, 0x93, 0xd4, 0x07, 0xeb, 0x9a, 0x85, 0xd1, 0x02, 0x7c, 0x64,
- 0x06, 0x71, 0x41, 0x2d, 0xdf, 0x94, 0x82, 0x45, 0x39, 0x74, 0x49, 0xfb,
- 0x32, 0xfa, 0xf1, 0x65, 0xc4, 0x86, 0xe5, 0x98, 0xb4, 0xc0, 0xb7, 0xd4,
- 0xb9, 0xa8, 0x51, 0x9a, 0x7f, 0x17, 0xfe, 0xc0, 0xdf, 0x70, 0x50, 0x5b,
- 0x9e, 0x8b, 0x19, 0xf4, 0x2d, 0x75, 0x8e, 0x76, 0x8e, 0x72, 0xea, 0x1c,
- 0xed, 0x9c, 0x74, 0xf8, 0xfe, 0x82, 0xf7, 0x73, 0x23, 0xfa, 0x9e, 0xfa,
- 0x86, 0x4d, 0x5e, 0x7e, 0x20, 0xd9, 0x2a, 0x6b, 0x44, 0xf2, 0x23, 0xdd,
- 0xa8, 0x65, 0x76, 0x65, 0xed, 0x81, 0xb1, 0x75, 0xf9, 0xa8, 0x7c, 0xdd,
- 0xf9, 0x11, 0xf8, 0x22, 0x1f, 0xcd, 0x7c, 0x91, 0xa7, 0x2e, 0x69, 0xd1,
- 0x7c, 0xf9, 0xfc, 0x40, 0xd0, 0xe0, 0x67, 0xef, 0xc9, 0x18, 0xf0, 0x7f,
- 0x11, 0x31, 0xa0, 0x0f, 0xcf, 0x27, 0xf0, 0x44, 0x4a, 0x3b, 0x47, 0xde,
- 0xc9, 0xeb, 0x75, 0xd4, 0x8d, 0x3e, 0x9f, 0x53, 0x78, 0x7f, 0x55, 0xa6,
- 0xe7, 0x9d, 0xe3, 0xc8, 0xab, 0xbc, 0x43, 0xef, 0x71, 0xef, 0x83, 0xb7,
- 0xf2, 0xfe, 0xaa, 0xb8, 0xf2, 0x49, 0x98, 0x35, 0xc1, 0xfb, 0xd2, 0x56,
- 0x59, 0x34, 0xc7, 0x8e, 0x98, 0xae, 0xc3, 0x0f, 0xd7, 0x19, 0x27, 0x28,
- 0xa3, 0xeb, 0x92, 0x9d, 0xe7, 0xfd, 0x97, 0x8b, 0x6f, 0xaa, 0xee, 0xc7,
- 0x8d, 0xe6, 0x3d, 0x36, 0xe0, 0xfa, 0x00, 0x47, 0xba, 0xd6, 0x28, 0x3f,
- 0xc4, 0x9c, 0xde, 0xa6, 0x58, 0xd3, 0xbc, 0x6f, 0x4c, 0x9e, 0x43, 0x1d,
- 0xf0, 0x9a, 0xbd, 0x49, 0xae, 0x53, 0xac, 0x85, 0x6a, 0xf5, 0x49, 0xf8,
- 0x64, 0x0b, 0x62, 0x99, 0x29, 0xeb, 0xe5, 0x56, 0xa9, 0xa1, 0xde, 0x59,
- 0x5c, 0x62, 0x2c, 0x24, 0xed, 0xed, 0x98, 0x77, 0xe3, 0x17, 0x63, 0xed,
- 0x7a, 0x19, 0x79, 0x16, 0xbe, 0xbd, 0x5e, 0x8e, 0xe2, 0xd9, 0x87, 0xa7,
- 0x85, 0x67, 0x1c, 0xcf, 0x24, 0x9e, 0x23, 0x78, 0x8e, 0xe0, 0x69, 0x61,
- 0x6f, 0x0c, 0x4f, 0xbf, 0x67, 0x20, 0xae, 0xdb, 0x7c, 0x97, 0xf4, 0x79,
- 0xa8, 0x15, 0x2d, 0xe6, 0xb4, 0xb0, 0x9d, 0x43, 0x1f, 0x91, 0x1d, 0x61,
- 0xad, 0xc7, 0x9a, 0xef, 0x03, 0xc7, 0xb4, 0xd8, 0x97, 0x17, 0x8d, 0xfd,
- 0x43, 0xcc, 0x0b, 0x55, 0xe4, 0x85, 0xf7, 0x76, 0xa3, 0x7f, 0x34, 0x0f,
- 0xe8, 0xbb, 0xa3, 0x79, 0x7c, 0xf3, 0x1d, 0x3d, 0x6f, 0x74, 0x06, 0x79,
- 0x8a, 0xf1, 0xd3, 0xc1, 0x9e, 0x3c, 0xe2, 0xf8, 0x2e, 0xf8, 0x5f, 0x06,
- 0x71, 0x1b, 0xef, 0x0b, 0x97, 0x76, 0xbb, 0x39, 0x15, 0xf9, 0x56, 0x6d,
- 0xbd, 0xaf, 0xb1, 0xb1, 0x67, 0xbb, 0xde, 0xa0, 0x13, 0x38, 0x12, 0xd5,
- 0x05, 0xf8, 0xe0, 0xf7, 0xed, 0xe3, 0xba, 0xb6, 0xa3, 0x2e, 0x9e, 0x45,
- 0x8d, 0x9a, 0x9b, 0x63, 0x0d, 0x73, 0x0c, 0x7d, 0x09, 0xfa, 0xb3, 0x28,
- 0x7b, 0x72, 0xe6, 0x02, 0x5d, 0x8b, 0x46, 0xa5, 0x9d, 0x79, 0xe0, 0x06,
- 0xce, 0x03, 0x5f, 0x8b, 0x0e, 0x64, 0xf6, 0x08, 0x6a, 0x42, 0xc7, 0x09,
- 0x5b, 0xfb, 0x25, 0xfe, 0x38, 0x63, 0x8e, 0x60, 0xbf, 0x29, 0xee, 0xbd,
- 0x3a, 0xe2, 0xee, 0xa4, 0xfe, 0xbd, 0x18, 0xc6, 0x65, 0x63, 0xef, 0x1d,
- 0xc0, 0xc5, 0x79, 0xde, 0x69, 0x8b, 0xec, 0x9f, 0x73, 0x6b, 0x5a, 0x65,
- 0x35, 0xe3, 0xfb, 0x39, 0x0f, 0x1f, 0xd7, 0x95, 0xf7, 0xdb, 0xc6, 0x1e,
- 0xc8, 0x08, 0xfe, 0x00, 0x1d, 0x9f, 0x40, 0xfd, 0x7c, 0x11, 0x7a, 0x79,
- 0x0d, 0x3a, 0xb9, 0x54, 0xa6, 0xad, 0x0f, 0xc3, 0xee, 0x21, 0xc3, 0x49,
- 0xe2, 0x1a, 0xd1, 0x67, 0x5f, 0x2c, 0x23, 0x76, 0x32, 0xfe, 0xa9, 0x5f,
- 0x8d, 0xb2, 0x3e, 0x64, 0x1e, 0x74, 0xf1, 0xf4, 0xb9, 0x70, 0xe2, 0xaf,
- 0xed, 0xd6, 0xf4, 0xd4, 0xf4, 0x3d, 0x18, 0xe5, 0x04, 0x1b, 0xe4, 0x6f,
- 0x04, 0x1a, 0xe6, 0x0b, 0x51, 0x7d, 0x0f, 0xaf, 0x38, 0x47, 0x3e, 0x46,
- 0x24, 0x3b, 0xe7, 0xef, 0xeb, 0xc6, 0xbe, 0x1d, 0x4d, 0xb8, 0xee, 0xdc,
- 0xc2, 0x83, 0xf2, 0x78, 0xe0, 0xfa, 0xd6, 0xba, 0x3f, 0x61, 0x16, 0x37,
- 0xee, 0x86, 0x99, 0x7f, 0xa9, 0x9b, 0x14, 0xf6, 0xfb, 0xfa, 0xe9, 0xf3,
- 0x7a, 0x81, 0xc4, 0x6c, 0x51, 0x58, 0xab, 0x50, 0x47, 0x63, 0xf0, 0x6b,
- 0x13, 0xf8, 0x6d, 0xa9, 0x96, 0xdb, 0x44, 0xf5, 0xb0, 0x37, 0x66, 0xad,
- 0xdc, 0x7c, 0xe6, 0xaf, 0x78, 0x67, 0xa2, 0x9f, 0x3e, 0xc5, 0xba, 0x59,
- 0xe7, 0x19, 0xc0, 0x74, 0x6c, 0xa1, 0xed, 0x17, 0x3d, 0x38, 0xae, 0x27,
- 0xa5, 0x88, 0x3a, 0x34, 0x37, 0x87, 0x8a, 0x1e, 0xf1, 0x5b, 0xa5, 0xf9,
- 0xbb, 0x16, 0xef, 0xf0, 0x86, 0xe3, 0xd3, 0xa0, 0xb1, 0x68, 0x66, 0x78,
- 0x6f, 0x06, 0x1c, 0xbd, 0x5b, 0x70, 0x8c, 0x7b, 0x38, 0xc6, 0xa5, 0x74,
- 0x66, 0x02, 0xbe, 0x96, 0x41, 0x7e, 0xef, 0x37, 0x1f, 0x91, 0x4f, 0xa0,
- 0xb9, 0xc6, 0xdc, 0xd9, 0x11, 0xe8, 0xc9, 0x71, 0xf6, 0xdb, 0x87, 0x40,
- 0xf7, 0x77, 0x90, 0x5b, 0xfd, 0x9a, 0xa7, 0x14, 0x0b, 0x21, 0x87, 0x1d,
- 0xd1, 0xbf, 0xc3, 0x16, 0x4d, 0x13, 0xf6, 0xaa, 0x8c, 0xe1, 0x24, 0xda,
- 0x7b, 0xe4, 0xb7, 0x59, 0xe4, 0x2a, 0xf2, 0xd9, 0x29, 0x25, 0xd3, 0x78,
- 0x38, 0x84, 0xba, 0x26, 0x3b, 0x47, 0x3f, 0x92, 0x81, 0x50, 0xba, 0x15,
- 0x35, 0xa9, 0x23, 0x6f, 0xdb, 0xfc, 0x77, 0x0a, 0xb3, 0x72, 0xb1, 0x6e,
- 0xe2, 0xf9, 0x5d, 0xe8, 0xe1, 0x4f, 0xf1, 0xfe, 0x76, 0x0f, 0xea, 0x3e,
- 0xac, 0x64, 0x60, 0xbb, 0x49, 0x5d, 0xcf, 0xb0, 0x8e, 0xa8, 0x21, 0xdf,
- 0x2a, 0xe4, 0x1a, 0xd4, 0x55, 0x63, 0xac, 0x5d, 0x9f, 0x5b, 0xbc, 0x26,
- 0x97, 0xe6, 0xf9, 0x3b, 0x28, 0xf3, 0xf2, 0x41, 0xc6, 0x03, 0x73, 0x26,
- 0x85, 0xb9, 0x25, 0xc6, 0x32, 0x7c, 0x37, 0xe0, 0x40, 0x3d, 0xa8, 0x11,
- 0x50, 0x6b, 0xaf, 0x5b, 0x49, 0xf0, 0x79, 0x4d, 0x2e, 0xce, 0x87, 0x65,
- 0xd1, 0x62, 0x5d, 0x24, 0xf1, 0x2c, 0x60, 0x2f, 0x2e, 0xfd, 0x93, 0x6b,
- 0x13, 0x84, 0x47, 0xcf, 0x53, 0x44, 0x5d, 0xf7, 0x88, 0xde, 0xfb, 0xd3,
- 0xf4, 0x4c, 0x9a, 0x9a, 0xfb, 0xbc, 0x82, 0x5c, 0xa4, 0x3f, 0xe9, 0xdf,
- 0x28, 0x58, 0x1b, 0x1c, 0x83, 0xcd, 0xb2, 0x76, 0x67, 0x3f, 0x80, 0xf7,
- 0x3a, 0xd7, 0xc9, 0x3b, 0x9e, 0x0b, 0xfd, 0x90, 0x0d, 0xfd, 0x9e, 0x77,
- 0x62, 0xc8, 0xa3, 0x8a, 0xbe, 0x5e, 0xd2, 0xb1, 0xa0, 0x54, 0x29, 0x20,
- 0xa7, 0x20, 0x06, 0xd8, 0xbd, 0xb0, 0xc5, 0x49, 0xe8, 0x72, 0x0c, 0x70,
- 0x5b, 0x72, 0xc9, 0x6a, 0x49, 0xd7, 0x65, 0x6a, 0xe5, 0xf6, 0xfd, 0x4d,
- 0x1e, 0xfe, 0xa3, 0x56, 0x61, 0x5b, 0xf0, 0x21, 0xb5, 0x1a, 0xc5, 0x13,
- 0xf1, 0x78, 0x15, 0xfd, 0x45, 0x99, 0xf7, 0x43, 0xe8, 0x0d, 0xca, 0xbc,
- 0x3b, 0x49, 0xe2, 0x39, 0xc2, 0xfb, 0x22, 0x2f, 0xae, 0x11, 0x3f, 0xe9,
- 0xf0, 0xe3, 0x0b, 0x6b, 0x49, 0xc6, 0x17, 0xbf, 0x9e, 0x74, 0x6d, 0xe1,
- 0x44, 0x85, 0x31, 0x84, 0x76, 0xdd, 0x8f, 0xb8, 0x45, 0x5b, 0x70, 0x6b,
- 0xc9, 0xa5, 0xaa, 0x2b, 0xb3, 0xe9, 0xc6, 0x05, 0x9d, 0x23, 0x0e, 0x88,
- 0x05, 0x1b, 0xa3, 0xec, 0xb0, 0xa6, 0x73, 0xc0, 0x79, 0xc9, 0xe8, 0x27,
- 0x65, 0xf6, 0xaa, 0x64, 0x96, 0x46, 0xe4, 0x05, 0x1d, 0xb7, 0xfc, 0x98,
- 0xc5, 0x1a, 0x92, 0xbf, 0x1f, 0x27, 0xe5, 0xf9, 0xd3, 0xd7, 0x24, 0xfb,
- 0x22, 0xe3, 0xd6, 0x70, 0x6c, 0x87, 0xc1, 0x58, 0xe5, 0x48, 0x1d, 0xb9,
- 0xe9, 0x11, 0x9b, 0xff, 0x16, 0x20, 0x84, 0x9e, 0xce, 0x91, 0xd6, 0xd1,
- 0x84, 0x1d, 0x37, 0xfa, 0x9f, 0xd8, 0x61, 0x30, 0x37, 0x0e, 0x9b, 0x4f,
- 0x89, 0x7f, 0x1f, 0xd5, 0x26, 0x4f, 0xe9, 0xbb, 0x0a, 0xb8, 0xed, 0xdc,
- 0xfb, 0xfa, 0x77, 0x94, 0x1b, 0x29, 0xca, 0x1a, 0xdf, 0xab, 0x9c, 0x2f,
- 0x46, 0x6e, 0xa4, 0x5a, 0xa4, 0x74, 0x87, 0xe3, 0x3c, 0x39, 0xfa, 0xc0,
- 0x6e, 0xf7, 0xdf, 0x8b, 0x3c, 0x7d, 0x87, 0x1b, 0x0b, 0x7e, 0xcd, 0xfb,
- 0xfe, 0x3a, 0x9e, 0xb4, 0x6d, 0xe6, 0x5b, 0xe6, 0x47, 0xea, 0x0d, 0xcf,
- 0x25, 0xbe, 0x33, 0xf7, 0xce, 0x22, 0xf7, 0x32, 0x5f, 0xee, 0x92, 0x1c,
- 0x7f, 0xe7, 0x53, 0x7a, 0xbe, 0xe8, 0xd6, 0xd2, 0x1e, 0x5c, 0x75, 0x4a,
- 0xa6, 0xab, 0xac, 0xa1, 0x2e, 0x22, 0x97, 0x0d, 0xc1, 0x56, 0x99, 0xd3,
- 0x8e, 0x23, 0x9f, 0xf3, 0xf7, 0x69, 0xac, 0x2d, 0x70, 0x5f, 0x22, 0x19,
- 0x57, 0xcd, 0xbf, 0x2b, 0xdd, 0x8c, 0xf2, 0x3e, 0xea, 0xfc, 0x10, 0xf4,
- 0xfe, 0x15, 0xf6, 0x16, 0x03, 0xda, 0x46, 0xb2, 0x2f, 0x51, 0xf6, 0xee,
- 0xef, 0xd7, 0xd2, 0xed, 0xfa, 0x00, 0xeb, 0x80, 0xcf, 0x40, 0x2e, 0x07,
- 0xec, 0x6b, 0xcc, 0xdd, 0xff, 0xa6, 0xac, 0xe1, 0xe4, 0x53, 0x06, 0x7d,
- 0x1b, 0xdf, 0x4b, 0x21, 0x59, 0x88, 0x92, 0x7f, 0xc8, 0xcb, 0xa0, 0xef,
- 0x6c, 0x27, 0x87, 0xad, 0x32, 0xf8, 0x0b, 0xc8, 0x80, 0xb2, 0xf4, 0x65,
- 0xc0, 0xf7, 0x09, 0xe8, 0x8b, 0x3d, 0x43, 0xbf, 0xee, 0x23, 0x4b, 0x0d,
- 0xf7, 0xec, 0x52, 0xa5, 0x99, 0x66, 0xd2, 0x4b, 0x9d, 0x9e, 0x97, 0x9c,
- 0xd6, 0xef, 0xac, 0xe4, 0xaa, 0xe7, 0x65, 0x7f, 0x75, 0x56, 0x1e, 0xb5,
- 0x1e, 0x06, 0xbf, 0x57, 0x9c, 0x82, 0xa5, 0x7b, 0x95, 0xb1, 0x3c, 0xce,
- 0x2e, 0x8c, 0xf4, 0xca, 0x4d, 0xd4, 0x1d, 0xcf, 0x2e, 0x9a, 0xf2, 0x3f,
- 0x9d, 0x5b, 0x5f, 0x6c, 0x5b, 0xd5, 0x19, 0xff, 0x7c, 0x6d, 0x27, 0x69,
- 0x68, 0xc2, 0xad, 0xeb, 0x24, 0x6e, 0x9a, 0x51, 0x3b, 0xbe, 0x6d, 0x23,
- 0x92, 0xa2, 0xdb, 0x10, 0x68, 0xd4, 0x65, 0x8a, 0x71, 0x42, 0x17, 0xb6,
- 0x22, 0xd2, 0xae, 0xab, 0x2a, 0x8d, 0x81, 0xe5, 0xa6, 0x7f, 0xd8, 0xc3,
- 0x0a, 0x85, 0x75, 0x08, 0x21, 0xd5, 0xb8, 0xe9, 0xd6, 0x69, 0x21, 0x4e,
- 0xff, 0x2d, 0x8c, 0x87, 0xcd, 0x4a, 0xd2, 0x96, 0x4d, 0x11, 0x2e, 0x88,
- 0xb2, 0x3d, 0x6c, 0xa3, 0x4a, 0x01, 0xed, 0x79, 0x7b, 0x99, 0x34, 0x36,
- 0x65, 0x05, 0x36, 0x5e, 0x36, 0xf5, 0x81, 0x07, 0xa6, 0xd1, 0x79, 0xbf,
- 0xdf, 0x77, 0xee, 0x75, 0x6c, 0x13, 0x84, 0xb4, 0x48, 0x91, 0xef, 0x39,
- 0xf7, 0xdc, 0x73, 0xce, 0x3d, 0xdf, 0xff, 0xef, 0xfb, 0xdd, 0x8c, 0x3d,
- 0x28, 0x3f, 0xd2, 0x5c, 0x3e, 0xe3, 0x93, 0x00, 0x7c, 0x52, 0x83, 0x2d,
- 0x90, 0x36, 0x27, 0x76, 0x53, 0xe8, 0x53, 0x86, 0x41, 0xeb, 0xb8, 0xf1,
- 0x9b, 0x6d, 0x73, 0x7f, 0xcb, 0x59, 0xf8, 0xee, 0xee, 0x7d, 0x6d, 0x7e,
- 0xce, 0xd7, 0xf8, 0xb7, 0x7f, 0xf2, 0x6a, 0x68, 0x83, 0x32, 0x83, 0xfd,
- 0xbc, 0xa1, 0x7a, 0xd6, 0x01, 0x2f, 0x31, 0x37, 0x1d, 0xd3, 0xfc, 0x43,
- 0x78, 0x9a, 0x3a, 0xea, 0x2a, 0x74, 0xd4, 0x10, 0x75, 0xd7, 0xf0, 0xbc,
- 0xcb, 0xfc, 0x40, 0x54, 0xfe, 0x38, 0x45, 0x3d, 0x1c, 0x97, 0x3f, 0x4c,
- 0x3d, 0x8b, 0xfd, 0x24, 0x8a, 0xcc, 0x51, 0xde, 0x98, 0xc9, 0xd1, 0x4f,
- 0x52, 0x7f, 0x3e, 0xed, 0x3e, 0xad, 0x76, 0x20, 0x6e, 0xe5, 0xd7, 0x87,
- 0x55, 0xdf, 0x1c, 0xd3, 0xda, 0x6e, 0xdc, 0xea, 0x92, 0x1b, 0x17, 0x8c,
- 0x8e, 0x0d, 0x4f, 0x47, 0x03, 0x23, 0x0b, 0xb4, 0x4b, 0xc9, 0x58, 0xd6,
- 0x6a, 0x94, 0x43, 0x51, 0xe6, 0x9e, 0x53, 0xd4, 0xcf, 0xb0, 0x85, 0xbd,
- 0x76, 0xd6, 0x6a, 0xf2, 0xec, 0x4f, 0xac, 0x4e, 0xcf, 0x1e, 0xf3, 0xf4,
- 0x2c, 0xef, 0xa5, 0x68, 0x03, 0x20, 0x93, 0x89, 0x99, 0x51, 0x2b, 0x09,
- 0x9b, 0x87, 0xeb, 0x45, 0xce, 0x1f, 0x97, 0xe3, 0x8b, 0x47, 0xe1, 0x7f,
- 0xf7, 0xda, 0x7b, 0x69, 0x57, 0xed, 0x21, 0xe2, 0x71, 0xb0, 0xfe, 0x97,
- 0xea, 0xe6, 0x7a, 0xd4, 0x9b, 0x8b, 0xf7, 0x21, 0xe7, 0xd3, 0xac, 0xd7,
- 0x36, 0x32, 0x9f, 0xa3, 0x7b, 0xad, 0x1d, 0xbb, 0xa7, 0xb2, 0xee, 0x64,
- 0xc1, 0xf1, 0xb0, 0x61, 0xf8, 0x85, 0x2f, 0xf4, 0x8d, 0x08, 0xd7, 0xe4,
- 0x7a, 0xad, 0x92, 0xde, 0x0f, 0xfd, 0x32, 0xcd, 0xff, 0x9c, 0x57, 0xbb,
- 0x42, 0xbc, 0x12, 0xed, 0x5c, 0xc5, 0x36, 0x7d, 0xc5, 0x9b, 0xaf, 0xbf,
- 0x5d, 0x9a, 0xa3, 0x55, 0xe3, 0x99, 0x5b, 0x61, 0x3b, 0x2e, 0xb9, 0x45,
- 0xfe, 0x96, 0xcb, 0x11, 0xa7, 0x41, 0xf6, 0xda, 0x1b, 0xeb, 0xe6, 0xd8,
- 0x86, 0x3e, 0xe3, 0x13, 0x04, 0xa7, 0x03, 0x9e, 0x6f, 0xb1, 0x89, 0x7e,
- 0x93, 0x77, 0xdd, 0xa4, 0x39, 0x99, 0xb8, 0xd5, 0x59, 0xf7, 0x1e, 0x9b,
- 0x2a, 0x76, 0x38, 0x6e, 0x51, 0x77, 0x36, 0x46, 0xa5, 0x95, 0x3c, 0x54,
- 0x56, 0x3f, 0x3e, 0xe4, 0x18, 0xcc, 0x45, 0xd4, 0x39, 0xd2, 0xce, 0x9c,
- 0xfd, 0x5b, 0x7a, 0x6e, 0x2d, 0xf4, 0x09, 0x70, 0x0d, 0x3e, 0xf9, 0x4c,
- 0xbe, 0x97, 0xb9, 0x5e, 0xcc, 0xdf, 0xcc, 0xf9, 0x5d, 0xef, 0x9c, 0x13,
- 0x6e, 0xce, 0xba, 0x5f, 0xb2, 0x17, 0x0c, 0xff, 0xa5, 0x1d, 0xf0, 0x5e,
- 0x2b, 0xda, 0x0b, 0xb4, 0x09, 0x9f, 0x37, 0x8f, 0x6f, 0x1b, 0x7a, 0xd4,
- 0x36, 0x9c, 0x2a, 0x90, 0x3f, 0xc9, 0x97, 0x3e, 0x3f, 0xfa, 0x3a, 0x8f,
- 0x3c, 0x4a, 0x3d, 0x3b, 0x28, 0x67, 0x0b, 0x3c, 0x9b, 0x94, 0xd6, 0xb4,
- 0x36, 0x9f, 0x3b, 0xa8, 0x98, 0xac, 0xee, 0xe9, 0xc4, 0x4b, 0x39, 0x19,
- 0x96, 0xab, 0x2e, 0xcf, 0x2c, 0x51, 0xcc, 0x04, 0x5b, 0xaa, 0xde, 0x7f,
- 0xbf, 0x9e, 0x59, 0x58, 0x7d, 0xc6, 0x18, 0xc6, 0x3e, 0xef, 0xd1, 0xbb,
- 0x55, 0xcf, 0x36, 0x53, 0x43, 0x9f, 0xaf, 0xeb, 0x39, 0x85, 0xa1, 0x13,
- 0x59, 0xdf, 0x0f, 0x47, 0xf8, 0x0c, 0xd7, 0xa5, 0xcf, 0xc7, 0xb5, 0xc8,
- 0x7b, 0xdd, 0xb0, 0xd8, 0xfd, 0x12, 0xdc, 0x09, 0xd1, 0xdf, 0xc9, 0x3a,
- 0x72, 0x00, 0xb2, 0xba, 0xd9, 0x60, 0x60, 0xc6, 0x8d, 0xaf, 0x91, 0xb1,
- 0xae, 0xe1, 0x1c, 0x11, 0xab, 0xc0, 0x8f, 0x3e, 0xf5, 0x93, 0xdb, 0x98,
- 0x2f, 0xe3, 0xf9, 0xeb, 0x03, 0x98, 0xdf, 0xf1, 0xea, 0xea, 0x53, 0xdb,
- 0xc9, 0xab, 0xa3, 0x5a, 0x1f, 0xe4, 0x33, 0x94, 0x63, 0x9e, 0x19, 0xe9,
- 0xf2, 0x1e, 0x9e, 0x67, 0x7b, 0x5b, 0x1d, 0x1d, 0x93, 0xde, 0xfe, 0xfc,
- 0xfb, 0x61, 0x09, 0xb7, 0x53, 0xc7, 0x45, 0x25, 0x39, 0xcd, 0x98, 0x05,
- 0xb6, 0x6b, 0x9c, 0x73, 0x7d, 0xb1, 0x2e, 0xce, 0xfc, 0x9f, 0xba, 0x38,
- 0x63, 0x7d, 0xa4, 0xbc, 0x13, 0xd6, 0x3c, 0xd6, 0xe7, 0xd3, 0xb5, 0x58,
- 0x43, 0x57, 0xbf, 0x76, 0x1f, 0xad, 0xd0, 0xf1, 0x87, 0x05, 0xda, 0xab,
- 0x94, 0xe6, 0x94, 0xff, 0x3e, 0xc5, 0xb3, 0xe5, 0x1e, 0xaf, 0x72, 0x8f,
- 0xc3, 0x4b, 0x8a, 0x83, 0x7c, 0x58, 0x65, 0xf8, 0x74, 0x81, 0x3a, 0xa6,
- 0x45, 0xe6, 0x67, 0x7c, 0x3d, 0x33, 0xe6, 0xf9, 0xb8, 0xf9, 0xf5, 0x0d,
- 0xaa, 0x67, 0xe0, 0xdd, 0x38, 0x23, 0x9e, 0x7d, 0xe9, 0x92, 0xb9, 0x0b,
- 0xb4, 0xbb, 0x49, 0xf4, 0x45, 0x03, 0x73, 0x0b, 0xac, 0x4d, 0x12, 0x8b,
- 0x32, 0x2c, 0xac, 0xfb, 0x8f, 0xd8, 0xa7, 0x20, 0x6f, 0x31, 0x79, 0x7f,
- 0x8a, 0x3e, 0x7d, 0x03, 0x7c, 0xe3, 0xd6, 0xba, 0xf3, 0xdd, 0x51, 0xf1,
- 0x09, 0x6b, 0xe9, 0x1e, 0xef, 0x90, 0x66, 0xf2, 0xb9, 0x63, 0xdf, 0x10,
- 0xfa, 0x60, 0xbc, 0xce, 0x22, 0x16, 0x60, 0xec, 0x11, 0xd7, 0xd8, 0x63,
- 0xae, 0xc8, 0xbe, 0x16, 0x2f, 0xaf, 0xd4, 0xa2, 0xbc, 0x42, 0x7e, 0xcb,
- 0xa8, 0xff, 0x3d, 0xa4, 0x3a, 0x2b, 0x3f, 0xd5, 0x6b, 0x70, 0x2c, 0x76,
- 0x4c, 0x79, 0x4f, 0x6a, 0x78, 0x2f, 0xe6, 0xad, 0x3d, 0xd6, 0x61, 0x7c,
- 0x2b, 0x5b, 0xf5, 0x4d, 0x58, 0xc7, 0xd1, 0xae, 0x70, 0x7e, 0xf2, 0x06,
- 0x79, 0x84, 0x3a, 0xcf, 0x1f, 0xe7, 0xd3, 0xc3, 0x6f, 0x73, 0x3c, 0xf9,
- 0xbf, 0x1a, 0x8b, 0xe0, 0xcb, 0xaa, 0xdf, 0xe7, 0xcb, 0x1d, 0xef, 0x55,
- 0xdb, 0x04, 0xca, 0x5d, 0x75, 0x7d, 0xd2, 0x96, 0xc8, 0xf4, 0x0a, 0x5d,
- 0xd2, 0xfd, 0xdc, 0xff, 0xf3, 0xcc, 0xed, 0x42, 0xde, 0x56, 0xa3, 0xcd,
- 0x09, 0xa5, 0x4d, 0x06, 0xb4, 0x89, 0x28, 0x6d, 0x18, 0xef, 0x3d, 0xe5,
- 0xf1, 0x5b, 0x0b, 0xce, 0x8b, 0xb9, 0x5a, 0xe8, 0xba, 0x7d, 0xd4, 0xf9,
- 0xcf, 0x76, 0x68, 0x7d, 0xd0, 0xa1, 0xee, 0x5b, 0x0b, 0x7d, 0xc6, 0xf6,
- 0x56, 0xf5, 0x47, 0x4c, 0xbc, 0x15, 0xd7, 0x3c, 0x68, 0x10, 0xfa, 0x79,
- 0x6e, 0x0a, 0xbe, 0x1a, 0x71, 0x6f, 0x35, 0xb4, 0xfa, 0x8e, 0x77, 0x5e,
- 0xf3, 0x4a, 0x1b, 0xca, 0x00, 0xf5, 0xe6, 0x3a, 0xcc, 0xb7, 0x27, 0xda,
- 0x07, 0xfe, 0xfa, 0x19, 0xfa, 0x37, 0x6b, 0x3c, 0x11, 0x84, 0xcc, 0xdf,
- 0x9c, 0x6a, 0xf7, 0x62, 0x38, 0x07, 0x6d, 0xc4, 0xad, 0x53, 0x11, 0xc6,
- 0x14, 0x68, 0xf7, 0x48, 0xc3, 0x34, 0xe2, 0x57, 0xe8, 0xf1, 0x25, 0xb5,
- 0x47, 0x7d, 0xb8, 0x7f, 0x07, 0x71, 0x7e, 0xb8, 0x3e, 0x8a, 0xe7, 0x7a,
- 0x0d, 0x16, 0x21, 0xba, 0x45, 0xcf, 0x74, 0x6e, 0x2a, 0x11, 0x3b, 0x2c,
- 0x5e, 0xdf, 0xb8, 0xab, 0xfa, 0x60, 0x65, 0x5f, 0x0f, 0xca, 0x9e, 0x8a,
- 0xbd, 0x60, 0x1c, 0x0d, 0x1f, 0x7e, 0xc6, 0xd8, 0x83, 0x7c, 0xb1, 0x4f,
- 0xf1, 0x51, 0xc1, 0xa1, 0x45, 0x9c, 0x25, 0x7d, 0xd2, 0x65, 0xf8, 0xe1,
- 0x2e, 0xce, 0x90, 0x7e, 0x77, 0xf9, 0xe4, 0xa4, 0x9b, 0x62, 0x7d, 0x0c,
- 0xfa, 0xe0, 0xa4, 0x8c, 0x20, 0x2e, 0x18, 0x09, 0xb6, 0x32, 0xaf, 0x0c,
- 0xdf, 0x30, 0xe7, 0xe5, 0x1e, 0xfb, 0x98, 0x33, 0x95, 0x73, 0x0b, 0xdc,
- 0x3b, 0x65, 0xdb, 0xc4, 0xde, 0x73, 0x53, 0xdc, 0xaf, 0xc9, 0x43, 0xb0,
- 0x6d, 0x4d, 0xbb, 0xf8, 0xe5, 0x59, 0x0c, 0xe0, 0x77, 0x10, 0xf2, 0xc0,
- 0xb1, 0xf8, 0x5d, 0x58, 0x96, 0x77, 0x2f, 0xf8, 0xb6, 0x3d, 0x20, 0x6f,
- 0x3b, 0xe5, 0x93, 0xa7, 0xdc, 0xf5, 0x3c, 0x03, 0x37, 0xc7, 0x9a, 0xb5,
- 0xe3, 0xb8, 0x79, 0x29, 0x97, 0x97, 0xdc, 0xa5, 0xf5, 0x96, 0xd2, 0x92,
- 0xf2, 0xbf, 0x8c, 0x33, 0xbc, 0x7e, 0xaf, 0x25, 0x86, 0x7e, 0xa4, 0xcd,
- 0x67, 0x6b, 0x7f, 0xd5, 0xb6, 0xc0, 0xd7, 0x7f, 0xe4, 0x47, 0xf2, 0xe5,
- 0xb2, 0xec, 0x52, 0xfd, 0xbf, 0xda, 0x73, 0xd5, 0xba, 0xdf, 0xf7, 0x6f,
- 0xa9, 0xdf, 0xb5, 0xfe, 0xa3, 0xf1, 0xc1, 0x96, 0xe9, 0x7a, 0x9d, 0xf0,
- 0x98, 0x57, 0x57, 0x58, 0x8d, 0xf7, 0x0e, 0x78, 0x7a, 0x21, 0xa5, 0xbe,
- 0x73, 0xca, 0xa6, 0x7e, 0xe0, 0x7e, 0x9a, 0xe5, 0xe0, 0xec, 0x6d, 0xd0,
- 0xc4, 0xd7, 0xc1, 0x8c, 0xfb, 0x7c, 0xdd, 0xd1, 0xea, 0xf9, 0xc2, 0x96,
- 0x74, 0x9f, 0xa3, 0xef, 0xe4, 0x40, 0x8f, 0xb6, 0x49, 0x66, 0x3c, 0x28,
- 0xc9, 0x73, 0x1b, 0x62, 0xc6, 0xd7, 0x25, 0xff, 0x41, 0xde, 0xb4, 0x4f,
- 0x7d, 0x51, 0xf4, 0xdf, 0x29, 0x5c, 0xdb, 0xf0, 0x33, 0xe4, 0x79, 0x9f,
- 0x7f, 0xcf, 0xae, 0xe3, 0xd1, 0x9d, 0x1e, 0x8f, 0xf2, 0xbe, 0x65, 0xea,
- 0x1f, 0x18, 0xdb, 0x7d, 0x8e, 0x7b, 0x34, 0xcf, 0x75, 0x9f, 0x33, 0xf1,
- 0x7a, 0xed, 0x73, 0x7d, 0x95, 0xe7, 0x70, 0xbf, 0x47, 0xb1, 0x61, 0x98,
- 0x7b, 0xd7, 0x20, 0x7c, 0xba, 0x3e, 0xda, 0x1c, 0xda, 0xef, 0xcd, 0xee,
- 0x2e, 0x21, 0xbf, 0x27, 0x3c, 0x9e, 0xa3, 0xbe, 0x89, 0x78, 0xfa, 0x66,
- 0xc5, 0xbe, 0x8c, 0x18, 0xfc, 0x09, 0x73, 0x22, 0x55, 0xf6, 0xe5, 0x71,
- 0xf3, 0x6e, 0x35, 0xf6, 0xe5, 0x4e, 0x6f, 0x1e, 0xff, 0x9e, 0xaf, 0x57,
- 0xfc, 0xb6, 0xaf, 0x57, 0xea, 0x7d, 0x5a, 0x9f, 0xf6, 0xb5, 0xb8, 0xaf,
- 0xea, 0x98, 0x2f, 0xbf, 0x6a, 0xde, 0x25, 0x8b, 0x98, 0x8d, 0x3e, 0x65,
- 0x22, 0x67, 0x30, 0xd3, 0xd6, 0x59, 0x8b, 0xb8, 0x0f, 0xe7, 0xc7, 0x92,
- 0x8e, 0xdc, 0xd6, 0xd8, 0xfa, 0xf4, 0xec, 0x98, 0xe6, 0x79, 0xe6, 0x5c,
- 0x4f, 0xef, 0x44, 0x77, 0x43, 0xae, 0x5e, 0x89, 0xac, 0x60, 0x8a, 0x66,
- 0x4e, 0xa4, 0x61, 0x87, 0x52, 0x5a, 0x2f, 0xfb, 0x2e, 0xf6, 0x3b, 0xa8,
- 0x78, 0xae, 0x35, 0xce, 0x73, 0xf2, 0x90, 0x5d, 0xd6, 0xda, 0x4d, 0xd3,
- 0x50, 0xf1, 0x44, 0xd3, 0x8b, 0x3e, 0xdf, 0x93, 0x9f, 0x66, 0x4e, 0x1c,
- 0x9c, 0x29, 0x0f, 0x87, 0xb6, 0xf7, 0xda, 0x79, 0x21, 0x66, 0x7f, 0x58,
- 0x8e, 0x28, 0x76, 0xf8, 0x15, 0xdc, 0xdf, 0xc7, 0xf8, 0x32, 0x11, 0x52,
- 0x4c, 0x70, 0x22, 0x36, 0x01, 0x59, 0xcc, 0xba, 0xc4, 0xf8, 0xaf, 0x55,
- 0xac, 0xff, 0x9c, 0xd0, 0xcf, 0x22, 0xa6, 0xe0, 0x59, 0x39, 0xec, 0x6e,
- 0x76, 0x97, 0xc4, 0xf8, 0xbf, 0x59, 0xad, 0x09, 0x35, 0xca, 0x84, 0x1b,
- 0x6a, 0x4a, 0x97, 0x8c, 0x0c, 0x8c, 0x06, 0x53, 0x6b, 0x26, 0x9d, 0x68,
- 0xd3, 0xae, 0x12, 0x64, 0xbc, 0x04, 0xfd, 0x5f, 0x8a, 0x05, 0x46, 0x14,
- 0x9b, 0xf6, 0x65, 0x49, 0xb7, 0xd3, 0xcf, 0xa7, 0x3e, 0xf9, 0x8a, 0xdc,
- 0xb4, 0xb7, 0xca, 0xcd, 0x1e, 0xe2, 0x31, 0xfb, 0xd1, 0xa6, 0x2e, 0x19,
- 0x44, 0x5f, 0x12, 0x7d, 0x4d, 0xca, 0x8f, 0x1a, 0x9f, 0x41, 0x67, 0xdd,
- 0xb4, 0xa9, 0xab, 0xee, 0xe2, 0x2f, 0xde, 0xf5, 0x6f, 0xa0, 0x09, 0xb1,
- 0x1d, 0xdb, 0xd0, 0xa6, 0x8e, 0xb3, 0xeb, 0xfa, 0x3b, 0xd1, 0xbe, 0x17,
- 0x73, 0x34, 0xe8, 0xfb, 0x59, 0xce, 0x76, 0x53, 0xe7, 0xac, 0x19, 0xb3,
- 0xae, 0xae, 0xfd, 0xfb, 0x36, 0x83, 0x4f, 0xf8, 0x94, 0xf4, 0xce, 0xa5,
- 0xe4, 0xe1, 0x8e, 0xda, 0xf6, 0xbf, 0xea, 0xda, 0xad, 0xb2, 0xa6, 0x8d,
- 0x64, 0x38, 0xd6, 0x5e, 0xdb, 0xef, 0xf3, 0x93, 0xdf, 0xee, 0xc0, 0xfb,
- 0x42, 0x66, 0xac, 0xa4, 0xc6, 0x52, 0x37, 0xa3, 0x5c, 0xeb, 0xc3, 0xba,
- 0x67, 0x78, 0xcd, 0x67, 0xf8, 0x2c, 0xf3, 0x7a, 0xb7, 0xd9, 0x8f, 0x67,
- 0x98, 0x13, 0x60, 0x5e, 0x83, 0x3c, 0xbb, 0x5a, 0x9c, 0xc5, 0x31, 0x9f,
- 0xcd, 0x37, 0x64, 0x2a, 0xbc, 0xe7, 0xeb, 0x95, 0x58, 0x05, 0xab, 0xb6,
- 0xab, 0xe0, 0xe7, 0x84, 0x49, 0x3b, 0xad, 0x49, 0xc5, 0x6e, 0x80, 0xce,
- 0x87, 0x40, 0xe7, 0x07, 0x83, 0x8c, 0x0b, 0x9b, 0x3d, 0x5a, 0x3b, 0x32,
- 0x52, 0xfa, 0x0d, 0x64, 0x9c, 0x3c, 0x0a, 0x9f, 0xa2, 0x64, 0x79, 0xf8,
- 0x8c, 0x01, 0xd8, 0x34, 0x57, 0x82, 0x9a, 0x77, 0x40, 0x7c, 0x3f, 0x7f,
- 0x5d, 0x46, 0xa6, 0x98, 0x13, 0x20, 0x3f, 0x33, 0xae, 0x4f, 0xe1, 0xde,
- 0x2d, 0x8c, 0x75, 0x21, 0xc3, 0x63, 0xe0, 0xd7, 0x90, 0x38, 0xd3, 0xdb,
- 0x24, 0x37, 0x3e, 0xa6, 0x3e, 0x40, 0x37, 0x6c, 0xd4, 0x29, 0x77, 0x54,
- 0x26, 0xaf, 0x6c, 0x82, 0xac, 0x32, 0xee, 0xd7, 0x9c, 0x46, 0x39, 0xac,
- 0xbe, 0x39, 0x7d, 0x0e, 0xe6, 0xe1, 0x4c, 0x8d, 0xd9, 0xc8, 0xed, 0xa1,
- 0x98, 0xb4, 0x8e, 0xca, 0xcc, 0xac, 0xad, 0x78, 0x97, 0x94, 0xdc, 0x2e,
- 0x93, 0x76, 0xd9, 0x7d, 0x71, 0xe8, 0x2a, 0xfa, 0xf2, 0x3f, 0x88, 0x98,
- 0xb3, 0xdc, 0xbd, 0x81, 0x31, 0x71, 0x72, 0xba, 0x7a, 0x0e, 0xc5, 0xc8,
- 0xe0, 0xde, 0x2f, 0xdb, 0x8c, 0xcc, 0x30, 0x3e, 0xfe, 0xa0, 0x9c, 0x8a,
- 0x72, 0x4d, 0x8e, 0x65, 0xed, 0x96, 0x3c, 0xc2, 0xbd, 0xfd, 0xc7, 0xe3,
- 0xe5, 0x97, 0x31, 0x5f, 0x5c, 0xba, 0x5f, 0x1d, 0xd3, 0xb8, 0xfe, 0x54,
- 0x4d, 0x0c, 0x6b, 0xf2, 0x05, 0x26, 0x8e, 0xbd, 0x2e, 0x13, 0x8b, 0xa4,
- 0x0f, 0x6d, 0x7c, 0x40, 0x7e, 0xe1, 0xf4, 0xda, 0x4f, 0x68, 0xad, 0x31,
- 0x91, 0x62, 0x7d, 0xa6, 0xd9, 0x49, 0xda, 0xf3, 0x12, 0x1a, 0xfc, 0x1a,
- 0xae, 0x19, 0xd7, 0xe6, 0xdd, 0x5e, 0xf7, 0x09, 0xf1, 0x71, 0x20, 0x9b,
- 0x53, 0x8d, 0x81, 0x4f, 0xca, 0xd7, 0xf7, 0x71, 0x8c, 0xc1, 0x81, 0x48,
- 0x80, 0xb4, 0x7a, 0xef, 0x2e, 0xe2, 0x67, 0x6a, 0xf3, 0x7f, 0x0f, 0x1c,
- 0xdb, 0x3b, 0x90, 0x38, 0xc3, 0x18, 0x36, 0xec, 0x3c, 0xba, 0xc1, 0xbc,
- 0x6b, 0x2e, 0xb7, 0x4e, 0xb4, 0x7e, 0x76, 0xfc, 0x1f, 0x0e, 0xf1, 0x10,
- 0x89, 0x58, 0xa3, 0xc5, 0x3c, 0x38, 0x75, 0x1c, 0x6b, 0x2a, 0xcc, 0xb9,
- 0x11, 0xcb, 0xdf, 0x24, 0x97, 0xfb, 0x2c, 0x79, 0x20, 0x94, 0x8a, 0x5b,
- 0xb2, 0x25, 0x7e, 0x4e, 0xb0, 0x26, 0xeb, 0x2b, 0x8b, 0x89, 0x1c, 0xc7,
- 0x87, 0xa6, 0x39, 0x5f, 0x5c, 0xe3, 0x95, 0xe4, 0x96, 0x72, 0xf9, 0x29,
- 0x57, 0x02, 0xc9, 0x7b, 0x3e, 0x2c, 0xb3, 0x16, 0x6e, 0xbd, 0xfa, 0x79,
- 0x38, 0x05, 0xea, 0x0a, 0x7b, 0xc2, 0x60, 0x0e, 0x27, 0x8f, 0x77, 0x2f,
- 0xb2, 0xfd, 0xe4, 0x43, 0xa6, 0x7d, 0x06, 0xed, 0x06, 0x0f, 0xeb, 0x34,
- 0x75, 0xbc, 0xbb, 0x78, 0x6c, 0x83, 0x89, 0xbf, 0x97, 0x15, 0xff, 0xf5,
- 0x56, 0x4d, 0x4c, 0x93, 0x0a, 0x8c, 0x17, 0xc6, 0x02, 0x63, 0x05, 0xab,
- 0xaf, 0x09, 0xb4, 0x5a, 0x70, 0x99, 0xab, 0xf1, 0x73, 0x56, 0xcc, 0xf7,
- 0x8b, 0x3c, 0xa9, 0x18, 0x29, 0xd6, 0x14, 0x2d, 0xf5, 0x85, 0x0e, 0x2d,
- 0x30, 0xc7, 0x1f, 0x51, 0x7d, 0x70, 0x78, 0xb1, 0x55, 0xf2, 0xf6, 0x7a,
- 0xc9, 0xab, 0x8c, 0x47, 0x55, 0x07, 0x58, 0xce, 0x3d, 0xe8, 0xe3, 0xbe,
- 0x1f, 0x57, 0x5c, 0xc4, 0xeb, 0x85, 0x4e, 0xb4, 0x99, 0x6b, 0xde, 0x51,
- 0xd7, 0x5f, 0x5d, 0x97, 0x4d, 0xd8, 0x96, 0x55, 0x5f, 0x93, 0x65, 0x5f,
- 0x7d, 0x2d, 0xf6, 0xb4, 0x5c, 0x27, 0xdf, 0x94, 0xfc, 0x9c, 0xbb, 0xeb,
- 0xe5, 0xdc, 0x1f, 0xc3, 0x9c, 0x9c, 0x5b, 0x32, 0xa1, 0xa1, 0xa6, 0xbe,
- 0x53, 0x53, 0xc1, 0x5b, 0x2b, 0xf9, 0x53, 0xb4, 0x17, 0x2b, 0xb5, 0x72,
- 0xdc, 0x7b, 0x06, 0xbe, 0x48, 0x1e, 0x7e, 0x45, 0xce, 0xfb, 0xfe, 0x80,
- 0xf7, 0x2b, 0xcf, 0x7f, 0xc1, 0x9e, 0x9a, 0xb5, 0xce, 0x6e, 0xd5, 0xd4,
- 0xd9, 0xbf, 0x8d, 0x67, 0x59, 0x63, 0xcf, 0x95, 0x1b, 0xc0, 0xbb, 0x0d,
- 0xc4, 0x89, 0x54, 0xc6, 0x53, 0xc7, 0xab, 0x2e, 0xd7, 0xb9, 0x76, 0x79,
- 0x73, 0x05, 0xa1, 0xe7, 0x0f, 0x4e, 0xf9, 0x63, 0x4e, 0x4a, 0x63, 0x7f,
- 0x22, 0x16, 0xb4, 0x38, 0xc6, 0xe8, 0xfb, 0xb4, 0x7b, 0x12, 0x7a, 0x9c,
- 0x3a, 0x9f, 0xef, 0xed, 0xc0, 0xd7, 0xa3, 0x2e, 0xa0, 0x3e, 0x57, 0x1b,
- 0x10, 0xcf, 0x43, 0xd7, 0x8f, 0x94, 0x34, 0x97, 0x1f, 0xfb, 0x6a, 0x30,
- 0x31, 0x93, 0x55, 0xdd, 0x00, 0x7f, 0xaf, 0xf4, 0x26, 0xf3, 0x41, 0x67,
- 0x24, 0x50, 0x5d, 0xa7, 0x61, 0x6c, 0xc6, 0x9a, 0x46, 0x0b, 0x74, 0x83,
- 0xc8, 0x55, 0xf0, 0xc6, 0x6b, 0x0b, 0xe4, 0xd7, 0x60, 0xbb, 0x89, 0xaf,
- 0x96, 0x76, 0x58, 0xd2, 0xae, 0xb5, 0xcf, 0xbc, 0x13, 0xa1, 0x7f, 0x32,
- 0x9c, 0xec, 0x87, 0x9f, 0xad, 0xd8, 0x03, 0xe6, 0x2b, 0x0f, 0x22, 0x1e,
- 0xab, 0xce, 0xb1, 0x40, 0xbe, 0xc6, 0xd9, 0x9f, 0x85, 0x5f, 0xb9, 0x52,
- 0xf7, 0xc8, 0x17, 0x27, 0x35, 0xb7, 0x39, 0xb7, 0xd0, 0xa2, 0x3a, 0x76,
- 0xae, 0x38, 0x86, 0x73, 0x91, 0xad, 0xd6, 0x50, 0xde, 0xeb, 0x0f, 0x4b,
- 0xb1, 0xc8, 0xb6, 0x74, 0x35, 0xe8, 0xb9, 0xfb, 0xb5, 0x1d, 0x5b, 0xe6,
- 0xe1, 0x2b, 0x16, 0x17, 0x1d, 0xfc, 0xf7, 0xe0, 0xbf, 0x0f, 0xff, 0xbb,
- 0x25, 0x3d, 0x4d, 0xff, 0x95, 0xb5, 0x9c, 0x96, 0xba, 0xf5, 0xe9, 0x23,
- 0x75, 0x29, 0x0e, 0x2c, 0xef, 0xc5, 0x39, 0xf9, 0x62, 0xbd, 0x9c, 0x30,
- 0x4f, 0xea, 0xeb, 0x08, 0xe6, 0x4b, 0xfd, 0x5a, 0x5f, 0x75, 0x0d, 0xcb,
- 0xf2, 0xea, 0x5e, 0xe4, 0xe9, 0x66, 0x39, 0x5c, 0xf4, 0x6b, 0x57, 0x31,
- 0x39, 0x52, 0xa9, 0x5d, 0x49, 0x26, 0x38, 0xf4, 0xc9, 0x23, 0xd9, 0x29,
- 0xc5, 0x13, 0x58, 0xd6, 0xd0, 0xf5, 0x47, 0x26, 0x16, 0xdf, 0x7e, 0x64,
- 0x05, 0x13, 0x8e, 0x7b, 0x8b, 0xab, 0x61, 0x86, 0x88, 0xa5, 0xe3, 0xb7,
- 0x72, 0xea, 0xbb, 0x61, 0xdf, 0x7e, 0xcc, 0x43, 0x9c, 0x1d, 0xf4, 0x4c,
- 0xf3, 0x0a, 0x76, 0xd7, 0xc4, 0xa3, 0xc4, 0x91, 0xf2, 0xb9, 0x6a, 0xec,
- 0x47, 0x08, 0xe7, 0x2f, 0x01, 0xcb, 0xc9, 0x61, 0x1f, 0x3f, 0xed, 0x34,
- 0x7e, 0x20, 0x71, 0xa6, 0x89, 0x2a, 0xec, 0x91, 0x8f, 0x35, 0x7d, 0x09,
- 0x73, 0x65, 0xe4, 0x77, 0xa5, 0x47, 0xe5, 0x57, 0xa5, 0x31, 0xc8, 0xf7,
- 0x04, 0xe6, 0x3c, 0x20, 0x6f, 0x96, 0xf6, 0xc9, 0xb5, 0xd2, 0xb8, 0xbc,
- 0x51, 0xda, 0x8d, 0x98, 0x6a, 0x94, 0x58, 0x4f, 0x0f, 0x2b, 0x3d, 0x2c,
- 0x07, 0xcf, 0x2b, 0x06, 0xf0, 0x16, 0xfd, 0x9e, 0xe3, 0xea, 0x67, 0x13,
- 0x5f, 0x9f, 0xf8, 0x35, 0xe3, 0x79, 0x62, 0x33, 0x8b, 0x25, 0x1f, 0xc3,
- 0x71, 0xb4, 0x0b, 0x6b, 0xdb, 0xfc, 0x36, 0x65, 0xe4, 0x7c, 0x24, 0x30,
- 0x7a, 0x3e, 0x14, 0x78, 0x50, 0xbf, 0x73, 0x61, 0xbd, 0xb3, 0x2c, 0x93,
- 0xae, 0x43, 0xde, 0x1c, 0x1c, 0x81, 0x2c, 0x8c, 0x42, 0xd5, 0x3f, 0xe4,
- 0xac, 0x17, 0x90, 0x34, 0xf5, 0x11, 0xfc, 0xcc, 0xe4, 0x8b, 0xae, 0x64,
- 0x0b, 0xf3, 0x01, 0x83, 0x47, 0xb3, 0xd1, 0xee, 0x43, 0xfb, 0xe7, 0x5e,
- 0x7b, 0xa7, 0x64, 0x67, 0x25, 0xf5, 0xbe, 0xfa, 0xc3, 0x2f, 0x7b, 0x7d,
- 0x83, 0xe8, 0x03, 0x67, 0x5e, 0x64, 0xdf, 0x45, 0xaf, 0x8f, 0x67, 0xc2,
- 0x5a, 0x7d, 0x5c, 0xf9, 0x2a, 0x6b, 0x8f, 0x8b, 0x7e, 0xd7, 0xa0, 0xb5,
- 0xf8, 0x0f, 0x3a, 0x8d, 0x6e, 0x23, 0x26, 0xf0, 0x9f, 0x9d, 0x8c, 0xc1,
- 0x8a, 0x90, 0xaf, 0xbb, 0xa0, 0x13, 0xff, 0xba, 0x75, 0xa5, 0x6d, 0x0d,
- 0x7d, 0x5c, 0x85, 0xd1, 0xfe, 0x58, 0xba, 0x17, 0xff, 0xed, 0xe1, 0x79,
- 0x9f, 0xc0, 0xbb, 0xe1, 0xac, 0x0a, 0xc4, 0x8d, 0xc7, 0x21, 0xdb, 0x2d,
- 0xb2, 0xfe, 0x2c, 0xe9, 0xd5, 0x0b, 0x5d, 0x9d, 0x82, 0xdc, 0xba, 0xb2,
- 0x50, 0x0a, 0x05, 0x46, 0x0a, 0x29, 0x31, 0x78, 0x6a, 0x4b, 0x32, 0xd1,
- 0x94, 0x9c, 0x1e, 0x48, 0xf4, 0x30, 0x0f, 0x99, 0xed, 0x77, 0xe5, 0x52,
- 0x89, 0xf6, 0x38, 0x27, 0x97, 0x07, 0x12, 0x6e, 0x51, 0x88, 0x8b, 0x71,
- 0xe5, 0x32, 0x64, 0xf3, 0x9d, 0xf3, 0xbb, 0xe5, 0x48, 0x41, 0xfd, 0xe0,
- 0xde, 0xb0, 0xbc, 0x20, 0x97, 0x06, 0x5e, 0xb8, 0x75, 0xc9, 0x3d, 0x84,
- 0x33, 0x25, 0x1f, 0x1e, 0xee, 0x32, 0xfb, 0x56, 0x1c, 0x92, 0x30, 0x1f,
- 0xa2, 0x35, 0x35, 0xa7, 0x51, 0xd2, 0xfb, 0x23, 0x5e, 0x5c, 0x0e, 0x9f,
- 0x3b, 0x30, 0x60, 0xea, 0x29, 0x01, 0x7f, 0x9f, 0x61, 0xf8, 0x31, 0x7c,
- 0xce, 0xa7, 0x8d, 0x3f, 0x4f, 0x67, 0x20, 0x3d, 0xdb, 0x2a, 0xa1, 0x8b,
- 0xf7, 0x81, 0xae, 0x21, 0x39, 0xd4, 0x5f, 0x2e, 0x7f, 0xd3, 0x0d, 0xc5,
- 0x27, 0x10, 0xa3, 0x60, 0xff, 0xb2, 0xee, 0xc5, 0x36, 0xd0, 0xa4, 0x49,
- 0xa2, 0x2f, 0xfa, 0xeb, 0x35, 0x7a, 0x58, 0x86, 0x8b, 0xeb, 0x8c, 0x2d,
- 0xf3, 0xb1, 0x0d, 0xfe, 0x7c, 0x06, 0x53, 0xd6, 0x6d, 0xf5, 0x07, 0xbc,
- 0xef, 0x24, 0xbc, 0xf6, 0x3d, 0x81, 0x07, 0x42, 0xed, 0x12, 0x72, 0x9e,
- 0xdf, 0x48, 0x6c, 0xe4, 0x52, 0xc1, 0xef, 0x87, 0x9f, 0x18, 0xf2, 0xfd,
- 0x61, 0xd9, 0xbe, 0x72, 0xd6, 0xb2, 0xbd, 0x7b, 0xf1, 0x5b, 0xde, 0x9c,
- 0x29, 0x6f, 0x2c, 0x62, 0x8e, 0xd8, 0x5a, 0xb5, 0x4f, 0x66, 0xec, 0xa7,
- 0xf2, 0x74, 0x7f, 0xe2, 0x15, 0xc5, 0xc9, 0x56, 0x9e, 0xe1, 0x7d, 0xc4,
- 0x90, 0x25, 0x7d, 0x26, 0xb6, 0x07, 0xf4, 0xcd, 0xc4, 0xee, 0xb6, 0xe7,
- 0xad, 0x60, 0xc0, 0xf8, 0x23, 0x0d, 0xf2, 0xbd, 0x28, 0xec, 0x36, 0xbf,
- 0x61, 0x61, 0xfe, 0xcb, 0xbd, 0xed, 0xf9, 0x29, 0xec, 0x4b, 0x9c, 0x49,
- 0x5a, 0x13, 0xd8, 0x1f, 0xcf, 0x80, 0x18, 0x50, 0x0b, 0x74, 0xea, 0xc4,
- 0xfb, 0x21, 0x7e, 0xea, 0xf7, 0xdf, 0x7f, 0x1d, 0x74, 0x18, 0xf7, 0x6f,
- 0x70, 0x61, 0x62, 0x31, 0x17, 0x32, 0xec, 0x61, 0x60, 0xab, 0xe5, 0xd6,
- 0xc7, 0xc6, 0xfa, 0x78, 0x3a, 0x62, 0x94, 0x62, 0xf0, 0x03, 0x29, 0x13,
- 0xe4, 0xcd, 0x0e, 0xf4, 0xaf, 0xf9, 0x24, 0xa5, 0xaf, 0xee, 0xf7, 0x7d,
- 0x58, 0xc1, 0x76, 0x4f, 0x14, 0xf6, 0x19, 0x6c, 0x9e, 0xb5, 0x2c, 0xa9,
- 0xae, 0xa4, 0x3d, 0x89, 0xfd, 0xa6, 0x43, 0x89, 0x62, 0x4e, 0x62, 0x32,
- 0x0f, 0x7d, 0xf1, 0x1a, 0x64, 0xff, 0x5a, 0x29, 0x1e, 0x48, 0x63, 0x4f,
- 0x87, 0x0b, 0x43, 0x32, 0x31, 0xab, 0xdf, 0x7e, 0x41, 0xef, 0x0f, 0xc9,
- 0x5c, 0x21, 0xd1, 0x33, 0x0f, 0xfe, 0x9b, 0x2f, 0x10, 0x5f, 0xd4, 0x1b,
- 0x1f, 0xc5, 0x8c, 0x4b, 0x85, 0xcd, 0xb0, 0x0f, 0x92, 0xba, 0x04, 0xff,
- 0xe7, 0x52, 0xa9, 0x07, 0x7c, 0x86, 0xfb, 0x25, 0x07, 0xbf, 0xd0, 0x99,
- 0xa5, 0x01, 0xc8, 0x39, 0xf7, 0x62, 0xcb, 0xc2, 0x56, 0x9c, 0x1d, 0x71,
- 0x44, 0x8a, 0x1f, 0xff, 0x2f, 0xce, 0xd7, 0x7f, 0xef, 0x1d, 0x6a, 0xa7,
- 0xe7, 0x75, 0x5f, 0xb0, 0xcb, 0x88, 0x01, 0xb2, 0xfd, 0xc6, 0x6e, 0xa7,
- 0x23, 0x6d, 0x92, 0xbe, 0x9b, 0x76, 0xbc, 0x5d, 0x63, 0x44, 0xe5, 0xc5,
- 0x08, 0xef, 0xbf, 0xb3, 0xd1, 0xd0, 0x2f, 0x5c, 0xd7, 0xbe, 0x8e, 0xdf,
- 0x56, 0xe9, 0x70, 0xf8, 0x6b, 0xe3, 0xf7, 0xed, 0x8d, 0xac, 0xef, 0x76,
- 0x38, 0x49, 0xac, 0xf5, 0x5b, 0x2f, 0x5f, 0x80, 0xeb, 0x79, 0x3e, 0xb3,
- 0xc1, 0x5b, 0x97, 0xf3, 0xb6, 0x62, 0x9e, 0x16, 0x6f, 0xad, 0x56, 0xcd,
- 0x4f, 0x9a, 0xb5, 0x10, 0xe3, 0x16, 0xfe, 0xb2, 0x51, 0xbf, 0x35, 0x86,
- 0xbd, 0xa8, 0x6d, 0xff, 0x79, 0x23, 0x71, 0x73, 0x1d, 0x4e, 0xab, 0x62,
- 0x3c, 0x6f, 0xb6, 0xb7, 0xe3, 0x9a, 0x6b, 0x72, 0x8c, 0xc9, 0x87, 0xcf,
- 0x95, 0x38, 0x3f, 0xdb, 0x29, 0x39, 0xa1, 0xf9, 0x0c, 0x83, 0xe5, 0x9b,
- 0x2b, 0xdc, 0x2f, 0x13, 0xe7, 0x15, 0x5f, 0x37, 0x93, 0xb7, 0xf8, 0xdd,
- 0x0b, 0xbf, 0x97, 0xa3, 0x2f, 0x31, 0x26, 0x07, 0x71, 0x7e, 0x97, 0xe1,
- 0x53, 0x2d, 0x99, 0xef, 0x62, 0xf1, 0x77, 0x00, 0xe7, 0x12, 0x82, 0x8c,
- 0x51, 0x46, 0x29, 0x53, 0x38, 0xbf, 0x71, 0x5b, 0xde, 0x1d, 0xa0, 0x3c,
- 0x0f, 0xc8, 0x95, 0x8a, 0x3c, 0xe7, 0x20, 0xcf, 0x94, 0xe5, 0x1c, 0x64,
- 0xda, 0xf0, 0xf5, 0x7e, 0x7e, 0x67, 0x1d, 0x83, 0xbd, 0x52, 0x1f, 0xe2,
- 0x25, 0xf0, 0xb5, 0xed, 0x7d, 0x2b, 0x15, 0xd0, 0x1c, 0x4e, 0x76, 0xb6,
- 0xc1, 0xfb, 0x0e, 0x00, 0xd7, 0x57, 0x9e, 0x93, 0xf4, 0x6c, 0x33, 0xbf,
- 0xe7, 0xea, 0xe2, 0x99, 0x65, 0xaf, 0xf0, 0xdf, 0xe7, 0x45, 0xe2, 0x4d,
- 0xe9, 0xcf, 0xf2, 0x9a, 0x71, 0xde, 0x26, 0x8c, 0x19, 0x04, 0x9d, 0x9b,
- 0x31, 0x3f, 0xf7, 0xb8, 0xda, 0x38, 0xde, 0x0f, 0x55, 0xe1, 0x53, 0x7d,
- 0x7a, 0xaf, 0xd5, 0x35, 0xb3, 0xfd, 0xcd, 0xde, 0xfb, 0xf1, 0x1c, 0x94,
- 0xef, 0xc1, 0xb7, 0xf4, 0x89, 0xc9, 0x2f, 0x29, 0x3d, 0x87, 0xb9, 0x02,
- 0xf9, 0x37, 0xa4, 0x39, 0x8c, 0x2c, 0x6c, 0xcb, 0x5e, 0x1d, 0x1f, 0x5b,
- 0x91, 0xef, 0xae, 0x80, 0xc6, 0xdd, 0xd9, 0xc2, 0x1a, 0xe9, 0x56, 0x1d,
- 0xd4, 0xe5, 0xf1, 0x36, 0xec, 0x85, 0x62, 0xb9, 0x0f, 0xc8, 0xf1, 0xd2,
- 0x20, 0xe8, 0x10, 0x93, 0xa7, 0xe0, 0x37, 0x3f, 0x53, 0xba, 0x43, 0x96,
- 0x23, 0xd8, 0x57, 0x45, 0xc6, 0x86, 0xe5, 0xfb, 0xf3, 0x09, 0xef, 0x3a,
- 0xe1, 0x2e, 0x5b, 0x3b, 0xb0, 0x07, 0xca, 0x13, 0xe5, 0x8a, 0xe3, 0x82,
- 0x88, 0x45, 0x38, 0xef, 0xd3, 0x46, 0xb7, 0x61, 0xde, 0x62, 0x84, 0xf2,
- 0xcb, 0xbd, 0x85, 0x3c, 0x99, 0x65, 0x5c, 0xc5, 0x77, 0x36, 0x36, 0x29,
- 0x53, 0x73, 0x16, 0x09, 0xc5, 0x81, 0xae, 0x9c, 0x81, 0x3f, 0x8f, 0x2f,
- 0x97, 0xfe, 0x77, 0x14, 0xd4, 0xa3, 0xb0, 0x95, 0x05, 0xd8, 0xca, 0x02,
- 0x6c, 0x24, 0x64, 0xe1, 0x5a, 0x01, 0x36, 0xb2, 0x00, 0x1b, 0x09, 0x7d,
- 0xf6, 0x3a, 0x62, 0xbb, 0xd7, 0xc0, 0x43, 0xc6, 0xd7, 0x3e, 0x4a, 0x5f,
- 0x1b, 0x7f, 0xff, 0x03, 0x4c, 0x03, 0x3a, 0xe1, 0xd4, 0x71, 0x00, 0x00,
- 0x00 };
-
-static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
- 0x08004590, 0x08004590, 0x08004508, 0x08004540, 0x08004574, 0x08004598,
- 0x08004598, 0x08004598, 0x08004478, 0x00000000 };
-
-static struct fw_info bnx2_rxp_fw_06 = {
- /* Firmware version: 4.1.1 */
- .ver_major = 0x4,
- .ver_minor = 0x1,
- .ver_fix = 0x1,
-
- .start_addr = 0x080031d0,
-
- .text_addr = 0x08000000,
- .text_len = 0x71d0,
- .text_index = 0x0,
- .gz_text = bnx2_RXP_b06FwText,
- .gz_text_len = sizeof(bnx2_RXP_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_RXP_b06FwData,
-
- .sbss_addr = 0x08007220,
- .sbss_len = 0x58,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08007278,
- .bss_len = 0x44c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x080071d0,
- .rodata_len = 0x24,
- .rodata_index = 0x0,
- .rodata = bnx2_RXP_b06FwRodata,
-};
-
-/* Initialized Values for the RX Processor. */
-static const struct cpu_reg cpu_reg_rxp = {
- .mode = BNX2_RXP_CPU_MODE,
- .mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT,
- .mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA,
- .state = BNX2_RXP_CPU_STATE,
- .state_value_clear = 0xffffff,
- .gpr0 = BNX2_RXP_CPU_REG_FILE,
- .evmask = BNX2_RXP_CPU_EVENT_MASK,
- .pc = BNX2_RXP_CPU_PROGRAM_COUNTER,
- .inst = BNX2_RXP_CPU_INSTRUCTION,
- .bp = BNX2_RXP_CPU_HW_BREAKPOINT,
- .spad_base = BNX2_RXP_SCRATCH,
- .mips_view_base = 0x8000000,
-};
-
-static u8 bnx2_rv2p_proc1[] = {
- /* Date: 12/07/2007 15:02 */
- 0xd5, 0x56, 0x41, 0x6b, 0x13, 0x51, 0x10, 0x9e, 0xdd, 0x6c, 0xbb, 0xdb,
- 0x64, 0xb3, 0x59, 0xaa, 0xd6, 0x50, 0x53, 0x93, 0x06, 0x2f, 0xad, 0x29,
- 0x6d, 0xaa, 0x82, 0x42, 0xa1, 0x92, 0x4b, 0xc1, 0xf6, 0x20, 0xf5, 0x22,
- 0x22, 0xd8, 0x46, 0xd1, 0x5f, 0x21, 0x06, 0xdb, 0xd4, 0x73, 0x05, 0x0b,
- 0xf5, 0xa0, 0x3d, 0x59, 0x11, 0xc1, 0x04, 0x14, 0x44, 0x04, 0x41, 0x45,
- 0x04, 0x3d, 0x78, 0xa8, 0x60, 0x2f, 0xad, 0x22, 0x56, 0x3c, 0x78, 0xd4,
- 0x93, 0x26, 0xbe, 0x37, 0x33, 0xaf, 0xdd, 0xdd, 0x66, 0x9b, 0x2a, 0x82,
- 0x18, 0x68, 0x3f, 0xde, 0xec, 0xbc, 0x37, 0x33, 0xdf, 0xcc, 0x9b, 0x79,
- 0x2e, 0x00, 0xe8, 0x50, 0xaa, 0xa6, 0x05, 0x82, 0xa5, 0x69, 0x96, 0x00,
- 0x0d, 0xe0, 0xae, 0x8d, 0x58, 0xea, 0x77, 0x05, 0xda, 0xda, 0x70, 0x46,
- 0x62, 0x04, 0x86, 0xbb, 0x25, 0xee, 0x87, 0x27, 0x99, 0xa4, 0xc0, 0x9f,
- 0x75, 0x28, 0xc9, 0xf5, 0xee, 0xca, 0xc3, 0x6a, 0x0c, 0xcf, 0x59, 0xed,
- 0x07, 0xfc, 0xbd, 0x8b, 0x10, 0x1e, 0xce, 0x59, 0x88, 0x25, 0x46, 0xe8,
- 0x73, 0x11, 0x96, 0x66, 0x2d, 0x34, 0x57, 0xea, 0xb3, 0x70, 0x1f, 0xe8,
- 0x24, 0x5f, 0x99, 0x4d, 0x88, 0xff, 0x29, 0x78, 0x5f, 0x90, 0x6b, 0x2b,
- 0x3a, 0x8d, 0x7a, 0x15, 0xde, 0x2f, 0xfe, 0x50, 0xff, 0xb8, 0xd8, 0x07,
- 0xfc, 0x53, 0xfb, 0x5c, 0x3c, 0xa7, 0x98, 0x93, 0x7e, 0xb5, 0x0b, 0x83,
- 0xca, 0x1f, 0x9b, 0xe2, 0x4b, 0x93, 0xb6, 0x89, 0xdf, 0xd7, 0x84, 0xdf,
- 0xca, 0x6e, 0x33, 0x7b, 0x41, 0x7f, 0x83, 0x76, 0xe5, 0x79, 0x86, 0xb0,
- 0xe7, 0xb7, 0x03, 0x20, 0xe5, 0xcb, 0xf5, 0x75, 0x79, 0x8f, 0xff, 0xfb,
- 0x6a, 0xaf, 0x3c, 0xaf, 0x05, 0xa0, 0x57, 0xea, 0x2d, 0xb1, 0x3f, 0x83,
- 0xb0, 0x4f, 0x4f, 0xe2, 0x77, 0x03, 0xf7, 0xef, 0x11, 0xe7, 0x4a, 0xec,
- 0x62, 0xec, 0x66, 0x1c, 0x67, 0xbc, 0xca, 0xb8, 0x8b, 0x71, 0x27, 0xe3,
- 0x0e, 0xc6, 0x76, 0xc6, 0x97, 0x8c, 0x2e, 0x63, 0x82, 0xd1, 0x61, 0x7c,
- 0xce, 0x68, 0x33, 0xc6, 0x18, 0x5f, 0x30, 0xbe, 0x62, 0xb4, 0x18, 0x6f,
- 0x30, 0x7e, 0x61, 0xfc, 0xaa, 0xfc, 0xd0, 0x08, 0x1f, 0xf1, 0xfa, 0x10,
- 0xaf, 0x8f, 0x30, 0x02, 0xf3, 0xa4, 0x05, 0x78, 0xba, 0xcf, 0x75, 0x24,
- 0x79, 0xe6, 0xef, 0x3d, 0x4a, 0x8f, 0xf3, 0x84, 0x3c, 0xdd, 0x63, 0xbd,
- 0xf6, 0xca, 0x42, 0xa0, 0xde, 0x32, 0x5b, 0xd6, 0x59, 0xaa, 0x41, 0xde,
- 0x12, 0x18, 0xcf, 0xc4, 0x48, 0x02, 0xed, 0x38, 0xad, 0x24, 0x57, 0x6e,
- 0x9d, 0x4c, 0x10, 0x9e, 0x8b, 0x12, 0x7e, 0x62, 0x3c, 0x1f, 0x23, 0x9c,
- 0x8c, 0x2b, 0x9e, 0xd5, 0x39, 0xca, 0x9f, 0x66, 0x7e, 0x84, 0xd9, 0x53,
- 0x7e, 0x35, 0xb3, 0x4b, 0x58, 0xd4, 0xfd, 0xf1, 0x5f, 0x1f, 0x20, 0x34,
- 0xf2, 0x44, 0xea, 0x9c, 0xdd, 0x26, 0xa0, 0x5e, 0x9f, 0xb7, 0x0d, 0xb9,
- 0x3e, 0x38, 0xff, 0x1a, 0xef, 0xc7, 0xe0, 0x5c, 0x95, 0xfd, 0x4b, 0x28,
- 0x9e, 0xe9, 0xde, 0x64, 0x81, 0xd6, 0xe3, 0xc8, 0xbb, 0xa8, 0xb0, 0x1e,
- 0xee, 0x03, 0x59, 0x7f, 0xbe, 0xa8, 0x6e, 0x23, 0x9c, 0x8f, 0x8b, 0x9c,
- 0x8f, 0xae, 0x90, 0x7c, 0x84, 0xdd, 0xa3, 0xcd, 0xf7, 0xf7, 0x4c, 0x26,
- 0xc8, 0x5b, 0xd8, 0x7d, 0x53, 0x7c, 0x93, 0xf4, 0x77, 0x79, 0xbc, 0xc0,
- 0x3c, 0x16, 0x89, 0xc7, 0xe4, 0xe7, 0x86, 0x3c, 0x65, 0x3c, 0x3c, 0xc9,
- 0x38, 0xf7, 0x86, 0xe4, 0x39, 0x2c, 0xbe, 0xdc, 0x1f, 0xe7, 0x39, 0xe0,
- 0x1f, 0x9c, 0xc5, 0xfe, 0xe4, 0x42, 0x71, 0x44, 0xf9, 0xeb, 0xe7, 0xb9,
- 0x93, 0xf2, 0x0d, 0xd3, 0x79, 0x29, 0xaf, 0x03, 0x3c, 0xd5, 0x71, 0x6d,
- 0x14, 0x34, 0x09, 0x56, 0x31, 0x4f, 0xfb, 0x1d, 0x5d, 0xe7, 0xf5, 0x76,
- 0xeb, 0x42, 0xe5, 0x5d, 0x62, 0x2b, 0x14, 0x26, 0x39, 0xce, 0x2c, 0xd9,
- 0xa3, 0x3a, 0x30, 0xb8, 0x0e, 0x86, 0xb8, 0x7f, 0x05, 0xf9, 0xb0, 0x2a,
- 0x0b, 0xb3, 0xde, 0x7b, 0x9d, 0x84, 0x62, 0x9e, 0xea, 0x6a, 0x73, 0x5e,
- 0xd5, 0xdc, 0x51, 0x7d, 0x09, 0xc5, 0x95, 0x52, 0xc4, 0x17, 0xef, 0x51,
- 0xc8, 0x79, 0x79, 0xd6, 0x1a, 0xd4, 0x47, 0x33, 0x3b, 0xbe, 0xf3, 0x1c,
- 0xc8, 0x35, 0xea, 0x37, 0x26, 0xc7, 0xd5, 0xcd, 0xf5, 0xdd, 0xb1, 0xa9,
- 0xbe, 0xd5, 0x7c, 0xfb, 0x7b, 0x75, 0xce, 0xf1, 0x9b, 0xa8, 0x97, 0x5a,
- 0x79, 0xe0, 0x9d, 0x67, 0x51, 0xcf, 0x3c, 0xa3, 0x6d, 0xa6, 0xf2, 0x3b,
- 0xed, 0x9d, 0x43, 0xb1, 0x90, 0x3c, 0x78, 0xe7, 0x57, 0x30, 0x5e, 0x7f,
- 0x3d, 0x52, 0x5e, 0xa3, 0x1c, 0xbf, 0xd6, 0xa4, 0x2f, 0xb7, 0xb1, 0xde,
- 0x8f, 0x5a, 0xb8, 0x1e, 0x9d, 0x5b, 0xe8, 0xf1, 0xf6, 0xf1, 0xef, 0x35,
- 0x9a, 0x07, 0xdf, 0x6a, 0x8a, 0xdf, 0xc7, 0x21, 0xfc, 0x0e, 0xfd, 0x53,
- 0x7e, 0x21, 0xc0, 0xef, 0x6a, 0x6d, 0x7b, 0xfc, 0x02, 0xc7, 0x0f, 0x21,
- 0xfc, 0xb6, 0x32, 0x0f, 0x6f, 0xb7, 0xe0, 0x4d, 0xea, 0xc5, 0x58, 0xef,
- 0x8d, 0x47, 0x0f, 0xfd, 0x1e, 0xa2, 0x7b, 0x65, 0x16, 0xd7, 0x02, 0xbc,
- 0xe5, 0x73, 0xf2, 0x7e, 0x5f, 0x82, 0x2a, 0xc7, 0xbf, 0xec, 0xe3, 0x21,
- 0x2e, 0xfc, 0x73, 0xd1, 0xfe, 0xed, 0xaa, 0xe2, 0x8b, 0x3e, 0x67, 0x72,
- 0x84, 0x8b, 0xa8, 0xef, 0x7a, 0x78, 0xf3, 0xbe, 0xaf, 0x5c, 0xb8, 0x55,
- 0x55, 0xfd, 0x4c, 0xf6, 0x15, 0x13, 0x06, 0x78, 0x4e, 0x4e, 0x70, 0xff,
- 0xfa, 0x10, 0xa5, 0x3e, 0x59, 0x1c, 0xc5, 0x3e, 0x03, 0x1d, 0xeb, 0xfd,
- 0x8c, 0xd6, 0x9d, 0x71, 0x7a, 0x47, 0x0e, 0x98, 0x36, 0xea, 0x75, 0xc6,
- 0x09, 0x3b, 0x62, 0x72, 0x5f, 0x12, 0x3e, 0x8e, 0xa1, 0x7a, 0x6e, 0xa3,
- 0x3f, 0x05, 0xfb, 0x12, 0xc7, 0x79, 0x40, 0xca, 0x3b, 0x02, 0xfd, 0x48,
- 0xe8, 0xf4, 0x92, 0x7f, 0x37, 0x81, 0xe3, 0x52, 0xfb, 0xd2, 0x92, 0xc7,
- 0xc5, 0x9a, 0xea, 0xe3, 0xd9, 0x11, 0xe9, 0x4f, 0x02, 0x1c, 0x93, 0xf2,
- 0x48, 0x28, 0xf4, 0x74, 0x53, 0x6e, 0x4b, 0x95, 0x75, 0x5a, 0x97, 0x2f,
- 0xe3, 0x31, 0x63, 0x65, 0x25, 0x2f, 0x60, 0x61, 0x8e, 0xdf, 0x79, 0x86,
- 0x72, 0xa7, 0x1a, 0x21, 0xb9, 0x39, 0xaa, 0xf8, 0x48, 0x60, 0x7c, 0x73,
- 0xc4, 0xc7, 0xe9, 0x6b, 0x84, 0xa7, 0xe0, 0x18, 0x62, 0x74, 0x63, 0x2e,
- 0x5b, 0x88, 0x10, 0xf7, 0xf6, 0xdf, 0x16, 0xe1, 0x1e, 0xf6, 0x4d, 0x4f,
- 0x7e, 0x82, 0x73, 0xb5, 0x59, 0x9e, 0xbc, 0x73, 0x5d, 0xe6, 0xa9, 0xd1,
- 0xfc, 0x8e, 0x73, 0x5d, 0x95, 0x9b, 0xd4, 0x9f, 0xea, 0x83, 0x25, 0xae,
- 0xfb, 0x46, 0xef, 0x1a, 0x89, 0x4e, 0xc8, 0xfc, 0x4f, 0xad, 0xfb, 0x95,
- 0x0e, 0x7d, 0x77, 0x91, 0xfe, 0xf6, 0xde, 0x5b, 0x6e, 0xc8, 0x1c, 0xfe,
- 0x1f, 0xde, 0x55, 0x5b, 0xbd, 0xa7, 0x1c, 0xe6, 0xf9, 0x04, 0xf3, 0x6c,
- 0x40, 0x4b, 0x04, 0x89, 0xb1, 0x8d, 0x29, 0x3c, 0x57, 0x2f, 0xd3, 0x58,
- 0xb7, 0x5b, 0x66, 0x70, 0xae, 0x3b, 0xf6, 0x0c, 0xe9, 0x19, 0x24, 0x4f,
- 0x2a, 0xbc, 0x32, 0x45, 0xef, 0x6c, 0x1d, 0x7e, 0x01, 0x50, 0xb6, 0x82,
- 0xa7, 0xd8, 0x0d, 0x00, 0x00, 0x00 };
-
-static u8 bnx2_rv2p_proc2[] = {
- /* Date: 12/07/2007 15:02 */
- 0xed, 0x59, 0x5d, 0x6c, 0x54, 0xc7, 0x15, 0x9e, 0xbd, 0xbb, 0x7b, 0xf7,
- 0x7a, 0x7d, 0xf7, 0xae, 0x71, 0xa8, 0xff, 0xf9, 0xb3, 0x09, 0xd8, 0xa9,
- 0x21, 0xce, 0x9a, 0x98, 0x02, 0x55, 0x63, 0x39, 0x95, 0x81, 0xa6, 0x55,
- 0x0c, 0x49, 0x9b, 0xbe, 0x35, 0x76, 0x02, 0xb6, 0xa9, 0x4d, 0x2d, 0x43,
- 0x83, 0x4a, 0x1b, 0x65, 0x85, 0xd7, 0xf6, 0xcb, 0x26, 0xea, 0x22, 0xc0,
- 0x24, 0xaa, 0xa8, 0x1b, 0xa4, 0x28, 0xea, 0xdb, 0x56, 0x6a, 0x6d, 0xda,
- 0x97, 0xfe, 0x10, 0xb7, 0x4a, 0xa4, 0x42, 0xa5, 0xf6, 0xa1, 0x52, 0x85,
- 0x44, 0xda, 0x62, 0x99, 0xc4, 0x20, 0x63, 0xba, 0x79, 0x21, 0x75, 0x67,
- 0xce, 0x77, 0xe6, 0xee, 0xbd, 0xeb, 0xb5, 0x21, 0x2d, 0x8f, 0xdd, 0x07,
- 0x1f, 0x66, 0xee, 0x99, 0x33, 0xe7, 0xe7, 0x9b, 0x33, 0x67, 0x0e, 0x65,
- 0x42, 0x08, 0x43, 0x24, 0xb3, 0x1b, 0x24, 0x15, 0x56, 0x20, 0x20, 0xf0,
- 0x7b, 0xac, 0x8c, 0xc8, 0x9f, 0xb3, 0x96, 0xfc, 0x1b, 0x16, 0xcf, 0x1b,
- 0x55, 0x34, 0x0e, 0x09, 0x45, 0x1d, 0x21, 0x92, 0x5e, 0x5a, 0xce, 0xf4,
- 0x67, 0x4c, 0x77, 0x1b, 0xa0, 0x3d, 0x4c, 0xeb, 0x98, 0x9e, 0x64, 0xba,
- 0x91, 0xe9, 0x56, 0xa6, 0x27, 0x98, 0x7e, 0x8f, 0xe9, 0x07, 0x4c, 0x77,
- 0xb2, 0x3c, 0xf9, 0x4b, 0xda, 0xf2, 0x4f, 0x40, 0x24, 0x9b, 0xb4, 0x7e,
- 0x36, 0xa6, 0x9b, 0xa0, 0xe7, 0x73, 0x1b, 0x15, 0xdf, 0xcd, 0xa5, 0x3c,
- 0x1f, 0xe6, 0xaf, 0x65, 0x40, 0x37, 0x60, 0xd5, 0x4f, 0x93, 0x8f, 0xeb,
- 0xf5, 0x20, 0xdd, 0x31, 0xd0, 0x9e, 0x20, 0x68, 0x7b, 0x33, 0x91, 0xf4,
- 0x4b, 0x06, 0xc6, 0x9d, 0x5b, 0x2c, 0xb2, 0x2f, 0x64, 0x28, 0x39, 0xeb,
- 0x2d, 0xf3, 0x12, 0xe6, 0xbf, 0x19, 0x07, 0x7d, 0x39, 0x0a, 0xfa, 0x4f,
- 0xa6, 0x87, 0x4b, 0x59, 0xbe, 0xcd, 0x6a, 0x97, 0x62, 0xfd, 0x8c, 0xad,
- 0x68, 0x50, 0x24, 0x79, 0x9d, 0x10, 0xd0, 0xeb, 0xc7, 0x02, 0xdf, 0xd7,
- 0x6c, 0xc5, 0xec, 0x0f, 0x0f, 0x63, 0x5c, 0x7b, 0xb1, 0x8c, 0xf8, 0xcf,
- 0x67, 0xb5, 0xfe, 0x16, 0x79, 0x3f, 0x19, 0x87, 0x1c, 0x51, 0x6f, 0xd1,
- 0x26, 0xc9, 0x66, 0x50, 0xb1, 0x4d, 0xcb, 0xc3, 0xef, 0xdc, 0xa3, 0xda,
- 0x3f, 0x18, 0xaf, 0x4d, 0x80, 0x9e, 0x65, 0x5a, 0xd1, 0x4a, 0x64, 0xfb,
- 0xdf, 0x9f, 0xb0, 0x48, 0x97, 0xe4, 0x36, 0xaf, 0x1f, 0x7f, 0x23, 0xfd,
- 0xc8, 0x82, 0x1a, 0x40, 0x6e, 0x3c, 0xaa, 0xf8, 0xa4, 0x71, 0xf5, 0x90,
- 0x7b, 0xb0, 0xbf, 0x98, 0xff, 0x7f, 0xf9, 0x19, 0xfc, 0xaf, 0xe4, 0xb5,
- 0xb3, 0xfe, 0x1b, 0xa5, 0xfe, 0x8a, 0xd6, 0x05, 0x92, 0xdb, 0xfc, 0xfe,
- 0xb9, 0x96, 0x89, 0xd3, 0xbf, 0x6f, 0x76, 0x94, 0x91, 0xfd, 0xcf, 0x62,
- 0xfe, 0x74, 0xe7, 0x14, 0xfc, 0xb4, 0x9f, 0xe2, 0x22, 0xa2, 0xa9, 0x9f,
- 0x63, 0x55, 0x77, 0x4c, 0x8d, 0x5f, 0xd8, 0x71, 0x23, 0x8b, 0xef, 0xe1,
- 0x11, 0x35, 0x36, 0xe4, 0x3a, 0xfc, 0xf6, 0x07, 0x09, 0xe0, 0x69, 0x73,
- 0x84, 0x86, 0xf6, 0x0c, 0x7d, 0xb7, 0xc5, 0x78, 0x16, 0xdf, 0x8f, 0x96,
- 0xaa, 0xf1, 0xb3, 0xcd, 0x73, 0x18, 0x37, 0xf7, 0x8f, 0xf1, 0x42, 0xa3,
- 0x44, 0xfe, 0x59, 0x5a, 0xba, 0x69, 0x40, 0x1e, 0x87, 0x37, 0x1a, 0x32,
- 0xe2, 0x64, 0xaf, 0xdd, 0x09, 0x3a, 0x4a, 0xdf, 0xef, 0x05, 0xd2, 0x64,
- 0x77, 0xa7, 0x13, 0x9a, 0x02, 0x23, 0xe3, 0xca, 0xc5, 0x8d, 0xc6, 0xdd,
- 0x83, 0xe2, 0x67, 0xcc, 0xc5, 0x0f, 0xfb, 0xbf, 0x69, 0x25, 0xfc, 0x80,
- 0x76, 0x6e, 0x01, 0x35, 0x1b, 0x14, 0x5f, 0xb8, 0x08, 0x8e, 0xfc, 0x7e,
- 0xe6, 0xf8, 0x14, 0xe2, 0x44, 0xe2, 0x03, 0x63, 0xc6, 0x8b, 0xc4, 0x95,
- 0xe2, 0xaf, 0x96, 0xfe, 0xd2, 0xf1, 0x57, 0x82, 0x22, 0xe2, 0xdb, 0x2c,
- 0xaf, 0x9f, 0xed, 0x1a, 0x60, 0x7b, 0xe6, 0xa3, 0xda, 0xaf, 0xda, 0x1e,
- 0xd0, 0x71, 0x9f, 0x3d, 0x01, 0x89, 0x27, 0x8d, 0x23, 0x9f, 0x3e, 0xe9,
- 0xf7, 0xea, 0xf1, 0x8f, 0x5a, 0xc6, 0xa1, 0x6b, 0xe7, 0x16, 0xc5, 0x67,
- 0x26, 0x26, 0xb2, 0x7e, 0x1c, 0x6e, 0x10, 0x5a, 0x8e, 0x96, 0xaf, 0x70,
- 0x99, 0x93, 0xb8, 0x44, 0xdc, 0xce, 0x67, 0xbd, 0xe7, 0xa8, 0xa6, 0xc8,
- 0x39, 0xf2, 0x9f, 0x07, 0xed, 0x97, 0xa3, 0x31, 0x4a, 0x10, 0x3b, 0xae,
- 0xcc, 0xfa, 0xf7, 0x03, 0xbe, 0x23, 0x2e, 0x7e, 0xd6, 0xb6, 0xb1, 0xff,
- 0x98, 0x56, 0xec, 0x54, 0xf2, 0xba, 0x58, 0x7e, 0x0b, 0xcb, 0xb7, 0x0b,
- 0xce, 0xdb, 0x73, 0xee, 0x79, 0xd3, 0x71, 0xcb, 0x9f, 0x3b, 0xed, 0x3f,
- 0xda, 0xbf, 0xf9, 0xca, 0xac, 0x5a, 0x5f, 0x7b, 0x9f, 0x73, 0xb8, 0xbf,
- 0xc8, 0x39, 0x84, 0x9c, 0xbf, 0x3c, 0xee, 0xb7, 0x6b, 0x88, 0xf3, 0x5c,
- 0x0f, 0xe2, 0x66, 0xbd, 0xf4, 0x2b, 0xfe, 0xf0, 0x18, 0xe1, 0x5d, 0xbc,
- 0x18, 0x41, 0x7c, 0x1d, 0xd2, 0x5f, 0xb0, 0x1d, 0x2f, 0x7b, 0xce, 0x6b,
- 0x09, 0xf9, 0xb5, 0xc3, 0xc4, 0x7e, 0x1d, 0xdd, 0x58, 0xde, 0xce, 0x78,
- 0xc8, 0xf1, 0x79, 0x99, 0xb5, 0x49, 0xff, 0xe8, 0x9d, 0x53, 0x98, 0x1f,
- 0xdd, 0x43, 0x24, 0x7d, 0xd5, 0xd0, 0xf6, 0x86, 0xd4, 0xdf, 0xc9, 0x41,
- 0x7c, 0x9f, 0x0c, 0xf1, 0xf9, 0x7c, 0xaf, 0x9e, 0xd6, 0x5b, 0xf3, 0x19,
- 0xac, 0xcf, 0xb1, 0x7e, 0x27, 0x82, 0xc4, 0x1f, 0x1d, 0x63, 0xbe, 0xf1,
- 0x11, 0xbf, 0x9d, 0x3f, 0x40, 0x3e, 0xb7, 0xbf, 0x3f, 0x42, 0xe7, 0xdd,
- 0x31, 0x5d, 0x3e, 0xa2, 0xce, 0xe8, 0x29, 0xc5, 0x5f, 0x29, 0xc6, 0xb2,
- 0x4a, 0xd1, 0x2a, 0xd1, 0xbd, 0x17, 0xeb, 0xde, 0x30, 0x91, 0x6f, 0x7a,
- 0xf7, 0x82, 0x7e, 0x88, 0xf9, 0xf5, 0xce, 0xb8, 0xe2, 0x5f, 0x53, 0xe3,
- 0x4c, 0x29, 0x1a, 0x97, 0xf6, 0x28, 0xfb, 0xa5, 0xed, 0x8c, 0xcf, 0xc1,
- 0x46, 0xf0, 0xf7, 0x1d, 0xa2, 0x8d, 0xcf, 0x0c, 0xe4, 0x28, 0x5f, 0x4d,
- 0x0e, 0x5f, 0x52, 0x7e, 0xa9, 0x16, 0xb3, 0xc7, 0x14, 0x0d, 0x89, 0x8e,
- 0x4d, 0xec, 0x97, 0x3d, 0xfe, 0xfc, 0x3c, 0xbf, 0x53, 0x8d, 0x6b, 0x24,
- 0x9f, 0x17, 0xbf, 0x16, 0xc7, 0x39, 0xe4, 0xfa, 0xf5, 0x13, 0x03, 0x76,
- 0xa7, 0x48, 0xff, 0x3d, 0xd1, 0x14, 0x9d, 0xeb, 0x98, 0xe8, 0x25, 0x3c,
- 0x85, 0xac, 0xc1, 0x4b, 0xf8, 0x3e, 0xff, 0x0b, 0x2d, 0x57, 0xe1, 0x61,
- 0x17, 0xdf, 0x9f, 0xc2, 0x95, 0x13, 0xda, 0xc9, 0x71, 0xd0, 0xfb, 0xb6,
- 0xe2, 0xbe, 0xe9, 0x08, 0xa8, 0xf1, 0x3a, 0x39, 0xb6, 0x29, 0x6e, 0x1d,
- 0xdd, 0x6a, 0xbd, 0x4c, 0x02, 0x74, 0x7e, 0x1c, 0x29, 0x5f, 0xcd, 0x47,
- 0xa4, 0x1d, 0xfe, 0x7d, 0x06, 0x11, 0x0f, 0xfb, 0x28, 0xf9, 0xe7, 0xf3,
- 0xf6, 0xad, 0x8c, 0xb6, 0x07, 0xf3, 0xb7, 0x5d, 0x7d, 0x6c, 0xb2, 0xab,
- 0x63, 0x13, 0xf6, 0x9b, 0x75, 0x78, 0x9f, 0x4d, 0xbc, 0xef, 0x31, 0xb5,
- 0x5f, 0x83, 0x47, 0x5f, 0xc5, 0x67, 0x45, 0x6f, 0x91, 0xdc, 0x75, 0xd6,
- 0x77, 0x2e, 0x91, 0x7f, 0xad, 0xa3, 0x53, 0xd8, 0xff, 0xf6, 0xd4, 0x6a,
- 0x7a, 0xd7, 0xb0, 0x9c, 0x75, 0xec, 0xd7, 0xd8, 0x43, 0x8c, 0xdb, 0xea,
- 0x71, 0xca, 0xfb, 0x57, 0xfb, 0x87, 0xe4, 0xdb, 0x0b, 0xd3, 0xab, 0xe9,
- 0x2b, 0x6d, 0x4a, 0x82, 0x3f, 0x65, 0xd0, 0xc1, 0xa8, 0x82, 0x5f, 0xf2,
- 0x71, 0xd3, 0xfa, 0xce, 0x1f, 0xc2, 0x7d, 0x34, 0xe8, 0xe6, 0x0b, 0x25,
- 0xb7, 0x9d, 0xf1, 0x20, 0xe5, 0x05, 0xe0, 0x9f, 0x85, 0x69, 0x9c, 0x9b,
- 0x13, 0x74, 0x3e, 0xbe, 0x68, 0x87, 0x68, 0xff, 0xa8, 0x75, 0x83, 0xef,
- 0xa5, 0xfc, 0xfd, 0x03, 0x79, 0x7d, 0x36, 0x68, 0x2f, 0xe7, 0xe9, 0x1b,
- 0x4c, 0x53, 0xb6, 0x5a, 0x57, 0x2a, 0xf3, 0xad, 0x45, 0xf2, 0x91, 0x57,
- 0x4b, 0x5c, 0x7d, 0x8f, 0xb0, 0x9c, 0x8f, 0x98, 0x0a, 0x96, 0x33, 0xc0,
- 0xeb, 0xe7, 0x7c, 0x72, 0x0c, 0x8f, 0x1c, 0x7f, 0x3e, 0x1a, 0xe3, 0x7b,
- 0xef, 0xbc, 0xb9, 0x52, 0xbd, 0xa4, 0x68, 0xb9, 0x5c, 0x8f, 0x59, 0x7d,
- 0x2f, 0xa4, 0x1a, 0x89, 0xb4, 0x85, 0x0c, 0xb2, 0x77, 0x32, 0x35, 0x02,
- 0x3f, 0x8d, 0xb3, 0x9f, 0x22, 0xf0, 0x53, 0x4d, 0xfe, 0x9e, 0xe4, 0x8d,
- 0xf8, 0xfc, 0xcd, 0x6c, 0xf6, 0x9f, 0xc7, 0xf3, 0xa6, 0x8e, 0x2f, 0x91,
- 0x34, 0xf2, 0x90, 0xbe, 0x3f, 0xf5, 0xbd, 0x72, 0x4b, 0xe7, 0x6d, 0xb9,
- 0x6f, 0x81, 0x3e, 0x41, 0x8a, 0x73, 0x74, 0x9c, 0xf3, 0xd1, 0xd5, 0xa0,
- 0x8e, 0x27, 0xf4, 0x1b, 0xff, 0x8c, 0xfa, 0xe5, 0xef, 0xe5, 0xb0, 0x22,
- 0xcd, 0xb3, 0xc7, 0x88, 0xb6, 0xf4, 0x1d, 0xc7, 0x7c, 0x65, 0xab, 0xd2,
- 0xe7, 0x27, 0x01, 0x9c, 0xd3, 0xb0, 0x98, 0xc9, 0xe0, 0x9e, 0x13, 0x11,
- 0xd2, 0xa3, 0xee, 0x32, 0xe1, 0xc2, 0x8c, 0xa6, 0x32, 0x3e, 0x7f, 0x79,
- 0xec, 0x2e, 0x66, 0xef, 0x84, 0xc4, 0x93, 0xfa, 0x6e, 0xf2, 0x79, 0x95,
- 0x78, 0xb5, 0xf9, 0xbc, 0x3c, 0x4d, 0x7c, 0xf6, 0x22, 0xd9, 0xf9, 0x0d,
- 0x6b, 0x9c, 0xeb, 0xb4, 0x8f, 0x3b, 0xd5, 0xf8, 0x79, 0xfb, 0x75, 0x9c,
- 0x77, 0xfb, 0x75, 0xe4, 0x5b, 0x2b, 0x7c, 0x11, 0x79, 0xb8, 0xf3, 0xa2,
- 0x6f, 0xff, 0x74, 0xc8, 0xd0, 0xe7, 0xe7, 0x7f, 0xf2, 0x9b, 0xfd, 0x5d,
- 0xf6, 0xdb, 0xdd, 0xd5, 0xe3, 0x9a, 0x36, 0xf9, 0x1c, 0xf6, 0xdd, 0x2d,
- 0xb4, 0x57, 0xf9, 0xef, 0x43, 0xf7, 0x1e, 0x0e, 0xed, 0x62, 0x7d, 0x76,
- 0x71, 0x1e, 0xe0, 0xfa, 0x67, 0x7d, 0x50, 0xdf, 0x8b, 0x1a, 0x0f, 0x7c,
- 0x3f, 0x02, 0xa7, 0xd6, 0x28, 0xec, 0x15, 0xaf, 0xf2, 0x39, 0xf8, 0x37,
- 0xd3, 0xd7, 0x18, 0xff, 0x27, 0xb9, 0x3e, 0xd2, 0xf5, 0xdd, 0x3d, 0xcc,
- 0x3b, 0x13, 0x6e, 0x3d, 0xa4, 0xef, 0x1f, 0x35, 0x0e, 0x08, 0x27, 0x52,
- 0x4a, 0xfb, 0x25, 0x7f, 0x07, 0x80, 0x8d, 0x3f, 0x0d, 0x3f, 0xce, 0xb6,
- 0x82, 0xef, 0x0d, 0xf8, 0xc7, 0xd1, 0xfa, 0x2d, 0x36, 0xfa, 0xde, 0x01,
- 0x6d, 0xf0, 0xaf, 0xe9, 0xfa, 0x57, 0xe3, 0x73, 0x89, 0x69, 0xed, 0x66,
- 0xb6, 0xf3, 0xbf, 0xf3, 0xbb, 0xa7, 0x1e, 0x5b, 0xc9, 0xef, 0xb4, 0xbe,
- 0xad, 0xef, 0x2e, 0xe6, 0xcb, 0x76, 0x83, 0x66, 0x76, 0xd3, 0xfc, 0x66,
- 0xe4, 0xdb, 0x70, 0xdb, 0xe9, 0xfb, 0xd4, 0xa7, 0xfa, 0x5d, 0x53, 0xf9,
- 0x25, 0xd0, 0x33, 0x4c, 0x3f, 0xf7, 0x14, 0xe8, 0xb9, 0xa7, 0xfc, 0x79,
- 0xc4, 0x8c, 0xfb, 0xe2, 0xdb, 0x86, 0xf8, 0xbe, 0xe3, 0xc6, 0x77, 0x3d,
- 0xea, 0x03, 0x19, 0xaf, 0x55, 0xe3, 0xe9, 0xc6, 0xe9, 0x7e, 0xf1, 0x7c,
- 0xd8, 0x71, 0x4c, 0xed, 0xc2, 0x3d, 0x37, 0xcc, 0xef, 0xcd, 0x45, 0xf7,
- 0x9e, 0x2a, 0x16, 0xdf, 0xc8, 0xff, 0xe3, 0x4b, 0xf1, 0x3d, 0xb2, 0xa4,
- 0xf3, 0x1f, 0xee, 0x79, 0x5d, 0xd7, 0x0f, 0x79, 0xea, 0x7a, 0xff, 0xbe,
- 0xdf, 0xa2, 0x7a, 0x79, 0x34, 0xe0, 0xe2, 0x82, 0xf8, 0xa7, 0x79, 0x5d,
- 0x19, 0xaf, 0xdb, 0xb7, 0x6c, 0xdd, 0xb5, 0x8c, 0x5a, 0xf7, 0xb7, 0x4f,
- 0x97, 0xf7, 0x25, 0x7c, 0x7a, 0x26, 0x45, 0x1c, 0xf1, 0xc1, 0x7d, 0x61,
- 0x16, 0xe9, 0x63, 0xf8, 0x71, 0xb7, 0x37, 0x8e, 0x7c, 0xa8, 0xdf, 0x79,
- 0xfe, 0xba, 0xfe, 0x8f, 0x9f, 0xae, 0x5c, 0xd7, 0x6b, 0x79, 0x88, 0x5f,
- 0xb7, 0x11, 0x23, 0xbe, 0xeb, 0x43, 0x6a, 0x5d, 0xbf, 0x6b, 0x5f, 0x3b,
- 0xd9, 0x75, 0x99, 0xed, 0xab, 0x63, 0xfb, 0xe4, 0xe7, 0x6d, 0x74, 0x9f,
- 0x58, 0xd7, 0x87, 0xbc, 0xf6, 0xfd, 0x7a, 0x95, 0xfd, 0x1e, 0xf4, 0x1d,
- 0xc1, 0xfb, 0xc6, 0xf5, 0xfe, 0x4a, 0x5e, 0x2d, 0xd7, 0x63, 0x8e, 0xe0,
- 0xe7, 0x54, 0x91, 0xba, 0x46, 0xed, 0xff, 0x7b, 0xe9, 0x00, 0xbe, 0xc7,
- 0xe8, 0x1d, 0x11, 0xb4, 0x2e, 0x67, 0x8a, 0xf9, 0xe5, 0x6b, 0x01, 0xf0,
- 0x15, 0x8b, 0x9b, 0xfa, 0x1e, 0x66, 0x39, 0xc5, 0xec, 0x66, 0x3d, 0x5d,
- 0x3c, 0xf0, 0x3a, 0xe2, 0xeb, 0x63, 0xbe, 0x50, 0x91, 0xbe, 0x04, 0x46,
- 0xb9, 0xad, 0x54, 0x2f, 0x5e, 0x38, 0x39, 0xad, 0xf8, 0x62, 0xee, 0xbb,
- 0xcc, 0xaf, 0xdf, 0xc4, 0x43, 0xf0, 0x23, 0xbd, 0x3f, 0x44, 0xaf, 0xb3,
- 0x92, 0xbf, 0xf0, 0x7e, 0x5a, 0x98, 0xd6, 0xfe, 0xb6, 0xc9, 0x4e, 0xd4,
- 0xd3, 0x17, 0x0a, 0xfc, 0x68, 0x78, 0xfc, 0x08, 0xfe, 0x95, 0x71, 0xef,
- 0x7f, 0x97, 0x03, 0x17, 0xaf, 0x16, 0xc1, 0x3d, 0xf5, 0xf7, 0x1e, 0xd8,
- 0xce, 0x03, 0xad, 0x5e, 0xbb, 0x1a, 0xc4, 0x4c, 0x16, 0xf8, 0xef, 0x62,
- 0x9c, 0xbc, 0xc8, 0x79, 0xf6, 0x7a, 0x54, 0x4d, 0x58, 0xa2, 0xe7, 0x19,
- 0xe4, 0xe9, 0x8a, 0x52, 0xd8, 0xdd, 0xf3, 0x55, 0xed, 0x27, 0xcc, 0xd7,
- 0xc4, 0x50, 0x57, 0x77, 0x45, 0xf0, 0xbe, 0xa8, 0x89, 0x81, 0x56, 0x70,
- 0x9e, 0x9e, 0x71, 0xfb, 0x29, 0xa0, 0xf9, 0xfa, 0x12, 0x7d, 0xa5, 0xdf,
- 0x9a, 0xa8, 0xc3, 0x45, 0x13, 0xd7, 0xcf, 0x94, 0xef, 0x82, 0xe2, 0x60,
- 0x13, 0x70, 0x22, 0xea, 0xfd, 0x79, 0x8a, 0xf3, 0xec, 0xb2, 0x7a, 0x0d,
- 0x7d, 0x99, 0x12, 0x4f, 0x5f, 0x42, 0xef, 0xa7, 0xfd, 0xa8, 0xe5, 0xd2,
- 0x70, 0x85, 0xba, 0x72, 0x91, 0xf3, 0xd8, 0x23, 0xe2, 0x0f, 0x59, 0xd8,
- 0x35, 0x93, 0x2d, 0xc4, 0x95, 0xde, 0x4f, 0xcb, 0x83, 0xde, 0xda, 0x8e,
- 0xbc, 0x7c, 0xec, 0x7f, 0x88, 0xf5, 0xfc, 0x07, 0xf5, 0x33, 0x2b, 0xd8,
- 0x1e, 0x25, 0x17, 0xf3, 0xfb, 0xb8, 0x4f, 0x94, 0x74, 0xc7, 0xfe, 0xfe,
- 0x4e, 0x17, 0xe9, 0xb5, 0x86, 0x71, 0x54, 0xe1, 0xc1, 0x39, 0xf8, 0xd7,
- 0xb6, 0x80, 0x9e, 0x6d, 0xd1, 0x71, 0xd0, 0xf1, 0xd2, 0xf1, 0x41, 0x1c,
- 0x2b, 0xd0, 0x4f, 0xda, 0xd1, 0xf3, 0x04, 0xdd, 0x0f, 0x2d, 0x3d, 0x0b,
- 0xfa, 0xdc, 0x61, 0xfd, 0x81, 0x66, 0xc5, 0xff, 0x9a, 0xf8, 0x13, 0xf7,
- 0x1b, 0xfe, 0xca, 0xb4, 0xb0, 0x6f, 0x82, 0xbe, 0x8b, 0x8c, 0x5b, 0x98,
- 0x03, 0xd2, 0xaa, 0xf3, 0xac, 0xf7, 0x9d, 0xa0, 0xcf, 0xdf, 0xd6, 0x65,
- 0x78, 0xcd, 0xe7, 0x4b, 0x6d, 0x9f, 0xe2, 0x6f, 0x66, 0x1c, 0xca, 0xf7,
- 0xe9, 0x5e, 0xa5, 0x47, 0x5c, 0xde, 0xdb, 0xc8, 0xc7, 0x4e, 0xc4, 0x1b,
- 0x27, 0x89, 0x87, 0x92, 0x88, 0x1a, 0xd6, 0x95, 0x97, 0x90, 0x1d, 0xa7,
- 0xdf, 0xff, 0x80, 0x3e, 0xbf, 0x3d, 0x51, 0x8a, 0xf9, 0xca, 0x67, 0xe2,
- 0xe4, 0x87, 0x73, 0xc0, 0xf1, 0x8f, 0xce, 0x82, 0xbe, 0x25, 0xbe, 0x82,
- 0xf5, 0xe5, 0xa7, 0xe8, 0xfe, 0xb7, 0x2a, 0x19, 0x97, 0x55, 0x38, 0xf7,
- 0x69, 0xd4, 0x0f, 0x4b, 0x4b, 0x22, 0x86, 0xba, 0x4d, 0xdf, 0x03, 0xc0,
- 0x65, 0xc8, 0x13, 0xdf, 0xfb, 0xe1, 0x54, 0x51, 0xbb, 0xf0, 0x9d, 0x64,
- 0x15, 0xe2, 0x55, 0xfb, 0xa3, 0xca, 0x28, 0x8a, 0xcf, 0x36, 0x3f, 0x3e,
- 0x4d, 0xc6, 0xe7, 0x5d, 0xb7, 0x8e, 0x5a, 0x2e, 0x97, 0xde, 0x89, 0x12,
- 0xb7, 0x0f, 0x0b, 0xaf, 0xa0, 0xfb, 0x1a, 0xd4, 0xfe, 0x95, 0xcb, 0xf2,
- 0xeb, 0x06, 0x5f, 0x9c, 0x6f, 0xde, 0xd3, 0x7a, 0x9d, 0x32, 0xbd, 0xdf,
- 0x5b, 0xdc, 0x7b, 0x66, 0x98, 0xfb, 0xfc, 0x39, 0xf4, 0xa3, 0x12, 0xf3,
- 0x69, 0x1a, 0xda, 0xd5, 0xef, 0x52, 0xdf, 0x22, 0x31, 0xcc, 0xf9, 0xf3,
- 0xfd, 0xa0, 0xae, 0xb7, 0x30, 0xbe, 0xc2, 0x79, 0xe3, 0x0e, 0xeb, 0x75,
- 0x80, 0x61, 0x39, 0xdf, 0x48, 0x79, 0x37, 0xa1, 0xeb, 0xb4, 0x61, 0x7e,
- 0x5f, 0xe8, 0x3e, 0xd5, 0x97, 0x83, 0x9c, 0x4f, 0xc9, 0x8f, 0xa1, 0xc4,
- 0xed, 0x29, 0xdd, 0x4f, 0xd0, 0xfd, 0x05, 0xd6, 0x07, 0xfd, 0x30, 0x71,
- 0x30, 0x02, 0x2a, 0x9a, 0xfc, 0xf1, 0x11, 0xae, 0x9d, 0x18, 0x99, 0x05,
- 0xfd, 0x86, 0x08, 0xf7, 0x09, 0x27, 0x58, 0xbf, 0x33, 0xfc, 0xbe, 0x73,
- 0xc8, 0x4f, 0x65, 0xd2, 0x7e, 0xea, 0x5b, 0x25, 0x8e, 0x4d, 0xc3, 0xae,
- 0x01, 0xf7, 0xfd, 0x06, 0x3e, 0xa6, 0xce, 0x9b, 0xdc, 0x2f, 0xe3, 0xbe,
- 0x9a, 0x63, 0x8e, 0xc0, 0x9e, 0x81, 0x1c, 0xc6, 0x8b, 0x78, 0x17, 0x39,
- 0xff, 0xe2, 0x3a, 0xef, 0xf8, 0x49, 0xfd, 0x1e, 0x2c, 0xbe, 0x4e, 0xd7,
- 0x85, 0x83, 0xf4, 0x2e, 0x79, 0x61, 0x92, 0xfb, 0xea, 0xa2, 0x9f, 0xea,
- 0xd1, 0xaf, 0xdb, 0x39, 0x1e, 0xe7, 0xfb, 0x07, 0xfe, 0xbe, 0x81, 0xae,
- 0xbf, 0xe7, 0xd0, 0xff, 0x9c, 0xcc, 0xa5, 0x81, 0x97, 0x64, 0x89, 0x17,
- 0xe7, 0x25, 0x89, 0x4a, 0x8e, 0xdb, 0xda, 0x27, 0x41, 0xcf, 0x3e, 0x89,
- 0x77, 0xf2, 0xc0, 0x2b, 0xec, 0x97, 0x1d, 0x14, 0xa7, 0xed, 0xe8, 0xbf,
- 0x78, 0xeb, 0x50, 0x85, 0x9b, 0x4f, 0x5c, 0x3c, 0xcf, 0x91, 0x5e, 0xb5,
- 0x93, 0x39, 0xe2, 0xab, 0x11, 0x8f, 0xd0, 0xbd, 0x57, 0xed, 0x2c, 0x40,
- 0xcf, 0xc4, 0x04, 0xdb, 0x37, 0xf4, 0x05, 0xd0, 0x57, 0x38, 0xce, 0x3a,
- 0x7e, 0x57, 0xdd, 0x3e, 0x1e, 0xf4, 0xd5, 0xf7, 0xf1, 0xf2, 0xf7, 0x3b,
- 0xc6, 0xd5, 0xad, 0x48, 0x60, 0x7d, 0xc7, 0x8b, 0xf7, 0xa7, 0xfc, 0x78,
- 0x50, 0x78, 0xd1, 0xb8, 0xf4, 0xe2, 0xa8, 0xf0, 0x9c, 0xe5, 0x71, 0xe1,
- 0x34, 0x55, 0x91, 0xbf, 0x70, 0x9f, 0x98, 0x89, 0x89, 0xcc, 0xea, 0x7e,
- 0x7a, 0x13, 0x7e, 0x4a, 0xb0, 0xde, 0x76, 0xff, 0x08, 0xee, 0xa1, 0x31,
- 0x8e, 0xd3, 0x5c, 0x23, 0xd7, 0x11, 0xac, 0xdf, 0xc7, 0xfc, 0xce, 0x40,
- 0x3c, 0x23, 0xf6, 0xe1, 0x69, 0x8e, 0x1f, 0xe3, 0xea, 0x08, 0xdb, 0xfd,
- 0x11, 0xec, 0xb6, 0xb5, 0xdd, 0xfd, 0xae, 0xdd, 0xba, 0x4e, 0xf1, 0xca,
- 0x29, 0x97, 0xb8, 0xa0, 0x7a, 0xc7, 0xbe, 0x4a, 0x79, 0x24, 0xcc, 0x76,
- 0x4a, 0xbe, 0x56, 0xfd, 0xff, 0x8e, 0xf0, 0x57, 0xef, 0x76, 0xef, 0xba,
- 0x52, 0x5e, 0x17, 0x95, 0xeb, 0x30, 0x8f, 0xf3, 0x67, 0xaf, 0xe0, 0x4f,
- 0xe5, 0x37, 0x2d, 0xb7, 0xf0, 0x7c, 0x79, 0xfd, 0x47, 0x95, 0x1d, 0xfd,
- 0x90, 0x57, 0x64, 0x9c, 0xe8, 0x1e, 0xb2, 0xdd, 0xbc, 0x72, 0x87, 0xea,
- 0xc0, 0xe8, 0x85, 0x41, 0xe4, 0x81, 0x0b, 0x83, 0xef, 0x72, 0x1d, 0xce,
- 0x7e, 0xe9, 0xa2, 0xff, 0xaf, 0x92, 0xb1, 0xab, 0xf7, 0xe7, 0x15, 0xbf,
- 0x1e, 0xb5, 0x1e, 0x3d, 0xf4, 0xbe, 0xff, 0x01, 0xfe, 0xf0, 0x11, 0xdc,
- 0xa0, 0x1d, 0x00, 0x00, 0x00 };
-
-static u8 bnx2_TPAT_b06FwText[] = {
- 0xbd, 0x59, 0x6f, 0x70, 0x5c, 0xd5, 0x7d, 0x3d, 0x6f, 0xf7, 0xed, 0xee,
- 0x93, 0xb4, 0x92, 0x9e, 0x90, 0x0c, 0xab, 0x56, 0x8d, 0xf6, 0x59, 0x6f,
- 0xa5, 0xc5, 0xab, 0xd8, 0x6f, 0x2d, 0xb9, 0xac, 0x87, 0x37, 0xcd, 0xb3,
- 0x2c, 0x29, 0x8b, 0xec, 0xd8, 0xeb, 0x42, 0x66, 0xe4, 0x09, 0x1d, 0x0b,
- 0x59, 0xd8, 0xc2, 0x18, 0xa2, 0x12, 0x3e, 0xa8, 0x13, 0x4f, 0xbd, 0xe8,
- 0x9f, 0x85, 0xbd, 0xd2, 0x23, 0x02, 0x2c, 0x3b, 0x93, 0x0e, 0x1e, 0xf9,
- 0x8f, 0x18, 0x58, 0x6b, 0xa1, 0xfd, 0x92, 0x69, 0xc3, 0x44, 0x13, 0x1b,
- 0xec, 0x90, 0x38, 0x4e, 0xa7, 0x5f, 0xcc, 0xb4, 0x9d, 0xaa, 0x80, 0x29,
- 0x50, 0x70, 0xdc, 0xce, 0xa4, 0x63, 0x0a, 0xf5, 0xed, 0xb9, 0x6f, 0x57,
- 0x46, 0x38, 0x4e, 0x3f, 0xd6, 0x33, 0x8b, 0x76, 0xef, 0x7b, 0xf7, 0xde,
- 0xdf, 0xbd, 0xbf, 0x73, 0xce, 0xef, 0xdc, 0xcb, 0x6a, 0x1f, 0xca, 0x51,
- 0xfa, 0x57, 0xc9, 0x4f, 0xfb, 0x23, 0x43, 0x4f, 0x6f, 0x58, 0x6b, 0xad,
- 0x95, 0xbf, 0x95, 0x00, 0x54, 0xfc, 0x3f, 0xfe, 0xf3, 0x03, 0xfa, 0x72,
- 0x1c, 0xf2, 0x03, 0xcd, 0x67, 0x2f, 0xae, 0xee, 0x30, 0xa1, 0xf9, 0xed,
- 0x87, 0x5a, 0x76, 0x9b, 0x80, 0x93, 0x4f, 0x44, 0x37, 0xe3, 0x7f, 0x44,
- 0xb6, 0x4e, 0x85, 0x6c, 0xff, 0x23, 0xfb, 0x8b, 0x75, 0x6f, 0xdc, 0x67,
- 0x5c, 0x3f, 0xe1, 0x87, 0xa6, 0xdb, 0x93, 0x9a, 0xde, 0x0c, 0xad, 0x81,
- 0x7d, 0x7e, 0xd4, 0xb2, 0x2b, 0x88, 0xaa, 0xe5, 0xb1, 0x80, 0x93, 0x39,
- 0xc3, 0xda, 0x83, 0x84, 0x7e, 0x8e, 0x0b, 0x72, 0x38, 0xc7, 0x99, 0x3c,
- 0x70, 0x28, 0xa7, 0xe0, 0x2a, 0xc7, 0x1c, 0xcf, 0x6b, 0x58, 0xf2, 0x7b,
- 0xd3, 0xf5, 0x95, 0xd9, 0xc8, 0x98, 0x53, 0x07, 0x45, 0xc8, 0x44, 0xf6,
- 0x0f, 0x6c, 0x33, 0x7e, 0x08, 0xe1, 0xd4, 0x5c, 0x3b, 0x32, 0xab, 0xcf,
- 0x6a, 0xd8, 0xe9, 0x36, 0xf4, 0x69, 0x36, 0xf8, 0x8e, 0x82, 0xd4, 0x7d,
- 0x1a, 0x7a, 0x0b, 0x71, 0x64, 0x0b, 0x59, 0x38, 0x85, 0x31, 0x7e, 0x34,
- 0x84, 0xa6, 0x34, 0x6d, 0xdd, 0xd4, 0xdd, 0xf2, 0x1d, 0x84, 0xa7, 0xae,
- 0x8b, 0x6b, 0x49, 0x1d, 0x6f, 0x6f, 0x14, 0xa2, 0xd2, 0x46, 0xb6, 0xa2,
- 0x3d, 0x0b, 0xbf, 0x6d, 0x58, 0x5b, 0xfc, 0x0a, 0x3a, 0xbf, 0x6e, 0xc6,
- 0xa7, 0x94, 0x07, 0x1f, 0xf4, 0xd9, 0xd0, 0x14, 0x3b, 0xaa, 0x35, 0xe5,
- 0x1b, 0x30, 0x51, 0xd0, 0x71, 0xa8, 0x50, 0x87, 0xb1, 0x02, 0x0e, 0xf8,
- 0x37, 0x04, 0x31, 0xa7, 0xc3, 0xf9, 0x4e, 0xcb, 0x01, 0xec, 0xcb, 0x0d,
- 0x63, 0x77, 0x2e, 0x85, 0xc3, 0x05, 0x19, 0x63, 0x14, 0xa3, 0x05, 0x15,
- 0xc1, 0x29, 0x23, 0xf2, 0x73, 0xdc, 0xe9, 0x99, 0x10, 0x63, 0x56, 0x08,
- 0x23, 0x56, 0x1c, 0xe3, 0xae, 0x8f, 0xeb, 0x0c, 0x61, 0xd4, 0xbc, 0x21,
- 0x06, 0x2c, 0xc3, 0x1a, 0x87, 0x68, 0x3c, 0x6f, 0x19, 0x91, 0x4e, 0x3f,
- 0x9c, 0xef, 0x9b, 0x11, 0x8c, 0x33, 0xf6, 0x31, 0xaf, 0xdf, 0x18, 0x3a,
- 0x6f, 0xf5, 0x73, 0xd8, 0x4f, 0xc7, 0xc4, 0x57, 0xfb, 0x46, 0xc7, 0x91,
- 0x88, 0x4c, 0xc0, 0x87, 0xbe, 0xba, 0x56, 0xf6, 0x6b, 0x8a, 0x4e, 0xc0,
- 0x88, 0x73, 0x9c, 0x6c, 0xb0, 0xdd, 0xe1, 0x18, 0x59, 0xf6, 0x37, 0xa2,
- 0x67, 0x20, 0xc7, 0x6a, 0xe0, 0xef, 0x76, 0xf6, 0x57, 0xe0, 0xb3, 0x63,
- 0xd1, 0x11, 0xf6, 0x39, 0x67, 0xa9, 0x78, 0x93, 0x9f, 0x3e, 0xdd, 0x90,
- 0x99, 0x55, 0x42, 0x6c, 0x3f, 0x04, 0x3e, 0x37, 0x2b, 0x70, 0x22, 0x63,
- 0x61, 0x84, 0xeb, 0xd6, 0xd8, 0x36, 0xc9, 0xb6, 0x80, 0x69, 0x71, 0x7c,
- 0xe8, 0x9d, 0x85, 0x95, 0x98, 0x58, 0xce, 0xcd, 0xef, 0x6b, 0xe7, 0x18,
- 0x6e, 0x31, 0xa7, 0xf2, 0x9d, 0xcd, 0xee, 0x4d, 0xf1, 0x88, 0xba, 0xf2,
- 0xf9, 0xb0, 0xd2, 0xc1, 0x36, 0x47, 0x6d, 0xc0, 0x21, 0x17, 0x5a, 0xd0,
- 0xd4, 0x38, 0x8f, 0x86, 0xf7, 0x72, 0xc3, 0x4a, 0x77, 0xc1, 0x51, 0xba,
- 0xe6, 0x3b, 0x14, 0x67, 0x5e, 0x55, 0x3a, 0x67, 0x65, 0xdc, 0x42, 0x3c,
- 0x6b, 0x29, 0x8c, 0xf9, 0x07, 0x32, 0x5e, 0x27, 0xaa, 0xdc, 0x14, 0x6b,
- 0x62, 0x3e, 0x54, 0x98, 0xdd, 0xca, 0x96, 0x79, 0x21, 0xd2, 0xc9, 0xb4,
- 0xd2, 0x33, 0x0f, 0x2d, 0x6c, 0xdb, 0x5a, 0x6e, 0xea, 0x30, 0xb2, 0xab,
- 0x4c, 0x1c, 0x77, 0xa3, 0xb8, 0x64, 0xf9, 0x70, 0x62, 0x55, 0x19, 0x54,
- 0x53, 0xe1, 0x07, 0xe1, 0xcb, 0x16, 0xd4, 0x2a, 0x7e, 0xbf, 0xb6, 0x43,
- 0xc5, 0x58, 0x7b, 0x8f, 0xd2, 0xc9, 0x3e, 0x01, 0xe6, 0xf9, 0x74, 0x2e,
- 0x8d, 0x30, 0xb1, 0x53, 0x61, 0xc7, 0x22, 0x79, 0xee, 0xcd, 0xdb, 0x56,
- 0x2c, 0xfe, 0xb8, 0xc4, 0x63, 0x8d, 0x11, 0x91, 0x7b, 0x53, 0x69, 0xc7,
- 0xe2, 0x67, 0xb9, 0x0f, 0x7e, 0x53, 0xc5, 0xaf, 0xac, 0x00, 0x16, 0x77,
- 0x58, 0xcc, 0xa9, 0x8e, 0x20, 0xdb, 0xcf, 0x78, 0xed, 0xf2, 0x37, 0xf4,
- 0xae, 0xaf, 0xec, 0x43, 0x71, 0x0f, 0x46, 0xdd, 0x26, 0xc6, 0x5c, 0xdc,
- 0x83, 0xed, 0x5c, 0xef, 0xbf, 0x06, 0xe4, 0xd7, 0xaf, 0xdd, 0x6a, 0xdb,
- 0xc9, 0x38, 0x7d, 0xb6, 0xb9, 0xb8, 0xda, 0x5f, 0x0f, 0xd4, 0xb6, 0xe3,
- 0x30, 0x73, 0xdc, 0x99, 0xbc, 0x1b, 0x59, 0xef, 0x79, 0x9d, 0xbe, 0x65,
- 0xb6, 0x16, 0x7d, 0xab, 0xbc, 0x7d, 0xd3, 0xb7, 0xcd, 0x0a, 0xf1, 0x66,
- 0x32, 0x88, 0xb3, 0xe6, 0x48, 0xa4, 0x12, 0x59, 0xcb, 0xcf, 0x7c, 0x5f,
- 0xe0, 0xfc, 0xf9, 0xa4, 0x1f, 0x27, 0x93, 0x27, 0x90, 0xad, 0x01, 0xe6,
- 0x72, 0x92, 0x57, 0xc6, 0xe2, 0x05, 0xfe, 0xd7, 0x57, 0x90, 0xeb, 0xb3,
- 0xb8, 0x3e, 0x05, 0x67, 0x4c, 0x89, 0x69, 0x4b, 0x6b, 0x26, 0xbf, 0xf6,
- 0x71, 0x3f, 0xeb, 0xdb, 0xc3, 0xc4, 0x27, 0xf0, 0x6e, 0x6e, 0x00, 0x3b,
- 0x8b, 0xb1, 0xe0, 0x46, 0x8e, 0xc2, 0xd2, 0x96, 0xc6, 0x89, 0xe2, 0x6f,
- 0x72, 0x3c, 0xad, 0x75, 0xe4, 0x8c, 0x4c, 0x1a, 0x89, 0x8b, 0x1d, 0x8a,
- 0xec, 0x9f, 0xd6, 0xd6, 0xe4, 0x83, 0x88, 0xd6, 0x16, 0x9f, 0x57, 0xd8,
- 0x5b, 0xb5, 0xc7, 0xa7, 0x14, 0xec, 0x8d, 0xc9, 0x67, 0x5b, 0xb5, 0x96,
- 0x3c, 0xb4, 0x4a, 0x7b, 0x48, 0x3b, 0x3b, 0x65, 0xf4, 0xbd, 0xac, 0x24,
- 0xa2, 0x53, 0x5e, 0x9f, 0x21, 0xad, 0x35, 0x1f, 0xe2, 0x7a, 0xe2, 0xcc,
- 0x09, 0xb4, 0x2a, 0xfb, 0x69, 0xed, 0x57, 0x7c, 0x70, 0xd1, 0xeb, 0xf3,
- 0xb4, 0x16, 0xcf, 0xcb, 0x76, 0xc3, 0x8a, 0x2a, 0x21, 0xdc, 0x9b, 0xd4,
- 0xb0, 0xa6, 0x45, 0x34, 0x76, 0x25, 0x8d, 0xc5, 0x2e, 0x7f, 0x04, 0xc7,
- 0xc9, 0x05, 0xe2, 0xce, 0xf9, 0xc3, 0x96, 0x31, 0x74, 0x15, 0xfc, 0x88,
- 0xd6, 0x38, 0x38, 0xe2, 0x86, 0xf0, 0x33, 0xe2, 0xbf, 0xdb, 0xd2, 0x31,
- 0xe6, 0x1a, 0xf1, 0x5f, 0x20, 0x91, 0x3a, 0xc5, 0x9c, 0x2d, 0x91, 0x03,
- 0x47, 0x0a, 0x4d, 0xf1, 0x53, 0x30, 0x06, 0xbb, 0xc8, 0x01, 0xad, 0x5d,
- 0xc6, 0x00, 0x5d, 0xb5, 0xc9, 0x9d, 0x42, 0x03, 0x72, 0xe4, 0x43, 0x97,
- 0xc7, 0xab, 0x61, 0xa5, 0xb3, 0xf0, 0x4b, 0x6a, 0x6b, 0x37, 0xf1, 0x85,
- 0xea, 0x88, 0x19, 0x44, 0xaa, 0x36, 0x8a, 0xf3, 0xc4, 0x4a, 0xb6, 0xae,
- 0x8c, 0xb9, 0x94, 0xf9, 0x7c, 0x87, 0xcf, 0x7b, 0x94, 0xcd, 0xf3, 0x51,
- 0xfc, 0xcc, 0xfa, 0x42, 0x38, 0x75, 0x95, 0x6c, 0x0b, 0xac, 0x68, 0xd7,
- 0x70, 0xf5, 0x85, 0x72, 0x7c, 0xfc, 0x42, 0x18, 0x9f, 0xbd, 0x40, 0x7e,
- 0xbb, 0x68, 0x2f, 0x87, 0x10, 0xa9, 0x36, 0x21, 0x0a, 0x56, 0x2b, 0xde,
- 0xab, 0x89, 0x45, 0xaf, 0x40, 0x6a, 0xa3, 0xa3, 0xed, 0xce, 0x19, 0x43,
- 0x83, 0x48, 0x38, 0xe7, 0xbc, 0xbd, 0x70, 0xb4, 0xb5, 0xf9, 0xf3, 0x02,
- 0x3b, 0x8a, 0x7b, 0x11, 0xb4, 0x3b, 0xb5, 0xb7, 0x98, 0x9b, 0xcb, 0x5e,
- 0x6e, 0x3a, 0xb5, 0x75, 0xf9, 0xfb, 0xfd, 0x28, 0x2f, 0x3e, 0x53, 0xed,
- 0x8c, 0x36, 0x96, 0x33, 0x7a, 0x27, 0xb9, 0xbe, 0x01, 0xaf, 0x6f, 0x46,
- 0x4b, 0x70, 0xef, 0x97, 0x4a, 0xb9, 0xa9, 0xb4, 0x1f, 0xe2, 0x3e, 0x33,
- 0xf7, 0xde, 0x3e, 0x3e, 0xc4, 0x3d, 0x96, 0xf3, 0x0d, 0xdf, 0x36, 0xdf,
- 0x30, 0xe7, 0x7b, 0x79, 0xc5, 0x7c, 0x07, 0x56, 0xcc, 0x77, 0x60, 0xc5,
- 0x7c, 0x29, 0x72, 0xf5, 0x1f, 0xc4, 0x48, 0x5d, 0x71, 0x6c, 0xd5, 0x1e,
- 0xbc, 0x6d, 0xee, 0x41, 0xce, 0x7d, 0x54, 0x2c, 0x65, 0x8a, 0xe3, 0x54,
- 0xda, 0xfb, 0x57, 0xcc, 0xbd, 0x9f, 0x73, 0x2f, 0x8f, 0xa3, 0x53, 0x8b,
- 0x84, 0xd8, 0x66, 0x09, 0xa1, 0xda, 0xa6, 0xde, 0x89, 0xe6, 0x4c, 0x27,
- 0xb1, 0x53, 0x8e, 0xc4, 0xa2, 0x0f, 0xe6, 0x70, 0xbd, 0x3f, 0x80, 0xa5,
- 0x9a, 0x65, 0x6e, 0x54, 0x96, 0xfe, 0xbe, 0xa4, 0x80, 0x5a, 0xff, 0x6a,
- 0xae, 0x9a, 0x63, 0xc4, 0xf4, 0x01, 0x45, 0x88, 0x73, 0x1b, 0x13, 0x83,
- 0x7e, 0x24, 0xfa, 0xaa, 0x60, 0x12, 0x43, 0x81, 0x12, 0x17, 0x56, 0xf6,
- 0x79, 0xd9, 0xeb, 0x53, 0xf0, 0xfa, 0x08, 0xf1, 0xee, 0x86, 0x0f, 0xc5,
- 0x1b, 0x2d, 0x75, 0xf8, 0x29, 0x39, 0xf9, 0x5a, 0x61, 0x59, 0x57, 0xa4,
- 0x6e, 0xc0, 0x77, 0xce, 0x0a, 0x32, 0xa6, 0x91, 0x7d, 0xc1, 0xaf, 0xf4,
- 0x27, 0x60, 0x4c, 0xd9, 0xe6, 0xc7, 0x2b, 0x49, 0x3c, 0x52, 0x0e, 0xa3,
- 0xf7, 0xb0, 0x92, 0x4d, 0x57, 0xc0, 0x70, 0xd6, 0x28, 0xd9, 0x94, 0x06,
- 0xc9, 0x1b, 0xb5, 0xe9, 0xb4, 0x69, 0x64, 0xaf, 0xf2, 0x65, 0x75, 0xfa,
- 0x4e, 0x31, 0xa8, 0x1c, 0x23, 0x8c, 0x27, 0xdd, 0x0b, 0x58, 0x0c, 0x34,
- 0x50, 0x9f, 0xa5, 0x76, 0x72, 0xe0, 0x05, 0x8d, 0x35, 0x2d, 0x44, 0x22,
- 0xaa, 0x38, 0xe8, 0xfa, 0xce, 0x37, 0x42, 0x20, 0xd8, 0x16, 0xc0, 0x3b,
- 0xe6, 0xa8, 0x55, 0x8f, 0x4d, 0xb8, 0xdc, 0xca, 0x3d, 0x58, 0xa5, 0x22,
- 0x32, 0xb7, 0x72, 0xac, 0x08, 0xc7, 0xfa, 0xb3, 0x10, 0xaa, 0xea, 0xa0,
- 0x36, 0xab, 0xd8, 0xeb, 0x6a, 0x4a, 0x97, 0x2b, 0xb1, 0x6b, 0x46, 0x4e,
- 0xe1, 0x14, 0xb5, 0x82, 0x35, 0xec, 0x8c, 0xaa, 0x6c, 0x99, 0x0d, 0xa1,
- 0x7c, 0xe6, 0x13, 0xf1, 0x18, 0xb5, 0x2f, 0xbd, 0x41, 0x08, 0x33, 0x19,
- 0x82, 0xc6, 0x79, 0x86, 0xc9, 0xe7, 0xea, 0xb6, 0x5a, 0x5c, 0xfb, 0x3a,
- 0xb5, 0xe9, 0xdb, 0x21, 0xf8, 0x67, 0x42, 0x08, 0xce, 0x28, 0x78, 0xa7,
- 0x3d, 0x84, 0xfa, 0x39, 0xf9, 0x5b, 0x41, 0xa3, 0x79, 0x14, 0x07, 0x75,
- 0x3f, 0x63, 0xfc, 0x2b, 0xf4, 0xeb, 0x0d, 0x98, 0xa4, 0x36, 0x3f, 0xea,
- 0x6a, 0xa8, 0x3a, 0x4a, 0x2d, 0xb0, 0x85, 0x38, 0x49, 0xfc, 0x1f, 0x64,
- 0x8c, 0x32, 0xde, 0x0b, 0x56, 0x36, 0x1a, 0x42, 0x00, 0xc1, 0x39, 0x23,
- 0x3d, 0xc9, 0xe8, 0x52, 0x53, 0xaa, 0xb2, 0x7d, 0x96, 0xb5, 0xd7, 0x36,
- 0x7b, 0xeb, 0xfd, 0x42, 0x7c, 0x9a, 0x6c, 0xea, 0x5b, 0xa0, 0x06, 0x8f,
- 0xc4, 0x62, 0x99, 0x7e, 0x05, 0x58, 0x73, 0x96, 0x76, 0x64, 0xe6, 0xbf,
- 0x44, 0x98, 0xe3, 0x1c, 0xd9, 0x20, 0x30, 0x6e, 0x65, 0x23, 0x01, 0x18,
- 0x37, 0x86, 0x50, 0x87, 0x0f, 0x9e, 0x17, 0x42, 0xb4, 0x57, 0xe3, 0x1d,
- 0xcb, 0x18, 0x34, 0xfd, 0x02, 0x3f, 0x4e, 0x66, 0x87, 0x22, 0x30, 0x86,
- 0x7f, 0xad, 0x44, 0xf1, 0xf1, 0x94, 0x91, 0xbe, 0xa8, 0x04, 0x51, 0x39,
- 0x67, 0xea, 0x5b, 0x94, 0x30, 0xca, 0x17, 0xc2, 0x58, 0x7d, 0x36, 0x88,
- 0xc0, 0x4c, 0x18, 0xc1, 0x69, 0xf3, 0xe2, 0x2e, 0x78, 0xe3, 0x2c, 0x0e,
- 0xa1, 0x19, 0xd5, 0xb3, 0x66, 0xf4, 0x5f, 0x20, 0xb1, 0x1d, 0x86, 0xba,
- 0x10, 0x45, 0x7d, 0xc1, 0x44, 0x35, 0xf3, 0x7d, 0xf9, 0xac, 0xcc, 0xb3,
- 0x8e, 0xb0, 0xe9, 0xe3, 0xda, 0x1c, 0x65, 0xab, 0x57, 0x37, 0x3a, 0xf9,
- 0xe9, 0x56, 0x3a, 0xe6, 0xe5, 0x9e, 0x29, 0x28, 0xe3, 0xb3, 0x8b, 0xd6,
- 0x4d, 0xb1, 0x2f, 0x26, 0xeb, 0x44, 0x19, 0x02, 0x76, 0x8f, 0xf2, 0xc0,
- 0x3c, 0x8b, 0x90, 0xa7, 0xef, 0x65, 0x4a, 0xc0, 0x2e, 0x6a, 0xfb, 0x25,
- 0x6a, 0xfb, 0x89, 0x92, 0xb6, 0x57, 0x51, 0xdb, 0x17, 0xfe, 0x4f, 0x6d,
- 0x67, 0xbd, 0x9f, 0xf1, 0xe1, 0xbc, 0x19, 0xc2, 0x71, 0xab, 0x69, 0xb1,
- 0x1e, 0x21, 0x54, 0xb7, 0xe9, 0xa8, 0x5e, 0xb0, 0xf0, 0x1c, 0xf7, 0x16,
- 0x77, 0x15, 0xf5, 0xfd, 0x9b, 0x52, 0xf3, 0x4b, 0x5e, 0xed, 0x71, 0x77,
- 0x59, 0x13, 0xc2, 0xd4, 0x2a, 0x55, 0xe9, 0xa1, 0x9e, 0x3f, 0x90, 0xbc,
- 0x29, 0xe2, 0x31, 0x23, 0x4e, 0xce, 0xde, 0x38, 0x89, 0xa2, 0x46, 0xc4,
- 0xa8, 0x97, 0x4b, 0xb5, 0x71, 0x1c, 0x73, 0x65, 0x4d, 0xeb, 0x64, 0x4d,
- 0x53, 0x30, 0x12, 0x2b, 0x6a, 0xc4, 0xea, 0xbc, 0x6c, 0xd7, 0x51, 0x4f,
- 0x9d, 0x5c, 0xd7, 0x16, 0xc1, 0x31, 0x6a, 0xa4, 0x4b, 0x9f, 0xb3, 0x9d,
- 0xe3, 0x6d, 0x9b, 0x35, 0xb2, 0xdb, 0x99, 0x9f, 0xf3, 0xc4, 0xc5, 0x14,
- 0xab, 0xc3, 0x89, 0x1a, 0x6a, 0x67, 0x73, 0x08, 0x13, 0xd4, 0xcb, 0xf3,
- 0xf4, 0x10, 0x2f, 0xb1, 0xdf, 0xb8, 0x6b, 0x44, 0x5f, 0x22, 0xaf, 0xc7,
- 0x4b, 0x9a, 0xf9, 0x12, 0x7d, 0xc3, 0x38, 0xf3, 0xf4, 0x53, 0x3e, 0x7b,
- 0xcd, 0x35, 0x1c, 0xe9, 0x1f, 0xfc, 0x9e, 0x7f, 0x30, 0xe2, 0x7e, 0x45,
- 0x7a, 0x88, 0x08, 0xde, 0x68, 0x91, 0x58, 0x24, 0xc6, 0x6f, 0xe9, 0xa7,
- 0xaa, 0x7c, 0x6b, 0xf6, 0xba, 0xc8, 0xc7, 0xca, 0x55, 0xc9, 0xbf, 0xb1,
- 0xa4, 0xc4, 0x93, 0x10, 0x65, 0x76, 0x98, 0x5e, 0xcb, 0x8c, 0x7f, 0x84,
- 0x18, 0x71, 0x1b, 0xe1, 0xb3, 0x30, 0xfc, 0x67, 0xb7, 0xa8, 0x9e, 0x8f,
- 0x5d, 0x90, 0x7e, 0x8b, 0x79, 0x9a, 0x32, 0x7b, 0xa7, 0x94, 0x58, 0x66,
- 0x40, 0x91, 0xcf, 0x75, 0x94, 0x9f, 0x5d, 0x22, 0x77, 0x23, 0xe4, 0x6e,
- 0x1d, 0x5e, 0xbf, 0x8d, 0xbf, 0xd4, 0x55, 0xdf, 0x00, 0xf9, 0x9b, 0xad,
- 0x1b, 0xe9, 0xf7, 0x7f, 0x85, 0x7b, 0x87, 0x24, 0x7f, 0xd9, 0xe6, 0xc7,
- 0xb3, 0x49, 0xec, 0x2c, 0x83, 0x91, 0x79, 0x4c, 0xc9, 0x3a, 0xe4, 0x71,
- 0xaa, 0x4c, 0xc9, 0xd2, 0x31, 0x7d, 0xc9, 0xdf, 0x37, 0xf9, 0xb6, 0x9f,
- 0xfc, 0xed, 0xab, 0xbb, 0x9d, 0xbf, 0x47, 0x38, 0x86, 0x8a, 0x27, 0xdc,
- 0xe3, 0x98, 0x0b, 0x04, 0x11, 0x99, 0x09, 0x20, 0x34, 0xa3, 0xa2, 0x92,
- 0x5c, 0x09, 0xdb, 0xd9, 0x78, 0x08, 0x46, 0xfa, 0x35, 0x44, 0x90, 0x98,
- 0xd2, 0xf0, 0xe7, 0x2d, 0x01, 0x9c, 0x89, 0x19, 0x99, 0xfd, 0x4a, 0x84,
- 0x58, 0x1f, 0x61, 0x44, 0x46, 0x34, 0xea, 0x2b, 0xf2, 0x35, 0xd0, 0x1c,
- 0x84, 0x36, 0x23, 0xb9, 0x2e, 0x0e, 0xfa, 0xec, 0x6c, 0x54, 0x23, 0x46,
- 0x7f, 0x40, 0x6c, 0x5c, 0x99, 0x12, 0x62, 0x73, 0xbb, 0x79, 0xf1, 0x3d,
- 0xbf, 0x41, 0xdd, 0x53, 0x89, 0xd3, 0xe2, 0xf8, 0x15, 0x33, 0x1a, 0x82,
- 0x47, 0xbd, 0xf1, 0x6f, 0xbc, 0xce, 0x28, 0x3e, 0x75, 0x55, 0x65, 0x2b,
- 0x71, 0x40, 0x6e, 0x45, 0xe6, 0xa9, 0x7d, 0x87, 0x93, 0x46, 0x7a, 0x8b,
- 0xd2, 0xe4, 0x34, 0xf3, 0xbb, 0x2f, 0x19, 0x8b, 0xf6, 0xf3, 0x9d, 0xf7,
- 0x0b, 0x45, 0x0e, 0xd7, 0x9b, 0xbb, 0xf1, 0x17, 0xe4, 0x70, 0x95, 0xf9,
- 0x14, 0x9e, 0xf4, 0xf4, 0x88, 0x38, 0x98, 0x2e, 0x27, 0xb7, 0x1d, 0x65,
- 0x17, 0x71, 0xbf, 0x73, 0x9e, 0xba, 0x32, 0xd3, 0xee, 0x69, 0x51, 0xc8,
- 0xec, 0x54, 0x7a, 0xe7, 0xbb, 0x3d, 0x0f, 0xb5, 0x7d, 0xd6, 0x87, 0xd7,
- 0xad, 0x4d, 0xf4, 0x2b, 0x69, 0x65, 0xfb, 0xbc, 0xc4, 0x7c, 0x8f, 0xf2,
- 0x4d, 0xe2, 0x3f, 0x7a, 0x97, 0x8a, 0x39, 0x6b, 0x93, 0x12, 0xf4, 0xf0,
- 0x1f, 0x80, 0x93, 0x29, 0x62, 0xdf, 0x6f, 0xc7, 0xac, 0x73, 0x2b, 0xb0,
- 0xdf, 0x7d, 0x07, 0x5f, 0x23, 0xf5, 0x03, 0x45, 0x2d, 0xd7, 0x3b, 0x99,
- 0xaf, 0x67, 0x4a, 0x18, 0x7f, 0x92, 0xed, 0x81, 0x19, 0x68, 0xe5, 0xc4,
- 0x71, 0xcf, 0x54, 0x18, 0xd3, 0x1e, 0x56, 0x04, 0x5e, 0x65, 0x4d, 0xc8,
- 0x27, 0x0d, 0x6b, 0xbf, 0x62, 0xa4, 0xbb, 0x95, 0x44, 0x76, 0x4d, 0xa9,
- 0x1e, 0xde, 0xcb, 0x9a, 0x86, 0xbb, 0xa8, 0x0b, 0x16, 0xb4, 0x10, 0xf1,
- 0xfd, 0x6f, 0xac, 0x4f, 0xff, 0x51, 0xaa, 0x87, 0xc9, 0x7c, 0x39, 0xaa,
- 0x5b, 0xa8, 0xef, 0xc4, 0x73, 0x97, 0xc4, 0x33, 0x3d, 0xc4, 0x18, 0xeb,
- 0xff, 0x4e, 0xe2, 0x79, 0x75, 0x9b, 0x91, 0xed, 0xa4, 0x77, 0xf6, 0xad,
- 0x8f, 0x10, 0xab, 0x71, 0xfa, 0xd5, 0x31, 0x74, 0x70, 0xae, 0xf4, 0xac,
- 0x11, 0xe9, 0x20, 0x07, 0x54, 0xf6, 0x79, 0x89, 0x7d, 0x96, 0x6a, 0xa5,
- 0xaf, 0x0e, 0xe1, 0x59, 0xf6, 0x31, 0x93, 0x8e, 0xa7, 0x15, 0x92, 0x03,
- 0x13, 0x48, 0x64, 0x24, 0x07, 0x9c, 0x55, 0xad, 0xf4, 0xf8, 0x92, 0x03,
- 0xc4, 0xa0, 0x4b, 0x0c, 0x16, 0x79, 0x30, 0x28, 0x79, 0x50, 0x45, 0x0f,
- 0xb1, 0x40, 0x0f, 0x51, 0x61, 0x47, 0xc9, 0x01, 0xc9, 0x89, 0xa2, 0x8f,
- 0xe8, 0x2c, 0xf1, 0x60, 0x8b, 0x37, 0x9f, 0x4a, 0xed, 0x0b, 0xa3, 0x69,
- 0xda, 0xd0, 0x55, 0xe5, 0x3f, 0xc5, 0x2e, 0xd3, 0x5c, 0xdc, 0x4b, 0x2f,
- 0xf0, 0x59, 0x5b, 0x8c, 0x79, 0x0f, 0x63, 0xdd, 0x42, 0x79, 0x40, 0xe2,
- 0xbc, 0x7e, 0x3a, 0x8c, 0xea, 0x69, 0xc9, 0x83, 0xec, 0x24, 0xf5, 0x6f,
- 0xc8, 0xf2, 0xfd, 0x13, 0xf1, 0x1f, 0x25, 0x2e, 0x54, 0xa5, 0x8b, 0x63,
- 0x54, 0xcd, 0xe8, 0x68, 0x9d, 0x36, 0x06, 0x17, 0x70, 0x4d, 0xbc, 0x1a,
- 0x33, 0x33, 0x87, 0x98, 0xff, 0x3d, 0xc9, 0x18, 0xf7, 0x4a, 0xc7, 0xbd,
- 0xb7, 0xc6, 0xf0, 0x38, 0xe1, 0xf4, 0x5b, 0xe1, 0x92, 0xaf, 0xd6, 0xd0,
- 0xef, 0x02, 0x7b, 0x5c, 0x1a, 0x5b, 0xd3, 0xb7, 0x36, 0x88, 0xeb, 0x38,
- 0x49, 0xf4, 0x0f, 0xe8, 0x0e, 0xf3, 0x1f, 0xc2, 0xde, 0xd2, 0x3b, 0x45,
- 0xbf, 0xfd, 0xe3, 0xd2, 0x79, 0xf2, 0x17, 0xfe, 0xe2, 0xdf, 0xbf, 0x55,
- 0x97, 0xcf, 0x97, 0xfd, 0xc4, 0xe0, 0x66, 0x62, 0xb0, 0x9b, 0x39, 0xda,
- 0x6b, 0x91, 0xdf, 0xcc, 0x67, 0x56, 0x0d, 0x51, 0x0f, 0x9b, 0xfa, 0x2a,
- 0xa9, 0x6b, 0x87, 0xa9, 0x51, 0x3f, 0x37, 0xcb, 0xe9, 0xb7, 0x1d, 0xfa,
- 0xed, 0x0e, 0x6a, 0x68, 0x27, 0xf5, 0x53, 0x62, 0x2b, 0x4d, 0x1c, 0x69,
- 0x4a, 0x9a, 0x1e, 0x36, 0x90, 0xa4, 0xd7, 0xae, 0x5b, 0xf6, 0xda, 0x32,
- 0x4e, 0xe9, 0xaf, 0x8d, 0xb8, 0x2c, 0xb5, 0x4f, 0x32, 0x0f, 0x8b, 0x35,
- 0x9b, 0xa0, 0xda, 0x9b, 0x14, 0xd5, 0x96, 0xe7, 0x09, 0x15, 0xdf, 0xa5,
- 0xd6, 0x2e, 0xed, 0x90, 0xe7, 0x0a, 0xae, 0x8b, 0x6d, 0x11, 0x33, 0x16,
- 0x3d, 0x4e, 0x5c, 0x1d, 0xfb, 0x9d, 0x73, 0x46, 0x11, 0x6f, 0xa3, 0xae,
- 0x7a, 0xcb, 0x33, 0x4b, 0x7d, 0xd8, 0x74, 0x0b, 0x6f, 0x1a, 0x9e, 0x68,
- 0x89, 0x12, 0x8f, 0x12, 0x6b, 0x1a, 0xf2, 0x2f, 0x96, 0xe3, 0xd5, 0x17,
- 0xc3, 0x78, 0xe5, 0x45, 0x21, 0xc6, 0x93, 0xe0, 0x69, 0x46, 0x6a, 0xec,
- 0x46, 0xbc, 0xac, 0xc7, 0xa2, 0xcf, 0x7a, 0x9e, 0xd5, 0xa1, 0x67, 0x35,
- 0x06, 0x2f, 0xe0, 0x26, 0xf5, 0x4b, 0x72, 0x3a, 0x41, 0xbe, 0x15, 0xb1,
- 0xe8, 0x79, 0xdb, 0x1a, 0x0d, 0x57, 0x88, 0xbf, 0x6a, 0xe2, 0xef, 0x37,
- 0xd4, 0xdd, 0x6b, 0x25, 0xdd, 0x5d, 0x9b, 0x27, 0x1f, 0xdb, 0x42, 0xe8,
- 0x96, 0x6b, 0x21, 0x0e, 0x47, 0x6f, 0xe1, 0x50, 0x88, 0x0f, 0xb8, 0xe7,
- 0x17, 0x2c, 0x23, 0xbe, 0x99, 0x78, 0x9c, 0xb3, 0x0c, 0xa7, 0x83, 0xde,
- 0x75, 0xd4, 0xc3, 0x24, 0xf5, 0x37, 0x26, 0x71, 0x49, 0x1c, 0x32, 0x27,
- 0x87, 0xd9, 0xe7, 0x3c, 0xfb, 0x4c, 0x94, 0xbc, 0xeb, 0xdb, 0x48, 0xa4,
- 0xa5, 0x77, 0x8d, 0x12, 0x83, 0x87, 0x3d, 0xef, 0x2a, 0xbd, 0xaa, 0xf4,
- 0xa9, 0x32, 0xce, 0x76, 0x2f, 0xce, 0xae, 0x5b, 0x38, 0xa4, 0x86, 0xd5,
- 0x48, 0xfc, 0x7d, 0x03, 0x13, 0xcf, 0x57, 0xa1, 0xda, 0xbc, 0x07, 0x97,
- 0x33, 0xdf, 0x50, 0x23, 0x26, 0xf4, 0x7a, 0xbb, 0x88, 0xc7, 0x9d, 0x85,
- 0x14, 0x5c, 0xf7, 0x2d, 0xe1, 0xd6, 0x19, 0xce, 0x05, 0xcf, 0x7f, 0x0e,
- 0xb2, 0xd6, 0xdc, 0x14, 0xbe, 0x98, 0x71, 0xb1, 0x9f, 0x1e, 0xac, 0xc9,
- 0x5f, 0xf4, 0x72, 0x1b, 0xf3, 0xbf, 0x14, 0xa8, 0x2d, 0xae, 0x53, 0xa5,
- 0x7f, 0x1b, 0x23, 0xe7, 0xc6, 0xcd, 0xa2, 0x97, 0x8b, 0xe5, 0xaf, 0x06,
- 0xa4, 0xa6, 0xfb, 0xda, 0xe4, 0xb8, 0x69, 0x6a, 0xc8, 0xf2, 0xd8, 0x5f,
- 0xea, 0xf2, 0x18, 0x31, 0x38, 0x2a, 0x7d, 0x15, 0x7d, 0x09, 0xcf, 0xe5,
- 0x2b, 0x34, 0x75, 0xd8, 0x0f, 0x53, 0xb6, 0x39, 0xca, 0x03, 0x5c, 0x83,
- 0x66, 0x0e, 0x2b, 0x69, 0x9e, 0x3b, 0x0f, 0x11, 0x5f, 0xdd, 0xac, 0xc3,
- 0x57, 0xad, 0x66, 0x72, 0x98, 0xf5, 0x89, 0xb5, 0xf8, 0xb0, 0xb9, 0x7c,
- 0x7e, 0x93, 0x35, 0x99, 0x35, 0xcc, 0xad, 0x64, 0xfd, 0xee, 0x61, 0xcd,
- 0xe6, 0x28, 0xcc, 0xe9, 0x67, 0x31, 0xd1, 0xb8, 0xb6, 0xcd, 0x18, 0xdc,
- 0xe6, 0x0f, 0x21, 0x47, 0xbc, 0x1f, 0x63, 0x1d, 0x72, 0xb9, 0xa7, 0xd3,
- 0x05, 0x23, 0x95, 0xc5, 0x18, 0xb6, 0x71, 0x4f, 0x79, 0xde, 0x71, 0xfe,
- 0x2e, 0x56, 0x3c, 0x0f, 0xef, 0x65, 0x7d, 0x9b, 0x2c, 0x71, 0xfb, 0x43,
- 0x24, 0x2c, 0xc9, 0xed, 0x45, 0xd6, 0xb7, 0x49, 0x8f, 0xdb, 0x46, 0x4a,
- 0xf2, 0xb9, 0xac, 0x54, 0xd7, 0x3e, 0x82, 0xe4, 0xf0, 0xed, 0x35, 0x4d,
- 0xe2, 0xd9, 0x0e, 0x4a, 0x1f, 0xeb, 0xba, 0xb2, 0x26, 0xc9, 0x5a, 0xb4,
- 0x5c, 0x97, 0x34, 0x79, 0x77, 0x90, 0x69, 0x9c, 0x3a, 0x28, 0x7c, 0xc5,
- 0xfb, 0x87, 0x8b, 0xef, 0xfa, 0xc3, 0xa9, 0xd4, 0x7d, 0xc8, 0x44, 0xce,
- 0x6a, 0xd8, 0xe1, 0x36, 0xf4, 0x85, 0x6c, 0xf0, 0x1d, 0x05, 0xd6, 0x1f,
- 0x6b, 0xc8, 0xdc, 0x76, 0xff, 0xf0, 0x41, 0x4e, 0xd3, 0xaa, 0xa7, 0xee,
- 0x96, 0xef, 0xe0, 0x93, 0xdc, 0x1d, 0xef, 0x1f, 0xd2, 0xbf, 0xef, 0xfe,
- 0xe1, 0x59, 0xf2, 0x63, 0xa2, 0x78, 0xff, 0xe0, 0x7c, 0xa7, 0xc5, 0x8f,
- 0xb9, 0x3a, 0x1c, 0x78, 0xaf, 0x5d, 0xc5, 0xd5, 0x9c, 0x11, 0x79, 0x19,
- 0x07, 0x30, 0xe0, 0xdd, 0x35, 0xf0, 0xcc, 0x6f, 0x0f, 0xe1, 0xd7, 0xed,
- 0xf2, 0xae, 0x21, 0x25, 0xd7, 0x38, 0xc9, 0xe5, 0x43, 0xa3, 0xde, 0x6c,
- 0x61, 0x2d, 0xd8, 0xb7, 0x51, 0xc1, 0x03, 0xc9, 0x7b, 0x3c, 0x6c, 0x4f,
- 0x16, 0x8c, 0x74, 0x94, 0xcf, 0xd6, 0x4d, 0xc9, 0x1a, 0xf9, 0x30, 0xcf,
- 0x86, 0xd0, 0x1a, 0xed, 0x5e, 0x4d, 0xb8, 0x4d, 0x91, 0x0f, 0x15, 0xc3,
- 0x39, 0x09, 0x79, 0x1f, 0x90, 0xb8, 0xe8, 0x57, 0x8c, 0xc5, 0x77, 0xfd,
- 0x46, 0xaa, 0xde, 0xc3, 0xcc, 0xc3, 0x3c, 0xa7, 0xc9, 0xbf, 0xbd, 0xf2,
- 0x8c, 0x87, 0x6d, 0x1c, 0xf3, 0xd2, 0x46, 0x79, 0xee, 0xfc, 0x54, 0x64,
- 0x57, 0x19, 0xce, 0x92, 0xa2, 0x31, 0x37, 0xa0, 0x3e, 0x49, 0x0d, 0x7f,
- 0x98, 0x1a, 0x2e, 0xcf, 0x08, 0xbd, 0x3c, 0x23, 0x34, 0x2d, 0xc6, 0xfd,
- 0x46, 0xe6, 0x06, 0xf5, 0x8e, 0x63, 0xf6, 0xf5, 0x2a, 0x46, 0xef, 0x02,
- 0xf5, 0x7f, 0xbf, 0x52, 0x1c, 0x73, 0x4d, 0x69, 0xcc, 0x7b, 0xf3, 0x9a,
- 0xb2, 0xd9, 0x05, 0x75, 0x07, 0xd1, 0x3d, 0x16, 0xb5, 0xa3, 0x50, 0x4e,
- 0x8e, 0x99, 0x72, 0xcd, 0x8c, 0xad, 0x95, 0xb1, 0x29, 0xf8, 0xb0, 0x45,
- 0xbe, 0xdb, 0x2a, 0xe3, 0x70, 0x2a, 0xec, 0x14, 0xb5, 0xf7, 0xb9, 0x60,
- 0x49, 0xbf, 0x7c, 0xfd, 0xd6, 0x2a, 0x38, 0x75, 0xa8, 0x0e, 0x98, 0xb5,
- 0x18, 0xd7, 0x51, 0x19, 0x36, 0x9b, 0x91, 0xd3, 0x83, 0xe8, 0xb7, 0x7e,
- 0x2b, 0xa8, 0x93, 0x7c, 0x1f, 0x78, 0xec, 0x79, 0x9e, 0xd7, 0xcd, 0xeb,
- 0x88, 0x25, 0x9f, 0xc6, 0x19, 0x7d, 0x08, 0xe5, 0xac, 0xa5, 0xaf, 0x78,
- 0x7a, 0x62, 0x13, 0xcf, 0x0a, 0x31, 0x64, 0xcb, 0x5a, 0x77, 0xdb, 0xd8,
- 0xf2, 0xfe, 0xe1, 0x7d, 0x91, 0x2d, 0x8e, 0xe1, 0xec, 0xb1, 0x32, 0x8c,
- 0xeb, 0x4b, 0xdd, 0xdd, 0x47, 0xdd, 0xa5, 0xb7, 0xfc, 0x5a, 0x39, 0x75,
- 0x77, 0xb7, 0xf5, 0x6d, 0x3c, 0x46, 0x8e, 0x57, 0x98, 0x9f, 0x88, 0xc7,
- 0xeb, 0xe4, 0x98, 0xd4, 0xd7, 0xaa, 0x95, 0xe3, 0xff, 0x33, 0xc7, 0x94,
- 0x73, 0xc8, 0x7a, 0x78, 0x59, 0x48, 0x6f, 0x56, 0x61, 0x0f, 0x2b, 0xdb,
- 0xc8, 0xa9, 0x45, 0x96, 0xde, 0xef, 0x92, 0x4f, 0x4b, 0xcc, 0x4f, 0xe3,
- 0x1d, 0xf8, 0xd4, 0x48, 0x3e, 0xed, 0x5a, 0xc1, 0xa7, 0xe3, 0xe4, 0x53,
- 0x2f, 0xf9, 0xd4, 0xd2, 0xf6, 0x27, 0xd4, 0x15, 0x21, 0x82, 0x6d, 0x37,
- 0xc5, 0x9b, 0x9e, 0xff, 0x95, 0x9e, 0x37, 0xad, 0x74, 0xcd, 0x4b, 0x7d,
- 0xaa, 0xa4, 0x27, 0xee, 0xa1, 0x1f, 0x06, 0x06, 0xc8, 0xa7, 0xc7, 0x4d,
- 0xd1, 0xb8, 0x2f, 0x69, 0xa4, 0x16, 0xe9, 0x6b, 0x7a, 0xc8, 0xa9, 0xb7,
- 0xc8, 0xa9, 0xb1, 0x42, 0x51, 0xa7, 0x0e, 0x73, 0xdd, 0xf7, 0x53, 0xa7,
- 0x7a, 0x0a, 0x52, 0xdb, 0x1c, 0xe2, 0x3f, 0x84, 0x4f, 0xc9, 0xa9, 0xf9,
- 0xa4, 0xa7, 0x53, 0xd6, 0x6f, 0x90, 0x18, 0x3a, 0x2f, 0xf9, 0x44, 0x9d,
- 0x72, 0x0b, 0x4d, 0xd6, 0x79, 0xae, 0x69, 0xd2, 0x35, 0x6e, 0x74, 0x93,
- 0x53, 0x81, 0x76, 0xe3, 0xe2, 0x55, 0x62, 0x37, 0x14, 0x83, 0x1e, 0xb1,
- 0xe5, 0x9a, 0x58, 0x63, 0x59, 0x27, 0x8f, 0x13, 0xff, 0xdd, 0xd4, 0x8c,
- 0xde, 0x82, 0x8d, 0x43, 0x85, 0x95, 0x7b, 0xca, 0x3a, 0x74, 0xc7, 0x7d,
- 0x19, 0x0d, 0xdd, 0xb9, 0x9d, 0xf5, 0xea, 0x8e, 0xed, 0x92, 0xaf, 0x7a,
- 0x48, 0xf2, 0x75, 0xd4, 0xfd, 0x61, 0xe0, 0xce, 0xef, 0xc8, 0xfb, 0x33,
- 0x21, 0x4e, 0x5b, 0xf2, 0xfe, 0x41, 0xfa, 0x1e, 0xfa, 0x68, 0x4b, 0xde,
- 0xa1, 0x75, 0x44, 0x55, 0x18, 0x91, 0x47, 0xf1, 0xb9, 0xc8, 0xd6, 0x39,
- 0xf1, 0x80, 0x57, 0x23, 0x0d, 0xbd, 0x8f, 0xb5, 0x6e, 0xb1, 0x74, 0xce,
- 0x9b, 0xcb, 0x09, 0xf1, 0x16, 0xeb, 0xd4, 0x69, 0x9e, 0xe9, 0x46, 0xf2,
- 0x9f, 0x8b, 0xc5, 0x3a, 0x15, 0x63, 0xe6, 0xad, 0xfb, 0x48, 0x4f, 0xc7,
- 0x4e, 0xf2, 0xd9, 0x44, 0x7e, 0xb9, 0x46, 0x51, 0x33, 0x4d, 0x21, 0x76,
- 0x9b, 0xff, 0x2d, 0xfa, 0xbf, 0xf2, 0xae, 0x10, 0xd3, 0x8c, 0xe1, 0x8a,
- 0x85, 0x03, 0x01, 0xc4, 0xfa, 0x6e, 0xb0, 0xae, 0x5f, 0xda, 0x68, 0x64,
- 0xf2, 0x4a, 0xa2, 0x77, 0xab, 0x22, 0xbd, 0x9e, 0xaf, 0xb3, 0x8c, 0xef,
- 0xb4, 0xd0, 0x1b, 0x7d, 0xc8, 0x0c, 0x06, 0xf9, 0xfd, 0x4d, 0xcb, 0xa0,
- 0x7f, 0x16, 0xa2, 0x3f, 0x25, 0xc7, 0x10, 0xa2, 0xc3, 0x92, 0xe7, 0x80,
- 0x31, 0x9e, 0x03, 0xb2, 0xa2, 0xc2, 0xbc, 0x42, 0x6d, 0x32, 0x32, 0x63,
- 0x8a, 0xc9, 0xbe, 0x51, 0x78, 0x3a, 0xcb, 0x67, 0xda, 0x54, 0x04, 0x7f,
- 0xed, 0xf9, 0xe7, 0x28, 0x35, 0xab, 0x01, 0x7f, 0xe3, 0xe9, 0x96, 0x8a,
- 0x3d, 0xcf, 0x1b, 0x29, 0x55, 0x39, 0x88, 0xf7, 0x2d, 0x43, 0xff, 0x21,
- 0xe3, 0xa6, 0xd6, 0x3c, 0xb7, 0x19, 0x51, 0x70, 0x8e, 0x6c, 0x9f, 0xbf,
- 0x46, 0xd1, 0x58, 0x3b, 0xbe, 0xdf, 0x22, 0x6b, 0xf7, 0x10, 0xba, 0x9b,
- 0xf7, 0xf3, 0xa3, 0xa2, 0x76, 0x46, 0x55, 0x76, 0xd0, 0x93, 0x54, 0xcf,
- 0x54, 0x63, 0xef, 0x7a, 0x21, 0xd6, 0xae, 0x77, 0xc0, 0x33, 0x5f, 0xfc,
- 0x02, 0x6b, 0xd0, 0x89, 0x1a, 0x23, 0x0d, 0xfc, 0x04, 0x3b, 0xe9, 0x65,
- 0x53, 0x6d, 0x39, 0xe0, 0x1e, 0xb9, 0xc6, 0x9f, 0x60, 0xb3, 0xf4, 0xc0,
- 0x56, 0xb5, 0xf4, 0x5b, 0x1e, 0x7e, 0x8b, 0x77, 0x48, 0x4c, 0xf5, 0xd1,
- 0xac, 0x28, 0x37, 0x8d, 0xbe, 0x79, 0xd6, 0xdb, 0x4b, 0xb1, 0xbb, 0xf5,
- 0x6f, 0xcd, 0x4b, 0x0f, 0x6c, 0x46, 0xb7, 0x28, 0x82, 0xb9, 0x78, 0x86,
- 0xb9, 0x88, 0x39, 0x61, 0x5a, 0x86, 0x6a, 0x3b, 0xe6, 0x54, 0x2b, 0xc3,
- 0xca, 0x83, 0xe4, 0x43, 0x5f, 0xb0, 0x9c, 0x1e, 0xc2, 0xa1, 0x7f, 0xf0,
- 0xa1, 0xf2, 0xa8, 0xf4, 0x14, 0x21, 0x6a, 0x4d, 0x53, 0x2f, 0x4f, 0x17,
- 0xd8, 0x97, 0x94, 0xfe, 0x83, 0x58, 0x3f, 0x7a, 0x53, 0x6c, 0xa6, 0xc7,
- 0xdd, 0x5c, 0xf2, 0xb8, 0xbb, 0x66, 0xd3, 0xf4, 0xc0, 0x9a, 0x22, 0xef,
- 0xd3, 0x52, 0x6d, 0x3c, 0x94, 0x3e, 0x28, 0x7d, 0x88, 0x5c, 0x83, 0x8e,
- 0x6b, 0x49, 0x89, 0x5d, 0x1d, 0xa3, 0xed, 0x46, 0x24, 0x0b, 0x79, 0x7f,
- 0x73, 0xbb, 0xbf, 0x80, 0x9e, 0xfe, 0x1d, 0xcf, 0x01, 0x7d, 0x07, 0x63,
- 0x31, 0x82, 0x42, 0xd4, 0x26, 0xfd, 0xe8, 0xf3, 0xce, 0x73, 0x11, 0x3d,
- 0x4d, 0xde, 0x5f, 0xa4, 0x4f, 0xf0, 0xf3, 0xdc, 0x7c, 0x90, 0x58, 0xfa,
- 0xac, 0x65, 0xe4, 0x58, 0x3d, 0xb2, 0x93, 0xb5, 0x30, 0xac, 0xfb, 0xa9,
- 0xab, 0x57, 0x72, 0x0f, 0xb2, 0x9e, 0xfb, 0xda, 0x23, 0x3c, 0x03, 0x34,
- 0xce, 0x64, 0x45, 0x3d, 0xfd, 0xe0, 0x37, 0x78, 0xee, 0xad, 0x69, 0x8b,
- 0xd3, 0x6f, 0x2f, 0xef, 0x95, 0x0f, 0x4f, 0x59, 0x26, 0x1c, 0xef, 0x77,
- 0x58, 0xef, 0x9a, 0xbd, 0x29, 0xe6, 0xcc, 0xbb, 0xf5, 0x8e, 0x62, 0x5c,
- 0x6a, 0x99, 0x6d, 0xa1, 0x65, 0x03, 0xcf, 0x8e, 0x77, 0x88, 0xa9, 0x47,
- 0x7a, 0x9f, 0x40, 0xb1, 0xdf, 0x9f, 0xce, 0x36, 0xe8, 0xdb, 0x59, 0xef,
- 0x16, 0x89, 0x95, 0x5d, 0xeb, 0x2d, 0x19, 0xcb, 0xa2, 0x8c, 0x85, 0xfe,
- 0xd2, 0xb9, 0xdf, 0x47, 0x5f, 0x92, 0x04, 0xaa, 0xcf, 0x3e, 0x45, 0x5e,
- 0xf9, 0x5a, 0xab, 0x91, 0x1d, 0x62, 0x8c, 0xc7, 0xfe, 0x91, 0x5b, 0x33,
- 0x30, 0x8d, 0x01, 0x1f, 0xfb, 0x4c, 0x59, 0xc0, 0x13, 0x0b, 0x3c, 0x97,
- 0x4e, 0xc7, 0xe8, 0xcb, 0xe9, 0x23, 0x17, 0x34, 0x3c, 0x3a, 0x5b, 0x8e,
- 0xef, 0xcd, 0x86, 0xb1, 0x6f, 0xd6, 0xbb, 0xd7, 0xda, 0x5a, 0xcb, 0xf7,
- 0x3a, 0x92, 0x42, 0xcc, 0x5b, 0xeb, 0xf1, 0x1e, 0x3d, 0xd4, 0x6a, 0xc5,
- 0x87, 0xc8, 0x51, 0xe8, 0x3a, 0x71, 0x53, 0xd3, 0xf2, 0x3d, 0x26, 0x58,
- 0x08, 0x73, 0xbd, 0xd4, 0xc9, 0x67, 0xbc, 0xef, 0x63, 0xf4, 0x8f, 0x19,
- 0x89, 0x41, 0x97, 0x18, 0x74, 0x89, 0xc9, 0x5b, 0x9e, 0x5a, 0x62, 0x39,
- 0x4e, 0x1f, 0xfd, 0xb4, 0x28, 0x62, 0xe3, 0x0b, 0x71, 0xda, 0x7c, 0x95,
- 0xfc, 0x55, 0xa9, 0xa1, 0xc0, 0xdf, 0xe7, 0x22, 0xfa, 0x8e, 0x82, 0xcc,
- 0xff, 0x5f, 0x96, 0xf2, 0xbf, 0x18, 0x2a, 0xea, 0x85, 0xe1, 0xcc, 0xa3,
- 0x01, 0xd3, 0x6e, 0x83, 0xbe, 0xd5, 0x1d, 0x19, 0xd6, 0x90, 0x8d, 0x56,
- 0xc3, 0x18, 0x9c, 0x86, 0xaf, 0x35, 0x0c, 0xb9, 0x76, 0x20, 0xef, 0xad,
- 0x51, 0x88, 0x09, 0xea, 0x9b, 0xcc, 0xc1, 0xbf, 0xe7, 0xd0, 0xea, 0x63,
- 0x3e, 0x1c, 0xc6, 0xbe, 0x8f, 0x7b, 0xf0, 0x71, 0x5e, 0xde, 0x73, 0xc6,
- 0xd2, 0x5d, 0xb8, 0xee, 0x8d, 0xf9, 0x51, 0x3e, 0x85, 0x23, 0xee, 0x25,
- 0x71, 0xa4, 0xae, 0xa8, 0xf1, 0x69, 0x9e, 0x8f, 0xaa, 0x8f, 0x96, 0xbc,
- 0x10, 0x39, 0x5c, 0xc9, 0xf5, 0x5e, 0x4b, 0x7a, 0xde, 0x9f, 0x35, 0x72,
- 0x50, 0x3b, 0x6d, 0x6e, 0xe4, 0xda, 0x6e, 0x8a, 0x89, 0x58, 0xb3, 0x56,
- 0x8c, 0x29, 0xa1, 0x9f, 0x42, 0x19, 0xb1, 0x2b, 0xcf, 0x48, 0x52, 0x3f,
- 0xe4, 0x6f, 0x9e, 0x4f, 0x54, 0x27, 0xe2, 0xe7, 0xba, 0x9c, 0x87, 0x64,
- 0x5b, 0xa8, 0xe4, 0x57, 0x97, 0xbd, 0x48, 0x07, 0x9f, 0x49, 0x2f, 0xf2,
- 0xb9, 0xe8, 0xab, 0xeb, 0xb8, 0xa5, 0x39, 0x59, 0xbe, 0x31, 0xee, 0xca,
- 0xfb, 0xab, 0x16, 0x3a, 0x62, 0x05, 0xe7, 0x18, 0xf9, 0xa9, 0xd6, 0x98,
- 0x3e, 0xca, 0xf1, 0x1c, 0x5d, 0x27, 0x97, 0x0f, 0xd2, 0x2f, 0xf3, 0x9d,
- 0x42, 0x0b, 0xfb, 0x48, 0x2d, 0xdb, 0xc1, 0xb5, 0xfe, 0xb6, 0x59, 0x62,
- 0x7b, 0xd4, 0x7d, 0xc3, 0xa7, 0x9a, 0x72, 0x9d, 0x89, 0xd4, 0x28, 0xe3,
- 0x59, 0xd2, 0xa5, 0xb7, 0x76, 0xa8, 0x6d, 0x09, 0xaf, 0x7f, 0x56, 0x95,
- 0x71, 0x78, 0xf1, 0xb0, 0x4d, 0x6a, 0x96, 0x91, 0x39, 0x87, 0x84, 0x33,
- 0x20, 0xcd, 0xc1, 0x2a, 0x19, 0x43, 0x53, 0x64, 0x80, 0xf1, 0x9c, 0xa8,
- 0xf3, 0xf4, 0x90, 0xcf, 0x38, 0x9f, 0xeb, 0xdb, 0x5a, 0x0e, 0x81, 0xd5,
- 0x49, 0xef, 0xdc, 0x5f, 0xfa, 0x7f, 0x18, 0x2a, 0x7d, 0x88, 0xc4, 0xe2,
- 0xff, 0x02, 0xc7, 0x2a, 0x26, 0xcf, 0x94, 0x1a, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
-
-static struct fw_info bnx2_tpat_fw_06 = {
- /* Firmware version: 4.0.5 */
- .ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
-
- .start_addr = 0x08000888,
-
- .text_addr = 0x08000800,
- .text_len = 0x1a90,
- .text_index = 0x0,
- .gz_text = bnx2_TPAT_b06FwText,
- .gz_text_len = sizeof(bnx2_TPAT_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TPAT_b06FwData,
-
- .sbss_addr = 0x080022c0,
- .sbss_len = 0x44,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08002304,
- .bss_len = 0x450,
- .bss_index = 0x0,
-
- .rodata_addr = 0x00000000,
- .rodata_len = 0x0,
- .rodata_index = 0x0,
- .rodata = bnx2_TPAT_b06FwRodata,
-};
-
-/* Initialized Values for the TX Patch-up Processor. */
-static const struct cpu_reg cpu_reg_tpat = {
- .mode = BNX2_TPAT_CPU_MODE,
- .mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT,
- .mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA,
- .state = BNX2_TPAT_CPU_STATE,
- .state_value_clear = 0xffffff,
- .gpr0 = BNX2_TPAT_CPU_REG_FILE,
- .evmask = BNX2_TPAT_CPU_EVENT_MASK,
- .pc = BNX2_TPAT_CPU_PROGRAM_COUNTER,
- .inst = BNX2_TPAT_CPU_INSTRUCTION,
- .bp = BNX2_TPAT_CPU_HW_BREAKPOINT,
- .spad_base = BNX2_TPAT_SCRATCH,
- .mips_view_base = 0x8000000,
-};
-
-static u8 bnx2_TXP_b06FwText[] = {
- 0xad, 0x7b, 0x7f, 0x70, 0x9b, 0x75, 0x7a, 0xe7, 0xe7, 0xd5, 0x0f, 0x5b,
- 0xb2, 0x65, 0x59, 0x0e, 0x4a, 0x90, 0x77, 0xbd, 0x8d, 0x5e, 0xf4, 0xca,
- 0x16, 0xd8, 0x49, 0x5e, 0x25, 0xce, 0xc6, 0x59, 0xab, 0x44, 0x75, 0x1c,
- 0xdb, 0x71, 0x1c, 0x30, 0xc1, 0xdd, 0x3a, 0x3d, 0xae, 0xf1, 0x25, 0x26,
- 0x31, 0x10, 0xc0, 0xe9, 0xa6, 0x7b, 0x62, 0x8f, 0xd6, 0xc2, 0x76, 0x82,
- 0x43, 0x64, 0xbf, 0xce, 0x2a, 0x59, 0x87, 0x4e, 0x67, 0xd6, 0x60, 0x07,
- 0x07, 0x56, 0x8e, 0x60, 0xdb, 0x6b, 0xbb, 0x73, 0xbb, 0x83, 0x8e, 0x40,
- 0xf0, 0x72, 0x01, 0xb6, 0xfd, 0xa3, 0x47, 0x6f, 0xee, 0xda, 0xcc, 0x02,
- 0x59, 0xa0, 0x4b, 0xa0, 0x3b, 0x7b, 0x53, 0x67, 0x0b, 0xbc, 0xf7, 0x79,
- 0xde, 0x57, 0x4a, 0xb2, 0x94, 0x4e, 0x67, 0x3a, 0xe7, 0x19, 0x8f, 0xac,
- 0xf7, 0xc7, 0xf3, 0x7d, 0x7e, 0x3f, 0x9f, 0xe7, 0xf9, 0x7e, 0x5d, 0x0f,
- 0x54, 0xa0, 0xf8, 0x53, 0xc5, 0xdf, 0xe6, 0xe1, 0xd4, 0xe1, 0x8d, 0x6b,
- 0xf5, 0xb5, 0xd6, 0x05, 0x37, 0x5c, 0x72, 0xf3, 0xab, 0x0a, 0x30, 0xf0,
- 0x01, 0xfe, 0x5d, 0x3f, 0x5f, 0xf9, 0xf7, 0xbd, 0x66, 0xfd, 0x38, 0x81,
- 0x40, 0x89, 0x2f, 0xf9, 0x85, 0xc7, 0x91, 0x40, 0x6b, 0x9b, 0x06, 0x8f,
- 0x33, 0xf1, 0x67, 0x89, 0x7d, 0x1a, 0x90, 0xcc, 0x35, 0x86, 0xb7, 0xe2,
- 0x53, 0x33, 0x1d, 0x74, 0x41, 0xae, 0x7f, 0x25, 0xf1, 0xc9, 0xc8, 0x8f,
- 0x36, 0xa9, 0x1f, 0xcf, 0x3a, 0xe1, 0x09, 0x24, 0x4e, 0x23, 0x50, 0x0f,
- 0x4f, 0x1d, 0xdf, 0xf9, 0x93, 0x86, 0x6a, 0x27, 0xfc, 0x25, 0x5a, 0x2d,
- 0x18, 0x33, 0x90, 0xf6, 0x24, 0x86, 0x51, 0xbe, 0x11, 0x78, 0x37, 0x13,
- 0xd5, 0xc7, 0x80, 0x69, 0x47, 0x22, 0x1a, 0x7e, 0x09, 0x3a, 0x8e, 0xe4,
- 0xc3, 0x68, 0xe7, 0xef, 0x76, 0xe3, 0x33, 0x33, 0xec, 0x46, 0xda, 0xc9,
- 0xe7, 0xf6, 0x36, 0x03, 0xdb, 0x32, 0x3a, 0x8e, 0x1a, 0xf0, 0xd4, 0x26,
- 0x1e, 0xc5, 0x66, 0x7e, 0xfa, 0x13, 0x29, 0xbc, 0x31, 0x19, 0x09, 0x3f,
- 0x03, 0xb5, 0x5f, 0x73, 0xaa, 0x29, 0xa0, 0x71, 0x68, 0x50, 0x51, 0x07,
- 0xde, 0x54, 0xd4, 0xde, 0x49, 0x05, 0x1e, 0x85, 0xcf, 0x35, 0xe6, 0xe4,
- 0x33, 0x85, 0xdb, 0x72, 0x1e, 0x5c, 0x72, 0xca, 0xfa, 0xbf, 0x49, 0x7d,
- 0x2b, 0x70, 0x69, 0x2d, 0x18, 0x27, 0x0f, 0xee, 0x84, 0x82, 0xa7, 0x9b,
- 0xa3, 0xa1, 0x51, 0xc8, 0xfd, 0x30, 0xb6, 0xe6, 0xe5, 0x53, 0xa5, 0xd4,
- 0xa6, 0x39, 0xae, 0x9b, 0xe6, 0x19, 0xbd, 0x1c, 0xe9, 0x80, 0x1a, 0x02,
- 0x14, 0x8c, 0xea, 0x0e, 0x24, 0x03, 0x6d, 0x61, 0x17, 0xd4, 0xd0, 0xbd,
- 0xf8, 0x67, 0xca, 0x9c, 0x8c, 0xb9, 0x61, 0x3f, 0x3f, 0x80, 0x72, 0x14,
- 0x02, 0xb6, 0xd6, 0x9e, 0xce, 0x98, 0xe6, 0x05, 0xcd, 0x85, 0x33, 0xd4,
- 0xcf, 0x68, 0xee, 0x9f, 0xcd, 0x02, 0x75, 0x33, 0xae, 0x95, 0xd6, 0xf7,
- 0x60, 0x36, 0x60, 0x9a, 0x73, 0xbc, 0x77, 0x34, 0x57, 0xd2, 0xb3, 0x69,
- 0x3a, 0x34, 0xd3, 0xdc, 0xa7, 0xfd, 0xca, 0xdc, 0xfb, 0x6b, 0xcf, 0x9a,
- 0xe6, 0x13, 0xfa, 0x4d, 0x38, 0x9b, 0x6d, 0x57, 0xba, 0x17, 0x56, 0xf9,
- 0xb7, 0xcf, 0x98, 0xb8, 0xa0, 0x23, 0xe0, 0x48, 0x74, 0x28, 0xdb, 0x17,
- 0xba, 0x94, 0x6d, 0xf9, 0x5d, 0x4a, 0xc7, 0xdc, 0xef, 0x2a, 0x5d, 0x0b,
- 0x03, 0x4a, 0x67, 0x3e, 0x84, 0x79, 0x23, 0x88, 0x39, 0xa3, 0x5f, 0x69,
- 0x5f, 0xe8, 0x53, 0x6c, 0x39, 0x52, 0x4a, 0x5b, 0xbe, 0x44, 0xeb, 0xba,
- 0x1e, 0xb7, 0x67, 0x12, 0x98, 0x30, 0xca, 0xb9, 0xce, 0xb2, 0xf9, 0xa3,
- 0x86, 0x65, 0xca, 0xa9, 0xe3, 0x58, 0xfe, 0x09, 0xec, 0x9c, 0x31, 0xcd,
- 0x5c, 0x1c, 0xc8, 0xe5, 0x81, 0xef, 0x19, 0x91, 0xde, 0x21, 0xc5, 0x34,
- 0x3b, 0xa3, 0xe6, 0xea, 0xcb, 0x7a, 0x63, 0xec, 0x65, 0xfc, 0x93, 0x39,
- 0x1b, 0x44, 0xda, 0x47, 0x1a, 0xc7, 0x69, 0xb3, 0xfb, 0x27, 0xe1, 0x29,
- 0x4f, 0x8c, 0xe3, 0x67, 0x19, 0x78, 0xca, 0x12, 0x69, 0x5c, 0xc8, 0x8c,
- 0x06, 0x3c, 0x88, 0x84, 0xb6, 0x2b, 0xe9, 0x94, 0x03, 0xea, 0xf0, 0xdb,
- 0x50, 0xc3, 0xb4, 0xc7, 0xd2, 0x79, 0x45, 0x2d, 0xbc, 0x0c, 0x35, 0xf9,
- 0x2b, 0x45, 0xed, 0xaa, 0x75, 0x22, 0xe9, 0x88, 0x7a, 0xf0, 0xa3, 0x06,
- 0xb1, 0xc9, 0x38, 0xd6, 0x5a, 0xb6, 0x49, 0xe3, 0xd6, 0x6b, 0xb6, 0x49,
- 0x60, 0x94, 0x7c, 0x1d, 0x25, 0x5f, 0xaf, 0xe8, 0x6a, 0xe8, 0x69, 0x98,
- 0xab, 0x07, 0x75, 0xb9, 0x97, 0xc0, 0x78, 0xde, 0x0c, 0xfb, 0x13, 0x97,
- 0xc8, 0x2f, 0xd2, 0x5f, 0x4a, 0x78, 0xd2, 0xd5, 0x89, 0x4f, 0xcd, 0xd7,
- 0x37, 0x86, 0xf0, 0x62, 0x3e, 0x88, 0x17, 0xf2, 0x01, 0x3c, 0x9f, 0x6f,
- 0x87, 0x91, 0x87, 0x7f, 0x67, 0xfe, 0x8b, 0xfc, 0xd8, 0x84, 0x8f, 0xcf,
- 0x93, 0x6f, 0xff, 0x8e, 0xbc, 0x6b, 0xa0, 0x2c, 0x81, 0xde, 0x1f, 0x67,
- 0x46, 0xcc, 0x0a, 0x0d, 0x03, 0x35, 0x09, 0x2d, 0x79, 0x9b, 0xe2, 0x6b,
- 0xa1, 0x1f, 0xf6, 0xbe, 0x9a, 0x6b, 0x71, 0x69, 0x53, 0x5e, 0xb8, 0xa9,
- 0xff, 0x6d, 0x79, 0xd3, 0x1c, 0xd3, 0x0f, 0xad, 0xdb, 0xdb, 0xf2, 0xa7,
- 0x85, 0x5e, 0xad, 0x07, 0xe9, 0xfc, 0x20, 0xe0, 0x4f, 0xf0, 0x93, 0xa1,
- 0xb8, 0xab, 0xa9, 0x3d, 0x7c, 0xee, 0x41, 0x97, 0xed, 0xcf, 0xe4, 0x81,
- 0x7a, 0x7f, 0xc1, 0x20, 0x0f, 0xc6, 0xb4, 0x1f, 0x15, 0x61, 0xca, 0xf7,
- 0x13, 0xf2, 0x19, 0xc3, 0xf7, 0xf3, 0x1a, 0x79, 0x6b, 0x22, 0x8f, 0x61,
- 0xf2, 0xe7, 0xc1, 0xde, 0xac, 0x3a, 0x9d, 0x86, 0x3a, 0x31, 0x8b, 0x35,
- 0x48, 0x06, 0x03, 0xf4, 0xc1, 0x3f, 0x86, 0x4d, 0xa3, 0x07, 0x53, 0x06,
- 0xd6, 0x07, 0x12, 0xb4, 0x6f, 0x1c, 0x8f, 0x96, 0x21, 0x3a, 0xf0, 0xb1,
- 0xa2, 0xe0, 0xf5, 0x68, 0x0f, 0x26, 0x29, 0x4f, 0x4f, 0xce, 0x8b, 0x07,
- 0xb2, 0x15, 0xb8, 0x2f, 0x6b, 0xe2, 0xfe, 0x38, 0x12, 0x15, 0x94, 0x27,
- 0x16, 0x8f, 0x86, 0xdf, 0x83, 0x0b, 0xed, 0xb9, 0x1e, 0xc6, 0xd2, 0x56,
- 0x24, 0xcb, 0x3c, 0xd8, 0x9a, 0xf3, 0x31, 0x1e, 0x93, 0x38, 0x3d, 0xe3,
- 0x81, 0x7b, 0x83, 0x03, 0xb3, 0xc1, 0x32, 0xc4, 0xea, 0x1d, 0xfc, 0x0d,
- 0xfa, 0xdb, 0x66, 0xea, 0xfc, 0xdb, 0x0c, 0x17, 0x0e, 0x18, 0x0e, 0x8c,
- 0x64, 0x4d, 0xb3, 0x5d, 0x37, 0x71, 0x75, 0x43, 0x00, 0x3f, 0xa0, 0xfe,
- 0x0e, 0x19, 0x21, 0x9c, 0xcd, 0x3f, 0x4e, 0x5e, 0x82, 0x36, 0xbf, 0x06,
- 0x79, 0x37, 0xc8, 0xbb, 0x41, 0xbe, 0x0d, 0xe1, 0xf3, 0x3c, 0x63, 0x46,
- 0xa7, 0x5c, 0x5e, 0xf2, 0x50, 0x89, 0x21, 0xf2, 0x11, 0x89, 0x9b, 0x70,
- 0xc4, 0xd5, 0xf4, 0x5e, 0x26, 0xaf, 0xd5, 0xf5, 0xa6, 0xf9, 0xf1, 0x06,
- 0x91, 0x85, 0x36, 0x77, 0xf4, 0x48, 0x8c, 0xfe, 0x56, 0x15, 0xe3, 0xea,
- 0x6f, 0xa9, 0xb7, 0x27, 0xf3, 0x5e, 0xa4, 0xb2, 0x96, 0xdf, 0x1e, 0x2e,
- 0x23, 0xdf, 0xc2, 0x57, 0x5e, 0x8b, 0x32, 0x46, 0xa3, 0xfd, 0x8c, 0x51,
- 0xec, 0x20, 0xcf, 0xf7, 0x1b, 0xd1, 0x96, 0x5d, 0x8a, 0x0b, 0x9d, 0xb9,
- 0xa0, 0xbf, 0xfd, 0x06, 0x3e, 0x29, 0xaf, 0xc4, 0x20, 0x65, 0x0d, 0x90,
- 0xbf, 0x20, 0xf6, 0x91, 0xcf, 0x17, 0x8a, 0x7c, 0xce, 0xe5, 0x65, 0xad,
- 0xcf, 0xf3, 0x5a, 0xe2, 0x13, 0xe9, 0x15, 0x89, 0xa0, 0x82, 0x0a, 0x1f,
- 0x76, 0xe5, 0xde, 0xa2, 0x2d, 0xea, 0xf0, 0xa7, 0xb4, 0xc1, 0x8b, 0x8c,
- 0x91, 0xef, 0x5f, 0xf3, 0x17, 0xb1, 0xc7, 0x63, 0xb4, 0x83, 0x7a, 0x3a,
- 0x0d, 0x1f, 0x06, 0xf2, 0x49, 0x1c, 0x99, 0x41, 0x72, 0x5e, 0x3f, 0xce,
- 0x78, 0x5f, 0x05, 0xa7, 0x56, 0x9e, 0x0c, 0x68, 0x15, 0xd8, 0x37, 0x17,
- 0xc4, 0x70, 0xbe, 0x0d, 0x46, 0x36, 0x88, 0x83, 0xf4, 0xcd, 0x2b, 0xf1,
- 0xe4, 0xfd, 0x7e, 0x08, 0xef, 0x41, 0x3c, 0xc0, 0x77, 0x9e, 0x98, 0x09,
- 0x62, 0x88, 0x3a, 0xda, 0x1e, 0x8f, 0xb6, 0x78, 0x79, 0xed, 0x00, 0xaf,
- 0x1d, 0xa5, 0xfe, 0xcf, 0xeb, 0x93, 0x18, 0xe8, 0x55, 0x63, 0x40, 0x10,
- 0xfb, 0x0d, 0x04, 0xe8, 0xc2, 0x8f, 0x31, 0xbf, 0xc5, 0xce, 0xf3, 0xfb,
- 0xbd, 0xf9, 0x0a, 0xca, 0xe9, 0x47, 0x48, 0xfb, 0xc4, 0x74, 0x37, 0x9b,
- 0xe6, 0x77, 0xf5, 0xe8, 0xd2, 0x4f, 0x9d, 0x2e, 0x3c, 0x92, 0x77, 0x20,
- 0x35, 0x57, 0x81, 0xdf, 0xcf, 0xba, 0x70, 0x57, 0x7d, 0x05, 0x0e, 0xcd,
- 0x25, 0x31, 0x36, 0x53, 0x81, 0xc1, 0x2c, 0x56, 0xef, 0xd7, 0xc7, 0x6a,
- 0xca, 0xa0, 0x2e, 0xb7, 0x23, 0x86, 0xab, 0xb4, 0xc3, 0x23, 0x73, 0x3e,
- 0x7f, 0xff, 0x4c, 0x00, 0xa9, 0x05, 0x2f, 0x9f, 0x77, 0xf0, 0xf9, 0x72,
- 0xe8, 0xeb, 0x23, 0xa9, 0x00, 0x84, 0xc7, 0x4a, 0x3c, 0x34, 0xe7, 0xc5,
- 0x83, 0xd9, 0x00, 0x0e, 0xce, 0x34, 0x63, 0xda, 0x48, 0xe2, 0x18, 0x73,
- 0xc7, 0xf7, 0xe2, 0x6a, 0xef, 0x41, 0x45, 0x4d, 0x6e, 0x53, 0x92, 0x68,
- 0x88, 0xbb, 0x71, 0x89, 0x79, 0xc8, 0x1d, 0x6f, 0x6c, 0x79, 0x9e, 0xb9,
- 0xa1, 0x2c, 0x11, 0xe4, 0x77, 0x75, 0x82, 0x31, 0x9b, 0x74, 0x3b, 0x36,
- 0x00, 0x2b, 0x25, 0x7e, 0x83, 0xfe, 0x6e, 0x23, 0xe0, 0xef, 0xce, 0xd7,
- 0xf9, 0xb7, 0x1b, 0x21, 0xff, 0x76, 0xc6, 0xd7, 0x36, 0xf1, 0x47, 0xc3,
- 0x83, 0xe3, 0xf1, 0x4f, 0xcd, 0x81, 0x1a, 0x2b, 0x9f, 0xf9, 0x77, 0xce,
- 0xa8, 0xe9, 0x59, 0xa8, 0x3a, 0xab, 0x01, 0x26, 0x17, 0x5c, 0xb4, 0x9f,
- 0x82, 0x1a, 0xad, 0x99, 0x79, 0x3c, 0x80, 0x87, 0x98, 0x53, 0xfe, 0x9a,
- 0x39, 0x65, 0x70, 0x2a, 0x12, 0x98, 0x86, 0x97, 0xfa, 0x06, 0xf6, 0x9e,
- 0x0b, 0xd2, 0xe6, 0x5d, 0x78, 0x9c, 0x7c, 0x6d, 0xdf, 0x18, 0xc4, 0x7d,
- 0xf9, 0x80, 0xbf, 0x8b, 0xf6, 0x7b, 0x2f, 0x17, 0xf2, 0x6f, 0xa5, 0x2d,
- 0xdf, 0xce, 0xa9, 0xe1, 0x02, 0xfe, 0xaf, 0xf8, 0x53, 0x0c, 0x0e, 0x60,
- 0xff, 0x94, 0x1b, 0x85, 0xa0, 0xac, 0x45, 0x9d, 0x1b, 0x2f, 0x9a, 0x3e,
- 0x4d, 0x3b, 0x7d, 0x90, 0xba, 0xfe, 0x46, 0xde, 0x87, 0x07, 0x0d, 0x35,
- 0xf6, 0x7d, 0xc5, 0x47, 0x9d, 0x7a, 0xa8, 0x07, 0x26, 0x98, 0x55, 0xf2,
- 0x5c, 0x1c, 0xe1, 0x55, 0x76, 0xae, 0x3d, 0x34, 0x27, 0x7e, 0x42, 0xdb,
- 0x1b, 0xf4, 0x01, 0xfa, 0xcf, 0xf7, 0xaf, 0xc5, 0xaa, 0x1a, 0x48, 0x5b,
- 0xb9, 0x3b, 0x46, 0x7f, 0xb1, 0x75, 0x74, 0x62, 0x46, 0xf4, 0xa0, 0x4e,
- 0xc3, 0x91, 0xc4, 0xba, 0xf5, 0x7f, 0x6d, 0x5e, 0x5a, 0x29, 0xfa, 0x08,
- 0x60, 0x84, 0x3a, 0x3c, 0x6d, 0x98, 0xe6, 0xd5, 0x0d, 0x1f, 0x9a, 0x2d,
- 0x37, 0x8b, 0x5e, 0x44, 0xd6, 0x1f, 0x28, 0x52, 0x47, 0x6a, 0x34, 0xff,
- 0xff, 0x07, 0x5f, 0xf9, 0xa6, 0x39, 0x60, 0xc9, 0x27, 0xfe, 0xe2, 0xa2,
- 0x2f, 0x3e, 0x4e, 0xda, 0x0e, 0x0c, 0x90, 0xde, 0xc3, 0x86, 0xf9, 0x51,
- 0x6d, 0xe2, 0x33, 0xb3, 0x65, 0x93, 0x36, 0xbc, 0xac, 0xfc, 0x4f, 0x5e,
- 0x0f, 0xe2, 0xa1, 0x7c, 0x0b, 0x75, 0xd7, 0x8e, 0x27, 0xa8, 0xc3, 0xa3,
- 0x86, 0xe4, 0xc4, 0x10, 0xfd, 0xb9, 0x8e, 0xfe, 0xed, 0x52, 0xb6, 0x19,
- 0x39, 0x6c, 0x9f, 0x4c, 0xa3, 0x93, 0xfe, 0xbe, 0x94, 0x89, 0xb4, 0x3c,
- 0x0b, 0x35, 0x4d, 0x19, 0xfc, 0x5d, 0xd4, 0x71, 0xbb, 0xa1, 0x76, 0x89,
- 0x4d, 0xdb, 0x99, 0x97, 0x5e, 0xca, 0x84, 0xfc, 0x6d, 0x79, 0xd1, 0x77,
- 0x9d, 0x7f, 0x6b, 0xfe, 0xab, 0xb4, 0xbd, 0x82, 0xcd, 0x6b, 0x3c, 0xcc,
- 0x33, 0x77, 0xc1, 0xb6, 0xab, 0x6d, 0xbb, 0xd7, 0xe3, 0x8d, 0x03, 0x1f,
- 0x32, 0x3f, 0xa5, 0x57, 0xda, 0xd7, 0x52, 0xbc, 0x56, 0xbd, 0x01, 0xfe,
- 0x3b, 0xe9, 0x07, 0x7b, 0xe8, 0x07, 0x57, 0x37, 0x7c, 0x6a, 0x86, 0x6f,
- 0xb2, 0xfd, 0xa0, 0x6d, 0xc6, 0xe5, 0xef, 0xa0, 0x9e, 0xb6, 0xe9, 0x0a,
- 0xe6, 0xf4, 0x0c, 0x06, 0xae, 0x61, 0x87, 0xe4, 0xec, 0x59, 0x3d, 0xc9,
- 0x3c, 0xf2, 0x9b, 0x70, 0xd5, 0x60, 0xf6, 0x59, 0xfd, 0x71, 0x84, 0x6d,
- 0xdf, 0xc1, 0xc1, 0xac, 0x17, 0xe9, 0xbb, 0x02, 0x98, 0x6f, 0x08, 0xe0,
- 0x61, 0xd2, 0xbe, 0x12, 0x6f, 0x1c, 0x7a, 0x83, 0x3a, 0x98, 0xad, 0x91,
- 0x6b, 0x49, 0xfc, 0xa5, 0xfe, 0x28, 0x70, 0x93, 0xbd, 0xf6, 0x82, 0xc4,
- 0xe8, 0x42, 0x33, 0x8e, 0xe6, 0xfb, 0x15, 0x3b, 0x6f, 0xaa, 0x5d, 0x49,
- 0xfc, 0xc4, 0x94, 0x5c, 0xba, 0x60, 0x30, 0xc7, 0x51, 0x1f, 0xe3, 0xf4,
- 0xa3, 0xd1, 0x5c, 0x9d, 0xbf, 0x93, 0x7e, 0xf4, 0x78, 0x4e, 0x64, 0x8a,
- 0xea, 0xba, 0xb3, 0x96, 0xb5, 0x99, 0xfa, 0x31, 0xac, 0x9a, 0x5f, 0x1d,
- 0xd0, 0x8e, 0x61, 0xda, 0xe2, 0x2d, 0xa5, 0xf4, 0x13, 0x63, 0x30, 0x64,
- 0xaa, 0xcb, 0xb5, 0x43, 0x78, 0xdc, 0xba, 0x16, 0xf4, 0xef, 0x9e, 0x49,
- 0x3a, 0x1c, 0x1a, 0x02, 0x95, 0x89, 0x76, 0x65, 0x37, 0xeb, 0x6e, 0xc7,
- 0x4c, 0x87, 0xd2, 0xb1, 0x20, 0x31, 0xd0, 0xa5, 0x6c, 0x67, 0xcd, 0x4d,
- 0xb2, 0xe6, 0x26, 0x59, 0x73, 0x93, 0xe4, 0x23, 0xc9, 0x5a, 0xdb, 0x96,
- 0x4f, 0x29, 0x3b, 0x44, 0xff, 0xf4, 0xaf, 0xe7, 0x0d, 0x1b, 0x47, 0x30,
- 0x07, 0xf9, 0x3b, 0xf3, 0x6b, 0x1d, 0x36, 0xb6, 0x4b, 0x29, 0x45, 0x2c,
- 0xe3, 0xa9, 0xd0, 0x58, 0xcb, 0x8c, 0x94, 0xd2, 0xcd, 0x7a, 0xdb, 0x6f,
- 0xe9, 0x32, 0x32, 0xfc, 0x0e, 0xeb, 0xec, 0xeb, 0xac, 0xb3, 0xb9, 0x38,
- 0xe3, 0x6a, 0xcd, 0x55, 0x73, 0x60, 0xa5, 0x5d, 0x13, 0xc6, 0xc8, 0xef,
- 0x77, 0x69, 0xb3, 0x02, 0x6b, 0x69, 0xbb, 0x53, 0xc1, 0x7e, 0x0d, 0xd5,
- 0xb5, 0xcc, 0xa9, 0x47, 0xf3, 0xac, 0x03, 0x7a, 0xa4, 0xe5, 0x7d, 0x2a,
- 0xf6, 0xa8, 0xe6, 0xc6, 0xd5, 0x9b, 0x08, 0x76, 0xb4, 0x36, 0x1c, 0xcf,
- 0x96, 0x63, 0x28, 0x9e, 0x5c, 0xe1, 0x21, 0x56, 0xe9, 0x6a, 0xc6, 0xa3,
- 0x5c, 0x5a, 0x09, 0x25, 0xa2, 0xf4, 0x1b, 0x24, 0xa7, 0x58, 0x27, 0x26,
- 0x8d, 0xaf, 0x22, 0xc7, 0x7a, 0x3a, 0xaf, 0xbb, 0xf0, 0x7a, 0x6e, 0x2d,
- 0xf3, 0x5c, 0x54, 0xf7, 0x29, 0x15, 0x8c, 0xdf, 0x04, 0x32, 0x86, 0xe4,
- 0x27, 0xd3, 0x9c, 0x17, 0x1e, 0xa2, 0xd1, 0xe4, 0x28, 0x24, 0x67, 0x99,
- 0xab, 0xef, 0x8d, 0x97, 0x61, 0x73, 0xd4, 0x8f, 0xd5, 0xda, 0x80, 0xd2,
- 0x95, 0x8f, 0xea, 0xe7, 0xf1, 0xbb, 0xca, 0x9e, 0x85, 0x04, 0x63, 0xbb,
- 0x9f, 0xba, 0xa9, 0xc0, 0xa5, 0xa0, 0xf0, 0x88, 0x6a, 0xb7, 0xe6, 0xc0,
- 0xbb, 0x77, 0x2b, 0x08, 0x68, 0x49, 0x5c, 0x68, 0x0e, 0xd0, 0xaf, 0xba,
- 0x88, 0x31, 0xc2, 0x70, 0x2e, 0x86, 0xfc, 0x3b, 0x68, 0x8b, 0xca, 0xc5,
- 0x3a, 0xda, 0x87, 0xbe, 0x47, 0x1d, 0xb6, 0x51, 0x87, 0xdd, 0x73, 0x08,
- 0x54, 0x24, 0xfa, 0x94, 0x8e, 0x7c, 0xbb, 0xd2, 0x9e, 0x57, 0xa9, 0x27,
- 0xd1, 0xc9, 0x37, 0x89, 0x95, 0xc4, 0x57, 0x4a, 0xb6, 0x14, 0x7f, 0xbd,
- 0xd1, 0x9e, 0xfd, 0x0e, 0x89, 0xb9, 0xcd, 0x6b, 0x12, 0x8c, 0x47, 0x07,
- 0xf9, 0x12, 0x1e, 0x3c, 0xa8, 0x6e, 0x30, 0x57, 0x5f, 0x89, 0x33, 0x79,
- 0x56, 0x24, 0x30, 0x95, 0xef, 0xa1, 0x5d, 0x36, 0x14, 0xfd, 0x2b, 0xe0,
- 0xdf, 0x36, 0xd3, 0xae, 0x6c, 0x5b, 0x58, 0xe1, 0xef, 0xa5, 0x0d, 0x7b,
- 0x17, 0x42, 0x42, 0x97, 0xeb, 0x8b, 0x6d, 0x93, 0x70, 0x68, 0xff, 0x9a,
- 0x2d, 0xbf, 0x41, 0x5a, 0x62, 0x4f, 0x6f, 0xc9, 0x4f, 0xfd, 0x7b, 0x66,
- 0x92, 0x78, 0x77, 0x83, 0x9b, 0x35, 0xb5, 0x84, 0x29, 0xaa, 0x8a, 0x9f,
- 0xa7, 0x1d, 0xd0, 0x52, 0x4a, 0x97, 0xf8, 0x91, 0xdb, 0x5e, 0xf3, 0xce,
- 0x19, 0xb8, 0x09, 0x15, 0xc2, 0x4e, 0x62, 0xba, 0x0f, 0xe3, 0xd1, 0x81,
- 0x73, 0x4a, 0x8f, 0xd2, 0x93, 0x97, 0x1a, 0x6c, 0xfb, 0x54, 0x1b, 0x7d,
- 0xaa, 0x9d, 0xfc, 0xb4, 0xd3, 0xa7, 0xba, 0xc9, 0x4f, 0xb7, 0xe5, 0x53,
- 0xe2, 0x9b, 0xbf, 0xce, 0xcb, 0xd6, 0xfc, 0x1e, 0x4b, 0x2f, 0x3b, 0xf8,
- 0x6e, 0x17, 0xe5, 0xe8, 0xe2, 0x7b, 0x7b, 0xf8, 0xde, 0x9e, 0x85, 0xff,
- 0x2d, 0xfc, 0x51, 0x16, 0x3b, 0xf6, 0xaf, 0xd7, 0x34, 0xc9, 0x01, 0xaf,
- 0x15, 0x31, 0x05, 0xd2, 0x8e, 0x84, 0xe4, 0x88, 0x61, 0xf4, 0x36, 0xc3,
- 0xb3, 0x22, 0xf1, 0x93, 0xd6, 0x5d, 0xf5, 0xcc, 0x67, 0xcc, 0xa7, 0x9e,
- 0x29, 0x62, 0x69, 0xe6, 0xe8, 0xf9, 0x16, 0x05, 0x63, 0xfa, 0xcd, 0x8c,
- 0x53, 0x1d, 0x13, 0x79, 0xb5, 0x2b, 0xcc, 0x7b, 0x4d, 0x93, 0x82, 0xf1,
- 0x0f, 0xa2, 0x8d, 0xb8, 0x2e, 0x94, 0x18, 0x42, 0xc8, 0x88, 0x84, 0x26,
- 0x14, 0x75, 0x68, 0x2b, 0xd4, 0x25, 0xd6, 0x86, 0xd4, 0x9c, 0xa2, 0x0e,
- 0xd7, 0x3a, 0xd5, 0xe4, 0x9b, 0x16, 0xbe, 0x3e, 0x88, 0x35, 0x16, 0x86,
- 0x1b, 0x42, 0x8c, 0x58, 0x76, 0x07, 0x69, 0x1e, 0xd8, 0xac, 0xe0, 0xb2,
- 0xfe, 0x21, 0xed, 0xa8, 0x26, 0xd3, 0x8a, 0x8e, 0x0c, 0xf3, 0x44, 0x68,
- 0x4a, 0xb0, 0xfa, 0x41, 0x62, 0x75, 0x78, 0x7c, 0x7c, 0x36, 0x33, 0x19,
- 0x49, 0x79, 0x9c, 0x6a, 0x8c, 0x38, 0x3d, 0x49, 0x9a, 0x7a, 0x9e, 0xf8,
- 0x9d, 0x6b, 0x84, 0xf7, 0x17, 0x69, 0x46, 0x8b, 0x34, 0xb5, 0x1c, 0x18,
- 0x37, 0x13, 0xe8, 0x8c, 0xb2, 0x56, 0x30, 0xe7, 0x1d, 0x93, 0x9e, 0x80,
- 0xf4, 0xca, 0xa7, 0x74, 0x7e, 0x4f, 0x29, 0xbb, 0x25, 0xa6, 0xca, 0x6d,
- 0x2b, 0x54, 0x73, 0x8d, 0xaa, 0xc4, 0x61, 0x2c, 0x5a, 0x6b, 0x0c, 0xcb,
- 0x1a, 0xc3, 0x3f, 0x53, 0xd4, 0xd8, 0x39, 0x45, 0x72, 0x75, 0x63, 0xff,
- 0x39, 0xc6, 0xd0, 0x51, 0x45, 0x6d, 0x39, 0x4e, 0xf1, 0xbd, 0x9a, 0xd0,
- 0x3f, 0x5c, 0x5c, 0x67, 0x18, 0x0d, 0x39, 0xc6, 0x67, 0xde, 0xa3, 0x6c,
- 0xcd, 0xb6, 0x61, 0x6c, 0xae, 0x0d, 0xa3, 0x59, 0x05, 0x7b, 0xf4, 0x95,
- 0xb8, 0x74, 0xb3, 0xd5, 0xa7, 0x54, 0xad, 0xd6, 0x6a, 0x31, 0x12, 0x40,
- 0xb5, 0x43, 0xfb, 0x0a, 0xf6, 0x16, 0x31, 0x7e, 0xe7, 0x89, 0x5e, 0xe6,
- 0x7d, 0x13, 0xef, 0x33, 0x96, 0x22, 0x35, 0x48, 0xba, 0x13, 0x2d, 0xc4,
- 0xe3, 0x75, 0x4e, 0x3b, 0xde, 0xff, 0xc9, 0x63, 0xdb, 0x40, 0xf4, 0xff,
- 0xf9, 0x7b, 0x6d, 0x78, 0x32, 0x5b, 0x86, 0x96, 0x0d, 0xb8, 0x2b, 0x84,
- 0x2a, 0x07, 0x6b, 0xdc, 0x5b, 0xbb, 0x94, 0x14, 0xef, 0x59, 0xcf, 0x7a,
- 0xbe, 0x9c, 0xe8, 0x4d, 0xfc, 0x97, 0x06, 0xb9, 0x6e, 0xe5, 0x8d, 0x1b,
- 0xae, 0x0f, 0x7f, 0xc1, 0x75, 0x05, 0xcf, 0x31, 0x91, 0x7d, 0x8f, 0x35,
- 0x25, 0x97, 0x31, 0xe1, 0x4c, 0xb8, 0x30, 0x34, 0x19, 0xc6, 0xc1, 0xc5,
- 0x20, 0x16, 0x33, 0xea, 0xc0, 0x25, 0xf6, 0x0f, 0x7b, 0x9b, 0x35, 0x3c,
- 0xb8, 0x18, 0xc2, 0x42, 0x06, 0xa6, 0x37, 0xa1, 0x15, 0xbc, 0x4a, 0x0c,
- 0x07, 0x16, 0xeb, 0x70, 0x2e, 0xa3, 0x2d, 0x8d, 0x2a, 0xd1, 0x54, 0x2d,
- 0x71, 0xc7, 0xc3, 0x8b, 0x4d, 0x78, 0x68, 0xd1, 0xc3, 0x77, 0x4c, 0x74,
- 0xc7, 0xeb, 0xf8, 0xbc, 0x03, 0xcf, 0x9e, 0x34, 0x4d, 0xc1, 0x5d, 0x43,
- 0x8b, 0xc0, 0xc2, 0x34, 0x6b, 0xd1, 0x19, 0xd6, 0xa5, 0xa7, 0x80, 0x03,
- 0x4f, 0x39, 0x30, 0x37, 0x6d, 0x62, 0xaf, 0x3e, 0x5a, 0xeb, 0xa0, 0xc3,
- 0x0f, 0xb0, 0x6e, 0xb8, 0x59, 0x03, 0xef, 0x0d, 0xd8, 0xf9, 0xfc, 0x12,
- 0xf3, 0xd4, 0xfd, 0x4f, 0xc5, 0xf0, 0x56, 0x26, 0x8d, 0x6e, 0xe2, 0xf3,
- 0x14, 0x79, 0x79, 0x33, 0xc3, 0x3a, 0xb6, 0xa8, 0xe3, 0x8d, 0x8c, 0x87,
- 0xeb, 0x34, 0xe1, 0xe5, 0x8c, 0x3c, 0x23, 0xcf, 0xfa, 0x30, 0x48, 0x5e,
- 0x5e, 0xcf, 0x84, 0xb8, 0x66, 0x10, 0x3f, 0xe6, 0x73, 0xf7, 0x2d, 0x6a,
- 0xac, 0x5b, 0x1e, 0xae, 0x1b, 0xc6, 0xab, 0x19, 0x1f, 0x79, 0x0d, 0xb2,
- 0x56, 0x0d, 0x62, 0x2c, 0xd3, 0xb8, 0xb4, 0x95, 0x89, 0xda, 0xae, 0x35,
- 0x72, 0xed, 0x1d, 0xb3, 0xc7, 0x8a, 0x45, 0x59, 0xa7, 0xb4, 0xee, 0x20,
- 0x46, 0x33, 0x6f, 0x38, 0x4b, 0xfd, 0xf4, 0x73, 0xd3, 0xcb, 0x16, 0xf6,
- 0x7b, 0xd6, 0xe0, 0xdf, 0x73, 0xc0, 0x39, 0x23, 0x6d, 0x56, 0x27, 0x88,
- 0x75, 0x59, 0xa3, 0x7e, 0xba, 0xb1, 0x89, 0xeb, 0x6a, 0x03, 0x2f, 0x29,
- 0xd2, 0xef, 0xb8, 0x10, 0x7e, 0x4a, 0xf4, 0x45, 0xcc, 0xbc, 0x00, 0xfc,
- 0x25, 0xf1, 0x67, 0xc3, 0xa4, 0x2a, 0x7e, 0xdf, 0x4f, 0x5c, 0xd3, 0x5b,
- 0x40, 0x7d, 0xec, 0x41, 0x8c, 0x98, 0x65, 0xc4, 0xe7, 0xd5, 0xc4, 0xb5,
- 0x8b, 0x4d, 0xac, 0x53, 0x1b, 0x4d, 0xf3, 0x6f, 0x9b, 0x61, 0x3a, 0x12,
- 0x9a, 0x5e, 0xeb, 0x2c, 0x7c, 0xa5, 0x0a, 0xda, 0x92, 0x5f, 0xd1, 0x0a,
- 0x3f, 0x45, 0x74, 0xf8, 0x3c, 0x44, 0xaf, 0xc0, 0xda, 0x45, 0x17, 0xd6,
- 0x51, 0x9e, 0x6d, 0x93, 0x5c, 0x9b, 0xf8, 0x24, 0x4a, 0x99, 0x76, 0x4e,
- 0x12, 0x73, 0x69, 0x3e, 0xac, 0xa1, 0x8e, 0x87, 0x4e, 0x99, 0x66, 0x39,
- 0x75, 0xdc, 0x40, 0xfb, 0xec, 0x3f, 0x61, 0xe2, 0x25, 0xfd, 0x25, 0xea,
- 0x54, 0x21, 0x6e, 0x6c, 0xe6, 0x3b, 0x41, 0x3e, 0xef, 0xc1, 0x81, 0x49,
- 0xe9, 0x97, 0xea, 0xf8, 0xcc, 0x45, 0x1c, 0xcf, 0xc4, 0xd0, 0x44, 0xfd,
- 0x85, 0x49, 0xb3, 0x91, 0xef, 0x84, 0x49, 0x2f, 0xbc, 0xf8, 0x35, 0x6c,
- 0x3f, 0xa5, 0x40, 0x8b, 0x8a, 0x0e, 0xbe, 0x86, 0xf6, 0x33, 0x5f, 0x94,
- 0x13, 0x98, 0xa5, 0xa6, 0xd5, 0x89, 0x02, 0xf1, 0x77, 0x55, 0x62, 0x04,
- 0xac, 0xdf, 0x78, 0x73, 0x56, 0xc1, 0xd4, 0x34, 0xfb, 0xbd, 0x8d, 0x30,
- 0x2b, 0x28, 0xd3, 0x1b, 0xb3, 0xbf, 0x81, 0x67, 0x4e, 0x52, 0x0f, 0x4f,
- 0x07, 0xf1, 0xbd, 0x8c, 0x0b, 0xb7, 0x4e, 0x09, 0xa6, 0xd3, 0x62, 0x07,
- 0x15, 0xe9, 0x8f, 0xa4, 0x6f, 0x89, 0x86, 0xdd, 0x8a, 0x03, 0xf5, 0xcf,
- 0xb8, 0xa0, 0x9d, 0x0b, 0xc3, 0x5d, 0xef, 0x81, 0x56, 0xff, 0xfb, 0xcc,
- 0x35, 0x0e, 0x94, 0xb1, 0x97, 0xed, 0xfc, 0x76, 0x8c, 0xd7, 0x82, 0xbc,
- 0x86, 0xdf, 0x28, 0x87, 0x73, 0x95, 0x93, 0x35, 0xbc, 0x4c, 0x23, 0x1e,
- 0x73, 0x99, 0xa6, 0x93, 0xb5, 0x61, 0xf7, 0x77, 0x4c, 0x33, 0xb2, 0x41,
- 0x9e, 0x0f, 0x20, 0x72, 0x4e, 0xe3, 0x73, 0x76, 0xbd, 0xbc, 0x8e, 0xc7,
- 0x9c, 0xf4, 0x23, 0x89, 0x55, 0xd6, 0x7b, 0xab, 0x87, 0xb2, 0x71, 0xfb,
- 0x0b, 0x79, 0xc1, 0x36, 0x61, 0x4b, 0x86, 0xb3, 0xd3, 0x0a, 0x73, 0x76,
- 0x82, 0xcf, 0x6e, 0x81, 0x33, 0xae, 0x4e, 0xa4, 0xe9, 0x07, 0x7b, 0x03,
- 0x2d, 0x78, 0xce, 0x70, 0xa3, 0x52, 0x5b, 0x85, 0x07, 0x7a, 0x03, 0x78,
- 0x8e, 0x7d, 0x01, 0x6d, 0x16, 0x2b, 0x80, 0x8d, 0xb4, 0x9f, 0xf4, 0x1c,
- 0x3f, 0x84, 0xf6, 0x6d, 0x07, 0xf3, 0x9c, 0xd3, 0xca, 0x73, 0x65, 0xf5,
- 0x40, 0x21, 0xe7, 0xc2, 0x05, 0xcd, 0xc6, 0x84, 0x2f, 0x58, 0x35, 0x5b,
- 0x0d, 0x14, 0xae, 0x61, 0x41, 0xb5, 0x25, 0xa9, 0x90, 0x19, 0xbf, 0xe8,
- 0xae, 0xdf, 0x65, 0xfb, 0xd2, 0xdf, 0x38, 0xa5, 0xe7, 0xb8, 0xfe, 0xbd,
- 0x02, 0x8e, 0x84, 0x1a, 0x6a, 0x73, 0xc2, 0xe3, 0x4a, 0x0c, 0xb5, 0x8e,
- 0x6b, 0x5f, 0xba, 0x81, 0xf7, 0x26, 0x8c, 0xe5, 0xaf, 0xf7, 0xda, 0x5d,
- 0x19, 0xcb, 0x87, 0xba, 0x44, 0xf7, 0x4f, 0xe8, 0x92, 0x67, 0x53, 0x4a,
- 0x3b, 0xf3, 0x56, 0xda, 0x85, 0x74, 0x15, 0x9f, 0xa1, 0xfe, 0x71, 0x74,
- 0x52, 0xe8, 0x1c, 0xc6, 0x78, 0x46, 0x66, 0x1b, 0xc3, 0xd8, 0x6c, 0x44,
- 0x62, 0x4b, 0xec, 0xa1, 0x8f, 0x40, 0xe6, 0x10, 0x8d, 0x85, 0x57, 0x14,
- 0x35, 0x75, 0x8b, 0x53, 0x1d, 0x5a, 0x56, 0xec, 0xbc, 0xb5, 0xb6, 0x98,
- 0xb7, 0xd6, 0xe4, 0x56, 0xf9, 0x7b, 0x58, 0x0f, 0x7a, 0x16, 0x4a, 0xf5,
- 0xa1, 0x47, 0xe9, 0xb4, 0x6a, 0x6b, 0xbf, 0xb2, 0x63, 0xc1, 0xa3, 0x74,
- 0x64, 0x3d, 0x78, 0x85, 0x58, 0x6c, 0xb6, 0x0f, 0x81, 0x5b, 0x37, 0xc2,
- 0xbb, 0x23, 0xdb, 0x8b, 0x72, 0x4d, 0x7a, 0xc8, 0x72, 0x74, 0x5a, 0x75,
- 0xad, 0xce, 0xdf, 0xc3, 0xfa, 0xd3, 0x93, 0xef, 0x63, 0xfe, 0x43, 0xc0,
- 0x9b, 0xb0, 0x67, 0x06, 0x92, 0x0b, 0xef, 0xe0, 0xbb, 0x4b, 0xf1, 0x15,
- 0x80, 0x5d, 0xff, 0x94, 0x7e, 0xf6, 0x12, 0xd5, 0x1b, 0x14, 0x5c, 0xba,
- 0xcb, 0x03, 0xd2, 0x62, 0xcf, 0x7f, 0xb1, 0xf5, 0xc2, 0x74, 0xaf, 0xd2,
- 0x31, 0x37, 0xef, 0xdd, 0x66, 0xc8, 0x2c, 0x62, 0xd6, 0xdb, 0x4e, 0x1e,
- 0xda, 0x17, 0x9e, 0xf6, 0x6e, 0x25, 0x4f, 0x5b, 0x17, 0x3e, 0x4f, 0x53,
- 0xea, 0xca, 0x44, 0x6b, 0x1b, 0x63, 0x7b, 0xb7, 0xfe, 0x91, 0x19, 0xfe,
- 0x1d, 0xa1, 0xb3, 0x58, 0xd4, 0x67, 0x92, 0x7c, 0x05, 0x3d, 0x9d, 0xf9,
- 0x80, 0x27, 0x99, 0x6f, 0xf7, 0xb6, 0x19, 0xbd, 0xde, 0xad, 0x46, 0x9f,
- 0xb7, 0xdd, 0xb8, 0x87, 0xb4, 0x7b, 0xbc, 0x1d, 0x06, 0xe3, 0x3a, 0xdf,
- 0x47, 0xbd, 0xf6, 0x62, 0x3c, 0x7f, 0x0f, 0xb1, 0x87, 0xd0, 0x1c, 0x20,
- 0x0e, 0xf2, 0x52, 0xc6, 0x11, 0xca, 0x58, 0x08, 0xb9, 0x91, 0x54, 0xdd,
- 0xd4, 0xd7, 0x98, 0x65, 0xc7, 0x09, 0x6b, 0x16, 0x55, 0x91, 0x98, 0x6c,
- 0xed, 0x3e, 0xc1, 0x7c, 0x9f, 0x38, 0xda, 0x7a, 0xeb, 0x29, 0xd4, 0xb8,
- 0x13, 0xd2, 0x3b, 0xb3, 0x1f, 0x8e, 0x46, 0xf5, 0xf7, 0x10, 0x0d, 0xbd,
- 0xc2, 0x67, 0x47, 0xe9, 0xbb, 0x63, 0xd6, 0xfc, 0x81, 0x06, 0xc9, 0x35,
- 0xa1, 0xdb, 0xf0, 0x78, 0x77, 0xb2, 0x37, 0xf3, 0x27, 0xd4, 0x96, 0x3b,
- 0x9c, 0x32, 0x0f, 0x29, 0xfc, 0x96, 0x0f, 0x4d, 0xe8, 0xca, 0x7b, 0x28,
- 0xd7, 0x97, 0xf0, 0x0f, 0x27, 0x59, 0xd7, 0x20, 0x7e, 0x68, 0x9a, 0xf7,
- 0xb1, 0xaf, 0x39, 0x96, 0xab, 0xc3, 0x65, 0xcb, 0xc6, 0x2e, 0x1c, 0xcd,
- 0x85, 0xf1, 0x0e, 0xe5, 0x73, 0x2d, 0xd6, 0xe2, 0xed, 0x69, 0x27, 0xf6,
- 0xe9, 0xb7, 0x17, 0xeb, 0x85, 0x03, 0xf7, 0xc6, 0x0e, 0x11, 0x3b, 0x38,
- 0x50, 0x4d, 0xfc, 0xf6, 0xb0, 0x75, 0xcd, 0xc9, 0xfe, 0xef, 0xb7, 0x91,
- 0xb2, 0xeb, 0x09, 0x79, 0x7c, 0x94, 0x3c, 0x36, 0x7b, 0xb7, 0x66, 0x55,
- 0xef, 0x9d, 0x59, 0x78, 0xdc, 0x89, 0xd1, 0xd6, 0x33, 0x27, 0x4d, 0x0c,
- 0xea, 0xb7, 0xe1, 0xca, 0xc9, 0xd1, 0x21, 0x17, 0xfd, 0xe7, 0xe7, 0xf1,
- 0x7e, 0x18, 0x33, 0xb8, 0x40, 0xe4, 0x71, 0xd1, 0xc7, 0xdc, 0xde, 0x10,
- 0x8f, 0x06, 0x58, 0x8b, 0xf5, 0x05, 0xc6, 0x66, 0x07, 0xd4, 0x21, 0xd6,
- 0xe4, 0xa4, 0x33, 0x11, 0x1d, 0x18, 0x23, 0x78, 0xac, 0x22, 0x3f, 0x5e,
- 0xe6, 0x6e, 0xdf, 0x62, 0xd8, 0xbb, 0x9b, 0xf5, 0x26, 0xc4, 0xfe, 0xce,
- 0x1b, 0xc5, 0xed, 0xb5, 0x88, 0xc6, 0x96, 0x29, 0xb7, 0x7b, 0xb1, 0xc9,
- 0x7b, 0x07, 0xeb, 0xc7, 0xe5, 0xa8, 0x39, 0xf2, 0x92, 0xee, 0x83, 0x7f,
- 0x51, 0xa7, 0xbe, 0xfb, 0x31, 0xba, 0xc0, 0x96, 0x2b, 0xca, 0x9e, 0x7f,
- 0xb1, 0xc5, 0xbb, 0x93, 0xb1, 0x59, 0x45, 0x13, 0x35, 0x2e, 0x26, 0xbd,
- 0xd2, 0xf3, 0x35, 0x2d, 0x6e, 0x22, 0x7f, 0xe2, 0xa3, 0x99, 0xd6, 0xcd,
- 0xf4, 0x87, 0xf0, 0x22, 0x3a, 0x99, 0xe6, 0x5e, 0x26, 0xcd, 0xfe, 0x10,
- 0x31, 0xec, 0x81, 0x8d, 0x3e, 0xe6, 0x29, 0xd1, 0x25, 0xf5, 0x98, 0x2f,
- 0xc9, 0x24, 0x75, 0xf9, 0x68, 0xeb, 0xe2, 0x29, 0xa9, 0xcb, 0xa9, 0xd6,
- 0xcc, 0x29, 0x0d, 0xef, 0xb0, 0xb6, 0xac, 0x8d, 0xab, 0xfa, 0x39, 0x25,
- 0x12, 0xba, 0x48, 0x59, 0x5c, 0xf8, 0x85, 0xb9, 0x57, 0x8b, 0x16, 0x6e,
- 0x61, 0x3c, 0x55, 0x33, 0x37, 0x86, 0x98, 0xf3, 0xab, 0x17, 0xa9, 0x98,
- 0x45, 0xa7, 0x1b, 0x15, 0x21, 0x78, 0xa2, 0x1a, 0xde, 0x3d, 0x19, 0xa3,
- 0x1e, 0xae, 0xd1, 0x3c, 0x48, 0xa8, 0x35, 0xc8, 0x52, 0xf8, 0xd8, 0x33,
- 0xf4, 0xc5, 0x71, 0xae, 0x5b, 0xb6, 0x28, 0x3c, 0xcb, 0xf3, 0x41, 0x3e,
- 0x7f, 0x7d, 0xed, 0x6a, 0xae, 0xfd, 0xd1, 0x29, 0xf1, 0xd7, 0x54, 0xeb,
- 0x85, 0x93, 0xf6, 0xda, 0xd1, 0x78, 0x0c, 0x1f, 0x9e, 0x54, 0x87, 0xdf,
- 0x55, 0x22, 0x03, 0x17, 0x14, 0x59, 0x1f, 0x75, 0x55, 0xb8, 0x62, 0x8e,
- 0x46, 0xa3, 0xa9, 0xbd, 0xa4, 0xd9, 0xb2, 0x89, 0xfa, 0xb7, 0xf8, 0xa0,
- 0xcf, 0x33, 0xcf, 0xba, 0xc9, 0x8f, 0xcd, 0x4b, 0x1d, 0x69, 0x9f, 0x2c,
- 0xf6, 0x6a, 0xec, 0x53, 0xaf, 0xf3, 0x13, 0xa4, 0x1e, 0x3c, 0xbb, 0x9b,
- 0x7d, 0xa8, 0xb5, 0x9e, 0x0b, 0xf0, 0x39, 0xd1, 0xc3, 0x2f, 0x15, 0x87,
- 0xf6, 0x1e, 0xf3, 0x98, 0xe4, 0x92, 0x20, 0x73, 0xd8, 0x3d, 0xd2, 0xd3,
- 0xa6, 0xd3, 0xf4, 0x77, 0x37, 0xfd, 0x7d, 0x9b, 0xf8, 0xb4, 0x41, 0x9f,
- 0x36, 0xe8, 0xd3, 0x86, 0x1a, 0x1a, 0x46, 0x24, 0x30, 0x48, 0xbb, 0x25,
- 0x43, 0xe2, 0xeb, 0x7d, 0xd8, 0xc7, 0xdf, 0xfd, 0xbc, 0x7f, 0x94, 0x7d,
- 0x2e, 0x56, 0xc8, 0x9a, 0x87, 0xd1, 0x6e, 0x3c, 0x86, 0xa1, 0x2c, 0x7e,
- 0xe5, 0x6d, 0x2e, 0x47, 0xf9, 0x1a, 0xe9, 0xe1, 0xd5, 0xc0, 0x31, 0x3c,
- 0xc6, 0x3e, 0xea, 0x97, 0x4a, 0xa5, 0xe6, 0xea, 0x3d, 0xae, 0xa8, 0x81,
- 0x76, 0xf6, 0xc3, 0x7b, 0xf3, 0xf7, 0xd0, 0xbe, 0x91, 0xa1, 0x57, 0x14,
- 0xf6, 0x52, 0xb5, 0x5c, 0x9b, 0xb1, 0x74, 0x27, 0xd7, 0x31, 0x84, 0x0f,
- 0x2b, 0xdf, 0xfe, 0x1e, 0x44, 0xb7, 0x3f, 0x6a, 0x18, 0xe4, 0xfa, 0x36,
- 0x1f, 0xa3, 0xec, 0x29, 0x07, 0x19, 0x63, 0xfb, 0xac, 0xf8, 0xea, 0x23,
- 0x8d, 0xeb, 0x79, 0x6c, 0x6b, 0x46, 0x6a, 0xa9, 0x89, 0xc7, 0x75, 0x13,
- 0xcf, 0xf2, 0x77, 0x89, 0xb9, 0x6c, 0xec, 0x86, 0x5c, 0xe6, 0xe0, 0x73,
- 0xbb, 0xf9, 0x5c, 0x0b, 0x53, 0xe7, 0xc2, 0x9c, 0xcc, 0x06, 0x0f, 0xcb,
- 0x6c, 0x10, 0x39, 0x43, 0x74, 0x3f, 0x8c, 0x0b, 0x99, 0x48, 0xca, 0xe9,
- 0x34, 0x47, 0x18, 0x57, 0x4b, 0x1f, 0xd1, 0x77, 0x5f, 0xdf, 0xa8, 0xf6,
- 0x52, 0x87, 0xb1, 0x49, 0x45, 0x0d, 0xbd, 0x86, 0x42, 0xa7, 0x07, 0x8d,
- 0xe1, 0x75, 0xce, 0x68, 0xe0, 0x2c, 0xd4, 0xc2, 0x20, 0x25, 0x7d, 0x3a,
- 0x6f, 0xe7, 0xba, 0xcd, 0xc5, 0x5c, 0xd7, 0x92, 0xab, 0x50, 0xee, 0xcc,
- 0xb2, 0x3e, 0xcf, 0x99, 0x69, 0x3f, 0xeb, 0x55, 0x7e, 0x4e, 0x68, 0x8f,
- 0xa0, 0x31, 0x2e, 0xb4, 0xb4, 0xae, 0x49, 0x05, 0x5f, 0xaf, 0x44, 0x94,
- 0xb5, 0x0a, 0x7a, 0xb9, 0x96, 0x36, 0x59, 0x93, 0x02, 0xee, 0x84, 0xd4,
- 0xce, 0x1e, 0xf6, 0x2d, 0x7d, 0xcc, 0x8b, 0x82, 0xa9, 0x65, 0x5e, 0x6a,
- 0xe7, 0xa3, 0x6d, 0x79, 0xb1, 0x8b, 0xd8, 0x44, 0x6c, 0x73, 0x18, 0x07,
- 0xac, 0x79, 0xb4, 0x89, 0x69, 0x5d, 0x72, 0x83, 0xd8, 0xe9, 0x30, 0xf6,
- 0xe7, 0xdd, 0xb8, 0x97, 0x79, 0x70, 0xbe, 0x99, 0xba, 0xf2, 0xbb, 0x31,
- 0x38, 0x77, 0x3b, 0xf6, 0x65, 0x65, 0x9e, 0xe0, 0xa6, 0xfd, 0x92, 0xc4,
- 0x40, 0xcc, 0x3a, 0xc4, 0x3f, 0x65, 0x5a, 0x49, 0xa7, 0x42, 0x5b, 0x74,
- 0x5a, 0xfa, 0xbe, 0xe0, 0xb6, 0x75, 0x6c, 0xcf, 0x2d, 0x9d, 0x09, 0x59,
- 0xab, 0x34, 0xb3, 0xb4, 0xf5, 0xda, 0x99, 0x91, 0x35, 0x4d, 0x9c, 0xd5,
- 0x6d, 0x4c, 0x5b, 0xd2, 0x67, 0x88, 0x32, 0xd7, 0x6c, 0x02, 0xd6, 0xdd,
- 0x80, 0x6b, 0x2b, 0x78, 0xad, 0xfb, 0x3a, 0xae, 0xed, 0x17, 0xec, 0x4c,
- 0x5c, 0xdb, 0xb5, 0x83, 0xb8, 0xb6, 0x5e, 0x29, 0x61, 0x5a, 0x99, 0x59,
- 0x94, 0x70, 0x6d, 0x75, 0x31, 0x7f, 0x1f, 0xc6, 0x5e, 0x62, 0x9e, 0xda,
- 0xfa, 0x11, 0x78, 0xd6, 0x3b, 0x3e, 0x73, 0x60, 0x84, 0xbd, 0x4c, 0x19,
- 0xb0, 0xd2, 0xc4, 0x2d, 0x1b, 0xd2, 0x66, 0xb9, 0x56, 0x1f, 0x2e, 0x77,
- 0xc8, 0x4c, 0x3a, 0x9a, 0x1e, 0x63, 0x9e, 0x71, 0xac, 0x57, 0xd3, 0x49,
- 0x78, 0x02, 0x35, 0xda, 0x3d, 0xc5, 0x5e, 0x22, 0xe4, 0xd9, 0x4e, 0x4c,
- 0x14, 0x8d, 0x7f, 0x6a, 0xce, 0x06, 0x85, 0x46, 0xa1, 0xe0, 0x41, 0xf2,
- 0x11, 0x0f, 0x6b, 0xd4, 0xb2, 0x32, 0x81, 0xd7, 0xa3, 0x21, 0xcf, 0xce,
- 0x7c, 0xda, 0xdb, 0xdd, 0x70, 0x0b, 0x7a, 0x4e, 0x49, 0x3d, 0x0a, 0x63,
- 0xc7, 0xa9, 0x76, 0xd6, 0x20, 0x0d, 0x1d, 0x93, 0x5d, 0xec, 0xf1, 0x7a,
- 0x95, 0xde, 0x39, 0xd1, 0xa1, 0xd8, 0x40, 0x0d, 0x84, 0x1d, 0x37, 0xce,
- 0x4c, 0x4b, 0xfd, 0xf2, 0x7b, 0x96, 0x7f, 0x8d, 0xeb, 0x01, 0xea, 0xe7,
- 0xaa, 0x1b, 0x7e, 0x13, 0x67, 0x74, 0xf1, 0x4b, 0x7e, 0x37, 0x92, 0xd8,
- 0xd6, 0x3c, 0x6d, 0xba, 0x34, 0x99, 0x7d, 0x87, 0x2c, 0x9b, 0x6e, 0x65,
- 0x9d, 0x6b, 0x9f, 0xeb, 0xa3, 0x1d, 0x4b, 0x73, 0xee, 0x1b, 0xed, 0xb9,
- 0xc5, 0xbb, 0x8d, 0x39, 0x8f, 0x3d, 0xbc, 0xc7, 0xc3, 0x3c, 0xea, 0x39,
- 0x65, 0x62, 0x4e, 0x7f, 0xcb, 0x7c, 0x5c, 0x73, 0xd1, 0x6e, 0x5f, 0x65,
- 0x4e, 0x16, 0xcc, 0x92, 0xf0, 0xde, 0x31, 0xe3, 0x72, 0x54, 0x25, 0xd0,
- 0x5c, 0x46, 0x7f, 0xbc, 0x18, 0xb7, 0xe7, 0x91, 0xc7, 0x73, 0xb7, 0x7b,
- 0xbb, 0xb3, 0xec, 0x33, 0xd8, 0x07, 0xdb, 0xbd, 0xdf, 0x57, 0xbd, 0x7b,
- 0xb2, 0x4e, 0xa5, 0x36, 0x01, 0x67, 0xcb, 0x26, 0x13, 0x1f, 0x6f, 0x88,
- 0xa6, 0x42, 0x0e, 0xe6, 0x4f, 0xd2, 0x32, 0x72, 0xcd, 0xde, 0x7e, 0xe6,
- 0xeb, 0x9d, 0x59, 0xba, 0x01, 0x7d, 0xc7, 0xbf, 0x61, 0x74, 0xc0, 0x0f,
- 0x99, 0xb3, 0xe1, 0xeb, 0x8c, 0xd8, 0x20, 0xfd, 0x31, 0xd4, 0xa6, 0x44,
- 0x97, 0x87, 0x10, 0x5d, 0xfa, 0xd8, 0xf9, 0x96, 0xf9, 0x64, 0x6e, 0x13,
- 0x9f, 0xef, 0x62, 0x2e, 0x4d, 0x32, 0xb7, 0x8e, 0xa6, 0xdc, 0x90, 0x77,
- 0xd4, 0xfe, 0x37, 0x95, 0x08, 0xe3, 0x00, 0xbf, 0xc3, 0xe7, 0x03, 0x1d,
- 0xcc, 0xa3, 0x73, 0x7a, 0x34, 0xb9, 0x15, 0xe9, 0xae, 0x6a, 0xa8, 0x7a,
- 0x83, 0x22, 0x73, 0x31, 0xb1, 0x43, 0x0c, 0x3f, 0xe1, 0x9a, 0x2e, 0x4d,
- 0xf4, 0xb8, 0x85, 0xbe, 0x48, 0x6c, 0xe0, 0xf8, 0xbc, 0xdf, 0xfd, 0x5e,
- 0x19, 0x2a, 0x56, 0x50, 0xb6, 0x9f, 0x58, 0x39, 0xc7, 0xab, 0x69, 0xf8,
- 0xaf, 0xc4, 0x4e, 0x7f, 0x96, 0x97, 0xf9, 0x67, 0x09, 0x0f, 0x8a, 0x6f,
- 0x64, 0x5a, 0x6f, 0x9d, 0x8d, 0x15, 0xe7, 0xa1, 0x1e, 0x6f, 0xd7, 0x8c,
- 0x89, 0xac, 0xee, 0x87, 0xf4, 0xff, 0xe5, 0xf1, 0x02, 0xd1, 0x41, 0x13,
- 0x3a, 0x78, 0xbd, 0x7d, 0xa6, 0x52, 0x69, 0xcf, 0x9a, 0xf8, 0x33, 0x5d,
- 0x4d, 0xb7, 0x39, 0x19, 0xef, 0xba, 0x7a, 0x16, 0xf8, 0x19, 0x71, 0x94,
- 0xf8, 0x98, 0x0b, 0x3e, 0xcd, 0xa6, 0xd5, 0x34, 0x7b, 0x3b, 0xb1, 0x85,
- 0xc4, 0x9f, 0x73, 0x6d, 0x05, 0x9a, 0x95, 0x59, 0x97, 0xe8, 0xad, 0x0b,
- 0xc9, 0x7c, 0xa5, 0xb2, 0x8b, 0xba, 0xbc, 0x73, 0xbd, 0x17, 0x97, 0x2c,
- 0x5d, 0xde, 0x4e, 0x5d, 0xe2, 0x8d, 0xd5, 0x70, 0x5e, 0xa8, 0x05, 0xc1,
- 0x44, 0xb9, 0x1a, 0x1e, 0x70, 0x88, 0x4d, 0x18, 0x27, 0x82, 0xd5, 0x50,
- 0xc9, 0x7a, 0x9e, 0x24, 0x0e, 0x26, 0x6e, 0x0c, 0xf4, 0xe1, 0xdb, 0xcc,
- 0x4b, 0x8f, 0xd3, 0x6f, 0x7f, 0xa1, 0x35, 0xa1, 0xe2, 0x3b, 0xcd, 0xb4,
- 0xe9, 0x26, 0xef, 0xf6, 0x6c, 0x3f, 0x9e, 0x58, 0x30, 0xf1, 0x0c, 0x63,
- 0xa6, 0x21, 0x9e, 0x0e, 0x94, 0xb3, 0xaf, 0x63, 0xed, 0x5b, 0x3e, 0x61,
- 0xf9, 0xfc, 0x68, 0xeb, 0x96, 0xf9, 0x10, 0x9c, 0xdf, 0xb6, 0xf6, 0x7e,
- 0x5a, 0xc3, 0xf3, 0xd6, 0xde, 0x0f, 0x3f, 0x4d, 0x0c, 0xeb, 0x6a, 0xf2,
- 0x63, 0x67, 0x05, 0x2a, 0xa3, 0xa6, 0x39, 0x1c, 0xb7, 0xf6, 0x1f, 0x5a,
- 0x63, 0xd6, 0xfd, 0xa3, 0xfc, 0x2c, 0xcd, 0xae, 0xff, 0x46, 0x30, 0x63,
- 0x38, 0x49, 0xf9, 0x77, 0x10, 0x07, 0xf4, 0x13, 0x07, 0xd4, 0x26, 0xd4,
- 0xe4, 0x6e, 0xa7, 0xcc, 0x69, 0x0a, 0x87, 0xaa, 0x79, 0xfd, 0x8e, 0x22,
- 0x0e, 0xa8, 0x3a, 0x25, 0xb3, 0x3f, 0x62, 0x45, 0xd8, 0x7b, 0x26, 0x3d,
- 0xc4, 0x01, 0x15, 0x93, 0x2e, 0x74, 0x13, 0x03, 0xb8, 0x89, 0xd9, 0xb7,
- 0xe5, 0x6a, 0xe1, 0x3d, 0xe1, 0x44, 0x24, 0xfe, 0x23, 0x1c, 0xa2, 0xbf,
- 0x1d, 0x8a, 0x79, 0x94, 0xf0, 0x2a, 0x07, 0x75, 0xf6, 0x2b, 0x1c, 0x0c,
- 0x38, 0x51, 0xa5, 0xbd, 0x86, 0x07, 0xbf, 0xa0, 0xf6, 0xf7, 0x67, 0x25,
- 0xce, 0x47, 0x5b, 0xbb, 0x4f, 0xd9, 0xb5, 0xdf, 0x77, 0x6a, 0x74, 0x59,
- 0x6a, 0x7f, 0xed, 0x86, 0x7e, 0x9c, 0x9e, 0xc1, 0x37, 0x57, 0x13, 0x64,
- 0xd6, 0x72, 0xcd, 0xfa, 0x78, 0x94, 0x3d, 0xb8, 0x3a, 0xd4, 0xa1, 0x44,
- 0x27, 0xaa, 0x98, 0x0f, 0x4e, 0xb3, 0xf6, 0x7b, 0x12, 0xd1, 0x40, 0xcc,
- 0x81, 0x1e, 0x37, 0x6d, 0xf3, 0x3e, 0xfb, 0xf1, 0x9f, 0xe6, 0xc2, 0xa4,
- 0x59, 0x06, 0x17, 0x6b, 0xff, 0xfb, 0x1a, 0x3e, 0x73, 0xd2, 0x0f, 0xdf,
- 0x71, 0x7a, 0x70, 0x35, 0x67, 0xd7, 0xfe, 0xea, 0x06, 0x73, 0xe4, 0x72,
- 0xdc, 0x87, 0x2b, 0x39, 0x9d, 0xfe, 0xd8, 0x8f, 0xa3, 0xac, 0xfd, 0x97,
- 0xb5, 0x00, 0x3e, 0xcc, 0xb5, 0xd0, 0x47, 0x83, 0xf8, 0x39, 0x71, 0xf2,
- 0x7a, 0xd6, 0xfe, 0xbb, 0xe8, 0x5f, 0x71, 0xd6, 0xfe, 0x36, 0x0b, 0x97,
- 0x64, 0x5a, 0xcf, 0x4c, 0x5b, 0xb5, 0xbf, 0xc1, 0xc1, 0xba, 0xe9, 0x46,
- 0x74, 0x99, 0x39, 0xc3, 0xfc, 0xc5, 0x26, 0x1f, 0x9f, 0xa5, 0xde, 0xf2,
- 0x1b, 0x30, 0x6b, 0xd5, 0xaa, 0x2d, 0xde, 0x5d, 0x5c, 0x7b, 0xa5, 0x15,
- 0x73, 0x26, 0x76, 0xac, 0xff, 0x6b, 0xfc, 0x41, 0x8d, 0x83, 0x3e, 0x99,
- 0xf0, 0xde, 0xc9, 0xb8, 0xf3, 0x27, 0x4a, 0xb3, 0x91, 0x18, 0xd7, 0xb9,
- 0xdd, 0x7b, 0x17, 0xfd, 0xe4, 0x96, 0xf5, 0xcc, 0x2a, 0x01, 0x3b, 0xe6,
- 0xda, 0x19, 0x73, 0x21, 0xc6, 0xdc, 0x6a, 0xc6, 0xdc, 0x93, 0x7a, 0x34,
- 0xb6, 0x85, 0xf8, 0xec, 0x95, 0x9c, 0xc4, 0x5d, 0x33, 0xe9, 0xaa, 0x94,
- 0x6b, 0x74, 0x40, 0xe2, 0x67, 0xc7, 0xfa, 0xd1, 0xb3, 0x95, 0x10, 0x5d,
- 0xe1, 0xb3, 0x95, 0xc4, 0x22, 0xcc, 0x52, 0x4b, 0xcb, 0xce, 0x68, 0xea,
- 0x36, 0x67, 0x74, 0xf8, 0x3d, 0xe5, 0x2d, 0xf3, 0x0d, 0xc6, 0xdc, 0x4e,
- 0xc6, 0xdc, 0x2e, 0xc6, 0x5c, 0x9b, 0x61, 0xe2, 0x85, 0xb8, 0xda, 0xdf,
- 0xe4, 0x88, 0xe8, 0x6d, 0x0e, 0xac, 0xae, 0x64, 0x09, 0xf1, 0x22, 0xda,
- 0xf5, 0x07, 0xe4, 0x7f, 0x49, 0x8f, 0xf6, 0xc6, 0x14, 0x89, 0xb3, 0x30,
- 0x3e, 0xa0, 0xdc, 0xe5, 0xc5, 0x38, 0x3b, 0x30, 0x77, 0xbe, 0xe8, 0x1b,
- 0x25, 0xd9, 0x9d, 0x78, 0x5e, 0x67, 0x5e, 0x5d, 0x21, 0xbe, 0xdb, 0x87,
- 0x09, 0xea, 0xd1, 0x1b, 0xed, 0xc3, 0x31, 0xd6, 0xcd, 0xfb, 0x58, 0xaf,
- 0xef, 0x37, 0x22, 0x2d, 0xdb, 0xd9, 0x27, 0x5d, 0x0a, 0xa9, 0xe1, 0xb0,
- 0xd2, 0x87, 0x41, 0xfa, 0xf0, 0x20, 0xeb, 0x4b, 0x9b, 0xf1, 0x4b, 0xa5,
- 0x83, 0x98, 0x62, 0x7f, 0x5e, 0xde, 0x53, 0x63, 0x69, 0xc7, 0x10, 0x06,
- 0x16, 0x24, 0xcf, 0x21, 0x70, 0x53, 0xa2, 0x0f, 0x53, 0x46, 0x19, 0xfa,
- 0x9a, 0x7b, 0x94, 0x3b, 0xf2, 0x32, 0xa7, 0x63, 0x6c, 0x1a, 0x8c, 0x5d,
- 0x8b, 0x5f, 0x05, 0xb9, 0x68, 0x0f, 0x32, 0x12, 0xab, 0xc6, 0x2e, 0xe5,
- 0xae, 0x39, 0x89, 0xf7, 0x3e, 0xa5, 0x4f, 0xe2, 0xd9, 0x48, 0x29, 0x77,
- 0x4b, 0x7c, 0x5b, 0xb3, 0x6d, 0xc9, 0x01, 0xb2, 0xf7, 0x71, 0x3b, 0xf1,
- 0x1e, 0x18, 0x5f, 0xce, 0xef, 0x84, 0x18, 0x83, 0x6d, 0x65, 0x0e, 0xfa,
- 0x69, 0x84, 0xb6, 0x73, 0xa0, 0x5d, 0xff, 0xb2, 0x99, 0x0e, 0x0c, 0x30,
- 0xa6, 0xfa, 0x70, 0xd4, 0x08, 0x99, 0x97, 0x2d, 0x1c, 0x53, 0xca, 0xf1,
- 0x5b, 0x58, 0xeb, 0x56, 0xc1, 0xa3, 0x49, 0x7d, 0xf7, 0x21, 0x56, 0xe3,
- 0x41, 0x85, 0x26, 0xb5, 0x27, 0xd3, 0xba, 0x78, 0x42, 0x91, 0x3e, 0xa5,
- 0x18, 0xeb, 0x5b, 0xf0, 0x00, 0x73, 0xc2, 0xbe, 0xf8, 0xbd, 0xb8, 0x3f,
- 0x50, 0x01, 0x3f, 0xf5, 0xf4, 0x50, 0xc0, 0xc7, 0x5c, 0xfb, 0x7b, 0x45,
- 0x3a, 0x7f, 0x51, 0x56, 0xec, 0xbf, 0xaf, 0x61, 0xb0, 0x5a, 0xc6, 0xd8,
- 0xe6, 0x19, 0x99, 0x27, 0xa5, 0x5a, 0x43, 0x33, 0x1a, 0xfc, 0xec, 0x7b,
- 0xb7, 0xc4, 0xd5, 0xd4, 0x16, 0x67, 0x44, 0x7a, 0x9a, 0x8c, 0x9f, 0xf8,
- 0x2f, 0x17, 0x8d, 0xf6, 0x36, 0x89, 0x8e, 0xb5, 0x10, 0x3a, 0xa9, 0xa7,
- 0xee, 0x5c, 0x90, 0x31, 0xe4, 0x28, 0x17, 0x2c, 0x95, 0xcc, 0x5d, 0xa7,
- 0x15, 0x22, 0xad, 0xd0, 0x8c, 0xe0, 0xba, 0x14, 0x71, 0x9d, 0xc6, 0x38,
- 0x34, 0xcd, 0xcd, 0xc4, 0x73, 0xbe, 0x53, 0x32, 0x97, 0x8a, 0x4c, 0x10,
- 0x03, 0x37, 0x11, 0x1f, 0xf7, 0xd1, 0xab, 0xcd, 0x5b, 0xea, 0xa3, 0x7a,
- 0x9b, 0x82, 0xc7, 0xe6, 0x9b, 0xe1, 0x71, 0x92, 0xe6, 0x3b, 0xb9, 0x00,
- 0x2e, 0xe7, 0x42, 0x78, 0x9b, 0xb4, 0x2f, 0x59, 0xb4, 0xeb, 0xf0, 0xb3,
- 0x62, 0x0e, 0x8b, 0x33, 0x87, 0x6d, 0xcd, 0x2a, 0xf4, 0xd7, 0x30, 0x46,
- 0xf4, 0xbf, 0xfa, 0xec, 0xd2, 0xcd, 0x1e, 0xea, 0x4d, 0x64, 0x71, 0xf1,
- 0x73, 0x1c, 0x0f, 0x59, 0x39, 0xfb, 0xb5, 0xcf, 0x66, 0x6b, 0x68, 0x2b,
- 0xea, 0xbe, 0xba, 0xf8, 0xde, 0xba, 0xd9, 0x3f, 0x2f, 0xca, 0xdb, 0x53,
- 0xb4, 0x35, 0x71, 0x9b, 0x71, 0x9e, 0xd7, 0x04, 0x47, 0x69, 0x70, 0x9c,
- 0x8a, 0xa1, 0xec, 0xd4, 0x35, 0xfe, 0x35, 0x89, 0x19, 0x56, 0xde, 0xc7,
- 0xbe, 0x4b, 0x9e, 0x1e, 0x21, 0x5e, 0x34, 0xc9, 0xd3, 0x55, 0x8b, 0x97,
- 0x20, 0x79, 0xf9, 0xe4, 0xb3, 0x12, 0xb6, 0x0c, 0x5d, 0x7b, 0x27, 0x40,
- 0x7d, 0xe0, 0xd1, 0x10, 0xf5, 0x79, 0x65, 0xa3, 0x3c, 0xe7, 0xc3, 0x1d,
- 0xb9, 0x44, 0xb9, 0xe4, 0x79, 0xaf, 0xb6, 0x05, 0x7b, 0xe7, 0x3e, 0xaf,
- 0xf7, 0x20, 0x6d, 0x11, 0xa0, 0xf1, 0xe4, 0xde, 0x17, 0xd5, 0xd4, 0x3f,
- 0x42, 0x8a, 0x3d, 0xd3, 0x23, 0xd9, 0x34, 0x1e, 0xca, 0x7e, 0xcb, 0xda,
- 0xcb, 0x5b, 0xb7, 0x01, 0xfb, 0x49, 0xff, 0x60, 0x35, 0xe3, 0xe8, 0x7f,
- 0xc4, 0xa3, 0x82, 0xa5, 0x76, 0x55, 0x42, 0xea, 0x6e, 0xb4, 0xe5, 0x36,
- 0xc5, 0x44, 0x59, 0x1c, 0xc3, 0xed, 0xcd, 0xd1, 0xd8, 0x65, 0x3c, 0x66,
- 0xca, 0x5c, 0xdc, 0x59, 0xac, 0xc1, 0xc4, 0xaf, 0x4a, 0x3b, 0xeb, 0x70,
- 0x5b, 0x11, 0x53, 0x6d, 0xcd, 0xbf, 0xf5, 0xb9, 0xd9, 0x83, 0xf4, 0xed,
- 0x52, 0x7b, 0xbc, 0x4a, 0x1b, 0xd7, 0x39, 0xca, 0x9c, 0xfd, 0xbc, 0xfe,
- 0x52, 0x88, 0x95, 0x19, 0xae, 0xf5, 0x0a, 0x0e, 0x11, 0x3f, 0xa5, 0x83,
- 0x26, 0x76, 0xf1, 0xf3, 0x00, 0x71, 0xd6, 0xbb, 0x7a, 0x15, 0x66, 0x03,
- 0x01, 0x62, 0x4b, 0xe6, 0x60, 0xc7, 0xdf, 0x49, 0x4d, 0x88, 0x85, 0x1d,
- 0xb2, 0x57, 0xff, 0x6f, 0xed, 0xdf, 0xac, 0x27, 0x96, 0x11, 0xd9, 0xbd,
- 0x0a, 0x73, 0x68, 0x0c, 0xc4, 0x37, 0x7b, 0xf5, 0x42, 0xd8, 0x81, 0xe4,
- 0x55, 0x07, 0xd4, 0xd3, 0xef, 0xb0, 0x1f, 0x7c, 0xa4, 0x5e, 0x3d, 0xdd,
- 0xea, 0xd4, 0x90, 0x9a, 0xf2, 0xe0, 0xe1, 0xa9, 0x0e, 0x54, 0x5b, 0x73,
- 0xa4, 0x71, 0xda, 0xcc, 0xc1, 0x3e, 0x6c, 0xf4, 0x53, 0x17, 0xfb, 0xb1,
- 0xab, 0x1b, 0x1e, 0x45, 0x8b, 0x75, 0x7d, 0x0c, 0xfb, 0xb3, 0x5e, 0xa5,
- 0x3b, 0xeb, 0x42, 0xc7, 0x5d, 0x8f, 0xc2, 0xbd, 0x7e, 0x80, 0x7c, 0xc9,
- 0x75, 0xf9, 0xfb, 0x6e, 0xf6, 0x71, 0xc2, 0x5f, 0x19, 0xc2, 0xab, 0xc8,
- 0xdb, 0x7a, 0x0d, 0x23, 0x53, 0x2e, 0x65, 0xb7, 0xf1, 0x37, 0xe6, 0x55,
- 0x6b, 0x6f, 0x48, 0xae, 0x55, 0xc8, 0x99, 0x01, 0x3e, 0x23, 0x39, 0x67,
- 0x10, 0x59, 0xc6, 0xf6, 0xdd, 0xd6, 0xfb, 0xa7, 0xca, 0x6c, 0x99, 0x92,
- 0xec, 0x6f, 0xdb, 0xe9, 0x1f, 0xf2, 0x4c, 0x5b, 0xf1, 0xda, 0x76, 0x8f,
- 0x7d, 0x2e, 0x41, 0xec, 0x3e, 0x88, 0x5b, 0x69, 0x84, 0xfa, 0xa8, 0xf8,
- 0xd8, 0x20, 0xea, 0x73, 0x4c, 0xa8, 0xab, 0x6c, 0x7e, 0x1f, 0x34, 0x0a,
- 0xec, 0x4d, 0x35, 0xe6, 0x4d, 0xea, 0x6e, 0xa5, 0xbc, 0x4f, 0x47, 0xfd,
- 0xb5, 0xf7, 0x4b, 0xf5, 0x54, 0x70, 0xe9, 0x17, 0xdd, 0xff, 0x4d, 0xc8,
- 0x3d, 0x97, 0xf6, 0x87, 0x8c, 0xe3, 0x68, 0x6f, 0xa5, 0x43, 0xfc, 0xe7,
- 0x0f, 0x71, 0xff, 0x1c, 0x1b, 0xd7, 0x0a, 0xa1, 0x4f, 0xdc, 0x6b, 0xb8,
- 0x94, 0x2e, 0xe6, 0x9f, 0x03, 0x53, 0x8e, 0x3b, 0xca, 0xf0, 0xe7, 0x66,
- 0xf9, 0xca, 0x11, 0xd4, 0xc7, 0xc7, 0xf8, 0xbc, 0x82, 0x76, 0x62, 0xc8,
- 0x27, 0xf4, 0xad, 0xe8, 0xa8, 0x91, 0x1c, 0xf0, 0xbc, 0x39, 0xd8, 0x27,
- 0x3a, 0x54, 0xb0, 0x8d, 0xd7, 0x5f, 0xa0, 0x7d, 0x9f, 0xd6, 0x5d, 0xa8,
- 0x5f, 0x21, 0x33, 0x41, 0x75, 0x3a, 0x89, 0x3d, 0x1e, 0x7b, 0x8f, 0x2c,
- 0x6d, 0x56, 0x6b, 0xda, 0xf0, 0x9d, 0x8e, 0xfa, 0xe9, 0x37, 0xe9, 0x4f,
- 0x6d, 0xeb, 0x6f, 0xbc, 0x57, 0xd2, 0x89, 0x8e, 0xd0, 0xfa, 0xe7, 0x4c,
- 0xdc, 0x34, 0x8a, 0xc0, 0xfa, 0x1b, 0xed, 0x5f, 0xe2, 0xfb, 0x30, 0x63,
- 0x10, 0xe9, 0xea, 0x84, 0xcc, 0x89, 0xa2, 0xa4, 0x73, 0x18, 0xbf, 0x9f,
- 0x1f, 0xc3, 0xa1, 0xac, 0xc8, 0xb9, 0x60, 0xf9, 0xb6, 0xb6, 0xfe, 0xba,
- 0x6c, 0x0f, 0x66, 0xa3, 0x03, 0x55, 0x45, 0xd9, 0x0e, 0xb2, 0x1f, 0xa9,
- 0x64, 0x8e, 0x7d, 0x80, 0x3a, 0x1d, 0xb6, 0x74, 0xda, 0x07, 0x3d, 0x77,
- 0x9d, 0xee, 0x10, 0xe9, 0x7a, 0x13, 0xa2, 0x37, 0xd9, 0x97, 0x63, 0x2f,
- 0x40, 0xba, 0xfb, 0x6e, 0xa0, 0x3b, 0xa8, 0x5f, 0xa7, 0xbb, 0x37, 0x1b,
- 0x3d, 0xed, 0x28, 0xd2, 0xfd, 0xc6, 0x5c, 0x89, 0x46, 0x1a, 0x3b, 0xd7,
- 0xa7, 0x91, 0xdb, 0x7c, 0xd0, 0x3c, 0x68, 0xe9, 0xe3, 0xfb, 0xd6, 0xf5,
- 0x6d, 0xf5, 0x12, 0x0f, 0xfc, 0x33, 0xa1, 0x59, 0x67, 0x00, 0x6c, 0x1c,
- 0x76, 0x63, 0x7c, 0xa8, 0x6f, 0x75, 0x3b, 0x93, 0x8c, 0xe3, 0xa0, 0x67,
- 0xfb, 0xe7, 0x66, 0x1f, 0x1d, 0xec, 0xd7, 0x3a, 0x8d, 0x1e, 0x6f, 0x97,
- 0xe1, 0x21, 0x06, 0xab, 0x54, 0xb6, 0x65, 0x65, 0x06, 0x22, 0xb1, 0x5c,
- 0xc4, 0xc5, 0x79, 0xe9, 0x0b, 0xef, 0x61, 0xcf, 0xb0, 0x81, 0xf6, 0x1d,
- 0xc0, 0x44, 0x7e, 0x40, 0x49, 0x06, 0xb9, 0x8e, 0x21, 0x75, 0x05, 0xac,
- 0x79, 0xbd, 0xa8, 0xa4, 0x2f, 0x05, 0x13, 0xd3, 0x89, 0x93, 0xf5, 0x26,
- 0x88, 0x51, 0x3c, 0x2b, 0x12, 0xb3, 0x89, 0x5d, 0xf5, 0x4e, 0x1c, 0xb7,
- 0xb0, 0x98, 0x3a, 0xcb, 0xdf, 0x69, 0x89, 0x99, 0x3b, 0xb3, 0x52, 0xc7,
- 0x08, 0x27, 0xb5, 0x11, 0xfc, 0x63, 0xbc, 0x30, 0x5c, 0x83, 0xe4, 0x7d,
- 0x35, 0x90, 0x1e, 0x63, 0x02, 0x7f, 0xa9, 0x85, 0x3c, 0xfd, 0x79, 0x97,
- 0xd2, 0x6d, 0xcc, 0x7b, 0x77, 0x18, 0x7e, 0xf8, 0xd8, 0xbf, 0xf5, 0x38,
- 0x23, 0xec, 0x39, 0xac, 0x19, 0x7d, 0xeb, 0xad, 0xb9, 0x7e, 0x6f, 0xbb,
- 0x61, 0xe7, 0xc2, 0x5b, 0x66, 0x3d, 0xde, 0x8e, 0x99, 0x48, 0x68, 0xc2,
- 0xc2, 0x62, 0x07, 0x5b, 0x23, 0x39, 0xd3, 0x7c, 0x55, 0x2f, 0x5c, 0x2d,
- 0xb7, 0xbe, 0x4f, 0xb7, 0xc6, 0x72, 0x4d, 0xd8, 0x43, 0xfc, 0xd4, 0x36,
- 0xd3, 0x04, 0x7d, 0x06, 0x38, 0x31, 0x15, 0xc2, 0xba, 0xac, 0x7a, 0x3a,
- 0xe5, 0xec, 0xc7, 0xf4, 0x42, 0x17, 0xb2, 0x79, 0xef, 0x72, 0xd8, 0x41,
- 0x8c, 0x1d, 0x77, 0xe0, 0x0e, 0x7d, 0x83, 0x52, 0xb0, 0x62, 0x5a, 0xc1,
- 0xdd, 0xfa, 0x2e, 0x65, 0xc0, 0xc2, 0x14, 0xf3, 0xc4, 0x22, 0x0a, 0x6e,
- 0xb2, 0x72, 0xef, 0xc9, 0xd6, 0x38, 0xf1, 0xf7, 0x1d, 0x59, 0xa9, 0xef,
- 0x26, 0x2e, 0xc6, 0xa9, 0x97, 0x78, 0xba, 0xdf, 0xcd, 0x7e, 0xe8, 0xa0,
- 0xa2, 0xf6, 0xea, 0x8a, 0x8d, 0xf1, 0x6e, 0x9b, 0xb7, 0x71, 0xe1, 0xad,
- 0xf3, 0xcd, 0x5e, 0xc9, 0x41, 0xed, 0xba, 0x1a, 0x72, 0x39, 0x02, 0x18,
- 0xb6, 0x68, 0xa4, 0x5b, 0xf5, 0xf9, 0x32, 0xac, 0xd6, 0xfa, 0x70, 0xda,
- 0x92, 0x61, 0xa2, 0x75, 0x0b, 0xb1, 0xf6, 0x93, 0x46, 0x3f, 0x7b, 0x65,
- 0xd9, 0x37, 0x8d, 0xc4, 0x5a, 0x9c, 0x6d, 0xc4, 0xb3, 0x91, 0xf0, 0xb2,
- 0x92, 0x54, 0xd2, 0xae, 0xc6, 0xe4, 0x3c, 0x58, 0x51, 0x6a, 0xec, 0xfa,
- 0x26, 0x32, 0x46, 0x89, 0xb3, 0xda, 0xa6, 0xbc, 0xcb, 0x49, 0xd8, 0x73,
- 0x9e, 0x4e, 0xfd, 0xff, 0xe0, 0x52, 0x50, 0x9d, 0x48, 0x92, 0xef, 0x0e,
- 0xe6, 0xdd, 0x42, 0x9f, 0x8b, 0xf7, 0x65, 0xbe, 0x37, 0xdc, 0x3a, 0x9e,
- 0x41, 0xc1, 0x99, 0x90, 0x1e, 0x0b, 0xfe, 0xde, 0x3c, 0x64, 0xd6, 0xc4,
- 0x3e, 0xe3, 0x53, 0xb3, 0xb4, 0xc7, 0xd4, 0x33, 0x63, 0xef, 0x9f, 0x65,
- 0x16, 0x5c, 0xfe, 0x1d, 0x46, 0x33, 0x8e, 0xe7, 0x5d, 0x37, 0xd0, 0x8e,
- 0x4e, 0xdc, 0xe2, 0x70, 0x20, 0xba, 0xfe, 0x6e, 0xa5, 0xb8, 0x07, 0xc5,
- 0x3c, 0x91, 0xb2, 0x6a, 0x62, 0x19, 0xe5, 0xbc, 0x70, 0x52, 0xd6, 0xf8,
- 0x56, 0xeb, 0xf8, 0x49, 0xa9, 0x91, 0xc3, 0xad, 0x21, 0x43, 0xed, 0x95,
- 0x9e, 0xb0, 0x9a, 0x7a, 0xfa, 0x68, 0x52, 0x6a, 0xf0, 0x14, 0x6b, 0xb0,
- 0xba, 0xdc, 0xae, 0x48, 0x1d, 0x53, 0x63, 0x5e, 0xa7, 0x03, 0x57, 0x1a,
- 0xd4, 0xfe, 0x1f, 0x40, 0x1d, 0xb0, 0xe7, 0x8a, 0x8f, 0xb6, 0x36, 0x16,
- 0xf1, 0xf0, 0x6d, 0xf3, 0x83, 0x72, 0xee, 0xc4, 0xd2, 0x71, 0x53, 0x4e,
- 0xb0, 0xb1, 0x69, 0xbe, 0x1c, 0xef, 0x21, 0x6e, 0x10, 0x6c, 0x2c, 0xd7,
- 0x27, 0x5b, 0x1b, 0x66, 0x3d, 0xe4, 0x4d, 0xc1, 0x7b, 0x5a, 0x0f, 0x7d,
- 0xaf, 0xc4, 0xa3, 0x8d, 0x9b, 0xb7, 0x13, 0x37, 0x3b, 0x13, 0x6a, 0xcb,
- 0x56, 0xe2, 0x66, 0x8d, 0xfd, 0x84, 0x0b, 0x7d, 0x78, 0xc2, 0xb0, 0x7b,
- 0x0a, 0xc1, 0xce, 0xe6, 0x49, 0x35, 0x29, 0xb8, 0xf9, 0xea, 0x06, 0x60,
- 0x37, 0x71, 0xf3, 0x72, 0xc6, 0x85, 0x7e, 0xe2, 0xe6, 0x8f, 0x98, 0x82,
- 0xee, 0x24, 0x6e, 0xbe, 0x42, 0x8c, 0x75, 0x3e, 0xfe, 0x73, 0x7c, 0xa3,
- 0x38, 0x3b, 0xdb, 0x4b, 0xec, 0x9c, 0x0c, 0xde, 0x88, 0x9d, 0xff, 0xe2,
- 0x5f, 0x60, 0xe7, 0x3d, 0xc4, 0x84, 0x3d, 0x59, 0xd9, 0x67, 0x1a, 0x6d,
- 0x7d, 0xe3, 0x94, 0x9c, 0x6d, 0xb9, 0x0d, 0xef, 0x9e, 0x1c, 0x1d, 0x22,
- 0x56, 0xc6, 0x58, 0xbc, 0x1f, 0x99, 0x19, 0xac, 0x22, 0x2e, 0x78, 0xd9,
- 0xc9, 0x75, 0xd7, 0xc5, 0x55, 0xfd, 0x4d, 0x25, 0xda, 0xd5, 0x8f, 0x28,
- 0xfb, 0x66, 0x75, 0x99, 0x26, 0x4c, 0xba, 0x12, 0xc4, 0xc6, 0xac, 0x81,
- 0xab, 0x89, 0x9d, 0xab, 0x16, 0x81, 0xda, 0x45, 0x1b, 0x3b, 0xcb, 0xdc,
- 0xac, 0x2a, 0x8a, 0x3f, 0x22, 0x76, 0x66, 0xaf, 0xcb, 0x50, 0x5b, 0x6c,
- 0x62, 0x8c, 0x2a, 0x38, 0x1a, 0xf5, 0xa1, 0x67, 0x8a, 0xb8, 0xc7, 0x9a,
- 0x9b, 0x99, 0x23, 0x3f, 0xd6, 0xfb, 0x71, 0x6c, 0xc1, 0x9e, 0x9b, 0x75,
- 0x12, 0xbf, 0xb9, 0xa2, 0x41, 0x94, 0x2f, 0xba, 0xf0, 0x1c, 0xf1, 0xf3,
- 0x36, 0xda, 0xf9, 0x0c, 0xf1, 0xf3, 0x9e, 0x1b, 0x66, 0x67, 0xb3, 0x8b,
- 0x78, 0x95, 0x58, 0xbe, 0xae, 0x16, 0x51, 0x99, 0x8b, 0x98, 0x57, 0x36,
- 0xfa, 0x70, 0xce, 0xc2, 0xcf, 0xde, 0xe5, 0xb4, 0x62, 0xcb, 0x56, 0x46,
- 0x5b, 0x88, 0x5d, 0x1d, 0xb4, 0x6b, 0xdb, 0x49, 0xb5, 0xeb, 0x25, 0xea,
- 0xa2, 0x31, 0x7a, 0xde, 0xb2, 0xc7, 0x60, 0x5c, 0x66, 0x2c, 0x43, 0xad,
- 0x72, 0xfe, 0xaa, 0x82, 0xf6, 0xee, 0x9e, 0x8c, 0x24, 0x3f, 0x80, 0x1d,
- 0x93, 0xb1, 0x5c, 0x59, 0xb1, 0x1e, 0xca, 0xbd, 0x09, 0xde, 0x4b, 0xa2,
- 0x6b, 0xa3, 0xed, 0xdf, 0xb1, 0xdc, 0x71, 0x62, 0x57, 0xd9, 0x5b, 0x0d,
- 0xf8, 0x3b, 0x8d, 0x2e, 0x4c, 0x1b, 0x61, 0x94, 0x9f, 0x2b, 0xee, 0xd1,
- 0x9e, 0x93, 0x33, 0x7b, 0x8f, 0xb6, 0x06, 0xbe, 0x53, 0xc2, 0x84, 0x49,
- 0xe2, 0xbb, 0xa0, 0xe7, 0x8e, 0xbc, 0xe0, 0xc5, 0x5e, 0x1c, 0x33, 0xd4,
- 0xd0, 0x4f, 0x18, 0x13, 0xf7, 0xc9, 0xfe, 0xfc, 0x0d, 0x33, 0xaa, 0x87,
- 0x79, 0xcf, 0xf8, 0xdc, 0x8c, 0x2a, 0x95, 0xc5, 0xaf, 0x9c, 0xcd, 0xe5,
- 0x70, 0xac, 0x93, 0x19, 0x89, 0x1a, 0x1a, 0xc3, 0x63, 0xc4, 0x1c, 0xbf,
- 0x54, 0x7c, 0x9a, 0x6b, 0xa8, 0xc9, 0xa9, 0x86, 0xe6, 0x15, 0x1f, 0xdf,
- 0xbd, 0x87, 0xf9, 0xed, 0x1e, 0xfa, 0x46, 0x64, 0xb9, 0x42, 0x71, 0xe2,
- 0xd2, 0x97, 0x2d, 0x3c, 0xea, 0xed, 0xe5, 0xb5, 0xe9, 0x7c, 0x09, 0xd7,
- 0xf4, 0x09, 0xaf, 0xe8, 0x9c, 0xb2, 0x73, 0x88, 0x96, 0xf3, 0x2e, 0x5f,
- 0x82, 0x2d, 0x5b, 0x25, 0x65, 0x7d, 0x60, 0x32, 0x60, 0x0e, 0xac, 0x94,
- 0x18, 0xd6, 0xb0, 0xd3, 0x10, 0xff, 0x1a, 0x24, 0x9f, 0x7d, 0x38, 0x62,
- 0xac, 0x66, 0xef, 0x26, 0xf3, 0xd2, 0x26, 0x62, 0xeb, 0x5e, 0xd6, 0x60,
- 0xd3, 0x4c, 0xe9, 0x69, 0xb3, 0x69, 0x93, 0xa6, 0xe7, 0x94, 0x42, 0x4d,
- 0x88, 0xf8, 0x66, 0x3d, 0x6b, 0x77, 0x5b, 0xbe, 0x09, 0x6f, 0x9e, 0xd1,
- 0xe8, 0x9b, 0xed, 0xc4, 0xef, 0xbd, 0xb8, 0x97, 0xf2, 0x7c, 0x23, 0xff,
- 0x4d, 0x24, 0xbf, 0xee, 0xc2, 0xc4, 0x54, 0x12, 0x5b, 0xd6, 0x8f, 0xe0,
- 0xd2, 0xef, 0x78, 0x98, 0xab, 0x7c, 0x78, 0x72, 0x4a, 0xf2, 0x6b, 0x09,
- 0x6f, 0xdf, 0x88, 0x45, 0x3c, 0x08, 0x5b, 0x38, 0xe4, 0x8b, 0xef, 0xd9,
- 0x18, 0xc5, 0xcb, 0x5e, 0xb8, 0xf4, 0x3e, 0xf3, 0xd0, 0xfa, 0x7f, 0x81,
- 0x67, 0x88, 0x5b, 0x88, 0x05, 0x2a, 0x62, 0xd6, 0xf9, 0xb8, 0x12, 0xde,
- 0x75, 0xd1, 0x07, 0x24, 0xa6, 0x57, 0x33, 0xd6, 0x4d, 0x62, 0xe7, 0xe5,
- 0xe2, 0xfc, 0xf2, 0xed, 0x93, 0xea, 0xd2, 0x11, 0x44, 0x88, 0xa1, 0x31,
- 0x28, 0xd8, 0xcd, 0x49, 0xbc, 0x7b, 0x25, 0x1a, 0xd5, 0xcf, 0x11, 0xef,
- 0x8e, 0xd2, 0xd6, 0x2e, 0x4d, 0x7c, 0x33, 0x80, 0xb2, 0xc5, 0x10, 0x7d,
- 0x52, 0xe6, 0x97, 0x7f, 0xe5, 0xb5, 0xe7, 0x97, 0x32, 0x33, 0x97, 0xf3,
- 0x23, 0xe8, 0x28, 0x63, 0xef, 0x56, 0xae, 0xa4, 0x99, 0x93, 0x67, 0xbd,
- 0xbb, 0x99, 0xdf, 0xfb, 0x8d, 0xa0, 0x7f, 0x77, 0x3e, 0xc0, 0xdf, 0x3a,
- 0x7f, 0x7f, 0x7e, 0x07, 0x9f, 0x0f, 0xf1, 0x33, 0x8c, 0x6c, 0x2e, 0x52,
- 0x21, 0xcd, 0x40, 0x36, 0x67, 0xe7, 0xbc, 0x70, 0xee, 0x90, 0x57, 0xb0,
- 0x66, 0xdb, 0x94, 0xfd, 0x5d, 0xbb, 0xe1, 0xfb, 0xe7, 0x31, 0xbf, 0x9b,
- 0x7c, 0x9f, 0x39, 0xa9, 0xe1, 0xa3, 0x93, 0x16, 0xe6, 0x2f, 0x10, 0xf3,
- 0x0f, 0xbb, 0x9d, 0x82, 0x35, 0x7f, 0x61, 0x9e, 0x8f, 0x46, 0x07, 0xe6,
- 0xe8, 0x07, 0x3d, 0xa4, 0xeb, 0xd0, 0x82, 0x16, 0xbf, 0x36, 0x9f, 0xf6,
- 0xcc, 0xf7, 0xf2, 0xc9, 0x18, 0xde, 0xb9, 0x3e, 0x63, 0xfd, 0xa4, 0xcc,
- 0x9a, 0x15, 0xe3, 0xb1, 0x77, 0x37, 0xc1, 0xd3, 0xc2, 0x7e, 0xd3, 0xcd,
- 0xe7, 0x43, 0xd6, 0xf3, 0x32, 0xf3, 0xbd, 0x8e, 0x9d, 0x3f, 0xba, 0xfe,
- 0xce, 0x61, 0x76, 0x6a, 0x9e, 0xf3, 0x8c, 0x2d, 0xa7, 0xf5, 0x9c, 0xcc,
- 0x65, 0xbd, 0xcb, 0xb0, 0xe2, 0x6b, 0x88, 0x32, 0x89, 0x7d, 0x0f, 0x99,
- 0xb6, 0xdf, 0x06, 0xfd, 0x3b, 0x19, 0x0f, 0xdf, 0xa6, 0x7d, 0x76, 0x9e,
- 0xab, 0xf3, 0xdf, 0x6d, 0xec, 0xb2, 0x64, 0xbe, 0xfb, 0x9c, 0xd4, 0x24,
- 0xb9, 0xff, 0x40, 0x85, 0x60, 0xef, 0x27, 0x59, 0xb3, 0x46, 0x0d, 0xd9,
- 0x03, 0x80, 0xe2, 0x4a, 0x1c, 0x41, 0xe7, 0x74, 0x18, 0x6f, 0xeb, 0xde,
- 0xe2, 0x59, 0x17, 0x89, 0xc9, 0x69, 0xc6, 0x64, 0x10, 0x63, 0x46, 0x24,
- 0xfc, 0x36, 0xf1, 0x69, 0x9a, 0x0c, 0x1f, 0xcb, 0x3a, 0xf1, 0x36, 0x31,
- 0x23, 0x14, 0xfb, 0xac, 0xa8, 0xfd, 0x6e, 0xe9, 0xef, 0x4a, 0x84, 0x6b,
- 0x22, 0x2d, 0x07, 0x50, 0x87, 0x0c, 0x73, 0xbe, 0x57, 0xfb, 0x21, 0x8e,
- 0x9f, 0x70, 0xe0, 0x7e, 0xf6, 0x7d, 0xc9, 0xbb, 0x74, 0x7e, 0x6f, 0x1c,
- 0x7a, 0x1f, 0xff, 0x68, 0xce, 0xca, 0x79, 0x2c, 0x45, 0xce, 0x7c, 0x7c,
- 0x62, 0xd6, 0x6a, 0x5a, 0xe1, 0x07, 0xd0, 0x52, 0x57, 0xd1, 0x38, 0xbc,
- 0x8c, 0x0f, 0xcc, 0x02, 0xef, 0xbd, 0xc7, 0xf8, 0x79, 0x49, 0x8f, 0x84,
- 0x1c, 0x14, 0xa6, 0x10, 0x74, 0xe2, 0x3e, 0x5d, 0xe6, 0x29, 0xea, 0xf0,
- 0xb3, 0x50, 0x87, 0x2e, 0x28, 0x72, 0x86, 0xe7, 0x92, 0x99, 0xae, 0x91,
- 0x75, 0x15, 0xac, 0x5b, 0xd3, 0xd8, 0x55, 0x06, 0xb5, 0xc5, 0xad, 0x68,
- 0xfa, 0xfb, 0xca, 0xff, 0x32, 0x0b, 0xc1, 0x4f, 0xcc, 0x77, 0xb4, 0x12,
- 0x5d, 0x35, 0xec, 0x71, 0x96, 0x78, 0xab, 0xc3, 0x71, 0x43, 0xf6, 0xf1,
- 0x7e, 0x88, 0xfb, 0x4f, 0xb8, 0xd0, 0x1e, 0xff, 0xb9, 0x99, 0x0e, 0x0a,
- 0xcd, 0x50, 0x25, 0x2a, 0x84, 0xbe, 0x3d, 0xdb, 0x7e, 0x31, 0x0f, 0xa5,
- 0xc3, 0x10, 0xbc, 0x2c, 0x7e, 0x3a, 0x0d, 0xd3, 0x90, 0x99, 0xa2, 0x89,
- 0x3b, 0xe3, 0x23, 0x78, 0x2f, 0x9e, 0xfc, 0x4f, 0x1e, 0xa8, 0x4b, 0x97,
- 0x9d, 0x6a, 0xa1, 0xc9, 0x19, 0x56, 0xbc, 0x0d, 0xda, 0x70, 0x83, 0x55,
- 0x6f, 0x2e, 0xb2, 0x77, 0xf2, 0x31, 0xb7, 0x48, 0x8f, 0x39, 0x8d, 0xc5,
- 0xc9, 0x34, 0x5c, 0xc4, 0x76, 0xa3, 0xcd, 0x6a, 0xff, 0x33, 0x8a, 0x1a,
- 0x3a, 0xa8, 0x84, 0x95, 0x7b, 0xb5, 0x14, 0x9e, 0xd3, 0xa3, 0xc9, 0x36,
- 0xa5, 0xce, 0xd3, 0x95, 0x2f, 0xd1, 0x6e, 0x27, 0x56, 0x51, 0x0b, 0x97,
- 0x9d, 0xe5, 0xa8, 0xdd, 0xa0, 0x75, 0x95, 0x3b, 0xd5, 0xd4, 0xd7, 0x18,
- 0x5f, 0xdb, 0xf3, 0x05, 0xef, 0xfb, 0x51, 0x07, 0xd6, 0x5a, 0xfb, 0x0d,
- 0x99, 0xe2, 0xbc, 0x74, 0x1a, 0xdd, 0x93, 0xe6, 0x96, 0x8b, 0x71, 0x35,
- 0xf4, 0x8c, 0x92, 0xde, 0xed, 0x23, 0xa6, 0x79, 0x00, 0x5a, 0x78, 0x81,
- 0x75, 0xaa, 0x3d, 0xef, 0xc0, 0x2d, 0xa7, 0x84, 0x66, 0x86, 0x34, 0x8f,
- 0xa0, 0xfc, 0x84, 0xb9, 0x65, 0xb7, 0xae, 0xa6, 0x2e, 0x3b, 0xd3, 0xff,
- 0xbd, 0x96, 0x7a, 0xeb, 0x50, 0x64, 0xbf, 0x6d, 0x84, 0xb8, 0x62, 0x44,
- 0xce, 0xcd, 0xc5, 0xfe, 0x98, 0x98, 0xe2, 0x5b, 0xf4, 0x55, 0x67, 0xc2,
- 0x4f, 0x3e, 0xd5, 0xd8, 0x1c, 0x64, 0xce, 0x1e, 0xc6, 0x65, 0x3d, 0xed,
- 0xed, 0x6c, 0x88, 0x11, 0x9b, 0x85, 0x58, 0x07, 0xc3, 0x38, 0x46, 0x8c,
- 0x77, 0x24, 0x5f, 0x86, 0x42, 0x40, 0x23, 0x36, 0xeb, 0x85, 0x63, 0xd2,
- 0xa7, 0xcc, 0x67, 0x22, 0x7a, 0x3b, 0xfe, 0x33, 0x0a, 0x21, 0x71, 0x91,
- 0x23, 0xf0, 0x9d, 0xf8, 0x7b, 0xb3, 0x4a, 0xd3, 0x5a, 0x26, 0x15, 0xae,
- 0xfb, 0x54, 0x88, 0x3a, 0xe6, 0x7b, 0x72, 0xbe, 0xc5, 0xe8, 0xc1, 0xbd,
- 0x93, 0x41, 0xbe, 0x5f, 0x85, 0x75, 0x27, 0xc2, 0xb8, 0x12, 0xbf, 0x19,
- 0x85, 0x1a, 0x1b, 0x03, 0x79, 0x35, 0xfa, 0x11, 0xfb, 0xac, 0x34, 0x7b,
- 0x4a, 0xd9, 0x63, 0x3a, 0x62, 0x48, 0x7f, 0xee, 0xe2, 0x77, 0x1f, 0x7f,
- 0x45, 0x9f, 0xdf, 0x2a, 0x62, 0x9d, 0xa9, 0xd6, 0xf0, 0xfc, 0xcf, 0x2b,
- 0xec, 0x79, 0x5a, 0x98, 0xcf, 0x05, 0xac, 0x19, 0xe1, 0x28, 0x69, 0x9e,
- 0x9d, 0x96, 0xbe, 0xad, 0x6d, 0xb3, 0xa7, 0xb8, 0x4f, 0xff, 0x53, 0xdd,
- 0x81, 0x2d, 0xec, 0xed, 0x43, 0x9a, 0xd4, 0xcb, 0x51, 0xb5, 0x16, 0x9b,
- 0x71, 0x3a, 0xc0, 0x26, 0x5c, 0xfb, 0x0f, 0x98, 0x08, 0xc4, 0x98, 0xf3,
- 0x35, 0xbc, 0x9b, 0xf9, 0x32, 0xfb, 0x9d, 0x3a, 0x39, 0xe3, 0x83, 0x5b,
- 0x4e, 0xb8, 0xb9, 0xe6, 0x16, 0xe2, 0x9a, 0x4e, 0xbc, 0x16, 0xb0, 0x7b,
- 0x8d, 0xa3, 0xbc, 0x3e, 0x3e, 0xe7, 0x23, 0x16, 0xf5, 0xf0, 0xf7, 0x46,
- 0xde, 0xbe, 0x88, 0x27, 0x91, 0xe5, 0xdf, 0xe2, 0xc9, 0x43, 0x3c, 0xa0,
- 0xe1, 0x6a, 0xe6, 0x65, 0x5c, 0x21, 0xed, 0xf4, 0x9c, 0x4d, 0x73, 0x2a,
- 0x2f, 0x74, 0x65, 0xbd, 0x48, 0xaa, 0xd6, 0x29, 0xf4, 0x7d, 0x72, 0xde,
- 0xf7, 0xdf, 0xb9, 0x06, 0x91, 0xdd, 0x09, 0xf6, 0xc7, 0x7a, 0x03, 0xda,
- 0x03, 0xb4, 0x97, 0x21, 0x6b, 0xa8, 0xec, 0x45, 0xe5, 0xdd, 0x10, 0xd6,
- 0x4e, 0x9a, 0x23, 0xa1, 0x84, 0x5c, 0x37, 0xcd, 0xea, 0x4d, 0x5a, 0xe8,
- 0x4d, 0xc5, 0xc5, 0x5a, 0xe7, 0xa2, 0x0e, 0xc6, 0x71, 0x36, 0xd3, 0xb8,
- 0xf4, 0x1e, 0xb1, 0x53, 0x98, 0xbd, 0xde, 0x25, 0xe7, 0x38, 0xe6, 0x33,
- 0x0b, 0x95, 0x32, 0x23, 0x18, 0xcf, 0xfb, 0x94, 0xb9, 0xcc, 0x91, 0x4a,
- 0xc9, 0x45, 0x63, 0xf4, 0x85, 0xa6, 0x49, 0xe1, 0xd5, 0x1c, 0xa9, 0x22,
- 0x9d, 0x63, 0xa4, 0x33, 0xb7, 0x51, 0xeb, 0x1f, 0x53, 0x44, 0x67, 0x3e,
- 0xe2, 0xba, 0x8b, 0x32, 0x3f, 0xa3, 0xde, 0xfe, 0x94, 0xcf, 0x8b, 0xde,
- 0x82, 0x78, 0xad, 0x48, 0xe7, 0x89, 0xfc, 0x12, 0xe6, 0x32, 0x1f, 0x58,
- 0x7f, 0x8f, 0xe5, 0x63, 0xac, 0x7d, 0x83, 0xc8, 0x31, 0x9f, 0x4c, 0x66,
- 0x1a, 0xfb, 0x27, 0xc9, 0x87, 0x7d, 0x36, 0x6f, 0x10, 0x4f, 0x17, 0x9f,
- 0x19, 0xe5, 0xbb, 0xa3, 0xd7, 0xfe, 0x16, 0x1d, 0xd9, 0xfb, 0xff, 0xf6,
- 0x1e, 0x43, 0x39, 0x6d, 0x67, 0xf7, 0xe1, 0x47, 0x0d, 0xb7, 0xcc, 0xc3,
- 0xf1, 0xf2, 0xf4, 0x16, 0x8c, 0xe9, 0x7f, 0x8e, 0xbd, 0x94, 0x7b, 0x9c,
- 0xfa, 0x3c, 0x61, 0x58, 0xfb, 0xfc, 0x72, 0xfe, 0x8b, 0xb9, 0xfa, 0x60,
- 0xeb, 0x19, 0x62, 0xb1, 0xe3, 0x8c, 0x99, 0xfd, 0xf1, 0xc6, 0xde, 0x57,
- 0xe8, 0x77, 0xc9, 0xdf, 0x96, 0xbd, 0x74, 0x60, 0x32, 0xfb, 0x0d, 0xcc,
- 0xd6, 0x34, 0x2e, 0x3f, 0xcf, 0x9c, 0x70, 0x9a, 0x79, 0xca, 0xc5, 0x9c,
- 0x50, 0x9d, 0x25, 0x86, 0x64, 0x9e, 0x2a, 0x30, 0x4f, 0xb9, 0xb4, 0xc6,
- 0xa5, 0x79, 0xfc, 0x15, 0xf5, 0x22, 0xfc, 0x45, 0x62, 0xf3, 0x90, 0x67,
- 0xed, 0xf9, 0xab, 0x36, 0x3f, 0x84, 0x4b, 0x37, 0xdb, 0x33, 0x34, 0x27,
- 0x6b, 0xf6, 0xbe, 0x4c, 0x63, 0x60, 0x4c, 0x68, 0xf7, 0xa9, 0xa1, 0x34,
- 0x6d, 0x35, 0x61, 0x61, 0xef, 0x61, 0xf6, 0x0b, 0x72, 0xde, 0xab, 0x0a,
- 0x2e, 0xfa, 0xfe, 0x98, 0x2e, 0xe7, 0x20, 0x42, 0xfe, 0xed, 0xb4, 0xe1,
- 0x98, 0xd1, 0xd8, 0x12, 0x51, 0x76, 0xe3, 0x52, 0x31, 0xc7, 0xda, 0x58,
- 0x5a, 0xed, 0x3f, 0x86, 0xc6, 0xde, 0x07, 0xf0, 0x75, 0x24, 0x6b, 0x1a,
- 0x07, 0xa6, 0x11, 0xd1, 0xef, 0x83, 0x9c, 0x1b, 0xb5, 0x69, 0xd5, 0xe7,
- 0x9c, 0xc4, 0x23, 0x9f, 0x98, 0xab, 0xb5, 0x27, 0x30, 0x4d, 0xcc, 0xd8,
- 0xb0, 0x5e, 0x5b, 0xfa, 0x6e, 0xf1, 0x9e, 0xbd, 0xa7, 0x24, 0xfe, 0xe2,
- 0xa1, 0x0e, 0xca, 0xe1, 0x5a, 0x51, 0xc7, 0x35, 0xa8, 0x0b, 0xeb, 0x4c,
- 0xf1, 0x45, 0x1c, 0xa2, 0xbf, 0x4d, 0xe7, 0x15, 0xe8, 0xf5, 0x17, 0x31,
- 0x2c, 0xb5, 0x89, 0xef, 0xb4, 0x65, 0x7c, 0xc4, 0x29, 0x21, 0x94, 0x6b,
- 0x91, 0xf0, 0x28, 0xe5, 0x6b, 0x63, 0x2e, 0x1f, 0x67, 0x0e, 0x49, 0x07,
- 0x7c, 0xd6, 0x39, 0xd7, 0x72, 0x2d, 0x64, 0xfd, 0x6f, 0x82, 0xf4, 0x41,
- 0x0d, 0xb3, 0xb2, 0x9f, 0x7d, 0x04, 0x17, 0xa7, 0x0b, 0x38, 0x1e, 0x4f,
- 0xe2, 0x40, 0x4d, 0x00, 0x93, 0xc6, 0x4a, 0x6b, 0x6e, 0x20, 0xfd, 0x56,
- 0x77, 0xf6, 0xb0, 0x35, 0x8b, 0xdc, 0x16, 0x77, 0xd4, 0xcb, 0x79, 0x8f,
- 0x39, 0xf6, 0x5d, 0xd3, 0xfa, 0x08, 0x0e, 0xe9, 0xdf, 0x82, 0xbe, 0x42,
- 0x72, 0xe7, 0x18, 0xce, 0xcf, 0x4a, 0x0d, 0x9b, 0x68, 0xbd, 0x75, 0x52,
- 0xf4, 0xe3, 0x20, 0xe6, 0xf5, 0xa0, 0xc9, 0xc2, 0x70, 0xaf, 0xb7, 0xae,
- 0x99, 0xb5, 0xb1, 0x5c, 0x53, 0x4e, 0xce, 0x66, 0x57, 0xc1, 0x4f, 0x7d,
- 0x5d, 0x88, 0xbb, 0x99, 0x73, 0x44, 0x9f, 0x72, 0x16, 0xd0, 0x96, 0x33,
- 0x96, 0x53, 0x30, 0xd6, 0x7c, 0xe3, 0x5e, 0x8b, 0xfc, 0x9f, 0xc2, 0xb5,
- 0xf3, 0x89, 0xc5, 0xd9, 0xf8, 0x1f, 0x9b, 0x97, 0x6e, 0x12, 0xb9, 0x5b,
- 0x7d, 0xcc, 0xe9, 0xe1, 0xd9, 0x6b, 0xfa, 0x15, 0x9d, 0x9e, 0x93, 0x9a,
- 0x61, 0xe9, 0xdc, 0x9e, 0xb7, 0xa9, 0xc3, 0xef, 0x28, 0x8d, 0xac, 0x27,
- 0xf4, 0xab, 0x1a, 0xfa, 0x5b, 0x13, 0x06, 0x56, 0x27, 0x5c, 0x7d, 0x57,
- 0x8d, 0x2d, 0x68, 0xd9, 0xf0, 0xae, 0x89, 0x9b, 0xdb, 0xe0, 0xd4, 0xe4,
- 0xfa, 0xac, 0x99, 0x0c, 0xc8, 0xdf, 0x4f, 0xfa, 0xa4, 0x96, 0xbf, 0x68,
- 0x14, 0xcc, 0x35, 0x2b, 0x6d, 0x6c, 0xf8, 0xf7, 0x19, 0xd9, 0x07, 0x4b,
- 0x9b, 0xec, 0xb5, 0x97, 0xde, 0x76, 0x1e, 0xc6, 0xdf, 0xe6, 0x8e, 0xe0,
- 0xad, 0x69, 0x17, 0x71, 0xa6, 0xc8, 0xb2, 0x05, 0xd5, 0x1b, 0xa2, 0xc9,
- 0x77, 0x99, 0x17, 0x97, 0x66, 0x4b, 0x7e, 0xf1, 0x7a, 0xeb, 0xda, 0x59,
- 0x85, 0xb4, 0xaa, 0x50, 0x46, 0x39, 0x7f, 0xac, 0x3b, 0x11, 0x2e, 0x62,
- 0x5b, 0x27, 0xf9, 0xdc, 0x97, 0xb1, 0x31, 0x6f, 0x24, 0x37, 0xed, 0xb3,
- 0xe7, 0x5f, 0x3e, 0xe6, 0xd1, 0x71, 0x4c, 0x64, 0x1a, 0x63, 0xef, 0xc9,
- 0x79, 0x1e, 0xf6, 0x62, 0x97, 0x30, 0x8e, 0x13, 0x99, 0x52, 0x0e, 0x0d,
- 0xc9, 0x39, 0xd8, 0x58, 0xd8, 0x61, 0xe7, 0xc8, 0xb0, 0x43, 0x4d, 0xf3,
- 0xd7, 0x27, 0xd8, 0x60, 0x34, 0x1f, 0x09, 0x95, 0xc3, 0x89, 0xfd, 0xba,
- 0xed, 0x1f, 0xf5, 0xf3, 0x6e, 0x84, 0x57, 0x48, 0x5d, 0x96, 0x9a, 0xec,
- 0x62, 0x4d, 0x5e, 0x89, 0xe4, 0x4a, 0x17, 0x5e, 0xd7, 0x44, 0x1f, 0x53,
- 0x25, 0x7d, 0xe8, 0xe7, 0xf0, 0x90, 0x59, 0xe8, 0x15, 0x5f, 0x72, 0xe3,
- 0x48, 0xd3, 0x9c, 0x39, 0x1b, 0x14, 0xd9, 0x9d, 0x38, 0xcd, 0xfc, 0x8a,
- 0x9b, 0x23, 0xa1, 0xd3, 0xac, 0xd9, 0x63, 0x5a, 0xc9, 0xc7, 0xff, 0x63,
- 0x91, 0x4f, 0xad, 0x7f, 0x01, 0x47, 0xf8, 0x77, 0x7d, 0xe8, 0x80, 0x62,
- 0xaf, 0xb7, 0x66, 0xfe, 0x43, 0x5f, 0x69, 0x76, 0x2a, 0xcf, 0x86, 0x73,
- 0xa7, 0xf9, 0x5d, 0x68, 0xf9, 0xe8, 0x9f, 0xe5, 0x18, 0x08, 0xca, 0x79,
- 0x10, 0xd1, 0x8b, 0xec, 0x3f, 0x82, 0xfa, 0x30, 0xf1, 0x32, 0xf5, 0x71,
- 0xe4, 0xda, 0xd9, 0x2b, 0x3b, 0x7f, 0x55, 0xf0, 0xfa, 0xf6, 0xf8, 0x4b,
- 0x9b, 0xbd, 0xf8, 0x95, 0x79, 0x29, 0x18, 0x62, 0x4e, 0x10, 0x9b, 0xa6,
- 0x2c, 0x1c, 0xe9, 0x24, 0x3e, 0xd9, 0x67, 0x9f, 0x33, 0x69, 0x95, 0xff,
- 0xa1, 0x29, 0xca, 0x51, 0x18, 0x24, 0xce, 0x5e, 0xcc, 0x58, 0x67, 0xfb,
- 0x06, 0xde, 0x54, 0x22, 0xcc, 0x35, 0x5f, 0xc2, 0x40, 0xad, 0xd0, 0x0b,
- 0xf8, 0x77, 0xce, 0xc4, 0xa8, 0x83, 0x3a, 0xa1, 0x6b, 0x3e, 0xc3, 0x6e,
- 0xee, 0xc8, 0xa4, 0xd0, 0x07, 0xc6, 0x26, 0x23, 0x43, 0x3f, 0x06, 0x36,
- 0x57, 0x41, 0x4d, 0x2d, 0x14, 0xff, 0xdf, 0xe3, 0x67, 0x8a, 0xd0, 0x12,
- 0x3a, 0x2e, 0x18, 0xcc, 0x71, 0x53, 0x8b, 0x15, 0xd4, 0x9d, 0xda, 0xfb,
- 0x3d, 0xa5, 0x02, 0x4f, 0x3c, 0x15, 0x23, 0xef, 0x2b, 0xfc, 0xdb, 0x67,
- 0x3c, 0xf0, 0x9e, 0xa9, 0x62, 0xcd, 0xf5, 0xe0, 0x72, 0x33, 0xed, 0xfa,
- 0x54, 0x89, 0x77, 0x6b, 0x9f, 0x14, 0x8f, 0x67, 0xc3, 0x30, 0xe8, 0xb3,
- 0x8b, 0x86, 0xec, 0x17, 0x7b, 0xac, 0xfc, 0xb9, 0xb4, 0xb1, 0xce, 0xda,
- 0xaf, 0x7a, 0x3e, 0xaf, 0x85, 0xce, 0x2a, 0x55, 0xf8, 0xe0, 0x44, 0xe1,
- 0xe6, 0x72, 0x98, 0x2f, 0xae, 0x4e, 0x44, 0xfb, 0xf7, 0xd2, 0xe7, 0xd7,
- 0xae, 0x09, 0xb2, 0x97, 0x61, 0x4f, 0xb9, 0x49, 0xfa, 0xdf, 0x69, 0xf6,
- 0xbf, 0xa5, 0xbd, 0x7f, 0x6d, 0xe8, 0x11, 0x25, 0xdd, 0xe9, 0x87, 0xf9,
- 0x51, 0x79, 0xc2, 0xfc, 0xd8, 0x9d, 0x88, 0xf2, 0x7d, 0xd9, 0xdf, 0x33,
- 0xcd, 0x9f, 0x36, 0x9b, 0x66, 0xae, 0x39, 0xd2, 0x1f, 0x70, 0x06, 0x70,
- 0xa6, 0x41, 0xf6, 0x04, 0x1d, 0xf8, 0x20, 0xaa, 0x85, 0xf6, 0x42, 0xf6,
- 0xe8, 0x99, 0xe3, 0x57, 0xca, 0xf9, 0xc4, 0x3a, 0x7f, 0x97, 0xb1, 0x02,
- 0xcf, 0x2d, 0x6c, 0xc2, 0x80, 0x1b, 0xd6, 0xf9, 0x19, 0x53, 0xc7, 0x9b,
- 0xab, 0x21, 0x75, 0x3b, 0xda, 0xf2, 0x08, 0x82, 0x58, 0xc8, 0x1f, 0xc1,
- 0xc3, 0x27, 0x64, 0xaf, 0x71, 0xb2, 0xd5, 0x73, 0xc2, 0xfc, 0xfb, 0x50,
- 0xa2, 0xc0, 0xbc, 0x68, 0x9a, 0x15, 0x9b, 0x1a, 0x43, 0x2c, 0x47, 0xc4,
- 0x18, 0x69, 0xc1, 0xee, 0x43, 0x1f, 0xa0, 0x06, 0x67, 0xe7, 0x92, 0x37,
- 0xb3, 0x97, 0xec, 0x7a, 0x5a, 0x09, 0xe0, 0x07, 0x94, 0xf1, 0xd9, 0xbc,
- 0xe0, 0x14, 0xa3, 0xb5, 0xfb, 0xc4, 0x2a, 0xbc, 0xb8, 0x10, 0xc4, 0x59,
- 0x43, 0x23, 0x4e, 0x82, 0x52, 0x99, 0x30, 0xab, 0xab, 0xc9, 0x6b, 0xa5,
- 0xd3, 0x89, 0xce, 0xb8, 0xf4, 0x87, 0xda, 0x90, 0x4f, 0xc1, 0xaa, 0x72,
- 0x68, 0xcb, 0x0f, 0x01, 0xc3, 0x5e, 0xf6, 0xab, 0x4f, 0x2b, 0xd1, 0xfe,
- 0xf7, 0x9d, 0x41, 0xfc, 0x80, 0xf9, 0xe7, 0x7b, 0x79, 0x39, 0x5b, 0xc5,
- 0x1c, 0x33, 0x17, 0xa6, 0xad, 0x3c, 0x70, 0xd4, 0x57, 0xe1, 0x28, 0xe3,
- 0xe5, 0x65, 0xbd, 0x8c, 0x39, 0x4a, 0xce, 0x5a, 0x49, 0x7e, 0x7f, 0x54,
- 0xce, 0x94, 0x98, 0xcf, 0x6b, 0x76, 0xbf, 0xaf, 0xcf, 0xdf, 0x78, 0x5e,
- 0x39, 0xc0, 0xbc, 0xde, 0xd8, 0x1b, 0x52, 0x5e, 0x35, 0x93, 0xbf, 0xad,
- 0x50, 0xce, 0x07, 0xab, 0x50, 0x61, 0xc9, 0x8a, 0xd1, 0x6c, 0xa9, 0xa6,
- 0x54, 0x4b, 0x2f, 0xd7, 0x9b, 0x2e, 0xfa, 0x60, 0x25, 0x63, 0xfd, 0x18,
- 0x6b, 0x74, 0xf9, 0x09, 0xa9, 0x25, 0xec, 0x5f, 0x94, 0x2d, 0xc4, 0xc2,
- 0x82, 0x1b, 0x3c, 0x78, 0x20, 0xa0, 0xb6, 0xc8, 0x99, 0xed, 0x67, 0xf3,
- 0x1d, 0x2e, 0x39, 0x3b, 0xf5, 0x5c, 0x5e, 0x6a, 0xb9, 0xe4, 0x82, 0xd2,
- 0x7a, 0x21, 0xd4, 0x4e, 0x8a, 0x8d, 0x86, 0x5b, 0x3f, 0x9a, 0xf4, 0xc9,
- 0xf9, 0xfa, 0x11, 0x07, 0x7b, 0x6d, 0xcf, 0xa4, 0x69, 0xee, 0x69, 0xd6,
- 0x86, 0xb6, 0x38, 0x65, 0x6f, 0x39, 0x32, 0x70, 0x4e, 0x51, 0x5b, 0x26,
- 0x94, 0x1b, 0xe9, 0xfc, 0xb7, 0x2a, 0x89, 0x91, 0x34, 0xe5, 0x7c, 0xdc,
- 0x92, 0x69, 0x8a, 0x32, 0x95, 0xce, 0x16, 0x55, 0xe1, 0xf2, 0x34, 0x34,
- 0x46, 0x2d, 0xce, 0xeb, 0x4c, 0x4e, 0x81, 0x68, 0xb2, 0x1d, 0xe2, 0xff,
- 0xea, 0x80, 0x60, 0xa8, 0x4a, 0xe6, 0xe4, 0xb9, 0x69, 0xa9, 0x31, 0x8a,
- 0xe0, 0x93, 0x34, 0xd7, 0xc6, 0x95, 0x8d, 0xc0, 0xab, 0x93, 0xf6, 0xde,
- 0x7b, 0xf1, 0x2c, 0xb8, 0x75, 0xe6, 0xe1, 0x11, 0xeb, 0x2c, 0x83, 0xd0,
- 0x3f, 0x8c, 0x33, 0x19, 0xc1, 0x94, 0xc3, 0xc4, 0x94, 0x91, 0x14, 0xf1,
- 0x66, 0x4b, 0xde, 0x3e, 0x97, 0xa5, 0x7f, 0x44, 0x9f, 0x7f, 0x9a, 0x58,
- 0xf5, 0x28, 0xec, 0xbd, 0xf7, 0x86, 0xe2, 0x59, 0x85, 0x48, 0xae, 0x4b,
- 0xd9, 0x91, 0x97, 0x18, 0x9b, 0x66, 0x8c, 0xb5, 0x2b, 0xdb, 0x17, 0x3a,
- 0x94, 0xee, 0x85, 0x1e, 0x65, 0x77, 0x5e, 0x7a, 0xd6, 0xc9, 0xd6, 0x07,
- 0x4e, 0xec, 0x52, 0x76, 0xcc, 0xf5, 0x29, 0xc4, 0xb4, 0x01, 0x4f, 0xa2,
- 0x5f, 0xe9, 0x59, 0xb0, 0xe7, 0xe7, 0x5d, 0xec, 0xbb, 0x76, 0x18, 0xa5,
- 0x7e, 0x5e, 0xfe, 0xdf, 0x2b, 0x28, 0xff, 0x5b, 0x31, 0xb0, 0x4d, 0x31,
- 0xcd, 0xdb, 0xe2, 0x7f, 0x27, 0xf6, 0x30, 0x9f, 0x8d, 0xb3, 0x36, 0x1a,
- 0x55, 0x18, 0x64, 0xdf, 0x31, 0xaa, 0xdf, 0x5a, 0xdc, 0x2f, 0x13, 0x99,
- 0xe4, 0x3c, 0x85, 0xf8, 0x2b, 0xd2, 0xe5, 0xe4, 0xe1, 0x1f, 0xc8, 0xff,
- 0x81, 0xa2, 0x5c, 0x3d, 0x72, 0xa6, 0xc0, 0x7d, 0xfd, 0xbc, 0xd9, 0xf1,
- 0xc9, 0xeb, 0x72, 0x31, 0xd7, 0x63, 0x9c, 0xf8, 0xf4, 0x80, 0xa2, 0xa6,
- 0x9e, 0xb1, 0xe5, 0x5a, 0xba, 0xcc, 0x18, 0x1e, 0xb5, 0x62, 0xd8, 0x96,
- 0x6b, 0x5d, 0x51, 0xae, 0xb5, 0xb9, 0x2e, 0xeb, 0x1c, 0x17, 0xf1, 0x7a,
- 0xeb, 0xe2, 0xa4, 0x9c, 0x37, 0x93, 0xd9, 0xa5, 0xc8, 0x26, 0x72, 0x9c,
- 0x30, 0x2b, 0xb4, 0x1e, 0x65, 0xa7, 0x75, 0xfe, 0x4c, 0xce, 0x7e, 0xc9,
- 0x5e, 0x7f, 0x49, 0x2e, 0xa9, 0xe3, 0x2b, 0xfc, 0x1d, 0x33, 0x72, 0x1e,
- 0xdb, 0x34, 0x5f, 0xd3, 0x83, 0x7e, 0x91, 0xe5, 0xac, 0x2e, 0xb2, 0xc8,
- 0xb9, 0x92, 0x92, 0x3c, 0x5f, 0x2b, 0xca, 0x23, 0xb6, 0xba, 0x6e, 0xa7,
- 0xd2, 0xff, 0x09, 0xbe, 0x9d, 0xb1, 0xcf, 0x9c, 0x94, 0xe4, 0xf1, 0x27,
- 0x84, 0xff, 0x8b, 0xad, 0xe3, 0xd3, 0xc3, 0x78, 0x95, 0xf7, 0x7f, 0x9e,
- 0x29, 0xc9, 0xe5, 0xc4, 0xfc, 0x5c, 0xe9, 0x2c, 0x1d, 0x5b, 0x4a, 0x23,
- 0xa2, 0x8f, 0xd1, 0x8f, 0x6c, 0xf9, 0xe4, 0x2c, 0x5d, 0x63, 0xe1, 0xb2,
- 0x35, 0xf7, 0x8a, 0x26, 0xd9, 0x2f, 0xe3, 0x6c, 0xfe, 0xd7, 0xed, 0xd7,
- 0x94, 0xab, 0x60, 0x8f, 0x2c, 0xb4, 0x5f, 0x27, 0x6d, 0x39, 0x73, 0xa2,
- 0xe0, 0x99, 0x39, 0x60, 0xce, 0xe0, 0xb2, 0x89, 0x11, 0x3c, 0xa9, 0x9b,
- 0xe6, 0xd3, 0xcd, 0x9a, 0x9c, 0x15, 0xba, 0x50, 0x6b, 0xcd, 0x85, 0xa0,
- 0x57, 0x69, 0xb2, 0x77, 0x27, 0xe7, 0x4d, 0xfa, 0xa8, 0x03, 0x91, 0x5d,
- 0x7c, 0xa0, 0x64, 0x7b, 0x39, 0x07, 0x97, 0xa6, 0x7e, 0x44, 0x37, 0xa5,
- 0xf3, 0x70, 0x32, 0x73, 0xb9, 0x51, 0x27, 0x5d, 0x96, 0x4e, 0x9e, 0xd5,
- 0xc5, 0x5f, 0x99, 0x7d, 0xe8, 0xab, 0xf3, 0xc4, 0x0f, 0x63, 0xba, 0xdb,
- 0xc2, 0x6a, 0x47, 0x89, 0x4f, 0x26, 0x18, 0x3b, 0x8f, 0x1b, 0x4b, 0x58,
- 0xca, 0xbd, 0x8c, 0x57, 0xaf, 0xfd, 0xcf, 0x9c, 0xf8, 0x8b, 0xde, 0xd2,
- 0x6d, 0x9d, 0x79, 0xfa, 0xa4, 0xe5, 0xd6, 0xa8, 0xe4, 0xa1, 0x1f, 0x36,
- 0xc9, 0x19, 0xa8, 0xf2, 0x44, 0xe0, 0x6b, 0xb2, 0xbf, 0x55, 0x96, 0x98,
- 0xfd, 0xea, 0x05, 0x4d, 0x74, 0xa3, 0x35, 0x9f, 0xd1, 0x44, 0xae, 0x1e,
- 0x7d, 0xdc, 0xfa, 0x1f, 0xce, 0x96, 0x4d, 0xfb, 0x34, 0x89, 0x1d, 0xdf,
- 0xc6, 0x36, 0x2b, 0x27, 0x9c, 0x4e, 0xdc, 0x66, 0xe9, 0xe0, 0x64, 0xe2,
- 0x56, 0xeb, 0x73, 0x3a, 0x11, 0xb3, 0x3e, 0xff, 0x24, 0x61, 0xeb, 0x26,
- 0x97, 0xa8, 0xb7, 0x3e, 0xe7, 0x13, 0xf6, 0xd9, 0xe9, 0xd9, 0x84, 0x66,
- 0x7d, 0x3e, 0x9f, 0x88, 0x58, 0x9f, 0x67, 0x13, 0xb7, 0x5c, 0xe7, 0x8b,
- 0x3f, 0xff, 0x0f, 0x4c, 0xd3, 0x85, 0x76, 0xdc, 0x3a, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
-
-static struct fw_info bnx2_txp_fw_06 = {
- /* Firmware version: 4.0.5 */
- .ver_major = 0x4,
- .ver_minor = 0x0,
- .ver_fix = 0x5,
-
- .start_addr = 0x08000098,
-
- .text_addr = 0x08000000,
- .text_len = 0x3ad8,
- .text_index = 0x0,
- .gz_text = bnx2_TXP_b06FwText,
- .gz_text_len = sizeof(bnx2_TXP_b06FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TXP_b06FwData,
-
- .sbss_addr = 0x08003b00,
- .sbss_len = 0x68,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08003b68,
- .bss_len = 0x14c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x00000000,
- .rodata_len = 0x0,
- .rodata_index = 0x0,
- .rodata = bnx2_TXP_b06FwRodata,
-};
-
-/* Initialized Values for the TX Processor. */
-static const struct cpu_reg cpu_reg_txp = {
- .mode = BNX2_TXP_CPU_MODE,
- .mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT,
- .mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA,
- .state = BNX2_TXP_CPU_STATE,
- .state_value_clear = 0xffffff,
- .gpr0 = BNX2_TXP_CPU_REG_FILE,
- .evmask = BNX2_TXP_CPU_EVENT_MASK,
- .pc = BNX2_TXP_CPU_PROGRAM_COUNTER,
- .inst = BNX2_TXP_CPU_INSTRUCTION,
- .bp = BNX2_TXP_CPU_HW_BREAKPOINT,
- .spad_base = BNX2_TXP_SCRATCH,
- .mips_view_base = 0x8000000,
-};
diff --git a/drivers/net/bnx2_fw2.h b/drivers/net/bnx2_fw2.h
deleted file mode 100644
index fe753b6bcb4..00000000000
--- a/drivers/net/bnx2_fw2.h
+++ /dev/null
@@ -1,4616 +0,0 @@
-/* bnx2_fw2.h: Broadcom NX2 network driver.
- *
- * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, except as noted below.
- *
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
-
-static u8 bnx2_COM_b09FwText[] = {
- 0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x75, 0xe6, 0x79, 0x6f, 0xde, 0x90,
- 0x43, 0x8a, 0xa2, 0x1e, 0x99, 0x31, 0x33, 0x8e, 0xd8, 0x7a, 0x86, 0xf3,
- 0x48, 0xd1, 0x21, 0xe3, 0x3e, 0x33, 0x63, 0x99, 0x76, 0xa6, 0xd6, 0x64,
- 0x66, 0x28, 0x2b, 0x0e, 0x69, 0xd0, 0x8e, 0x82, 0x4d, 0x01, 0x03, 0xe5,
- 0x0e, 0xa9, 0x54, 0xd9, 0xf5, 0x22, 0xda, 0x34, 0x45, 0x8a, 0xa2, 0x88,
- 0x26, 0x24, 0xe5, 0x2a, 0xcd, 0x88, 0x1c, 0xcb, 0x34, 0x1b, 0x14, 0x5e,
- 0x64, 0x3c, 0xa4, 0x14, 0xb7, 0x1d, 0x89, 0x72, 0xe2, 0x2d, 0xbc, 0x58,
- 0x07, 0x66, 0xa9, 0x1f, 0x4e, 0x83, 0x14, 0xf0, 0x2e, 0xbc, 0x68, 0x60,
- 0xa4, 0x80, 0x20, 0xbb, 0x8d, 0xb3, 0xc8, 0x62, 0x83, 0xdd, 0x00, 0x71,
- 0x02, 0x27, 0x6f, 0xbf, 0xef, 0xde, 0xfb, 0xc8, 0xd1, 0x88, 0x76, 0xd2,
- 0xfc, 0xb5, 0x04, 0x06, 0xf7, 0xfd, 0xb8, 0x3f, 0xce, 0x3d, 0xf7, 0xdc,
- 0x73, 0xbe, 0x73, 0xee, 0x79, 0x7c, 0x40, 0xa4, 0x53, 0xcc, 0xdf, 0x5e,
- 0xfc, 0x32, 0xff, 0xe1, 0xb3, 0xb3, 0x63, 0x77, 0x65, 0xee, 0xc2, 0xe5,
- 0x87, 0xed, 0xf7, 0x3b, 0x0e, 0x9f, 0x47, 0xf0, 0x8b, 0xe3, 0x37, 0x66,
- 0xae, 0x77, 0xfb, 0x73, 0xf1, 0x3b, 0x68, 0x89, 0xcc, 0xfc, 0x4f, 0x11,
- 0xab, 0xe5, 0x5d, 0xec, 0x5d, 0xda, 0xbc, 0xd7, 0x9f, 0xfd, 0x1b, 0xb4,
- 0xf9, 0xd7, 0xfe, 0x45, 0x34, 0xd9, 0x6a, 0xde, 0xfc, 0x49, 0xcc, 0xce,
- 0xce, 0x4c, 0xe6, 0x3d, 0x89, 0x45, 0xb2, 0x47, 0xa7, 0x66, 0x3d, 0x91,
- 0x5c, 0x63, 0x24, 0x59, 0x90, 0x5f, 0x04, 0xe5, 0xb8, 0x23, 0x7c, 0xfe,
- 0x5b, 0xd9, 0x77, 0xbe, 0xf6, 0xad, 0x7b, 0x53, 0x3f, 0xae, 0x45, 0x24,
- 0xe6, 0x66, 0xdf, 0x16, 0x77, 0x48, 0x62, 0xfd, 0x68, 0xf3, 0xcc, 0x81,
- 0x57, 0x6d, 0xe9, 0x0e, 0xfb, 0x72, 0x67, 0x22, 0x59, 0x99, 0x3e, 0x56,
- 0x39, 0x19, 0xd8, 0x9e, 0x94, 0x9d, 0xac, 0x37, 0x5c, 0x97, 0xae, 0xf1,
- 0x73, 0x99, 0x7b, 0x05, 0xf7, 0xd3, 0xc7, 0x1a, 0x31, 0x99, 0x6f, 0x94,
- 0xbb, 0x6c, 0xcf, 0x43, 0x29, 0xb1, 0xb6, 0xec, 0x62, 0xec, 0x9a, 0xc7,
- 0xb1, 0xbf, 0x8a, 0xb1, 0xf7, 0x4b, 0xd4, 0x0b, 0x82, 0x73, 0x18, 0xfb,
- 0x70, 0xe3, 0x17, 0xc1, 0xb3, 0x8e, 0x1e, 0xd7, 0xce, 0x9e, 0x88, 0xb0,
- 0xb4, 0xb2, 0xb5, 0xc9, 0x81, 0x06, 0xef, 0x8b, 0xed, 0x9a, 0x4e, 0xbf,
- 0x13, 0x74, 0xc6, 0x9c, 0xec, 0x89, 0xce, 0x45, 0x94, 0xd1, 0x6c, 0x7c,
- 0xec, 0x9c, 0xaa, 0xb7, 0x6e, 0xea, 0x3d, 0x1e, 0xd5, 0xed, 0xde, 0x9a,
- 0x1c, 0x6a, 0xb0, 0xfc, 0xc9, 0xe4, 0xa0, 0x2a, 0xdf, 0x99, 0x4c, 0xab,
- 0x52, 0xa6, 0x06, 0x54, 0xe9, 0x4c, 0x79, 0xaa, 0x7c, 0xc6, 0x3c, 0x7f,
- 0x6e, 0x32, 0xa9, 0xca, 0x86, 0x29, 0x2f, 0x99, 0xf2, 0x05, 0x53, 0xbe,
- 0x68, 0xca, 0x97, 0x4c, 0xb9, 0x69, 0xca, 0x2b, 0x93, 0xba, 0x9f, 0x6f,
- 0x9b, 0xfb, 0xef, 0x9a, 0xf2, 0x55, 0x53, 0xbe, 0x66, 0xca, 0xef, 0x99,
- 0xf2, 0xfb, 0x86, 0xae, 0xeb, 0xa6, 0x7c, 0xd3, 0x94, 0x3f, 0x32, 0xef,
- 0x7f, 0x6c, 0xe8, 0x7d, 0x1b, 0x74, 0xfd, 0x49, 0xd4, 0xc8, 0x2a, 0xe6,
- 0x9d, 0x94, 0xd9, 0x8a, 0x23, 0xf3, 0xcb, 0x11, 0x29, 0xa8, 0x35, 0xfc,
- 0xca, 0x5e, 0xe9, 0x74, 0x64, 0x61, 0x23, 0x26, 0xd7, 0x95, 0x88, 0xbe,
- 0x15, 0x7c, 0xeb, 0x80, 0x94, 0xed, 0xac, 0x2b, 0x97, 0x36, 0xe2, 0xf2,
- 0xf2, 0x86, 0x58, 0xd3, 0x99, 0x0e, 0xb1, 0xcf, 0x7e, 0x40, 0x72, 0xae,
- 0x25, 0x11, 0xc5, 0xd3, 0xa4, 0xe4, 0x2b, 0x7d, 0xb8, 0x4f, 0x25, 0x44,
- 0xae, 0xee, 0xd5, 0xeb, 0x17, 0x93, 0xc8, 0x2a, 0xd7, 0xe4, 0xfe, 0xa9,
- 0x6b, 0x2b, 0x09, 0x71, 0x96, 0x46, 0x31, 0x46, 0x97, 0x44, 0x57, 0xa5,
- 0x3f, 0x22, 0x83, 0x89, 0x4f, 0xa3, 0x46, 0xb1, 0xe1, 0xc8, 0x44, 0xc3,
- 0x12, 0xc7, 0x8b, 0x41, 0x3e, 0xba, 0xf0, 0x73, 0xf1, 0x8b, 0xe3, 0x97,
- 0xc0, 0xef, 0x47, 0xe8, 0xa7, 0x5f, 0x0a, 0x0d, 0xf6, 0x89, 0x71, 0x97,
- 0x31, 0xfe, 0x72, 0xca, 0x9d, 0x11, 0xd2, 0x95, 0x90, 0x6f, 0x1d, 0x20,
- 0x5d, 0x2e, 0xe9, 0x01, 0x6d, 0x31, 0x2b, 0xbf, 0x22, 0x27, 0x0a, 0xbe,
- 0x24, 0x6d, 0xaf, 0x53, 0x4a, 0xae, 0x95, 0x9c, 0x1b, 0xee, 0x95, 0xf2,
- 0x51, 0xbc, 0x5f, 0x96, 0x9c, 0x8d, 0xfe, 0x4b, 0xae, 0xcc, 0xe8, 0x77,
- 0x7c, 0xf6, 0x36, 0xf6, 0x6a, 0xca, 0xa5, 0xd0, 0xbe, 0xbc, 0xfc, 0xb7,
- 0xb8, 0x66, 0x7f, 0x3f, 0x77, 0x34, 0xdd, 0x3f, 0xc5, 0x3d, 0x9f, 0x0f,
- 0x99, 0x79, 0xf0, 0x9a, 0x75, 0xc3, 0x71, 0xc3, 0xf9, 0x72, 0xfc, 0x61,
- 0xcc, 0x99, 0x34, 0x84, 0x73, 0x96, 0x72, 0x14, 0xb4, 0xd4, 0x57, 0xba,
- 0xac, 0xb5, 0x95, 0x51, 0x79, 0x62, 0xf9, 0x01, 0xc9, 0xfb, 0x41, 0x30,
- 0xeb, 0x4b, 0xdc, 0x96, 0x41, 0xb7, 0x80, 0x0a, 0x5b, 0x0d, 0xb1, 0xea,
- 0x15, 0x89, 0xb5, 0x83, 0x2f, 0x3f, 0x58, 0x61, 0xdf, 0x0e, 0x9e, 0xf5,
- 0xa1, 0x7e, 0xb7, 0xb5, 0xbe, 0x02, 0xfa, 0xb3, 0xe4, 0x4f, 0x10, 0x2c,
- 0xfa, 0x83, 0x89, 0x39, 0x8c, 0x79, 0xb9, 0x31, 0x38, 0x7e, 0x43, 0x5c,
- 0xf4, 0xd9, 0x8b, 0x3a, 0xe4, 0x15, 0xfb, 0x62, 0x9f, 0xec, 0xaf, 0x0b,
- 0x6d, 0xe3, 0x78, 0x47, 0xba, 0x82, 0x20, 0xef, 0xbb, 0xbc, 0x97, 0x4d,
- 0xf0, 0x6f, 0x93, 0xfc, 0xeb, 0xec, 0x97, 0x57, 0x1a, 0x1c, 0x63, 0x37,
- 0xda, 0x47, 0xfe, 0x3f, 0xa4, 0x3d, 0x81, 0xfe, 0xe3, 0x28, 0xf7, 0x58,
- 0xf5, 0x6a, 0x80, 0xf1, 0x13, 0xb8, 0xde, 0x6d, 0x1e, 0xd7, 0xd5, 0xda,
- 0x5f, 0xc2, 0xda, 0xbb, 0xd9, 0xb8, 0x3c, 0xbf, 0xd1, 0x8f, 0x79, 0x24,
- 0xe4, 0x1b, 0x90, 0xcd, 0x9e, 0x83, 0x7b, 0x24, 0x0d, 0xd9, 0xe4, 0x9a,
- 0x8f, 0xad, 0xce, 0x49, 0x29, 0x9e, 0x1a, 0xa6, 0x1e, 0xcd, 0x8f, 0xed,
- 0xc3, 0x7c, 0xb5, 0xb6, 0x1a, 0x58, 0xca, 0xed, 0xb7, 0xe5, 0x90, 0xd8,
- 0x59, 0x8c, 0x9b, 0x19, 0x01, 0x2d, 0x11, 0xbc, 0x8b, 0x8b, 0xb7, 0x9a,
- 0xc3, 0xb3, 0x54, 0xa2, 0x04, 0x1a, 0xe7, 0x41, 0x63, 0x49, 0xca, 0x62,
- 0x5f, 0x7c, 0xce, 0x0a, 0xf7, 0x8a, 0xe6, 0xdd, 0xb0, 0xe9, 0x67, 0x5b,
- 0xce, 0x2d, 0x7b, 0xb5, 0xcb, 0x8a, 0xac, 0x8e, 0xca, 0xa9, 0x5d, 0x78,
- 0x56, 0x07, 0xcf, 0xec, 0xa5, 0x70, 0x1f, 0x38, 0xb8, 0xef, 0x43, 0xdd,
- 0x6e, 0xcb, 0x59, 0xbd, 0x95, 0x5f, 0x6b, 0x8d, 0x41, 0x7f, 0x0b, 0xfc,
- 0xb2, 0x57, 0x7b, 0x51, 0xe7, 0x56, 0x7e, 0xd5, 0xc1, 0x2f, 0x7b, 0x55,
- 0xf3, 0xaa, 0x0e, 0x5e, 0xd9, 0x4b, 0x71, 0x94, 0x7b, 0x2c, 0xfb, 0xac,
- 0xe6, 0x55, 0xdd, 0xec, 0x99, 0xf3, 0x4a, 0x5f, 0xe5, 0x40, 0xab, 0x25,
- 0x5a, 0x67, 0xe5, 0x84, 0xba, 0x29, 0x92, 0x2d, 0x62, 0xaf, 0xdb, 0xe0,
- 0x85, 0x23, 0xc5, 0x31, 0x4b, 0x66, 0xd5, 0xbb, 0xa2, 0xa4, 0x1b, 0x1f,
- 0x00, 0x23, 0x47, 0x86, 0x61, 0x29, 0xca, 0x6d, 0xd9, 0x17, 0xed, 0xad,
- 0x4a, 0x4c, 0x0a, 0x4e, 0x52, 0xbc, 0x25, 0xa5, 0xc7, 0x9b, 0xfa, 0x99,
- 0x41, 0x3f, 0xdf, 0x01, 0x3f, 0x2c, 0xe8, 0x56, 0xbe, 0x7b, 0x4c, 0xed,
- 0xfb, 0xf4, 0xaa, 0x23, 0x83, 0x4b, 0xac, 0x53, 0xb6, 0xaf, 0x34, 0xde,
- 0x09, 0x74, 0xbf, 0x8f, 0x71, 0x4c, 0xd7, 0xce, 0x2e, 0xda, 0x97, 0xd7,
- 0x4f, 0xdb, 0x57, 0x1b, 0xe8, 0xb7, 0xc1, 0xb5, 0xc0, 0x5a, 0x2d, 0x63,
- 0xad, 0x96, 0xb1, 0x6e, 0x66, 0x4f, 0xd7, 0xd4, 0xde, 0x4a, 0x9a, 0x75,
- 0x25, 0x0d, 0x5c, 0xdb, 0x04, 0xd6, 0x94, 0x6b, 0x2b, 0xd6, 0xab, 0x99,
- 0x3d, 0x12, 0x39, 0x1b, 0x51, 0x6b, 0xda, 0xb3, 0xfa, 0x91, 0xed, 0x35,
- 0x1d, 0x68, 0x5a, 0x53, 0xfb, 0x5d, 0xd6, 0xd4, 0xd9, 0x65, 0x4d, 0xb7,
- 0x1a, 0x3f, 0x31, 0x6b, 0xfa, 0x73, 0x31, 0xb2, 0xff, 0x9e, 0xfc, 0x1a,
- 0x00, 0xbf, 0xbc, 0x5f, 0x83, 0x5f, 0xce, 0xae, 0xfc, 0xea, 0xb3, 0x5b,
- 0xf9, 0x15, 0x01, 0xbf, 0xa2, 0xbf, 0x36, 0xbf, 0xc0, 0x87, 0x5d, 0x79,
- 0x15, 0x83, 0xde, 0x2b, 0x4b, 0x3e, 0x23, 0x92, 0xaf, 0x6a, 0x5d, 0x5d,
- 0x56, 0x3a, 0x9b, 0xba, 0x2a, 0xd4, 0xd9, 0xd4, 0xd7, 0x6a, 0x9f, 0x58,
- 0x85, 0x4a, 0x12, 0xba, 0xd4, 0x41, 0xf9, 0x1c, 0xca, 0x3d, 0xd6, 0x74,
- 0xb5, 0x1f, 0x76, 0x36, 0x10, 0x77, 0x2c, 0xb4, 0x97, 0xe5, 0x84, 0x8b,
- 0xb5, 0x71, 0xef, 0x8a, 0x8a, 0xf4, 0xa5, 0xc0, 0xa7, 0x14, 0xde, 0xa7,
- 0x12, 0x39, 0xc9, 0xda, 0x21, 0xae, 0xc9, 0x57, 0x3a, 0xde, 0xce, 0xa9,
- 0x2b, 0x3e, 0x67, 0xbb, 0x0c, 0x9e, 0x45, 0x65, 0x06, 0x76, 0xa0, 0xe8,
- 0x71, 0x3c, 0xf6, 0x9f, 0x9c, 0xe1, 0xb8, 0x85, 0x46, 0xa8, 0xb3, 0x25,
- 0x07, 0x1b, 0x8e, 0x77, 0xdc, 0xb7, 0xe3, 0x56, 0x41, 0xd9, 0xa0, 0x8c,
- 0x78, 0x8d, 0x66, 0xfb, 0xb2, 0x4d, 0x27, 0xf6, 0x73, 0x0e, 0x72, 0x4d,
- 0xda, 0x92, 0xd8, 0x7b, 0xc7, 0x22, 0xe1, 0xfa, 0x38, 0xd9, 0x71, 0x81,
- 0x5d, 0x96, 0xf9, 0x0a, 0xfb, 0xfb, 0x63, 0x2b, 0x72, 0x31, 0xec, 0x9f,
- 0x7c, 0x64, 0xdf, 0xba, 0xbf, 0xf9, 0xc6, 0x5b, 0x46, 0x37, 0x28, 0x5b,
- 0x85, 0xfe, 0xca, 0x4d, 0xfd, 0x95, 0xad, 0xc8, 0x92, 0xec, 0x53, 0xf6,
- 0xe0, 0x28, 0xf9, 0x77, 0x1a, 0xef, 0xae, 0x4b, 0x84, 0x32, 0xa3, 0xf6,
- 0x18, 0xf7, 0xfb, 0x97, 0x38, 0xdf, 0x26, 0xde, 0x4e, 0xc3, 0xc6, 0x71,
- 0x7f, 0x61, 0x8d, 0xe3, 0x7c, 0x7e, 0xc8, 0xd0, 0xe4, 0x48, 0x4e, 0xdd,
- 0x7f, 0x63, 0x4f, 0xa8, 0x3f, 0xb1, 0x9f, 0x41, 0xdb, 0x8b, 0x6a, 0x8e,
- 0x76, 0x36, 0x0b, 0xde, 0x34, 0xd3, 0xc8, 0x79, 0x67, 0xb1, 0xc6, 0xa1,
- 0x0e, 0x0b, 0xd7, 0x8a, 0xb8, 0xc6, 0xb1, 0x16, 0x2a, 0x5d, 0xb0, 0x8f,
- 0x31, 0x63, 0x83, 0xd9, 0x7e, 0x11, 0xed, 0xf9, 0x9c, 0x6d, 0xbb, 0x60,
- 0x8f, 0xd9, 0x7e, 0xd1, 0xb4, 0xdf, 0xb1, 0xcb, 0xdc, 0x2b, 0xb4, 0xc9,
- 0x57, 0x32, 0xc0, 0x42, 0x2b, 0xb6, 0x14, 0x7c, 0xe0, 0x1c, 0xbf, 0xdf,
- 0xec, 0x0b, 0x2d, 0x9b, 0x1f, 0x75, 0x2c, 0x69, 0xf7, 0x76, 0x93, 0xcd,
- 0x7f, 0xb0, 0xb5, 0xad, 0xdb, 0x91, 0xcd, 0x05, 0xe8, 0xa8, 0x53, 0x90,
- 0x95, 0xc5, 0xed, 0x7a, 0x94, 0x4b, 0x25, 0xa3, 0x90, 0xcd, 0xd4, 0x38,
- 0xa7, 0x79, 0xa5, 0xd1, 0x2c, 0xa3, 0x61, 0x1f, 0x31, 0x25, 0x07, 0x7a,
- 0x9c, 0xc5, 0xa6, 0x71, 0x16, 0x9b, 0xc6, 0x59, 0x32, 0xd8, 0x8e, 0xfd,
- 0x68, 0xbb, 0x7a, 0xfd, 0x26, 0x7b, 0xce, 0x35, 0xfb, 0x24, 0xf6, 0xa4,
- 0x96, 0x05, 0x60, 0x35, 0xbd, 0x06, 0x15, 0x57, 0xe6, 0x37, 0x2e, 0x84,
- 0x7b, 0xb5, 0xdc, 0x8e, 0xe7, 0x3f, 0xc4, 0xf3, 0xe1, 0x33, 0x2e, 0xec,
- 0x14, 0xb1, 0xda, 0x4b, 0x72, 0xae, 0x42, 0x19, 0x79, 0x11, 0x74, 0xa7,
- 0xfd, 0x36, 0x8b, 0x7c, 0x4d, 0x0d, 0x9f, 0x97, 0x54, 0x72, 0x5e, 0x46,
- 0x7c, 0x96, 0x4f, 0x88, 0xc2, 0x58, 0xa2, 0x31, 0xd0, 0x8b, 0x90, 0x3f,
- 0x91, 0x1f, 0x57, 0xda, 0xc5, 0x1e, 0xfb, 0x61, 0x40, 0x3b, 0x78, 0x7a,
- 0xa3, 0xb5, 0x1f, 0x91, 0xa1, 0x33, 0xaa, 0x1f, 0xf4, 0x91, 0xf6, 0xbf,
- 0xad, 0xfa, 0x0b, 0xfb, 0xc2, 0x3c, 0xc7, 0x5a, 0xfb, 0x73, 0xe4, 0xba,
- 0x6b, 0xa3, 0xbf, 0xb4, 0x99, 0x23, 0xaf, 0x21, 0x23, 0xae, 0x83, 0xf2,
- 0x61, 0x3b, 0x94, 0x19, 0x7b, 0xec, 0x3b, 0x41, 0x6e, 0x9a, 0x73, 0x2b,
- 0x99, 0x67, 0xff, 0xc3, 0xc8, 0x9b, 0x54, 0xed, 0x2c, 0x78, 0x96, 0x19,
- 0xc4, 0x78, 0xbc, 0x4f, 0x02, 0x1f, 0x49, 0x99, 0xf8, 0xac, 0x54, 0xf9,
- 0x65, 0x90, 0x73, 0x34, 0xa6, 0xd2, 0x6b, 0xcf, 0xf7, 0x96, 0x14, 0x50,
- 0x77, 0xc1, 0xe8, 0x83, 0x62, 0xe3, 0xba, 0xe2, 0xdf, 0xf3, 0x6a, 0x1f,
- 0xa5, 0x4e, 0x97, 0xa9, 0x37, 0x36, 0xdc, 0x08, 0xf7, 0xf8, 0x25, 0xff,
- 0xa5, 0x60, 0x61, 0x39, 0x95, 0x4c, 0xda, 0x83, 0x52, 0xaa, 0x0e, 0x96,
- 0x6d, 0x94, 0x27, 0x6a, 0x09, 0x39, 0x51, 0x61, 0x3f, 0xfb, 0x51, 0x07,
- 0x8a, 0xc8, 0xc6, 0x26, 0xef, 0xa3, 0xae, 0xe1, 0x98, 0x6f, 0x5b, 0x7a,
- 0x4c, 0xcc, 0xc1, 0xdb, 0xb4, 0xfe, 0x63, 0xe3, 0x8a, 0x55, 0xaa, 0x71,
- 0xfd, 0xf1, 0xbc, 0xd1, 0xac, 0x8f, 0x42, 0x5d, 0xb4, 0x83, 0xc5, 0x22,
- 0xd9, 0x45, 0xab, 0xb4, 0x22, 0x76, 0xde, 0x8f, 0x12, 0x0f, 0x26, 0x45,
- 0xee, 0x75, 0xf5, 0x3c, 0x3f, 0x19, 0xa1, 0x1e, 0x74, 0xbc, 0xd3, 0xe8,
- 0xbb, 0x53, 0x72, 0x0e, 0xd7, 0x9f, 0xd7, 0x12, 0x44, 0xb2, 0x1e, 0x6d,
- 0xa5, 0x13, 0xc9, 0x3a, 0xd8, 0x63, 0xac, 0xf3, 0x52, 0xc0, 0xbd, 0x90,
- 0xaf, 0x6a, 0x19, 0x29, 0xef, 0x60, 0x2f, 0xd0, 0x9b, 0x83, 0x8e, 0x11,
- 0x1b, 0x7b, 0xcc, 0x8d, 0x64, 0xf9, 0x7c, 0x1c, 0xd7, 0x9b, 0xa8, 0x4f,
- 0x1d, 0x0b, 0x4c, 0x5a, 0x53, 0xbc, 0xc3, 0x58, 0x39, 0xab, 0x58, 0x09,
- 0x79, 0xf2, 0x52, 0xf0, 0xe4, 0x72, 0x88, 0x11, 0x94, 0x6c, 0xc9, 0xc0,
- 0xd9, 0xa4, 0xd9, 0xd7, 0x5d, 0xdc, 0x73, 0xe4, 0x3f, 0x9e, 0xf9, 0xe6,
- 0x59, 0x7b, 0xd3, 0xb3, 0x70, 0xff, 0x7f, 0x09, 0xb4, 0xf5, 0x2b, 0xfe,
- 0xd8, 0xd9, 0x23, 0x56, 0x5e, 0xe1, 0x93, 0x20, 0x28, 0x78, 0x51, 0x29,
- 0x8d, 0xfe, 0x09, 0xe6, 0xca, 0x77, 0x65, 0x30, 0x9c, 0x76, 0x63, 0x78,
- 0x72, 0xd6, 0x4b, 0x29, 0xfb, 0x9f, 0xc7, 0xfe, 0xd3, 0x3a, 0x53, 0xca,
- 0x3d, 0xa0, 0xdd, 0x5b, 0xe2, 0x9a, 0xbc, 0x14, 0x9c, 0x05, 0x16, 0x9e,
- 0x5e, 0x2a, 0x5a, 0x03, 0xd8, 0x12, 0x76, 0x9f, 0x05, 0x3e, 0x77, 0x49,
- 0xfe, 0x22, 0xd7, 0x82, 0x75, 0xf8, 0xbc, 0x4d, 0xa6, 0xe3, 0xad, 0xb6,
- 0xf2, 0xdc, 0x3e, 0xe9, 0x24, 0xbf, 0x51, 0x77, 0xe9, 0xff, 0x46, 0xb4,
- 0x5e, 0x76, 0x65, 0x60, 0x95, 0x7c, 0x2f, 0x5a, 0xb3, 0x15, 0xea, 0xb1,
- 0x0e, 0xd8, 0x47, 0x3e, 0x67, 0x9f, 0x78, 0x77, 0xbe, 0xb5, 0x8f, 0xdf,
- 0x8b, 0xe8, 0x3e, 0xd8, 0x2e, 0xec, 0xa3, 0x99, 0x1f, 0x7b, 0x94, 0x9e,
- 0xeb, 0xcd, 0xf6, 0xb6, 0xf4, 0x9b, 0x68, 0xea, 0x17, 0xef, 0xce, 0x7f,
- 0x37, 0x42, 0x5c, 0xf6, 0xf2, 0x32, 0xf8, 0xac, 0xe6, 0xc4, 0x77, 0x6c,
- 0x53, 0xb4, 0x0a, 0x4b, 0x41, 0x30, 0xed, 0xdb, 0x12, 0xe9, 0x0b, 0xeb,
- 0xea, 0x79, 0x15, 0x31, 0xaf, 0x3c, 0xe6, 0x65, 0xf7, 0xb5, 0xd2, 0xf4,
- 0xfb, 0x86, 0xa6, 0xde, 0x26, 0x9a, 0xe2, 0xef, 0x31, 0xaf, 0xf8, 0x2e,
- 0xf3, 0x7a, 0xa9, 0x57, 0xf7, 0x11, 0x6f, 0xea, 0xa3, 0xaf, 0xa5, 0x0f,
- 0xe8, 0xfd, 0x38, 0xdb, 0xf7, 0xed, 0xd2, 0xfe, 0x87, 0x1d, 0xba, 0x3d,
- 0xdb, 0xb4, 0x41, 0xb7, 0xf7, 0x1b, 0xbd, 0x78, 0xa2, 0x49, 0x97, 0x9d,
- 0x80, 0x2e, 0x6b, 0x6e, 0xd3, 0x2c, 0xff, 0xa1, 0x8f, 0x44, 0xff, 0x28,
- 0xc4, 0x8a, 0x1f, 0x50, 0x18, 0x64, 0x07, 0x63, 0xc7, 0x80, 0x47, 0xba,
- 0x60, 0xff, 0xbb, 0xe9, 0x07, 0x19, 0x4c, 0x48, 0xbf, 0x88, 0x38, 0x50,
- 0x3c, 0xa0, 0x28, 0xe8, 0x96, 0xc1, 0xc4, 0x31, 0x11, 0xe5, 0x07, 0x11,
- 0x5f, 0xd3, 0x27, 0xe2, 0x38, 0xf4, 0x89, 0xb8, 0xee, 0xbc, 0x2f, 0x6c,
- 0xfb, 0x48, 0xfd, 0xd8, 0xf7, 0xc4, 0xc7, 0xdc, 0x33, 0xa1, 0xad, 0x69,
- 0xd6, 0xa7, 0xbb, 0xd1, 0xd4, 0xdf, 0x42, 0x13, 0x74, 0x12, 0x7c, 0xb3,
- 0x05, 0xc8, 0x23, 0x30, 0x29, 0x74, 0xe0, 0xfd, 0x53, 0xe7, 0x56, 0x44,
- 0x4a, 0x0d, 0xda, 0xc7, 0x51, 0x81, 0x5f, 0x05, 0xba, 0xd8, 0xb7, 0xb2,
- 0x91, 0xd0, 0x4d, 0xdd, 0x39, 0x3b, 0x3b, 0x08, 0x3f, 0xdc, 0x91, 0x39,
- 0x43, 0xdb, 0x8c, 0xf2, 0xe1, 0xba, 0x50, 0x26, 0x94, 0x5c, 0xcd, 0x80,
- 0x3e, 0x5e, 0xcf, 0x18, 0xec, 0x7e, 0xac, 0xd1, 0x4a, 0xdb, 0xf7, 0x40,
- 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x02, 0xb0, 0xfb, 0x37, 0xd5, 0xbe, 0x0c,
- 0x75, 0x17, 0x65, 0x29, 0x55, 0x2d, 0xcb, 0x66, 0xb0, 0xb2, 0xcc, 0x7d,
- 0x4b, 0x1b, 0xde, 0x25, 0x65, 0xac, 0xd7, 0xc0, 0x52, 0x2a, 0x99, 0xb3,
- 0xc5, 0x7a, 0xdf, 0x41, 0xca, 0xd3, 0xe3, 0x32, 0x70, 0x51, 0x2c, 0x67,
- 0x09, 0x7b, 0xbd, 0x3b, 0xc4, 0x57, 0x9c, 0xdf, 0x6f, 0x63, 0x7e, 0xe8,
- 0x7b, 0x39, 0x9c, 0x5f, 0x97, 0x94, 0x56, 0x39, 0xbf, 0xed, 0xb9, 0xc5,
- 0x19, 0x11, 0xf9, 0x1c, 0xf4, 0x35, 0xe6, 0x08, 0x1a, 0xc7, 0x81, 0x73,
- 0xef, 0x30, 0x73, 0xea, 0xc2, 0x9c, 0x60, 0xa3, 0x97, 0xd8, 0x1e, 0x74,
- 0x81, 0xe6, 0x12, 0xea, 0xcd, 0x2f, 0x71, 0xcd, 0x41, 0x2b, 0xd6, 0xbd,
- 0xd4, 0xe0, 0xda, 0x73, 0x6e, 0xda, 0xae, 0x3b, 0x1e, 0xe7, 0xc7, 0x79,
- 0x0e, 0x63, 0x5e, 0xac, 0xc3, 0x76, 0xad, 0x32, 0x32, 0xfc, 0x1e, 0xeb,
- 0xf1, 0xdb, 0x2d, 0xeb, 0x21, 0x66, 0x3d, 0x62, 0xd2, 0xb6, 0xaa, 0xfc,
- 0x65, 0x45, 0x03, 0x7d, 0x08, 0x07, 0xf4, 0x2f, 0xae, 0xc8, 0x68, 0x54,
- 0x48, 0x7b, 0x82, 0xcf, 0x32, 0x6d, 0x32, 0xe8, 0x5f, 0x81, 0x5c, 0x95,
- 0x20, 0x0b, 0xf4, 0x07, 0x5e, 0x5e, 0xd6, 0x6b, 0x51, 0x6a, 0x74, 0xc2,
- 0x47, 0xe7, 0xf8, 0xe4, 0x37, 0xe7, 0xe6, 0xaa, 0x75, 0x68, 0x5e, 0x97,
- 0x4f, 0xdf, 0xb2, 0x2e, 0xd4, 0xbb, 0xd4, 0x03, 0xc4, 0x3d, 0xd4, 0x05,
- 0x61, 0x4c, 0xa0, 0xe6, 0xea, 0xfd, 0x14, 0xda, 0x9f, 0xeb, 0xdb, 0xf8,
- 0x52, 0xaf, 0x59, 0xc2, 0xc4, 0x05, 0xba, 0xc4, 0x5e, 0xbd, 0x83, 0x7a,
- 0x1f, 0xf6, 0x27, 0x9c, 0xdf, 0xef, 0xe0, 0x3e, 0x71, 0xd3, 0x7a, 0xd8,
- 0x98, 0x93, 0xa3, 0xe6, 0xa8, 0xd6, 0x62, 0x5b, 0xe6, 0xe6, 0x1a, 0x7a,
- 0x5e, 0xce, 0xd2, 0x1e, 0xb3, 0x1e, 0x31, 0x3c, 0xe3, 0xbc, 0x42, 0x9b,
- 0xc3, 0x79, 0x91, 0x5e, 0xd7, 0xc8, 0x1c, 0xe7, 0xc3, 0xfd, 0xd7, 0x2c,
- 0x6b, 0x2f, 0x05, 0xd5, 0xe5, 0xa8, 0x9a, 0x7b, 0xde, 0xef, 0x26, 0x46,
- 0xa3, 0x8e, 0x34, 0xfa, 0x89, 0xcf, 0x69, 0x07, 0xf1, 0x2e, 0x43, 0x19,
- 0xc2, 0x7d, 0x9d, 0xf7, 0xcd, 0x36, 0xed, 0x79, 0x47, 0xeb, 0x01, 0xc6,
- 0x9f, 0xde, 0xdb, 0xd6, 0x45, 0xb3, 0x62, 0xad, 0x57, 0xe8, 0x33, 0x07,
- 0xc0, 0x5d, 0x77, 0x40, 0xaf, 0x1c, 0x92, 0x92, 0x0b, 0x7b, 0x3d, 0x7c,
- 0x3b, 0xe6, 0x3c, 0x2e, 0x2a, 0xde, 0x30, 0xbc, 0x17, 0xd7, 0x7b, 0x94,
- 0xef, 0x52, 0x1a, 0xfe, 0x90, 0xe4, 0xa6, 0x69, 0xd3, 0x7e, 0x5f, 0x66,
- 0x60, 0x5b, 0x4b, 0xc3, 0x77, 0x82, 0x3e, 0xde, 0x43, 0x27, 0x7a, 0x43,
- 0x8c, 0x51, 0xe0, 0xef, 0x71, 0x13, 0x9b, 0x39, 0x80, 0xfb, 0x3d, 0xa8,
- 0xf3, 0x49, 0x53, 0xa7, 0x1b, 0x75, 0x06, 0x5b, 0xea, 0x70, 0xbc, 0xfb,
- 0x50, 0x07, 0xf6, 0x14, 0x56, 0xd2, 0xf6, 0x0e, 0xe2, 0x37, 0x81, 0x67,
- 0xf7, 0xe2, 0xd9, 0x3d, 0x78, 0x76, 0x0f, 0xee, 0x7f, 0xd7, 0xc4, 0x3c,
- 0xc2, 0x36, 0xdd, 0xb8, 0xff, 0x12, 0xde, 0x43, 0xc7, 0xb9, 0xdf, 0xc6,
- 0xfb, 0xfb, 0xf0, 0x1b, 0x6b, 0xa9, 0xe3, 0xb6, 0xdc, 0x9f, 0x76, 0x74,
- 0x8c, 0x84, 0xcf, 0x82, 0xc8, 0xce, 0xf5, 0x7f, 0x35, 0xcf, 0xbd, 0xa6,
- 0xf7, 0x1f, 0x37, 0xd7, 0xad, 0xb2, 0x94, 0x86, 0x2c, 0xf1, 0xfd, 0x57,
- 0xf6, 0xe9, 0xb5, 0xb8, 0x43, 0xc7, 0x1f, 0x6e, 0xc2, 0x1b, 0x4a, 0xfc,
- 0x71, 0xbd, 0x09, 0x9c, 0x41, 0xec, 0xd1, 0x8c, 0x3b, 0x48, 0x8b, 0xab,
- 0xe4, 0xf5, 0xe5, 0xe5, 0xd7, 0xba, 0xf5, 0x18, 0x62, 0xd5, 0x21, 0x73,
- 0x13, 0x2a, 0x16, 0xf1, 0x33, 0xf3, 0xcc, 0xdb, 0xb7, 0xf3, 0x6e, 0xaf,
- 0x4c, 0x54, 0xff, 0x68, 0xdf, 0x0e, 0x6d, 0x93, 0x4d, 0xd7, 0x3b, 0x98,
- 0x02, 0xfe, 0x84, 0xbd, 0x83, 0x77, 0x72, 0xf6, 0x5c, 0xa3, 0x68, 0xeb,
- 0x71, 0x59, 0x07, 0xef, 0x1a, 0x9b, 0x3d, 0x8e, 0x92, 0xfd, 0x9c, 0x4d,
- 0x5f, 0xa3, 0xbc, 0xc6, 0xeb, 0xdb, 0x51, 0x36, 0xb7, 0xed, 0x87, 0x1e,
- 0xcf, 0xd9, 0x9a, 0xee, 0xd6, 0xf6, 0xe1, 0xbe, 0xf1, 0x65, 0xa1, 0x0a,
- 0x99, 0xf3, 0x52, 0xc3, 0x65, 0xac, 0xdd, 0xac, 0x9f, 0x9a, 0xa6, 0x4c,
- 0xc2, 0x9f, 0xfd, 0x94, 0xc8, 0xa4, 0xcc, 0x57, 0x1f, 0x06, 0xfe, 0x0e,
- 0xe4, 0x21, 0xe0, 0x8a, 0x7f, 0x0f, 0x5c, 0x52, 0x83, 0xac, 0xd7, 0x1a,
- 0x1e, 0x7e, 0xfd, 0xf2, 0x57, 0x95, 0x84, 0x3c, 0x07, 0x7f, 0x02, 0xb2,
- 0x06, 0x3d, 0x9c, 0x76, 0x1f, 0x12, 0xe9, 0xb1, 0xe5, 0xf2, 0xbd, 0xb6,
- 0x8c, 0x24, 0x07, 0xac, 0x74, 0x02, 0x3f, 0xb7, 0x0d, 0xbf, 0x22, 0x7c,
- 0xb8, 0xb5, 0x06, 0x63, 0x01, 0x71, 0xf9, 0xeb, 0xf5, 0x24, 0x7e, 0x7d,
- 0xf2, 0x37, 0xeb, 0x1c, 0x7f, 0xc0, 0x94, 0x6a, 0x1f, 0xc3, 0xe7, 0x28,
- 0xcb, 0x62, 0x26, 0x21, 0x0b, 0x95, 0xe0, 0xa4, 0xf6, 0x99, 0x3d, 0xf8,
- 0xc8, 0xdc, 0xb3, 0x2f, 0x60, 0xcf, 0xe2, 0xb9, 0xc2, 0x9e, 0xa1, 0xdd,
- 0x7b, 0x01, 0x76, 0x2f, 0x5c, 0x23, 0xce, 0xb3, 0x75, 0x7d, 0xd8, 0x2f,
- 0xd7, 0x88, 0x7a, 0x9d, 0xba, 0x3c, 0x06, 0xfc, 0x10, 0xea, 0x76, 0xea,
- 0x08, 0x6f, 0xdb, 0x0f, 0x7d, 0xe4, 0x60, 0x17, 0xb0, 0x86, 0xc4, 0xe2,
- 0xd9, 0x9f, 0xca, 0xca, 0x59, 0xee, 0x1b, 0xda, 0xe3, 0xbb, 0x21, 0x6f,
- 0xa9, 0xaf, 0x96, 0x89, 0x99, 0xbd, 0x0c, 0xf8, 0x51, 0x96, 0xe9, 0x83,
- 0xab, 0xbd, 0x5a, 0x4e, 0x26, 0xc5, 0x39, 0xfb, 0x85, 0xa8, 0x74, 0x9f,
- 0x94, 0x45, 0x1f, 0x7e, 0xa9, 0x5d, 0x0e, 0x22, 0x9e, 0x97, 0x28, 0x28,
- 0xbf, 0x69, 0x05, 0x74, 0xc6, 0x64, 0xe2, 0x2c, 0xeb, 0x9c, 0x84, 0x8c,
- 0xb5, 0x81, 0xe6, 0x76, 0x39, 0x15, 0x4f, 0x95, 0x0b, 0xf0, 0xf7, 0x6d,
- 0xaf, 0x47, 0x06, 0xea, 0x2c, 0x89, 0x41, 0xfe, 0x37, 0xe4, 0x87, 0xd7,
- 0xf0, 0x03, 0x57, 0xf9, 0x7c, 0x00, 0x25, 0x9f, 0x7b, 0xd0, 0x2f, 0xe4,
- 0x07, 0x70, 0xc3, 0xc5, 0xb2, 0x9c, 0xca, 0x4c, 0x4a, 0xbd, 0x2a, 0xd6,
- 0x42, 0x06, 0x7b, 0xa0, 0x96, 0x95, 0x3a, 0x78, 0x51, 0x6a, 0x1c, 0x87,
- 0xdf, 0xf9, 0x26, 0xca, 0x39, 0x94, 0xd7, 0x51, 0x3e, 0x8e, 0xf2, 0x2d,
- 0x94, 0xa4, 0xfd, 0xb8, 0xd4, 0x6b, 0x7b, 0xda, 0xa4, 0x93, 0x7d, 0x6c,
- 0x18, 0x9a, 0xe1, 0x3b, 0x1e, 0x3c, 0x0e, 0x2c, 0x1a, 0x3e, 0x3f, 0x2e,
- 0x52, 0xff, 0x0c, 0x7e, 0x0f, 0xaa, 0x7b, 0xfa, 0x96, 0x0b, 0x99, 0x71,
- 0xe0, 0x7a, 0xb1, 0x4e, 0x65, 0x1e, 0x37, 0xfd, 0x7c, 0x06, 0xe3, 0x5d,
- 0xc5, 0xd8, 0x31, 0xc8, 0x48, 0x20, 0x8f, 0xf8, 0x27, 0xe5, 0x73, 0xfe,
- 0x7e, 0x19, 0xeb, 0x8d, 0x95, 0x63, 0x59, 0xce, 0x9f, 0x7a, 0x6a, 0xb7,
- 0xf9, 0x87, 0xf3, 0xe6, 0x9c, 0xa1, 0x5b, 0x97, 0xf6, 0x6a, 0xdc, 0x6d,
- 0x7f, 0x39, 0xaa, 0x69, 0xb1, 0x64, 0x60, 0x88, 0xfd, 0x65, 0x25, 0x72,
- 0x76, 0xc8, 0xcd, 0xd8, 0x23, 0xf0, 0x52, 0xd2, 0xf8, 0x9d, 0x84, 0xfc,
- 0x79, 0xa7, 0x07, 0xec, 0xdb, 0x40, 0x13, 0xde, 0xd5, 0x39, 0x0e, 0xec,
- 0xe9, 0x3d, 0xaf, 0x62, 0x6e, 0x65, 0x69, 0xbf, 0x27, 0x2b, 0x37, 0x1a,
- 0xbc, 0x86, 0x3d, 0xba, 0x30, 0x29, 0xff, 0x5c, 0xbd, 0x2a, 0x4f, 0x54,
- 0x27, 0xe5, 0x0d, 0x94, 0x8b, 0xd5, 0x32, 0xf8, 0xc8, 0x58, 0x3c, 0xfb,
- 0x08, 0xb0, 0x2e, 0x83, 0xf0, 0x8d, 0x3e, 0x98, 0x98, 0xc3, 0xfa, 0xcd,
- 0xb8, 0x81, 0x9c, 0xf3, 0xcb, 0x72, 0x6e, 0x1c, 0x6d, 0x6a, 0x1d, 0x12,
- 0x7d, 0x96, 0xf3, 0xed, 0x96, 0x02, 0x2c, 0x7a, 0x31, 0x43, 0x9d, 0xd9,
- 0x29, 0x85, 0x5a, 0xab, 0xdc, 0x51, 0xde, 0xde, 0xb6, 0xea, 0xdb, 0x3a,
- 0x60, 0xd3, 0xfa, 0x66, 0x83, 0x36, 0x78, 0x37, 0x7b, 0xaa, 0xe5, 0xae,
- 0x5e, 0xa3, 0x4d, 0xdd, 0x91, 0xbd, 0x3a, 0xfc, 0xb9, 0x7a, 0xf5, 0xba,
- 0x91, 0x3f, 0x25, 0xb7, 0x58, 0x17, 0x62, 0xf1, 0x9f, 0x08, 0xb0, 0x1f,
- 0x78, 0x14, 0xc6, 0x09, 0xb5, 0x7f, 0x54, 0x03, 0xad, 0x85, 0x38, 0x71,
- 0x06, 0xac, 0x5b, 0xed, 0x0b, 0x8a, 0x57, 0xde, 0xd9, 0x7e, 0xa9, 0x2e,
- 0x93, 0xbf, 0x29, 0xd7, 0xb6, 0x95, 0x4f, 0x02, 0xbe, 0x7a, 0x58, 0x9f,
- 0xf0, 0x7d, 0x0a, 0x7e, 0xd2, 0x49, 0x71, 0xc7, 0x3a, 0x31, 0x27, 0x5e,
- 0x8b, 0x4c, 0x5f, 0x6c, 0xc5, 0x91, 0xa1, 0x9d, 0x68, 0x83, 0x3f, 0x1e,
- 0xc5, 0x5a, 0x76, 0xc1, 0x9f, 0x86, 0x9f, 0x0a, 0x39, 0xfa, 0x33, 0x60,
- 0xaf, 0xd3, 0xca, 0xb7, 0xe6, 0x9e, 0xea, 0x9e, 0x1a, 0x58, 0x67, 0xb9,
- 0x77, 0x2a, 0x5d, 0x63, 0x19, 0x9f, 0xd2, 0xbe, 0x64, 0x62, 0x4a, 0xc7,
- 0xed, 0x93, 0x53, 0x07, 0x54, 0xe9, 0x4d, 0x0d, 0xab, 0x72, 0x78, 0x6a,
- 0x27, 0x66, 0x42, 0x9e, 0x8a, 0x95, 0xcf, 0x64, 0xa4, 0x58, 0x21, 0x8d,
- 0xe2, 0x1c, 0x83, 0x3c, 0xcd, 0x01, 0xcb, 0xe4, 0x2b, 0xbe, 0x9c, 0xda,
- 0xc8, 0x82, 0x66, 0xe8, 0x99, 0xac, 0x8f, 0x52, 0xcc, 0x5f, 0xd8, 0xb6,
- 0x8d, 0x31, 0x32, 0xae, 0x99, 0xf1, 0x33, 0x7d, 0xfa, 0x99, 0xcd, 0x7f,
- 0xec, 0x0f, 0xb2, 0x49, 0xfb, 0xf9, 0x0b, 0xf8, 0xc6, 0xe2, 0x94, 0x32,
- 0x6c, 0xeb, 0xc3, 0x07, 0x17, 0xd9, 0x5a, 0x91, 0x58, 0x2c, 0xfb, 0x1d,
- 0x89, 0x3d, 0x1d, 0x04, 0x3f, 0xf0, 0x53, 0x47, 0xca, 0x02, 0x5e, 0x59,
- 0x78, 0xbe, 0xce, 0x77, 0xd4, 0x4d, 0x23, 0xee, 0x0d, 0xc8, 0x5c, 0xee,
- 0xa8, 0xc8, 0x2b, 0x78, 0x56, 0x5f, 0xe1, 0x1a, 0x7c, 0x17, 0x6b, 0x60,
- 0xd6, 0x44, 0x3d, 0x63, 0x3d, 0xf8, 0x58, 0x71, 0xce, 0x63, 0xc4, 0x6d,
- 0x47, 0xfb, 0xda, 0x3a, 0xdb, 0xa4, 0xc6, 0x79, 0xe4, 0xf5, 0xca, 0xba,
- 0x9e, 0xdf, 0xe1, 0xcc, 0xb0, 0x5c, 0xae, 0xa8, 0x3e, 0x20, 0xeb, 0xbf,
- 0x44, 0x9b, 0x4d, 0xc8, 0x2d, 0x63, 0x53, 0x59, 0x99, 0x07, 0x4e, 0x9b,
- 0xaf, 0xa4, 0x21, 0x3b, 0x8e, 0xcc, 0x24, 0x48, 0xb6, 0x27, 0x5b, 0x95,
- 0x37, 0xdb, 0x88, 0x85, 0xf3, 0x1e, 0xaf, 0xc7, 0x51, 0x67, 0x5a, 0x88,
- 0xb7, 0xf2, 0x19, 0xce, 0xa9, 0x99, 0x17, 0xfa, 0xaf, 0x84, 0xb5, 0x30,
- 0x73, 0x54, 0x7f, 0x7a, 0x1c, 0xb4, 0x37, 0xe3, 0x14, 0x01, 0x53, 0xe0,
- 0x6b, 0x4a, 0xfa, 0x82, 0xe3, 0xe4, 0x2b, 0x8e, 0x0c, 0x5c, 0xc0, 0xb6,
- 0xca, 0x1a, 0x5e, 0x34, 0x42, 0x59, 0x0b, 0x31, 0x10, 0x65, 0x8b, 0x3c,
- 0x48, 0x95, 0x37, 0xc1, 0xec, 0xde, 0xec, 0x35, 0x79, 0x74, 0x55, 0xcf,
- 0xd9, 0x3e, 0x2f, 0x3c, 0x0b, 0x91, 0x1b, 0x2b, 0x29, 0xff, 0x3a, 0xf4,
- 0x7d, 0x21, 0xee, 0x43, 0x56, 0xfe, 0x4b, 0x1b, 0xf6, 0xf4, 0x78, 0xce,
- 0xde, 0xdf, 0xae, 0x6d, 0xac, 0x83, 0x3d, 0x01, 0xac, 0x59, 0xc9, 0xa1,
- 0x4d, 0xbb, 0xfc, 0x5b, 0x07, 0xd7, 0xc4, 0x9e, 0x78, 0x66, 0xec, 0x22,
- 0xae, 0x75, 0x7f, 0xf3, 0x98, 0x87, 0x8e, 0x03, 0x5b, 0xf2, 0x28, 0x2c,
- 0x88, 0xa0, 0xff, 0x01, 0x33, 0xd6, 0xc0, 0xf9, 0x50, 0x36, 0x40, 0xf7,
- 0x6a, 0x16, 0xf8, 0xdd, 0x31, 0x7e, 0x2b, 0x75, 0x8c, 0xec, 0xe2, 0xf7,
- 0x34, 0xc7, 0x5e, 0x63, 0x2a, 0x4e, 0x47, 0x2c, 0x47, 0xd9, 0x3a, 0x62,
- 0x64, 0xeb, 0x33, 0x90, 0xad, 0xe3, 0x4a, 0xb6, 0x02, 0xf9, 0x81, 0xef,
- 0xcb, 0x97, 0x77, 0x95, 0xaf, 0xd6, 0xbf, 0x2e, 0xd0, 0xcb, 0x5f, 0x9f,
- 0x2c, 0xfc, 0x05, 0xc6, 0xbd, 0xe0, 0xe2, 0x3a, 0x95, 0x9b, 0x11, 0xf2,
- 0x31, 0x81, 0xeb, 0x18, 0xca, 0x7e, 0x55, 0x67, 0xe0, 0x02, 0xec, 0x1a,
- 0xe4, 0x8d, 0xfc, 0x9d, 0x87, 0x8d, 0x1b, 0xb8, 0x10, 0x85, 0x2d, 0xe4,
- 0x9e, 0x95, 0x5e, 0x1b, 0xba, 0x81, 0xf5, 0xeb, 0xd8, 0x3b, 0x03, 0x17,
- 0xba, 0x50, 0x26, 0x55, 0x5f, 0xf5, 0x8a, 0xa7, 0xda, 0xd7, 0x2b, 0xc3,
- 0xaa, 0x5d, 0xbd, 0x32, 0x8a, 0x12, 0xfa, 0x3d, 0xe3, 0xcb, 0xd0, 0x85,
- 0x8c, 0x24, 0x2f, 0x58, 0x52, 0x9a, 0x0e, 0x82, 0x18, 0x68, 0x1f, 0xbe,
- 0xd0, 0x23, 0xd7, 0xa7, 0x39, 0x37, 0xea, 0x62, 0xb1, 0x16, 0x33, 0xd3,
- 0xd8, 0x9b, 0xe4, 0x1f, 0xb0, 0xfe, 0x85, 0x22, 0x6c, 0x6e, 0x51, 0x4e,
- 0xad, 0x90, 0x3f, 0x8c, 0xb5, 0x6f, 0x25, 0x22, 0x92, 0x82, 0x2e, 0x3b,
- 0x2a, 0x73, 0xd5, 0x76, 0xe8, 0x32, 0xc7, 0xad, 0xcb, 0x13, 0x58, 0xa3,
- 0x41, 0xca, 0x03, 0xf8, 0x92, 0x45, 0xdf, 0x45, 0x29, 0xa0, 0x4d, 0x71,
- 0x65, 0xa7, 0x7e, 0x49, 0xda, 0xb1, 0xa7, 0x8e, 0xca, 0xb1, 0x2a, 0xfb,
- 0x71, 0xdc, 0x79, 0x39, 0x00, 0x19, 0xf2, 0xdc, 0x09, 0xf4, 0x03, 0x1b,
- 0xd9, 0xf4, 0xc7, 0xfd, 0x97, 0x7b, 0x0f, 0x99, 0x0c, 0xf7, 0x5d, 0xac,
- 0xdc, 0x96, 0x9d, 0xb6, 0xb6, 0x32, 0xe2, 0xcc, 0x66, 0x1e, 0xb2, 0x5e,
- 0xc9, 0x64, 0xac, 0x2b, 0x99, 0x9c, 0x75, 0x35, 0x53, 0xb4, 0xae, 0xc1,
- 0x36, 0xd5, 0x37, 0xde, 0x81, 0xfc, 0x00, 0x4f, 0x10, 0x7b, 0x6f, 0xaf,
- 0x61, 0xdc, 0xf8, 0x39, 0x6f, 0xc9, 0xb9, 0x0a, 0xed, 0x74, 0x70, 0x68,
- 0xd6, 0x2f, 0xdf, 0x0e, 0xfa, 0x40, 0x07, 0xe3, 0x11, 0x3b, 0xb6, 0x23,
- 0x9a, 0x1d, 0x06, 0x4e, 0xa0, 0xed, 0xe8, 0xa2, 0xed, 0xf0, 0x0b, 0xb2,
- 0x57, 0xb6, 0xaa, 0x3a, 0x2e, 0x97, 0x07, 0x6e, 0xda, 0xaa, 0xc5, 0xe5,
- 0xcb, 0xcb, 0xa1, 0x2c, 0x71, 0xbe, 0xf3, 0xef, 0xeb, 0x90, 0x88, 0x1c,
- 0x51, 0xf6, 0xba, 0x5b, 0x2e, 0xaf, 0x03, 0xd3, 0x02, 0x81, 0xd8, 0x77,
- 0x32, 0xce, 0x63, 0xab, 0xf8, 0x85, 0xf4, 0xf0, 0x3c, 0xf0, 0x1f, 0xc0,
- 0x2b, 0x9e, 0xd9, 0x61, 0x9e, 0x3d, 0x9c, 0x51, 0x78, 0x3f, 0x8a, 0x3d,
- 0xc9, 0x6b, 0x4b, 0x0a, 0xc0, 0xed, 0x5b, 0x15, 0x96, 0x09, 0x94, 0x26,
- 0x56, 0x0f, 0x5d, 0x10, 0xc9, 0xfe, 0xa3, 0x7a, 0xdf, 0xee, 0x89, 0x35,
- 0x0b, 0x3b, 0x5c, 0x5a, 0xa1, 0x4c, 0xa3, 0x5c, 0xd7, 0x63, 0x17, 0x7c,
- 0x60, 0xe6, 0xd1, 0x0e, 0xda, 0x37, 0xe0, 0x27, 0xec, 0x7b, 0x85, 0xed,
- 0x33, 0xd8, 0x73, 0x3f, 0x68, 0xa7, 0x6d, 0x3f, 0xec, 0x8f, 0xcb, 0xb5,
- 0x0a, 0xaf, 0xf9, 0x3e, 0xe5, 0x8b, 0x8a, 0x1b, 0xc7, 0xa6, 0x16, 0x3d,
- 0xdf, 0xec, 0x31, 0x15, 0xd3, 0xb1, 0x3e, 0x06, 0xcc, 0x38, 0x70, 0xa6,
- 0x4d, 0xd2, 0x4f, 0xdb, 0x7d, 0xfa, 0x7c, 0xe5, 0x90, 0x14, 0xfd, 0x03,
- 0x98, 0xc3, 0x3e, 0x99, 0x87, 0x2f, 0xb6, 0xb0, 0x31, 0x2c, 0xf3, 0xc3,
- 0xf0, 0xb9, 0xdd, 0xbb, 0x89, 0xd5, 0xf0, 0xeb, 0xc0, 0xf3, 0x41, 0x94,
- 0xed, 0x28, 0x6f, 0x97, 0xf9, 0xa7, 0xba, 0x63, 0xba, 0xbf, 0x68, 0xcb,
- 0xfd, 0xb3, 0x1c, 0x3b, 0x99, 0xb4, 0x7e, 0x15, 0x2e, 0x6c, 0xc6, 0x84,
- 0xa4, 0x23, 0x2a, 0xde, 0x93, 0x5d, 0x32, 0x78, 0xc6, 0x95, 0xa1, 0x33,
- 0x09, 0x39, 0x70, 0xa6, 0x5f, 0x86, 0xcf, 0x24, 0xe5, 0xce, 0x33, 0x21,
- 0xfe, 0xea, 0x9e, 0x4a, 0x1b, 0x5b, 0xe1, 0xfd, 0x9a, 0xb6, 0xe2, 0xce,
- 0x86, 0xc6, 0xa8, 0xf3, 0x6b, 0xc4, 0x74, 0xaf, 0x62, 0xef, 0x6e, 0xaa,
- 0xf3, 0xca, 0x4b, 0x1b, 0x41, 0x70, 0xc9, 0x6f, 0x77, 0xa7, 0x85, 0xfc,
- 0xce, 0x00, 0x9f, 0xf9, 0xd0, 0x61, 0xa3, 0xd0, 0x61, 0xe3, 0xca, 0x36,
- 0xd6, 0xbf, 0x2e, 0xd6, 0xb1, 0xcc, 0x03, 0xb2, 0x06, 0xd9, 0x7e, 0xd0,
- 0x4f, 0x7d, 0x75, 0x53, 0xf1, 0x47, 0x62, 0x3d, 0xd0, 0x67, 0x77, 0xaf,
- 0xb6, 0xcb, 0x1b, 0xf1, 0x20, 0x38, 0x0b, 0x1d, 0x50, 0xaf, 0x68, 0xf9,
- 0xcd, 0x7b, 0xd4, 0x05, 0x0f, 0x61, 0xfe, 0xa3, 0x78, 0x96, 0x33, 0xba,
- 0xbd, 0x43, 0x6e, 0xc4, 0x13, 0xb2, 0x7e, 0x60, 0xbc, 0xa5, 0x5e, 0x06,
- 0xf7, 0xc0, 0x3d, 0x8d, 0xdf, 0x23, 0xbf, 0xf0, 0xdc, 0x95, 0x73, 0xf0,
- 0x99, 0xcf, 0x1f, 0x48, 0x8d, 0x27, 0x6d, 0xea, 0xc3, 0xa4, 0xd4, 0xbe,
- 0x9e, 0x90, 0xb5, 0x65, 0x6d, 0x97, 0x66, 0xbd, 0x71, 0x29, 0x00, 0xfb,
- 0xae, 0x2d, 0x67, 0x51, 0xb2, 0x7e, 0xa8, 0x73, 0xb4, 0x5c, 0x16, 0x33,
- 0x79, 0xec, 0x63, 0xee, 0x0f, 0x6d, 0x77, 0x6c, 0xbb, 0x1d, 0x72, 0xc4,
- 0x3d, 0xf1, 0x30, 0x9e, 0xe7, 0xb1, 0xaf, 0x69, 0xc7, 0xd3, 0x90, 0xaf,
- 0xcf, 0xc6, 0x28, 0x1f, 0x05, 0x9f, 0xf8, 0x9a, 0x6d, 0x52, 0x89, 0x34,
- 0x9e, 0x4f, 0x4b, 0x5a, 0x9d, 0x0b, 0xcd, 0xfa, 0x61, 0x7f, 0x59, 0xa3,
- 0x17, 0x22, 0x8c, 0x81, 0xe1, 0xef, 0x64, 0x8c, 0xf2, 0x18, 0xf1, 0xc2,
- 0xe7, 0x23, 0xb0, 0x3d, 0x51, 0x35, 0xc6, 0xfc, 0x32, 0x9f, 0xa5, 0x5d,
- 0xb6, 0x2f, 0xf8, 0xbc, 0x17, 0xf9, 0x44, 0x83, 0xf1, 0x9a, 0x98, 0x3c,
- 0xda, 0xe8, 0x02, 0xbd, 0x6d, 0xbf, 0xc2, 0xf6, 0xec, 0xec, 0x73, 0x3b,
- 0xbb, 0x95, 0x70, 0x95, 0x6e, 0xa1, 0x1e, 0xa1, 0x0e, 0x69, 0x17, 0x67,
- 0x8c, 0xfb, 0x0c, 0x6b, 0xb2, 0x8c, 0x35, 0x5a, 0xc6, 0x1a, 0x2d, 0x63,
- 0x8d, 0x96, 0xb1, 0x7e, 0xcb, 0xd4, 0x2d, 0x83, 0xd8, 0xcf, 0x39, 0x73,
- 0x86, 0x40, 0xfd, 0xf2, 0x1c, 0xd6, 0x76, 0x5a, 0xfe, 0x76, 0x63, 0x52,
- 0xfe, 0xf3, 0xc6, 0x11, 0xe0, 0xee, 0x22, 0xd6, 0x35, 0x87, 0x75, 0xcd,
- 0x62, 0x5d, 0x8f, 0x62, 0x5d, 0xc7, 0x55, 0xcc, 0xb3, 0x5a, 0x49, 0x5d,
- 0x2a, 0x2b, 0x8c, 0xff, 0x16, 0xe4, 0x61, 0x4c, 0x9c, 0xd5, 0x7e, 0xe8,
- 0x8b, 0x72, 0x10, 0xf7, 0x82, 0x43, 0xc0, 0xd6, 0x18, 0xbb, 0x9c, 0x72,
- 0x94, 0xee, 0xf3, 0xdc, 0xcf, 0x63, 0xaf, 0xbc, 0x2f, 0x9b, 0xaa, 0x52,
- 0x75, 0x9d, 0xab, 0x0e, 0x4b, 0xe9, 0x22, 0xea, 0x9f, 0xed, 0x02, 0xad,
- 0xc4, 0x7c, 0xa9, 0xd3, 0x25, 0xd9, 0x84, 0xbe, 0xcb, 0x81, 0xc6, 0x0f,
- 0xc9, 0x7c, 0x3c, 0xf5, 0x9c, 0xc8, 0xb8, 0xdc, 0x03, 0x3f, 0x9d, 0xf1,
- 0xcc, 0x9c, 0x8a, 0xb1, 0xe1, 0xfa, 0x62, 0x16, 0xfe, 0x36, 0x6d, 0xec,
- 0x3e, 0xe3, 0x87, 0x6b, 0x1c, 0x5b, 0x13, 0x8e, 0xcb, 0xf1, 0xfe, 0x58,
- 0xe6, 0x80, 0x15, 0xe1, 0xeb, 0x03, 0x8b, 0x78, 0x09, 0x8c, 0x19, 0x9b,
- 0xbd, 0xe8, 0xc6, 0xe6, 0x2e, 0xb2, 0x9f, 0x98, 0x44, 0x96, 0xa8, 0xb3,
- 0xd8, 0x0f, 0x74, 0x3b, 0xfa, 0x4e, 0xab, 0x33, 0xb3, 0x11, 0xb4, 0xfb,
- 0x5d, 0xe0, 0x4c, 0xcd, 0xc7, 0xfc, 0x59, 0x6d, 0xf7, 0xf2, 0xf5, 0x66,
- 0xac, 0x07, 0xdd, 0x02, 0xbb, 0x98, 0xab, 0x6b, 0xdc, 0x56, 0x54, 0xb8,
- 0x4e, 0x63, 0xba, 0xa3, 0x72, 0xa8, 0x43, 0x3a, 0x3d, 0x35, 0x9f, 0xc8,
- 0xd9, 0x4d, 0xe2, 0x58, 0x8c, 0xc1, 0x36, 0xd1, 0x26, 0xba, 0x33, 0xb0,
- 0xa7, 0xb7, 0x77, 0x50, 0x66, 0x3e, 0x09, 0xdc, 0x38, 0xb0, 0xa4, 0xcf,
- 0x98, 0x06, 0x2e, 0xfa, 0x98, 0x8f, 0xf4, 0x31, 0xb2, 0x69, 0x63, 0x0e,
- 0x1f, 0x55, 0x76, 0x79, 0x0c, 0xb6, 0xd8, 0x85, 0xac, 0x53, 0xe7, 0xf4,
- 0x61, 0xff, 0xf0, 0x9e, 0xba, 0x87, 0x7a, 0x8c, 0x32, 0x13, 0x07, 0x6e,
- 0x82, 0xfe, 0xe9, 0xee, 0x97, 0xda, 0x06, 0xdf, 0xf5, 0x2b, 0x1d, 0xed,
- 0x60, 0x0d, 0x16, 0x2b, 0xc1, 0xa1, 0xbc, 0x5f, 0x86, 0x16, 0x25, 0xcf,
- 0xc9, 0x0f, 0xf2, 0x7d, 0x14, 0xb4, 0x91, 0xc7, 0xdd, 0x65, 0x7d, 0x6e,
- 0xb9, 0x57, 0x4a, 0x55, 0xea, 0x69, 0x94, 0xb5, 0xbd, 0xf0, 0x9d, 0x5c,
- 0x85, 0x65, 0x73, 0xd3, 0x9c, 0x7b, 0xac, 0xec, 0x42, 0x6e, 0xdd, 0x83,
- 0x93, 0x2a, 0xa6, 0x72, 0x79, 0x29, 0xe5, 0xd7, 0x6c, 0x8c, 0x09, 0x9d,
- 0x69, 0x9f, 0x1f, 0x93, 0xb9, 0x95, 0x6e, 0x19, 0x5c, 0xe5, 0xf9, 0xf2,
- 0x50, 0x4c, 0xba, 0x83, 0xe0, 0x9c, 0x9f, 0x57, 0xb1, 0xc7, 0x81, 0x55,
- 0x60, 0x82, 0xa3, 0x9a, 0x77, 0x9c, 0x2f, 0x74, 0xc4, 0xbf, 0x82, 0x8f,
- 0xef, 0x8e, 0x8f, 0x8b, 0xbb, 0xe0, 0xe3, 0x57, 0x2f, 0x42, 0xfe, 0x96,
- 0x21, 0x9b, 0xcb, 0x90, 0xcd, 0x65, 0xc8, 0xe6, 0x32, 0x64, 0x73, 0x19,
- 0xb2, 0x89, 0xfd, 0xf3, 0xfc, 0xf2, 0xb8, 0xc1, 0x1f, 0x9f, 0x82, 0x2c,
- 0x7f, 0xdb, 0xe0, 0x8f, 0x51, 0xc8, 0x70, 0x12, 0xb2, 0xeb, 0x43, 0x6e,
- 0x87, 0x21, 0xcb, 0x1e, 0x64, 0xb9, 0x1f, 0x72, 0x9c, 0x50, 0xfe, 0xe3,
- 0x04, 0xb0, 0xe8, 0x83, 0xf0, 0x41, 0xce, 0x57, 0xfb, 0x65, 0x51, 0xd1,
- 0x12, 0xc8, 0x96, 0xbf, 0x49, 0x1e, 0x62, 0x5f, 0xd0, 0x3f, 0x77, 0xe5,
- 0xfc, 0x5a, 0x48, 0xdb, 0xab, 0xf2, 0xcd, 0xca, 0x6b, 0xf2, 0x42, 0x85,
- 0x34, 0xe6, 0x64, 0x11, 0xef, 0xd6, 0x9e, 0xa2, 0x1f, 0xa9, 0xe8, 0x83,
- 0xcc, 0x9d, 0x94, 0xff, 0x03, 0x5e, 0xae, 0x6f, 0x7c, 0x58, 0x3e, 0xe7,
- 0x52, 0x86, 0xe3, 0xd0, 0x35, 0xb8, 0x3f, 0x40, 0xbd, 0x04, 0x3f, 0xb4,
- 0x92, 0x2a, 0x97, 0xa0, 0x27, 0xaa, 0xf6, 0x08, 0x30, 0x58, 0x39, 0xe8,
- 0xa1, 0x0e, 0xab, 0x7a, 0xee, 0x80, 0x4d, 0xde, 0xec, 0x87, 0xbc, 0xa4,
- 0xbe, 0x0a, 0xe1, 0xc5, 0x33, 0xda, 0x73, 0x94, 0x35, 0xe8, 0xcf, 0xa7,
- 0xc8, 0x47, 0xfa, 0xb5, 0xb8, 0x56, 0xba, 0xf7, 0x27, 0x2a, 0x7e, 0x5c,
- 0x9a, 0x86, 0x2f, 0xbf, 0x46, 0x3e, 0x41, 0x56, 0x9e, 0x22, 0x1f, 0x49,
- 0x9f, 0xe6, 0xe3, 0x23, 0x12, 0xf2, 0x90, 0xef, 0x5a, 0x79, 0x08, 0x27,
- 0xaa, 0x33, 0x8e, 0xb9, 0x7f, 0x2d, 0x66, 0x62, 0xc8, 0xc6, 0x26, 0xbf,
- 0x2a, 0xd3, 0x0d, 0xce, 0xc7, 0x92, 0xdb, 0xbc, 0xab, 0xf0, 0xa9, 0x38,
- 0xf6, 0xab, 0xc1, 0xa3, 0x71, 0xce, 0x81, 0xeb, 0xba, 0x47, 0xea, 0x7d,
- 0xbe, 0x89, 0xaf, 0xfc, 0x2a, 0x5b, 0xc4, 0x7a, 0xe0, 0x3b, 0xf4, 0xcb,
- 0x0b, 0xcb, 0xe0, 0x37, 0xfc, 0xae, 0x6f, 0xc0, 0xef, 0x62, 0x9c, 0x53,
- 0xaf, 0xcf, 0xb8, 0x89, 0xd9, 0xb6, 0xc6, 0x6a, 0x93, 0x58, 0x23, 0xfa,
- 0xed, 0xa9, 0xf2, 0x75, 0xe8, 0xc1, 0xe7, 0x7d, 0xc6, 0xf8, 0x02, 0xf9,
- 0xef, 0x7e, 0xb3, 0xa6, 0x53, 0xf1, 0x6d, 0x79, 0x04, 0xba, 0xf1, 0x51,
- 0xe8, 0xc6, 0x4f, 0xdc, 0x92, 0xe7, 0x43, 0x79, 0xbb, 0x7f, 0x6a, 0x76,
- 0x65, 0xb0, 0x1c, 0xb1, 0xfb, 0x31, 0xa7, 0xe6, 0xb6, 0x8c, 0xf1, 0x25,
- 0x4d, 0x2c, 0xb6, 0x19, 0xb3, 0x86, 0xf1, 0x56, 0xca, 0x74, 0x20, 0xd7,
- 0xfc, 0x72, 0x57, 0x44, 0x9d, 0x3f, 0x7b, 0xb4, 0x13, 0xbb, 0xfc, 0xbd,
- 0xd8, 0xa1, 0xed, 0xf3, 0x5b, 0x46, 0xc6, 0x76, 0x72, 0x99, 0x26, 0x32,
- 0xe1, 0x99, 0x73, 0x37, 0x6c, 0x1e, 0xf7, 0x6d, 0x2a, 0x99, 0xc3, 0xde,
- 0x9e, 0xdf, 0xa0, 0x5d, 0x20, 0x9e, 0x6c, 0x63, 0x4c, 0x6f, 0xa6, 0x3d,
- 0xcb, 0xd8, 0x41, 0x37, 0xfc, 0x97, 0xd7, 0xe5, 0xdc, 0xca, 0x3f, 0x75,
- 0xe8, 0xfd, 0xa4, 0x73, 0xcf, 0xec, 0x8b, 0xad, 0x71, 0x54, 0xbd, 0x46,
- 0x85, 0x4c, 0x37, 0x30, 0x0c, 0xfd, 0xa5, 0x6b, 0xca, 0x5f, 0x3a, 0xec,
- 0x3b, 0xb2, 0x19, 0x67, 0x9f, 0xaf, 0xcb, 0xb1, 0x95, 0xe1, 0x4e, 0xc6,
- 0x2b, 0x17, 0x97, 0x0f, 0xc8, 0x96, 0xd2, 0x65, 0x0f, 0xa3, 0x6e, 0x16,
- 0x7b, 0x36, 0x08, 0x26, 0xfc, 0xb4, 0x7b, 0x5e, 0x46, 0x12, 0xe7, 0xc1,
- 0xd3, 0x3f, 0x43, 0x1b, 0xf8, 0xd4, 0x41, 0x11, 0xcf, 0xae, 0xc2, 0x6f,
- 0xbf, 0x21, 0xbc, 0x1e, 0x71, 0x4f, 0x43, 0x18, 0x72, 0x6e, 0xda, 0x7d,
- 0x4b, 0x42, 0xdb, 0x45, 0x3b, 0xc5, 0x33, 0xeb, 0x3e, 0x29, 0xac, 0x6b,
- 0x5a, 0xe7, 0x41, 0xeb, 0xa9, 0x15, 0x8e, 0xc1, 0x79, 0x91, 0xde, 0x7f,
- 0xe2, 0x19, 0x07, 0xe6, 0xf2, 0x41, 0x60, 0x59, 0xe2, 0x28, 0x1d, 0x8b,
- 0x28, 0xa0, 0x8d, 0xc2, 0x5a, 0x3e, 0xcf, 0x2b, 0xc9, 0xc7, 0x2f, 0xc2,
- 0x6f, 0x88, 0x43, 0x8e, 0xf1, 0x7c, 0xbd, 0x39, 0xe6, 0xcb, 0xfa, 0xfa,
- 0x1c, 0xed, 0x92, 0xf2, 0x11, 0xf2, 0xc0, 0x85, 0x93, 0xa8, 0xcb, 0x78,
- 0x67, 0x10, 0x1c, 0xf7, 0xe1, 0xc7, 0x3f, 0x45, 0xd9, 0xbb, 0x53, 0x4a,
- 0xca, 0xe7, 0x20, 0x86, 0x65, 0xfe, 0xc6, 0x96, 0x1b, 0xc3, 0xfe, 0x9c,
- 0x86, 0x6d, 0xcb, 0xc3, 0xb6, 0x45, 0xee, 0x3e, 0x02, 0x3c, 0xab, 0xce,
- 0xd9, 0x60, 0x3f, 0x39, 0xee, 0xc3, 0xd6, 0xdf, 0x67, 0x46, 0x81, 0x6f,
- 0x1f, 0x00, 0xbe, 0x65, 0x1e, 0x59, 0x1e, 0x18, 0x97, 0xf8, 0xd6, 0x95,
- 0xbf, 0xda, 0xc8, 0x43, 0xb7, 0x4d, 0x74, 0x52, 0x17, 0x1f, 0xd9, 0xb6,
- 0xd3, 0x45, 0x63, 0xc7, 0xf7, 0x49, 0x41, 0x9d, 0xbb, 0x15, 0x95, 0xbd,
- 0x9f, 0x5f, 0x27, 0xae, 0x87, 0xed, 0x5f, 0x87, 0xef, 0x57, 0xa1, 0x8f,
- 0x96, 0xc3, 0xfd, 0x03, 0xb8, 0x7f, 0x08, 0xe5, 0x11, 0x94, 0xda, 0xf7,
- 0xb9, 0xb4, 0x1c, 0xe9, 0xd4, 0x31, 0xde, 0x44, 0x93, 0xff, 0x43, 0x39,
- 0x8c, 0x4f, 0xcd, 0x56, 0xc3, 0x38, 0xfd, 0x21, 0x39, 0xee, 0xeb, 0xb3,
- 0xf5, 0x09, 0xf8, 0xeb, 0x9d, 0xc0, 0x60, 0x0f, 0x3d, 0x0d, 0x9b, 0x71,
- 0xdf, 0x21, 0xb1, 0xef, 0xb3, 0x64, 0x76, 0x14, 0x74, 0x8f, 0x0e, 0x42,
- 0x3f, 0xf7, 0xc3, 0xdf, 0x56, 0x7e, 0xb0, 0xc1, 0x9c, 0xd4, 0xfb, 0x71,
- 0xf9, 0xf3, 0x8d, 0x10, 0x7b, 0xb6, 0x01, 0xa7, 0x32, 0x56, 0x98, 0x54,
- 0xb8, 0xd9, 0xbe, 0x8d, 0xeb, 0xdf, 0x25, 0xf9, 0xdb, 0xc8, 0x53, 0x3e,
- 0x03, 0xa6, 0x51, 0xd7, 0x71, 0x49, 0x9f, 0xe1, 0xba, 0xb5, 0x9b, 0x18,
- 0x2f, 0x6d, 0x06, 0xcb, 0xbf, 0xec, 0xdc, 0xc6, 0x96, 0x8c, 0x01, 0x59,
- 0xe3, 0x9d, 0x3b, 0x79, 0x69, 0xa1, 0xdc, 0x87, 0xf9, 0x04, 0x94, 0xff,
- 0x4b, 0xa0, 0x9f, 0xf6, 0x9e, 0xb6, 0xc1, 0xb5, 0xa2, 0x07, 0x89, 0x05,
- 0x22, 0xd2, 0xe6, 0x71, 0x9f, 0xd2, 0x4e, 0x1d, 0xc1, 0x9c, 0x88, 0x0d,
- 0x3e, 0xdf, 0x2d, 0xdd, 0xc4, 0x07, 0x49, 0x3c, 0xbb, 0x8e, 0x7a, 0xbc,
- 0x67, 0x3d, 0xf8, 0x52, 0xcb, 0x62, 0x45, 0x0e, 0xce, 0x41, 0xae, 0x3d,
- 0x5c, 0x1f, 0x47, 0x39, 0x8c, 0xf2, 0x71, 0x94, 0xd4, 0x4f, 0x57, 0x65,
- 0x56, 0xc7, 0x7f, 0x14, 0x0e, 0xa1, 0xed, 0x9c, 0xf6, 0xa9, 0x53, 0x4f,
- 0x8a, 0x3d, 0xf6, 0x41, 0x3c, 0xa3, 0x1f, 0x8f, 0x91, 0xee, 0xff, 0x82,
- 0x89, 0x3f, 0x6d, 0xc7, 0xac, 0x8c, 0x4e, 0x5e, 0x51, 0x31, 0xfc, 0xf5,
- 0xa7, 0xe8, 0x23, 0xff, 0x54, 0x1e, 0xbd, 0x29, 0xb6, 0xb7, 0x1d, 0xcb,
- 0x1a, 0x2f, 0x28, 0x5d, 0x4c, 0x7e, 0x40, 0x0f, 0xbb, 0x19, 0xf9, 0xfa,
- 0x46, 0x0f, 0xf4, 0x5b, 0x5c, 0xde, 0x58, 0x09, 0x80, 0xd5, 0xb9, 0x37,
- 0x47, 0x60, 0x33, 0x5d, 0x83, 0x03, 0xe2, 0xf2, 0x2f, 0x90, 0xf3, 0x7f,
- 0xae, 0x24, 0xe4, 0xcd, 0x4a, 0x10, 0x5c, 0xf3, 0xd3, 0xfe, 0x61, 0x91,
- 0xbb, 0xdb, 0x74, 0x0e, 0x00, 0x6a, 0xe8, 0x73, 0xfb, 0x79, 0x75, 0x76,
- 0x8f, 0x7a, 0xd0, 0x3b, 0x6f, 0x36, 0x7e, 0x01, 0xbe, 0xea, 0x3e, 0x5b,
- 0xdb, 0x6e, 0xe9, 0xb6, 0x3c, 0xfb, 0x4f, 0x6c, 0x4a, 0xda, 0xe4, 0x10,
- 0xa4, 0xd1, 0x36, 0x3d, 0xbc, 0xb6, 0xdd, 0x9e, 0x6d, 0x33, 0xca, 0x5e,
- 0x94, 0xd6, 0x7b, 0xa5, 0xfe, 0x17, 0xdc, 0x2b, 0xf0, 0x63, 0xd5, 0x99,
- 0x11, 0x4b, 0x9e, 0x55, 0xb0, 0x4e, 0xd2, 0xbc, 0x1f, 0x30, 0xef, 0x3d,
- 0x85, 0x5f, 0x9d, 0xed, 0x18, 0x20, 0x7c, 0xdb, 0xe5, 0xd4, 0x69, 0x65,
- 0x47, 0x18, 0xb7, 0x5d, 0xa6, 0x7f, 0x4f, 0x5d, 0x3e, 0x69, 0xec, 0x09,
- 0x7c, 0x8f, 0xda, 0x71, 0x99, 0x51, 0xd7, 0x9f, 0x90, 0x47, 0x5c, 0xf2,
- 0xee, 0xa4, 0xf8, 0x63, 0x1a, 0x4b, 0x89, 0x89, 0x09, 0x76, 0x78, 0x27,
- 0xe1, 0x9b, 0x29, 0x7b, 0xec, 0x7e, 0x4c, 0xc8, 0xe3, 0x36, 0xda, 0x8f,
- 0x9c, 0x6d, 0x01, 0x83, 0x3d, 0x99, 0x91, 0xe7, 0x36, 0x50, 0x17, 0xeb,
- 0xf5, 0x31, 0xc1, 0xfd, 0xb3, 0xb8, 0x67, 0x1c, 0xed, 0xe9, 0xb8, 0x44,
- 0x9e, 0xee, 0x97, 0xf6, 0x33, 0xc4, 0x29, 0xe4, 0x69, 0x42, 0xda, 0xce,
- 0x10, 0x2f, 0x33, 0xb6, 0x9c, 0x1a, 0xbf, 0x21, 0x8c, 0xe5, 0xa4, 0xfc,
- 0x2b, 0xf8, 0x6d, 0x61, 0xde, 0xed, 0xf0, 0xc3, 0xdb, 0x2e, 0xe8, 0x76,
- 0xf6, 0xb9, 0x3e, 0x00, 0xc3, 0x98, 0xd8, 0xf0, 0x59, 0xec, 0x0b, 0x2c,
- 0xbb, 0x50, 0xf2, 0x1d, 0x48, 0x3a, 0x37, 0x60, 0xde, 0x41, 0x37, 0x5e,
- 0xe0, 0xf8, 0xb0, 0x8f, 0xbe, 0xce, 0x17, 0x1d, 0x18, 0xf2, 0xe5, 0xd2,
- 0x1a, 0x65, 0x93, 0x71, 0x74, 0x62, 0x97, 0x57, 0xc5, 0x5e, 0xca, 0x48,
- 0xe4, 0x4c, 0x06, 0x72, 0xe8, 0xc3, 0xee, 0x12, 0xf3, 0xd1, 0xd6, 0xe1,
- 0x39, 0xf0, 0x56, 0xfd, 0x29, 0xce, 0xe9, 0xaa, 0xd8, 0xf5, 0x5f, 0x65,
- 0xc3, 0xc2, 0x7d, 0xc1, 0x31, 0x4e, 0xc2, 0xfe, 0x46, 0xe5, 0x73, 0x71,
- 0xca, 0x8a, 0x96, 0xbd, 0xb4, 0x3d, 0xa4, 0x64, 0xb5, 0x48, 0xbb, 0xfc,
- 0xd4, 0xed, 0x7b, 0xe0, 0xa7, 0x9d, 0x2e, 0x6f, 0xcb, 0x18, 0xf3, 0x42,
- 0x03, 0xa9, 0x02, 0xef, 0xcc, 0x7b, 0x96, 0x2c, 0x78, 0x27, 0x15, 0x1e,
- 0x7c, 0x14, 0xed, 0x4f, 0x98, 0xf6, 0x0b, 0x32, 0x64, 0x64, 0x5d, 0xc5,
- 0x11, 0xa0, 0xc7, 0xb8, 0x66, 0xbc, 0xff, 0x2d, 0xf1, 0x7b, 0xb9, 0x9e,
- 0x27, 0x65, 0x60, 0x4c, 0xe3, 0x90, 0x92, 0x4d, 0x1c, 0xf2, 0xae, 0x71,
- 0x5a, 0x95, 0xcb, 0x57, 0xa8, 0xd0, 0xce, 0xec, 0x85, 0xfc, 0xc2, 0x27,
- 0xda, 0x08, 0x63, 0xb5, 0x6a, 0x5f, 0x25, 0x06, 0x6c, 0x4b, 0xbc, 0xa1,
- 0xa1, 0xe1, 0x12, 0xf0, 0xc9, 0x3c, 0x7c, 0x5e, 0xd2, 0xb1, 0x00, 0x3b,
- 0xb7, 0xe6, 0xff, 0x4b, 0x70, 0x22, 0x9e, 0x3a, 0x3d, 0xf3, 0xae, 0xf1,
- 0xfb, 0x30, 0x6e, 0xdf, 0x7c, 0x9e, 0xb2, 0x69, 0xfd, 0x61, 0xe3, 0x88,
- 0xd2, 0x91, 0x37, 0xe3, 0xae, 0x30, 0x7e, 0x3f, 0x7d, 0x53, 0x1c, 0xb5,
- 0xd4, 0x08, 0x73, 0xf0, 0x42, 0x3d, 0x7f, 0x1a, 0xba, 0x3a, 0x22, 0x37,
- 0x80, 0x41, 0x27, 0xc0, 0xbb, 0x73, 0x6b, 0x65, 0xeb, 0x4a, 0x45, 0xd4,
- 0x7d, 0xc1, 0x67, 0x4e, 0xde, 0x47, 0xc0, 0x3b, 0xd8, 0x98, 0x0d, 0xc7,
- 0x9c, 0x29, 0x39, 0x78, 0x66, 0x2b, 0x9f, 0xb9, 0xa4, 0x74, 0xf3, 0xe1,
- 0x2e, 0x9e, 0xb9, 0x5c, 0x5a, 0xfe, 0x28, 0xee, 0x79, 0xf6, 0x71, 0xa4,
- 0xe5, 0xf9, 0x66, 0x4f, 0x54, 0x63, 0x37, 0xf0, 0x5d, 0xf3, 0xcd, 0x01,
- 0xbf, 0x8b, 0x8c, 0xe7, 0x35, 0x88, 0x83, 0x3b, 0x0d, 0x0e, 0x26, 0xce,
- 0xc2, 0x7a, 0x6d, 0x30, 0x0e, 0x43, 0xac, 0x15, 0x57, 0x7e, 0xa1, 0xc2,
- 0x5e, 0xfe, 0x31, 0x93, 0x7f, 0x71, 0xab, 0x5c, 0xcd, 0x56, 0x42, 0x3c,
- 0xd7, 0x2c, 0x57, 0xee, 0x6f, 0x20, 0x57, 0x13, 0x5d, 0x3a, 0xdf, 0x81,
- 0x36, 0xcd, 0x92, 0x37, 0xaa, 0x7b, 0x64, 0xab, 0xfa, 0x20, 0x70, 0xb4,
- 0xca, 0xfb, 0x90, 0x2d, 0xac, 0xc5, 0x83, 0x95, 0x49, 0x99, 0xa8, 0xc6,
- 0xe4, 0x5a, 0xd5, 0x7e, 0xa0, 0x5d, 0x18, 0x07, 0x27, 0x36, 0xf9, 0x1b,
- 0xa5, 0xdf, 0x7e, 0xe0, 0xef, 0xb4, 0xe7, 0xb9, 0xca, 0x0d, 0xb4, 0x9f,
- 0xad, 0xde, 0x2b, 0x25, 0xd5, 0xbe, 0x7e, 0xcb, 0x18, 0x51, 0x33, 0x46,
- 0xbd, 0x7a, 0x97, 0x89, 0xdf, 0x95, 0xe5, 0x12, 0xb0, 0xaf, 0x7d, 0x96,
- 0xf3, 0xbd, 0xc3, 0xe4, 0x77, 0xc5, 0x9a, 0xfc, 0x91, 0xa8, 0xf1, 0x47,
- 0x7e, 0x06, 0x3d, 0xfe, 0x94, 0x44, 0xbd, 0xb0, 0x2f, 0xe6, 0x6a, 0x27,
- 0x4c, 0x6e, 0xc7, 0x5e, 0xf4, 0x75, 0x10, 0xef, 0xee, 0xc3, 0xef, 0x49,
- 0xd4, 0xa3, 0xbd, 0xe2, 0xd9, 0x28, 0x31, 0x02, 0xcf, 0xeb, 0x7a, 0x51,
- 0xaf, 0x03, 0x58, 0x72, 0xbf, 0x79, 0x16, 0xf6, 0x11, 0xd6, 0x0d, 0xef,
- 0x9b, 0xcf, 0x53, 0x59, 0x2f, 0xd9, 0x74, 0x9e, 0x0a, 0x45, 0xa5, 0xda,
- 0x86, 0xb6, 0x36, 0xb4, 0x51, 0xc9, 0x26, 0x1b, 0xf5, 0x56, 0x53, 0x9e,
- 0xa7, 0xc6, 0x61, 0x57, 0x33, 0x9c, 0x6b, 0x5f, 0x53, 0x0e, 0x4a, 0xaa,
- 0x4c, 0xfb, 0xc8, 0x78, 0xdf, 0x7a, 0x25, 0xb4, 0x1f, 0xb9, 0x1e, 0x9e,
- 0x5b, 0x2c, 0xfa, 0x2a, 0x16, 0x97, 0x8c, 0x64, 0x69, 0x7f, 0xfc, 0xd8,
- 0x16, 0x70, 0x65, 0x5d, 0x9d, 0xeb, 0x47, 0xf0, 0x83, 0x5d, 0x76, 0x2c,
- 0x71, 0x3d, 0x3e, 0x2b, 0x1b, 0xbd, 0x03, 0x5d, 0x6e, 0xab, 0x3a, 0xc9,
- 0xbc, 0xdf, 0x67, 0xee, 0x13, 0xb2, 0x56, 0xf9, 0x50, 0xbf, 0x9d, 0xfd,
- 0x5f, 0xb7, 0xe7, 0x33, 0x3d, 0x3c, 0x7f, 0xc2, 0x33, 0xe2, 0xf5, 0xd7,
- 0x54, 0x4e, 0xa3, 0xc6, 0x46, 0x0e, 0xcf, 0x2f, 0x81, 0x73, 0x7e, 0x04,
- 0x9e, 0x84, 0xb8, 0xfb, 0x75, 0x99, 0x50, 0x98, 0xaa, 0x0d, 0xb6, 0xd2,
- 0x60, 0xaa, 0xee, 0x14, 0x30, 0x15, 0xdb, 0xb7, 0xe2, 0x40, 0xbd, 0x97,
- 0x22, 0x59, 0x1d, 0x57, 0x6d, 0x89, 0x15, 0x5b, 0x8f, 0x64, 0xc4, 0x3a,
- 0x81, 0x1f, 0x65, 0xd4, 0x5e, 0x7a, 0x4d, 0xbc, 0xa5, 0x54, 0x95, 0xf9,
- 0xb1, 0x0b, 0x1b, 0x3c, 0xc7, 0x03, 0x16, 0x4b, 0x50, 0x96, 0xf9, 0x6e,
- 0x1a, 0x63, 0xbc, 0x06, 0xff, 0x73, 0x0f, 0xf8, 0x6d, 0x1b, 0x1e, 0xf9,
- 0x26, 0x46, 0x11, 0x63, 0x2c, 0x18, 0x7b, 0x71, 0x5e, 0x61, 0x89, 0x52,
- 0x7c, 0x11, 0xe5, 0x0f, 0x0d, 0x76, 0x78, 0xbd, 0x2b, 0x3c, 0xb7, 0x2f,
- 0xc5, 0xbf, 0x84, 0xe7, 0xaf, 0xc3, 0x1f, 0x8c, 0x4a, 0x9b, 0x5a, 0xb3,
- 0x10, 0x3b, 0xff, 0x3d, 0xea, 0x90, 0xfe, 0x3b, 0x4d, 0x7e, 0x0d, 0xf3,
- 0x06, 0xd8, 0x1f, 0xec, 0x96, 0xca, 0xe1, 0xca, 0xa1, 0x64, 0x3b, 0xb6,
- 0x79, 0x05, 0x75, 0x73, 0x98, 0x37, 0x9f, 0x4b, 0x5f, 0x44, 0x9a, 0x9f,
- 0x7f, 0x14, 0xcf, 0x29, 0x87, 0xef, 0x37, 0x72, 0x18, 0xbe, 0xcb, 0x1b,
- 0x3e, 0xdd, 0x8e, 0x31, 0xc8, 0xab, 0x66, 0xba, 0x38, 0x9f, 0x70, 0xcd,
- 0xdb, 0x4c, 0xae, 0x01, 0x9f, 0xbd, 0xdf, 0x3c, 0x73, 0xcc, 0x1c, 0x3f,
- 0xde, 0x65, 0xb0, 0x04, 0x76, 0x7b, 0xb8, 0x1f, 0x49, 0x67, 0xac, 0x09,
- 0xb3, 0xfe, 0x61, 0xef, 0x4e, 0x1e, 0x26, 0x65, 0xce, 0x53, 0xb1, 0x23,
- 0xe6, 0x8f, 0xe5, 0x6c, 0x9d, 0xb3, 0xf1, 0x8d, 0x9b, 0xe2, 0xdd, 0x4a,
- 0xd7, 0xf2, 0x0c, 0xa4, 0x6a, 0x67, 0xdb, 0x7f, 0xed, 0xbc, 0xbb, 0x48,
- 0x36, 0x6c, 0x07, 0x9c, 0xa6, 0xda, 0x24, 0x65, 0xae, 0xf1, 0x6e, 0x39,
- 0x7a, 0xca, 0xbf, 0x30, 0x79, 0x10, 0xfb, 0x55, 0x1e, 0x04, 0xf5, 0xe2,
- 0x5a, 0x35, 0x02, 0x5e, 0xf7, 0x31, 0x37, 0x0a, 0x7e, 0x4c, 0x0c, 0x73,
- 0x45, 0x5f, 0xf1, 0xf7, 0xab, 0x5c, 0xa9, 0x88, 0x17, 0xe6, 0xf5, 0x72,
- 0x1f, 0xde, 0xa1, 0xde, 0x7f, 0x7d, 0xa5, 0x9d, 0xf9, 0xaa, 0x28, 0xb9,
- 0x47, 0x7f, 0x09, 0xfd, 0x18, 0x95, 0x42, 0xd5, 0x03, 0xfe, 0x89, 0x52,
- 0x2e, 0xf1, 0x7c, 0x3f, 0xfc, 0x61, 0xc1, 0x3e, 0x69, 0x83, 0x6f, 0xa2,
- 0x7c, 0x1d, 0xcc, 0x68, 0x87, 0x0e, 0x62, 0x70, 0x9d, 0x1f, 0x1a, 0x40,
- 0x87, 0xcf, 0xcb, 0xda, 0xf8, 0xa2, 0xd4, 0xc7, 0x9b, 0x31, 0x2c, 0x30,
- 0xaa, 0x5b, 0x0e, 0xea, 0x9e, 0x8a, 0x65, 0x1a, 0xdd, 0x72, 0xc2, 0xe0,
- 0x4e, 0xae, 0x83, 0x2d, 0x85, 0xd1, 0x05, 0x25, 0x5f, 0x75, 0xb5, 0x1e,
- 0x8e, 0x75, 0x59, 0xe5, 0xf9, 0x72, 0x0c, 0xe6, 0xfa, 0x46, 0x0c, 0x0e,
- 0x3b, 0x65, 0xd6, 0xd5, 0xd9, 0x1b, 0xe6, 0xcc, 0x47, 0xb3, 0x87, 0x99,
- 0xdb, 0x01, 0x6c, 0x3d, 0x3d, 0x35, 0x5b, 0xa1, 0x2d, 0x0c, 0x82, 0xba,
- 0xbf, 0x89, 0x1e, 0x7f, 0xac, 0x30, 0xe4, 0x96, 0x68, 0xdd, 0xbe, 0xa0,
- 0x72, 0x66, 0x27, 0xa7, 0xf2, 0x2a, 0x5e, 0xd8, 0x7c, 0x76, 0xf3, 0x5e,
- 0xe7, 0x36, 0x31, 0xf8, 0xfe, 0x1d, 0x66, 0xfd, 0x63, 0x4e, 0xa9, 0xd2,
- 0xe5, 0xcc, 0xaa, 0xb3, 0xb5, 0xac, 0xf9, 0x16, 0x27, 0x37, 0x95, 0x6e,
- 0x7c, 0x76, 0x2f, 0xb1, 0x3e, 0xcf, 0x31, 0x0a, 0x15, 0x9e, 0xe3, 0xe8,
- 0xf7, 0x69, 0xf3, 0x7e, 0xa0, 0xa1, 0xde, 0xa9, 0x78, 0x23, 0x63, 0x8c,
- 0xed, 0x28, 0x6f, 0x54, 0xa8, 0x6b, 0xd0, 0x7f, 0x5c, 0xcf, 0x21, 0x92,
- 0x2d, 0xc2, 0x3f, 0x25, 0x7d, 0x47, 0xa6, 0xf2, 0x2b, 0xcc, 0xdb, 0x7a,
- 0x68, 0xea, 0x1a, 0xfc, 0xa5, 0x73, 0x9e, 0xce, 0x2b, 0x5f, 0x67, 0x1c,
- 0x8c, 0xed, 0x54, 0x9f, 0x45, 0x13, 0xab, 0x3d, 0x3c, 0x35, 0xb8, 0x1e,
- 0x91, 0x27, 0x4c, 0x1f, 0xbc, 0x4f, 0x6e, 0xfb, 0x52, 0x4a, 0xff, 0xc1,
- 0x3f, 0x18, 0x85, 0x7f, 0xd0, 0x09, 0x5d, 0x4f, 0x3f, 0x83, 0xf8, 0xbb,
- 0x13, 0x7b, 0x85, 0xe3, 0xdc, 0xa5, 0xc6, 0x89, 0x60, 0x9c, 0x59, 0xf8,
- 0x38, 0x8c, 0x47, 0xe6, 0x3d, 0x07, 0x58, 0x02, 0xb6, 0xde, 0x63, 0xbc,
- 0xdc, 0xc6, 0x9c, 0x87, 0xa1, 0x27, 0x98, 0xa3, 0x32, 0x11, 0xe6, 0x0d,
- 0xa1, 0x9d, 0x6f, 0xda, 0x1d, 0x44, 0x3b, 0xfa, 0x07, 0x6c, 0x2b, 0xb7,
- 0xd9, 0x32, 0xa8, 0xb0, 0x81, 0xf6, 0x6b, 0x48, 0x43, 0x0d, 0x73, 0xa5,
- 0x5d, 0xc5, 0x9e, 0x53, 0xf3, 0x3a, 0xa8, 0xda, 0x59, 0xd9, 0x31, 0xd0,
- 0x4e, 0xfc, 0x87, 0xbe, 0x97, 0x75, 0xbc, 0xb3, 0xa0, 0xe4, 0x08, 0x72,
- 0x32, 0x1e, 0xe6, 0xbd, 0xe8, 0x76, 0x61, 0xfd, 0x81, 0xf5, 0x86, 0x19,
- 0xff, 0xe7, 0x41, 0xee, 0x68, 0xa7, 0xf2, 0xad, 0x5f, 0xbe, 0x29, 0x07,
- 0x8d, 0x6d, 0xc2, 0x3a, 0x91, 0x30, 0x2f, 0xb9, 0x89, 0xe6, 0xac, 0x59,
- 0x73, 0xb6, 0x63, 0x6c, 0x58, 0xe5, 0xe2, 0xf3, 0x99, 0x33, 0x97, 0x61,
- 0x1f, 0xcd, 0x67, 0x4d, 0xa3, 0xc0, 0x19, 0xda, 0x86, 0x94, 0x37, 0x3c,
- 0xd8, 0xeb, 0x36, 0xac, 0x1d, 0x6d, 0xc2, 0xa0, 0xf1, 0x2d, 0xde, 0x2b,
- 0xce, 0xca, 0x73, 0xcc, 0x51, 0xf8, 0xf5, 0x61, 0x7b, 0xae, 0x63, 0x6e,
- 0xea, 0x5a, 0xc5, 0x93, 0x53, 0xcb, 0x3a, 0x3f, 0x4c, 0xf3, 0x81, 0x3a,
- 0x9b, 0x6b, 0x9b, 0x94, 0x59, 0x8f, 0xb1, 0x9c, 0xa4, 0xbc, 0xe2, 0x35,
- 0xe7, 0x39, 0xa1, 0xfe, 0xc6, 0xa8, 0xc9, 0xc7, 0x3e, 0x88, 0xf9, 0x13,
- 0x37, 0x6a, 0x59, 0x3a, 0x00, 0x3b, 0xf4, 0x77, 0x0e, 0x70, 0x21, 0xf6,
- 0xd3, 0x75, 0xa7, 0x79, 0x7e, 0xdb, 0xf9, 0xdf, 0x4a, 0x2e, 0x1d, 0xc8,
- 0xc8, 0xe2, 0x36, 0xdf, 0xe1, 0xb7, 0xdf, 0x35, 0x04, 0x7d, 0x6f, 0x49,
- 0x71, 0xd4, 0x4b, 0x2c, 0xf0, 0x5c, 0xc3, 0x1d, 0x01, 0xca, 0xa7, 0x1f,
- 0x9d, 0x04, 0xbd, 0xbc, 0x1e, 0x04, 0x3e, 0x62, 0x4e, 0x22, 0xee, 0x99,
- 0x13, 0x18, 0xf7, 0x40, 0xaf, 0xab, 0xce, 0x2b, 0xb4, 0xce, 0xfe, 0xfe,
- 0x5e, 0xe6, 0xc0, 0xf5, 0x78, 0xe1, 0xda, 0xab, 0xef, 0xda, 0xd0, 0x77,
- 0xc4, 0xbc, 0x9f, 0xd8, 0xe6, 0xbf, 0xf4, 0xb1, 0xdc, 0xce, 0x35, 0x33,
- 0xb1, 0x17, 0xd6, 0x1f, 0x57, 0xb4, 0xcc, 0x42, 0x57, 0xcf, 0xa9, 0xf9,
- 0xdc, 0x0f, 0x59, 0x88, 0xc8, 0xfc, 0xb6, 0xfc, 0xde, 0x0f, 0xf9, 0xdd,
- 0xc3, 0x14, 0xcf, 0x5d, 0x64, 0x2d, 0x94, 0x31, 0xca, 0x17, 0x65, 0xeb,
- 0xe3, 0xdd, 0xdc, 0x73, 0xe5, 0xed, 0x75, 0x77, 0x94, 0xcd, 0x4d, 0xda,
- 0xe1, 0xba, 0xf3, 0x7a, 0xb7, 0xdc, 0xaa, 0x70, 0x7f, 0x64, 0x7e, 0x83,
- 0xb5, 0xf5, 0xcd, 0xda, 0x66, 0x9a, 0xbe, 0x83, 0x08, 0xfb, 0x63, 0x0c,
- 0x94, 0x36, 0x88, 0xe7, 0x50, 0xed, 0x52, 0x56, 0x32, 0x68, 0x29, 0x6c,
- 0x9d, 0x73, 0xf3, 0x49, 0xc6, 0xbc, 0x8f, 0xc9, 0xbf, 0x03, 0xcd, 0xb9,
- 0xe1, 0xa8, 0xe8, 0xb6, 0x33, 0xe0, 0xf7, 0xa6, 0x0b, 0x7f, 0x90, 0x67,
- 0xd6, 0x15, 0x47, 0xce, 0xa9, 0x73, 0x57, 0xec, 0xd1, 0x4e, 0x47, 0x16,
- 0xbd, 0xed, 0x73, 0x78, 0xa9, 0xa1, 0xce, 0x1a, 0xde, 0x3d, 0xb1, 0x4d,
- 0x1b, 0xfd, 0x09, 0xf8, 0x52, 0xde, 0xcf, 0x83, 0x52, 0xfc, 0xa6, 0xba,
- 0x46, 0xaf, 0x33, 0x4e, 0xc3, 0xf3, 0x01, 0x57, 0x0a, 0xf0, 0x0b, 0x0b,
- 0xf0, 0x09, 0x0b, 0x4a, 0x2f, 0x30, 0x6e, 0xc3, 0x18, 0x5b, 0x19, 0x3e,
- 0x48, 0x39, 0x68, 0xf7, 0x4e, 0xaa, 0x18, 0xe2, 0xa5, 0x8d, 0x54, 0xb9,
- 0x2c, 0x5e, 0xf2, 0xc1, 0xed, 0x7c, 0xba, 0xee, 0x72, 0x2c, 0xdb, 0x1c,
- 0x87, 0x4b, 0xaa, 0x5c, 0xb4, 0x0e, 0x60, 0xe4, 0xe3, 0xd0, 0xd5, 0xcf,
- 0xfb, 0x8c, 0xbf, 0xdd, 0x49, 0x7e, 0x7f, 0x95, 0x93, 0xb4, 0x87, 0x46,
- 0xc5, 0xbb, 0xe0, 0x0d, 0x3f, 0x28, 0xf4, 0x3f, 0x52, 0xc9, 0x23, 0xe4,
- 0xdb, 0xf6, 0x37, 0x0d, 0xa1, 0x7d, 0x1d, 0x95, 0xc1, 0x0b, 0xaf, 0xab,
- 0x33, 0x8e, 0x4f, 0xf8, 0xad, 0xb2, 0xa1, 0xe2, 0x77, 0xa3, 0x3d, 0x32,
- 0x08, 0xdf, 0x57, 0x60, 0xa1, 0xf8, 0x8d, 0x83, 0x05, 0xdf, 0x43, 0xdd,
- 0xcb, 0x74, 0x23, 0x69, 0xf2, 0x54, 0x69, 0x5f, 0x19, 0xdf, 0xd3, 0x79,
- 0x7a, 0xcc, 0x4d, 0x65, 0xfe, 0x64, 0x51, 0xe5, 0xeb, 0x31, 0xd6, 0xc7,
- 0x58, 0x1e, 0xe3, 0x7d, 0x8c, 0xdb, 0xe9, 0x5c, 0xbd, 0x89, 0xc6, 0x6e,
- 0xb1, 0xbd, 0x30, 0x5f, 0x52, 0xdb, 0xad, 0xad, 0xcc, 0x3e, 0xd8, 0x3a,
- 0x57, 0xc5, 0x4e, 0x4a, 0x6e, 0x8f, 0x1c, 0x1b, 0x6e, 0x07, 0xcf, 0x7b,
- 0x55, 0x3e, 0x9d, 0xed, 0xdd, 0x0f, 0x1c, 0xcb, 0xf8, 0x1c, 0xb1, 0x69,
- 0xc8, 0xe7, 0x7b, 0xf0, 0xec, 0x1d, 0xf0, 0x9e, 0xcf, 0x80, 0x5b, 0x95,
- 0x1d, 0xfa, 0xbc, 0x6c, 0x55, 0x98, 0x03, 0x5f, 0xdb, 0x97, 0x57, 0xeb,
- 0x41, 0xdf, 0x3c, 0xd4, 0x4d, 0x61, 0xfe, 0x28, 0x7d, 0x2a, 0xd7, 0x9c,
- 0x93, 0xd3, 0x37, 0xef, 0x85, 0xbf, 0x4e, 0xfd, 0x63, 0xa9, 0xb1, 0xae,
- 0x47, 0x3e, 0x20, 0xe5, 0xda, 0x6e, 0x67, 0xfe, 0x41, 0xf0, 0x0d, 0x5f,
- 0xe5, 0xac, 0xc2, 0x9f, 0xd4, 0x6b, 0xac, 0xbf, 0x8f, 0x74, 0x76, 0xf2,
- 0xcb, 0xe3, 0xda, 0x67, 0xcc, 0xf5, 0x02, 0xb3, 0x78, 0xa7, 0xbb, 0x77,
- 0xb0, 0xf3, 0x2f, 0x0d, 0xae, 0x25, 0x6e, 0xee, 0x55, 0xd8, 0xc0, 0xae,
- 0x87, 0x72, 0xc2, 0x7c, 0x1f, 0x62, 0xea, 0x03, 0x92, 0xab, 0x41, 0x6f,
- 0xf6, 0xf1, 0xfe, 0x47, 0xa6, 0x2d, 0xaf, 0x03, 0x39, 0x3c, 0xd6, 0x7a,
- 0x96, 0x3f, 0xae, 0x71, 0x7d, 0x67, 0x78, 0x9e, 0x1f, 0xe6, 0xbc, 0xdf,
- 0x94, 0x5b, 0x0b, 0x79, 0x0a, 0x69, 0xd0, 0x63, 0x4d, 0x80, 0xde, 0x7a,
- 0x35, 0x21, 0xbd, 0x1e, 0xf3, 0x84, 0x22, 0x32, 0xd6, 0x9b, 0x82, 0x13,
- 0xaf, 0xe9, 0xa9, 0xd7, 0x60, 0xf3, 0xab, 0x21, 0x9d, 0x1a, 0xe3, 0xd7,
- 0x6b, 0x7c, 0x9f, 0xc4, 0x58, 0xed, 0x32, 0xd6, 0x47, 0x3e, 0xb7, 0xd2,
- 0x91, 0x34, 0xf9, 0xdc, 0xad, 0xcf, 0xef, 0x6b, 0xa2, 0xef, 0xd6, 0xef,
- 0x4a, 0xf3, 0x8c, 0x8b, 0xad, 0xd0, 0x3f, 0x21, 0x8d, 0xbd, 0xd0, 0x73,
- 0x98, 0xa3, 0x1f, 0xfa, 0x1a, 0x21, 0x5f, 0x42, 0x1f, 0x25, 0xaa, 0xe4,
- 0x62, 0x36, 0xc3, 0xb9, 0x44, 0x8d, 0xcf, 0x42, 0xba, 0x14, 0x6d, 0x11,
- 0x9e, 0x25, 0x46, 0xbd, 0xcf, 0xec, 0xd3, 0xeb, 0xff, 0xa4, 0x99, 0xaf,
- 0x6b, 0xea, 0xb0, 0xaf, 0xfd, 0x68, 0xff, 0xb5, 0x00, 0x63, 0x31, 0x08,
- 0x87, 0xfd, 0x1f, 0x62, 0xf7, 0xfd, 0xba, 0xaf, 0xce, 0x10, 0xbf, 0x87,
- 0xdf, 0xa1, 0x91, 0x4e, 0xee, 0xaf, 0x90, 0x87, 0xec, 0xa3, 0xd7, 0xc4,
- 0x5c, 0x49, 0x43, 0x47, 0x0b, 0x0d, 0x29, 0xff, 0x66, 0x1d, 0x77, 0x4f,
- 0xd3, 0xdc, 0x29, 0x6b, 0xdd, 0xb2, 0x50, 0xed, 0x94, 0xf9, 0xaa, 0xf2,
- 0x75, 0x86, 0x45, 0x88, 0xed, 0xb8, 0x2f, 0x55, 0x2e, 0xb3, 0xc9, 0x99,
- 0x0c, 0xf7, 0x67, 0x37, 0xea, 0xd1, 0x86, 0xa0, 0xac, 0x69, 0xfd, 0x54,
- 0x93, 0x5b, 0xbf, 0xd3, 0x98, 0x6b, 0xb4, 0xe6, 0xe3, 0x5d, 0x6f, 0xca,
- 0xc7, 0x6b, 0xce, 0x7f, 0x2a, 0xcb, 0x23, 0x07, 0x3b, 0x64, 0xe0, 0x6c,
- 0xa7, 0x91, 0xd1, 0xfb, 0xcd, 0x38, 0x18, 0x6f, 0x69, 0x5c, 0x06, 0x96,
- 0xbe, 0x28, 0xa5, 0x69, 0x95, 0xff, 0xde, 0xf4, 0xfd, 0xc3, 0xa0, 0xf9,
- 0xfe, 0x29, 0x67, 0x31, 0x17, 0xa6, 0xb0, 0x84, 0xf5, 0x3a, 0x98, 0x1a,
- 0x4e, 0xda, 0xfc, 0x46, 0xf7, 0x31, 0x19, 0x58, 0x1d, 0x97, 0xf4, 0x12,
- 0x31, 0x03, 0xb3, 0x01, 0x52, 0x2a, 0x2e, 0x9a, 0xbe, 0xa8, 0xfb, 0xf3,
- 0x96, 0xf8, 0x3e, 0x0d, 0xbc, 0xca, 0xf7, 0x85, 0x44, 0x44, 0x65, 0x0c,
- 0x7c, 0x10, 0xf2, 0xd4, 0x66, 0xf0, 0x80, 0x23, 0xf9, 0x25, 0xb6, 0x27,
- 0xf6, 0xf8, 0x47, 0xac, 0x59, 0x21, 0x69, 0x0b, 0xdb, 0xa8, 0xfe, 0x70,
- 0x1d, 0xc6, 0xd3, 0xc9, 0xeb, 0x51, 0x59, 0x6f, 0x78, 0xd8, 0x13, 0xfa,
- 0x9b, 0x89, 0x52, 0x2d, 0xcc, 0x27, 0x7d, 0xc4, 0xc4, 0x00, 0x34, 0x8d,
- 0xc5, 0x4a, 0xab, 0xec, 0x3d, 0x63, 0xbe, 0x9d, 0xe8, 0x50, 0x67, 0x68,
- 0x4d, 0xfa, 0xcf, 0xd4, 0xbf, 0xdd, 0x65, 0xde, 0x80, 0x08, 0xdf, 0x37,
- 0xf9, 0x24, 0xf1, 0xb8, 0xda, 0x07, 0x03, 0xf5, 0xb0, 0xde, 0xa8, 0xab,
- 0x7d, 0x60, 0xf2, 0x29, 0x6b, 0x68, 0x1e, 0x83, 0xcf, 0xc3, 0x67, 0x07,
- 0xd0, 0x96, 0xeb, 0x84, 0xb2, 0x7e, 0x40, 0xe5, 0x39, 0x46, 0xb2, 0x47,
- 0xcc, 0x59, 0x5a, 0x9f, 0x1a, 0xcb, 0xcd, 0xb2, 0xff, 0x50, 0x37, 0x74,
- 0x34, 0x8d, 0xdf, 0x4a, 0x2f, 0x7d, 0xf8, 0x9f, 0x19, 0x79, 0xe1, 0x7b,
- 0xde, 0xb7, 0xd6, 0xf9, 0xa3, 0x7d, 0xe1, 0x7b, 0x67, 0xfb, 0x1b, 0x0c,
- 0xf2, 0x92, 0x67, 0x80, 0x28, 0x2f, 0x32, 0x97, 0x9d, 0xd7, 0x28, 0xcd,
- 0xb7, 0x25, 0xce, 0x12, 0x7f, 0xad, 0xfd, 0x38, 0xe8, 0x3b, 0xdc, 0xb3,
- 0xbb, 0xe5, 0x06, 0x51, 0x17, 0x9f, 0xb6, 0xb6, 0x2a, 0x8c, 0x5d, 0x94,
- 0xe5, 0x58, 0xa6, 0x5b, 0x66, 0xab, 0x36, 0xbf, 0x4d, 0x65, 0x2c, 0x96,
- 0x67, 0x95, 0x32, 0xa7, 0x74, 0xdc, 0x90, 0xe8, 0xef, 0x76, 0x3b, 0xa4,
- 0xe8, 0x52, 0x9e, 0x87, 0x64, 0xbd, 0x36, 0xdd, 0x94, 0x03, 0xdc, 0x66,
- 0xe4, 0xec, 0xef, 0xa2, 0xd2, 0xc9, 0x38, 0x52, 0xb8, 0xa7, 0x87, 0xa4,
- 0x58, 0x6b, 0x3e, 0x67, 0x60, 0x9e, 0x11, 0xe5, 0xb6, 0xbf, 0x69, 0xef,
- 0x31, 0x57, 0x0f, 0xb8, 0x2a, 0x4e, 0x9f, 0x95, 0xf5, 0xf6, 0x1a, 0x7b,
- 0xfb, 0x15, 0xac, 0xc7, 0xfb, 0x2d, 0xf1, 0x48, 0x1b, 0x6c, 0x84, 0xc9,
- 0x35, 0x3e, 0x1c, 0x2f, 0xc3, 0x3f, 0x1b, 0x32, 0xe3, 0xde, 0x81, 0x7b,
- 0xd6, 0xdd, 0x67, 0xde, 0xef, 0x37, 0xf7, 0x9d, 0xe6, 0x3e, 0x82, 0x7b,
- 0xe6, 0x8d, 0xb3, 0x4f, 0x96, 0xfc, 0x9e, 0x88, 0xdf, 0xeb, 0x64, 0x25,
- 0x7a, 0x11, 0xe8, 0xa9, 0xd1, 0x29, 0x9f, 0xae, 0x29, 0xfe, 0x5a, 0xde,
- 0x12, 0x01, 0xc1, 0x7e, 0x73, 0x7d, 0xeb, 0x1e, 0xfc, 0xdc, 0x4d, 0xdf,
- 0x4a, 0x55, 0x8c, 0xac, 0x34, 0xd3, 0x9b, 0x03, 0xad, 0xef, 0x96, 0x83,
- 0x45, 0x1b, 0xa5, 0xfd, 0xc6, 0x62, 0x45, 0xe7, 0x1a, 0x1d, 0x83, 0xdf,
- 0x78, 0xb8, 0xfa, 0xa8, 0xab, 0xf3, 0x62, 0xc2, 0x5c, 0xca, 0x4e, 0xcc,
- 0x6b, 0xc8, 0x9c, 0x5b, 0xb3, 0x2d, 0x73, 0x3a, 0xc3, 0xf3, 0x99, 0x66,
- 0xac, 0x4a, 0x5b, 0x44, 0x3b, 0xc3, 0xef, 0x9a, 0x7c, 0xd4, 0x5d, 0xa4,
- 0xae, 0x69, 0xca, 0xcd, 0xff, 0x52, 0x4b, 0x6e, 0x3e, 0xbf, 0xfb, 0x16,
- 0xf9, 0x6f, 0x0d, 0xc6, 0x95, 0x3a, 0x24, 0x72, 0x36, 0xcc, 0xc1, 0xe2,
- 0x1a, 0x13, 0x87, 0xf1, 0x7b, 0xef, 0xa9, 0x5d, 0x62, 0x4e, 0xa1, 0x9c,
- 0x7f, 0xc7, 0x65, 0x7e, 0xab, 0x9b, 0x0d, 0xe3, 0x54, 0xcc, 0xeb, 0x21,
- 0xe6, 0x3a, 0x60, 0x62, 0x0a, 0x7c, 0x57, 0x96, 0x9e, 0x83, 0x53, 0xdc,
- 0x1b, 0xbf, 0x1d, 0xd9, 0xce, 0xfd, 0x57, 0xe3, 0xc4, 0x35, 0x86, 0xe4,
- 0x77, 0xe3, 0x3e, 0xf6, 0xd5, 0x9e, 0xcd, 0xf0, 0x9b, 0x8c, 0xcb, 0x8d,
- 0x8c, 0xfa, 0xf6, 0x83, 0x67, 0x1e, 0x5b, 0x0d, 0xee, 0x3b, 0x7e, 0x23,
- 0x9e, 0x55, 0x39, 0x01, 0x5b, 0xe6, 0x9b, 0xe7, 0xab, 0x0d, 0xfd, 0x1d,
- 0xcb, 0xe2, 0xb2, 0xca, 0xcb, 0x07, 0x56, 0x4b, 0xe2, 0x3d, 0x73, 0xe8,
- 0xfa, 0x55, 0x2e, 0xc1, 0x7c, 0xe3, 0x53, 0x28, 0x3f, 0x2f, 0x6b, 0x15,
- 0x1d, 0x7f, 0x9d, 0x6f, 0x30, 0xa7, 0xc0, 0x55, 0x67, 0x44, 0x03, 0x4b,
- 0x45, 0x8c, 0x17, 0x7e, 0xb3, 0x1d, 0xc7, 0x33, 0xd2, 0x57, 0x36, 0x7b,
- 0x34, 0xcc, 0x05, 0xe9, 0xea, 0xa1, 0x4d, 0x28, 0x37, 0xba, 0x54, 0x1e,
- 0x82, 0xc6, 0x23, 0xc4, 0x7a, 0x31, 0xd4, 0xe5, 0x5c, 0x3b, 0x69, 0xaf,
- 0x02, 0xea, 0xa4, 0x34, 0xc6, 0xa9, 0xab, 0xdc, 0x44, 0xf2, 0xd9, 0x73,
- 0x4b, 0xf4, 0xd7, 0x94, 0x8e, 0x4f, 0x0d, 0xcf, 0x48, 0xc1, 0x8d, 0xc2,
- 0x17, 0x9b, 0x57, 0x7e, 0xce, 0xfd, 0xc0, 0xd0, 0x5d, 0x9b, 0x91, 0x2c,
- 0xe7, 0xc6, 0xb1, 0xe9, 0x87, 0xe8, 0xf9, 0xe8, 0x33, 0x02, 0xb1, 0xe6,
- 0xd5, 0xf7, 0x8f, 0x7c, 0xce, 0x78, 0x6f, 0xf8, 0xcd, 0x90, 0xfe, 0x26,
- 0x64, 0xa6, 0x71, 0x44, 0x4e, 0x55, 0xf6, 0xf2, 0x5b, 0x09, 0x7f, 0x0b,
- 0x7c, 0x3b, 0xd6, 0xe8, 0x52, 0xdf, 0xa5, 0xcc, 0x34, 0x98, 0x3f, 0x17,
- 0xda, 0x1e, 0xae, 0x55, 0xdc, 0x7c, 0x37, 0x91, 0x30, 0xdf, 0x4d, 0xf0,
- 0xdb, 0x8f, 0x1f, 0xed, 0x0d, 0xf7, 0xfb, 0xad, 0x38, 0x9c, 0x32, 0xf8,
- 0xa7, 0xf0, 0x0d, 0xc3, 0x3c, 0x4c, 0xe6, 0x8b, 0x06, 0xc1, 0x31, 0x9f,
- 0xf1, 0xdb, 0xe9, 0xc3, 0x6b, 0x98, 0xe3, 0x95, 0x1a, 0x78, 0x78, 0x94,
- 0xcf, 0x98, 0x37, 0xd6, 0x2e, 0xf9, 0xd1, 0x76, 0xea, 0xf2, 0xce, 0x35,
- 0x6f, 0xaf, 0x5c, 0xae, 0xc6, 0x55, 0x0e, 0x5c, 0x09, 0x38, 0xbf, 0x2e,
- 0x1f, 0xeb, 0xe1, 0xd9, 0xdd, 0x84, 0x6a, 0x1f, 0xee, 0x77, 0x1d, 0x37,
- 0x98, 0x58, 0xd7, 0xfa, 0xe4, 0x78, 0x06, 0xb8, 0xe5, 0x82, 0x58, 0x7f,
- 0x90, 0xe9, 0x87, 0xef, 0xcd, 0xb1, 0xd2, 0x68, 0x07, 0xd9, 0x49, 0x70,
- 0xaf, 0xbf, 0x13, 0xd4, 0x41, 0xef, 0x8d, 0x06, 0xf1, 0x3a, 0x30, 0xd4,
- 0x34, 0xdb, 0x64, 0xc5, 0x3e, 0xc3, 0x3a, 0xbd, 0x90, 0xbf, 0x28, 0xe6,
- 0xe3, 0xc0, 0x17, 0xd8, 0x27, 0x75, 0x97, 0xef, 0x1c, 0x7d, 0xa6, 0x12,
- 0x0f, 0xfd, 0x94, 0xef, 0x81, 0x7f, 0x49, 0xa5, 0x93, 0xc2, 0xf3, 0x4e,
- 0xe6, 0xb3, 0xce, 0x56, 0x27, 0xb1, 0x87, 0x1c, 0x83, 0xcd, 0x1c, 0xf4,
- 0xf1, 0xe1, 0x1e, 0x8d, 0x15, 0x78, 0x1e, 0xaa, 0xb1, 0x88, 0xb6, 0x31,
- 0x3c, 0xdf, 0x71, 0xe0, 0x0b, 0x84, 0xfb, 0xf2, 0x99, 0x7d, 0x37, 0x7f,
- 0x0b, 0x43, 0x1c, 0x93, 0x4e, 0x9c, 0xe7, 0x79, 0xdc, 0xc6, 0xc3, 0x32,
- 0x03, 0x9a, 0x4f, 0x9b, 0x79, 0x3e, 0x98, 0xf1, 0xe4, 0x7a, 0x8d, 0xe7,
- 0x95, 0x07, 0x50, 0x32, 0xd7, 0x91, 0x34, 0x8f, 0x98, 0x7c, 0xce, 0x2c,
- 0xe6, 0xfa, 0x98, 0xbc, 0x01, 0x7c, 0xfd, 0x66, 0x25, 0xed, 0x4f, 0xa8,
- 0x3c, 0xa4, 0x54, 0xe2, 0xb2, 0x8c, 0x24, 0xe9, 0x03, 0x96, 0xdd, 0x54,
- 0xe2, 0x3a, 0xe4, 0xe1, 0x46, 0xe5, 0x99, 0x1e, 0xfe, 0xaf, 0x8a, 0x3a,
- 0xec, 0xe1, 0x0d, 0x95, 0x83, 0x94, 0x62, 0xcc, 0x04, 0xf7, 0xfd, 0x26,
- 0x0f, 0x8a, 0xe3, 0xf0, 0x5d, 0xbf, 0xbc, 0x51, 0xd9, 0xb6, 0xbf, 0x1c,
- 0xc7, 0x7c, 0x03, 0xcf, 0xb1, 0x2e, 0xf4, 0x50, 0x0f, 0x71, 0x3c, 0xdd,
- 0x47, 0x58, 0x87, 0x7c, 0x0d, 0xe3, 0x9a, 0xea, 0x5b, 0xcb, 0xa4, 0x58,
- 0x96, 0xb4, 0x79, 0x9c, 0xfb, 0x54, 0x8f, 0xc6, 0x40, 0x6c, 0x97, 0x76,
- 0x0f, 0xab, 0xfe, 0x78, 0xb6, 0xc7, 0xf3, 0xaf, 0xb0, 0x1f, 0xe6, 0x43,
- 0x31, 0xe7, 0x8a, 0xba, 0xaf, 0x99, 0x06, 0x6d, 0xff, 0xdf, 0x50, 0xb1,
- 0xf4, 0x71, 0xd4, 0xa7, 0x8d, 0x86, 0xbc, 0xd4, 0x12, 0xdb, 0xdf, 0x7c,
- 0x68, 0x5e, 0xf2, 0xfa, 0x99, 0xed, 0x6f, 0x32, 0xec, 0xbb, 0x5d, 0xf3,
- 0x3e, 0xc4, 0xa5, 0xfd, 0xd8, 0xaf, 0x8f, 0x49, 0x7d, 0x25, 0x9d, 0xf8,
- 0xb4, 0x84, 0xfd, 0x06, 0x87, 0x78, 0xde, 0x51, 0xcc, 0x8c, 0xb8, 0x0b,
- 0x8a, 0x9e, 0x54, 0x82, 0x39, 0xc8, 0x97, 0x31, 0x5e, 0xbd, 0xd1, 0x1a,
- 0x7b, 0x48, 0xe5, 0x36, 0x25, 0xed, 0xeb, 0xb5, 0x19, 0x92, 0x4d, 0xac,
- 0xcd, 0x9f, 0x9b, 0xb5, 0xf9, 0x18, 0xfa, 0xf6, 0xce, 0x8c, 0x4a, 0xfa,
- 0x4c, 0x3a, 0x79, 0x5a, 0x78, 0x96, 0xb8, 0x8f, 0x31, 0x2c, 0xeb, 0xc1,
- 0x4c, 0x12, 0xf3, 0x4d, 0x61, 0xbe, 0x28, 0x1b, 0xbc, 0x1e, 0x81, 0x6f,
- 0xbe, 0x87, 0x7b, 0xfb, 0x10, 0x75, 0x26, 0x79, 0x51, 0x54, 0xef, 0x80,
- 0x4f, 0x9e, 0x26, 0x4d, 0x00, 0xca, 0x9d, 0x29, 0x15, 0x07, 0xbc, 0xde,
- 0xe0, 0xf9, 0xa2, 0xa6, 0xaf, 0x00, 0xfa, 0xe6, 0x34, 0x7d, 0xc9, 0x99,
- 0x6d, 0xec, 0x9a, 0x4a, 0x9c, 0x12, 0xe2, 0x25, 0xe2, 0x17, 0xe2, 0xfa,
- 0x47, 0x7a, 0xc3, 0x6f, 0x5a, 0xf2, 0x77, 0xe7, 0xb6, 0xe7, 0xde, 0x86,
- 0xba, 0x57, 0x32, 0x2a, 0xbf, 0xd9, 0x3d, 0x22, 0x1f, 0x91, 0xdc, 0xa7,
- 0x52, 0xc9, 0x9c, 0xe5, 0x19, 0x0c, 0x88, 0xb2, 0xc6, 0x6b, 0xea, 0x5c,
- 0xcf, 0x60, 0x0b, 0xae, 0x4d, 0x06, 0x63, 0x29, 0xde, 0xc2, 0x67, 0xea,
- 0x87, 0xcc, 0x53, 0xd6, 0x7e, 0x07, 0x7b, 0x48, 0xff, 0x9f, 0x8e, 0xcb,
- 0xe0, 0xe3, 0x3c, 0xf8, 0x78, 0xfc, 0x16, 0x0c, 0x16, 0xdd, 0xc6, 0x60,
- 0x5b, 0x6a, 0xbc, 0x7b, 0x41, 0x53, 0xc1, 0x25, 0xfe, 0x9a, 0xdf, 0x96,
- 0x15, 0xd2, 0x34, 0xca, 0xff, 0xb5, 0x23, 0x57, 0x33, 0x5c, 0x0f, 0x60,
- 0x30, 0xf4, 0xb7, 0xb6, 0x23, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e,
- 0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x1a, 0x68, 0xd9, 0x52,
- 0x72, 0xa0, 0x65, 0x60, 0xab, 0xd6, 0xf9, 0x1e, 0x32, 0xc0, 0x79, 0x52,
- 0xfe, 0x42, 0xd9, 0xdb, 0xc9, 0xa7, 0xe8, 0x00, 0x4f, 0x3e, 0x78, 0x4f,
- 0x56, 0xf2, 0x67, 0x78, 0x16, 0x26, 0xd6, 0xc8, 0x3d, 0x94, 0x49, 0xe2,
- 0x04, 0x60, 0xc8, 0x04, 0x79, 0xac, 0xf1, 0xe0, 0xcc, 0xb3, 0x7b, 0xf1,
- 0x7b, 0xb3, 0x87, 0x39, 0x33, 0xf9, 0x73, 0xd4, 0x57, 0x62, 0xdd, 0x79,
- 0x8f, 0xf6, 0x0f, 0x6f, 0xc4, 0xc1, 0x73, 0xbc, 0x1f, 0x78, 0xb2, 0x0d,
- 0xfa, 0xca, 0x31, 0xf3, 0xe6, 0x3d, 0xf9, 0x8a, 0xf2, 0xd9, 0x29, 0xa3,
- 0x03, 0xa8, 0x47, 0xc4, 0xec, 0x8b, 0xb2, 0xcc, 0x31, 0x46, 0x9f, 0xe9,
- 0x94, 0x09, 0xe8, 0xb5, 0x23, 0x95, 0x71, 0xf9, 0x72, 0xa5, 0x4b, 0xe1,
- 0x86, 0xbf, 0xf6, 0xd3, 0x89, 0x61, 0x2b, 0x90, 0x07, 0x81, 0x7f, 0x66,
- 0xfa, 0xdb, 0xe4, 0xcd, 0x51, 0x9d, 0xfb, 0x7b, 0x83, 0xc9, 0x8d, 0x2e,
- 0xf3, 0x55, 0x39, 0x1f, 0xe8, 0x7d, 0x0b, 0xbe, 0x80, 0xd5, 0x2e, 0x33,
- 0xf1, 0x2e, 0xf9, 0xb8, 0x8f, 0xf2, 0x36, 0x5f, 0x7d, 0x63, 0x9c, 0x8b,
- 0x37, 0xeb, 0x91, 0x37, 0xcd, 0xd8, 0x5f, 0x34, 0xe5, 0xbf, 0xe9, 0x6d,
- 0xa2, 0xc5, 0x9a, 0xcb, 0x44, 0xd4, 0xfc, 0xe6, 0x6b, 0xd4, 0x6f, 0x6c,
- 0x03, 0x7d, 0xd2, 0xe0, 0x39, 0x51, 0x59, 0xd6, 0xa0, 0x5f, 0x4a, 0x55,
- 0xb1, 0xce, 0x65, 0x80, 0xa8, 0x3d, 0x8d, 0x3f, 0x4b, 0x90, 0xaf, 0xd9,
- 0xaa, 0x8a, 0x59, 0xaa, 0xbc, 0xed, 0x59, 0x60, 0x5d, 0xf8, 0xc4, 0xc0,
- 0x10, 0x26, 0x7f, 0xa5, 0x93, 0xf1, 0x90, 0x66, 0x1d, 0x16, 0xfe, 0x2f,
- 0x9d, 0xff, 0xd4, 0x2b, 0xdd, 0x65, 0xac, 0x4b, 0x88, 0xb9, 0xc1, 0x53,
- 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x73, 0xbe, 0x78,
- 0x88, 0x39, 0xb8, 0x67, 0x69, 0x2f, 0xa4, 0x1c, 0x03, 0xa6, 0xed, 0x38,
- 0x03, 0xdb, 0x5d, 0xcd, 0x42, 0x56, 0xc6, 0x55, 0xde, 0xe7, 0x3c, 0xb0,
- 0xdb, 0x1f, 0xf8, 0x7f, 0x2a, 0xf6, 0xd3, 0x07, 0x64, 0xad, 0xda, 0x01,
- 0x7e, 0xd0, 0x2e, 0x44, 0x95, 0x7f, 0x7d, 0xe3, 0x28, 0xed, 0x1d, 0x6d,
- 0x89, 0x5e, 0x8b, 0xad, 0xda, 0xf7, 0x7a, 0xf5, 0xb7, 0x33, 0x7b, 0x65,
- 0xb3, 0x16, 0xda, 0x42, 0xf8, 0x87, 0xd5, 0xa8, 0xb1, 0xcb, 0x9d, 0xd0,
- 0xdd, 0xdf, 0x8f, 0xd6, 0x95, 0xaf, 0xce, 0xf9, 0xd3, 0x06, 0x45, 0x99,
- 0x17, 0xd7, 0x59, 0xf7, 0x38, 0xf7, 0x66, 0x1b, 0xa4, 0x71, 0x87, 0x7b,
- 0x90, 0xe3, 0x31, 0x87, 0x82, 0x73, 0x8c, 0x4b, 0xf4, 0xfc, 0x63, 0x62,
- 0xc3, 0x6f, 0x89, 0x2c, 0x11, 0xeb, 0xdd, 0xec, 0xbb, 0x44, 0x2e, 0xba,
- 0xe6, 0x5b, 0xec, 0x41, 0x8d, 0x65, 0x32, 0x28, 0xeb, 0xe1, 0xf7, 0xd9,
- 0xfc, 0x35, 0xdb, 0xcd, 0xd0, 0xb7, 0xd8, 0xd5, 0x96, 0xe2, 0xef, 0xff,
- 0x01, 0x37, 0x64, 0x26, 0x2b, 0x1c, 0x4c, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e20, 0x08000e78,
- 0x08000ebc, 0x08000f50, 0x08000f94, 0x80080100, 0x80080080, 0x80080000,
- 0x00000000 };
-
-static struct fw_info bnx2_com_fw_09 = {
- /* Firmware version: 4.4.23 */
- .ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
-
- .start_addr = 0x080000f8,
-
- .text_addr = 0x08000000,
- .text_len = 0x4c18,
- .text_index = 0x0,
- .gz_text = bnx2_COM_b09FwText,
- .gz_text_len = sizeof(bnx2_COM_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_COM_b09FwData,
-
- .sbss_addr = 0x08004c60,
- .sbss_len = 0x38,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08004c98,
- .bss_len = 0xbc,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08004c18,
- .rodata_len = 0x30,
- .rodata_index = 0x0,
- .rodata = bnx2_COM_b09FwRodata,
-};
-
-static u8 bnx2_CP_b09FwText[] = {
- 0xad, 0xbc, 0x0b, 0x74, 0x1c, 0xd5, 0x95, 0x2e, 0xfc, 0x55, 0x75, 0xb7,
- 0xd4, 0x92, 0xda, 0x52, 0x4b, 0x6e, 0xcb, 0x6d, 0xd0, 0xe0, 0x6a, 0xab,
- 0xda, 0x6a, 0x2c, 0x01, 0xd5, 0xb2, 0x0c, 0x4d, 0xa6, 0xc0, 0x1d, 0x5b,
- 0x80, 0x0c, 0x26, 0x11, 0xc6, 0xb9, 0x23, 0xe6, 0x7a, 0xfe, 0xf4, 0x18,
- 0x03, 0x86, 0x90, 0x5c, 0x33, 0x93, 0x9b, 0x71, 0xb8, 0x9e, 0xeb, 0x8a,
- 0xe4, 0x87, 0xc0, 0xa5, 0xee, 0x96, 0x90, 0x1f, 0xac, 0x35, 0xeb, 0xa7,
- 0x2d, 0xcb, 0x92, 0x21, 0xad, 0x16, 0x49, 0x98, 0x19, 0xe7, 0xe6, 0x81,
- 0xc6, 0xd8, 0x60, 0x93, 0xf0, 0xc8, 0x6b, 0xfd, 0x4c, 0xfe, 0xb9, 0x7f,
- 0x3c, 0xb6, 0x79, 0x83, 0xe3, 0x3c, 0x47, 0x9e, 0xc1, 0xa9, 0xff, 0xdb,
- 0xd5, 0xdd, 0xb6, 0xec, 0x40, 0x1e, 0xeb, 0x8e, 0xd6, 0xaa, 0xa5, 0xee,
- 0xaa, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0x4e,
- 0xb5, 0x06, 0x54, 0xa3, 0xf4, 0x37, 0x8b, 0xd7, 0xd5, 0x1d, 0x1b, 0xee,
- 0x5e, 0xdc, 0x7e, 0x75, 0x87, 0x7c, 0xf7, 0xce, 0xf5, 0x7a, 0xf1, 0x61,
- 0x7f, 0x26, 0x12, 0x97, 0xde, 0xd2, 0x3e, 0xb4, 0xe0, 0x47, 0xfc, 0x25,
- 0x10, 0x91, 0x7f, 0xad, 0xa5, 0xaf, 0x1e, 0x20, 0x58, 0x6e, 0x5f, 0x2e,
- 0xf8, 0x55, 0xb3, 0xf3, 0xbf, 0x2e, 0xd3, 0xe1, 0xf7, 0x98, 0x9f, 0xff,
- 0x8b, 0xbb, 0x75, 0x20, 0x99, 0x6f, 0xd5, 0x96, 0xe3, 0x9c, 0x63, 0x85,
- 0xbc, 0x90, 0xfb, 0x7f, 0x62, 0x7e, 0xf0, 0xc4, 0xb7, 0xae, 0x8b, 0x9c,
- 0xc9, 0x79, 0xe0, 0x0f, 0x9a, 0x16, 0x82, 0x0b, 0xe1, 0x6f, 0x62, 0x9d,
- 0xbf, 0x6b, 0xd9, 0xa6, 0xa2, 0xb6, 0x2c, 0x2b, 0x12, 0xce, 0x21, 0x12,
- 0xb4, 0x10, 0x89, 0x59, 0x40, 0xca, 0x6b, 0x22, 0x55, 0x69, 0xfa, 0x51,
- 0xa1, 0x57, 0x20, 0x15, 0xdc, 0xa8, 0x6d, 0xe1, 0x18, 0x97, 0xd9, 0x7e,
- 0xed, 0x44, 0x1e, 0xb8, 0xdb, 0xf6, 0xe3, 0xb8, 0x27, 0xa0, 0x9d, 0xcc,
- 0xef, 0xab, 0x2b, 0xea, 0x23, 0x09, 0x8f, 0x8e, 0x94, 0x6a, 0xca, 0x7d,
- 0x68, 0xcb, 0xf3, 0x48, 0xf9, 0xcc, 0xcf, 0x6b, 0xe3, 0x36, 0xd0, 0x9b,
- 0x69, 0x36, 0x4e, 0xa0, 0x35, 0x7c, 0x18, 0x95, 0x48, 0x85, 0x22, 0x31,
- 0xe0, 0x83, 0x73, 0x8f, 0x66, 0x14, 0xf8, 0xf4, 0xd9, 0xe8, 0xdc, 0x0b,
- 0x3c, 0x92, 0x89, 0x24, 0x75, 0x05, 0xe8, 0x9f, 0x94, 0xba, 0x91, 0x60,
- 0x8e, 0xcf, 0xb7, 0x64, 0x80, 0xad, 0x99, 0xd9, 0xd8, 0x96, 0x75, 0xf0,
- 0x9c, 0xd1, 0x1c, 0xdc, 0xc7, 0x16, 0x7a, 0xdd, 0xe7, 0xb3, 0x61, 0xe5,
- 0xe4, 0xf9, 0x5b, 0xce, 0xb7, 0x5a, 0x82, 0x78, 0x7a, 0x32, 0x84, 0x67,
- 0x27, 0xeb, 0xf1, 0x48, 0xb6, 0x1e, 0xdb, 0xb3, 0x31, 0xa8, 0xba, 0x83,
- 0x58, 0x3c, 0x86, 0x8a, 0xeb, 0x1d, 0x9c, 0x34, 0xda, 0xb0, 0x95, 0x82,
- 0x5f, 0x6d, 0x6b, 0xc4, 0xda, 0x60, 0x13, 0xb6, 0xe8, 0xd7, 0xa1, 0x38,
- 0xd6, 0x0f, 0xce, 0x65, 0x32, 0xd2, 0x3f, 0xaf, 0xaa, 0xea, 0x37, 0xe2,
- 0xf4, 0x4e, 0x13, 0xef, 0xef, 0xc4, 0x9a, 0x5a, 0x38, 0x4e, 0x3e, 0x1e,
- 0xed, 0x7e, 0x50, 0x09, 0x6a, 0x4f, 0xe5, 0xd9, 0xa1, 0x55, 0x5e, 0xca,
- 0x83, 0x36, 0x92, 0x9f, 0x39, 0x15, 0x6c, 0x2f, 0xc3, 0x76, 0x33, 0xd2,
- 0x97, 0x30, 0xbe, 0xd5, 0xf2, 0xdf, 0x68, 0x0f, 0xc5, 0x31, 0x6d, 0xcd,
- 0xbc, 0xc6, 0x3e, 0x69, 0xec, 0x4f, 0x13, 0xbe, 0x36, 0x19, 0xc6, 0x57,
- 0xd9, 0xb7, 0xaf, 0x4c, 0x4a, 0x1f, 0x23, 0x7b, 0x2c, 0xd4, 0x63, 0x34,
- 0xdb, 0x84, 0xa7, 0xf5, 0x36, 0x7c, 0x85, 0x7d, 0xec, 0x33, 0x62, 0x58,
- 0x9b, 0xb8, 0x8b, 0xfd, 0x51, 0xb0, 0xaa, 0xed, 0x2f, 0x4b, 0xfd, 0x8a,
- 0x68, 0x50, 0x55, 0x24, 0x1b, 0x22, 0x31, 0x4d, 0x15, 0x99, 0x17, 0xfa,
- 0x3b, 0x90, 0x81, 0xe5, 0x37, 0xa5, 0xcf, 0x37, 0x22, 0xcf, 0xfe, 0x7e,
- 0x79, 0x67, 0xd4, 0x58, 0xaf, 0x62, 0x65, 0x80, 0x7d, 0x7e, 0x20, 0x1e,
- 0x4d, 0x2c, 0x62, 0x9f, 0xc7, 0xf3, 0x2a, 0xc7, 0x13, 0xd2, 0xc6, 0xd8,
- 0xf7, 0xe4, 0x2a, 0x95, 0x7d, 0x67, 0x5f, 0x32, 0xec, 0x4b, 0x86, 0x7d,
- 0xc9, 0xb0, 0x2f, 0x6e, 0xbf, 0x63, 0xec, 0x73, 0x71, 0x8e, 0x46, 0xf2,
- 0xc7, 0xd9, 0xdf, 0x99, 0xfd, 0x6c, 0x62, 0xdf, 0x91, 0xaa, 0xe7, 0xbc,
- 0x35, 0xa7, 0x65, 0xde, 0x1c, 0xe7, 0x55, 0xc3, 0x71, 0x7e, 0x6e, 0x04,
- 0xa8, 0xbf, 0x0c, 0xed, 0xa0, 0xdc, 0x9f, 0xf9, 0x56, 0x85, 0x89, 0x4e,
- 0x9a, 0xa0, 0x73, 0xa4, 0x23, 0x9a, 0x68, 0x50, 0x54, 0x78, 0xf5, 0xa0,
- 0xd6, 0x52, 0x88, 0x18, 0xd4, 0x8f, 0x16, 0x2d, 0x40, 0xd3, 0x0b, 0x94,
- 0x75, 0x51, 0xbb, 0x91, 0xe0, 0x14, 0xa4, 0x5d, 0x8d, 0xed, 0x1f, 0x2f,
- 0xcd, 0x9d, 0xc8, 0x0f, 0xb3, 0x4d, 0x69, 0x5f, 0x64, 0x3b, 0xce, 0xcf,
- 0x0c, 0xe8, 0x41, 0x44, 0xad, 0x41, 0xda, 0x9f, 0xc7, 0x0c, 0x6a, 0x1b,
- 0xf2, 0x7c, 0x7e, 0x5e, 0x46, 0x71, 0x3e, 0xd6, 0xe6, 0xb5, 0xd2, 0x18,
- 0x22, 0xec, 0x82, 0xd8, 0x41, 0x38, 0x15, 0x30, 0x83, 0xd2, 0xf7, 0xee,
- 0x3d, 0x03, 0x9b, 0x9d, 0x79, 0xba, 0xe8, 0x4a, 0xdf, 0x38, 0xcf, 0x13,
- 0x48, 0x9c, 0x5e, 0xf2, 0x90, 0x35, 0xab, 0x23, 0x8e, 0x6a, 0x1d, 0x81,
- 0x2a, 0x1d, 0xdd, 0xe9, 0x89, 0x6a, 0xab, 0xc6, 0xfc, 0xe6, 0x9d, 0x03,
- 0x13, 0x7e, 0x54, 0x4f, 0xe8, 0xa8, 0x9a, 0x78, 0xdc, 0x8b, 0x5a, 0x03,
- 0x3b, 0x26, 0xff, 0xcc, 0x5b, 0x1c, 0xdb, 0xcd, 0xa5, 0x31, 0xba, 0xb6,
- 0xef, 0x7f, 0xdd, 0x3e, 0xe3, 0x54, 0xe8, 0x55, 0x7f, 0xe6, 0x31, 0x75,
- 0x6d, 0x0c, 0x38, 0xb3, 0xb6, 0x63, 0x39, 0x7a, 0x83, 0x0a, 0xe6, 0xeb,
- 0x7f, 0x32, 0x0b, 0xb5, 0x26, 0xac, 0xc9, 0xc6, 0x54, 0x85, 0x19, 0x4a,
- 0x71, 0x6e, 0xf0, 0x82, 0x9d, 0x83, 0x6f, 0xc0, 0x71, 0xa4, 0xec, 0x49,
- 0xdc, 0x79, 0xa7, 0x6a, 0x1e, 0xba, 0xc6, 0x87, 0x4e, 0x96, 0xc7, 0xa6,
- 0xa3, 0x1d, 0x3f, 0x57, 0xd4, 0x9d, 0xdd, 0xb0, 0xc6, 0x3d, 0x48, 0x06,
- 0x53, 0xfc, 0x7f, 0xc5, 0x15, 0x2b, 0x13, 0xdd, 0xb0, 0xc7, 0xa7, 0x79,
- 0xdf, 0xcb, 0x7b, 0x26, 0xd2, 0x99, 0x2b, 0xae, 0xb8, 0x3d, 0x91, 0xc2,
- 0xc0, 0xb8, 0x7c, 0xf6, 0x62, 0xaa, 0x3e, 0x85, 0xed, 0xbb, 0x35, 0xd4,
- 0xe9, 0xdd, 0xc8, 0x8c, 0xcb, 0x67, 0xc7, 0x39, 0x65, 0x7c, 0x09, 0x7b,
- 0xda, 0xe8, 0xff, 0x73, 0xbb, 0xb1, 0x6d, 0xb7, 0x85, 0x4a, 0xdd, 0xa2,
- 0xee, 0x15, 0xef, 0x3f, 0xb7, 0x29, 0xd0, 0xee, 0x84, 0xb7, 0x42, 0x17,
- 0xbd, 0x25, 0xbc, 0xf7, 0xd8, 0x66, 0x70, 0xbe, 0xee, 0x38, 0x23, 0xc6,
- 0x22, 0x7c, 0xba, 0x7b, 0x2d, 0xac, 0x7d, 0x01, 0x58, 0xab, 0xe5, 0x7f,
- 0x37, 0x75, 0xb8, 0x16, 0xbd, 0xfb, 0xd6, 0xa2, 0xff, 0x31, 0x3a, 0x6e,
- 0x7d, 0xd0, 0x9d, 0xa7, 0x6f, 0xb5, 0x48, 0x9f, 0xa4, 0x7f, 0x3d, 0xbc,
- 0x44, 0xb7, 0x5f, 0xe0, 0x7f, 0x29, 0x33, 0xed, 0x60, 0xce, 0x85, 0x32,
- 0xdb, 0x59, 0x66, 0xdb, 0x45, 0x65, 0x4c, 0x3c, 0x31, 0x29, 0xba, 0x10,
- 0x95, 0xfd, 0x3e, 0x5d, 0x7c, 0xdb, 0xe9, 0x0d, 0x89, 0x2e, 0xac, 0x1e,
- 0x1f, 0x22, 0xdd, 0xf7, 0x2a, 0x5e, 0xac, 0x18, 0x00, 0xeb, 0xd0, 0x09,
- 0xaa, 0x23, 0xc9, 0x85, 0x8a, 0x89, 0xea, 0x01, 0x05, 0x2b, 0xe2, 0x55,
- 0xd0, 0xea, 0x45, 0xde, 0x8f, 0x1c, 0x2b, 0x28, 0xfd, 0x3d, 0x8a, 0x1a,
- 0xde, 0x5f, 0x17, 0xff, 0x01, 0xf1, 0x4c, 0xfa, 0x14, 0x67, 0xf9, 0x3b,
- 0x78, 0xff, 0x95, 0x19, 0xdf, 0xa5, 0x9c, 0xe3, 0xf4, 0x19, 0x06, 0xfa,
- 0x33, 0x6d, 0xd8, 0x9e, 0x49, 0x46, 0xa8, 0x25, 0xcb, 0x67, 0xf2, 0xbe,
- 0x19, 0xed, 0xea, 0x85, 0xb4, 0x03, 0xa5, 0xda, 0x84, 0x37, 0xdf, 0x71,
- 0xdc, 0xff, 0x92, 0xad, 0xf7, 0x3c, 0xa5, 0xf8, 0x68, 0xec, 0xd2, 0xce,
- 0x71, 0xff, 0x2b, 0xb6, 0x82, 0x37, 0xf5, 0xe8, 0x86, 0x77, 0x94, 0xe3,
- 0xfe, 0x97, 0xf3, 0x41, 0xcc, 0x1b, 0x88, 0xf4, 0x58, 0x4a, 0x02, 0x5f,
- 0xcf, 0x87, 0x10, 0x1e, 0x30, 0x71, 0x30, 0x6f, 0xe0, 0xc9, 0x8b, 0x70,
- 0xe0, 0x43, 0xff, 0x2c, 0x0f, 0xc7, 0xbe, 0xce, 0xd6, 0xd0, 0x6b, 0x9c,
- 0x73, 0x92, 0x41, 0xa4, 0xea, 0xcc, 0xe3, 0xfe, 0xf7, 0x07, 0xa0, 0xd4,
- 0x9a, 0x7a, 0xb8, 0xa0, 0xfc, 0xab, 0x93, 0x0a, 0x49, 0x31, 0xf6, 0xcf,
- 0xc5, 0xb2, 0x24, 0xed, 0xce, 0x20, 0xce, 0x9d, 0x71, 0x6a, 0x68, 0xb3,
- 0x15, 0xe6, 0x65, 0x18, 0x1f, 0xd6, 0xf1, 0xa4, 0xed, 0x38, 0xef, 0x19,
- 0x53, 0x89, 0x00, 0xf4, 0xee, 0x77, 0x11, 0x49, 0x2e, 0xa2, 0x5e, 0x8e,
- 0xe6, 0x75, 0x8c, 0xda, 0x26, 0x9e, 0xb3, 0x9b, 0x83, 0x7d, 0x58, 0x8c,
- 0x64, 0xb8, 0x18, 0x43, 0x26, 0xd8, 0xef, 0x91, 0x68, 0x37, 0xea, 0xcc,
- 0x04, 0x0e, 0xb1, 0xdf, 0xa7, 0x97, 0x88, 0x1c, 0x03, 0x2f, 0xff, 0x01,
- 0x7d, 0x25, 0xbe, 0xe3, 0x71, 0xf6, 0x35, 0xb1, 0xf8, 0x9c, 0x83, 0xd9,
- 0x7e, 0x9c, 0x30, 0xe6, 0xd2, 0x0e, 0x61, 0x55, 0x99, 0x7e, 0x6f, 0xbf,
- 0x1d, 0xc4, 0x81, 0x7c, 0xc0, 0xdb, 0x67, 0x87, 0xb0, 0x8f, 0xfe, 0x36,
- 0x8f, 0xa6, 0x1e, 0xa6, 0xdc, 0x79, 0xc4, 0xb5, 0xc2, 0x70, 0x13, 0x26,
- 0x87, 0x23, 0xc6, 0x2b, 0x4a, 0x18, 0x63, 0xa3, 0x97, 0x61, 0x62, 0x58,
- 0xc1, 0x78, 0x94, 0x7d, 0xe7, 0xe7, 0x2f, 0x0f, 0x5f, 0x81, 0xfc, 0xb0,
- 0x07, 0x3b, 0x5c, 0xbd, 0xba, 0x38, 0x53, 0xfa, 0x7f, 0x19, 0x72, 0xa3,
- 0xf0, 0x2e, 0x1a, 0x08, 0xe2, 0xa9, 0xbc, 0xd7, 0xab, 0x0f, 0x84, 0x30,
- 0x9a, 0xff, 0x36, 0xe7, 0x4d, 0x64, 0x6b, 0x18, 0xb1, 0xc7, 0xdc, 0x39,
- 0xac, 0x33, 0x29, 0xac, 0x18, 0x5f, 0x19, 0xcb, 0x34, 0xc6, 0x99, 0x04,
- 0x71, 0x48, 0x7c, 0xdc, 0x4f, 0x0c, 0x12, 0x1f, 0x7f, 0x4d, 0x41, 0x6d,
- 0x02, 0x7d, 0x93, 0xe5, 0xe7, 0x0a, 0xed, 0xdf, 0x8b, 0x75, 0x41, 0x03,
- 0x76, 0x46, 0xec, 0xb4, 0x8c, 0xcb, 0xf2, 0x59, 0xe6, 0xbf, 0x1a, 0xd6,
- 0xfe, 0x6a, 0xec, 0xa0, 0x8f, 0x3d, 0xba, 0x53, 0xee, 0x3b, 0xce, 0x7d,
- 0xf1, 0x3a, 0xda, 0x18, 0x6e, 0xaa, 0x42, 0xd4, 0x78, 0xcb, 0xed, 0x9b,
- 0x85, 0xb1, 0xbc, 0xc4, 0x50, 0x8d, 0xf1, 0xed, 0x28, 0xdb, 0xea, 0x60,
- 0x3b, 0x06, 0xbe, 0x3d, 0xd9, 0x86, 0x7f, 0x9c, 0x8c, 0xe1, 0x1f, 0x26,
- 0x75, 0xfc, 0xfd, 0xa4, 0x86, 0x67, 0x2e, 0xc2, 0xf5, 0x3b, 0xa9, 0x2b,
- 0xc1, 0x30, 0x03, 0x5b, 0x32, 0x15, 0xd8, 0x36, 0x5c, 0x8d, 0xbe, 0xe1,
- 0xe6, 0xd8, 0x73, 0xc4, 0xe3, 0x7f, 0x30, 0x6e, 0xc7, 0x54, 0x43, 0x87,
- 0xeb, 0x33, 0x8f, 0xf0, 0xfe, 0xa3, 0xc3, 0xcd, 0x9c, 0x43, 0xc7, 0x51,
- 0xe3, 0xad, 0x89, 0x43, 0xc4, 0xf7, 0xe3, 0xa1, 0x88, 0x36, 0xa5, 0x46,
- 0xb4, 0x24, 0x7c, 0xb0, 0xdb, 0x54, 0x58, 0x73, 0x22, 0x39, 0x7a, 0x31,
- 0x42, 0xfa, 0x7d, 0x1c, 0x5b, 0x44, 0xb3, 0x54, 0x83, 0xf6, 0xcb, 0x98,
- 0xa1, 0x76, 0x10, 0x5f, 0xaa, 0xf1, 0xfe, 0x70, 0xa4, 0xdf, 0x52, 0xef,
- 0x80, 0xd5, 0xe0, 0x38, 0x5f, 0x8d, 0x63, 0xc3, 0x5c, 0x13, 0xc9, 0x39,
- 0x8c, 0x05, 0x57, 0x98, 0x49, 0x30, 0x8e, 0xe1, 0xf4, 0x80, 0x1e, 0xfe,
- 0x7f, 0x94, 0x3b, 0xf1, 0xdf, 0xbb, 0x23, 0x9a, 0xa6, 0xb6, 0x5a, 0xfb,
- 0x54, 0x92, 0x8d, 0x46, 0x68, 0x61, 0xf3, 0x56, 0x6c, 0x74, 0x79, 0x82,
- 0x82, 0xa0, 0xde, 0x81, 0xbe, 0x0c, 0x2b, 0x85, 0x9a, 0x7b, 0x06, 0xd5,
- 0xe6, 0x69, 0x43, 0x8d, 0x1c, 0xed, 0x56, 0x89, 0xb7, 0x8b, 0x4f, 0x3b,
- 0x5a, 0xa3, 0xe3, 0xb4, 0x2f, 0x96, 0x36, 0x35, 0x34, 0x70, 0x9e, 0xeb,
- 0x39, 0xcf, 0xed, 0x85, 0x6a, 0xbc, 0x33, 0x0c, 0x6b, 0xae, 0x19, 0xe9,
- 0x7a, 0x40, 0xad, 0xc6, 0xdb, 0xa3, 0xd5, 0x38, 0x39, 0xec, 0xc5, 0x5b,
- 0xc3, 0x8e, 0x73, 0x8f, 0x51, 0x87, 0x8a, 0x38, 0xe6, 0x54, 0x20, 0x7a,
- 0x66, 0x04, 0x16, 0x7e, 0xc3, 0xb2, 0xbf, 0x1c, 0x0e, 0xe3, 0x57, 0xc3,
- 0x1f, 0xc3, 0x33, 0x0d, 0xc9, 0x63, 0xb3, 0x19, 0x23, 0xa7, 0x69, 0x3f,
- 0xa7, 0xed, 0x48, 0xcf, 0x3c, 0x4f, 0x64, 0x23, 0x79, 0xcb, 0xfa, 0x2f,
- 0x2a, 0x91, 0xd4, 0x2b, 0x4a, 0x44, 0x1b, 0x50, 0x42, 0x78, 0x97, 0x76,
- 0x7a, 0x2a, 0xdf, 0x9c, 0xf8, 0x01, 0xdb, 0xff, 0xb5, 0xf1, 0x0f, 0xce,
- 0x54, 0xa3, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xd3, 0x77, 0xff, 0x91, 0x31,
- 0xea, 0x1f, 0x32, 0xd4, 0x39, 0xfb, 0xf3, 0xcc, 0x6f, 0xc5, 0x2f, 0x99,
- 0xaf, 0x04, 0xe7, 0xf1, 0x72, 0xfc, 0x4f, 0x77, 0x6c, 0xc7, 0x9c, 0xbf,
- 0x09, 0xc9, 0xf8, 0x3a, 0x1b, 0x8b, 0x18, 0x24, 0xe3, 0x3c, 0xea, 0xa4,
- 0x82, 0x32, 0x46, 0x19, 0xab, 0xab, 0x4b, 0x6d, 0x83, 0xf2, 0x90, 0x8a,
- 0x6a, 0xc7, 0x79, 0xcc, 0x28, 0x3d, 0x0f, 0x95, 0xc7, 0xfa, 0x31, 0xde,
- 0x97, 0xf1, 0xbe, 0xe3, 0x11, 0xdd, 0x6b, 0xea, 0xd5, 0xfc, 0x1e, 0xb1,
- 0x92, 0xb8, 0x33, 0xc0, 0xef, 0xb1, 0xe4, 0xf9, 0xef, 0xde, 0xba, 0x8b,
- 0x9f, 0xd3, 0x4e, 0xdd, 0xf6, 0xee, 0xe4, 0x77, 0x19, 0xcb, 0xab, 0xb4,
- 0x9b, 0x0f, 0xb3, 0x13, 0xb1, 0x91, 0x18, 0xed, 0xe9, 0x94, 0xc4, 0x15,
- 0x2b, 0x64, 0xfa, 0x2d, 0xd5, 0x84, 0x46, 0x9c, 0xf0, 0x2b, 0xe6, 0x06,
- 0x68, 0x79, 0x0b, 0x9f, 0xea, 0xf0, 0xe0, 0xaf, 0x3a, 0x14, 0xcc, 0xd6,
- 0x37, 0x20, 0x7b, 0xad, 0xe5, 0xd4, 0xeb, 0x7b, 0x55, 0xf1, 0x81, 0x8a,
- 0x34, 0x2c, 0xfa, 0x1d, 0x12, 0xe4, 0x4a, 0x75, 0x7f, 0xaa, 0xe0, 0x44,
- 0x3c, 0x4a, 0x9b, 0xdb, 0x82, 0x6d, 0x9c, 0xf3, 0x59, 0x69, 0xf8, 0x03,
- 0xa6, 0x09, 0x7b, 0x00, 0xfe, 0x2a, 0xfa, 0xfe, 0x95, 0x03, 0xcd, 0x1b,
- 0xc6, 0x94, 0x48, 0x22, 0xad, 0x44, 0xba, 0xa9, 0x6f, 0xe3, 0xb4, 0x8b,
- 0x1b, 0x11, 0xad, 0x42, 0x91, 0x76, 0x4c, 0xb4, 0xe4, 0xb7, 0x60, 0x60,
- 0x52, 0x3e, 0x27, 0xa0, 0xe7, 0x7f, 0x5c, 0xea, 0x3b, 0xfc, 0x3e, 0xf6,
- 0x61, 0xbf, 0xfd, 0xba, 0x93, 0x0b, 0x46, 0xb4, 0x9c, 0xfb, 0x7d, 0x3d,
- 0xbf, 0xc3, 0x5f, 0x61, 0x3e, 0x88, 0xe7, 0xed, 0x37, 0xe7, 0x94, 0xcb,
- 0x15, 0xfb, 0x7a, 0x69, 0x7f, 0xfe, 0xb7, 0x93, 0x0c, 0xb9, 0xfd, 0xf1,
- 0xd7, 0xb0, 0x8d, 0xcf, 0x0c, 0xb0, 0x8d, 0x4c, 0xb9, 0x3f, 0x40, 0x20,
- 0x2d, 0x71, 0x38, 0xa2, 0x2d, 0x50, 0x9a, 0x8d, 0x01, 0x25, 0x12, 0xbb,
- 0x57, 0x69, 0x4d, 0x8c, 0x91, 0x5f, 0x6e, 0x47, 0xb1, 0x4f, 0xd1, 0x7c,
- 0xb1, 0x3f, 0x0b, 0xf2, 0x50, 0x3c, 0x03, 0x08, 0xcc, 0xd7, 0x17, 0x62,
- 0xb3, 0x3b, 0xa7, 0x50, 0xc2, 0x03, 0x1a, 0x6a, 0xc9, 0x5f, 0xc2, 0x13,
- 0xc0, 0xe4, 0x10, 0xb9, 0x5c, 0xbc, 0x19, 0x9f, 0x63, 0x2c, 0x98, 0xc7,
- 0x32, 0x5f, 0x0c, 0x9e, 0xc7, 0x2f, 0xa5, 0xdf, 0x26, 0xc0, 0xcc, 0x29,
- 0xf2, 0xb2, 0xd4, 0x7f, 0x41, 0x52, 0xee, 0x3d, 0x6e, 0x43, 0xc9, 0xd8,
- 0x91, 0x3d, 0x80, 0x3e, 0x15, 0xf7, 0x24, 0xef, 0x0f, 0x63, 0x33, 0x4e,
- 0xc7, 0xa3, 0xa9, 0x82, 0x12, 0x35, 0x86, 0x14, 0xc3, 0xbf, 0x8d, 0xed,
- 0xed, 0x60, 0x99, 0xed, 0xbc, 0x1e, 0x88, 0xea, 0x5d, 0x77, 0x28, 0xc9,
- 0x2b, 0xab, 0x58, 0xe6, 0xa4, 0x11, 0x25, 0xcf, 0x8c, 0x4e, 0xaf, 0x82,
- 0xe1, 0x7f, 0x22, 0x2f, 0xb2, 0x12, 0xca, 0x96, 0xc2, 0xe3, 0x6a, 0x11,
- 0x8f, 0x7e, 0x5d, 0xd2, 0xd9, 0x49, 0xf9, 0xee, 0xb6, 0xed, 0x1d, 0x68,
- 0xaa, 0xf9, 0xed, 0x7b, 0xda, 0x9c, 0x8b, 0xef, 0xb5, 0x06, 0x47, 0xe9,
- 0x7f, 0x1e, 0xbd, 0x8a, 0x73, 0x27, 0xfc, 0x28, 0x19, 0xf3, 0x41, 0xee,
- 0x79, 0x90, 0xf3, 0x26, 0xc3, 0x1e, 0x7c, 0xe0, 0x24, 0x57, 0xcb, 0xbd,
- 0x6a, 0xa4, 0xba, 0x5b, 0xc3, 0x5e, 0xb4, 0x26, 0xb6, 0x12, 0x0b, 0x8e,
- 0xaf, 0x5e, 0xc6, 0x67, 0x51, 0xe3, 0x39, 0x34, 0x6b, 0x5b, 0x21, 0x9f,
- 0xcf, 0xd2, 0x66, 0x97, 0x49, 0x5d, 0x96, 0x29, 0x72, 0x1f, 0xc1, 0x9a,
- 0x2d, 0x86, 0x83, 0xe7, 0x0d, 0x58, 0x95, 0xe6, 0x41, 0xe5, 0x84, 0xfd,
- 0x1b, 0x27, 0xe9, 0xc5, 0x4a, 0xfa, 0xa5, 0x41, 0xda, 0xab, 0xf9, 0xcd,
- 0xa8, 0x76, 0x94, 0x99, 0x82, 0xc7, 0xb4, 0x94, 0xe3, 0xf9, 0x2d, 0xca,
- 0xeb, 0xf9, 0x7e, 0xe5, 0x54, 0x5e, 0xea, 0x1e, 0x54, 0x4e, 0xe6, 0x25,
- 0x1e, 0x36, 0x69, 0x47, 0xc8, 0x6f, 0xc8, 0xa9, 0xd4, 0x3e, 0x03, 0xca,
- 0x36, 0xa3, 0x96, 0x3c, 0x5f, 0x8f, 0x8d, 0xb0, 0xbf, 0xfb, 0x3b, 0x60,
- 0x6c, 0x37, 0x7c, 0x38, 0x1e, 0x44, 0xa0, 0xcf, 0xf0, 0xca, 0x77, 0xe6,
- 0x03, 0x52, 0xb7, 0x49, 0xdb, 0x9a, 0x3f, 0x47, 0xff, 0x2a, 0x7e, 0xdf,
- 0xdf, 0x51, 0xbe, 0xf7, 0x0b, 0x67, 0x6a, 0xb5, 0xca, 0xef, 0x7f, 0xea,
- 0xe1, 0x50, 0x58, 0x77, 0x26, 0x3f, 0x17, 0x2e, 0xa5, 0x92, 0x3f, 0xd6,
- 0xc3, 0x0a, 0x46, 0xac, 0x1c, 0x73, 0x85, 0xbe, 0x4c, 0x3b, 0xfd, 0x2d,
- 0xcc, 0x58, 0x99, 0x24, 0xbe, 0x93, 0xf7, 0xb2, 0xcd, 0x0a, 0x3d, 0x80,
- 0x9b, 0xec, 0x66, 0x4f, 0x51, 0x7f, 0x2a, 0x31, 0xcc, 0xc3, 0x98, 0x2e,
- 0x1c, 0xef, 0x52, 0xce, 0xdd, 0xa4, 0xbd, 0xc5, 0x7e, 0x57, 0xe9, 0x7a,
- 0xac, 0x4a, 0x69, 0xd2, 0x5e, 0xcf, 0x27, 0xe9, 0xe3, 0x3d, 0x6c, 0x37,
- 0x80, 0xd7, 0xed, 0x5a, 0xe6, 0x20, 0x91, 0xa4, 0x45, 0x81, 0x37, 0x77,
- 0x84, 0x41, 0xce, 0x37, 0xe3, 0xaf, 0x1b, 0x8c, 0xff, 0x12, 0xa3, 0xd5,
- 0x5b, 0x96, 0x24, 0xb0, 0x3e, 0x0f, 0xef, 0xba, 0x0e, 0x13, 0xf7, 0x30,
- 0xb6, 0xdf, 0xc7, 0x78, 0xf9, 0x20, 0x63, 0xe1, 0x8e, 0x38, 0xc7, 0x56,
- 0xef, 0x38, 0x95, 0xfa, 0x66, 0xc9, 0x67, 0x30, 0xc0, 0x58, 0x7c, 0x37,
- 0xe3, 0xcb, 0x16, 0x7e, 0x7e, 0x29, 0xff, 0x1f, 0xce, 0x7d, 0xcc, 0xa7,
- 0x9e, 0xbf, 0x48, 0x26, 0xd4, 0x51, 0xbd, 0x35, 0xb6, 0x95, 0xb1, 0x98,
- 0x72, 0xad, 0x5a, 0xd3, 0x71, 0xae, 0x8c, 0x46, 0x92, 0x3e, 0xc5, 0xc0,
- 0x73, 0x13, 0xc7, 0x1d, 0x6d, 0x8e, 0xe4, 0x52, 0xe5, 0x38, 0x28, 0x63,
- 0x95, 0x1c, 0x41, 0xf0, 0x41, 0xf2, 0x84, 0x99, 0x18, 0xa1, 0xe2, 0xe6,
- 0x61, 0xc9, 0x13, 0xc2, 0x58, 0x65, 0x7f, 0x09, 0xcf, 0xb5, 0x79, 0xd1,
- 0xc5, 0x1c, 0xeb, 0x16, 0x3b, 0x80, 0x3b, 0x88, 0xa5, 0x2b, 0x6c, 0xe6,
- 0x4e, 0xc1, 0x10, 0x6e, 0xb5, 0xbd, 0x38, 0xdc, 0xc6, 0x1c, 0x28, 0x54,
- 0x89, 0x77, 0x0d, 0x0f, 0x8e, 0x18, 0x41, 0xe4, 0x5c, 0x7f, 0xd8, 0x41,
- 0x0c, 0xa4, 0x1e, 0x55, 0xc9, 0x1d, 0x44, 0x87, 0x1e, 0xea, 0x53, 0x45,
- 0xea, 0xbc, 0x0e, 0x3f, 0x2c, 0x17, 0x90, 0x7e, 0x49, 0x3e, 0xf0, 0x33,
- 0x27, 0x35, 0x47, 0xea, 0xc3, 0x0a, 0x98, 0x32, 0x0e, 0xe1, 0xb7, 0x06,
- 0xfa, 0x26, 0x3a, 0xc8, 0xed, 0x66, 0x0e, 0xf5, 0x0c, 0xb9, 0x75, 0x1d,
- 0x5e, 0xd3, 0x85, 0x5b, 0xbf, 0x8a, 0x20, 0x7d, 0xb7, 0x7f, 0x22, 0xba,
- 0xe1, 0x8c, 0xe2, 0xc1, 0x4b, 0x7a, 0x2d, 0x79, 0x9f, 0x89, 0xed, 0x13,
- 0xf0, 0x6e, 0x5d, 0x62, 0x20, 0x3d, 0xd1, 0x9b, 0x98, 0xc5, 0xb4, 0xd7,
- 0xbb, 0xa4, 0xc8, 0x89, 0x3e, 0x43, 0xdd, 0xae, 0x8d, 0xbb, 0x9c, 0xa8,
- 0xc8, 0x07, 0x82, 0x8e, 0x73, 0x52, 0x17, 0x3d, 0x03, 0x07, 0x4a, 0x3a,
- 0xde, 0xcf, 0xcf, 0xfd, 0x25, 0x1d, 0x6f, 0xa1, 0x3c, 0xfa, 0x1f, 0xb6,
- 0x5d, 0xc4, 0x63, 0x34, 0x54, 0x9a, 0xc2, 0x6f, 0x88, 0xc3, 0xc4, 0x93,
- 0x24, 0x75, 0xfc, 0x42, 0x7e, 0xbd, 0xe0, 0x36, 0xa7, 0xbb, 0xdd, 0xc5,
- 0xef, 0xa4, 0x7a, 0x80, 0x76, 0x20, 0x7a, 0x78, 0xad, 0x94, 0xdb, 0x38,
- 0xce, 0x90, 0x21, 0x3a, 0x2e, 0xe7, 0x65, 0xa2, 0xeb, 0x36, 0xc9, 0xb1,
- 0xfa, 0x81, 0xdf, 0xb0, 0xac, 0x87, 0xb8, 0x6b, 0xe2, 0x6b, 0xdd, 0x62,
- 0x3b, 0xb3, 0xdc, 0x58, 0x79, 0xd5, 0x42, 0xc7, 0xf9, 0x4a, 0x5c, 0xc3,
- 0x7b, 0x7a, 0x6b, 0xa2, 0x5d, 0x8d, 0xb0, 0xaf, 0x49, 0xd8, 0x93, 0x1d,
- 0x9c, 0xbb, 0x2b, 0x90, 0x0c, 0x89, 0xad, 0x61, 0x43, 0x45, 0x11, 0xc3,
- 0x71, 0xca, 0xd6, 0x63, 0xdb, 0x38, 0x67, 0xfb, 0x42, 0x5d, 0xe4, 0x71,
- 0x6a, 0x27, 0xd3, 0x7f, 0xf2, 0x27, 0xdd, 0x7a, 0x04, 0xef, 0x38, 0xb9,
- 0x90, 0xc3, 0x38, 0x29, 0xb9, 0xd1, 0x7c, 0x1c, 0x0e, 0x7a, 0xf0, 0x62,
- 0xac, 0x11, 0xc9, 0x7a, 0x05, 0x35, 0xfa, 0x9b, 0xce, 0x77, 0x42, 0xd2,
- 0x0e, 0x73, 0x3c, 0xf5, 0x56, 0x8f, 0xe4, 0x80, 0x5e, 0x5d, 0xe4, 0x76,
- 0x31, 0xc7, 0xbd, 0xb4, 0xfd, 0x7f, 0x75, 0x8e, 0x87, 0xa4, 0xfd, 0x48,
- 0x50, 0x53, 0x7f, 0xd7, 0x1c, 0x7e, 0xdf, 0xf9, 0x81, 0x2b, 0x33, 0xe3,
- 0xea, 0x01, 0xaa, 0xc8, 0x23, 0x54, 0x54, 0x8b, 0xcc, 0x72, 0x3b, 0xe2,
- 0x67, 0x73, 0x79, 0x4f, 0x9e, 0x89, 0x8d, 0x6c, 0x61, 0xbb, 0xcf, 0x39,
- 0x68, 0x94, 0xef, 0xd3, 0x1e, 0x29, 0x6b, 0x4d, 0x1e, 0x5a, 0xe1, 0xc5,
- 0x52, 0xb4, 0xc4, 0x97, 0x2d, 0x97, 0xb1, 0xa8, 0x66, 0x52, 0xf3, 0xc3,
- 0x6a, 0xf4, 0x10, 0x8b, 0xdf, 0x68, 0x6b, 0xc3, 0x72, 0xe6, 0x8c, 0xef,
- 0x10, 0x5c, 0x7a, 0x75, 0x0f, 0xa6, 0x38, 0xbe, 0x27, 0x0d, 0x59, 0x2f,
- 0x70, 0x70, 0x4b, 0xdc, 0x4a, 0xd1, 0x63, 0xad, 0x59, 0xb4, 0x9d, 0x6a,
- 0x5d, 0xe2, 0x7c, 0x2d, 0x6a, 0x4c, 0x6f, 0xec, 0x1d, 0x44, 0x8c, 0x1d,
- 0xe4, 0x39, 0x5a, 0x7d, 0x4b, 0xc2, 0x47, 0xed, 0xbe, 0x6c, 0x47, 0x13,
- 0x47, 0x94, 0xa2, 0x3f, 0xbc, 0xc0, 0xb9, 0x7d, 0xcd, 0xd6, 0x37, 0x56,
- 0x7a, 0x8a, 0xdf, 0x5f, 0x71, 0xf3, 0xd1, 0xb2, 0x3f, 0x84, 0x4b, 0xb8,
- 0xe1, 0xf7, 0x9f, 0xb2, 0x71, 0x86, 0x54, 0x88, 0x79, 0x29, 0xce, 0xf4,
- 0x19, 0x53, 0x8a, 0x4f, 0xaf, 0x25, 0xae, 0x0a, 0x96, 0x56, 0x90, 0x13,
- 0x4a, 0xec, 0xf7, 0xfb, 0xdf, 0x61, 0x19, 0x72, 0xba, 0xe3, 0xb1, 0xeb,
- 0x5b, 0x13, 0x7e, 0x24, 0xad, 0x4a, 0xfa, 0xe5, 0x2c, 0x33, 0xe4, 0xbf,
- 0xaa, 0x60, 0x35, 0x06, 0x68, 0xd7, 0x35, 0xcc, 0x57, 0x5b, 0xd2, 0x13,
- 0x8c, 0xe1, 0x6d, 0x78, 0x70, 0x82, 0x23, 0x6b, 0x18, 0x6c, 0x54, 0x4d,
- 0x59, 0x83, 0x08, 0xc2, 0xd7, 0xf0, 0xe0, 0x0d, 0xaa, 0x79, 0x1c, 0x3d,
- 0x1d, 0xfe, 0xce, 0x44, 0x01, 0xfe, 0x7a, 0x73, 0x13, 0xe2, 0x69, 0xc9,
- 0x3b, 0x05, 0x23, 0x93, 0x5b, 0x89, 0x5a, 0x8d, 0x75, 0xd7, 0x96, 0xf5,
- 0x0d, 0xb5, 0xd6, 0x94, 0xfc, 0x53, 0xeb, 0x7c, 0xc5, 0xc5, 0xd2, 0x20,
- 0xf3, 0x85, 0x1f, 0x87, 0xff, 0xcf, 0xea, 0x27, 0x38, 0x27, 0xd2, 0x17,
- 0xf9, 0x2f, 0x79, 0x3f, 0xbc, 0x2a, 0xb1, 0xb0, 0x77, 0xdc, 0xcb, 0xfc,
- 0x4a, 0xe6, 0x4c, 0xe2, 0xf1, 0x6b, 0xff, 0xf5, 0x79, 0xfa, 0x8b, 0x8f,
- 0xba, 0x7f, 0x44, 0xb7, 0x08, 0xf3, 0x8e, 0xa3, 0xc7, 0x23, 0xe1, 0x0a,
- 0x45, 0xc3, 0xf6, 0xb6, 0x7f, 0xa7, 0x8d, 0x80, 0x38, 0x06, 0x12, 0xeb,
- 0x5a, 0x6c, 0x19, 0xaf, 0x98, 0x51, 0xaf, 0x67, 0x4d, 0xb9, 0xde, 0x80,
- 0x6e, 0xa5, 0xa4, 0xde, 0x68, 0x3c, 0xd2, 0xb3, 0x8d, 0xf5, 0x1e, 0x65,
- 0xbd, 0x24, 0x63, 0xe7, 0x3d, 0x13, 0x41, 0x37, 0x9f, 0xb3, 0xc6, 0xab,
- 0x67, 0xb6, 0x77, 0xbe, 0xde, 0xe3, 0xba, 0x35, 0xe5, 0xb6, 0xb7, 0x38,
- 0xb2, 0xb1, 0xc2, 0xe3, 0x45, 0x9a, 0xf5, 0xa6, 0x58, 0xef, 0xf5, 0x09,
- 0x59, 0x8f, 0xc0, 0x0d, 0xe3, 0x76, 0xe6, 0xb8, 0x47, 0xd7, 0x83, 0x27,
- 0x91, 0x24, 0xe6, 0xba, 0x73, 0x79, 0xc3, 0x58, 0x7e, 0x33, 0xb6, 0xeb,
- 0x87, 0xe2, 0x95, 0xac, 0x77, 0x44, 0x3f, 0x14, 0xf6, 0xd1, 0xaf, 0xd6,
- 0x51, 0x5e, 0x2f, 0xf3, 0x1a, 0x95, 0xfe, 0xb2, 0x65, 0x5c, 0x62, 0xbf,
- 0x41, 0x5e, 0x12, 0xa2, 0xcd, 0xc9, 0x98, 0xa5, 0x5d, 0x99, 0x53, 0x19,
- 0x5f, 0x24, 0x36, 0xee, 0x8e, 0x4f, 0x99, 0x7b, 0x40, 0x72, 0xdd, 0x7a,
- 0x0b, 0x7d, 0x6d, 0x12, 0xff, 0x14, 0x62, 0x6f, 0x03, 0xf3, 0x4f, 0x69,
- 0x23, 0x84, 0x6d, 0xf4, 0xed, 0xfd, 0x86, 0xe3, 0x3c, 0x6f, 0xcc, 0xc7,
- 0x01, 0x23, 0x92, 0x12, 0x3b, 0x7c, 0xd3, 0x58, 0x76, 0xa5, 0xe4, 0x96,
- 0xc0, 0x9f, 0x60, 0x8a, 0xb6, 0x51, 0xa5, 0x8b, 0xbf, 0x29, 0x08, 0x47,
- 0xbd, 0x5a, 0x8d, 0xe2, 0xc0, 0xbf, 0x78, 0xe1, 0xc6, 0x85, 0x1c, 0x7b,
- 0xed, 0xf5, 0x0a, 0xde, 0xbf, 0x4a, 0xc1, 0xa1, 0xab, 0xa2, 0xe1, 0x11,
- 0x65, 0x16, 0xb1, 0x35, 0xda, 0xdd, 0xa9, 0x58, 0x47, 0x59, 0x37, 0xd9,
- 0xe6, 0x89, 0x84, 0xa1, 0xd4, 0xd1, 0xef, 0x5b, 0x34, 0x09, 0xfd, 0xde,
- 0x81, 0x68, 0xf8, 0x51, 0xfe, 0xf7, 0x4c, 0x28, 0x98, 0xd0, 0x23, 0x49,
- 0xb8, 0xf2, 0xd9, 0x36, 0xd3, 0xce, 0xab, 0xa3, 0x8e, 0x73, 0x2c, 0xde,
- 0x1a, 0x3c, 0x86, 0x37, 0x89, 0x6d, 0xd2, 0x4e, 0x19, 0xeb, 0xc1, 0x5c,
- 0x56, 0x4f, 0x76, 0x2a, 0x8e, 0x57, 0xf8, 0xc3, 0xfa, 0xbc, 0xc4, 0xc3,
- 0x72, 0x7f, 0xcb, 0x71, 0xd1, 0x71, 0xde, 0x34, 0x8a, 0xb2, 0x82, 0x1d,
- 0x91, 0x14, 0x30, 0x1f, 0x93, 0x7a, 0xa4, 0x6b, 0x8a, 0x3a, 0x08, 0xd3,
- 0xdf, 0xe6, 0xe9, 0x8d, 0x38, 0xee, 0x8b, 0x04, 0x8f, 0x2b, 0xcb, 0xcf,
- 0xaa, 0x58, 0xb4, 0xfe, 0x09, 0xa5, 0x75, 0x43, 0x15, 0xf4, 0x64, 0x41,
- 0x99, 0x2b, 0x3a, 0x09, 0x07, 0xc8, 0xa5, 0xd6, 0xc1, 0x8d, 0xd1, 0xb8,
- 0xcd, 0xf6, 0x26, 0xa7, 0xd1, 0x4c, 0xdb, 0xd7, 0x7b, 0xee, 0x23, 0x0f,
- 0x04, 0x3e, 0xce, 0x24, 0x41, 0xfa, 0xda, 0x88, 0xd4, 0xa7, 0x1c, 0xe7,
- 0x7e, 0xf6, 0x75, 0x07, 0xfb, 0xfa, 0x60, 0xfc, 0x3d, 0xe7, 0x5f, 0x5d,
- 0x99, 0x37, 0x62, 0x44, 0xbf, 0x54, 0xee, 0xbb, 0xcc, 0xf5, 0x45, 0xae,
- 0x0f, 0x37, 0xcf, 0x61, 0xbe, 0xd2, 0x21, 0xb8, 0x71, 0xd2, 0x4b, 0xdc,
- 0xa0, 0x3c, 0xc6, 0x10, 0xf5, 0xd2, 0x38, 0xec, 0x01, 0xe3, 0x5b, 0x38,
- 0xa5, 0xa8, 0x24, 0x42, 0x41, 0xf8, 0x75, 0x07, 0x0f, 0x90, 0x33, 0x24,
- 0xe7, 0xd4, 0xe1, 0x73, 0x86, 0x1f, 0xb3, 0xa2, 0xea, 0x65, 0x1e, 0xce,
- 0xc9, 0x81, 0xb8, 0x7c, 0xf7, 0x61, 0x6a, 0x8e, 0x07, 0x9b, 0xc9, 0x25,
- 0x82, 0x51, 0x75, 0x9e, 0xdc, 0xf7, 0xb7, 0xcb, 0x77, 0xf6, 0x7f, 0xae,
- 0x82, 0xfb, 0x69, 0x15, 0x6a, 0xb4, 0x37, 0x2c, 0xf7, 0xbb, 0x0c, 0xf9,
- 0xae, 0xa0, 0x39, 0xee, 0xe5, 0xbc, 0x38, 0xf0, 0x48, 0x7a, 0x1f, 0xe5,
- 0xfd, 0xb8, 0x7c, 0x4e, 0xde, 0xcf, 0x71, 0x27, 0xf7, 0x29, 0x82, 0x33,
- 0x3f, 0x72, 0x5e, 0x64, 0x1c, 0x09, 0xf2, 0xf9, 0xe7, 0xd8, 0xf6, 0xd1,
- 0xf8, 0xf3, 0xce, 0x3c, 0xe2, 0xeb, 0xb1, 0x84, 0x86, 0xf9, 0x57, 0x35,
- 0xe1, 0xf8, 0x9d, 0x32, 0x66, 0x05, 0xb3, 0xf4, 0x2f, 0xf8, 0x24, 0xcf,
- 0xac, 0xd5, 0xe7, 0xe2, 0xe6, 0x3b, 0x8a, 0xf7, 0xaa, 0xa2, 0xb2, 0x4e,
- 0xa8, 0xa1, 0xea, 0xaa, 0x06, 0x68, 0xa5, 0x7b, 0xcb, 0xa3, 0xde, 0xee,
- 0x59, 0x8a, 0x1e, 0xbc, 0x4d, 0x91, 0xe7, 0xbf, 0x24, 0xb7, 0x75, 0x9c,
- 0x07, 0x38, 0x5f, 0x2d, 0xf1, 0x00, 0x4e, 0xb3, 0x9d, 0x5e, 0xea, 0x6f,
- 0xe5, 0xf9, 0xf9, 0x2a, 0xd7, 0xff, 0xb9, 0xa3, 0x7d, 0x4a, 0xea, 0x8a,
- 0x8c, 0x85, 0x5d, 0x37, 0x2b, 0x1c, 0x50, 0xb5, 0xe8, 0xd9, 0xd5, 0x19,
- 0xcb, 0xf6, 0xba, 0xdf, 0x83, 0x1d, 0xaf, 0x9d, 0x5f, 0xf3, 0x3a, 0xe3,
- 0xc6, 0xa3, 0x65, 0xd7, 0x07, 0x71, 0xdc, 0xa9, 0x6f, 0xb7, 0x82, 0x95,
- 0x90, 0xb8, 0xd4, 0x1c, 0xfb, 0x0a, 0xe5, 0xfe, 0xc0, 0x28, 0xc6, 0xac,
- 0xfd, 0x46, 0x24, 0x6b, 0xd1, 0x1f, 0x52, 0xcc, 0x13, 0x3b, 0x25, 0x76,
- 0x4f, 0xd6, 0xfa, 0x50, 0x3b, 0x1f, 0x95, 0xed, 0x91, 0xfe, 0x05, 0xcc,
- 0x9b, 0x3c, 0x1d, 0x12, 0xeb, 0x64, 0x7e, 0xdc, 0x32, 0x6c, 0xab, 0x0a,
- 0xcb, 0xd9, 0xc7, 0x78, 0xfb, 0xef, 0x8b, 0x13, 0x22, 0x47, 0xac, 0x33,
- 0xd2, 0x9f, 0xc4, 0xef, 0x2b, 0x0b, 0x46, 0x65, 0x59, 0x4f, 0xf2, 0xdf,
- 0x90, 0xca, 0xab, 0xe4, 0x19, 0x15, 0xc1, 0xde, 0x8e, 0x46, 0x5e, 0xf2,
- 0xdc, 0x7b, 0xc3, 0xda, 0xfc, 0xf9, 0x75, 0x3c, 0x64, 0x8d, 0x0a, 0xa8,
- 0x57, 0x0b, 0x66, 0x13, 0x7d, 0x83, 0x32, 0x3e, 0x8b, 0x56, 0x2e, 0x39,
- 0x7a, 0xe7, 0x5d, 0x77, 0xd3, 0x9f, 0x9f, 0x63, 0x8b, 0xa3, 0xe4, 0x33,
- 0x96, 0xeb, 0x19, 0xe2, 0xeb, 0x33, 0xd7, 0xf5, 0x24, 0x86, 0x94, 0xd7,
- 0x06, 0x1b, 0x30, 0xb8, 0xfb, 0x0e, 0x68, 0x8d, 0x45, 0x1c, 0x52, 0xcd,
- 0xc5, 0x58, 0x96, 0x7d, 0xdb, 0x57, 0xe4, 0xe0, 0xb5, 0x18, 0xd8, 0x1d,
- 0x47, 0x6e, 0x8e, 0x3c, 0x93, 0x7b, 0x7e, 0x08, 0x4e, 0x6e, 0xdf, 0x7d,
- 0x99, 0xe4, 0xd4, 0x61, 0x91, 0x9b, 0xa2, 0xef, 0xa8, 0xfa, 0xdb, 0x8e,
- 0x15, 0x14, 0xf9, 0x87, 0xae, 0xf4, 0x52, 0x87, 0x37, 0xa1, 0xb5, 0x67,
- 0x0c, 0xa7, 0xc8, 0xeb, 0xdc, 0x35, 0x54, 0xad, 0xd2, 0x9c, 0xba, 0xdf,
- 0x87, 0x68, 0x6a, 0x9c, 0x38, 0x10, 0x98, 0xf0, 0x93, 0x9f, 0xcc, 0x77,
- 0xd7, 0x8e, 0x96, 0x91, 0x7f, 0xa4, 0xc8, 0x6d, 0x3f, 0xee, 0xf5, 0xe2,
- 0x6e, 0x62, 0xc6, 0x7e, 0xbd, 0x75, 0xc3, 0x18, 0x7e, 0x45, 0xac, 0x93,
- 0xf2, 0x3f, 0x60, 0x7b, 0x22, 0xd3, 0xcb, 0xf6, 0xe0, 0xf7, 0x12, 0x8f,
- 0xc9, 0x09, 0xbd, 0x3e, 0x3d, 0xed, 0x93, 0xf8, 0x2d, 0xdc, 0x75, 0xc7,
- 0x6e, 0x05, 0x9d, 0x94, 0xf3, 0x28, 0x6d, 0xe6, 0xfe, 0x28, 0xbc, 0x5d,
- 0x57, 0x91, 0xa3, 0x90, 0xf3, 0x61, 0x4e, 0x00, 0x8f, 0x8c, 0x23, 0x91,
- 0xd7, 0xa7, 0xe6, 0x05, 0xf0, 0x26, 0xe5, 0x08, 0xae, 0x57, 0x94, 0xe4,
- 0xf4, 0xac, 0xb9, 0x58, 0x4e, 0x2d, 0x1e, 0x2f, 0xc9, 0xd9, 0x43, 0x39,
- 0xd7, 0xb4, 0xc0, 0x5b, 0x7b, 0x8d, 0xcc, 0x55, 0x1b, 0xfd, 0xa7, 0x16,
- 0x19, 0x17, 0xdb, 0xc9, 0xe9, 0x3e, 0x06, 0x45, 0x5f, 0x28, 0xfc, 0xff,
- 0x1b, 0x6e, 0xbd, 0x9b, 0xda, 0xa6, 0xa6, 0xeb, 0x09, 0x9e, 0x67, 0x5a,
- 0xa6, 0xe8, 0xa8, 0x65, 0xdd, 0x34, 0x62, 0xeb, 0xee, 0xea, 0x72, 0x7f,
- 0xd9, 0x4e, 0xb9, 0x8d, 0x06, 0xde, 0x0b, 0xe1, 0x11, 0xe6, 0x71, 0x37,
- 0xb1, 0x9d, 0x03, 0x86, 0x70, 0xb1, 0x56, 0xa3, 0x4a, 0x91, 0xbc, 0x36,
- 0xcc, 0xb8, 0xde, 0x80, 0x3e, 0x37, 0x16, 0x84, 0x59, 0x7f, 0x77, 0x5d,
- 0x91, 0x4f, 0xc0, 0x77, 0x2b, 0xcb, 0x76, 0xc6, 0x8b, 0xed, 0xf9, 0x74,
- 0xc9, 0x15, 0xdb, 0xb1, 0x7f, 0xf8, 0xfc, 0xf3, 0xc8, 0x4d, 0xfa, 0xcc,
- 0xf9, 0x9a, 0x8a, 0x10, 0x4b, 0x2b, 0x50, 0x5d, 0x21, 0x58, 0x7f, 0xd1,
- 0xd8, 0xb7, 0x8c, 0xff, 0x29, 0xef, 0x57, 0x63, 0xeb, 0xb8, 0x83, 0x2d,
- 0x6e, 0x9e, 0x50, 0x81, 0xde, 0x36, 0xc1, 0x43, 0xb1, 0xa5, 0x39, 0x92,
- 0x27, 0x25, 0x72, 0x90, 0x18, 0x27, 0xf6, 0xb3, 0xc6, 0xb5, 0x1f, 0x8f,
- 0x32, 0xd3, 0x7e, 0x36, 0xe3, 0xbb, 0xfa, 0xa1, 0x3b, 0x2a, 0x71, 0xe8,
- 0x2e, 0x59, 0xff, 0xde, 0x10, 0xc7, 0xe1, 0x5b, 0xe8, 0x9b, 0xaf, 0x13,
- 0x5b, 0xb6, 0xb4, 0x30, 0x86, 0xb8, 0x98, 0xa5, 0xa0, 0x92, 0xb1, 0x7d,
- 0xdb, 0x6e, 0xe6, 0xc0, 0x6a, 0x90, 0x6d, 0x5e, 0x8a, 0x5d, 0xd2, 0x7f,
- 0x83, 0xb9, 0xee, 0xa1, 0x2f, 0x56, 0x22, 0x20, 0x39, 0xc7, 0x4f, 0x4e,
- 0x51, 0xc6, 0x4d, 0x46, 0x59, 0x57, 0xa2, 0xa7, 0xb2, 0x9c, 0x06, 0xa4,
- 0x77, 0x97, 0xeb, 0x2b, 0x78, 0x29, 0x1a, 0x2e, 0xad, 0x3f, 0x37, 0x60,
- 0x60, 0xfc, 0xd0, 0x31, 0x72, 0x0d, 0x27, 0xd1, 0x72, 0x68, 0x63, 0x98,
- 0x7d, 0x39, 0x13, 0x2f, 0xcf, 0xa9, 0xf8, 0xe6, 0x4c, 0x19, 0x62, 0xbb,
- 0x50, 0x6a, 0x17, 0x62, 0x4b, 0x2d, 0x6d, 0x34, 0x1f, 0x45, 0xaa, 0xc6,
- 0xac, 0x85, 0x3d, 0x4e, 0xdf, 0x9a, 0xa8, 0x80, 0xf7, 0x5a, 0x89, 0x7d,
- 0xc2, 0x77, 0xbc, 0x37, 0x9c, 0xb0, 0x2b, 0xf0, 0x69, 0xe3, 0x9c, 0x23,
- 0xb8, 0x78, 0x4c, 0xc7, 0xe5, 0x15, 0xc4, 0xc4, 0x85, 0xf1, 0x68, 0x72,
- 0x1d, 0xf3, 0xc2, 0x23, 0x6d, 0xde, 0x1b, 0xde, 0xca, 0xff, 0x9a, 0xdc,
- 0xf2, 0xd2, 0xf1, 0x88, 0x3e, 0x70, 0x74, 0x45, 0x54, 0xda, 0x94, 0xf6,
- 0xca, 0x36, 0x2a, 0xed, 0x3b, 0x4e, 0x34, 0x1e, 0x70, 0xe7, 0xbc, 0x3c,
- 0x86, 0x37, 0xf4, 0xf2, 0x18, 0x02, 0x8c, 0xa7, 0x49, 0x72, 0x57, 0xe1,
- 0xd5, 0x7e, 0xe6, 0x91, 0x5e, 0xf2, 0xf1, 0x6e, 0x08, 0xdf, 0x3b, 0x4a,
- 0x7e, 0xf2, 0xa4, 0x0d, 0xbc, 0x93, 0x75, 0xb0, 0x2c, 0x3e, 0x8b, 0xf8,
- 0xd2, 0x4f, 0xd9, 0xb2, 0xa6, 0x76, 0x50, 0x19, 0x67, 0xae, 0x79, 0xdc,
- 0x5b, 0x95, 0x54, 0x99, 0x5b, 0x1e, 0xc8, 0x47, 0xc3, 0x87, 0x98, 0x67,
- 0xfa, 0x99, 0xeb, 0x72, 0x06, 0x94, 0x27, 0x99, 0x67, 0xee, 0x2b, 0xe5,
- 0x99, 0x07, 0xf2, 0x01, 0xe4, 0xb3, 0xc4, 0xc6, 0x38, 0xf3, 0x5b, 0x37,
- 0x4f, 0x0f, 0x60, 0x32, 0xab, 0x32, 0x1f, 0x7f, 0xdf, 0x99, 0xaa, 0x77,
- 0xf7, 0x0b, 0xf0, 0x75, 0xbb, 0x01, 0x07, 0x87, 0x9b, 0x70, 0x36, 0x3f,
- 0x45, 0xbb, 0xb8, 0x0c, 0xd3, 0xa3, 0xb5, 0x98, 0x18, 0x7e, 0x95, 0x9f,
- 0xdb, 0xf0, 0xfe, 0xa8, 0x9b, 0xe3, 0x12, 0x0f, 0xa5, 0x7f, 0x07, 0x95,
- 0x43, 0x6e, 0x8e, 0x6b, 0x25, 0x99, 0xdb, 0x26, 0xfa, 0x4b, 0xb9, 0xed,
- 0x14, 0x73, 0xdb, 0x23, 0x6c, 0xf3, 0x85, 0x52, 0x9b, 0xcf, 0xb9, 0xff,
- 0xa5, 0x2f, 0x52, 0x77, 0x66, 0xbd, 0x44, 0x52, 0xd6, 0xa6, 0xc7, 0xed,
- 0x68, 0xac, 0x5c, 0xf7, 0x05, 0xd6, 0x3b, 0x72, 0xbe, 0xde, 0x6a, 0x0c,
- 0x64, 0xd6, 0x90, 0xe7, 0xcb, 0xda, 0xca, 0x7b, 0x6b, 0x6c, 0xea, 0xf2,
- 0xcb, 0xd1, 0xa9, 0xee, 0x59, 0xa8, 0xc3, 0xfa, 0xb8, 0x70, 0xa2, 0xb7,
- 0xc8, 0x89, 0x22, 0x89, 0x95, 0x8c, 0x0f, 0x9e, 0x68, 0x84, 0x58, 0x0f,
- 0x44, 0x27, 0x98, 0x03, 0xe4, 0xeb, 0x70, 0x37, 0x73, 0x31, 0xb5, 0x7e,
- 0x75, 0x69, 0x0f, 0xab, 0x94, 0xe3, 0x78, 0xd6, 0xa0, 0x6f, 0x52, 0xe4,
- 0xad, 0x26, 0xbf, 0xae, 0xc1, 0x2d, 0xc5, 0x75, 0x0b, 0xbf, 0x9f, 0xb2,
- 0xfd, 0xd1, 0xa9, 0x18, 0x5d, 0xc6, 0x38, 0xc0, 0x1b, 0xcf, 0xd9, 0x0a,
- 0x96, 0xe9, 0x3e, 0xac, 0x0b, 0xd6, 0x61, 0x99, 0xf1, 0xef, 0xce, 0x2d,
- 0xab, 0xe5, 0xd9, 0x79, 0x1e, 0xe1, 0xaf, 0x64, 0xbb, 0x6f, 0x92, 0x53,
- 0x8f, 0xf3, 0xcb, 0x54, 0xbe, 0x78, 0xdf, 0xca, 0x53, 0x36, 0xe5, 0x6e,
- 0xa3, 0xdc, 0x7b, 0x83, 0x6e, 0xbe, 0x5b, 0x2a, 0x37, 0x15, 0xf3, 0x10,
- 0xd7, 0xa5, 0x6c, 0x27, 0xe5, 0xde, 0x4d, 0xb9, 0xfd, 0x41, 0xe9, 0xdf,
- 0xbf, 0x3b, 0xf7, 0xae, 0x96, 0x67, 0xe5, 0x7d, 0x13, 0x29, 0xff, 0x9e,
- 0xc8, 0x35, 0xc6, 0x4b, 0x6d, 0x1d, 0xb2, 0x91, 0x95, 0xdc, 0x6f, 0x6d,
- 0x47, 0x54, 0xeb, 0x75, 0xd7, 0xb2, 0x35, 0xac, 0xcb, 0x6b, 0xb8, 0x87,
- 0xba, 0xcb, 0x79, 0xcb, 0x63, 0x72, 0xfb, 0x64, 0x09, 0x77, 0x5e, 0xce,
- 0x72, 0x7d, 0x25, 0xdc, 0xee, 0xcc, 0x8b, 0x0d, 0xcd, 0xdc, 0x4f, 0x6a,
- 0x2a, 0xf9, 0xb3, 0x17, 0x4f, 0xdb, 0x1f, 0x9c, 0x1b, 0xcc, 0x48, 0x3c,
- 0x93, 0xf5, 0x10, 0x0d, 0xd9, 0xfc, 0xe5, 0x68, 0x1e, 0x0a, 0x62, 0xad,
- 0x31, 0x9b, 0xbe, 0xfe, 0xa5, 0xf3, 0x36, 0x75, 0x80, 0xed, 0xc0, 0xe7,
- 0x8a, 0x57, 0x9e, 0xce, 0xb7, 0x06, 0x1b, 0x70, 0xe9, 0x1e, 0xd2, 0xfc,
- 0x64, 0x8d, 0x19, 0xed, 0xfe, 0x0e, 0xe7, 0xae, 0xca, 0xe5, 0xd0, 0x5b,
- 0x94, 0x1c, 0xe7, 0xef, 0xa9, 0xd2, 0xfc, 0x3d, 0x99, 0xbf, 0xae, 0xb2,
- 0x88, 0x45, 0x97, 0xa3, 0x65, 0x48, 0xfe, 0x07, 0xf1, 0x46, 0xc7, 0xc7,
- 0x79, 0xef, 0x72, 0x2c, 0x1c, 0xf9, 0x54, 0x25, 0xb9, 0xb5, 0x51, 0xcc,
- 0xc1, 0x2f, 0xcd, 0x33, 0x22, 0xfd, 0x16, 0x16, 0xb0, 0x5c, 0x13, 0x75,
- 0x26, 0x18, 0x28, 0xfd, 0x7a, 0xe4, 0x7c, 0xbf, 0xbe, 0xcc, 0x7e, 0xa5,
- 0x7c, 0xb2, 0xd6, 0x2a, 0xfd, 0x52, 0x92, 0xb5, 0x66, 0x13, 0xde, 0x1f,
- 0x40, 0x30, 0x68, 0x46, 0x53, 0x2f, 0xd3, 0xde, 0x27, 0xd8, 0xd7, 0x7a,
- 0xf4, 0x2b, 0x79, 0x77, 0xaf, 0xea, 0x20, 0xcb, 0xcc, 0x8c, 0xa3, 0xd2,
- 0x4f, 0xaf, 0xe4, 0x59, 0x3e, 0xd9, 0x67, 0xf2, 0xe9, 0x22, 0xff, 0x6d,
- 0x72, 0xc5, 0x3e, 0xca, 0x4f, 0x72, 0xfe, 0xfc, 0x6c, 0x03, 0x56, 0xb5,
- 0xd9, 0xed, 0x72, 0x55, 0x2f, 0xfd, 0x6e, 0x19, 0x6d, 0xea, 0xc9, 0x9c,
- 0x82, 0x51, 0x2a, 0xfd, 0x68, 0x56, 0xd6, 0x89, 0xc3, 0x38, 0x90, 0xf3,
- 0xe1, 0x85, 0xec, 0x3c, 0x8c, 0xe7, 0x2a, 0xf0, 0x5c, 0xf6, 0x32, 0xec,
- 0xcb, 0x11, 0xfd, 0xb2, 0x97, 0x63, 0x24, 0xe7, 0xc7, 0x4f, 0xb2, 0xd4,
- 0x53, 0xae, 0x0a, 0xff, 0x9c, 0xfd, 0x13, 0x7c, 0x3d, 0x57, 0x8d, 0xd7,
- 0xb2, 0x57, 0xe0, 0x60, 0xae, 0x06, 0xaf, 0x64, 0xc9, 0x27, 0x73, 0x01,
- 0xbc, 0x9c, 0xd5, 0x50, 0xc8, 0xcd, 0xc2, 0x4b, 0xd9, 0x08, 0x26, 0x72,
- 0xb5, 0xf8, 0x6e, 0x76, 0x01, 0xf2, 0xb9, 0x3a, 0x7c, 0x27, 0xdb, 0x8c,
- 0x2f, 0xe7, 0x82, 0x78, 0x31, 0xab, 0xe3, 0xa9, 0x5c, 0x3d, 0x8e, 0x65,
- 0xa3, 0x6c, 0x37, 0x84, 0xa3, 0xc3, 0x31, 0x1c, 0x18, 0x6d, 0xc4, 0x0b,
- 0xc3, 0x8b, 0x30, 0x3e, 0x1a, 0xc6, 0x73, 0xc3, 0x6d, 0xd8, 0x37, 0xfa,
- 0x6f, 0x15, 0xa2, 0x9f, 0x23, 0xf6, 0xff, 0x38, 0xaf, 0xc7, 0x6d, 0x1f,
- 0x31, 0xdf, 0xaf, 0xda, 0xa2, 0x37, 0xbf, 0x55, 0xcf, 0x39, 0x7a, 0x3a,
- 0xef, 0xce, 0x3b, 0xf4, 0x21, 0x77, 0x7f, 0x06, 0x7d, 0xc6, 0x65, 0xcc,
- 0xd9, 0xfa, 0x25, 0x7e, 0xd0, 0x16, 0x0e, 0x2a, 0xdb, 0x5d, 0x1c, 0xa9,
- 0x4d, 0xce, 0xa2, 0x2e, 0x39, 0xec, 0x60, 0x0d, 0x7d, 0x32, 0x4b, 0x7f,
- 0xb6, 0x38, 0xaf, 0x76, 0xfe, 0xa0, 0xb2, 0x83, 0x39, 0xe2, 0x95, 0x43,
- 0x96, 0x53, 0xed, 0xe2, 0x69, 0x34, 0xb9, 0x88, 0x3e, 0x17, 0x1b, 0x11,
- 0x7d, 0xde, 0x59, 0x21, 0xfa, 0xac, 0xd0, 0x3f, 0xcc, 0x4e, 0xca, 0x7a,
- 0x0f, 0x94, 0xec, 0xe1, 0xfb, 0x95, 0xc5, 0xbc, 0xaa, 0x3c, 0xef, 0x8e,
- 0x33, 0x68, 0x94, 0xe7, 0x9e, 0xfc, 0xaf, 0x41, 0xd6, 0xa4, 0xc0, 0x58,
- 0x50, 0x8f, 0x5c, 0x48, 0xf2, 0xf5, 0x99, 0x98, 0x81, 0x64, 0xa5, 0x19,
- 0xd5, 0x5a, 0xd4, 0x99, 0x7c, 0x45, 0xb0, 0x43, 0xe4, 0x5b, 0x2e, 0xee,
- 0x1c, 0x3e, 0x8f, 0x1f, 0x67, 0x2b, 0x85, 0xa7, 0xec, 0xb7, 0xa5, 0x6f,
- 0x50, 0x2b, 0xa4, 0xcf, 0x28, 0xde, 0x43, 0xa1, 0xac, 0xaf, 0x99, 0x76,
- 0xa7, 0x52, 0xb7, 0x62, 0x7b, 0x5e, 0xfa, 0xc2, 0x72, 0x89, 0x7b, 0xec,
- 0x47, 0x13, 0x5e, 0xb0, 0x8b, 0x7b, 0x33, 0xe3, 0x79, 0xd1, 0xb7, 0x86,
- 0xad, 0xe4, 0x5e, 0x87, 0x87, 0x15, 0xea, 0xee, 0x2f, 0x51, 0xdc, 0x3f,
- 0xf2, 0xd2, 0x57, 0xd7, 0xb2, 0x3c, 0x63, 0x7c, 0x61, 0xda, 0xdd, 0x1b,
- 0xae, 0x73, 0xf3, 0xee, 0x30, 0x0a, 0x03, 0x1f, 0x9c, 0xdb, 0x96, 0xf9,
- 0xe5, 0xb9, 0x3d, 0x99, 0x68, 0x4a, 0xf6, 0x67, 0xf2, 0x13, 0x3e, 0xe4,
- 0xf6, 0x06, 0xf0, 0xd4, 0x84, 0x1f, 0x35, 0x69, 0xc9, 0xf3, 0x83, 0x78,
- 0x6a, 0xff, 0xa1, 0x15, 0x35, 0x68, 0xe0, 0xff, 0x10, 0xaf, 0x46, 0x5e,
- 0x01, 0x1c, 0x1b, 0xf5, 0xe3, 0x2d, 0x5b, 0x7c, 0x58, 0xfc, 0xa3, 0x8d,
- 0xd8, 0x1f, 0x60, 0xbc, 0x55, 0x19, 0x47, 0x9a, 0x70, 0x38, 0x1f, 0xc4,
- 0xf2, 0x6c, 0x3d, 0x9e, 0xcb, 0x25, 0xf1, 0x44, 0xa6, 0x1e, 0x67, 0x1f,
- 0xf3, 0x63, 0xde, 0x3e, 0xf1, 0x87, 0x06, 0x9c, 0x1e, 0xfc, 0x04, 0x0a,
- 0x7b, 0x93, 0xb0, 0x33, 0xb3, 0xb1, 0x63, 0xb0, 0x01, 0xdf, 0x61, 0x99,
- 0x7e, 0xea, 0xa9, 0x7a, 0xa7, 0x89, 0x17, 0x69, 0x43, 0x55, 0x3b, 0x6f,
- 0xa4, 0xec, 0x30, 0x7c, 0x03, 0x21, 0x1c, 0xc9, 0x7b, 0x85, 0xd7, 0x71,
- 0x1e, 0x7f, 0x5a, 0x9c, 0x17, 0x08, 0x6f, 0xbd, 0x98, 0x07, 0x1e, 0x3f,
- 0xcf, 0x03, 0x81, 0x5c, 0x5e, 0xd6, 0x18, 0xdb, 0x3a, 0xfb, 0xec, 0x89,
- 0xff, 0xcf, 0x6f, 0xfe, 0xf4, 0xdb, 0x15, 0x4b, 0x0c, 0x62, 0x9d, 0x8c,
- 0x7f, 0xed, 0x83, 0xd5, 0xe6, 0x86, 0x2f, 0xae, 0x58, 0x52, 0x89, 0xfb,
- 0xdd, 0xf9, 0xea, 0x81, 0xbd, 0xbb, 0x9b, 0xf1, 0xb5, 0xb5, 0x67, 0x40,
- 0xb9, 0x02, 0xa9, 0xfa, 0x21, 0xde, 0x53, 0x4b, 0x3e, 0x07, 0x55, 0x6c,
- 0xad, 0x8e, 0xfa, 0x54, 0x0b, 0x1a, 0x4e, 0xd0, 0xc8, 0x6a, 0xd3, 0x11,
- 0x4c, 0xd5, 0xcb, 0x38, 0x63, 0xcc, 0xb3, 0x3c, 0xb2, 0x77, 0x8d, 0x4f,
- 0x33, 0xc6, 0x9d, 0x5d, 0xac, 0x20, 0xf1, 0x67, 0xe2, 0x83, 0xb7, 0x96,
- 0xf6, 0x80, 0x65, 0x3f, 0x4c, 0xe6, 0xad, 0xac, 0xff, 0xbd, 0xb2, 0xee,
- 0xc9, 0x3f, 0xc1, 0x0a, 0x2f, 0x0e, 0xdb, 0x39, 0xe6, 0x08, 0x32, 0x07,
- 0x32, 0xa6, 0xed, 0xac, 0x27, 0xe3, 0x92, 0xe7, 0xad, 0x89, 0xfa, 0x8f,
- 0x1c, 0x97, 0x8c, 0x67, 0xad, 0x1f, 0xd5, 0x32, 0x86, 0xb2, 0x2e, 0xfa,
- 0x58, 0xf7, 0x51, 0xde, 0x93, 0x7a, 0x8e, 0xb3, 0xfd, 0xa2, 0x98, 0x55,
- 0x91, 0xac, 0x66, 0xdf, 0x9f, 0xb4, 0xa3, 0xc9, 0x77, 0x88, 0x8b, 0xc7,
- 0xa8, 0xc3, 0x51, 0x5b, 0xec, 0x6f, 0x0b, 0xed, 0xae, 0x5f, 0x39, 0x7a,
- 0xde, 0xf6, 0x80, 0x83, 0xb6, 0xcc, 0xaf, 0xf0, 0x29, 0x19, 0xaf, 0x86,
- 0xe9, 0x89, 0xa0, 0xcb, 0xc7, 0xdf, 0xb6, 0xc5, 0x26, 0x62, 0xcc, 0xcf,
- 0xa6, 0xcf, 0xf5, 0x66, 0x0c, 0x1c, 0xe3, 0xdc, 0x9e, 0xb6, 0xab, 0x88,
- 0x37, 0x1d, 0x90, 0xbd, 0xce, 0xf7, 0xed, 0x04, 0x5e, 0x22, 0x66, 0xbd,
- 0x47, 0x5b, 0xfb, 0x2e, 0x31, 0xec, 0x5d, 0x5b, 0xc7, 0x77, 0x68, 0x7b,
- 0xef, 0xd8, 0x31, 0xbc, 0x98, 0xaf, 0xc7, 0x51, 0xe2, 0xd0, 0x49, 0x7e,
- 0x5e, 0x9e, 0xf7, 0xc1, 0x0a, 0xc9, 0xbe, 0xda, 0x1e, 0x3f, 0x6a, 0x7b,
- 0xd9, 0xe7, 0x48, 0x97, 0x1c, 0x44, 0x79, 0x96, 0xe3, 0xd3, 0x94, 0x32,
- 0x0f, 0x29, 0xe7, 0x04, 0x49, 0x64, 0x33, 0x33, 0xb1, 0x21, 0xd2, 0x9f,
- 0xa3, 0xdd, 0xfa, 0xd2, 0xe5, 0x38, 0xc0, 0xd8, 0x59, 0x10, 0xdb, 0xf6,
- 0xc0, 0x33, 0x24, 0xf6, 0x7f, 0x0d, 0x75, 0x3d, 0x7d, 0x4e, 0xf6, 0xd2,
- 0x54, 0x7d, 0x8a, 0xfe, 0x5e, 0x85, 0xde, 0xdc, 0xe5, 0xa8, 0x19, 0x5a,
- 0x8a, 0xfb, 0xe3, 0xe2, 0xf7, 0x7e, 0xf4, 0xe7, 0x3c, 0xa8, 0x1c, 0x22,
- 0x77, 0x61, 0xd9, 0xa9, 0x50, 0x31, 0x1e, 0xa9, 0x69, 0xc3, 0xf5, 0x83,
- 0x05, 0x85, 0x0f, 0xce, 0xd9, 0x99, 0x43, 0xf3, 0x54, 0x4c, 0x9f, 0x4b,
- 0x67, 0x02, 0xe8, 0xa3, 0x4d, 0xab, 0x69, 0x05, 0x75, 0x7a, 0x88, 0xf9,
- 0x5f, 0x1b, 0x7a, 0xa9, 0x8b, 0xf9, 0xe9, 0x26, 0x3c, 0x31, 0xd1, 0x88,
- 0x79, 0xbb, 0x4c, 0x3c, 0x4e, 0xdb, 0x0f, 0xef, 0xba, 0x11, 0x7b, 0x58,
- 0xee, 0x15, 0x3e, 0x7b, 0x65, 0x7f, 0x03, 0xaf, 0x10, 0xaf, 0x46, 0x5e,
- 0xf5, 0x18, 0xd8, 0xab, 0x97, 0xce, 0x61, 0x78, 0xd0, 0x30, 0x24, 0xf8,
- 0xa2, 0xe2, 0x8e, 0x76, 0x05, 0xc6, 0xd5, 0x6c, 0x73, 0xe1, 0x87, 0x61,
- 0x4d, 0xc3, 0x1f, 0xd0, 0xef, 0x1f, 0x38, 0x53, 0xe7, 0xed, 0xc7, 0x0f,
- 0x6f, 0xfa, 0xfb, 0xae, 0xfd, 0x2c, 0x28, 0x48, 0x3b, 0xef, 0x12, 0x33,
- 0xc4, 0x86, 0x7e, 0x17, 0x9e, 0x95, 0xf5, 0xfe, 0xdb, 0x67, 0x2b, 0x70,
- 0xde, 0xbe, 0x2e, 0x5a, 0x77, 0x47, 0x9e, 0x36, 0xb1, 0xc3, 0x3d, 0x3b,
- 0x22, 0xb9, 0x4e, 0xa4, 0x2b, 0x47, 0xfd, 0xf4, 0x33, 0x87, 0xb9, 0x87,
- 0x38, 0xb1, 0x3d, 0x13, 0xb1, 0x2c, 0xb6, 0xe5, 0x23, 0x36, 0x3c, 0x30,
- 0xe8, 0x97, 0xf5, 0x6e, 0xcd, 0xa7, 0xcf, 0xc3, 0x3b, 0x39, 0xb1, 0xf9,
- 0x2a, 0x1c, 0xce, 0x86, 0x71, 0xca, 0xfd, 0x5c, 0xcd, 0x58, 0xe3, 0xa0,
- 0xd3, 0x98, 0x85, 0xbe, 0x60, 0x15, 0x06, 0x62, 0x37, 0x22, 0x77, 0x07,
- 0x73, 0x6c, 0xfa, 0x58, 0xad, 0xee, 0x47, 0x3a, 0x28, 0xf9, 0x8b, 0x07,
- 0x99, 0xd8, 0xed, 0x38, 0x5e, 0xef, 0xc5, 0x3c, 0x59, 0x6f, 0xe1, 0xb3,
- 0x3d, 0x41, 0x28, 0xf4, 0xbd, 0xa4, 0x8f, 0xb8, 0x34, 0x6b, 0x00, 0x4e,
- 0xad, 0xa9, 0xcb, 0x1e, 0x4c, 0xcf, 0x56, 0xe2, 0x52, 0xcd, 0x44, 0x0d,
- 0xe3, 0x4e, 0x0b, 0xaa, 0xf7, 0xca, 0x5e, 0x40, 0x00, 0xeb, 0x86, 0xaf,
- 0x95, 0xbd, 0x81, 0x98, 0xa6, 0x04, 0x70, 0xef, 0xb0, 0xc4, 0x8f, 0x35,
- 0xa8, 0xd8, 0x5f, 0x8b, 0x2f, 0x66, 0xbd, 0xc4, 0x78, 0xe2, 0x0d, 0xcb,
- 0xed, 0xc9, 0xd4, 0xa1, 0xee, 0xb1, 0x67, 0x9d, 0x30, 0x75, 0x5c, 0xb7,
- 0x57, 0xb0, 0x88, 0xb6, 0x9b, 0xf9, 0x3c, 0x0a, 0x76, 0x33, 0xe5, 0xf6,
- 0x70, 0x7c, 0x21, 0xbc, 0x4b, 0xec, 0xaa, 0x99, 0x08, 0xe3, 0x9d, 0xdd,
- 0x92, 0xab, 0x24, 0xe1, 0x9d, 0xb8, 0x0c, 0x6f, 0xf2, 0xf3, 0x09, 0xa3,
- 0x13, 0xea, 0x44, 0x13, 0x4e, 0x66, 0xba, 0xe0, 0x99, 0xa8, 0x2d, 0x62,
- 0xd8, 0x5e, 0x3f, 0xea, 0x06, 0xf5, 0xd8, 0x34, 0xe7, 0xc8, 0xb7, 0x97,
- 0x04, 0xa7, 0x51, 0xda, 0x3f, 0x6f, 0xdb, 0xc6, 0x85, 0x7d, 0x87, 0xf2,
- 0xd9, 0x15, 0xb1, 0xef, 0xef, 0x3a, 0x4f, 0x04, 0xd9, 0xbf, 0x8e, 0x08,
- 0xfa, 0x62, 0xc7, 0x64, 0x3f, 0x9f, 0xe3, 0x4b, 0x72, 0xee, 0x9f, 0x77,
- 0xe4, 0x5c, 0x88, 0xcf, 0x94, 0x33, 0x19, 0xcf, 0x39, 0xdb, 0x57, 0xcb,
- 0xfd, 0xdb, 0xab, 0x50, 0xcd, 0xc4, 0xc9, 0x14, 0x99, 0x3b, 0x64, 0x6e,
- 0x19, 0x75, 0x3e, 0x4c, 0xe6, 0x3f, 0x3a, 0x8f, 0x9f, 0x2f, 0x8f, 0xa0,
- 0xcf, 0x5d, 0x13, 0xbf, 0xe0, 0xcb, 0x35, 0x9c, 0xbb, 0xf5, 0x25, 0x5f,
- 0x7e, 0xc7, 0x96, 0xf9, 0x93, 0xf3, 0x4b, 0x01, 0x72, 0x30, 0x03, 0xd5,
- 0x9c, 0xbb, 0xf7, 0x6d, 0x28, 0xb7, 0x76, 0x74, 0x63, 0xd6, 0x44, 0x80,
- 0xbe, 0x1e, 0x59, 0x6f, 0xc1, 0x66, 0x5b, 0x1d, 0xa8, 0x62, 0x9d, 0x93,
- 0xb6, 0x87, 0x7e, 0x9e, 0xe0, 0x98, 0x83, 0x70, 0x5c, 0x5e, 0xbf, 0x1a,
- 0xf3, 0xa9, 0xa7, 0xb3, 0xb6, 0x89, 0x79, 0xd4, 0xd3, 0xb4, 0xed, 0x25,
- 0x4e, 0x34, 0x11, 0x0f, 0x34, 0xd4, 0x12, 0x1b, 0x2b, 0x06, 0x1d, 0x1c,
- 0x32, 0xea, 0xc8, 0xf5, 0xc5, 0x4e, 0x3b, 0x10, 0x1e, 0x30, 0x30, 0x6f,
- 0xa0, 0x79, 0xe3, 0x3c, 0x8f, 0x07, 0xc7, 0x7d, 0xc5, 0xd8, 0x93, 0x9b,
- 0x23, 0xfa, 0x91, 0x31, 0xb9, 0xb9, 0xfc, 0x87, 0x60, 0xc0, 0x6a, 0x80,
- 0xb2, 0x0a, 0xc4, 0x8c, 0xcf, 0xb1, 0xad, 0x37, 0xec, 0x57, 0x71, 0xf3,
- 0x84, 0xe0, 0xcb, 0x0f, 0xb1, 0x92, 0xfd, 0x78, 0x97, 0xb8, 0x76, 0x5f,
- 0xf4, 0x1b, 0x1c, 0x6b, 0x13, 0x6e, 0x99, 0x98, 0x3e, 0xd7, 0xe7, 0x8e,
- 0xb3, 0x9c, 0xff, 0xf9, 0x71, 0x5f, 0xb6, 0x7c, 0x06, 0x2d, 0x49, 0x9f,
- 0x91, 0x38, 0xe1, 0x87, 0xf8, 0x4d, 0xb7, 0xbd, 0x0d, 0xc5, 0x78, 0x2e,
- 0x57, 0x59, 0x8f, 0x3b, 0xbd, 0x92, 0x97, 0x17, 0x7d, 0x43, 0xfa, 0xf3,
- 0xbb, 0xca, 0x14, 0x7d, 0x43, 0xfc, 0xe2, 0xcb, 0xae, 0x7e, 0x85, 0x77,
- 0x69, 0xb8, 0x6d, 0xe2, 0x97, 0xc4, 0xc7, 0x48, 0x32, 0x47, 0xcc, 0x7e,
- 0x9d, 0xfa, 0xdd, 0x4e, 0xfd, 0x32, 0x07, 0x60, 0xbc, 0x4a, 0x50, 0x9f,
- 0x3e, 0x72, 0x15, 0x2f, 0x31, 0xd3, 0xa4, 0x2e, 0x41, 0x0c, 0x64, 0xee,
- 0x1e, 0x2c, 0x8e, 0x37, 0x77, 0x7e, 0xfe, 0xd8, 0x96, 0x92, 0xc0, 0x09,
- 0xfb, 0x87, 0x55, 0x72, 0x26, 0xe8, 0xa4, 0xed, 0x3e, 0x97, 0x35, 0xcd,
- 0x19, 0x65, 0x2e, 0xb4, 0xbd, 0xcf, 0x16, 0xfe, 0x5c, 0x49, 0xbb, 0xd6,
- 0x28, 0xaf, 0xa6, 0x84, 0xa9, 0x52, 0x57, 0xf6, 0x60, 0xa5, 0xfd, 0x6e,
- 0xe1, 0x20, 0x78, 0x83, 0x3e, 0x77, 0xc4, 0xa8, 0xc0, 0xa8, 0x3b, 0x17,
- 0x62, 0x8f, 0xc5, 0x76, 0x2f, 0xd8, 0x4d, 0xba, 0xae, 0x74, 0x1e, 0xab,
- 0xba, 0xc8, 0xc9, 0x2e, 0x6d, 0xa3, 0xe2, 0x3f, 0xb1, 0x8d, 0x44, 0xa9,
- 0x8d, 0x8f, 0x3a, 0xe3, 0x06, 0x3c, 0x65, 0x4b, 0xec, 0x97, 0xfd, 0x0f,
- 0x0d, 0x8b, 0x26, 0x04, 0x5f, 0xe8, 0xbb, 0x03, 0xd3, 0x2e, 0xf7, 0xcf,
- 0x41, 0xf6, 0xb6, 0x42, 0xf0, 0x45, 0x35, 0x9c, 0xd2, 0x63, 0x58, 0x58,
- 0x90, 0xfd, 0xa9, 0x7d, 0x75, 0xc2, 0xe1, 0xce, 0xe8, 0xc2, 0x3b, 0x64,
- 0xbe, 0xca, 0xf7, 0xfc, 0xd8, 0xaf, 0x17, 0xfb, 0x9a, 0x54, 0x8b, 0xdc,
- 0xd1, 0x43, 0xee, 0xd8, 0x6b, 0xf8, 0x69, 0x97, 0xad, 0xc1, 0xd9, 0xbf,
- 0x73, 0x2f, 0xab, 0xdc, 0xdf, 0xdf, 0x57, 0xee, 0xc2, 0x7a, 0x5c, 0xf6,
- 0xa2, 0xfd, 0x21, 0x19, 0xd3, 0x5c, 0xa0, 0x41, 0xe2, 0x55, 0x91, 0xa3,
- 0x6e, 0x3d, 0x9f, 0xff, 0x58, 0xca, 0x60, 0xfe, 0x31, 0xd4, 0xeb, 0x0b,
- 0x50, 0xdf, 0x50, 0xc3, 0xb8, 0x1c, 0xed, 0xa2, 0x7b, 0x4b, 0x2c, 0xb3,
- 0x82, 0xa6, 0xe4, 0xbf, 0xc2, 0x5b, 0xa5, 0xcd, 0x7e, 0xa5, 0xaa, 0x20,
- 0xed, 0x1e, 0x54, 0xfc, 0x85, 0x0f, 0x6b, 0x5b, 0xce, 0xfb, 0x4d, 0x9f,
- 0x1b, 0xca, 0x74, 0xbb, 0x7b, 0x8c, 0xcb, 0x86, 0x1c, 0xdc, 0x69, 0x34,
- 0xe1, 0xee, 0x06, 0x69, 0xa3, 0x98, 0xc3, 0x68, 0xea, 0x34, 0x39, 0xdc,
- 0x6f, 0x1c, 0x55, 0x97, 0xcf, 0x3e, 0x78, 0x1e, 0xd3, 0xa7, 0xd7, 0x42,
- 0xc5, 0xd9, 0xeb, 0x24, 0x9f, 0xf1, 0x91, 0x7f, 0x6d, 0xaa, 0x2e, 0xee,
- 0x2f, 0x8b, 0x1d, 0x4b, 0x3f, 0xfc, 0xf4, 0xb3, 0x0b, 0xfd, 0xd8, 0xf6,
- 0x07, 0xf5, 0xc3, 0x8f, 0x9b, 0x86, 0x92, 0x18, 0x35, 0x4e, 0x38, 0x56,
- 0x68, 0x66, 0xdb, 0x3e, 0xac, 0x1c, 0xfa, 0x8d, 0x33, 0xcb, 0x6d, 0x5b,
- 0x27, 0xa7, 0x52, 0xf1, 0xc0, 0x12, 0x1f, 0x6e, 0x1d, 0x89, 0x62, 0xc5,
- 0x90, 0x8a, 0xd8, 0x12, 0xe9, 0x43, 0x14, 0x5d, 0x23, 0xbb, 0xbd, 0xc5,
- 0xf2, 0xc0, 0x2d, 0x1c, 0xc3, 0x1b, 0x46, 0x0d, 0x7e, 0x40, 0x0c, 0xac,
- 0x75, 0xb9, 0xfd, 0x46, 0x25, 0x23, 0xdc, 0xde, 0xa7, 0x62, 0xb6, 0x8e,
- 0x60, 0x83, 0x99, 0xa4, 0xee, 0x3a, 0x95, 0xc7, 0x72, 0x1b, 0x95, 0xa1,
- 0x7c, 0xb9, 0xef, 0x01, 0x7c, 0xa2, 0x10, 0xc4, 0x27, 0xc6, 0x1a, 0x78,
- 0x85, 0x78, 0x35, 0xf2, 0x7a, 0xf1, 0xfc, 0xb8, 0xca, 0x67, 0x3c, 0x9f,
- 0x65, 0x4e, 0xb1, 0xcd, 0xf5, 0x4b, 0x89, 0x0b, 0x9a, 0x9c, 0xd5, 0xc1,
- 0x5b, 0x59, 0xc9, 0x27, 0xb6, 0xd1, 0x86, 0x65, 0x4d, 0xb8, 0x92, 0x39,
- 0x45, 0x24, 0x36, 0x85, 0xbf, 0xaa, 0x2e, 0xce, 0x7d, 0xd1, 0x86, 0x71,
- 0xde, 0x86, 0x7d, 0x78, 0x3b, 0xab, 0xa2, 0x25, 0xfe, 0x6f, 0xce, 0xf1,
- 0xa0, 0xe0, 0xc9, 0xa5, 0xcf, 0xcb, 0x9c, 0x65, 0xfa, 0x5c, 0x36, 0xd3,
- 0x34, 0x63, 0x5f, 0x56, 0x41, 0xc5, 0x90, 0xf0, 0xf3, 0xeb, 0x5c, 0xbe,
- 0xf7, 0x7d, 0xc3, 0x07, 0xef, 0xd0, 0xa1, 0x2b, 0xe5, 0x68, 0x93, 0x6f,
- 0x8c, 0x71, 0xab, 0x83, 0xf3, 0x32, 0xf2, 0xf1, 0x92, 0xce, 0xca, 0xba,
- 0x50, 0xdc, 0x35, 0x49, 0xd5, 0x8d, 0xe9, 0x41, 0xa8, 0x63, 0xc2, 0x43,
- 0xc9, 0x0d, 0xc6, 0x24, 0x1f, 0x08, 0xf1, 0xbf, 0xe4, 0x06, 0x8d, 0xfc,
- 0xcf, 0xc4, 0xa2, 0x51, 0xe2, 0x78, 0x0f, 0xfa, 0x19, 0x9f, 0x2a, 0xa3,
- 0x3d, 0xd8, 0x3e, 0xfe, 0x61, 0x31, 0xbf, 0x98, 0x63, 0x3d, 0x7b, 0xde,
- 0xcf, 0xdc, 0x39, 0x62, 0x9f, 0xa6, 0xcf, 0x89, 0xcf, 0xc8, 0x5c, 0xed,
- 0xcb, 0x4a, 0x1f, 0x1c, 0x6c, 0x30, 0x6e, 0x64, 0xdb, 0x3e, 0xa8, 0x0d,
- 0x33, 0xb9, 0xe7, 0x79, 0x3e, 0x4d, 0xdd, 0x6d, 0x54, 0x46, 0x39, 0x27,
- 0x96, 0xb7, 0x52, 0xd6, 0x87, 0x82, 0x15, 0x9c, 0x93, 0xaf, 0xe4, 0x45,
- 0x46, 0xa7, 0x32, 0x9e, 0x9b, 0x59, 0x67, 0xa3, 0x32, 0x96, 0xff, 0x55,
- 0xb5, 0xac, 0x99, 0x5f, 0xd0, 0x4d, 0xb9, 0x0f, 0x62, 0x63, 0x1a, 0xea,
- 0xd3, 0xa2, 0x67, 0x19, 0xb3, 0x06, 0x2f, 0x79, 0x5c, 0x7d, 0xe1, 0x43,
- 0xdb, 0x6c, 0xac, 0x72, 0xcf, 0x62, 0xc6, 0x18, 0x8b, 0x02, 0x56, 0x25,
- 0x39, 0x1f, 0x6d, 0x34, 0xe5, 0x33, 0xbb, 0x3a, 0xf7, 0xd9, 0x0b, 0x83,
- 0x87, 0x4b, 0x6b, 0x11, 0x6b, 0x21, 0xbc, 0x54, 0x71, 0x71, 0xd6, 0xa3,
- 0x47, 0xb1, 0x9c, 0xb9, 0xee, 0x4d, 0xb9, 0x62, 0x7f, 0xc7, 0xd8, 0xdf,
- 0x29, 0xd7, 0xf7, 0x92, 0xca, 0x68, 0x5e, 0x75, 0xfb, 0xed, 0x35, 0xa5,
- 0xbf, 0x52, 0x97, 0xe3, 0xc9, 0xbf, 0x56, 0xca, 0xa9, 0x92, 0x18, 0xcc,
- 0xcc, 0xf4, 0x61, 0xe9, 0x73, 0x2d, 0xda, 0x86, 0x3e, 0xa0, 0x9f, 0xc9,
- 0xbc, 0x0a, 0xfe, 0xcc, 0xc3, 0xca, 0x91, 0x59, 0x68, 0x1d, 0x0a, 0xe3,
- 0xb6, 0x91, 0x06, 0x2c, 0xda, 0xb5, 0x06, 0xd5, 0x63, 0x41, 0x5c, 0xb9,
- 0x4b, 0xd6, 0xf8, 0x57, 0xa3, 0xb2, 0x70, 0x5b, 0x8d, 0xe4, 0xb8, 0x7a,
- 0x3a, 0xc1, 0xf9, 0x4b, 0xa0, 0x22, 0x1d, 0x49, 0x24, 0x21, 0x6b, 0xa4,
- 0x26, 0x2a, 0x0a, 0x26, 0xf9, 0xa4, 0xb3, 0x79, 0xbe, 0xe9, 0x73, 0xcf,
- 0x9b, 0x2d, 0x2b, 0xd0, 0xe6, 0x39, 0x6e, 0x1f, 0x2f, 0x4f, 0xda, 0x71,
- 0xce, 0x5e, 0x87, 0xcd, 0x35, 0x66, 0x13, 0x3c, 0x85, 0xcb, 0x91, 0x1c,
- 0x69, 0xc3, 0xbc, 0x42, 0x03, 0x3a, 0x47, 0x42, 0x88, 0xa5, 0xc5, 0xc7,
- 0x23, 0x5a, 0x4a, 0xed, 0x80, 0xbf, 0xc0, 0x78, 0x9a, 0xfe, 0x8d, 0xf3,
- 0x16, 0xed, 0xa0, 0x87, 0xfa, 0xba, 0x26, 0xdd, 0x85, 0xba, 0x42, 0x00,
- 0x57, 0x0f, 0x7d, 0x02, 0xb5, 0x23, 0x7e, 0xcc, 0x1a, 0xd2, 0x90, 0x5f,
- 0xe2, 0x47, 0x60, 0x24, 0x8c, 0xea, 0xb4, 0xde, 0x75, 0x9b, 0x82, 0xe4,
- 0xc2, 0x25, 0x61, 0xb6, 0x4d, 0x7b, 0xa3, 0x7f, 0x8d, 0x90, 0x7f, 0x2d,
- 0xef, 0x06, 0x36, 0xa7, 0x05, 0x1b, 0x45, 0x27, 0x9f, 0x72, 0xcf, 0x9f,
- 0xac, 0x4b, 0x7f, 0x18, 0xce, 0x95, 0xed, 0x5b, 0xfc, 0xdc, 0x72, 0xcf,
- 0xc4, 0x32, 0x07, 0x52, 0xa6, 0x5b, 0xf4, 0xec, 0x3c, 0xde, 0xfb, 0x39,
- 0xe3, 0xf3, 0x43, 0xe9, 0x80, 0x55, 0x6b, 0x6e, 0xc6, 0x55, 0xed, 0x11,
- 0xab, 0xa0, 0xbc, 0xca, 0xf1, 0xff, 0x90, 0x41, 0xbb, 0x89, 0xfd, 0xfc,
- 0x63, 0xe5, 0x5f, 0xba, 0xce, 0xb6, 0xe4, 0xa2, 0xf5, 0xb9, 0x23, 0xcc,
- 0xe7, 0xa7, 0x2e, 0x5a, 0x9f, 0x13, 0xbc, 0x2f, 0x9f, 0x83, 0x90, 0xb9,
- 0xd2, 0x66, 0xd8, 0xb7, 0xac, 0x17, 0x09, 0x36, 0xca, 0x7c, 0x95, 0xd7,
- 0x8b, 0x7c, 0x58, 0x3e, 0x24, 0xb9, 0x92, 0xca, 0x3c, 0xa1, 0x05, 0xc9,
- 0xd0, 0xa3, 0x9c, 0x03, 0x77, 0x4d, 0x89, 0xf7, 0x06, 0xf8, 0x59, 0xd6,
- 0x7b, 0x34, 0xe2, 0x8f, 0x56, 0xca, 0x0b, 0xaa, 0x70, 0xeb, 0x50, 0x83,
- 0xbb, 0x1f, 0xb5, 0x22, 0x7e, 0x39, 0x62, 0xf5, 0x5f, 0x62, 0x99, 0x0b,
- 0x6b, 0x43, 0x57, 0x31, 0xdf, 0xa8, 0x71, 0xcf, 0x4a, 0x2c, 0xa3, 0xbe,
- 0x2f, 0x47, 0xdb, 0x48, 0x11, 0xcf, 0x6e, 0x1b, 0x29, 0xe2, 0x56, 0x5a,
- 0x6c, 0xce, 0x57, 0xb4, 0xb9, 0x2c, 0x6d, 0x2e, 0xa8, 0x77, 0x2a, 0xd9,
- 0xdc, 0x47, 0xc5, 0x13, 0x04, 0xeb, 0xcc, 0xf2, 0x99, 0x6a, 0x62, 0x5e,
- 0xfe, 0x48, 0xcd, 0x1f, 0x16, 0x7f, 0x2e, 0xd5, 0xd9, 0xb5, 0x7f, 0xa4,
- 0xce, 0xca, 0x31, 0xeb, 0x82, 0xce, 0x06, 0x2f, 0xd1, 0xd9, 0x02, 0xea,
- 0xa0, 0x41, 0x2f, 0xea, 0x6d, 0xb9, 0x71, 0x19, 0x52, 0xae, 0xde, 0xaa,
- 0x64, 0x6d, 0x8c, 0xf7, 0x04, 0xaf, 0xe7, 0xe0, 0xfb, 0xc1, 0x2f, 0xb9,
- 0xf7, 0x16, 0x51, 0x27, 0x45, 0x7d, 0x05, 0xa9, 0xaf, 0x0b, 0xb1, 0x00,
- 0xea, 0x07, 0xcc, 0xa7, 0x8a, 0xb1, 0x40, 0x74, 0xf7, 0xda, 0xa0, 0x86,
- 0xba, 0xeb, 0x2e, 0xc7, 0x2b, 0x7b, 0xab, 0xd0, 0x3e, 0xe2, 0xa3, 0x7f,
- 0x49, 0x7c, 0x28, 0xc6, 0xa4, 0xd6, 0x11, 0x77, 0x3f, 0x8a, 0xf8, 0xda,
- 0x10, 0xf8, 0xc3, 0x63, 0xb0, 0x8c, 0x47, 0xce, 0xe5, 0xc9, 0xb9, 0x39,
- 0x19, 0x97, 0x3e, 0xc3, 0x16, 0x1c, 0xe7, 0x19, 0xce, 0x77, 0xaa, 0x21,
- 0x92, 0x95, 0xf5, 0xa6, 0x2c, 0x39, 0x99, 0x27, 0x2d, 0x3a, 0x13, 0xbe,
- 0xad, 0xde, 0xe8, 0x81, 0xda, 0xe6, 0xc1, 0x66, 0x9c, 0x32, 0xf4, 0xfe,
- 0x7b, 0xf1, 0x27, 0xe8, 0x0d, 0x39, 0xd8, 0x6f, 0xac, 0x64, 0x3e, 0x51,
- 0x8d, 0xf5, 0x6d, 0x34, 0xcf, 0x3b, 0x3a, 0x88, 0x09, 0x56, 0x8f, 0x07,
- 0xb2, 0x9e, 0xbb, 0xf1, 0x2e, 0x3b, 0x1a, 0xe9, 0x7e, 0x50, 0x01, 0x56,
- 0x0c, 0xf8, 0xa1, 0x29, 0x2e, 0xdf, 0x89, 0x0d, 0xa9, 0xb2, 0xb6, 0xfc,
- 0x2f, 0x15, 0xc5, 0xb3, 0x10, 0x2a, 0xb4, 0x46, 0x69, 0x67, 0x25, 0xac,
- 0xc9, 0x0e, 0x17, 0x4f, 0x6a, 0x16, 0x2a, 0xb8, 0x75, 0x61, 0xc4, 0x4a,
- 0x29, 0x8e, 0xb3, 0x2a, 0xee, 0x75, 0x9f, 0xef, 0x98, 0x6c, 0x4d, 0xdd,
- 0xa9, 0xfe, 0x8b, 0x63, 0xb9, 0xeb, 0xd9, 0x91, 0x60, 0x52, 0x65, 0x9f,
- 0x3f, 0xf2, 0xac, 0xa2, 0x8c, 0x93, 0x5c, 0x9c, 0xbc, 0xfb, 0xc9, 0xd2,
- 0xfa, 0xaf, 0xcf, 0x5c, 0xff, 0x17, 0xfb, 0x75, 0xc9, 0xf7, 0xbe, 0xe4,
- 0x9e, 0xfb, 0xc8, 0x66, 0x64, 0xfd, 0xf0, 0xe1, 0x00, 0xaa, 0x57, 0xa2,
- 0x77, 0xf2, 0x3a, 0x4c, 0xb4, 0xfd, 0xab, 0x93, 0x2b, 0xf6, 0x5d, 0xcc,
- 0xd0, 0x3f, 0xcf, 0xcc, 0xdd, 0x75, 0x7d, 0x4b, 0x84, 0x1c, 0x5c, 0xce,
- 0x7a, 0x92, 0x0b, 0x2b, 0x45, 0x1e, 0x3e, 0x5f, 0xbf, 0x09, 0xcf, 0x5e,
- 0x24, 0x53, 0xd6, 0x12, 0xca, 0x32, 0x77, 0x51, 0x9e, 0xc8, 0x65, 0x3c,
- 0xd0, 0xff, 0xcd, 0x19, 0x09, 0xcd, 0x2c, 0x17, 0xab, 0x2a, 0xc6, 0x2a,
- 0x29, 0x57, 0x6e, 0xb7, 0x82, 0xf5, 0xde, 0x77, 0x46, 0x2f, 0x2a, 0xf7,
- 0xd3, 0x52, 0xb9, 0x67, 0x02, 0x72, 0x66, 0x24, 0x9b, 0x11, 0xce, 0x7a,
- 0xca, 0x19, 0xbb, 0xa8, 0x4c, 0x4b, 0xf5, 0xc5, 0x65, 0x9a, 0x89, 0xd1,
- 0xff, 0xaf, 0x33, 0x7e, 0x51, 0x99, 0xe4, 0x25, 0x65, 0x16, 0x10, 0x13,
- 0xbf, 0xef, 0xec, 0xbb, 0xa8, 0x4c, 0xed, 0x25, 0x65, 0x16, 0xd3, 0x1e,
- 0x9f, 0x71, 0x0e, 0x5c, 0x54, 0x66, 0xcc, 0x7f, 0x71, 0x19, 0xd9, 0xe3,
- 0x58, 0xff, 0x17, 0x5b, 0xf4, 0x75, 0x25, 0x9f, 0xbb, 0x70, 0xbf, 0x58,
- 0xfe, 0xf1, 0x4b, 0xfa, 0x1f, 0xb1, 0x64, 0xbe, 0x7d, 0xed, 0xe5, 0xf9,
- 0x7e, 0xb8, 0x74, 0xff, 0x7b, 0x35, 0x17, 0x97, 0xbb, 0x22, 0x70, 0x69,
- 0x3b, 0x45, 0x79, 0x47, 0x2f, 0x69, 0xff, 0xe6, 0xca, 0x8b, 0xbf, 0xbf,
- 0x5d, 0x51, 0xfc, 0x5e, 0xd6, 0xe9, 0xa1, 0x4b, 0x9e, 0xff, 0x7d, 0xc5,
- 0xc5, 0xdf, 0x37, 0x54, 0x7e, 0x78, 0x3b, 0xb5, 0x97, 0xb4, 0xa3, 0xf4,
- 0xca, 0xbb, 0x38, 0x1e, 0x53, 0xad, 0xed, 0xed, 0x58, 0x7f, 0x43, 0x2a,
- 0xbf, 0x89, 0xf6, 0x29, 0xb6, 0xf5, 0xe0, 0x0d, 0x6b, 0xf3, 0x6f, 0xcd,
- 0xe0, 0xb1, 0xcb, 0xc2, 0x41, 0x7c, 0x1c, 0x6b, 0xdd, 0xbd, 0x34, 0x95,
- 0x38, 0x69, 0xb9, 0xb6, 0x40, 0x8e, 0xe9, 0x57, 0xcc, 0x14, 0x0c, 0xf7,
- 0xbc, 0xe5, 0x3a, 0x34, 0xe7, 0xdd, 0x3d, 0xbb, 0x58, 0x0a, 0xcf, 0xaa,
- 0x5d, 0xba, 0x55, 0x3a, 0x47, 0x67, 0x5d, 0x1f, 0x44, 0x72, 0x66, 0x7e,
- 0xaa, 0x8d, 0x23, 0x12, 0xde, 0x86, 0x75, 0xee, 0x59, 0x6b, 0xc5, 0xec,
- 0x29, 0x9d, 0xd7, 0x5c, 0x03, 0x3d, 0x5f, 0xe6, 0x4d, 0xb2, 0x9e, 0x2b,
- 0xe7, 0x19, 0x1c, 0xfa, 0xa0, 0xc4, 0xf9, 0x83, 0x8a, 0x3a, 0xe0, 0xae,
- 0x99, 0xae, 0xf6, 0x20, 0x9a, 0xe8, 0x54, 0x90, 0xaa, 0x32, 0xa3, 0xda,
- 0xdb, 0x25, 0x4c, 0xf3, 0x4d, 0x6c, 0x51, 0x2a, 0x26, 0xfa, 0x15, 0xef,
- 0x44, 0x11, 0xd3, 0x3c, 0x13, 0xb2, 0xb6, 0xd0, 0xc0, 0x32, 0x41, 0xb4,
- 0x2c, 0xf1, 0xe2, 0x3b, 0x76, 0xad, 0xfb, 0x1e, 0xc7, 0xd6, 0x25, 0x15,
- 0x78, 0x20, 0xae, 0xa0, 0xeb, 0xaa, 0xc3, 0x78, 0x2b, 0x2f, 0xeb, 0x6c,
- 0x56, 0x7c, 0x94, 0x6d, 0x1e, 0xb2, 0x65, 0xbd, 0x74, 0x4b, 0x7c, 0xc4,
- 0x6d, 0xff, 0xf3, 0xe8, 0x73, 0xf7, 0xad, 0xba, 0x9d, 0xed, 0x99, 0x1e,
- 0x67, 0x1b, 0x73, 0x8d, 0x82, 0xdd, 0x90, 0xaa, 0x63, 0xfd, 0xb7, 0x96,
- 0xac, 0xc7, 0x69, 0x96, 0x99, 0xb0, 0x1f, 0xc4, 0xfb, 0xf9, 0x20, 0xf2,
- 0xf6, 0x4a, 0x7c, 0x37, 0x1f, 0x60, 0xce, 0xd7, 0x85, 0xef, 0xe4, 0x57,
- 0xe3, 0xc5, 0x61, 0xf7, 0x7d, 0x29, 0x2c, 0xb3, 0x15, 0xac, 0x88, 0xae,
- 0xc6, 0xb1, 0xd1, 0xd5, 0x38, 0x3c, 0x2c, 0xef, 0x0e, 0xcc, 0x25, 0x8f,
- 0x2c, 0xda, 0x9b, 0x4a, 0x8c, 0x59, 0x66, 0xaf, 0xc2, 0xa1, 0xd1, 0x30,
- 0x73, 0x29, 0x03, 0x27, 0xf3, 0x21, 0x8c, 0xd8, 0x6d, 0x38, 0x91, 0x0f,
- 0xe3, 0xeb, 0x76, 0x02, 0x67, 0xf9, 0xfd, 0xa0, 0x2d, 0x9c, 0xa5, 0x03,
- 0xd3, 0xf9, 0x6f, 0x32, 0xcf, 0x99, 0x87, 0x23, 0xdd, 0xcf, 0x30, 0x1c,
- 0x1d, 0xe4, 0xd5, 0x85, 0x13, 0xa3, 0x5d, 0x38, 0x35, 0x7c, 0x2b, 0x4e,
- 0x8d, 0xfe, 0x18, 0x6f, 0x0d, 0x4b, 0x7f, 0xe5, 0xfc, 0xb7, 0xc8, 0xd5,
- 0x29, 0x77, 0x35, 0xa6, 0x46, 0xff, 0x18, 0xd9, 0xef, 0x3a, 0x47, 0x56,
- 0x8b, 0xdc, 0x67, 0x7e, 0x87, 0x6c, 0xd1, 0xa5, 0x60, 0xbf, 0x1f, 0xc7,
- 0x6c, 0x3f, 0x8e, 0xda, 0x53, 0x57, 0x56, 0x61, 0xea, 0x7a, 0x22, 0x1d,
- 0xb6, 0xe7, 0x2b, 0xf1, 0x5c, 0x56, 0xd6, 0xd8, 0x3e, 0x86, 0x64, 0x70,
- 0x23, 0xb6, 0x4e, 0x56, 0xe2, 0x3b, 0x59, 0x3f, 0x75, 0x7c, 0x3d, 0x92,
- 0xf5, 0xab, 0xa9, 0xbf, 0x00, 0x5e, 0xb2, 0x43, 0x78, 0xd9, 0x6e, 0x4d,
- 0x15, 0x94, 0x76, 0x58, 0x2e, 0xfe, 0x07, 0xa8, 0xef, 0x0d, 0x6e, 0x9f,
- 0xbe, 0x63, 0x77, 0x3b, 0x5b, 0xa9, 0xe3, 0xfe, 0xcc, 0xe7, 0xdd, 0xb3,
- 0xdb, 0x2f, 0xda, 0xd3, 0x8e, 0xbc, 0x93, 0xf1, 0x14, 0x75, 0x7a, 0xcc,
- 0x4e, 0x91, 0xdb, 0x35, 0x71, 0x8e, 0xa6, 0x30, 0x4a, 0xbb, 0x3c, 0x99,
- 0xd5, 0x8f, 0xae, 0xc5, 0x26, 0x9c, 0xcd, 0x55, 0xe2, 0x35, 0xb6, 0x51,
- 0xb7, 0xd8, 0x8b, 0xe3, 0xae, 0xbc, 0x4d, 0x78, 0x3f, 0xab, 0x30, 0xde,
- 0x6e, 0xc2, 0x7b, 0x7c, 0xf6, 0x0a, 0x3f, 0x9f, 0x8e, 0xb3, 0x87, 0xa5,
- 0x67, 0xa7, 0xc8, 0xcf, 0x65, 0xcd, 0xa8, 0xb7, 0x63, 0x13, 0x4e, 0xe4,
- 0xde, 0x23, 0xa7, 0x75, 0xf0, 0x45, 0x63, 0x36, 0x12, 0xb3, 0xc9, 0x9b,
- 0xf4, 0x4a, 0x1c, 0xe3, 0xf3, 0x85, 0xc4, 0xdf, 0xe2, 0xfa, 0xd9, 0x26,
- 0xbc, 0xcb, 0xf1, 0x3c, 0x40, 0x59, 0xef, 0xe4, 0xfe, 0x96, 0x72, 0x97,
- 0x22, 0x1f, 0xff, 0x5b, 0xca, 0xfd, 0x31, 0xc6, 0x4b, 0xfa, 0x38, 0x61,
- 0xc8, 0xb8, 0xbe, 0x31, 0x0b, 0xd5, 0x21, 0x8e, 0xe3, 0x9b, 0xfc, 0xbf,
- 0x01, 0xc7, 0xf3, 0xff, 0x9b, 0xff, 0xbf, 0x8b, 0x03, 0x79, 0x59, 0xaf,
- 0x9e, 0x19, 0x4b, 0xc5, 0x7f, 0xca, 0x1c, 0x64, 0x0e, 0x32, 0x83, 0xb5,
- 0xa9, 0xd9, 0xb4, 0xa3, 0xbf, 0xbe, 0xb6, 0x0e, 0xef, 0xc6, 0x2d, 0xec,
- 0xd8, 0xe7, 0x45, 0x86, 0xb8, 0xbb, 0x63, 0xa0, 0x01, 0x4f, 0xec, 0x0c,
- 0xe2, 0xf1, 0x9d, 0x97, 0x61, 0xcb, 0xce, 0x2b, 0xb0, 0x67, 0x67, 0x13,
- 0xd2, 0x3b, 0x1d, 0xe7, 0xfd, 0xc5, 0x8e, 0xb3, 0x88, 0xd7, 0x23, 0xf4,
- 0x05, 0x3f, 0xff, 0xbf, 0x10, 0x17, 0x3f, 0xd1, 0x71, 0x95, 0xeb, 0x2f,
- 0x9d, 0xb8, 0xd2, 0xfd, 0x9f, 0xc4, 0xa2, 0xfc, 0xc6, 0xf8, 0xfa, 0xc2,
- 0xa6, 0xf8, 0x7d, 0x85, 0x39, 0xd8, 0x3a, 0xd8, 0x88, 0xc1, 0x9d, 0x0d,
- 0xa9, 0x06, 0xb6, 0xb3, 0xea, 0x5a, 0xe1, 0x76, 0x8e, 0x63, 0xb4, 0xf7,
- 0xc7, 0xd7, 0x16, 0x9e, 0x41, 0x77, 0x21, 0x84, 0xbe, 0xc1, 0x30, 0xdb,
- 0x92, 0xbd, 0x5c, 0xef, 0xd1, 0x7b, 0xe1, 0x38, 0xd3, 0x8b, 0x0f, 0xe2,
- 0xae, 0xc2, 0x37, 0xc9, 0x1b, 0x43, 0x48, 0x0f, 0xae, 0x47, 0x66, 0xb2,
- 0x22, 0xe5, 0x37, 0x1d, 0xbc, 0x14, 0x9f, 0xc2, 0xed, 0x94, 0xf7, 0xe8,
- 0x60, 0x2d, 0xfb, 0x54, 0x9d, 0xaa, 0x34, 0x25, 0x86, 0x3f, 0xc8, 0x18,
- 0x25, 0xfc, 0xe2, 0x28, 0x56, 0x30, 0xbf, 0xaa, 0x5f, 0xa2, 0xcf, 0x42,
- 0x6d, 0xd0, 0x7b, 0xa6, 0x43, 0xec, 0x2f, 0x45, 0xfb, 0x93, 0x7d, 0xf5,
- 0x75, 0xb8, 0xdb, 0x3d, 0xe7, 0xdd, 0x83, 0xe7, 0x6d, 0xc1, 0x9d, 0x35,
- 0xd8, 0x6f, 0xaf, 0x63, 0xce, 0x25, 0xf1, 0x7a, 0x25, 0x9a, 0x0b, 0x7f,
- 0x17, 0xbf, 0xa7, 0xb0, 0x9a, 0x7c, 0xf6, 0x5f, 0x70, 0x53, 0x21, 0xc7,
- 0x7e, 0x8d, 0xc6, 0xef, 0x2e, 0xec, 0x89, 0xdf, 0x5b, 0xe8, 0xc2, 0x02,
- 0x37, 0xa7, 0x64, 0xfe, 0x55, 0x90, 0x38, 0x77, 0x9c, 0x5c, 0xf8, 0x14,
- 0x96, 0x17, 0x5e, 0xc3, 0xcd, 0x05, 0xc1, 0x0d, 0x89, 0x7f, 0x2f, 0x7a,
- 0x51, 0x2d, 0x71, 0xef, 0x0b, 0xd8, 0xba, 0x3b, 0x85, 0xbe, 0xdd, 0x65,
- 0x8c, 0x6a, 0x0d, 0xee, 0x13, 0x7c, 0x99, 0xf4, 0x95, 0x62, 0xd4, 0xa7,
- 0x68, 0x8f, 0x2a, 0x63, 0xa3, 0xac, 0xd3, 0xaf, 0xa3, 0x2f, 0x6f, 0x24,
- 0x66, 0xca, 0x7a, 0xfc, 0x27, 0x4b, 0xf7, 0x25, 0xd6, 0xcb, 0x5a, 0xbc,
- 0x86, 0x43, 0x79, 0x77, 0x4f, 0x5b, 0xf3, 0xeb, 0xb7, 0xf3, 0x99, 0xd4,
- 0xff, 0x02, 0xd2, 0xbb, 0x57, 0x3b, 0x8f, 0x66, 0x8a, 0xfb, 0x66, 0x47,
- 0xa2, 0x6c, 0x6b, 0x9c, 0xb1, 0x7d, 0x2f, 0xfc, 0xb3, 0x38, 0xb6, 0x89,
- 0x01, 0x58, 0x1e, 0xbd, 0xdb, 0xd9, 0x92, 0xc1, 0xbd, 0xb3, 0x10, 0xc6,
- 0xca, 0x89, 0x0a, 0x24, 0xf7, 0x57, 0xe3, 0xb6, 0x9d, 0x3d, 0xb4, 0x65,
- 0x8b, 0xf6, 0xab, 0x1b, 0x77, 0x2b, 0xd5, 0xb8, 0x99, 0xf7, 0x3e, 0x3d,
- 0x28, 0x6b, 0x58, 0xd1, 0xa3, 0x27, 0x3c, 0xd5, 0xb8, 0x6b, 0xaf, 0x1f,
- 0xb9, 0xdc, 0x4a, 0x24, 0xf7, 0x1e, 0x81, 0x95, 0xa3, 0x4d, 0xee, 0x22,
- 0xce, 0x30, 0xcd, 0x51, 0xcd, 0x1f, 0x63, 0xcf, 0xa8, 0x8a, 0xba, 0x5d,
- 0xb2, 0xfe, 0xa8, 0xe8, 0xa7, 0xa3, 0x05, 0xa4, 0x47, 0xbd, 0x98, 0x95,
- 0xee, 0xc4, 0x04, 0xb1, 0x26, 0x90, 0x4e, 0x22, 0x9f, 0xef, 0x46, 0x8e,
- 0x58, 0x92, 0x1b, 0x0d, 0xa0, 0x26, 0x6d, 0x20, 0xa0, 0xc7, 0xb0, 0x83,
- 0xfe, 0x52, 0x91, 0xd6, 0xb1, 0x2d, 0x7f, 0x23, 0xac, 0xd1, 0x4f, 0x60,
- 0xfb, 0x68, 0x37, 0x2f, 0x13, 0x7d, 0xa3, 0x9f, 0xc7, 0xb2, 0x89, 0xa3,
- 0xe8, 0xcf, 0xa7, 0x68, 0x8f, 0xef, 0x61, 0x7b, 0xee, 0x30, 0x9e, 0xc8,
- 0x6e, 0xc6, 0xd9, 0xc5, 0x87, 0xf1, 0x38, 0x3f, 0x67, 0xb3, 0xfa, 0xc6,
- 0xb0, 0x7a, 0x18, 0x99, 0xdc, 0x26, 0x7c, 0x62, 0x50, 0xc1, 0x4b, 0xb4,
- 0xf5, 0xdb, 0xf7, 0xd2, 0x16, 0x1f, 0xdb, 0x80, 0xae, 0x89, 0xef, 0xc2,
- 0xce, 0x3f, 0x8f, 0x1d, 0xb9, 0x07, 0xd1, 0x9f, 0x59, 0xcf, 0xfc, 0xff,
- 0x19, 0xca, 0x39, 0x48, 0x3f, 0xdf, 0xc8, 0x31, 0x3e, 0xcc, 0xeb, 0xc2,
- 0x1a, 0xe3, 0x85, 0x35, 0x39, 0xfa, 0x7d, 0x46, 0x72, 0xcf, 0x75, 0xc4,
- 0x89, 0x27, 0x6b, 0x65, 0x5d, 0xb2, 0x4a, 0x9f, 0xb9, 0x56, 0x2f, 0xb6,
- 0x1f, 0x76, 0x73, 0xed, 0xaa, 0xb4, 0xe4, 0x75, 0x53, 0x91, 0x2a, 0x72,
- 0x0c, 0x7f, 0x5a, 0x74, 0xd8, 0xe3, 0xf4, 0x66, 0x04, 0x4b, 0x64, 0x3e,
- 0x34, 0xbc, 0x90, 0xff, 0x31, 0xb6, 0x0e, 0xcf, 0xc6, 0xf2, 0x6c, 0x1b,
- 0x39, 0xa5, 0xe3, 0x7c, 0x85, 0xbe, 0x66, 0x93, 0xeb, 0xec, 0x18, 0x4c,
- 0x12, 0x53, 0x66, 0x23, 0x39, 0xa7, 0xc8, 0x4f, 0xc2, 0x69, 0x69, 0xcb,
- 0x57, 0xda, 0xab, 0x9b, 0xba, 0x32, 0xcc, 0x7b, 0x75, 0x69, 0x99, 0xb7,
- 0x88, 0xa1, 0xb9, 0xfb, 0x69, 0x8e, 0xf3, 0x52, 0xb4, 0xcc, 0x95, 0xa6,
- 0xae, 0xac, 0xc3, 0x6c, 0x59, 0x77, 0x4d, 0xc8, 0x39, 0xdf, 0x6f, 0xb5,
- 0x2c, 0xa7, 0xaf, 0x7e, 0x01, 0x03, 0xe3, 0xe5, 0x77, 0x23, 0xff, 0xb3,
- 0xe4, 0xdd, 0xf5, 0x9f, 0x2c, 0xaf, 0xbc, 0x07, 0x2a, 0xe7, 0x8c, 0xcb,
- 0xef, 0x50, 0x8a, 0x2e, 0xaf, 0x90, 0xfd, 0x03, 0xab, 0xb8, 0x4f, 0x0a,
- 0x1c, 0xb1, 0x2b, 0x18, 0x87, 0xd5, 0xa5, 0x64, 0x63, 0x21, 0x1f, 0x2a,
- 0x19, 0x2f, 0x1b, 0xd1, 0x47, 0xbe, 0x7a, 0x93, 0x51, 0x81, 0x03, 0x6d,
- 0x49, 0x39, 0xcf, 0xd7, 0xe3, 0x73, 0x79, 0xea, 0xa6, 0x3f, 0xff, 0x6d,
- 0x9e, 0xba, 0x09, 0xe9, 0x8c, 0x9c, 0x63, 0xeb, 0xc6, 0x4b, 0xf5, 0xf2,
- 0x5e, 0xe7, 0x26, 0xf7, 0x9c, 0x70, 0xd5, 0x42, 0x62, 0x46, 0x5c, 0xc3,
- 0x51, 0xbd, 0x55, 0x6b, 0x50, 0x23, 0x06, 0x94, 0xd7, 0x1d, 0x2b, 0x94,
- 0x44, 0xff, 0xa4, 0x9c, 0xd5, 0xfb, 0xa8, 0x3d, 0x84, 0xb5, 0xd8, 0xfe,
- 0x58, 0x07, 0x8e, 0xaf, 0x96, 0xb5, 0xbc, 0x9f, 0x95, 0xde, 0xdb, 0x93,
- 0x3e, 0x46, 0xea, 0xe4, 0x0c, 0xaa, 0xc8, 0xde, 0x9e, 0x51, 0x19, 0x7b,
- 0xe2, 0x78, 0x3d, 0xe8, 0x8e, 0x37, 0x56, 0x3e, 0x97, 0x59, 0xa9, 0x2f,
- 0x2f, 0x95, 0x5f, 0x50, 0x27, 0xbc, 0x64, 0x5b, 0x66, 0x13, 0xb9, 0xb6,
- 0xf4, 0xe7, 0xd7, 0xce, 0xda, 0x50, 0x03, 0xcb, 0x8e, 0x95, 0x9e, 0x8b,
- 0xad, 0x45, 0x8c, 0x24, 0xe4, 0x9e, 0xd4, 0x11, 0x9d, 0xcd, 0xac, 0xe3,
- 0x41, 0xbd, 0x7e, 0x25, 0x1e, 0xa2, 0x8f, 0xcf, 0xd7, 0x5f, 0x76, 0x36,
- 0xcb, 0x39, 0xcd, 0x85, 0xc1, 0x19, 0x6d, 0x2d, 0x75, 0xfb, 0x52, 0xc9,
- 0xbe, 0x0c, 0x66, 0xe4, 0xbd, 0x81, 0xb3, 0xce, 0xc2, 0x46, 0x79, 0x7e,
- 0x5b, 0x6d, 0x51, 0x7e, 0xb3, 0x7b, 0x0e, 0x7b, 0x4f, 0xa6, 0xdc, 0x6f,
- 0x39, 0xe3, 0x1e, 0x2a, 0xb7, 0x15, 0xbb, 0x30, 0x1e, 0xe9, 0xdb, 0xd7,
- 0x6a, 0x2f, 0xee, 0xf3, 0x9d, 0xb3, 0xca, 0xef, 0x17, 0xcc, 0x73, 0xeb,
- 0x94, 0xdb, 0x94, 0x3e, 0x6e, 0xc2, 0xe3, 0x93, 0x97, 0x8e, 0xf1, 0xee,
- 0x19, 0x63, 0x92, 0x3a, 0x32, 0xae, 0x60, 0xc9, 0x0e, 0x36, 0xb2, 0x8c,
- 0xd4, 0x91, 0x75, 0x82, 0xa0, 0x9b, 0x3f, 0xd4, 0xed, 0x16, 0x79, 0x22,
- 0xc3, 0x71, 0xde, 0x70, 0x63, 0xf2, 0x02, 0xb7, 0xcc, 0xe0, 0xe4, 0x6a,
- 0xfa, 0x91, 0xb3, 0x99, 0xf8, 0xec, 0xbc, 0xd1, 0x11, 0xc6, 0x56, 0x5b,
- 0x74, 0xad, 0x87, 0xc7, 0x88, 0x4d, 0x7d, 0x2e, 0x9f, 0xf1, 0xa1, 0x37,
- 0x57, 0x3e, 0xeb, 0x52, 0x29, 0x7b, 0x21, 0x61, 0xd1, 0x79, 0xaf, 0x41,
- 0x1e, 0x17, 0x5c, 0xa6, 0x79, 0xc9, 0xc5, 0xee, 0xc1, 0x7f, 0xc8, 0xfc,
- 0xc6, 0x7c, 0xa5, 0x75, 0x93, 0x14, 0xed, 0xa8, 0x18, 0x0f, 0x41, 0xfe,
- 0x40, 0x1e, 0x56, 0x3a, 0x43, 0xdf, 0x9b, 0xff, 0x0f, 0x67, 0xca, 0x3d,
- 0x43, 0x7f, 0xe1, 0x2c, 0x4a, 0x2e, 0xe8, 0x38, 0xfb, 0xf8, 0xec, 0xc2,
- 0x79, 0x7a, 0x72, 0x06, 0x5d, 0xce, 0xdd, 0xff, 0x3b, 0xe7, 0x6e, 0x66,
- 0xd9, 0xa9, 0xfa, 0xe2, 0xfb, 0x25, 0x49, 0x75, 0x99, 0x5e, 0xc6, 0x6d,
- 0xd9, 0x27, 0x12, 0xdc, 0x3e, 0x58, 0x57, 0x5c, 0x3f, 0x8e, 0x74, 0x75,
- 0x43, 0xf6, 0xe4, 0xcb, 0x38, 0xa3, 0x1b, 0x8b, 0x94, 0xcd, 0x68, 0x89,
- 0x57, 0xcb, 0xf9, 0xba, 0x88, 0xd7, 0x8c, 0x04, 0xdf, 0x42, 0x34, 0x76,
- 0xd8, 0x3d, 0x43, 0x22, 0xd8, 0xa3, 0xe3, 0x9e, 0xbc, 0x4e, 0x9b, 0x95,
- 0xf7, 0xd2, 0xe5, 0x73, 0xf1, 0xdd, 0xc7, 0x64, 0x5e, 0xb0, 0xba, 0x87,
- 0x58, 0x6d, 0xfd, 0xa5, 0xcf, 0x95, 0x17, 0xe9, 0x19, 0x55, 0x22, 0x5d,
- 0x0f, 0x2a, 0x65, 0x79, 0x81, 0x0f, 0x91, 0x17, 0x63, 0x7d, 0xad, 0xf4,
- 0x2e, 0xb8, 0x4e, 0x19, 0x97, 0x9e, 0x0d, 0x9a, 0x93, 0x92, 0x3c, 0xfa,
- 0x40, 0x89, 0x73, 0x1e, 0xfe, 0xad, 0x3c, 0xfa, 0x43, 0xdb, 0x4c, 0xb2,
- 0xcd, 0xae, 0x6a, 0x25, 0x19, 0x97, 0xf7, 0x80, 0x2a, 0xe3, 0xd1, 0xd8,
- 0x0b, 0x74, 0x72, 0xaf, 0x19, 0x0d, 0x8f, 0xba, 0x67, 0x5d, 0x0c, 0xff,
- 0xf2, 0x7c, 0xd1, 0x7f, 0xac, 0xc9, 0xdf, 0xad, 0x93, 0x1a, 0x5d, 0xef,
- 0x6e, 0x55, 0x92, 0xd7, 0x57, 0x53, 0x4e, 0x2c, 0x0e, 0xad, 0xc2, 0x2c,
- 0xeb, 0x28, 0x1a, 0x7b, 0x8b, 0xf3, 0x79, 0xa8, 0x23, 0x1a, 0x1e, 0x71,
- 0x73, 0x74, 0xd1, 0x8b, 0xe1, 0x2f, 0xce, 0xbd, 0x2e, 0x7c, 0xde, 0xf2,
- 0x31, 0x36, 0x8f, 0xdb, 0x7e, 0x8e, 0xa5, 0x35, 0xb8, 0x1d, 0xf5, 0xb4,
- 0x71, 0x24, 0xfb, 0xda, 0x18, 0x1f, 0x6c, 0x24, 0x3d, 0x57, 0xd5, 0x21,
- 0x45, 0x82, 0xee, 0xd1, 0x53, 0xe4, 0x5c, 0xad, 0xb1, 0x47, 0x68, 0xbf,
- 0xb9, 0x50, 0x24, 0x6c, 0x21, 0x85, 0xe7, 0xec, 0x65, 0x7f, 0xee, 0x81,
- 0x65, 0xd4, 0x70, 0xa2, 0xab, 0xcd, 0xa9, 0x3f, 0xbf, 0x35, 0x1a, 0xd1,
- 0x5e, 0x2c, 0x9d, 0xd5, 0xe9, 0xb5, 0x7f, 0xe1, 0xee, 0x51, 0x79, 0xf4,
- 0xdf, 0x55, 0x46, 0xda, 0xf6, 0x63, 0x2c, 0x9b, 0xc5, 0x96, 0xc7, 0xd8,
- 0x47, 0xdd, 0xc1, 0x32, 0x63, 0x33, 0x96, 0x1b, 0x01, 0xac, 0x0b, 0xb6,
- 0x24, 0xe4, 0x2c, 0xd2, 0x48, 0xae, 0xb8, 0x36, 0x52, 0x5c, 0x0b, 0xef,
- 0xc7, 0xa3, 0x19, 0x37, 0x3e, 0x07, 0xfd, 0x66, 0x52, 0x79, 0x34, 0xdf,
- 0xa9, 0x3c, 0x52, 0x5a, 0x8f, 0xeb, 0xcf, 0xdf, 0x10, 0x44, 0xb5, 0x85,
- 0x13, 0x86, 0xbc, 0x47, 0x29, 0x72, 0x2d, 0x8c, 0x76, 0xfc, 0x21, 0xef,
- 0x53, 0x8a, 0x4e, 0x37, 0xa2, 0x6f, 0xf8, 0x61, 0xf4, 0x0e, 0xbf, 0xe4,
- 0x9e, 0x65, 0xf5, 0xe9, 0x7e, 0xeb, 0x0a, 0x33, 0x72, 0xd0, 0xc2, 0xbc,
- 0x7a, 0x59, 0x13, 0x6e, 0x34, 0x8f, 0xe2, 0xd1, 0xa0, 0xbc, 0x27, 0xd8,
- 0x4f, 0x9e, 0x22, 0xef, 0x9c, 0xad, 0xc1, 0x67, 0x06, 0x64, 0x0e, 0x6b,
- 0xad, 0x4a, 0x33, 0x92, 0x5c, 0xe7, 0xce, 0x61, 0x1b, 0x8e, 0x15, 0x1e,
- 0xc6, 0x1b, 0xbb, 0x36, 0x43, 0x8d, 0x47, 0xc2, 0xb7, 0xc0, 0xd9, 0x7c,
- 0xc4, 0x48, 0x5a, 0x3e, 0x44, 0x0e, 0x78, 0x54, 0xe0, 0xd9, 0x5d, 0x92,
- 0x4f, 0xf7, 0xe0, 0x7a, 0x72, 0x80, 0x3a, 0xdd, 0x59, 0xfa, 0xab, 0xc5,
- 0x91, 0x7e, 0xdd, 0x63, 0xfd, 0xd3, 0x1c, 0x44, 0xb2, 0x09, 0x55, 0xef,
- 0xf9, 0xa4, 0x0a, 0x25, 0x60, 0xca, 0x6f, 0x00, 0x6c, 0xc6, 0x27, 0xda,
- 0x03, 0xd6, 0x2c, 0x33, 0x92, 0x7d, 0x49, 0x89, 0xc4, 0x2c, 0xf5, 0x1b,
- 0x9c, 0xe7, 0x18, 0x5e, 0x24, 0xc7, 0xe9, 0x62, 0x6c, 0x5f, 0x21, 0x31,
- 0xdd, 0xc5, 0xbe, 0xe6, 0x44, 0x95, 0x12, 0xc4, 0x2d, 0x05, 0xe0, 0x50,
- 0x6e, 0x0d, 0x4e, 0xee, 0x32, 0xd0, 0xc9, 0x67, 0x83, 0x19, 0x02, 0x16,
- 0x31, 0x60, 0x83, 0x61, 0xb5, 0xaa, 0xe4, 0x16, 0x3e, 0x15, 0xcb, 0xe6,
- 0x9b, 0xd1, 0xa9, 0xa5, 0x1e, 0x2f, 0x12, 0x05, 0x2f, 0xee, 0x60, 0x99,
- 0xed, 0x8c, 0x0b, 0x9f, 0x4c, 0xfb, 0xc9, 0x6f, 0x9b, 0xf0, 0x33, 0xf2,
- 0xec, 0x9f, 0x92, 0x4f, 0x1f, 0x27, 0x5f, 0x38, 0x9e, 0xaf, 0x46, 0xf7,
- 0x90, 0x4f, 0xce, 0x1f, 0x4d, 0xf9, 0x38, 0x17, 0xb5, 0xed, 0x21, 0x9c,
- 0x1e, 0xf5, 0xe3, 0xf6, 0x5d, 0x91, 0x3d, 0xc7, 0xd5, 0x46, 0xbc, 0x3f,
- 0x5a, 0x8d, 0x95, 0x43, 0x7e, 0xf6, 0xcd, 0xc1, 0x0e, 0xe2, 0xff, 0xbb,
- 0x7c, 0xd6, 0xb9, 0x0b, 0x4a, 0x7e, 0xc9, 0x02, 0xe6, 0x04, 0x3a, 0xeb,
- 0xd7, 0xe0, 0xd6, 0x21, 0xe1, 0x81, 0x2a, 0xde, 0x1e, 0x55, 0xf0, 0x56,
- 0xce, 0xc0, 0x32, 0xb6, 0xd7, 0x97, 0x79, 0xd6, 0xf1, 0xd3, 0xcf, 0xd7,
- 0xe6, 0x0d, 0xdc, 0x9b, 0xd3, 0x19, 0x53, 0x7e, 0xe2, 0x78, 0xf4, 0x76,
- 0xfc, 0x64, 0xa7, 0x7e, 0xf4, 0x75, 0x4f, 0x74, 0x6a, 0x89, 0xa7, 0x1d,
- 0xaf, 0xed, 0x6f, 0xc7, 0xf7, 0x06, 0x97, 0xe2, 0x9a, 0xf6, 0x24, 0xce,
- 0x2c, 0x69, 0xc7, 0xab, 0x7b, 0x75, 0x3c, 0x92, 0xe9, 0x80, 0x36, 0x31,
- 0x45, 0xfe, 0x9b, 0x40, 0xeb, 0x84, 0x09, 0x7d, 0xd0, 0xd9, 0x5c, 0x63,
- 0x6e, 0xc6, 0xa3, 0x86, 0x89, 0x45, 0x7b, 0x45, 0x0f, 0x8e, 0xb3, 0x6e,
- 0x89, 0x89, 0x17, 0xb2, 0x3a, 0xfd, 0xd4, 0xa4, 0x1e, 0x74, 0x3c, 0x9e,
- 0x31, 0x11, 0x7d, 0x4c, 0x9f, 0xde, 0xc7, 0xef, 0x4b, 0xf7, 0x75, 0xa0,
- 0x87, 0xed, 0xdb, 0xc4, 0xeb, 0x3d, 0x13, 0x6d, 0x1c, 0xb3, 0xc1, 0xf1,
- 0x37, 0x5b, 0x3f, 0x53, 0x3a, 0x91, 0x9d, 0xe8, 0x22, 0x9f, 0xdd, 0x4c,
- 0x1e, 0xdb, 0xe5, 0xee, 0xb9, 0x6f, 0xcd, 0x18, 0xb8, 0x35, 0xdd, 0x85,
- 0x27, 0x6d, 0x39, 0x3b, 0xaf, 0x27, 0xae, 0x55, 0xe4, 0x1d, 0xdd, 0x2e,
- 0x8c, 0x51, 0x27, 0xcb, 0x86, 0x56, 0xba, 0xe7, 0x9d, 0x96, 0xef, 0xd2,
- 0xf1, 0x44, 0xe6, 0x13, 0x38, 0x39, 0x6e, 0xa0, 0x3b, 0x2d, 0xfa, 0x96,
- 0xf3, 0x9b, 0x29, 0x1c, 0x61, 0x6c, 0xf9, 0xd9, 0x50, 0xf2, 0x9f, 0x38,
- 0xcd, 0xc7, 0x54, 0xc8, 0x7a, 0x89, 0x8a, 0xab, 0xdb, 0xe5, 0x0c, 0xae,
- 0x87, 0xa8, 0x16, 0xb1, 0xea, 0x54, 0x4b, 0xe3, 0x7d, 0xcb, 0xab, 0x6e,
- 0xc2, 0x67, 0x87, 0xbc, 0xcc, 0x19, 0x54, 0xe6, 0x3a, 0xd6, 0x06, 0xda,
- 0x86, 0x55, 0xab, 0x16, 0xe7, 0xcd, 0xdd, 0x63, 0xd0, 0x3d, 0xd8, 0x61,
- 0x34, 0x77, 0xd7, 0xb0, 0xde, 0x8a, 0x78, 0x24, 0x59, 0xa5, 0x76, 0x30,
- 0x0f, 0x7d, 0x18, 0xeb, 0x76, 0x3d, 0x8c, 0xb5, 0xbc, 0x36, 0xec, 0x72,
- 0x36, 0xdf, 0x6c, 0x28, 0x78, 0x4e, 0x77, 0x36, 0x6f, 0x36, 0x74, 0xce,
- 0xad, 0xcc, 0xeb, 0xc3, 0xd8, 0x38, 0xf6, 0x30, 0x1e, 0xa2, 0x7d, 0x35,
- 0xd0, 0x8f, 0x57, 0xa5, 0x9d, 0xcd, 0xd7, 0xb4, 0xc7, 0xf0, 0x73, 0x37,
- 0xbf, 0x11, 0x7b, 0x3d, 0xe3, 0xe6, 0xdc, 0x39, 0xd5, 0xb5, 0xdd, 0xa0,
- 0x7c, 0xb6, 0xd4, 0x25, 0xc1, 0x72, 0x6c, 0xf9, 0x05, 0xe5, 0xfe, 0x72,
- 0x57, 0x1d, 0x1e, 0x6b, 0x90, 0xf8, 0xe1, 0xb7, 0xaa, 0x4c, 0x28, 0xfa,
- 0x12, 0xe6, 0x71, 0x8f, 0x1d, 0xc1, 0x76, 0xf2, 0xc2, 0x50, 0x5c, 0x72,
- 0xec, 0x56, 0x63, 0x8b, 0x7a, 0x23, 0xb1, 0x5d, 0xc1, 0xa3, 0x0b, 0xb3,
- 0x18, 0xa0, 0xaf, 0xee, 0x58, 0x18, 0x49, 0x0d, 0xc0, 0x74, 0x76, 0xcc,
- 0xe9, 0xff, 0x23, 0xde, 0xa1, 0x2d, 0xef, 0x4b, 0xca, 0x7b, 0xb4, 0x0f,
- 0x63, 0xf3, 0x2e, 0x99, 0xff, 0x87, 0xf1, 0x45, 0xf6, 0x7f, 0xe3, 0xd0,
- 0xc3, 0xf8, 0x1c, 0x6d, 0xa7, 0x7e, 0xf1, 0xa1, 0x2f, 0xd6, 0xa3, 0x25,
- 0x5b, 0x87, 0xa9, 0xfb, 0x1b, 0xe4, 0xbc, 0x2d, 0x31, 0x71, 0x40, 0x79,
- 0x18, 0xf7, 0x8c, 0xd4, 0xd2, 0x17, 0xdd, 0x31, 0x10, 0x8b, 0xcb, 0xf1,
- 0x2a, 0x8c, 0x75, 0xf9, 0xa6, 0x12, 0xae, 0x87, 0xb0, 0xd6, 0x3e, 0xe0,
- 0xfa, 0x7e, 0x85, 0xb9, 0x9a, 0x7e, 0xdf, 0x4d, 0xbf, 0x5f, 0x49, 0xbf,
- 0xef, 0xa2, 0xdf, 0x77, 0xd2, 0xef, 0x93, 0xf4, 0x7b, 0x93, 0x7e, 0x9f,
- 0xa0, 0xdf, 0x77, 0xd0, 0xef, 0x0d, 0xd9, 0x3b, 0x54, 0x8e, 0x76, 0x1c,
- 0x81, 0x6f, 0xd0, 0x4f, 0x1b, 0x2a, 0xbe, 0xd3, 0xb8, 0x9f, 0xf8, 0x73,
- 0xc2, 0x58, 0x14, 0xbe, 0x89, 0xaa, 0x1a, 0x25, 0x46, 0xe4, 0xc6, 0xff,
- 0xce, 0x7d, 0xff, 0x2d, 0x47, 0xdc, 0x7f, 0x91, 0xfa, 0x58, 0x11, 0x6f,
- 0x36, 0x9e, 0x64, 0x0c, 0xfb, 0xa1, 0xde, 0xda, 0x1f, 0x62, 0x99, 0xaf,
- 0x65, 0x5a, 0xb3, 0xb3, 0xa1, 0x5b, 0xed, 0xea, 0x56, 0x60, 0x55, 0x88,
- 0x63, 0x96, 0x73, 0xdd, 0xab, 0xf0, 0xc5, 0xe1, 0x6e, 0xfc, 0xcf, 0xe1,
- 0x20, 0x75, 0xd1, 0x3c, 0x75, 0xa3, 0x07, 0xdf, 0x0c, 0xc3, 0x13, 0x9a,
- 0x0b, 0x7c, 0xd0, 0x88, 0x45, 0x07, 0xe4, 0x5d, 0xec, 0x5c, 0xa3, 0xa7,
- 0x6d, 0x3e, 0xc4, 0x46, 0x40, 0xa4, 0xf6, 0x30, 0xd3, 0x5c, 0xe4, 0xbe,
- 0xaf, 0x99, 0x5c, 0x2d, 0x98, 0x5e, 0x85, 0xad, 0x31, 0x17, 0x67, 0x9f,
- 0x96, 0xf3, 0xe9, 0x8d, 0xc4, 0xa3, 0x80, 0xd9, 0x85, 0x6d, 0x03, 0xd6,
- 0x5d, 0x8d, 0x58, 0x89, 0xfe, 0x81, 0xa2, 0x0e, 0xee, 0x8f, 0x13, 0xf2,
- 0xcc, 0xa8, 0xb6, 0x48, 0x81, 0x77, 0x43, 0x47, 0x02, 0xf7, 0xe6, 0x6d,
- 0x64, 0x39, 0xc6, 0xf5, 0xf4, 0xb3, 0x75, 0xbf, 0xff, 0x3d, 0x7c, 0x7c,
- 0xce, 0xd6, 0x68, 0xff, 0xe7, 0x9c, 0x5c, 0xfd, 0xa2, 0x6c, 0x23, 0xf4,
- 0x8d, 0x77, 0xa8, 0xd7, 0x32, 0x67, 0x8e, 0x1c, 0xe4, 0x23, 0x6b, 0x8e,
- 0x7b, 0x8e, 0xce, 0x8f, 0x05, 0x43, 0x50, 0x46, 0xd3, 0xf2, 0xce, 0xda,
- 0x66, 0xfc, 0x5f, 0xc6, 0x37, 0x5c, 0x5b, 0x9a, 0xf2, 0xc8, 0x99, 0x16,
- 0xb9, 0xef, 0x2c, 0x3d, 0xbb, 0x38, 0x12, 0xd3, 0x3c, 0x3f, 0xa8, 0x93,
- 0xfd, 0x8b, 0xaf, 0x33, 0xce, 0x86, 0x87, 0x96, 0x42, 0x5d, 0xec, 0xc7,
- 0x9d, 0x6d, 0xb3, 0x90, 0x5a, 0x25, 0x3c, 0xd4, 0xdd, 0x5f, 0xa1, 0x3e,
- 0xff, 0x02, 0xf7, 0x19, 0x5f, 0xc1, 0xf1, 0x90, 0x8d, 0x21, 0xe2, 0xd7,
- 0x3a, 0xe3, 0x76, 0xc5, 0xe2, 0x67, 0xe6, 0x44, 0x58, 0x6f, 0x30, 0xd7,
- 0xfa, 0x54, 0x03, 0x1a, 0x76, 0x49, 0x79, 0x91, 0x7b, 0xc6, 0x95, 0xb7,
- 0x3f, 0x23, 0x9f, 0x8b, 0x36, 0x3b, 0xe5, 0xf9, 0x24, 0xd0, 0x20, 0xe7,
- 0x84, 0x15, 0xbc, 0xbd, 0xd0, 0xc6, 0x63, 0x19, 0x7c, 0xb3, 0x0a, 0xcd,
- 0xb9, 0x41, 0xd5, 0xf3, 0xcd, 0xb9, 0x58, 0x64, 0xfc, 0x5a, 0x95, 0xf9,
- 0x48, 0xe2, 0xbe, 0x85, 0x72, 0x1e, 0x4d, 0x3f, 0xf3, 0x3d, 0xfa, 0xd6,
- 0x71, 0xd8, 0xd8, 0x3e, 0xf9, 0x92, 0x33, 0x35, 0x37, 0x84, 0xa7, 0x26,
- 0xa5, 0x6e, 0x37, 0x4e, 0x70, 0x4e, 0xbe, 0xec, 0xee, 0xe7, 0x45, 0x92,
- 0x27, 0x54, 0x79, 0xe7, 0xb0, 0x1b, 0x6f, 0x8d, 0x1a, 0xd8, 0xc7, 0x1c,
- 0xea, 0x57, 0xc3, 0xab, 0xf0, 0xeb, 0xe1, 0x66, 0xed, 0x6f, 0x14, 0x39,
- 0x03, 0xff, 0x71, 0xfc, 0xa8, 0x21, 0x88, 0x83, 0xb4, 0xa1, 0x69, 0xbb,
- 0x0b, 0x6f, 0xdb, 0x56, 0x64, 0x2e, 0x22, 0x7b, 0xbc, 0x9e, 0xc8, 0x01,
- 0x79, 0xcf, 0x79, 0x9d, 0x1a, 0x39, 0xb8, 0x44, 0x89, 0x58, 0x6f, 0xa8,
- 0x2b, 0xf1, 0x8b, 0x7c, 0x17, 0xce, 0xe4, 0x67, 0xda, 0xc2, 0x66, 0x07,
- 0x8d, 0x62, 0x07, 0x62, 0x0f, 0xb4, 0x45, 0xe6, 0x8a, 0xdf, 0x26, 0x8f,
- 0xee, 0xfd, 0x18, 0xed, 0x31, 0x43, 0x7b, 0xcc, 0xd0, 0x1e, 0x89, 0x49,
- 0xcf, 0x10, 0xab, 0xbe, 0x96, 0xa1, 0x3d, 0xd2, 0x7f, 0xbe, 0x42, 0xff,
- 0x29, 0x72, 0xe5, 0x1e, 0x77, 0x4d, 0xff, 0x15, 0xc6, 0x44, 0xfb, 0x31,
- 0x79, 0x7f, 0xb8, 0x79, 0x7d, 0x01, 0x91, 0x9e, 0x01, 0x65, 0x5d, 0xbd,
- 0xbc, 0xcf, 0xf1, 0xf9, 0xa8, 0xf8, 0x80, 0xbc, 0x7b, 0x46, 0xbf, 0x1a,
- 0x3f, 0x55, 0x27, 0xef, 0xb2, 0xee, 0xdf, 0xfd, 0x51, 0x3a, 0xfb, 0x7b,
- 0xf6, 0x43, 0xf4, 0xf5, 0xc7, 0x8e, 0x5d, 0x74, 0xf9, 0x4f, 0xce, 0x8f,
- 0x1a, 0x65, 0xfc, 0xab, 0xf1, 0xf3, 0xe1, 0x4e, 0x9c, 0x65, 0xfc, 0xfd,
- 0x74, 0xfb, 0x94, 0x45, 0x9b, 0xdd, 0x68, 0x78, 0x4c, 0x4c, 0xe6, 0x3b,
- 0x71, 0xda, 0x36, 0x91, 0xb7, 0x9b, 0xd7, 0x7f, 0x57, 0x79, 0x53, 0xcd,
- 0xcd, 0x2b, 0xf2, 0xf9, 0xdf, 0x90, 0x5f, 0x1e, 0x6a, 0x91, 0xf7, 0x5d,
- 0x13, 0x18, 0xc9, 0x8b, 0x9d, 0x06, 0x71, 0xd3, 0x12, 0x43, 0xde, 0x11,
- 0xfb, 0xbd, 0x7f, 0xf7, 0xd9, 0xb2, 0x97, 0x72, 0xce, 0x99, 0x0a, 0xfa,
- 0xad, 0x20, 0x7d, 0xd8, 0xb3, 0x4b, 0x7e, 0x07, 0x40, 0xfc, 0x59, 0xc1,
- 0x67, 0x8c, 0x29, 0xad, 0x06, 0x91, 0xa7, 0x77, 0x33, 0x81, 0x7a, 0x2d,
- 0x2d, 0x67, 0x88, 0x3b, 0xf1, 0x26, 0xcb, 0x57, 0xd1, 0x2f, 0x5e, 0xcb,
- 0x7b, 0xbd, 0x3f, 0x4a, 0xcb, 0x7b, 0xec, 0x2b, 0xf1, 0xa3, 0xfc, 0xcb,
- 0xea, 0x2f, 0x82, 0x06, 0xde, 0x2e, 0xac, 0xc2, 0xfc, 0x5d, 0xb2, 0xbe,
- 0x90, 0xc4, 0x7e, 0x3b, 0x72, 0xf4, 0x59, 0xac, 0xc2, 0xbc, 0xb1, 0xd5,
- 0xcc, 0xa3, 0x15, 0xbc, 0x17, 0x5d, 0x8d, 0x00, 0x3f, 0xd7, 0xee, 0x72,
- 0x9c, 0xc3, 0xf1, 0x3a, 0x67, 0xfb, 0x6a, 0x99, 0x3b, 0xc1, 0x93, 0x65,
- 0xf5, 0xa8, 0x5d, 0x0d, 0x8c, 0x09, 0x57, 0xd1, 0x71, 0xeb, 0xc0, 0x2a,
- 0x5c, 0xb1, 0xab, 0x39, 0x76, 0x2b, 0x9a, 0xb3, 0x47, 0x3c, 0xab, 0xd0,
- 0x30, 0x76, 0x2f, 0xe7, 0x40, 0xca, 0x6a, 0xb4, 0x3f, 0x0b, 0x95, 0xe4,
- 0x84, 0x9d, 0xe9, 0x9f, 0x3a, 0xf3, 0x4d, 0x77, 0x1f, 0x0e, 0xeb, 0x0a,
- 0x3a, 0xe3, 0x5d, 0x35, 0x52, 0x23, 0x4f, 0x38, 0x75, 0xa6, 0x17, 0x6b,
- 0x0b, 0x6d, 0xb8, 0x69, 0xc8, 0x71, 0x4e, 0x2f, 0x49, 0x22, 0x60, 0x06,
- 0x88, 0x61, 0x01, 0x3c, 0x94, 0xae, 0xe1, 0x7f, 0x07, 0x15, 0x8c, 0xc9,
- 0x2d, 0xaa, 0xbe, 0x7e, 0x9e, 0x47, 0xef, 0x29, 0x28, 0x12, 0xf7, 0x03,
- 0x78, 0x80, 0xf1, 0x79, 0x45, 0x3a, 0x8c, 0x54, 0xc1, 0x71, 0x5e, 0xed,
- 0x08, 0xe1, 0x7e, 0xd6, 0xef, 0x4a, 0xf7, 0xa3, 0x97, 0x76, 0x91, 0x1a,
- 0xd3, 0xb5, 0x20, 0xe3, 0xfd, 0xba, 0x82, 0x9f, 0x31, 0xac, 0x01, 0xb7,
- 0xec, 0xd2, 0xf0, 0x50, 0x21, 0xc0, 0xf8, 0xe6, 0x2c, 0x3d, 0x69, 0x58,
- 0x57, 0x7a, 0xa0, 0x63, 0x63, 0x21, 0x84, 0x95, 0xe9, 0xc8, 0xb4, 0xbc,
- 0x47, 0x7d, 0xd6, 0x88, 0xe1, 0xc1, 0x42, 0x18, 0xb7, 0xa5, 0x0f, 0x3d,
- 0x34, 0x1f, 0xd6, 0xff, 0x98, 0x87, 0x36, 0x7c, 0xa6, 0xd0, 0x44, 0xf9,
- 0x91, 0xf5, 0xaf, 0x28, 0x4d, 0xf8, 0xec, 0x98, 0x41, 0xf9, 0x2a, 0x6e,
- 0xa5, 0x9c, 0x9b, 0xd3, 0x57, 0xe0, 0x81, 0xb1, 0x0e, 0xdc, 0x5b, 0x58,
- 0x8c, 0xe5, 0x8c, 0x4f, 0x1b, 0x98, 0x1b, 0xe2, 0xbf, 0x00, 0xb7, 0x0d,
- 0x89, 0xee, 0xa1, 0xbc, 0xda, 0x31, 0xc5, 0x7c, 0xdc, 0x00, 0x0d, 0x91,
- 0xf7, 0x74, 0x72, 0x30, 0x03, 0xb7, 0xed, 0x5d, 0xec, 0xee, 0xc9, 0x37,
- 0xc7, 0x2b, 0x91, 0xea, 0x56, 0xd0, 0x39, 0x24, 0x71, 0x56, 0xb8, 0x8d,
- 0xc1, 0xb8, 0x1a, 0x65, 0x1b, 0x06, 0xe3, 0x6a, 0xf1, 0x7e, 0x6f, 0x46,
- 0xd6, 0x2e, 0x7e, 0x42, 0xbe, 0x14, 0x47, 0xa7, 0x1b, 0xa3, 0xfd, 0xe4,
- 0xd7, 0x16, 0xbc, 0x8c, 0xdd, 0x71, 0xda, 0xf8, 0xd2, 0x76, 0x89, 0xd5,
- 0x3a, 0x06, 0xe8, 0x0f, 0x93, 0x83, 0xfa, 0x86, 0x69, 0xc5, 0x44, 0x61,
- 0xaf, 0xc4, 0xc4, 0x10, 0x1e, 0x4c, 0x9b, 0x38, 0x29, 0xe7, 0xf8, 0xaf,
- 0x4a, 0xae, 0xa8, 0x81, 0x6e, 0x3c, 0x80, 0xa8, 0x75, 0x8c, 0xb1, 0xfd,
- 0x4c, 0xae, 0x01, 0x37, 0xed, 0x92, 0x32, 0xed, 0x78, 0x7d, 0xd4, 0x8b,
- 0x9b, 0xd2, 0x9b, 0xf0, 0x44, 0xd6, 0x83, 0x11, 0xa3, 0xb9, 0x5f, 0x65,
- 0xfc, 0xbc, 0xbe, 0x3d, 0x12, 0xfc, 0x3a, 0xb9, 0xea, 0xf4, 0x62, 0x46,
- 0xe5, 0xb9, 0x1d, 0xe8, 0x64, 0xbf, 0x3a, 0x75, 0xf1, 0x49, 0x0b, 0xf7,
- 0x76, 0x6c, 0xc2, 0xb1, 0xac, 0x6e, 0x3d, 0x29, 0xeb, 0x0c, 0xed, 0x7c,
- 0x3e, 0xc7, 0x8b, 0x3e, 0x5d, 0x38, 0xad, 0x4e, 0xdf, 0x22, 0xeb, 0xd4,
- 0x3b, 0x70, 0x92, 0xf6, 0xda, 0x9f, 0x5b, 0xca, 0xd8, 0x2f, 0x31, 0xdf,
- 0x6f, 0x85, 0x59, 0xaf, 0xee, 0x3a, 0x05, 0x27, 0xf6, 0x09, 0xc7, 0x5a,
- 0x8a, 0xbb, 0xa8, 0xa7, 0xce, 0xb4, 0x8a, 0xeb, 0xc7, 0xd6, 0xe0, 0xf4,
- 0xce, 0x22, 0xe7, 0x7a, 0x35, 0x6e, 0x7d, 0x86, 0x9c, 0xab, 0x67, 0x16,
- 0x39, 0x17, 0xb9, 0x5c, 0xec, 0x41, 0xc5, 0x8b, 0x68, 0x21, 0x41, 0x5e,
- 0x21, 0xfc, 0x22, 0x8c, 0xa7, 0xf2, 0x1d, 0xb8, 0x25, 0xdd, 0x84, 0x71,
- 0xf2, 0xad, 0x1c, 0xf1, 0x22, 0x97, 0x67, 0x5c, 0x19, 0x6d, 0xe4, 0xa5,
- 0xf1, 0x5a, 0xc0, 0x4b, 0x77, 0xef, 0xad, 0xa5, 0x2d, 0x27, 0xbb, 0x25,
- 0x4f, 0x23, 0xff, 0xcd, 0x4b, 0xac, 0x56, 0x98, 0xb7, 0xfe, 0xaf, 0x7a,
- 0xc9, 0x4d, 0x83, 0xba, 0x82, 0xaf, 0x65, 0x35, 0xfc, 0x55, 0xfb, 0x76,
- 0x25, 0xd9, 0xe0, 0xbe, 0x83, 0x4a, 0xdf, 0xb6, 0x70, 0x92, 0x63, 0xba,
- 0x37, 0x2b, 0x76, 0x49, 0x19, 0xcc, 0xd1, 0x8f, 0x19, 0xf5, 0xd0, 0xea,
- 0x35, 0x39, 0xd7, 0xc4, 0xd8, 0xc1, 0xf8, 0x6b, 0xa7, 0xc8, 0xa3, 0x5a,
- 0xbb, 0x5b, 0x55, 0x8f, 0xbc, 0x9f, 0x67, 0x68, 0xaa, 0xf8, 0x58, 0x0a,
- 0x15, 0x69, 0xbf, 0x55, 0x27, 0xf5, 0x97, 0x6c, 0x60, 0x3c, 0x68, 0x5d,
- 0xff, 0xb2, 0xf0, 0xfb, 0x39, 0x11, 0x6d, 0x0a, 0x1b, 0xb0, 0xce, 0xd6,
- 0x19, 0x03, 0xd7, 0x38, 0xbd, 0x9c, 0x87, 0x51, 0x7b, 0x03, 0xee, 0xb2,
- 0x5b, 0xa7, 0x1e, 0xa7, 0x6d, 0xe1, 0xce, 0x0d, 0xe8, 0xe4, 0xb3, 0x91,
- 0x4c, 0xf3, 0x74, 0x2f, 0x75, 0x7d, 0x7c, 0x76, 0xcc, 0x5d, 0xf7, 0x97,
- 0x33, 0xe4, 0xa3, 0xe4, 0xd7, 0x5f, 0xcd, 0xb4, 0x26, 0x87, 0xd4, 0x1e,
- 0x05, 0x73, 0x24, 0x97, 0x4c, 0x90, 0x53, 0x05, 0xf0, 0x99, 0xb4, 0x45,
- 0x1f, 0x00, 0x6d, 0xae, 0x83, 0x79, 0xc5, 0x13, 0x4e, 0xbd, 0x19, 0x35,
- 0x44, 0x3f, 0xeb, 0x0b, 0x4b, 0xf1, 0x14, 0x63, 0x6f, 0xf3, 0xb5, 0x7a,
- 0xf0, 0x39, 0x68, 0xf0, 0x99, 0x3f, 0x75, 0x1a, 0xcc, 0x1a, 0x3c, 0x30,
- 0x12, 0x4d, 0xdc, 0xc4, 0x38, 0xdb, 0x79, 0xad, 0x7e, 0xf4, 0x14, 0x63,
- 0xe0, 0x7c, 0xd3, 0x96, 0xf3, 0x26, 0xe4, 0x3b, 0x01, 0xd7, 0xce, 0x4f,
- 0xdb, 0xe2, 0x27, 0x3a, 0x71, 0x33, 0x84, 0xcf, 0xd1, 0xce, 0xdf, 0xb7,
- 0x63, 0x98, 0x24, 0xdf, 0xf8, 0x2c, 0xfd, 0xe3, 0x8c, 0x1d, 0x49, 0x5d,
- 0xa3, 0xea, 0xd8, 0x40, 0xff, 0x78, 0xd7, 0x4e, 0xd0, 0x77, 0x3e, 0xc6,
- 0xab, 0x8d, 0xfe, 0x10, 0x63, 0x1d, 0x8d, 0x7e, 0x10, 0x72, 0xcf, 0x95,
- 0x8e, 0x65, 0x9a, 0xbb, 0x1f, 0x42, 0x73, 0xec, 0x66, 0xa5, 0x8e, 0x79,
- 0x6a, 0x10, 0xf7, 0x14, 0x6e, 0xc0, 0x89, 0x6c, 0x64, 0x9a, 0x39, 0xf9,
- 0xc6, 0xa5, 0x0a, 0xee, 0x20, 0x67, 0x5b, 0x5f, 0xad, 0xb4, 0x4e, 0x3d,
- 0xa5, 0x44, 0x68, 0x93, 0x8c, 0x97, 0xf4, 0xcf, 0xcf, 0xb2, 0xcc, 0x99,
- 0x6c, 0x35, 0x36, 0x8c, 0xd8, 0xe8, 0xcf, 0x54, 0xa0, 0x6a, 0xa7, 0x1f,
- 0xf7, 0x8f, 0xe9, 0xc8, 0x64, 0x64, 0x1d, 0xd9, 0x6f, 0xd5, 0x12, 0x37,
- 0x46, 0x89, 0x0d, 0x2f, 0x2d, 0x01, 0xa6, 0xf7, 0xae, 0xc1, 0x81, 0x9d,
- 0x3a, 0xe3, 0x5d, 0xd1, 0x3e, 0x82, 0x71, 0x97, 0x93, 0xa7, 0x84, 0x93,
- 0x57, 0x99, 0x12, 0xfb, 0xa2, 0x3d, 0x8f, 0x50, 0x07, 0xb7, 0x15, 0xc4,
- 0xee, 0x12, 0x9c, 0xa3, 0x30, 0x06, 0x69, 0x23, 0xfb, 0xec, 0x26, 0xe6,
- 0xe6, 0x01, 0x58, 0xb4, 0x11, 0x4b, 0xde, 0x53, 0xa5, 0x8d, 0x58, 0xb4,
- 0x11, 0x8b, 0x36, 0x62, 0xd1, 0x46, 0xac, 0xfc, 0x52, 0xe6, 0x4c, 0x3a,
- 0xc6, 0xd9, 0xe6, 0xb6, 0x51, 0x72, 0xf7, 0xa0, 0xd8, 0x4a, 0x0c, 0x5f,
- 0xcf, 0xf4, 0x2b, 0xda, 0x9d, 0x37, 0x60, 0x24, 0x7b, 0x23, 0x2f, 0x05,
- 0xb7, 0xd2, 0x56, 0x1e, 0xcd, 0x89, 0xed, 0xe9, 0xee, 0xef, 0xd3, 0x3c,
- 0x9b, 0xdf, 0x33, 0x1b, 0xd5, 0xe2, 0x03, 0x8c, 0x45, 0xee, 0x7d, 0x39,
- 0x73, 0xec, 0xc7, 0x68, 0xfe, 0x82, 0x5f, 0x7c, 0x4f, 0xce, 0xab, 0xb4,
- 0xcb, 0x6f, 0xc5, 0x74, 0x30, 0x0f, 0x90, 0x73, 0xee, 0x32, 0x4e, 0x19,
- 0x57, 0x71, 0x4c, 0x55, 0x83, 0x9b, 0xf0, 0xf5, 0x41, 0x9d, 0xb1, 0xca,
- 0xc0, 0x93, 0x39, 0x89, 0xe5, 0xe2, 0xdf, 0x32, 0x0f, 0xe2, 0xeb, 0x1e,
- 0xd4, 0xb4, 0x7b, 0x11, 0x70, 0xfd, 0xbc, 0x39, 0xbc, 0x43, 0xb1, 0xe9,
- 0x3b, 0xba, 0x9c, 0x03, 0x9d, 0x0a, 0xeb, 0x0d, 0x38, 0xbd, 0xbb, 0x1d,
- 0xff, 0x6d, 0xa7, 0x87, 0x3c, 0xc0, 0x59, 0xfa, 0x52, 0x5c, 0x4f, 0x4e,
- 0x2b, 0xd1, 0xd8, 0x2c, 0xa5, 0x1d, 0xf7, 0x90, 0xfb, 0x6f, 0x18, 0x8c,
- 0x74, 0x33, 0x66, 0x1b, 0xb7, 0x28, 0x4b, 0x51, 0xc5, 0x1c, 0xa0, 0x8d,
- 0x39, 0xc0, 0x83, 0xc4, 0x80, 0xaf, 0x66, 0xbc, 0x68, 0x59, 0x2c, 0xbf,
- 0x4d, 0xa6, 0xbb, 0x6b, 0x3b, 0x2f, 0x90, 0xa3, 0xce, 0x37, 0x3b, 0xe4,
- 0x2c, 0x8e, 0x72, 0xf6, 0xba, 0x29, 0x24, 0x28, 0x7f, 0xcc, 0xcd, 0x2f,
- 0x12, 0x38, 0x98, 0x27, 0x6e, 0x70, 0xdc, 0xaf, 0xb4, 0xfd, 0x84, 0xf9,
- 0xb0, 0x70, 0x7b, 0x13, 0x13, 0x39, 0x97, 0xff, 0x47, 0xea, 0x88, 0x19,
- 0xd9, 0x41, 0xbd, 0xcb, 0xaf, 0x9a, 0x78, 0x64, 0xaf, 0xf8, 0xb0, 0x89,
- 0xf6, 0x21, 0x3d, 0x7c, 0x9b, 0x1a, 0x0d, 0xae, 0xe3, 0xb3, 0x05, 0x9c,
- 0xcf, 0xc7, 0x33, 0x32, 0x8f, 0x1a, 0x5a, 0x18, 0x9b, 0xdf, 0x9c, 0xd0,
- 0xb1, 0x88, 0x71, 0xfa, 0x9d, 0x89, 0x18, 0x96, 0x32, 0x66, 0x3b, 0xcc,
- 0x1f, 0x12, 0x19, 0xf1, 0x45, 0xf2, 0x81, 0x09, 0x8d, 0x71, 0x56, 0xd6,
- 0x87, 0x9e, 0xc0, 0xd8, 0x6a, 0x0d, 0xfb, 0xdc, 0xf3, 0x7c, 0x7e, 0xab,
- 0x81, 0x58, 0xd9, 0x39, 0xe0, 0xc7, 0xa7, 0x87, 0x36, 0xe3, 0xf5, 0xc5,
- 0xc2, 0x95, 0xd6, 0x38, 0xa2, 0x9f, 0xc7, 0x29, 0x73, 0x8c, 0xbc, 0x78,
- 0x94, 0x79, 0xd7, 0xc2, 0x7d, 0x6b, 0xf0, 0xc9, 0x5d, 0x17, 0xf2, 0xb4,
- 0x33, 0x71, 0xeb, 0x6e, 0xda, 0xc4, 0xfa, 0x00, 0x6d, 0xa2, 0x96, 0x36,
- 0x61, 0x67, 0xa2, 0xc9, 0x02, 0x6d, 0x22, 0x46, 0xdc, 0xc8, 0x0e, 0x48,
- 0x39, 0xf7, 0x9d, 0x99, 0xbb, 0xe4, 0xdd, 0x65, 0x83, 0xbe, 0xb3, 0x75,
- 0xc0, 0xd9, 0xec, 0x65, 0xbc, 0x79, 0xa4, 0xa3, 0x89, 0xd8, 0x72, 0x23,
- 0xf6, 0x0c, 0x36, 0xa1, 0x85, 0x31, 0x63, 0x61, 0x1a, 0x77, 0x84, 0xa1,
- 0xce, 0x0f, 0x23, 0xb2, 0xe1, 0x1d, 0x44, 0xa7, 0xef, 0x56, 0x5a, 0x8f,
- 0xbe, 0xa8, 0x44, 0x36, 0xfe, 0x84, 0x36, 0x7c, 0x56, 0x91, 0xb6, 0x9b,
- 0x70, 0x35, 0xfd, 0xe4, 0x2a, 0xfa, 0x84, 0xc6, 0x5c, 0x52, 0x63, 0xdd,
- 0xfe, 0x41, 0x1f, 0xe6, 0x33, 0xd7, 0x93, 0xb3, 0xca, 0xb1, 0x31, 0x2f,
- 0xb2, 0x3b, 0xf5, 0xa9, 0x47, 0xd0, 0x08, 0x63, 0xec, 0x46, 0x6c, 0x1d,
- 0xd4, 0x10, 0xe5, 0xbd, 0xbe, 0x9d, 0x0b, 0xd0, 0x4c, 0xfb, 0xd6, 0xe8,
- 0xa7, 0xbd, 0x83, 0x2a, 0x16, 0x8c, 0xdd, 0x80, 0x1d, 0x83, 0x0a, 0xee,
- 0x8b, 0x2a, 0x68, 0x19, 0x91, 0x1c, 0x2c, 0x86, 0xa7, 0x32, 0xc2, 0x15,
- 0xa1, 0xb4, 0x5c, 0x4b, 0x8e, 0x4c, 0xee, 0xf9, 0x93, 0x9c, 0xcc, 0xb9,
- 0xe8, 0x53, 0x7e, 0x53, 0xa6, 0x1d, 0x9f, 0xdb, 0xd9, 0x80, 0xab, 0x76,
- 0xeb, 0xd6, 0x69, 0xc5, 0x59, 0x7a, 0x80, 0x7c, 0xde, 0xaf, 0x16, 0xe7,
- 0xfc, 0xc1, 0xc1, 0x67, 0x19, 0x2f, 0x7e, 0xe2, 0x04, 0xf5, 0xa5, 0xe8,
- 0x8b, 0x27, 0xb1, 0xb6, 0xa3, 0x1d, 0x6b, 0xf7, 0x8a, 0xbe, 0x1c, 0xe6,
- 0x87, 0xcc, 0xfd, 0x26, 0xa7, 0xf0, 0x0e, 0xfd, 0x77, 0x11, 0x39, 0xed,
- 0x52, 0xc6, 0x89, 0x37, 0x16, 0x9b, 0xd4, 0x9f, 0xee, 0x9e, 0xf5, 0x9b,
- 0x67, 0x9a, 0xa8, 0x1d, 0xd4, 0x19, 0x67, 0x4c, 0xcc, 0xda, 0x2b, 0xed,
- 0x99, 0xb8, 0x67, 0x50, 0x4f, 0x3d, 0xcd, 0xb9, 0x14, 0xbb, 0x11, 0xcc,
- 0xae, 0x61, 0xec, 0x3f, 0x39, 0x29, 0x38, 0xd5, 0x89, 0x13, 0xcc, 0x03,
- 0xde, 0x7c, 0x2c, 0xda, 0xfd, 0x33, 0xe6, 0x74, 0xef, 0x50, 0x46, 0x96,
- 0xfd, 0x1b, 0xe0, 0xbc, 0x56, 0xa4, 0xf5, 0x8d, 0xff, 0x8c, 0x28, 0xfd,
- 0xbb, 0x0b, 0xb5, 0xd4, 0xc9, 0x81, 0xc1, 0x95, 0xf0, 0xd3, 0x16, 0x1e,
- 0xc9, 0x88, 0xdd, 0x10, 0xbf, 0x77, 0x7e, 0x02, 0x5b, 0xf7, 0x17, 0xf3,
- 0xbc, 0x7b, 0x06, 0x36, 0xd1, 0xc6, 0x85, 0xb3, 0xc7, 0x68, 0xef, 0x98,
- 0xe7, 0x43, 0xb2, 0x9e, 0x18, 0x91, 0x58, 0x4e, 0xcc, 0x7c, 0xd4, 0x20,
- 0xae, 0xd6, 0x47, 0xc2, 0x2d, 0xaa, 0x95, 0x60, 0x5e, 0x17, 0xbe, 0x0f,
- 0xd2, 0xbe, 0x85, 0x75, 0x4b, 0x36, 0x61, 0x4f, 0xd6, 0x8b, 0xaa, 0xc5,
- 0x1e, 0xe2, 0xb1, 0x60, 0x94, 0x15, 0x94, 0xe7, 0x6b, 0x21, 0x7e, 0x22,
- 0xf3, 0xeb, 0xc1, 0x99, 0x78, 0xf3, 0x86, 0xac, 0xfc, 0x96, 0x05, 0x73,
- 0xbe, 0xcf, 0xa2, 0x83, 0x73, 0x2f, 0xfe, 0x98, 0xc0, 0x3d, 0x63, 0xc2,
- 0xd5, 0xc8, 0xe7, 0x6c, 0x3f, 0xfe, 0x3a, 0x2b, 0x9c, 0x6e, 0x33, 0xee,
- 0x69, 0x2f, 0xe7, 0x6e, 0x62, 0x77, 0xad, 0xd3, 0x1e, 0x34, 0x93, 0x93,
- 0xe9, 0xb9, 0xac, 0x1a, 0xb1, 0x52, 0x88, 0xf4, 0xa7, 0x20, 0x71, 0xa2,
- 0xd5, 0xe2, 0x0c, 0x53, 0x36, 0xb9, 0xa5, 0xed, 0x41, 0x1d, 0x7d, 0x5c,
- 0x7e, 0x44, 0xae, 0x9d, 0xf6, 0xf3, 0xac, 0x5d, 0x0d, 0xcd, 0xb5, 0x75,
- 0x2f, 0x96, 0x16, 0x2c, 0xe2, 0xed, 0x52, 0xb4, 0x3d, 0x16, 0xc0, 0x35,
- 0xe4, 0x26, 0x57, 0xa7, 0x9f, 0x70, 0x66, 0x11, 0x7b, 0xdb, 0x46, 0xa2,
- 0xc1, 0x23, 0xe4, 0x81, 0x07, 0x96, 0xfc, 0xd4, 0xf1, 0x98, 0xae, 0x5f,
- 0x68, 0xf4, 0x00, 0xe7, 0x33, 0x1d, 0xfa, 0xd4, 0x0e, 0x04, 0x90, 0x20,
- 0x7e, 0x5e, 0x99, 0x69, 0x40, 0xfb, 0xee, 0x7e, 0xce, 0x7f, 0x10, 0x57,
- 0xf2, 0xfb, 0x62, 0xc6, 0x37, 0x8d, 0xd8, 0xaa, 0xc9, 0xe7, 0x82, 0xd8,
- 0x4b, 0x98, 0x7e, 0xe4, 0x2c, 0xbd, 0xb3, 0xdd, 0xba, 0x63, 0x36, 0xf5,
- 0xd5, 0x42, 0x5c, 0x5e, 0x9a, 0x89, 0x6c, 0xbc, 0x59, 0x51, 0xb0, 0xb2,
- 0xdd, 0x60, 0xdb, 0x01, 0xc4, 0x32, 0xb2, 0x36, 0x70, 0xe8, 0xa1, 0x3a,
- 0x58, 0xad, 0x01, 0xda, 0xe9, 0x11, 0x45, 0xd6, 0x35, 0x44, 0x6f, 0x4d,
- 0xb8, 0x8a, 0x7c, 0x44, 0x23, 0x66, 0xc7, 0x0a, 0xa2, 0x43, 0x60, 0x6d,
- 0x6e, 0x0d, 0xf6, 0x0c, 0x8b, 0x7f, 0x0a, 0x76, 0x3a, 0x4e, 0xe5, 0xe2,
- 0xa8, 0xf1, 0x36, 0x75, 0xf8, 0xc6, 0x84, 0x60, 0x90, 0x82, 0x79, 0xb4,
- 0x63, 0x55, 0x97, 0x58, 0x2b, 0xb8, 0x15, 0xa6, 0xdf, 0x76, 0xe0, 0xd3,
- 0x8c, 0x6d, 0xd5, 0x9c, 0x83, 0x55, 0x4b, 0x9a, 0xe8, 0xbf, 0xc4, 0xc9,
- 0x89, 0x20, 0xaf, 0x10, 0x8e, 0xef, 0x6f, 0xe4, 0xa5, 0xf1, 0x5a, 0xc0,
- 0x4b, 0xe7, 0x3d, 0x15, 0x67, 0xf6, 0x93, 0x33, 0xed, 0x15, 0x0e, 0x22,
- 0x3e, 0xe8, 0xc7, 0xd3, 0x13, 0x20, 0x8f, 0x31, 0xc8, 0x43, 0x04, 0xff,
- 0x64, 0x9e, 0x98, 0xc7, 0x0c, 0xc6, 0x11, 0x1d, 0x29, 0x72, 0x8e, 0x93,
- 0xc3, 0x7a, 0xcf, 0x5a, 0x44, 0xb5, 0xbf, 0x26, 0x7e, 0x9d, 0x1a, 0x6d,
- 0xc7, 0x74, 0x96, 0xb8, 0xb5, 0xb8, 0x1d, 0x6f, 0xe7, 0x36, 0xd1, 0xff,
- 0x55, 0x9c, 0x25, 0x66, 0x69, 0x73, 0x05, 0xd7, 0x05, 0x43, 0xfd, 0xb4,
- 0xd7, 0x0e, 0x59, 0x03, 0x55, 0xe2, 0xc4, 0xac, 0x6b, 0xd2, 0xcf, 0x3a,
- 0xb5, 0x3a, 0x73, 0x2a, 0x35, 0x81, 0x0c, 0x31, 0xcb, 0xce, 0xca, 0x7c,
- 0x6d, 0xc6, 0x56, 0xe2, 0xd5, 0xd6, 0x9c, 0xd8, 0x37, 0x6d, 0x7a, 0x50,
- 0x0f, 0x16, 0x68, 0xdb, 0xea, 0x5e, 0x91, 0x61, 0xa2, 0x8f, 0xb1, 0xfd,
- 0x33, 0x1d, 0x26, 0x76, 0xe4, 0x24, 0x0e, 0x0a, 0x07, 0xd3, 0x98, 0x97,
- 0x24, 0xd1, 0x43, 0x9c, 0x7a, 0xdb, 0xee, 0xc4, 0x0a, 0xe2, 0xd4, 0x2f,
- 0x98, 0xa7, 0xdc, 0x49, 0x9c, 0x7a, 0xc3, 0x2e, 0xe2, 0xd4, 0xcd, 0x13,
- 0x62, 0x0b, 0x45, 0x5e, 0x7e, 0xc2, 0x6e, 0x6b, 0x90, 0xdf, 0x39, 0xab,
- 0x36, 0x7f, 0x57, 0x5c, 0x58, 0x85, 0x97, 0x86, 0xcb, 0x7b, 0xc5, 0x91,
- 0xe4, 0xed, 0xe4, 0xcc, 0x47, 0x47, 0xcb, 0x9c, 0xf7, 0xb8, 0x9b, 0x5b,
- 0xcf, 0x32, 0xcb, 0xfb, 0x96, 0xe5, 0xfd, 0x06, 0x0b, 0x5f, 0x5d, 0x22,
- 0x3c, 0x53, 0xd6, 0x81, 0x2a, 0xc8, 0x27, 0xbb, 0x31, 0xbe, 0xf3, 0x3d,
- 0x3c, 0x32, 0xa8, 0xde, 0x5c, 0xc3, 0xd8, 0x7a, 0x8b, 0xb2, 0x19, 0x9e,
- 0xb8, 0xbc, 0x47, 0x2a, 0x6b, 0xe5, 0xcc, 0x5d, 0x26, 0xb3, 0xe8, 0xdb,
- 0x57, 0x83, 0x43, 0x41, 0xc7, 0x79, 0xda, 0x98, 0x27, 0x3f, 0x13, 0x20,
- 0xb8, 0x19, 0xa8, 0xa0, 0x2f, 0xdc, 0xfc, 0x5b, 0xbf, 0xdd, 0x58, 0xde,
- 0x3b, 0xd8, 0x88, 0xbb, 0x76, 0x3d, 0x8c, 0x9e, 0x5d, 0x7f, 0x8b, 0x4f,
- 0x0e, 0x2d, 0xec, 0x9f, 0xe7, 0x71, 0x9c, 0xab, 0xdb, 0xa7, 0x70, 0x2a,
- 0xce, 0xd8, 0x18, 0x52, 0xf0, 0xbd, 0xab, 0x16, 0x8a, 0x1c, 0xfe, 0xbd,
- 0xef, 0x68, 0xae, 0xbc, 0x5b, 0x4b, 0x3e, 0x92, 0x98, 0xc3, 0xf1, 0x53,
- 0xf6, 0x8a, 0xfa, 0xd2, 0xbb, 0xc2, 0x7f, 0x40, 0x5b, 0x3f, 0x16, 0x19,
- 0xfc, 0x2b, 0xcb, 0x78, 0xcd, 0x49, 0xae, 0x96, 0x7a, 0x15, 0xa5, 0x36,
- 0xfe, 0x96, 0x9c, 0x90, 0xbc, 0xd0, 0xe0, 0xff, 0x91, 0xeb, 0x44, 0x3e,
- 0x9f, 0x95, 0xe5, 0xbf, 0xe4, 0x24, 0xbb, 0xe5, 0xbb, 0x94, 0x59, 0xc7,
- 0x67, 0x52, 0xae, 0xfc, 0xec, 0xf9, 0x92, 0x9c, 0x4a, 0x68, 0x0d, 0x45,
- 0x39, 0x9f, 0xa6, 0x9c, 0x33, 0x8b, 0x93, 0x50, 0xaf, 0x9d, 0x29, 0xab,
- 0xdc, 0xee, 0xff, 0x3a, 0x2f, 0xab, 0x58, 0xee, 0x6f, 0xe6, 0xc8, 0xbe,
- 0x80, 0x7a, 0xed, 0xcc, 0x75, 0xf2, 0x0a, 0xfa, 0x6f, 0x34, 0xb8, 0xd5,
- 0x5d, 0x9f, 0x36, 0xb0, 0xf6, 0xe2, 0x1c, 0x4b, 0xb0, 0x03, 0xe3, 0x76,
- 0xb0, 0x94, 0x53, 0xc9, 0x2d, 0x13, 0x5f, 0x66, 0xce, 0xf6, 0x94, 0x1d,
- 0xe9, 0x5a, 0xa7, 0xb4, 0x26, 0x17, 0x31, 0xce, 0xa0, 0x5e, 0xd6, 0xb0,
- 0x13, 0xee, 0xef, 0xf9, 0xe5, 0xa3, 0x09, 0xe4, 0x69, 0x8f, 0xaf, 0xd8,
- 0x91, 0x0d, 0xa7, 0xdc, 0xfd, 0x3b, 0x13, 0x2f, 0xe7, 0x5f, 0x2d, 0xed,
- 0x33, 0x95, 0x7f, 0x4f, 0x6c, 0xe6, 0x1a, 0xaa, 0xcc, 0xbf, 0x9c, 0xb1,
- 0x6e, 0x90, 0xb5, 0x0a, 0xcb, 0xa2, 0x9f, 0xf7, 0x66, 0xac, 0xb0, 0x8a,
- 0xeb, 0x90, 0x0a, 0xc9, 0xbe, 0xc4, 0xd6, 0xd2, 0x6f, 0x52, 0xb1, 0xde,
- 0xef, 0x58, 0x13, 0x02, 0x8c, 0xd2, 0x39, 0xb6, 0x18, 0xac, 0xc9, 0x2b,
- 0xc8, 0xc5, 0x64, 0xbd, 0x01, 0xd6, 0x6c, 0x53, 0x43, 0x48, 0x3f, 0xcc,
- 0x71, 0xfb, 0x30, 0x87, 0xf9, 0x54, 0x7c, 0x61, 0x6b, 0x77, 0xbb, 0x3a,
- 0x57, 0x70, 0x36, 0x98, 0x54, 0x63, 0x12, 0x07, 0x50, 0x99, 0x96, 0xb3,
- 0x26, 0x56, 0x97, 0x9f, 0x98, 0xba, 0x98, 0xd8, 0x52, 0x11, 0x85, 0xf7,
- 0xbe, 0xbc, 0x17, 0xc1, 0x85, 0xbf, 0x70, 0x7e, 0x18, 0x8a, 0x61, 0xdb,
- 0x64, 0xb9, 0x0f, 0x06, 0xfe, 0x7b, 0xe1, 0xd2, 0x8c, 0xb3, 0x2c, 0xf3,
- 0x3d, 0x27, 0x39, 0x47, 0xda, 0x2e, 0xca, 0xfd, 0xe8, 0xbe, 0x4a, 0x1f,
- 0xa5, 0xaf, 0xcd, 0x1a, 0x51, 0x15, 0x5b, 0x8d, 0x89, 0x39, 0xf2, 0x9b,
- 0x3f, 0xf7, 0xb8, 0x67, 0xd3, 0x65, 0x0e, 0xe4, 0xfd, 0xf1, 0x04, 0xee,
- 0x93, 0xf7, 0x30, 0x19, 0xb3, 0xee, 0xcd, 0xbb, 0xef, 0x77, 0x42, 0x7e,
- 0x17, 0xf1, 0xde, 0x7c, 0x51, 0x7f, 0x0f, 0xe5, 0x03, 0xe4, 0xdd, 0x01,
- 0xcb, 0x6b, 0x6e, 0x80, 0x4f, 0x97, 0x33, 0x67, 0x65, 0x5d, 0xfe, 0xdf,
- 0x73, 0x24, 0x97, 0xff, 0x2a, 0xfd, 0xc9, 0xbb, 0x50, 0x3e, 0x5b, 0xf2,
- 0xae, 0xa2, 0x52, 0xfc, 0x7c, 0xc6, 0x7d, 0xef, 0x5d, 0x35, 0xd7, 0xd1,
- 0x2f, 0x67, 0xbb, 0xef, 0xeb, 0x89, 0x7e, 0x42, 0xa6, 0xe5, 0xcc, 0xd6,
- 0x03, 0xb4, 0x91, 0xde, 0x39, 0xa5, 0x77, 0x0f, 0xba, 0xee, 0x20, 0x8e,
- 0x2c, 0x22, 0xb7, 0x5a, 0xac, 0x44, 0xb4, 0x55, 0x4a, 0x37, 0xeb, 0x51,
- 0x4f, 0x05, 0x91, 0xa1, 0xb8, 0xbf, 0xbd, 0xeb, 0xa3, 0x8c, 0xfd, 0x76,
- 0xab, 0xe6, 0x53, 0x7f, 0x5e, 0x3a, 0x7b, 0x2d, 0x7b, 0xf1, 0x29, 0x3c,
- 0x6f, 0xcf, 0xc1, 0xd4, 0x6f, 0xc9, 0x3d, 0xbf, 0x66, 0xfd, 0x4f, 0x41,
- 0x62, 0x88, 0x4f, 0x8f, 0x6c, 0x8c, 0x7b, 0x22, 0xeb, 0xa7, 0xe9, 0xd3,
- 0x85, 0xb8, 0x9e, 0xfa, 0x1a, 0xdb, 0xf8, 0x3e, 0xb9, 0x85, 0x3d, 0x43,
- 0x7e, 0x51, 0x56, 0x6b, 0x4f, 0x85, 0x7a, 0xc6, 0x29, 0xbe, 0x77, 0x2d,
- 0xbf, 0xfb, 0xbb, 0x06, 0xc1, 0xb4, 0xe5, 0x84, 0x28, 0x73, 0xbe, 0x19,
- 0xd9, 0x53, 0xaf, 0xea, 0xd9, 0xcf, 0xab, 0x9b, 0xb1, 0x56, 0x8e, 0x7c,
- 0x98, 0x11, 0xed, 0xd3, 0xb4, 0x8f, 0x76, 0x57, 0x46, 0x32, 0x56, 0x81,
- 0x8f, 0x3a, 0xd3, 0xc6, 0xf1, 0x41, 0xd6, 0x28, 0x59, 0xce, 0xdd, 0xe3,
- 0x97, 0xf7, 0x77, 0x98, 0x63, 0xdb, 0xf2, 0xbb, 0xa6, 0x6e, 0x33, 0xa5,
- 0x7d, 0x24, 0xe6, 0xc8, 0x8c, 0x97, 0xf7, 0xc8, 0x6f, 0xc8, 0x55, 0x07,
- 0x70, 0xaf, 0x2d, 0xeb, 0x0e, 0xff, 0x3f, 0x45, 0x18, 0xff, 0x64, 0x3c,
- 0x59, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
- 0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
- 0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
- 0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
- 0x00000001, 0x00000001, 0x00000001, 0x00000000 };
-static const u32 bnx2_CP_b09FwRodata[(0x16c/4) + 1] = {
- 0x80080100, 0x80080080, 0x80080000, 0x08001744, 0x08001744, 0x0800177c,
- 0x0800177c, 0x08001790, 0x08001760, 0x080019b8, 0x08001984, 0x08001a10,
- 0x08001a10, 0x08001a98, 0x080019c8, 0x80080240, 0x08003260, 0x080031cc,
- 0x08003288, 0x080032b0, 0x080032d8, 0x080032fc, 0x08003344, 0x08003320,
- 0x08003368, 0x08003234, 0x0800345c, 0x0800344c, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080033bc, 0x080033bc, 0x080031e8, 0x080031e8, 0x0800343c,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x0800342c, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x0800341c, 0x080031e8, 0x080031e8, 0x0800340c, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8,
- 0x080031e8, 0x080031e8, 0x080031e8, 0x080031e8, 0x080033f4, 0x080031e8,
- 0x080031e8, 0x080033e4, 0x080033d4, 0x08003d6c, 0x08003d40, 0x08003d0c,
- 0x08003ce0, 0x08003cc0, 0x08003c74, 0x80080100, 0x80080080, 0x80080000,
- 0x80080080, 0x00000000 };
-
-static struct fw_info bnx2_cp_fw_09 = {
- /* Firmware version: 4.4.23 */
- .ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
-
- .start_addr = 0x08000080,
-
- .text_addr = 0x08000000,
- .text_len = 0x5938,
- .text_index = 0x0,
- .gz_text = bnx2_CP_b09FwText,
- .gz_text_len = sizeof(bnx2_CP_b09FwText),
-
- .data_addr = 0x08005ac0,
- .data_len = 0x84,
- .data_index = 0x0,
- .data = bnx2_CP_b09FwData,
-
- .sbss_addr = 0x08005b44,
- .sbss_len = 0x91,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08005bd8,
- .bss_len = 0x19c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08005938,
- .rodata_len = 0x16c,
- .rodata_index = 0x0,
- .rodata = bnx2_CP_b09FwRodata,
-};
-
-static u8 bnx2_RXP_b09FwText[] = {
- 0xec, 0x5c, 0x7f, 0x70, 0x1c, 0xd5, 0x7d, 0xff, 0xbc, 0xbd, 0xbd, 0xbb,
- 0x95, 0x74, 0x3e, 0xed, 0x9d, 0x4e, 0xb2, 0x04, 0x06, 0xef, 0xa2, 0x95,
- 0x74, 0x58, 0xc6, 0xec, 0x9d, 0x4e, 0xb6, 0x48, 0xb7, 0xc9, 0xd5, 0x36,
- 0x20, 0x17, 0x52, 0x84, 0xa1, 0xc1, 0xcc, 0x30, 0x9d, 0x1b, 0x63, 0x8c,
- 0xb0, 0x1d, 0xa2, 0x00, 0x33, 0xc8, 0x29, 0x13, 0x16, 0xfc, 0xb3, 0xf8,
- 0xa4, 0x93, 0x8d, 0x8c, 0xc9, 0xf4, 0xd7, 0x21, 0xcb, 0x8a, 0x81, 0x93,
- 0xce, 0x04, 0xda, 0x98, 0x69, 0xa8, 0x15, 0x6c, 0x53, 0x87, 0x5f, 0x21,
- 0x19, 0x68, 0x4d, 0x9b, 0x99, 0xa8, 0x06, 0x1c, 0xd3, 0xa6, 0xd4, 0xb4,
- 0x0e, 0xb5, 0x8b, 0xeb, 0xd7, 0xef, 0x77, 0x4f, 0x97, 0x50, 0x42, 0xcb,
- 0x64, 0xa6, 0x7f, 0xee, 0x77, 0xe6, 0xe6, 0xf6, 0xde, 0xfb, 0xbe, 0xef,
- 0x7b, 0xdf, 0xdf, 0x9f, 0xb7, 0x1a, 0xfb, 0xbe, 0x08, 0x6a, 0x31, 0x4b,
- 0x73, 0xe8, 0x93, 0x19, 0x18, 0xbc, 0x27, 0xbd, 0x28, 0xb3, 0x88, 0x1e,
- 0xbb, 0x02, 0x73, 0x55, 0x95, 0xc7, 0x05, 0x7c, 0xf2, 0xc9, 0x27, 0x9f,
- 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2,
- 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27,
- 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c,
- 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xf2, 0xc9,
- 0x27, 0x9f, 0x7c, 0xf2, 0xc9, 0x27, 0x9f, 0x7c, 0xfa, 0xff, 0xa4, 0x00,
- 0xa0, 0xf3, 0xf7, 0x9c, 0xd9, 0x0f, 0x34, 0xc5, 0x71, 0x37, 0x2e, 0xb5,
- 0xa0, 0x05, 0x9c, 0x33, 0x1b, 0x6f, 0xb7, 0x80, 0x6c, 0xa9, 0xd3, 0x58,
- 0x86, 0xff, 0x92, 0x6e, 0x42, 0x05, 0x8f, 0x5f, 0xe2, 0x9c, 0xff, 0xf3,
- 0x17, 0x96, 0x98, 0xa7, 0x8b, 0x01, 0x68, 0xba, 0xf3, 0x46, 0x4a, 0x6f,
- 0x87, 0x36, 0x8f, 0xd6, 0xfc, 0x49, 0xc7, 0x95, 0x71, 0x44, 0xab, 0xb2,
- 0xe0, 0x2a, 0x8e, 0x94, 0xfb, 0x6c, 0x89, 0x97, 0x6c, 0x57, 0xf4, 0x66,
- 0xe0, 0x06, 0x9c, 0x83, 0xe2, 0xae, 0xfc, 0x05, 0x69, 0x04, 0x2b, 0x3b,
- 0xab, 0x93, 0x1a, 0x82, 0xfb, 0xa0, 0xab, 0x8e, 0x82, 0xa0, 0x55, 0x8b,
- 0xd0, 0x13, 0x75, 0x08, 0x3e, 0xd1, 0x8c, 0xf0, 0xe4, 0x01, 0x91, 0x2b,
- 0x6a, 0x98, 0x09, 0x1c, 0x14, 0x6b, 0x4a, 0xc8, 0x05, 0x9d, 0xb3, 0x37,
- 0x8c, 0xd1, 0xba, 0xac, 0xf7, 0xef, 0x4b, 0xa6, 0x6f, 0x18, 0x2f, 0x41,
- 0x0f, 0x38, 0x50, 0x54, 0xe7, 0x08, 0x3d, 0x33, 0xdf, 0xd9, 0x1b, 0xf6,
- 0x96, 0x4e, 0xc9, 0x17, 0x3a, 0x12, 0x38, 0x54, 0xd6, 0x71, 0xa0, 0xfc,
- 0x10, 0x9d, 0xc3, 0x74, 0x5d, 0x68, 0xae, 0xea, 0xb8, 0xd8, 0x92, 0x09,
- 0x62, 0x62, 0xe4, 0x82, 0x0c, 0x58, 0xa6, 0x01, 0xc5, 0xd2, 0x0f, 0x83,
- 0xf8, 0x0a, 0xc4, 0x57, 0x08, 0x62, 0xac, 0xb8, 0x23, 0x8e, 0xda, 0x66,
- 0xbc, 0xd0, 0xc1, 0xeb, 0x79, 0x2d, 0xcb, 0xf8, 0x38, 0x5a, 0x5d, 0x1f,
- 0xa2, 0xf5, 0x47, 0x33, 0xc0, 0xf8, 0x48, 0x1f, 0x2d, 0x95, 0xd8, 0x64,
- 0x87, 0xb1, 0x5a, 0x87, 0x5b, 0xe3, 0xb0, 0xac, 0xaa, 0x1c, 0x57, 0x18,
- 0x93, 0xff, 0x5c, 0x5f, 0x91, 0x03, 0xa1, 0x59, 0x70, 0xc3, 0x9f, 0x9a,
- 0x3f, 0x55, 0xaa, 0xce, 0x6f, 0xa7, 0x7d, 0x34, 0x9a, 0xef, 0xc7, 0x5f,
- 0x96, 0xd7, 0xe0, 0x2f, 0xca, 0xb7, 0xe1, 0xd9, 0x72, 0x1f, 0xed, 0x7b,
- 0x1f, 0xed, 0x3b, 0x80, 0xbf, 0x2e, 0x6f, 0xc0, 0x77, 0xcb, 0x39, 0x3c,
- 0x57, 0x5e, 0x85, 0xef, 0x94, 0x6f, 0xc6, 0x33, 0x65, 0x78, 0x67, 0x38,
- 0x95, 0x49, 0x8a, 0x1f, 0xe5, 0x6b, 0xa0, 0xee, 0xdc, 0x8c, 0xe9, 0x52,
- 0x10, 0xc1, 0x9d, 0x12, 0x23, 0xb6, 0xf9, 0x38, 0xd0, 0xa1, 0x07, 0x21,
- 0xb0, 0xcc, 0x36, 0xf7, 0x03, 0x5f, 0x40, 0x2e, 0x61, 0x1e, 0x00, 0x9a,
- 0xc4, 0x8f, 0x47, 0x9b, 0xc4, 0x6b, 0xa3, 0xaa, 0x78, 0x3d, 0x2f, 0x50,
- 0xef, 0x20, 0xf2, 0x72, 0x46, 0xca, 0xeb, 0xd2, 0x52, 0x96, 0x52, 0x56,
- 0xef, 0x0f, 0x85, 0x69, 0x3f, 0x22, 0x2e, 0x85, 0xd1, 0x68, 0x66, 0xd7,
- 0x09, 0xcd, 0xad, 0x25, 0xf9, 0x2b, 0xba, 0x01, 0x6b, 0xa7, 0x41, 0x7e,
- 0x60, 0x1d, 0x37, 0xe1, 0x0e, 0x2f, 0x26, 0xfa, 0xd0, 0x60, 0x2d, 0xc5,
- 0xbd, 0x7d, 0x36, 0x8a, 0x65, 0x68, 0x31, 0xe7, 0x0c, 0x52, 0xc3, 0x02,
- 0x36, 0xf9, 0x5b, 0xd0, 0xb3, 0x5d, 0x5a, 0xdf, 0x50, 0xf1, 0x37, 0x9d,
- 0xbd, 0x40, 0x67, 0x2f, 0xd0, 0xd9, 0x0b, 0xa4, 0x57, 0x81, 0xf4, 0x2a,
- 0x90, 0x0e, 0x05, 0xd2, 0xad, 0x40, 0x7a, 0x14, 0x48, 0x8f, 0x02, 0xe9,
- 0x58, 0x60, 0x5f, 0x0d, 0x92, 0x0d, 0x22, 0xf8, 0xbb, 0xfc, 0x3c, 0x9c,
- 0xe1, 0xcf, 0x4a, 0x1d, 0xc7, 0xe9, 0x8c, 0x8a, 0xf5, 0x9b, 0xca, 0xf8,
- 0x6e, 0x84, 0x7c, 0x64, 0xfc, 0xe6, 0x7b, 0x2f, 0xc4, 0xc9, 0xfc, 0xbb,
- 0x32, 0x34, 0x97, 0xf7, 0xfc, 0x22, 0xe4, 0x28, 0x70, 0xe9, 0x6e, 0x29,
- 0xcf, 0x75, 0xcd, 0xc8, 0xb7, 0x6f, 0x61, 0x59, 0x0e, 0x4e, 0x8c, 0x2a,
- 0x08, 0xd0, 0xd8, 0xb5, 0xf6, 0xdf, 0xcb, 0x3b, 0x13, 0xcc, 0xf7, 0x51,
- 0x04, 0xb5, 0x6c, 0x27, 0x68, 0x0d, 0xce, 0xbb, 0x1b, 0xef, 0x6d, 0x87,
- 0x1b, 0x75, 0x54, 0xf1, 0xe6, 0x90, 0x81, 0xb9, 0x4e, 0x16, 0x73, 0x1c,
- 0x6b, 0x64, 0x8f, 0xd2, 0x39, 0x18, 0x47, 0xf6, 0xf2, 0x7a, 0xd8, 0xd8,
- 0x57, 0x56, 0xc5, 0xab, 0x43, 0x73, 0x10, 0xdf, 0x69, 0xad, 0x1a, 0x12,
- 0x0a, 0x72, 0x8d, 0x59, 0x8c, 0x67, 0x4c, 0xa3, 0x08, 0x03, 0xab, 0xd2,
- 0x0a, 0x30, 0xd7, 0xc5, 0xd6, 0x8c, 0x69, 0xbb, 0x78, 0x08, 0xd3, 0x09,
- 0x1b, 0x13, 0x65, 0x8d, 0x72, 0xc3, 0xc5, 0x9d, 0x19, 0x0d, 0x72, 0x24,
- 0x8b, 0x93, 0x5d, 0x21, 0x4c, 0xf7, 0x71, 0x8c, 0xa8, 0xb4, 0xf7, 0x56,
- 0x28, 0xf1, 0x38, 0xf9, 0xe5, 0xb0, 0x0c, 0xc6, 0x79, 0x0c, 0xe2, 0x5f,
- 0x32, 0xbc, 0xff, 0x45, 0xe2, 0xd5, 0xdd, 0x51, 0xd4, 0xee, 0xd6, 0xf0,
- 0xf4, 0x4e, 0x15, 0x2b, 0xc8, 0xb7, 0x7b, 0x52, 0xaa, 0xb1, 0x4e, 0x38,
- 0x18, 0x2f, 0xab, 0x48, 0x0c, 0xb5, 0xc0, 0x88, 0x69, 0xb8, 0x74, 0xc8,
- 0xc5, 0x3b, 0x24, 0x77, 0x90, 0xe4, 0xd6, 0x77, 0xe9, 0x98, 0x69, 0xac,
- 0xf8, 0xf5, 0xeb, 0xf9, 0x56, 0x77, 0xa7, 0x12, 0x02, 0x42, 0x70, 0x35,
- 0x27, 0x83, 0xfb, 0xf3, 0xad, 0xa4, 0xc3, 0xad, 0x58, 0x1a, 0xd2, 0xb0,
- 0x7a, 0x98, 0xc7, 0x96, 0x03, 0x93, 0x73, 0xe7, 0xa0, 0x96, 0xf5, 0xe7,
- 0x7c, 0x5e, 0x4a, 0xcf, 0x1c, 0x07, 0xbf, 0x9d, 0x60, 0xbb, 0xbb, 0xca,
- 0x7f, 0xc8, 0x6c, 0x82, 0xf9, 0x2a, 0x39, 0x72, 0x38, 0x93, 0xc1, 0xc6,
- 0x7c, 0x6b, 0xf6, 0x5b, 0x4a, 0x03, 0x10, 0x34, 0x0d, 0x43, 0x81, 0x96,
- 0x70, 0x90, 0x1a, 0xa5, 0x78, 0x79, 0xd4, 0x8b, 0x17, 0xa4, 0xba, 0x4a,
- 0x9c, 0x97, 0x9a, 0xab, 0x13, 0xff, 0xfc, 0xc5, 0x6d, 0xf8, 0xe8, 0x51,
- 0xe6, 0x53, 0xf1, 0x03, 0x7a, 0x7e, 0x7f, 0xef, 0x8e, 0xd9, 0xda, 0xf1,
- 0xa7, 0x9e, 0x5f, 0x0d, 0xa5, 0xba, 0xb7, 0x8d, 0x3b, 0xf3, 0xad, 0x67,
- 0xb7, 0x29, 0xe4, 0xbf, 0x8b, 0x23, 0xa8, 0xa1, 0xfa, 0x13, 0x24, 0x59,
- 0xfb, 0xf2, 0xe7, 0xb1, 0x32, 0x6d, 0x1e, 0xe4, 0x7f, 0x6f, 0x36, 0x66,
- 0x55, 0xe4, 0x5f, 0x56, 0xb2, 0xf1, 0x64, 0xd9, 0xc6, 0xed, 0x74, 0x8e,
- 0xfb, 0xf0, 0x8f, 0x40, 0xcb, 0x02, 0xe3, 0x94, 0x72, 0x42, 0xba, 0x37,
- 0xb3, 0xbc, 0x79, 0x38, 0x15, 0x6f, 0xcd, 0x9d, 0x52, 0xcc, 0xe2, 0x76,
- 0x85, 0x6d, 0xa5, 0xe0, 0xcb, 0xe9, 0x0c, 0x8a, 0x31, 0x1d, 0xb7, 0xa6,
- 0x35, 0xf7, 0x52, 0x3a, 0xd3, 0x1b, 0x4b, 0x34, 0x34, 0xed, 0xca, 0xe2,
- 0xad, 0xf4, 0x9b, 0x28, 0xae, 0x64, 0x3b, 0xf0, 0x3a, 0x3e, 0x73, 0x33,
- 0xe2, 0x56, 0x0d, 0xe2, 0x63, 0x41, 0xd4, 0xef, 0xba, 0x20, 0x9b, 0x2d,
- 0x1e, 0xb7, 0x06, 0xce, 0x0a, 0x3e, 0x73, 0x10, 0xd1, 0xb1, 0xab, 0xa0,
- 0x5a, 0x66, 0x92, 0x1c, 0x9b, 0x60, 0xde, 0x90, 0x55, 0x3d, 0xbb, 0xc0,
- 0x75, 0x5f, 0x10, 0x58, 0x97, 0xfa, 0xbe, 0xcc, 0x36, 0xf2, 0x9a, 0x67,
- 0x68, 0x9c, 0xcf, 0x50, 0x73, 0x36, 0x8b, 0x26, 0x5a, 0x53, 0xe5, 0x8b,
- 0xa0, 0x7f, 0x57, 0xe5, 0x0c, 0x6f, 0x2f, 0xc1, 0xb3, 0x1a, 0x7a, 0xd0,
- 0x51, 0x78, 0x08, 0x6f, 0x2d, 0xf6, 0xf6, 0x3f, 0xbd, 0x2f, 0xbd, 0x83,
- 0x6c, 0xc2, 0x75, 0xf4, 0xd3, 0x7e, 0xe1, 0xf9, 0xff, 0x64, 0x7f, 0x24,
- 0x21, 0x9a, 0x69, 0x8c, 0xe3, 0x77, 0xa7, 0x34, 0x6e, 0xaa, 0xf8, 0x25,
- 0x4c, 0xf2, 0xde, 0xcf, 0xf4, 0xa0, 0x75, 0x48, 0x85, 0xcc, 0xb7, 0xda,
- 0x3f, 0x0d, 0x3c, 0x22, 0xa7, 0x6f, 0xe3, 0xb9, 0x56, 0xfd, 0x70, 0x40,
- 0x60, 0xa9, 0x6a, 0x9e, 0xce, 0xa1, 0x19, 0xfb, 0xa9, 0xc6, 0xb4, 0x38,
- 0x3a, 0xd5, 0x9c, 0x04, 0xd5, 0x1e, 0x43, 0x74, 0xec, 0xb1, 0xb1, 0x60,
- 0xe8, 0x36, 0x7c, 0x69, 0xb7, 0x83, 0x83, 0x05, 0x1b, 0x4f, 0x17, 0xa4,
- 0x3c, 0x69, 0x4b, 0xf9, 0xaf, 0x5d, 0x66, 0xff, 0x31, 0x6a, 0x07, 0x8b,
- 0x96, 0x74, 0xe6, 0xea, 0x03, 0x2a, 0xd9, 0xa7, 0xcd, 0xd8, 0x20, 0xcc,
- 0xe6, 0x29, 0x61, 0x53, 0xcc, 0xf5, 0x92, 0xed, 0x0d, 0xec, 0x2d, 0x27,
- 0xf1, 0x54, 0xd9, 0xa2, 0xcf, 0x42, 0x8a, 0x95, 0x0c, 0xd5, 0x33, 0xd6,
- 0x55, 0xc7, 0x78, 0x07, 0xe5, 0x45, 0x41, 0xc1, 0x7e, 0x9b, 0xe2, 0x3f,
- 0x46, 0xbc, 0x85, 0x0b, 0xe4, 0x3f, 0x0d, 0xc9, 0x9d, 0x59, 0xd4, 0xa4,
- 0x1a, 0x60, 0xdc, 0x68, 0x61, 0xbc, 0xa0, 0xb9, 0x41, 0x8a, 0xf9, 0xb1,
- 0xfc, 0x38, 0xfe, 0x40, 0x4f, 0xa0, 0x96, 0xec, 0xb7, 0x2a, 0x1d, 0x01,
- 0x6e, 0xe2, 0xb9, 0x08, 0x5a, 0xac, 0xef, 0xa3, 0x25, 0x3e, 0x07, 0xa1,
- 0x05, 0x7f, 0x85, 0x69, 0x3d, 0x8a, 0x30, 0xf5, 0x8c, 0xf9, 0xc4, 0x33,
- 0x9f, 0x7c, 0xd5, 0x68, 0x59, 0x24, 0x53, 0xc0, 0x6a, 0x23, 0x5e, 0xca,
- 0xa7, 0x66, 0xd2, 0x3d, 0xb8, 0x24, 0x81, 0x32, 0x9d, 0x7f, 0x2a, 0x2f,
- 0x65, 0x24, 0x63, 0xf6, 0x17, 0x28, 0x37, 0x27, 0x4b, 0x3d, 0x98, 0x2a,
- 0xff, 0x1e, 0xd5, 0x73, 0x1b, 0x7b, 0xf3, 0x0e, 0xc6, 0x0a, 0xea, 0xaa,
- 0x3c, 0xcc, 0xbe, 0xf5, 0xc8, 0xe0, 0x29, 0x8a, 0x9f, 0x89, 0x82, 0x69,
- 0xbc, 0x18, 0xd0, 0x70, 0xcc, 0xae, 0xa3, 0x73, 0x52, 0xde, 0x92, 0x4e,
- 0xcf, 0xe7, 0x47, 0x60, 0x35, 0xb0, 0xfd, 0xd9, 0x4f, 0x19, 0x7c, 0xbb,
- 0xe0, 0xc5, 0xf7, 0x75, 0x1a, 0x5c, 0xd8, 0xdd, 0xec, 0x1b, 0xf7, 0x74,
- 0x30, 0x5d, 0xa9, 0xa3, 0x7d, 0xdd, 0x36, 0xc2, 0xc3, 0x3d, 0x24, 0xb7,
- 0xd5, 0x3e, 0x81, 0x3b, 0x30, 0xdd, 0xec, 0x62, 0x11, 0xc5, 0xbf, 0xea,
- 0x3c, 0x9e, 0xda, 0x9c, 0x77, 0x65, 0xbd, 0x65, 0xf5, 0xff, 0x50, 0x3c,
- 0x88, 0x57, 0x53, 0x5c, 0xd7, 0x55, 0xca, 0x7b, 0x1d, 0x3b, 0xec, 0x11,
- 0xbc, 0x56, 0xfa, 0x2d, 0xe4, 0x62, 0x66, 0x72, 0x93, 0x58, 0x8f, 0x83,
- 0x23, 0x57, 0x01, 0xb7, 0x70, 0x9e, 0x90, 0x6e, 0xd6, 0x7a, 0x1c, 0x2a,
- 0x7e, 0x03, 0x47, 0x47, 0x6b, 0xf1, 0xbc, 0x15, 0x47, 0xcb, 0x44, 0x65,
- 0x9f, 0xab, 0xbb, 0x35, 0x8c, 0x51, 0x4e, 0x5f, 0x6b, 0xab, 0x98, 0x49,
- 0x70, 0xfd, 0xa0, 0x58, 0x4b, 0x6f, 0xa0, 0x5a, 0xe3, 0xb5, 0x5e, 0xac,
- 0xc9, 0x18, 0xc8, 0xe7, 0xb3, 0x54, 0xff, 0x6a, 0xb0, 0x2b, 0x06, 0x71,
- 0x3b, 0xf5, 0xb0, 0xbb, 0xf3, 0xad, 0xfd, 0xc3, 0x4a, 0x1c, 0xc5, 0x96,
- 0x2c, 0xf9, 0x42, 0xa0, 0xc9, 0x32, 0xb0, 0xa5, 0x44, 0x15, 0xb4, 0xa4,
- 0xe2, 0x9b, 0xa5, 0x2b, 0x50, 0x6c, 0xe2, 0xb5, 0x1d, 0x98, 0xf6, 0xbe,
- 0x83, 0x98, 0x89, 0x9b, 0xcd, 0x20, 0x9b, 0x8d, 0x17, 0x54, 0xec, 0xb6,
- 0xf7, 0x5c, 0x28, 0xae, 0x34, 0xf5, 0x1c, 0xe5, 0x5b, 0xc0, 0x8b, 0x5b,
- 0x7e, 0x06, 0xbe, 0x96, 0xff, 0x50, 0x9e, 0xf1, 0xf6, 0x54, 0x39, 0xff,
- 0xa7, 0xdf, 0x0e, 0xbc, 0x2f, 0x45, 0x98, 0xe5, 0xdf, 0x1f, 0xad, 0xfc,
- 0x5b, 0xd1, 0x67, 0x99, 0x37, 0x0b, 0x70, 0x1c, 0xcc, 0xfd, 0x44, 0xcc,
- 0x57, 0xea, 0x80, 0xbe, 0x98, 0xcf, 0x51, 0xcd, 0xb3, 0x38, 0x9a, 0x26,
- 0xda, 0x50, 0xb3, 0x8b, 0x7f, 0xf3, 0xb8, 0xc0, 0x65, 0xdd, 0x9c, 0x63,
- 0x6d, 0x50, 0xc6, 0x56, 0x47, 0x2b, 0x35, 0xb8, 0x5a, 0x1f, 0xfe, 0x70,
- 0x56, 0xbe, 0xd7, 0xeb, 0xe9, 0x77, 0xa5, 0x86, 0x7e, 0x33, 0xc3, 0xcf,
- 0xbc, 0xa6, 0x06, 0x6f, 0xed, 0x35, 0xed, 0xa2, 0xb2, 0x84, 0xf7, 0xac,
- 0xe4, 0x08, 0x36, 0xce, 0xae, 0xa1, 0x98, 0x2f, 0x4c, 0x49, 0xdc, 0xca,
- 0xf2, 0xaa, 0xeb, 0xdb, 0x10, 0xfa, 0xe5, 0xbe, 0x2a, 0x5e, 0xcc, 0x7c,
- 0x7a, 0xdf, 0xdb, 0x64, 0xed, 0xca, 0x38, 0xc5, 0x59, 0x23, 0xd4, 0x05,
- 0xd4, 0xe0, 0xf5, 0x26, 0xd4, 0x51, 0xde, 0x06, 0xac, 0x5b, 0x64, 0xe0,
- 0x2b, 0x1c, 0xa7, 0x9a, 0x1b, 0x71, 0x2e, 0xc6, 0xf0, 0xce, 0x17, 0xc8,
- 0xc7, 0x51, 0x8e, 0x47, 0xf2, 0xf3, 0xc5, 0x18, 0x7a, 0xe2, 0x92, 0x28,
- 0xeb, 0xbb, 0x2a, 0x0d, 0x77, 0x3e, 0xd5, 0xec, 0xf7, 0xf6, 0xdc, 0x2d,
- 0x8b, 0x7d, 0x3a, 0x5e, 0xca, 0xfc, 0x0e, 0x8d, 0x73, 0x3c, 0xd9, 0x78,
- 0x2e, 0xaf, 0xe1, 0xfe, 0xe1, 0x66, 0x3a, 0x27, 0xd7, 0xca, 0x9a, 0xb3,
- 0x33, 0x8a, 0x8d, 0x67, 0x29, 0x16, 0x9f, 0x29, 0xb0, 0xad, 0x54, 0x5c,
- 0x96, 0x5e, 0x21, 0xc3, 0x4d, 0x1c, 0xdf, 0x49, 0x5a, 0xa3, 0x93, 0xec,
- 0x28, 0x74, 0x6b, 0x99, 0x3c, 0xb0, 0x92, 0x9f, 0x3b, 0x68, 0xac, 0x89,
- 0xbe, 0xbb, 0x65, 0xdd, 0xaf, 0x9d, 0x43, 0xff, 0xac, 0x73, 0x50, 0xdc,
- 0x9b, 0xf6, 0x5a, 0x74, 0x12, 0x0e, 0x52, 0x91, 0xa5, 0x3e, 0x3f, 0x41,
- 0x31, 0xb0, 0x8d, 0x7a, 0xf0, 0x7b, 0x84, 0xf5, 0xb6, 0x78, 0x78, 0xca,
- 0x83, 0x67, 0x1e, 0x5e, 0x5b, 0x5d, 0xc1, 0x5d, 0x9a, 0x6a, 0x31, 0x16,
- 0xab, 0xce, 0x71, 0x9e, 0xf6, 0x62, 0x6c, 0x54, 0xca, 0xcd, 0x76, 0x0b,
- 0xc9, 0x88, 0x63, 0xb3, 0x45, 0x39, 0x3d, 0xca, 0x6b, 0xa4, 0x4c, 0xa6,
- 0x16, 0xf4, 0xa8, 0xa2, 0x01, 0x33, 0xba, 0x2b, 0xd6, 0x66, 0x0c, 0xf1,
- 0xd5, 0x51, 0x15, 0xf9, 0xc2, 0x45, 0x64, 0x2f, 0x29, 0x9f, 0x4a, 0x21,
- 0xbb, 0x29, 0x55, 0x87, 0x57, 0x8a, 0x3a, 0x72, 0xfa, 0x05, 0xb9, 0xbc,
- 0xad, 0x17, 0x65, 0x92, 0xf3, 0x41, 0xaa, 0x33, 0x79, 0x44, 0x44, 0x50,
- 0x4c, 0x44, 0xf0, 0x78, 0x21, 0x81, 0x23, 0xe3, 0x11, 0x6c, 0xa5, 0x18,
- 0x7d, 0x31, 0xc3, 0x7b, 0x46, 0xf0, 0x70, 0x99, 0x31, 0x55, 0x80, 0x6c,
- 0xe4, 0x8a, 0x13, 0xde, 0x58, 0x1d, 0x96, 0x17, 0x99, 0xf7, 0x82, 0x6c,
- 0xb1, 0x2c, 0xbd, 0x25, 0x50, 0xe5, 0x3b, 0x4e, 0xf8, 0xca, 0xa0, 0x5a,
- 0x36, 0x8f, 0x70, 0x55, 0x33, 0x61, 0xa8, 0x04, 0x61, 0x28, 0x6b, 0x16,
- 0x17, 0x9a, 0x94, 0x8d, 0x52, 0x3e, 0x4b, 0xb5, 0xec, 0xc7, 0xf4, 0x39,
- 0x43, 0xf5, 0x34, 0x46, 0x3a, 0x5e, 0x36, 0xcc, 0x3a, 0xba, 0xc2, 0xa6,
- 0x7a, 0x9b, 0x55, 0x94, 0x7a, 0xee, 0x43, 0x81, 0x29, 0xde, 0x5f, 0xc5,
- 0x96, 0x02, 0xb0, 0xa9, 0x00, 0xf7, 0x08, 0xe5, 0x7e, 0xc3, 0x44, 0x14,
- 0xf1, 0x09, 0x1d, 0xc1, 0x89, 0x24, 0xcd, 0x6b, 0x48, 0xd0, 0x6f, 0x97,
- 0xb0, 0x60, 0xbd, 0xd3, 0x24, 0x16, 0x3e, 0x76, 0x5e, 0xee, 0x48, 0xa9,
- 0x58, 0xd7, 0x66, 0xf6, 0xde, 0x28, 0x90, 0x4d, 0x0e, 0x49, 0x19, 0x4e,
- 0x85, 0x29, 0x37, 0xe5, 0xa1, 0x04, 0xe9, 0x1d, 0x75, 0xe4, 0x83, 0xaf,
- 0x75, 0x5b, 0xf6, 0x6b, 0x20, 0xb9, 0x65, 0x5e, 0xc3, 0xe3, 0xae, 0xf8,
- 0xb0, 0xdb, 0x7a, 0xfc, 0x4d, 0xb4, 0xa3, 0x6b, 0x42, 0x15, 0xff, 0x36,
- 0xb4, 0x10, 0xe9, 0x29, 0xe8, 0x21, 0xe7, 0x80, 0x98, 0x79, 0xe2, 0xa0,
- 0x38, 0x39, 0x49, 0xe7, 0x2e, 0x90, 0x2e, 0x05, 0xd2, 0xa5, 0x40, 0xba,
- 0x90, 0x5d, 0x9e, 0xf1, 0xf0, 0x24, 0xeb, 0x9a, 0x24, 0x2c, 0x73, 0xdc,
- 0xc3, 0xbc, 0x8c, 0x11, 0x63, 0x8e, 0x99, 0x75, 0xc1, 0x7a, 0xb3, 0x9e,
- 0x52, 0xbe, 0x69, 0x57, 0xf4, 0x71, 0xa9, 0xdc, 0x6a, 0x53, 0x55, 0x5b,
- 0x48, 0xf9, 0xef, 0x36, 0xdb, 0x82, 0x75, 0x94, 0xf2, 0x3b, 0xa4, 0xd3,
- 0x16, 0xd2, 0x71, 0x53, 0x41, 0x1e, 0x0a, 0x59, 0x96, 0x31, 0x41, 0x67,
- 0x8b, 0x93, 0x4e, 0x89, 0x09, 0x8d, 0x74, 0x6d, 0x87, 0x4a, 0xba, 0x06,
- 0x26, 0xa0, 0x2b, 0x74, 0x1e, 0x63, 0x8c, 0xec, 0x34, 0xf5, 0x79, 0xe7,
- 0x61, 0xcc, 0xef, 0x8a, 0xab, 0x09, 0x9f, 0xa8, 0x64, 0xd7, 0x4d, 0x14,
- 0x3b, 0x39, 0x15, 0x46, 0xd8, 0x52, 0xa8, 0x27, 0x6a, 0xf8, 0xf6, 0x78,
- 0x1d, 0x26, 0xc8, 0xef, 0xc5, 0x71, 0xe8, 0x41, 0x92, 0xe9, 0x16, 0x0f,
- 0x8a, 0x4f, 0xc6, 0x5b, 0xd0, 0x19, 0x20, 0x9c, 0x04, 0x3c, 0x92, 0x8f,
- 0x8b, 0x89, 0x11, 0x15, 0x9b, 0x0b, 0xa7, 0x49, 0x3f, 0x89, 0xc3, 0xf6,
- 0xc3, 0xcd, 0xc4, 0x22, 0x1e, 0xb6, 0xcd, 0x1e, 0xe0, 0x2a, 0x8a, 0xb7,
- 0x00, 0xd6, 0x5a, 0xc8, 0x6e, 0xb3, 0xaf, 0xc2, 0x4c, 0x1f, 0x8c, 0xed,
- 0xb6, 0xab, 0x87, 0x60, 0x1e, 0xbb, 0x9a, 0x7a, 0xd3, 0x95, 0xa4, 0xcf,
- 0xa0, 0xe5, 0x0e, 0x50, 0xe1, 0x42, 0xb9, 0x6c, 0xf6, 0x1f, 0x25, 0x5f,
- 0x94, 0xa8, 0xff, 0x95, 0xca, 0x4d, 0xe2, 0xe9, 0xd1, 0xf3, 0xf2, 0xae,
- 0x94, 0x99, 0x6d, 0xa3, 0xb1, 0xe0, 0x90, 0x46, 0x38, 0x4d, 0xa3, 0x9c,
- 0x32, 0x6d, 0x80, 0x6b, 0x03, 0xb4, 0x30, 0xd5, 0xe2, 0x9f, 0x59, 0x47,
- 0x08, 0xa7, 0x6b, 0x20, 0x0c, 0x8f, 0xa5, 0x23, 0x02, 0xfb, 0x28, 0xc7,
- 0x27, 0x17, 0x9a, 0xc7, 0x56, 0xc3, 0x9d, 0x6e, 0x81, 0x39, 0x18, 0x0e,
- 0x9c, 0xc6, 0x07, 0x43, 0x21, 0xc2, 0x0d, 0xed, 0xf6, 0xeb, 0x30, 0xf5,
- 0x7d, 0x81, 0x5f, 0xc8, 0xfd, 0x09, 0x5c, 0x14, 0xc4, 0x19, 0x69, 0xfc,
- 0x3e, 0xaf, 0x61, 0xdd, 0x07, 0xb0, 0x2d, 0xc3, 0x38, 0x45, 0x25, 0x9c,
- 0x02, 0xbc, 0x93, 0x37, 0xb0, 0x7f, 0x61, 0x0d, 0xf5, 0x93, 0xd6, 0x9e,
- 0x75, 0x70, 0x57, 0xd1, 0xf5, 0x47, 0x8b, 0xd0, 0x5e, 0x79, 0x8a, 0x95,
- 0x0d, 0x42, 0xe0, 0x29, 0xeb, 0xac, 0xdd, 0x31, 0xc9, 0x18, 0x46, 0x4d,
- 0x2d, 0xa0, 0x5c, 0xdc, 0x5a, 0x16, 0xd4, 0xdb, 0x4c, 0x7d, 0x06, 0x6c,
- 0x1b, 0x9d, 0xec, 0x7a, 0x5e, 0x22, 0xc6, 0xba, 0xbb, 0x39, 0xd2, 0x73,
- 0xd5, 0x16, 0x3a, 0xff, 0x1a, 0xd2, 0xe9, 0x2e, 0xcb, 0xed, 0x21, 0xa9,
- 0xd4, 0xa3, 0xcc, 0xe6, 0xf7, 0x48, 0xf7, 0xb5, 0x54, 0x47, 0x8a, 0xe5,
- 0xe7, 0xea, 0xb9, 0x66, 0x4c, 0x94, 0xf9, 0x1e, 0xd7, 0x83, 0xa5, 0xf9,
- 0x6a, 0x3e, 0xb0, 0xff, 0xd9, 0xf7, 0x1c, 0x0b, 0x1c, 0x33, 0x1c, 0x27,
- 0x8c, 0xd1, 0x7a, 0x30, 0xda, 0xae, 0x20, 0x9b, 0x90, 0x72, 0xa5, 0x65,
- 0x8e, 0x70, 0x1d, 0xa7, 0x98, 0xcf, 0xee, 0xb5, 0xeb, 0x29, 0x3f, 0xe1,
- 0x3e, 0x69, 0x1b, 0x08, 0x39, 0x1c, 0x1b, 0x75, 0x14, 0xeb, 0x11, 0x6c,
- 0xa3, 0x58, 0xd1, 0x2c, 0x2b, 0x49, 0x97, 0x0d, 0xfd, 0x9d, 0x0c, 0xf1,
- 0x96, 0x61, 0x94, 0xed, 0x5a, 0xc2, 0x95, 0x2a, 0x62, 0xce, 0x21, 0xd9,
- 0x60, 0x35, 0xea, 0xd4, 0xb8, 0xf5, 0x7b, 0xb1, 0x9a, 0xee, 0x17, 0x06,
- 0xea, 0x1c, 0x9e, 0x3f, 0x27, 0x67, 0x62, 0x11, 0x8a, 0x33, 0xe6, 0xb1,
- 0xdc, 0x67, 0xf0, 0x91, 0x44, 0x9c, 0x79, 0xb3, 0x58, 0x9d, 0x81, 0x38,
- 0x48, 0x7b, 0xa1, 0x81, 0x73, 0xd7, 0xc0, 0x7c, 0xc7, 0x3a, 0x76, 0x88,
- 0x7a, 0x8f, 0xd1, 0x00, 0xaa, 0xb9, 0x2a, 0x02, 0x8e, 0xa5, 0xef, 0xc5,
- 0x51, 0xaf, 0x4e, 0x11, 0x52, 0x17, 0x2b, 0x76, 0xcf, 0x13, 0xbd, 0x84,
- 0xcd, 0xdb, 0x53, 0x70, 0x34, 0xb4, 0x19, 0x7f, 0x43, 0xa3, 0x9b, 0x29,
- 0xfe, 0xe7, 0x38, 0x11, 0x51, 0xda, 0x0d, 0xfd, 0x69, 0x5b, 0xa3, 0x3e,
- 0x2a, 0xe5, 0xd6, 0x94, 0x81, 0x29, 0x9b, 0x70, 0x74, 0x63, 0x10, 0x31,
- 0x0b, 0xba, 0xee, 0x58, 0x83, 0x07, 0x30, 0xc0, 0xf8, 0x37, 0x3a, 0x9f,
- 0x7a, 0x25, 0x8d, 0x89, 0x31, 0xbb, 0x06, 0xd9, 0x9b, 0x05, 0x22, 0x4e,
- 0x82, 0xce, 0x16, 0x42, 0xce, 0x7b, 0x66, 0x1d, 0x91, 0x7d, 0xd7, 0xde,
- 0x43, 0xfa, 0x8a, 0xf9, 0xb5, 0x0e, 0x8f, 0x59, 0x76, 0x09, 0x77, 0x11,
- 0x56, 0xa7, 0x21, 0x9a, 0xdf, 0x4c, 0xf3, 0x8f, 0x92, 0xec, 0x5c, 0xdc,
- 0xbb, 0x87, 0xd6, 0xb7, 0x38, 0xd6, 0xf4, 0xf3, 0xd8, 0x4e, 0x3a, 0x70,
- 0x8d, 0xe7, 0x31, 0x3e, 0xf3, 0x42, 0x3e, 0x33, 0xf5, 0x78, 0x8e, 0x2b,
- 0x1b, 0x3f, 0xcb, 0xd3, 0xde, 0x09, 0x64, 0xb7, 0xdb, 0x10, 0x13, 0xf6,
- 0x6e, 0xc2, 0x2f, 0xa8, 0x8f, 0x3a, 0x56, 0xff, 0x14, 0xa0, 0x44, 0x9c,
- 0x9d, 0x28, 0xc5, 0x80, 0x47, 0x0b, 0x96, 0x7b, 0x8f, 0x62, 0x0e, 0x26,
- 0x08, 0x13, 0x9f, 0x21, 0x4c, 0xbf, 0xab, 0x7d, 0xda, 0x8c, 0x83, 0xb1,
- 0x7e, 0x54, 0xbc, 0xb4, 0x5b, 0x41, 0xc7, 0x62, 0xea, 0x4b, 0x54, 0x4b,
- 0xae, 0xb1, 0xf9, 0xbe, 0x7c, 0x79, 0x7d, 0x05, 0x2f, 0xff, 0x6f, 0x39,
- 0x69, 0x92, 0xc5, 0xaa, 0x79, 0x69, 0xf5, 0x3d, 0x8d, 0x3f, 0x93, 0xd9,
- 0x18, 0xfb, 0x22, 0x42, 0xb5, 0xf8, 0x97, 0xf5, 0x28, 0x39, 0x49, 0xf2,
- 0x37, 0x75, 0x07, 0x75, 0x8e, 0x19, 0xf2, 0x65, 0xf6, 0x8d, 0x3c, 0x44,
- 0x7d, 0x9a, 0xf2, 0x2a, 0xc6, 0x7e, 0xe1, 0xfb, 0x3d, 0x19, 0x6f, 0x38,
- 0x41, 0xba, 0xa9, 0xe8, 0x4a, 0xa3, 0x5e, 0x71, 0xac, 0xb3, 0x63, 0x74,
- 0xe6, 0x16, 0xa7, 0x1e, 0xe7, 0x1a, 0xb8, 0x36, 0x46, 0xc5, 0x0f, 0x46,
- 0xcd, 0x1e, 0xc2, 0xc3, 0xab, 0xee, 0x21, 0x1c, 0x75, 0x9f, 0x50, 0xd1,
- 0x4b, 0x67, 0xb7, 0xda, 0xc8, 0x07, 0x84, 0x4d, 0x12, 0x6d, 0xd3, 0x66,
- 0x02, 0xd5, 0xf3, 0x5e, 0x90, 0x71, 0xcb, 0x72, 0xe3, 0xca, 0xc7, 0x32,
- 0x95, 0xe6, 0x18, 0xdf, 0x80, 0x70, 0x5c, 0x20, 0x94, 0x1e, 0xf2, 0x6c,
- 0x4b, 0x77, 0x2a, 0xd4, 0xa7, 0x1f, 0x62, 0x1f, 0x11, 0x7e, 0x7b, 0x59,
- 0xe6, 0xbe, 0xc2, 0xba, 0x6d, 0x9f, 0xd5, 0x73, 0x2d, 0xc7, 0x15, 0xfd,
- 0x96, 0x73, 0xd8, 0xde, 0x87, 0xa8, 0x8e, 0x77, 0x2d, 0xe9, 0xdc, 0x3e,
- 0xa8, 0x0c, 0x49, 0x63, 0x25, 0xfb, 0x93, 0x2e, 0x37, 0xb5, 0x9e, 0xaf,
- 0xb5, 0xa8, 0x73, 0x1c, 0xaf, 0x0f, 0x45, 0x45, 0xfd, 0x63, 0xae, 0xd7,
- 0x53, 0x5f, 0xa3, 0xb3, 0x9c, 0x4c, 0xf1, 0x19, 0x38, 0xc7, 0x8e, 0xe3,
- 0x8a, 0xd2, 0xed, 0xc4, 0x1b, 0xa0, 0xfd, 0xa1, 0x51, 0xbc, 0x41, 0x52,
- 0x9f, 0x39, 0xd7, 0x35, 0x25, 0x8d, 0x06, 0x96, 0x4f, 0xb6, 0x1e, 0x65,
- 0x5b, 0xf3, 0xdd, 0xb2, 0x6a, 0x6f, 0xe6, 0xe7, 0xf5, 0x74, 0xe9, 0x8e,
- 0xb1, 0xff, 0x50, 0x5f, 0xe7, 0xb0, 0x4d, 0x21, 0x6a, 0x9c, 0x4e, 0x63,
- 0x81, 0xd8, 0x21, 0xdd, 0x44, 0xb5, 0x86, 0x45, 0xc5, 0x84, 0xb7, 0x9e,
- 0xf7, 0xfe, 0xf4, 0xfa, 0x26, 0xf1, 0xce, 0x9e, 0xdf, 0xa5, 0x67, 0x2f,
- 0x46, 0x7a, 0x9f, 0xa2, 0x1c, 0xd2, 0x9c, 0x7e, 0x99, 0x6c, 0xe4, 0x18,
- 0x83, 0xf2, 0x8a, 0xbd, 0x56, 0xe6, 0x1a, 0x39, 0xd6, 0xe0, 0x26, 0x48,
- 0xce, 0xae, 0xc7, 0x7e, 0x75, 0x8e, 0xab, 0xdb, 0xa5, 0x9c, 0xb0, 0xd7,
- 0x90, 0x2d, 0x58, 0x4e, 0xd5, 0x16, 0x7b, 0x66, 0x6d, 0xd3, 0x5e, 0xf1,
- 0x5f, 0xc1, 0x3b, 0x83, 0x16, 0x72, 0xde, 0xc0, 0x4b, 0x79, 0xa5, 0x89,
- 0x6e, 0x2b, 0xe8, 0xb3, 0x05, 0x7e, 0xda, 0x43, 0xfa, 0x5d, 0x49, 0x58,
- 0x65, 0x91, 0x35, 0xdd, 0x1a, 0x58, 0x2f, 0x31, 0x77, 0x9a, 0x82, 0xe3,
- 0xbc, 0xd4, 0xda, 0x55, 0x84, 0xaf, 0xe0, 0x1e, 0xc5, 0xb6, 0x57, 0xf0,
- 0x32, 0xf1, 0xad, 0xb8, 0xc2, 0x32, 0x5a, 0x05, 0xf5, 0xb5, 0xbe, 0xa5,
- 0xe9, 0xe0, 0x2f, 0x63, 0x8f, 0xcf, 0x90, 0xf3, 0x74, 0xe0, 0x18, 0xec,
- 0x22, 0xdf, 0xe5, 0x56, 0x2a, 0x48, 0x2d, 0x06, 0x61, 0x8d, 0xa8, 0xd8,
- 0xba, 0x9b, 0xfd, 0xff, 0x3d, 0x9a, 0x67, 0xbe, 0xce, 0x66, 0x1d, 0xd6,
- 0xaa, 0xc3, 0x74, 0xb1, 0x24, 0x2c, 0x4a, 0xf6, 0xe0, 0xbd, 0xaa, 0x72,
- 0xaa, 0x32, 0xa2, 0x62, 0x72, 0x94, 0x79, 0x59, 0x17, 0xaa, 0xcd, 0x1c,
- 0x2b, 0x29, 0x8e, 0x8f, 0x8f, 0x65, 0x47, 0x3a, 0x1a, 0x43, 0x2d, 0xaf,
- 0x89, 0x0a, 0x7d, 0x0f, 0xcb, 0x85, 0x60, 0x3b, 0xc6, 0x48, 0xff, 0xf6,
- 0xf4, 0xe5, 0xb3, 0xfa, 0xff, 0xb1, 0x5e, 0xc1, 0x71, 0x51, 0x71, 0xd4,
- 0xdb, 0xbb, 0x62, 0xa3, 0x49, 0xb2, 0xf5, 0x44, 0xaa, 0xca, 0xf3, 0x38,
- 0xf1, 0x70, 0x9c, 0x7d, 0x66, 0x4f, 0x22, 0xea, 0x15, 0x8f, 0xe4, 0xe9,
- 0x92, 0x6a, 0x29, 0xd7, 0xd7, 0x52, 0x9e, 0x3c, 0x49, 0xbd, 0x69, 0x7f,
- 0xb1, 0x57, 0x6c, 0xcb, 0xeb, 0xd4, 0xa7, 0x96, 0x8b, 0xad, 0x79, 0x8b,
- 0x71, 0xd1, 0x6c, 0x9f, 0xaa, 0xbc, 0x8b, 0xda, 0x52, 0xfa, 0xe4, 0x3b,
- 0xa2, 0x48, 0x4e, 0x77, 0xd0, 0x37, 0x7f, 0xf8, 0x41, 0xa9, 0x58, 0xfc,
- 0x3e, 0xc8, 0x3a, 0x76, 0x22, 0x10, 0xe9, 0xe9, 0x59, 0x12, 0x40, 0xbd,
- 0x85, 0xbe, 0x66, 0xc2, 0x07, 0x57, 0x7a, 0x35, 0xdd, 0x80, 0x51, 0x6a,
- 0x6f, 0xac, 0xf8, 0x89, 0xf3, 0x0e, 0x6a, 0xad, 0x83, 0x5c, 0x0d, 0xd5,
- 0x91, 0x6b, 0xba, 0x43, 0xda, 0xd1, 0xee, 0xde, 0x96, 0xf6, 0xc9, 0xa6,
- 0x5c, 0xad, 0x73, 0x7d, 0x4b, 0xdb, 0xa4, 0xdb, 0xb2, 0x70, 0x08, 0xf8,
- 0xf2, 0x90, 0x0e, 0xcd, 0xb9, 0xd1, 0x0d, 0x74, 0x23, 0xa7, 0x52, 0x5c,
- 0xec, 0xe8, 0xb6, 0x7a, 0xa6, 0xc4, 0x4d, 0x37, 0x91, 0x1e, 0x2d, 0x9d,
- 0x93, 0x86, 0xb1, 0x39, 0xf3, 0xc0, 0x4d, 0x81, 0x29, 0xee, 0x2f, 0x1b,
- 0x06, 0xf7, 0xf1, 0x7b, 0x33, 0xba, 0x9b, 0x9e, 0xd0, 0xf1, 0xc0, 0xb2,
- 0xee, 0x41, 0x0c, 0xe4, 0x1f, 0x40, 0x7f, 0x9e, 0xdf, 0x3b, 0x69, 0x18,
- 0xe1, 0x1a, 0x5f, 0xe0, 0x77, 0x4e, 0x0f, 0x35, 0x30, 0x6e, 0xdc, 0x5e,
- 0x56, 0x71, 0xed, 0x10, 0xcf, 0x99, 0xcd, 0xef, 0xa3, 0xca, 0xfb, 0x59,
- 0x7c, 0x9f, 0xd4, 0x93, 0x6b, 0x1e, 0xb2, 0x81, 0x61, 0x29, 0x95, 0x0c,
- 0xdf, 0x63, 0x4e, 0x13, 0xd6, 0xe3, 0xbd, 0x7f, 0x4e, 0xbd, 0x71, 0x2e,
- 0xbf, 0x0b, 0x63, 0xca, 0x86, 0x87, 0x79, 0xee, 0xd4, 0xec, 0xdc, 0xbb,
- 0x34, 0x07, 0x71, 0x92, 0xea, 0xfa, 0x74, 0x25, 0x2f, 0xb2, 0xb5, 0xc3,
- 0x1a, 0xfe, 0xa8, 0xc0, 0x3c, 0x33, 0xb3, 0x3c, 0x3f, 0x21, 0x9e, 0x04,
- 0x56, 0xc4, 0xb8, 0x76, 0x53, 0xce, 0xec, 0xae, 0xbe, 0x2b, 0x93, 0xf2,
- 0x25, 0xfb, 0xc3, 0x68, 0xe5, 0x5d, 0x59, 0x54, 0x68, 0x8f, 0xd1, 0x33,
- 0x61, 0x95, 0x50, 0x2a, 0x2a, 0x42, 0x8f, 0xf1, 0xfa, 0x57, 0x53, 0x95,
- 0xf5, 0xc7, 0x52, 0xbc, 0xfe, 0xd7, 0xd7, 0xa8, 0xd9, 0xc8, 0x30, 0xdd,
- 0xa9, 0x0a, 0xff, 0x24, 0x77, 0x34, 0x56, 0x64, 0x57, 0xd6, 0x7d, 0x6f,
- 0x76, 0xdd, 0x41, 0x5a, 0xb7, 0x8f, 0x62, 0x8c, 0xd7, 0xb2, 0x9e, 0x1c,
- 0xa3, 0xd5, 0xf7, 0x86, 0x49, 0x71, 0x80, 0x7a, 0xf5, 0x81, 0x92, 0x2a,
- 0xf6, 0x52, 0x1d, 0x1c, 0xcf, 0x13, 0x36, 0xf2, 0xde, 0x05, 0x52, 0xcd,
- 0x2f, 0x7f, 0x23, 0x56, 0xf1, 0x21, 0xf7, 0xd5, 0x69, 0xea, 0xab, 0xed,
- 0x54, 0xdf, 0x55, 0x4f, 0xa7, 0xb0, 0x73, 0x84, 0xea, 0xbb, 0xc0, 0x49,
- 0xaf, 0xbe, 0x1c, 0x41, 0x7b, 0x89, 0xfb, 0x80, 0x25, 0xce, 0x15, 0x8c,
- 0x5c, 0x33, 0xc9, 0x6e, 0x29, 0x57, 0x6a, 0x03, 0xf5, 0x82, 0x2c, 0xf5,
- 0x64, 0xf1, 0x62, 0x89, 0x7f, 0x52, 0xf1, 0x8c, 0xf3, 0x19, 0xb2, 0x62,
- 0x4e, 0xbb, 0x8b, 0xfa, 0x76, 0x97, 0x71, 0xec, 0xc0, 0xf3, 0xc2, 0x9a,
- 0x3e, 0x27, 0xb2, 0xb7, 0x36, 0xe3, 0x41, 0xfc, 0x3c, 0x95, 0x5d, 0x11,
- 0xa5, 0x6f, 0xc2, 0xcc, 0x86, 0xc6, 0xef, 0x48, 0xbb, 0xdb, 0x7a, 0x36,
- 0x88, 0x36, 0xaa, 0x37, 0x6d, 0xee, 0x16, 0xb4, 0x51, 0xcf, 0xb7, 0xb5,
- 0xc3, 0x25, 0x5b, 0x7b, 0xa3, 0x54, 0xb5, 0x03, 0xc7, 0x29, 0xdb, 0x80,
- 0x42, 0xdf, 0xb1, 0xb2, 0x0b, 0x04, 0xf5, 0x55, 0xea, 0xbb, 0xc3, 0xd4,
- 0xb3, 0x2b, 0xf7, 0xce, 0x30, 0xe1, 0x16, 0xde, 0x7b, 0xdd, 0xec, 0xbb,
- 0x96, 0x7f, 0x90, 0x95, 0x1e, 0xf5, 0x0a, 0xd9, 0x83, 0xcf, 0xfc, 0xa3,
- 0x48, 0x65, 0xfc, 0x4c, 0x6c, 0xf6, 0xff, 0xf9, 0x21, 0x9c, 0x42, 0xf7,
- 0xc8, 0x21, 0x81, 0x1d, 0x6d, 0x95, 0x58, 0xee, 0xe4, 0xf7, 0x98, 0xde,
- 0x7b, 0xb7, 0x2a, 0x4f, 0xc5, 0x86, 0x0a, 0xe1, 0x99, 0x43, 0xe5, 0xac,
- 0xb8, 0x26, 0x8f, 0x01, 0xea, 0x89, 0xd9, 0x20, 0xf1, 0x5e, 0x53, 0xea,
- 0x15, 0xcb, 0xf3, 0x96, 0xb1, 0x89, 0x74, 0xdd, 0xa2, 0x77, 0xea, 0xe3,
- 0x84, 0x21, 0x68, 0x3f, 0x23, 0x4c, 0xf1, 0xaf, 0x39, 0x73, 0xb1, 0x7d,
- 0x36, 0x76, 0x28, 0x1f, 0x28, 0x7f, 0x06, 0xc5, 0x82, 0x49, 0xfe, 0xa9,
- 0x7b, 0xb1, 0x5b, 0xd1, 0xe3, 0x9c, 0xdc, 0x76, 0x33, 0xcf, 0x5f, 0x31,
- 0x6b, 0xfb, 0xa6, 0x38, 0xed, 0x49, 0xbf, 0x47, 0x66, 0xcf, 0xff, 0x7f,
- 0xad, 0xbd, 0xf6, 0x92, 0xff, 0xb9, 0x66, 0x86, 0xce, 0xc9, 0x18, 0x08,
- 0x6e, 0xdc, 0x61, 0xfc, 0x33, 0x6f, 0xd6, 0xe7, 0xd4, 0x15, 0xa3, 0x03,
- 0xb8, 0x71, 0x31, 0xdd, 0x7c, 0xe9, 0x0e, 0xb6, 0x8d, 0x7c, 0x95, 0x1c,
- 0x66, 0xbd, 0xcf, 0x93, 0xde, 0xd0, 0x6a, 0x9c, 0xb3, 0xb8, 0x7c, 0xa8,
- 0xb5, 0x3f, 0x2c, 0xcc, 0xe4, 0x90, 0x30, 0xfb, 0xa8, 0xbe, 0xd9, 0x93,
- 0x30, 0x9b, 0x17, 0x08, 0xd3, 0x58, 0x0b, 0xb6, 0xc9, 0x79, 0xb4, 0x95,
- 0xf8, 0xfb, 0x2c, 0x2c, 0xf2, 0x6b, 0xdf, 0x70, 0x00, 0x4a, 0xfa, 0x03,
- 0xb2, 0x2b, 0xe1, 0x35, 0xd1, 0x4c, 0xb9, 0xc4, 0xb1, 0x77, 0x1e, 0x9b,
- 0xf3, 0xd0, 0x5a, 0x88, 0xe7, 0x2a, 0xaa, 0xd1, 0xad, 0xc3, 0xe6, 0x59,
- 0xc2, 0x9c, 0x83, 0x5f, 0x0a, 0xb4, 0x26, 0xfb, 0x61, 0x0e, 0x6c, 0x41,
- 0xe7, 0xf4, 0x51, 0x61, 0x66, 0xcf, 0x12, 0x16, 0x0c, 0xa7, 0x2b, 0x32,
- 0x17, 0xcd, 0xca, 0x4c, 0x32, 0x3e, 0xf6, 0x72, 0x88, 0x30, 0x74, 0xfa,
- 0x6f, 0xe5, 0xb4, 0x67, 0xb3, 0xe0, 0xac, 0xfe, 0x4b, 0xe2, 0x15, 0x1f,
- 0x3c, 0x37, 0x6b, 0x1f, 0x42, 0x24, 0xb5, 0xcc, 0xc7, 0xf7, 0x30, 0x88,
- 0x35, 0xf9, 0x2f, 0xe2, 0x61, 0xc2, 0x43, 0x59, 0x6f, 0x7d, 0x2f, 0x72,
- 0x25, 0x88, 0xb5, 0xf9, 0xe9, 0xf0, 0x51, 0x3b, 0x88, 0xa2, 0x27, 0xe7,
- 0x7a, 0x1a, 0xeb, 0xa3, 0x0f, 0xdb, 0x8c, 0xef, 0xe4, 0x37, 0xd3, 0x73,
- 0xd6, 0xe3, 0xeb, 0xcf, 0xa3, 0x27, 0x9c, 0x22, 0xdc, 0xe6, 0xf1, 0x79,
- 0xf7, 0x75, 0xe2, 0x59, 0xce, 0x73, 0x23, 0xfc, 0xae, 0x61, 0x75, 0xa6,
- 0xcd, 0x78, 0xd8, 0xbb, 0x23, 0x1a, 0x58, 0x53, 0x32, 0x70, 0x07, 0xd5,
- 0xd5, 0xa2, 0x57, 0x57, 0x7f, 0x85, 0xe7, 0x15, 0xe2, 0x5b, 0x46, 0x7c,
- 0x9b, 0xbc, 0x31, 0x03, 0xcb, 0x4b, 0xc7, 0xbd, 0x58, 0x51, 0x1d, 0xf6,
- 0x03, 0xdb, 0x9e, 0xf1, 0x68, 0xf5, 0xae, 0xc6, 0x3e, 0xc9, 0x8a, 0x47,
- 0xf3, 0xbd, 0x62, 0x67, 0x3e, 0x4a, 0xfb, 0xb9, 0x62, 0x24, 0xa3, 0x8c,
- 0xc6, 0x20, 0xb1, 0x2c, 0x7d, 0x35, 0xd5, 0x19, 0x2b, 0x69, 0xd1, 0xb5,
- 0x65, 0x6d, 0x72, 0x2e, 0x61, 0xa7, 0x25, 0x58, 0x97, 0x0c, 0x51, 0xff,
- 0xfe, 0x16, 0xee, 0xd4, 0xc3, 0xe8, 0x4f, 0xde, 0x0b, 0xdc, 0x58, 0x43,
- 0xfd, 0xf6, 0x61, 0x0f, 0xb3, 0x86, 0x68, 0xdf, 0x1a, 0xaa, 0x0d, 0x77,
- 0x79, 0x7a, 0x4f, 0xb1, 0xae, 0x74, 0xce, 0xe5, 0x62, 0x84, 0xea, 0x7d,
- 0xa2, 0x82, 0x01, 0x36, 0x66, 0x8a, 0xfc, 0x3d, 0xb3, 0xb1, 0xcb, 0xb3,
- 0xf3, 0x4f, 0x36, 0xda, 0xa5, 0x5f, 0xc4, 0x2b, 0x3d, 0x75, 0x29, 0xb2,
- 0x8d, 0xdd, 0x58, 0x9f, 0xec, 0xc1, 0x1c, 0x6b, 0x39, 0xbe, 0xaa, 0xbb,
- 0x88, 0x5a, 0x63, 0xb8, 0xdb, 0x93, 0xc1, 0xf2, 0xbc, 0xbf, 0x6d, 0x10,
- 0x4d, 0x13, 0xc8, 0xf9, 0xbc, 0xfb, 0x50, 0xe5, 0xdd, 0x42, 0x4e, 0x09,
- 0x62, 0xd3, 0x2e, 0xfe, 0x56, 0x71, 0x77, 0xa6, 0xf2, 0xce, 0x70, 0x78,
- 0x2c, 0x88, 0xa1, 0x5d, 0xd4, 0xfb, 0x52, 0x21, 0xb8, 0x8d, 0x9f, 0x96,
- 0xdd, 0x4f, 0xb2, 0x2b, 0xf7, 0xef, 0xaf, 0x91, 0x5d, 0x67, 0x82, 0x41,
- 0x34, 0x13, 0x0c, 0x4b, 0x10, 0x4f, 0xc3, 0x54, 0x1d, 0x9a, 0xc7, 0xf8,
- 0xef, 0x23, 0x07, 0xc5, 0x7d, 0xa5, 0x0a, 0xcf, 0x46, 0xfe, 0x9b, 0x4a,
- 0x58, 0xc1, 0x7c, 0x8b, 0xd5, 0x55, 0x89, 0x47, 0xa3, 0x7b, 0x5c, 0x2d,
- 0xe6, 0x8f, 0xd5, 0xd1, 0x47, 0x47, 0x6c, 0x82, 0x26, 0xa6, 0x96, 0x8b,
- 0xaf, 0xe7, 0x93, 0x88, 0xd1, 0xfd, 0x32, 0xee, 0x54, 0xd6, 0xdf, 0x53,
- 0xfa, 0xbc, 0xf3, 0x07, 0xff, 0xbb, 0xb2, 0x6f, 0x01, 0x8e, 0xea, 0xbc,
- 0xd2, 0xfc, 0x6e, 0x3f, 0xa4, 0xd6, 0x93, 0xab, 0x27, 0x2d, 0x1e, 0xa6,
- 0x9b, 0xbe, 0x2d, 0xb5, 0xad, 0x4e, 0xb8, 0x0d, 0xa2, 0x90, 0x3d, 0xbd,
- 0xa5, 0x06, 0x0b, 0x5b, 0x04, 0x63, 0xcb, 0xb6, 0x32, 0x83, 0x67, 0x53,
- 0x63, 0x05, 0x03, 0xc6, 0xd8, 0x33, 0x91, 0x09, 0x35, 0x25, 0xef, 0xce,
- 0x44, 0x77, 0x25, 0x10, 0x02, 0xf5, 0x4b, 0x12, 0x04, 0x98, 0xaa, 0x2d,
- 0x37, 0x92, 0x40, 0xd8, 0x69, 0x49, 0x78, 0x92, 0xec, 0x90, 0x4c, 0xd5,
- 0x58, 0x01, 0x61, 0x20, 0x04, 0xe3, 0xec, 0x4e, 0x6d, 0x91, 0x5d, 0xcf,
- 0x98, 0xc2, 0x06, 0x9c, 0x18, 0x3f, 0x33, 0x59, 0x8b, 0x78, 0xe2, 0xbb,
- 0xdf, 0xb9, 0xdd, 0x0d, 0x82, 0x21, 0x99, 0x1a, 0x57, 0x75, 0x89, 0xee,
- 0x7b, 0xff, 0xff, 0x9e, 0xff, 0xfc, 0xe7, 0x7c, 0xe7, 0x3b, 0xe7, 0xfc,
- 0xb7, 0x4c, 0x2e, 0x2d, 0xfb, 0xb5, 0x08, 0xc5, 0xda, 0x94, 0xf9, 0x42,
- 0x96, 0xe3, 0x48, 0x1c, 0xed, 0xbe, 0xd9, 0x8f, 0x11, 0x99, 0x84, 0xcb,
- 0x41, 0xad, 0x08, 0x4b, 0x9e, 0xc7, 0x1f, 0xad, 0x3c, 0x51, 0x64, 0x90,
- 0xb9, 0x0b, 0x91, 0x3f, 0x2c, 0x73, 0x17, 0x21, 0xef, 0xa6, 0x2c, 0xf2,
- 0x1c, 0xa6, 0x5c, 0x13, 0x12, 0x5b, 0xe5, 0x79, 0xc7, 0x95, 0xa1, 0xb4,
- 0xc8, 0x90, 0x7b, 0xee, 0x59, 0x73, 0xa3, 0x5a, 0xc4, 0x18, 0x3e, 0x62,
- 0x6e, 0x62, 0x5e, 0xe2, 0x5f, 0xfa, 0x86, 0x99, 0x6a, 0x93, 0xb5, 0xba,
- 0xcd, 0xbd, 0x09, 0x27, 0xfa, 0xa9, 0xb7, 0xad, 0xa1, 0xa3, 0xc2, 0x67,
- 0xb3, 0xff, 0xe5, 0xf4, 0xf6, 0x97, 0xd4, 0xdb, 0xa9, 0xec, 0x3e, 0x1e,
- 0x57, 0x4e, 0xde, 0x8c, 0xf5, 0x22, 0xa3, 0xc8, 0xa5, 0xa0, 0x42, 0x13,
- 0xb9, 0x6c, 0x28, 0x67, 0xdc, 0xac, 0xa0, 0x7e, 0xca, 0x2d, 0x99, 0x9a,
- 0x95, 0x9f, 0x47, 0xa1, 0xce, 0x21, 0x17, 0x2c, 0x9b, 0xc8, 0xc8, 0x35,
- 0x45, 0xfd, 0x5c, 0xb8, 0x69, 0x13, 0xb3, 0xf5, 0x2c, 0x74, 0x46, 0x7c,
- 0xfa, 0xe2, 0x4b, 0x3b, 0x92, 0x32, 0xaf, 0x5d, 0xf2, 0x04, 0x2b, 0xdf,
- 0xb3, 0xd1, 0x9e, 0x56, 0x45, 0x33, 0x3a, 0xb0, 0x59, 0x7b, 0x20, 0x3e,
- 0x20, 0xeb, 0xcf, 0xad, 0xbd, 0x59, 0x79, 0x3a, 0x2a, 0xe3, 0x35, 0x2c,
- 0xb2, 0xc6, 0x59, 0xfb, 0xce, 0x71, 0x6f, 0x73, 0x5c, 0x80, 0x63, 0x32,
- 0xb6, 0xe9, 0x49, 0x7d, 0x26, 0x7e, 0xcd, 0x7d, 0x3a, 0xae, 0x74, 0xf2,
- 0x99, 0xb0, 0xf6, 0xf6, 0xfd, 0xac, 0xaf, 0x1f, 0xa7, 0x6f, 0xf2, 0x37,
- 0xa7, 0x8d, 0xf6, 0x5e, 0x04, 0xc7, 0xb0, 0xcb, 0xaa, 0x49, 0xc8, 0xdc,
- 0xcf, 0x45, 0xcb, 0x51, 0x70, 0x24, 0x37, 0x36, 0x13, 0xc3, 0x33, 0xbd,
- 0xac, 0x9c, 0x3f, 0x0a, 0x3e, 0x0a, 0x76, 0x1b, 0x4a, 0xe4, 0x66, 0x3f,
- 0x4a, 0x6a, 0x38, 0xd2, 0xa7, 0xcb, 0xa7, 0x3c, 0x52, 0xef, 0x53, 0x88,
- 0x19, 0xcc, 0x07, 0xd5, 0x55, 0x1e, 0x07, 0x71, 0x6e, 0x13, 0xbe, 0x20,
- 0xb7, 0x8d, 0x04, 0x9c, 0x96, 0x0f, 0x4b, 0xcd, 0x2f, 0x1f, 0x19, 0x0c,
- 0x02, 0x86, 0xa3, 0x8c, 0xbb, 0x5c, 0x2b, 0x63, 0x3d, 0xba, 0xd3, 0x5f,
- 0x98, 0x53, 0x95, 0xcc, 0xd9, 0xb5, 0x9b, 0x35, 0x22, 0xfa, 0x9d, 0x69,
- 0x8e, 0xf0, 0x5a, 0x6f, 0x3a, 0xb7, 0x4f, 0xe4, 0x10, 0xe4, 0x68, 0xcf,
- 0x68, 0xbf, 0x35, 0x37, 0xdc, 0x76, 0x6f, 0x0e, 0x9b, 0x73, 0x79, 0xa9,
- 0x60, 0x73, 0x31, 0x7a, 0xf7, 0x7a, 0x93, 0x29, 0x54, 0x22, 0xa9, 0xd9,
- 0xe6, 0xd3, 0x4b, 0x98, 0xf5, 0x7b, 0xfb, 0x9a, 0x61, 0xe5, 0xeb, 0x9e,
- 0x14, 0xfa, 0x2b, 0xc4, 0x8f, 0x9c, 0x5a, 0xbd, 0xa7, 0xcc, 0x56, 0x2e,
- 0xb2, 0x5b, 0x52, 0xd9, 0x07, 0x0b, 0xb0, 0x89, 0xb9, 0x76, 0xaa, 0x95,
- 0x98, 0x35, 0x68, 0xb4, 0x70, 0x7a, 0x57, 0x61, 0x38, 0xd5, 0xf9, 0x35,
- 0xbf, 0x97, 0xf1, 0x10, 0xc8, 0x67, 0xde, 0x7f, 0x09, 0x59, 0x4c, 0x1b,
- 0xf4, 0x1a, 0x36, 0x9b, 0x8c, 0xff, 0xcc, 0x34, 0xda, 0x64, 0xac, 0xcc,
- 0xc1, 0x67, 0xff, 0x1b, 0x5f, 0xf0, 0x50, 0x4f, 0x87, 0x2b, 0xa4, 0x7e,
- 0xa6, 0xd6, 0x92, 0xab, 0x0f, 0x16, 0xa3, 0x88, 0xb9, 0x6b, 0x7f, 0x95,
- 0xaf, 0x43, 0xb7, 0x15, 0xe2, 0xfc, 0x57, 0xfe, 0x13, 0x52, 0x55, 0x79,
- 0x70, 0xd5, 0x02, 0x0f, 0xc6, 0x6d, 0xb0, 0xd5, 0x12, 0x7b, 0x1b, 0x80,
- 0xe6, 0x09, 0xee, 0xdb, 0xa0, 0x82, 0xa7, 0x92, 0x36, 0x3c, 0x9a, 0xb4,
- 0x63, 0x6d, 0x12, 0xdf, 0x59, 0x04, 0x4c, 0xd7, 0xc0, 0xdf, 0x3e, 0xa3,
- 0x60, 0x6b, 0x29, 0xfc, 0xad, 0x31, 0xc5, 0xdf, 0xb2, 0x96, 0x39, 0xd3,
- 0x9a, 0x09, 0xe2, 0x19, 0xef, 0x75, 0x0e, 0x70, 0x5f, 0x07, 0xec, 0xa8,
- 0x19, 0xc0, 0x3d, 0xf9, 0x40, 0x83, 0x13, 0xfe, 0x19, 0xc6, 0x99, 0x72,
- 0x07, 0xfc, 0x53, 0x97, 0xed, 0xfe, 0xce, 0x1a, 0x3b, 0x37, 0xb7, 0x56,
- 0x64, 0x71, 0xe1, 0x31, 0xda, 0xf3, 0xa2, 0x41, 0xde, 0xcf, 0xfc, 0x5d,
- 0x65, 0x9e, 0xf3, 0xc9, 0x9f, 0x48, 0xfd, 0x52, 0xae, 0x49, 0xef, 0x52,
- 0x41, 0xe9, 0xa0, 0x9d, 0x18, 0x76, 0xce, 0x3c, 0x5f, 0x25, 0xf8, 0x0d,
- 0x3c, 0x45, 0xd9, 0xdc, 0xfc, 0x4d, 0xad, 0x25, 0x37, 0x5d, 0xa1, 0x62,
- 0xfd, 0xb0, 0xdc, 0x0b, 0x6b, 0x1e, 0x27, 0x7d, 0x2a, 0x8f, 0x3e, 0x7e,
- 0xc4, 0xea, 0x77, 0xd9, 0xb8, 0x46, 0x3b, 0x8a, 0x06, 0x81, 0x35, 0x71,
- 0x3c, 0x51, 0x0c, 0x7f, 0x44, 0x64, 0xac, 0x5b, 0xee, 0xe0, 0xd8, 0x62,
- 0xb4, 0x4c, 0x64, 0xc6, 0x3d, 0x3c, 0xf1, 0xa3, 0x8a, 0x4c, 0x2d, 0xf7,
- 0xf7, 0xf7, 0x5e, 0x7b, 0x1a, 0xfc, 0xd8, 0x94, 0xa4, 0xcd, 0xd9, 0x3c,
- 0x18, 0xce, 0xd6, 0x54, 0x37, 0xa4, 0xbc, 0xb3, 0x7a, 0xa3, 0xff, 0xbd,
- 0x38, 0xdb, 0x37, 0xa5, 0x2f, 0xcc, 0x70, 0x1e, 0x43, 0xd9, 0x40, 0xdd,
- 0x0d, 0x4f, 0x9a, 0x88, 0xea, 0x26, 0xc6, 0xf9, 0x79, 0x53, 0x87, 0x51,
- 0x44, 0x5f, 0xd8, 0x18, 0xfb, 0xd2, 0x34, 0xb2, 0xfe, 0xfc, 0x4a, 0x22,
- 0xa0, 0x6c, 0x21, 0x57, 0x7e, 0x95, 0xf1, 0x74, 0x8c, 0x9f, 0x51, 0xe6,
- 0x70, 0x4e, 0xca, 0x6d, 0xa3, 0x5f, 0xef, 0x4c, 0x01, 0x23, 0xcc, 0xd1,
- 0x0f, 0x2e, 0x17, 0xfe, 0x5e, 0xc4, 0xe7, 0xd1, 0x6b, 0x78, 0x4f, 0x9a,
- 0x9f, 0x23, 0xfc, 0x4c, 0x72, 0x4f, 0xf9, 0x3c, 0x04, 0xc6, 0x1d, 0x88,
- 0x8c, 0x13, 0x68, 0xc7, 0x03, 0x98, 0x62, 0x0c, 0xbc, 0x31, 0xaa, 0xa2,
- 0x64, 0xac, 0x1c, 0x1f, 0x1d, 0x26, 0x3e, 0x1e, 0xca, 0x70, 0xfe, 0x4d,
- 0xe3, 0xd2, 0xdf, 0x92, 0xf5, 0x49, 0x1f, 0x58, 0xfc, 0xa9, 0x00, 0x63,
- 0xa4, 0x1f, 0xd2, 0x0b, 0x7e, 0x57, 0xe7, 0xdc, 0xaa, 0xf4, 0xf1, 0x5a,
- 0x71, 0x34, 0xea, 0xf3, 0xf4, 0xd1, 0xe6, 0x0d, 0x87, 0xf8, 0x58, 0x03,
- 0x5e, 0x8d, 0xe6, 0x7a, 0x42, 0xbe, 0x96, 0x9f, 0x4a, 0x3d, 0x83, 0x21,
- 0x3b, 0x4f, 0x93, 0x6b, 0xb9, 0x58, 0x2a, 0x6b, 0x96, 0xba, 0x74, 0x8e,
- 0xb7, 0xcc, 0xfe, 0xfd, 0x8c, 0x29, 0x7d, 0xca, 0xd7, 0x26, 0xbd, 0x7d,
- 0x29, 0xe8, 0x56, 0xac, 0x3c, 0x5c, 0xe7, 0x4d, 0x1a, 0x90, 0xfd, 0x6d,
- 0xa0, 0x0c, 0xdf, 0xa5, 0xed, 0x07, 0x44, 0xd7, 0x8c, 0xed, 0x52, 0xef,
- 0x2d, 0x43, 0xff, 0x40, 0x39, 0xf6, 0x0c, 0x18, 0xe8, 0x5d, 0xde, 0x86,
- 0x33, 0x51, 0x13, 0x9b, 0x42, 0x26, 0xd6, 0x84, 0xbc, 0x81, 0x57, 0x50,
- 0xdf, 0x78, 0x14, 0x8f, 0x91, 0x43, 0xa8, 0xd4, 0xc9, 0x37, 0xf0, 0xce,
- 0x5e, 0x07, 0x36, 0xeb, 0x7f, 0x4c, 0x1f, 0x36, 0xcd, 0xf7, 0x96, 0x2d,
- 0xc0, 0x70, 0xa2, 0x5e, 0xed, 0xa6, 0x7c, 0x91, 0x36, 0xee, 0x55, 0xd0,
- 0x81, 0x67, 0xf5, 0xef, 0xf0, 0x5e, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b,
- 0xe3, 0xa9, 0xec, 0xa5, 0x41, 0xfb, 0xca, 0xc4, 0xb2, 0x48, 0xb6, 0xce,
- 0xbe, 0xb9, 0x41, 0x30, 0xbf, 0x18, 0xa7, 0xa9, 0xb7, 0x13, 0xc9, 0x08,
- 0xc3, 0x2e, 0x94, 0x67, 0x1b, 0xba, 0xf0, 0x34, 0xf9, 0xc6, 0x3b, 0x24,
- 0x02, 0xf7, 0xc7, 0x15, 0x34, 0xd6, 0xe9, 0xb8, 0x98, 0xfe, 0x06, 0xde,
- 0x1a, 0x0d, 0xe3, 0x4d, 0xc6, 0xf4, 0x25, 0xdf, 0xf5, 0x92, 0x83, 0x7a,
- 0x70, 0x3e, 0x1d, 0xc6, 0xb9, 0xa8, 0xb7, 0xf5, 0x05, 0x65, 0x01, 0x7e,
- 0x9a, 0x76, 0xe0, 0xde, 0x38, 0xf0, 0x4b, 0xce, 0xe3, 0x8f, 0x3b, 0x70,
- 0x25, 0xad, 0xe2, 0x28, 0xf7, 0xc7, 0x11, 0x5a, 0x02, 0xa3, 0xcd, 0x83,
- 0x23, 0x43, 0x8f, 0x62, 0x2a, 0xf5, 0x28, 0x4e, 0x25, 0xdf, 0x31, 0x5d,
- 0x9a, 0xf4, 0x75, 0x5c, 0xb8, 0xc2, 0x7c, 0x6c, 0x9a, 0xda, 0x28, 0x5e,
- 0xd1, 0xca, 0x38, 0xaf, 0x19, 0xa2, 0xf7, 0xb7, 0xf8, 0xdb, 0xfd, 0xf1,
- 0x46, 0x1c, 0x1c, 0xa7, 0x4a, 0x13, 0x3a, 0x12, 0x31, 0x79, 0x56, 0x03,
- 0x62, 0xe4, 0x85, 0xfd, 0x4c, 0xdb, 0xb7, 0x86, 0xee, 0x95, 0x5c, 0x43,
- 0x69, 0xa9, 0xed, 0xcf, 0xae, 0xa3, 0x71, 0x56, 0xcf, 0x4e, 0x72, 0x28,
- 0xea, 0x95, 0xe3, 0xfe, 0x36, 0x11, 0xb4, 0x62, 0xd3, 0xb1, 0x9b, 0xfb,
- 0xd1, 0xc8, 0xfd, 0xf8, 0x06, 0x2e, 0xee, 0x6d, 0xc3, 0x5b, 0xc4, 0xbb,
- 0xd2, 0x65, 0xbe, 0x4e, 0xa7, 0xad, 0x9e, 0x73, 0xa7, 0xcd, 0x54, 0x95,
- 0xe8, 0xb4, 0x0d, 0xbf, 0x88, 0x8a, 0x4e, 0xd3, 0xc4, 0x3f, 0x9f, 0xc7,
- 0x6f, 0xff, 0xcb, 0x4a, 0xda, 0xb3, 0xad, 0x3b, 0x98, 0xe9, 0x41, 0x15,
- 0xaf, 0x70, 0xe1, 0xaa, 0x25, 0x9b, 0xc8, 0xfa, 0x87, 0xe4, 0xfb, 0x85,
- 0xb9, 0xa6, 0x4a, 0xe4, 0x33, 0xcc, 0x3c, 0x4d, 0x0b, 0xe4, 0x29, 0x12,
- 0x67, 0x03, 0x56, 0x3d, 0xbe, 0x2e, 0xde, 0x05, 0x7b, 0xa8, 0x98, 0x79,
- 0x98, 0x77, 0xa6, 0x03, 0x6f, 0xe1, 0xda, 0xa4, 0x0b, 0x8b, 0xe3, 0x1a,
- 0x5e, 0x9e, 0x7c, 0x8d, 0xcf, 0xfa, 0x47, 0x5c, 0xe6, 0x77, 0x5f, 0x3c,
- 0xe3, 0x6f, 0xdd, 0x0d, 0x6d, 0x78, 0x30, 0x2d, 0xeb, 0xcb, 0xe3, 0x83,
- 0x74, 0x44, 0xd2, 0xb2, 0xce, 0x18, 0x7d, 0x43, 0xd6, 0x59, 0xfe, 0xef,
- 0xac, 0xf3, 0xbf, 0x72, 0xbe, 0x05, 0xf4, 0xa5, 0x5c, 0xec, 0x28, 0xc1,
- 0x91, 0xa4, 0x8a, 0xd3, 0x7a, 0x31, 0x2e, 0xa9, 0x52, 0x5f, 0x76, 0x31,
- 0x86, 0x38, 0xd0, 0xcc, 0x9c, 0x71, 0x84, 0x9f, 0x8d, 0xcc, 0x7f, 0xce,
- 0xea, 0x0e, 0x9c, 0xd2, 0x17, 0x10, 0xeb, 0xef, 0xb4, 0x61, 0xb9, 0x46,
- 0xb2, 0x5f, 0x56, 0x8e, 0x73, 0x52, 0xff, 0xb3, 0xae, 0xbb, 0xa4, 0x2f,
- 0x89, 0x31, 0xea, 0x2b, 0x2f, 0xf6, 0x1b, 0xf3, 0xaa, 0x85, 0x35, 0x77,
- 0xca, 0x77, 0xe7, 0x3c, 0x12, 0x82, 0x7f, 0x69, 0x6e, 0xad, 0xca, 0xc6,
- 0x2e, 0xe5, 0x4f, 0x2b, 0x33, 0x78, 0x21, 0x71, 0xec, 0xef, 0x72, 0xd8,
- 0x21, 0xf9, 0x64, 0x1b, 0xe3, 0x10, 0xe3, 0xf2, 0xf1, 0x6d, 0x92, 0xe7,
- 0xd9, 0xc2, 0xef, 0xb5, 0xad, 0xd2, 0xf2, 0x60, 0xb7, 0xf8, 0xde, 0x7b,
- 0x2f, 0x65, 0x38, 0xfa, 0xfb, 0x2f, 0x69, 0xd6, 0xdf, 0xeb, 0x2f, 0x2d,
- 0xb6, 0xfe, 0x7e, 0xf2, 0x92, 0x2f, 0x75, 0x2b, 0x5e, 0x65, 0x38, 0xb0,
- 0x75, 0x6e, 0x05, 0x7d, 0xba, 0xa1, 0x3c, 0xdc, 0x20, 0x5c, 0x72, 0x36,
- 0x8f, 0x08, 0x28, 0x67, 0xa3, 0x92, 0xa7, 0x15, 0x1a, 0xcc, 0xe3, 0x95,
- 0x46, 0xbf, 0x46, 0x3c, 0xee, 0x42, 0xc9, 0x32, 0x0d, 0x17, 0xa8, 0x73,
- 0xc2, 0x28, 0xed, 0xf8, 0xff, 0x20, 0xba, 0x17, 0xed, 0x85, 0x16, 0xf6,
- 0x98, 0x66, 0x7f, 0x48, 0x6a, 0x0c, 0x32, 0xaf, 0x03, 0x1f, 0x70, 0x2f,
- 0x7f, 0x35, 0x5a, 0x84, 0xf7, 0x53, 0x1a, 0x2e, 0xa5, 0xdb, 0xb0, 0x7b,
- 0x32, 0xc3, 0x33, 0x4e, 0x59, 0xfc, 0x5b, 0x63, 0x8e, 0xe9, 0xc0, 0xc1,
- 0xa8, 0x86, 0x58, 0xe2, 0x75, 0xb3, 0x40, 0xf3, 0x4d, 0xf9, 0xed, 0x0e,
- 0x1c, 0x48, 0x4f, 0x63, 0x72, 0xe0, 0x63, 0xd3, 0xae, 0x75, 0xe1, 0xa3,
- 0xd0, 0x34, 0x26, 0x0e, 0x49, 0x5f, 0x4f, 0x47, 0xff, 0x90, 0x86, 0xde,
- 0x84, 0x0d, 0x7b, 0x96, 0xb7, 0xa0, 0x7f, 0xb2, 0x19, 0xc6, 0x98, 0x07,
- 0x7b, 0xd2, 0x69, 0x4c, 0x8d, 0x4e, 0xe3, 0x4c, 0x52, 0x6b, 0x2c, 0x50,
- 0xa6, 0x71, 0x9a, 0xcf, 0xd9, 0x91, 0x78, 0x1b, 0x06, 0xe7, 0xd8, 0x99,
- 0x94, 0x9a, 0xa4, 0x3c, 0x67, 0x1a, 0xdd, 0xa9, 0xbb, 0xd5, 0x44, 0x28,
- 0x4f, 0xa2, 0xa7, 0x3d, 0x53, 0xab, 0x27, 0xbe, 0xa6, 0x35, 0xa5, 0x8f,
- 0xfb, 0x74, 0x34, 0x9d, 0xab, 0xdb, 0xdf, 0x59, 0x0b, 0xd1, 0xd1, 0x37,
- 0xd4, 0xc2, 0x31, 0x1a, 0xba, 0x13, 0xd2, 0x1b, 0xf5, 0xf1, 0x99, 0x26,
- 0x7e, 0xa9, 0x7b, 0xdd, 0x8b, 0xf9, 0xf7, 0xb0, 0xde, 0x89, 0x2d, 0x9c,
- 0x6b, 0x8a, 0x79, 0x90, 0xa6, 0x78, 0x1b, 0x0d, 0xd8, 0xf1, 0x9e, 0x4e,
- 0xce, 0x53, 0x69, 0xc7, 0xab, 0x7a, 0x09, 0x22, 0x65, 0x76, 0xd4, 0x87,
- 0x18, 0xa7, 0xb3, 0x71, 0xfb, 0xc3, 0xa4, 0x82, 0x47, 0x89, 0xa9, 0x27,
- 0x42, 0xf5, 0xed, 0xab, 0x85, 0xd1, 0x1d, 0x52, 0x70, 0x4d, 0xbb, 0x61,
- 0x1a, 0x8c, 0x5d, 0x2e, 0x7f, 0x6e, 0x8f, 0x7e, 0x6d, 0x66, 0xfa, 0x9b,
- 0x5f, 0x98, 0xb9, 0x71, 0x33, 0x94, 0xf1, 0x29, 0x8e, 0x5b, 0xbc, 0xac,
- 0xbe, 0x53, 0xc6, 0xb9, 0x89, 0xe9, 0x32, 0x4e, 0xea, 0xd1, 0xb7, 0xc6,
- 0xe9, 0xd8, 0x39, 0x14, 0xb1, 0xe4, 0xdd, 0x95, 0xc0, 0x52, 0x07, 0xc4,
- 0x9f, 0xea, 0xd5, 0x2b, 0x40, 0xd7, 0xb4, 0x3e, 0x87, 0x5c, 0xc7, 0x1f,
- 0xd8, 0x08, 0xd1, 0x95, 0xe4, 0x92, 0x6f, 0x63, 0x4f, 0x74, 0x14, 0xcc,
- 0x27, 0x89, 0x73, 0xfe, 0xf5, 0x23, 0x48, 0xe1, 0xf9, 0x74, 0x0a, 0x2f,
- 0x50, 0x47, 0x86, 0x75, 0x6e, 0x29, 0x8d, 0x3f, 0x8f, 0xbe, 0x8d, 0x98,
- 0xb5, 0x67, 0x47, 0xb1, 0x21, 0xfa, 0xf7, 0x55, 0xc2, 0x11, 0x77, 0x24,
- 0x56, 0x72, 0x7e, 0xd1, 0xab, 0xb7, 0xd5, 0xc0, 0x97, 0x9c, 0x7f, 0x25,
- 0x7a, 0x46, 0x4c, 0xf3, 0x7b, 0x8c, 0x5f, 0x3f, 0x23, 0xbf, 0xba, 0x96,
- 0x3d, 0x03, 0x55, 0x40, 0x7d, 0x6b, 0x56, 0x1c, 0x6b, 0xe3, 0x3e, 0x57,
- 0x0b, 0xaf, 0x47, 0xc9, 0xb8, 0xa6, 0x2c, 0x8e, 0xc9, 0xbe, 0x93, 0x37,
- 0x8e, 0x7b, 0xf0, 0x14, 0x39, 0x4a, 0xfe, 0xe1, 0x1f, 0x28, 0x12, 0xcb,
- 0x6a, 0x0e, 0x91, 0xef, 0x1f, 0xf2, 0x28, 0x4b, 0xf6, 0xb9, 0xf0, 0x68,
- 0x4c, 0xea, 0x37, 0xcd, 0xe8, 0xd9, 0xaf, 0xf1, 0x1e, 0xaf, 0x7e, 0x81,
- 0x39, 0xe9, 0x69, 0xf8, 0x3c, 0x23, 0xe4, 0x55, 0x6e, 0x62, 0xb1, 0xe3,
- 0x70, 0x29, 0x8a, 0x0e, 0xab, 0xb0, 0x1d, 0x2e, 0x47, 0xf1, 0x61, 0x37,
- 0x6a, 0x18, 0xdb, 0xdc, 0xe3, 0x17, 0x31, 0xb9, 0x0f, 0x6a, 0x51, 0xf8,
- 0x73, 0x33, 0x5f, 0x93, 0x3e, 0x5b, 0x00, 0xa5, 0xe3, 0xdb, 0x91, 0x8e,
- 0x05, 0x51, 0x3c, 0x4e, 0x2a, 0x35, 0x7e, 0x5c, 0xa9, 0xe7, 0x33, 0x1f,
- 0x8a, 0x69, 0x9c, 0x2b, 0xc3, 0x75, 0x56, 0x73, 0x5c, 0x5f, 0xc2, 0xbb,
- 0x5e, 0x7a, 0x65, 0xd7, 0xf4, 0x37, 0x50, 0x30, 0x70, 0xeb, 0x2c, 0x97,
- 0x16, 0xc2, 0x3c, 0x72, 0x91, 0xd6, 0x67, 0x91, 0x39, 0xd7, 0xf5, 0x70,
- 0x76, 0x4d, 0x41, 0x59, 0x93, 0xb3, 0x8d, 0xb6, 0x30, 0x57, 0xea, 0x5f,
- 0xb8, 0x4c, 0xfb, 0xb9, 0x9f, 0xf2, 0xde, 0x60, 0x6e, 0xd8, 0x19, 0x13,
- 0xbb, 0xff, 0x81, 0x42, 0xbf, 0xc1, 0x4c, 0xaa, 0x08, 0x1f, 0xa7, 0x3c,
- 0x8a, 0x8f, 0xeb, 0xf9, 0x0b, 0x5e, 0xff, 0x73, 0xae, 0x67, 0xc7, 0x7e,
- 0x6f, 0xeb, 0x49, 0xc5, 0xdb, 0xbe, 0x4e, 0xf1, 0xa9, 0x3b, 0x94, 0x62,
- 0x5c, 0x1e, 0x2d, 0xc5, 0x15, 0xc6, 0xe2, 0x1b, 0xa3, 0xe5, 0xb8, 0x3a,
- 0x5a, 0x49, 0x5f, 0xd1, 0x38, 0x87, 0x69, 0x96, 0x68, 0x6e, 0xcc, 0xa4,
- 0x5f, 0xc0, 0x9c, 0xd8, 0x02, 0x7c, 0x9c, 0xde, 0x82, 0xd2, 0x98, 0x70,
- 0x76, 0x0f, 0x3e, 0xe2, 0xf5, 0x0f, 0xd3, 0x13, 0x28, 0xdc, 0xf7, 0x39,
- 0xef, 0x31, 0xcd, 0x87, 0xb8, 0xc6, 0xab, 0xe9, 0x0e, 0x14, 0xef, 0xdb,
- 0x06, 0xc7, 0x3e, 0xb3, 0xab, 0x27, 0x84, 0x9f, 0xda, 0xb9, 0x96, 0x6e,
- 0xdd, 0x3b, 0xb5, 0xd8, 0x1e, 0xe4, 0x1c, 0x3a, 0xe7, 0x3c, 0xae, 0x2c,
- 0x19, 0xdf, 0x86, 0xd2, 0x7d, 0x1e, 0x6c, 0xa5, 0x2e, 0x27, 0xa0, 0x05,
- 0xd6, 0x29, 0xdb, 0x90, 0x77, 0x38, 0xa3, 0x83, 0x4d, 0xe3, 0x19, 0x1f,
- 0x79, 0xa8, 0x41, 0xea, 0x43, 0xc7, 0x95, 0x11, 0xcb, 0x47, 0xdc, 0x72,
- 0xfe, 0x04, 0xd3, 0xe9, 0x22, 0x9c, 0x4d, 0x89, 0x8e, 0xe4, 0xec, 0xda,
- 0x04, 0xf2, 0xf7, 0x11, 0x23, 0x47, 0x75, 0x8b, 0x43, 0x88, 0x6f, 0x8c,
- 0xa6, 0xef, 0xe6, 0x5f, 0x41, 0xec, 0x49, 0xd4, 0xd0, 0xb7, 0x16, 0x60,
- 0xcd, 0x3e, 0xe9, 0x91, 0x4e, 0xdd, 0xef, 0xa2, 0x35, 0x8d, 0xa5, 0xef,
- 0xe6, 0x5b, 0x0d, 0xb4, 0x53, 0x6f, 0x8b, 0x01, 0x39, 0xab, 0x61, 0x62,
- 0x5a, 0x3f, 0xae, 0xd8, 0x62, 0x92, 0x6f, 0xb5, 0xd1, 0xe7, 0x5b, 0xd1,
- 0x33, 0x84, 0xf6, 0x83, 0x0d, 0xd2, 0xb7, 0x75, 0x62, 0x84, 0xf9, 0xd3,
- 0x65, 0xe6, 0x1c, 0xd4, 0xb9, 0x9a, 0x17, 0xce, 0xc3, 0xf0, 0xa8, 0x0b,
- 0x3f, 0x1a, 0xf5, 0xa0, 0x31, 0xf6, 0x39, 0x31, 0xa3, 0x10, 0xc7, 0xa9,
- 0xef, 0x49, 0xf2, 0x9f, 0x8f, 0xa2, 0x2a, 0x26, 0x18, 0x6b, 0x3f, 0x8c,
- 0x56, 0x62, 0x9c, 0xb9, 0xd6, 0x75, 0xe2, 0x4c, 0x9a, 0x7b, 0xf3, 0x01,
- 0xf3, 0x8e, 0xef, 0xa5, 0x83, 0xf8, 0x55, 0x34, 0x88, 0x57, 0xa9, 0xc7,
- 0xba, 0x98, 0x9b, 0x32, 0x1d, 0x53, 0x70, 0xe8, 0xb8, 0x92, 0x47, 0xbb,
- 0xf0, 0xc7, 0x34, 0xcf, 0x48, 0xd6, 0x2e, 0xb4, 0xf1, 0x56, 0xfa, 0x91,
- 0xf4, 0xff, 0x25, 0x3e, 0x38, 0xf4, 0x11, 0x90, 0xd3, 0x05, 0x73, 0x75,
- 0x42, 0xaf, 0x7b, 0x0a, 0x15, 0xf4, 0xa5, 0x2f, 0x4d, 0x55, 0x93, 0x9a,
- 0x58, 0x32, 0x74, 0x2d, 0xaa, 0xa9, 0x57, 0xad, 0x35, 0x18, 0x8a, 0x73,
- 0x39, 0x39, 0x46, 0xe5, 0x0e, 0xae, 0x5f, 0x23, 0x66, 0x38, 0xe8, 0x32,
- 0x26, 0xef, 0xbb, 0x8e, 0xfb, 0x0e, 0xfd, 0x69, 0x75, 0x86, 0x03, 0xd1,
- 0x9f, 0x6d, 0x77, 0xd6, 0xb1, 0xa4, 0x96, 0xbd, 0x37, 0xf4, 0x46, 0x34,
- 0x56, 0x2d, 0x3d, 0xa5, 0x93, 0x08, 0x52, 0x2f, 0x77, 0xcb, 0x15, 0x4c,
- 0xbc, 0x45, 0x4c, 0xb9, 0x9a, 0x14, 0xbe, 0x24, 0x3c, 0xa9, 0x8b, 0x31,
- 0xa9, 0x84, 0x3c, 0x41, 0xc3, 0x4e, 0x72, 0x79, 0x5f, 0x7c, 0x8a, 0xb9,
- 0xca, 0x57, 0xc9, 0xd5, 0x4a, 0x39, 0x8d, 0xc1, 0xe7, 0xb5, 0x62, 0x0f,
- 0x7d, 0xb3, 0x40, 0x5b, 0x8c, 0x35, 0xe4, 0x41, 0x0e, 0x8d, 0xa1, 0xe4,
- 0x09, 0x89, 0x27, 0x40, 0x6d, 0x5c, 0x95, 0x7e, 0xcf, 0xfa, 0x9f, 0xe1,
- 0x7e, 0xb4, 0x57, 0xb9, 0x20, 0x3d, 0x9a, 0x37, 0xd1, 0x84, 0xd4, 0xd7,
- 0xad, 0xde, 0x30, 0xdc, 0x61, 0xcd, 0xb8, 0x88, 0x45, 0x16, 0x23, 0x2f,
- 0x0c, 0x8b, 0x3c, 0x95, 0xd4, 0xbf, 0x8a, 0x77, 0xa9, 0xd7, 0x2b, 0x51,
- 0xdf, 0xcc, 0x83, 0xa8, 0x3f, 0x73, 0xc5, 0x2e, 0xfd, 0x2b, 0xb9, 0x3f,
- 0x08, 0x8d, 0xf3, 0x7d, 0x1a, 0x0d, 0x61, 0x40, 0x95, 0xef, 0xc2, 0x1b,
- 0x5b, 0xd1, 0x3d, 0x22, 0x32, 0x98, 0x66, 0x39, 0xf1, 0xf1, 0x09, 0xeb,
- 0xf9, 0xf2, 0xec, 0x3b, 0xf3, 0x0e, 0xaf, 0x6a, 0x20, 0x97, 0x7b, 0x4c,
- 0xe3, 0x68, 0xd2, 0x03, 0xc7, 0xf2, 0xff, 0x41, 0x3d, 0x4c, 0x63, 0x34,
- 0xa5, 0x91, 0x53, 0x16, 0xc1, 0x53, 0x15, 0x44, 0x3f, 0xe3, 0x78, 0x8c,
- 0xf7, 0xa7, 0x63, 0x45, 0x30, 0xaa, 0x32, 0xcf, 0xfc, 0x6a, 0xfc, 0xba,
- 0x39, 0xf5, 0xb8, 0xcc, 0x29, 0xdf, 0x7f, 0xce, 0x31, 0x73, 0xe5, 0xd8,
- 0x23, 0x36, 0xc7, 0xae, 0x9a, 0x53, 0xad, 0xb3, 0x7f, 0x2f, 0xb3, 0xce,
- 0x10, 0x45, 0x6c, 0x55, 0x52, 0x6f, 0xb1, 0xf4, 0xd2, 0x4d, 0xbd, 0xcc,
- 0xd1, 0xde, 0x36, 0x1f, 0xb3, 0xe4, 0x9a, 0xaa, 0x16, 0x9e, 0x5f, 0x1b,
- 0xff, 0xbc, 0x5a, 0xea, 0xa5, 0x12, 0xc3, 0x5c, 0x61, 0xad, 0xf1, 0x0c,
- 0xfe, 0xd1, 0xbc, 0x74, 0xdb, 0x3c, 0x15, 0xbc, 0x26, 0xf1, 0xe8, 0x52,
- 0xb6, 0x1f, 0xed, 0xce, 0xe6, 0x02, 0xd3, 0x38, 0x99, 0x94, 0x58, 0xe0,
- 0xc1, 0x06, 0xa9, 0x43, 0xa9, 0xde, 0x3e, 0x03, 0x53, 0xe4, 0x7e, 0xef,
- 0x50, 0xf7, 0x4c, 0x80, 0xfc, 0x53, 0xe4, 0x7f, 0xb3, 0xe3, 0x55, 0x04,
- 0xa9, 0x4a, 0xe9, 0x29, 0x08, 0x9e, 0x4e, 0x63, 0x57, 0xf2, 0x75, 0xe2,
- 0xda, 0xc7, 0xe4, 0x43, 0x5d, 0xe4, 0xda, 0xd3, 0xe8, 0x49, 0x35, 0xe3,
- 0xe5, 0xfd, 0x2d, 0xc4, 0x18, 0xc1, 0x4a, 0xdf, 0x99, 0xcb, 0xf6, 0x66,
- 0x1c, 0x1c, 0x4b, 0x23, 0x75, 0x58, 0x62, 0xa4, 0x9c, 0xc7, 0x92, 0xf8,
- 0xa8, 0x21, 0x9a, 0x38, 0x0d, 0x83, 0x7f, 0xf7, 0x24, 0xb6, 0x21, 0x72,
- 0xf8, 0x6d, 0x72, 0xfc, 0x69, 0xac, 0x1e, 0xd0, 0xd6, 0x1f, 0xc1, 0x34,
- 0xd6, 0x32, 0x7e, 0x26, 0x13, 0x2d, 0x9c, 0xbf, 0x19, 0xbd, 0xfb, 0xbd,
- 0x01, 0x87, 0x6d, 0x0e, 0x63, 0x94, 0x07, 0x3b, 0x27, 0x23, 0x30, 0x46,
- 0xe4, 0x8c, 0x81, 0x0b, 0xc1, 0xb8, 0x47, 0xf9, 0x90, 0x3c, 0xb9, 0x3e,
- 0xee, 0x65, 0x7e, 0xe6, 0x35, 0xd6, 0x2a, 0x3e, 0x4f, 0x9e, 0x4d, 0xfa,
- 0x59, 0x73, 0x70, 0x46, 0x57, 0x50, 0x70, 0xbf, 0x82, 0x10, 0x63, 0x97,
- 0xa7, 0x9a, 0x31, 0x65, 0x44, 0x47, 0xef, 0x10, 0xd7, 0x7b, 0x73, 0xdf,
- 0x64, 0xbf, 0x1e, 0xe1, 0x7c, 0xb2, 0x77, 0x2d, 0xe8, 0x9d, 0xf4, 0x75,
- 0x9c, 0x81, 0xdb, 0xe2, 0x5c, 0xbd, 0x43, 0xb9, 0x7b, 0x50, 0xfc, 0x71,
- 0x83, 0x37, 0x30, 0x47, 0x91, 0x7b, 0x77, 0x10, 0xbf, 0x66, 0xdf, 0x6f,
- 0x28, 0xc9, 0xe5, 0xe4, 0xa5, 0x36, 0xf1, 0x8b, 0x6e, 0xcb, 0x5f, 0x44,
- 0x17, 0xbd, 0xc9, 0x08, 0x6d, 0xfa, 0xc7, 0x66, 0xaa, 0xb5, 0x95, 0x72,
- 0x36, 0x48, 0xaf, 0xc7, 0xe2, 0x26, 0xe7, 0xa5, 0xee, 0xe6, 0x94, 0xd8,
- 0xdd, 0xdd, 0xee, 0xa2, 0x3d, 0xe5, 0x13, 0x9f, 0x0a, 0x26, 0x5c, 0x70,
- 0x1d, 0x29, 0x42, 0xfe, 0xb0, 0xf0, 0x34, 0xa8, 0xa5, 0xcc, 0xfb, 0xe5,
- 0x3c, 0xc3, 0x30, 0x6d, 0xd4, 0x36, 0x41, 0x1f, 0x8b, 0xba, 0xb1, 0x68,
- 0xc2, 0x8d, 0x1f, 0x11, 0x03, 0x6a, 0x26, 0x34, 0x1c, 0x27, 0x06, 0xb8,
- 0x27, 0x02, 0x98, 0x24, 0x06, 0xcc, 0xc9, 0xd6, 0x3e, 0xde, 0x4c, 0xcf,
- 0x9f, 0x8b, 0x42, 0x79, 0x96, 0xe8, 0x31, 0xb7, 0xaf, 0xb2, 0xa7, 0x2d,
- 0xc4, 0x3d, 0xd9, 0xdf, 0x00, 0x76, 0x0f, 0xa5, 0xb1, 0x6a, 0x9f, 0x89,
- 0x9f, 0xeb, 0xf5, 0xee, 0x02, 0x45, 0xf2, 0x04, 0x13, 0x69, 0x5d, 0xce,
- 0x4d, 0x7a, 0xd7, 0xcb, 0xb9, 0xe2, 0xf6, 0x4a, 0x13, 0x79, 0x21, 0xaf,
- 0x4e, 0xb4, 0x5f, 0x5f, 0xa0, 0x48, 0xdc, 0xaa, 0xf7, 0x6c, 0xc1, 0x7c,
- 0x64, 0x7a, 0x65, 0x0f, 0x62, 0x8b, 0xaa, 0xd0, 0x1f, 0x5b, 0xb0, 0xa7,
- 0xcc, 0x70, 0x5d, 0x6b, 0x30, 0xcd, 0x4d, 0xa1, 0xdf, 0x56, 0x59, 0xb5,
- 0x65, 0xdb, 0x1f, 0x71, 0xed, 0x6d, 0x5c, 0xb7, 0xac, 0xbd, 0x03, 0xb1,
- 0xbd, 0x0a, 0xd2, 0xfe, 0x0e, 0x44, 0x47, 0x3b, 0xd0, 0xbf, 0x57, 0x30,
- 0xa1, 0x8f, 0x98, 0x60, 0x76, 0x3d, 0x1b, 0x7a, 0x0c, 0x57, 0x2d, 0x16,
- 0x20, 0x63, 0xbc, 0x01, 0x8f, 0x6d, 0xf6, 0x3e, 0xe4, 0x53, 0xfe, 0x8c,
- 0xef, 0x34, 0x0f, 0x08, 0xa7, 0xf6, 0xf7, 0xf5, 0x72, 0xff, 0x1f, 0x3f,
- 0x24, 0xf1, 0xc6, 0x34, 0xfb, 0xc8, 0x59, 0x51, 0x26, 0x6b, 0xd0, 0xa4,
- 0x3e, 0xfe, 0x71, 0x8d, 0xe6, 0x9b, 0xe9, 0x67, 0x6c, 0xbf, 0xb8, 0xaf,
- 0x7e, 0xcb, 0x16, 0xe1, 0x31, 0xcb, 0x84, 0xdb, 0xa5, 0x71, 0xe1, 0xf0,
- 0x7d, 0x48, 0x3d, 0xce, 0xf5, 0x70, 0xaf, 0x9c, 0xf1, 0x2f, 0x4c, 0xe1,
- 0x72, 0x76, 0x4d, 0x53, 0x8f, 0x12, 0xfb, 0x6c, 0x13, 0x7e, 0xf4, 0x94,
- 0xc1, 0xb8, 0xd6, 0x20, 0xcf, 0xbf, 0x29, 0x3f, 0xd7, 0xdb, 0x8c, 0xfe,
- 0xfd, 0xc2, 0x35, 0x84, 0x97, 0xf9, 0x8c, 0x0f, 0xd0, 0x82, 0xe4, 0x64,
- 0xe6, 0x59, 0xd1, 0xc4, 0x9d, 0xb6, 0x22, 0xfb, 0x7e, 0x1a, 0xbb, 0x69,
- 0x97, 0x2e, 0xce, 0xcf, 0xf8, 0xc2, 0xf9, 0xb4, 0x40, 0x81, 0x3c, 0x6f,
- 0xe2, 0xc7, 0xe6, 0x9e, 0x2a, 0xd1, 0x8d, 0xcc, 0x7f, 0xba, 0x4a, 0x30,
- 0x63, 0x53, 0xe8, 0x0f, 0xad, 0xf5, 0x75, 0xfe, 0xf5, 0xb6, 0x64, 0xf4,
- 0x21, 0xf7, 0x9e, 0xfe, 0x3d, 0xf2, 0x5c, 0xe0, 0x7d, 0x22, 0x53, 0x07,
- 0x76, 0xef, 0x85, 0x51, 0xa8, 0x49, 0xaf, 0xa0, 0x03, 0x7d, 0xd4, 0xef,
- 0xce, 0x64, 0x07, 0x0e, 0xd2, 0x67, 0x87, 0xf5, 0x13, 0x35, 0x36, 0xd4,
- 0xcd, 0xd8, 0x31, 0xf5, 0x93, 0x45, 0xc4, 0xd3, 0x25, 0xcb, 0xfc, 0xf4,
- 0xaf, 0x0e, 0xc4, 0x53, 0x63, 0x73, 0xad, 0x3e, 0x9f, 0x4d, 0xe2, 0x9f,
- 0xe8, 0xa2, 0x13, 0x85, 0x03, 0xa7, 0xe1, 0x1c, 0xe8, 0x44, 0x81, 0xbf,
- 0x09, 0x0f, 0x87, 0x2e, 0x99, 0x57, 0x35, 0x87, 0xfb, 0x24, 0xf5, 0x73,
- 0x22, 0x58, 0xc3, 0x7c, 0x92, 0x39, 0xcc, 0xc8, 0x3c, 0xfa, 0x7e, 0x03,
- 0xf9, 0xae, 0xf4, 0xf4, 0x6d, 0x58, 0xbb, 0x5c, 0x72, 0x75, 0x85, 0xb6,
- 0x5d, 0xcd, 0x5c, 0x53, 0x53, 0x9f, 0xb7, 0xce, 0x5f, 0x90, 0x87, 0x55,
- 0x7a, 0xf0, 0x8c, 0x75, 0xee, 0x40, 0xae, 0x6f, 0x67, 0x8e, 0xb0, 0x1d,
- 0x35, 0x31, 0xc3, 0x14, 0x7d, 0x9f, 0x44, 0xe4, 0x25, 0x1b, 0xe5, 0x68,
- 0x5c, 0xe6, 0xdf, 0x32, 0xa3, 0x88, 0x4d, 0xfb, 0xdb, 0x27, 0x14, 0xdd,
- 0xf5, 0xc8, 0xb8, 0x82, 0xc0, 0x00, 0xe7, 0x0a, 0xfd, 0xf5, 0xdc, 0x4c,
- 0x7d, 0x2c, 0xc7, 0xf9, 0xb6, 0x93, 0x27, 0x6c, 0x47, 0x09, 0xc7, 0xbb,
- 0x35, 0xc1, 0x86, 0xc8, 0x4a, 0xe9, 0xa5, 0xa4, 0x43, 0xfe, 0xd6, 0x62,
- 0x45, 0xf8, 0x90, 0xbf, 0x71, 0xad, 0x22, 0xdc, 0x45, 0xc6, 0xe9, 0xae,
- 0xba, 0xf1, 0x8b, 0xd9, 0x9e, 0x57, 0x03, 0xf1, 0xc1, 0x63, 0x9d, 0x85,
- 0x7c, 0xed, 0xe6, 0x79, 0x89, 0x4c, 0xbd, 0xda, 0x19, 0x97, 0xbc, 0xe2,
- 0x58, 0x68, 0x55, 0xb4, 0x91, 0x58, 0x67, 0x36, 0x8d, 0xd1, 0xee, 0x2f,
- 0xa3, 0x12, 0xff, 0x33, 0x2a, 0xb8, 0xe6, 0xc1, 0xff, 0x8a, 0xe6, 0x4b,
- 0xbe, 0x9c, 0x92, 0x7a, 0xe4, 0xb9, 0xa4, 0x61, 0x52, 0xaf, 0x2d, 0x6b,
- 0x69, 0x4b, 0x81, 0x50, 0x31, 0x50, 0xd5, 0xfd, 0x8c, 0xd3, 0xca, 0xdf,
- 0x4b, 0x50, 0xc6, 0x18, 0x30, 0x30, 0xf2, 0xfb, 0x6a, 0xaf, 0xc4, 0xe1,
- 0x42, 0xa9, 0x81, 0xda, 0xb1, 0x33, 0xf4, 0x2f, 0x66, 0x2a, 0x7b, 0x76,
- 0xf5, 0xc2, 0x5e, 0xb1, 0xd3, 0x00, 0xf2, 0xe3, 0x17, 0x69, 0x93, 0x2a,
- 0xce, 0x47, 0x7d, 0xfa, 0x3a, 0xdb, 0x37, 0x68, 0xff, 0x8b, 0x6e, 0xc3,
- 0xee, 0x45, 0xda, 0xa3, 0x78, 0xda, 0xc2, 0xee, 0x30, 0x7a, 0x18, 0x1b,
- 0xc8, 0xe3, 0x0e, 0x3c, 0x63, 0x53, 0x51, 0x10, 0xf3, 0xa9, 0x3e, 0xe6,
- 0xdb, 0x3d, 0x7c, 0x86, 0x70, 0xcc, 0x0a, 0x72, 0xc0, 0x67, 0xa3, 0xf5,
- 0x9e, 0x5f, 0x63, 0x03, 0xfd, 0x51, 0x9e, 0x21, 0x6b, 0xd2, 0x50, 0xcc,
- 0xbc, 0xf2, 0x14, 0xd7, 0xb1, 0xb3, 0x2c, 0xf3, 0xdc, 0xd2, 0xec, 0xdc,
- 0xf1, 0x11, 0xe1, 0x5f, 0x2b, 0xb0, 0xce, 0x9a, 0x3b, 0x68, 0xf9, 0xe6,
- 0x01, 0x39, 0x5b, 0x5e, 0xa7, 0x21, 0x91, 0x6e, 0xc6, 0xb6, 0xf2, 0x05,
- 0x38, 0x98, 0xd8, 0x8e, 0xa5, 0xe4, 0xc1, 0x4f, 0x96, 0x1b, 0x8c, 0x8d,
- 0xc4, 0xa1, 0xb8, 0xa6, 0xde, 0xa7, 0x3c, 0x90, 0xed, 0x3f, 0x54, 0xc2,
- 0x11, 0x97, 0x98, 0x97, 0x87, 0x41, 0x75, 0x3e, 0x8a, 0xac, 0x33, 0x7f,
- 0x99, 0xb9, 0xfb, 0x47, 0xbc, 0xd9, 0x38, 0x48, 0xd4, 0x88, 0x5b, 0xe7,
- 0x2d, 0x02, 0x2f, 0x90, 0x4b, 0xa4, 0x18, 0x01, 0xf3, 0xc2, 0x5a, 0x6a,
- 0x33, 0x0a, 0x60, 0x54, 0x0b, 0x26, 0xca, 0x98, 0x79, 0x77, 0xc8, 0x54,
- 0x9e, 0x95, 0x29, 0x77, 0x3d, 0xc5, 0x6b, 0x62, 0x5b, 0xc2, 0x2f, 0xe4,
- 0xf7, 0x42, 0xb4, 0xd2, 0x9e, 0x2a, 0x29, 0x73, 0xc2, 0x3a, 0xb7, 0xe9,
- 0xd5, 0x0d, 0x5b, 0x03, 0x3e, 0xdb, 0x97, 0xb1, 0xc1, 0xf5, 0xb5, 0xdc,
- 0xff, 0xd2, 0x06, 0xcc, 0x1c, 0x96, 0x78, 0xf6, 0xfb, 0xcf, 0x52, 0x18,
- 0x37, 0xcf, 0x52, 0x88, 0x5e, 0xbd, 0x67, 0xde, 0x45, 0xfd, 0xd4, 0x53,
- 0xb6, 0xa3, 0x26, 0x2a, 0x44, 0xc7, 0x9b, 0xdd, 0x92, 0x87, 0xda, 0xc8,
- 0x23, 0x8c, 0x74, 0xd2, 0x2d, 0xb1, 0xd2, 0x11, 0x07, 0x16, 0xc5, 0x0d,
- 0xe4, 0x87, 0xb5, 0x03, 0xd7, 0xec, 0x37, 0xcc, 0xf6, 0xea, 0x79, 0xcc,
- 0x03, 0x6f, 0xad, 0xb9, 0x8f, 0xb2, 0xdb, 0xb5, 0x1f, 0x9b, 0x0f, 0x56,
- 0x8a, 0x8c, 0x3f, 0x72, 0x67, 0xea, 0xcc, 0x0b, 0xa9, 0x97, 0x9c, 0x4e,
- 0x4c, 0xda, 0xcf, 0xdf, 0x98, 0x5f, 0xbb, 0xed, 0xba, 0xf0, 0x19, 0xb1,
- 0xd3, 0xd9, 0x67, 0xdb, 0xc4, 0x66, 0x3d, 0xb4, 0xd3, 0x69, 0x8c, 0x25,
- 0x1b, 0x30, 0x90, 0x10, 0x1d, 0x47, 0x70, 0x99, 0xfc, 0xb0, 0x76, 0x70,
- 0x1a, 0xc3, 0xe4, 0x87, 0xbe, 0xb8, 0xf7, 0x00, 0x35, 0x89, 0x6d, 0x6a,
- 0x93, 0xc5, 0x93, 0x5c, 0x5a, 0x4e, 0x86, 0xaf, 0x5a, 0x7a, 0x97, 0x18,
- 0xb3, 0x87, 0xeb, 0xbd, 0x97, 0x3c, 0xa9, 0x39, 0x96, 0x0f, 0xad, 0xac,
- 0x14, 0xc5, 0x9a, 0xf4, 0x2b, 0x32, 0xf7, 0x45, 0x29, 0x4b, 0x91, 0xe6,
- 0xc3, 0x5a, 0xeb, 0x5e, 0x8f, 0x75, 0xae, 0xc1, 0x51, 0x2e, 0x31, 0x58,
- 0xe2, 0x2e, 0xf9, 0xf7, 0x72, 0x89, 0xbb, 0x61, 0xca, 0xb6, 0x98, 0x7b,
- 0xb6, 0x14, 0xee, 0x07, 0x3c, 0xa8, 0x79, 0x80, 0x31, 0x72, 0x89, 0x82,
- 0xf2, 0x25, 0x7e, 0x63, 0xa9, 0xad, 0x19, 0xa8, 0xd6, 0x88, 0x3f, 0x6e,
- 0xb3, 0x27, 0xf1, 0x3b, 0xce, 0xd1, 0x01, 0x73, 0x6f, 0x21, 0x36, 0xec,
- 0x9d, 0x43, 0x5b, 0xf5, 0x48, 0x7d, 0xdd, 0xe5, 0x0a, 0x47, 0x43, 0xae,
- 0x58, 0xbd, 0xee, 0x54, 0x16, 0x33, 0x1e, 0xcb, 0xfe, 0xc9, 0xf3, 0xbf,
- 0x72, 0x1b, 0x5f, 0xaa, 0x60, 0x7c, 0x7b, 0xd2, 0x92, 0x41, 0x6a, 0xc0,
- 0x32, 0xee, 0xdf, 0xee, 0xd3, 0xd4, 0xcd, 0x7d, 0xba, 0x0f, 0x8e, 0x27,
- 0x2a, 0xc9, 0xbf, 0xee, 0x1e, 0x43, 0x0a, 0x18, 0x43, 0xee, 0x8d, 0x99,
- 0x5d, 0x5b, 0x43, 0x45, 0x52, 0x17, 0xb2, 0x62, 0x48, 0xbb, 0x8d, 0x38,
- 0x5a, 0x2a, 0x76, 0xe1, 0xab, 0x21, 0xc6, 0xe9, 0x99, 0xdf, 0xc4, 0x3e,
- 0xac, 0x3a, 0x5e, 0xf6, 0xb7, 0x0e, 0xec, 0x22, 0x66, 0xca, 0xd9, 0x6e,
- 0xa7, 0xa6, 0xd1, 0xff, 0x3b, 0xd0, 0xc3, 0x39, 0x5f, 0x26, 0x6e, 0x0e,
- 0x10, 0x37, 0x6f, 0x2c, 0x3b, 0xf1, 0x93, 0x1a, 0xd4, 0xd1, 0x08, 0xa6,
- 0xfe, 0x5b, 0xb9, 0xe0, 0xe6, 0x52, 0x7f, 0xc7, 0x27, 0x16, 0x6e, 0xca,
- 0xdc, 0x32, 0xdf, 0xec, 0xb9, 0x17, 0xf2, 0xdf, 0x85, 0x52, 0x4b, 0x34,
- 0x9d, 0xda, 0xff, 0x36, 0x77, 0x56, 0x8a, 0xac, 0x77, 0x93, 0x43, 0xb0,
- 0x76, 0x76, 0x4f, 0x7e, 0x9a, 0x98, 0x6b, 0xe5, 0x08, 0x8c, 0xb9, 0x11,
- 0xac, 0x59, 0xae, 0xe2, 0x6a, 0x74, 0x1a, 0x05, 0x87, 0x72, 0xf8, 0x64,
- 0x36, 0x9d, 0x22, 0x36, 0x0d, 0x43, 0xf0, 0xa8, 0x91, 0xfb, 0x62, 0xd0,
- 0x4f, 0x4a, 0x30, 0x91, 0xd4, 0x88, 0x99, 0x26, 0xfa, 0x43, 0x2e, 0x72,
- 0xdb, 0xee, 0x93, 0x79, 0x56, 0x9c, 0x28, 0x21, 0x86, 0xe7, 0x78, 0xb7,
- 0x70, 0x6e, 0xc1, 0x1f, 0xe6, 0x18, 0x23, 0x76, 0xe4, 0x2d, 0x93, 0xbc,
- 0xe2, 0x73, 0xf3, 0x42, 0x9b, 0xdc, 0xb7, 0x00, 0xc3, 0x7b, 0xc5, 0xfe,
- 0x7c, 0xa8, 0xd1, 0x2e, 0x32, 0xcf, 0x00, 0xde, 0x8f, 0xda, 0xee, 0x71,
- 0x91, 0x1b, 0x77, 0xe9, 0xcb, 0x71, 0xa3, 0xa2, 0x87, 0x3e, 0xef, 0xe6,
- 0x6f, 0x53, 0x38, 0x12, 0x75, 0x21, 0xcf, 0xd2, 0x69, 0x29, 0xd7, 0x90,
- 0xb1, 0xa1, 0x9d, 0xb4, 0xa1, 0x7c, 0xe6, 0x6f, 0x0f, 0x5b, 0xbe, 0x2a,
- 0xf3, 0x4c, 0xe3, 0x15, 0x72, 0x5a, 0x6d, 0xb9, 0xf0, 0xd9, 0x20, 0xe3,
- 0x62, 0x09, 0xe2, 0x03, 0x5d, 0x38, 0x1f, 0x2a, 0x41, 0xec, 0x90, 0xf8,
- 0xd8, 0x02, 0xc1, 0x52, 0x3e, 0xb7, 0x91, 0x3a, 0x51, 0x89, 0x35, 0xf5,
- 0x9d, 0x76, 0x7b, 0x09, 0x2e, 0x95, 0x31, 0xaf, 0xb5, 0xde, 0xe3, 0x69,
- 0xc5, 0xc1, 0xac, 0x5d, 0xa8, 0xb4, 0x8b, 0xd6, 0x9b, 0x3c, 0x3a, 0xb7,
- 0x96, 0x9c, 0xcf, 0x66, 0xfa, 0xe1, 0xbd, 0xe4, 0x36, 0x2f, 0x4b, 0xfd,
- 0xc8, 0xe6, 0x63, 0x2c, 0x61, 0xce, 0x34, 0x29, 0xfa, 0xfd, 0xeb, 0xb9,
- 0x19, 0xac, 0x78, 0xa5, 0x26, 0x73, 0x76, 0x25, 0xa7, 0xf7, 0xdc, 0x77,
- 0x6d, 0x7d, 0xa1, 0xf2, 0x0b, 0x73, 0x6b, 0x95, 0xc8, 0x77, 0x9d, 0x79,
- 0xda, 0x77, 0xf9, 0xfb, 0x2a, 0xf4, 0x8e, 0xcc, 0x8e, 0x15, 0xe2, 0x87,
- 0x9e, 0xdb, 0xce, 0xd5, 0x95, 0xc5, 0xe5, 0xdd, 0xa9, 0x63, 0xa1, 0x67,
- 0xb8, 0x0f, 0xfe, 0xa5, 0xf5, 0x56, 0xdd, 0x85, 0xdc, 0x97, 0x79, 0x89,
- 0x60, 0xac, 0xc1, 0x18, 0x5f, 0x82, 0x9f, 0x26, 0x25, 0xe6, 0x9a, 0xc8,
- 0xa7, 0xfd, 0x5d, 0xaa, 0xec, 0x7e, 0xbe, 0xcc, 0xe2, 0xd2, 0x25, 0x28,
- 0xa7, 0xbd, 0x0f, 0x8e, 0xdc, 0xcd, 0xb6, 0x6f, 0xc5, 0x85, 0x74, 0x48,
- 0x21, 0x4e, 0xfc, 0x8b, 0xd9, 0xff, 0xf5, 0xcc, 0x98, 0x0b, 0x49, 0x17,
- 0x3e, 0x0a, 0xb5, 0x63, 0xaa, 0x2c, 0x8c, 0xa1, 0x44, 0x01, 0xda, 0xab,
- 0xeb, 0xac, 0x77, 0x0a, 0x6a, 0xe2, 0x1e, 0x5c, 0x8c, 0x3a, 0xd1, 0x38,
- 0xd7, 0x63, 0xd5, 0xd3, 0x6c, 0xf4, 0x85, 0x77, 0xa2, 0x11, 0xcb, 0xe7,
- 0x66, 0xc7, 0x8c, 0x3c, 0x6d, 0x19, 0x1e, 0xca, 0xe2, 0xfa, 0xc1, 0xc4,
- 0xe7, 0xc4, 0x9d, 0x52, 0xa3, 0x22, 0x5c, 0x82, 0x7b, 0x87, 0x0c, 0xc1,
- 0x64, 0xa3, 0x24, 0xac, 0xcd, 0xdc, 0xa7, 0x94, 0xa0, 0x69, 0x44, 0x30,
- 0x5e, 0x7c, 0x35, 0x4d, 0x5f, 0x6d, 0xe3, 0x1e, 0x75, 0xa2, 0x6e, 0xbf,
- 0xa5, 0x57, 0xd5, 0xae, 0x98, 0x5d, 0x57, 0xf4, 0x88, 0xce, 0x18, 0xd7,
- 0xf9, 0x10, 0xed, 0x7e, 0x26, 0xe4, 0x6d, 0xaf, 0xb0, 0x6b, 0x1d, 0xef,
- 0x29, 0x41, 0x4c, 0x8c, 0x03, 0x03, 0x87, 0x03, 0xf8, 0x20, 0x21, 0x9c,
- 0x3f, 0x80, 0x5f, 0x4d, 0x06, 0xf1, 0x2e, 0x63, 0x53, 0x41, 0xdc, 0x1b,
- 0x79, 0x8e, 0x39, 0xdd, 0xfb, 0xfc, 0x9e, 0x1f, 0xd7, 0x71, 0x8d, 0xfa,
- 0x73, 0xc6, 0x1b, 0x70, 0x65, 0xf2, 0x01, 0x5c, 0xdd, 0xaf, 0xe0, 0x84,
- 0xf6, 0x00, 0x2e, 0x8f, 0x75, 0x62, 0xd9, 0x7e, 0x39, 0x87, 0x76, 0x2c,
- 0xa4, 0x32, 0x36, 0x3c, 0x53, 0x6b, 0x76, 0xbd, 0xa8, 0xd7, 0x41, 0x2f,
- 0xf7, 0xea, 0xed, 0xcc, 0x99, 0x04, 0xd3, 0x23, 0x36, 0xd9, 0x33, 0xd9,
- 0xbb, 0x4e, 0x5c, 0xb5, 0x70, 0xfc, 0xee, 0xd8, 0x70, 0x0b, 0xc3, 0xe5,
- 0x39, 0x82, 0x27, 0x0b, 0xf1, 0x7d, 0x26, 0xab, 0x3d, 0xbc, 0xcf, 0x45,
- 0xec, 0x7b, 0x36, 0x5a, 0x80, 0xfc, 0xaa, 0x52, 0x2b, 0x97, 0x29, 0x8c,
- 0x07, 0x70, 0x96, 0xba, 0x5b, 0x53, 0xe5, 0xe5, 0x77, 0x89, 0xbb, 0x41,
- 0xe6, 0x2d, 0x15, 0xf8, 0xe0, 0xb6, 0x78, 0xfb, 0x7d, 0xf3, 0x49, 0x0b,
- 0x9f, 0xeb, 0xe7, 0x09, 0xff, 0x7a, 0x3d, 0xf1, 0xeb, 0x1a, 0xc1, 0x69,
- 0xa9, 0x21, 0x96, 0x6a, 0xda, 0x96, 0xbf, 0x80, 0xbc, 0x6f, 0x75, 0xe2,
- 0x3f, 0x17, 0x93, 0x17, 0xbf, 0x18, 0xaa, 0x33, 0xca, 0xa0, 0xf1, 0xbe,
- 0xa9, 0x65, 0x2a, 0x56, 0xf1, 0xaf, 0x9f, 0xf7, 0x05, 0x29, 0xc7, 0x75,
- 0x33, 0xa5, 0xfa, 0xf8, 0xef, 0x05, 0x8c, 0xef, 0xdb, 0x71, 0x3e, 0x56,
- 0xdf, 0x7e, 0x58, 0xb9, 0x66, 0x1a, 0x55, 0xb5, 0xfc, 0xad, 0x12, 0x17,
- 0xa2, 0xde, 0xa9, 0x31, 0xd4, 0x7b, 0x66, 0x94, 0x83, 0xa6, 0xa1, 0xca,
- 0xfe, 0xc8, 0x7a, 0x65, 0xfc, 0x62, 0x5e, 0xbf, 0x34, 0xcb, 0x0e, 0x6f,
- 0xe5, 0x5d, 0xce, 0x9b, 0xf6, 0x27, 0xbc, 0xc4, 0x6c, 0x1a, 0xd5, 0xeb,
- 0xd5, 0x1e, 0x62, 0x41, 0x44, 0xbd, 0x9b, 0xfd, 0x15, 0xd0, 0xfe, 0xc2,
- 0xcc, 0x23, 0x4b, 0xa0, 0x5a, 0xf1, 0xa9, 0x15, 0xc9, 0x91, 0xd9, 0xdc,
- 0x52, 0xec, 0x2e, 0xc3, 0x53, 0xdb, 0xcb, 0xba, 0x4f, 0x3a, 0x89, 0x45,
- 0x09, 0xe2, 0x78, 0x9c, 0x38, 0x9e, 0x4f, 0x1c, 0xbf, 0xbe, 0xaf, 0x10,
- 0xe7, 0xf7, 0x35, 0x22, 0x5d, 0x26, 0x63, 0xec, 0x70, 0x72, 0x75, 0xa9,
- 0xec, 0x79, 0x85, 0x9a, 0xc1, 0x95, 0x72, 0x8e, 0x13, 0x82, 0x5f, 0x79,
- 0x71, 0xe6, 0x59, 0xad, 0x76, 0x38, 0xac, 0x33, 0xf6, 0x73, 0x6e, 0xb3,
- 0x3f, 0x97, 0x96, 0x8f, 0x96, 0x4a, 0xc1, 0x87, 0xd7, 0xe7, 0x49, 0x1c,
- 0x7d, 0x9d, 0xb2, 0x9c, 0xa4, 0x4d, 0x6f, 0xd4, 0x57, 0x48, 0x5f, 0x8f,
- 0xf7, 0xcb, 0x38, 0xc9, 0x6d, 0x4c, 0xec, 0xa6, 0x85, 0xd5, 0x55, 0x99,
- 0x48, 0xe8, 0x61, 0xc6, 0xac, 0x10, 0x22, 0x65, 0x41, 0xc6, 0x2a, 0xf9,
- 0xae, 0xe2, 0x0a, 0xf3, 0xb2, 0xf1, 0xa0, 0x82, 0x8f, 0xbe, 0x22, 0x5c,
- 0xc0, 0xaf, 0x9f, 0x57, 0x84, 0x0b, 0xc8, 0x78, 0xc1, 0x88, 0x52, 0x0b,
- 0x23, 0xf2, 0x2d, 0x5e, 0x34, 0xd7, 0xc2, 0x16, 0x79, 0x47, 0xa9, 0x86,
- 0x71, 0xe7, 0xfe, 0x44, 0xfd, 0x94, 0xcf, 0x4e, 0x8e, 0xf6, 0x27, 0x5f,
- 0x21, 0x37, 0xb3, 0x38, 0x02, 0xf1, 0x3e, 0x87, 0x0d, 0x72, 0xee, 0x76,
- 0xb6, 0x3e, 0x72, 0xe7, 0x72, 0x3d, 0x19, 0xac, 0x2c, 0x15, 0x2e, 0xf7,
- 0xff, 0xcc, 0xd6, 0xdb, 0xe4, 0xcf, 0xe1, 0xc8, 0x3f, 0xf0, 0xbb, 0x8c,
- 0x17, 0xbf, 0xa3, 0x5d, 0xc4, 0x7f, 0x62, 0x3e, 0x6d, 0xf1, 0xb9, 0x97,
- 0xe7, 0xc9, 0xf9, 0x43, 0xc7, 0xe0, 0xd0, 0x3c, 0x39, 0x6f, 0x65, 0x9b,
- 0xc5, 0x0b, 0x32, 0xb1, 0xf6, 0x5d, 0x73, 0xad, 0x25, 0xeb, 0x91, 0xec,
- 0x7d, 0x92, 0x43, 0x8b, 0x2c, 0x0a, 0x5e, 0xd1, 0xea, 0xd5, 0xb3, 0x28,
- 0x16, 0x3c, 0x89, 0x48, 0x0f, 0xb3, 0x50, 0xf3, 0xb9, 0x8f, 0xf0, 0x6f,
- 0x3f, 0xaf, 0xbf, 0xa1, 0x39, 0x1a, 0xb7, 0x42, 0xfa, 0xb6, 0x36, 0xee,
- 0x55, 0xbd, 0xfb, 0x2c, 0xfc, 0x91, 0x7c, 0x65, 0xc6, 0x6c, 0xaf, 0x94,
- 0x7b, 0x32, 0xfd, 0x5b, 0x28, 0x17, 0xad, 0xfa, 0x49, 0xc6, 0x66, 0x16,
- 0xd0, 0x66, 0x04, 0xbb, 0x84, 0x8b, 0x2c, 0xe1, 0xda, 0x55, 0x8c, 0x4c,
- 0x02, 0x79, 0x83, 0x2e, 0x8b, 0x1b, 0xa9, 0xb5, 0xb5, 0x9e, 0xcd, 0xf8,
- 0xe7, 0x79, 0xf2, 0xee, 0xd1, 0x0e, 0x1d, 0xf7, 0xd8, 0xf0, 0xf6, 0x3d,
- 0xb6, 0xf0, 0xca, 0x6f, 0x3d, 0xd4, 0x90, 0x37, 0x5f, 0xde, 0xff, 0x20,
- 0xc3, 0x93, 0xfa, 0xad, 0x5b, 0x7a, 0x8d, 0xab, 0x19, 0xc3, 0x86, 0x99,
- 0xe3, 0xaf, 0x0e, 0xfe, 0xd6, 0xfc, 0xa6, 0x23, 0xe2, 0xb1, 0xa3, 0xd6,
- 0xd3, 0x8b, 0x1b, 0x66, 0xaa, 0x52, 0xae, 0xcb, 0x1c, 0xf2, 0x6e, 0xa1,
- 0xf4, 0x4b, 0x4c, 0xf3, 0xde, 0x5a, 0x93, 0xf9, 0xb3, 0x6d, 0x95, 0x9d,
- 0x7e, 0x91, 0xaf, 0x5d, 0x36, 0xeb, 0xaa, 0x6b, 0xdd, 0x36, 0xa5, 0x8e,
- 0xd6, 0x51, 0x89, 0x57, 0x69, 0xbf, 0xaf, 0x4e, 0x4a, 0xcc, 0x53, 0x71,
- 0x94, 0x7e, 0x3a, 0x56, 0xe7, 0xeb, 0xbc, 0xca, 0x5c, 0xf2, 0x43, 0x72,
- 0xfc, 0x37, 0x35, 0x6f, 0xfb, 0x19, 0xa9, 0x3b, 0x86, 0x1c, 0x38, 0x17,
- 0xbc, 0x61, 0xd5, 0x82, 0x63, 0x87, 0x54, 0x0c, 0x27, 0x32, 0xfe, 0xfe,
- 0x1a, 0xfd, 0xf8, 0xd6, 0xd9, 0x05, 0x1d, 0x3d, 0x43, 0xe2, 0x1f, 0x0d,
- 0x96, 0x1f, 0xdd, 0xaa, 0x15, 0x09, 0x5e, 0x8b, 0x5f, 0x6c, 0x90, 0xde,
- 0x9d, 0x91, 0x02, 0xb9, 0xcc, 0xe0, 0x6a, 0x72, 0x60, 0x89, 0xb1, 0x01,
- 0xe6, 0xbb, 0x0e, 0xfa, 0xcf, 0x19, 0xe6, 0x1e, 0x94, 0x2d, 0x6c, 0x9a,
- 0xef, 0x32, 0x17, 0x1b, 0x41, 0xbd, 0x7a, 0x0a, 0xeb, 0xc8, 0x63, 0xc9,
- 0x71, 0x26, 0x9b, 0xb1, 0xc7, 0xca, 0xa5, 0x7c, 0xea, 0xc3, 0xca, 0x52,
- 0xae, 0xbf, 0x19, 0xdd, 0x63, 0x0b, 0x70, 0x80, 0xeb, 0x7a, 0x44, 0xff,
- 0x2b, 0x94, 0x0f, 0x75, 0x77, 0x96, 0x53, 0x1f, 0x9f, 0x86, 0x8c, 0x0e,
- 0x62, 0xfa, 0x96, 0x53, 0x4a, 0xfd, 0xfa, 0x98, 0xf2, 0x4d, 0xee, 0x87,
- 0xd4, 0x47, 0x3c, 0xcc, 0xd3, 0x1f, 0x61, 0x3c, 0xfb, 0x33, 0xec, 0x56,
- 0x95, 0x26, 0x5b, 0x58, 0x38, 0x22, 0xfc, 0xaa, 0x75, 0x76, 0xf0, 0xbf,
- 0x40, 0x9f, 0xdb, 0xc0, 0x6b, 0x12, 0xd7, 0xe5, 0x5e, 0x39, 0x37, 0xde,
- 0x89, 0x93, 0x69, 0xda, 0x75, 0xb4, 0x0f, 0xa7, 0xd2, 0xf2, 0x4c, 0xe1,
- 0x58, 0x01, 0xc4, 0x86, 0xec, 0x98, 0xd0, 0x7d, 0x91, 0x52, 0xea, 0xa5,
- 0x30, 0xe4, 0x8d, 0xac, 0x53, 0x02, 0xe4, 0x72, 0x69, 0x9c, 0xdb, 0xeb,
- 0x6d, 0xaf, 0x63, 0xde, 0x18, 0x9d, 0x84, 0xfa, 0xdc, 0xf2, 0x34, 0xce,
- 0x8e, 0x3e, 0x0e, 0x4f, 0xb5, 0xd7, 0xb3, 0x5a, 0x69, 0xc1, 0x8e, 0xc9,
- 0x7f, 0xaf, 0xc6, 0xe4, 0xe1, 0xb3, 0x5b, 0x60, 0x50, 0xf7, 0xbb, 0xf0,
- 0xad, 0xf9, 0xe2, 0xf3, 0xbd, 0x93, 0xc5, 0x58, 0xc4, 0x78, 0xf4, 0xb2,
- 0x15, 0x67, 0x33, 0x7e, 0x54, 0xa3, 0x7d, 0x64, 0x3e, 0x95, 0x8d, 0xe1,
- 0x7f, 0x58, 0x5f, 0x3f, 0x34, 0x23, 0xaa, 0xe8, 0x4b, 0xc6, 0xd5, 0xa0,
- 0x80, 0xf3, 0xec, 0xce, 0xc6, 0xeb, 0x32, 0xed, 0x9f, 0xcc, 0xc7, 0xad,
- 0x39, 0x56, 0xce, 0x97, 0x44, 0x61, 0xa7, 0x95, 0xe7, 0xcb, 0xba, 0x75,
- 0x7c, 0x16, 0x95, 0x5a, 0x87, 0x8a, 0x53, 0xba, 0xe0, 0x48, 0x0b, 0x7d,
- 0xd5, 0x89, 0x2d, 0x41, 0xba, 0xa3, 0x55, 0xf7, 0x9f, 0xc6, 0x9e, 0xe4,
- 0xbf, 0x9a, 0xcf, 0xd3, 0x8e, 0xd6, 0x90, 0xc3, 0x78, 0x88, 0x03, 0x1b,
- 0x43, 0x8f, 0x90, 0x87, 0x72, 0xcd, 0x09, 0x07, 0x31, 0x48, 0x41, 0xa2,
- 0x91, 0xfe, 0x1f, 0x5a, 0x82, 0x29, 0xeb, 0xfe, 0x4f, 0xe7, 0x65, 0x6a,
- 0x8b, 0x67, 0xe6, 0x67, 0x72, 0x43, 0xd1, 0xff, 0x7f, 0x44, 0x7f, 0xaf,
- 0x99, 0x9e, 0x72, 0xd1, 0x9f, 0x03, 0x6e, 0xc6, 0xad, 0x03, 0xbc, 0xe7,
- 0xc2, 0x5e, 0x07, 0x06, 0xb5, 0x16, 0x0c, 0x4e, 0xc2, 0xf3, 0x29, 0xef,
- 0xf9, 0xf9, 0x68, 0xc7, 0xfc, 0x0c, 0x57, 0x78, 0x1b, 0xdd, 0xd1, 0x17,
- 0xcc, 0x55, 0xe5, 0xb2, 0x5e, 0x39, 0xaf, 0xd3, 0xca, 0xfb, 0x73, 0x75,
- 0xbe, 0xcd, 0xe6, 0x13, 0x56, 0x9c, 0x78, 0x71, 0xbe, 0xf4, 0xd7, 0x5e,
- 0x4f, 0x98, 0xb8, 0xa2, 0xf7, 0x58, 0xb9, 0xb9, 0x60, 0x43, 0x6f, 0x42,
- 0xf6, 0x56, 0x64, 0xfb, 0x66, 0x56, 0x1f, 0x13, 0x55, 0xb7, 0xcb, 0xbd,
- 0x2a, 0x6b, 0xcb, 0xd2, 0xdf, 0xce, 0xf1, 0x7e, 0xb1, 0x65, 0xb1, 0x63,
- 0xeb, 0xbd, 0x96, 0xa4, 0xbc, 0xd3, 0xb9, 0x41, 0xfd, 0x1d, 0x9f, 0x21,
- 0x75, 0x96, 0x16, 0xce, 0x61, 0x9a, 0x9b, 0xf5, 0x7a, 0xcf, 0x29, 0xfc,
- 0x31, 0x6d, 0x5b, 0xc7, 0xae, 0x21, 0xa9, 0xc3, 0x7a, 0x14, 0xc7, 0xbe,
- 0x75, 0xb8, 0xc2, 0xf8, 0xbf, 0xc7, 0xb2, 0x43, 0xc1, 0x15, 0x91, 0x43,
- 0xb0, 0xa5, 0x8d, 0x71, 0x5c, 0x6a, 0xdd, 0x46, 0xa4, 0x26, 0xdc, 0xa9,
- 0x7c, 0x58, 0xd7, 0x89, 0x63, 0x21, 0xc3, 0x2c, 0xd5, 0xfc, 0xeb, 0x6b,
- 0x6c, 0x28, 0x98, 0x6c, 0xc8, 0xc7, 0xf1, 0x90, 0xf0, 0x47, 0xb8, 0xd2,
- 0x69, 0xaf, 0x31, 0xc7, 0xae, 0xba, 0xbe, 0x97, 0xce, 0x62, 0xa5, 0xad,
- 0x7e, 0xbe, 0xe4, 0x50, 0x49, 0x0b, 0x47, 0xbe, 0x8a, 0x07, 0xad, 0xbd,
- 0x55, 0x19, 0x43, 0xa5, 0x0e, 0x7c, 0x2c, 0x74, 0x2d, 0x2a, 0x98, 0x62,
- 0x36, 0x35, 0x87, 0xea, 0xd5, 0x5d, 0xb8, 0x87, 0xd8, 0xd5, 0x84, 0x73,
- 0xba, 0xf4, 0x3f, 0x8c, 0x6f, 0x3a, 0xac, 0xb3, 0x34, 0x47, 0x43, 0x3b,
- 0xa2, 0x2b, 0x71, 0x60, 0xc8, 0x50, 0x9c, 0x61, 0x6f, 0x24, 0x46, 0x2e,
- 0xc4, 0x1c, 0xdd, 0xaa, 0x03, 0x4a, 0x8d, 0x61, 0xb8, 0xa1, 0x13, 0xbb,
- 0xf4, 0x7c, 0xf4, 0xea, 0x91, 0x82, 0x9e, 0xe5, 0x5d, 0x38, 0xa8, 0x17,
- 0x1b, 0x8b, 0xc2, 0x06, 0x31, 0x5d, 0xdb, 0x92, 0x84, 0xbf, 0xe5, 0x32,
- 0x39, 0xc7, 0x49, 0x78, 0x3b, 0x9a, 0xec, 0xc4, 0xdc, 0x15, 0x0e, 0x57,
- 0x6c, 0xbc, 0x11, 0x89, 0xc9, 0x4a, 0xd7, 0xee, 0xf1, 0x20, 0xe2, 0x93,
- 0xdc, 0x6f, 0xe6, 0xba, 0x8e, 0xf1, 0x95, 0xe4, 0xa0, 0xa2, 0x47, 0x3b,
- 0x6d, 0xb1, 0x0e, 0xcf, 0xb5, 0x5e, 0x32, 0x9f, 0xf1, 0x0b, 0x7e, 0x2e,
- 0xc0, 0x56, 0xd5, 0x67, 0x71, 0xca, 0x88, 0xed, 0x0f, 0xf9, 0x87, 0x9d,
- 0x36, 0xf7, 0x7d, 0xd3, 0xf3, 0x75, 0xd1, 0x9b, 0x63, 0x01, 0x0a, 0x1f,
- 0x21, 0x7e, 0xca, 0xbf, 0x45, 0x77, 0xa2, 0x43, 0x13, 0x9b, 0x74, 0xa9,
- 0xf1, 0x35, 0xd0, 0x67, 0xdc, 0x78, 0x47, 0xbd, 0xb5, 0x0f, 0xcf, 0xea,
- 0x3e, 0x7d, 0x0c, 0x52, 0xdb, 0x5b, 0xc1, 0x71, 0x52, 0x83, 0x69, 0xc4,
- 0x4b, 0xd9, 0x9c, 0xc3, 0x63, 0x2b, 0x22, 0xee, 0xe6, 0xe2, 0x88, 0x5c,
- 0xf7, 0x26, 0x23, 0xb4, 0xd3, 0x6d, 0xc1, 0x19, 0x33, 0x52, 0x6e, 0x74,
- 0xca, 0xf9, 0x15, 0x77, 0x78, 0xba, 0xd3, 0x5d, 0xe7, 0xed, 0x98, 0x51,
- 0x80, 0x73, 0x31, 0xc6, 0x61, 0xeb, 0x7f, 0xb1, 0x28, 0x73, 0x3b, 0x31,
- 0x12, 0x5c, 0x88, 0xf6, 0x36, 0x79, 0x56, 0x33, 0xfa, 0xf6, 0x9b, 0x66,
- 0x71, 0xc8, 0xa7, 0xa6, 0xe1, 0xc4, 0xc3, 0x41, 0x3b, 0x2e, 0xa9, 0x26,
- 0x1c, 0xa1, 0x7f, 0x35, 0xc7, 0x19, 0x1f, 0x47, 0xe9, 0x27, 0xbb, 0x69,
- 0x63, 0xf2, 0xbe, 0x8f, 0x9f, 0x7e, 0x12, 0xa7, 0x9f, 0x9c, 0x0b, 0xdd,
- 0x97, 0x7d, 0x5f, 0x50, 0x23, 0xaf, 0x98, 0x46, 0xd3, 0x90, 0x8a, 0x4f,
- 0x57, 0x4c, 0x23, 0x34, 0x92, 0x93, 0x5d, 0xfc, 0x32, 0x27, 0xbf, 0xf4,
- 0x11, 0x45, 0x76, 0x91, 0x51, 0xd6, 0x22, 0xff, 0xce, 0x5d, 0xcb, 0xfd,
- 0x26, 0x71, 0xd6, 0x89, 0x56, 0x6b, 0x6d, 0x7f, 0x56, 0x93, 0xc1, 0x8c,
- 0xdc, 0x9a, 0x2e, 0xb9, 0x6f, 0xff, 0x7e, 0xe2, 0x8e, 0xeb, 0x2b, 0xee,
- 0xb8, 0xbe, 0x71, 0xde, 0xed, 0xdf, 0x73, 0x3e, 0x71, 0x4b, 0xaf, 0x1d,
- 0xba, 0x6f, 0xea, 0x18, 0xd7, 0x3a, 0x67, 0xc9, 0x98, 0x79, 0xa9, 0x4c,
- 0x64, 0x91, 0x3c, 0x36, 0x23, 0xeb, 0xaa, 0xf1, 0xd9, 0xb2, 0xbe, 0x95,
- 0xed, 0x19, 0x58, 0x67, 0x7c, 0xe9, 0x37, 0x1a, 0x7e, 0x78, 0xdb, 0xb9,
- 0x43, 0xb1, 0xb5, 0x80, 0xd2, 0x17, 0x93, 0xf7, 0x33, 0x0b, 0xad, 0x77,
- 0xac, 0x55, 0xbf, 0x81, 0x22, 0xbf, 0xb6, 0x65, 0x8e, 0xad, 0x0b, 0xce,
- 0xa5, 0x5a, 0xc7, 0xb7, 0x94, 0x24, 0xe2, 0xe3, 0xde, 0xc0, 0x18, 0x75,
- 0x15, 0x1b, 0xbf, 0xce, 0x5c, 0xbb, 0x0b, 0xcf, 0x85, 0x1c, 0x46, 0x61,
- 0x58, 0xce, 0x82, 0xae, 0xc2, 0xae, 0x91, 0xbf, 0xc2, 0xe6, 0xa4, 0x70,
- 0xfc, 0x05, 0xe8, 0x99, 0xb4, 0xe1, 0x04, 0xed, 0xbb, 0x8f, 0xcf, 0x21,
- 0xfe, 0xb9, 0x53, 0x90, 0xf7, 0x6b, 0x1a, 0x98, 0x37, 0xeb, 0xd6, 0x67,
- 0xc7, 0xc8, 0xcf, 0xb0, 0x39, 0x6a, 0xe2, 0x53, 0x9d, 0xb1, 0x47, 0x13,
- 0xf9, 0x1c, 0xd0, 0xca, 0x5b, 0x2d, 0x2c, 0x7d, 0x32, 0xce, 0xfd, 0xac,
- 0x16, 0x5f, 0x5d, 0x49, 0x9f, 0x55, 0xf0, 0x99, 0xf4, 0x27, 0xcb, 0x29,
- 0x33, 0xb9, 0xe1, 0xf1, 0xe8, 0x76, 0x8c, 0x5a, 0xfd, 0x67, 0xad, 0xaf,
- 0xc6, 0x1e, 0x79, 0xb1, 0x8c, 0x3c, 0x3b, 0xa1, 0xfb, 0xdb, 0x2f, 0x28,
- 0xf0, 0x94, 0x84, 0xfd, 0x8c, 0x33, 0x5f, 0xe2, 0x37, 0xba, 0xd4, 0xd8,
- 0x74, 0xd7, 0x5a, 0xda, 0xfb, 0xbe, 0x91, 0x80, 0x55, 0x33, 0xf8, 0xe1,
- 0x5d, 0x6b, 0x1a, 0x99, 0x77, 0xab, 0x33, 0xf5, 0xc7, 0x9f, 0xe1, 0x48,
- 0xda, 0x85, 0xa7, 0xe2, 0x1e, 0x65, 0xd1, 0x3e, 0x15, 0x0f, 0xc5, 0xbd,
- 0x53, 0x4d, 0x76, 0xf2, 0x8f, 0x65, 0x73, 0x38, 0x9f, 0x82, 0x1f, 0x2c,
- 0x95, 0x58, 0xf0, 0x47, 0x30, 0xaa, 0x23, 0x9c, 0x13, 0xc5, 0x79, 0xcb,
- 0xbd, 0xea, 0x11, 0x9b, 0xcf, 0xfd, 0x1b, 0xec, 0x80, 0x7d, 0xfc, 0x11,
- 0x74, 0x53, 0xfe, 0x35, 0x71, 0xe9, 0x69, 0xd5, 0x03, 0x65, 0xcd, 0xd8,
- 0x3d, 0x26, 0xbe, 0x09, 0xa3, 0x2a, 0x0c, 0x4f, 0x65, 0xd8, 0xbf, 0x10,
- 0x85, 0x5f, 0x92, 0x6b, 0x4f, 0x4b, 0xfe, 0xb9, 0xa5, 0xd4, 0x66, 0x32,
- 0x7f, 0xb9, 0x2f, 0xdb, 0xab, 0x58, 0x89, 0x1d, 0x43, 0x52, 0x87, 0x27,
- 0x6e, 0xeb, 0xcc, 0x83, 0xca, 0xb4, 0xc0, 0x46, 0x9b, 0xf4, 0x87, 0xb6,
- 0xc3, 0x17, 0xdb, 0x8e, 0x40, 0x4c, 0x7c, 0x56, 0x53, 0x3b, 0x10, 0x39,
- 0x2b, 0xb5, 0xbf, 0x45, 0x21, 0x3f, 0xe5, 0xf2, 0xf7, 0x55, 0xda, 0x75,
- 0xd7, 0x6b, 0x13, 0x2a, 0xa6, 0xd4, 0x4c, 0x1e, 0x39, 0x96, 0xd4, 0xd6,
- 0xe7, 0xdb, 0xe4, 0x0c, 0xc5, 0x55, 0xeb, 0x3d, 0xeb, 0x88, 0xed, 0x9f,
- 0x89, 0x47, 0xcd, 0x18, 0xd8, 0xff, 0x3e, 0x63, 0x90, 0x3c, 0xe3, 0x77,
- 0xcc, 0xaf, 0x9d, 0x58, 0xdd, 0xe6, 0xc1, 0x83, 0x71, 0xa9, 0x9d, 0xae,
- 0xaf, 0xca, 0x9c, 0x01, 0x91, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xd9, 0xea,
- 0x2f, 0xcc, 0x4a, 0x2b, 0x2f, 0xfd, 0xbf, 0x19, 0x9b, 0x49, 0xe4, 0x2d,
- 0x14, 0x1f, 0xef, 0x9d, 0x64, 0x02, 0x69, 0xd9, 0x5d, 0x15, 0xbf, 0xcb,
- 0x5c, 0xda, 0x81, 0xed, 0xd8, 0x56, 0x25, 0x7c, 0xe6, 0xc9, 0x89, 0xd9,
- 0xf7, 0xe7, 0xea, 0x32, 0x95, 0x59, 0x4e, 0x95, 0xb3, 0x37, 0xe9, 0x05,
- 0x46, 0x94, 0x27, 0xa2, 0x2d, 0xca, 0xda, 0xa8, 0xf4, 0x03, 0x6d, 0xd1,
- 0x22, 0x72, 0x18, 0xdf, 0x52, 0x13, 0xdf, 0x0e, 0x1d, 0x57, 0x76, 0x5a,
- 0xe7, 0x66, 0xe5, 0xac, 0x2b, 0x50, 0x3e, 0xd1, 0xac, 0xec, 0x8a, 0x7e,
- 0x62, 0x6e, 0xb4, 0x7a, 0xf0, 0x79, 0xd6, 0x79, 0x9c, 0xfc, 0x09, 0x17,
- 0xca, 0x8e, 0xc8, 0xf9, 0x41, 0x0d, 0x15, 0x13, 0x8f, 0x91, 0xb7, 0x0a,
- 0xd7, 0x31, 0x5a, 0x1c, 0xd6, 0xb9, 0xb6, 0xe6, 0x97, 0x72, 0xe7, 0xda,
- 0x1c, 0x31, 0x79, 0x1b, 0xd9, 0xfa, 0x8f, 0xb9, 0xd2, 0x51, 0xe6, 0x4a,
- 0x66, 0xd3, 0xb7, 0x43, 0xc6, 0xee, 0x0a, 0x78, 0x03, 0xe5, 0x36, 0xc3,
- 0x94, 0x7a, 0xce, 0x6b, 0x24, 0x8c, 0xeb, 0x6a, 0x0d, 0x3c, 0x5c, 0x2b,
- 0xef, 0x1f, 0xca, 0xbb, 0xc7, 0x5d, 0x38, 0x1a, 0xea, 0xc2, 0x2f, 0xf5,
- 0x2e, 0xec, 0xd1, 0xe5, 0x4c, 0x43, 0x31, 0x65, 0xd5, 0xa6, 0xa2, 0xd0,
- 0xf4, 0xb4, 0xa2, 0x9d, 0xb9, 0x0e, 0xef, 0x01, 0x9f, 0xe2, 0x35, 0x56,
- 0x29, 0x1a, 0xae, 0x8e, 0x7b, 0x67, 0x4a, 0xe9, 0x03, 0x37, 0xc6, 0x03,
- 0x98, 0x21, 0xae, 0x26, 0x27, 0xe5, 0xfc, 0xc9, 0x02, 0x0c, 0x4d, 0x7e,
- 0x4d, 0xb8, 0x81, 0x41, 0x4c, 0xb2, 0xce, 0x48, 0x3e, 0x2f, 0xbd, 0x4e,
- 0x67, 0x30, 0xcb, 0x61, 0x0c, 0x65, 0x53, 0x43, 0x09, 0x6e, 0x30, 0x3a,
- 0xfd, 0x6d, 0xba, 0x93, 0xf9, 0x1c, 0xde, 0xa8, 0x81, 0xfd, 0x3b, 0x6e,
- 0xd4, 0x25, 0xe7, 0xe0, 0x44, 0x5d, 0x39, 0xf2, 0x70, 0x6c, 0xf4, 0x45,
- 0x72, 0xfc, 0xee, 0xf6, 0x52, 0xe6, 0xa7, 0x13, 0xa3, 0x4e, 0xa4, 0x52,
- 0x52, 0x73, 0xb0, 0x7a, 0x96, 0xd3, 0x0e, 0xfa, 0x52, 0x7f, 0x02, 0x75,
- 0x35, 0x61, 0x7f, 0xb2, 0xc6, 0xae, 0x72, 0x8e, 0x4a, 0xa4, 0xd2, 0x1a,
- 0x3f, 0x01, 0x7e, 0x82, 0xfc, 0x34, 0xe2, 0xdb, 0xf4, 0xd9, 0x32, 0xe2,
- 0xed, 0xf7, 0xd3, 0x25, 0xf8, 0x24, 0xa9, 0x05, 0x74, 0xda, 0xc1, 0x28,
- 0x73, 0x04, 0xc3, 0xd2, 0x53, 0x09, 0xae, 0xd3, 0x4f, 0x5f, 0x0e, 0x95,
- 0xc0, 0x4c, 0xdd, 0x2d, 0x27, 0x94, 0xdc, 0x16, 0x6a, 0x61, 0x58, 0xf8,
- 0xe2, 0x31, 0x25, 0x95, 0x3d, 0xf3, 0xf5, 0xea, 0x38, 0xda, 0xcb, 0xc3,
- 0xae, 0xe0, 0xea, 0xb8, 0xfd, 0x13, 0x79, 0x9f, 0x75, 0x43, 0x83, 0xbc,
- 0xf3, 0xe4, 0x0a, 0x3e, 0x3d, 0xe1, 0x0a, 0xae, 0x8f, 0x1f, 0x53, 0x28,
- 0xcf, 0x81, 0x1a, 0xbb, 0x2b, 0xf8, 0xe4, 0xc4, 0xb1, 0x85, 0x99, 0xbc,
- 0x0f, 0xca, 0xd3, 0xb5, 0x06, 0x6d, 0x8c, 0x79, 0xef, 0x32, 0xe9, 0xcb,
- 0x68, 0x9d, 0x57, 0xec, 0x85, 0x46, 0x4d, 0xd8, 0xeb, 0xa9, 0xb1, 0xcb,
- 0xd9, 0x90, 0x69, 0xc4, 0x93, 0xf2, 0xae, 0x97, 0xd8, 0xfe, 0x3f, 0x99,
- 0x46, 0x99, 0x9c, 0xf5, 0xe8, 0x44, 0x5c, 0x2b, 0x67, 0xee, 0x24, 0x67,
- 0xcd, 0x8f, 0x86, 0xa2, 0xb1, 0x62, 0x79, 0x77, 0xb6, 0xe9, 0x7b, 0x21,
- 0x6f, 0xcb, 0xa0, 0x62, 0x3c, 0x5e, 0x04, 0xd9, 0xd7, 0x2e, 0xe2, 0xb7,
- 0xa6, 0x3a, 0x15, 0x6f, 0x63, 0x0f, 0x02, 0x38, 0x91, 0x16, 0x5d, 0x07,
- 0xe5, 0x8c, 0xba, 0xa5, 0xeb, 0x5b, 0x67, 0xae, 0x33, 0xb6, 0xb3, 0x2d,
- 0xea, 0xe0, 0x5f, 0xb1, 0x17, 0x1b, 0x63, 0x0a, 0xe3, 0x8a, 0x65, 0x33,
- 0xb7, 0x64, 0x5c, 0x57, 0xdb, 0x85, 0xc9, 0x50, 0xa1, 0xbc, 0x77, 0xcd,
- 0xb8, 0xee, 0x0d, 0x7c, 0xa2, 0x58, 0xf1, 0xdc, 0x28, 0x62, 0x9c, 0x7d,
- 0x61, 0xfc, 0xef, 0xcc, 0xf6, 0x6a, 0xc1, 0x2b, 0x3b, 0xc7, 0x5e, 0xc7,
- 0x6b, 0xa9, 0x5b, 0xe3, 0x5a, 0x38, 0xae, 0x90, 0xe3, 0x8a, 0xc2, 0x92,
- 0x3b, 0x7a, 0xf5, 0xb5, 0x8a, 0xe6, 0x29, 0x50, 0xa4, 0x57, 0xa6, 0xe1,
- 0xbd, 0xf4, 0xe4, 0x42, 0xc9, 0x79, 0x7b, 0x27, 0xcb, 0xb1, 0x6e, 0xaf,
- 0xd9, 0xb4, 0x68, 0xa9, 0xd9, 0x94, 0x0e, 0x45, 0xcd, 0x97, 0xab, 0x64,
- 0x4f, 0xa5, 0xff, 0x27, 0x63, 0x34, 0xd5, 0xc7, 0x5c, 0xf3, 0x6b, 0x7a,
- 0x6f, 0xf6, 0xcc, 0x2e, 0xed, 0x9a, 0xcf, 0x38, 0x9d, 0x12, 0x3b, 0xd9,
- 0xd1, 0xee, 0x62, 0x3e, 0x2a, 0xef, 0x87, 0x1e, 0xe5, 0xfe, 0x1f, 0x49,
- 0xfd, 0xcd, 0x42, 0x39, 0xc3, 0x2e, 0x67, 0x08, 0x80, 0xff, 0x0f, 0x1d,
- 0xab, 0x22, 0x97, 0x70, 0x78, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b09FwRodata[(0xf0/4) + 1] = {
- 0x5f865437, 0xe4ac62cc, 0x50103a45, 0x36621985, 0xbf14c0e8, 0x1bc27a1e,
- 0x84f4b556, 0x094ea6fe, 0x7dda01e7, 0xc04d7481, 0x80080100, 0x80080080,
- 0x80080000, 0x08004efc, 0x08004efc, 0x08004fd8, 0x08004fac, 0x08004f90,
- 0x08004ecc, 0x08004ecc, 0x08004ecc, 0x08004f04, 0x08007220, 0x0800726c,
- 0x0800722c, 0x08007150, 0x0800722c, 0x0800725c, 0x0800722c, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x0800724c, 0x0800723c, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150,
- 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x08007150, 0x0800723c,
- 0x080077f4, 0x080076bc, 0x080077bc, 0x08007718, 0x080076e8, 0x080075a4,
- 0x00000000 };
-
-static struct fw_info bnx2_rxp_fw_09 = {
- /* Firmware version: 4.4.23 */
- .ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
-
- .start_addr = 0x080031d0,
-
- .text_addr = 0x08000000,
- .text_len = 0x786c,
- .text_index = 0x0,
- .gz_text = bnx2_RXP_b09FwText,
- .gz_text_len = sizeof(bnx2_RXP_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_RXP_b09FwData,
-
- .sbss_addr = 0x08007980,
- .sbss_len = 0x58,
- .sbss_index = 0x0,
-
- .bss_addr = 0x080079d8,
- .bss_len = 0x1c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x0800786c,
- .rodata_len = 0xf0,
- .rodata_index = 0x0,
- .rodata = bnx2_RXP_b09FwRodata,
-};
-
-static u8 bnx2_xi_rv2p_proc1[] = {
- /* Date: 06/17/2008 16:52 */
- 0xbd, 0x56, 0xcf, 0x6b, 0x1c, 0x75, 0x14, 0x7f, 0x3b, 0xbb, 0x33, 0x3b,
- 0x99, 0x9d, 0xdd, 0x99, 0xda, 0x34, 0x4c, 0xb7, 0x2b, 0xd9, 0x86, 0x5e,
- 0x36, 0x99, 0x62, 0xa2, 0x11, 0x0a, 0x46, 0x5b, 0x72, 0x09, 0xd8, 0x9e,
- 0x02, 0x95, 0x22, 0x82, 0x71, 0xa9, 0x3d, 0xd8, 0x96, 0xe2, 0x5f, 0xe0,
- 0x90, 0x9a, 0x08, 0x45, 0x0f, 0x0b, 0x36, 0x90, 0x20, 0x1a, 0x7b, 0x50,
- 0x09, 0x0a, 0x3b, 0x07, 0x41, 0x44, 0x2d, 0xa8, 0x88, 0x60, 0x3d, 0x08,
- 0x85, 0xda, 0x8b, 0x51, 0x8b, 0x8a, 0x07, 0x0f, 0x01, 0x8f, 0x9a, 0xf1,
- 0xfb, 0x7e, 0x7c, 0x37, 0x33, 0x93, 0xdd, 0x24, 0x27, 0x03, 0xed, 0x87,
- 0xf7, 0x9d, 0xf7, 0x7d, 0xdf, 0xf7, 0xde, 0xf7, 0xf3, 0x3e, 0xdf, 0xf5,
- 0x01, 0xc0, 0x80, 0x28, 0x1e, 0x55, 0x08, 0x87, 0x8c, 0xa2, 0xad, 0xa0,
- 0x00, 0xf0, 0x21, 0xf0, 0x9f, 0xe9, 0x92, 0x1d, 0x3d, 0x22, 0xf6, 0x04,
- 0x43, 0x34, 0xe1, 0xab, 0xff, 0xaf, 0xc2, 0xe9, 0x26, 0x62, 0x11, 0x4e,
- 0x1f, 0x47, 0x7c, 0x12, 0x6e, 0x37, 0x03, 0x85, 0xff, 0x26, 0x10, 0xa1,
- 0x3d, 0xdc, 0xfd, 0x24, 0xae, 0x50, 0xfc, 0x4d, 0xd9, 0xff, 0x63, 0x91,
- 0xf1, 0x54, 0x68, 0x73, 0x1c, 0x41, 0x38, 0xe9, 0x13, 0xdc, 0xed, 0xa0,
- 0x7d, 0xfe, 0x3c, 0x58, 0x18, 0xe7, 0x6d, 0xe5, 0x80, 0x76, 0xa3, 0x10,
- 0x9d, 0x94, 0xbc, 0x0c, 0xf6, 0xfb, 0xa9, 0xe3, 0xe1, 0x3a, 0xfc, 0x3c,
- 0x8b, 0xf6, 0x51, 0xe7, 0xd5, 0x0e, 0x62, 0x00, 0x97, 0x6c, 0x97, 0xeb,
- 0x19, 0xe5, 0xb0, 0x9b, 0xe3, 0xb8, 0x4f, 0xf9, 0x8e, 0x4b, 0x5c, 0x13,
- 0xe3, 0xfe, 0x99, 0x70, 0x5c, 0x8c, 0x97, 0x8e, 0xd3, 0x50, 0x71, 0x70,
- 0xdd, 0x92, 0xbc, 0xac, 0x5c, 0x5e, 0x96, 0xca, 0x43, 0xfa, 0x00, 0x3a,
- 0x0f, 0xc4, 0x23, 0xea, 0x5c, 0x8c, 0xbb, 0x25, 0x75, 0x03, 0x3c, 0xdf,
- 0x94, 0xf8, 0x31, 0xa2, 0x5b, 0xe0, 0x78, 0xea, 0x9f, 0xd4, 0xb1, 0x3b,
- 0x8e, 0xee, 0x53, 0x36, 0xff, 0x72, 0xa8, 0xbf, 0xeb, 0xfb, 0xc0, 0x73,
- 0x7e, 0x50, 0xe7, 0xa4, 0xfd, 0x61, 0x1f, 0xff, 0xef, 0x94, 0x7f, 0x36,
- 0x2e, 0xaf, 0x7f, 0xbb, 0xb3, 0xde, 0xea, 0xd7, 0x37, 0x33, 0xd7, 0xb7,
- 0x2f, 0xa5, 0x6f, 0x73, 0x70, 0xc2, 0x08, 0xc8, 0xaf, 0x04, 0x88, 0xc7,
- 0x54, 0x02, 0x88, 0x0f, 0x0b, 0x5e, 0x13, 0xbc, 0x25, 0xf8, 0xae, 0xe0,
- 0x11, 0xc1, 0x61, 0xc1, 0xc3, 0x82, 0x0f, 0x09, 0x6e, 0x09, 0xfa, 0x82,
- 0x9e, 0x60, 0x4d, 0xf0, 0x2f, 0x41, 0x57, 0xb0, 0x92, 0x8b, 0x57, 0x17,
- 0xb4, 0x05, 0x3f, 0x17, 0x7c, 0x22, 0xb7, 0xff, 0x68, 0x81, 0xf1, 0x81,
- 0xd8, 0x4f, 0x89, 0x7d, 0x41, 0x6c, 0x6c, 0xa8, 0xf0, 0x3e, 0xd3, 0xaf,
- 0x5b, 0xbd, 0xfb, 0xbd, 0xdb, 0x91, 0xef, 0x2d, 0xed, 0x67, 0x53, 0xff,
- 0x60, 0x3c, 0xed, 0xff, 0xd6, 0x1e, 0xfe, 0xec, 0x36, 0xdb, 0xea, 0xb7,
- 0xef, 0x66, 0xc2, 0x79, 0xbc, 0x29, 0xfb, 0x83, 0xee, 0x67, 0x03, 0xe6,
- 0x68, 0x26, 0xcc, 0xf3, 0xab, 0xdf, 0x1c, 0x3d, 0x2e, 0x73, 0x34, 0xbd,
- 0x8b, 0xbf, 0xcc, 0xd3, 0x33, 0xb2, 0x7f, 0x46, 0xf8, 0xd9, 0x18, 0xe0,
- 0x17, 0xa5, 0xe6, 0x95, 0xce, 0x1b, 0x30, 0x0f, 0x1f, 0x15, 0xda, 0x61,
- 0xc0, 0xfc, 0x89, 0xf6, 0xca, 0x0f, 0xf7, 0x0b, 0x7f, 0x5b, 0x9a, 0xc7,
- 0x59, 0xfe, 0x32, 0x0f, 0xad, 0x1c, 0x0f, 0x5f, 0xde, 0xe7, 0x1e, 0x2a,
- 0xb9, 0x7e, 0x5e, 0x56, 0xfe, 0x6c, 0x1a, 0x06, 0xe3, 0x1a, 0x63, 0xe8,
- 0x5a, 0x25, 0xc4, 0x69, 0xf7, 0x1b, 0x8e, 0x37, 0x4a, 0x75, 0xb8, 0xc1,
- 0x0a, 0xcd, 0x6d, 0x09, 0x56, 0xac, 0x21, 0x85, 0xff, 0x24, 0x6f, 0xb0,
- 0x5f, 0xdd, 0xfc, 0x9e, 0x30, 0x58, 0xbb, 0xc3, 0xfe, 0xf7, 0x9a, 0x9c,
- 0xf7, 0x33, 0x13, 0x90, 0xfb, 0xd3, 0xdf, 0x65, 0xde, 0x3d, 0xb4, 0xff,
- 0x2e, 0x44, 0xb1, 0x3e, 0x47, 0xf6, 0x5d, 0xd6, 0x73, 0xc4, 0x7f, 0x8b,
- 0x96, 0x4f, 0xf5, 0xde, 0x88, 0xc9, 0x1c, 0x76, 0x97, 0x7d, 0xfa, 0xfa,
- 0x7a, 0xac, 0xeb, 0x11, 0x5d, 0x19, 0xd7, 0xf5, 0xf3, 0xfe, 0x2a, 0x9d,
- 0x77, 0xb8, 0xbb, 0x9e, 0xe3, 0x49, 0xf3, 0x40, 0x3a, 0xbb, 0x95, 0xec,
- 0xe8, 0x6c, 0xba, 0x0f, 0x5a, 0x67, 0x6d, 0x58, 0x98, 0xf3, 0xe8, 0xdc,
- 0x9a, 0xc5, 0x61, 0x2e, 0x78, 0x8c, 0x17, 0x1d, 0xc6, 0xdf, 0x1c, 0xec,
- 0x53, 0x92, 0x5c, 0xaa, 0xb0, 0xfd, 0x42, 0x55, 0xcf, 0xb7, 0xde, 0xaf,
- 0xf3, 0xda, 0x2b, 0x1f, 0x3c, 0x5f, 0x9f, 0xa3, 0xf3, 0xd0, 0xe7, 0x65,
- 0x79, 0x31, 0xf8, 0x5c, 0xc6, 0xb6, 0x91, 0xed, 0xc3, 0xda, 0x24, 0x63,
- 0x69, 0x0a, 0xf3, 0xba, 0x9d, 0xf4, 0xe6, 0xbb, 0xe5, 0x93, 0xdf, 0x18,
- 0xb0, 0x3d, 0x2f, 0x3c, 0x9c, 0xa7, 0xb9, 0x54, 0xba, 0x63, 0x20, 0xd6,
- 0x21, 0xa2, 0x77, 0xc7, 0x70, 0xbe, 0x26, 0x5e, 0x14, 0x65, 0x5d, 0xdd,
- 0xc3, 0x58, 0x76, 0x9e, 0x37, 0x99, 0x77, 0x76, 0x96, 0xaf, 0xc7, 0x84,
- 0xaf, 0x4e, 0x77, 0xbd, 0xb3, 0xdf, 0x3c, 0x48, 0xc1, 0xbd, 0xfe, 0x6b,
- 0x3d, 0xd4, 0xef, 0xb2, 0xd6, 0x3d, 0xfa, 0xdc, 0x8d, 0x8a, 0x99, 0x3a,
- 0xcf, 0x40, 0xd8, 0xef, 0x7e, 0x3f, 0x16, 0x3d, 0x99, 0x16, 0x7d, 0x53,
- 0x97, 0x18, 0x65, 0xf6, 0xd5, 0x80, 0xf2, 0x29, 0xe7, 0xe6, 0xac, 0xd4,
- 0x9b, 0x9b, 0x45, 0x6b, 0x80, 0xde, 0x99, 0xfc, 0x7e, 0x2e, 0xcc, 0xe1,
- 0xb9, 0x76, 0xe3, 0x06, 0xcd, 0x7f, 0x19, 0xfe, 0x70, 0xf9, 0x5e, 0xda,
- 0x26, 0xda, 0xe6, 0xf0, 0x95, 0x4f, 0x33, 0xfd, 0x01, 0x38, 0xae, 0xdf,
- 0x97, 0xf4, 0x1c, 0x07, 0xd0, 0x9e, 0x3a, 0xe8, 0x7b, 0x99, 0xe6, 0x7d,
- 0x6d, 0x17, 0xef, 0xb5, 0x3e, 0x36, 0xc3, 0xf4, 0x9c, 0xe0, 0x3b, 0xc1,
- 0xf7, 0xcd, 0xfa, 0x54, 0xc9, 0xf7, 0x41, 0xbd, 0x9f, 0xba, 0xbe, 0x7e,
- 0xef, 0xe8, 0xaf, 0xdb, 0x07, 0xd3, 0xb3, 0x74, 0x9f, 0xfa, 0xe9, 0x99,
- 0x93, 0xd3, 0xa7, 0x7b, 0xdb, 0x3d, 0x7d, 0x32, 0xfb, 0xd5, 0xff, 0x7f,
- 0xe8, 0x36, 0xf7, 0xd3, 0x81, 0x74, 0x3d, 0x1b, 0x1b, 0xcc, 0x9f, 0xab,
- 0xa9, 0x79, 0x49, 0xdf, 0xff, 0x90, 0xf0, 0x45, 0xf9, 0x51, 0x1d, 0x5f,
- 0x6c, 0xef, 0xe8, 0x72, 0x9a, 0x7f, 0x2f, 0x0a, 0xff, 0x8d, 0x99, 0x75,
- 0xe6, 0x47, 0xfb, 0xf7, 0xdc, 0x7d, 0x4d, 0x85, 0xc8, 0x97, 0x57, 0x20,
- 0x96, 0x3c, 0xef, 0x67, 0xf2, 0xad, 0x8a, 0x2e, 0x95, 0xe1, 0x83, 0x58,
- 0xd7, 0xc5, 0x9f, 0x9b, 0x21, 0xe3, 0xfb, 0xe4, 0xef, 0xef, 0xf3, 0x2e,
- 0xf9, 0xf0, 0x5e, 0x4f, 0x7f, 0x3d, 0x8a, 0x37, 0x29, 0x3a, 0xb6, 0x20,
- 0x7a, 0xf2, 0x8b, 0xc3, 0x7a, 0xd5, 0x3e, 0x4b, 0xfc, 0x85, 0x11, 0xd1,
- 0x95, 0x76, 0x95, 0xed, 0x7a, 0x95, 0x7f, 0xef, 0x4e, 0x96, 0x5d, 0xf2,
- 0xab, 0x57, 0x19, 0x47, 0x2a, 0xb8, 0x2f, 0x80, 0x07, 0xe7, 0xc8, 0x3d,
- 0x5c, 0x75, 0xf9, 0x5d, 0x59, 0xbd, 0x23, 0x7a, 0xe7, 0xe9, 0xfe, 0x49,
- 0xbd, 0x8f, 0xe1, 0xfa, 0x88, 0xd2, 0x0f, 0xb6, 0x99, 0x17, 0x6e, 0x6f,
- 0x1e, 0xde, 0x91, 0xec, 0x9b, 0x5e, 0xba, 0xdf, 0x7a, 0x2e, 0x3b, 0xb9,
- 0x3e, 0xeb, 0x7b, 0x3a, 0x95, 0x68, 0xbd, 0x1d, 0x9b, 0xc3, 0x7c, 0x3d,
- 0xa8, 0x95, 0x99, 0x47, 0x8c, 0x2a, 0x8e, 0x51, 0xc6, 0x6d, 0x8d, 0x25,
- 0xd1, 0xaf, 0xa5, 0x45, 0x0a, 0x73, 0x6e, 0x49, 0xaf, 0xcf, 0xd2, 0xe0,
- 0xcc, 0x6f, 0x7c, 0x45, 0xeb, 0xb5, 0xb8, 0xc8, 0xeb, 0xe5, 0xb3, 0xba,
- 0x5f, 0x1e, 0xd5, 0xbf, 0xc2, 0xfd, 0x7a, 0xee, 0x26, 0xe3, 0xb3, 0xf0,
- 0x34, 0xa1, 0xb3, 0x22, 0x73, 0xbf, 0xea, 0xda, 0x84, 0x40, 0xfd, 0x32,
- 0x1e, 0xe5, 0xf7, 0xd4, 0x94, 0x77, 0x70, 0x28, 0x75, 0x8f, 0xf9, 0xf7,
- 0xea, 0xa0, 0xf7, 0x99, 0xd6, 0x6f, 0xfd, 0x9e, 0x16, 0x72, 0xbf, 0x5f,
- 0xab, 0x39, 0x7e, 0xbe, 0x34, 0x80, 0x9f, 0x87, 0x06, 0xf0, 0x3b, 0xaf,
- 0x87, 0x6d, 0x99, 0xff, 0x12, 0x98, 0x45, 0x7a, 0x08, 0xdd, 0xd2, 0x75,
- 0xba, 0x5f, 0x63, 0x89, 0x7f, 0x4f, 0xb8, 0xe6, 0x72, 0x81, 0xfa, 0xe6,
- 0x2e, 0xb3, 0x5f, 0x89, 0xd7, 0x03, 0x8d, 0xaf, 0x5d, 0xe7, 0x39, 0x33,
- 0xe0, 0x3f, 0xdd, 0xd1, 0x99, 0x07, 0x78, 0x0d, 0x00, 0x00, 0x00 };
-
-static u8 bnx2_xi_rv2p_proc2[] = {
- /* Date: 06/17/2008 16:52 */
-#define XI_RV2P_PROC2_MAX_BD_PAGE_LOC 5
-#define XI_RV2P_PROC2_BD_PAGE_SIZE_MSK 0xffff
-#define XI_RV2P_PROC2_BD_PAGE_SIZE ((BCM_PAGE_SIZE / 16) - 1)
- 0xad, 0x58, 0x4d, 0x4c, 0x54, 0x57, 0x14, 0xbe, 0xf3, 0xc3, 0xcc, 0x30,
- 0xbc, 0x99, 0x41, 0x98, 0x0e, 0x7f, 0xa6, 0x22, 0x28, 0x82, 0x1d, 0x14,
- 0x06, 0xd4, 0xb6, 0x36, 0xa9, 0xc1, 0x06, 0xb5, 0xb5, 0x11, 0x69, 0x63,
- 0xba, 0x68, 0x8a, 0x60, 0x45, 0x06, 0xc1, 0x10, 0x31, 0x2e, 0xdc, 0x74,
- 0x02, 0x16, 0xbb, 0x98, 0x85, 0x98, 0xe2, 0x60, 0xd3, 0x18, 0x52, 0x37,
- 0xa6, 0x3b, 0x92, 0xb6, 0x62, 0xbb, 0x30, 0x31, 0x2d, 0xb1, 0xb6, 0x89,
- 0x36, 0xb1, 0x7f, 0x9b, 0xa6, 0xa6, 0x5a, 0x8a, 0x4a, 0x2d, 0xda, 0xb2,
- 0xaa, 0xd0, 0x77, 0xcf, 0x77, 0xee, 0x9b, 0x37, 0x33, 0x6f, 0x44, 0x53,
- 0xd9, 0x1c, 0xee, 0x7d, 0xe7, 0x9e, 0x7b, 0xce, 0x77, 0x7e, 0xef, 0xe4,
- 0x0b, 0x21, 0x9c, 0x22, 0x36, 0xbe, 0x4c, 0xa7, 0x62, 0x89, 0xdd, 0xe1,
- 0xd1, 0xc9, 0x82, 0x10, 0x39, 0xc5, 0x72, 0x2d, 0xec, 0x82, 0xff, 0x56,
- 0xe7, 0x13, 0xb9, 0x36, 0x2e, 0xbf, 0xbb, 0xc5, 0xeb, 0x76, 0x7c, 0x77,
- 0x0a, 0x49, 0x03, 0x42, 0xc4, 0x24, 0xcd, 0x67, 0xba, 0x9d, 0xe9, 0x4a,
- 0x1b, 0xe8, 0x46, 0xa6, 0x51, 0xa6, 0x2b, 0x98, 0xd6, 0xdb, 0x41, 0x57,
- 0x31, 0xad, 0xe6, 0x7d, 0x8d, 0xcf, 0xd7, 0xf2, 0xfe, 0x7b, 0x4c, 0x8f,
- 0xf2, 0xbe, 0xa6, 0xf3, 0x29, 0xbd, 0xe4, 0x7a, 0x66, 0x41, 0xc4, 0xf4,
- 0x33, 0x42, 0xdf, 0xae, 0x51, 0xfb, 0x1a, 0x91, 0x58, 0x0d, 0xf4, 0x7e,
- 0xad, 0x5c, 0xf2, 0xfd, 0x61, 0xc1, 0x27, 0xf7, 0x6f, 0x2e, 0x28, 0x79,
- 0x03, 0x0e, 0xb9, 0xfe, 0x55, 0x5f, 0xdb, 0xe4, 0x32, 0x18, 0x82, 0x98,
- 0x60, 0x71, 0x5c, 0xca, 0x71, 0x88, 0xd1, 0x61, 0x0f, 0xa1, 0x72, 0x52,
- 0xc3, 0x3a, 0x46, 0x78, 0xd8, 0xf4, 0x35, 0xcb, 0x63, 0x5a, 0xe2, 0xc3,
- 0xbd, 0xbb, 0xca, 0x71, 0xdf, 0x8f, 0xcf, 0x80, 0x2f, 0x16, 0x50, 0x80,
- 0xe2, 0xfb, 0x32, 0xc1, 0xdf, 0xf7, 0xcb, 0xf5, 0xac, 0xad, 0xd0, 0x06,
- 0x5c, 0xdd, 0xcc, 0x65, 0xcf, 0x91, 0xfb, 0xcb, 0x1b, 0x4f, 0x0e, 0x83,
- 0xbf, 0xad, 0x1c, 0xfb, 0x4f, 0x87, 0xa5, 0x3c, 0x97, 0x88, 0x31, 0x15,
- 0xb5, 0xa4, 0x97, 0x2d, 0x56, 0x9b, 0x2a, 0xff, 0x97, 0x61, 0xac, 0xda,
- 0x7d, 0x90, 0xeb, 0x4d, 0x91, 0x1b, 0xca, 0x90, 0xfb, 0x53, 0xae, 0x59,
- 0xbe, 0xdf, 0x06, 0xf9, 0xde, 0x45, 0xe5, 0x77, 0xf8, 0x40, 0x0b, 0xc3,
- 0x56, 0xf7, 0xe4, 0x2e, 0xa2, 0x7f, 0xf7, 0xa2, 0xf2, 0x8f, 0x18, 0xfa,
- 0x2b, 0xff, 0xa9, 0xef, 0xe9, 0x38, 0xd2, 0xf2, 0xe3, 0xd8, 0x5a, 0x16,
- 0xb3, 0x5a, 0xd9, 0xcf, 0x7a, 0x3a, 0x40, 0x37, 0x85, 0x89, 0xc4, 0xf7,
- 0x70, 0x80, 0x37, 0x57, 0xc9, 0xfb, 0x0b, 0x84, 0xd3, 0x2e, 0xe5, 0xd5,
- 0x79, 0x5c, 0xe7, 0xb1, 0xff, 0x06, 0xfb, 0xeb, 0x6d, 0x36, 0xe8, 0xa6,
- 0x57, 0x02, 0xb4, 0xb0, 0xd0, 0x99, 0xc7, 0xf2, 0xd9, 0xdf, 0xb1, 0x3c,
- 0x9c, 0x9f, 0xd4, 0xa4, 0x9e, 0x5f, 0xeb, 0xf1, 0x63, 0xe5, 0x7f, 0xc7,
- 0x43, 0xfc, 0x8f, 0xf3, 0x4b, 0x56, 0xe1, 0xeb, 0xf1, 0x4e, 0xac, 0xcb,
- 0xce, 0xe4, 0x13, 0x4e, 0xa3, 0xe3, 0x56, 0xf1, 0x92, 0x2e, 0x5f, 0xcf,
- 0xe3, 0x00, 0xee, 0x11, 0x15, 0x1e, 0x52, 0x0e, 0xf8, 0xea, 0x3c, 0xb5,
- 0x96, 0x38, 0x89, 0x93, 0x2b, 0xe5, 0xbe, 0x5d, 0xb4, 0x3a, 0x34, 0xba,
- 0xa7, 0x35, 0xaa, 0xf2, 0x06, 0xdf, 0x3b, 0x5d, 0x44, 0x8a, 0xdb, 0x87,
- 0xa4, 0xdd, 0x01, 0xb1, 0xdb, 0x1e, 0x20, 0x7e, 0xe0, 0xe4, 0xf0, 0x68,
- 0x9f, 0x81, 0xff, 0xc2, 0x32, 0x8d, 0x6c, 0xea, 0x6c, 0xc0, 0xb9, 0x60,
- 0x04, 0x74, 0x24, 0x92, 0x23, 0x49, 0xb8, 0xb3, 0x9f, 0x96, 0x6b, 0x7e,
- 0xab, 0xf7, 0x10, 0x5f, 0xac, 0x56, 0xe5, 0xa5, 0xf2, 0xa3, 0xc4, 0xed,
- 0x90, 0x91, 0x87, 0xa2, 0x12, 0x38, 0xff, 0xbe, 0x52, 0xf2, 0xeb, 0x60,
- 0x57, 0xe0, 0x9e, 0xa4, 0x7e, 0xe6, 0xbc, 0xee, 0x35, 0xe5, 0xf5, 0xe3,
- 0xc5, 0xc5, 0x26, 0xc2, 0x67, 0x13, 0xe3, 0x54, 0xce, 0x71, 0xb8, 0xd4,
- 0x22, 0x0e, 0x03, 0xf4, 0xff, 0xad, 0xa6, 0x7c, 0xc2, 0x79, 0x07, 0xf6,
- 0x4f, 0x34, 0x9f, 0x83, 0x9f, 0xb6, 0x11, 0x1e, 0xc2, 0x7b, 0xf4, 0x53,
- 0x9c, 0x6a, 0xa7, 0xfc, 0xef, 0x6d, 0xec, 0xfc, 0x1c, 0xeb, 0x0e, 0x87,
- 0x5c, 0xef, 0xd7, 0xf6, 0x4c, 0x80, 0x3f, 0x67, 0x10, 0xb8, 0xef, 0xe0,
- 0x5b, 0xb6, 0x39, 0xa8, 0xde, 0xc4, 0x5d, 0x83, 0xb4, 0xd4, 0x26, 0xe9,
- 0x7b, 0xbe, 0x38, 0x36, 0x8e, 0xef, 0x07, 0xf2, 0xa4, 0x9d, 0xaf, 0x1a,
- 0x75, 0x29, 0xea, 0xc2, 0xf9, 0xf8, 0x30, 0xea, 0xca, 0xf4, 0x27, 0x72,
- 0xdd, 0x16, 0x9e, 0x06, 0x7f, 0x38, 0x3a, 0xc4, 0x82, 0xed, 0xc0, 0xf1,
- 0x96, 0x1d, 0xfc, 0x1c, 0xae, 0x5e, 0x27, 0xf9, 0xd1, 0x26, 0xb4, 0x66,
- 0xd0, 0x77, 0xe9, 0xfb, 0xbf, 0xb6, 0x38, 0xe1, 0xb6, 0xcb, 0xef, 0x3c,
- 0xa7, 0xf0, 0x61, 0x1a, 0x50, 0x76, 0x81, 0x3e, 0x6a, 0x3e, 0x0c, 0x69,
- 0xd9, 0xf2, 0x80, 0xfd, 0x59, 0xb3, 0x58, 0x1e, 0x80, 0x36, 0x57, 0x81,
- 0xba, 0x2a, 0xa9, 0x9e, 0x3c, 0x46, 0x3e, 0xb0, 0x5e, 0x19, 0xf9, 0x86,
- 0xdd, 0x64, 0x9c, 0x12, 0xd1, 0xe3, 0x33, 0x25, 0x5e, 0x39, 0x3f, 0x96,
- 0xeb, 0x7e, 0x50, 0x71, 0x27, 0x05, 0xba, 0xc5, 0x7e, 0x96, 0x1b, 0x65,
- 0x3c, 0x7a, 0x18, 0x8f, 0x19, 0xa6, 0x07, 0xf2, 0x14, 0x0e, 0xa0, 0xc7,
- 0x34, 0xdc, 0xdb, 0x1a, 0x95, 0x7e, 0x0c, 0x5a, 0xf4, 0x17, 0xd5, 0x47,
- 0xe0, 0xa7, 0x51, 0xf6, 0xeb, 0x29, 0xa3, 0x9f, 0x28, 0x7c, 0xb3, 0xf5,
- 0x95, 0xd4, 0x7c, 0x4a, 0xb3, 0x33, 0xfe, 0x55, 0x05, 0x8e, 0x17, 0x54,
- 0x82, 0x1a, 0xf8, 0x56, 0x51, 0x1e, 0xfb, 0x8b, 0x26, 0x94, 0x7d, 0x52,
- 0xbf, 0x3b, 0x2a, 0x0f, 0xfd, 0x89, 0x01, 0xa2, 0xde, 0x82, 0x33, 0xf2,
- 0x9e, 0x52, 0x8b, 0xba, 0x92, 0x9a, 0xcf, 0xe9, 0xf8, 0x1e, 0xf0, 0x51,
- 0xc1, 0x6d, 0xbc, 0x32, 0x95, 0x9a, 0xb7, 0xc8, 0x4f, 0xb7, 0x11, 0xdf,
- 0xc1, 0xf5, 0xec, 0x07, 0xa6, 0xa1, 0x0d, 0x52, 0x6e, 0x0b, 0xdf, 0x53,
- 0xc7, 0xf7, 0x68, 0xa6, 0xba, 0x21, 0xf5, 0xfc, 0x73, 0x5e, 0xd5, 0x0b,
- 0x15, 0x1f, 0xc9, 0xba, 0xa1, 0xfc, 0x40, 0xf7, 0x87, 0xaf, 0x4c, 0xc9,
- 0xf3, 0x65, 0x8b, 0xd4, 0x91, 0x1b, 0x86, 0xbc, 0xef, 0x8d, 0x3a, 0x21,
- 0xbf, 0xe7, 0x89, 0x17, 0x79, 0x99, 0x5a, 0x0f, 0xff, 0xd2, 0xeb, 0x21,
- 0xd9, 0xe1, 0xd1, 0xce, 0x71, 0xfd, 0xeb, 0x97, 0xf7, 0x14, 0xb3, 0xde,
- 0xc5, 0xaa, 0xaf, 0xe9, 0x7a, 0x73, 0x9d, 0x6c, 0x33, 0xd7, 0xbb, 0x1f,
- 0xe6, 0x93, 0x75, 0x4b, 0xae, 0xaf, 0xcd, 0x67, 0xce, 0x27, 0x96, 0xb8,
- 0xc6, 0x44, 0x00, 0x73, 0x58, 0x2c, 0x20, 0xcf, 0xe5, 0xd8, 0x32, 0xeb,
- 0x5f, 0xba, 0x1d, 0xc0, 0xa5, 0xdd, 0xee, 0x23, 0xbe, 0xeb, 0x7d, 0xf2,
- 0xdc, 0xb4, 0x50, 0xf6, 0xa2, 0x0e, 0x96, 0x73, 0xbf, 0x5f, 0xca, 0x7a,
- 0xeb, 0xf2, 0x6a, 0x29, 0x1f, 0x3c, 0xd7, 0xfb, 0xcc, 0x7a, 0x5f, 0x98,
- 0xcf, 0x7e, 0x9f, 0x75, 0x1c, 0xf4, 0x71, 0x9f, 0xe5, 0x39, 0xc1, 0xb3,
- 0xe7, 0x0b, 0xa5, 0x17, 0xdf, 0x1f, 0x50, 0x7a, 0x68, 0xe4, 0xa7, 0xa9,
- 0x7e, 0x29, 0xa7, 0x50, 0x70, 0xd8, 0x88, 0xde, 0x6a, 0xd4, 0xdf, 0x99,
- 0xbd, 0xb0, 0xa3, 0xb7, 0x4a, 0xea, 0xa1, 0x7b, 0x25, 0x86, 0x3c, 0x17,
- 0xdc, 0x8f, 0xbe, 0x1c, 0xb6, 0xf2, 0xeb, 0xb7, 0xcc, 0x17, 0x64, 0xfb,
- 0xf2, 0xd9, 0xbe, 0xb0, 0x48, 0xaf, 0xf3, 0x6d, 0xe5, 0xd4, 0x0f, 0x98,
- 0xef, 0x05, 0xd5, 0x0f, 0x74, 0x3e, 0xc2, 0x99, 0xe5, 0x58, 0xe1, 0x64,
- 0x25, 0x67, 0x82, 0xe3, 0xa0, 0x8b, 0xf9, 0x9c, 0x59, 0xe7, 0x9b, 0xb9,
- 0x55, 0xd4, 0x57, 0x4e, 0x1f, 0xa1, 0xfe, 0xe0, 0x33, 0xe2, 0x34, 0xd5,
- 0x8e, 0xe3, 0x4f, 0x10, 0x77, 0x9a, 0xff, 0xc4, 0x3e, 0x7f, 0x36, 0x7c,
- 0x9d, 0x72, 0x7b, 0x6c, 0x76, 0x42, 0xf9, 0x47, 0x23, 0x7b, 0xa7, 0xfa,
- 0xd5, 0x9c, 0x6f, 0xc6, 0xdd, 0x6e, 0xc2, 0x1d, 0xfc, 0x98, 0xef, 0xfe,
- 0x0f, 0xde, 0x56, 0xf3, 0x41, 0x9f, 0x91, 0x9f, 0x03, 0x2e, 0xab, 0xfa,
- 0xbf, 0xd6, 0x88, 0x97, 0x83, 0x3c, 0xe7, 0xcd, 0x69, 0xf4, 0x4f, 0x64,
- 0x26, 0x4e, 0x4b, 0xad, 0xe4, 0xac, 0xe4, 0x5b, 0x1d, 0x39, 0xc8, 0x76,
- 0x5d, 0x76, 0xc0, 0xee, 0xae, 0xbd, 0x58, 0x5f, 0xe1, 0x7a, 0x7d, 0x8f,
- 0xeb, 0xe3, 0x4e, 0x0f, 0xe8, 0x4c, 0x35, 0xe1, 0x11, 0x39, 0x78, 0x5e,
- 0xc9, 0x27, 0xb9, 0xda, 0x1c, 0xe3, 0xf9, 0x92, 0x83, 0xed, 0xac, 0x20,
- 0x3f, 0x46, 0xee, 0x52, 0x3d, 0x70, 0x8a, 0xa6, 0xe5, 0x92, 0x96, 0xe8,
- 0xb8, 0xb1, 0x3e, 0x1b, 0x41, 0x5b, 0xd5, 0x80, 0x5f, 0x93, 0xee, 0x67,
- 0x6c, 0xbb, 0x2a, 0xf8, 0x7c, 0x3b, 0xd6, 0x6e, 0xae, 0x67, 0x09, 0xd6,
- 0xeb, 0xfd, 0x6a, 0x50, 0x7f, 0x0d, 0xe6, 0x84, 0x29, 0xea, 0x0b, 0x81,
- 0x48, 0xff, 0x04, 0xec, 0xe9, 0xd9, 0x0c, 0x7b, 0xef, 0x33, 0x0e, 0x4c,
- 0xfd, 0xa7, 0x06, 0xa9, 0xef, 0xf8, 0x87, 0x30, 0x67, 0xf8, 0x5d, 0x83,
- 0xb0, 0xa3, 0x67, 0x0e, 0xeb, 0xfb, 0xcf, 0x81, 0xfe, 0xf3, 0x3c, 0xce,
- 0x1d, 0x3a, 0xc2, 0xf8, 0x6c, 0xb6, 0x3e, 0xd7, 0xf5, 0x37, 0xf8, 0x7a,
- 0xab, 0xe5, 0xfd, 0x6f, 0x8d, 0xf1, 0xfc, 0x21, 0xa2, 0x34, 0xef, 0xbc,
- 0xa9, 0xcd, 0xf1, 0xba, 0x9b, 0xfb, 0xe2, 0x6d, 0x9e, 0x17, 0x7a, 0xd2,
- 0xe6, 0x85, 0x69, 0xd4, 0xe9, 0xb1, 0xb9, 0xb8, 0xdc, 0xd0, 0xeb, 0x65,
- 0xae, 0x95, 0x7f, 0x7d, 0x91, 0x22, 0xf6, 0x5b, 0x70, 0x1d, 0xe8, 0xc8,
- 0x3a, 0xf4, 0xeb, 0x9e, 0xc3, 0x8c, 0x4f, 0x23, 0xf9, 0x69, 0xcd, 0xec,
- 0x44, 0xfa, 0x79, 0x19, 0x3f, 0xed, 0xf3, 0x78, 0x3f, 0x6e, 0xd6, 0xa9,
- 0xba, 0x0f, 0xe7, 0x3a, 0xe8, 0x7d, 0x71, 0xcf, 0x98, 0x3f, 0xa7, 0x49,
- 0xff, 0xb2, 0xb1, 0x39, 0x92, 0x53, 0x2a, 0x0a, 0x29, 0x0e, 0x4b, 0xfc,
- 0xb3, 0xb0, 0x27, 0x92, 0x60, 0x1c, 0xfa, 0x9e, 0x05, 0x3d, 0xcc, 0x71,
- 0xa0, 0xfc, 0x7b, 0x75, 0x83, 0x46, 0xe7, 0xa6, 0xfa, 0x71, 0x8f, 0xca,
- 0xa3, 0xf4, 0xb9, 0x58, 0xc5, 0x45, 0x49, 0x03, 0xad, 0x45, 0xd7, 0x21,
- 0xb2, 0x53, 0xf7, 0xa7, 0x8c, 0x27, 0x1d, 0x2b, 0xee, 0xdb, 0xa9, 0xf1,
- 0x22, 0xe3, 0x49, 0xc5, 0xad, 0x39, 0xce, 0xcc, 0x71, 0x94, 0x1a, 0x3f,
- 0x7e, 0xea, 0x2f, 0x7a, 0x31, 0xa0, 0x77, 0x89, 0x2b, 0x92, 0x18, 0x7e,
- 0x38, 0x8e, 0xa7, 0x80, 0x63, 0x84, 0xf5, 0xd6, 0xa2, 0x34, 0x8f, 0x3e,
- 0x25, 0x86, 0xd8, 0x9f, 0xd3, 0xd5, 0x9c, 0xff, 0x15, 0xf0, 0x67, 0xdf,
- 0x0a, 0xe8, 0xd3, 0xc7, 0x79, 0x74, 0x87, 0xe7, 0x0c, 0xc4, 0x81, 0x5b,
- 0xeb, 0x9c, 0x60, 0xbf, 0x73, 0x3c, 0x76, 0x33, 0x0e, 0xb7, 0x81, 0x83,
- 0xa6, 0x70, 0x88, 0x1a, 0x38, 0xa8, 0x7a, 0x63, 0x96, 0x53, 0xa0, 0xc7,
- 0x93, 0xa4, 0x4b, 0xb4, 0xab, 0x34, 0x8f, 0xe5, 0xb0, 0xdd, 0x3a, 0x5f,
- 0x83, 0xb4, 0xcf, 0xcf, 0xf6, 0xf9, 0xc4, 0xbe, 0x35, 0xe6, 0x73, 0x79,
- 0x7c, 0xce, 0xab, 0x9f, 0xc3, 0x3e, 0xf2, 0x55, 0xcb, 0x82, 0xaf, 0xc4,
- 0x51, 0xc9, 0x4d, 0xcf, 0x4b, 0x33, 0x9e, 0x54, 0xa9, 0xe9, 0x0f, 0xf5,
- 0x48, 0xf7, 0x1b, 0xd5, 0x2d, 0xcd, 0xa8, 0x43, 0xf7, 0xa8, 0xae, 0x7b,
- 0x4f, 0xf7, 0xa2, 0x6e, 0x9c, 0xee, 0x3d, 0xcb, 0x7d, 0x98, 0x71, 0x69,
- 0xa1, 0xf7, 0x83, 0x8e, 0x5d, 0x45, 0x6a, 0x1d, 0x4a, 0xd5, 0xa3, 0xcc,
- 0xa4, 0x87, 0xba, 0x77, 0xb1, 0x39, 0x01, 0x73, 0xea, 0x16, 0x9a, 0x13,
- 0x3c, 0xc6, 0xbc, 0x9d, 0xda, 0x4f, 0x26, 0x1f, 0x3c, 0x6e, 0x3f, 0xd9,
- 0xd9, 0x60, 0xbe, 0xaf, 0x46, 0x4c, 0x8e, 0xe3, 0x9e, 0x16, 0xee, 0xdf,
- 0xbb, 0x39, 0xcf, 0xaf, 0x7b, 0x03, 0x74, 0x6f, 0xc7, 0x2b, 0x64, 0xaf,
- 0x08, 0xe5, 0xc1, 0xbe, 0x8e, 0xed, 0xf8, 0xde, 0xe1, 0xc3, 0x7e, 0xa9,
- 0x0f, 0xbf, 0xa3, 0xb4, 0xb8, 0x35, 0xe2, 0x2f, 0xf5, 0x81, 0x86, 0xb8,
- 0x3e, 0x4c, 0x1a, 0xef, 0x09, 0xd0, 0x51, 0x57, 0xb6, 0xf7, 0x04, 0xde,
- 0x65, 0x17, 0x5d, 0xa8, 0x1f, 0xa2, 0x06, 0x73, 0x74, 0x53, 0x95, 0x46,
- 0xdf, 0x5b, 0x6b, 0xd0, 0xa7, 0x51, 0x9f, 0x33, 0xed, 0x2a, 0x43, 0xbc,
- 0x96, 0x26, 0xdf, 0x1d, 0xe6, 0xf7, 0x89, 0x16, 0x49, 0x18, 0xf3, 0x7f,
- 0xaa, 0x1e, 0xc8, 0x33, 0x29, 0x9f, 0x96, 0xfa, 0x9c, 0xfd, 0x28, 0xef,
- 0x12, 0x07, 0xcf, 0x6d, 0x77, 0xf9, 0x77, 0x82, 0x42, 0x71, 0x69, 0x1c,
- 0x38, 0x4c, 0x8e, 0x5b, 0xe5, 0xb1, 0xd4, 0x43, 0xdd, 0x03, 0xbb, 0x94,
- 0x9d, 0xc9, 0x7b, 0xa1, 0xd7, 0x5e, 0xd6, 0xff, 0x06, 0xfd, 0x9e, 0x11,
- 0x62, 0x7b, 0xa5, 0x5c, 0xec, 0x6f, 0xa5, 0xf7, 0x53, 0x8e, 0x88, 0x19,
- 0xeb, 0xd4, 0x77, 0x4d, 0x0b, 0xe9, 0x55, 0xc0, 0xfd, 0x3d, 0x64, 0x9a,
- 0x43, 0xc0, 0x1f, 0xac, 0x03, 0x1d, 0xa9, 0x53, 0x7e, 0x53, 0xfe, 0x55,
- 0xfe, 0x84, 0xdf, 0x43, 0xf5, 0xc4, 0xd6, 0xd8, 0x51, 0x4f, 0x09, 0x5f,
- 0xd7, 0x31, 0xab, 0xfa, 0x3d, 0xce, 0xef, 0x0c, 0x4b, 0xfe, 0x77, 0xc4,
- 0x77, 0x61, 0x34, 0xd8, 0x9f, 0x99, 0x26, 0xe7, 0x7c, 0xc1, 0x7f, 0xe6,
- 0xf7, 0x82, 0x43, 0x5c, 0xcc, 0xe1, 0xed, 0x06, 0x35, 0xff, 0x66, 0x7b,
- 0xf7, 0x48, 0x3b, 0xba, 0x1f, 0xa4, 0xcf, 0xd3, 0xc9, 0x79, 0x58, 0xd9,
- 0x2b, 0xcf, 0xd5, 0x71, 0x1c, 0x7b, 0x44, 0xd3, 0x16, 0xfc, 0xce, 0xe1,
- 0x77, 0x23, 0x6f, 0xfc, 0x6e, 0xab, 0xf7, 0xa9, 0x1e, 0x47, 0xb9, 0x54,
- 0x30, 0x96, 0x16, 0xe4, 0x92, 0x7d, 0x27, 0x2e, 0x7f, 0x43, 0x6c, 0x1f,
- 0x25, 0xf2, 0xb0, 0x5f, 0xd4, 0x84, 0x6b, 0x9c, 0x14, 0xf7, 0x0e, 0x71,
- 0x14, 0x79, 0xf1, 0xe1, 0x08, 0xe8, 0x07, 0xe2, 0x65, 0xc8, 0x29, 0x18,
- 0xa0, 0xbe, 0xea, 0x29, 0x02, 0xcc, 0xf1, 0x04, 0xc7, 0x7b, 0xb1, 0x9d,
- 0x7e, 0x87, 0x5d, 0x10, 0x3e, 0xfe, 0x9d, 0x8c, 0xf3, 0x17, 0x71, 0xed,
- 0x34, 0xf9, 0xff, 0x51, 0xe3, 0x1c, 0xfd, 0x33, 0xc1, 0x7e, 0xe7, 0x78,
- 0xf7, 0xa4, 0xc7, 0xbb, 0xc2, 0xa9, 0xd8, 0x6e, 0x19, 0xdf, 0xeb, 0x33,
- 0xe3, 0x5b, 0xe9, 0x97, 0xda, 0x3f, 0x33, 0xe5, 0xe3, 0x1d, 0x75, 0xe9,
- 0x89, 0xc5, 0x37, 0xe8, 0xd6, 0x4a, 0x79, 0x7f, 0x51, 0xc6, 0xbc, 0x9c,
- 0x9e, 0x7f, 0xa8, 0x77, 0xd5, 0x7a, 0x3c, 0xfc, 0x07, 0xd7, 0x0d, 0x36,
- 0x4f, 0xf0, 0x16, 0x00, 0x00, 0x00 };
-
-static u8 bnx2_TPAT_b09FwText[] = {
- 0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0x73, 0xe7, 0xee, 0x7a,
- 0x6d, 0x39, 0xf1, 0xb8, 0x99, 0x96, 0x4d, 0x63, 0xd4, 0x99, 0x78, 0xfc,
- 0x43, 0x6d, 0x95, 0x69, 0x59, 0x15, 0x17, 0x56, 0x68, 0xba, 0xbb, 0x71,
- 0xad, 0xaa, 0xaa, 0x5c, 0x29, 0x88, 0x4a, 0x8d, 0x90, 0x59, 0x37, 0x6d,
- 0x79, 0x4b, 0x11, 0x0f, 0x48, 0x45, 0xca, 0xb2, 0x76, 0xd2, 0x08, 0x2d,
- 0x99, 0xd6, 0x85, 0x44, 0x42, 0x7d, 0x88, 0x9c, 0x3a, 0xee, 0xc3, 0xca,
- 0x9b, 0x8a, 0x07, 0x24, 0xa4, 0xa8, 0x55, 0x80, 0xc0, 0x1b, 0x7d, 0xa8,
- 0xf8, 0x79, 0x22, 0x12, 0x0f, 0x54, 0x08, 0x90, 0x85, 0x04, 0x2a, 0xa5,
- 0xe4, 0xf2, 0x7d, 0x77, 0x67, 0x92, 0xc5, 0x4d, 0x41, 0xe5, 0x81, 0x95,
- 0x56, 0x77, 0xe6, 0xde, 0x73, 0xce, 0x3d, 0xf7, 0xfc, 0x7c, 0xe7, 0xdc,
- 0x39, 0xec, 0xc8, 0x88, 0x64, 0xbf, 0x7d, 0xf8, 0x57, 0xbe, 0x72, 0xe2,
- 0xeb, 0x0f, 0xdc, 0x57, 0xb9, 0x0f, 0x8f, 0x0f, 0x3a, 0x77, 0x6b, 0x2d,
- 0xff, 0xc7, 0x9f, 0x2b, 0xe2, 0xe5, 0x7a, 0xf0, 0x2f, 0x25, 0x55, 0x4d,
- 0x0e, 0xd6, 0x22, 0x29, 0xb9, 0xd5, 0xea, 0xfc, 0x6a, 0x24, 0x92, 0x74,
- 0xe7, 0x82, 0xba, 0xfc, 0xd3, 0xb4, 0x7c, 0x2d, 0x9c, 0xff, 0x64, 0xf5,
- 0x83, 0x4f, 0x5f, 0xf9, 0x6c, 0xb8, 0x7b, 0xc1, 0x95, 0x92, 0x57, 0x3d,
- 0xa3, 0xbd, 0x69, 0x29, 0x4d, 0x80, 0xe7, 0xd5, 0x99, 0x6f, 0x17, 0x64,
- 0x7f, 0x2e, 0xab, 0x65, 0x54, 0x74, 0xdd, 0x5c, 0x99, 0x89, 0xbc, 0x36,
- 0x36, 0xb8, 0xdc, 0x0b, 0xa4, 0xd6, 0x2b, 0xcb, 0x9b, 0x3d, 0x5f, 0xde,
- 0xe8, 0x69, 0x39, 0xfe, 0xca, 0x49, 0x59, 0x8f, 0xc3, 0x72, 0xc3, 0x2d,
- 0x89, 0xaa, 0x86, 0xe5, 0xa6, 0x04, 0xb2, 0x15, 0x87, 0xad, 0x15, 0x77,
- 0xdc, 0x29, 0x55, 0x4b, 0xf2, 0xc2, 0x8c, 0x92, 0x0b, 0xfe, 0x31, 0x79,
- 0x26, 0x7a, 0x12, 0x7f, 0x2d, 0x6a, 0x43, 0x3b, 0xf5, 0xf3, 0x5a, 0xf4,
- 0xc6, 0x98, 0x3c, 0x12, 0x1b, 0xb3, 0x1a, 0x27, 0xe0, 0x9f, 0x9c, 0x7d,
- 0x56, 0x86, 0xa5, 0xe5, 0x85, 0x4b, 0x22, 0x05, 0xd2, 0x48, 0x2d, 0x2e,
- 0x48, 0xe2, 0xf5, 0xcf, 0x75, 0xc1, 0x8e, 0x1f, 0x98, 0x2d, 0xf0, 0x0f,
- 0x47, 0xf9, 0xfa, 0x1d, 0xd9, 0xba, 0x97, 0xad, 0x2b, 0x51, 0xe7, 0xc2,
- 0x60, 0x5b, 0xa6, 0x12, 0xed, 0xdc, 0x30, 0xb5, 0xe8, 0x2e, 0xaf, 0xb6,
- 0xad, 0xc5, 0xdd, 0xa0, 0xfe, 0x91, 0x57, 0x17, 0x03, 0x1e, 0x97, 0x3c,
- 0x5a, 0x55, 0xbf, 0x06, 0xbf, 0x4d, 0x25, 0xca, 0x11, 0xb9, 0xda, 0x29,
- 0x7b, 0xb5, 0xde, 0x37, 0x9c, 0x5a, 0x7a, 0xc3, 0x24, 0x7a, 0x44, 0x54,
- 0x94, 0x38, 0xb5, 0x6d, 0xca, 0x1a, 0x16, 0x1d, 0x0d, 0x81, 0x67, 0xd2,
- 0x53, 0xc2, 0xb1, 0x96, 0xcd, 0x53, 0x76, 0x03, 0xcf, 0x8b, 0x4e, 0xb2,
- 0xad, 0x9d, 0xda, 0xf9, 0x25, 0x3c, 0x97, 0xc0, 0x0f, 0xbb, 0xc4, 0x8e,
- 0x24, 0xcb, 0x0e, 0xf8, 0x78, 0x4e, 0x0f, 0xef, 0x4a, 0x12, 0xdf, 0x93,
- 0xb5, 0x4a, 0x58, 0x6e, 0xc9, 0xa3, 0x4e, 0x7d, 0xfb, 0x43, 0x4e, 0xf3,
- 0x96, 0x7a, 0x1f, 0x9e, 0xa3, 0x2e, 0x0f, 0x6b, 0x63, 0xd4, 0xfd, 0x43,
- 0xd9, 0x19, 0x29, 0x2f, 0xe9, 0xeb, 0xef, 0xf3, 0x1d, 0x3a, 0xa7, 0xd0,
- 0xbd, 0x5b, 0x84, 0x3e, 0xc6, 0x70, 0x9f, 0x5a, 0x54, 0x87, 0x9e, 0x09,
- 0xfe, 0xe1, 0x99, 0x26, 0x42, 0xe1, 0xf0, 0xb9, 0x7d, 0x12, 0x8c, 0x1b,
- 0xd3, 0x88, 0x43, 0x6f, 0x5b, 0x26, 0x64, 0x2d, 0x9d, 0xf0, 0x8e, 0xa4,
- 0x6d, 0xac, 0xb7, 0x48, 0x03, 0x7b, 0x88, 0x1c, 0xe9, 0x1a, 0x73, 0x29,
- 0x3e, 0x50, 0x94, 0xfd, 0x6a, 0xbe, 0x20, 0x61, 0x90, 0x60, 0xee, 0xf0,
- 0xa5, 0xbd, 0x36, 0xbb, 0x27, 0xd3, 0x81, 0x76, 0xc7, 0x3e, 0xf1, 0xa1,
- 0xec, 0x7d, 0xd4, 0xab, 0x9d, 0xcf, 0xed, 0x6c, 0xf5, 0x86, 0x5d, 0x63,
- 0xa9, 0x55, 0xa0, 0xff, 0x47, 0x9e, 0x29, 0xe7, 0xa3, 0x2e, 0xd4, 0x1b,
- 0xf4, 0xd1, 0x2d, 0x9d, 0x9e, 0xfa, 0x90, 0x4e, 0xd4, 0x47, 0x89, 0x3e,
- 0x57, 0x92, 0xf5, 0xe8, 0x71, 0x25, 0xfb, 0x8d, 0x59, 0x8f, 0xb5, 0xd3,
- 0x38, 0x7f, 0x2c, 0x7b, 0x46, 0x1c, 0xa6, 0x88, 0xc3, 0x14, 0x71, 0x99,
- 0x8a, 0xa7, 0xaa, 0x81, 0x5c, 0x99, 0x29, 0xc9, 0x75, 0x17, 0xfe, 0xec,
- 0xcd, 0x79, 0xaf, 0x21, 0xa6, 0x12, 0xcf, 0x11, 0x37, 0x4a, 0x66, 0x0b,
- 0xc2, 0x77, 0xc4, 0x92, 0x4e, 0xca, 0x2e, 0x62, 0x29, 0x39, 0xca, 0xb9,
- 0x21, 0x59, 0xb1, 0x67, 0x99, 0xf3, 0x4e, 0x09, 0x7d, 0x55, 0xc3, 0xda,
- 0x64, 0x70, 0x4a, 0x76, 0x11, 0x1f, 0x35, 0xac, 0x53, 0x56, 0xe8, 0xb5,
- 0x40, 0xd1, 0x4e, 0xdf, 0x45, 0x0e, 0xf8, 0x88, 0xfb, 0x99, 0xb2, 0x12,
- 0x47, 0x56, 0xe7, 0x61, 0x8b, 0xf9, 0x29, 0xd8, 0x88, 0x39, 0xc1, 0xb8,
- 0xfa, 0xeb, 0xb4, 0x8e, 0x4e, 0x22, 0x7e, 0x40, 0x8b, 0xf3, 0x9f, 0x4a,
- 0x67, 0xc0, 0x1f, 0x15, 0xa9, 0xe7, 0x56, 0xac, 0x65, 0x3d, 0xbd, 0xa2,
- 0x0a, 0xd1, 0xef, 0x1d, 0xd9, 0x1f, 0xb6, 0x12, 0x09, 0x5b, 0x4a, 0x29,
- 0x9f, 0x5b, 0xbf, 0x84, 0x3c, 0x7a, 0xd3, 0xea, 0xaf, 0xc1, 0x57, 0xce,
- 0xf4, 0xa7, 0xdd, 0x45, 0x36, 0x3b, 0x61, 0xbc, 0x08, 0xdd, 0xae, 0xc2,
- 0xff, 0xb4, 0xf9, 0xa5, 0x2e, 0x64, 0x77, 0x1c, 0xe6, 0xae, 0xb4, 0xbb,
- 0xa4, 0xb3, 0x69, 0xbe, 0xa2, 0xab, 0xb2, 0xdc, 0xee, 0x9c, 0x34, 0x6e,
- 0x24, 0x2b, 0x85, 0x2a, 0xfd, 0x36, 0xba, 0x00, 0x3f, 0x2c, 0xb7, 0xbb,
- 0x13, 0x8f, 0x6d, 0x76, 0xa4, 0x75, 0x77, 0x55, 0x5a, 0x6e, 0x45, 0xdd,
- 0xa5, 0x64, 0x0c, 0x72, 0xab, 0xd8, 0x87, 0x71, 0x15, 0x06, 0x75, 0x77,
- 0xe2, 0xb1, 0x8b, 0x9d, 0x7b, 0x90, 0xb7, 0xf2, 0x41, 0xad, 0x12, 0x21,
- 0x77, 0xaf, 0x1e, 0x74, 0x25, 0x92, 0xb5, 0x5e, 0x49, 0x6a, 0xe9, 0x84,
- 0xac, 0xf7, 0x24, 0x79, 0x6a, 0x06, 0xfb, 0x55, 0xf0, 0xde, 0x9b, 0x97,
- 0x56, 0x6f, 0x62, 0x45, 0x55, 0x5b, 0x92, 0xf4, 0xd6, 0xf1, 0x2f, 0x49,
- 0xa3, 0x53, 0x2a, 0x5d, 0xec, 0xb4, 0xc8, 0x5f, 0x72, 0xaa, 0x81, 0x3e,
- 0xdc, 0xdd, 0x65, 0xdc, 0x40, 0xce, 0xf0, 0x97, 0x54, 0x55, 0x4b, 0xd3,
- 0xf7, 0x21, 0xc3, 0x81, 0x4d, 0xa8, 0xeb, 0x2c, 0xf6, 0xed, 0x8f, 0xad,
- 0x1e, 0x7d, 0x37, 0x24, 0xed, 0x78, 0x1e, 0x76, 0x62, 0xd4, 0x0e, 0xc9,
- 0x5a, 0xf4, 0x9e, 0x79, 0x1a, 0xb1, 0xfa, 0x9a, 0x98, 0x7b, 0x6a, 0xc0,
- 0x93, 0x1a, 0x4c, 0xfa, 0x42, 0x54, 0x96, 0x53, 0xd8, 0xb7, 0xcf, 0xb7,
- 0x0e, 0x1d, 0xc8, 0x37, 0x06, 0xbe, 0x06, 0xf8, 0x7c, 0x39, 0x6d, 0x79,
- 0xc7, 0xc0, 0xbb, 0x9b, 0xf1, 0xce, 0x95, 0x17, 0x25, 0x06, 0xcf, 0x64,
- 0xb0, 0x08, 0x7f, 0xae, 0xf8, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x54,
- 0x5a, 0xba, 0x42, 0xb9, 0x61, 0xf9, 0x69, 0xe6, 0x83, 0x95, 0xd9, 0x82,
- 0x4c, 0xe8, 0x95, 0x96, 0x20, 0x67, 0x01, 0xe3, 0x3b, 0xa6, 0x9d, 0x02,
- 0x77, 0x7c, 0x3e, 0xbf, 0x69, 0x54, 0x15, 0x31, 0x5a, 0x89, 0x82, 0xb6,
- 0xf0, 0xbd, 0x28, 0x75, 0xe4, 0x99, 0x8a, 0xc6, 0xa4, 0xe9, 0x39, 0x8e,
- 0xaa, 0xba, 0xd2, 0x44, 0x84, 0x26, 0xcb, 0xda, 0xce, 0xad, 0x20, 0xce,
- 0x54, 0xf5, 0x7b, 0xaa, 0x5f, 0x0f, 0x0a, 0xa0, 0x41, 0x6e, 0x46, 0xa3,
- 0xb0, 0xc1, 0x38, 0x68, 0xcf, 0x62, 0x7e, 0x0a, 0xf8, 0x39, 0x0e, 0x1a,
- 0x8e, 0xcc, 0x11, 0xda, 0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60,
- 0x9b, 0xc1, 0xb4, 0xc9, 0x7d, 0x0c, 0x9a, 0x54, 0x67, 0x79, 0x37, 0x98,
- 0x4b, 0xf9, 0x7a, 0x80, 0xf5, 0xab, 0x9f, 0x52, 0xb2, 0x6b, 0x2e, 0x46,
- 0x8c, 0x61, 0x79, 0xaf, 0x11, 0x25, 0xe3, 0xae, 0xcd, 0xf3, 0x3c, 0xdf,
- 0x39, 0xb2, 0x16, 0x9c, 0x39, 0xb8, 0x1a, 0x39, 0xee, 0xfa, 0xfc, 0x01,
- 0x69, 0xf9, 0x61, 0x5c, 0x87, 0xbf, 0xd7, 0x53, 0xe6, 0xc6, 0x18, 0xce,
- 0x1d, 0x22, 0xea, 0x26, 0xf1, 0x9c, 0x1c, 0x04, 0x0f, 0xfc, 0xd8, 0x82,
- 0x2c, 0x8e, 0x88, 0x99, 0x34, 0x84, 0x8e, 0xb0, 0x47, 0x34, 0xe7, 0x1d,
- 0x61, 0x3c, 0xfa, 0x5c, 0x63, 0x8d, 0x79, 0xf5, 0x50, 0x2d, 0x0a, 0xe3,
- 0x66, 0x96, 0x2b, 0x6f, 0xc1, 0xb6, 0xed, 0x94, 0xf5, 0x22, 0xaf, 0x11,
- 0xcc, 0x0f, 0xc6, 0x4a, 0x8e, 0xb1, 0xe0, 0x89, 0x98, 0x9f, 0xa5, 0x0c,
- 0x6b, 0x6b, 0x19, 0x8e, 0x2e, 0x40, 0x0f, 0x63, 0x9e, 0x00, 0x86, 0xb6,
- 0x63, 0x1b, 0x9f, 0xad, 0x40, 0xdd, 0x30, 0x93, 0xd3, 0xb4, 0xb9, 0x31,
- 0x27, 0xe2, 0x45, 0xd0, 0xfe, 0x16, 0xf6, 0x5a, 0x02, 0x8e, 0x12, 0x7b,
- 0xb9, 0x77, 0x55, 0xd7, 0x3a, 0xfb, 0xa0, 0x4b, 0x00, 0x7c, 0x83, 0x0d,
- 0x2c, 0xde, 0x0e, 0x23, 0xdf, 0x99, 0xf3, 0x61, 0xb0, 0x22, 0x9c, 0x97,
- 0x61, 0x85, 0xf7, 0x26, 0xfc, 0xb4, 0x5e, 0x79, 0xd4, 0x69, 0x6c, 0xbf,
- 0x9f, 0xf9, 0x48, 0xc6, 0x14, 0x6a, 0x49, 0xd3, 0x27, 0x5f, 0x11, 0x7c,
- 0xfb, 0xc0, 0xf3, 0x77, 0xac, 0x15, 0x30, 0x0e, 0xca, 0xb1, 0xb8, 0x8d,
- 0xbd, 0x02, 0xec, 0xb5, 0x24, 0xba, 0xfa, 0x3c, 0xb0, 0x67, 0x2a, 0x68,
- 0xc8, 0xf7, 0x55, 0xbf, 0x46, 0xd2, 0x37, 0x5f, 0x18, 0xf0, 0x4d, 0x20,
- 0xae, 0xcd, 0xc1, 0x87, 0xb2, 0x98, 0x22, 0x66, 0x3e, 0x98, 0xad, 0xfb,
- 0xc0, 0xbe, 0xcf, 0x64, 0x18, 0x5e, 0x22, 0x0e, 0xca, 0x19, 0x8b, 0x83,
- 0x45, 0xe2, 0x20, 0x70, 0xa5, 0xb5, 0x00, 0x7b, 0xc7, 0xef, 0x02, 0x5f,
- 0xea, 0xf0, 0xc4, 0x4f, 0x3a, 0x1a, 0x71, 0xe5, 0x82, 0x9f, 0x75, 0xf8,
- 0xf3, 0xae, 0x8c, 0x84, 0xde, 0xbb, 0xc0, 0x9b, 0xe4, 0x28, 0xf3, 0xc0,
- 0x18, 0xe4, 0x3a, 0xb0, 0x6a, 0xba, 0x7c, 0x0a, 0x71, 0xef, 0x02, 0x27,
- 0xb4, 0x70, 0xdf, 0xbc, 0x6e, 0xe6, 0xf5, 0x9b, 0xbf, 0xb7, 0x1d, 0xb8,
- 0x19, 0xb5, 0xee, 0x73, 0x90, 0x31, 0x15, 0x1c, 0x81, 0x1f, 0xd7, 0x16,
- 0xfe, 0x1b, 0xcf, 0x6f, 0x32, 0x1e, 0xd4, 0x90, 0x0a, 0xf7, 0x15, 0x69,
- 0x74, 0x69, 0x87, 0x18, 0x76, 0xb0, 0x18, 0x84, 0x9c, 0x8f, 0x91, 0xf3,
- 0x22, 0x4d, 0x62, 0x05, 0x30, 0x8c, 0xb8, 0xb7, 0x06, 0x7a, 0x55, 0x19,
- 0x82, 0x5d, 0x11, 0x4b, 0x4a, 0x4a, 0xba, 0x7a, 0x54, 0xaf, 0x83, 0xb6,
- 0x50, 0x5d, 0xd6, 0x5b, 0xd1, 0x31, 0x37, 0xef, 0x97, 0xda, 0x1d, 0x71,
- 0x6a, 0x7d, 0x3f, 0x67, 0x74, 0x8f, 0x65, 0x74, 0x4b, 0x83, 0x74, 0x98,
- 0x6f, 0x64, 0xf3, 0x09, 0xe6, 0x3f, 0x91, 0xd9, 0x9c, 0xb5, 0xa0, 0x84,
- 0x3a, 0xcb, 0x3a, 0x10, 0x06, 0x81, 0xfa, 0x4f, 0x75, 0x60, 0x61, 0x00,
- 0xbb, 0x45, 0xd9, 0xbe, 0xc2, 0x67, 0x4c, 0x0e, 0x9e, 0x75, 0x58, 0x49,
- 0x74, 0x33, 0x3e, 0xf1, 0xdb, 0xcc, 0xf6, 0x21, 0x2d, 0xf1, 0x7a, 0x90,
- 0x16, 0x69, 0x04, 0xbb, 0xa8, 0xb3, 0xb7, 0xb3, 0xd9, 0x01, 0xac, 0x21,
- 0xe7, 0x53, 0x57, 0x1e, 0xd6, 0xcc, 0xef, 0x7b, 0xb5, 0x3d, 0xc7, 0x0e,
- 0xe8, 0x77, 0x26, 0x2c, 0xce, 0x2c, 0x75, 0x86, 0x20, 0x7e, 0x54, 0x8e,
- 0x23, 0x9f, 0x9f, 0x86, 0xef, 0x2f, 0xc6, 0x0a, 0xdd, 0x02, 0x6b, 0x8e,
- 0x41, 0x1c, 0x86, 0xd6, 0x17, 0xb5, 0x68, 0x0d, 0x91, 0xfc, 0x2d, 0xb9,
- 0x3a, 0x3f, 0x22, 0x85, 0x4b, 0xd4, 0x01, 0xfd, 0xd2, 0xe6, 0xe0, 0x3e,
- 0x73, 0xd8, 0x67, 0x02, 0x18, 0x78, 0x3f, 0xea, 0x8b, 0x2f, 0x7a, 0x1a,
- 0x58, 0x9b, 0x96, 0x9c, 0x3a, 0xe4, 0xab, 0x4b, 0x3c, 0x3f, 0x31, 0xb8,
- 0x94, 0xd5, 0x36, 0xe6, 0xd6, 0x10, 0x6a, 0xfa, 0x1f, 0x91, 0xbb, 0x4a,
- 0x56, 0x2b, 0xc6, 0x1c, 0x89, 0x7f, 0x00, 0xfb, 0x62, 0x6e, 0x93, 0x6b,
- 0xbb, 0x98, 0xe7, 0x1c, 0x65, 0x30, 0x16, 0x0f, 0xa0, 0xae, 0x61, 0xcf,
- 0xa3, 0xe4, 0x19, 0x42, 0xcd, 0x27, 0xfe, 0x63, 0xdc, 0xe4, 0x3b, 0xcf,
- 0x44, 0x6c, 0x73, 0x31, 0x8e, 0x60, 0xe4, 0x99, 0x7e, 0x91, 0xf9, 0x8a,
- 0xcf, 0xc6, 0xe8, 0xea, 0xa8, 0xd4, 0x3b, 0x11, 0x30, 0x76, 0xaa, 0x7c,
- 0x5c, 0xb8, 0x86, 0xf7, 0x2e, 0xe7, 0xbd, 0x81, 0x79, 0x3c, 0x77, 0xad,
- 0xce, 0xa8, 0xed, 0x79, 0xff, 0xb2, 0x06, 0xc3, 0xa2, 0xc7, 0xd8, 0x64,
- 0xaf, 0xc2, 0xfa, 0x67, 0x71, 0x6b, 0x96, 0x7d, 0xca, 0xeb, 0x1d, 0xd6,
- 0x42, 0xcd, 0xbc, 0x44, 0x00, 0x1c, 0x92, 0xba, 0x9f, 0x9f, 0x0b, 0x71,
- 0x1c, 0x53, 0x36, 0x65, 0x4c, 0xc2, 0x76, 0xec, 0x47, 0xa2, 0xb2, 0x76,
- 0xa6, 0x92, 0x26, 0xf9, 0xba, 0x05, 0x29, 0x6c, 0xcc, 0x8b, 0x7b, 0xd6,
- 0xc8, 0x66, 0x5f, 0x9e, 0xb7, 0x2c, 0xbe, 0xd4, 0x5e, 0xa2, 0x1e, 0x98,
- 0xdf, 0x61, 0x3d, 0x0c, 0x81, 0x67, 0xc5, 0x6c, 0xdf, 0xb2, 0x34, 0x3b,
- 0x91, 0xd7, 0x10, 0x8c, 0xdd, 0x3b, 0xe0, 0xbb, 0x22, 0xce, 0xac, 0xe5,
- 0x62, 0xa7, 0xbf, 0x17, 0x73, 0xee, 0xb9, 0xb8, 0xbf, 0x57, 0x43, 0x7e,
- 0x89, 0xbd, 0xc4, 0x57, 0xc2, 0x3e, 0x12, 0x7d, 0xe3, 0x39, 0x8d, 0xfd,
- 0x68, 0xa3, 0x02, 0x7a, 0xdb, 0xd9, 0xec, 0x3c, 0x21, 0xe8, 0x34, 0x6c,
- 0x4e, 0x5b, 0x73, 0x0f, 0xc6, 0xe2, 0x3f, 0x0c, 0xf1, 0x05, 0x75, 0x05,
- 0xfa, 0xe2, 0xbd, 0xc7, 0x3d, 0x26, 0xe4, 0xc5, 0xd4, 0x62, 0xad, 0x77,
- 0x02, 0x98, 0xd5, 0xe8, 0xfc, 0x2d, 0xaf, 0x3d, 0x49, 0x1b, 0xf8, 0xfb,
- 0xac, 0x8c, 0x8a, 0xde, 0x19, 0x95, 0xe7, 0xd0, 0xef, 0x15, 0x36, 0x50,
- 0xe7, 0x61, 0x63, 0x75, 0xb6, 0x35, 0xcb, 0x9e, 0xed, 0x32, 0x72, 0x79,
- 0xb5, 0x12, 0xc5, 0xae, 0x33, 0x2d, 0x67, 0xbe, 0x1b, 0xce, 0x6e, 0xdb,
- 0x7c, 0xc6, 0xfa, 0x4e, 0x20, 0xa7, 0xbb, 0x91, 0x9c, 0xe9, 0x7a, 0xd0,
- 0xcb, 0xbb, 0xd5, 0xd7, 0x46, 0xc4, 0xdb, 0x06, 0xfe, 0xc4, 0x53, 0x9e,
- 0x0b, 0x3e, 0xa8, 0xd2, 0x6e, 0xec, 0x63, 0xe9, 0x5f, 0xe2, 0xdb, 0xa3,
- 0x78, 0x1e, 0x11, 0xf7, 0x1c, 0xfb, 0x4e, 0xc6, 0x24, 0xfd, 0x33, 0xd8,
- 0x0b, 0x13, 0xfb, 0x20, 0x73, 0x87, 0xb9, 0x9f, 0xe7, 0x66, 0x9e, 0xab,
- 0xc4, 0x01, 0xed, 0x2c, 0xc2, 0x5e, 0xd7, 0x62, 0xe6, 0xeb, 0x0d, 0x73,
- 0xcd, 0xf6, 0x6e, 0x1e, 0xfb, 0xe2, 0x81, 0xde, 0x2d, 0xef, 0x7b, 0x18,
- 0xaf, 0xe5, 0x81, 0x7c, 0xbd, 0x6e, 0x73, 0xf5, 0x0d, 0xe4, 0xed, 0xcb,
- 0x69, 0xd9, 0xe6, 0xec, 0xe1, 0x07, 0x6e, 0x97, 0xb3, 0x97, 0x3f, 0x46,
- 0xce, 0xfe, 0x30, 0xcb, 0xd9, 0xa2, 0x8d, 0x6b, 0xb5, 0x31, 0xb8, 0xf6,
- 0x23, 0xac, 0x0d, 0x65, 0x77, 0x0a, 0x6d, 0x3b, 0xe8, 0xc3, 0x0f, 0xd2,
- 0x47, 0xb9, 0x7f, 0xfa, 0x71, 0x5a, 0xd7, 0xa4, 0x81, 0x0f, 0x37, 0x46,
- 0x11, 0x4f, 0xcc, 0xe9, 0x3c, 0x9e, 0x02, 0xc4, 0x72, 0xce, 0x8f, 0x7e,
- 0xf3, 0x28, 0x63, 0xa1, 0x60, 0xf3, 0xc6, 0xad, 0xe6, 0x34, 0x65, 0x59,
- 0x44, 0x2f, 0xf7, 0x63, 0x8e, 0xdd, 0x7e, 0xac, 0x14, 0x37, 0x4a, 0xf2,
- 0xfc, 0x0c, 0xb1, 0x2b, 0x8c, 0xaf, 0x42, 0xe7, 0x6b, 0x91, 0x2f, 0x85,
- 0x69, 0xe6, 0x33, 0xab, 0x51, 0x11, 0x31, 0x84, 0xbb, 0x55, 0x6a, 0x4e,
- 0xa2, 0xdf, 0x0a, 0x34, 0xfc, 0xfc, 0x32, 0xe2, 0x88, 0xd8, 0x8a, 0x98,
- 0x98, 0xdd, 0x44, 0x4c, 0x1c, 0xe7, 0xbb, 0xdd, 0xb7, 0x60, 0x69, 0x5d,
- 0xbb, 0xbf, 0x0f, 0xfd, 0x4b, 0x32, 0x74, 0xce, 0xe0, 0x4e, 0x75, 0x8b,
- 0xef, 0xb4, 0x8d, 0x5f, 0x60, 0x09, 0xe6, 0x57, 0x6d, 0xfc, 0xd2, 0xa7,
- 0x8c, 0x7b, 0x63, 0x7e, 0x67, 0xf3, 0xe6, 0xd7, 0x16, 0x03, 0xae, 0xc5,
- 0x36, 0x9e, 0x63, 0xf6, 0x9b, 0xa7, 0xbb, 0x3f, 0xd7, 0x16, 0x23, 0x36,
- 0x8c, 0x9c, 0x8a, 0x6d, 0xac, 0xcd, 0xbe, 0x81, 0x63, 0xbf, 0xd6, 0xcf,
- 0x85, 0x01, 0x39, 0x93, 0xde, 0x23, 0x90, 0x83, 0x9a, 0x17, 0xac, 0xb1,
- 0x3f, 0x88, 0xa7, 0xd0, 0x2f, 0x81, 0xae, 0xbb, 0x17, 0x2f, 0xc6, 0x31,
- 0xd2, 0xde, 0x7f, 0x80, 0x5c, 0x0f, 0x36, 0xa4, 0x1c, 0xea, 0x4d, 0xbd,
- 0x46, 0x25, 0x3a, 0x9b, 0xeb, 0xf4, 0x17, 0xab, 0xcb, 0xbf, 0xcb, 0xc3,
- 0xfa, 0xce, 0xed, 0xf8, 0xbc, 0x01, 0xbe, 0x3f, 0xdf, 0x86, 0x0f, 0xeb,
- 0x3b, 0xe4, 0x19, 0xb9, 0xd9, 0x6b, 0xd4, 0x6f, 0xc6, 0x75, 0x82, 0xb8,
- 0x27, 0xef, 0xde, 0xbb, 0xdc, 0x60, 0x0e, 0xe4, 0x35, 0x9e, 0x71, 0xce,
- 0x3d, 0xf3, 0x58, 0xcf, 0x63, 0x3c, 0x8f, 0xf9, 0x3c, 0xd6, 0xc3, 0xf8,
- 0x19, 0xe9, 0xfb, 0x57, 0x6f, 0x84, 0xd8, 0x7f, 0xe4, 0x7f, 0xb8, 0xb7,
- 0x10, 0x23, 0x24, 0xb9, 0x75, 0xd7, 0xfb, 0x69, 0xd6, 0xaf, 0x94, 0x98,
- 0x6b, 0xf8, 0xb3, 0x8f, 0xdf, 0x45, 0x7f, 0x10, 0x67, 0xb6, 0x4d, 0xb2,
- 0xb1, 0x4f, 0xd3, 0xef, 0x07, 0xbf, 0x9a, 0x61, 0xf2, 0x17, 0xfb, 0xf5,
- 0x47, 0xf2, 0x9c, 0x62, 0x0e, 0xd9, 0x9c, 0xe2, 0x79, 0x70, 0x0f, 0x37,
- 0x66, 0x19, 0x7e, 0x7c, 0x3e, 0xce, 0xf3, 0x08, 0xf1, 0xf4, 0x40, 0x9e,
- 0xe3, 0xb0, 0x53, 0x74, 0xc3, 0xe8, 0xe9, 0x04, 0x36, 0xe3, 0xdd, 0xb7,
- 0x81, 0xde, 0x89, 0x76, 0x5a, 0x72, 0x9e, 0xb8, 0x79, 0xdf, 0xdd, 0xdb,
- 0x27, 0xd1, 0x6e, 0xb4, 0xeb, 0xa0, 0xdd, 0xc2, 0x78, 0x5c, 0x11, 0x03,
- 0x6e, 0x87, 0x13, 0x79, 0x3d, 0x07, 0x06, 0x4d, 0xe7, 0x76, 0xfa, 0xd8,
- 0x35, 0x3d, 0xe9, 0x7f, 0x2b, 0xd8, 0x8b, 0x0f, 0xdb, 0xee, 0x00, 0x3e,
- 0xdc, 0xa6, 0xe7, 0xa4, 0x0c, 0xda, 0x00, 0xf5, 0xcd, 0xf6, 0x21, 0xec,
- 0x31, 0x6f, 0x18, 0xd7, 0xf6, 0x9b, 0xc4, 0x46, 0xf6, 0x99, 0xdf, 0x2c,
- 0xc8, 0xc8, 0x3e, 0xfb, 0x9e, 0x6c, 0x73, 0x64, 0x4c, 0x48, 0xbf, 0x6e,
- 0x59, 0xfd, 0x1f, 0xcf, 0xf4, 0xef, 0xeb, 0x2c, 0xea, 0xa3, 0x30, 0x8d,
- 0xba, 0x7a, 0xd0, 0x35, 0xcc, 0xed, 0xd2, 0x52, 0xd5, 0x13, 0xd2, 0xa8,
- 0xb0, 0x5f, 0x12, 0xdc, 0xb5, 0xa0, 0xc3, 0x02, 0xf5, 0x28, 0x43, 0x8f,
- 0x51, 0xdc, 0x4d, 0xc2, 0xa5, 0x96, 0x84, 0xc9, 0x0a, 0x08, 0x67, 0xbe,
- 0x43, 0xbb, 0x1d, 0xd3, 0x5b, 0x1d, 0xda, 0xed, 0x49, 0xbd, 0xde, 0x99,
- 0x44, 0x7f, 0x18, 0xc2, 0xdb, 0xe1, 0xec, 0x25, 0x61, 0x8c, 0xcd, 0xc5,
- 0x1c, 0x4f, 0x0b, 0xfb, 0xb1, 0x63, 0x7a, 0xaa, 0xcb, 0xf1, 0x49, 0x1d,
- 0x75, 0x07, 0xe5, 0xfe, 0xc9, 0x00, 0x13, 0x93, 0xeb, 0xc8, 0xa3, 0x17,
- 0x7b, 0xfd, 0xbd, 0x71, 0x3f, 0xcc, 0xe4, 0x62, 0x2e, 0xcd, 0x65, 0x0b,
- 0x71, 0x8a, 0xb2, 0x21, 0x77, 0x32, 0xfe, 0x99, 0xdd, 0x83, 0xf7, 0xa3,
- 0x8f, 0xda, 0xe3, 0xae, 0xfc, 0xfb, 0x04, 0x72, 0xa7, 0x60, 0xb1, 0x67,
- 0x2d, 0xc5, 0x9d, 0xda, 0x37, 0xa6, 0x19, 0xbd, 0x0d, 0xdb, 0xa1, 0x47,
- 0x98, 0xf7, 0xf0, 0x07, 0xae, 0x2e, 0x73, 0x0d, 0x7d, 0x38, 0xee, 0x82,
- 0xbc, 0xcf, 0xad, 0xa5, 0x5c, 0x63, 0x8c, 0xa3, 0x57, 0x9c, 0xff, 0x15,
- 0x68, 0xdf, 0x31, 0xad, 0x9e, 0xb2, 0xf7, 0x75, 0x15, 0xe1, 0x1e, 0xd6,
- 0x63, 0x3f, 0x23, 0x4e, 0x23, 0x95, 0xa0, 0x19, 0x2f, 0xd8, 0xfb, 0x5a,
- 0xe2, 0x05, 0xbc, 0x93, 0xa2, 0x07, 0x9d, 0x1f, 0xe8, 0x41, 0xe7, 0xd1,
- 0x83, 0x8e, 0x15, 0x11, 0xe7, 0x09, 0xee, 0xa1, 0xaa, 0xd9, 0xcf, 0x9b,
- 0x31, 0xde, 0x39, 0xdb, 0xbe, 0xec, 0x43, 0x77, 0x05, 0xdd, 0x22, 0xec,
- 0xcf, 0xf5, 0x3b, 0xb3, 0xef, 0x5a, 0xa3, 0xa0, 0x4f, 0x6c, 0x3f, 0xd6,
- 0xf6, 0x8b, 0xd2, 0x8c, 0x49, 0x73, 0x28, 0xa3, 0xf9, 0xf2, 0x1e, 0x9a,
- 0x3b, 0x79, 0x46, 0xca, 0x96, 0xe6, 0x2b, 0xcc, 0x3b, 0xd6, 0xd2, 0x62,
- 0x96, 0x6f, 0x27, 0xf0, 0x3c, 0x94, 0x3d, 0xe7, 0xf4, 0xf7, 0xee, 0xe1,
- 0x7f, 0xc8, 0xe9, 0xbf, 0xf3, 0x99, 0x3a, 0x27, 0xec, 0x93, 0x21, 0x6f,
- 0xc1, 0xe9, 0x7f, 0x27, 0xc1, 0x85, 0x73, 0x84, 0x3e, 0xe9, 0xf7, 0x17,
- 0xc0, 0x60, 0x74, 0x5f, 0x53, 0xb0, 0xbb, 0x31, 0xed, 0x05, 0xe2, 0xda,
- 0xdc, 0xec, 0x11, 0x8b, 0x6f, 0x6a, 0x42, 0x49, 0x8e, 0xb9, 0x83, 0xcf,
- 0x18, 0x17, 0xec, 0x37, 0x03, 0xbc, 0xf7, 0x65, 0x6c, 0xe1, 0xfe, 0x2c,
- 0xc8, 0xe1, 0x96, 0xd5, 0xcb, 0xe9, 0xdf, 0x8b, 0xbc, 0x1a, 0xeb, 0x01,
- 0xea, 0xc6, 0x0c, 0xf5, 0xba, 0xf9, 0x6d, 0x63, 0x05, 0xb5, 0xe6, 0x2d,
- 0xc4, 0x3e, 0xf2, 0xd3, 0xf6, 0x58, 0x5b, 0xf6, 0xdb, 0x02, 0xea, 0xd0,
- 0x08, 0xee, 0x4b, 0xd1, 0xcd, 0x6f, 0x0c, 0x72, 0x01, 0x34, 0x17, 0xb1,
- 0x76, 0xba, 0x9b, 0xf7, 0xbc, 0xe8, 0xf3, 0x81, 0x7b, 0xab, 0xd1, 0xfb,
- 0xa6, 0xe9, 0x0f, 0xd2, 0xf2, 0xf7, 0x2f, 0x97, 0xa2, 0x15, 0x3a, 0x18,
- 0x15, 0x00, 0x00, 0x00 };
-
-static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = {
- 0x00000001, 0x00000000 };
-
-static struct fw_info bnx2_tpat_fw_09 = {
- /* Firmware version: 4.4.26 */
- .ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x1a,
-
- .start_addr = 0x08000488,
-
- .text_addr = 0x08000400,
- .text_len = 0x1514,
- .text_index = 0x0,
- .gz_text = bnx2_TPAT_b09FwText,
- .gz_text_len = sizeof(bnx2_TPAT_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TPAT_b09FwData,
-
- .sbss_addr = 0x08001940,
- .sbss_len = 0x48,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08001988,
- .bss_len = 0x12b4,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08001914,
- .rodata_len = 0x4,
- .rodata_index = 0x0,
- .rodata = bnx2_TPAT_b09FwRodata,
-};
-
-static u8 bnx2_TXP_b09FwText[] = {
- 0xc5, 0x7b, 0x7b, 0x74, 0x1c, 0x55, 0x9a, 0xdf, 0xef, 0x56, 0x3f, 0x54,
- 0xdd, 0x6a, 0xb5, 0x4a, 0x72, 0xdb, 0x6e, 0xed, 0x68, 0xc6, 0x5d, 0xee,
- 0x6a, 0xb9, 0xb1, 0x84, 0x5d, 0x2d, 0xb5, 0xec, 0x66, 0x5d, 0xb1, 0x7b,
- 0x8c, 0xb0, 0x65, 0x10, 0x3b, 0xc2, 0xeb, 0x9d, 0x88, 0x09, 0x27, 0xf4,
- 0x18, 0x19, 0x64, 0x63, 0x40, 0x30, 0x64, 0xa3, 0xd9, 0x25, 0xeb, 0x1a,
- 0xf9, 0x81, 0x1f, 0xad, 0xee, 0xd6, 0xc3, 0xc8, 0xec, 0xd9, 0x13, 0x64,
- 0x49, 0xb6, 0xcc, 0xd0, 0x0f, 0x33, 0xc0, 0xcc, 0x30, 0x27, 0x13, 0x77,
- 0x8c, 0x01, 0x03, 0x63, 0x98, 0xdd, 0x6c, 0x92, 0x99, 0x3d, 0x49, 0xd6,
- 0x07, 0xf3, 0xb0, 0xc1, 0x60, 0x32, 0x43, 0x12, 0xb1, 0xcb, 0x4c, 0xe5,
- 0xfb, 0xaa, 0x25, 0x63, 0x58, 0xb2, 0x9b, 0x6c, 0xfe, 0x88, 0xce, 0xd1,
- 0xe9, 0xee, 0xaa, 0x5b, 0xf7, 0x7e, 0xef, 0xef, 0xf7, 0x7d, 0xf7, 0x56,
- 0x04, 0xf0, 0x62, 0xee, 0xaf, 0x86, 0xfe, 0xe3, 0xfd, 0x03, 0x0f, 0xb7,
- 0xae, 0x88, 0xaf, 0xa0, 0xaf, 0x6d, 0x58, 0xec, 0x74, 0xf2, 0xcd, 0x55,
- 0x02, 0x48, 0xbd, 0x87, 0x7f, 0xd4, 0xdf, 0x57, 0xff, 0x71, 0x8f, 0xc1,
- 0x01, 0x28, 0xf3, 0x34, 0xf1, 0x3f, 0x64, 0xc9, 0x30, 0xd7, 0xac, 0xd7,
- 0x20, 0x3b, 0x8c, 0xc4, 0xda, 0xbb, 0x34, 0x20, 0x99, 0x6f, 0x0e, 0xdd,
- 0x88, 0xdf, 0x58, 0x66, 0xc0, 0x09, 0xbe, 0xfe, 0x55, 0xe3, 0xd3, 0x5d,
- 0x3f, 0x5d, 0xad, 0x7e, 0x34, 0xe1, 0x80, 0xac, 0x18, 0x63, 0x50, 0x9a,
- 0x20, 0x37, 0xd2, 0x33, 0x7f, 0xb6, 0xec, 0x79, 0x27, 0xfc, 0xf3, 0x73,
- 0xc1, 0x74, 0x19, 0x3a, 0x76, 0x67, 0xfb, 0x31, 0x13, 0x07, 0x2e, 0xa6,
- 0x23, 0xfa, 0x6e, 0x20, 0x27, 0x19, 0x91, 0xd0, 0x69, 0x84, 0x30, 0x9d,
- 0x87, 0x59, 0x65, 0x68, 0xd8, 0x5f, 0x0a, 0xe1, 0x52, 0xfa, 0xb7, 0x56,
- 0xc8, 0xd5, 0x8f, 0xb7, 0xe2, 0x90, 0x83, 0xc6, 0x23, 0x08, 0x66, 0x21,
- 0xd7, 0x18, 0x03, 0x28, 0x0c, 0x01, 0x7b, 0xd3, 0x6a, 0x3f, 0xa0, 0xf6,
- 0x14, 0x45, 0xf8, 0xec, 0x09, 0xa8, 0xdd, 0x0d, 0x8e, 0xe6, 0xd4, 0xed,
- 0x42, 0x4d, 0xee, 0x14, 0x90, 0x05, 0x8d, 0x5d, 0x9e, 0xe7, 0xcf, 0x01,
- 0x44, 0xf3, 0x32, 0xce, 0x3b, 0x78, 0x59, 0x83, 0xe4, 0x2c, 0xe0, 0xd4,
- 0x74, 0xec, 0xcd, 0xc2, 0x74, 0x1a, 0x02, 0xbb, 0xe3, 0x11, 0x65, 0x0a,
- 0x7c, 0x3f, 0x84, 0x41, 0x7b, 0x9c, 0x4a, 0x1c, 0x5b, 0xd6, 0x1e, 0xdd,
- 0xb2, 0x8e, 0xe9, 0x55, 0x30, 0x15, 0x35, 0x08, 0x08, 0x0c, 0xea, 0x12,
- 0x92, 0xca, 0xfa, 0x90, 0x13, 0x6a, 0x70, 0x1b, 0xfe, 0x96, 0xf8, 0x4d,
- 0x46, 0x5d, 0xa8, 0x8c, 0x4f, 0xa1, 0x0a, 0x65, 0xa5, 0x22, 0xb1, 0xc9,
- 0xb4, 0x65, 0xbd, 0xa4, 0x39, 0x71, 0x8c, 0x64, 0x33, 0x98, 0xff, 0x5b,
- 0xab, 0x4c, 0x72, 0xd9, 0xa3, 0xcd, 0xaf, 0x2f, 0x63, 0x42, 0xb1, 0xac,
- 0x29, 0xba, 0xb7, 0x2f, 0x3f, 0x2f, 0x63, 0xcb, 0x92, 0x34, 0xcb, 0xba,
- 0x4b, 0xfb, 0x1b, 0x6b, 0xeb, 0xe7, 0xc6, 0xc6, 0xf0, 0xfd, 0x9c, 0x82,
- 0xa7, 0xb2, 0x49, 0xe4, 0xd3, 0x16, 0x1c, 0x86, 0x13, 0x7d, 0x43, 0x21,
- 0xec, 0x2c, 0x74, 0xa0, 0x90, 0x56, 0x53, 0xe7, 0xe9, 0xb9, 0xad, 0x71,
- 0x0d, 0xf7, 0x15, 0x3a, 0x31, 0x93, 0x86, 0xe5, 0x31, 0xb4, 0xb2, 0x47,
- 0x44, 0x71, 0x4f, 0xa1, 0x0b, 0xc5, 0xb4, 0x76, 0x76, 0x50, 0x44, 0x06,
- 0x1a, 0x1c, 0x4e, 0x3c, 0x50, 0x68, 0xc1, 0xfd, 0x85, 0x04, 0x3d, 0x63,
- 0xe1, 0xe6, 0x58, 0x23, 0x8d, 0x6f, 0xc5, 0x93, 0x63, 0x96, 0x15, 0x8d,
- 0x29, 0xe8, 0x2b, 0xe8, 0x98, 0xc9, 0x49, 0x48, 0x1d, 0x73, 0x22, 0x75,
- 0x14, 0xb8, 0xe7, 0x68, 0x2b, 0xa6, 0x72, 0x16, 0xb6, 0xea, 0x83, 0x0d,
- 0x12, 0x5c, 0x48, 0x29, 0x02, 0x2e, 0xcd, 0x8f, 0x6d, 0x4a, 0x85, 0xf6,
- 0xf3, 0x0e, 0x81, 0x1d, 0x47, 0xa3, 0xf8, 0x45, 0xda, 0xc4, 0xcd, 0xed,
- 0x41, 0x0c, 0x14, 0x02, 0x78, 0x23, 0x1d, 0xa0, 0x35, 0x74, 0xbc, 0x9e,
- 0x96, 0x69, 0x9d, 0x16, 0x9c, 0x49, 0xf3, 0x18, 0x1e, 0xeb, 0x43, 0x6f,
- 0xa1, 0x11, 0xe7, 0xd2, 0x41, 0x5a, 0x33, 0x80, 0x57, 0x68, 0xdc, 0xf6,
- 0x82, 0x86, 0xb3, 0x34, 0xae, 0xaf, 0x10, 0xc2, 0xcb, 0x69, 0x1f, 0xd1,
- 0x1a, 0xc0, 0xe9, 0x74, 0x3f, 0x76, 0xa7, 0x9b, 0xcf, 0xde, 0x48, 0x32,
- 0x0c, 0x2d, 0xe0, 0x75, 0xf8, 0xda, 0x5b, 0x56, 0x57, 0xc0, 0x36, 0x13,
- 0x5a, 0x67, 0x7e, 0xdd, 0x7e, 0x0c, 0xa6, 0xcf, 0xcc, 0xf9, 0x89, 0x8e,
- 0x03, 0xb9, 0x59, 0xeb, 0xa7, 0xcb, 0x1a, 0x71, 0x22, 0x0b, 0x3c, 0x39,
- 0x05, 0x4c, 0x65, 0x4d, 0xab, 0xc6, 0xb0, 0xac, 0xc9, 0xf6, 0x16, 0x92,
- 0x97, 0xd6, 0xb3, 0x95, 0x46, 0x3d, 0x55, 0x72, 0x02, 0x47, 0xd5, 0x9e,
- 0x32, 0x24, 0x4c, 0xcc, 0x38, 0xe1, 0x1e, 0x52, 0x3b, 0x27, 0xa0, 0x9e,
- 0xbd, 0x87, 0x3c, 0xe9, 0x58, 0x56, 0xed, 0x36, 0xb1, 0xcb, 0x0a, 0x1a,
- 0x4d, 0xa1, 0x16, 0x87, 0x05, 0x3f, 0xd9, 0x42, 0xba, 0xc5, 0xb2, 0x6a,
- 0x57, 0x5b, 0xd6, 0xb9, 0x76, 0x58, 0x92, 0xa1, 0x9d, 0x2d, 0x41, 0x2b,
- 0x7f, 0x00, 0x6d, 0xe0, 0x34, 0xca, 0x5f, 0xf5, 0x21, 0xd2, 0x17, 0x76,
- 0x44, 0xfa, 0x67, 0xe9, 0xd9, 0x9a, 0x02, 0x99, 0x32, 0xf1, 0xa2, 0x91,
- 0x0d, 0x16, 0x4a, 0x32, 0x9c, 0xc4, 0x4f, 0xcb, 0x90, 0x65, 0x39, 0x35,
- 0x1f, 0x7c, 0x24, 0xdf, 0x8d, 0x87, 0x2d, 0xeb, 0x1d, 0x5d, 0x81, 0x9b,
- 0x74, 0x73, 0xd3, 0xb0, 0x85, 0x49, 0xfd, 0x34, 0xc9, 0x53, 0x20, 0xd5,
- 0x1d, 0xa7, 0x67, 0x02, 0x34, 0x3e, 0x81, 0x8d, 0x43, 0x41, 0x7c, 0x3f,
- 0x2b, 0xe3, 0xa7, 0xcb, 0xa2, 0xa8, 0xa6, 0xb9, 0xbc, 0x24, 0xab, 0x2a,
- 0x92, 0x1f, 0x0a, 0x64, 0x6e, 0x85, 0x8a, 0x3d, 0xa2, 0x70, 0x9e, 0x78,
- 0x0c, 0xe2, 0x07, 0xa5, 0x00, 0x9e, 0x2e, 0x29, 0x38, 0x59, 0x6a, 0xc4,
- 0xa9, 0x92, 0x8e, 0x6c, 0x4e, 0xdd, 0x5f, 0x86, 0x85, 0x1a, 0x32, 0xe7,
- 0x37, 0x26, 0x62, 0xc8, 0xe4, 0x2c, 0x2b, 0x4f, 0x34, 0x7b, 0x89, 0x87,
- 0xd7, 0x27, 0xbe, 0x86, 0xe3, 0x63, 0x4e, 0x84, 0x26, 0x03, 0x78, 0x2a,
- 0xed, 0xc4, 0x75, 0x19, 0xd5, 0x9c, 0x80, 0x16, 0xdd, 0x29, 0xb4, 0xe4,
- 0x72, 0xa1, 0xe6, 0x4c, 0x44, 0x42, 0x2e, 0x21, 0xa1, 0xe9, 0xb8, 0x13,
- 0x5a, 0x31, 0x04, 0x57, 0x93, 0x0c, 0xad, 0x89, 0xdc, 0xc8, 0x2f, 0xc1,
- 0x4d, 0x7e, 0xb1, 0x71, 0x24, 0x4a, 0xd7, 0x02, 0x74, 0x0d, 0x5f, 0xab,
- 0x82, 0x63, 0x91, 0x03, 0x24, 0x37, 0xcd, 0x81, 0xa4, 0xd3, 0xb2, 0x1c,
- 0x5a, 0x2b, 0x7a, 0x1e, 0xa3, 0xcf, 0x36, 0x1e, 0xaf, 0x20, 0x5c, 0x24,
- 0x19, 0x34, 0x11, 0x4d, 0x59, 0xa2, 0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6,
- 0xac, 0x83, 0x6c, 0x46, 0xd5, 0x81, 0x3f, 0x22, 0x5d, 0x85, 0x88, 0xbf,
- 0x5f, 0xd8, 0x7a, 0x7a, 0xba, 0x14, 0x24, 0xfa, 0x43, 0x36, 0xfd, 0x4f,
- 0xe6, 0x04, 0x24, 0x4d, 0xed, 0x3e, 0x8f, 0x75, 0x08, 0xc7, 0xd4, 0xe4,
- 0x04, 0x92, 0xf4, 0x9c, 0xba, 0xdf, 0x84, 0xda, 0x59, 0x26, 0xfd, 0x6f,
- 0x55, 0x12, 0x98, 0xc9, 0xba, 0x50, 0xad, 0xa9, 0x21, 0xd2, 0x57, 0xb4,
- 0x8c, 0x05, 0xb8, 0x57, 0xa1, 0x39, 0x25, 0xb7, 0xa8, 0xc4, 0x90, 0x47,
- 0x10, 0x19, 0x91, 0x30, 0xad, 0x3b, 0xc8, 0x3f, 0x75, 0x38, 0x9a, 0x68,
- 0xb9, 0x62, 0x9c, 0x3e, 0x69, 0xfe, 0x2c, 0xad, 0x45, 0xf4, 0xd0, 0x7c,
- 0xe4, 0x97, 0x2c, 0xc7, 0x28, 0xd1, 0xb0, 0xd7, 0xa6, 0xf7, 0x64, 0xa9,
- 0x4b, 0x54, 0xec, 0xc7, 0x20, 0x7b, 0x51, 0x43, 0x10, 0x6a, 0x34, 0x24,
- 0x54, 0x3d, 0x29, 0x14, 0x4c, 0x95, 0x7e, 0x46, 0x63, 0x02, 0xd7, 0x8c,
- 0xe9, 0xc6, 0x60, 0x56, 0xe0, 0x46, 0xcd, 0xc2, 0x7a, 0xbd, 0x1b, 0xbb,
- 0x4b, 0xf3, 0x7e, 0xc9, 0xb1, 0x4b, 0xf1, 0x4f, 0xa5, 0x3b, 0xb0, 0x27,
- 0x1b, 0xc2, 0xee, 0x7c, 0xd0, 0x3f, 0x99, 0xe6, 0x7b, 0x1a, 0xf9, 0x3b,
- 0xdf, 0x0b, 0x5c, 0x73, 0xaf, 0xf1, 0x9a, 0x7b, 0x09, 0x0c, 0x8e, 0x7e,
- 0x85, 0x62, 0x48, 0x2d, 0x76, 0x6b, 0x1f, 0x91, 0xad, 0x68, 0x89, 0x5e,
- 0x34, 0xe0, 0xbc, 0xd2, 0x82, 0x43, 0xe3, 0x5d, 0xd8, 0x33, 0xbe, 0x02,
- 0x07, 0x46, 0x1b, 0x53, 0x5e, 0x63, 0x88, 0xd6, 0x0f, 0x27, 0x7b, 0x85,
- 0xda, 0xef, 0x10, 0xe1, 0x68, 0x2f, 0xd9, 0x6e, 0x53, 0x9d, 0x65, 0x9d,
- 0x8e, 0x91, 0x6d, 0xeb, 0xcd, 0xfa, 0x46, 0x12, 0x40, 0xb9, 0x5b, 0xed,
- 0x7c, 0x0b, 0x3e, 0xdc, 0x4a, 0x36, 0x37, 0x15, 0x43, 0xaf, 0x03, 0x8e,
- 0x16, 0x1f, 0x7e, 0x6d, 0x1d, 0x75, 0xb2, 0xdc, 0xad, 0x5d, 0x77, 0xe9,
- 0x7b, 0x05, 0xc7, 0x39, 0xf7, 0xd5, 0x58, 0xc2, 0xf3, 0xf3, 0x33, 0x96,
- 0x15, 0xa6, 0x79, 0xfa, 0x62, 0xcd, 0x89, 0x3e, 0xcc, 0x5a, 0xe7, 0xb7,
- 0x74, 0x61, 0xf7, 0xcc, 0x0a, 0x1c, 0x1c, 0x75, 0x21, 0x59, 0x27, 0x50,
- 0xab, 0x85, 0xcb, 0xf7, 0x62, 0x05, 0xcc, 0x29, 0x7e, 0xae, 0x0b, 0x47,
- 0x66, 0x2a, 0xbf, 0xb3, 0x57, 0x7f, 0xcf, 0xcf, 0x77, 0x91, 0x74, 0xca,
- 0xf2, 0xe4, 0x38, 0x49, 0x2a, 0x30, 0x9a, 0x71, 0x62, 0x34, 0x40, 0xba,
- 0xed, 0x10, 0xce, 0xe3, 0x8b, 0xfc, 0xde, 0xc7, 0x2c, 0xbc, 0xa4, 0x93,
- 0x9e, 0xb3, 0x1b, 0x84, 0xf7, 0x78, 0xa7, 0x70, 0x15, 0x37, 0x0b, 0xf7,
- 0xe4, 0xb7, 0x84, 0x7c, 0x3c, 0x25, 0xaa, 0x8a, 0x2d, 0x24, 0xfb, 0x1e,
- 0xe1, 0x39, 0xae, 0x86, 0x42, 0xe2, 0xbb, 0xa4, 0xcf, 0x2d, 0xc2, 0x51,
- 0x84, 0x22, 0x19, 0x03, 0x42, 0x2a, 0xd2, 0x1c, 0xb6, 0x0d, 0xf1, 0x3a,
- 0x41, 0xd2, 0x1b, 0x4c, 0x87, 0xd1, 0x8f, 0xad, 0x94, 0x23, 0x6e, 0x49,
- 0x1b, 0x38, 0x98, 0xad, 0xa2, 0xf8, 0xc8, 0x7e, 0x3f, 0x4b, 0xeb, 0x6a,
- 0x38, 0x54, 0x82, 0xe9, 0x31, 0x0e, 0x62, 0x05, 0xf9, 0xdb, 0xb9, 0x18,
- 0xfb, 0x22, 0x90, 0xcf, 0x86, 0x93, 0x07, 0x85, 0x65, 0x55, 0x45, 0xac,
- 0x25, 0xef, 0xe8, 0xcd, 0xd1, 0x33, 0xf8, 0x9f, 0xd6, 0x44, 0xa0, 0x1f,
- 0xd1, 0x76, 0xc8, 0x55, 0xc6, 0x1e, 0xbc, 0x9b, 0x86, 0xec, 0x36, 0x4c,
- 0xbc, 0x94, 0x06, 0x7c, 0x43, 0x83, 0x8a, 0x17, 0x64, 0x07, 0x08, 0x07,
- 0x0f, 0x09, 0xb5, 0xfb, 0x02, 0xa5, 0xb3, 0x44, 0xbb, 0x39, 0x20, 0x81,
- 0xe2, 0x91, 0x50, 0x7b, 0xce, 0x90, 0x3d, 0x7e, 0x57, 0xa8, 0xca, 0xac,
- 0x60, 0x3f, 0xe5, 0x5c, 0xb2, 0x67, 0x2e, 0xa7, 0x98, 0xb8, 0xee, 0x9a,
- 0x9c, 0x32, 0x48, 0x74, 0xed, 0x23, 0xba, 0x5e, 0xd4, 0xd5, 0xe0, 0x24,
- 0xac, 0x25, 0xbd, 0x3a, 0xdf, 0x33, 0xb0, 0xa7, 0x64, 0x85, 0x1c, 0x06,
- 0xcb, 0x0a, 0xa9, 0x2a, 0x03, 0xa6, 0x6c, 0x28, 0xe4, 0x1b, 0xbf, 0xb1,
- 0x7a, 0xe3, 0xb2, 0xfe, 0x76, 0x5e, 0x21, 0x79, 0xc1, 0xef, 0x2c, 0x7c,
- 0x59, 0xde, 0xb5, 0x20, 0x19, 0xbf, 0xb1, 0xee, 0x8c, 0xc3, 0xbf, 0xa4,
- 0xe0, 0x4c, 0x55, 0x1b, 0xe8, 0x1e, 0x18, 0xda, 0x65, 0x35, 0x68, 0x12,
- 0xc5, 0x29, 0x8d, 0xe2, 0xba, 0x2f, 0x71, 0xb9, 0xdd, 0x23, 0xce, 0xb5,
- 0x07, 0xbb, 0x3e, 0xc8, 0x7b, 0x48, 0xcf, 0xe8, 0xde, 0x59, 0x48, 0x38,
- 0xdf, 0x23, 0x5b, 0x73, 0x53, 0x4c, 0x45, 0xa1, 0xb1, 0xeb, 0x12, 0xe5,
- 0xa1, 0x9b, 0x62, 0x9e, 0x7f, 0xea, 0x36, 0xa4, 0xaf, 0x79, 0xf0, 0xe0,
- 0xca, 0xe9, 0x44, 0x2d, 0xc5, 0x75, 0x05, 0x67, 0xe3, 0x9d, 0x18, 0x2c,
- 0x55, 0x91, 0x1d, 0x3e, 0x53, 0xde, 0xab, 0x35, 0x76, 0xbd, 0x9f, 0x5e,
- 0xc2, 0x71, 0xe4, 0xd3, 0x7c, 0xbb, 0xd6, 0xbd, 0x53, 0x9c, 0xde, 0xe4,
- 0x45, 0x1c, 0x07, 0x4a, 0xb2, 0xfc, 0x49, 0x1a, 0x1f, 0x2d, 0xd1, 0xb4,
- 0xf2, 0x3a, 0x47, 0x53, 0xbf, 0xec, 0x68, 0x1a, 0x70, 0x53, 0x0c, 0xbe,
- 0x78, 0xbd, 0xc0, 0x4b, 0xd7, 0x47, 0x12, 0x6e, 0xe1, 0xc1, 0xf9, 0xee,
- 0x04, 0xd9, 0x49, 0x63, 0xca, 0x63, 0x50, 0xfc, 0x20, 0x93, 0x75, 0x68,
- 0x09, 0xec, 0x9e, 0xc2, 0x23, 0x83, 0x7a, 0x17, 0xcc, 0x19, 0xb6, 0xa1,
- 0x16, 0x0c, 0xce, 0x74, 0xc3, 0x2c, 0x39, 0x30, 0x11, 0x20, 0xe6, 0x4b,
- 0x48, 0xb9, 0x8c, 0x96, 0x8e, 0x89, 0x7c, 0xaf, 0xab, 0xe2, 0xc3, 0xc4,
- 0x7f, 0xf6, 0xa8, 0x1f, 0x5e, 0xd6, 0xf3, 0x59, 0x92, 0x51, 0x0b, 0x9e,
- 0x29, 0x45, 0x29, 0xd6, 0xe9, 0x24, 0x17, 0x8d, 0xe2, 0x45, 0x88, 0xec,
- 0x4b, 0xc6, 0xd6, 0x51, 0xf5, 0x08, 0xc5, 0x85, 0xdc, 0x04, 0xda, 0x91,
- 0x0c, 0x28, 0x94, 0xbb, 0x5f, 0x9a, 0x8b, 0x01, 0xdb, 0xe8, 0x53, 0x35,
- 0x93, 0xc0, 0x19, 0x09, 0x68, 0x6d, 0x30, 0x22, 0xfb, 0x1b, 0x48, 0x1f,
- 0x75, 0x45, 0x0f, 0x1e, 0x18, 0xad, 0xc7, 0xfd, 0xe3, 0x5e, 0xec, 0x18,
- 0xb5, 0x70, 0x39, 0xc6, 0xb6, 0xa1, 0xf6, 0x10, 0x89, 0x1d, 0xd5, 0x24,
- 0xd7, 0x4d, 0xb1, 0x48, 0xc2, 0x23, 0x9c, 0xa8, 0x2a, 0x76, 0x13, 0x06,
- 0x48, 0xb2, 0x5f, 0xe8, 0x34, 0x47, 0x68, 0xb7, 0x7e, 0x2b, 0x52, 0x01,
- 0x19, 0xae, 0xa2, 0x8f, 0x62, 0x09, 0xfb, 0x31, 0xdf, 0xfb, 0x06, 0xb6,
- 0xba, 0x7d, 0x70, 0x64, 0x64, 0xe4, 0x28, 0xff, 0x63, 0x91, 0x1b, 0x9d,
- 0x4d, 0x12, 0xfd, 0x07, 0xfc, 0xd3, 0x63, 0x8d, 0xfe, 0x63, 0x14, 0x5f,
- 0xef, 0xc9, 0x4a, 0xbc, 0x0e, 0xe3, 0x05, 0x9a, 0x5b, 0xc1, 0x93, 0x14,
- 0xab, 0x1f, 0xa2, 0xf8, 0x73, 0xa2, 0x94, 0x17, 0x1c, 0x4f, 0x6c, 0x7e,
- 0xb2, 0xc4, 0x5b, 0x96, 0x78, 0xcb, 0x12, 0x5f, 0x14, 0x17, 0x4e, 0x66,
- 0x99, 0x8f, 0x2b, 0xe4, 0xa3, 0x09, 0xe2, 0xdd, 0x83, 0x6d, 0x44, 0xef,
- 0x83, 0xe3, 0xd5, 0xb8, 0x8f, 0xe8, 0x2d, 0xea, 0x6a, 0xcf, 0x9f, 0x0b,
- 0x0b, 0xf9, 0x98, 0x6a, 0xee, 0x14, 0x5e, 0x48, 0x4d, 0x96, 0xd5, 0xad,
- 0x33, 0xcf, 0x64, 0xa7, 0x92, 0xcd, 0xf3, 0xfe, 0x24, 0x3c, 0xe8, 0xa3,
- 0x67, 0x7a, 0xc7, 0xf1, 0xa9, 0x44, 0x3c, 0x79, 0x88, 0xc7, 0x83, 0xba,
- 0x9a, 0x58, 0x4e, 0x71, 0xfd, 0x82, 0x16, 0x29, 0x5f, 0x70, 0xe0, 0xeb,
- 0x24, 0x0f, 0x9d, 0xe5, 0xd1, 0x44, 0xfc, 0x3c, 0x40, 0x58, 0xc7, 0x6f,
- 0x30, 0x9f, 0x91, 0xe8, 0xaf, 0x89, 0xf7, 0x48, 0x31, 0xe0, 0x3f, 0x77,
- 0xb8, 0xd1, 0xff, 0xe2, 0x50, 0x85, 0xfe, 0x9d, 0x44, 0xff, 0x74, 0xcc,
- 0xc2, 0x21, 0xa2, 0xff, 0x29, 0xa2, 0xbf, 0x8f, 0xe3, 0xf9, 0x1c, 0xfd,
- 0x27, 0x4a, 0xbc, 0xee, 0x97, 0xf1, 0x30, 0x4f, 0x7f, 0x3d, 0xb6, 0x8e,
- 0xcf, 0xcb, 0xcb, 0xb2, 0xee, 0xd4, 0x9f, 0xb5, 0xbe, 0x4d, 0x32, 0x5b,
- 0x52, 0x64, 0xb9, 0x31, 0x8e, 0x8b, 0x1c, 0xb9, 0x07, 0x7d, 0x12, 0xbc,
- 0x3e, 0x2c, 0x28, 0x72, 0x2e, 0x08, 0xe1, 0x59, 0xd2, 0xef, 0x29, 0xca,
- 0x65, 0xcf, 0x94, 0xae, 0xcd, 0x6d, 0xac, 0xeb, 0x31, 0xd2, 0xb1, 0x3a,
- 0x61, 0x52, 0x6c, 0x4b, 0x95, 0x92, 0xd8, 0x3b, 0x8e, 0xe4, 0xb4, 0xfe,
- 0xaf, 0x29, 0xc0, 0x2c, 0x22, 0xfb, 0xaa, 0x4a, 0x2a, 0x9a, 0x17, 0x77,
- 0x4d, 0x05, 0xd0, 0x5f, 0x5a, 0x8f, 0x2c, 0xc5, 0x9b, 0x9d, 0x14, 0x9f,
- 0x3f, 0x8c, 0x25, 0x77, 0xf8, 0x11, 0x21, 0xfd, 0x06, 0x70, 0x2f, 0x3d,
- 0x73, 0x70, 0x9c, 0xe9, 0x57, 0xe6, 0xf4, 0x1c, 0xc0, 0x3d, 0x74, 0x6d,
- 0xdf, 0xb8, 0x8c, 0x17, 0xf4, 0x27, 0x08, 0xcf, 0x54, 0xf0, 0xc5, 0xdd,
- 0x59, 0x28, 0xe4, 0x9e, 0x84, 0xff, 0x22, 0xd1, 0x17, 0xe8, 0xf7, 0xb6,
- 0x92, 0xd7, 0x3f, 0x38, 0x86, 0xef, 0x2d, 0x31, 0xfc, 0x58, 0x40, 0x58,
- 0xec, 0x76, 0x3d, 0x42, 0x76, 0xef, 0xc4, 0x40, 0x49, 0xc2, 0x77, 0xa6,
- 0xbc, 0x78, 0x68, 0xf4, 0x53, 0xcb, 0x1d, 0x77, 0xe2, 0xb6, 0x26, 0x2f,
- 0x1e, 0x9c, 0x4a, 0x62, 0xff, 0x38, 0x42, 0x55, 0xb1, 0x61, 0x8a, 0xdd,
- 0x95, 0x7c, 0x50, 0x4d, 0xbc, 0x1f, 0x18, 0xf7, 0xf9, 0xfb, 0x0e, 0xb3,
- 0x0c, 0xd6, 0x07, 0x3d, 0x40, 0xb9, 0x2a, 0xe6, 0xc0, 0x36, 0xdd, 0xb1,
- 0xa0, 0x8a, 0x0c, 0xfd, 0x09, 0x9a, 0x6f, 0x12, 0x8e, 0x57, 0x97, 0x20,
- 0x72, 0xa4, 0xc1, 0x51, 0xce, 0x2d, 0x40, 0x3d, 0x1e, 0x9a, 0x49, 0x62,
- 0x98, 0x6c, 0xf4, 0x81, 0xd1, 0xc1, 0xef, 0xd5, 0x51, 0x0c, 0xf1, 0xb7,
- 0xaa, 0x7d, 0x6f, 0x08, 0x03, 0xf9, 0x88, 0x07, 0x3b, 0xa7, 0x7c, 0xfe,
- 0x1d, 0x87, 0xad, 0x75, 0x6c, 0x4f, 0xdb, 0x67, 0xea, 0x71, 0xdf, 0x38,
- 0x5d, 0x1b, 0x65, 0x1b, 0x26, 0x5b, 0x8b, 0x54, 0x11, 0x6f, 0xe1, 0xa4,
- 0x87, 0xf0, 0x92, 0x23, 0x56, 0x4d, 0xf2, 0xf0, 0xe0, 0x1e, 0xdb, 0x16,
- 0x14, 0x6c, 0x1b, 0xb7, 0xf0, 0xa6, 0x1e, 0x45, 0x8e, 0xec, 0xfa, 0xc8,
- 0xb8, 0x3a, 0xdb, 0x41, 0x58, 0xe7, 0x6d, 0x87, 0x7a, 0xa4, 0xc9, 0x91,
- 0x44, 0x7d, 0x1b, 0xc5, 0xf8, 0x7a, 0xcb, 0xba, 0xbb, 0xb5, 0xb9, 0xff,
- 0xe7, 0x44, 0x73, 0x9d, 0xb1, 0x08, 0xe5, 0x3a, 0x35, 0x07, 0x34, 0x0f,
- 0xb8, 0xa5, 0xeb, 0x71, 0x7e, 0x21, 0xc7, 0x41, 0x8e, 0xe5, 0x01, 0x7f,
- 0x7d, 0xa6, 0x92, 0xe3, 0xea, 0x8b, 0x8d, 0xfe, 0xba, 0x4c, 0xd0, 0x5f,
- 0x57, 0x84, 0xdf, 0x5d, 0x04, 0x7e, 0x4c, 0xf1, 0x65, 0x41, 0xdb, 0x6f,
- 0xac, 0x54, 0xbd, 0x8d, 0x07, 0xfd, 0xcf, 0x8f, 0xa9, 0x66, 0x19, 0xea,
- 0x7e, 0x0a, 0x9b, 0x78, 0x7c, 0xc6, 0xe9, 0x3f, 0x4e, 0xd8, 0xaf, 0x5e,
- 0x8b, 0x62, 0x1f, 0xe9, 0x73, 0x17, 0xd9, 0xc2, 0xaf, 0xdb, 0x80, 0x03,
- 0x99, 0x70, 0x48, 0x17, 0x3d, 0x34, 0x31, 0xb0, 0xa7, 0x48, 0x31, 0x5f,
- 0x4a, 0x52, 0x10, 0x53, 0xa3, 0x94, 0xd6, 0x90, 0xce, 0xb8, 0x60, 0x2e,
- 0xac, 0xe8, 0xe4, 0xbe, 0xec, 0x29, 0xcb, 0xaf, 0x69, 0x13, 0x45, 0xd2,
- 0xd9, 0xc3, 0x25, 0x1f, 0x06, 0x08, 0x0f, 0x2c, 0x20, 0x0c, 0xf9, 0x20,
- 0xd9, 0xc5, 0x03, 0xa3, 0x0e, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x54,
- 0xc1, 0xa2, 0x0f, 0x4d, 0xb1, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x4b,
- 0x39, 0xff, 0x99, 0xcf, 0x61, 0x10, 0x55, 0x31, 0xaf, 0xe6, 0xfe, 0x8a,
- 0x3c, 0x06, 0xc7, 0x99, 0x67, 0xf5, 0x08, 0xa4, 0x24, 0x6e, 0xd2, 0x7f,
- 0x49, 0x39, 0x81, 0x79, 0x27, 0x0c, 0x3c, 0x1e, 0xc5, 0xa3, 0x59, 0xc2,
- 0x34, 0xb1, 0xcb, 0xd6, 0x3d, 0x01, 0x96, 0x01, 0xf3, 0xb3, 0xca, 0xc1,
- 0xf9, 0xb3, 0x9e, 0xb0, 0xef, 0xff, 0xbb, 0xdd, 0xdd, 0x65, 0xa5, 0x6c,
- 0x2c, 0x4b, 0x18, 0x9b, 0xec, 0x29, 0x75, 0xd5, 0x7e, 0x1e, 0xb4, 0xce,
- 0x07, 0x38, 0x5f, 0xd7, 0x23, 0x75, 0xd5, 0x16, 0xd8, 0x96, 0xb0, 0x44,
- 0x6f, 0xdd, 0xfd, 0xa0, 0x02, 0xb6, 0x87, 0xe8, 0x35, 0xf6, 0x50, 0x45,
- 0x34, 0x29, 0xd8, 0x31, 0xc3, 0xf6, 0x6b, 0x5d, 0x59, 0x62, 0xfc, 0xd6,
- 0xfa, 0x64, 0xb5, 0x76, 0xe4, 0x97, 0xe8, 0xa2, 0xeb, 0x01, 0x7c, 0x87,
- 0xfc, 0xe8, 0x5e, 0xe2, 0x73, 0x47, 0xfb, 0xbd, 0xb6, 0xdf, 0xee, 0x28,
- 0xad, 0xa1, 0xeb, 0x2c, 0xef, 0x0e, 0xec, 0xcf, 0xea, 0x48, 0x67, 0xcb,
- 0x9c, 0x87, 0xc8, 0xe6, 0xe3, 0xf8, 0x11, 0xc5, 0xd9, 0x67, 0x4b, 0x8c,
- 0xc9, 0x12, 0x36, 0x1e, 0xfb, 0x61, 0xa9, 0x05, 0xcf, 0x91, 0x4f, 0x3e,
- 0x43, 0x31, 0xf7, 0x07, 0x36, 0x4e, 0x73, 0x8a, 0x43, 0x69, 0xc2, 0xa4,
- 0x43, 0x26, 0xd2, 0xf9, 0x10, 0x3c, 0x87, 0xc3, 0xfb, 0x77, 0x08, 0xf5,
- 0xc7, 0x24, 0x2f, 0xff, 0x81, 0xe9, 0xa5, 0xa8, 0x3a, 0xac, 0x4e, 0x10,
- 0xdd, 0xfe, 0x47, 0xa7, 0x35, 0xc2, 0xd4, 0x41, 0xff, 0xbe, 0xbc, 0xe2,
- 0xdf, 0x3b, 0x16, 0xf0, 0xef, 0x9d, 0xae, 0x27, 0x3f, 0x5a, 0xe4, 0x1f,
- 0x9c, 0x0e, 0xfa, 0x77, 0xa7, 0x1b, 0xfd, 0xbb, 0xf3, 0x6d, 0x08, 0xd5,
- 0xc3, 0x5c, 0x44, 0x39, 0xe2, 0xbe, 0xd1, 0x6f, 0x62, 0xa2, 0xae, 0x12,
- 0xf7, 0xfb, 0xc9, 0x36, 0x6a, 0xc9, 0x0e, 0x57, 0x4a, 0xb7, 0xa1, 0xbc,
- 0xb0, 0x72, 0xed, 0x3b, 0x74, 0xed, 0xa1, 0x56, 0xf8, 0xff, 0xc2, 0x8e,
- 0xbd, 0xc0, 0x73, 0x64, 0x6b, 0xcf, 0xb6, 0x52, 0x5d, 0x79, 0xd5, 0xd6,
- 0x9c, 0x14, 0x6f, 0x2d, 0x4b, 0x6f, 0x13, 0x08, 0xb6, 0x6e, 0x00, 0x16,
- 0xcc, 0xd7, 0x92, 0xc9, 0x09, 0x67, 0x6b, 0x12, 0x4b, 0xb4, 0x8d, 0x78,
- 0x42, 0xa1, 0x54, 0xd3, 0xfa, 0x75, 0xcc, 0x3d, 0x83, 0xef, 0x8c, 0x7a,
- 0x90, 0xda, 0xac, 0x60, 0x9a, 0xb0, 0xca, 0x76, 0x9a, 0x7f, 0x59, 0xac,
- 0x59, 0x99, 0x21, 0x3d, 0x24, 0x15, 0xbe, 0x46, 0x3e, 0xd1, 0xba, 0x8a,
- 0x7c, 0xa2, 0xb2, 0xfe, 0xd3, 0xa4, 0xaf, 0xdc, 0x4c, 0x14, 0x7b, 0x4b,
- 0x3f, 0x91, 0x2a, 0xf9, 0x45, 0x9d, 0x48, 0xe2, 0xac, 0x3d, 0xf6, 0xe9,
- 0xec, 0x1b, 0x56, 0xc8, 0xb6, 0x3b, 0x81, 0xc7, 0x56, 0x44, 0xf6, 0xff,
- 0x27, 0xa9, 0x81, 0xf8, 0x22, 0xd9, 0x65, 0xed, 0x3a, 0xb2, 0x76, 0xb1,
- 0xf6, 0x2f, 0xf0, 0x23, 0x85, 0x65, 0x3b, 0x20, 0xf6, 0x53, 0xbd, 0x4a,
- 0xa5, 0x53, 0xed, 0x02, 0xed, 0x30, 0x9e, 0xe9, 0xe6, 0x6b, 0x01, 0xff,
- 0x81, 0xb1, 0xa4, 0x14, 0xd0, 0xa0, 0xb8, 0x8c, 0x0e, 0x71, 0x60, 0x7a,
- 0x91, 0xff, 0xd1, 0xb1, 0x0d, 0xe2, 0xd1, 0xe9, 0x46, 0xff, 0x60, 0xba,
- 0x53, 0x0c, 0xe6, 0x37, 0x0b, 0x73, 0xe2, 0x5b, 0xc2, 0x9c, 0x4e, 0x09,
- 0x33, 0xdf, 0x43, 0x9f, 0x5b, 0xc4, 0x58, 0x7e, 0x40, 0xec, 0xcd, 0xf3,
- 0xfc, 0xa4, 0x2b, 0x5a, 0xe3, 0x87, 0x14, 0x7b, 0x9f, 0xa3, 0xd8, 0xfb,
- 0x2c, 0xc5, 0xde, 0x67, 0xc8, 0xde, 0x7f, 0x70, 0x15, 0xe3, 0xb2, 0x8d,
- 0x27, 0x19, 0x9b, 0xf8, 0xff, 0xbc, 0x78, 0x86, 0xf4, 0xcd, 0xb2, 0xfb,
- 0x37, 0x64, 0xdb, 0x2c, 0x93, 0x87, 0x38, 0x57, 0x90, 0x9e, 0xde, 0xb7,
- 0x6d, 0xf9, 0xb1, 0x15, 0x8c, 0xa5, 0x06, 0xc4, 0x56, 0xa2, 0x2f, 0xe9,
- 0x24, 0x0c, 0xa4, 0x11, 0x3e, 0xc9, 0x0e, 0x88, 0xbb, 0xf3, 0x7c, 0xfd,
- 0x20, 0x76, 0x52, 0x4d, 0x78, 0x28, 0x16, 0xee, 0xee, 0x25, 0xec, 0xb4,
- 0x89, 0xb0, 0xd3, 0xb2, 0x98, 0x8c, 0x8b, 0x2d, 0x9f, 0x58, 0x58, 0x88,
- 0xe4, 0xfd, 0x71, 0x75, 0x62, 0xa2, 0x92, 0x6f, 0x73, 0x19, 0x70, 0xdd,
- 0x8e, 0xda, 0x1a, 0x4d, 0x3d, 0x91, 0x44, 0x78, 0x7f, 0x5c, 0x82, 0xe9,
- 0x36, 0x5c, 0xb8, 0xcf, 0xae, 0x15, 0xd7, 0x63, 0x74, 0x54, 0x60, 0x5b,
- 0x6b, 0xf2, 0x8f, 0x5c, 0x24, 0xab, 0xb7, 0xdb, 0x11, 0x20, 0xf5, 0x0a,
- 0x99, 0xea, 0xfa, 0x4e, 0x92, 0x5e, 0x07, 0xe5, 0xdc, 0x27, 0xb2, 0xab,
- 0xd0, 0xd0, 0x2a, 0x93, 0x0e, 0x9d, 0xb8, 0xb3, 0x78, 0x13, 0xe9, 0x31,
- 0x72, 0xe4, 0x79, 0x78, 0xfd, 0x2f, 0x8c, 0x19, 0x18, 0xca, 0xe2, 0x7b,
- 0x3e, 0xaa, 0xe1, 0xee, 0x25, 0xfc, 0xf4, 0x03, 0xa2, 0x61, 0x63, 0x6b,
- 0xa4, 0x93, 0x6a, 0x79, 0xc5, 0x6b, 0xb8, 0x31, 0xd2, 0xe4, 0x87, 0xa2,
- 0xa5, 0xc4, 0x2b, 0xf9, 0xc8, 0x91, 0x1d, 0xd2, 0xb7, 0xc4, 0xcf, 0xa7,
- 0x0d, 0x3c, 0x5a, 0xea, 0x11, 0x7f, 0x31, 0x2d, 0x83, 0x74, 0x43, 0x71,
- 0x4b, 0xc7, 0x11, 0xa2, 0xcb, 0x45, 0x18, 0xc9, 0xf5, 0xfb, 0x02, 0x8b,
- 0xb5, 0x24, 0xbe, 0xb3, 0x8a, 0x7d, 0xa1, 0x12, 0xd3, 0x9c, 0xab, 0x80,
- 0xfd, 0x64, 0x93, 0x0d, 0x99, 0x0e, 0xb1, 0x84, 0xbe, 0x5f, 0xa4, 0xbc,
- 0x96, 0x94, 0x3a, 0x45, 0x03, 0x61, 0xd3, 0x85, 0x93, 0x5b, 0xc4, 0x82,
- 0x22, 0x63, 0x51, 0x28, 0x0b, 0x49, 0x46, 0x0b, 0x8b, 0x17, 0x1d, 0x95,
- 0x1a, 0xc0, 0xc5, 0xb6, 0x64, 0xfa, 0x0c, 0xd9, 0x7f, 0x88, 0x62, 0xfb,
- 0x8e, 0x58, 0x27, 0xe1, 0x64, 0xbe, 0x3e, 0x20, 0x86, 0x48, 0x8e, 0x13,
- 0x2e, 0xdb, 0x76, 0xfc, 0x4f, 0x8c, 0xc1, 0xd5, 0x60, 0x20, 0xe4, 0xa6,
- 0xdc, 0xf1, 0xdf, 0xdb, 0x22, 0xe6, 0xf3, 0x52, 0x97, 0xc8, 0xe5, 0x03,
- 0xfe, 0x23, 0x63, 0x9c, 0x67, 0x3a, 0xc4, 0x11, 0xd2, 0x79, 0x96, 0x74,
- 0x9e, 0x25, 0x9d, 0x67, 0x48, 0xe7, 0x99, 0x2f, 0xd1, 0xf9, 0x3e, 0xd2,
- 0xf9, 0xee, 0xfc, 0xaf, 0x6c, 0x1d, 0x3a, 0x0d, 0x03, 0x59, 0xca, 0xcb,
- 0x23, 0x4d, 0x15, 0xfe, 0x3e, 0x24, 0x59, 0xbc, 0x14, 0xfb, 0x86, 0x13,
- 0x5e, 0x83, 0x62, 0x6b, 0x17, 0x3d, 0xf3, 0x95, 0x39, 0x1b, 0x57, 0xfc,
- 0xc3, 0x63, 0x1d, 0x62, 0x98, 0xfc, 0x6e, 0x84, 0xe6, 0x1f, 0x21, 0xbf,
- 0x1b, 0x4c, 0xff, 0x9f, 0xd8, 0x0d, 0xdb, 0x1d, 0x4c, 0x2f, 0xe5, 0xad,
- 0x6a, 0xb2, 0x4b, 0xa7, 0xc1, 0x36, 0xb4, 0x59, 0x24, 0x8f, 0x7e, 0x4b,
- 0x24, 0x8f, 0xa5, 0x44, 0xb2, 0xd0, 0x43, 0x9f, 0x5b, 0xc4, 0x2d, 0x76,
- 0x1d, 0x3a, 0x20, 0x3a, 0x0a, 0x01, 0xff, 0x38, 0xad, 0x33, 0x4e, 0x7c,
- 0x3c, 0x46, 0xeb, 0x3c, 0x66, 0xdb, 0x2e, 0x15, 0x99, 0x5e, 0x5e, 0x8b,
- 0xed, 0x8c, 0xed, 0xeb, 0x32, 0xd1, 0xce, 0xbe, 0x71, 0xb5, 0xc7, 0x43,
- 0x7f, 0x37, 0x38, 0xa0, 0xed, 0x74, 0x56, 0x78, 0xe2, 0xdc, 0xcf, 0xb9,
- 0x9e, 0xe3, 0xb0, 0x62, 0xd7, 0x82, 0xcf, 0x5e, 0xc5, 0x00, 0x8c, 0x07,
- 0x20, 0x2f, 0x30, 0xb6, 0x18, 0xdf, 0x69, 0xfa, 0x1f, 0x34, 0x5f, 0x3f,
- 0xf4, 0x55, 0x90, 0x03, 0xc6, 0x5f, 0x1a, 0x63, 0x4d, 0x14, 0xa7, 0x69,
- 0x4e, 0x39, 0x03, 0x68, 0x19, 0x81, 0xdd, 0x09, 0x41, 0x38, 0x76, 0x11,
- 0xf9, 0x25, 0xd3, 0xaf, 0x76, 0x52, 0x36, 0xc1, 0xd2, 0x21, 0xc8, 0x4b,
- 0x8c, 0x9d, 0xb0, 0xb2, 0x90, 0x6b, 0x8d, 0x3e, 0x5c, 0x19, 0x0a, 0x07,
- 0x3b, 0xa1, 0xa6, 0x2e, 0x38, 0xd4, 0x32, 0xe5, 0xb7, 0xfe, 0xdd, 0x42,
- 0xed, 0x9b, 0x15, 0xdc, 0x27, 0x62, 0xec, 0xbe, 0x13, 0x2d, 0x36, 0x86,
- 0xef, 0x43, 0x73, 0x1e, 0x54, 0x87, 0x0b, 0xbc, 0x43, 0x73, 0xbe, 0xa8,
- 0x7f, 0xc0, 0x39, 0x21, 0x49, 0x58, 0xf0, 0x0b, 0x73, 0x81, 0x70, 0x0c,
- 0xcf, 0xc3, 0x73, 0x84, 0x95, 0x3e, 0x9a, 0xf7, 0x4d, 0x47, 0x73, 0xff,
- 0xa0, 0x50, 0x13, 0x5f, 0x9c, 0x6f, 0x59, 0x1e, 0x62, 0x59, 0xc6, 0xb4,
- 0xaa, 0x35, 0x2f, 0xe3, 0x21, 0xe9, 0x1d, 0x4d, 0x4b, 0xbe, 0x86, 0x10,
- 0x96, 0x51, 0x9d, 0x1c, 0x2d, 0x32, 0x0f, 0xbb, 0x70, 0x46, 0x57, 0xbb,
- 0xa9, 0x1a, 0xa5, 0xba, 0xa5, 0x03, 0x07, 0x29, 0xf6, 0x3e, 0x5a, 0xe2,
- 0x3e, 0xd7, 0x80, 0x58, 0x3e, 0x44, 0x7e, 0x69, 0xdb, 0x13, 0xe4, 0x06,
- 0xe3, 0x61, 0xdc, 0x40, 0xeb, 0xfb, 0xa9, 0xf6, 0x79, 0x9d, 0xd6, 0x97,
- 0x32, 0xea, 0x00, 0xad, 0x9f, 0x7a, 0x43, 0x84, 0x67, 0x89, 0xaf, 0x9e,
- 0x75, 0x8e, 0xe6, 0xbe, 0x5d, 0x42, 0x4d, 0x12, 0xe9, 0xe4, 0xc7, 0xbc,
- 0xf6, 0xc3, 0xcc, 0x0b, 0x7d, 0x52, 0x9d, 0x43, 0x76, 0xd4, 0x54, 0x90,
- 0x45, 0x64, 0x78, 0x3d, 0xf6, 0x4e, 0xad, 0xc7, 0x1e, 0xf2, 0xc7, 0x03,
- 0x7a, 0x2d, 0x42, 0x75, 0xa8, 0xa9, 0xd5, 0x30, 0x7b, 0x41, 0x13, 0x8e,
- 0x1d, 0x2d, 0x8d, 0x64, 0xc7, 0xa7, 0x1b, 0xaa, 0xf0, 0x91, 0xd5, 0xab,
- 0xad, 0xef, 0xa4, 0x88, 0x78, 0x83, 0x07, 0xe3, 0x0e, 0xf2, 0xef, 0x5f,
- 0xfc, 0x9a, 0x02, 0xaa, 0xc7, 0x60, 0xdc, 0x96, 0x10, 0x97, 0xf2, 0x67,
- 0x9d, 0x15, 0x3f, 0x68, 0xc2, 0x15, 0x05, 0xb5, 0x41, 0x6d, 0x39, 0x66,
- 0x15, 0x99, 0xe2, 0x85, 0x69, 0xd7, 0x64, 0x37, 0xe7, 0xba, 0xd1, 0x40,
- 0xf5, 0xf1, 0x9d, 0xb1, 0x5f, 0x5b, 0x9f, 0x2c, 0xe6, 0xe7, 0x4e, 0x7a,
- 0x2a, 0xb1, 0xf3, 0xcb, 0xe6, 0x88, 0x53, 0xbc, 0x69, 0xa6, 0x7a, 0xb6,
- 0x9a, 0x82, 0x74, 0x27, 0xe5, 0x23, 0xb5, 0x27, 0x4d, 0xf5, 0x68, 0x5f,
- 0xa4, 0x59, 0x77, 0x08, 0x37, 0xca, 0x81, 0x70, 0x7f, 0x2f, 0x92, 0xdb,
- 0xfd, 0x73, 0x74, 0x3c, 0x2b, 0x34, 0x17, 0x3d, 0xc7, 0xf3, 0x5c, 0x63,
- 0x4f, 0x27, 0xc9, 0x9e, 0xf8, 0x3e, 0x7f, 0xbf, 0x7a, 0x5f, 0xfe, 0x8a,
- 0xf1, 0x97, 0xff, 0xe4, 0x8f, 0x97, 0x7d, 0xd9, 0xf5, 0x8f, 0xbf, 0xe4,
- 0xfa, 0xff, 0xae, 0xae, 0x2f, 0xd7, 0x39, 0x6d, 0xcc, 0x90, 0x94, 0xb8,
- 0x8f, 0xe9, 0x34, 0x2e, 0xaf, 0xd9, 0xa3, 0xfd, 0x0e, 0xc5, 0x34, 0xee,
- 0x63, 0x70, 0x9e, 0x3e, 0x6f, 0xf7, 0x31, 0x4e, 0x7d, 0x0e, 0xb3, 0x72,
- 0x6c, 0xf1, 0x88, 0xea, 0x11, 0xd3, 0xaa, 0xd7, 0xbe, 0x4d, 0x75, 0xcd,
- 0x2e, 0xf4, 0xc6, 0x74, 0x0c, 0x67, 0xd5, 0xee, 0xdb, 0xa0, 0x25, 0x37,
- 0x0b, 0x9a, 0xa8, 0xe8, 0x11, 0x8e, 0x91, 0xb9, 0x7b, 0xba, 0x49, 0xb5,
- 0x5a, 0x19, 0x55, 0x14, 0x9b, 0x9c, 0x9a, 0x22, 0xa3, 0x18, 0x90, 0x9d,
- 0xc5, 0xa0, 0xec, 0x2e, 0x36, 0xca, 0x55, 0x34, 0xce, 0x37, 0xa2, 0xce,
- 0xde, 0x86, 0x5d, 0x98, 0x6d, 0xf3, 0x9a, 0x0d, 0x86, 0xaa, 0x34, 0x38,
- 0x76, 0x61, 0x4f, 0x8c, 0x9f, 0xed, 0xa0, 0x9a, 0x0d, 0xa2, 0x2e, 0x43,
- 0xc8, 0xd8, 0x10, 0xd8, 0xdb, 0xae, 0x0e, 0x2c, 0x95, 0xb4, 0xce, 0x5f,
- 0x09, 0xa7, 0xec, 0x29, 0x42, 0xf8, 0x33, 0x12, 0x8e, 0xb4, 0xc3, 0xe3,
- 0x59, 0xa5, 0xf6, 0x9d, 0x16, 0x03, 0x78, 0x2a, 0x16, 0xe9, 0xde, 0x26,
- 0x42, 0xb2, 0x97, 0xee, 0xb9, 0x32, 0x14, 0x7f, 0x33, 0xa6, 0xc7, 0xb5,
- 0x4a, 0x0d, 0x4a, 0x22, 0x89, 0x5e, 0x4d, 0xd3, 0x47, 0x20, 0xd3, 0x9a,
- 0x10, 0x55, 0x19, 0x75, 0xf6, 0x4d, 0xc2, 0x54, 0x9f, 0x2c, 0x1b, 0x40,
- 0x6b, 0x5b, 0x64, 0x7f, 0x8f, 0xa4, 0xc9, 0x84, 0xf5, 0x84, 0x33, 0xe3,
- 0xc3, 0xca, 0xc3, 0xf3, 0x7d, 0x1d, 0xcb, 0xfa, 0x30, 0x56, 0x26, 0xbd,
- 0x40, 0xae, 0x29, 0x46, 0x65, 0x1f, 0xe1, 0xfa, 0xe6, 0xc3, 0x8c, 0xb3,
- 0x2c, 0x6b, 0x47, 0xac, 0xfc, 0x75, 0x2f, 0x5a, 0x88, 0xc7, 0x6e, 0x4c,
- 0xa5, 0x19, 0x77, 0x19, 0x98, 0xa4, 0x9a, 0x48, 0x1b, 0x6a, 0xc4, 0x71,
- 0x8a, 0x43, 0x33, 0x69, 0xee, 0xff, 0xf4, 0x91, 0x8c, 0x7b, 0x88, 0xfe,
- 0x2d, 0x54, 0x0f, 0xa7, 0x28, 0x7e, 0xb1, 0x8c, 0x7b, 0xc9, 0xee, 0x21,
- 0x7b, 0x8d, 0x3a, 0xe3, 0xe6, 0x61, 0xc8, 0x1e, 0xc3, 0x6b, 0x5c, 0x77,
- 0x18, 0x75, 0x94, 0xf7, 0x0d, 0xaa, 0x78, 0x10, 0x8d, 0x44, 0xf4, 0x8b,
- 0x88, 0x04, 0x5f, 0x24, 0x7d, 0x0c, 0x6a, 0xc0, 0x6e, 0xbb, 0xd6, 0x76,
- 0xc2, 0xcc, 0x73, 0x0d, 0x0d, 0x4f, 0x55, 0x7b, 0x1d, 0xde, 0xc9, 0x45,
- 0xed, 0x1e, 0x92, 0x49, 0xf5, 0xcf, 0x0b, 0xba, 0x9a, 0x9a, 0xa0, 0xe7,
- 0xb6, 0x2a, 0xff, 0x65, 0x5f, 0x75, 0x1c, 0x32, 0xc5, 0x34, 0xb2, 0xbd,
- 0x3f, 0xf5, 0xbe, 0x49, 0x36, 0x7a, 0xfb, 0xd8, 0x9f, 0x79, 0xaf, 0xc4,
- 0x27, 0xbc, 0x1f, 0xc4, 0x2d, 0x2b, 0x41, 0x78, 0xb4, 0x87, 0xea, 0xed,
- 0x0f, 0x87, 0x4c, 0xef, 0xc5, 0x38, 0xf7, 0x81, 0x9d, 0xf8, 0x3d, 0xfa,
- 0xfd, 0xe4, 0x90, 0x8c, 0x4d, 0x85, 0x06, 0xb8, 0x86, 0x1d, 0x98, 0xd2,
- 0x6f, 0x44, 0xaf, 0x22, 0xe1, 0xee, 0xe8, 0x49, 0xb2, 0x49, 0x89, 0xc6,
- 0x1c, 0xa2, 0xdf, 0xdc, 0xd3, 0x7a, 0x0c, 0xdb, 0x94, 0x69, 0xef, 0x3b,
- 0x71, 0xa6, 0x17, 0x4c, 0xaf, 0x2c, 0x69, 0xb7, 0x62, 0xeb, 0x6d, 0x5c,
- 0x5b, 0xd9, 0xff, 0x9e, 0x17, 0xdb, 0xeb, 0x71, 0x3c, 0xd7, 0x80, 0xe7,
- 0x73, 0xa6, 0xe7, 0xb5, 0xf6, 0x28, 0xfa, 0x86, 0x2c, 0xbc, 0xac, 0x9b,
- 0x03, 0x55, 0x64, 0xe7, 0x09, 0xaa, 0xaf, 0xc2, 0x6d, 0xdc, 0x4b, 0x40,
- 0xc4, 0x81, 0x48, 0x3f, 0x81, 0xcc, 0x3b, 0x28, 0x74, 0xa5, 0x6a, 0xa8,
- 0x4e, 0x3b, 0x27, 0x2c, 0xf7, 0xf6, 0x76, 0x27, 0xd1, 0x00, 0x6c, 0x28,
- 0xb4, 0x90, 0xdc, 0xa2, 0xd8, 0x14, 0x91, 0xb1, 0xb1, 0xa0, 0xe3, 0xf9,
- 0xb4, 0x0f, 0xb7, 0x17, 0xe2, 0x84, 0xbd, 0x15, 0xa2, 0x3d, 0x81, 0x52,
- 0x3a, 0x80, 0x6f, 0x14, 0x1a, 0x49, 0xde, 0x41, 0xdc, 0x58, 0x08, 0xe1,
- 0x44, 0x9a, 0xf3, 0xb7, 0xe1, 0xd9, 0x1a, 0x6f, 0x44, 0x67, 0x41, 0xc3,
- 0x74, 0x1a, 0x9e, 0x07, 0xe2, 0x21, 0x74, 0x14, 0xa2, 0x28, 0x10, 0x86,
- 0xbb, 0x95, 0xe6, 0xbc, 0x9d, 0x74, 0xd2, 0x52, 0x08, 0x60, 0x69, 0x84,
- 0x22, 0x72, 0xc1, 0x27, 0x06, 0x08, 0x5b, 0x25, 0x0a, 0xf5, 0xb8, 0x38,
- 0xcc, 0x76, 0xae, 0x18, 0x7b, 0x72, 0x0a, 0x42, 0x05, 0xac, 0x94, 0x01,
- 0x0a, 0xd6, 0x91, 0x54, 0x81, 0xe8, 0x3d, 0xd8, 0x5e, 0xe9, 0xe1, 0x2e,
- 0x2f, 0x7c, 0xc6, 0x6f, 0x2d, 0xe9, 0xe9, 0xca, 0xe1, 0x69, 0xef, 0x27,
- 0x71, 0x8e, 0x4d, 0x9f, 0xae, 0x79, 0xfd, 0x30, 0x10, 0x1d, 0x67, 0xde,
- 0xec, 0xd8, 0xc8, 0xf1, 0xb0, 0x45, 0xc6, 0xaf, 0x2c, 0xaa, 0x41, 0x43,
- 0x53, 0xbc, 0x57, 0xa0, 0xf9, 0x88, 0x0e, 0x05, 0x49, 0x5a, 0xfb, 0x96,
- 0xc2, 0x0f, 0xad, 0xad, 0x0b, 0x83, 0xb8, 0x39, 0x52, 0x91, 0xd5, 0x39,
- 0xd2, 0xe1, 0xe4, 0x70, 0x03, 0x66, 0x88, 0x06, 0x97, 0xe1, 0x36, 0x8e,
- 0x8d, 0x59, 0xd8, 0xa0, 0x9b, 0xde, 0xd7, 0xda, 0x97, 0xe3, 0xfe, 0xc3,
- 0x83, 0x67, 0xdd, 0xa4, 0xd7, 0x59, 0xfd, 0x0e, 0x3c, 0x3a, 0x8e, 0xaf,
- 0x35, 0x00, 0x8f, 0x04, 0xc1, 0x3d, 0x6b, 0x35, 0x74, 0x02, 0x91, 0xce,
- 0x07, 0x10, 0x51, 0x34, 0xa1, 0xea, 0x2f, 0x0b, 0x24, 0xab, 0x8d, 0xc8,
- 0xd9, 0x5b, 0x80, 0x33, 0x6e, 0xf2, 0xe0, 0xdb, 0x0b, 0x4e, 0x92, 0x51,
- 0x10, 0xa5, 0x61, 0x37, 0x1c, 0xe4, 0x27, 0x97, 0x34, 0x6c, 0xa8, 0x25,
- 0x59, 0x3b, 0x84, 0x4c, 0x7a, 0x6e, 0xc1, 0xb1, 0xa1, 0x79, 0x59, 0xf9,
- 0x70, 0x13, 0xc9, 0xf0, 0xa9, 0x21, 0x6b, 0x97, 0x16, 0x0b, 0x90, 0xac,
- 0x15, 0xa2, 0x6f, 0x5e, 0x4e, 0x2c, 0xbf, 0x79, 0x39, 0xdd, 0x81, 0x3d,
- 0x33, 0x2c, 0xb7, 0xff, 0x1b, 0x79, 0x4d, 0xdb, 0x76, 0xb7, 0x61, 0x2c,
- 0x8a, 0x86, 0xc3, 0x57, 0x65, 0xc7, 0xf4, 0x3d, 0x42, 0x7c, 0x7c, 0xcf,
- 0xbf, 0x3a, 0xd2, 0xf7, 0xbe, 0xf0, 0x11, 0x3d, 0x0a, 0xe9, 0xe6, 0x03,
- 0x17, 0x63, 0x77, 0x92, 0xc9, 0x55, 0x19, 0x07, 0x49, 0xc6, 0xc1, 0x71,
- 0x96, 0xf5, 0xa7, 0x6b, 0xae, 0x90, 0x7c, 0x5f, 0x27, 0x5c, 0x76, 0x43,
- 0x2c, 0x8a, 0x9a, 0xc3, 0x6a, 0xb2, 0xc1, 0x11, 0x4e, 0xd4, 0x0a, 0x50,
- 0x55, 0x82, 0x96, 0x1a, 0x7c, 0xc8, 0x72, 0xd6, 0x49, 0xce, 0xdf, 0x1b,
- 0x24, 0x7e, 0xd6, 0xd3, 0x7c, 0x1b, 0x48, 0xce, 0x49, 0xe2, 0xff, 0x16,
- 0x7b, 0xde, 0x46, 0x9a, 0x77, 0x0b, 0xd5, 0x1e, 0xd3, 0xde, 0x4b, 0x44,
- 0x4f, 0xf4, 0x33, 0x5a, 0x08, 0x8d, 0x47, 0x82, 0xef, 0x53, 0x8d, 0x7d,
- 0xa3, 0x3d, 0x4e, 0xa1, 0x71, 0x4c, 0xfb, 0xcf, 0xab, 0x24, 0xed, 0xcb,
- 0xfa, 0xcd, 0xdf, 0x02, 0xf7, 0x1c, 0x4c, 0xf4, 0x50, 0x1d, 0xb1, 0x85,
- 0x6a, 0x25, 0x99, 0x72, 0x9b, 0x89, 0x1f, 0xc4, 0xd5, 0x68, 0x9d, 0xe0,
- 0xf8, 0x67, 0x92, 0x1f, 0x96, 0xa9, 0x4e, 0x0a, 0x87, 0x66, 0x10, 0x94,
- 0xa5, 0xa2, 0x4c, 0x78, 0xb0, 0x51, 0x76, 0x14, 0xc9, 0x5f, 0x83, 0x3d,
- 0x84, 0xa7, 0x9d, 0x78, 0x31, 0xef, 0xc4, 0x2b, 0xe9, 0x2d, 0x38, 0x50,
- 0xf2, 0x10, 0x6e, 0x36, 0x3d, 0xce, 0x55, 0x13, 0xee, 0x4a, 0x4c, 0x5e,
- 0x86, 0xae, 0x91, 0x87, 0x51, 0x9d, 0x71, 0x76, 0x53, 0x3e, 0xd5, 0x6f,
- 0x21, 0xb9, 0x6c, 0x28, 0xf2, 0xfd, 0x46, 0x64, 0xd2, 0x29, 0xc2, 0x40,
- 0x61, 0xaa, 0x81, 0x9c, 0x98, 0x68, 0x68, 0xb4, 0xfb, 0xba, 0x39, 0xba,
- 0x96, 0x2b, 0x7d, 0xb1, 0xdf, 0x7c, 0xc7, 0x5c, 0x9f, 0xb9, 0x0f, 0xfb,
- 0xb2, 0x3d, 0x84, 0x4d, 0xb7, 0x50, 0x7c, 0xaf, 0xd0, 0x38, 0x1d, 0xef,
- 0xc6, 0xbe, 0xbc, 0x71, 0x35, 0x7e, 0x4c, 0xda, 0xf1, 0xa3, 0x1f, 0x55,
- 0xed, 0xbc, 0x7f, 0xb5, 0x05, 0x77, 0xa5, 0x81, 0xf7, 0xd2, 0xdc, 0x4f,
- 0x24, 0x4c, 0x41, 0xf9, 0xe0, 0x90, 0xce, 0x39, 0x74, 0x0b, 0x96, 0xe6,
- 0x2d, 0xe4, 0x75, 0x0b, 0x67, 0x75, 0x8d, 0x72, 0x34, 0xe7, 0xea, 0x01,
- 0xa1, 0x51, 0x7e, 0x36, 0x9d, 0xfd, 0x88, 0xb4, 0xb3, 0x8e, 0x1e, 0x9e,
- 0xdb, 0x87, 0xea, 0xb7, 0xf7, 0xa1, 0x66, 0xd2, 0x0e, 0x3c, 0x45, 0x8a,
- 0x78, 0x3e, 0x1b, 0x0e, 0xbd, 0x07, 0x6b, 0x97, 0xc3, 0x50, 0x13, 0x4e,
- 0x07, 0xef, 0xcf, 0xf0, 0xfe, 0x94, 0xd6, 0xbd, 0xd4, 0xa1, 0xea, 0x45,
- 0xd1, 0xdc, 0xf3, 0x16, 0xca, 0x1b, 0x65, 0xa8, 0xa1, 0xd7, 0x10, 0x89,
- 0x76, 0xf2, 0x1e, 0x44, 0xa9, 0x92, 0xbb, 0x97, 0xcd, 0xe5, 0x6e, 0x2d,
- 0xef, 0x15, 0xe1, 0x61, 0x09, 0x13, 0x53, 0x96, 0x29, 0x91, 0xfd, 0x4e,
- 0xd1, 0x9c, 0x3f, 0xce, 0xee, 0x42, 0x36, 0x66, 0x59, 0xb7, 0xc7, 0xb5,
- 0xbe, 0x06, 0x07, 0xfe, 0x90, 0x32, 0x39, 0xc8, 0xe6, 0x53, 0xe4, 0x6b,
- 0xa1, 0x1d, 0xed, 0xa6, 0xe5, 0xb6, 0xeb, 0x0a, 0xee, 0x4f, 0x76, 0x89,
- 0x96, 0xc2, 0x16, 0xb1, 0x9c, 0xb0, 0x5b, 0xe8, 0xd8, 0x66, 0xd1, 0x74,
- 0xb4, 0x82, 0xdd, 0x22, 0x85, 0xcf, 0x7a, 0xa8, 0x37, 0xa7, 0x2d, 0xa4,
- 0x89, 0xaf, 0xa7, 0xfe, 0x0e, 0x5f, 0xac, 0x8b, 0x7e, 0x5c, 0xd7, 0xce,
- 0xbe, 0xf8, 0x30, 0x8e, 0xa5, 0xd9, 0xce, 0xfb, 0xb1, 0x87, 0xe4, 0xb3,
- 0x62, 0x88, 0xf7, 0xc3, 0xd4, 0xb3, 0x83, 0x08, 0xf7, 0xbd, 0x2a, 0xd4,
- 0x72, 0x01, 0xcd, 0x7a, 0x8d, 0x83, 0xe3, 0xab, 0x3a, 0xd0, 0xe4, 0xa8,
- 0xd0, 0x9f, 0xc8, 0x83, 0xe2, 0x69, 0x85, 0x87, 0x95, 0xf9, 0xa5, 0x64,
- 0xab, 0xa6, 0xe7, 0x52, 0xbc, 0xb9, 0xbf, 0x1a, 0x1b, 0xc4, 0x07, 0xd3,
- 0x21, 0x78, 0x0f, 0x27, 0x17, 0xfa, 0xd1, 0x21, 0xde, 0xb3, 0xeb, 0xc5,
- 0x4e, 0xf1, 0x4e, 0xbe, 0x5b, 0x5c, 0x9e, 0xe8, 0x42, 0x64, 0xf8, 0x3e,
- 0xf1, 0xf6, 0x04, 0xd3, 0xd9, 0x23, 0xce, 0x4f, 0x73, 0x9f, 0xd4, 0xc2,
- 0x1e, 0x9d, 0xfb, 0xa2, 0x8b, 0xab, 0xe0, 0xb7, 0x70, 0x4c, 0x67, 0x7d,
- 0x72, 0x9f, 0xb0, 0xd2, 0x5f, 0xda, 0x10, 0xcf, 0x59, 0x4e, 0x8d, 0x7b,
- 0xc5, 0x41, 0x9b, 0xdf, 0x29, 0xc2, 0xd1, 0xd3, 0x13, 0x5b, 0xc4, 0xf1,
- 0x7c, 0x85, 0xd7, 0xc9, 0x3c, 0xdb, 0xaf, 0x4c, 0x3a, 0xfe, 0x62, 0x9e,
- 0x36, 0xa1, 0xb4, 0x07, 0xe1, 0xb6, 0xfb, 0x51, 0x16, 0x46, 0xf4, 0x48,
- 0xe8, 0x65, 0x04, 0xe1, 0x2c, 0xb2, 0x6d, 0x5b, 0x78, 0x5a, 0x77, 0xc1,
- 0x31, 0x22, 0x93, 0x8c, 0xc8, 0x96, 0xfc, 0x2e, 0x48, 0x93, 0x5c, 0x1b,
- 0x7c, 0xbd, 0x8a, 0xfb, 0x14, 0x21, 0x89, 0xbf, 0x7f, 0xd1, 0xe6, 0x5c,
- 0x94, 0x0f, 0xb8, 0xbf, 0xfe, 0x57, 0xee, 0x8a, 0xed, 0xb1, 0x5d, 0xcd,
- 0xf7, 0xc4, 0x29, 0xd7, 0xb6, 0x73, 0x2f, 0xdc, 0x83, 0x99, 0x9c, 0x9b,
- 0x5b, 0x14, 0x1e, 0x77, 0xbb, 0x85, 0x0b, 0xba, 0x93, 0xea, 0x97, 0x87,
- 0x28, 0x47, 0x49, 0x90, 0xb5, 0x3b, 0x50, 0x1c, 0x73, 0x4a, 0xbc, 0x5f,
- 0xf5, 0xb3, 0x18, 0xf7, 0x10, 0x80, 0x43, 0xc4, 0xc3, 0xf7, 0x73, 0x21,
- 0x6c, 0xa2, 0xba, 0x2b, 0x64, 0xd7, 0x18, 0xbf, 0x87, 0x53, 0x39, 0x87,
- 0xa0, 0xba, 0xc2, 0x91, 0x58, 0x6d, 0xe1, 0x4a, 0x5b, 0x24, 0xca, 0x7d,
- 0x68, 0x85, 0x72, 0xd6, 0xde, 0x7c, 0x1d, 0x7e, 0x96, 0xab, 0xc3, 0x2b,
- 0x39, 0x0b, 0x07, 0x63, 0x83, 0x3d, 0x5e, 0x8a, 0x95, 0xcb, 0x62, 0x2e,
- 0xec, 0x88, 0x98, 0x8a, 0x17, 0x51, 0x5c, 0x48, 0x5c, 0x87, 0x54, 0x20,
- 0xdc, 0x39, 0x88, 0x7a, 0xbc, 0x91, 0x03, 0x61, 0x09, 0x78, 0x96, 0xd2,
- 0x1c, 0x6f, 0xc7, 0xcc, 0x7e, 0x17, 0xe1, 0xd8, 0x9f, 0x0b, 0xc4, 0x6b,
- 0x60, 0xb9, 0xcf, 0xc4, 0x29, 0x57, 0x17, 0xea, 0xd0, 0x95, 0xab, 0x47,
- 0x0f, 0xe5, 0xac, 0x75, 0xab, 0xe3, 0x78, 0x2b, 0xeb, 0x13, 0x2b, 0xb3,
- 0x83, 0x3d, 0x0a, 0xcd, 0xe9, 0x6a, 0x53, 0xfb, 0x9f, 0x22, 0xe0, 0x26,
- 0x23, 0x4c, 0xe6, 0x8e, 0x07, 0xfc, 0x14, 0x77, 0x8f, 0x8b, 0x4f, 0xf1,
- 0x04, 0xd9, 0xe3, 0x3d, 0xba, 0x5a, 0xbe, 0xe4, 0x88, 0x9c, 0xdd, 0x08,
- 0x75, 0xe0, 0x16, 0x61, 0x46, 0x6b, 0x29, 0x9e, 0x34, 0x54, 0x62, 0x85,
- 0x19, 0x11, 0x32, 0x61, 0x73, 0x27, 0x3c, 0x9a, 0x89, 0xce, 0x76, 0x96,
- 0xa9, 0x07, 0x9e, 0xa3, 0x64, 0x47, 0xd2, 0x17, 0xfb, 0xfb, 0x75, 0x78,
- 0x9d, 0xf2, 0xe5, 0xb9, 0x1c, 0xf7, 0xe6, 0xdd, 0xc6, 0xbb, 0x94, 0x03,
- 0x5e, 0x8a, 0x0d, 0x86, 0x38, 0xf6, 0xe7, 0x63, 0xf8, 0xe7, 0x64, 0x96,
- 0x8d, 0x3e, 0x5a, 0xf3, 0x2e, 0xc1, 0xeb, 0x20, 0xb9, 0xc4, 0xe0, 0xbe,
- 0x9c, 0xcd, 0x0f, 0xc5, 0x63, 0xe6, 0xe9, 0xff, 0x27, 0xed, 0x8f, 0x54,
- 0xc1, 0x5b, 0x4f, 0xba, 0x9c, 0xef, 0x69, 0x5e, 0xdb, 0xcf, 0xe4, 0x7a,
- 0xa6, 0x82, 0x0f, 0xdd, 0x46, 0xb5, 0x78, 0x21, 0xc7, 0x36, 0x67, 0xe1,
- 0x19, 0x5d, 0xa7, 0xda, 0x85, 0x6b, 0xf2, 0x7e, 0xaa, 0x5f, 0xb8, 0xcf,
- 0x64, 0x7a, 0xce, 0x10, 0x85, 0xfb, 0x73, 0x58, 0x2b, 0xc3, 0xb1, 0xa2,
- 0x0a, 0xe3, 0x98, 0x70, 0x3a, 0x09, 0x73, 0x70, 0xac, 0x65, 0x7f, 0x52,
- 0x0c, 0x6d, 0x82, 0xeb, 0xcf, 0x4e, 0x98, 0xb6, 0x1f, 0x57, 0x8b, 0xfb,
- 0xc9, 0x46, 0x5e, 0x8c, 0x55, 0x61, 0x82, 0xea, 0x1f, 0xc9, 0x30, 0x3d,
- 0xdf, 0xa5, 0xe7, 0x13, 0xa3, 0xd8, 0x17, 0x84, 0xe3, 0x4f, 0x14, 0xfc,
- 0x19, 0xde, 0x74, 0xc9, 0x74, 0x1d, 0x9e, 0xee, 0xb8, 0xe9, 0xdd, 0x18,
- 0xaf, 0x16, 0xb7, 0xe6, 0x5a, 0xf0, 0xfe, 0x58, 0x1d, 0xd9, 0x77, 0x3d,
- 0x96, 0x8c, 0x04, 0xf1, 0x36, 0xd1, 0x32, 0x40, 0xb4, 0x7c, 0xd2, 0x66,
- 0x0e, 0x34, 0x40, 0xed, 0xa7, 0xba, 0xa8, 0x9b, 0xfb, 0xcd, 0x4f, 0xeb,
- 0x6a, 0xe7, 0x6d, 0xc2, 0x0b, 0x2d, 0x92, 0x24, 0xd9, 0x5b, 0xd6, 0xb0,
- 0xde, 0xac, 0xfb, 0xc0, 0xfd, 0xa3, 0x3b, 0x70, 0x68, 0x86, 0x69, 0x71,
- 0x1b, 0xcb, 0xa7, 0xf9, 0x53, 0x36, 0xae, 0xb3, 0x3f, 0xbd, 0x73, 0x9f,
- 0x30, 0x42, 0xf6, 0xe7, 0xa7, 0x6b, 0x42, 0xd3, 0xdc, 0xa7, 0x0e, 0x9b,
- 0x6e, 0xf1, 0x53, 0x17, 0xf7, 0xab, 0x93, 0xe0, 0xff, 0x57, 0x5d, 0x95,
- 0x7e, 0xdf, 0x1d, 0x30, 0xed, 0x1e, 0xca, 0x15, 0xbb, 0x97, 0x1d, 0x22,
- 0x37, 0x90, 0x89, 0x3f, 0x99, 0x30, 0x57, 0x20, 0x46, 0x05, 0x7c, 0xbd,
- 0x6c, 0x2e, 0x31, 0x7a, 0xa8, 0x46, 0x90, 0x89, 0x5f, 0x13, 0xfb, 0xda,
- 0x05, 0x0e, 0x69, 0x06, 0x5e, 0xcb, 0x73, 0x2c, 0x77, 0xe2, 0xfb, 0x69,
- 0x35, 0x94, 0x12, 0xe1, 0xce, 0x5b, 0x84, 0x84, 0x50, 0x43, 0x0f, 0x0e,
- 0x51, 0x5e, 0x99, 0x4e, 0x73, 0x1e, 0x71, 0xda, 0xe7, 0x05, 0x6a, 0x29,
- 0x0e, 0x7d, 0x38, 0x54, 0x89, 0xfb, 0x85, 0xb8, 0xba, 0xff, 0xf7, 0x48,
- 0xa7, 0x4f, 0x17, 0x78, 0x4e, 0x13, 0x9f, 0xac, 0x66, 0x1f, 0x56, 0xa3,
- 0x29, 0xe9, 0x5e, 0x84, 0xa6, 0x38, 0xb6, 0xd0, 0x72, 0xb4, 0xd6, 0x91,
- 0xac, 0x1b, 0xdd, 0xf1, 0x2e, 0xd1, 0x53, 0xfc, 0x67, 0xbc, 0x27, 0xa1,
- 0x2c, 0x30, 0x36, 0x8b, 0xf5, 0x93, 0xdc, 0x53, 0xdc, 0x22, 0xba, 0x8b,
- 0xdc, 0x57, 0x1c, 0x10, 0xbf, 0x5f, 0x64, 0x9f, 0x9f, 0xef, 0x2f, 0xce,
- 0xeb, 0x9f, 0xfb, 0x8a, 0xa6, 0xe7, 0x05, 0x92, 0xfd, 0x03, 0x39, 0x8e,
- 0xc9, 0x8e, 0xfb, 0xfd, 0x68, 0xc3, 0x84, 0x0b, 0x9e, 0xd3, 0xf1, 0xaf,
- 0xe0, 0x76, 0xc2, 0x07, 0x4b, 0xb4, 0x8a, 0xfe, 0xd6, 0x4d, 0x48, 0x48,
- 0xb4, 0x91, 0xd0, 0x17, 0xb0, 0x4e, 0x7b, 0x29, 0x9e, 0x65, 0xac, 0xbe,
- 0x00, 0xeb, 0x92, 0xed, 0xcd, 0x2e, 0xf7, 0x28, 0x0e, 0x9b, 0x94, 0x57,
- 0x3c, 0x98, 0xce, 0x2d, 0xa2, 0xda, 0xc0, 0xc2, 0x7e, 0xbd, 0x06, 0x55,
- 0x76, 0x0c, 0xf0, 0x10, 0x9e, 0x84, 0xec, 0xa3, 0x79, 0xd2, 0xc3, 0x32,
- 0xbc, 0x74, 0xef, 0x8c, 0x4e, 0x72, 0x69, 0xaf, 0xcc, 0xdd, 0x3c, 0xb1,
- 0x12, 0x07, 0xc9, 0xe3, 0x6b, 0xb4, 0x28, 0x86, 0x14, 0x1f, 0xc5, 0x9a,
- 0x3b, 0xe6, 0xe6, 0xf4, 0xd0, 0x60, 0x5e, 0xaf, 0xbf, 0xaa, 0xa2, 0x87,
- 0x35, 0x72, 0xa5, 0x06, 0x93, 0xcd, 0x6a, 0x5a, 0x6b, 0x47, 0xfb, 0x16,
- 0x74, 0x0e, 0xf9, 0xc4, 0x2b, 0xe9, 0xbb, 0xad, 0x50, 0x1d, 0x8d, 0x23,
- 0x9b, 0x75, 0xcf, 0xd1, 0xdb, 0x34, 0x21, 0xf3, 0x58, 0xee, 0x79, 0xe0,
- 0xc1, 0x9c, 0x84, 0xc0, 0xdc, 0xf5, 0xf8, 0x44, 0x08, 0x7a, 0x6b, 0x35,
- 0x50, 0x2f, 0xe8, 0x1a, 0xcf, 0xcd, 0x6b, 0xc8, 0xa8, 0x23, 0x3f, 0xb9,
- 0x33, 0x9e, 0xc0, 0xbb, 0x59, 0x27, 0x36, 0x52, 0x9e, 0xbf, 0x31, 0x6d,
- 0xe0, 0x42, 0x29, 0x60, 0xcf, 0x21, 0x19, 0xf3, 0xe3, 0x9c, 0x34, 0xce,
- 0x83, 0xc9, 0x89, 0x2f, 0xd2, 0x17, 0x20, 0x9a, 0x7f, 0x42, 0xdf, 0xf9,
- 0xde, 0x45, 0xbb, 0x3f, 0x70, 0xea, 0x9a, 0xba, 0x4a, 0x1a, 0xe1, 0x9e,
- 0x52, 0x25, 0x17, 0x74, 0xe8, 0xac, 0x4b, 0x3f, 0x66, 0x47, 0x4d, 0x5c,
- 0x58, 0x5d, 0x8b, 0x4f, 0x46, 0x9b, 0x70, 0x7f, 0xce, 0x8b, 0x4b, 0xa3,
- 0x16, 0x56, 0xb6, 0xe1, 0xee, 0x20, 0x61, 0xb1, 0x5a, 0xf2, 0xfb, 0xd7,
- 0xa8, 0xf6, 0xa1, 0x78, 0x4a, 0x94, 0x46, 0x12, 0x1b, 0xc8, 0xae, 0xa3,
- 0x31, 0xa4, 0x6e, 0x8a, 0x47, 0x42, 0x17, 0xf1, 0x3d, 0x8b, 0x62, 0xb1,
- 0xe2, 0x30, 0xba, 0x84, 0xd3, 0xde, 0x67, 0xdc, 0x62, 0xef, 0x4b, 0x4a,
- 0x93, 0x03, 0xc2, 0x51, 0xbc, 0xd6, 0xaf, 0xbf, 0x2c, 0x0f, 0x71, 0xee,
- 0xe1, 0x1e, 0xc6, 0x88, 0xe5, 0xd2, 0xb8, 0x57, 0xb3, 0x59, 0xec, 0x9d,
- 0xb8, 0x9a, 0x9b, 0xae, 0xe6, 0xa3, 0xdd, 0x73, 0x79, 0x68, 0x30, 0xff,
- 0x8b, 0x2f, 0xe0, 0xa8, 0xd0, 0xdc, 0x7e, 0x07, 0xe7, 0x1f, 0x8f, 0x78,
- 0x93, 0xcc, 0x61, 0x1f, 0xf9, 0xe0, 0x49, 0xfd, 0x74, 0x90, 0x32, 0x04,
- 0x9c, 0xad, 0x02, 0x0f, 0xf2, 0x59, 0x93, 0x80, 0x85, 0xcd, 0x7a, 0xc5,
- 0x1e, 0xda, 0xda, 0x5d, 0xe8, 0xa3, 0x9c, 0xe4, 0x8a, 0xf9, 0xc8, 0xd7,
- 0x15, 0xbc, 0xaa, 0xb3, 0x0d, 0x6f, 0x9e, 0xcb, 0x49, 0xbc, 0x7f, 0x5e,
- 0xd9, 0xeb, 0xfe, 0x7c, 0xdf, 0x7b, 0xde, 0x36, 0x75, 0x24, 0x17, 0xc2,
- 0xfb, 0x76, 0x5c, 0xa3, 0xfa, 0x41, 0xa6, 0xda, 0x61, 0x23, 0x12, 0x0b,
- 0x54, 0x6e, 0x6d, 0x10, 0xf6, 0x36, 0xf1, 0xef, 0xdb, 0xfb, 0x70, 0xdf,
- 0x88, 0x84, 0x6a, 0x8d, 0xe3, 0xac, 0x89, 0x43, 0x75, 0x1c, 0xa7, 0xba,
- 0xb0, 0x6b, 0xc4, 0x23, 0xce, 0xe4, 0x9c, 0x78, 0xa2, 0xfb, 0x11, 0x2c,
- 0x68, 0xbd, 0x07, 0xb0, 0x6d, 0x90, 0xbf, 0x7f, 0x0b, 0xa9, 0x45, 0xbc,
- 0x3e, 0xf7, 0xda, 0x04, 0x7c, 0xad, 0xcc, 0x07, 0xbc, 0xef, 0xd3, 0xfc,
- 0xdb, 0x86, 0x9c, 0xe2, 0x62, 0xfa, 0x3f, 0x5b, 0x27, 0x02, 0x8c, 0x13,
- 0xf8, 0x5e, 0x0d, 0xcc, 0x3a, 0x1e, 0xcb, 0x3a, 0xf4, 0x51, 0x6d, 0xda,
- 0x87, 0x21, 0xa2, 0xeb, 0x9c, 0x3d, 0xd7, 0x95, 0x39, 0xfa, 0x7d, 0xa2,
- 0x36, 0x23, 0x9b, 0x41, 0xa2, 0x45, 0x59, 0xdd, 0x8d, 0xda, 0xe2, 0xb5,
- 0xf9, 0xb6, 0xc6, 0xc3, 0xfd, 0x4a, 0xd2, 0x15, 0xe5, 0x84, 0x5e, 0xbc,
- 0x9b, 0x16, 0x78, 0xc7, 0xb6, 0xc1, 0x5e, 0x34, 0xe5, 0x6b, 0x00, 0x3b,
- 0x86, 0xf0, 0xb8, 0xaf, 0x57, 0x6c, 0x5b, 0xea, 0xc3, 0x03, 0xc4, 0x4b,
- 0x0d, 0xf1, 0xf2, 0x61, 0x6c, 0x29, 0xad, 0xc3, 0xd7, 0xfe, 0x9d, 0x3c,
- 0x77, 0xd6, 0x68, 0x6e, 0x2e, 0x4a, 0x18, 0x7e, 0xae, 0xf7, 0x22, 0xd8,
- 0x39, 0x12, 0xe9, 0xf1, 0x49, 0x6c, 0x87, 0x11, 0xdc, 0x3b, 0x79, 0x2b,
- 0xdd, 0xe7, 0xb9, 0x82, 0xb8, 0x2b, 0xe3, 0x14, 0x6f, 0x51, 0xbd, 0x74,
- 0x2a, 0x2d, 0x2d, 0x72, 0xe0, 0x39, 0xeb, 0x89, 0xc0, 0x2e, 0xdc, 0xa4,
- 0x77, 0x61, 0x3b, 0xd9, 0x60, 0x47, 0xd3, 0x2e, 0x8c, 0x92, 0x0d, 0x6c,
- 0xab, 0xa7, 0x1a, 0x2e, 0x56, 0xb2, 0x7a, 0x03, 0x2c, 0x47, 0x81, 0x4e,
- 0xba, 0x5e, 0x47, 0x75, 0x9d, 0x14, 0x23, 0x6b, 0x23, 0xbf, 0x90, 0x35,
- 0x35, 0x97, 0xc4, 0xef, 0xd8, 0x6b, 0xd6, 0x51, 0x9e, 0x76, 0x31, 0x3e,
- 0xf0, 0x33, 0x4e, 0xf8, 0x22, 0x3d, 0xa6, 0x55, 0xa5, 0x69, 0xd1, 0x8d,
- 0x52, 0x53, 0x6e, 0x86, 0x6c, 0x76, 0x7d, 0xeb, 0xb5, 0xcf, 0xcd, 0xcb,
- 0x48, 0x87, 0xbb, 0x75, 0xca, 0x2a, 0x2b, 0x83, 0x50, 0x5a, 0xaf, 0xd5,
- 0xfd, 0xfc, 0x1c, 0x4c, 0x73, 0x25, 0xae, 0x85, 0xa4, 0x88, 0x72, 0x37,
- 0x2e, 0xd0, 0x1a, 0x41, 0x6c, 0x2d, 0x76, 0xa1, 0x77, 0xc4, 0xf1, 0x19,
- 0x3e, 0xf1, 0xb3, 0x2d, 0x7f, 0xc6, 0xff, 0x8e, 0x91, 0x48, 0xa7, 0x77,
- 0x8e, 0xff, 0xed, 0x93, 0x9f, 0xcd, 0x35, 0x90, 0xe1, 0xbc, 0xca, 0xf3,
- 0xf1, 0xb9, 0xa1, 0x79, 0xf9, 0x06, 0xf1, 0x80, 0x3d, 0xdf, 0x61, 0x0f,
- 0xfb, 0xb0, 0x8b, 0x7c, 0x7d, 0x43, 0xab, 0x89, 0x57, 0x13, 0xf7, 0x5b,
- 0x3b, 0x6c, 0x19, 0xdc, 0x6f, 0x3f, 0xdf, 0xd9, 0x74, 0x76, 0x0e, 0xfb,
- 0x54, 0xfa, 0xb0, 0xa7, 0x4a, 0x2d, 0xf6, 0x1e, 0xc3, 0x0f, 0x29, 0x0f,
- 0x3e, 0xf7, 0xb9, 0x3e, 0xdf, 0x76, 0x17, 0xef, 0x4d, 0x3c, 0x5d, 0x92,
- 0x85, 0x73, 0xa4, 0x5a, 0xb8, 0x46, 0x98, 0xb6, 0x8f, 0xe5, 0x8a, 0x8f,
- 0xfd, 0x57, 0x24, 0x03, 0xbc, 0xcf, 0x58, 0xb1, 0xff, 0x68, 0xfb, 0xbd,
- 0xc0, 0x51, 0xd3, 0x53, 0xb5, 0x0a, 0x54, 0xeb, 0x77, 0xdb, 0xf6, 0xb0,
- 0xd0, 0x08, 0xac, 0x7d, 0xae, 0x89, 0xeb, 0x7d, 0xee, 0x0d, 0x6a, 0x6b,
- 0xc7, 0x08, 0x80, 0x6e, 0x55, 0x78, 0x4d, 0xf5, 0x04, 0xf7, 0xeb, 0xb9,
- 0x8f, 0x4f, 0x71, 0xd7, 0x5b, 0xb7, 0xca, 0xf4, 0x2c, 0x58, 0xe5, 0x14,
- 0x8b, 0x33, 0x3d, 0x64, 0x7b, 0x1a, 0x12, 0x19, 0xd3, 0xdb, 0xb0, 0x2a,
- 0x84, 0x87, 0x32, 0xf3, 0x31, 0xb9, 0x05, 0x2d, 0xe3, 0xc0, 0x0f, 0x33,
- 0x41, 0x34, 0x8f, 0x86, 0xfb, 0x6f, 0x95, 0xc2, 0x03, 0xb3, 0x12, 0xdf,
- 0xbb, 0xbc, 0x66, 0xa5, 0x8d, 0xc5, 0x3f, 0x5a, 0xb3, 0xc2, 0xfe, 0x0c,
- 0x18, 0xd7, 0xe7, 0xef, 0x40, 0x7a, 0xc6, 0x33, 0x5b, 0x96, 0x2c, 0x3c,
- 0x14, 0x93, 0x70, 0xb3, 0xfe, 0x6f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab,
- 0x9c, 0x83, 0xed, 0x60, 0xb6, 0x64, 0x95, 0x86, 0x55, 0x99, 0x3a, 0x8a,
- 0x49, 0xf5, 0x14, 0x9f, 0xea, 0x70, 0x85, 0x62, 0xd2, 0x8a, 0x36, 0x0b,
- 0x8b, 0xdb, 0xcc, 0xbe, 0xc5, 0xe0, 0x3d, 0x68, 0xd5, 0x2c, 0x0a, 0xb5,
- 0xa7, 0x4b, 0x52, 0xbb, 0xeb, 0x25, 0x05, 0xdb, 0x23, 0x3c, 0x77, 0xd0,
- 0x58, 0x95, 0xaf, 0xe4, 0xd3, 0x4a, 0x5e, 0x75, 0xce, 0xe5, 0x53, 0xb7,
- 0xa1, 0x4f, 0xab, 0x3f, 0x4e, 0x49, 0xbc, 0x6f, 0xd2, 0x83, 0x91, 0x6c,
- 0x0a, 0x7b, 0xb3, 0x21, 0xfc, 0x3a, 0xe3, 0x26, 0xdb, 0x08, 0xeb, 0x3f,
- 0x00, 0x8f, 0xf1, 0x19, 0xb1, 0x7c, 0x38, 0xfa, 0x90, 0xf4, 0x13, 0x94,
- 0x9d, 0xea, 0x11, 0xaa, 0x12, 0x08, 0x37, 0x34, 0x87, 0x5e, 0xc4, 0x4f,
- 0xec, 0x7d, 0x36, 0xa0, 0xc2, 0x43, 0x53, 0x1e, 0xc8, 0x65, 0x3c, 0xb3,
- 0xb0, 0x7b, 0xb2, 0xbc, 0x6f, 0x2c, 0x61, 0xbd, 0x7e, 0x3f, 0xc9, 0x59,
- 0xa0, 0xa9, 0xb5, 0x0e, 0xe5, 0x2d, 0x4e, 0x8c, 0x64, 0x38, 0x0f, 0x7f,
- 0xbc, 0x46, 0x1e, 0x42, 0x79, 0x6e, 0x4f, 0x34, 0xe1, 0xa0, 0x0c, 0xfd,
- 0x72, 0x11, 0x38, 0x48, 0xb1, 0x63, 0x53, 0xec, 0x37, 0x56, 0x05, 0x8f,
- 0xca, 0xfe, 0xf4, 0x98, 0xc0, 0x02, 0x2d, 0x49, 0xf2, 0x70, 0xfa, 0x0f,
- 0xa5, 0xa3, 0x76, 0x0e, 0x1e, 0xa1, 0xf9, 0x93, 0xf6, 0xfc, 0x91, 0xfd,
- 0x4b, 0x25, 0x09, 0xd7, 0xb7, 0x1e, 0xc5, 0xc4, 0xc2, 0x0a, 0x0d, 0x41,
- 0xc2, 0x04, 0x5c, 0xcb, 0xd6, 0x13, 0x8f, 0x9b, 0x1f, 0xe3, 0xbe, 0xe6,
- 0x6f, 0xd7, 0xdc, 0x30, 0xce, 0x7e, 0xfd, 0xf1, 0x9a, 0x77, 0xd3, 0x6a,
- 0xb2, 0x9e, 0xea, 0x87, 0x6a, 0x92, 0xc3, 0xbd, 0x43, 0xdc, 0x4f, 0xa8,
- 0x37, 0x5e, 0x3f, 0xcc, 0x79, 0x59, 0x1d, 0x68, 0x10, 0x3e, 0x71, 0x73,
- 0x46, 0xed, 0x63, 0xc2, 0x2f, 0x47, 0xd4, 0x20, 0xc9, 0xae, 0xf3, 0x1e,
- 0xd1, 0xc7, 0x35, 0x8b, 0x2d, 0xb7, 0xeb, 0xf2, 0x15, 0xdc, 0x11, 0x9e,
- 0xc3, 0x21, 0x51, 0x1b, 0x77, 0x58, 0xd6, 0x9e, 0x18, 0xe7, 0x71, 0xfb,
- 0x4c, 0x00, 0x5d, 0xaf, 0x33, 0x96, 0x52, 0x6d, 0x31, 0xc8, 0xf4, 0xf1,
- 0x19, 0x0f, 0x89, 0x6a, 0xd1, 0xec, 0xab, 0x73, 0xb8, 0xc4, 0x87, 0x7d,
- 0x74, 0xbd, 0x6c, 0xe3, 0x13, 0x3e, 0xa7, 0xe8, 0x35, 0x94, 0xc7, 0xf8,
- 0x6c, 0xe3, 0x6f, 0xd7, 0xac, 0x1f, 0x53, 0x43, 0x12, 0xf1, 0xb1, 0x97,
- 0xf7, 0xe7, 0x69, 0xce, 0x69, 0x9d, 0xe9, 0xbe, 0xbc, 0x86, 0xfb, 0xb1,
- 0x4b, 0x88, 0x6e, 0x2b, 0x1b, 0x66, 0x0c, 0x6a, 0xdb, 0x4a, 0x22, 0x4f,
- 0x55, 0xfd, 0xe2, 0x0a, 0xaf, 0x2e, 0xd2, 0xc9, 0xb1, 0x74, 0x12, 0xa7,
- 0xe2, 0x15, 0xfd, 0xac, 0xcb, 0x7f, 0x03, 0xa9, 0xfa, 0x0e, 0xe4, 0xb2,
- 0x8a, 0x7f, 0x43, 0xa6, 0x03, 0xa3, 0xa4, 0xc3, 0xbb, 0x8b, 0x41, 0x7f,
- 0x47, 0x46, 0x43, 0x6f, 0x91, 0xeb, 0x2b, 0x18, 0x7b, 0xc6, 0x26, 0xe7,
- 0xea, 0xe0, 0x4a, 0x2e, 0x39, 0x90, 0xa9, 0xd8, 0x5c, 0x38, 0xef, 0x99,
- 0x0d, 0x89, 0xca, 0xbc, 0x32, 0xad, 0x23, 0x0f, 0xfd, 0x89, 0x85, 0x85,
- 0x6c, 0x0b, 0x77, 0x60, 0x6c, 0xdc, 0x6f, 0x2e, 0x36, 0x14, 0xac, 0x6a,
- 0xfd, 0x73, 0x7a, 0xb6, 0x05, 0x1f, 0x1f, 0xff, 0x3a, 0xca, 0xdf, 0x24,
- 0x7c, 0x94, 0x49, 0xa2, 0xb9, 0xf5, 0x16, 0xa4, 0xfe, 0x40, 0xc6, 0xd3,
- 0x19, 0x1f, 0x9e, 0xcf, 0x54, 0xf6, 0xec, 0x7f, 0x94, 0x25, 0x3f, 0x24,
- 0x1f, 0x78, 0xee, 0x4b, 0xf7, 0x49, 0x29, 0x9e, 0x3b, 0x78, 0x0f, 0xff,
- 0x1f, 0x1e, 0x77, 0xde, 0x1e, 0xe7, 0x11, 0x75, 0x23, 0xf3, 0xf3, 0x5a,
- 0xd0, 0x5a, 0xff, 0xbe, 0x67, 0x08, 0xf3, 0x81, 0x62, 0x48, 0xe5, 0x8c,
- 0x83, 0x90, 0x47, 0xec, 0x7d, 0x23, 0xc2, 0xb9, 0x11, 0xfd, 0x02, 0x4c,
- 0xb8, 0x09, 0x5f, 0x2d, 0x25, 0x59, 0x68, 0x99, 0x80, 0x5f, 0x2a, 0x2a,
- 0xf4, 0xdf, 0xe8, 0x77, 0x92, 0x7c, 0x9c, 0xc5, 0x8f, 0x28, 0xa6, 0xb0,
- 0x4f, 0x55, 0x72, 0x9c, 0x54, 0x7c, 0xc4, 0x4b, 0xc0, 0x87, 0x3e, 0x2b,
- 0x36, 0x1d, 0xca, 0x2f, 0xf6, 0x32, 0x96, 0xc9, 0x65, 0x2a, 0xbf, 0x23,
- 0x57, 0x7f, 0x93, 0x9e, 0x6d, 0x99, 0x8d, 0xd0, 0x6f, 0x96, 0xc5, 0x73,
- 0x56, 0x6a, 0x33, 0xcb, 0x2b, 0xe0, 0x7f, 0x83, 0xe4, 0x3f, 0x46, 0x34,
- 0x66, 0x69, 0x8d, 0xd7, 0x69, 0xcd, 0x4c, 0xf1, 0x10, 0x8d, 0xe1, 0x7b,
- 0x24, 0x67, 0xdb, 0x76, 0x0f, 0x7b, 0xf9, 0x7c, 0xc2, 0xf3, 0x19, 0x60,
- 0x30, 0x6b, 0xaa, 0xce, 0xb9, 0x73, 0x9d, 0x83, 0x94, 0x2f, 0xab, 0x28,
- 0x16, 0xbd, 0x19, 0xdf, 0x8e, 0x1b, 0x73, 0x6a, 0xd2, 0x24, 0x3c, 0x96,
- 0x52, 0x20, 0x48, 0x77, 0x64, 0xc3, 0x01, 0xe3, 0xdd, 0x74, 0x23, 0xf1,
- 0x14, 0x0e, 0x5d, 0xa0, 0xf1, 0xa6, 0x53, 0xc6, 0x81, 0x51, 0x07, 0x2e,
- 0xf0, 0x1e, 0xb2, 0xa8, 0x3c, 0x6f, 0x82, 0xc7, 0xce, 0x7f, 0xaf, 0xa6,
- 0xba, 0x2e, 0x9c, 0xa0, 0xac, 0x6a, 0xd6, 0x10, 0x6e, 0xcf, 0xb7, 0x3f,
- 0x82, 0x43, 0x54, 0xeb, 0xef, 0x88, 0x85, 0x90, 0xac, 0x8b, 0x53, 0xbd,
- 0xd1, 0xdc, 0x7f, 0x09, 0xff, 0xcd, 0x2a, 0xf3, 0x3e, 0xbc, 0x08, 0x27,
- 0x2e, 0xe1, 0x53, 0xcb, 0xa1, 0x69, 0x67, 0xa7, 0xa0, 0x95, 0x2f, 0xa0,
- 0x79, 0xe0, 0x13, 0xbc, 0x67, 0xf1, 0x1e, 0xbd, 0xec, 0x70, 0x10, 0x06,
- 0x0c, 0x2b, 0x4e, 0x04, 0x50, 0x0e, 0x38, 0xb0, 0x49, 0xe7, 0xde, 0xb4,
- 0x3a, 0xf0, 0x24, 0x61, 0xf9, 0x77, 0x44, 0x73, 0xdf, 0x87, 0x38, 0x6f,
- 0x4d, 0xd4, 0xf1, 0xba, 0x02, 0x89, 0xeb, 0x9b, 0xcf, 0xba, 0xa1, 0x76,
- 0xba, 0x84, 0x96, 0x68, 0x70, 0xfc, 0x95, 0x75, 0x3e, 0xf0, 0xa9, 0xa5,
- 0x45, 0x3e, 0x25, 0x1c, 0xa4, 0x05, 0x27, 0xc9, 0xf6, 0xfb, 0x30, 0x4f,
- 0x9b, 0xa8, 0x86, 0x57, 0x27, 0x1a, 0x18, 0xf7, 0x99, 0x9e, 0x7d, 0x44,
- 0xdb, 0x6b, 0x84, 0x03, 0x76, 0xc4, 0x2e, 0x59, 0xc9, 0x85, 0x7c, 0xfe,
- 0x4f, 0xa9, 0xae, 0xf4, 0xc0, 0xb9, 0x6f, 0x72, 0x07, 0xee, 0x4a, 0x3b,
- 0x49, 0x4e, 0xf3, 0x78, 0xcd, 0x45, 0x31, 0x98, 0x63, 0x7f, 0xf9, 0x3a,
- 0x2a, 0xcd, 0x24, 0x2a, 0xf1, 0xb1, 0x87, 0xe2, 0xc2, 0x6e, 0x3b, 0x17,
- 0xc0, 0xbb, 0x64, 0x55, 0x2b, 0x3e, 0x19, 0x7f, 0xd3, 0x4b, 0xbe, 0xb4,
- 0x4e, 0x6b, 0x83, 0x08, 0x66, 0x4c, 0x51, 0x6b, 0x38, 0xf0, 0x61, 0xbb,
- 0xda, 0x29, 0x39, 0x06, 0x70, 0x7d, 0xcc, 0xb4, 0x7c, 0x9a, 0xd6, 0xd3,
- 0x22, 0x22, 0xdd, 0x45, 0x11, 0x45, 0x75, 0xd1, 0x27, 0x57, 0x17, 0x5b,
- 0x64, 0x6f, 0xd1, 0xf4, 0x28, 0xab, 0xb6, 0x53, 0xdd, 0xb2, 0x8b, 0x6a,
- 0x5b, 0x1f, 0xd5, 0xd7, 0xaa, 0x7e, 0x11, 0x6e, 0x92, 0x7f, 0x08, 0xfb,
- 0x4a, 0x06, 0x9c, 0x99, 0x9d, 0x70, 0x65, 0xc2, 0xca, 0x5e, 0xec, 0x42,
- 0x32, 0x58, 0xc1, 0xb6, 0x32, 0xe9, 0xaa, 0xaa, 0x9d, 0xb1, 0xcc, 0x76,
- 0x9c, 0x9f, 0x60, 0x7c, 0x9e, 0xc0, 0xd6, 0x34, 0xff, 0x86, 0xf7, 0xc5,
- 0xb8, 0x81, 0x93, 0x54, 0x3b, 0x79, 0x5a, 0x1b, 0x48, 0x0f, 0x8d, 0x18,
- 0x2c, 0x09, 0x36, 0x2b, 0xd2, 0x05, 0xbc, 0x27, 0xdb, 0x65, 0x1c, 0x9c,
- 0xa2, 0x44, 0x42, 0xf9, 0xca, 0x99, 0x51, 0x28, 0x4e, 0xc8, 0xf0, 0x69,
- 0x3e, 0xfa, 0x1d, 0xe0, 0x73, 0x4b, 0x64, 0x67, 0xbf, 0x5d, 0xd3, 0x62,
- 0xc7, 0x9a, 0x7a, 0xaa, 0x75, 0xde, 0x21, 0x5e, 0x58, 0x16, 0x06, 0xaa,
- 0x47, 0xe6, 0x6b, 0xc2, 0xf5, 0xb7, 0x55, 0x23, 0x48, 0x73, 0x32, 0x0e,
- 0xac, 0x9c, 0x57, 0x5d, 0x1f, 0x6b, 0x45, 0x21, 0x27, 0xe6, 0x30, 0xd6,
- 0xa0, 0xea, 0xc3, 0x3a, 0x1c, 0xa2, 0xda, 0xdf, 0xaf, 0x6d, 0x45, 0x46,
- 0x29, 0x7b, 0x7f, 0x11, 0xe7, 0x1a, 0x00, 0xde, 0x5e, 0xc2, 0x50, 0x43,
- 0xe9, 0xaf, 0x72, 0xcc, 0xf4, 0xdc, 0x1d, 0xd7, 0x71, 0x24, 0x47, 0x21,
- 0x4a, 0x5b, 0x87, 0xda, 0xb6, 0x2e, 0x7c, 0x58, 0xc7, 0xf8, 0x97, 0x62,
- 0x15, 0xd1, 0xb3, 0x77, 0x2a, 0x60, 0x9f, 0xab, 0xd8, 0x57, 0x9a, 0xa7,
- 0xf9, 0x5a, 0x5a, 0xbf, 0x8c, 0x46, 0x96, 0xc9, 0x3f, 0x44, 0x23, 0xd9,
- 0x2c, 0x61, 0x9e, 0x5c, 0xba, 0x17, 0x2f, 0xa7, 0x79, 0xde, 0x70, 0x52,
- 0x17, 0x0a, 0xf7, 0xe6, 0x6d, 0x99, 0x98, 0x53, 0xbc, 0x06, 0xaf, 0x3f,
- 0xbf, 0x4e, 0x80, 0x6a, 0x85, 0x7f, 0xec, 0x5a, 0x14, 0x37, 0x72, 0xeb,
- 0xa8, 0xee, 0x8c, 0x42, 0xfb, 0xfd, 0x32, 0xe9, 0x83, 0x7b, 0xd5, 0x4b,
- 0x09, 0xf3, 0xc2, 0xf3, 0x4a, 0x9c, 0xcf, 0x30, 0x5b, 0xbb, 0x64, 0xc3,
- 0xb2, 0x5c, 0xed, 0x9a, 0xf2, 0x36, 0xd8, 0x0e, 0x7d, 0xbc, 0xe7, 0xe1,
- 0xd9, 0xdb, 0xee, 0xc3, 0x41, 0xca, 0x81, 0x4f, 0xa5, 0x9b, 0x4d, 0xae,
- 0xfd, 0xc0, 0x38, 0x54, 0xa4, 0xe8, 0xd9, 0x7f, 0x55, 0xcd, 0x3e, 0xbb,
- 0xa7, 0xb4, 0x13, 0x52, 0xa6, 0xa7, 0x9a, 0xeb, 0x0d, 0x37, 0xd5, 0xc9,
- 0x83, 0x69, 0xa6, 0xd7, 0xda, 0xe5, 0xa4, 0xb9, 0x76, 0xc7, 0xb5, 0xd9,
- 0x1b, 0xc9, 0x2e, 0x1a, 0x0c, 0x96, 0x63, 0x00, 0x4f, 0xd0, 0xd8, 0x50,
- 0x89, 0x65, 0x79, 0xa8, 0x9a, 0xfb, 0x9e, 0xfb, 0x48, 0xbf, 0xb5, 0xd9,
- 0xca, 0x3c, 0xd9, 0x52, 0x1f, 0x96, 0x0e, 0xbd, 0x58, 0x5d, 0xa9, 0x7d,
- 0xb8, 0x2e, 0xef, 0xc7, 0xbe, 0x74, 0x00, 0x53, 0xe9, 0x66, 0xe5, 0x05,
- 0xfb, 0xcc, 0x40, 0xa5, 0x47, 0x36, 0x98, 0x9e, 0x1f, 0x13, 0xc0, 0xe4,
- 0xd5, 0xef, 0x2c, 0x9f, 0x4a, 0xef, 0xf4, 0x94, 0x8d, 0xf9, 0x65, 0x4c,
- 0x04, 0x2a, 0x78, 0x88, 0x62, 0x85, 0xf7, 0x51, 0xd2, 0xeb, 0x3b, 0xa4,
- 0x57, 0x89, 0xf4, 0xfa, 0x82, 0xfe, 0x23, 0xc6, 0x2c, 0x9e, 0x3d, 0x71,
- 0x1f, 0xef, 0x13, 0x99, 0x04, 0x5a, 0xec, 0x31, 0x99, 0xb8, 0x13, 0xe7,
- 0x86, 0xf8, 0x6c, 0xe2, 0x47, 0x6b, 0x5e, 0x4a, 0x5b, 0xeb, 0x66, 0x62,
- 0xcd, 0xa9, 0x77, 0x08, 0x4f, 0x9b, 0x7f, 0xa0, 0xea, 0xe7, 0xc9, 0x4f,
- 0xb3, 0xa3, 0x7f, 0x88, 0xf3, 0x75, 0xcd, 0xca, 0xcf, 0x61, 0x7a, 0x1e,
- 0x8f, 0x3f, 0x42, 0x35, 0x3f, 0xd5, 0x0d, 0x6d, 0xff, 0x92, 0x9c, 0x2c,
- 0x0e, 0x87, 0xd6, 0x3c, 0xfb, 0x02, 0xfe, 0x23, 0xce, 0x2f, 0x0e, 0xeb,
- 0x2f, 0x80, 0xc7, 0x54, 0xea, 0xf1, 0xf0, 0xf4, 0x7d, 0x7c, 0x9e, 0x2a,
- 0x48, 0x69, 0xb4, 0xb2, 0x9f, 0x95, 0xe6, 0xfd, 0x37, 0x81, 0x89, 0x2d,
- 0x54, 0x4b, 0xdb, 0xe7, 0x58, 0xe1, 0x7d, 0x92, 0xfc, 0x22, 0x3a, 0xcc,
- 0xe3, 0x3f, 0x5e, 0xa3, 0xe5, 0x43, 0x70, 0x10, 0xc6, 0x49, 0x05, 0xd4,
- 0x4e, 0x20, 0xe8, 0x7f, 0x32, 0x1d, 0xa4, 0x1a, 0xad, 0xb9, 0x3b, 0x2a,
- 0xee, 0x9c, 0xdb, 0xf7, 0xe6, 0x3c, 0xf7, 0xf1, 0x9a, 0x63, 0x69, 0x35,
- 0xf5, 0x24, 0x9a, 0x7b, 0x7c, 0xe2, 0x0e, 0xa4, 0xea, 0x9a, 0xfb, 0x4e,
- 0x22, 0x9c, 0xf0, 0x08, 0x35, 0x7a, 0x1e, 0x95, 0x79, 0x96, 0xe5, 0x1d,
- 0x54, 0x27, 0x72, 0x9c, 0x49, 0xe3, 0xa4, 0xe2, 0xc0, 0xf2, 0x56, 0x6d,
- 0x76, 0x12, 0xf3, 0xf6, 0x52, 0x19, 0xb3, 0x2e, 0x4f, 0xe3, 0x1d, 0x0a,
- 0xd5, 0xfb, 0x6e, 0x38, 0xeb, 0x79, 0x4f, 0x71, 0x27, 0x76, 0xa4, 0x39,
- 0x4f, 0x93, 0x5c, 0xc8, 0x37, 0xbb, 0x23, 0x3b, 0xd1, 0x9f, 0x0f, 0xe0,
- 0x50, 0x36, 0xbc, 0x7f, 0x2f, 0xe1, 0xba, 0xe1, 0x52, 0x38, 0xb4, 0x4d,
- 0x04, 0x48, 0xdf, 0x54, 0xff, 0xd7, 0x07, 0xa9, 0x4e, 0x56, 0xe8, 0xbf,
- 0x52, 0xcf, 0xbc, 0x44, 0xf5, 0xcc, 0x39, 0xf2, 0x35, 0xdf, 0x5c, 0xad,
- 0xba, 0x6c, 0xc2, 0xc2, 0x4c, 0x6c, 0x23, 0x2e, 0xdb, 0x3a, 0x0b, 0x92,
- 0x8d, 0x71, 0x2e, 0xe2, 0xb3, 0x35, 0x1e, 0xb1, 0x6d, 0xd8, 0xf4, 0x3c,
- 0xd8, 0x1e, 0x44, 0x38, 0xc3, 0x98, 0x53, 0xfa, 0xa6, 0x83, 0xe4, 0x31,
- 0xa5, 0xed, 0xc2, 0x86, 0xd8, 0x2e, 0xf4, 0xeb, 0x7f, 0x02, 0x77, 0x3d,
- 0xc7, 0x23, 0xd9, 0xac, 0xa5, 0x79, 0x2f, 0xb5, 0x77, 0x21, 0x7c, 0x94,
- 0x73, 0x30, 0x55, 0xc3, 0x43, 0xec, 0xbb, 0x3c, 0xff, 0x6d, 0xc6, 0x0a,
- 0xc2, 0x15, 0x35, 0xed, 0x95, 0x3c, 0x7f, 0x7d, 0x9e, 0xcf, 0x74, 0x82,
- 0x6a, 0x53, 0x78, 0xdf, 0x5a, 0x6d, 0xe0, 0x71, 0x8a, 0x31, 0x89, 0x36,
- 0x17, 0xb0, 0x80, 0xcf, 0x2e, 0x57, 0xea, 0x18, 0xe6, 0x77, 0x69, 0x5e,
- 0x60, 0x3a, 0x4e, 0xf6, 0xf1, 0x77, 0xce, 0x28, 0x85, 0xe6, 0xce, 0x96,
- 0x72, 0xff, 0xe4, 0xb0, 0x95, 0xe4, 0xf7, 0x0d, 0xa4, 0xa0, 0x8f, 0xe2,
- 0x6d, 0xb0, 0x0c, 0x2a, 0xea, 0x29, 0x2e, 0x3b, 0xb4, 0x79, 0xb9, 0xb3,
- 0xac, 0x4f, 0x58, 0x13, 0x73, 0xba, 0x70, 0xd2, 0x33, 0x7b, 0xc6, 0xd4,
- 0x81, 0xbd, 0x68, 0xee, 0x7f, 0x57, 0x54, 0xd9, 0x3b, 0x98, 0x93, 0x2d,
- 0x48, 0x2d, 0x31, 0x9c, 0x5b, 0x3e, 0xc9, 0xae, 0x23, 0x3a, 0x2e, 0x10,
- 0x08, 0x5d, 0x6f, 0xef, 0x73, 0x4d, 0xb6, 0xfc, 0x29, 0xcd, 0xcd, 0xdf,
- 0xff, 0xd8, 0xc7, 0x67, 0x2e, 0x4f, 0x65, 0x9f, 0xb7, 0xa2, 0x0b, 0x2b,
- 0xf2, 0x39, 0x4d, 0xbe, 0x1f, 0x34, 0x24, 0x34, 0x68, 0x91, 0xd9, 0x1e,
- 0xfa, 0xfd, 0xd7, 0x79, 0x42, 0xfb, 0xab, 0xfb, 0xf0, 0xcb, 0x09, 0x03,
- 0x07, 0x28, 0x0f, 0xd4, 0x6a, 0xaa, 0x32, 0x81, 0x10, 0xd7, 0xd2, 0x36,
- 0xff, 0x2b, 0x27, 0xc8, 0x0f, 0xeb, 0x14, 0xbb, 0xc6, 0xa8, 0xf0, 0x77,
- 0x99, 0xf8, 0x7b, 0xd0, 0xc7, 0xbe, 0xb0, 0x84, 0xfc, 0x62, 0x3f, 0xf9,
- 0xeb, 0x01, 0xb2, 0x35, 0xaa, 0xe0, 0xc9, 0x0f, 0xd4, 0xfd, 0x20, 0x7f,
- 0x1d, 0x4e, 0xb3, 0xfc, 0x83, 0xfe, 0x5e, 0x3e, 0xde, 0xac, 0xd9, 0x7d,
- 0x55, 0x3d, 0x24, 0x71, 0xdc, 0xb5, 0xe3, 0xa9, 0x19, 0x92, 0xac, 0x6a,
- 0xa6, 0x6b, 0xb0, 0x14, 0x0e, 0x7a, 0xf9, 0x5d, 0x00, 0x02, 0x87, 0xbd,
- 0x7a, 0x25, 0x57, 0xce, 0x50, 0x3e, 0xba, 0x4c, 0x74, 0x1c, 0x8a, 0x35,
- 0x20, 0x45, 0xf9, 0x28, 0xa3, 0x55, 0x6c, 0x49, 0x9b, 0x66, 0x8c, 0x59,
- 0x6f, 0x04, 0xc7, 0xd5, 0x90, 0xcb, 0xd1, 0x3c, 0x70, 0x06, 0x3b, 0xad,
- 0xf3, 0x75, 0x6c, 0x53, 0x2e, 0x1c, 0x6f, 0x99, 0xb6, 0xca, 0x01, 0xe6,
- 0xd7, 0x81, 0xe7, 0x75, 0xb2, 0x99, 0xc5, 0xe1, 0xe0, 0xf3, 0x94, 0x53,
- 0xa7, 0xe6, 0xf4, 0x11, 0xce, 0xcf, 0xdb, 0xe3, 0x5a, 0x96, 0x75, 0x34,
- 0x05, 0x2d, 0x91, 0x47, 0x2f, 0x7d, 0x6f, 0x0a, 0x5e, 0x9e, 0xb3, 0xd5,
- 0x15, 0xd3, 0xaf, 0xfb, 0xe6, 0xde, 0xcb, 0xb1, 0x9f, 0x09, 0xe5, 0xff,
- 0x88, 0x7e, 0xf3, 0x9c, 0x01, 0xc6, 0x32, 0x7c, 0x56, 0xcb, 0xbb, 0xa3,
- 0xdd, 0xcd, 0xfe, 0xa2, 0xf0, 0x3b, 0x09, 0x1b, 0x86, 0xb9, 0x2f, 0xcc,
- 0x3d, 0x1a, 0x07, 0xf6, 0x5e, 0x7d, 0x67, 0x82, 0x3f, 0x3b, 0xb1, 0x69,
- 0x98, 0x7b, 0x11, 0xa7, 0x6f, 0x90, 0xf1, 0x37, 0x94, 0x87, 0x65, 0xf6,
- 0x79, 0xf2, 0xf5, 0x4f, 0xd7, 0xbc, 0x34, 0xc6, 0x39, 0x35, 0x60, 0xdc,
- 0x95, 0x9e, 0xd7, 0xf1, 0x55, 0x9e, 0xce, 0xde, 0x4d, 0x71, 0x27, 0x93,
- 0x56, 0x07, 0x22, 0x0e, 0x7b, 0x7f, 0x2d, 0x55, 0x14, 0x5f, 0xa5, 0x22,
- 0x8d, 0xe7, 0x53, 0xfc, 0x03, 0x87, 0x43, 0xc8, 0x64, 0xbb, 0xf0, 0x8d,
- 0x61, 0xcb, 0x72, 0xb7, 0x39, 0xf1, 0xca, 0x90, 0x85, 0x0f, 0x62, 0xc0,
- 0xcb, 0x43, 0xe1, 0x81, 0x73, 0xc0, 0xb7, 0x6b, 0xa9, 0x46, 0x6e, 0x11,
- 0x6a, 0x37, 0x61, 0x83, 0xd0, 0x7b, 0x68, 0x0e, 0xe6, 0xa1, 0x9e, 0xdd,
- 0x4d, 0xf3, 0xbd, 0x58, 0x00, 0x7e, 0x59, 0xf0, 0xe2, 0x17, 0xc3, 0x3c,
- 0xa7, 0x17, 0xe7, 0x8e, 0xd6, 0xfb, 0x77, 0xd2, 0x5c, 0x07, 0x29, 0xbe,
- 0x77, 0x1d, 0x4b, 0x60, 0xd3, 0x61, 0x81, 0x68, 0x24, 0x81, 0xce, 0x63,
- 0x35, 0xd8, 0x38, 0x2c, 0xe3, 0xfd, 0x78, 0x0d, 0x6e, 0x39, 0x3a, 0xcf,
- 0x47, 0xa5, 0xaf, 0xc1, 0x67, 0x35, 0xf9, 0x1c, 0xdc, 0xc9, 0x2c, 0xc7,
- 0x6c, 0xca, 0x17, 0x59, 0x8e, 0x81, 0x96, 0x15, 0x6c, 0xaf, 0xf4, 0x39,
- 0x9e, 0xa6, 0xfc, 0xf1, 0x78, 0xbb, 0x16, 0x0c, 0x4a, 0x06, 0x96, 0x8f,
- 0x96, 0xef, 0xac, 0x85, 0x75, 0x8a, 0xf7, 0x33, 0x3e, 0x6a, 0xb1, 0xac,
- 0x4d, 0xf1, 0xc8, 0xec, 0xbd, 0x36, 0xae, 0x0d, 0x90, 0x4f, 0x35, 0xe2,
- 0xf1, 0xec, 0xfc, 0x9e, 0x97, 0xd6, 0x73, 0xc9, 0x61, 0xee, 0x52, 0x60,
- 0x5d, 0xa9, 0x32, 0xac, 0x8f, 0x5c, 0x46, 0x24, 0xf8, 0x80, 0xe0, 0xb3,
- 0x22, 0xdc, 0x13, 0xb7, 0xac, 0x37, 0xe3, 0x96, 0x55, 0x88, 0x9b, 0x9e,
- 0x15, 0xab, 0x14, 0x1c, 0x5b, 0xc6, 0xef, 0x2a, 0x84, 0x93, 0x0d, 0x64,
- 0x5f, 0xde, 0x65, 0x5a, 0x70, 0x2b, 0x54, 0xd3, 0xa4, 0x20, 0x17, 0x5a,
- 0xa8, 0xf6, 0x00, 0x8d, 0xfe, 0x43, 0x43, 0xf5, 0xf8, 0xfe, 0xcc, 0xef,
- 0xf2, 0xf1, 0x1d, 0xbb, 0x9f, 0x76, 0x45, 0xc7, 0xba, 0x5a, 0x44, 0x92,
- 0xf7, 0x80, 0x7b, 0xa3, 0x7c, 0xa6, 0xd5, 0xc4, 0x2d, 0xf1, 0x3e, 0xec,
- 0x18, 0xe6, 0x7d, 0xb6, 0x3a, 0xe3, 0xca, 0xb0, 0xf5, 0xd7, 0x1e, 0xa2,
- 0x7f, 0x5d, 0x7b, 0x73, 0xca, 0x6b, 0xbf, 0xe3, 0xe4, 0x34, 0xd6, 0x8f,
- 0xd5, 0xa1, 0x34, 0xa5, 0x95, 0x97, 0x88, 0xe4, 0x1b, 0x3e, 0x44, 0x82,
- 0x0d, 0x14, 0xab, 0x66, 0xc8, 0x77, 0xa7, 0x4a, 0x5c, 0x07, 0x2c, 0x30,
- 0xac, 0xd1, 0x45, 0x98, 0x9c, 0xa1, 0xb9, 0xb2, 0x5a, 0xe7, 0x07, 0x84,
- 0xf3, 0xaa, 0x0d, 0xab, 0xd6, 0x6b, 0x44, 0xce, 0x36, 0x0b, 0x07, 0x66,
- 0xdb, 0x2c, 0xab, 0xab, 0x5d, 0x1b, 0xa8, 0x11, 0xe8, 0x97, 0x0c, 0x2d,
- 0xd1, 0xe2, 0xc0, 0xd7, 0x82, 0x88, 0x74, 0xbe, 0x89, 0x48, 0xcf, 0x05,
- 0x8a, 0x61, 0x4f, 0x95, 0xf8, 0x9c, 0xf0, 0x23, 0xf8, 0xeb, 0xe1, 0x85,
- 0x38, 0x35, 0xd5, 0x3f, 0xd7, 0x13, 0x83, 0xf7, 0xfa, 0x55, 0x06, 0x8e,
- 0x0f, 0x87, 0xc8, 0x7e, 0xdc, 0x14, 0xd7, 0x65, 0x48, 0x4d, 0x90, 0xeb,
- 0xa8, 0x4e, 0x88, 0x3d, 0x66, 0x59, 0x2b, 0x9a, 0x2a, 0x35, 0xcf, 0x8a,
- 0xe9, 0x6b, 0xdf, 0x71, 0x98, 0xef, 0xf7, 0x04, 0x49, 0x7f, 0xcd, 0xa9,
- 0x1d, 0xe2, 0x8c, 0x65, 0xfe, 0x81, 0x20, 0x9e, 0x7b, 0x6a, 0xe0, 0x65,
- 0xbe, 0x65, 0xec, 0x1e, 0xe5, 0x3e, 0x1c, 0xeb, 0x0d, 0xde, 0xce, 0x38,
- 0xef, 0x97, 0xb3, 0x8e, 0xca, 0xde, 0x0d, 0x71, 0x8a, 0x89, 0xc2, 0x4f,
- 0x78, 0xca, 0xf4, 0x74, 0x50, 0x7e, 0xaa, 0x1a, 0xe6, 0xf7, 0x2d, 0x7c,
- 0x38, 0x40, 0x71, 0xe3, 0xb2, 0x5e, 0x8d, 0x43, 0x75, 0x6a, 0x82, 0xeb,
- 0xe9, 0x27, 0x4b, 0xdc, 0x33, 0xdc, 0x89, 0xed, 0xfc, 0xbe, 0x4a, 0x69,
- 0xb5, 0x7d, 0xb6, 0x90, 0xae, 0x11, 0x36, 0x60, 0x3a, 0xe6, 0xd7, 0xef,
- 0xc4, 0x92, 0x21, 0xd6, 0xe3, 0xc7, 0x6b, 0x82, 0x24, 0xa3, 0xc7, 0xc9,
- 0x2e, 0x24, 0xa3, 0x03, 0xf2, 0x90, 0x65, 0xdd, 0x18, 0xbf, 0x76, 0x0e,
- 0xad, 0xff, 0x82, 0x83, 0xea, 0x3b, 0x07, 0xef, 0xeb, 0xa9, 0x89, 0x13,
- 0xe2, 0xda, 0x39, 0x0b, 0x35, 0xdc, 0x4f, 0x34, 0xa7, 0x2a, 0x79, 0xe9,
- 0x38, 0xe5, 0xa5, 0x97, 0x73, 0xec, 0x23, 0xf5, 0x06, 0xfb, 0x88, 0x44,
- 0xb1, 0x76, 0x7d, 0x3a, 0x84, 0x0b, 0x3a, 0x34, 0x37, 0x62, 0x44, 0x77,
- 0xa4, 0xbb, 0x63, 0x0e, 0xf3, 0xb9, 0x28, 0xfe, 0x4f, 0xe5, 0x78, 0xaf,
- 0x4d, 0xa0, 0x46, 0x63, 0x1b, 0xb0, 0x73, 0x01, 0xc5, 0xb4, 0x7e, 0xd4,
- 0xae, 0x06, 0x2e, 0x0d, 0xf1, 0xfe, 0x8c, 0x86, 0x03, 0xa5, 0x01, 0xd1,
- 0x30, 0xf4, 0x5b, 0x2b, 0x54, 0x35, 0xbf, 0x07, 0xf8, 0x30, 0xef, 0x01,
- 0x92, 0x0d, 0xf4, 0xdb, 0xe7, 0x7c, 0xde, 0x4c, 0xf3, 0x39, 0x9f, 0x70,
- 0x68, 0x13, 0xf9, 0x4e, 0x2f, 0x9a, 0xf5, 0x69, 0xc2, 0xce, 0xb3, 0x44,
- 0x67, 0x93, 0xa8, 0xec, 0x73, 0x45, 0xe6, 0xf6, 0xe9, 0x96, 0xe5, 0x3b,
- 0x45, 0x4d, 0x81, 0x69, 0x0a, 0x10, 0x4d, 0x1d, 0xa2, 0xfa, 0xd8, 0x06,
- 0xe1, 0x3b, 0xd6, 0x25, 0xa4, 0x02, 0xc7, 0xe4, 0x3a, 0x63, 0x4f, 0x8e,
- 0xf3, 0xd9, 0x66, 0xe1, 0x3c, 0xba, 0x45, 0x78, 0x0b, 0x3d, 0xc2, 0x7f,
- 0xcc, 0xc4, 0xfd, 0xf1, 0x2e, 0x9c, 0x1b, 0xe6, 0xb3, 0x6c, 0xf7, 0x89,
- 0x9a, 0xb9, 0xbd, 0x39, 0x6f, 0xa1, 0xd1, 0x5f, 0x48, 0x73, 0x7f, 0xf7,
- 0xe3, 0x35, 0xe9, 0xa1, 0x45, 0xfe, 0xa7, 0xc6, 0x02, 0xfe, 0x27, 0xc7,
- 0xd4, 0xfe, 0x7d, 0xc2, 0xb2, 0x76, 0xc6, 0xfe, 0x03, 0xeb, 0xd0, 0x6a,
- 0x8e, 0x55, 0xf0, 0xc1, 0x6e, 0x92, 0xc7, 0x36, 0xca, 0x2d, 0x93, 0x7a,
- 0xf3, 0x1c, 0x16, 0x51, 0x53, 0xfc, 0xee, 0x1b, 0xfd, 0x77, 0x73, 0x6e,
- 0xe3, 0x7d, 0x4d, 0x67, 0x3b, 0x28, 0xee, 0x7e, 0xc6, 0x6b, 0xcd, 0x10,
- 0x9f, 0x51, 0xeb, 0x87, 0xff, 0x4b, 0xf6, 0xf5, 0xce, 0x7d, 0xb6, 0xaf,
- 0x97, 0x78, 0x52, 0xa8, 0xe5, 0x19, 0xe2, 0xb7, 0xca, 0xf1, 0xb9, 0x3d,
- 0xbd, 0xb9, 0xfd, 0xbc, 0x4e, 0xe1, 0x2b, 0x70, 0x7d, 0x1e, 0x30, 0x5e,
- 0x1f, 0xea, 0x10, 0xde, 0x63, 0xc3, 0x94, 0x1f, 0x37, 0x10, 0xcf, 0x7c,
- 0x76, 0xac, 0x4b, 0xf8, 0x0b, 0x9b, 0x85, 0x8f, 0xf8, 0xac, 0x26, 0x3e,
- 0x71, 0xcc, 0x23, 0xbc, 0xc4, 0xa3, 0x87, 0x78, 0xf4, 0xce, 0xf1, 0xe8,
- 0x29, 0x04, 0xfd, 0xe9, 0x74, 0xbd, 0xff, 0xd1, 0x31, 0xc5, 0xbf, 0x6f,
- 0xcc, 0xb2, 0xde, 0xd7, 0x15, 0x3f, 0xf3, 0xf5, 0xaa, 0xfe, 0x45, 0xbe,
- 0x6e, 0x20, 0xbe, 0x2a, 0x7b, 0xb1, 0xa4, 0xc3, 0x14, 0xeb, 0x90, 0xcf,
- 0x71, 0xcc, 0xf3, 0x75, 0x30, 0xcd, 0xfb, 0x95, 0xbc, 0x6f, 0x39, 0x20,
- 0x56, 0x10, 0x5f, 0x65, 0xe2, 0x6b, 0xe5, 0x97, 0xf0, 0xf5, 0xe1, 0x35,
- 0x7c, 0xbd, 0xfa, 0xf7, 0xf2, 0xe5, 0x11, 0xcb, 0x87, 0x39, 0x0e, 0xdd,
- 0x66, 0xc8, 0xc3, 0x16, 0x61, 0x47, 0x07, 0xbe, 0x3f, 0x05, 0x14, 0xb3,
- 0xbb, 0x20, 0x53, 0xbc, 0x39, 0x1d, 0x8f, 0x84, 0x5e, 0xa1, 0x7a, 0x72,
- 0xba, 0xe4, 0x15, 0xcb, 0xec, 0x3d, 0x59, 0xac, 0x90, 0x89, 0xa6, 0x19,
- 0xfb, 0x5d, 0x33, 0xe8, 0xb5, 0x1a, 0xeb, 0x52, 0x3b, 0xbb, 0x15, 0x91,
- 0x72, 0xc4, 0xd1, 0x25, 0x12, 0x05, 0xde, 0x83, 0xdd, 0x22, 0x56, 0xda,
- 0xfb, 0xaf, 0x9d, 0xe2, 0xfa, 0x42, 0x87, 0x68, 0x21, 0xbb, 0x68, 0x3e,
- 0xc6, 0xe7, 0xc1, 0x36, 0x8b, 0xe6, 0x39, 0x79, 0x2c, 0x27, 0x79, 0x0c,
- 0x7d, 0x4e, 0x1e, 0x1b, 0x6c, 0x79, 0xfc, 0x4c, 0xbf, 0x78, 0x4d, 0x0f,
- 0x8d, 0xeb, 0x2a, 0xca, 0x86, 0x54, 0x3b, 0xd5, 0xce, 0xd5, 0x4e, 0x6f,
- 0xc5, 0xf8, 0x9c, 0x8f, 0x69, 0xd5, 0x68, 0x08, 0x39, 0x0d, 0xb5, 0xe7,
- 0xb4, 0xd0, 0x52, 0xf7, 0x89, 0xe4, 0x26, 0x1f, 0xd5, 0x3f, 0x3b, 0x62,
- 0x91, 0xe4, 0x72, 0x11, 0x49, 0x38, 0x05, 0xe7, 0x15, 0x5d, 0xae, 0x2a,
- 0x9a, 0xd8, 0x47, 0xf1, 0xed, 0xc5, 0x9c, 0x44, 0xd8, 0x81, 0xdf, 0x3f,
- 0x73, 0xe2, 0x46, 0x82, 0x12, 0x4f, 0x10, 0xee, 0x78, 0x3c, 0xdb, 0x87,
- 0x27, 0xf2, 0xbd, 0x78, 0x3c, 0xff, 0x77, 0xde, 0xb5, 0x91, 0xbd, 0x46,
- 0x63, 0xa2, 0x72, 0x16, 0xe1, 0xe3, 0xc4, 0x75, 0x11, 0x96, 0xcd, 0x89,
- 0x16, 0x39, 0xc2, 0xb5, 0xae, 0xf3, 0x77, 0xdf, 0xd5, 0xd8, 0x17, 0x7b,
- 0x56, 0xbd, 0x64, 0x63, 0x91, 0x93, 0x6d, 0xc7, 0xec, 0x33, 0x52, 0xe5,
- 0x95, 0x7b, 0xec, 0x77, 0x41, 0x7d, 0xab, 0xef, 0xd2, 0xd8, 0x1f, 0x4e,
- 0xc4, 0xd7, 0xdb, 0xf9, 0xb5, 0x71, 0x6d, 0xe5, 0x3d, 0x99, 0xe0, 0xda,
- 0x4a, 0xaf, 0x26, 0xb0, 0x36, 0x6a, 0x7f, 0x86, 0xd6, 0x56, 0xf6, 0xba,
- 0xf5, 0xb5, 0x4d, 0xf6, 0x67, 0x74, 0x6d, 0xc5, 0xa7, 0xb4, 0xb5, 0x9a,
- 0xfd, 0x19, 0x5f, 0x5b, 0xc9, 0xcb, 0x2d, 0x6b, 0x97, 0x5e, 0x7d, 0xbf,
- 0x86, 0xff, 0xfe, 0x17, 0x9f, 0xed, 0x4e, 0xb2, 0x20, 0x3b, 0x00, 0x00,
- 0x00 };
-
-static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
- 0x80000940, 0x80000900, 0x80080100, 0x80080080, 0x80080000, 0x800e0000,
- 0x80080080, 0x80080000, 0x80000a80, 0x80000a00, 0x80000980, 0x80000900,
- 0x00000000 };
-
-static struct fw_info bnx2_txp_fw_09 = {
- /* Firmware version: 4.4.23 */
- .ver_major = 0x4,
- .ver_minor = 0x4,
- .ver_fix = 0x17,
-
- .start_addr = 0x08000094,
-
- .text_addr = 0x08000000,
- .text_len = 0x3b1c,
- .text_index = 0x0,
- .gz_text = bnx2_TXP_b09FwText,
- .gz_text_len = sizeof(bnx2_TXP_b09FwText),
-
- .data_addr = 0x00000000,
- .data_len = 0x0,
- .data_index = 0x0,
- .data = bnx2_TXP_b09FwData,
-
- .sbss_addr = 0x08003b80,
- .sbss_len = 0x6c,
- .sbss_index = 0x0,
-
- .bss_addr = 0x08003bec,
- .bss_len = 0x24c,
- .bss_index = 0x0,
-
- .rodata_addr = 0x08003b1c,
- .rodata_len = 0x30,
- .rodata_index = 0x0,
- .rodata = bnx2_TXP_b09FwRodata,
-};
-
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
deleted file mode 100644
index fd705d1295a..00000000000
--- a/drivers/net/bnx2x.h
+++ /dev/null
@@ -1,1165 +0,0 @@
-/* bnx2x.h: Broadcom Everest network driver.
- *
- * Copyright (c) 2007-2008 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * Maintained by: Eilon Greenstein <eilong@broadcom.com>
- * Written by: Eliezer Tamir
- * Based on code from Michael Chan's bnx2 driver
- */
-
-#ifndef BNX2X_H
-#define BNX2X_H
-
-/* compilation time flags */
-
-/* define this to make the driver freeze on error to allow getting debug info
- * (you will need to reboot afterwards) */
-/* #define BNX2X_STOP_ON_ERROR */
-
-/* error/debug prints */
-
-#define DRV_MODULE_NAME "bnx2x"
-#define PFX DRV_MODULE_NAME ": "
-
-/* for messages that are currently off */
-#define BNX2X_MSG_OFF 0
-#define BNX2X_MSG_MCP 0x010000 /* was: NETIF_MSG_HW */
-#define BNX2X_MSG_STATS 0x020000 /* was: NETIF_MSG_TIMER */
-#define BNX2X_MSG_NVM 0x040000 /* was: NETIF_MSG_HW */
-#define BNX2X_MSG_DMAE 0x080000 /* was: NETIF_MSG_HW */
-#define BNX2X_MSG_SP 0x100000 /* was: NETIF_MSG_INTR */
-#define BNX2X_MSG_FP 0x200000 /* was: NETIF_MSG_INTR */
-
-#define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */
-
-/* regular debug print */
-#define DP(__mask, __fmt, __args...) do { \
- if (bp->msglevel & (__mask)) \
- printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
- bp->dev ? (bp->dev->name) : "?", ##__args); \
- } while (0)
-
-/* errors debug print */
-#define BNX2X_DBG_ERR(__fmt, __args...) do { \
- if (bp->msglevel & NETIF_MSG_PROBE) \
- printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
- bp->dev ? (bp->dev->name) : "?", ##__args); \
- } while (0)
-
-/* for errors (never masked) */
-#define BNX2X_ERR(__fmt, __args...) do { \
- printk(KERN_ERR "[%s:%d(%s)]" __fmt, __func__, __LINE__, \
- bp->dev ? (bp->dev->name) : "?", ##__args); \
- } while (0)
-
-/* before we have a dev->name use dev_info() */
-#define BNX2X_DEV_INFO(__fmt, __args...) do { \
- if (bp->msglevel & NETIF_MSG_PROBE) \
- dev_info(&bp->pdev->dev, __fmt, ##__args); \
- } while (0)
-
-
-#ifdef BNX2X_STOP_ON_ERROR
-#define bnx2x_panic() do { \
- bp->panic = 1; \
- BNX2X_ERR("driver assert\n"); \
- bnx2x_int_disable(bp); \
- bnx2x_panic_dump(bp); \
- } while (0)
-#else
-#define bnx2x_panic() do { \
- BNX2X_ERR("driver assert\n"); \
- bnx2x_panic_dump(bp); \
- } while (0)
-#endif
-
-
-#ifdef NETIF_F_HW_VLAN_TX
-#define BCM_VLAN 1
-#endif
-
-
-#define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff)
-#define U64_HI(x) (u32)(((u64)(x)) >> 32)
-#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo))
-
-
-#define REG_ADDR(bp, offset) (bp->regview + offset)
-
-#define REG_RD(bp, offset) readl(REG_ADDR(bp, offset))
-#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
-#define REG_RD64(bp, offset) readq(REG_ADDR(bp, offset))
-
-#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
-#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
-#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
-#define REG_WR32(bp, offset, val) REG_WR(bp, offset, val)
-
-#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset)
-#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val)
-
-#define REG_RD_DMAE(bp, offset, valp, len32) \
- do { \
- bnx2x_read_dmae(bp, offset, len32);\
- memcpy(valp, bnx2x_sp(bp, wb_data[0]), len32 * 4); \
- } while (0)
-
-#define REG_WR_DMAE(bp, offset, valp, len32) \
- do { \
- memcpy(bnx2x_sp(bp, wb_data[0]), valp, len32 * 4); \
- bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \
- offset, len32); \
- } while (0)
-
-#define SHMEM_ADDR(bp, field) (bp->common.shmem_base + \
- offsetof(struct shmem_region, field))
-#define SHMEM_RD(bp, field) REG_RD(bp, SHMEM_ADDR(bp, field))
-#define SHMEM_WR(bp, field, val) REG_WR(bp, SHMEM_ADDR(bp, field), val)
-
-#define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg)
-#define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val)
-
-
-/* fast path */
-
-struct sw_rx_bd {
- struct sk_buff *skb;
- DECLARE_PCI_UNMAP_ADDR(mapping)
-};
-
-struct sw_tx_bd {
- struct sk_buff *skb;
- u16 first_bd;
-};
-
-struct sw_rx_page {
- struct page *page;
- DECLARE_PCI_UNMAP_ADDR(mapping)
-};
-
-
-/* MC hsi */
-#define BCM_PAGE_SHIFT 12
-#define BCM_PAGE_SIZE (1 << BCM_PAGE_SHIFT)
-#define BCM_PAGE_MASK (~(BCM_PAGE_SIZE - 1))
-#define BCM_PAGE_ALIGN(addr) (((addr) + BCM_PAGE_SIZE - 1) & BCM_PAGE_MASK)
-
-#define PAGES_PER_SGE_SHIFT 0
-#define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT)
-
-#define BCM_RX_ETH_PAYLOAD_ALIGN 64
-
-/* SGE ring related macros */
-#define NUM_RX_SGE_PAGES 2
-#define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
-#define MAX_RX_SGE_CNT (RX_SGE_CNT - 2)
-/* RX_SGE_CNT is promised to be a power of 2 */
-#define RX_SGE_MASK (RX_SGE_CNT - 1)
-#define NUM_RX_SGE (RX_SGE_CNT * NUM_RX_SGE_PAGES)
-#define MAX_RX_SGE (NUM_RX_SGE - 1)
-#define NEXT_SGE_IDX(x) ((((x) & RX_SGE_MASK) == \
- (MAX_RX_SGE_CNT - 1)) ? (x) + 3 : (x) + 1)
-#define RX_SGE(x) ((x) & MAX_RX_SGE)
-
-/* SGE producer mask related macros */
-/* Number of bits in one sge_mask array element */
-#define RX_SGE_MASK_ELEM_SZ 64
-#define RX_SGE_MASK_ELEM_SHIFT 6
-#define RX_SGE_MASK_ELEM_MASK ((u64)RX_SGE_MASK_ELEM_SZ - 1)
-
-/* Creates a bitmask of all ones in less significant bits.
- idx - index of the most significant bit in the created mask */
-#define RX_SGE_ONES_MASK(idx) \
- (((u64)0x1 << (((idx) & RX_SGE_MASK_ELEM_MASK) + 1)) - 1)
-#define RX_SGE_MASK_ELEM_ONE_MASK ((u64)(~0))
-
-/* Number of u64 elements in SGE mask array */
-#define RX_SGE_MASK_LEN ((NUM_RX_SGE_PAGES * RX_SGE_CNT) / \
- RX_SGE_MASK_ELEM_SZ)
-#define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1)
-#define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK)
-
-
-struct bnx2x_fastpath {
-
- struct napi_struct napi;
-
- struct host_status_block *status_blk;
- dma_addr_t status_blk_mapping;
-
- struct eth_tx_db_data *hw_tx_prods;
- dma_addr_t tx_prods_mapping;
-
- struct sw_tx_bd *tx_buf_ring;
-
- struct eth_tx_bd *tx_desc_ring;
- dma_addr_t tx_desc_mapping;
-
- struct sw_rx_bd *rx_buf_ring; /* BDs mappings ring */
- struct sw_rx_page *rx_page_ring; /* SGE pages mappings ring */
-
- struct eth_rx_bd *rx_desc_ring;
- dma_addr_t rx_desc_mapping;
-
- union eth_rx_cqe *rx_comp_ring;
- dma_addr_t rx_comp_mapping;
-
- /* SGE ring */
- struct eth_rx_sge *rx_sge_ring;
- dma_addr_t rx_sge_mapping;
-
- u64 sge_mask[RX_SGE_MASK_LEN];
-
- int state;
-#define BNX2X_FP_STATE_CLOSED 0
-#define BNX2X_FP_STATE_IRQ 0x80000
-#define BNX2X_FP_STATE_OPENING 0x90000
-#define BNX2X_FP_STATE_OPEN 0xa0000
-#define BNX2X_FP_STATE_HALTING 0xb0000
-#define BNX2X_FP_STATE_HALTED 0xc0000
-
- u8 index; /* number in fp array */
- u8 cl_id; /* eth client id */
- u8 sb_id; /* status block number in HW */
-#define FP_IDX(fp) (fp->index)
-#define FP_CL_ID(fp) (fp->cl_id)
-#define BP_CL_ID(bp) (bp->fp[0].cl_id)
-#define FP_SB_ID(fp) (fp->sb_id)
-#define CNIC_SB_ID 0
-
- u16 tx_pkt_prod;
- u16 tx_pkt_cons;
- u16 tx_bd_prod;
- u16 tx_bd_cons;
- u16 *tx_cons_sb;
-
- u16 fp_c_idx;
- u16 fp_u_idx;
-
- u16 rx_bd_prod;
- u16 rx_bd_cons;
- u16 rx_comp_prod;
- u16 rx_comp_cons;
- u16 rx_sge_prod;
- /* The last maximal completed SGE */
- u16 last_max_sge;
- u16 *rx_cons_sb;
- u16 *rx_bd_cons_sb;
-
- unsigned long tx_pkt,
- rx_pkt,
- rx_calls;
- /* TPA related */
- struct sw_rx_bd tpa_pool[ETH_MAX_AGGREGATION_QUEUES_E1H];
- u8 tpa_state[ETH_MAX_AGGREGATION_QUEUES_E1H];
-#define BNX2X_TPA_START 1
-#define BNX2X_TPA_STOP 2
- u8 disable_tpa;
-#ifdef BNX2X_STOP_ON_ERROR
- u64 tpa_queue_used;
-#endif
-
- struct bnx2x *bp; /* parent */
-};
-
-#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
-
-#define BNX2X_HAS_TX_WORK(fp) \
- ((fp->tx_pkt_prod != le16_to_cpu(*fp->tx_cons_sb)) || \
- (fp->tx_pkt_prod != fp->tx_pkt_cons))
-
-#define BNX2X_HAS_RX_WORK(fp) \
- (fp->rx_comp_cons != rx_cons_sb)
-
-#define BNX2X_HAS_WORK(fp) (BNX2X_HAS_RX_WORK(fp) || BNX2X_HAS_TX_WORK(fp))
-
-
-/* MC hsi */
-#define MAX_FETCH_BD 13 /* HW max BDs per packet */
-#define RX_COPY_THRESH 92
-
-#define NUM_TX_RINGS 16
-#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_tx_bd))
-#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
-#define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS)
-#define MAX_TX_BD (NUM_TX_BD - 1)
-#define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2)
-#define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \
- (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
-#define TX_BD(x) ((x) & MAX_TX_BD)
-#define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT)
-
-/* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */
-#define NUM_RX_RINGS 8
-#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
-#define MAX_RX_DESC_CNT (RX_DESC_CNT - 2)
-#define RX_DESC_MASK (RX_DESC_CNT - 1)
-#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS)
-#define MAX_RX_BD (NUM_RX_BD - 1)
-#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
-#define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \
- (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1)
-#define RX_BD(x) ((x) & MAX_RX_BD)
-
-/* As long as CQE is 4 times bigger than BD entry we have to allocate
- 4 times more pages for CQ ring in order to keep it balanced with
- BD ring */
-#define NUM_RCQ_RINGS (NUM_RX_RINGS * 4)
-#define RCQ_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe))
-#define MAX_RCQ_DESC_CNT (RCQ_DESC_CNT - 1)
-#define NUM_RCQ_BD (RCQ_DESC_CNT * NUM_RCQ_RINGS)
-#define MAX_RCQ_BD (NUM_RCQ_BD - 1)
-#define MAX_RCQ_AVAIL (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2)
-#define NEXT_RCQ_IDX(x) ((((x) & MAX_RCQ_DESC_CNT) == \
- (MAX_RCQ_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
-#define RCQ_BD(x) ((x) & MAX_RCQ_BD)
-
-
-/* This is needed for determining of last_max */
-#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b))
-
-#define __SGE_MASK_SET_BIT(el, bit) \
- do { \
- el = ((el) | ((u64)0x1 << (bit))); \
- } while (0)
-
-#define __SGE_MASK_CLEAR_BIT(el, bit) \
- do { \
- el = ((el) & (~((u64)0x1 << (bit)))); \
- } while (0)
-
-#define SGE_MASK_SET_BIT(fp, idx) \
- __SGE_MASK_SET_BIT(fp->sge_mask[(idx) >> RX_SGE_MASK_ELEM_SHIFT], \
- ((idx) & RX_SGE_MASK_ELEM_MASK))
-
-#define SGE_MASK_CLEAR_BIT(fp, idx) \
- __SGE_MASK_CLEAR_BIT(fp->sge_mask[(idx) >> RX_SGE_MASK_ELEM_SHIFT], \
- ((idx) & RX_SGE_MASK_ELEM_MASK))
-
-
-/* used on a CID received from the HW */
-#define SW_CID(x) (le32_to_cpu(x) & \
- (COMMON_RAMROD_ETH_RX_CQE_CID >> 7))
-#define CQE_CMD(x) (le32_to_cpu(x) >> \
- COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT)
-
-#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr_hi), \
- le32_to_cpu((bd)->addr_lo))
-#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
-
-
-#define DPM_TRIGER_TYPE 0x40
-#define DOORBELL(bp, cid, val) \
- do { \
- writel((u32)val, (bp)->doorbells + (BCM_PAGE_SIZE * cid) + \
- DPM_TRIGER_TYPE); \
- } while (0)
-
-
-/* TX CSUM helpers */
-#define SKB_CS_OFF(skb) (offsetof(struct tcphdr, check) - \
- skb->csum_offset)
-#define SKB_CS(skb) (*(u16 *)(skb_transport_header(skb) + \
- skb->csum_offset))
-
-#define pbd_tcp_flags(skb) (ntohl(tcp_flag_word(tcp_hdr(skb)))>>16 & 0xff)
-
-#define XMIT_PLAIN 0
-#define XMIT_CSUM_V4 0x1
-#define XMIT_CSUM_V6 0x2
-#define XMIT_CSUM_TCP 0x4
-#define XMIT_GSO_V4 0x8
-#define XMIT_GSO_V6 0x10
-
-#define XMIT_CSUM (XMIT_CSUM_V4 | XMIT_CSUM_V6)
-#define XMIT_GSO (XMIT_GSO_V4 | XMIT_GSO_V6)
-
-
-/* stuff added to make the code fit 80Col */
-
-#define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE)
-
-#define TPA_TYPE_START ETH_FAST_PATH_RX_CQE_START_FLG
-#define TPA_TYPE_END ETH_FAST_PATH_RX_CQE_END_FLG
-#define TPA_TYPE(cqe_fp_flags) ((cqe_fp_flags) & \
- (TPA_TYPE_START | TPA_TYPE_END))
-
-#define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG
-
-#define BNX2X_IP_CSUM_ERR(cqe) \
- (!((cqe)->fast_path_cqe.status_flags & \
- ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG) && \
- ((cqe)->fast_path_cqe.type_error_flags & \
- ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG))
-
-#define BNX2X_L4_CSUM_ERR(cqe) \
- (!((cqe)->fast_path_cqe.status_flags & \
- ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) && \
- ((cqe)->fast_path_cqe.type_error_flags & \
- ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG))
-
-#define BNX2X_RX_CSUM_OK(cqe) \
- (!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe)))
-
-#define BNX2X_RX_SUM_FIX(cqe) \
- ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
- PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
- (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
-
-
-#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES)
-#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES)
-
-#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS
-#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS
-#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS
-
-#define BNX2X_RX_SB_INDEX \
- (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX])
-
-#define BNX2X_RX_SB_BD_INDEX \
- (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_BD_INDEX])
-
-#define BNX2X_RX_SB_INDEX_NUM \
- (((U_SB_ETH_RX_CQ_INDEX << \
- USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \
- USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) | \
- ((U_SB_ETH_RX_BD_INDEX << \
- USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT) & \
- USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER))
-
-#define BNX2X_TX_SB_INDEX \
- (&fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX])
-
-
-/* end of fast path */
-
-/* common */
-
-struct bnx2x_common {
-
- u32 chip_id;
-/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
-#define CHIP_ID(bp) (bp->common.chip_id & 0xfffffff0)
-
-#define CHIP_NUM(bp) (bp->common.chip_id >> 16)
-#define CHIP_NUM_57710 0x164e
-#define CHIP_NUM_57711 0x164f
-#define CHIP_NUM_57711E 0x1650
-#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710)
-#define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711)
-#define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E)
-#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \
- CHIP_IS_57711E(bp))
-#define IS_E1H_OFFSET CHIP_IS_E1H(bp)
-
-#define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000)
-#define CHIP_REV_Ax 0x00000000
-/* assume maximum 5 revisions */
-#define CHIP_REV_IS_SLOW(bp) (CHIP_REV(bp) > 0x00005000)
-/* Emul versions are A=>0xe, B=>0xc, C=>0xa, D=>8, E=>6 */
-#define CHIP_REV_IS_EMUL(bp) ((CHIP_REV_IS_SLOW(bp)) && \
- !(CHIP_REV(bp) & 0x00001000))
-/* FPGA versions are A=>0xf, B=>0xd, C=>0xb, D=>9, E=>7 */
-#define CHIP_REV_IS_FPGA(bp) ((CHIP_REV_IS_SLOW(bp)) && \
- (CHIP_REV(bp) & 0x00001000))
-
-#define CHIP_TIME(bp) ((CHIP_REV_IS_EMUL(bp)) ? 2000 : \
- ((CHIP_REV_IS_FPGA(bp)) ? 200 : 1))
-
-#define CHIP_METAL(bp) (bp->common.chip_id & 0x00000ff0)
-#define CHIP_BOND_ID(bp) (bp->common.chip_id & 0x0000000f)
-
- int flash_size;
-#define NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */
-#define NVRAM_TIMEOUT_COUNT 30000
-#define NVRAM_PAGE_SIZE 256
-
- u32 shmem_base;
-
- u32 hw_config;
- u32 board;
-
- u32 bc_ver;
-
- char *name;
-};
-
-
-/* end of common */
-
-/* port */
-
-struct nig_stats {
- u32 brb_discard;
- u32 brb_packet;
- u32 brb_truncate;
- u32 flow_ctrl_discard;
- u32 flow_ctrl_octets;
- u32 flow_ctrl_packet;
- u32 mng_discard;
- u32 mng_octet_inp;
- u32 mng_octet_out;
- u32 mng_packet_inp;
- u32 mng_packet_out;
- u32 pbf_octets;
- u32 pbf_packet;
- u32 safc_inp;
- u32 egress_mac_pkt0_lo;
- u32 egress_mac_pkt0_hi;
- u32 egress_mac_pkt1_lo;
- u32 egress_mac_pkt1_hi;
-};
-
-struct bnx2x_port {
- u32 pmf;
-
- u32 link_config;
-
- u32 supported;
-/* link settings - missing defines */
-#define SUPPORTED_2500baseX_Full (1 << 15)
-
- u32 advertising;
-/* link settings - missing defines */
-#define ADVERTISED_2500baseX_Full (1 << 15)
-
- u32 phy_addr;
-
- /* used to synchronize phy accesses */
- struct mutex phy_mutex;
-
- u32 port_stx;
-
- struct nig_stats old_nig_stats;
-};
-
-/* end of port */
-
-
-enum bnx2x_stats_event {
- STATS_EVENT_PMF = 0,
- STATS_EVENT_LINK_UP,
- STATS_EVENT_UPDATE,
- STATS_EVENT_STOP,
- STATS_EVENT_MAX
-};
-
-enum bnx2x_stats_state {
- STATS_STATE_DISABLED = 0,
- STATS_STATE_ENABLED,
- STATS_STATE_MAX
-};
-
-struct bnx2x_eth_stats {
- u32 total_bytes_received_hi;
- u32 total_bytes_received_lo;
- u32 total_bytes_transmitted_hi;
- u32 total_bytes_transmitted_lo;
- u32 total_unicast_packets_received_hi;
- u32 total_unicast_packets_received_lo;
- u32 total_multicast_packets_received_hi;
- u32 total_multicast_packets_received_lo;
- u32 total_broadcast_packets_received_hi;
- u32 total_broadcast_packets_received_lo;
- u32 total_unicast_packets_transmitted_hi;
- u32 total_unicast_packets_transmitted_lo;
- u32 total_multicast_packets_transmitted_hi;
- u32 total_multicast_packets_transmitted_lo;
- u32 total_broadcast_packets_transmitted_hi;
- u32 total_broadcast_packets_transmitted_lo;
- u32 valid_bytes_received_hi;
- u32 valid_bytes_received_lo;
-
- u32 error_bytes_received_hi;
- u32 error_bytes_received_lo;
-
- u32 rx_stat_ifhcinbadoctets_hi;
- u32 rx_stat_ifhcinbadoctets_lo;
- u32 tx_stat_ifhcoutbadoctets_hi;
- u32 tx_stat_ifhcoutbadoctets_lo;
- u32 rx_stat_dot3statsfcserrors_hi;
- u32 rx_stat_dot3statsfcserrors_lo;
- u32 rx_stat_dot3statsalignmenterrors_hi;
- u32 rx_stat_dot3statsalignmenterrors_lo;
- u32 rx_stat_dot3statscarriersenseerrors_hi;
- u32 rx_stat_dot3statscarriersenseerrors_lo;
- u32 rx_stat_falsecarriererrors_hi;
- u32 rx_stat_falsecarriererrors_lo;
- u32 rx_stat_etherstatsundersizepkts_hi;
- u32 rx_stat_etherstatsundersizepkts_lo;
- u32 rx_stat_dot3statsframestoolong_hi;
- u32 rx_stat_dot3statsframestoolong_lo;
- u32 rx_stat_etherstatsfragments_hi;
- u32 rx_stat_etherstatsfragments_lo;
- u32 rx_stat_etherstatsjabbers_hi;
- u32 rx_stat_etherstatsjabbers_lo;
- u32 rx_stat_maccontrolframesreceived_hi;
- u32 rx_stat_maccontrolframesreceived_lo;
- u32 rx_stat_bmac_xpf_hi;
- u32 rx_stat_bmac_xpf_lo;
- u32 rx_stat_bmac_xcf_hi;
- u32 rx_stat_bmac_xcf_lo;
- u32 rx_stat_xoffstateentered_hi;
- u32 rx_stat_xoffstateentered_lo;
- u32 rx_stat_xonpauseframesreceived_hi;
- u32 rx_stat_xonpauseframesreceived_lo;
- u32 rx_stat_xoffpauseframesreceived_hi;
- u32 rx_stat_xoffpauseframesreceived_lo;
- u32 tx_stat_outxonsent_hi;
- u32 tx_stat_outxonsent_lo;
- u32 tx_stat_outxoffsent_hi;
- u32 tx_stat_outxoffsent_lo;
- u32 tx_stat_flowcontroldone_hi;
- u32 tx_stat_flowcontroldone_lo;
- u32 tx_stat_etherstatscollisions_hi;
- u32 tx_stat_etherstatscollisions_lo;
- u32 tx_stat_dot3statssinglecollisionframes_hi;
- u32 tx_stat_dot3statssinglecollisionframes_lo;
- u32 tx_stat_dot3statsmultiplecollisionframes_hi;
- u32 tx_stat_dot3statsmultiplecollisionframes_lo;
- u32 tx_stat_dot3statsdeferredtransmissions_hi;
- u32 tx_stat_dot3statsdeferredtransmissions_lo;
- u32 tx_stat_dot3statsexcessivecollisions_hi;
- u32 tx_stat_dot3statsexcessivecollisions_lo;
- u32 tx_stat_dot3statslatecollisions_hi;
- u32 tx_stat_dot3statslatecollisions_lo;
- u32 tx_stat_etherstatspkts64octets_hi;
- u32 tx_stat_etherstatspkts64octets_lo;
- u32 tx_stat_etherstatspkts65octetsto127octets_hi;
- u32 tx_stat_etherstatspkts65octetsto127octets_lo;
- u32 tx_stat_etherstatspkts128octetsto255octets_hi;
- u32 tx_stat_etherstatspkts128octetsto255octets_lo;
- u32 tx_stat_etherstatspkts256octetsto511octets_hi;
- u32 tx_stat_etherstatspkts256octetsto511octets_lo;
- u32 tx_stat_etherstatspkts512octetsto1023octets_hi;
- u32 tx_stat_etherstatspkts512octetsto1023octets_lo;
- u32 tx_stat_etherstatspkts1024octetsto1522octets_hi;
- u32 tx_stat_etherstatspkts1024octetsto1522octets_lo;
- u32 tx_stat_etherstatspktsover1522octets_hi;
- u32 tx_stat_etherstatspktsover1522octets_lo;
- u32 tx_stat_bmac_2047_hi;
- u32 tx_stat_bmac_2047_lo;
- u32 tx_stat_bmac_4095_hi;
- u32 tx_stat_bmac_4095_lo;
- u32 tx_stat_bmac_9216_hi;
- u32 tx_stat_bmac_9216_lo;
- u32 tx_stat_bmac_16383_hi;
- u32 tx_stat_bmac_16383_lo;
- u32 tx_stat_dot3statsinternalmactransmiterrors_hi;
- u32 tx_stat_dot3statsinternalmactransmiterrors_lo;
- u32 tx_stat_bmac_ufl_hi;
- u32 tx_stat_bmac_ufl_lo;
-
- u32 brb_drop_hi;
- u32 brb_drop_lo;
- u32 brb_truncate_hi;
- u32 brb_truncate_lo;
-
- u32 jabber_packets_received;
-
- u32 etherstatspkts1024octetsto1522octets_hi;
- u32 etherstatspkts1024octetsto1522octets_lo;
- u32 etherstatspktsover1522octets_hi;
- u32 etherstatspktsover1522octets_lo;
-
- u32 no_buff_discard;
-
- u32 mac_filter_discard;
- u32 xxoverflow_discard;
- u32 brb_truncate_discard;
- u32 mac_discard;
-
- u32 driver_xoff;
- u32 rx_err_discard_pkt;
- u32 rx_skb_alloc_failed;
- u32 hw_csum_err;
-};
-
-#define STATS_OFFSET32(stat_name) \
- (offsetof(struct bnx2x_eth_stats, stat_name) / 4)
-
-
-#ifdef BNX2X_MULTI
-#define MAX_CONTEXT 16
-#else
-#define MAX_CONTEXT 1
-#endif
-
-union cdu_context {
- struct eth_context eth;
- char pad[1024];
-};
-
-#define MAX_DMAE_C 8
-
-/* DMA memory not used in fastpath */
-struct bnx2x_slowpath {
- union cdu_context context[MAX_CONTEXT];
- struct eth_stats_query fw_stats;
- struct mac_configuration_cmd mac_config;
- struct mac_configuration_cmd mcast_config;
-
- /* used by dmae command executer */
- struct dmae_command dmae[MAX_DMAE_C];
-
- u32 stats_comp;
- union mac_stats mac_stats;
- struct nig_stats nig_stats;
- struct host_port_stats port_stats;
- struct host_func_stats func_stats;
-
- u32 wb_comp;
- u32 wb_data[4];
-};
-
-#define bnx2x_sp(bp, var) (&bp->slowpath->var)
-#define bnx2x_sp_mapping(bp, var) \
- (bp->slowpath_mapping + offsetof(struct bnx2x_slowpath, var))
-
-
-/* attn group wiring */
-#define MAX_DYNAMIC_ATTN_GRPS 8
-
-struct attn_route {
- u32 sig[4];
-};
-
-struct bnx2x {
- /* Fields used in the tx and intr/napi performance paths
- * are grouped together in the beginning of the structure
- */
- struct bnx2x_fastpath fp[MAX_CONTEXT];
- void __iomem *regview;
- void __iomem *doorbells;
-#define BNX2X_DB_SIZE (16*2048)
-
- struct net_device *dev;
- struct pci_dev *pdev;
-
- atomic_t intr_sem;
- struct msix_entry msix_table[MAX_CONTEXT+1];
-
- int tx_ring_size;
-
-#ifdef BCM_VLAN
- struct vlan_group *vlgrp;
-#endif
-
- u32 rx_csum;
- u32 rx_offset;
- u32 rx_buf_size;
-#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */
-#define ETH_MIN_PACKET_SIZE 60
-#define ETH_MAX_PACKET_SIZE 1500
-#define ETH_MAX_JUMBO_PACKET_SIZE 9600
-
- struct host_def_status_block *def_status_blk;
-#define DEF_SB_ID 16
- u16 def_c_idx;
- u16 def_u_idx;
- u16 def_x_idx;
- u16 def_t_idx;
- u16 def_att_idx;
- u32 attn_state;
- struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
- u32 nig_mask;
-
- /* slow path ring */
- struct eth_spe *spq;
- dma_addr_t spq_mapping;
- u16 spq_prod_idx;
- struct eth_spe *spq_prod_bd;
- struct eth_spe *spq_last_bd;
- u16 *dsb_sp_prod;
- u16 spq_left; /* serialize spq */
- /* used to synchronize spq accesses */
- spinlock_t spq_lock;
-
- /* Flags for marking that there is a STAT_QUERY or
- SET_MAC ramrod pending */
- u8 stats_pending;
- u8 set_mac_pending;
-
- /* End of fields used in the performance code paths */
-
- int panic;
- int msglevel;
-
- u32 flags;
-#define PCIX_FLAG 1
-#define PCI_32BIT_FLAG 2
-#define ONE_TDMA_FLAG 4 /* no longer used */
-#define NO_WOL_FLAG 8
-#define USING_DAC_FLAG 0x10
-#define USING_MSIX_FLAG 0x20
-#define ASF_ENABLE_FLAG 0x40
-#define TPA_ENABLE_FLAG 0x80
-#define NO_MCP_FLAG 0x100
-#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
-
- int func;
-#define BP_PORT(bp) (bp->func % PORT_MAX)
-#define BP_FUNC(bp) (bp->func)
-#define BP_E1HVN(bp) (bp->func >> 1)
-#define BP_L_ID(bp) (BP_E1HVN(bp) << 2)
-
- int pm_cap;
- int pcie_cap;
-
- struct work_struct sp_task;
- struct work_struct reset_task;
-
- struct timer_list timer;
- int timer_interval;
- int current_interval;
-
- u16 fw_seq;
- u16 fw_drv_pulse_wr_seq;
- u32 func_stx;
-
- struct link_params link_params;
- struct link_vars link_vars;
-
- struct bnx2x_common common;
- struct bnx2x_port port;
-
- u32 mf_config;
- u16 e1hov;
- u8 e1hmf;
-#define IS_E1HMF(bp) (bp->e1hmf != 0)
-
- u8 wol;
-
- int rx_ring_size;
-
- u16 tx_quick_cons_trip_int;
- u16 tx_quick_cons_trip;
- u16 tx_ticks_int;
- u16 tx_ticks;
-
- u16 rx_quick_cons_trip_int;
- u16 rx_quick_cons_trip;
- u16 rx_ticks_int;
- u16 rx_ticks;
-
- u32 lin_cnt;
-
- int state;
-#define BNX2X_STATE_CLOSED 0x0
-#define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000
-#define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000
-#define BNX2X_STATE_OPEN 0x3000
-#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000
-#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
-#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000
-#define BNX2X_STATE_DISABLED 0xd000
-#define BNX2X_STATE_DIAG 0xe000
-#define BNX2X_STATE_ERROR 0xf000
-
- int num_queues;
-#define BP_MAX_QUEUES(bp) (IS_E1HMF(bp) ? 4 : 16)
-
- u32 rx_mode;
-#define BNX2X_RX_MODE_NONE 0
-#define BNX2X_RX_MODE_NORMAL 1
-#define BNX2X_RX_MODE_ALLMULTI 2
-#define BNX2X_RX_MODE_PROMISC 3
-#define BNX2X_MAX_MULTICAST 64
-#define BNX2X_MAX_EMUL_MULTI 16
-
- dma_addr_t def_status_blk_mapping;
-
- struct bnx2x_slowpath *slowpath;
- dma_addr_t slowpath_mapping;
-
-#ifdef BCM_ISCSI
- void *t1;
- dma_addr_t t1_mapping;
- void *t2;
- dma_addr_t t2_mapping;
- void *timers;
- dma_addr_t timers_mapping;
- void *qm;
- dma_addr_t qm_mapping;
-#endif
-
- int dmae_ready;
- /* used to synchronize dmae accesses */
- struct mutex dmae_mutex;
- struct dmae_command init_dmae;
-
- /* used to synchronize stats collecting */
- int stats_state;
- /* used by dmae command loader */
- struct dmae_command stats_dmae;
- int executer_idx;
-
- u16 stats_counter;
- struct tstorm_per_client_stats old_tclient;
- struct xstorm_per_client_stats old_xclient;
- struct bnx2x_eth_stats eth_stats;
-
- struct z_stream_s *strm;
- void *gunzip_buf;
- dma_addr_t gunzip_mapping;
- int gunzip_outlen;
-#define FW_BUF_SIZE 0x8000
-
-};
-
-
-#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
-
-#define for_each_nondefault_queue(bp, var) \
- for (var = 1; var < bp->num_queues; var++)
-#define is_multi(bp) (bp->num_queues > 1)
-
-
-void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
-void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
- u32 len32);
-int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
-
-static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
- int wait)
-{
- u32 val;
-
- do {
- val = REG_RD(bp, reg);
- if (val == expected)
- break;
- ms -= wait;
- msleep(wait);
-
- } while (ms > 0);
-
- return val;
-}
-
-
-/* load/unload mode */
-#define LOAD_NORMAL 0
-#define LOAD_OPEN 1
-#define LOAD_DIAG 2
-#define UNLOAD_NORMAL 0
-#define UNLOAD_CLOSE 1
-
-
-/* DMAE command defines */
-#define DMAE_CMD_SRC_PCI 0
-#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
-
-#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT)
-#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT)
-
-#define DMAE_CMD_C_DST_PCI 0
-#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT)
-
-#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
-
-#define DMAE_CMD_ENDIANITY_NO_SWAP (0 << DMAE_COMMAND_ENDIANITY_SHIFT)
-#define DMAE_CMD_ENDIANITY_B_SWAP (1 << DMAE_COMMAND_ENDIANITY_SHIFT)
-#define DMAE_CMD_ENDIANITY_DW_SWAP (2 << DMAE_COMMAND_ENDIANITY_SHIFT)
-#define DMAE_CMD_ENDIANITY_B_DW_SWAP (3 << DMAE_COMMAND_ENDIANITY_SHIFT)
-
-#define DMAE_CMD_PORT_0 0
-#define DMAE_CMD_PORT_1 DMAE_COMMAND_PORT
-
-#define DMAE_CMD_SRC_RESET DMAE_COMMAND_SRC_RESET
-#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
-#define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT
-
-#define DMAE_LEN32_RD_MAX 0x80
-#define DMAE_LEN32_WR_MAX 0x400
-
-#define DMAE_COMP_VAL 0xe0d0d0ae
-
-#define MAX_DMAE_C_PER_PORT 8
-#define INIT_DMAE_C(bp) (BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
- BP_E1HVN(bp))
-#define PMF_DMAE_C(bp) (BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
- E1HVN_MAX)
-
-
-/* PCIE link and speed */
-#define PCICFG_LINK_WIDTH 0x1f00000
-#define PCICFG_LINK_WIDTH_SHIFT 20
-#define PCICFG_LINK_SPEED 0xf0000
-#define PCICFG_LINK_SPEED_SHIFT 16
-
-
-#define BNX2X_NUM_STATS 42
-#define BNX2X_NUM_TESTS 8
-
-#define BNX2X_MAC_LOOPBACK 0
-#define BNX2X_PHY_LOOPBACK 1
-#define BNX2X_MAC_LOOPBACK_FAILED 1
-#define BNX2X_PHY_LOOPBACK_FAILED 2
-#define BNX2X_LOOPBACK_FAILED (BNX2X_MAC_LOOPBACK_FAILED | \
- BNX2X_PHY_LOOPBACK_FAILED)
-
-
-#define STROM_ASSERT_ARRAY_SIZE 50
-
-
-/* must be used on a CID before placing it on a HW ring */
-#define HW_CID(bp, x) ((BP_PORT(bp) << 23) | (BP_E1HVN(bp) << 17) | x)
-
-#define SP_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_spe))
-#define MAX_SP_DESC_CNT (SP_DESC_CNT - 1)
-
-
-#define BNX2X_BTR 3
-#define MAX_SPQ_PENDING 8
-
-
-/* CMNG constants
- derived from lab experiments, and not from system spec calculations !!! */
-#define DEF_MIN_RATE 100
-/* resolution of the rate shaping timer - 100 usec */
-#define RS_PERIODIC_TIMEOUT_USEC 100
-/* resolution of fairness algorithm in usecs -
- coefficient for calculating the actual t fair */
-#define T_FAIR_COEF 10000000
-/* number of bytes in single QM arbitration cycle -
- coefficient for calculating the fairness timer */
-#define QM_ARB_BYTES 40000
-#define FAIR_MEM 2
-
-
-#define ATTN_NIG_FOR_FUNC (1L << 8)
-#define ATTN_SW_TIMER_4_FUNC (1L << 9)
-#define GPIO_2_FUNC (1L << 10)
-#define GPIO_3_FUNC (1L << 11)
-#define GPIO_4_FUNC (1L << 12)
-#define ATTN_GENERAL_ATTN_1 (1L << 13)
-#define ATTN_GENERAL_ATTN_2 (1L << 14)
-#define ATTN_GENERAL_ATTN_3 (1L << 15)
-#define ATTN_GENERAL_ATTN_4 (1L << 13)
-#define ATTN_GENERAL_ATTN_5 (1L << 14)
-#define ATTN_GENERAL_ATTN_6 (1L << 15)
-
-#define ATTN_HARD_WIRED_MASK 0xff00
-#define ATTENTION_ID 4
-
-
-/* stuff added to make the code fit 80Col */
-
-#define BNX2X_PMF_LINK_ASSERT \
- GENERAL_ATTEN_OFFSET(LINK_SYNC_ATTENTION_BIT_FUNC_0 + BP_FUNC(bp))
-
-#define BNX2X_MC_ASSERT_BITS \
- (GENERAL_ATTEN_OFFSET(TSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
- GENERAL_ATTEN_OFFSET(USTORM_FATAL_ASSERT_ATTENTION_BIT) | \
- GENERAL_ATTEN_OFFSET(CSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
- GENERAL_ATTEN_OFFSET(XSTORM_FATAL_ASSERT_ATTENTION_BIT))
-
-#define BNX2X_MCP_ASSERT \
- GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT)
-
-#define BNX2X_DOORQ_ASSERT \
- AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT
-
-#define BNX2X_GRC_TIMEOUT GENERAL_ATTEN_OFFSET(LATCHED_ATTN_TIMEOUT_GRC)
-#define BNX2X_GRC_RSV (GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCR) | \
- GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCT) | \
- GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCN) | \
- GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCU) | \
- GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCP) | \
- GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RSVD_GRC))
-
-#define HW_INTERRUT_ASSERT_SET_0 \
- (AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT)
-#define HW_PRTY_ASSERT_SET_0 (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR |\
- AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR)
-#define HW_INTERRUT_ASSERT_SET_1 \
- (AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT)
-#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR |\
- AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\
- AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\
- AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR)
-#define HW_INTERRUT_ASSERT_SET_2 \
- (AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT | \
- AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT |\
- AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT)
-#define HW_PRTY_ASSERT_SET_2 (AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |\
- AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
- AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
-
-
-#define MULTI_FLAGS \
- (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE)
-
-#define MULTI_MASK 0x7f
-
-
-#define DEF_USB_FUNC_OFF (2 + 2*HC_USTORM_DEF_SB_NUM_INDICES)
-#define DEF_CSB_FUNC_OFF (2 + 2*HC_CSTORM_DEF_SB_NUM_INDICES)
-#define DEF_XSB_FUNC_OFF (2 + 2*HC_XSTORM_DEF_SB_NUM_INDICES)
-#define DEF_TSB_FUNC_OFF (2 + 2*HC_TSTORM_DEF_SB_NUM_INDICES)
-
-#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH
-
-#define BNX2X_SP_DSB_INDEX \
-(&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX])
-
-
-#define CAM_IS_INVALID(x) \
-(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
-
-#define CAM_INVALIDATE(x) \
- (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
-
-
-/* Number of u32 elements in MC hash array */
-#define MC_HASH_SIZE 8
-#define MC_HASH_OFFSET(bp, i) (BAR_TSTRORM_INTMEM + \
- TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(BP_FUNC(bp)) + i*4)
-
-
-#ifndef PXP2_REG_PXP2_INT_STS
-#define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0
-#endif
-
-/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */
-
-#endif /* bnx2x.h */
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
deleted file mode 100644
index 192fa981b93..00000000000
--- a/drivers/net/bnx2x_fw_defs.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/* bnx2x_fw_defs.h: Broadcom Everest network driver.
- *
- * Copyright (c) 2007-2008 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- */
-
-
-#define CSTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x7000 : 0x1000)
-#define CSTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0x8522 + ((function>>1) * 0x40) + \
- ((function&1) * 0x100) + (index * 0x4)) : (0x1922 + (function * \
- 0x40) + (index * 0x4)))
-#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8500 + ((function>>1) * 0x40) + \
- ((function&1) * 0x100)) : (0x1900 + (function * 0x40)))
-#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x8508 + ((function>>1) * 0x40) + \
- ((function&1) * 0x100)) : (0x1908 + (function * 0x40)))
-#define CSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x11e8 : 0xffffffff)
-#define CSTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x8704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
-#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0x801a + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)))
-#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0x8018 + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)))
-#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0x8000 + (port * 0x280) + (cpu_id * 0x28)) : \
- (0x1400 + (port * 0x280) + (cpu_id * 0x28)))
-#define CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0x8008 + (port * 0x280) + (cpu_id * 0x28)) : \
- (0x1408 + (port * 0x280) + (cpu_id * 0x28)))
-#define CSTORM_STATS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x1108 + (function * 0x8)) : (0x5108 + \
- (function * 0x8)))
-#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x31c0 + (function * 0x20)) : 0xffffffff)
-#define TSTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0xa000 : 0x1000)
-#define TSTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x3358 + (port * 0x3e8) + (client_id * 0x28)) \
- : (0x9c8 + (port * 0x2f8) + (client_id * 0x28)))
-#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
- 0x28) + (index * 0x4)))
-#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xb000 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1400 + (function * 0x28)))
-#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xb008 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
-#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2b80 + (function * 0x8)) : (0x4b68 + \
- (function * 0x8)))
-#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x3000 + (function * 0x38)) : (0x1500 + \
- (function * 0x38)))
-#define TSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x1ad0 : 0xffffffff)
-#define TSTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
-#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x12c8 + (function * 0x80)) : (0x22c8 + \
- (function * 0x80)))
-#define TSTORM_INDIRECTION_TABLE_SIZE 0x80
-#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x3008 + (function * 0x38)) : (0x1508 + \
- (function * 0x38)))
-#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
- (IS_E1H_OFFSET ? (0x2010 + (port * 0x5b0) + (stats_counter_id * \
- 0x50)) : (0x4000 + (port * 0x3f0) + (stats_counter_id * 0x38)))
-#define TSTORM_RX_PRODS_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x3350 + (port * 0x3e8) + (client_id * 0x28)) \
- : (0x9c0 + (port * 0x2f8) + (client_id * 0x28)))
-#define TSTORM_STATS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2c00 + (function * 0x8)) : (0x4b88 + \
- (function * 0x8)))
-#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3b30 : 0x1c20)
-#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa040 : 0x2c10)
-#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2440 : 0x1200)
-#define USTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x8000 : 0x1000)
-#define USTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x3298 + (port * 0x258) + (clientId * 0x18)) : \
- (0x5450 + (port * 0x1c8) + (clientId * 0x18)))
-#define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0x951a + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0) + (index * 0x4)) : (0x191a + (function * \
- 0x28) + (index * 0x4)))
-#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1900 + (function * 0x28)))
-#define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1908 + (function * 0x28)))
-#define USTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x2448 : 0xffffffff)
-#define USTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x9644 + (port * 0xd0)) : (0x1954 + (port * 0xb8)))
-#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x3290 + (port * 0x258) + (clientId * 0x18)) : \
- (0x5448 + (port * 0x1c8) + (clientId * 0x18)))
-#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5408 + \
- (function * 0x8)))
-#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)))
-#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
- (IS_E1H_OFFSET ? (0x9018 + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
- (index * 0x4)))
-#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0x9000 + (port * 0x280) + (cpu_id * 0x28)) : \
- (0x1400 + (port * 0x280) + (cpu_id * 0x28)))
-#define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
- (IS_E1H_OFFSET ? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \
- (0x1408 + (port * 0x280) + (cpu_id * 0x28)))
-#define XSTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x9000 : 0x1000)
-#define XSTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x24a8 + (port * 0x40)) : (0x3ba0 + (port * 0x40)))
-#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
- 0x28) + (index * 0x4)))
-#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xa000 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1400 + (function * 0x28)))
-#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
-#define XSTORM_E1HOV_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2ab8 + (function * 0x2)) : 0xffffffff)
-#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3b70 + \
- (function * 0x8)))
-#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2568 + (function * 0x70)) : (0x3c60 + \
- (function * 0x70)))
-#define XSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x2ac8 : 0xffffffff)
-#define XSTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
-#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
- (IS_E1H_OFFSET ? (0xc000 + (port * 0x3f0) + (stats_counter_id * \
- 0x38)) : (0x3378 + (port * 0x3f0) + (stats_counter_id * 0x38)))
-#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2528 + (function * 0x70)) : (0x3c20 + \
- (function * 0x70)))
-#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \
- (function * 0x10)))
-#define XSTORM_SPQ_PROD_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2008 + (function * 0x10)) : (0x3330 + \
- (function * 0x10)))
-#define XSTORM_STATS_FLAGS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3b60 + \
- (function * 0x8)))
-#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
-
-/**
-* This file defines HSI constatnts for the ETH flow
-*/
-#ifdef _EVEREST_MICROCODE
-#include "microcode_constants.h"
-#include "eth_rx_bd.h"
-#include "eth_tx_bd.h"
-#include "eth_rx_cqe.h"
-#include "eth_rx_sge.h"
-#include "eth_rx_cqe_next_page.h"
-#endif
-
-/* RSS hash types */
-#define DEFAULT_HASH_TYPE 0
-#define IPV4_HASH_TYPE 1
-#define TCP_IPV4_HASH_TYPE 2
-#define IPV6_HASH_TYPE 3
-#define TCP_IPV6_HASH_TYPE 4
-
-/* Ethernet Ring parmaters */
-#define X_ETH_LOCAL_RING_SIZE 13
-#define FIRST_BD_IN_PKT 0
-#define PARSE_BD_INDEX 1
-#define NUM_OF_ETH_BDS_IN_PAGE \
- ((PAGE_SIZE) / (STRUCT_SIZE(eth_tx_bd)/8))
-
-
-/* Rx ring params */
-#define U_ETH_LOCAL_BD_RING_SIZE (16)
-#define U_ETH_LOCAL_SGE_RING_SIZE (12)
-#define U_ETH_SGL_SIZE (8)
-
-
-#define U_ETH_BDS_PER_PAGE_MASK \
- ((PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))-1)
-#define U_ETH_CQE_PER_PAGE_MASK \
- ((PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe)/8))-1)
-#define U_ETH_SGES_PER_PAGE_MASK \
- ((PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8))-1)
-
-#define U_ETH_SGES_PER_PAGE_INVERSE_MASK \
- (0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1))
-
-
-#define TU_ETH_CQES_PER_PAGE \
- (PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe_next_page)/8))
-#define U_ETH_BDS_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))
-#define U_ETH_SGES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8))
-
-#define U_ETH_UNDEFINED_Q 0xFF
-
-/* values of command IDs in the ramrod message */
-#define RAMROD_CMD_ID_ETH_PORT_SETUP (80)
-#define RAMROD_CMD_ID_ETH_CLIENT_SETUP (85)
-#define RAMROD_CMD_ID_ETH_STAT_QUERY (90)
-#define RAMROD_CMD_ID_ETH_UPDATE (100)
-#define RAMROD_CMD_ID_ETH_HALT (105)
-#define RAMROD_CMD_ID_ETH_SET_MAC (110)
-#define RAMROD_CMD_ID_ETH_CFC_DEL (115)
-#define RAMROD_CMD_ID_ETH_PORT_DEL (120)
-#define RAMROD_CMD_ID_ETH_FORWARD_SETUP (125)
-
-
-/* command values for set mac command */
-#define T_ETH_MAC_COMMAND_SET 0
-#define T_ETH_MAC_COMMAND_INVALIDATE 1
-
-#define T_ETH_INDIRECTION_TABLE_SIZE 128
-
-/*The CRC32 seed, that is used for the hash(reduction) multicast address */
-#define T_ETH_CRC32_HASH_SEED 0x00000000
-
-/* Maximal L2 clients supported */
-#define ETH_MAX_RX_CLIENTS_E1 19
-#define ETH_MAX_RX_CLIENTS_E1H 25
-
-/* Maximal aggregation queues supported */
-#define ETH_MAX_AGGREGATION_QUEUES_E1 (32)
-#define ETH_MAX_AGGREGATION_QUEUES_E1H (64)
-
-
-/**
-* This file defines HSI constatnts common to all microcode flows
-*/
-
-/* Connection types */
-#define ETH_CONNECTION_TYPE 0
-#define TOE_CONNECTION_TYPE 1
-#define RDMA_CONNECTION_TYPE 2
-#define ISCSI_CONNECTION_TYPE 3
-#define FCOE_CONNECTION_TYPE 4
-#define RESERVED_CONNECTION_TYPE_0 5
-#define RESERVED_CONNECTION_TYPE_1 6
-#define RESERVED_CONNECTION_TYPE_2 7
-
-
-#define PROTOCOL_STATE_BIT_OFFSET 6
-
-#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define ISCSI_STATE \
- (ISCSI_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define FCOE_STATE (FCOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-
-/* microcode fixed page page size 4K (chains and ring segments) */
-#define MC_PAGE_SIZE (4096)
-
-
-/* Host coalescing constants */
-
-/* index numbers */
-#define HC_USTORM_DEF_SB_NUM_INDICES 4
-#define HC_CSTORM_DEF_SB_NUM_INDICES 8
-#define HC_XSTORM_DEF_SB_NUM_INDICES 4
-#define HC_TSTORM_DEF_SB_NUM_INDICES 4
-#define HC_USTORM_SB_NUM_INDICES 4
-#define HC_CSTORM_SB_NUM_INDICES 4
-
-/* index values - which counterto update */
-
-#define HC_INDEX_U_TOE_RX_CQ_CONS 0
-#define HC_INDEX_U_ETH_RX_CQ_CONS 1
-#define HC_INDEX_U_ETH_RX_BD_CONS 2
-#define HC_INDEX_U_FCOE_EQ_CONS 3
-
-#define HC_INDEX_C_TOE_TX_CQ_CONS 0
-#define HC_INDEX_C_ETH_TX_CQ_CONS 1
-#define HC_INDEX_C_ISCSI_EQ_CONS 2
-
-#define HC_INDEX_DEF_X_SPQ_CONS 0
-
-#define HC_INDEX_DEF_C_RDMA_EQ_CONS 0
-#define HC_INDEX_DEF_C_RDMA_NAL_PROD 1
-#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2
-#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3
-#define HC_INDEX_DEF_C_ETH_RDMA_CQ_CONS 4
-#define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5
-
-#define HC_INDEX_DEF_U_ETH_RDMA_RX_CQ_CONS 0
-#define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1
-#define HC_INDEX_DEF_U_ETH_RDMA_RX_BD_CONS 2
-#define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3
-
-
-/* used by the driver to get the SB offset */
-#define USTORM_ID 0
-#define CSTORM_ID 1
-#define XSTORM_ID 2
-#define TSTORM_ID 3
-#define ATTENTION_ID 4
-
-/* max number of slow path commands per port */
-#define MAX_RAMRODS_PER_PORT (8)
-
-/* values for RX ETH CQE type field */
-#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0)
-#define RX_ETH_CQE_TYPE_ETH_RAMROD (1)
-
-
-/**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
-#define EMULATION_FREQUENCY_FACTOR (1600)
-#define FPGA_FREQUENCY_FACTOR (100)
-
-#define TIMERS_TICK_SIZE_CHIP (1e-3)
-#define TIMERS_TICK_SIZE_EMUL \
- ((TIMERS_TICK_SIZE_CHIP)/((EMULATION_FREQUENCY_FACTOR)))
-#define TIMERS_TICK_SIZE_FPGA \
- ((TIMERS_TICK_SIZE_CHIP)/((FPGA_FREQUENCY_FACTOR)))
-
-#define TSEMI_CLK1_RESUL_CHIP (1e-3)
-#define TSEMI_CLK1_RESUL_EMUL \
- ((TSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define TSEMI_CLK1_RESUL_FPGA \
- ((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-
-#define USEMI_CLK1_RESUL_CHIP \
- (TIMERS_TICK_SIZE_CHIP)
-#define USEMI_CLK1_RESUL_EMUL \
- (TIMERS_TICK_SIZE_EMUL)
-#define USEMI_CLK1_RESUL_FPGA \
- (TIMERS_TICK_SIZE_FPGA)
-
-#define XSEMI_CLK1_RESUL_CHIP (1e-3)
-#define XSEMI_CLK1_RESUL_EMUL \
- ((XSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define XSEMI_CLK1_RESUL_FPGA \
- ((XSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-
-#define XSEMI_CLK2_RESUL_CHIP (1e-6)
-#define XSEMI_CLK2_RESUL_EMUL \
- ((XSEMI_CLK2_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define XSEMI_CLK2_RESUL_FPGA \
- ((XSEMI_CLK2_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-
-#define SDM_TIMER_TICK_RESUL_CHIP (4*(1e-6))
-#define SDM_TIMER_TICK_RESUL_EMUL \
- ((SDM_TIMER_TICK_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR))
-#define SDM_TIMER_TICK_RESUL_FPGA \
- ((SDM_TIMER_TICK_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-
-
-/**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
-#define XSTORM_IP_ID_ROLL_HALF 0x8000
-#define XSTORM_IP_ID_ROLL_ALL 0
-
-#define FW_LOG_LIST_SIZE (50)
-
-#define NUM_OF_PROTOCOLS 4
-#define MAX_COS_NUMBER 16
-#define MAX_T_STAT_COUNTER_ID 18
-#define MAX_X_STAT_COUNTER_ID 18
-
-#define UNKNOWN_ADDRESS 0
-#define UNICAST_ADDRESS 1
-#define MULTICAST_ADDRESS 2
-#define BROADCAST_ADDRESS 3
-
-#define SINGLE_FUNCTION 0
-#define MULTI_FUNCTION 1
-
-#define IP_V4 0
-#define IP_V6 1
-
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
deleted file mode 100644
index efd764427fa..00000000000
--- a/drivers/net/bnx2x_hsi.h
+++ /dev/null
@@ -1,2873 +0,0 @@
-/* bnx2x_hsi.h: Broadcom Everest network driver.
- *
- * Copyright (c) 2007-2008 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- */
-
-
-#define PORT_0 0
-#define PORT_1 1
-#define PORT_MAX 2
-
-/****************************************************************************
- * Shared HW configuration *
- ****************************************************************************/
-struct shared_hw_cfg { /* NVRAM Offset */
- /* Up to 16 bytes of NULL-terminated string */
- u8 part_num[16]; /* 0x104 */
-
- u32 config; /* 0x114 */
-#define SHARED_HW_CFG_MDIO_VOLTAGE_MASK 0x00000001
-#define SHARED_HW_CFG_MDIO_VOLTAGE_SHIFT 0
-#define SHARED_HW_CFG_MDIO_VOLTAGE_1_2V 0x00000000
-#define SHARED_HW_CFG_MDIO_VOLTAGE_2_5V 0x00000001
-#define SHARED_HW_CFG_MCP_RST_ON_CORE_RST_EN 0x00000002
-
-#define SHARED_HW_CFG_PORT_SWAP 0x00000004
-
-#define SHARED_HW_CFG_BEACON_WOL_EN 0x00000008
-
-#define SHARED_HW_CFG_MFW_SELECT_MASK 0x00000700
-#define SHARED_HW_CFG_MFW_SELECT_SHIFT 8
- /* Whatever MFW found in NVM
- (if multiple found, priority order is: NC-SI, UMP, IPMI) */
-#define SHARED_HW_CFG_MFW_SELECT_DEFAULT 0x00000000
-#define SHARED_HW_CFG_MFW_SELECT_NC_SI 0x00000100
-#define SHARED_HW_CFG_MFW_SELECT_UMP 0x00000200
-#define SHARED_HW_CFG_MFW_SELECT_IPMI 0x00000300
- /* Use SPIO4 as an arbiter between: 0-NC_SI, 1-IPMI
- (can only be used when an add-in board, not BMC, pulls-down SPIO4) */
-#define SHARED_HW_CFG_MFW_SELECT_SPIO4_NC_SI_IPMI 0x00000400
- /* Use SPIO4 as an arbiter between: 0-UMP, 1-IPMI
- (can only be used when an add-in board, not BMC, pulls-down SPIO4) */
-#define SHARED_HW_CFG_MFW_SELECT_SPIO4_UMP_IPMI 0x00000500
- /* Use SPIO4 as an arbiter between: 0-NC-SI, 1-UMP
- (can only be used when an add-in board, not BMC, pulls-down SPIO4) */
-#define SHARED_HW_CFG_MFW_SELECT_SPIO4_NC_SI_UMP 0x00000600
-
-#define SHARED_HW_CFG_LED_MODE_MASK 0x000f0000
-#define SHARED_HW_CFG_LED_MODE_SHIFT 16
-#define SHARED_HW_CFG_LED_MAC1 0x00000000
-#define SHARED_HW_CFG_LED_PHY1 0x00010000
-#define SHARED_HW_CFG_LED_PHY2 0x00020000
-#define SHARED_HW_CFG_LED_PHY3 0x00030000
-#define SHARED_HW_CFG_LED_MAC2 0x00040000
-#define SHARED_HW_CFG_LED_PHY4 0x00050000
-#define SHARED_HW_CFG_LED_PHY5 0x00060000
-#define SHARED_HW_CFG_LED_PHY6 0x00070000
-#define SHARED_HW_CFG_LED_MAC3 0x00080000
-#define SHARED_HW_CFG_LED_PHY7 0x00090000
-#define SHARED_HW_CFG_LED_PHY9 0x000a0000
-#define SHARED_HW_CFG_LED_PHY11 0x000b0000
-#define SHARED_HW_CFG_LED_MAC4 0x000c0000
-#define SHARED_HW_CFG_LED_PHY8 0x000d0000
-
-#define SHARED_HW_CFG_AN_ENABLE_MASK 0x3f000000
-#define SHARED_HW_CFG_AN_ENABLE_SHIFT 24
-#define SHARED_HW_CFG_AN_ENABLE_CL37 0x01000000
-#define SHARED_HW_CFG_AN_ENABLE_CL73 0x02000000
-#define SHARED_HW_CFG_AN_ENABLE_BAM 0x04000000
-#define SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION 0x08000000
-#define SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT 0x10000000
-#define SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY 0x20000000
-
- u32 config2; /* 0x118 */
- /* one time auto detect grace period (in sec) */
-#define SHARED_HW_CFG_GRACE_PERIOD_MASK 0x000000ff
-#define SHARED_HW_CFG_GRACE_PERIOD_SHIFT 0
-
-#define SHARED_HW_CFG_PCIE_GEN2_ENABLED 0x00000100
-
- /* The default value for the core clock is 250MHz and it is
- achieved by setting the clock change to 4 */
-#define SHARED_HW_CFG_CLOCK_CHANGE_MASK 0x00000e00
-#define SHARED_HW_CFG_CLOCK_CHANGE_SHIFT 9
-
-#define SHARED_HW_CFG_SMBUS_TIMING_100KHZ 0x00000000
-#define SHARED_HW_CFG_SMBUS_TIMING_400KHZ 0x00001000
-
-#define SHARED_HW_CFG_HIDE_PORT1 0x00002000
-
- u32 power_dissipated; /* 0x11c */
-#define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000
-#define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT 24
-
-#define SHARED_HW_CFG_POWER_MGNT_SCALE_MASK 0x00ff0000
-#define SHARED_HW_CFG_POWER_MGNT_SCALE_SHIFT 16
-#define SHARED_HW_CFG_POWER_MGNT_UNKNOWN_SCALE 0x00000000
-#define SHARED_HW_CFG_POWER_MGNT_DOT_1_WATT 0x00010000
-#define SHARED_HW_CFG_POWER_MGNT_DOT_01_WATT 0x00020000
-#define SHARED_HW_CFG_POWER_MGNT_DOT_001_WATT 0x00030000
-
- u32 ump_nc_si_config; /* 0x120 */
-#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MASK 0x00000003
-#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_SHIFT 0
-#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MAC 0x00000000
-#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_PHY 0x00000001
-#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MII 0x00000000
-#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_RMII 0x00000002
-
-#define SHARED_HW_CFG_UMP_NC_SI_NUM_DEVS_MASK 0x00000f00
-#define SHARED_HW_CFG_UMP_NC_SI_NUM_DEVS_SHIFT 8
-
-#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_MASK 0x00ff0000
-#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_SHIFT 16
-#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_NONE 0x00000000
-#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_BCM5221 0x00010000
-
- u32 board; /* 0x124 */
-#define SHARED_HW_CFG_BOARD_TYPE_MASK 0x0000ffff
-#define SHARED_HW_CFG_BOARD_TYPE_SHIFT 0
-#define SHARED_HW_CFG_BOARD_TYPE_NONE 0x00000000
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1000 0x00000001
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1001 0x00000002
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G 0x00000003
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1004G 0x00000004
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1007G 0x00000005
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1023G 0x0000000b
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1033G 0x0000000c
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711T1101 0x0000000d
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711ET1201 0x0000000e
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711A1133G 0x0000000f
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711EA1233G 0x00000010
-
-#define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000
-#define SHARED_HW_CFG_BOARD_VER_SHIFT 16
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK 0xf0000000
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT 28
-#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK 0x0f000000
-#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT 24
-#define SHARED_HW_CFG_BOARD_REV_MASK 0x00ff0000
-#define SHARED_HW_CFG_BOARD_REV_SHIFT 16
-
- u32 reserved; /* 0x128 */
-
-};
-
-
-/****************************************************************************
- * Port HW configuration *
- ****************************************************************************/
-struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
-
- u32 pci_id;
-#define PORT_HW_CFG_PCI_VENDOR_ID_MASK 0xffff0000
-#define PORT_HW_CFG_PCI_DEVICE_ID_MASK 0x0000ffff
-
- u32 pci_sub_id;
-#define PORT_HW_CFG_PCI_SUBSYS_DEVICE_ID_MASK 0xffff0000
-#define PORT_HW_CFG_PCI_SUBSYS_VENDOR_ID_MASK 0x0000ffff
-
- u32 power_dissipated;
-#define PORT_HW_CFG_POWER_DIS_D3_MASK 0xff000000
-#define PORT_HW_CFG_POWER_DIS_D3_SHIFT 24
-#define PORT_HW_CFG_POWER_DIS_D2_MASK 0x00ff0000
-#define PORT_HW_CFG_POWER_DIS_D2_SHIFT 16
-#define PORT_HW_CFG_POWER_DIS_D1_MASK 0x0000ff00
-#define PORT_HW_CFG_POWER_DIS_D1_SHIFT 8
-#define PORT_HW_CFG_POWER_DIS_D0_MASK 0x000000ff
-#define PORT_HW_CFG_POWER_DIS_D0_SHIFT 0
-
- u32 power_consumed;
-#define PORT_HW_CFG_POWER_CONS_D3_MASK 0xff000000
-#define PORT_HW_CFG_POWER_CONS_D3_SHIFT 24
-#define PORT_HW_CFG_POWER_CONS_D2_MASK 0x00ff0000
-#define PORT_HW_CFG_POWER_CONS_D2_SHIFT 16
-#define PORT_HW_CFG_POWER_CONS_D1_MASK 0x0000ff00
-#define PORT_HW_CFG_POWER_CONS_D1_SHIFT 8
-#define PORT_HW_CFG_POWER_CONS_D0_MASK 0x000000ff
-#define PORT_HW_CFG_POWER_CONS_D0_SHIFT 0
-
- u32 mac_upper;
-#define PORT_HW_CFG_UPPERMAC_MASK 0x0000ffff
-#define PORT_HW_CFG_UPPERMAC_SHIFT 0
- u32 mac_lower;
-
- u32 iscsi_mac_upper; /* Upper 16 bits are always zeroes */
- u32 iscsi_mac_lower;
-
- u32 rdma_mac_upper; /* Upper 16 bits are always zeroes */
- u32 rdma_mac_lower;
-
- u32 serdes_config;
- /* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT 16
-
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK 0x0000ffff
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 0
-
- u16 serdes_tx_driver_pre_emphasis[16];
- u16 serdes_rx_driver_equalizer[16];
-
- u32 xgxs_config_lane0;
- u32 xgxs_config_lane1;
- u32 xgxs_config_lane2;
- u32 xgxs_config_lane3;
- /* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_SHIFT 16
-
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_MASK 0x0000ffff
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_SHIFT 0
-
- u16 xgxs_tx_driver_pre_emphasis_lane0[16];
- u16 xgxs_tx_driver_pre_emphasis_lane1[16];
- u16 xgxs_tx_driver_pre_emphasis_lane2[16];
- u16 xgxs_tx_driver_pre_emphasis_lane3[16];
-
- u16 xgxs_rx_driver_equalizer_lane0[16];
- u16 xgxs_rx_driver_equalizer_lane1[16];
- u16 xgxs_rx_driver_equalizer_lane2[16];
- u16 xgxs_rx_driver_equalizer_lane3[16];
-
- u32 lane_config;
-#define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff
-#define PORT_HW_CFG_LANE_SWAP_CFG_SHIFT 0
-#define PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK 0x000000ff
-#define PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT 0
-#define PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK 0x0000ff00
-#define PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT 8
-#define PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK 0x0000c000
-#define PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT 14
- /* AN and forced */
-#define PORT_HW_CFG_LANE_SWAP_CFG_01230123 0x00001b1b
- /* forced only */
-#define PORT_HW_CFG_LANE_SWAP_CFG_01233210 0x00001be4
- /* forced only */
-#define PORT_HW_CFG_LANE_SWAP_CFG_31203120 0x0000d8d8
- /* forced only */
-#define PORT_HW_CFG_LANE_SWAP_CFG_32103210 0x0000e4e4
-
- u32 external_phy_config;
-#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK 0xff000000
-#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_SHIFT 24
-#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT 0x00000000
-#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482 0x01000000
-#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN 0xff000000
-
-#define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK 0x00ff0000
-#define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT 16
-
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK 0x0000ff00
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SHIFT 8
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT 0x00000000
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8071 0x00000100
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072 0x00000200
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00
-
-#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK 0x000000ff
-#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT 0
-
- u32 speed_capability_mask;
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_MASK 0xffff0000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_SHIFT 16
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL 0x00010000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF 0x00020000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF 0x00040000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL 0x00080000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_1G 0x00100000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G 0x00200000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10G 0x00400000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_12G 0x00800000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_12_5G 0x01000000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_13G 0x02000000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_15G 0x04000000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_16G 0x08000000
-#define PORT_HW_CFG_SPEED_CAPABILITY_D0_RESERVED 0xf0000000
-
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_MASK 0x0000ffff
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_SHIFT 0
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10M_FULL 0x00000001
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10M_HALF 0x00000002
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_100M_HALF 0x00000004
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_100M_FULL 0x00000008
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_1G 0x00000010
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_2_5G 0x00000020
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10G 0x00000040
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_12G 0x00000080
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_12_5G 0x00000100
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_13G 0x00000200
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_15G 0x00000400
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_16G 0x00000800
-#define PORT_HW_CFG_SPEED_CAPABILITY_D3_RESERVED 0x0000f000
-
- u32 reserved[2];
-
-};
-
-
-/****************************************************************************
- * Shared Feature configuration *
- ****************************************************************************/
-struct shared_feat_cfg { /* NVRAM Offset */
-
- u32 config; /* 0x450 */
-#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
-#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
-
-};
-
-
-/****************************************************************************
- * Port Feature configuration *
- ****************************************************************************/
-struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
-
- u32 config;
-#define PORT_FEATURE_BAR1_SIZE_MASK 0x0000000f
-#define PORT_FEATURE_BAR1_SIZE_SHIFT 0
-#define PORT_FEATURE_BAR1_SIZE_DISABLED 0x00000000
-#define PORT_FEATURE_BAR1_SIZE_64K 0x00000001
-#define PORT_FEATURE_BAR1_SIZE_128K 0x00000002
-#define PORT_FEATURE_BAR1_SIZE_256K 0x00000003
-#define PORT_FEATURE_BAR1_SIZE_512K 0x00000004
-#define PORT_FEATURE_BAR1_SIZE_1M 0x00000005
-#define PORT_FEATURE_BAR1_SIZE_2M 0x00000006
-#define PORT_FEATURE_BAR1_SIZE_4M 0x00000007
-#define PORT_FEATURE_BAR1_SIZE_8M 0x00000008
-#define PORT_FEATURE_BAR1_SIZE_16M 0x00000009
-#define PORT_FEATURE_BAR1_SIZE_32M 0x0000000a
-#define PORT_FEATURE_BAR1_SIZE_64M 0x0000000b
-#define PORT_FEATURE_BAR1_SIZE_128M 0x0000000c
-#define PORT_FEATURE_BAR1_SIZE_256M 0x0000000d
-#define PORT_FEATURE_BAR1_SIZE_512M 0x0000000e
-#define PORT_FEATURE_BAR1_SIZE_1G 0x0000000f
-#define PORT_FEATURE_BAR2_SIZE_MASK 0x000000f0
-#define PORT_FEATURE_BAR2_SIZE_SHIFT 4
-#define PORT_FEATURE_BAR2_SIZE_DISABLED 0x00000000
-#define PORT_FEATURE_BAR2_SIZE_64K 0x00000010
-#define PORT_FEATURE_BAR2_SIZE_128K 0x00000020
-#define PORT_FEATURE_BAR2_SIZE_256K 0x00000030
-#define PORT_FEATURE_BAR2_SIZE_512K 0x00000040
-#define PORT_FEATURE_BAR2_SIZE_1M 0x00000050
-#define PORT_FEATURE_BAR2_SIZE_2M 0x00000060
-#define PORT_FEATURE_BAR2_SIZE_4M 0x00000070
-#define PORT_FEATURE_BAR2_SIZE_8M 0x00000080
-#define PORT_FEATURE_BAR2_SIZE_16M 0x00000090
-#define PORT_FEATURE_BAR2_SIZE_32M 0x000000a0
-#define PORT_FEATURE_BAR2_SIZE_64M 0x000000b0
-#define PORT_FEATURE_BAR2_SIZE_128M 0x000000c0
-#define PORT_FEATURE_BAR2_SIZE_256M 0x000000d0
-#define PORT_FEATURE_BAR2_SIZE_512M 0x000000e0
-#define PORT_FEATURE_BAR2_SIZE_1G 0x000000f0
-#define PORT_FEATURE_EN_SIZE_MASK 0x07000000
-#define PORT_FEATURE_EN_SIZE_SHIFT 24
-#define PORT_FEATURE_WOL_ENABLED 0x01000000
-#define PORT_FEATURE_MBA_ENABLED 0x02000000
-#define PORT_FEATURE_MFW_ENABLED 0x04000000
-
- u32 wol_config;
- /* Default is used when driver sets to "auto" mode */
-#define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003
-#define PORT_FEATURE_WOL_DEFAULT_SHIFT 0
-#define PORT_FEATURE_WOL_DEFAULT_DISABLE 0x00000000
-#define PORT_FEATURE_WOL_DEFAULT_MAGIC 0x00000001
-#define PORT_FEATURE_WOL_DEFAULT_ACPI 0x00000002
-#define PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI 0x00000003
-#define PORT_FEATURE_WOL_RES_PAUSE_CAP 0x00000004
-#define PORT_FEATURE_WOL_RES_ASYM_PAUSE_CAP 0x00000008
-#define PORT_FEATURE_WOL_ACPI_UPON_MGMT 0x00000010
-
- u32 mba_config;
-#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK 0x00000003
-#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT 0
-#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE 0x00000000
-#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL 0x00000001
-#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP 0x00000002
-#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_ISCSIB 0x00000003
-#define PORT_FEATURE_MBA_RES_PAUSE_CAP 0x00000100
-#define PORT_FEATURE_MBA_RES_ASYM_PAUSE_CAP 0x00000200
-#define PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x00000400
-#define PORT_FEATURE_MBA_HOTKEY_CTRL_S 0x00000000
-#define PORT_FEATURE_MBA_HOTKEY_CTRL_B 0x00000800
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK 0x000ff000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT 12
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED 0x00000000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_2K 0x00001000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_4K 0x00002000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_8K 0x00003000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_16K 0x00004000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_32K 0x00005000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_64K 0x00006000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_128K 0x00007000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_256K 0x00008000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_512K 0x00009000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_1M 0x0000a000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_2M 0x0000b000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_4M 0x0000c000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_8M 0x0000d000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_16M 0x0000e000
-#define PORT_FEATURE_MBA_EXP_ROM_SIZE_32M 0x0000f000
-#define PORT_FEATURE_MBA_MSG_TIMEOUT_MASK 0x00f00000
-#define PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT 20
-#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK 0x03000000
-#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT 24
-#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO 0x00000000
-#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS 0x01000000
-#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H 0x02000000
-#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H 0x03000000
-#define PORT_FEATURE_MBA_LINK_SPEED_MASK 0x3c000000
-#define PORT_FEATURE_MBA_LINK_SPEED_SHIFT 26
-#define PORT_FEATURE_MBA_LINK_SPEED_AUTO 0x00000000
-#define PORT_FEATURE_MBA_LINK_SPEED_10HD 0x04000000
-#define PORT_FEATURE_MBA_LINK_SPEED_10FD 0x08000000
-#define PORT_FEATURE_MBA_LINK_SPEED_100HD 0x0c000000
-#define PORT_FEATURE_MBA_LINK_SPEED_100FD 0x10000000
-#define PORT_FEATURE_MBA_LINK_SPEED_1GBPS 0x14000000
-#define PORT_FEATURE_MBA_LINK_SPEED_2_5GBPS 0x18000000
-#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_CX4 0x1c000000
-#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_KX4 0x20000000
-#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_KR 0x24000000
-#define PORT_FEATURE_MBA_LINK_SPEED_12GBPS 0x28000000
-#define PORT_FEATURE_MBA_LINK_SPEED_12_5GBPS 0x2c000000
-#define PORT_FEATURE_MBA_LINK_SPEED_13GBPS 0x30000000
-#define PORT_FEATURE_MBA_LINK_SPEED_15GBPS 0x34000000
-#define PORT_FEATURE_MBA_LINK_SPEED_16GBPS 0x38000000
-
- u32 bmc_config;
-#define PORT_FEATURE_BMC_LINK_OVERRIDE_DEFAULT 0x00000000
-#define PORT_FEATURE_BMC_LINK_OVERRIDE_EN 0x00000001
-
- u32 mba_vlan_cfg;
-#define PORT_FEATURE_MBA_VLAN_TAG_MASK 0x0000ffff
-#define PORT_FEATURE_MBA_VLAN_TAG_SHIFT 0
-#define PORT_FEATURE_MBA_VLAN_EN 0x00010000
-
- u32 resource_cfg;
-#define PORT_FEATURE_RESOURCE_CFG_VALID 0x00000001
-#define PORT_FEATURE_RESOURCE_CFG_DIAG 0x00000002
-#define PORT_FEATURE_RESOURCE_CFG_L2 0x00000004
-#define PORT_FEATURE_RESOURCE_CFG_ISCSI 0x00000008
-#define PORT_FEATURE_RESOURCE_CFG_RDMA 0x00000010
-
- u32 smbus_config;
- /* Obsolete */
-#define PORT_FEATURE_SMBUS_EN 0x00000001
-#define PORT_FEATURE_SMBUS_ADDR_MASK 0x000000fe
-#define PORT_FEATURE_SMBUS_ADDR_SHIFT 1
-
- u32 reserved1;
-
- u32 link_config; /* Used as HW defaults for the driver */
-#define PORT_FEATURE_CONNECTED_SWITCH_MASK 0x03000000
-#define PORT_FEATURE_CONNECTED_SWITCH_SHIFT 24
- /* (forced) low speed switch (< 10G) */
-#define PORT_FEATURE_CON_SWITCH_1G_SWITCH 0x00000000
- /* (forced) high speed switch (>= 10G) */
-#define PORT_FEATURE_CON_SWITCH_10G_SWITCH 0x01000000
-#define PORT_FEATURE_CON_SWITCH_AUTO_DETECT 0x02000000
-#define PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT 0x03000000
-
-#define PORT_FEATURE_LINK_SPEED_MASK 0x000f0000
-#define PORT_FEATURE_LINK_SPEED_SHIFT 16
-#define PORT_FEATURE_LINK_SPEED_AUTO 0x00000000
-#define PORT_FEATURE_LINK_SPEED_10M_FULL 0x00010000
-#define PORT_FEATURE_LINK_SPEED_10M_HALF 0x00020000
-#define PORT_FEATURE_LINK_SPEED_100M_HALF 0x00030000
-#define PORT_FEATURE_LINK_SPEED_100M_FULL 0x00040000
-#define PORT_FEATURE_LINK_SPEED_1G 0x00050000
-#define PORT_FEATURE_LINK_SPEED_2_5G 0x00060000
-#define PORT_FEATURE_LINK_SPEED_10G_CX4 0x00070000
-#define PORT_FEATURE_LINK_SPEED_10G_KX4 0x00080000
-#define PORT_FEATURE_LINK_SPEED_10G_KR 0x00090000
-#define PORT_FEATURE_LINK_SPEED_12G 0x000a0000
-#define PORT_FEATURE_LINK_SPEED_12_5G 0x000b0000
-#define PORT_FEATURE_LINK_SPEED_13G 0x000c0000
-#define PORT_FEATURE_LINK_SPEED_15G 0x000d0000
-#define PORT_FEATURE_LINK_SPEED_16G 0x000e0000
-
-#define PORT_FEATURE_FLOW_CONTROL_MASK 0x00000700
-#define PORT_FEATURE_FLOW_CONTROL_SHIFT 8
-#define PORT_FEATURE_FLOW_CONTROL_AUTO 0x00000000
-#define PORT_FEATURE_FLOW_CONTROL_TX 0x00000100
-#define PORT_FEATURE_FLOW_CONTROL_RX 0x00000200
-#define PORT_FEATURE_FLOW_CONTROL_BOTH 0x00000300
-#define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400
-
- /* The default for MCP link configuration,
- uses the same defines as link_config */
- u32 mfw_wol_link_cfg;
-
- u32 reserved[19];
-
-};
-
-
-/****************************************************************************
- * Device Information *
- ****************************************************************************/
-struct dev_info { /* size */
-
- u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
-
- struct shared_hw_cfg shared_hw_config; /* 40 */
-
- struct port_hw_cfg port_hw_config[PORT_MAX]; /* 400*2=800 */
-
- struct shared_feat_cfg shared_feature_config; /* 4 */
-
- struct port_feat_cfg port_feature_config[PORT_MAX];/* 116*2=232 */
-
-};
-
-
-#define FUNC_0 0
-#define FUNC_1 1
-#define FUNC_2 2
-#define FUNC_3 3
-#define FUNC_4 4
-#define FUNC_5 5
-#define FUNC_6 6
-#define FUNC_7 7
-#define E1_FUNC_MAX 2
-#define E1H_FUNC_MAX 8
-
-#define VN_0 0
-#define VN_1 1
-#define VN_2 2
-#define VN_3 3
-#define E1VN_MAX 1
-#define E1HVN_MAX 4
-
-
-/* This value (in milliseconds) determines the frequency of the driver
- * issuing the PULSE message code. The firmware monitors this periodic
- * pulse to determine when to switch to an OS-absent mode. */
-#define DRV_PULSE_PERIOD_MS 250
-
-/* This value (in milliseconds) determines how long the driver should
- * wait for an acknowledgement from the firmware before timing out. Once
- * the firmware has timed out, the driver will assume there is no firmware
- * running and there won't be any firmware-driver synchronization during a
- * driver reset. */
-#define FW_ACK_TIME_OUT_MS 5000
-
-#define FW_ACK_POLL_TIME_MS 1
-
-#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS)
-
-/* LED Blink rate that will achieve ~15.9Hz */
-#define LED_BLINK_RATE_VAL 480
-
-/****************************************************************************
- * Driver <-> FW Mailbox *
- ****************************************************************************/
-struct drv_port_mb {
-
- u32 link_status;
- /* Driver should update this field on any link change event */
-
-#define LINK_STATUS_LINK_FLAG_MASK 0x00000001
-#define LINK_STATUS_LINK_UP 0x00000001
-#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E
-#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1)
-#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1)
-
-#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020
-#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020
-
-#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040
-#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080
-#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080
-
-#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200
-#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400
-#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800
-#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000
-#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000
-#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000
-#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000
-
-#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000
-#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000
-
-#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000
-#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000
-
-#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000
-#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18)
-#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18)
-#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18)
-#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18)
-
-#define LINK_STATUS_SERDES_LINK 0x00100000
-
-#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000
-#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000
-#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000
-#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000
-#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000
-#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000
-#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000
-#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000
-
- u32 port_stx;
-
- u32 reserved[2];
-
-};
-
-
-struct drv_func_mb {
-
- u32 drv_mb_header;
-#define DRV_MSG_CODE_MASK 0xffff0000
-#define DRV_MSG_CODE_LOAD_REQ 0x10000000
-#define DRV_MSG_CODE_LOAD_DONE 0x11000000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000
-#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000
-#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000
-#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000
-#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000
-#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000
-#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000
-#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000
-#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000
-#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000
-
-#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
-#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
-#define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000
-#define BIOS_MSG_CODE_VIRT_MAC_ISCSI 0xff040000
-
-#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
-
- u32 drv_mb_param;
-
- u32 fw_mb_header;
-#define FW_MSG_CODE_MASK 0xffff0000
-#define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000
-#define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000
-#define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000
-#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000
-#define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000
-#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000
-#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x20110000
-#define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 0x20120000
-#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x21100000
-#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50100000
-#define FW_MSG_CODE_DIAG_REFUSE 0x50200000
-#define FW_MSG_CODE_DIAG_EXIT_DONE 0x60100000
-#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70100000
-#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x70200000
-#define FW_MSG_CODE_GET_KEY_DONE 0x80100000
-#define FW_MSG_CODE_NO_KEY 0x80f00000
-#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x80f80000
-#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90100000
-#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x90210000
-#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x90220000
-#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x90230000
-#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x90240000
-
-#define FW_MSG_CODE_LIC_CHALLENGE 0xff010000
-#define FW_MSG_CODE_LIC_RESPONSE 0xff020000
-#define FW_MSG_CODE_VIRT_MAC_PRIM 0xff030000
-#define FW_MSG_CODE_VIRT_MAC_ISCSI 0xff040000
-
-#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff
-
- u32 fw_mb_param;
-
- u32 drv_pulse_mb;
-#define DRV_PULSE_SEQ_MASK 0x00007fff
-#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000
- /* The system time is in the format of
- * (year-2001)*12*32 + month*32 + day. */
-#define DRV_PULSE_ALWAYS_ALIVE 0x00008000
- /* Indicate to the firmware not to go into the
- * OS-absent when it is not getting driver pulse.
- * This is used for debugging as well for PXE(MBA). */
-
- u32 mcp_pulse_mb;
-#define MCP_PULSE_SEQ_MASK 0x00007fff
-#define MCP_PULSE_ALWAYS_ALIVE 0x00008000
- /* Indicates to the driver not to assert due to lack
- * of MCP response */
-#define MCP_EVENT_MASK 0xffff0000
-#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000
-
- u32 iscsi_boot_signature;
- u32 iscsi_boot_block_offset;
-
- u32 drv_status;
-#define DRV_STATUS_PMF 0x00000001
-
- u32 virt_mac_upper;
-#define VIRT_MAC_SIGN_MASK 0xffff0000
-#define VIRT_MAC_SIGNATURE 0x564d0000
- u32 virt_mac_lower;
-
-};
-
-
-/****************************************************************************
- * Management firmware state *
- ****************************************************************************/
-/* Allocate 440 bytes for management firmware */
-#define MGMTFW_STATE_WORD_SIZE 110
-
-struct mgmtfw_state {
- u32 opaque[MGMTFW_STATE_WORD_SIZE];
-};
-
-
-/****************************************************************************
- * Multi-Function configuration *
- ****************************************************************************/
-struct shared_mf_cfg {
-
- u32 clp_mb;
-#define SHARED_MF_CLP_SET_DEFAULT 0x00000000
- /* set by CLP */
-#define SHARED_MF_CLP_EXIT 0x00000001
- /* set by MCP */
-#define SHARED_MF_CLP_EXIT_DONE 0x00010000
-
-};
-
-struct port_mf_cfg {
-
- u32 dynamic_cfg; /* device control channel */
-#define PORT_MF_CFG_OUTER_VLAN_TAG_MASK 0x0000ffff
-#define PORT_MF_CFG_OUTER_VLAN_TAG_SHIFT 0
-#define PORT_MF_CFG_DYNAMIC_CFG_ENABLED 0x00010000
-#define PORT_MF_CFG_DYNAMIC_CFG_DEFAULT 0x00000000
-
- u32 reserved[3];
-
-};
-
-struct func_mf_cfg {
-
- u32 config;
- /* E/R/I/D */
- /* function 0 of each port cannot be hidden */
-#define FUNC_MF_CFG_FUNC_HIDE 0x00000001
-
-#define FUNC_MF_CFG_PROTOCOL_MASK 0x00000007
-#define FUNC_MF_CFG_PROTOCOL_ETHERNET 0x00000002
-#define FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA 0x00000004
-#define FUNC_MF_CFG_PROTOCOL_ISCSI 0x00000006
-#define FUNC_MF_CFG_PROTOCOL_DEFAULT\
- FUNC_MF_CFG_PROTOCOL_ETHERNET_WITH_RDMA
-
-#define FUNC_MF_CFG_FUNC_DISABLED 0x00000008
-
- /* PRI */
- /* 0 - low priority, 3 - high priority */
-#define FUNC_MF_CFG_TRANSMIT_PRIORITY_MASK 0x00000300
-#define FUNC_MF_CFG_TRANSMIT_PRIORITY_SHIFT 8
-#define FUNC_MF_CFG_TRANSMIT_PRIORITY_DEFAULT 0x00000000
-
- /* MINBW, MAXBW */
- /* value range - 0..100, increments in 100Mbps */
-#define FUNC_MF_CFG_MIN_BW_MASK 0x00ff0000
-#define FUNC_MF_CFG_MIN_BW_SHIFT 16
-#define FUNC_MF_CFG_MIN_BW_DEFAULT 0x00000000
-#define FUNC_MF_CFG_MAX_BW_MASK 0xff000000
-#define FUNC_MF_CFG_MAX_BW_SHIFT 24
-#define FUNC_MF_CFG_MAX_BW_DEFAULT 0x64000000
-
- u32 mac_upper; /* MAC */
-#define FUNC_MF_CFG_UPPERMAC_MASK 0x0000ffff
-#define FUNC_MF_CFG_UPPERMAC_SHIFT 0
-#define FUNC_MF_CFG_UPPERMAC_DEFAULT FUNC_MF_CFG_UPPERMAC_MASK
- u32 mac_lower;
-#define FUNC_MF_CFG_LOWERMAC_DEFAULT 0xffffffff
-
- u32 e1hov_tag; /* VNI */
-#define FUNC_MF_CFG_E1HOV_TAG_MASK 0x0000ffff
-#define FUNC_MF_CFG_E1HOV_TAG_SHIFT 0
-#define FUNC_MF_CFG_E1HOV_TAG_DEFAULT FUNC_MF_CFG_E1HOV_TAG_MASK
-
- u32 reserved[2];
-
-};
-
-struct mf_cfg {
-
- struct shared_mf_cfg shared_mf_config;
- struct port_mf_cfg port_mf_config[PORT_MAX];
-#if defined(b710)
- struct func_mf_cfg func_mf_config[E1_FUNC_MAX];
-#else
- struct func_mf_cfg func_mf_config[E1H_FUNC_MAX];
-#endif
-
-};
-
-
-/****************************************************************************
- * Shared Memory Region *
- ****************************************************************************/
-struct shmem_region { /* SharedMem Offset (size) */
-
- u32 validity_map[PORT_MAX]; /* 0x0 (4*2 = 0x8) */
-#define SHR_MEM_FORMAT_REV_ID ('A'<<24)
-#define SHR_MEM_FORMAT_REV_MASK 0xff000000
- /* validity bits */
-#define SHR_MEM_VALIDITY_PCI_CFG 0x00100000
-#define SHR_MEM_VALIDITY_MB 0x00200000
-#define SHR_MEM_VALIDITY_DEV_INFO 0x00400000
-#define SHR_MEM_VALIDITY_RESERVED 0x00000007
- /* One licensing bit should be set */
-#define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038
-#define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008
-#define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010
-#define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020
- /* Active MFW */
-#define SHR_MEM_VALIDITY_ACTIVE_MFW_UNKNOWN 0x00000000
-#define SHR_MEM_VALIDITY_ACTIVE_MFW_IPMI 0x00000040
-#define SHR_MEM_VALIDITY_ACTIVE_MFW_UMP 0x00000080
-#define SHR_MEM_VALIDITY_ACTIVE_MFW_NCSI 0x000000c0
-#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0
-#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0
-
- struct dev_info dev_info; /* 0x8 (0x438) */
-
- u8 reserved[52*PORT_MAX];
-
- /* FW information (for internal FW use) */
- u32 fw_info_fio_offset; /* 0x4a8 (0x4) */
- struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */
-
- struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */
- struct drv_func_mb func_mb[E1H_FUNC_MAX];
-
- struct mf_cfg mf_cfg;
-
-}; /* 0x6dc */
-
-
-struct emac_stats {
- u32 rx_stat_ifhcinoctets;
- u32 rx_stat_ifhcinbadoctets;
- u32 rx_stat_etherstatsfragments;
- u32 rx_stat_ifhcinucastpkts;
- u32 rx_stat_ifhcinmulticastpkts;
- u32 rx_stat_ifhcinbroadcastpkts;
- u32 rx_stat_dot3statsfcserrors;
- u32 rx_stat_dot3statsalignmenterrors;
- u32 rx_stat_dot3statscarriersenseerrors;
- u32 rx_stat_xonpauseframesreceived;
- u32 rx_stat_xoffpauseframesreceived;
- u32 rx_stat_maccontrolframesreceived;
- u32 rx_stat_xoffstateentered;
- u32 rx_stat_dot3statsframestoolong;
- u32 rx_stat_etherstatsjabbers;
- u32 rx_stat_etherstatsundersizepkts;
- u32 rx_stat_etherstatspkts64octets;
- u32 rx_stat_etherstatspkts65octetsto127octets;
- u32 rx_stat_etherstatspkts128octetsto255octets;
- u32 rx_stat_etherstatspkts256octetsto511octets;
- u32 rx_stat_etherstatspkts512octetsto1023octets;
- u32 rx_stat_etherstatspkts1024octetsto1522octets;
- u32 rx_stat_etherstatspktsover1522octets;
-
- u32 rx_stat_falsecarriererrors;
-
- u32 tx_stat_ifhcoutoctets;
- u32 tx_stat_ifhcoutbadoctets;
- u32 tx_stat_etherstatscollisions;
- u32 tx_stat_outxonsent;
- u32 tx_stat_outxoffsent;
- u32 tx_stat_flowcontroldone;
- u32 tx_stat_dot3statssinglecollisionframes;
- u32 tx_stat_dot3statsmultiplecollisionframes;
- u32 tx_stat_dot3statsdeferredtransmissions;
- u32 tx_stat_dot3statsexcessivecollisions;
- u32 tx_stat_dot3statslatecollisions;
- u32 tx_stat_ifhcoutucastpkts;
- u32 tx_stat_ifhcoutmulticastpkts;
- u32 tx_stat_ifhcoutbroadcastpkts;
- u32 tx_stat_etherstatspkts64octets;
- u32 tx_stat_etherstatspkts65octetsto127octets;
- u32 tx_stat_etherstatspkts128octetsto255octets;
- u32 tx_stat_etherstatspkts256octetsto511octets;
- u32 tx_stat_etherstatspkts512octetsto1023octets;
- u32 tx_stat_etherstatspkts1024octetsto1522octets;
- u32 tx_stat_etherstatspktsover1522octets;
- u32 tx_stat_dot3statsinternalmactransmiterrors;
-};
-
-
-struct bmac_stats {
- u32 tx_stat_gtpkt_lo;
- u32 tx_stat_gtpkt_hi;
- u32 tx_stat_gtxpf_lo;
- u32 tx_stat_gtxpf_hi;
- u32 tx_stat_gtfcs_lo;
- u32 tx_stat_gtfcs_hi;
- u32 tx_stat_gtmca_lo;
- u32 tx_stat_gtmca_hi;
- u32 tx_stat_gtbca_lo;
- u32 tx_stat_gtbca_hi;
- u32 tx_stat_gtfrg_lo;
- u32 tx_stat_gtfrg_hi;
- u32 tx_stat_gtovr_lo;
- u32 tx_stat_gtovr_hi;
- u32 tx_stat_gt64_lo;
- u32 tx_stat_gt64_hi;
- u32 tx_stat_gt127_lo;
- u32 tx_stat_gt127_hi;
- u32 tx_stat_gt255_lo;
- u32 tx_stat_gt255_hi;
- u32 tx_stat_gt511_lo;
- u32 tx_stat_gt511_hi;
- u32 tx_stat_gt1023_lo;
- u32 tx_stat_gt1023_hi;
- u32 tx_stat_gt1518_lo;
- u32 tx_stat_gt1518_hi;
- u32 tx_stat_gt2047_lo;
- u32 tx_stat_gt2047_hi;
- u32 tx_stat_gt4095_lo;
- u32 tx_stat_gt4095_hi;
- u32 tx_stat_gt9216_lo;
- u32 tx_stat_gt9216_hi;
- u32 tx_stat_gt16383_lo;
- u32 tx_stat_gt16383_hi;
- u32 tx_stat_gtmax_lo;
- u32 tx_stat_gtmax_hi;
- u32 tx_stat_gtufl_lo;
- u32 tx_stat_gtufl_hi;
- u32 tx_stat_gterr_lo;
- u32 tx_stat_gterr_hi;
- u32 tx_stat_gtbyt_lo;
- u32 tx_stat_gtbyt_hi;
-
- u32 rx_stat_gr64_lo;
- u32 rx_stat_gr64_hi;
- u32 rx_stat_gr127_lo;
- u32 rx_stat_gr127_hi;
- u32 rx_stat_gr255_lo;
- u32 rx_stat_gr255_hi;
- u32 rx_stat_gr511_lo;
- u32 rx_stat_gr511_hi;
- u32 rx_stat_gr1023_lo;
- u32 rx_stat_gr1023_hi;
- u32 rx_stat_gr1518_lo;
- u32 rx_stat_gr1518_hi;
- u32 rx_stat_gr2047_lo;
- u32 rx_stat_gr2047_hi;
- u32 rx_stat_gr4095_lo;
- u32 rx_stat_gr4095_hi;
- u32 rx_stat_gr9216_lo;
- u32 rx_stat_gr9216_hi;
- u32 rx_stat_gr16383_lo;
- u32 rx_stat_gr16383_hi;
- u32 rx_stat_grmax_lo;
- u32 rx_stat_grmax_hi;
- u32 rx_stat_grpkt_lo;
- u32 rx_stat_grpkt_hi;
- u32 rx_stat_grfcs_lo;
- u32 rx_stat_grfcs_hi;
- u32 rx_stat_grmca_lo;
- u32 rx_stat_grmca_hi;
- u32 rx_stat_grbca_lo;
- u32 rx_stat_grbca_hi;
- u32 rx_stat_grxcf_lo;
- u32 rx_stat_grxcf_hi;
- u32 rx_stat_grxpf_lo;
- u32 rx_stat_grxpf_hi;
- u32 rx_stat_grxuo_lo;
- u32 rx_stat_grxuo_hi;
- u32 rx_stat_grjbr_lo;
- u32 rx_stat_grjbr_hi;
- u32 rx_stat_grovr_lo;
- u32 rx_stat_grovr_hi;
- u32 rx_stat_grflr_lo;
- u32 rx_stat_grflr_hi;
- u32 rx_stat_grmeg_lo;
- u32 rx_stat_grmeg_hi;
- u32 rx_stat_grmeb_lo;
- u32 rx_stat_grmeb_hi;
- u32 rx_stat_grbyt_lo;
- u32 rx_stat_grbyt_hi;
- u32 rx_stat_grund_lo;
- u32 rx_stat_grund_hi;
- u32 rx_stat_grfrg_lo;
- u32 rx_stat_grfrg_hi;
- u32 rx_stat_grerb_lo;
- u32 rx_stat_grerb_hi;
- u32 rx_stat_grfre_lo;
- u32 rx_stat_grfre_hi;
- u32 rx_stat_gripj_lo;
- u32 rx_stat_gripj_hi;
-};
-
-
-union mac_stats {
- struct emac_stats emac_stats;
- struct bmac_stats bmac_stats;
-};
-
-
-struct mac_stx {
- /* in_bad_octets */
- u32 rx_stat_ifhcinbadoctets_hi;
- u32 rx_stat_ifhcinbadoctets_lo;
-
- /* out_bad_octets */
- u32 tx_stat_ifhcoutbadoctets_hi;
- u32 tx_stat_ifhcoutbadoctets_lo;
-
- /* crc_receive_errors */
- u32 rx_stat_dot3statsfcserrors_hi;
- u32 rx_stat_dot3statsfcserrors_lo;
- /* alignment_errors */
- u32 rx_stat_dot3statsalignmenterrors_hi;
- u32 rx_stat_dot3statsalignmenterrors_lo;
- /* carrier_sense_errors */
- u32 rx_stat_dot3statscarriersenseerrors_hi;
- u32 rx_stat_dot3statscarriersenseerrors_lo;
- /* false_carrier_detections */
- u32 rx_stat_falsecarriererrors_hi;
- u32 rx_stat_falsecarriererrors_lo;
-
- /* runt_packets_received */
- u32 rx_stat_etherstatsundersizepkts_hi;
- u32 rx_stat_etherstatsundersizepkts_lo;
- /* jabber_packets_received */
- u32 rx_stat_dot3statsframestoolong_hi;
- u32 rx_stat_dot3statsframestoolong_lo;
-
- /* error_runt_packets_received */
- u32 rx_stat_etherstatsfragments_hi;
- u32 rx_stat_etherstatsfragments_lo;
- /* error_jabber_packets_received */
- u32 rx_stat_etherstatsjabbers_hi;
- u32 rx_stat_etherstatsjabbers_lo;
-
- /* control_frames_received */
- u32 rx_stat_maccontrolframesreceived_hi;
- u32 rx_stat_maccontrolframesreceived_lo;
- u32 rx_stat_bmac_xpf_hi;
- u32 rx_stat_bmac_xpf_lo;
- u32 rx_stat_bmac_xcf_hi;
- u32 rx_stat_bmac_xcf_lo;
-
- /* xoff_state_entered */
- u32 rx_stat_xoffstateentered_hi;
- u32 rx_stat_xoffstateentered_lo;
- /* pause_xon_frames_received */
- u32 rx_stat_xonpauseframesreceived_hi;
- u32 rx_stat_xonpauseframesreceived_lo;
- /* pause_xoff_frames_received */
- u32 rx_stat_xoffpauseframesreceived_hi;
- u32 rx_stat_xoffpauseframesreceived_lo;
- /* pause_xon_frames_transmitted */
- u32 tx_stat_outxonsent_hi;
- u32 tx_stat_outxonsent_lo;
- /* pause_xoff_frames_transmitted */
- u32 tx_stat_outxoffsent_hi;
- u32 tx_stat_outxoffsent_lo;
- /* flow_control_done */
- u32 tx_stat_flowcontroldone_hi;
- u32 tx_stat_flowcontroldone_lo;
-
- /* ether_stats_collisions */
- u32 tx_stat_etherstatscollisions_hi;
- u32 tx_stat_etherstatscollisions_lo;
- /* single_collision_transmit_frames */
- u32 tx_stat_dot3statssinglecollisionframes_hi;
- u32 tx_stat_dot3statssinglecollisionframes_lo;
- /* multiple_collision_transmit_frames */
- u32 tx_stat_dot3statsmultiplecollisionframes_hi;
- u32 tx_stat_dot3statsmultiplecollisionframes_lo;
- /* deferred_transmissions */
- u32 tx_stat_dot3statsdeferredtransmissions_hi;
- u32 tx_stat_dot3statsdeferredtransmissions_lo;
- /* excessive_collision_frames */
- u32 tx_stat_dot3statsexcessivecollisions_hi;
- u32 tx_stat_dot3statsexcessivecollisions_lo;
- /* late_collision_frames */
- u32 tx_stat_dot3statslatecollisions_hi;
- u32 tx_stat_dot3statslatecollisions_lo;
-
- /* frames_transmitted_64_bytes */
- u32 tx_stat_etherstatspkts64octets_hi;
- u32 tx_stat_etherstatspkts64octets_lo;
- /* frames_transmitted_65_127_bytes */
- u32 tx_stat_etherstatspkts65octetsto127octets_hi;
- u32 tx_stat_etherstatspkts65octetsto127octets_lo;
- /* frames_transmitted_128_255_bytes */
- u32 tx_stat_etherstatspkts128octetsto255octets_hi;
- u32 tx_stat_etherstatspkts128octetsto255octets_lo;
- /* frames_transmitted_256_511_bytes */
- u32 tx_stat_etherstatspkts256octetsto511octets_hi;
- u32 tx_stat_etherstatspkts256octetsto511octets_lo;
- /* frames_transmitted_512_1023_bytes */
- u32 tx_stat_etherstatspkts512octetsto1023octets_hi;
- u32 tx_stat_etherstatspkts512octetsto1023octets_lo;
- /* frames_transmitted_1024_1522_bytes */
- u32 tx_stat_etherstatspkts1024octetsto1522octets_hi;
- u32 tx_stat_etherstatspkts1024octetsto1522octets_lo;
- /* frames_transmitted_1523_9022_bytes */
- u32 tx_stat_etherstatspktsover1522octets_hi;
- u32 tx_stat_etherstatspktsover1522octets_lo;
- u32 tx_stat_bmac_2047_hi;
- u32 tx_stat_bmac_2047_lo;
- u32 tx_stat_bmac_4095_hi;
- u32 tx_stat_bmac_4095_lo;
- u32 tx_stat_bmac_9216_hi;
- u32 tx_stat_bmac_9216_lo;
- u32 tx_stat_bmac_16383_hi;
- u32 tx_stat_bmac_16383_lo;
-
- /* internal_mac_transmit_errors */
- u32 tx_stat_dot3statsinternalmactransmiterrors_hi;
- u32 tx_stat_dot3statsinternalmactransmiterrors_lo;
-
- /* if_out_discards */
- u32 tx_stat_bmac_ufl_hi;
- u32 tx_stat_bmac_ufl_lo;
-};
-
-
-#define MAC_STX_IDX_MAX 2
-
-struct host_port_stats {
- u32 host_port_stats_start;
-
- struct mac_stx mac_stx[MAC_STX_IDX_MAX];
-
- u32 brb_drop_hi;
- u32 brb_drop_lo;
-
- u32 host_port_stats_end;
-};
-
-
-struct host_func_stats {
- u32 host_func_stats_start;
-
- u32 total_bytes_received_hi;
- u32 total_bytes_received_lo;
-
- u32 total_bytes_transmitted_hi;
- u32 total_bytes_transmitted_lo;
-
- u32 total_unicast_packets_received_hi;
- u32 total_unicast_packets_received_lo;
-
- u32 total_multicast_packets_received_hi;
- u32 total_multicast_packets_received_lo;
-
- u32 total_broadcast_packets_received_hi;
- u32 total_broadcast_packets_received_lo;
-
- u32 total_unicast_packets_transmitted_hi;
- u32 total_unicast_packets_transmitted_lo;
-
- u32 total_multicast_packets_transmitted_hi;
- u32 total_multicast_packets_transmitted_lo;
-
- u32 total_broadcast_packets_transmitted_hi;
- u32 total_broadcast_packets_transmitted_lo;
-
- u32 valid_bytes_received_hi;
- u32 valid_bytes_received_lo;
-
- u32 host_func_stats_end;
-};
-
-
-#define BCM_5710_FW_MAJOR_VERSION 4
-#define BCM_5710_FW_MINOR_VERSION 5
-#define BCM_5710_FW_REVISION_VERSION 1
-#define BCM_5710_FW_COMPILE_FLAGS 1
-
-
-/*
- * attention bits
- */
-struct atten_def_status_block {
- u32 attn_bits;
- u32 attn_bits_ack;
-#if defined(__BIG_ENDIAN)
- u16 attn_bits_index;
- u8 reserved0;
- u8 status_block_id;
-#elif defined(__LITTLE_ENDIAN)
- u8 status_block_id;
- u8 reserved0;
- u16 attn_bits_index;
-#endif
- u32 reserved1;
-};
-
-
-/*
- * common data for all protocols
- */
-struct doorbell_hdr {
- u8 header;
-#define DOORBELL_HDR_RX (0x1<<0)
-#define DOORBELL_HDR_RX_SHIFT 0
-#define DOORBELL_HDR_DB_TYPE (0x1<<1)
-#define DOORBELL_HDR_DB_TYPE_SHIFT 1
-#define DOORBELL_HDR_DPM_SIZE (0x3<<2)
-#define DOORBELL_HDR_DPM_SIZE_SHIFT 2
-#define DOORBELL_HDR_CONN_TYPE (0xF<<4)
-#define DOORBELL_HDR_CONN_TYPE_SHIFT 4
-};
-
-/*
- * doorbell message sent to the chip
- */
-struct doorbell {
-#if defined(__BIG_ENDIAN)
- u16 zero_fill2;
- u8 zero_fill1;
- struct doorbell_hdr header;
-#elif defined(__LITTLE_ENDIAN)
- struct doorbell_hdr header;
- u8 zero_fill1;
- u16 zero_fill2;
-#endif
-};
-
-
-/*
- * IGU driver acknowledgement register
- */
-struct igu_ack_register {
-#if defined(__BIG_ENDIAN)
- u16 sb_id_and_flags;
-#define IGU_ACK_REGISTER_STATUS_BLOCK_ID (0x1F<<0)
-#define IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT 0
-#define IGU_ACK_REGISTER_STORM_ID (0x7<<5)
-#define IGU_ACK_REGISTER_STORM_ID_SHIFT 5
-#define IGU_ACK_REGISTER_UPDATE_INDEX (0x1<<8)
-#define IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT 8
-#define IGU_ACK_REGISTER_INTERRUPT_MODE (0x3<<9)
-#define IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT 9
-#define IGU_ACK_REGISTER_RESERVED (0x1F<<11)
-#define IGU_ACK_REGISTER_RESERVED_SHIFT 11
- u16 status_block_index;
-#elif defined(__LITTLE_ENDIAN)
- u16 status_block_index;
- u16 sb_id_and_flags;
-#define IGU_ACK_REGISTER_STATUS_BLOCK_ID (0x1F<<0)
-#define IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT 0
-#define IGU_ACK_REGISTER_STORM_ID (0x7<<5)
-#define IGU_ACK_REGISTER_STORM_ID_SHIFT 5
-#define IGU_ACK_REGISTER_UPDATE_INDEX (0x1<<8)
-#define IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT 8
-#define IGU_ACK_REGISTER_INTERRUPT_MODE (0x3<<9)
-#define IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT 9
-#define IGU_ACK_REGISTER_RESERVED (0x1F<<11)
-#define IGU_ACK_REGISTER_RESERVED_SHIFT 11
-#endif
-};
-
-
-/*
- * Parser parsing flags field
- */
-struct parsing_flags {
- u16 flags;
-#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE (0x1<<0)
-#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE_SHIFT 0
-#define PARSING_FLAGS_VLAN (0x1<<1)
-#define PARSING_FLAGS_VLAN_SHIFT 1
-#define PARSING_FLAGS_EXTRA_VLAN (0x1<<2)
-#define PARSING_FLAGS_EXTRA_VLAN_SHIFT 2
-#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL (0x3<<3)
-#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT 3
-#define PARSING_FLAGS_IP_OPTIONS (0x1<<5)
-#define PARSING_FLAGS_IP_OPTIONS_SHIFT 5
-#define PARSING_FLAGS_FRAGMENTATION_STATUS (0x1<<6)
-#define PARSING_FLAGS_FRAGMENTATION_STATUS_SHIFT 6
-#define PARSING_FLAGS_OVER_IP_PROTOCOL (0x3<<7)
-#define PARSING_FLAGS_OVER_IP_PROTOCOL_SHIFT 7
-#define PARSING_FLAGS_PURE_ACK_INDICATION (0x1<<9)
-#define PARSING_FLAGS_PURE_ACK_INDICATION_SHIFT 9
-#define PARSING_FLAGS_TCP_OPTIONS_EXIST (0x1<<10)
-#define PARSING_FLAGS_TCP_OPTIONS_EXIST_SHIFT 10
-#define PARSING_FLAGS_TIME_STAMP_EXIST_FLAG (0x1<<11)
-#define PARSING_FLAGS_TIME_STAMP_EXIST_FLAG_SHIFT 11
-#define PARSING_FLAGS_CONNECTION_MATCH (0x1<<12)
-#define PARSING_FLAGS_CONNECTION_MATCH_SHIFT 12
-#define PARSING_FLAGS_LLC_SNAP (0x1<<13)
-#define PARSING_FLAGS_LLC_SNAP_SHIFT 13
-#define PARSING_FLAGS_RESERVED0 (0x3<<14)
-#define PARSING_FLAGS_RESERVED0_SHIFT 14
-};
-
-
-struct regpair {
- u32 lo;
- u32 hi;
-};
-
-
-/*
- * dmae command structure
- */
-struct dmae_command {
- u32 opcode;
-#define DMAE_COMMAND_SRC (0x1<<0)
-#define DMAE_COMMAND_SRC_SHIFT 0
-#define DMAE_COMMAND_DST (0x3<<1)
-#define DMAE_COMMAND_DST_SHIFT 1
-#define DMAE_COMMAND_C_DST (0x1<<3)
-#define DMAE_COMMAND_C_DST_SHIFT 3
-#define DMAE_COMMAND_C_TYPE_ENABLE (0x1<<4)
-#define DMAE_COMMAND_C_TYPE_ENABLE_SHIFT 4
-#define DMAE_COMMAND_C_TYPE_CRC_ENABLE (0x1<<5)
-#define DMAE_COMMAND_C_TYPE_CRC_ENABLE_SHIFT 5
-#define DMAE_COMMAND_C_TYPE_CRC_OFFSET (0x7<<6)
-#define DMAE_COMMAND_C_TYPE_CRC_OFFSET_SHIFT 6
-#define DMAE_COMMAND_ENDIANITY (0x3<<9)
-#define DMAE_COMMAND_ENDIANITY_SHIFT 9
-#define DMAE_COMMAND_PORT (0x1<<11)
-#define DMAE_COMMAND_PORT_SHIFT 11
-#define DMAE_COMMAND_CRC_RESET (0x1<<12)
-#define DMAE_COMMAND_CRC_RESET_SHIFT 12
-#define DMAE_COMMAND_SRC_RESET (0x1<<13)
-#define DMAE_COMMAND_SRC_RESET_SHIFT 13
-#define DMAE_COMMAND_DST_RESET (0x1<<14)
-#define DMAE_COMMAND_DST_RESET_SHIFT 14
-#define DMAE_COMMAND_E1HVN (0x3<<15)
-#define DMAE_COMMAND_E1HVN_SHIFT 15
-#define DMAE_COMMAND_RESERVED0 (0x7FFF<<17)
-#define DMAE_COMMAND_RESERVED0_SHIFT 17
- u32 src_addr_lo;
- u32 src_addr_hi;
- u32 dst_addr_lo;
- u32 dst_addr_hi;
-#if defined(__BIG_ENDIAN)
- u16 reserved1;
- u16 len;
-#elif defined(__LITTLE_ENDIAN)
- u16 len;
- u16 reserved1;
-#endif
- u32 comp_addr_lo;
- u32 comp_addr_hi;
- u32 comp_val;
- u32 crc32;
- u32 crc32_c;
-#if defined(__BIG_ENDIAN)
- u16 crc16_c;
- u16 crc16;
-#elif defined(__LITTLE_ENDIAN)
- u16 crc16;
- u16 crc16_c;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 reserved2;
- u16 crc_t10;
-#elif defined(__LITTLE_ENDIAN)
- u16 crc_t10;
- u16 reserved2;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 xsum8;
- u16 xsum16;
-#elif defined(__LITTLE_ENDIAN)
- u16 xsum16;
- u16 xsum8;
-#endif
-};
-
-
-struct double_regpair {
- u32 regpair0_lo;
- u32 regpair0_hi;
- u32 regpair1_lo;
- u32 regpair1_hi;
-};
-
-
-/*
- * The eth storm context of Ustorm (configuration part)
- */
-struct ustorm_eth_st_context_config {
-#if defined(__BIG_ENDIAN)
- u8 flags;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
- u8 status_block_id;
- u8 clientId;
- u8 sb_index_numbers;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4
-#elif defined(__LITTLE_ENDIAN)
- u8 sb_index_numbers;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4
- u8 clientId;
- u8 status_block_id;
- u8 flags;
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
-#endif
-#if defined(__BIG_ENDIAN)
- u16 bd_buff_size;
- u16 mc_alignment_size;
-#elif defined(__LITTLE_ENDIAN)
- u16 mc_alignment_size;
- u16 bd_buff_size;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __local_sge_prod;
- u8 __local_bd_prod;
- u16 sge_buff_size;
-#elif defined(__LITTLE_ENDIAN)
- u16 sge_buff_size;
- u8 __local_bd_prod;
- u8 __local_sge_prod;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __bd_cons;
- u16 __sge_cons;
-#elif defined(__LITTLE_ENDIAN)
- u16 __sge_cons;
- u16 __bd_cons;
-#endif
- u32 bd_page_base_lo;
- u32 bd_page_base_hi;
- u32 sge_page_base_lo;
- u32 sge_page_base_hi;
-};
-
-/*
- * The eth Rx Buffer Descriptor
- */
-struct eth_rx_bd {
- u32 addr_lo;
- u32 addr_hi;
-};
-
-/*
- * The eth Rx SGE Descriptor
- */
-struct eth_rx_sge {
- u32 addr_lo;
- u32 addr_hi;
-};
-
-/*
- * Local BDs and SGEs rings (in ETH)
- */
-struct eth_local_rx_rings {
- struct eth_rx_bd __local_bd_ring[16];
- struct eth_rx_sge __local_sge_ring[12];
-};
-
-/*
- * The eth storm context of Ustorm
- */
-struct ustorm_eth_st_context {
- struct ustorm_eth_st_context_config common;
- struct eth_local_rx_rings __rings;
-};
-
-/*
- * The eth storm context of Tstorm
- */
-struct tstorm_eth_st_context {
- u32 __reserved0[28];
-};
-
-/*
- * The eth aggregative context section of Xstorm
- */
-struct xstorm_eth_extra_ag_context_section {
-#if defined(__BIG_ENDIAN)
- u8 __tcp_agg_vars1;
- u8 __reserved50;
- u16 __mss;
-#elif defined(__LITTLE_ENDIAN)
- u16 __mss;
- u8 __reserved50;
- u8 __tcp_agg_vars1;
-#endif
- u32 __snd_nxt;
- u32 __tx_wnd;
- u32 __snd_una;
- u32 __reserved53;
-#if defined(__BIG_ENDIAN)
- u8 __agg_val8_th;
- u8 __agg_val8;
- u16 __tcp_agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __tcp_agg_vars2;
- u8 __agg_val8;
- u8 __agg_val8_th;
-#endif
- u32 __reserved58;
- u32 __reserved59;
- u32 __reserved60;
- u32 __reserved61;
-#if defined(__BIG_ENDIAN)
- u16 __agg_val7_th;
- u16 __agg_val7;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val7;
- u16 __agg_val7_th;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __tcp_agg_vars5;
- u8 __tcp_agg_vars4;
- u8 __tcp_agg_vars3;
- u8 __reserved62;
-#elif defined(__LITTLE_ENDIAN)
- u8 __reserved62;
- u8 __tcp_agg_vars3;
- u8 __tcp_agg_vars4;
- u8 __tcp_agg_vars5;
-#endif
- u32 __tcp_agg_vars6;
-#if defined(__BIG_ENDIAN)
- u16 __agg_misc6;
- u16 __tcp_agg_vars7;
-#elif defined(__LITTLE_ENDIAN)
- u16 __tcp_agg_vars7;
- u16 __agg_misc6;
-#endif
- u32 __agg_val10;
- u32 __agg_val10_th;
-#if defined(__BIG_ENDIAN)
- u16 __reserved3;
- u8 __reserved2;
- u8 __da_only_cnt;
-#elif defined(__LITTLE_ENDIAN)
- u8 __da_only_cnt;
- u8 __reserved2;
- u16 __reserved3;
-#endif
-};
-
-/*
- * The eth aggregative context of Xstorm
- */
-struct xstorm_eth_ag_context {
-#if defined(__BIG_ENDIAN)
- u16 __bd_prod;
- u8 __agg_vars1;
- u8 __state;
-#elif defined(__LITTLE_ENDIAN)
- u8 __state;
- u8 __agg_vars1;
- u16 __bd_prod;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 cdu_reserved;
- u8 __agg_vars4;
- u8 __agg_vars3;
- u8 __agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u8 __agg_vars2;
- u8 __agg_vars3;
- u8 __agg_vars4;
- u8 cdu_reserved;
-#endif
- u32 __more_packets_to_send;
-#if defined(__BIG_ENDIAN)
- u16 __agg_vars5;
- u16 __agg_val4_th;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val4_th;
- u16 __agg_vars5;
-#endif
- struct xstorm_eth_extra_ag_context_section __extra_section;
-#if defined(__BIG_ENDIAN)
- u16 __agg_vars7;
- u8 __agg_val3_th;
- u8 __agg_vars6;
-#elif defined(__LITTLE_ENDIAN)
- u8 __agg_vars6;
- u8 __agg_val3_th;
- u16 __agg_vars7;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val11_th;
- u16 __agg_val11;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val11;
- u16 __agg_val11_th;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __reserved1;
- u8 __agg_val6_th;
- u16 __agg_val9;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val9;
- u8 __agg_val6_th;
- u8 __reserved1;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val2_th;
- u16 __agg_val2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val2;
- u16 __agg_val2_th;
-#endif
- u32 __agg_vars8;
-#if defined(__BIG_ENDIAN)
- u16 __agg_misc0;
- u16 __agg_val4;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val4;
- u16 __agg_misc0;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __agg_val3;
- u8 __agg_val6;
- u8 __agg_val5_th;
- u8 __agg_val5;
-#elif defined(__LITTLE_ENDIAN)
- u8 __agg_val5;
- u8 __agg_val5_th;
- u8 __agg_val6;
- u8 __agg_val3;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_misc1;
- u16 __bd_ind_max_val;
-#elif defined(__LITTLE_ENDIAN)
- u16 __bd_ind_max_val;
- u16 __agg_misc1;
-#endif
- u32 __reserved57;
- u32 __agg_misc4;
- u32 __agg_misc5;
-};
-
-/*
- * The eth aggregative context section of Tstorm
- */
-struct tstorm_eth_extra_ag_context_section {
- u32 __agg_val1;
-#if defined(__BIG_ENDIAN)
- u8 __tcp_agg_vars2;
- u8 __agg_val3;
- u16 __agg_val2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val2;
- u8 __agg_val3;
- u8 __tcp_agg_vars2;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val5;
- u8 __agg_val6;
- u8 __tcp_agg_vars3;
-#elif defined(__LITTLE_ENDIAN)
- u8 __tcp_agg_vars3;
- u8 __agg_val6;
- u16 __agg_val5;
-#endif
- u32 __reserved63;
- u32 __reserved64;
- u32 __reserved65;
- u32 __reserved66;
- u32 __reserved67;
- u32 __tcp_agg_vars1;
- u32 __reserved61;
- u32 __reserved62;
- u32 __reserved2;
-};
-
-/*
- * The eth aggregative context of Tstorm
- */
-struct tstorm_eth_ag_context {
-#if defined(__BIG_ENDIAN)
- u16 __reserved54;
- u8 __agg_vars1;
- u8 __state;
-#elif defined(__LITTLE_ENDIAN)
- u8 __state;
- u8 __agg_vars1;
- u16 __reserved54;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __agg_val4;
- u16 __agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_vars2;
- u16 __agg_val4;
-#endif
- struct tstorm_eth_extra_ag_context_section __extra_section;
-};
-
-/*
- * The eth aggregative context of Cstorm
- */
-struct cstorm_eth_ag_context {
- u32 __agg_vars1;
-#if defined(__BIG_ENDIAN)
- u8 __aux1_th;
- u8 __aux1_val;
- u16 __agg_vars2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_vars2;
- u8 __aux1_val;
- u8 __aux1_th;
-#endif
- u32 __num_of_treated_packet;
- u32 __last_packet_treated;
-#if defined(__BIG_ENDIAN)
- u16 __reserved58;
- u16 __reserved57;
-#elif defined(__LITTLE_ENDIAN)
- u16 __reserved57;
- u16 __reserved58;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 __reserved62;
- u8 __reserved61;
- u8 __reserved60;
- u8 __reserved59;
-#elif defined(__LITTLE_ENDIAN)
- u8 __reserved59;
- u8 __reserved60;
- u8 __reserved61;
- u8 __reserved62;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __reserved64;
- u16 __reserved63;
-#elif defined(__LITTLE_ENDIAN)
- u16 __reserved63;
- u16 __reserved64;
-#endif
- u32 __reserved65;
-#if defined(__BIG_ENDIAN)
- u16 __agg_vars3;
- u16 __rq_inv_cnt;
-#elif defined(__LITTLE_ENDIAN)
- u16 __rq_inv_cnt;
- u16 __agg_vars3;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __packet_index_th;
- u16 __packet_index;
-#elif defined(__LITTLE_ENDIAN)
- u16 __packet_index;
- u16 __packet_index_th;
-#endif
-};
-
-/*
- * The eth aggregative context of Ustorm
- */
-struct ustorm_eth_ag_context {
-#if defined(__BIG_ENDIAN)
- u8 __aux_counter_flags;
- u8 __agg_vars2;
- u8 __agg_vars1;
- u8 __state;
-#elif defined(__LITTLE_ENDIAN)
- u8 __state;
- u8 __agg_vars1;
- u8 __agg_vars2;
- u8 __aux_counter_flags;
-#endif
-#if defined(__BIG_ENDIAN)
- u8 cdu_usage;
- u8 __agg_misc2;
- u16 __agg_misc1;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_misc1;
- u8 __agg_misc2;
- u8 cdu_usage;
-#endif
- u32 __agg_misc4;
-#if defined(__BIG_ENDIAN)
- u8 __agg_val3_th;
- u8 __agg_val3;
- u16 __agg_misc3;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_misc3;
- u8 __agg_val3;
- u8 __agg_val3_th;
-#endif
- u32 __agg_val1;
- u32 __agg_misc4_th;
-#if defined(__BIG_ENDIAN)
- u16 __agg_val2_th;
- u16 __agg_val2;
-#elif defined(__LITTLE_ENDIAN)
- u16 __agg_val2;
- u16 __agg_val2_th;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 __reserved2;
- u8 __decision_rules;
- u8 __decision_rule_enable_bits;
-#elif defined(__LITTLE_ENDIAN)
- u8 __decision_rule_enable_bits;
- u8 __decision_rules;
- u16 __reserved2;
-#endif
-};
-
-/*
- * Timers connection context
- */
-struct timers_block_context {
- u32 __reserved_0;
- u32 __reserved_1;
- u32 __reserved_2;
- u32 flags;
-#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0)
-#define __TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0
-#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2)
-#define TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2
-#define __TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3)
-#define __TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3
-};
-
-/*
- * structure for easy accessibility to assembler
- */
-struct eth_tx_bd_flags {
- u8 as_bitfield;
-#define ETH_TX_BD_FLAGS_VLAN_TAG (0x1<<0)
-#define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT 0
-#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<1)
-#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 1
-#define ETH_TX_BD_FLAGS_TCP_CSUM (0x1<<2)
-#define ETH_TX_BD_FLAGS_TCP_CSUM_SHIFT 2
-#define ETH_TX_BD_FLAGS_END_BD (0x1<<3)
-#define ETH_TX_BD_FLAGS_END_BD_SHIFT 3
-#define ETH_TX_BD_FLAGS_START_BD (0x1<<4)
-#define ETH_TX_BD_FLAGS_START_BD_SHIFT 4
-#define ETH_TX_BD_FLAGS_HDR_POOL (0x1<<5)
-#define ETH_TX_BD_FLAGS_HDR_POOL_SHIFT 5
-#define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6)
-#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6
-#define ETH_TX_BD_FLAGS_IPV6 (0x1<<7)
-#define ETH_TX_BD_FLAGS_IPV6_SHIFT 7
-};
-
-/*
- * The eth Tx Buffer Descriptor
- */
-struct eth_tx_bd {
- u32 addr_lo;
- u32 addr_hi;
- u16 nbd;
- u16 nbytes;
- u16 vlan;
- struct eth_tx_bd_flags bd_flags;
- u8 general_data;
-#define ETH_TX_BD_HDR_NBDS (0x3F<<0)
-#define ETH_TX_BD_HDR_NBDS_SHIFT 0
-#define ETH_TX_BD_ETH_ADDR_TYPE (0x3<<6)
-#define ETH_TX_BD_ETH_ADDR_TYPE_SHIFT 6
-};
-
-/*
- * Tx parsing BD structure for ETH,Relevant in START
- */
-struct eth_tx_parse_bd {
- u8 global_data;
-#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET (0xF<<0)
-#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET_SHIFT 0
-#define ETH_TX_PARSE_BD_CS_ANY_FLG (0x1<<4)
-#define ETH_TX_PARSE_BD_CS_ANY_FLG_SHIFT 4
-#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN (0x1<<5)
-#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN_SHIFT 5
-#define ETH_TX_PARSE_BD_LLC_SNAP_EN (0x1<<6)
-#define ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT 6
-#define ETH_TX_PARSE_BD_NS_FLG (0x1<<7)
-#define ETH_TX_PARSE_BD_NS_FLG_SHIFT 7
- u8 tcp_flags;
-#define ETH_TX_PARSE_BD_FIN_FLG (0x1<<0)
-#define ETH_TX_PARSE_BD_FIN_FLG_SHIFT 0
-#define ETH_TX_PARSE_BD_SYN_FLG (0x1<<1)
-#define ETH_TX_PARSE_BD_SYN_FLG_SHIFT 1
-#define ETH_TX_PARSE_BD_RST_FLG (0x1<<2)
-#define ETH_TX_PARSE_BD_RST_FLG_SHIFT 2
-#define ETH_TX_PARSE_BD_PSH_FLG (0x1<<3)
-#define ETH_TX_PARSE_BD_PSH_FLG_SHIFT 3
-#define ETH_TX_PARSE_BD_ACK_FLG (0x1<<4)
-#define ETH_TX_PARSE_BD_ACK_FLG_SHIFT 4
-#define ETH_TX_PARSE_BD_URG_FLG (0x1<<5)
-#define ETH_TX_PARSE_BD_URG_FLG_SHIFT 5
-#define ETH_TX_PARSE_BD_ECE_FLG (0x1<<6)
-#define ETH_TX_PARSE_BD_ECE_FLG_SHIFT 6
-#define ETH_TX_PARSE_BD_CWR_FLG (0x1<<7)
-#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7
- u8 ip_hlen;
- s8 cs_offset;
- u16 total_hlen;
- u16 lso_mss;
- u16 tcp_pseudo_csum;
- u16 ip_id;
- u32 tcp_send_seq;
-};
-
-/*
- * The last BD in the BD memory will hold a pointer to the next BD memory
- */
-struct eth_tx_next_bd {
- u32 addr_lo;
- u32 addr_hi;
- u8 reserved[8];
-};
-
-/*
- * union for 3 Bd types
- */
-union eth_tx_bd_types {
- struct eth_tx_bd reg_bd;
- struct eth_tx_parse_bd parse_bd;
- struct eth_tx_next_bd next_bd;
-};
-
-/*
- * The eth storm context of Xstorm
- */
-struct xstorm_eth_st_context {
- u32 tx_bd_page_base_lo;
- u32 tx_bd_page_base_hi;
-#if defined(__BIG_ENDIAN)
- u16 tx_bd_cons;
- u8 statistics_data;
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7
- u8 __local_tx_bd_prod;
-#elif defined(__LITTLE_ENDIAN)
- u8 __local_tx_bd_prod;
- u8 statistics_data;
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7)
-#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7
- u16 tx_bd_cons;
-#endif
- u32 db_data_addr_lo;
- u32 db_data_addr_hi;
- u32 __pkt_cons;
- u32 __gso_next;
- u32 is_eth_conn_1b;
- union eth_tx_bd_types __bds[13];
-};
-
-/*
- * The eth storm context of Cstorm
- */
-struct cstorm_eth_st_context {
-#if defined(__BIG_ENDIAN)
- u16 __reserved0;
- u8 sb_index_number;
- u8 status_block_id;
-#elif defined(__LITTLE_ENDIAN)
- u8 status_block_id;
- u8 sb_index_number;
- u16 __reserved0;
-#endif
- u32 __reserved1[3];
-};
-
-/*
- * Ethernet connection context
- */
-struct eth_context {
- struct ustorm_eth_st_context ustorm_st_context;
- struct tstorm_eth_st_context tstorm_st_context;
- struct xstorm_eth_ag_context xstorm_ag_context;
- struct tstorm_eth_ag_context tstorm_ag_context;
- struct cstorm_eth_ag_context cstorm_ag_context;
- struct ustorm_eth_ag_context ustorm_ag_context;
- struct timers_block_context timers_context;
- struct xstorm_eth_st_context xstorm_st_context;
- struct cstorm_eth_st_context cstorm_st_context;
-};
-
-
-/*
- * Ethernet doorbell
- */
-struct eth_tx_doorbell {
-#if defined(__BIG_ENDIAN)
- u16 npackets;
- u8 params;
-#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0)
-#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0
-#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6)
-#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6
-#define ETH_TX_DOORBELL_SPARE (0x1<<7)
-#define ETH_TX_DOORBELL_SPARE_SHIFT 7
- struct doorbell_hdr hdr;
-#elif defined(__LITTLE_ENDIAN)
- struct doorbell_hdr hdr;
- u8 params;
-#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0)
-#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0
-#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6)
-#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6
-#define ETH_TX_DOORBELL_SPARE (0x1<<7)
-#define ETH_TX_DOORBELL_SPARE_SHIFT 7
- u16 npackets;
-#endif
-};
-
-
-/*
- * ustorm status block
- */
-struct ustorm_def_status_block {
- u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
- u8 func;
- u8 status_block_id;
- u32 __flags;
-};
-
-/*
- * cstorm status block
- */
-struct cstorm_def_status_block {
- u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
- u8 func;
- u8 status_block_id;
- u32 __flags;
-};
-
-/*
- * xstorm status block
- */
-struct xstorm_def_status_block {
- u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
- u8 func;
- u8 status_block_id;
- u32 __flags;
-};
-
-/*
- * tstorm status block
- */
-struct tstorm_def_status_block {
- u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
- u8 func;
- u8 status_block_id;
- u32 __flags;
-};
-
-/*
- * host status block
- */
-struct host_def_status_block {
- struct atten_def_status_block atten_status_block;
- struct ustorm_def_status_block u_def_status_block;
- struct cstorm_def_status_block c_def_status_block;
- struct xstorm_def_status_block x_def_status_block;
- struct tstorm_def_status_block t_def_status_block;
-};
-
-
-/*
- * ustorm status block
- */
-struct ustorm_status_block {
- u16 index_values[HC_USTORM_SB_NUM_INDICES];
- u16 status_block_index;
- u8 func;
- u8 status_block_id;
- u32 __flags;
-};
-
-/*
- * cstorm status block
- */
-struct cstorm_status_block {
- u16 index_values[HC_CSTORM_SB_NUM_INDICES];
- u16 status_block_index;
- u8 func;
- u8 status_block_id;
- u32 __flags;
-};
-
-/*
- * host status block
- */
-struct host_status_block {
- struct ustorm_status_block u_status_block;
- struct cstorm_status_block c_status_block;
-};
-
-
-/*
- * The data for RSS setup ramrod
- */
-struct eth_client_setup_ramrod_data {
- u32 client_id_5b;
- u8 is_rdma_1b;
- u8 reserved0;
- u16 reserved1;
-};
-
-
-/*
- * L2 dynamic host coalescing init parameters
- */
-struct eth_dynamic_hc_config {
- u32 threshold[3];
- u8 hc_timeout[4];
-};
-
-
-/*
- * regular eth FP CQE parameters struct
- */
-struct eth_fast_path_rx_cqe {
- u8 type_error_flags;
-#define ETH_FAST_PATH_RX_CQE_TYPE (0x1<<0)
-#define ETH_FAST_PATH_RX_CQE_TYPE_SHIFT 0
-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<1)
-#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 1
-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<2)
-#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 2
-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<3)
-#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 3
-#define ETH_FAST_PATH_RX_CQE_START_FLG (0x1<<4)
-#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4
-#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5)
-#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5
-#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6)
-#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6
- u8 status_flags;
-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0)
-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0
-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG (0x1<<3)
-#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG_SHIFT 3
-#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG (0x1<<4)
-#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG_SHIFT 4
-#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG (0x1<<5)
-#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG_SHIFT 5
-#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG (0x1<<6)
-#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG_SHIFT 6
-#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG (0x1<<7)
-#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7
- u8 placement_offset;
- u8 queue_index;
- u32 rss_hash_result;
- u16 vlan_tag;
- u16 pkt_len;
- u16 len_on_bd;
- struct parsing_flags pars_flags;
- u16 sgl[8];
-};
-
-
-/*
- * The data for RSS setup ramrod
- */
-struct eth_halt_ramrod_data {
- u32 client_id_5b;
- u32 reserved0;
-};
-
-
-/*
- * The data for statistics query ramrod
- */
-struct eth_query_ramrod_data {
-#if defined(__BIG_ENDIAN)
- u8 reserved0;
- u8 collect_port_1b;
- u16 drv_counter;
-#elif defined(__LITTLE_ENDIAN)
- u16 drv_counter;
- u8 collect_port_1b;
- u8 reserved0;
-#endif
- u32 ctr_id_vector;
-};
-
-
-/*
- * Place holder for ramrods protocol specific data
- */
-struct ramrod_data {
- u32 data_lo;
- u32 data_hi;
-};
-
-/*
- * union for ramrod data for Ethernet protocol (CQE) (force size of 16 bits)
- */
-union eth_ramrod_data {
- struct ramrod_data general;
-};
-
-
-/*
- * Rx Last BD in page (in ETH)
- */
-struct eth_rx_bd_next_page {
- u32 addr_lo;
- u32 addr_hi;
- u8 reserved[8];
-};
-
-
-/*
- * Eth Rx Cqe structure- general structure for ramrods
- */
-struct common_ramrod_eth_rx_cqe {
- u8 ramrod_type;
-#define COMMON_RAMROD_ETH_RX_CQE_TYPE (0x1<<0)
-#define COMMON_RAMROD_ETH_RX_CQE_TYPE_SHIFT 0
-#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x7F<<1)
-#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 1
- u8 conn_type_3b;
- u16 reserved1;
- u32 conn_and_cmd_data;
-#define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0)
-#define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0
-#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24)
-#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24
- struct ramrod_data protocol_data;
- u32 reserved2[4];
-};
-
-/*
- * Rx Last CQE in page (in ETH)
- */
-struct eth_rx_cqe_next_page {
- u32 addr_lo;
- u32 addr_hi;
- u32 reserved[6];
-};
-
-/*
- * union for all eth rx cqe types (fix their sizes)
- */
-union eth_rx_cqe {
- struct eth_fast_path_rx_cqe fast_path_cqe;
- struct common_ramrod_eth_rx_cqe ramrod_cqe;
- struct eth_rx_cqe_next_page next_page_cqe;
-};
-
-
-/*
- * common data for all protocols
- */
-struct spe_hdr {
- u32 conn_and_cmd_data;
-#define SPE_HDR_CID (0xFFFFFF<<0)
-#define SPE_HDR_CID_SHIFT 0
-#define SPE_HDR_CMD_ID (0xFF<<24)
-#define SPE_HDR_CMD_ID_SHIFT 24
- u16 type;
-#define SPE_HDR_CONN_TYPE (0xFF<<0)
-#define SPE_HDR_CONN_TYPE_SHIFT 0
-#define SPE_HDR_COMMON_RAMROD (0xFF<<8)
-#define SPE_HDR_COMMON_RAMROD_SHIFT 8
- u16 reserved;
-};
-
-/*
- * Ethernet slow path element
- */
-union eth_specific_data {
- u8 protocol_data[8];
- struct regpair mac_config_addr;
- struct eth_client_setup_ramrod_data client_setup_ramrod_data;
- struct eth_halt_ramrod_data halt_ramrod_data;
- struct regpair leading_cqe_addr;
- struct regpair update_data_addr;
- struct eth_query_ramrod_data query_ramrod_data;
-};
-
-/*
- * Ethernet slow path element
- */
-struct eth_spe {
- struct spe_hdr hdr;
- union eth_specific_data data;
-};
-
-
-/*
- * doorbell data in host memory
- */
-struct eth_tx_db_data {
- u32 packets_prod;
- u16 bds_prod;
- u16 reserved;
-};
-
-
-/*
- * Common configuration parameters per function in Tstorm
- */
-struct tstorm_eth_function_common_config {
-#if defined(__BIG_ENDIAN)
- u8 leading_client_id;
- u8 rss_result_mask;
- u16 config_flags;
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
-#elif defined(__LITTLE_ENDIAN)
- u16 config_flags;
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
- u8 rss_result_mask;
- u8 leading_client_id;
-#endif
- u16 vlan_id[2];
-};
-
-/*
- * parameters for eth update ramrod
- */
-struct eth_update_ramrod_data {
- struct tstorm_eth_function_common_config func_config;
- u8 indirectionTable[128];
-};
-
-
-/*
- * MAC filtering configuration command header
- */
-struct mac_configuration_hdr {
- u8 length_6b;
- u8 offset;
- u16 client_id;
- u32 reserved1;
-};
-
-/*
- * MAC address in list for ramrod
- */
-struct tstorm_cam_entry {
- u16 lsb_mac_addr;
- u16 middle_mac_addr;
- u16 msb_mac_addr;
- u16 flags;
-#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0)
-#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0
-#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1)
-#define TSTORM_CAM_ENTRY_RSRVVAL0_SHIFT 1
-#define TSTORM_CAM_ENTRY_RESERVED0 (0xFFF<<4)
-#define TSTORM_CAM_ENTRY_RESERVED0_SHIFT 4
-};
-
-/*
- * MAC filtering: CAM target table entry
- */
-struct tstorm_cam_target_table_entry {
- u8 flags;
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST (0x1<<0)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST_SHIFT 0
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<1)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 1
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE (0x1<<2)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE_SHIFT 2
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC (0x1<<3)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC_SHIFT 3
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0 (0xF<<4)
-#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0_SHIFT 4
- u8 client_id;
- u16 vlan_id;
-};
-
-/*
- * MAC address in list for ramrod
- */
-struct mac_configuration_entry {
- struct tstorm_cam_entry cam_entry;
- struct tstorm_cam_target_table_entry target_table_entry;
-};
-
-/*
- * MAC filtering configuration command
- */
-struct mac_configuration_cmd {
- struct mac_configuration_hdr hdr;
- struct mac_configuration_entry config_table[64];
-};
-
-
-/*
- * MAC address in list for ramrod
- */
-struct mac_configuration_entry_e1h {
- u16 lsb_mac_addr;
- u16 middle_mac_addr;
- u16 msb_mac_addr;
- u16 vlan_id;
- u16 e1hov_id;
- u8 client_id;
- u8 flags;
-#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0)
-#define MAC_CONFIGURATION_ENTRY_E1H_PORT_SHIFT 0
-#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE (0x1<<1)
-#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE_SHIFT 1
-#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC (0x1<<2)
-#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC_SHIFT 2
-#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED0 (0x1F<<3)
-#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED0_SHIFT 3
-};
-
-/*
- * MAC filtering configuration command
- */
-struct mac_configuration_cmd_e1h {
- struct mac_configuration_hdr hdr;
- struct mac_configuration_entry_e1h config_table[32];
-};
-
-
-/*
- * approximate-match multicast filtering for E1H per function in Tstorm
- */
-struct tstorm_eth_approximate_match_multicast_filtering {
- u32 mcast_add_hash_bit_array[8];
-};
-
-
-/*
- * Configuration parameters per client in Tstorm
- */
-struct tstorm_eth_client_config {
-#if defined(__BIG_ENDIAN)
- u8 max_sges_for_packet;
- u8 statistics_counter_id;
- u16 mtu;
-#elif defined(__LITTLE_ENDIAN)
- u16 mtu;
- u8 statistics_counter_id;
- u8 max_sges_for_packet;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 drop_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
- u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
-#elif defined(__LITTLE_ENDIAN)
- u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
- u16 drop_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
-#endif
-};
-
-
-/*
- * MAC filtering configuration parameters per port in Tstorm
- */
-struct tstorm_eth_mac_filter_config {
- u32 ucast_drop_all;
- u32 ucast_accept_all;
- u32 mcast_drop_all;
- u32 mcast_accept_all;
- u32 bcast_drop_all;
- u32 bcast_accept_all;
- u32 strict_vlan;
- u32 vlan_filter[2];
- u32 reserved;
-};
-
-
-/*
- * Three RX producers for ETH
- */
-struct tstorm_eth_rx_producers {
-#if defined(__BIG_ENDIAN)
- u16 bd_prod;
- u16 cqe_prod;
-#elif defined(__LITTLE_ENDIAN)
- u16 cqe_prod;
- u16 bd_prod;
-#endif
-#if defined(__BIG_ENDIAN)
- u16 reserved;
- u16 sge_prod;
-#elif defined(__LITTLE_ENDIAN)
- u16 sge_prod;
- u16 reserved;
-#endif
-};
-
-
-/*
- * common flag to indicate existence of TPA.
- */
-struct tstorm_eth_tpa_exist {
-#if defined(__BIG_ENDIAN)
- u16 reserved1;
- u8 reserved0;
- u8 tpa_exist;
-#elif defined(__LITTLE_ENDIAN)
- u8 tpa_exist;
- u8 reserved0;
- u16 reserved1;
-#endif
- u32 reserved2;
-};
-
-
-/*
- * per-port SAFC demo variables
- */
-struct cmng_flags_per_port {
- u8 con_number[NUM_OF_PROTOCOLS];
-#if defined(__BIG_ENDIAN)
- u8 fairness_enable;
- u8 rate_shaping_enable;
- u8 cmng_protocol_enable;
- u8 cmng_vn_enable;
-#elif defined(__LITTLE_ENDIAN)
- u8 cmng_vn_enable;
- u8 cmng_protocol_enable;
- u8 rate_shaping_enable;
- u8 fairness_enable;
-#endif
-};
-
-
-/*
- * per-port rate shaping variables
- */
-struct rate_shaping_vars_per_port {
- u32 rs_periodic_timeout;
- u32 rs_threshold;
-};
-
-
-/*
- * per-port fairness variables
- */
-struct fairness_vars_per_port {
- u32 upper_bound;
- u32 fair_threshold;
- u32 fairness_timeout;
-};
-
-
-/*
- * per-port SAFC variables
- */
-struct safc_struct_per_port {
-#if defined(__BIG_ENDIAN)
- u16 __reserved0;
- u8 cur_cos_types;
- u8 safc_timeout_usec;
-#elif defined(__LITTLE_ENDIAN)
- u8 safc_timeout_usec;
- u8 cur_cos_types;
- u16 __reserved0;
-#endif
- u8 cos_to_protocol[MAX_COS_NUMBER];
-};
-
-
-/*
- * Per-port congestion management variables
- */
-struct cmng_struct_per_port {
- struct rate_shaping_vars_per_port rs_vars;
- struct fairness_vars_per_port fair_vars;
- struct safc_struct_per_port safc_vars;
- struct cmng_flags_per_port flags;
-};
-
-
-/*
- * Protocol-common statistics collected by the Xstorm (per client)
- */
-struct xstorm_per_client_stats {
- struct regpair total_sent_bytes;
- u32 total_sent_pkts;
- u32 unicast_pkts_sent;
- struct regpair unicast_bytes_sent;
- struct regpair multicast_bytes_sent;
- u32 multicast_pkts_sent;
- u32 broadcast_pkts_sent;
- struct regpair broadcast_bytes_sent;
- u16 stats_counter;
- u16 reserved0;
- u32 reserved1;
-};
-
-
-/*
- * Common statistics collected by the Xstorm (per port)
- */
-struct xstorm_common_stats {
- struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID];
-};
-
-
-/*
- * Protocol-common statistics collected by the Tstorm (per port)
- */
-struct tstorm_per_port_stats {
- u32 mac_filter_discard;
- u32 xxoverflow_discard;
- u32 brb_truncate_discard;
- u32 mac_discard;
-};
-
-
-/*
- * Protocol-common statistics collected by the Tstorm (per client)
- */
-struct tstorm_per_client_stats {
- struct regpair total_rcv_bytes;
- struct regpair rcv_unicast_bytes;
- struct regpair rcv_broadcast_bytes;
- struct regpair rcv_multicast_bytes;
- struct regpair rcv_error_bytes;
- u32 checksum_discard;
- u32 packets_too_big_discard;
- u32 total_rcv_pkts;
- u32 rcv_unicast_pkts;
- u32 rcv_broadcast_pkts;
- u32 rcv_multicast_pkts;
- u32 no_buff_discard;
- u32 ttl0_discard;
- u16 stats_counter;
- u16 reserved0;
- u32 reserved1;
-};
-
-/*
- * Protocol-common statistics collected by the Tstorm
- */
-struct tstorm_common_stats {
- struct tstorm_per_port_stats port_statistics;
- struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID];
-};
-
-/*
- * Eth statistics query structure for the eth_stats_query ramrod
- */
-struct eth_stats_query {
- struct xstorm_common_stats xstorm_common;
- struct tstorm_common_stats tstorm_common;
-};
-
-
-/*
- * per-vnic fairness variables
- */
-struct fairness_vars_per_vn {
- u32 protocol_credit_delta[NUM_OF_PROTOCOLS];
- u32 vn_credit_delta;
- u32 __reserved0;
-};
-
-
-/*
- * FW version stored in the Xstorm RAM
- */
-struct fw_version {
-#if defined(__BIG_ENDIAN)
- u16 patch;
- u8 primary;
- u8 client;
-#elif defined(__LITTLE_ENDIAN)
- u8 client;
- u8 primary;
- u16 patch;
-#endif
- u32 flags;
-#define FW_VERSION_OPTIMIZED (0x1<<0)
-#define FW_VERSION_OPTIMIZED_SHIFT 0
-#define FW_VERSION_BIG_ENDIEN (0x1<<1)
-#define FW_VERSION_BIG_ENDIEN_SHIFT 1
-#define FW_VERSION_CHIP_VERSION (0x3<<2)
-#define FW_VERSION_CHIP_VERSION_SHIFT 2
-#define __FW_VERSION_RESERVED (0xFFFFFFF<<4)
-#define __FW_VERSION_RESERVED_SHIFT 4
-};
-
-
-/*
- * FW version stored in first line of pram
- */
-struct pram_fw_version {
- u8 client;
- u8 primary;
- u16 patch;
- u8 flags;
-#define PRAM_FW_VERSION_OPTIMIZED (0x1<<0)
-#define PRAM_FW_VERSION_OPTIMIZED_SHIFT 0
-#define PRAM_FW_VERSION_STORM_ID (0x3<<1)
-#define PRAM_FW_VERSION_STORM_ID_SHIFT 1
-#define PRAM_FW_VERSION_BIG_ENDIEN (0x1<<3)
-#define PRAM_FW_VERSION_BIG_ENDIEN_SHIFT 3
-#define PRAM_FW_VERSION_CHIP_VERSION (0x3<<4)
-#define PRAM_FW_VERSION_CHIP_VERSION_SHIFT 4
-#define __PRAM_FW_VERSION_RESERVED0 (0x3<<6)
-#define __PRAM_FW_VERSION_RESERVED0_SHIFT 6
-};
-
-
-/*
- * a single rate shaping counter. can be used as protocol or vnic counter
- */
-struct rate_shaping_counter {
- u32 quota;
-#if defined(__BIG_ENDIAN)
- u16 __reserved0;
- u16 rate;
-#elif defined(__LITTLE_ENDIAN)
- u16 rate;
- u16 __reserved0;
-#endif
-};
-
-
-/*
- * per-vnic rate shaping variables
- */
-struct rate_shaping_vars_per_vn {
- struct rate_shaping_counter protocol_counters[NUM_OF_PROTOCOLS];
- struct rate_shaping_counter vn_counter;
-};
-
-
-/*
- * The send queue element
- */
-struct slow_path_element {
- struct spe_hdr hdr;
- u8 protocol_data[8];
-};
-
-
-/*
- * eth/toe flags that indicate if to query
- */
-struct stats_indication_flags {
- u32 collect_eth;
- u32 collect_toe;
-};
-
-
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
deleted file mode 100644
index 130927cfc75..00000000000
--- a/drivers/net/bnx2x_init.h
+++ /dev/null
@@ -1,811 +0,0 @@
-/* bnx2x_init.h: Broadcom Everest network driver.
- *
- * Copyright (c) 2007-2008 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * Maintained by: Eilon Greenstein <eilong@broadcom.com>
- * Written by: Eliezer Tamir
- */
-
-#ifndef BNX2X_INIT_H
-#define BNX2X_INIT_H
-
-#define COMMON 0x1
-#define PORT0 0x2
-#define PORT1 0x4
-
-#define INIT_EMULATION 0x1
-#define INIT_FPGA 0x2
-#define INIT_ASIC 0x4
-#define INIT_HARDWARE 0x7
-
-#define STORM_INTMEM_SIZE_E1 (0x5800 / 4)
-#define STORM_INTMEM_SIZE_E1H (0x10000 / 4)
-#define TSTORM_INTMEM_ADDR 0x1a0000
-#define CSTORM_INTMEM_ADDR 0x220000
-#define XSTORM_INTMEM_ADDR 0x2a0000
-#define USTORM_INTMEM_ADDR 0x320000
-
-
-/* Init operation types and structures */
-/* Common for both E1 and E1H */
-#define OP_RD 0x1 /* read single register */
-#define OP_WR 0x2 /* write single register */
-#define OP_IW 0x3 /* write single register using mailbox */
-#define OP_SW 0x4 /* copy a string to the device */
-#define OP_SI 0x5 /* copy a string using mailbox */
-#define OP_ZR 0x6 /* clear memory */
-#define OP_ZP 0x7 /* unzip then copy with DMAE */
-#define OP_WR_64 0x8 /* write 64 bit pattern */
-#define OP_WB 0x9 /* copy a string using DMAE */
-
-/* Operation specific for E1 */
-#define OP_RD_E1 0xa /* read single register */
-#define OP_WR_E1 0xb /* write single register */
-#define OP_IW_E1 0xc /* write single register using mailbox */
-#define OP_SW_E1 0xd /* copy a string to the device */
-#define OP_SI_E1 0xe /* copy a string using mailbox */
-#define OP_ZR_E1 0xf /* clear memory */
-#define OP_ZP_E1 0x10 /* unzip then copy with DMAE */
-#define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */
-#define OP_WB_E1 0x12 /* copy a string using DMAE */
-
-/* Operation specific for E1H */
-#define OP_RD_E1H 0x13 /* read single register */
-#define OP_WR_E1H 0x14 /* write single register */
-#define OP_IW_E1H 0x15 /* write single register using mailbox */
-#define OP_SW_E1H 0x16 /* copy a string to the device */
-#define OP_SI_E1H 0x17 /* copy a string using mailbox */
-#define OP_ZR_E1H 0x18 /* clear memory */
-#define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */
-#define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */
-#define OP_WB_E1H 0x1b /* copy a string using DMAE */
-
-/* FPGA and EMUL specific operations */
-#define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */
-#define OP_WR_EMUL 0x1d /* write single register on Emulation */
-#define OP_WR_FPGA 0x1e /* write single register on FPGA */
-#define OP_WR_ASIC 0x1f /* write single register on ASIC */
-
-
-struct raw_op {
- u32 op:8;
- u32 offset:24;
- u32 raw_data;
-};
-
-struct op_read {
- u32 op:8;
- u32 offset:24;
- u32 pad;
-};
-
-struct op_write {
- u32 op:8;
- u32 offset:24;
- u32 val;
-};
-
-struct op_string_write {
- u32 op:8;
- u32 offset:24;
-#ifdef __LITTLE_ENDIAN
- u16 data_off;
- u16 data_len;
-#else /* __BIG_ENDIAN */
- u16 data_len;
- u16 data_off;
-#endif
-};
-
-struct op_zero {
- u32 op:8;
- u32 offset:24;
- u32 len;
-};
-
-union init_op {
- struct op_read read;
- struct op_write write;
- struct op_string_write str_wr;
- struct op_zero zero;
- struct raw_op raw;
-};
-
-#include "bnx2x_init_values.h"
-
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
-
-static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- REG_WR(bp, addr + i*4, data[i]);
- if (!(i % 10000)) {
- touch_softlockup_watchdog();
- cpu_relax();
- }
- }
-}
-
-static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
- u16 len)
-{
- int i;
-
- for (i = 0; i < len; i++) {
- REG_WR_IND(bp, addr + i*4, data[i]);
- if (!(i % 10000)) {
- touch_softlockup_watchdog();
- cpu_relax();
- }
- }
-}
-
-static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
-{
-#ifdef USE_DMAE
- int offset = 0;
-
- if (bp->dmae_ready) {
- while (len > DMAE_LEN32_WR_MAX) {
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_WR_MAX);
- offset += DMAE_LEN32_WR_MAX * 4;
- len -= DMAE_LEN32_WR_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, len);
- } else
- bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
-#else
- bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
-#endif
-}
-
-static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
-{
- if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! addr 0x%x len 0x%x\n",
- addr, len*4);
- return;
- }
- memset(bp->gunzip_buf, fill, len * 4);
-
- bnx2x_write_big_buf(bp, addr, len);
-}
-
-static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len64)
-{
- u32 buf_len32 = FW_BUF_SIZE/4;
- u32 len = len64*2;
- u64 data64 = 0;
- int i;
-
- /* 64 bit value is in a blob: first low DWORD, then high DWORD */
- data64 = HILO_U64((*(data + 1)), (*data));
- len64 = min((u32)(FW_BUF_SIZE/8), len64);
- for (i = 0; i < len64; i++) {
- u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
-
- *pdata = data64;
- }
-
- for (i = 0; i < len; i += buf_len32) {
- u32 cur_len = min(buf_len32, len - i);
-
- bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
- }
-}
-
-/*********************************************************
- There are different blobs for each PRAM section.
- In addition, each blob write operation is divided into a few operations
- in order to decrease the amount of phys. contiguous buffer needed.
- Thus, when we select a blob the address may be with some offset
- from the beginning of PRAM section.
- The same holds for the INT_TABLE sections.
-**********************************************************/
-#define IF_IS_INT_TABLE_ADDR(base, addr) \
- if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
-
-#define IF_IS_PRAM_ADDR(base, addr) \
- if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
-
-static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1)
-{
- IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
- data = is_e1 ? tsem_int_table_data_e1 :
- tsem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
- data = is_e1 ? csem_int_table_data_e1 :
- csem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
- data = is_e1 ? usem_int_table_data_e1 :
- usem_int_table_data_e1h;
- else
- IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
- data = is_e1 ? xsem_int_table_data_e1 :
- xsem_int_table_data_e1h;
- else
- IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
- data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
- data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
- data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h;
- else
- IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
- data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h;
-
- return data;
-}
-
-static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
- u32 len, int gunzip, int is_e1, u32 blob_off)
-{
- int offset = 0;
-
- data = bnx2x_sel_blob(addr, data, is_e1) + blob_off;
-
- if (gunzip) {
- int rc;
-#ifdef __BIG_ENDIAN
- int i, size;
- u32 *temp;
-
- temp = kmalloc(len, GFP_KERNEL);
- size = (len / 4) + ((len % 4) ? 1 : 0);
- for (i = 0; i < size; i++)
- temp[i] = swab32(data[i]);
- data = temp;
-#endif
- rc = bnx2x_gunzip(bp, (u8 *)data, len);
- if (rc) {
- BNX2X_ERR("gunzip failed ! rc %d\n", rc);
- return;
- }
- len = bp->gunzip_outlen;
-#ifdef __BIG_ENDIAN
- kfree(temp);
- for (i = 0; i < len; i++)
- ((u32 *)bp->gunzip_buf)[i] =
- swab32(((u32 *)bp->gunzip_buf)[i]);
-#endif
- } else {
- if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! "
- "addr 0x%x len 0x%x\n", addr, len*4);
- return;
- }
- memcpy(bp->gunzip_buf, data, len * 4);
- }
-
- if (bp->dmae_ready) {
- while (len > DMAE_LEN32_WR_MAX) {
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, DMAE_LEN32_WR_MAX);
- offset += DMAE_LEN32_WR_MAX * 4;
- len -= DMAE_LEN32_WR_MAX;
- }
- bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
- addr + offset, len);
- } else
- bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
-}
-
-static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
-{
- int is_e1 = CHIP_IS_E1(bp);
- int is_e1h = CHIP_IS_E1H(bp);
- int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h);
- int hw_wr, i;
- union init_op *op;
- u32 op_type, addr, len;
- const u32 *data, *data_base;
-
- if (CHIP_REV_IS_FPGA(bp))
- hw_wr = OP_WR_FPGA;
- else if (CHIP_REV_IS_EMUL(bp))
- hw_wr = OP_WR_EMUL;
- else
- hw_wr = OP_WR_ASIC;
-
- if (is_e1)
- data_base = init_data_e1;
- else /* CHIP_IS_E1H(bp) */
- data_base = init_data_e1h;
-
- for (i = op_start; i < op_end; i++) {
-
- op = (union init_op *)&(init_ops[i]);
-
- op_type = op->str_wr.op;
- addr = op->str_wr.offset;
- len = op->str_wr.data_len;
- data = data_base + op->str_wr.data_off;
-
- /* careful! it must be in order */
- if (unlikely(op_type > OP_WB)) {
-
- /* If E1 only */
- if (op_type <= OP_WB_E1) {
- if (is_e1)
- op_type -= (OP_RD_E1 - OP_RD);
-
- /* If E1H only */
- } else if (op_type <= OP_WB_E1H) {
- if (is_e1h)
- op_type -= (OP_RD_E1H - OP_RD);
- }
-
- /* HW/EMUL specific */
- if (op_type == hw_wr)
- op_type = OP_WR;
-
- /* EMUL on E1H is special */
- if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h)
- op_type = OP_WR;
- }
-
- switch (op_type) {
- case OP_RD:
- REG_RD(bp, addr);
- break;
- case OP_WR:
- REG_WR(bp, addr, op->write.val);
- break;
- case OP_SW:
- bnx2x_init_str_wr(bp, addr, data, len);
- break;
- case OP_WB:
- bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0);
- break;
- case OP_SI:
- bnx2x_init_ind_wr(bp, addr, data, len);
- break;
- case OP_ZR:
- bnx2x_init_fill(bp, addr, 0, op->zero.len);
- break;
- case OP_ZP:
- bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1,
- op->str_wr.data_off);
- break;
- case OP_WR_64:
- bnx2x_init_wr_64(bp, addr, data, len);
- break;
- default:
- /* happens whenever an op is of a diff HW */
-#if 0
- DP(NETIF_MSG_HW, "skipping init operation "
- "index %d[%d:%d]: type %d addr 0x%x "
- "len %d(0x%x)\n",
- i, op_start, op_end, op_type, addr, len, len);
-#endif
- break;
- }
- }
-}
-
-
-/****************************************************************************
-* PXP
-****************************************************************************/
-/*
- * This code configures the PCI read/write arbiter
- * which implements a weighted round robin
- * between the virtual queues in the chip.
- *
- * The values were derived for each PCI max payload and max request size.
- * since max payload and max request size are only known at run time,
- * this is done as a separate init stage.
- */
-
-#define NUM_WR_Q 13
-#define NUM_RD_Q 29
-#define MAX_RD_ORD 3
-#define MAX_WR_ORD 2
-
-/* configuration for one arbiter queue */
-struct arb_line {
- int l;
- int add;
- int ubound;
-};
-
-/* derived configuration for each read queue for each max request size */
-static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
- {{4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4} },
- {{4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {16 , 3 , 11}, {16 , 3 , 11} },
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81}, {64 , 64 , 120} }
-};
-
-/* derived configuration for each write queue for each max request size */
-static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
- {{4 , 6 , 3}, {4 , 6 , 3}, {4 , 6 , 3} },
- {{4 , 2 , 3}, {4 , 2 , 3}, {4 , 2 , 3} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 9 , 6}, {16 , 9 , 11}, {32 , 9 , 21} },
- {{8 , 47 , 19}, {16 , 47 , 19}, {32 , 47 , 21} },
- {{8 , 9 , 6}, {16 , 9 , 11}, {16 , 9 , 11} },
- {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} }
-};
-
-/* register addresses for read queues */
-static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
- {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
- PXP2_REG_RQ_BW_RD_UBOUND0},
- {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
- PXP2_REG_PSWRQ_BW_UB1},
- {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
- PXP2_REG_PSWRQ_BW_UB2},
- {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
- PXP2_REG_PSWRQ_BW_UB3},
- {PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
- PXP2_REG_RQ_BW_RD_UBOUND4},
- {PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
- PXP2_REG_RQ_BW_RD_UBOUND5},
- {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
- PXP2_REG_PSWRQ_BW_UB6},
- {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
- PXP2_REG_PSWRQ_BW_UB7},
- {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
- PXP2_REG_PSWRQ_BW_UB8},
- {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
- PXP2_REG_PSWRQ_BW_UB9},
- {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
- PXP2_REG_PSWRQ_BW_UB10},
- {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
- PXP2_REG_PSWRQ_BW_UB11},
- {PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
- PXP2_REG_RQ_BW_RD_UBOUND12},
- {PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
- PXP2_REG_RQ_BW_RD_UBOUND13},
- {PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
- PXP2_REG_RQ_BW_RD_UBOUND14},
- {PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
- PXP2_REG_RQ_BW_RD_UBOUND15},
- {PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
- PXP2_REG_RQ_BW_RD_UBOUND16},
- {PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
- PXP2_REG_RQ_BW_RD_UBOUND17},
- {PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
- PXP2_REG_RQ_BW_RD_UBOUND18},
- {PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
- PXP2_REG_RQ_BW_RD_UBOUND19},
- {PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
- PXP2_REG_RQ_BW_RD_UBOUND20},
- {PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
- PXP2_REG_RQ_BW_RD_UBOUND22},
- {PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
- PXP2_REG_RQ_BW_RD_UBOUND23},
- {PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
- PXP2_REG_RQ_BW_RD_UBOUND24},
- {PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
- PXP2_REG_RQ_BW_RD_UBOUND25},
- {PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
- PXP2_REG_RQ_BW_RD_UBOUND26},
- {PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
- PXP2_REG_RQ_BW_RD_UBOUND27},
- {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
- PXP2_REG_PSWRQ_BW_UB28}
-};
-
-/* register addresses for write queues */
-static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
- {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
- PXP2_REG_PSWRQ_BW_UB1},
- {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
- PXP2_REG_PSWRQ_BW_UB2},
- {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
- PXP2_REG_PSWRQ_BW_UB3},
- {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
- PXP2_REG_PSWRQ_BW_UB6},
- {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
- PXP2_REG_PSWRQ_BW_UB7},
- {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
- PXP2_REG_PSWRQ_BW_UB8},
- {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
- PXP2_REG_PSWRQ_BW_UB9},
- {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
- PXP2_REG_PSWRQ_BW_UB10},
- {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
- PXP2_REG_PSWRQ_BW_UB11},
- {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
- PXP2_REG_PSWRQ_BW_UB28},
- {PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
- PXP2_REG_RQ_BW_WR_UBOUND29},
- {PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
- PXP2_REG_RQ_BW_WR_UBOUND30}
-};
-
-static void bnx2x_init_pxp(struct bnx2x *bp)
-{
- int r_order, w_order;
- u32 val, i;
-
- pci_read_config_word(bp->pdev,
- bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val);
- DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val);
- w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
- r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12);
-
- if (r_order > MAX_RD_ORD) {
- DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
- r_order, MAX_RD_ORD);
- r_order = MAX_RD_ORD;
- }
- if (w_order > MAX_WR_ORD) {
- DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
- w_order, MAX_WR_ORD);
- w_order = MAX_WR_ORD;
- }
- if (CHIP_REV_IS_FPGA(bp)) {
- DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
- w_order = 0;
- }
- DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
-
- for (i = 0; i < NUM_RD_Q-1; i++) {
- REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
- REG_WR(bp, read_arb_addr[i].add,
- read_arb_data[i][r_order].add);
- REG_WR(bp, read_arb_addr[i].ubound,
- read_arb_data[i][r_order].ubound);
- }
-
- for (i = 0; i < NUM_WR_Q-1; i++) {
- if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
- (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
-
- REG_WR(bp, write_arb_addr[i].l,
- write_arb_data[i][w_order].l);
-
- REG_WR(bp, write_arb_addr[i].add,
- write_arb_data[i][w_order].add);
-
- REG_WR(bp, write_arb_addr[i].ubound,
- write_arb_data[i][w_order].ubound);
- } else {
-
- val = REG_RD(bp, write_arb_addr[i].l);
- REG_WR(bp, write_arb_addr[i].l,
- val | (write_arb_data[i][w_order].l << 10));
-
- val = REG_RD(bp, write_arb_addr[i].add);
- REG_WR(bp, write_arb_addr[i].add,
- val | (write_arb_data[i][w_order].add << 10));
-
- val = REG_RD(bp, write_arb_addr[i].ubound);
- REG_WR(bp, write_arb_addr[i].ubound,
- val | (write_arb_data[i][w_order].ubound << 7));
- }
- }
-
- val = write_arb_data[NUM_WR_Q-1][w_order].add;
- val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
- val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
- REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
-
- val = read_arb_data[NUM_RD_Q-1][r_order].add;
- val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
- val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
- REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
-
- REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
- REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
- REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
-
- if (r_order == MAX_RD_ORD)
- REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
-
- REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
-
- if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, PXP2_REG_WR_HC_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_USDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_CSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_TSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_XSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_QM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_TM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_SRC_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_DBG_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
- REG_WR(bp, PXP2_REG_WR_CDU_MPS, w_order+1);
- }
-}
-
-
-/****************************************************************************
-* CDU
-****************************************************************************/
-
-#define CDU_REGION_NUMBER_XCM_AG 2
-#define CDU_REGION_NUMBER_UCM_AG 4
-
-/**
- * String-to-compress [31:8] = CID (all 24 bits)
- * String-to-compress [7:4] = Region
- * String-to-compress [3:0] = Type
- */
-#define CDU_VALID_DATA(_cid, _region, _type) \
- (((_cid) << 8) | (((_region) & 0xf) << 4) | (((_type) & 0xf)))
-#define CDU_CRC8(_cid, _region, _type) \
- calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff)
-#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type) \
- (0x80 | (CDU_CRC8(_cid, _region, _type) & 0x7f))
-#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type) \
- (0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
-#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
-
-/*****************************************************************************
- * Description:
- * Calculates crc 8 on a word value: polynomial 0-1-2-8
- * Code was translated from Verilog.
- ****************************************************************************/
-static u8 calc_crc8(u32 data, u8 crc)
-{
- u8 D[32];
- u8 NewCRC[8];
- u8 C[8];
- u8 crc_res;
- u8 i;
-
- /* split the data into 31 bits */
- for (i = 0; i < 32; i++) {
- D[i] = data & 1;
- data = data >> 1;
- }
-
- /* split the crc into 8 bits */
- for (i = 0; i < 8; i++) {
- C[i] = crc & 1;
- crc = crc >> 1;
- }
-
- NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
- D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
- C[6] ^ C[7];
- NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
- D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
- D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
- NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
- D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
- C[0] ^ C[1] ^ C[4] ^ C[5];
- NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
- D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
- C[1] ^ C[2] ^ C[5] ^ C[6];
- NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
- D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
- C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
- NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
- D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
- C[3] ^ C[4] ^ C[7];
- NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
- D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
- C[5];
- NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
- D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
- C[6];
-
- crc_res = 0;
- for (i = 0; i < 8; i++)
- crc_res |= (NewCRC[i] << i);
-
- return crc_res;
-}
-
-/* registers addresses are not in order
- so these arrays help simplify the code */
-static const int cm_start[E1H_FUNC_MAX][9] = {
- {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START,
- XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START,
- XSEM_FUNC0_START},
- {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START,
- XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START,
- XSEM_FUNC1_START},
- {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START,
- XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START,
- XSEM_FUNC2_START},
- {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START,
- XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START,
- XSEM_FUNC3_START},
- {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START,
- XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START,
- XSEM_FUNC4_START},
- {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START,
- XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START,
- XSEM_FUNC5_START},
- {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START,
- XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START,
- XSEM_FUNC6_START},
- {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START,
- XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START,
- XSEM_FUNC7_START}
-};
-
-static const int cm_end[E1H_FUNC_MAX][9] = {
- {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END,
- XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END,
- XSEM_FUNC0_END},
- {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END,
- XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END,
- XSEM_FUNC1_END},
- {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END,
- XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END,
- XSEM_FUNC2_END},
- {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END,
- XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END,
- XSEM_FUNC3_END},
- {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END,
- XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END,
- XSEM_FUNC4_END},
- {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END,
- XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END,
- XSEM_FUNC5_END},
- {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END,
- XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END,
- XSEM_FUNC6_END},
- {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END,
- XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END,
- XSEM_FUNC7_END},
-};
-
-static const int hc_limits[E1H_FUNC_MAX][2] = {
- {HC_FUNC0_START, HC_FUNC0_END},
- {HC_FUNC1_START, HC_FUNC1_END},
- {HC_FUNC2_START, HC_FUNC2_END},
- {HC_FUNC3_START, HC_FUNC3_END},
- {HC_FUNC4_START, HC_FUNC4_END},
- {HC_FUNC5_START, HC_FUNC5_END},
- {HC_FUNC6_START, HC_FUNC6_END},
- {HC_FUNC7_START, HC_FUNC7_END}
-};
-
-#endif /* BNX2X_INIT_H */
-
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
deleted file mode 100644
index 9755bf6b08d..00000000000
--- a/drivers/net/bnx2x_init_values.h
+++ /dev/null
@@ -1,14723 +0,0 @@
-#ifndef __BNX2X_INIT_VALUES_H__
-#define __BNX2X_INIT_VALUES_H__
-
-/* This array contains the list of operations needed to initialize the chip.
- *
- * For each block in the chip there are three init stages:
- * common - HW used by both ports,
- * port1 and port2 - initialization for a specific Ethernet port.
- * When a port is opened or closed, the management CPU tells the driver
- * whether to init/disable common HW in addition to the port HW.
- * This way the first port going up will first initializes the common HW,
- * and the last port going down also resets the common HW
- *
- * For each init stage/block there is a list of actions needed in a format:
- * {operation, register, data}
- * where:
- * OP_WR - write a value to the chip.
- * OP_RD - read a register (usually a clear on read register).
- * OP_SW - string write, write a section of consecutive addresses to the chip.
- * OP_SI - copy a string using indirect writes.
- * OP_ZR - clear a range of memory.
- * OP_ZP - unzip and copy using DMAE.
- * OP_WB - string copy using DMAE.
- *
- * The #defines mark the stages.
- *
- */
-
-static const struct raw_op init_ops[] = {
-#define PRS_COMMON_START 0
- {OP_WR, PRS_REG_INC_VALUE, 0xf},
- {OP_WR, PRS_REG_EVENT_ID_1, 0x45},
- {OP_WR, PRS_REG_EVENT_ID_2, 0x84},
- {OP_WR, PRS_REG_EVENT_ID_3, 0x6},
- {OP_WR, PRS_REG_NO_MATCH_EVENT_ID, 0x4},
- {OP_WR, PRS_REG_CM_HDR_TYPE_0, 0x0},
- {OP_WR, PRS_REG_CM_HDR_TYPE_1, 0x12170000},
- {OP_WR, PRS_REG_CM_HDR_TYPE_2, 0x22170000},
- {OP_WR, PRS_REG_CM_HDR_TYPE_3, 0x32170000},
- {OP_ZR, PRS_REG_CM_HDR_TYPE_4, 0x5},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_1, 0x12150000},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_2, 0x22150000},
- {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_3, 0x32150000},
- {OP_ZR, PRS_REG_CM_HDR_LOOPBACK_TYPE_4, 0x4},
- {OP_WR, PRS_REG_CM_NO_MATCH_HDR, 0x2100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0, 0x100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000},
- {OP_ZR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000},
- {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000},
- {OP_ZR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
- {OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0},
- {OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0},
- {OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0},
- {OP_RD, PRS_REG_NUM_OF_DEAD_CYCLES, 0x0},
- {OP_WR_E1H, PRS_REG_FCOE_TYPE, 0x8906},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_0, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_1, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_2, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_3, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_4, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_5, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_6, 0xff},
- {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_7, 0xff},
- {OP_WR, PRS_REG_PURE_REGIONS, 0x3e},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_0, 0x0},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f},
-#define PRS_COMMON_END 47
-#define SRCH_COMMON_START 47
- {OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
-#define SRCH_COMMON_END 48
-#define TSDM_COMMON_START 48
- {OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
- {OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211},
- {OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
- {OP_WR_E1H, TSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
- {OP_WR_E1, TSDM_REG_Q_COUNTER_START_ADDR, 0x404},
- {OP_WR_E1H, TSDM_REG_Q_COUNTER_START_ADDR, 0x204},
- {OP_WR_E1, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419},
- {OP_WR_E1H, TSDM_REG_PCK_END_MSG_START_ADDR, 0x219},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_ZR, TSDM_REG_AGG_INT_EVENT_0, 0x2},
- {OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
- {OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, TSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, TSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, TSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, TSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa},
-#define TSDM_COMMON_END 86
-#define TCM_COMMON_START 86
- {OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20},
- {OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020},
- {OP_WR, TCM_REG_TQM_TCM_HDR_S, 0x2150020},
- {OP_WR, TCM_REG_TM_TCM_HDR, 0x30},
- {OP_WR, TCM_REG_ERR_TCM_HDR, 0x8100000},
- {OP_WR, TCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, TCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, TCM_REG_PRS_WEIGHT, 0x4},
- {OP_WR, TCM_REG_PBF_WEIGHT, 0x5},
- {OP_WR, TCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, TCM_REG_TSDM_WEIGHT, 0x4},
- {OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1},
- {OP_WR, TCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, TCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, TCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, TCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, TCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, TCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, TCM_REG_TQM_INIT_CRD, 0x20},
- {OP_WR, TCM_REG_XX_INIT_CRD, 0x13},
- {OP_WR, TCM_REG_XX_MSG_NUM, 0x20},
- {OP_ZR, TCM_REG_XX_TABLE, 0xa},
- {OP_SW, TCM_REG_XX_DESCR_TABLE, 0x200000},
- {OP_WR, TCM_REG_N_SM_CTX_LD_0, 0x7},
- {OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8},
- {OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR, TCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
- {OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd},
- {OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d},
- {OP_WR_E1, TCM_REG_PHYS_QNUM1_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM1_1, 0x27},
- {OP_WR_E1, TCM_REG_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1, TCM_REG_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1, TCM_REG_PHYS_QNUM3_1, 0x27},
- {OP_WR, TCM_REG_TCM_STORM0_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_STORM1_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_TQM_IFEN, 0x1},
- {OP_WR, TCM_REG_STORM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_TQM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_TSDM_IFEN, 0x1},
- {OP_WR, TCM_REG_TM_TCM_IFEN, 0x1},
- {OP_WR, TCM_REG_PRS_IFEN, 0x1},
- {OP_WR, TCM_REG_PBF_IFEN, 0x1},
- {OP_WR, TCM_REG_USEM_IFEN, 0x1},
- {OP_WR, TCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1},
-#define TCM_COMMON_END 141
-#define TCM_FUNC0_START 141
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7},
-#define TCM_FUNC0_END 145
-#define TCM_FUNC1_START 145
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27},
-#define TCM_FUNC1_END 149
-#define TCM_FUNC2_START 149
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17},
-#define TCM_FUNC2_END 153
-#define TCM_FUNC3_START 153
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37},
-#define TCM_FUNC3_END 157
-#define TCM_FUNC4_START 157
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47},
-#define TCM_FUNC4_END 161
-#define TCM_FUNC5_START 161
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67},
-#define TCM_FUNC5_END 165
-#define TCM_FUNC6_START 165
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57},
-#define TCM_FUNC6_END 169
-#define TCM_FUNC7_START 169
- {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77},
- {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77},
-#define TCM_FUNC7_END 173
-#define BRB1_COMMON_START 173
- {OP_SW, BRB1_REG_LL_RAM, 0x2000020},
- {OP_WR, BRB1_REG_SOFT_RESET, 0x1},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0},
- {OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220},
- {OP_WR, BRB1_REG_SOFT_RESET, 0x0},
-#define BRB1_COMMON_END 178
-#define BRB1_PORT0_START 178
- {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8},
- {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
-#define BRB1_PORT0_END 182
-#define BRB1_PORT1_START 182
- {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8},
- {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114},
- {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
- {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
-#define BRB1_PORT1_END 186
-#define TSEM_COMMON_START 186
- {OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, TSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, TSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, TSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, TSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, TSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, TSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, TSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, TSEM_REG_TS_0_AS, 0x0},
- {OP_WR, TSEM_REG_TS_1_AS, 0x1},
- {OP_WR, TSEM_REG_TS_2_AS, 0x4},
- {OP_WR, TSEM_REG_TS_3_AS, 0x0},
- {OP_WR, TSEM_REG_TS_4_AS, 0x1},
- {OP_WR, TSEM_REG_TS_5_AS, 0x3},
- {OP_WR, TSEM_REG_TS_6_AS, 0x0},
- {OP_WR, TSEM_REG_TS_7_AS, 0x1},
- {OP_WR, TSEM_REG_TS_8_AS, 0x4},
- {OP_WR, TSEM_REG_TS_9_AS, 0x0},
- {OP_WR, TSEM_REG_TS_10_AS, 0x1},
- {OP_WR, TSEM_REG_TS_11_AS, 0x3},
- {OP_WR, TSEM_REG_TS_12_AS, 0x0},
- {OP_WR, TSEM_REG_TS_13_AS, 0x1},
- {OP_WR, TSEM_REG_TS_14_AS, 0x4},
- {OP_WR, TSEM_REG_TS_15_AS, 0x0},
- {OP_WR, TSEM_REG_TS_16_AS, 0x4},
- {OP_WR, TSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, TSEM_REG_TS_18_AS, 0x2},
- {OP_WR, TSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, TSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, TSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, TSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, TSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, TSEM_REG_THREADS_LIST, 0xff},
- {OP_ZR, TSEM_REG_PASSIVE_BUFFER, 0x400},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18000, 0x34},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18040, 0x18},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x18080, 0xc},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR_ASIC, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, TSEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, TSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2000, 0xb2},
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x23c8, 0xc1},
- {OP_WR_EMUL_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x23c8 + 0x304, 0x10223},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1000, 0x2b3},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x1000 + 0xacc, 0x10223},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3b28, 0x6},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4},
- {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x940000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
- {OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM, 0x30b10000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33c50c2d},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xbc6191f},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
- {OP_WR_64_E1, TSEM_REG_PRAM + 0x117f0, 0x5d020232},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x6140, 0x200224},
- {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x960000},
- {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x360, 0x140244},
- {OP_ZP_E1H, TSEM_REG_PRAM, 0x30cc0000},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x33df0c33},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0xdce192b},
- {OP_WR_64_E1H, TSEM_REG_PRAM + 0x11c70, 0x5c720246},
-#define TSEM_COMMON_END 276
-#define TSEM_PORT0_START 276
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0xfc},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28},
- {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0xfa},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0xbe},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20234},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
-#define TSEM_PORT0_END 294
-#define TSEM_PORT1_START 294
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x43f0, 0xfc},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28},
- {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3738, 0xfa},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xcb8, 0xbe},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20236},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
-#define TSEM_PORT1_END 312
-#define TSEM_FUNC0_START 312
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
-#define TSEM_FUNC0_END 318
-#define TSEM_FUNC1_START 318
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-#define TSEM_FUNC1_END 324
-#define TSEM_FUNC2_START 324
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20248},
-#define TSEM_FUNC2_END 330
-#define TSEM_FUNC3_START 330
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2024a},
-#define TSEM_FUNC3_END 336
-#define TSEM_FUNC4_START 336
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x2024c},
-#define TSEM_FUNC4_END 342
-#define TSEM_FUNC5_START 342
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2024e},
-#define TSEM_FUNC5_END 348
-#define TSEM_FUNC6_START 348
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20250},
-#define TSEM_FUNC6_END 354
-#define TSEM_FUNC7_START 354
- {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0xe},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x20252},
-#define TSEM_FUNC7_END 360
-#define MISC_COMMON_START 360
- {OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_3, 0x9c0424},
- {OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0},
- {OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209},
- {OP_WR_E1, MISC_REG_SPIO, 0xff000000},
-#define MISC_COMMON_END 367
-#define MISC_FUNC0_START 367
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC0_END 368
-#define MISC_FUNC1_START 368
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC1_END 369
-#define MISC_FUNC2_START 369
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC2_END 370
-#define MISC_FUNC3_START 370
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC3_END 371
-#define MISC_FUNC4_START 371
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC4_END 372
-#define MISC_FUNC5_START 372
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC5_END 373
-#define MISC_FUNC6_START 373
- {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC6_END 374
-#define MISC_FUNC7_START 374
- {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC7_END 375
-#define NIG_COMMON_START 375
- {OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1},
- {OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1},
- {OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1},
-#define NIG_COMMON_END 380
-#define NIG_PORT0_START 380
- {OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28},
- {OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0},
- {OP_WR, NIG_REG_LLH0_XCM_MASK, 0x4},
- {OP_WR, NIG_REG_LLH0_BRB1_NOT_MCP, 0x1},
- {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT0, 0x0},
- {OP_WR_E1H, NIG_REG_LLH0_CLS_TYPE, 0x1},
- {OP_WR, NIG_REG_LLH0_XCM_INIT_CREDIT, 0x30},
- {OP_WR, NIG_REG_BRB0_PAUSE_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB0_OUT_EN, 0x1},
- {OP_WR, NIG_REG_XCM0_OUT_EN, 0x1},
-#define NIG_PORT0_END 392
-#define NIG_PORT1_START 392
- {OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
- {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28},
- {OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0},
- {OP_WR, NIG_REG_LLH1_XCM_MASK, 0x4},
- {OP_WR, NIG_REG_LLH1_BRB1_NOT_MCP, 0x1},
- {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT1, 0x0},
- {OP_WR_E1H, NIG_REG_LLH1_CLS_TYPE, 0x1},
- {OP_WR, NIG_REG_LLH1_XCM_INIT_CREDIT, 0x30},
- {OP_WR, NIG_REG_BRB1_PAUSE_IN_EN, 0x1},
- {OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1},
- {OP_WR, NIG_REG_BRB1_OUT_EN, 0x1},
- {OP_WR, NIG_REG_XCM1_OUT_EN, 0x1},
-#define NIG_PORT1_END 404
-#define UPB_COMMON_START 404
- {OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END 405
-#define CSDM_COMMON_START 405
- {OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211},
- {OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR_E1H, CSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
- {OP_WR_E1, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
- {OP_WR_E1H, CSDM_REG_Q_COUNTER_START_ADDR, 0x204},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, CSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_0, 0xc6},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_1, 0x0},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, CSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR, CSDM_REG_AGG_INT_EVENT_4, 0x1c},
- {OP_WR, CSDM_REG_AGG_INT_T_0, 0x1},
- {OP_ZR, CSDM_REG_AGG_INT_T_1, 0x5f},
- {OP_WR, CSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, CSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, CSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, CSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, CSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, CSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa},
-#define CSDM_COMMON_END 444
-#define USDM_COMMON_START 444
- {OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
- {OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411},
- {OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
- {OP_WR_E1H, USDM_REG_CMP_COUNTER_START_ADDR, 0x400},
- {OP_WR_E1, USDM_REG_Q_COUNTER_START_ADDR, 0xa04},
- {OP_WR_E1H, USDM_REG_Q_COUNTER_START_ADDR, 0x404},
- {OP_WR_E1, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21},
- {OP_WR_E1H, USDM_REG_PCK_END_MSG_START_ADDR, 0x421},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, USDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, USDM_REG_AGG_INT_EVENT_0, 0x46},
- {OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5},
- {OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR, USDM_REG_AGG_INT_EVENT_4, 0x5c},
- {OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
- {OP_ZR, USDM_REG_AGG_INT_MODE_1, 0x1f},
- {OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, USDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, USDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, USDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q2_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, USDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, USDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, USDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa},
-#define USDM_COMMON_END 486
-#define CCM_COMMON_START 486
- {OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020},
- {OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020},
- {OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000},
- {OP_WR, CCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, CCM_REG_TSEM_WEIGHT, 0x0},
- {OP_WR, CCM_REG_XSEM_WEIGHT, 0x4},
- {OP_WR, CCM_REG_USEM_WEIGHT, 0x4},
- {OP_ZR, CCM_REG_PBF_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1},
- {OP_WR, CCM_REG_CNT_AUX1_Q, 0x2},
- {OP_WR, CCM_REG_CNT_AUX2_Q, 0x2},
- {OP_WR, CCM_REG_INV_DONE_Q, 0x1},
- {OP_WR, CCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, CCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, CCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, CCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, CCM_REG_CQM_INIT_CRD, 0x20},
- {OP_WR, CCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, CCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, CCM_REG_XX_INIT_CRD, 0x3},
- {OP_WR, CCM_REG_XX_MSG_NUM, 0x18},
- {OP_ZR, CCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240238},
- {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x240254},
- {OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1},
- {OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2},
- {OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8},
- {OP_WR, CCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR, CCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR, CCM_REG_CCM_REG0_SZ, 0x4},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
- {OP_WR_E1, CCM_REG_PHYS_QNUM1_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM1_1, 0x2c},
- {OP_WR_E1, CCM_REG_PHYS_QNUM2_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM2_1, 0x2c},
- {OP_WR_E1, CCM_REG_PHYS_QNUM3_0, 0xc},
- {OP_WR_E1, CCM_REG_PHYS_QNUM3_1, 0x2c},
- {OP_WR, CCM_REG_CCM_STORM0_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_STORM1_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_CQM_IFEN, 0x1},
- {OP_WR, CCM_REG_STORM_CCM_IFEN, 0x1},
- {OP_WR, CCM_REG_CQM_CCM_IFEN, 0x1},
- {OP_WR, CCM_REG_CSDM_IFEN, 0x1},
- {OP_WR, CCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, CCM_REG_XSEM_IFEN, 0x1},
- {OP_WR, CCM_REG_USEM_IFEN, 0x1},
- {OP_WR, CCM_REG_PBF_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1},
-#define CCM_COMMON_END 547
-#define CCM_FUNC0_START 547
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7},
-#define CCM_FUNC0_END 554
-#define CCM_FUNC1_START 554
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27},
-#define CCM_FUNC1_END 561
-#define CCM_FUNC2_START 561
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x17},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17},
-#define CCM_FUNC2_END 568
-#define CCM_FUNC3_START 568
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x37},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37},
-#define CCM_FUNC3_END 575
-#define CCM_FUNC4_START 575
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x47},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47},
-#define CCM_FUNC4_END 582
-#define CCM_FUNC5_START 582
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x67},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67},
-#define CCM_FUNC5_END 589
-#define CCM_FUNC6_START 589
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x57},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57},
-#define CCM_FUNC6_END 596
-#define CCM_FUNC7_START 596
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77},
- {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x77},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b},
- {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77},
-#define CCM_FUNC7_END 603
-#define UCM_COMMON_START 603
- {OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020},
- {OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020},
- {OP_WR, UCM_REG_TM_UCM_HDR, 0x30},
- {OP_WR, UCM_REG_ERR_UCM_HDR, 0x8100000},
- {OP_WR, UCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, UCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, UCM_REG_TSEM_WEIGHT, 0x3},
- {OP_WR, UCM_REG_CSEM_WEIGHT, 0x0},
- {OP_WR, UCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x6},
- {OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1},
- {OP_WR, UCM_REG_INV_CFLG_Q, 0x1},
- {OP_WR, UCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, UCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, UCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, UCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, UCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, UCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, UCM_REG_TM_INIT_CRD, 0x4},
- {OP_WR, UCM_REG_UQM_INIT_CRD, 0x20},
- {OP_WR, UCM_REG_XX_INIT_CRD, 0xe},
- {OP_WR, UCM_REG_XX_MSG_NUM, 0x1b},
- {OP_ZR, UCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b025c},
- {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b0278},
- {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10},
- {OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf},
- {OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10},
- {OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xd},
- {OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
- {OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf},
- {OP_WR_E1, UCM_REG_PHYS_QNUM0_1, 0x2f},
- {OP_WR_E1, UCM_REG_PHYS_QNUM1_0, 0xe},
- {OP_WR_E1, UCM_REG_PHYS_QNUM1_1, 0x2e},
- {OP_WR, UCM_REG_UCM_STORM0_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_STORM1_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_UQM_IFEN, 0x1},
- {OP_WR, UCM_REG_STORM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_UQM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_USDM_IFEN, 0x1},
- {OP_WR, UCM_REG_TM_UCM_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_TM_IFEN, 0x1},
- {OP_WR, UCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_XSEM_IFEN, 0x1},
- {OP_WR, UCM_REG_DORQ_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1},
-#define UCM_COMMON_END 659
-#define UCM_FUNC0_START 659
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC0_END 663
-#define UCM_FUNC1_START 663
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC1_END 667
-#define UCM_FUNC2_START 667
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC2_END 671
-#define UCM_FUNC3_START 671
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC3_END 675
-#define UCM_FUNC4_START 675
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC4_END 679
-#define UCM_FUNC5_START 679
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC5_END 683
-#define UCM_FUNC6_START 683
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC6_END 687
-#define UCM_FUNC7_START 687
- {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
- {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC7_END 691
-#define USEM_COMMON_START 691
- {OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, USEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, USEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, USEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, USEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, USEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, USEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, USEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, USEM_REG_TS_0_AS, 0x0},
- {OP_WR, USEM_REG_TS_1_AS, 0x1},
- {OP_WR, USEM_REG_TS_2_AS, 0x4},
- {OP_WR, USEM_REG_TS_3_AS, 0x0},
- {OP_WR, USEM_REG_TS_4_AS, 0x1},
- {OP_WR, USEM_REG_TS_5_AS, 0x3},
- {OP_WR, USEM_REG_TS_6_AS, 0x0},
- {OP_WR, USEM_REG_TS_7_AS, 0x1},
- {OP_WR, USEM_REG_TS_8_AS, 0x4},
- {OP_WR, USEM_REG_TS_9_AS, 0x0},
- {OP_WR, USEM_REG_TS_10_AS, 0x1},
- {OP_WR, USEM_REG_TS_11_AS, 0x3},
- {OP_WR, USEM_REG_TS_12_AS, 0x0},
- {OP_WR, USEM_REG_TS_13_AS, 0x1},
- {OP_WR, USEM_REG_TS_14_AS, 0x4},
- {OP_WR, USEM_REG_TS_15_AS, 0x0},
- {OP_WR, USEM_REG_TS_16_AS, 0x4},
- {OP_WR, USEM_REG_TS_17_AS, 0x3},
- {OP_ZR, USEM_REG_TS_18_AS, 0x2},
- {OP_WR, USEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, USEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, USEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, USEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, USEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, USEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, USEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18000, 0x1a},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18040, 0x4e},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x18080, 0x10},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x180c0, 0x20},
- {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
- {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0x102},
- {OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57e8, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8020, 0xc8},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d0, 0x5},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x2},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d0 + 0x14, 0x10277},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3760, 0x4},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1e20, 0x42},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3738, 0x9},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3738 + 0x24, 0x10293},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x20278},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x42},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x2027a},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x20294},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x20296},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x20298},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x10027c},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x10029a},
- {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x10028c},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002aa},
- {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc20000},
- {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xc40000},
- {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x13029c},
- {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x368, 0x1302ba},
- {OP_ZP_E1, USEM_REG_PRAM, 0x311c0000},
- {OP_ZP_E1H, USEM_REG_PRAM, 0x31070000},
- {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x33450c47},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x330e0c42},
- {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x38561919},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x389b1906},
- {OP_WR_64_E1, USEM_REG_PRAM + 0x17fe0, 0x5004029e},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x132272d},
- {OP_WR_64_E1H, USEM_REG_PRAM + 0x18250, 0x4fb602bc},
-#define USEM_COMMON_END 787
-#define USEM_PORT0_START 787
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0xa},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x28},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1950, 0x2e},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9640, 0x34},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d00, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d20, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3288, 0x96},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5440, 0x72},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
-#define USEM_PORT0_END 818
-#define USEM_PORT1_START 818
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1928, 0xa},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x95a0, 0x28},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9710, 0x34},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d10, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1da0, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x34e0, 0x96},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5608, 0x72},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
-#define USEM_PORT1_END 849
-#define USEM_FUNC0_START 849
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4010, 0x2},
-#define USEM_FUNC0_END 851
-#define USEM_FUNC1_START 851
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4020, 0x2},
-#define USEM_FUNC1_END 853
-#define USEM_FUNC2_START 853
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4030, 0x2},
-#define USEM_FUNC2_END 855
-#define USEM_FUNC3_START 855
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4040, 0x2},
-#define USEM_FUNC3_END 857
-#define USEM_FUNC4_START 857
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4050, 0x2},
-#define USEM_FUNC4_END 859
-#define USEM_FUNC5_START 859
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4060, 0x2},
-#define USEM_FUNC5_END 861
-#define USEM_FUNC6_START 861
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4070, 0x2},
-#define USEM_FUNC6_END 863
-#define USEM_FUNC7_START 863
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4080, 0x2},
-#define USEM_FUNC7_END 865
-#define CSEM_COMMON_START 865
- {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, CSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, CSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, CSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, CSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, CSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, CSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, CSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, CSEM_REG_TS_0_AS, 0x0},
- {OP_WR, CSEM_REG_TS_1_AS, 0x1},
- {OP_WR, CSEM_REG_TS_2_AS, 0x4},
- {OP_WR, CSEM_REG_TS_3_AS, 0x0},
- {OP_WR, CSEM_REG_TS_4_AS, 0x1},
- {OP_WR, CSEM_REG_TS_5_AS, 0x3},
- {OP_WR, CSEM_REG_TS_6_AS, 0x0},
- {OP_WR, CSEM_REG_TS_7_AS, 0x1},
- {OP_WR, CSEM_REG_TS_8_AS, 0x4},
- {OP_WR, CSEM_REG_TS_9_AS, 0x0},
- {OP_WR, CSEM_REG_TS_10_AS, 0x1},
- {OP_WR, CSEM_REG_TS_11_AS, 0x3},
- {OP_WR, CSEM_REG_TS_12_AS, 0x0},
- {OP_WR, CSEM_REG_TS_13_AS, 0x1},
- {OP_WR, CSEM_REG_TS_14_AS, 0x4},
- {OP_WR, CSEM_REG_TS_15_AS, 0x0},
- {OP_WR, CSEM_REG_TS_16_AS, 0x4},
- {OP_WR, CSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, CSEM_REG_TS_18_AS, 0x2},
- {OP_WR, CSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, CSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, CSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, CSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, CSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, CSEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, CSEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18000, 0x10},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18040, 0x12},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x18080, 0x30},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x180c0, 0xe},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x5000, 0x42},
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_WR_EMUL_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x1000, 0x42},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7020, 0xc8},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3070, 0x80},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7000, 0x2},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x4280, 0x4},
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x240},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b88, 0x2002be},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002a8},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002de},
- {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002b8},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ee},
- {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x6e0000},
- {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x6f0000},
- {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002c8},
- {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x1002fe},
- {OP_ZP_E1, CSEM_REG_PRAM, 0x32580000},
- {OP_ZP_E1H, CSEM_REG_PRAM, 0x31fa0000},
- {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x18270c96},
- {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x19040c7f},
- {OP_WR_64_E1, CSEM_REG_PRAM + 0xb210, 0x682402ca},
- {OP_WR_64_E1H, CSEM_REG_PRAM + 0xb430, 0x67e00300},
-#define CSEM_COMMON_END 944
-#define CSEM_PORT0_START 944
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8500, 0x40},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1980, 0x30},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8700, 0x3c},
- {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END 956
-#define CSEM_PORT1_START 956
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8600, 0x40},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x87f0, 0x3c},
- {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
- {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END 968
-#define CSEM_FUNC0_START 968
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
-#define CSEM_FUNC0_END 970
-#define CSEM_FUNC1_START 970
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
-#define CSEM_FUNC1_END 972
-#define CSEM_FUNC2_START 972
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
-#define CSEM_FUNC2_END 974
-#define CSEM_FUNC3_START 974
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
-#define CSEM_FUNC3_END 976
-#define CSEM_FUNC4_START 976
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
-#define CSEM_FUNC4_END 978
-#define CSEM_FUNC5_START 978
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
-#define CSEM_FUNC5_END 980
-#define CSEM_FUNC6_START 980
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
-#define CSEM_FUNC6_END 982
-#define CSEM_FUNC7_START 982
- {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
-#define CSEM_FUNC7_END 984
-#define XPB_COMMON_START 984
- {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
-#define XPB_COMMON_END 985
-#define DQ_COMMON_START 985
- {OP_WR, DORQ_REG_MODE_ACT, 0x2},
- {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
- {OP_WR, DORQ_REG_OUTST_REQ, 0x4},
- {OP_WR, DORQ_REG_DPM_CID_ADDR, 0x8},
- {OP_WR, DORQ_REG_RSP_INIT_CRD, 0x2},
- {OP_WR, DORQ_REG_NORM_CMHEAD_TX, 0x90},
- {OP_WR, DORQ_REG_CMHEAD_RX, 0x90},
- {OP_WR, DORQ_REG_SHRT_CMHEAD, 0x800090},
- {OP_WR, DORQ_REG_ERR_CMHEAD, 0x8140000},
- {OP_WR, DORQ_REG_AGG_CMD0, 0x8a},
- {OP_WR, DORQ_REG_AGG_CMD1, 0x80},
- {OP_WR, DORQ_REG_AGG_CMD2, 0x90},
- {OP_WR, DORQ_REG_AGG_CMD3, 0x80},
- {OP_WR, DORQ_REG_SHRT_ACT_CNT, 0x6},
- {OP_WR, DORQ_REG_DQ_FIFO_FULL_TH, 0x7d0},
- {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
- {OP_WR, DORQ_REG_REGN, 0x7c1004},
- {OP_WR, DORQ_REG_IF_EN, 0xf},
-#define DQ_COMMON_END 1003
-#define TIMERS_COMMON_START 1003
- {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
- {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
- {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
- {OP_WR, TM_REG_CFC_CLD_CRDCNT_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT0_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT1_VAL, 0x1},
- {OP_WR, TM_REG_CLOUT_CRDCNT2_VAL, 0x1},
- {OP_WR, TM_REG_EXP_CRDCNT_VAL, 0x1},
- {OP_WR_E1, TM_REG_PCIARB_CRDCNT_VAL, 0x1},
- {OP_WR_E1H, TM_REG_PCIARB_CRDCNT_VAL, 0x2},
- {OP_WR_ASIC, TM_REG_TIMER_TICK_SIZE, 0x3d090},
- {OP_WR_EMUL, TM_REG_TIMER_TICK_SIZE, 0x9c},
- {OP_WR_FPGA, TM_REG_TIMER_TICK_SIZE, 0x9c4},
- {OP_WR, TM_REG_CL0_CONT_REGION, 0x8},
- {OP_WR, TM_REG_CL1_CONT_REGION, 0xc},
- {OP_WR, TM_REG_CL2_CONT_REGION, 0x10},
- {OP_WR, TM_REG_TM_CONTEXT_REGION, 0x20},
- {OP_WR, TM_REG_EN_TIMERS, 0x1},
- {OP_WR, TM_REG_EN_REAL_TIME_CNT, 0x1},
- {OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
- {OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
- {OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
-#define TIMERS_COMMON_END 1025
-#define TIMERS_PORT0_START 1025
- {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
-#define TIMERS_PORT0_END 1026
-#define TIMERS_PORT1_START 1026
- {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
-#define TIMERS_PORT1_END 1027
-#define XSDM_COMMON_START 1027
- {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
- {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
- {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
- {OP_WR_E1H, XSDM_REG_CMP_COUNTER_START_ADDR, 0x410},
- {OP_WR_E1, XSDM_REG_Q_COUNTER_START_ADDR, 0x604},
- {OP_WR_E1H, XSDM_REG_Q_COUNTER_START_ADDR, 0x414},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX0, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX1, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX2, 0xffff},
- {OP_WR, XSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_0, 0x20},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_1, 0x20},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_2, 0x34},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_4, 0x23},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_5, 0x24},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_6, 0x25},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_7, 0x26},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_8, 0x27},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a},
- {OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b},
- {OP_ZR, XSDM_REG_AGG_INT_EVENT_12, 0x54},
- {OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1},
- {OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f},
- {OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff},
- {OP_WR, XSDM_REG_ENABLE_IN2, 0x3f},
- {OP_WR, XSDM_REG_ENABLE_OUT1, 0x7ffffff},
- {OP_WR, XSDM_REG_ENABLE_OUT2, 0xf},
- {OP_RD, XSDM_REG_NUM_OF_Q0_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q1_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q3_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q4_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q5_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q6_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q7_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q8_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q9_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q10_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_Q11_CMD, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
- {OP_RD, XSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
- {OP_WR_E1, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
- {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
- {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
- {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
-#define XSDM_COMMON_END 1074
-#define QM_COMMON_START 1074
- {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
- {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
- {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
- {OP_WR, QM_REG_ACTCTRINITVAL_3, 0x5},
- {OP_WR, QM_REG_PCIREQAT, 0x2},
- {OP_WR, QM_REG_CMINITCRD_0, 0x4},
- {OP_WR, QM_REG_CMINITCRD_1, 0x4},
- {OP_WR, QM_REG_CMINITCRD_2, 0x4},
- {OP_WR, QM_REG_CMINITCRD_3, 0x4},
- {OP_WR, QM_REG_CMINITCRD_4, 0x4},
- {OP_WR, QM_REG_CMINITCRD_5, 0x4},
- {OP_WR, QM_REG_CMINITCRD_6, 0x4},
- {OP_WR, QM_REG_CMINITCRD_7, 0x4},
- {OP_WR, QM_REG_OUTLDREQ, 0x4},
- {OP_WR, QM_REG_CTXREG_0, 0x7c},
- {OP_WR, QM_REG_CTXREG_1, 0x3d},
- {OP_WR, QM_REG_CTXREG_2, 0x3f},
- {OP_WR, QM_REG_CTXREG_3, 0x9c},
- {OP_WR, QM_REG_ENSEC, 0x7},
- {OP_ZR, QM_REG_QVOQIDX_0, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_0, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_5, 0x0},
- {OP_WR, QM_REG_QVOQIDX_6, 0x4},
- {OP_WR, QM_REG_QVOQIDX_7, 0x4},
- {OP_WR, QM_REG_QVOQIDX_8, 0x2},
- {OP_WR, QM_REG_WRRWEIGHTS_1, 0x8012004},
- {OP_WR, QM_REG_QVOQIDX_9, 0x5},
- {OP_WR, QM_REG_QVOQIDX_10, 0x5},
- {OP_WR, QM_REG_QVOQIDX_11, 0x5},
- {OP_WR, QM_REG_QVOQIDX_12, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_2, 0x20081001},
- {OP_WR, QM_REG_QVOQIDX_13, 0x8},
- {OP_WR, QM_REG_QVOQIDX_14, 0x6},
- {OP_WR, QM_REG_QVOQIDX_15, 0x7},
- {OP_WR, QM_REG_QVOQIDX_16, 0x0},
- {OP_WR, QM_REG_WRRWEIGHTS_3, 0x1010120},
- {OP_ZR, QM_REG_QVOQIDX_17, 0x4},
- {OP_WR, QM_REG_WRRWEIGHTS_4, 0x1010101},
- {OP_ZR_E1, QM_REG_QVOQIDX_21, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_21, 0x0},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_5, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_22, 0x4},
- {OP_ZR_E1, QM_REG_QVOQIDX_25, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_23, 0x4},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_6, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_24, 0x2},
- {OP_ZR_E1, QM_REG_QVOQIDX_29, 0x3},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_5, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_25, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_26, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_27, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_28, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_6, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_29, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_30, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_31, 0x7},
- {OP_WR, QM_REG_QVOQIDX_32, 0x1},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_7, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_7, 0x1010120},
- {OP_WR, QM_REG_QVOQIDX_33, 0x1},
- {OP_WR, QM_REG_QVOQIDX_34, 0x1},
- {OP_WR, QM_REG_QVOQIDX_35, 0x1},
- {OP_WR, QM_REG_QVOQIDX_36, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_8, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_37, 0x1},
- {OP_WR, QM_REG_QVOQIDX_38, 0x4},
- {OP_WR, QM_REG_QVOQIDX_39, 0x4},
- {OP_WR, QM_REG_QVOQIDX_40, 0x2},
- {OP_WR, QM_REG_WRRWEIGHTS_9, 0x8012004},
- {OP_WR, QM_REG_QVOQIDX_41, 0x5},
- {OP_WR, QM_REG_QVOQIDX_42, 0x5},
- {OP_WR, QM_REG_QVOQIDX_43, 0x5},
- {OP_WR, QM_REG_QVOQIDX_44, 0x5},
- {OP_WR, QM_REG_WRRWEIGHTS_10, 0x20081001},
- {OP_WR, QM_REG_QVOQIDX_45, 0x8},
- {OP_WR, QM_REG_QVOQIDX_46, 0x6},
- {OP_WR, QM_REG_QVOQIDX_47, 0x7},
- {OP_WR, QM_REG_QVOQIDX_48, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_11, 0x1010120},
- {OP_WR, QM_REG_QVOQIDX_49, 0x1},
- {OP_WR, QM_REG_QVOQIDX_50, 0x1},
- {OP_WR, QM_REG_QVOQIDX_51, 0x1},
- {OP_WR, QM_REG_QVOQIDX_52, 0x1},
- {OP_WR, QM_REG_WRRWEIGHTS_12, 0x1010101},
- {OP_WR, QM_REG_QVOQIDX_53, 0x1},
- {OP_WR_E1, QM_REG_QVOQIDX_54, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_54, 0x4},
- {OP_WR_E1, QM_REG_QVOQIDX_55, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_55, 0x4},
- {OP_WR_E1, QM_REG_QVOQIDX_56, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_56, 0x2},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_13, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_13, 0x8012004},
- {OP_WR_E1, QM_REG_QVOQIDX_57, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_57, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_58, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_58, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_59, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_59, 0x5},
- {OP_WR_E1, QM_REG_QVOQIDX_60, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_60, 0x5},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_14, 0x1010101},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_14, 0x20081001},
- {OP_WR_E1, QM_REG_QVOQIDX_61, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_61, 0x8},
- {OP_WR_E1, QM_REG_QVOQIDX_62, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_62, 0x6},
- {OP_WR_E1, QM_REG_QVOQIDX_63, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_63, 0x7},
- {OP_WR_E1, QM_REG_WRRWEIGHTS_15, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_64, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_0_LSB, 0xffff003f},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_15, 0x1010120},
- {OP_ZR_E1, QM_REG_VOQQMASK_0_MSB, 0x2},
- {OP_ZR_E1H, QM_REG_QVOQIDX_65, 0x4},
- {OP_WR_E1, QM_REG_VOQQMASK_1_MSB, 0xffff003f},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_16, 0x1010101},
- {OP_WR_E1, QM_REG_VOQQMASK_2_LSB, 0x100},
- {OP_WR_E1H, QM_REG_QVOQIDX_69, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_2_MSB, 0x100},
- {OP_WR_E1H, QM_REG_QVOQIDX_70, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_71, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_72, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_17, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_73, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_74, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_75, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_76, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_18, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_77, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_78, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_79, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_80, 0x0},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_19, 0x1010120},
- {OP_ZR_E1H, QM_REG_QVOQIDX_81, 0x4},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_20, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_85, 0x0},
- {OP_WR_E1H, QM_REG_QVOQIDX_86, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_87, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_88, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_21, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_89, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_90, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_91, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_92, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_22, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_93, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_94, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_95, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_96, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_23, 0x1010120},
- {OP_WR_E1H, QM_REG_QVOQIDX_97, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_98, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_99, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_100, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_24, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_101, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_102, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_103, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_104, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_25, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_105, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_106, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_107, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_108, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_26, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_109, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_110, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_111, 0x7},
- {OP_WR_E1H, QM_REG_QVOQIDX_112, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_27, 0x1010120},
- {OP_WR_E1H, QM_REG_QVOQIDX_113, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_114, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_115, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_116, 0x1},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_28, 0x1010101},
- {OP_WR_E1H, QM_REG_QVOQIDX_117, 0x1},
- {OP_WR_E1H, QM_REG_QVOQIDX_118, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_119, 0x4},
- {OP_WR_E1H, QM_REG_QVOQIDX_120, 0x2},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_29, 0x8012004},
- {OP_WR_E1H, QM_REG_QVOQIDX_121, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_122, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_123, 0x5},
- {OP_WR_E1H, QM_REG_QVOQIDX_124, 0x5},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_30, 0x20081001},
- {OP_WR_E1H, QM_REG_QVOQIDX_125, 0x8},
- {OP_WR_E1H, QM_REG_QVOQIDX_126, 0x6},
- {OP_WR_E1H, QM_REG_QVOQIDX_127, 0x7},
- {OP_WR_E1H, QM_REG_WRRWEIGHTS_31, 0x1010120},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB_EXT_A, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB_EXT_A, 0x3f003f},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB_EXT_A, 0x1000100},
- {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB_EXT_A, 0x1000100},
- {OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2},
- {OP_WR_E1, QM_REG_VOQQMASK_4_LSB, 0xc0},
- {OP_WR_E1H, QM_REG_VOQQMASK_3_LSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_4_MSB, 0xc0},
- {OP_WR_E1H, QM_REG_VOQQMASK_3_MSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_VOQQMASK_5_LSB, 0x1e00},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_5_MSB, 0x1e00},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_6_LSB, 0x4000},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB_EXT_A, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_6_MSB, 0x4000},
- {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB_EXT_A, 0xc000c0},
- {OP_WR_E1, QM_REG_VOQQMASK_7_LSB, 0x8000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_7_MSB, 0x8000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_8_LSB, 0x2000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB_EXT_A, 0x1e001e00},
- {OP_WR_E1, QM_REG_VOQQMASK_8_MSB, 0x2000},
- {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB_EXT_A, 0x1e001e00},
- {OP_ZR_E1, QM_REG_VOQQMASK_9_LSB, 0x7},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB_EXT_A, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB_EXT_A, 0x40004000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB_EXT_A, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB_EXT_A, 0x80008000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB_EXT_A, 0x20002000},
- {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB_EXT_A, 0x20002000},
- {OP_ZR_E1H, QM_REG_VOQQMASK_9_LSB, 0x2},
- {OP_WR_E1H, QM_REG_VOQQMASK_9_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_9_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB_EXT_A, 0x0},
- {OP_WR_E1H, QM_REG_VOQPORT_0, 0x0},
- {OP_WR, QM_REG_VOQPORT_1, 0x1},
- {OP_ZR, QM_REG_VOQPORT_2, 0xa},
- {OP_WR, QM_REG_CMINTVOQMASK_0, 0xc08},
- {OP_WR, QM_REG_CMINTVOQMASK_1, 0x40},
- {OP_WR, QM_REG_CMINTVOQMASK_2, 0x100},
- {OP_WR, QM_REG_CMINTVOQMASK_3, 0x20},
- {OP_WR, QM_REG_CMINTVOQMASK_4, 0x17},
- {OP_WR, QM_REG_CMINTVOQMASK_5, 0x80},
- {OP_WR, QM_REG_CMINTVOQMASK_6, 0x200},
- {OP_WR, QM_REG_CMINTVOQMASK_7, 0x0},
- {OP_WR_E1, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB, 0x1ff01ff},
- {OP_WR_E1, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB, 0x1ff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB_EXT_A, 0x1ff01ff},
- {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB_EXT_A, 0x1ff01ff},
- {OP_WR, QM_REG_ENBYPVOQMASK, 0x13},
- {OP_WR, QM_REG_VOQCREDITAFULLTHR, 0x13f},
- {OP_WR, QM_REG_VOQINITCREDIT_0, 0x140},
- {OP_WR, QM_REG_VOQINITCREDIT_1, 0x140},
- {OP_ZR, QM_REG_VOQINITCREDIT_2, 0x2},
- {OP_WR, QM_REG_VOQINITCREDIT_4, 0xc0},
- {OP_ZR, QM_REG_VOQINITCREDIT_5, 0x7},
- {OP_WR, QM_REG_TASKCRDCOST_0, 0x48},
- {OP_WR, QM_REG_TASKCRDCOST_1, 0x48},
- {OP_ZR, QM_REG_TASKCRDCOST_2, 0x2},
- {OP_WR, QM_REG_TASKCRDCOST_4, 0x48},
- {OP_ZR, QM_REG_TASKCRDCOST_5, 0x7},
- {OP_WR, QM_REG_BYTECRDINITVAL, 0x8000},
- {OP_WR, QM_REG_BYTECRDCOST, 0x25e4},
- {OP_WR, QM_REG_BYTECREDITAFULLTHR, 0x7fff},
- {OP_WR_E1, QM_REG_ENBYTECRD_LSB, 0x7},
- {OP_WR_E1H, QM_REG_ENBYTECRD_LSB, 0x70007},
- {OP_WR_E1, QM_REG_ENBYTECRD_MSB, 0x7},
- {OP_WR_E1H, QM_REG_ENBYTECRD_MSB, 0x70007},
- {OP_WR_E1H, QM_REG_ENBYTECRD_LSB_EXT_A, 0x70007},
- {OP_WR_E1H, QM_REG_ENBYTECRD_MSB_EXT_A, 0x70007},
- {OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0},
- {OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff},
- {OP_WR_E1, QM_REG_FUNCNUMSEL_LSB, 0x0},
- {OP_WR_E1H, QM_REG_BYTECRDPORT_LSB_EXT_A, 0x0},
- {OP_WR_E1, QM_REG_FUNCNUMSEL_MSB, 0xffffffff},
- {OP_WR_E1H, QM_REG_BYTECRDPORT_MSB_EXT_A, 0xffffffff},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_0, 0x0},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_1, 0x2},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_2, 0x1},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_3, 0x3},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_4, 0x4},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_5, 0x6},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
- {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
- {OP_WR, QM_REG_CMINTEN, 0xff},
-#define QM_COMMON_END 1374
-#define PBF_COMMON_START 1374
- {OP_WR, PBF_REG_INIT, 0x1},
- {OP_WR, PBF_REG_INIT_P4, 0x1},
- {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
- {OP_WR, PBF_REG_IF_ENABLE_REG, 0x7fff},
- {OP_WR, PBF_REG_INIT_P4, 0x0},
- {OP_WR, PBF_REG_INIT, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
-#define PBF_COMMON_END 1381
-#define PBF_PORT0_START 1381
- {OP_WR, PBF_REG_INIT_P0, 0x1},
- {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
- {OP_WR, PBF_REG_INIT_P0, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
-#define PBF_PORT0_END 1385
-#define PBF_PORT1_START 1385
- {OP_WR, PBF_REG_INIT_P1, 0x1},
- {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
- {OP_WR, PBF_REG_INIT_P1, 0x0},
- {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
-#define PBF_PORT1_END 1389
-#define XCM_COMMON_START 1389
- {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
- {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
- {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
- {OP_WR, XCM_REG_TM_XCM_HDR, 0x1000030},
- {OP_WR, XCM_REG_ERR_XCM_HDR, 0x8100000},
- {OP_WR, XCM_REG_ERR_EVNT_ID, 0x33},
- {OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30},
- {OP_WR, XCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, XCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_TSEM_WEIGHT, 0x5},
- {OP_WR, XCM_REG_CSEM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_USEM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_PBF_WEIGHT, 0x7},
- {OP_WR, XCM_REG_NIG1_WEIGHT, 0x1},
- {OP_WR, XCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, XCM_REG_XSDM_WEIGHT, 0x5},
- {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x3},
- {OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1},
- {OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6},
- {OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0},
- {OP_WR, XCM_REG_AUX1_Q, 0x2},
- {OP_WR, XCM_REG_AUX_CNT_FLG_Q_19, 0x1},
- {OP_WR, XCM_REG_GR_ARB_TYPE, 0x1},
- {OP_WR, XCM_REG_GR_LD0_PR, 0x1},
- {OP_WR, XCM_REG_GR_LD1_PR, 0x2},
- {OP_WR, XCM_REG_CFC_INIT_CRD, 0x1},
- {OP_WR, XCM_REG_FIC0_INIT_CRD, 0x40},
- {OP_WR, XCM_REG_FIC1_INIT_CRD, 0x40},
- {OP_WR, XCM_REG_TM_INIT_CRD, 0x4},
- {OP_WR, XCM_REG_XQM_INIT_CRD, 0x20},
- {OP_WR, XCM_REG_XX_INIT_CRD, 0x2},
- {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
- {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
- {OP_ZR, XCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02cc},
- {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0302},
- {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
- {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
- {OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb},
- {OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe},
- {OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xc},
- {OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3},
- {OP_WR, XCM_REG_XCM_REG0_SZ, 0x4},
- {OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_STORM1_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_XQM_IFEN, 0x1},
- {OP_WR, XCM_REG_STORM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XQM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XSDM_IFEN, 0x1},
- {OP_WR, XCM_REG_TM_XCM_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_TM_IFEN, 0x1},
- {OP_WR, XCM_REG_TSEM_IFEN, 0x1},
- {OP_WR, XCM_REG_CSEM_IFEN, 0x1},
- {OP_WR, XCM_REG_USEM_IFEN, 0x1},
- {OP_WR, XCM_REG_DORQ_IFEN, 0x1},
- {OP_WR, XCM_REG_PBF_IFEN, 0x1},
- {OP_WR, XCM_REG_NIG0_IFEN, 0x1},
- {OP_WR, XCM_REG_NIG1_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_AG_WR_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_AG_RD_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
- {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
- {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
-#define XCM_COMMON_END 1453
-#define XCM_PORT0_START 1453
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-#define XCM_PORT0_END 1461
-#define XCM_PORT1_START 1461
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-#define XCM_PORT1_END 1469
-#define XCM_FUNC0_START 1469
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC0_END 1478
-#define XCM_FUNC1_START 1478
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC1_END 1487
-#define XCM_FUNC2_START 1487
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC2_END 1496
-#define XCM_FUNC3_START 1496
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC3_END 1505
-#define XCM_FUNC4_START 1505
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC4_END 1514
-#define XCM_FUNC5_START 1514
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC5_END 1523
-#define XCM_FUNC6_START 1523
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC6_END 1532
-#define XCM_FUNC7_START 1532
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
- {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
- {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
- {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC7_END 1541
-#define XSEM_COMMON_START 1541
- {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC1, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC2, 0x0},
- {OP_RD, XSEM_REG_MSG_NUM_FOC3, 0x0},
- {OP_WR, XSEM_REG_ARB_ELEMENT0, 0x1},
- {OP_WR, XSEM_REG_ARB_ELEMENT1, 0x2},
- {OP_WR, XSEM_REG_ARB_ELEMENT2, 0x3},
- {OP_WR, XSEM_REG_ARB_ELEMENT3, 0x0},
- {OP_WR, XSEM_REG_ARB_ELEMENT4, 0x4},
- {OP_WR, XSEM_REG_ARB_CYCLE_SIZE, 0x1},
- {OP_WR, XSEM_REG_TS_0_AS, 0x0},
- {OP_WR, XSEM_REG_TS_1_AS, 0x1},
- {OP_WR, XSEM_REG_TS_2_AS, 0x4},
- {OP_WR, XSEM_REG_TS_3_AS, 0x0},
- {OP_WR, XSEM_REG_TS_4_AS, 0x1},
- {OP_WR, XSEM_REG_TS_5_AS, 0x3},
- {OP_WR, XSEM_REG_TS_6_AS, 0x0},
- {OP_WR, XSEM_REG_TS_7_AS, 0x1},
- {OP_WR, XSEM_REG_TS_8_AS, 0x4},
- {OP_WR, XSEM_REG_TS_9_AS, 0x0},
- {OP_WR, XSEM_REG_TS_10_AS, 0x1},
- {OP_WR, XSEM_REG_TS_11_AS, 0x3},
- {OP_WR, XSEM_REG_TS_12_AS, 0x0},
- {OP_WR, XSEM_REG_TS_13_AS, 0x1},
- {OP_WR, XSEM_REG_TS_14_AS, 0x4},
- {OP_WR, XSEM_REG_TS_15_AS, 0x0},
- {OP_WR, XSEM_REG_TS_16_AS, 0x4},
- {OP_WR, XSEM_REG_TS_17_AS, 0x3},
- {OP_ZR, XSEM_REG_TS_18_AS, 0x2},
- {OP_WR, XSEM_REG_ENABLE_IN, 0x3fff},
- {OP_WR, XSEM_REG_ENABLE_OUT, 0x3ff},
- {OP_WR, XSEM_REG_FIC0_DISABLE, 0x0},
- {OP_WR, XSEM_REG_FIC1_DISABLE, 0x0},
- {OP_WR, XSEM_REG_PAS_DISABLE, 0x0},
- {OP_WR, XSEM_REG_THREADS_LIST, 0xffff},
- {OP_ZR, XSEM_REG_PASSIVE_BUFFER, 0x800},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18000, 0x0},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18040, 0x18},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x18080, 0xc},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x180c0, 0x66},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18300, 0x138},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18340, 0x0},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18340, 0x5},
- {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
- {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
- {OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0},
- {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d00, 0x4},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9020, 0xc8},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3128, 0x8e},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202eb},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402ed},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x20321},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x40323},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ac8, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202f1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ab8, 0x0},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f50, 0x202f3},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100327},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x83b0, 0x20337},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x1002f5},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100339},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80305},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80349},
- {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8030d},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80351},
- {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xa90000},
- {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xac0000},
- {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130315},
- {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x368, 0x130359},
- {OP_ZP_E1, XSEM_REG_PRAM, 0x344e0000},
- {OP_ZP_E1H, XSEM_REG_PRAM, 0x34620000},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38840d14},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x38240d19},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3e711b35},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3e971b22},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x1dd02ad2},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x21542ac8},
- {OP_WR_64_E1, XSEM_REG_PRAM + 0x1c0d0, 0x47e60317},
- {OP_WR_64_E1H, XSEM_REG_PRAM + 0x1c8d0, 0x46e6035b},
-#define XSEM_COMMON_END 1651
-#define XSEM_PORT0_START 1651
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x10},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c20, 0x1c},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x10},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2528, 0x1c},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2608, 0x1c},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26e8, 0x1c},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x27c8, 0x1c},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d10, 0x100319},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5030, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5010, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2035d},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20329},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
-#define XSEM_PORT0_END 1683
-#define XSEM_PORT1_START 1683
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3be0, 0x10},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c90, 0x1c},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24e8, 0x10},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2598, 0x1c},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2678, 0x1c},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2758, 0x1c},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2838, 0x1c},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d50, 0x10032b},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5038, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5008, 0x2},
- {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5018, 0x2},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2035f},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2033b},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
-#define XSEM_PORT1_END 1715
-#define XSEM_FUNC0_START 1715
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28b8, 0x100361},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-#define XSEM_FUNC0_END 1718
-#define XSEM_FUNC1_START 1718
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28f8, 0x100371},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-#define XSEM_FUNC1_END 1721
-#define XSEM_FUNC2_START 1721
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x100381},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
-#define XSEM_FUNC2_END 1724
-#define XSEM_FUNC3_START 1724
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2978, 0x100391},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
-#define XSEM_FUNC3_END 1727
-#define XSEM_FUNC4_START 1727
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29b8, 0x1003a1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
-#define XSEM_FUNC4_END 1730
-#define XSEM_FUNC5_START 1730
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f8, 0x1003b1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
-#define XSEM_FUNC5_END 1733
-#define XSEM_FUNC6_START 1733
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a38, 0x1003c1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
-#define XSEM_FUNC6_END 1736
-#define XSEM_FUNC7_START 1736
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a78, 0x1003d1},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
-#define XSEM_FUNC7_END 1739
-#define CDU_COMMON_START 1739
- {OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
- {OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
- {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
- {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
- {OP_WB_E1, CDU_REG_L1TT, 0x200033d},
- {OP_WB_E1H, CDU_REG_L1TT, 0x20003e1},
- {OP_WB_E1, CDU_REG_MATT, 0x20053d},
- {OP_WB_E1H, CDU_REG_MATT, 0x2805e1},
- {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
- {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6055d},
- {OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
-#define CDU_COMMON_END 1750
-#define DMAE_COMMON_START 1750
- {OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
- {OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
- {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
- {OP_WR_E1, DMAE_REG_PXP_REQ_INIT_CRD, 0x1},
- {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
- {OP_WR, DMAE_REG_PCI_IFEN, 0x1},
- {OP_WR, DMAE_REG_GRC_IFEN, 0x1},
-#define DMAE_COMMON_END 1757
-#define PXP_COMMON_START 1757
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50563},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50609},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50568},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5060e},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5056d},
-#define PXP_COMMON_END 1762
-#define CFC_COMMON_START 1762
- {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
- {OP_WR, CFC_REG_CONTROL0, 0x10},
- {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
- {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
-#define CFC_COMMON_END 1766
-#define HC_COMMON_START 1766
- {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
-#define HC_COMMON_END 1767
-#define HC_PORT0_START 1767
- {OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
- {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
- {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1, HC_REG_LEADING_EDGE_0, 0xffff},
- {OP_WR_E1, HC_REG_TRAILING_EDGE_0, 0xffff},
- {OP_WR_E1, HC_REG_AGG_INT_0, 0x0},
- {OP_WR_E1, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_PORT0_END 1785
-#define HC_PORT1_START 1785
- {OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
- {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
- {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1, HC_REG_LEADING_EDGE_1, 0xffff},
- {OP_WR_E1, HC_REG_TRAILING_EDGE_1, 0xffff},
- {OP_WR_E1, HC_REG_AGG_INT_1, 0x0},
- {OP_WR_E1, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_PORT1_END 1803
-#define HC_FUNC0_START 1803
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC0_END 1818
-#define HC_FUNC1_START 1818
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC1_END 1833
-#define HC_FUNC2_START 1833
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC2_END 1848
-#define HC_FUNC3_START 1848
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC3_END 1863
-#define HC_FUNC4_START 1863
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC4_END 1878
-#define HC_FUNC5_START 1878
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC5_END 1893
-#define HC_FUNC6_START 1893
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
- {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
- {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC6_END 1908
-#define HC_FUNC7_START 1908
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
- {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
- {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
- {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
- {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
- {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
- {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
- {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
- {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
- {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
- {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC7_END 1923
-#define PXP2_COMMON_START 1923
- {OP_WR_E1, PXP2_REG_PGL_CONTROL0, 0xe38340},
- {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
- {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
- {OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1},
- {OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_0, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_7, 0xffffffff},
- {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_XSDM_7, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_0, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_1, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_2, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_3, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_4, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_5, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_6, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_CSDM_7, 0xffffffff},
- {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_0, 0xffff3330},
- {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_0, 0xff802000},
- {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340},
- {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000},
- {OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ11, 0x2},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ17, 0x4},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ18, 0x5},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ19, 0x4},
- {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ22, 0x0},
- {OP_WR, PXP2_REG_RD_START_INIT, 0x1},
- {OP_WR, PXP2_REG_WR_DMAE_TH, 0x3f},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD0, 0x40},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD1, 0x1808},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD2, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD3, 0x803},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD4, 0x40},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD5, 0x3},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD6, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD7, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD8, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD9, 0x10003},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD10, 0x803},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD11, 0x803},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD12, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD13, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD14, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD15, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD16, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD17, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD18, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD19, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD20, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD22, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD23, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD24, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD25, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD26, 0x3},
- {OP_WR, PXP2_REG_RQ_BW_RD_ADD27, 0x3},
- {OP_WR, PXP2_REG_PSWRQ_BW_ADD28, 0x2403},
- {OP_WR, PXP2_REG_RQ_BW_WR_ADD29, 0x2f},
- {OP_WR, PXP2_REG_RQ_BW_WR_ADD30, 0x9},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND0, 0x19},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB1, 0x184},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB2, 0x183},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB3, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND4, 0x19},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND5, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB6, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB7, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB8, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB9, 0xc86},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB10, 0x306},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB11, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND12, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND13, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND14, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND15, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND16, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND17, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND18, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND19, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND20, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND22, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND23, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND24, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND25, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND26, 0x6},
- {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND27, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_UB28, 0x306},
- {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND29, 0x13},
- {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND30, 0x6},
- {OP_WR, PXP2_REG_PSWRQ_BW_L1, 0x1004},
- {OP_WR, PXP2_REG_PSWRQ_BW_L2, 0x1004},
- {OP_WR, PXP2_REG_PSWRQ_BW_RD, 0x106440},
- {OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440},
- {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
- {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
- {OP_WR_E1H, PXP2_REG_PGL_CONTROL0, 0xe38340},
-#define PXP2_COMMON_END 2040
-#define MISC_AEU_COMMON_START 2040
- {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_0, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_0, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_1, 0xf0000000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_1, 0x0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_1, 0x10000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_1, 0x5014},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
- {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
- {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
-#define MISC_AEU_COMMON_END 2059
-#define MISC_AEU_PORT0_START 2059
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff55fff},
- {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0xf00003e0},
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1, 0xa000},
- {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1, 0x5},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2, 0xfe00000},
- {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x7},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4, 0x400},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_5, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5, 0x1000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_0, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_6, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6, 0x4000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_7, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7, 0x10000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_0, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x4},
- {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
- {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
- {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
-#define MISC_AEU_PORT0_END 2091
-#define MISC_AEU_PORT1_START 2091
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff55fff},
- {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0xf00003e0},
- {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1, 0x0},
- {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1, 0xa000},
- {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1, 0x5},
- {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2, 0xfe00000},
- {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x7},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4, 0x800},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_5, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5, 0x2000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_1, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_6, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6, 0x8000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555},
- {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_7, 0x3},
- {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555},
- {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7, 0x20000},
- {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
- {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x4},
- {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
- {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
- {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
-#define MISC_AEU_PORT1_END 2123
-
-};
-
-static const u32 init_data_e1[] = {
- 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
- 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
- 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
- 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
- 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
- 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
- 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
- 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
- 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
- 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
- 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
- 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
- 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
- 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
- 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
- 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
- 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
- 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
- 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
- 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
- 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
- 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
- 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
- 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
- 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
- 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
- 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
- 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
- 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
- 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
- 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
- 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
- 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
- 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
- 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
- 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
- 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
- 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
- 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
- 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
- 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
- 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
- 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
- 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
- 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
- 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
- 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
- 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
- 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
- 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
- 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
- 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
- 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
- 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
- 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
- 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
- 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
- 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
- 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
- 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
- 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
- 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
- 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
- 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
- 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
- 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
- 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
- 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
- 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
- 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
- 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
- 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
- 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
- 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
- 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
- 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
- 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
- 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
- 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
- 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
- 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
- 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
- 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
- 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
- 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
- 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
- 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
- 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
- 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
- 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
- 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
- 0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500,
- 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0,
- 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540,
- 0x00012600, 0x000146c0, 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0,
- 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40,
- 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140, 0x00033200, 0x000352c0,
- 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740,
- 0x00043800, 0x000458c0, 0x00047980, 0x00049a40, 0x00008000, 0x00010380,
- 0x00018700, 0x00020a80, 0x00028e00, 0x00031180, 0x00039500, 0x00041880,
- 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80,
- 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280,
- 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780,
- 0x000ddb00, 0x00001900, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
- 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
- 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
- 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
- 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
- 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
- 0xccccccc1, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, 0x00000000,
- 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000,
- 0x00003500, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x00100000,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x00100000,
- 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7,
- 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a,
- 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
- 0x040fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170,
- 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370, 0x00080000,
- 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200, 0x00070210,
- 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198, 0x00020250,
- 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100, 0x00028180,
- 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380, 0x00028000,
- 0x000b8028, 0x000200e0, 0x00010100, 0x00008110, 0x00000118, 0xcccccccc,
- 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0x00002000
-};
-
-static const u32 init_data_e1h[] = {
- 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
- 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
- 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
- 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
- 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
- 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
- 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
- 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
- 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
- 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
- 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
- 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
- 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
- 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
- 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
- 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
- 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
- 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
- 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
- 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
- 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
- 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
- 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
- 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
- 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
- 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
- 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
- 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
- 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
- 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
- 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
- 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
- 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
- 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
- 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
- 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
- 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
- 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
- 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
- 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
- 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
- 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
- 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
- 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
- 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
- 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
- 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
- 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
- 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
- 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
- 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
- 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
- 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
- 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
- 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
- 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
- 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
- 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
- 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
- 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
- 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
- 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
- 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
- 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
- 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
- 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
- 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
- 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
- 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
- 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
- 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
- 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
- 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
- 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
- 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
- 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
- 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
- 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
- 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
- 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
- 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
- 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
- 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
- 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
- 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
- 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
- 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
- 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
- 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
- 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
- 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
- 0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240,
- 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0,
- 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40,
- 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0,
- 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440,
- 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0,
- 0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80,
- 0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80,
- 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480,
- 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980,
- 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900,
- 0x00000028, 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
- 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
- 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
- 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
- 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
- 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
- 0xccccccc5, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, 0xcccc0201,
- 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201,
- 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201,
- 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
- 0x00007ff8, 0x00000000, 0x00003500, 0x00100000, 0x00000000, 0x00100000,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
- 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x31afffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffff97, 0x058fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000,
- 0x00070100, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280,
- 0x00010370, 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0,
- 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170,
- 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000,
- 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298,
- 0x00080380, 0x000d0000, 0x000000d0, 0x000280d0, 0x000b80f8, 0x000201b0,
- 0x000101d0, 0x000c81e0, 0x000002a8, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000
-};
-
-static const u32 tsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9b38a, 0x22717618,
- 0xa70143f8, 0xa4303332, 0x10267103, 0x97e204af, 0xaf0c0c8c, 0x2fd78918,
- 0xcf608621, 0x38606610, 0x4206c402, 0x22450c0c, 0xa07af108, 0xfe407b9a,
- 0xb698a842, 0x76c30328, 0x3bf781d1, 0x34957035, 0x24a458a6, 0x458d5d82,
- 0xa0d7191e, 0x4494efc9, 0xd012d7e5, 0x4538d03f, 0x513f9509, 0x547f4201,
- 0x342fa684, 0xf95049f9, 0xa57f5039, 0x77376129, 0x001e542e, 0x61aa8a92,
- 0x00000360
-};
-
-static const u32 tsem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x49999cce,
- 0x204e4cce, 0x30840909, 0x43511879, 0x7c061e1c, 0x201276f4, 0x06bf2ae5,
- 0x0ea2a17c, 0x2de42108, 0xebf8fea5, 0x092132fd, 0xf636c544, 0xda2f45a2,
- 0x05a855e1, 0xa180d03b, 0x4a00ee05, 0x7836daa1, 0xf5ab15bd, 0x62a2968e,
- 0x96ad2248, 0xbfcb17fe, 0x24fbdad6, 0x00664e73, 0xbbf7bdcb, 0x9fa7efd7,
- 0xece7d9dd, 0xebdaf7b3, 0x7b5ad7b5, 0x5d8a3ded, 0x19d7ea62, 0xa0ff873b,
- 0xc631b3ec, 0x9f2c19ae, 0x23a57cc8, 0x6ad8cbd7, 0x3127d43b, 0x0f623c16,
- 0x5b18926d, 0xb59fda32, 0x71ca0d30, 0xbc20be69, 0xebe16767, 0xc654c612,
- 0x9b4aadff, 0xe8f2c994, 0xf073b9f9, 0xf30f81dc, 0x58564b19, 0x63026530,
- 0xafcc6c2b, 0x8fba830f, 0xfc9c0fb1, 0x7ff8739b, 0xf61b24c1, 0xbf874233,
- 0xaf3edfa1, 0x814f682d, 0xedcdb37e, 0x1215494e, 0xd5db1993, 0x140bd2c4,
- 0x9c9abac6, 0x49b4fe54, 0x60282f4f, 0x26534f6c, 0x7935f7d5, 0x8d348ca9,
- 0x9a07e7a5, 0xb34f547c, 0xf7e3d7f5, 0x2b7c8e23, 0xce0d1595, 0x68ae5adf,
- 0x060b7182, 0x64cc7feb, 0xf9e00541, 0xafeec2a3, 0x5f9aef80, 0x8512989f,
- 0x802c99f2, 0xf7e86536, 0x45fb2ecf, 0x8ce1b4fe, 0x387c3d65, 0x6844da7f,
- 0xe139b127, 0x87459c22, 0xe25c6b34, 0x77b19f71, 0xcdc032a4, 0x6991802d,
- 0xb9b58c99, 0x4f2e6ffa, 0x44f5cc65, 0x0b9a7fb6, 0x5d0cdde6, 0x2eec648c,
- 0xde0c1056, 0xf81ffd00, 0xe80525b8, 0x614976a1, 0x4b26cd78, 0xd012cd15,
- 0x7ccedd8b, 0xa538709b, 0xd41479a2, 0xde60eefb, 0xe383bdc7, 0x9880c5dc,
- 0x46ccd8e9, 0x32a864e5, 0xa5dd87e8, 0xe2e53686, 0x15c5fd87, 0x2fb712e3,
- 0xd517f839, 0xf6f1a6eb, 0x078d328f, 0x7f13b9df, 0xcbe07597, 0xaef7d77d,
- 0x78842332, 0xe11f9853, 0xc657753b, 0xde25c7ba, 0x7d8f163e, 0xc70aab2a,
- 0x8e1567a1, 0x66dcfc0b, 0x367b74e7, 0xb18d4a17, 0x16663835, 0x9c62b563,
- 0x03d95a29, 0x3000b258, 0xb58cb5e7, 0xdda0bd20, 0x3abf6894, 0xdf4ae00f,
- 0x852a4b33, 0x0af1fa7a, 0xf2115e69, 0x10cf41a1, 0xb1259ff5, 0x9ef81d8a,
- 0x70ca92cd, 0xe71f3b1c, 0x8b50fe86, 0xe86ee007, 0xec9eddca, 0x6194fde5,
- 0x48553fbb, 0x3858b5f3, 0x7a4fd4bd, 0xdf038c17, 0x38c0f7a7, 0xa56b3ef0,
- 0xfe69bac4, 0xe1a614de, 0x32c67e78, 0x70a6a440, 0xa8d99099, 0x7867e424,
- 0xfc8165ae, 0x3f2e3364, 0x8be635a7, 0x9f737e00, 0xd0d47cd4, 0x783579ab,
- 0x69c85a3f, 0x266aa076, 0x01b630f3, 0x530593d0, 0x7ca8dd1e, 0xb3918d10,
- 0xcda37331, 0x9663fa28, 0x997b9f99, 0x9cf286d7, 0xcf3f341b, 0xbfd7376f,
- 0x2769dccd, 0xdc3f82ae, 0x8e4e7dcc, 0xc0e38f33, 0x12cf00d4, 0x6fc0ef21,
- 0xadbf2c6a, 0x5a19626d, 0x91396241, 0x5dce1c96, 0xb7687a89, 0xf7c073e4,
- 0x907b602f, 0x6ef890ef, 0x05d7a8bd, 0x0d5d8555, 0x1e282025, 0x958afc7f,
- 0x1fba406e, 0x101b6567, 0xbf4a0dff, 0x0d7c03aa, 0xa43faa8d, 0x17bf6d0d,
- 0xd7db1118, 0x4e03be2b, 0x99bfbf18, 0xf8c3d6f9, 0x197aec4b, 0xec3c97d6,
- 0xd798bd25, 0x7e472d1e, 0xea05d31d, 0xfbf0772a, 0x2767808b, 0xecf001c2,
- 0x97f4e3e4, 0xdfedfea3, 0xb9f5b12b, 0x77ef0e38, 0x165ceec9, 0xe70c4dcc,
- 0xfc4ecc73, 0xbc0b40b4, 0x267ee582, 0x02c62729, 0x83cc3d9a, 0xcaa968f4,
- 0x54394efb, 0xe9f7c69f, 0xf9ccf583, 0x00033233, 0x6618d657, 0xb3a557a2,
- 0x7af50731, 0x1cb84575, 0x25c3e2f9, 0x12c0acaf, 0x00ae9cf0, 0x2a388fbe,
- 0xea7ec75e, 0xa21636e6, 0xe870edc8, 0x7b1afe34, 0x7237d647, 0x1fa50f11,
- 0xd06fc02b, 0x1865306d, 0xff4595f2, 0xc60fbfc3, 0x989cba8a, 0x172a17ee,
- 0xe20a3f60, 0xf59fcb8d, 0x0f4207fd, 0xf8261e81, 0x957ecbbc, 0xb63c305f,
- 0xc17e7afe, 0x09500144, 0x13f0cbc1, 0x4552a2c6, 0x663dbd1c, 0xa561e977,
- 0xff3c3138, 0x7404f3d9, 0x001a7cd2, 0x7527c8b7, 0x1cb4356e, 0xa7753df0,
- 0xe075f23d, 0x5275ba93, 0xdb7501c8, 0xefbd173e, 0x11ebcb5d, 0xe9f5cab7,
- 0x0a83a846, 0x7f74706c, 0xb3e47afb, 0x8f5b329d, 0xf5858edd, 0x09ccf418,
- 0xc49b3b01, 0x174ae7d7, 0xdbadd6af, 0x5f7e1f7f, 0x2e60e5d5, 0xf76eafe8,
- 0x87af9ba2, 0x76c3a2fa, 0x36ea4d86, 0xa123ab35, 0xd7c438be, 0x0e32bea5,
- 0x4c97705f, 0xa79f4beb, 0xa076e33b, 0x2726c9cf, 0xd0f182f3, 0xb8ceeee2,
- 0x3aadf80d, 0xbf1cbdb4, 0xf92adeab, 0x7753ed10, 0x85943a6e, 0x9721faf3,
- 0xc92d9af3, 0x0fe06bcc, 0x29d13bfe, 0xef0ebe47, 0x193cc097, 0x7588bbf4,
- 0xac3ea394, 0xad14f4db, 0x4ebe0633, 0xce34e936, 0x10fe1c80, 0xeaef81c6,
- 0x387c925f, 0x0b1b7ac5, 0xeef63ca0, 0xa0d9cd76, 0xd59afce1, 0x6bce3742,
- 0x16ed8aa5, 0x72ede685, 0x75be1179, 0xafbc396a, 0xad4ebb5e, 0x9adf918c,
- 0x70cdc32d, 0x111fc9ad, 0x717d8f38, 0x6f0bec12, 0x1abd60e1, 0x45ea01f5,
- 0xaec6a425, 0xa9496f6b, 0x2d9adf44, 0xf89af332, 0xf83dd388, 0xedd68caf,
- 0x5f375ee0, 0x06dd05b7, 0xdba0aaf4, 0x51d05d69, 0x67892fe9, 0xe91b7c7f,
- 0x2074f000, 0x255ca09e, 0xc0dcf3e0, 0xdfe8154a, 0x2e3a67e3, 0xcbe217bb,
- 0xc79b3b0e, 0xcd39ac60, 0xac0afd9b, 0x7b2a1da3, 0xef99ed10, 0xd3fd86b6,
- 0x966dbd60, 0x8025b302, 0xaa05b65b, 0xce15baf8, 0x857f75c4, 0x946f6f58,
- 0x15af34bc, 0x809fc059, 0x25e98ef7, 0xc049641b, 0xcaf5869e, 0x4b9e3c1f,
- 0xfd43dcfd, 0xfe4fd0a8, 0xcbd1fb85, 0xd1fa98a7, 0x7e8cabcb, 0x493f5016,
- 0x474fd717, 0x786675f9, 0x7e8dabca, 0xcf1fa8ea, 0xff4bcdc5, 0x78660dc6,
- 0xfd4b51be, 0xb1f34ea4, 0xbaeb8680, 0xedd607e0, 0xb6bde197, 0xe3c27535,
- 0xca2f962c, 0xdcf1c61e, 0x7cb12520, 0xc9253291, 0xfea987c4, 0xf43aa661,
- 0x2cbad3a4, 0xe3df8ff4, 0x4754b924, 0x4a17a4aa, 0x9e093a47, 0xa46a4687,
- 0x2eba1e17, 0x87ae3970, 0x4bda3638, 0xab81a90f, 0x0d7c38f5, 0x132c4a70,
- 0x320fb04b, 0x695fbe87, 0x1b2878e7, 0x7df0b675, 0xd6c1bef8, 0xf50a985f,
- 0x3fe95b36, 0x959e3ce2, 0x24969db8, 0x976c46b3, 0xdef6e0e4, 0x0d92dcca,
- 0xb53c18c1, 0x4bfa068f, 0xdbb6fd83, 0x5fc89903, 0x0ebf4bcf, 0x18adbf22,
- 0xfc7d92ad, 0x22aff342, 0x2b8fd041, 0x22665747, 0xc82a1d3e, 0x2af8ec77,
- 0xe3445f8c, 0x7ff1c06f, 0x477c6098, 0xf8d314de, 0xd32a9cce, 0xc6154ef8,
- 0x26df7e07, 0x07c625bd, 0xd8c75dfc, 0xa1bfcd4b, 0x55391df1, 0xb44afe34,
- 0x4fc7634f, 0x27ff181a, 0x5bbb8c12, 0x90d2ebe2, 0x675de7f9, 0xb54e7f9e,
- 0x9f2afe79, 0xdfe95eff, 0x3449f8c4, 0xefcd7dff, 0x54e7f9f1, 0x783bf9f3,
- 0x7be303bf, 0x107ff006, 0xd1247fe7, 0x306ff3fc, 0xad4c7fcf, 0x3e0efe79,
- 0x0fa52ffe, 0x8d1af8c5, 0x13e6abff, 0x6a63fe7c, 0x11d57c69, 0xa91f21f0,
- 0xc91a92a3, 0xed06cf9e, 0x94748234, 0xdcb1ca9f, 0xf2976eee, 0x250f0f08,
- 0x3cfbbe71, 0x1b4df809, 0x042c77d4, 0xacfa0512, 0xcd7cf05e, 0x503552d6,
- 0xde83de24, 0x5d40285b, 0x5f1325d0, 0xd08ed5b3, 0x6f6f0065, 0xfac41c97,
- 0x0b5fd582, 0x71deb4c9, 0xb9cc007f, 0xc3ff3e08, 0xc7d6e3d3, 0x2e5acbce,
- 0x889fb0ec, 0xc388e49a, 0x63632c13, 0x6bbe011b, 0x67f09d25, 0x1e804fd4,
- 0x3f3fa065, 0xe58a3d00, 0x381fc287, 0xa9967a0e, 0x4cd372b1, 0x6f7741df,
- 0xeebcc116, 0x509ff010, 0x2c4fbe38, 0xff884295, 0x507a9fcf, 0xb0b4fd45,
- 0x3e901923, 0xa0834708, 0x476eff53, 0xf844bd68, 0xee7e22f4, 0xec645124,
- 0x5fbec277, 0xe9b866b4, 0xd42cb9bb, 0x1fed0996, 0xb46f3558, 0x67bff30e,
- 0x4c82638e, 0x947f9f7e, 0x8d98e48d, 0x318f81b2, 0xfb29f3a7, 0x39dca828,
- 0xefb26ec7, 0xeb980aef, 0xeb9954f7, 0xdd90f6bd, 0x62c6f686, 0x7e83ad89,
- 0xbf346def, 0xdbb1c637, 0x8c7b0986, 0x0647778f, 0x2c5ef787, 0x9d63e027,
- 0xce9f7ae8, 0x69e035bf, 0x22cec478, 0xd3465eb4, 0xc1678fd1, 0x02d7b274,
- 0x15b79f3a, 0x4eecfbde, 0x73c0057f, 0xe132c3df, 0x747f0ad3, 0x06dfb25f,
- 0xcd745c76, 0xe768ed1f, 0x8563e75a, 0xd665feff, 0xea2ae8f9, 0xeb4179fb,
- 0x5627ce73, 0x2ae86a7e, 0xa63c7e1d, 0xeff85d5d, 0xe18f1f87, 0xb32d9aaf,
- 0xa1c5f54c, 0x17ed4cbb, 0x7a6799ad, 0xb163b0bf, 0xed03fde9, 0xf3ea9a0f,
- 0xda9b0f82, 0xd9acbfdf, 0xc6defef4, 0xefef4cc7, 0x54ca7aa9, 0xacf02bbf,
- 0x739dfda9, 0x4bde99d6, 0x898f16fb, 0x8c0d5e92, 0xf2bb42c9, 0x7e43076d,
- 0x90ddf834, 0x329a8f87, 0xe4d93ca9, 0xe519b2a5, 0xb6dfe414, 0xeb0d979b,
- 0x63d18de7, 0xed0ff6ec, 0x4f28398d, 0xe2b7be56, 0xf0dfcad3, 0x75bc546f,
- 0xc16b28c8, 0xd73d475f, 0xe367d627, 0xf8648f79, 0x2e49cb07, 0xb72e556b,
- 0xcab23bb5, 0x55ae5fd0, 0x718d8523, 0x79018afc, 0x0f344b0e, 0x3a745686,
- 0xd5b80dd2, 0x137cd744, 0x65fb3d9c, 0x651ebf1a, 0xffdff417, 0xb2df1565,
- 0x1c883ea1, 0x1c75b9cc, 0xc87fe3c2, 0xa574f086, 0xd3dbfad3, 0x71f86334,
- 0x4157f105, 0x734d47e5, 0x14d13ca8, 0x5378f2a0, 0x341f9515, 0x6d195235,
- 0x7be5465a, 0xdf2a414d, 0xf2a76a6d, 0x541d4db7, 0x435a6b1e, 0x429a6fe5,
- 0xf936f654, 0x2bf01ca9, 0x26993d0c, 0xff614aec, 0xf5410ac3, 0x322e62d3,
- 0xf24dddfc, 0x7944cbe8, 0x5e7dad3c, 0xe9f37688, 0x72c60e63, 0xcacbe313,
- 0xcaf1090f, 0x545764fc, 0x4c394086, 0x95defa1c, 0xb2e4e9c4, 0xf40c19b1,
- 0xfd9763c6, 0x88bf37c0, 0x861b0aea, 0xb37c87df, 0x05fa71dc, 0x75e915df,
- 0x7f313a21, 0xa06cf17f, 0xfee789c7, 0xedfb04bd, 0xd70a75c1, 0xad3283cb,
- 0xc1b22c97, 0xc18af487, 0xfd3fad1b, 0xbe5e853b, 0xa54efe00, 0xceebf81b,
- 0xd8bb7f41, 0xa7ff53a6, 0x414c1d3b, 0x0e49ee3c, 0xf4eaa861, 0x5c1e0de1,
- 0xda6496ef, 0xf071e3f4, 0xe1759460, 0x5d8b5d5c, 0xf5ccba27, 0x0cd21dd3,
- 0xa6f2bf1e, 0xd67c86dc, 0x0bc7eba4, 0x5499fe90, 0xc92cfd1a, 0xe4e3f554,
- 0x3af8871f, 0xf89535b5, 0x6a36fc14, 0x470d1ff7, 0xe1067ea2, 0x87bf64e8,
- 0xc917c9ef, 0x337ef2ff, 0x7144fe53, 0xfec7b626, 0x0ee7ae39, 0xf91ceff8,
- 0x8dd50af7, 0x72c21b7e, 0x3e3571d0, 0x0f1a6adf, 0x3e1af3be, 0xf3bcb9f1,
- 0x4ec2abf1, 0xbdf9f8c4, 0x71f90638, 0xf7acdd2e, 0x86f54d53, 0xb4dd2cae,
- 0x201fe00e, 0x524aacf7, 0x056a5f90, 0x5a29f4f7, 0x1df004bb, 0x2e8979b1,
- 0x576f120d, 0x01aa8ce7, 0xcb4df22f, 0xb17bd71d, 0x2f1a8765, 0xe9b2716e,
- 0x125157b0, 0x9f235fc3, 0x8e22a87e, 0x8d1c3f9d, 0x368bd427, 0x67334f6e,
- 0x24fe83d0, 0x667a0ccb, 0x6d3409bb, 0x07e43f00, 0x753138c1, 0x21c59fa3,
- 0x75bc7f7b, 0xedc6c7b2, 0x05b8eb64, 0xf85174b2, 0xb47adfab, 0xc56de71c,
- 0xa7d77d63, 0x0be4806a, 0x883257fe, 0x47bf0347, 0x3205156c, 0xe5bd5ff4,
- 0x3f27b27d, 0x1f0b07b2, 0x1ade8f39, 0x7996bf0a, 0xde663922, 0xe38dd641,
- 0x5a7117cc, 0xdf3befe0, 0xe3f17581, 0xe30cecd7, 0xb42cecf0, 0x8303818a,
- 0x3fa8364c, 0x3bf36a20, 0xfb3e286b, 0x41db8db1, 0x0785580b, 0xd62ac29d,
- 0xe0768251, 0x819b6629, 0xdec53a78, 0xa18c4cf0, 0x25590cd3, 0x6ed03cfa,
- 0x7ec043b6, 0xad17d535, 0xd92bd731, 0x33d40cec, 0x2cedab95, 0x4cfcd124,
- 0x3ac8a7ef, 0x3588bbf5, 0xb9f5c0ae, 0xdfe3cec5, 0x8ca675f3, 0x5eeaf802,
- 0xe304be7e, 0xdcc8b7e2, 0x1be2308f, 0xf871878b, 0x54ebc3ab, 0x7dffbc3f,
- 0xae3bc4e7, 0x687df867, 0xc10fae05, 0x936f929d, 0xbf7e2877, 0x7856fc2c,
- 0x487bf58d, 0x51c0459c, 0x1b8a45b7, 0xf057bd37, 0x3f8fc1b7, 0xec36f312,
- 0x1eb197fa, 0xca37f763, 0x332aae22, 0x4a7ee919, 0x296d0677, 0xefe29ef4,
- 0x5f0e1dc1, 0xacefcc0b, 0xf22962ad, 0xc50fd817, 0x59dda62c, 0xf79e805b,
- 0xd257af48, 0xa11299be, 0x7b58107d, 0x357dd894, 0x8c53c939, 0x83376371,
- 0xf71f35f5, 0x241482d5, 0x9aaee158, 0x6e318ac9, 0xfa00fa0d, 0x7e53d27b,
- 0x4bba8258, 0x9fd864eb, 0x971cd323, 0xf5cd7977, 0xf703fc06, 0x8a32c67d,
- 0x558f251f, 0x308c782c, 0x9f6e1fd4, 0xe42fbe25, 0x1f13de11, 0xa1c5887b,
- 0xb9116a74, 0xe9461918, 0xf297f019, 0xf0e35fd0, 0xda007c53, 0xfb79d52f,
- 0x5f07117a, 0x88d976fa, 0x9789e761, 0x15819c35, 0xdd4c7868, 0x519fd388,
- 0x25e26858, 0xac2f55e8, 0xf57a31b6, 0x07e05b65, 0xa3d40f48, 0xe3049f08,
- 0x04f86204, 0x563d571c, 0xf85a0fce, 0x23866fe1, 0xfbf4998d, 0xe5e05b11,
- 0xcdfc7078, 0xe90e67fd, 0x687fe0ff, 0xfa4305ff, 0xfebc75ff, 0xb6de5eeb,
- 0x54fc082b, 0x3da7e3fd, 0x63ecccc0, 0x07c323a5, 0xd4ddaf74, 0xfcb941e6,
- 0x907a0948, 0x64871fae, 0xf2b3f7da, 0xe4315d81, 0x2549afd3, 0x47c43fc4,
- 0xe27c5f27, 0x3eb7b466, 0xc9d764df, 0x88e2dfbf, 0xeb298038, 0xf973173b,
- 0x9f78e2d8, 0x8a7e57d7, 0x65d0d9fc, 0x9bd517d6, 0xd2f0ce9f, 0xfe1415fa,
- 0x87fc846f, 0x287f8dfa, 0x81ac7b47, 0xb3de93f5, 0x9fe3877e, 0xc2f64619,
- 0xe865353c, 0xaebf637b, 0xa1a5e041, 0x654f89f3, 0xf9289612, 0x55f6d68b,
- 0x5cf80fc2, 0x9367fb16, 0x33e464d9, 0xc42c1f03, 0xe5f900fd, 0x8e318be7,
- 0x35f1b3d3, 0xcb14548f, 0x9def5c9f, 0xfdf03f0e, 0xcb137a9f, 0xc5e82f53,
- 0xb0db7b58, 0xc25dbcef, 0xcbc3d97f, 0x83c47b5a, 0x75dafd71, 0x1e105f76,
- 0xf0db6ed7, 0xae30e783, 0x77c3b6f2, 0xb35ff419, 0x5cdfd5ed, 0xed9af507,
- 0x7c99b4f6, 0x31949a1a, 0xf8069748, 0x4184d96f, 0xe4ff543a, 0x8e3bd555,
- 0xd8747f3f, 0xb66a3d20, 0xb8d957ef, 0x1a98f8a1, 0xb546afde, 0xbf097438,
- 0x867e8e5f, 0x2a17f2fc, 0x7de3fdd2, 0x1b911b12, 0x5eeb9f07, 0xf1197b25,
- 0x74147444, 0xa59ba01a, 0x05d0037d, 0x2741abf5, 0x4263fbeb, 0x6f3fb1de,
- 0x4bf3f111, 0x907dc53f, 0x387c3adf, 0xbe97aaff, 0x7c79c1e9, 0xbe7234a8,
- 0xc32dbe7e, 0xd956e30f, 0x953a1983, 0x0bd579fc, 0x5b7e22df, 0x195bf474,
- 0xfe60bf14, 0x0ad91b2c, 0xdf9c2cc1, 0xd3b7b5c2, 0x80592afc, 0x79eaaef8,
- 0xabd702b9, 0x633614cf, 0x78b91c7b, 0x87c5c844, 0x80f1c1eb, 0x0b887df9,
- 0xbc0bee07, 0x06de5321, 0x7c520f63, 0x7ec65be4, 0xf5425b0e, 0x4e9c9ccf,
- 0xefc315b3, 0x96279585, 0xecae375f, 0x1c9cfa46, 0x71811fed, 0x04a606df,
- 0x73a43e05, 0x747cafd0, 0x1f4e08fa, 0xc44a55e6, 0xa7efa077, 0xdf6c73e2,
- 0x8abbf76d, 0x73b1df4d, 0x2fe383b9, 0xdc03e315, 0x7ecf6849, 0x1f7f1198,
- 0xac62b37f, 0xc5576037, 0x7c8c57f0, 0xf8df7973, 0x436f9718, 0x66b343de,
- 0xbd3ffbe0, 0xbf07e5c9, 0xe0057b43, 0xf7a08c8a, 0x48936ffb, 0x2458381f,
- 0xb46f5c9e, 0xbf36b90b, 0xe004f837, 0x1ddd7056, 0x7fec17e0, 0xec9fe118,
- 0xf0d5cad8, 0x6cbe8c5d, 0x433cf1c0, 0x76e433fb, 0x87ff9091, 0xb3fcb314,
- 0x13ee5cb5, 0xc2411bfb, 0xf43dad4f, 0x5e50e783, 0x1f713e41, 0xbd9b76ba,
- 0xc9fde702, 0xb9bf83d6, 0x93e4e41b, 0x66a721b0, 0xd39569fd, 0xb0d71daa,
- 0x09fa7278, 0x93c413a6, 0x571e7853, 0xf128b54e, 0xfe957ff1, 0x82f7f034,
- 0x3e867f05, 0xab47844c, 0xf15ebc3e, 0xfaad3e12, 0xc9bdfe10, 0x9ff2864a,
- 0xbf0677c1, 0x6ea8ff55, 0x019dea0c, 0x6ef834be, 0xbe0d2f80, 0x342f121b,
- 0x3e886fe1, 0xf00cd8c3, 0x7feec549, 0x99fcc72d, 0x5f7c3dda, 0x843bbe14,
- 0x9f93c075, 0x871d61bb, 0xd6c5a546, 0xd87a9643, 0xa96fded2, 0x07da5857,
- 0x4b46f52c, 0x0bf710fb, 0x3caa0ebb, 0x6a62254f, 0x82ce5f6f, 0xef538c6e,
- 0xd21e2995, 0xc0af3007, 0xb9ada4bc, 0x6863cc21, 0x5338f173, 0x02baba7f,
- 0xde9f57f5, 0xb07b41ef, 0x73e3c5df, 0x9efd157d, 0xec3b18d4, 0xe9323dfd,
- 0xcd8868df, 0x822fe788, 0x8bf44187, 0x79ef44b2, 0xacba7ddc, 0xf8c32ce5,
- 0xc3ec874a, 0xe682cd90, 0xdfb83d3b, 0xff27b7df, 0x7cf03996, 0xb69911e1,
- 0xfed0faf3, 0xfb34414e, 0x3f18ac95, 0x7c1623ed, 0xa38c06e6, 0xdafee1ef,
- 0xbb165582, 0xbe22ad82, 0xaa96d4a8, 0xbfc117a8, 0x8fbcc0fa, 0x5abbf9c0,
- 0xd6b557f4, 0xdef8defc, 0x37abe3f0, 0x8407df9a, 0xf9167fdf, 0xf1d2ed1d,
- 0xbbf73c6c, 0x09378f19, 0x2e5d3afd, 0xe00e65ba, 0xccb0efbf, 0xef4e5f90,
- 0xa7ff0991, 0x737df2b7, 0x8b5f9f8a, 0x7a4fda7c, 0x0f53c0cd, 0x589a85ca,
- 0xfcecf4ef, 0xd023c95d, 0x3bd776a4, 0x6504ffc5, 0x0bb7aecf, 0x97f5867f,
- 0x8779cadf, 0x753f6d0d, 0x2bf68b9f, 0x69b9f6fa, 0xef6fb17f, 0xc11e732f,
- 0x8f876efa, 0xfdf6fef2, 0xa7f918b9, 0x0aa3b96f, 0x68df56f5, 0xecb667ee,
- 0x947173fd, 0xa256c9d6, 0xee76e5db, 0xf3de9ee7, 0x6949efef, 0x70acc258,
- 0x4c97dffd, 0x9f86b771, 0xd65e28ba, 0x25cff7b7, 0xa5fbf6b1, 0xec5ea7ce,
- 0xd9b9f623, 0x5f081d9c, 0x697fdf2a, 0x1bb5d9f8, 0xa20f319a, 0x00fabf73,
- 0xcffa9fbc, 0x3ea3145f, 0xedc1dbec, 0xf47b5e9a, 0x9b27dc05, 0xb962b6d0,
- 0x8bd5e81d, 0x64fb8142, 0x0b2f3f6d, 0xf2f0f16a, 0x2f01c505, 0x8f7f1f16,
- 0x9fff48f8, 0xf6890f80, 0xb8f76bbf, 0xe7094e43, 0xdef797fd, 0xcfb03d41,
- 0xcc697c41, 0x337093f7, 0x9a171dd9, 0x6e57d577, 0x62e452de, 0xbff2bde6,
- 0xedbbff39, 0x2acf825e, 0x7cf94307, 0xdf5443ef, 0xbc11f6e6, 0x9befc917,
- 0xdf746abf, 0x5cf77401, 0xfe87de78, 0xc8fdd2c7, 0x3aee827d, 0xfc3499e6,
- 0xdf0417f3, 0x2773d597, 0x3dd39bfe, 0xfb0dfcd1, 0xaf9b71fc, 0x6ce30f23,
- 0x3ac3fd68, 0xb767b9ad, 0xf1efd863, 0xb475b3b1, 0x2fb16517, 0x846f8569,
- 0x191ffdca, 0x5e3127f7, 0x3c899a37, 0xd10fee6d, 0xad0c1d96, 0x8f649568,
- 0x6e0ada2a, 0x6ebe2b27, 0xf1e5e03f, 0x28fbe72b, 0x384d8787, 0xf67ac016,
- 0x438a3e0d, 0x56c2fc5b, 0xb025f989, 0x6f2b9553, 0x8a7e8c3c, 0xe22dac7d,
- 0x7df2a628, 0xf88a572c, 0x4d575da2, 0x64568bfe, 0xe6bcbbae, 0xe7f443ba,
- 0x677e1c64, 0x9c610b26, 0x80e2be59, 0xf265f98e, 0x50498578, 0x208eb177,
- 0x4c8e09fa, 0xc47ff7f3, 0xb898d364, 0x11ebda2c, 0xbe7fd7b0, 0x07c50375,
- 0xfef8bd4e, 0xcd6fd8cd, 0x04e664cf, 0x756ef4bc, 0x8df208b3, 0xffd15212,
- 0xfd94eea8, 0x523c8f3c, 0x3ecc6b72, 0xd62761a0, 0x704dd8fc, 0x8470ef55,
- 0xd5f7c266, 0x4c5f7ebb, 0x7ef2f6eb, 0x2f8363b2, 0x3d4f3c4a, 0x7dc62d18,
- 0x0e716abe, 0xf1a74ac0, 0xf77f8f2a, 0x839e4eec, 0x85b4bafe, 0x875649e7,
- 0x623bb4ef, 0xaac64bf2, 0xf11da376, 0x1287f051, 0x7c20a9e5, 0x8679f9b1,
- 0x43f3da9d, 0x65d7c389, 0x65be610f, 0xbded96f5, 0x3ea87718, 0xd9a1f0e6,
- 0x53e5b0d7, 0xfd4f6b8a, 0x944f36f1, 0xe4d92cfc, 0xf7f10e77, 0xd744c8b6,
- 0xb23acefa, 0xf44ea15b, 0x8fc70fad, 0x2fc85c7b, 0xdef1f9a9, 0x6140415d,
- 0x7b364fcd, 0xb271ae30, 0xfc87937b, 0x8fe72dbe, 0xeff10cb7, 0xd79d8fc2,
- 0x7f893bbf, 0xb774fd80, 0xb78ff16a, 0x15fb270c, 0xb7892be0, 0x4df065df,
- 0x5ecfb6cd, 0xcf63f8c0, 0x405e4f8e, 0xfaff6b78, 0xfed017c7, 0x3a5cfb64,
- 0xbc3443ee, 0xbf14aff8, 0x2a5bbe31, 0x87f7aee4, 0xd5ee299b, 0xf6357e0b,
- 0xc3f7bbd6, 0x7a3ff41c, 0x0325ffb7, 0x7ba5e4fd, 0xf9c08fa7, 0x7539dd2e,
- 0xbf238b04, 0x1b7c8946, 0x9bb888ba, 0x3b075e95, 0x7c9d920f, 0x7e8de80a,
- 0x1ebf80ca, 0x0ff1e3ae, 0xb7d3f0af, 0x0e6f8fc6, 0x6f3bcbf1, 0x936be5bd,
- 0x50fbb4b0, 0x3fd05c0d, 0x78e8137f, 0x6fd045f5, 0x5fc263eb, 0x53bf4f89,
- 0xe9d007f8, 0x57f0aabb, 0xeb3efd04, 0xe7fdf85c, 0xf0e75df0, 0xe479fe84,
- 0xc466f022, 0xfd57ef4f, 0x3728abcf, 0xf1447e3b, 0x4cdba410, 0xb6ef6898,
- 0xee3072cf, 0xffbd91fc, 0xef579e3e, 0xad1fd1d0, 0xc916fbde, 0xa3ceef4f,
- 0x22649f14, 0x06cbd98e, 0x93b8f1fe, 0xd86b85c8, 0xbd7ee6e8, 0xfdfa3fc0,
- 0x173d0f5e, 0x63e73dfe, 0xe44fefc3, 0xf2a9bfef, 0xae23023c, 0x1df1b75b,
- 0xd20f3fe1, 0x74829a4b, 0x71bcff7a, 0x3a0f0368, 0x6c7261e2, 0x5c7e2afc,
- 0x29ce2065, 0xadc465e8, 0x5053e206, 0x4578c6cf, 0xc58b7a48, 0xebbd07d1,
- 0xd7abdc78, 0x199fce6e, 0x678f0fa4, 0xa72adafd, 0x638b8ba1, 0x2ffe085d,
- 0xea889f8b, 0x0c73c535, 0x8d9cf53c, 0xab4fc7af, 0x37fa9e3c, 0x902c87ef,
- 0x9f21fbac, 0x75d63f22, 0xf3f2afbe, 0xcbbcfc04, 0xc8b7bec0, 0x5179ebf7,
- 0x8ac878a6, 0xe3d241f0, 0xec617d56, 0x55e15997, 0xd54f5c1c, 0xa275f177,
- 0xa43b8767, 0x073d3f41, 0xd73f1376, 0x455f7d6f, 0x96d0f33f, 0x9edca89f,
- 0xeb83f2e2, 0xfe062844, 0x17f6979e, 0xcf1d78f3, 0x338eb63f, 0xd2f1c1cc,
- 0x38fe27b0, 0x353f5b0d, 0x0c13538d, 0xf37f3cab, 0x549de3fc, 0x7f6277fc,
- 0x0cedbb27, 0x864ef3f3, 0xf6f119e5, 0xeb133f67, 0x035e71a6, 0xb3ca4bd7,
- 0x33cfca3e, 0x89237a4c, 0x1e9798f2, 0x9e0ef19d, 0xe20a5b8b, 0x6760f68c,
- 0xced3e733, 0x428ff07f, 0xbd1e777a, 0x6a75c65b, 0xc637e217, 0xb3792c2e,
- 0xf41baa71, 0x15bbc942, 0xad5d9093, 0x31f266fa, 0x187e099b, 0x03ae0467,
- 0x9e0fd0ad, 0x27fcc02f, 0x94f64784, 0x647840cf, 0xe2bba6dd, 0xb5da95e4,
- 0x36f3ca0a, 0xe6ebb5fa, 0x76766e3c, 0xe9fb17a2, 0x0bc8c2bd, 0x3c4148aa,
- 0x3b7dd67d, 0x29159d2f, 0x99d679fa, 0xecbe848f, 0xef01f269, 0x581673f3,
- 0xbdf9106f, 0xd20e7b55, 0xb0aaa2b9, 0xaf80bcc4, 0xe483acc5, 0xaa4766e6,
- 0xdb335bc8, 0xfe7bd50f, 0x7757da85, 0x2c35f6f2, 0x3cf1ed4c, 0x1f24c446,
- 0x07762d13, 0x913eefe7, 0xa67b51d7, 0xf6624584, 0x7c13ef71, 0x9ba4d3db,
- 0xc22d7bf4, 0xa939e1a7, 0x2ea71a6e, 0x8e34dc3c, 0xcceeaed1, 0x93122c75,
- 0x74a7547f, 0x9dd5bf13, 0x671a3bf9, 0x329abe40, 0xfb890f09, 0x7b82651f,
- 0x2629ffb0, 0xbffb0778, 0xe6b5c681, 0xe6ce6677, 0x5bacc271, 0xce341979,
- 0x852654bd, 0xb76f005a, 0x0e25816b, 0x5ee99f68, 0xc32afb9d, 0x285356f3,
- 0x8761fa3f, 0x8cde50a4, 0x4a759f38, 0x583682d7, 0xd6d39f6f, 0xa303753f,
- 0x707f813c, 0x2793135c, 0x3e7422c0, 0xe43768d3, 0x208f25bd, 0x15013f1b,
- 0xf2f80b28, 0x68c11e45, 0xb4f3a516, 0x3cfcdd6b, 0xcd2d18e0, 0x106fdf86,
- 0xde71be76, 0x40f9c86f, 0x0bc0b9cb, 0x9b4c079d, 0x18e0fa5a, 0x396f631f,
- 0x798a9d3e, 0x967769e2, 0x83a51f6e, 0xa652c1df, 0xe9737d51, 0x97a82cf8,
- 0xf5e16fb5, 0xcf8e975f, 0xab957a81, 0x246bd793, 0xb35fabca, 0x60b4c172,
- 0xe5e825d1, 0x252300db, 0x11bcbd26, 0xe2aa71e9, 0x7a163bdd, 0x5fa14f31,
- 0x1565f8e5, 0x14f46ed8, 0xed6cb78e, 0xa788eddd, 0x3368b631, 0xefef93ea,
- 0xea2a73fd, 0x09d32f71, 0xd56b3a3f, 0x68f07e91, 0xe4f3b9ca, 0xc2f359c3,
- 0xa5d9fe0c, 0x1c227605, 0xd2c7f36d, 0xaae7bc39, 0x1fd13826, 0x6cf2235c,
- 0x0fc81d9e, 0x7ef1e7e4, 0x75fbe0ee, 0xeb0f2299, 0x29b9a3f4, 0x0fa3cec3,
- 0x5dbb321a, 0x7d5c0c4a, 0xb3ed3f4a, 0xff7d9df7, 0xc49bcc3e, 0x759c6a7a,
- 0x37fbf065, 0x93c90a5d, 0xe981ff39, 0x0b5fc469, 0xde217f04, 0xf879319c,
- 0xcaa0e48b, 0x8874c3cf, 0x8e9a6ef5, 0xb58297f3, 0xbeabb9f2, 0x68169e3c,
- 0xcf90f781, 0xbc8871df, 0x34be711b, 0x7be33ce6, 0x79eb4788, 0x8a8e8dc6,
- 0x55977e28, 0xe5072679, 0xa27ce06d, 0xf48591d4, 0x64779eb3, 0x9e2dbf4a,
- 0x9c5eb11f, 0xf7044c77, 0x3e819d8f, 0x9fef3f1c, 0x830e3bbd, 0x40bd5fdc,
- 0xe7ca61f5, 0xa526cbd5, 0x215cfc2b, 0x820d05d9, 0x5c6d32af, 0x1887b03f,
- 0x39f6d3ed, 0xebfa3f24, 0xc9d4df7d, 0x305ec80e, 0xbee6fc93, 0xe630dce4,
- 0xc23df513, 0xfd8297cf, 0x8f7ca120, 0x711293de, 0x3f3e4879, 0xe7e7c8b7,
- 0x3cc97b66, 0x6f39df6e, 0xd3fa9457, 0xc8607f45, 0x0f9e0c67, 0xfaf993ee,
- 0x25e4d7de, 0xe0b34638, 0x2f13b47e, 0xd38f3c76, 0xf017fe7c, 0xf0633baf,
- 0x811c740f, 0x426734f5, 0xc6708e3a, 0x1cf5a3a1, 0x204711ea, 0x587ddb1b,
- 0x86056879, 0x4fe7ac5e, 0x42cc1299, 0xdbe9593c, 0x6b3c74a0, 0xec662987,
- 0x16ec94f9, 0x2f577e83, 0xc32ba5f3, 0x8b1cf44d, 0xe7bd5e70, 0x6dc21b53,
- 0x527bf1d0, 0x8277bb7c, 0xd667af93, 0x44e632f1, 0xed38816d, 0x5095978b,
- 0x499f807f, 0x8f5cfc16, 0x14e29af3, 0xfc50c2eb, 0x2fed8f5c, 0x8bfe3f02,
- 0xc7e18fc1, 0xae3908d5, 0xa0277dc1, 0xb3bc1ff3, 0xdc60f233, 0x3e235972,
- 0xa649bc5d, 0x9fb42db8, 0x28319599, 0x6daf8bf7, 0x7e076fdc, 0x44bcfc59,
- 0x9c40b4fc, 0x9c44ff2f, 0xefe6b13f, 0x9209ce55, 0x1e70bd9e, 0x46f4885f,
- 0xf3f316cd, 0x7fc29dbb, 0xca1cb374, 0x47f715cb, 0xad7f82c8, 0x09ad3ff8,
- 0x6a905eb9, 0xc7a5676a, 0x299b46e8, 0xea6b3c0f, 0xd7e43f40, 0x6fbcda67,
- 0x17edfc51, 0x20f18676, 0x293692bf, 0x2498f882, 0x4b7ec34d, 0xfd197c85,
- 0xb666598d, 0xe68372eb, 0xedf979f3, 0x9779f3e6, 0xb5348c75, 0x9e4d7cbf,
- 0xa115fde9, 0xafef4d2b, 0x54c132da, 0xcebe171f, 0xaeeafed4, 0x7c7d5332,
- 0xfb5346e4, 0x9b678789, 0xdf74d7ea, 0xf93f6a6d, 0xfbd37cd8, 0xa6d5a36b,
- 0xb47fd7f7, 0x5aff54c4, 0xb531ffff, 0xfae42c8f, 0x665340eb, 0x7c98f1f6,
- 0xaa0f03e3, 0x3f9f1d36, 0x8bd36858, 0xf8679f63, 0x9658c5bd, 0x4e9fd1f8,
- 0x3aa767a4, 0xd763b2b3, 0x376652f7, 0x4ea99fe9, 0xf0643d73, 0x0bf00e4b,
- 0x45937f10, 0x6dbc80ef, 0xd5193941, 0x983b4378, 0xe2e46ca1, 0xa7941482,
- 0xc5f9f1a7, 0x9236d9c9, 0x9d08fab3, 0x0e738f8b, 0x17356dfe, 0xf7482ef9,
- 0x2e1980a1, 0xa33100ca, 0x9606e60c, 0x29060b0a, 0x28f99cd9, 0xeebad2ef,
- 0x15bdeb1b, 0xdc9c071f, 0x6178701e, 0xdfd9379d, 0x645fee21, 0x3129731e,
- 0xa8f590f8, 0x1ef0eea9, 0xd77fe2d6, 0xeb2e7a6d, 0x69754cc7, 0xffca4cd1,
- 0x3d970449, 0x1b4dfe73, 0xb3d9bf41, 0xcf1a5402, 0xe2d8e6db, 0x9d45f7e6,
- 0x9de79717, 0xf10bbed0, 0xfb18a5fc, 0x39748a2e, 0x33c6f695, 0x3f56af98,
- 0xeffc9fb7, 0x3f59872c, 0x237dd60c, 0x97963e78, 0xf9d4279f, 0xda9b6b9f,
- 0xdf75c26f, 0xb7c2e798, 0x7e606767, 0x7f027642, 0xe7c5c73c, 0xd55342f1,
- 0x8cf00b4d, 0x2589da09, 0x73b2e783, 0x68e50d22, 0xf9118d7f, 0xe2d8cfd4,
- 0x759d3de7, 0x047b7f72, 0x13b4682a, 0xcb3f7e34, 0x3d77caa9, 0x2455b298,
- 0x7f22ce07, 0xbbbabfce, 0xf65f9f84, 0x7c3cf265, 0xf437e09d, 0xf1568e5c,
- 0x1cadea0c, 0xb9bcd730, 0x3119e143, 0x2e4662b7, 0x661d6fbc, 0xef5469f3,
- 0xf05ce897, 0x870d8ca3, 0x957fadf6, 0x03d6be09, 0x905e52d7, 0xda1805aa,
- 0x993cc6e1, 0xf63037c8, 0xbb4b3e11, 0xd6d4fc8d, 0x05ce072b, 0xb55bf231,
- 0xf7ec6e8a, 0x0858bc33, 0x932d69c6, 0xb473ef4c, 0x010f078e, 0xc99d951c,
- 0xd6549714, 0x967e4cdc, 0x69e1c99a, 0xd962417d, 0xe3c3c112, 0x0f8e1ee6,
- 0x42ea83c0, 0x3f73fb3a, 0x869319b7, 0x2a2975f7, 0x9d1ceb9d, 0x8d719e20,
- 0x5b7ebf01, 0x9709d906, 0x5795e19b, 0x21e0fd3f, 0x89d903cc, 0xfde11637,
- 0x3d04cb22, 0x4b6df3cd, 0x5dcb7d9b, 0x4de5aed0, 0xb800c999, 0x30d8ca37,
- 0x0a1c879a, 0x41b7c1c5, 0x1afb802f, 0x535e5b84, 0x15ccf34e, 0x74045e74,
- 0xd32575c6, 0xe8833156, 0x3863619e, 0x37fc2b4f, 0x7fdcb8b8, 0x790ba5cd,
- 0xe369bcad, 0x90172c70, 0x9b5e81bc, 0xba97fd86, 0xd311da12, 0xdbf4715c,
- 0xa8ffee85, 0x087dd39d, 0x136fd94b, 0x61636d76, 0xfa0cbdac, 0xd7ec16f0,
- 0x8f29cba8, 0x17bf6316, 0x141bbbb2, 0xee617b5f, 0xb432ed85, 0x0cff90c7,
- 0x39e60c7b, 0xcfbbc70f, 0x31ebd665, 0xeb9e7c7a, 0x4ac9ece2, 0xdde1f76c,
- 0x12f6b891, 0x1bb271e8, 0xfaf8d5d3, 0x1e82fbee, 0x28caba0d, 0x3ec1302f,
- 0x5c5d77d1, 0x4ff3adae, 0xc85ddeb4, 0x611bc8ef, 0x14ec07ee, 0xa5583ff2,
- 0xa756fb4a, 0x58f75d1f, 0x68fbe621, 0x9bc79479, 0xcb519fa8, 0x0f3f20de,
- 0xe204f9f0, 0xbb5fc0c1, 0xc69e7f85, 0xc5d6f1f7, 0xcda7c05a, 0xd70ecf84,
- 0x7f9fd845, 0xf328b9fb, 0x815e9e79, 0x0ffbd077, 0xf5b83e92, 0xb38c12bd,
- 0x39fedfd4, 0x79bffde9, 0xb8e6399c, 0x802f1181, 0x9c716a71, 0x2aff5bde,
- 0x8a51bae2, 0xbcecb647, 0xab07ee9c, 0x49f4332b, 0x45ce93a3, 0x7d11e766,
- 0xf872ed4e, 0xc353ce11, 0xd4ec5c78, 0x3087c9ae, 0xd349f32e, 0x73d8bce1,
- 0x3a5ea759, 0xfe87625a, 0x5a38ed4e, 0x0f5e90a2, 0xf78cde11, 0xa5fee775,
- 0xe377fd04, 0xdf00c1fc, 0x4bafe339, 0xf9fc16bf, 0xf180f165, 0x525fda78,
- 0xcf68b3d8, 0xd6a5e00d, 0x2a7ff79c, 0xc412bdf9, 0x13ffe603, 0x463c045e,
- 0x8bb57bbc, 0xa45a9fc7, 0xc6e31060, 0x54f7522d, 0xff06d38c, 0x4073a317,
- 0x9256b799, 0xcc3dfe99, 0xd61abc03, 0xb7db0ca1, 0x3e667db1, 0x750b9b1b,
- 0x111d2bc7, 0x1dd49f7c, 0xed42bca6, 0x4b047758, 0x8fdfb44f, 0x47fa86db,
- 0x6f2c7efa, 0x86ff02d7, 0x0feb0fe3, 0xfdf2815e, 0x3313058f, 0x4ca12631,
- 0x62f61df5, 0x852ce21e, 0x7d3a6dee, 0x2275a658, 0x3d739663, 0xa8ceff3f,
- 0x5eedccfe, 0x9392375a, 0x81e9f38c, 0x15575c5c, 0xf611fa56, 0xf815d5bb,
- 0xc33ff904, 0x08785dd6, 0xfb1d73be, 0x79e60e6d, 0xeda2f71b, 0x8fd8ad2a,
- 0xbbfdc6fb, 0x367aef25, 0x9c9f6e34, 0x28dfe5c4, 0xbe3527bf, 0xc961f98d,
- 0x63a7db8f, 0xae7bebbc, 0x0547ba46, 0x999df9fe, 0x702b9fd0, 0x71854b0f,
- 0xc66da924, 0x876ea0d7, 0x7bf1e3f7, 0xd02b5b5b, 0x606a5761, 0xbbde0d94,
- 0x87ad73a5, 0x8dfc3df1, 0x49c965f9, 0x9ef15ae7, 0xe7493538, 0xb902d0f3,
- 0xba818748, 0x4c77750e, 0x2ba969dd, 0xabcc6ebc, 0x285fe0ee, 0x0f7eb3ef,
- 0xef07d7bf, 0x337dc333, 0xe50cb7bc, 0xe849353f, 0xb1698d09, 0xdacea1e7,
- 0x3c49e902, 0xe5c8593e, 0x265f88c4, 0x97e22f78, 0xe291ac85, 0x60f1236b,
- 0x5bda3e75, 0xb0e654dd, 0xf88d2a7e, 0x51f31e5b, 0xa82ac059, 0xa83acb1c,
- 0xa98592bc, 0x54dd622c, 0x2a7eb316, 0xb1974c7d, 0x547cc09c, 0x8f1ad9a6,
- 0xf97d474e, 0xcbe93b0b, 0x1e0f2dc2, 0x0508c918, 0x6aa5ba26, 0x69867e5c,
- 0x2864a1a5, 0x80388b57, 0x16a9ae71, 0x3545e669, 0xd07d90a0, 0x93ea6423,
- 0xee20b635, 0x2ab9b29f, 0xe715af3d, 0x3edf6b80, 0x27e47640, 0xaa79f8fe,
- 0x4b949353, 0xeb3287dc, 0x1ab586c7, 0x73e41be1, 0x1ebbe22a, 0xcdba82e1,
- 0x1ee74dd9, 0xdfc3cbed, 0x745f7196, 0x45f69d9b, 0xa026506b, 0x0c2ee35e,
- 0xa7984b35, 0x9f6a515b, 0xf24d7c44, 0xce1a9353, 0x9e0da098, 0x78fac407,
- 0xebdf906d, 0xc1ca9ebb, 0xf78ff67d, 0xf9eb4dbf, 0x34b9c9f5, 0xa3ceba9f,
- 0xfb4dc06a, 0xcdca2a76, 0xf603e9c7, 0x6d8dd937, 0x9e0a5f2e, 0x25ffe93b,
- 0xc0ca8fbf, 0x7e95f7df, 0xc7beec57, 0x745026e1, 0x37af632a, 0xabf95265,
- 0xbf952f26, 0x1f99d268, 0xf623b91c, 0xe11136a8, 0x11d02f4d, 0xf0f44fde,
- 0x612663eb, 0x179e7b1e, 0x7692d3e7, 0xd444d57c, 0x77d93e3f, 0x77638c19,
- 0xf7849f2f, 0xce64b627, 0x95947ca6, 0x1fe704da, 0xc5169e00, 0x71874ce7,
- 0x6876d35f, 0xd3794197, 0xb89d9317, 0xd696bfae, 0xdf7179a9, 0x3aedfc64,
- 0x7f4103ee, 0xfea56fab, 0x09bfa2ec, 0x18ff6c4e, 0xf60da3f6, 0x6fd45fb3,
- 0xc348ef72, 0x189a87f7, 0x7a537dc1, 0xf7f61a67, 0xaf85a2f3, 0xdf84984f,
- 0xbbdee2db, 0x3499d374, 0x67bb07e6, 0xe61c99e6, 0x737af587, 0x2895e359,
- 0x9a4ddfff, 0xf904e6d6, 0xab1b7257, 0x4dac5f51, 0x09cdb9ba, 0x3653efc6,
- 0xf54e93a0, 0x0015dae9, 0x1fae34c7, 0xbc36f200, 0x659ed06f, 0xfc3af8a3,
- 0x8e5eeba3, 0x8eb8fea0, 0x2d969fbf, 0xfda010f2, 0x9f9fc7cc, 0xad57768e,
- 0xe962f9c4, 0xd3ee8ced, 0x544f6448, 0xf3a2499d, 0x7afd4679, 0xf31104ba,
- 0x8fb483d8, 0x43c67552, 0xbe2efae7, 0x1ce9a73f, 0x34fed0e0, 0x95f0ef1a,
- 0x29f93f06, 0xbb74b36e, 0xf970cfc8, 0xefbb6047, 0x83f98dd9, 0x7c44edbd,
- 0x0a83d40d, 0xaa23dbe8, 0x6df9ff31, 0x6e7f40d3, 0xb3df0756, 0x658f9829,
- 0xf47e67bc, 0x89248f87, 0x7e3ab07a, 0xfb4b24fb, 0x4dfea33c, 0xe7856f6a,
- 0xbac1ae7b, 0x5f2bda13, 0x08ea0638, 0x4b3653df, 0xf18cc37f, 0x6afea11f,
- 0xbed16572, 0x12bf55f5, 0xaae0ef43, 0x667bd2f3, 0xad6dd3d2, 0x9011fdf0,
- 0x6ebf5a73, 0xa17eb467, 0xf462f9dc, 0x6eb14ce0, 0xd2b99d55, 0x3a418f44,
- 0xfee89b14, 0xec65c821, 0xada2eb3e, 0x2173a4df, 0xbcbc9333, 0xe7e4161f,
- 0x9be6d69c, 0x3fff57f6, 0x1c2b7f1c, 0x4c7004fe, 0x63862ffb, 0x41bc69ac,
- 0xf04c8a38, 0x51c3e7fd, 0xf28e0096, 0x561c14af, 0xc728c57b, 0xf642bda0,
- 0xb0f38f2a, 0xb7b236e5, 0x151552fb, 0x369897f3, 0x5204ec85, 0x8eea5e19,
- 0xf146f1f6, 0x8f7799ae, 0xf3b61e63, 0x995dac2a, 0xe82afa80, 0xed7dc3cc,
- 0xe07ef16f, 0x740561f9, 0x2754e8d0, 0x177b47ed, 0xfc60d454, 0xb2a73bdf,
- 0xf1bd4a8e, 0x33ffbc16, 0x3c7fa0a7, 0xb4eb77da, 0x98db17b4, 0x6905ef49,
- 0x241e97dd, 0x13ee76bb, 0x2c94dadb, 0xcf8d9bd4, 0x052c1da2, 0xce1db5b7,
- 0xeb9ef78a, 0x5f927bad, 0x542975a2, 0x3f44aec6, 0x850ae428, 0xda3d200f,
- 0x23d21f34, 0x7b5089f7, 0xc795d41e, 0x8066be6c, 0x6d0d4957, 0x2bf00f59,
- 0x9afa164f, 0xf5087de1, 0x527fb61f, 0xab3de109, 0xd9bc9a2b, 0x8b49bf78,
- 0xb7d68fb0, 0xdf31d4ce, 0xb30a9ed8, 0xb0ae5204, 0xf685de37, 0xd7e49afa,
- 0xe2d79cdb, 0x1f6be07a, 0x267af3ae, 0x8f39b5c0, 0xc55339e5, 0x437f587b,
- 0x1ea46ccd, 0x7f4af753, 0x5fbcf995, 0x80dff36f, 0x6a92fceb, 0x157fbfc6,
- 0x879b95e3, 0xefe17819, 0x5c7531bd, 0xc1e6944f, 0xf79834fa, 0xbeb9e786,
- 0x47fa147f, 0x13e61f7b, 0x1c6e3b24, 0x8c324f9f, 0x2710f78d, 0xf5a3cf8f,
- 0x8beb0435, 0x578fdf07, 0xb1963ce8, 0x671ce3bf, 0x6c1dfda3, 0xdce4f58f,
- 0x73ffda3c, 0x08be62ce, 0x6966ede6, 0xf150bf7c, 0x38fcc34f, 0xf8bf00f7,
- 0x8aa8de29, 0x926d0ffd, 0xa93fff79, 0x39b4bbf5, 0x7e64549e, 0xd7302cee,
- 0x1f37cc1d, 0xb66a9683, 0x592879f9, 0xb387efc4, 0xe457e891, 0x6c3682db,
- 0x510b0577, 0x908b1579, 0x458e3f5d, 0x86357ea9, 0x38f1f33e, 0x700e9794,
- 0x997e644d, 0x642b47c7, 0x68163bf4, 0xbf68cd81, 0xfe164c6f, 0x6fde48ca,
- 0x77c1454b, 0xbe297ba6, 0xc5e519b1, 0x559eafa8, 0x448df14e, 0x3c69a5f2,
- 0xdee2388e, 0xfbdef382, 0x8f8cf539, 0x3ce46379, 0xbb79e35d, 0xba31b70d,
- 0x0f61a28f, 0xf78ca3f7, 0x7ef324af, 0x2fc4121b, 0xc15fae41, 0x459f7c79,
- 0x74b9edcb, 0xd3dfc9cf, 0xda8fb03d, 0x17548218, 0x6dfb9b79, 0x513b7b16,
- 0x92cfd91e, 0x80f2fe79, 0x18fc235f, 0xce9035f2, 0xe0597fc2, 0xbe6ee832,
- 0xc7b8c1cf, 0x4dc84fa1, 0xc44aa55f, 0x09834068, 0x05b7e9ea, 0x4a801ee8,
- 0x35ca9f31, 0x1fe819a5, 0x177fd82c, 0xf570b9c1, 0x0e30352c, 0x23cdc9cf,
- 0x5d7818bc, 0xfe0ff160, 0xbcf131d8, 0x9ec332f1, 0xc303fc36, 0x09fab01f,
- 0x71bfbe89, 0x43a27eec, 0xed296679, 0x7b237edb, 0xc0eb0d96, 0x4fbc7e6d,
- 0x78af38ca, 0x9feecec4, 0x6439445d, 0xb3f9f033, 0x550f7e2e, 0x7543dc48,
- 0x0c3f9bd8, 0xff919bbf, 0xbe5815c5, 0xa86b0ce6, 0x7b3b5fb7, 0x1ff266f4,
- 0x7986b094, 0xee14a717, 0xc67519ff, 0xbf14c8ce, 0xc9bf7817, 0x8fdd06fd,
- 0xefee5370, 0x9d78bce8, 0x573a0dfb, 0x4ed3aa7e, 0xb9377279, 0xf7b169c2,
- 0xbb94dc67, 0xf87ced37, 0x2387fc31, 0x79c3de02, 0x6804e49f, 0xe19f915c,
- 0x4b9d20df, 0x35bdfc4e, 0x471ae33f, 0x61f23759, 0x5dd7e0b7, 0x8345205a,
- 0x21766db2, 0xacda4fc9, 0xbfde4e49, 0x94247f39, 0xc57c44cc, 0xff0647cc,
- 0x5905ef59, 0xe873f12a, 0x386ae089, 0xafad3363, 0xa884f783, 0x8af6beb4,
- 0x26774378, 0x907afa7b, 0xd1ac5997, 0xe26ffb4e, 0xc916957e, 0x313d476b,
- 0xdfb96fcb, 0x5551e447, 0x2df0f588, 0x6a051f91, 0xe63f55f1, 0x7d3f3175,
- 0x63ee2dd7, 0x8f602c61, 0xfd023f97, 0xaddaf49a, 0xdbf5cc33, 0xeb75cc2b,
- 0x1e46863d, 0x7a4d2bcc, 0x5d3dec76, 0x87e812d3, 0xa5db351b, 0xcd1a0fc5,
- 0xae2303f1, 0xc3f98757, 0xe3c2cfb4, 0x7c9dd37a, 0x8b88b2fc, 0x341a2ff6,
- 0xb8861d75, 0x3de19f51, 0xae35d3f6, 0x845e306f, 0x574d04f7, 0x436dfb8c,
- 0xef939f22, 0x6457a47b, 0x7dfdfb8a, 0x54af7499, 0x1ce99257, 0x386711ab,
- 0x494de05d, 0x3b7f0f3d, 0xad70d8d6, 0x54afa818, 0x07c89d1a, 0x5e79b32b,
- 0x871f20d5, 0xc754f14c, 0xfdee351a, 0x80fd0372, 0xe273c15e, 0xdb6fb12e,
- 0xd8f5f8ae, 0x5ec38478, 0xda7f23a1, 0x5edd65dd, 0xab55e5e0, 0xabc72cee,
- 0xbf305a0b, 0x4694ec17, 0x822bebed, 0xed3b4fe0, 0xaf78c3be, 0xf36dd3af,
- 0xacdc7ae2, 0xab3f68d9, 0xeb49d325, 0x56a90aef, 0xe8d2f5c7, 0x685519d7,
- 0x3cb5a73e, 0xe0897fd2, 0x669fc153, 0xbe631fb4, 0x6f3fea8f, 0x0dda8d3c,
- 0xe0eaffb9, 0x756714b5, 0xff946d79, 0x746816a4, 0x5fc19a8f, 0x6b9c7ed6,
- 0x24fdb894, 0xba427fc2, 0xd794a3db, 0xdfc5abd6, 0xbb497e5f, 0xb9eebcc4,
- 0xea777896, 0xf8230a6f, 0xe0f514bd, 0x8f902eb9, 0xab8c3497, 0xabfd3e8d,
- 0x47c92f52, 0xe1afcf06, 0x2da2db72, 0x5fbcf277, 0x89693df3, 0x4bc0d1f8,
- 0x47283c22, 0x4fdc51fe, 0xfab1601f, 0x563529c6, 0x68e1bed0, 0x138a6d85,
- 0x5cdc514f, 0x3e28b74f, 0x6bf95fe2, 0x075c4e15, 0x9ccad39a, 0xa6df9fb8,
- 0xd1725378, 0x33223c3e, 0xeab59b8c, 0xca31b966, 0x4f7ef1c7, 0x8898e380,
- 0x27df5a8b, 0x380bc825, 0xc7f5d627, 0xeddb5ff7, 0x009f0f3f, 0x491e68de,
- 0x7a8e8a79, 0x7873b641, 0xed7dc593, 0xc44dfa89, 0xe7ec4f1f, 0x8abbe0f7,
- 0xca8e749c, 0x38ab5e3a, 0xf00ad72f, 0x9adb9da0, 0xbee3e30d, 0xc9d157b8,
- 0xc49b1e8e, 0xa17c319c, 0xf7a24ea4, 0x3c34b5a7, 0x135ac7bb, 0xa7819df0,
- 0x1f552ed7, 0x97fc2c07, 0x978a5bfe, 0x5fdff0c7, 0x6bdff1e3, 0x1ce973c8,
- 0x2d7bd8fe, 0xbfbe5495, 0xc8d78567, 0xdb6677af, 0xc04bed4c, 0xa371e0b7,
- 0x032a1cef, 0x50311cd6, 0xf1870607, 0x71cf513a, 0x74e22e7f, 0x714fb60e,
- 0x55bca77f, 0xc39d3aa1, 0xebfcef83, 0xf74f6a34, 0xcea1d4d9, 0xf6aa3f07,
- 0xb0e98d4e, 0x4bd59f3e, 0x6f00ddd3, 0x7e01f749, 0x9d33a61e, 0xf88b5eff,
- 0x8def0ade, 0x1bf74e1e, 0x29953a3d, 0xc23ffcc7, 0xece83fdf, 0x1c62f24e,
- 0xfc5873b7, 0xcc7883df, 0x742fe46d, 0x28c8fd88, 0x4fa44bed, 0xff51ebe5,
- 0x8ff264ee, 0x99a7e286, 0xb16177df, 0xc1ee0637, 0x77642250, 0xc3bb0ad4,
- 0x2e64bf18, 0xf287aff3, 0xeed624d5, 0xca70fb04, 0x15dff8c0, 0x47802dfb,
- 0x9f96fb80, 0x4ffb455d, 0xc2af7f46, 0x33ed84b2, 0x92c5a232, 0x13fc097c,
- 0xcefba666, 0x42d19cea, 0xd97b1fdc, 0xf88e9816, 0xcd16386e, 0x1be77ac0,
- 0xbc1ec927, 0x72ee1e10, 0x7b9a7d73, 0x479f6195, 0xeb38d8d4, 0xe7a5edd2,
- 0x8b570f3d, 0xfd1890f1, 0x72b78836, 0x7e90ebc2, 0xe8af3fa1, 0xe92be31f,
- 0x3ae9f12d, 0x2c919f48, 0xf47cfc38, 0x89c161c9, 0x22a12e9c, 0xe7dc7f4e,
- 0x5d937983, 0xf59b741f, 0x8afeffc9, 0x130d37cc, 0xd29f80d1, 0xbef3c4a1,
- 0xde2cef78, 0xe3c4bb8f, 0x693fad35, 0x1d457b0a, 0x4987c316, 0xfa84e82c,
- 0x4be88e2d, 0x7518ff68, 0x0e2dfde3, 0xcfec69e0, 0x90c8e5c9, 0xf1b9dadf,
- 0xedc736e5, 0xc74df9e1, 0xf7dc1e22, 0x03e38e98, 0xbfc33bbe, 0x3ac77ba7,
- 0x3f8664bb, 0x6e62309d, 0x83680e40, 0x0fda1a74, 0xfc86abd7, 0x95793983,
- 0xed3fc85b, 0xfee32ee3, 0x8c67a1b5, 0x6b725eef, 0x8b8fa697, 0x7af39c86,
- 0xe408e509, 0xcb2e10ea, 0xbdf8cb39, 0x5ee2b577, 0x0f711e9b, 0xdfc207e2,
- 0xaff73a60, 0x3eb07b8d, 0xf7c81c28, 0xd6af3f23, 0xde0effe5, 0xca8ec343,
- 0x27fa6f94, 0xfdc29fdd, 0xd4bfb343, 0x31b9ee23, 0x66b6a5fc, 0x36736f71,
- 0x4936e7e7, 0xf6167fba, 0xf74a363b, 0xf0646718, 0xa738d3f5, 0xf4a332c7,
- 0x1f065a7b, 0x7fb3e225, 0x7a80f211, 0x8f97182f, 0xe32fe255, 0xeeb007f9,
- 0xb5ec6305, 0xd0151ff9, 0x98079bb9, 0x0f97e28f, 0x60b327b4, 0x5f3b5e0c,
- 0x732f9f88, 0x29db8c42, 0x456679ee, 0x7c835e7c, 0xb9d1e7ce, 0x0fdc3e3c,
- 0xe8fe70a7, 0x7779f714, 0xc464fe2a, 0xe175a253, 0xf65e80c4, 0x2b1f2327,
- 0x99bc1c5f, 0xc79af5c6, 0xfbf457bd, 0xe2cabfb3, 0x8f0004f7, 0x7b607f42,
- 0x1762c7a7, 0xf0feb25d, 0x419bd69b, 0xbd234fbc, 0x43fae972, 0x48fe80bf,
- 0xf2c2fa23, 0xe2bb41ee, 0x57bf30c5, 0xb6c3c5ed, 0xd0e3eb19, 0xe5c840ad,
- 0xdd0ae995, 0x84557643, 0xda89fbaf, 0xf7130c65, 0x5a3c0b0a, 0x8fcb4be1,
- 0x08b71fcf, 0xf196d43a, 0x9ef1917b, 0x942f9c76, 0xafe83e39, 0xd20b4ca7,
- 0xbc8bbff3, 0xdad17187, 0xfe2f0e1d, 0x0ecf524e, 0x85ea1557, 0xaa8e1d9e,
- 0xfa50daf5, 0x9bf42df9, 0xff8cec2c, 0x64bffae9, 0x2fe27fae, 0x4ba01f71,
- 0xad1c7ba6, 0x76e93dfd, 0xfa0377d3, 0xe5dd813b, 0x2d33fa10, 0x9ec5d399,
- 0xab4dd7c7, 0xf023dd5c, 0x67c08f76, 0x1e57b89a, 0xae2721d6, 0x39bb4643,
- 0x0094fde2, 0xef3f7b8b, 0xfa570863, 0xecf03ae0, 0xfbf632b2, 0x7d3bf8e1,
- 0x742b8a41, 0x839236fe, 0xf294f6fd, 0xfbf58138, 0x8c67c162, 0xc9e8ed99,
- 0xfd12bcd3, 0xd258611e, 0x807edf71, 0x4f7e61de, 0xb2770af0, 0xc5a2cfb0,
- 0xf73f92f7, 0x48a3f524, 0x0f1c50af, 0x0dbf366c, 0x0a7e88f3, 0x9e4c5b76,
- 0xbd16bde6, 0xbe678563, 0x13b7cf9b, 0xa3f637f5, 0xdde38b45, 0x5bac60ff,
- 0x86d3bcc6, 0x49e0e59b, 0x26c71f0f, 0x25974bc6, 0x6eba0f1a, 0xebe30c77,
- 0xe60bcf31, 0x479e127a, 0xc80b39e8, 0xfaee00e3, 0xfc6fc5fb, 0x59ce7888,
- 0x13d2b03d, 0x5da00763, 0xb095eb4e, 0xc6553bc3, 0x5d844bf7, 0x8274fa88,
- 0x90770b16, 0x6d974906, 0xf12b5f5c, 0x43cc35f5, 0x9b897efc, 0x2fb419fa,
- 0x4fb11db8, 0x389d6bcc, 0x8daafa3f, 0x21bd92b5, 0xe9c864f0, 0x6e9c8b4e,
- 0xec357cf5, 0x77e275b4, 0xf17e912d, 0x614ae1f4, 0xf31c95af, 0x95bcc78f,
- 0x1f342acb, 0xdd25a1fa, 0x9e600fb3, 0xfc1ee14e, 0x39419a61, 0x8cfc142e,
- 0xc18dcdfd, 0x6e3cefdf, 0xe6f7dd93, 0x857f0457, 0x7cc0d8c7, 0xebd18def,
- 0x7ae1eeff, 0x2dfc1d2b, 0x5fd38394, 0x785ebd11, 0x9e00e2ac, 0xba05aac3,
- 0xf830caa3, 0x6f3c33a3, 0xe1ed0bb9, 0xf687cc63, 0x9e786f74, 0x47f01c6d,
- 0x3f6e1aef, 0xd5f9e80e, 0x97a05f1c, 0x2f97a8c3, 0x2e4fe63b, 0xc296ba82,
- 0x7365eef5, 0x2967bf19, 0x5fa10eec, 0xf489e86d, 0xe2a7fadb, 0x727d6f3e,
- 0xe62bb363, 0x2efb40f9, 0xa83b9f68, 0xdf516a6f, 0xf3db1378, 0x79925323,
- 0xc71e7b3e, 0xe664f4cb, 0xaf3c0174, 0xdc6506e6, 0xb2f57cc7, 0xaf7809dc,
- 0x40a4a1fa, 0x7ef812d1, 0x0e3e0cf2, 0x2e8472eb, 0x47878dcb, 0x4433afae,
- 0xe44328dc, 0xf124676f, 0xe70a4572, 0x979d24f7, 0x1f9ce9f7, 0xe3f13c32,
- 0xbb44cb4c, 0x3bd71b3e, 0xb7c6978f, 0x914bae4b, 0x8b3ced2e, 0xdfc6b24f,
- 0x17494baf, 0x06db6af7, 0x3fc1b5f5, 0xc677c427, 0xfc6265f8, 0x89986745,
- 0x8d29167f, 0xce8b37c4, 0x8637c428, 0x3fe2245c, 0x1aeeff63, 0x14c6e047,
- 0x9fa3f79c, 0x209c6315, 0xdf0f6577, 0xdfdfc237, 0x7cb136b9, 0x4181eb18,
- 0x9df3d06f, 0x3d00cf18, 0xad0a693f, 0xfc8bcf43, 0x31a72e53, 0xf08ffa76,
- 0xbb3b1df7, 0x8e6bccaf, 0x7ac0eba1, 0x8cfee3e9, 0x85195d75, 0x89e9c049,
- 0x7298d5e7, 0xcaedfaa9, 0xf1787604, 0x5e1da97f, 0xe4813dd2, 0x578101f6,
- 0xc466be23, 0x7897f0b1, 0x8ab3bdb9, 0x1a7931f0, 0xffc06f97, 0x22ff8156,
- 0x1a7fff8e, 0x643dffc0, 0x79707427, 0x4bd688c9, 0xf45f24f9, 0x453bf19d,
- 0xa0df27b9, 0x293dce7c, 0xa9df7fdc, 0xbe409ffb, 0xbbf2255c, 0xa888cf27,
- 0x407b58de, 0x2ad17efc, 0x1af9c0fb, 0x591bc7ca, 0x0ecdfbcb, 0x189497ef,
- 0x8596d1f9, 0xf9802cc7, 0xf9f15767, 0x9bb14dac, 0x5875a7d6, 0x485f2e87,
- 0xbb2dfae1, 0x6015222a, 0x4a376b7f, 0x1237f40a, 0xf809877f, 0x0b236466,
- 0xd0fefec5, 0x4f1f1f48, 0x07a485f3, 0xd3e7068a, 0xa4559b6e, 0xcf695e83,
- 0xa0b5f648, 0x3606a4c8, 0xbed79f23, 0xf2fca11b, 0x2b76efc9, 0x9e5fc7e8,
- 0xcf82dfea, 0x6578f98d, 0xbefd247d, 0xce1cbbf9, 0x32f7610e, 0x71e1cd16,
- 0xfe0427ff, 0x887b0bd7, 0x23dfa61d, 0x94fdb8d2, 0xe9ac7cb1, 0xff0ce777,
- 0xfa73fd07, 0xb599693d, 0x70a78a33, 0xbcb196fd, 0x834bec90, 0x57e7a61f,
- 0xd3e7c46c, 0x01315c47, 0x5fc897ef, 0x77f05115, 0xd6ba7fa5, 0x94fef716,
- 0xc01f4243, 0xcec7f63c, 0x6b7242e3, 0x9d27b3b4, 0x67936f9f, 0x0ddbb7c4,
- 0x3e7d2c3e, 0x0fba6eed, 0xb86555b1, 0xffe064ef, 0x378ad4f2, 0xe1919e11,
- 0x46e11275, 0x49c4678c, 0xcfca39f0, 0x9cf9aa07, 0x5cf9425e, 0x82cc63b6,
- 0x556cf958, 0x2ceb3e89, 0xe86e13bf, 0xae14de8b, 0xad48efc7, 0x71f203f8,
- 0x1453d77d, 0x91bc59b7, 0x424c1eff, 0xfe245cfc, 0x78cdde60, 0xf80d5dcf,
- 0xa3ef7817, 0xeec89614, 0xf7c39dad, 0x72b76adf, 0x2aad657e, 0x1b5703dd,
- 0x7f411ede, 0x7ea3d462, 0xd5a76e1f, 0x2d2edd6c, 0xa8ebc18c, 0x27e510da,
- 0xe436ee5c, 0x2b19eb89, 0xd8dc63df, 0xc876fc05, 0x9eeaedc5, 0xff07ee52,
- 0x7ac9083f, 0x0080006b, 0x00000000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
- 0xd5947c79, 0x6779f0b9, 0xcc93324f, 0x2133df64, 0x61262201, 0x01161212,
- 0xa0084933, 0x24584e08, 0x81ec36c8, 0x8bf628ac, 0x0c197e95, 0x6f62e452,
- 0xb90556ac, 0xda544076, 0x1a080962, 0x88b0e834, 0x148d6ad0, 0x43b05b05,
- 0x921088a5, 0x6f16b629, 0x79e7bd69, 0x799939ce, 0xf8b0ccdf, 0xabbf7ed1,
- 0x9cce1c7f, 0xf3cf6cf7, 0x273f679c, 0x2d675a5d, 0x2ba42229, 0xcae6c229,
- 0x9dbde424, 0x91488ee3, 0xe9769884, 0x55ae503d, 0xd034496d, 0x7483b5f6,
- 0x4eda16b6, 0x62909b88, 0x8e35a242, 0x12cfd0dd, 0x92adb26b, 0x49eab108,
- 0xc848d9a1, 0xeec4f1b0, 0xf0b7e5a6, 0xafad095f, 0x425cf5a4, 0xc1d334ee,
- 0x293fa0e2, 0xc9089874, 0x9c709b36, 0xc3211578, 0xac39090b, 0x34432e25,
- 0x8be0bb21, 0x89ac8411, 0xe399c472, 0xb10f1e60, 0xf196fed1, 0x4258f7f4,
- 0x5b891a6a, 0x6cd5f3a2, 0xf423adda, 0x76847277, 0x6524224a, 0xd6f384bb,
- 0x2d2cdf6c, 0x5e67bfa0, 0x075fb5d8, 0xa19357df, 0x7ab3f461, 0xd03b8d89,
- 0x7180cf62, 0xf61c7b49, 0x9654eb13, 0xbd70b884, 0xe9b7c6c3, 0x0e38b9ac,
- 0xbff4a3ee, 0x079f4ab6, 0x5666cfec, 0x9b3577e3, 0xa64feeb6, 0x626a91f3,
- 0xefc56fee, 0xe6c5dff6, 0xff89e8d7, 0x675864fb, 0xa2e75b2e, 0xc4baff5c,
- 0x2aaad7fe, 0xdfb4cd73, 0x5b08f8da, 0xb38b6d0b, 0x7ac18738, 0x0f3aa78d,
- 0x61918851, 0xa73a3ca7, 0x77febfd1, 0xd1848475, 0x58c3877e, 0x15b352ff,
- 0x47563ae1, 0xcebbf85c, 0xe3a56395, 0x8e17ee1d, 0x49b9bde3, 0xa4e01e35,
- 0x2773270d, 0x3793f9d3, 0xb454956d, 0xe6411b1e, 0x23d6023a, 0x5cc7bbd6,
- 0x062e6156, 0x1c227438, 0x706936ea, 0x473a15fd, 0xff5cf2f6, 0x2acc5377,
- 0xf4c0f79c, 0xfa5e74cf, 0x7c6fd3fb, 0x6ba9f884, 0xb06dec95, 0x748fd6de,
- 0xac00f2d3, 0x7893533f, 0xf6102642, 0x3e7b33df, 0xefe959d2, 0xfc337613,
- 0xa9deedd5, 0xaecb4059, 0x1a4ba352, 0x303c780c, 0xaeace807, 0x24c24f4d,
- 0x06739fc0, 0xa74943c0, 0x78841e02, 0x42be81d3, 0xe80233e1, 0x3aaa08a8,
- 0x67a47f77, 0xfa64e667, 0xdd346b7d, 0x8ee811bf, 0xd91883ed, 0xbec10fef,
- 0xc7e902e2, 0xafe60cb9, 0x801db708, 0x28515173, 0xac085ad9, 0x23ee18f3,
- 0x31c19cb6, 0x79953d70, 0x0ab3d6c1, 0x618b89e7, 0x378d12f3, 0xe713e61d,
- 0xd64d4e2b, 0xff7f4292, 0xfa578e26, 0x4efd87bb, 0xfcf239fa, 0x6de256eb,
- 0x75c259ab, 0x55a7a107, 0x53dacf80, 0xa7a30f1e, 0x93d00d4e, 0x8fa0bf58,
- 0xc6693657, 0x56e39e07, 0x6bc70eb3, 0x1d706b35, 0xa27e00cf, 0xe765a968,
- 0x065599f2, 0x198ff237, 0xf9488f63, 0xebf72f14, 0xabbe503c, 0xed0b5f9a,
- 0xf9b326ef, 0x0f54aad7, 0xa3ed7d40, 0xf882d246, 0xf0093fb4, 0x123d303c,
- 0xa55b52f1, 0x38e9eb73, 0xb126bf4f, 0x26e8cbba, 0xceb59ff4, 0x1fa10ba9,
- 0xbdb30d89, 0x1e737804, 0xf5334dd2, 0x3d2b27a5, 0xfbfa56f6, 0xce763684,
- 0xdb6a1e04, 0xdd015d18, 0x5c39bc23, 0xcb74f0fd, 0xc7c08dce, 0xa333289a,
- 0x00274a07, 0x616d9aef, 0x3606b3e6, 0xe804b7d7, 0x37ab22d2, 0xcf9927b4,
- 0x35ebf8e6, 0x83a00ff0, 0x8648c4ed, 0x75f075d2, 0xee72a1be, 0x19d43c02,
- 0x14b587bc, 0xfa4f43b5, 0xa2875cf0, 0x5fa69adb, 0x843b380d, 0x47896590,
- 0x55e714b0, 0x47ed8fdb, 0xc70eff7c, 0xd250cbfb, 0xba730ff1, 0xc36a29a9,
- 0xb67358f3, 0x71b1cf11, 0xc667e33c, 0x4d7e7253, 0xbf7c13c8, 0x8a9c71eb,
- 0x6ab1b688, 0x9f8af70a, 0x1216e64a, 0x912e5f9a, 0x8e8da388, 0x83a6c5f7,
- 0xbe00f391, 0xe355bf57, 0x7ed8c37e, 0xd0fe704f, 0x1c028db5, 0x4751bde9,
- 0x46f7ec82, 0xe39e23c7, 0x86bde012, 0x7b6bbec3, 0x513f88f9, 0x8b6d717a,
- 0xbdff01b2, 0xc3ca7db8, 0xeeeba27f, 0x53625ada, 0x38b4d903, 0x717c7e90,
- 0x942db661, 0x64d5627e, 0xbef144bc, 0xe460edaa, 0xcbefda48, 0xd42e0c5f,
- 0x7cdd7ed3, 0x535e179d, 0x1e5c0137, 0x9dc7657d, 0x96e35ed0, 0x778f8062,
- 0x3fe9fb6d, 0x6f57cf81, 0x9308006d, 0xa3bc5f96, 0x54efd2f3, 0xf7eccdee,
- 0xf866516d, 0x9f17cbee, 0xdde013bc, 0xed82d6d2, 0x8cdc5e17, 0xecaf03f5,
- 0xe9bffb78, 0x488eb577, 0xe1777c1b, 0x9788fdb5, 0x0ec6a75a, 0xd7450dfb,
- 0xcfdceccf, 0x849b64f8, 0x31548de7, 0x5ae825fe, 0xaf97efd0, 0x28111dcc,
- 0x8ed56a1f, 0x4fbe0954, 0x925edbd0, 0x9ca05e50, 0x688c3778, 0xdffee8c2,
- 0x9681a5a3, 0xfbe5ea15, 0x2ce780b5, 0xd908cfc6, 0xa7b5e42c, 0x6f7efe84,
- 0x75e6c449, 0x3eaeee70, 0x26e78d98, 0x1d1dd182, 0x31c7c0c7, 0x434438c0,
- 0x0fbeb0ec, 0xb2db6fd3, 0xa547ce8e, 0x924efb34, 0x47779c70, 0xce05bedf,
- 0x8c2f58bd, 0xda0f3937, 0x9e41532b, 0xf2d7df88, 0x670dae75, 0xe722edf2,
- 0xc6653537, 0x7c5e50b5, 0xf00aac35, 0x0ef3af53, 0x72fc00b0, 0x5b471d19,
- 0x6daebf18, 0x37adae5b, 0xe71c7f62, 0xa0a7ca13, 0xe9e7a3cc, 0xf49f3d1c,
- 0x0edfadab, 0xc97ef981, 0x193864f8, 0x3e98fb0e, 0xf0048ceb, 0xd46dc88b,
- 0x7f5c20d6, 0x9629dac1, 0xae87db02, 0x4947e760, 0x2316b9b7, 0xb73b1b87,
- 0x532bbbc9, 0xf4b7c8ad, 0xfa01feb6, 0xb3b57253, 0xbf7f44c5, 0xa6d3857b,
- 0xe6f774a6, 0x536363f9, 0x1c95fd68, 0xabd20869, 0xd8f2625a, 0xea79c465,
- 0xe7c8ca9a, 0x2d23bd74, 0x9bc75cec, 0x428ee689, 0x342a9e3f, 0xf8446344,
- 0xd5af90fb, 0x7af2e5ad, 0x31275b2b, 0x98a7d2f8, 0x8ef19fb0, 0x683aff68,
- 0xeb11a33f, 0xf2fbf4be, 0xaaba3e40, 0x755a3e50, 0x820bdeb8, 0xfe57117f,
- 0x7f3f3cec, 0x139b7aa0, 0x475e35e8, 0x8fe3234b, 0xfbfc7495, 0x9695a52c,
- 0x1f197f38, 0x7095dace, 0x74ed0f5a, 0x762dd79c, 0x8b6c8efc, 0x50afc991,
- 0xe39eb07c, 0xbbc919ff, 0xb5cce818, 0x740ccc37, 0x77a77f5d, 0x5c1f2040,
- 0xb07c616b, 0xf74dd39b, 0xef2f465e, 0xd82e54aa, 0x6e5bbbdf, 0xa8740cdf,
- 0xff03c794, 0x8695762b, 0x2edc9b8e, 0xc92f0199, 0xf0cb269b, 0x55baf547,
- 0xe5d657a0, 0x5f814348, 0x7fcbed48, 0xd7ad1b75, 0xbd41bc53, 0x9f3f377e,
- 0xef854f54, 0x172bdbeb, 0xb1297cc2, 0x12d4d977, 0x536347ea, 0x96bebd68,
- 0x7ff9c314, 0x37becd26, 0x9121f705, 0x4f20ac97, 0xf20d5ea9, 0xf50f2e34,
- 0x56e77af1, 0x8e49bfd4, 0x85bdcb8e, 0x27d7afa8, 0xf9c1b4ce, 0xf627c3ea,
- 0xaf7d42ae, 0x0b6e1ade, 0x684fdfa3, 0xfa601e97, 0xf5b0918e, 0x4fa87648,
- 0xc3748f70, 0xf8092e7a, 0x39db5288, 0xdeefe607, 0xda2e27a3, 0x71dedefe,
- 0xbd05cf28, 0xa3d75e98, 0x98d68f5c, 0x2fcbd025, 0xe7c9db36, 0x65982554,
- 0x05bc22b1, 0x67b66b3c, 0x5c9ce0aa, 0x9ff0ede2, 0x43cb9e35, 0x42dd69fa,
- 0x2d67d20f, 0xf563dbd7, 0x030782f6, 0x28f427f0, 0x82fc1d25, 0xa6f27fd3,
- 0x621c1243, 0xaeee7e25, 0xba069e26, 0xa937bbbe, 0xa8f9253c, 0x7c8fdd5f,
- 0x6c8e957f, 0xb78efa91, 0x8a8bf383, 0xf0014718, 0x46e98ac9, 0xaa7f205b,
- 0xc2abb708, 0x423cf402, 0xfa2a451c, 0x1378f9dd, 0xd875ffc2, 0xacbd1077,
- 0x63967fb7, 0x22bbc02b, 0xa7ed0c21, 0xf95d5a7b, 0x5d6d1fa4, 0xe7055e15,
- 0x2363f292, 0xed334df2, 0xdf8bbf4f, 0xe445f232, 0xd705a4b3, 0x6662d9b5,
- 0x8a38c4e3, 0x64b5811a, 0x39305639, 0xdb05b266, 0x3f7c7dcf, 0x29cfa607,
- 0x4c9d0150, 0xf4f4da35, 0x92dfa7bb, 0xb8dd23e6, 0xf384c0a8, 0xec715ce2,
- 0xd8af662e, 0x5388ee80, 0x7d56fa83, 0x9c1dc3a3, 0xd71d18ae, 0xf40bfd53,
- 0x88574a70, 0x2676fab7, 0xddb8227f, 0x50227c07, 0x4ae715df, 0xd7e05b9c,
- 0xde823740, 0xd1bdb9c4, 0xcfcdd9f3, 0x7fdd3747, 0xde9a7d20, 0x6eb97464,
- 0xda14b595, 0x731055d7, 0xb4aabda0, 0xf870ac83, 0x62fadd68, 0x11c61b84,
- 0xe2ce2e7c, 0xa8fc0b38, 0x35d1cb7e, 0x2f9cb648, 0xf8f9bfd5, 0x67e96b80,
- 0xcf1b0d06, 0x07708ee0, 0x82818fd2, 0xa58854db, 0x4473f80b, 0x12df5c93,
- 0xdcb93fe5, 0x65facef8, 0x7c01a4ae, 0xa8f2fd09, 0x0b4ff9ca, 0x45292fd7,
- 0xa626f490, 0xaf03c65f, 0x25b07e07, 0x24fc0dc2, 0x77389e3e, 0x97cf5905,
- 0xbc099cfc, 0x3e233b0a, 0x1c9f7d92, 0x5324f4cd, 0x8b2efb34, 0x0bf60197,
- 0xcaab079e, 0x43a88679, 0x8fd101cb, 0xc5db0bae, 0x1fed7a7a, 0xfc6f5b03,
- 0xacb603a3, 0xffa7c00b, 0x0856dd5c, 0xef5ace78, 0xfa37ccd1, 0x48f211e7,
- 0x7eb03f49, 0x9fb05b90, 0xdfd0dcca, 0x76e7eeb5, 0xcb9e829c, 0x633af9f8,
- 0xf2ddf821, 0x68eae718, 0x45159f5a, 0xff1431ec, 0x23d1deb3, 0xdf1c913d,
- 0x6b43b000, 0x8fa5c434, 0xdd6abc06, 0xfe3c00de, 0xfb40f00d, 0x2e0c98f5,
- 0x2d073d35, 0x68e2ce31, 0x8cab9e3a, 0xc7a03cd8, 0x0bf29f7e, 0x53c49738,
- 0x81a4fc0c, 0x8e012378, 0x239c982f, 0x757abbe0, 0xa9d43a67, 0xf30f931d,
- 0xecc11b3c, 0xb551df27, 0xc785207b, 0x47f78365, 0x2e7ae923, 0xb9b2c8af,
- 0xdfa738e8, 0xdf9efdfc, 0xed2fafd3, 0x19cd22f9, 0x0deb57c0, 0xc626832a,
- 0x4896ef5f, 0xbe105b55, 0xc99a233b, 0x09dbccd3, 0x68b804e9, 0xaeb7a87c,
- 0x8027b308, 0xbec567df, 0xe96b84d2, 0xca570df3, 0x9e603b88, 0xfa1fda06,
- 0x4b195c35, 0x8c8243dc, 0xf903c74b, 0x992570d0, 0x3cd862b8, 0x315437c0,
- 0xfbf8ce4c, 0xed1713a7, 0xaa455a7f, 0xe7fbad83, 0xbb5f0cd1, 0xac1f1909,
- 0xd7df077d, 0xfcec7eee, 0x6e4836fa, 0xaf160fb0, 0x14d47930, 0xcfe98ba4,
- 0x362d2fa0, 0x48aa3cbb, 0x8f943fe0, 0x4e34460d, 0x647b5035, 0xf467971e,
- 0xa028cd3b, 0xcf199757, 0xc39f93a1, 0x7defed79, 0xc589fe03, 0x4518621a,
- 0xb06f99c7, 0xbfa14e1d, 0x2638c9ff, 0xc2c4c412, 0x83c4a687, 0xd5984b1c,
- 0xbd2273a8, 0x7e83318d, 0xea51912a, 0xa5ae236f, 0x8f50690f, 0x74a27a45,
- 0xac718ba0, 0x3a00ba04, 0xf5983a04, 0xe26be320, 0x5e7e5cfb, 0x59f87495,
- 0x8ecf7c08, 0xf181cb29, 0x358e512c, 0x5e0fdf48, 0x6ebff192, 0xf3f2fbc9,
- 0x4dcba740, 0xdf4897b6, 0x70e13ffe, 0xd4e829ef, 0x2e5a2c91, 0xea3a47ff,
- 0x9def1da3, 0x675d3e04, 0xa0d47a30, 0x76d6ec57, 0x283ec579, 0xd945060e,
- 0xf073c29f, 0x739651c3, 0x02482694, 0xe3d71dfd, 0x03bf00dc, 0x0363db9d,
- 0x151adce9, 0xeba2740d, 0x10c38bc5, 0x490bc7ef, 0xd1f1c935, 0x31f11471,
- 0x01d760df, 0x1dd817dc, 0x5159beb8, 0x0cb3629e, 0x6feab9fe, 0xf871bf6f,
- 0xf9e7e7af, 0x61d28eb4, 0x83b07390, 0xc31543c3, 0x64e9c6f8, 0xd3a7af46,
- 0x282ef549, 0xf692d107, 0xd78fdd3b, 0x007d790b, 0xd59e2eff, 0x797e700f,
- 0xa77d9f3a, 0x3e33e79c, 0x7b18eccf, 0xf68bc007, 0x4f00e8f3, 0x41b9876f,
- 0xeafca64f, 0x8f13a700, 0x155f9025, 0x1f0006f9, 0xf8a629ec, 0x5759fba2,
- 0x013f4bea, 0xde9f64fc, 0x7d7ac5bc, 0xd7c27dbc, 0x97e59df5, 0xa1afca8d,
- 0x49f5f932, 0x885f9334, 0x1d12ba27, 0x11b2abd3, 0xea17483f, 0x5bcfc71b,
- 0xf4ee0c61, 0x51a3789c, 0x1cf2794e, 0xaffd7c01, 0x8f826e1c, 0xe3970e9c,
- 0xf7f7c5d1, 0xeb473f25, 0xde4ccda3, 0x30e97cd9, 0xe0e8e9ce, 0xc7ed5f78,
- 0x239e3747, 0x0c4e6fbd, 0xa8fbb7a5, 0x442ba0be, 0xf587ac7c, 0x734bb1f4,
- 0x73857f3d, 0x8980f0dc, 0x22bbdc80, 0xa1f22be6, 0x97ca937f, 0x4e8f0674,
- 0x87afd41d, 0x27d1f01f, 0xd4951a51, 0xd5a02274, 0x71c5621c, 0x9e3328c8,
- 0x3e5eb0b3, 0xf38989a2, 0xef3947c3, 0xc8af8e29, 0x0e734918, 0x36236af0,
- 0xa3e737e8, 0x29b34caf, 0x1b325c9d, 0xcf2a2a5c, 0xd19caaae, 0x79efe031,
- 0xbbea28f8, 0x019e74a7, 0xed20c6ad, 0xcf0bcf3a, 0xb9f6fe4a, 0x74bb533f,
- 0xeeef1cf4, 0x74c9faec, 0xa7677fba, 0xd8e706da, 0x1faff2b9, 0xa5bd030c,
- 0x4feb6b53, 0xd7aeae50, 0x991a3ec0, 0x254a767e, 0xefc5ff87, 0xc187edc9,
- 0x540f0c31, 0x133a409f, 0x5854e0fc, 0xeba13e64, 0xfd3c4259, 0x51e7ee81,
- 0xef4a17c3, 0x10f725f2, 0x181627ca, 0x7dfd22a7, 0xe85dc0f1, 0x9c485e6f,
- 0xb9e62fc8, 0xe40c7fb4, 0xcad60ba3, 0xe55a8beb, 0xc9cf25f5, 0xdffebdeb,
- 0x4effb972, 0x98635394, 0x0ba8ba5c, 0x863e3ede, 0x9777e3d1, 0xee5083c7,
- 0xf9c795f6, 0xe395a728, 0xaee5c3de, 0x1e42cb90, 0x84315c37, 0xe388c718,
- 0x7c1c5c5c, 0xf5f1f7fd, 0xa3315c37, 0x3fdbef7c, 0xd53ae516, 0x813bf0c4,
- 0x892b86cf, 0x0ba8bbf8, 0x2fdfd07d, 0x8ca3c715, 0xc22e7cdf, 0xdf85fe7f,
- 0x19efd057, 0xd0921889, 0xfb927b5e, 0xe0f9cc6b, 0xf2033a87, 0x39d9e29d,
- 0xa5edbc8e, 0x48f79c4b, 0x3f4d00d2, 0xf72b7d3f, 0x82e0e941, 0xd59f8037,
- 0x716298c6, 0x3064c1de, 0x73e82bcc, 0x5115c3ce, 0xb0ffdf20, 0x50213cb2,
- 0x6bf5eaff, 0x447d98e8, 0xaf265188, 0xcd9e4288, 0x2bf2a76b, 0x0188f51f,
- 0xef9f9740, 0xb9f4819b, 0x81e2d890, 0xe9f67b6e, 0xf7ffd1d3, 0x5898e51d,
- 0x3cd714cf, 0xa92fd32d, 0x65e7a090, 0x4a7f9f32, 0x5467d307, 0xf516bb06,
- 0x9ab13b15, 0x64a4d1e3, 0x130a96f2, 0x168fad0d, 0x5a1e2075, 0x2337c51f,
- 0xfeba7f41, 0xf324bcd1, 0x9e70899d, 0x1aaf30f4, 0x113b90d8, 0x361196ca,
- 0x9225942b, 0xc1d6c343, 0x34963cf0, 0x2af7c2a6, 0xf4cd5783, 0x7882ba25,
- 0x63e62fe8, 0xafaf1375, 0xce797a9e, 0x68ddf822, 0xe3af73c2, 0xf05578eb,
- 0xc031032f, 0xcf46f5be, 0xe24f1897, 0x8accaba5, 0x1faba876, 0x9c3fbb41,
- 0xd79811b4, 0x82e4bc68, 0x59899acd, 0xf9987a82, 0x0211e7b2, 0x52e8cd7c,
- 0xb6be460d, 0xf49af913, 0x7be062fe, 0x03e68f94, 0xaed90d1f, 0x2efea0f1,
- 0x5f3452f8, 0x4be70b5f, 0x21c18449, 0xbe71d886, 0x23169b1f, 0xae338a5f,
- 0x86ffa090, 0x97c8f1c8, 0xb4f001e2, 0x46bc663d, 0x1ce267c6, 0x95427af2,
- 0x94e49ebc, 0x14e40dd7, 0xe3c903ca, 0x0636fc48, 0xf01c91ed, 0xd8cb683b,
- 0xce1e99f9, 0xeb0dd5d6, 0x1139fba3, 0x937ffaa3, 0xbb7245fb, 0x475a3eb5,
- 0x4f150fd0, 0xa8c1e62d, 0x61889c07, 0x2e67c07a, 0x90fb5768, 0xfee09eff,
- 0x1de3a983, 0xdf8a1a15, 0x07c972fb, 0x8f9e5a76, 0xef869e73, 0xac691c67,
- 0xaaf5a5ab, 0x879e49f7, 0xe6250596, 0x9f14ed9a, 0x6c9b666b, 0x1afad28f,
- 0x576d2313, 0x22f51e9c, 0xb698f202, 0xa225566f, 0xfc01a3ff, 0x6bff74ad,
- 0x3a006f40, 0x5ed04fe8, 0x1ac87aa6, 0x79b7ed03, 0xcebcd99d, 0xdf2a7e0a,
- 0xfa07f058, 0x16f31116, 0x5c3ce412, 0xe28ce7a5, 0x53a845f5, 0xbe9c4a3c,
- 0xe15befc4, 0x2f562cf7, 0x1e760a19, 0x83ab2ffb, 0xcff02832, 0xfddce8e4,
- 0xa51d3d61, 0xcf5a38da, 0x7f43631a, 0x617ce131, 0x9f879898, 0x73fe91bb,
- 0xbc05ed80, 0x64f1dd9e, 0x978c3c45, 0xca7e504b, 0xd62c0dce, 0xca187f4c,
- 0x73c0edcc, 0xfff1077b, 0xfb95e307, 0x8dbc47c7, 0xceef6de1, 0x61d8f166,
- 0x387ecf1a, 0x597923d7, 0x8774cbc0, 0xa511fe54, 0xed8342d7, 0x802b1ee0,
- 0x7d86a1d4, 0xde3f350f, 0x708ff302, 0x7c03147c, 0xf281946c, 0x0cb65a03,
- 0x59ccd9b7, 0xf8156fb8, 0x42b5ba97, 0x40a3d91e, 0x92ad4dae, 0x7d00ff5c,
- 0xe11a8c60, 0xe53197f3, 0x7794d751, 0x3ab22a4d, 0xd6acce50, 0xf3f7fcc9,
- 0x65ff9963, 0xecd8ec5c, 0x2c079458, 0x962837de, 0xdba009f2, 0x7c03921c,
- 0xe71ce022, 0xa55d77c3, 0xce750ebf, 0x9cfcede5, 0xd10fb34f, 0xcfcb3ea2,
- 0x8eabe0bb, 0x669e7670, 0x74069210, 0x22349532, 0xba563dff, 0x7dfbcf14,
- 0x7805a5c4, 0xe0c65a7d, 0x653dd62c, 0x98af5cbc, 0xa7d790e6, 0x0ef52957,
- 0x7fbc7b3a, 0x794e19de, 0x3fa164fb, 0x8feb978e, 0x55cffeb3, 0x84b5ca0b,
- 0xcdbeeb97, 0x54f83f00, 0x03f81c6d, 0xfa33243b, 0x8c243bc1, 0x195434fb,
- 0x6c6fe0dc, 0x5bf16768, 0xefd05ab2, 0x7e80c7bc, 0x31da5653, 0xbedf571e,
- 0x80145a53, 0xb75a94af, 0x207cfc04, 0xc8275185, 0x9c77ae2f, 0x83f7bad0,
- 0x52c4fcbf, 0x9e74e24a, 0xe1df3c83, 0x143be410, 0x34cee9fa, 0x28fff987,
- 0x3c7fa315, 0x03611cd5, 0xaaad79bd, 0x6b85fd10, 0xbf324d23, 0xf655baee,
- 0xf84ef80a, 0xcafe4509, 0x6c693d74, 0x43a7fe63, 0xcc8d8cc8, 0x76e6e43f,
- 0xd32c7672, 0x6afb68cb, 0xce294ff4, 0x410c5c6d, 0x333711b9, 0x5580fd07,
- 0xe045051d, 0x07f2a587, 0xb1d9d3fd, 0xe55fec56, 0xd5ff402c, 0x1819c6dd,
- 0xd8e86817, 0xf46859ac, 0x82c3cfd3, 0x044822ee, 0x5faf5dd0, 0xfd1e9768,
- 0x8e555742, 0xd57d001f, 0x44f93cea, 0x7bf8974e, 0x84b2f928, 0xe65b5de3,
- 0xc288b198, 0x9d03e7a5, 0xaa3bec0d, 0x5ebe2040, 0xfe416bdb, 0x904c99a7,
- 0x252eafcf, 0x367b27c8, 0x17c8bf33, 0x687bea96, 0xb52d590b, 0x8eee1f22,
- 0x5ff08b1e, 0x7a843c66, 0x4a26f548, 0x7e7c014f, 0xbd7956d9, 0xb2fb3086,
- 0xba1f7b76, 0xf8247e44, 0x796efd55, 0xe4cd923f, 0xb9c38db7, 0x42d1f380,
- 0x054a6d87, 0x96cabd2c, 0x6244ecc5, 0xfc5e3e07, 0x0bfb8ebe, 0x85cf9967,
- 0x597b8b01, 0xd41e96ba, 0x66af3a63, 0xcdf198e7, 0x928f3e62, 0xfd73179f,
- 0x9d0d4ee7, 0xcfafd0a7, 0x3f561314, 0x2750eaa4, 0x2debfcaa, 0x1e84fde2,
- 0xc0a9f825, 0x4270e957, 0x3b3a5386, 0x8fddf020, 0xd37c03f4, 0x25ce91f1,
- 0xc68954c8, 0xef605df1, 0x51f3e48c, 0x5d01707a, 0x370654b9, 0xa91aefd0,
- 0x0188e511, 0xae5a65f4, 0x57c89c93, 0xa976a8df, 0x4823de01, 0x327b94e3,
- 0x4676bf81, 0x9d289c00, 0x9fa40e1c, 0xdf49e216, 0x08e8c929, 0xbf2cbbdb,
- 0x82474a0e, 0x653e7bef, 0xba04c0fa, 0x02a71863, 0x3cb40902, 0x3a412d24,
- 0x5a7c6719, 0xad7ffd03, 0x78d3f662, 0xfac0d6e2, 0xfc72cc2a, 0xd7944b8f,
- 0xa1f6b2ef, 0xdbff8c0f, 0xe4273c39, 0x82eddbc8, 0xdf39116f, 0x995724ca,
- 0xe1f8fb7d, 0x8eaec087, 0x10392268, 0x9d1aa3df, 0xf8907fad, 0x2dec4f49,
- 0xc4f7c3f7, 0xf7c3f106, 0xafbeb968, 0xc3faafa0, 0x27ace617, 0xe7143a7e,
- 0xa8d20ee1, 0x9370a44e, 0x8ef161de, 0x28fe803b, 0x90370c3d, 0x486fd05c,
- 0x8973f311, 0x6de821f3, 0xc545af28, 0x20cafa71, 0xa35f4019, 0xbfd0c3db,
- 0x19d00779, 0x3e02dba5, 0x42df90ae, 0xde196f2f, 0xa532ae87, 0x78e3942c,
- 0x1f1c84de, 0x7f9ed922, 0x72f41324, 0x01e5ea17, 0x87131474, 0x11d288fc,
- 0x723ecf9e, 0xa0aede52, 0xe3ef8133, 0x252cdf5c, 0x535f488d, 0x3d2c5655,
- 0x2f4ecc95, 0x40d54e37, 0x3326f7ff, 0x74031b3a, 0xcbdf0598, 0x20dca4e9,
- 0x90e92baf, 0x9c0aa8ce, 0xa1974957, 0xe8032ce8, 0x98c7c84c, 0xa8d9d3eb,
- 0x674e5bb8, 0x826ee2a3, 0xdadf04ce, 0x372e6619, 0x96aedc82, 0xf90c0e50,
- 0xea05bb20, 0x5132eb03, 0xb169dccf, 0x46f6c41d, 0x69d45ed6, 0x42de4357,
- 0x9ede0ad6, 0x7a8728e9, 0xa76d1343, 0x671f1743, 0x2bd90d79, 0xa3c17b59,
- 0xe04d078d, 0xfeb172c7, 0x46b97e6f, 0xdddb491d, 0xd2ff786b, 0x37a872d6,
- 0xbffd65ac, 0x60c87880, 0xb77287c8, 0xadb7efc0, 0xb331b4cf, 0x25b7e994,
- 0xa53bbf7c, 0x5fb1075d, 0xe4b7eb2b, 0xa09c21b0, 0xd6f4ccfd, 0x4b3ef93b,
- 0xc67db136, 0x78f77e7e, 0x458ba52b, 0x5fea173e, 0x43b554e7, 0xb085af91,
- 0xd6a54b3f, 0x51c72854, 0xdda50bb6, 0xeeab5b60, 0x5b61e2c7, 0x714d14e8,
- 0xe2217fcc, 0xaeaf1048, 0x9a67d00c, 0x245d98e2, 0x268f8bbe, 0x8d911fa8,
- 0x4437b426, 0x2cf3cb9c, 0x850ec091, 0x50bf423d, 0x5971af71, 0x8c2fa88d,
- 0x2ef110cb, 0x9d3e66af, 0xafdbe0b7, 0xaff306c6, 0x3d31c734, 0xbf8f3ce5,
- 0xddabdf8b, 0x13bf2e2c, 0xe0192488, 0x7057f87a, 0x3c42775e, 0x1727098b,
- 0x65780e19, 0x727e27f5, 0x6a5add60, 0x35512fbc, 0xcc205c6a, 0x23cc25d2,
- 0x3c49d49a, 0xd77d9151, 0x3c434e3f, 0x8407963a, 0xa2dc5feb, 0xc2203cc3,
- 0xc134d9f9, 0xc7f5469e, 0xe3953df3, 0x4fe0a369, 0xe010c843, 0xde38d34f,
- 0x3d5033ee, 0xab72e518, 0x5e37c156, 0x21b1be40, 0x6f2dfea4, 0x6a95f057,
- 0xae62ef3e, 0x3e252f77, 0x49ce4bd4, 0x6fcf2c6e, 0x8d777a60, 0x35ea38f1,
- 0x9e991b3d, 0xa8bc4b59, 0xcb752cf7, 0x36cd42f9, 0x4daebd79, 0x97686f5e,
- 0x5cf27bd7, 0x86cf4f38, 0x4fe0a1ba, 0x03ee7eab, 0x0b56dff4, 0xf396e2fe,
- 0x32564217, 0x20ecf2fe, 0xed28e7f4, 0xeef76a70, 0xa1f8c38b, 0xe82d6679,
- 0x58227305, 0x98da82be, 0x64c07c87, 0x14383b40, 0x39da501f, 0x8320ef42,
- 0x2a0f9f82, 0xcf000c69, 0xc6777800, 0x921edb5d, 0x21f02bb7, 0x39fb91ec,
- 0x7c50a63e, 0x93bf3cc3, 0x1cf768ec, 0x31f0ca5b, 0xe902b8cd, 0x0c65d3e1,
- 0xba2ec21f, 0xaec83b79, 0x90762efe, 0xce2e5fd2, 0xb09a7755, 0x8768ad4f,
- 0x29800036, 0xf37bae9f, 0x9fa00bc4, 0x358eef8a, 0xc04d3893, 0x2a563c79,
- 0x9e4e8ff7, 0xe4287a70, 0x2b0f6e3b, 0x93e00bfb, 0xffa1c474, 0xd8412eb0,
- 0xe9fc6c45, 0xf2eaff3c, 0xe8a8ccca, 0x89bdd96b, 0x009a619d, 0xc68f6cff,
- 0x4e760917, 0xe70955cf, 0x4825ba85, 0xffdfc91c, 0x87c41878, 0xf9dfcefb,
- 0x3f03dfbd, 0xe302217b, 0x3257977f, 0xa6f2ef7b, 0x7c079881, 0x0549c791,
- 0xde1c961c, 0xce17b6f6, 0x1c31d35b, 0x7f7246af, 0x1db687bd, 0xe2633bd5,
- 0x3caa0e41, 0x2c57463a, 0x1df6219e, 0x42e96fda, 0xc03ba6fe, 0x0a4face4,
- 0xfa4ebcc7, 0xb8c080fb, 0xe302524e, 0x7e0e42c3, 0x2d6afdcc, 0x17d8a5bd,
- 0xc4b42bf3, 0x3d60b3d8, 0xc1bac31f, 0x1691f43f, 0xbbf835f9, 0xa548ce21,
- 0xee89492e, 0xa3881ebb, 0x3881bd6f, 0xc99e2dba, 0xf694a583, 0x62cd3f30,
- 0xcef9802f, 0x79e1b8f3, 0x1f3a771e, 0x2350e2c9, 0x5f1f19e3, 0xe44dfbca,
- 0xf110f9e5, 0xd9ddf16e, 0x35618366, 0x9b1feb5d, 0x36756189, 0xf567f125,
- 0x339f988d, 0x67abed8b, 0x39f305af, 0xf8aabf45, 0x8eb0a5d2, 0x18c71621,
- 0x9eb61728, 0xa9fa05d1, 0xa83f607b, 0xf57db04f, 0xcc52b184, 0xb95f1557,
- 0x3ce01e34, 0xec788bc3, 0x75108fad, 0x33df8e07, 0xc24ff19a, 0xfc7510fd,
- 0x5b8a85fc, 0xa55e2f5d, 0xe6cefb8c, 0xefb889e3, 0x9914362c, 0x73bee3cd,
- 0x0a4d640c, 0x91db9f6d, 0x48d5ecc0, 0xdc5900d7, 0x537115d7, 0x87417771,
- 0xb8fe693d, 0x889bc6e9, 0xfe20fe9b, 0x7f4dc796, 0x6e241f10, 0xbfa78caa,
- 0xb6417a0e, 0x980f0f1f, 0xd42adc19, 0xcfe0e5b5, 0x6090bcbc, 0xe901731e,
- 0xd028ecf7, 0x89688eb3, 0x137c8adb, 0xe1ebe3f5, 0x22a1ce2d, 0x39df9956,
- 0xd603589c, 0x968ce49f, 0x0ee351d5, 0xa94c0fc8, 0x4ff5964e, 0xfb27ec6b,
- 0x9069a33e, 0x55d33dac, 0xad67ab28, 0x7df643bd, 0x5932d6ff, 0x7773e07d,
- 0xcdbfbecb, 0xbf56593d, 0x7e40ff0c, 0x767e46a6, 0x65fbb6fb, 0x1d1c97fd,
- 0xddca7e82, 0x9712fe5c, 0x287733bd, 0xfac0a373, 0xcbe6daf3, 0xc91e23c6,
- 0x45f6d123, 0x23174f1c, 0x85893dd9, 0x3f9fcc9d, 0x6c997db8, 0x2d751afc,
- 0x47194fe2, 0xc3be242c, 0x96ea3f98, 0x37d21e6c, 0x7db4b8ae, 0x9ebbf633,
- 0xfafc227e, 0xb14de207, 0x24c91748, 0x92b3d199, 0x70bd8c1e, 0x05197b80,
- 0xa3b3c064, 0x20f4648a, 0x1b851bc3, 0x6f2ea9fa, 0xd1de6137, 0x700ba392,
- 0x3944fa3d, 0xe559843d, 0x239110f4, 0x4d9307a7, 0xe1a8ff8e, 0xe12bfc72,
- 0xe9cbb16d, 0xffe97881, 0xcc7780d7, 0xfcbd3978, 0x1ddce0ab, 0x1c81e3cf,
- 0xd90e43be, 0x37088c5b, 0xec243f96, 0xa3b73d7b, 0xcfdcac49, 0x7fa7f425,
- 0x1578f3c6, 0xd5f8471f, 0xb42e48d7, 0x66e37bcb, 0x9ee93dc3, 0x1bcfb04c,
- 0x38f3f309, 0x41c50954, 0x7bf884fd, 0x80a13f28, 0x67ae54eb, 0xfa3b10d6,
- 0xfc4117a5, 0x2b67969b, 0x677fa297, 0x1d69f189, 0x9938bff4, 0xc4d563e9,
- 0x7afdfc8d, 0xdc256ff1, 0x01252f40, 0x1c25547e, 0x63c90ea5, 0xe5c33e02,
- 0x10e93240, 0xf2c9c072, 0x12fee5f8, 0x00b2f102, 0x5ef4253e, 0x9f80be31,
- 0x7c625fe0, 0xe059f83d, 0x19f8281c, 0x45e391c9, 0x63815fe9, 0x181a1860,
- 0xc092b12f, 0xafd28af8, 0x50a7f7e2, 0xa7ce92bb, 0x216cc8ce, 0xcc436f14,
- 0x15d7f476, 0xf099ce93, 0xa0a7f0bb, 0xd236e17f, 0x29085feb, 0x8f13ae9f,
- 0xbc92e29d, 0x8df667cf, 0x2eb88ac3, 0xbfe7c305, 0x49479da7, 0xe4f7c456,
- 0x01c60737, 0x2ff5f51d, 0x45be4eda, 0x7cab51c7, 0x3f7e8131, 0x4f7f5fe1,
- 0xee7ee2f2, 0x48c7f623, 0x4f519e80, 0xcccec6da, 0x952eff04, 0x3250918b,
- 0x5769143f, 0xf41ad9ea, 0x4ee8aaff, 0x486bde80, 0xd3329c40, 0x75758edf,
- 0xe68dfadf, 0xc13afcbb, 0x2cbd9dcc, 0xfe70935f, 0xd0c3ec27, 0x7d7c98f6,
- 0x330b8c0b, 0x82fbfa25, 0xc0dc75c0, 0x037e453a, 0x7884e3dc, 0x9f2a26c6,
- 0xb04bcf51, 0x17515ea2, 0x3b13ea7e, 0x99d4567c, 0x36d7a81e, 0x0301a8e8,
- 0x7aebf8f6, 0x936c9716, 0x4c3fcbeb, 0xa12ef960, 0xa8f3c0e1, 0xf5cc7614,
- 0x47911df4, 0x16e01135, 0x944b3eb0, 0x9f803fe3, 0x9ef49da4, 0xfefe5493,
- 0xcc2eea15, 0xaedcbc13, 0xf54efbc6, 0x1fc85da3, 0xf1aaf7ea, 0xe8777508,
- 0x756f3ef1, 0x93d441fb, 0x03299aba, 0x85c97aa2, 0xe6b33a66, 0xec57f01a,
- 0x207d9437, 0x4c5e8df2, 0x9f33fce0, 0x2be607e4, 0x8af83e51, 0xdaf60f8c,
- 0x4a79bdad, 0x93e304af, 0x28dcea15, 0x9bdae7b8, 0xa5f1a287, 0x8fc00e4f,
- 0x720f1f72, 0x1a37e43b, 0x5d025b47, 0xd4ce99d7, 0x0abc6067, 0x64e1c775,
- 0xc90acf80, 0x12b47106, 0xa87fbb3d, 0x35b72f57, 0x0375d806, 0x203b521f,
- 0xc57a795e, 0xbf70d183, 0x503b8c59, 0x393de152, 0xf67d7642, 0x9f8822fd,
- 0xa3adb2cd, 0x667ad9b5, 0x2f7e6657, 0xcf4593c2, 0x763a3bd7, 0xafdb4b3f,
- 0x7dfef311, 0xe3fa3516, 0x0c64d562, 0xaf5885d0, 0x7e2857b8, 0x70cefb87,
- 0x5efc4d7f, 0xf21be2d2, 0x071f2d00, 0xaff62cfa, 0x37dca4af, 0x87e8d1a4,
- 0x6e9c7d7b, 0xdd45e80d, 0x443f2606, 0x6b31159e, 0x30ad7cf0, 0xaa75f3b0,
- 0x3d9bb0bf, 0xeabfb026, 0x9851ecc3, 0x9a91f5e7, 0x17f95d80, 0x82ca3db3,
- 0xdea2b3fb, 0xfaccc2b9, 0xde7cf375, 0xa1969f15, 0x12d7165d, 0x7ce8cf3c,
- 0x6a9fb302, 0x7964a8af, 0x0f1ab546, 0x5ed50be6, 0x913e61d1, 0x148ffdf8,
- 0xfe01ae0e, 0xd9f3fcfa, 0x0b5d6163, 0x7c0d6d88, 0x046d60bf, 0x21e80571,
- 0x8958af22, 0x7c71efff, 0x44345bd7, 0xe7ef1833, 0xddf5ae3a, 0x0754ff5b,
- 0x9d12efbd, 0x5c71cec8, 0xa5ebcb39, 0xe1c60576, 0x2585df94, 0x6cfc8a4a,
- 0xecafde2f, 0x5bdb07cd, 0x61ae409a, 0xb15fd7e7, 0xebb3f2cb, 0x57e87f69,
- 0x228c657f, 0x4b8f9b3f, 0xfd1ab3c7, 0xe0a16079, 0x6604bdff, 0x9e43d4df,
- 0xdfc090d7, 0xe7f8fd19, 0x5b79e589, 0x7f3848de, 0xe3576f3f, 0x1f9fe3fd,
- 0x12df8d51, 0x12c3dd64, 0xc506dc19, 0xdc5cf069, 0xcdf621ee, 0xdf17e641,
- 0xe205fb89, 0x7d729c7e, 0x73bccbbb, 0xc6c3fd60, 0x72aeff30, 0xec89419c,
- 0xddeeb13b, 0xf51f0cd1, 0x607c536f, 0x9fcb08fe, 0x5ded1ddd, 0x2cc0fc8c,
- 0x8e7cf3c7, 0x7b77dde7, 0xcbbef1d3, 0x0e7ecc5d, 0xcd570f45, 0x4f8007ce,
- 0x42374ed4, 0xaa19192e, 0x01cc9469, 0xf47aebe7, 0x4abb87e0, 0x70bed786,
- 0xc57e21d7, 0xffdf42b8, 0xc63539f2, 0xc63cbff1, 0x1bb12dcf, 0xf77c80a5,
- 0xebf3092f, 0xa12ad97f, 0x49df3f9e, 0x2fe51348, 0xa0d6b6f3, 0xa5f8b85e,
- 0x03629821, 0x7ca4afbf, 0x21225e64, 0xfe72d277, 0x775c796a, 0x7e3efae1,
- 0x7f281239, 0x94469117, 0x969f8b17, 0xeb26abf7, 0x837a0cff, 0x3e8cde32,
- 0xcf176a4f, 0xf77ae44e, 0xf8143250, 0x7d2f03fd, 0x86b48ba5, 0x94f3ffa6,
- 0x806b669f, 0xecb01aaf, 0xb963366a, 0x28bed13c, 0x39a5c291, 0x089d59d1,
- 0x188f8cfe, 0x5ed72e3c, 0x2e00f266, 0x7e008e4f, 0xd33ca12d, 0xd8f164cf,
- 0x723dc21f, 0x9ebd0f0a, 0xd47575c9, 0x7093c9ca, 0xff846e95, 0x8e79af30,
- 0x2d8de505, 0xf63de811, 0x63c6e317, 0x222fd75e, 0x75bf00ec, 0xc197eea5,
- 0x556eb08f, 0x0d71fa38, 0xce0f167a, 0x82aa5eda, 0xedb703fb, 0x1f83f696,
- 0x5563a1a3, 0x37efdc0e, 0x8f31c35a, 0x5e63aa20, 0x6c639326, 0xc716d89e,
- 0x2c67c04e, 0xeba36bdc, 0x4ee9975a, 0xe99a7c64, 0xf61cf539, 0x3ff5923d,
- 0xebb39ee1, 0x21ef1aa8, 0xbcb0d65e, 0xe18441fa, 0xc12be455, 0x5cfa81dc,
- 0x241b8517, 0x939ef5d5, 0x8da3c936, 0x301c77c4, 0xa8fb50ce, 0xc8267e27,
- 0x30699f9b, 0xaebbd34e, 0x20ca9277, 0xcce4231e, 0xfcccc94c, 0x9d5f5c42,
- 0x2c7fc441, 0xe9c5539e, 0x53d70661, 0xf8304667, 0x74b627ce, 0x81bf77e8,
- 0xd1e8aa44, 0x56de5999, 0xd1abfb8c, 0x116f405a, 0x7ad08971, 0x4e7f7042,
- 0x7626cbfd, 0x0df2521f, 0x682e4180, 0x79d6b909, 0x43f9c3db, 0x97e600fd,
- 0x0ec4d925, 0xb7fab071, 0xf8866e07, 0xc59c3e87, 0x321f2959, 0xef277bc0,
- 0xfba63c82, 0x1856fa5e, 0xdc42bf7b, 0x0bdb3687, 0xc3617ee0, 0xcc42d4e4,
- 0xc3e9385f, 0xb5ba0877, 0xaf3c74de, 0x5448bf94, 0x38987e06, 0xa50d1eef,
- 0xaa64faf3, 0x3ffad16f, 0xbd581b12, 0x8ab1779f, 0x3d2407d6, 0xbc83eace,
- 0x4b6ea0e7, 0x0d1efa7a, 0xf42b63dc, 0xfad3562e, 0xac2da484, 0x324b060e,
- 0xcfd26f85, 0xf1d171ee, 0x3eb8582f, 0x3de2f363, 0x0737fad0, 0x84fd02aa,
- 0x7f189263, 0xbec610ba, 0xe64990bb, 0xe778064e, 0x873eff04, 0x5cf42f7f,
- 0x9fd15fb1, 0xf7ef0624, 0x4b7b9719, 0x92d03df9, 0x8c36b208, 0x915c95c5,
- 0x3a870f14, 0xec5c6206, 0xcb346240, 0xf17b35df, 0x8e31109d, 0x4f18a780,
- 0xe40cbbcc, 0xc9f311b0, 0xe2f964aa, 0x79d27e5c, 0xd93ce356, 0x727f7676,
- 0xe0016a72, 0xc34de28f, 0xbc01a6f1, 0x30d77b89, 0xf91f25ae, 0x43f010fd,
- 0xbf4aba1f, 0x5baff4cf, 0x38572749, 0x616d2c9d, 0x259f40f1, 0x24a9e90b,
- 0x513bbf82, 0x04c7df24, 0x4931bf0e, 0x5ecfb616, 0x384824bc, 0x63870b4f,
- 0xe4c077aa, 0x77df9bbc, 0xcf5b1278, 0x0077dead, 0x7ef0ecbe, 0xdbf6a1c4,
- 0x30fdb0b6, 0x473d017c, 0xa4f75ea3, 0xab0bbc6c, 0xd387fd14, 0x8dfb0903,
- 0x3ffec2ce, 0x100defe4, 0x5fb7a5b2, 0x3fd33e66, 0xf7152f41, 0x4eeb89e4,
- 0xed17e812, 0xc6df0fbd, 0xf7faadee, 0xdf114f79, 0xd3ef99a7, 0x96e9f6cc,
- 0xee392bd1, 0xea6a9f4b, 0xf0bdc74b, 0xb72f1def, 0x3b278f90, 0x83c6c1e7,
- 0x2f0a1d73, 0x316e93a3, 0x2a758a3d, 0x670bd9e0, 0x3c04fac5, 0xbf637ce1,
- 0x8a5d395c, 0x9d42da75, 0x38efccef, 0x57eb295f, 0xbfcb30f7, 0x5d395625,
- 0x54ceedd7, 0xf45bdc41, 0xee3e0a3b, 0xcb5fbf38, 0x98e3c499, 0x443524a9,
- 0xa4c2dcde, 0x30fea0b8, 0xe7695dfc, 0x3e5858f5, 0xefded2b2, 0xc275b389,
- 0x25d7343d, 0xa47a7f76, 0x71013fc2, 0x7f465d92, 0x917cbf3f, 0xf87177d7,
- 0xf8aff5f5, 0x91677ef0, 0xab35ecbe, 0x9bff908d, 0xebf20ef4, 0x07b2a8a2,
- 0xf57d6933, 0xdfc8fd86, 0xbeca528b, 0x7cfca4ca, 0xac0386cd, 0xafb2f6fd,
- 0xe93d41fa, 0xd897ab20, 0x4f7e035f, 0xc67bc1c8, 0x88f5f924, 0x7159261f,
- 0x0ab9755e, 0xd5eadfdf, 0xa3d1de5f, 0x1ae022fe, 0xabd22caa, 0x9fc5831a,
- 0x81e97b5a, 0xc38609c5, 0xa790ad3f, 0xaf78edc4, 0xf7c76646, 0xaffbb244,
- 0x86fefb3d, 0x4f9e19f7, 0xf004fe72, 0x35d110d0, 0x1fd69327, 0xe30cf88d,
- 0xea9d9250, 0xb0c7e021, 0xba2cc99a, 0x9d6ba95e, 0xb225f403, 0x20d066cc,
- 0x075fb95c, 0xf0a2f4de, 0x9fedeb7b, 0xa6c2923d, 0x463ac071, 0xf0d03e70,
- 0x435f37f6, 0x82e1b2dc, 0xe1ea06d1, 0x0f0d8e88, 0xa235be82, 0x30dfd7e3,
- 0x5feecc39, 0x008f7588, 0x7dfd1dbf, 0xd71ebb78, 0xb6e3a23f, 0xc8fdf045,
- 0x016476df, 0xe53e8c9d, 0xd0b60169, 0x148defb3, 0x2fcdfdf9, 0x186f99ae,
- 0xe0248e32, 0x54aa27f1, 0xde3c2145, 0x8ab8f060, 0x71dd51f9, 0xd178d6c7,
- 0xdfbf27b9, 0x8c76f542, 0xe1265e83, 0x8bd3f036, 0x7f4ac57b, 0xba4ac9e0,
- 0x68fbfa3f, 0x80415d1f, 0x85725cde, 0x7a01ffda, 0xc8b12978, 0x2486e5ea,
- 0xe615f7d9, 0xb8fb594c, 0xed64dbc4, 0x640b5977, 0x233909f5, 0xb44fdf64,
- 0xf7eaca95, 0xf64bbf0e, 0x52bda57d, 0xb4f02f56, 0x721fbec9, 0x7ede5da4,
- 0x0f01a89c, 0x076d2785, 0x6b3e2ca1, 0xd0e2b747, 0xa1078df3, 0x0617f11c,
- 0xf43fa50e, 0x076d2b8e, 0x0fe177e1, 0x1157de55, 0x6ae9d1fe, 0xdc175ba3,
- 0xa1a89a0f, 0x8bc925e5, 0x62ad44fc, 0x305e55f7, 0x6f01bb39, 0x094abee2,
- 0x122943f8, 0x625ee62a, 0x3167b2f7, 0x4049d87f, 0x19a7f00c, 0x9de3f426,
- 0xfabe36d4, 0x4ec7167b, 0xda37be03, 0x77db2557, 0x6ca715c9, 0xa964a5df,
- 0x65cb4f02, 0xc3f30af5, 0x25c7efb2, 0xdfb592ae, 0x815c7d65, 0xf56527a7,
- 0x0a0db689, 0xe0566d3c, 0x76b267e9, 0xdc1ddf41, 0xf836f53f, 0xca396895,
- 0x780e59db, 0x0fbcf3b8, 0xb3bc31f1, 0x74f01cb5, 0xc436c9c7, 0x51c79157,
- 0xe872ec0e, 0x5083c691, 0x05fda87a, 0x27340efd, 0xd9a87962, 0xc3a9fe8a,
- 0x1e5839cd, 0xefe1b669, 0x8e1e6abf, 0x76cdfbe5, 0x3cd37f2c, 0x66cecb1e,
- 0xcd6d9607, 0xaefdf86d, 0xdfe676e6, 0xd7bde98a, 0x807e069f, 0x1eb7956e,
- 0x27643eee, 0x7e044ec7, 0xedee1dd9, 0xaea3fa86, 0x2fc089e8, 0xa1130007,
- 0xcbcf9c78, 0x3df629b1, 0x0dbf94c9, 0x91756649, 0xb2a6d057, 0x5e1e8017,
- 0x09e331b2, 0x8f211a4d, 0x9a2472ad, 0xa06eac2d, 0xe6364475, 0x613c655b,
- 0x55e4254f, 0x60772510, 0x7bd4227d, 0x90fb58c2, 0x4113198d, 0xf1ceff0f,
- 0xbc9f7b60, 0x20e492c0, 0xcf57e0f1, 0xbfe04d5b, 0xa0757639, 0x8c71e009,
- 0xa4ecb1fb, 0x968f3b40, 0x2d029aa5, 0x0a93d9c8, 0x3d9444bd, 0xc9f1d2aa,
- 0xdb6fb071, 0xbe43cc34, 0x7e804b5b, 0xdecc4b27, 0x4ff5df15, 0x1317f9e1,
- 0x1d4f68f5, 0x6117d957, 0x7be493de, 0x64bce001, 0x7b8410e3, 0x0e97c98f,
- 0xb1b45bf0, 0x7ce3d590, 0x80b6482f, 0x67c196ba, 0x8982c6fa, 0x0a5bdcae,
- 0xe0c1059f, 0x666c9d53, 0x9ec7b6fa, 0xa8807a06, 0xd7b4af1f, 0x5e3e79c1,
- 0xa2fbc76a, 0x767a1cc7, 0xbc261d7e, 0xf63440e7, 0xfe0169e2, 0x5ac9b39c,
- 0x2e1537ec, 0xf35f819e, 0x739e357e, 0x29553c25, 0x3a470f4c, 0x46733b01,
- 0xc705da04, 0xb7deec55, 0x14ccfbf2, 0x0c5d1f66, 0xeb77ee0f, 0xa6cbdbc7,
- 0x87babdd4, 0x22b3d78e, 0x71ee870c, 0xac7d440c, 0x7bc251a7, 0x1be73db5,
- 0xbd76b12f, 0xe304838d, 0x5fe13392, 0x8ed5fdb4, 0x31faff07, 0x15b3fefd,
- 0x21943611, 0xbf0841e6, 0xb3c7f9fb, 0x3fa80c63, 0x569c9ecd, 0x26717206,
- 0x31cd738f, 0xdc31e269, 0xe0e8b1a5, 0xc685ba09, 0x82143582, 0xa56c7164,
- 0xa9cc9e0e, 0x06be5d4e, 0x4fd965ca, 0xf0ada2ea, 0x35ced77e, 0xd1d6c6a0,
- 0xfc8c5c23, 0x3341fbcf, 0x26dcd75d, 0x73d995b5, 0x6bdaae5c, 0x433f2a6e,
- 0x9e71efd0, 0x8081432f, 0x87166af6, 0xc597e8b7, 0x325b74e9, 0x91e4138f,
- 0xa7df763c, 0x1db00e37, 0xf66ba4e8, 0xc4420307, 0x5cede409, 0xc744fc7f,
- 0xbbbe55e6, 0x4ecde620, 0x71fe7a61, 0xd04ca51d, 0x7267ef27, 0xabeabf20,
- 0xfee98b47, 0x2acc3bf3, 0xadcfc38c, 0xb87803db, 0xa8f1cedc, 0x9e70ed25,
- 0x7de6b8a6, 0x8a4ab986, 0x93d79a7b, 0x734eb697, 0x2cbca079, 0x03ca3af2,
- 0x5f70e5e5, 0x45c8396b, 0x7c451f21, 0xcd5cd3d0, 0xf22372f9, 0x4dcd43d3,
- 0xecdc3f58, 0xf348f2c2, 0x5b97ce5a, 0xe6fdfdb1, 0x765f38e7, 0x0dbcbe73,
- 0xae68ef7f, 0x66edf2c2, 0x28969627, 0x7e016fc7, 0xcc4e0d53, 0x83777bef,
- 0xeb7c409e, 0xf31e8772, 0x7889e80e, 0xc858f9e1, 0xbde3d1a7, 0x8d5e653b,
- 0xd2f7cf92, 0x25f7df43, 0xf4f300fe, 0xbe80c3e6, 0x9e9a1198, 0x09ab118e,
- 0x92dfd2f8, 0xbe82269b, 0x356acc7d, 0x657d3e81, 0xa5f21363, 0x49ab7663,
- 0x24dfeb4b, 0x9ddacc3f, 0xd69e9356, 0xc3e37bff, 0x3565ddac, 0xdffad185,
- 0xeacfbf93, 0xc482c26e, 0xe7c8cd29, 0x0874894b, 0x21b947ce, 0x17150c73,
- 0x1e975e54, 0x2e317382, 0x3818de71, 0x56c97517, 0xacbb8fa4, 0x7d410eab,
- 0x0d66ce42, 0x1bb6c55c, 0xbf43560b, 0x0d4ad8b2, 0xba931bf4, 0x1bf4357c,
- 0x26a4fd9b, 0xdcf8dfb0, 0x7ea1ab9d, 0x06b36d8f, 0xce3ad3f4, 0xa238c4c7,
- 0x9f05da2e, 0x835e7916, 0x0f281c3b, 0x281ddbf2, 0xca5c040f, 0x063e56a6,
- 0x7686c77e, 0x3ac12cc9, 0xc1bd4aa6, 0xab91c86f, 0x291af787, 0xfe7a8ebf,
- 0xba2ad309, 0xdfa806cf, 0x5627f581, 0x9dfe5add, 0x97d71292, 0xe7e09f7f,
- 0xe43de41d, 0xb1d09f65, 0x001e32f7, 0x7de314b8, 0x2bbe1334, 0xd0269c49,
- 0x3cb89ab3, 0x6d25095f, 0x3bebcedf, 0xd9579c85, 0xdfd0a7fb, 0x7db85373,
- 0xd83f97d9, 0xfcf41d60, 0x8439ee2b, 0xa1fce768, 0x7b2cc530, 0xb08ea15f,
- 0xcbd7557b, 0x31e6531b, 0x9629f32b, 0xf6c3b691, 0x1479becc, 0xc7bd84b5,
- 0xae4fcca2, 0xad5eec27, 0xd7b94f32, 0xfc670aae, 0x0d780ab4, 0x2989e3a5,
- 0x6564f921, 0xe135f14a, 0x910f6f20, 0xb094bd97, 0xf93eec3c, 0x5b1f3c35,
- 0x8ce22fb9, 0xf25def63, 0xfee56cfc, 0xddf45d04, 0xbf832b5f, 0xea9fc186,
- 0x7d600b77, 0x044d7315, 0xfc8156fc, 0xf06be3e7, 0xbb3f251f, 0xfa727c55,
- 0x9f763adc, 0x6b1f2fbf, 0xc7c2094a, 0xb2975e44, 0xdc2a7a14, 0x3efc831b,
- 0xec060f78, 0x9c123bfc, 0x3d97402d, 0x55afbe65, 0xb2c68760, 0x2dbb93f7,
- 0xbbf035ce, 0x03f963a4, 0xbcf6af22, 0xd04bf5ca, 0xf94a9edb, 0x6ebbf215,
- 0x8cf41610, 0xe075a3ac, 0x8e2c4367, 0xe48fd0f5, 0xef817578, 0x1fca8730,
- 0xe1cb9a7d, 0xe59125be, 0xfe6cf655, 0x0fde86e6, 0x0a8f050a, 0xdc2f28f5,
- 0x3c3cb85f, 0x9767e502, 0xfef03c44, 0x3c69576b, 0x695d2dea, 0xb7940d3a,
- 0x4aee2eda, 0x2be3801b, 0xa4aee3ed, 0xef3606e1, 0xfe50f1d8, 0x115ce926,
- 0x790fbdc8, 0xcebb613e, 0xe037e435, 0x86111e1f, 0x257bfa71, 0x41c0116f,
- 0x1d775769, 0xcd66559d, 0xd35f6bef, 0xfd818dfd, 0x3d519ed5, 0xacddbf06,
- 0xf4db5dbd, 0xed3c8135, 0x09574d91, 0xbcdf8fe4, 0x9d19ddfd, 0xc2bd056f,
- 0x322402d9, 0x13ea8bac, 0xfcbd7eb4, 0xb5124ba4, 0xec0333d3, 0x66bfe1f2,
- 0x54bc4a79, 0xde7de7da, 0x92e65b4b, 0x7a95c3e7, 0x44df318a, 0xfbc48ded,
- 0x9ef62aaa, 0x7a57c882, 0xd4f3db8f, 0x829b3f5e, 0x74ceb87e, 0xfdfebd99,
- 0x823ce74f, 0xf30c207c, 0xff6d5e33, 0xfad60e3c, 0x9fb8ce87, 0xd3f565bc,
- 0x6bf98377, 0x5f679812, 0x565974db, 0xed7ee2ef, 0x2fbb2d56, 0x354ffb54,
- 0xc72a25ca, 0xc89e22d6, 0x0103dd01, 0xfdb495f2, 0x83de17b9, 0x04abbf29,
- 0x1d7ca180, 0xfb4ec939, 0x887b7255, 0x9d587790, 0x95c48fdb, 0xe271eac2,
- 0x7ab31ffb, 0xa9fef89a, 0x4f3a7649, 0xe7689265, 0x75e36ffd, 0x33d58797,
- 0x647ff7c5, 0xbb589bdf, 0x498ed37e, 0x3f05ce70, 0xdfcaa537, 0xddfca201,
- 0xcd7c5a92, 0x3b791a7c, 0xdde2ffe7, 0xdfef8a9f, 0x9c01f115, 0x730936d3,
- 0x6a576ae7, 0x317f5fd1, 0xf03f2dba, 0x7791507d, 0x613728e3, 0xebdd541e,
- 0x0b80b703, 0x1e3a6d53, 0x44ca7a0f, 0xa154ff9e, 0xe59c6236, 0xc7c67af2,
- 0x8b79e943, 0xe194de9b, 0x7f3b4fab, 0x9103178f, 0x4f4bbe74, 0x90f7b024,
- 0xee313bb3, 0xe995383f, 0x22bef0f1, 0xf915e7dc, 0xc459b15c, 0xec71f60e,
- 0x5dec611b, 0xc89db3c8, 0xc1bf175f, 0x1b75d7fc, 0x9b3ca20e, 0xffa2b6af,
- 0x673f5c68, 0x47c42a71, 0x30039d4c, 0x36f4ddee, 0x673fc39e, 0xcb9c7998,
- 0xcf081b97, 0x5fe17dd1, 0x97f81d7a, 0xbfe13bfe, 0x180dea9b, 0x8613dae7,
- 0xc6826cf6, 0x1c41b3ab, 0x577b24f3, 0xdb872172, 0xe23fced0, 0x7887ff7d,
- 0xc59daa3d, 0x959e4469, 0x54a1f798, 0x8f038313, 0x7e4dd487, 0x43c4147f,
- 0x224afe04, 0xb7f81b48, 0x1c6c1e29, 0x83c0360f, 0x2e3fb780, 0x0665fb42,
- 0xbd956b8e, 0x1ee02b5f, 0xe92b1cea, 0x195bac43, 0x3c665827, 0x5df80c54,
- 0x81799376, 0xbe38d297, 0xfbcc5e35, 0x410673fb, 0xb8f028b9, 0x5dde2fb2,
- 0xc4d771a9, 0x5ffdbcbb, 0xdc25778c, 0x8f2d6594, 0x7f7f297b, 0x2ff55521,
- 0x36ffe385, 0xc6ecea7f, 0xb9f6b2fd, 0xc86f474d, 0xa0fc2adf, 0xabbf2eff,
- 0x7a4eb7f0, 0xe20a896d, 0x7c7b4a32, 0x6be3ba5a, 0xdf7bbfa0, 0x09ee47fc,
- 0x00f57c58, 0x90793fcc, 0x51abe5ef, 0x11ecfb7f, 0x355f4f4a, 0xa9d43f32,
- 0xad6a5ffd, 0x63e97d79, 0xb11515f6, 0xecd5d007, 0x20b48fa6, 0xcd5366af,
- 0xea3c5822, 0x309e9cef, 0x81f2847f, 0xc6d1032a, 0x555ff3d2, 0xae73dec5,
- 0x344bc082, 0x6d271e96, 0x1e21a49f, 0xd2b5af78, 0x31e8f1a8, 0xb7bf241e,
- 0xb9efe7aa, 0x7652c352, 0x576d557f, 0xb4d37e63, 0x748e2ce1, 0xef0db1bf,
- 0xf238ce25, 0x6847a5e8, 0x2aed593b, 0xe2b77966, 0x54efd19e, 0xfa1f1337,
- 0x7e612a7b, 0x1dc78954, 0xee316b97, 0x61f7eca8, 0x4d63f32a, 0xbf2c4b52,
- 0x4fcb2f60, 0xee91e713, 0x90be88ef, 0xbbc3c1e5, 0x5a8d95a6, 0xd07cc0cf,
- 0xfea3f63f, 0x557c30d1, 0x61afe03e, 0x9f46748c, 0x1b03d7ef, 0xfd82fe9a,
- 0x5958fc95, 0xe9dfa8de, 0x4823e6b3, 0x3c5f422f, 0xbac1ecd5, 0xab350fd2,
- 0x6e303fe4, 0xee2fe233, 0x5e472816, 0x66189fb5, 0x95f6eefd, 0x9d84abb0,
- 0x04dbb4a5, 0xb5ef10bf, 0xc3fc140d, 0x777b11f0, 0xbccac351, 0x15ff3934,
- 0xd9f2957c, 0x7f8c3482, 0x006ff9ca, 0x7ff6c61f, 0xd3f61f17, 0xfc0da37d,
- 0xeca95535, 0xdd25737d, 0xf93226d7, 0x7577a4a9, 0x19f51ab9, 0x3a0bbd25,
- 0x19becfbf, 0x20b375fd, 0x31d74f56, 0xfbc241ab, 0xff5f2752, 0xba0643e1,
- 0xa7b6ae84, 0xe8f7b2b4, 0xfbee926e, 0xe9b381ca, 0x9677df30, 0x9c33a403,
- 0xf8665bdd, 0x47d69458, 0xbb4d2e8e, 0xb7951cb6, 0x17f18bff, 0xbe73ff64,
- 0xca241c9b, 0xd473057b, 0xd39f362a, 0x213ef2c8, 0xcdc7acef, 0x675579ee,
- 0xd37be2b6, 0x122fb864, 0x7dd2c8f8, 0xc58eb26a, 0x01493437, 0x117508ef,
- 0xe92327cf, 0xb1464bef, 0xf9943877, 0x4f3cf598, 0x37719973, 0xbe5213de,
- 0x3df22407, 0xca78f9eb, 0x7f448177, 0xf9582f71, 0x34c6d02e, 0x90ad7f7e,
- 0xf838b214, 0x3753f9b5, 0xff00c9c8, 0x66d5f770, 0xa4b673b4, 0xae47f1fd,
- 0x6f3c7e51, 0x3e7ee34b, 0xbf6c5d3f, 0xff6c5d0e, 0x6a1749ff, 0xef7c56d3,
- 0xe2e966e3, 0x3f7dab11, 0x8f9c5bac, 0x96fc73de, 0x78b1cf1e, 0xf967b80f,
- 0x471ef8ab, 0xe30437cf, 0xc3f3d740, 0x6bb17494, 0xbacfa33d, 0xaf144c5b,
- 0xd0b94f23, 0xb8e2303f, 0x0dbfef13, 0x990edf7b, 0x90e0a4c6, 0x16eb0d43,
- 0x1bd0827a, 0xdf80fcfc, 0x1d79e153, 0x6e37ca37, 0xaff1be36, 0xfb886b8a,
- 0x4f5add32, 0xdb9009f1, 0xbe82c37b, 0x8d257d97, 0xef50edc9, 0x9ca25a6e,
- 0x534f0057, 0xef15df38, 0xd9a8566f, 0x3b97b93b, 0x589fe8d5, 0xfedf83f1,
- 0xdf6b79f2, 0x58fa95f1, 0x5072f983, 0x0d9446fb, 0x5f2f962a, 0xbcc56e58,
- 0xc07bb02c, 0x17fc215f, 0x5847efca, 0xd1d3c2cb, 0x69d51ede, 0xc73cf587,
- 0x5f0a13d6, 0x123e4d0d, 0xa87ceef8, 0x15f61bf9, 0x9c07e79b, 0xbde9098f,
- 0x9cf99676, 0x1bef8fc1, 0x6dff8ba5, 0x3524fffa, 0xfe544971, 0xa66e49e6,
- 0x57a6124f, 0x589d22ce, 0x2c3e21ce, 0x4fe5849d, 0x2c3627cf, 0xaef61217,
- 0x670ca1f9, 0x8de83a49, 0x0fbe1f5a, 0xbff5e97b, 0x4cfbe2e7, 0x856c8e77,
- 0xe55ba89c, 0x55ea56b7, 0x8fbe053d, 0xd8ff03a7, 0x2b74f7f3, 0x7b1bffca,
- 0x94507aa7, 0x107a4a7d, 0x4a6ff6bf, 0xc4beecd5, 0x5e5107c9, 0x1f599a54,
- 0xfdf98632, 0xe2642627, 0xcdf3f1f9, 0x6f82cd84, 0xef2afc42, 0xdfc58a8c,
- 0x77f84a97, 0x2abdda79, 0x8b79623c, 0xa86add32, 0x79ed66ef, 0x44b71675,
- 0xc22379eb, 0x8b72fb58, 0x67ddf21b, 0xcb9e2f13, 0xaeed90b9, 0xbd13bff6,
- 0x7bf9d880, 0x127ebe06, 0xc3a8bfed, 0x89b6f2c0, 0x9bf61b37, 0x1049760f,
- 0xe997f73b, 0xee0fbcec, 0xe0fdf8c7, 0xe15fb932, 0x267ede21, 0xe013aca3,
- 0xfb74bbf1, 0x0d7ce0f7, 0xf75cee8e, 0x53f81154, 0xc2fc0454, 0x18788c5f,
- 0x5fa228e3, 0x11ecb598, 0xc4876ef8, 0xfb5d8bf2, 0xd2dde2f4, 0xfc7f40f8,
- 0x55f28ca1, 0x74daddf0, 0xc1429fc6, 0x942efe15, 0x261d8823, 0x8306d5f2,
- 0x427e886e, 0xed06ef82, 0x437d5890, 0x577bd8fa, 0xe977d11b, 0xcc33fd02,
- 0xec31fcea, 0x108eb063, 0xbfffac23, 0xd219bdf8, 0xef710e98, 0x55e82f25,
- 0x4a7c5fa0, 0x27dc31c5, 0x63b53df8, 0xed4d3ca1, 0x40ff2851, 0xcf2851ed,
- 0xca147b50, 0x0a3da9cf, 0x362ba2e5, 0x14971c78, 0xce7fd867, 0xbbf83ce8,
- 0x33a62f1b, 0xc32679b9, 0xc75b29d9, 0x63ae1d3e, 0xc7f3a587, 0xec75d14f,
- 0x82ad93d8, 0xe0a12cfb, 0x6fefb3d1, 0xf820cee9, 0x93dfcdec, 0x6ccbe782,
- 0xefe7f3e4, 0xcfdca0d6, 0x2e46f76f, 0x3daef80e, 0xc878875d, 0x123673db,
- 0xf736efc6, 0xd12ed5c2, 0xb1524ead, 0x330bfb7a, 0x0b9d5def, 0x0277b0fb,
- 0xeef9e8fe, 0xfdbf3280, 0xfb863fb7, 0x8c7c741b, 0xbe48f6c7, 0x532f4067,
- 0x6fb943ee, 0xffba2fb1, 0xc77fd075, 0x13b07e9e, 0x3b086fca, 0xfbd8fb2f,
- 0xbbf77db8, 0xaf7bd70a, 0xf70457de, 0x56fdee12, 0xf41f341d, 0xc229464c,
- 0x99d056bb, 0xba71b788, 0xaefaf812, 0x1e395ae7, 0x0017ef11, 0x3c82b50f,
- 0xfa091aba, 0x5b8f2560, 0xfeceefb6, 0x1cb9ef10, 0x3bf81351, 0xe5a38381,
- 0xc19d4ee7, 0xf3289dce, 0x801ce9f6, 0xcefb1daf, 0x9cfbc365, 0xf0d93f14,
- 0x4abf5b77, 0x17f32fef, 0x66f88de6, 0xfd0fd023, 0xe02eff1e, 0x02b9b20c,
- 0x0d33f3e2, 0x2d85dffb, 0xa99f36cd, 0xdcfcf880, 0x9430e944, 0x6399acf3,
- 0xf22f2e21, 0x94e4179a, 0x74a3861e, 0xf512ad8f, 0x2e6052b8, 0xdca17201,
- 0xe71fc110, 0x46287215, 0x98971f56, 0x2efefb22, 0x7dac966b, 0xb2edce42,
- 0x26fbdef6, 0xdffe21b6, 0x7c3c01fb, 0x465e20fd, 0x8efec1f7, 0x7dec4bd9,
- 0xc73dbcdd, 0xd69dbeef, 0x0d3cbd27, 0xc1db63df, 0x2aed27db, 0xd623bfc7,
- 0xa3a9e143, 0xe1f9d48a, 0x14f33f8f, 0x13b0a60c, 0x78bdf76a, 0xbe67de18,
- 0x1d709dae, 0xfbd420fb, 0xd2bfa2a1, 0xf2fca03e, 0x072fc0c7, 0x0cd53ebf,
- 0x231da1f1, 0x790649be, 0xefc19994, 0x21bb7187, 0x9ef4dd14, 0x61fac90f,
- 0x2528fde0, 0x28f210dd, 0x4e5643a7, 0x01eec63a, 0xfb3f2cdd, 0xb433f013,
- 0xf0245dc3, 0xfd2a08ef, 0xb6758365, 0xff041f0f, 0xb86a07ce, 0x3f7bd109,
- 0x5bfc316b, 0xb277a7ed, 0x4963f370, 0x0bbbf8b1, 0xee7ae0f4, 0xc1959b3f,
- 0x76a4ace2, 0x454963ff, 0xe2b276fe, 0xb27bec8c, 0xab235a52, 0xd794ceaf,
- 0x09ae97d7, 0x0f4a1fec, 0x3cdcfc5b, 0xee0f339d, 0xff4149f1, 0x7aef626e,
- 0xd85f3962, 0xecf904b7, 0xf14bfdb9, 0xbf2ab9ef, 0x81e3a7af, 0x08716fdf,
- 0xd3f82af9, 0xcf7b350c, 0x4cbed957, 0xb5bb67cc, 0x614a7df3, 0x6f5c798f,
- 0x69fbb930, 0x93275394, 0x7f4c19eb, 0xc9e1b4bd, 0x710d7c1f, 0x9eccbda4,
- 0x726164ba, 0x17f77f23, 0xcc7bf82a, 0x7d19c383, 0x2abd9be5, 0x53d327b8,
- 0xbc82e11d, 0x26a586ed, 0xdc1bb7cc, 0xa189f7cf, 0xfc1f9080, 0x1a7fd0f4,
- 0x0efe7d28, 0xc805bf2e, 0xb9d01ee1, 0x8cf1fd68, 0x49872843, 0xb86fcb2e,
- 0x9c7cfb55, 0xbfa864ea, 0x317e3194, 0xcb8fe807, 0x55cf422b, 0x57a463c3,
- 0x021f017e, 0xc0fd40b8, 0xf0fbdf4f, 0x1e33f069, 0xfc02fc65, 0x0f513307,
- 0x7ee51bb0, 0x1ef63685, 0x0bbd9598, 0x4242f222, 0x87658ff1, 0x5760755a,
- 0xf1fe6ade, 0xc4f9f5f2, 0x8f1409b1, 0x3e597b0d, 0xfe8ee5f7, 0x6f802451,
- 0xf0d7e128, 0xb7cf0a9c, 0xa87777a8, 0x5079c3c7, 0x70164bde, 0xb201e626,
- 0x181e78f7, 0x20c9b7fd, 0xa7d81f97, 0x50f44161, 0x1155acf3, 0x833cc06b,
- 0x8e51e9f7, 0x98f7f589, 0xf7d91f39, 0x5cd2e8d7, 0x220aae56, 0xa01ea94f,
- 0xa03d058d, 0xf5bb4252, 0x65097de3, 0x258fff00, 0xe216b1e2, 0x3a2f9810,
- 0xbf070d85, 0x899df11b, 0xe04d1cc4, 0x6ec27afb, 0x5a6fb69d, 0x3f57d07f,
- 0x63ff3dd9, 0x69f2198a, 0x879e1646, 0x1f8ef0e9, 0x16c7ef85, 0x43f81a47,
- 0xeb78f126, 0x175f16c7, 0x8f1fd5e8, 0x6fc0908e, 0x0d5fc749, 0x7d7d8be3,
- 0x35a475ac, 0xed17fa06, 0xfbd3be83, 0x42bda25d, 0x0274b2bd, 0x11678bc4,
- 0x5efcd77c, 0xc9a3d335, 0x0b3cec3b, 0x7520dabe, 0xc73be346, 0x32bb9319,
- 0xa684ff68, 0xab3da11f, 0x51ba27cc, 0x6ed7ba3d, 0x77b126de, 0x4e8c6c32,
- 0xfc5d47eb, 0x7f3a74c9, 0x41efb53d, 0xdf6babaf, 0x28a6ef8f, 0x7b5ef9ed,
- 0xbc2fe94a, 0x7fe83f8e, 0xca6fb100, 0x0080005b, 0x00000000, 0x00088b1f,
- 0x00000000, 0x58adff00, 0xe554700b, 0xdef73e15, 0x66cd927d, 0x421b22f3,
- 0x260ddde2, 0x9b709601, 0xf51e4357, 0x8ca4109a, 0x6388376d, 0xfadea56a,
- 0x59092040, 0xd6a27509, 0x0071a6e1, 0x3b634ea9, 0xb33088a3, 0x2331e1d2,
- 0x3054d353, 0x32d740a3, 0x5da96255, 0x66d42d8b, 0x88d46b98, 0xf1a6c935,
- 0xa1986655, 0x5ef7fce7, 0xd6086f76, 0xe6ccdd3a, 0xe73effec, 0x9cff8f3b,
- 0xaa36c01f, 0x5cfb0195, 0x8bdff016, 0xed2bf1f6, 0x8ca2c020, 0x06ac43b0,
- 0x27c8f2d8, 0xfb0dbd7f, 0x990dedd4, 0x47f18b63, 0x475f8e3e, 0x5c8054b3,
- 0x000ea580, 0xd4c0154f, 0xbee8b4fe, 0xf097f500, 0xd9b00350, 0x80453f87,
- 0x9c944e8f, 0x8ff1c6ed, 0x8703b0de, 0x9f1b275d, 0xdb107c9e, 0xf9a7f65b,
- 0x059e349c, 0xef8d3e6a, 0x38aa8d2b, 0x6a7e3ee1, 0x27073ba4, 0xfb4ba60e,
- 0xbdc3fc71, 0xc61fcfa5, 0xafe786f6, 0xaecd8897, 0xd9883c5d, 0x0d885fd8,
- 0x3e6dffea, 0xfd7e075b, 0xfd2e75dc, 0x92e0e15c, 0xf8d0379f, 0xce896cc1,
- 0xcb39a569, 0x75ec2e00, 0xf00e50cb, 0x7dcac419, 0x731f00c5, 0x1b8f18ea,
- 0xcf87f3b7, 0xb3c03c73, 0xe494a50e, 0x37fbb8de, 0x7947ab7f, 0xe77e0f9a,
- 0xdfc865e9, 0x40b93386, 0x5cf2c0fb, 0x787e0186, 0x1a728b98, 0x9708b5e7,
- 0x60085abc, 0x067158fa, 0xb4f89284, 0xdefb721f, 0xe2b81977, 0xd32073b7,
- 0xca1aeed2, 0x965fbdf7, 0x8e83b76c, 0xd9c3dc31, 0x7d0eff68, 0x65798608,
- 0x09d5f109, 0x0808039a, 0x97847298, 0x9c085400, 0x13ff840c, 0x65ff864e,
- 0xa490dcfa, 0xf8cf222d, 0x1941e0e8, 0x6cfce0f0, 0x702bf970, 0x97e3a2b9,
- 0xdf74a278, 0xad66c44e, 0xcd500598, 0xbd592df6, 0x8b7fc924, 0x15e9b230,
- 0x977a7fdc, 0xef627253, 0x0cee1bb8, 0xa73eae87, 0xeb64cc55, 0x053eb9d7,
- 0x7fb2765b, 0xadbfcf53, 0x51c810ed, 0x27d15f5c, 0xb48fde56, 0xafcbd0db,
- 0x0c35e1fc, 0x8f2781f7, 0xee78669e, 0x3a1de079, 0xe98794f7, 0xb8eb4e0f,
- 0x23683827, 0xd6fdcc39, 0x56c0a6b9, 0xc73efc49, 0xc7fb35f8, 0xae5b399e,
- 0x4763fee0, 0xda039716, 0x7c425df3, 0x67c459ec, 0xfe7e3d32, 0xa783a461,
- 0xf15732fe, 0x476fcd5c, 0xcfdb34cf, 0x1c738f6c, 0xe483b793, 0x829bfec0,
- 0x9e228de1, 0x09903603, 0x4b9dd1bf, 0x422d7e18, 0x9ff48328, 0xdfcac8f8,
- 0xfdcd3e4c, 0xfdccfe4d, 0xa43d79cd, 0xc261c42f, 0xc2cf2f11, 0xa24539fe,
- 0x6f09ae45, 0x43d33cbc, 0x3fd63efd, 0x14ed8591, 0x9fa36b7b, 0x1736dfa8,
- 0xbf9073d8, 0xea4e36b6, 0x42afd603, 0x0531a316, 0x2ffc3bc7, 0xd841b81b,
- 0xab767685, 0x93906761, 0x5a3f236d, 0xdf5dba03, 0x8bc7fb5a, 0x76e0179c,
- 0xfa03b018, 0xf7be39cb, 0xe3a42ec7, 0x13b4bf03, 0xbe10e87e, 0x4e5fb431,
- 0xbcbf877d, 0x4db96af8, 0xa58d804a, 0x5f831bc6, 0x22ca09b5, 0xcf84cfb8,
- 0x014bf2a3, 0x1b39119e, 0x8508579b, 0xa5c70f34, 0x3a81da18, 0x90fa94e8,
- 0x787c4b9f, 0xe1dfe12f, 0x1f939588, 0xf12eeb98, 0xe71feb0a, 0x7d23af4e,
- 0x1e562d83, 0x647d474e, 0x40cb803a, 0x65c52b9a, 0x0cfd43c4, 0x23015c58,
- 0x9518f1fe, 0x1d849ce8, 0x8f9106da, 0xfd37ea46, 0xaaa4ed13, 0x7a0c8f99,
- 0xfc93f392, 0x0195db5b, 0xb2aacfdd, 0x2cc0c8f9, 0xc327f1fe, 0x4060fb0f,
- 0xd617fdd0, 0x7ae710b8, 0x59006703, 0x64df7f20, 0x3cb937b4, 0x54e30131,
- 0x0552ebc2, 0x18febfe4, 0xf5db01ea, 0x44abd8b6, 0x07a1ebd1, 0x310759f5,
- 0x6b21bf7d, 0x8f70e6fc, 0xfc1c703b, 0xa91c598b, 0x8dbbd433, 0xd1e9008b,
- 0xee8cfd05, 0xd102e2e4, 0xa314c16f, 0x446cf832, 0x97467611, 0x15d19843,
- 0x25746110, 0x0aba33f4, 0x19bd1806, 0xa2c28ce2, 0xf8b01f58, 0x58df13ff,
- 0xdf6f921a, 0x5a465fc7, 0x66441b75, 0xc32987f3, 0x078dafce, 0xaf9af546,
- 0x500ac78f, 0x6baf8cfc, 0x8cbf32e1, 0x8b89b9d9, 0xd711ec93, 0x27ea21b9,
- 0xdb1a08da, 0x5c3206e7, 0x1046e7dc, 0x066ed46d, 0xbe5bb599, 0x9ab51e22,
- 0xb3425362, 0xbb3cd2e0, 0x70345c9d, 0xab2c25e9, 0x185afa93, 0xd4db5910,
- 0x149f201b, 0x27d6afff, 0x559f1114, 0x889f4d69, 0x03b22218, 0xc61b61bd,
- 0xa6caaad7, 0x2f6c62ee, 0xb7a93c08, 0xed2a9beb, 0xfbd39e12, 0x8c72f08b,
- 0xee0c2eab, 0x2845c46e, 0xa916a016, 0x0396f6e2, 0xb85395fa, 0x54ff225f,
- 0x10f100dc, 0x40b9e373, 0xc256d0fe, 0x3e2dbfee, 0x3aef3f5d, 0xda00f494,
- 0xe62ba777, 0x2de71115, 0x74792dbd, 0xe8776e0f, 0x2b9bbefb, 0x65057e2e,
- 0xae39e272, 0x383ca48a, 0xadb1baae, 0x4f776271, 0x57ee7920, 0x5020af38,
- 0x9af3ed7d, 0xfc488afc, 0x4804ab80, 0x3dc605cf, 0x2f58383d, 0xef9d3c49,
- 0xe96be763, 0x383ddd25, 0xbc3fa4f4, 0xa44bf690, 0x90b5f6eb, 0xd24dcff0,
- 0x94b90135, 0x27f667c6, 0x1a38bf7a, 0x1f137dc3, 0xaeb8c1e0, 0xd394a031,
- 0x56bc5db9, 0xf87a8954, 0x0779da69, 0x4fb4dfe9, 0x0772950e, 0x4327dbca,
- 0xbeecc1d4, 0xaf2577c1, 0x77da4e2a, 0x0fdc5ee2, 0x870aa871, 0x5c38ed9b,
- 0x493916d3, 0x6fe956b4, 0xa73a11c6, 0x12e9f89e, 0xbe91d6a6, 0x38cf3327,
- 0x37fe603e, 0x2333b75f, 0x313f1d2e, 0xde8170fc, 0x7f8a430c, 0xf8b89d75,
- 0x1e303ff9, 0x247b4d76, 0xec7f5e9a, 0x26f06e99, 0x3ab30afd, 0xfd30dc4b,
- 0x19c86eac, 0x85bcd813, 0xc6fcd2f7, 0x14c52333, 0xd1186f6f, 0x42dc30fa,
- 0x02d9f8e2, 0x7b8ddedd, 0xfb82fe41, 0x8b42f73a, 0xb8c74a80, 0x1088f9bf,
- 0x9b5ca275, 0xda304f29, 0x743fb62a, 0xd0649da1, 0x8f93d97c, 0xe437ad72,
- 0x83fe1cea, 0x6d3a8303, 0x1bbc92a3, 0xefd7fe0c, 0xca66fbb9, 0xed4436fb,
- 0xdf8ef8c9, 0x36e891f6, 0x90fdbbe2, 0x21229fb5, 0xac65dfc9, 0xabbca0ef,
- 0xeb37f298, 0xfc782ebc, 0xba97145f, 0x9bfdac86, 0x4c39e902, 0x063dc60f,
- 0x9f78be46, 0xa3e48731, 0x71f379bc, 0xb289d447, 0x2ddbde6d, 0xe85da8f9,
- 0xdd1c5891, 0x5bb328f3, 0xc9ec3e73, 0xfa623666, 0xc01d86e7, 0xc71360f2,
- 0x329c07a5, 0x81e963e9, 0x62df963c, 0x0af2ce5e, 0xcecc138c, 0x1c262297,
- 0x990bddda, 0xcf1e4153, 0x9978e179, 0xcbf37944, 0x6f78655b, 0x333f9241,
- 0x0e116f6f, 0x3ed03b37, 0x1f01efa6, 0x50357de5, 0xae0374f6, 0x87653eab,
- 0x834f8e28, 0x0be98fae, 0xebbfcb3c, 0x64fd2b86, 0x231cc207, 0x4f31f86e,
- 0x2dc3c14f, 0x253101ce, 0x75f135cf, 0x2b4b7a1a, 0xa78cb2cb, 0xeb2cf34b,
- 0xd6836a33, 0x0f1caaf5, 0xd69c50d5, 0x8bca67d7, 0xc341f32c, 0x306f1c3f,
- 0x5deedbe0, 0xb7ec8a71, 0x66feb3d1, 0x657b29c2, 0x53be6585, 0xff102638,
- 0x2cda9f0d, 0x8426fc7a, 0xce51d39b, 0x0f31b7da, 0xc6ea73c1, 0x4d6ee3ad,
- 0x7ee75a05, 0xa01f253b, 0x7b6b44fd, 0xf987b4c0, 0x1ed53f30, 0xae7b7892,
- 0x50f649e0, 0x782c0b03, 0x0aebc4cf, 0xf3071efe, 0x6ee1ba87, 0xd86e5fc6,
- 0x9b5e7b8a, 0xc57cf715, 0x7ac1738a, 0x1185ce2b, 0xf5d7ce2b, 0xa80d7158,
- 0x778adc56, 0x5fe659d4, 0x6964dfdf, 0x655aee97, 0xba30bf99, 0x7c5ed2da,
- 0xfccb76e8, 0x59770325, 0x6d0e97c6, 0xf69b8cb4, 0xdfff5335, 0x619e6d88,
- 0x5ff03c5f, 0x53caffa2, 0x99ce590f, 0x888077a9, 0x6bd6f840, 0x5703bb00,
- 0xedfabdeb, 0x578af07e, 0x0f029deb, 0xf5339de5, 0xa7fa453f, 0xffe86f38,
- 0xc629d233, 0x17bd37b9, 0xfd37271e, 0xcf1e9a6e, 0xb886845a, 0xb06d7a4c,
- 0xcfeb7ab3, 0x3a737662, 0x1ee303c5, 0x18f71b0b, 0xecc1dfac, 0xdbd3ec21,
- 0x493a5c52, 0x5ce2ac71, 0xaaf899b8, 0x512722d2, 0xd0b9a84c, 0xf3419cdf,
- 0x387d1065, 0xfaf0339f, 0x36072d5e, 0x7b613f8b, 0x5bcf126e, 0x03215ed4,
- 0x8a5fd727, 0x4b30b1f6, 0xbf9e0ec5, 0x6ae718da, 0x55a27bf5, 0x052d8376,
- 0xf35ac697, 0xfe3108fe, 0x316ffc4c, 0xe7cc08ea, 0x3cf941c1, 0x05f68aef,
- 0xa45fcb66, 0xafcb025d, 0xbd6f9614, 0xa27629ce, 0x22f15c6b, 0x9e4aeb8a,
- 0xb8882f32, 0xc892f24d, 0xeb4e33f2, 0x2412a123, 0x6a565d18, 0x754cab66,
- 0x30a39618, 0xd19f290f, 0xfb187aaa, 0x2f46ad3e, 0x1253e97b, 0x18838a54,
- 0xdf394717, 0xfb5c4ab6, 0x45c7dd66, 0xca2d6f74, 0xff501790, 0x3c8ef795,
- 0xabe30b94, 0x412a8bc6, 0xb1c43ea0, 0xda63e1fa, 0xdf8a5964, 0x7bb3b0ee,
- 0x6a7a8c0a, 0x599381ad, 0x9c61dd4f, 0xac5b8a3b, 0x76bdf8c7, 0x478675e8,
- 0xd59c7fbb, 0x926f689f, 0x7bbff70f, 0xea82a7be, 0x252b9049, 0xeb370ebd,
- 0x7fe102ab, 0x7acd47b9, 0xdbf35af4, 0x752c17fd, 0xefd61c2e, 0xafef6b97,
- 0xca4d7b32, 0xfa3fefad, 0x77bb1a58, 0x6c2b1f46, 0x7fdc9a22, 0x36bfed92,
- 0x3ec596f2, 0xbbf9ecee, 0xa47eeec5, 0xd7196bbe, 0x05eca672, 0x3476bf28,
- 0x100fc57f, 0xce2389bf, 0x5133aa1a, 0xa60fdf5f, 0x13dac1d4, 0xbce9cba5,
- 0x3fe72eff, 0x5b23be19, 0x905b60e3, 0xd6fcf394, 0x6dadac73, 0x299d18d5,
- 0x9a9759a7, 0x287bf1d4, 0xa67ea1b3, 0x6cd239b8, 0x41232cef, 0xb91f6f3d,
- 0xdd136e71, 0x0e8523bf, 0xf44b4e9b, 0x4bad7e76, 0x4958af6f, 0xecf76134,
- 0x8474baa0, 0x7b439903, 0xf9f79d18, 0x516e0701, 0x403ca797, 0xa69a2672,
- 0x2977a73e, 0x288ad1c8, 0x2a664c9e, 0x873f520f, 0x167e5fc9, 0xf284b3e3,
- 0xfabc0bff, 0x7018c06b, 0xad6ddf60, 0x7a4fd794, 0x647fbb75, 0x2aad2ddf,
- 0x199952e2, 0x40eb4ade, 0x917bd8d6, 0x8ef9afc9, 0xd52f7542, 0x4eb70921,
- 0x263907b7, 0x74198eff, 0x28d4d537, 0x1d064bdf, 0x384afbe5, 0x4edd87f2,
- 0x7e601fd8, 0x315e5320, 0xfba9cc7d, 0x8bc00d81, 0x711defe3, 0x3cf6473e,
- 0xbca67917, 0x9633b305, 0xcefc57ff, 0x6138a319, 0x14e4bfbe, 0xe10b3f8b,
- 0xec979cfa, 0x4c9fceac, 0xbfc86b17, 0xb2afbd3b, 0xa0a6ebbc, 0x40e4c032,
- 0x8c7e2849, 0xdbee751e, 0x2a4dfcc9, 0x7ffe9d5a, 0x103b677d, 0xa68c7564,
- 0x3bc691e7, 0x8b77299b, 0x7b9338f0, 0x4813977a, 0xe37b89ce, 0xbbd8854f,
- 0x7c445492, 0xdf3af28e, 0x7ca6bf26, 0x7dc91ca6, 0xcd6edcbe, 0x7be4a2f7,
- 0xf212f6d6, 0x7f51c403, 0x3bb813c7, 0xfeb2cf57, 0x9aabe90c, 0xa09da7bd,
- 0xa231b638, 0xf525a7bf, 0x3bc0ffde, 0x0f61b7a4, 0x5ad7638b, 0xcece533f,
- 0x0f0cc313, 0x2487f394, 0xa79c8a5f, 0x7eef2983, 0x3ecfc713, 0xbebf1215,
- 0x38c2897c, 0x3c4cdf7b, 0xc448b177, 0x5ec79df5, 0xd276473f, 0x33ffd469,
- 0x739da9df, 0x9acc7eb0, 0x6f1a7ded, 0xc97c9485, 0x6f9fae69, 0x04c7aeb3,
- 0x886cfc99, 0x0af291fc, 0x5e2927bc, 0x8be4f79b, 0x69c19d46, 0x4d78b1af,
- 0x6efd91e7, 0x5f7654e3, 0x7d05ef99, 0x5447de1c, 0x2cdd2b97, 0x79d70b8e,
- 0x17cfb224, 0x74e306d1, 0x34e4d8ff, 0xa33c2ef6, 0x54e79d8e, 0xd93b253e,
- 0x1e5356f2, 0x6f83b9d5, 0x27ea32ac, 0x36a91efd, 0xce9ab2ec, 0x1943fe27,
- 0x32a93eec, 0x4571abf8, 0x0cbade58, 0x177f4154, 0x1e19de30, 0x7752cd7b,
- 0xa2bf07fd, 0x17f0846b, 0x000017f0
-};
-
-static const u32 usem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33ab678a, 0x32ea7830,
- 0x31e9c830, 0x43d24c30, 0xb712d388, 0x9fa65173, 0x8181859d, 0x81b98813,
- 0x5f881798, 0xbc303231, 0xff5e2466, 0x3b046147, 0xe181804b, 0x0b6f9013,
- 0x32089fa4, 0xb2075c30, 0x0371033f, 0x88073f90, 0x35b10057, 0x480fbf90,
- 0xa3e204df, 0x1845fc40, 0x095ff9bf, 0x42156fc8, 0xe3443fe5, 0xafc4159f,
- 0xf980825f, 0xb1e40472, 0xe42269e1, 0x0a6dc7c7, 0xde040ef4, 0x67ca86a6,
- 0xe0606553, 0xaac58a07, 0x91dbf843, 0x6281f3e4, 0xf610aaec, 0x8606396b,
- 0x1db9405f, 0x7dcdd86a, 0x0dff9403, 0x9a86ab94, 0xf1b90003, 0x03685054,
- 0x00000368
-};
-
-static const u32 usem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0x45547809, 0xbedd70b6, 0xe9d3bb7d,
- 0x84849d25, 0x1674b090, 0x26c43510, 0x630a0840, 0x944c2127, 0x615151a8,
- 0x8408ec44, 0xf9707d90, 0x37d7d470, 0xdf95012c, 0x3e30eb89, 0x0e0c1a74,
- 0x1036a0c3, 0xc6c06a30, 0x680e8300, 0x8cc08378, 0x364584cb, 0x5c710921,
- 0x7f9e6466, 0xbb75539d, 0x48e9bdef, 0x9bdffc74, 0x3f6fef37, 0x556ea2bf,
- 0x5b3aaa9d, 0xaa753a9d, 0x42049462, 0x1be426ae, 0x71f4d1f8, 0x10921091,
- 0x69f2bb4e, 0xb910963a, 0x96bfca27, 0xff6e0d56, 0x401904fa, 0x5be6b9c8,
- 0x4254e65c, 0xc1513d3c, 0x39f969ab, 0x4cdf9e7f, 0xbcb60bcb, 0x7cd230ef,
- 0x08d116f5, 0x16ed86e5, 0x4ab9df6c, 0xd6be43f0, 0x55d8fedc, 0x45bddf34,
- 0x68286b24, 0x2066ceb2, 0x889c8439, 0xb467ec22, 0x2122481b, 0xad961665,
- 0x1663bd5e, 0x62de57f4, 0xfeda1626, 0x81e8b344, 0x82b582fc, 0xaafed09f,
- 0x4a665b5f, 0xf9e6f0a6, 0x45c58085, 0x371f6bf3, 0x2c84ecb9, 0xa381feda,
- 0x19c846c3, 0x9971145f, 0x81e51e70, 0xfc2a424c, 0xd324a71b, 0x041b15f6,
- 0xafc281b7, 0x13be7558, 0x2cd157c6, 0xbc29170d, 0xe25675ca, 0xfefac91a,
- 0x6d7f4086, 0x2dbfb0c7, 0x57f40652, 0x136ee17e, 0x929e6111, 0xd355da07,
- 0x95bcc071, 0x1af8cf7e, 0x18446b89, 0xa1bfd59f, 0x357ad1fd, 0x986e0b2f,
- 0x78818d62, 0xaf9d1c61, 0x60bfa659, 0x9bd5f983, 0xf3d5d846, 0xf30add28,
- 0x36aff0a8, 0xf8c1b14d, 0x32ca9b56, 0xd72af0c3, 0x515c493d, 0x4cadf1aa,
- 0x9555e81f, 0x3e33d3eb, 0x054f19a2, 0x06c05925, 0x6e9bf678, 0x7efe151c,
- 0x7a458858, 0x3513ae57, 0xf1e529f0, 0xfd3efcbb, 0xbc83c527, 0x9b5feecd,
- 0x02dba61a, 0x2bb7fd27, 0xa71eb74c, 0x1ceec742, 0x7d257c35, 0xc741e80c,
- 0x6273e8d3, 0x092f84fa, 0x2e7ca7d3, 0xbe33d3a4, 0xf4ae9891, 0xb3fbf1b9,
- 0x574c5cbe, 0x3e983cf9, 0xd4c22bef, 0x7ac12bef, 0x31d37c6b, 0xf179f26d,
- 0x72be8bfb, 0xeaf9d74c, 0xdf7afbf0, 0xf8374c42, 0xb2fefc64, 0x01a6396f,
- 0xbe4da74e, 0xfb369895, 0xab6f58fc, 0x2da61d6f, 0x5f7e00be, 0x98e7f1c1,
- 0x748cf248, 0x710f0efe, 0xb8937252, 0x449e4f62, 0x2c2571f3, 0xce53389f,
- 0xa27cd133, 0x3e29e697, 0x7982ab92, 0xae4f9a66, 0x1f43e563, 0x3451f924,
- 0xe566543f, 0xf93c2b69, 0x6b4f9a16, 0x5623e564, 0x34d1f9c9, 0xcacfc23f,
- 0xcc10db2f, 0x65fcd2b7, 0xd59e5601, 0x346c0a4a, 0xf964159f, 0x029ebdec,
- 0xb767cd3b, 0x87ce7cb3, 0xe6838172, 0x7b583a73, 0x1203de3d, 0x6d284d99,
- 0x3c8b959e, 0x6f3441c6, 0x37137722, 0xa37c8bc5, 0xe28138c7, 0xf9617241,
- 0x5827f976, 0xc2e4c9be, 0x367976f2, 0x1e4b3796, 0x572a3f2c, 0xc9b37961,
- 0x917fe583, 0x56fcc5ef, 0xa6e58bc9, 0xfac37ffa, 0x2c5e4d5b, 0x865faa4f,
- 0xc64916f9, 0x1beacbf2, 0x498b7eb1, 0x9627f2c6, 0x9933d2fc, 0xef04fb96,
- 0x8b67c053, 0x49396f05, 0x2409fe07, 0x69fe5095, 0xe074c810, 0xc98107d7,
- 0x20fcd1c6, 0x605dca13, 0x200bce57, 0x001bf8af, 0x1f17b2f9, 0xcf384549,
- 0xc2891c21, 0xc70e2f11, 0x03573bbd, 0x5cbbbdc7, 0xd422f381, 0x1fe96c5b,
- 0x2beec09c, 0x5dd9e3b5, 0x0579c0a1, 0x37fbd8e1, 0x26eff72f, 0xbbf3c76a,
- 0x0b4e052a, 0xdfed89c2, 0xd3ed3678, 0xbed367e2, 0x20767e10, 0x37fa127e,
- 0xb577ec9e, 0x377ec9f8, 0x70779f84, 0x07fa833c, 0x5abbd367, 0x377a6cfc,
- 0xe03f9f84, 0x6ff48678, 0x69efd95e, 0x5efd93f1, 0x221f3f08, 0xc1fed49c,
- 0x8b5f7e69, 0x43f7e69f, 0xe104f9f8, 0xbcdfef0c, 0xe2d41ec6, 0x10c1ec67,
- 0x3f113a7e, 0x4e0ff697, 0x7e2d41f3, 0xf0860f9a, 0x678e25f3, 0x35e6ff54,
- 0x3f1690f6, 0xf0850f63, 0x33800443, 0xd9e37fba, 0x3f1691fa, 0xe10a3f5b,
- 0xc67082c7, 0x393c6ff5, 0x93f16b1f, 0x3f0871f3, 0x42670871, 0xfd6ce0ff,
- 0xad9f8b58, 0x93f0871f, 0xf5267082, 0x7f395e6f, 0xe727e2d6, 0x64fc21cf,
- 0x3e3c9c20, 0xd8e1421e, 0xf2d386fb, 0x2d3f1689, 0x33f0849f, 0xf214e10a,
- 0x4e045cf1, 0x7e2d09ee, 0xf0844f72, 0xae708393, 0x969c1fe9, 0xb4fc5a13,
- 0xe7e1089c, 0x5d73846a, 0x7b95e6ff, 0xdc9f8b52, 0xa33f0c93, 0xc1b496f7,
- 0x40d7437a, 0x4c9b48b7, 0x08f1ee38, 0x64e8beb4, 0x26e9d179, 0x8a888760,
- 0x3dda417d, 0xdb6fad22, 0x08fd9b10, 0xf919db51, 0xec78c037, 0xdb52fad4,
- 0xd1b93119, 0xd62bbb1a, 0xc7c9a713, 0xea6b2517, 0x69a49427, 0xbf4e07ca,
- 0xc83e534c, 0xa7c9ad9b, 0xa9a95f94, 0x5f2ea43f, 0xf0b61f93, 0x54fd4d5a,
- 0x3e4d26f9, 0x344ff97d, 0xde3787f5, 0x64bf29a5, 0xfca68565, 0x4d02ff52,
- 0x3f75f2fe, 0x151fd4d3, 0xbf29a458, 0x4d11e5a2, 0x13e0e8f9, 0x3d98fc9a,
- 0x8fea6acf, 0x29a35f6b, 0xbd787f1f, 0xc7427ca6, 0x529e4d26, 0x72e279c2,
- 0xcf81179e, 0x07ebb309, 0x0b9ed099, 0x37984dda, 0x4ed0db25, 0x5ccbda0f,
- 0x4d1d29c7, 0x006baf06, 0x8486814d, 0xc979dbae, 0x507497e5, 0xa577df3a,
- 0xfd2712f7, 0x7bc99f7e, 0xfd823385, 0x902fe949, 0x065d4824, 0xcbe5f548,
- 0xf97fc624, 0x1c461729, 0x0d6beda1, 0x696223dd, 0xf790cbbe, 0xf1f94094,
- 0x7c80c159, 0x3a922d19, 0x266d17a8, 0x4b2ff768, 0x564179cd, 0x21f2e7f1,
- 0x3084ee54, 0x3792e5dc, 0xe78aec09, 0xc193dfeb, 0x421868ce, 0xc84c95e7,
- 0x82f784af, 0x3f6d0672, 0x4bc92ca4, 0xd44d99e1, 0x6ff7570e, 0x6267fda2,
- 0xffd04dff, 0x37fa3efa, 0xfa6ae5a7, 0xae5a1a8f, 0x44ca3fe9, 0x3b5277fb,
- 0xef10feb3, 0x4ae9129f, 0x0e115e42, 0xa1e6ff61, 0x32ffd8e5, 0xa88fdd13,
- 0xf50e8ffb, 0xf1f20cdf, 0x109ff43a, 0x5769fe61, 0xb43fe76a, 0x137f3b42,
- 0xfaf6ff9b, 0xa3fef33f, 0x0a6ffe71, 0x1ff3667f, 0x6fe6c15a, 0xfd437066,
- 0xdff8423b, 0xa77ff309, 0x4fa7f9af, 0x587fced4, 0x66fe7695, 0xf5bbffd6,
- 0x36ff7927, 0xe13dffec, 0xb0ff9b24, 0x64dfec2a, 0x7f81baf6, 0x75d1294c,
- 0x193fda7e, 0x40d1154c, 0x0fda1760, 0x28e323a4, 0xb0f21313, 0xb8e38690,
- 0xdbf19a2f, 0xdf94d117, 0x88c8bf50, 0x9aa7e21f, 0x6a43ee8c, 0x6e542cb8,
- 0x1e8133c8, 0x1fba72c2, 0x3a87cb99, 0xfe4445a7, 0xfd994f26, 0x3b78e9c3,
- 0xf219445b, 0xe49a9e73, 0x6b577d07, 0x40967726, 0xc209233b, 0x1e9e4ff7,
- 0x2f3d46b5, 0x51b73a7d, 0x91a1d13a, 0x391e362f, 0xa3ac8c9f, 0x26042be3,
- 0x9fce1718, 0x421dfba0, 0xe94711f7, 0x93d2027e, 0x7e8fed12, 0x43f74e3f,
- 0x9b96a4c4, 0x64476c7a, 0x7419fbcf, 0xe512b7fc, 0xde79c1e7, 0xe1452281,
- 0x4ffe1919, 0xd0357dd0, 0x95a36e63, 0x1e3c3f22, 0x6f9c1f3a, 0x5fe0a977,
- 0xd2bc7023, 0xf6f1b7f6, 0xe147c604, 0x36b272cf, 0x0f72511f, 0xb79f28a2,
- 0x67035e32, 0x4d2ff106, 0x5f6feda2, 0xb42243b1, 0x74a141ce, 0x97e002c8,
- 0xc4122407, 0x0247647d, 0x40cce4c9, 0x0c9d7be1, 0xa5d36dfe, 0x382a1de3,
- 0x4f28a4b3, 0xaccf1d09, 0xef1c45fb, 0xbcb6af0c, 0x63d5bb63, 0xcae9a2c8,
- 0x494224cf, 0xb6b97b7e, 0x6d3a8efc, 0xda85cefe, 0x098f9d3c, 0x5952b5d6,
- 0x874e9dff, 0xd0aef3ce, 0x69c4e9bc, 0x9b2f367e, 0x35925cbd, 0x686d8474,
- 0x034f2f0e, 0x13c413b4, 0x5def4fb6, 0x2681f29f, 0x0ea56f3f, 0xff8be71e,
- 0xddffff4f, 0xc96daff4, 0x1aae3f8b, 0x9ae07557, 0x7aaae3f8, 0xd46eeb95,
- 0x67fbe7e4, 0x5bcfea68, 0x9f29aa59, 0x535f38db, 0x4ff97b3e, 0xf952f935,
- 0x3bfd4d7e, 0xca6bd617, 0x587ba8ef, 0xf97b7e53, 0x0cfc9ae3, 0xf5352fef,
- 0x5abe9b6f, 0x9f6c2e53, 0xd703ac3f, 0x41b0ef4d, 0xa3fc0fe0, 0x299f0099,
- 0xfbf0acfc, 0xa6125f29, 0x4c2e7c67, 0x530f41eb, 0x8d786efd, 0x4a6bb5a5,
- 0x573e8187, 0x54a4fff8, 0xa5f41437, 0xfaf59f9e, 0xf4a7cf57, 0xcec91297,
- 0x812ad250, 0xd63ac094, 0xe55eedc5, 0xcebe39fb, 0xd308b211, 0xcb93132a,
- 0xf2834daa, 0xc1f20389, 0xbeb67511, 0x808092e1, 0xcde020f3, 0xa5ba004c,
- 0x4d4bb5d0, 0x38cd74d7, 0xb110eecf, 0xc9901aff, 0x94dcb009, 0xff40326c,
- 0x37a1b6c1, 0x78f1828f, 0x25be6336, 0xb3aded01, 0xe3f8a2be, 0x095fc046,
- 0xd37ca7a6, 0xf3e13d31, 0x57dc7a62, 0x5f51e98e, 0xbe1da61d, 0xec7e9885,
- 0xd0fd3193, 0x3fd31cb7, 0x3d311af9, 0xe9895bec, 0xd31f9f41, 0x53079f4e,
- 0x55ff4f85, 0xf0ca3ae8, 0x73d74edf, 0x328eba6a, 0x3878d938, 0xf1851f5d,
- 0x939bb046, 0xa71918c1, 0x563c47b2, 0xe02eabf4, 0x896a70fe, 0xef2b3f31,
- 0xd705317b, 0x7f8b768e, 0x9ee1e824, 0x011b7f91, 0xc39ee47e, 0xed480174,
- 0xfa7a7e7b, 0xe20789f5, 0xccbdfb41, 0x3187174f, 0xd12dcbbd, 0x0316af0c,
- 0xd4d92229, 0xa2fe1b5e, 0xcc4caefb, 0xb41c491b, 0xb46fbbf7, 0x6d4b8047,
- 0xc5efc041, 0xfed8baf0, 0x3bc01645, 0x39d7ecf1, 0xa4328e90, 0x4db8bb31,
- 0x0494bb44, 0x7e03705f, 0xecd67a43, 0x6d3f024e, 0x139370f7, 0xb8a7bdd7,
- 0x9fc15a9f, 0xfe0af2cc, 0xafe10e1e, 0x97f10931, 0x14bfc5f1, 0x3ba788fe,
- 0x6151a6eb, 0xbe139dfc, 0x39ca7f1d, 0x1bbfbe89, 0xe277e344, 0x0544aecb,
- 0x0943edaf, 0xe02de7ed, 0xa7bf0a7f, 0xc01892f9, 0xd93ec873, 0x87f7f662,
- 0x4e80e74e, 0x6abc30b6, 0x3d9ebc1d, 0xeec0382f, 0x7064905f, 0x67808f1e,
- 0xa40ead25, 0x3b6a6d3a, 0xef9b45a9, 0x028a1469, 0x62b8cf68, 0xfd028da6,
- 0xcf1e74eb, 0x84993d00, 0x416702a9, 0x3c79c992, 0xe4c3e91e, 0xca2c437a,
- 0x145f19fd, 0xc7a1fbd6, 0xf09c17d1, 0x31c99a38, 0xf9501eda, 0xf5df7a4d,
- 0xe353e4fb, 0x37e04c5f, 0x17d2ad23, 0xd144bf60, 0x0381bfff, 0xbcc46232,
- 0x2036b702, 0xe02be6ca, 0x7f4d06fb, 0x394b9db4, 0xed26fbc3, 0x48c1e4db,
- 0x4afc284e, 0xf0468a97, 0xbe038d49, 0xf6b538b5, 0x5f26ac51, 0xa9c832db,
- 0x1fe097b1, 0x72928f54, 0x577c08c1, 0xcba6d9c5, 0xd02e5b68, 0x538255f1,
- 0x6055f80a, 0x3aa3aaf5, 0xf0175e4c, 0xaf5be2cb, 0x46cd4172, 0x7c7eaf9c,
- 0x1a377e94, 0xbf8f7d8d, 0xafb9ec52, 0x6c7c8224, 0xcabb7ae1, 0x240afcc0,
- 0xf9c0764a, 0x1d924917, 0x6871d937, 0xd07e10b6, 0x51fb470f, 0xf33815e5,
- 0xd6b752fd, 0xcf91957e, 0xbf981acf, 0x6eefdf40, 0xe2e137e8, 0xb0d9abf8,
- 0x5bcc0a7f, 0x969ac78f, 0xca2f26f3, 0x272ffd15, 0xbf05478c, 0x6ec96295,
- 0x58afc291, 0xd5f70477, 0xc47924a7, 0x17a2df03, 0x96df8f7b, 0x9aaac274,
- 0xa1da4cb7, 0x7972bb9f, 0xdb75c447, 0x9f5f5407, 0x1e44bdfe, 0xa05cba01,
- 0xa0e354b5, 0xe4310516, 0xbbf5ed84, 0x618b2b9a, 0xfb0d3efd, 0xe72faa15,
- 0x38071290, 0x6349cb1d, 0xe7e7d80e, 0xf008a188, 0x87fc8e74, 0x4e8a8c63,
- 0xe2134467, 0x47efda89, 0xf6a3e3d5, 0xed4f26bb, 0x8cbe4d77, 0xe70894dc,
- 0x494f65d9, 0xfce02fc4, 0x127fe534, 0x79f7489d, 0xec01aea4, 0x5b12c59d,
- 0x1272efd7, 0x5f1d0a63, 0xe5cfabf5, 0x79fcd294, 0xca23d991, 0x38fcec79,
- 0xc08afe36, 0x9687936a, 0x731e6b1f, 0xda0455eb, 0xfd601bfb, 0xee08b791,
- 0xf8deaeb5, 0xd7e3aefd, 0x87b1578f, 0xf30b9d7a, 0x13af5471, 0x7648fe3c,
- 0x8533e711, 0x4e8c631f, 0x45237f8d, 0x9744bf97, 0x7fcba31f, 0x401f796f,
- 0x295ef234, 0xe38c537a, 0xfec37c98, 0x2376304e, 0xf86f7f3f, 0x5fe0bd49,
- 0x1fc283f2, 0xd13393ac, 0x8507e63b, 0xfc6bd19f, 0x5f824757, 0x5b4beafd,
- 0x2a9faa65, 0x41da795e, 0x6d3a7ea8, 0x53744c6c, 0x5dad57fa, 0x383e00ea,
- 0xc01d9465, 0x62fda7cf, 0xbe823f91, 0xf0a8d7bb, 0x8026c783, 0x49fe0dff,
- 0xff599fe1, 0xaeb0f5e8, 0x7256b17f, 0x9d6d5fa2, 0xf2a66839, 0xbf3cd35a,
- 0xfe616498, 0x3b2fcb08, 0x45be422f, 0xbf159fcb, 0x85d13a7e, 0x314e52fa,
- 0x8838ffa0, 0xd34d7ff6, 0xdd605327, 0x28dd25af, 0xd076fa67, 0xb87157ff,
- 0x629a953e, 0x46e3977a, 0xb3da113e, 0xa3f36d5f, 0xfc0745e7, 0x06fd03ab,
- 0xdce5fafa, 0xda332f8e, 0x1afea007, 0xfe83c64f, 0xfc41f052, 0x5f178ecc,
- 0xfc0b2e7d, 0x7e9b67a7, 0x785410ef, 0x27ace452, 0xaf57fb30, 0x97d6fabb,
- 0xd50e549d, 0x4f62a3f6, 0xfef85ab8, 0x55a595a3, 0x1571d052, 0xab5593d5,
- 0x3f4cb725, 0xc2f4bd57, 0x3f82cf8b, 0xf7668ff3, 0xf2bf0a70, 0xaf075da5,
- 0x8dcaf9a4, 0x366280d2, 0x18909b0d, 0xfd2d4ba6, 0x9876617f, 0x779b150e,
- 0xd8a35c99, 0xc2e307f7, 0xb8dca8f4, 0xf54644c3, 0x604147c6, 0x16c3a987,
- 0x23812e81, 0x12fec053, 0x09bbfd5f, 0xbb7a7ee8, 0x46a60640, 0x5deae7c0,
- 0x9e019f68, 0x4e9c8e90, 0xeae9ba21, 0x80ba52d7, 0xa4e8573e, 0xfae22f2f,
- 0x32b9e004, 0x7e5f9f91, 0xfe84e21d, 0xfcc37664, 0xdbbe5fcb, 0x6938f301,
- 0xfd7c63ac, 0x0f44d2dc, 0x925cb7ed, 0xb2989d13, 0xdfcfe5ef, 0x6f36fc8b,
- 0xcc89bdff, 0x6419e58f, 0x1e49b5c0, 0xbb9bf304, 0x5f9c16ea, 0xdf22f119,
- 0x96273f95, 0xdcfc7e80, 0x46368a48, 0x8d4f8b90, 0xb9380ecc, 0x74b81a86,
- 0xb2e9277e, 0xff337183, 0x14fc6221, 0x3f453f21, 0x2e7cbdd9, 0xfcc382d4,
- 0x4e8c51e7, 0x5c0d196f, 0xaf15a8ae, 0x65a6d7e6, 0x339f40ed, 0xe1033c43,
- 0x1896a5bc, 0xe10f8e65, 0xdc570a1b, 0xd190385f, 0x398cb887, 0xc3b51dbc,
- 0xd43be00a, 0x963c976f, 0xf23b4d2c, 0xffb86a4d, 0x74ff787b, 0x3f60d1dc,
- 0xbc8c4c9d, 0x2928180f, 0x71d74f72, 0xe4a97f15, 0xd37bc99b, 0x15be4cc3,
- 0x58dff779, 0x397fe504, 0xda07e4c0, 0xc748fac1, 0xe5881c15, 0xa809a63b,
- 0x1824cc0f, 0x249bae49, 0x72dad72e, 0xb8e84f85, 0x8a8c428d, 0x1c7e005f,
- 0xa6ed1fe2, 0x3b68a7b2, 0x85acbe95, 0xe1bd1cfe, 0x8f3b7229, 0x9009ffcb,
- 0xf2c3cbff, 0xb931564f, 0x95bedbef, 0x92553f11, 0x4167c5ff, 0xca7ca95e,
- 0xa957902e, 0xe9fde604, 0x3f83b686, 0x69f272a1, 0xad539140, 0x69cbd4fe,
- 0x097ba6f9, 0x4e5ea7f0, 0x475c1d3f, 0xfd29ca22, 0x074e511e, 0xea97fc77,
- 0x0e7f054f, 0x153fab49, 0x1e17d87d, 0xb7f0faf5, 0x53e21746, 0xefe90faf,
- 0xcde9c900, 0x29df0a7f, 0xdbf156fc, 0x77a061ea, 0xf0a97c42, 0x152f885d,
- 0x57cfd3be, 0xf97d3f8b, 0xd199f061, 0xf6bc9571, 0x4a1494fe, 0xc156aacf,
- 0xbb61766d, 0x78a790dd, 0xbfb330f2, 0x00ca7771, 0xcbafde75, 0x3df57407,
- 0xae897cba, 0xaf9757be, 0xb3f7d5d3, 0x9b4b487d, 0x041f2089, 0x45a5f535,
- 0xfc738644, 0xee226dee, 0x98e8bbbb, 0xaefb681b, 0x997ea90d, 0x16a583ea,
- 0x4eefbfb6, 0xfe803530, 0x3b7672ea, 0x616f20e2, 0x92aeb5fe, 0xcaac476e,
- 0x2ad23c3e, 0xf0edfea2, 0xfb48a293, 0x22d16a13, 0x5f483a9e, 0xa3bcece5,
- 0x5d0db450, 0x46977e08, 0x81ae0dd1, 0x39b7f539, 0xaba1bce0, 0xe986fd35,
- 0xb7dcfbf4, 0xe85f0c45, 0xc164768a, 0x31ec88b8, 0x0bed520e, 0x99f9114e,
- 0xb33e7489, 0x60fed95b, 0x5d9d0ace, 0x5f205641, 0x31eed994, 0xf6a45e81,
- 0x9fad51fc, 0x0577f19e, 0x4abe5787, 0x57b4ae5b, 0x4d158df6, 0xdf2f72da,
- 0x5c495667, 0xa3268c5f, 0x308f3ed9, 0xafd7093f, 0x0de66285, 0xbbfe29d3,
- 0xf80488f6, 0x4455a7a5, 0x106cf7fc, 0x226fe0fc, 0x4dca0272, 0xbd46e90d,
- 0x2ce9e0a6, 0x6fa985c8, 0xcb7673bd, 0xd00f3947, 0x3f5b552a, 0x9a77fac8,
- 0xc7fadd9e, 0xfe406f11, 0x3f4343d5, 0x17ebbd20, 0x79e0b76c, 0x3b76d76e,
- 0x6d76afc6, 0x01f437db, 0x7666bfc8, 0xb6bb38c3, 0xfc05997f, 0x5cc8b5d3,
- 0x6bab7a0e, 0x2cd7db08, 0x5665f6de, 0x4b93ae07, 0x90bf6e90, 0xa7aabed8,
- 0x858febf5, 0x59d29001, 0xddbffac1, 0xda9dfe8a, 0xa7182dd7, 0xcbedb5db,
- 0x87edaf1c, 0x3f0d4f9b, 0x93b2efbf, 0x7c609be9, 0xba7cecb1, 0x2f098df6,
- 0xabfed3d4, 0x6698779b, 0x3782f2d3, 0xfa059eff, 0xb3136bb0, 0x8ea53a6b,
- 0x7a7ce1e7, 0x8bedd2cd, 0x4ee78a24, 0x42648a10, 0x4df0d47e, 0x09199cbe,
- 0x7f477f2f, 0xf1f17f53, 0x7c18ffda, 0x53ef1808, 0x47f76ad5, 0xbfef3009,
- 0xe801fc7e, 0xe466ed81, 0x9fbe654b, 0xeed1ea06, 0x0fbcd8b8, 0xfdc7bcc3,
- 0x085bcd2b, 0x5fde67f6, 0xfbd393fe, 0xe385c921, 0x6f41cbd3, 0x1f76df3e,
- 0xbbb25fe6, 0xe4fdbc71, 0x7fa681f7, 0xa26fba31, 0x7c5c7774, 0xe4ff39de,
- 0xee9beef3, 0x74e2cf6f, 0x8c7de277, 0xe38eff37, 0xee7aaefb, 0xf3a1ffd6,
- 0xb373ec57, 0x8f3da4a1, 0x693a6f8e, 0x316183b4, 0x2f67a123, 0x8799c484,
- 0x8c0065fc, 0x8ae7e257, 0x332df1fa, 0x048ffdb1, 0x5fb4c6e7, 0xf7c08b72,
- 0x743f6c75, 0xae1fb73d, 0xf6865c1f, 0x661ef5e8, 0x496313af, 0x8858de49,
- 0x46e39aff, 0x3ec9273f, 0x2dfc85ec, 0xbb5e7893, 0x20577c2f, 0xe3da811e,
- 0xda2d0fd7, 0x0de9f603, 0x33418d83, 0xfa408f4b, 0xcf7f83be, 0x665feed5,
- 0xdbf9b578, 0xb7f36ba6, 0x82b77870, 0xbffb4571, 0x83f044b5, 0xf21a535f,
- 0x39f80254, 0x1112b9a5, 0xa9138804, 0x84fb0a5b, 0xedb44a5b, 0x767ec367,
- 0xf38f185c, 0xe153bca3, 0xa46a21fc, 0x61b8f880, 0x24fa8885, 0xf840532a,
- 0xc612b925, 0x28627e13, 0x173c01c9, 0xf35f198f, 0x0dce0633, 0xf1cf9df3,
- 0xd0ea4655, 0xbe1721de, 0x0e6266f9, 0xda0973f8, 0x843df34b, 0xf5ed475c,
- 0x304289b2, 0x3ce5ca9a, 0xb2639123, 0x9029cfc1, 0xa73f1aa3, 0x1fbf0f36,
- 0x5ce18625, 0xfc5f7eac, 0x7fa743f8, 0x347ffca6, 0x90cdda83, 0xf33bb9e2,
- 0xaafb29d7, 0x1e195b3b, 0x7f04ab6b, 0x5055f21a, 0x7c539f52, 0x85fe626d,
- 0x06383f3f, 0xe7ef2ae5, 0x7ed862a3, 0xcced032f, 0xf6676e5a, 0xf018aec8,
- 0xa6b4f46f, 0x02b1f3f3, 0x3f023787, 0xadfbe7ef, 0x3ef9c03f, 0x0b26bb4d,
- 0xfdd8228d, 0x78fd1ba4, 0x590b64f2, 0xee0e211b, 0xa7e29303, 0x1ffdc3a8,
- 0xa01cc4fc, 0xa3cdfb23, 0x54e2634d, 0xdd715b74, 0x6f566369, 0xa8efc03a,
- 0x1fe83cea, 0xefec2fc5, 0x2dfbaf00, 0x224a531d, 0x971cf7cc, 0xfeb7e2df,
- 0x6eb5f78a, 0x00954d6a, 0x164d372f, 0x9fa6e735, 0x75bef898, 0xe303190c,
- 0x1aeb7e2a, 0xcba004c7, 0xf70dd11e, 0xcf5b6ab3, 0xce11bc9b, 0x04f8f48f,
- 0x97dfe8f8, 0xcf8065dc, 0x42c7ff63, 0x8fb59f60, 0x4264e79f, 0x6e2674bc,
- 0x4fe03de5, 0x75e382fa, 0x7489d9aa, 0x4f38b9be, 0x66fda04a, 0xc3473b36,
- 0xaf325691, 0xad16153f, 0xc11c1071, 0x92f529da, 0x23bd58ab, 0xa44d6726,
- 0x128a2ff9, 0xfb8579f8, 0x9fe15cbe, 0x3f796e8f, 0x61f307b7, 0xeecc993d,
- 0x6be6f5d5, 0x53d1f282, 0xdf41f824, 0xf309fec3, 0xe03eecc5, 0x972b033e,
- 0x597a626f, 0x9e3d7be1, 0xcf0ccdd3, 0x3c05ff4a, 0xf0ccd23f, 0xc159e0a3,
- 0x4abc7eaf, 0xaeafaa7d, 0x6e21fb56, 0x32fd1968, 0xad3587ac, 0x4140d382,
- 0x4c3b18d5, 0x2db58720, 0x67e04b8f, 0x7062e19f, 0xa5907ae9, 0x6a9dd73e,
- 0x6debe766, 0x02cd57d9, 0x056cf93e, 0x7b684bb5, 0x0ef39ccf, 0x19f77758,
- 0xbdc1efdc, 0x915df949, 0x7d16fdac, 0x79cf81f5, 0x1aa364ed, 0xf38e2a6e,
- 0x093caae6, 0x57b726dc, 0xaa0690ed, 0x39aa69f8, 0xef95cb0e, 0x6cae55c9,
- 0xc3fb4ef8, 0x998fc871, 0x6787c409, 0x3ef1da06, 0xb175edda, 0x03cb0f8c,
- 0x4f984c3b, 0x7f4afac5, 0x797a3f4a, 0x8dac569a, 0xd05d99fb, 0x52f01831,
- 0xe3de0e6c, 0x9da7c08e, 0xbbe40e9c, 0xca1e13ae, 0x8bff59b7, 0x947b89d6,
- 0x2a43a275, 0x6c89c551, 0xa73d3335, 0x4606275a, 0xd416275a, 0x1d0206bb,
- 0x1f4b6c16, 0xe0b24208, 0x48c4c2ed, 0x3efbc4eb, 0x88785e76, 0x9aecdfdf,
- 0x2b89d746, 0x34c4eb54, 0xbe89f20b, 0xc4acdf9d, 0x9d645d61, 0x5ff6e850,
- 0x87de6fac, 0x7c822275, 0xd76b366f, 0x4b5b5b89, 0x75b89d71, 0x57b9a89a,
- 0xb17cdeb1, 0x712f2275, 0xb725e606, 0xbcff0235, 0x43e1edcf, 0xfa0ebe3c,
- 0x34e2f581, 0xde84ffe8, 0x7a5f46eb, 0xeafeb1fd, 0x3c26fff5, 0xc17d7a2b,
- 0x781eec2d, 0xc8243e6f, 0x50660bcf, 0x3f002ebd, 0xe0bebd32, 0xd317ee0e,
- 0xd012d9e9, 0x7ad563b3, 0xf1afb596, 0xb6a175b2, 0x3317f525, 0x1a4ff969,
- 0xad147725, 0xdeb093ff, 0xddeb51cd, 0x1377a0d3, 0x72dde822, 0x6b3f77a6,
- 0x53f6831d, 0x88fbf35f, 0xcfaa5beb, 0xf811dc32, 0xab4cfa63, 0xb1ce9ee6,
- 0xdccbbfd1, 0x4fb2f20c, 0x4fbb73c4, 0x77b01db8, 0x82c6eff4, 0x144a7a9f,
- 0xa71c4f1b, 0x5c8fa767, 0x81ea993b, 0x9ecc3982, 0x2220deae, 0x999a6afe,
- 0x4464d7fc, 0x3f345dfb, 0x26affb25, 0x636e57c8, 0x06746fe7, 0xfa2a79c5,
- 0x68ebee57, 0xe5703f00, 0x0fcf016a, 0xf019ce21, 0xb3e38f39, 0xfb895dcc,
- 0x80fc7d15, 0xe6ad17e2, 0xaeb7e6f5, 0x3ea9ff46, 0xe33aa0ae, 0xafb0d3da,
- 0x3a333628, 0xfc166f14, 0x1ce153ab, 0xfdcf575b, 0x541b9e30, 0xc7dfb407,
- 0x15cef9f0, 0x619b9983, 0xe89ef55f, 0x8dceb48e, 0xfca5e3d1, 0x7ecbc41f,
- 0xffb1978a, 0x17d2f1ef, 0x8f7da81e, 0x3e3d64fe, 0xbd7145c6, 0x82c64d92,
- 0xf0627e1c, 0xdf915ea0, 0x642e3111, 0x35c3e3ce, 0xa20bfef7, 0x67dabe98,
- 0xdc4036f0, 0xe2c35cae, 0xdaade647, 0xe6912bb8, 0x68c80667, 0x5bcf4770,
- 0x43875da9, 0x0bb37eeb, 0x7599f5d7, 0x1388051b, 0xfdefcb9c, 0xc71ffb94,
- 0x58ee12f7, 0x5a79d748, 0xd9b6767f, 0xfb9fe70b, 0x37a8dd2d, 0x105dbe15,
- 0x3a97ecc5, 0xc9638e3e, 0x7d7193dd, 0x289c116a, 0x5b0b418f, 0xe09d28af,
- 0x09b6871d, 0x74e14e5f, 0x16887e61, 0x4a5ac746, 0x29e79037, 0x8ebf3cad,
- 0x2bb781d9, 0x77e080f9, 0x7757a009, 0x085dec48, 0x9c0bc481, 0x11f5aa08,
- 0x12f2d5ce, 0x76de7455, 0x5afff184, 0xfc1f8dc1, 0x43efbff4, 0x9ef93ee7,
- 0xe5fd31d9, 0x0b4f0577, 0x6fde7474, 0x831e2f69, 0x1b8233e7, 0x8d68c7df,
- 0xe38573c5, 0x079dec8d, 0xcbd3b799, 0x5c3bec05, 0x8dcabf2a, 0x1f887030,
- 0x9c60b22d, 0xc69bf61e, 0xbded32ec, 0xd7135940, 0x4ee35df3, 0xda3b496a,
- 0x3178e163, 0x802637ef, 0xb5182457, 0xc8dd5c71, 0xfc003fe7, 0x02dfcdd7,
- 0x3139249f, 0xa76ef46e, 0xeec9ddf2, 0xdb7cf06f, 0x33439c90, 0x5b3f7e29,
- 0xdd79e22e, 0xc1d7066d, 0x1e6fa089, 0xcbc80891, 0x0f257b67, 0xb8ac075b,
- 0x3bee94ee, 0x4a5ef786, 0x2911ec59, 0x2fad887d, 0xfe78f8c7, 0x0f6dd744,
- 0x604844f8, 0x4dfbc41c, 0x7428ef73, 0xec64df81, 0x2e70a5fe, 0xf3817376,
- 0xe7a041e0, 0x93bdecc3, 0x700bcba3, 0x4ff7769f, 0xc3b79405, 0xfed06e94,
- 0x07a96996, 0xef7ed20f, 0xe7809e58, 0x093d335c, 0xd7b9c2b7, 0xdba2bdcc,
- 0xbecdeb45, 0x73836ec1, 0x4523a9af, 0xe7e155e2, 0x7e8ed20e, 0x3f75999a,
- 0x5dc605bd, 0x3143d74e, 0x85fdd215, 0x4abf2103, 0xb2b5f6c0, 0xb29034d7,
- 0xf3cafb4e, 0xffb4b1a6, 0xd00f5a32, 0xd58abb5e, 0xdc126dab, 0xd65b7a10,
- 0xcbea38fa, 0x1f0126b2, 0xf6a76896, 0xeb83146f, 0xdb70a28f, 0x34f6d157,
- 0x03da0f3f, 0x5bd8a6dc, 0x96ab3ce1, 0xe7db138e, 0x6479e3d6, 0x8b476d19,
- 0x4fd37b49, 0x55fcde11, 0x447b8102, 0x8fa9b9e5, 0xbdbc02e5, 0x0fca1b92,
- 0xc625f8ed, 0xfda2cc8d, 0x67f0a20d, 0xe8851d8b, 0x70407b57, 0x83233be2,
- 0x5d7e9033, 0x70686130, 0x64fd0d3c, 0x42e9d718, 0x71d51834, 0x1616c908,
- 0xb0b65cdf, 0xd5e601be, 0x1aa42721, 0x9bceaf90, 0x4e3f1d60, 0xf6a5edf1,
- 0x8b1331eb, 0x8f93686f, 0x7a543a99, 0x1d25bc74, 0x969cd8f5, 0x9f2f3c3c,
- 0xbcf04a4b, 0xeccf5bdc, 0x2d4b2391, 0x30ec017e, 0xbe1439c9, 0xe3352db7,
- 0xd897cef7, 0xa439d3fa, 0x27a1fd03, 0xee044957, 0x955e2d39, 0xf1d00cfe,
- 0xf90906e4, 0x424e7c4d, 0x25ef363d, 0x5b6b27e6, 0xbc9ee0c5, 0xcfdec4c7,
- 0x9f9a7281, 0xff651bf7, 0x6563d5ab, 0x53d40aae, 0x2bd4bd7a, 0x7aa9efee,
- 0x2f6cb013, 0x14cf757d, 0x741557d4, 0xeb4601dd, 0x3706afa5, 0xaf52bfa0,
- 0x4d896aaf, 0x10d953d1, 0x3d5a5237, 0xe04ad664, 0xc0583be3, 0xb5f07b76,
- 0x75869fcf, 0xe04ecab7, 0xf9d18d4b, 0x82f8c08c, 0x6cccbc80, 0xc839f8dd,
- 0x0b4cf941, 0x0273bbbe, 0xb37200e8, 0x59c59e22, 0xdf114bf9, 0xbce51c4a,
- 0x573e5a95, 0x7867b5ce, 0xaf51e245, 0xe256e55f, 0xf43bd551, 0xda57e510,
- 0x822d9dcf, 0xfe4022df, 0xc77beec8, 0xe389de62, 0x83edc85a, 0xe7e47615,
- 0x5f9ff743, 0xeb3afc0a, 0xbd808141, 0x036f644e, 0x2b3587ac, 0x65f81705,
- 0xdac83de7, 0x61eda3cf, 0xc97e87dc, 0xb7f28af8, 0x66bff80b, 0xb1bbe3d5,
- 0x02e0937e, 0x975687f8, 0x2e513da2, 0x9bcb048b, 0x81fee08e, 0x5f1853ae,
- 0x898b26d4, 0x4b35ffc0, 0x95304ecc, 0xf8523e14, 0x17bf08f2, 0x59dca24d,
- 0x9f76d337, 0xde849000, 0x174e28fc, 0xf029eb42, 0xf8ccad49, 0x924bc8ec,
- 0xe2e6d81b, 0xc3eec97c, 0xabebe49e, 0x532ddcf8, 0xd73cc106, 0xb68638b2,
- 0xb0260555, 0x05fa4e23, 0xcdef8f3c, 0xb6a6c497, 0x7cbe14a3, 0xfafa604e,
- 0xbda87162, 0xa5f38ef8, 0xa9947fc2, 0xb5595f71, 0x0f702257, 0x5e8fcf57,
- 0xc42b7029, 0x4cbe940b, 0x5bc743e7, 0xda3f70d0, 0x691e0aeb, 0x65f2113e,
- 0xa1ef1646, 0x91b543c8, 0xe77d05c5, 0x37fae9f1, 0x7961ec5b, 0x4adc5910,
- 0xbbfbf690, 0x9c602f0d, 0x47f5b9dc, 0xe6fb47ae, 0x8007ca0d, 0x12760dff,
- 0x1f87fdc4, 0xb34550f5, 0x4238c1e8, 0x66e73063, 0x895dbed5, 0xc57ca897,
- 0xd8aef88e, 0xd317f664, 0x8f5b15f6, 0xf5f9e165, 0xe78c6ea2, 0x680bd790,
- 0x23b9131f, 0x546fee0b, 0x86dc5918, 0x64582ede, 0xb3aa7e61, 0x83a759af,
- 0x63ac26dd, 0x045569ef, 0x2acc936e, 0x16fdeebf, 0xe787a949, 0x33a53229,
- 0xf18693dc, 0x5271dfa9, 0xfece35e2, 0x455ff186, 0x5cf6848b, 0x9d8dbac5,
- 0x71577f10, 0xdcfb8cd8, 0x31e775da, 0x95e0b89e, 0xae1df097, 0x135116da,
- 0xee2bd57f, 0xe7889d69, 0xd5cd351b, 0xf341bf18, 0x1351ce78, 0x77ff1c88,
- 0xca9cf8b1, 0x956db657, 0x372b0a29, 0xef81daff, 0x75afb572, 0x7593bde0,
- 0xd8771edf, 0xf029ce2b, 0x39c6b7f0, 0x507f819d, 0x45adfac6, 0xd644e71b,
- 0xc746bd31, 0x9ee91397, 0x7adec841, 0x21e7f3e9, 0xa6ecf70e, 0xf1879f4f,
- 0x67e7fd56, 0x061c43cf, 0x82716ed9, 0xfebb523d, 0x54638c7d, 0x30b2edda,
- 0x37f3affb, 0xcff8c6bf, 0xdd9a3fce, 0xdb73ad00, 0x6f60a1c9, 0x6bfc6e74,
- 0xde75c422, 0xfd10adb3, 0x296cf739, 0xf8224818, 0xf814940b, 0xf88fdfd6,
- 0xdabd3d53, 0x5e30db9a, 0x37a51ce4, 0xdc5087e8, 0xc59aa05a, 0xbc78ba01,
- 0x71c886da, 0xd3e2bdbe, 0x61be6f9a, 0x66c5e812, 0x345c1766, 0xa500ed4e,
- 0xa0fd15e3, 0xb98786df, 0xbf4c893e, 0x4a0ff073, 0xfa3a63a7, 0xf73cde7d,
- 0x5942cf57, 0x719f7c73, 0xe07ec16a, 0x0e23894d, 0x169d3c58, 0xbf4d9b90,
- 0xa040b8c5, 0xf40bb15b, 0xc143e7f3, 0xea4a7c2f, 0xf743ff46, 0x5bde3336,
- 0x0876d8ab, 0xcb73a7e5, 0x25d38c7e, 0x93b79e3c, 0xfe2c7e84, 0x6a7afb92,
- 0xbe2cec9b, 0xe21fe38d, 0xfc0e5cdf, 0x18dce3ce, 0x6ff12b1f, 0x0dbdc57d,
- 0xefe34e8f, 0xbcf8b02a, 0x780fa6ea, 0x5e98591c, 0xe9d02e42, 0x13c6b7c8,
- 0x0270782a, 0xe3abc61e, 0x17c72338, 0x397de286, 0xa07e80bd, 0x9a7143a7,
- 0xe2183f34, 0x21c2fcf6, 0x741f4112, 0x9ff166ae, 0x1ef6929d, 0x2c3e9868,
- 0xad15d3ae, 0xff7f5393, 0x362f39e2, 0x9f8aeffe, 0x269768d8, 0xd3c151ae,
- 0xf5910bd9, 0xf0b44178, 0x9a93dd8f, 0x05efe823, 0xc02747e4, 0x1311f979,
- 0x7c5e7bc1, 0x37dca4ff, 0xb3b4fee2, 0x0b8c45eb, 0xa1b4086c, 0x8bebd71e,
- 0xa24e7e1a, 0xd12def1f, 0xb4d54f4c, 0xece275b0, 0x46dfbb26, 0xeb7d9ce1,
- 0x9ae7e435, 0x324c470d, 0xdd7bb785, 0x2b8b1366, 0xeb03f260, 0xfe355f84,
- 0xc8ef2fb3, 0xdfcdbd42, 0x33f7d215, 0xdb53f79b, 0xda9fb91a, 0xfd35e70d,
- 0x9301ca54, 0xfef176d3, 0xb73d18ce, 0xed33bc01, 0x133a5ecc, 0xdd228b10,
- 0x2d12998b, 0x2373fdf1, 0xf5d373f3, 0xb257df12, 0x4494f7b3, 0x5fda3447,
- 0x0f73d8f7, 0xd4800cc7, 0x8b127184, 0xc55c79eb, 0xa024ee43, 0xb5fb62f7,
- 0x14bbc604, 0xc7daabf0, 0x012f4e4b, 0x2a4a4dbb, 0x673eab19, 0x1a6fc651,
- 0x157e2060, 0x17b1effd, 0x27fd840d, 0x6183ca31, 0x7da7d71c, 0xaff58469,
- 0xf7fcc7dd, 0x0cb1c2e4, 0x746edef8, 0x70a78aee, 0x6e0b27db, 0xe6f6bd70,
- 0xe43f067b, 0xdf68f04f, 0x7a588485, 0xdb8f5f98, 0xdda0f680, 0x2ad27410,
- 0x4f696ec4, 0x8bac0dc2, 0x18898cb8, 0xe8718f02, 0xa6a2f88f, 0x073abdc1,
- 0xd429e6a1, 0xef351b73, 0x1ae4c424, 0x9026ef75, 0xbd741903, 0x557e71b1,
- 0xf67672fc, 0x03b70a6f, 0xcd8863df, 0xbec0f524, 0xb45eec2b, 0xefe49e1b,
- 0x48dfd058, 0x23886788, 0x3bf56ed1, 0xcd5fb42e, 0x5fb410fb, 0xa3d63e4d,
- 0x1917c7cd, 0x5f5a478f, 0xa638f9e2, 0x43c43688, 0xd941a16c, 0x4f0f15af,
- 0x363b8f0c, 0x5083b881, 0xe30d9d7e, 0xc978a9c0, 0x6cd879ea, 0xf1d371da,
- 0x4c44f469, 0x606c8766, 0x777cd4e3, 0xf3809712, 0xd3bf68f7, 0xdbf26af1,
- 0xaa3c79a3, 0xdf411891, 0x09daa2d9, 0x068f7fc7, 0x7b8c4bdf, 0x7d022487,
- 0xcb57df08, 0xc411ee04, 0xfed079f0, 0xe09df535, 0x6bfd601d, 0x4ec190e1,
- 0x2bbf7df5, 0xccb7faf8, 0xe81ef25a, 0x75619c9b, 0x313bc818, 0xbde26489,
- 0xa801d6d5, 0xe616d29f, 0x2f346393, 0xcabe3234, 0x6e504158, 0x9c59ba32,
- 0x8d12590a, 0x8a39a8f6, 0xb86c96c8, 0x296444c7, 0xf3f17a1b, 0x22d725f3,
- 0x5c650503, 0xb68d794e, 0x37ceed6b, 0x0844a5cc, 0xbf851140, 0x31f3da37,
- 0xa370dff4, 0x1a30c937, 0x74b7de3e, 0xda9460e7, 0x6823c14b, 0xb5ddee10,
- 0xe90b0867, 0x089af781, 0xf01777b9, 0x4f286378, 0xbacf7082, 0xf7943a31,
- 0xdf7d5144, 0x67f2c698, 0xba5defa3, 0x3fbbc29c, 0x346ce4a6, 0x79ca278c,
- 0x05779e19, 0x17fe70e3, 0x71945f5b, 0x98ea6c8e, 0xf9963d12, 0xcf1de14d,
- 0x3dd0f6e1, 0xd7875c6a, 0x107c94da, 0xcd2511f7, 0x55af51fb, 0xb963f607,
- 0x1d34f201, 0x2531df16, 0xeb109625, 0x930b4ba3, 0xfd78852e, 0x9d0324d2,
- 0x974780e7, 0x60fb82ee, 0xa23c3c61, 0xb0d183c1, 0x499ed77c, 0xdf2c3c6a,
- 0x7f487605, 0xbac030f1, 0x89f2e97c, 0xe5379ffd, 0xc42b788b, 0xf019e43b,
- 0x87f1a5dd, 0xa15fe86d, 0x47ae0b3f, 0x3eeace1c, 0xfb2abfee, 0xc5270a11,
- 0x5fcc2e3a, 0xaf853b4a, 0x749be2fa, 0xbd8cbce2, 0x9fe5a7af, 0x0327ab62,
- 0x7ab70de0, 0xe1c6d9f6, 0xf63ef1fc, 0x3dd7af54, 0xaf984c79, 0x063bcd89,
- 0xb32ef7ee, 0xaaca35de, 0xcd4ecbf2, 0xd1a6205b, 0x2c8166f1, 0x93e78424,
- 0x8cb650b0, 0xf04cf3a0, 0x7ace3018, 0x063bd599, 0xef4c71fa, 0x8495d20e,
- 0x31de009a, 0x0b961882, 0x6d86bfa5, 0x50debf6c, 0x622ff06a, 0xc002bde7,
- 0x8747f30b, 0x19ba3f8e, 0x411cb47f, 0x3d69a8fe, 0xa5a3f8c2, 0x0bf81f3e,
- 0x9f60cdce, 0x47ba48df, 0x79afdd03, 0x48d0a9b4, 0xb5987ff9, 0xf28521bb,
- 0x14d64485, 0x788a5f16, 0xaf8c31fd, 0xf8f87d17, 0x45f57994, 0x693dc6df,
- 0x7ec2668f, 0xcf01af72, 0x85bc14bb, 0x8b2b07ec, 0xf7641c23, 0x6a7e834e,
- 0xc3763b73, 0xf9ed37f4, 0x70db8c0f, 0x0769bdec, 0xa34c77b4, 0xfb857214,
- 0x08bbdc6d, 0xa46dcbdf, 0x319000f3, 0x75865ba4, 0x307c6fbd, 0x03e109f9,
- 0xc04c9eec, 0x979411c7, 0x109efcf5, 0xffbc3b95, 0xdecacc3a, 0x65679865,
- 0xac07e7fb, 0x1d994f22, 0xc7b7b096, 0xdaadfb04, 0x9fac0625, 0x7aa66900,
- 0xdeb04bfe, 0x26a35603, 0xa7a14e5e, 0x93544fc2, 0x877de15a, 0x3def588c,
- 0xb389fe5a, 0x29e0a9a6, 0x11f31eed, 0x4a0c9cf7, 0xdd779d87, 0xe52aeb0d,
- 0xed351b9f, 0xc0164946, 0xf81f529b, 0x687d1233, 0xae8c45bb, 0x17b05671,
- 0x205cee36, 0x7f42f9c2, 0xef039ae9, 0x39fad1c7, 0x89b75256, 0xa189cfb6,
- 0x79e3e429, 0xa7cf207e, 0x43fd34b0, 0xdfa041b7, 0xebbf7357, 0x171e56b3,
- 0x065e7460, 0xcb3c53ef, 0x29313af1, 0x4505d71a, 0x8066c16e, 0x3f236b73,
- 0x4eeb4ebf, 0x14dd0033, 0x1b763639, 0x68ba7682, 0x065d19a5, 0xc7786388,
- 0xec6de747, 0x7b5cef5b, 0xa7bfbb29, 0xa732feff, 0xafb6f7f3, 0xaf75eabf,
- 0x4ba065f7, 0x63c75475, 0xcd7cd137, 0xf9e19fa5, 0xcd6b22e0, 0x3b73ea55,
- 0xff1faa7d, 0x3a4e173b, 0xfcec3ec0, 0xc9145cca, 0x32b0eece, 0x6f8f77fb,
- 0xec53b63a, 0xe815242e, 0x413df564, 0x5768a633, 0x1e5508fd, 0xc63651d0,
- 0x656afac1, 0x75aba4fe, 0x147f03f7, 0x42bd7e64, 0xf41238d2, 0x5fd58e64,
- 0xe5c38b8c, 0x481718e9, 0x51f662be, 0xce0ffd14, 0x79f90a97, 0x73b0e798,
- 0x397f2c27, 0xe3938d31, 0x2a4c7ea0, 0xda23cfc2, 0xe272b9f7, 0x5de82365,
- 0xf08a9e92, 0xe574a20a, 0xd1da0903, 0x30cb92e4, 0xa890ab9e, 0xbe3a31ec,
- 0x6fc6749c, 0xba964753, 0x9feff327, 0x6cfaf301, 0xd61319c4, 0x66b8d7f3,
- 0xec6b27b8, 0xe8374694, 0x5dffdfed, 0x3c5233bc, 0xe31b78c5, 0x12be3dc7,
- 0xeb339c37, 0x12ef9af1, 0xbd5dd896, 0x9fc7abf1, 0x3e0adf1e, 0xfbcb78f5,
- 0xce393dd0, 0x7a3f1bd5, 0x5074287c, 0xc7c7acf0, 0x8a6ff03b, 0xcd3277af,
- 0x3bdacef8, 0x77df8646, 0xdec8b9a8, 0xfda0f46d, 0x43c7c85a, 0x4fb457ed,
- 0x6eec120b, 0xe29e1ec6, 0x78f0c4c2, 0xe3d578f5, 0xe3bf8731, 0x7c446242,
- 0xe0377447, 0x0161f28b, 0x7ed04c1c, 0x7099b60b, 0x578248ff, 0x06fc7513,
- 0x47be061d, 0x17973577, 0xd6392f05, 0x00b19dba, 0xe78a9ccf, 0xa57f57d7,
- 0x5b0b67b5, 0x7f069ca7, 0x778c4e40, 0x8941f809, 0x5f384a98, 0x15f2d51d,
- 0xd535971f, 0xa8eaf9cf, 0x9198af8e, 0x0bcacf13, 0x74f2ba9d, 0x85507e82,
- 0x56f3f4ef, 0xf815ebf8, 0x9e37a130, 0xb2cafe14, 0x993bfb71, 0x387b060c,
- 0x31b1b5eb, 0x6b499fa0, 0xc3bf445c, 0x2125c3f8, 0x914f9c38, 0x0de2050f,
- 0xffa6777d, 0x9daa7a03, 0x3f2a82ae, 0x5bd10cc0, 0xa7a08b60, 0xc4993e14,
- 0xc88935e9, 0x347fc03b, 0x12ff1889, 0x5553f7b2, 0x99e657f3, 0x9e605242,
- 0x4c5d58af, 0x8679f3bf, 0x47cd4de6, 0xde44fba0, 0x1b28c4ff, 0xdd20b7de,
- 0xfc21b3c6, 0x32bbe1a7, 0x3c2e29b2, 0x27d7890e, 0xb308eb43, 0x7be266d7,
- 0xe42f14b6, 0x1c786b1b, 0xc4609b5e, 0x38f85677, 0x928badce, 0x79ed4e21,
- 0xec073bd1, 0xdec2b3b8, 0x319f9c2c, 0x37d60238, 0x2d67f97d, 0x9ca06b3b,
- 0x7ac32bd6, 0x2295fc7c, 0x6f742ff3, 0xa4d7fb33, 0x52876df6, 0x4075c671,
- 0x70899f91, 0x900af15f, 0x8c0a60b7, 0xca586afb, 0x7cfdba68, 0xf2fbee39,
- 0xd08db25a, 0x299eaecf, 0x4f9f9718, 0x5fb0463c, 0xe7af7cf5, 0xeb3f3d6f,
- 0x8fec37f9, 0xfb0a1ee8, 0x2fcaef90, 0xe2169d8a, 0x6f94c39b, 0xc29beb54,
- 0x1e7f942f, 0x8d75bc05, 0x3019e4fd, 0xfd8df7ab, 0x37d6112c, 0xdb0f0ec5,
- 0xa0c79e1b, 0xb8f65f5e, 0xbbff8762, 0xf034fbcd, 0xcf7491a3, 0x2369f682,
- 0xefb8065d, 0xf3cdb6fe, 0xec577c0c, 0x2bed8b93, 0xe1ba4ec8, 0x8b337ca5,
- 0x206021d3, 0xbcabdef8, 0x753d4040, 0xa096e907, 0x24ea3bbf, 0x9675fecd,
- 0x07e3fba5, 0xfeb03ce0, 0xf2078c12, 0x889a9442, 0x715c59ed, 0x31efbf03,
- 0xe0047bb2, 0xda85cef5, 0x64d8f8f6, 0xcd5df84e, 0xafb6058f, 0x48e9659f,
- 0xa5b47b80, 0xbebeb6b2, 0x7a1e657f, 0xb576fab8, 0x78219dfc, 0xb2add8b7,
- 0x31b55e0b, 0xde34263b, 0x03bbf877, 0xf006df14, 0xea5eb4d7, 0xff02247f,
- 0x2a37a92a, 0xaf18d32e, 0x99b62fb2, 0xff7a47a7, 0xc147e943, 0xaed24cf7,
- 0x916ff3e0, 0xe89a2fde, 0xc37dfb65, 0x79cd4153, 0x746692bb, 0x2ebb464f,
- 0x1da02023, 0x33c8155d, 0xf3d8d6cc, 0xcbdbbf6c, 0x2977879e, 0x0ef37ea0,
- 0xea07cf66, 0xd5505f71, 0xab37f6cc, 0x99398ce1, 0xed13240f, 0x15bed0fc,
- 0xe1aaa0e2, 0x1e563f9d, 0xe9e6ab84, 0xd7feac8d, 0x87a685b6, 0xe9df6033,
- 0x34dc924d, 0x86a1e2bf, 0x6a3fba28, 0x42162548, 0x5d7f47f7, 0x1594d0f1,
- 0xe2ca54b9, 0xc589023c, 0x426d837c, 0x5fc9f7ff, 0x01b078af, 0x7f74c9f6,
- 0xed5363d5, 0x8f92fb5b, 0xe21736e3, 0xeafdafb1, 0x5f2531fd, 0x077e54db,
- 0xa27bfd3d, 0x7fc0315c, 0xf47df30f, 0xc2ef0bb5, 0x92e581fd, 0xde21430b,
- 0xbba7226b, 0xa9fdced9, 0x3acf7656, 0xed9af45f, 0x5d6fdf20, 0xe27e0118,
- 0xc31e4677, 0x7f2b597d, 0xafaf716f, 0x8523ed1c, 0x6676718e, 0x697b5fd7,
- 0x15f6039b, 0x03fb8dd7, 0x673f0fde, 0x9d99ef64, 0xec6935cd, 0x856c87d8,
- 0x495f0071, 0xd044da29, 0xeec713cb, 0x7ceb0c3c, 0x5843eb5f, 0xd0047bff,
- 0xfec2e4ff, 0x69df3c44, 0xbf00e5de, 0xdf7e59cd, 0x5b735cfc, 0xad345de2,
- 0x0707f8de, 0xf9d2a7ec, 0xdb19cefc, 0xaa9b7df1, 0xcbbe222d, 0xbc4dfb40,
- 0xcdc7fc1d, 0x611e73b3, 0xd7a944dd, 0xd5dfc23f, 0x49bfec50, 0xaf9fb251,
- 0x12df8a87, 0xbab8e1df, 0x1c58f459, 0x73c0edbd, 0x2c9ed27b, 0xc9107a06,
- 0x1a3e1c3d, 0x0bb44ec9, 0xfd0df9f9, 0x7ef784ed, 0x9bccf3b7, 0x7cdd9fcd,
- 0x73913215, 0xd802e5c9, 0xcc01de47, 0xb0f4c739, 0xfd5dbf62, 0xa93fd695,
- 0x5bf31fb7, 0x21492f47, 0xdef60f88, 0x1fc9b77b, 0xec2ecec9, 0x9ed1129e,
- 0xc471e424, 0xf496f657, 0x4cfef0a9, 0x2706dbf6, 0xcec83bf4, 0xf9b6b1f8,
- 0xa51f7c33, 0x856f0486, 0xd1669af2, 0xa6df2419, 0x1efc979f, 0x57545efe,
- 0xbe02e4ab, 0x15dd6aed, 0x16f90595, 0xb55dfd11, 0x0e5e26fb, 0x2ad9d67c,
- 0xb5213be1, 0x80713edb, 0xf7d6501e, 0x7ef656ce, 0x31eb5748, 0xedc0aefc,
- 0x1cbf896c, 0x068d9dd6, 0xb9dcbfb6, 0xd0566ffb, 0xe85e6f0b, 0xad7dc789,
- 0xb6f73eb2, 0x052f117f, 0xbfe43176, 0x44bfdb55, 0xe200789c, 0x24630a9f,
- 0x3b610a22, 0xfcfad7b5, 0x27625921, 0x7ce9d7bd, 0x08c5f758, 0x37c735eb,
- 0xfc08cfed, 0xefbf5fae, 0x6a7b73b5, 0xf786c908, 0xc42e5af5, 0xcdbde257,
- 0x1173ab56, 0x5d985ffa, 0xccf3b5d2, 0xfbe15313, 0xdbdd915e, 0xdf2220bf,
- 0x72bdb5bf, 0x8d4d8758, 0xd7a406f7, 0x77ce8317, 0x7feb41be, 0xf99a2bb1,
- 0xcbee8da3, 0xc206f7d5, 0x5f1cfdf5, 0xae7664c1, 0xbbc32725, 0xeedbdf38,
- 0x2ef5eeec, 0xb47613d5, 0x80a7bb3b, 0xeab11dfa, 0xc5f40988, 0x53c97b20,
- 0xac040f4c, 0xe4991780, 0x6fda10a7, 0x07c93479, 0x27aeeafe, 0xdba3884e,
- 0x0060c7b2, 0x9b5d8cba, 0xeb2ef18a, 0xfcdfb9f9, 0x5529a340, 0xf3e65fa5,
- 0x9253a373, 0xf54e343c, 0xf4c1d93d, 0x155da9c0, 0xf93d42bf, 0x1e193347,
- 0x1bfc5d61, 0x4d9b67d7, 0x500dd4f2, 0xf701a8ef, 0xbf773b1b, 0x69de1bbe,
- 0x35d87f9b, 0x0399d61a, 0x5eb40f20, 0x0df5decb, 0xf2db2f10, 0x6aef4121,
- 0x68a9534e, 0x41befda0, 0x760fcc5c, 0xe0fb80c0, 0x7890ff90, 0xfb9e61e2,
- 0xf9bf6ced, 0xe6831ec6, 0xfe0de99c, 0x765be83e, 0x33b7c189, 0x3da6d43f,
- 0xb7a0f1f9, 0x6fbdd907, 0x8f6b1e00, 0x5c383477, 0x6299bf61, 0xb0384d27,
- 0xfa28ea69, 0x0d6709cf, 0xebb7204e, 0xe6111ac0, 0x48453aeb, 0xd97a40ac,
- 0x2ede144d, 0xce37bc35, 0x1c747832, 0x2a9c816f, 0xef2ba7f8, 0xff3499a3,
- 0x0e31bb46, 0xfc14a4e2, 0xfa50f32b, 0x67880577, 0xc9450db5, 0xfc5be9b3,
- 0xe69c4ab7, 0xde512718, 0x9cbe4727, 0xcfbcf76a, 0x3b4641f8, 0x68aed4f6,
- 0xf33647b4, 0x95248c75, 0x29fc030e, 0xa782fa74, 0xeafa78ca, 0x075f3cff,
- 0xf2bbf494, 0x25c97af5, 0x77f0df23, 0x30725cfa, 0xb1e21d2a, 0xeff1d25a,
- 0x55e2a8a1, 0xa93e03cf, 0x87f8d602, 0x060c3a5a, 0xb3554fb8, 0x67c5884d,
- 0xd769fa42, 0x18ccf886, 0x396bfe40, 0x2b8e504c, 0xf994fdd6, 0xe1bea8ef,
- 0x79e157ef, 0x3f0fc834, 0xd0241e97, 0xeaeb4274, 0xdf8829c5, 0x2ae403a0,
- 0x372a278c, 0x9a35d690, 0xdfe75f80, 0xfc79d2c3, 0x4afe777c, 0xd967ca2f,
- 0x67a7162a, 0x38e2a475, 0x257e71ce, 0x8864e886, 0x1bb068e3, 0x4fc9f134,
- 0xdd3dbe70, 0xf41b64fc, 0xd62bf94b, 0x6cafcb41, 0x1819fc79, 0xa7afc2ae,
- 0x5384249b, 0xff3dad1e, 0x7830744e, 0x7e300e5b, 0xe524d09f, 0x1349fbc3,
- 0x7f04e264, 0x6b4d1bf0, 0x6fdfd045, 0x32a73f00, 0xfd758739, 0xac47aed4,
- 0xeef5833f, 0xdf808188, 0x9489b379, 0xc5c9546f, 0x6aafd5ce, 0x5d62b7e4,
- 0x6ff454fd, 0xa009c477, 0x55b915e7, 0xe4d9bef0, 0xffe506be, 0x4ffc9d7a,
- 0x418bed66, 0x27bd6858, 0x593ffcb9, 0x7e9fe544, 0x158a6d8a, 0x5366ce00,
- 0x26b4f7e4, 0xff1fbe39, 0xf1eaf485, 0x92757a5e, 0x1de7ed83, 0x9affb4e9,
- 0x3f707aeb, 0xe71f1a1f, 0x2b27279b, 0x002a937c, 0x05291bfe, 0x145f0033,
- 0x68cfc0af, 0xcdbe82b7, 0x8277c34b, 0x22e3f37a, 0x234ddce5, 0xa6bd61b7,
- 0x06f7afc8, 0xe4ce4f18, 0x5f60c5ba, 0xc8cb17c7, 0xef05a7a7, 0xaeba38b0,
- 0x8e79069d, 0x394617a0, 0x42f91e98, 0x11de6af2, 0x920e3def, 0x4e5d7c0c,
- 0x2f306a77, 0x02704ab2, 0xd772947d, 0xe09fbe2a, 0x4aef94f0, 0xfde37bfe,
- 0xbdfcbd2f, 0xb8718e55, 0x6420999e, 0xad9f8473, 0x47c84467, 0x6b8620b9,
- 0xe6de4193, 0x27ec75d3, 0xb4ec75aa, 0xaafc88d4, 0xce3ee1e0, 0xb2c45fef,
- 0xfce70f79, 0x3f6c0d31, 0x173f37c4, 0x81468c13, 0x3028b5c9, 0xfe011779,
- 0x5e575de9, 0x5d7f7c83, 0xdcafbe64, 0x33f91ab0, 0xf789c8b6, 0xba349e41,
- 0x9199b12d, 0xd31fb1f4, 0x817f6b9d, 0x63e02bfb, 0xe4befb90, 0x80e41ca0,
- 0x3f7fe044, 0xfd157fe5, 0x7ca03e14, 0xa54384f1, 0xa17cf427, 0x7829df9c,
- 0xff3bacd9, 0xf5c1c8fb, 0x7d5d4f3c, 0xf328a1c4, 0x3e74def9, 0xbfce8bdb,
- 0xcb0e7461, 0xd15bd017, 0x9c818f13, 0xce5beb8d, 0xac4e316c, 0x6cd1f0d7,
- 0xe468fb8c, 0xde0140e7, 0xe7dd685f, 0x39d7d9fc, 0xf7ab32ce, 0xe0fe3575,
- 0x1995d1bc, 0x6e428fe6, 0x6b582ed7, 0x8df473c6, 0xbcb3c984, 0xbeafda33,
- 0x5234e9a7, 0xfaa29403, 0x09e7d01d, 0x21070ab8, 0x22685aef, 0xf83f7419,
- 0x4ee96a45, 0x71f9a788, 0x8a3c5cbb, 0x49a363ce, 0xee1d769e, 0x00d7dc0b,
- 0x0d8a6bfc, 0x88af884e, 0xf00538f5, 0x004ba043, 0xeb2f70e4, 0xfbba4c67,
- 0xbaafdc72, 0x1f4063dc, 0x52f4e01c, 0xa1e0abe8, 0x2faef5af, 0x9862daba,
- 0x72f0245c, 0x99791ebd, 0x4f034dcb, 0x6447ae2f, 0x41c9e411, 0x18448bbc,
- 0x07a644ff, 0x22647a43, 0xcfbe73c1, 0xf3e47a75, 0x7c8f5e1f, 0xb923d1ae,
- 0x08f5111d, 0xff9445fd, 0x68b9a684, 0x91c392cf, 0x862959ed, 0xb009c7ad,
- 0x097ad28e, 0xa1fbfb32, 0x52df3807, 0xc438c48e, 0xc63326c6, 0xc87a2b5d,
- 0xc3e48d31, 0xc0753bdf, 0xa6b50bba, 0x824f0f79, 0x9324d7f3, 0x4f83ce0b,
- 0xf748dd4b, 0xdcc374d3, 0x2251fc88, 0xe823bd00, 0x0b7e0223, 0x99834ff9,
- 0x456c5ddf, 0x48505939, 0xb9dd1d70, 0x55f23c76, 0x009a7179, 0x2eb15b7c,
- 0xb8f28056, 0xe8034ec9, 0xe31e652b, 0xc6481a17, 0x94839418, 0x8c1c9518,
- 0xc044eb97, 0x6f78b0d7, 0xc84b1492, 0xff4f3165, 0xb9b7ed58, 0x7ed5e684,
- 0xf65f9a1b, 0x9736fc5d, 0x65c9fcfd, 0x73c9b7e0, 0x8cc64678, 0x65cdff43,
- 0xac0ce690, 0x6f4a8913, 0xfb8ecc5d, 0xcb52fcbe, 0x40e443fd, 0xacec7f2f,
- 0xc7f42e75, 0xd47c024e, 0x06789f24, 0x153be1c0, 0x366eed11, 0x2f5c018e,
- 0xd2090f90, 0x9d494063, 0x4512fe08, 0x87035cef, 0x1ed428ae, 0x1433ce01,
- 0x85bd0379, 0xce3c6ee7, 0x7655fc01, 0x91fbd7f4, 0x931f208f, 0x2b47d61d,
- 0xdf110d8a, 0xc633be11, 0x67ea83f6, 0xd6f5fad2, 0xf8f0e59f, 0xe9e5115f,
- 0x3d9518ce, 0xd1f164f4, 0xc10e7644, 0x9bbbe5de, 0x45abf1f7, 0x192ef7ee,
- 0x615f7e10, 0x4324d9b4, 0x10f1293c, 0x4f155397, 0x410ab42c, 0xfea7c43b,
- 0x746e760d, 0x0337fdbf, 0xb7fabfa6, 0xb054a292, 0x6e0c5be7, 0x7c41196a,
- 0x7b83ca05, 0x267bc118, 0x616efe01, 0x23cd9b5e, 0x8843bf81, 0x3da0f7e2,
- 0xdc8df3da, 0x681ba1ee, 0x3356e2f9, 0xaebdcdfe, 0x1eefe53c, 0xb21ef1b8,
- 0x7dacdf82, 0xb8c48e4f, 0x1ba3634d, 0x858d6ce4, 0x51635fc1, 0x6062bbea,
- 0x1cebeebd, 0x64c2e27d, 0xfe29f7f4, 0x41dd89c5, 0xd692f011, 0xe0b032ed,
- 0xb18fd635, 0x957ce09b, 0xc700f5f3, 0x9b3de6fb, 0x73c75844, 0x862e3726,
- 0x764bcefd, 0xf3c00aef, 0x76b51395, 0x0ea158de, 0xb9246eff, 0x493ee086,
- 0x0ef88f91, 0x9a4c03b2, 0x1e1dc3d8, 0x9e573d50, 0xfd80ecf2, 0x11094c64,
- 0xae2a9e00, 0x5f2017e7, 0xb8478064, 0xbdfc006e, 0x08b7fe4e, 0x7bcd9c39,
- 0xf79005f2, 0x0593ed01, 0xfe6f6657, 0xeefb095e, 0x04fe2cb1, 0x07ecaae8,
- 0xb2f6fd87, 0x534fe0c9, 0x618d6fea, 0xaf2afc7a, 0xc45c00b7, 0x422f3e74,
- 0xfba613bf, 0xa929e0db, 0x9b72e5f1, 0xcf9aa5c9, 0x52f0827c, 0xc79c643a,
- 0x3cdec3a0, 0x62d9f748, 0x4f2bdfb1, 0x656e3105, 0x70c11d60, 0x07ed219e,
- 0x521a7ed0, 0x1d002ed7, 0x0b79ef37, 0x7db83bc7, 0x5cb94b27, 0x80f6e26d,
- 0x367dae32, 0xe3ee5eb6, 0xe70dd1e7, 0x7af97ad8, 0x92e3178c, 0xe4347994,
- 0x28ea9379, 0x6f1095fc, 0x78efb633, 0x4263b79b, 0x016f36f1, 0x77a76abd,
- 0xd3de06ec, 0xf7120dfb, 0x247a451e, 0xf1db642e, 0x08177b95, 0xce5627a0,
- 0x5037ec8c, 0xee4ac5f4, 0xb5c55577, 0x5aa317bc, 0xc696a72f, 0xfa54d359,
- 0x4cf76948, 0x3365ae38, 0x53796b8f, 0x52d46ed3, 0x0cd3f00b, 0x8c10e79b,
- 0x3f7bf95b, 0xd1dff9eb, 0x0ab1f651, 0x0c9d52be, 0xdcc7af5f, 0x8dce0fb8,
- 0xca4e4f00, 0x912debc7, 0x9c13c3e3, 0x306f6e06, 0x8ced217e, 0x6a1e605f,
- 0xb702ebbb, 0x78f2ae3b, 0x4f8c8c0b, 0xc93e453e, 0xdf01b7f5, 0xdb922f8e,
- 0x1087ff80, 0x8c4527ce, 0x1efcf44f, 0x7ce38ced, 0xef004dd2, 0xb1bde163,
- 0x3ff1fa08, 0x067cd863, 0xff23e7b4, 0x0af87950, 0x3a949bd7, 0x4923c251,
- 0xc38c54e7, 0x7e995584, 0x69eb931f, 0x7a737e03, 0xd39e504a, 0x07664ead,
- 0xa0fe32a5, 0x426705ed, 0x2ffe9e58, 0x4f842ce7, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dedff00, 0xd554780b, 0xb3dae8b9, 0x64932667, 0x6f264c92,
- 0x80849af2, 0x3c870108, 0x4e3d2878, 0x0f78601e, 0x02483508, 0x48042bc3,
- 0xd2d04132, 0x20196f1e, 0x83548086, 0xa96a1ea5, 0x5af11e0e, 0xd528368a,
- 0xf09d8360, 0x41d0582a, 0x396b42d1, 0x0a8a2341, 0xf41ea009, 0xfffde3d0,
- 0xcccdad7f, 0x228899de, 0xb9eefbf6, 0x62ecfd37, 0xdaf6bded, 0x8fdffaff,
- 0xfb0cd7b5, 0x33d6c60f, 0x2a1d76c6, 0x8cb96c96, 0x794bfbc5, 0xc5a398cb,
- 0x8cf3d8cc, 0xff40b595, 0x9dbbfc2b, 0x7463cfb1, 0x1630258c, 0x2b18916b,
- 0xa46fac64, 0x598dfa85, 0x187ae4ae, 0x15d236bf, 0x79c0496d, 0x26090e74,
- 0xecc27e19, 0xf8743065, 0x99997af2, 0xc4bf5e71, 0xd5acc664, 0xbc232296,
- 0x2ec6b537, 0x7efe60b9, 0x0b78ce91, 0x0b1703cd, 0x79d22da0, 0x2d73c0d7,
- 0x66a38ed1, 0x6792cf78, 0x269d2dc2, 0xc15f7f46, 0xb12db57f, 0x35bbbeaa,
- 0x2039d2c5, 0xff825fd0, 0x0eff8148, 0xc61b1331, 0xc5bf0d58, 0x2caec896,
- 0x6b57cc0b, 0x0e6878ea, 0xf37eebf4, 0x92c191b9, 0x805eb86c, 0x7943f9e3,
- 0x81cd7391, 0xd62adef5, 0x55c39b79, 0xcff187a2, 0xc66eb946, 0xf08e47e7,
- 0xa1e193ee, 0x7d9e65e1, 0xa40b687a, 0xb0517dfa, 0xd996365e, 0xae3f41b7,
- 0x4347b583, 0x8744f637, 0x47fa1a23, 0xa784b1cd, 0xb4743f5b, 0x62fac2e7,
- 0xe7c24c9c, 0x38f95f01, 0xe5778b1f, 0xde23073b, 0xe00ccb96, 0x61e90178,
- 0x8e3d36be, 0xdf04759a, 0x53873351, 0x4884c3a1, 0x5d0b28c7, 0x4f5ef467,
- 0xd7801b31, 0x95d04c37, 0x579e8379, 0x4cc5a75a, 0xcf1baee3, 0x307d309f,
- 0x7fdb599e, 0xe813f8bd, 0x32dff1bb, 0xf029dde1, 0xd617dd1e, 0xef09f3fd,
- 0x95e0ba26, 0x61f7533a, 0xdb51f009, 0x5864db26, 0x9664a0c2, 0xd8c719db,
- 0x0eadfb9a, 0x5a2783e4, 0x8c187b24, 0xb3660e67, 0x25643224, 0xdff9d622,
- 0xb7610cc7, 0xac170b40, 0x6293ce30, 0xde436ef4, 0x43337fd9, 0x02b1dc38,
- 0xc3e8068e, 0x05165d73, 0x0df50730, 0x459feaec, 0xf861f182, 0x6a4b982f,
- 0x80976f69, 0x30466b70, 0xdee00197, 0x3f1326d7, 0xe118d13e, 0x7ff9830d,
- 0xe1e2e3bb, 0xb9cfd099, 0x82cb875f, 0x339609bf, 0x43a8f891, 0x395a0afa,
- 0x0f4034da, 0x8472edf7, 0x2df1865d, 0x5843d111, 0xfb45630c, 0x9ad9f988,
- 0xbc0f307e, 0x047b4d67, 0x3f4d6fad, 0xe22c8f90, 0xff917b83, 0x591947f7,
- 0x04bf5c0a, 0x86e38372, 0x46378eb3, 0x74e80565, 0x59d3f5a9, 0xeefd617b,
- 0xd76f3e48, 0x91fd2bde, 0xe3fb957f, 0x97b5cc56, 0x2c5633e6, 0xf38a7ebb,
- 0x1d5fd729, 0xe2345ef0, 0x8234b19b, 0x0727e897, 0x378abbe0, 0x1cafc70b,
- 0x7475a7a5, 0xae3b08b1, 0x60e8c5bb, 0x29cf2748, 0x5e0adfce, 0x746f04eb,
- 0x709e15b5, 0x389efac1, 0xe7c76691, 0x852f5abb, 0xb37de0eb, 0x230f5c63,
- 0xeef4e5dd, 0xe22e6768, 0x1dcdd2f3, 0xe75eb8b9, 0xd2ef8446, 0xaeacf791,
- 0xdf5aebdc, 0x7d64df63, 0x49b9bd6e, 0x3fc9e98a, 0xda903e5a, 0x8690bfda,
- 0xd4309c90, 0xe60c9e5b, 0x6eeb035d, 0x49b43c1c, 0x634f4246, 0xc64f9436,
- 0x06672c2a, 0x313de805, 0x12ddb9c6, 0x188e5f24, 0x2f5c0ee7, 0x8f3527be,
- 0xde1cf9d6, 0x5e74721f, 0x5d7741be, 0xf4297ceb, 0xaf447d3a, 0x5a9eb15a,
- 0x0327d993, 0xe1976cfc, 0x3e450e93, 0x0bc27bb3, 0xf08bd8f4, 0x27ed8a79,
- 0xbfcf485c, 0x106bed9a, 0xc5bf7a1f, 0xeff04519, 0x11b1f7c7, 0xbd719273,
- 0xff1d236b, 0xf6fe8665, 0x83f38c55, 0x127f6114, 0xbf73b716, 0xe4f50235,
- 0x9fd718c4, 0xba81be71, 0xd09cb38b, 0x753bf02f, 0x781db973, 0x92fbac4d,
- 0x97a8e09e, 0x58ebfe71, 0xaf425fff, 0xfe1d07bf, 0x05074c16, 0x7d04a33f,
- 0x507e2147, 0x3feb7721, 0xf00530e9, 0x4f528123, 0x8f9cf6b5, 0x840c8eb1,
- 0x07f77db7, 0xbe603bfd, 0x983e57ba, 0xf75bf285, 0xb7111872, 0x639be5f4,
- 0x17cf8f90, 0x7316f2b1, 0xc9fa7d4f, 0x3ebb7aca, 0x4b4eb187, 0x1ad5e936,
- 0xbeb237e6, 0xda974fa8, 0x14fa41f5, 0x47fba620, 0x3809fe0c, 0x994291ff,
- 0xbbbe02ad, 0xc49e1f64, 0xa569e842, 0xb3256d7d, 0x7fd807cf, 0xf00e7a8e,
- 0x4177643f, 0xcda5e10c, 0x3b58fa4a, 0x6acac8fe, 0xef4e697b, 0x1a191df3,
- 0xbb45ee5e, 0xb0673121, 0xe588497d, 0xb4572576, 0x081d28a0, 0xa317b9e7,
- 0x74b81ebc, 0x68adef2e, 0xb73a7806, 0x0f7ccdeb, 0xe639cbf0, 0x9407f65f,
- 0x6ccd4f9f, 0xa1c76a1b, 0x8aafe56f, 0x0fdbc80a, 0xffb5f046, 0xd1a3a5e0,
- 0x613f1836, 0x4f78bee7, 0xc07efe10, 0xe55e9ff4, 0x2f7c2cdf, 0x7d30fc23,
- 0x07a47f47, 0x44d9c3fb, 0x7613b41b, 0x7ce7881f, 0x3a43a890, 0xeb7a172f,
- 0x64697877, 0x2b09be60, 0x948f88ea, 0x1365ed7e, 0xf505c6f3, 0x9a237ef5,
- 0x66cbdabe, 0x5f7185e6, 0x49e2a258, 0x7d61f47f, 0x537c7f50, 0x2baf69bc,
- 0xf4323b78, 0xefda066c, 0xf9a1e1f3, 0x77188464, 0x09323ec9, 0x4609a3fd,
- 0xc4258e5f, 0x34bcc638, 0x57aebb4e, 0xa5ecba57, 0x1be1defa, 0x96ae646f,
- 0xf4347c10, 0x99c37bea, 0xd97ae407, 0xa1d90356, 0x32fe57a3, 0xf7e81f2d,
- 0x658316c1, 0xfab3e035, 0x7ed2fbd7, 0x87abf70e, 0xe8245986, 0xe5f3607f,
- 0xfc2f1f20, 0x75c4ecb5, 0x5965b07f, 0x3f683ce2, 0x01ac7e06, 0x356e1638,
- 0xadeaf5d0, 0xb3f5d2f7, 0xfe174f82, 0xea10613a, 0xd7fba3f9, 0xab3ae227,
- 0x87f6b1ff, 0x1a762fa8, 0x4286832d, 0xb243b35b, 0xc5c90697, 0x55c2a7e2,
- 0x563a9dfd, 0xd650eb8d, 0xd5d724cd, 0xa78036fb, 0xddf7562a, 0x6afd97fc,
- 0x95fc05ff, 0xf204d8aa, 0x09dd2657, 0xbc2baeeb, 0xbee27e44, 0xc7641183,
- 0xc99668ff, 0xfd0df01f, 0x02df3fcf, 0xe87f92fd, 0x0843e4ed, 0xf42d1f3e,
- 0xa4c96332, 0xbc4caa87, 0x4f5bb25f, 0x944944fe, 0xf186f84c, 0xff70d1e6,
- 0x1f78c45f, 0x37e40de8, 0x34da8f26, 0x8e8dc612, 0x13f43031, 0x78b7c5ff,
- 0x7efd0302, 0xbbfd65fb, 0x29eb411d, 0xd003cd66, 0x06622911, 0x1e8775cd,
- 0xd49897af, 0x8ce747d7, 0x6e768b3b, 0x5d7d45b4, 0x58869b91, 0x0141ffe0,
- 0xf077dffe, 0xc3c647a3, 0xc88eaafa, 0x86bb0fdc, 0xe10d797e, 0x5f9d23d7,
- 0xcf01d8ad, 0x3958151d, 0x8683e57a, 0x11abe414, 0xfd0d5b12, 0x9584ae0f,
- 0x0b879285, 0xbca36fe8, 0x80efa033, 0xda277d00, 0xa3ed5d17, 0xb11e4c38,
- 0xe11f6af4, 0xee7ae6ff, 0x11d1e5eb, 0x6bf7a46b, 0x6e56a0f5, 0x383d2fbe,
- 0x0c81e861, 0x4fb5144f, 0x4ec9fb63, 0x7ab45fae, 0x14f7ab51, 0xd6f0b4b8,
- 0xf4a9d65e, 0x1b58d0dd, 0x3de80b8d, 0x1bbde923, 0x8d1d5f18, 0x815f110d,
- 0x797c265d, 0xae29e986, 0x0de1bf03, 0xb66b971c, 0x480115c5, 0x48ec960d,
- 0xcc33e7d4, 0xee50b7ae, 0xb03b7f32, 0x1ebd8194, 0x8759a3b4, 0xe24ba37a,
- 0x106edaf4, 0x0373f62d, 0x623bcff1, 0xbcb1edfd, 0xc50ff10f, 0x8a2bd98d,
- 0xfeb07bd9, 0x84f31330, 0xf7bd91e7, 0xf302f218, 0xa2e31cbf, 0x8c458d71,
- 0xdcb19dc7, 0x601ecbef, 0x7e6059d3, 0x87592036, 0x70265af4, 0x25a576b1,
- 0x7bf813b7, 0x6a64cadd, 0xe7c45fd1, 0x68237b3c, 0xce4bef5d, 0x6b772821,
- 0x7a5a7c05, 0xfe155b64, 0xf60ff676, 0x87141687, 0x56d1d3d6, 0xe8a7ad3d,
- 0xe81919d1, 0x7edfbc6f, 0xcfea0677, 0x3f5e01f7, 0x3dbd3fda, 0x84fcebe6,
- 0x3e3c8587, 0x8c44ec28, 0x267f2388, 0xc7d804e4, 0xb5fd13b1, 0xbfba4e95,
- 0xb539656e, 0xa0ae571b, 0x59b1ddfb, 0x91e8fef4, 0x81b3fbcf, 0x641b9d7e,
- 0x8c0b03b2, 0xf0b1fece, 0x8e934ede, 0xeaf7d1e2, 0xccbb65cd, 0x5c519d78,
- 0xf1d1e0b3, 0x142e50db, 0xf563ba38, 0xd6deeeb4, 0x3ebd6d99, 0x3acb5dfd,
- 0x5d1ed1a2, 0x0077c7e5, 0x7e01893b, 0x32bb219c, 0xc71809ad, 0x38e22474,
- 0xbfefe4b7, 0xee808283, 0x956ff40c, 0xeccafff7, 0x6216b6c8, 0xa106c39c,
- 0x7044b45c, 0x7385a37b, 0xd9f395a0, 0xc13695da, 0xfda80307, 0xef61f858,
- 0xa10a9da3, 0xcf116e57, 0x6e3b361d, 0x6630f7c1, 0xd6937f26, 0xda3bfa81,
- 0x42708791, 0xf78050bc, 0xcbd52587, 0xdbf90906, 0xf80df5c2, 0x771fdca5,
- 0x2c71c48e, 0x044d21de, 0xf9130c7a, 0x05f2de9b, 0xb4de385a, 0xe6d0f972,
- 0xc9569411, 0xf95a9423, 0x6b16fe7a, 0x6c77e551, 0x2a11cc2d, 0xcad5b07f,
- 0xc3b266f5, 0x7ada4721, 0xd702bb97, 0xf3191ebb, 0xdecce524, 0x51a49a0f,
- 0x3f98ed2d, 0xaef52949, 0x634afcc2, 0x3d0e56ac, 0xc95798e1, 0x3d12e976,
- 0xefd12e30, 0x1c02322a, 0xe912625b, 0x7eac497d, 0xc0abd215, 0x1745a3a5,
- 0x4af08fec, 0x4307904a, 0x047e85f2, 0x79470d09, 0x9ae51f1b, 0x5f9df843,
- 0xc368c6bf, 0x464793fc, 0x025672fd, 0x38fe013e, 0xa422207b, 0x228f773f,
- 0x1f7152b7, 0x4f05e934, 0x050f0819, 0x1662fd4f, 0xd4f05bc2, 0x28297a1d,
- 0x6ac87f4e, 0x3d9dfc20, 0xe29338b0, 0xac6193e6, 0x79cf565f, 0x545f051b,
- 0x60bf7c09, 0xab77cd0c, 0x5baffbc5, 0x7f82774f, 0xd3d2a893, 0x8109adab,
- 0xed5d4c7c, 0xb3d3d245, 0xfc3edcac, 0xb072df4a, 0x57f3e00f, 0xf11d99f3,
- 0xad99f8be, 0xc17ba794, 0x077632d8, 0xc74ea7ae, 0xffb00f30, 0xfb07cbe0,
- 0xdf387fa0, 0x83fd1436, 0xd91fcfab, 0x7fd788de, 0x2286cd55, 0x1bbc53fe,
- 0x7c07cc25, 0xf84cde1e, 0x185b7cfa, 0x5a4b055b, 0xec65ac74, 0xb9bfa04f,
- 0xaf50c746, 0x6f0dd768, 0xb192e832, 0x237419f5, 0xff51fd38, 0xc6077429,
- 0x143d2232, 0x50fe21ba, 0xf6dfed9f, 0xc0afc112, 0x46c625b5, 0xccfc5bf8,
- 0x27c8b1ce, 0x12ac6a7d, 0xb81467e6, 0xb89dabbe, 0xf7f3f681, 0x3f666fd6,
- 0x69fa465f, 0x6ed6a7ed, 0xf63b30ce, 0x86bbfe90, 0xf8231cfd, 0x0f4237f0,
- 0x41ed98db, 0x23b253cc, 0x68f7ca3a, 0xf82a52e9, 0x7a2f2831, 0x791d7ac4,
- 0x2b5661d1, 0x179b57bd, 0x7ae46edd, 0x66cad9b4, 0x87e5094f, 0x9b757809,
- 0x17688dba, 0x90a4dbe3, 0x99a8e97a, 0x9bd025eb, 0x9f7241ff, 0x86af5a1a,
- 0xc419efc0, 0x7c3bcddb, 0x5e54717b, 0xba244e6c, 0x0fcf805d, 0x7814f854,
- 0xe0aaf054, 0x88a631b3, 0xf0bb65f8, 0x70c4b733, 0x9970297c, 0x8e7194e3,
- 0x7a5f380b, 0x0bfafa2f, 0xff806781, 0xbf1fc232, 0xeaf2a99c, 0xbe3d3e4a,
- 0x0b1923de, 0xca302cd0, 0xb9c665bf, 0x5c601956, 0x7f6648f7, 0x1531fa12,
- 0x77d42296, 0x3b7b6ad6, 0xcf1bdde6, 0xe366bcf1, 0x4d5de652, 0x7ffe30f3,
- 0xa3ca6cae, 0xe69dde22, 0x5941769e, 0x532bd81f, 0x15c1215c, 0xf635f711,
- 0x45ca06ea, 0x9337dc72, 0x10b8f48b, 0x731b7b74, 0xc7210980, 0x4379c5f7,
- 0xaf0739d0, 0xb7ce8b5f, 0xe5e57889, 0xcd472998, 0x0cb56fc2, 0x4b5dd009,
- 0xdf91becf, 0xc4f78f51, 0x09716dcb, 0x61b2f13d, 0x1e806e82, 0xec22c9d7,
- 0xa4ceeca1, 0xdf3defb8, 0x442e293f, 0x54fe1fbe, 0xab13f4fe, 0x84dfafed,
- 0x5326be70, 0x4fc4f49c, 0x27988c3b, 0x0ad2f256, 0x812feebc, 0x773f40a3,
- 0x56a3a97d, 0x26d75eb9, 0x55dc63e5, 0xf90aefb4, 0x5fed5dc7, 0xa5dc7f92,
- 0xf7958ff1, 0x89ec03de, 0x365a31f2, 0xdc5fff13, 0x9978e3c2, 0x146dfed9,
- 0x643ee1c0, 0xf11b5e60, 0xb40ff92f, 0xc45fe85e, 0x633fc716, 0xe16f78a4,
- 0xf98617e1, 0x08cc52e0, 0xe105b31d, 0xc111d62b, 0x8af8416c, 0xfaaab32b,
- 0xaa3ece09, 0xd9e549f1, 0xae29fbaa, 0xa9fbaa81, 0x7eaa79d5, 0xaaadfd7a,
- 0xb76099f1, 0x9e59fb82, 0x7df1aa71, 0xfaaaa69b, 0x56ef9afd, 0x871e678d,
- 0x39d6073f, 0xa6f3ac5f, 0xe35573cd, 0x61f24f99, 0x2081647d, 0xc7dbc7f3,
- 0xc8fac21c, 0xb88f917c, 0x3558bbd9, 0x756682df, 0x08f0815e, 0x956aab78,
- 0xb78863d8, 0xd5fbeacd, 0x531b1b6d, 0x55e45da1, 0x758c5f5f, 0x53f9090f,
- 0x3af7fd7d, 0xe3f432e7, 0xcea7197f, 0xbe935dd3, 0x45ae9b9e, 0xc70fbb5f,
- 0x7f2288ef, 0x79e1e167, 0xc9614724, 0xdb86fa6a, 0x7f16be22, 0x9aac0391,
- 0xafbff0fb, 0x5d945fc1, 0xfc5a0fcd, 0xc1f759e9, 0xceab8054, 0xac7dd92b,
- 0xb516fe27, 0xb538256e, 0xede2d3f8, 0xbcea718f, 0xd748dace, 0x971bd45e,
- 0x0ccb975a, 0xbc65f3f3, 0xf5a978fe, 0x6c4721d3, 0x7ef97941, 0x5fe5e6bd,
- 0x97910b8d, 0xcb7ac2ef, 0xd41bec2d, 0x817df65b, 0x8b030878, 0xb27a0063,
- 0xd5d37611, 0x20784afa, 0x5bd5af0f, 0xfb7a0b4a, 0xcfa4716f, 0x35a97503,
- 0x98b0f4f0, 0xaf089db7, 0xef18b752, 0xb7bc1172, 0xe1232020, 0xa75f333f,
- 0xe1e00f32, 0x7c679c3d, 0xe3123591, 0xeffb9da7, 0xb58078a1, 0x073d73c5,
- 0x1f1e0f24, 0xfe9297e4, 0xa67fc16c, 0x48fc3d90, 0x704fc3d8, 0x321ec53e,
- 0x57bf959f, 0xe6dec3d8, 0xbd16ea51, 0x995ed2b5, 0x58dd2fea, 0xcfa1097f,
- 0xd1dff18d, 0x23d27cae, 0x0f8c69ff, 0xbdee0f8e, 0x3af51074, 0x1e3c3de0,
- 0x051519d6, 0xd80a52f6, 0x8c8b7fcb, 0x3eeb7926, 0x826f7b2c, 0xb64d170b,
- 0xa06e6b18, 0x7785a2be, 0xab9ac994, 0x6de3d20f, 0x365eda92, 0x23ff71e6,
- 0x1dfb9e31, 0x2fdccc93, 0xe9d62c1d, 0xeeebf8d6, 0x82971e26, 0x05b75434,
- 0xe38381f9, 0x3bfc68a3, 0x71834511, 0x5c455b3d, 0xd12598df, 0x89251afb,
- 0x312dfaec, 0x9dff74c5, 0x6c5ca2b8, 0x0ef789fb, 0xda089f46, 0x8f0e6ce6,
- 0x5013ec4d, 0xc710ffe6, 0x4c5b6217, 0x8b78e0ed, 0x0658efc8, 0x448fbd22,
- 0xa35e6838, 0x29fcab2c, 0xe78bcda5, 0x99a7447e, 0x2a937e29, 0xe8463c7f,
- 0x8717cc31, 0x26393091, 0xe40c4e8c, 0xea3c998b, 0xe45e31b8, 0xdc7a2589,
- 0x5dbc7481, 0xbcb7b1d0, 0x658063b1, 0x4439bc3f, 0x1c97d8de, 0x1f6c6f32,
- 0x78637943, 0xd2eb8f52, 0x0e918fe6, 0x3c80d691, 0xaabf8c4c, 0xdf50d26f,
- 0x3c756634, 0xe3f91e32, 0x127f6ca8, 0x13c77f41, 0xb6e00439, 0x7c7675d9,
- 0xb616e464, 0x0bfa1c3a, 0x2fca363d, 0x8afe2019, 0xefc80bca, 0x4e2cf892,
- 0xd33e13ff, 0xfc3fb810, 0xe63b671d, 0x634ffb93, 0xcdff5456, 0x1a24b9ac,
- 0x2c2d88fd, 0x2552bc64, 0xd17c66f8, 0x3ce5195e, 0x25f81ba1, 0xe2aa3d04,
- 0xbdbf8a75, 0xbc36e900, 0xf50975db, 0x4807a289, 0xb45c6195, 0xb27e475f,
- 0xe896f9f6, 0x07c42592, 0x9279d0de, 0xe387334e, 0x29738442, 0x57783fce,
- 0xcdf51187, 0xce6f4542, 0xd03d31d7, 0xbf414ef7, 0xbaf0b73b, 0xd5f2bb34,
- 0x5fe2b257, 0xa19f9a31, 0x2d38583e, 0x87798bca, 0x1e596d85, 0x5129cb82,
- 0x76ddc55e, 0x85fd89cc, 0x8c160505, 0x657f1d73, 0xe40199d2, 0x77ae319a,
- 0xa28cecf4, 0xc67ec807, 0xaa629d53, 0xb34eabe0, 0xfd04e08d, 0xe81221bc,
- 0xaacb70b0, 0xe12fb8bd, 0x54677fad, 0x7721388f, 0xa6c9c30f, 0xe4567203,
- 0x1567ab61, 0xaf30f879, 0xf3134c77, 0xf784be78, 0x9def029a, 0xd69876de,
- 0x3cc0c273, 0xae97e026, 0xd0d9773d, 0x304c6d4f, 0x457f89d9, 0xec94eb9d,
- 0x878c807a, 0x410ebbbe, 0x6916d19b, 0x58eb0f59, 0xafdc6463, 0x11d845d5,
- 0x1dcd13ff, 0xf897e27a, 0xf1e23d6e, 0xf467410d, 0x4fcfc9ed, 0x39274460,
- 0x96e9c755, 0x44fbe369, 0xbff9d472, 0xc1dd0497, 0xebc34c6b, 0x58df2313,
- 0x7cce036e, 0xc70fd376, 0xdea247e9, 0x1679637b, 0xdd365bf4, 0xfc8f4e35,
- 0xa7c6fa9d, 0xcfea2059, 0xf7e72a6f, 0x69f1bd07, 0x6d77f436, 0xdfefc19a,
- 0x5ecfbc46, 0x38f774dc, 0x74bfebcc, 0xf9f02f55, 0x12422097, 0xc395bfae,
- 0xe2a1f574, 0x92bc5f0b, 0x7c06665f, 0x4fedb38f, 0x3aced027, 0xc3b7fa95,
- 0x237faaa0, 0xdf8098c7, 0x62be0bc6, 0x0764d1f1, 0x8dfa09c6, 0x3f68fbd7,
- 0x23e4ce8c, 0x1ac4defc, 0x8037c82c, 0xe55f4dad, 0xc07f7cf7, 0x4bf9a9ae,
- 0x02b63072, 0x2cd92de8, 0x566b27c4, 0xda385730, 0x5ddd40fd, 0xcceeebc7,
- 0xe057ef89, 0x03dfde51, 0xdead202e, 0x16d70c1a, 0xab81479a, 0x0798686b,
- 0x9fb149e5, 0x525d5c0a, 0xf498e3f7, 0x0f2fd9fe, 0x75ba404e, 0x48677545,
- 0x7090dfd0, 0x95d8e890, 0x64b8fdd0, 0x381bea0f, 0x5a6ccf1d, 0xef03ce36,
- 0xce3b28d9, 0x1986dca0, 0x2692bef9, 0x3de0538c, 0x3cb8260f, 0xbe03cf58,
- 0xef90fbb3, 0x87a48dd2, 0x79d40b4a, 0x67c16e89, 0xdeb813cb, 0x5cd61d1f,
- 0xd2f80c7f, 0xab624bbd, 0xcafbbc60, 0x89da2325, 0x8da76d89, 0x76eb680e,
- 0xbea2369d, 0xcc3ec3aa, 0x18c5b753, 0x12796f52, 0xd43f6164, 0xf481f07e,
- 0xe3c40ffe, 0x12f985be, 0xd9eee255, 0xfb1a3b1d, 0x55c1ccf7, 0xa8f77632,
- 0x5d91a39d, 0x0fed9d2a, 0x759b3b60, 0x9a16401c, 0x7e5592e1, 0x48eacce9,
- 0x595b5f95, 0xcfeaa71f, 0x80ea066e, 0x915ecf5c, 0x181f8eaa, 0xcf00abc4,
- 0x43f8160c, 0xe82e56fd, 0x83792338, 0xccadf71f, 0x1d3c1970, 0x6c4df341,
- 0x22b7a55b, 0x9d92f5dc, 0xd987afd4, 0x7c99b9f0, 0x3dead085, 0xd1b0f5c1,
- 0x51893cad, 0x7f226e57, 0x80fb02bf, 0xd91a8ad7, 0x0f10936b, 0x6eefba46,
- 0x5bbee895, 0x4b5777dc, 0xec961d4a, 0xe3016cee, 0x46c73dcc, 0xe110b6d3,
- 0xcef02bdf, 0x4b3b2f2e, 0x7afc28fc, 0x36e55d65, 0x7d70b3b0, 0x06dbfa6d,
- 0x8ff6779c, 0x45971624, 0x50eceaeb, 0xafdd51e1, 0x19f757ac, 0x9e6030eb,
- 0xf50af67a, 0xc209e1f5, 0x83620e9e, 0x25469e50, 0x2f927a48, 0xfd24ffd1,
- 0x007cd7ed, 0xf3b2e3df, 0x83e004f6, 0xea8fa31a, 0x2ecb8f50, 0xe1f72bea,
- 0xb9231d7a, 0xe4807f03, 0x5cf92258, 0x8a587063, 0x95ae8fd0, 0xb2676f88,
- 0x2b217f20, 0x72fa9e30, 0x093dfecf, 0x135a5fdc, 0xf54e5cee, 0x65923db0,
- 0xd52a5c1b, 0x07e8f43b, 0xe74291ae, 0x70259643, 0x418d7879, 0xf5700ef4,
- 0xbb452647, 0xd78c677e, 0xffedef03, 0xf41e39c7, 0x03e7fbef, 0xee50d81f,
- 0x2f19bdb9, 0xf024cdec, 0xebffd12f, 0x9394b72f, 0x68c5bf7e, 0xec2efd21,
- 0x1c2fa290, 0xa1db51bf, 0x288769f1, 0x79b498fe, 0x8bd405c3, 0x791d7d39,
- 0x07be011b, 0x1ffbf9c3, 0x71792ddc, 0xee5d4e1f, 0x499fd241, 0xdef81ec0,
- 0x47a164ba, 0xacfbd55b, 0x21af5092, 0xa5c84cc3, 0x1498a6f7, 0x1e90776e,
- 0xbac57c94, 0x497e80af, 0x69a9bde2, 0xe257c236, 0xd70916e2, 0xab3cce9d,
- 0x45cf8ed0, 0xb40c2c21, 0x97cfedd7, 0xbe7f5a4a, 0xe4f9fc9b, 0x7bc5230e,
- 0x9df8dbac, 0xe73d73f2, 0xfcd432ff, 0x53aa7cb0, 0x2bf2e207, 0xb9a798d1,
- 0xafdf4f67, 0x9b24dfdd, 0xc1b771d4, 0xc7bb8ea2, 0x9feb500f, 0xdeb57689,
- 0xafa23c99, 0xc714feea, 0x3bfdd520, 0xfd55f2cb, 0x54dbcee9, 0x2f2aefe3,
- 0x92c3f551, 0x00f269c7, 0xe44abcea, 0x255e7500, 0xa3ceaeca, 0x7dfe1d84,
- 0x317804b9, 0x2e1d3c9a, 0xc81343c0, 0xc06b08c6, 0x368a0c8e, 0x22367151,
- 0x6d8cdc3f, 0x1f30d0d3, 0x1f5349f2, 0x1d87871e, 0x07d937be, 0x766298f3,
- 0xf104b098, 0x1c5bc95b, 0x9a007307, 0xf03a9ea8, 0x39bfb57e, 0x17db8532,
- 0xb825f5a5, 0x36844f5e, 0x2a5b19f7, 0x14fd67f7, 0x1822989f, 0x345e8bf7,
- 0xc4a45f91, 0xe93ccac9, 0x50074569, 0xefdee47f, 0x6b09baa0, 0x27cc1665,
- 0x7914693e, 0xbef917d4, 0x0ed6dcdb, 0xbe48239d, 0xfae44cef, 0xe2ce17e0,
- 0x5d7f38b1, 0x9459581b, 0x1aefcda7, 0xd7593eb1, 0xf68d1ed6, 0x5df3886c,
- 0x02ebe623, 0xd39d85d7, 0x5d604777, 0x722d77e5, 0x72cafdc8, 0x1febcf22,
- 0xf2bd7a14, 0x547c40de, 0xafa02c34, 0xf5f2772b, 0x92374e55, 0x46c2c13e,
- 0x7a0dbd28, 0x2ade67ba, 0xf28c1ed8, 0x03ba803e, 0xdc6ab7f4, 0x2e3c69ec,
- 0x8dbd00aa, 0x5cfa0c72, 0x91ad3f7d, 0x73e80bf4, 0x010bf5d5, 0x15fb9e7d,
- 0x19c2773c, 0xe8f65f7a, 0x3f375e14, 0xfc212ae1, 0x88f002ff, 0x7a2ff27e,
- 0xf3e38de0, 0x167af85a, 0x37441f69, 0x2929b8ed, 0xb67c7fdc, 0x433d7d17,
- 0xc949f5d0, 0xd4ca879f, 0xbe208ced, 0x8d72699d, 0x7a47ccef, 0xf588de7c,
- 0x4bdfca89, 0xdfeced0c, 0x7ed30fda, 0x03cee33d, 0xd28fb889, 0x912072dd,
- 0x18d5df01, 0x8fd0ab6c, 0xa3b0be07, 0xead753df, 0x5b6bf823, 0x7af1dbf2,
- 0x4764ab6d, 0x75deec55, 0x93ad0c61, 0xbd623475, 0xe05ec9ef, 0x76e44cca,
- 0x8da26064, 0x985c07e7, 0xc3e7c113, 0xf9095ebc, 0xc212f400, 0xcd625bb5,
- 0x9d727fd0, 0xb79d6429, 0xff7be052, 0x57c5233a, 0xae3cf035, 0x41fa60e3,
- 0x68f909a3, 0xc24bac27, 0x1e9b1c75, 0x372ff389, 0x142ff430, 0xfba5cef8,
- 0x4ffae14f, 0x070087ce, 0x2f99afae, 0x2e4fbe13, 0x05c87917, 0x58cfea06,
- 0xdd7e2464, 0x46bdff37, 0xac9defcc, 0x4bdcfbe1, 0xf9467c16, 0x248b19be,
- 0x8a993f65, 0xd57e159f, 0x7f96a7f2, 0xf569f07b, 0x98e9f1f5, 0x3a7cabc4,
- 0xd03ced04, 0xf212747d, 0xce218fcf, 0xb2b9f946, 0xf00490cf, 0xec5a3766,
- 0xb06bafb8, 0x11207dec, 0x7e3ec4f5, 0x56cd687f, 0xdb1beb89, 0xa98728dd,
- 0x1eb6464d, 0xae44cbfd, 0xbd206697, 0xdd69710a, 0x7bc52452, 0x4bd46cfe,
- 0x0ef7ca59, 0x13be5606, 0xae7a71f3, 0x94bf066f, 0x107d75bc, 0x39129adf,
- 0x707a2abf, 0x76b99190, 0xa5bfde52, 0xe79814cf, 0xdbaf0359, 0xfaf98864,
- 0x331eedf5, 0x089fda05, 0xe027997e, 0x0af7fa50, 0xcd4f67fe, 0x344efc20,
- 0x5b8fbc71, 0x75c0abe1, 0x8b5d1934, 0x84fee112, 0xd06bb78c, 0xbf6535ce,
- 0x42f94b9a, 0xa73b2366, 0x46fbe7c4, 0x1965b07e, 0xe6fc37ac, 0xf863a208,
- 0xe4168d9e, 0x057ef0e3, 0x7c10ae49, 0xcbeeb4a7, 0x3902e636, 0x4d9cbbaa,
- 0xb29fd2ad, 0xf691acf7, 0x185db721, 0x39727243, 0xcf2bae99, 0xf9114a2d,
- 0x53dfb12a, 0x9e825fc9, 0x0bc88fd6, 0xc0f0538c, 0x215e1770, 0xd114f3c2,
- 0x3652d96b, 0x37d1a794, 0xd667fad2, 0xc0e6931c, 0x1c19773c, 0xd6167306,
- 0x77c7cacf, 0x537ee0e6, 0x71fd5cc6, 0xb9899d9f, 0xcfdfb88c, 0xcaff7d42,
- 0xb1bfea64, 0x63ed46d2, 0xd0cfe726, 0x5fdf4cde, 0x4df68fdf, 0x2cea3fa6,
- 0x1d74f786, 0xb6be0831, 0x3a94be10, 0x9936a5d0, 0xa5fee099, 0x35d5125d,
- 0x5d67f815, 0x715cc3ee, 0xdf15fd8c, 0x5da9ef07, 0x3be926f1, 0x3185f57b,
- 0xad0d1718, 0x7d88dd39, 0xc6cf8af7, 0x0a713fa0, 0xf5f907ec, 0x4b27dfe0,
- 0x198e47a8, 0xc55d7f71, 0xf3cd2b65, 0x0c7baeac, 0x15e797ca, 0xa74dea89,
- 0x93182f5a, 0x08627db8, 0x9f5816ca, 0x1895d703, 0xb771f84b, 0xfa71d50d,
- 0x4ab8f0e6, 0xc0fb43f0, 0x1e91a32f, 0xd7b615a6, 0x0fe7c36f, 0x77e50cc9,
- 0xb477717d, 0x3dfe8425, 0xfeb2f301, 0x6ad81d7c, 0x3d1b97ef, 0x5cf0ecfd,
- 0xfef42eb9, 0x9f0557a8, 0x3e29a602, 0x11293fc0, 0x55ff99e5, 0xac6292c2,
- 0x22f8f714, 0xdb2b8e40, 0xb1eace4a, 0xbbd897ad, 0xbd8c78ea, 0xf7b7e41b,
- 0xb4df87c6, 0xf4f9c3ad, 0xe201f641, 0x07e41646, 0x54c8dc61, 0xbcf0f7ef,
- 0x924e7a52, 0xaf3ac42b, 0x1f4741ca, 0xd57a0366, 0xf3ba0135, 0x5207df91,
- 0x5af77e7b, 0x298fca1b, 0xb451fba2, 0x8ebfac13, 0x8f5a8ce2, 0x93d9ffda,
- 0x4f78e5cc, 0x77eb9732, 0x12f1d513, 0xa3ef45c4, 0x145c431c, 0xa0df858d,
- 0x9d7b4978, 0xca1325e2, 0x1077bc15, 0x10f9e7d0, 0x2e4e1f70, 0x3df908fe,
- 0x9f133583, 0xe473e033, 0x3f3aed2f, 0x9153f613, 0xd72819eb, 0x5cadbfc8,
- 0x1ef3b5ae, 0x0cfa2e4f, 0xfb8759e1, 0x8de842b5, 0x6b3ac557, 0x97c23337,
- 0xf095b37b, 0x766d8e74, 0x9e5f0316, 0xfeb03803, 0x4674e5df, 0xc67d62c6,
- 0x9ab48ce5, 0x6ea07a03, 0xb73d0473, 0xdc6a672e, 0x2447e81c, 0xdf3fbe71,
- 0x3c42625a, 0xe5ccdacf, 0x29df794f, 0x94388cdf, 0xb74342a7, 0xd3f70ed1,
- 0xa3474eda, 0xfbb857df, 0xc39438ce, 0x47fce0de, 0xed775f12, 0xe3c67b8a,
- 0x87f85df7, 0xfea54cf9, 0x33ed5ee6, 0x0578dd52, 0x7f6dfe23, 0x28756ff1,
- 0x22dbe7c7, 0xcf37682d, 0xa0f489ed, 0x257aeffe, 0x2893abcc, 0x80c4f0ee,
- 0xe8673b5e, 0xe5fe4498, 0xfe82d96e, 0x8f95fb9d, 0x7479451f, 0x9e8618bf,
- 0xb6d25b1e, 0xbdda02f6, 0x67b1b69a, 0x9f6843f5, 0x1e553ff9, 0x47dc576a,
- 0xffd2917e, 0x89c9a578, 0x9ebcf47a, 0xad2589eb, 0xbbbf902f, 0x21a5cae4,
- 0xb73ef758, 0xa186bfe7, 0xf1ff735e, 0x67d430d2, 0x1a5c3fee, 0x2fddf786,
- 0xf287d645, 0xc8a55657, 0x5ec57f44, 0xabd71d66, 0x0b1f43f2, 0x686ac8fe,
- 0x9bfdc32e, 0xd9a6c785, 0xdcab7f31, 0xa3a7ec2f, 0x6f85fafd, 0x082dc695,
- 0xafc1ae7a, 0x05ebc32f, 0xe7234ac7, 0x4765f107, 0x2fc941b2, 0x075e575e,
- 0x0587eaef, 0x3afc71e5, 0x5b8c3847, 0x7df3d7e7, 0x1792d5b4, 0x5ff00be3,
- 0xdf91cfb4, 0xce28b5d4, 0x04fc9ebb, 0x05c1f8e7, 0x5f67efd8, 0x62b5436f,
- 0xe413903a, 0xebf0cd27, 0x47c0617c, 0x3e616de5, 0xfafdeff2, 0xfe17d4d3,
- 0x1f0bacd3, 0x21496544, 0xde0333f2, 0x5c7a8d18, 0xbf81a79b, 0xf15b8428,
- 0x5dea2ab7, 0x36bf08e9, 0xfcbb337f, 0x690fca0e, 0x7e5937f3, 0x01626ebd,
- 0x4d79e7d6, 0x937f9d74, 0xf145e509, 0xbb7e9143, 0x67ffc842, 0x8a7e9c49,
- 0x75f8355c, 0x7f069744, 0xda0729b1, 0x2efee2f3, 0x1df8a730, 0x9ddb4347,
- 0xd08f30db, 0x48aee570, 0x1c355dac, 0x3bf0ca9f, 0xb14b2e8e, 0x773e1fa9,
- 0xf4d30ee5, 0x68bf00dc, 0x8927b7df, 0x9f80cbeb, 0x3deeda10, 0x9ff9e427,
- 0x27b6ff65, 0xffcfcd5d, 0x20ff6d5f, 0x9499df0e, 0x4cf87140, 0x71e1279e,
- 0x286ed6b8, 0xf79958fa, 0x9ee7415d, 0xf92cf8fa, 0x932f1037, 0xc9377e3e,
- 0xdad2e346, 0x1c51c4a6, 0x9c5a7c7d, 0xfe73dccd, 0xcebb7abe, 0x7e73db9a,
- 0x7b738fc5, 0x184c071c, 0x3ef838e7, 0x8934f731, 0x7e2ad5f6, 0x9129db9f,
- 0x30aeee3f, 0x029c7178, 0xcf1a7f97, 0x18774eab, 0xc052e1bc, 0xc7fc543f,
- 0x12edf7ab, 0x49fc57dd, 0x3bf46fc5, 0x5a771e79, 0x98ffbf01, 0x093275c9,
- 0x70be41eb, 0x92385eba, 0x79cc675f, 0x77fa1520, 0x246250fd, 0x549fc2ff,
- 0x6feb54f8, 0xfbeb6c5e, 0xb7e4fbb5, 0xe454fe08, 0x1f23432c, 0x108afd8a,
- 0xfb43aa78, 0xfbf6871d, 0xae5f950b, 0xf7ec179d, 0x8e7a24b9, 0x6f05f3d1,
- 0xe2a19de9, 0xfe6295f3, 0xa0fd207f, 0x2feff34d, 0x99d37842, 0xf6b9f69f,
- 0x85bb5766, 0xfddbd37f, 0xcf286f88, 0xf89d8403, 0x4e73c967, 0x790cfff2,
- 0xf617eabe, 0xe1dd9df2, 0xc9c1a2e4, 0xdeb97f48, 0xf7f2845f, 0xfac84367,
- 0x7f8115f4, 0x7c557388, 0xa8dd207c, 0x5dc8b8c3, 0x4d03f3cd, 0x29d7b6b1,
- 0xd32c397e, 0x1025ebfe, 0xb6ffa207, 0xda85b2f8, 0xa193f41a, 0x31ccf99d,
- 0x9997ea03, 0x9bf86ad5, 0xcf8b7730, 0xa2f2cd2f, 0x4ac95cdf, 0xd954af29,
- 0xfdc16b16, 0x2d094dcc, 0x3cae5107, 0xb6db64db, 0x06ebf1e0, 0x9e26f18a,
- 0xa58eab6f, 0xe34c93fd, 0x6bd65407, 0x5fb57dfd, 0x13c89b70, 0xfc1fe6f5,
- 0xeb9c3da1, 0xc9324395, 0x97e61d79, 0xd8cc616e, 0x7b82f5c6, 0x4de53845,
- 0xb8435e30, 0x79215c3e, 0xad77004d, 0xdea1f718, 0xaa27f94f, 0xb390c1a7,
- 0x51131b6d, 0x5d43992e, 0xea7daa3f, 0xda9bd22d, 0x9775923a, 0xad5d0ba8,
- 0xb0930d1b, 0x64f10b5f, 0x3697fa12, 0x3fc464db, 0x47daa7c0, 0x1705f8a6,
- 0xf147bd0f, 0xbcddcce7, 0x7ea3d3fe, 0xd78e34d4, 0x0d3ec48f, 0x76721e6d,
- 0xa903c1e6, 0x8dd76bb6, 0x198f5aea, 0xe1e8ae30, 0x8efc687f, 0xf3ab269f,
- 0x9e7a998c, 0x936ccdc7, 0xca9f982c, 0xbe1c7814, 0xeafc822e, 0x1f9f7f31,
- 0xa140fa87, 0x1c29f9d3, 0x7e4fe7af, 0x045b445a, 0x84b7aefe, 0x70febac3,
- 0xa99bf972, 0xd9336fbc, 0x91e5b9f0, 0xdff43df4, 0xbc4489ef, 0xdc5a01fe,
- 0x09d2f997, 0xa47cc87d, 0x1fe5c294, 0x93cfe1ec, 0x2fde1ed1, 0xb07ad2f2,
- 0x7c815187, 0x9b39f68e, 0xc209ae78, 0xee63ca14, 0xa6fdf5e6, 0xea38d714,
- 0x6d9b32ff, 0x41d0ff23, 0x8017e779, 0x345f31af, 0xf58b1608, 0x5822e7e7,
- 0x9a8bd603, 0x92af5c12, 0x6752fd1c, 0xe7823943, 0xd9e4cea9, 0x88fb2369,
- 0xce7ac328, 0x2649b010, 0xf7c0d7da, 0x74140c47, 0x1638814c, 0xcd0049eb,
- 0x0f37ac34, 0x219d7512, 0xf38f4c11, 0xad70683f, 0x48eb19bf, 0x2afb7aed,
- 0xdc7b0212, 0xf59ea894, 0xebc1c925, 0x499d4ae2, 0x56f78fa9, 0x3df09267,
- 0xaf0e1f7c, 0x727d892b, 0xfd893d4a, 0xae4549d0, 0x19ea2335, 0x6949adc6,
- 0x0bedbbec, 0xf9e759eb, 0xdab9c63b, 0xc047cf3a, 0xa13f3ce3, 0x1fae2bae,
- 0xe9f13cf0, 0x0e27adb7, 0xb8376648, 0xa3f1c5fe, 0xf620bb85, 0x5bc52262,
- 0x68cff8ff, 0x976db3b2, 0x75761ec8, 0xe53f3187, 0x9e783b1d, 0xef7f8dbd,
- 0x5b7105d3, 0xbd9d9042, 0x7b5bf843, 0xff884adb, 0x234bf977, 0xb0bd7c71,
- 0x4f8eebe3, 0xd3bf13bb, 0xb4f5f8f2, 0x1e31872f, 0xebf2ed87, 0xb96fd10b,
- 0x22f97481, 0xcdfd4429, 0x93edc114, 0x4b9e8e56, 0xe7a4f9e6, 0x947f3992,
- 0x97f1e49c, 0xa3af397b, 0x705e8458, 0x0f491997, 0x944f4c1e, 0x5279fc94,
- 0xeecb3aa8, 0x951bb26e, 0x3fda248b, 0x9675dd7b, 0xb76176d6, 0xb2e9f934,
- 0x7b37a431, 0xd5075bcb, 0x33f755cd, 0xe13ec452, 0xdd7f3cc1, 0xf5a16c9c,
- 0x1687eb5a, 0xaca64ba1, 0xe1d206ff, 0x5bf7ca68, 0xf3eaed67, 0x27bfcefd,
- 0xdc9c8421, 0xfb3ff9c0, 0x4397e79e, 0x381ba7e9, 0xefc4df7f, 0xf93fff17,
- 0xf79fe79e, 0x6467e33d, 0xfff43d28, 0x6d003eea, 0x2fbb5f9d, 0x0fef5b40,
- 0x83c0bc3b, 0x1b4ad6f7, 0x9ad07dba, 0x972c5fa2, 0x63eb5540, 0x1da1329f,
- 0xd792309d, 0x9a95d6c1, 0xc0a55bbc, 0x5f0500fe, 0x1c7953a7, 0xe0bdc961,
- 0x673c0389, 0x71a5fc38, 0xc91b2798, 0x0aee0e28, 0xa630f5e7, 0xa14ca4b7,
- 0x9496f6fd, 0x9b37a0a9, 0xe95ef97a, 0x6f5f3141, 0xad3d2476, 0x214a70e8,
- 0x943c8eff, 0xea2596bf, 0xbe569652, 0x6de996df, 0xbde95329, 0x87f414b6,
- 0xebf3f662, 0xd8e63ed1, 0xb2d9704a, 0x683c52a6, 0x1ef842cb, 0xeb5ef511,
- 0x9859feb8, 0x5f82b68f, 0x8dc0f588, 0x78a41758, 0x94e342d6, 0xc3eccdf7,
- 0xc0c47de1, 0x7adfac24, 0x99fbe66e, 0x5542f358, 0xc188ef3d, 0xa24739d7,
- 0xea275e7a, 0x5f3aa3eb, 0x825993ee, 0xb9bf0189, 0x67542cbb, 0xffe46d7c,
- 0x5bbfc01e, 0x65bdf5e2, 0x1f643e16, 0xc700cdc6, 0xc4f93db2, 0x8ef733bf,
- 0xc6054bfc, 0x1cfc391d, 0xa5711e90, 0x109c17c8, 0x5f250ef9, 0xdeb5d4a0,
- 0x53927911, 0xb6817f98, 0xd021f303, 0x37747d4a, 0xa1493eda, 0x1223c7ec,
- 0x8e790fcf, 0xbe50fcf2, 0x7837ded1, 0xc0b464df, 0xaf1f1ceb, 0x9ef9285b,
- 0xf93d62ed, 0x617d963f, 0x37e697e0, 0x9da2360e, 0x8f4c6fcf, 0xc38876c0,
- 0xef12c3ab, 0x753bf98c, 0xf142fd0a, 0xee1f7251, 0xd43bac8f, 0x17bd754d,
- 0x99fe7534, 0xff748c7d, 0x99c7e0b8, 0x97f5187d, 0x41afd3f5, 0x946631f7,
- 0x4f550e45, 0x18b884aa, 0xc4d39ce1, 0x5df056e1, 0xe095b3e9, 0xe81f4e7b,
- 0xaf36c46e, 0xf284ab3a, 0x1a1735ed, 0x5f737fd1, 0x76f074b9, 0x6d1997ca,
- 0xeacc4f18, 0x2edde750, 0x96fdf2a5, 0x7bfc482f, 0x3d58cf4c, 0x63f9c7c5,
- 0xd63fc4f5, 0x5f8a70ca, 0x9b2606ad, 0xfb853fb1, 0xf1657945, 0xd367d825,
- 0xcc1fc962, 0x5d8b643b, 0x83c81b90, 0x4f2ec759, 0xab5d3c40, 0xd3e4aabe,
- 0x4639331e, 0x6dbf3d22, 0xc8f6b57d, 0xaa57da71, 0x8bc14bac, 0xaded2752,
- 0x73ecaabe, 0xaa7d9770, 0xd6e197da, 0xfcc18f77, 0xd39efe63, 0xd2cfb146,
- 0xa8159c92, 0xbeefe6bf, 0xa5577540, 0xbfaeeace, 0x3c357e40, 0xe490e747,
- 0x4053f903, 0xc95aee4f, 0x022fafeb, 0xc2b6d83c, 0xd7001dfa, 0x6c7eb0cb,
- 0x78fd60db, 0x039595fd, 0xb4adf5a8, 0xe577bb53, 0x6ddd6a08, 0xeb5ea817,
- 0x7f63d3ea, 0x1ef3d524, 0xfaf39d97, 0x5247f7a8, 0x93ef5b5f, 0xc6be7823,
- 0xdf40c87d, 0x988fb82b, 0xb5177f48, 0xf8c4c9cd, 0xae63f3e0, 0x0ebb844c,
- 0x7c416deb, 0x0f61de71, 0xce3173c7, 0x58e1ed3b, 0x3f6fcb67, 0x2ffdc46b,
- 0x11bf7a75, 0x710061f3, 0x744d6e2a, 0xf7c0baef, 0x8515b6f7, 0x59af7e23,
- 0xfffd6b17, 0x536fb175, 0x202afb17, 0xf247a49f, 0x56c73a9c, 0xc2390f6c,
- 0x89e90417, 0x4f5e4e75, 0x4d939759, 0x99c9b872, 0x683f3b1d, 0x9e3286be,
- 0xcd8eb0bf, 0x3ebe0f09, 0xf340cd35, 0xa09cf15b, 0x156fef10, 0xea06ecfa,
- 0x213ed6ed, 0x47f3b6fc, 0x48ddf44d, 0x9985eefb, 0xea5fc41d, 0xb2badc7c,
- 0xfdf899f9, 0x1844e7bd, 0x75f3c7eb, 0xd31c7caa, 0xcb7ae3d4, 0xd32ccdcb,
- 0xce29c239, 0xbb40ceea, 0x319bcdad, 0xb706777d, 0x7e548eeb, 0x9527835e,
- 0xea3d608d, 0xde657f72, 0xfc6072b7, 0xd91d328c, 0x973ea50b, 0x2b67a657,
- 0x56f33f81, 0x9754bc18, 0xa69fd32b, 0x6c6e22fb, 0x22a5e4b0, 0x623a9f9f,
- 0x57da84b4, 0xaa7b2f6d, 0xb79e1b29, 0x5c7648d7, 0x77eab5d6, 0xa3edad95,
- 0x16fd6953, 0xf124e519, 0x53efa320, 0xf8f3d67b, 0xd63cef7e, 0xe30a54dc,
- 0x82ce8e58, 0x679b51f6, 0xbf433e43, 0xef879b44, 0x4bbbf612, 0x48c1cfd8,
- 0x8f9c04db, 0x73ca4bfb, 0x4d29fe5a, 0xaf36be95, 0xfdca905f, 0xbcb286aa,
- 0xdf483975, 0xf6863a09, 0xd8aca1a4, 0x9f341394, 0xe34f552e, 0x60fac11e,
- 0x907d707c, 0x75b501d7, 0xe5cf4541, 0x06317fb7, 0xf409bdf1, 0x7731da35,
- 0xe41faf32, 0x087452bf, 0x4e0046f5, 0xc94dbebe, 0x8eb7bf57, 0x0c5d7c65,
- 0xf679cbf7, 0xcb9f9448, 0xdee9f09b, 0x139fc448, 0xb5ea1eec, 0xcc6b3923,
- 0xe8268fa8, 0x1dfbf10b, 0x5aba53b7, 0xd27ac267, 0x8f57af9d, 0xf209efc3,
- 0x863d0fa7, 0x615e9f78, 0x7780fda0, 0x063e5ebe, 0x2ff62baf, 0xd5d6fa7f,
- 0x807f7811, 0xe1b70f64, 0xbc62b2fd, 0x0f877e3f, 0x226ce933, 0xdcfa0742,
- 0x8f53a47f, 0xc998f372, 0xf00a9d95, 0x75114fe6, 0xa76e0aa6, 0x314db7a7,
- 0xaa4fee30, 0xf4bee6ec, 0x741f29cf, 0xea9f2da9, 0xefb87147, 0xaf603721,
- 0x1d80f7f2, 0xb1d80a8b, 0x4abf6aef, 0xcf842d53, 0x218ec05b, 0xbc29d63c,
- 0xbfa5af3e, 0x37bfd04e, 0x1e9bd4bb, 0xe783fb46, 0x4a7ca0a8, 0xb8ed3dc9,
- 0xc33ef30d, 0xf0975fd1, 0xf95e9590, 0x6fd0a96f, 0x73f8bdb1, 0x7af80af7,
- 0xfad537dd, 0x2d33a9cf, 0x521ffd4d, 0x97f11267, 0xe2526f52, 0x9e04d7b5,
- 0xa175f695, 0x77f3be37, 0x435c680c, 0x0d60c77e, 0xacc31dfd, 0x44873a16,
- 0x80e18ef9, 0x8ced1591, 0xe2b3fdc7, 0x93af26bb, 0x8f03a4fc, 0x37f1b5fd,
- 0x935df8f1, 0x80672784, 0x76463c3d, 0xae8f395e, 0x9e63edae, 0xfbe16d6f,
- 0x435b6bc0, 0x9912eb9f, 0x297bedc6, 0x33ea87ac, 0x98ed7f62, 0xe44ea25d,
- 0x596d7a30, 0x4fbcb798, 0x74b79c1f, 0xca09fcdb, 0xc52f5dbe, 0x663cea7b,
- 0x3acb796f, 0x6afc3be5, 0xd1df8ec9, 0xd31e775c, 0x7ee1f7c1, 0x4be63cdb,
- 0xce3aeaa9, 0xad0b1481, 0xd125dcbf, 0x9d264cb9, 0xe7f686b3, 0x425922bf,
- 0x9a3eebed, 0xbc75e5ca, 0x6d3c83a8, 0xf4f1fce4, 0x8bed12ad, 0x90edefc7,
- 0xc2bf4fee, 0x3a79b7bf, 0xa36f7f8f, 0xef943dd4, 0xd40e6e68, 0x3b3be83d,
- 0xe51bfbe5, 0xfbe51a7b, 0x239b29cd, 0x07e23ce8, 0xdcc92d0d, 0x5f10f5ef,
- 0xf61e2bfe, 0x30d0f580, 0x5e4a1f56, 0xfd16a777, 0xbb8d2a6b, 0x476f71e1,
- 0x29ff086a, 0x7848e309, 0x5ed499cf, 0xa9b385e3, 0xfa8178ea, 0x46e178da,
- 0x4bee3dd5, 0xdd7a3765, 0x8df94203, 0x2dfe7037, 0x9bfcf3df, 0x4d6dd143,
- 0x15f3e878, 0x1d44d32b, 0x380e735d, 0x245df1eb, 0x924debb7, 0x51b72fed,
- 0xf540dd3d, 0x36af4574, 0x73f9f145, 0x7b4a7cc5, 0xb3d71a47, 0xf9d0864d,
- 0xdc62a9b2, 0x2831d946, 0xcf41da0d, 0x8397f3a8, 0xcbf9d45b, 0xe7d55a5b,
- 0xa9f50c85, 0x3fc903cf, 0xa61f3ea4, 0x1f3eafd0, 0xf509f866, 0x3b2330f9,
- 0xdcc3e7d4, 0x7cfaa1f6, 0xab741f98, 0x5fb797f3, 0x5ef9aa9e, 0x77cfcbd3,
- 0x7e0dce02, 0x4f34c4ae, 0x4e8d2e73, 0x844d2e73, 0xcd1a5ce6, 0xde622839,
- 0xcd1f4f2c, 0xf5ea34f9, 0x971eb159, 0xb8f5fd7b, 0x44d8fa67, 0x386fae3d,
- 0x5948f73e, 0x6dfa384e, 0xffd377ca, 0x97ccf821, 0xf48b9ae6, 0x5b1ead71,
- 0xb1d57c87, 0xf3032c2a, 0x29d5ae2e, 0x83f03c72, 0xbe8921eb, 0x9d5e2f9b,
- 0xe67bfb42, 0x3f250c35, 0xc8398f29, 0x638caa4f, 0x5873cf21, 0xd6f5c69f,
- 0x33037adc, 0x6ccbe0c6, 0xd0a81d46, 0x5b124d73, 0x798dedcf, 0x3561f022,
- 0xbb587ce3, 0xd53458ee, 0x59dd85bd, 0xaac151c4, 0xb9d217eb, 0x5d73da0d,
- 0x318b586a, 0xbc59e605, 0x41e49da1, 0x628bce7b, 0x9e62dc87, 0x7df516da,
- 0x8170db37, 0x1d6789ce, 0xee33b446, 0x86fdf556, 0xb32f5134, 0x8dca3b33,
- 0x1328beeb, 0x02c597fa, 0x4836732f, 0xce0fac16, 0xb84f686b, 0x0ef3fa0b,
- 0x296f14c9, 0xce3d6178, 0x73a5c9e1, 0xea1e2fd2, 0x45f3fe47, 0xc7092d9b,
- 0xbc79a2b9, 0xc35de920, 0x9c657af1, 0x5f9e386b, 0x0a327dd6, 0xa761f1bf,
- 0x5fc8eb2f, 0x08681f00, 0x36166df9, 0x3bcf3824, 0xc44960c7, 0xdd878b3c,
- 0xa6714c93, 0x75957b88, 0xc7104dbb, 0xe21f6346, 0xe93ebe54, 0x46e8892b,
- 0xfc1bad26, 0xf80f7c22, 0x9ac7143f, 0xfa156998, 0xcd6d673f, 0x3afae889,
- 0x5f90301f, 0x2c477731, 0x1b7315f9, 0xfe788c4a, 0xb15ddcc1, 0x79967fb4,
- 0xae31c71c, 0xba78e855, 0x3260ff21, 0x25b73bcc, 0xe9ab2ecb, 0x17138aa7,
- 0xe8569d37, 0xba0d79d6, 0x1ba28675, 0xfd754bd0, 0x17e134e5, 0xfbb17a08,
- 0xbdfbe8e3, 0xfa07a58a, 0x62efbe61, 0x0efd387d, 0xc038cf45, 0x5a64f5c3,
- 0x29de2abc, 0x8e3573eb, 0x2fba73a3, 0xba24286d, 0xf655e969, 0xe386f3df,
- 0xafec55f7, 0x8dfd0c51, 0xf66cbeca, 0x5b3eb854, 0xb955f2e2, 0xfa196c66,
- 0x7d0a6f39, 0x8b88baf8, 0x045c618e, 0x189bfc7e, 0x2dff4117, 0x05fd1711,
- 0x4f6822e3, 0x6d045c62, 0x4fff38a7, 0x00603391, 0x4293d7e2, 0xd55e4ebe,
- 0x3193cbf3, 0xdff6569f, 0x80ea166f, 0xb53c12e7, 0x33a74693, 0xf6a1d936,
- 0xa9a7cba7, 0x830ee9fd, 0xed324c65, 0x81f5e26b, 0x54dbceb9, 0x66de99e3,
- 0x1b073cc4, 0x4eb81f90, 0xc466c7f6, 0x098cc73c, 0x3ff1aa71, 0xf5554a6c,
- 0x0c5fa02f, 0xeb294df0, 0x777ebaab, 0x7f5520c5, 0x424065ce, 0x95af723e,
- 0xe22ce79f, 0x2794ca24, 0x9f0dea06, 0xfa4f0fd6, 0xe9fbc011, 0xd7dd0311,
- 0xeba143d2, 0xca3acdfc, 0x0cdbcedf, 0x3b79836b, 0x5c91e79b, 0x8a227c7d,
- 0xdc6987ce, 0x08daff91, 0x61de9fe8, 0xa764fda0, 0xc21ee21b, 0xef4faaf3,
- 0xefc68848, 0x328d5cf2, 0xb59e91f3, 0xe6559e90, 0x4558692d, 0xc7307fbf,
- 0xf947661b, 0xf3dfb39f, 0xfdc7d2b8, 0x0645b401, 0xecb8e3e5, 0x3f4449f5,
- 0x7b77e107, 0x3fc5e538, 0x058f3034, 0x1d79cbfc, 0x250fae1c, 0xb3fd80d6,
- 0xfff4efe1, 0x6e71c011, 0x0e957362, 0x48f928fd, 0xe7cbe902, 0x5b7c8665,
- 0xe740d4b1, 0x4b7a2f09, 0x267d8ade, 0x7a72a5e5, 0x1d3bf4cb, 0xcd187b6c,
- 0x4381bacf, 0xdff2dc60, 0x5eb93d84, 0xffa8b9e4, 0xf5dec1fb, 0x8f913f82,
- 0x8e658c3e, 0xe7960258, 0x963a3e1b, 0x009e7540, 0x7043bd3e, 0x3bd4bfdd,
- 0xbd83a5fb, 0x3bcaa8fa, 0xfddaf484, 0x5a572409, 0xb91a77bc, 0x1ca0f2de,
- 0x197d0148, 0x9dfe3390, 0x3d833cd5, 0xaafa4ed1, 0x55f50520, 0xe50306e7,
- 0x11de9915, 0xcf70ebcd, 0xef2b1f13, 0xc6dbd4e9, 0x4d9d7c20, 0xe11df459,
- 0xd9320ddc, 0x3e3fe43b, 0xebe3cbde, 0xe30bb28d, 0xe4934f75, 0xcb5d78c2,
- 0x0e96cb37, 0x9815dfa7, 0xd9193885, 0x4f9c0f53, 0xa50775e1, 0x3f0f78bf,
- 0x74159fd7, 0x0e0da7e8, 0x7f03475e, 0x5f9f325f, 0x26bc7739, 0xf0a74ffb,
- 0x878ba668, 0xf7e0c6fa, 0xcb8f6738, 0xb36767c4, 0x0325879b, 0xedd13f3d,
- 0xe823f61d, 0x73d13c7f, 0x70fd8f46, 0xebc454d7, 0x0c86dd12, 0xabba1efc,
- 0x6e87bded, 0x7a3ee783, 0x312760d6, 0xfa40915f, 0x45f6f163, 0x7df75f99,
- 0x3ef05810, 0x48e8cf3c, 0x4b9f0091, 0x30632d6c, 0x3980b07f, 0xf8e21d85,
- 0x79e0edb1, 0x9e26cb0c, 0x30af78d7, 0x67ee3d6a, 0x5bc9a79b, 0x13be27bc,
- 0xa92e905c, 0xa2ed84fc, 0xf9c74f3f, 0xf3c73d9b, 0xd2a7f059, 0xfbf16eff,
- 0x57de8a1e, 0x6b0d75f4, 0x7fa9f3a6, 0xf04d9e94, 0x34bc922c, 0x9a4f0eae,
- 0x65551506, 0xcd6af1e1, 0x8a5e6133, 0xe9606d47, 0xdd80fc82, 0x6e7a36e9,
- 0x47d9f1b1, 0x32176d91, 0x669f5f3f, 0x6f0647dc, 0xa7ab3f95, 0x6cb2a9bd,
- 0xfcd2b06d, 0x57ee3b06, 0xb4e4285c, 0xfaf259b6, 0x6ec83af8, 0x2cf3102e,
- 0x6b537610, 0x23d87a9f, 0xa05a1d8d, 0x59acb3b1, 0x5e01576d, 0x815b973a,
- 0x33a70b57, 0xb0f08a32, 0xcf9f99b8, 0x1ef2e551, 0x4b70449c, 0x0f64a076,
- 0x67321678, 0xe3ae2c69, 0x6b8f1e19, 0xabaed3e1, 0x9d62bc07, 0xecabb85a,
- 0x01727c17, 0xda0a3dff, 0x8759a9df, 0xbfad0f42, 0xcaa5d0a6, 0xd55bf1c3,
- 0xdf3d1126, 0x3207eabf, 0xf0aa07da, 0xff816b0b, 0x4e779ea9, 0x70b67d42,
- 0xacdfe813, 0xfc28ff00, 0x44b598b4, 0x31d4bf23, 0xd496235f, 0x7e5afacf,
- 0xcf0b3238, 0xe7463a65, 0x7d585547, 0x80b174fd, 0x1fdfcf42, 0x8041fb2a,
- 0xbe78b5af, 0x17af5d16, 0x11d44c6f, 0xd3c039e8, 0xfa64a782, 0x9c6827ae,
- 0x243d7f88, 0x8f1ed54f, 0xd5cbeb11, 0xdc3e7e7a, 0xeb74e0b5, 0x5d29eff9,
- 0xfc5ede13, 0xf70aefa4, 0xf9bde907, 0x4262fd59, 0x9d6529e9, 0x72bd08ef,
- 0xb7aefb4d, 0xbec8c5df, 0x8f984827, 0x575f4de9, 0x00bebb09, 0x67b43ced,
- 0xe740bf36, 0xe9bfbe2e, 0xd55f3a05, 0xda02ecf8, 0xf3667097, 0xf7f087bc,
- 0x98ecce23, 0xe17d7647, 0x775d8a63, 0x85fd8319, 0x9e73cd92, 0xafc85ff8,
- 0xdd5384cf, 0x4bbf6ab8, 0x47a039c4, 0x336d9c61, 0x136c9bd7, 0xd10ba3d7,
- 0xfd92e5fe, 0xddc709bb, 0x09bae557, 0x3ae83ef9, 0xe6fbc5d9, 0x07b77eb9,
- 0xb7efbde6, 0x2d0f7691, 0x79e3e2d9, 0xed0f8b67, 0x7f3ded5f, 0x0bbf4539,
- 0xeb791f25, 0x87bd8ac7, 0x577aedee, 0x97ca0642, 0xf2b5f3b0, 0xfa0b0cd6,
- 0xfc2ec205, 0x173df1b3, 0x14fe4df1, 0x4dbbf7c7, 0x6defcf1c, 0xdc6f78e0,
- 0xd3e297d1, 0x92fa9b77, 0x8eeef51f, 0xf9ef847e, 0xe4df01eb, 0x7ed4db47,
- 0x1be01354, 0x37c404e3, 0xbf7735c0, 0xcedbe04d, 0xf1c4ddf1, 0x76f036cc,
- 0x7abc0f7e, 0xfbf4fce8, 0x8ecc3dfe, 0xe187c17e, 0x3e97f23e, 0x99d329dc,
- 0xa59f8a67, 0xb19f39f8, 0x1fd1c7e6, 0xa8bdf053, 0xea087fbf, 0x7f8d8a97,
- 0x2fbc468a, 0x2393c9da, 0x1ccdf03d, 0x076fe849, 0x2fd57fde, 0x0848cb2a,
- 0x21be8bf2, 0x9398ea5d, 0xe1d723f6, 0x82436479, 0xbf2b3df6, 0xe7dda65b,
- 0xc8f9e36c, 0x99376630, 0xed349e10, 0x18b9afef, 0xbcfe7bee, 0xf75985df,
- 0xab771c90, 0x12634f7e, 0x9cf019f3, 0xd122d602, 0xe5da967e, 0x188ba34b,
- 0x4f5a3f9e, 0xe0cdac70, 0xbc2bbd76, 0xb2fc833b, 0xef1c613d, 0xf3aaf19d,
- 0x6fdd2789, 0xb457f98f, 0xf9f847fb, 0x763c93c4, 0x1a4e67ca, 0x2ab93431,
- 0x2e0bae88, 0xab8973f3, 0xf2e6032e, 0xc6fdf7f1, 0x0587bed2, 0xcea853cd,
- 0x496d055f, 0xbe5ef8f0, 0xc19b5bbf, 0xb8539be3, 0x973c3ca6, 0x9d7efc49,
- 0xea8d1738, 0x539b80b4, 0x373a4ee1, 0xc98254ef, 0x8bbacfce, 0xeffdf3a1,
- 0xa6707a16, 0x13ed20f9, 0xcc3c7987, 0xbfd6e78a, 0xab014069, 0x8b3c7530,
- 0xe4ecf021, 0xe935eef7, 0x837f6b70, 0x7773e445, 0x13d7157d, 0xd51d009e,
- 0x23b9b9e7, 0x9a3fe742, 0x87255e05, 0x610cea83, 0xbc047730, 0x3619e7ff,
- 0x6fec5d7e, 0x9e805b67, 0x85cf3d51, 0x0f33ae53, 0xa6b60f3f, 0x2b7dfe18,
- 0x7a848ce3, 0xfaa9d643, 0x7f7e4635, 0xc9c4c67b, 0xf631469b, 0xf7ac0306,
- 0xf194bf45, 0x8c4e7f38, 0x4d75f717, 0xaca373c6, 0xaf89ead8, 0x4799eaa6,
- 0x3326dbc7, 0x79c43bd6, 0xfe049351, 0xbe608fa6, 0xdf7de018, 0x89b9f561,
- 0xbe74f977, 0x93af009b, 0x21ba5cf1, 0xcd9cfe78, 0x38f78160, 0x8c3ca4cb,
- 0x7f566a4f, 0x64f77833, 0x94de4f94, 0x8e9d7d06, 0x9e63f9c3, 0xf989988f,
- 0x2cc3c079, 0xe72fdb3d, 0x5e237a71, 0xed1b56dc, 0x2a5ee8f3, 0x25147ed1,
- 0x7bd0af2f, 0x4f2f2068, 0xe0299c74, 0xa29a7983, 0x686379f1, 0x50ce1d7a,
- 0x8a16e8e2, 0xf90897af, 0xe5c8a25c, 0x9e5cb50e, 0x7e823a45, 0xc8893dc6,
- 0x0b453357, 0x6bf9a4eb, 0x73947bc4, 0xf064cfd3, 0x0c99e97c, 0xfe387f5e,
- 0xccc7df2d, 0x45469cfc, 0xf8c36b3e, 0x27fbcafc, 0xc333b68b, 0xf02bf34a,
- 0x1ff1f368, 0x7e43596c, 0xccb7f552, 0x1be907c7, 0xc6497baa, 0x7a88f9ee,
- 0x49c25fe9, 0x5b1a66ee, 0x7b9bd5fa, 0x1dce538e, 0x037e60ac, 0x55300faf,
- 0x6cb4741d, 0x2b2c73a6, 0x9afbfe24, 0x1e51455d, 0x6be60c5d, 0x8ada440c,
- 0xe973f31f, 0xfbe709de, 0xee632b3b, 0x607e849b, 0x4f51b445, 0x7f31ece7,
- 0x40565654, 0xc91636ef, 0x04214e74, 0x6eb19382, 0x7feb06b6, 0x23b0ffbc,
- 0xa24bb28d, 0x51d7b3ff, 0x02bb4d1f, 0x43fea7f4, 0x0f101d93, 0xf7101d75,
- 0x7cf4c3d9, 0x8f8203d7, 0xfde73f3d, 0x37f7285f, 0xe53afef3, 0xffde16fe,
- 0xe8bf3299, 0x5fdcd46f, 0x4bffb9a5, 0x627c4fde, 0xfa0f64cb, 0xa59cc5af,
- 0xe8956e2b, 0x05ca3577, 0xf6ac559f, 0x742b7e11, 0xcc5b797b, 0x6b82ba7c,
- 0x74ce2b8f, 0x211fa396, 0xa1467547, 0xe5909e9d, 0x75bb4728, 0x2b2bba6b,
- 0x53c5da13, 0xd6118f24, 0xc97b8ecd, 0x45ea4c6e, 0xbe0b971f, 0xf9f1b22d,
- 0x3cc37c14, 0xbf0b3303, 0x847e3cfd, 0x4f35412b, 0xf3c0f5fe, 0x798f5b6b,
- 0x3ccf5d46, 0xbaf52cba, 0x89e83f14, 0x385dc76c, 0x2e1ed69f, 0x063da9f9,
- 0x35ec50f3, 0xeae1fdf1, 0x987c8c96, 0xbb73c97f, 0xefd0aa33, 0x1d40fe12,
- 0x3c7cc3da, 0xc3db82e7, 0xf24fdb8f, 0xdabb707d, 0xbf30638d, 0x3db06d0f,
- 0xce05e9ac, 0xd89d4c8a, 0xd791b047, 0xab3b9ec5, 0xd12e7a47, 0x0c799cb5,
- 0x52adfbed, 0x1127dfe8, 0xe5ea9dcf, 0x66e68e77, 0x90d43d72, 0xeb8398e3,
- 0x3464c92c, 0xe84d64be, 0x9b7f9a73, 0x8572edc9, 0x86f37bb0, 0x806c9945,
- 0xaee3c2e7, 0xaabfb835, 0x1e564b6a, 0xa56785e6, 0xfcc92f17, 0x376abcda,
- 0xf1b6abcf, 0xd5856abc, 0x37941cbf, 0xedb33a7b, 0x633a5361, 0x914dffe3,
- 0x78591033, 0xe94c2cb6, 0x74b939bf, 0x617bcf14, 0x4713dd7f, 0x39b9461e,
- 0xfe60f084, 0x08e0f87c, 0x591d0bd4, 0xe80b3a91, 0x7369598b, 0xacfe469e,
- 0xda03fe1c, 0x1614532f, 0xcf0e7fd5, 0xcc5f13cf, 0x42ae734a, 0xe63c7138,
- 0x5f465c43, 0x0eb05dc2, 0xed32abd7, 0x890d7553, 0x4efc8574, 0xe9e1e059,
- 0xebe10b4c, 0xfd199010, 0xe50e0514, 0x2fe7e0fd, 0x9d7cc3f7, 0xe28653ab,
- 0xb4be4e77, 0x85996da2, 0xd2fbf781, 0xbf048f5c, 0xfac753bf, 0x4df1a863,
- 0xc05878e1, 0x06e90db1, 0xcc9473ad, 0xdef1411c, 0x5548d2d4, 0x3884da7f,
- 0xd7ce08e6, 0xf5554b4e, 0xaafa2bcb, 0x7f3ddfc6, 0xc4feea90, 0x7d417f30,
- 0xbbdbbf90, 0xe7e1e49f, 0x4545458f, 0xbfbcbee0, 0x36f67db7, 0xd7745efe,
- 0x7d1db253, 0xb67b45da, 0x03478dbd, 0xb39fc45f, 0x8da43ca0, 0x1d1f66f2,
- 0xd73f1992, 0xae0fa1c2, 0xfe639d0f, 0x1077f147, 0x2907ab7a, 0xcb12eef1,
- 0x801dfa7e, 0x3a0f5d1b, 0x41ea2998, 0xed0f2c79, 0xb7fac5e1, 0x67576f28,
- 0xb73bebe6, 0x8b4f9f9b, 0x057f53e7, 0x3e077efc, 0x65e1fe88, 0x4bb5e50f,
- 0xfd534f5a, 0xeb932aac, 0xa5b4bae9, 0xdd8bf47a, 0x181da2d0, 0x062afa03,
- 0xcedfc5f8, 0x7dc2ef06, 0xdc51596c, 0x953cbf5f, 0x2be438b1, 0x9439e79e,
- 0x53bf4b18, 0x8ca9a4bc, 0x8e5dd7ae, 0x975ff9a0, 0xcd4fb4fd, 0x754492f3,
- 0x95a98988, 0xc6bf71ab, 0xee4f08a1, 0xc4ef7832, 0x8651dddf, 0xc5dbab78,
- 0x944c91f7, 0x0a5828df, 0x19734d6d, 0x66513f3d, 0x17f02487, 0xfb7097c6,
- 0xbe6d113b, 0x46e0f715, 0x2bbb47ad, 0x7ffd7d1b, 0x18c67a85, 0xe6267a45,
- 0x7ef4ddf2, 0x3d1365f7, 0x88f425df, 0x35c383a1, 0xae93b2fa, 0x59f0fc2b,
- 0x77eab666, 0x4f090c7f, 0x91f7f1e9, 0xc68c1d0d, 0x903cbb8f, 0xafbd655a,
- 0xfa77f80e, 0xc2435b5d, 0xfa5fb4a7, 0x42c978d5, 0x0f46886e, 0x1e1faa5f,
- 0xa9e842c3, 0xf111efab, 0x5fea1848, 0x72ccbf68, 0x3012da44, 0x63d0e99e,
- 0x4d99885d, 0xffe44fb4, 0x0538cd00, 0x00800076, 0x00000000, 0x00088b1f,
- 0x00000000, 0x7dc5ff00, 0xd554780b, 0x399ef0b5, 0x66491e67, 0x99212726,
- 0x4ce21024, 0xe010245e, 0x0f080424, 0x860240cb, 0x084013a7, 0xbc80e834,
- 0x2b101025, 0x0337e95e, 0x60d22049, 0x45405283, 0x68b0503b, 0xaaf8ff6d,
- 0x0131f5a9, 0xe94a0fe4, 0x7ab7bd60, 0x52036b6f, 0xe08d4504, 0xb16dcfed,
- 0xbdad6bfe, 0x3267324f, 0xfdeded41, 0xbe3ef9ff, 0x3ef6759d, 0x7af6b1fb,
- 0xb30fb5ef, 0xcb5d8aca, 0x0afb188b, 0x9318137f, 0xbb302e8e, 0xda663286,
- 0xb1ecc67d, 0xb2816631, 0x96bea23c, 0x046b4f31, 0x2e4995ac, 0x19236323,
- 0x3950b6fc, 0xfbc1db0b, 0x631f77cc, 0x576ec64e, 0x4a6dff18, 0xb1832c65,
- 0xed04dfbf, 0x0fde7b53, 0x852ea01b, 0x968bc0b1, 0xbbf861e0, 0xc72fb65f,
- 0x89e1f505, 0xec39faac, 0x55670e47, 0xcddfa1d9, 0xda15b29d, 0x39559b31,
- 0x9ff806ec, 0x6f82ff34, 0x8ba77f39, 0x12b7ffcf, 0xfdfd84db, 0xb084c276,
- 0x7ed5e607, 0x921188ff, 0x31dfa7ab, 0x63b5332e, 0x5675d74a, 0xd7bad8ca,
- 0x603b5c12, 0xc1fb337d, 0x5ebb8033, 0xba0f04b5, 0xa43339e9, 0x68396960,
- 0x8e75fa80, 0x8c2f7cae, 0x5c7afe5f, 0x7e830d88, 0x19938f5f, 0xae52f38c,
- 0xa5e20c6f, 0x1541f5fc, 0xf24c0706, 0xa0cc8b15, 0x3c9ba4dd, 0x5f79f163,
- 0xaf5e8df3, 0xf9c60256, 0x18a7cefc, 0xadbbbdf1, 0x5529b5fc, 0x22624086,
- 0xc954d774, 0x16c608d8, 0x9b0d9b5f, 0x6b92d8c2, 0x5afb04f1, 0x75abf3f8,
- 0xdf705369, 0x49866eae, 0x6c963ac3, 0x017d0c36, 0x765cc5d6, 0x30f00f35,
- 0xada2c073, 0x5339e60c, 0x677ad232, 0xd60a490e, 0x71dbd343, 0x73e0c7bf,
- 0x664861d6, 0x3db97a6c, 0xd6f18460, 0xdfa8535c, 0x1a2e6bda, 0x64b5ed6f,
- 0xb35dd782, 0xdae4b952, 0xb96e7a60, 0x801e6466, 0x1c035e97, 0xdb273c00,
- 0x3fd70ab7, 0x4a96feb3, 0x35b7cf1c, 0x8b67d4a3, 0x82b317a4, 0x92f40574,
- 0xb3d6dcbe, 0x05f6fafe, 0x2fe85530, 0xb2f44bc5, 0x88f2ca14, 0x0e8265fa,
- 0x56b6f1a2, 0xa537ffec, 0x5f411a97, 0x3ca16c4b, 0x54c1e023, 0x856ea717,
- 0x71495cf9, 0x6cbc414d, 0x6fe38078, 0x6e5bc983, 0x786ef987, 0xcec2a0c4,
- 0xd9473bb0, 0x32f00cad, 0xb33addea, 0x176e822f, 0x5cc61b5c, 0xd739feb0,
- 0x7dbca972, 0xae336fa0, 0x79b5f17f, 0xa8c34f02, 0x2364d664, 0x46d8c51b,
- 0x4e1757dc, 0xb3ef9928, 0x7517df98, 0x85eed3a3, 0x6538bff1, 0xb88bfaa2,
- 0x5530252f, 0x9c09e04f, 0x51682997, 0x2ebcc00f, 0x8140589a, 0x9f73b8ad,
- 0xdf000591, 0x41f4a14b, 0xb07b5d09, 0x291de59d, 0x92ed8ed8, 0x04a92798,
- 0x2deb09f1, 0x057c63e0, 0xc2192eff, 0xfd42f7f9, 0x965b3327, 0x81e0731b,
- 0x86552a74, 0x9cf27e75, 0xbe7824c4, 0x4e1bfd6a, 0x95ab1e58, 0x5029640e,
- 0xcc10d1bf, 0x3d8c4937, 0xe2f6fb22, 0xd85a3eba, 0xd0656ffa, 0xf3cb7cee,
- 0x0d57dc0e, 0x2872adaf, 0x0569fb0f, 0xee60067c, 0x6552cdad, 0x26c346d0,
- 0xa1ed0d54, 0xa39e8d6f, 0xb5f57ce9, 0xaba7a26c, 0x2fa19675, 0xdd031d20,
- 0x415af3e2, 0xfd2177ef, 0xacea6943, 0xe9c8f414, 0x5aeba35f, 0x5aadcb99,
- 0x0030625b, 0xbff99bf3, 0xf500fe80, 0xf2a85f6b, 0x2bba444e, 0x5079a830,
- 0x32fc11ac, 0xe0f83a53, 0xcf83e458, 0x787ad452, 0x579af93e, 0xc1f3d73c,
- 0xc674fe4b, 0xbc4b19f2, 0xd5c690b6, 0xe822dfe8, 0xdff484dd, 0x2d83de8f,
- 0xd9fffe05, 0x77ff9edf, 0xdb90f3f8, 0x6be216f7, 0x7fca1c9a, 0x3b4b052c,
- 0x94e4d1d1, 0xe7e9192a, 0xb3cfcb9b, 0xd59e7e42, 0x7db5cfc9, 0xb7f0cfc8,
- 0x04d787e4, 0xd85a543f, 0x2e22de1d, 0x7bdb67df, 0x3d97ebfa, 0xea0b9ce9,
- 0x7819743f, 0xf343ff7f, 0xca5bf0fe, 0x86fd7ffd, 0x42afff72, 0x79cb47ee,
- 0x9ca1fd06, 0xc2d5ecff, 0xf781ea20, 0xd405e819, 0xb824af7b, 0x403d0b0e,
- 0x313e227a, 0xd03d2378, 0x5fe77b90, 0x7f03d0fb, 0xa3fdbc43, 0x3fa3407a,
- 0xfe345f8d, 0x9a21f8d0, 0x987e347f, 0xf13503fe, 0x401fdc5e, 0x1fe461cc,
- 0xae0cf039, 0x5095d6a3, 0xf1a97c8c, 0x0c17dad1, 0xf4bd67c4, 0x1e9be083,
- 0x0bebd13e, 0x3e341f8d, 0x56a6f8d1, 0x28b2c3f0, 0xb526387e, 0xde163c3e,
- 0x15f6eedb, 0xf87b53b9, 0xd173cd63, 0x7a4fa17a, 0xcb4f4862, 0xd218ea52,
- 0x91942d53, 0x83e964f4, 0xdfdd8a9e, 0x126e9e8e, 0x9e8ebfed, 0x6a66dc2a,
- 0x4f483ff7, 0x3191ee15, 0xfbb269e9, 0x5c57689f, 0xa97dfbad, 0xb573e60b,
- 0xbbace414, 0xbfa6de87, 0x90ddb8c5, 0x7e915763, 0x3af9e23a, 0x8303cc3b,
- 0x2beed8f5, 0xd4788756, 0x67db52e8, 0x86580ecd, 0xb6e50074, 0x9c2aef6c,
- 0xa07c476f, 0x9337fd68, 0x96cfb477, 0x53d9b094, 0xd61dfb84, 0xecbeffe9,
- 0x72dfb5c5, 0xdfdc6b9f, 0xddf86e4c, 0xd17b74ff, 0x272d8eef, 0x7d9dff02,
- 0x7f0e599d, 0x94f047f6, 0xf61e33d7, 0x660287e7, 0xcbf22f61, 0xfead32bc,
- 0x191e2d37, 0x3dfc03e5, 0x30f04696, 0xc381e12b, 0x0ae1d381, 0x87f4e798,
- 0x5803ebbb, 0xa27c793f, 0x0c798fe8, 0x8ffda7ac, 0x6e15bc0f, 0xc2defd26,
- 0x94ebeff1, 0xe02343bd, 0x11ed8052, 0xbc145970, 0xc877b79f, 0x7ea14c9d,
- 0xa0af9c82, 0xc209437f, 0x7e827f5a, 0x55f8e799, 0xc52cf3c0, 0x3ec076c0,
- 0xf0394bad, 0x6b9455c6, 0x7066066d, 0xfd81e045, 0x04c9ebde, 0x20c578ba,
- 0x7b08ffe0, 0xf85b1972, 0xb84f8702, 0xc812d4ff, 0xbe02fd15, 0x9b7408d7,
- 0x091e0d5a, 0x66535bfa, 0x7bbb6608, 0x5b84fbe3, 0x7cdaabd3, 0xdfea5540,
- 0x6f94e667, 0x6d1a3ef7, 0xbd367ef4, 0x8b7cb21f, 0x678fe7f1, 0x7b0c609e,
- 0x1f820ff8, 0x63134a2a, 0x4b779fd6, 0x01d7ff1c, 0x4787c6d6, 0xc1fd6073,
- 0x5975fc18, 0x1a3617f4, 0xd6ff3e05, 0x36167482, 0x6bfef86b, 0x327be20b,
- 0x8274dd63, 0x13e30374, 0x7fdc7ffc, 0x7cc936f5, 0x7c289eb9, 0x6fbd68dd,
- 0x2057c0c6, 0x372cbf6a, 0x6ee9f7c0, 0xbef3d0b9, 0xe87eff4b, 0x4ef5fb46,
- 0xdd05f1af, 0xd8e8d4ae, 0x44f7a3a3, 0x99f44bd9, 0x02506298, 0xbd6b8f40,
- 0x2fe8cd71, 0xa9a7f0f4, 0x8e14f10a, 0x87a9e3d3, 0x1555ccff, 0x448fb236,
- 0xe42eeb7b, 0xbbb1af5f, 0x6ec7e73d, 0x029e66ba, 0xd29a2bc0, 0x41d27ef8,
- 0x8d80aecb, 0x09ea82e8, 0x77988dce, 0x46b63f34, 0xf8a3e3c1, 0xc91ff057,
- 0x8007d40f, 0x6f943ca7, 0xaecd6729, 0xb3513a08, 0x313e9e39, 0xa7946ab0,
- 0x8edc49e1, 0xd2f3670c, 0xfaa06d9b, 0x1fbe6cb2, 0xe386511e, 0xa7a0f023,
- 0x2bfa109f, 0x3c26eb11, 0xd6d1482d, 0x0335505d, 0xe64e15d6, 0x73b2d3f5,
- 0x7b320577, 0x66fee8e0, 0x05541764, 0xcffb228a, 0x5d78833f, 0xcde6f020,
- 0xeb06741e, 0x4b507935, 0x11f44284, 0x8b507940, 0x4de861f4, 0xbdd9e91f,
- 0xf51033e8, 0x8374c7be, 0xbf7ab3f7, 0x9f7a89ef, 0xcdbe5299, 0x66df62fb,
- 0x656bed44, 0x4456bed4, 0x1c1a35c1, 0x4d5fc9d4, 0xdb692f2e, 0x7984e8d5,
- 0xe40475dc, 0xe7a48b2c, 0x77cf4451, 0x8efd1a29, 0xbb7a833e, 0x08cb9e87,
- 0xf62add9e, 0x1766302d, 0x942a9fea, 0xe07b63c3, 0x08872839, 0x19e55b1e,
- 0xc6afa91e, 0x3db942ed, 0x3f6b49bf, 0x6c2fda9e, 0x99bbfad0, 0x647db5ea,
- 0xd154ef81, 0xc3b90abe, 0x60ce1302, 0xf857eafd, 0x3d07f5fb, 0x0fc86e67,
- 0xd978512d, 0xa207051f, 0x1afeefda, 0xf510d6fd, 0xfaa8e6fe, 0x5f7828e6,
- 0x7fa4dc14, 0x0352f17f, 0xa062e1f1, 0x6888dc07, 0x8fa68cbe, 0xedbbb387,
- 0x6e7d6e9c, 0xa77d91b0, 0xf5e9abe3, 0xe0fc7e1c, 0xa2a6aacc, 0xd6fb3808,
- 0xdff700aa, 0x2697480d, 0x73207fc6, 0x83d01203, 0xf9b90fa9, 0xb2e8be83,
- 0xf3df5a20, 0x9fe13ffa, 0x332f6819, 0x4c725d9d, 0x92edc3d2, 0x6745ef36,
- 0x43e11636, 0x42a9ae0d, 0x5efa7a7f, 0x9fc0bafd, 0xaac2f015, 0xbb08cc8a,
- 0xcaa0b028, 0xad4eb113, 0xbf2f94fd, 0xe7bc7092, 0x1d5417b3, 0x499afa82,
- 0x983abca1, 0x2f324d67, 0xa84a5f41, 0xf889d7af, 0x255794cd, 0x9acbea2f,
- 0x86de50f8, 0xb27588a2, 0x675c7cd6, 0xed12fdfb, 0xf61ea04f, 0x98b4f007,
- 0x8f0a2381, 0x331e64ee, 0xc4fa81cb, 0xc24f4dc4, 0x97eec77b, 0x7e9ea136,
- 0x273f537f, 0x39c943fa, 0x963ceedc, 0x19739378, 0x7709edc0, 0xdf6dbc90,
- 0xa3ca993e, 0x975b6792, 0xd9dbd8c2, 0x856caaab, 0x78489f58, 0x69707d3a,
- 0xefa016d5, 0x7a2ed933, 0x38ac97df, 0xdeded0db, 0x5d876261, 0xe2952f38,
- 0x5a778b48, 0x7ce0778a, 0xa2710cb6, 0x47e4b9fd, 0xa0325355, 0x934692dd,
- 0xa754768a, 0xf9c2c951, 0x364c76f9, 0x06d2fd63, 0xa16e0651, 0xffbff5f2,
- 0xed01dea4, 0xa8371ebb, 0xcdfda107, 0x35beb45f, 0x4d15e00c, 0xd16e2a39,
- 0x2807e06b, 0x7db9ce30, 0xd0128283, 0x757107e5, 0xf6f16627, 0xb8afdb0c,
- 0xab3d3aee, 0xca4bdb14, 0x017f6856, 0x7cfda39e, 0xa0e901e1, 0xb0e5e701,
- 0x49601bc7, 0x1464be17, 0x68d0b9cf, 0xee7c6209, 0xfb77cd9c, 0x9f671c3e,
- 0x767d2d09, 0x1872e0c1, 0x1d9f0f00, 0x3d2ab7bc, 0xc45b9f03, 0xb49bdefe,
- 0xd8b0f018, 0xa43f4dd8, 0x7127964f, 0x7becb3f8, 0x3ac30eab, 0x88323c2e,
- 0x722b57e2, 0x80d95d3c, 0xcf5cc2af, 0x107e58e7, 0xebd6f5c7, 0x40ee977f,
- 0x97d7fe3b, 0xbe913897, 0xd6f426fe, 0x3896d76b, 0x55d84497, 0x89913fcb,
- 0xbb375e0e, 0x5f7ce236, 0x40681f8f, 0xa0e81b3f, 0x97c9c61f, 0xe805bf0a,
- 0x31f3d379, 0xcd7fabec, 0xdabf6896, 0xde3a907f, 0x6deba3a5, 0xdfc8a7a4,
- 0x93f6d800, 0xa002bbad, 0x365bcfdb, 0x8e500fb1, 0x7147ee6d, 0xc84ca5db,
- 0x82e26781, 0xf4b157e8, 0xf8c8fcd6, 0x8a1f374d, 0xd80c7ff6, 0x847faf09,
- 0xfdf7e8f6, 0x761ff031, 0x7eddeb66, 0x401ec385, 0xbb43e2e3, 0x78fdc65d,
- 0xb85ff65f, 0xfe5bde0f, 0xc0f489b8, 0x3753c7f2, 0x40b8e177, 0x8b571837,
- 0x1c82d75e, 0xf4638f13, 0x878197c5, 0xfe742aab, 0xbf24c3ca, 0xfccbe2fb,
- 0x75543c9f, 0x5f37d6c8, 0x7cb850ae, 0xc9b8f29a, 0x62b4fc8b, 0xa0665da4,
- 0xfe3d264f, 0xcfc461c6, 0x2571f58a, 0x8af89816, 0x5fb42dc7, 0x407b769d,
- 0xc39f7a81, 0x5941272e, 0xd6e5c39a, 0xed171cbc, 0x64c4b973, 0x0d95096b,
- 0x82bd6f18, 0x2f800de1, 0xcf787a6d, 0x23e71868, 0x1a379c16, 0xc3c577f0,
- 0x0bcaf4e9, 0x991dc512, 0x826791ec, 0xb8c95cbc, 0xf93da89c, 0xfc2279bc,
- 0xc56eb2b9, 0x5707f40c, 0x3ae74d05, 0xf18e0f85, 0xf9ac75d8, 0xea186973,
- 0xa273fd57, 0xf3d62704, 0x49d61adf, 0x35b6a372, 0xdaebfbf6, 0xe467cff4,
- 0x0c2e53d8, 0x2e431861, 0x2bb10c01, 0x067ca675, 0x03615c4b, 0x96f582fe,
- 0xbcd037ef, 0x82926c57, 0x79779816, 0x3e2f1e3f, 0x37fd87ef, 0x0a03bad3,
- 0x73762bc0, 0x1982b3bd, 0xf3f85682, 0x29ebfd96, 0xc84c797e, 0xe606c599,
- 0x20fefa45, 0x3f42cd4e, 0x71e3f97f, 0x4f15df84, 0x47b7faac, 0x2dcebde0,
- 0xfd225333, 0x174825ea, 0x9accbf1c, 0x87cfd3dc, 0x859fbe5b, 0x63fe5ff4,
- 0x3d618ff0, 0x2fd8922b, 0xbf71b816, 0xb65cb232, 0xb62b769e, 0xdbcf9fde,
- 0x7e0d7f81, 0x2407e2f4, 0xd17b075a, 0x78107a42, 0xdbc4895d, 0x669386d2,
- 0x5bff1173, 0xdafb0a71, 0x39bc7285, 0xe7fbc12c, 0x11b25ea0, 0x119d02fe,
- 0xb03bf271, 0x23920caf, 0x8d5f5c3e, 0x6cc770d1, 0x8ccba7ea, 0x8733bd7c,
- 0x441b43c7, 0xbd4b38b9, 0x0fcfe29d, 0x6eadd45a, 0x4a348fde, 0xbbfc03cc,
- 0x3978635a, 0x2fd981c6, 0x5957142d, 0x89e710d7, 0xe23f9073, 0x5dfa0e79,
- 0x9cd93327, 0xfa72fd8c, 0x72e2e35b, 0x2bbf9e03, 0x3b5af3c3, 0x49b58b97,
- 0x97ae6f80, 0xffe8463d, 0x872bfc33, 0xac3197f7, 0xf1eefde7, 0x85f53d0d,
- 0xfd5f10c3, 0x3ce355e6, 0xdf112e7e, 0x2c1e3202, 0xe7eefb43, 0xabf408d2,
- 0x6c703f17, 0xbbd9ca0a, 0xf0562d9e, 0xf8bfc5d5, 0xbb89e91d, 0xa2773ec4,
- 0x037a8f9d, 0x7ca167e0, 0x45cb8732, 0x42e3c49f, 0x687c0a4f, 0xd7d5adfb,
- 0xf1e2603e, 0x28e79079, 0xfcb76a40, 0xb5adfa9e, 0x67289d87, 0x8d345f6b,
- 0x94fc7942, 0x2d92ff98, 0x0bbfc703, 0x94c4b3f4, 0x5a5ea0a8, 0x46699813,
- 0x818b4d78, 0x52f79ee0, 0x3f1e90b3, 0x81c9786e, 0x5c41f274, 0x4ff50f28,
- 0xf538fad7, 0xe1402e20, 0x1b8fb971, 0xfc620ef2, 0xb612a966, 0xe97ea01b,
- 0x94649cc6, 0x212befd3, 0xdfbfd633, 0xec2236ea, 0x08f19451, 0x04e1e47b,
- 0xab220c7f, 0xca0fd055, 0xbe06b599, 0x399e6b9f, 0xf186ce66, 0xfdc3937e,
- 0xfe7e4f9b, 0xf38c7cbb, 0xf38566d4, 0x7ec07f51, 0x3c400fe7, 0xfd206d3f,
- 0xc919f6bb, 0x67ac3713, 0x7ee2d7bf, 0x16ad7f03, 0x85f6bcfb, 0xba45ee97,
- 0x5dfb8b5f, 0x805e9bd2, 0xf3d38f6e, 0x614c0ee7, 0x48e3fdfc, 0x02be9a17,
- 0x8c94c1b8, 0x9f0e3a71, 0x02fce1ce, 0xf3f82bcf, 0x4bc91140, 0x67682390,
- 0x5f7bd346, 0xd8b1fbfb, 0x2c5b25bf, 0x163f5724, 0xc0f9dbfb, 0xbfdc0e8b,
- 0xec7e7e4f, 0xd4a39e04, 0xd8da073e, 0x05ee8315, 0xfae1d63e, 0xb27f341d,
- 0x7ae1d623, 0xefeb3d1d, 0x6fc173a6, 0x9f5f18eb, 0xb275deb6, 0x2f56bf58,
- 0xd62cbfde, 0x7c0986b9, 0xf38830bd, 0xe427e097, 0xb4c7b457, 0xf992f9f5,
- 0x267d1afb, 0xffb972e7, 0x99ff2137, 0xfc40ead2, 0x9ca2fee0, 0x98f1fa01,
- 0x01b90947, 0x16793e4d, 0x5fb11fe6, 0x73b3fcda, 0xae403cf9, 0x7b929279,
- 0xc8d3b1f6, 0xb73ac656, 0x78e5c84c, 0x9698db3c, 0xfbf806d5, 0x892bfc18,
- 0x23957a71, 0x46e8d3c6, 0x67fcaf1b, 0xdd70d355, 0xfb087fd0, 0x3f7dc6d7,
- 0x3f632090, 0x1fce33ef, 0xbe35fcda, 0x345faf2c, 0xed81d8ad, 0x14e7b13e,
- 0xdd39bae1, 0x542ae766, 0x802ed07a, 0x066d3df7, 0x159f4f8a, 0xc6d9fcfe,
- 0x8a4b1c97, 0x25dde87a, 0xd93f8de6, 0x1a9e7bd9, 0x33d045fd, 0xfb7cb3cd,
- 0x6b0869fc, 0x4ba68df3, 0x7d1a6f0d, 0x64a9cdb2, 0xe9d344af, 0x66b3ccba,
- 0xb9fa2f1c, 0x807cb766, 0xffe415f1, 0xf2e3c654, 0x6e78ec0d, 0x9f863e84,
- 0xd1ea8d8d, 0xd79c9a0f, 0x14baf3f4, 0x2fc225cf, 0x43703a0b, 0x5366e736,
- 0xc72977bf, 0xfde039b7, 0x74c3e731, 0x87d9abfe, 0x92117f37, 0xf48e3112,
- 0x5224bb82, 0x7cb9adcf, 0x96b6e89c, 0xbfa1b785, 0xdf81f8b3, 0xf48d1ccd,
- 0xce8994f9, 0x4e37165b, 0xbddda336, 0xa39df0ea, 0x35cfdf70, 0xa9763d71,
- 0x6893e461, 0x7a6b9f37, 0x116779d8, 0x653e57be, 0xbc5f3c2c, 0xf5f698ab,
- 0x4cf0b883, 0x91eebb84, 0x6f7841d8, 0x9b91e1dc, 0xce3c0217, 0xae12537e,
- 0x5243fdef, 0x3a08d8c5, 0xcd94ca58, 0x934ed10b, 0x8be41513, 0xab3c85f7,
- 0x5a7df137, 0x517fe82e, 0x45f3e72e, 0xebcb7f62, 0x7cf1f3eb, 0xc800ebbc,
- 0x8d63c051, 0xc21ad5d9, 0x234d5f71, 0xd81d7fbb, 0x74c9e908, 0xd2764d4e,
- 0x66b3334a, 0x6b73d094, 0x693f3c06, 0xeb83df0a, 0xbd8f7939, 0x58e20b78,
- 0x096a3eba, 0x5f896fb7, 0xf1a5aec0, 0x3168edbb, 0x2e82658f, 0xded3fba3,
- 0x1ebb40ef, 0xff989ee5, 0xe6a786a5, 0x74babea1, 0xd7192f24, 0x71abe1ff,
- 0x7cdf684d, 0x4c72e268, 0xaeec1feb, 0x11f691f3, 0x183a5bd8, 0x0c1d2aec,
- 0x6f5e75f4, 0xbc256d8f, 0xb7ab9bdc, 0xad3a34ab, 0x18979f59, 0xcbd01799,
- 0x0a43fefe, 0x9cf7ff9d, 0x644e8cbf, 0x7742e431, 0x880fd5dc, 0x3c6c67ca,
- 0xcf18fada, 0xf9f2f84d, 0x2ddfda30, 0xeb02c516, 0x8e748f3c, 0x4a2f4be7,
- 0x72b7eedc, 0xe2ff3fba, 0x77fa2088, 0xe1c0ffcb, 0x2086ade5, 0xdf1edd1e,
- 0xf6c25db5, 0x4beec0cb, 0xb3d84433, 0x03cd77bb, 0x545767f2, 0x680cb6df,
- 0xcf08e57f, 0x5b6a8077, 0x227b1d94, 0x1db7d5c3, 0x5fb6cffb, 0x61c0b8b5,
- 0x532adf0d, 0x9e1adf11, 0x75e67f35, 0x92b287a0, 0xea7dbc1e, 0xebf6495f,
- 0xca8fbf65, 0x1f670ccf, 0x6c74871c, 0x5f91544f, 0xb0f6dd7e, 0xfbf70034,
- 0xe8ebe285, 0x25b58e97, 0x9fb7c82a, 0xb9d137fa, 0x1d7f65e6, 0x6b7eda95,
- 0x5f9bb171, 0x3ef7a768, 0xcaf11b6d, 0x35ef7838, 0xd790a25b, 0x35f731c9,
- 0xeee3bf3a, 0xf0d3a3f5, 0x8faeb6b9, 0xabfbe3ee, 0x23a3fbcd, 0x5d703a77,
- 0x7bf58fed, 0x6bee0c65, 0xf682a242, 0xdf910ad9, 0x971f6171, 0x89ad170f,
- 0xfd80ce4f, 0x8e7fb8bd, 0x5c9c8193, 0x1e773ed6, 0xaafe5f3e, 0x5cfb4141,
- 0x81cab57d, 0xcb3f8df1, 0x4b050e9d, 0xf3842f78, 0xca128391, 0x6c95b1a3,
- 0x1b1fb60e, 0xfa0b9992, 0xd3833319, 0x72cb98c9, 0x3e780f10, 0xb714e786,
- 0x714f1eb8, 0xc3f5f80b, 0xbf658dfc, 0x0d0ef1e2, 0x35df9aef, 0x04dbac4e,
- 0x2e7447ec, 0xf197979e, 0x7fee1fe7, 0x77f6167e, 0xc14990e9, 0xc87a7f79,
- 0x06affd44, 0xe308c97f, 0xfdc23c5d, 0xdce38410, 0xdfdcc7c8, 0xfdcadd58,
- 0x26f5da8d, 0x37b1398f, 0xb447963d, 0x9e0ebf43, 0x55dc70b9, 0x3a34de82,
- 0xebe1ed5d, 0x0d7a0d5b, 0xb74d1bd7, 0x1b75ac49, 0xe8ebe9e2, 0xedd29bf7,
- 0x135e90df, 0xe87cb758, 0xe8bed7a6, 0xf913e044, 0xa355e91d, 0xf8fbd587,
- 0x6b727a39, 0x3ba444f1, 0x79343e8d, 0x0ac49812, 0x9bd66f50, 0xdde60159,
- 0x2af18c04, 0x9b2a81ca, 0x7f7284cb, 0x05674a4e, 0x1e4965a2, 0xb952a797,
- 0xfd4463d1, 0x79216f53, 0x526f2d11, 0xdffcb8f2, 0xed074483, 0x2a14f28b,
- 0xfc8eac4d, 0x8584ad07, 0x5cfd440c, 0x9ffc9095, 0x5372682e, 0x65b383de,
- 0xb8d57f98, 0x54727be4, 0xede506c6, 0xe488f0e6, 0x97a82691, 0x5d9a1feb,
- 0x9e457001, 0x445e6067, 0xa70e97bf, 0xc0f5c40d, 0x8c1e5773, 0x97c53dbb,
- 0xb33ae583, 0x67f7e48d, 0x9b61ae86, 0xcfed3ddc, 0xff7f6abc, 0xb81eaed7,
- 0xd4b2c4d3, 0xcd198422, 0xcaef2b5b, 0xe3e60cf3, 0x612f9fe8, 0xe2f291ac,
- 0x5dfbff02, 0xe7e043b4, 0xdefec2b5, 0x8969e82a, 0xfdc216d5, 0xcba64d64,
- 0xa80576dd, 0xca26a67e, 0x04b30748, 0x872adc1d, 0x42fdf1da, 0xb05ca0d6,
- 0xffb3e992, 0x3a377eab, 0x05d995a7, 0x87a03fad, 0x3eb04ccf, 0x900367a0,
- 0x196026d7, 0x06b12003, 0x95e197e4, 0xd85ffdff, 0x75807d6f, 0x6b9e11c6,
- 0x067b9414, 0x057e33e6, 0x63826d65, 0x3c33c618, 0x3643d92f, 0x3f0dc7d8,
- 0x5fba204f, 0x5217ec25, 0xa65f98c6, 0x74b0f5f0, 0x8f7fde7e, 0xfd0fb7a0,
- 0x5817372c, 0xf47613fb, 0xb1e61953, 0x1b37ce2a, 0x78c6bdf1, 0x0b836b2a,
- 0x81deb4f9, 0xbf27c576, 0x09145490, 0xc8dd846b, 0x7e0aa50e, 0xa0134297,
- 0x785dc3be, 0x8d4bf510, 0x6ecb97a0, 0x606f7e46, 0xfaf2858b, 0x5963f5d8,
- 0x995c03f7, 0xfe8a8b7d, 0xb767e5e4, 0x7d832ee7, 0x0ed8c0b2, 0xe854e758,
- 0x6aa60cb3, 0x73a25802, 0x03f520de, 0x3c0701f5, 0x387ee6df, 0xf319d38b,
- 0xfdb47ae2, 0x6bdef0d1, 0xb468603f, 0x66568d2f, 0x90b1ff42, 0xff9057ed,
- 0x8c997db4, 0xfff03dce, 0x9c791786, 0x75818363, 0xf9af18c3, 0x8d780ad0,
- 0x4f6a5f21, 0x267641be, 0x27405bb0, 0x19dff657, 0x1d95ff5b, 0xffd76330,
- 0x98d83d6c, 0x315ff427, 0x037b262b, 0xadfd0697, 0x4b266d10, 0xd7192e35,
- 0x91556a93, 0x9e3c361e, 0x1d867a43, 0xa0f44dd9, 0xfbfb63b5, 0x736c9d11,
- 0x55ff844b, 0xcc4cb06d, 0x4feb69d3, 0xda338b79, 0x5c74a992, 0x97e7a74b,
- 0x94ab7c9e, 0x3fbe1bcb, 0x369a7f33, 0x7e83f289, 0x6d4a883a, 0xbd041b1e,
- 0xe2be7869, 0xc93e7815, 0xbb06d5f5, 0x397dfc99, 0x79489850, 0x0b121d8c,
- 0xe4f73c02, 0x57e2131c, 0x6d74e78a, 0x57323749, 0xc459bc0c, 0xe2b9c47e,
- 0xded22b99, 0x68c2780f, 0xf517cfd7, 0x51c90509, 0xe6df7cf5, 0xb7cfe589,
- 0xf3819cad, 0x75fdabb6, 0x4c776ce3, 0x92ba20e9, 0x5f38cb2e, 0xeb0304cb,
- 0x352be787, 0x3b987dfa, 0xc69b0f57, 0xd5f24e7f, 0xbf7a3e34, 0x4dfd0999,
- 0xfcff478b, 0x17a13cb5, 0xe461590a, 0x9fc2f63e, 0x0d7c4acd, 0x78ef79da,
- 0x9875e780, 0xedc5d058, 0xafc7b435, 0xb7442c78, 0xde04e3db, 0x21e9a50c,
- 0xa6589f68, 0x47925fc7, 0x957eaf8f, 0x7aa4fc7a, 0xab4878f5, 0x67d5d6ce,
- 0xeaeb06f8, 0xd12cac07, 0xc6eb03c1, 0xb4dfdaea, 0x760e9269, 0xdae9a607,
- 0xd6cd34e7, 0x0b2d79c1, 0xed07ed75, 0x2faba25b, 0xd5d6ae0c, 0x41b2390f,
- 0xfd6d0f07, 0xe1fb5d17, 0xf5755b6d, 0xba1da1c5, 0x0f1d11fa, 0xe191e0e9,
- 0x47ed7547, 0x57507bbf, 0x69f3a63f, 0x8bb8fd5d, 0x9be0e9cf, 0xb5d65ebb,
- 0xa8ed709f, 0xdec89e0e, 0xb72fb5d2, 0x4f074efe, 0xd743fe56, 0x0ff496fe,
- 0x5d53f574, 0xa7eaeb1f, 0xc1d55c17, 0x097d9877, 0xea97c8f9, 0xcdef74df,
- 0x8e1fae62, 0x9f9e3a07, 0x00435462, 0xfc85f3db, 0x8c977410, 0xdaed13fa,
- 0x7485965c, 0x1f1a593a, 0x336bba22, 0x4457e8a8, 0x63f927eb, 0x65e307af,
- 0x8a8325ec, 0xb044ac71, 0xf188e4eb, 0x70563c92, 0x7ee07b00, 0x4e0e8a95,
- 0xdaeba6f5, 0x74bb55a7, 0x02be19f5, 0x9580fd5d, 0x581e0eaa, 0x7f6ba657,
- 0x0e8f26d3, 0x752a0776, 0xbc9a73ed, 0xa5af383a, 0xd07ed75a, 0xbeae9f3e,
- 0x5752b830, 0x9d48e43f, 0xbada1e0e, 0x787ed749, 0x5f57405b, 0xd5d26a1c,
- 0xd168e88f, 0xfbc323c1, 0xbf47ed74, 0x8fd5d41b, 0xaba23ce9, 0x55b1771f,
- 0xd5dcdf07, 0xe13f6ba6, 0x4f07485a, 0xed752764, 0x7467adcb, 0x3de564f0,
- 0xd25bfb5d, 0xa7eaeacf, 0xeae92eba, 0x7a647b35, 0xe7fae7c1, 0xa9993ec2,
- 0xfdee97fe, 0x430f24c0, 0x673c08fa, 0xa05deb50, 0xb9b3f2ff, 0x2d13073e,
- 0xc67b424e, 0xc945f94b, 0x7207a098, 0x2060312b, 0x5b9542ba, 0x149ef143,
- 0x52a453d2, 0x0347985c, 0xde81de7a, 0xf68ddb93, 0x9d8f426d, 0x88d5f995,
- 0x7d676e6f, 0x30387d1f, 0x944db65d, 0x0de563aa, 0xc79f3f7e, 0xfbe50e39,
- 0xa2a7e436, 0x14ecf11f, 0xb157b3b4, 0xe79c36c0, 0xb128a964, 0x71a8e313,
- 0x568538fa, 0x645eb54e, 0x77dd8472, 0xb325ae32, 0xfcfe06e4, 0x2665eb54,
- 0x57e8888f, 0xb00c2fc4, 0xfd110dfe, 0x807e083f, 0x8b7f3e0c, 0x6c0af81f,
- 0x0afc87a4, 0xe9fdbbc1, 0xbbf1ef04, 0x2fe7dca8, 0xbf51f2a0, 0xfdfbf54a,
- 0xe13f0465, 0xf41c10f7, 0xd0795257, 0x87e7a5ef, 0x3f04d5fc, 0x96317e09,
- 0xc64fc047, 0x77f069f2, 0xf019feb1, 0x85fe117f, 0xab65403f, 0x3f9e89bf,
- 0xf8216fe7, 0x823eff05, 0x520fe97f, 0x423fe6d9, 0x56fecbe5, 0xdfc57faa,
- 0xfe6bf046, 0x7f21c110, 0xfd47c107, 0xfb8f8261, 0x84f825df, 0x0eca93bf,
- 0xdf2a45ff, 0xfd5177f4, 0x8235ff29, 0x6f53f67b, 0xf3e346ff, 0x65571123,
- 0x215c4ec2, 0x70a587e8, 0x273970fb, 0xd042b605, 0xa81269ad, 0xfa3fb457,
- 0x3cc41fe7, 0x574891d6, 0xa7574405, 0x1efd8dbe, 0x25697fed, 0x9bf719d0,
- 0x3c781bd7, 0x22efd346, 0xefd3405f, 0x7f70f735, 0xbbd81175, 0x43ffff18,
- 0xaf3fb71c, 0xd00a99d4, 0xc431ab8e, 0x5d2f68ab, 0xd933fba9, 0xafcf0c47,
- 0x78ee4581, 0x476072c5, 0x0356df84, 0xfde11bef, 0x18b45999, 0x4c3ac356,
- 0x332a2e74, 0x357c048f, 0x37efa076, 0x0f561fa8, 0x7fc80634, 0xd1f305b6,
- 0xa07dbb6f, 0x7ef48c2f, 0x09d96ea5, 0xd2a28fc2, 0x4b4ce0b9, 0xc63e7528,
- 0x144a4e49, 0x1f0bebdf, 0x785e44eb, 0x5daff59f, 0xbc3b44ca, 0x0f92eff2,
- 0xc9b4e7f7, 0x83718d5e, 0x1fb9f20f, 0x51be41fa, 0xe81e5e57, 0xfcf3873b,
- 0x76eebd8b, 0x2ff0a023, 0xe4ff59df, 0xbf1eeedd, 0x3d7456f9, 0x62ae5ec1,
- 0x29e5132e, 0x6e1bcf32, 0xe636eae8, 0x0b3e7823, 0xa67b7950, 0xd75c63ef,
- 0xd8241602, 0x1592d637, 0xf3d15d6b, 0x03908bfa, 0xea37c97f, 0xbe59feca,
- 0xf2f3e4ff, 0x8f4ebcd0, 0xd71f25b9, 0x616bcda5, 0x3fe68b96, 0x813d758b,
- 0xabcbfbf3, 0xe4305f9f, 0xff8fa6f4, 0x61b0ba01, 0x31da0598, 0xc7a8df3c,
- 0xafa81cc4, 0xf940cfbf, 0xd45d1ad9, 0xdf104060, 0xbca06cdb, 0x013a1efd,
- 0x2bbf40fa, 0xf1ee8ba5, 0x0f249d01, 0x23193a42, 0x4f60cc05, 0xf306369e,
- 0xbc5e740d, 0x84718ccc, 0x1f402915, 0xc1d37dd9, 0x409f715a, 0x95f40e7b,
- 0xfa7dfd89, 0x8805d1ab, 0x8daf75af, 0xeabe2171, 0xe80fb08d, 0xa929be27,
- 0x8b851f3c, 0x50dc697e, 0x5932578a, 0x34ce3155, 0xde5b12d3, 0xe9c41f8e,
- 0xa9ba74e7, 0xe9fd4832, 0x074a55cf, 0x1d2b7df1, 0xc373f7c4, 0x48d70ffa,
- 0x47d3ef30, 0x947dd12f, 0xf4dff35e, 0xc46e6166, 0x9db5d7bc, 0x2189e29d,
- 0xfe8be7bf, 0xcc91ba34, 0x5b01df76, 0xe9babce4, 0xfbae1c78, 0xc740492f,
- 0x17c74439, 0x9670fcf0, 0x1f3895c5, 0x09404eca, 0x1fbee9da, 0x2dffe42b,
- 0x4b952a61, 0x15ca9799, 0xb748edb0, 0x332ec0de, 0x6b357be2, 0xcb6be7a5,
- 0x1d2274ee, 0xc8fa372f, 0x99835e2f, 0xcb9e78b7, 0x01d22aba, 0x6d35b76f,
- 0xd01d2379, 0xd765a737, 0xcecf8c64, 0x037e2e0e, 0x8643aacb, 0x0a87980b,
- 0xe70b317c, 0x6ba869d5, 0x2fe30fec, 0xe362667c, 0x4b3e7800, 0xdec1fbe2,
- 0xc9a1fbe2, 0x0375e88d, 0x941bcc1f, 0xd0f2eb8a, 0xa54724ba, 0xb66a0f8e,
- 0xa5218f32, 0x9bbe1f27, 0xfaeeca2f, 0x5f9400d3, 0x07c51772, 0x4966bdd6,
- 0xcd5e7dc6, 0xf0603db8, 0xcd0ff168, 0xe744600e, 0x1578b177, 0xe8247ddb,
- 0x8c81a3fa, 0x0323fae8, 0x3d258438, 0xf2cb29f6, 0xf4e497a5, 0xc675ebe8,
- 0x9e218667, 0xe2d79f40, 0xd07f577c, 0x8dd8adba, 0x85983f72, 0x69e989f6,
- 0xd6ef5a8b, 0x55f615e9, 0xeb5c4f42, 0x3b8f1341, 0x50cbcf45, 0xd0bfe276,
- 0x5998b11e, 0x8039cf00, 0xe428d9af, 0xe266fee7, 0x2d447aab, 0x7926c7c6,
- 0x557cfc5d, 0x3169ffdf, 0xb92f8edf, 0xf5801c3f, 0xf7a49c60, 0x594f5c38,
- 0x21c67be2, 0x3464e1b9, 0x9c41cece, 0x98f1b57f, 0xed1333ad, 0x7de3fbf7,
- 0xd5fdc03f, 0x3f9a3de2, 0x30fee1d9, 0x8d99ee97, 0xf74354bd, 0xe858c637,
- 0x22addf7e, 0x196b760e, 0xaadd838f, 0x47c6bdc5, 0xe2a2bdc5, 0xec7c6c2f,
- 0x97269838, 0xefc95319, 0xd07f642d, 0x17f14fd6, 0xd2f60e4d, 0x3090b0ab,
- 0x145da5c5, 0xcb8ee8af, 0x1e799b14, 0xad306b8d, 0xe4e42cc7, 0x4f972f4e,
- 0xd569fbda, 0xfce8c2e0, 0xd5cb2b08, 0x0e8a11f9, 0xae97581e, 0x26d37f6b,
- 0x1ddeae97, 0xe7d5d028, 0x383aa934, 0xd74ca5af, 0x8f3ed07e, 0x560c2e0e,
- 0x390fdaea, 0x43c1d5e2, 0xed75ab5b, 0x74f9b787, 0x95a1c5f5, 0x1d11faba,
- 0x64783a75, 0xfdae9378, 0xba0377e8, 0x4d9d31fa, 0x1771faba, 0xcdf0745b,
- 0xed74fb5d, 0xea0b5c27, 0xa7b227ea, 0xd6e5f574, 0x64f07567, 0xf6ba57e5,
- 0x74fd0b8f, 0xeebb7a4b, 0x49d754f9, 0x0bd37bdd, 0xc7e0e8ce, 0x0f919f71,
- 0x0f899816, 0xe9efaa66, 0x10f267de, 0xe39b938a, 0x1dfdb3f8, 0x3ca3146f,
- 0x170c6fdc, 0x6e3e9f23, 0xf96374ec, 0xb5b5c184, 0xce49d01f, 0xd61489f8,
- 0xbc58abce, 0x3341cb15, 0x5d5318b6, 0x0f731fb0, 0x393d456c, 0xe8dda6a4,
- 0xd2e87804, 0x889d5bb3, 0x290635f7, 0xd1bdf10d, 0x88e58f5d, 0x74a513cd,
- 0xb0d91fa8, 0xe8e51eb8, 0x8b33e6e8, 0x007496d1, 0xfe3187cf, 0x3e887b25,
- 0x69186637, 0xc6471bde, 0xcedcde53, 0x9d1936b1, 0x9c3b9d96, 0xdc0f180d,
- 0x09a4a3b9, 0xbf606dcb, 0x358ccd07, 0xe58efd81, 0x83dfb00e, 0x3c6c8be0,
- 0xe424e7f3, 0x53a6e547, 0xbf2e78e9, 0xaa47d27d, 0x4a15c551, 0xbf438f73,
- 0x22f1a9cd, 0x3b9a515f, 0x4efb7411, 0xdf8049e4, 0x1730923f, 0xe1a370f3,
- 0xad788717, 0x72f7c805, 0xbaed1b8b, 0xac06fd5e, 0xfe017efa, 0x927afd66,
- 0x1e785fb1, 0xad216f33, 0xf7e1eb80, 0xde5a8c0b, 0x715be53a, 0xb04a1c53,
- 0x9e41123f, 0xf0e98f35, 0xcabc00ad, 0xee819d4a, 0x26fb8b09, 0xf8a6aa18,
- 0x26aff5ee, 0x2e9c03c4, 0xe451dbde, 0xfe802bcb, 0x9ca0606c, 0xf497a08b,
- 0xd04700a5, 0xefc05ec7, 0xf99edcb9, 0x0630ee98, 0xa60b9064, 0x1555789f,
- 0x516c79c6, 0x7b97393c, 0x223b7acd, 0xdc8de44f, 0xf7146057, 0x68a8e65f,
- 0xc057dcff, 0xfe23dcf5, 0xe7cff38b, 0xf35dff62, 0x329e03cf, 0x0f988696,
- 0xf54d99e4, 0x611a98aa, 0xb17567aa, 0xf19bc8fc, 0x6fbc0612, 0xee92763a,
- 0x702aafaf, 0xd4325e11, 0xff775a16, 0x646fd0a5, 0x33ae4d9c, 0xda403e60,
- 0xce033ae6, 0xaaf14d2f, 0xacc78e78, 0xbcfddd4e, 0x997f4db4, 0xa7e41e7f,
- 0xb155efc9, 0x46ba699d, 0x222b218f, 0x925aaafb, 0x47cc62c8, 0xfc9d6d2b,
- 0x7aafa8fc, 0x759bc947, 0x625a3794, 0xd111e173, 0xeab6c5e3, 0x7bf63103,
- 0x66efd895, 0x9b7c7e87, 0xe4203e76, 0x718555f4, 0xf7f8213d, 0x6b0e24ee,
- 0x5c5ddcfd, 0xf9c37692, 0xce7463ee, 0x30cdc1a9, 0xf9a9e20e, 0xd715bb7a,
- 0x0b798cdf, 0xe9182fa4, 0x547e2789, 0xa1876070, 0xa2f63ef7, 0xc4fca047,
- 0xce8fa412, 0x83f03d60, 0xa2acd8bd, 0xdefb645d, 0xdeea0372, 0x89475674,
- 0x1591b637, 0x1bb0f21d, 0x4f5aafcc, 0x3d3e6987, 0x97d9329d, 0x62faf941,
- 0x1c3d351f, 0xafa66fbd, 0xc872d272, 0xd979e2ee, 0x67fe4e1b, 0xef022f9c,
- 0x557c123f, 0xe4245ac6, 0x95acb193, 0x4c2cf1ca, 0x175877e5, 0xc8a61e95,
- 0x2a624e58, 0x4bcc1595, 0x475614e5, 0xa16b2565, 0xa56b1a72, 0x530b0672,
- 0x950afe09, 0x5f90a65e, 0x36f41b35, 0x97997396, 0x8eac79ca, 0x1d229fca,
- 0x59ab3e03, 0x590bc10b, 0xc06d952b, 0xfaa5787f, 0x586f9065, 0x0df202be,
- 0xe9fcd7cb, 0x2efc8654, 0xbf47cae6, 0xe3ca80bf, 0x13ca957e, 0x3b2a32fe,
- 0xf76a1efc, 0xca92bfa6, 0x952f7e53, 0x54d5fda7, 0x6a3efd86, 0x257fb6f7,
- 0xebf8ef95, 0xff37fca8, 0xf5df2a26, 0x77fca807, 0x7995137f, 0x39764666,
- 0xcf15082b, 0x7e67fc06, 0x60b8f660, 0x3c0aaf1f, 0x5318f31e, 0xff70530b,
- 0x4df18664, 0x2231c55b, 0x48cb9b0a, 0x5c9addf7, 0x289dd947, 0x3b734f07,
- 0x27669ecd, 0x72d6d03b, 0x613e619c, 0x4a53a19b, 0x793cbd80, 0xd6b98ee4,
- 0xaf93d042, 0x150486b0, 0xadbba5e1, 0x309e07a0, 0x027eeb85, 0x960bc7f5,
- 0xce82b5cc, 0xfb7f6b1a, 0x4c39a7e3, 0xb38e63f5, 0xdfe0057a, 0x1bb1591e,
- 0x3ce130af, 0x57bede50, 0xe62e7ab0, 0xf2155feb, 0x00c37c02, 0xb7ad2de5,
- 0xb16f3105, 0x3168e5b8, 0x7531b62a, 0x37d412b6, 0x1e28ed11, 0xe8bb57d0,
- 0xc7bded7a, 0xe2129d6a, 0x64cff9a1, 0x9cccb37e, 0x9dc63150, 0x7e35fb22,
- 0x7499f1b3, 0xdb23f183, 0xdfd06e19, 0x9fcf228e, 0xfffccf50, 0xfa68f3a6,
- 0xec757d36, 0x062efa59, 0x7e438aeb, 0xe5c4983e, 0xa5d8174d, 0x0b34dfe8,
- 0x364b79b8, 0xb507a9d9, 0xcbefb37c, 0x5e307f54, 0xf081d2bd, 0x378a5c96,
- 0xe2792734, 0x637db10b, 0xcc9dc936, 0x63794604, 0x8a13d53b, 0xe3ef822b,
- 0xb2fcb90b, 0x7285fcdd, 0xefe5ca27, 0xae8f0ccb, 0x3bfefa6f, 0xde00b71d,
- 0x05468d5c, 0xe6f12df7, 0x7e512a77, 0xa3cb3704, 0x18e32124, 0x12792fd5,
- 0xaa9da6fd, 0xf61f3e39, 0x0ea200f5, 0x1b26aced, 0xfd9959d9, 0xc377c542,
- 0xcf328d78, 0x6f968aff, 0x9cb90bb3, 0xc34bda37, 0xc0b76e74, 0x4478c2ea,
- 0xd9b0f25f, 0xf3c2caef, 0x6fbc6764, 0x287e0331, 0x4a676a7c, 0xa7732823,
- 0xa313db83, 0xf6483a9f, 0x27c8b344, 0xd2314c6d, 0x256c49f7, 0x445203ce,
- 0xc87336bf, 0x36f8e785, 0xb163e0a3, 0x3207e69e, 0xf7b75f29, 0xefba5d3c,
- 0x9855d915, 0x6e1c8447, 0xee817116, 0x3ff446f1, 0xcdc44520, 0x4a90966c,
- 0x4bfa69e3, 0x3fc76f1b, 0x914ede36, 0x678da927, 0x9f5fa51f, 0xf5a61cdd,
- 0xa1fd85d9, 0xd713b78d, 0xe30f2317, 0xf5c3c76b, 0x5a378e45, 0x25bb3ebf,
- 0x4bb3eb4c, 0x1ee95edc, 0xf1ec476f, 0x4f671afa, 0x569cfe54, 0x72e42fce,
- 0x7632cc15, 0xd33ff60e, 0x09f9e9c2, 0xd9c5d313, 0x7e7a0937, 0xa69788b2,
- 0x992e5c09, 0xcfba669c, 0x7179d133, 0x6db5d217, 0x9dce91b7, 0xc827296c,
- 0x4ed3927e, 0x40fc8931, 0x9fcf8ad6, 0x02f7f030, 0x7998e6a9, 0xe1fc7b2b,
- 0x7111b9f9, 0xceb534e3, 0x134ff980, 0xe30c1d9d, 0x3314b6ec, 0x6296dfad,
- 0xfca1c60d, 0xcd809955, 0xdb8004c1, 0x0b1b7c8b, 0x954e3d61, 0xc5338bf3,
- 0x92f3007c, 0xdfa1aad2, 0x84ff7d08, 0x772663a0, 0xee22abba, 0xc45b3cd7,
- 0xaf8d49ed, 0x7237e7a3, 0x41ff5f30, 0x4f31e7f0, 0x8f0c6ba7, 0xdc3e9c93,
- 0x5987fc9f, 0xd07bc60f, 0xc0fd3e8f, 0x77820ae0, 0xf5f3a58c, 0x4ec787d3,
- 0xd6627f41, 0x8246698e, 0xe303ac0d, 0x2c76b31f, 0xccf3e234, 0xdffb461c,
- 0xf24cd675, 0xd58ed675, 0x4cbffda2, 0xc665f6c1, 0x6e30cfc0, 0x91ef7650,
- 0x8c8b8c04, 0x00373fb5, 0xcec6d3cb, 0xa07df88d, 0x1bf6155b, 0x5bbcd734,
- 0xb228ed92, 0x36c81eab, 0x44f59fa1, 0x99bf3f21, 0x9e263cc3, 0xbf25e187,
- 0xf091fc7e, 0xfbb2bc31, 0x72aed69d, 0xb4f6c63c, 0x9cb1c729, 0xdaf15214,
- 0xf0e8ab32, 0x4a72c71e, 0xcd02aeb8, 0x5b77cad9, 0x3159638e, 0xe204f7dc,
- 0x46f7f0f7, 0xc614fc95, 0x6e6fbac9, 0xd93bda3c, 0x0f27435b, 0x44d65c50,
- 0x94f6c2f7, 0x18249b79, 0x6bcb8f6f, 0x27b43d45, 0xf248db25, 0x256ea935,
- 0x3c6073ad, 0x51ee75c3, 0x45c9717c, 0xbec97724, 0x11ec137f, 0xe7eeffdc,
- 0x33f9fcf1, 0x151afe82, 0xf88935af, 0x027ca140, 0x9acbb09b, 0x151d2799,
- 0x04f76ca1, 0xc7b72e31, 0xc078e5c3, 0x6c52fdc6, 0x58ec0dbe, 0xec6992ba,
- 0x95594fd9, 0x60c779f5, 0xb2bf60de, 0x10b28768, 0xa6bc5fed, 0x0fe8308a,
- 0xc61d5dfe, 0xe6dda1f5, 0x36be38a4, 0xfa14b97f, 0x9c33a08b, 0xcf5b6cff,
- 0x67b8da7b, 0x237e7ac4, 0x1f1ef4e4, 0xef9b4fef, 0x463728db, 0x465dbcd2,
- 0xe6248f9c, 0x4630eb03, 0x1da227cc, 0xde7bafad, 0xf7e74d4c, 0xdf8c3d4d,
- 0x392e6543, 0x8b0efd62, 0x1e912ad7, 0xbf482a34, 0xf948d576, 0x2fdb76fc,
- 0x7a3f0f29, 0x790a171d, 0x7287eabc, 0x365fa188, 0xe430f54d, 0x1e2a1fcb,
- 0x0164abb2, 0x0edc29cb, 0x624fc793, 0xcaf588a6, 0xdda89329, 0xf18f6834,
- 0x096569c5, 0x74ebd22a, 0x70a0dad6, 0x2e78e03f, 0x318f2fcc, 0x2cb75e5d,
- 0x9faac7e0, 0xf0bb72ab, 0x7b4b592a, 0xf745da01, 0x9dbca72c, 0x3ad30d86,
- 0x05e9be70, 0xa193dbeb, 0xdf39fbde, 0xe3cc5677, 0xcb760372, 0x8cdfbcba,
- 0x9e470095, 0x30f4fb5f, 0xbdae83d0, 0x43365746, 0x847682a5, 0xaefae131,
- 0xecbf983c, 0x2c1bfae0, 0x4637365c, 0x5d17ba3c, 0xfb6bfc09, 0x4b9c1f63,
- 0x1c6d94f8, 0xb54bacef, 0x89f7c6de, 0x84fe8de8, 0x6d81eaf1, 0xbebd1f31,
- 0x7de20a42, 0x7b777b4a, 0x1afb8a96, 0x96d94fbd, 0xb8795dae, 0xca4675fe,
- 0x2bc68f0f, 0xb9b711d8, 0xa4d6ce91, 0xa73c3d50, 0xe8cc6f7c, 0x8a47eee9,
- 0xe3f7eb05, 0xca3fdaeb, 0xbe78bb82, 0x7a79fea9, 0x059bc94a, 0x500714a5,
- 0xebeb36f9, 0xf7ea36f3, 0x283a6315, 0x1654d3c7, 0xfdbfb90c, 0x394b4e7e,
- 0xbd6cc158, 0xbba355f7, 0xe5b17ecc, 0xce421bfc, 0xd3282667, 0xa7ce500a,
- 0xf3fec91a, 0x23531aa6, 0x8329defd, 0xf09cfeb9, 0x37e48d92, 0xf74ac0fb,
- 0x3850d4d6, 0x49c4ed01, 0x3ec9185f, 0xd1d4e37f, 0x3941a787, 0x9b4b37f9,
- 0x0ce4ddb0, 0x86ed0e78, 0xc47d74be, 0x84b7649d, 0x5f5f910b, 0xed93a166,
- 0x4c3b1fa8, 0x2da7bdf4, 0x26536c9f, 0x4cabfee1, 0x6d29dcc5, 0xdc6215dc,
- 0x5e029b5f, 0x996ea792, 0x51e7e41d, 0xf6d2bfd7, 0x2865c789, 0xf036577f,
- 0xbad57bb5, 0x9997d23a, 0xf142cc45, 0xd22af0ee, 0x19e31bc7, 0xa56ccbf2,
- 0xcf08bbf5, 0x4664ecbe, 0xeab66fe8, 0xf3c62d32, 0xce676119, 0x44d35451,
- 0x3f95552c, 0x73e7f2b7, 0x9f3d0f15, 0x73f87aab, 0x6feff71b, 0x3f610253,
- 0x2d9b77f4, 0xddfd85d9, 0xfd797aa6, 0x9fd50b35, 0x172fff02, 0x171ac158,
- 0xb7ae5050, 0xf3f2345c, 0xd13c5f2f, 0xa4ada37b, 0x2bf385c3, 0x36fdd235,
- 0x3ee893b0, 0x4bc54ef2, 0x32f791f7, 0xf822065f, 0x64d9d2e5, 0x629cbf47,
- 0x2f4b7ba4, 0xbf0c8c7b, 0x91a81403, 0x41423df9, 0x67572f47, 0x3654f9d2,
- 0xebf71322, 0x43b256bb, 0x0fa0f11a, 0xe7f757db, 0xf6e642fa, 0x2951bec3,
- 0x6161ded4, 0x074895c9, 0x3bca6587, 0x1e78e1ff, 0x650f943f, 0x735ed107,
- 0x5df9e8d6, 0xe9c49d2e, 0xf20a6541, 0x25550cc1, 0xcddfafba, 0xf88ba354,
- 0x7d87de9e, 0x2cee75a5, 0x1fa2bb7d, 0x55546bc2, 0x93a18ce2, 0x6fa5f517,
- 0x8cf83c73, 0xb3be4794, 0x9befbc54, 0xd7c70874, 0xe0b07cf8, 0xf4ae4d4f,
- 0xf52a4396, 0xa49a4f63, 0x306800ee, 0xbffc800c, 0x51cf0ccf, 0x74cb242e,
- 0xa9706adf, 0xf586521c, 0xe8867df0, 0x4fe0b077, 0xcf9e88f9, 0xe1e90ef2,
- 0xeeff0447, 0x1fb92163, 0xe8c2dbf6, 0x8b406a5c, 0x3e781dbe, 0xd1639406,
- 0x22abfc7c, 0xd48f1683, 0x9e17a1e1, 0xd9d7b17d, 0x5c40aeb3, 0xc8cbad3e,
- 0x5de425d7, 0x3d2b6dae, 0xd56455cf, 0x2d62f385, 0x07fae36f, 0x40c1921c,
- 0x352afd85, 0x7801cece, 0x71264046, 0x49859337, 0xbadd7c5e, 0x2b5c451b,
- 0xebd19d7a, 0x44b065bb, 0xf1cccbeb, 0xca6ec979, 0x326ec990, 0x18c2006d,
- 0xbdb0d78e, 0xa3716e3b, 0xd4fb3b3d, 0xe6439060, 0x182b567b, 0xe4233e0f,
- 0x892be992, 0x56fdd7d3, 0xda5357a2, 0xfbc8828c, 0x4f86972a, 0xf318333a,
- 0x7ababfbd, 0x4f8f1072, 0xe5a3fe11, 0x7f455fdc, 0xf9f53a63, 0xc62ee386,
- 0xe9c7e547, 0x5c270df3, 0x1f951feb, 0x1f951397, 0x3f574437, 0x95111959,
- 0x2a2e371f, 0x075cae3f, 0xae982f4f, 0x9d533f6b, 0x2d6f83a3, 0x7daeaefb,
- 0x5d4ee795, 0xbbca9cfd, 0x79b7f574, 0xf3c1d6ef, 0xb5d7efab, 0xd7abe05f,
- 0xe5777fd5, 0x20f5740f, 0x8bc6622f, 0xf74a3c31, 0x613dd386, 0x3016a0fa,
- 0x3d8637bc, 0x57722920, 0xf471fea4, 0x1e4c5fe1, 0x71e3f7c2, 0x3b093fcd,
- 0xc4591c78, 0x838b595f, 0x7c5ab1e2, 0x9a763436, 0xb722fd15, 0xbd434d45,
- 0xf5cb7ece, 0x74380b06, 0xdf89cb71, 0x1b76a4ab, 0xfce9b292, 0xb3b051e3,
- 0xef30f97d, 0xe927cf20, 0x1c6b001f, 0x500ddbe3, 0xd7febb42, 0x2237cccc,
- 0x9e2c1e62, 0x3cb585c7, 0xe64f3107, 0x8bf3e049, 0x61f7cfe3, 0xfd1f313c,
- 0x0f952b38, 0x4173b53a, 0xf6bf6195, 0xf2807332, 0xed834b11, 0x036f9866,
- 0xc51447c8, 0xc74e5e12, 0xbd4db838, 0x7aaa3de1, 0xb3dd3a7f, 0x050d2db1,
- 0x3aa5d04c, 0x3d1fd1e4, 0x7cdbef02, 0xe314e28c, 0x11ffec87, 0x433ce1c6,
- 0xbb3f345c, 0xf7bcf1cc, 0x74b97ff6, 0x9265e518, 0x45f5ee93, 0xb1dda7d7,
- 0x6e37f3f9, 0xd177bf50, 0x765bdef7, 0xdf6ff7a3, 0xa231b674, 0xcbf9afbe,
- 0x13ccfeb6, 0x66590741, 0xad55fdfd, 0xfae10ef4, 0x3358dd7d, 0x49272fc5,
- 0x604399be, 0xfec6cfbc, 0xe1db7bf5, 0xbe2b4fbd, 0x3bfd1db8, 0xe7c5ee78,
- 0xfaf08ed0, 0x2c95e669, 0x04399e7c, 0xb3d47fec, 0xbe662c71, 0xadd05f9c,
- 0x45d3569c, 0x99aa79fe, 0x6b4e43e2, 0xb0f3fce7, 0xf1516def, 0xcbf46682,
- 0x447baf01, 0x8f8b447c, 0x59fa2ddf, 0xe9494a21, 0x660e73a4, 0x527dd00d,
- 0xc5ec5ecd, 0x86328e0f, 0x936ca37e, 0xc5ca442f, 0xc53354f6, 0x4cc52407,
- 0x3292e779, 0x2823be8a, 0xe78fa381, 0x985b7637, 0xd4f68cfc, 0x900f1451,
- 0xce286342, 0xa885b360, 0x2fb6bf3f, 0x77dfdeaa, 0xbcd3cf5a, 0x759feefa,
- 0xc7704f3f, 0x1e6a2718, 0x47d61e38, 0xccc0738f, 0xdcb9dfb8, 0xf1be331a,
- 0x0d8990e2, 0x5f915243, 0x82dd773b, 0xd8bbfafc, 0x312b5972, 0x81183e8f,
- 0x6486879f, 0xfe605d13, 0x5c62307c, 0x848f97cc, 0xdee80281, 0x6aa0c104,
- 0x71425a06, 0xa13c7083, 0x6acd9a07, 0xa087d93a, 0xf71f70fe, 0x0a7e7e09,
- 0x51fc8d68, 0x03ef87e1, 0x51f2c63e, 0xda7642bf, 0x843fe07e, 0xa8bbf09f,
- 0xa80bfa0c, 0xa957e83c, 0x8cbf90fe, 0x1efd27e0, 0x2bf88f82, 0xefda7ca9,
- 0xf8cfe7a5, 0x85fe09ab, 0xab6547df, 0x7f3d257f, 0xf0475fce, 0x044dfe0b,
- 0x42ed12ff, 0x9a27cf19, 0xdfd97ca8, 0xf8aff542, 0x9afc11f7, 0xc865483f,
- 0x1f9e847f, 0x7c12b7f5, 0xf046dfdc, 0xe0887f09, 0x95077f0e, 0xf4c3fa6f,
- 0x5dff94fc, 0x2758afde, 0xfc672278, 0x45b49780, 0x79da1746, 0xcc968b69,
- 0x6f7800ae, 0x6df74cb5, 0x4be40b9d, 0x1e2e8007, 0xf7f26555, 0x5234aef6,
- 0x2bb347dc, 0x486cd6f7, 0xb9faa72a, 0x1592df54, 0xbed9764f, 0x77ba66a5,
- 0xedc55b6d, 0x46ccb659, 0x32c56ded, 0x72ba3fd5, 0xcd8dd92e, 0xae300538,
- 0x07818c32, 0x25bb6326, 0xfbdf9246, 0xefbae2a2, 0x6f79fd89, 0x45efcc88,
- 0x2253891d, 0x5b6b21cf, 0xbaf07493, 0x7ce50cb6, 0x25dcdd04, 0x989b61c6,
- 0xc49df91c, 0x33bdf64f, 0x79d602af, 0x0f7be497, 0xfba7c8e5, 0x3403cdcf,
- 0xcbb5a331, 0xc8e4fc8c, 0xbea7ad89, 0x4b3fe4d4, 0xdbf8893f, 0xbf84caab,
- 0x69c6eabd, 0x2c5fe8b9, 0x137be992, 0xcfe48b69, 0xbfe99fd1, 0x997ba640,
- 0xc53255b6, 0xa322d903, 0x5a46c7c0, 0x7305ff77, 0xe9b95ea9, 0x9dd1c514,
- 0x27878eab, 0xf802dda3, 0x387da3ca, 0x4fdf8494, 0xd77110ca, 0x94f1297d,
- 0x9f3d1637, 0xf8bbff2f, 0x19f80cd9, 0x5f3f1315, 0xa3cfc2c6, 0x7f75fee2,
- 0x68857df1, 0x31df693c, 0xcf7c547d, 0xc791b03b, 0xa5dba3ef, 0xe62ab888,
- 0x4ff7d174, 0x1f92656a, 0x81f059fb, 0xc59d807c, 0x7de3dd32, 0xb3ead264,
- 0x733e6007, 0x114a7c8a, 0xc855039e, 0x26c65147, 0x6ffef257, 0x893f235a,
- 0xbaf40574, 0xb76849ea, 0x99fa617d, 0x05fb287c, 0x7f18ed5c, 0x9fde8fb5,
- 0x8df313e1, 0xc5b217a5, 0x447bf63c, 0x81e614fc, 0xaadb3b71, 0xf9c785dd,
- 0x504559b8, 0x657accef, 0x77fd5e2a, 0x9832edcd, 0x2c5feca0, 0x2cf1c7af,
- 0x893f4ddf, 0x3c06a5e3, 0x38c578da, 0x53c537de, 0x69157dd6, 0xf75deeb1,
- 0x4ebf0f25, 0x12288e0e, 0xb00674f7, 0x1f072801, 0x9c527531, 0xcb86703a,
- 0xd326a641, 0x71e8b87d, 0x98fbcafa, 0x6193f028, 0xd10de7e1, 0xf6eb4def,
- 0xee54025b, 0xa2aff4f7, 0xb2c9a83c, 0x233d0ef8, 0xc4c37b7f, 0x0dcb6578,
- 0x421e63ce, 0x36840bf9, 0x7e8988be, 0x7ef2a732, 0x9b9fbc8c, 0x27827ad9,
- 0x0dc094da, 0x8b7601ce, 0x5157507e, 0x95c2c45e, 0x3de11abb, 0xca265bfb,
- 0xbe4bb355, 0x7e77245d, 0xe47f912b, 0x3aacb634, 0x62dfd116, 0x1ced1eb1,
- 0x8a35f302, 0x88f39ee4, 0x91f01af4, 0xbdadf022, 0xd1c450b7, 0x6f7ebb1f,
- 0x1445e512, 0xfb438c6f, 0x12b32f6f, 0x214cd81d, 0x7f0238a5, 0x0eff0336,
- 0xebfcf44e, 0x1e5acc8b, 0x28e26d80, 0xfc64473c, 0x51ca30be, 0x3eabf798,
- 0xd1deff07, 0x0fa677a2, 0x17fc7807, 0x383f9d32, 0x7bf3c597, 0x52367fd0,
- 0x226bcf7e, 0xb59df85e, 0x2c3f7415, 0x4ff44b1d, 0x78054fd1, 0x86a666fc,
- 0x8d9f7df0, 0xaf9bc1fc, 0xed22e7c9, 0xec152412, 0x4645dc6f, 0x5d71e5f1,
- 0xd83eeeb2, 0xf6fa8b98, 0xfa12ffb0, 0xfa9de9b5, 0xfe426976, 0xe8da473b,
- 0x1f769d1e, 0xdee5f9cf, 0x13d272c2, 0x1fff24f1, 0xe7e26553, 0x076d4ac7,
- 0x2b76ddb0, 0xa27e84bb, 0x4155817d, 0x8ceed039, 0x1b6ab927, 0xf3f64f11,
- 0xd6a3ccf6, 0x659fc04e, 0xda0a3be4, 0xbe2d032b, 0x7ebb1803, 0xbcc668b4,
- 0xc72431f4, 0x5c03be7b, 0x2f077a06, 0x733c1037, 0xbda6920f, 0xe9df48d8,
- 0x63345fda, 0xb68c804f, 0x5b979a16, 0x7cf30652, 0x35786ec0, 0x9c760dda,
- 0x63b418fb, 0xd0e01ea0, 0x9401df70, 0x7529e947, 0xcd5748ed, 0x292ba3b6,
- 0x429a5d0e, 0xabe4d572, 0x689ca10b, 0x91ac4b56, 0xc9f1adfc, 0x1afbe5b7,
- 0x3afef711, 0x7ebafffe, 0x4df3e2fb, 0xfaef9c85, 0x7e68038a, 0x9a7f747e,
- 0x60c6ff5f, 0x90a37efe, 0xe6b381e7, 0x70bf7298, 0x65279728, 0x5661ef22,
- 0xaf7d254a, 0x53a0567d, 0xa1d3fca6, 0x9bd80fdc, 0x867ca76a, 0xc2166ebd,
- 0x016079f8, 0x2ba40fd7, 0x29b29e88, 0x086cd54e, 0x3c1c812b, 0x70b90d0f,
- 0x97e09c5f, 0xd17bffe1, 0xa418d0bc, 0x7d05d8ef, 0x393df871, 0x17e747e8,
- 0xc57b4ad8, 0xd77ec9ab, 0x1f78d0e2, 0x439bbf1f, 0xa09820ae, 0x7d236af6,
- 0xbdfa261f, 0xf0f4bb9b, 0x787a6b84, 0xe77fd322, 0x87aadca5, 0xf87a2b27,
- 0x6e472153, 0x9f3fd749, 0xfdc3d2ea, 0x338c1c17, 0x1415fbf2, 0x828ed2af,
- 0xc60ef7e1, 0x200806c5, 0xfca16a47, 0x6b9d01a0, 0x3f341e48, 0xbff88338,
- 0x7c7d1aff, 0x6dd59d38, 0x9c603649, 0x59dcff5a, 0xefd68674, 0x073fd1ac,
- 0xfc60e83c, 0x7dd209ec, 0x3c9f70c5, 0x387fe614, 0xe657e79f, 0x7869de48,
- 0x5a0263e4, 0xfdf915bb, 0xdb8fbe76, 0xfe0b5f64, 0x4adb16bf, 0xa0af2853,
- 0xb5f7c2cc, 0xf77c58ab, 0xdf8525a6, 0xbcb35edb, 0xa67f0dc9, 0xfba6cc8d,
- 0xfedd6dd8, 0x2be48fb5, 0xe291be3b, 0x646b7bff, 0x8676aefa, 0x85eb4035,
- 0xc5d15c75, 0x5cba34a9, 0x6049cfc0, 0x587aba3d, 0x3d3d15cf, 0xa874443c,
- 0x31f90bad, 0xe45eb110, 0xfb4440c3, 0x72fb86f7, 0x8fc8dd71, 0x72e3cf91,
- 0x0f744d3b, 0x2fa7ac59, 0x42e4d4be, 0xd68f3899, 0x10bed2f2, 0x69796a63,
- 0x695e451b, 0x878f439b, 0x5127aa2f, 0xf08be11c, 0x0c5f789c, 0x0fbe453e,
- 0xc7be73e4, 0x87bc3b72, 0xfae7bd7c, 0x1e38a9e2, 0xc44081ca, 0x084e1bf7,
- 0xed87fc3a, 0xbb2896ca, 0x3fbfecfb, 0xaec8cf59, 0xeb0a1cac, 0x8e781dac,
- 0xdf174fdf, 0xf4213ab7, 0xe9c094be, 0xebbcafa6, 0x56bc9efa, 0x8a5bae2b,
- 0x12bbe3ca, 0x020daf85, 0x57fbda5f, 0xd3c26c94, 0x6b728e95, 0x4262785f,
- 0x1f21323e, 0xb32a7bf1, 0x4c6ecfca, 0x3a5b1955, 0xf879b9f4, 0x7759887d,
- 0x02cd2d9d, 0xd7d0f378, 0xb3d3fc38, 0xa6800c2f, 0x2dfcfd1f, 0xf67c3f0e,
- 0xf9154c8b, 0xe1e73ff2, 0xe21c23f7, 0xaf9b45dc, 0xa1fade36, 0xb758dedc,
- 0x238f1ce9, 0xbf3a5ec8, 0xc97a77ac, 0xa52cffcf, 0x07e781cb, 0x9cbb52eb,
- 0xd7206e4b, 0x40ba6dd7, 0xe9860c71, 0x5f30a351, 0x9f129188, 0x57c7e5ad,
- 0x1de3f3ea, 0xd7c4d58e, 0x50501616, 0x3d59c5de, 0x7d7e7e74, 0x73e68ba8,
- 0xf9ab531b, 0x0f2bb9f9, 0x5dd667f7, 0x5ff69886, 0x8f9150e3, 0x68df42ca,
- 0xf2f2265c, 0x768994e7, 0x7117f8ca, 0x9e8cdb9c, 0xfffbd446, 0x2a51663a,
- 0xbf2d098a, 0x3dcf4869, 0xe6df43b7, 0x0face4fe, 0x24575c0c, 0x53f178f2,
- 0xcf345dc3, 0xea0038c8, 0xe5f6be85, 0x3d53d088, 0x38a1e2fb, 0x87b27d67,
- 0xe5d28bef, 0x92fb82d8, 0x5adce5d4, 0x7bfaf7d4, 0x3e144fed, 0xcd32875a,
- 0x7e90967e, 0xda7f0ebf, 0x607968fe, 0x1e5706f5, 0x87172bd9, 0x609fe2e8,
- 0xf6bcbbe8, 0x718df4d8, 0xa7360d4a, 0x648e297b, 0x300b514a, 0xeffeb84f,
- 0xe9bccc52, 0xb74e8273, 0xbee9e238, 0x4cc3bd75, 0x1ddabdf7, 0x61da183b,
- 0xc236db56, 0x89a3854b, 0x835c9e61, 0xb7d2b59b, 0x82f2a20f, 0x790bec1b,
- 0x659f2a7d, 0x8e4d54c3, 0xc6d67e71, 0xdc94aabb, 0x772a2e30, 0xa3affff2,
- 0xf2477aaf, 0xec1f9e34, 0xb07e5330, 0x8bae6894, 0x26dc1f95, 0x5c768dec,
- 0x83ae0a57, 0xf5b4c9c7, 0xaf3c5d58, 0x9c639f11, 0xd1f2eccc, 0xada2e3ff,
- 0x87ec4dbb, 0xaae2ded6, 0x25ef2863, 0xf942eab3, 0xff73c52a, 0x4147f51d,
- 0xc6d49c84, 0x89a87e7f, 0xae1b0bdf, 0x2b35fcf0, 0x7eb317d7, 0x7f19886b,
- 0xf3543abf, 0xbf19beb7, 0xdb32f469, 0x3461f3c8, 0x336b9ebe, 0x981ed07b,
- 0x7ca74b6b, 0x8040b99d, 0xda239317, 0xbf3e677f, 0xe9ab29bf, 0x1bbf4748,
- 0xdfc5e137, 0x4c36f801, 0xf6f4f117, 0x6bdd1354, 0x3cc0db7a, 0xe74652e8,
- 0x49bd7a23, 0xb79a7193, 0x80db38ce, 0x31d8786c, 0xcbe504be, 0x13728ee1,
- 0x3b0067de, 0xca186e21, 0x46eea599, 0xbf30efbc, 0x7fbe98a6, 0xd77fc5a2,
- 0x49303d09, 0xddb039f2, 0x9a3f6367, 0xde6c4155, 0x7fdf4595, 0x88dff114,
- 0xbb44fd76, 0xaca26ed3, 0xc03efa2e, 0x45e8e515, 0x83f68b9f, 0xf1a21af2,
- 0xf912fb89, 0x72698bff, 0x8b3bf502, 0xe123b3b2, 0x949d89ed, 0xa9e9af6f,
- 0xcdf23ea6, 0xf2130db6, 0x714fe351, 0x7cc7109e, 0x6493c456, 0xf37b72f0,
- 0x3f4fd3c8, 0x37b1eced, 0xa43d0877, 0xd05093f5, 0x2209954a, 0x78a0c4ef,
- 0x2564fe88, 0x75801e90, 0xfb197d36, 0x61dcf89e, 0x716d8e5c, 0xf6c74b6f,
- 0x3a6ab915, 0x79d14bfa, 0x51eef5de, 0xf57fc8e9, 0xaafd3553, 0xaff9235a,
- 0x7bff9ddd, 0x75b42f3c, 0xb9e45898, 0xc669747c, 0xe41bb573, 0xfdc59bed,
- 0xc7476dc8, 0xbcbe3158, 0xc61256cd, 0xb66dd9f3, 0xbb721294, 0x478f3c6c,
- 0xf1b36f6b, 0xca9b3abc, 0x1b36d5e3, 0xf2d37bcf, 0x27ddda6f, 0xbb5a0f08,
- 0xfef8c3e1, 0xff7e54d9, 0x520d5e21, 0x1bd938bb, 0xb8acbcc0, 0x66f64614,
- 0xc77f959c, 0xc8c0a12f, 0xf9fc31ac, 0xea266182, 0x49665b67, 0x9b54ec98,
- 0xd87642ec, 0x4e925e96, 0x0df11272, 0xbbdbd6e3, 0x19f745f1, 0x6b7c0856,
- 0xf3b7d4fd, 0xa9bede75, 0x08c56e72, 0x8bbd13b4, 0xd9b74e90, 0xbf315896,
- 0xde97b254, 0xc3f5bfb0, 0xca7cba0c, 0x7994fe9e, 0xd815bfa2, 0x512f649f,
- 0x8b133fb0, 0xfa0cfffd, 0xbbfebcc5, 0x819815e7, 0x60e3df46, 0x9e4fbb4c,
- 0x68cf4b1e, 0x439c55a5, 0x0ff7bf44, 0xfacd95db, 0x93d82578, 0x75830d0f,
- 0x3b9e66d5, 0x709e9131, 0x5e31b27b, 0xd849177c, 0xdbc2b285, 0x3df91a37,
- 0x637bed4d, 0x27289d9a, 0x73d0f1e9, 0xc3ef8a7f, 0x31c78555, 0xc518daae,
- 0xf9f9a257, 0xba63a9ea, 0x67a8107b, 0xc6dec23d, 0x8f48ed12, 0x3895cf19,
- 0x8efc6b5f, 0x3f28ba77, 0xf77f9aaa, 0x2918a6c4, 0xf400c25f, 0xddad744b,
- 0x8a4af9df, 0x115d7f69, 0xab486afb, 0x6dbf8951, 0xa32c42a1, 0xf3bf7bf9,
- 0xf3f22154, 0xfadd69fe, 0x6d75c156, 0xf7e5ca48, 0x564e4f17, 0x5fc3d962,
- 0x71c25f77, 0xa4ddc76e, 0xcf5c9d67, 0x3fbebffe, 0xaf34e8d1, 0x66debd44,
- 0x97f7fbd0, 0x50fddc85, 0x9afd8ff0, 0xdbbcf74c, 0x22ef7c8b, 0xde8c98bd,
- 0xfb07d46a, 0xbf9366eb, 0x501e0324, 0x30dfeeef, 0xc0af2a2d, 0x08b0fef7,
- 0x326b2e7e, 0x1aa677d3, 0xbf208fc0, 0xa31f6a2e, 0xb7eda7f1, 0xf9abdb06,
- 0xbfb69a39, 0x216cd313, 0x764bb791, 0xb9653387, 0xb398e501, 0xd9f067da,
- 0xec987db1, 0xfddabe8d, 0xad3bc84c, 0xb7fb0dbd, 0x3c4afce1, 0x8c4c7bfc,
- 0x6b24aef2, 0xec7fffec, 0x810f0a30, 0xcbac2b1f, 0x82aa7471, 0xeec24afd,
- 0xe8f9146d, 0xd5a94af5, 0x94bef113, 0x149d6a54, 0x7df52f41, 0x874a87c4,
- 0x942bdb77, 0xfce5a7e7, 0x60af684b, 0xbe4d9f5e, 0x20471ddc, 0x675e20ff,
- 0x47e36a2f, 0x9cf7bb9f, 0xbe3a73b3, 0xbd9294aa, 0xbb018f28, 0x4307ec00,
- 0x489bd2d2, 0x3f7c9a3f, 0x743c034e, 0xfca167bd, 0x3f05f7db, 0xec7e0a76,
- 0xd8056e4b, 0xb7dcba51, 0x4bc71d95, 0x2527401e, 0xf5274889, 0x39dd4699,
- 0x8b16568c, 0x5fb0c675, 0xfc8f87f2, 0x90cbf646, 0x17ec31e1, 0xcf224fb4,
- 0xf12ed1cf, 0xb445c844, 0xec313c4b, 0xf0a36697, 0xe779c4df, 0xadab9369,
- 0xfa70f013, 0xcefa44e6, 0xdbb469cd, 0xfb3ec04a, 0xdc5cd9e9, 0xee865994,
- 0x3b0853ef, 0x760c1191, 0x5e7077da, 0x1abbcc55, 0x1cd6ffff, 0x883f1bc9,
- 0xffd197e7, 0xfb75f2ab, 0x40b80719, 0xfbc76cbc, 0x1f744570, 0xf9d632ae,
- 0xe9baf7da, 0x88974504, 0x601e11c3, 0x5be22217, 0x5176e2bd, 0xa30c3a71,
- 0xe6fde774, 0xfdbf6ef4, 0xdae281ba, 0x882c7d3b, 0xb5bfb9df, 0x7b571f4c,
- 0xed99e443, 0xcf88ca5c, 0x86b41676, 0x53495fd0, 0xabc9c519, 0x73f6fa3c,
- 0xe3bfa32a, 0xddbf8fac, 0xcf4535e6, 0xd6ebbe97, 0xc06fac5f, 0x9714d5ee,
- 0x8b8f15eb, 0xfad1c38a, 0xf2943f50, 0x46adbc78, 0x6f655f9f, 0x7ddf419e,
- 0x12aeac66, 0x34cce7d7, 0xda8f8c32, 0xcff3a3ab, 0x1ecf0202, 0x9e1a5a12,
- 0xd878efb5, 0x7bfc8d8a, 0x540981a4, 0xe1c1e5af, 0x3a2705f7, 0x5b65d67b,
- 0x2c53e62f, 0xd881ace2, 0xf189daeb, 0x2e57cc46, 0x83c4830a, 0x302e70fe,
- 0xa30d464e, 0xbac299ef, 0x8705e775, 0xd0356f77, 0x03e147ff, 0x3c26ed71,
- 0x9813cfe8, 0x5afb40cf, 0x807f3fa3, 0x68e0ea75, 0xecebfebb, 0xb3bbc3f9,
- 0x58ff7e63, 0x5038b52b, 0x7610f8af, 0x383a4800, 0x6ca77c5c, 0xf68a1b28,
- 0x2378ad8d, 0x4c95c3ed, 0x0acaf79e, 0xa1bb9f62, 0x0ddf8f9d, 0x327c8a9a,
- 0xa679fd12, 0xf302cefb, 0x6f9f94c8, 0x3573e328, 0xa672f3f4, 0xd7c4622b,
- 0xb1307896, 0xbcfff04a, 0x1fa0f78a, 0x8c00b167, 0xdf1063df, 0xbdc4969f,
- 0x26062da4, 0xd514cc23, 0xb5e4f3ca, 0xe9043cef, 0x8d7d0f3b, 0x8b077da3,
- 0xda7bf805, 0x37dfd138, 0x74fbd1ba, 0x7e894d1f, 0x3ae282bf, 0xe17df8da,
- 0x17efafbd, 0x9dfcb1fd, 0x953e3c91, 0xc35a7449, 0xeba71fb4, 0x2b74ddc5,
- 0x53b83c93, 0x0f0f4eab, 0x773e7e45, 0xf74a824f, 0x0475b56f, 0x8eb44ba6,
- 0xf75fd96f, 0x595dd23c, 0x5881defc, 0xdbefe897, 0x117e8bae, 0x9301acf2,
- 0x1a8e816f, 0xcf91ef81, 0x2e93296c, 0xa10e74c9, 0xbf8bcfbf, 0x35fd1173,
- 0xf9493d1c, 0xbdc47b3b, 0xa75c6d70, 0x8a0433ea, 0x3c107ef0, 0xd08f118f,
- 0xdf8ca5ca, 0xf5e6d28f, 0x3504017f, 0x7fe05f6a, 0x00007fe0
-};
-
-static const u32 csem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0xe733ff00, 0x51f86062, 0x39fbc10f, 0x716e1819,
- 0x0143f822, 0xd9433117, 0x1017fa40, 0x606463bf, 0xbc48cf78, 0x040e357e,
- 0x033b2f7b, 0x3e200ac3, 0xfef03ec0, 0xc95c481a, 0x4ebb3f4d, 0x622ed1d0,
- 0x067e2ef0, 0x0c023d86, 0x1082590c, 0x54417ffe, 0x08fcddf9, 0x651898b6,
- 0xf5012976, 0x93320003, 0x038009d3, 0x00000380
-};
-
-static const u32 csem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7dd5ff00, 0xc5547c0b, 0xbddcf8d5, 0xeecddd8f,
- 0x21079b26, 0x086e3c21, 0x4bc60a22, 0x9bade102, 0x88b46204, 0x7d608a89,
- 0x8420182d, 0x96d22247, 0xedf7ed7e, 0x5ab11062, 0x68db151b, 0x34105db1,
- 0x060b28da, 0x2df0980c, 0xaa5694a0, 0xd1f58df1, 0x90cbc8a0, 0xf87e8784,
- 0xce7feb69, 0x7bbbb999, 0x7c486eef, 0xfefdfbf4, 0x730ecfe9, 0x3399dee7,
- 0x9ce735e7, 0xc92b3339, 0x210cb102, 0xbbf81be4, 0x22ad909c, 0xa46c6421,
- 0xe5a22aec, 0x79fc4218, 0x8126c08e, 0xafaed090, 0x4234908e, 0x54cd364e,
- 0xec84d9ad, 0x2e8473ce, 0x0327eda7, 0x6d2b0185, 0x76f6de2f, 0x4beb44a2,
- 0xb41289b6, 0xf1d9765b, 0x4275cefb, 0xd6d5ea00, 0xd12607b6, 0x9136f77a,
- 0x935da06c, 0xd242d390, 0x23623909, 0x61754fec, 0x559dbe7d, 0x7ddfac97,
- 0xd9578c2b, 0xfa76256c, 0xd12691fd, 0x9b65f503, 0xe3a10084, 0x8f71d92d,
- 0xb7f68032, 0xed042020, 0x7a6fad2a, 0x845d5150, 0xfdebb5dc, 0x212776c4,
- 0xa2367c27, 0xca8f382a, 0xaa4228e0, 0x064a5b02, 0x1aabefd0, 0xfb42cd05,
- 0xaa775aaf, 0x6aabe013, 0x69102f92, 0x1c1a8b7f, 0xc6c11d44, 0x78c086fe,
- 0xbc703b7b, 0x1830f26d, 0x3bebf2af, 0x3cc22215, 0xb77c0f65, 0xf301c284,
- 0xe13dc7d6, 0x74f1c7ab, 0x9a792e7c, 0x5bdf478e, 0xc1a09cfa, 0x885a9714,
- 0xdce8e017, 0x84fd9f61, 0x52b7e613, 0x9e8aee19, 0x30ed9cc7, 0x7ac0aa8f,
- 0xf009c4a5, 0x8fe657ad, 0xa8b7f48a, 0xf846f7e1, 0x7bfa73ea, 0xe5cddaa3,
- 0xe9451f09, 0x8abd48f0, 0xf6904f10, 0x5280a44b, 0xf9e4497e, 0xd2324207,
- 0x4883517b, 0x7fa45b54, 0xfa42794a, 0x9b7fffd1, 0xc1e293fe, 0x6c0aeadf,
- 0x6dd08eca, 0x16681b99, 0x3769dba1, 0x5dd4a3a7, 0x5ebfdd10, 0xa0f4003e,
- 0xdcf9d4f0, 0xcbe43e58, 0x4fad72c0, 0xd6fdbc45, 0x7acb0237, 0x1fcf869f,
- 0x72c78df3, 0xe583cf9d, 0x58a57c1f, 0xf8657c06, 0x6cdf06de, 0xbcfa372c,
- 0x5f49fcf8, 0xbe0d9625, 0x8cfe7c1a, 0x8d96056f, 0x7f3e3f3e, 0xcb06b7ce,
- 0xcb0eafa0, 0x5a2f40ad, 0xf802f936, 0x035f76de, 0x20becd96, 0x6be9df3e,
- 0x8e7ef2c6, 0xa4c9c4c7, 0x4878a250, 0x253710f4, 0xee99493b, 0x3d699429,
- 0xd3d58ca5, 0x2a17f66f, 0xa5ee9eb4, 0x01978a75, 0x5685438b, 0xc3501f5a,
- 0x92ff07da, 0x7d68d914, 0x0fb59fb0, 0x6453dfbd, 0x75a1f5a7, 0x3af87dac,
- 0xad02517f, 0xf6b00f0f, 0x45431b8b, 0x38bf5a0e, 0x5b73dac8, 0xd693b148,
- 0x9eac4373, 0xec53c077, 0x36bcf5a2, 0xc0f82f56, 0xeb489c5f, 0xfbeced05,
- 0x51011d89, 0x61d2c675, 0x4edeacab, 0xf9d6ad28, 0x1348f4af, 0xef515d68,
- 0x8fc51a24, 0x948f5aff, 0x7b21f149, 0xbfe43db0, 0x149bdb09, 0xe1bfb60f,
- 0x76fac0af, 0x87ed8bd9, 0x5d584bfd, 0x17fb62f1, 0xbd629ffe, 0xbb63f659,
- 0xd58fa56d, 0x0fb63f15, 0xfb06b958, 0xb00729df, 0x07cad47d, 0x12a77db1,
- 0x5687f6c0, 0x4a99e63d, 0xf782b5eb, 0xb48fc0b7, 0xc03924ac, 0x328cc14f,
- 0x05ab4fca, 0xf7f81b32, 0x28e980bf, 0x54ceae5f, 0xfeb70e50, 0x9009e0ad,
- 0x834bfc5f, 0x7f27fcfa, 0xffdf8d95, 0x6991fb11, 0xfdef623f, 0xde3abde4,
- 0xabde4fd0, 0x0d3f7a95, 0xbdad5ef0, 0x7d6cfd6f, 0x9e11a275, 0x7ef4ab57,
- 0xae3c20b6, 0xef2bcdbe, 0x7846c9b5, 0xf7ac5b5e, 0x49e113b3, 0x4d3c1bee,
- 0xd3f11b6f, 0x3f1876f4, 0x7e9e117b, 0xcc67837d, 0x8cfc463b, 0x9f8c2779,
- 0x664fd803, 0x7a69fadf, 0xa69f88c7, 0x79f8c277, 0xa835e71b, 0xf31af36f,
- 0x633f11ae, 0xe7e30dde, 0xbb278423, 0xff6cfd6f, 0xed9f88d0, 0x73f1861f,
- 0xa0b9fb14, 0xf82af36f, 0x829f88c8, 0xe9f8c28f, 0xea2e7ec6, 0x3fdb3f5b,
- 0xfb67e232, 0x7cfc6147, 0xd25cfd89, 0xfc1579b7, 0x829f88c3, 0x63f1847f,
- 0xd19fa011, 0xf9a7837d, 0x9a7e2353, 0xc7e30d3f, 0xed8cfd81, 0x8fe33c1b,
- 0xfe33f118, 0x693f1848, 0x427dd002, 0x3e69fadf, 0xf34fc462, 0x067e3091,
- 0xfa533f61, 0x47f1af36, 0x7f19f88d, 0xe19f8c34, 0x2a42af38, 0xa10f00f7,
- 0xee7ab8fd, 0x2349e767, 0x0c9e767e, 0xec52e7e3, 0x27ed1a67, 0x267ef7a7,
- 0x33f11a76, 0x9f8c33b1, 0x95cfd8f1, 0x6767eb7d, 0x3b3f11a7, 0x29f8c33b,
- 0xdd5cfc44, 0xec4d79b7, 0x6267e232, 0xfe4fc317, 0x89c5355b, 0x85ae9db4,
- 0x993f489a, 0x08f1e1d4, 0x59ba2eb4, 0x046b745d, 0xb75112ec, 0x479b4837,
- 0x1b3bdfa4, 0x457ef393, 0xa28eeda2, 0x8b979872, 0x76d1635a, 0x04f8d247,
- 0xec939d83, 0x53d43149, 0xde18074b, 0xd43657ef, 0xf67fded0, 0x4cf686c5,
- 0x9ea19e6f, 0xf0d13955, 0x229aa0fe, 0x8ac87d43, 0x67ef0cab, 0xd435affb,
- 0xd8fcd673, 0x7505fef0, 0x17ed0d73, 0xda1957d6, 0x332c0a2f, 0xfc3647d4,
- 0x4bfde187, 0xda197782, 0x95fe6d2f, 0xe8747da1, 0x7f3d4321, 0xf78663ff,
- 0x306db6c7, 0xf83b8fb4, 0x427da18c, 0x7d4356fb, 0x269db1d2, 0x3ee9cf3b,
- 0x45d79232, 0xecc27be0, 0xed054cfe, 0xc14b90bd, 0x89c032ba, 0xd76efc76,
- 0xa530f57c, 0x76e7b2af, 0x17d28d35, 0xbae84a68, 0xf2a0385e, 0xfcfa76c2,
- 0x17bd13a7, 0x9ff3e9ba, 0xdd4bde2a, 0xca53ec71, 0x80c9020f, 0x6940b552,
- 0x6647bf6e, 0xf59458fc, 0xf443f0f5, 0xf74b6afb, 0xb75a64f0, 0xc0f58588,
- 0x2c107fbf, 0x2209a7c8, 0x12f781a9, 0x82fd04ac, 0x9e0bb27b, 0xebf147f0,
- 0x0e54419a, 0x6bbf4885, 0xd8066f64, 0xbe561b19, 0x643b07ee, 0xaf3a20f5,
- 0x213c8401, 0x0ff21ebc, 0x9a0fdfa3, 0xfda5e19f, 0xa76a1559, 0xd0af8f47,
- 0xf8e147f1, 0x73fe300d, 0x1d6f8c3d, 0xbe30de3a, 0x61a5706d, 0xc7429b7c,
- 0x607b5377, 0x7c7c7be5, 0x8489844a, 0x87bc2f3c, 0x57075be3, 0x28f7f8e2,
- 0x1e895fd4, 0x7e3c213f, 0x2ecbc833, 0x9c6c7f18, 0x689d0ff9, 0x2ae0ff9c,
- 0x3615fce3, 0x0f2b3dff, 0x7013f1f1, 0x43857bfe, 0xab83fe6c, 0xacadfcd8,
- 0x89f8f0df, 0x87effc61, 0xd3dabff9, 0x1b2673fc, 0xb1643fe7, 0x3656fe71,
- 0x8f2b1bfe, 0x389df1f3, 0x71c29bfe, 0x8b21ff36, 0xeac57c71, 0x947f80d5,
- 0x009a84ac, 0xa40c9f1d, 0xb03fa98a, 0xca071d0b, 0xa9942911, 0x30b5f909,
- 0x69f8e114, 0x2fb7e302, 0xa1bf2812, 0x73e3f1be, 0xad9aa012, 0x9c5dfa80,
- 0x163517d7, 0xb097a02a, 0xf32bfa9d, 0xcd15a838, 0x5937f222, 0x405c0d6b,
- 0x166cede1, 0x58af50fd, 0xfa00253b, 0x6e4adaaf, 0x24ef832b, 0x9fe78212,
- 0x86c9723e, 0xcb9979e8, 0x91f27579, 0x0b7928f6, 0x644551fb, 0x6f850d44,
- 0xd8c1301a, 0xea63fd48, 0x5fea1107, 0x0cfd407c, 0x13f25942, 0x11f78d99,
- 0xdea097f5, 0x6825fd4e, 0x7e256427, 0x2b7bbb47, 0xc65fc283, 0x6258ffe1,
- 0xcdf1faf2, 0xe54fc042, 0x8f9f8bf3, 0xb6f53f46, 0xf48a0e15, 0xfc731c08,
- 0x9d3a86a9, 0xd4e81f97, 0xd81ac3bd, 0x557e2020, 0x8a3957c0, 0xafb72126,
- 0x8eb8a2c9, 0x252effbc, 0xfd45267b, 0xf723c40d, 0xb2dfefa7, 0xa6e4185c,
- 0x58f4cee3, 0xe13ad8f3, 0x5ca0b2c9, 0x78cb2c93, 0x1a6dae42, 0x481ed32d,
- 0xb8fe47b9, 0xebdc6a3d, 0x99f58d4a, 0xa77ac665, 0x142d91ec, 0x8172ceae,
- 0xcefda7ac, 0xd76c6d9a, 0x525a71c7, 0x78f99d18, 0xbe0ce965, 0xc1e65059,
- 0x79d23763, 0xab7d9bb6, 0xbb7d53c3, 0xa0585d4c, 0x011fbfa7, 0xf0d3faba,
- 0xd9bb1fbd, 0xcef0cdbc, 0x329e6d96, 0x73d9cf3a, 0xb7f000c4, 0xefbffe19,
- 0xb92c7872, 0xb0f35cb4, 0xf3b12c4c, 0xa37fc331, 0xa09f3cd7, 0x4df0eb0c,
- 0x8ce7e695, 0xfa708e6f, 0x41fc0c7f, 0x1fc0a3cb, 0x9cc3fe14, 0x957a223f,
- 0xd5b547f1, 0xa1f8033b, 0x209151fb, 0xdcbf395d, 0x5e65f9c0, 0x082f919d,
- 0xc740caf1, 0xbc85b305, 0xc1f1455f, 0x0b07ce2c, 0x737c8dea, 0x99cbf10b,
- 0xe372e871, 0x6777f5da, 0xfbf3b1a8, 0x4dcdf390, 0xfc46eff7, 0xd193cec4,
- 0xa74e56e9, 0xed8c6a5b, 0xdeba7037, 0xbb3ae9c2, 0xa997c1fe, 0x563f20fa,
- 0x7bc83203, 0x7a742ff5, 0xe9e81bb6, 0xc334f4e5, 0xe7a72b79, 0xf4673fad,
- 0xcedbc334, 0x7f5ed9e9, 0x63432646, 0x77c335e1, 0xf9988adb, 0x39cf4028,
- 0xacf4f8fe, 0x3d4c2e6e, 0x497cf51c, 0xc3d4caf0, 0xa8b67251, 0x5f50dca1,
- 0xf0d1b818, 0x39fa82fe, 0x7579f686, 0xb7ed0d0b, 0x50c3b9af, 0xb9ffe39f,
- 0x56dbfde1, 0xdfb434ac, 0xa1af7352, 0x07caa6fd, 0xbd1bf50d, 0x9fde1a8f,
- 0xa1bd7b35, 0xd3d9667d, 0x4aebf686, 0xe5ea18b7, 0xf7861d9e, 0x870b5d85,
- 0xeabae3b4, 0x887f63fd, 0x4567be27, 0x3beb353e, 0xf61e2f5d, 0x88fcf8a9,
- 0xc796046f, 0x3f3e1a7c, 0xe58f1be1, 0x74dfd04a, 0x60ecb05d, 0x7343f565,
- 0xe2a3b886, 0xdac89f1e, 0xbdb3d060, 0x7dfd43e9, 0x7fa3deb3, 0x14ecf159,
- 0x902c5cbd, 0xbb075832, 0x3fad1db8, 0x49d7c53f, 0xb942ee42, 0xb930ac5c,
- 0xb335bc5d, 0x3d422488, 0x4e26bc34, 0xcf2c267c, 0x33e70141, 0x00c72eaf,
- 0x91fa82e7, 0xe036f826, 0xf9030b38, 0x1a8be786, 0xebbe1926, 0x7c222dd8,
- 0x27c6414b, 0xb65672c0, 0x85f002c7, 0xeebe0ef6, 0xb3d78012, 0x4beb02d7,
- 0xe7b43f73, 0xa9a57c3a, 0x73c02587, 0x7cc79619, 0xe23cb1b3, 0xd87962f3,
- 0xc7e58957, 0xdb2c1abe, 0xfcb02b7d, 0xf2c7e7c8, 0x2c1adf03, 0xc3abeeff,
- 0x1eafa0f2, 0x017c77cb, 0x35f2df2c, 0x2f86f960, 0xaf9b6588, 0x9f4ecb19,
- 0x5e5d4b07, 0x4865f8a2, 0xe8bf1466, 0x8fd74ffa, 0x9cbf38c7, 0xc7897e00,
- 0x7c8c1b17, 0x41ae5471, 0x43eb30be, 0xfacc1d33, 0xc3f2bbef, 0xdbb30b58,
- 0x443f2fbe, 0xa2659de8, 0xf46f4e77, 0xbd146226, 0x0cdc5ac7, 0xfbef4e1e,
- 0xf638de00, 0xb8b025fa, 0x83b28bf7, 0xff160e3c, 0x6a7a71e5, 0x2ff8b201,
- 0xbe96bb1f, 0x52f686db, 0xe3e80460, 0x77fe23d3, 0x4fb7c438, 0x6752b41f,
- 0x99f9e7aa, 0x1e23d7e9, 0x86fd0788, 0x28ba01f9, 0xdbb6c7e4, 0xed5e1813,
- 0xe84a5216, 0x05ef717a, 0x47736a4f, 0x29225d61, 0x2b407df0, 0x97e9c577,
- 0xdf80a0da, 0xeb5af0de, 0xfa1722fa, 0x57d8f23b, 0xb58e5005, 0x61343b30,
- 0x30f688af, 0x01a13d09, 0xdefac37e, 0xdc4065aa, 0xc502fbb8, 0xc071eb8d,
- 0x9f9fc469, 0xf8220bd6, 0xa8e297bb, 0xbab3d70d, 0xb0dfc40c, 0xf667862f,
- 0xe9bd7f01, 0x39f0dec9, 0xdfe03037, 0xf4decf82, 0x8b7a6f57, 0x9ae7d478,
- 0x76bbfce9, 0x2bf7925d, 0x50d4f415, 0x80f4ffe6, 0xc7bf7d6f, 0xf0254f0c,
- 0xf3bed8f1, 0xceba5771, 0x09836dc7, 0x906de71d, 0xe9ffda17, 0x80930ba6,
- 0xb41fb42e, 0x71b7bbbb, 0xba17b9fb, 0xf636cc9e, 0x2fe5cd57, 0x42925fdc,
- 0xb8e94b84, 0x4921452e, 0xbd161d74, 0x1bf4442b, 0xf83f76b4, 0x5a1cbbe3,
- 0xd8fe0aad, 0x2a435789, 0xdbf468f4, 0x227fef4f, 0x659bfc11, 0xe1f71619,
- 0xcbd47438, 0xb76cc125, 0x680fda33, 0xd74fd636, 0xf441a509, 0xeba4d493,
- 0xc075812f, 0x0c3c3eed, 0x960672f4, 0x32cb3f7a, 0x54e1f714, 0x23d33fa4,
- 0x67a8c98d, 0xf86cf84e, 0x470d0fde, 0xe044fd4f, 0xd09f2268, 0xdf1481ef,
- 0x7efcf4e4, 0x9d20728f, 0x485e2055, 0xc02fe45a, 0xffd3b37f, 0xfd0a19be,
- 0xfbd7584a, 0x7e8a0ead, 0xbcf0a5eb, 0xfd1e30d1, 0x32f7d54e, 0xe59ebbe1,
- 0x7447224d, 0xdb74a77e, 0x175bf7c2, 0x46ddd835, 0x50d930bb, 0x74ce6eaf,
- 0xf844ec1b, 0x95c21807, 0xb77c0482, 0x975db398, 0x7c035ce4, 0xe3043f74,
- 0xf605df80, 0xbb5b12de, 0x4c5155e2, 0xe72f80da, 0x5ef9d78e, 0xd53ef59d,
- 0x915fc74f, 0xf917c809, 0x1055429a, 0xa0ae8fe9, 0xb7eb42c4, 0xa6dcdaf3,
- 0xbd61d345, 0xf6616e3a, 0x4b290578, 0x92b37f04, 0x7c4015d4, 0x94b124f2,
- 0x249e5c82, 0x47e6246f, 0xa2fbe1c9, 0xbedcf082, 0x531768c6, 0x5f50d97f,
- 0xcfac6f50, 0xc3a6d727, 0xb5fcf2be, 0xa0080932, 0xafed8c2f, 0x168e4c88,
- 0xb0d59a90, 0xd995afbe, 0x4dd7363a, 0xdf0a2ca4, 0x2f1e1792, 0x1feb4398,
- 0xd31ecc8b, 0xa61745f7, 0x82abf830, 0x6d0f15eb, 0xff29a4ff, 0xe879aa06,
- 0xb0d581f7, 0x09b7f95e, 0x963526da, 0x7e16df7e, 0xfafabc33, 0xcb3fb31f,
- 0x20d258e1, 0xec710278, 0x0ebe6e80, 0x4d2e7aeb, 0x08e21b72, 0xe2a3d42a,
- 0x9f99df0c, 0x9f8188d2, 0x36bd17ee, 0x1fe31fa9, 0xa904a7f0, 0x9f7ef15b,
- 0xfa6233fe, 0xfec6934f, 0xa40ffd80, 0xfa1817fd, 0xf8507f57, 0x3fc0c587,
- 0x4bff5e2a, 0xbb76785e, 0xaa93ea9f, 0x12248fcd, 0x971e3eba, 0x4a35d2ea,
- 0xee9bc5df, 0x1f3a044e, 0xc089fc93, 0x6203c7af, 0x7ace2069, 0xe9d25735,
- 0x100a71ed, 0xd27f82c7, 0x733c4ffe, 0x5ff7fa1f, 0x18dd926c, 0x86b06a9f,
- 0x971e54ac, 0x4e9c2d36, 0x887eb172, 0x2539efd5, 0xc8d9bd42, 0x3d4f557f,
- 0x0af90e92, 0xbc785394, 0xecf68426, 0x969f8dd2, 0xba44bae0, 0xdfcc8e51,
- 0x52e7f8c1, 0x51cdff50, 0x29db6292, 0x5777e89c, 0x3754bc73, 0x4c4a77dd,
- 0xa3b57f84, 0xbf7e6c3f, 0xd7a5db92, 0x23b4ae49, 0xe32704d4, 0x87d038c8,
- 0x80483e3a, 0x0be2a5d9, 0x1c42e78f, 0x2be363b2, 0x9e144289, 0x1d3a3974,
- 0x3b8ffdbc, 0x6df59ed5, 0x68b39527, 0xaf5f47fb, 0x4f6e66d4, 0xb172b0b7,
- 0x449c4a1c, 0xf5e2e0f5, 0x8fa7e6b2, 0xc4fb3f17, 0x5c418f93, 0x76ab3df0,
- 0xd17fed01, 0x33bf2fb3, 0x6d17d691, 0xb3a6d391, 0xf4853869, 0xe9aa5d08,
- 0x22f22b7f, 0xfe7aa874, 0x84bd4565, 0x4a65ff3d, 0xb68b1e84, 0x25c856ec,
- 0x0e28f8b1, 0x9dda56ee, 0x3c12e871, 0x81f60254, 0x153fc2f8, 0x5df1fba0,
- 0x1d9fe902, 0x5feb9f07, 0xf01ff5c6, 0x74e47484, 0xf4cdd30a, 0x0ba5357e,
- 0x4e9d6be8, 0x5cb1f6e6, 0xea7f40bf, 0xe7e7e428, 0x54fc5276, 0xc1aaddfe,
- 0xbb9f2bfc, 0x71e61133, 0x7c61aa54, 0xe9ddf8fd, 0xa56e3a1e, 0x63774fec,
- 0xfe579ec9, 0x6fc827e1, 0x49ff5e0b, 0x8867c63a, 0x6b82d327, 0xe6133f8f,
- 0x4cdd6f37, 0xe27cdf9c, 0x7cabbe45, 0xfd032c5c, 0x4a44b9f7, 0x8b91c4b7,
- 0xe3b31283, 0x06a06e8e, 0x51df9d18, 0x7e60acba, 0xe6221bca, 0x07721129,
- 0x09fff901, 0x10b50b9f, 0x8db9feb0, 0xa4b369d1, 0xcad461fb, 0x8dd7e68c,
- 0x7d01b4f7, 0xf4f20c4e, 0x6a8b7d87, 0x3e39f922, 0xbf686f84, 0xfad3ebe2,
- 0x5550fa33, 0xa3bfc05b, 0x3c317ceb, 0x64dbf787, 0xf0d73d8f, 0x3b26f91d,
- 0x3e72fe32, 0x013b853e, 0xe9a3e7d6, 0x4954edf1, 0xdaf87416, 0x457f1448,
- 0xf79337c9, 0xf932f78d, 0x503de5d6, 0x67ed0a5e, 0x03f262df, 0x47fac1df,
- 0xc7f50ae1, 0x0bd7ddf6, 0x24ac0fa8, 0x37ae4f14, 0x8dae5cca, 0x509f3aed,
- 0x292125b8, 0xffa05f8a, 0xee3fc414, 0x4b5fcc57, 0x97d28bbf, 0x625e30d5,
- 0xdcba7f6c, 0xfff2e02e, 0xc8ffc826, 0x7593fc88, 0xb67bee4c, 0x17a8fc9f,
- 0x2781cb17, 0xa579031f, 0x4157e9f2, 0x9832e55e, 0x7b8d67f7, 0x9531f9df,
- 0xba82cf93, 0xa7f51a9c, 0xb72b4e59, 0xe4f1258e, 0x46a733f4, 0x7d29cae2,
- 0x9d4e571e, 0xffc7c8ed, 0xc753fa57, 0xfc2657df, 0x27b0fae9, 0x61f59a3c,
- 0x3e22a4bd, 0xfe90facd, 0x620a45bd, 0x3be74ff9, 0xfeaadf9d, 0xe80864b4,
- 0xea5f309d, 0x4be6177c, 0xe262ef9d, 0x99fc06a1, 0x18865fdb, 0x816b8510,
- 0xf032fead, 0x809a6c23, 0x87617e72, 0x6ceef305, 0xbff40463, 0x584bd446,
- 0x1ee2dd7f, 0x8ce8760b, 0xf67c2f49, 0xededf273, 0xbe5aefff, 0x307b63e0,
- 0x861ca03b, 0x74d14be0, 0xe0c2d71c, 0x02403eac, 0x781f5143, 0x7f28b2c4,
- 0xf7970e79, 0x9ad83e17, 0xec2c780f, 0x8ed4951a, 0xfa30727a, 0x6f5cd593,
- 0x49abf69c, 0xb74f4fa0, 0x78bfa0e4, 0x8ae8bf7a, 0x34f7ff97, 0x209fefa7,
- 0xaecb463e, 0xa44ea48d, 0xba45d6fc, 0x6ff06ed1, 0x714d91b4, 0xcba6aff6,
- 0x5f7e2f4c, 0x01fd007c, 0xdbdb4f1f, 0xd8e2ca4b, 0xf9f2b7b1, 0x25f3d8ce,
- 0xb7178fae, 0xbd80b7ac, 0x8b46f174, 0x41bfefc1, 0x479d7ce6, 0x67af80f2,
- 0xc6bbb1ec, 0x8bf71e00, 0x5649e41a, 0xbc529cb7, 0xf342fc71, 0xb07fa1fc,
- 0xdd93eeb7, 0xca2f4fc8, 0x0f01dbc1, 0x11b49e2f, 0xa1db2fd8, 0x078a2dd4,
- 0x830a9de7, 0x4661c773, 0x2f0a1f97, 0x50ce5d85, 0x3673c411, 0x58dbe412,
- 0xf3e4133a, 0xb0240dd3, 0x2de81b32, 0xc1237ab2, 0xca0a57bc, 0x77c327af,
- 0xa35ed35f, 0xe6c2f3e4, 0xe8127f2d, 0x045b4b7b, 0x2fb685b7, 0xe015da95,
- 0x64e6ea97, 0x68d8f411, 0x74ffcf55, 0x147d725f, 0x4b27ddff, 0x13bd9788,
- 0xf009bc5f, 0x2143a672, 0x79efcfb0, 0x68f31ba9, 0x23e4b4cf, 0xaf34f5bf,
- 0xb2e47de7, 0x43f412a9, 0x3a665f10, 0x304c6a8e, 0x7b1527d4, 0x335c0007,
- 0xb5cbedac, 0x2bb77838, 0xa1fdeecc, 0xb2b7b3e4, 0x96fbf2cf, 0xb15ebf2e,
- 0xfeef8a2c, 0xfdbf2b1e, 0xb2efc9e3, 0x987f6a95, 0x9cd6b2f7, 0x65cf80fe,
- 0xc5fb917f, 0x7d67abe3, 0xccdc2fcc, 0x9abb65f3, 0x1a5efca8, 0x544dbf25,
- 0x01c4e37e, 0xe581fa5f, 0xdf9059f7, 0x2bbdf038, 0xf2e8fa33, 0x0872db9b,
- 0xc9b737e5, 0x7933c862, 0x7d76e655, 0xf42bf28f, 0xea0d3ebb, 0xa388e6b2,
- 0x100f01af, 0xe3ccdcc7, 0xc80e30fc, 0x71b8a4b1, 0x63957d9e, 0x8e59bfdf,
- 0x98236d97, 0x6f4b1317, 0x76cbc726, 0x80163950, 0x978e4cee, 0xce3952b5,
- 0x11df958e, 0xbecbf231, 0xdf621a5f, 0xff673757, 0x5e3a66ee, 0x6cd6479e,
- 0x88bcfdf4, 0x968d8f3c, 0x70914967, 0xbcf231be, 0xbcf26fbf, 0x9533cb8d,
- 0x1c5aa1d3, 0xc62d6aba, 0x2717acfc, 0x1e7c6d1c, 0x226ff2f8, 0x5baf49fa,
- 0xeafb5d98, 0x8063a384, 0x7870a62f, 0x743a7086, 0x7fd8fcfa, 0xd347c4c9,
- 0x5f8a4e41, 0xe42dfbaa, 0x28d92f35, 0x4b87d013, 0x1fa10e9b, 0xe8ab8e6a,
- 0xbe399576, 0x7311eba2, 0x8351659c, 0xc7c79eb1, 0x11db172f, 0xa89af25e,
- 0x77c38a6d, 0xb9c13d79, 0xe71deebf, 0xbd9c0898, 0x79f47dc5, 0x3e9706f4,
- 0x970a31af, 0x1f24d197, 0x8f1489e2, 0xbffe2f28, 0x2a87188a, 0x90c0bc2b,
- 0xeb913fef, 0xc2bafcc9, 0x944b0862, 0xf80e3e43, 0xec77f551, 0xb1b27d83,
- 0x303cd507, 0xb44d27a7, 0x7a9fc17a, 0xf28ddeda, 0x0965d3ac, 0xbc0dcba7,
- 0xd407179f, 0x55bf0114, 0x586e0b37, 0x5f43aa77, 0xbd86b9e2, 0x02517e8f,
- 0x55b0b47c, 0x0f915b70, 0xe7e0294f, 0x17f5d095, 0xe5bf29f8, 0x0bbdda14,
- 0xf8450b5b, 0x010ee17e, 0xc37bd213, 0xb6e95f4f, 0x59e3d388, 0x7009df80,
- 0x8d75b376, 0x57b7a7c3, 0xfc037e4b, 0x5b9d8fc5, 0x56e0c59d, 0xde046aad,
- 0xe77861b1, 0x3eaf3888, 0xbde3abc2, 0x98977837, 0xe4daf8e8, 0x220f1833,
- 0xf27dc92d, 0x5c6dbe6b, 0xa1b49aaa, 0xa7c7a67f, 0xf3bd17ee, 0x951b8864,
- 0x8e31920a, 0xedf18ddb, 0x8fffa01f, 0xf83fd7ce, 0x6eba2117, 0x09f1b9fd,
- 0x67c9f7c4, 0xba00cd0e, 0x24517a2c, 0xce974a36, 0xe1091746, 0x0140483e,
- 0x8935543a, 0x48f78c1e, 0x5ceb82a1, 0x65a8f8d1, 0x42ecd8f8, 0xd5b5583d,
- 0xbf4e981a, 0x49fedaaf, 0x9d33d82e, 0xcbef7577, 0x19ffbf02, 0xf898e501,
- 0x1f6173db, 0xfb624aa8, 0x6efc663b, 0xd8fad854, 0x1b31c3b1, 0x606841e4,
- 0x82aa8be7, 0x946b64b3, 0x457bfc3d, 0x7be971c6, 0x7fe6d798, 0x30bcc05a,
- 0x5cfa2f80, 0xd36f9e8b, 0x4bf334f1, 0x00e59aaa, 0x6aaa539c, 0x7109d2d8,
- 0x5683aa92, 0x1baad75c, 0xb75c614e, 0xa8b3f378, 0x459bab7f, 0xe31c9f83,
- 0x2188369f, 0x4d57f82b, 0x4ece304b, 0x1eb087eb, 0xe9a71f8c, 0xb45a8fcd,
- 0x1fbb75b9, 0xa7f9e4e4, 0x529cf112, 0xf444a6db, 0x1fce1b53, 0x47f18a1f,
- 0xd79ef783, 0xf9c13d1f, 0x318a6fe3, 0x521a479e, 0xf0a54fd1, 0xb1c59415,
- 0xff7cc3d7, 0x807fe7ec, 0xd6c76978, 0xf000fecf, 0x99d7fe2e, 0xe282fc3f,
- 0xbbb2ec91, 0x3f55ff41, 0x9bc636f3, 0x728eeff4, 0xf4f9d5bd, 0xeba71853,
- 0x41aacf7c, 0x47ad9d6f, 0xaabc4307, 0xe997cb73, 0x6f2c9f60, 0xd6f6869d,
- 0xfdc56df2, 0x40fb1c49, 0x036f812f, 0x9a13887d, 0x69b7b5e9, 0xf38060ef,
- 0x6c37a524, 0x0be38609, 0x5e2c25c1, 0x42b8f2a3, 0x6c78fc63, 0xe9a11c4c,
- 0x8ca66bba, 0x54d65281, 0xc27887d2, 0x978e945b, 0x8d7e81f6, 0x89ef6fcc,
- 0x1fe1277e, 0xd5b24e94, 0x9bcfbf48, 0x31f1fde6, 0xed4a6b68, 0xea109e31,
- 0x78f4de03, 0xc78a1bef, 0xdaf9056d, 0xdf8c27fa, 0xd3a6dd00, 0xfb3e7689,
- 0x938860f9, 0x6fbb931f, 0x56d57dc5, 0x5797ee2b, 0xf28bbeb5, 0x75edb9d3,
- 0x8f0937b4, 0xf09276bb, 0xf1938b1f, 0x8dead3dc, 0xe087162e, 0x853887f8,
- 0x79cf889a, 0xb1f1823c, 0x29e8a71e, 0x7585713e, 0x6523cf28, 0x1b259471,
- 0x298857df, 0x8f8c23ee, 0xd13df3ac, 0x1b83c749, 0x3a2e30f0, 0x0e3f16de,
- 0x72cb8e14, 0x20fd017a, 0xa78e16ce, 0x8840fad1, 0x778404af, 0xd07d1c49,
- 0xe9c59eb9, 0xfe63653a, 0x2c3e8449, 0xa26456fe, 0xdecf3eb3, 0xe0dea7d6,
- 0xc9f8b6ff, 0x6c79c587, 0xbe3a9e2c, 0xe7c7af8e, 0xb7ef8559, 0x98215a5f,
- 0x802a6ff7, 0x1d34971f, 0x513f2052, 0xf9f4c75f, 0xbc3b7076, 0xf31119e3,
- 0xf707576b, 0xeb371ea2, 0xde70a58b, 0x3fbc0e21, 0x6d2ef0e3, 0xc744eb66,
- 0x49c05756, 0xb3d8e9fb, 0x6979f903, 0x4fc521e3, 0xf0d7dbfb, 0x46fcc2bc,
- 0x4eb03f26, 0xefe0a204, 0x2e776e78, 0xbb322f8b, 0xddce3cdf, 0xd3a79e56,
- 0xea9c7f12, 0x718653c6, 0x0a83f916, 0xff3e97cb, 0xcf242778, 0x44efe82c,
- 0x5f204c9b, 0x2c5044f2, 0x593fb78d, 0xdc799569, 0x74958eba, 0x25f3c4bd,
- 0x449e762e, 0xde30514c, 0xfe35dcb1, 0x941a5260, 0x507e0a8a, 0x5fb64aed,
- 0x5a9ffb5b, 0x36bbd006, 0xc78c06f9, 0xebf099d6, 0xc217734e, 0xd4f71339,
- 0xaec031b2, 0xec937d66, 0x5fe018b1, 0xafed2aee, 0xd1573852, 0x275ce07e,
- 0xef3c3491, 0x94962622, 0xb7447cc2, 0x138f6dc5, 0x659d9307, 0x17851bc4,
- 0x9f3c6dd9, 0x57cebe42, 0x9f7d1fa1, 0x6dadb175, 0x3dba361f, 0xc495f002,
- 0xaf0bd5f7, 0xbbbce377, 0x580d051a, 0xd563aa9c, 0x05f2ce9d, 0xdae8dd60,
- 0x2e4b949a, 0x87890fc5, 0xfe0e27ae, 0xbddc685c, 0xaad1f41b, 0xa649e244,
- 0xaab14672, 0x4e70398a, 0xc84db467, 0xf53d3e01, 0x5fb48bea, 0x60488b7b,
- 0xa9cbbf8b, 0x92790be7, 0xe41cce41, 0x010bcc7e, 0x3526fe56, 0x5f39a702,
- 0xe92bc084, 0xd3bc7391, 0x39c62744, 0xd113af4e, 0xc5c9159f, 0xfccc9bbf,
- 0xf8001273, 0x88b27af9, 0x4a1a79c3, 0xc142bf78, 0x7f05da3c, 0x4420be79,
- 0xf1a21d18, 0xf46a5a95, 0x89edeb17, 0x436fb0b9, 0xc8369efc, 0xfde0ae4b,
- 0x9e332bf5, 0xe7e2a1f3, 0xcf52fb07, 0x7e6cffd3, 0x7fd07ec9, 0xa8f9de15,
- 0x36cffbd7, 0xdb32039e, 0xe42f08ef, 0x7bb9500d, 0xe7b5884c, 0x5c1e5b2b,
- 0xb1e0f90d, 0x0464f3fb, 0x91541be4, 0xa1f20d04, 0x077df6cd, 0xf1c84de8,
- 0xe0271271, 0xd97d67b1, 0x87db7e0b, 0x98f26eff, 0x0b57e2f3, 0x2e8dfbc1,
- 0xf058dfdc, 0x3f51db97, 0xf88c3359, 0xfc46abb5, 0xf198463a, 0x4bb3c468,
- 0xb28de233, 0x787ce079, 0x3c6f1a4e, 0xb3c6655f, 0x0e1da844, 0xd0404af6,
- 0xf931fe80, 0x11ebcd0f, 0xa6fcdeee, 0x8f5f1b34, 0x5fe95e38, 0xa99d2d99,
- 0x533b806c, 0x985ca10a, 0x19cb28e5, 0x83dfe012, 0xf12b02d2, 0x7e85cd2b,
- 0x8f9f0649, 0x73bec150, 0x00891c80, 0x047286af, 0xcf402827, 0x6e07c83b,
- 0x7c85a7a0, 0xd919be42, 0x2cef3d33, 0x5cd0e97f, 0xe03ad5fa, 0xae514bdf,
- 0x14a939d8, 0x06cda812, 0xb0dcd539, 0x367d076e, 0xf38242b5, 0x18ad44e6,
- 0xddcce706, 0xc7903e58, 0x451aefde, 0x182c5f30, 0xfa0e9b3a, 0x291e7aa9,
- 0x80f7fd03, 0xfc033dd2, 0xccedfbdb, 0xaec8b94f, 0xa5ff3ea0, 0x9cafdf5d,
- 0xa9cb97fa, 0xc8b5763c, 0xebc39c2a, 0xbb64d96a, 0x22cdea00, 0x4eaef79e,
- 0xc608bbae, 0x19916cef, 0xc0b6155c, 0xb7c7e005, 0x741eb8ca, 0xf3c64c56,
- 0xadbb612c, 0x7613ed85, 0x78927cb5, 0xef3e947b, 0x22f87e6c, 0x6a3c3388,
- 0x793fbf89, 0x9df2cdbd, 0xfaf0d4fc, 0x3f9314db, 0xe58dbd71, 0x94303c4f,
- 0xf96963ce, 0x330ebe69, 0xe9c49879, 0xabfcd2fc, 0x5adbfe70, 0xe74f3fa8,
- 0xfcde2251, 0x3ce84ba3, 0x312dbc27, 0xd33c4afd, 0xa3b3a4e7, 0x0efef03c,
- 0x3e0065a2, 0x02214c26, 0xf784f3c8, 0x8febee08, 0x7e8f99a9, 0x94898bd5,
- 0x4c5f29cf, 0x0b7ca16d, 0x89c3ae7a, 0x36d8fbf6, 0xc997c0c9, 0xc17bbd53,
- 0x90771ccf, 0x771dbea0, 0x9e3ed8d0, 0xa71c4404, 0xd27cf8dd, 0xc6bd6331,
- 0x1233f7c6, 0xf7f03a49, 0x8445afda, 0x689babab, 0xbb7ed177, 0xfde0062a,
- 0xe1675d02, 0xbf2d1494, 0xade34b16, 0x8c6d2bf3, 0x08551e2f, 0xce8f2fae,
- 0xc13ee277, 0x9855f99e, 0xcfc5fd27, 0x9de243bd, 0x4bd28bbb, 0xddff6c49,
- 0xa7814493, 0x604abd7c, 0x8ccbaef8, 0x4bd297de, 0xbe758f9d, 0x7339f9d6,
- 0x5e37827e, 0xcec38ade, 0xf9a29dec, 0xfc050423, 0x01025db2, 0xe5de76bc,
- 0x9b5fe435, 0x2bb93f4b, 0x6ea9e00b, 0xb676833e, 0x1e7e25ad, 0x225b06d4,
- 0xf2eefbf3, 0x8d7c84af, 0x04a1529f, 0xbf73d8fd, 0x5aafd16b, 0x88534103,
- 0xe6ead9eb, 0x79a7b9e0, 0xe201b236, 0xe65d52b0, 0xfbe02eb5, 0x53572be2,
- 0xb32b1f78, 0x951f9d20, 0xbfdf8435, 0x2f8c1084, 0x077e4c48, 0xa3eb20ce,
- 0xda357fcf, 0xb46d9b0a, 0x1b9b66df, 0x6af54ffb, 0xfdafc002, 0xc1127ff3,
- 0x673ae99e, 0xe00e3a45, 0xddfe8ffe, 0xaf66369b, 0x6cf762dd, 0x9527fe05,
- 0x9a1f2869, 0x48ad5137, 0x14a07385, 0x4fe271ef, 0xe29a5dba, 0xc28dbaa5,
- 0xe0b4e293, 0x78f110be, 0x979eb754, 0x517bf840, 0x024240f2, 0x5d05bc81,
- 0x422d0a9f, 0x7ff945c8, 0x0219cd8c, 0x92a5233f, 0x60829bce, 0x5fd63627,
- 0x3e11d49b, 0x907986c7, 0x200b2f94, 0xde609df9, 0x415a2403, 0xd59ebaff,
- 0x64aaf3f5, 0xd566fa82, 0x96a05283, 0x6a4eb3f6, 0x24fc43b7, 0xc116a3db,
- 0xa48a7356, 0x41baf9e2, 0x1d1e4c95, 0x87278f39, 0xec2a15ed, 0xde25ffa3,
- 0xef8e2f16, 0x8b757ce6, 0xe03efbdd, 0xf77f773b, 0x346b301e, 0x7b4f1b3b,
- 0x79f686d9, 0x3b706f58, 0xbbaf84ac, 0xfb653e13, 0x397424c6, 0x71e863e6,
- 0xa0deb37a, 0x08a6f072, 0x44a9f572, 0x87943cf0, 0x4f40affe, 0x1fd288c9,
- 0x682c9d7c, 0xb68bd9ae, 0x2f6a389b, 0x57a4e3f0, 0x8c73ecf0, 0xc077191e,
- 0x7ef00b5b, 0xe661fd57, 0x2a21d187, 0xa33e9c8f, 0xec173854, 0xfda1d70e,
- 0x937d265f, 0x3fa63e56, 0xcf9cb5da, 0xe5d5f8cc, 0x79ef2cda, 0x56bdb42b,
- 0x488035ec, 0x84438f30, 0x0e6a1c08, 0x2203a3e8, 0x855df7d8, 0x5c285f94,
- 0x28ee411b, 0x0d9f26bf, 0xb37c095c, 0x3b0ae5b6, 0x5e77c7c8, 0xebf4423f,
- 0x7fe3b8a8, 0x7681de88, 0x08983f96, 0xfbba5878, 0x423f5f2c, 0x5d30e748,
- 0xc7447ca9, 0x37be7443, 0x172eb9f3, 0x394070b5, 0x009b9d87, 0x104288fa,
- 0xeb256b09, 0xe8a760dc, 0xd86d75f6, 0x7cc64d9e, 0x366ee5ef, 0xdbacad5e,
- 0xe60d9ae5, 0xd455dcbb, 0x2efb7cff, 0xffa8e7d5, 0x5d2f9512, 0x7fa3752d,
- 0x214e7d56, 0x81efd481, 0x7a3a16af, 0x455f01ba, 0xf8b17ef6, 0xd472081a,
- 0xf9cbffef, 0xcf9e6cdc, 0x3e646a3d, 0xc5f78893, 0x0a17aa76, 0x64cfacee,
- 0xcade417c, 0x7e0be688, 0xf927b1de, 0x1be54f1e, 0x7918c7dc, 0x84f1c936,
- 0x96c72a16, 0xe4d63958, 0x4827bc32, 0xbea0756b, 0x59f5cb33, 0x076aaf3e,
- 0xa24dfbc3, 0x9f3067f7, 0x60f74b6a, 0x955cbbe0, 0xc0a74ea4, 0xe88b36e6,
- 0x54b69007, 0xbb123ac3, 0xdc59fbbe, 0x7a07af8a, 0xa668529c, 0xb3e74d7c,
- 0x0bbdeec9, 0xcdd6a5e4, 0x58384afc, 0xa3707604, 0x3c377bcd, 0x12d85077,
- 0x88c75ce0, 0x838b3650, 0xd4720c84, 0x4c38dc93, 0x490c1172, 0xe9f93eb8,
- 0xd08174fa, 0xf6c53c33, 0xd52f0664, 0x0c7f6016, 0xb06c202c, 0xf9f304a5,
- 0xf3b2e606, 0xd8f303f8, 0xd84f59fd, 0x91b9bad9, 0xd97a07af, 0x075b2b68,
- 0xe2259378, 0x777de6b7, 0x885401b8, 0x7bb26e0b, 0x6cfe831e, 0x479c1ea5,
- 0x02689b96, 0x292ca3e5, 0x53fec028, 0x605562ca, 0xd6c240f1, 0x7f692813,
- 0x42d5d359, 0x20b28f58, 0x07de0097, 0x9c8e263b, 0xefe5dab4, 0x8e6ac717,
- 0xb95ba3b1, 0xe853ec1c, 0xb3a7537c, 0x3c70e43c, 0xf80f8286, 0x80dd74ed,
- 0x9cfced93, 0x93f835e5, 0x7ecd9e19, 0xe60c1015, 0xddfaf125, 0x29ec910a,
- 0x2df8f7e8, 0x86c59df0, 0x68838f7e, 0x078bd041, 0xce5ceced, 0x035b416a,
- 0xdd48dff5, 0x40b7b836, 0x2607ebe7, 0xf449ab5f, 0xa729c495, 0xa517c173,
- 0xf026fe7c, 0xd3e4e75b, 0x0ce157c3, 0x7e3307ba, 0xbc8688f3, 0xcd6e9d47,
- 0x766e81b2, 0xeb447388, 0x7e829761, 0xa090a77b, 0xb9d39f81, 0x0a706050,
- 0x2a179e36, 0x5c2fe319, 0xfdfae9cf, 0xe9bcd82b, 0x8ff1f307, 0x6c567bc6,
- 0xd1e00d9a, 0x1b9f0fe1, 0x31eb9d32, 0xc8c9fb9f, 0x3263c709, 0x4cab4f31,
- 0xc852bb81, 0xda0716e9, 0x4c89d555, 0xd0fccdae, 0x79c2941f, 0x7c50cbce,
- 0xedf4097d, 0x8324d72f, 0xcb7fed1e, 0xafa044e1, 0x825d0f19, 0xd83ef47f,
- 0x1c9bfab7, 0x2f5b7f77, 0x94063233, 0x91999d83, 0xfea58199, 0xc529debc,
- 0x26a5ef8d, 0x6bb8cf7c, 0x46dbe580, 0x026a6bf1, 0xf7a4efed, 0x283c778d,
- 0xf718ddee, 0xf8604fae, 0x3c7457ae, 0x672049aa, 0xc496ba91, 0xb32779ce,
- 0x8cdc1c7b, 0xb67d6b9e, 0x7e8a4972, 0x467683cf, 0xf2b9e23f, 0x6b025046,
- 0xf909b265, 0xf465c59a, 0xe8aa5c7c, 0x1992fd18, 0x8df5bf5c, 0xff7d872e,
- 0x9c6484dc, 0xd3b5d9ef, 0x7274bc70, 0xc5387d97, 0x8b32fceb, 0x939af106,
- 0x089eff73, 0x66e6ff47, 0x3c1015b5, 0x1ab35a62, 0x16ffaefc, 0x9409b9bd,
- 0x54f5694e, 0x3e32a511, 0x74a3b900, 0x13f712b9, 0xe6e258e7, 0x604d8ddf,
- 0x76a7f57e, 0x919b8e37, 0x22bcb831, 0x103eba3f, 0x23f3a4e9, 0x8accc395,
- 0x61739131, 0x24a63f94, 0x2ea791c4, 0x7ec33499, 0xd30fae80, 0x7d75fe38,
- 0x1a43cbac, 0xefec19c8, 0xa8fd5195, 0x7f2873d3, 0x90e31d35, 0xfcb427f8,
- 0xf3b04bf9, 0xa114a713, 0xbff2a3be, 0x0465e506, 0xd076dfd3, 0xc7f151a7,
- 0x0777d6ae, 0x87debec1, 0x05c679ff, 0x90ff3bfb, 0x3fa05dba, 0x4df2fd8f,
- 0x7c11e417, 0x87164bf8, 0x1fe4d5b8, 0x9e981379, 0xcd94260f, 0xe6dd7982,
- 0x378167fb, 0x0ac92f8a, 0x90b15fb6, 0xf3c6bb2e, 0xbcf3c683, 0xf3e6824b,
- 0x77ec7ebb, 0x8e3f1489, 0xc3a708fe, 0x4af5c6c2, 0x7be30a96, 0x8f3d0217,
- 0x58efff71, 0x4367bb13, 0xe36e6787, 0xa27c0568, 0xf958b47f, 0xcc9b76be,
- 0x74cf05d6, 0x72f2a7d8, 0xdce199bc, 0xfd81cbb7, 0x44447bcd, 0x1d0e64bf,
- 0xafd5056b, 0x679616de, 0xbcc79e6b, 0x3812d50f, 0x5eef3f2f, 0x785dfd01,
- 0x9d7497ff, 0x07b8aef2, 0xf3ccb3f7, 0x603fdf34, 0xfba4b73e, 0xfd380b49,
- 0xe517882b, 0xa20f262f, 0x9b3bed85, 0xf7a77ae3, 0xfe6038e7, 0x3f7025f7,
- 0x838c80a3, 0xfbad877c, 0x2f9d2687, 0x9f83aacf, 0xf3c13ed7, 0x08f98f33,
- 0x5412b396, 0xe5ba2e76, 0xabe012f5, 0xf05bcda5, 0xab6f96be, 0x1cb4966f,
- 0x8931fc4f, 0x1f6a1de8, 0x21fe07ae, 0x3760c15e, 0x467f5d2e, 0xc32c7e61,
- 0xf9fccdc3, 0xdc5f30cd, 0x72f76527, 0x3e58bcdc, 0xcb9f7d1b, 0x7cc609d3,
- 0xf9f08eeb, 0x258f3673, 0x9f481f7c, 0x679f999f, 0x5e78b025, 0xd5f2c6c5,
- 0x6b94e803, 0xe60e8f5b, 0xdf300ae7, 0x3317e75a, 0x65202c3f, 0x14429925,
- 0x8d7e5bdd, 0xa9f4ea70, 0xe7c39ba8, 0xfbe0cfe3, 0xe710196f, 0xcc0f8de9,
- 0xdb94eef4, 0x9a7c8307, 0xc3d9dde9, 0x09adf0f9, 0x50afdd6c, 0xffa0253d,
- 0xd5b291e6, 0xe3bb28ee, 0xefb75498, 0x1b372017, 0xad46df19, 0x7b38cca7,
- 0x79f5c645, 0x0fed4b99, 0x1d210cf7, 0xbdfec026, 0xe9ef0fd5, 0x79f11ce3,
- 0xe01261b4, 0x13cb14b9, 0xd86d32be, 0xfcfb48b0, 0x4224cf47, 0x046bb53c,
- 0xa74b78c1, 0xc7ef08cb, 0xf3c22209, 0x62c3a731, 0xef5feda9, 0xd8d9ce83,
- 0x47097986, 0x9af1e6be, 0xf1a5adaf, 0xbe4ff9e6, 0x9f7e11fe, 0x6e5cadca,
- 0x36e1ff74, 0x5b5bb74e, 0xdcf3bed8, 0x0f48e575, 0x0720fdf3, 0x16497704,
- 0x1c1bcaed, 0xcdfd00ad, 0x5da799f4, 0x6bf41c71, 0xfdc89d0c, 0x98bd2f9c,
- 0x2f51534f, 0x4cc27c62, 0x9b870abf, 0x35abcde5, 0xea2d6fe8, 0xe55dcf41,
- 0xafae7a60, 0x63cf31f3, 0x7a80934e, 0x82ff0ccf, 0x0f572b8d, 0x367f3020,
- 0x8479d8bf, 0xe19ea206, 0x55e7d4f3, 0x473c3441, 0xd38fb31a, 0xce89397e,
- 0x72d85cab, 0x2ec1e63b, 0x2c27f3a5, 0x1bf183de, 0x5e1d7e1d, 0xc44a3cf3,
- 0xf106d90e, 0x068215d6, 0xdef636fa, 0x5ee18f16, 0xbb0d39a8, 0x8efd0207,
- 0x21abed48, 0x2fc47bfe, 0xf5d6ffa0, 0xb445c101, 0xfb808d6b, 0xafd23d5e,
- 0xf4ede585, 0x051ac74c, 0x58aa39ee, 0xe3a5c427, 0x6d42fa82, 0x59de9458,
- 0x1b52b818, 0x88378066, 0x1a8b1c79, 0xa7cf0dca, 0xb8fa8c38, 0x35237937,
- 0x74d2f3f1, 0x4de5d2f9, 0x870abf97, 0x52ffe2ca, 0x36565f60, 0xd107e9e8,
- 0xf67aa0cf, 0xc38b076a, 0x7d23703c, 0x67a3e965, 0x79fc710c, 0xe67d19e3,
- 0x79f1d389, 0xc503eb4f, 0xcedf4183, 0xedf51872, 0x3e8f9df7, 0xf42e5d0f,
- 0xc2e599f9, 0xfe3d7f8c, 0x1983a665, 0xd81700ff, 0x1d5a07fb, 0x9004bb81,
- 0xbfa70677, 0x76708ed5, 0x70691466, 0x7c00e59e, 0xd2dcf540, 0xfd631fcc,
- 0xb96cb126, 0xee34fd03, 0xf3f16907, 0x0ff6c26d, 0xfec463b7, 0x1e301196,
- 0xc8341311, 0x2cb3170b, 0xbce95b35, 0x1cb421c4, 0x9ac1e905, 0xeb9fe708,
- 0xe1132f8a, 0x7e5a86de, 0xc2d6ba3e, 0xfde96dce, 0x75b071ad, 0x39772f49,
- 0x683b56ca, 0x6b5f27ff, 0x78b0702b, 0x3819fa2f, 0x93ee114f, 0xd8317ea4,
- 0xcc132fb3, 0x234bcd4f, 0x0ebe817b, 0xf20f19e2, 0x85238cfd, 0xfb655f9f,
- 0x0b2ff46c, 0x796acd4a, 0xf908d55e, 0xa6077dfd, 0x5a703dc1, 0x6ccee592,
- 0xf1c27f5a, 0x5967ab3a, 0xa9bb64ce, 0x8378edff, 0xce5a47d5, 0xa7f5a50c,
- 0x3ab26f1c, 0x0551086c, 0xade3b4f3, 0x3051fe69, 0x3fdf9b8e, 0xf20919e0,
- 0x5f985920, 0x3051ed2b, 0xa3efacfe, 0x2c06a2af, 0x00cfaff8, 0xba9f82ff,
- 0x0e4fe8b2, 0x7915ef88, 0xbf1fd854, 0xfdb6821f, 0xe3a97bbe, 0xf0587455,
- 0x01280a5e, 0x3e385bff, 0x2690ba75, 0x23c848cf, 0x48cf4124, 0xe5d877d8,
- 0xdd0136f0, 0x5db40ff3, 0xf4d47206, 0xf00bdfc6, 0xac21ccfe, 0x28ca7c9f,
- 0xc9e6df70, 0x8fad0617, 0xe5dbbfde, 0xf401dc28, 0x3b4064a1, 0xe4dd5041,
- 0xd4176a66, 0xc95e3f52, 0x68c47f01, 0x7e713787, 0x6ca12d7b, 0xc0d9f237,
- 0x8e1fd310, 0x8fd0bdb2, 0x2da4572e, 0xa77c4fa5, 0x4110aee4, 0x3564a63f,
- 0x720b9c1f, 0x9cecdff8, 0x60f1e0ac, 0xf0e6dbfe, 0x3f6c20fd, 0xe9fb01dd,
- 0x9235afa0, 0x71e74fe1, 0x238f1605, 0xfe510569, 0xfd079f05, 0x37dc2a7e,
- 0xf6c1ce32, 0x44bce95b, 0x13461f58, 0x887ccb15, 0x6a00e413, 0x49df58bd,
- 0x417f0782, 0xcec87ffb, 0x035b74fc, 0x2c5dc431, 0x5f7eb64e, 0x7dd992e8,
- 0x5af0722d, 0xa709e3d0, 0x78f41b88, 0x848ae3d7, 0xfb9218f9, 0xb09fb847,
- 0xde0042cf, 0x1b80e4a7, 0x17ddd9e2, 0x1206ea49, 0xd38bafe9, 0x21f7ef5b,
- 0xe208bd45, 0xcc5ca31d, 0x90aa78be, 0xf768fe60, 0xfb002571, 0xb659294c,
- 0xfabf689a, 0xef7b072b, 0xcfa2a4d6, 0xd6c11e81, 0x8fe30204, 0x440d45db,
- 0x353f874a, 0x1f81d9e6, 0x288e0336, 0xeeac521e, 0x94bfa03b, 0x6cde1433,
- 0xfc41ee7c, 0x24e8ea4a, 0x5789df8a, 0xbfb85539, 0xf07b29e1, 0x7b9fcc2a,
- 0x24f782d6, 0x72b4566d, 0xad3e6fa8, 0xf35e21ba, 0x01307654, 0x05acf3e7,
- 0xa139b3e7, 0x1465e2fb, 0x608d5fee, 0x20e4bf7e, 0xe4052d92, 0x83bd48a8,
- 0x32704f3e, 0xc2cab87d, 0x938a68e4, 0x0243cfc9, 0xde0f3f1d, 0xd1f9442b,
- 0xbaba1bf3, 0x7e8879d9, 0xc089b7d7, 0xbae509c7, 0xc1121e3f, 0x465c9e8f,
- 0xec9cfd70, 0x3a2a0394, 0x1ce71e9f, 0x08cbff4a, 0xfb2e1f5b, 0x5fc63160,
- 0x82de0529, 0xebd80bdf, 0xf052f7e4, 0x39cb987d, 0xed214c9f, 0x53e7ac22,
- 0x442d11ce, 0x9cfcbbc7, 0x9f3d7714, 0x527dfbc6, 0x7d125220, 0x2aacf0af,
- 0x1215df01, 0xad3b7ae3, 0xc438e4be, 0xa66d8b7b, 0x235eb0e7, 0xf4091e3c,
- 0xb1b734d7, 0xaf93a47d, 0xe0c9834f, 0x3d1abce8, 0x1c4d3e6e, 0x0bda28f5,
- 0x78068aa5, 0xbcf4e2d9, 0x7e44fb0b, 0x2f9e26ea, 0x8fa4f33e, 0x388d3fe5,
- 0x72f18097, 0xe04e9fca, 0xebeb8b8b, 0xef3a76fc, 0xfeb1878b, 0xaf410f81,
- 0x5a78f85c, 0xf7f9e82a, 0x4bd1beb9, 0xbf80ef9d, 0xbf8c49dc, 0xe44697dc,
- 0xc49214b3, 0x0de446c6, 0xd9fa0ef8, 0x8a6e0729, 0xa92f7e7b, 0x0fd9d4a8,
- 0x4ed041e6, 0x36d32fbe, 0x1f4ce41b, 0xe32701e7, 0x7ab9736b, 0x10ddb2e5,
- 0xce7ff707, 0x03a98bd6, 0x5a1e61ce, 0x62488fd8, 0xd6ad567c, 0xf203375d,
- 0xc6329c62, 0xf9f9d3bb, 0xc97e68ab, 0x9d17e28c, 0xcc9d3aef, 0xa7f9d68f,
- 0x989bc778, 0x39fc5fdf, 0x126cee21, 0xfe7507b6, 0xf8cfccb9, 0x6cfdb2f0,
- 0x7f8de89d, 0xa9eedd3c, 0xf8631ea0, 0x9be33f66, 0xf81fca22, 0xf03d10fb,
- 0x966f998f, 0x5f37caf5, 0x967e0227, 0x779f16b7, 0x67d9a59f, 0x973393cc,
- 0xf3f11c13, 0x624d9f28, 0xa943b1fc, 0xe82e51fb, 0x1a2dab8b, 0x15ca03e8,
- 0x3e52d759, 0xdfa091df, 0x03935a7b, 0xd3122df5, 0xac5a5b3f, 0x38b67fa8,
- 0x678c5ebd, 0x68f3b065, 0x43b6f244, 0xc036b41e, 0xf3df46a6, 0x8d93a57c,
- 0x13439413, 0xf41d828e, 0xf1ff4617, 0x8dc1e757, 0x82b32430, 0x31cc61d1,
- 0x0d98bd65, 0x8f853be9, 0x00bd7f00, 0x577e833a, 0x73c1587d, 0x2b0f4bfe,
- 0xd85f17a8, 0xc4097af5, 0xcb7cf48d, 0x2f5f3b71, 0xef051a29, 0x9c7b3e33,
- 0x8ebd63eb, 0x27a0e7a9, 0x4ea6f74d, 0x997f4c20, 0x032d3def, 0xb48dc9fe,
- 0x9d03ef9b, 0xd61e4545, 0xb5db6b9d, 0xcc16a069, 0x0ace81f7, 0xfff6855d,
- 0x699e83cc, 0x7dce352e, 0x6e1f9ca0, 0xc1db6d20, 0x4fdf3525, 0x6de7d749,
- 0xaf93ff30, 0x2f881484, 0x919a9506, 0x9aeebeec, 0xba3fd01c, 0xc51fe1dc,
- 0x11c3f05b, 0xbf68fb86, 0x5fbef3e4, 0x08bdd893, 0xbfee0aed, 0xefb09afc,
- 0x7add7c82, 0xdde2c9d3, 0xbb9fcb79, 0x7e61f409, 0xb9f707a5, 0x9f98934a,
- 0xb2121bfc, 0x34bd00e5, 0x41c8e309, 0x2a3e2d59, 0x5223de44, 0x0f3808d9,
- 0x425fb3b5, 0xb9af8c3e, 0xc138efbc, 0xf7ba90ae, 0x26e377c3, 0xde83e5e6,
- 0x955e8e76, 0x0e98eb0a, 0x74ab8537, 0x87023393, 0xbe5ed70e, 0x39ae68ce,
- 0xe1fcc0ef, 0xcd43d03b, 0xe0d88e87, 0x820f9d7b, 0xfd18a7ad, 0xe801f8a3,
- 0xe107e11f, 0x78eba836, 0x87e707f8, 0xfc6dff2f, 0xf159fd40, 0xfe00fc3c,
- 0xe2f7e260, 0xe689ff87, 0xfdaf6a07, 0xaf6519d3, 0xa7961505, 0x3e75d7a5,
- 0xc428e458, 0x608534f7, 0x65d905be, 0xe2dfbf67, 0xf038c64d, 0x46366ef3,
- 0x064787d7, 0x76e22f83, 0xe37930a5, 0x0e8f5df7, 0x8e576809, 0x66e10aa6,
- 0xa206e3b4, 0xbe38d43e, 0x804111c8, 0x1730ac7b, 0xcbec0b37, 0xc5c82a50,
- 0x10f4eb68, 0xc756fff0, 0x1f605965, 0xe72639e6, 0x1f6d7f00, 0x5815fcb1,
- 0xa80fb6b2, 0x1aa37e7c, 0xbd749fb1, 0xab7797b7, 0xc5c43f8f, 0x0f72e1f8,
- 0x7a014f3b, 0x5d0e1a3b, 0x005903ff, 0xcb34210e, 0xf5038df2, 0xe83b4b75,
- 0xe2838073, 0x9a40b775, 0xb4283ec0, 0xc18ad278, 0x9217ebce, 0xd6aece00,
- 0xbc43072f, 0x9fcb7a68, 0xd3bc020f, 0xcd267df5, 0xb664cfb8, 0x477b75a3,
- 0x7b742bf7, 0xd088a248, 0xb76826ed, 0xb86ee7f0, 0xafd61b1f, 0x71cf0d90,
- 0xbd5a743e, 0x57e5c3c8, 0xce98f3a2, 0x690d71e7, 0xd7c8b843, 0x99337cdf,
- 0xc70667d2, 0x24fdf4c7, 0xed0b9094, 0xf14d5c84, 0xfc44b570, 0xab9c7449,
- 0x1c7c8135, 0x8cd727c5, 0xefe1d637, 0x3f48f4b2, 0x5e6fbdbd, 0xe299261f,
- 0xdcb7dff1, 0xabe763ef, 0xe763eaff, 0x150e2767, 0xa82c12fd, 0xb9d933e3,
- 0xc3c33759, 0x7afe257e, 0xc98b88f5, 0x7b4b44f1, 0xdc1b9c2e, 0x5c2bf3bd,
- 0xfcecf71f, 0x13b01dea, 0x08971c27, 0x3c4e01e4, 0xf709263e, 0xe067c73d,
- 0x6fde9d3e, 0x0e4da7f5, 0xff239ec2, 0xef82f7e8, 0x1478f0a3, 0xe586cf80,
- 0x3d0f1d8b, 0x3d9dfd0c, 0x3ce8912c, 0x3bc512f3, 0x2569e20c, 0x7df87efc,
- 0xf497b302, 0x5efc7df6, 0x5972ffe6, 0x9b6b7ef8, 0x625efdc4, 0xd5f3a28d,
- 0xe524f354, 0xf57ae845, 0x52e3d2b1, 0xe07d2c6e, 0x0f9d63ef, 0xdc6793cf,
- 0x579fa95b, 0x23f8e3ae, 0xf3c3df7b, 0xdd345700, 0x7e7d8121, 0x3c488645,
- 0xa95ee351, 0x2a3e0f52, 0x8b8f71ee, 0x76eae5e7, 0x1fa7deca, 0xf706919e,
- 0x7a988859, 0xe5b2dd55, 0xb7a85c95, 0x71cf7189, 0x457bf19b, 0xf0121dcb,
- 0x262e17ff, 0x3f8dbd1f, 0x27ca62f1, 0x09dd0297, 0x040af3b3, 0x7d332394,
- 0x7dfcecf7, 0x9ea8fb6a, 0xfd13ddf1, 0xb17874cd, 0x2ff708a3, 0x9987a37a,
- 0x79d1776f, 0x42fce9fa, 0x6a7e9e74, 0xb9f1ed8f, 0x2f92feb1, 0xbf3aeb03,
- 0x913eb756, 0xce9cf60a, 0x1952d3a7, 0xf1d84cdf, 0x46712a70, 0xdbc665e8,
- 0x66fd395f, 0x0ce66d11, 0x826dcffa, 0xe17d42e6, 0xcf906d27, 0x9c61c652,
- 0xda0956f5, 0xcfe7841f, 0x59b1d79b, 0xd7bc28e2, 0xd97bd7ba, 0xa0ca1587,
- 0x15ebcd6e, 0x7c0e17dc, 0x4aa75e6d, 0x7049d40f, 0xb48958ad, 0x6e31e99c,
- 0x9970eba7, 0x2936fce9, 0x04f479c3, 0xcc0f99a7, 0xb9f6eaf0, 0xc5394f7e,
- 0xda14b4c7, 0x216ab5df, 0x1d662fce, 0x69e978e6, 0x5e69edfd, 0x7ffc4d47,
- 0xd7d4d8e6, 0xc93dbd00, 0xe66e999b, 0x947f5d76, 0x587900c0, 0xf91ec1fa,
- 0xf48e95c2, 0x10a7392d, 0x0f1bec0f, 0xa24f93b4, 0x7d3221d6, 0x9ddbf208,
- 0x27acf66e, 0xce7a5b7e, 0x11a9bc42, 0x1f9b93be, 0xeddf0074, 0xb01cea90,
- 0x59c533af, 0xf1449b5e, 0xa2d3f535, 0x74bcf1eb, 0xc84085bb, 0xa9cb5a6c,
- 0xa84710bd, 0x9f30483e, 0x7765a8ba, 0x4be9f031, 0x51fa1b52, 0x7909675d,
- 0x6cceca30, 0x8075a96e, 0xc69cd61d, 0x4bed03ce, 0xcdbc8626, 0xbf191247,
- 0x3d3e1f36, 0xfda713c3, 0x8ebf6f00, 0x7172d278, 0xfc61765d, 0x058d64a3,
- 0xd0553fe7, 0xbb034e5e, 0x0f7646e5, 0xb8eb5763, 0xbc28d397, 0xa324b79d,
- 0x7cd6999e, 0x4a6e1dcf, 0xf33fe088, 0x1cf779f1, 0xdf40db41, 0xac35512b,
- 0xe3645497, 0x7fb8f8be, 0x1d375ea5, 0xd194afda, 0x2e2699bf, 0x751e2096,
- 0x03c84332, 0xd0a7717f, 0xa77e12be, 0xc6ce5fcd, 0x2a7f6e21, 0x4c6f9ff8,
- 0xbf8d1d4f, 0xf5eaa26d, 0x6bf7f00b, 0x5b4fc988, 0x6eccedbe, 0x3e5f6d2b,
- 0xc77cc053, 0xe22cee69, 0x929fe28f, 0xf99e9435, 0xfa5b2f94, 0x5f5f0117,
- 0x673c6a57, 0x41ccb335, 0x63f1d102, 0xc2c32dc1, 0xb5e78fb3, 0x7efc0b76,
- 0x57e72e59, 0x359f7e71, 0x5df0d53b, 0x66766139, 0xdd9136f5, 0x7ec85257,
- 0xaf975127, 0xbc39711f, 0x37c7fb8a, 0x700cb37a, 0x0d28874c, 0x693334fd,
- 0xd75dda28, 0xe5c76d9c, 0xe0fc5cb9, 0x78e89bad, 0xf2611a3f, 0xabc5c56b,
- 0xd8322f90, 0xc84cca7e, 0x6f41122e, 0x66bbdf1a, 0x471eb1bc, 0x27abcf8e,
- 0xb3307d74, 0x9bfdc455, 0xcf148599, 0xd3b18902, 0x18beadbf, 0x865ed167,
- 0xe7b5d078, 0x04bbf83c, 0x83e2fa31, 0x2fa4efd2, 0x3832a05e, 0xd2f5ca9e,
- 0x0fdfee44, 0x6f408322, 0x1f1b134c, 0xa2ea3e06, 0x0e35a6eb, 0x8eebe91f,
- 0x5097efee, 0x21be0639, 0x8f18691d, 0x032e769d, 0x7f7449f3, 0xa847ac3f,
- 0xb1c5a25d, 0xcc4bee97, 0x1307dc31, 0x76512bd6, 0xfdf05c89, 0xd46992ed,
- 0x00f2551e, 0x9fc481be, 0xe30cfa8f, 0x70902592, 0x8cc1f102, 0xa9e71853,
- 0x8affa896, 0x4c13f3eb, 0x097fd1cf, 0x30f91129, 0x9c7a2bdb, 0xdba49ad9,
- 0x093e4653, 0x97af1bc7, 0xf3a3ee31, 0x13e00949, 0x117affe4, 0xf1bd3ae3,
- 0x6f7e3e8d, 0xfaa212fc, 0x0f384928, 0xfbf970bf, 0xbcf2fcb6, 0xc8c327ce,
- 0x89f0beb0, 0xbf3a1fce, 0xa609d8c4, 0xeb4f5078, 0xe9894bcd, 0xd69edf88,
- 0xc847979b, 0xb37bd7a8, 0x3126766b, 0x744aee3d, 0x5d577f63, 0x7609d334,
- 0x11eb958d, 0xc70add7d, 0x9f19eab5, 0x573edcbc, 0x6aa3fd82, 0x11d91fd0,
- 0x60f1e83a, 0xae972f9d, 0x9cff1821, 0x6756f5ce, 0x56078b2b, 0x7003154f,
- 0xe5b8a284, 0x9d5987c1, 0xd3a2cbdd, 0x27ce6af7, 0x096ed285, 0x1af3777e,
- 0xbe20d04d, 0xc4f1e1e4, 0x8094e719, 0xafab1d9a, 0xc75fba74, 0x0bbf07bf,
- 0x23c6bfde, 0x1c4ba804, 0x3baecfa3, 0x188aecc7, 0xcfbc2a7b, 0x891e62ab,
- 0xeb4e5f99, 0x86421f74, 0x0aed3bfc, 0x76fce921, 0x6f7dfe85, 0x1e064e74,
- 0x65ee7a06, 0x1d80aef7, 0xe2be740f, 0x3afd849c, 0xccf18c93, 0xbf791db3,
- 0xbf93df41, 0xcdafbe6f, 0xc6de9f3c, 0x17f746ff, 0x8fa0ffb8, 0xcec4957b,
- 0x27d79bc7, 0xd75e9c7d, 0x99bdfe23, 0xe293c37e, 0x3eba7ddb, 0xd73fc18e,
- 0xafd13dd7, 0xebad7d37, 0xbeb77fc5, 0xd7d7fbd6, 0xb35c7d13, 0x8fc9ef1e,
- 0xeaf2f5d4, 0xdf8c16f5, 0xfafee14c, 0x9e2f1e14, 0x6ce2c499, 0xeedeb8b3,
- 0x0166dcfa, 0xb3282ebb, 0x6eff30fd, 0x36a1c627, 0xd0f662ef, 0x724e3c9b,
- 0x9c6220b7, 0x16b1eee4, 0x17d4dbd4, 0x4b7987ca, 0x808c8445, 0x2c01dcfd,
- 0x8528df4e, 0x6bef50ca, 0x6f738112, 0xefdfeaaf, 0xfd04dff1, 0x70f1fddf,
- 0xa3c62d4b, 0xc7e06d43, 0x7093cb8f, 0xaad92c5f, 0xb3bafc62, 0x03f78ad5,
- 0xd9f8ed75, 0xf9fa196e, 0x5ae0689c, 0x0d6ad4be, 0x1e814bef, 0x101e2699,
- 0xaba33f21, 0x59fde09b, 0x8a876793, 0x429b3fc1, 0x0e216ada, 0xf9615130,
- 0x3d3c66e8, 0xcc31f7ca, 0x7de114fb, 0x9f665689, 0x7644bb15, 0xfb4f580f,
- 0xe60acd12, 0x2fb6f757, 0xa0967851, 0x2fb3169d, 0xd2f4ccd1, 0x9897ddb7,
- 0xdf87b808, 0x9ff9d367, 0xc3d227eb, 0x8566c4fe, 0xbf7567ed, 0xbfb0132e,
- 0xb8b4b1c9, 0xf6dea371, 0x4aec7629, 0x1d3dc0f0, 0x4deff99b, 0xc035d8ec,
- 0xfcf6e6a3, 0x777b6e7e, 0xcda4a811, 0x984ad78d, 0xb9e3c6f7, 0x19a0b8e1,
- 0x66ff1caf, 0xc8156e7c, 0x07c4072a, 0xe0a9b45b, 0xbfb8f517, 0x71c1edd3,
- 0x5d478afa, 0x491f364e, 0x6f9f00f0, 0x03c0323e, 0xfc003fe3, 0xab59710a,
- 0x93f015fb, 0x9d3e1c77, 0x8abcfb80, 0xa4bf0547, 0xb1a6d93b, 0xef8c8973,
- 0x03c39983, 0x9abd0fb0, 0x84e6f9f3, 0x4c8ebfee, 0x61afde8b, 0x39fa33fb,
- 0x60855aff, 0xc2df883e, 0x78cc41f2, 0xeb66e41b, 0xebc4e6b5, 0xa69c89c3,
- 0x35f2f18a, 0x7f9662b5, 0x807e7e60, 0xf03977f3, 0x7147ed01, 0x8956b833,
- 0xaeff8465, 0xcef58128, 0xbfe5af5c, 0xc67b4387, 0x1cd565df, 0xed2a3396,
- 0x67d278e3, 0x40efc057, 0x3b96f96b, 0x2f70dc73, 0xf2ca5083, 0xb2f92c3c,
- 0xc493c846, 0xd6953a52, 0x0ecb922b, 0xb883f526, 0xe40d73b1, 0x479e4333,
- 0x2f445a5e, 0x0ad747dc, 0x2e245e5b, 0xbf12b0eb, 0x3d70ec1d, 0x79e79fcf,
- 0xfbebb52c, 0x3eecedd1, 0x86fe8aea, 0x850e4e73, 0xbfbf477e, 0x9a3deade,
- 0xa14cf984, 0x7dd29544, 0x78698ef9, 0x76e2907f, 0x3e477ce3, 0xf803293f,
- 0xd9f5c281, 0xff5c31ff, 0xc82e0f1b, 0x3a71816f, 0x062c8eb6, 0x087231fd,
- 0xd08b599c, 0x7c41aa87, 0xbc120f6e, 0x01fff12f, 0x512809c2, 0x00008000,
- 0x00088b1f, 0x00000000, 0x5bb5ff00, 0xd554740d, 0x79bfff9d, 0xbe4cdef3,
- 0x21264cdf, 0x012f0842, 0x1c424242, 0x61f08062, 0xc4443e1d, 0x602a0320,
- 0x43e196eb, 0x9a1af909, 0x7ab76eba, 0x2904930e, 0xb693db02, 0xb654e56e,
- 0x28bb560e, 0x82609d89, 0x04ec2681, 0x6eb50314, 0x5b604040, 0x6a445477,
- 0xbb8d3243, 0xb29eec54, 0xf7bdffff, 0x60c33325, 0x392dd9e9, 0xddf73739,
- 0x7ffdeefb, 0xf75ffefc, 0x595c003e, 0xc9a00392, 0xe7b73aa6, 0x001aa802,
- 0x6dbcdc64, 0xa0556052, 0x324e4018, 0x63240a6d, 0xd4da669b, 0x668a6d86,
- 0x9aa9e362, 0x70805ace, 0x6c14b2ce, 0xf2ce70b4, 0xc6efbc29, 0xc34b9656,
- 0xfdec32c1, 0x45f38a5d, 0xe1d90a9c, 0xfec49e0f, 0x39148ffb, 0x42ff63b7,
- 0xa4096a62, 0xe7f2ac01, 0x3fb08535, 0x1b1fe2d5, 0x69ceba44, 0x1a6d2c9e,
- 0xfe2dd7c0, 0x7be32089, 0x68529bc9, 0xf005c97d, 0xbab63b1d, 0x22948f06,
- 0xd5d02e7d, 0x60a300f1, 0x08a976b7, 0xeb82a900, 0x05f6f1e9, 0x58074c2b,
- 0x8eff1339, 0xf19217d8, 0x53d22679, 0x741b9fce, 0xb405fee0, 0x30cf41bf,
- 0x5dad901d, 0xeff6024a, 0x96eff63a, 0x8fb81851, 0xdf9313f7, 0xbf8b6122,
- 0xa2fd7fd4, 0xbfc3efc9, 0xdb9f6807, 0x792bb669, 0xc43674cd, 0xebf999f6,
- 0xeb119946, 0x3e7c1fc3, 0x65092f8d, 0x9015d59d, 0xf33efd8a, 0xd8ab2147,
- 0xf4677f07, 0xe327e67a, 0x45ce337b, 0x8175c73f, 0xd62d9fe8, 0x0cbf072d,
- 0xa1998f28, 0x61b379e8, 0x5c641fe7, 0xe8e5f677, 0x14b40be7, 0x3467e307,
- 0xf8cebe8c, 0xbd70aa43, 0x6f5f2b7a, 0x34bc9de8, 0xcd9bfd40, 0xbb945328,
- 0x8e50cbaa, 0x77fa75ed, 0x66fb4017, 0x700f979c, 0xb595b360, 0xeb6b4e53,
- 0xcdcefe88, 0xe0152008, 0xd62ce6d0, 0x98c69aaa, 0x561a729c, 0x3ec44943,
- 0x90c7df1a, 0x2e39d0e3, 0x82a1a9c7, 0x5f60e6e7, 0xafc055e9, 0x4b39f08f,
- 0xb80869c8, 0x9534879c, 0xf1fa79c9, 0xc411dd9f, 0x132c9647, 0x25fc11e8,
- 0x17a089e8, 0x0a93f48c, 0xd97d51ec, 0xd5cf8fd0, 0xdfeb8597, 0x714fd621,
- 0x075a8e8e, 0xa113f8fc, 0x85f643bf, 0x71f212bd, 0x05657247, 0x9e5693f1,
- 0xd96eb517, 0x427ab13b, 0xd3cbe1c1, 0x209fc890, 0xc69fa69e, 0x33f988f1,
- 0x00923e1c, 0xfa26ff94, 0x4cb34039, 0x62eb3476, 0x6f27f3f4, 0xc99bb7a6,
- 0x9b9e4a13, 0xe5ebf8e3, 0xcb457369, 0xb4517d33, 0xd1dc333c, 0x2ab51cf2,
- 0x79b76e5a, 0xa632e5a2, 0xf8d47272, 0x51a54dd8, 0x99df71fd, 0xd73f3515,
- 0x3faa2f37, 0xa8e2db7e, 0x979b13f9, 0xed27f547, 0xfcd47afa, 0xa8daff42,
- 0x55bda2f1, 0x29ffa4b7, 0x79a8fa81, 0x57d35e24, 0xcef6ffe8, 0xf3ed46ef,
- 0x2fffd6b7, 0x9c7ff463, 0xd234d97c, 0xf447fa17, 0xf24a838b, 0xd99f0936,
- 0x93f25690, 0xafb7aeb6, 0xbe976849, 0xe88fba79, 0x67062df0, 0x2b3d8e13,
- 0x6bf225bb, 0x26d45063, 0x4c5b1bf4, 0xfefe4950, 0x6ad326fb, 0x9d88f277,
- 0xb624d71f, 0x982af3fe, 0xf3d1ec13, 0xcc8f1796, 0x14d3da33, 0xf88da61f,
- 0xf45bafd9, 0x3df210a6, 0x147ee655, 0xf269ebfd, 0xa7a417af, 0x8a997214,
- 0x8a78a7c3, 0xed59bc59, 0x0e06d6c6, 0xb4db1ea9, 0x5faebf11, 0x505ce547,
- 0x98ff2ffd, 0x3b213fe8, 0xdffa465f, 0x86dc8125, 0x89bb56bf, 0xc361f3ec,
- 0x9a7ae96f, 0x21ae822d, 0x048fa5e4, 0xd0d3d66c, 0xfad0c3e7, 0x9dafccf1,
- 0x4805a6ff, 0xce55e7ff, 0xb2ff318f, 0x099f6bf0, 0xfe4fd6bf, 0xbc647f2c,
- 0x528fcf72, 0x7ce75c74, 0x440a2c01, 0xe42c29c8, 0x58d06604, 0x75cd99bc,
- 0x876aa176, 0xbfae18f2, 0x44d87df2, 0x13fcacfb, 0xef7c8a6c, 0xdec29acf,
- 0xb326b3fb, 0x59360576, 0x1815e728, 0xaca56ccb, 0x5db0941f, 0xe40a0bda,
- 0xe4f32c01, 0xf794242a, 0x03a679c0, 0xa292b4b7, 0xc107bdf1, 0x3fff90ad,
- 0x14dacdfb, 0xcebc379a, 0x4fdd4fdb, 0x8a815d38, 0x7dff61b6, 0x44c94f9b,
- 0x53be107f, 0xf711f162, 0xf773d2b1, 0xa69e6323, 0x3c167338, 0xbea0ce57,
- 0xad938396, 0x600bac67, 0x1733f28f, 0xe3a60854, 0x160bbe3a, 0x4748cbff,
- 0x4561b23d, 0x8f77d4fd, 0xb0647e62, 0x3fad8fea, 0xc7ab79c6, 0x9c52c684,
- 0xa7f550be, 0xc3f3d27c, 0x20afd0bb, 0x3d124b6f, 0x118cb619, 0xff5f9c39,
- 0x638d0a79, 0x867a65bc, 0xcbe7167d, 0xd8fb7e4c, 0x71bcc67b, 0x6da3b9b6,
- 0x5c72e724, 0xf88de664, 0xb00a5a33, 0xa9549f94, 0x177e9ffe, 0x0a1384e9,
- 0xcbc0cf5b, 0xfa978146, 0x24547d5c, 0x8653ea5e, 0xf08a32f1, 0xccb2ff52,
- 0x3bbea6ec, 0x97280fc1, 0xde770233, 0xfb5ed77d, 0x9e1d4eae, 0xb88c7cef,
- 0x9f2711d1, 0x8c746e20, 0x6e229f7b, 0xd90dffa8, 0xfde8953d, 0xa9c7e778,
- 0xc1f75a1e, 0x507ba35b, 0x06fd9f0a, 0xc738f7c9, 0x9d0c10fb, 0xbdba7e65,
- 0x1d21f750, 0x3b5c0ff3, 0x5d5cf94b, 0x60b745bb, 0x742d8aff, 0x7f9a79ec,
- 0x5f9a0250, 0x4e604c17, 0xf25daeab, 0x5578e027, 0x31d6db67, 0x596aafd8,
- 0xc3614656, 0xbbc10a9b, 0xe4bf7c68, 0x4bf1c46f, 0x1725839b, 0x87bae027,
- 0x75a25dae, 0x75f10e07, 0xe60e6f2f, 0xb0300e53, 0xb407cd7f, 0x05bb4d5e,
- 0xb1bf2812, 0xb431d505, 0xa0149b5f, 0x3f032afd, 0xcafd6950, 0xa04d9697,
- 0x6f7aa6f4, 0x1109c4cf, 0xc0e06b7e, 0x39475549, 0x60ffb655, 0xc65798a1,
- 0xe19f97c3, 0xa37fe0d7, 0x1cdf27bf, 0x6ff13fe9, 0xf093d91f, 0xf216bfbf,
- 0xbe35d55f, 0x7e89c489, 0x8979e3a5, 0x84d595f9, 0x5b870ba7, 0xda4bfb7f,
- 0x4ebfe0ef, 0xd940dc24, 0xdc1bc9ad, 0xeb17163e, 0xf9703ec4, 0x429dd53d,
- 0x452e53f2, 0xff3e73fb, 0x435dcd90, 0x2a9861fb, 0xc48444d8, 0xd0db87e4,
- 0x93e4801e, 0x43ecc89b, 0x6bab0e4e, 0xd1ef9e90, 0xacc7a404, 0xd8b5d585,
- 0xf31766df, 0x97feacf2, 0xafa46f73, 0xf26666c3, 0x2781e6b1, 0xed186fd2,
- 0x3a471a7e, 0xa67de68e, 0x4ebc7086, 0x6e12acbf, 0x53bf82eb, 0xdbdfa475,
- 0x5742e1f9, 0x3602f79c, 0x9314afee, 0xd94f72bb, 0x4bd47d88, 0xf089218d,
- 0xce92707e, 0x2f9b58f2, 0x48ebe8c4, 0xf98f89d0, 0x3d377e07, 0xefdeb114,
- 0x26131f11, 0x7eebf48c, 0x428961f1, 0xc3fd7b72, 0xc8ca7312, 0xe4cc81f3,
- 0x3a5c7f4a, 0x3a78bc78, 0xf6997dd5, 0xd1603dad, 0x13be191b, 0x77c2419c,
- 0x3d139257, 0x6d5be135, 0xf7c48b2c, 0xbaee8cc3, 0x4889d92e, 0x65ceba87,
- 0x3f36069e, 0x906a49c5, 0x08fae73b, 0x66e6b267, 0xc1ff8478, 0xa54710fd,
- 0xa3fa37f4, 0xcfcf3695, 0xe4e67f49, 0xbc48c4e0, 0x394299d5, 0xcfe9128d,
- 0xc2373cd3, 0x9f64e4fe, 0x7920e8de, 0x7d653ba6, 0x898a7f44, 0x0f4065eb,
- 0x8e29daa5, 0x50f5c66d, 0xdfc1031e, 0xb7fc92a5, 0x92b3ae76, 0xa6c77fdd,
- 0x55593d31, 0xff61ae9f, 0xbe47d4db, 0x4aeea9b7, 0x996dabb2, 0x0d764089,
- 0xef8676d9, 0x01d784bf, 0xbd5457b2, 0xb8a01e02, 0x36f0203a, 0xff981630,
- 0x708fdca5, 0x37be5326, 0xa3c8cc9e, 0x676f3cd1, 0x08c5c94f, 0xae0e077e,
- 0x4a7d1274, 0x321f7f22, 0xf7635e39, 0xc3814ffd, 0x9b6b4da7, 0xe1c446e7,
- 0x15bf79d8, 0x00e43478, 0xab165f66, 0x8cf13107, 0xdb3adf87, 0x1fe433bc,
- 0x0bbbb69f, 0x899b0fc8, 0xaea3c230, 0xe703a5c6, 0xcde907ff, 0xc85c7f98,
- 0x1a3c5555, 0x214df5c9, 0x33754557, 0xeb61a339, 0xfcc3c764, 0xed71a9e5,
- 0xdfc10bec, 0xbd68dcb6, 0x2abbcec7, 0xbe4c53f8, 0xe744b5ac, 0xcdd99961,
- 0xfa661ea0, 0x060de637, 0x77fd71af, 0x8bbf7e7d, 0x05773cec, 0xaf67e7c3,
- 0x11ca9614, 0xcdb38eeb, 0xffe22ffb, 0x8a0f0313, 0x0ee88b2f, 0xdeb1f0c5,
- 0xf892fee6, 0xc83bf236, 0x4e12dc76, 0x4e07d440, 0x3eb0ef11, 0xabe33028,
- 0x24e89083, 0xf226deff, 0x19b83360, 0xa9c0924e, 0x05d77ab3, 0xfc8d9abf,
- 0x6098f535, 0x9b53763b, 0x8139ca24, 0x9ccd608d, 0x228c9b2a, 0x52c565c2,
- 0x0c8c88af, 0xf6ed53c7, 0xbd20b77b, 0xf327c107, 0xfeba39ba, 0x92e49705,
- 0x37deeb22, 0xbdd7e2ab, 0x644d3dbb, 0xeea97fd7, 0xad34199d, 0xfafed351,
- 0x1d8277fa, 0x1822e8f3, 0xdb27a3ce, 0xa0544675, 0x102fe380, 0x7b33f44c,
- 0xf09f54c4, 0x1a7e4fdb, 0x922bf9e5, 0xa553ce29, 0x0dab0281, 0x78eec4a0,
- 0xda365b66, 0x3fce04d7, 0xefe89bf5, 0x0c679e5e, 0x4e6fd3d7, 0xfa277966,
- 0x93d59921, 0x4625a09a, 0x1f98656f, 0xd88d3a41, 0xe0f1eaa3, 0xc9532fb1,
- 0xf5dab6ef, 0x84bd277f, 0xf940cb8f, 0xa439825b, 0xd5d8e2da, 0x3163ca01,
- 0xcedc790f, 0x9dac6bcf, 0xfb8fcb92, 0x5017755b, 0xb4d04f7c, 0x7d8472a9,
- 0x3625d815, 0x85d8f6af, 0xc7f3151c, 0x5277a62b, 0x9afd718b, 0x74a9fd8e,
- 0xfe7d53ac, 0xed4a74d4, 0x0a9ecd8b, 0x4cfbce3b, 0xa56f93da, 0xbf9b70bc,
- 0x0813e484, 0xbc51a5e6, 0x9f06629d, 0x7a46f4b9, 0x594abbbc, 0xcbb75591,
- 0x5d29dace, 0xbca06c77, 0xfce41bd4, 0x0e0a1ed2, 0xeb027615, 0xd936740f,
- 0xbfef3d69, 0xff268f75, 0x56032fb4, 0xf578ff91, 0x7dfcc98b, 0xfe699833,
- 0xe04dbb1a, 0xf3a26fdc, 0xdce27da7, 0x130be06a, 0x3fec679b, 0xacae73a5,
- 0x838a0e21, 0x0fc847cd, 0x58597424, 0x12f0951e, 0x61747970, 0x38e7477e,
- 0x8a01ef87, 0x70368343, 0x9ade384a, 0x4f796618, 0xbfa2dbb8, 0x9adc9128,
- 0x55bcec81, 0x214af5e5, 0xf27f7202, 0xbf6373c8, 0xe8e7ae84, 0xe170898c,
- 0x6097b8a2, 0x933b866e, 0xc29de523, 0x73b46ee8, 0x0626b53c, 0x9794c94d,
- 0x9178044f, 0x274235d1, 0x3a0d7db0, 0x6f7f990b, 0x9e97c355, 0x34ba3074,
- 0x702141c2, 0x926ba13a, 0x412dfe4e, 0x123e3173, 0x93e9dd34, 0x5bcba46e,
- 0xda178982, 0x611bf7cd, 0xaec98ed8, 0x7d2389bd, 0x6b42da2b, 0xf835c71e,
- 0x20b33e16, 0x0e4fa23b, 0xfde47ca6, 0x3ef7ece7, 0x9d9b25b3, 0x5464f917,
- 0x29b61275, 0x6753e276, 0x74d7a27c, 0x39729465, 0x494e5138, 0x3c3e3e56,
- 0x4c9e711f, 0xcf3e64fd, 0x1692d169, 0x017b32e7, 0x2f2317b2, 0x5e0a5c7b,
- 0xb5ed0bba, 0xb4ee07ff, 0xdfabe462, 0x1689e474, 0x35fbf79c, 0xf620fc81,
- 0x179ea94f, 0xfc6f9f09, 0x298eed66, 0x155b6fe4, 0x9df90567, 0x2c87ef90,
- 0xd1557dff, 0x1dd847b7, 0x09338764, 0x78fbb1bf, 0x90fe37cf, 0x83c1dbf2,
- 0xc9d56e92, 0x887386ef, 0x4faebaee, 0xdee7f255, 0x7cb21f83, 0xe7ba6e76,
- 0xafea3b35, 0x3e61b3bc, 0x342675c9, 0x2ebf9137, 0x20417912, 0xa193fb8b,
- 0x362ff9d3, 0xb4e1e844, 0x7b0837b0, 0xea7c51c6, 0x987af612, 0x3b6c4eea,
- 0x4f1e1e7a, 0xba8877eb, 0x01af78d8, 0xb9218c8e, 0xac9bc237, 0x7e378e1d,
- 0x59c222f3, 0x6aeb59d1, 0x77fcc457, 0x7abf3ced, 0xbdf3ced7, 0x379ee9f5,
- 0x3dd53e49, 0xc4a9a91f, 0x0e40c5e7, 0xac0193d5, 0x7e38b58f, 0x637ed864,
- 0x0e6bc9ec, 0x7bdf34ab, 0x415f9819, 0x43496f7d, 0xdb3bedfd, 0x3e0d7939,
- 0xa49d40ef, 0x9e709e51, 0x8a1d87d7, 0x6fcd0c7b, 0x84b57338, 0x2201d8fc,
- 0xdab9e902, 0xe48e3d5d, 0x979ff886, 0x06d67648, 0x7619afcc, 0x8a764c5a,
- 0xfe1317ef, 0xc85fa8cb, 0xdaab72fc, 0x65d998b7, 0x2ec80987, 0x1eccff11,
- 0xc51aff10, 0xed0d62e3, 0x893fbd81, 0x9f6b79d9, 0x58f2c5c9, 0x5913ebf4,
- 0xd403de7f, 0xa05bed6f, 0x21373b31, 0x5ec94b9e, 0x3ad84783, 0xa4898001,
- 0x91dc093a, 0xf60503e7, 0xc337a654, 0xf6174e5f, 0xd3d0281b, 0x9247c89c,
- 0x47d9472c, 0x7de49c44, 0x3f5d4711, 0x9e67c7fa, 0xfb4f839d, 0x44d09c44,
- 0xfdc73c7c, 0xac45b7fe, 0xd66b7faa, 0xc7ca16d2, 0xf1b32d7f, 0x227ce2c3,
- 0x44727028, 0xdc504f9c, 0x6f3f51d0, 0x69d7738a, 0x1fa177d8, 0x34daee9d,
- 0xf2aa729f, 0xa947cd45, 0xcc0ee59d, 0xce7154a7, 0x0aa3beaa, 0xc222f337,
- 0x7b91fb5f, 0xf7e4cc8b, 0xaefaf3ce, 0x07f0cbfd, 0x9e1ca2af, 0x8ff28c38,
- 0x1d90a713, 0xafcc3f86, 0x8dd640c6, 0xe19283e3, 0x4bde7647, 0x97681c78,
- 0x4848fa47, 0xfa9b021d, 0x9fdbe919, 0x9fdf61f1, 0x474acaee, 0x78711e79,
- 0x9e51d2b2, 0xccbf2783, 0x38ecb324, 0x9bab11fd, 0x115755db, 0x0f3da7e1,
- 0x3838cd4b, 0x73f3a735, 0xf44b3294, 0xced18af9, 0x3071e74e, 0x243b07df,
- 0x9acb1756, 0x76e6ea9f, 0xfe62a5d9, 0x2b7c1973, 0x11bf9366, 0x828f81e7,
- 0x1fc2e7f8, 0xa263cfd4, 0x2be528fb, 0x7b1eb718, 0xaf398956, 0x3c2264db,
- 0xe092e86d, 0xe57bc827, 0x1771d8ee, 0xc46a5bcb, 0xf73b1b3a, 0xfa831b1c,
- 0x7a297aac, 0x2be50d5e, 0xc03c9cec, 0x169acfea, 0x499f3a25, 0x78cb7917,
- 0x0b794f18, 0x07f989e2, 0x16bd0cc5, 0x8745efc4, 0x6b4c90a7, 0x09cb899f,
- 0xcbb32afd, 0xb4bf9142, 0x28fee3ce, 0xccfc057c, 0x8e06f66e, 0xb3dd22a6,
- 0xb49d725a, 0x1f332cc7, 0xcb99d59f, 0xfd980ce2, 0x445432f2, 0x90b3cbb9,
- 0xd73ed3e5, 0x47942ce9, 0xa093f0a5, 0x8daef3f1, 0x914aaf82, 0x47f46dcf,
- 0xfc133dd3, 0x86cfb44d, 0xa83392bd, 0x1280f9d3, 0x8af3af37, 0x9d766a75,
- 0x7bc7463c, 0x79e881b5, 0x6f1f215e, 0xfdf3f467, 0xd58136c0, 0x347ce2e9,
- 0xf9d87207, 0xd5adef78, 0x7857bf53, 0xac4a717e, 0x166f8c63, 0xf243a9b8,
- 0x7e35bf48, 0xa9b84fd9, 0x3ca97c94, 0x35e485bf, 0x033af748, 0xa0fe3a2f,
- 0xf90bd63c, 0x617813ac, 0xb5fbe17c, 0xdd3f25bb, 0x19dfad2b, 0x81a3ff4d,
- 0x0f090b35, 0x6caab8b1, 0x5b7e5851, 0xca549b05, 0x5571636f, 0x66978c35,
- 0x2c58e295, 0xd23cea9e, 0x79e6e84d, 0xee95fff9, 0xcec8256a, 0x59ffaa7d,
- 0xfe88fa72, 0x74a96ff6, 0x7da378fe, 0x1956fd70, 0xfd7c1138, 0x6f3cfcb5,
- 0x4c327fe0, 0x945dfa66, 0x50758b7e, 0xa6dd3e74, 0x3218fb72, 0x0362f3f3,
- 0x2fefb13f, 0x3df8f914, 0x57b580bb, 0xa54f3f3a, 0xbec1dff3, 0xad6054a1,
- 0x3fc51169, 0xf0884fea, 0x79d2fb3b, 0xeb35b89d, 0xbe53efe3, 0xe29b4f7e,
- 0x6a0e4cc4, 0x8a6e2ac6, 0xdf6335d3, 0x11109cca, 0x79d2da57, 0xdb4f79fd,
- 0x74098da3, 0xe48af0ce, 0xec1bf324, 0xd423fbfa, 0xce48b5f7, 0xb1fef889,
- 0x6777a1be, 0x92b23e93, 0xde7ad3a6, 0x5a8bbbee, 0xc5ec7fb1, 0x75919c3b,
- 0xe73b31e5, 0x0ab19eef, 0xa3fd9b8b, 0x41567e93, 0x3dae80e7, 0x0ffb8ecc,
- 0x9d92aebd, 0x904ab60f, 0xcb1d1b85, 0x8f9afa3a, 0x27039cea, 0xe7c64a55,
- 0x43549fb7, 0x5c0f915f, 0xc82b72c1, 0x559b49ce, 0x1ddc6baa, 0xca21a89f,
- 0x90fa5e8f, 0x75553f9d, 0x548fcc4a, 0x3afd96ed, 0xfbb479fe, 0x5470950d,
- 0xa8c122d7, 0x8571c8dc, 0xa3bf938d, 0xdc2da7fe, 0x5cf81a7f, 0xe068f02b,
- 0x5aebc0d3, 0x6dd667e1, 0x63e3c68b, 0x1a3adae0, 0x65b47fdf, 0xcd794a8d,
- 0xfdf1cda3, 0x36afe18c, 0xfe88fd50, 0xe8aec37f, 0x71871b79, 0x387e63e8,
- 0x1bf59fd6, 0x42842c38, 0x7050e1c2, 0xe23338ed, 0xaac9eafe, 0x5ee71071,
- 0xb7111de4, 0x3379b88d, 0x7e740eb9, 0xf3bc52ae, 0x6eac2b66, 0xb7ff66f0,
- 0xab93891a, 0xbb0b2702, 0x53f4c0fe, 0x80b3d5d1, 0x9e025bf6, 0x92ef921a,
- 0xf28d24ae, 0xb7108ae0, 0x165dc5db, 0xfa225fbf, 0x2dce2c4c, 0xd216c081,
- 0x0b61e0ff, 0x243c773f, 0x84087cb1, 0xe420db1f, 0x77c841bd, 0x6359d603,
- 0xe62f294a, 0x82c6f475, 0xa528c73d, 0x6bcf13af, 0x254d1f8e, 0xee062f39,
- 0xb8071667, 0x65f4319f, 0xe31b89c4, 0xa49bf861, 0x0b2eeaef, 0xf708f7d0,
- 0x5f733f09, 0xe919fa0b, 0xbc1fbb46, 0xc5e1892d, 0x8de9c1d7, 0xed758b8d,
- 0x0e4df3d1, 0x890e5f9e, 0x11cf36bc, 0x308aafad, 0x7ae31524, 0xe9d9758b,
- 0x99f56f67, 0x12deff69, 0xf5d3dd89, 0x3cd3e3ea, 0x9c38f471, 0xdd7c8b57,
- 0xf3a52fe8, 0xd01f9c2d, 0xeb23939a, 0x9e0e9df1, 0x94cd577f, 0x88ff247d,
- 0x696965fa, 0x65fadc6e, 0xbfe703a6, 0xe76ebd9d, 0xc5fac8d4, 0x709f27b5,
- 0x1facbdf8, 0x7f929455, 0x64fee168, 0x4dd71ca0, 0x581c7ca3, 0xb16deb7e,
- 0xf0cea9f8, 0xef288e22, 0x427087ba, 0xdd25d9f6, 0xfcc1384d, 0xcd126eff,
- 0x437aba32, 0x627597fe, 0x97e5c63c, 0xc303f82d, 0x9c09f1dd, 0xa8db946f,
- 0x5180f578, 0xc17dd407, 0x79e34df3, 0xeac4399d, 0x892eba81, 0xc8fdb6e1,
- 0xa45c9cb5, 0x8ffbb077, 0xfdb06b39, 0xa38f0707, 0x1f02f3ed, 0x572077d1,
- 0xf371ad5b, 0x2dbf61ca, 0x5276616d, 0x593284a7, 0xf31071de, 0x3f5819bb,
- 0xd58cfa9c, 0x1247ed0f, 0xf6b9d356, 0x38cf5ac0, 0xd4f42bed, 0x3f2c8d00,
- 0xac2d846d, 0x3225fca5, 0xf1a0db9f, 0x131e4aef, 0x4ffa8ef1, 0xc31fae21,
- 0x8d2b5fb9, 0x5b7c17e7, 0xfa374b67, 0xd4afc303, 0x1757bc0a, 0x294ad9ef,
- 0x539e6c57, 0x3308ec2b, 0x62df1678, 0x0e9d9bf3, 0x9c08bf91, 0x644a9c36,
- 0x71e0eaf9, 0x5d33a359, 0x474feb94, 0x7986fe53, 0x739c5e7a, 0x2e04cfcc,
- 0x65fdc5fb, 0xe4ccb943, 0x5bc99a66, 0xf9421f23, 0x9e0cbc31, 0xbe53f64c,
- 0x8df8745f, 0xf57fd23c, 0x69179c5e, 0x0f3fa877, 0xcfc7aefb, 0x481b5c70,
- 0xc6327762, 0x6fc3bef8, 0x359c264c, 0x9f32fa9c, 0xbe5ae5eb, 0x7d39b8ea,
- 0xbc492b46, 0xbc49358e, 0x8730ed8e, 0xf27ea952, 0xfedd941e, 0x7a1a7d08,
- 0x476117fe, 0xfaf5e660, 0xface871e, 0x171c5d0d, 0xe2de6ea6, 0x79f82bfe,
- 0xbff6c28d, 0xe21e7c61, 0x1ae22be5, 0x7ba85d10, 0xb86612af, 0x31349ef3,
- 0x8727bc7a, 0xbbe32332, 0x451dd68f, 0x06a1af7e, 0x02491f98, 0xc7e8b3f2,
- 0xdef7547c, 0xe5812e77, 0x76f2c74b, 0x95bf3054, 0xadf90327, 0x4d554e27,
- 0xf90f8c8a, 0x27e7990e, 0xca2c8724, 0xfbe59e56, 0xc234390b, 0x73ef5172,
- 0xce92bf1c, 0x527580e5, 0x6c71d937, 0xf9ab749d, 0x05b7436e, 0x7bd81ce8,
- 0x13bec2c1, 0x81bddab9, 0x85f0e1d5, 0x19f91267, 0xa76e78f0, 0x1bc389f6,
- 0xabf3d126, 0xcede3787, 0xc6a52fce, 0x23e5f8a8, 0x2f28b2fa, 0xe3a9933a,
- 0x99f76d78, 0xc2ad604c, 0x647ea7e8, 0xc1d77afc, 0x4f60d7e3, 0x90a73b02,
- 0x00e38f20, 0x5bad4426, 0xcb16fed3, 0x653a6a23, 0x8c1e2457, 0xf0703ef7,
- 0xc223eafc, 0x9013f101, 0x6dcf4c5c, 0x7ce9adbc, 0xad53d19d, 0x1b1e9804,
- 0xde3e145a, 0x2fcc5bca, 0xb03e1d19, 0x36fe88fb, 0xf7e6bf3a, 0x02bcec1a,
- 0x18fb3267, 0x6ff4282a, 0xe8affec7, 0xc875ca11, 0xdcfe026f, 0x9b83eec2,
- 0x11a7c77a, 0x5f7a87ee, 0x178bc477, 0x083dd0ef, 0x97227a92, 0xe3b117d7,
- 0x39f8327b, 0xdcf389c2, 0xeb989d8f, 0x9fcf1499, 0xaf1e60f9, 0xef2125b7,
- 0xbc516576, 0x3217b4fb, 0xdecf39f8, 0xe209df6c, 0x812dbfa7, 0xdbf5a7dd,
- 0xfce8b9f8, 0xe9cdc7fd, 0xa5db7714, 0xaa3f1469, 0x405fde0b, 0x2fd8f8f7,
- 0x782b7e63, 0xd61bdd90, 0x742db4b6, 0x2ea3a1c5, 0xc5f1fb83, 0xc8fbfc6a,
- 0x7bf8c5db, 0xf510cce0, 0xee130ed1, 0xa2855ef7, 0x8679676d, 0xf436f92b,
- 0xff0bf7bf, 0x8512c0fb, 0x81ef25e5, 0x077bf0ae, 0x54b03f7e, 0x85fbd1f8,
- 0x1e5a5e5f, 0xed9727ed, 0x7ee9a786, 0xbe2b9960, 0xac487e1f, 0x6c5c1cbf,
- 0x451607dd, 0xe4487bcf, 0xa3b90f77, 0x10ca4f9f, 0xf21f37fe, 0x3006ffc9,
- 0xebbe901e, 0x5c58130b, 0xc4ca6fbd, 0xb1c179b8, 0xfdeec0cd, 0xbffdc57b,
- 0xc286f7a1, 0x3abc59f7, 0x35fe73d1, 0x09dbf31b, 0x5ee71790, 0x195e246b,
- 0xd720fef6, 0xa82fb8b7, 0x868d38d5, 0xe560afde, 0x652e7913, 0x90b17de8,
- 0x04def57f, 0xaf9ef22d, 0xea8b6036, 0xd36f3b7b, 0xf9f8462e, 0xf46f816a,
- 0x73c8e6fd, 0x67b29d8a, 0x0bdd0671, 0x3e59fb58, 0xb8b01c8d, 0x08e57c85,
- 0x112c72be, 0x6dcae8f1, 0x77e2e26b, 0x8fbb3f84, 0x6b077dfb, 0xcc2d0a7b,
- 0x92036aee, 0x6aa3ee9f, 0xac9ebc83, 0xc9ebc05d, 0x579e76fc, 0xf25078ae,
- 0xbee624bb, 0x067d134e, 0x795a967e, 0x327036fc, 0x1f812f2c, 0x7e78a71a,
- 0xb1e788bf, 0x7d049a38, 0x779ce90b, 0xd2724ba5, 0x78b171f7, 0xea6abe5a,
- 0x6f9ee45b, 0x9bc41f86, 0x16327e42, 0xf0cf3f47, 0x1a632b7c, 0x4c570bab,
- 0x144f75c1, 0xb8439a7e, 0xdd89bba9, 0xdb7a14ec, 0x413bec9b, 0xbf66bef1,
- 0x5fdf07b8, 0x792219d8, 0xf7cb02f4, 0x5b7d6dfa, 0xcc1e79eb, 0x836bc1ee,
- 0xdefa4e09, 0xc92bb6b5, 0xf6fd4099, 0x54c9c486, 0xcec9761f, 0xb457ec24,
- 0xf2405c9f, 0xdfe328ac, 0x61a9d465, 0xb4ae6f96, 0x5e92b679, 0xa27b3897,
- 0x3a0dbfee, 0x58f3866f, 0x0902f6bf, 0xe76fe327, 0xe0c85e6f, 0xf8feaef1,
- 0x719399e7, 0xcf36e9ab, 0xf07ba26e, 0xba5557ad, 0x7e4ef326, 0x4eba6163,
- 0x6f3674f3, 0x16cf4b49, 0xe8357e3a, 0xee343b0f, 0x367f155f, 0x6f8b23cb,
- 0x86907bed, 0x50976f83, 0x73d03cde, 0xc08d44bc, 0xfa3d7f77, 0x6bfa38e7,
- 0x5bb09300, 0x69256b33, 0xb86fc8b9, 0x8fbb7b1d, 0x41b9d266, 0x316fd93f,
- 0x295267b5, 0xbdb6d62e, 0xf2913a97, 0x1ade0e8c, 0x92e95deb, 0x87303cd9,
- 0x894a1ff2, 0x4669efa4, 0x5f0095df, 0xff942007, 0xf1c894c0, 0xfb6fffa6,
- 0xae38413f, 0xeca286b5, 0x561390df, 0x47563eed, 0x7bb0b61e, 0x8927ba75,
- 0x92ea9efc, 0x2c0cf5c0, 0x674ec86e, 0x78f0bdd2, 0xf0ccc54a, 0x10cdf508,
- 0x9ee9db34, 0xeff32836, 0xff99b2cc, 0x9ff62e9e, 0xd0f60e61, 0xc53396f7,
- 0xe82ce2bd, 0x06bef363, 0x40bad661, 0x0f3b5333, 0xb72dac9c, 0x32a3ef06,
- 0x901038af, 0x4cc1ff49, 0x9592edb3, 0xf1007f7d, 0x37223df4, 0xe4325c33,
- 0x13fdd321, 0x962f5eff, 0x8f02eb9f, 0xefdc5c33, 0xdf412a50, 0x80439659,
- 0x09df77dd, 0x1def7121, 0x58d98f9f, 0xd77dd1a7, 0x893b689d, 0x367e1e4c,
- 0x23f10e7f, 0x7427e3c7, 0x2c33531f, 0x293e88d0, 0x9eba6998, 0x0c7ceb74,
- 0x375b0266, 0xe0785d75, 0xfb91b2c9, 0xdbd76742, 0x50bbe8e7, 0xdf62e5c9,
- 0xc9ad3a8d, 0x04975641, 0x7ec3fdcd, 0x39200f2c, 0x66626d73, 0xf777c8c6,
- 0x3df601e0, 0xf777ec45, 0xcce5eec4, 0x8cb4ef91, 0xfaf73fef, 0xc426eb97,
- 0xd5872ac7, 0x4a3e2329, 0xd07739ad, 0xcd39e0f9, 0x8d399893, 0x996d03be,
- 0xfb3116c8, 0x53bcb1a7, 0x5c092ae0, 0xe4bfc4e5, 0x07fbbe32, 0x389f1786,
- 0x8265f6bf, 0x9252ae9f, 0x91587c30, 0x43881dae, 0x5fa19dab, 0xe159efa7,
- 0xe53af9a9, 0x566d5bb7, 0x166fe527, 0x846937a2, 0xff2b26de, 0x7ef8c1ee,
- 0x4d8e562b, 0x663e8328, 0xcb2b4e7f, 0x628fd78b, 0x6b8f34f7, 0xb27fbf9c,
- 0xfd10a678, 0x1bcca78f, 0xd16ef945, 0xb164e62f, 0x30e51bfc, 0xe98390c7,
- 0x80e7ffc6, 0x3c91977c, 0x817fff63, 0x802a2fc1, 0x72134681, 0x48d7f834,
- 0x5c6f143f, 0xbf431fa8, 0xd9722379, 0x57f9c891, 0xf18f4be8, 0xec9d5dec,
- 0x836f9634, 0xcf05ffbf, 0x10785073, 0x00107850
-};
-
-static const u32 xsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x94f3ff00, 0x51f86066, 0x257bc08f, 0x799c1819,
- 0x8968c550, 0x1819390b, 0x0bf1030e, 0xda005620, 0xc0c5caeb, 0xfdc406e0,
- 0x88013c40, 0x3eb100bf, 0x01830337, 0xd902a710, 0x736e6852, 0x17ba0264,
- 0xd8815d88, 0x32bf881d, 0x637c3030, 0x767ede20, 0x623da021, 0x2039fe08,
- 0xfd04b2fb, 0xf0d83ffc, 0xdafa655d, 0xc0c2a817, 0x2a83a310, 0x8fc68b16,
- 0x466fc1d3, 0x027c9a3c, 0x8f113f1a, 0x5473717e, 0x2a019d7e, 0x8188c93f,
- 0x9a920f61, 0x6efc037a, 0x81afc741, 0x3100df7a, 0x74769a00, 0x0003685d,
- 0x00000000
-};
-
-static const u32 xsem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0x45547809, 0xbedd70b6, 0x4e9def4b,
- 0x62585908, 0x81511007, 0x05e42ce9, 0x62d9b1c4, 0x970621f4, 0x66854611,
- 0x44749ecb, 0xf9d1c1c6, 0x153610d3, 0xc713309d, 0x60ec44e0, 0x81a0d050,
- 0x60241009, 0x3cc0ea03, 0x64ffe31d, 0xb83066dc, 0xc5a4c6b0, 0xfcb8df0d,
- 0x4dd54e75, 0x11d37bdf, 0x7fef999c, 0xca3fbff3, 0xfb5ba957, 0x539cead9,
- 0x2c922aa7, 0x4222e910, 0xab9f83be, 0x409bf908, 0x4d171908, 0x69e5a909,
- 0x24e05295, 0xbfa2e024, 0xe1521366, 0xd3cb4254, 0x43b29909, 0x48955f0e,
- 0xc8428df3, 0x7da6f34c, 0x6eef2c56, 0x53b0f960, 0xfe5a11f1, 0xd3cd1371,
- 0x8ee6033e, 0xe5a0ae87, 0xd9221d91, 0xb28edd08, 0x21124899, 0xfd842dc7,
- 0x0e7cd364, 0x96568521, 0x3fdc68ad, 0xb717da07, 0xf6958999, 0x68bbb157,
- 0x5f3415c6, 0x50264874, 0x32d362a5, 0x97cd1065, 0xc8168484, 0xf3664cf7,
- 0x4314ee0b, 0x1efd689b, 0xcdd24757, 0x574e420e, 0x2147885b, 0x91d9c6a4,
- 0x4268d374, 0xf2db434a, 0xb3695da0, 0x581135e0, 0x5397a6c7, 0x045b5d61,
- 0x4843d9af, 0xf13b66d9, 0xf873628c, 0xde3bfe8e, 0xa2af862a, 0x3ae98be5,
- 0x88b7ed09, 0x1111e6d4, 0x78a75fc6, 0x9df8519c, 0x38e376ae, 0x0b62be6a,
- 0xabb6871d, 0xc2f0567c, 0xc44d2b12, 0xefc742df, 0xf59d6dde, 0xb7d60384,
- 0x84e9194c, 0xa056ad75, 0xde68515e, 0xe607ab4e, 0xd1e4a8d7, 0x4686d2f2,
- 0xb47470a5, 0x03cdb2bf, 0x1faaf3f4, 0x94d7ec9e, 0xd5d3d31b, 0x46467884,
- 0xf884a5f3, 0x44bf685a, 0xc733290a, 0x407fbf44, 0x081909e2, 0x63c48bfd,
- 0x214ff689, 0x4783df89, 0x5e14afe8, 0x844ebdc1, 0xc5b78aab, 0x27bbfa6e,
- 0x6eb3b78a, 0x9229478e, 0x4d5feda3, 0xd03c021f, 0x9c02d4f9, 0xcf96ba68,
- 0x4c9135cf, 0x2eff6892, 0xe903711f, 0x351eb7f5, 0x3cc995ad, 0x185ac742,
- 0xc693e31c, 0xee42bcd3, 0x7e425e20, 0x37c722bd, 0x241fe695, 0x6f3039fe,
- 0x062fe4d1, 0x92d2113c, 0x4abbf402, 0xfd60b320, 0xd349813f, 0x94a955f2,
- 0x6bdc293e, 0x213ce5a7, 0x89ee7c0a, 0xf27c2f90, 0xa7ec74fe, 0x6851fb08,
- 0xdfcfc33f, 0x572f3b8f, 0xaf3b8fd7, 0x0aa7ed58, 0x585db1fb, 0x1379b53f,
- 0x2bc9f3f4, 0x1bb9fb55, 0xd85d71fb, 0x4f57dcba, 0xeae7cfd4, 0x7e27ec72,
- 0x69f897aa, 0x07a5517d, 0x6913e1d2, 0x3e39a3b9, 0xa5a27ef3, 0x812bc98b,
- 0x4b949dff, 0x971174b4, 0x61d1d36b, 0x97412fbc, 0x8fb93da7, 0x30f3ce5f,
- 0x7c82cb88, 0x50520ca9, 0x641a4c2e, 0x35dcf9c1, 0xe17281c8, 0x4bfe09ae,
- 0x301e74dc, 0x79a54936, 0x7723ffc5, 0xf3a6ba0c, 0xa40a4814, 0xc6a4131e,
- 0x8332d5f2, 0x5fc1e4c3, 0xdb463c8f, 0x91914c07, 0x4ebf34f1, 0xac38f498,
- 0x21311363, 0xa9226c7c, 0x33367a82, 0x3ab4f941, 0xa089e73d, 0x866b4e06,
- 0xd10bfc52, 0xfec8d77e, 0x2dafa014, 0xd020e6e4, 0x94a1aadb, 0xf21107c9,
- 0x70a6f074, 0x87eda250, 0x3c00a616, 0x6fe50acd, 0x1d0af8ed, 0xff8e347f,
- 0x03bf8c1c, 0x77d71fc6, 0x5cb0f37c, 0xb496f8dd, 0x16f8dd62, 0xe94f8e85,
- 0x9db9377d, 0x37e14f8f, 0x83e79081, 0xe6f8e1b7, 0x7f1c62b4, 0x758a42b5,
- 0xc77adbe3, 0xfdd6017f, 0x1feb7f52, 0xfebf4136, 0xfafd52b4, 0xc3feb615,
- 0xdf1f1164, 0x63ffeb86, 0x7f5b2170, 0xbf5b295a, 0x3bdbf599, 0xfe17abbe,
- 0x8fbac1af, 0xe1feb7f4, 0xbfebf513, 0x7ebf5ca8, 0x6dff1b33, 0x77c7c152,
- 0x04eff8e0, 0x2ffad9cb, 0x15f1c72a, 0x740bdfb3, 0x55b60ca4, 0x64f8e885,
- 0x64886508, 0x4c3e5194, 0x42102547, 0x6191d7db, 0x6cbb8708, 0xb0beee8c,
- 0x44737a51, 0x51091de5, 0xacf2a28e, 0x597cd392, 0xe40524f3, 0xb953962c,
- 0x754f88b7, 0x74889b61, 0xa1ccea4d, 0xbb7ce98b, 0xe420c4db, 0x195dd617,
- 0x23bf7112, 0x9da00b73, 0xfdf0c244, 0x6cc787a3, 0x98cbaed4, 0x8f95aa2e,
- 0x88f8ea77, 0x993827cd, 0xf3a2aa8c, 0x3044069b, 0x4e3f9a2e, 0xf2a128e5,
- 0x472a7df3, 0xd3213d21, 0x0ff7e8f1, 0x8a259ca9, 0xb1966f96, 0xde483c7d,
- 0x72049518, 0x971cfd82, 0x2f8fbc18, 0xff004211, 0xa1ddd62f, 0x545a7c80,
- 0x8f40a76b, 0xf1c023ce, 0x0e6dd914, 0x9e10146d, 0x2dcf801e, 0xfc848ac8,
- 0x9535a295, 0x7ea8b682, 0x6dddae80, 0x8532b424, 0x76b05fd6, 0x5d3750de,
- 0xccb3adff, 0x1fec2299, 0x84d837c4, 0x9b064c7c, 0xd5990972, 0x4c1e4eba,
- 0x92ccb733, 0xb4d4efdf, 0xe7d7ed9f, 0xe7d62d6f, 0x6c90e5bb, 0x44a37d02,
- 0xdfb48d20, 0xe5f4abdb, 0x42f138ea, 0x1f2bc302, 0x6c4927ef, 0x9a43b7be,
- 0x88dd9f09, 0xd66e39d7, 0xe04f9d56, 0x7184991e, 0x481cecbf, 0xb103ff10,
- 0xd6cddf9e, 0x1cef9c6d, 0xa02be2d9, 0xb77399f3, 0xce34f088, 0xdd9f73bf,
- 0xd34b1a67, 0x20654ffa, 0x8c7ae341, 0xd4bb9ff3, 0xea371eb8, 0xc682f361,
- 0x8c4e8cef, 0x9b6814f4, 0x4d43e034, 0x6b968abd, 0xa1a87c06, 0x33cdb2af,
- 0xd092f975, 0xa2fd5d6c, 0xf2ba79fa, 0xba25b545, 0xee6b05f2, 0x05e7e5d0,
- 0x9fd5d6ef, 0xae9974bb, 0xfbaaf6fc, 0x16b7e574, 0x67e5d3af, 0xeaebd7fb,
- 0x51ab32df, 0x2bec2e57, 0xe513a8b9, 0x54a2ffaa, 0x36df2bd0, 0x9547a013,
- 0x387e55de, 0xe9829d59, 0xa60f6ae9, 0x294f80cb, 0xb3769bff, 0xde71b034,
- 0x2aefc045, 0x55c84e9c, 0x464fc069, 0xd3c237ba, 0x67f4df48, 0x487dac70,
- 0x5205cb4d, 0x87ae7200, 0xf7eacfef, 0x120e5c73, 0x72d31cb2, 0xf96df185,
- 0xc4c9d4f6, 0xc8f0f905, 0xfdff472a, 0xd7011692, 0x1e8b4041, 0xd4a37808,
- 0x70ebc3aa, 0xf6bb3cdd, 0x257e388b, 0x0078eef0, 0x0132c155, 0x307c21f8,
- 0x3031c6ed, 0xcc72df1f, 0xfdc40db7, 0x7f3aabb7, 0xc01287c0, 0x93d300af,
- 0x3d30b3d5, 0xf4c7ed5e, 0x4c62eac3, 0xc2aeafdf, 0x297ab3b4, 0x83ab47a6,
- 0x7aa5fe98, 0x54efa60d, 0x56fa62d7, 0x7fa63d75, 0xda610eae, 0x54c3ed5d,
- 0x395edba5, 0x4af5c899, 0x1dd3ffae, 0xf967f302, 0x7bfa445a, 0x37a3f207,
- 0xacf1f805, 0xa0918be3, 0xcb7d9f37, 0xef2f404c, 0x7a465e0f, 0xc4ae17e8,
- 0x61457a87, 0xac870a88, 0x1b56e5be, 0x44d593c3, 0x1b9509f2, 0xa4fc5df7,
- 0xcc68fe77, 0xda01244b, 0x9d33bc87, 0x411dfa31, 0xc3e75f10, 0xc645f113,
- 0x71f140de, 0xe5bfd1fc, 0xf8e7bf40, 0x283b653e, 0xc2497ee2, 0x5f01784f,
- 0xfee1b81a, 0xe5c1d913, 0xf7e079f2, 0x7e1540f1, 0xa684691d, 0xd2370413,
- 0x3356d9df, 0xed8e0091, 0xfda110f6, 0x84f43d9c, 0xc5bbf60b, 0x87f72629,
- 0xa6a0e031, 0x6ee92d15, 0x689f7687, 0xd6cfe7d3, 0x282df90a, 0x37713d37,
- 0x72ba018d, 0x011c3fbb, 0x54c14ff8, 0x8a7167ed, 0x0070fee2, 0x45f18fc2,
- 0x29d23c73, 0xdeb0dbb5, 0xfd1e7b3f, 0x479d13f5, 0xb680f92b, 0xf8645b47,
- 0x3e91edf9, 0x533e96f8, 0xed4f000a, 0x9fb017f2, 0xefbfe8db, 0x12bf4186,
- 0x037ed5e6, 0xfcd0622d, 0xacdef823, 0xf3b68f1b, 0xb43136a8, 0x255e9feb,
- 0x27a55c72, 0x0bfeda2a, 0xce3b403a, 0xfdcbd6ea, 0xd03e5d78, 0xedd6ea96,
- 0xe50bf003, 0x482c527b, 0x9ce52f40, 0xc7247a7a, 0xefce811a, 0xf461e088,
- 0x157ab026, 0xefc54e96, 0x00ec3241, 0xae7e603d, 0x5b9e6f4a, 0xf972a5de,
- 0xe4c87fd4, 0x9aff287e, 0xda272ace, 0xc4c0951f, 0x780bf344, 0xd96b7e6e,
- 0xa7779074, 0x5e1f6c4c, 0x605c0a48, 0xda931494, 0x3e43d01c, 0xa07ca626,
- 0xffc98ffb, 0xec696576, 0x05261181, 0x8d60b3e7, 0xfaa41f7e, 0x545f2e93,
- 0x9217cfaf, 0xce80921b, 0x1264eb0b, 0xf51f8012, 0xc62689e5, 0x6aa4450f,
- 0x2b0fec15, 0xdf313db8, 0x74c1a44d, 0x1ebb157e, 0xe74799cb, 0xc989b971,
- 0x2ebed56f, 0x2ff36049, 0x7c54696d, 0xd683fcb4, 0x415c9fac, 0x15687da0,
- 0x3b8219f8, 0x4f26ef04, 0xd0fdfc5f, 0xabe71bf9, 0xec7d1fee, 0x8a8f3e7c,
- 0x142f82cd, 0x6f191f63, 0x13fef812, 0x035e3844, 0x99e8d6eb, 0xa8387337,
- 0xf28679f9, 0xeffe430a, 0xa244b7a6, 0x8223b7a3, 0x40d366ff, 0x5fa05f46,
- 0xf1445209, 0xa7fd23ff, 0x9e7fe9f4, 0xb13fdc69, 0xffb421ff, 0x15ff5d1c,
- 0x47fed4ff, 0xddff99f4, 0xd8affab1, 0x906775b5, 0xe7d29bca, 0xba11761e,
- 0x6a929cff, 0xff14bc93, 0xba569be5, 0x4a4e0e80, 0xf3d01741, 0x1f9890a9,
- 0x3f57618a, 0x3e0f4bd7, 0x0f760087, 0x3ffb4afc, 0x3303f4fd, 0x62f97f60,
- 0x7b46ec93, 0x6c39b366, 0xd95afca6, 0x8c9d325a, 0x9631fcc5, 0x0889fd5f,
- 0x7d3d36f9, 0x70f53e96, 0x28c7f812, 0x3f7d70a5, 0x6552fa8c, 0xb07947d3,
- 0x044804ff, 0x0ed8ccf9, 0x80973fc6, 0x129e71f2, 0xce9cb7d7, 0x00f0f513,
- 0xf5a04b87, 0xf0444f81, 0xe64e924d, 0x2fd434a7, 0xc84f7ae6, 0x4e3c4ce4,
- 0x6ff23c55, 0x5e40dfe4, 0x2120f0aa, 0xbb88f7a6, 0x760b1b1e, 0x7fd3576b,
- 0x9c0d04b8, 0xdb3b3e54, 0xe7f1e0b2, 0xe3cbfd3d, 0x45876e6e, 0x9db085db,
- 0x6beb8da7, 0x972d2ced, 0x63f02ec3, 0xdeca3796, 0xbe5cfd20, 0x1f2789f5,
- 0x6df23b05, 0xda62f7b3, 0x97d6d97f, 0xe6813cfe, 0x89c9b6cb, 0x1c32d9d3,
- 0x2f145242, 0x696ffa01, 0xa50f1466, 0xf1497fbf, 0xefdf618c, 0xa3e2884d,
- 0x857edb6c, 0x8f0be98c, 0x95fb2d29, 0xbc0c474e, 0x03cb1cb4, 0xf5dc4abd,
- 0x3f78028d, 0xc9204fb5, 0xd9e031e9, 0x07ea12f8, 0x23c42700, 0xde2f53c7,
- 0x1403f50c, 0x55cf202f, 0x97cb193c, 0xfd037973, 0x3d234679, 0xf83cfb3f,
- 0x7b31df7d, 0xcfc5fd61, 0x7582e9de, 0x18aa909c, 0x32b63f5d, 0x2dc747c9,
- 0x6e498396, 0xe2f7d94c, 0x7a433f0d, 0x67fd7a2b, 0xf35ecc49, 0x6f709aa5,
- 0xfac2a60a, 0x8cdc3516, 0x7e242beb, 0xc7e2bba4, 0x8f9002c4, 0x7f244b9f,
- 0xb8be0c5b, 0x717c6458, 0xb4552362, 0xd04efae8, 0xa0fd076d, 0x6d0c5bff,
- 0x1dc57f42, 0x67fff804, 0x2c9affaa, 0x16e7fcc6, 0x4dafa786, 0xb54f9eaa,
- 0x36bd2d3c, 0xfc00eead, 0x4bea1e9c, 0x80573f06, 0x0f0e4148, 0xafda3be1,
- 0x64b4faf8, 0x91e21f86, 0xaa3b7872, 0xef814c07, 0xf643bf50, 0xdaeac759,
- 0xa3d2ef91, 0xe3e12fe3, 0x60db79d3, 0x44913eff, 0xac625b8a, 0xf2a8a66f,
- 0x35c7dd3d, 0x6fe1a5f4, 0xf74defc6, 0xf956fe31, 0x1f33343d, 0x837b3fca,
- 0x83b40ff1, 0x2bce91fd, 0xfbe58c9c, 0x1e50126f, 0x16384998, 0x9cc9375f,
- 0x2ae5f5af, 0x4b79d09d, 0x5e869c42, 0x8404ffa0, 0x0ab7fa3f, 0x8d3b68eb,
- 0x78c00cbc, 0xa9fdbeae, 0xf9c45b7c, 0xf9ea23df, 0xbe30349f, 0x0abf5fef,
- 0x2e573ee2, 0x147c9e87, 0x67f295f8, 0x2afc03d0, 0xcfbac017, 0xf3fc1f34,
- 0x9c9f294f, 0x54f95169, 0x7c8d3f2f, 0x5c7dbc5a, 0xb33d3e4c, 0x9f362336,
- 0xf931efd2, 0xd3e32d74, 0x53f25bff, 0xc03e5f85, 0xfc28f2ef, 0x1fd87954,
- 0xf0f28d1c, 0xe1079323, 0xf4879469, 0xd3920de7, 0xba54fe97, 0xf4ade953,
- 0x408b8a99, 0xa5d2f4ee, 0x74bd774a, 0x1f5dd2a9, 0x7e0e88ff, 0xa004f2c6,
- 0x05274a05, 0x0de48fbb, 0x6f2cf8a6, 0xb440e767, 0xa790cbdd, 0x36e1f270,
- 0x1e5f6a46, 0x87cda89c, 0x4316f90c, 0x5f219f7d, 0x37efa860, 0xf50cabe4,
- 0xd03fcc43, 0x48215076, 0x7d5d6107, 0x3a093979, 0x57b72fc1, 0x87affb44,
- 0x6d1579ce, 0x1e9cd3df, 0xb079520a, 0xeaeccad2, 0x156540c8, 0x771eafc8,
- 0x790095c4, 0x7b6bd32b, 0x78ae220a, 0xac787e8d, 0xdbf9445d, 0x5af92219,
- 0x1f94457f, 0x9d7f106a, 0xe672bfa4, 0x3a269c67, 0x3d8296d2, 0xc17a2b59,
- 0xecb85d44, 0x3cb81716, 0x5f87da7a, 0x5f7e8b3f, 0xe3c45874, 0x6b9b1e8b,
- 0x048bcc2c, 0xc6aa527d, 0x8249382e, 0x7e089dbf, 0x1f6676c3, 0xd06b5c2c,
- 0xa45ac82b, 0x12c7428b, 0xd522e405, 0xfbd7dfe7, 0x977d194d, 0x1b8afef2,
- 0x7b6ae5f4, 0x3b023938, 0x5f49b4ad, 0xce76e7ee, 0x67bd2a93, 0x17940c90,
- 0x7d80c060, 0x34ebe5cd, 0xb3f5f471, 0x0e7bfc28, 0xe5e80489, 0xf088bb6c,
- 0xceccdb3f, 0x20704909, 0x89254df2, 0xe1535ca0, 0xa17c05d4, 0xba772ff4,
- 0xe735fc76, 0x7ca55a1e, 0x7f63bbe7, 0x9daed347, 0x03dc8f6f, 0xa66f5df9,
- 0xd6fa4bbd, 0x8acfb29f, 0x7d9ed9fe, 0xe94f3c4e, 0xda6afbd9, 0x6ddf903d,
- 0x7b3cc2f6, 0x16397df6, 0xb967a7e8, 0x56e418b9, 0x7f8a50cf, 0xfdecd69a,
- 0xee276c72, 0x6f102b93, 0xd30a8baf, 0x76ffda73, 0x94844854, 0xfff60aae,
- 0x33f4767d, 0xa2b79e04, 0xef67a07f, 0xc77e3997, 0x953d6f3f, 0xc7a4dcfc,
- 0x876d6649, 0x7f33c5f9, 0xf8cf6073, 0xb9c19627, 0x657eeb6f, 0xf29f2d01,
- 0x416337c2, 0x676cf61e, 0xdcb74d7a, 0x05ce01b9, 0xeef352fe, 0xb9c29932,
- 0x1062981b, 0x862bb995, 0x623a0e4c, 0xf41be5c1, 0x3c285c7b, 0x067ffd3e,
- 0xf79e021e, 0x433bb795, 0xfdd60116, 0x4177d1d5, 0x2333ec0e, 0x3debaa5d,
- 0xf50cb2d3, 0x3badf38e, 0xf5f66241, 0x0b759cff, 0x77590be1, 0x8daff486,
- 0x07a25def, 0x83e462f1, 0xf7be74be, 0x756fcc2e, 0x17be717a, 0xff33ef48,
- 0x83ffd7c5, 0xe29dbef1, 0x75fe75dd, 0xaf8bfd57, 0x1fbc7fbb, 0xeef1c39e,
- 0xc0f57386, 0xfce0df0b, 0xab9ca87e, 0xf7e717fd, 0xeaafd6fe, 0x79307fe7,
- 0xf5a0c8de, 0x03ad49f3, 0x2a6b8b14, 0xa0ce1c0e, 0x72187fa5, 0x3be61e30,
- 0x18c39f99, 0x125fb7e7, 0xc164fdb0, 0x891d7684, 0xc75db817, 0x5cc1a1ec,
- 0xa4bc187f, 0xc190f510, 0x7a641e43, 0x83a9e483, 0xa43fbe73, 0xcc62f02d,
- 0xcb7cc902, 0x95f7790f, 0x0bb7af3c, 0x1f10277f, 0x4e0e411c, 0xa043f7fb,
- 0x22190e9f, 0x534afea2, 0x745f5bd4, 0xe5efb3e5, 0xb97ece8a, 0x67b7a3c6,
- 0x76f512f2, 0xdfde54cf, 0x3fe6c234, 0x428421cd, 0x87930e14, 0xfc1126fe,
- 0x962f939c, 0x79f34089, 0xec02bfc4, 0x7d0ea984, 0x19c18f7f, 0x580fc68c,
- 0x16bb6964, 0xaf16dffc, 0xd25dfd80, 0x62794265, 0x0e9016c9, 0x984bd546,
- 0x1ee4dd7f, 0x719e7007, 0x7733aec5, 0xfa97f013, 0x528f1614, 0x5fdefcc0,
- 0x44ddf77f, 0xf0e2e388, 0xaeffa22b, 0x036eff03, 0x7ae8db09, 0x18244917,
- 0x4efe0097, 0xf3afbc81, 0xf0f3ea77, 0x68a4e3f3, 0xdfabe73f, 0xb3fe1d1f,
- 0xee945dd3, 0xdbb0a7df, 0x1c08e90d, 0x53dad25e, 0xe0ced6ff, 0x84857815,
- 0x6ef3b186, 0x2e7340b1, 0xeccca974, 0xd97f5dee, 0xccf6059e, 0x71d19ea4,
- 0xa0471f8c, 0xfae0197e, 0x89e259e5, 0x1f803af3, 0x79e1c787, 0x19d121d7,
- 0x0b6bde2b, 0x819eb3b7, 0xf69a5073, 0x115a9134, 0x41127df4, 0xc9b05dff,
- 0x88c53642, 0x4d94483b, 0xe39c5cfc, 0x3988fe8d, 0xe36787e0, 0xe34da22f,
- 0x9aeb78b4, 0xdb1a4a7e, 0xf3f00f17, 0xe21ce6be, 0xd82f851f, 0x2ddf0075,
- 0x82bcced6, 0x923b7c18, 0x81c66fc3, 0xbe9ed0af, 0x04d1bdac, 0x93597e7c,
- 0x969e7749, 0x3dfd7326, 0xbcc26493, 0x3ab01c66, 0x872f01b3, 0xd9c42f44,
- 0x513fda05, 0x83ce31fc, 0xfe84f08c, 0x9b7a8fc1, 0xed7846ec, 0x00165b91,
- 0x6c7cf75c, 0xed676021, 0x62cb6a56, 0x0a4ff3cd, 0xd222e79b, 0xf4d8e772,
- 0x4ef83d7f, 0x278471ea, 0x44d2bd83, 0xd2fbaf90, 0x3e3a411f, 0x408499bb,
- 0x037d831e, 0x336ce172, 0x8280fdc1, 0xd3b041e4, 0xa55fbf28, 0x692fdfb5,
- 0xec0cf6db, 0x82ed9523, 0x95cb5c1b, 0xfe02a752, 0xbc5b40b9, 0xc33b7208,
- 0xba21c6a3, 0xe1a4dcc7, 0x0964db8b, 0xc2707be1, 0xdc615b9e, 0x0214bb4f,
- 0xc5ef9afb, 0xfee40b88, 0xc859eda7, 0xebadfd07, 0xdae4d5f7, 0xc3f412a9,
- 0x1e919ae4, 0x74db3746, 0xff442bf9, 0x19afe020, 0xde25cee6, 0x96fbf818,
- 0xcb05d9d3, 0x67ffd0b7, 0x550dedf2, 0x02c5f9be, 0x2cbd1f0d, 0x23557db3,
- 0xc96392df, 0x2782c5b7, 0x78bee019, 0xc064f0ef, 0xf2c3e2eb, 0x6df258c0,
- 0xdf3b356b, 0x8fc78e7a, 0xf952b4f6, 0x7c8d23f6, 0x2df2a56b, 0x8b7ff9c6,
- 0xcf5ffaac, 0xff42df23, 0x15b7fc3d, 0xf58c5be4, 0x53f0e41e, 0xf6d8dbe5,
- 0xc6df2863, 0x71749ab6, 0xdccbcf96, 0x7cafd99f, 0x04de0613, 0xd921d4fa,
- 0x3f418f6b, 0xf6feb95b, 0x819f8f1c, 0x7dce4071, 0xdce503f5, 0xe72a173b,
- 0xace09bfe, 0x3bc5b9ca, 0xf69fc608, 0xe72643a5, 0x72a6ef16, 0x647a004e,
- 0x5ef16e72, 0x0638fcc2, 0x8faa36f9, 0xbf58237c, 0x07dacc32, 0xb91fd2da,
- 0xe997f68d, 0x5a16bd93, 0xef2a333f, 0xdde569c6, 0xbbc9fd57, 0xef261743,
- 0x47797076, 0x9030d8e5, 0xf0fa46af, 0x74e3ebb6, 0xd13f8cf7, 0x97e07bfc,
- 0x673c4557, 0xcec4dd7a, 0xfe34fe05, 0x57d03644, 0x33e6c281, 0xd7f46142,
- 0xfec41d5d, 0xd6c8bca7, 0xf160e157, 0x4cad95bb, 0x166cac3f, 0x6bfa1e42,
- 0xf0af84de, 0xaf64a8bc, 0x7e699240, 0x27d599a6, 0x24e7a94f, 0x86867a64,
- 0x96e6161e, 0xa1777fa1, 0xbfe02c44, 0x9de4732d, 0x2cb63d02, 0xcb7bf997,
- 0xc392f7f8, 0xdfc0ab9d, 0xc05eb259, 0xee353273, 0xecbf8d50, 0xbede5e73,
- 0xc681fd0c, 0x3c19f373, 0x33c6664e, 0xc631a842, 0x66d97fb9, 0xa71a7e7d,
- 0x276299e7, 0x26bc8bc2, 0xe0c5377a, 0x2f5eb51f, 0x38710e9c, 0x9fb88935,
- 0xc289c2f6, 0x17de93cd, 0xd3d3144e, 0x70a29233, 0xae957929, 0xf5ffbb37,
- 0xae3370aa, 0x9677f55b, 0x83fa7ef1, 0x3ee70a83, 0x2770e7eb, 0xd2728424,
- 0x95ab8f08, 0x16683f5e, 0xba50a7c4, 0xfc133941, 0x0d7188a3, 0xd62e9305,
- 0x8eb843dd, 0xed564fd3, 0x8c7029a4, 0x7de2133d, 0xfeaddce1, 0x6e21978e,
- 0x9e5bdc6f, 0xaf4ed84c, 0xc3f66098, 0x6b16dbf9, 0x4aa0e504, 0x87408d87,
- 0xf0f7ae14, 0xaa0cf67e, 0x61768c9a, 0x3d06e09b, 0x22b61024, 0xae14035c,
- 0x20242f70, 0x2806fc31, 0x1dff023d, 0x8305ff5c, 0x03c15ee3, 0x753c80fe,
- 0xd0bc02bf, 0x0ced59fa, 0x8090812f, 0x1126c978, 0xd657bbf4, 0xc030de0b,
- 0xe111adaf, 0xfa67caa7, 0x49e2d0e3, 0x2c52bf43, 0x9a4ac5fa, 0xd78cb2fd,
- 0xfdae619b, 0x8cf3d033, 0x88d264a7, 0x7dffa6e0, 0x279f3d1f, 0xa788c3fe,
- 0xb6bc39c7, 0x001d3c02, 0xbbd308b7, 0x3de15fc2, 0x203cb515, 0x9cf07505,
- 0xefb9e8f2, 0x1538d785, 0x20c7405e, 0x89e7dadf, 0x136c2f90, 0xbef480c8,
- 0x307385eb, 0xec97bf2d, 0x7ffac63d, 0x1892f04c, 0xba60beeb, 0x8b9e87ee,
- 0x7f82dd29, 0x36ba3fbd, 0xe151a9c2, 0xe7a726fb, 0xaf23593f, 0xef3d0164,
- 0x49cf9015, 0x3ceebc7b, 0xf4c2bf6b, 0x4a562d88, 0x91dd74f7, 0xa377b2c3,
- 0xd83cafa7, 0xf60be1ce, 0xd01ef683, 0x8810b0a5, 0xc16cdc0f, 0xc79c2f38,
- 0x6a9fa630, 0x2b56f3e5, 0x76537819, 0x7987fdff, 0x47e9fdff, 0x8c0c7e6a,
- 0x6dcd7107, 0xd151bc74, 0x83fb8cf1, 0x6f9ff76a, 0x3972af5d, 0x4baef7f7,
- 0xc687e71d, 0x074804c1, 0x878d55e2, 0xc7f82239, 0xe5cfa0c8, 0xae3e920b,
- 0xd6e5c22c, 0x1fffdc3f, 0x927fafbf, 0x4e7bc6e2, 0xefd5ba77, 0x02cfa46e,
- 0x41e7e137, 0x7d84df13, 0x3b1f53ff, 0x9136caf7, 0xff611323, 0xa0132c98,
- 0x915f4fab, 0xe9f96fd1, 0x79671654, 0x2507abfd, 0xcf5cdd70, 0xf5c8a162,
- 0xb3b404e3, 0xc7ae875e, 0x216e1e83, 0xbf0891be, 0x954fb82c, 0xc53b54d1,
- 0x733af943, 0x5206a873, 0xe24894ef, 0x936f009f, 0xeb780244, 0xe2980df0,
- 0x3f3bf9a0, 0x32e01922, 0xb601faa3, 0x06443ccf, 0xbe09bd42, 0x8cc66881,
- 0x8decfd6f, 0xc63ce91b, 0x3d7a22bf, 0x83ccdeb4, 0xfaa1070e, 0x1306a8f4,
- 0x35e06bf1, 0xc06a8481, 0x43fe346f, 0xef308ddf, 0x40efaa62, 0x7b717efc,
- 0xf20b8d63, 0x0fb6020d, 0x2e79fd04, 0xf5ad9eba, 0x0e5de49f, 0x83d68172,
- 0xac0d026e, 0xf049a05e, 0x616a4842, 0xe5053afb, 0x17809346, 0x0486b6bd,
- 0x86fd6162, 0xaddfb42c, 0x367db40d, 0x3db45fec, 0xc9f4dbf4, 0xdc82371b,
- 0xf6c4f3a1, 0xb63ceccd, 0x00f3b690, 0x81dd34bf, 0x083495fd, 0x1419ee04,
- 0xa97db337, 0x0bd915f8, 0xd7fbade5, 0x9d3b7ee3, 0x0e9a978e, 0x2a7850fb,
- 0x12c8d7de, 0x6d8f78dc, 0x5fc450fa, 0x23f8610f, 0x1c984389, 0xdb9e7813,
- 0xf7deaa3d, 0xe430f32b, 0x32ef4283, 0xe7ed0065, 0xd303b94f, 0x9f57484d,
- 0x7da7a028, 0xa7ede148, 0xc79d7ef0, 0xfdcc1c29, 0xecd4e940, 0xe1e6cd8b,
- 0xdb617ed8, 0x5a7f8c24, 0xfcf00a44, 0xa678c67e, 0xa576be6f, 0xbafe0435,
- 0x10c8e4d7, 0x4af07ef8, 0xdeef7e33, 0xf770e4ca, 0xcff44ed0, 0x0990689e,
- 0x69a82fdc, 0x9c5e5110, 0xbcf19668, 0x464c7c5a, 0x95b45db9, 0x1b071fe9,
- 0x4027bf58, 0x393f036f, 0xd17cd394, 0xfbdb8116, 0xf6ab4e4c, 0x9d9ba167,
- 0xb772abbb, 0xcfbbaf82, 0x4cb7543e, 0xca359201, 0x8f2e0adb, 0x02a4a94b,
- 0xddca3342, 0x7577380a, 0xe31a5f01, 0x3b511c83, 0xfc20e806, 0xe575d215,
- 0x3b01322b, 0x2ba0f846, 0x6a7de60f, 0xee7e80af, 0x0f82edf1, 0xdf8bbdce,
- 0xff508732, 0xfb9bcd0e, 0xde5fd80b, 0x55081336, 0xa0780e3d, 0x1cd72a72,
- 0xe86fcbf9, 0x5baf53f7, 0xd2841220, 0xbb843ccd, 0xbd99df1a, 0x6471c589,
- 0x04975ebf, 0xd4c92cf7, 0x8a072801, 0xd7e245ea, 0x825389c8, 0xb29fc6ef,
- 0x8dadc1fd, 0x6a56cce3, 0x3d7f610b, 0xd1f2666a, 0xd88649b3, 0xccd2b208,
- 0x0fb534e4, 0x64b2fe30, 0x4524baf7, 0x7b250743, 0xf48925d7, 0x071e2afb,
- 0x2bfb0351, 0xb0a2576d, 0x09f64a71, 0x38cd46ee, 0xbf6a3f6a, 0x6ed66eca,
- 0xf6965ef8, 0xcc097fd7, 0xb9f9d70f, 0xd8c2f202, 0xfbf19f4f, 0x3ff727e9,
- 0x7409d5cf, 0x89afb95e, 0xfb9ca418, 0xdae1f4c1, 0x55350073, 0xde7215e3,
- 0x069f1130, 0xb17fb97e, 0xdf069f11, 0xdf28e3ad, 0xd75dfc53, 0x02ac8426,
- 0x15298fe4, 0x037798d9, 0xff72579f, 0x7654e573, 0xf19ad3be, 0xfbe00afa,
- 0xd202d9e9, 0x95fa0903, 0xafa88901, 0xb8ce2079, 0x2fb59b28, 0x1f81eda2,
- 0xfe33d75b, 0x03c272a4, 0x61b2a472, 0x6fd61e5d, 0x7fd03c12, 0xd43ce36b,
- 0x45738a47, 0xc74de582, 0x6e2a3f50, 0x7c08963b, 0x0eb6f94c, 0x89ca81f4,
- 0x71c83766, 0xfe551f95, 0x05c78d7e, 0x0c7b8b13, 0x0067e3c4, 0xcbec0df3,
- 0x4c2be2d7, 0x199a07ae, 0x1972063f, 0x55b6bebf, 0x085e1586, 0x9f3f237f,
- 0x55f8ccd8, 0x3ce6ec7c, 0xb45ca7b8, 0x1ca7c589, 0x80a2986c, 0x24227d3e,
- 0x97d37ee0, 0x6ade99bf, 0x811aefe4, 0x543f7bed, 0x5bf954bf, 0x73fa63e5,
- 0x4e578c1d, 0xb5ee14f9, 0x867af919, 0x3be7f2dc, 0x7faf7ce9, 0xce87ae96,
- 0xef8fca77, 0xe46a7576, 0x4127cd24, 0x716250be, 0xa95caa3c, 0xd7bc5890,
- 0x619f9e0f, 0x7acd1bfc, 0x734ac8ff, 0x6e6b8b3c, 0xcfee9192, 0xf87d9fc7,
- 0xf3f902ec, 0x7ceaf942, 0x2f8ea9fc, 0xb3f7d5ee, 0xb19bd392, 0xd70a6ebf,
- 0x1feb8530, 0xb8c09f9a, 0x3e9f8fb1, 0x53f00336, 0x39d287b6, 0x93b357d0,
- 0x49ce4184, 0x4aafdc21, 0xc61f455b, 0x9ce14abf, 0x3e5a9d1b, 0x653e7166,
- 0x9e9139cf, 0x439bb74a, 0xd2fb69d3, 0xc58c1f9d, 0x11e58bb8, 0x3e0a438c,
- 0x60e5f5cd, 0x83e058e7, 0x1bc58952, 0x00c2e519, 0xe8673b0b, 0x059f6dda,
- 0xb33613eb, 0x2da5fd7b, 0xcd66c8b7, 0x22cd84b9, 0x1cf0f5ab, 0x18e94830,
- 0xfcc255ee, 0xd5c9f7b4, 0x2daea338, 0xb6944e4c, 0x960768c9, 0x0dd6de6e,
- 0x6fa5a371, 0x15dfd199, 0xc609fcd8, 0x6e794fc1, 0x0253fa2b, 0xfceea26d,
- 0xdebc4fac, 0x866c3166, 0x0ad6b378, 0xf9a3ef3c, 0x896f9863, 0xbe7ab71d,
- 0xe7b2b2b8, 0x520ceef6, 0xfefd9610, 0x97c81729, 0x5c9b1dd3, 0xf9b7b718,
- 0xfb65e3fb, 0xdcb5e7c4, 0x79f1bdf7, 0xca17e1a7, 0x862d1338, 0x03cdc6f8,
- 0xf3a48f50, 0x718829cb, 0x97abd1ce, 0x037cfd6f, 0x6d778fc4, 0xe601b33f,
- 0xa7edfe5b, 0x887e201b, 0x7ee2b3ec, 0x08fa7817, 0xedaadfc6, 0x7ee1627e,
- 0x614f2d8f, 0xdbf772dc, 0xd6f42f66, 0x1a44f7bd, 0x6f758fc4, 0xfc092afb,
- 0x4ef64b96, 0x92eebf43, 0x4992531d, 0x4d42fd8c, 0x17436e81, 0xc46d3710,
- 0x83d6c1d7, 0x31f4e718, 0xbfc837c5, 0x96cb78de, 0xeabf160a, 0xcd9671e1,
- 0xfbd3e3b1, 0xdeb655c4, 0x2095fd78, 0xfe995bf7, 0xcaf8de78, 0x7f1e2837,
- 0x6bf80174, 0xb102fd56, 0xfc31f7f1, 0x76e21e32, 0xbcfbf8f5, 0x8fe3d175,
- 0x80eb5942, 0xc32be37e, 0x35370017, 0xc5927dfe, 0xbe016d57, 0xc60cfed9,
- 0xa6de02b3, 0xf9ff607b, 0x0dee0d3c, 0x7323949c, 0x5ed93ef0, 0x09e21bb3,
- 0x89bef74b, 0xe3bdd3fc, 0x1343f475, 0x4dde871e, 0xdc587f7a, 0xd9d7c0b0,
- 0x997164e4, 0xb710fe1c, 0x77e171e9, 0xe8c99f1e, 0xecdb8d58, 0xa7735e2f,
- 0x6ad9e985, 0xd3457e5c, 0x31fe3cbb, 0x17212f8a, 0x7bec74f0, 0x70a811ef,
- 0x1c397370, 0x1d8e3f8d, 0xa71bdb17, 0xf805f1ce, 0x37a87d83, 0x87e698be,
- 0xe8dfa264, 0x1e43124d, 0xb8b23774, 0x7f596ee5, 0x1f8a33df, 0xcdbc8f16,
- 0x0ba1a7c8, 0xdf3e438b, 0x7c287ffc, 0x33f28236, 0xba9c2fb0, 0xc72d8ebe,
- 0xff7ce0df, 0x5967df77, 0xb3ef1828, 0x63d027fc, 0x0531eb45, 0x3b5ee0ec,
- 0x8bb7af9b, 0x9ebbd5fb, 0x759e3116, 0x9441cb55, 0x517946e3, 0xc458ef09,
- 0x0b71ef98, 0xd8dbc3d7, 0xddb5d13e, 0x7ed07219, 0x46ec0eba, 0x3e6cae7a,
- 0xe09c40a6, 0xaf7f9bcb, 0xc629f3b0, 0x844fb03f, 0x7aeff334, 0x1658ff76,
- 0xf8fccd6f, 0xe33e71c6, 0x63da04e3, 0xfe68138f, 0x594e3744, 0x3b7145b0,
- 0x69de3fce, 0xf40b77c9, 0xe983ba77, 0xc45ba783, 0xb9f758fc, 0x66fbe4de,
- 0x743d7bef, 0x4177c4bf, 0x101dec9c, 0xfd4365d1, 0xf7338972, 0x4844b8ad,
- 0xa9ef8c15, 0x81e3c659, 0x014de97e, 0xaf38d77c, 0x95df3025, 0x9f8d5f00,
- 0x09fb7647, 0x4a72a5e8, 0x15f83641, 0x4946f28c, 0x06909134, 0xf99c4bff,
- 0xef3c1ec9, 0x7c010f08, 0x2138cd1e, 0x19efbf43, 0x49ef54fc, 0x9d325564,
- 0xc1417bdf, 0x4bf68cbb, 0x6860febe, 0xff6fb381, 0xaf7fde6a, 0x552bf3a8,
- 0xc147239a, 0x582f212e, 0xdc41be31, 0x17f7c567, 0xb8ac1b02, 0xbe3b83de,
- 0xebf5127c, 0x9d84cdc7, 0x85eb50fb, 0x9b915fd2, 0xc76271f5, 0x06fe1b97,
- 0xa63433fa, 0xa06d17e3, 0x686ec1f5, 0xd39da3b6, 0x2c6e3db3, 0x5e8a45f8,
- 0xc80667b8, 0xa33b22b3, 0x92e7a2c7, 0xbfb43543, 0xfe5903e3, 0x78a1d6f8,
- 0xbb6cbfdf, 0x0f0ce313, 0x0955d8ee, 0x73f752fb, 0x52fb0276, 0xcf5c0bf7,
- 0x1fbf867f, 0xb47b2f54, 0x4425c6f1, 0x71ef68f2, 0x959e4194, 0xfc107de3,
- 0x047ce1c9, 0x38b6aafe, 0xf541ffbc, 0x1f3f5d5f, 0xbcbb91cb, 0x41c1c748,
- 0x784bdeec, 0x6303c810, 0x4afcb53d, 0x8f7e30eb, 0x4473b698, 0x489407eb,
- 0x0ed7cb21, 0x03a4f262, 0x656b5feb, 0xf796affc, 0xcfd597ed, 0xd5d30eb7,
- 0xf257db53, 0xf48c41f7, 0xe055b37b, 0x2e6fc1fe, 0x45fef589, 0xf7e3f98c,
- 0x6824099f, 0x9b653d02, 0x8225df15, 0xdf10f37b, 0xe76153be, 0x30aee55a,
- 0x87b23fbe, 0x5b72e3cb, 0x1943df18, 0xf501e7c4, 0x9d2c4f21, 0x56bbe2cf,
- 0xde04acbb, 0xc178a9c7, 0x577c03e9, 0xf8f2fcec, 0x8e21b2ef, 0xd4718ecd,
- 0x1cfc2f15, 0x1cc2a0e9, 0x10fc039e, 0x1b2666d9, 0x1db7cf81, 0xed7e034e,
- 0x0969c392, 0x575e73df, 0xbc3662d1, 0x71d6c01f, 0x0afebaba, 0xdeace7b8,
- 0x47ed2ca7, 0x656b3cce, 0x585fe87e, 0x78ad4b7d, 0x677fadae, 0xacf574e7,
- 0xaf57b82c, 0xc4b52fd6, 0xad6b8b96, 0x4f763ff2, 0x5ee7d1d8, 0x40eb5ae2,
- 0x923a63d0, 0x4953efc0, 0xe7906ef5, 0x87d39ba5, 0x80e09f80, 0xee77bd55,
- 0xe8fd8389, 0x7b41ec80, 0x3eed521a, 0x9bdab273, 0xff008d25, 0x892ca8cd,
- 0xf1a7a3ae, 0x0441c293, 0xb3ad0ee2, 0x0dbdc962, 0xa3c23b56, 0xc5f662d4,
- 0x0cf8d7ba, 0xc107d7a7, 0xc6c71fe8, 0xc750fe03, 0x5087203d, 0x79b70f0e,
- 0x2ed43f58, 0x9b65ef82, 0xdee96767, 0xb16a90c5, 0x8453e51e, 0x53a90967,
- 0x5bf235b2, 0x6964af1d, 0x05949676, 0xeaffa5df, 0x8a3157a5, 0x444c1267,
- 0x30e250bd, 0xbaa97526, 0x5c9204fb, 0x29f80160, 0x892dc0a4, 0xc8b52a40,
- 0x82d236ef, 0x5baa83a9, 0x2aa8fdec, 0x64f27202, 0x0417bbef, 0xeebc28d3,
- 0x1c1fb946, 0xe9c5c84a, 0x13dfff70, 0xafc0d6e7, 0xf9c2eacd, 0xc22aa598,
- 0x3774c5e4, 0xd04223e8, 0xf4a3be4f, 0x9f9d5354, 0x7f48f405, 0x0cff707c,
- 0x3f3a0f4d, 0xafe5fb97, 0x74a20f40, 0xfb59deca, 0x50d50931, 0x28f84310,
- 0x132755fa, 0x9ad83ef6, 0xded688b7, 0x6fe72bf8, 0x728fdc12, 0x3fa241cc,
- 0xb1079a11, 0x26b6f20a, 0x385cdbee, 0x49b87447, 0xbb42f418, 0x34ed8483,
- 0x4e968c75, 0x95dff96b, 0x3a1af34d, 0x97d44f75, 0xca82f91b, 0x2db8c335,
- 0xefda3f08, 0x3f7e8667, 0xd9fbf433, 0xc2abf5f7, 0xe8d96029, 0x5609f785,
- 0xb8701756, 0x1c2cf1b1, 0xa33e146e, 0x62337de0, 0x79f979b2, 0xc6d5c238,
- 0xfa866367, 0x6c83af14, 0x07a708e9, 0x2045f6e2, 0xd624966e, 0x577bb013,
- 0xa69f6c08, 0x4d0e053f, 0x20b6e23b, 0xc7c7de1f, 0xf4636419, 0xef5bdeae,
- 0xe78adf5b, 0x5bea7d1a, 0x8b6fabfb, 0xdfd9df5d, 0xe731ec7c, 0x4ce543f3,
- 0xfe6f0be5, 0x7b61ce09, 0x829b8de5, 0x6f274732, 0x9c28d906, 0x7f8fe22a,
- 0x985f89db, 0xa21968de, 0xe80d9fc7, 0x6d8fd295, 0x11bbfe84, 0xcbd1fdef,
- 0x9a0ebe3c, 0x75d2a477, 0x3f8f94fd, 0x639d89b5, 0xf984b6df, 0xe7b9a8dd,
- 0xf2b7fa83, 0x14b53ffa, 0x18e0ffa1, 0xb6e9177f, 0xde17a67a, 0xe788af76,
- 0xfdde7dcd, 0xff285f81, 0x0854bedc, 0xbd63d385, 0xe09a4463, 0x3e5cd47e,
- 0x205df1be, 0xade4f13f, 0x0bbd6311, 0xbd4ce8c4, 0x6f7c6557, 0xe0292160,
- 0xbfe93def, 0x91bab26f, 0xd61e410e, 0x4bee8e8e, 0x8e9475c1, 0x74a49f41,
- 0x70ece70c, 0x3ce3063d, 0xf38b0a5c, 0xe78a18e8, 0x3b3caa63, 0xe1c4f1eb,
- 0xd34deafe, 0x78b817bd, 0x5e3927bc, 0x73a5af23, 0x2b7bdd36, 0x0537b235,
- 0xee7c95e4, 0xa6a1e232, 0x1e8d42af, 0xea9ca68f, 0x10ccc8a1, 0x277284a6,
- 0x9c810a45, 0xa405dc93, 0x9958f408, 0x5f5aa7d1, 0x57acbc49, 0xfe8d7c6f,
- 0x878801bb, 0x3be2e5d2, 0xd728c93c, 0xe00b05ed, 0xf5cae893, 0xe97d1dfa,
- 0xad95b821, 0x9dd606bb, 0x353d77de, 0xfa8bd78a, 0xf7de84f3, 0x3f302c69,
- 0xd379ecd1, 0x0ffbf303, 0xa51f8099, 0x27bc7c2f, 0x677e1443, 0xde318343,
- 0x3e9b8c43, 0xdf57c612, 0x9d535c45, 0x2bade782, 0x2b897bf8, 0xfe6147aa,
- 0xe59efe7e, 0xa60f6aaa, 0xde2cfc2a, 0xcfc77c5a, 0x6ff58232, 0x24fc7371,
- 0xfc7c389a, 0x52592fa8, 0xd01cf0aa, 0xc30aaeea, 0x086459fb, 0xda6027dd,
- 0x9f845aee, 0x87e826e2, 0x6f31f5a4, 0xe54d3c86, 0x0f88d1fa, 0x8a455dc9,
- 0xddbe7968, 0xcdc020ff, 0x7ba419ea, 0x329cd01f, 0x03df7bec, 0xf5a7a5ec,
- 0x72262e4c, 0x27c2327a, 0x65ef6151, 0x9fd474aa, 0xe3c3555e, 0xf6ae1f74,
- 0xdfc35a62, 0x7781aa81, 0x3d48147f, 0xedc81f98, 0x470a1ac4, 0xdf08fef8,
- 0x73aa6b37, 0x972cfcb1, 0xaaa68957, 0x25c032fd, 0x66ff3081, 0xc90c9062,
- 0x14042c21, 0xc482527e, 0x9cf57903, 0xe6c69dd0, 0x7441e9cd, 0xdc77864b,
- 0x5e008f3c, 0x26cb0eea, 0x4b8b93f0, 0x681f25af, 0xe59c59e8, 0x99bf078b,
- 0xb00bf0e8, 0x78003dff, 0x4759f3a5, 0x96ef85e7, 0xc9587a72, 0xd39abef1,
- 0x1f407dc3, 0xd3907d34, 0xfae8afc5, 0x65e35f21, 0xe6d601f7, 0xc4b778b3,
- 0xc77f130c, 0xf1b44c2c, 0x16def164, 0x2275d0a2, 0xc5307a8f, 0x5bc8ea77,
- 0xfb17a466, 0xa113e268, 0x43bbadfc, 0x82c91dec, 0xe337d854, 0x272377d5,
- 0xe367e27a, 0xc4b0d545, 0x991373df, 0xf311d1dd, 0xef1ac67d, 0xefd80b01,
- 0xeec7cdfd, 0xa4afa5f5, 0xd9ebd9e3, 0xfe01c5bd, 0x688bd982, 0xf54f51de,
- 0x8ce5026f, 0xde741d2e, 0xc67d1a45, 0xbffd8fde, 0x51cd7ed4, 0x7be7c51b,
- 0xe45141b0, 0xb87ebaff, 0x614be015, 0xc73f01ed, 0x2a4172c3, 0xf1c3fff0,
- 0x8735fdb1, 0x83d2326d, 0x1d32fb2b, 0x3ec9d73d, 0x989ee76c, 0x3afba3a9,
- 0xa612772e, 0x577dd04e, 0x6defcce5, 0xb12eef4c, 0xbcc2cffb, 0xc5d1ce92,
- 0xbc4a7e51, 0xa9dcb621, 0xdc209591, 0xc319afdf, 0xa6705ce4, 0x3eabf4c2,
- 0xa7c98472, 0x6f32e4b3, 0x645f4350, 0xf03d4114, 0xee8a998b, 0xc035c1dd,
- 0x7e5e941f, 0x057ee9cd, 0xc54d01f0, 0x4dd20a11, 0xda1374c2, 0x5f38aba9,
- 0x68f9cfdd, 0x87a3e72d, 0xc2467f80, 0xdf8cae3b, 0x051de224, 0x8b8d48fb,
- 0xc0258fbd, 0x8d49b4ff, 0xe85cfe6d, 0xb32de6af, 0x350fe700, 0x11752f92,
- 0x977e29e4, 0xef8f307b, 0xedeb06ea, 0xbbf1589e, 0x9293ed4b, 0xc95e14ec,
- 0xdfbf8676, 0xfe2167d4, 0x316f6e2c, 0xd8724bac, 0x19afaed0, 0x658e2969,
- 0xbdecd81f, 0x53b74ef0, 0x9fc80f78, 0x817f6bd0, 0x666ea17b, 0x37fdc20e,
- 0x06399f70, 0x33b18cfd, 0x04864079, 0xff0d08c9, 0xdcf7f1d7, 0x46482788,
- 0xf2c0e469, 0xf808f38b, 0x7ff2fa77, 0x136ff23f, 0x02357f93, 0x780c57df,
- 0x5531f755, 0xd78049fe, 0xb9e77d01, 0xdd5ca2f2, 0xcb997b3d, 0x3cbd636f,
- 0x4f9d9dbb, 0x2fc46f11, 0x70a72df4, 0xce6bb3ca, 0x09c49495, 0x5d95efbd,
- 0x461d6315, 0xf61277b9, 0x9225903f, 0x5905df1f, 0x191e78a8, 0x8fe4f20f,
- 0x3fa5fe2c, 0xaf1d40fd, 0xee315ce8, 0x72e785f3, 0xae299f71, 0x20fe45cf,
- 0xd8d78de0, 0x7e1a2749, 0x9dbc02e6, 0xa3e7e7a8, 0xe208720d, 0xbc6ff652,
- 0x14d9a1e7, 0x88370b9e, 0xd7fefeec, 0x6a277ddf, 0xb6481be2, 0xf53af507,
- 0xa113b43d, 0x73da5d3b, 0x58dfc2ec, 0xf62fa07d, 0x3614cfb7, 0x6bdfb6c4,
- 0x53d057e0, 0x1e801f29, 0x4881f54a, 0x5f85f418, 0x08bdf15b, 0x68dc1f35,
- 0x540ef98f, 0x195a7dbe, 0xddbe67d0, 0xc4a42777, 0xfafe8091, 0x8ea1e6fe,
- 0xa67c1c7b, 0x28f64e70, 0x70a5b38f, 0x9ff3a99f, 0xe3b273b1, 0x2c421fdc,
- 0x78db94fd, 0x729fa7b9, 0x21678b17, 0xeae5d8ee, 0x3b714e7c, 0x7b46e170,
- 0xfd8c7968, 0xefbf217c, 0x479f90b7, 0xd53ff8a8, 0xba3137ab, 0x3f2ffb51,
- 0xdfe18a37, 0x53c26740, 0x3eae9063, 0x7fa3243d, 0x4aea784d, 0xf2a52f7c,
- 0x97eb059c, 0x415fde8b, 0x4d79161c, 0xf3bbba44, 0x873c38f0, 0xc3bc32ea,
- 0xb7f387b8, 0x2b9e169a, 0x8599e9d5, 0xec0a05a1, 0x2ae785cb, 0xde211e91,
- 0x1397ee11, 0x934bf6f2, 0x13574e24, 0x6991fda0, 0xa2bd69cb, 0x64bf464e,
- 0xfd12b062, 0xef768d84, 0xdae431fd, 0xe747bb1e, 0x2cea2837, 0x2389fec7,
- 0xe7351248, 0x7bf90bf5, 0xd8e745e1, 0x1dc4847b, 0xcf402924, 0xe944de5c,
- 0x6c6eff52, 0xcbe18997, 0xf857deb8, 0x5de95f3a, 0xd67e84ef, 0x5eb663fb,
- 0x7517cfbe, 0xf5d61ae6, 0xd6b1f1bb, 0x44cf5d15, 0xdfce5f6c, 0x31372df9,
- 0x9fe5abbc, 0xf4d5f1f3, 0xb82cf578, 0xf84a4361, 0xa185903b, 0xff78153b,
- 0x3e21b0a8, 0xb3acd041, 0x5d56fea8, 0xfd61495c, 0xaaff7c3c, 0x329e61a8,
- 0x7a47235f, 0xecfc14f1, 0xa22349a5, 0x81fcfa78, 0x1dcb699e, 0x1c14afb0,
- 0xfe3b3e03, 0xe79cc564, 0xf0cbf409, 0x8e095276, 0x72b942ad, 0x3dd62ba7,
- 0x788dcf94, 0x1b78e7ab, 0x35a32411, 0x97c54672, 0x4df1fdb1, 0xf9c17765,
- 0xecf5f1f4, 0xe5fe8f75, 0x1a7c6c4c, 0x3076e8e1, 0x71e9a9f8, 0x2ffb2fba,
- 0xeb978e08, 0x85fa9be2, 0x0abfc723, 0xd53bf527, 0x1c0eacab, 0xa37bb097,
- 0x0417b9f5, 0x8cf8e8bf, 0xbe2a4e3e, 0x7e41eb91, 0x7c093951, 0x07c9ea7a,
- 0xe5db6ac6, 0x840d27db, 0x85ed4871, 0x6fdd8f9d, 0xfd41a7f7, 0x21ef64e0,
- 0xd15bca0f, 0x5dd7435b, 0x7768f712, 0xdfab5718, 0x935656bf, 0x4a5fc12b,
- 0xc12b87ed, 0x05b5436f, 0xe6a8a3d4, 0x847d05e0, 0x7ac5f156, 0x83926a17,
- 0x5656b3f9, 0x95bfa157, 0x0dc48258, 0xf8c23d7e, 0x42cc9c92, 0xd0e497ff,
- 0xec8a01eb, 0x4dbf8377, 0x6591f7e1, 0x3d26bfc9, 0xc4d9ec1b, 0xbe06a08c,
- 0xbc583957, 0xc594dac4, 0xb7438841, 0x38719f80, 0xeace37fa, 0xa517fbec,
- 0xdd280385, 0xda7dcfa9, 0xe5cbe846, 0xfe8216c4, 0xbbf4d1b4, 0x74891e76,
- 0x4c7dbade, 0xe2c9170f, 0x890f73c2, 0x8715bf70, 0x7282fd07, 0xc3973578,
- 0xdc2eedcb, 0x645d567f, 0x8ea0fb42, 0x0b7ec3fb, 0x8b84307e, 0x84327684,
- 0x257d40dd, 0xb0eb882e, 0xd0447ac2, 0x7798c3db, 0x22328bc2, 0x4025b13e,
- 0x04789e3e, 0xe1200fc8, 0xf687a055, 0x0bbcea4c, 0xfd58a7be, 0x5fbf01b3,
- 0x151c76a4, 0xe05a0fc0, 0x5ce004bf, 0x3c33062f, 0x62e3feb4, 0xa5ea0324,
- 0x12b7a2d1, 0xc4117a58, 0xe735fb41, 0xce1dec2b, 0x9bec5e68, 0x64a968bf,
- 0xfaf86f38, 0x2ff96d12, 0x0762beac, 0xf656fbec, 0x07e24d7e, 0x9ab9ca02,
- 0x01773f5e, 0x71a9dbde, 0xd23d7f30, 0x21d5d005, 0x959f4fb6, 0xe809713c,
- 0xf5951b3f, 0x5e1e6ea2, 0x76e25e5d, 0x53a5134d, 0xf4ab8bf0, 0x99f24231,
- 0xae2e8e80, 0x78b5dfa5, 0xc15fa18c, 0x39fa2338, 0x47e7504f, 0x157a45c7,
- 0xfdb0e5cf, 0x7b0f40d6, 0xa0ff3604, 0x0fecced5, 0xaf011412, 0x93c255b3,
- 0x3c7cb056, 0xddf07f51, 0x3f55b7cf, 0xf2c15937, 0xcc0b966e, 0xc66ae767,
- 0x5f6eccf9, 0xe5fe01dd, 0x0ba9edd9, 0xb6659ce0, 0x208ff2e5, 0x0e4723dd,
- 0xfc4e41d8, 0xf9a3bd8c, 0xca2f23d3, 0xbc778a20, 0x43ef11b1, 0x71f9ce3f,
- 0x80c8890e, 0x2b713f7f, 0xc21e4fcc, 0x5e27cdf5, 0xc1916f9e, 0x1c2dbd7e,
- 0x9a3af9ba, 0xd0c5fdbb, 0xcd5a6075, 0x09791439, 0x716fe6d0, 0x5a2fa1e7,
- 0x7de6d76d, 0xbb59e599, 0xdff81c28, 0xb82c90c1, 0x2dbae8ae, 0x9d750708,
- 0xa3e226b4, 0xfdfc4e17, 0xbd2e1520, 0x7adfb6eb, 0xfb0bf82d, 0x2db36f93,
- 0x71623e63, 0x465e6cb9, 0x45067d38, 0xc3915ef0, 0xf2e807b7, 0x1daf8761,
- 0x12dca4f8, 0x21869349, 0x5f2184df, 0x4a2ffa29, 0x78f870a2, 0x8192ffa8,
- 0x018e8f00, 0xbe67a417, 0xd5fce9ca, 0x83f7def4, 0xbe99d113, 0x66c1f986,
- 0xb55b7a70, 0x9b8c4de3, 0x7b30f8fc, 0xf442a90f, 0xfa0f7f5c, 0x4b1244bf,
- 0x57d355ef, 0x2de61fb9, 0x9d1f7a87, 0xc48673ad, 0xd5a33de0, 0x667af78e,
- 0xfd3a8b64, 0xc0b6467b, 0xc63ad7e3, 0x4bd3a4de, 0xeeba7057, 0x11c40fdb,
- 0xb059fb18, 0x55da3274, 0x24f7153b, 0x0dc1ff90, 0x4c16ce8c, 0x671089f5,
- 0x808d613c, 0x1ff188fe, 0x87901276, 0x09e2ea0b, 0xb82f839c, 0xbc16717b,
- 0xe1d95097, 0x3904eb69, 0xe0bc1219, 0xef164b47, 0x9d25f8c8, 0xd807c3d7,
- 0x3bf90c3e, 0x9f0e9e60, 0x2bf1a1c7, 0x1955c977, 0xdbeba06e, 0x0b903e1d,
- 0xbdf26ef3, 0x922d780d, 0x76b5fbc2, 0x3cdbbcc8, 0xf31f40b9, 0x4c3eac5a,
- 0x51b2442d, 0x224f36b9, 0x15934816, 0xdf215922, 0xece7d4fe, 0x3bad86b0,
- 0xec2c46d9, 0x80afe1fb, 0xacdf2e4e, 0xa63dd6e8, 0x51ff9f45, 0x119f3e9b,
- 0x0eb3e7d6, 0x80b7f3e9, 0x87d1a31a, 0xe765ec0e, 0xd86765dc, 0x05e7c13d,
- 0x7fc083d8, 0x37b9466a, 0x073daca5, 0x3ccf4dce, 0xf94134eb, 0xfd986f9e,
- 0xc562d916, 0xbff6cbf7, 0x44b62363, 0xbad4c778, 0xd8cfca11, 0xffc0725a,
- 0xfc63eb44, 0x4735dd03, 0xf3b1fd82, 0x0cced532, 0xcec49c61, 0x7b9c596f,
- 0x04398b64, 0x7667b1e7, 0xd02cf53f, 0x832d99dd, 0x5e79ef51, 0xdfa09a08,
- 0xaf0c7de0, 0x9d2e6c13, 0xacdb29fc, 0x3846ebb7, 0x73d53e99, 0xf10b994a,
- 0xebd4974f, 0x48697dd7, 0x64ed1f9f, 0xd13e67f2, 0x73874f7c, 0x14aacf66,
- 0x48278ba0, 0x5983fbcc, 0x9f7f264e, 0xed515a7e, 0x33bf916c, 0xd1493c46,
- 0xa27b4f7b, 0x064b3fe7, 0xc0001c43, 0x7bf45862, 0xb55c6199, 0x7cb96fff,
- 0xfa7ee44f, 0xc222abc8, 0xb17574e7, 0x57b89cee, 0xa6f6ad3f, 0x33ecd54c,
- 0x93fbf585, 0xb85ea1e6, 0xd6be693f, 0x3072db2e, 0x738856e9, 0xdfe12cd9,
- 0xfd9f2a4f, 0x121343e4, 0x02d8bbe1, 0x1f7285f3, 0x2f2d1fd8, 0xd51ea0b9,
- 0x71b5333f, 0xe3f54523, 0xf66aa652, 0x974a1fd7, 0xbb4aefbd, 0xe5767c19,
- 0x1d78dc16, 0x835977c5, 0x656a85e8, 0xfbff372d, 0x837b8018, 0xcb5cf78c,
- 0xbef8c9b7, 0x0af1a079, 0x359413f4, 0xef879ebf, 0xe79fade8, 0x48e57985,
- 0x44cc40a4, 0x904dc0d7, 0x81df6c9e, 0xfd95d5ef, 0x3c914eb5, 0x7d3d5f30,
- 0x3f437a50, 0x7280d517, 0xf01e006e, 0x54f8c32d, 0xae11bbf5, 0x7b7d2125,
- 0x17febe23, 0x33fa37a7, 0x63778b4a, 0x83d301bd, 0xca4877f8, 0xa3b95297,
- 0x3fca2fb1, 0x38f8c5ac, 0x542838e3, 0xb0d0e735, 0x1f90797f, 0x271f7cad,
- 0xc7872582, 0x79670e8f, 0xe80f377c, 0x197fd60b, 0xfb81ea99, 0x7c90378d,
- 0xc2179f48, 0xe322890f, 0x6c3bf46b, 0x775f23b5, 0xfc9f3bb9, 0xf343d01d,
- 0x18c73c18, 0x767befc4, 0xdef8c279, 0x0ff7faa0, 0x5f2cdcba, 0xf8c56eda,
- 0x2b1f338a, 0x4196cf28, 0x7fd4175c, 0xd1326ad6, 0xb6cce67d, 0x4e219301,
- 0xbd85abb0, 0x65ba7b2f, 0x7be564c0, 0xff2347f6, 0x31d6fbaa, 0x6fee95f8,
- 0x1b7d384f, 0x15df009c, 0x79328e2c, 0x55465540, 0xeda93c0c, 0x0caa9512,
- 0xb7221fb0, 0x991bbc3b, 0x720e93be, 0x053facff, 0xdc79f9ed, 0xae37b17f,
- 0xd7e819e0, 0xe8faeb49, 0xe24384bf, 0x0fafa046, 0xee5def44, 0xb5f3d1e1,
- 0xbc7ed985, 0x30564a4f, 0x4481663b, 0x4fd512c2, 0x1fbc8017, 0x8394798b,
- 0x8c041a0b, 0x56b85a2b, 0xef781ebf, 0x0377fb54, 0x5e2fe18a, 0x9138870d,
- 0x1b8b4c16, 0xb025e5f4, 0xfe30b87f, 0x4bcfcf03, 0x70e5f49b, 0xbdf41093,
- 0xccefe6f2, 0x39f6e0b1, 0x7be7d751, 0x1f93a9c9, 0x8f8fca32, 0x5f5c02c4,
- 0x909b5819, 0x702afdf2, 0x42ca6e77, 0xa59ee20a, 0x66165213, 0x04183be1,
- 0x1645a7f6, 0xb2657412, 0x8003bc3c, 0xc9fc83ac, 0xf5825bde, 0x9487ef69,
- 0xa1e1254d, 0x613ae8ae, 0xf272da7d, 0x5963c306, 0xe31e10bb, 0x8237de8a,
- 0x95eb6a75, 0x3797f5f3, 0x837e759b, 0x84f3880a, 0xefd69538, 0x797ebacc,
- 0x37dd1cfc, 0xe7e29589, 0x1bb95ee1, 0xfc5634ba, 0xa70e51f9, 0x4c2e6f87,
- 0x15fcbe05, 0x388381e8, 0x3da97320, 0x0271c20a, 0x8e85b803, 0xcdeacb63,
- 0x72ce7963, 0xf9d4ff96, 0x10fd5e55, 0x7ec9376a, 0x2058573c, 0xf70cbc16,
- 0xfdba669a, 0x17fc025f, 0x12697c98, 0x246fa7f2, 0x652e47c6, 0xb3247feb,
- 0x18aad2ea, 0xc78aa9f6, 0x782d0adf, 0xcddc17be, 0x76673df6, 0x3bfad644,
- 0xee4c5de3, 0xc4e81dc4, 0x0ec8fe78, 0xae11ef01, 0x3de18e17, 0x78d7f5bb,
- 0x29cfd808, 0x17206f14, 0x05640bd7, 0xdd9563bc, 0x978ef33a, 0x36d97f00,
- 0x5a2a77d4, 0x0e158927, 0x77d33f5c, 0x708d55ec, 0x773c98ce, 0x33d02654,
- 0x1bdcf75d, 0x83cbbbe0, 0x183aa5e3, 0x0f2ca41d, 0x0d1e2fa6, 0xf1dc17e3,
- 0x18dbf012, 0x4d3fde1b, 0x2672b0a6, 0xf406ba60, 0xb1921497, 0xca77e41f,
- 0xf8264f74, 0xb1761f5a, 0xc49a0671, 0xcf4133b9, 0x84f964ca, 0x46df057b,
- 0xb875ae24, 0xc93364fe, 0x77c2f987, 0x602d13d0, 0x887963cf, 0x554a79e1,
- 0x3c9f8c06, 0x4a89a59c, 0x5e82e318, 0xcedef151, 0xb89673e2, 0x25e3ca09,
- 0x4e4a4d5f, 0xe95feda0, 0x952d86a2, 0x510caf53, 0x03b0e1f5, 0x623210f4,
- 0xf5cfab14, 0x2c1925e1, 0x4d313dee, 0xbd5857d5, 0x9717d91e, 0x75f3f205,
- 0xe67f17a6, 0x9c41c5f0, 0xec4a15da, 0x1c49dbb8, 0x3673814f, 0xfff8d212,
- 0xc0beb303, 0x73811c7b, 0xecd2122e, 0x9b2ef007, 0xbcb37e36, 0x17be00f8,
- 0x303a415c, 0x45a2b80e, 0x857a6f1f, 0x2ab8f62d, 0x99ce079d, 0x42ed1048,
- 0xc0271f0a, 0xce0ab227, 0x057b8271, 0xce06aff4, 0x19a82429, 0x412e703f,
- 0x679def9f, 0xad13f612, 0xdaf5f447, 0x247ac4be, 0xe305d3b7, 0x713bbb74,
- 0x939c08bf, 0xafba9db0, 0x414c84f4, 0xdd6fea99, 0xc3de561e, 0xeb55a3df,
- 0xcf75fdab, 0x977df852, 0x55dbf608, 0x8511054d, 0x9feda3cb, 0xbcb39fa0,
- 0x45c23f7d, 0x7c2887a5, 0x81a824ec, 0x474d524f, 0xfb7944d8, 0x584d0fe7,
- 0x4a52fa3d, 0x1f38075a, 0xf6ae2707, 0xa2e5a44d, 0xf6d7c749, 0x473e5eec,
- 0x49b0f2f1, 0x2bc8fee4, 0xa89d4f57, 0xbdfaf3c9, 0xbe3f83ed, 0x47b3ca1a,
- 0x1ecbf6b3, 0xcb0feaba, 0xa25ca8a5, 0x702b48eb, 0x4316f26a, 0x63f341de,
- 0xa1b77934, 0x9e50d13c, 0x610fc862, 0xe19cbbf5, 0xc84bd134, 0x5ca687da,
- 0x03dfc12d, 0x81cf0d4a, 0xc56bfb9b, 0xefe1abbc, 0xb364562b, 0xd95817bf,
- 0x3859782e, 0x655f8313, 0xa76cf9ef, 0xc03460b2, 0x9065e3a1, 0x826de503,
- 0x4770f41b, 0xe630b6cb, 0xd3479da1, 0x7bdd85ae, 0x86396f2a, 0x7fedfaed,
- 0xf8f90994, 0x63ef51fe, 0x15c5f3bd, 0x78fae991, 0x19e2fef3, 0x26fe088f,
- 0x3be8b8d7, 0xdedb5dbd, 0x37bdfe8c, 0x53ba472a, 0x8e51077d, 0x067fee1a,
- 0x288e3e60, 0xbc70a89f, 0x7c59d47f, 0x31ddf0b7, 0xdb6047ed, 0x64f92fb7,
- 0x7f91e819, 0x0e3138ad, 0xfb782af4, 0xdf8df610, 0x614ba10a, 0xf8947a1f,
- 0x6f71852f, 0x3f78b8af, 0x547d913c, 0xde0c7cee, 0x87cffdb5, 0x7f0d5ee6,
- 0xb3a8eeef, 0xa9fc2873, 0x52ae239e, 0x81d1c7c4, 0x4292f89d, 0xcb195c66,
- 0x6a1ced0f, 0x5db7f9a2, 0xe2fe59eb, 0x2f20c7ce, 0xed632dc4, 0x150e74c7,
- 0x2c3260dd, 0x726dfc47, 0x3ff7e6c7, 0xcea33972, 0xbee1eeef, 0xa42e0097,
- 0x7037ed9c, 0xe542d0bd, 0xd3d29ce9, 0x7851375b, 0x1d85f9cc, 0xaea6dce5,
- 0xfa65af1b, 0xe200b070, 0xbc39928d, 0xb9443f71, 0x90dea12e, 0x42607b0a,
- 0xb4ce9f14, 0x17ee0f0e, 0x036d5597, 0xce79207d, 0x1a2fdc68, 0xb8acbe9c,
- 0x4374d171, 0xe2b34b22, 0x8bae4cdc, 0x961fbc26, 0xf5138f7c, 0x77f15fa5,
- 0x21df29ae, 0x5e38387d, 0xbb3173de, 0xf3173dec, 0x4e741c2b, 0x11de7ec3,
- 0x222deb7c, 0x056824a4, 0x50d896bc, 0x91b5b90f, 0xd72a15ca, 0xebbcf8eb,
- 0xfe8a5dd6, 0x5fc15b82, 0xfbbe1a3b, 0x47461352, 0x0cbafcf5, 0xed44779a,
- 0xbe99bab0, 0xda7bed54, 0x5cac8d75, 0xe9755b95, 0x5fbabdac, 0x71b0d725,
- 0xe9757f92, 0x5d875846, 0x8bf5e762, 0xb8dc8d66, 0x1bfff70c, 0x1fc0e2b2,
- 0x82a5f3e2, 0xc961fcdd, 0x9fe81330, 0x861a7e2a, 0xd172befb, 0x73f29ff2,
- 0xbd4f1516, 0x5b1c65f6, 0xea9102f7, 0x3fbd740f, 0xfd71fb72, 0xcb189f54,
- 0x3e99b30e, 0x4cd74591, 0x5225f034, 0xfef838e7, 0x694e083f, 0x147feeb0,
- 0xbc777f4e, 0xf73ef4f4, 0xbe61325e, 0xe84f4b15, 0xb870bdef, 0xcb0856ff,
- 0xf79ad9c9, 0xb077e848, 0xfa76bf33, 0xce69c7c7, 0x53dce7e7, 0xbaa77a81,
- 0x77cffb1e, 0x64dfc3e5, 0x51a7f234, 0x8efa3c2f, 0x3ff82d65, 0x282d2a8e,
- 0x4b5e8f8f, 0x51c5fef0, 0xaa941efe, 0xa2fce6d7, 0xd3b015ec, 0x4889c536,
- 0xbe09f71f, 0x7dc78054, 0xfee01e94, 0xa28f1ab6, 0xf175c7ee, 0x4085f5a1,
- 0xc68f370f, 0x881eef73, 0x4b7a848c, 0x2eb8df99, 0xf0ed13be, 0x371ef1ba,
- 0x07d0099d, 0x5b3231e2, 0x5d4fff41, 0xbab3a306, 0x3ef0cb92, 0x2097a505,
- 0xe8cd9fb6, 0x41266eae, 0x766ea1bb, 0x959bd20a, 0x9f30ac84, 0xa927e8fe,
- 0x10a3c586, 0x7b5637c9, 0x638c1d6e, 0x767b117e, 0x41378ee7, 0x456b5d8f,
- 0x8950163d, 0xc9b51de7, 0x074a5f38, 0xaa5748c5, 0xd49bf67d, 0x0f68fdd0,
- 0x5feed17a, 0xc3cdf4ed, 0xeed2fff9, 0x5837f981, 0x264b1ac9, 0x05643598,
- 0x1f3e49ca, 0xc608fb52, 0x7ae5cc2f, 0x67c57be1, 0xfc7fa09d, 0xff504e3c,
- 0xec0fa52e, 0x9584f9f0, 0x7ed7bfcf, 0xf9a9ec0c, 0x6277b2f7, 0x3e699ac9,
- 0x9d05f9fd, 0xb9f8126b, 0xc47d4ff9, 0x87e37409, 0xffe82e76, 0xff709cbf,
- 0xbb2f7fc6, 0xb4824acf, 0xfb68a8fd, 0xc1df81fb, 0xf9b22e5f, 0x27bb6a93,
- 0xf7a0fbd6, 0x44bf71c7, 0xed3e23ed, 0xc638ea78, 0xf8bda97e, 0xc28bc000,
- 0x8cf70c3d, 0x7f64bf22, 0xdf38c097, 0xa0f22544, 0xa9cf9695, 0xefe1e316,
- 0x3a97fb88, 0x7ceabd71, 0xae4726e7, 0xa1847f44, 0xcaf6e3ff, 0xab67f01c,
- 0x57b90ff6, 0x5c21ef63, 0x845e6894, 0xb411f87b, 0xe77cfaa3, 0xeed1b1f6,
- 0xb35be424, 0xdc6f5eb6, 0xcc3047be, 0x4795d39f, 0x7e6f0090, 0x28af1e7e,
- 0x5ef83991, 0x2ade6194, 0xba73773c, 0x08c2e953, 0xc0fdddef, 0x1ce9513b,
- 0x97fafd0a, 0xc64e119a, 0xf4fdd5fe, 0x1fe52b11, 0x82f5774a, 0x7f5af480,
- 0xc7f71db7, 0x49e46b1e, 0xefb8d7bc, 0x7777c46a, 0x4103cd89, 0xb5528f5a,
- 0xf633cf1d, 0x9e8cf3b1, 0x81239d91, 0x9ae9ba9f, 0xdd3f147d, 0x418d8aaf,
- 0xd5049d41, 0x37155e8f, 0xef77fd02, 0xb3f586be, 0x89dececc, 0xbdc30806,
- 0xaadfe0c4, 0x81f39fc1, 0x002fbd89, 0x6b458f7f, 0xd1bdc377, 0xbca8cce2,
- 0x180281e8, 0x573d4dbf, 0x38e097f2, 0x3df0dab7, 0xe0934a81, 0xb2abbd03,
- 0x67bc32f4, 0xd1dff840, 0xa568e551, 0x99a3da89, 0x34afbe51, 0x31723fbd,
- 0x491293f3, 0xf5a347e3, 0xb03b045e, 0x03b6b2dc, 0x49bb51ef, 0x6843eff4,
- 0x6b95a5fc, 0xf3037ccf, 0xf8356caf, 0x83fe0c11, 0xa53d2d52, 0xf504e947,
- 0x531f907e, 0x775bde09, 0xbf3dbcf2, 0x018efd03, 0xf030ce7e, 0xd6d77b00,
- 0xc042dd99, 0xc9381aaf, 0xed0996f4, 0x0ec1078d, 0x18efcf8f, 0x700dcb0a,
- 0x9ef19f3f, 0x75f6f8c9, 0xaa95d822, 0x6bb1a3be, 0x8c61bd2f, 0x4df76536,
- 0xf1864ec1, 0xf013e13a, 0xc9f6c48d, 0xf74803ff, 0x800023ad, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b, 0x733ef0b5, 0x9992bcce,
- 0x9264cce4, 0x0927de4c, 0x27010084, 0xd4500421, 0xe6a2bc21, 0xa2d101da,
- 0x3c2438b5, 0xa0992112, 0xf7ad8b95, 0x24844032, 0x111a0804, 0xa284e028,
- 0x17edaf62, 0x04c0622c, 0x16c45407, 0x6b5ec5fb, 0x46f7f6d5, 0x485ca008,
- 0x6c5cb046, 0xad7bfcb5, 0x67324fbd, 0xde952892, 0x1e9f7cde, 0xecfbd9f6,
- 0xaf6b5ac7, 0xa5b3def7, 0x90d74b32, 0x44b44849, 0xc8485488, 0xbb11a6c2,
- 0xfe840957, 0x5b6673b9, 0x862a7909, 0x83c9e03c, 0x33c8abb2, 0x72599086,
- 0x9e3c8c71, 0xb1722390, 0xf7878e59, 0xda1e9181, 0x08e3f88e, 0x55c84499,
- 0xe075bbf8, 0x24203693, 0x625dbfbe, 0x8d7e4d76, 0x0e76e865, 0x83a7fd03,
- 0xd8b6d090, 0x8f986ec0, 0xd1796024, 0x0d2df46f, 0x613a3f38, 0x7687df3a,
- 0xfe600666, 0x40c9a415, 0x4a5909b2, 0xd2220602, 0x8fe22676, 0xda4fa029,
- 0x173e962c, 0x2512356f, 0x55dfe097, 0x40655ffa, 0x6ccd265b, 0xe0a54b5e,
- 0x90862111, 0xfb13a425, 0xdb57b259, 0x1234e96e, 0x2afad2b4, 0xc3460913,
- 0x5f5b55b3, 0x0f38424d, 0xa355db5f, 0x44d27fa6, 0x36db8508, 0x3b662133,
- 0xf99dc9cc, 0xe87f9d38, 0xb76bbd6d, 0x6869c842, 0x870fd492, 0x38e2d88e,
- 0xa8947380, 0x568675c3, 0xd3760745, 0x48eb7675, 0xb70a3ec5, 0xc0f2364d,
- 0x59ecfa6c, 0x0d8738a9, 0x9d8c7043, 0x3c20663d, 0x2b990e1b, 0x6e7f1402,
- 0x55708759, 0xd5895fdf, 0x40cbb963, 0x7d695a2a, 0x5fda6ad1, 0xf57d7f5e,
- 0x7c2f163d, 0x70165337, 0xbbe780de, 0x0d64cf00, 0x3ded077e, 0x71a8fc74,
- 0x777ea9ec, 0xcdfb5f67, 0xfe14df0c, 0x952dff30, 0x27802d51, 0x0493b922,
- 0x04759407, 0x63cf2ee9, 0x0fefd2f0, 0xfd7e7405, 0x5849f40d, 0x31ad7f7b,
- 0x97b62cf0, 0xe5a0ade7, 0xb9e69f43, 0x489c281a, 0xd03e7bae, 0x5173d2c1,
- 0xf1c1d00a, 0xff5f3f73, 0xf17f5a5b, 0xa4628353, 0x36800bf5, 0x090f1e28,
- 0xe7684ade, 0x3c8a37bf, 0x352ddf4b, 0xbb8c3710, 0x8088c0f4, 0x807bf69f,
- 0xb0feb196, 0x1a59c715, 0x90b6dde3, 0xa5f4b3f6, 0x40a51778, 0xf03eaaf2,
- 0xdf5073c2, 0x4b3d7661, 0xc51a5dfb, 0xa1e971e8, 0xbe7efc14, 0xf014bbd9,
- 0xfc0c6c93, 0x7be92fc7, 0xf5d19af2, 0x245c7d2c, 0xff3045c1, 0x0166ad8b,
- 0x75849dda, 0xad27d2c5, 0xed5d6013, 0xbfb63c74, 0xefd21692, 0xb227d54e,
- 0x9d387175, 0xe91a30da, 0x8d9e8b79, 0x60283fe7, 0xcf7a93fb, 0x3e5a248c,
- 0x6bbe72f9, 0xf5eaad15, 0x4a068218, 0x4b4dbe7f, 0x84b1904e, 0x5d94eb94,
- 0x38722700, 0xe2abe71a, 0x7171b7c3, 0x1efbd429, 0x124eec7c, 0xf4fef433,
- 0x310919b5, 0x0f6bd3f5, 0xfd03a509, 0x6ac8af6f, 0x7b71d20d, 0x44ba47da,
- 0xe45275ac, 0x5990fa53, 0x833d6edb, 0x8f43a86b, 0xfb5af4fb, 0xb44af587,
- 0x5bfc1f1f, 0xf0dd2784, 0xbc017eea, 0xc1c59787, 0x747f14ca, 0x8943bebd,
- 0x7ac8af08, 0x0bbbd5b3, 0x13f553f8, 0x0af1f3ff, 0xf9086f84, 0xc78a6919,
- 0x1de7467d, 0xbbefd134, 0x5f7159b7, 0xb4a63c65, 0xf77e0175, 0xb69d70db,
- 0x0ad16e69, 0x58991de5, 0x314571be, 0x86c71539, 0xaf940925, 0xa4ffa44c,
- 0x49122efd, 0xdf00a9ad, 0xeda36ce7, 0x869cbccf, 0x24645cf8, 0xcfba2675,
- 0xebc32349, 0xa7ca1699, 0x8dca7c28, 0xc967c85d, 0xe804087f, 0x85abb685,
- 0x20e94b76, 0xe1030549, 0x034b7c06, 0x395840b7, 0xb5abce8b, 0xff742445,
- 0xfaa7ca10, 0xcfd59fd6, 0x693f80c7, 0x337f27be, 0x57e8e16a, 0x63ee2df9,
- 0x59c4a8ba, 0x51f9fa63, 0x18e7ac47, 0x12c3f3e3, 0x44677e01, 0xf29972ef,
- 0x8fc4c5b7, 0x0492b1fc, 0x478ea9f1, 0xbbe32df9, 0xe177c626, 0xfc0d7519,
- 0x8ad241f7, 0x380ab37c, 0xf77c60d2, 0xc777ca31, 0x0977cd0e, 0xb807c9a9,
- 0xb8b7eefa, 0xf803ce00, 0x2aefe72f, 0x8c0d131e, 0x58f8df0f, 0xfd792440,
- 0xeadd7870, 0xcfa0e73e, 0x06e242e8, 0xc0fbe7fe, 0x806e5264, 0x516487b2,
- 0x4eb0ecf8, 0xad027ef9, 0x0dc449f7, 0x93ba337c, 0xfbe85bb8, 0x87e2669d,
- 0x2826a6fe, 0xc0d38fd8, 0x792f42e8, 0x2fad3e48, 0xea0cee2a, 0x13c49f60,
- 0xb5bdf819, 0xd3bff593, 0x802bbf4a, 0xaefc04ef, 0xa9137bef, 0xbefb0a8d,
- 0xe91990f8, 0x6b41f2e8, 0xd0f288c0, 0xfda3619b, 0x48d1fc25, 0x873dbd60,
- 0x7be7c8ac, 0x2b6e64f4, 0x4910ef6d, 0x73e22b4d, 0xd827f62d, 0x27e9f132,
- 0x680429c5, 0x053db857, 0xab2132b6, 0x65575f91, 0xf283de76, 0x81519f76,
- 0xd6d97c7d, 0x74ca1cb5, 0xe5a7e23c, 0xdb05652f, 0xcd4ff6f9, 0xef7d09ff,
- 0x0c5c58f3, 0xa07cdeba, 0xa3f8a317, 0x6f144c7b, 0x42c7c433, 0x5679d28f,
- 0xe06459a5, 0xfe32d3c7, 0xb4bdfef4, 0x3d7ed9fc, 0x9fde0231, 0x64973a9d,
- 0x2a27cd0d, 0x5d93fa03, 0x64baf461, 0xd55cb6af, 0xdafb2daa, 0x9b54e5b4,
- 0x1a2671d5, 0x2aeba6f7, 0xb1a327a5, 0x3a16d3e6, 0x46abe35f, 0x967f9be4,
- 0xe03699bd, 0x31d0ba0b, 0xe331a380, 0xe02f58fc, 0x0173fdb9, 0x1b4a469e,
- 0xbe0c799d, 0x9b2eafb0, 0x79c867e7, 0xfe97cf43, 0x47087499, 0x93c189b7,
- 0x9b1f07f1, 0xee57dd12, 0xf5d08ecf, 0x251d9a2f, 0xee37c6af, 0xa045f1d2,
- 0x891ce0af, 0x9f6deb6f, 0x5db16309, 0x5989f225, 0x579d1db4, 0xb7c656c5,
- 0x18ce9297, 0x54d50fd8, 0x145131af, 0x78636c3e, 0x2a1b5258, 0x367fd20a,
- 0xc2464bdb, 0x25afa53c, 0x1d7fe00f, 0x87a61bf4, 0xb1d366dd, 0x72cd7bf6,
- 0x368e06b7, 0x96d7d94d, 0xed877724, 0xff7c2597, 0x60904513, 0x7af94b3d,
- 0x6f782f7e, 0x9955f803, 0xe8530cba, 0xfd7eb7f8, 0xc5efca05, 0x75c6ca2b,
- 0xdbd70b8f, 0x1757c88c, 0xf7c5ea3f, 0x399b6faf, 0xcdb7d71f, 0xcfdc00ac,
- 0x9e9014ec, 0x025aa717, 0x5bcffa26, 0x5b9f4c6d, 0x8413bf4c, 0x848c7081,
- 0x331dd9db, 0x6747409d, 0xdfcf1b09, 0x59e4e4ca, 0x9b2bc299, 0xcefe81b5,
- 0xebbe31b6, 0x33f33adb, 0x778b4fe0, 0x67902e8a, 0x1aeac3a4, 0x7d3ca04e,
- 0xf40b42e4, 0x0a6e2977, 0x6bbcdf6d, 0x7be22cba, 0xfd8013d1, 0x6f3bb923,
- 0x5da5efa5, 0x78df5013, 0xcd91a763, 0x0e7a66d3, 0xd7eb71d6, 0x92c7ea22,
- 0x2f41788e, 0x47b8366b, 0x76557ec2, 0xf0033b3c, 0xb2567672, 0x42ffdb0e,
- 0xc3c03220, 0xde0122b6, 0x0f24162f, 0xad8acfec, 0x72e1a595, 0x11136cd9,
- 0x1e32535f, 0xe0b2e84b, 0xe407ba7e, 0xba4ed554, 0xd9fc607f, 0xaf7fbd1f,
- 0x3d3f7c23, 0x6174445c, 0xbfc77672, 0x5fc13d20, 0x34f808b0, 0xeef5c583,
- 0xbab4632b, 0x80726a2f, 0x5d5e2e5f, 0xa20f2393, 0x8bedf7bf, 0x8e1f741d,
- 0x4d836426, 0xb0755720, 0xfd1aed31, 0xdfbd2876, 0x0373ab92, 0xe22e4ddc,
- 0x133e967e, 0xa0bf548d, 0xa025f07c, 0x1a78788f, 0x97d23e10, 0x877ded0f,
- 0xcd926bae, 0xc7a053fb, 0x07cee20c, 0xb9212bbc, 0x005baa98, 0xc80fd462,
- 0xb7d3230e, 0x6defa624, 0x81cf2789, 0xfb8ea0be, 0x1e2fe84b, 0x1b1ec2f9,
- 0xc3e7b7ed, 0x5c018eaf, 0x8fcfd3ab, 0xbbecf905, 0xa14185f2, 0x0bb4b5eb,
- 0x2e2dafc8, 0xf17a010f, 0x0b22cfb5, 0xacf9faf2, 0x40e4c5cf, 0x6afebae4,
- 0xcfb67a63, 0x4e7ec211, 0x6dfed9db, 0xdcfa31b6, 0x002a22be, 0x23bb75fc,
- 0xff498660, 0x7c94fbbd, 0xc538a545, 0xe189a573, 0x57e7b4d9, 0x3be8116e,
- 0xa1c3c820, 0xd1fdb0ac, 0x202f315b, 0xdb3e71d2, 0xf2c7ed93, 0x912e29fe,
- 0xfcf659d6, 0xe00b2eac, 0x4177a6d4, 0x2bab8b7b, 0xd9f7d606, 0xb031539e,
- 0x223d8abe, 0xf022bbae, 0xbcc2c279, 0xbaf0be7e, 0xc00dfde0, 0x4b04388b,
- 0x6cf87f38, 0x0584a5cf, 0x98395416, 0x1c1c2c7c, 0x29e4472e, 0x5bb7809d,
- 0x3978616f, 0x00630bf7, 0x3339def8, 0xfc615f95, 0xc9959cf6, 0x263693b3,
- 0x4d69091f, 0x57d37907, 0x07573fbe, 0x6648ffe3, 0x5a1877eb, 0xfe3f61d3,
- 0xe7eda0b7, 0x091d3ac1, 0x595ede50, 0xf9434147, 0x5e17b9d1, 0xff7e0749,
- 0xa4afb3d9, 0x2fcd8597, 0x79f53bf2, 0x9aedc6de, 0x26dda7a6, 0x51195e3a,
- 0xc2a60bc7, 0xe32e6578, 0x485fc027, 0xdf7774dd, 0xcf62c9be, 0xab64f6f0,
- 0xaf60f91b, 0x1d00a8cb, 0x56f5dfaa, 0x804db944, 0xfe426217, 0x062ed657,
- 0xdb9fd08d, 0xfa01cc3d, 0x447dfab6, 0x4638aeff, 0x809b424f, 0x5e746976,
- 0x77f1f908, 0x2d4ef7e6, 0x7f9e293e, 0x32ae7801, 0x10a58e85, 0xc0030fa4,
- 0x916d50cd, 0xac253e40, 0x7a15f461, 0xbffa8744, 0x0169d921, 0x4e6b767e,
- 0x6e8ead54, 0xcc544744, 0xa7f54258, 0x6c5ce4b4, 0x74662fef, 0x81204fef,
- 0x590c0235, 0x96bf2023, 0x3a9c5e99, 0xb40dc891, 0xd33b3df8, 0xb5c49c57,
- 0xbc46cc55, 0x507fe00b, 0x05caa1e1, 0x8fe01fa0, 0xd21304e7, 0xa02ed08f,
- 0x5aea289e, 0x43bf41e7, 0x5d9e53d1, 0x3d1953b5, 0x49ff95f5, 0xe76454f4,
- 0x9e803bf4, 0x93d20abc, 0x3d3834d3, 0xbbf90229, 0x07bf13da, 0x0e44acec,
- 0xef9c4daf, 0x31311e84, 0x19050abf, 0xf794b7ac, 0x04b26a57, 0x2e1f9045,
- 0x30aef9fd, 0xd507627b, 0x494ec16f, 0x3e9e7d02, 0x57ccd653, 0xb3a46f10,
- 0xe8daec0b, 0x8f942609, 0x999d75eb, 0x8e24afa0, 0x7407d9aa, 0xaf2f3891,
- 0x67da0d60, 0x079036a9, 0xbfd15b20, 0xd3d8a2b0, 0x2fa6171d, 0x2fa80874,
- 0xc6ea3f54, 0x99db53f7, 0x661be07e, 0xd7d77d40, 0xcf01f826, 0x00431ed5,
- 0x817aa0f4, 0x1bfc01f9, 0xefd80acc, 0x156536cd, 0xbff34fd0, 0x5d3f2e29,
- 0xf9806f47, 0xd7497a13, 0xbd009fae, 0x3ed05855, 0xb605b66f, 0x7776822d,
- 0x03bb61e7, 0xf8d9137f, 0xdf8e09c3, 0x7a8adf9c, 0x0a6df37a, 0xfc7003f3,
- 0x2772cf35, 0xa81f40d9, 0xe6e7eed3, 0x9d927716, 0x52b5efbe, 0xcaf1d0c0,
- 0x8788cd1a, 0x99c19164, 0xfc989ac4, 0x4c17c819, 0x8984f700, 0x4f4d311c,
- 0xb7d3bea3, 0x80a729cf, 0x6faf3272, 0xd0e3a4ce, 0x3cf35879, 0x9f79a099,
- 0x3c7e5a6a, 0x024fd28a, 0xc46e87f8, 0xebd07e26, 0x564c61a3, 0x4f70c376,
- 0x9244e8e9, 0x86cef6a1, 0xcac39369, 0xf7ff7dbc, 0x69f6efff, 0xfb7728a9,
- 0x54da61ea, 0xb765ab1e, 0x9d6bce99, 0xa25ebfb5, 0x4da9aefa, 0xd7fbdf60,
- 0x8a9d3edf, 0x1d415ee8, 0x377aceff, 0x44cca9f8, 0xfcf85e33, 0xf5fe88a4,
- 0xa28b7fb4, 0x02565fb6, 0xa0553dfd, 0x73aedf96, 0xd26df9d3, 0x9043fb6b,
- 0xa0a1eff2, 0x4f8be78e, 0xdc9c686a, 0x3d5017af, 0xdf1f6021, 0xfbac1faf,
- 0x06e9b4a8, 0x7cb4563a, 0x577200c9, 0x873ef395, 0xe447fa80, 0xef897d7e,
- 0x57ccefd7, 0xba3d5187, 0xbf47a348, 0xdabe4764, 0x24b60335, 0x6f903fb5,
- 0x10f31efb, 0x3ea8e7d0, 0xfa8ec072, 0x4733f9c8, 0xeccf7d68, 0x514b1cbf,
- 0x79b2dda0, 0xaefaf7a0, 0xbeb74848, 0xa04062bd, 0xfbe26b74, 0xc0f1ca85,
- 0x9e9fa170, 0x9d39941e, 0x0744fcda, 0x8c21df74, 0xd57d23f7, 0x714ddfa4,
- 0x3ee71299, 0xb7ef8f62, 0xfdd7231b, 0x0fd99d91, 0x6de2dcbe, 0x1effd039,
- 0xd09e8081, 0x61327b90, 0x9f4dda01, 0xfb0c2c24, 0x29edb2ae, 0x5ee56784,
- 0xfc70a0fd, 0x1c222ec8, 0xecbe0fab, 0x2e71be06, 0xa84f2020, 0x37f50290,
- 0x854572d2, 0x5241340e, 0x2f7f9818, 0x35cc8fac, 0x7d74e190, 0x409bd041,
- 0x977bda8f, 0x375846ff, 0xafa04ffd, 0xa1167bb6, 0xd73edd3c, 0x30992164,
- 0x0865b2cf, 0x0dca3907, 0x2dc86870, 0xaa71824e, 0x4590cd67, 0x1c7aa7a8,
- 0x7a3f57d4, 0xd30c405f, 0xf4da1b03, 0x14e7a025, 0x57ee7d51, 0xf669de74,
- 0x745c4bdb, 0xfb88a71f, 0xe5a61ff2, 0xf1f0432d, 0x6e4c1c47, 0xff1e0ad4,
- 0x5fd10af7, 0x6ffdc247, 0x6f4c6d19, 0x683768bc, 0xed17affc, 0xd9377e12,
- 0xc81539df, 0x15d4b0e7, 0x8fb4fa0d, 0xfb073fb8, 0xca2c7899, 0xc62788b3,
- 0x152b1c8f, 0x1c992bf4, 0x806feb5d, 0xda12c9fa, 0x7aea442f, 0xa9edc612,
- 0x081ab877, 0x7e5007df, 0x9eed0f34, 0xabde71f9, 0x5c454740, 0x3839ed4f,
- 0xaf2cbf33, 0x7faaef5f, 0x0d581ad6, 0x3caad4fc, 0xf4fc0251, 0x24f9094b,
- 0xa73a8531, 0xff2a7ed2, 0x1b7ec76a, 0x7151bda2, 0xe6f5fe74, 0x81d03d40,
- 0x76c445bf, 0x20a6d98e, 0x73d9f3f4, 0x2fd016d6, 0x02268ef5, 0x15cd4c74,
- 0x1c9887f4, 0xf2d0a21e, 0x497cff54, 0xa1117900, 0xbf054ccf, 0x0e2bda11,
- 0xf3162bf4, 0x529c31fd, 0x6e1319c1, 0x71abda85, 0xf1cdfafd, 0xf048e6af,
- 0x747bd552, 0x9de7e626, 0xc08a3736, 0xe86d64f8, 0xcafc0e98, 0x7a024e8e,
- 0x80ab5570, 0xbee554e3, 0x65bb0064, 0xdfdb2b49, 0x50676e3e, 0x5e83a5f8,
- 0xcd171d91, 0x465acbf5, 0x58f3a4ef, 0x45f9c00a, 0x68424f86, 0xbdb86b3b,
- 0xd5d98ab2, 0xf7033fbc, 0xbf715787, 0x58849511, 0xd54e363f, 0x67f35633,
- 0x71f27b13, 0x6e9d08b7, 0x2f99e011, 0xeab6fc68, 0xe31c7a73, 0x4347b13b,
- 0x86ff6033, 0xff817d28, 0x6b309b68, 0x7d749bd9, 0x728fc6db, 0xa4e60a81,
- 0xc01624e4, 0x148a4a7b, 0x9f6d85ee, 0x21ba00cf, 0x6bf70425, 0xb114db75,
- 0x400dc78a, 0xae8c485f, 0xc4fa8169, 0x3e517207, 0xfc1f1f83, 0xb87077ff,
- 0xff985926, 0x9fdab9ce, 0x8c1e50f9, 0x26f659ef, 0x0a263f8c, 0x148915e3,
- 0x3e3b5637, 0xe57fc0eb, 0x4047f924, 0x954b3afe, 0x1a8f9802, 0x89d78a37,
- 0x43cacc0f, 0xbb658e3e, 0xa6ef704b, 0x6ce3bbcf, 0xdf6a2eb8, 0xe17cc095,
- 0x0ddb807d, 0x4e274760, 0x7187c9ad, 0xcf044e21, 0x84a0a49e, 0xcf2a68fe,
- 0x6d3a059f, 0xaf00ca33, 0x3eb7b6d2, 0x6a5b7900, 0xe822ad22, 0x4b7a113f,
- 0xf35dcc56, 0x2f7b6e80, 0x38f5d99c, 0x03eeebcc, 0x47e22f2e, 0x7adc8fab,
- 0xcfcbd30b, 0x80ad1b3d, 0xf39bb91e, 0xb23faa6d, 0x982fc138, 0x47a9191d,
- 0xb5a7123e, 0xffcafa4b, 0xcd923d70, 0xf7e74fcf, 0xf77f186c, 0xb7afbb71,
- 0xc80c62e2, 0xf47d55af, 0x517fe546, 0xb6529ebf, 0xd813fa27, 0x45767d67,
- 0xb5223e84, 0x840538b0, 0xdaef90d9, 0xe2fe3c0c, 0xff07ce76, 0xf9072d87,
- 0xa2e7f1cf, 0x173740fd, 0x97a8cd5b, 0x10433649, 0xb2fb55e6, 0x8013a031,
- 0x7578720f, 0x818ab8f0, 0x39ec6bc7, 0x0714280a, 0xfbe41e0c, 0x2cf497fe,
- 0x781312ae, 0x5e5a39e1, 0xc789387a, 0xeff6085d, 0xf08d183f, 0xc4a51a5e,
- 0x7f4bff42, 0x9e20471d, 0x03c74bd2, 0x7b37cf3c, 0x4d780a7f, 0xc9feb236,
- 0xc585466b, 0x36398279, 0x0096870a, 0xe54effd3, 0xba0682ea, 0x17d016ee,
- 0x3546dfa0, 0xd9d6c2fe, 0xc58521bb, 0x0119400f, 0xfb9eacbb, 0xcab8d5e9,
- 0x2b87e661, 0x5393f1e7, 0x033d17b3, 0xa15ab4a1, 0xb4ec04a6, 0xd0530dcb,
- 0x89fcbd6f, 0xaf2cf859, 0x17dbfad3, 0xaf7c1a91, 0x3f5527c6, 0x19711977,
- 0xefdcfe98, 0x7d51d43f, 0x8a93a946, 0x12667e41, 0x03c83579, 0x37b14fc5,
- 0xe96b3e81, 0x81789413, 0x93b69942, 0x80511dea, 0x3ab575ef, 0x5afe5b94,
- 0xa9da1b9d, 0x1c56f2f4, 0x57fd23f3, 0x5097f31c, 0x1c600750, 0xe7ab59f5,
- 0xdfde7efe, 0xc20ba22a, 0xe7b02753, 0x192a593a, 0xfdab7e4c, 0x4c6bead5,
- 0x4e6f4053, 0xfb3fa1d3, 0x173dc1b2, 0x1cf6c5fd, 0xb5ad53c4, 0xd584aea6,
- 0x6cba5ee3, 0xfeb0790e, 0x96298966, 0x3f03b144, 0xfa6388ed, 0x16dc2445,
- 0x91cb6936, 0x80ca9071, 0xbc4e5cb6, 0x59b29223, 0x7dfc20dc, 0x9767e707,
- 0xbc39321b, 0xbbe0065d, 0xa557faea, 0xd2e9b832, 0xad2b33d8, 0x41d02e78,
- 0x3285f816, 0xaafcc9e1, 0xff382574, 0x021d9bac, 0x7cc447d2, 0x9e8c6d6b,
- 0x0fccf5fc, 0x3fcef7f9, 0xe367de72, 0x763ef812, 0x56be213b, 0x5e301b2e,
- 0x12fead7a, 0xdf6b4393, 0xf1ff95f6, 0xe7b32df6, 0x2fc645eb, 0xa97c8c88,
- 0x396b664c, 0x0b9eb825, 0xd50b7bc2, 0xf51d601b, 0x91f00162, 0x705977a9,
- 0x2987d51d, 0x55f5a11f, 0x83a5758f, 0xee2eaf5c, 0x80bc81ca, 0x6cc2f848,
- 0xd19f9525, 0x6a0e6576, 0x50de808f, 0x0d878da7, 0xd3ba038c, 0xeec1e31c,
- 0x2defb539, 0xccfb5f90, 0xbfe8bf28, 0xff61188e, 0xbe44cc1f, 0x3bc589f6,
- 0xbe3ee21c, 0xe7aee0a8, 0x618f4133, 0xbb55547a, 0xc4f405b1, 0xf8b0dab2,
- 0x51affc1a, 0x75236f1b, 0x93bbf476, 0x8afbed66, 0x0ddf111d, 0x2135bf88,
- 0xbc18b65e, 0x53bf6123, 0xf1f18439, 0x023a950b, 0x5d172df8, 0x5d48408b,
- 0xf3f56b30, 0xaf86560b, 0xfe550e69, 0xcf0072b8, 0x7801e57d, 0x9e00e576,
- 0x1bc475cb, 0xe0154fde, 0x2977e299, 0x9785f3c7, 0x9e00e427, 0x909befcf,
- 0xa2de7803, 0xbec3726f, 0x4b7b2599, 0xd3dd8e00, 0x415fa83d, 0xd1f613bc,
- 0x7de3d2b5, 0xf464f37d, 0xf390df78, 0x5bf8c7fc, 0x8b8f9286, 0x95a1e6fa,
- 0x92830e8f, 0xcca0fc0a, 0x3946fc64, 0xfa837f09, 0xf4464cf3, 0xeafe1c7f,
- 0x1bcc46d2, 0x3f511768, 0x2c3bfb51, 0x3f41b379, 0xd381fc3a, 0xee8617e5,
- 0x8afc0adf, 0xe0fcffc5, 0x02ed5167, 0xe48cbf55, 0xfbe63fc7, 0xfdc3b37a,
- 0xd83bfd99, 0xb8ffaaa7, 0x0531b782, 0x77bd312e, 0xfe62e08f, 0x27f456e3,
- 0x97cc7757, 0x69fc5fc1, 0xab8ff980, 0xff47ce5f, 0xf5e06571, 0xdfc80a60,
- 0x7b064176, 0x27cf72a4, 0xfd2c8b31, 0x73b52f76, 0x886e809b, 0xfa471b49,
- 0xa62a7034, 0x3ef382dc, 0x768ef30d, 0xf7400c84, 0x23fed4d5, 0x52d54974,
- 0x5bf418e8, 0x17a820ed, 0xed69b614, 0xb8054a41, 0x031eedee, 0xededddf2,
- 0x75f80042, 0x999bc182, 0xa48d720a, 0xe40718ca, 0xc3976cfb, 0xe8f301dd,
- 0x03bb6b8f, 0xa33cb08e, 0x48b16dae, 0xe27a5dbf, 0x6d9f8196, 0x267e72b3,
- 0xf3fb7f21, 0x21a05b0e, 0x73f86f4c, 0x9509e980, 0x4491be6a, 0xd7c51282,
- 0x0fee39a2, 0xefc0df01, 0x3efc1183, 0xa3c6acbc, 0x3cfc4097, 0xde1dee22,
- 0x1f8e2fae, 0xf4d6f716, 0x95f26a43, 0x5bdc6d42, 0x7667ef5b, 0x2b0fdd33,
- 0x57e9fa0a, 0xbf4a83c5, 0xed1fdcd5, 0x16b938ab, 0x26d7d7e8, 0x2f5f60c8,
- 0x5dfa3175, 0xe32fed4a, 0x9dfb81d8, 0x0dfa52b4, 0xed4377e3, 0xe4228fff,
- 0x7bff47d1, 0x3b5068f2, 0xf8df74fd, 0xebabdf6c, 0x7df7fd57, 0xd8176ceb,
- 0x57588cbe, 0xe91adda4, 0xceed5777, 0x5f87e56b, 0xafc3f045, 0xa1f88ffe,
- 0x7e287e29, 0xfc6b8da8, 0x7ff0fcdd, 0x4cf1be39, 0x3a31d3c7, 0x332a2aca,
- 0xd7a64efd, 0xe2f135b9, 0xcdc5a219, 0xcb22a6e2, 0xbb8c8897, 0xdc78332b,
- 0xd7e7ed9d, 0x5f11165f, 0x5c3e3c55, 0x417561d5, 0x62cb0ad3, 0xc646cf8c,
- 0xfb241f4f, 0x228a0066, 0x614ba8e3, 0x7b7f671f, 0x9e3f353c, 0x5ce947c5,
- 0xa14f2132, 0xdfcb58a8, 0x8a5cb75f, 0xbbe186f3, 0x021a8f38, 0x49b5d083,
- 0xd87b13f2, 0x99e35bfb, 0xcf3afd3e, 0x481a71e7, 0x6ca1e41d, 0xc1bb46b2,
- 0x58ea718e, 0x9c4a51be, 0x78fc4a67, 0x9e1cefe0, 0x744fbf07, 0xe8cf2e14,
- 0xf89f915b, 0xe02e2cab, 0x471faa7f, 0xf7077fed, 0x9d2b5e83, 0xddaf1bdf,
- 0x7fe57df7, 0x572fbed2, 0xe37bfbc7, 0x6c295b76, 0x2081fb34, 0x38809efd,
- 0xba40e653, 0xa19faa1d, 0xbc7977e8, 0xee3c5967, 0xcc58f73b, 0xfe46bd9f,
- 0x3a185d12, 0xb222fe05, 0x7f80a8df, 0x2825fc13, 0xb8931b17, 0x022aeebd,
- 0x2ebe4338, 0x0c7d6be4, 0xb4349cff, 0xb7d8d8fe, 0xd8fe99ff, 0xe907fe57,
- 0x9ec8378f, 0xeeceb08d, 0x901cee29, 0x74aceb6f, 0xbe1760fe, 0x768cf2c0,
- 0xee7d1998, 0x925d1810, 0xe4d77115, 0xaf13d977, 0x867b9fe5, 0x2efff79c,
- 0xa7fd6cff, 0xc4bfcff1, 0xe8751f80, 0x2f2cfc7e, 0xcdd3b8b7, 0x776469e3,
- 0x07db7f98, 0xfbf466f9, 0xeabe7c23, 0x2e5c9dfb, 0x47dc125a, 0xff9c1f81,
- 0xb12264d0, 0x6429e554, 0x63dab17c, 0x7542f8c1, 0xa97bcb2b, 0xff208c7e,
- 0x69ff06ae, 0x6715f81e, 0x26f7d011, 0x0027bcd9, 0xb23eebcf, 0xf058c5f8,
- 0xa026cfbb, 0xc87cf5df, 0xbd967fca, 0x7bef509d, 0x19e30bac, 0x61cfb3cd,
- 0xd5d155de, 0x0a4b6b4b, 0x47e8be71, 0x4d491870, 0x1afe9e38, 0xd596f2cf,
- 0x783e95e7, 0x7fafd1bb, 0x11e582be, 0x196e1cfb, 0x5faa11fc, 0x44e95a3c,
- 0x7ef5533f, 0x8915b4a6, 0x27e43d6c, 0xd54f48a9, 0x83e4a7fb, 0x9ab494ff,
- 0x2dcf41f3, 0xed05a3fa, 0x268ff3bd, 0xfcc49e63, 0x9859ef38, 0x7030b5af,
- 0x19a5e81b, 0x77d01c74, 0x2dbbefcf, 0xf2ade61f, 0x3fe02dbf, 0x58b7eda7,
- 0x62717eb5, 0x95ddf962, 0xfea8a7cf, 0xb7f410f3, 0x6243ef85, 0x359a2a69,
- 0xf757bec8, 0xc3a8a27b, 0x607f13fe, 0xcab938c2, 0x89e8b60f, 0xcfdd94d7,
- 0xcf10fe47, 0x3c1cfbde, 0x167db15f, 0x65e14fcb, 0xf0aa7f0b, 0xfe98ecdc,
- 0x1fc79807, 0xcbeba5e2, 0x4b05930b, 0x75eb3c78, 0x7887fbc1, 0x8032cf16,
- 0x8a314e7d, 0x2be8967e, 0x92ce7f4c, 0x5647480d, 0x3e30dfba, 0xf408e943,
- 0xcea1c9f8, 0x9d74b1a9, 0x93839ac3, 0xaf87be01, 0xd24f10e8, 0x9f1813ac,
- 0x78d81589, 0xf55d8dd9, 0x22ffc023, 0xa03377bf, 0x8b926952, 0xc937d421,
- 0x404e49e6, 0x2e4d7a7f, 0x7bfc578c, 0xec93cb3d, 0x42bf4688, 0xcc52fa73,
- 0xc8f9ec93, 0x489cfe88, 0xfd3ea0f9, 0x45e63564, 0x27fdb566, 0xfbac09c6,
- 0xd4dc0d05, 0x0b04f8e7, 0x3bf95f8b, 0xcd6e6067, 0x57f20764, 0x188fe3a9,
- 0x25ea969f, 0x56a43ce0, 0x8199d6ef, 0xe822ad7f, 0x2cde1ce7, 0x195f00eb,
- 0xf7a62f3c, 0x7ac75ff0, 0xe3514ed1, 0xd7960102, 0x0b5aefa4, 0xaab497f6,
- 0xe03f16eb, 0x574dbf63, 0x85fd079d, 0xd2cfd1aa, 0xcf804d11, 0xaf65b467,
- 0x339689be, 0x838c64ea, 0x925a1ef5, 0xba557e81, 0xac83e1ce, 0xe5813d33,
- 0x18133921, 0xd11d48bd, 0xd267903a, 0xd182e266, 0x32dd6b33, 0xcb8779f8,
- 0x25b9d212, 0x70025bc1, 0x807ce68d, 0xb8c288ac, 0x7e6255a2, 0x8f8aeb11,
- 0x44e7017e, 0x03f3f176, 0x9e8f0f47, 0x7abdfe8d, 0x5fb80049, 0xc9bcb1b6,
- 0x73da0939, 0x3ef0fd07, 0x59a7f98a, 0xe4c9ff1d, 0xfa0b1d17, 0x3e8cf497,
- 0x0b477aa4, 0x587711f8, 0x7b6f98bd, 0xc4506d73, 0xfddc9938, 0x66128964,
- 0xf2656ccf, 0xb32f7aa4, 0x97ed23bf, 0x5523936f, 0xd2395a09, 0xe927fe57,
- 0xae122b27, 0x5a212ed3, 0x4f522e7b, 0x06dfb489, 0xfd11dbe8, 0xa8afa50d,
- 0xfdc52779, 0xd9bd30e3, 0x7e43eaaa, 0xb14e5e4d, 0x4c4b8d85, 0xdb27feda,
- 0xcc8f9665, 0xd61274f3, 0x9024ab28, 0xd046ff57, 0x0be6a72f, 0x5e598bf9,
- 0xf9475f8f, 0x97c4265f, 0x284f309a, 0x01050485, 0x045d66fd, 0x7c844bbe,
- 0xe3ddfa21, 0xef385909, 0x2755c49d, 0x04547f22, 0xf219b798, 0x352f304c,
- 0x8c116db0, 0xc705b773, 0xc99e4331, 0x70154838, 0x3a7e036f, 0x11c582b5,
- 0x05dca992, 0xc61e4dfa, 0x973cd0e8, 0xf9a89be5, 0x87fe6a24, 0x0e62870a,
- 0x8b11e4df, 0xd5ef8132, 0x4017de0b, 0x1817a9cf, 0x981bfc7c, 0x46d9a11f,
- 0x6e5a68f5, 0xf9851cae, 0xf584bd7e, 0x21d0afef, 0x80f9aa5d, 0x7615c3cd,
- 0x226fe53e, 0xf9cdefea, 0x4064bf2c, 0x5c044a1e, 0x6e943cd5, 0xf603b7ab,
- 0xe4c8b26d, 0xa2379aa8, 0xfe1849d2, 0xde3a66fc, 0xbfa60ef6, 0x70185717,
- 0xb795bd1d, 0xb7b1ffa3, 0xce404752, 0x191bb717, 0xb78c45dd, 0x0481ae7d,
- 0x60295fa1, 0x8e79fcc6, 0x5fd36fff, 0xc1735e29, 0x65747bbf, 0x0a6eb8c9,
- 0x7a5637e3, 0x166bd9f0, 0xd7c8455a, 0x01e68731, 0xf89cda47, 0x49a43ba3,
- 0x4a135790, 0xecc92817, 0x54a0fe70, 0x37a072a2, 0x9431f43e, 0x9c7c4c5f,
- 0x76878795, 0xd1fdb409, 0xd8a51da7, 0x9931681e, 0x98253f90, 0xeb96fd4b,
- 0x40646f90, 0xc0a7c6be, 0xd748aa87, 0x0bf44eda, 0xc856f971, 0x669921f8,
- 0x94bf300c, 0x77b1fe82, 0xee513293, 0xf6b3725b, 0xaa7d4277, 0xb469fd11,
- 0xddfde91e, 0xbd5853e1, 0x524ef0c2, 0x836f2cad, 0x9f81f974, 0x05399bbd,
- 0xb055d2fd, 0xf4fea81f, 0x057bc5a6, 0xe8417af0, 0xe0fb0e5c, 0x9affe9dd,
- 0xe17df407, 0x01864fc0, 0xa06999bf, 0xfc20f97a, 0xe32771e5, 0x4b7abd2f,
- 0x79fb409d, 0x1215e2dc, 0xe883f969, 0x95203379, 0x14dc6e7c, 0x200d1c03,
- 0xe04417fe, 0x7f1cf177, 0x5f4c39b6, 0x08f34db4, 0xc6b9f790, 0xef11e6cc,
- 0xbfa8dc95, 0x7708e778, 0x11aff5d3, 0x94433eb8, 0x143bb458, 0x8eec1625,
- 0xc21e2ba5, 0xef916fbc, 0x9bad49e7, 0x7f97d045, 0x4df8f2b7, 0xe5a1b0d2,
- 0xf6115df0, 0x1254fa85, 0x8b663ad9, 0x8fa018ca, 0x6fe342b5, 0x3de0934a,
- 0x31e9b3a3, 0x5f210a2b, 0x4d74667a, 0x22cdc621, 0xf7d2c7df, 0x23656179,
- 0x14d4b76b, 0x3d28974a, 0x61decd3b, 0xf3cb9700, 0xfb0e593f, 0xbbf27977,
- 0xc2be431f, 0xd6e27abb, 0xe24d3ec3, 0x1f2a4371, 0x32c7bf01, 0x286e2c6c,
- 0x031a9d6f, 0xef866ce5, 0xe30048db, 0xd873a5d4, 0x483bc139, 0x6d176d67,
- 0x57a9d337, 0xece8c2ba, 0xbe5b4536, 0x2e5b5723, 0xff1179e5, 0xbfbed2e2,
- 0xc0248493, 0x7e26f7ff, 0xfdfc223d, 0x1beecd8f, 0x0aaffe61, 0x3fd28f2c,
- 0x87a8c889, 0xe83f043a, 0x495fa305, 0x5926e7e6, 0xb9cfdfbe, 0x44caf31d,
- 0x7b09f582, 0x0f21bb4d, 0x8b07f55f, 0x93b47ebc, 0xc8ec3298, 0x84ae508f,
- 0xe8379e04, 0x390918c0, 0x7e664cb0, 0x40d6da51, 0x5f3039fb, 0x5824b841,
- 0xa016e474, 0xd21342eb, 0x298a5175, 0x28e0e80a, 0x3f1f23a7, 0x55d2a387,
- 0x903c4491, 0x9e8740bf, 0xf577cf03, 0xfff011f2, 0x78233ffa, 0x29908a4e,
- 0xf231e612, 0x855908b1, 0xbd39a7e5, 0xedf9551e, 0x6fc849bf, 0x701ab4df,
- 0x16bf895f, 0x439f805b, 0x5fd6991b, 0xf3851c6c, 0xdd03f753, 0x091cc3bd,
- 0xfde672e8, 0x44983a4a, 0x2acaccae, 0x38f862bd, 0x410fe401, 0x738d523d,
- 0xbefa99a5, 0x4977c373, 0x74bb9fbc, 0x8a4cde2c, 0xdc9d1c78, 0x3f7cc465,
- 0xbfb42f5e, 0xf7e025f5, 0xdc4cc4f1, 0xb7887b74, 0x3446e80b, 0x4ba014b8,
- 0xdae5ce95, 0x9d29bf43, 0x79c9eb04, 0xbb73d704, 0xe4f58655, 0x6b9c3252,
- 0xae3ba7c7, 0xf461fa00, 0xefb1462e, 0xfb792aef, 0x3e8c2926, 0xec55f7e8,
- 0xf7ed68fb, 0x3dbdfa4e, 0xfa18fbec, 0xefc0de7d, 0x72220909, 0xbff3e76e,
- 0xee89e79d, 0xba829ab1, 0x917fd0b1, 0x13bf45d2, 0xc3f7d813, 0xe07be862,
- 0x7cdab9fb, 0x65d1320c, 0x88de3cc2, 0xc2998bfc, 0xd7404963, 0xdaaa99b7,
- 0x6fff68bb, 0xd4ccfc71, 0xf380bf79, 0xcbcd6f66, 0x57fc0379, 0xbfba2625,
- 0x055f60b2, 0x7ad202d7, 0xb19f78a7, 0xddfee365, 0x2d5ff401, 0x69d8477a,
- 0x69be82f9, 0xdc4cb2d8, 0xe3133b17, 0xc55fce07, 0xa00ebabf, 0x3ea7a003,
- 0xb798883a, 0x67722f8a, 0xedac262b, 0x3c087aa4, 0x9084bd55, 0xac9f961a,
- 0x8baff5a4, 0x530ccb12, 0x0bd030cd, 0xe3f4aade, 0x7b699dbe, 0x9e97f312,
- 0x04bef24f, 0xc37b9df3, 0x3412e9e7, 0x011fce76, 0xdf3a207e, 0xce5ffd5f,
- 0x06bfd557, 0x667ee7e4, 0x0ee7e4d0, 0x71d47fb5, 0x8957a07d, 0x82dbc790,
- 0x39beb6f9, 0xab9c1716, 0x68be41f0, 0x5079c621, 0x30243aaf, 0x982fd57d,
- 0xad741eb8, 0xe984bc79, 0xfa7d554b, 0xbd0f2692, 0xbbcd9f39, 0xfa829979,
- 0x6b02abd6, 0x984f9fef, 0xd78b363e, 0x5eb1942f, 0x6e6f57cd, 0xe6b5fe61,
- 0xd0284797, 0x50a3d52f, 0xae58931e, 0xfe3265a7, 0x91493cda, 0x44dc0cfd,
- 0xafcfe848, 0xfa67a2de, 0xab9d76df, 0x0c41f308, 0xf1623f54, 0x869fc65b,
- 0xfd23f1b3, 0xaa275f70, 0xc3f30076, 0x41ff95f5, 0xb259b87e, 0x7f693897,
- 0xe9dcf30b, 0x17982cfa, 0xfa51c7f3, 0x2049d1dc, 0x1866ac4d, 0x91b7cde8,
- 0xd974f79a, 0x68069f48, 0xa534773f, 0x7d0d6ccf, 0x8cf19d1a, 0x22bcc21f,
- 0x1d2441f9, 0x6578c566, 0xd6d9a7e8, 0xd06ac7fa, 0x2e8ddb37, 0xf2ca7f96,
- 0x40f922e9, 0x48167cd8, 0x510e3e6c, 0x0738f9c4, 0xecb5cf9b, 0x4cfa7093,
- 0x0c3f6c24, 0x25125fb5, 0xf416b7e2, 0x9b1f97ef, 0xbd6023bd, 0x2d66fb7d,
- 0xcc062fb3, 0x7d20b45b, 0x8b2f73dd, 0x99a2f837, 0x43b8835c, 0x167f1d12,
- 0x7a9eff1f, 0xfcf78746, 0x4b7480d0, 0xf9841fa7, 0xb3f5e6cf, 0xdf30abda,
- 0xfd34f668, 0xff0d2ec9, 0xe7bc2375, 0x1c7376f2, 0x02d87af9, 0x71b54a73,
- 0xb3f7b985, 0xa4ddc6b8, 0xbdf30f46, 0x9fb68e67, 0x73f1a4b9, 0x7b9a9fc8,
- 0x54fdf6bf, 0xc9b9df67, 0x788f1011, 0xbde1db83, 0x7ec0bf74, 0xf17e337a,
- 0x7e94658e, 0xaf34fc47, 0xd303fc00, 0x6cf72a13, 0xb7e7e5a6, 0x9bf2c28f,
- 0xd1f83f09, 0x2bbf50bb, 0x20d3cb07, 0x08ec0c19, 0x6f208fd8, 0x3dbdee8a,
- 0x86fb8e93, 0x8cbbf799, 0xa33bdbe5, 0x68b3cdbc, 0x2cd8e73b, 0xc69c1bcc,
- 0x42ef4df9, 0x0dc77f56, 0xfa1a9656, 0xb97e8280, 0x79a15169, 0xf227ff40,
- 0x790050ff, 0x78b2d3ac, 0x51d5e0b9, 0xf8437e50, 0x4dd81e7c, 0x0916553d,
- 0xcc9d5fe0, 0x73a399fc, 0x0a48e085, 0xde766997, 0x575b157f, 0xc90bc169,
- 0x15a63fb0, 0xbb467eb3, 0x4367d4a6, 0x2c45dd3b, 0x629b24f7, 0xfbaa1f80,
- 0xfb93996c, 0xe49eb807, 0x15fefbe1, 0x71b527f7, 0x498f5fb4, 0x3d12c170,
- 0xfb413f13, 0x39d85894, 0x533b8f2c, 0x54e87f02, 0xdc73cb37, 0x02ac8aba,
- 0xcdeb647d, 0xad0d696e, 0x7a226a9f, 0xce946b90, 0x9b7a011f, 0xf4f3e13b,
- 0x8b2e2018, 0x3a55ce96, 0xf7d2a59a, 0xd31d2d34, 0xe713f9fd, 0xcfe76ff8,
- 0xf7363a1a, 0x7a50f1d3, 0x1d579d39, 0xb49bbfee, 0x9c6faaf2, 0x39187d88,
- 0x01fc50ee, 0x67f9c2fe, 0x715afcff, 0xb642a5bf, 0xc7ec3658, 0x6e3f7526,
- 0x7418f803, 0x24fe789d, 0xc28d7043, 0xe8439b03, 0xd2fcea15, 0x305927c0,
- 0x27f05e70, 0xfb1d7aa9, 0x9b1d8073, 0x77e9ebca, 0x9fef626e, 0x05ff1d17,
- 0xd96b7fe4, 0x350a767c, 0xbd709f8c, 0xab7fb55a, 0x69b6f5d5, 0xc5145bd7,
- 0xc13b7bce, 0xe93e814f, 0xf37d51fc, 0xa83c06be, 0x3971f1eb, 0xb1e4c73d,
- 0xeedae81a, 0xfd2395b6, 0x5ff89f7c, 0xa0e87d06, 0xe6187bc5, 0xefe75479,
- 0x2163fb00, 0x925c6371, 0xce6bc7d2, 0x9d42fd30, 0xaa9c246f, 0x919fe087,
- 0x4f8489eb, 0x513ade3f, 0x77cf539f, 0x1af7adf5, 0x21eaa9d7, 0x3fd6830e,
- 0x1cfee764, 0x00dff73b, 0x2e3c8145, 0xd02e5125, 0x04baa7eb, 0x894a27d4,
- 0x6970f909, 0x76df9309, 0x5437d30b, 0xfed43f39, 0x8216f5b8, 0x2974a9fc,
- 0xd8c9e7e1, 0x30e922ba, 0x823d7491, 0xd9499e76, 0x39f600b6, 0xff4a25e8,
- 0xcc2d4bfc, 0xa9c57bcf, 0xf1aef5ca, 0xcafbd720, 0xd77ae403, 0xf337e078,
- 0xa3fc6d44, 0x2ff30af4, 0x7c10afda, 0x193eba96, 0x5edd720f, 0xf81e35d2,
- 0xeeb1add6, 0x1f9f012f, 0x361f98eb, 0x24fa8e12, 0xbc5fea9d, 0xdc8cfa26,
- 0xe95c6a3f, 0x94d78b4d, 0x1fdfbe34, 0x2ce84171, 0x38ae4682, 0xcdeff799,
- 0xf4a63a04, 0xf2897288, 0xc157abc7, 0x837f8398, 0x532c721c, 0x092d9bf9,
- 0x2e08dbf8, 0x8f8c3dc7, 0xdb758b9c, 0x0d1c5893, 0x8710f2e1, 0x572e74cb,
- 0xd110ee2f, 0x9dcd3f9f, 0xdcb834fb, 0x24f5c77d, 0x8dd7fb80, 0x5f097172,
- 0xa53a45d7, 0xd17fb420, 0xe2c67a8a, 0x1e31cbb7, 0x8eab6231, 0x72726128,
- 0x734a2064, 0xbde8c47f, 0x4c794d76, 0xfda6b26b, 0x9a596d0d, 0x28e0fcfa,
- 0xe3b8fd4d, 0xf8f29a05, 0xed351bce, 0xac507c27, 0xbaea4f29, 0xa6fed35d,
- 0xca6b674f, 0xac123014, 0x0283b9fb, 0x7dd74ed9, 0xcd3ee873, 0x7dbdfff7,
- 0x0b8871c6, 0x33f6e29e, 0x733bbbf1, 0xa8161c29, 0x4ca57c74, 0x08505fdb,
- 0x07c0450a, 0x4682dfd8, 0x853cd796, 0xdfbc2e42, 0x7d5a4d85, 0x6d56f162,
- 0xf37da2b9, 0x0395e05a, 0x8a6a21f3, 0x646c88e1, 0x7934c43e, 0x75e80ebe,
- 0x2fd51276, 0x91c63040, 0x1ac7c838, 0x1b7fdf6a, 0xb0c873fe, 0x6b3fc36f,
- 0x7a80d5bf, 0x7fb7e2fd, 0xafa41455, 0xfe2d4e8c, 0xff168acd, 0xfc5ab9d1,
- 0xfc5a5d5b, 0xe2d44ec7, 0xe2d6e6df, 0x8b44ae3f, 0x168f78ff, 0xb57389ff,
- 0x6af24ff8, 0xa1529ff1, 0x8d5a7fc5, 0x2b19df16, 0xf4ccf8b4, 0xffbda83f,
- 0x2aff0224, 0x7baeccff, 0x149ee228, 0xd185d11d, 0x0b474a81, 0xe798153c,
- 0xc7e9bc32, 0xe922719a, 0x3a8dda81, 0xda8b87bc, 0x6b85db71, 0xbdca0fa7,
- 0x491a5fd0, 0xf1244f1f, 0xb13b183c, 0xeef9455f, 0x40f8127e, 0xf2a15ea4,
- 0x1e3970ad, 0xc50eff6e, 0x27c806cf, 0x290f0f6e, 0x361ec09f, 0x43c3dbf7,
- 0x9087e9d1, 0x53fa838d, 0xee8bfa23, 0x2e3cd995, 0xe049abc1, 0xf225fd5f,
- 0x04e90fbb, 0x7ef9d227, 0xe3a1eb08, 0x1a35187f, 0x203f18fd, 0x7fcfd441,
- 0x74871908, 0x712007b0, 0x13e73e99, 0x5ce59f05, 0x7ee42f5e, 0xdbd9a70e,
- 0x16a97006, 0x300919bd, 0x9e276a6e, 0xe227221f, 0x855ee9ae, 0x976fe093,
- 0x7f06e908, 0x98f67d3b, 0x519c7d19, 0x289b87f9, 0x9678308e, 0x5172154d,
- 0x30a3157f, 0xfbeca80f, 0xb2a5ca02, 0xcecf61ff, 0x4707a624, 0x50acd73e,
- 0xf5c4d9e1, 0xfc0fa600, 0xe3c29277, 0x416bc433, 0xe064b9b8, 0xe63fb4fb,
- 0xf319feff, 0x4925d193, 0xec78ec57, 0xf80cf10a, 0xa241f386, 0x8c73cd89,
- 0xe8574c44, 0x8bc4d1fb, 0x49c7dffa, 0x7aee3859, 0xd632b289, 0xb7e828ef,
- 0xefa3c60b, 0x045c5ba7, 0xd3a2bdfc, 0xabffd045, 0xc32b0996, 0xf55bac1f,
- 0x7a72a5eb, 0xcc2563d8, 0xe7e1157f, 0x2729114b, 0x3d157c85, 0x94ed0f3b,
- 0xf0bb32b6, 0x18ceab98, 0x792a2eb6, 0xed7e706d, 0xc81cf4db, 0x96133d2f,
- 0x5ee14e0f, 0x3f1c9833, 0xa8e2cc9e, 0x6e9a566b, 0x0f497886, 0xbe3d078f,
- 0xf80cdc92, 0xe6172514, 0x417dc181, 0x0defb0b6, 0xb61f5a0e, 0x498b24df,
- 0x3c5bd653, 0xdac65978, 0x17483595, 0xd1af7e7a, 0x6487d4ba, 0x217f986f,
- 0x4c4f8f9a, 0x1027227e, 0xbfd2f2ae, 0x5812a74f, 0x674b28af, 0x9feaf634,
- 0xdc0146ae, 0xa93d38aa, 0xe93a35f3, 0xdeed6138, 0x2557f4e1, 0xfe601a77,
- 0x741c50ef, 0xea413c42, 0x56bde074, 0xffb8e975, 0x37f0e4ef, 0x908217ee,
- 0xe0946ff7, 0xd2f4268c, 0xd28e3cd9, 0xf477dae9, 0x6b25e204, 0x7e44cfc7,
- 0xb8d7b066, 0x1e4f05a8, 0xeca1677e, 0xea9e041d, 0x2e94e8d3, 0x61a3f387,
- 0x9e0edcc9, 0x3e002640, 0xca0f9906, 0xf66587a7, 0x59e3c3cd, 0x3fc3c1be,
- 0x4c7f9824, 0xa2bfd056, 0x13c4f87e, 0x1b1bf217, 0xc6cbe109, 0x50037495,
- 0xa561b71b, 0xa8737889, 0xa835221c, 0x3710251f, 0xfe6351d2, 0xfd395709,
- 0xebf052ce, 0x3787b05c, 0x0d53ff8c, 0x1f45ad94, 0x61b94055, 0x90ad8be4,
- 0xb981642b, 0x23bf3038, 0xa2b66700, 0xef7cfd46, 0xef07686a, 0x425f3e21,
- 0xacf9d3df, 0x821ed31f, 0x0f63d1f6, 0x51f50a7d, 0x9b29a096, 0x3f75177e,
- 0x45b04971, 0xb253855c, 0x4856d3e9, 0x8e28a17b, 0x4f47dfe6, 0xc646fd64,
- 0xbb2d1203, 0x93217dd9, 0xb1678f09, 0x1faaec73, 0xbbb2de3e, 0xc6f818a9,
- 0x53fd6d30, 0x96711e1c, 0x41678e97, 0xe7612a7d, 0x93fd7957, 0x7966debc,
- 0xe598b3a9, 0xdfbe681c, 0xb58ffbcc, 0x50bf18e8, 0xb1b78f08, 0xdebc4dfa,
- 0x093bd6ac, 0xfab1a78f, 0xb46f5e7a, 0xba12fcb0, 0xafdf35ad, 0xdc27e3e3,
- 0x30de23af, 0x89cc74fa, 0xfa30de22, 0x35da97b0, 0x9d85bd65, 0x25a79523,
- 0xfb53be6b, 0x1b8f9c7d, 0xf34b3933, 0x28d8699d, 0x34cefb6d, 0x710f2394,
- 0x0b521b38, 0xf9eaf534, 0xb3a7226c, 0x276b3276, 0xf4d46e39, 0x6251517b,
- 0x999fff61, 0xcbadd2a4, 0x90fb7404, 0xe2112b35, 0xb99581b4, 0x1f0144a0,
- 0x3f994fe1, 0x6674789d, 0xcb054acd, 0xb8bfdc99, 0x2c44e566, 0x0b74a6ef,
- 0x74accff5, 0x2d277961, 0x53f9f42b, 0x58950fda, 0x07ed1b64, 0x7ed34fca,
- 0xed14f9e0, 0xd24f9e07, 0x337ea0f1, 0x9bca0efd, 0xde507f68, 0xe58dd2b0,
- 0xb04b2bf5, 0x83d2bf5c, 0xe72b75e5, 0x95f1f3e2, 0x59ae7c5e, 0xbbf58159,
- 0x3beb8593, 0x22485f7f, 0x93bbb9e3, 0xdde7f7c7, 0x16dcf1ab, 0xd476e0c3,
- 0x32ffce01, 0x8988e788, 0xa5c63fd1, 0x8f5b1ad2, 0xe719bd80, 0x6a48f861,
- 0x5b7ac1ac, 0xfd471b09, 0x24fc388e, 0x331d88b5, 0x5950fc64, 0x230df98d,
- 0x7317cb09, 0xc45289fa, 0x9fc25fcf, 0xbcff4214, 0xabe5ab94, 0x71f91199,
- 0x9923b3ea, 0xb0e279d9, 0xc72c371a, 0x8413d134, 0xcb8b5e7c, 0x33b1e78b,
- 0xa9ced0ae, 0xe57b1cbd, 0x5f80a216, 0xbfab54bf, 0x6815a7da, 0x4af144f4,
- 0xa533b635, 0x6769a7de, 0xda699470, 0x5cc92d95, 0xa47804eb, 0x1b1875b0,
- 0xbd101157, 0xe3379b0b, 0x999367b8, 0xebd74bbd, 0x3efbff47, 0xeb97ad81,
- 0x7ccbcf4d, 0xe446a6bd, 0xac6c23ab, 0xd7eb1398, 0xff3c3f01, 0xafdc58ab,
- 0x43a33dcf, 0x1248dfff, 0x46be01d0, 0xf50cf153, 0x96174863, 0x4aee006f,
- 0x1144f9cb, 0x848e3ca1, 0x7aa4bed0, 0xb3257fd3, 0x6633d0b8, 0x79a50b88,
- 0x23f9679f, 0x392b9441, 0xaa391f1c, 0x8a55b8fe, 0x4e9da7f4, 0x7b56fb46,
- 0x5b8d449e, 0x2516b2ae, 0x33d13e82, 0xb44f7e44, 0x169bbef3, 0x27463850,
- 0xfaa7c5cd, 0x1ba2bd7e, 0x55e57cf4, 0x4cefaf0e, 0x77c601e7, 0x6afce8c2,
- 0x0bbfa532, 0x0c83bf79, 0x2c3d5219, 0x1af0f684, 0x941fcabd, 0xfd0fe058,
- 0xe62c5765, 0x2127b473, 0xc199447c, 0xde95b9e7, 0x7fa9249b, 0xf997e29d,
- 0xe49be432, 0xbdb67cf0, 0x34dd972b, 0xc75fea4d, 0x5fb614e8, 0xf22b4973,
- 0xce875cfb, 0xa735ecc5, 0x0f33bec6, 0x79c3726b, 0x7114715f, 0x48c42e41,
- 0x5ee784d2, 0xc889bfc5, 0xb7a3c47f, 0x17ea8511, 0x40807251, 0x2fda873e,
- 0x8fe276e1, 0xc2fcbf38, 0x2de70d32, 0x94f7aba6, 0xf9af51b9, 0x90c97642,
- 0xb345f2cf, 0x4f123f1e, 0x6573eb6a, 0x4a5e07d7, 0x47f68b97, 0x517a60bb,
- 0x5f784db9, 0x204bb89b, 0x83ce02a9, 0x99d9a7e5, 0x5adfaa7e, 0xe0e3fc44,
- 0x2e37aed0, 0xa5dae005, 0xc2a9d01c, 0x8aabb69e, 0x3f06ec33, 0x0b8008d4,
- 0x2e5873c0, 0x5f2171c2, 0xab95deef, 0x14ee4e10, 0x6935e786, 0x7cf9dc2a,
- 0xf70ddb88, 0x566a2dbb, 0x3aed5bed, 0x7f15e7d7, 0x3b6bea0f, 0x8bd3cc45,
- 0x9885e784, 0x286263f7, 0x3346cba2, 0xa79d0cff, 0xc129e61b, 0xbe00e3bc,
- 0x58b3d704, 0x5ce00436, 0x5ad08f66, 0x31a97182, 0x971e123a, 0x53339f52,
- 0x277aff18, 0xb467c659, 0x0b4dde73, 0xef9785c6, 0xc31eba47, 0x122c4fd7,
- 0xbb7093cb, 0x5abf7095, 0xf0676a83, 0x3e28ea3c, 0xa0fbbedf, 0x2f3cb146,
- 0x0adce90b, 0xd9431779, 0x614c3f11, 0x3b7ef2f1, 0xe806a282, 0xf309bc67,
- 0x7cd41a1b, 0x055de514, 0x13e96bf3, 0x9c4c51f2, 0xd959d74e, 0xfaea043d,
- 0xbe30a656, 0xa3e392b9, 0x22ecc4d7, 0x27e4db88, 0x6f9f9d84, 0x58fb472f,
- 0xb6f4f38d, 0xd552fcb3, 0x49c950ff, 0x060df7a0, 0x221dde87, 0xdb2a77c6,
- 0x0ef760ef, 0xf7893c76, 0x14bed235, 0xde7287a0, 0x6b4ebcbe, 0xe3d82f0f,
- 0x0ca51b59, 0xc117bbb4, 0x03d9ab7d, 0x3b48eded, 0xae14b1fb, 0x3e48babf,
- 0x354e71c4, 0xa28b1f66, 0x126435f3, 0x2297bf3c, 0x6ef784be, 0x09b3ed53,
- 0x79243bee, 0x488fbeec, 0x6a92bfbc, 0x15ef3840, 0x5a5b8f08, 0x8ef7fe90,
- 0xef7ffb67, 0x0e778b91, 0x93dcfda7, 0x7ea6e0c1, 0xcb064f77, 0x0607dd33,
- 0x4adf7d15, 0xf960c948, 0xdc38bb3c, 0x9b9f33bf, 0x5573e5ac, 0xa2c75d6d,
- 0x3b77e415, 0x8f7bde81, 0x0f2625fd, 0xef0847f7, 0x833f7f2d, 0x0de607cd,
- 0x74fbf479, 0xa70bcf9f, 0x12297d83, 0xfaeeb79f, 0xda698cf4, 0x7bc85d79,
- 0x3676e12f, 0x579856af, 0x4264f04f, 0x3ab47e78, 0x83c57daf, 0xfd7cef9f,
- 0x9133e77a, 0x5068a7ce, 0x26fd1d38, 0x0c33ed38, 0xf80f9f3e, 0x0de3fe7c,
- 0xc0c0ef76, 0xd3d4ebfa, 0xefc04476, 0x807bcec5, 0x7ef9d35d, 0x847a0290,
- 0x63013bb3, 0xad7e1c4c, 0x0b3e9c85, 0xa171df39, 0x1f7c444d, 0xa4bcc04d,
- 0xfbd58956, 0xab028bec, 0x8ebafd28, 0x7900c82c, 0x88d0fd60, 0x86f8c5f7,
- 0x4b8b37c8, 0x97d8eb65, 0x870a0c2c, 0xe47f5e18, 0xb7f61944, 0x012303fe,
- 0xf5cb507e, 0xab72f5f4, 0x5501ee09, 0x02e508e1, 0x4219f4fa, 0x2e505c8b,
- 0x58a4c2fc, 0xc74f1906, 0xb114dbc6, 0xd4f1d46f, 0x973529a7, 0x3785ddf9,
- 0xdea3c844, 0xbc3df934, 0xa15367af, 0x3bf73c84, 0x4b59bfc3, 0xef82172f,
- 0xe8c9dc25, 0x7a0a94c5, 0xe63a7094, 0x13ecb47b, 0x03cdbf42, 0xb8bc19f8,
- 0x4647df7e, 0x840c22d2, 0x2f4e25d3, 0xf5d4faea, 0xdeb6f3ab, 0xd6f300bc,
- 0xf1301f01, 0x7a9d5498, 0xd5f21e2f, 0x60f72e58, 0x2627285d, 0x7d0f2c4b,
- 0xdd7884bc, 0x3c46f134, 0xc78fb027, 0x0c93439b, 0x7e43de83, 0xfd7f1f0b,
- 0x04ecff95, 0xaedfd5fb, 0x44d9f3c7, 0x45de72ea, 0x8ef7c8e9, 0x52bdf784,
- 0xfb812a7a, 0xb89c8e67, 0xdd7a0318, 0x847aa94d, 0x0fc04df3, 0x115c3e41,
- 0xff7f304b, 0x18b217c4, 0x5393ff46, 0x7497ae45, 0xfe5e4276, 0x979602c6,
- 0x807ae16c, 0x057744e5, 0xf132dfcc, 0x4c2146c7, 0x1aa5e6ce, 0x868dbbf1,
- 0xf68b8250, 0x4910ebe7, 0x2e81f510, 0xefab47bc, 0xe0cc91dc, 0x05485d50,
- 0x47dc1e4c, 0x9ad7eeca, 0x3e30aa9c, 0x807de74b, 0xf91a8fbe, 0xf50e5c85,
- 0xacbc7485, 0x32adeffe, 0x78d467c3, 0xa6c59f76, 0xe193bfc9, 0x8158aefe,
- 0xafb43de0, 0x7935eaa4, 0xe8649ffa, 0x9d9dbf78, 0x65f9bfa0, 0x5b09f309,
- 0x40990f83, 0xc5f757af, 0x86dd54d3, 0xfdf8eb76, 0xe626ebaa, 0x805ce006,
- 0x4a7fc74a, 0x61527af5, 0xbc5f747d, 0xa7577a84, 0x47c22a67, 0xc97c87ce,
- 0xef13a431, 0x0685210d, 0xae4be419, 0x6fd9a74e, 0xea6f1c2d, 0xa8a5ea93,
- 0x69c23cef, 0x62f79559, 0x39e0898b, 0x62b32ba3, 0xd3152f41, 0x25cf3d54,
- 0x6cff1c03, 0xe1fa8399, 0x8d2d37d9, 0xf57cf1e1, 0xb3da9a79, 0x797f4341,
- 0x0333cba1, 0xde222fda, 0x2e8fa0b5, 0xe735166a, 0x7df2cfae, 0x144af0be,
- 0xf5e98609, 0x87de270b, 0x5e1647e7, 0xaa412189, 0xe7e59d27, 0x3cf2ce7d,
- 0x654f7f9f, 0xaf81b2f2, 0x75ea4b67, 0x08aefbea, 0x0ff3b97e, 0x7e3195cf,
- 0xf700eff9, 0x00cba12a, 0x8de36e7c, 0xfe3cc17f, 0x0f4ed4d3, 0x3ad37ce6,
- 0x6c3048e3, 0x5776be9c, 0x7e9eb84c, 0xff3828bc, 0x105af5fe, 0xfda9a70e,
- 0x4c70cdff, 0xbfb1c0d1, 0x1c0d2cff, 0x839ff607, 0x995e9fe3, 0x8ffd2dfb,
- 0x457fa21e, 0x7efeff33, 0x3db8e187, 0x8f9ecb47, 0x68e5fba6, 0x57f6f570,
- 0xb0ed5f21, 0x272fef11, 0x78c5ad6d, 0x0417e89e, 0x3f2d99cf, 0x90c7e5fc,
- 0xb77cb687, 0xf46305c1, 0x5cf343ea, 0x6187c883, 0x7dc3f644, 0x6f73ea3e,
- 0x27ae366a, 0x0a49bdf2, 0x666f90c8, 0x55e495ca, 0x9d65e80a, 0x1fb8d581,
- 0x549fc84c, 0x6fdab83f, 0x9ea88a6d, 0xad7dc567, 0x10d0dbde, 0x7c00eded,
- 0xe6a5167f, 0x8237f91d, 0x67f2ad1f, 0x85eecca2, 0xa21da1b3, 0xe225b1fa,
- 0x91a3bf45, 0xe5e40878, 0xdf7865e7, 0x53fefe00, 0xafc006ca, 0xe3d98e2d,
- 0xb723ff45, 0x3b9836f7, 0x7e30ae9d, 0xe954fbf7, 0xd6fce4fa, 0xfe333908,
- 0x4c82e7fd, 0xe61efcce, 0xfe762551, 0xf2132cb2, 0xbdf8bb08, 0xe3018a3d,
- 0xf0c78505, 0xd532afbe, 0x8c8baf5e, 0x40d9a75f, 0xeefd55ff, 0x044f9031,
- 0x9646c23a, 0xcd1e5dbf, 0x89bfe5ca, 0x907573c3, 0xf0079fc2, 0xec5d156e,
- 0xe119379e, 0xa1af917a, 0x1d31b4d7, 0xe1cbd9e0, 0x75fdb17a, 0x62ee57bc,
- 0x7fc470dd, 0xc13f6bf9, 0x25f6a17b, 0x0ea77cf3, 0x729fca2b, 0xee08aba3,
- 0xcc97db2d, 0x2956ccf4, 0xa6105318, 0x2d4bae77, 0xbe7abe46, 0xf40eb86e,
- 0x7fae1572, 0xa360fce6, 0x4293efea, 0x2ebbf045, 0xbf830be7, 0xdfb7f945,
- 0xa267bf8c, 0x1165f03b, 0xd1b76fde, 0x1782f788, 0x65b9181f, 0xcaafad2e,
- 0xa59e61d1, 0xe71980ee, 0xdd81a173, 0x82df03af, 0x903aae9c, 0x52c3bf82,
- 0x3cc21d1e, 0x5728aaa9, 0xca41c40e, 0xf784dc0f, 0x30da9f7a, 0xe5f81d32,
- 0x1d2578c9, 0x40dd35ef, 0x7dd74e81, 0x7b0463b2, 0xcf013f5f, 0x463759ad,
- 0x5ff3077b, 0xf22472a8, 0xc97d9efe, 0x006d3df9, 0xd726919f, 0x2d3e5a6e,
- 0xeb9c58b8, 0x82b66878, 0x9e171671, 0x9cb72bdf, 0xdbef1afb, 0x7ee4fe6a,
- 0x481def82, 0x161daab7, 0x97395e39, 0xa10cfb33, 0x387bf079, 0xdc386be5,
- 0xab9f2c0d, 0x839f975c, 0x8df70e65, 0xe65cf711, 0xab7831a5, 0x242753cf,
- 0xca8c2fbc, 0x67c874ff, 0x88d8753e, 0xe36a7674, 0xaaaf3c68, 0x614e578e,
- 0x797dd322, 0x058caed2, 0x634b8ebc, 0x0d7caafc, 0xf7d52fb3, 0x25cdbae5,
- 0x8750e780, 0xbd2bf988, 0xe2062872, 0xb53b6a1c, 0x769eb7dc, 0x65d77f11,
- 0xc411f25f, 0x0227a537, 0xcd7ba4f4, 0xf7d5f28a, 0xe037719a, 0xf1217cf3,
- 0xfe5c8347, 0xce4efd80, 0xea230ed1, 0x321fbdbd, 0xfdc074bb, 0x3a509649,
- 0x7be81fdc, 0x58f9052d, 0x17685a6f, 0xeccd93d3, 0xbd77b55e, 0x2c3c7813,
- 0x9647df89, 0xe5d9fa04, 0xf410730e, 0xf8c4fa33, 0x71ec9f86, 0xd1c3fbe2,
- 0xf436fc04, 0x53854019, 0xdfc4efd8, 0xfc4d2095, 0x7efc4efb, 0x0477ba79,
- 0xd9e5e5f0, 0x7c0b7fb4, 0x2eed8ddf, 0x806f7967, 0xe64bfd32, 0xbf6325e3,
- 0x7c0cde69, 0x64e17c2f, 0xc4d0a7bf, 0xdeb13beb, 0xc04ef467, 0x4ad1fc75,
- 0xe759065a, 0x55bbdef5, 0x7887169c, 0xe14de754, 0x245efa8c, 0x98d26a5c,
- 0x23c2a47e, 0xf0fb2e92, 0x03f32df9, 0x97c009bf, 0x363c33b4, 0x3e30348c,
- 0xf51a3f52, 0xa51b525a, 0xd55a13c9, 0xf761cec1, 0x9e22b06c, 0xa7eef57b,
- 0xde851e41, 0xaf7613d5, 0xc008d515, 0xf07130bf, 0xe78e72fd, 0xb3d65709,
- 0x2f73a27c, 0x6f9f4d9c, 0x678af381, 0x5515e735, 0x24ed1f3f, 0x1628fc06,
- 0x96531297, 0x116cf4c7, 0x377ec7e7, 0xc15ea367, 0x6ff207df, 0x847e8918,
- 0x00e50653, 0xc3518efe, 0x55d01d18, 0x1ef18bbd, 0x9f5b137f, 0x7a8e5f7a,
- 0x7c244def, 0xd9b2d35a, 0xef1091ef, 0xf2877003, 0xf024a249, 0xffde1a60,
- 0xa2ff0155, 0xa618afa0, 0x3f919b73, 0x185ca0d4, 0xe196cf78, 0xe83f7e5b,
- 0x3fbcb6ff, 0xeb3ae09d, 0x9018fe5d, 0xccca9fab, 0x53d8a3de, 0x6c8bae50,
- 0x69a7789d, 0x4f6bc812, 0xd63c5a5b, 0x54fc3f23, 0x9f2af560, 0xa07eb01b,
- 0xda07e817, 0xa78ebed1, 0x3219bf31, 0x8ca7b809, 0x8f900df8, 0x9f27caa6,
- 0x3ce0e920, 0x894db76d, 0xaeec7a01, 0xbd83b6cf, 0x1253665c, 0xc2e8c20a,
- 0x73c106f7, 0x37dc0aa4, 0x5f7e013c, 0xfc163dc2, 0x5aecfb75, 0x7ce4417f,
- 0x35d29a5e, 0x77febc2f, 0xedff4c69, 0x8a28fbe2, 0xdf9063c3, 0x2fbc4279,
- 0x77af78e6, 0xfb416f79, 0xe2dda231, 0x1e9cb1ad, 0xbd37de22, 0xf798affa,
- 0x4f7b43b1, 0x78f8cfdc, 0xf8371e9f, 0x19e01b85, 0x15baf985, 0xab9f199b,
- 0xe734bb78, 0xf3c65651, 0x1e5a53d5, 0x58e3dfc7, 0x0e7a7bb0, 0xf10b7c61,
- 0x82e3d2a0, 0xe80e7774, 0xa26da171, 0x62a2fb0c, 0xa9f388ab, 0xdb4c9a97,
- 0x5b33fbe8, 0x55dfa8f5, 0x499cf9f0, 0xde20c6f5, 0x28192224, 0xde48cfdc,
- 0xb75fd418, 0x891ddff1, 0xf76d0758, 0x0830549e, 0xcf0c4c7c, 0x41ec9f08,
- 0x1d5de0e8, 0xfc0169e2, 0xa3cc197e, 0xe4bf4045, 0x03ef3499, 0x76a6ee50,
- 0xdbffde3b, 0x59f78954, 0x8cfbc244, 0xb9f48bc9, 0x8547af98, 0x2a38e467,
- 0x9e017b3c, 0xdf1d2fa0, 0xf7cf728e, 0x4b140894, 0x425fb48e, 0xc74a7a7b,
- 0x826f8ff4, 0xdea99bf7, 0xcd9c80a2, 0x400fedfa, 0xf889d5ce, 0x1d65267b,
- 0x422409d9, 0x58dd835e, 0x189ccef6, 0xac9c985d, 0x7e31166f, 0x766c3f52,
- 0x7f6c42cc, 0xafa04ef1, 0xa12b8a93, 0xe8ddac20, 0x8178bef4, 0x9be55f06,
- 0xe3031aff, 0x71ea3454, 0x7a5e2a5d, 0xff909ce9, 0xbfa34536, 0x843537a8,
- 0xea78aafd, 0x83c06fa3, 0xddb44f4a, 0x1f32e95d, 0xa8fc8fc7, 0xe45bd33b,
- 0x164e841a, 0x85c7493d, 0xf15ab6fe, 0x1d6bc2fe, 0x1f478557, 0xc6bef9be,
- 0x5771e032, 0x75bffa26, 0x4c984aef, 0x6669b27d, 0x72e3ec3a, 0xdfc02f2a,
- 0x3e842e50, 0x3b247bc6, 0x6b0f788c, 0x0f25e6f9, 0x1fe578c0, 0xdf50751a,
- 0x58e6787d, 0x5e04579c, 0x07d29c29, 0xccdef7a3, 0x0c2bba50, 0xc09f547e,
- 0x27aeadfd, 0x0f38de6c, 0x7de14f6a, 0x1499bd24, 0x607c619f, 0xbbd33a76,
- 0x80d97b68, 0xc3eecdf4, 0x1caf5be9, 0x62395eb1, 0xa411efbd, 0xe2f2e26f,
- 0x647c167a, 0x05fbc1d4, 0x0391dc4f, 0x86eeb5fe, 0x6eaeb8a9, 0xec2c7bbb,
- 0xda74eeaf, 0x72fc20ff, 0x9d7413c1, 0xceb0df79, 0x6be23326, 0x43da75c8,
- 0xac37c8bb, 0x50e9c7d3, 0x4969e75d, 0x2bdfc189, 0xf012283b, 0x3cd2f897,
- 0x65626f1b, 0x9f289dfc, 0x6f83d19e, 0x31e63473, 0xfbb3b4f6, 0x403e55c9,
- 0x7a46bbc7, 0x743d21d0, 0x265b2b17, 0x106d7d02, 0xed8bc865, 0x5bf7186e,
- 0xeeaf1df8, 0x7a0ca28d, 0x83317742, 0x2807e51f, 0x3dd3bbb7, 0xb0f96277,
- 0xea8f7f1e, 0xdf5fd354, 0x1de173c7, 0xfae0857a, 0x42e71b3c, 0xf817ce99,
- 0x3dcb851a, 0xe3d55f4c, 0x9eebebfa, 0xff7a83aa, 0xfcf01bd6, 0xacf940c3,
- 0xa3457385, 0x4487d9a8, 0xdf3c7052, 0xaf782913, 0xca670a83, 0x1ec07361,
- 0xe501e152, 0xe1fa6339, 0xa0e7e3e2, 0xf7602f41, 0x067e7120, 0x7262c9f0,
- 0x0081ce02, 0x28f3831f, 0x48abc943, 0x47a913fe, 0xaf8fbcfd, 0x6571f968,
- 0x3e18efc4, 0x125e5118, 0x469637c1, 0xd44557d4, 0xe77cf953, 0xe4e7fe60,
- 0x2b5f2d0c, 0xfd5470e3, 0x041bbda0, 0x24cb43b4, 0xcff600c5, 0x7c98534b,
- 0xe988972e, 0xec97dc16, 0x44994b7c, 0xf0058d6a, 0xb70865de, 0xb57f6893,
- 0x472d3b46, 0xdb443e31, 0xcac21895, 0xe755bf2a, 0x878701f3, 0x7ecefcfa,
- 0xe321d281, 0x8fa41f15, 0x28af181f, 0x757eb310, 0x83abec02, 0xbe95da22,
- 0x21fc99b7, 0xf2da5d5f, 0x97ee03a2, 0x30bcc6cd, 0x7091fd75, 0x14bb6dec,
- 0xd7ebbf03, 0xe780dc73, 0xe3dacb93, 0xb2fed18a, 0x7b850687, 0xda9f5f0f,
- 0x15d48f5f, 0x6f5c2b33, 0xe1315d26, 0xd65aa3bf, 0xd8256976, 0x7e7e14b3,
- 0x9f8f8c31, 0x062f88ea, 0xd7fcb2bb, 0x7e70c5c9, 0xdaa196d6, 0x1acfcafd,
- 0x341cdf61, 0xe7a23fa2, 0xf83ab9ed, 0x0aede7be, 0xf78e5cfe, 0x3e9cf5b8,
- 0xc7e30e95, 0xfee7b4e8, 0x5b6fdc0d, 0xd764fbae, 0x0fffc0cd, 0x09ae6625,
- 0xeb9737f3, 0x7e1ed00a, 0x079a1f51, 0x7e7aa6f3, 0xaa57e41d, 0x1432d8fd,
- 0xf071af96, 0x0fe02eec, 0x15a636a7, 0x39e95b00, 0xdfed0238, 0xe5c70f9e,
- 0x247f68c8, 0xbc2f80b9, 0x339657a8, 0xdaeac57b, 0x1fdfd99d, 0xc671038c,
- 0x8a13839e, 0xf3d05fc0, 0x2d2f9b21, 0xb680ffa3, 0xa51e43f3, 0x4e8c6fda,
- 0xdd7904d9, 0xb47ad7e4, 0x3afa1e23, 0xb9ee113b, 0x1e0c3188, 0x41bb019f,
- 0x1abcd79b, 0xabdeade7, 0x2c57691d, 0x4f961e20, 0xa97f611b, 0xda4773f7,
- 0x69a41589, 0xd030976d, 0xb88aa45e, 0xfb009fc9, 0x456bfd5a, 0xef64bf79,
- 0xbef6a355, 0x9fdf3f62, 0x65c7e426, 0xa0363f74, 0xfcc029bf, 0xa0e2757b,
- 0x65efd771, 0x9e3ae264, 0xbcdbfe8e, 0x9ebc30ae, 0x49c911d4, 0x40d27ae1,
- 0xc182ce4c, 0xe9cbc6ec, 0xb40d9f60, 0x1fa2cf17, 0xbefc3ca3, 0x6ed03230,
- 0xc01c593c, 0x0d93bdbc, 0xc09efe22, 0x918ddaf5, 0x97bfabdf, 0x2c20c9e0,
- 0x6772191f, 0x3764dfed, 0xc2abe76b, 0xc77fccd3, 0xe2fdb222, 0xca37160c,
- 0x6e245afd, 0x7a1df7d8, 0xdd13bf3c, 0x1f96c5f2, 0xebb67d00, 0xe3054ce5,
- 0x0b7bf82b, 0xf988a0e4, 0xa7edbd7f, 0x39041e62, 0x1e1c7073, 0xd793eb23,
- 0x938c4507, 0x4a5db4f4, 0xed0a7880, 0xbec6e307, 0x405ca78e, 0xe3cd43bf,
- 0xfaf10cd1, 0x08eef9fc, 0x1f8f28bf, 0xc99cb4f7, 0xf94efe01, 0xb019a3e0,
- 0xe2be733f, 0x15756cf7, 0xf9d1fd01, 0x1bdefea1, 0xa5fa8cb8, 0xf41c5da9,
- 0x19f5aafe, 0xcfe3eb86, 0x8bf20325, 0xf7c467d6, 0x095ab3cf, 0x7ece4019,
- 0xb4c51e5b, 0xc3570b83, 0x4dbd33fd, 0xb77f0b82, 0xb9445db9, 0x3a3da0b5,
- 0x4cbc50a0, 0x72c1611b, 0xee764ef9, 0xf9388663, 0x2e6ff07d, 0x7fa220de,
- 0xf2cb48f3, 0x6798f5f7, 0xe58327a1, 0x5de7f461, 0xc6147c3c, 0xdc14fc59,
- 0xc4ff4312, 0x6fd00dfb, 0x8102d3e5, 0xcc884a9f, 0x779818bf, 0x144f35d1,
- 0xc05de607, 0x6907e5f9, 0x466d15bf, 0x3c0faff4, 0x1bc840ef, 0x21f7fd09,
- 0xbc6f0ee5, 0x9f6d28ef, 0xf96062db, 0x3e35667f, 0x0ef685d5, 0xd0f3b209,
- 0xa74f073d, 0x877d1e03, 0xb1fd07fe, 0xd20fed43, 0x0e3cf2ce, 0x57dfb066,
- 0xd2fafdcc, 0xda419e9d, 0x8b3cf237, 0x327f7abd, 0x5b47b1e8, 0xe83f232e,
- 0x6cfcc83d, 0xfc4ff643, 0x0aefe666, 0x570fd19a, 0x0edf2ad8, 0x83ea84fb,
- 0xeedf5eb0, 0xd377b3b5, 0xbd55f9b2, 0x6f95aa02, 0x0bf705b8, 0xdff08fec,
- 0xc9f75203, 0x53a71e5e, 0x791a47f3, 0x3f9a8dbe, 0x4493e6a2, 0x27cd43ce,
- 0x7c614c69, 0xf3c32f23, 0x945bd001, 0xe77ecfce, 0x68cf2233, 0xc8a1bca8,
- 0x71910773, 0x8ae24182, 0x46c0af2c, 0xc6a06e30, 0xbe540d17, 0x31d647c3,
- 0xd06537b3, 0x227bfd7a, 0xc5434fda, 0x1c75d51b, 0x79865139, 0x8b2f5556,
- 0xb0bfafe8, 0xbce3cf5f, 0xe9438c21, 0xc8617c4f, 0x7ece7e44, 0xcb47c95f,
- 0x5937def0, 0xd28efcd2, 0xe71e1c57, 0xd9f07233, 0x978fb923, 0xe47b7ed2,
- 0xf5e80332, 0x4a0b13fa, 0x9de8de40, 0xd7980665, 0xa6c51391, 0x4d9bc04c,
- 0xb6b37dc2, 0x53b71d5d, 0x3ffffe86, 0x1f012a80, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7db5ff00, 0x55945c0b, 0xe779f8da, 0x380c2b9d, 0xa5117280,
- 0x380a0ee1, 0xdb95902a, 0x9784268e, 0x4d32d45a, 0xe5450757, 0xdb698032,
- 0xcbbaeee7, 0x5acd4d78, 0xb5aca8dd, 0xbcc0c1be, 0x1a163b60, 0x25a3b614,
- 0xb68b9599, 0x3f9b5b99, 0x0286f328, 0xffb9f562, 0xcffebf6d, 0x3af39cf3,
- 0x7e988ef3, 0xbf67dfbb, 0xde73877e, 0x73ce7d73, 0x9339cf3f, 0x196e39a6,
- 0x9eb19fd3, 0xcadb2d1c, 0xc87b3b18, 0x630d81bc, 0xf7fc07ec, 0xacf2c653,
- 0x18036312, 0x319abafb, 0x3e57deaf, 0x7c81fb3f, 0x02d8c196, 0x316358e6,
- 0x33235a43, 0xbfd191af, 0x1d1fb01f, 0xf281ee9b, 0x988357f9, 0x5dafc237,
- 0xb63d14f4, 0x94357f9b, 0x3d424779, 0x3677af13, 0x4f285204, 0x1872f1c0,
- 0x9de912cb, 0x6edf2d22, 0xebf69cb2, 0xa613c2bf, 0xc53557ca, 0xf9a74e58,
- 0x47f8e5f2, 0x636ffc0c, 0x98c91646, 0x97627f93, 0xdb74fc5e, 0x913f485c,
- 0x5856091c, 0x9ed48557, 0xb10c0f7f, 0xef57ba26, 0x2d3ae330, 0x63f29bcc,
- 0x5e608ceb, 0xd5ae71bf, 0xf5a46abb, 0x2566e0f8, 0x6bd6f9b8, 0x5d7c3826,
- 0x38137d1d, 0xe8e0aac6, 0x05413feb, 0x4ffbebc7, 0xaebff1a1, 0xff49bb4e,
- 0xbfd06f43, 0x5f7f3555, 0xee3449bf, 0x0b0d0caa, 0xa4f486cd, 0x5e00cdc1,
- 0xcb235500, 0x1d80cc65, 0x795654c1, 0x66ad19c7, 0x75257b5f, 0x6cb171b1,
- 0x946f7c14, 0xfdf0dc0b, 0x25ae6592, 0x985d5219, 0xa1dbb186, 0x705ecebd,
- 0x086bf417, 0x41708f0b, 0x89ac133f, 0xc2efaeb4, 0x28301516, 0x08f06eff,
- 0x838f15d9, 0xfcc42a2c, 0xf2c541aa, 0xe37f1c7a, 0xb5f70c73, 0x0fc7c8ca,
- 0xfc332fd9, 0xba30eece, 0x777ea193, 0x7996c7cb, 0x06dfce30, 0x3ee0e639,
- 0xc909f32b, 0x3ee19779, 0x6dc726b3, 0x3d8c2185, 0x0dac616e, 0x50f6daf3,
- 0x725eaf5c, 0x405de7fc, 0x06afec0f, 0x77c90f56, 0x25aa4726, 0xcabed7c3,
- 0x01f9a7aa, 0x68b2c435, 0xa50d5f5c, 0x08574d55, 0x8916d6ce, 0xaf7ca5d6,
- 0x77043d62, 0x8851e586, 0x7d2b5a93, 0x16a4726f, 0x71e6fa66, 0xccf7ffad,
- 0x9fd00d2e, 0x433fff61, 0xdadd9e11, 0x906dfb9e, 0x60e45a7a, 0x11aef87f,
- 0xf0763974, 0x50ed5937, 0xfaed895e, 0xdbd8f631, 0xf30ca9e5, 0x9c2c9e86,
- 0xffb7c1f7, 0xe90ed591, 0x6fcbfb77, 0x50edf2c3, 0x6ef90adf, 0xcda54f7d,
- 0x6624bfaf, 0xf9466971, 0x0fb16ad2, 0xf7dbe581, 0xf3881caf, 0xdcc1d068,
- 0xa59c61c3, 0x474f2365, 0x9fd83a20, 0xb5b8478e, 0xec3d58e8, 0x54d35747,
- 0xe54af919, 0x43058c27, 0xf619bb3e, 0x83d9f207, 0xfb035b99, 0x93ffb953,
- 0x955fb8e9, 0x068b7a39, 0xbc341296, 0xbe02bdcd, 0x2d18e507, 0x2c53e212,
- 0xeccf5f1f, 0xfb62258c, 0xb7dc08bc, 0x2a310637, 0x41f997ff, 0x6bdbc71d,
- 0xbc7bc0fc, 0xabc601b2, 0x47efdb90, 0xa17c003e, 0xf2a5f11e, 0x668e6fa3,
- 0x4f46b158, 0x78cfee24, 0xd0f8171c, 0x369fa2c7, 0xac0ee16b, 0xfbe0fdd7,
- 0x2de8b06b, 0xf5c0e1c9, 0xb68c62b8, 0x68cfc47a, 0xbf14c277, 0xaacd7d7d,
- 0x4ff0f6a1, 0x221dbc42, 0xa07bbae6, 0x22587167, 0x470ee5fe, 0x30d2a87c,
- 0x3643f207, 0x077a8009, 0xe66165e2, 0xe9ebcc94, 0xd415b18a, 0x7b56dbdf,
- 0x57c735b3, 0x336993ff, 0xd07d1d33, 0xc12a6221, 0x0479ef53, 0x6153d9e7,
- 0x7d856db6, 0x827e0bf8, 0x334f2f76, 0x5850e578, 0x56bcce8f, 0x193a3c02,
- 0x0075bb3c, 0xd9b57fac, 0x73ae1ef1, 0xd7e343fa, 0x183a5e60, 0x788c5d61,
- 0x8b9ed459, 0x726d12fb, 0x3be3807c, 0x22db8e8d, 0x06978961, 0xc1fb523b,
- 0x08c2b356, 0x98566f0e, 0xfce7d859, 0x797c7cf9, 0x54b841a6, 0x36f4b808,
- 0x7c43f626, 0x5fad7aed, 0x74f98316, 0xca095869, 0xdf312e87, 0x988f2073,
- 0x712e9f1f, 0x4117d31f, 0x63bad2fd, 0xeb7eb9fa, 0xeecc60af, 0xfc7eb8c9,
- 0x301fb88b, 0xffd785fe, 0xa1afddf8, 0xf76fceab, 0xc004b0a5, 0xad22e913,
- 0xc71dbbeb, 0x9df58b66, 0xd63ff5c5, 0x87a713db, 0x073d3975, 0x887f9cf4,
- 0x527b69f5, 0x5d7d6c7e, 0xc27cb69a, 0xa5927d8b, 0xaed7de3e, 0x7e58f1a2,
- 0x497be02c, 0x9908d85d, 0xe20a59e3, 0x061ba959, 0xa55bc3f1, 0x8b3e051f,
- 0x5debbf05, 0x1413e02a, 0x5af2859a, 0xfe328f81, 0xccf800a9, 0xe1e4f6d6,
- 0x0b2f663c, 0xea7e70d3, 0xbe51fc26, 0x1eaa59cf, 0x30e22577, 0x1bf5cfcc,
- 0x66f34dc9, 0x2b86ff3c, 0xf21ebdcc, 0xbf95cd06, 0x21bd454c, 0xbd436353,
- 0xf0104b61, 0xfd8c1180, 0x8bcfec59, 0xe18c1fc0, 0xcb16be54, 0xfb7883a3,
- 0xee3567e8, 0x70bed095, 0xe1e1336c, 0x9b6695cb, 0x3115630c, 0x8530ac60,
- 0x47aecc79, 0xe63d7fb8, 0x61dbfb1f, 0x1de2839d, 0xfeb0f151, 0xb89a1139,
- 0x1c3cd0bf, 0x9c032743, 0xc70e68d8, 0xc207b840, 0xe8b30a7f, 0x36c65fb0,
- 0xa7ee9068, 0xe652f858, 0xa78e9c4b, 0xc70ebb32, 0xa839907b, 0xbd2ef1de,
- 0x1c1d019d, 0x3060f407, 0x8b9887ef, 0x373067ca, 0x979933a5, 0xb59cffea,
- 0x03a15e53, 0xfd39ffc0, 0x8d9ffe39, 0xb26f0992, 0xc7be01e2, 0x2f06b382,
- 0x7e4c7585, 0x6199352e, 0x0803359f, 0xf79b373e, 0xb1c38964, 0x1db8eacd,
- 0xf05bdfd7, 0xd0354bed, 0x25e8c68f, 0x27c6bbfc, 0x78100dc6, 0xa27ce3f8,
- 0x09e397ad, 0x06398390, 0xd8af70e0, 0xe5ed7bd2, 0x8cbd7093, 0xfe9e4859,
- 0x9e5fd04c, 0xb3fd666c, 0x6dd97c71, 0xa5d8b9c0, 0xbe42468f, 0xd6cc8c60,
- 0x5bde3cc3, 0xbede48ce, 0x13765c37, 0x869f20ae, 0x7e8bf7f6, 0xba998d27,
- 0xcbd41faa, 0xdb3dbeff, 0x20c1690b, 0x7eed97dd, 0x7fbe35f8, 0x4830aaed,
- 0xcba92427, 0x2d36b227, 0x065275c2, 0xf3f1fb94, 0xf5d5b3fb, 0xe198e00e,
- 0x2328db98, 0x0f8ccdfd, 0x18267fe9, 0x90d843b2, 0xbd1f641f, 0x9de9eb28,
- 0x0ddf4574, 0xef10d8f3, 0xb2fb8b98, 0x67afbef8, 0x2d33bd23, 0xca2468fb,
- 0x5d7ca3a9, 0x00dd025f, 0xd5d3b206, 0x7e80d120, 0x883e80ce, 0xb7a073f9,
- 0xdaa17a61, 0xd045e94a, 0x577bf0b3, 0x9ef28db5, 0xec72c2f8, 0xcbdaee77,
- 0x4e06475a, 0x6df0852b, 0x36b7c089, 0x8c13578d, 0xb255b4f4, 0x625c7ca1,
- 0x0c1b1b6a, 0x1f525bf0, 0x671d836f, 0x569e4d65, 0xb7b17e9c, 0x75b71f30,
- 0xad45e1c1, 0x055c5698, 0x6cbd078c, 0x1ff85cae, 0x7f5d0788, 0x7dda72f9,
- 0x7ab67e50, 0xbe7f8d14, 0x77e34eda, 0xfa501756, 0x37e3bc7e, 0x4b7b0f38,
- 0x15846b47, 0xe132e577, 0x1d0d7dcb, 0xe7c858da, 0xd23b25d9, 0xe676dde1,
- 0x6d3d0376, 0xb5b971d6, 0xd216e419, 0x29cc98e5, 0x50ca3e2f, 0xc71e38ae,
- 0x509c1ef1, 0xdcfd879a, 0x8b48aa3f, 0x9efa1ef5, 0x1f7888b1, 0x8f0cddde,
- 0xbf5f0059, 0x7844b6f4, 0xfd634978, 0xae59ea19, 0x0be93223, 0x2a985abd,
- 0x727bdff4, 0x7b05db88, 0x626f78bb, 0xc5b7f214, 0xb8546b3a, 0x0ceb5f1f,
- 0xbb9d6be0, 0x97f68f6f, 0x9ee19d77, 0xbe433eef, 0x4be705f4, 0x5e6733b0,
- 0x8e65be40, 0x76fee1b6, 0xf404bb09, 0xcf9460c9, 0x47417a95, 0xdf3057c0,
- 0x14e6c419, 0xd5f73e42, 0x1748b1d8, 0x7caa1e38, 0x7949df0a, 0x5f84b9f5,
- 0x6de37d5b, 0xecffccf7, 0x725fc805, 0x903a5c6b, 0xa7989753, 0x575c4deb,
- 0xfa86d99d, 0x0da49a63, 0xea784a5a, 0x934c3a26, 0xc0a5daac, 0xfabc7657,
- 0x303fc0e2, 0x1b181bd4, 0xdadfdf05, 0xe77c4c14, 0xd4ed9d2d, 0x22ff6c52,
- 0x53caff6f, 0x09b2fcbf, 0x462b27d3, 0x3ef112fc, 0x5ae09c3e, 0x21d2fbfc,
- 0x63436788, 0xbfa01b61, 0x5e486f5d, 0x99631653, 0xc4560735, 0x6d867cc0,
- 0x840cd0e9, 0xb49d7874, 0x21a1d312, 0xf8658705, 0x95bc5efe, 0x21b231e6,
- 0x72458e5e, 0xecfee819, 0xa87fa4a7, 0x9a8c92f5, 0x320763cb, 0x44327e9f,
- 0x7dc05cf2, 0x62721959, 0xb63fc904, 0xdbd9fa91, 0x99e3f532, 0x7cd00eb4,
- 0x7a45de70, 0xb70bc91b, 0xecf116ab, 0x46cd2392, 0xeba17afa, 0x4bdfdc79,
- 0xca1b488e, 0x571a7d8f, 0xff589de8, 0xf9d69694, 0x50b1dd46, 0x35fbe41d,
- 0xbe0998ea, 0x21ef0c57, 0xd83159b9, 0xc1dc70ca, 0x805bdd2f, 0xdc6ca9f0,
- 0x38fd4b5b, 0xea09368d, 0xd2bdec95, 0x8d94728a, 0xc464b667, 0x7f9e46af,
- 0x86dd9c62, 0xf6a4b572, 0x2b6f9e5b, 0x58217ca4, 0x3fac5a13, 0xcf69eb8f,
- 0xdac53909, 0x117f88b3, 0xfb7d5aca, 0xc67c04f5, 0x5de39bef, 0x3ecc8b31,
- 0xe97206f9, 0x8c59d202, 0x1b6fb79e, 0xe08e333b, 0x49728b72, 0x3d39e7e9,
- 0x4e509973, 0xacfcb9ea, 0xf8817e07, 0x17fffd01, 0xd1c8aff6, 0x6cca5958,
- 0x3ec77584, 0xb4adb067, 0xd338fade, 0x3921adfb, 0x5575e8aa, 0x89585f42,
- 0x36fda055, 0x804e43b3, 0xb90be671, 0x0cd6b4cb, 0x319e43d4, 0xa409b5db,
- 0xa3de81d7, 0x4c667921, 0x0658bd40, 0x4fd12f3d, 0xdf8733cf, 0x366b3c92,
- 0xfdb143db, 0x2fefd6ad, 0x3157f9e6, 0x444b424f, 0x31c85748, 0xf23de03b,
- 0xa127764e, 0xeb0357aa, 0xe790701b, 0x6dfa1213, 0x7aba055a, 0xfa958252,
- 0x7c11f801, 0xca19e761, 0x243ca509, 0xb841e39b, 0x47fa48c3, 0xe1a2c454,
- 0x9af0fc8b, 0x1123bd69, 0x5bffeb0e, 0xbfa84af6, 0x1bb33ffd, 0xbe7025f1,
- 0x3fdc0945, 0xb9890bf1, 0x97578834, 0x45af54f5, 0x8febbed7, 0x34a5aed0,
- 0xed7686c3, 0xd821e43e, 0xf49ea84f, 0xe61096a9, 0x99697a42, 0x7d46e91c,
- 0xa7b42dec, 0x88661e90, 0x7c4626f6, 0x40c665ba, 0x0d0387e2, 0xf35c1800,
- 0xaf6f034a, 0x2641f45b, 0x963cbff6, 0xc94ac7e4, 0xf48136bd, 0xcbe49935,
- 0x6a8fc149, 0x6533bcc2, 0x9cb9af28, 0x939c70c2, 0x61569760, 0xa22092bd,
- 0x7b309abb, 0x7dd7f20c, 0xdf132dff, 0x790e19ab, 0xf225f133, 0xb64cd4c7,
- 0xfe4184c7, 0x351fb161, 0x67faeeb5, 0x69c9bfb1, 0x3281aeb4, 0xe2f5445b,
- 0xe99f3f79, 0xfdc73b78, 0xdbd45ac1, 0x20c50241, 0x4e285efc, 0x2a07c866,
- 0x44cec613, 0xf7ec52bc, 0x28df82e9, 0x630363fd, 0xfc63ea2e, 0xf5f98cdf,
- 0x07aba426, 0x201d4c4b, 0x92c9d839, 0xbf682115, 0xbd90e83e, 0x1e5bd406,
- 0xd35fb3c8, 0x7fb0120b, 0xb3c24cfb, 0xf27ec562, 0xbdb843ce, 0xeb6463dd,
- 0x7d847f49, 0xdf1ebccd, 0x22633c2a, 0x52c7edfc, 0xf397a703, 0xd7482f38,
- 0x714a3b07, 0xe34d55de, 0xcaedfc23, 0x8757f319, 0xf18bdd12, 0x23db562e,
- 0x5ea1274e, 0x32a94050, 0xc14e329e, 0xea5da314, 0x818df68f, 0x4239aaf4,
- 0x7832ad0f, 0x4dfd21a7, 0xa31e3937, 0x642eca71, 0x7fd8bea1, 0x9c3f5a4a,
- 0x32fbf77f, 0x253d3c43, 0x3214f5f6, 0x45a7c46c, 0x4c2f8421, 0x8ebf1de4,
- 0xf41cfd20, 0xc737c21a, 0xde5286ef, 0xccc7b7a1, 0x1c5cfc47, 0xca71f84c,
- 0x729fbfc2, 0xcd7e1186, 0x87f95dfa, 0xaa7be00c, 0x78784f50, 0x3f2645aa,
- 0xca96dfcf, 0xb9c03d5e, 0x67d5ca6b, 0xd75da053, 0x3772afb2, 0xe2beda43,
- 0x3f9438f3, 0x4c5456b3, 0xcab376c2, 0xfc8fdd96, 0x3d7446f9, 0x441069cb,
- 0x35b6e1cc, 0xd711bec1, 0xd5ca7fd9, 0x03cbe47c, 0xcfcf9dcb, 0x0983f287,
- 0xcf88678e, 0x112bdbe8, 0x7d6f951e, 0x73fa8711, 0x7b2bf377, 0x6dfd215a,
- 0xfa79e388, 0xf8dee2be, 0xb099d8d5, 0xb0b52abf, 0xb73f805f, 0xc45e3a27,
- 0xbce355ef, 0xa2eed829, 0xe11f2dae, 0x9add96c6, 0xa5a17dde, 0x76849f7e,
- 0x254b5060, 0x0b3bb2a5, 0x7929d1e7, 0x8444a543, 0xb00be823, 0x6f168bee,
- 0xb9e21868, 0xb7cbc3d0, 0x5347d7ab, 0x077e148b, 0x91ee5768, 0xb3d226ed,
- 0x6f9c7add, 0x2872fd60, 0x58b77aa7, 0xbc3cc65e, 0xa9e9ac3c, 0x7b7ef8bb,
- 0x179fb0bd, 0xc56f2476, 0xf7b4befd, 0x3b7f1495, 0x7ebd3038, 0x17fd7cbe,
- 0x8e00bf11, 0x8744a117, 0x5060d5f8, 0x3b5d7fd9, 0xd5f85462, 0xbdd523b5,
- 0x762f8fde, 0x6cc1be09, 0x88c9dc9e, 0x2e4f76f7, 0x9f0a55ea, 0x164f4660,
- 0x9e696fd9, 0x1457b42c, 0x3d0ac33e, 0xf6ee5429, 0x7dfd60a4, 0x7d9acf68,
- 0x8aed96e3, 0xfdcf5dad, 0x364d2e8e, 0xc56e87e6, 0xcdefd2bc, 0x59ba97d6,
- 0xbba7caaf, 0x09d3f9d5, 0x73b69fdc, 0x83b15ea7, 0x30476165, 0x568fb2ab,
- 0x5c11afae, 0xe057aafe, 0x2e6c68f2, 0xafe00dfa, 0xe7379a04, 0xddb93be3,
- 0x23b86fbc, 0x62a9f916, 0x830bef9f, 0x51ca067c, 0xaf256f3e, 0xde7021c0,
- 0x20bafe2b, 0x967bfd16, 0x4e508d44, 0x3f88516c, 0x2f9c4d2b, 0xbe81d4ad,
- 0x4976819a, 0x5ad3c8c9, 0xd16c57b4, 0x1c1f5ac5, 0x6e1e6c16, 0xb85d3a44,
- 0x1fd1b865, 0x1f6e561f, 0xf30ad879, 0x6b5db8bc, 0xd4af29c3, 0x7d429fba,
- 0xd976e56c, 0xddf462e3, 0x17fa8768, 0x628f07cd, 0xb85b05bd, 0xbf69429f,
- 0x744e7370, 0x873cdfb1, 0x33c3576e, 0x0fcea3d3, 0x07e7526b, 0xf391aea2,
- 0xdc376f3f, 0x3c8fceab, 0xfd9fceac, 0x10d3a3cb, 0xd7644aed, 0x87ea3253,
- 0x461fe79f, 0xdf6e71b9, 0xdfe4a11b, 0x15b8a2f9, 0x9b85def5, 0x7d8670d5,
- 0x701f5093, 0x2e48936d, 0xe903ba96, 0x65ba6fa3, 0xd7e2b96c, 0x93c7f34b,
- 0xd56ae632, 0xbf5f5fc6, 0xd9a67993, 0x74b48fd1, 0x23d3c8f1, 0xe1defd7d,
- 0x7b47a4d9, 0x1bdc7027, 0xdb3329d1, 0x165f68ad, 0xeedfe28d, 0x7d963a5c,
- 0x6d882205, 0xf88f9638, 0x4484f457, 0xf5e8b6f2, 0x2f9177d4, 0x3199ec77,
- 0x0569d281, 0xcfc50f04, 0xf245b0b2, 0x32de4086, 0xfcede38a, 0xc19b92cd,
- 0x32aee7bc, 0xc541fca8, 0x58f3d41b, 0xbefea350, 0xdfc0e9b0, 0xc4bfe825,
- 0xe51e92f8, 0x4316c956, 0xfdcb1f80, 0x65e1ea0e, 0xd9d918e7, 0x183f7565,
- 0xcd73f2fa, 0xbae1d657, 0xb8fae19b, 0x07d3e78a, 0xf806634f, 0x857efef8,
- 0xfea11233, 0x32b5359d, 0x3982adc2, 0x9224b31e, 0x860de99d, 0x7d002c79,
- 0x9069f509, 0x2baeb4b7, 0x0db9fb9b, 0x4cce54f1, 0xb5857e50, 0xbe1ca2e5,
- 0xe36218d2, 0x5cb6b0fe, 0x4217e40b, 0xc256e11e, 0x9c7c1236, 0x8e657fc8,
- 0xf9bf762f, 0xe7f93ee2, 0x8fae46d9, 0x03deb53b, 0xd6728708, 0xff70ed4e,
- 0x6139ebfc, 0x51c3275d, 0xcf6808df, 0xaf0fe46c, 0xdf69eb32, 0x307e9aaa,
- 0xec577ff8, 0x512ec500, 0x59ff6dfc, 0xe21070f6, 0xfec96af5, 0xd4c651bc,
- 0xf115a7bd, 0x724cd4b8, 0xce5ae1fe, 0xd9d06bcf, 0x6cd7fd02, 0xf37d274a,
- 0x829ec961, 0x4c9b65eb, 0x1e810764, 0xdb3abf18, 0x3e81d7a7, 0x9fa132e8,
- 0xbdc834b8, 0xe70fbf15, 0x8ccd79f6, 0xde17d214, 0xe45e3c92, 0x3867aec3,
- 0xe64cd4bd, 0x64f353f8, 0x0cff7d0c, 0xfa831aa7, 0x6a4bd722, 0x3d72a536,
- 0x60f3e656, 0xfe210bbf, 0xe62f1358, 0xf34ac035, 0xc9f5f452, 0x8973c716,
- 0x5e2ceb7e, 0xf4247a01, 0x995bfc5f, 0x95829fa1, 0x3c92dc44, 0xaa7217af,
- 0x8dc99367, 0x52d3eefe, 0x3f9e2b61, 0x13dfb35c, 0x1dcfdf39, 0xea26df6b,
- 0x58bc5f91, 0x4ffd7933, 0x3567bc71, 0x7ef195d6, 0x53dbb7f0, 0xbd3fcf50,
- 0xf70234c9, 0xce70d4e9, 0x72c773b7, 0x25d801bf, 0xee90adf6, 0xfca8d449,
- 0xb9127bab, 0xd13fb09d, 0x3ce9e94a, 0xc90c47ee, 0x0cff242e, 0xf1f115ec,
- 0x17ec75c0, 0x85f58aed, 0xc7d27e47, 0xb0f8147c, 0x4e7f7c71, 0x5c91223f,
- 0x58a4f584, 0x7bfb9f20, 0x4e75f913, 0xeca2f90b, 0x0e51e00b, 0xbfc15bc9,
- 0x49fc459e, 0x27f014c4, 0x51fc2fbb, 0x60c3c7e3, 0x7f1098ef, 0x1f683f00,
- 0x327afc15, 0xf011f693, 0xe7a1f087, 0xf00dd349, 0x285f6d47, 0xe5a9adeb,
- 0x5da047f6, 0x3270f801, 0xa0bcefd1, 0x0427ac26, 0x3c14b7cf, 0x8e775a60,
- 0x205a39ff, 0xe6c9e41e, 0x4befe434, 0xea1b20a4, 0x7f844bdd, 0x467cc97b,
- 0x8b658df3, 0x68d7a424, 0x0ec895e6, 0xec266d66, 0x003d27ef, 0xfc3a3f73,
- 0xf32355e9, 0x58637b97, 0x8f7f2a98, 0x3f554631, 0xfaaf12cf, 0xba746f7e,
- 0xeb78fbea, 0x627e5570, 0xfaaa1dda, 0xa8c6d9f7, 0x351b3ff2, 0xb27f555e,
- 0x6f2ab27d, 0xce2d1667, 0x60baa5bf, 0x6f1fda24, 0x5e921757, 0xd1970810,
- 0x5baf8386, 0xea46206d, 0x00b453b4, 0x0efdd1bf, 0x7c87892e, 0x14d33aff,
- 0xe8c7e02d, 0xe25783d8, 0xd5a2602d, 0x43eff105, 0x80495e0f, 0x305d747c,
- 0xc8c5dfcf, 0x67581f1e, 0x9332e29e, 0x093630bf, 0xeaed3ce0, 0xf66843a2,
- 0xca7cb27d, 0x75a478fc, 0x3ff33267, 0x7566d8b7, 0xe53d6184, 0x547f52bb,
- 0xefb52152, 0xfcf9ccbe, 0x393fb827, 0x760a7aff, 0xb18fc917, 0xac6c341c,
- 0x5be74cd1, 0x78bba8cc, 0x7c0cafcd, 0x8633b253, 0x6a96b9fe, 0xc22d67d8,
- 0xb7a948cb, 0xc1e942da, 0xdf4a68ea, 0x62b2b6ad, 0x756b6780, 0xab87a51a,
- 0xa47e546d, 0x1fa5147a, 0x3d29db56, 0x69405d5a, 0xa521755b, 0xb34f2812,
- 0xb36c6f90, 0x3c21d5ad, 0x33b0da5c, 0xd9fe3e30, 0xe1f2df17, 0x519d96ad,
- 0xff2a15f6, 0x4dcf64ca, 0xb20d75a2, 0x945b9f90, 0xa9ffda1f, 0xe8d1f915,
- 0xf5e1236c, 0xd59b7368, 0x48f3cd98, 0x99977567, 0xebca1357, 0xf5ebfd69,
- 0xfe470cf7, 0xa669da30, 0x50bd497a, 0xbdeb0b2f, 0xf2c5a317, 0xca1b7a45,
- 0x3f04e7cb, 0x901cd10e, 0x5e909c71, 0xc834367e, 0x144ef9c0, 0x5df85fa8,
- 0xf5d5a3f1, 0x8706f1f2, 0x9df3a22f, 0xc4cdb3c1, 0x15b9147f, 0xc18de11b,
- 0xd12ec5f9, 0xe6887953, 0x2efd15b8, 0x09ded55d, 0x84e3af88, 0x67a71f9c,
- 0xa60f3869, 0x94f92209, 0x1adf7f27, 0xcdc5f90b, 0x398c70d2, 0xdc286718,
- 0x96a1f642, 0x6feb31d3, 0xb6b8fae2, 0xa815f4ad, 0xd6323c77, 0x15a11eb6,
- 0x81258fbd, 0x5557959e, 0xf2728190, 0xf448db38, 0x31d43f3d, 0x6a6df10f,
- 0x46bdd006, 0x13f40920, 0xfc4c105d, 0x6a7f7bb3, 0x53cdea0e, 0x0cbdd60c,
- 0x292ca2e8, 0x4a7ef087, 0x648e6b3f, 0x445dfcc1, 0xaca25327, 0x9e1b257b,
- 0x194ce49e, 0x71bfc777, 0xd2493d2e, 0x7ca9c7fa, 0xc31e3922, 0x5c1455f9,
- 0xf5f9f3d2, 0xebf89e90, 0xb3f12b24, 0xc9190701, 0x21f19edf, 0x7fd15fc4,
- 0x61f918b5, 0xeb073586, 0x427ae9c5, 0xfba0ee31, 0x5dc52d7b, 0x07d0cd40,
- 0x2f1efcfc, 0x8c78f0b5, 0x9a1bbc40, 0x554de5cc, 0xaa038f12, 0x291a368c,
- 0xcf9cb96d, 0x30a24e28, 0xd036ed09, 0x5794fb1e, 0xdcb99383, 0xe7a35f8b,
- 0x49643afe, 0x107b6530, 0x8c2ef253, 0x2c7da907, 0xecee5148, 0xc7a64e00,
- 0xe87f9476, 0x5492e3f7, 0xdf58edf5, 0x11d99df7, 0x9dfb4a9c, 0xbf7e9375,
- 0x43c62b4a, 0xdcc0597c, 0x7e4084b8, 0xb87245fe, 0xfb411e72, 0x137f62fc,
- 0x324993d9, 0x71e037e0, 0xfc87b06c, 0x8e26757f, 0x9e1a49ef, 0x77f869d6,
- 0x93e8107d, 0x790c1f90, 0x3efa773c, 0x1e49e1d9, 0x0599ed40, 0xa87bcbdb,
- 0xd0f30c7d, 0x28f7ca78, 0x9d435ef4, 0x304f2041, 0xfa6b2d1d, 0xe498db84,
- 0x7d211f31, 0xf91f0177, 0x775f8fda, 0xf52e8705, 0x6c4aa7df, 0x376ff66f,
- 0xed29da96, 0xd86a962b, 0xffc411d7, 0x922a5f08, 0xb7377634, 0x5095df37,
- 0x7a6d604f, 0xbb4a6b94, 0xbeefc013, 0x05ff7806, 0x27a61ff8, 0xf8e1ef81,
- 0xc3df019f, 0xf7c06ff4, 0xf014fcb0, 0x81db4c3d, 0x97f961ef, 0x9d30f7c0,
- 0x1b243336, 0x69aaa4e9, 0x855afb0c, 0xff873af7, 0x3189ddf9, 0xd9cbe37d,
- 0x9ed76e24, 0xfbfbef88, 0x7c71277f, 0xdf37713a, 0xd7906eb7, 0xfe019fa8,
- 0xdf84b2ad, 0x87776e58, 0xef9e73f0, 0xd77eb8d2, 0x5ff3c31d, 0x3fa8e926,
- 0xc66d86bb, 0xe9a5dff6, 0xe649ef29, 0xf85ba372, 0xa8ff012f, 0xc31e657f,
- 0x7aaa4a86, 0x814d24ee, 0xdef98fbb, 0x23c7cc9d, 0x1c3d44fc, 0x0fde31f1,
- 0x84ad2b3f, 0xf178819f, 0x249ba085, 0x58bbc703, 0x27c8f1e4, 0xbe744ca3,
- 0xe3b5f30a, 0xc49d7479, 0xfc3af1f1, 0xe77b70d4, 0x7e84fc3a, 0xe7804e08,
- 0x093fa412, 0x35251fc0, 0x45b77988, 0xe082fc86, 0xa0b3a2dc, 0x3227efff,
- 0x6bdb1600, 0x84ce8f7a, 0x10c8d8f2, 0xe41d9e2b, 0xd45e6e3d, 0xebb8ff17,
- 0x35ff5ddf, 0xffaf547a, 0x738b75ba, 0x375d5b93, 0x97e413f1, 0xf07d3f88,
- 0x1fc82187, 0x33f87c72, 0x849ed926, 0x264b74fd, 0xbb81fa2d, 0x022f1c4d,
- 0x1a5dfbd7, 0x3f055fc7, 0x18fc40be, 0xbac3fd80, 0xb9eb7d12, 0x80a0ff36,
- 0x14642df5, 0x8fb8110f, 0x5bf15f0a, 0x39c91dd7, 0x2601b83e, 0x041efc92,
- 0x71fd1bf2, 0xc70b649e, 0x676701f3, 0x81f9426f, 0xffea0272, 0xfafdc341,
- 0x56bedf0a, 0x2673c92e, 0x39f8a867, 0x67b07b43, 0xcbe881bf, 0xaf2561ab,
- 0x43825da1, 0x8f59d9f9, 0xf6f5f325, 0xa0d64f4e, 0x9df5d4de, 0x27f145d9,
- 0xa14e7b03, 0x59b5d67d, 0x6d3db8c7, 0x3c81249f, 0x057e8f9b, 0x8dc5fa2b,
- 0xa17b6e74, 0xd43d991a, 0x853e5cf3, 0xf3d56176, 0xe8023332, 0x9dbfe7e4,
- 0x60b2f886, 0x7a82cebf, 0x4fcdcac7, 0x3b7c461f, 0x515928d3, 0xc23577de,
- 0x457ea1b2, 0x04db884d, 0x8f21f3f5, 0xf59a17f5, 0x8f1f2b6e, 0x18a74cf4,
- 0x65536bef, 0xefa5fa02, 0x70475e79, 0xc783b05e, 0x79b3bc31, 0x9f639d09,
- 0x0a2c4b71, 0xcbcbe5da, 0x9fd0635a, 0x3364a2f8, 0x39a73b40, 0xefda3cff,
- 0xcd983b65, 0x3d8afe8b, 0xb2be7421, 0x7f1d46a0, 0xa4dee250, 0x64a27d47,
- 0xacbcba8b, 0x9d879d4e, 0x6ceb7e21, 0x3c33c750, 0x15e22c92, 0xf270d9d2,
- 0x9384d633, 0xd3f0a01e, 0xf631d91b, 0x324f9cc5, 0xfa244df6, 0xdffde549,
- 0xe6697dc6, 0xdf22c9f9, 0xdf4bf901, 0xe0517df2, 0xbf9ca952, 0x4f6cb0c7,
- 0x99dfc636, 0x55c7682c, 0xca157f36, 0xa82cee30, 0xcfa27efd, 0x538a6537,
- 0xbb24d75a, 0x2d15be10, 0x3e3197a6, 0x31ef72af, 0xe10435bd, 0x01e908fe,
- 0x1ad732f7, 0x1abcbfb4, 0x3c236b0d, 0x15ff236a, 0x202cf7b3, 0xc9b370bf,
- 0x6f3de742, 0x133ada7e, 0x66257bf3, 0xdc1c7dc2, 0xe0b2784e, 0x75ce9979,
- 0xb93e6a19, 0x71913c3e, 0x3d9f715f, 0x16bf68fd, 0x3ee3bee2, 0x3ee3bec3,
- 0xd89fb8cb, 0xe6ef443e, 0xccedc278, 0xfef9db33, 0x2f9efb2a, 0xdf93d06f,
- 0xf3ef96b8, 0x3fd7cf3d, 0xa078441b, 0x680f0263, 0xe16ccfdf, 0xbfdfaefb,
- 0xf1103f5a, 0x0f0036b7, 0xf0d70d9a, 0x1d77e700, 0x7fec041e, 0x07cbf0a9,
- 0xfee041e2, 0x44f82bdf, 0x10fa3c9e, 0xfe2cd9c6, 0xf1571f05, 0xef0ecd73,
- 0xaa0478ac, 0x11ff1a9c, 0x392cdd9a, 0x049635fa, 0xb421bd72, 0xc0f909b0,
- 0x86bb09f1, 0xfc099c53, 0x9c524633, 0xddefc11b, 0x053dfd5f, 0x7e3bbfe9,
- 0xe23796f2, 0x703aff69, 0xc161dd1d, 0x96ee7e5c, 0x1b9512dc, 0x538006bc,
- 0xa451f01e, 0x81b6f643, 0x07ba91ce, 0x31e8f43c, 0x693f77c8, 0x48f6e1b6,
- 0x951f6e76, 0x1277bcb7, 0x31ac86fd, 0x9fb2aecf, 0x8e537d84, 0x6f7e15f6,
- 0xefcafb00, 0x7cb24e3c, 0x4f3eed44, 0xcaf5a04e, 0xb266db1a, 0x9598ea83,
- 0xe3af63ce, 0xbdf88cf7, 0xa1ba07e2, 0xf7c0163e, 0xeb9efc7d, 0x2835cc61,
- 0xb14be90c, 0xb47e14b3, 0x0f4bf850, 0x1b44763d, 0x03aceb81, 0xb5bee3b8,
- 0x8fea1f00, 0xdb9d3d7e, 0x8dd1f92a, 0xf1167fa8, 0xce78e00a, 0x469f68b5,
- 0xd332fc46, 0x0f029d7c, 0x605f112b, 0x07d9659d, 0x775f5142, 0x6ce1fe0a,
- 0x497f210e, 0x8f98db19, 0xe30655f8, 0x9bc0fb79, 0x487bedb2, 0xde19bfcf,
- 0x655bfa28, 0x3fdebaa3, 0x250c9f90, 0x03f9927e, 0xfc69dfe0, 0x37c7c73b,
- 0x7e8ce4f2, 0xcbdc0718, 0x6e90fdac, 0x52d7246f, 0xfb290337, 0x36ee9bf5,
- 0xcfcaad32, 0x33e5516f, 0xfaaad13d, 0xaaac9ac3, 0x69bdc3ef, 0x0f23efaa,
- 0x9cf954db, 0xfaaa51b6, 0xabb49fb7, 0x17b477f2, 0x75dfeaa8, 0xef9550ae,
- 0xfcf580cd, 0xbdd739c8, 0xfeaa92d1, 0xd549ab78, 0x042a683f, 0x6169899f,
- 0x335ef2aa, 0xfa8dd387, 0xeea6cfbd, 0x7f6fb157, 0xffdd4a36, 0xdfbabb64,
- 0x6d87dd5b, 0xa0b52720, 0xb9076f6f, 0xd04ee989, 0x6fa0b5cb, 0x8e5e8037,
- 0x2f4157f9, 0x7a03d4c7, 0x06bf9639, 0x1be6397a, 0xfcc72f41, 0x3023b03e,
- 0x405d54df, 0x85d59be9, 0x78337e54, 0x0f718ab5, 0x888f718b, 0xc4db1971,
- 0xe04dfee5, 0x7f68a1f2, 0xc36fb454, 0x3c3e49f6, 0xd64828ac, 0x1d3a055c,
- 0x8f5e7e13, 0xc5f65ae7, 0xd768f9ed, 0xb32fbcf7, 0xcc2740ad, 0xdd5c3ee1,
- 0x0452e51f, 0xec2faf3f, 0x0efd00f9, 0x2d137b95, 0xaeb06e78, 0xf8a3e3e9,
- 0xb651abbd, 0x6c1ddd22, 0xfb142afa, 0x141578b9, 0x9e4291bc, 0x77f9de41,
- 0xf0f5f946, 0xc7d5e31d, 0x964501ef, 0xe48794e4, 0x2524c5d4, 0x0e7ba6ef,
- 0xf47b0d85, 0xb6fe74ed, 0xefbfbe87, 0x6fbfa9d1, 0xb77d55af, 0xf73c7d60,
- 0xcec9bad5, 0xf4a4d0be, 0xcefaa5e7, 0xfa8ec924, 0xefed85f1, 0xb738c1ac,
- 0x11453d8a, 0xde567e78, 0xde722c70, 0xd2ffc08f, 0xc8195dbe, 0xa19a2bd7,
- 0xbfafb33f, 0xc89d668a, 0x933bf9f3, 0x2387e4f6, 0x18906edf, 0x6c8b928a,
- 0x950dc523, 0x913bd537, 0xcda7952f, 0x4e39e1d4, 0xf61647b7, 0x73c38f3f,
- 0xc7d7185a, 0xe742573c, 0xf27fbf41, 0xe31fba1c, 0xde5bba69, 0xbb71c509,
- 0xdf869ef1, 0xc2913efe, 0x5227daf5, 0x8b87bdf8, 0x6284ef8d, 0xcf3ac5fc,
- 0x5aee1c3b, 0xa0ffad2f, 0x4a4377c8, 0x69926ef0, 0x3557a5fd, 0x7f4a0fb4,
- 0xd4c8a6cf, 0xe4a6f8cf, 0x71d75c10, 0x8dcf1f0f, 0xce3005c1, 0x62a2a4f8,
- 0xe891ff9c, 0xe9323919, 0xdc6fdc75, 0x3d62643d, 0x8e7813ea, 0xf5dd97de,
- 0x55b7e89a, 0x9fbdf7c4, 0xf22b7af4, 0x110523db, 0x880649c3, 0xb8533b7a,
- 0x77af919d, 0x389ca124, 0x1f92b66e, 0x62414579, 0x41efee08, 0xe0bcb14c,
- 0x97cbf265, 0x8ef1f235, 0x1142da5b, 0x8e378eef, 0x516f5194, 0x71c3abfa,
- 0x6facf8fd, 0x4fb45cdf, 0x335aee25, 0x3fdbe3f6, 0xb14eee5e, 0xee23bb50,
- 0x3f50d363, 0x4c169e3a, 0x9eab45fa, 0x37977b9f, 0x78f6fd70, 0xecad6c4b,
- 0x16e15e77, 0xa69dd1fb, 0x6aed7da1, 0x337a89d2, 0x9eaa99eb, 0x9d57ef8e,
- 0x77163e7a, 0x57a853c7, 0xe9945f3b, 0xb7538eee, 0x7fd71228, 0x7e7a8b76,
- 0x4ece0225, 0xd232379d, 0xcd9d5f0f, 0x4cc6e8d7, 0xd0acde78, 0x53f69589,
- 0x69e3c7d9, 0x1e3b2f5c, 0x390befcd, 0x5e13d4f7, 0x5b7de4fb, 0xb11dea3c,
- 0x4ee3c1ff, 0x2ad7666f, 0x5d9f80fa, 0xd3aed0c4, 0x68e62415, 0x3f727c12,
- 0x79fec52b, 0x97b400ca, 0x040ec90a, 0x3f210f64, 0xfdc3ea08, 0xedfeff90,
- 0xb7b71c59, 0xd440f411, 0x134d8c83, 0xaf4afef0, 0xe604080d, 0xe745bbdb,
- 0x198bf616, 0x4205d2f5, 0x756b3d2f, 0xbe78cae4, 0xeb435cb8, 0x81dd8272,
- 0x825d8a71, 0x13da5ddf, 0x07d233ff, 0xb416cb0e, 0x70f1ee67, 0xc0d9d63d,
- 0x4f4ad2f5, 0xa346effc, 0xb3a0ddde, 0x535a0559, 0x2fd0ac5c, 0xf5bd08ce,
- 0x3d1ef2cc, 0x25fb27d9, 0x5ff434f6, 0xce89b4d2, 0x7e842bab, 0x90372151,
- 0xb370b09e, 0xbd002f5a, 0xdf2f9545, 0x0837a81e, 0x5d47907f, 0x7277d8ae,
- 0x21fd35ea, 0xd011ed1d, 0x0e90a34b, 0xdcad53a2, 0x93ec266f, 0x28b69925,
- 0x5a75f7a4, 0x4fc504eb, 0xdaaaf080, 0xce297aff, 0xb20ceddb, 0xf4b0bd91,
- 0xf76b824d, 0xe90edc37, 0x8f04668e, 0xdbe1c66e, 0xbbf1c4dd, 0x8db9274a,
- 0x95d01ed8, 0xee4a33fa, 0xba87a8e5, 0x2f89437a, 0xf4805631, 0xb70678b0,
- 0x0be8ed37, 0x850bf485, 0x29f9140e, 0x5bbfba71, 0xf9872edb, 0x54e487f1,
- 0x138e77ae, 0x424b3b71, 0x06bf246c, 0x9d9eb91a, 0x8e19e257, 0xec1030f8,
- 0x9f9f8368, 0x2dd9a07a, 0x52babd61, 0xe45717ee, 0x45ad64f3, 0x7e2bfd87,
- 0x4cfce522, 0xb7895fe9, 0x16ff69bf, 0xebecdfe8, 0x0fdde01f, 0xdb257de1,
- 0x6e39f246, 0x6d2f72b2, 0xb2a3d111, 0x6f808b9e, 0x1f451fe8, 0x739bee0a,
- 0x7e7c81cb, 0xf746ddfe, 0xf943f2cc, 0x5c45f23c, 0x4f107e73, 0xbf72a4c7,
- 0x0e54cacc, 0x2a9166b7, 0x549beb7c, 0xc854d8fb, 0xf23aa7b7, 0x42dca953,
- 0xdae4b9f8, 0xa88c807d, 0xeef83ef6, 0xbdf88fe2, 0x0f402bbb, 0xbe7e7fc8,
- 0xa926b248, 0xe78e22f4, 0xe308bc55, 0x468c4e1f, 0x6decb838, 0xce789169,
- 0xce6be9ce, 0xc9359352, 0xec2e4fdf, 0xc4db0c2f, 0xd1529c73, 0x4a52c4be,
- 0x4b1c15f7, 0xd7e8ad23, 0x487a42af, 0x07fe39b8, 0xdbfc3de2, 0xc956f882,
- 0xde7e360c, 0xa6ddf81e, 0x417b3d45, 0x09c45d00, 0x4875ad3c, 0xfb598e74,
- 0xb9fb96bd, 0xd7e44966, 0x790a107a, 0x57a8b7bc, 0xa3e28632, 0x9d2c841e,
- 0x17f4d503, 0xe9fdafe7, 0xb101ea7c, 0xdc4507fe, 0x279d21c0, 0x8730fd1e,
- 0xcdf9f82a, 0x73a1e60c, 0x8dac59e2, 0x95c113d2, 0xb9d4bd7b, 0xd1da306b,
- 0xe40c3a9f, 0xb55da9ff, 0x6bf90435, 0xc1655b16, 0x93202373, 0xbc8c3fed,
- 0x78119eb1, 0xbdc4a4be, 0x9edcfb2a, 0xf11ab85a, 0x51ec1ce0, 0xdbeb88f4,
- 0x97b27f97, 0x1f3a69e2, 0x43da7d7d, 0x1e9bed0c, 0x5b28778a, 0xee9a3c34,
- 0x5b58b855, 0x7f6fae5a, 0xf654fd95, 0xaaacca0f, 0x0cb5857d, 0x674cf802,
- 0xe95eb93d, 0xc0a9fbe6, 0x33d74e39, 0xf2094115, 0xe050f88b, 0xaf702b3e,
- 0x3dc48b64, 0x674745a0, 0x5787fd40, 0x4fa8ac69, 0x37efb75e, 0x89af1fd9,
- 0x4886f27f, 0x68dea764, 0xfa7d94bf, 0x742fb8b9, 0x3bb78c32, 0xfc9973f9,
- 0xfbdbff7d, 0x63aa4df5, 0x3bc92a7f, 0x1b749f4b, 0xa237a748, 0x034b39cb,
- 0x4e8037e8, 0x0da5d1af, 0x3fdbf3fe, 0xa250d2c7, 0x9d7f6547, 0x517fb056,
- 0xd884b5fe, 0xfdfaecdc, 0xe7163b44, 0xb128d653, 0xa15ba417, 0x7bb276d7,
- 0x700bf703, 0xe0f28ec5, 0x553a00f3, 0x7c46f1f6, 0x277be14b, 0xbb9e5cf4,
- 0xfce9931e, 0x7bc90bf0, 0x2c7c82c8, 0xd7dd38fd, 0xb17fea52, 0x23f06dbc,
- 0x6317cfd0, 0xcf427a78, 0xbc94f9e3, 0xe5fb883d, 0xb83188be, 0x485ffd70,
- 0x9e5163e9, 0xc7fd217f, 0xa51f3cfd, 0x467e62b7, 0xe40b58d4, 0x3f14e84f,
- 0x87c10ade, 0x3c7fdcdd, 0x5471f6e3, 0x32ef624f, 0x2ff5bf7f, 0xcf5bf225,
- 0xf38e9601, 0x5cfb1f8b, 0x9f940241, 0x70e255fa, 0xac5b5f3a, 0x62e50fee,
- 0xb8fff93c, 0xd5f776dd, 0x86515d1e, 0xf26b9c6f, 0x5e65dc6c, 0xf64c9c5e,
- 0xad808941, 0xdb9d3c3d, 0xcf7e6ea9, 0xbd379150, 0xfb375f87, 0x0bcf27fb,
- 0x7cb5ee7f, 0xfe7193fa, 0xb6c0eaf2, 0x9fb05227, 0x0b2bbd12, 0xab9f1bef,
- 0xca1c43fd, 0x8f6d92f5, 0xb99e90a7, 0xda0a5d6d, 0x9f5b250b, 0x3e53b148,
- 0x8af641d8, 0x73bbaf96, 0xaf2f1df7, 0xeb6bd3f7, 0x3f9eb9d3, 0x0f2078cb,
- 0x4309cdf5, 0x3f46ad2f, 0x24aff278, 0xd6f44c8b, 0xe0e51ab6, 0xef8e34ec,
- 0x7c48c6ac, 0xa2fde199, 0xbefed8fe, 0x47c7e43a, 0x15d2bed2, 0x34ecbd43,
- 0x3663c12d, 0x82886f73, 0x64ad6cef, 0xf5fe67a9, 0x6139d307, 0x1f492ad1,
- 0x5be51fdd, 0xe3b470d8, 0x68c2d3b2, 0x0ed7731e, 0xd9f2c56f, 0x04f978cb,
- 0x38f1bb83, 0x9e9cf3f6, 0x804067e2, 0x9bc7f825, 0x3b71a767, 0x8906ce6a,
- 0x9c656bf4, 0x6b2367e4, 0x9d99d7fd, 0x39f3e426, 0xe521f137, 0x65a4db1e,
- 0x868ddec7, 0x1d6a0f7e, 0xf7c1a677, 0x499ccfa3, 0x2e333e42, 0xda067cfc,
- 0xc77ac919, 0xeeb8a50b, 0xcb8a06ad, 0x958aceca, 0x88fea0a3, 0x8d3cc747,
- 0x45659ce9, 0x3fa2942f, 0x3871b375, 0xf3e56f0f, 0x35592c5b, 0x53be3f68,
- 0x845cd0fb, 0x8c67b9db, 0xae2f1fa4, 0x3f628d4d, 0x02bfef62, 0x614d6ffb,
- 0xfbd8076c, 0x7b02ee98, 0xed4bef1f, 0xfca68eae, 0x94adab1f, 0xbf1ce9b2,
- 0x1f385b16, 0x237f51b9, 0x02b78ec1, 0x0b5ec91f, 0x78fe81fd, 0x107f6f46,
- 0xa43c99d7, 0xb13aeb62, 0x3f6864ae, 0x0f7f15dc, 0xdd7b21c2, 0x5aa8ad23,
- 0xe7e3498e, 0x5f1c1f7a, 0xf1fa471b, 0x4a978eb2, 0xb486fbe1, 0xded8d9c2,
- 0xd932e5b8, 0x3f34efef, 0x5de11b3e, 0xd7c0d5b2, 0xee7dd627, 0x17a89499,
- 0xfbd77fa0, 0xaba7b23a, 0xb4bc74b6, 0x1b79d20e, 0xe3fbd11e, 0x77aeadfb,
- 0xcdcf9896, 0x7046eae8, 0xd5d39ff8, 0x3f447113, 0x32ae815b, 0xaaba75fe,
- 0xe09cb65a, 0xe15a5af7, 0x9fc834ea, 0x90e2b9d3, 0xffa5ce9e, 0xb5dcf084,
- 0x2bf8225f, 0xbf6955fc, 0x9bdb8d32, 0x06cf1ae5, 0x7f04efd2, 0x3a2c16fd,
- 0xe681ef84, 0xdfa829b3, 0xe334db7e, 0xafbdd747, 0xd233bf9a, 0x7ff5f004,
- 0x734942c7, 0x1b448ef5, 0xc4572fac, 0xdf7e07dd, 0xce51a69d, 0xe05e48f1,
- 0xae2fc93f, 0xd62602a2, 0x92e51c2f, 0x7b420de4, 0xf3dee9aa, 0x379450da,
- 0xad52fb12, 0xfd2fb21f, 0xe68dede4, 0x12b4b37b, 0xf8fad1fb, 0x3527edee,
- 0xee43f7aa, 0xbd520f68, 0x8ecd71c7, 0x9d3d3280, 0x2ad4c4a3, 0xbf18f6f1,
- 0x4e9cd5d3, 0xc5e7fdf1, 0x7daea27d, 0x3f712f60, 0xdefd9309, 0xdcdf3835,
- 0x367c8599, 0x6f95bd70, 0x387e1276, 0x4cbf1e9b, 0xf8d364f6, 0x9bacdaf3,
- 0xb6c0ffaf, 0xe2677a4e, 0x173daebc, 0x7d2ea2ed, 0x43ee167b, 0x9f9c5be5,
- 0xa0e14fff, 0xd5ae9794, 0x649dbf73, 0x4f2efb21, 0x79f648be, 0x9f6e61d7,
- 0x4cbf3657, 0x85b7b4fc, 0x34aa47fb, 0xe851f96d, 0xd1d4584f, 0x37acfc8a,
- 0x954bdb9a, 0xe8ff9ee2, 0xb5072144, 0xff78713d, 0x9f3892e0, 0x7c34ec55,
- 0xb5e90037, 0x5271e34a, 0x305650dc, 0x0b8f73c3, 0x3e50cf48, 0x1afc697b,
- 0xee73f3c4, 0x3f902301, 0x8ff5907e, 0xfda7f24a, 0x9322d829, 0xe2ab297e,
- 0xc3adaf9a, 0x14c0f32d, 0xc1abe8a6, 0x2adef8aa, 0x6467f5bd, 0xe7e11eef,
- 0x3843555e, 0x3937b13d, 0x3aac553d, 0xebf68fa0, 0x9e82afef, 0xc26f3d14,
- 0x7441fe9f, 0xfb64cff9, 0xa33f217f, 0x5fd86ffb, 0x24b73f74, 0xbeb97a89,
- 0x8b733e73, 0x640bafb0, 0x24d55efa, 0x62ef3c33, 0x1e7421d1, 0x5236c05f,
- 0xe604e09c, 0xb17a4d19, 0x7c29fdb6, 0x9fe26587, 0x371891e4, 0x9d2e7a05,
- 0x3907e71b, 0xe8ae3092, 0x70124684, 0xf64f64f5, 0xe9396793, 0x968d4e5c,
- 0x3d639225, 0xa7a4c131, 0x315e9f8c, 0xfa7f5fcb, 0x4fedc487, 0x26f487e8,
- 0xf7e1eee6, 0x593dbc40, 0x4c64effe, 0x22f053fb, 0x93cc8b92, 0x9c6fcd3d,
- 0xa71e74fc, 0x9dcf0571, 0x89549f81, 0xf93ccdf3, 0x0ed167fb, 0x9f9fbc5a,
- 0xc4d09deb, 0xc9714a7f, 0xc258af78, 0x1efcbbfb, 0xbb307337, 0x7327e91d,
- 0xa95fdd00, 0x8c312dda, 0x366cab2f, 0x4d7f456c, 0x123daea5, 0xd35d79f1,
- 0xe7c47a27, 0xccef3c2a, 0xb97ff7e4, 0xf742daff, 0x8c2cabb9, 0x534557e4,
- 0x47e8a7ea, 0xa5cc38ab, 0x18f68568, 0xb7c8e9d9, 0xc6f2bc71, 0x3b97643d,
- 0x72ec9799, 0x6f1a8367, 0xf6fba37a, 0x5ba7e7a3, 0x8c62ef55, 0x63e9ccdf,
- 0x9ac3c61a, 0x43f939a9, 0xd54747c7, 0xc9bbdffa, 0xb5f0e74f, 0x51ab9dcb,
- 0x904ee98f, 0x4a8ef86c, 0x156b9077, 0x14ae47ea, 0xbf74d7ae, 0x017b2bbd,
- 0xf67717f1, 0x077c4cd4, 0xe3b1eb86, 0xcad26ed7, 0xdf19f37e, 0xdd7ffdc2,
- 0x1f64ac41, 0x1063bbed, 0x29fdc7ee, 0x39e90585, 0xd1cc7ef4, 0x234fd0bb,
- 0xae04e9ee, 0x9f0a68e3, 0xdff411cf, 0x3de6f864, 0xf3963631, 0x3c26e633,
- 0x62f7156a, 0xa516f894, 0x578116fd, 0x8917ecd7, 0xc46e9dfb, 0x04bcf05f,
- 0xbcf132e3, 0x229dd304, 0x4bcf137e, 0x88aaff30, 0x12f3c4df, 0x12f3c72c,
- 0xf88a37cc, 0xc12f3c4d, 0x60979e3c, 0xdf88a6fa, 0xa553823c, 0x1ae6b3b8,
- 0xa4568bc4, 0xfcbe81b5, 0xfc80f089, 0x13fd7540, 0x3f3a92e1, 0x8bfaa250,
- 0x5c6b9bd2, 0xb4a7e819, 0xfdc57908, 0x1d83eb94, 0x2af840bf, 0x15cf0ef7,
- 0xe90fbd3c, 0x8cf85c68, 0xbd5f4859, 0xf90c0dfd, 0xc774aed0, 0xf877ac32,
- 0x9b493df0, 0xe89a3f88, 0xc3c4f8fc, 0x05f75543, 0x5c8da4c7, 0x31f90d95,
- 0x6bdc4966, 0x50ac38de, 0x5cf0fbb1, 0x5b28a5bc, 0x0582f9cb, 0xd93ce4f5,
- 0x2ce38c59, 0x448d318e, 0xd53c3bfe, 0x1fba78f1, 0xb81fcebf, 0xa1f50930,
- 0x53f59d56, 0x3eba97f4, 0x9bb431d2, 0x529abf14, 0xe63a90cf, 0x3e376c19,
- 0x08d5712d, 0x0c881fec, 0xcf5d9cf9, 0x767e701a, 0xdfc4b04d, 0x916ab08d,
- 0xf6233c0f, 0xeb95ac7b, 0x55bd5ec5, 0x76768e1b, 0x78fe98d0, 0xf62ada7e,
- 0xdfd8b0f7, 0xf17f6223, 0x969c69bc, 0x8a61379f, 0x2a984de7, 0xd2c75a71,
- 0x274a5f0a, 0x21c4f6f8, 0xddbf157c, 0x1a3ee504, 0x9ea1c4f3, 0xd7c099f0,
- 0x919f0407, 0x79eb0ad2, 0x2fdd0f3b, 0xb4fe172c, 0xa0be714e, 0xe76953ac,
- 0x9dc7cf6b, 0x67f38c32, 0x13dc4fd6, 0x185cc41b, 0x8de53af7, 0x7507f218,
- 0xce3df9b9, 0xc8db4029, 0xfc1bd8bf, 0x73459dfc, 0x7af2993a, 0x295bd514,
- 0xe1159afc, 0x0718296d, 0x49e825df, 0x76f72bc9, 0xde40462b, 0xafab8bec,
- 0x8296d298, 0x925df571, 0x54788349, 0x3f7f95b1, 0x22ade82e, 0xbca7f441,
- 0xc4f46087, 0xef743ee1, 0xef0e237f, 0x7b37ad89, 0xef7e7017, 0x98f2f7e5,
- 0x84e30537, 0x29cf253a, 0xdfad878c, 0x8c41f939, 0x79d4ed87, 0x8efcc25e,
- 0xc41f539d, 0x694ed878, 0xff8b29cf, 0x389e01f7, 0xdfad978c, 0xf7e44539,
- 0xf36614bc, 0x3b5eebcb, 0x2bf5df85, 0xf1883ea6, 0xee0d13b3, 0x2f88d5c3,
- 0x6578e47f, 0x0cf7bdda, 0x99bca7c2, 0x7763ebeb, 0x1af8bdef, 0x21bde3ca,
- 0x55ff6e74, 0x7bc13c7a, 0x1b2bf365, 0xf6bacf10, 0xd60e88e8, 0xd2f27c37,
- 0x819ea9af, 0x689b2b9e, 0x6ba364f0, 0x979dd5e4, 0x2771c01f, 0xc1be7b06,
- 0xcc869ffc, 0x8c4c79a6, 0xeefc74e0, 0x3107a290, 0xef6bbd9e, 0xee90c7ee,
- 0xfc63f626, 0x132ef5de, 0xebd94fed, 0xaed0e3e9, 0x9b690aef, 0xee57fd8d,
- 0xfdf3f034, 0xbde8a3d7, 0xee749e88, 0xb21d2e6f, 0xabe50e31, 0xdb1dcde6,
- 0xc67e8d7e, 0x6f3a269d, 0xfae70aa9, 0x9b5c995d, 0xdfed08fb, 0x80fedbcb,
- 0xa261def3, 0xf452cff3, 0x74be40ad, 0x17bf325b, 0x66afcffe, 0xc9e43ee3,
- 0xca7ee85b, 0x0d267537, 0xdeb8e1c2, 0x83ef0fde, 0xc8eb8eb8, 0xf9152cce,
- 0x7c1113d2, 0xf9edc13e, 0x37fd7fb4, 0x2d7ca1c6, 0xfde5f88b, 0xf289ef38,
- 0xced097c6, 0xf7f0af61, 0x00efcecd, 0xf3bb41b8, 0x0e8a3af5, 0x4211daed,
- 0xa53bb6f7, 0xddf1b38d, 0xaf3d570c, 0x48da69d7, 0xa7d574f0, 0x76bdf7f2,
- 0xb0c3a740, 0xf95526de, 0xb257faf9, 0xb0bd0ed0, 0xa3d92273, 0xf42b9e0a,
- 0x78175652, 0xafdf8c2f, 0x337f132c, 0xfd998b8b, 0xf6174afc, 0x02f5df3d,
- 0xd0bfb5f3, 0xc8fba3a0, 0x0ab606a5, 0x7a1571e3, 0xb7bd8b28, 0xa657d700,
- 0x7d414da9, 0xfb6474a5, 0xf38ba46c, 0x868c6626, 0x39081f7a, 0x7cb8d655,
- 0x37bdea32, 0x431dcf9a, 0x56fa1f38, 0x4db7e1d0, 0x79ffb726, 0xb7fa605f,
- 0x50fd666a, 0x7cffcbeb, 0xdc9efa91, 0x138f7a07, 0x70cab3ed, 0x414e3fce,
- 0x5fe006fd, 0xfce10fb7, 0x7552ce62, 0x3c218cfd, 0xdf52b10e, 0x4ef2829e,
- 0x887d3fe9, 0xda83eb85, 0x2a277a76, 0x5944ddb0, 0xfc5d9bf0, 0xa35969de,
- 0x1df741d4, 0x3e91a410, 0x5d199678, 0xe9d38c6e, 0x73a21f6b, 0xbde03ec5,
- 0x34f12182, 0x8983595e, 0x07972dee, 0x7ea287b5, 0x0f690ce4, 0xeba7bd45,
- 0x8bde994d, 0xafebedc4, 0x1be09ff4, 0x9617f14f, 0x5376747a, 0x72c1e35f,
- 0x885e2ed0, 0x3e28037f, 0xeb40921b, 0xe60a692e, 0xed2da4f7, 0xf0386f74,
- 0xd3ae211e, 0x5d8f47e2, 0xfa472f4d, 0x87b3e7db, 0x57ff0bc4, 0xf74dd107,
- 0x438cbf3f, 0xb0d3283c, 0x785e7855, 0x15f7e241, 0x15f74f20, 0xc773882e,
- 0x41ccefb2, 0xbe173f88, 0x771d1275, 0xe7c4ed49, 0x88aabbcc, 0xdae9743f,
- 0x4349cf89, 0xae7c417f, 0x367dac2b, 0xd0f32df2, 0x4c7bfc35, 0x4fbc6cfb,
- 0xc8886173, 0xf724660f, 0x40daee07, 0xcca264fc, 0xcbd818e3, 0x0bf70b3a,
- 0x142f7871, 0xed6c6270, 0x3bb26a89, 0x8fd45674, 0x424a8762, 0xd6fbd7ff,
- 0xa9e8fb2f, 0x3777598b, 0xf0967d22, 0x9f406277, 0xf50d786a, 0xf49119be,
- 0xdc204dce, 0xfebe7394, 0x805f7fe1, 0x710a64fb, 0xe7821cac, 0x64ed19d5,
- 0x93b60057, 0xb6f95efe, 0x6ecbec81, 0xe436cf5d, 0xc7661d5f, 0xa9cf58e3,
- 0x2d935b6f, 0xf6fa7de1, 0x9bdf3c56, 0x7be3dca0, 0x575be385, 0x9efccbc6,
- 0x7c273882, 0xbe03ec4e, 0xf88b5881, 0x7e7df121, 0x0ff5e9a7, 0xb574df91,
- 0x0e9f1225, 0x4df3a7a4, 0x0a7bd34f, 0xbbae4127, 0x93ffecfc, 0x79d0af45,
- 0xc38c74fc, 0x3f7f5f30, 0xa9fbf7b5, 0x0db20764, 0x8f88e57e, 0x207cea35,
- 0xbd2f105c, 0x11703a2a, 0x5ba78fdc, 0x63a3bbf8, 0x821de8db, 0x9029f96b,
- 0x07f2fd97, 0xf501f203, 0xea3b5ef1, 0x2f51c70f, 0xf60e3840, 0x7dbb209e,
- 0x5d938f37, 0xf28d7209, 0x9ce9837b, 0xe41bb358, 0xb72e7f56, 0x87945e50,
- 0xaabf91b6, 0xce81af6b, 0x9f345637, 0x03f5c38d, 0xa65f923e, 0x488df9bc,
- 0x12bfe7b4, 0xc7c80376, 0xd94b8a48, 0xf6891cdb, 0xd4ee5287, 0x7c445278,
- 0x0ff2167c, 0xf642bca5, 0x553dd0a6, 0x39de8da9, 0x4de70af8, 0x632f21f5,
- 0x9c3ad19e, 0xd67ba712, 0x0a6bdfcc, 0x8213b7dc, 0xa07f019f, 0xbc572777,
- 0x0a05fdc9, 0x7c15283f, 0x679620e5, 0x28b7fa70, 0xde7843e7, 0x07df7483,
- 0xe140789f, 0xf9116c7b, 0xb10f8e73, 0xf68ab872, 0x37f72fd4, 0xb7b8b8f1,
- 0x3212b33a, 0xdaf59db0, 0xfc6b8f7d, 0x5fc7d128, 0x13440f90, 0x8ba1581f,
- 0xbd957584, 0x3abbd124, 0xe796b3a5, 0x50b67543, 0xe7bd08fb, 0xae718259,
- 0x15e7ebe6, 0x43154788, 0x34ca9c38, 0xdb2eeedc, 0xcf39d126, 0x3f3f1d05,
- 0x71437e03, 0x2dc70bf4, 0x9bfa47cf, 0xef42bfdf, 0xacdf1f6f, 0x5beeebff,
- 0x1f9e5a2f, 0x979d07d5, 0x3ad4dd2d, 0x5fdf5d80, 0x3f36a3a9, 0xb97d7ad2,
- 0x260bef32, 0x75639e65, 0x31e1fc03, 0xbe3e797d, 0xf8d0b8fb, 0xaf83c2af,
- 0xc1b342fb, 0xe017728b, 0x77b5e74b, 0xf2a45d5f, 0xbfacdeab, 0x73a6e652,
- 0x3fcd1b8f, 0xde4a7530, 0x0ad71413, 0x744f55f4, 0x37e37406, 0x024363de,
- 0x452511fc, 0x157bd1b7, 0xfcdba28e, 0x298111fd, 0x1a81ca30, 0x5170d98a,
- 0xdb38740a, 0x943c07d6, 0xb94389fa, 0x8131f55f, 0x962703c7, 0x231aff3f,
- 0xe86d8e3f, 0xc7df1b80, 0xfff043b8, 0x718fbe5b, 0xb7af304f, 0x574164df,
- 0xbffef74b, 0x7bb83f93, 0x3f3a79b5, 0x18b33067, 0x9d1adef8, 0xefdfd5b9,
- 0xb7b889fb, 0xe996f780, 0xee9a79fe, 0x1949fdc7, 0x49fcd721, 0x04646fa4,
- 0x574af9d3, 0x6f9215d3, 0x16392ddd, 0x6ae9073c, 0xde919b73, 0x5ff9feaa,
- 0xbb872891, 0xb8a6be5a, 0xcfefaeb0, 0x3ad8bc52, 0xb077b711, 0xb55bc449,
- 0xbcb04359, 0x7cabe0bb, 0xa45eb7ac, 0xf7027f3e, 0xe2a92ba7, 0x9f7bf02f,
- 0x1cd0d667, 0xdd6b3f7c, 0x3e30d953, 0x45cc6e33, 0x7376007e, 0x9f0dca38,
- 0xf51ac11f, 0xe88bf163, 0x72d24847, 0xe8a6023f, 0xe24a4847, 0xa3cc047e,
- 0xf453011f, 0xfa396023, 0x7e8f3011, 0x1fa3cc04, 0x47e8f301, 0x08fd14c0,
- 0xb88dfe58, 0x8c0dd12f, 0xcd39fb8b, 0x6097f7c4, 0x6fc030fc, 0x78bf7889,
- 0x777f3d49, 0xa04bef07, 0x7e2ebbfc, 0xcfc451a6, 0xf9d13678, 0xd95ed55f,
- 0xf7845b86, 0x18295c2a, 0x0873d347, 0x7b553ffd, 0x2b72db24, 0x79a74f96,
- 0xf9c96bac, 0xd7961674, 0x5ef86ceb, 0xdf13e016, 0xe2895acf, 0xea5aca98,
- 0x2e355fc9, 0xcdc53f6a, 0x0c483557, 0x0cd3acfd, 0x90ae4edc, 0x9d0474a1,
- 0x5d1e9297, 0xfb236861, 0x64bb7ca5, 0x5c9fbff5, 0xf132ea35, 0x78dce509,
- 0x2ac4ff01, 0xb16b263c, 0x79dace4a, 0x69fe13fc, 0x9137c5f5, 0x17a7e21e,
- 0x64f3c02d, 0xa7bf972c, 0x60151b7b, 0x374846e0, 0x6b2a7f8f, 0xe306b3d9,
- 0x0e356ea6, 0xe2a1e5ea, 0xbf3878fc, 0x4cf0518f, 0x30bdeef1, 0x0346ef5e,
- 0xd2bb29e9, 0xbf113b1d, 0xe4ece90e, 0xdfb4396f, 0xe9d67644, 0x7f2aa94d,
- 0x883c9e4b, 0x758b1dfc, 0xe1efc912, 0xb60f0ea9, 0x1e60a7bb, 0x89ee59f9,
- 0x563a210e, 0x5a90d0f0, 0x81f21af8, 0xf25699c5, 0xd819e56f, 0x113fa82f,
- 0x53eca557, 0xde894ade, 0x36622e4d, 0xc7305fba, 0x5389dfce, 0xc39b75de,
- 0x82839c78, 0x49378b57, 0x364eddfc, 0x5b3ce088, 0xcb4e73c0, 0xc74ef47b,
- 0x5778833c, 0xbfcfc34e, 0x78f3d763, 0xc2f8f986, 0x8177be11, 0x7c9327d8,
- 0xca1dbb7d, 0xe283c11d, 0x8d6f7eb8, 0x8e8bfec2, 0x373e28e8, 0x14beea2f,
- 0x71f9c907, 0x7920c714, 0x0c3fca67, 0xa9fe31fd, 0xa438638e, 0xeb841c2b,
- 0x253c456e, 0xd2838eff, 0x9425d523, 0x251c7e2a, 0xff7bb06e, 0xfc707b1b,
- 0x6efe2abc, 0xc5ef0dec, 0x3f7df505, 0xf027b94c, 0x0e29c619, 0x1f1ff5c0,
- 0xc4dbef89, 0xe1b6677e, 0xf6a2f3fa, 0x44aabdd3, 0x933fffd1, 0xfee0cf0b,
- 0x0b9943d8, 0xcc39e1db, 0x3e678046, 0x3f42402e, 0xf78ec7b9, 0x4bf67a53,
- 0xbe5f8a16, 0x5a6e6f8e, 0x5521f18d, 0x6bbd1249, 0x31b41f9d, 0xcffa122f,
- 0x21b7884f, 0xe26aaedf, 0x482ed67e, 0xe5dfbef9, 0x18aaf7a6, 0x826a3f7f,
- 0x53fbb7d8, 0x3a1f7f1c, 0x513e57c0, 0xcb7755d0, 0x7bb71e15, 0x1d6c3f73,
- 0xf8c73fbd, 0x0ff41f7b, 0xe87135e6, 0x2ac7f260, 0x10dbd378, 0x26f115b5,
- 0x9bb78324, 0x0e98eb35, 0xcd2906f5, 0xfc80cc61, 0xabcbe2ec, 0x7d9d6923,
- 0xf894c5fb, 0x98bf40f6, 0xbffd7f3f, 0xb0ff6b88, 0x47a5117a, 0xda5297ab,
- 0xefa2ed56, 0xcb6e1720, 0x6a7f35b8, 0xfe1f464a, 0xf6b46654, 0xf40ab923,
- 0x01d6fdcd, 0x6ba053fe, 0xdf5d1f8d, 0x773612d3, 0x351dea2d, 0x128f7a7a,
- 0x98978ce3, 0x32d80f89, 0x2aa3f4fa, 0xdf933370, 0x469997b5, 0xa6c7fc20,
- 0xf0356a25, 0x490ccefd, 0x74865e75, 0x3a43eb82, 0x44e914c1, 0x7cefe7eb,
- 0x9c240f51, 0x1700f5cd, 0xda2601e9, 0x81cb35d7, 0xeef8487f, 0x3fc5458f,
- 0x0ff0062e, 0xa61e5830, 0x062d55fb, 0x8946877a, 0xc90b1cb7, 0xf07d11d5,
- 0x27e70f13, 0x3b3c8383, 0x657fbee8, 0x1ef3c510, 0x3afc71d2, 0xc9c78eb4,
- 0xfe42b315, 0x7cf5d0de, 0xcccbee85, 0xf539e88b, 0xef3fa807, 0x33e93309,
- 0xe416626b, 0x257c3bfe, 0xe0106507, 0x4b2c6b9d, 0x9be0b8c3, 0x03bbcaa5,
- 0xd021ded7, 0x271cf78b, 0xaa6a77f0, 0x5953fe84, 0x54fa216c, 0x6a5661ee,
- 0xb06b1d3d, 0x1e10ff5e, 0xf465a1ef, 0xcd71c8ce, 0xa9eefe40, 0x13e3b3a0,
- 0x1b9fc912, 0xc5e3d2b9, 0x93ee7b7e, 0x71da7de8, 0x831dfcc1, 0xf3a14d3c,
- 0xaefef815, 0x7d47df86, 0x9029df11, 0x5fb95f71, 0x93ef77c4, 0x05b169eb,
- 0x7fb95b21, 0xb3fbbf98, 0x00fe1252, 0xb74b6ef1, 0x1fdde03b, 0x374aeef1,
- 0x08f59c2b, 0xcae981f2, 0x27d68ffb, 0xa6a07cf1, 0xf7788874, 0xcf7fe387,
- 0xf90da364, 0x3e70cd59, 0x04d29aff, 0xac948fee, 0xb98e51cb, 0x1c68c37e,
- 0x833fbbdf, 0x1fb2bbe9, 0xa72e3bca, 0x43bf1c43, 0x9ef811be, 0xe152b3cb,
- 0x4fd8f98c, 0x27af9f26, 0x43e3f399, 0xb93c8633, 0xc838e10d, 0xf87a839a,
- 0xb96151dc, 0xac47e012, 0x800cb996, 0xa69be87f, 0x69d66e77, 0xbc602bdd,
- 0x2f715a41, 0x3df82b5f, 0x82341974, 0x90f5dbea, 0x217a7a2f, 0x8abca3b3,
- 0x6c5ef465, 0x879f9192, 0x29863b43, 0x946469ba, 0x85fb8c83, 0xfef1fa8a,
- 0x7b98a28b, 0xd9fd4485, 0x673c4a35, 0x020efe2e, 0xb6173f23, 0xed411d0f,
- 0xdede1a5d, 0xb6f485ae, 0x51defe44, 0x9d036acf, 0x3e3d1683, 0xa4e3e498,
- 0xedfbeab1, 0x38f067df, 0x985d2505, 0xf9d15569, 0x74e955dc, 0xd577389e,
- 0x43d40a8c, 0x74c10d1c, 0x81f3af1f, 0x9df0bb97, 0xbdd972f1, 0x6bb413e0,
- 0x216f1d32, 0x5920b95f, 0x0a85ef67, 0x477c1f73, 0x0e31718f, 0x6f4be4cf,
- 0xed70dca2, 0xbaef8a39, 0x4c80ffdd, 0xfc67efed, 0x8ab6647d, 0x9f7903bf,
- 0x1a36b2eb, 0xb46fbffa, 0x0ef27e44, 0xf50e2593, 0x5fb122ba, 0x14ff82ad,
- 0x829c19ad, 0x787df576, 0x9c87dece, 0x3d793291, 0xf76dfbe5, 0x635d9530,
- 0x990ddf10, 0x25b7bd7c, 0x6bc5eff2, 0xa1891d0d, 0xa9bcea98, 0x8d86da90,
- 0x65f118fd, 0xdfcb0252, 0x25fc708c, 0x987633f7, 0x97ce9798, 0xae0933eb,
- 0xf1d3d60e, 0x6ea3ae38, 0x63a3ad28, 0xde8e258c, 0x8aef10bf, 0xfe70b7ce,
- 0x8f8631d4, 0x1ed2ca73, 0xe9c19e12, 0x9d17df07, 0xebf4b627, 0xba9f2ba5,
- 0x5bcdea1d, 0x927ba466, 0x4a999ff3, 0x1abcca76, 0xb247ee99, 0x45f7ea0d,
- 0xe2749e41, 0x0bdf02fc, 0x14177c0d, 0xa0f11cf7, 0x78448378, 0x9b4adb74,
- 0x7bdfcf1e, 0x009e8136, 0xdecd8bdf, 0x8a0bd424, 0x0adb266d, 0x43778fa9,
- 0xe5b807bf, 0x8ccbbbe2, 0x592126fc, 0x6e38ab8e, 0x7a22c6d1, 0xc33833a7,
- 0xdbb0fe41, 0xfd441ec0, 0x4e4c8ee7, 0xbc00933f, 0xb683cef4, 0x9fed063d,
- 0xaf1c193d, 0x525b8526, 0x269784cc, 0x3bbbf786, 0x9c149674, 0x936ac75f,
- 0x499ef506, 0x027e382b, 0x23b518dd, 0x059fbe30, 0x111efd21, 0xd72d67ed,
- 0x7e42d616, 0x90ed8810, 0xe19bc470, 0x0e8f9f84, 0xf119fc73, 0xd86fdcef,
- 0xf39fe428, 0xf3e26c36, 0xb4cffb12, 0x9ef0e36d, 0xf8fab9e5, 0xa0571811,
- 0xc3a3c3e0, 0xfd325ac6, 0x8901e0f1, 0x73d61ff6, 0x6d8de518, 0xccc8dcd8,
- 0x007e5401, 0x58d263f1, 0xe421c52f, 0xe7864ec9, 0x8cd1bdf8, 0x197be9e2,
- 0xb5ded7a7, 0x0a6fe25a, 0x01f8509f, 0xef1d83e0, 0xadfb2ac7, 0x2bff85f0,
- 0x43e0043d, 0x1be1457c, 0xf0517f0a, 0x8133e14b, 0xc01b3578, 0x6a08f77c,
- 0xe14cfc4f, 0xcd0eb863, 0x517f1f08, 0x76b759f6, 0xadfc868c, 0xe4f39f62,
- 0x40dfbb8b, 0x49989438, 0x1706b96f, 0x12e091b3, 0xf84d67a7, 0x47caea3e,
- 0x402cf70a, 0x416dfc7c, 0x331fea3c, 0x18f7d44b, 0x7d48be7f, 0x52ce717f,
- 0x59c5fdf5, 0x843e3f4b, 0x5086a77e, 0xbfdc04c7, 0xf33dbf53, 0xfe50a7e2,
- 0x90bdbf9f, 0x8becedcc, 0xb8e1cff5, 0x3cc482cb, 0x96bcf9da, 0xdcbe49e9,
- 0xfc30f426, 0x9732fb87, 0x8a2d3a71, 0xf28a3b0f, 0x29c22e6f, 0x611fdf0b,
- 0x89bfcf04, 0xf62539fd, 0xf73568a7, 0x24b8743b, 0x5dcc43f2, 0xad74e825,
- 0x97f25efa, 0x383dac31, 0xf97f77d1, 0xc4a4dfcb, 0xf72b5d21, 0xf96b1d95,
- 0xe969667d, 0x1c5fd261, 0xae50fbca, 0x96a1f780, 0xcf7bf2b6, 0xc4fbeaed,
- 0x3d76d9c1, 0xb71829f9, 0x1da6e6a3, 0x1b35f1e4, 0xb28a0b25, 0xbc5e5162,
- 0x57dd5256, 0xdf93247b, 0xd0cc6b17, 0xfa0bbf72, 0x1f38949c, 0x7c04be3f,
- 0x15cfee83, 0x5fae1c6f, 0xe747c7e0, 0x6979f28a, 0xf2954a1a, 0x571e0cc6,
- 0x03448c1a, 0x4b4faefd, 0x7e27cfd0, 0xa8bf2567, 0xda6e7f52, 0x37e83588,
- 0x7f01bb98, 0xfed7c79d, 0x6a5a9937, 0x26f428df, 0xfcf80de7, 0xfc2a38b5,
- 0x379a0ef3, 0xaf65d3d9, 0xdf157aee, 0xdcfb2fbd, 0x6ca67240, 0xcf5f3898,
- 0xa54ee770, 0x9f7e63f3, 0xf7ec52aa, 0x845f5db8, 0xd5509da2, 0x8671dfc8,
- 0xcad303b4, 0xef642565, 0x1e80da57, 0xf78fafc2, 0xcfd5f77e, 0xd95fb943,
- 0x9f41ab15, 0xa59df888, 0xc8afc6ca, 0xdefca0ef, 0x2abb6052, 0x6e50fbe9,
- 0xff985abf, 0xede411ef, 0x549d11d7, 0xb97b7335, 0xf215ef6a, 0x5fed579b,
- 0x63e8e91d, 0x13dfd7fd, 0xe8e2abb1, 0xcb86d8ab, 0x06fe0f74, 0x4c9eeaf1,
- 0xedc3eef1, 0x538a76ec, 0x2b8a32d7, 0x2ebbf6ba, 0x8d1fe4ee, 0xacdaac8f,
- 0x5ea078a1, 0x9e1fb5ad, 0xfb8b75c7, 0xbef58151, 0xd776e4cd, 0x7c23a025,
- 0x41bba377, 0xee9df3a6, 0xabbfee06, 0x15ba786c, 0x8256a5ef, 0x5ec30ce1,
- 0xd9543fbb, 0x7fa33328, 0x1fc61adc, 0x9e78dc45, 0xe842bbe5, 0x8f52981d,
- 0xf987af64, 0x34bd82f4, 0xc73e6fc0, 0x1b955e05, 0x2fb4b93c, 0x0387fe62,
- 0x96d29df4, 0x2b9ee9a7, 0xfd22ebd4, 0x8cc18fe4, 0x1cf5939f, 0x6e7679c5,
- 0x5ae74919, 0x953d9ea5, 0x086c77e4, 0x0b9578a6, 0xe9bdf53a, 0x53bc6253,
- 0xafee3c99, 0xb124e313, 0xe932abfd, 0xa44f38a7, 0x3a920bc7, 0x68b4e38e,
- 0x6dc05a77, 0xa54ba09d, 0x23a7a97e, 0x9fea0934, 0xd298fa6d, 0xd4bf512e,
- 0x728596dc, 0x30636cf3, 0xdb3d63dd, 0xb7fc87f8, 0x9e4bbc60, 0x3f25fd31,
- 0x74b292fa, 0x88b63f7c, 0x08eeb8fb, 0x43c4cf71, 0x886ce9eb, 0xacbed095,
- 0x9d5ef110, 0x6a87af8d, 0xff5d7e88, 0x4d5defde, 0xb15deebf, 0xfea046ef,
- 0xbd576c62, 0xd5bff62b, 0xff28a57f, 0xe3142a44, 0xb9c5e8f4, 0x101dff30,
- 0xe13ba08b, 0xcc3d9d8f, 0x7fde10fa, 0xdff01f65, 0xffbd030d, 0x668fb439,
- 0xec8239ff, 0x0ffdfc4f, 0x21f37fcc, 0x3d9b2f3f, 0xe895f052, 0xd7f41cf6,
- 0xfd73c477, 0x2816b9c1, 0x0e5a4011, 0xf802e5f8, 0xe61add39, 0x2cd0fc80,
- 0x02753f6e, 0xe187ebfe, 0xe58e3cc8, 0xf877d814, 0x35eb8c9e, 0x4cec8e7e,
- 0xbde0a6f0, 0x4f114ebe, 0xa6f70ce0, 0x17bf4044, 0xa7389e05, 0xdffc5378,
- 0xf56e74a9, 0x45cd3c52, 0xdf873f11, 0x1ce79fd1, 0xc475ebc1, 0xdee8ba5b,
- 0x8610dec6, 0x8de6aafa, 0x8ac3c210, 0x0d5b4c57, 0xa8d2767e, 0x5f0fae2c,
- 0xad77f3d4, 0x7cf8db5d, 0x5237434a, 0x7e05173f, 0xa46d0697, 0xf7129df9,
- 0x3cf54b83, 0xf463a1df, 0x0ecf7c9e, 0x85cf6efe, 0x387db698, 0xe91d85ce,
- 0x11da6714, 0x44d05eef, 0x497c79df, 0x17834ed9, 0x477e75e7, 0x2a03dd08,
- 0x3a66edf8, 0x33adec5f, 0xceffc848, 0xcf74600f, 0x00fd7ce1, 0x25e7d792,
- 0xcf37f92b, 0xfd411fbf, 0xa52f5595, 0xc0652cfb, 0x84ef5026, 0xb5f500b4,
- 0xc7cff5f3, 0x7e42fd21, 0x6c1de62d, 0x215fece3, 0x260f6e9d, 0xcec2f33b,
- 0x9ffba47f, 0xe06928f7, 0x9fb289b9, 0x59e9f7ca, 0x2e986edc, 0xcb2b34e0,
- 0x832dcfc2, 0xd026cf3d, 0x037d38fa, 0x002ec99c, 0x7177a27a, 0x239a794e,
- 0xeca7e825, 0xca3b108d, 0x379d0ef7, 0x87040fe5, 0x30bbf160, 0xf3c2ec8c,
- 0x2ec822db, 0xfa9a2d07, 0x932dbf39, 0x389543e2, 0xaba84993, 0x12663ed1,
- 0x2de4f37c, 0x706ef459, 0xe1c5305d, 0xbb7e3d94, 0x644ee286, 0xbd9777ae,
- 0xc8926f3a, 0xa69cf1db, 0x56bf57ec, 0x49fe45e0, 0x29d48e25, 0xe3c568f8,
- 0xb8c3f577, 0x9967f65b, 0x68aee3e2, 0x20639c79, 0x0964765c, 0x45efba3e,
- 0xe0275ba2, 0x502efe39, 0x2f0388b9, 0x2cfdc9df, 0x7aee6be5, 0x51e3f88e,
- 0xdf38c31d, 0x43a79e8b, 0xb4fee1fd, 0xded7c7e8, 0xa1cbf546, 0x41ff6f3e,
- 0x9b67cd28, 0x0392e28e, 0xdb96ebf7, 0xa5ff94ef, 0xd01e65f6, 0x0738fa03,
- 0x1edac2be, 0x40f91cfb, 0xa2e6c983, 0xd7b71e52, 0xe02cf3a9, 0xc44c19f7,
- 0xc4c33a1f, 0xf35689ef, 0x35f281f8, 0x71477f13, 0xd2a7c70a, 0xee85a61d,
- 0x36e9cfbe, 0x115cfe0b, 0x7487eb61, 0x41fb0158, 0xbf1f09f7, 0xb375ee8b,
- 0x7da8eb3f, 0x131e7ae0, 0xe1d1aeed, 0xdcff1e6e, 0x4bef9039, 0x24a9abe7,
- 0x38c23a77, 0xc97cc35e, 0xe30ced4e, 0x60480529, 0xe3858ddc, 0x0f18e743,
- 0xd29ddfd9, 0x743b4a1e, 0x52d95dbc, 0x5e177bf1, 0x44e2371e, 0x77c44d9c,
- 0xa1b43677, 0x38fc81be, 0x5ea50477, 0xeff5f843, 0x931e0386, 0xc593d77d,
- 0x7f129be5, 0x93d6ef43, 0x47a3d35f, 0x7a10ea7e, 0xfae1b39f, 0x7ba033df,
- 0xc5120def, 0xe959ff1d, 0x94ffc447, 0xcacf0e73, 0xe39d125d, 0xa47aaf97,
- 0x7cbef114, 0x4899a6d1, 0xca3aca0f, 0xed00acb5, 0xa6490eaf, 0x3f5d80f9,
- 0xf5c64a67, 0xfdf029e3, 0x513fd04c, 0x8067228e, 0x59654ed6, 0x6d953d15,
- 0xab9cfe84, 0x4e340da4, 0xf27762bc, 0xc27029f5, 0x638c1f73, 0x3701fc54,
- 0xcf32bf5a, 0x57a7cd1b, 0x788ea1f0, 0xe346efeb, 0x13247f7e, 0xfdf2b93f,
- 0x3fe17ec8, 0x2fd1b7a2, 0xe1fd2a59, 0x11d4127d, 0xc8839fa1, 0x046e30cf,
- 0x3cc0bb6f, 0x8087e853, 0xd5a6e37c, 0x1a43f3a9, 0x468cf9d4, 0x45ab3e75,
- 0xabbdb79d, 0xe3159fce, 0x3b42702a, 0x6c3def18, 0xd01ff717, 0x4bfbc60e,
- 0x1e630768, 0xd14c60ed, 0xb472c60e, 0x768f3183, 0x0ed1e630, 0x1db9eab6,
- 0xc1da298c, 0x8c359e58, 0xcb59c9c3, 0x0fb090fd, 0x9f8f3a76, 0x026efca1,
- 0x8fa885d8, 0xbd220e96, 0xa8be7d0e, 0xedfff437, 0x478805d5, 0xd44710a6,
- 0xc38c1cb0, 0x83135b6a, 0x93e203f5, 0x664c239c, 0xafb437f4, 0xd506bb3e,
- 0x63b30e90, 0xe257d610, 0xbe962a96, 0xd6efbf43, 0xe7fadcbe, 0x227df29f,
- 0xfbf287bf, 0xbef86543, 0x2e7e4cbb, 0x391dff23, 0xf7afb19b, 0x8ce303a3,
- 0x22f895fe, 0x368e8abb, 0x53fe5c12, 0x7c8313d7, 0x461dabfe, 0x2bf5677a,
- 0x4d931f71, 0xe77ea8b7, 0xde79daf1, 0xcb9d1293, 0x9c2c3ddc, 0x061ef7da,
- 0x790fbbfd, 0xd0f3a4aa, 0x9f77ef59, 0x4906de78, 0xa6dce383, 0x276470e7,
- 0x1c6f1164, 0x4ea77fca, 0xf51531cc, 0xa7f9bf73, 0xf85483bb, 0x787b7433,
- 0x0c35efc0, 0xd61fd554, 0x7bf01094, 0xbfd4430d, 0xf2c0f023, 0x4f676803,
- 0x555230dd, 0x6bd20aef, 0x28d5ca36, 0x85c597e2, 0x27c40577, 0x4f7eaa86,
- 0xa7ae896f, 0xbfa871e3, 0xc90c6f64, 0xb7986283, 0xf388a47d, 0x49c7a581,
- 0xb7c435ae, 0x3dfa256b, 0xde4279b2, 0xf96aa5b0, 0xe7e5a25b, 0x3646f87a,
- 0xbdce83ea, 0x84fef451, 0x16258f82, 0x811b0f66, 0x596dbcf1, 0xde1fb45e,
- 0xf117397f, 0x8dae42aa, 0x781bdfc3, 0xc36f7254, 0xc217a78b, 0x01de44f7,
- 0x38d63fdf, 0x2f0f112a, 0x3a39ce1e, 0xb17ce00a, 0x4b7ba641, 0xe46f3a71,
- 0xff0fb308, 0x209674e2, 0x8ddaffdc, 0xf41bfdfc, 0x3ee1c95b, 0x18dda8fc,
- 0xf6649411, 0x87c15bad, 0x41def4db, 0xaf5d704b, 0x02af4899, 0xd3e49a3d,
- 0xe932c395, 0x2463256f, 0x62b9e917, 0x4b7dca9d, 0x85a73d65, 0x78d2c83d,
- 0xef8a8fbf, 0x640fd317, 0xce1d6159, 0x1938a6ea, 0x61a6b8f9, 0x63a40c5b,
- 0xc3758e8c, 0xa8efe006, 0xef8a7f25, 0x227d9497, 0xf8ef8c33, 0xd09ee6ba,
- 0xdccf503b, 0x824db3ad, 0x5f1be3fc, 0x6595fba6, 0xed1eb75a, 0xb51d92d2,
- 0x5ee68f74, 0x82d26ef1, 0x9f6445ed, 0xc88b642f, 0xc4a73cce, 0x94780b9d,
- 0x58b6958c, 0x823dde60, 0x7788946f, 0xf1f7942b, 0xefe76cae, 0xb8503f3e,
- 0xf5e77e87, 0x902f5165, 0x9c3f7a5e, 0xfd00379a, 0xf6c91e4d, 0x1f4cf763,
- 0xc03fa0c4, 0xad57a987, 0x75703e94, 0x9fb9d908, 0xa184afe0, 0xb008c8bc,
- 0xf1e43f77, 0xbbf8bd19, 0xef78f148, 0x2a7fdbd2, 0x3adbc3ee, 0xc00a87da,
- 0x7823519f, 0x909dc33c, 0xdf568e16, 0x171aa9f7, 0xe9f7c2ac, 0xa08e8fcc,
- 0x7c1869bf, 0x607f97ee, 0xfeaaa252, 0x0d0c0f43, 0xbe1187a0, 0x742e74ef,
- 0xb44e2aa7, 0x4acb9962, 0xe4f1f4f7, 0xd21cbfce, 0x13678465, 0xd82bed54,
- 0x78bd5f14, 0x45ba3bfe, 0x7a6d7f84, 0x344a97b4, 0xba7d6e3c, 0xb79443a3,
- 0x442c3953, 0x25b79745, 0x72e53eda, 0x83e3c751, 0x3a7b1f85, 0x97d89dfe,
- 0x168d845c, 0xc9efe2e3, 0xa1c1ffa1, 0x54da3bd6, 0x3fc22271, 0xfdc69154,
- 0x36ae1543, 0x01df9e3d, 0x00b1b5fc, 0xfc8dca92, 0x6fa8085d, 0xf9e70d8c,
- 0x7fae2365, 0xc3fb0f2f, 0x0f2ac877, 0x2f4845cb, 0xf12bdf81, 0x0f9c027d,
- 0xe94273fa, 0xbfde719d, 0xcfc157e8, 0xc09438c0, 0xb5f1b27e, 0xdf7a1c9f,
- 0x9aa3de8f, 0x89efc85a, 0xf9933d3b, 0x3c00fbbd, 0x15fdf853, 0xfd12cf7c,
- 0x43be1fdb, 0x5dbbd678, 0x00b76367, 0xf73b4a8f, 0xdfe20677, 0xbe0f5802,
- 0x51a0b86f, 0x5e25b9b2, 0xfff2e10f, 0xf482dc01, 0x00800036, 0x00000000,
- 0x00088b1f, 0x00000000, 0x5bcdff00, 0x6595580d, 0xf3be7e9a, 0x700e01c7,
- 0x0427e540, 0x094a880f, 0x44101df6, 0x18293b53, 0x54da1595, 0x021f44a2,
- 0x9a2824fe, 0x2edb52ed, 0x4c7350c7, 0x4a976867, 0x57a3ab1b, 0xb5accd39,
- 0x8cce9a98, 0x7e927bbb, 0xa772b268, 0xa9aeae69, 0x66b663b5, 0x3b448dae,
- 0xb5b4d45d, 0xdfbefdcf, 0x23bef9c7, 0xb5cced4c, 0xd7175c3f, 0xfff79e73,
- 0xe7defe7d, 0xbbf79e7d, 0xc89132a3, 0x1befe24d, 0xffe56ffe, 0xd5a212ec,
- 0x441f9d07, 0xabe5a30a, 0xae0decfb, 0x60fd65cb, 0xcbf5c5da, 0xc32a63f1,
- 0x9c284a23, 0xd70770c7, 0x4d5dc69b, 0x27b53edb, 0x97f1ca03, 0x3463fc69,
- 0x284a83c3, 0x1e3c5ca4, 0xca8d9055, 0x0c61d689, 0xf1c0d11f, 0x3f685d3b,
- 0xaf214bb0, 0xa09d9a22, 0xd41eb974, 0x62bbdeb7, 0xc8614d3e, 0xf5e6cc63,
- 0x11741c2d, 0x1b8d1295, 0xe6e5c27f, 0x1487fd7e, 0xbbf70f75, 0xca21d065,
- 0x10e41d5b, 0x6a21acfb, 0xf9bdf867, 0x9dc1d117, 0xefeb269d, 0x60f37865,
- 0xbb17e8ba, 0xe87a21ce, 0x6e88b9f4, 0x7645c274, 0x798dfed3, 0xa22ff1f5,
- 0x71ff4c53, 0x1af6e9e3, 0x0a27510f, 0x7f0cb8b2, 0x8fb90257, 0x86688ca8,
- 0xccfa349a, 0xb2efc264, 0xf21e786f, 0xa3d3a0f0, 0x512162ed, 0x8f0c6890,
- 0xc7ad22eb, 0xd2593c03, 0xb8e92bd9, 0x48cbe9ce, 0x99dfe22d, 0x3bfa56c9,
- 0x3728297c, 0x61d869c6, 0xa3d31f23, 0x3d363eca, 0x8c68e3c2, 0xc8b43e83,
- 0x345f036b, 0x1bcdbc7d, 0x4c46e7c7, 0xce4db4fd, 0xb9f6e274, 0xd809461b,
- 0x574def10, 0x8361beb9, 0xf0c426bd, 0xa467ef83, 0x7d1cb057, 0x7a39c9b0,
- 0xc1f10f3e, 0xa97353dd, 0x80957818, 0x5b8c1fa7, 0xbc5cf214, 0x26d506af,
- 0x37fad1e8, 0xf9dae4ef, 0xe3b627e7, 0xfe788bc9, 0x92874d96, 0x559c782b,
- 0xf72ade9b, 0x6ddd13e6, 0xde54dad3, 0xf76539ff, 0xe5e82f5e, 0x86a53ddd,
- 0x52015dc7, 0xd8ee5f30, 0xdc419554, 0xdeebe5ae, 0x79e3bdc7, 0xe99c1bbd,
- 0x8f9f9636, 0x3b276d7f, 0x2759cfcb, 0xe24cbd05, 0x7e52f1b3, 0x18953ecf,
- 0x3f7964ea, 0x9e2050ab, 0x5fda57cb, 0x5b718298, 0x75888e3a, 0xbd1db2ac,
- 0xb5fff305, 0xc32de79b, 0x99bda1bc, 0x4e0d5798, 0x86dabcc4, 0xd15a2909,
- 0xb35afcc8, 0x75d044a3, 0x99f7076f, 0xa8817448, 0xba7b7c1a, 0x9ff02dc3,
- 0x59a13076, 0x6475f7d4, 0x0ed9fc0a, 0x1d3d809f, 0xbbbca285, 0xddf92bc8,
- 0xc75fefd9, 0x50e704f3, 0x7c079b61, 0x783a14f3, 0x092a77fd, 0xa8029c6a,
- 0xf7c17866, 0xff04b327, 0x5d88790c, 0xa27eaccf, 0x5e7c9326, 0x26a6e839,
- 0x455efc93, 0xae7c16a9, 0xbed2cb3b, 0xa9679bca, 0x52f33abf, 0x3e35fd4b,
- 0xaebf05bf, 0xfda5ba70, 0x1655eaf5, 0x6b8ac6fc, 0x0417ed2c, 0x9bf05816,
- 0xed2d6baa, 0xb069ae6f, 0x68badfd4, 0x56bea5a5, 0x97c16b5b, 0xd2dbb8ac,
- 0x0db6b6fe, 0x7900fa96, 0x7272c41d, 0x63e3f994, 0xf313ffba, 0xd7cef005,
- 0x7ccc7827, 0xd6d7399d, 0xdc8c33d6, 0x32dc861e, 0x07f5de7f, 0xe47c839e,
- 0x321ca4d8, 0x53cb100c, 0xf513eaaf, 0x305614d9, 0x2cbd9b0f, 0xbb6c4dc8,
- 0x8999fad8, 0x31f33ec7, 0x7ffd730f, 0xf6c1c8b1, 0x63b4e660, 0xbf19e3a5,
- 0x916fbfc9, 0xccc8ed83, 0x067d8e2b, 0x19ff0dfc, 0x5dc4df89, 0xf6fef067,
- 0xf20a2c37, 0x995e673a, 0x3d654dbf, 0xea9d37a4, 0x7cb23453, 0x0e4ddf62,
- 0x30c06fb9, 0x31e023cb, 0x17c04796, 0x0a9b1e59, 0x79665e88, 0x50ebec04,
- 0x3b2ff945, 0xde3c042a, 0x8df01011, 0x4f016a8e, 0xf808d474, 0x02458eab,
- 0x1343bafe, 0xb1d37efd, 0x3a77c042, 0x6ff944da, 0x7c05da3b, 0xca2823af,
- 0xa11557df, 0x8202bcff, 0x0339c2dd, 0xf6ed5df9, 0x2e7ced84, 0xf9e711d0,
- 0xfacabb21, 0xeed804ad, 0xdf14dd33, 0xd863aa68, 0x449146d9, 0x91c465e8,
- 0x8bf9867a, 0x37edc39f, 0x741d476a, 0x1b8f18c6, 0x381f13df, 0x3442bb07,
- 0x31267bd6, 0x1fc07e5a, 0x03e504f8, 0x2539f505, 0x3ebd9fcc, 0xf9f053ed,
- 0x4dc692e6, 0xae376c29, 0x09cdaafc, 0x46db7939, 0x8f93862b, 0xb23e5d5e,
- 0x638c141d, 0x29b8177e, 0xf0269298, 0x0e618b80, 0x88eec397, 0x0177de3f,
- 0x81e43e60, 0xb963e508, 0xb670cdde, 0xf10a793b, 0xe5c394f9, 0x142f2176,
- 0xc27ac870, 0xb41e5c78, 0xa9e745a5, 0xdf61241a, 0x84716d66, 0x1c921f60,
- 0xc895b614, 0x7225c9f6, 0xdcb3e05e, 0xe5857e3d, 0x478b5664, 0x327ef20d,
- 0x2255deb8, 0x0cec07da, 0xf73dfc9f, 0x514c229b, 0xd444a130, 0xbd72f58b,
- 0xa0d54758, 0xcff40146, 0xef4e3524, 0x41f596ef, 0x6bc59ff4, 0x30c15f80,
- 0x9c79f184, 0x7689d600, 0x185db289, 0xce7c14e3, 0xf49b24f3, 0x9642fec5,
- 0xdf65fb83, 0x9f6152e9, 0xe44ed273, 0x3f31eec1, 0xfeb9f9c6, 0xdbd9d4a6,
- 0x9a9fcc23, 0x26bfef38, 0xf34a5f32, 0xff9402b4, 0xc13f194a, 0x4c17e60f,
- 0xc4935319, 0xe7c6c4f6, 0x39f630e4, 0x3f062f96, 0xf41bba0c, 0x48dbe58d,
- 0x4f891afc, 0x1aa9fcb1, 0xf41bd28c, 0x512f991a, 0xff9505fe, 0x754cbe7b,
- 0x7ac6ecf4, 0x2adc5ae2, 0x7c6df3d6, 0xe69fbdba, 0x869370a5, 0x80cbdf41,
- 0x5eb4f267, 0x5d2351e8, 0x9a0bcf35, 0xe0c5ed79, 0x0bbb6c4f, 0x03e3b423,
- 0x779c56f7, 0x6d273e7d, 0x8b5ff9e5, 0xa0a73a67, 0x33f1e03c, 0xf6eae61f,
- 0x84da8fa2, 0x2937673d, 0xea54fe08, 0xb45b9aac, 0x9597f85c, 0x36bfab1e,
- 0x8d9aabef, 0xe8de7798, 0xcd95ff18, 0x6bd1ce32, 0xa6af71f5, 0xf56e312e,
- 0x6bbb6b58, 0xdaf0bf75, 0x5df96b02, 0xcbafdd7e, 0x91d83ca3, 0xbae5524a,
- 0xcbf09b68, 0xdc72bd2a, 0xe3af9d6c, 0x099a767d, 0x80e691be, 0x77f17af1,
- 0x7bd600ae, 0x7e050535, 0xbc04850d, 0x9c62c28e, 0x01d0d9eb, 0x09c891bf,
- 0x9fddc5bc, 0x5e9162eb, 0x87ded76d, 0x8e49f3df, 0xeb852936, 0xfbb5e333,
- 0x89bd17a1, 0xe1add437, 0xce96e6f9, 0x63bf402d, 0x2fe13e95, 0x178f731c,
- 0xdfe40bfe, 0x8fd51699, 0x17fed957, 0xf97adaf0, 0x897c007c, 0x160287cf,
- 0x7cf857f6, 0xe16d7e00, 0x79bf4206, 0xa61c853e, 0xaffd1b7d, 0x4721cef3,
- 0xf7f6c8e9, 0x1b3f29ba, 0xbc9cb1ab, 0x92a93a96, 0x55a70192, 0xa5afbf62,
- 0x8c24d866, 0x7c580973, 0xff3860b8, 0xe8bf90ca, 0x31c8f37c, 0x1b3a646a,
- 0xa7a58d74, 0x813fe741, 0x470dcfae, 0xc4955ed7, 0x3ee03639, 0x313d9ab0,
- 0xf6944d6a, 0x89387020, 0xd77e5932, 0xa087b21d, 0x89631f8f, 0xd25f1859,
- 0xbfa50a89, 0xef5f5ebe, 0x16341d47, 0x53a7a6f4, 0xba5df944, 0xcfb736cc,
- 0xd65cfb10, 0x7dfa215e, 0x88bda719, 0x092f9c75, 0x820f644f, 0x99d5da3e,
- 0xf9e7833c, 0x0abb59e4, 0xeec5bbff, 0xd742a6db, 0x4fabb35f, 0x55f4b8f1,
- 0xe842ee6f, 0x86a393d3, 0xb8b467bd, 0x7b8d1d25, 0x357957c6, 0xc8ef38bd,
- 0xf5299a5b, 0x85e81490, 0x8d8f3e71, 0xf2c2bb63, 0xe125cbbb, 0x7975e748,
- 0x12a7db02, 0x49d85ed1, 0x4fdc7f83, 0x4e3cd9e0, 0x0fc8ec39, 0x7e3f8413,
- 0x9ef0252e, 0x9256f31f, 0xbf659fc5, 0x81add857, 0xb38e92d1, 0x3323e269,
- 0x73ecaf19, 0x07eb8852, 0x1b5da52a, 0xdd85b8f0, 0xd1b57aac, 0xa9dcfb01,
- 0x4cb88bdb, 0xf498f7be, 0x4097de3f, 0x26fc933e, 0xf059a616, 0x4b12f524,
- 0x7c8a94fb, 0xe06a7d4b, 0xa8fd4b32, 0x3e0b12ea, 0xa58666a6, 0x39a2c67d,
- 0xbb4b3c16, 0x7b3ed2d6, 0x6e0b42c5, 0x596ca1d8, 0x8b6d3944, 0xb5c7fd2d,
- 0xcfb4b52f, 0xa961de0b, 0x44e060a7, 0xd6aff721, 0xb2df8ffb, 0xe4cf5ace,
- 0x2f4395b5, 0x928fdfe4, 0xe614fbab, 0xd967b55f, 0x84e5e87c, 0xebac7bae,
- 0xc7657fb1, 0xa29d9039, 0xffa628d0, 0xddab3ed5, 0xe2b4caab, 0x8bff5e95,
- 0xaf5cdd60, 0x9fb2eed5, 0xb29e40a7, 0xf2961cdb, 0xddba25b1, 0xc453429c,
- 0xf8dbf87d, 0xe1665daf, 0x2ebd2c7f, 0xfe038796, 0xb49bb730, 0x97072ac3,
- 0x3072ac86, 0x1cab69f9, 0xe558f714, 0x5623f2e0, 0xad87f039, 0x67da5072,
- 0x13b28395, 0xf6983956, 0x0c0e558e, 0xd7e58cf9, 0x3e5588f4, 0xe5345348,
- 0x8aebf08f, 0x89f956b3, 0xbf510fe5, 0x8f3cdfe0, 0xfde68f42, 0x185afcf9,
- 0xfe21afc3, 0x77e1bd30, 0x4e4f0ece, 0x67d55e01, 0xf7cf10a7, 0xabcfbe98,
- 0xf279b727, 0x74ee9ed9, 0xd0257568, 0x3aae5d73, 0x0d5ca4b3, 0x87881df4,
- 0x198fafdd, 0x5a59c7ff, 0x1a2fda03, 0x0bae59f5, 0x4dafd1f2, 0x39e97dc2,
- 0x1ddd8495, 0xe7c72097, 0x4758b27b, 0xa87b1ef0, 0xd271d793, 0x3ec0a5d6,
- 0x2b6b2737, 0xa2f6ffd1, 0x07708536, 0xfe82a0a3, 0x971cfff5, 0x1c7ebc0b,
- 0x151e7b89, 0x2416ca45, 0x7d62ed45, 0x7af39736, 0xf7e896d6, 0xb9eb9514,
- 0x1912fadf, 0xbd5248b7, 0x290f112e, 0x20e200a2, 0xadc8bd7c, 0x8e3d062f,
- 0x3d024fc7, 0x9b2a6dba, 0x7d388a38, 0xf067d829, 0xa53d3b55, 0xfe113f48,
- 0x7fee8e5e, 0x4eff5365, 0x0ed273ac, 0x97ab9cb2, 0x30e4dc86, 0xd3f27dd1,
- 0xdc5e0b5e, 0x7f696993, 0xa59f11f9, 0xb42e1fde, 0xa9f697d4, 0x44ecbc16,
- 0xb4fda585, 0x7c160277, 0xd2daa47a, 0x35b38afe, 0x229c7c16, 0x5f7fafef,
- 0xe3e92f92, 0x7de44563, 0xba9fdfd6, 0xf788ab7b, 0xe1ad7bc9, 0x23d7534f,
- 0x4ce23701, 0xdec71cba, 0x404c5c87, 0xfec5cff0, 0xb183ce2f, 0x6b47e96e,
- 0x294fbaf7, 0xdd3f51c9, 0xff0db3f0, 0x01558295, 0xfdc3b9f3, 0xfba2f9e4,
- 0x6d7f86f3, 0x8bd3cdf8, 0x721ce27d, 0x26cabc6e, 0xc911c1e4, 0xc7d79c82,
- 0xfdf7b0d1, 0xbde44be7, 0xc6fd7621, 0x9fe762ba, 0xed95ec5e, 0x729f71f5,
- 0xc335edd3, 0x5cba33f9, 0x735f1c2d, 0xb8f9f214, 0x79677d53, 0x9e7f7fde,
- 0xb3cfa4ce, 0x2e5cde84, 0xb3675fd7, 0x31a3f889, 0x52a991cf, 0x7f380d5e,
- 0x7e3bfb0e, 0xe37deea2, 0x1fd87876, 0x21ddbc79, 0x9fc708e2, 0x2c1b515b,
- 0x01443f80, 0xef8e338c, 0x7c0fe003, 0xae1fdc0a, 0xfd176a99, 0xbd4897cf,
- 0x1265da8b, 0x24807976, 0x5dda07ff, 0x0c317ee2, 0x181c85bf, 0xcc7c41fb,
- 0x62e32051, 0x398b8880, 0x062e321c, 0x4031711c, 0xfe50c5c4, 0xf02a875c,
- 0x02151d83, 0x2023be7f, 0xd51d23f0, 0xa3bcfe02, 0x721b9446, 0xe32f4b13,
- 0x1ff0663e, 0xa373886a, 0xe71e4620, 0xe5f927df, 0xd9aceb5b, 0x6f9c5bc3,
- 0x24a56aa3, 0xa6dbcf4a, 0x2dc8794a, 0x3b407495, 0xed48ffe8, 0x2945ecaa,
- 0x900ea788, 0x47fbc52f, 0x53ff86e2, 0x6ee830f4, 0xfaa357dc, 0x2461f526,
- 0xbfee34bd, 0xd0acfba6, 0x8c7d58bb, 0xba58dbd5, 0xbdeb3f8b, 0x8d7bde59,
- 0xa7ae85f8, 0xbd0c5f06, 0x16a45276, 0x605425f6, 0xef7d06ab, 0xd1eab24f,
- 0xbe92a5f5, 0x8623d003, 0x74de7ca7, 0x7687ce1b, 0x5607f0af, 0x90ccb6e8,
- 0xec87e6d3, 0xf3e27ce2, 0xed37e3d6, 0x7db779b7, 0x6eef9ea8, 0xe215bfbc,
- 0x201d9d5c, 0xda5f1f71, 0x737684a5, 0xf5a086bf, 0x2521147c, 0xfae46fae,
- 0xe35fb817, 0x33f3d896, 0xf221d620, 0xe6b5bc2c, 0x72fd6b2e, 0x33c91efd,
- 0x632760ba, 0x96570af3, 0x4aa0e7ea, 0x5f7237ea, 0xdd105ee2, 0xa1572e97,
- 0x873829f1, 0xcbb4af70, 0xce3846b8, 0x21f3af74, 0x8a2a3fce, 0x0a133d33,
- 0x746e4e71, 0x177c13a8, 0xcf41a1cb, 0x9e833ca1, 0xeae7184f, 0xe23f753f,
- 0x8bc7cf8b, 0x7fcf057b, 0xbe76e823, 0xff40aecf, 0x7a08f287, 0x3b41f3fb,
- 0xe73e99d9, 0xba09c60f, 0x7e3b627e, 0x94cfbe4b, 0x5f28b877, 0xb015c941,
- 0xa8c6fb1f, 0x65d661c1, 0xfb222d40, 0xe1bf588f, 0x99ee3250, 0xfcc8cf2d,
- 0xbd33cb44, 0x7b2605e9, 0x10ea5cd8, 0xa6dbbbfb, 0xff2294b5, 0x8b9ddf60,
- 0x5f1dde7b, 0xce00a686, 0xb12de3d7, 0x77b219fb, 0x47211533, 0x613fbc03,
- 0xb115aaef, 0x0497b63f, 0x989b7b3d, 0x02ce3c9b, 0x34068f0a, 0x96da00f2,
- 0x2307c10a, 0xae10d00f, 0xb9b8fb10, 0x8133b973, 0xde76449b, 0x8be0955b,
- 0x392207e6, 0xc7fe08b4, 0x9b827948, 0xde315506, 0x886706f7, 0xcd281e71,
- 0xc6d0fe93, 0x1fe16bed, 0x3934f65e, 0x53888741, 0xa74b138e, 0xf3ca943f,
- 0x1d3c1320, 0xbadfdd13, 0xe7b08a0d, 0xc02ba0eb, 0x9ec22bb7, 0x5d67f81b,
- 0xf1255e3a, 0x3c49373b, 0x516cf4e2, 0x117ee452, 0x013ec02f, 0x6bdc1fb1,
- 0x05f1e9f7, 0xfb1003ec, 0x18ec3940, 0xe031d870, 0x61c063b0, 0xc76100c7,
- 0x6a94be50, 0x43e71172, 0xacd2a33e, 0xaa6e8327, 0xc825f934, 0xe4719867,
- 0x91edcc33, 0x23d730cf, 0x47ae619f, 0x238cc33e, 0x8f6e619f, 0x4719867c,
- 0x1edcc33e, 0x8e330cf9, 0x3db9867c, 0x7ae619f2, 0xf5cc33e4, 0x719867c8,
- 0xedcc33e4, 0xd730cf91, 0x58aededf, 0xb3b71df2, 0x35dc86f9, 0xf21348ee,
- 0xa6af3631, 0x7efe720f, 0x3977d7e2, 0xa3e7c1f3, 0xebb7212b, 0xc954135a,
- 0xc96aaee7, 0x3e491b77, 0x3e0ad7f7, 0x7892ebdf, 0x1de19a95, 0x1e422fc6,
- 0xe640b2a1, 0x47910011, 0x011e4400, 0x4a847910, 0x0023cc87, 0x72808f22,
- 0x910011e4, 0x1e440047, 0x04791001, 0x0011e440, 0x3f404791, 0x910011e4,
- 0xf2394047, 0x23c88008, 0xaf24fca0, 0x6304f903, 0x0ba3f05d, 0x963cf72c,
- 0xcf3dcb43, 0x47e1c16b, 0x8fc3db9b, 0x8fc3d736, 0x8fc3d736, 0xa3f0e336,
- 0x47e1edcd, 0xa957719b, 0xfc17e84f, 0xf83f7369, 0xb8bc66d3, 0x6212f82b,
- 0xfaefd744, 0x91808bdd, 0xc571e524, 0x41ec67cb, 0x4f7c8c5a, 0x4dc95e24,
- 0x545cf955, 0x192b8b5c, 0x844b06d7, 0x7ea14fde, 0xf22df81b, 0x2d37ccb7,
- 0xcde4214c, 0x14c8bf8b, 0x513e46f5, 0xfddf31fc, 0xe7f84907, 0x5d7245dd,
- 0xbc957f46, 0x7da34076, 0x5dbe1f14, 0x3b46fcec, 0xeb4d2f61, 0x1f9b0be0,
- 0xbdff7cf9, 0x2cad929e, 0x8a6d7b4f, 0xb2f74ff0, 0x1870b59f, 0xf74b34bb,
- 0xf6daf69b, 0x7ee04b1f, 0xba8a0dfd, 0xe89e8787, 0x09673ea0, 0x0256d4e8,
- 0xd4c2623f, 0xd47f3d54, 0x71616336, 0x3c46dd74, 0x0044ed8f, 0xfd99e779,
- 0x79e26ae4, 0xb907fd66, 0xb9cfe19a, 0x7e811fa4, 0x0e4dcfb8, 0x263d812a,
- 0xaa7cbef9, 0xe0b4ff3c, 0x5c4d19da, 0xdb5f793e, 0x77f8668c, 0x8fdfb209,
- 0x7416489f, 0xb2a361bc, 0x99fbcec7, 0xbb028fb9, 0xbe855db9, 0xbcfbc9ee,
- 0xaf3126ae, 0xce6cd5d7, 0x75caefbf, 0xa45f70f9, 0x88a66548, 0x3c842bc5,
- 0xde37419d, 0x1fd88bdf, 0xc43ef89b, 0x1d3d5765, 0x24d0fdef, 0xa93dad1f,
- 0x91cd7c16, 0x2687ef2c, 0x1f855b39, 0xeec4172c, 0x16adce21, 0xf5abe59d,
- 0x9a95b7f2, 0x9e784bcf, 0x0bbf7756, 0x35359bf4, 0x6c346ab5, 0x275251ff,
- 0x36a6ee40, 0xebc31a6c, 0xd50142d2, 0xdabd03ee, 0x93f8125e, 0xe2170235,
- 0x27d62e53, 0x4149c3ce, 0xa4c89c25, 0xdbb821b8, 0xebf19a36, 0xe99c1b83,
- 0x548fbf68, 0xf89303b8, 0x7449767f, 0xc274455f, 0x5e40af16, 0x499477a8,
- 0x7c72d8fe, 0x57e2f20f, 0x58f9049d, 0x613af0e0, 0x8dfd626f, 0xec0f77d8,
- 0xec2adc7f, 0x21d39f54, 0x3fdd3afc, 0xb5caf06a, 0x29d1b67e, 0x43868ffc,
- 0x3ea07fec, 0xde30dfc6, 0xa1dfb043, 0x1f8e7186, 0x720d4ebc, 0xb7dacb55,
- 0x7383bbc5, 0xa9bda179, 0xf2e7d72c, 0x0152dff7, 0x0aed90bf, 0x0dfb29ec,
- 0xb9654e77, 0x52f4d86b, 0x915dee32, 0x6fe101e0, 0xa1f1b67c, 0x905f1964,
- 0x9d2689f9, 0xa6fc464e, 0x9347e759, 0x03e5eefe, 0xa96c5bb6, 0xf186ee71,
- 0x2bd7815e, 0x3f588afc, 0x9bfbc891, 0x82bf5c99, 0xb195b3f7, 0x361adbe5,
- 0xfec5d267, 0xae6fe1a2, 0xb95de7d2, 0xb7de29d1, 0x3890a0ac, 0xac86560f,
- 0xfee957ed, 0xada7aae7, 0xca983fe5, 0xa1f2277e, 0xdfa9df86, 0xdbd4ee93,
- 0x7bdebc34, 0xda7bf0b3, 0x5075c89c, 0x07e906dd, 0x4d0a7ed1, 0xb5cf8050,
- 0x775e33c5, 0xc32aa028, 0xba9bcdc8, 0x931f343f, 0x0c173d32, 0xb23b0826,
- 0x8112f070, 0x299832df, 0x8583ade0, 0x19b11cb2, 0x4aa473e6, 0xe3c7dd09,
- 0x41fba5bf, 0x265e0f37, 0x198207ea, 0x58078e42, 0x14c5318e, 0x165d3edd,
- 0xd6117a50, 0x36d4ef9e, 0xf9fae18d, 0x95f849bb, 0xe25fc3d7, 0x9ff0458a,
- 0x7907a14a, 0x6f9f1855, 0x0f21346f, 0x9756b07a, 0x1203d67b, 0xec202376,
- 0x1082e559, 0xd22c93de, 0x6fc0dbf6, 0xe0b5fe43, 0xebf00729, 0x57cb8a83,
- 0xe215ee24, 0x77c86cfe, 0x27d41eac, 0x8f26f1ea, 0xc50d278c, 0x5e58b09b,
- 0xc5b5051a, 0x47afae01, 0x9d12f06c, 0xa4aa4cb1, 0x77df5922, 0x91bc5b50,
- 0x353fbdcf, 0xb367511e, 0xb3f57e09, 0x8a07b79f, 0x32aa274a, 0x94db27a0,
- 0xe8bead92, 0x9f289e7a, 0xba665033, 0xf5d52f27, 0x032ef58a, 0xdf758ef7,
- 0xc341909f, 0x6c0605f8, 0xbf433a64, 0x772253ea, 0xfeea4c29, 0x64a814a9,
- 0xbe92d6d6, 0x79fe244f, 0x3c758b9d, 0xdff6d0f7, 0xfa08f16e, 0xd4fcfc08,
- 0x45838b35, 0xac1d867f, 0x77d01c53, 0xadbe0ec3, 0xb7a0e768, 0x3cc8eead,
- 0xa8b135f0, 0xc5be05df, 0x6db6e7d2, 0x3127db3d, 0x24cb721d, 0x5d5ceaff,
- 0x80b8f14e, 0xd3dc4e42, 0xb9e48b1a, 0xee5f0e42, 0xf11f9112, 0xb19fb889,
- 0x6fe00fef, 0xf497430f, 0xc36fe932, 0xa4b9f63f, 0xff080c7f, 0xe04fef18,
- 0x7f87031f, 0x18ff080c, 0x818ff0e5, 0x0e063fc3, 0xfc3818ff, 0xc7f84063,
- 0x16d87f28, 0xf33f7538, 0x685b51f3, 0xd39661ff, 0xee6b47c7, 0x51ef9e32,
- 0x238f92ea, 0x63fb1348, 0x627611b9, 0x7cb13ec8, 0x72a3cbb9, 0xf4fdb4b4,
- 0x547e5b21, 0x7cb69a9e, 0xdc29f3ba, 0x841fd983, 0x945b6b3e, 0x9194dc70,
- 0x3b89ece5, 0x3cbe8412, 0xd84b8f71, 0x89d73add, 0x5179dc97, 0xfedbbe7a,
- 0x27694eb7, 0x3c7c13c3, 0x78b6e2ee, 0x89ff7615, 0xac1c9af2, 0x1548b137,
- 0xd9c0197c, 0xb256f88e, 0xa5f28796, 0x4ce5e274, 0x57ff576e, 0x7ea2e7af,
- 0x173cd1cd, 0x11c36fec, 0x1f4ce6ff, 0x21136bfa, 0xaf1e0daf, 0xeac5fe0b,
- 0xbce2a98d, 0x7190cfad, 0x9140965c, 0x31f83307, 0xdfc64cbb, 0x80ef79fa,
- 0x127bf417, 0xc0b9c813, 0x2df24ed2, 0xb88cdf56, 0x2b5c6c62, 0x72795f1a,
- 0x22e23e4b, 0xf4ed49a3, 0xc42f4c5d, 0xd1255c3d, 0xfc6c4ab8, 0x5d5f4863,
- 0x19e78964, 0x7e994d70, 0xa9efd74f, 0xd4f743cd, 0xf01979a2, 0xbc541fe7,
- 0x79373f88, 0x674eb77c, 0x89cfa9bc, 0x3f348817, 0x62cae7cd, 0x8afbffbc,
- 0xbdf80f77, 0x56ec2fde, 0xebc2781d, 0x2151da69, 0xc429b6f4, 0xfac8d470,
- 0xdec1e4bd, 0x5f619f9c, 0xeb0b80e1, 0x5c06f26c, 0xa77f2669, 0x98094bb1,
- 0xf819fddf, 0x8e3265ed, 0x07d7c758, 0xf5b6efd0, 0x88a5ae79, 0x83dbb25b,
- 0x746b6ef7, 0x71fa3139, 0x625ef13b, 0x0cbd3e7e, 0x7de7eab9, 0xbe616ec1,
- 0x4bf8d312, 0x7e69be31, 0xb5fc2f6e, 0x62496595, 0xef2f06bc, 0x2bd00f3b,
- 0x1074c9d6, 0xcedfea74, 0x3cc4f9e3, 0xe18dee82, 0x7ac55390, 0xf1834ef0,
- 0x1390dec5, 0xe8dd2cf3, 0x6d7ef117, 0xdb479c9b, 0x862aea92, 0xbaf0e73f,
- 0x1e7ecc72, 0xb2e41dcb, 0xd1fa970e, 0x0fc2bd62, 0xa53a626e, 0x634cffc1,
- 0x3173d7bf, 0xf5f41abd, 0x5aa57537, 0x07aec6fd, 0xad4fe09d, 0xf2c4ae7e,
- 0x8e5d31e1, 0xcabc6e97, 0x08efe845, 0x533ef0b8, 0x6ffde9d3, 0x22b7e36b,
- 0xfddb523f, 0xf18f3388, 0x4fd265ed, 0x46740c7d, 0x3c3f383c, 0xfa53ef01,
- 0xf78bc6d7, 0x2edeb5b6, 0x7a21dfb1, 0x81f4c43f, 0x11ade25f, 0x093966f4,
- 0x535afde2, 0xd1bf95b7, 0x718924f5, 0x841bba9b, 0x68732dfe, 0x1d79af2e,
- 0xa0985e3b, 0x596a5d30, 0x3f9c15ef, 0xf2172d5e, 0x5ba1e673, 0x793ec573,
- 0x9273a09d, 0xd8879bea, 0x908dcb04, 0xea7e436b, 0x1b3ea54b, 0x932c1df3,
- 0x65839cf1, 0xbfe9c7c3, 0xb69b4f4d, 0x71005035, 0x15524cbc, 0xd4f5dbe5,
- 0x5f434fd0, 0x6538f56b, 0xa405b6e3, 0x9f0dec99, 0x0dcf6ddf, 0xdd019f43,
- 0xf9d62c9e, 0x917cf4c9, 0xf7baf14c, 0xe5d67e74, 0xe31ef55b, 0x7557dc61,
- 0x139bafbd, 0x28b6b09e, 0xb798deda, 0x83f64d2e, 0x5ece43fc, 0xf682e9d5,
- 0xdd7b44eb, 0xa376e99e, 0xec6ec871, 0xbb0e94db, 0x79115fb1, 0xa5db75ab,
- 0x99eeb75f, 0xfadf1124, 0xdf8775f7, 0x9ddb85b8, 0x3d77787b, 0xabac6bf6,
- 0x44ed2c29, 0xb053fb33, 0x73f4cb1b, 0x7b58b3bf, 0xc7a4cca7, 0xccf77f4d,
- 0xe2c5e844, 0xdf99ff1e, 0x1877d892, 0x67bde6f6, 0x0cf6f17e, 0x357cf45f,
- 0xcb74b1f6, 0x3c1b38bf, 0x7dc9ba66, 0x2a5c2d6e, 0x5f8139de, 0x6e357fb8,
- 0x81de4454, 0xffc25dda, 0x2b1df834, 0xbfac0d07, 0x1ca89e8d, 0xc91ffc18,
- 0xe50d726f, 0x0dff24e7, 0x60721b7e, 0x13e0dbf0, 0xf9359ce1, 0xffbac6fd,
- 0xb17bafa0, 0xeb5fbf2e, 0x4578b77a, 0xd0996b9e, 0x23573cf7, 0xafaf5ee4,
- 0x0f96b26d, 0x643bc9f1, 0x2f4337df, 0x9f247a06, 0x6539b606, 0x45df721c,
- 0xb9c5ca7c, 0xb963ac6f, 0xd66c6f1e, 0x74cb86e3, 0x94f9983f, 0x6a665e54,
- 0x53e484f7, 0xffafb3e3, 0x627dcfeb, 0x6d8ed27f, 0xe2fe138f, 0x82fd9ed2,
- 0x1e5bb55f, 0xbb71e674, 0x7719729c, 0x6df3b21c, 0xe7e22f7e, 0x76ecb78b,
- 0xca73ff42, 0xe562dd25, 0x077f4ebd, 0xe715d06b, 0xf73a628f, 0x7bb0f68c,
- 0xf59e79fb, 0xf193e36b, 0x6798c6ae, 0xe394b95e, 0x34d4b6c6, 0xd6d8d7cc,
- 0xabdc03f0, 0xab1fbb0c, 0xa5e3a777, 0xf1e52c3e, 0xafa797a0, 0x15d77352,
- 0x332f9c5d, 0xc972ace0, 0x79311fb7, 0x3b258ef1, 0xe227e7b1, 0x049ac41d,
- 0x82e5f915, 0xf3084882, 0x6eb18e42, 0xbc45db17, 0x89682987, 0x14758a7c,
- 0x02ff7c90, 0xf3269498, 0xef8ce91f, 0x305765e1, 0xd84bb7cc, 0x2107d3a8,
- 0xe8d3d434, 0x1ff61948, 0xf246b76b, 0x34f90c2b, 0x53b589c6, 0xc96fed23,
- 0xe9dfdc77, 0x525e3d3c, 0x79bae6a8, 0x4e1ffade, 0xfa3f1152, 0x12ba7db6,
- 0x6869be64, 0x15ac2cbf, 0xb7ecc369, 0x4683de40, 0x55776fde, 0xbdfb30fa,
- 0xebac0f28, 0x7bd6f189, 0x25d23f28, 0x15a723f3, 0xdfb8b73e, 0xe2f1b5e9,
- 0x2fb199bd, 0x5dff3e23, 0x9477e7df, 0x8b71e9a7, 0xc9fc1248, 0xff5d04ba,
- 0xf94712c3, 0x71b95302, 0x46f49fde, 0xf64cd292, 0xfd36c3f9, 0x76c8a43c,
- 0x1f6f8311, 0x9c73884f, 0x649d3aec, 0xca7c822b, 0xd6fd19f5, 0xed93d53b,
- 0xe29b73b0, 0xf66efbc4, 0x8e23369b, 0x154c1cd4, 0xdadb99f1, 0xe0eccf4b,
- 0x98db6e71, 0x5ebf0aad, 0xe997f3f7, 0x7d712ff6, 0x6869e6c3, 0x0bcf23bf,
- 0x53d9be3f, 0x2dfc42e3, 0x2b817bb1, 0xf2bdf85f, 0xabe4601e, 0x03542bd6,
- 0xfb0e5bfd, 0xbdb2bd08, 0x66f38050, 0xffe90ef9, 0x16d1b7cf, 0x75c73be4,
- 0x82cbccd6, 0xa8a9d87d, 0x176927f0, 0x7ee351db, 0x6923b6c6, 0x72cecd4a,
- 0x962bebd0, 0x32ff1e3b, 0xec76b19c, 0x7b8027a7, 0x817fb127, 0xa03d60fd,
- 0xb4b9564b, 0x4fbb278f, 0xa28af925, 0xbf53fcf4, 0xc2e4317f, 0x23359bc8,
- 0xf20a33ee, 0xf90e9751, 0x63f3d268, 0x0ae7bb9b, 0x4df779bc, 0x4e973be2,
- 0x647be634, 0x0f5583d3, 0x733e5907, 0xb5347a75, 0x7e01bdce, 0x713d8ad1,
- 0xe35ee2a9, 0xfd9ae60c, 0xf7dda6d0, 0xce5eef8b, 0xdf178eee, 0x177a54bd,
- 0x3ef2a654, 0xf54aed97, 0xc2e74ddb, 0xddfeba2b, 0xf2d73ad1, 0x8f334afd,
- 0x7ff1e5e9, 0xde2893df, 0xa5df192f, 0x8ed6e55c, 0xfbe34ec1, 0xf93ee994,
- 0x68964a5d, 0x3e361bef, 0x1d33c06f, 0xd3073bf2, 0xd4373677, 0xd696ff72,
- 0x6718c903, 0x956f43d5, 0xd7108533, 0x1a7c037a, 0x8766cefa, 0xf9a6cefc,
- 0x77bfe1a1, 0x3e435c81, 0x4b211c57, 0x50b6f17e, 0xb543f08a, 0xef90b930,
- 0xfc24bcd6, 0x6a76b3dc, 0xf86eb9c7, 0x44794625, 0x94d9c3a7, 0x7ff05cae,
- 0x7247dee5, 0x9c7c6e71, 0xbdbaf124, 0x7612feb7, 0x4e327b48, 0x120edffa,
- 0x50636dfe, 0xf7c6cbfa, 0x1baa4453, 0xe573f0f7, 0x95bc6289, 0xc63877fa,
- 0x10bfd8ba, 0xa83b1fe5, 0xf7c0eb1a, 0x77e79035, 0xf066e11d, 0x47f65df3,
- 0x4578ef91, 0xbb77bf97, 0x7bc4f3ec, 0xf8045622, 0x1d76ef15, 0xd11e4248,
- 0xecaac3f0, 0xf0ec05ef, 0x7e290e97, 0x4589c39c, 0x863dc427, 0x6ac978f4,
- 0x75b794af, 0xcbce733f, 0x2afc2d1e, 0x08e2d251, 0xd7e386bb, 0x34dfba1d,
- 0x2fdc1f84, 0xfb2d65ee, 0xd2d05fa4, 0x05f84a73, 0x7c619f86, 0xdf6ab747,
- 0x1827e129, 0x941f56fd, 0x283d6974, 0x6d0a1bcb, 0xa025bc46, 0xacbee014,
- 0xd9727c08, 0x38364bfd, 0x25e6f8cc, 0xbd000a1b, 0x5fa43c7a, 0x0b5be5f8,
- 0x33ee257f, 0x71f51bad, 0xe69a7719, 0x4636994b, 0xe5c5c77e, 0xefe83de3,
- 0x5adfdcb3, 0x50fbca0f, 0x8b6135b8, 0xdabb1778, 0x6cec00e3, 0x7cf388f5,
- 0x10ad9b57, 0x4a03c9ef, 0x8ee7f082, 0xc6b9efea, 0x3c4dfaac, 0xd45904e2,
- 0x13cb6bdf, 0xa7f2b8ef, 0x14193cf1, 0x8cbaef14, 0xfc2e67ef, 0x18a547e3,
- 0xe45c767f, 0x97802200, 0x096c7b4e, 0x53b325f2, 0xf8a0a522, 0x951f87a5,
- 0x00e44678, 0x60de50e2, 0xe9ca92f7, 0x695c467f, 0xaf8962be, 0x6568adbf,
- 0xe0eb4120, 0x6b8c9779, 0xfe7c8bf4, 0x8e52698c, 0x7be31cc6, 0x5f51ee24,
- 0x303dc478, 0xf89b5463, 0x228a8bae, 0x147768a5, 0x823e587d, 0xf084265f,
- 0xc93c8c3e, 0x983ccf32, 0xa8ef121f, 0x30df32dc, 0xf02e9fd0, 0xb431ce30,
- 0xda2dd4ff, 0x5dd1cac7, 0xa0fde4d3, 0x63e64e26, 0x399c546f, 0x9b9300ff,
- 0xfa0b5da7, 0x8bdbe4d5, 0xdef1e3fd, 0xbf03be4e, 0x0d6de7a0, 0xbe8e797f,
- 0x9efd1caf, 0xd324bae7, 0x0253fd03, 0xe5ddf101, 0x1ac7457d, 0xfd03ff31,
- 0xd0fe426e, 0xa738c778, 0xabde413f, 0xe716a92e, 0x5073e2ab, 0x563fb71d,
- 0x1de30b64, 0x16e403ff, 0xc7726579, 0x78b6d9f8, 0x395b1ef1, 0x3817cafa,
- 0x9fedb267, 0xfef0a6f6, 0x5152ffb3, 0x07eb8361, 0x26f63cce, 0x3dc1bac3,
- 0x7d8fb1fb, 0xf6235ac9, 0xfaa07271, 0x7e24c694, 0x56e3dbc0, 0xe645f9e5,
- 0xfbbd1ff5, 0x5b34e48b, 0xfa175d74, 0x78733ccf, 0xc45ba02a, 0xb51ce7a5,
- 0xcc5638cb, 0xfa642e7a, 0x6e70bbc4, 0xc17ee827, 0x5ee10b63, 0xef68e738,
- 0x1cdf583b, 0x7dc677bc, 0x6f3cedc1, 0x97c8e73e, 0x1af78a93, 0x64df9d30,
- 0x1ac0ed47, 0xef4a3cfd, 0x0579bdf4, 0xed57c9ce, 0x73037884, 0x963ff052,
- 0x1fc16f7f, 0x699ce3c1, 0x2a36def2, 0x4d3826bf, 0x072863e8, 0x3ed338fa,
- 0xd0b53bfc, 0x638f4534, 0xfc1a7e49, 0xf063f832, 0xdd33a0c3, 0x14a5e270,
- 0xf8b7d045, 0x3fae9287, 0xe2fd7410, 0x4b5626f8, 0xd70fe4ba, 0x7ffefa0a,
- 0xfbc8eba3, 0x0d85df93, 0xde1eefed, 0x7f659e5f, 0xda5ffd3f, 0xeff7d09f,
- 0xd613bfbc, 0x8677a5fd, 0x4e4127e3, 0x7f09b21e, 0x28bdf62a, 0x97b09215,
- 0x1104f6f5, 0xe412d537, 0x276c06f7, 0x349d825f, 0xeab8e3ec, 0x8afc3148,
- 0x638f4493, 0x8f5b115d, 0x5a78ff28, 0xb19390be, 0x7c4b2274, 0x9488e137,
- 0x54ed6fc1, 0x76dd3b02, 0x8733c8c0, 0x7a565f61, 0x42edde44, 0xf27416c8,
- 0xa1a9ddf8, 0xde78cb9d, 0x448b9bee, 0xd102e51e, 0x1f382394, 0x7f082457,
- 0x84953bb4, 0x9daeeadd, 0xe796fc28, 0xc2e7b6bf, 0x4dafed5f, 0x6edbf910,
- 0xfc3b647f, 0x3e09eecf, 0x7f4dc835, 0xf844d0a1, 0x6e05c1ab, 0x02f74f31,
- 0xb7bb0769, 0x83f7c8e7, 0xf209fa14, 0x48ae8f48, 0xeec17910, 0xc42c81dd,
- 0xd24c3ecf, 0x2e1f434e, 0xb873cbb1, 0x19cb8f3b, 0xd4d4ac3e, 0x62bc6336,
- 0x6d48eeb9, 0x797bb3c2, 0x3602f894, 0xb27e5c99, 0x6be4493d, 0xe2317d0d,
- 0xa782e3d5, 0xc64e8276, 0xebefb677, 0x5dd065f2, 0x0eefc809, 0x721bfa0d,
- 0xbba75a36, 0xb794af72, 0xabc7f7a1, 0x1e3fbc49, 0x77c04bcb, 0xaa71f56a,
- 0x32be740f, 0xeb12fb45, 0x7ccb5cee, 0x92fd63b1, 0x1df127fe, 0x95fe30e1,
- 0xd38f42b3, 0xd45fdfe8, 0xf523b493, 0xed16f7c6, 0x282defd6, 0x79153632,
- 0xdc47213b, 0x9abef7ff, 0x8dd80ab8, 0xc125df82, 0x4fff1c6e, 0x80efb0fb,
- 0xbcf215bc, 0x296bc4f0, 0xfdfebda2, 0x1f5fe189, 0x83947ff7, 0xdde4e273,
- 0xfc058caf, 0xad26a92a, 0x70f5d782, 0x70f3e7ed, 0x159fbd74, 0xbccddf11,
- 0x8e65fb5f, 0xfbdfb788, 0xeff7908a, 0x02ffceba, 0xb38b7a5f, 0x000040d0
-};
-
-static const u32 tsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33b3af8a, 0x21716830,
- 0x9f0143f8, 0x38606664, 0x8167c40d, 0x81859798, 0x818997c1, 0x78898fc1,
- 0x10c533fd, 0x0611416c, 0x5e203b06, 0xf0c0c42e, 0xce21044e, 0x10c0ce28,
- 0x20c0ca2d, 0xafe10a2b, 0x6266d204, 0x40ff71d4, 0x4c194663, 0x089207b1,
- 0x79161336, 0x268ccc64, 0xca8520ef, 0x7fa02167, 0x2517f1a0, 0x22acbe54,
- 0x8a846e84, 0x9793457f, 0x432bca83, 0x094df5fd, 0x502ab9bb, 0x1aa00079,
- 0x03605f82, 0x00000360
-};
-
-static const u32 tsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780d, 0x733ee8b5, 0x49999cce,
- 0x21264cce, 0x61021309, 0x40a02092, 0x200c7e18, 0xf7f09d78, 0x803aa568,
- 0x07515a56, 0x43f21081, 0xbd1f5202, 0x24266bed, 0x1bd568c1, 0xab45a8fa,
- 0x68a90076, 0x62348ed1, 0xa80740a8, 0x0db6a85c, 0xc7f42ad6, 0xc405ad1b,
- 0x96aa4490, 0x6bb94abe, 0xe64fbdad, 0x4019939c, 0x6f5fb7bd, 0x6fd697bf,
- 0x67d9cfb3, 0xdfd7b5ef, 0xb5ed6b5e, 0x897628f7, 0xec650ee5, 0xc75dfe02,
- 0x319902d8, 0xf4a27576, 0x0d0ebbc1, 0x07f8adfe, 0xccdd2832, 0x2862b12f,
- 0x2f6e2cfd, 0xfc707281, 0xd65e9618, 0xf37e18c9, 0x959905f1, 0x3271e632,
- 0xb09417f1, 0xdaf2f5ee, 0x6d87b2b7, 0xd5b28428, 0x6cc653f7, 0x67aaed8c,
- 0x44f66181, 0xff57873b, 0x91c17e2e, 0xfa4870cb, 0x877560cb, 0xbb87c187,
- 0xb6e2e7a4, 0x8ef58c89, 0x7e2d8161, 0x5dde0718, 0xcffd059b, 0x316dec61,
- 0x704605e6, 0x8a50b85c, 0x4b8231df, 0xe73af8fb, 0x0ee76842, 0x00c55fad,
- 0x7334cf5e, 0xb9a26d7b, 0xf50d18ee, 0xa5fa8991, 0x6ca603da, 0x881de00c,
- 0xed5c03f0, 0xd79a4ef5, 0x81bdeb8f, 0xb6305761, 0xf547dea7, 0x2a7ef57d,
- 0xe923f5e3, 0x00fa81f9, 0xb05873d5, 0xeac7f090, 0x66ca2c36, 0x8536f1ac,
- 0x7412c7dd, 0x8c3d66f9, 0xfea24577, 0x222cd1a7, 0xa4fee4c3, 0x00423bb0,
- 0x132bc36b, 0xbca13a32, 0x7f41db1f, 0x28018d0f, 0x3fda26c6, 0xdce5f6bc,
- 0xcb181399, 0xdc91eafb, 0xbde00399, 0x46c616c4, 0xd2ad78e3, 0x9df031bc,
- 0xdbd1fbca, 0xeb6325eb, 0xed9a0f88, 0x65afdfc9, 0xf2cf0212, 0x7e60ac0e,
- 0x0f6bf437, 0x07013be7, 0x04c644b7, 0xb8c3065b, 0x186bec48, 0x111b32fb,
- 0x370e0089, 0x8c799761, 0xf342d0ed, 0x5f1cbbf0, 0x91230a48, 0x299c40c3,
- 0x2cab658c, 0x470a4b1c, 0x2b71c103, 0x4b0733fe, 0x0f4bd53f, 0x7ef571f2,
- 0xe711b2f4, 0xcee4e507, 0xde2c5b30, 0x77fbe197, 0xe862d242, 0xe7c5d9bf,
- 0x736302f3, 0x1249bc70, 0x12b9610b, 0x2dfa1299, 0x312732c7, 0xe5c60aee,
- 0x6173bae1, 0x547e8416, 0xc785985f, 0xfc837ef0, 0x6c8ca6fb, 0x1b7f9b9a,
- 0xda9443f1, 0x474ddb1b, 0x88b6fcb8, 0xedc7033d, 0x23ed883d, 0xf6c3163e,
- 0x39b6682f, 0x3b44b45b, 0x6e499e1d, 0x968b685b, 0x16c82fe8, 0xe5d3fa9b,
- 0xbe72764d, 0x81def9d3, 0xda9c809f, 0xc228fbe1, 0x3705983b, 0xbdebc127,
- 0x07a5be62, 0x3c06415d, 0xa3542ead, 0xafa9242e, 0x39eb0cb5, 0x0640594b,
- 0xe5eb4e1a, 0x0703b8f3, 0x3bcc49c9, 0x37c003e7, 0xfec01d94, 0x08e3e60c,
- 0xda03a8b0, 0x826b79ab, 0x1f4f5065, 0x1b02d5cc, 0x3672631c, 0xcdc473c9,
- 0x97a1c3fa, 0xfc13c7da, 0x00df1748, 0x0604ef5d, 0x41dba832, 0x78020ca1,
- 0xa83b8f1a, 0xe5dc8fff, 0xfd33b143, 0xf1f553bb, 0x3e414b71, 0xa61fd74e,
- 0x83beabb2, 0x63faeeca, 0x0f1aa654, 0x26c6d124, 0x60df8c03, 0x5dca2741,
- 0x075d12a1, 0xffee37fd, 0x218ff32a, 0x878823f8, 0x2d16cd74, 0x4e665e42,
- 0xf815cd59, 0xe12b7c45, 0x8e6ef9bc, 0xbdb3c45f, 0x866d0950, 0x2ad9cf32,
- 0x786d1aad, 0xfc40740e, 0xb87c1e97, 0x2ea4f101, 0x855ce365, 0x4f9c2f28,
- 0x97c89f11, 0x5f381abb, 0x284efd62, 0x029539af, 0xef1c5def, 0x53a9dada,
- 0xc06099df, 0x5c82c29f, 0x28bf39ae, 0x78c77ff0, 0x7b343a80, 0xbde82645,
- 0xbc077fbc, 0x9e7d268e, 0x906b95c1, 0x9e2adea1, 0x30ddebac, 0xabd27e23,
- 0x5079edc0, 0x97cfac1f, 0xf8897ff9, 0xfa04dcd8, 0xd57eeb09, 0x21fbc2af,
- 0x70e0f5a2, 0xca545cc5, 0x1ee7cb5b, 0x62bc6092, 0xa8fde3f9, 0x29d487de,
- 0xf41a776f, 0x6042c165, 0x86c622bc, 0x2f3f35ae, 0x30eb988c, 0xf3042d80,
- 0x3f316e2f, 0xd9dcce3f, 0x2e19d227, 0x80906e48, 0xbd5af37e, 0x849a45ec,
- 0xf58dde95, 0x0dd9ae2c, 0xf427a175, 0xdc99e4ba, 0xadf98119, 0x900592be,
- 0x449269c6, 0xefc56c78, 0x141e8f80, 0x7e96fde5, 0xac9952f4, 0x02ef50d9,
- 0xf4c983de, 0xd654be58, 0x56bc748b, 0xfd8bde9a, 0xe6312ba6, 0x54bf90d5,
- 0xfb6b13e2, 0xf1a14934, 0xa08e94d3, 0x14deeb8c, 0xb6adeebe, 0x9e51c6f7,
- 0x03f99756, 0x028f5c11, 0x4cdf9251, 0x5e50b358, 0x363c013f, 0x9363c389,
- 0xf5189c68, 0xdb2beb03, 0xbc38e122, 0xfa57d5df, 0x0d4a4459, 0x2d191fe7,
- 0x1698ec62, 0x3cfec4ce, 0x709ca492, 0x58d3e826, 0xb36ff451, 0xc372eaa1,
- 0x7513abfb, 0x7c739ddf, 0x4379c7c8, 0x772bf4cd, 0x7f2015d6, 0xb3628654,
- 0x7a4e7f91, 0x0edeba7e, 0xf602def3, 0x9ff80282, 0x61e50ce4, 0xea8b353f,
- 0xf30aa386, 0xe303a2e3, 0x1eb7b26e, 0x39824b07, 0x5ff48859, 0x0175cccb,
- 0x67dbde05, 0xf03b712a, 0x01f27da5, 0xac5c57b2, 0xc9c7eb8e, 0x07b43291,
- 0xef83239c, 0x455ef0ca, 0xdee78079, 0x75c32b60, 0xbccc39c4, 0x9b3c83ce,
- 0xb9b64aea, 0x5ccf4a9e, 0xf8ca5caa, 0x84069efa, 0xb267fc22, 0x995fe228,
- 0xf841281c, 0xf3e6bc1e, 0xaa67847e, 0x84a5d7c4, 0xde72e2fe, 0xbfb5ef47,
- 0x00361dc8, 0xf972b79f, 0xee4afb5f, 0x8f8809b0, 0x73979a56, 0x0b926ac6,
- 0x7323f115, 0x13b90ff9, 0xf878ebdf, 0x961bcf7b, 0xf4979a05, 0x5027f393,
- 0x6f3e363f, 0x9f9ea3f7, 0x7e3dbcf1, 0x366bd41d, 0x6df7a44b, 0x9f845cfb,
- 0x3d7947ee, 0xd88356ee, 0x5013ccfe, 0x3ad57c07, 0x8a9c1e3a, 0x665e7bf8,
- 0x0b3d085b, 0x4ecfa86d, 0x3b68f6e8, 0x78bb97af, 0xfef366b5, 0x8afbf1db,
- 0x7d430776, 0xf97bb35c, 0xbea1530d, 0x619db0fc, 0x0d6d9a93, 0xafa820ea,
- 0xac314a88, 0xf4e74cf7, 0xa392ec89, 0x8f7da0db, 0x66f723a7, 0x271dd70d,
- 0xb8008ff3, 0x37b91ddd, 0x46571f01, 0xdf8d9b9f, 0x0290ee55, 0xc7983140,
- 0xf07943b6, 0x5253cd5d, 0x5c7c01c0, 0xf99d3db5, 0x89e5f60d, 0x1d7e3936,
- 0x93cc19ca, 0x59cbbf41, 0x4fa46ceb, 0xaa0db6cd, 0xd39f40df, 0xdf9923f5,
- 0x3cd7a891, 0x77c0e305, 0x02959f2b, 0x3695c538, 0xef753f6e, 0xaadc2d76,
- 0xd41afce1, 0xd79c6ee1, 0x5bb62a3d, 0xcbbc5d1e, 0x36f847e5, 0x7de1b3ab,
- 0xd59ba3e5, 0xa85e8372, 0x640a3eda, 0xa6d700c9, 0x24e181e2, 0x0f01237a,
- 0x8953c133, 0xedd6867a, 0xa5768aa8, 0x2daa7cfe, 0x6ab1f893, 0x5fea6cbb,
- 0xd7e47ba7, 0xc887ec8c, 0x55e1375e, 0x2f6adba7, 0xa08eebe3, 0xa0af59db,
- 0x6a5bd2a3, 0x1f2f5fec, 0x50383a44, 0xfca97b5f, 0xca8fbd56, 0xa27ef58d,
- 0xbf8843cf, 0xc64edc11, 0x97d760e7, 0x827b2f21, 0xc3ec0bcc, 0xcb06e6b2,
- 0x0acf50ec, 0xa2ee7af1, 0xc8bfe4b0, 0xec12f5fc, 0x04e0c5de, 0x7afdfac1,
- 0xf63b0150, 0x8abc3521, 0xa6fc6005, 0x04ce08ff, 0x528ff77b, 0x4afa8638,
- 0xb82b85b6, 0x287cc5dc, 0xfac5eb77, 0x13f25db3, 0xa9e7d61e, 0xba1f6fa4,
- 0x2cab74ad, 0x6366b989, 0xf7fbfcbd, 0xbb3f5215, 0xfa151fa9, 0x3f74be29,
- 0x364fb7b9, 0x7b7b93f5, 0x01cfde85, 0xf2ed27ea, 0xf6e879fa, 0xdcf0cc6b,
- 0xf3f7a95e, 0xb9e3f532, 0xdee579bc, 0xcf0ccd31, 0xcfd4d51d, 0xd20145c0,
- 0x3fceb2b7, 0xb43bd60c, 0x8e647717, 0x5341fa37, 0xc0dfd36d, 0x520dc5f5,
- 0x8ca3e465, 0x792669c9, 0x99660cca, 0x0ce603ea, 0x09cfb532, 0x0fde9915,
- 0x8595785c, 0x89ef352f, 0x408ea251, 0xf68b43a1, 0xf49520f1, 0x2720d94e,
- 0x20f77fc1, 0xddcef48d, 0xe04784d7, 0xa2b08e3a, 0x1ab7737f, 0xea4deb1e,
- 0xcc4874c7, 0x86dfa587, 0x3dfdf5a5, 0x9e9c1ec2, 0xb7f0f1ff, 0x5b5afbe0,
- 0xa84cf0ef, 0xfb2b6bbf, 0xbcf9e233, 0x3269ffd0, 0x6976c3ab, 0xeffa460e,
- 0xadd2c29e, 0x5b5e0311, 0x48bf0086, 0xec5b7e89, 0xa3f21f61, 0x901a9364,
- 0x510fd73f, 0xfa041b19, 0x1fdb1d74, 0x9ee73581, 0xc43ee521, 0x2ffd03bf,
- 0x8c2af8e3, 0x77c69a3f, 0xb77c60d8, 0x8ef8f92d, 0xf1a6c9a2, 0xa615059d,
- 0x8c2a9df1, 0x6991f20f, 0x9df18973, 0xad6617e4, 0x8ef8d273, 0xff1a0a82,
- 0x9855951e, 0x1beb4fc6, 0xc60da07f, 0xfee3621d, 0x17f9bf4a, 0x7f9e635d,
- 0xfe79a541, 0xa17f9f2a, 0x9f8c532d, 0x5a2ff346, 0x2ff3e5e7, 0x77f3e4a8,
- 0xc6fb7ef0, 0x7fe1f4f7, 0x263f8e04, 0xe28ef8c5, 0x0ff9e669, 0xdfcf36ad,
- 0x671fc7c1, 0x6be313cb, 0x75f8fe34, 0xa1ff3e3e, 0xeabe34d5, 0x8f900708,
- 0xbab4fcd4, 0x8343da28, 0x240dfb41, 0x72a4181d, 0xbb93f724, 0xe38222a4,
- 0x77ce34ee, 0xbf01a51f, 0xca7d0969, 0x9e29eba2, 0x74f052b2, 0x35328ed5,
- 0x07bc5a3c, 0x00997f7b, 0x4cbb6975, 0x3a36cd7c, 0xbc0057a2, 0xf932eddd,
- 0x5e374b3b, 0x3d69951b, 0x1808fee5, 0xfe7c7190, 0xd98f6fc7, 0xb5979c62,
- 0x3f6ad65c, 0xab9069d1, 0x9d3efd3e, 0xf803ac8d, 0x535e4836, 0x69e804fd,
- 0x06dea674, 0x49e58c7d, 0xf3c0338c, 0xb38f4077, 0x7ffdfd11, 0xd1b5eee8,
- 0x0a2faf30, 0x1c284ff8, 0x48d627df, 0x47ffc451, 0xa8a9561b, 0xa6b596cf,
- 0x07d3d1a3, 0x53a0ad47, 0xd9076eef, 0x3f4f8055, 0x1216e7e2, 0xbf7ec645,
- 0x24870bef, 0x6f967bb0, 0x6efa601a, 0xfb368b11, 0xfb92fda0, 0xc2f10f17,
- 0xe85d6ffc, 0x1f932f18, 0x91b7cc18, 0x1b7cb31c, 0xdb0b4ef8, 0xa1f3d836,
- 0xbb42cb72, 0x52f94fc9, 0xb5bf5cd8, 0xb6ef5cc2, 0xcf18ed47, 0xb1215eea,
- 0x6defd0cd, 0xff8b7675, 0x6159c7c3, 0x08f112cb, 0x8117de3e, 0xe8f07986,
- 0xe3c72c36, 0xf5d12f63, 0x56ff2f76, 0x6bf6a787, 0x90547076, 0xe8399d7e,
- 0x0e48b347, 0x2f6177f9, 0xde15b79f, 0x60ceeddb, 0xfdb9e008, 0xd3e132ab,
- 0xbee77f0a, 0xec0da0f4, 0x7f4dced1, 0x6e7da3b2, 0xfe158f9d, 0xe75ad63b,
- 0x7d7155e3, 0x3eb11c58, 0x5aec988f, 0x2f6dacbd, 0x818efadb, 0x9f626a9f,
- 0xe18efadb, 0xf3edaabb, 0xd115f54c, 0x2fda992f, 0xf4d8b4df, 0x0aeb597e,
- 0x2d25fbd3, 0xc5f54cab, 0xda9aaf91, 0xc1b6b1df, 0xbab6fef4, 0x6fef4d7b,
- 0xaa60d8ad, 0xb0fc297f, 0x0b2dfda9, 0x4bde9b37, 0xed0c56fb, 0x1e1abd24,
- 0xeb76879a, 0x59f90771, 0xf2ebbf3a, 0x16ec0a70, 0xdd834f2c, 0xca036582,
- 0x6dbfc829, 0xb76b2f37, 0x35ea1e2c, 0xed2761f8, 0x4f280575, 0xe2b7be56,
- 0xf0dfcad3, 0x1d6c9f97, 0x8c6acbd2, 0x3dbf4143, 0x24393f16, 0x1f1ea0f4,
- 0xdcb956ac, 0x9bccef56, 0xb57ffe8e, 0x975e1f1a, 0x93ec4fc4, 0xf34498e7,
- 0xe7a56860, 0x5b80dd20, 0xdaab780d, 0xb3826c5e, 0xe34cbf6b, 0x05d944af,
- 0x0a5f37fd, 0x88f5c71d, 0x2c160fc5, 0x04f08318, 0xf6f5437f, 0xbb7f5a1c,
- 0x7d6ce7ea, 0x0bf88ec7, 0x7eaa7951, 0xea279521, 0x53be54c3, 0xdbe5415f,
- 0x765475f5, 0xf2a5afd6, 0x9508facd, 0xa16fabbf, 0xadf537f2, 0xdfab1e54,
- 0xf5ebe544, 0xebbb2a51, 0x7cea5483, 0x4327a7db, 0xfe156ec2, 0xb7224805,
- 0xe45cc55b, 0x96b8bedc, 0xacf1e50f, 0xb470d1f6, 0x031ecfcb, 0xc6a61722,
- 0x521f9597, 0xc90595e2, 0x028f28ae, 0x7ff4079d, 0x74e34aef, 0x1cd8d972,
- 0xdee37a06, 0xc01fbe2b, 0x15d41338, 0x47df8596, 0x49dcf303, 0x107f05fa,
- 0x3a2975e9, 0xc96f60b1, 0x89c7a07c, 0x8a5afe47, 0x456c86fd, 0x28385edc,
- 0xe2c97ad3, 0xaf48035b, 0xe9378a4f, 0x402fbf27, 0xa39339b9, 0x00a3afe3,
- 0xb2df04e3, 0xb39fa979, 0x20a60e6d, 0x47a4f71e, 0xf67d2431, 0xae0f56f0,
- 0x727dab77, 0xb31f18d4, 0xc2b13596, 0x4f9866a8, 0x7eb9bb6d, 0xc39a55b6,
- 0x8cfe69e3, 0x5f20c69b, 0x50efa379, 0xa547d15c, 0x9f6acfde, 0xfee8e34a,
- 0x4991db38, 0x217e0a7c, 0x86affbb5, 0x093f5523, 0x1fd8da38, 0x2e287700,
- 0xb93f8a17, 0x0f94ce5f, 0xb1bb8c54, 0x708ff63d, 0x7fc0773d, 0x6591d017,
- 0x7ef5d50a, 0xc472636b, 0xef9f1631, 0xdf078d30, 0xfb9f75f9, 0xf8c5d142,
- 0xf4276155, 0x9b6a8279, 0x0e443e8f, 0x6a2b95f2, 0xa699fbd6, 0x5e7b6d7a,
- 0xe00eb4d4, 0x59ee403f, 0x3ae0a485, 0xa8b82d58, 0x245ad147, 0xec8c6f80,
- 0xf126fce7, 0x4ece3576, 0xbe47ec35, 0x54e2fc69, 0xa56cb63f, 0x3be15af9,
- 0xabd87f5d, 0x5c7e245c, 0x3bbd9f25, 0xffc8bed9, 0x48bef996, 0xd3db8db5,
- 0xa0f119cc, 0x117ccabf, 0xe18bc60f, 0x0fc3eb4f, 0x8e304df9, 0xb3f7aea1,
- 0x4def6a22, 0xd9764eb6, 0x1d6c9db8, 0x7b8c45b7, 0xdcadfc29, 0xce367471,
- 0x95c78adb, 0xb4abefed, 0xffc0a31f, 0xd478134a, 0x0e463bf1, 0xdfc0c8b5,
- 0x22dfdb95, 0x3d94f27b, 0x176bfc32, 0xe1fd5bd1, 0xb7147cd7, 0x611de7d5,
- 0x9dce381d, 0xff67f17d, 0x7585bf2d, 0xed97ddf1, 0xf62cbe3c, 0x70387437,
- 0xf506d0d3, 0x6776a225, 0x9bc5155b, 0x3d75dddf, 0x594b6fd9, 0x644e83c8,
- 0x452d6b05, 0xb30cf03b, 0x9d3c41cd, 0x267aaf61, 0x43b4e818, 0x974e4956,
- 0x10ed98b4, 0xf54d5fb0, 0xf5cc9be5, 0x173f3672, 0x46f94cf5, 0x344a8b3b,
- 0x47fbd33f, 0x7fe12f65, 0x8f5bab39, 0x9da373eb, 0xe9ddb3ef, 0xe83e4a65,
- 0x1e179adb, 0xff38c52b, 0x7ebe648f, 0x1593f1ea, 0xab8edc59, 0x31566d8c,
- 0xb687ffbe, 0xca9c5f09, 0x7ae8fbf0, 0xcf221f5c, 0xfe6d814b, 0xa4fdf8fe,
- 0xd5e15bf0, 0x717eefd7, 0xcd47011c, 0xbc692976, 0x892cbf77, 0x63f39ff5,
- 0xbaa5e286, 0x5be7d76e, 0x22c9afea, 0x19332c1e, 0xebc67ee9, 0xe832d88c,
- 0xf38e207d, 0x3408e9db, 0x72c2fcc2, 0xf64c98e8, 0x1984bc44, 0x30e585da,
- 0x5e92ef3d, 0x93bb4729, 0xb412f129, 0x21ed6123, 0x3f05553e, 0x129e69c8,
- 0x31bb778c, 0x67718bbe, 0xd60b6797, 0xe62bbbd7, 0x16b51c62, 0xf7f401f5,
- 0x61f66780, 0xb2709fdc, 0xf81078d6, 0xef33e1d7, 0xe6fcb82f, 0x75ea3a7a,
- 0x00f877d4, 0x8c02f9f7, 0x23e954e2, 0x01dcedcd, 0x1f6cfd73, 0x5f7ce29e,
- 0xf71c589c, 0x0cb8b5c7, 0x4ac9b3e3, 0x54bf9f57, 0x871afe84, 0x5a64ec1f,
- 0x7978d6ff, 0x7e2295fb, 0xf4f8e6bf, 0x89175981, 0x939ed547, 0xceb0d458,
- 0x2abd2ad4, 0x39ed61f2, 0x6a7f9e85, 0xd587eabd, 0xf357a0d6, 0x929a70e5,
- 0xc228f5c3, 0x6138c127, 0xe3809f03, 0xf9ca35ea, 0x7c3f0b08, 0x99b2386a,
- 0x918fbf49, 0xe0c9f9c3, 0xfbfdd4f8, 0xe23ff5fa, 0x61ffb4bf, 0x909ffafd,
- 0x179affac, 0x8115d99e, 0x87f2a2f5, 0x3300f6df, 0xd69577b3, 0xbdd000dc,
- 0x07b35b7a, 0x1294f2e5, 0xdf5d20f1, 0xa273ca8d, 0x52a1f849, 0xa82ef9d1,
- 0x3fc4a549, 0x9fa747c4, 0xe80de6fe, 0xcdb47fc7, 0x7eff25ee, 0x00ee23bb,
- 0xb6d95ca6, 0x76c7cb82, 0x7ebc5bc7, 0x9fc8fbcf, 0x7d66edb5, 0xb7e4f951,
- 0x7eb4fd73, 0x1bff8445, 0xe561ff27, 0x8d9c7f13, 0xeb2d58f6, 0xfd67bd25,
- 0x973fc70e, 0x62c2f645, 0x7bffa335, 0x56b21f7d, 0xedb6a5e0, 0x3ee3ef9b,
- 0xe7db6d44, 0xe9a1724e, 0xfad1bf24, 0x07f0855d, 0xd9dc556e, 0xc49baf14,
- 0xe9bf2126, 0xee516178, 0x3c2fc80f, 0x9cf18256, 0xf65e27ae, 0x7c8da348,
- 0xd9dff5ca, 0xfdef92d8, 0xae5a9fd8, 0x1a3f41ba, 0xcedd6eed, 0x3f0bb7f3,
- 0xab2f0f66, 0xee0f71ed, 0xb66f541f, 0xf55cbed3, 0xffbf5b33, 0x8e57c608,
- 0x4057023b, 0xbccf55ff, 0x5035faf4, 0x9ece7aaf, 0x434f973d, 0xf4137293,
- 0xd6ff85a9, 0xa3d04f8e, 0xa92f47f2, 0xcf8d0fb8, 0xa0959ebf, 0xfb73d54b,
- 0x3fa63655, 0xf6c4663e, 0x125a9dab, 0x9adec4fa, 0xfc86fe8d, 0xe91579c2,
- 0x893eeeff, 0x824c2c0d, 0x912fcdcf, 0x22788cdd, 0xf57a0a7a, 0xbed2cfd1,
- 0x7a42e816, 0x6b2f42d1, 0xfe4269bb, 0xa78c5fb1, 0xfb3f7f03, 0xf977dc63,
- 0x7880238d, 0x2ef678a8, 0xa4e7ce0f, 0xfcf9c752, 0xcc5ce6b1, 0x47b0a8b3,
- 0xf254bd72, 0x7f8f15e7, 0xf96ff885, 0x52e4afd1, 0xf305833c, 0x443b646c,
- 0xcb9e70f2, 0xe699bd1e, 0xc4c2ce59, 0xc98f1587, 0xa1f0ff94, 0x973ce6c2,
- 0x16de4e44, 0x8b727272, 0x4e859283, 0xfb8242e2, 0xd1caaf10, 0x5bcf146d,
- 0xaf92f145, 0x6c47fbe8, 0x743fd535, 0x2bb57a72, 0x4b0c1fba, 0x9f7f9189,
- 0xe903a7b8, 0x70487a74, 0x6b81c620, 0xf8111299, 0xbf402e90, 0x0359d1f2,
- 0x5f989d39, 0x81df1529, 0xcf819ffe, 0x3d877db1, 0x7d312ae8, 0x26142ec7,
- 0xc6235fc6, 0xd0d3b807, 0x0b993dbe, 0xf99260f6, 0x3d25d865, 0x0cc1d46e,
- 0x7790667c, 0xdc4fff2e, 0x975de5cb, 0x39bce8ff, 0xd783fef8, 0x77e11cb8,
- 0x5c00bf68, 0x7ef481f1, 0xe9124dff, 0x278b0707, 0xec27f393, 0xefcdce42,
- 0xf002fcad, 0xf71eb82b, 0x938e0df1, 0xfb207445, 0x7c237cb6, 0x38abd46f,
- 0xbf7fa7ae, 0x172f1cba, 0x8af7e0fa, 0xfa100fc8, 0xf5ca3d80, 0x243f6a40,
- 0x7b75edc2, 0xa08ffbf4, 0x46bc82fc, 0xf6bf28fc, 0xbdffce10, 0xff5f071d,
- 0x7bcdc832, 0xcd6e5d31, 0xb72ad57a, 0x66af3b15, 0x3df6e4c9, 0xca92c02d,
- 0x2a4f3c2d, 0xf1275ab7, 0xaf5bdff3, 0xed5478ea, 0xebaabd66, 0xb4f854c9,
- 0x8acdc9ea, 0xd56af09f, 0x1af7f093, 0x8fcfed2b, 0xfcea1f3a, 0x9a83f957,
- 0xfa8fa8a1, 0xc3e754f8, 0xf9d53e3e, 0xd13c5fb0, 0xfbeb4784, 0x18dc605f,
- 0xfbb425f8, 0x81f3b3d7, 0xf87bd5ae, 0x777c2cbe, 0xaf80eb08, 0x5ad37720,
- 0x1b67e50f, 0x3d4b51eb, 0xb41f6966, 0xf69643d4, 0xcebd4b61, 0xe3ca3ed2,
- 0x5507ed69, 0x37139f9e, 0x63afb7b5, 0xb1c63711, 0xc714caf7, 0xd79801ee,
- 0x3b3df7c3, 0xc291a30a, 0x6f5b5e44, 0xf51eba8e, 0xd7b78f59, 0xaf62f683,
- 0x7aefc78b, 0x4c9ebd42, 0xd6f69d83, 0x71f4991e, 0x49cd9467, 0x05824fe6,
- 0x64ebf44d, 0xb8f3dea9, 0xddda0f7c, 0x592cde30, 0x718b582b, 0xf2995698,
- 0xdc369667, 0x8cfcc1e2, 0x37c53d9e, 0xcbe7842e, 0x9b7cc88e, 0xf2541230,
- 0x29dc7e0c, 0x9a687916, 0xf7c7fb84, 0xec97fd13, 0xd2dd7ee1, 0x73f393fb,
- 0x5caef8a5, 0xdea2a35b, 0x6dec7f04, 0xde83bee3, 0x96a3c54f, 0x17ae7be7,
- 0xfdfdcf7c, 0xefcc27ca, 0xb03e22c3, 0x71fbe74c, 0xcff71c6c, 0xae77e519,
- 0x96777a16, 0x85c6fa3c, 0xc39e8740, 0x39be4332, 0x3a2647bb, 0xf7c1dd9c,
- 0x3ece29ef, 0x97b5f905, 0xaf8e9df4, 0x118f942e, 0xd750f5a9, 0xfd2fbff3,
- 0xdea9341a, 0xef92dbf5, 0xebb5d942, 0xb117f0f8, 0x051bc2fe, 0xdbfd65bf,
- 0xa2e7d8cf, 0x7d9e8d7d, 0xec87da6e, 0x82f3fbd9, 0xb77d61af, 0xf6708023,
- 0x0973fbec, 0x3acf51f2, 0xb1ea0547, 0x1fdc219e, 0xe7fbdc6d, 0x3f5a4e92,
- 0x937e789b, 0x67c3fb9d, 0x4df5fcf7, 0x984b1b29, 0xfb07da15, 0xa87f69d2,
- 0x8a2ec7f6, 0xfdecf5ab, 0xced1a973, 0x59f3acff, 0x7b1bf629, 0x4ee16cdc,
- 0xef932f84, 0x38bed4d3, 0xe6036b65, 0x57edb463, 0x19fbc097, 0x825f393f,
- 0x2767b1fa, 0xedba7bb7, 0x7ee38f9d, 0x2fed77da, 0xbd03b3ae, 0x063851ba,
- 0x3f529a81, 0x92d11e9e, 0xc53ce5e1, 0x1f172f0b, 0xe0c7ff3b, 0xf57da243,
- 0xa8ee3dea, 0xff79c253, 0xa2dfcde5, 0x20e7d83e, 0xfbe7d4be, 0xec81ac5e,
- 0xfbcd4b91, 0xbcdd3fe8, 0xcce5f8a5, 0x7c1ff7bb, 0xf26377de, 0xe5fdd5db,
- 0xef9f3fa0, 0xcfea9bbd, 0xef0403b8, 0x57bbf265, 0xfd1c7955, 0x9ffe741f,
- 0x813bee98, 0xcf4b9eee, 0xf83fec7b, 0xfdd353bc, 0xee82edc8, 0xa947cc5e,
- 0x8279c9fd, 0xb9ea93ef, 0xce87ff1b, 0xefd7b75f, 0x315a05b3, 0xbd1d3b2f,
- 0xe1e73c01, 0xe182df9e, 0xce46fbc1, 0x28dda2f7, 0x2b4bfd8b, 0xfb95117c,
- 0xf3c4b27d, 0x1e10d9d6, 0x4fc263cf, 0xd710f342, 0x272b454f, 0xd6d154bb,
- 0x94ccdd93, 0xf0104740, 0x7755df72, 0x87d72806, 0xc6163f8d, 0x0169e0fa,
- 0xfc5b578a, 0x058926c5, 0x9557b025, 0x187f3eab, 0x48fb16fd, 0x4251dc5b,
- 0xde585be5, 0x7690e223, 0x67f26aaf, 0xbae6d1b4, 0x3bae6fcb, 0xc64e7f44,
- 0x58fa77e1, 0xf2d1e314, 0x98bc0795, 0x538f26cf, 0xbb2ea618, 0xfd046b58,
- 0xfccf8706, 0x73f422fd, 0xb45bf10d, 0xb060e3db, 0xad8efbfd, 0xf3383f14,
- 0x60375bf4, 0xca2f55bf, 0xe97809cc, 0x7166e1de, 0xaa251be4, 0xd9523fa2,
- 0xbe290726, 0x174bc4a2, 0x750bf618, 0x87eab17b, 0x72ab826e, 0x173a23a7,
- 0xf5dcafbe, 0xb75a1287, 0x3d92f5d7, 0x0a5a791b, 0x3be1a36c, 0xb03f704b,
- 0xbe7e4952, 0xe79511e4, 0x4eed751b, 0xbc7e885f, 0x6be79db4, 0xb16ec656,
- 0x28790c3b, 0xdebb541b, 0xf228f88e, 0x2cf94494, 0x4f319f08, 0xbb57b750,
- 0x7c38929e, 0xe628f6ed, 0x7f6e567d, 0x11e31bae, 0x011cc795, 0xb76b1b74,
- 0xeff14fbf, 0xc67c3f19, 0x977e49d3, 0xfb43f26c, 0x65db7ff9, 0xb6caeba2,
- 0xa15bb21a, 0x195df44e, 0x27d6fe13, 0x7eaa4ff4, 0x1e1777b8, 0xd1faa894,
- 0x778c1e93, 0xe6d8ee9c, 0xfb703f21, 0xfd31e3c5, 0xbdd8bdfc, 0xc2fbdfc2,
- 0x54e3e449, 0xfc69defe, 0x3f51d807, 0xf37e2d55, 0xc76401f6, 0xc9a59c02,
- 0xfe74c7f6, 0xc3e67aa9, 0xd95e31c7, 0xc7bdf3b5, 0xbfeaee11, 0xb471e9fd,
- 0x973ed943, 0x6a2df717, 0xc535fe9f, 0xdeeff477, 0xa25c7954, 0x2927a9fb,
- 0xfe0dd63e, 0xbdd6f636, 0xfa0164f7, 0xfdcfdd23, 0xe7fd1725, 0xd1677b35,
- 0xcf358ff9, 0x92c818cf, 0x225eb1c8, 0x232f46ff, 0xdba5673e, 0x6483b6c1,
- 0xba019f2f, 0xe7d2bfa3, 0x786ac7c7, 0xfc2fc47c, 0xe3c91df7, 0xf5fcfda1,
- 0x5e3705b6, 0x6db8f98b, 0x83aa00f6, 0xafedfa4b, 0x5ec73d01, 0x88771d06,
- 0x0bec4cf8, 0xcfdbf517, 0x5e803fe0, 0xfc742de7, 0xf7d96db0, 0x6d77c11e,
- 0xedfa5203, 0x9fc0cbf1, 0xa23d6f1e, 0x940e9d06, 0xa03f9db7, 0x6fd20978,
- 0xfbb84c2e, 0x300b0f99, 0xdeca7d5e, 0xb1e53b7b, 0xd17875ef, 0xfbdcad4f,
- 0xf753c906, 0x9e2947f3, 0xb3dc44c9, 0xf1fdf59b, 0xa1c894f8, 0xcdc27dab,
- 0x07417dfd, 0x3df8078c, 0xfdf85cf4, 0x78f5af9c, 0x4038aa40, 0xe4f3c1d0,
- 0xcd7038f4, 0x7e15bf13, 0xd26e8275, 0x5bd7a464, 0xeb5f8d17, 0x1e22f078,
- 0x5ce31926, 0x7d2ee3c9, 0xdd0b2e71, 0x5f56f8f4, 0x83ea0b1c, 0x95119e31,
- 0x371648de, 0xe3ccdeed, 0x7376dd63, 0x4e824dfe, 0xd535ee3c, 0xe8d38e61,
- 0x2f254df3, 0x6a5edcba, 0x4f149f1e, 0xbb08d0a3, 0xbabe3fba, 0xdfae4e3e,
- 0xde5c776f, 0xfdca757e, 0x7592a594, 0xc736e53f, 0xbc3f68d5, 0x57ca32a5,
- 0x0c79e5e8, 0xc8b9befa, 0x5a7aec17, 0xfac978a6, 0xefd241d8, 0xefa1fd56,
- 0xade159b7, 0x6caef013, 0xd747ebe7, 0x8354774e, 0xec0eba7e, 0xb95ebe26,
- 0xfd152de3, 0x7fdb43cf, 0x8b3b72a4, 0x1fae11cb, 0xba7cc351, 0xc25fdd9e,
- 0xdf3c7ae3, 0x37ce3ad9, 0xa93edc1c, 0x9c7c93dd, 0x9bef1dda, 0xc48aa9c6,
- 0x79ff9e54, 0x2b4ef1f1, 0xbfb05bc1, 0x3a761dd3, 0x263a73cf, 0xbfb649cf,
- 0x1761d8bb, 0x2f2b41f6, 0xbca51d61, 0xbcfca3ee, 0xd357c4c5, 0xcd7a0f28,
- 0xc5bf39d1, 0x406b8c73, 0x6c4ed1ac, 0xda7ce06b, 0xf9827ff6, 0xa3b6ef48,
- 0xfd71965f, 0x35f885da, 0xafa58bd8, 0x8370cdd5, 0x5dfd287e, 0xabb22268,
- 0x3a4cef55, 0x0fc13366, 0x75c40ce3, 0xc1fa09a1, 0x9fcc7dfc, 0xcf647842,
- 0x8f0839ec, 0x5d79b5ec, 0xed52f249, 0xcaf2885a, 0x5eed7ef5, 0xc338de73,
- 0x4fd086f3, 0x5e7a95f7, 0xf1032851, 0xcdc761f4, 0x328674bc, 0x775917bc,
- 0xd9bd094e, 0xf1601f55, 0x081cfc11, 0x7e456bd6, 0x839ec570, 0x560f51b3,
- 0x2fe624c4, 0xada473c4, 0x763f3724, 0xa573f264, 0x515db351, 0xd457e7b9,
- 0xb78db2be, 0x6a3162af, 0x8c45e78f, 0x6c4d5bf6, 0xe11ec582, 0xf223ddfc,
- 0x95cfaa42, 0xff21b8b2, 0x9f8267eb, 0x26bdeaba, 0xf08d5f3d, 0xd61afb41,
- 0xc4d4e341, 0xd1c69806, 0x9b9cd5db, 0x46afea6a, 0xab7e20e9, 0xf42ff739,
- 0xeabe4fbc, 0xd487847d, 0xe09be7fd, 0x853ff44e, 0xeb2427c5, 0xb73d1a7f,
- 0xe6fa87e6, 0xde6378f3, 0x882cbd02, 0xe88cfea2, 0xd3ca73e7, 0xbf808da2,
- 0x3ff85a23, 0xdcf81f50, 0x625f0b1b, 0x326cde78, 0x709f59e5, 0x0f047c88,
- 0x047cf0f3, 0x7583622d, 0xcb6d11f8, 0xf28c6986, 0x8c3b4e0d, 0x5e2c06f9,
- 0x6f447a82, 0x25bdefd7, 0x7e30611f, 0x1650aa02, 0xde631670, 0x8d07ac3f,
- 0xb05b3cf3, 0x9f9ba8fe, 0xbd602c93, 0x60ff31fb, 0x0a03f0ab, 0xdc58ce31,
- 0xa7e4bcff, 0x3d99273d, 0xd0d56ca3, 0x9cb36300, 0xa02a6723, 0x296fb32f,
- 0x0bdf2e7b, 0x3d9b1966, 0xb3d0f313, 0x971b2c9f, 0x4b58f507, 0xcbff7f27,
- 0x500571b2, 0xe2eae63f, 0xca24abef, 0xbe5b57d3, 0x7da2333b, 0x137d3d06,
- 0xa4d4a660, 0x409cb3a7, 0xdfa133cf, 0x1f99717d, 0x557a1ef3, 0xc216678e,
- 0x73264376, 0x7ed60dfc, 0x75fa1cf7, 0x0d9d6d43, 0xb7be5fa8, 0x7499cff7,
- 0x23f30fde, 0x6b1e9cf0, 0xe11d22f2, 0x170be4d1, 0xe6b3afc9, 0x74fce999,
- 0xec5c3b95, 0xdf363a04, 0x23ce9239, 0xde31523e, 0x26e37e89, 0x70f3b791,
- 0x3f21be5f, 0x93b57897, 0x44f9f7ef, 0x0fd9d75e, 0x2eb2330a, 0x7d6a1fa2,
- 0x0628278b, 0x5e947ab8, 0xf9efb7da, 0x31dbadf8, 0x99eb130f, 0xc499d649,
- 0x7be94bf7, 0xf3053e6b, 0x2d9f1366, 0x78867c15, 0xfaf21a73, 0x9511cb97,
- 0xc55bda07, 0x8bd337fa, 0xd52297f3, 0x9f5185f2, 0xb4c74f1c, 0xd3c45cf0,
- 0xcf299ce7, 0x7a45ce75, 0x6675cf5a, 0xe0374339, 0xe7e57977, 0xfaee500a,
- 0xad4a69ce, 0xeb3f4879, 0xf4a64fb9, 0x19f992da, 0xcfb9c45b, 0x710f7054,
- 0x71c36f85, 0xdfe27e8a, 0x7fe41879, 0x803552ec, 0xd763a4a9, 0xa4280c4e,
- 0x45de789f, 0x3c2be0ad, 0x1ee74eae, 0xcfb466ee, 0x8290e3db, 0xdcf7d7e8,
- 0x60bb25e5, 0xe4b9d2f0, 0x17a4f75f, 0xa93f30c6, 0xda7e6be7, 0x427b040f,
- 0xb21f3942, 0xf2ee2327, 0x647e9c90, 0xcc8fd391, 0xb71e6972, 0xbdbf82e7,
- 0x8af3fa93, 0xcfd0c0fe, 0xee9f9c4d, 0xdf7af991, 0x3827ef53, 0x7ec8b086,
- 0x772f1fb4, 0x853bafbc, 0x03e8281d, 0x1186fff8, 0x66c740ff, 0x3a43afac,
- 0xc74a4c8e, 0xb47464e6, 0xe49dc79e, 0xfd87df0c, 0x443f2c9c, 0xe7ad72e7,
- 0xc9129970, 0xe9593c43, 0x3eb4ab5b, 0xb9d25b8c, 0x3b27de7b, 0xd8dfa746,
- 0x4e88e3b5, 0x843e7a06, 0xf3dd8c70, 0xd6e10dbe, 0x291df8e9, 0xc14c1db9,
- 0x8ffbabc0, 0xd3b0bb97, 0xbed24e16, 0xf5296d64, 0x82d9f807, 0xf3f018e3,
- 0x9fbfd614, 0xe14f3f1a, 0x3f032fbc, 0x7e0e5ecf, 0x4aaf3f74, 0xee1571c8,
- 0xff9d015b, 0x5b9f9fe8, 0x96cee304, 0x15d3e235, 0xef8a64db, 0x79b9fb42,
- 0x5fb909b9, 0x3f6ea531, 0xf15c579e, 0xb4fc4498, 0x7fbf9c54, 0xb7bf9c4f,
- 0x2f9603e6, 0xbd9e908c, 0x94605e74, 0x76d546f4, 0x09c3f3f3, 0x3ca02afe,
- 0x89ef715f, 0x15805f7e, 0x213567ff, 0x365d4bd7, 0xfd02bde3, 0x66ceb7e4,
- 0x9bcf2bca, 0xf90fd7d1, 0xff9b3efd, 0xfdd38a0d, 0x6e30cecc, 0x27b25414,
- 0x131f11c6, 0x6fd899a5, 0xbd2f9099, 0xcd6ba1bf, 0xc4615e76, 0xb8b03e7c,
- 0xf03e7cc5, 0xf9f3568a, 0xcc9b11c0, 0x8caf03e7, 0x8e07cf9a, 0x54de3eda,
- 0xc6bb131f, 0xfb6c7ed4, 0x5c7d5374, 0xf6a6f3fc, 0x37cf0e13, 0xf8eeafd5,
- 0xa4fda9b2, 0xde9a7763, 0x34ace94f, 0x6a7a9fbd, 0x6d7ea9b5, 0xda9abfef,
- 0xfd7197c7, 0xe47ea075, 0xfa9e6354, 0xcdaa5581, 0x0d57cf8b, 0x8c4b79b7,
- 0xfe8373cf, 0x834b2c12, 0xd2a767e8, 0x579c33b3, 0xf7ae354e, 0xd26ecc65,
- 0xe69c333f, 0xe225c7ba, 0x2fc00510, 0x2e01fc40, 0xbc815cb3, 0x1e40bae5,
- 0xb5a6ebf2, 0x83c7870c, 0x40cb0c56, 0xcb390279, 0x9c9e5d75, 0x93bb63e5,
- 0xb1ebe32b, 0x003eec9e, 0x2ef910b5, 0xb29bf942, 0xe32ff738, 0xfe32173d,
- 0xc2a5443f, 0x5e4a1122, 0x7c860167, 0xf5f75d6f, 0x8f8adef5, 0x27c78b80,
- 0x04f0fe1d, 0xdc3f2cc5, 0x4c55f0df, 0x92f80c50, 0x76a675bd, 0x499cff0e,
- 0xef89f7c6, 0xdfcc9342, 0xa5d5342d, 0x7f2973e5, 0x765c1528, 0x4f5192df,
- 0xe7b37e80, 0x7f52a62d, 0x96d0bcde, 0x06f05f34, 0xc3f467d7, 0xc9ff3ca3,
- 0x80dddf60, 0xfd933974, 0xf79843ea, 0x2f5172b6, 0x0e79e3f9, 0xd4487eb3,
- 0x3a2f3df9, 0xb3d68f3c, 0xebdeb8d1, 0x4196dae7, 0x9a6dd621, 0xf3e3b2ef,
- 0x61af3173, 0xfd3f0a70, 0xc79f3101, 0x96a323eb, 0xa7306322, 0x41793ce9,
- 0xda3676bc, 0x9e454361, 0xe4b643f6, 0x2e5553f9, 0x440caebe, 0x82f68d45,
- 0xc13ed2a6, 0x79dff299, 0x55abf530, 0xff21570e, 0xa3b639de, 0x0ea39f94,
- 0x3f7e78f8, 0x77d75b87, 0x21e85a05, 0x60055fd4, 0xfb0bf9b6, 0x517033c3,
- 0xbc214e68, 0x05b2ca6f, 0x4af7aa34, 0xebf8de74, 0xbed03320, 0xc1326fe9,
- 0x0a6074d7, 0x5aa915e5, 0x27464598, 0x7e44c9e6, 0xf0efbe82, 0xe44df661,
- 0xd55d36bf, 0x9188de77, 0x3a85ab3f, 0x370fdfb0, 0xa6dc69da, 0x7de992e9,
- 0xeabad681, 0xde51c010, 0x4bf14e96, 0xe40dd365, 0x0e3ea97f, 0x12e3d34f,
- 0x3c112c1b, 0xe1eece3c, 0x7c3c00f8, 0x2670f105, 0x4d91f858, 0xafbc349f,
- 0xbce950c9, 0x711490e8, 0xfc3a6d8e, 0x3a2691c1, 0xc3308de7, 0xf6fc6f2d,
- 0x3f9843aa, 0x807a7cf2, 0x2e3ea4a4, 0x779e6ae8, 0x1bfcf673, 0x1aed04bf,
- 0x1e19935f, 0xc277f0f9, 0x91f34f1a, 0x7824d1a3, 0xf006e9d7, 0x957e436f,
- 0xf9a6cd37, 0x2f7a0a16, 0x3ae37a07, 0xe685b3e3, 0x6d73fd10, 0x9d6be70c,
- 0x07a10ec7, 0x8579719e, 0xf97396fc, 0xf51d2df3, 0x73d204c4, 0x73ffd86d,
- 0x73f694ae, 0xdd892b9b, 0x517ba975, 0x1c7617aa, 0xca0e52c2, 0xd427ee01,
- 0xcfda370d, 0xe27f1fa0, 0x72cdf832, 0xb04bd7c6, 0xe1d94bdf, 0x65a04ab5,
- 0xeda5e178, 0x90cfb434, 0x0cfb750f, 0xe71479e6, 0x9e8b0bf9, 0xa3f5e837,
- 0x4499e6c9, 0xed8ebfaf, 0x9e397e4e, 0xbd027ed4, 0x8e64764e, 0x65ff5c9a,
- 0xd47a71a4, 0xf946557a, 0x97f62985, 0xedc9696c, 0xdfeb54c6, 0xa290fca5,
- 0xc07ee681, 0x847f216e, 0xdfb4ab95, 0xcd83f675, 0x3cc70ef7, 0xf288ad21,
- 0x93f55383, 0x04c976bf, 0x22bfcf81, 0x9dfc741e, 0xf015e0b3, 0xeba4d7f9,
- 0xd3e03564, 0x4b27c266, 0xf47b0cbb, 0x32bb9fd3, 0x16ea179f, 0xe0758778,
- 0x16075a2d, 0xf18a59bc, 0x7f379597, 0xa7c0eb44, 0x39a1671e, 0x0fc7a08e,
- 0x21df9c60, 0xfc17ba9e, 0x3b7dc44d, 0xf8d95e29, 0x17ba08fc, 0xaeba66af,
- 0x749cea4f, 0x117072ee, 0x2ecce7d1, 0x3ce11047, 0x66e3c593, 0x3a4d7667,
- 0xf799f184, 0x19670fea, 0xd9e67ce9, 0xe876a5a3, 0xa3ceccef, 0xf7e90aa5,
- 0x9ddee9a8, 0x2abf0b9a, 0x3f5e7f45, 0x77c7d0df, 0xd3ebe4ce, 0x3f3f8275,
- 0x5e301e29, 0x0a51fb4f, 0xbbed187b, 0x9b54bc3e, 0x499c15cf, 0xf114b37f,
- 0x0eb97800, 0x43d3aee9, 0x332b878f, 0xdc60663a, 0xfc0bf7b6, 0x2e8da93e,
- 0xe352a71e, 0xcd769875, 0xe35b879c, 0xc475a658, 0x3b50ef28, 0xd2c711d6,
- 0xc41bd9d3, 0x7676a7ed, 0x5fb1e7e7, 0x7eef29ef, 0x06f567ac, 0xd0c7873e,
- 0x06afe765, 0xbb7c03bd, 0x71fade71, 0xf7e94fe8, 0xd98af96b, 0xe0b1c2c8,
- 0xe25e61bf, 0x2dcb8a58, 0xe607efc0, 0x71c41eda, 0xf37325a5, 0x6c5c8196,
- 0x8794a8f2, 0x1c08cca9, 0xf37c23f6, 0xecef8214, 0x17df9961, 0x85b9cf32,
- 0xfc67bf9f, 0xfd9b921e, 0xa7d4beb4, 0xc3e3e7e9, 0x2afeb885, 0x1a516cac,
- 0x85a707d4, 0xd732c0ef, 0x10fc31d6, 0xf63ae77c, 0x609c029b, 0xd0bfc1e9,
- 0xcabb3abd, 0x3f71fb42, 0xe4b777ba, 0xc7fac2df, 0x7e85ebfd, 0x48efcbd0,
- 0xef31c775, 0xebbefeac, 0xec7c6166, 0xba3aae3b, 0x82fe05f7, 0xe7f41f4e,
- 0x32cadf0a, 0x6a691c61, 0xa16b9cf3, 0xe3f7876e, 0xcd69fbf0, 0x577ed04d,
- 0xaf1f3866, 0x534b71c2, 0xc10f0f9a, 0xb5bca33a, 0xcd29b4fa, 0xfe663011,
- 0xe3cbcd35, 0x10b85aed, 0xf757d4e9, 0xa86ddd42, 0x85752d3b, 0xd579f5d7,
- 0xe50bfc1c, 0xc3dcae95, 0xd9ca2def, 0x1bdf8f33, 0xee8f3ed7, 0x134e6b8d,
- 0x9a63447a, 0x58563cf1, 0xf88bdf0e, 0x195e92ea, 0x8f48e5ce, 0x2f78a67b,
- 0x59c39ee2, 0x06e3c51d, 0x62eec1e1, 0xbc78cbb4, 0x52f580b3, 0x8aebc7a9,
- 0x61ca8058, 0x48e5442c, 0x55e54ad6, 0x68e5462c, 0x096541d6, 0xc032a5eb,
- 0xe39632bc, 0x6cca8059, 0x59d1dd5b, 0x667f4fa8, 0x7c3a7d27, 0x8303aafb,
- 0x44de9118, 0xc78d66b7, 0x656bd6e9, 0xdcbc1ad9, 0x3f50f828, 0x348d5557,
- 0xdb62be03, 0xe87ec8f3, 0xdef63212, 0xf7045b26, 0xf9a3d963, 0x9c5abcf4,
- 0x7e3eae47, 0xf7cdec80, 0x60f3c982, 0xbb8bc05f, 0x963ed33e, 0x3ed67f59,
- 0x41be11aa, 0x39405f7e, 0x41708959, 0xa0ece6dd, 0x75f69773, 0x3ee907b1,
- 0xb4ec67b8, 0x18555abf, 0xbd43b32a, 0xa061776a, 0x7a8720c1, 0x6655703e,
- 0x96bc772c, 0xf5888f38, 0xdf825a71, 0x286fb657, 0x77fb7dc0, 0xf5a71ff7,
- 0x85e987fe, 0xb69a9f34, 0x4dd86aa3, 0xca2a7efb, 0x7d39bbcd, 0x97d93af6,
- 0x0640aecd, 0xfde9779e, 0x4b6fbf39, 0x94f7dfc7, 0xdf71975e, 0x283d70e4,
- 0x5ee9b042, 0xf951f7a9, 0x953f7a8b, 0xb2f7ab3f, 0x4700f820, 0x04da9dec,
- 0x30ce4f9c, 0x7bfbca2f, 0x432bd8de, 0x7cbe6227, 0xe601bf91, 0xcefd98d7,
- 0xded013fd, 0x7401c80c, 0x75eeec0b, 0xf3b42513, 0xcf29f37c, 0xbc6d1ee5,
- 0x4f008ff3, 0xe67012a3, 0x6b2fb8c0, 0xa02bb53b, 0x24fcfebc, 0xe5ffce27,
- 0x0fcd36ec, 0xddc61bf5, 0x247dc5ec, 0x02e36fe8, 0xfa2ecfea, 0xf6c4ef1b,
- 0x5a3f62f7, 0xa2fd9fa2, 0x677bbd7e, 0x543fbe36, 0xebee08cf, 0xb1b2da73,
- 0xbd1f7fbf, 0x13f195ec, 0xba477ee9, 0x17caca2f, 0x66cb9fd7, 0xe6cbb041,
- 0x41602b9e, 0xd393c7a0, 0xf942aeeb, 0xd1bfd357, 0xa0fd04ec, 0xa255d614,
- 0xb7a6f0be, 0x1f413b34, 0x9d01b06c, 0xa59f54bc, 0xcc70095d, 0xb181fae4,
- 0xa432e696, 0xc62bb03b, 0xae8fe1e3, 0xfa82399b, 0x7efe1ae3, 0xd79160e6,
- 0xf7e3ed00, 0xed0b31bd, 0x918a6ab2, 0x66e6b630, 0xa479f746, 0xce2a37b2,
- 0xc1a8b3a5, 0xba61fbae, 0x42a7e49f, 0x4c3ed089, 0xbd0f39c5, 0x5cfefcbf,
- 0xfd8873a6, 0xfde8d3fb, 0x7e74abe1, 0x679c520a, 0xdf2273cd, 0x881c15c3,
- 0xd763beed, 0xb8f60fe7, 0x57d5f113, 0xcc3e288f, 0xffe7d043, 0x49ffcd28,
- 0xef1ef135, 0xf7d81cf5, 0x7fd1059e, 0xea26923e, 0xb7922791, 0x2fb4b34f,
- 0x34cfebd2, 0x1fd69ccf, 0x12b8ef9e, 0x57b42775, 0xeafa3bce, 0x9b06df08,
- 0x7d2cbfa5, 0xfc69e7fc, 0xb45942aa, 0x5052f7df, 0x723bd031, 0xabef19a8,
- 0x78ef454d, 0x9b9b2fda, 0xae23fbe0, 0x5fad1950, 0xbf5a3337, 0x0602ee50,
- 0xe34f183d, 0xb9c555fe, 0x247a2651, 0x7a6250e8, 0xd2e4127e, 0x7cbb4fb8,
- 0xfe745dc7, 0xe7e69e24, 0x3f08b0fd, 0xb168f557, 0xfff67f69, 0xe169f1c3,
- 0xc7014b28, 0x1c33bfcc, 0x3fe49a57, 0xd368c701, 0x387efff3, 0x6380a466,
- 0x1c153ff6, 0x2f457b56, 0x2bda2fff, 0xcabda357, 0x9d6c41e3, 0xf7fdce8d,
- 0xe52a2a64, 0xc99369ef, 0xe195204e, 0xdf68eea7, 0xcd779f2f, 0x8b1c7bfc,
- 0x615f9db1, 0xd478ca2d, 0x11671157, 0x857f87ee, 0x0fcf03f7, 0x8683a02b,
- 0x1f693a64, 0x5434bfdb, 0xfe05fb85, 0x5435e585, 0x546eeb7a, 0x587a5f70,
- 0xefb438ef, 0x4fd96b36, 0xde933337, 0x2fbad08b, 0xb6bb22ad, 0x9b279be3,
- 0x6078df71, 0x68c3dd5a, 0x93914b07, 0x24a787cd, 0xd6f5cf7b, 0xd14fd32f,
- 0xce9d14ba, 0x293f42ae, 0x0ec68aea, 0xb59a3d20, 0xf0a3d200, 0x2296d19b,
- 0xdaf72ba8, 0xaf000d02, 0xbedd1992, 0x1e57e005, 0x4d764e18, 0xb61ff514,
- 0x6e89407f, 0xfa9dfcc1, 0x1bb7c500, 0xa5b47d85, 0xf317ae69, 0x3099ed98,
- 0x7ae5204b, 0xd097dd7b, 0x7534d75e, 0xae0a73bd, 0x01968107, 0x01f75e5e,
- 0xb1164f5c, 0x78a66722, 0xb46feb0f, 0x1af20d81, 0x6fe97eea, 0xbab79f32,
- 0xd70d383e, 0x8c95d5f9, 0xf7087f7f, 0xd2cc9e89, 0xfbdfc2f1, 0x4f5c750d,
- 0x7d448694, 0xeb7bcc26, 0xf7df5c63, 0xd1ebaba6, 0x44f987de, 0xc31b8ec8,
- 0x630e93e7, 0xf4fe007b, 0xbeb44571, 0xf17d6146, 0x0a71fbe0, 0xf7d2f79d,
- 0x6c639c83, 0xed841fb4, 0xc2ea7ee9, 0x742fda22, 0x388163ce, 0x69e703e6,
- 0x09517f7c, 0x3b3cc4ce, 0x04bf1f77, 0x8aa6ce29, 0xa26d12fd, 0xad205f39,
- 0x99b45be9, 0xfcda369e, 0x5ccc39dc, 0x9dc0b077, 0x60ec8f74, 0x2681be4b,
- 0xb00687f6, 0x1457e841, 0x6c3622db, 0xca85da07, 0x76df7851, 0xec811e31,
- 0x0c58faa4, 0x31e31691, 0x0c1d3f2b, 0x3282c09b, 0x6486a38f, 0x698e3bf4,
- 0x07947ce1, 0x66e2269f, 0x8dbf7883, 0x36ff61a1, 0x8ff14fcb, 0xf5efb47c,
- 0xb379c6fa, 0x4a91fe29, 0x889a22be, 0xec36dee7, 0xce9af7a2, 0x19100738,
- 0xc68e6ff4, 0x6f6b81f3, 0xd779f7e2, 0x947ee1ee, 0xe8b27efe, 0x9c4536b7,
- 0x327ae413, 0xd63df9c2, 0x485edb39, 0x0e7cacf7, 0x75f356e9, 0x6b4fc31b,
- 0xdfb9c7e2, 0x53b7b166, 0x158da1e5, 0x5f9f4dfe, 0xf218fc23, 0xc2ce902d,
- 0xd2ea597f, 0x4fbe6ee9, 0xa247bf42, 0x4f4dc847, 0xa8c44ab9, 0xea098345,
- 0xe9853739, 0x3172821e, 0x654df29f, 0x2c1fe8b9, 0x8225ffdd, 0x79c6d973,
- 0x5e4bde2a, 0xe13171be, 0x52ebc745, 0xa7f07f8b, 0x8d1709d6, 0xb4f6e9a7,
- 0xfee81fee, 0x484fd580, 0x47e7fdf5, 0xcc3a27ee, 0x3ed195f6, 0x3c1affef,
- 0xe07586cf, 0x67de20b6, 0x473ffba5, 0xf98eecec, 0x73655cf8, 0x2ec3f9f0,
- 0x54560f7e, 0xd87583dc, 0xdf859c5f, 0x7f3e29cd, 0x3b2f9625, 0xedea1a63,
- 0x7a3e3f97, 0x4a0ff903, 0x8d3cc34c, 0xfff70a33, 0xe7633af4, 0x0bf38a64,
- 0x7eef5fbc, 0xb867ee95, 0x74f7f0be, 0xfdc6bd3e, 0x3f639d2a, 0x3ca766d3,
- 0xb15debbb, 0x1dfde36c, 0xcdee17d7, 0x747e18be, 0x8088e1ff, 0x7bd170f7,
- 0x571a6105, 0xb70473e4, 0x53d2174a, 0xe7cd6f7f, 0x3e98ecd8, 0xa669e513,
- 0x2ff9e926, 0xcd97c88d, 0xfc9387f3, 0xe89bcf64, 0xf39bfde4, 0xc791b24d,
- 0x47cfeeae, 0xef59ff3a, 0xf1235925, 0xe0a9ef73, 0x19b405aa, 0x3dc4d1d7,
- 0xef3d2a25, 0x0e86f116, 0x54f6fb1f, 0xac799790, 0x75fb4ece, 0xfd177ee2,
- 0x4179975e, 0x2242fdcb, 0xd6242aff, 0x5e4437c3, 0xa7e63cd5, 0x376817ef,
- 0x75bf51d9, 0x6e60fb88, 0xf1bb6162, 0x425ea67c, 0xb6bd26bf, 0x7eb98e60,
- 0xb75cc873, 0xe7a8a3de, 0xdeb4fccd, 0x89ef153f, 0x999dfbd3, 0xd3ec3f42,
- 0xb03c5d3e, 0x67507e2f, 0x71e81f8e, 0x43cc1abf, 0x1e18fda6, 0xe4e59bf7,
- 0xbb8f4fe3, 0x56a37f68, 0x16e33753, 0xc5b3ea0c, 0xc6967cf0, 0x8bc60df5,
- 0x59a29ef0, 0x6f1f7e8a, 0x80e7bf54, 0xf909cbbe, 0x0ddc6336, 0x5ee930f3,
- 0xdf1e70ab, 0xa0721157, 0x0ece19c7, 0x5e6467f3, 0x4db5bf84, 0xba9ee9b2,
- 0x13b895fb, 0x00fee0f9, 0xf04ac3cf, 0x6f14d471, 0x49a936d5, 0xebebb7ef,
- 0x9e0af407, 0x3ee0724f, 0x01f7d02f, 0xc635e825, 0x887b3423, 0xf4f776ea,
- 0xf2f23f0e, 0xe3661b03, 0x988d1055, 0xca760c1f, 0x6957da3b, 0x03db767d,
- 0x621ef187, 0xc7e6dbb7, 0xb341b8f5, 0xa357bed1, 0xefeb49cf, 0x8bdaa97a,
- 0xebf7a4fc, 0xae0854ee, 0x06515ab3, 0xabff08bb, 0xda334fe0, 0x87df31af,
- 0x9e37dff5, 0xddfaed46, 0x0a7075bf, 0x131d59c5, 0x17bc016d, 0xb1ac1d5c,
- 0xcfc9243f, 0x936f1bec, 0x549fb492, 0x77494ff8, 0xf507a77b, 0x7c96b743,
- 0x2dc8ba3f, 0x3fc2fb89, 0xb22c3ca5, 0x5f33c3c4, 0xefc71e1f, 0x8a1bcea5,
- 0x8a3e490b, 0x2b6f20dc, 0xccf59dc7, 0xe47c93f0, 0x2e1c7cf2, 0xabda8db7,
- 0x6c379e4e, 0x152da7be, 0x4978ea3f, 0xc8e50785, 0x37e78c5d, 0x7f719986,
- 0x43c52dce, 0x4e32d794, 0xb8afba49, 0x51a1e056, 0xcabf1009, 0xb89c86d7,
- 0x4f64340e, 0x7ffee277, 0x28cfe2b3, 0x88f0fb44, 0xd66e30cc, 0x8dcb35e4,
- 0xfb88b65e, 0x6dbae745, 0x7559ef49, 0xeeff92da, 0xbe6e5dce, 0x9fecb44e,
- 0x52dee742, 0xd46809f1, 0xa5a5d910, 0xf3ef178a, 0x5e1ced96, 0x04fc8a57,
- 0xfc54dfbd, 0x177eef71, 0x61993dff, 0x659f3a4e, 0x9c49af1d, 0x78026bc3,
- 0x1a6dced0, 0x6c7841dc, 0xd178a89a, 0xd3f9768e, 0x5ed0d398, 0xef489cc9,
- 0x78d96acf, 0xa5359026, 0x4f1d3be0, 0x9f6db9d7, 0x16c2ff8d, 0x0df9cbfe,
- 0xfc0dcbc5, 0xff193ab7, 0x983c875d, 0xde37e1c3, 0xf264a9ab, 0xbc2b3ffd,
- 0xde3e7e7a, 0x9fcc6e87, 0x845f052a, 0x1c8e8dc7, 0xec0c3e9a, 0x303abedd,
- 0x86d78c38, 0x73fb8e7a, 0xd133a771, 0x647dd1be, 0x75429376, 0xdf07df3a,
- 0x6cf7f105, 0x39fdc4da, 0xc1f3a835, 0x45beaa8f, 0x9f585e63, 0xbb2ccaef,
- 0xda51e717, 0xab9f8071, 0xf9a1cb69, 0xadef8b57, 0x9c3dc6f0, 0x2f1ee39f,
- 0x82c71995, 0x77dfc03f, 0xf348eb68, 0x2db71c63, 0xd639db8b, 0xf5bbceef,
- 0xb156873c, 0xfb49d1df, 0xf8333912, 0x3bbbd47a, 0xfea3fc9d, 0xf7e069f8,
- 0x8dec5869, 0x94367bbe, 0xd51dd938, 0xc7d0eec2, 0x82c45d2f, 0x2f4bbbf8,
- 0x2716b1a5, 0x843b87d8, 0x2df6321c, 0x780a5fb1, 0x7c6fb804, 0x3fed1471,
- 0x04bdfde9, 0xcfb612cb, 0x912cedcd, 0x3fc0cfe4, 0x6fba6631, 0x39d9c6ad,
- 0xbe47f51c, 0x46edde1c, 0x6758e33f, 0x5edbd62e, 0xe0f64d3d, 0x73f0f0a5,
- 0x51c2bf81, 0x571e7dba, 0x35d6718d, 0xf45d95cf, 0xc6355d7c, 0x50fe0c43,
- 0xe9b36f02, 0xa17ebf79, 0x1fe8bf3f, 0x8d392be3, 0xa09ae9c9, 0x4c8b3e4f,
- 0x0a7d18b8, 0x25d23de8, 0x1fd39a3a, 0xde60f9f7, 0x607fd764, 0x09ef27d1,
- 0x9f4ffd7a, 0xae26366f, 0x40e53f01, 0xf188e789, 0x9fbc5bde, 0x6fc794f7,
- 0x15b27f5a, 0xcb3553f6, 0x2c6987c0, 0x8dfa84e2, 0xd167ce8e, 0xfaebd3fe,
- 0xc7c11bfb, 0x39fd8c9a, 0xf2e91cb9, 0xb928bd5b, 0xedcb7edc, 0x3c0efc21,
- 0xbee0f716, 0xfc628bc7, 0xe81fd8b6, 0x76b6b3be, 0x3d4fe199, 0x96145c0c,
- 0x4e825ac3, 0xebe1fbfd, 0x60ff2e8f, 0x0b728e4e, 0x4a3947f9, 0x6bfdcb5f,
- 0xdfe8cf5d, 0xcfb47915, 0xee8f1f66, 0xc8ac4e77, 0x75724393, 0x05f44308,
- 0x7bbdf96b, 0xa2ff0b6f, 0xd39fdc5a, 0x18c7dfa5, 0xde33691c, 0x5a76f5bb,
- 0x87fd1441, 0xe5f787b7, 0xed1ae609, 0xf0576aaf, 0x1bbef0df, 0x7ca65476,
- 0xc1bc0fd5, 0x9a2fee0c, 0x712ea7fd, 0x3fee8eaf, 0xffdf8b35, 0x7f398362,
- 0x1dd24b37, 0x91ffb0f3, 0x72af749d, 0xa75f2e6e, 0xcc7f73f5, 0xf64259d7,
- 0x54abe0b7, 0x0f39f77c, 0x83d40f97, 0xad7ca491, 0x0dbf9e9a, 0x70c460eb,
- 0x53cee84e, 0xcf1ce8c3, 0x78a01612, 0x749692e6, 0xbde03116, 0xf9e4f1ed,
- 0xbe848b35, 0x4ef7136f, 0x5e7cd1b3, 0xf3e7be09, 0x1c975b68, 0xbe0c9eee,
- 0xfb89b70e, 0x6094dbc5, 0xd529e23a, 0x078fa13a, 0x3ca74b04, 0x6f07f387,
- 0xe6fd71a0, 0xfa257f71, 0xb26ff17d, 0xc0037df8, 0xd827d0a3, 0x9b1e1bfe,
- 0xe2bebe49, 0xb3faacf9, 0x24feb4cc, 0x9e933ef0, 0x927d767f, 0x927d0979,
- 0xf251ef4d, 0x3a78ced0, 0x7b75efc6, 0xce6db0fa, 0xdb742496, 0xaaf4e424,
- 0x3fee851c, 0x76e7151b, 0xb976aa40, 0x639ee259, 0x7c2b4781, 0xf9c9c5d9,
- 0xfe0ca5e3, 0x7e74f57d, 0x1bde334f, 0xb285f38f, 0x75fd0020, 0xf422d74d,
- 0x6fe25ffc, 0x7ab49c62, 0xbf8fc3a7, 0xd3b5d7cf, 0xa27a8155, 0x62a3a76b,
- 0x7e9fd68b, 0x3b663cbb, 0x4ccf99f7, 0xf58c7fbf, 0x705174a0, 0x5fd1cfc2,
- 0x3ee99768, 0x927f6b49, 0xecf34dc7, 0xec29e7d3, 0xb9b9afb0, 0xe74ecd3e,
- 0xf117b174, 0x572ad475, 0x1d3c8547, 0x2d90f215, 0x75876bee, 0x92eb89c9,
- 0x0217eede, 0x2cc393df, 0xe7c17de9, 0xb12e02dd, 0x76bc3c2e, 0x04c3fb06,
- 0x08ce7dfc, 0x7eda19c5, 0x7ec02f13, 0xdc78cabb, 0x16fdfac0, 0x998c67c1,
- 0x3349eaed, 0xb9e612fd, 0xc5e498b0, 0xfdbd7c7d, 0xb7bf18a4, 0xd3b9fff8,
- 0xdbc5ecfb, 0x807bbfc8, 0xf49a2eff, 0x81eb8a53, 0x61b4170d, 0xc18fd15e,
- 0x5ff8338e, 0x1de8b2bf, 0x0baf3c2b, 0xefc4da78, 0xeb8d3287, 0xf55d2b61,
- 0x779f4c75, 0x1cb300f6, 0xd7ff82c8, 0x9647328a, 0xb9743c68, 0x7d7c591c,
- 0x5cc4f9e6, 0x49d2e24f, 0x1e5859cf, 0xbcaf7003, 0x90e6fc43, 0x95dcef88,
- 0x31ef3e19, 0xe9da3df0, 0xbb097eb4, 0x6fdc4dbc, 0xa889dba9, 0x466bc74f,
- 0x0e0223b8, 0x4ad7d71b, 0xf30d7d72, 0xe2a7bf10, 0xf6127ea6, 0x262bb706,
- 0x166dfc0a, 0xb25f51e7, 0x3fb226b1, 0x39749e04, 0x9661951d, 0x7f8ca2d3,
- 0xacdd390e, 0xa4727cf2, 0x787d325f, 0x9427ed1e, 0x71c16387, 0x4572c798,
- 0x5fa00b48, 0xff31da5a, 0x0cf1e600, 0x943f83df, 0xe1e39093, 0xbfb19f82,
- 0x2dfc0645, 0xf09b70c8, 0x7f8cf9f7, 0xf877bb0e, 0xdf37d631, 0x7d7a0cdb,
- 0xe5c68655, 0x942ffc00, 0x9a7f8a83, 0xe00e86f9, 0xa06aae39, 0x9d0caa3b,
- 0x8b62da3f, 0x3ed0b9d7, 0x6802c63e, 0x16c7775f, 0x7f00c6db, 0xf6e26f74,
- 0xdf9e9f63, 0x7a05f1c8, 0xf97a8639, 0xf4c1638a, 0x275f50d1, 0x458ae3f8,
- 0x14e7df8c, 0xcfd14773, 0xce44f5d6, 0x7033bd4d, 0x7a6577df, 0xf0cb835d,
- 0x3b7dafbc, 0xe84c2fb4, 0x37d46a9b, 0x7df6d4fe, 0x8d3a466b, 0xe209eb87,
- 0x733a5665, 0x979e00ba, 0xee32230a, 0x4574be6b, 0xe7bc78e1, 0x785a50fd,
- 0x7ef86af4, 0x0e3e1cd2, 0xaf44776b, 0xd2ff1248, 0x88ae75f5, 0x7c8ae54f,
- 0x5e34dcef, 0x45f42c7e, 0xc1f39783, 0x9ebcbdaf, 0xcf1e49eb, 0x17ef11ea,
- 0xdcef5cc8, 0x2edc9657, 0xc67c6589, 0xb24063f8, 0x1963e3c6, 0x6f9ee239,
- 0xeb5f425b, 0x7c4273fc, 0x2edf8fa7, 0x9cfcb5e6, 0xe59fe264, 0xcdf11d4a,
- 0x3d0a73f2, 0x1522e5d7, 0x79fbe9ff, 0x78e11d9b, 0xbe7bd406, 0xc60961fe,
- 0xe9ef0a0d, 0xf848fbe2, 0x5253407b, 0x1ebe87cb, 0x3d06f4e8, 0x0df186df,
- 0x2713f3d0, 0x18f43ad3, 0x9c85975f, 0x1ff4ec1a, 0xb659efe0, 0xd4555c75,
- 0xdf6ba060, 0xfee0197a, 0xd95d758c, 0x57c4c980, 0x89d79ea7, 0xa3ef2ccf,
- 0x25e1d852, 0xbc3b577f, 0xc93c63b4, 0x578112ed, 0xc7a6de3d, 0x507b18b5,
- 0x13f731f8, 0xe4cd277e, 0xdff80df2, 0x9a3ff021, 0x7dbbffe3, 0xec95bff8,
- 0x2f2e5684, 0xa52b9db9, 0xfa2f9262, 0xa4ddff4e, 0x52afd3c2, 0x2f78e77e,
- 0x13ffe7f7, 0xc9555084, 0x00008000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
- 0xd5d47c79, 0xcefdf8b5, 0x3324b677, 0x5f64ccc9, 0x25849308, 0x2126126a,
- 0x26504109, 0xc5116109, 0xfb094049, 0x515983b0, 0x2fb5696c, 0x4a444103,
- 0x505d8bdf, 0xd101da94, 0x101ac55a, 0x83b06034, 0x6795622c, 0x05b054a4,
- 0x2108ee3b, 0xf16b43c9, 0x3dde5a57, 0x999bdee7, 0x006677ef, 0x7e7ebe7d,
- 0xdeb8ff0f, 0xdef7cbb9, 0xfb3dce73, 0x3ab3c9bd, 0x21094b25, 0x0b62a21b,
- 0x99941c48, 0xc84b125e, 0xbd3e0988, 0xe90844dd, 0x95242448, 0xa423aefe,
- 0x475aea0b, 0x2423c932, 0xbd389ead, 0xbed19eb4, 0xfad2d25f, 0x8637f865,
- 0xc94ad310, 0xfe9e30b9, 0xd3b694be, 0x3a166ddf, 0x9ed03130, 0x1609ebcc,
- 0xd025213b, 0x820d27cf, 0x936f36f9, 0xb4be74b4, 0x62908976, 0x2f13365a,
- 0x4b8c0ac9, 0x99efb073, 0x01695e1c, 0xbb48dfed, 0xac849191, 0x59e754d3,
- 0x14996812, 0xbfa568e3, 0x07bab06d, 0x4fea7ec0, 0xda667cf9, 0x2ea9c465,
- 0x7b8e9bad, 0xb4cceac2, 0x63f60624, 0x24692d97, 0x53989087, 0x366d9d6c,
- 0xfb05d732, 0x174cfe23, 0xc63f240c, 0x15b211f5, 0x93289bd7, 0xab46c423,
- 0x2f7e87d0, 0xd6ee7569, 0x7d6052f5, 0x6ee23649, 0x49496da7, 0x84d3bdc4,
- 0x2291d7fd, 0x7048d7da, 0x87ab493f, 0x059f5d6c, 0xde7179f3, 0x36d71caa,
- 0xf92abdf8, 0xfa56a2ba, 0x9f06ce7b, 0xb71d3e76, 0x0266b377, 0x2bcc53ec,
- 0x0916d1ca, 0x8c7dd1c7, 0x7d89fd80, 0x9289fba8, 0x5bae0f10, 0xb345d3f4,
- 0x5bf685fd, 0x4cc6f385, 0x6d0df060, 0x2f6c77ff, 0x0cc265ff, 0x1afd6f58,
- 0x0148313d, 0x75613ff8, 0x4d7002dd, 0x0122df6b, 0xa68c3e6c, 0xf02c3474,
- 0x29a30fdd, 0x76b0153d, 0x87f3853b, 0x79474a7a, 0xb48a3a01, 0xb295fafe,
- 0xa0f0e173, 0xe23d1afa, 0x2c9e8b69, 0x5e0bcf6d, 0xdf5c6adf, 0xcb068b22,
- 0x2cd756a3, 0xc7634f80, 0xfbc07ac3, 0xe81f6db2, 0xcef857dd, 0xee91c2b5,
- 0xe296957f, 0xb25daebd, 0x4ae92818, 0xe81392ed, 0xe8d6bea0, 0x6fd47805,
- 0xd64b7467, 0xa183bde8, 0xa7c3bede, 0xf7e9eda1, 0xfd321d3b, 0x0efb6eb9,
- 0x7c105169, 0x12bdebd3, 0x59a86bac, 0x1e9f2b9c, 0xfe8a95cf, 0x4578510f,
- 0x1c3bba51, 0x5a463c45, 0x3c9b9776, 0xb76f8512, 0xfd0f5dce, 0x1c6353ba,
- 0xf5efda1e, 0x488fe31d, 0x779adcf4, 0xae507c1a, 0x314d6cd3, 0xd775f6d2,
- 0x41ad1deb, 0xbad36774, 0x6b38c176, 0x8ab1d982, 0x206eca7e, 0x9c131645,
- 0x47fe2577, 0xc5cecfdc, 0xa32c4b6e, 0xe08a4223, 0x316e3c5c, 0x82893d63,
- 0xf7d28cbb, 0xd75b1d61, 0xe1e8c24e, 0x836b9c52, 0x23e3bf05, 0x3ade3a0e,
- 0x3a979d81, 0x7e891fba, 0x2ef36eaf, 0x623927dc, 0x6fa7b843, 0x75bbf097,
- 0xb9e0b7db, 0x73bb3ace, 0x2ffa1ebf, 0x2451a525, 0x1b9cce98, 0xd5efcf83,
- 0x426235f0, 0xade81ebb, 0xf2a1f38e, 0x3e936e5f, 0xafdfda0a, 0xa3c2322d,
- 0xfdb6f36e, 0x647bf469, 0xb60cb129, 0x13fdbf63, 0x06b5f7d9, 0x607fc412,
- 0x9d6c799d, 0x8ff8828b, 0x3e187fd8, 0xaf585bf4, 0x41d754e9, 0x487c87c6,
- 0x6afd628f, 0x7e7076bc, 0x3c4f4e38, 0x93debbf8, 0x1df3a76b, 0xf9c68ece,
- 0x73805f04, 0xa5f9c35c, 0x6213d686, 0x5a0eb9e8, 0x9e6f588f, 0x82d3a2b5,
- 0x3842e870, 0xe2d66c34, 0xaef4abfa, 0xce83cb41, 0xb9f9efc3, 0xfbda6d79,
- 0xfdfd3f7a, 0x83bf2fe7, 0x936869f8, 0x48cfc09c, 0x3bfa3bdb, 0xbfac01f2,
- 0x21124991, 0xb7fb0893, 0x7a3bf771, 0xd27dfd3b, 0x86bf862e, 0x0bb43b5d,
- 0xccfa014c, 0x1cdafb3a, 0x7686b3a0, 0x00928903, 0x582eee7f, 0x054e9a8f,
- 0x8ddf043c, 0x0998cf84, 0x0f128f8c, 0xcf485f3d, 0x731aacee, 0x8a5f6f80,
- 0x353a30d3, 0x2dbbdfb1, 0x1fa01eac, 0x974007f7, 0xd78ed155, 0x15545ce0,
- 0x02568e49, 0xfb863ceb, 0x7064a848, 0x754f5e0c, 0x997e647e, 0x85e5cf18,
- 0x63599fd6, 0x7eaf9c0e, 0xf7c7cfbe, 0xfc995e02, 0x49dfb1f0, 0xb03f2bb6,
- 0xd2de356e, 0x0ff612ad, 0x01174f43, 0x26b96a7e, 0xe3e82fd6, 0x0ab59bd7,
- 0xeab061f9, 0x55833e71, 0x08dbeb8b, 0x7e72a1f8, 0xcb9d8ea3, 0x5e8cab8d,
- 0xc7d31fe4, 0x9f28911d, 0xfbd0cf36, 0x99a43ca0, 0x87ed0f5f, 0xd7f7d8d2,
- 0x43773469, 0x136add7d, 0x3a7c4569, 0xa044d68d, 0x4bc4589b, 0x6bdead7d,
- 0xfcfcf3a0, 0xeabfc645, 0x012f263d, 0xba9ee83e, 0x8491c610, 0x8053c728,
- 0xfd41f737, 0x7a50e61d, 0x6f63d3b2, 0x6a4fbfa7, 0xe04ce767, 0xa451f281,
- 0x04bf212b, 0xf4f0035c, 0xc08dce2a, 0x0b38a5c7, 0x2cee5be7, 0x33dd7780,
- 0x738fde51, 0x132eb7d9, 0xa2ab4ba0, 0xea91d4de, 0xa818d8fd, 0x00ffc1d7,
- 0x52a76c1d, 0x83ae94ad, 0x765d33af, 0x6efb075f, 0xeb0ffa30, 0x4f4b6a28,
- 0x8eb9e1f6, 0x2b75b744, 0x98fb4cdf, 0xa57743ea, 0x38a581bc, 0xa56cbaaf,
- 0x78e52e3c, 0x9bcbc01f, 0xd41f8cac, 0x79e3b715, 0x19b8fbac, 0x0269b1cf,
- 0x53a667e3, 0xc84d7e4a, 0xb2beb84f, 0xc557c701, 0x29938fb4, 0x257eabdc,
- 0x64495a59, 0x2244b97e, 0x9fa7902e, 0x3b103e6d, 0xe97be00f, 0x8dfb8cb2,
- 0x6c9dfb62, 0xfba8e765, 0xa4700a19, 0x093d66f7, 0x9d6bdfb3, 0x4b8ef88f,
- 0x0e3af780, 0x95edeeeb, 0xf4a13f23, 0xce2679e2, 0xdcf7fc01, 0xf83f29f6,
- 0x7bbbae84, 0x9b9418db, 0xa42ead09, 0x28c4be9f, 0x3f4a56c7, 0x20993209,
- 0x6aafbc51, 0x8a3b103f, 0xb9fcfb8e, 0x8f204561, 0x9e75f117, 0x095e517d,
- 0xebfd5970, 0xf6866e17, 0x0f14af3a, 0x99fbbc7c, 0xf813fd5f, 0x4d6dd2fc,
- 0xd69149a0, 0xf7a77ee7, 0xef1a7ed3, 0x33fbf616, 0xf7e81671, 0xdf0f93f9,
- 0x6d6ef00c, 0xb3f6c56f, 0xfac16e4f, 0xe17ebf6b, 0xf207ffd5, 0x80eb15de,
- 0xdc5f677e, 0x77a9788f, 0xdfb09d6b, 0x71bd7448, 0x27c67ec7, 0x39c3ae41,
- 0x4bfc65a8, 0xdfa0b5d0, 0x773d7fcf, 0xa87cb064, 0x12195d97, 0x38364ff4,
- 0x5e50929e, 0x14389ca0, 0x7451b445, 0xd2d3afff, 0x792acb48, 0xe01d7ef9,
- 0x33f18739, 0x790921aa, 0x7f431bed, 0xcc4c7dbf, 0x2f3bd416, 0xcf0833dd,
- 0x3ba30c4d, 0xcf918f3a, 0x88798463, 0xf33ea096, 0xa875e676, 0xcd2952d7,
- 0xce1249fa, 0x1ba6e873, 0x17b9c2b6, 0x6af985eb, 0x3abda1f2, 0xf889e403,
- 0xe75f1d7d, 0xdf2668ba, 0x537e71ce, 0x075a6157, 0xa3e7b9e5, 0x8d3f016a,
- 0x2b10ff7a, 0xd18f2fc0, 0x265643f1, 0x97dbea87, 0x384d1aeb, 0x9779e71e,
- 0xf32829f2, 0x94fa79e9, 0x6bda579e, 0xf0e1e5db, 0x3e32dfbd, 0x60ca4d19,
- 0x7d66d31f, 0x62fc0120, 0x75759af2, 0x58e7d708, 0x7052c53b, 0x760ae97b,
- 0xfb74d47e, 0xcfc4d5a4, 0x69b73b0f, 0xec33aabb, 0x8e0cb7c8, 0x53fa41c1,
- 0xab7752da, 0xcb7efe99, 0xa643b70a, 0xccf7b774, 0xb4e971b1, 0x695cebfe,
- 0x2cabd238, 0x31ec7931, 0x561a77e1, 0xe88f9256, 0xcfc9dfb9, 0x68859275,
- 0xe00a2c6f, 0xb44b4aa9, 0x1f7f8426, 0x7586b5f2, 0x636f5e5c, 0xbec624eb,
- 0x1c6629cc, 0x16d1ba67, 0x671d0758, 0x2fbd6132, 0x907ccef3, 0x945a9e8f,
- 0xae3d768f, 0x5fe0acf7, 0x3b3053c4, 0xa81fc03f, 0x7a06e6de, 0x7b33d24d,
- 0xb563f805, 0xf2e6f419, 0x4092d623, 0xdacd1499, 0x6d9270d5, 0x3bae9db4,
- 0x7ec4e6df, 0x857899e4, 0x07c48afc, 0x37fe391b, 0x40c5fe4a, 0x513d9e67,
- 0xc6eba016, 0x1443fd9b, 0x53870976, 0x9e9ba70f, 0x0e5e8c3d, 0xd81e3469,
- 0x37ada1df, 0x4295696c, 0xae50f1e5, 0x4875a79f, 0xda4bc016, 0xfe051ae6,
- 0x0ab75ea8, 0x5c86caf4, 0xf7f514a9, 0xbfbfe58e, 0x291bd68e, 0xb8dea0de,
- 0xaa4f9f8b, 0xc6ff42a7, 0xf085ea8e, 0x8984f4bd, 0xfd42590e, 0xad3a5c68,
- 0x1293d637, 0x071bff38, 0xe3a4f738, 0x94f2243e, 0xd529e41d, 0x269e41ab,
- 0xde3ea3e6, 0xfa86dee8, 0x73d5c937, 0xf510b7b9, 0x9994c6f5, 0x215f380e,
- 0x2acf627c, 0xed1af7d4, 0xda288ed1, 0x7487527f, 0x4c77d337, 0x7247ad84,
- 0x77927d42, 0x73d61794, 0x9447c05e, 0xf039aeba, 0x06dd9efd, 0xafeda1e2,
- 0xf28f19ef, 0xf98bd05c, 0x75ca0325, 0x8122d69b, 0xc5ae7e5e, 0x4c1a3e49,
- 0x9cb81fc8, 0xdbacf011, 0x7381a59e, 0xc3b79e72, 0x97127b3f, 0xc36bb487,
- 0x67d21f42, 0x13dbd73d, 0x7bc2ce0c, 0xf427f082, 0x641d3528, 0xd35e18db,
- 0xe0941f36, 0x73f1ab10, 0x6be252cb, 0x65bbeba2, 0xa637c6b3, 0x19abf500,
- 0xe957f7c8, 0x742956c9, 0xc63621be, 0x5de2aa2f, 0xab27c085, 0xc11c99a6,
- 0xda2aa9fc, 0xd20a89a9, 0x157108f3, 0x26763d83, 0xcff08cc9, 0xeac3d9b7,
- 0x79f6a165, 0xb74fda14, 0x480a79b6, 0x155d6d36, 0x92e70b5d, 0xf21363f2,
- 0x0f1d0b4d, 0x51d6fdf6, 0xbefb324f, 0xb14de715, 0x8ef9d859, 0x83371577,
- 0xb5c7203f, 0xb331c982, 0x8e7edc23, 0x3e1e855a, 0x740350a7, 0x00e4d532,
- 0xafe7f2bb, 0x6e91f348, 0xc260543c, 0x38af7179, 0x2bd99136, 0xe23ba00e,
- 0xd5bea2d6, 0x86f2ecd8, 0xc7462ba7, 0x02ff548d, 0x15d29c3d, 0x83b1ade2,
- 0xf7611fc9, 0xd6089f03, 0x12b9c577, 0x35f816e7, 0x37a08dd0, 0xf5af6e71,
- 0xf3f0f67c, 0x1ff743d1, 0xbde69f4c, 0xafd72e8c, 0xfb4397b2, 0x09622afa,
- 0x76d557b6, 0x1f0e1d90, 0x8c9fdbad, 0x823cc2f1, 0xbab06dcf, 0xbd60da66,
- 0xab58df5b, 0xd4be0125, 0x21a1f7b8, 0x8ccfd257, 0xd19f365a, 0xa60de31b,
- 0xb705231f, 0x0f4b08b9, 0x9598e7f0, 0xf723fde1, 0xcf4c4cda, 0x65fab6fb,
- 0x7c05a49e, 0x5f32fd09, 0xe36bdf76, 0x08a525fa, 0xe992b992, 0xebc04997,
- 0x8d6c1f81, 0x113f02f1, 0x7af5267e, 0x099cfcdc, 0x233b0abc, 0x7ff59629,
- 0x359b9f98, 0xbc63dfbc, 0xf05fb20c, 0xee35d83c, 0x591c880f, 0xdf71880e,
- 0x7c4bdf95, 0x3523c847, 0x41fac0fd, 0xaa7ec16e, 0x6bf722f3, 0x38edcfdb,
- 0xe1ef3d15, 0xe016abe7, 0xbc627a08, 0xe700effb, 0x19c47159, 0xeb3ff14f,
- 0x27a40677, 0x0437db92, 0x2d3ad0ec, 0x806c18f1, 0x1fd79d57, 0x78a6b784,
- 0x6cd7be36, 0x1cf4c8f4, 0x6f778a5c, 0x153c7987, 0x3d03e1c4, 0x5f9487f6,
- 0xbe24b9c0, 0x4d27e012, 0x700b1fc4, 0xdbbac5b4, 0xaee53e91, 0x3b53a84c,
- 0xf3be00a6, 0x9fb30c48, 0xbd90defa, 0x2e3c2943, 0x3efffd18, 0xc2e7ae8a,
- 0x87871c8a, 0xef7a73ce, 0x99ff779f, 0xfbbf3ef6, 0x7ec101b3, 0xeca346ac,
- 0xea07c6d2, 0x6da9123d, 0xbb77c30f, 0x986fcc6c, 0xbbf08375, 0xbadea1f5,
- 0x0c99ca22, 0xfb159f7e, 0xa4af93ca, 0xac5d37cf, 0x3f20de24, 0x0f1d135c,
- 0x8e2e9ae3, 0xe643dfc3, 0x7c81f3a5, 0x4e98ba68, 0x77d9c33c, 0x30fc6f80,
- 0xc0dbf19e, 0x3f6c4cf8, 0xf3fa51ad, 0x3c45e5fa, 0x422ed7c3, 0x1f6b8426,
- 0xb5f6cf1a, 0xdf9d9b2b, 0x17924dbe, 0x2bc583ec, 0x82993ecc, 0x19fd3174,
- 0x16c5a5f4, 0x0b134f8f, 0xb1f287fc, 0xa9c68861, 0xcc8f6a46, 0xf68cf2e3,
- 0x7a068ed3, 0x1cf058f5, 0x9c39f9ba, 0xd7faf1d7, 0xac589fe0, 0x74d1c625,
- 0xc746f99e, 0xfbfa74e1, 0xb1b1a627, 0xde162620, 0xe409253b, 0x66acf258,
- 0x32122ff4, 0xa9fa02d6, 0x97cb4644, 0x0fa4ae63, 0x458f5169, 0xf074a27a,
- 0x2faef16f, 0x1d021d04, 0xf187bacc, 0x49ffd135, 0x17f3869b, 0x1fbe1d25,
- 0xc6efdf01, 0xe80afc57, 0xd738c1ec, 0x7bde703f, 0x5ff82bce, 0xfa7fe48f,
- 0xe5d3a071, 0x2453c766, 0xc389bc74, 0x4bb0b7bd, 0xdef1fe0f, 0x44c8ffe5,
- 0xf5f3b47d, 0x1ba7c093, 0x0c9f268c, 0x5d2ec57a, 0x03ec5fb7, 0x339c62e4,
- 0xf38e9e3a, 0xfada383c, 0x9209a529, 0xfdc77f4c, 0xde144ed2, 0xbc191b77,
- 0x5b778ddf, 0xee9113e3, 0x757d82e7, 0xb38f68c1, 0xfbe8bd01, 0x2632e3f1,
- 0x3243f005, 0x74bc4acc, 0x997881be, 0x01ea746f, 0x2e9c0bfe, 0x38ace75c,
- 0x8145895f, 0xf2f93c87, 0x078ed70d, 0xd3eb9f99, 0x730e5fe0, 0xb872861e,
- 0xd1fa10fc, 0xa31a74f2, 0x6499d3db, 0xaf284ee9, 0x771d25a7, 0x8bd79b3a,
- 0xef087d78, 0x37eac497, 0x5d3dba72, 0xbfa9fac0, 0xceff2773, 0x62cef1bb,
- 0xe71d1380, 0x5ebe03d3, 0xbe82f28d, 0x8dd6f94c, 0x7c5e8cf1, 0x55be60d6,
- 0xf80437dc, 0xc5096f61, 0xfacfdd1b, 0x13ccbef2, 0x19f657c0, 0x57ed5b2c,
- 0xbe64dfc7, 0xc72d6fae, 0x958e541c, 0xe4d8e42a, 0x10c72678, 0x7a25744f,
- 0x420d5fa6, 0xc87d20fc, 0x1b9f8ed7, 0xe9dc19a2, 0x478da979, 0x77cbe579,
- 0x86f7f105, 0x044e7678, 0xad1d393f, 0x38dfe3c4, 0xfbc79c1f, 0x6616f1c9,
- 0x32fa39ef, 0xb6d39e61, 0xbbff78f0, 0x8b1f1fad, 0x1967be81, 0x53c4e6fa,
- 0xea93bb7a, 0xc422fa0d, 0x09eb0c87, 0x7cf34fb1, 0xdcf3857f, 0x8099b774,
- 0xef866bfc, 0x589e2225, 0x7d97297c, 0x3d4f7297, 0x1f86afd4, 0x52a7d5f0,
- 0xf4c9243e, 0x563c3643, 0x1aa71676, 0x16f3c16d, 0xee4fcfd5, 0xfa8f860f,
- 0xbe38a7bb, 0xda4bc6d6, 0x0e8f014f, 0x737180e2, 0x3cc2f9de, 0x79c9d29b,
- 0xa1a3d18b, 0xbb2dcd72, 0xbb7ec3d7, 0xea06f07f, 0xbef4a7bd, 0x30a66d21,
- 0x13df7aed, 0xf681488f, 0x3d91bfb9, 0x778e7a7a, 0x62ff7575, 0xbbbfdd1a,
- 0x39c0764b, 0xd7ffdf76, 0x7f4023a3, 0xc039d2e9, 0x75f2a0ac, 0xd1f61683,
- 0x53b4f4cc, 0xcffc251a, 0x47694f7d, 0x46f1c33c, 0x33a40af5, 0xf14e0fc1,
- 0x6212e5b8, 0x159fba41, 0xea15bb1d, 0x6e4be5fe, 0x7ce63885, 0xa4ec38e2,
- 0xeeecfff0, 0x5e77e889, 0x2fc89c44, 0x1f7479e6, 0x05d3f306, 0x45f594eb,
- 0xfd3aca6d, 0x92efd222, 0x73bfd547, 0xf865707f, 0x78d1daf8, 0xd39d27a6,
- 0xcfdf6f87, 0x7cbdbfdb, 0x837881be, 0x7c8080f4, 0xd5dfc02d, 0x39021ef3,
- 0xd390125c, 0x5d373e42, 0x8f308a8c, 0xb73f7f09, 0xdffafc38, 0xe9a37ce6,
- 0x79e515a2, 0xfc04f8e8, 0xd8666a9d, 0xe9b5e04f, 0xc4f12a62, 0x3f42ea07,
- 0xc0cb8c0c, 0x2c002a76, 0xf804c69f, 0x0b03f080, 0x2240fe3a, 0xdfb454c6,
- 0xac7ae61e, 0x52fc00a5, 0xa7bc801f, 0x278f76f8, 0x12e9faaf, 0x3a97dde7,
- 0xa01d9b44, 0x283ef573, 0x07f59c3d, 0xe24fb9f1, 0xae7809cd, 0xf0619186,
- 0x73a7415d, 0x0715507e, 0xf72ffef2, 0xeb072657, 0x0e7efd63, 0xa897b33d,
- 0x2dc85524, 0xf36b92a2, 0x2b1ca83a, 0x0862bd40, 0xf68f8d30, 0xb93e474d,
- 0x80923890, 0x19f77b8e, 0xf81fd132, 0x5899e52d, 0x3ccf14cf, 0x1337d31d,
- 0xf0d70e50, 0x64e94fef, 0xe8c68dfa, 0xe2fea1d4, 0x124b7624, 0xee4c989a,
- 0xa5a2a152, 0x1d449bf5, 0x47d68788, 0x3048cdf3, 0x26ffae9e, 0xeef9925e,
- 0x06573814, 0xec0caef8, 0x65029bc8, 0x1d8748eb, 0x4b9231ca, 0xf0c1d6cb,
- 0x67348e3c, 0xd18d7f40, 0x89fd332f, 0xc60920ae, 0xbab1ef8b, 0x4cd7d799,
- 0x116730bd, 0xe3326efc, 0x75f3d7f9, 0x7ca0490c, 0x246df60c, 0xc1b7d846,
- 0xe31cfbe4, 0x54f4bc4b, 0xf52ed1d8, 0x03f41364, 0x02769344, 0xce9935df,
- 0x16b3607b, 0x1ea09162, 0xbbe0b965, 0x337f008f, 0x90c33479, 0x009f5dbf,
- 0xade96f7e, 0x28ffc0c5, 0xf3802d3f, 0xeb5db11f, 0xf05e7d43, 0x5f5f1b27,
- 0xa94fe72b, 0xfec24054, 0x7e9fce65, 0xfc8c5e6a, 0xf6b88129, 0x14da7f03,
- 0x53f9013b, 0x7ae37132, 0x156827e2, 0xa5d1267c, 0x6ad727ac, 0x23c87c55,
- 0xdd52fac1, 0xe48ddfca, 0xc907ca14, 0x1cb94ae7, 0x2e4a768f, 0x157423f8,
- 0x44f51cec, 0xb4fd78b1, 0x9aceb668, 0xbff31b04, 0xfdb8b145, 0x2101f4d5,
- 0x017ad5ff, 0xb5da5629, 0x413d368d, 0xb512553f, 0x7ea187a8, 0xf4c09350,
- 0xd03df783, 0x5f21f72e, 0x0bfdc13e, 0xaab82753, 0x77df14b4, 0x4ea391e6,
- 0x724b2e5a, 0xba5026d7, 0xb9a47e99, 0x6bd69ea1, 0x3ef922df, 0xb18e165a,
- 0xf8a76dd4, 0xecdb3b5d, 0x6beb4d58, 0x3dd48ccd, 0x97d40689, 0xda69c808,
- 0x829345be, 0xf02691fe, 0xb47e52c7, 0x4011e216, 0xda098317, 0x593f54d3,
- 0xb6e3a46b, 0xd658b7ac, 0xd58fc1db, 0x85fc0e37, 0x65888b7d, 0x3e73092b,
- 0x4773d12e, 0xd424fcf1, 0x4e255e29, 0x6df7e26f, 0xab0e7bf0, 0x3b05298f,
- 0xe9cbfd90, 0xfc0b0ca4, 0x4f2cb937, 0x5cb3a9a0, 0x39eb4897, 0x4fe81d63,
- 0x8c4f9c26, 0xe7e1df10, 0x5ce05470, 0xaf217b60, 0xb87cea0f, 0xcbe6092a,
- 0xaeee0e23, 0x58239c0b, 0x50fe85ac, 0xe0f1ccca, 0x09237c73, 0x2af983fc,
- 0xde23f303, 0x43b6f2c6, 0x76bc59b3, 0x1fb7d684, 0x5e28f9ce, 0xd332f216,
- 0x43be5525, 0xe8c8bfe9, 0x0edbb038, 0xb0c97520, 0x43cb52ef, 0x91fdf0ad,
- 0x81e277ae, 0x52368daf, 0xd6cb40fe, 0x92c38732, 0x80d6fb83, 0x2747a9ff,
- 0x0e3393e4, 0x11606b73, 0x9cd5fbf4, 0x96d6a696, 0xfb0c5edf, 0xec0992eb,
- 0x5c1ca22f, 0xc1359329, 0x8be787f2, 0x09fbfa88, 0x207fbfcc, 0x21379c61,
- 0x74f82e28, 0x7283d702, 0x8ff02e49, 0x2cfdf3a0, 0xf9775bd0, 0xbfce919b,
- 0xff9f9db2, 0x75c39c3b, 0x3e72efa8, 0x8badf820, 0x274cc5e7, 0xa7c01d4e,
- 0x01f28a2b, 0xbe563f5a, 0x34c0f90c, 0xdfdfc6e2, 0xa6f060ab, 0x7cc1d788,
- 0xf5282653, 0xca5c3b8d, 0xb55ab4fa, 0x9ebf423e, 0x74eef814, 0x46bdb2b7,
- 0x941397e8, 0xeface5fa, 0x9ca2b25f, 0xe1ba7e4d, 0x97f040f2, 0x8225d54f,
- 0xe793b0df, 0x184a74bb, 0xf9e26a1f, 0x921d4d2e, 0xa9a5df22, 0x8903de73,
- 0x8d2ef941, 0x77cb571d, 0x09c8fa61, 0xf83f779d, 0xa32c4fd5, 0x39dfa63b,
- 0x0e22f3c0, 0x51445e42, 0x73ccfe80, 0x52909f98, 0x33d1fa33, 0xd00e312c,
- 0x8a69d7ab, 0x2eb8afd0, 0xfff0acd6, 0xace55fae, 0x9fc27e82, 0xa65cf228,
- 0x3b734819, 0x641d53f3, 0x8fcc5cf9, 0xb4f6e5e4, 0x7e124137, 0xc7e835e1,
- 0xc4df9d52, 0x24f28278, 0xfa2e6671, 0x0b3b6b0b, 0x4b5fc18b, 0xb1fa12e5,
- 0x1c7609bd, 0x442eeb5f, 0xa62dd73f, 0x683f18e9, 0x5da2dcea, 0xcfd00a68,
- 0xc5dd055f, 0xbba01890, 0x4ed1ff7e, 0xdc8ffa03, 0xa06bebb2, 0xafbd7aaf,
- 0x12e92880, 0x77248f7f, 0xebbc7096, 0x17d35c2a, 0x1ef4b851, 0xfec03bd5,
- 0xe2058aa3, 0x563dc5eb, 0x1ada83e4, 0x4d7efc82, 0xd97e4139, 0x4ff985bb,
- 0xbd2eb33e, 0x9afef815, 0xaa72826a, 0xe10e36c7, 0x0f788cbf, 0xa5b8e93b,
- 0x053d299b, 0xb6bbfff1, 0xa4f5eb29, 0xfd78f91d, 0x44ba10f6, 0x56f824be,
- 0x3acbb103, 0x52ec6b88, 0x9883278e, 0x7870777c, 0x3abe7217, 0xadb18efc,
- 0xae1f6f10, 0x2c85fc61, 0xa0d7a474, 0xf2cb34fd, 0xbab01469, 0xe92ba5a7,
- 0x33e6bd47, 0x8cc73b32, 0xf9f0967f, 0x84bd7cd5, 0x6b3745eb, 0x1450a1a9,
- 0x7f6873d0, 0x74d41fac, 0xc09a29ca, 0x38f98b3a, 0xbe095fa1, 0x5e55f02a,
- 0xa5194846, 0x39139bb3, 0x3649b3be, 0x8fce9be0, 0x46412e74, 0xf7e70d8b,
- 0x8a343d80, 0x83d28f7f, 0xa3cae807, 0x7e817a31, 0x28cd4ad7, 0x47a08c4f,
- 0xe4bd72d3, 0xf2fafe46, 0xf40c8f52, 0x4f349231, 0xf80b35b9, 0xf00c576c,
- 0x15274a1f, 0xfa018989, 0xccbe2569, 0x8e82921d, 0xfadbbdb0, 0x123a5866,
- 0x1ef7dffc, 0x11260bd3, 0xefd1bfaa, 0xf4c4ff3a, 0x12d28397, 0xc7aa13a4,
- 0xe5fd041d, 0xafb30d4d, 0x406dd226, 0x128b2abf, 0x9453e3ff, 0x10f689f5,
- 0x013cc0fa, 0xbd3c3f67, 0xa4cf585a, 0xa73f655c, 0xc9445fe0, 0x25c8b2bf,
- 0x743f0766, 0xbfb05ef8, 0x5c925663, 0x8d520788, 0x4c3831cf, 0xf13ea5bc,
- 0xd7dbf73b, 0xdbf18627, 0x3db8eaf7, 0xc6b3a2a0, 0x6ce767c3, 0x147a0120,
- 0xd246e2e7, 0xf850a72c, 0xf163bf49, 0x0e811b91, 0x19945d29, 0x3be81e49,
- 0xc3f998a4, 0x7410f9c4, 0x1b6bca57, 0x240d9d04, 0x6ece8103, 0x7f4288ea,
- 0x6f408de8, 0xf90b7e94, 0x0b9e42bc, 0x2cb5bdbd, 0xa4b2be84, 0x39eb941c,
- 0xae424f40, 0x8f1c970f, 0x7a0597df, 0xf6f507bb, 0x436a7a20, 0x3d28927a,
- 0x4427bfa1, 0x55db2a5e, 0x7ef026f4, 0xe5a3eb9c, 0x85ed19a4, 0x4e4cd1a9,
- 0x3d99aafa, 0xd224d94f, 0x8c35ebdb, 0x1388aade, 0x289cade9, 0xa8d2a4e9,
- 0x91e9abac, 0xa4a3517e, 0x9bd23737, 0xd1234e9a, 0x37a040db, 0xafe32f21,
- 0x137b6f4e, 0xff33ff4d, 0xedbd285a, 0x76b92c4d, 0x6c7c137a, 0xd2a59447,
- 0xa97c7204, 0xf8617284, 0x50ad41d1, 0x8590da1f, 0xab0ee7fa, 0x37b600e3,
- 0x2ee2f6b3, 0x0ef90ca7, 0x7b782b39, 0xea12ab96, 0x3b692b4d, 0x38e4ba9d,
- 0x741887cb, 0x5c2f6b3f, 0x0cc07cdd, 0x1b0f2f7e, 0xb5f3f7bf, 0xf76d2c72,
- 0xcbe3e5ae, 0xdea12adb, 0xff8d8eb4, 0xc328e20c, 0xdbca8f20, 0xb75fbf0a,
- 0xccc1cb21, 0x8ef7a657, 0x21ddfbe1, 0xe3803ced, 0x25b8d8da, 0x04d18d87,
- 0xcfa66ced, 0x39f7ccde, 0x67db3366, 0x4cb747c2, 0xa7bf83b0, 0xd8fa83cf,
- 0x52fa9aa7, 0xec1173e4, 0x2da972d4, 0xc0f1ca03, 0xbbc064bf, 0xcd9c9d63,
- 0xe95b68e2, 0x644abe27, 0x7f110e7e, 0x75773882, 0x55f37e90, 0x8a13f322,
- 0x8236497e, 0xcc7912fa, 0x8888768c, 0x211ef98f, 0xd84f9c12, 0x148b8c23,
- 0xd39f1b2f, 0xf8c3fa8c, 0xe64e2281, 0xdfa7ced7, 0xc5fcbc2d, 0x987e70b8,
- 0xbd32247f, 0xdb8f0ce5, 0x7a97df8b, 0x077f3c59, 0xc01a4910, 0xd626f755,
- 0x2b0844ad, 0xbc03290f, 0x46cc7ab2, 0xa8ebc7e9, 0xd344bf91, 0x7080f5ac,
- 0xff3094cb, 0xf1177268, 0xae86c5c5, 0xf896bc7f, 0x087f2cf4, 0x55b8bfd7,
- 0x8443f98f, 0x383bb5f3, 0xc1e8c8fe, 0x72a7ce78, 0x7124a53c, 0x19387dbb,
- 0x0eea7c0e, 0x8d3bb78e, 0xa7263acd, 0xfe2a74db, 0x7a049191, 0xfa88a6cf,
- 0xc55db2b8, 0xeff2965f, 0xf87ae62e, 0xfe87d232, 0x1eb94fc2, 0xd313667e,
- 0xed22efc3, 0x7dec2fe8, 0x0d9de98c, 0x2f407b74, 0xbe4abccb, 0xb28cf750,
- 0xacaed0de, 0x0eb15237, 0xa87537f3, 0xf31e4ef8, 0x6a6ef6c3, 0xdbff0528,
- 0xa28f47d2, 0xe0a977df, 0x9f255e33, 0xc67ee421, 0x1eb91e67, 0x7b6a3ffd,
- 0xd4e9d85d, 0x0929be3e, 0x999690e3, 0xcc37a0f5, 0x0f796189, 0xf91f29b2,
- 0xf688d982, 0xa0be2472, 0x5e8483b6, 0x7f0fae42, 0x3204a85e, 0xe0823ec2,
- 0x5fef82ef, 0xb6525ec1, 0xec23f0ab, 0x3f1c1995, 0xe1fe2853, 0x76127f3b,
- 0x9f8632d2, 0x0875c4a9, 0x5ddef3f0, 0x6ec23f0c, 0x9276e6fa, 0x93b60e53,
- 0xad75bd84, 0xefda92f6, 0xcf5bce2e, 0xdacf6100, 0x026d9ed1, 0xddfe5340,
- 0x13c4f7b0, 0xefd02455, 0x68710b58, 0x72f54175, 0x66b57fa5, 0xc852e9d2,
- 0xae88cc9f, 0x46e017b8, 0xffd1133a, 0xec2c90d8, 0x34ff3627, 0xe175cf9e,
- 0xdb38accb, 0x29c4fc95, 0x836b86f3, 0x6d5ee3ec, 0x43d82c5f, 0xfc2497bd,
- 0x61add42e, 0xf18151e2, 0xe87c710b, 0xf7bebbf7, 0x4f73e067, 0xf13c60c4,
- 0x2ecc97c2, 0x2879b0bc, 0xe39f15e6, 0x87015771, 0x799f8725, 0x70e70fd5,
- 0x10e182e5, 0xbc93aebf, 0x6da6ed5f, 0x9fee8c23, 0xd3adf9c3, 0xbe8cf4f8,
- 0xec445c58, 0xd3dfb23b, 0xff4f7c83, 0x7dbf931a, 0x89e63452, 0x0487dfd2,
- 0x273687c7, 0xf081f8b3, 0xf93909c7, 0xe56f5e47, 0xa35a9ef7, 0x3f98fec4,
- 0xf3bc52e2, 0x1fff8029, 0x57e0fd61, 0xfc87477a, 0x10e6fc1c, 0x9952a4b7,
- 0xd742dba4, 0x6df9f105, 0xdf9f10d7, 0xc5e4c499, 0xb08b4a39, 0xe73645be,
- 0x33bdf08b, 0x86790e3c, 0xc4ceb1c7, 0xbed6b8b2, 0x7cacfefe, 0x2267979b,
- 0xbf45d1c4, 0xae8c5b8f, 0x3ede9435, 0x35ae216c, 0x1fd83e54, 0xde633431,
- 0xafb62ccf, 0xcc563dde, 0xfee31513, 0x0e7e5494, 0xd5acf1d6, 0x85ca1875,
- 0x347bca6d, 0xd41fb0bd, 0x7abed837, 0xbe2958a3, 0xeaa4a7f7, 0xdecf8073,
- 0x67c47ee9, 0xa8a47d7f, 0xdefe70bb, 0x5fc8fc9b, 0x345bf709, 0x2918f3f0,
- 0xf8b5760e, 0x3c8e3a97, 0x1e6f9c5b, 0xa6c59e47, 0x1c79b322, 0xac918e79,
- 0x73eda74d, 0xffd1933b, 0x33d634be, 0xf6471144, 0x78a37cc4, 0xdec7a0be,
- 0xec388101, 0x0e20df63, 0x3be9397b, 0x4e5ec38f, 0x5587130a, 0x025fe9c7,
- 0xc01741bd, 0x0616ddc3, 0xbeb92ab7, 0x17a0fc12, 0x8fcc1216, 0x8fd9242e,
- 0xec3d068c, 0x91788e88, 0xfa3d326f, 0x744b786a, 0xe15d8869, 0xf6268ebf,
- 0xbaa4fda0, 0x6a3a8a6d, 0x877941e6, 0x14d34be9, 0x673407e3, 0x5c0ffa2b,
- 0x3da2bd79, 0xa8a453cb, 0x51bbace7, 0x5b707fd1, 0xf43ea285, 0xfd145bd1,
- 0x28d6f3af, 0x7fe017ea, 0xc8c9af90, 0x66786ed7, 0x92fc6286, 0xf52c5e37,
- 0x7cb9b6c1, 0x8b72e56e, 0x795d9c78, 0x02fdcca5, 0x9f6fc8fb, 0xf89798af,
- 0x0a549f24, 0xeff64971, 0x87bb2c5c, 0xc58bb0b1, 0xdc758607, 0x684ef8a5,
- 0xa32ed25c, 0x9121d5de, 0xf8d0a4c7, 0x87ced2e4, 0x8ade42d7, 0xffa17f5a,
- 0xa0c5b572, 0x3e6344ef, 0xa99f5aa4, 0xa027364a, 0xd24691de, 0xe9ab5d18,
- 0x0f0fd4c2, 0x4851f7b8, 0xba323c86, 0x0a174158, 0xa1f851fc, 0x76c2eb7f,
- 0x2d35e633, 0xd2016379, 0x494521a3, 0x25765117, 0x2ae4c45d, 0x50ecc2e9,
- 0x995c41d2, 0xf0d40e92, 0x74953ab6, 0xbff4fc41, 0x7e3bc02b, 0xd46e9282,
- 0x7d222ef0, 0xd80f3187, 0xdf00392b, 0xeb2f786a, 0xbafb82d8, 0x3cb8be9a,
- 0x3917c799, 0x741f877c, 0x6e109ab6, 0xf8493f2c, 0xeedc0c03, 0xbf4a0926,
- 0x56abd098, 0x8dbd7325, 0xf2fc23cf, 0xda0f256b, 0xb871fdf1, 0x2fa65f32,
- 0x66f9ec0b, 0xae43fcc2, 0xc3139207, 0xf7f117fa, 0x0145fe48, 0xff5ca9d7,
- 0xff2c23ac, 0xf31478e6, 0xbd5c7d0b, 0x8b42fd0c, 0xd1ea3349, 0x73c66ae7,
- 0xfb07a1ff, 0x0219e1a9, 0x529d353f, 0xf904957d, 0x1aa2ef5f, 0x142726b2,
- 0xe4a7529e, 0x533dc333, 0x81e429d2, 0x5013dd9b, 0x84e857fa, 0x12bf3052,
- 0x5f98b0fa, 0x31f04fc0, 0xfc01af31, 0x540e7032, 0x2ae48d7c, 0xc7f6a2f1,
- 0x963031c0, 0xec5bc706, 0xa33e3824, 0xfc04c3f6, 0x84fed42f, 0xacc0e178,
- 0x3a07b856, 0x3f44e2dc, 0x9ae9095f, 0xff0bbf09, 0xae21fa0b, 0x887efd23,
- 0x2aea7288, 0x1e29ddf1, 0x5678ffc9, 0xc4575c68, 0x3e182989, 0x3c1d33fa,
- 0x800fb25a, 0x1decd475, 0x1474089a, 0x9c7497ea, 0x23ce857c, 0xa1e2fa6b,
- 0x2824155f, 0x5f7dc507, 0x9fb8fc97, 0x81f3893b, 0x8dddfbe0, 0x4cdc7da4,
- 0xf95307f4, 0xf3250b18, 0xb50e915b, 0x7f45adde, 0x04ee86b1, 0x048ebde8,
- 0x02b33bc5, 0x439758ed, 0x479ad7eb, 0xc2c53933, 0x3e5809f3, 0x4ffce128,
- 0xed9191d8, 0x16fae535, 0x49661698, 0xc105f7f4, 0x7586b8eb, 0xb8097c8a,
- 0x90710a27, 0xd7042981, 0xc76c95d3, 0x4fa21bdf, 0x6e84ebbd, 0xc1995dc5,
- 0x9e936e7a, 0xb760361a, 0x716064bf, 0xfea576cd, 0xf4c29d1c, 0xe070c8e0,
- 0xbb2a59f9, 0x8f7a6ae6, 0x4aeacfc8, 0xf7d628b6, 0x362b9c60, 0xc06f7e85,
- 0x92a7ff49, 0x4abe3026, 0xc43cc6ee, 0xde321d0b, 0x89bc6aa7, 0x3dc687f1,
- 0x9ea11e32, 0x17de034e, 0x0071da5e, 0x16eea5f5, 0x7ea880ca, 0x7e85b672,
- 0xe015f079, 0x246fdaaf, 0x31e4417b, 0x7ee1490d, 0x10520288, 0xf105079c,
- 0xf1b094fd, 0x27fcfeff, 0x93e73b65, 0x1c5e7255, 0xcfeda3dc, 0x65f6d16b,
- 0x47e104d6, 0xb8af8fbd, 0x73aa525d, 0x70a14f0d, 0x632ba0fb, 0x2557cc23,
- 0x034e1e77, 0x1c90acf8, 0x631b7f10, 0x0d1bf760, 0x734772f2, 0xf4379d90,
- 0x7105d95e, 0xee2bd3ce, 0x69fdc1b1, 0x4950ef31, 0xa8f0f783, 0x0ffef185,
- 0x36ee218b, 0xd69eb1cb, 0x9d981b66, 0x18bdf599, 0x5f3d0e5f, 0xfbb3d3bf,
- 0x66ecba5f, 0x67d057bc, 0x976fd195, 0x40b19320, 0xe2bd6217, 0x1df8a2de,
- 0xfe4353ee, 0x4c7df8a6, 0xbbf0df6b, 0xb14a6969, 0x187bde2b, 0xbc37d953,
- 0xbb8014d9, 0x4c6ad7c8, 0xfd05afd4, 0xeac8c7a8, 0x7a8b99c4, 0x3b230ae4,
- 0x3db8a75f, 0xb0b06a76, 0xe0e67da7, 0x28c6a83c, 0x93e61c67, 0xb01323bd,
- 0x38b4bf3b, 0x5fb8ace3, 0xc2c79b0b, 0xf9e1e9e6, 0xabde2bc3, 0xb12d7b40,
- 0x531e7c35, 0xbbd30a43, 0x8aca2feb, 0xad7aa63c, 0xea91f30f, 0xbf15ea2f,
- 0xe2e1487f, 0xf3ea0431, 0x071a0ccf, 0x1c405beb, 0x82ffa16b, 0x13c43175,
- 0x3c8897a4, 0x7c3d3566, 0x68dff1cd, 0x30ed12d5, 0xbaec0fbc, 0xfe57bf52,
- 0x5fbd8729, 0x468a48f3, 0x1e61a1e4, 0x3037b531, 0xf7eea79e, 0x7cea29ef,
- 0xe7de3f33, 0xdb37cfec, 0x77c57e53, 0x962f1a19, 0x1bc1f22b, 0xd71878e9,
- 0x2aac7178, 0x4bcf9c1f, 0x029bb3e7, 0xe0916679, 0x5b3275ff, 0x91e42357,
- 0xceff07c5, 0x9df029e8, 0xe6179e04, 0xf8f3858f, 0xf78c876c, 0xa23d9f9d,
- 0xcc35b099, 0x5c393bba, 0xe2d44fae, 0x47c1b939, 0x7cc25b9c, 0xf713f45f,
- 0x3c7dc419, 0x5576faf5, 0xfac0e7f8, 0x7e658c47, 0x2f3cf561, 0x758af870,
- 0x7c31b2ef, 0xf14abe34, 0x2c28f981, 0xcd97774f, 0x83f918bf, 0x4fe78945,
- 0x763ad992, 0xc4cfe2dd, 0xcc899cfc, 0x0f448eae, 0x7fdd58f7, 0x9a6e3d45,
- 0x48d57209, 0xb259b6a9, 0xabb79d04, 0xee0043d1, 0xa1af02b2, 0xbb63d770,
- 0x63f3f798, 0x7e7edcec, 0x61539d8c, 0xa8fe7c0f, 0xf401f98c, 0xa0a49b40,
- 0x09cffb3c, 0xde7c0b8b, 0x3ffea126, 0x4ac84ddf, 0x6de677ca, 0xe2fa63ab,
- 0x7531c353, 0x9fbf7e07, 0x547997f2, 0xcb4cddde, 0xf1546bf9, 0x08576e61,
- 0x8370bc39, 0x1b21deca, 0x3cc64bfe, 0x279466cf, 0x1cae7f8b, 0xa4db74bf,
- 0xea7be0cf, 0x4afa3638, 0x71fcfda9, 0x4bcbd70a, 0x83c82949, 0x42fa9fbb,
- 0x7c8f6b1f, 0x7e50ce1e, 0xf030683b, 0xdd96235d, 0x2f2c162d, 0x41bb38a6,
- 0xdd53e83e, 0x7bd7c0bd, 0xbaf061df, 0xc9817f50, 0x39bcb80b, 0x84b9f812,
- 0x9330cef2, 0x841f79c5, 0x2e14ec7b, 0xfb930306, 0x35fddc72, 0x5e957193,
- 0x7e118ba4, 0xca2b1ccb, 0xd00a4723, 0xe373c27f, 0x13fc0027, 0xc2718b9f,
- 0x7b97d6be, 0xc37f069f, 0xe8d155fa, 0x581a35ff, 0x7b67399c, 0xc0ec06b9,
- 0xfb4976eb, 0xd4d1dfc1, 0xde172ab9, 0xa3d93017, 0xae213f31, 0x93165e73,
- 0x093bec73, 0x801daead, 0x57b804cf, 0x3eb5d747, 0xf8c29bcb, 0x1a83d338,
- 0x257bcc39, 0x3dc07ffb, 0x321bcf6b, 0xa0bc83de, 0xd7fcf965, 0x915f8613,
- 0x0edf050f, 0x29baf7d6, 0x40d0c8dc, 0xc976fafd, 0x77c58ba7, 0x515e3024,
- 0x3497dabf, 0x6fd1e413, 0xe9ef18b4, 0x52efd75f, 0x23ae202b, 0xc94cd0e4,
- 0x5c47fcc2, 0xc44e9d9f, 0xaa17163f, 0x9d3274e5, 0x6333b1eb, 0x13e77c18,
- 0x9b8c2647, 0x1ab12461, 0x5666947a, 0xfee097b6, 0xd05674ea, 0x237c4407,
- 0xde111eb2, 0xb4f8d3ef, 0x94c7dd99, 0x24c086fa, 0x72a7c167, 0x3a37f385,
- 0xc69dc995, 0x4b8fcc21, 0xc4271106, 0x1d5f1ad3, 0x72ec05ba, 0xdb8b3443,
- 0x8464be52, 0x810e56f7, 0x5efba6bc, 0x7b144af6, 0xc7dc433f, 0xe10b38b6,
- 0x4d53637e, 0xb7de1146, 0xef87d93a, 0xfce8f420, 0x297e7899, 0x4ca891bf,
- 0xb6d373bc, 0xce94b55b, 0x3ea8d31b, 0x366beb46, 0x0b55bced, 0xfdb2e4f7,
- 0xfeb4358b, 0x58b7a6fc, 0x4ffef5fb, 0xa6f2fea1, 0xc8bdac13, 0xf5a658bf,
- 0x613e9b63, 0xa4d060ed, 0x4d97f211, 0xe87ab7dd, 0x5cad67fc, 0xf1f871df,
- 0xdee36a1e, 0x7f609aa1, 0x8ca99be2, 0x628d9d5f, 0x9166cefd, 0xef0035b9,
- 0x5ffdf0dc, 0x24f0d548, 0xc52c368d, 0x9278c57e, 0x22dc7e12, 0xbf196e3e,
- 0x86263a87, 0xf1628bac, 0xc52c4f29, 0xa1cec1c3, 0x989b5f18, 0xf370e36a,
- 0x62253be3, 0x314f011e, 0x5deef89f, 0xbe599720, 0x9e706d5a, 0x7f1cddfa,
- 0xf06b3bf4, 0xec9c833b, 0x464d66fe, 0xe28fe021, 0xa6f1cb4d, 0x7b89bc05,
- 0xb5af30df, 0x70fff900, 0xbc1f5bf0, 0x0567fb44, 0x93a6add6, 0xa7c65496,
- 0xb8b2b597, 0x07359f62, 0x0c4c69e9, 0x58a2f77f, 0x1c638fb9, 0x5aa66f0e,
- 0x01073df9, 0xbf0964af, 0x98e1cad3, 0x93521fe1, 0xfdf7cdff, 0x77cf5f30,
- 0x7c20efbd, 0x8afde139, 0x6dd71d83, 0xb1b1fb65, 0xcf4a54bc, 0x1ef3d436,
- 0x7677cc56, 0x197c6a95, 0x5fb0903d, 0x7f8e0e5b, 0x2077bf90, 0x7182f3de,
- 0x3f4c0559, 0xdc55bd05, 0x9b9e27d3, 0xb4ffb049, 0x3b7e3eff, 0xd81b37bb,
- 0x7cc5ade7, 0x4fbe169f, 0x57a7db0b, 0x78e4af41, 0x7354e65f, 0xc3f71d28,
- 0xbcbe7fbf, 0xe29f3e22, 0x0f9b879c, 0xbc2475ce, 0xf1aefc1c, 0x82a9d622,
- 0x559c3f67, 0x84f013eb, 0xf2e38df3, 0xd6297494, 0xf3a472f9, 0xbf2df59d,
- 0x35c6ce57, 0xf7e580fc, 0xae92bb12, 0x6965761b, 0xc62e7e20, 0x2ecf03e5,
- 0x3ebdf809, 0x6076e54b, 0x9088c906, 0x352e778f, 0x7f0cbfbc, 0xbd81db57,
- 0xacef9656, 0x26f407f6, 0x109cba3a, 0xeecf3a47, 0xf9528f6f, 0xb29e202f,
- 0x171814d3, 0xfaca2f90, 0xbf0634c8, 0x1f4bff50, 0x362d2fde, 0x7768bc54,
- 0x31eebb50, 0xbfc06dcd, 0xee2ae38b, 0x98f5a2c9, 0xc06ddd34, 0x2bd38bbf,
- 0xfca2c8be, 0x67a69cdc, 0xbe2a1bf5, 0x63fa86c8, 0x8c7fd67a, 0xf7e045f3,
- 0x6dbfa3c4, 0x8f406a6c, 0xb3b34d88, 0x1a9553fb, 0x5fabff7c, 0x019df97f,
- 0xd70117f5, 0x41b16548, 0x4e2e1cd3, 0xe8269c95, 0xca13c581, 0x90ed7fe0,
- 0x7cedc4f7, 0xe76156bf, 0xfbb2c6f7, 0xfefbbdb7, 0xb227f786, 0x6919dcd3,
- 0x314d5d74, 0x68b273dd, 0xfbcc757d, 0x9c92af18, 0x3f010f54, 0x6642dd87,
- 0xdd4af5d1, 0x2fa05deb, 0x461cbb91, 0xfb95c22d, 0x314de07d, 0x5e57bf0a,
- 0xe97dcdfd, 0x582e33ec, 0x07ce48c7, 0xfafd5e9a, 0x3673882b, 0xc039359d,
- 0x73b23e2d, 0x6fa03dd3, 0xf37cec8d, 0xd987266b, 0xeeb10f7d, 0xa3d7e091,
- 0x187597bf, 0x3b23fd70, 0xfd045baf, 0x33a1fd47, 0xa6e4e807, 0x6056be53,
- 0x5efbbd0b, 0x1fde574e, 0x798aecfd, 0x4de3118c, 0xe89f1e02, 0x1499e809,
- 0x7833371e, 0xab7cc25c, 0x6b63c49e, 0x2b97a8fd, 0xbd50d3ef, 0x17a6e31d,
- 0xfc03b448, 0xb35ee2f8, 0xb2785fda, 0xfe8fee9a, 0x5d1f537e, 0x3cde9041,
- 0x3291a2e6, 0x9cbd4092, 0x4af51558, 0x7fa2aa63, 0xd14b2595, 0x3ae53e3e,
- 0x7b44fb45, 0x293ea2a1, 0xffa2a477, 0x45728e6d, 0x89b2f6fd, 0xced5fe8a,
- 0xd0bd456a, 0x3fe8aed7, 0xb28748fc, 0x019138fd, 0x1d27450f, 0xf92ca007,
- 0xc76e89d8, 0x07cd33d2, 0x25f91ca0, 0x5fda8703, 0xf6c5e37a, 0xf0bbf003,
- 0xc7efaa97, 0x34e9ff08, 0x87d5e4d9, 0x68a693f7, 0xf25e7969, 0x35913f23,
- 0x2d8c7eec, 0xe02f7dd6, 0x198fdc4d, 0x8a52fe03, 0xe7b9aa84, 0x59f0bdd9,
- 0x12765fcc, 0x69fc0310, 0x7cfd19ba, 0xcfcd7527, 0xbdc599ff, 0xbbdf0007,
- 0xb156afa9, 0xdd1731ef, 0x93977d8a, 0x2d3c2a65, 0x2cabd457, 0x1ff4503f,
- 0xd14ab29f, 0x90fed13e, 0x2b0f4f0a, 0x3639b7ea, 0x45b4f0a9, 0x28dfa785,
- 0x70edfbda, 0x157abfee, 0x1cb44efc, 0x04aaefed, 0xa67cdc3c, 0xd651f10f,
- 0x780956d5, 0x3b64f1ba, 0xe7d8abe2, 0x597604aa, 0x00f9a47a, 0x7f6a3e94,
- 0x5ad7b8c1, 0xd83cb052, 0xd5ff4762, 0x2c5c96e1, 0xf038b48f, 0x94b7dff7,
- 0x8b56f961, 0x6cffcb13, 0x57658099, 0xf6cb0b8b, 0xbfec7696, 0xf983a5b3,
- 0xdffbe2bf, 0x7e001815, 0xbf8d1e81, 0x3c56ee11, 0xe434d8f7, 0xfed13d9f,
- 0x26afa81e, 0x9636de77, 0x81e78d32, 0xcc9d8089, 0xcee9a3cb, 0xbf94e9d1,
- 0xac1c85ed, 0x41fe4092, 0x0859c6bb, 0xb4e1f87a, 0x0ed13f05, 0x5581e420,
- 0x958b14ae, 0x8eb48dd5, 0x643186c8, 0x199c4fc1, 0x25105e74, 0x70584c18,
- 0xa37bd41b, 0xb4defb58, 0xf279b705, 0x637107fe, 0xe17e4867, 0x7130b4e1,
- 0xd8cfe7e3, 0x39cfe0cd, 0x19a86976, 0xfb8c71e0, 0x50a49cb5, 0xe5968f37,
- 0xc81d42da, 0xbd2a93d9, 0xe4539444, 0xde61b7f2, 0x0ee38d76, 0x45be6fcc,
- 0x6b7e8047, 0x8aef6624, 0x99d3db7e, 0x9b7bd0bd, 0xe3a9ed01, 0xbc22e71a,
- 0x3df52717, 0x49ee7001, 0xa9ca3efb, 0x265f735e, 0xed3bafc0, 0xd89eac7b,
- 0x08e484f7, 0x7c18ebaa, 0xf7bb4fde, 0xd9cf86bb, 0xf85092b4, 0x5859a6f4,
- 0x1ce7c0dc, 0xaf007a80, 0x3676af1f, 0xdcac9c60, 0x71f61839, 0xe76065cc,
- 0xfbc665d7, 0x2ceb4413, 0xbfc823b9, 0xc3ae9753, 0xa2e15371, 0x6739f81b,
- 0xd5ce78c8, 0x9d287cf0, 0x27481fd9, 0x8f4e6760, 0xb8e0bb41, 0x5737dd86,
- 0x9d267ff7, 0x1173d9c9, 0x0dfd83de, 0x94c57b87, 0xd377e786, 0x44577af9,
- 0xaebdd4e1, 0xf58fa8a1, 0x9f784b36, 0xf34cf7b7, 0x706ed679, 0xdc609070,
- 0x1ffc2672, 0xf3be7f6d, 0x91febf9e, 0x457f7ff6, 0x8865038c, 0xdf847ae5,
- 0x7679de0c, 0xa7f511bc, 0x2a0335d9, 0xe4ce2e40, 0x6639b071, 0xc386126d,
- 0x3c3d56b4, 0x54d0b89d, 0x904296b8, 0xd6a84e2c, 0x4b4553c3, 0x85af9633,
- 0x0f41aef2, 0x9f09e1eb, 0x6b1dbcfa, 0xa06d8d41, 0xf904b847, 0x0b68ff9f,
- 0x95dcd75d, 0x73d99db2, 0xeb3aae5c, 0x871e51be, 0x3ce3dfa0, 0x010286af,
- 0xd367d5ed, 0xfb7f8525, 0x61af0e59, 0xcc7f5ce9, 0x1eecf927, 0x609c7f51,
- 0xeefb9c38, 0x448747d9, 0xdb282388, 0x2ef8feb9, 0xfd56e77f, 0xeef883ee,
- 0xc7ef1c73, 0x413294f5, 0xe4c19c9f, 0x17ed4140, 0xfee84bab, 0x1a2d3a0b,
- 0x6dcfd38c, 0xb8780dd8, 0xa8f1c1d0, 0x9e701d23, 0xbde678a6, 0xaa4d398f,
- 0x9357a17b, 0x4b2e8e97, 0x2cbcb065, 0x832abbf6, 0x5f5965e5, 0x45c8255b,
- 0x2d7d1f21, 0x6e3f394b, 0xb07a3e46, 0x0fd62565, 0x3cb078b7, 0xf38eb2d2,
- 0x7f6c36e3, 0xce51e5ab, 0x1f9cbd8f, 0x77bf833f, 0xf962d4b6, 0xcb1b8b6a,
- 0x33dce307, 0x3e226e00, 0xc6e8d539, 0x9b43d1bc, 0x5fe2040c, 0x980d3a17,
- 0xc44f4097, 0x40278f13, 0xef018dde, 0x6ff3a9f5, 0x9fbe7cd4, 0xb7df421e,
- 0x189e9c58, 0xfa033794, 0xf4c8c0e2, 0xcdd88c74, 0xedfe97c0, 0x0f9057f1,
- 0xcddbb31d, 0xa4b74fa0, 0x38bca277, 0x759bb4e6, 0xbc79eeb4, 0xedbbb593,
- 0xafad0366, 0xdac7df4a, 0x1473763d, 0x7c7eafad, 0x12f76b1f, 0xf83f220c,
- 0xc7c86bf8, 0x107489ca, 0x31a547ce, 0x17152c6b, 0x1f975e54, 0x3e317384,
- 0x3858de65, 0x3d725f17, 0xd57da27d, 0xca4fa841, 0xab85a2dd, 0xe1534edf,
- 0x9157181a, 0x7185ad50, 0xaf963363, 0x06e37181, 0x1e0dac3d, 0xc76f2137,
- 0xeadfa81a, 0xfd05a2d8, 0xc7ce4bf4, 0x2ea23cc4, 0x169f05da, 0x3ac360f9,
- 0x0a0f285d, 0x0f285c3a, 0xa62a5c04, 0x7e003f56, 0xc90ea6c7, 0xa63ac122,
- 0x71c1fd4a, 0x846ba5c8, 0xbf2922f7, 0x8efe98de, 0xd71d1579, 0xb11bf504,
- 0xa65593fe, 0x6f7f94ef, 0xdf230f4d, 0x0ef3f04e, 0xbbf21ef2, 0x3bd9e84f,
- 0x5c035f1d, 0x9b9ef04a, 0x24b5df19, 0xe3fa336e, 0x3d833641, 0xb69e7204,
- 0x1965e70f, 0x6453fb97, 0xcef876e7, 0xc3f9918b, 0xabfcfccb, 0x68444dee,
- 0x4f61fce7, 0x4bd985ba, 0x06875dfc, 0xd07e86d2, 0xa997e5ab, 0xf9d5a1f3,
- 0x59ff2216, 0x4f515f9d, 0xa1307bd8, 0xdeecce79, 0xb39e486e, 0x19a2abb0,
- 0x5e05ad3f, 0x78f8e943, 0x0957cf3a, 0xabc9c385, 0x3864e1c0, 0x87ec8438,
- 0x2eef3178, 0x74c6ff24, 0xdeacf11c, 0xb2277117, 0x3f8936f7, 0x5d04feec,
- 0x8dafee84, 0xe0cb5fc1, 0xb3bbf54f, 0xb9aae780, 0xab7e0266, 0xc7f3fe60,
- 0x351ff02b, 0xf8aefb5f, 0x0db9b4e5, 0x5080fdec, 0x1c39763e, 0xc2f7131f,
- 0x53d0a5d5, 0xe41a3ee1, 0x343bc201, 0x4befe760, 0x80674776, 0xf7d1567e,
- 0xd0ec0695, 0xf37ef604, 0x9cdb9b22, 0xe922e141, 0xc8817e59, 0xf1a33dc3,
- 0xb6f416fc, 0xc9e6cdb4, 0xb0832fa8, 0x4ac767a0, 0x7e3fe0eb, 0x878aead6,
- 0xafd72471, 0x3a077e0f, 0x7a699e52, 0xa17f9306, 0x5fe45125, 0xfaf96ef6,
- 0x8a2fde9a, 0x792a8f04, 0x41ee1fb4, 0x418b285c, 0x112dd9f9, 0xdb3fbc1f,
- 0x7a849e5d, 0xbd00f74b, 0xdaefca16, 0x301eee2e, 0xdb57e704, 0x65a9ddc7,
- 0x71ddf646, 0xd0eca013, 0x079d1fbb, 0x0691e0fe, 0xcdbc938c, 0xc7270ff3,
- 0xb7c3fcb0, 0xc980fdf9, 0x004a5e1f, 0xf65938f9, 0xa1481525, 0x1bf77676,
- 0x05ec2ab3, 0xdd36f6a1, 0xefd858ef, 0x976eecd5, 0x6006cbb1, 0xf5dfdb55,
- 0x9022bf2b, 0xe56a3de7, 0xe3f90225, 0xbc7b73ff, 0xa4f5132b, 0x9533e4ab,
- 0x415b79f5, 0x897318ff, 0x228e39e5, 0x9525ce2c, 0x9bf2c9bd, 0xdbb6a978,
- 0xbda868e7, 0xa76a1d9e, 0xa5fd92cf, 0xd421ef50, 0xd809cf5e, 0x374ec2eb,
- 0x45bf9610, 0x3806f7ed, 0xddb9e717, 0x8f13314e, 0x7c3f2179, 0xc87dce6f,
- 0x9f30a217, 0x8f8ef9e3, 0x7fad6112, 0xc5fc4ae9, 0xbd00f62b, 0x22be5937,
- 0xf5fa79c1, 0xc120bf2b, 0x7375bcef, 0x8e9b773f, 0xffaa43dd, 0x8a728ca7,
- 0x8075b5ca, 0x9af27aa7, 0x7920eefe, 0xabffda4b, 0x28c3de1f, 0x3586abff,
- 0xb4f5bc81, 0x7ed2764c, 0x223edcd5, 0xac76f91e, 0x32927b73, 0x289ed646,
- 0xeacbbffa, 0x13ff4403, 0xbbf49d93, 0x9da2a9d5, 0xd78ebf8f, 0x6c76ee89,
- 0x0df312cf, 0x6b337565, 0x72f8cb6f, 0x8231e832, 0xe0cc6fbf, 0x47bf91f2,
- 0x63fdf944, 0xcc578919, 0x73b651bf, 0x1fde2079, 0xc4e1faaa, 0x6e70a398,
- 0xb5cc25db, 0x875fbfab, 0xb673fbfe, 0xf7e082f6, 0x8e9e454a, 0x798cd2ab,
- 0x0d2f0d53, 0x22740add, 0x81278f9b, 0xe3c5d2de, 0x09b255f1, 0x36172ee3,
- 0x491ebe30, 0xf2bc5bef, 0x42be0515, 0xc0fbf9da, 0xdfa49818, 0x6493ff3b,
- 0xa0f33ef6, 0xe80bcc2e, 0xde0c7ce0, 0xc37b847b, 0x212bff22, 0x5ec13887,
- 0x8a39784e, 0x71f953bd, 0xc5dbf217, 0x767f332f, 0x2803a6c3, 0x76cbe6df,
- 0xc89d27f4, 0xf00abf76, 0x0d7731e9, 0xcaf838c1, 0x3f5d7157, 0xdc785bb2,
- 0x182f2fab, 0xe143879e, 0xc0abfbff, 0x4afff7ff, 0xfc82eff8, 0xbb73e032,
- 0x4dbed0a3, 0x0ef5fad6, 0x649e6b88, 0xe79e5cef, 0xfaed2b70, 0xf815df10,
- 0xd3b30667, 0xdc583ae2, 0x8965e446, 0xc333feef, 0x1e74eccc, 0x79a8691f,
- 0x47c4346b, 0xc4c6fe04, 0x77f07690, 0x38383c53, 0x07801c1e, 0x9c40ef01,
- 0x0acb8e84, 0xb0aed79e, 0x23dc050f, 0x7d35639d, 0xe3ab7588, 0x0e997706,
- 0xef7e0096, 0x847986fa, 0xb0b4cfdf, 0xcc7eb4f9, 0xf011fc13, 0x1e00c4ca,
- 0xef940375, 0x46bc5180, 0x22b9280d, 0xffed95de, 0xc35778cb, 0xf3d65d4d,
- 0xf7fa9838, 0xff3403a1, 0xbffc70ab, 0xdd9d5fe6, 0x3ed15fbc, 0xd71be577,
- 0x7e157fe4, 0x1f957fd1, 0xf5ff9236, 0x16ee992f, 0x2fc9bba0, 0xfc40d12e,
- 0xffbdf6e6, 0x8b013bc8, 0x5e303bf7, 0xcbdf0f74, 0xf6ffa317, 0x9e947dfe,
- 0x7e6668be, 0x3ffb53a9, 0x43f3d9d7, 0x45f663e9, 0xe8833899, 0x77caf66a,
- 0x669f2074, 0x5c22cd53, 0xa70d6a7c, 0xa127cc27, 0x48d6a07c, 0xfcf40974,
- 0xf7b2d6d7, 0x10216ba5, 0xe7d2c363, 0xb593eda6, 0xc7ef07c4, 0x3eb49b56,
- 0x9487c603, 0xfc0d61f7, 0x686a597d, 0xcac5ee2a, 0x9ef3194e, 0x716328ee,
- 0x76a619a5, 0xfd38dfbc, 0xf7f3eac8, 0xe35dd9c1, 0xba796129, 0x9fd27ee2,
- 0x5e24df34, 0x37e406b4, 0x1e259ff8, 0xc3ae5c87, 0x5c7aa438, 0xfe7600ed,
- 0xcb12cb26, 0xf2c3d837, 0xa479c4d7, 0x28623bfb, 0xf0f37962, 0xb3756ace,
- 0x00b437ce, 0xa8fd8ff4, 0xad95347f, 0x353c002a, 0x303e958d, 0xc0f40414,
- 0xa25f95a6, 0xc7e6a37e, 0xfd5af2ea, 0x1cb7ef50, 0xfa117a41, 0x1f16a9e2,
- 0xa97ed5d6, 0x8c7e6359, 0x5f919c71, 0xd470bd32, 0x1189e725, 0x6f6f6ff6,
- 0xd84b3b09, 0x4e3b6a5d, 0x5ef10bf0, 0x0b00fb5c, 0x77c6bb93, 0x5a8ffbd8,
- 0x4034be56, 0x5f057729, 0xef767ca5, 0x4a5fe400, 0x87c41bfe, 0xc55ffdb1,
- 0xdf740387, 0x4dff00ec, 0x6f7b066d, 0xf5f74d5d, 0xaa7e4c29, 0x94ae5de9,
- 0xd3519f51, 0x3bf3a0bb, 0x7fd05b9d, 0xd2c60b37, 0x926acc75, 0xc9d59ef0,
- 0xd7bc1e97, 0xddd09748, 0xe29d33fe, 0x486fbc3d, 0xe072a1f7, 0xbe23b463,
- 0x5d201cb5, 0x33feecd1, 0xa84f47c3, 0xc0a0bd1c, 0xbd1ca84f, 0x5fc4aff0,
- 0xf9cffd98, 0xf0907276, 0xc8bb7f3c, 0x6b239ff3, 0x26dcf7d8, 0x790a0796,
- 0x765ebd68, 0x56696c2f, 0x4d7fbe1b, 0xe058b20d, 0xc9f6cb23, 0x778b3d64,
- 0xde835368, 0xbe26ea2b, 0xe0494777, 0x9bf9624f, 0xf7b3464b, 0x9a79d43e,
- 0x91b3ff22, 0xb4cbbb8f, 0x54788f4b, 0xe62443bd, 0xd443bf51, 0x67fc7a38,
- 0xf7e7ff18, 0x0fefd58b, 0xf9e4ca0d, 0x88a4459f, 0xccafc7c5, 0x5e407aa7,
- 0x7b8df906, 0xbda0b52e, 0xf4399793, 0x01193c3f, 0x8665177c, 0x99a5d7e8,
- 0x94b3d657, 0xfa62ffed, 0xf0dbcd90, 0x4a6f913d, 0xe72c861f, 0x38b75824,
- 0xf9e7fd27, 0x679e0315, 0xef713ef1, 0xbdf1e7f2, 0x09afde8f, 0xe6ae87c6,
- 0xcdd3199f, 0xf4dd03ae, 0x4cd5b7b1, 0x94ea3ef1, 0x2304fd07, 0xdef1bb8f,
- 0x9cb788dc, 0x0a4c8190, 0x5864ba0f, 0x841bd0b7, 0x0be0111e, 0xcf0b7efc,
- 0xfe56b8f7, 0xdc4bfff1, 0xe9b3dc43, 0x4e4af9d1, 0x13defc80, 0xef1df615,
- 0x2b9a99d5, 0x60f9ffbe, 0xe0357b9c, 0xbfe70a69, 0x2ad01de2, 0x7bdbbd99,
- 0x3f464ba1, 0xfd1f8ac5, 0xdb8fb7e1, 0xeb57e743, 0x2f964d67, 0xd247ae50,
- 0x2c349bd7, 0xd2a8beaf, 0x605af98e, 0x42df80ff, 0xfdd431f8, 0x7e2bd90f,
- 0xf776899e, 0xac272ee8, 0x9eb651e7, 0x5a6af848, 0xbf0a5ff9, 0x37efa449,
- 0xccb12bed, 0x7f1f3a0f, 0xfd0494cc, 0x06353e5b, 0x74ad7df0, 0x0ecd7ff1,
- 0x8f132c98, 0xbe70e544, 0x257a65e4, 0x2ce5fa61, 0x1ce585d2, 0x9ba587d2,
- 0xf9eabcb0, 0x42e581c4, 0x65d3cf7e, 0x0991bf77, 0x1f5d55fe, 0xfe7b53be,
- 0xe1e7bfa5, 0x8f37503b, 0xa95c836a, 0xad9fcaef, 0x0b7aafd6, 0x0d38fefb,
- 0xbfeec7f8, 0x0f51da67, 0xb377b6b8, 0xd3ce71bd, 0xddfc6199, 0xb32e59ff,
- 0xee97157b, 0x5a4def65, 0x363218d8, 0x2574fb11, 0x09f9e167, 0x2de4cdf0,
- 0x5c426f82, 0x0d03ff2b, 0x932fcb8b, 0x7505eff0, 0xc47835f8, 0x796517f2,
- 0x62efa865, 0x560df9ed, 0x717904af, 0xfb58a323, 0x5dfe2b72, 0x8fc4d9cf,
- 0x3c2e72e7, 0x3dc32b65, 0x0b963b09, 0x54d4fbf8, 0xe896cee3, 0x469d45f8,
- 0xfc4dcf96, 0x05bf6083, 0xb1849f60, 0xf206cb77, 0xe3367438, 0x542ac3f7,
- 0x0fce05fe, 0x3315ec1a, 0xe172d206, 0x48192740, 0xad987ee9, 0x20cffd6b,
- 0x86b7606f, 0xcfafbdc0, 0xe300fe46, 0x2fdc622b, 0xe83a15ec, 0xf2c482f7,
- 0x0cfb3d8e, 0xa4d4bde2, 0xcbbd3f60, 0xfd03195e, 0xa8b6146c, 0x2b80451f,
- 0x572abdfc, 0xe44c7b18, 0x1d030db1, 0x0485fd11, 0x417a25df, 0x819cf562,
- 0x4d7dbe3f, 0x3d30fa1e, 0xc2fe87a0, 0x7d80ceee, 0x6213d30c, 0x92fff582,
- 0xcd21afdf, 0x5f0f1099, 0x034184f2, 0x547bc67a, 0x833dc31c, 0x167b533f,
- 0x2ed4d3ca, 0xd42ff285, 0x03f2852e, 0xf942976a, 0xa14bb511, 0x10b1745c,
- 0xbe2224de, 0xd862ce81, 0xa83b888f, 0x903f9bd7, 0xbb06cdc9, 0x1d62867b,
- 0x8eb8f4fb, 0x3f5dac17, 0xc75d19fd, 0x6907bb0b, 0x244bbee0, 0xfbeef478,
- 0xfe95e65b, 0x7f888d3e, 0xf107dba8, 0xd2ec17ef, 0xe82fdca2, 0x0e2ec7f0,
- 0x503157ea, 0x77f3e38f, 0xf30b1c7f, 0xe1fa58f7, 0x56e894ea, 0xbd586b27,
- 0x845e57e2, 0x39dd836b, 0xcf4bf603, 0x4fd838f7, 0x7e1fc741, 0xe83af70a,
- 0xeda718fc, 0x8236fa95, 0x87dea67e, 0x5f62df7a, 0x61ebff74, 0xb3bb0bfc,
- 0xdf942761, 0xf65e7610, 0x437977b1, 0xf70abbf7, 0xafa1bb73, 0xdc2bee18,
- 0x9b0e597e, 0x2f60da27, 0xc57f7847, 0x38fed0f5, 0x812ba71c, 0xae7b6faf,
- 0xf111f3d5, 0x50f001ee, 0x4ba3c83b, 0x560fa0b1, 0xc76678f3, 0xe36f41ae,
- 0x322397fd, 0x385fbf81, 0x773ca6cc, 0x1278e13f, 0xbd3efe65, 0xc2f5f00b,
- 0xc1074fbe, 0x3f14a07b, 0xc9efe083, 0x60e068fe, 0xfe7dfe45, 0x031fafc8,
- 0xf1fda1fa, 0x274e15ef, 0x6e20aa5b, 0xffb8d33f, 0xb6696c10, 0x882a83e5,
- 0x914dcfdb, 0xcf39430e, 0xe20e359e, 0x79df22f5, 0x61f96e41, 0x3ab74a38,
- 0x2b8f51aa, 0x2412e607, 0x318d2a17, 0x216051fc, 0xf515e287, 0x8ae929f1,
- 0x39ed13fe, 0xb949f68a, 0xfbda2837, 0x8638a1ef, 0x06cf7e07, 0x4365f478,
- 0x83ee8d1c, 0xa7b57dfd, 0xca77cc64, 0x96fc7ddf, 0xf27d681b, 0x7be077d3,
- 0xf6f02f6f, 0xf12b3bc9, 0x52f59bef, 0x22a9ea78, 0xa1eca675, 0xc9833f8d,
- 0xfd42f654, 0xc30f27be, 0xd8dfd0bb, 0x2760885e, 0x97a611d4, 0xd417b246,
- 0x9be50276, 0x39be053f, 0x16a9a5ec, 0x617f0fc8, 0x2069d7e4, 0xe40fb697,
- 0xfb7066ef, 0xf4fd1221, 0xfec9139f, 0x29fdf076, 0xbf88fd35, 0xc9ca2d6f,
- 0xa13dd8c7, 0x3ed7ca6f, 0x7686be01, 0xafdb87b9, 0xcff954bc, 0x6f1de986,
- 0x9efe03df, 0x94dc32a3, 0xb5bfbfe8, 0x0e5ffe18, 0xb8593dd0, 0x04d481e5,
- 0xfa03ddfc, 0xa7f72370, 0xeb90367d, 0x1ffbf553, 0xb40e2d48, 0x281f1593,
- 0xa5fb93fa, 0x9afa8ab5, 0x437d652c, 0xf1e0daf9, 0xc5b1f491, 0xbbd3ce8f,
- 0x9f9ee1f3, 0x3aeff614, 0x8127aff6, 0x4b7d87f3, 0xba7edf90, 0xbdfe197f,
- 0x46ff7559, 0x01f81f3a, 0xb3904717, 0x974d4f82, 0xeac23bd9, 0xef8abff6,
- 0xefdbbe39, 0x8f6147bd, 0x332f5e79, 0x9c5efbf9, 0x13a0af5b, 0xf9eefb3b,
- 0xe8ff0f4d, 0xed2b882b, 0x79d57661, 0x051f932b, 0xc0d33ebb, 0x161e8bdf,
- 0xc0abe8cd, 0x3dc0d7e2, 0x7e06ff9a, 0x00334c2b, 0x0000334c, 0x00088b1f,
- 0x00000000, 0x18adff00, 0xf514707b, 0x7bdbdbf9, 0x79724b92, 0x71211240,
- 0xc220572f, 0x4849ac91, 0x92ea4903, 0xf03ea410, 0xa2a21900, 0x799e0fae,
- 0x2a93a84a, 0x028d361d, 0xd6d36d52, 0x4f4e2a2a, 0xd1954a2c, 0x2562bc34,
- 0x40569478, 0x2f2a7b1d, 0x419cca69, 0xee421923, 0x8cc38a8c, 0xbf7dfa1d,
- 0x5eddcddd, 0xc9a75502, 0xf6fbbf1f, 0xcfdef8f7, 0x05048af0, 0x571a0192,
- 0x02a62a26, 0xc8dc8280, 0x00b5fb71, 0xbb4c6176, 0x94e00b3d, 0x157004c9,
- 0xa5029fd0, 0x30276100, 0xf0efdd38, 0xbdbf423d, 0x225f1c91, 0x9e5eef7e,
- 0x77dc2323, 0x4055a560, 0x5dfd12f8, 0x361b5d17, 0x709563df, 0xd480197f,
- 0x0fb91ce1, 0x1d300ad0, 0xe7f015df, 0x32a3a458, 0xe784db92, 0xf716faee,
- 0x2412fc55, 0x828f9d20, 0x76048f4e, 0x15798f80, 0x0624279e, 0x8df3c49f,
- 0x22b07847, 0x3810033f, 0x8ec7077e, 0x004ab339, 0x814fd396, 0x815877be,
- 0xc005bf67, 0xefb42bef, 0xdf97cbcb, 0x6f084904, 0xf286f4b1, 0x4970fbd8,
- 0x90e30343, 0xaadced7e, 0x9d5bb7bf, 0x78c9feb4, 0xff1e01ae, 0xb5fbc782,
- 0xd7ef6410, 0x7b7dc0ed, 0xf5f97ecc, 0x0dfbd39f, 0x0af78cbb, 0xbef4c485,
- 0x0a03f4a9, 0xb3ecf12f, 0xb6adf089, 0xf9aaf8ab, 0xb1bc3f6f, 0x837af918,
- 0x69f86d17, 0x64c4df68, 0xd98fe2f0, 0x91aca428, 0x8cdc6c72, 0xe145a48f,
- 0x5cfc7dc1, 0x47379d3f, 0x1b4fe672, 0x44906f29, 0xb561c913, 0xbab7c54b,
- 0x80059be2, 0x9b7756f8, 0xe02bb801, 0x1083c8d9, 0xdba0a783, 0xa33bf3e6,
- 0x2a5d87f4, 0x5fdd058f, 0xaaf2cea7, 0x01d12b6b, 0x405e2aed, 0xa67a41bb,
- 0x47496071, 0x139f307c, 0xac72e1b7, 0xe492a33b, 0x80838c74, 0xb89ec850,
- 0x2df48ed5, 0xefa39f54, 0x1fc5484e, 0xc2667999, 0xcbd340b3, 0x2f77d2c2,
- 0x516f7872, 0x4889a2f7, 0x75df1c01, 0x1cd431ef, 0x0c3c152c, 0x2c5062df,
- 0x296397a4, 0xa466ecbe, 0xddcf1e73, 0x1c12f3ed, 0xff10e019, 0xae048ab1,
- 0x3fef638d, 0x7cebef42, 0xb2f8b31d, 0xb35f189b, 0x37a87d5d, 0x5fc29a4e,
- 0x8f29184a, 0xd0cd5ca8, 0x5797eba7, 0x59ec86dd, 0xd7e6afdf, 0x1d31bace,
- 0x5c04b8f5, 0x16fba436, 0x610c0d1e, 0xdfe6cb78, 0xe03126e6, 0x5f2819ef,
- 0xf44a982e, 0x2d0584fa, 0x68cfde02, 0xd39835f9, 0x5667e462, 0x8fd74efd,
- 0xf491cf2e, 0xf9abf8a8, 0x7c84a0f2, 0x98e76d0e, 0xaa88351d, 0x9f94369d,
- 0xc462c3fb, 0x45e410df, 0xefa9e90e, 0xe492703a, 0x03aeb1d8, 0xce8016cc,
- 0xad6c5d75, 0x7c033bb7, 0xd98fe33e, 0x838d09af, 0xc1a55bf8, 0x74775f8c,
- 0x1c7fca3f, 0x3032cbbc, 0xf802e70c, 0x13bf7d93, 0xbf359f90, 0x62d8f2f8,
- 0x794376a2, 0xb207f30a, 0xf4a3abb9, 0x9c015817, 0x5b647f48, 0xc32b7f82,
- 0xa27eaa23, 0xfeff6dd9, 0x719a2749, 0x0b1dffbf, 0x1583db33, 0x1cfe0f4f,
- 0x12db35e1, 0x53fb9c98, 0xfda2c941, 0x0afd93ad, 0x8a6e581e, 0xdc9334f4,
- 0x6dc5133b, 0xf3f9ffb8, 0x81dd5f93, 0x2757caf0, 0xf926448a, 0xdf845091,
- 0xefa011b3, 0x3dd8b33b, 0xcbbc5590, 0x5fe4ff34, 0x729bf69e, 0x4d397fda,
- 0xfeba3c24, 0x90ef3ece, 0x35f5e500, 0x685df204, 0xa538e782, 0xd70f84cf,
- 0xe69c769a, 0x36ad3ed0, 0x75e92779, 0x397fb3d5, 0x54fc865e, 0xd3f37cbd,
- 0x95be9033, 0x7a058d1f, 0x11d7aa27, 0xe42920f1, 0x51e038a5, 0x9f2680e3,
- 0xff0eedda, 0xa57131a7, 0x00c523be, 0xf9657637, 0x47898d3f, 0x18caa0b5,
- 0x1f98e7ee, 0x35fe69d5, 0x20df978d, 0x4843d47d, 0xb110938d, 0xf2155d92,
- 0x2171449c, 0xc98d84f2, 0x3ecede3f, 0x2ecc4c10, 0x53204ceb, 0x034c2f7c,
- 0xaff9267b, 0xfc2fcaac, 0x9bade4c4, 0x42fd3650, 0x93ffeeaa, 0xb58b4c16,
- 0x37869ecf, 0xdb373ec9, 0x380e7d98, 0x3c67f980, 0x290b7f9e, 0xfb32fcec,
- 0x861fcc57, 0x45cb4bf3, 0xc0c51730, 0xee28905e, 0x4509b615, 0xacdae00f,
- 0x964a65e9, 0xadfc442f, 0x9eedf8ea, 0xb73c98f7, 0xf08a783c, 0xfd32761e,
- 0xdcaa7bc1, 0xc4d41cc3, 0xf665a9e6, 0x7bff342f, 0x7dcfe0c1, 0x97c89ccf,
- 0xddbefdf1, 0xed01f353, 0xd83e5ef9, 0x67ca1cf7, 0xfa783130, 0x0f3b5c61,
- 0xf28e387f, 0x75bd3c62, 0xe01a5f2d, 0x478d4e01, 0x7e07c475, 0xbbeb913f,
- 0xe181f640, 0xde87c584, 0xfc98d34d, 0x326f79aa, 0x6fdc3fe9, 0x4e9e2fa4,
- 0x3e9d7dfd, 0x9cfd7dfd, 0xebeaadd9, 0x9f9835bc, 0xcc9fdf8a, 0xefac1811,
- 0xe60a4f9f, 0xbbe938a7, 0x8a973d4b, 0xd5bd8c70, 0x6fd44fd0, 0x37e31d8d,
- 0xc35357d2, 0xbec06d89, 0x713f142b, 0x5fb8c80d, 0x26a6f997, 0xd1d9f037,
- 0x766916ce, 0x6669e906, 0x82b73bca, 0xb48bd76a, 0x743b7df8, 0xe5fd0058,
- 0x67f5a9a4, 0x3a075c76, 0x63916f7e, 0xca72afe3, 0xf7ea6974, 0x254abf8f,
- 0x3f1c51e4, 0x3ab272ef, 0x339ba267, 0x90d973b3, 0x5f70e74d, 0x281da00c,
- 0x0db1369d, 0xdf7991e9, 0x57bc6e35, 0x93e40d67, 0x64f7e81f, 0x07df665e,
- 0x9196f7b8, 0xc81cc1be, 0x8a4ff567, 0x3bac3815, 0xa0c563c2, 0xbe50f284,
- 0xe2571606, 0x02d865e3, 0x47489d35, 0xfdd77d05, 0xb8a4ed11, 0xe9d4d4ca,
- 0xc65e251c, 0xbd3407c1, 0x9a99a715, 0x8ff1463a, 0xe91f68db, 0x5e0e836b,
- 0x7f355ff5, 0xc6726996, 0xd6c7cf84, 0x5c5a0d33, 0x15d9270f, 0xdb2fe91e,
- 0xb8407a87, 0x40381ccc, 0xb43d7a2b, 0x42673ea0, 0xcbaf7d40, 0x6729bf18,
- 0x78f9612c, 0x33238b2a, 0xe7aef535, 0x68f4809a, 0xeb857ca7, 0xd3c82e26,
- 0xb08813fa, 0x99970255, 0x5b3b1456, 0xad8f8367, 0xad89a073, 0xad9da173,
- 0x5b074037, 0x5b20826f, 0x0da04a61, 0xeb5ffc58, 0x0c3cc3ea, 0xa26e5d3f,
- 0x18bc5c7c, 0x87f3469a, 0x2ebc9ab5, 0xea8c0f2f, 0x1e5c3f25, 0x64ce4073,
- 0x2e4e5d74, 0x9d98f213, 0x91b172eb, 0x073de23d, 0xad6933f8, 0x877b1080,
- 0x99de925c, 0xe0998205, 0x5c18902a, 0x51e51dfd, 0xb2cd921a, 0x54b91477,
- 0x8f276e8d, 0x9171726a, 0xea8d8f0d, 0x605baf6b, 0xcc37aeb0, 0xff1499d0,
- 0x7213ea47, 0x84e2ce88, 0x0c052fca, 0x21f77e11, 0x6be3199f, 0xb3655171,
- 0xf74ee107, 0xe3199f49, 0x65597168, 0x6ac44591, 0xdf63f5b3, 0x4765846c,
- 0x1fa03e52, 0x3bc831d9, 0x87bc3e50, 0xfa54d287, 0x7ca7e39e, 0x101fe369,
- 0x07654fc9, 0xadd59040, 0x17e45568, 0xaeef357e, 0xba7aa971, 0x4b3f26d9,
- 0x0f6f587e, 0xc3c80924, 0x0cead69a, 0xac1b87ca, 0x8c9fbbea, 0x89bea615,
- 0x1e21b172, 0x2f94617b, 0x081c57dc, 0xb9a13887, 0x47a51dc5, 0xf01dffc7,
- 0x784af9fe, 0xafca650f, 0x09bf29b9, 0xc61beb22, 0xb3bb796b, 0x97c44cb3,
- 0xa3170e90, 0xa9389423, 0x26dc85b9, 0xde97b7cb, 0xf6aa270b, 0x7b6c97b6,
- 0x75ed747a, 0xd3ddbb4b, 0xb70f7e47, 0x8027b37e, 0x433f86ef, 0x5def78c4,
- 0xce8fbcb7, 0x39429a35, 0x5f97a845, 0x92b69c26, 0xcaf6e83d, 0x209692a1,
- 0xf8126ddf, 0xca0fccad, 0x9675c35d, 0xe1ef6a27, 0xca1ef8a5, 0xabe7d8a3,
- 0x4a0fb2c2, 0xd20e9a6a, 0x57b72a5a, 0x39e10ee1, 0xf236f442, 0xffa46591,
- 0xac8f94c1, 0x9c7f319f, 0x169ddaa0, 0x1ff7baa7, 0x0abc7879, 0xdfc620fa,
- 0xbc5ff71a, 0x8f8c2ff0, 0x914e438d, 0x7bed978e, 0x7dea99a6, 0xcab0cfdd,
- 0xdd11c433, 0xd97666ef, 0x773b3c02, 0x5f3a52cd, 0x878f51f1, 0x3d75efe2,
- 0x832a36a1, 0xc627ddc3, 0xd7aff6ab, 0x3f70dfe9, 0x6e7c4f24, 0xa6487b47,
- 0xa7ca8b3c, 0xef37683e, 0xab7f21b7, 0x60d07ea9, 0xf6abf185, 0x58ff7a95,
- 0x561fe47f, 0x19f03bea, 0xa95df885, 0xcb62bfd1, 0x5d91377d, 0xfb1bf4ad,
- 0x6cafbd41, 0xf6d5ced4, 0x1f13d7f8, 0xe78ddbb5, 0xccafa91a, 0xeb0cfaa7,
- 0x75d50f31, 0xaa5bfb71, 0xd8d95f58, 0x1ffefc65, 0x2495f637, 0x81bf2d60,
- 0xd72e4756, 0x4e7f10ce, 0xfd59e7d6, 0xf56de436, 0x8ba2cdf3, 0xc8a76ce0,
- 0xf5d1ebe2, 0xb61e7b10, 0xd15b31a4, 0x46e575fd, 0xc3c7d58e, 0x364bdffd,
- 0x7828e889, 0xbdd58329, 0x7ab3af58, 0xd9881d03, 0x86ca016b, 0x3d7bfb43,
- 0x426b9225, 0xe777af3c, 0xff4f5489, 0x67049d75, 0xf4fa512c, 0xdf9abe7a,
- 0x3ea56551, 0x93ec7ee9, 0xef210ec8, 0x37bc72e9, 0xfc05b0fd, 0xaa043fb8,
- 0x9ace863e, 0xf33e5d58, 0xe49e4ec8, 0xfd518fcf, 0x026996d9, 0x0e1e4621,
- 0xa3080c61, 0x4d36f5f4, 0xa979097f, 0xf144fd86, 0xe4fdc32a, 0x7ec35cd2,
- 0x2b69239b, 0x0a4501e1, 0x8e284b7a, 0x48a4efab, 0x20f70c53, 0x5fb8ff84,
- 0x437189ae, 0x64c39cd2, 0x15ce15cf, 0x3690de6c, 0x9e78d0b7, 0x5f13cb5f,
- 0x87b833b6, 0x657f957c, 0xe675e836, 0x7e9e1180, 0x10921db4, 0x39a8e3af,
- 0x00a16e6e, 0xc13625d5, 0xd5ca5df8, 0x4c0262ec, 0x861bcc30, 0x961ceee5,
- 0x0945d92b, 0xf720c8fc, 0x1ea1b978, 0x3434dd58, 0x422a29c1, 0x7d630f54,
- 0xd467f946, 0x259fe518, 0x7e3de51b, 0xd9de5185, 0x5f79464d, 0xab9462dd,
- 0xcdca315b, 0xe1a671b3, 0x4af6c4fc, 0xf3793c03, 0xd7f3860d, 0xe01817f8,
- 0x376fdba9, 0x71d69f9c, 0xa0bf61af, 0x5f61956b, 0xd9cbb3b7, 0xd581b5c1,
- 0x0266f671, 0xa0ec15d3, 0x0643f0e8, 0xff7af17c, 0x12aaf831, 0x47a5ce51,
- 0x48c2de51, 0x1484703b, 0x6f1878a0, 0x57faf107, 0xaadff4e2, 0x93f793e5,
- 0xee4e3ece, 0x8f412f3a, 0xa0bcda7f, 0xb1fac2dc, 0x55690a7f, 0xcb567489,
- 0xaf2d3e6b, 0x644df6c1, 0xa973e024, 0x0f1418b0, 0x3c2b1c52, 0xbb22abe9,
- 0x1d350e2c, 0xe4a0f644, 0x32557b6c, 0x7040979d, 0x4b47538d, 0x5296fe74,
- 0x72b1cc0e, 0x8f366742, 0xa171ca8b, 0xe327cad2, 0xfd6fb2e1, 0x54ecc96d,
- 0xcfa7c33a, 0x3552b87d, 0x1c97cc6f, 0x47918e60, 0x4f9ea945, 0x5d5e8cbc,
- 0x089cfaee, 0x52b07deb, 0xfbb26fbd, 0xd5a3dcdb, 0x9e66e237, 0xab325fd5,
- 0x32710ec7, 0x6add1f9b, 0x7d90e60f, 0x5f90c99f, 0x317cc5c9, 0x56051268,
- 0x36a171bf, 0x8c4c2a62, 0x6e52f251, 0x9f512f9b, 0xcd2aed86, 0x8bf21727,
- 0x465e2be7, 0xa2542bbe, 0xb7f4c5b6, 0x99de5727, 0x739e794b, 0xbbc22fad,
- 0x973ccfef, 0x9fcc7943, 0xf7a2ed2c, 0x1921e787, 0xd9c617c8, 0x48504990,
- 0x1c43ca04, 0xd1ce2feb, 0xfc623323, 0xe585a376, 0xadfad02b, 0xe939353b,
- 0x0d12d6fd, 0xb13e2f6f, 0x9df8e302, 0x3c98875d, 0xb407336a, 0x7449ad3e,
- 0x4df7fbe1, 0xbf521670, 0xa8915209, 0xff7ae9f6, 0x3eff9e35, 0x57ef5579,
- 0x36be772f, 0x07d0dfb3, 0x51b48ec3, 0xf3f18de7, 0xeadf28ac, 0x258fbdfb,
- 0xfbd3fcb0, 0x1f9b3658, 0x641fdf46, 0x9b3b8173, 0xc7d8303e, 0x1b1f2ddd,
- 0xe51eeeec, 0x287ec313, 0x8f19623d, 0x64f687fc, 0xe503b9cd, 0xadb77e77,
- 0xd450fa84, 0x4c6e7f57, 0x627a1c9f, 0xf7c26cf2, 0xc73cf9bf, 0x1759e8e8,
- 0x9d34f364, 0x4eebd3cf, 0x2eb43832, 0x3e78d6c4, 0x5f55bef5, 0x3c837fad,
- 0xc227ea33, 0x9b47118d, 0xd479d4c3, 0xd667beba, 0xc3ca4ab8, 0xb356d93d,
- 0xe1524eba, 0x0abb52ac, 0x6b4b99cf, 0x48dce2d8, 0x070f6b7d, 0xd0f68712,
- 0x9785d57b, 0x7744f8ac, 0x50f56c86, 0xb9195a5d, 0x482b7340, 0xe379b10f,
- 0x41d954d2, 0x062c39df, 0x9d1952b3, 0x383fa893, 0x035e526b, 0x2f25018c,
- 0xf53e71fe, 0xaa498301, 0xf8be27dd, 0xe9057cdc, 0x97c5257e, 0x0a40f74c,
- 0x94e76359, 0xfa859cfa, 0xc253ea62, 0xf0cd750e, 0xcc8f8c70, 0x478a75b8,
- 0xd3d7578d, 0x9af5ef8a, 0xe47126da, 0x80dacf0f, 0x07e8a7e6, 0x4317d512,
- 0x1faa6cfb, 0x70920198, 0xdb6eccff, 0xe3cf640b, 0x5faa6690, 0x7d635ab0,
- 0xb65be141, 0x7d09c500, 0x11ee933e, 0xfbc5e57e, 0x6c2d7be9, 0x2898300e,
- 0xd77f9094, 0xf5601d27, 0x595c89d7, 0x15f9b0f2, 0x7a3f1448, 0x6eb6d8f7,
- 0x3991e752, 0xafff120b, 0x0f12b873, 0x6a4233eb, 0xe1cda95d, 0xf9abbe74,
- 0x43df19c7, 0x7c406d9b, 0x7c1a5f9e, 0x4ee6cbca, 0xd9d10e62, 0xd6e9526b,
- 0xd3f9d5e9, 0x73be88f9, 0xe7d5bb65, 0xd779d149, 0x07e44986, 0xce754728,
- 0x2f7773c7, 0x7dfee518, 0x7cb2beba, 0x558f88f3, 0x2dbcea4d, 0x07f6f7aa,
- 0x8ede914f, 0xbb1c5938, 0x3e78fddc, 0x611ff7eb, 0xef3e40f2, 0xf862fe22,
- 0x9989e25c, 0x3eef9e0b, 0xf85794f1, 0xb385fce1, 0xf878f9d5, 0x02398b85,
- 0x77dfafde, 0xc9d924e8, 0x6e3c1cf0, 0x831b6d8e, 0x68ea657d, 0x0acc6bf3,
- 0x4d92f531, 0x6cc13fbf, 0x9f218fbc, 0xfc8bacfc, 0x5d89eb11, 0xf9421f5a,
- 0x9eb6e292, 0xb1d9772f, 0xe2df454f, 0xb8b36f42, 0x8ec9784d, 0xcb0a73d7,
- 0xa15cfa5b, 0x44bcc38d, 0x599b963a, 0x76afe73c, 0xbba7648a, 0xd482f6d0,
- 0x04a59ad7, 0xeb8e3f36, 0xe4dbd76f, 0xd65ec947, 0x4199507c, 0x3be76ffd,
- 0x957d6837, 0x6ba64f9a, 0xf09d39f6, 0x64de1f13, 0x358a5796, 0x4dec4afa,
- 0x3321d53c, 0xf9d5e140, 0x788f3681, 0x8fd66dec, 0x775717fd, 0x1c70ea99,
- 0x00001c70
-};
-
-static const u32 usem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33a98f8a, 0x32e8f430,
- 0x31e8a430, 0x43d4dc30, 0xcf12d388, 0xbf4ca2e1, 0x83030b30, 0x038b1028,
- 0x7f1024b1, 0xf8606463, 0x7ebc48ce, 0xbb04115e, 0x81818045, 0x070fc80f,
- 0x1905ffd2, 0x330b3e18, 0xf903f030, 0x6dfc80b3, 0x88087c40, 0x376280c3,
- 0x2067f480, 0x02c40fbe, 0x17cdf822, 0x417f2024, 0x07ff9508, 0x1042ff8d,
- 0x61637ebf, 0x0496f2fc, 0x4de1b1e4, 0x0f8cdc04, 0xef40a77f, 0x6a87e040,
- 0x557d7ca8, 0xa02b0606, 0x843a8758, 0x7e4908ff, 0x40cc5016, 0x93e6c215,
- 0x05506067, 0x61ab1ff2, 0x281f9737, 0x5f9406af, 0x00073506, 0x15e5ac6f,
- 0x00000368
-};
-
-static const u32 usem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0x45147809, 0xf4f570da, 0x73264cf4,
- 0x10909264, 0xa70930ae, 0xe15c380a, 0x1084ca30, 0xa8ea2416, 0x1388a888,
- 0x2e421081, 0xf57175d1, 0x11c3a7fb, 0x9e375941, 0x1d47facb, 0xa22cdc10,
- 0x60188806, 0xb200c1c0, 0x1761bb8a, 0xc363d715, 0x01921a0d, 0xe5c58f15,
- 0xeaadf7ab, 0x44ceee99, 0xeff3eba2, 0xe3fdfb7e, 0x575453e3, 0xef555bf5,
- 0x5dbd6f5d, 0x71024a31, 0x02e426f6, 0xf211c6fc, 0x4908488c, 0xe36d9689,
- 0x1749c7c3, 0x92cde442, 0x8840ad6b, 0x343dbaf0, 0xfb21046e, 0x33010956,
- 0x587687ad, 0xd3f5a109, 0xcc07d735, 0xd43eb419, 0x9afac1ec, 0xbee7ac1c,
- 0x48c3aefa, 0x8aafa5eb, 0x761ba846, 0xdb34729c, 0x37372908, 0x7d05723d,
- 0x24557e1e, 0xc450e9ab, 0xb240c535, 0x471e3908, 0xad196fd8, 0x685212a7,
- 0x55d2d561, 0x3cc2673b, 0xc4cc1a8a, 0x6e94e142, 0x15ed7b99, 0xaf773eb4,
- 0xe94ba044, 0x77534ada, 0x10179f5a, 0x68bea0ea, 0x4e3887c7, 0x545278db,
- 0x4f908837, 0x35c471fd, 0x4d1dd680, 0xe7d137a9, 0x130d81c5, 0x7af17fa1,
- 0xfda06dc1, 0x7e766b8b, 0xeb8bf004, 0x8522bea5, 0x4ad6bf3f, 0xd8d9035c,
- 0x63ac0817, 0xdf30b5ce, 0xc4483fd2, 0xe745eb4c, 0xc01136ef, 0xe4dab191,
- 0x8ff8c3b5, 0x18765c9a, 0x51c716a7, 0x7bfa59f0, 0xaf7d0e3a, 0x0dc165ec,
- 0x10332b4b, 0x75a7cc1f, 0xf3fa658b, 0xa5575836, 0xbfbc3fa9, 0xf41341e5,
- 0xd8281b9b, 0xfcc1716c, 0xc2269956, 0x99566b3c, 0xe145070a, 0x517dafcd,
- 0x2be3af33, 0xa9f574fb, 0xa7e5f5da, 0x735a8a7e, 0x884c5eb4, 0xf306cea7,
- 0x1fae980e, 0x547e7d1c, 0xcf7a4448, 0x2b8915af, 0x529f0a2e, 0xefcb9f1e,
- 0x1f027fd2, 0xd607b76c, 0xb5e94466, 0x8eff09c0, 0x93acebd2, 0xce18cfd3,
- 0xca57c352, 0x740e8047, 0x277ed53e, 0xd3f98f96, 0xefc27cb0, 0xe53dbc42,
- 0x4ae5881f, 0x3f9f1bbf, 0x658d1fed, 0xe583df8d, 0x5849feb3, 0xec5efc06,
- 0x1d3fdab7, 0x1f7e35cb, 0x5fc17f3e, 0xbfad6584, 0xf3af9f02, 0xbd72c42f,
- 0x2fe7c65f, 0x596197fb, 0x72c6afe7, 0x96257fa3, 0xf600fef5, 0xd7e9ccdb,
- 0xe7c3afe0, 0x580dfd5b, 0x2c21fd06, 0x62f7f877, 0xd5e382b9, 0x8c724d91,
- 0x0f0e2f14, 0x20715271, 0x1c9ef949, 0xbc93d689, 0x433a9eac, 0x7ad131ce,
- 0x29d68faa, 0x8497ba9e, 0xdeb4cc72, 0xa7b582bd, 0xc7c6403f, 0xccba7ad1,
- 0x785733da, 0x3d685bc6, 0xf7b59ab3, 0xc7c791af, 0x00ff7ad3, 0x7d74bf6b,
- 0xd695bc68, 0xed63ad2f, 0xd7248243, 0x4243eb46, 0x9f6c3eac, 0xeb4ed727,
- 0x3d589ac3, 0xd73923eb, 0xcd59eb41, 0x2db1fdec, 0x5a04dca1, 0xed661b1f,
- 0x166f9d57, 0x67f8315d, 0x459be4b3, 0xf2032d28, 0x1bb18f14, 0x777c9bad,
- 0x97c53713, 0x1c63d53c, 0xc923f143, 0xbe4bbed8, 0x4c1bdb1d, 0x27bfb632,
- 0x56fb6217, 0x27ed8029, 0xdf6c72e5, 0xfb600a6a, 0xac42f2b7, 0xb610a507,
- 0xb12b2adb, 0xc214d07f, 0x87caf4f6, 0xd4877db0, 0xcaeeed8c, 0x877db1c7,
- 0x1fdb19a9, 0x99e3525b, 0x0b0feb40, 0x2f81a7be, 0x22be0b17, 0xadf807d2,
- 0xf94bcd2e, 0xd3204aad, 0x0117bf81, 0xaaf6d253, 0x47d4266e, 0x7ace3f9b,
- 0x6f38145e, 0xe17a8176, 0x20650f0b, 0x8e11e79c, 0x1788e144, 0xc9f59387,
- 0xac9c0d68, 0x38148a4f, 0xa58e11eb, 0x7f367073, 0x9f3b5632, 0x38158a4f,
- 0x149192af, 0xeb73bd8e, 0xb65bfaca, 0x2b7f3e76, 0xc0ece051, 0x6e7624f9,
- 0xb4c70d3e, 0x163869f8, 0x389bcfc1, 0xcdce949f, 0x2d71f467, 0x8f1f467e,
- 0xe109a7e0, 0x9c1ceb74, 0xfc5ae386, 0xe08f1c34, 0xd38403e7, 0x1aeb73ab,
- 0x9f8b427d, 0xf82227d1, 0xc9f88c39, 0xad9c1ce8, 0xd9f8b5a7, 0x9f823a7a,
- 0xbf4e10cf, 0x6c6badce, 0x633f16ab, 0xf9f8235b, 0x4975d702, 0x6d6ce0e7,
- 0x6b67e2d5, 0xdf3f046b, 0x9dc19c21, 0x36d8d75b, 0xb6c67e2d, 0x1263f045,
- 0xced0ce00, 0xa5f827cd, 0x2fc13f16, 0x4049f823, 0x373b2338, 0x5a73ec9f,
- 0x8b9f64fc, 0xe10d27e0, 0x9c1ce98c, 0x7e2d39e0, 0xf822e782, 0x573840c9,
- 0xd95d6e76, 0x93f1695f, 0x3f0455fd, 0xf7400a97, 0x421f3e1c, 0x863bd8e1,
- 0x2d3be3b3, 0x177c767e, 0x9c70cfc1, 0xcf9f1e4f, 0xf55ce045, 0xae7e2d0f,
- 0x3f0447fa, 0x726708d9, 0xf8ece0e7, 0x3b3f1687, 0x4fc111fe, 0x9aebae1e,
- 0xaaebadce, 0x5cfc5a0b, 0x67e18175, 0xdcbad1d4, 0x6d4eda04, 0xafa45ba3,
- 0xf1ef3b8c, 0x3a2eb408, 0xba745d59, 0xa22df809, 0x26908fe2, 0xb7df488f,
- 0xf61c4fad, 0x25fb5110, 0x75826fe3, 0xa697a9d9, 0x46124bf6, 0xa0fc6bc7,
- 0xa6924f44, 0xbba93c9e, 0x378a7fa6, 0x75ded353, 0xf69aa5fa, 0x9a61be6e,
- 0xb1a28f7a, 0x2abdfe9a, 0xbdea6bc6, 0xe9ad5e17, 0xa0df219f, 0x7659f7a9,
- 0xbf7fa6ab, 0xed353bea, 0x6b165603, 0x2c092fda, 0xab2fd4d0, 0xffa6a5fd,
- 0x9a45bae0, 0x1e1bcbf6, 0x0d0fb4d2, 0x0fa9a63d, 0xa6b4fbdf, 0xd5a6c8ff,
- 0x0751f69a, 0xc7da69d7, 0xd4d46f34, 0x55b938af, 0xf0caffd3, 0xb8fa9a1b,
- 0xf4d2dfaf, 0x1e7394a7, 0x45d78cbf, 0xfb820b90, 0x099bb902, 0xdd90c5fd,
- 0x77537584, 0xd827db1b, 0x29475d0b, 0x9f064ddd, 0x812d0bab, 0xfdda84e6,
- 0x0345ee9c, 0xdc5f299a, 0xc037d63b, 0x6bdf9f49, 0x8cee5df2, 0x7e509fe1,
- 0x941a4811, 0xfa94032e, 0xc62507f6, 0x9c7be3af, 0xbe887fef, 0xf7086e5f,
- 0xbff5a44f, 0xc002721b, 0xd4082fdf, 0x157ca7eb, 0xe80a922f, 0x1e266f17,
- 0x3307dfe0, 0x55979eb2, 0x17acbcfc, 0x0a215395, 0x4be49977, 0x5d643f03,
- 0xf832bbe5, 0xe8bd5529, 0xf213baba, 0x486ef0a2, 0xefdf4bee, 0xa3e69855,
- 0xea26ccf0, 0x37c7abe7, 0xe107f1d1, 0xcfc075f8, 0x94fc619b, 0x339be3f6,
- 0x8fc66b47, 0x8cd22f4b, 0xe3a2671f, 0xafbea93b, 0x4f8f98fc, 0x90963289,
- 0x38c7c26d, 0x08bd39be, 0x44d07fc7, 0xf1ea3df7, 0x87e323e3, 0x3a7bfd60,
- 0x58e67f5a, 0x8bd3faed, 0xb137ebb5, 0x7955bff5, 0x8f1f8f8c, 0x385b7feb,
- 0x5e9fd6c6, 0x666fd6cc, 0x3be32370, 0x826ff822, 0xd1d7bff5, 0x6b64fbfa,
- 0x44bbdfd7, 0x1b337ebb, 0xa795afff, 0x1c36f8f9, 0x34e143ff, 0x12ef7f5b,
- 0xf664df1c, 0x4c7f81b9, 0x022be23d, 0x93d27c74, 0xc0aeae2a, 0x281c742e,
- 0xa6512607, 0x2149e427, 0x6f71e713, 0x73b7e33c, 0x50df94f1, 0x9cf8c91f,
- 0xa3e6a804, 0xce329cfb, 0xe7d7f3fb, 0x616f4098, 0xccefdd3b, 0xdd9d53e1,
- 0x937f2220, 0x7e81cc27, 0x0dadbe74, 0xd9f50ca2, 0x00195c4f, 0x266e58fd,
- 0x3de17877, 0xf3c10923, 0x5e0e4f63, 0xbe975ead, 0x1d2d539c, 0x17c8d66f,
- 0x9e3c8f9b, 0xf3a0ac0c, 0x182603cb, 0xa71fad19, 0x98d829fb, 0x12fba61e,
- 0x74484f28, 0x28fcfa3c, 0x01916fdd, 0xc4a9b96a, 0x79ec88f7, 0xff9d2fb7,
- 0x3cfca234, 0x51dbceb8, 0x233c28a4, 0x1af1ffc3, 0x98f40021, 0xf9f74d53,
- 0x372ff92a, 0x170ef933, 0x02d58108, 0xff7d2bc7, 0x813efe66, 0x33f851f9,
- 0x8f9dec9d, 0x47b35c77, 0xedfdd070, 0x9c0d64ca, 0x6960485b, 0xb6ff7d1a,
- 0x62253b15, 0xe828be00, 0xe5f800b5, 0x7084897e, 0x429cda9f, 0xa0667106,
- 0x064e7df0, 0xd2e9e6ff, 0x9c1566d1, 0xc79c5299, 0xf333e74b, 0x7be7113e,
- 0xdedb4f8b, 0x31eac3bc, 0xcae5a10c, 0x494225cf, 0xb6915b7e, 0x6d0af6fd,
- 0xda858efd, 0xee0f5d3a, 0xfd640bf3, 0xba1cba73, 0xeb233bce, 0xf5a70ba6,
- 0xd66dbc59, 0xd0d64932, 0x4d736e91, 0x133dbc59, 0x4f104ed0, 0xf69f7ef8,
- 0x681f29fd, 0xea5773ea, 0xf8be71e0, 0xdffff4ff, 0x86f2ff4d, 0x5547c59c,
- 0x9bad2af3, 0xaaa8f8bc, 0xebdafcdf, 0x8179f535, 0xe7fd345b, 0xb4d02cae,
- 0xa79ea9cf, 0xecb59f69, 0x40bd4d2e, 0xffd34fbe, 0x9a95858e, 0x962bdbf6,
- 0x2b6fda6b, 0xbf53547a, 0x4d5bf7c5, 0xafa79bff, 0x3b0bb4d2, 0x466ef5e6,
- 0xddebe9bb, 0xf4fe928d, 0x7c026607, 0xc2b3f0a6, 0x69fd27ef, 0x77ea7e58,
- 0x7a095961, 0xc377ea98, 0xaf965616, 0xfa0de82e, 0x13ffe15c, 0xe83a4552,
- 0xeb3f3d4b, 0x4f9eaff5, 0x2c47afe9, 0x4b29433f, 0x3b05e204, 0x64fdc6d6,
- 0xdc37f9e5, 0x0ce782ce, 0xc9898965, 0x6ec6c965, 0xea0389e3, 0xb615fea1,
- 0x3a92e18e, 0x2041d701, 0x74029a4a, 0x976d41eb, 0x347dae9a, 0x29d96cf3,
- 0x2065f8e2, 0xdcc06393, 0x60187778, 0xfa6350fc, 0x3e61838d, 0xdeb1d79e,
- 0x56fe8290, 0xe2d27f8b, 0x7f00fda3, 0xfa4f2c5e, 0xdc7963a7, 0xa8f2c3ef,
- 0xc3cb08bf, 0x9b2c0afe, 0xfcb10bfd, 0xf9632fc4, 0x96197f91, 0x6357f57f,
- 0x12bfd079, 0x01fcf7cb, 0x1efd5b2c, 0xfd3e152c, 0x18eba14f, 0xae9cbfc3,
- 0x3ae9a8df, 0xf364e0c6, 0x187d74e1, 0x6fc31be6, 0xc8ce0fee, 0xe23f9548,
- 0xdb718c99, 0x4ece3c05, 0xc71624c8, 0xa62f63e5, 0x6fd09ae0, 0x3d040c09,
- 0xb7e0767c, 0x7d4e21fd, 0x4a2520f6, 0xd3ebc746, 0x3c43afd3, 0xeffa0f10,
- 0x974a0185, 0x96edf6e4, 0x8b578678, 0xc3224c81, 0xefde5908, 0x839df705,
- 0x49246eb0, 0x7dc07ef0, 0x5c063dbd, 0x7e020bea, 0xc5d7862f, 0x004373f6,
- 0xffa7f1de, 0x18e5059e, 0xe307f303, 0x4bf4451b, 0x3779e849, 0x67a237e0,
- 0x8834eecd, 0x99fb86f7, 0x9af7689c, 0x4fe2d6ae, 0xbf835abe, 0x55fc11e5,
- 0xfafe21a7, 0xc28ffb9e, 0x8784f11f, 0x8a3830dc, 0xef846fbf, 0x1e729fc7,
- 0x36ef1fa3, 0xf883f8d1, 0xc1552db2, 0xa13a536b, 0xf811fce3, 0x5b3fc29f,
- 0xf001203f, 0x1173811c, 0x7faf08fa, 0xe8fa0e9c, 0x16c9d034, 0x0e9f7785,
- 0xcfbdd9de, 0x5fefc03b, 0x47ca2690, 0x2959e063, 0x6432eb4b, 0x6a4fda9b,
- 0x56cfd6d0, 0xd0ea930b, 0x4c25719f, 0xd7fa0c1d, 0x40951f29, 0xa961a64f,
- 0x669059c0, 0x7d2871c2, 0x4faf5c98, 0xd4ffb944, 0x7efd871f, 0x047479ea,
- 0x7a8f3a27, 0x0fbe8472, 0x4fa17f2c, 0xe43bfdc7, 0x2617e353, 0xa091b388,
- 0x97fc0e74, 0x05fffa38, 0x46237838, 0xcb702bac, 0x7cd944eb, 0xaf5f3c39,
- 0xe7be8f19, 0x2f06ce52, 0x3c9f7e64, 0x8571c918, 0xa8a9a95f, 0x48d61881,
- 0xac8b5be0, 0x35128ff5, 0x6e86f2f5, 0x825fc6b2, 0x4a3d507f, 0xf023048a,
- 0x9f67094b, 0x996da336, 0x0bf7e740, 0x3e816208, 0xd2bf5810, 0xcf9366b8,
- 0x78b2fc05, 0xe82e15da, 0xd5eb8d59, 0x2fd28fcf, 0x3c7528c3, 0xd9e2f9ff,
- 0xe431bd7b, 0xdbd72763, 0x57160625, 0x03b27120, 0x9a48d7ce, 0x8ec1b8ec,
- 0xf045b353, 0x3a3b7183, 0x0a0f0a8e, 0x2901799c, 0x995ff5ac, 0x5818b65c,
- 0xee3f40bc, 0x94dc619f, 0x6cafe38b, 0xb089fefd, 0xcb1e3d6e, 0x7c98ce1a,
- 0xbff45728, 0x151e28ac, 0xf442fefc, 0xeba459fe, 0x843dae2a, 0x9293eafb,
- 0xeffeffdc, 0xe7ed8bd1, 0x6e3b4b6f, 0x265bad55, 0x9dce304d, 0xc440f9a3,
- 0x5487f375, 0x5b7a9f5f, 0x5d010f22, 0xaa5ed3ce, 0x828f5079, 0xfea2b218,
- 0xf3f59dfa, 0x9f7ec1f3, 0xf7053cda, 0xd789b32b, 0x22ca4101, 0xfe059d52,
- 0x986269f9, 0x4d3a7804, 0xae18ecfe, 0xd139d3a2, 0xfea1f484, 0xfcf561fb,
- 0xa9aeffa8, 0x535dff53, 0xa437242f, 0xe178f9c2, 0x08091213, 0xfb4d3eb8,
- 0x7089d171, 0x2a8a92e7, 0x4b1677f0, 0xe9dfaecc, 0x541ec624, 0xf6be979f,
- 0xad01564c, 0x7f32277f, 0x9def3944, 0x377b7547, 0xb75c5eda, 0xeda1e4ca,
- 0x4f87ea47, 0xfbc082bb, 0x3fb02a81, 0x7b82abf2, 0x7e3dabad, 0xf5fce87f,
- 0xa1fc55f3, 0x7ccee776, 0x82b5a51e, 0xcf831027, 0x67c646ac, 0x30f63f0a,
- 0x8df1353a, 0x70faba01, 0xae9c7d5d, 0xbde5a3fe, 0xfbc8d10b, 0x00df442f,
- 0x6f930a63, 0xc609dfd8, 0x8ff3f230, 0x0ed69f86, 0x149ff0fe, 0x9cad4f7e,
- 0x7ee3f851, 0xdb7df852, 0x2c4a7fcd, 0xbdafa5f8, 0xfaa659b4, 0x2795f8a9,
- 0xa7ea841d, 0x54eac653, 0xc97fa537, 0xe00ea5da, 0xd9469383, 0x2a7cfc01,
- 0xc40a4e20, 0x8c8b77d0, 0x3daff702, 0x6fe20136, 0xff0a4ff0, 0x5f0f75d3,
- 0x7387710b, 0xc627256b, 0x21cd6ad5, 0xb2d39533, 0x64f979fa, 0xb10fd608,
- 0x446783fa, 0xf96837a8, 0x4f77f8b3, 0x5f50baa6, 0x180c3dca, 0xffa10e3f,
- 0xd8e6b65f, 0xe5fbb044, 0xa6728c24, 0xffc60f7f, 0x53ed093a, 0x7da12981,
- 0x53e46e3b, 0x2bf67de1, 0x8cf87faf, 0xf27280e8, 0x7427d009, 0x03f184e7,
- 0xdc457bfd, 0x68dbbf9f, 0xf3f182ef, 0xe8146451, 0x242f0531, 0xf179fcc0,
- 0x408667b5, 0xcd65b51c, 0x85410edb, 0xcede452f, 0x6e7acdd6, 0xbd63abab,
- 0x51e54ad9, 0x7e2a47ed, 0xef81ab85, 0x2cac8243, 0xc80e4291, 0x255929ab,
- 0xb8fa65b9, 0x5fe7a5e4, 0x9ae21a78, 0xfddd981f, 0x2ff9fc28, 0x2c6f7eed,
- 0x20dfcfad, 0xcb67c975, 0x51a909b0, 0xffd394fa, 0xd28b0e17, 0x6ed378a3,
- 0x7b306b93, 0x945240fe, 0xec37f32e, 0xedc19134, 0xb75b91f1, 0x8b6cd4d3,
- 0x43ba9f41, 0x130fc113, 0x04cefb5f, 0x43b53ff4, 0x62335d20, 0x6ed573e0,
- 0x4f00d3f4, 0xaf4e4f48, 0xfd74fd08, 0x405d29cb, 0xa5e9ebaf, 0xf41537ef,
- 0x0b830a4b, 0xbf9412f9, 0xf90ade5f, 0xbb357f48, 0x2f450f01, 0xf580eddf,
- 0x3056309c, 0x69667f3e, 0x5f8e87aa, 0x4ea9c924, 0xa2f3d92c, 0xfc8e7f67,
- 0xcfff7737, 0xcb5c5953, 0xb680cdd3, 0xeb06ee4a, 0x1373539c, 0xf890b3ae,
- 0x9e8b0f90, 0x2fa0bd11, 0x499234bf, 0xc9c8621b, 0x4e4e5cb7, 0xa5c4a6ac,
- 0xcd413ceb, 0xfce9e610, 0xc5ac0c59, 0x185dfa38, 0x5f39fb37, 0xb0e8f50b,
- 0xa31c65fe, 0xc0d19357, 0xeaf52ef5, 0xe6bbfcd5, 0xd3a026c1, 0x5d3cbda7,
- 0x9ca5fce1, 0x0f8e6518, 0x2b8502e1, 0xcaebcfee, 0xc65c44e8, 0xf51efe2c,
- 0x39e172cb, 0x3c926ff4, 0xf79a2196, 0xe88c85c8, 0xf1f0f7f8, 0xc1e3bce9,
- 0x1a913a9f, 0x40305f7b, 0xb502ec52, 0x533e2aeb, 0xff933bc9, 0xbc99cb35,
- 0xb81ff22b, 0x7fb4127e, 0x11c98071, 0x92f607bc, 0x15d42bce, 0x154e77db,
- 0x49983f50, 0xaf9c9628, 0x6b9cb891, 0x42fcf5db, 0x12146fe7, 0xe3037c54,
- 0xd01d2124, 0x827c2a9f, 0xa3d2afbe, 0xa3ae30e5, 0x8e455c3d, 0xf07d72e7,
- 0x6b03e825, 0x1a901f54, 0xf63a07a6, 0x53c4657b, 0xe1781489, 0x2a5f9069,
- 0xe40bb2af, 0xfac2f257, 0xf8df5b3f, 0x6e54adde, 0xe453ab3e, 0xf557ab56,
- 0xf1b45b72, 0x54f804e7, 0xf59fb72f, 0xe53120ac, 0x298f3e96, 0xff9b3db7,
- 0xc1557a25, 0xd5a4ba63, 0xec9e8aab, 0x3d7a9f08, 0x42e8c5b9, 0x24f5eabc,
- 0x59201dfd, 0xe151f9ed, 0x8aff8543, 0x0ded2c5f, 0xa7c228fa, 0xf8461f0a,
- 0xfd43e154, 0xd478b5ba, 0x9e7c63b7, 0xcb778bf2, 0x507b13bb, 0x050496ba,
- 0xef85d9b7, 0xc53a81ed, 0x0b6d8797, 0xe8f4f7aa, 0x7407aea2, 0x7f5d3af5,
- 0xd5eeae8f, 0xeae9f7f5, 0x01feba15, 0x68694fb6, 0x87e41134, 0xb4bfa690,
- 0x9f90c888, 0xe22ede16, 0x9d1b41b9, 0xbf7d1573, 0x40467d6d, 0xa961faa6,
- 0xc3dbed85, 0xd02aa629, 0xb0ce6d67, 0x16ea0923, 0xf36b7f16, 0x2a891d86,
- 0x5050f1ff, 0x1cdc7d44, 0xed629320, 0x8bc7a85f, 0x1d266bf4, 0x90f3b3b5,
- 0x10c778b6, 0xb44f2f18, 0xf8842fa5, 0x86e8b54c, 0x95d98e23, 0x5ce03b37,
- 0xe7d82da2, 0xf9f4e9ba, 0x2c883f9c, 0x18f6422d, 0x0df6a9bb, 0x54fc8927,
- 0x95f900b6, 0xb3fe902b, 0x311f6c82, 0x7e6c457b, 0x15efe62e, 0x8131eeda,
- 0xfffea4de, 0x5f5c7561, 0xa3545381, 0xc29c1e7b, 0x2fed9ef9, 0xdb68d78b,
- 0xfa3f7c7d, 0x0fdf0a5f, 0x7ed94325, 0x0838b090, 0xe279bbd7, 0x53a6eba0,
- 0x15edb43a, 0xd9cdf009, 0x387488a0, 0x40085ebb, 0x29c88a5c, 0x24653f28,
- 0xc14efa8c, 0xc7c80b57, 0x50f58e80, 0x671fabcb, 0x94bb4fdd, 0xc870fe6c,
- 0xcb65a5ff, 0x6ffa0fe6, 0xef6bfa83, 0xda487fa7, 0x61ddcff7, 0xb6df73c1,
- 0x27cc761d, 0x4efedb6e, 0xdf50fdfa, 0x3cc37662, 0x357c76db, 0x6da8f804,
- 0xf408b991, 0xb62f5b58, 0xfdbc59ff, 0x68cd21ab, 0xfd20973f, 0x8b13256a,
- 0xfeff04d7, 0x4a05d089, 0x0ff02aba, 0xf9727e78, 0x20804b56, 0x7cb2affc,
- 0x3d6e9fb6, 0xbf9cfc65, 0x6fa64ecd, 0xb225f984, 0x6df2ec73, 0xa4af9e63,
- 0xefd697e3, 0xeda2cd34, 0x377fafb9, 0x3791f304, 0x55a7bf32, 0xce167e6a,
- 0x6f4937b1, 0x9e28922e, 0xba38415b, 0x299d7213, 0xc5b6572e, 0x1877cbc2,
- 0x3e2cea97, 0x7ed892de, 0x1f1fdff4, 0x9511e602, 0x3881ed04, 0xcdfdd601,
- 0x3e821f27, 0xbe4661d8, 0x59fbd654, 0x23fa255d, 0xa9f75b17, 0xd07c31ff,
- 0xa10b75d9, 0xce3bacce, 0xeebdeff4, 0xce172447, 0xed072f4f, 0xbdfb7cf9,
- 0xeec97f58, 0x9276f9c6, 0xfe9a07df, 0x237df8c3, 0xe2e3bba5, 0xbfd9feeb,
- 0xa63bbaf9, 0x72661ffb, 0x1f213bba, 0xeff5fcac, 0x543f7e70, 0x1ffdcdcf,
- 0xbf8af7ca, 0x9b78366e, 0xa6fce872, 0x383b6a93, 0x9ca4b716, 0x73a907dd,
- 0x745f5ee6, 0xfc4af981, 0xbf3f51fc, 0xefb62695, 0x997ce093, 0x126e4b8e,
- 0xed8f7ef8, 0xfee5ae93, 0x0b3db5c5, 0xd6bd2fd1, 0x6277fcc3, 0x46737af4,
- 0x6cd89e40, 0xc943c637, 0xa83e83b0, 0xaf2574df, 0x7f8bf76b, 0xa0478814,
- 0xe9b5f9fe, 0x9f82f693, 0x634f5d7a, 0x43caccc8, 0xe0ebbe50, 0xf76b47cf,
- 0xb4f8b733, 0x6ba79bf5, 0x787137eb, 0xa2b9c0d3, 0x0af34fe3, 0x4a7f8801,
- 0x81489ebd, 0x4734a878, 0xf9008222, 0x614b1524, 0x579370df, 0xb03dfefb,
- 0xc5191dcf, 0x82b8bce3, 0x114e70f9, 0x7c405037, 0x4442b75c, 0x4837127d,
- 0xd1def840, 0x1e1de612, 0x00b37833, 0x47c3f9cf, 0x8192fd95, 0xe77ac373,
- 0x92157c71, 0xc877f40a, 0xb2170bf9, 0x4bee20b3, 0xe79a5fd0, 0xea1ae421,
- 0x0b6617b7, 0x63c878a1, 0x61391231, 0x0543c418, 0x0f135872, 0x77e1d6d5,
- 0xce146a55, 0xc477fac5, 0xf9753f8f, 0x87ffca37, 0x433fea25, 0x2cf3e789,
- 0xb3eca7ae, 0x3c3208ee, 0x81089796, 0x90abe44c, 0xb0cf3ea4, 0xfdff1999,
- 0x28e181ed, 0x1ebf3957, 0x7ff6c09c, 0xa0bbf023, 0x9e67ee72, 0x10095d95,
- 0xec1b38f7, 0x72d1cfc3, 0xfc18be1d, 0xbbef9fbc, 0x007902fe, 0x209b6cb4,
- 0xffe08b54, 0xfbc63093, 0xb21609e4, 0x5cbe4636, 0x8739498b, 0x207dc0af,
- 0xa02cc4fc, 0xa5cdfb23, 0xa92426af, 0x9ae2b6e8, 0xed21c653, 0xc3bf00e9,
- 0x7e4bce31, 0x3cfb096c, 0x4b7eebc0, 0x8c6f44f3, 0xcb83fef5, 0xdf1bfe6f,
- 0x376377e0, 0xc0243304, 0x44130dcb, 0x39eaf9cd, 0x87e3f713, 0xaf30e193,
- 0x3b2637fc, 0xf65d00c6, 0x4ef86e8a, 0xc6783cac, 0xce718be4, 0xc027c7a4,
- 0xc90073c7, 0x3cf8085d, 0x810b2bf2, 0xfc3bd6fd, 0xe41067dc, 0xadc20f61,
- 0x4ce207bd, 0x0b8b3366, 0x713b30cd, 0xe7e6379e, 0xdc742948, 0xa1cef541,
- 0x9dd5f470, 0x46019ff7, 0x5124246b, 0x7e94f7b0, 0xbf584bdd, 0x59672643,
- 0x113ff5ac, 0x733ae2c7, 0xd1defb89, 0xdd1fbfc2, 0x0f6d7e72, 0x327b078d,
- 0xd8e77d81, 0xca09af9e, 0x4249d9c7, 0xec3df400, 0x2f9eb09f, 0xc779bda0,
- 0x1be5dac0, 0xf8565e98, 0x11e78f5e, 0xf8cacf1c, 0x0c7d7953, 0xcf052f97,
- 0xf3f57e0a, 0x7d53fa55, 0x8f1d4e35, 0xe861aeb8, 0xcb0f60cb, 0x40d38282,
- 0x9b199541, 0xe587204d, 0x104a8f0d, 0xc5c5bf8f, 0x307b52e0, 0x3bfe7d44,
- 0xe1ceccc3, 0x315d871b, 0xf3e4f813, 0xa12fd415, 0x9f667bef, 0x7ddd8071,
- 0x13fee0c7, 0xff29077c, 0xbf6b2451, 0xe87d5f47, 0x904f1677, 0x703370d4,
- 0xe496379e, 0xb93e1048, 0xd4a764ad, 0x334fc555, 0xaed849cc, 0xe25eef3c,
- 0xe9cf061a, 0xf90f3878, 0x3c813311, 0x4d7541f2, 0x6ddbfdf8, 0x0f8c8915,
- 0x9a76ea8b, 0xfd819eb0, 0x7194f195, 0x3534f2f4, 0x341f9b5f, 0x27b9b72b,
- 0x1cdf25e0, 0x831dc7ba, 0x95982f4f, 0x681f8873, 0x6f943c27, 0xb22ffc87,
- 0x7628f713, 0xaaf259a2, 0x34de49f2, 0xd9573933, 0xecb1ae89, 0x574a82c4,
- 0x82c3a057, 0x82ba7ded, 0x43f82c90, 0x3b2c6a5e, 0x9d9faef1, 0xbfcfbe2b,
- 0x4a9b6d23, 0x2ae5c4ed, 0x82d5313b, 0x6f7fa27c, 0x7693b983, 0xffdba142,
- 0x2ef37d63, 0xf21889d8, 0x4fe38bbd, 0x82d313b1, 0xa6276805, 0xdf35154d,
- 0xf3336c5f, 0x76877178, 0x16f52722, 0x6b6e4bac, 0x9779fe0c, 0xf3efc3fb,
- 0x07183c3c, 0x5cb7c5ec, 0x46edebff, 0x371d7a47, 0xa13b2335, 0x7845ffd7,
- 0x02faf456, 0x339b2fea, 0x4121f162, 0x0b705e7e, 0xf002ebd5, 0x0bebd323,
- 0x3171e76e, 0x82f59e9d, 0xd6a11d9e, 0x32fdecb3, 0xe50bb31f, 0x99bf190d,
- 0xad6fdb41, 0xb471dc96, 0xbd51adff, 0xbbd6a59b, 0x77a476df, 0xfdde988b,
- 0xfd1c383c, 0xf7d68ea7, 0x54b7d731, 0xc775f59f, 0x33e98fe0, 0x77ef9aac,
- 0x737d0c8e, 0x979026d0, 0xd73c4477, 0x80fdc63b, 0x1cdf437d, 0xe9eaf101,
- 0xbbe44671, 0xad9e9cbe, 0x813c527e, 0x36772fe2, 0xd74ba7f3, 0xb2bf888b,
- 0x65ff267a, 0x45c042b5, 0x7d8713eb, 0xfcfa8263, 0x8e7ceced, 0x473f20ae,
- 0xeff9ff45, 0x3c415734, 0x012afe78, 0x1f2117cf, 0x9739f01a, 0x3dd0b3e3,
- 0xfa2bf71f, 0xf1e5833c, 0x72e4d58e, 0xd3f18784, 0xdf3fde52, 0x72f8c61c,
- 0xf704effe, 0x1f3ed22a, 0xd5efb4a1, 0x319f60a7, 0xdcf756bf, 0x11cf1cbd,
- 0x718b5fa8, 0x6d3ad2d4, 0x4ff71e7b, 0x41a188e6, 0xf57f609b, 0xcb1dd127,
- 0x22fd29de, 0x27fa29f8, 0xe29fb3f1, 0x874fc467, 0x9dc1799f, 0xa1fe5f18,
- 0xe3e3d178, 0xbf5c7167, 0x4023230c, 0x3c198f1e, 0xb7e45fa8, 0x9923cc44,
- 0xcd3f68fd, 0x7137043d, 0xe0c779be, 0x5f3c82ab, 0x9be58cb9, 0xb0d9adcc,
- 0x67d6953b, 0x10a191d4, 0x52bb9e96, 0xf6238f6b, 0xfcc5debf, 0x020d8a82,
- 0xe1ce15e4, 0x051509df, 0x1b7bc51e, 0xed485f6e, 0x6b3fed3d, 0xe707d998,
- 0x612dfba3, 0xff0a9fd4, 0xf263892e, 0xe3cf88b4, 0x04f0f748, 0x820d53b4,
- 0x6432e513, 0xd28b7661, 0x6893ee09, 0x44d5f31c, 0x8f16174e, 0x2c746068,
- 0xb90374a7, 0xf5e4189e, 0xde0fe63a, 0xcec33c16, 0x253b82b5, 0x40852f76,
- 0xb9df5192, 0xd8acff71, 0xcb673847, 0x77d15549, 0xffc621fb, 0x3e37056b,
- 0xfeffd008, 0x4076fa19, 0xe99fc557, 0x3c157d2c, 0x79d1d12d, 0x7f29a5bf,
- 0x08d79e38, 0x23a7bc6e, 0x0be78898, 0xbdd9ab47, 0xfe718f13, 0xec05cbd7,
- 0x60f7d43f, 0x87130f5c, 0x1649d37c, 0x71c3ebcc, 0xa67f9933, 0xd6508efd,
- 0xd0fd01e4, 0xd272953c, 0x34597e84, 0x34e7ccbf, 0x249fdd83, 0x5f79b518,
- 0x9ffb9461, 0xdfdbfe00, 0xc5a49f07, 0xdbb97da1, 0xf6369ec9, 0xf4191132,
- 0xf90932fb, 0xeb8366e8, 0x2fd06cbd, 0xe404490f, 0x237df3e3, 0x05d19fdf,
- 0x8fe445da, 0x97867782, 0x80a48841, 0x829126e5, 0x3a5d98fb, 0x2bffc7c2,
- 0x019ed7b5, 0x83f0487c, 0xf80189fd, 0x7baa6cae, 0xe20b9e67, 0x2ff62326,
- 0x1bb1f385, 0xbdef9d73, 0xce5c7407, 0xbc395bee, 0x69f7172c, 0xa025df77,
- 0xf4a41d9c, 0x4d373802, 0x3def78cd, 0x97dbbf3a, 0xd739e0a5, 0x34ca4f0c,
- 0xb19af738, 0x68bb744f, 0xd9d759bf, 0x364e706d, 0x7c48a065, 0x4edcbc2a,
- 0x334e309a, 0x9baee2a3, 0xa88a4e40, 0x547b843d, 0xf3fb828a, 0x46bd42ba,
- 0x65cbf7c0, 0x9d2ba99f, 0x33cad35f, 0xfc7411a6, 0xd00fda42, 0xfac35e5d,
- 0xdc11af95, 0x185baa90, 0x64f5147c, 0x2f011ae1, 0xfea268aa, 0x1b831c6f,
- 0x9b70a388, 0xb4fbe86a, 0x07de173e, 0xa7126bb8, 0x395679c1, 0x3fbe279d,
- 0x25cf12ba, 0xb47be90b, 0xb9ad3499, 0xabcde10b, 0x6f7c0811, 0xe33a3454,
- 0x6f00d191, 0xf686e49f, 0x16fe77f7, 0xd2664af3, 0xf851baf1, 0x3ce6c4b3,
- 0x2fddab8c, 0x93bef138, 0xee517dd9, 0x91dcb8da, 0xb9d87d81, 0xef9440b4,
- 0xfcea8c7e, 0x96164184, 0xb0b85d07, 0xd5d60ab2, 0x1864a72c, 0x98ce9f90,
- 0xa51f8ec0, 0xff51f6f8, 0xe58988f5, 0x47ca343d, 0xfd2acd4c, 0x07d2d939,
- 0x437671e5, 0x3999ea0e, 0xe7e78bc4, 0x8fe64abe, 0x096a5a1c, 0x4987e008,
- 0xde7874ce, 0xcf8cd4b8, 0x76625f5b, 0x3357b5a7, 0xd44f43c6, 0x87be0448,
- 0xe7d35c5a, 0x89e3a029, 0x139e12f5, 0xa848cf8b, 0xc4bee6cf, 0x358d64e2,
- 0x5a89ee0c, 0x9f72dfa6, 0xe82269b9, 0x956bb9ed, 0x1ead6573, 0xa315742b,
- 0xc2c67a9e, 0x5f5e92f4, 0x5154f5e9, 0x76d8aaf5, 0xb1899ee8, 0x2acf50ed,
- 0xc0ecaf16, 0x9b13973e, 0x4186a7a2, 0x6941495e, 0x812b99af, 0x89676f9f,
- 0x2da14dde, 0x76093e5f, 0xf78ec4b7, 0x9d199503, 0x3f8c094f, 0x19ffe808,
- 0x825f0dc1, 0xb0cd143c, 0xc73ffde0, 0x47201e81, 0xdcf1922b, 0x805030b3,
- 0x2ef25778, 0xf2d4aee7, 0x7dce72bb, 0x1e244f8b, 0xb22afdb5, 0xdfaa8f12,
- 0xf945fffb, 0x47738e96, 0x08b01083, 0xe7b43f50, 0xeeb023e7, 0xe42d79c4,
- 0x3b0ac1fe, 0xf7fbf5f2, 0x7c0a599d, 0x8101f33b, 0x644edf80, 0xc3d8155f,
- 0x0b8295b2, 0x1f73b3e2, 0xa5cfef60, 0xdfbcc3ef, 0x2fe32dff, 0x902ee7ca,
- 0x479ab283, 0x35ff60f7, 0xbfe00b82, 0xfd00aabf, 0x24592289, 0x10e6bed8,
- 0xbda823ee, 0x46a3fcc2, 0x39054c59, 0x76625b28, 0xc2b779c2, 0x1e7f0a4f,
- 0x9351dfe2, 0x1b90f738, 0x00e77be9, 0x14be0c48, 0x7b110ba7, 0x2e53fc0a,
- 0xf43b7e33, 0x1106e492, 0xb27f38b9, 0xfe1567ef, 0x46ff8113, 0xb1aff944,
- 0xfc04d726, 0xe0202278, 0xf02e7cb9, 0xefe7f02f, 0xb10cf895, 0x8ba8fda9,
- 0x0f9ea7f1, 0xe51ff1db, 0x0af3d03b, 0xa8fc2a7f, 0x46c3c3e7, 0x7de60d32,
- 0xae0b52f7, 0xcb6ab723, 0xce4c85b4, 0xb7273cf0, 0x9054beea, 0xcb2342eb,
- 0x5af050fb, 0x4279646a, 0x44f5e6ed, 0x675ba9a5, 0x479ba7e6, 0x2a3d8b37,
- 0x63cb220f, 0xde71d109, 0xe63cff5c, 0x775e9dd3, 0x6ff45ae8, 0x003e51b6,
- 0x93b7affc, 0x0243ee10, 0xeb8a8fa8, 0x1be60f45, 0x3759431a, 0x4aeff6aa,
- 0x57fcc4fe, 0xe2ef88ec, 0x3e40e68d, 0xf378bf7d, 0x8e782191, 0xdff988bd,
- 0xfd013af2, 0x0f372263, 0x8a3def81, 0x438f2c8d, 0x613c17ef, 0x96f0fb61,
- 0xe0e9d62d, 0xecb509b7, 0xbae2af5e, 0x2ab3259b, 0x45b0fbbe, 0xb9e1fa52,
- 0x0ce94c8a, 0xfcc355df, 0x294af7d4, 0xbf2d1bf9, 0xdc57fc67, 0x573fa120,
- 0x15a1bb5c, 0x0f8af3f2, 0x5bbf719a, 0xf3067b5e, 0x795f738f, 0xd63fdd89,
- 0xb2f26a20, 0xd543e5da, 0x51ce788a, 0x798a5f56, 0xe78eb41c, 0x3c75651d,
- 0xe607e8ff, 0x657fcceb, 0xa29966fb, 0xdfa6fe70, 0xb09ef039, 0xfc0eb5a6,
- 0xfbf6a54e, 0xe5db13f3, 0xe72dd53f, 0x9cd74ff9, 0x631fa820, 0x0a7d3fe7,
- 0x947b80ff, 0x27fcda2c, 0x1bf4cb52, 0xac56679d, 0x7e2213ef, 0x3e5f4bd7,
- 0x2dbbf90b, 0x167b3f1b, 0x8ff25de6, 0xbc859fcf, 0x09d00a0c, 0xbaf94a7e,
- 0x51df3177, 0x85a0ef79, 0xff7e83ef, 0x6d17cc3b, 0x06ecc0fd, 0x4fdbad68,
- 0xd1ff83a4, 0x549be1ba, 0x67bd03c8, 0x77c61e7b, 0xb73579ee, 0x6f15892b,
- 0x6ff025e3, 0xaaf913a0, 0xd635ba7a, 0xc8fe6237, 0xd0774a69, 0xb6bc9113,
- 0x2f9652ba, 0x6cf9e2e8, 0x07e763eb, 0xab5fcbb7, 0x2bbaf1bf, 0x33d63f41,
- 0x79a2e13f, 0x3d28076c, 0x1d04ef2f, 0xc57cf3d7, 0x37be6bba, 0xfc34ed8f,
- 0x2bebd283, 0xf01f368b, 0xcf39facb, 0xf56d0d3d, 0xb1e61dc9, 0x3f813a85,
- 0xd1b8ff25, 0x83c431e2, 0x117c6d1c, 0x7e8107f3, 0xd7d02ef9, 0xbc43a65f,
- 0xc614a4f8, 0xbb7844b8, 0x2b7bbf19, 0xca3efede, 0xfbabeb53, 0xf097bf31,
- 0x1256e03c, 0x4d7cb1f9, 0x5f2a031e, 0x6ff96763, 0x1f900e9c, 0x73e072e7,
- 0xf8c7079e, 0xeb8fc95a, 0x6c6e2f28, 0xe38b267c, 0xd2e8bcf1, 0x3cf21f35,
- 0x84dd28b3, 0x43af40d1, 0xa8779bdf, 0x7809c1e0, 0xfbcea518, 0x18879d8c,
- 0xd1d4fbc9, 0x7a09e80d, 0x49d7923c, 0xbf213deb, 0x1fbc202f, 0x75b88f2b,
- 0x6d17cb15, 0x93dfb495, 0xf2c4e946, 0xebc64740, 0xb9d036e4, 0xad8bcffc,
- 0xa9e287e3, 0xc34bbc5f, 0x5abe0a37, 0xefd6c7ce, 0x7f85e3d3, 0xd9ab7bee,
- 0x82fbfe82, 0xfbe1e39b, 0x2643fa82, 0xf18bdf82, 0xddf2957d, 0xb5b78f12,
- 0x7f3113ac, 0x11aeaab0, 0x7f5ebbf5, 0x1473f194, 0xe38b7cfd, 0x6b2ade99,
- 0x65a3f660, 0xa3603da3, 0xd8de5a70, 0xb65d7c82, 0xf20990fe, 0x6ed4f6b1,
- 0x03bcb132, 0x3f604726, 0xb7f9aa02, 0x0873bcbc, 0x9f7e73ea, 0x859c7e91,
- 0x60f29c7c, 0xd7ca71ec, 0x338cd19f, 0x3933ae5f, 0xef1f176d, 0x66e7a353,
- 0x1369f780, 0xad3ea3f3, 0xfac52713, 0x78b6e6be, 0xababef89, 0x3b50fc99,
- 0xd93af78a, 0xa24e3dd9, 0xb2fd1e23, 0x0fa3ec7b, 0xf780fdc2, 0x47984dd8,
- 0xe792b8b1, 0x3b97fc5d, 0xd8bde80d, 0xf981357e, 0xaafc052e, 0xd392f7f6,
- 0x939fc047, 0xd423bcd2, 0xfcca30e7, 0x240c5d4d, 0xb7bf3ea0, 0xfb0aea4f,
- 0x7b946253, 0xcdae3cc2, 0x7608cafc, 0xe2cfc9b1, 0x91fce4fb, 0xc9bcf0be,
- 0x4c9ddce8, 0x104d36e1, 0x6d9a10dc, 0x7e0cf7cf, 0xd1e0ce24, 0x39095fde,
- 0xb3beb0f8, 0x89fa036e, 0x49c84376, 0xa5bb10bb, 0xb8370d29, 0xa632e22e,
- 0xe63cea62, 0x8fe43faf, 0xe7df0beb, 0x5b750839, 0xa8db9fa1, 0x61216fb9,
- 0xff7751b4, 0x97d03902, 0xe71b1fda, 0x675e2557, 0x70a6ff67, 0x875ef19b,
- 0x12a441c4, 0xdd8577d8, 0xe3c4fe87, 0x5f7e0f0e, 0x21037f46, 0xc48921df,
- 0xc1f7d5bb, 0xf73571d0, 0x3571d04c, 0xb68f44f5, 0x78c93c9e, 0x49bd9634,
- 0x2898f3e6, 0x890f10da, 0x2fee0679, 0xa5fbf27b, 0x989de746, 0x6821dc42,
- 0x7986c6bf, 0x64bc54e3, 0x366c3af5, 0xfce9bced, 0x61227a34, 0x606cb350,
- 0x773cd4f3, 0xeb809712, 0xd39f68f7, 0x7fea6af9, 0xcdf6e789, 0xefa08c48,
- 0x844d716c, 0x06acffe3, 0xde8c4bdf, 0x4cc254a4, 0x4e93cc26, 0x483fbe13,
- 0xe3a0ebe0, 0x213bfa6b, 0xd7c6c07a, 0x9d3d21c2, 0x2f06efea, 0xc6b076e7,
- 0xfa0a3dea, 0x0577ab26, 0xa766fa26, 0xc3a39e09, 0x0bb05b69, 0x85cca7ea,
- 0xad08e4b9, 0xaf8cd50b, 0x2820aefa, 0x2cc37d37, 0x892c858f, 0x1cd53f47,
- 0x30cb6447, 0xc88a1ef8, 0x251830d2, 0x5c9fcfc0, 0x94140c8b, 0x35e51971,
- 0x3c305efa, 0x128730de, 0x289a0ea1, 0x9ef143fc, 0xaafc61cf, 0x86697deb,
- 0x793cb0a1, 0x946caee9, 0x62204bda, 0xeff4a868, 0x4b257bde, 0x9f7b81f9,
- 0x0ddfec88, 0xa95ab876, 0xdf0ec553, 0x47c7576b, 0xaa389eea, 0x5933abef,
- 0xbfd8785d, 0x424f5974, 0x0af04b1e, 0x7107d056, 0x3cf14bce, 0xeb84942c,
- 0x517d98bf, 0x4d7039e6, 0x11f8c4f3, 0xf70a9e2c, 0x47b3f68a, 0x7b46c7be,
- 0xd4a6d6bc, 0xf0bfb843, 0xbd47efd6, 0x1fb75a56, 0xa7500ddb, 0xe6e4ef65,
- 0x29123d89, 0x79d5ac56, 0x5f809769, 0xa066905b, 0x5ac4bceb, 0xc1a8dbbd,
- 0x3c1a13c3, 0xa63d1718, 0x3f63c3c3, 0x3c970f08, 0xa1e218fc, 0x7ca6ebb3,
- 0xe94ad031, 0x80c72537, 0x3a8d37f7, 0x0bf8c368, 0x1ed059fd, 0x3aab3871,
- 0xd9568ef8, 0x6e3850a7, 0x97f0a380, 0x57c29ef2, 0x1f4df11d, 0xdd94bce2,
- 0x9fe5a7eb, 0x0c67ab02, 0xf56b1bc0, 0xe0a5b31c, 0xeebbf1fa, 0xef02be29,
- 0x5f28e484, 0x386f9b13, 0x635c277c, 0x55bc73bd, 0x929daf15, 0xa4cc40b3,
- 0x5905cdf3, 0x4f5d1918, 0xd2d942ca, 0xc533ae9f, 0xec3cc063, 0x126fab1a,
- 0x1e98e38c, 0x48f5510e, 0x70df005d, 0xa38e8c41, 0x76d547c8, 0x2aaf8fb6,
- 0xb1160430, 0xe00160f3, 0x59a3f945, 0xc6611fc7, 0x90870d1f, 0x8782ca3f,
- 0x54347f18, 0xe7e78f8e, 0xae8fb06a, 0x40a1e126, 0x57d699f7, 0x28bd8cf2,
- 0x55c358df, 0x485f283d, 0xfcbcfaf2, 0x33af104b, 0xcf87d262, 0x4757594b,
- 0x9bdeadf4, 0xd820f0f9, 0xe033ee67, 0x37829879, 0x2b62dfa5, 0x661cb3cb,
- 0xfc03cdf7, 0xde6e8f95, 0xb8dbe403, 0xd798cff7, 0xc377d8e1, 0x31df784e,
- 0x15c85295, 0xdf7ab71d, 0xb7bfbc22, 0x4003ae9a, 0x0cb09026, 0x7c63bd76,
- 0xe089f930, 0x419efc03, 0x28438f80, 0x77f8eb2f, 0xf0ee5445, 0x56deda3b,
- 0x03c3bf76, 0x52079656, 0xc979156d, 0x7d94b0fc, 0xffb04d67, 0xc0625f2a,
- 0x0e5029fe, 0x097faf52, 0x1ab6abf6, 0x0a74f935, 0xa27e155d, 0xf70ad49a,
- 0xe8955c44, 0x9fe5ae5b, 0x0aa66b24, 0x23def29e, 0x4d9de27e, 0xaed46519,
- 0xbb06ef3b, 0xd0a7f94a, 0x53d3b2aa, 0xc0164b06, 0x287f845b, 0x0fa2c67f,
- 0x3037ef7d, 0xfe038c1e, 0x0b5d86c2, 0xe8773844, 0xe0b35d2c, 0x3fda3a1e,
- 0x362a4acb, 0x12b3f7d2, 0x64f50968, 0xebcaef5e, 0xe7d9583d, 0xa041b723,
- 0xb8f157cf, 0x9e562bec, 0x5e746037, 0xbc5cf70a, 0x9d9af1c2, 0xa0bb4566,
- 0xa291adc8, 0x8db5ce0f, 0x333b7cfc, 0xba00699c, 0x0c6c7229, 0x6a76421b,
- 0x2e8d32b4, 0xbc39e403, 0xe179f7e5, 0xbd23b0bc, 0xec25f573, 0xf3fd3fbb,
- 0x1f9f3e46, 0xdd7f5fed, 0x46e0fbee, 0x5c696fc0, 0xd03723f3, 0x9f25d97a,
- 0x91769c63, 0xf50aecb5, 0xd4be9e79, 0xf3adffcf, 0x1fe01c27, 0x9e6d7eb6,
- 0xfecfcb14, 0xdffccaca, 0xf8e9febd, 0x2177e29e, 0xab2740a9, 0x63342fbf,
- 0x55d57e89, 0x8e80f2a8, 0xec0931b2, 0x99c595ab, 0x2bbee9c6, 0xaec7ce54,
- 0x5fb8b10a, 0xe833e816, 0xdd8335df, 0xf335fe57, 0x7fe8e28f, 0xc794ee70,
- 0x32dec9cf, 0x69db16fa, 0x3b08b7bf, 0xa84acd6f, 0x93ef8468, 0xcf033988,
- 0xf688732b, 0xe4acafbe, 0x8f3809ea, 0x479c0c84, 0xbdae9c6e, 0x40346cab,
- 0xcc0c9f7b, 0x2a23cc57, 0x23ce8cbf, 0x78c10fab, 0x29701916, 0x194d85e6,
- 0xb79ff948, 0xeccc0e7f, 0x426711b7, 0x764fef54, 0xa09de2dd, 0xddaa5bf1,
- 0xfedfc7a0, 0x5623bc4e, 0x3675c5fe, 0xfd7b9fc6, 0x03e42f5e, 0xde3cf1e8,
- 0xbbb12c25, 0x8f5be3da, 0x15fe3d4f, 0x98f1eabc, 0x427b91f3, 0xe93c0c52,
- 0xbf3d12f1, 0xba00ac0c, 0xd1140de4, 0xd074297e, 0xcbf689e3, 0x5f6f7e87,
- 0xf9c1fb42, 0x08c2b8ab, 0x43372f76, 0x457fdc20, 0xc22f36ff, 0x257fcc1f,
- 0x3748ed5d, 0xe3db5e3d, 0x979f93d1, 0x1edf5d1a, 0x37e617c0, 0x3e400fb9,
- 0xc24da359, 0x1c684971, 0xbc7be751, 0x04e4f102, 0xbbef1e1c, 0xaa40c71b,
- 0x5762aef8, 0xff2888e2, 0xeb5afb8c, 0x2705e6e7, 0x39ff029e, 0x04b7c12b,
- 0xcc44a6e2, 0x8a3a3cc0, 0x3e5ac3bf, 0xcd6bfce3, 0xf8a13e40, 0x0c43b6d4,
- 0x664fde07, 0x5d4e79ed, 0xf4cf8ebb, 0xecf857eb, 0xa6307815, 0x3e14be3d,
- 0x7ee3689b, 0x13d27779, 0x5b21e4fc, 0xde802446, 0x98a4c126, 0x075188f1,
- 0x9c3811bd, 0x051f915f, 0x773c8be2, 0xf427f9f6, 0x8eb51357, 0x1cc0f8aa,
- 0x2d9b77d1, 0xf852fe86, 0xb74e4ae3, 0x13bc892b, 0x12574be2, 0x7d9117e3,
- 0xfd744640, 0xde3c6cb3, 0x80f483d2, 0xbab2ee75, 0xaf997ed8, 0xea6eb233,
- 0xb3dd0256, 0x71d9f8f9, 0x834efc36, 0x112d8d84, 0xbde267fc, 0x2929b235,
- 0xf7890f3a, 0x8415e927, 0xf03371f9, 0x178a5cbe, 0x9d1ac172, 0x609b42c7,
- 0xf85c7bc4, 0xc6d74e3c, 0xb6df90c9, 0x003df44e, 0xf6116ceb, 0x19f5c10d,
- 0xeec1fd43, 0x6f3fdbe9, 0xed0655d8, 0xf6215fb4, 0x2f9ff3e3, 0x7843b8b2,
- 0x3ab039bb, 0x94ff63a3, 0x07da358a, 0xe1b22e45, 0x41cbc8bb, 0xcc22c2ce,
- 0x53cfc83b, 0xc2299c76, 0x3887a0fd, 0xe1465c97, 0x113b3eed, 0xa973f9f3,
- 0x7a7e81ba, 0xb7f3d7be, 0x90279f9e, 0x4f784cf0, 0x363fc7cf, 0xdff1400f,
- 0x90737c22, 0xeeca8df2, 0xf942fc29, 0x5d1b79e7, 0x6388db77, 0xfdbb814f,
- 0x53cf88ce, 0xfe29eec1, 0xf10fd479, 0x3afd00bc, 0xff15d3f2, 0xf7cd937c,
- 0xc233f412, 0x99fbe87a, 0xf8065d03, 0xcd90fe7e, 0x573c32f3, 0xed8b96fc,
- 0x232ec837, 0x3be74819, 0xcea1d393, 0x593ef040, 0xf6808179, 0x961276ec,
- 0x2bdbbc60, 0x76becd24, 0xc9fc25a6, 0x587e70fd, 0x99ed0039, 0x14fabe0f,
- 0x8f967df1, 0x13bfc55c, 0x0fee1819, 0x163bbefb, 0x43c7df6a, 0xbde8acc2,
- 0xbed09f9d, 0x6e0092dd, 0x877c0a73, 0xfb6b205b, 0xd657c7eb, 0x7fab87a1,
- 0x63df9caf, 0xbb22f704, 0x9fc2fe55, 0x8d8fcc6c, 0x7e2df7cc, 0x37c5018f,
- 0xc1b3d5d8, 0xc50f024b, 0xf4a55fe0, 0x8c7b25c5, 0xe6f5a3c3, 0xb1e9e6ed,
- 0xc65117ee, 0x833df051, 0xfcf82934, 0x65ff1636, 0xc01c58fb, 0x734844f0,
- 0x7d94af4e, 0xdfd013c3, 0xa0275beb, 0x97525d7f, 0xf1a59863, 0xb83ed9f3,
- 0xf70f9f9d, 0xfaff405d, 0xafcfcc9d, 0x42fdc4ab, 0xf7db3d49, 0x5cef82ac,
- 0x0c89f3ba, 0xb23fff42, 0xa9bc859f, 0x9047b852, 0x53e087b5, 0xacd53ef5,
- 0x897db27f, 0xf611b969, 0xc934bea3, 0x5abfeb4d, 0xf747155e, 0xc419554d,
- 0x29bee842, 0x27cb57f1, 0xb54d18ae, 0x20479273, 0xb2af5889, 0xfefce98d,
- 0xcb57f939, 0xe36596aa, 0xaede2bbe, 0x2476cfda, 0x2e6de71f, 0xfb4763c4,
- 0xbc12c7d8, 0x3c5576c9, 0xb3ff4f42, 0xe004ae71, 0x7f7ce5bf, 0x59c2f57d,
- 0x0cb06fb8, 0xf90e9f38, 0xee9cd961, 0xb38f3b2e, 0xdcf7d95a, 0x00f4d6e5,
- 0x456ba9e8, 0xd9e60b9f, 0xfef9c6f6, 0x6b7e4710, 0xb7dc11e0, 0x8ebdf905,
- 0x5e45fcfb, 0x65fabe75, 0x5f67e676, 0x03a3497d, 0x8cd71df6, 0x677e0bfc,
- 0xeec8da7e, 0x6d196b4d, 0x4fb9f8d2, 0x032ef2da, 0xd1494af8, 0xce7e8227,
- 0x20ebb11e, 0xec8efbd8, 0x780ed444, 0xe403b004, 0x3c54fefc, 0xeddfaa07,
- 0x0b65d880, 0x74fd6eff, 0x9dea637d, 0xf0dd2cb4, 0xb7ec0717, 0xcfccedb2,
- 0xc26c6d3b, 0x5e4a747b, 0x079ef115, 0x6dea6e3a, 0x9fae5f10, 0x1b10f595,
- 0x076d4e26, 0x43afbf09, 0x8caf07f1, 0x2edc0393, 0xbc4d712a, 0xbd5c63df,
- 0xda38b1e8, 0xf7a785fb, 0x0f9e3e66, 0x1b922174, 0xd92325dd, 0x3f227e85,
- 0x5dbfa1e7, 0x0ef0af70, 0xfebd795e, 0x40af1bf3, 0x4276a266, 0xd7c93f00,
- 0x98ef0585, 0xb7fc563e, 0xe36b5f71, 0x527f7a97, 0x83e33bb1, 0x20f49743,
- 0x8dd71780, 0x5ec21df8, 0xe94de623, 0xf0bccdfd, 0xcafc0ec4, 0x363f9147,
- 0x02b1f7d6, 0x19d9873d, 0x7fd7965f, 0x94aef78e, 0xb834d091, 0x5eaca6ff,
- 0xf7c88674, 0x6f25e9e9, 0x6ac1dfc3, 0xe02e4a0b, 0xeee0b6df, 0x6f5021b8,
- 0x561e3110, 0x65f64efe, 0x41ad67c0, 0x291fef09, 0x01cc7edf, 0xf3b140fa,
- 0x2f7641ad, 0x08f05b49, 0xb6e0573e, 0x065f2436, 0x818367f6, 0xed773fed,
- 0xfa0ad6f9, 0x67f3f5e1, 0xabdf7193, 0xff9d69d8, 0x7377c4ab, 0xbe2462ed,
- 0x896ff6ab, 0xf2007d98, 0x2412f2a7, 0x7f510a22, 0xfe9d9db5, 0x93b12c88,
- 0x823af6f6, 0x8231e27f, 0x77edeb9c, 0xfb3adf04, 0xfb9d88fd, 0x30c8bd8f,
- 0xe1afc7b8, 0xfc7cf27c, 0x756833ee, 0x0cf8c22e, 0x76da4ff3, 0x14d8fa7d,
- 0x644fbe78, 0x179ffddf, 0xd8dfef91, 0xb377bf31, 0x2af78d4d, 0x6eb9d7a4,
- 0xd1b75a67, 0xc776e7fe, 0xd1b578b3, 0xbbfa997d, 0x00ff6883, 0x3ba857c7,
- 0xbb92f73b, 0x3f3b7dc3, 0xb70cffda, 0x45eaffbb, 0xb8d2f790, 0xc35044f0,
- 0x990e6bfd, 0xb30c5f40, 0x7a625f7b, 0x7a0acea0, 0x7be32640, 0x516e3a10,
- 0xfc0f193c, 0x4e24ae15, 0x757bc3c8, 0x7400c1af, 0x0336b119, 0xf1d664f3,
- 0x7579c173, 0x950ca6d5, 0xcfc7997e, 0x724a4e95, 0xf9ea927a, 0x03d30770,
- 0x3f177727, 0x03f2fa87, 0xc317e933, 0x983b263e, 0x9264dbbd, 0x7e87aca7,
- 0xefb80d87, 0xeb67b5d8, 0x6e0fb81e, 0x50d741de, 0x41a737b0, 0x86bc281e,
- 0x20aaeb7d, 0x23e1b6cf, 0xbf5416b0, 0x0d1029af, 0xc46ddc74, 0x0764e2c5,
- 0x8dffb80c, 0x278917c4, 0x29f9d619, 0xf6dbbfd7, 0x50e7341a, 0xa43df8db,
- 0x39d9da1f, 0x8b3b7ed4, 0x3bdc6d53, 0x944ef93e, 0xd001df43, 0x9b47e5ff,
- 0x68ae1cab, 0x97f14d5c, 0x38d81cc6, 0xe7fd3065, 0x13831698, 0xb03aedc8,
- 0xbaf5845a, 0x25db524e, 0x13fe7690, 0x1a89f785, 0x0616b6de, 0x0de3ce8f,
- 0xff055390, 0x3c3f02d4, 0x35b7d688, 0xbf209319, 0xb2bfc14a, 0x577c650e,
- 0xb2acf11d, 0x367928a1, 0x577c4f7e, 0xb87cf7b9, 0xa0f72893, 0xb6ce5f23,
- 0x3f195a7b, 0x3f50e9c8, 0xfd1e3bb9, 0x9edc4d92, 0xde82b491, 0x4e853f80,
- 0x7f660e09, 0x3474f994, 0xbfa73c7e, 0xbe50fe52, 0x64b9275e, 0x1f7e1be4,
- 0xc50e4ba0, 0xae3c81f5, 0x77f83e86, 0xae79545a, 0x47c00ef1, 0xd47e368b,
- 0xc0306cd0, 0xdb6558f7, 0x66bc4485, 0x6dfe93a4, 0x758ccf84, 0x070d7fc8,
- 0x7171ca09, 0xbe2c5ded, 0xf83d4247, 0x5e7858bd, 0xcfc3f20d, 0xb409bbad,
- 0xb55c131c, 0x37e207b8, 0x8ab900e4, 0x0dca89e2, 0x26d51594, 0xf779d7e0,
- 0x3f2e72b0, 0xd2b79dff, 0x5859f287, 0xfafbf2c3, 0x7cd8323a, 0x4312bf38,
- 0xfbc8777c, 0x7fdb8e78, 0x022fde65, 0xa9fad2df, 0x611bc7fa, 0x975fca5c,
- 0xdeee203a, 0x3053e8f0, 0x4f5f855d, 0x4e1091ad, 0x7cf6bc51, 0xd74e72fc,
- 0x7e300f57, 0x1a46b31f, 0x8d31f70f, 0xe2138991, 0xacd6dbc5, 0x6f7f4115,
- 0x60ce7e03, 0xfd760e72, 0xac87eee4, 0x773b04bf, 0x2e2040c8, 0x8a44c9bd,
- 0x62e4a836, 0x34d7aad7, 0x5b5c5bf2, 0xdfe30539, 0xe80249cd, 0x156e4579,
- 0xb9326fbc, 0x5ffca327, 0x09ff93ab, 0x0e39fdec, 0xb9c79746, 0x893e3ffc,
- 0x947d3fca, 0x005126b8, 0xb14c9b38, 0xf69ae9ef, 0xa22ff923, 0xd3b68f57,
- 0x6c1cd3ab, 0x43e8ef5f, 0xe6bb2fc7, 0x23ebee2c, 0xf37ce3f3, 0x6f8504f8,
- 0x7fc00432, 0x5f60a535, 0x2bc517c0, 0xaffa33f0, 0x32736fa0, 0xf6a1bef1,
- 0x3948b8fc, 0x6dc8d397, 0xf229af54, 0x7a022beb, 0x58a84d67, 0x72767e0c,
- 0x7a7c8cbe, 0x4ef5f04a, 0x14ed76a2, 0xbd0c73c8, 0xf4c1d130, 0xa7c939c8,
- 0xfdbcafb9, 0xe077483c, 0x63ba22eb, 0x1a917583, 0x51f409c1, 0x6c355dda,
- 0xc394b15f, 0xf52b9e53, 0x2ff78d1f, 0x9783c5da, 0x333d983a, 0x7fb056c1,
- 0x2233d980, 0x20b9478c, 0x83bbab86, 0x76a3cdbc, 0x1d9556ec, 0x2355253b,
- 0xf8782abf, 0x73f7e735, 0x57dd6c89, 0x829679f1, 0x673aa7ef, 0xa3041ba2,
- 0x145ae4c0, 0x008bbc98, 0xb1eed4ff, 0xafef9193, 0xf3f7cd89, 0xfe42afd7,
- 0xc4e49c4c, 0x371e48ef, 0x83892dba, 0x00e3e962, 0xfed6bb96, 0xc059f706,
- 0x1df720c7, 0xc81141c9, 0xffc18901, 0x2affca01, 0x407c29fa, 0x8745e2f9,
- 0xf9e84f4a, 0x53df3942, 0x7749b2f0, 0xeb8e783e, 0xba5e46f9, 0x5153c83a,
- 0xe9a3f3d6, 0xce8ed2dc, 0x473a306f, 0xade80be5, 0x81df89e8, 0x2c74a59c,
- 0x9c12fd67, 0x8faa9f38, 0x485e6167, 0xaa273f35, 0xf329e3e3, 0x42f5c03e,
- 0x353ce747, 0x1c5fdf56, 0xd748f3ba, 0xe47f28a0, 0xc176bf71, 0xb39e335a,
- 0x9e4c206f, 0x01f15de5, 0x4e9e77f5, 0x294c7523, 0x3e808faa, 0x3856891f,
- 0x42d77504, 0xc74be913, 0xb051973d, 0x7e6df20b, 0x0fe724d6, 0x60d8eba6,
- 0x835ea792, 0x64f701fb, 0xdf393f80, 0x6f7884e0, 0x4029c7a2, 0x0343023c,
- 0xd8fb8720, 0xb8fbc338, 0xab7dc32f, 0xf41c3dcb, 0x2f4e69c1, 0x1e0abe85,
- 0x1d77b23a, 0x025fb5d1, 0xede3a73f, 0x26f23d7a, 0x38e79b97, 0x47ae2f1e,
- 0xc9e41164, 0x448b7c41, 0xd3367f98, 0x923d1183, 0xd01cf04d, 0x9e55c7c1,
- 0x509ff52b, 0x5212388f, 0x74647a54, 0x423d4c73, 0x3fe5317f, 0xf41ccd65,
- 0xd8c1c967, 0x027a6cfe, 0x6029c7b3, 0x14bf6947, 0xd33dfd99, 0x503edcd3,
- 0xc57cc48e, 0x8c6635ea, 0xc87a2be3, 0x878c9531, 0x00eacfbf, 0xa6bd0bbb,
- 0x095e0efa, 0x2669b3e7, 0x9f179c17, 0xf748c292, 0x5cc37453, 0x15e1fc8d,
- 0xf431de80, 0x85f88111, 0x2c9ed7fc, 0x51062efe, 0x11e4164e, 0xd6bba3b4,
- 0x2abe428e, 0x8014cfca, 0x136b8b6f, 0x9a4f6805, 0xbe8034e0, 0x6a31d652,
- 0x49fc88a1, 0x824460e5, 0xe4a31e8a, 0xd5f0110a, 0x2697d93b, 0xd6fdd225,
- 0x4cfd57af, 0xd0f1bf1d, 0x68b48afa, 0x1fd686fc, 0x7ceb75b4, 0x213726fc,
- 0x3fe420f0, 0xe4f0eadc, 0x5635b8c0, 0x59942e6f, 0xce302b5d, 0x88bcd9db,
- 0xe52fcb1f, 0x0e444e3c, 0xcecb8bb4, 0x5c6175ac, 0xa7cc1a76, 0xa7f1fbac,
- 0x73de1c00, 0x66efd311, 0xf5c2e8f3, 0x2088f902, 0x2b78ba3d, 0x28978844,
- 0x384ee77a, 0xf6a14594, 0xa1ae7008, 0x2de81bc8, 0x3c95a7f0, 0xd95b8808,
- 0x401f6e31, 0xc27a823e, 0x5a3ea8b0, 0x79886f91, 0x04c2f15f, 0x9faa4fdb,
- 0x9beff049, 0x477ca97f, 0x2d3ca228, 0xebe9504c, 0xa70ff3c7, 0x7608f3b2,
- 0x7cdddfaf, 0xb916e78c, 0x4ba034ff, 0xa1867ef4, 0xf90c9366, 0x5c43c4a6,
- 0xb1fe554e, 0x76421410, 0x56fd63c8, 0x874a1e20, 0x2c456fb6, 0xde3ffb9f,
- 0xcfe01949, 0xd4dc1837, 0x0bfc8233, 0x6f770794, 0xd4a7df82, 0x73127bf1,
- 0x091e6d1a, 0x1c421de2, 0xa3da8eff, 0x1d18e73d, 0xdb4f5f4e, 0xf8cd0717,
- 0x72dafdb7, 0xe0afbf94, 0x1598efc6, 0xe7790efc, 0xd79881f1, 0x8376ac69,
- 0x30b6ad9c, 0x2c2dabf8, 0xa2dab76e, 0x004ae7bc, 0x79d1ddbb, 0x1ec2f67b,
- 0xe253ff18, 0x90e1d98d, 0x0cc9f808, 0xc92c0cbb, 0x0c678d8d, 0x72b75c13,
- 0xf1c75f0e, 0x46ef69bf, 0xd679ec11, 0xb0c5ea84, 0xf763d9ef, 0x6bfa00bd,
- 0xdfd6b66c, 0xf3f0211b, 0xf704c9e1, 0x249c8a4b, 0xe09d9337, 0x6c1e24da,
- 0x1a0a80f6, 0x13b3d27b, 0x5e0995f6, 0x553c0022, 0x8006cffe, 0x8478ba4b,
- 0xdfc0ba6b, 0xfb7fe5eb, 0xb4d9c390, 0x7200bc77, 0x8269a5df, 0x9ed41ae0,
- 0xfec257cf, 0x53cb047b, 0xfb2afa01, 0x5e2fdec2, 0xa5f0013a, 0xfae26ff4,
- 0x2f9f0afc, 0x74c64217, 0x7718213d, 0x2340f4cc, 0xaa35495c, 0xb9346e48,
- 0x4799eb54, 0x668f5e10, 0xedd1d719, 0xca072fa0, 0x1c44b663, 0x10c9ec77,
- 0xad74b7e6, 0x43f69020, 0x401d357a, 0x4557aa3f, 0xdcf40093, 0x9c0df7b4,
- 0x5da6cf6f, 0xb5f2e4ac, 0xca05fb91, 0x98d98ebc, 0xcfc63cdd, 0x334eaba9,
- 0xc12079bb, 0xca4bf987, 0x7c72aa3a, 0xfe141569, 0x19cbc84a, 0xce5e71d1,
- 0xb2930491, 0xd608ffdf, 0x79bd3e57, 0x3ea0f00f, 0xefba907e, 0x7523d230,
- 0xaf96db21, 0x0040b7dc, 0x4672b17d, 0xa281f8ec, 0xf8f25637, 0xe5ff2aab,
- 0x4f4f5a94, 0x66b24829, 0xf292f4aa, 0xfcd153de, 0xff3c4d97, 0x7bcd03e5,
- 0x805a9783, 0x79b2ee9f, 0xe573c0ce, 0xe3ad0bef, 0xd947b77f, 0xbaf82acf,
- 0x80fcc9c2, 0x1fd70903, 0xc0247383, 0xf1f29393, 0x3cec4b3a, 0x069dcbf2,
- 0x7e3077ee, 0x5f8c4d21, 0xff6a1d60, 0xb001bfeb, 0x00d7432f, 0x0000d743,
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0xc9332666,
- 0xe4cc9924, 0x40275e49, 0x21c40a30, 0xeb141021, 0xef0c0124, 0x02415041,
- 0x8042120c, 0x2a941324, 0x8065bd6d, 0x8d520318, 0x8bd4b45e, 0xd7a5783a,
- 0x2941b622, 0x84ec1a86, 0x3a0bc157, 0x94b62a28, 0xaa54141b, 0xa5ac4090,
- 0xd7f97b96, 0x661f7b5a, 0x962264ce, 0xbfefbf62, 0x767e9fff, 0x67d9cfb3,
- 0xfbd7b59f, 0x649ecfb1, 0x1258c4ab, 0xdd3b3763, 0xd8c67a65, 0xc1b758be,
- 0x88d8c45a, 0x596edf62, 0xb9786c61, 0xda1eb777, 0x3bbf564c, 0x94061136,
- 0x6826c733, 0x3dac1dec, 0xa384da0e, 0xb838ce1d, 0xa36adfdf, 0xacfa6e79,
- 0x8c2db98b, 0xab98950d, 0x97631065, 0x60d6eff0, 0x31d56a9b, 0x0627f306,
- 0xe306254a, 0x6cb8c436, 0xe961bef8, 0x4001b2f5, 0xf1d66449, 0x03631fac,
- 0x2b8d0aad, 0x96ee762c, 0xa7563de1, 0x8b79c64b, 0x9ef4ac63, 0x6a771cc6,
- 0x1d3e7f3d, 0x4e89679f, 0x37c02269, 0x5b18bfec, 0xfb6ddd03, 0x1065254b,
- 0x6f1467be, 0xc0b67319, 0x056057f8, 0x115970a1, 0x9f7c249e, 0x39ebef44,
- 0x4acf3bbf, 0x129ceaf0, 0xa8fc324c, 0xe860c7c5, 0x32f5a5f0, 0x02c89fc2,
- 0x6d000312, 0x2312d6d5, 0xc6bd37bc, 0xfe61b921, 0xf95c629b, 0x0e635cf8,
- 0x6d0a1c5c, 0x0ab7ce89, 0xe7103b9e, 0xf981653c, 0xf668bf17, 0xfa31349e,
- 0xd5ff04bb, 0xfa6824b6, 0xef34d69e, 0x7f60bcc9, 0x0d23fe31, 0x4ccfdbfe,
- 0x3563186c, 0x407b16fc, 0xef8cdf76, 0x3c7535a9, 0x75fa173a, 0xc8caf8bf,
- 0xae0a4960, 0x6578e017, 0x3dcc417f, 0xa77ae096, 0x9977a4f5, 0xbd27a935,
- 0xde824a87, 0x4ade8163, 0xb29f7a4f, 0x3b7a0824, 0xfac107db, 0xc24c5de2,
- 0x135f01e7, 0x85dc3d39, 0xb788c1ae, 0x380332a5, 0x587a455e, 0x538f4cae,
- 0xa71fce16, 0x2a1e9c2c, 0x38c6e61d, 0x75d2b4ef, 0x96f5ef46, 0xbebc3cb2,
- 0xdcae8276, 0x16cf8117, 0xee342d59, 0x05fcf1aa, 0x99e287d3, 0xfb6dfdb5,
- 0xc1efa10f, 0xf784cb7f, 0xc0378845, 0x583f5c7b, 0xf84ebff7, 0x53f91928,
- 0x203aea67, 0xdb6a3e01, 0x25864564, 0x9c954c0c, 0x5b190b27, 0x89cda0f5,
- 0x8b5cf07c, 0xf18288e4, 0x6b14c9cc, 0x22564332, 0x75fd9d62, 0x11bb3e7c,
- 0x8360b85a, 0xa334de71, 0xcef2136f, 0x8c33c01e, 0x380824f3, 0x001fe01a,
- 0x0555a747, 0x0df749cc, 0x559ff2ec, 0xf851fb82, 0x6a4b982f, 0x80976f69,
- 0x998aab70, 0xef7000db, 0x1f89936e, 0xf68c6b9f, 0x2ffcc145, 0x607f396d,
- 0x3ffbf426, 0xc165c3a8, 0x27eb04df, 0x53a8f831, 0x1cad04ba, 0xc3d3ca67,
- 0xed1c877d, 0x4b7c6190, 0x8b3e5c74, 0x3764ac67, 0x955b3f31, 0x7bc0f30b,
- 0xd347b556, 0x82e556fa, 0x1f10e47c, 0xd9f8863c, 0x69646b13, 0xe41bbd70,
- 0x670dc706, 0xcc8cef1d, 0xbba9d209, 0xbbd9cbf5, 0x189efd60, 0x2627af3e,
- 0xde00c7cb, 0x07175dce, 0x5b8f1f20, 0xca35cf36, 0xd924d8ce, 0xafe91ebd,
- 0xde66f73e, 0x6f8871c7, 0x5e0832c6, 0x841c9fa2, 0xacde32ef, 0xac72bf1c,
- 0xc9d1d69e, 0xeeb81da2, 0x2193a316, 0x39c7bc9d, 0xad78ab7f, 0xd9d1bc13,
- 0x0dd47456, 0x68ee7beb, 0xef9f0386, 0xeb36ed6c, 0xe2cb7de0, 0x75c0bfdd,
- 0x715d99c9, 0xcf8841ae, 0x063bebee, 0x097a1e91, 0xfc1f77af, 0x741ee6d8,
- 0x86dbeb55, 0x7d695fcf, 0x49a5bd1e, 0x3fc9ef8a, 0xb5207ce1, 0xca55ffb5,
- 0xa8613927, 0xcc59bcb7, 0xddd60ab7, 0x93487838, 0xc69e848c, 0xc64f9414,
- 0x0c9fac2a, 0x2abbd20c, 0xf107b5de, 0x8cd7caac, 0x843ed778, 0x5e93df0b,
- 0x8fdceb40, 0xf343fcfd, 0xabba0d0a, 0xc8e1e75a, 0xfe13f4eb, 0x6a7ac56b,
- 0x0cbf164d, 0x866db3f0, 0xf9543a2f, 0x5e13dbec, 0x0e31c7a0, 0x1ba8e3af,
- 0x8b7bf9e9, 0x43e21563, 0x62bab01f, 0xf8e3fe09, 0x373c563e, 0x21bbd715,
- 0x858f69c6, 0x30579bf1, 0xb4520fce, 0xdc5879e3, 0x68b63dd6, 0xf15593d4,
- 0xdf3853ee, 0xb3f3ba0d, 0x02c7685d, 0xdc3ddd2e, 0xd7867c0e, 0x7adddd61,
- 0xc65ea382, 0xfd62aff9, 0x71f322e7, 0xd9fc3a0f, 0x54e7a21a, 0xf4148cfc,
- 0x41f8891d, 0xffa5dc85, 0xc414c3a2, 0x3d4a048f, 0x3e73d6dd, 0x10b23ac6,
- 0x9f1df6de, 0xf980e80e, 0x74f8deea, 0xdd6fca36, 0xb888a26f, 0x7d737ea3,
- 0xd9f1f23c, 0xc5bd3612, 0x7e9f53d2, 0xa5debcb1, 0x1ffae607, 0xcbd25f6b,
- 0x44602c35, 0xb2db5d3b, 0xd10fa5c4, 0xe93100a7, 0xc08683dd, 0x60ff9c04,
- 0x0056cc91, 0x863b75df, 0x7a08b0a7, 0x5adf6d5a, 0xb9955cce, 0xf512fd8c,
- 0x8ed7f21c, 0x9784f1a1, 0xe3e91b36, 0x9707f1f0, 0x1946bb57, 0xe0ef9f7a,
- 0x1f74f310, 0xcc213f3c, 0x8131b90f, 0xa23195db, 0x44e94505, 0x8f6ccf38,
- 0xd2e179f5, 0xe2f78299, 0xcce9e018, 0xbd0b77b6, 0x58672fc0, 0x51d7bee0,
- 0x30b4be7e, 0x0c267bf4, 0x4570af79, 0x6ede506c, 0xbf6be629, 0x7143b5e5,
- 0xb09f8c0a, 0x37a27775, 0x30b77f04, 0xf99797fd, 0xcbdf0737, 0x1df4c7d7,
- 0xec1e9003, 0x0ac9d3f5, 0xec7613b4, 0xa07ce44d, 0x4bce90e8, 0x15fade85,
- 0x9c111a5e, 0x3ab2c26f, 0x60c2a8d7, 0x9982f6bf, 0xfafb42f9, 0x5f4d1180,
- 0x5d0b05ed, 0x26c427b7, 0xc3e8fe92, 0xf8fea0fa, 0xbf0b78b6, 0xe0ede2ae,
- 0x6859d390, 0x239acfbf, 0x62edc9f3, 0x4463b75c, 0x1347fa0a, 0xd6fefe8c,
- 0xf318e308, 0x75f0b8d1, 0xeddcb9bd, 0x3bdb951a, 0xcc8de37c, 0x1cafc91d,
- 0x9afdc09f, 0x7999876e, 0xdbefae41, 0x743b2068, 0xd307e2e8, 0x9f7e810a,
- 0x5758306e, 0x9fab3e02, 0xaff19dd9, 0x487abf70, 0xfe825594, 0x3fbf8aa7,
- 0x6782f1f2, 0xfbae1764, 0x25f70dd3, 0x73f683cf, 0x801ac7e0, 0x0346c163,
- 0xf8deaf5d, 0x5a7eba7d, 0x6782e9f0, 0x9ea20692, 0x4d67b43f, 0xfab3ae32,
- 0x13be1fbf, 0xa356c5f5, 0x6810e075, 0xae48b66b, 0xb1722151, 0xa6b305e8,
- 0xaac755bf, 0xbaea1d71, 0x7cbee499, 0xbc78015f, 0xba0fdc09, 0x8f65ff6a,
- 0x7f017fd6, 0xfdc09bc5, 0x61534995, 0xdd4575dd, 0xdeee27e4, 0xfc764d17,
- 0xfc9916b7, 0xbf90ff01, 0xd08de7fc, 0xbd6ffb2f, 0xc1087c83, 0x5e85a3e7,
- 0xf48f2c66, 0xf7899550, 0xc9e876cb, 0x958b289f, 0xd07edf09, 0x08c8a313,
- 0x61a32d39, 0xe7d4f7dc, 0x46eb91e4, 0xf1d1b8c0, 0xe27e8606, 0x268bfcf7,
- 0xb7efd030, 0xd47fd05e, 0x529eb211, 0x23a3d4e6, 0x9a0cc252, 0xe3a3abeb,
- 0x08ff479e, 0x1ea3d326, 0xef69332f, 0xee3fee8f, 0xd1bbda34, 0x5575ed56,
- 0x39439e7e, 0x83941818, 0xf4fefbdd, 0x675878c4, 0xfb9941d5, 0x33d05763,
- 0x72bae16f, 0x566fde91, 0x0ee7816c, 0xba1cec09, 0x1a4369f8, 0xc4b157f2,
- 0xd3ff4256, 0x91e5518b, 0xd54622e4, 0x9ce80c37, 0x44f3a417, 0x7dcbc2c7,
- 0xc5c98b14, 0x11f72e4b, 0xefaf6ffe, 0xef2e59be, 0xfbd2304e, 0xb861f5c3,
- 0xfa577cfc, 0xbd90c270, 0x6a58de59, 0x17ed8e7f, 0x099eb95b, 0xfae18fd7,
- 0x1c2b854f, 0xb20bdade, 0x4f8def46, 0x505c6850, 0xfee919ff, 0x3eb38c35,
- 0x6710884b, 0x7c267d81, 0x29e98779, 0xe1ff03be, 0x641b8e0c, 0x0025ec51,
- 0x6fb58352, 0x25f5ea0c, 0x5e177716, 0x86e97ecf, 0x0c17e851, 0x43acd2dc,
- 0x7129d1fd, 0x88366d7a, 0x8283fb16, 0x045fd071, 0xfa131cdf, 0x53a0e200,
- 0x2efb6816, 0xc31f632b, 0xcc4ca2fa, 0xbb202e6b, 0x041435ef, 0x7e023fe7,
- 0x8d99c60c, 0x9fc78c25, 0xebffdc09, 0xace8a79b, 0xcbc3ff30, 0xc093cead,
- 0xa797abcf, 0xf2f2cb52, 0xfbbf4874, 0x6fd06e04, 0xbbbce7c4, 0xa75d69a2,
- 0xca3e5724, 0xbe02c3e5, 0x62dc7a70, 0x35dbf953, 0x9a2fd420, 0x5f591a5f,
- 0xd3d36f5f, 0x66a792f8, 0x71dfa164, 0x2ceefdaa, 0x00a7a3d4, 0x41da00de,
- 0x9bfe23bd, 0x84c785fc, 0xec223e3c, 0x2788bc45, 0x04e4227f, 0xd5b9c7d8,
- 0xd174eb82, 0xa7cbd5fd, 0xf2f8fb53, 0xc63f7465, 0x12fc4396, 0x4095e237,
- 0xc9dfa05f, 0x83d932b5, 0x80d746f9, 0x49ef7804, 0xd2e28e93, 0xe52deb8f,
- 0x9d782cdb, 0xff337c51, 0x509bf1a9, 0xb5cb2e2e, 0xeb6f4758, 0x7576c5bc,
- 0x7596bc7a, 0xba5da1c4, 0x00c78fcc, 0x7e41c93b, 0x6fbb2f9c, 0x3c6115b2,
- 0xe38c91d3, 0xc060523c, 0xba060a16, 0xaa3f50b2, 0xe2d57fef, 0x8496c5bc,
- 0x881b0ef1, 0xcd12d172, 0x9c384eed, 0x1efd05a3, 0xbe08ae5e, 0x88d6a3c8,
- 0xddc624be, 0xe822af68, 0xb9e27195, 0x38e71613, 0x42dfd11b, 0x03ad277e,
- 0x38eee5f8, 0x0ebc44e7, 0x6c64c371, 0x3cf0a587, 0x558b29cf, 0xe2538bf0,
- 0x9a6bb97e, 0xa71e422d, 0x3841bcb7, 0x3c6d671c, 0x4f9e138f, 0x9f355b50,
- 0xe7ac4730, 0x26ab04ab, 0x30b4a3cf, 0x423ca467, 0xe348cd9b, 0x394e9d52,
- 0xee5de946, 0xf23fba86, 0x992f98ca, 0x4e281cce, 0xda5b2329, 0x36928f31,
- 0xf302b7ca, 0xe1098d2c, 0x6335e872, 0x5bafa57e, 0x7185ec97, 0x897701c9,
- 0x1ed8e011, 0xa5f04c9f, 0x4815fab0, 0x1d6ea1af, 0x9ee87a2d, 0x06a49f68,
- 0x50a4307b, 0x509047e8, 0x655bca33, 0xa441fbac, 0xfacab0f3, 0xf3054655,
- 0xf5195e50, 0x9dc969cb, 0x38fe036d, 0xa23a37bd, 0x9b13f75f, 0x6952fbd0,
- 0xef0a961f, 0x7840c179, 0x93c2fa18, 0xa1de11b3, 0x97a6dc2f, 0x5ff5e242,
- 0xdf040cd8, 0xb28bbde9, 0x30fe7e29, 0xf4e6e58a, 0xe0a3779c, 0xdf02158b,
- 0xf3231aaf, 0xdc6233dd, 0x93e9eb55, 0x6b24e7e0, 0xb633f4f4, 0x5d4cbc90,
- 0xd3d279ed, 0xf429b03f, 0xb7d37f9e, 0xf803ebec, 0xe64ab7fc, 0x7a2fbc40,
- 0xebe52371, 0x8cb6355e, 0xa9eb82dd, 0x07cc31d3, 0x9bf7d9ec, 0x4fd07d7d,
- 0xa08654ac, 0xf9f9707f, 0xf11b9b83, 0xb355bffa, 0x34ff8821, 0xe612e3df,
- 0x3732be05, 0xdabebe13, 0xc056c514, 0x6e1e1692, 0xe843fb19, 0x31d1afaf,
- 0xebe12bd4, 0x74193786, 0x0dfad8a9, 0x7f4e62ba, 0xdd2a7fd4, 0x488cb181,
- 0x886e950f, 0x7b67d43f, 0xf046bd36, 0x8f6d70ab, 0x7a2d70e7, 0xe458eb71,
- 0x36353e93, 0x2a34f309, 0x9da8ff5c, 0x33f686b8, 0x2572e820, 0x8e1ef9fb,
- 0xe19fb70b, 0xc5897376, 0x5dc71479, 0x15ce7ec9, 0xe847b5fc, 0x8f298561,
- 0x1d92be60, 0x27de51d4, 0x6c732e9c, 0x9fa3f23d, 0x3f22aeda, 0x8b66c53a,
- 0x6cdd1f98, 0xd9b47ae4, 0x894ce6c6, 0x04130f20, 0x5d75babc, 0x898bb446,
- 0xbd44526d, 0xf5c2ca74, 0xafcde812, 0x23d3ee49, 0xf808d5eb, 0xff70ec95,
- 0x5dfe2dfa, 0xa120aa38, 0x5dba0c7f, 0x3d9d4f80, 0x8f029f14, 0x7c555e2a,
- 0x884be2fa, 0x3f0b365f, 0xa4bc7b73, 0xb3aee389, 0x169ce3ab, 0x2f664f7c,
- 0xced13afa, 0xedf8039f, 0xa5c4def8, 0x575f934c, 0xf589eaf3, 0x1438c95e,
- 0x3ca302cd, 0xbdddb65c, 0xbae300c2, 0xf3c73046, 0xb0af8fd0, 0xb3bea096,
- 0x31da3b55, 0x8678deff, 0x971b37e7, 0x9a4adf30, 0x73fff187, 0x2a7ca5f7,
- 0xe965dde2, 0xf5d41769, 0x67eabd81, 0x22e570e7, 0xabd9bd5c, 0x8517286b,
- 0x17276ff6, 0xd6e891c5, 0x6bf5cf15, 0xebdff184, 0xe2b7ce85, 0xf9d12bf5,
- 0x390f510e, 0xfc853f12, 0x6b3f944d, 0xe1ee907e, 0x918e2cf4, 0x7b7cb1fe,
- 0x19dcbc4f, 0x276b2f09, 0xb8f4f2e8, 0x88ed164e, 0xda167764, 0xffbcf3bf,
- 0xcf527b42, 0x69fc3fbc, 0x56e7e7fc, 0x0ebede3a, 0xa64b7ce1, 0x1fb9e938,
- 0x5f311877, 0x55a7e6ac, 0x4b5f3d78, 0xb9fa09cc, 0x5a996bf3, 0x9b5d7af5,
- 0x57718854, 0xe48beec9, 0x7fb6771f, 0x6771fe4d, 0xbeac7f98, 0x4f605ef7,
- 0xb2d18f94, 0xfcfff885, 0xcbcf1e06, 0x48e9f94c, 0xdfb3c380, 0xf10a7cc0,
- 0xb40ff92f, 0x679fe85e, 0xf1c7e1cc, 0x1ec9625b, 0x8f30382e, 0xac5f1cf0,
- 0xbe084a63, 0x4cd19c12, 0xbd97c109, 0x27e9a6dc, 0xc668fab9, 0xabef4ca7,
- 0xbee69fb9, 0xbd3f7341, 0xcfd340ba, 0x3349bfac, 0xa9597b3e, 0x1de39fa6,
- 0xafdf19a7, 0x3f4d76e9, 0xcd6ef9b7, 0xb8e6cdf8, 0xe00ea9e7, 0xc3fa0675,
- 0x7ac52b7a, 0x8f7f5baf, 0x97e639e6, 0x992f58fc, 0xf9fdc82f, 0xb1fb31e6,
- 0xf229525e, 0x16fbd713, 0xdf9de669, 0xe82fcdac, 0x74bed759, 0x4f9d5fc0,
- 0xbfa1f872, 0xfef6bd60, 0x848dd6c2, 0xed3e85cf, 0x6a2fc5f5, 0xa687f9fb,
- 0x4c71c40e, 0x7f442aef, 0x6d76d7ee, 0x748ae2be, 0x55775ef6, 0xd54a8e74,
- 0x68acd9d2, 0xbf8e1ce9, 0xd85b3c98, 0x37dff87d, 0xa1d62fe0, 0x0aef8be5,
- 0x6bb07f7f, 0x621b9cf3, 0xcf51c7dc, 0x952eb775, 0xcbebe619, 0xbbb23d79,
- 0x83fccbf5, 0x7d3c844a, 0xfd3c8f6e, 0xbb10f627, 0x3be9e6a6, 0x2372feb1,
- 0x97f516fb, 0x3c457fdd, 0x31e58144, 0x8acdff80, 0xf5cba61d, 0x2f307316,
- 0xd4bfae1f, 0x5ff7f416, 0x83d7a4ec, 0xf055aa75, 0xf7f8b0f4, 0x5aa7085d,
- 0x9eef18c7, 0x88def04b, 0xff808c80, 0xea9d7c2c, 0x4b87803c, 0x12f8cf38,
- 0x51c60c5b, 0x4bdcf75b, 0x4b6b0171, 0x480efae4, 0xc43e3a1e, 0xda3d253f,
- 0x234cff82, 0xe44c68bb, 0x1894d176, 0xbf31c712, 0xd857bf8d, 0x51e6dec5,
- 0xb5bd18eb, 0xea992ed2, 0x8f585d31, 0xfbd7a089, 0xf683fe26, 0xf91e8be5,
- 0x4589bed0, 0xf7c27121, 0x7ea1f7bb, 0x26e7bc07, 0x63627bc2, 0x414a6ec1,
- 0x98d3f9bb, 0xaeb79238, 0x3aefb203, 0xa4de70b8, 0x0506dbc4, 0xf0e12deb,
- 0x9dd9348e, 0xde7d10fa, 0x66ed6926, 0x43f70163, 0x9db9120a, 0xf8f0b2ad,
- 0x7be8ac75, 0x4f76fcc2, 0x414f8f13, 0x42dbaa1a, 0x89b1c1fc, 0x5cfe34b1,
- 0x5c58c974, 0xdf1146cf, 0xf448e637, 0x224946be, 0x5f1e5efb, 0x75d7163a,
- 0x8e525ec1, 0x3e044ae3, 0x046fa2c7, 0x0e5f736d, 0x0df6228f, 0x13ebf3a8,
- 0xb6127c61, 0x4d8ed4a5, 0xc83f0ab4, 0xfbd2037a, 0xde93b444, 0x8d65946b,
- 0x93b6a55f, 0x2ebaf912, 0x0a2acda2, 0x2168c9ca, 0x1e846337, 0x1471fcc3,
- 0xc2739309, 0xde4d64e8, 0x513188f8, 0x7a258de4, 0xbc7489dc, 0xb7b1d055,
- 0xcf33b23c, 0x69d507ba, 0xad791e78, 0xd591e799, 0x3c8f733c, 0xc44c63b2,
- 0x21d2323c, 0x879416c6, 0xf5978985, 0x9bea0673, 0x278e9cc6, 0x1c7f23c6,
- 0x23cf1d92, 0x31bcc7e8, 0xe2b700f9, 0x91f039d0, 0x4ad81b11, 0x7817f433,
- 0x1933ca15, 0x2d8b0e20, 0xc3efca08, 0x9f843989, 0xa6fd47c1, 0xfc3fb87c,
- 0xf31dab98, 0x31a603ca, 0x66ffaa1b, 0x87165cd6, 0x1606c4fe, 0x29596e31,
- 0x64be39e8, 0x9e728c97, 0x12fc05d4, 0x052b1e81, 0x578e403d, 0x77873d20,
- 0xeec9bbb9, 0xaa403d08, 0x3da3e30c, 0xc397f23a, 0x57103f9f, 0x7bd230f6,
- 0xbe722fb0, 0xc385a2e4, 0xfd718c61, 0xbc1fe704, 0xfa88c3ad, 0x37aa8166,
- 0x0f4c752b, 0xe82a9df4, 0xaf037537, 0x978bb353, 0x9faac92e, 0x867e68c5,
- 0xb4c160fa, 0x1fe61f58, 0x78e5b416, 0x44972e09, 0xdb4f15f9, 0x17f61761,
- 0xc56a1d0c, 0x7bf9d778, 0x47927d26, 0x7ae31a2e, 0x513ecf47, 0xcfd900f5,
- 0xdc5baa44, 0xa2eaf82e, 0x41382145, 0x018daf3f, 0xb0d82c3a, 0x53ee1762,
- 0x19dfef78, 0xca8e27d5, 0xb270c35d, 0xcb39003b, 0xb3d5b00a, 0x387c028a,
- 0x2699e695, 0x0d7ef1e6, 0xdf0535ef, 0x01db477b, 0x0351cf5a, 0x5f809af3,
- 0xa5de773a, 0x98dabfa0, 0xff107264, 0x71d7ba8a, 0x1910fdd9, 0x1d577d0f,
- 0x2da33682, 0xd606bac6, 0xb8c8cab1, 0x768bab7f, 0x5a27fe20, 0x2fc4f43a,
- 0xc47a5d89, 0x674159e3, 0xdfc9f1f4, 0x2744624f, 0xe9c75d39, 0x7df0ad96,
- 0x79b5fd23, 0x751377c0, 0x1902fe42, 0xcc627d78, 0xe0154b3b, 0x2aeb03cc,
- 0x7f41e9c7, 0x677f8c4f, 0x0ff40e69, 0x4e3f9bae, 0x313dfc0f, 0x732f9dfd,
- 0x5adfd440, 0x0fefc557, 0xbecbe77c, 0x5bac0fd0, 0x4cdfefc0, 0x59decfbc,
- 0xf30e3d57, 0xd65eeffb, 0x07fe7c0b, 0x57ef2e64, 0xba51cadb, 0xc67148fa,
- 0xcf3544b1, 0x1ef80ccc, 0x8eefdb57, 0xa9759da2, 0x41a770f5, 0x8e470f53,
- 0x8dbf0131, 0x12c57c17, 0x8c0ec8e3, 0xaf1bf413, 0x18fed3f7, 0xf84fc99d,
- 0x58358ebd, 0x5b006f91, 0xf6152eeb, 0xaed07f7c, 0x724bf969, 0xe80cb632,
- 0xe256292d, 0x98cb5593, 0x3f768cdb, 0xf1d78758, 0xe1733c3a, 0xd47855fb,
- 0x0b80f7f7, 0x85b7ab48, 0xe681b5c2, 0x1ceae151, 0x7945e512, 0x0aa7ed52,
- 0xf5d4a757, 0xb7bf262c, 0x013fbda4, 0xdb19d6e9, 0xff412595, 0x4423a4c5,
- 0xaea4cec7, 0x48472567, 0xa8e9c0df, 0x38c5727b, 0x19e7bc2f, 0x024ba9d9,
- 0xf91946fc, 0x8c26933e, 0x8f3de057, 0x58bdb924, 0x73be03df, 0x32ef91f8,
- 0x4687a48d, 0x27e6d50d, 0xcf9c492c, 0x3a3b459a, 0x30feb9aa, 0x9b67a5f0,
- 0x78c056c4, 0x236ec5cf, 0x6d8989da, 0x684e8c27, 0x309db6eb, 0xc3aabea2,
- 0xb753cc3e, 0x6f5118c1, 0x7992486d, 0x0fcc329e, 0xe0399bde, 0xc7dc44a1,
- 0x45512950, 0x091ddeee, 0xef7fb1a3, 0xf8255c5c, 0x8eb7232d, 0xb966c7c6,
- 0x76c21fda, 0x8bd8eb0e, 0x2dc3342c, 0x99d2fc6b, 0xbf1a31d5, 0x5dbd5676,
- 0x0cd39fd3, 0x9eb901d4, 0x1b5d2cb3, 0x5b88303f, 0x2c199e01, 0x6dfa87f8,
- 0x8ce3a0ba, 0xdc01b5d4, 0x6dc332c7, 0xcc8476f0, 0x856db137, 0xd77086de,
- 0xbf520e4b, 0x73e0a65e, 0xa10af933, 0xeb437bd5, 0x795ba362, 0x86aea332,
- 0xd815fbfb, 0x5456bc07, 0x42453e4b, 0xbee9183c, 0xfba255a7, 0x47c7d69e,
- 0xcf323ee1, 0x26f28952, 0x3c447dc9, 0x1cefec24, 0x51e82b01, 0xf333ce03,
- 0xa3b312fb, 0xbefe10de, 0xe99cff0a, 0x3f89a7e5, 0xaeaf9f85, 0x7602ba73,
- 0xc9cfae17, 0xfe80c4fe, 0x64efac35, 0xda9f0687, 0x6d7aacfe, 0x6d32ce7f,
- 0xf0926a7f, 0x81b207df, 0x93d34f28, 0x55ea3d24, 0xe645ffb5, 0x01f96ffb,
- 0x6bb2cd9e, 0x8d67f226, 0xa8f54fd1, 0xfa9bb2cd, 0x5eb87dea, 0xc0ee48c7,
- 0x9639201f, 0x19573e48, 0xf412d69c, 0xe2256ba3, 0xc42c99db, 0x8e09c85f,
- 0xb3dcbea7, 0xd71268ff, 0xaeccab3b, 0xdb1754a5, 0xc1375929, 0xa77a51a5,
- 0x55c0fd1e, 0xc8bce452, 0xdedc4963, 0x8a20c5be, 0x2006b807, 0x9f5da293,
- 0xc2f3ef1a, 0x76fc077b, 0xfbfd17ae, 0x07c08501, 0xb73dca0a, 0xbd85e337,
- 0x25fe0499, 0xe4037ffa, 0xdfa4e996, 0x495a346f, 0xa43b0bbf, 0x2fe70bea,
- 0x7c6876b4, 0x3f8a7ec6, 0x7b5fad26, 0xff62f50e, 0xc782ce7e, 0xcc47be01,
- 0xec8ffdfc, 0x2fb87c90, 0x3ed06ea7, 0xc0299fd2, 0xbadef816, 0x5b47a154,
- 0x52aefbb5, 0x2e61af50, 0x7a20c27f, 0xe5499a6f, 0x41e92776, 0xbbaa5fc9,
- 0x4529fa04, 0x0ca6f7bc, 0xbc95f085, 0x75c245a8, 0x0aef3267, 0x463fe3b4,
- 0xb60a4c21, 0x8fcfed57, 0x79fdc292, 0x65e6124b, 0x148c3b52, 0xe32eb1ef,
- 0xeba7943f, 0xf2327f39, 0xb0fcf859, 0x0757aa7c, 0x718bf2e3, 0x77b9af98,
- 0xdc6fbf67, 0xb49b24ef, 0xaac1b771, 0xe7c7bb8d, 0x44cff569, 0x4cef5687,
- 0xb9a7ee2e, 0x5039c53f, 0x796a7f73, 0x877fa6a1, 0xf8cd66eb, 0x6997a6bb,
- 0xe3a951fa, 0xda00f2c2, 0x9e4c4afc, 0xeb12bf36, 0xa251e6d0, 0xba7afc0e,
- 0x9a317804, 0xc06e1dbc, 0x46c81343, 0x47682db1, 0xa899c606, 0x685d1b48,
- 0x34db60b6, 0x7c8fca24, 0xc787d4d2, 0xbe0751e1, 0x7987ea9f, 0x4c5bf14c,
- 0x49788a58, 0x8a6295f2, 0x7544d018, 0xd41e1bd5, 0xd3d39bfa, 0xeda95cb8,
- 0x99f724b1, 0xbc1bac64, 0x7f73a4a8, 0x89f14036, 0xbf719a29, 0xfc89bb68,
- 0xbe4e3522, 0x9465a71c, 0x0eba409c, 0xf549d07a, 0xaccad613, 0xde7c5798,
- 0xdba9f228, 0x41dc3ef9, 0x673a1dad, 0x492f7c88, 0x49e0fae6, 0x9c58e957,
- 0xac0daebf, 0xfad3ca2c, 0xa7588c8f, 0x8f6b6bac, 0xef967b43, 0x7988c8fa,
- 0x6175e0bb, 0xd15df4e7, 0x55f95f58, 0xff711c8b, 0xf7cc92b2, 0x7a13ec6b,
- 0x83f7d67d, 0xb0c951f1, 0xb59e7ea0, 0xc32fcbb5, 0x5e8167fb, 0x4a6bf2f3,
- 0xfa0d3d24, 0x3ccf1359, 0xa7eea699, 0xc1ec6a71, 0x037ec5dd, 0xed6a9fd9,
- 0x78d339f8, 0x5c7a045c, 0x91a33d7b, 0x1d630bf4, 0x815bcc06, 0x8fdcd75e,
- 0xd271164b, 0x12e83640, 0xaea381e8, 0x2bb5fbc8, 0xc744f4d3, 0xa232eea3,
- 0x4f8093c3, 0xec9f97f4, 0xd78e3f81, 0x65ede12b, 0xfa1081e4, 0x4fab8f85,
- 0xcbf47ee3, 0x07ede8bd, 0x979f7d04, 0x54a80502, 0xe268ae3d, 0xb9a699df,
- 0xf73f718b, 0x1aafccbe, 0xeb315eb1, 0x7b4312d7, 0x03f687fb, 0xb8cf8fb4,
- 0xee326f75, 0xecb4f4af, 0x7fc0664d, 0x05650635, 0x1fc0f3fa, 0xea7ff40e,
- 0x7f04fd5a, 0x3b614b6d, 0x956daf5e, 0x3d92a81c, 0xa18dcedb, 0x468eb275,
- 0xdf3dffac, 0x93235c0b, 0x5b755fb9, 0x04f3c2b2, 0xda27786e, 0x3e516dfd,
- 0x00fc849f, 0xdae109fa, 0xe866b121, 0x14dabf3f, 0xa0fbeeb1, 0xd59ef7c0,
- 0x6ab38a46, 0xc75c79e0, 0x467dccbe, 0x56d3f213, 0xeb849758, 0x0c477c38,
- 0xc0d4bfce, 0xe150cfd0, 0x3819933b, 0xb0ffeb8e, 0xb81d0212, 0x2652aabe,
- 0x54b87f7c, 0x9fe723e4, 0xb8c74c6a, 0x77ef96a6, 0x4dd95ddf, 0xab0fbe79,
- 0x36569fb9, 0x397240df, 0x57f70963, 0xe55af9c2, 0x9f05a7db, 0x386ff386,
- 0xd7e0f6df, 0xd7e3abea, 0xe6bf20ca, 0xfa07dda3, 0x3e414e8f, 0xeeff01fa,
- 0xddc5fa65, 0xbb801486, 0x81d5a36f, 0xcb06bdfb, 0x519287be, 0xf7e6ec6f,
- 0x946cd487, 0xee51feb8, 0x37a5f5c6, 0x091ad919, 0xedd389f9, 0x85374101,
- 0x14314975, 0xa2fa05ff, 0xbf51ca9e, 0xe9b03087, 0xa73f315b, 0xf067fae7,
- 0xd71ba96b, 0x6e6ff084, 0x555be732, 0x32340e2f, 0x07aa56f7, 0x0299f4b4,
- 0xe06cbcf3, 0x312c9cf5, 0xaebf6e5f, 0x5da05331, 0xe4f5cc9f, 0xda87010a,
- 0x80e4275f, 0xf84ddc65, 0xf8e2689c, 0x5fccb71f, 0x99f8eb81, 0xea30fdd1,
- 0xef5909d5, 0x6bdda0d7, 0x20e6fbea, 0x07321fca, 0xbc6ae1f9, 0xa7c47bbe,
- 0xf583ee1b, 0x268faf9a, 0x3e779afa, 0x367e456e, 0x714d0ee7, 0xb53fe047,
- 0x61c85cf5, 0xd5f03b6e, 0xaad47e85, 0x4ebb29fd, 0x729f691b, 0x2431b9db,
- 0xe8d2172f, 0x535cfaba, 0xc1cf971a, 0x9aa83f62, 0xadbd04cf, 0x8e082e2f,
- 0x70c0f153, 0xc2115e77, 0xebd102f3, 0x086c25be, 0x4e3fab4f, 0x73599feb,
- 0xf30b9a58, 0x1a7065dc, 0xf7ef802c, 0xc62fa7e3, 0x2e6f2ffd, 0x851dcc67,
- 0xcc4ceffb, 0x03ee1d7d, 0xb03f52b4, 0xeffa953c, 0xdda8572c, 0x84bd7262,
- 0x4f63ba78, 0xabed2e7d, 0x55ca7ccc, 0x3ce9ef0a, 0x053b1068, 0xa827e44d,
- 0x36eea1f5, 0x7ee09999, 0xea8936f7, 0xb3fc2a9d, 0x3733a42f, 0xe3df97e8,
- 0xdac1e0fb, 0xde92ef65, 0x1b9f5473, 0x90d27183, 0xd88d139a, 0xf3fb2cf7,
- 0x8e2ff418, 0x3e413d83, 0xa59fbf03, 0x0e4fa84a, 0x5ddf711b, 0xcd3b05c5,
- 0x6baeb2f3, 0xf79dca0c, 0x50ea890d, 0x19cf5bc7, 0x62bdb853, 0x5806ca08,
- 0xffe0139f, 0xeb813922, 0x3a21b693, 0xdca1df4e, 0xd0fc11af, 0x71d7c37e,
- 0x32d30f48, 0xf19bede5, 0x4332fdf9, 0xda535eb9, 0xa08d6715, 0xbcc28f87,
- 0x75c15c98, 0x7f7e1b60, 0xeb9bd1ba, 0xeba6e780, 0xfa9bef22, 0xbe72f92c,
- 0xff14e482, 0x0ab7e024, 0x60b36fc1, 0x8a36f149, 0x20d1fc83, 0xcadab3cf,
- 0xadb1eb4e, 0xda47d897, 0x147d8cf8, 0xc6f7c7e2, 0xadb6df87, 0x8372f9c3,
- 0x59238c7d, 0x71845f88, 0xdfbcd324, 0x994cf3cb, 0x11dc53fd, 0x0e5979d6,
- 0x03bfc03a, 0xe381d57a, 0xdf91d8a4, 0x767b5207, 0xca0ac3c7, 0xebba298f,
- 0x6c17b429, 0x8ee28e80, 0x1fd6af5a, 0xe5ca963a, 0xc0aa58e1, 0x7e368a5b,
- 0x4e493882, 0x1c5271e1, 0xe2438416, 0x14ebf0a7, 0xae50993f, 0x8103bde0,
- 0xa244af3e, 0x29a96a4f, 0xabe50925, 0x019cf899, 0x857f239f, 0x229ed3af,
- 0xae42d9f2, 0x235ca067, 0xb972b6ff, 0x3bb79f0e, 0xf38ec4b5, 0x5c7dc6ae,
- 0x69c6f411, 0xf5daceb1, 0xb3cbe112, 0x3a784ede, 0x4abbd6c3, 0x00cf2f81,
- 0xa02fb81c, 0x498ae5d3, 0xdb8d7ac0, 0x04b36315, 0xfadd40f5, 0x756e7a18,
- 0x73eddbff, 0xc2979fa1, 0x6b6cfef9, 0x3cf10999, 0x3f973d7b, 0xfdc77df5,
- 0x4f28ec33, 0xa32e8645, 0xb467ee03, 0x3f43889d, 0x54c768b0, 0x6f61ca3b,
- 0x70a86670, 0xf16fbb2e, 0x07e73b49, 0xf5aa6fcc, 0xbf4acf38, 0x78bff111,
- 0x6dfe2319, 0x3a87fedf, 0x6db3e394, 0x87b45631, 0x78c67667, 0xbe77ff51,
- 0x49d3e511, 0xe3788714, 0x319daf41, 0x7f224c74, 0xc56c8773, 0xc6f3d1f8,
- 0x3ca14fe7, 0xa147b67a, 0xb716c7e7, 0xed0e7c3d, 0xd8db4d5e, 0xda7cfad3,
- 0x954ffe87, 0xf765da87, 0xfed57ad3, 0x0a4dcbe7, 0x7ab3d1ea, 0xb71627ae,
- 0xeffe4abe, 0xf9dd8be2, 0xb33f0f58, 0x50c36ff3, 0xdb7e79af, 0x99f50c3d,
- 0x61eef5e7, 0x5af3df78, 0xbf247d4c, 0xf3c697c5, 0xccbdaa40, 0xe4d7a239,
- 0x5d85a28b, 0x2e6869c8, 0x459d7dc7, 0x3039a787, 0x2fdeab9f, 0x7ed1d5ca,
- 0x46f7a2fe, 0x3c87e7d9, 0x97d010d7, 0x87a1f5e3, 0x8654c547, 0x41aa65f2,
- 0x555e37cd, 0xeaef079e, 0x75e48587, 0x19a73a02, 0xe80eadc6, 0x6adafef9,
- 0x06f187c9, 0xcfe12ff8, 0xb9d53f91, 0x435beed0, 0xfc6b827e, 0xcfd8a1e0,
- 0x5051ac75, 0xf6f698ad, 0x6697f10f, 0x28fe7404, 0x6de9a3e0, 0xf7f27e51,
- 0xd413fa03, 0xecd47e17, 0xe6c69f73, 0x34f21148, 0x468cef79, 0xaf9e1e3d,
- 0x8458bf81, 0xdeaff55b, 0xa3f9e34f, 0x0eab7a8c, 0x345667f7, 0xb5e22b30,
- 0xfa675e47, 0x0a2f946d, 0x8128efcf, 0x4e7c2675, 0x22b3afe9, 0x8a5faabc,
- 0x4116dc74, 0x72a6240f, 0xaf9544bf, 0xe88e8086, 0x352810d3, 0x563687f5,
- 0xab36d7c8, 0x68f7be8e, 0x09ba9b68, 0x170d0bf3, 0x0c198aef, 0x723869ef,
- 0x3defc33b, 0xa6a5ad3a, 0xe2ee7c5c, 0x063ba66d, 0xfc26f905, 0xb852c77d,
- 0x0bfa0cde, 0x21dfed91, 0x59fecfa1, 0x8a40f076, 0xff3de44e, 0x1083b6ef,
- 0x7852079f, 0xe7933e7c, 0x1e7c784f, 0xbd543f6e, 0x092bceac, 0xcbd4f73a,
- 0x81cfc9a7, 0xb2f49a38, 0xb8d0aa94, 0x7629b68c, 0x4c8faf8a, 0x9e962bb3,
- 0x3bd3f7f3, 0x3d41b674, 0x39fd57e7, 0xd7b9d78f, 0x938f7184, 0x4cf323ef,
- 0xaddf6893, 0x5c79ffea, 0x9ee5f912, 0xc70f830a, 0xa60570a9, 0x1dec7cf1,
- 0x2ccf834e, 0xd544fd05, 0xdf7cbc8f, 0xd57dd121, 0xc7fd54af, 0x77e78b80,
- 0xf7e50da7, 0x17dc98b7, 0xf71f2ed0, 0xd17ae99b, 0x319d7e08, 0xab8c5ed7,
- 0x6253baee, 0x5f8407a4, 0xb869f2a9, 0xadbe79df, 0xa3ee37df, 0x53f820df,
- 0x30acb395, 0x58ed50f9, 0xc7970a5e, 0x85e3b43a, 0xaaffc768, 0xe7c3cff1,
- 0x496e3b05, 0x3d18e7a5, 0xbd3df43f, 0xfebc522b, 0x0ca790ac, 0x3d817e95,
- 0x266f0825, 0xd83ed00b, 0x7c6becde, 0xded7971a, 0xb909e7ee, 0xdf3c92b9,
- 0x3fccf426, 0x52cb9e4b, 0xb5f877ff, 0x5ec3fd97, 0x2cfbc7be, 0x2a4264b5,
- 0xae5a35e0, 0xfca0940f, 0x6221a7fd, 0xd85d3add, 0x3577886b, 0x699bd9f4,
- 0xe47c61d4, 0x83f9e6a9, 0x6de504a6, 0xc80e638a, 0x317b3fb4, 0xc7e883c4,
- 0x4090ba2d, 0xcbfa0d6d, 0xf17cced0, 0x6623d530, 0x6fe16b56, 0x3e2e9cc2,
- 0x87c724bf, 0x362cf3fe, 0xb34cf28a, 0xb8ac12da, 0xa929b9df, 0x95ca1f65,
- 0x6cac9377, 0x50bf1d0a, 0x79e26f1d, 0xb46965b8, 0xf98592bf, 0xc3eab303,
- 0x7fad7efd, 0x1bc8b370, 0xbc27e6f5, 0x7ae66ede, 0x724cbf65, 0xa6f9875e,
- 0xb633191b, 0x59e0bd71, 0x7524f3c6, 0x7be82b6d, 0xff715aac, 0xf2807d33,
- 0x835f5450, 0x1edba7a1, 0x6479464f, 0xa93d6d4e, 0x48f785f6, 0x95d7865f,
- 0x5eb8db6c, 0xa2c8d4f2, 0xc24c348e, 0x93c42d7e, 0x2a5fe829, 0x3bc464ca,
- 0x57d9a5c0, 0xcf05faa6, 0xf9d2ba8b, 0x1c531ffd, 0x2f47733a, 0x71a6a475,
- 0xf6248ebc, 0x23acf46f, 0xae9bdbed, 0x548eb95c, 0x80d87ad7, 0xea95c5f1,
- 0x5ea4cf49, 0xde5127ae, 0xf3cf5b31, 0x926dd9bb, 0xd955f315, 0xc3dd7c6d,
- 0x7f934757, 0x958fe63d, 0x2a07d476, 0xe14ece9d, 0xe1fb3df8, 0x75b42597,
- 0xab7a8fe0, 0xfaf5d619, 0x4ddf4b87, 0xa4c57de7, 0x634b73e0, 0x3fe9bbe8,
- 0xf8831bde, 0xa45a1d7d, 0xf5476bcf, 0xc193f391, 0xa92bf57c, 0xf9167794,
- 0xc3d83d6a, 0x275e60d8, 0x855bb9fc, 0x70826bbe, 0x3b9af285, 0x29bfdd78,
- 0xfa8e3dcd, 0x36cbeb3f, 0xa4e89f91, 0xc0abf47c, 0x1a3798d7, 0xbac58b08,
- 0x59a32ff4, 0x9a91d603, 0x926fdc92, 0xa74cfd1c, 0xf3c11ca0, 0x6ef27f54,
- 0x623ec855, 0x3ceb0bea, 0x858046f9, 0x7df03bf6, 0x3a083713, 0x8b3c41a6,
- 0x33402571, 0x03d0eb0d, 0x3f27bd45, 0xfe71e99a, 0x35ee0c47, 0xa97d63d7,
- 0x4158ef5d, 0x4fb0e042, 0x7759ed89, 0x5ebc9c92, 0xd49fd6ae, 0xf56f79ba,
- 0x93df0927, 0xea8ff9cf, 0x9cff624d, 0x7762675a, 0xb5f8a8ba, 0x619eb8aa,
- 0x832c3afc, 0xd2faeb5d, 0xd42392df, 0x4c294c7f, 0x7ada67f8, 0x57bc9ae3,
- 0xdeff4f88, 0xa96de33a, 0x1efb1fec, 0x0adc07a6, 0x0c322eff, 0xe709a1ee,
- 0xfaee2993, 0x91c4bfef, 0x26eb6d9d, 0x15d9d87b, 0x7f9402c5, 0xf779e0ec,
- 0x503dfe36, 0x496fc427, 0x7e767621, 0x57779f0a, 0xfff1195b, 0x18a8c0b6,
- 0x0a58ff1c, 0x23eac7a7, 0xbfa2a6d3, 0x69e80def, 0x3c630ebf, 0xd016db1e,
- 0x72dfa117, 0x9a92e90d, 0xd12e891a, 0xcb853edc, 0x7f6121d1, 0xba72a50f,
- 0xe3c87d95, 0x5e52cf30, 0xbd0ab15f, 0x75e7a9e0, 0xc9997df5, 0x4f4f9a92,
- 0xd97f5489, 0x637645d1, 0xf68942d6, 0xfadb7ed5, 0x916913cb, 0x5b33f1eb,
- 0xbfae444f, 0xfd218f94, 0x3b3e5bd9, 0x4b7d8f3c, 0x0f63c89a, 0x5fec79e6,
- 0xbd695aa5, 0x2521fab6, 0xfaeab2c8, 0xbe1d21af, 0x87408b48, 0x5c7f386b,
- 0xdf5b77fa, 0x7d5230fd, 0x6fce1af7, 0xe16efe4b, 0xa7e92257, 0xf3bf386b,
- 0xfd7f9e3b, 0x8aff3c77, 0x77ff18ef, 0xff9844a5, 0x01fdd5ff, 0xf0fff5e1,
- 0xfbe102fd, 0xcc0ea200, 0x87bde2f7, 0x7e5db5a5, 0xdb714d68, 0x07a04ba7,
- 0x982f09f5, 0x184e8ed0, 0xab61ebc1, 0x1b7c9947, 0x01bee0a5, 0x832c5f15,
- 0x41d611c7, 0xc076bce7, 0x30339673, 0xb2f98eca, 0xe0e28c11, 0x8baf334e,
- 0x6d35bd31, 0xb7c3ed0a, 0x7e0edda6, 0xdf2f5349, 0x174e6d33, 0x762f6171,
- 0xc9466464, 0xacefa867, 0xd5a5fb61, 0x6aea29d6, 0x0fbe56d6, 0xb495e997,
- 0x4abde9db, 0xf143fa1a, 0x38f5f87b, 0x246e733f, 0xdb9c94b8, 0x72541e29,
- 0x4427be10, 0x6e36d7fd, 0xa5e60e40, 0x6217e06d, 0xac71f05d, 0x6b3c520f,
- 0xfbea71a5, 0xbf87d87e, 0x930309ef, 0xbdeb9eb0, 0x6273ef9e, 0x5d4d6a96,
- 0x7fc1a0ef, 0x7544ae72, 0x8c0fb93d, 0x0ff3a43f, 0x30473e7a, 0xd077e031,
- 0x1bd52b36, 0x1ff11adf, 0x26bbfc79, 0xcfbbe75e, 0xc6ec87ca, 0xb8e019b8,
- 0xf121676f, 0x235dccef, 0xf8c0a83e, 0x2f3f3fa3, 0x295c47a4, 0x454705f2,
- 0x17cd43be, 0x63adf5a8, 0x1c724f22, 0x76d02ff3, 0x5a043e60, 0x5aee8fa5,
- 0x4fa527db, 0x84f2fd04, 0xde43f3c4, 0x543f3c43, 0x0bf47468, 0xb8394fdd,
- 0xb9abe70f, 0x50bf5e7e, 0xc59b3df3, 0x207f0a7a, 0x2fc0a3fb, 0x6c1c6c2d,
- 0xd85f3b44, 0x6d8d1998, 0xc3a7d3be, 0xca8cef52, 0x7e953aad, 0xb868f891,
- 0xfdeae758, 0x7bdf545d, 0xffeeac35, 0x3f7c3ec3, 0xc7e0b743, 0xd461f61f,
- 0xbf572fbf, 0xf8c7dd0a, 0x52395691, 0xc416695d, 0xdce708c5, 0x8ab70e26,
- 0xa57e59ef, 0x6273df0c, 0xb623576f, 0x6539d505, 0x39af7794, 0x9bfe88d7,
- 0xbef762e7, 0x665f295b, 0x989e3054, 0xbbcda1dd, 0xfe7832d9, 0x7f8955fd,
- 0xab1de9af, 0x70b8f8a7, 0xc7f89eac, 0xf14ccb36, 0x64c0cdab, 0x70a7f60b,
- 0x3ca0a8bf, 0x6cfb0cb1, 0x83f9025a, 0x8495fb05, 0x798283f9, 0xa5d8db30,
- 0x2ba78849, 0x7cd559d5, 0x739316da, 0xeff3d23a, 0x1ed6b3ad, 0x4dfb423c,
- 0x78a975d5, 0xbda5eb51, 0x7dd559d5, 0x2ff29e0f, 0x3c34fb35, 0x9831aefa,
- 0x79dc2c7f, 0x5ff628c2, 0x8273535a, 0x1dc2d875, 0xaafea8e7, 0xf53d5bd6,
- 0x86afc8e7, 0x929ce8e7, 0xfd79cb6d, 0x81c03b75, 0xdbac2b6d, 0x06fcf009,
- 0x1b6d8dd6, 0xbfaf1bac, 0x5a8f3cb1, 0xb50772ff, 0x531796bb, 0x93ec085b,
- 0xedbac366, 0x2edbaa39, 0xdf63d3ef, 0x36f5d524, 0x2895aecb, 0x3f7521ef,
- 0xfdd787ea, 0xaf9e68e4, 0xd037ecf1, 0x839e0c77, 0x25dfd226, 0x31b3736d,
- 0xb0eaf83e, 0xaee11b3b, 0x085bbac3, 0x3a759c5f, 0xc66e78cc, 0x8cc39759,
- 0xf6c2b6f5, 0x0fdc46d3, 0x180fa753, 0x90061f31, 0x4596e3a7, 0x7c73b6cf,
- 0x895b6fdf, 0xc57bf119, 0xffeb58fa, 0x3dfd8faf, 0xa0acb1f5, 0x291e927c,
- 0x1b9ce970, 0x34efddb1, 0x13d10fcf, 0x9ebc5dab, 0x5f7fbab2, 0xae75c392,
- 0x219509be, 0xf39435f3, 0x6c6d85fc, 0xf5e8737f, 0x1e061925, 0x4239e047,
- 0x41ffde11, 0x8e35dd1f, 0xf41fdd5f, 0x9d57e089, 0xefa2643d, 0x2c77da49,
- 0xc418eec8, 0x1f343f05, 0x32bcbab7, 0xf7cfbf1b, 0xb9628d1e, 0xc9a75f3c,
- 0xbab0b1c7, 0xb9796f5c, 0xa73ae599, 0x750bf699, 0x0edda165, 0x7d319fcf,
- 0xebb71657, 0x9e7e74ce, 0x159d3783, 0xb9f51eb3, 0x7bdf33df, 0x8cfc61fd,
- 0x0bd91d72, 0x50574eb5, 0x81cb67ae, 0x19960b3f, 0x2b9f547c, 0xfba09fd7,
- 0xb06c6e22, 0x9f23a416, 0xb4683f1f, 0x3c2d5e62, 0x7f28e63f, 0x3c2fa9a1,
- 0x1c91a8ef, 0xd52bacb8, 0xe07dd4f1, 0x47db5ab3, 0x086dbe63, 0x051a6e6b,
- 0xafe90fcf, 0xe9fee2b3, 0xbe3cf59e, 0xf840bbff, 0x3679e139, 0x4bf433e4,
- 0x71f0f3c2, 0xe20f9ce9, 0x9cfdb9d2, 0x0a2db480, 0x173ea3ce, 0xd2f33fce,
- 0xf0bf75b5, 0xfdc553fb, 0xd582f286, 0x13be91fd, 0x49ed0c74, 0xa9a97943,
- 0x397cc87f, 0xdb7f7ce9, 0x4c1f5813, 0xf20fad0c, 0x5d78603a, 0x8573d550,
- 0x831d7fed, 0xfa075ef8, 0x2798ed1a, 0x0a0fd795, 0x8fd928df, 0xa708237a,
- 0x7a953fd8, 0x04ec7bf9, 0x70c5d7c6, 0xa7779cff, 0x82b9f944, 0x8aee5f09,
- 0x81733e81, 0x76bd43dd, 0x0b2affb0, 0xfa09a3ea, 0xc7aefc22, 0xd72e92e3,
- 0x349eb099, 0x71eaedf5, 0xe1419df8, 0x230e431d, 0x30a8ee5d, 0xd540fed0,
- 0x7b7d4dee, 0x7f7e18fa, 0xbc68cae3, 0xcc39279f, 0x2f2f5e0a, 0xb7e3ebc5,
- 0xce9331f8, 0xa0742226, 0x4f0703cf, 0xb66e51ea, 0x1825dc98, 0x114e173f,
- 0x6e0aa675, 0x9b68efa7, 0xe7e46062, 0xeee6ed69, 0x1f28afcc, 0x4856ddd4,
- 0xee3b23f5, 0xb414187f, 0xc13b8537, 0x3b5ec58e, 0xdd2f363b, 0x11bcf84a,
- 0x63c218ec, 0xf4ebc29b, 0x11cff4e1, 0x2ecdeff4, 0xd187a6f5, 0x2b39e0fe,
- 0x6a529f28, 0x60ae3b4f, 0xfa3867de, 0xc21e12eb, 0x35ff2bd2, 0xd096fd0b,
- 0x4eb73f8b, 0xfbaf7bf0, 0x39ff5aa7, 0xf4e6a675, 0x63751dff, 0xeb52fe35,
- 0x76bc6a4d, 0xda81f046, 0x3fed159e, 0x1a037dfc, 0x37df88d7, 0xdf7f22d8,
- 0xce85bb30, 0x6fbf5129, 0x25646bd8, 0x3f71135b, 0xc9def8ad, 0xa4fc8537,
- 0xbeff4fbd, 0xf88917f1, 0x278493bd, 0x3c3d806b, 0x3d5e764c, 0xedaeaeaf,
- 0x6d6f9e73, 0x6bc3fbe1, 0xfb9f235b, 0x77da0372, 0x2728ef78, 0x2b51bd23,
- 0xd98edbf6, 0x9744ea26, 0xebf796f3, 0x1e96f343, 0xeea49025, 0xbc51f5e3,
- 0xf663cda7, 0x53acb796, 0x96afcfbf, 0xae1f681c, 0x59b70fb4, 0x35edd7ec,
- 0xe6fce98f, 0x79e1b97d, 0xb5d3f7cc, 0x69939c75, 0x74ff5a56, 0x36e744b7,
- 0x1aae7499, 0x86ffb7da, 0xcfb48d64, 0x87610bfb, 0xc83a8bc6, 0x3f9c8dcf,
- 0x44937e7e, 0x77e0dfdf, 0x9ff74878, 0xc3bfc1bf, 0xff0179f9, 0x7bad470e,
- 0x5cd7dfa8, 0xd07bac1f, 0x77ea77f7, 0x3677ea39, 0x539d77ea, 0xb9d347d6,
- 0x5a188fc5, 0xebdfb952, 0x3a7cbe25, 0xe8fdd19d, 0x491f5628, 0x97a68f5e,
- 0x845e9d3c, 0xdc79aee3, 0x423d297b, 0xe30c3bdc, 0x218f7848, 0x3c85e203,
- 0x305e2916, 0xe2691465, 0xc787ea05, 0xeeaad70b, 0xcfc0a4f1, 0x6df75c35,
- 0x6bc6fc91, 0xdfebff38, 0x45affcf1, 0x732adba2, 0x1f17f3e4, 0xbe8490cc,
- 0xce179ed7, 0xc92f7c7a, 0xa4937aed, 0xd533707c, 0x4f540dd3, 0x536af557,
- 0xbc7f9f2c, 0x6da9a7c8, 0x0c9b6895, 0x4b65f391, 0x6467fdc4, 0x93e438e7,
- 0xf36a2f81, 0xb45b8397, 0x5b1bcbf9, 0x0c88e7b5, 0x09cf6bf1, 0x3dafdc29,
- 0xa028a63f, 0xf8663f3d, 0x31f9ed51, 0xe7b43a23, 0x99fcdcc7, 0x5b98fcf6,
- 0xcbf9b4ba, 0x1edc2f5b, 0x8fa71df6, 0x9c09479f, 0x995cfa1b, 0xb9d85e69,
- 0x73b0ba35, 0xcec3a26b, 0x1f3b09ad, 0xe39bcc45, 0x7e7613ed, 0x367d768d,
- 0xba0dc7ac, 0xefdc7afa, 0x1ea228fa, 0xcf8ccfd7, 0xdfde513d, 0xfa9b7e8c,
- 0x097ff53d, 0xe1913b3e, 0x71f4815e, 0x875b1caf, 0x22b1d57c, 0x2ef30b2a,
- 0x726995ee, 0xfb83f022, 0xa7be8951, 0x46995d2f, 0x35e67bfb, 0xa93f210c,
- 0x4fc93980, 0x1167659a, 0x9cd879cf, 0x3decf5c1, 0x8c6606f5, 0x462997c7,
- 0x33d0a81d, 0xc35b124d, 0x22658ded, 0xe33561f0, 0xfabb587c, 0xbdd51c70,
- 0xc859dd85, 0xebaac151, 0x0e79d017, 0xa8bde7e1, 0xc623c676, 0x6316b0d5,
- 0x68bbcc1a, 0x47c93b6d, 0x1e3079f8, 0xea1cf6b6, 0xb096dae1, 0x7db7f5eb,
- 0x1ff7f8ca, 0x3c8bf446, 0x2ffbdaad, 0x99ba8864, 0x7e503983, 0x9ac7f7dc,
- 0x152ccfd0, 0x56bb99f8, 0x709d62b2, 0xd27b435e, 0xb79fd05d, 0x4bb8a65f,
- 0x71eb0fc5, 0x3a20cf4e, 0xfefcfd57, 0xcfa3f25c, 0x8e0a4a2b, 0xb8f1c773,
- 0x87bbd241, 0x7659f5e3, 0xe73c70f7, 0x58c3ebac, 0x9d87f6fc, 0xdf9320b8,
- 0x3e50be00, 0x96566ff9, 0x9def9a1f, 0x6326b06b, 0xeecbc5be, 0x5378a54d,
- 0x7e2abfc4, 0x6788263c, 0xf10fb0e3, 0x749f5f2a, 0x91fa2249, 0xff02eb69,
- 0x7e03df08, 0x26b3c510, 0x7e815a66, 0x39a569d0, 0xd7605d19, 0x2ff20643,
- 0x4092d9ee, 0x0d3dc5fe, 0x1f3c4665, 0x096d9ee1, 0x79969fb4, 0xbe30479d,
- 0xa279e955, 0x2a5f70a1, 0x4b4f7bcc, 0xd2d6438e, 0xd137e4f1, 0x09d35171,
- 0x7b277e95, 0x48c9dfa1, 0x69ba03f4, 0x4321ffae, 0x6e8209f8, 0x7d3b41ec,
- 0x64b157e7, 0xffe62e6f, 0xe99bd7ce, 0xc67a2bf7, 0x37ae5e05, 0xc4d26f2b,
- 0x2e7de53f, 0xbe7475c7, 0x22daf777, 0xdd385fa2, 0xde67ffca, 0x8afefc70,
- 0xa1963efd, 0x1fab31ff, 0xc63b739b, 0xb79712c9, 0x96c6ab59, 0xa5f3bfa3,
- 0x8b6fcfd0, 0xc630e938, 0xbfd7e049, 0xf412718b, 0xd27113df, 0x41271807,
- 0x49c621fb, 0xe7149ed0, 0x0772aa05, 0xfb7c408c, 0xafb790b5, 0x6378d433,
- 0xd7e62a69, 0xdde7ffca, 0x5f159d22, 0xa349e3f5, 0xec9b1933, 0xd3d7fad4,
- 0xebfd69a7, 0x4c75830e, 0xd581da2a, 0x8f705ebc, 0x78cd66eb, 0x988c57a6,
- 0x857960f7, 0x8f64ebc1, 0x3de62314, 0x6bb04c66, 0x94d9dfc6, 0x32dbe9ae,
- 0x94f75a15, 0xeb9a7ef2, 0xd40c5777, 0x005ee7f4, 0x5df90cc7, 0x59f92629,
- 0xc626e22a, 0xac5d398a, 0xf597ec7c, 0x001e53c3, 0x683cbf78, 0xf4e1fba0,
- 0xb95ae950, 0xee7ca65e, 0xf312f5bc, 0x9b278802, 0x7d7c91e7, 0xce96347e,
- 0x52dc6991, 0xf43156f8, 0xd0316c4f, 0x0d13b2fe, 0x7cf147f6, 0x925b13eb,
- 0x3dbbf0e2, 0xfccca377, 0xa4ad77a4, 0xcb79d577, 0xefd0561a, 0x45f5cc26,
- 0xcc0f5039, 0x567de3dd, 0x4ddfa3ed, 0x4e50665b, 0xbf3ec88e, 0x1273f444,
- 0x299b377e, 0x8199fe4f, 0x92a7f179, 0xb87075e6, 0x0358933e, 0x8f9b4ff6,
- 0xe000780d, 0xb9b13338, 0x957e874a, 0xf489307c, 0x43322be7, 0x6258adbe,
- 0x1787f3a0, 0xc46f27be, 0xd20a933e, 0xfa65bd39, 0x39b60f7d, 0x5d67e68a,
- 0x6e3021c0, 0x9ea22fe9, 0x5ef2235f, 0x60f5ffd4, 0x9fc11adf, 0x259f47c8,
- 0x01026730, 0x7f0ff3cb, 0x75449c3a, 0x7d3e209f, 0xffeeb8f9, 0x64c6bbd0,
- 0x54fefd02, 0xfd27cbe5, 0xc91260f6, 0x4fde3855, 0xf2feb91a, 0x41481ca2,
- 0x339419bd, 0x3cd5fdfe, 0x41d92383, 0x1a686b7a, 0x6b93adea, 0x6467940d,
- 0xaf1c677a, 0x7c42bdcb, 0xa4e7beac, 0xf083195e, 0xa1ca6c9d, 0x59ef0cef,
- 0x43fd932b, 0x7de3e3fe, 0x971fff9c, 0x7bbf18dd, 0xc637249b, 0x737ce1ef,
- 0xf4e192df, 0x11b3047b, 0xea7a2327, 0xbc69b381, 0x17f6a10e, 0x07bfe4ed,
- 0xe87686c0, 0x5d0e0da7, 0x9f7f0347, 0x4e7358bb, 0xdfdf4d79, 0x9c23c71d,
- 0x17efefce, 0x9ce9df8f, 0x9f13223e, 0x3cdbee9d, 0xf9e8152c, 0xb0d76e85,
- 0xf9ffa007, 0x7a27ef44, 0xfbb46fa4, 0x62ebc43e, 0xfc2cdadd, 0xedb3ba6e,
- 0x866f47e3, 0xb2f4fee7, 0xbe6241c1, 0xc7f4892c, 0xb30bcda2, 0x21bbe9bf,
- 0x787dfcc6, 0x2699d1de, 0x2b173e01, 0x9f30632d, 0x84b99f30, 0x51f8e23d,
- 0x86bcf0b6, 0x73cf1d75, 0xbb145c7c, 0x79b4e306, 0x8f8c7961, 0x8d83f7c5,
- 0x6fc69299, 0xf5c99838, 0xe71d3cd7, 0x38b7886f, 0xb1a631bf, 0x5edeaa03,
- 0x220fbf8c, 0xaa80ed07, 0x33586bb7, 0xb3fd6b9d, 0xff34becc, 0xbf47c942,
- 0x27875223, 0x2af8c354, 0x6b638f2b, 0x51f28c5e, 0xe580aa9c, 0x8e0ff10b,
- 0xe7813ea1, 0x7e5f1916, 0x0177d90a, 0x8675f00b, 0xc193fb8d, 0xe9c81557,
- 0xacaa7f69, 0x346c1b1b, 0xfb81c1bf, 0x79081719, 0x7c966dad, 0x25075e7e,
- 0xcc5f3a3b, 0xd1d85f33, 0xc3d4fb70, 0xa3d9852e, 0x977661f9, 0x2ced6b35,
- 0x79e74bc0, 0xc386f0ab, 0x25898ae9, 0xe66a2c3c, 0xdcab3efb, 0x08937dbe,
- 0x1401c96e, 0x02cf01ed, 0x80951ae6, 0xc79178eb, 0x85f0e1e9, 0xbc07abaf,
- 0x70e19d62, 0xd1ce3957, 0x5b35e5f7, 0xf857c224, 0x847a543a, 0x5d2a71fb,
- 0xbf1cbcaa, 0xd1126d55, 0xff65d4f3, 0x50fed190, 0x0b586f95, 0x79e42ffc,
- 0x5d608f95, 0x2dbf5093, 0x38fa0758, 0x2d3f27a7, 0xc8712d62, 0xdfcc7537,
- 0xd3f72588, 0x473b96fe, 0x4e79e0e4, 0xa9dce987, 0x573f9b0a, 0xeca88097,
- 0x96fcb47c, 0xe3879f20, 0xbdf44afb, 0x5131fc5a, 0x00e7a067, 0x905ff35f,
- 0x909ffbe9, 0xf63e2271, 0x7b557c92, 0x3fac46bd, 0xb9f9eb57, 0xd3825772,
- 0xcbbfe7a3, 0x05784574, 0xdc35af3e, 0x7f5a59d1, 0xe577e839, 0x5bd247c6,
- 0x098f3aea, 0x7b45733d, 0xc5dc77af, 0x4927dec8, 0x4de9af98, 0x3b09577f,
- 0x3eed1f3f, 0x7fac9fb4, 0x3c6bce95, 0x3a55eeb5, 0xf2f8d59f, 0xf0b7da7c,
- 0x8f79fac9, 0x7c4fefe2, 0xd91e65b2, 0xab4f05f9, 0x0c6dde76, 0xd6ca1ff5,
- 0x5fee7dcf, 0x345f6f90, 0x6ab95d53, 0x41c45b8f, 0x9c6157a0, 0x51eb9eb2,
- 0xd5eb8eb6, 0x070f6805, 0x0ebc3d91, 0xe55fddc7, 0x3ff90ebe, 0xc9d93ae4,
- 0x7fb9e7fb, 0xbde613b5, 0x8718a5ff, 0xf56c9697, 0xd5b4bcf3, 0xf6b0f68f,
- 0xd38e0fde, 0x07c94bef, 0x6a81fbdf, 0x139e19ff, 0x42ce2ee5, 0xbf761339,
- 0x6598de56, 0xec223b45, 0xdf1b3fc4, 0xc9be20f7, 0xfef8e2bf, 0xf9e389a8,
- 0xef1cb5e3, 0x51fa5b8d, 0x5351fafc, 0x3eabf23f, 0xf84b92da, 0xf8035cae,
- 0xd15abf26, 0x804d55fa, 0x101f8c6f, 0x3dd700df, 0x6f81147b, 0x1377c707,
- 0xcb5b33c7, 0x781ecadb, 0xebf9d2f5, 0x947bfff7, 0xcf84fd03, 0x9ff27ecc,
- 0xd32adb3e, 0xdfaa6959, 0x7f3dfaa5, 0xa2cfcd66, 0x7be2a67f, 0x3e4080e1,
- 0xc78a97ea, 0x7887177f, 0x2795b85f, 0x9be07a4f, 0xbce85339, 0xbfefcbfd,
- 0xce2d27ec, 0xbe93f50a, 0x98ea5d25, 0xd72bf68b, 0xf96639e1, 0xd5a2fb21,
- 0xdf0b3fdf, 0x7cf0ad07, 0x98731465, 0x464f084c, 0xb9b8eff8, 0xfe8bee19,
- 0xecdcf72a, 0xbb8e497b, 0x31c7bf34, 0x780df989, 0x916b019e, 0xed4bbf68,
- 0x257125d2, 0xad2dcf0c, 0x67363827, 0x69df3b71, 0x3f22caee, 0xc714676d,
- 0x359ba8fb, 0x07a4d1f1, 0x423ff11d, 0x3f20e03f, 0xd79278df, 0x49cef941,
- 0xab5243c5, 0xff3ae842, 0xb8d73f02, 0x9cc482ea, 0xc09dfc76, 0x622fb4b1,
- 0xda14f37e, 0x6d055007, 0x5ef8e859, 0x9cdbcfbe, 0xc7a2f3c5, 0x78054d71,
- 0x1df8939e, 0x1a9e713c, 0x370171d5, 0x3a2ecdc7, 0x9278ef6f, 0xc8cfc1c9,
- 0x07dfa78b, 0xc1e85bb8, 0xb47d9699, 0xf1e61c8f, 0x7b9e1b32, 0x0501aeff,
- 0xf1d4c2ac, 0x73c68632, 0xbefe3f52, 0xff5b8749, 0xdf22ac1b, 0xbd92edbb,
- 0x3a413c27, 0xf381cf6a, 0x8fce4744, 0xfdc59abc, 0xa4e9c929, 0xcc14443a,
- 0xdfef0d1d, 0xebf0a59e, 0xdb3bff62, 0xed8cf400, 0x7a9c9e79, 0x39f9799d,
- 0xf0a535b2, 0x67189bef, 0xb21bd424, 0x31afd34e, 0x9e87fbf2, 0x5d793d9d,
- 0x30ef6306, 0xf43f7ac0, 0xff8f1953, 0x70fbc6e7, 0x3c64d7df, 0xad86ca6f,
- 0x76eaf89e, 0x78eaf33d, 0x7ac164db, 0x6a673888, 0x1ddfc092, 0x0f1fccc5,
- 0xa03fefbc, 0x2ef16f3d, 0x1d7fcebf, 0x9e3275e0, 0xe78f9767, 0x2b0629d6,
- 0x2e55c7bc, 0x52bc6015, 0xc1dbf2b3, 0xc2ecf1db, 0x4246ebc9, 0x70e3a75f,
- 0x29e780fe, 0x1efe6266, 0xcf5b30f0, 0x9c05c8f6, 0x8f1788de, 0x207da14d,
- 0xda244b5d, 0xede6a2af, 0x090f7a55, 0x8e89ede6, 0x307c0533, 0x3e1c534f,
- 0xaf4c8c6f, 0xb8d4b22f, 0xede285ba, 0x173e42c5, 0x45b972ab, 0x6c96972b,
- 0x8ff44741, 0x45336f01, 0xf9a4eb0b, 0xd47bc46b, 0xd9cdd773, 0x36737e7c,
- 0xf2ffe38f, 0x598fbe77, 0xaa8ef9f8, 0xf146d67c, 0x4ff7d5f9, 0xb6546d16,
- 0xe155e68d, 0x7fd7cf09, 0xf91561ba, 0x677fd549, 0xdf443ebe, 0x324c5d50,
- 0xea225576, 0x4999efa5, 0x5b1a66ee, 0x3d2deb72, 0x15e7a9c7, 0x8180b056,
- 0xbe440fd7, 0xd1a3d84c, 0xbfce85b2, 0xeff890ac, 0xc4967674, 0xe720757a,
- 0xbf7cccc7, 0x1ff079e7, 0xc0153df1, 0xef31f817, 0x27fbf8ac, 0x11583fa1,
- 0x7b63d467, 0x73cfcccc, 0xb102c39e, 0xfd413939, 0xd32258db, 0xfbcc8739,
- 0xafac64f4, 0x213ac2ad, 0xcce63fef, 0xe894aca0, 0xea36f73f, 0x811769a5,
- 0x9befa80f, 0xa93884ec, 0xcfb8af73, 0x9df3d236, 0xf67e090f, 0x27fde26e,
- 0x279bfbd5, 0xab9df3e3, 0xe4bffbd5, 0xf3a89ffd, 0x61e3fe8b, 0xdd8457f7,
- 0xdfef19ff, 0x272fdcf4, 0x2d8fd17b, 0x715dace5, 0xcfbf4493, 0x1bd423f1,
- 0x562b0fa0, 0x15cf09fa, 0x2dbc5dba, 0xd0dd7e65, 0xcaab8f2b, 0xed08fd76,
- 0x327b1c95, 0x92f5ed16, 0x67f5271c, 0x6747ba66, 0x8a68bb43, 0xbac235e4,
- 0xd91f11d9, 0xe8bd498f, 0xbd091fe5, 0xf9f0a55c, 0x3cc37c54, 0xfe8bb293,
- 0x9cfe79fe, 0xbb9e63dd, 0x5d9e06ae, 0x66914f08, 0xc0d5f71e, 0x768e5d73,
- 0xda1fd51e, 0x23f9d7d3, 0x2edc2b84, 0x23b1fe2e, 0xec53f31e, 0xe29df12d,
- 0x42ac96ca, 0x2ff17f98, 0xa1556477, 0x82fc25ff, 0x768bb43a, 0xdb83173c,
- 0x3fdbcfc5, 0xb6e5fbe4, 0x60c71bb5, 0x50da001d, 0x0bd358bb, 0xb56cde9c,
- 0xaf38ffce, 0xb4f2fe1b, 0x58b9e91e, 0xd3c9f2d7, 0x926fe768, 0x59777e22,
- 0xde3b9e2d, 0x3525efcb, 0xe03f7366, 0x87cefea5, 0xb20b6f10, 0xb291e919,
- 0x79cf9155, 0xb1e85b7e, 0xe6ff610a, 0x29358b0d, 0x23a2e780, 0x0fb855ee,
- 0x4e436aab, 0x978de601, 0x963e9667, 0xd6f98dfd, 0x6d6f9e2e, 0x0ad6f9e3,
- 0x2829605b, 0xf666f671, 0x32998f5b, 0xa9fe0fc1, 0xb220672a, 0x94796cf0,
- 0x79353fda, 0x0f9e48d4, 0xcfcbfec3, 0xe50c7f1d, 0x83c23f66, 0x83e1f5f9,
- 0x743f51a3, 0xace8c4e4, 0x25fe47a0, 0x089bee63, 0xb7e1acc7, 0x929a7ed0,
- 0x7301d8a8, 0xf89efe79, 0x5c325fe2, 0x38dd709b, 0x6e24f31e, 0x2ee93fa3,
- 0x4dfb8758, 0xbab3f699, 0x91dc63f3, 0x2efff3ea, 0xb666f0f0, 0x3afdda95,
- 0x0820b380, 0xf07efa87, 0x600697f7, 0xd32b93be, 0x50f7e086, 0x0e4a3227,
- 0xdf051764, 0xbdc3227f, 0xdf53e11d, 0x06c7527f, 0x6df1c860, 0xd05578e1,
- 0x0dd200f7, 0xe048d75a, 0xefb890b7, 0x9a3151f6, 0x7609b4fe, 0xe3cd0ce6,
- 0xf4d74b4e, 0xd3f457a7, 0x72bbbf8c, 0xc4fee6a0, 0xfad0c0a8, 0x77b7bf10,
- 0xf7cbc97f, 0x46c6c4ef, 0x3fbdfee3, 0x7df9fdb6, 0xcee9fdfc, 0xfa076417,
- 0x6e770bb6, 0x168f1f7a, 0xb5f40f3e, 0xa1527e53, 0xf69fda7c, 0x839f8ccb,
- 0xd687d4e1, 0xc0b0ce91, 0x60a52353, 0xeb6dfb7c, 0x7bad8b47, 0xae0577e8,
- 0xf3e8dd55, 0x287f516c, 0x1f680560, 0x47bfd7cf, 0x0b3abd79, 0x1d99e75f,
- 0x3c5b9cfc, 0xf012fae7, 0x20f86dfd, 0x40178bfa, 0x97fc83f1, 0x7aa09eb5,
- 0xae6c9adb, 0x9632ebaf, 0xf64fd1e8, 0x65f68b40, 0x78ade80c, 0x3b409be0,
- 0xf70dbc1b, 0x72c4e5bd, 0x54c2fdff, 0x8fef9bca, 0xfd9ff9e6, 0xfbf409c9,
- 0xc69b8bc7, 0x0bbaf5d2, 0xdbff3431, 0xb5f68072, 0xa8935f79, 0x7d31314e,
- 0xcf5c4ad6, 0xdf4401ff, 0x80006da0, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7dcdff00, 0xd554780b, 0x399ef0b5, 0x67091e67, 0x99212726, 0xe4c21024,
- 0x4e010249, 0xaaf08042, 0x9e180903, 0x6831004e, 0x0cfde1d0, 0xaf4a8809,
- 0x04819bf4, 0xa86c1808, 0x3bd15014, 0x6ad480a4, 0xa6a3ea6f, 0xd004c7d6,
- 0xa0d2941b, 0xdef6b7fe, 0x22c01b5b, 0xda046a28, 0xfad2de9f, 0x3ef6b5af,
- 0x82499cc9, 0xbf7b7b72, 0xdbe3ef9f, 0xb3ef6759, 0xd7bdeb1f, 0x6b4cfb5e,
- 0x7eef2074, 0xff99b185, 0x1b297b72, 0x97dad8c6, 0x1e609e4c, 0x857bd2c0,
- 0xd35ca0eb, 0xbeb19530, 0x5356b308, 0xd731631c, 0x046c61ef, 0x2c018cc1,
- 0x64ec728d, 0x435a5031, 0xc3c64fd9, 0x3b43ab33, 0xeaac66ec, 0x37bd147a,
- 0x3011d8bd, 0xdbbc7d43, 0xc648d8c4, 0xe953ed2c, 0xcbd7c9fd, 0xfc6bfea8,
- 0xfd631b77, 0xaf54e9dc, 0x438496c3, 0xdb0522f2, 0xb4fda89b, 0xaca843eb,
- 0xca873ebc, 0x147e7277, 0x84fac3ef, 0x17fa536b, 0x526f1c02, 0x64ac4a71,
- 0x628d999c, 0xa33b7eec, 0x47ab577f, 0xaba530c7, 0x72d2c8df, 0xe81e625d,
- 0x44dd76cf, 0x8f74c0e5, 0x6c604ee6, 0xd976a6d6, 0xec51eb8e, 0x8034e1ea,
- 0xcbddf28b, 0x93debaf2, 0xbab7cd8e, 0x7bfbc287, 0xd03d58ce, 0xe2ca0dbf,
- 0xc64afab0, 0xdd794d3c, 0x36e51bc7, 0xdb193ad3, 0x6c2ce54c, 0xcbb3ef07,
- 0xef3865df, 0x6f3e557b, 0x912611b6, 0xb60658cc, 0xbf7ae84f, 0x60c1d00d,
- 0x6d97815e, 0x77f0c3c1, 0xd4afba51, 0x4db4fd0d, 0x602fe564, 0x6a5b723f,
- 0x371fe399, 0x38b799ff, 0xfe6271ff, 0x46d896bf, 0xb7d7efec, 0x81e6d6dd,
- 0x3c3cb579, 0xeee48462, 0xb75ef7ea, 0x76abf795, 0xcf4060dc, 0xb8fa37aa,
- 0x66fac277, 0xdc208f02, 0xd82dbaf1, 0x99cf4698, 0x5b4b1e29, 0xabea09a3,
- 0x5ed91d9c, 0xcdf8bf18, 0x6ff210a8, 0x32519bcb, 0x9f7e7183, 0xe917bbe9,
- 0xa0e6fc58, 0x26139312, 0x464d9af9, 0xd036583e, 0xef3e1f73, 0xf1bdbe6d,
- 0xd69c6009, 0x535fc911, 0x18814cca, 0x1d5f6fe0, 0x82859397, 0xef5d173f,
- 0xc84fb043, 0xc4ead5cf, 0xabb74829, 0xb0d2609b, 0x4c9b458e, 0x75825f43,
- 0xcb43b731, 0xeccc3c02, 0x730b60bf, 0x69995ca2, 0xc48733bd, 0xe9a06b06,
- 0x06b1eb9a, 0x9ebcabf9, 0xbdaffd46, 0xeb9e97de, 0xc848b672, 0x19f90d87,
- 0x9f8225e0, 0x197e45ef, 0x1b8725d3, 0xe28f7dd3, 0x80d667fa, 0xbe78c3bc,
- 0x2885c92d, 0x62fc5d47, 0x80af9155, 0x8596925f, 0xcb4d4dc9, 0xf42a987c,
- 0x7e25ef1f, 0x71650259, 0xc152fd58, 0x7b789107, 0x65f916ec, 0x48bf68b3,
- 0x01996509, 0x28ea960f, 0xe7cc0b6d, 0x0a7bbc4a, 0x0efd65e2, 0x16f5bf8e,
- 0xe603b16f, 0x9371febb, 0x8b619406, 0xa8ec3947, 0x587d4687, 0xf185f56d,
- 0xc3ebfced, 0x30f01b98, 0x95267ae7, 0x83be01fe, 0xd785feb8, 0x0d3a09e7,
- 0x8bb992a3, 0xd8c5cccc, 0x1baba406, 0xe9c45427, 0xad77e62c, 0x43e2747a,
- 0x53b5fe30, 0x88bfaa16, 0xa9802d78, 0xe34f027a, 0x9b412cbc, 0x75e61076,
- 0x2a02c2d1, 0x7ef169d0, 0xdfa00589, 0x46fa5025, 0xd83d52d0, 0x1481f6ce,
- 0xb176c16c, 0x805b13cc, 0xe6f584f8, 0x86be31f0, 0x6d4c97ff, 0xfd410fd9,
- 0x961b33e7, 0x81e03399, 0x86412a74, 0x82fe7e75, 0xbe7824c4, 0x2e5bdd72,
- 0x94ab1e58, 0x50aaa60e, 0xcc14c1bf, 0x7be280b6, 0x86bdf646, 0xbbd3e07a,
- 0x08adfe9b, 0xf0dc7dda, 0xaae913a2, 0x0e49b5e3, 0x4d3f6165, 0xcc00cf80,
- 0x2a5ea9bd, 0x6c342a0d, 0x5da1b29f, 0x73f3adfc, 0xbaaf9f24, 0xba78419e,
- 0xfa1b6d5a, 0xf031f212, 0xf5d73e2d, 0xae3aeaf1, 0xbefd75d7, 0xcebff056,
- 0xd73295d7, 0x4c4a955b, 0x6e169030, 0x13bcca6f, 0x4c72ef91, 0xb70b165a,
- 0x8e8f8d37, 0x32f83945, 0x5d61ab5e, 0x839742f6, 0x8049fc57, 0xa47b2ebc,
- 0xc7ae81cb, 0xf3aebd75, 0x26af6ebd, 0x2f2fe4fd, 0x79fc3bfe, 0x81d7cd32,
- 0xe64d307c, 0xec9a6b76, 0x1c9a3e20, 0xff23265f, 0x79fd7b7c, 0xb3cfe856,
- 0xb6b9fd06, 0xc7f9fd17, 0xf387945b, 0xda967f42, 0x3cde7dd8, 0x3b67dfae,
- 0x4a2bfaba, 0x834b649f, 0x1334947e, 0xcd47fbb5, 0xf3e3495b, 0xfef3b6f8,
- 0x6fceb12f, 0xd303fbd2, 0xa46fd4ac, 0x1fd0679e, 0x5f2ff9ea, 0x1da20dcf,
- 0x5d8188f8, 0x5af7bb40, 0x6161f71f, 0x444ec807, 0x666f04c7, 0xb9927e07,
- 0xa7e22078, 0x4ee03b07, 0x80ec3bfb, 0xbcba57ce, 0xcba1f2e8, 0xe8fca443,
- 0x11fd30f2, 0xa421e62d, 0x30e6200f, 0x781c8fca, 0xe951d70e, 0x728f93ee,
- 0xf811cba9, 0xdd672461, 0x9b9083ec, 0xda31392e, 0x742e5d0b, 0xa6e5d139,
- 0x52c5c852, 0x3cba1721, 0x1e9a971c, 0x3def0b1b, 0x432be697, 0xb1f2e87c,
- 0xbb4885e6, 0x313f2bd0, 0xf1a5a7e4, 0xa9f90cd5, 0x7e70ca12, 0x4fc2f5b2,
- 0x9f916ef3, 0x9dbed24a, 0x8d32b11f, 0x40ff11fb, 0xd6995a7e, 0x0ab15fb3,
- 0xca7fecf9, 0xfd5ab8af, 0xcc37429b, 0xe8216ae7, 0x7e2eb4d9, 0xe32efe9b,
- 0xf806437e, 0x46b450d9, 0x5ab675f3, 0xb06b0407, 0x1aacd7dd, 0x01fba8f1,
- 0x7dee914b, 0x27f4f8bb, 0xfe71ff60, 0xc15bfd3a, 0xedf75fff, 0xd9d11df4,
- 0xf566df16, 0xdbbd21e4, 0x37bff60c, 0x5bb1f17f, 0x6fe6f3a4, 0x4243e749,
- 0xfa0ffc6f, 0xd17a878b, 0x1eff8713, 0x862cceba, 0xfc21fb3f, 0x3c67af7b,
- 0x02fbe7d0, 0xa2f39c0e, 0xd22bccbc, 0x3c1bdbeb, 0xe01fa899, 0x8234b1cf,
- 0x0f09d987, 0x56db3e02, 0xfe9cf302, 0x007d6758, 0x8f8f27eb, 0x8f33ef11,
- 0x3fb57589, 0x5b51f691, 0xd60bda3d, 0xaf8dedc0, 0x0d0ef65d, 0x76010b83,
- 0x1145c184, 0xdede01f0, 0x9533b729, 0x972084fc, 0x54dfe82b, 0xfd15f340,
- 0x9e65fe09, 0xcf015713, 0xdb1354b3, 0x8aaa7409, 0x55d6f83f, 0x26cd6bd4,
- 0xe1877266, 0xebc97021, 0xf6fd0149, 0x9fc0499a, 0x37c079b7, 0x0e25fbb8,
- 0xabf0767f, 0xfa2c8086, 0x8d6c7f05, 0xc9a5b740, 0xbfa091e4, 0x60a64535,
- 0x7c775a7a, 0x67c9d67f, 0x54c07cfa, 0xd667df1a, 0x1f7b5bf8, 0xa7ef4de9,
- 0xdb21fbd3, 0xd77f8c2d, 0xf609e678, 0xd29b0fe0, 0x292c5db9, 0x3eb1e98c,
- 0xf8e25d2a, 0x3eb001bf, 0xd39a3c3e, 0x91e5f7c4, 0xf9d363ed, 0xb3666db8,
- 0x3763a7c0, 0x559b59f2, 0x1bb2b7c7, 0xb1993df1, 0xbe413e4e, 0x4e09f181,
- 0xeaca5469, 0x4f5cbe64, 0xb66ebe04, 0x74d32fde, 0x5f0ba63f, 0xd97a0881,
- 0xabef826e, 0x6ddbe03d, 0x33743f7c, 0xdbb9fd7a, 0x576f82fb, 0x31ec7ce8,
- 0xec8c7bf0, 0x898cfe25, 0xe001a937, 0xa8deb5c7, 0x742fdc7a, 0x195267c9,
- 0x88ca2de1, 0x4bf92ea7, 0xc8512b2e, 0xfdf5123f, 0x7afca377, 0xb9ed9dcd,
- 0x0d7cea3c, 0x5e00e7ef, 0xf7c695d1, 0xdbf7a547, 0xbe23c81d, 0xe5827aa0,
- 0xca4779b0, 0x3c045363, 0x857e423e, 0x40fe91fc, 0xca78007b, 0x7f16fd42,
- 0xe30eead6, 0x7f053b93, 0xe5626e7c, 0x26db4fa8, 0x2db23f71, 0xa40f979d,
- 0x02ccb8f3, 0x754b97c1, 0xc30e8a7e, 0x427f9183, 0x5b095fb8, 0x7e69e137,
- 0x63cf2ebc, 0xbac066cb, 0x7d78e2da, 0xdda8e355, 0x382e9481, 0x8d75bfb2,
- 0x2f10cb63, 0x8a07fd9d, 0x997da0ce, 0x40f6f02f, 0x813398e3, 0x1767413c,
- 0x7fda19d9, 0x50047f01, 0x7f22541f, 0xc7f3ba98, 0xfc6ef484, 0xdf788819,
- 0xfbc9b963, 0xf7dfddc5, 0x2ccfbc44, 0xbef2b7f1, 0x088cdba0, 0xd04696ba,
- 0xae0224b5, 0x41a0e1d0, 0x797aeaff, 0xadeef351, 0xeac7982e, 0x5967a0a3,
- 0x2d4f3f38, 0xad5fb943, 0xed3bfcea, 0x176bf20c, 0x3c274f3f, 0xf9d26ecf,
- 0xd46ec675, 0x87a865c3, 0x73c176c7, 0x3c110f50, 0x1313ccb3, 0xed66af6e,
- 0x57757b46, 0x0efede9d, 0xad777f6a, 0xea979fde, 0xcf423a75, 0x42d74465,
- 0x3ecd5edd, 0x5eabf583, 0x4d1fefe3, 0x9026739f, 0x68791379, 0x81cbc088,
- 0xd1103808, 0xd837cf7e, 0xf788dab7, 0xd7d44537, 0x23fbc047, 0xfbe33ae0,
- 0x4898970b, 0x3f02170e, 0xe5222120, 0x9a3f9232, 0x9cfd3bd3, 0x526e7b4e,
- 0xc833bfc8, 0x0e1af4d5, 0x95f74b1f, 0x706129d5, 0x2e32c2e3, 0xf01a3017,
- 0x7ff185a5, 0x120373a0, 0x17a583f0, 0x1bd4d9bd, 0xda44e65f, 0x7bff5e7b,
- 0xfd1933fc, 0x4bf06665, 0xb8464b8e, 0x0ef31245, 0x90d99d54, 0x78750f87,
- 0xa7ee196d, 0xae33efa7, 0xa2b3f60b, 0x49594d7e, 0xd6c45fb8, 0xd6c27994,
- 0xf29fb7a9, 0x1c25afd7, 0xd5c6c3ef, 0xbea08765, 0xab285262, 0x5e38cb1a,
- 0xd094bd82, 0xf889575e, 0x25d794cd, 0x8acbda2f, 0xfad650e8, 0x35883f70,
- 0x5b3ae365, 0x3e88961e, 0x0fa01a81, 0x732169e0, 0x2eced15b, 0x832b1e66,
- 0x4c4b5cad, 0xf023c6cc, 0xa587f1de, 0x3fa7688d, 0x85d7d8da, 0x19d1a1fb,
- 0x3c717f7c, 0x296ba066, 0xee7d2dc0, 0xb2db7d23, 0xc795327d, 0x0eb6cf24,
- 0xdbffb195, 0x929970f8, 0x8431f58b, 0x0fe9aba7, 0xf9066d95, 0x9bba53f8,
- 0x538beaf0, 0x6fe8cd5d, 0x8c30b4ef, 0x51a63397, 0x2ee1691c, 0x9c4efe5b,
- 0x2e21e6cf, 0xfd173ff4, 0x324a6cb0, 0xd5b45bb4, 0xd51fa1a2, 0x7153566e,
- 0x939dbe7e, 0xa4bf58ad, 0xdb819456, 0x6ff37ca9, 0x4271aa3f, 0x4ca78efb,
- 0x9fb4235a, 0xdde9ad70, 0xaf2f0061, 0x4490d0cb, 0x33375c6f, 0xb739c615,
- 0x0250507f, 0x551f3cbe, 0xde2cf6fd, 0xe5fb619e, 0x67a7dc37, 0x497b6215,
- 0x2fed02dd, 0x9ff473c0, 0x1a90ec2f, 0xa72f384d, 0x4b04da23, 0x4657f0ba,
- 0x5b0b9cf1, 0xcf8c416d, 0xf77c539d, 0xf671c7ee, 0x67d3d05b, 0xa76e4c17,
- 0x9f10f009, 0x292cb3b1, 0x04db9f19, 0x2ec6773d, 0x685f3904, 0xb21fe4ee,
- 0x3962cb27, 0x1da3ff1c, 0x1d618765, 0x441f1e17, 0x195dabf1, 0xc00c849e,
- 0x1e991df7, 0xa3e79617, 0xf37addb8, 0xe87dd26f, 0xf2f2ffc7, 0x97f21722,
- 0xd3cb833b, 0xb917d71b, 0x55f98516, 0x89973ecb, 0xbab4de0f, 0xdf7ce037,
- 0xc2601e8c, 0x41f0367d, 0x2f938c5f, 0xe016fb11, 0xf62f8de7, 0x97fd5fe0,
- 0x1e5ac7f0, 0x36ef1849, 0xd27ef5f0, 0x00dfb49f, 0x87e33f38, 0xc7c003bb,
- 0xb236db1f, 0x9b8c28f3, 0x75dc52fa, 0xe07a1309, 0xee20a8b9, 0x535258ab,
- 0xa6fc7876, 0xfb450e53, 0x841c05df, 0x7b41dfd7, 0x2efdf7dc, 0xf08e1ff0,
- 0xfdbd0bf3, 0x8023a772, 0x0e27c5ce, 0xf8f48c87, 0xf85ff648, 0xecb7bc2e,
- 0x81d90b29, 0x6c254f65, 0x8171c0ea, 0x16ae306f, 0x867f2eb9, 0xabd5d685,
- 0x6523b25c, 0xfbe12925, 0xbfa4c395, 0xe9cb937b, 0x0ecb8719, 0x972ef5e5,
- 0x9fae55cb, 0xf1653ca6, 0x1f2d3ca2, 0x70d990e9, 0xf53d26c6, 0xcfc461d6,
- 0x055175f2, 0xf2f89836, 0xaf446ca7, 0xa0238776, 0xe9cfbd42, 0x9ca16390,
- 0xd6f5c19f, 0x3f2e0ca6, 0xed9312c5, 0x62d65405, 0xcc0af5bc, 0x97c02fa7,
- 0x77b63e36, 0x29f38c34, 0x0d1bce0b, 0xe1e2bbf8, 0x25e57a7c, 0x4c8ee289,
- 0x4133c8f6, 0x5c60ae5f, 0x7c9e544f, 0xfe113ad1, 0x5ff562ac, 0x5c1fb049,
- 0x067cbd51, 0x06570bee, 0xc5dae72d, 0xb16bfc5e, 0x55b3d45c, 0x5bd811fc,
- 0xfefebd63, 0xfa4ed61a, 0xa229b2a3, 0x4ff6fabe, 0xd5537e30, 0x3ebe7c6c,
- 0xa17f11c3, 0x7258c30f, 0x5d8a6001, 0x3364b6a9, 0x0572ea58, 0x5dd60ce4,
- 0xf344c07c, 0x0a51be5f, 0xc5fe60da, 0xf8dc797d, 0xc1f03f63, 0x407f5a20,
- 0x1ef97805, 0x33967f6e, 0x7f0ed053, 0x1d607ede, 0x0a2f31c5, 0xc4d0b37d,
- 0xe7e7c8bc, 0xdc54b4a3, 0x2a7b2fef, 0xfcbcf08a, 0xf6ff95e9, 0xbed7bc38,
- 0xf87c6679, 0xf90ebafe, 0xd999e383, 0xf9fabae3, 0x52f7f364, 0xff8a0e51,
- 0xb0c9f619, 0xecb1e5de, 0x90d3f3a7, 0x6ea9c96e, 0xf2ddaba5, 0xf3670f2d,
- 0x86cfb076, 0x21dc2f75, 0xcbd83ad1, 0x2087b236, 0x3e386af3, 0xb49ed497,
- 0x633db95a, 0xd9f84baa, 0xf5e7d46e, 0x7fbc126d, 0x8525ea0e, 0x0f6817f0,
- 0x87df978b, 0x3e93257d, 0x2afae1f1, 0x66fba6cc, 0x561d3f53, 0x3317ef94,
- 0xd9f45c78, 0x2ee7ee0c, 0xa5eed54c, 0x36a3f438, 0xef1a4b6d, 0xe6251a47,
- 0x4abcfb01, 0x3a32db73, 0x8db9fcc7, 0xb5552be2, 0x27289e51, 0x2f3c4bed,
- 0x3255bf40, 0xd871ad93, 0x1ae75f2f, 0xf01fd737, 0xcf1943fc, 0x3f5c1c67,
- 0xbe02c656, 0x6638ce15, 0xfc4bffe8, 0x97f7832b, 0xfdebac3c, 0x5d4df1ce,
- 0x10c3b9f5, 0x95e77d5f, 0x979e3ce3, 0x19017e48, 0x9fa1168f, 0x0234bcf7,
- 0x770bd7f7, 0xfa829f1c, 0xf2cff576, 0xe1757c55, 0x7b27df4f, 0xb9d05ab1,
- 0xb47dfd1d, 0x0cff001f, 0x7e4253ca, 0x0f8f127c, 0xd0f8129d, 0x57d7ade9,
- 0x38f0b0ee, 0x5475e83d, 0x7f9b9524, 0x3a56fd43, 0x6fa85cda, 0x8cb65f2b,
- 0x6bfcbd42, 0x5fb43f9c, 0xf8c079b4, 0x167f810f, 0xb4546259, 0x33026b4f,
- 0x69af08ad, 0xf5dc1130, 0xf22a425e, 0xafb567e3, 0xce4f9138, 0xd0b28547,
- 0x8bac750e, 0x01711ad2, 0x7dcf8f2a, 0x88d59b56, 0x6a259c71, 0xf504c39b,
- 0xc464364b, 0x48febea1, 0xfeb1590d, 0x3334a6a3, 0x1d551ec2, 0x1e47b08f,
- 0xa067f04e, 0xff049aba, 0x6b59bea0, 0xf35cf4e2, 0x3a6b71dc, 0xac55778c,
- 0xdfe7f3f7, 0x4f78c6cf, 0x365b6a65, 0x77a011da, 0xf3c47f76, 0xc3b226b3,
- 0x3c939f6b, 0xe8bac351, 0x0de916bd, 0xd04ab5f2, 0xaf4bed79, 0xbf7c843c,
- 0xd05de916, 0x6f805f9d, 0x17f3d04f, 0xfc614e0e, 0x17c813fd, 0xb802ddba,
- 0x377182d6, 0x09af872b, 0x25e7803e, 0x8f2079fc, 0x11e826f4, 0xf92337f4,
- 0xc6fa37bd, 0xb7fb7266, 0xf48db368, 0xe7266c6b, 0x2f1df6fb, 0x9f7e913b,
- 0x6dfc7f3f, 0x7ca94f3c, 0xbbb2ac01, 0xf817be07, 0x3bf5c2a8, 0x4fe4fe69,
- 0x9d7ae154, 0xe4efeb5d, 0x556f2173, 0x5f4faf8c, 0xd62c956f, 0xf78bd7af,
- 0xbc8532e3, 0x97af8130, 0x12f97106, 0x8af284f2, 0x3ebe997e, 0x5f7f1c5f,
- 0x4ca2cfe7, 0x62699fce, 0x726d4c9d, 0xbe907e22, 0x7f8067a8, 0x4251d63c,
- 0xcf93406f, 0x0ff3067f, 0xff3e97a3, 0xd00f3152, 0xb8d89e6b, 0x9bb63a2e,
- 0xce9e8ad9, 0x3933f32f, 0x9add9cdf, 0xf80cda98, 0x59f60cfb, 0xfc006794,
- 0xa78d872a, 0x5e3e8df3, 0xa6ca4ff1, 0xffa1bae1, 0x8faff610, 0x8fa051fb,
- 0xc47cfd8c, 0xf3e87cb8, 0xb8b2e5d7, 0x7cb4c166, 0xdcfbb627, 0xeb879191,
- 0x6697e3e6, 0x07bef4aa, 0xdf7803fd, 0x38a26cd3, 0xafb159f5, 0x15f5bb3f,
- 0x2ebca2e7, 0xde229f7e, 0xabb27fc3, 0xfe753cfb, 0x9a67e30b, 0xbbf6f167,
- 0xcfac21a6, 0x752f9237, 0xc9fce9bc, 0xdf902536, 0x55a7c912, 0x38ad6729,
- 0xdd73e45e, 0x718f397f, 0x5fff9416, 0xff248298, 0x6644ecb5, 0x7f865d98,
- 0x65d51b0a, 0xb3af361f, 0x51cb7b51, 0xbd75076e, 0xaaebdbaf, 0xc425cf78,
- 0x79328ff7, 0xf56ac91e, 0xf42736c4, 0x36e3e633, 0xfdd60f3a, 0x42d709c5,
- 0x95c60c52, 0x082b4a5e, 0x2e6b77b7, 0xadfe209f, 0x70db6d64, 0xc770b3ff,
- 0x234733fb, 0x42d8fe9f, 0xb70b2fe7, 0x1fa2b64e, 0xe2f0f2be, 0x73ff4851,
- 0x5d9edc75, 0x04791daa, 0x7573e8fd, 0xe716b98f, 0x53c57be1, 0x85f3c2c6,
- 0xbe89f3bb, 0x66daa3e7, 0x80f1dc22, 0xbde11ac4, 0x6e478771, 0x71e01bba,
- 0xb8b1818e, 0x490e8fce, 0xf8c36325, 0x37530961, 0x9b7e8ddd, 0x7ca2a31c,
- 0x5af4247c, 0x6bd3858d, 0xdaffe097, 0x79cb92ce, 0x364d4d71, 0x1c77979e,
- 0xf80a7d04, 0x9bbab0a9, 0xebee3842, 0xa80fb489, 0x524b6d82, 0x935b9d1c,
- 0xcac2b4df, 0xf405c9ec, 0xcf0c9edc, 0x1eda5a4f, 0x7c9cf5c0, 0x19bf91c0,
- 0x18dd2b71, 0xbbfb88b5, 0xe7e03724, 0xbe3af8d2, 0x0bd479f4, 0x4fec8b3e,
- 0xfd15bf7f, 0x627fd47c, 0x7f6a97fe, 0xd6ed0f3c, 0x7159a3a5, 0x5e4ffeb8,
- 0x3f43aa8f, 0xd70b13e7, 0xe0ff7a67, 0xee1c7d7f, 0x65bf8127, 0x32bfc180,
- 0x1f67c0c0, 0x2db5fd1b, 0x33a7af34, 0xce95fe8d, 0xb2eb15af, 0x04f3c262,
- 0x99e3f9ba, 0x744796b7, 0x02880fd9, 0x318c5d16, 0xf6ef8c0c, 0x6d8bebf9,
- 0xd8378fe8, 0xf3ac1b54, 0x3c77e463, 0xe2597a6f, 0xe73b00fb, 0x1e5f8fff,
- 0xdefdc411, 0xf0e4ffb2, 0x105326b2, 0xec4ea553, 0xfb612ede, 0x25ffe0a5,
- 0xdbfcc29a, 0x01e7bb3d, 0x9a2bb3db, 0xb4325b6f, 0xe79472bf, 0x12b5403f,
- 0x9dbed7e1, 0xf7dffeec, 0xc178f567, 0x6bbc74af, 0xebbc434c, 0x39f7d6f8,
- 0x145f026f, 0xefe17415, 0xf20aff0b, 0x7dfb2f67, 0x3a697e54, 0xe438e8fb,
- 0x868c4767, 0xe6cbf372, 0x48fea4c7, 0x6ff297f7, 0xac757ee0, 0xfca2a312,
- 0x48dfe17e, 0xfd978c87, 0x74ea54d5, 0x1365e3d7, 0xf7a16a5e, 0xf11e68be,
- 0xef7838da, 0xeb86250d, 0xf7cf0f6f, 0x646fa488, 0xebfdc7de, 0x73e22746,
- 0x7e9f5d7d, 0x9f59d397, 0x1747a7f7, 0x2d5d713b, 0x6d7df64f, 0x4fb7d20c,
- 0xdafe8a8c, 0x71f79172, 0x13d73f61, 0x4731ed17, 0x2f9d0066, 0x62e3981e,
- 0xb69737a0, 0xcf879dcc, 0x526ebd97, 0x5ed75fd1, 0xfee2732f, 0xbb720fea,
- 0xde12c553, 0xe47ce10b, 0x697a84a0, 0x839b296c, 0x6486c7ed, 0xc67e86e6,
- 0x32fce0cc, 0xc41cb2e6, 0xe0cf9f83, 0x6e33c539, 0x033c5344, 0xbcc5f5fe,
- 0xe0bfa58e, 0xef1d1071, 0x9c6c7efa, 0x1030f758, 0xf177e243, 0x3f88b8bc,
- 0x8bc0e4ff, 0x4bbfb0b3, 0xce2a2c87, 0x16438bfb, 0xec157fea, 0xde30cca3,
- 0x5f7ca3c5, 0x1a547082, 0x7fdf33ca, 0xfbe26aac, 0x1675ca8f, 0x3ba6358f,
- 0xb587165f, 0x3c1efdc3, 0x2bb8e373, 0xfcea1f05, 0xd7c3caba, 0x1cec0ab7,
- 0xf89bf7ae, 0x6d359637, 0xc6f5bc43, 0x7f96dfc7, 0xfa8cb333, 0x7b6f93a2,
- 0x578117e3, 0x5be47f94, 0xed562f9d, 0x71ece7e7, 0x9113f94d, 0xd13e74ff,
- 0x12604bf5, 0x5a7b41cb, 0x98396563, 0x47301397, 0xca17a86b, 0xed05b714,
- 0xf6f89cc0, 0x23cf4412, 0x4abf5c59, 0x198f66c5, 0x8d8d51ed, 0x78b747f4,
- 0xc7d71677, 0x283e6421, 0x7952ccef, 0xa6ab25be, 0x825e857d, 0xed0032e3,
- 0xb89f5976, 0x49a1ba3f, 0xd9c6e1e9, 0xd975f032, 0x3207b8b8, 0x87bcc634,
- 0x4478728f, 0xd40b48dc, 0xb333d2cb, 0xccae004b, 0x0ac94cf2, 0xe1d2f7eb,
- 0x1eb801c4, 0x9f153e78, 0x37de28ff, 0xea246b23, 0xf9f4857f, 0x618ea697,
- 0xdabad31b, 0xf1dd799f, 0x5ddd2fd1, 0xa585bb70, 0xeb08796a, 0x9ee5e5f3,
- 0xec1ccf2c, 0x22f9f227, 0xde52b6c6, 0x3f5fe05c, 0xfe04ff44, 0x8f40ed79,
- 0x2d5f043b, 0xa4212bb2, 0x5cb3ab33, 0xc037f4ee, 0x8c5a6015, 0x259b748c,
- 0x390ee4f8, 0xe7ef82d4, 0x82f55ab2, 0x03a25c9d, 0x5dedf75f, 0xd80603af,
- 0xe03fbd05, 0xb02d2f87, 0x136be03e, 0x1046dfb0, 0xb120131d, 0xe998f402,
- 0x33fd7fb5, 0x60135bf6, 0xe78451ed, 0x10c2f50a, 0xccface0c, 0xd959435f,
- 0xe30c39c7, 0x1c579e1d, 0xb8e80521, 0xc43ef9fe, 0x1f852bff, 0xc4457cc3,
- 0xbe541bcf, 0x4b1be61e, 0xe080f6fc, 0xacfc4fb7, 0xf044133a, 0x0bec7673,
- 0x70f1e619, 0xc461ef94, 0xa9f31afb, 0x946ef5d4, 0xfa271ad7, 0x54ff9f19,
- 0xac3550d2, 0x3b24fe11, 0x5ee42094, 0xf506dd0a, 0x8db969ad, 0x0ab66f68,
- 0xc69cb97e, 0xd81c3f68, 0x3fbca36c, 0xea78e376, 0xa69700c3, 0x3ee1aedf,
- 0xb6cff2f3, 0x3a052e67, 0x38bd40d9, 0xa1539d61, 0xb75822cf, 0xce896005,
- 0x4f448381, 0xe1380fa8, 0xc7b4b6f9, 0x319f3952, 0x4eb5ca2f, 0xddef1d1f,
- 0xa34301e8, 0x33b669df, 0x732bee0b, 0xe51501d9, 0x27cba74f, 0xe01bc076,
- 0xfe6e327b, 0x7fac1f41, 0xeb7ffb99, 0xa613ac4d, 0xfb374eb8, 0x9ff916f7,
- 0x83016e20, 0xf8b0397e, 0xa2c3d9db, 0xe21c5683, 0x81e2ed96, 0xcaf51ee2,
- 0x257ae8bf, 0x1f93e59f, 0xf1844b82, 0x93368b96, 0x8cb70aa5, 0x6bb049eb,
- 0x9feb17c8, 0xc3bb20ca, 0x8590fc66, 0xfa0763b7, 0x4b6cbf12, 0x2b0e8893,
- 0xd7944d9b, 0x3fb9b338, 0x8cd54373, 0x3a54bee6, 0xf3d327af, 0x2dde474b,
- 0xd3877ae4, 0x8933e669, 0xe88f2893, 0xea544199, 0xf82f58f3, 0x15f3c74e,
- 0x1cb3c72f, 0x1e37ddc8, 0x2d5a13cf, 0x3f26e82c, 0x35cfd784, 0xb4afde11,
- 0x7f91979e, 0xb1304ee6, 0xd14b00be, 0x496dcf9c, 0x01eee666, 0x9f4136bf,
- 0x73347728, 0x6a0bed87, 0xf88d9ca2, 0xda780b1e, 0x97701f70, 0x2727d768,
- 0xa74ed0ce, 0x8e813ce7, 0x331594bb, 0x9ddb1d70, 0xbf915a53, 0xc33f5a1c,
- 0xb14936b8, 0xabcc1f20, 0xee63d230, 0x196c235c, 0x5be915ff, 0x73e378cb,
- 0x5f08c79b, 0xcb98e9d4, 0x18e9c372, 0xfa0f3f86, 0x363c57e1, 0xdee63f8e,
- 0x79e01e37, 0x7cc3f861, 0x32292b96, 0x147b6fe1, 0xade017c7, 0xa63cf911,
- 0x58b788c8, 0x7d4f118f, 0x48f88d4b, 0x9bd71af0, 0xa86e9e58, 0x360df64f,
- 0x515ff7d4, 0x54078060, 0x1fb4358f, 0x019271b8, 0x334c0b4e, 0x9ba8cfb4,
- 0x1ab3806d, 0x1fb436ee, 0xa1917fb4, 0xcab8373e, 0xe8e43f50, 0xb43c037a,
- 0xed0c9fe9, 0x316f3787, 0x7687e7d4, 0xb447ea1a, 0x8f00c0fe, 0xd0c27b6c,
- 0x8d87f47e, 0xed31fa86, 0xc7ea1acf, 0x00c17c5d, 0xd578e84f, 0xebb6fed0,
- 0x44f00cc7, 0x7da1aef6, 0x037dfdb1, 0x0ffd593c, 0x93dbfb43, 0xa7ea1bce,
- 0xd4333fba, 0x6ab9cf4f, 0x7f6a6780, 0xb6afb431, 0xa36546fa, 0x265d2aff,
- 0xc059aab9, 0xeb4aeae5, 0x71ca3b1c, 0xdff03651, 0x7fc9d610, 0xd29ed0e3,
- 0x62a5857e, 0x34b264fc, 0xd9f2443e, 0xdf70d26c, 0xe4af6911, 0x8c1ebccf,
- 0x4c57b1ab, 0x06234f74, 0x361c8ecc, 0x0ec7ac7e, 0xb82ec41b, 0x806aa96f,
- 0x8649bc13, 0x6ee589f6, 0x2fb27d43, 0x7fdf50c7, 0x07806685, 0xda191754,
- 0x31e8dc0f, 0x528169c0, 0x3a8cfb43, 0x6ace01af, 0x1fb43728, 0xa867dfb4,
- 0x30ae0dcf, 0x5a390fd4, 0x3687806d, 0x1fb4346d, 0xd4301cde, 0x0cea87e7,
- 0x1b5a23f5, 0xb6c8f00c, 0xa3f686fd, 0xea1a0c3f, 0x351fb4c7, 0xd8bb8fd4,
- 0x74278064, 0xdfda1b34, 0x80643d76, 0x8693b227, 0x33f6c5f6, 0xfab27806,
- 0xdbfb435b, 0xea1ace93, 0x192fbaa7, 0x64ff75ea, 0xc657ce7a, 0x995fc2e7,
- 0xf0d9fda9, 0x8792607e, 0x5e047f21, 0x6e356930, 0xa766f6c6, 0xde817f13,
- 0xd0928f6e, 0x3e52f1bf, 0xf4261c52, 0x04c65f01, 0xe857c44c, 0x5c5057ea,
- 0xafe29e28, 0x98dc5a64, 0x1f760377, 0xb4e67fe3, 0xfb77f434, 0x295df974,
- 0xf6f88f5f, 0x6cd1d77e, 0xdb6bf646, 0xa7bca944, 0xd9a3c33c, 0xebf20e3c,
- 0xd953df6c, 0xf8bfb809, 0xbbf414d9, 0x36c0b257, 0x2964e79c, 0xde1da62f,
- 0x8c651d3b, 0x54e5e863, 0x6c2de03b, 0x1aa3273e, 0xb26e0a52, 0xbf6a9fdf,
- 0xfb3bed4c, 0x130df115, 0x587d7fac, 0xbec28fff, 0xadbf0640, 0x05720fc1,
- 0xfc0fecbe, 0xfc7bc12a, 0xf5ef0449, 0xefdca9bb, 0x09f2a1cf, 0x07f546bf,
- 0x3f0445fc, 0x1c10f7ed, 0xd95297f4, 0xf3d2f7e8, 0x8272fe43, 0x197ec08f,
- 0x7fb0a3cb, 0xd859f2c6, 0x73fd6307, 0xf8462fb0, 0x9500fea7, 0x7a3afe4d,
- 0x81bf82fe, 0xfbfc97e0, 0x3fb9fe09, 0xffb36548, 0xfaaf9528, 0x35fea89b,
- 0x6fc1337f, 0x870443f8, 0x1f04adfc, 0x7c11b7f3, 0xc121ffc2, 0xa9dbfb6f,
- 0xa45ff56c, 0x077f1df2, 0x5ff29fd5, 0x9e8bb827, 0x12387f46, 0xf88a9f9f,
- 0xe37e132b, 0x2c3fc172, 0xcb8bfb9e, 0xe5b02b38, 0x932d6f82, 0x78c10dc0,
- 0x46ecbf60, 0x891d7bcc, 0x7c43957c, 0xfc56ea75, 0x98fdc8f9, 0xf19f025e,
- 0x133af4fd, 0x76e8d78f, 0xe817e45e, 0x03c5527e, 0x00bb1f7c, 0x273c5ffc,
- 0xee28cff8, 0xb6a95eaf, 0x573fa0e4, 0xf0d68a61, 0xf54ae51c, 0x610fc81f,
- 0x220dde78, 0xb66bdf72, 0xf6c33b83, 0xbef01571, 0x4eafde19, 0x54f9a34d,
- 0x9d0b56b0, 0x23cccaa3, 0x33dd5c81, 0xf89d77c0, 0x4039807a, 0x98256afb,
- 0xff38fb8d, 0xf05fdf00, 0xa5ea95f9, 0x547e136f, 0x670fce8d, 0x770942da,
- 0xa4e4fc61, 0xdebff144, 0xf22551f0, 0x7fad7bc8, 0xfa0a52e3, 0x937fa5e5,
- 0xd39f487c, 0xc6394716, 0xf8839c13, 0xc839d4be, 0x5263286c, 0x30418e7d,
- 0xaa393f9f, 0x0a0335ef, 0x759df4ff, 0xeb4fee47, 0x81df47da, 0x9bf0515b,
- 0x42db98cb, 0xf3cc8d79, 0xb85d5e16, 0xbe08f993, 0xfca8058b, 0x35cf8a5e,
- 0x0fe62468, 0x8df60905, 0xb4f6a5b5, 0xa579c8ae, 0x207ae20d, 0x50d9906d,
- 0xb9f5484e, 0x393fbfb1, 0xd3af343c, 0xc6cf6e63, 0xfaf3e975, 0xdf9baa5e,
- 0x4f1d609f, 0xf4fefce3, 0x4c1757fa, 0xe3f9dd19, 0x0a17c01f, 0xc7686f9a,
- 0x06a41cf0, 0xafdf0764, 0xf289aef9, 0xa8be75b9, 0xbe2180c0, 0x7944c9b7,
- 0x027c5dfe, 0xb0fb81fc, 0xf7ba0ef8, 0x01327c07, 0x8c6ab9d7, 0x5f82b014,
- 0xcc1cda79, 0xf2b9d136, 0x15c62b52, 0x7f03c796, 0x07cef7a4, 0x03fdc56b,
- 0xd7f039fd, 0x2fcf48ed, 0x073a317e, 0xc6f555f1, 0xabe23718, 0xc0740cc6,
- 0x923be37d, 0xb857f3c6, 0x0dc697ea, 0x932678a5, 0x4fe30d35, 0xeb3d6d33,
- 0x7f82e5db, 0x4a59274e, 0xf19fd483, 0x413ee5fc, 0x3d04fbb7, 0x64fbafd7,
- 0x3ef3048d, 0xdd12ec7d, 0xff36e95f, 0x983c8f8d, 0x55c7c619, 0x78a767cd,
- 0x5bdfd07a, 0xdf3a7f44, 0xef875648, 0xaf3e12a0, 0x465e3e4e, 0x7c0b12fc,
- 0x7c7c419c, 0x6719cf01, 0x7731dcd9, 0x280ed941, 0xfbe94109, 0x81f69567,
- 0xe546988b, 0x72a5e612, 0xf91d9039, 0x6dd81bd6, 0x62af7c45, 0x6d7cf44d,
- 0xf21762d1, 0x8fb332f1, 0x306bc9f6, 0x7dcf1753, 0x12494759, 0x36ea4bc6,
- 0xe80495bf, 0x7bb0d39b, 0x676fc632, 0x85be1707, 0xd321d965, 0x055bcc05,
- 0xce2ef8b9, 0xbd54ddab, 0x7f8c1fb5, 0xb71373f7, 0xb3e787f6, 0xf60f4e24,
- 0xae87a72e, 0x0dd72237, 0xe499b072, 0xeb43d633, 0x06a59c92, 0xc2d8a839,
- 0xaef8a63c, 0xb94ef9fc, 0xfbfd5a28, 0xe4bfa8fe, 0x54178a0e, 0x438b61bd,
- 0xdc62af3a, 0xf479301f, 0x07ee8878, 0xd5f3e230, 0x76c35a2c, 0xfebe0a9f,
- 0xbe230074, 0x1b04d4fe, 0xff2e82c2, 0x92faa594, 0xecba320a, 0xb9f99575,
- 0xb0278861, 0x9f89fbe7, 0xcb6d37cf, 0x1fbd434f, 0xc4ff454c, 0xab4dacf2,
- 0x15d83349, 0xae9f75f6, 0x16a3d738, 0x9c8a871e, 0xede8a997, 0x623fa33f,
- 0x9e00b2b3, 0xb35c8083, 0xfdcf2851, 0x355724ac, 0x978c5a88, 0xf9baf24d,
- 0xffb1ac39, 0xadbe62d3, 0xdd71e57f, 0xe307ac00, 0xe1c7dd26, 0xdd16ca76,
- 0x0de90e35, 0x9a71a317, 0xead19107, 0xed298f1c, 0x37bfe829, 0x8e7efb44,
- 0x3fe3d1f4, 0x35b2befa, 0xba4c93ed, 0x52f63697, 0x18f7dd05, 0x80fba363,
- 0xd8b88877, 0x2e3c451d, 0x071e8776, 0x07111f1b, 0xb0c7888b, 0xc5c73df1,
- 0x98ccbd74, 0xe4f9c166, 0xd7d4ffb2, 0x5d18f14f, 0xabb3760f, 0x8a3690b0,
- 0x6e29bb57, 0xc99f19d1, 0x4cf8f2b7, 0xd5c53249, 0xee4f42ad, 0xa4fd72f2,
- 0x0e589fbf, 0x3ec3185b, 0x0d32cec2, 0x00d508fb, 0x324ea80f, 0xd1b81fb4,
- 0x0b4fa86d, 0x33ea18e4, 0x9c0334ea, 0x686450d5, 0xc7bf683f, 0x4b06e700,
- 0x1c87ed0d, 0xa1e01af5, 0xf686e54d, 0x867d9bc3, 0x0ad0fcfa, 0xd688fd43,
- 0xb23c036a, 0xfda1a36d, 0x86030fe8, 0x75ed31fa, 0x1771fa86, 0x84f00c1b,
- 0xf686fd8e, 0x1a0f5db7, 0x1fb227ea, 0xed8bea1b, 0x93c0333f, 0xda185fd5,
- 0xd3ec253f, 0x862d49ed, 0x5c4407e7, 0xa4fbaa62, 0x39e9fde1, 0x53f00c67,
- 0x87946f48, 0x879256f9, 0xf783f596, 0x07fd0055, 0x186b37ac, 0xfda999f3,
- 0xab2fd0d6, 0x6dfc47ee, 0x52cfe28d, 0x947cb6a4, 0xedcca7db, 0x6d3e5869,
- 0x7dc16f72, 0x89f8c66f, 0x2acef614, 0xcb05b859, 0x9b363341, 0x9f40dc13,
- 0xa0b707b9, 0x68a90c98, 0x1e00bb31, 0x16ece4ba, 0x8d61d217, 0xfc444a49,
- 0xc1ab486f, 0x89a6c472, 0x8fd41252, 0x83585dac, 0xfd71757a, 0x61cb8599,
- 0xd837a35e, 0xa09dcd89, 0x3e30da0b, 0x6f887b26, 0xe29b0037, 0x8c8c363a,
- 0x5dbbfca6, 0x37191563, 0xba76bb33, 0xb86e316a, 0x1d41676b, 0xafc0db96,
- 0xac620e0f, 0x2c7afc0e, 0x1f5f8277, 0x386e8584, 0x945887f3, 0xa9e07553,
- 0xdfd73c24, 0xcd53e93e, 0xfb0ae1ac, 0xe3013dcd, 0x8b4427d6, 0x737ec7bc,
- 0x7f426627, 0x0f00ab28, 0xdcfa71f8, 0xbe1dd280, 0x2a3bc436, 0x372a1707,
- 0xd7bfa1a4, 0xc0c0dfad, 0xc3e227b9, 0xa27805fa, 0xf5fa6dfc, 0x785fb078,
- 0xc3de63de, 0x9f6e1ce4, 0xf59ae407, 0xd7ca023c, 0x943a2ee2, 0x80c497e0,
- 0xd31fab9e, 0xf80e5bea, 0x136ad595, 0xf71637dd, 0x4da43056, 0x5f1be071,
- 0x700f16df, 0x64ef7892, 0x8e0e6f9e, 0x72e380ab, 0x927f8c2e, 0xc61c0096,
- 0xbf00fb1f, 0xf35d2ce7, 0x0e67dcb1, 0x2c2fa0c8, 0x069a65c5, 0x20b93ce3,
- 0xfb9d369a, 0x22ff46ac, 0xfc9de44b, 0xfbcc473c, 0xfd0d1cc6, 0xf58b9fa2,
- 0x8df7ee3c, 0xfd82d8fe, 0x7932a0af, 0x40f98849, 0x579a29cf, 0xcb0ad4c3,
- 0x8cda3fd7, 0x07c04ef7, 0x8a3b426a, 0xf98737cf, 0xb8732b1b, 0x5af9625f,
- 0xa5baf8a2, 0x85c5abc6, 0x4c916f8d, 0x4fed3dd5, 0x1065e237, 0x5186af7c,
- 0x49f8e5bd, 0xac9f4fba, 0x52969835, 0xe786213f, 0x3f884a21, 0x4d05a7ef,
- 0x923e004b, 0xff7c36e3, 0x9812dfa1, 0x4fbc787f, 0xbe6136ae, 0x6aa6e242,
- 0x5121e213, 0xbe786af5, 0xc35edcc8, 0xc6e275f9, 0x1e3fa3b5, 0x6af6f381,
- 0x99610798, 0xc87df3ae, 0x9cb5448e, 0x703262d7, 0xea5ee2dd, 0x1316b755,
- 0xf43ac3df, 0xe7e76952, 0x3bd5bd5b, 0xa6a9de0b, 0xc502d7bc, 0x4f58478d,
- 0x07e52be5, 0x23b3e07b, 0xa92fdc39, 0xa3e71a77, 0xc217e7e8, 0x19555c6e,
- 0x6f425bb7, 0x61cb1fdc, 0xf3fb9fbd, 0xcdd9120b, 0x44dfbbe6, 0x5c3ab1e7,
- 0xde20e30f, 0xd8b46fea, 0x98f56f11, 0x8bf64167, 0xfa7add91, 0x77073987,
- 0x4ff3ba9a, 0x89003937, 0xbe40298b, 0x01ac1b3c, 0xadf239fc, 0xca69fa1a,
- 0xe84ccb83, 0x6ab1240b, 0x4652184a, 0xc3cab496, 0x72bf326e, 0xfa27ff23,
- 0x64c1f28c, 0x37dd325f, 0xfdd57410, 0x7474ee82, 0xde206627, 0xe579e5df,
- 0x89dcd3eb, 0x5f9d4748, 0x63fc9fd7, 0x0e8c2f94, 0x2e7e081f, 0xca120d62,
- 0x44d658eb, 0x46d678e5, 0x075877e5, 0xcaa61e95, 0x1a624e58, 0x4bcc2595,
- 0x4d5614e5, 0xa06b2965, 0xa26b1a72, 0xa36b0672, 0x5453f612, 0xfb4a997a,
- 0x57e0d9be, 0x79973960, 0xaac79ca9, 0x7c80bca9, 0x672df80e, 0xcddf040d,
- 0x066ca89a, 0x841ee03d, 0x953b0971, 0xc59e81af, 0x127f0df2, 0x9bbf2195,
- 0x97186db9, 0x84f2a1c8, 0x6df2a35f, 0xad95117f, 0x7bb50f7e, 0xe54a5fc7,
- 0xca97bf29, 0x2a72fed3, 0x6a3efcdb, 0x057f9ef7, 0xabf81f95, 0xff37fca9,
- 0xf43f2a46, 0x77fca807, 0x59951d7f, 0x06fb4656, 0x9fca1396, 0x3948f40d,
- 0x81b8f56f, 0x1cb905ae, 0xe63dc78f, 0xa478dc84, 0xfe30cca7, 0x271c94aa,
- 0x66dc5126, 0xe757bfba, 0xa316c63e, 0xfdcd3e3e, 0x83a24748, 0xe1a554fc,
- 0xc8bcc304, 0xd4bb5366, 0xcf6b6807, 0xe7b5cff5, 0x8d7f1d82, 0x10d1f6d5,
- 0x0763ddae, 0xa5b4f47b, 0x5047faad, 0xf378fd2f, 0xced83b5c, 0x3ef78eb1,
- 0x54c3967b, 0xab04e63f, 0xe6760151, 0x5783df6e, 0xa81e70b2, 0xbc7e93f7,
- 0x4ce6ee63, 0x27d7279c, 0x500d77b0, 0x853ad5fe, 0x1bf2aff2, 0xa1a3e58e,
- 0x14ad531d, 0x6b0bdda0, 0xde8af147, 0xebd645da, 0xe9593def, 0xf50f1092,
- 0x01eda07f, 0xe508c94b, 0xbc2c5c63, 0x1bb7f35f, 0x1937499f, 0xe99dbc3f,
- 0xcc9dfd26, 0xfee6a4f3, 0x91e7c07f, 0xfaf96dfc, 0x3be8cff8, 0x0a23ac1f,
- 0x9631bbe5, 0xf00e9feb, 0x55ff719b, 0xcdfae02f, 0x3747e4e9, 0xdf7379ea,
- 0x31bea993, 0x8ad2bb5a, 0x8a4ce6f0, 0x7ac7d487, 0xfdb173a2, 0x43d274d6,
- 0xe5187d29, 0xded2edbd, 0x7261dd56, 0xeb97353f, 0x35c2655d, 0x8bea3175,
- 0x8f0cc9ef, 0xef7e07da, 0x01dbd683, 0x66adee6f, 0xcc529efa, 0xd14a0f84,
- 0xc937042e, 0xf3a124a3, 0x3a2fd518, 0x5dbafb82, 0x1b3a359a, 0x51107ae8,
- 0x9d5ffe87, 0x4a5ffe42, 0x7e3e50df, 0xccab6a57, 0xf522d7f3, 0xbe316edd,
- 0x86d851d9, 0x6f9fadef, 0xa4bc6377, 0xef58fd37, 0xf9e3e40f, 0xb7da2bb7,
- 0xac3c8190, 0x7e3e7dc8, 0x2e15382b, 0x1e6bf727, 0x17363dcc, 0x8bd543ef,
- 0xf1add8bc, 0x8adefa66, 0x283ae052, 0x58abf585, 0xb3b26e43, 0x62c72166,
- 0x523bf53d, 0xfbb8ef28, 0xd7f68d3c, 0xc23cc1a1, 0x88bd74f4, 0x378e745b,
- 0x2941dfa2, 0xd8a7ae2c, 0xa78d1a42, 0xbc7d33db, 0xf1bdff9d, 0x4f7c8976,
- 0x28c73c7d, 0xd61cfae3, 0x439f5a36, 0x78fa41f8, 0x3d7d70bb, 0xe37c8de4,
- 0xf0beb878, 0xd71b46f1, 0xd1b5b0e7, 0xf7121cfa, 0xdbc73a6b, 0xbd78f3d9,
- 0x2237b38d, 0xf72f4fff, 0xdc13ff0a, 0x180e7643, 0xf9c6c534, 0x330b69f9,
- 0x92bc039c, 0x1ff3edcb, 0x595f38f2, 0xc97ae36e, 0xfdd2b2e2, 0x8bae89a4,
- 0x95af91bb, 0x173a663d, 0x26dfe253, 0x3c4e4b3f, 0xa7da24c5, 0xfe7c26b2,
- 0x17bf89b4, 0x98f6b048, 0x5fd7b367, 0x2c333a34, 0x55a89dae, 0x6b6f309b,
- 0xe195aba2, 0x6f128039, 0xf12bf5a5, 0xea1460f6, 0xd8098d5f, 0xfe83ec1a,
- 0x8bdf50c4, 0x974f30b9, 0x15c5e5c6, 0xf9883d6f, 0xd0e58954, 0x9e3e186f,
- 0xe4cc7c16, 0xb0b2b4f6, 0x791d42fb, 0x5cba1f1c, 0xc36fce47, 0xc6878e60,
- 0xea2af049, 0x8e3c31cd, 0x3f70fa73, 0x7accc7da, 0xfb83da34, 0x063bd3fc,
- 0x73bc1097, 0x9c01e52c, 0x0a763c3e, 0xed666bee, 0xd826669c, 0x3e315ac4,
- 0xdde76b33, 0x929e7c66, 0x1dfe88c1, 0x5fa4ad67, 0x255ced67, 0x14d3ffda,
- 0x0e645f6c, 0x1ae304fc, 0xed1d0f45, 0xb19b7183, 0x63fa178e, 0xbedcda79,
- 0x7477bf01, 0x857eca87, 0x73779bee, 0x7d4d039c, 0x0b748ed9, 0x977ec5c6,
- 0xe697cfcb, 0xe7858f30, 0xee29788d, 0xdb68fe30, 0xfc82bc71, 0x628ea69d,
- 0x34f76e3c, 0x9cb027ab, 0xc84ad214, 0x9ef56c2d, 0x5b4a72c0, 0xbbba0975,
- 0x9c361fa5, 0xb861b2c0, 0xdf8877ef, 0x2a8e0fc3, 0x49c60678, 0x68dceefd,
- 0xb7d277f4, 0xa41e4e84, 0xee85b1b8, 0xf22dedb9, 0xde3049d6, 0x8ed7b75e,
- 0x7c6f6876, 0x6bf499ba, 0x5a0af56c, 0x866880e7, 0xfaabdceb, 0x6fbfd0a2,
- 0xef46e714, 0x2c4731f8, 0x7f3479ec, 0xbfe099fe, 0x1ed7aaad, 0x52a0724b,
- 0xfc2283be, 0x49e67ab4, 0x3b284342, 0x1b8c413c, 0x3d70f5ee, 0x7ef8501e,
- 0x036f9b19, 0x98ae8ebf, 0x29e8bb9a, 0x7f31b26b, 0xec1bdc1a, 0x50ed1657,
- 0x883fa217, 0x06116ed7, 0x13bfc1fb, 0x743db8c4, 0x673a2e28, 0x172fe7d0,
- 0x7c617f42, 0xad9ff386, 0x8fa7bd74, 0xf6160eab, 0x5ed3f041, 0x9f4fef1f,
- 0xb760ec6f, 0x731b5ef8, 0x923e719b, 0xc3ac0f98, 0xb09f361c, 0xcebeb476,
- 0x892d3379, 0x30f59fdf, 0xb996af7e, 0x3bf5b0e5, 0x44bb5e6d, 0x22acd076,
- 0x33343aff, 0x28704bdd, 0x04fba73f, 0x1ac8eb91, 0xdf69e3cc, 0x051f6197,
- 0x79a699eb, 0xf7e5ca18, 0x55f90f55, 0x78e580b2, 0xe3c987ee, 0xd84b3127,
- 0x49f8e57a, 0xb41a6ed4, 0xb4e7f8c7, 0xf21a3ea2, 0x54d674eb, 0xc17df2ab,
- 0x5f984c89, 0xfc866316, 0x4fc05974, 0x9650bf96, 0x71abc6e6, 0xe8392d0d,
- 0x8cb03d17, 0xd76a8cf2, 0xf9c56b4f, 0x6bace526, 0xef7a8389, 0x2cee9c57,
- 0xfb0dc79f, 0x790d91ef, 0x002bc9cb, 0xf75f3f0e, 0x07e06119, 0xaf9d7b43,
- 0x8aa95314, 0xcfb9847e, 0x3059dd8d, 0xedc9d97f, 0x6cb87837, 0xf2f10f6e,
- 0xf0257c6e, 0xc667d3af, 0xa7c24ce0, 0xb3bc70ac, 0x277ecd0e, 0x1bf113a7,
- 0xd5e309fd, 0x3e62d880, 0x14894d7d, 0x8ea1fbc4, 0x012cf6ce, 0xa7491ae9,
- 0xeec75b74, 0x957f5c2c, 0x23dbf299, 0xc47e0af1, 0x67c8699d, 0x1ea9e26b,
- 0x3abe539e, 0xf6752266, 0x1b04f523, 0xed4df1e9, 0xddc1609f, 0xf8d64f3c,
- 0xe0be293c, 0x8a429c9d, 0xcc9c6847, 0x0dacfac6, 0x8c62ba46, 0xa278f509,
- 0xb4a182c6, 0xb4e7a75b, 0xa612c6f8, 0xceaba774, 0x7b7d2977, 0x10f2f3d6,
- 0xea03b093, 0xf3d41cb4, 0xfff26609, 0x84e609bc, 0xd6f07df0, 0x725f7cc1,
- 0xe90a2bdb, 0x4ede766f, 0x50b4eff7, 0x13f41f5b, 0x93335d27, 0xa9d6fe7f,
- 0x834d8f63, 0x96aff272, 0xc9bb61d4, 0xbf46edb0, 0x372be862, 0xbf262c46,
- 0xe5172da5, 0x3a1655f5, 0xb1f682d9, 0x827142d5, 0x536f9fcd, 0x35fd2127,
- 0x7d3e7146, 0xb98323dc, 0x25a5fa9d, 0x9a7d25e0, 0x7e46b326, 0x6be3765e,
- 0x3e3c4e9d, 0xb2c77944, 0xabddaf89, 0xbd935755, 0x3663c94c, 0xadb7c78a,
- 0x21bc7b24, 0xccbca19a, 0x41ee9b56, 0x1765f678, 0xb37f4333, 0x2165b735,
- 0x3f091f9e, 0x59aa8e73, 0x69a96226, 0x3f9db9fc, 0xe87aab9f, 0xc3cd5cf9,
- 0xbf7c2b9f, 0x681aa77f, 0x777f43f3, 0xec6e712a, 0xcbcd4eef, 0xa8dbafeb,
- 0xffec14fe, 0x47b4efd0, 0xebd45405, 0xfccd170d, 0x4d17ce7c, 0x2955befc,
- 0xfce37568, 0x4f74cd0a, 0xba24fc0f, 0xf54bbd5f, 0x7deafdd2, 0x088c97cc,
- 0x3670b57e, 0xc6afd1f9, 0xd5fee99b, 0xe5331eab, 0x642a0581, 0xf0521f7e,
- 0x29e5abd1, 0x8e967e74, 0xdd7a44c8, 0x643f2763, 0x62441e2b, 0xdc7ef2fb,
- 0x7fdcc85e, 0x9e2a3fd8, 0x2c6d3bda, 0xe0f914ae, 0xf2f94cb0, 0xe3cf1fdf,
- 0xf4a1f298, 0xae6bfa20, 0xcbbca30a, 0x3f389385, 0x39454c68, 0xc469a198,
- 0x987b35f7, 0xdc937666, 0x5740fbd3, 0xc2aee75a, 0x22fa4af7, 0x24d346bc,
- 0x7d06182e, 0x1ef85351, 0x4ccf83c7, 0x0abbeff9, 0x49befbc5, 0x5d7c7087,
- 0xf90b07ce, 0x774af5d4, 0x3f51a43d, 0xda49d88e, 0xc306804e, 0xfbff2800,
- 0xf51cf0ad, 0xf74c9c42, 0xca1706c6, 0x97587521, 0x7e8b27dc, 0x94f90b07,
- 0x2ce51a8f, 0x7e1190eb, 0x7eefc85c, 0x62fb9216, 0xce8c0dbf, 0x1837facd,
- 0xc7cec1db, 0x522c7a84, 0x3f0baf8e, 0xdd0f1233, 0x79ebecf0, 0x0aeb5d9d,
- 0xbad36544, 0x425d7ccc, 0x5b2a65df, 0x2aa679e8, 0x179c6e6b, 0xd70f786b,
- 0x0c90ffdf, 0xabd02a0e, 0xe31b3cd0, 0x3202333c, 0xac99bba9, 0x37c5f48d,
- 0x88ab7bad, 0x33ae4573, 0x06db7d72, 0x64bf5c4b, 0x37e4bcf8, 0x37e4cb25,
- 0x6303d659, 0xe56bc70c, 0x23b79dde, 0xeece875d, 0x59da0433, 0x62a5581f,
- 0x7a155a5c, 0xc4b5f2c9, 0x3b61ebf9, 0x7125abf1, 0x7df84e46, 0x24da919b,
- 0x51c50875, 0x841c9eaf, 0x2d77c771, 0x3d48ff84, 0xc7086637, 0x637698f3,
- 0x8bb8e45e, 0x7c7911d1, 0xdbc8bcc6, 0xc88bf7ae, 0xc888cbe3, 0xa8621be3,
- 0x888eac9f, 0x171be3c8, 0x6c57c791, 0x4ce7a780, 0x9be3c88f, 0x28ef8063,
- 0xbed0c7ba, 0x50d8b3cc, 0xb574a73f, 0xef4efea1, 0xaef806fd, 0xed0d87f2,
- 0x0c6afbe7, 0x78acf7f5, 0xfa0f50c4, 0x73b8c7a2, 0x87ae10f1, 0x6d3c936b,
- 0x103081f4, 0xfe0f6f78, 0x1dcaa480, 0xd9c7f6e1, 0x56a2fecb, 0x7d29e3d0,
- 0xe248127f, 0x8f116671, 0x10c47705, 0x9d8d0daf, 0x517dc766, 0x444b4d9a,
- 0xcd7ecebb, 0x585806ed, 0xc4e6f9c3, 0xdda94b07, 0x3a74d8fa, 0xfc027987,
- 0xc0e81f6c, 0x77cf20da, 0x6f0017e9, 0xabf79e1c, 0xf5da1285, 0x78a56ebb,
- 0x583ce76e, 0x5577f529, 0xf3ea2f9c, 0x43f18fdc, 0xecdbee1b, 0x54cf3254,
- 0xe28e3f1e, 0xe9751eed, 0xc31a96e7, 0xd6451d7e, 0x164be500, 0x30ac5b06,
- 0x8fd05adf, 0x97849af8, 0x55dda1ec, 0x3de9bb45, 0x127f1ab0, 0x96520fdd,
- 0xe8160284, 0xbf27eab2, 0xf0e3e1f8, 0x1463e2be, 0x27f878a7, 0x7e21fcbf,
- 0xc43fc407, 0xc871744d, 0xeefbcf1c, 0x874ba7fd, 0xbac65f51, 0x64625ee8,
- 0x9b7de27d, 0x26eb7abe, 0x3c16fbf5, 0x37a5dbf8, 0x8ddeff7b, 0xd586b767,
- 0x597f36f7, 0x613cc7e9, 0x356a907c, 0xcbd5c3de, 0xaabe0bef, 0xf8a56b1a,
- 0x57c92ce5, 0xe5fcf28f, 0x707affd8, 0x45f7bc3b, 0x717bb5c9, 0xbfcf077f,
- 0x1da1cf8f, 0x948bf5e1, 0x3cf8a92b, 0xfff80865, 0x58a36768, 0x6f7cf98f,
- 0x8b7ee10c, 0x41d1589c, 0x2b04f3fb, 0xf65c87c5, 0xee3fa3f9, 0x447358cb,
- 0xf71ea0bc, 0xf7a760e5, 0x1e88f88a, 0xf4417f2f, 0x92944473, 0x41ce9f3a,
- 0xf7403d98, 0xb17f7562, 0x8b383c9b, 0x651bee18, 0xae10be45, 0xac125b17,
- 0x54901f14, 0x4b77e52b, 0x2efa28ea, 0x7d1b04a2, 0x2872473c, 0x68cfb46d,
- 0xf1451849, 0x86342900, 0x128a0ce2, 0x40defea2, 0x7ee024ba, 0x77dfb8c6,
- 0x5d682bd9, 0x3acff7bd, 0xeb49f79f, 0x79889c61, 0x1f5878e0, 0xfc41ce39,
- 0x9bda1c2e, 0xe31ef665, 0x4c86d71b, 0x4af48e3c, 0xbeefb5b3, 0xfdf5e51d,
- 0x5eb2f59e, 0x307f9e62, 0x86673f0c, 0x605f13a4, 0x6c307f7e, 0x0fe3cc5c,
- 0xe8038187, 0x60c1079e, 0x42d8066a, 0xb9f88351, 0x6f578d05, 0x3fc892d5,
- 0x7487f304, 0xe7908dfc, 0x61af023f, 0xc3ec57b9, 0x635c83f7, 0x255f84f9,
- 0xc800ed3f, 0xfb4fc21f, 0xfd0654dd, 0xfa365439, 0xe43faa35, 0x88f8222f,
- 0x51f043df, 0xcf95297f, 0xfcf4bdfa, 0xc1397f39, 0xa8fbf53f, 0xa0aff26c,
- 0xabf82fe7, 0xbfc97e09, 0xa39fe091, 0xe785985f, 0xbe547513, 0xfaa06fea,
- 0x09fbfcd7, 0xa41fc37e, 0x4a3fe432, 0x9bf98fcf, 0x6fe13e08, 0x7f6df826,
- 0x7f56e088, 0xf8ef952b, 0x29f9e8db, 0xa30487ff, 0x45fee23a, 0xe03f19d2,
- 0xd9817125, 0xe25e7e8d, 0x4bb34582, 0x2e57de00, 0xd7617dd3, 0x41d2f97c,
- 0x34278be0, 0xfb7bf699, 0xee299856, 0xfb95fba3, 0x16c7d62a, 0xaa5cfd53,
- 0x268d486f, 0x12ff6cbf, 0x571fdd2b, 0x967f7256, 0xbda8552d, 0xfd532f92,
- 0x92e62b13, 0x538f58df, 0xd92ae700, 0x1931d81c, 0x93322ddb, 0x111fdefe,
- 0xe3ca4dd7, 0x4f293f76, 0x8faff7e6, 0xcfc20546, 0x629b2b29, 0x7355700d,
- 0x30e3e072, 0xc62d59be, 0x1c991b61, 0xcfc7ddfe, 0xaf307ff7, 0x90f9d604,
- 0x03ca4be4, 0xe0717c7c, 0x99d83cdc, 0xc3bdb332, 0xcce4f28a, 0x8d4ed9e8,
- 0xebcfd3cf, 0xfe224e92, 0xe13269f6, 0x61b69f6f, 0x2fee265a, 0xddf4c816,
- 0xf205c48c, 0xe99fb857, 0xfba65f37, 0x994acaa4, 0x816c81e2, 0x0363e059,
- 0xfcdfbbad, 0x0eaf54b9, 0x7471453c, 0x6d13cad7, 0x016fd193, 0x1d11657c,
- 0x39e2c50e, 0xbb88b26e, 0xa68f8fee, 0xf9c8b6bc, 0xf17bff8c, 0x33f009b3,
- 0x8cfc47aa, 0x4f3f09ef, 0xfde3fb88, 0x222277c4, 0x977fa4f1, 0x7df109f5,
- 0x1e06c0f2, 0x376c8fbf, 0x731fcc47, 0x2e3be8ce, 0x8fe93295, 0x23b82c03,
- 0xf998e31b, 0x7e43dd32, 0xb3aad27c, 0x3f3e6107, 0x91ddf3c8, 0x2c9fed07,
- 0x8ea18f91, 0xfde52b8d, 0x1f235c0f, 0x7e02be41, 0xda04795d, 0xe93bbf6d,
- 0x7d94364c, 0x8c16ee03, 0x1f463abf, 0xf989f648, 0x161764f6, 0x80fbbf0a,
- 0x2b4fc447, 0x651a3df9, 0x13dc9ee5, 0x3805dc7c, 0xb5f52bae, 0x0309f8a9,
- 0x930edcf7, 0xf97eca05, 0xcf1c3af2, 0x49d24f76, 0xe0212f1c, 0xc7cbc7d1,
- 0x9e2dbef1, 0x925bbf52, 0xf1bdd3d8, 0x37e1f4de, 0x79f5c1e9, 0x7f513ee2,
- 0xe0f51fd6, 0x8a7696e3, 0x70ce0753, 0x38b4c83d, 0x3917bfba, 0x27f96f4e,
- 0x649f8101, 0x886f3f1b, 0xe7476f7c, 0xf02025be, 0xf28cafd8, 0xe2cb26b4,
- 0xf68cfabb, 0x4627ebdb, 0x726f9bab, 0xd403f31e, 0x1eafa0bf, 0x9fa263ce,
- 0x1fbca994, 0x0267ef33, 0x44f0475b, 0xe4dc0d45, 0xe88f601c, 0x00fd8fc7,
- 0x7bbf1f7e, 0x18adeec5, 0x42d77cb7, 0xc90e74b9, 0xcef49bb7, 0x1fda25af,
- 0x2b0dccb9, 0x17f5878f, 0x9fa97c14, 0x48de6043, 0x79d7565e, 0xec055244,
- 0xadf0c291, 0x88b8f7bf, 0xe3793fa3, 0x9bca58a1, 0x8510dfc8, 0x663edffe,
- 0x2c503e27, 0x0c3f3521, 0x7f898a7f, 0xfe7227cf, 0x7aacf2c7, 0x7132805e,
- 0x32239e14, 0xf519cf7e, 0x75fbcc28, 0xb77f939f, 0xd307c169, 0xfe3c0387,
- 0x0fe74c9a, 0xfcd1a5ae, 0xcc1ff6fe, 0x86f46794, 0x677e1788, 0x63dd096d,
- 0xf712c24b, 0x054fb8a7, 0xa626fc78, 0x9f7df085, 0x09c1fb42, 0xe173e5d7,
- 0x0ab2097e, 0x22ee37f6, 0xb8f2f8a3, 0x6f70d90e, 0x6345cc6d, 0x84bfa07b,
- 0x76a4dafb, 0xa144bb63, 0x15235dff, 0x7e8ffefa, 0xd7f5d06f, 0x64c5b97d,
- 0xff49a227, 0x24c9a93f, 0x2a164fcf, 0x76ddb107, 0xfb84bb3b, 0xbb7cc744,
- 0xc5a07a8a, 0x557a4d15, 0xfe4d1119, 0x6394f6f3, 0x9fc076f6, 0x2a07e46d,
- 0x6c032bfa, 0xbb1883be, 0xab73edfe, 0x218d25e7, 0x5df5de3d, 0x3bb022e3,
- 0xf282f978, 0x9decd699, 0x1579899c, 0xd8eefa66, 0x7ab73c7f, 0x2277f86f,
- 0x307524d3, 0x84ec57cf, 0xe0dfa157, 0x418fb9c0, 0x33ea063f, 0xd7c61cf0,
- 0x29217a8e, 0xf905babe, 0xb6395eaa, 0x85d0e282, 0x2d57a4f1, 0xea10eabe,
- 0xc0ad7a89, 0xbadf2e1e, 0xdcaadc9c, 0xd5ce293f, 0xbffe49be, 0xe4dedfa9,
- 0x2e5c95fc, 0x01c5bd77, 0xb77e7df4, 0x5ebec4fe, 0xdfdfc21e, 0xe079f42a,
- 0xbd47b5ac, 0xd72866bf, 0xef224517, 0x297c5661, 0x567e7f7d, 0x3cc65da0,
- 0x2e50cf50, 0x1c12fb47, 0x2fb0cf94, 0x7e30858d, 0xedcf981e, 0xe20ad903,
- 0x538a74a7, 0xd4da9bd5, 0x0a43d200, 0x2e2e91b9, 0xefe187d8, 0x6ddfd478,
- 0xf977d20e, 0xfc28be82, 0x63f41e3e, 0x852817d8, 0xe4d5e2dd, 0x6871ebbf,
- 0x7e008efc, 0x82b687ff, 0xca3a82e0, 0x9b9df4cd, 0x7426f7c8, 0xaedbe118,
- 0xcc89e11b, 0x629abdf8, 0xac9e11bb, 0x43a1e11a, 0xf6e2bef9, 0xa9f3e324,
- 0x6fdc236e, 0x9994637e, 0x78a0ffdf, 0x0c147e95, 0xb8c03eff, 0x64017f58,
- 0x60f7e20c, 0x21afb7fb, 0xe8ff507d, 0x7eff920c, 0xcae2226b, 0x8195b00c,
- 0xf3e36a71, 0x2d859cc4, 0xaaed7e98, 0x87be2390, 0x2ce746d2, 0x73c30f80,
- 0xf20b7cfc, 0x9e6ce1ff, 0xdc30d9ff, 0xc8e87937, 0xde1c79ae, 0xcfce9b33,
- 0x035f562c, 0x28c74efd, 0x36d2ec99, 0x9b75d399, 0x35ba72a6, 0x5779d327,
- 0x60b44aa2, 0x5d5f3645, 0x4723c61a, 0xc91e299a, 0x3df9e21a, 0xd3fae7f4,
- 0x2c6241f9, 0xe773439f, 0xfa47dbfe, 0x40d89d97, 0x2afb03e7, 0x788efa64,
- 0xf9403db2, 0x2bceb053, 0xce963886, 0x39f9f3b7, 0x50d7ac0a, 0x62bceb0f,
- 0x101f97e4, 0xa2f5f49d, 0xf0c206bc, 0x081a7280, 0xbe699b8f, 0x940788e5,
- 0x51e7f0d7, 0xba16ed99, 0xd3d62d4f, 0x7aeadc9b, 0x579c48a3, 0xd76c79eb,
- 0x1e7a98c4, 0xff9106db, 0xe234ecda, 0x24f95ae1, 0x6b5c338a, 0xebed139b,
- 0x2f418e49, 0x2f5c6c04, 0xde1db960, 0x7bdfb943, 0x1c54e163, 0x2044f50f,
- 0x16147bec, 0x6dffa7c1, 0xc221b3bf, 0xeffb3f2f, 0xf9186a47, 0x9e208f9d,
- 0xe39c072a, 0x77c5edf7, 0xb6782cbc, 0x3ea5cf07, 0xcb7aaf9c, 0xcae9af1b,
- 0xbae3b5bf, 0xbfbc88a5, 0x5af8112b, 0xbfa5f02f, 0x274d457f, 0x2d695d3c,
- 0x2786f7b6, 0x1327f426, 0x332f13fa, 0xbb3e2ace, 0xec634121, 0x9fdfe799,
- 0x671d0327, 0x985b3ead, 0xcf9bf00a, 0xcfc39eff, 0x3fa97d9c, 0xec361d34,
- 0x3df879f3, 0x9d8f598c, 0xa1a296bd, 0x85de26dc, 0x8a70c3df, 0xbe7d1973,
- 0x092f78fa, 0xf1b5597d, 0x90671e1e, 0x357724bd, 0x01c52f2e, 0x70ef8cbe,
- 0x5542f9e2, 0xd16b8742, 0xd57ef44d, 0xfbf97bc6, 0x0a353e98, 0x5cb889f3,
- 0xfbf3d6cd, 0xfdf98d4b, 0xd22ae74e, 0x5016367b, 0xd9442f51, 0xeebe743d,
- 0x3a26e619, 0x72b4c9dc, 0xceeebe7e, 0x5accfa42, 0x3fd1ea6d, 0xe7aa1d6c,
- 0xd5be86fb, 0x2bdc4cb8, 0xda245398, 0xc65fe3a9, 0x7b34ee71, 0xf05fa2b6,
- 0x482cc67f, 0xcf41b740, 0x75d21a7f, 0xadd0ef4f, 0x759cffdc, 0x496dc4de,
- 0xff278f0c, 0x575f3871, 0xed009c78, 0xf9746f46, 0x3c5d1bac, 0x89ad0714,
- 0xa8ba70f3, 0x48cdce1d, 0xd70ed897, 0xd7debc96, 0x113e8ddf, 0xf82ab8f8,
- 0xe42bfd1e, 0x9fc26fd7, 0x4f3d1f4e, 0xcee4c6ac, 0x40e67f22, 0x147c437f,
- 0xaf6e0236, 0x76fe67a3, 0xc88f7d87, 0x38a5e49a, 0xcb5e2593, 0x9ae67cc1,
- 0xe63d49bf, 0xe30f6777, 0x6766f37e, 0xaf17dd34, 0xbee95a71, 0x27738b5a,
- 0xaecd3f43, 0x94bc236c, 0xe618eb38, 0xb3a6d5d1, 0x06edfe26, 0xad715e63,
- 0xef5e6ef3, 0x9dacb3e2, 0x2e31eba6, 0xb4e7b5cf, 0x8103b418, 0xaf2edfd3,
- 0xbfe76e58, 0xbd5bd25b, 0xcf1a6e33, 0x295a762b, 0xb18a58af, 0x5794f756,
- 0xc7c117fc, 0x78beb82d, 0xa78f0f5c, 0xbbb2ebe9, 0x3e23fe79, 0xd59a78c7,
- 0xafdfa3ed, 0x97ffd7d1, 0x7a2e9ca1, 0x9abb9b7b, 0xac97dea1, 0xacf51b9a,
- 0x884fbe24, 0x4c272476, 0xffe3ea5f, 0xef85a869, 0x4a953597, 0x8ddb9db3,
- 0x39eebf59, 0x30f47c3f, 0x9dc92dd3, 0xcdb337ce, 0x97466f3c, 0xd58ab9ef,
- 0x5cc37e83, 0x7af28925, 0x2fea02e6, 0xffb585c6, 0x1efc5dce, 0x2125acaa,
- 0xee3fbd3f, 0x07df97b6, 0x2e983df0, 0xa9bde9e2, 0xf59fba16, 0x7079899e,
- 0xb79919eb, 0x4ec6f5e8, 0x1de3edc6, 0xa2d6ce33, 0x620c6638, 0xb0e43f74,
- 0x78e762b3, 0xccc3fe46, 0xae60d061, 0xde326caf, 0x9e5d98c7, 0xafb616ff,
- 0x8f407612, 0x49f55717, 0x91fe520d, 0x6c339be4, 0x3f8dc624, 0x6242559d,
- 0xdf4a91df, 0x4f6aecbd, 0xf6b0e371, 0xd3fb45f3, 0x1d71c469, 0x2b83ddf4,
- 0x3e8bb1ea, 0xf287d137, 0x8bf12221, 0x9dff0a74, 0xa07f5d35, 0xfe1167dd,
- 0x48fc3879, 0x13dd394c, 0xbd57edd0, 0xf578e7a5, 0xbd0986af, 0x38adcba9,
- 0x1f33b087, 0x4c91345d, 0x1ea7ee5e, 0x67d9f67d, 0xea7e5d5d, 0xf49f610e,
- 0x8333a27e, 0xf98d1954, 0x549a502a, 0xaca3f10f, 0x60052756, 0xdaffdb9d,
- 0x27f7fdf3, 0xf01e7975, 0x2fb61260, 0xb072fb71, 0xdf17cc8c, 0x072cba96,
- 0x34db72e5, 0x946aeedd, 0x9cedbe37, 0xbe7437fb, 0x1bcf0efa, 0x9d90196f,
- 0x4a517988, 0x59be45ab, 0xe415a65e, 0x3d137dd5, 0x3ff7156e, 0x631b1db7,
- 0x36f4f8c7, 0xcf0da0a5, 0xf129b777, 0x536db405, 0xde901e78, 0x5e78515e,
- 0x78f1a29e, 0xbcf0a2b7, 0xa77f3d39, 0x84dbc065, 0x03ddbd0f, 0x8d15af82,
- 0xd288e3df, 0x5d9da81a, 0xb2f7d2f6, 0xe28cf1ec, 0xff957652, 0xa67450ee,
- 0x907bd999, 0x2cc3b5d7, 0xe5b61f64, 0xa24db415, 0x146ec9f9, 0x05496d93,
- 0x1147a449, 0x8d7ef0ef, 0x316f13a3, 0x0a9fc788, 0xd4fdebbc, 0xde75f0b4,
- 0x417771bb, 0x23f45f49, 0x5f9087bd, 0xec8b29b7, 0x7246ef78, 0xbfb4de14,
- 0x432661e6, 0x7f57663e, 0x7f450a97, 0x24fec53f, 0xfd8a8147, 0xbfcf5859,
- 0xe8b6f8bb, 0xef3defe7, 0xfa360cc0, 0x226308de, 0xd494268f, 0x2761f9d3,
- 0x631cf0fd, 0xfef7f744, 0xbd677edb, 0xfe09de31, 0xbf516fe6, 0x7b9de654,
- 0xe13d127b, 0x68d6e6fe, 0xbf742fae, 0xfb795651, 0x0f7e66ad, 0x9abeff55,
- 0xb1ca47ee, 0xdd743c46, 0xb874e303, 0xc838f2aa, 0x7c518555, 0xafae5226,
- 0xb86e3a9e, 0xd8768147, 0x2c71fc23, 0x0cf4cfd1, 0x2e2973c2, 0xa3dcbadf,
- 0xebfd444e, 0x1f7f7728, 0xa8a4abbf, 0x30b7ca66, 0x5f12ff01, 0x9243de77,
- 0xc6cff47a, 0x3574e70d, 0x24685625, 0xb7284ae7, 0xe03f3927, 0x728b953a,
- 0x1ecba07d, 0x03aeb8ab, 0x1389dce7, 0xbf5ce4c3, 0xbff7a21f, 0x3564e4fe,
- 0x74df5d7c, 0x6e79c2ff, 0x8f64fde7, 0xff1edc5d, 0xd8c7df6f, 0x40aeb2ea,
- 0x326cdffb, 0xc391e5ea, 0x86d63eb9, 0x75e0f88b, 0xb3b7ee99, 0xe1b4bea1,
- 0xd98b3f80, 0xf97a8e5b, 0xdfdf3540, 0x1499b1ca, 0x7eb03987, 0x829e445a,
- 0x30f0d06f, 0xb3aa2c79, 0x85abbe92, 0x03ed077d, 0x491ae823, 0x3afe9d2f,
- 0xe7e728ec, 0x27bd3a72, 0x91212a26, 0x89fe4c07, 0x09997e2b, 0xdcab9af5,
- 0xb039f267, 0x81d91b7d, 0x115ddade, 0xaf6f4ffa, 0xce0aff60, 0x73e280af,
- 0xa0e75057, 0xfcf6a49f, 0x51976cfb, 0xec7e0498, 0xb1e72eb0, 0x2bf62aa9,
- 0xab793f09, 0x51af6fc8, 0xb09eed0b, 0x42d8a5f7, 0x3e30a4fb, 0xde25e9a9,
- 0xc7ae1fe4, 0xefb4439b, 0x4810efd7, 0x9e60d7e8, 0xee5f22a0, 0x7ed0478c,
- 0x9df0d4a2, 0xdefc7d45, 0x5f39edcf, 0x690b555f, 0x018f281f, 0x0bfc017f,
- 0x8192ec53, 0xbe2d3764, 0xfcc44e7f, 0x28dadf95, 0x2123f79f, 0x3e42ed9f,
- 0x0163d37b, 0x2d2e8c76, 0xf027616e, 0x49f008d2, 0x49f20c41, 0x70d98a4d,
- 0x9b97a3ae, 0xe26f3ac4, 0xbf0f54e7, 0xc1e73f35, 0x39f83de1, 0x9f84c7e8,
- 0xe2ffa3cf, 0xe89bd309, 0xf07a78bf, 0x62cdea73, 0x53ce27ff, 0xcddc5b4f,
- 0xd39780ed, 0x3be86213, 0xf87d193f, 0xe8d3df3d, 0x7f8015f7, 0x4cd9ccf7,
- 0x532cd624, 0x843a77e7, 0x0608c99f, 0xca276f3f, 0xaef31945, 0xd5bddfc2,
- 0xdf8988e5, 0x3a26f9a3, 0xe0dc06cf, 0x3de3b6bc, 0x87ba3cbc, 0x39d3da57,
- 0xfe4eb1de, 0xc7a61301, 0x401f08fb, 0x5a38b09d, 0x4460f8b7, 0x31c3103c,
- 0x19c5f99d, 0xbf6fdbdd, 0xf9f8a261, 0xe20b1f2e, 0x51dc02ef, 0xbddf8c64,
- 0x76d9f225, 0x7f24612d, 0x429a72bb, 0x6a245fe8, 0x65f1e28c, 0x39fb631e,
- 0xbddf91a5, 0xeef9c636, 0xe7225af4, 0xebb5df4b, 0x7fd7d627, 0xff8a2acf,
- 0x22fdc645, 0x3eb47de3, 0x3c8523b4, 0x1854afee, 0xf51cb8f3, 0xd8bbe833,
- 0x714af860, 0x3314ae7d, 0xa3ac38c3, 0x2dcf323c, 0x21ecf020, 0x59e3a665,
- 0x92899eff, 0x6bdfe66f, 0xf546dc0d, 0x7e1dbe7a, 0xaba27177, 0x3aca5d6b,
- 0x117c9f31, 0xbcf40dcf, 0xd7185dae, 0xbce8bcc4, 0xd084d036, 0xc605ce1f,
- 0xf460ae49, 0xb75857bd, 0xf0e25ce1, 0xfa262d9e, 0xa31f0f1d, 0x1e01a1ef,
- 0xcc16e78c, 0x5850f147, 0x039ce1bf, 0x238069d6, 0xe4df01f7, 0x93de1fff,
- 0xa277e3de, 0x278f52f5, 0x61338b75, 0x2fa48007, 0xbdf38b86, 0xfa286ca1,
- 0x06fe4a41, 0x1495c3a2, 0x72cb5f9e, 0xdbdf3e7a, 0xf7e1fd09, 0x72887e93,
- 0x01718092, 0x04def866, 0x0f74c8f3, 0xe7c454c0, 0xe5ebea6a, 0x48c79742,
- 0xccd16dbe, 0xa684798e, 0xea0f6882, 0x600d9b13, 0xf8852efc, 0xee24b74e,
- 0x283ffd3f, 0x00812bd4, 0x0000812b, 0x00088b1f, 0x00000000, 0x9095ff00,
- 0x50c34b31, 0x97bf8514, 0x4a36ac46, 0x1056dac1, 0xa8508a09, 0x755a5095,
- 0x97375433, 0x221d0e8c, 0x38ba383a, 0xfc5d251b, 0x09f9ce01, 0xe6e284fe,
- 0x482ae0e6, 0x22bf8290, 0x26a697de, 0xcbbd0820, 0x77dde779, 0xddf73dce,
- 0x2e8dcc2b, 0x5eca7550, 0x75619047, 0x444506d2, 0x9aea1152, 0x47e17536,
- 0x3cd6a5a4, 0x7c22c128, 0x4c12092e, 0xecbbaa75, 0xfbd45ab2, 0x5ffed246,
- 0x73e4ec6f, 0x7569fd73, 0x27e7cad2, 0x22ff8eba, 0xba77e898, 0x00839d12,
- 0xe4e3e1d6, 0x65f68fbd, 0xc8773d13, 0x5f94dcac, 0xd53da3e8, 0x3970079b,
- 0x3adf376b, 0xdbe20d46, 0x0aa8f38a, 0xa567047b, 0xfd398f74, 0xed34737e,
- 0xb0a56f2d, 0xef37e657, 0xbf89695e, 0xc21b71a5, 0xc1ec8481, 0xc81447a8,
- 0xbe0daad1, 0xb9417dcd, 0x3e99cb8b, 0xbf05c593, 0x67eb81f0, 0xf3ba7931,
- 0x8416bf0f, 0xcb62bcbf, 0x5f1dd7ff, 0x7f74f68d, 0x6b7d238c, 0xbb92f72c,
- 0x50a8dce1, 0xd9f695f8, 0xf4112ed5, 0x738dbcf3, 0xf3e569f1, 0x742b007e,
- 0x02505747, 0x00000250
-};
-
-static const u32 csem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0xe24bff00, 0x51f86062, 0x38cfc10f, 0x90981819,
- 0x770143f8, 0x01684331, 0x21060616, 0x62636620, 0x22676060, 0x072bbf5e,
- 0x9d877d82, 0x1038e181, 0x781f67df, 0x5e240d7f, 0xbb3f4dcd, 0x2ed1d37e,
- 0x7e27f062, 0x02af8606, 0x058b0c0c, 0x210b7c21, 0xfccff954, 0x18a47608,
- 0x02a57665, 0x150003f5, 0x8051b77b, 0x008051b7
-};
-
-static const u32 csem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dddff00, 0x45547c79, 0xbedd70b6, 0x97a7774b,
- 0x42c84274, 0x4010dc20, 0x804d8854, 0x024de3b0, 0x10602a31, 0x66b71c11,
- 0x04484b0f, 0xd3ce7cde, 0x0831baf9, 0x544e38e8, 0x387c0666, 0xa8d041af,
- 0x1a0c1a51, 0x166bc3b0, 0x26665419, 0xb8c38e3a, 0x6c8a89bc, 0xfd011242,
- 0x5f283798, 0x3b75539d, 0x4dba6f7d, 0xe3fbe65c, 0x45a7efcb, 0xeab7badd,
- 0x9cead9d4, 0x25aaa753, 0xd7a92059, 0xfe197212, 0x48a6f968, 0x51d11908,
- 0x1fb715b6, 0x04846927, 0x6dd5915e, 0x7fc22102, 0x0ed722b9, 0x16c8e427,
- 0xf5a56821, 0x21075ec8, 0xd3767eb4, 0x9735a0b4, 0x0e057d90, 0xbb3fde0d,
- 0x25eb08b5, 0x96e2febb, 0x2ee57b68, 0x65ba8251, 0x8b7729ef, 0x6b2a9093,
- 0xe963a3f3, 0x225df6f3, 0x228742d9, 0x490b1281, 0x8db8e427, 0xac8bbfb0,
- 0xaacec0be, 0xddf79b95, 0x3456fd05, 0xf69d895a, 0xe17bb953, 0xbeb4b1d4,
- 0xe04cb0f0, 0xab6dca95, 0xbeb45e94, 0xa0842828, 0x0fdec0fe, 0x62b69c70,
- 0x4c1a1152, 0x8dbf69c8, 0xbad057a8, 0x067d39bb, 0xb838be7d, 0x5fde14a3,
- 0x2d782f5c, 0x9bc5fdf4, 0xfe819df6, 0xfdc83717, 0x92ffda45, 0x0751073a,
- 0x132fb1b1, 0xa9fcc798, 0x1be56f00, 0x7ad2b132, 0x0a15a5c5, 0xb5491c01,
- 0xc60bb94a, 0x5d514c7f, 0x1c61ce30, 0xe567c747, 0xfa1c7473, 0x0497b2dd,
- 0x996d4c2f, 0x9e00f885, 0x59f6ddd6, 0x5e613b4f, 0xf08194ab, 0x0ab5eefd,
- 0x3830b7bc, 0x0abb15fb, 0x4a566df0, 0x9b4dce01, 0x3b830595, 0xf7525bfa,
- 0xe3ae0196, 0x7c32f21b, 0xf2e6ed31, 0xd5109fb4, 0x4c5f51da, 0x02721688,
- 0xda6541dc, 0x17e78e90, 0xf7a41484, 0xa8913a92, 0x29fe8eb6, 0x49e90861,
- 0xfa17ffff, 0x2683e04f, 0x6e5b7057, 0x7b96bd07, 0x0ed5bfe8, 0x70f39d7a,
- 0x85ed49fa, 0xe5ebfdb1, 0x0a0740a3, 0x83dfad4f, 0x4cfee3e5, 0x55fbd72c,
- 0xfc6fdbc4, 0xe0dcb083, 0x27f3e2f7, 0xdcb0a3fd, 0xfcb0d7e4, 0xcb0cbf9d,
- 0xdf1cbfa0, 0x859fe2db, 0x0fbf56e5, 0xafe33f9f, 0x5fceb2c0, 0xf79fcf8d,
- 0xbd658bdf, 0x5fcf803f, 0x32c3aff2, 0x72c5afe4, 0x96037fa7, 0xbe20fe0d,
- 0x0ebf8af7, 0x087f46cb, 0x37f1ef9f, 0x47f61962, 0xf40bdcb0, 0xdfc465a5,
- 0xff7ee58c, 0xfa0f2c51, 0x43bbf05b, 0x3e5893fe, 0x1eeef1c2, 0x8a248a47,
- 0x3c46b737, 0xea485c54, 0xa648ad64, 0x5672d4f5, 0x5023bf4f, 0xba7ad0a4,
- 0x1e29d68f, 0x148d2d7b, 0x57bd6959, 0xb9cf6b35, 0x68db149f, 0xdac0273d,
- 0x15a23dfb, 0x5fbd69db, 0xb81f6b2d, 0x449c5029, 0xac8303eb, 0x48faaafd,
- 0xafd683b1, 0xfcf6b10a, 0xd2712930, 0xd5847e7a, 0x25688e0b, 0x682f5a2e,
- 0x0fc2f566, 0x5a6e2503, 0xdf616c2f, 0x2913398f, 0x31f5a649, 0xc27daced,
- 0x43d13225, 0x808813eb, 0xd16762f5, 0x2f5a14c4, 0x697ab0f6, 0x1a92d9ef,
- 0xcaf6ff87, 0xe509732d, 0x4dc0ba85, 0xeb45949a, 0xe20acb4a, 0xcc0cf8a5,
- 0x26447ac2, 0x48fda0f3, 0x8d26b660, 0xac8575a6, 0x0efff684, 0xfdf6c62c,
- 0xeded8ab2, 0xbed81581, 0xddb1515f, 0xac7eeab2, 0x6c35941f, 0x20f55b4f,
- 0xd1507fbe, 0xaae07db0, 0x487eb147, 0xa8fb61f6, 0xf7c5bf55, 0x6c3e290f,
- 0x50757c7f, 0xffeb489b, 0x00b6f821, 0xbe08d75f, 0xfc07920a, 0xa72cca1a,
- 0x2046bafc, 0x1e3e40b3, 0xf2a6a606, 0xd14b26b0, 0xfdedbf40, 0x5169f0ba,
- 0x069dbce0, 0x3ccf05f5, 0xbcfd8b9c, 0xb4c8fd80, 0x7eebb11f, 0xca337c26,
- 0x6f84cfd0, 0x1a7ef42a, 0x7b1abde0, 0xfbd9faf7, 0x3c2318cd, 0xfbd62cdf,
- 0x5c7ec269, 0x84d79bdd, 0xf08ce3cb, 0xf7aa5e5c, 0x49fb0873, 0x113c1ee9,
- 0x9fa1a479, 0xef50bc88, 0x4fd84fe7, 0xa3c1eecf, 0xfd0da329, 0xbd22ca68,
- 0x4fd8a39f, 0x89faf756, 0xf08d6328, 0x7ef44b28, 0xfa7ec63e, 0x9a5e6f74,
- 0x1e11bc75, 0xcfdea56b, 0x6e7ba469, 0xefd9faf7, 0xbf67e232, 0xf39f8a2b,
- 0xee80cf08, 0x6dd8abcd, 0x3bb14fc4, 0xd84b9f8a, 0xebdd95cf, 0x88dbbf67,
- 0x28eefd9f, 0xe601647e, 0xf37ba435, 0xe2364e2a, 0x8a3938a7, 0xf000b71f,
- 0x3c1eed0c, 0xf11a7b07, 0x1467b073, 0xcf08193f, 0x33c1ee88, 0x9f88dd31,
- 0xfc51e989, 0xe8cf08a8, 0x3073f5ee, 0x839f88dd, 0x5cfc51e9, 0xef8cfd89,
- 0x6626bcde, 0x3133f118, 0x029f8a23, 0x57c8a7ec, 0xda10f087, 0x3f712b8f,
- 0xf118fa87, 0x144fa873, 0x9fb1633f, 0xbc9fb449, 0xcd29fbae, 0x34a7e231,
- 0x899f8a27, 0xbbebe788, 0x1ca1cfd7, 0xe50e7e23, 0x0533f144, 0xbdd299fb,
- 0x35f69579, 0x2fb4a7e2, 0xd2b5cfc3, 0xe8675c50, 0xe915e9da, 0x2ef5d727,
- 0xbefa04d2, 0xd17561e8, 0xf76025e3, 0x433dba88, 0xbe91359a, 0x294facef,
- 0xdac49878, 0x0277c535, 0xcad45c7e, 0x926bb58b, 0xec192547, 0xd52d14a8,
- 0xd651ef50, 0xcf7ef0cb, 0xf6867ef2, 0x1957598c, 0x057cb3da, 0xc5767a86,
- 0x7dfbc318, 0xf50d8baa, 0x60def7be, 0x70373f78, 0xb79ea1b3, 0xf78627ee,
- 0x31ced407, 0x61b15fb4, 0xcafda1b1, 0xfd4372e0, 0x377fbaea, 0xf4243fbc,
- 0x9afda180, 0xed0d87c6, 0x1b8f2343, 0x3f0ec3ea, 0x447f7869, 0xfb4316f3,
- 0x1bcfa3c8, 0xecb747da, 0x9ec7d434, 0x7f7863dc, 0x437efb7c, 0x6f8bdafd,
- 0x222fde1a, 0xdbda367f, 0xef0c0fb6, 0x6a7cf24f, 0xf32ebf68, 0xea9d9373,
- 0x9abf1cf4, 0x2b9045d7, 0x20497e82, 0x357b414b, 0xaeb052e2, 0x3f3272f4,
- 0x3d40b5c5, 0xd947f946, 0x434d573f, 0xd47fa4be, 0x55ea286e, 0x7d0b4571,
- 0xbe31d3fe, 0xf9f43c2b, 0x35df154f, 0x0df6389e, 0x648137e5, 0xa05aa942,
- 0x95afb734, 0x6717bf19, 0x31f81a5f, 0xd2cabefd, 0xd685303e, 0x2145897b,
- 0x04578f90, 0x49d5da0b, 0xf786a922, 0xfd04ac92, 0x85b9b5a6, 0xe462074f,
- 0x6a1f5d61, 0xfd1d0867, 0x997d93ae, 0xfaad4768, 0xce760028, 0x5e743e9a,
- 0x4d7908bd, 0xe81228f8, 0xb3efbf4f, 0xfb47d320, 0xcfd42ab3, 0xa15f1d88,
- 0xf1c60fe3, 0x870f2023, 0x9d11fc60, 0x1bf6b7c7, 0x96df1865, 0xdf186153,
- 0x3df1d0a6, 0xf55c3fd4, 0x129f1f19, 0x6f210c61, 0xf8e19f09, 0x1c0a9cd6,
- 0xfd42ad7f, 0x93f1d8ae, 0xc337e3a2, 0x344bdffc, 0x8c637eff, 0x6c59cff3,
- 0xe6c2bf9c, 0xb3aafeff, 0x9c24fc7c, 0x59c207ff, 0xc59cff36, 0xd656fe6c,
- 0x777c746f, 0x302dff14, 0xe304f1fe, 0x19c6f35b, 0xa977dfe7, 0x3656fe71,
- 0x5f55e9fe, 0x389df1f2, 0x97c2e7fe, 0x977dfe6c, 0xd58af8e2, 0x51fe05e7,
- 0x83aa93b2, 0x9bd27c74, 0x600cbe2a, 0x940e3a17, 0xd0a95283, 0xe84db210,
- 0x34fc7087, 0x57dbf189, 0x50df9449, 0x39f0059f, 0x59cd5209, 0xce46fd48,
- 0x8bea4beb, 0xd87bd014, 0xf9adfd4e, 0x8d79d41c, 0x5937f222, 0xa00e0d6f,
- 0x8a36b6f0, 0x5bcfa801, 0xfa083e3f, 0xee4acab5, 0x24ef872e, 0x9fe78112,
- 0x96c87afd, 0xcb9979d8, 0xf1f2b5f9, 0x8b791896, 0x64c581fa, 0x6f853550,
- 0x88c13012, 0xd427fa8e, 0xf8c7038f, 0x10f7ea43, 0x2a7cffea, 0x9bfef1b3,
- 0x6f507bfa, 0x3a1efea1, 0x7e1564ce, 0x377bbb47, 0xce5fc293, 0x6244ffe1,
- 0x1dc9faf2, 0xe5403042, 0x0d9fabf3, 0xeefaff45, 0xe9141d7b, 0x0ecc701d,
- 0xe9d430f4, 0xa74002bc, 0xe0d6ddf6, 0xabf10116, 0xa1a6be02, 0x77321268,
- 0x75c5365d, 0xdd7ffbc7, 0xe090e53b, 0xa256e426, 0xfdf419c9, 0x7d0a573b,
- 0x19dc743c, 0xad80b59a, 0x05b65a43, 0x5b649ae5, 0x73721146, 0xf69950c3,
- 0xf269a640, 0xe3312d27, 0xd6332f4e, 0xeb1b9467, 0x5b26b2ad, 0xd3ad5c28,
- 0xf699b204, 0xb196733b, 0xbfa71f5d, 0x99d19525, 0x714e578f, 0xcd1f4592,
- 0x1e00b284, 0xb3ce907b, 0x1d5bec3c, 0x32b9aa9e, 0x1f1fa089, 0xae8049e8,
- 0xef7c3481, 0x6f361e27, 0x64b3bc33, 0xe74e569b, 0x18b66b39, 0xc336fe04,
- 0x875efeff, 0xe5a7c966, 0x626427ba, 0x331f3ce9, 0xccf9b7fc, 0xb0c909f3,
- 0x615edfce, 0xe6f8ce7e, 0x27ffa738, 0x3cb41fc0, 0xe141fc01, 0xa3f9c63f,
- 0xfe32af43, 0xa6fab2a8, 0x6fb43f02, 0x95d20914, 0x9cadcbf3, 0x1ad7e65f,
- 0x9f1082f9, 0x385c740c, 0x3878284b, 0x72660f86, 0xc1b8583e, 0x927737c8,
- 0x87159c80, 0xdfadb72e, 0xdaa660fc, 0x711f7e79, 0x91fdb9be, 0xce9f887d,
- 0xba7464f3, 0xcee9d38b, 0xadfb636a, 0x7277ae9c, 0xf0daceba, 0x7d54ebd8,
- 0x41a89f90, 0xeabde419, 0x2d9e9d3e, 0x38fa7a06, 0xde70cd3d, 0xd779e9c5,
- 0xcd3d18cf, 0x7a70b6f0, 0x2f386cb6, 0xe19d7e93, 0xf777c335, 0x83e69dbd,
- 0x81d9ad71, 0x6aacf4f8, 0x2c715a2c, 0xe86579e6, 0x62c715fa, 0xdd496ce4,
- 0x517d4334, 0xfbc336f0, 0x36cc370b, 0x5dafcfb4, 0xbb9f6864, 0x7d431eee,
- 0x8667e076, 0x77beeff7, 0xcefda195, 0xed0c87ea, 0x663c57b7, 0xdbe6dfa8,
- 0xe67f7868, 0xf686cdac, 0x19cfe519, 0xed97a7da, 0x69a7d430, 0x0bef0dbb,
- 0x6df5177b, 0xf7d575c1, 0xef10199f, 0xf9159bfc, 0x74efacd4, 0xafcc78bd,
- 0xfee3f3e2, 0xf49e5841, 0x69f9f17b, 0x572c28ff, 0xeba6fe81, 0x2b376582,
- 0xdd9f1eab, 0x9742f817, 0x6f654f8b, 0xaed9e80e, 0xbefea1f4, 0xbfd1ef59,
- 0x8a7678ec, 0x48152e5e, 0x6d83ac39, 0x9fd74edc, 0x4ecc2ddb, 0x2c01e420,
- 0x6e4c2a97, 0x2accee97, 0x47a86e26, 0x133b5606, 0x02424bf7, 0x6d7e67ce,
- 0x85ce019e, 0xc136ae1b, 0x6af905b7, 0xe1987051, 0xb1ba92f9, 0xecceef86,
- 0x65be1113, 0x61a3e320, 0xdf7f2b39, 0x7233fa02, 0x10fa6720, 0x00fb5780,
- 0xd13d8deb, 0x2fe33b9e, 0x006c715b, 0xcb1cb9e0, 0x5859fe93, 0xb0fbf71e,
- 0xc0afe63c, 0x357f13f2, 0x7bfe2d96, 0x7f6ffcb1, 0xfd0fcb00, 0xdf7cb0eb,
- 0x51e58b5f, 0xdf2c06ff, 0x7cb107f3, 0xe5875fd7, 0x9610fe3b, 0x2c46fecd,
- 0x961afd5b, 0xf0c4bcba, 0x18acdf4b, 0x9ff5d17e, 0x724f1fae, 0xfc0d397e,
- 0xb62f8f12, 0x84e2f918, 0x617c8d5c, 0x3a6687d6, 0xf7dff598, 0x3f2987e5,
- 0xd0743f12, 0xef44db3b, 0x9de8aebc, 0x7bd0c629, 0xe0c3c58a, 0x05fef4e1,
- 0x5ec71bc0, 0xfb8b049f, 0x483b1888, 0xfac0b22b, 0x2fef9cb0, 0x3f5807d0,
- 0xa1aec7c7, 0xbda335dd, 0xfa041c14, 0xffa0dcf8, 0xf9f10819, 0x51294773,
- 0xcfcf1372, 0x7884bf4c, 0xabe8f180, 0x2e94820b, 0xdbb73a3d, 0xed5e1893,
- 0xe8465216, 0x80d0f17a, 0x0673bc67, 0xa9225d63, 0x3bd07df0, 0x5fa715cd,
- 0x7e02836a, 0x8d6bc2bb, 0xe87cabeb, 0xff93f8ef, 0x8a72842c, 0x49a1d985,
- 0x87b44407, 0x2f69e449, 0xefaa37e0, 0x884cdead, 0x500fb763, 0x931eb83c,
- 0x02fe2312, 0x3dfc06c5, 0x8cd47144, 0x266d59eb, 0x57ffafe2, 0x81bab303,
- 0x64f4aebf, 0x039cf857, 0xe017fef3, 0xd5fd2bb3, 0x9a22de95, 0x9d2352fa,
- 0x21dedb7f, 0x30ab0f05, 0x5be3b7ee, 0xc332b7df, 0x7c8ef813, 0xf3ae96dc,
- 0xa10e7371, 0xf2e59ce3, 0x8ae1ae72, 0xb44ba064, 0x29e82e9f, 0x3947d7fc,
- 0xe6cebfa0, 0x6b5bfb1a, 0x21592fee, 0x5c7435c2, 0x6490a297, 0xbe885642,
- 0x06fd115a, 0xfc004b6f, 0x6f0ebdf1, 0xd8fe0a8d, 0x54463fe9, 0xb7e8d9e8,
- 0xb4fc3b9f, 0xe59bfc1b, 0xb1f56299, 0xcbd47438, 0xb56e50ca, 0x680fd633,
- 0xd5cfd634, 0x9c21650a, 0xcb7c9a97, 0x3c075810, 0xd064c7d5, 0xea5899cb,
- 0x54cf2cfd, 0x7f4a1c70, 0x53ea47a6, 0xf69ccf50, 0x1fbdf0db, 0xfd448e1b,
- 0x40d1c074, 0x83dfa53e, 0x4bce5d88, 0x39427efc, 0x10282e90, 0xf961248f,
- 0xecdff02b, 0xfdcbbff4, 0xeb095fa0, 0x2155bf7a, 0x06bd6031, 0xc61bd79e,
- 0xfaa9dfa3, 0x977c2c1e, 0x7224de58, 0x4a77e75c, 0x7ef837b7, 0x7b3a92f1,
- 0x4c2ed1b5, 0x1aabd431, 0x760daab3, 0x0c03fc22, 0x02410ae1, 0x6729777b,
- 0xb9c936bf, 0x2b68f80e, 0xdf80fb04, 0xa55ef605, 0xa9f145ad, 0xc0cd2628,
- 0xe946739f, 0xfcceaf7c, 0x53a7ea80, 0xe404c96f, 0x50a25c8b, 0x47f47615,
- 0xa1625057, 0x36bcb9f5, 0x64c961a7, 0xbd4eaf58, 0xf5da2372, 0x1bb948f3,
- 0x520acdfc, 0xcff1085b, 0x0652c4b3, 0xbc967972, 0x23161ee3, 0x0545e787,
- 0xcebb99e1, 0x7f531768, 0xb85f50d9, 0x405f58c1, 0x7d874e6e, 0x65eb05f0,
- 0x5f401412, 0x153fdb18, 0x242d1c99, 0x7d606bd5, 0x75b32f5f, 0x48878e6c,
- 0x555f54d9, 0xe154fabe, 0x1fff5a6c, 0xf42dc591, 0xa945dd7d, 0x1c589fcc,
- 0xb468acda, 0x6186d3fd, 0x43cd52b7, 0x81ae0fbf, 0x4bb02af5, 0x3b536ef0,
- 0xc2bbefd3, 0x5f57866f, 0x2fed3bff, 0xeb2a3873, 0xc7182d04, 0x0249b00e,
- 0x580377f7, 0x863c960e, 0x5328c2b8, 0x53f37bfd, 0xd3f0311a, 0x4aa7d156,
- 0x80ff193d, 0xed48253f, 0xf487ef8a, 0xffa9d99f, 0xff6a3fc1, 0x85ff69bd,
- 0xfd47fe86, 0xeff7fda8, 0x6944ff04, 0x2bfee744, 0x95f17d5f, 0x8b27d500,
- 0x4ddaffb7, 0x4a78fae8, 0x52f74daa, 0xf6dd2efa, 0x7ce81ba0, 0x81b80a52,
- 0xc5054f5f, 0xf59c60b2, 0xe0493eea, 0x14e6a2f6, 0xff058e20, 0x7e9ffda4,
- 0xdfe817fe, 0xf64db57f, 0xceaa7c60, 0x3952b11a, 0x68b0d65c, 0xfac7c932,
- 0xf6beacc7, 0x8dea110b, 0xfc5bfe46, 0x21d3afec, 0x0a7282df, 0xd044d78f,
- 0xf5b65d9e, 0x975852b3, 0xca3b48aa, 0x183bf991, 0xea2a62ff, 0x724ad9bf,
- 0x270a76e7, 0x1c55ddfa, 0xbf0d552f, 0x437442f8, 0xd009fd79, 0x4043d417,
- 0x5dfcd8bf, 0x974fb705, 0xe3b4ae4a, 0x232714d4, 0x8bd048c9, 0x90485e3a,
- 0xabe2a7d9, 0x3c43e54f, 0xb7d6ccf2, 0xbe0c42dc, 0x173a7974, 0x7b9ffb9a,
- 0xb77ac4d4, 0xac5bca95, 0x5bafa41d, 0xabb7236a, 0x2a5cacc3, 0x1f90dc47,
- 0xecb374b3, 0x4bc7d00d, 0x99fa7c5f, 0xf83e2127, 0x0077ab37, 0x8bc97fed,
- 0x8637bfaf, 0x90ec97d6, 0x69b326d3, 0x0ef48538, 0xffd154fa, 0xa0e82dee,
- 0x5f97e2c7, 0xec21d457, 0x1da9fdf9, 0x63b25974, 0x7486429f, 0x684947c6,
- 0x8ce2d29f, 0xc7d09f43, 0x882760a5, 0x00ad7eaf, 0x15ed4ffd, 0x1c6e4648,
- 0x1d7e6e7c, 0x13c000ed, 0x2bd393d2, 0xfbd33f4a, 0xa02e9455, 0x32f4cdb7,
- 0xf40537bf, 0x2fd608cb, 0xfe502de4, 0xe40f697e, 0xf56fbd15, 0x5e2a1e02,
- 0xf986e15a, 0x19aa909c, 0x60f53f9f, 0xafc746ba, 0x1ee90390, 0x8af3d92c,
- 0xf21bfddf, 0xffb7c2df, 0x35e31d2d, 0xe0b2cb44, 0x82c8145a, 0x34dfce79,
- 0x80b9e703, 0x2b0f90f8, 0x41cb129e, 0x91297e1f, 0xe4711db2, 0x93973ce4,
- 0x71285b13, 0xd04f3ce9, 0x6df30665, 0xdb8311de, 0x87beded0, 0x37f83e80,
- 0x316a173e, 0x1b4bfd60, 0x921bd7a3, 0xab5197ee, 0xb77f9633, 0x3a066dae,
- 0x65a3ee9d, 0x15463ec0, 0x1f1c0291, 0xafda65c2, 0x0ca4f6f8, 0x4aa22746,
- 0xba3bfc85, 0x73c097ee, 0xd659bf78, 0xef86f9ec, 0x8edce5c8, 0xf1f257f1,
- 0xb049dc29, 0x8f489f5e, 0xb2aab76f, 0xbae807ae, 0x3167c31d, 0x7fe4cef2,
- 0xde4c43eb, 0x4e0ff975, 0x0bf6832b, 0x823932ef, 0xa43d60ef, 0xb0324570,
- 0x022ddf7d, 0x892b07ea, 0xadf393c4, 0x63739732, 0x285f99bb, 0x1c9092fc,
- 0x4e3037c3, 0xf701d22a, 0xa7ac1631, 0xd1e8c7df, 0xddd7182a, 0x8e5d5fb9,
- 0xd07d7217, 0x6407d26a, 0x8903d313, 0xae00aaed, 0xe0e54b7f, 0xfc824f33,
- 0xa80d7952, 0x3972bf20, 0xfaf3ffcc, 0x84fdef03, 0x21e7cdca, 0x7a8d6e5d,
- 0x15b72cd5, 0x7890473b, 0xd3b9fb72, 0x2dcae24b, 0x6e571e7d, 0xcfc82d9d,
- 0xaaf5afff, 0x990cc78e, 0x0eeaf1e2, 0x327aea3c, 0x7acd3e11, 0xc6a4a772,
- 0xeff493d5, 0x99d8525d, 0xd43e751f, 0x0bf16ff9, 0x1f417d95, 0xe754f945,
- 0xea9f28c3, 0x5e29d87c, 0xb9a3c06a, 0xefb0effd, 0xdb62fc01, 0x7518f538,
- 0x015e6d21, 0x338afee5, 0xb4afcc16, 0x5f70170d, 0x0906d064, 0x3c5b6feb,
- 0x9d4ec023, 0xcfd5f63a, 0xbbbe467f, 0xcb7df07f, 0x3f3e2957, 0x6ec84019,
- 0x5f046528, 0xc8e7a58a, 0xeab38330, 0x43f60908, 0xe589a0fd, 0xcff4fe31,
- 0xbdf76665, 0x61cee1fa, 0xb6a2c780, 0xa82dc9c1, 0x9fa20737, 0xc8f5c559,
- 0x0c9a80b9, 0x385cf5fa, 0x73c9fd0f, 0xbc574587, 0x38e7c6fc, 0xf8805f7d,
- 0xb6db2d19, 0xf2915a92, 0x47691b5d, 0xd5b022bb, 0xd9c5b646, 0x9990aadf,
- 0xf8a1fc9e, 0x3e03fa00, 0x94b7b39e, 0x73b1c796, 0xbbeb9dff, 0x81fffba9,
- 0xe155e6eb, 0xa7b016cd, 0x316adaae, 0xeb9605c4, 0x0a405d7c, 0xeea7af80,
- 0x0386bbb7, 0x5e8b0f1e, 0x0aad03c8, 0xe2f8a17f, 0xf9e68df8, 0x8f60ff43,
- 0x707b2b3d, 0xd0e4d7dc, 0x6bc3c05c, 0xf6046d67, 0xb52b76d3, 0xf9c1e24b,
- 0xb9c1852b, 0xcba318fb, 0xa297858f, 0x18a46736, 0x095b3de2, 0x3a676df2,
- 0x73f3e413, 0x2ab82475, 0xb22de817, 0x68353d7a, 0x9414fbe8, 0xef838e5f,
- 0x635ed12e, 0xc68af3e4, 0xf4082f1d, 0xc16165bd, 0xcbeda163, 0xf80516a4,
- 0x4531aaa5, 0x54367d04, 0x3d5bf3d5, 0xe1896e43, 0x096567bf, 0xcc6079e7,
- 0x5e03b76b, 0x08519fce, 0x076801e4, 0xf84f31db, 0xf218787c, 0xbd79a25b,
- 0x275327ec, 0x410fd0ca, 0x71d3363e, 0xa1927d70, 0xd7c4b63e, 0x6a9ae00b,
- 0x8de9596d, 0x1c01f783, 0x7c963fef, 0x5b765576, 0xe5d5df7e, 0xc79627d7,
- 0x9d57ddf0, 0x9e2337e5, 0xa55f2efc, 0x97bcc066, 0x0065e537, 0x21bf973e,
- 0x57c78cf7, 0xdf99fa2f, 0x03e79db8, 0xf95035b7, 0x7e4626bd, 0xc6fca81b,
- 0xfcb61389, 0x22fbf2c8, 0x7b3c6fc8, 0x9757cf8c, 0xc7f0fcdf, 0x0df9bf28,
- 0xca1e4316, 0xefaf9969, 0xe857e509, 0xd41a4b79, 0x8e23af65, 0x403c06be,
- 0xdf3b739c, 0x40718007, 0xbbe5558e, 0xfc7ff1c9, 0xf978e58b, 0x3379822e,
- 0xe4cde99d, 0x2a6ef978, 0x9dd002c7, 0x26f2f1c9, 0x9db9c72a, 0x275077e5,
- 0x2fdf65f9, 0xabefb08b, 0x7b7f731a, 0x40af1d07, 0xfa36bd93, 0x3c87417e,
- 0x6795888f, 0xcf204955, 0xcf27bb87, 0x533cb8bb, 0x8de7ed39, 0xd86f5743,
- 0xdaf61f98, 0x2ff513e8, 0x41fe5f03, 0x6de9ff44, 0xff73b30b, 0x70c4fa38,
- 0x00db8be0, 0x632fca1e, 0xfd5a1d39, 0x74bfec01, 0x9074c6cc, 0xb5839293,
- 0xec3c81bf, 0x0132adca, 0xe1acb87d, 0xcd53f463, 0xbedd1771, 0x745fc732,
- 0xc38e623d, 0xbd33a92c, 0x9dbe30a7, 0xbc20b626, 0x77a24fe4, 0xd3be1c5b,
- 0xe704ebdf, 0x9cf7dae1, 0xece03bc3, 0xcfa42e2a, 0xf4b82ba3, 0x7c2b9579,
- 0x864a1bbd, 0xe291bc41, 0xf025e511, 0xaa7188a6, 0x8601a2f2, 0x72b70cf3,
- 0x16d58738, 0x62d84095, 0x80ebe41a, 0x9ee1b55f, 0x368fb043, 0x005aa8e2,
- 0x31d8f566, 0x57f81f56, 0x51dbd9cf, 0x3cba759e, 0x3964f9c4, 0x5eb5e7ef,
- 0x6fc0c5d5, 0x07828d55, 0xc8aa9dd6, 0xc6dcf03f, 0x955f8d81, 0x6a2d1f02,
- 0xe4563c12, 0xf0142fc3, 0xfae94afb, 0x2c34fc0b, 0xbfda05fc, 0x448a9a8b,
- 0x6ed17ef8, 0xbbe41301, 0xe9774fc2, 0xf7c396b6, 0x04efc022, 0xbad9db38,
- 0xdbd3e1c6, 0x0180a4ab, 0x2f2792fe, 0x7066c9ae, 0x03b556ab, 0x785111de,
- 0xaf388b67, 0xe3abc26e, 0x1f782bbd, 0xe3deb852, 0xb8d3fc74, 0x222f18f3,
- 0xf96e94e1, 0x6e35df37, 0xd19a4555, 0x57e3d35f, 0x2adf455b, 0x6588e219,
- 0xf38c6482, 0xfbfc63b6, 0x7fffe847, 0xf07fadbe, 0xdd74222f, 0xd3fd7dfa,
- 0xcfb3ef88, 0xe8153c7f, 0x9135e4b2, 0x5a5d28d8, 0x82245deb, 0x054124fb,
- 0x41b8b0e8, 0x240e30d4, 0xbba70a45, 0xc351f162, 0x85ddb1f0, 0x4ef1707a,
- 0xfd32706b, 0x9f2bf17e, 0xd33d83e6, 0xa1fb40fa, 0x3c03886c, 0x931ca02f,
- 0xec3e4b40, 0xd8962d13, 0xbf198dbe, 0x87c58511, 0xcc76eccf, 0xea107902,
- 0xc5a9b9d8, 0x35b299a1, 0x557e1ec6, 0x641c5991, 0x15af3b37, 0xbcc04e78,
- 0xf62f8031, 0x8f9e8edc, 0xe639e673, 0x946e2c97, 0x6afe7083, 0x568edd71,
- 0x3e2c9b88, 0xad75c56a, 0x8c0beeaa, 0x7f6c96fb, 0x6aef9d91, 0x72fe0d14,
- 0x4eb53f27, 0xbfc1588c, 0x38c4a86a, 0x8c7fad3c, 0x0bf710f5, 0xb51fa3bf,
- 0x2bd37b64, 0x25c28a01, 0xc6eb3f2f, 0xdbcd5873, 0xd6afe8dc, 0xa8dc7b7d,
- 0x7a1a5f93, 0x53a5fb88, 0x97df804e, 0xcd3d2fc8, 0x62b4e4f9, 0x7aebeff2,
- 0xe14abfa0, 0x638f2c2c, 0xfff947b7, 0x077f2fc5, 0x3b33d571, 0xc01dff3f,
- 0xf39bf4bd, 0xe28fbbbf, 0x7bb5ec93, 0x3d560f40, 0x438c17ff, 0x5649dfe9,
- 0x7b9fafae, 0xad78e316, 0xa17ab37f, 0x13a6d6b7, 0x6ac71039, 0x748ff1dd,
- 0x365653b0, 0x6bbb424d, 0x0c92aee5, 0xd04ec712, 0x60dfe04b, 0x6688e237,
- 0x38681dba, 0x9e700390, 0x748774a5, 0x21bc68be, 0x38e2c954, 0xd4338f2a,
- 0x76db8fc7, 0x4c342b8a, 0x70fc69bf, 0x4aaf6528, 0x785f11ba, 0x9af3d297,
- 0x9eb1d06e, 0x534291c7, 0x70be35be, 0xe941fe16, 0xc6356795, 0x986cbe17,
- 0x424f9fff, 0x848f435b, 0x374885f1, 0x85c7a7f0, 0xdf2d14db, 0xf3b9720a,
- 0x00eb8c05, 0x09d326fd, 0x65f8beb7, 0x4fd5c40e, 0x6177edca, 0x15935bbe,
- 0x3717d7f7, 0xa9e515fd, 0x68dbd775, 0x9f1e127f, 0x3fd1256d, 0xb9e34716,
- 0x5d5b55aa, 0xe9c12e2c, 0xd50b7100, 0x7c79cf8d, 0x1eb5f182, 0xaf1448b7,
- 0xc7ed6058, 0x5c594ef3, 0x07eb72a5, 0x83c5310a, 0xeb1d5184, 0xe97a227e,
- 0x1e00f078, 0xe3c6c646, 0xa287c7e2, 0xdd1338f1, 0x87109e80, 0x68dbc68b,
- 0x5dc437bd, 0xe35fc282, 0x375b77c5, 0xab5e38b3, 0xe95bcc6c, 0xcf8b13a0,
- 0x5bd136cd, 0xeb576f9f, 0xf8f35756, 0x069a78ae, 0xcecf768b, 0x29733af8,
- 0x6d5f7ebe, 0x3ed87e15, 0xbcc13ceb, 0x7c0353ef, 0xb1f0d959, 0xfa8d7902,
- 0xf7cfa6fa, 0xcfcfb70c, 0x5e622f3c, 0x01d09aee, 0xfd66efd4, 0x61ce0cb1,
- 0x37f781c4, 0x8d65de1c, 0xb338fd6c, 0xd27415d3, 0xdfecce7e, 0xacbd7c8d,
- 0x402563fe, 0xf7543bfb, 0x49fcc2b2, 0x7eb04726, 0x3fe06304, 0x7cbed2f3,
- 0xfe647f16, 0xad9c7980, 0x85563f5c, 0x55538fe3, 0x9c6185ff, 0xc2908125,
- 0x7dbfacf2, 0x3692d3bc, 0xdd3bfa13, 0xb3c8132c, 0xcb121d3c, 0xae6bede2,
- 0x5f7ccab5, 0xb9c596b3, 0xe78a3ae9, 0x9cec5c5e, 0x60aa988b, 0x6ba5641c,
- 0x5f3851d4, 0xa8a5d2b9, 0xacd51fe0, 0x35bcfb62, 0x0266f73f, 0x6e526bbd,
- 0xad6d78c5, 0x349ebf09, 0x7f9c114f, 0x1f2c4cf1, 0xd66aec0e, 0xc59a293b,
- 0x574aff00, 0xe14a8659, 0x81fb4d5c, 0xf244a8f3, 0xd11c39e2, 0xf3065a5d,
- 0x8f163d11, 0x4c7c4e3d, 0x5f139676, 0x8f645e0c, 0xb90cdcf1, 0x7e854c34,
- 0xa5d9fdf4, 0xd843e6b6, 0xe004d1e8, 0xc7ef892b, 0xc1e2dd17, 0x0bd5b779,
- 0xaa71605e, 0x3a4f559e, 0x758033cb, 0x72676da4, 0x3f06b93e, 0x5f5d1a24,
- 0x50b9fc1c, 0xe81f6fbf, 0xa26ed5a5, 0xa33950a5, 0x3cc55558, 0xd4343f38,
- 0x9f01e426, 0xd7c7f17e, 0xb0f6bf68, 0xa0352048, 0x19e7a9cd, 0x67202969,
- 0xe608f20e, 0x5f2b0093, 0xa701d1ee, 0xc084cf39, 0x97e7312b, 0x8c4e8927,
- 0x24db9c7f, 0x922b9fa2, 0x8e3b7eab, 0x0824edf9, 0x65f5f3f0, 0x1cf38709,
- 0xf0231175, 0xe30bbd7e, 0x98df0bf3, 0x7403f28b, 0x8f57c588, 0xb91fa332,
- 0x87ceeec1, 0x768d9dfd, 0x492816f7, 0xbc866b40, 0xdfbc79e6, 0x73c6e59e,
- 0x030c5448, 0xe7ce7f60, 0x82f9faf2, 0xaf98c3d2, 0x7a805be0, 0xf196633e,
- 0xbed9929c, 0x1fb50897, 0x0a0d7d61, 0xb38908de, 0x19b8dfaf, 0xdecaeee1,
- 0xb0e8f1d7, 0x3909bd51, 0x04e24e42, 0x97d6263c, 0x65b7e05d, 0x0dc76fe0,
- 0xb5f8eeff, 0x6bf11a66, 0x75f88d57, 0xcfe3320c, 0xd7975f88, 0xe6ca2f88,
- 0x6fc36fc1, 0xb9e328f2, 0x7e157faf, 0x1db8d987, 0xff4af1c9, 0x4ce96dca,
- 0x59dc0365, 0xc2e50452, 0xced9472c, 0xeeff0088, 0x855c1693, 0xe85d795f,
- 0xf9f264af, 0x77d8f308, 0x1123900e, 0x1ca2f5e0, 0xd00bc9c1, 0xa1f20ef3,
- 0x2169e807, 0x57cb929f, 0x8ae7a627, 0x9e3f0769, 0x04dabf43, 0xf20d7bfc,
- 0x955f3b03, 0xb935824a, 0x0f5ea720, 0xbf21dfac, 0x864f3bcd, 0x3bc4f673,
- 0xaf9c006f, 0x68f960f7, 0x6dbf7b01, 0x1a73c130, 0x7485c8a1, 0xf3554fd0,
- 0xbfe83949, 0xa9f69547, 0x6cbef7e0, 0x1bbdf167, 0xd3ea0aec, 0xae16eda7,
- 0x71be2757, 0xb6c7952d, 0xf9c2acb0, 0x36f0b6c0, 0x37a800db, 0xbd6e788a,
- 0x4af6a52a, 0x2c35bf18, 0xd9e6b833, 0xbfc00382, 0x3d71926f, 0x0e379d68,
- 0xed44c1cf, 0x4fdb30b7, 0xea7f0b6c, 0xcfa31b9e, 0xb89f1b5b, 0x1b0fe212,
- 0x31f7f12d, 0xdf2cd857, 0xae8d7fcb, 0xf29d0dbf, 0x58d8562e, 0xfda3c75e,
- 0x4d963ce8, 0x61d7c73b, 0x39630f26, 0xb82e0f9d, 0x2bbfe701, 0x3a7cfd4c,
- 0x8ef1528f, 0x79d0871b, 0xc48bfe8e, 0x26d12bf4, 0x47674ecf, 0x1afde080,
- 0x5fa82fd0, 0x0e2cff6b, 0x44a0b887, 0xf0c45ce0, 0x6fe805ea, 0x7ca6e6bd,
- 0x50a2f94e, 0xbe030d0b, 0xc14e189d, 0x3eaa0a7b, 0x8fd76824, 0xfc0c9668,
- 0xd5d7c859, 0x9f1616c2, 0xd8d4791f, 0x3245ba3e, 0x8c4141d9, 0x693d8f1f,
- 0xf3ab5e7c, 0x03a49bb9, 0x24bfaf9f, 0xd517900a, 0x0fbc4ed6, 0xe6dbb850,
- 0xda3842f5, 0x2b29c02e, 0xcb125e5a, 0x9bf7ade2, 0x6b0f2c6d, 0x9d7042a3,
- 0x89c0b8d9, 0x17fb08fb, 0xeb3cc62c, 0xebe67eaf, 0x5edcef1b, 0x664a7e8c,
- 0x325af5fb, 0xbdfc0519, 0xaf78605a, 0xb7dd8acd, 0x9f9d4bd2, 0xf9d6fe75,
- 0x92416b3a, 0xcbde5e2f, 0x7bb33b60, 0x120c178a, 0xf6d7f014, 0xa9fc780a,
- 0x219f01f5, 0x065cdb7f, 0x00d903c8, 0x79e3554f, 0xe16dbbb4, 0xfb5479f8,
- 0x0fe66e6d, 0x0558103e, 0xa53f1e79, 0x327a09c2, 0xd1ebbf71, 0xa083aadf,
- 0xab677c2a, 0xa6e78d9d, 0x16c8dbe6, 0xb54ad388, 0x80bb3759, 0x5fae4bff,
- 0xb27de143, 0xebeb82dc, 0xf08bd946, 0xc1092a07, 0xa73f03f8, 0xd92a7bd5,
- 0xec7e7b1c, 0xa8e8ad88, 0xa8f7ce8d, 0xeef383cd, 0x000af3e1, 0xffebf7bf,
- 0xa6bb06e3, 0xe915a2ed, 0x43fb8bd8, 0x6de777fa, 0xd80f4f0c, 0x7be077b5,
- 0x72869152, 0xbdb9f5e2, 0x39c186f3, 0x18f78a55, 0x5fa0ea39, 0xea91e700,
- 0xc28e3aa3, 0x20b4ea93, 0x534d125f, 0x031e7a3d, 0xc8c5efe1, 0x04088905,
- 0xbd741cf2, 0x8885842a, 0x70c1ca8b, 0x7e02339b, 0x9d056a47, 0x4ec10537,
- 0x66bfac6c, 0x1cf44ce9, 0x5251e61c, 0xe4842cbe, 0x12798279, 0xfd05a890,
- 0xd756faeb, 0x0853abd3, 0xc7eacbca, 0xed0d60a4, 0x62d49367, 0xae4af887,
- 0x56c316a6, 0xe2a4aa74, 0x153ebcf9, 0x1c73f304, 0x44a54f79, 0xf42a16ed,
- 0xef11bf43, 0x1fe7178e, 0xe5f1d76a, 0x2be027fb, 0x7efb70ff, 0x76bc6f30,
- 0x75f79e36, 0x51e9da1b, 0xb1edc1fd, 0x8efebe52, 0x2bed8cfe, 0x24b5c893,
- 0xd66f8e36, 0x327dba1f, 0x03cb7c7a, 0x6feef80e, 0xadda4e0c, 0xe08ddf06,
- 0x13ea8df3, 0x0c8e6ebe, 0xbf427d53, 0x3b0f082f, 0x82eef100, 0x771c990f,
- 0x038727d2, 0xfbefe022, 0x5f3311ea, 0xb9508d0c, 0x5583ede4, 0x89ecbf38,
- 0xafbda1d6, 0xd277a8dd, 0x40cf0da6, 0x9bf3973b, 0x7cbacf19, 0xe0bee59b,
- 0x2b01ef5e, 0x60910b83, 0x1d08871e, 0xa079a870, 0x60888e97, 0x5115b7ef,
- 0x0eb8503c, 0xb94bf972, 0xe61ebc10, 0x9d7c3ebf, 0x7be4e41d, 0xfa1127af,
- 0xf27c4c75, 0xde37d171, 0xdcf8f2ce, 0xfb658780, 0x24f5f02e, 0xca8ef482,
- 0xd8939501, 0xffce8978, 0xe5d77e66, 0x3a0e06a3, 0x0bf9e1e7, 0x28aceb02,
- 0xbdf0f084, 0x00f26c95, 0xbb7b755e, 0x24b7db86, 0xdff68590, 0xebe10f4a,
- 0xf8104e51, 0xedd646a4, 0x362daf75, 0x55d2b53e, 0xfb6df19c, 0xa9175535,
- 0x8793167f, 0xa3b5255d, 0x517556ff, 0x1bdfe7c1, 0x450a617f, 0xf37f01ba,
- 0xe33b3ded, 0x57c83c6f, 0xe62fffcf, 0xbf3ccab7, 0xfcc76ab5, 0x6bdf12c6,
- 0x147f542d, 0xe35758ae, 0x7793f150, 0xeb3b0b33, 0x657cfd05, 0x96603d22,
- 0x6b4b91f7, 0xb498600f, 0x72af790b, 0x3212fc70, 0x98d9f41d, 0x725bb508,
- 0x05ffcb3b, 0x072abf3e, 0xaddb7bc3, 0x9e4103ed, 0xdfbe8856, 0x16a811d9,
- 0x8aec058b, 0x1eed04dd, 0x6e63beef, 0x1ee6f794, 0xb3a7f586, 0xf660105d,
- 0xf4475f26, 0x48d0a7b8, 0x738e80e5, 0x0e7beec4, 0x30f1affa, 0x340e14bf,
- 0x623a7e81, 0x5e03d5f3, 0x24c6141d, 0x28324f38, 0x28e2cb92, 0x25dc8311,
- 0x49873392, 0xde74428e, 0xe805aeb0, 0x484036ba, 0x7b02cf0c, 0xd502230a,
- 0xf4b7602e, 0xb06c242e, 0x06f30465, 0x7bb3e77b, 0xb0177a00, 0xb4dec77b,
- 0x5bc938b3, 0xcbd11d7c, 0x03f2b623, 0x912cbf00, 0xfbe0b580, 0x42a00dc3,
- 0x5d88f17c, 0xb27807db, 0x8f386995, 0x0af10f6c, 0x52d98e94, 0xad7d8048,
- 0xc0aaa5d4, 0xad848ae2, 0xfed25043, 0x45ab27b2, 0xfeecf740, 0x6509cf04,
- 0x4713fd83, 0xe5d98e6e, 0x6b07161f, 0x1f8764ec, 0x487172e3, 0x31edf3a1,
- 0x473fe599, 0x7c1439e3, 0xebab6fc0, 0xeb6c9c56, 0x225f2c97, 0x6cf0c290,
- 0x6080cbf6, 0xd7892f30, 0x6488541f, 0x29bf454f, 0xb0197c00, 0x726fd0d8,
- 0xef086f10, 0xc7ea4949, 0xbc1145ee, 0x2bfea0eb, 0xf706dda9, 0xa0f2e825,
- 0xe3a3f9f3, 0xf44af66e, 0x73f8f755, 0x52d3e0f9, 0xe027ff7e, 0xb9dc75b9,
- 0x2671ab81, 0xef8c39ed, 0x6790d134, 0x51afd3a9, 0x0ecfd036, 0xfd5892f1,
- 0x810652ed, 0x242ade3d, 0x6a5fc179, 0x7830245d, 0x43cf1b05, 0xccf30c95,
- 0xa33f3074, 0xfec5eb8d, 0x0f38b949, 0xf3a09d7d, 0x5d71875b, 0xe7a23cd3,
- 0x8ce74c8e, 0x3290e7cc, 0x9df1a2f3, 0x2b07cc2c, 0x184ee057, 0x40ec2e72,
- 0xddcaacfb, 0x9ce2439e, 0xb168c993, 0xa6073dc7, 0xfd6f1497, 0x5e427a92,
- 0xe80a7561, 0x993b8cd9, 0xa3e3307e, 0x3d0c084d, 0x7f63fb04, 0xa3eee390,
- 0xe66665eb, 0xe8f3298d, 0xd75999fb, 0xdf3fa963, 0xc6e294e0, 0x0925c70b,
- 0x0c8fcc3f, 0x18df3cb2, 0xf3071dfe, 0xe77beb39, 0xbfc50d3d, 0x1be9e31d,
- 0x37de1892, 0x6fbc3124, 0xaa7c7450, 0x1d7f20c9, 0x5f21af75, 0x96dfbd62,
- 0x509e4122, 0x73e50b20, 0xbbd187be, 0xed0d7de3, 0xbb449e96, 0x125036fe,
- 0x0db265eb, 0x7dc59ef9, 0xdfe0bcf4, 0x994b9ff8, 0xdba7ed48, 0x8d505f38,
- 0xc29be8c0, 0x7eb0bee0, 0x4e9b8e12, 0x1481da2d, 0x2dca0bcf, 0x9d07885e,
- 0x1bbef39d, 0xc9cdc88e, 0x78242e6e, 0x0d7ab5f4, 0x157f73f8, 0xd125b77d,
- 0x5036d27e, 0xf183d545, 0xa525c805, 0x8fb8f5d3, 0x3712db39, 0xc497cfef,
- 0x925776fc, 0xccc8e107, 0xea748a9c, 0x014e4fa8, 0xa7ccc37f, 0xe6b35e54,
- 0xb738ef0d, 0x1166f946, 0x6f2cd9e0, 0x1469326d, 0x208add70, 0x7674d2be,
- 0x975b7ae6, 0x43903497, 0xa72a8fd8, 0x73a7547a, 0x3a6afe3f, 0x4ff13bc6,
- 0x1ffeff08, 0xc7b847e0, 0xd45ea317, 0x620c88e5, 0x7a0ede7a, 0xd9ce2637,
- 0x3ed7f4d6, 0xd1f89fb0, 0x60bbcfcf, 0x52efe93f, 0xecf40bbb, 0xecfffbc9,
- 0x8f863c82, 0x8ef167ee, 0xd7fe4cbb, 0xff4c4923, 0x5e54947f, 0xdbbaf303,
- 0x2fa175ff, 0xbdc95f86, 0x51645f6c, 0x6f9d3450, 0xae379e34, 0x17cf990c,
- 0x95df1007, 0xfd78fc52, 0xe71624fe, 0x59bf5459, 0x7c6156c9, 0xae81afdf,
- 0x797fb927, 0x03dd81b2, 0xa733c3a2, 0x3e02a87e, 0x56c3dfd7, 0x2cdeafbe,
- 0x9b43f5b3, 0x3e62fb0c, 0x9c33378e, 0xa4fdf887, 0xa22d7ff3, 0x8e9b33df,
- 0xc3d52f75, 0xf3cb30be, 0xfe63cf35, 0x9c296a47, 0x90ff9fe7, 0xbc34fe80,
- 0xcf5d3f7f, 0xc5aef77c, 0x3cf333fd, 0xa08fdf3b, 0x90b5dfa1, 0xce7cdbd3,
- 0xed98616a, 0x3e23cf6f, 0xf94ecf94, 0x0f966118, 0x9e238e6d, 0x00e79c3b,
- 0xf126343c, 0x3242ab7d, 0x762ef212, 0xfc97ee1e, 0x675ef96d, 0xd3f2b9f8,
- 0xa4f44f3c, 0x9359609f, 0xdbf3b2a4, 0x814bb7e1, 0xee3596bf, 0xbe657bc0,
- 0x0caa3eab, 0x84ff729f, 0x6a25e874, 0xe811fe5f, 0xc1827c48, 0xf9b65cee,
- 0x65fcc2bc, 0xf83b9f86, 0x1f003bf3, 0xeececfb8, 0xa963b90f, 0xdef6217c,
- 0x8c92f799, 0xa267ebfb, 0x3cd9e4e7, 0x93bef92a, 0x5f333f3e, 0x9b3e70d7,
- 0x9ada75b7, 0x35ca745e, 0xf872274d, 0xfbcc0779, 0x2166f9d6, 0x8acd2f29,
- 0xbd3a1fc3, 0xfe107ca2, 0xd3abc225, 0x6ced5e69, 0x2640af3e, 0x84cbf7df,
- 0x2f9992b8, 0xd76f3aba, 0x80e4b72a, 0xdee99abc, 0xfb3ce09a, 0x3ed893df,
- 0x2b553ced, 0x9f38bd05, 0xc4f1af94, 0xa5272bd8, 0x81f743da, 0x7c656d1c,
- 0xe06bd51c, 0x7ebe82bc, 0x7cf5c64b, 0x80cd4bb9, 0x1e90917b, 0x87615e70,
- 0xe9ef0035, 0x6bf71ce3, 0xf0197f5a, 0x69e5865d, 0x7fd6b97f, 0x82fb4740,
- 0x10dde78d, 0x441b6dc7, 0xead3be30, 0x71ebc232, 0xc78f0888, 0xa5bbd6c1,
- 0x1f37f352, 0xdada0e80, 0xc711f98c, 0xd0f8f12f, 0xbc596b25, 0x10ed5e79,
- 0xdd05f70c, 0xf74ae5c5, 0xf4e6ee3f, 0xf6cc2bbb, 0x9a6ce7bd, 0xdf30f486,
- 0xfb847267, 0x041bb32d, 0xfa6623d4, 0x775ef7cc, 0xdcedf40a, 0xdf7e1160,
- 0x11e45e89, 0x6e99bba4, 0x761e1deb, 0xad548dbf, 0xc73f7dc0, 0x4fb80937,
- 0xde8124b8, 0x8f0777fb, 0x3e737767, 0x822479e6, 0x55d6e17f, 0x98117a6b,
- 0xf80550ff, 0x3ebf0cdc, 0x6344f9ff, 0x37cf877a, 0xcb48bcd1, 0x829f2cb5,
- 0xc28be3af, 0x65a97eec, 0xaf2c888f, 0x748bc793, 0xcd7875f8, 0x971528f3,
- 0xdb6f3e62, 0x09f31106, 0xd7040aef, 0x77cbbdc0, 0x3d7016ad, 0x5d27444d,
- 0x32fbe84f, 0x63671acb, 0xf68f957e, 0xdb697603, 0xd9170487, 0xde0275b6,
- 0x9e90937f, 0x94579661, 0x30849e88, 0x74a3cdba, 0x7e6e387b, 0x3fd6915c,
- 0x78273f76, 0x763fd6bd, 0x3084897f, 0xdd4964af, 0x4af3c334, 0x774f5187,
- 0x3aa47f25, 0x2e9cde7e, 0xe9fcba6f, 0x9c1eb8f2, 0xa51fb073, 0x5ceca1e0,
- 0xe863cfc0, 0xfbfd50af, 0xff8b0773, 0x7d1b7a3c, 0xf3c6d965, 0xf984fd86,
- 0xe6bd18a3, 0x79f1938b, 0xe28375a2, 0xd787a0c1, 0xf87a8c3a, 0x9f47ce87,
- 0xfa272e87, 0x6272ccfc, 0x0f4cdefe, 0xa6670e3d, 0x001e998b, 0x470df827,
- 0x07c11c9a, 0x04479c28, 0xc9a07706, 0x66b7708e, 0xfe706896, 0xedd65966,
- 0x0f811e58, 0x57bd8347, 0xed038cfe, 0x7957ee56, 0x4503e7e3, 0xf76e25ed,
- 0x41961988, 0x93111e30, 0x2ec790bc, 0x77aa5b66, 0x7d8a79d2, 0xd2183969,
- 0x9c22bd99, 0x992daee7, 0x143dc220, 0x77bcfc35, 0x379d858d, 0xc3dbfbd3,
- 0xed97a0f1, 0x8046f28e, 0x9a9fece7, 0xfe2c1d0b, 0xce0afe8c, 0x143dee13,
- 0x760dbfa8, 0xf304ebf0, 0xc8d20b69, 0x83b7a001, 0xee40a368, 0x72a4743f,
- 0xffed9c3b, 0x286cbfd1, 0xcbcb56bd, 0x3f9097aa, 0x49b3e2fc, 0x37b25f70,
- 0x9722b2d9, 0x38e2ffd6, 0xb9ee093d, 0xce5b66f3, 0xfda87ae7, 0xd59cf8ed,
- 0xef9cb6af, 0x737feb47, 0xd875619c, 0xf87b82a8, 0x0527671c, 0x1e38c306,
- 0xb5eae7a6, 0x243e41ab, 0xa597f30b, 0xc3c60afd, 0xd5fdfdf5, 0x17e0e694,
- 0x79f9c87f, 0x17e2aacd, 0x2c67101c, 0x6fd854d6, 0x71be0ade, 0xea5fefcf,
- 0x161d1578, 0x4a0367bc, 0x1ca7ffc0, 0x485d3a9f, 0xe4357683, 0x7690923d,
- 0xb483ec35, 0x1dc77c3b, 0x91d87db4, 0x572009e6, 0x5fbcef0d, 0xf68df788,
- 0xa30cfd65, 0xf3a6e20c, 0x9f6afb39, 0x8afbb1cd, 0xcfa28eed, 0x0c943e81,
- 0xaa084768, 0xed41dc87, 0xa88d1a86, 0x31f81e4a, 0x81bdbb46, 0x49d7d9f3,
- 0xcf91e7e5, 0x9f50477a, 0x7df0e53c, 0xfd9be305, 0xda9cd211, 0xf253fe2d,
- 0x7af8c5ef, 0xd1e3766a, 0xff9f2039, 0x0afdcec5, 0x7af9869a, 0x9ef7a3db,
- 0x1df7f410, 0x710bc924, 0x9925e236, 0xb71e7481, 0x4abe30b0, 0x4bf18c2b,
- 0xf7e87cf8, 0x951ee113, 0x1fb60e91, 0x8227e74c, 0xa894369f, 0xf8830e58,
- 0x9ab01e43, 0x487beb0f, 0xb47de8e8, 0xccedc7ff, 0x11d5b7ef, 0x84675c43,
- 0x7707d993, 0x275c58b9, 0x0cdd0e49, 0x0be93dfa, 0xdefd01e2, 0xe12294f6,
- 0xb9e4a67e, 0x0e39f711, 0xf82e3059, 0x40f41cac, 0x4afdbd7c, 0x3a42dd49,
- 0x74e36bfa, 0x5c7dfbd7, 0x7884af51, 0xb3175cca, 0x222d9e27, 0x7edaf798,
- 0xfec2094a, 0xadb66a57, 0xcf4fd63a, 0x4faddfe7, 0xa4e41e2e, 0x8929a865,
- 0xf723f8c0, 0xd2928352, 0x02fa85e3, 0x76c5f03b, 0x43c511c0, 0x0f73d5aa,
- 0x9e7a97f4, 0xcf8b9bc2, 0xa4afc435, 0xf8a64d0e, 0x5383731d, 0x9e297b85,
- 0xc06e87b5, 0x2d17bf3c, 0x76d3ff78, 0xea0d3bc5, 0x1ea9cfdb, 0x9b3d0788,
- 0xf9c24a1b, 0xf9c168bc, 0xbf6a4f6c, 0xfb85396a, 0x8e2c41e1, 0x64883920,
- 0x2a79054b, 0xcfa1ef56, 0x7d993bc7, 0xe4c2dabb, 0x62a9daa9, 0x8e8171fd,
- 0x15ef005f, 0xf9e91ca1, 0xeced6d17, 0x5bcf471c, 0xe7e0459a, 0x3fba69a4,
- 0x0fc1111f, 0x704e571f, 0x94e71d5d, 0xad3a2a83, 0x2176739a, 0xd6ceffdc,
- 0x2e1f098d, 0x29f2cc9d, 0xefc2efbd, 0xf2701c21, 0xbef836fb, 0x4f9cb5d0,
- 0xd11693c6, 0x5fc7db46, 0x2e48de24, 0x8c6af7dc, 0x5a633edf, 0xfef127e7,
- 0x44cf76b5, 0x8c445c78, 0x0da4f0eb, 0xae20a7a5, 0x09344c5c, 0x66c4a9f8,
- 0xdcf5876a, 0x9ac4f70d, 0xf273c9ee, 0xe4872b75, 0xe8fde6c4, 0xe249fb71,
- 0x47688de0, 0xc05e2994, 0xf6a70ecb, 0x0d4fd857, 0xdbf2f750, 0xf8cf3de2,
- 0xa0d67e59, 0x57020e8b, 0x74fe50ff, 0xdaae7cc2, 0xd3b01b50, 0x9fd55f79,
- 0x087c0ff5, 0xa78ae5fa, 0xbe807ad2, 0xe97a7377, 0xc077cea5, 0xc6649e5f,
- 0x3a6b9e5f, 0x273ef3e4, 0xf2e89b8b, 0xfd077c06, 0xb78391ec, 0xa41fdbc7,
- 0xf01f7afc, 0x41270eeb, 0x5917fa7b, 0x672059b6, 0x9dfb38fa, 0xe5cdff8c,
- 0xf7cb559a, 0x0412efc1, 0xc6eb64be, 0x31175ec4, 0x6eba2e4f, 0xab783327,
- 0x53e9dad4, 0x29c76f21, 0x3a4e5e63, 0xcb16373f, 0xfc31592f, 0xab5df3a2,
- 0x3adff993, 0xfeec94ff, 0x284b9e33, 0x06fa92f9, 0x376a24b9, 0x2133fcea,
- 0xb37dc110, 0x89d98409, 0x99d9fe66, 0x2e8a7f80, 0xade812a8, 0x9873fc4e,
- 0xbe224ff1, 0xb048fda1, 0xe7f99a0e, 0xe3b72719, 0x25cff212, 0x6569e037,
- 0xeeb7c953, 0x8dfa34ef, 0x72e67cf9, 0xbe7e23b4, 0xef1c67e7, 0x1bda95bb,
- 0x4c6f41f3, 0x2f4178b1, 0xbec8ee50, 0x3bbbc299, 0xb5d7bf49, 0x3bea0f3a,
- 0x7687a624, 0x87a8ad84, 0x3e7d3876, 0xb2658b8c, 0xf24474f3, 0xb6fe40b5,
- 0x8d4d97b7, 0x7efb27bd, 0x39218fce, 0xd804fa32, 0x3e306f45, 0x00a53518,
- 0x5921bc6e, 0x185e98f3, 0x0cd9527e, 0xd0b28fbf, 0x9386f455, 0x74067fbe,
- 0xc753ac07, 0x60b7bc14, 0xf50531d9, 0xdf7babe3, 0x93b8852e, 0x723a179e,
- 0xc5a5dbcf, 0xc67de183, 0xfd736f6f, 0x6531d7aa, 0xe9a5f41e, 0x84d1d85e,
- 0xbdf331e9, 0x47c0e5ae, 0xe6ed1df9, 0x49434efb, 0x933d2e2c, 0x0e9bb2a8,
- 0xf958fd31, 0x885d7083, 0x99d3def9, 0x4fd01b91, 0x5f5de5b8, 0x394f7bfc,
- 0xdfef987f, 0x77c93afc, 0xf95fe61a, 0x985ef342, 0xbad95102, 0xafaa521d,
- 0x579ef766, 0xe93f01e7, 0x147f8872, 0x068fa17f, 0xf5ddee19, 0x11e8f5f2,
- 0x7beec4af, 0xbf705168, 0x7d8497e7, 0x98ebe217, 0x40f4c5cd, 0x6e97cac1,
- 0x55873807, 0x2e800768, 0xf9993bff, 0x1122bfd7, 0xcdd01e5b, 0x3a9c612b,
- 0x2725ab24, 0x88f78e84, 0xce083e54, 0x99e9ed75, 0x5fc60c34, 0x5c39f2e8,
- 0xed486f60, 0x91bbe187, 0x81860a63, 0x5d0e771e, 0x35d603dd, 0x570a6e1d,
- 0x076736d9, 0x175c3a1c, 0x742cbf39, 0x7ab876cd, 0x2f40efb2, 0xdc7c7e35,
- 0xfcebdf06, 0x82fa6a10, 0x5f0c41f1, 0xf0741f00, 0xd4377085, 0xf1a43c75,
- 0xd8ffaf52, 0x97fba17c, 0xf805f25d, 0xc5efee8f, 0x715c4317, 0x73da82f8,
- 0xd9b9e1c3, 0x2c290b9e, 0xfcfccccf, 0xbe114729, 0xe60855ef, 0x76bd9089,
- 0xbe3bbbf6, 0xbf2f8c14, 0xb66361ec, 0x073c747d, 0x5ceb957c, 0xf90e4ca9,
- 0x2343df3d, 0x439fda02, 0x03b8a2a9, 0xa8debced, 0x7f1cbd27, 0xc020b8e4,
- 0x4b985dfd, 0x68760d9c, 0x6bd807a4, 0x2393ad43, 0x1d3b0f20, 0x7ec1b213,
- 0xcb8c702c, 0x32bff983, 0xb05be568, 0xabd2bda4, 0x6aade5e2, 0xeba57d87,
- 0x5bbc03c3, 0x5d5bfc7d, 0xd5ae3f8c, 0xd010f9d8, 0xe870b1eb, 0x099003eb,
- 0x332210e0, 0xa81d972d, 0x142dc3c7, 0x1c02d76f, 0x04fb0f14, 0x43f600d2,
- 0x2b4b4591, 0x67b03b01, 0xdb380244, 0x0391fe9a, 0xe1c9a771, 0x78051fdf,
- 0x5bfbeb27, 0x96fee35e, 0xedd6ded9, 0xd0ffdd21, 0x228925ed, 0xa0abb742,
- 0xa73c047d, 0xbdc0f4f8, 0x45beb0e0, 0xf53e786c, 0x95ea73f1, 0x8967971a,
- 0x9f3263ce, 0x19a44dc7, 0x2e9722e1, 0xe9471e5f, 0x63e39533, 0x491261f2,
- 0x427687ca, 0xfdc014a6, 0x4c902433, 0x15e299c7, 0x7c3127c8, 0x6328d373,
- 0xa426fe1d, 0xd5d3f477, 0x6375e6fb, 0xffce29ac, 0x7ec3cb43, 0x4dfc6e76,
- 0x3c173b3f, 0x90189fa6, 0x951dfd60, 0x7b03cecb, 0x2b0e1e18, 0x23b1d7f1,
- 0x58c79e5c, 0x3ce1f25a, 0xff3dbee4, 0xff7375c4, 0x07be7f9e, 0x53e8e476,
- 0xc63c8112, 0x2786a731, 0x28ebbee3, 0xef4af915, 0x06b3eab7, 0x49cf6107,
- 0x87e87dec, 0x15da3c28, 0xcb0d9f00, 0xfe3cced7, 0xe177f404, 0xf3624498,
- 0x5f154be4, 0x968f887f, 0x0ff17bf2, 0xd29ecc09, 0xfbf10fdb, 0x78b977a8,
- 0x93d28e7c, 0x1ac4c7fb, 0x5429e743, 0x74172513, 0xc9ca75d0, 0x7e5253b2,
- 0xdfc0fa67, 0x7e1f3a27, 0x57749e4b, 0xfb0e7ea5, 0x5eb62ef7, 0xc37f0392,
- 0x35d70cf3, 0xfd8123dc, 0x48a65d7e, 0xaf7198b4, 0x1fa7a957, 0xebd8f713,
- 0x07bfd932, 0x2a627b9e, 0x111e79e4, 0x2aac6531, 0x7cade3bc, 0x718b37a8,
- 0xf19ba7cf, 0x1ef85d7b, 0x887ff809, 0x574dc99b, 0x8ab98fe3, 0x4035c9f2,
- 0xc0ecc277, 0xc8e50142, 0x7bfddf4c, 0xcb47a3fe, 0x4ef8c4e0, 0x1d337f44,
- 0x8c533b5e, 0xd15d21fb, 0x7bb7ccc3, 0x57033ce9, 0xd97aefc0, 0xd77f0048,
- 0x83f583cb, 0xebac4cfe, 0xf4d55afc, 0xf3b00f74, 0xd49d3e74, 0xe8cdf183,
- 0x20f44fdd, 0x997a0ece, 0x19b826f1, 0x75d976fd, 0x633bc4bb, 0x67f47d2a,
- 0xa3210eba, 0xe4334806, 0x587394d9, 0x8a5bbe67, 0xf9e10976, 0x6df5e6ff,
- 0x24c778a6, 0xdd5da750, 0x3a8b7f4b, 0xb9f75bbb, 0x95a91d97, 0x952c1d60,
- 0xc63d3256, 0x1e1d78ed, 0x42ff9d33, 0x44fe11ca, 0xc0f999f0, 0x68aee70c,
- 0xeb86b27e, 0xfb4f7e81, 0x72b9fef4, 0xe8799c6a, 0xd085b8f8, 0xfbaf38f5,
- 0xdb8e71eb, 0x4fe7ffc8, 0xa013fc4e, 0x99bc9135, 0xd76e66e9, 0x0c2947f5,
- 0x00658050, 0xee2193ec, 0xd2879474, 0x60d10a8b, 0x9db7ba5f, 0x379b1a7c,
- 0xe40af93a, 0xf61e15b7, 0x2dbf112c, 0xdf1228bb, 0x93be0eb0, 0x00731f1b,
- 0x6a96eddf, 0xf7f45e1d, 0x5324d5a7, 0xacfc4d3c, 0x073c16f8, 0x102162de,
- 0xfe149b5a, 0x19c400e2, 0xcc128eaa, 0xef0e2f07, 0x3d3e012b, 0x9fa33528,
- 0x908176d5, 0xceec62c7, 0x038d70c6, 0x34c6b2ec, 0x50e99e76, 0x9be4310a,
- 0x7d33711e, 0xdcec78dd, 0xbb4e2d54, 0x79f8cc98, 0xf2d2d13a, 0xd74b3fe9,
- 0x3f00fe51, 0xe30ba7b8, 0xef051324, 0xb76069eb, 0x9feec6dc, 0xf91a6b6c,
- 0xb7851a7a, 0xd414cef5, 0xd71a9333, 0x84a1e3de, 0x0c3d7d08, 0x16cfb79f,
- 0x7be85bbc, 0xeb17aaa5, 0xd172f3a5, 0x4df91bef, 0xa193e98f, 0xfd197afd,
- 0x52e2499e, 0x6755e209, 0xf0028533, 0x2d08f727, 0xf2f7e0ab, 0x38d8d302,
- 0x01e813c4, 0x933be9fe, 0xdfc50c7b, 0xfaf55174, 0x205dfc00, 0x56dff262,
- 0xcfbf3aee, 0xce57db4a, 0x733f3010, 0x049b2792, 0x74a7f862, 0xbaf3829d,
- 0x0c519c39, 0xccbd3d7c, 0xc22c4e78, 0xe519c9ed, 0xdd8c120e, 0x283c1527,
- 0xedec87d7, 0x5cefe2b7, 0xe604c936, 0x0df9cba7, 0xce67df9c, 0x6ef861ea,
- 0xa776611a, 0x7237572e, 0xfb81bbf9, 0xb2f9b7cd, 0x1397e30d, 0x81fd0f66,
- 0x92044fb4, 0x3cb32794, 0xcdeda9a2, 0x2f0edeef, 0x8047bd89, 0x9071bc3e,
- 0x9715efc9, 0xc8be46ae, 0xc780bc14, 0xfb635e29, 0xe74ca34d, 0x6bf24d14,
- 0x20330fd6, 0xacec4a3b, 0x307d7427, 0x219449a3, 0x88a3341e, 0x62ed19e2,
- 0x95dedda3, 0x949918be, 0x525c5f40, 0xa433041f, 0xb0f8be93, 0x8be97bec,
- 0x32dba957, 0x36f5ca8a, 0x21f46f5d, 0x4c6f407d, 0x009feb12, 0xeba36a3e,
- 0x1f0e35a6, 0x1e8eebe9, 0x72a52807, 0x0ce07a8c, 0x749e2fcb, 0x86048b31,
- 0xa201c475, 0x25da847a, 0xd2f638de, 0x619e777e, 0x57aa23ff, 0xb912ec62,
- 0x25db87f0, 0xaa3da893, 0xbd7c0014, 0xc252be11, 0x90a596e2, 0xc3f102c8,
- 0x0e302fcc, 0x7f512554, 0xa7e7d716, 0xffa39e99, 0xe43b5212, 0xe8af6cc3,
- 0x3c09e871, 0x97e6617e, 0x16f23c68, 0x3a42e319, 0x3e02949f, 0x116ffe41,
- 0x2ba09f71, 0x37c7d1be, 0x14c44bf3, 0x5f92ea1f, 0x577ddcb8, 0xe6ed397e,
- 0xa4fea1f1, 0x44f8777f, 0x5f9d0fe7, 0x9bcdebcc, 0xa25138a6, 0xb09fe6f5,
- 0xbc4cf4de, 0x483ebcde, 0x95debd46, 0x992e735d, 0x6e89f9e9, 0x75773b0f,
- 0xd8270ce5, 0x59921335, 0x6ebe817e, 0x1b5de345, 0xdebc9f18, 0x7d824732,
- 0x1fd02aa6, 0xd0741db9, 0x5f3ac5e3, 0x60275b2e, 0xd732747c, 0x2c4dad5f,
- 0x5135585e, 0x8fd1c20c, 0x4f63f092, 0x6fbb3ab0, 0x14efa746, 0xd24527ce,
- 0xff7e093e, 0xe0af26f4, 0xc693b885, 0x35538de3, 0x668de301, 0x44d7b5bd,
- 0x1fbce9f7, 0xbbe0bff0, 0x2084ca9b, 0xfd6693f8, 0xb322fd36, 0x53d93a2f,
- 0xccd89f7c, 0x7326572f, 0xf497d0fd, 0x15da57fd, 0xddbf92a3, 0xefbfd0ae,
- 0xb065ce8a, 0xc0ffa0a6, 0x3b0193ee, 0xdd7ce81e, 0x2dfb0945, 0x49da3649,
- 0xfc14ce17, 0xfe4f7d0a, 0x3a1ef9be, 0x1aba7cf3, 0x17f750bf, 0x8fa0ffb8,
- 0xcec4837b, 0xa7d79bf7, 0xfe23d72e, 0x775e999d, 0xb5e31b24, 0x3d745d3a,
- 0x5cef09dc, 0x5ba2274f, 0xd75a7a57, 0x3d6aff87, 0xafaff7ad, 0x66b8fa23,
- 0x7fc89dfd, 0x9af1f5d4, 0xdb8c16cd, 0xfa7ee78c, 0xfe3f1e78, 0x7ee7b705,
- 0xdffccc99, 0x166d2fb6, 0x32436f58, 0xec0b27db, 0x69fc6273, 0x07665efb,
- 0xbe2a5cd9, 0x6220a0f7, 0x11c1e47c, 0xd4d7d416, 0xf3061a07, 0x19098a96,
- 0xbdbdfb04, 0xbd6f7ed8, 0x7d472914, 0x9c0895ef, 0x8c5d13d3, 0x1fdc1e1f,
- 0x7ffa1db8, 0x968193f0, 0x474f8c1a, 0x1a5ec19a, 0x7ee12059, 0xc5558a59,
- 0x936b7678, 0x6a3bef15, 0xf6bffddb, 0x97cfd0c9, 0xe52e0bc4, 0x746b26c1,
- 0xc7f40abf, 0x0888f124, 0xed6d1cf9, 0x1b03ef04, 0x02522b37, 0xd278d97e,
- 0xfffe035c, 0xc1e58518, 0x6cd4f19b, 0xfbcca75a, 0x2c4d255d, 0xc5c4a5ff,
- 0xed3a5ff3, 0xefe33457, 0x04904f26, 0xbce90d6f, 0xc992f15f, 0xefd8e9df,
- 0xd15fb04a, 0x77d1f4c8, 0x0318afdd, 0xde7ca034, 0xd701cba4, 0xbec1244f,
- 0xed8576c5, 0xcdbfb577, 0x6993d3ed, 0x5d46e371, 0xdeec5fed, 0x7dc1a49b,
- 0xeff9db23, 0xdbdeec6c, 0x13f3534b, 0xd2df9fbf, 0xd8d30c5e, 0x84b37f5e,
- 0xbe3c73f9, 0x9a0b8d1b, 0x90e9cbf1, 0x6b481f68, 0xf5041cf4, 0xe7df7095,
- 0xaae18a82, 0x5d4f8aef, 0x4f1fb66e, 0xb7ef80d2, 0x01a5ef1f, 0xdc79fb1c,
- 0xbcf56bd0, 0xeec2f605, 0x7092e763, 0x54d1583f, 0x53da4ff0, 0xae765e6c,
- 0x2841c992, 0xf610606b, 0xeff0f7ab, 0xbfb527b6, 0xec5a7579, 0xbfdb0e7e,
- 0xd7d9cfd1, 0x47f30428, 0x3f961602, 0x0cdfc662, 0x3b938f0f, 0x2274faf1,
- 0xbc62a9a7, 0x096f503c, 0x3f3057cb, 0xce4c3c97, 0xfdfe2fff, 0x80006684,
- 0x00008000, 0x00088b1f, 0x00000000, 0x5bbdff00, 0xd554780d, 0xdceefe99,
- 0xf26677b9, 0xfc999933, 0x4dc2fe10, 0x00908102, 0x7e100843, 0x502021d4,
- 0x4540647e, 0x043abaec, 0xa1bf9085, 0x56d3ebb1, 0x4126e1f7, 0x27d3e08a,
- 0x6796dd6d, 0x57067db5, 0x3b1254b6, 0x770704c1, 0x08a00ec2, 0x80a0db54,
- 0x11dae3c2, 0x2486a229, 0xec56bb0d, 0x3befdd6e, 0x6664dce7, 0xecfa5c18,
- 0xf8728376, 0x9cf739ee, 0xfbdf7cef, 0xb3739dfd, 0x330001d3, 0x68776e01,
- 0xdb00d900, 0x8c802f64, 0xde0820cf, 0x16e91bf4, 0xd305d609, 0x7ae77688,
- 0xa9dfe0a7, 0xce1a6ba6, 0x2cb0ef91, 0x7a448f35, 0x42d1e986, 0xc639e7a4,
- 0x699e7a72, 0xf806e286, 0xba5bc867, 0xcfc00e68, 0x03875e9c, 0xd257e9d7,
- 0x00194876, 0x65049366, 0x528ed859, 0xec373803, 0x65ac0152, 0x3c1daeb8,
- 0xaa40174e, 0xd21b7405, 0x54fb360d, 0x1e95f1a0, 0xd11a4b6d, 0x87c43d00,
- 0xa5039a39, 0xd336bed8, 0xbe00b304, 0xadc1fb4d, 0x1ef8aaa4, 0xc5a8ffbe,
- 0xfb81ce37, 0xec46b7ab, 0x1ff6015a, 0xa40473ba, 0x6c1d7ed1, 0xcf2f25bf,
- 0xc60285cb, 0x33ffe157, 0xf8c9655f, 0x75f0a6da, 0x2c940f7a, 0x64bf5c04,
- 0x1a5f8a1c, 0x59994fd6, 0x416dcf63, 0xf49f3d00, 0x9095c9e0, 0xeeaa716e,
- 0xce34f99d, 0xb6f267d0, 0x21fd4145, 0x69aa725f, 0xce51e90b, 0xc0e96d30,
- 0x89874ef6, 0xac58bfcd, 0xb7903003, 0x8e0df51a, 0x5335bc81, 0x96fa4d38,
- 0x4881b2e5, 0x9b7f5239, 0x871e7eee, 0x0f8198c2, 0xddfa471e, 0x3bdc4a07,
- 0xc290be91, 0x502eb1e5, 0x7a4512d0, 0x363025ba, 0x9d397c82, 0xf7c92f3e,
- 0x04c0969b, 0x2db4a786, 0xe4bf34e9, 0xca0ef801, 0x3d104243, 0xf16efb80,
- 0x0216a680, 0x1ce7808c, 0x90004b97, 0x332af82b, 0x2560bad9, 0x8737deb9,
- 0x1758d5cb, 0x1c856865, 0x3f82a7e4, 0xf5c0f837, 0xc1beb47d, 0x301f10cf,
- 0x153971c6, 0x4857cfd8, 0xd33cd1f7, 0x0a321e50, 0xfff3d705, 0xa0b014de,
- 0x3ff8fdfc, 0x325f2fd1, 0xc9897405, 0x2cfd6d3d, 0x33ad88f6, 0x9966ade7,
- 0x9fe3ab31, 0xecd44c59, 0xbb543ca7, 0xf748ec02, 0xad462f98, 0x37f61d62,
- 0x9cf91c6e, 0x7d9fde27, 0x8d30b7c2, 0xc7e2f7da, 0xffa783cd, 0x15fbe320,
- 0xe5019010, 0xd09a2732, 0x31fe5a1f, 0x4aef3fcd, 0x77bff3fc, 0x7db167a4,
- 0x5f51828d, 0x77227db1, 0x95a35eb8, 0x66f837af, 0xd3e10641, 0xa2d9466c,
- 0x864d55fc, 0xa2bf6c0a, 0x3a003b9f, 0x0b38e2b7, 0x56adc1c0, 0xe3394ed6,
- 0x84eb40d8, 0x269022b6, 0x35babc02, 0x1d86b597, 0x0f03394d, 0x7598d4c1,
- 0x390dde04, 0xe5c7be0e, 0xe93a3d38, 0x5691f3a7, 0xd010284e, 0x5730e586,
- 0x5d106bc8, 0xf079e906, 0x475b9a4a, 0xbbc9d67a, 0x4b4fb265, 0x98b409ae,
- 0x14b4d9fd, 0xd30d26d0, 0x715c93a9, 0xb8f42cb4, 0x9e7f66cd, 0xf4f742e1,
- 0x333ae2e4, 0xeee93ac4, 0x41f37151, 0xe8c4ff00, 0xe2d755f3, 0x67ee1213,
- 0x0af55a46, 0x454657da, 0xe5fcdc41, 0xbbcbc66f, 0x091ebc0c, 0x8fbf765f,
- 0xb3fbe3fc, 0xcc7f60ce, 0x2b488af8, 0xfbc547c3, 0x5ee7cff1, 0x6f3ba78a,
- 0xc99bb7a6, 0x74fea613, 0x2e5fd67e, 0x5e27a74f, 0xe34b999e, 0x8ded99e5,
- 0x7588e797, 0xe91af2f1, 0xe8c7978b, 0xfd71c9ea, 0xc594b763, 0x33bee3d1,
- 0xbe7c6e37, 0x1747195e, 0x371658ee, 0x9aeb427e, 0xeee27a38, 0x2f8dc66f,
- 0xf5c5540e, 0xf9abec97, 0x253ff48b, 0x9e3718d8, 0x1afa6cc4, 0x7d0b4ffd,
- 0xbfbd6e2f, 0x9dfffe96, 0xcf7e8ff4, 0x7a44bfd0, 0x42fa499f, 0x1c36593f,
- 0x06b89c9f, 0xf8674bf9, 0xda12eb8d, 0xe9a95ea5, 0x0cbebcc4, 0xf7d82ddc,
- 0xc895ec8c, 0x51468dbf, 0x6c6fd09b, 0xf9354133, 0x4c981ffd, 0x86d3790f,
- 0x94e4dced, 0xaacffcd8, 0x14b8a660, 0xe94d6e3b, 0x4da338f0, 0x78d89a77,
- 0xd37edfc3, 0xd144b5a2, 0xb9974e9f, 0x9b3f453f, 0x707f44ee, 0x21427a41,
- 0xe964a937, 0xc594af8a, 0xd8bc879d, 0x6a4b213a, 0xd86336c4, 0xa15f6bbf,
- 0x81a82e52, 0xfe213fbd, 0xbdeec94f, 0x486fffc8, 0x17492320, 0xef3f166e,
- 0xa696fc37, 0xf8633865, 0xe2334c1a, 0xf14196ad, 0x42e1f073, 0x3fced7e6,
- 0xf50b4e88, 0xfbe55e7f, 0x115fc631, 0xe153ed7e, 0x9fc97ad7, 0xabfb8659,
- 0x5d38fcf7, 0x4fce79c3, 0x18c1a582, 0x390b1539, 0x2c1c1981, 0x3ae3ccee,
- 0x4bb350bb, 0xdff388d9, 0xa16c2ef7, 0x13fbee75, 0x6f7d896c, 0xfe6153b6,
- 0x6653b671, 0x726c5aed, 0x316bce51, 0x18cb39a6, 0x5db0911d, 0xb2140275,
- 0x7cbed5cb, 0x0ef28485, 0xe176cfb8, 0xd1480b92, 0xe03ddef8, 0x9fffc855,
- 0x9d3eb07b, 0xf3cd0dc6, 0x117713c6, 0xa2a2d73e, 0xd7792f29, 0xe8392ba9,
- 0x936e060f, 0x75c49c58, 0xfbdcf4ac, 0x2927e8c0, 0xdf039cbe, 0xafa8b3d5,
- 0xf366e035, 0x7222f319, 0x05ccfce3, 0x38992215, 0x12c17e8f, 0x347c8bd8,
- 0xfa825e52, 0xc11eec69, 0xcd7f5fe2, 0x827fdb1f, 0x1d1a1ee3, 0xfaf14b1d,
- 0x8a9fcd42, 0xeff7cf48, 0x7d434196, 0x77c5377e, 0x90c0e117, 0xaf87f9c3,
- 0xc63f53a5, 0xd867a65d, 0x65ef716f, 0xdecfdbf2, 0x73adc633, 0xde9bb82e,
- 0xd0140a83, 0x67f11b9c, 0x496814b4, 0xe06a352e, 0x3e43dfe7, 0xe6c294e1,
- 0x59b2f033, 0x5f31a5e0, 0x978b111b, 0xbc21f4c6, 0x71ab7cb0, 0xa6ecccaf,
- 0x0016dbb1, 0x8159cb94, 0xebfeff3b, 0x234f7d2f, 0x1f3de782, 0xc4346e21,
- 0x3711efc9, 0x8fbdc61a, 0x3f443711, 0x886b7b2a, 0xfe9e8fdf, 0x79a3eec8,
- 0xbe35b9ef, 0x7381a5fb, 0x3df2437f, 0x083ef1c9, 0x5f98e783, 0x28d62cef,
- 0xf0785baf, 0xebca39fa, 0x9a2d3a1a, 0xceabe905, 0x6967f1e8, 0x680921fc,
- 0xc6c4437c, 0xa743559c, 0x7f61b014, 0xfb63a84d, 0xda6ba468, 0xd8539756,
- 0x7221dbf0, 0x901ff507, 0x7fd8cd02, 0x7b5eab79, 0xf0b87509, 0x6997ebd5,
- 0xf957bede, 0xeab657bc, 0x9013cc1b, 0x03feb03e, 0xd3aeaf9a, 0x6fd43602,
- 0x8ea2339f, 0xa43af5a6, 0x1d57ad20, 0xf34aa1fc, 0x7ab0bf57, 0xb539a53c,
- 0xc6aa9afb, 0xbebff8c7, 0x0d55a783, 0xf9dd54e5, 0x5c62c5c3, 0x015f0f39,
- 0xfec63766, 0x369a0737, 0x2ee36398, 0x7b275bfe, 0x2df77e12, 0xe175ff21,
- 0x271216c2, 0x67ae95fa, 0x7657e625, 0xb872bf33, 0x85fedffd, 0x8bf43bd6,
- 0x281b8409, 0x837935bf, 0xb1716757, 0x5703ac41, 0x9ea951de, 0x2e54e869,
- 0x7c65e7c7, 0x77a735fc, 0xf92673af, 0x85b49855, 0x79f13bd5, 0x25940ee2,
- 0x7e7ae1e5, 0x390fb30a, 0x8f5d406d, 0x069f7cfc, 0xc7663f20, 0xf4855a80,
- 0x5718970e, 0xcdec0d60, 0x3ebf91bf, 0x67ad99a7, 0xac5f002d, 0xcfda30df,
- 0x82b1ff44, 0xd528d54f, 0x9515da17, 0xf910db70, 0x7f90d544, 0xc5c3e87f,
- 0x7def249e, 0x6295fc22, 0x29ef56f2, 0x468fb61f, 0x714a39a9, 0x44d0f1aa,
- 0xd67a674d, 0x2ebf8ca3, 0x58fb469b, 0x5993f078, 0x3ef998d1, 0x578c7c43,
- 0x5f86e986, 0x2155387d, 0xe1fcbdb9, 0xcc7a7354, 0xaad2723e, 0xe0f94903,
- 0xbb49e2f1, 0x5bad0af7, 0x35a2d07f, 0xdcdb7c33, 0x3877c211, 0x44668dd5,
- 0xcb9b56f8, 0x3f7df163, 0x2c21bbe3, 0xd0e911bb, 0x6bed5a10, 0xddd3e362,
- 0xb43906a4, 0xc99c2740, 0x23c32f0e, 0x37ae27fc, 0xfe30e28b, 0x756a3fa0,
- 0x78477efa, 0x55e9a731, 0xdaf898e6, 0x35e68a60, 0x5f3fa44b, 0xfb1882eb,
- 0xad74d393, 0x99e48b39, 0x61b596e9, 0xae2629fd, 0x6a2d3e97, 0xdb1c5177,
- 0xbd91f38a, 0x93b13e44, 0x3687b7fc, 0x3beec958, 0x47ae0e9c, 0x481cd755,
- 0x877a09b7, 0xbb26adea, 0xc29391da, 0x2e31b5eb, 0x09ffef86, 0xaf647daf,
- 0x3e028eb8, 0x09f77f56, 0x058df5bc, 0xf7297fe6, 0x94c99c23, 0x199215ef,
- 0xce341cf9, 0xbdaa6a1f, 0x87976b14, 0x7f1373ee, 0x1f7f0a4a, 0x135e3872,
- 0x7175cdd7, 0xaa693d9c, 0x13105d6a, 0xe5c71387, 0xc399b8d0, 0xceb30072,
- 0x697001ce, 0xfefc324f, 0x776959c2, 0xde5dfe91, 0xcd87e449, 0x51e118c4,
- 0x81f29353, 0xd95cb3e3, 0x2e4de3c3, 0x554f5b07, 0xeb920e7c, 0xad39397f,
- 0x67265ea8, 0xec8d6c34, 0x057f6878, 0x9b3b526a, 0x91def82e, 0xc4f7af1f,
- 0x38c4d371, 0x56e7a4c5, 0x65879f11, 0xdafd3766, 0x31bfd300, 0x9d723fae,
- 0xed7c3feb, 0x79d90f2e, 0xcf865afe, 0x5c597f4f, 0xbbccc726, 0x853959ce,
- 0x12e793f6, 0x5cf45078, 0x2ba47be2, 0x733f1f7e, 0x62b8677a, 0x4c601fce,
- 0x04e12dd6, 0x16e07d44, 0x83eb0ef1, 0xb57c6649, 0xe4dc521f, 0x1e443bdf,
- 0xc32f066c, 0x35b82a49, 0xe07af756, 0x7f70f3d7, 0xb04c472d, 0x1d3b4913,
- 0xf3628c72, 0x04d8b079, 0x8a326cbb, 0x4b158f08, 0x323212bd, 0x9ae25fec,
- 0xc86d8df6, 0x65d021ef, 0xd7c73f5e, 0x3c91e0c1, 0xfbfd6c52, 0xd5adcd5a,
- 0x5af9cfbf, 0xeb13cec8, 0xd31139df, 0x16e3357a, 0x96d7e0ea, 0x1f83ad25,
- 0x53d7c574, 0xc634bb0f, 0xc712705c, 0x12923061, 0x3028e7e0, 0x845c7083,
- 0xedfa84e1, 0xa555bc39, 0x275649be, 0xf4d733c6, 0x418c76a7, 0xe5cf1b3b,
- 0xfd0b7440, 0x8df3ca3b, 0xb5fabaa1, 0x44ff2cc9, 0x7ab3247f, 0x497821d2,
- 0xe6395fd0, 0x7118bc49, 0x91e5d5c7, 0xc9da5fe3, 0xb4bbb6ff, 0x067e92df,
- 0x7940ca4e, 0x551ccd9c, 0xebec499d, 0x98b3e520, 0xe2e4bc8f, 0x921ad67e,
- 0xdf5c013c, 0xe28079aa, 0x98e1cdbc, 0x59d8c72e, 0x85c78b95, 0xf217e3fa,
- 0xaf23cc54, 0x97b4de9a, 0x5d75fce2, 0xcc74ec07, 0xedfe7b53, 0xb4147459,
- 0x4edbecc8, 0xb4a9fb76, 0xf94ac8a7, 0x54c08ee1, 0x52304f92, 0x77714190,
- 0x7374198a, 0xf8fc8dd9, 0x50a6e377, 0x33bb0d86, 0x3c253b59, 0xa7e51363,
- 0x2fdf08fe, 0x0ba0a1ad, 0x8c490e2c, 0xb8b50bee, 0xbfff3e68, 0x3f228f76,
- 0x9f9b3fb5, 0x45f8be2f, 0x0cdf7f09, 0xacff1a66, 0x1ef029cb, 0xd479d130,
- 0xd58e717e, 0xc6cc85f7, 0x094feb19, 0x881d902d, 0xeb48d283, 0x164e7651,
- 0xca7cb0b6, 0x797002f6, 0xa3cf3184, 0x4bc39cf3, 0xbf51e280, 0xf612dc13,
- 0xb00ca7b7, 0xdba067fc, 0x912f3da2, 0xec815adc, 0x75e55dbd, 0xf602314b,
- 0x73f0da40, 0xf85b3d63, 0x44e674a7, 0xfc50f0b8, 0xe15b99b3, 0x7958b4b6,
- 0x877933a7, 0xa6c80f29, 0x34a62275, 0x77d1cfca, 0x1af8cf3e, 0xbad813e6,
- 0xccc59f06, 0x03abb7cf, 0x62cf1f97, 0x0708397c, 0x84f9c0c5, 0xfc8d44f0,
- 0x61e1cd9c, 0x3439b0fb, 0xc8dd2eb7, 0x262a7f97, 0x3f3f6860, 0x7b218668,
- 0xa7f6fb26, 0xb456d30c, 0x8e02f685, 0x3c37d06b, 0x0c7e68b5, 0x62a68e4d,
- 0xaed3fdf8, 0x1b6d4f8d, 0x748dcec3, 0x8a9ff519, 0xf68bba6d, 0xbd0aedc9,
- 0x8cbb27a7, 0x728dc1cb, 0xfef2b54a, 0xf388f1a1, 0xf8d3a234, 0x91c5b738,
- 0xd99f2cba, 0x18bd900b, 0xa5b7d9f9, 0x503be5c8, 0xf43fbdb5, 0xbee29466,
- 0x1f474d7a, 0x9f71c36b, 0x45160fad, 0x7d50fea8, 0x5f3e13ef, 0xd76abf79,
- 0xedbbf214, 0xf9057b8a, 0x23fea89f, 0xa8bf0796, 0xec633b68, 0xe40cc60e,
- 0xd7137e10, 0xfe6f9ff1, 0xfdb9e511, 0xaacd2487, 0xc81dff91, 0xc21bbe23,
- 0xd7e4ab1f, 0x643e87fd, 0x9913ed79, 0x5eb42bbe, 0x2169a845, 0xb40e75c9,
- 0x2edf90b6, 0x3041f911, 0xc193fb97, 0x37cf4533, 0x9ec1e8c5, 0x0edc7129,
- 0x9c51c6f8, 0x3d7b0b0a, 0xb627f54c, 0x2fee475d, 0x44bbf9a4, 0xd7bc6c7d,
- 0x93474704, 0x35e19bdc, 0x9dc50ed6, 0xe1297980, 0xf59ce4ac, 0x78cc4f21,
- 0xbf3f266b, 0x02f58ab5, 0x133fbe99, 0x2e47b5bf, 0xe7da76aa, 0xd51e60a5,
- 0x93ac4195, 0xc8fc491d, 0xd826fd90, 0xa03cdf93, 0x15ff78d2, 0xf5057e60,
- 0xf5032dbd, 0x685cffb7, 0xde7c7af2, 0xa0c93a85, 0xaf3ce17c, 0xef14bb13,
- 0x74df1a68, 0xe4a9f3f6, 0xa82806c7, 0x779f7fe1, 0xb9238ed7, 0x532bfe21,
- 0x803acec8, 0x4ec335f9, 0xf14ec94b, 0x7fc252fd, 0xccc5d139, 0x3dabb72f,
- 0x765d98cb, 0x12ec8099, 0x01eccff1, 0xb8a0eff1, 0x7b40ea5c, 0x644fef60,
- 0x63dede76, 0x167cb0f2, 0x4604fafd, 0x744dde57, 0x0722cf7b, 0xe21373b3,
- 0x35ec8cb9, 0x13cd9472, 0xa634a004, 0xec6f025c, 0xcb954139, 0xf86cf0ce,
- 0x7ec22dcb, 0x0cb49383, 0x5523ee37, 0x23ece396, 0x5a725e26, 0x7fc7d3c4,
- 0x9ea793fc, 0xa78f4f99, 0x10e138f3, 0xce9b5271, 0x22a3fefc, 0x3ebe3556,
- 0xe51b5577, 0xacc96fe5, 0xa738b0ff, 0x1c9c0888, 0x1414e715, 0xcfd43437,
- 0x75fce26b, 0xf41ed226, 0x5b3cb3a3, 0x556e5216, 0x18f5b4b1, 0xc1bd73b5,
- 0xce329485, 0x4c73d75f, 0x425e66e1, 0xfa3cebf8, 0xf933128d, 0xcebcf3bd,
- 0xe072fceb, 0x0e511783, 0xf9461d8f, 0xb8538927, 0xcc3f861d, 0xee4346b3,
- 0x92fdfd8d, 0xf97e47e1, 0xfa43aa0d, 0x1a61e53a, 0x020363e3, 0x9955e89b,
- 0x474a78bf, 0xf4c83ec6, 0x7944c9ac, 0x35bed9ca, 0x9cef9499, 0xcc8732fe,
- 0x45ccebb2, 0xaa773f56, 0x4fc2129e, 0x9c960167, 0x7b7a7049, 0x51f4c2a6,
- 0x673f896e, 0x84c7da31, 0xb0e9141d, 0xb1f5624b, 0xfd5008ec, 0x547b29dc,
- 0x80ae83cc, 0xf91e76be, 0xf81e711b, 0x0f1f8808, 0x6cfd41fe, 0x9423e414,
- 0xdadc60b7, 0x77128cf8, 0x2de4673e, 0xb07bc675, 0xdaf844c5, 0x1fe09614,
- 0xcfd51651, 0xa3af8fc5, 0xd9e705bc, 0x7c73da1c, 0xe6b5ea34, 0xca7e8485,
- 0x79b9d85b, 0x75a3d590, 0xfe5c4a6d, 0x38a658f2, 0x42842c0f, 0x57105fca,
- 0x66284fcc, 0x1c416138, 0x6df6c84f, 0x6fdf3b20, 0xff42f2e2, 0x0373ecca,
- 0xb79f15e1, 0x34bf7257, 0xcc021570, 0x8f05f67e, 0xb9df91d9, 0x5a6ef96d,
- 0xf799ae63, 0xf3e50dcf, 0x40730d7b, 0xa90a8d5e, 0xb316f8f0, 0x9cf75afc,
- 0x54b945c9, 0x0e097f0b, 0x59b5fe7e, 0xe45abeec, 0x4a039b77, 0x2fcefcd2,
- 0x4081cdc6, 0x69bbad0b, 0x47cec49f, 0x8fc5f76b, 0xd5390bf7, 0x9c7d3eed,
- 0x83eafd8e, 0x4e42fd09, 0xf3fc50fe, 0x78727c03, 0x1e5390d6, 0xf373b1e4,
- 0x6756b713, 0x7cf0a67d, 0x8f316de3, 0x38161fd1, 0x906dc06a, 0x7202eb7e,
- 0x2d547080, 0xf79e76e9, 0xdc7ada42, 0x060306df, 0xb941fe1a, 0xb4e42c3c,
- 0xed87e041, 0x7fafdf1f, 0xbdd00a4e, 0xc74fc3d3, 0x5e035ff3, 0xdf3e3475,
- 0x952df9d8, 0xf112f5ce, 0xb0a6dd56, 0xc846b7fc, 0x355f1127, 0x5569f843,
- 0xe225be29, 0xdd27c1ab, 0xb79e7f84, 0x37f96fff, 0xa6235cf4, 0xec2255a9,
- 0x1ff6a89c, 0xddaeb724, 0xfb435f7c, 0x4bfbfb11, 0xd0de75f7, 0xcc9864f7,
- 0xf334bdf4, 0xf8a5eb16, 0xe543bb7c, 0xe6683376, 0x9e06cae7, 0x2c5fdf12,
- 0xbb25f5f2, 0x357ade79, 0xe74ecd74, 0x833dfdc4, 0x69ad6076, 0xa247c529,
- 0xa5f8c7c7, 0x5d79324f, 0xa3f73dbd, 0xbf3e501f, 0x637143a4, 0x637507a6,
- 0xf1c52f15, 0xe7afb1ba, 0x2bad8f8c, 0x1d25f8c5, 0xe8db348f, 0x9297e23c,
- 0x3fb2cc9b, 0x894777fc, 0xf724dbd6, 0x78ff7c04, 0xe66fe0cf, 0x53725e91,
- 0xfe7cd167, 0xda4b3bee, 0xfcfe3e91, 0xfd6c770c, 0xf7c5dc79, 0xc2ac64b7,
- 0xa8ef6ae2, 0x415a7fd4, 0x3d9e85e7, 0x5f7bbecc, 0xfb25597d, 0x20976fef,
- 0x9e3a1717, 0x1d25ec7b, 0xf07bdde5, 0xfac94ab4, 0x6ad3cec2, 0x85f26bf4,
- 0x458e58ab, 0xab6a79d8, 0xb78f754a, 0x946af7eb, 0x3e17a7f2, 0x3554e764,
- 0x3e53e794, 0xd01c9cf6, 0xbac79ff0, 0x4f09515f, 0x8c126d0d, 0x57ed8fc8,
- 0x41f93f58, 0xe36e3fa2, 0x69c0d4fe, 0x81a5c095, 0x55b70353, 0xd86cffc2,
- 0x86971c91, 0x9e08da9f, 0xbe70a3ed, 0xabd6da47, 0xd23d0794, 0x137e3f1a,
- 0x68d399d5, 0xa6e5c73c, 0x9bfdf1dd, 0x33a8f087, 0xefe89d3f, 0x1e04b24a,
- 0xf098a18b, 0x1aa91838, 0x7fdc4667, 0x1c66ba7e, 0x7947b924, 0x2377c453,
- 0xbe4cdebe, 0x2a6ba17d, 0x18ff45c5, 0xfe17d585, 0xc6a1ff31, 0x166665e2,
- 0xf0e2cbc7, 0x569e981f, 0xa22c8f84, 0xaf8256f5, 0x32bce48e, 0x7ca0ea9c,
- 0xdb944579, 0x25b0b2f1, 0x3f889010, 0x2b878b13, 0x708db821, 0xc2d87fd0,
- 0x955f29cf, 0xc204de58, 0x72126dbf, 0xbce424df, 0xd1b1eb09, 0xa883ddf4,
- 0xdd441bc7, 0x9ed279bd, 0x340254e3, 0x93bafe88, 0xe724ecc7, 0xcffdc065,
- 0x3ff720b2, 0x788cfe86, 0x18f76892, 0xfd241ea9, 0x402d86d7, 0x172c33df,
- 0x1b7967fe, 0x46e91ffa, 0x323fd03f, 0xef47e195, 0xc6277ce2, 0xf8ce86cf,
- 0x78b20bf1, 0xf2283a3e, 0x712caae0, 0xb6f4203e, 0x4b520062, 0x9a65be71,
- 0xb7b00eec, 0xfeb4cc7a, 0x4788a989, 0x5684ff9c, 0xa24be198, 0x8dfda34f,
- 0x7a0defc8, 0xe18b9d15, 0x35a3a0f8, 0x7f7eb62d, 0xebd78b2b, 0x9d647335,
- 0xef5310f4, 0x4fcb2aac, 0x377cef5a, 0x31bfc70b, 0xd3d3c366, 0xcf1deb63,
- 0xe3c2229e, 0xbc7f73f7, 0xf157be82, 0xd2ff71b7, 0x66f38157, 0x2c0efe50,
- 0x59b7f61f, 0xf8975402, 0x37544f11, 0x90bc212c, 0x3ba586bd, 0x2f582f09,
- 0xaff3493c, 0xdc3b2ba6, 0xc610eaff, 0xf57e9c69, 0xfc303fa2, 0xf7cf1c9d,
- 0x911b728d, 0xea307eac, 0x782f8686, 0x6f3c6a7e, 0xfd594730, 0x189610d0,
- 0x5e8f3b7e, 0x7e47cbcf, 0x98ffbbfb, 0x50db1eb7, 0x9db38f16, 0xf48bc195,
- 0xede7c91d, 0xe879a4d6, 0xb6971f90, 0x50697b31, 0x3f2c39a2, 0xe0f98439,
- 0xde37ac6c, 0x1bd594fe, 0x0f6d479d, 0xcab43cb1, 0x35f1ce37, 0x66826a7a,
- 0xc336cf96, 0x9e52d636, 0x6dff9b13, 0x52eff072, 0x48388a36, 0xeb8813f4,
- 0xf6f6388d, 0x83fd1bb2, 0x05ea6fe1, 0xbe8337ae, 0xa3749e7d, 0x7617a89f,
- 0x67ba5b53, 0x8968a53b, 0xb0bd5079, 0x59fccc27, 0x83cc4bdc, 0x6bc04ade,
- 0x2c29dbd3, 0x293fedcf, 0x184ce83b, 0x51f3fbe5, 0x7e61ef94, 0x1ce4905f,
- 0xcf8153f4, 0xd9ff715e, 0xf9332154, 0xd6f0e699, 0x8e509bc8, 0xa7fd370c,
- 0x275402d3, 0xa57e1c94, 0xbb507080, 0xdac5c70f, 0xc7d1ea1f, 0xf00a0fbe,
- 0x2a60a573, 0xfa31d3bb, 0x657e1ff7, 0xe9ade132, 0xb88b2fed, 0xa917ae7e,
- 0xcfe73759, 0xd7892568, 0xd78926bf, 0xa8e65dbf, 0xff2eea9d, 0x881bd921,
- 0xefa1abd1, 0xc08e040f, 0x8bfcebcc, 0x9ba31a59, 0xa61f1cc2, 0xfae2de6e,
- 0x8f39f96b, 0xa1bfd6c2, 0xf37112bf, 0x880ef135, 0x5f80c42f, 0xf3f86019,
- 0x7e31369f, 0x7307a7fc, 0x4ebee362, 0xff208ef3, 0xcc0754d7, 0xf902a49f,
- 0x3a67f45d, 0xdfcbcbd5, 0xea7cb1b3, 0x15aec178, 0xc8157fcc, 0xb1ebfe40,
- 0xc6266bb7, 0x598d8bc6, 0x254c3f32, 0x1652e439, 0x5f5f0cf3, 0xd619a1c8,
- 0x8e027388, 0xb9338fe7, 0xeafac15f, 0x89cf64cf, 0xe6add5f5, 0x16dd4dc5,
- 0xff6473a0, 0xcefb0b05, 0x4deef3e4, 0x2f877eac, 0xdfc9137c, 0x8d37cf80,
- 0x6f0ec7da, 0x3fcf489a, 0x1a79bc3f, 0x9a94f73b, 0x4e99e2e3, 0xbe52e5fc,
- 0xc3473674, 0xb3eefafe, 0xfab8bbec, 0x4ff1856e, 0xcb3c6c74, 0xefe7e6c8,
- 0xec6c47fd, 0x0282437c, 0x1f18038e, 0xe75d6f37, 0xa8bf2ceb, 0x589ec90b,
- 0x8def183c, 0xb171e6cb, 0x20e05b30, 0x9e987928, 0x175b783b, 0x53f1997a,
- 0x1e9904ab, 0xde14da9b, 0xcc5bcedf, 0x3a1f193b, 0xbfe274b8, 0xf9bfce83,
- 0xe73b08bd, 0x3ecc91c0, 0x07152706, 0x6bfd2276, 0x1d72847a, 0x3f80980c,
- 0xe4fbb0b7, 0x19851396, 0x13c1fb84, 0x8b25672f, 0x3dd26f1b, 0x54e5420a,
- 0x1243af3e, 0xf3652ffb, 0xe75387f3, 0xb53b3fb9, 0x993137c0, 0x92a1d35f,
- 0x9092e9d7, 0x34b2a777, 0x45dc7dd9, 0x31bedf31, 0x4fda29fa, 0xdd8d876f,
- 0xf93af5c7, 0x03c2ea79, 0x1499cd27, 0x99a53b7f, 0x276a4714, 0xbe88bbbd,
- 0x9cba4003, 0xe46d5afc, 0xac77bb10, 0xec58eb6f, 0x4747c249, 0x32dfc736,
- 0xe67df935, 0x3bff44b7, 0x7516cee0, 0xae132ed4, 0xc50acef7, 0x1de593b1,
- 0xe891b49e, 0x7e12ef87, 0x0a95eef8, 0x01de53cb, 0x16f7e14d, 0x95617efc,
- 0x0977b3f0, 0x22aabcff, 0x57be3fb9, 0x39fab3cc, 0x17ee9278, 0xc7e27b56,
- 0xbdf22bdd, 0xf361e035, 0xa134bddf, 0xf77de45f, 0xc1f2137a, 0x8b87e16c,
- 0x70fc88a0, 0xe903e310, 0xc6d8b1bd, 0x29f2ece2, 0x09e69213, 0xd2ffd1c7,
- 0xc42703f7, 0xfe860477, 0x65df8a9b, 0x91d4ebf1, 0x99392ff3, 0x4141b6ff,
- 0xe1b1fb92, 0xfdd865f8, 0xe2ef5c3d, 0xc1dea1be, 0x7ff43479, 0xd8a32b15,
- 0xff432d73, 0x7f73674f, 0xb6cfbb59, 0xb0bef625, 0xa38ce83e, 0x5b91a1fd,
- 0xfbf8c52e, 0x8c73815a, 0x73d8e601, 0xdf641790, 0xf4d9d9d3, 0xcb2f6b3d,
- 0x2c0771af, 0xf2bee17e, 0x2cf2bec4, 0xeae97131, 0x7149f5c8, 0x973fbc3c,
- 0x167ffdce, 0x5b148f6b, 0x07d5fd98, 0x6bdd00a5, 0x3db847d5, 0xb123dfd6,
- 0xcea2c273, 0x857bec23, 0xb7248bb5, 0x33b1bb87, 0xa3819fc4, 0xcf1e5655,
- 0xc90cbc0d, 0xfa88e04b, 0x25dfbe29, 0x9e227be2, 0x62cf4226, 0x8f3eff9a,
- 0xecefa6e4, 0x75a38a6e, 0x30a75fd3, 0x211c3374, 0x9bf2152e, 0x24fa7889,
- 0xf249d7db, 0xed71fac3, 0x54ff9c14, 0x8479c7f1, 0xd89b869f, 0x1d856fd1,
- 0x4fd34bed, 0x3baffc51, 0x0fd5ee20, 0x24a28714, 0xf2c01397, 0xcf675ec0,
- 0x1f9e46f6, 0xfaf57bb3, 0x0f7d8d88, 0x754e1f58, 0x6cee88db, 0x754c994a,
- 0xa7765864, 0xf3a2bd22, 0xdfaa22f4, 0xeff39457, 0x01d41a3c, 0x3ab68796,
- 0xbf89277d, 0xb8a6ee95, 0xcf8374fb, 0xd13de19b, 0xe1245dcf, 0xfcf5ff64,
- 0x972145cf, 0x72d793c6, 0x9d7e1326, 0x5365dfbe, 0x45fd793c, 0xfcf6ae95,
- 0x9c595f93, 0x8d38d1a9, 0x76d95b8d, 0xe31d1b64, 0xcf4ffc1a, 0x4efe3076,
- 0x2c318129, 0xb5bd2cbf, 0x0e9a4bef, 0xf29531bd, 0x2723bee9, 0x3831aaa7,
- 0x7f446def, 0x4d7f449d, 0x6bf61260, 0xad24ad66, 0xb70ef911, 0xb1f77f67,
- 0xe85f3a1c, 0xa52e3b25, 0xe29dacf6, 0x3bc77d64, 0x779409f6, 0x98d6f174,
- 0x66586aef, 0x2d1cc0e3, 0x963d37ba, 0x7f1927bf, 0x1e7c8357, 0xddd16880,
- 0x5bfb6253, 0x40fdaffe, 0x03f30e7a, 0x603f38d1, 0x7bab09c8, 0x8799d59d,
- 0x9e9eec2d, 0xbf625bee, 0xe1ce2acf, 0x1636697e, 0x73af643d, 0x90b99ee8,
- 0x3c333352, 0x2219b440, 0x07dd1766, 0xddfe6447, 0xe7e618da, 0x67f58967,
- 0xe847239b, 0xe239cdbb, 0xf42e727e, 0xc3b771b0, 0xe03d6b00, 0x095b5330,
- 0x5856d66e, 0x6ca9cb23, 0x65060d2f, 0xc7247fd2, 0xe56cbcec, 0x4c90f2bf,
- 0x3372c3df, 0x1e4365c3, 0xf163dd32, 0xf712ffef, 0xf1c39953, 0xfdc3db38,
- 0xf416a50f, 0x040566dd, 0x6df9fdd9, 0xe8f71510, 0x0f31f7c9, 0x37ba37eb,
- 0x99d30dbb, 0x008f2614, 0xf69f3f1b, 0x4fdb2723, 0x33533974, 0x7f10722c,
- 0xf4c72452, 0xefadea55, 0xd8073fa3, 0x030df6bc, 0x0f978f7d, 0xc3ba3bdf,
- 0xdf47bc6f, 0x0f1e4a99, 0x6dd50efb, 0x1d508b4d, 0x1de8da83, 0xe80563f2,
- 0x56aa7337, 0xfe1ccce6, 0xc07c1f9e, 0xfc48cfbe, 0x7bb69f9e, 0xbbf86725,
- 0xd27be32f, 0x9a35817d, 0x2eb1f109, 0x1196eacb, 0xbcd6651f, 0x657bec19,
- 0xe1256fa7, 0x36d482ea, 0x0e624d81, 0xa87964cc, 0x782a55c0, 0x92ff682a,
- 0x027df8c7, 0xc5d17860, 0x039eb7f9, 0x5238f7ec, 0x2bf7fc2d, 0xad0e2176,
- 0x8d7e862e, 0x27858fbe, 0xef946a16, 0xdd5a776e, 0x8859cf94, 0x7e61d4df,
- 0x3bfcac5b, 0x5e6b168a, 0xf1b8fc80, 0x3ca2585d, 0x3d16505b, 0x56dd0ecc,
- 0xfc272f96, 0xc59b47fe, 0xcf922df7, 0x472bd3b7, 0xf25c1e50, 0x2cb9f9ab,
- 0xcc79472f, 0xba61e437, 0x7028f7f1, 0xfda1dfff, 0x82fefe27, 0x04546fb1,
- 0xc8438f03, 0x838390d3, 0xc77144f4, 0xf4327a83, 0x9f2c305c, 0x0e5c295d,
- 0x52417d0a, 0xc8d5dec8, 0x6ff7135e, 0x01bfefec, 0x8f1a3ec3, 0x00003430
-};
-
-static const u32 xsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x277bff00, 0xa3f0c0cd, 0xa5fd811e, 0x79ba1818,
- 0x8968c550, 0x30327137, 0x303170b0, 0x06710268, 0x2036ded0, 0x17c40edd,
- 0x1022f880, 0x3033719b, 0x11710214, 0xf2032f10, 0x56dcd093, 0x50c0c4c1,
- 0x4035c405, 0x3ac4075c, 0xba0c0c8c, 0x1fdbc48c, 0xf0c0c42f, 0xd7c10c42,
- 0x48606710, 0xff9fa491, 0x54ee1b07, 0xc27dafa1, 0x860c0caa, 0x4662a8ba,
- 0x5d637c68, 0xa09866fc, 0xf1a29bc9, 0x17e8f0cd, 0x87e540b4, 0xe3f2a219,
- 0x7618198c, 0x3709a922, 0x7416efc4, 0xf7a802fc, 0x00031025, 0x22037beb,
- 0x00000368
-};
-
-static const u32 xsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0x73b9f8b9, 0xc999dee7,
- 0xac84992c, 0x5d86f12c, 0x48409c04, 0x5876c443, 0x0622b4a4, 0x30a20a97,
- 0x9037d96c, 0xff69f0fa, 0xa5ab0819, 0x68d06a1a, 0x68304ec1, 0x1a0741b0,
- 0x01c04830, 0x6a2be2d4, 0x6d8ad3ec, 0x2c3480c5, 0x0dc46486, 0x3ff2d3de,
- 0xcdce77df, 0x11337bdc, 0xbffbfb6c, 0x4f169fe5, 0xb7fb3dce, 0xe77cef9d,
- 0x92cc5f3b, 0x407e1240, 0xa1f865c8, 0x211318e9, 0x5d245c64, 0x88fdfd6c,
- 0xe5227d53, 0xacc8957f, 0x465a48e0, 0x46dbe42a, 0xb213be45, 0xb16feb12,
- 0x589346b9, 0xc402d348, 0x93df3f45, 0x84592268, 0xf826e7dc, 0x9bce25b3,
- 0x12126426, 0x6f7168de, 0x25dfa74d, 0xd02425c5, 0xb720fd74, 0x4a76805f,
- 0xebc3e412, 0x9a56f725, 0x165f5f27, 0xcad9bda1, 0x27e813da, 0xf87c9089,
- 0xd221107d, 0xe8f89145, 0x024ba4fc, 0x32245ba6, 0x4fce972f, 0x2646df72,
- 0x73f3223a, 0x9392e427, 0x994efbf4, 0x52efd396, 0x37d5ae42, 0x2d7e5232,
- 0xe4fe7011, 0x5fec4aeb, 0xfbb56f1d, 0xd717ab36, 0xdfb517eb, 0x5c17dcbb,
- 0xcb757df0, 0x2d0fd8ed, 0xc39675c1, 0x9e5a14fc, 0xa6265270, 0x3811ff48,
- 0x351c7005, 0x71d0b4af, 0xf08847bf, 0x84ed37ca, 0xb76abbae, 0x5c2858a4,
- 0x4296ef26, 0xd2f9a03f, 0x7900213a, 0x211b01d3, 0x9b9d6e14, 0x94e43e59,
- 0x7cff50bd, 0x2ed3cd3d, 0x8fad2dca, 0xdd7000dc, 0x38ad922d, 0xe609ae4c,
- 0xadc2aedb, 0x6cf3e599, 0x775a5b2c, 0x2fb42e70, 0x1b10b668, 0x6f74afed,
- 0x681b8cfe, 0x4488ff3e, 0xb6e94aa0, 0x9a5f7215, 0x41080c2f, 0x224d77c8,
- 0x8f7fbe38, 0xeb46d818, 0x935ab977, 0x3c70a4ee, 0xca256957, 0x676f3a30,
- 0x141dd26b, 0x9d81450e, 0x515da153, 0x1201e0a3, 0xdb7bbc9a, 0x5db4a9eb,
- 0x63c176e9, 0x6e2970a1, 0x386513b0, 0xfa65c39b, 0x0c49bdaf, 0x2f9680fd,
- 0xe924eba5, 0xa9ead780, 0x37f18444, 0x02338aca, 0xc39573a7, 0xe4896289,
- 0x71d3b74b, 0x17b2bb68, 0xb12c0f04, 0x407c44cc, 0x6d7b9d97, 0xc0719eb3,
- 0x43c856fa, 0xb5aeb09d, 0x0fcbd432, 0x5363dfcc, 0xf2757e60, 0xb45e5a54,
- 0xd3ce4eb9, 0xe1b8bfe0, 0x3558a23a, 0x941daaf3, 0x630fa5ac, 0x89928e7a,
- 0x84453e76, 0x200e8378, 0x533c8083, 0x857d17c3, 0x7177c438, 0x9feba883,
- 0x44909242, 0xe8f7dffa, 0xfe5e14af, 0xab844efd, 0x9ca5b78a, 0x5dbc548e,
- 0xcc43fce0, 0xff6d2ce1, 0xe008fa6a, 0xbaa7ce81, 0x2fe98dd2, 0xad30532b,
- 0x3f1054a9, 0x68fc038f, 0xdbcf81ba, 0x344c8135, 0x5e5d71d3, 0x8b3606e2,
- 0x289dee9f, 0x2e7c7cd1, 0xe3dd27cb, 0x596f9413, 0x2e3e9abf, 0x4f03e6f9,
- 0xbd53226e, 0x979a54e6, 0x87884b7d, 0xd5be6f8e, 0x213c653b, 0xa3df12af,
- 0xe4d17eb0, 0x12bc002b, 0xa5c94c12, 0x50235978, 0xb5e14239, 0xe1491616,
- 0xd29526b0, 0xe3d3c533, 0x233d66f7, 0x09ad7c0a, 0xf67bcf90, 0xa7ec74e1,
- 0x6991fb16, 0xdcae833f, 0x6cdcd24f, 0x73493f5d, 0xea7ed40b, 0xab989fb0,
- 0xb9f1e7eb, 0xccf9fa39, 0x79fb522d, 0xae89ea1e, 0xd2575bab, 0xf9fa09bc,
- 0x7ec12bcc, 0x10f1ef92, 0xaa2fad1f, 0xbd5a43f4, 0x34772d22, 0x98798dc6,
- 0xd268e968, 0x49cfe81e, 0x474b4ab9, 0x3a31d9b1, 0xc6f38a7e, 0xa67df2eb,
- 0x4fd5d5f5, 0x2ba81dcc, 0xc2359e4f, 0x770e9740, 0x0f3c75fb, 0x91597293,
- 0x32bee5ef, 0x7d899dca, 0xfbff38ad, 0xee503afb, 0x1be39fdc, 0x86f3a6e6,
- 0xff8a12b9, 0xf5df65fb, 0x437428ee, 0x149025d7, 0xa4131548, 0x12b5f2c6,
- 0x7ea4db83, 0x413d0f5f, 0xc29b97db, 0xfe68e343, 0x8ff13088, 0x80bfeeb0,
- 0x8b78a530, 0xd4054911, 0x9410b18b, 0xb3d36b7f, 0xe06bf19e, 0xa5006eba,
- 0xefd22117, 0x0297c93a, 0xafe6d8f4, 0xae7d03f0, 0x60532019, 0x54827212,
- 0x6983fc84, 0x297901fb, 0x4c8b7f00, 0x7c7687e5, 0x123f8e99, 0xf1876fc7,
- 0xdf197a3b, 0x375b3032, 0x40ad35be, 0xa655be37, 0x08fe53e3, 0xf1f397fb,
- 0x0872fc29, 0xc72c94f9, 0x05692df1, 0x995afe38, 0x8fc6e814, 0x4bff1ee9,
- 0x186bf718, 0xfaca313f, 0xd7e8e607, 0x5fa4569f, 0x4fd6ccbf, 0xf8f9f856,
- 0x417eb831, 0xa7f5b3f0, 0x5bf5b115, 0xe3ddbf58, 0x2fe1babb, 0x875c740b,
- 0x07facbd0, 0xffafd04d, 0xfafd129a, 0xf77c6c2d, 0x7c7c758a, 0x271f8e07,
- 0xbfeb63ac, 0x97c704a6, 0xd00f3e2d, 0xa62fdc91, 0x69fb0022, 0xc940ca7f,
- 0x98bd0328, 0x84278f0e, 0x93df93ca, 0xfb870881, 0x7ddd1863, 0xcde94319,
- 0x24a79111, 0xee903940, 0xa69c65c3, 0xca271b8b, 0xe3f67f6c, 0x4f98bebe,
- 0x88b35175, 0x2c6a4d74, 0xbe742181, 0x1fa2cd9d, 0x6e6a8bf2, 0x9fb8880c,
- 0x98823d32, 0xffbe0849, 0xada8d375, 0xd31975da, 0x7b52d5c5, 0xbaaf869b,
- 0x3224fbe5, 0xafce82bc, 0x5c608802, 0xe54edf24, 0xf872a134, 0x90c79524,
- 0x5e98969e, 0x71ca8a72, 0x37cb4c32, 0xe25e982b, 0xa70eef27, 0x9f09fff3,
- 0xc199bb7f, 0x10997dbb, 0xb97ff800, 0xf20c8971, 0x9db5716c, 0x8f323d02,
- 0xf0a78e72, 0xf5004b5e, 0x001dba29, 0x5642ee7c, 0x03c3e424, 0x502ebcb7,
- 0xb6bf2d3d, 0x3dddae8f, 0x853ab024, 0x61b85fd6, 0x5d3700fe, 0x96599cff,
- 0x4fec2231, 0x84cfdbc4, 0x99fa4c7c, 0xd59909b2, 0x47ea51b4, 0x92cd7733,
- 0xda69b64e, 0xf3e9f6cf, 0xf9f40a73, 0x9920294e, 0x14299f40, 0xf7ed1d48,
- 0xb97d0ade, 0x2134ce3a, 0x8f95e19e, 0x830a13f7, 0x5ee9fa54, 0x67c0c748,
- 0xae75e237, 0xe755b59b, 0x44a0fe53, 0xb71fb842, 0x7fc41225, 0xb9f3d622,
- 0xf38dbad9, 0xbd592b9d, 0x733e74b9, 0x9e11101f, 0x1db7f9c6, 0xa34d7bb0,
- 0x99fb5a69, 0x5c682404, 0xf3fe718f, 0xe3d71b96, 0x987f6196, 0x677e37ef,
- 0xa7a46274, 0x8f89e6f2, 0x53d0d29d, 0x8f47f069, 0x2bb4d29d, 0xcba9986e,
- 0xeb660617, 0xced7e7ea, 0xae2f95d7, 0x2f95d42e, 0x9744b75c, 0x407fef9f,
- 0xf2de7f57, 0x7bf2ba15, 0xcaebd62b, 0xd46c14e7, 0x9efb67e5, 0x6bbfd5d4,
- 0x5cae9d56, 0x4d785038, 0xdf55ca1b, 0xb7a0a935, 0x4021607e, 0xabbd2a8f,
- 0xea8670fc, 0xa39e902d, 0x2ba40b7a, 0xff294f80, 0xb4b2f69b, 0x6bfceb7c,
- 0xfebd1adc, 0x069154b4, 0x7ba464fc, 0xf48d3c23, 0x45fa7f4d, 0xb4d487db,
- 0x20b92044, 0x7ef8bae7, 0x5ebf7eae, 0x647a7130, 0x7e129de7, 0x95d9289e,
- 0x3bce093a, 0x68687225, 0x7ef7a385, 0x75c05049, 0x13d2d010, 0x5a946f01,
- 0x6e2b7035, 0x679ba418, 0xc71141c7, 0xa5de032f, 0xe4832ff2, 0x0f200b36,
- 0x6ed38742, 0xf1f3051f, 0x4cf905ee, 0xff71139a, 0xf69ca8ed, 0xe00929d8,
- 0x99e98b97, 0xb69859ca, 0x3d30fa57, 0xe9805955, 0x4c0acac9, 0x63972adb,
- 0x8fd2bc7a, 0xd72a5fe9, 0xcaa7fa61, 0x558f4c6a, 0xc7fa62d6, 0x9da600ca,
- 0x554c5e95, 0x9396edba, 0xe56f5cb9, 0x81fa0be7, 0x2d7cade9, 0x15bdfd22,
- 0x0293d1f9, 0xf1c178fc, 0xcbd050e5, 0x48a31c2f, 0x5e1def4e, 0x15e87a46,
- 0x7a8bc4ae, 0xe2805e45, 0x72cf4fb9, 0x93c30c5b, 0x11a644cd, 0x0fd6372a,
- 0x60b3d679, 0x24cde624, 0x3c07da1e, 0xfa519d33, 0xe0147ba5, 0x22784aeb,
- 0x3868f0de, 0xf53fb70f, 0xefd0599f, 0xb640c2f5, 0x71161e5f, 0x67a124bf,
- 0xefaf803c, 0x95e1370a, 0x6f80d30f, 0xf0aa27ce, 0x34234d6b, 0xb1b8225d,
- 0x164d0bff, 0xb6380662, 0x847003d8, 0x19e470bd, 0x4b77ec17, 0x53eac453,
- 0x57877b63, 0xdabd3069, 0x794f59a1, 0xa17f3eb3, 0xcec6985a, 0x1dec4af9,
- 0xdcae80a3, 0x0086a7d5, 0x553053fe, 0x229a59fb, 0xb9ea38e3, 0x21c63496,
- 0x2173d29d, 0xcf67fbd6, 0x227eb7a3, 0x1f2268f3, 0xbb01d853, 0xe5741e5c,
- 0x7c0f4bf3, 0x73973f9b, 0xd22d4f01, 0xc79fb097, 0x07977fd0, 0xcc66bf42,
- 0x0796fdab, 0x7ae5bf45, 0x1ba8def8, 0xd453b68f, 0xebb43733, 0xa4cd5e9d,
- 0x15275d5d, 0xdedc196d, 0xab60dc52, 0x38fdcbd6, 0x39bcbe5d, 0x0fb75ab5,
- 0xef942fc0, 0x06608149, 0x54e129ba, 0xac7665d4, 0x1cfce813, 0x2dfb0526,
- 0x52bd5817, 0x53ec9b6b, 0x415b0c90, 0xad90580f, 0xd7729dd2, 0x3e5ca99f,
- 0x3c897bfb, 0xeedce50c, 0x2547f6a2, 0xfcd13130, 0xd05b9e42, 0xe41d3c54,
- 0x373dd9dd, 0x88b0fea3, 0x10e0bae4, 0xb3aa4053, 0x4f390f40, 0xee80d34c,
- 0xb83f93cf, 0x03ce6ac6, 0xce324c73, 0xfd3ae167, 0x27f5483e, 0x56bf3e5d,
- 0xb723cf9f, 0xe79d0125, 0x202448d5, 0xcbea3f00, 0x7e31366f, 0x6b1527c8,
- 0xc5587f60, 0xdc0b13cf, 0xf28fdcc4, 0x5b4be97b, 0x79d3e6b2, 0xf931302c,
- 0x0bdf9ead, 0x511e99e3, 0xc193ac14, 0xd371f39e, 0x40dc9fd8, 0x0d607da0,
- 0xbbfc31d8, 0xa536cf05, 0xebbefe27, 0x55f38dfc, 0x761e8ff7, 0xd28f3e04,
- 0x881bc106, 0x98548fb2, 0xf8ffbe04, 0xeb097e99, 0x1b99e8d6, 0x435af90c,
- 0xff90debe, 0x812de9bb, 0x61cde8e8, 0x25306df2, 0xfd02fa32, 0x6587304a,
- 0x7fd23fdf, 0x6bfe8f4a, 0xf7fda9ff, 0xe967fda7, 0xa7ffaffa, 0xc7b83ff6,
- 0xfad183fc, 0xc7697d2f, 0x37953f1e, 0x726e2f45, 0x9cffba11, 0x79275735,
- 0xb64bfe28, 0xe2fb46ad, 0x05dfb319, 0x20367cf4, 0x39440b4e, 0x71369f57,
- 0x3af125bb, 0xc0f73804, 0x73ffb4af, 0x067cffcf, 0xdcbe5b9c, 0x3cf1b926,
- 0x590960d3, 0x35969f28, 0xa3274e15, 0xe5827f31, 0x422a7ed7, 0x9f4f59be,
- 0x4a6dcf45, 0xa51bfb02, 0x87efae14, 0xab2a5f50, 0xd854ebff, 0x1849ca7f,
- 0x0ed8ccf9, 0x8f18bfc6, 0x1cbe71f2, 0xce9cb3db, 0x72f0f513, 0xa6f2970e,
- 0xba2a7f9f, 0x69d1fd20, 0x369317b4, 0xed8d93d4, 0x73feb80a, 0x684ce4cc,
- 0xf91eaaa7, 0xc81ef91e, 0x242e154d, 0xf11ff4c0, 0xe1a32da5, 0xff51dafc,
- 0x81a0977b, 0x176fca97, 0xfd7f0b82, 0x5cbbd2b2, 0xb1e7e4ee, 0xb600bb48,
- 0xdeb99a53, 0x12d2c2d6, 0x7b02e429, 0xe49d4969, 0x25cfd3f1, 0xf6799e3b,
- 0x7e4f3829, 0xa10cf160, 0x78ef17fd, 0x34398fed, 0x4a53bc5f, 0x4049ce98,
- 0xa7e08a48, 0x3e5bfe9c, 0xa28f8226, 0x2b26bedf, 0x87f7d8a3, 0x297823e2,
- 0x265079de, 0x63c27aa3, 0xdca0f072, 0x9f8288e6, 0xa0a989e0, 0x7d2f895f,
- 0xcffe0323, 0x7248101e, 0xd678147a, 0x027a86bd, 0xc9f109c0, 0x3f8dd5f1,
- 0x8a72fd43, 0x46eb9017, 0xedeb197c, 0xfa05f2e5, 0xa521fb05, 0x065e17ef,
- 0x2c9ff33b, 0xc143801e, 0x60b9f70b, 0x15cda73d, 0xacb7ce8c, 0xf1d2f24e,
- 0x927f240b, 0xbdf6531b, 0x229fe9e0, 0xf3bfe5fd, 0x7e7624d3, 0x709aa6f3,
- 0xc2a7f2af, 0xbe6f173a, 0x4799d713, 0x0587487c, 0x905cc45b, 0xc9985f97,
- 0xf8519db4, 0xe4c89e64, 0x14ade9e6, 0xa79d74b9, 0x768436e9, 0x81883fd7,
- 0x58bf686d, 0xfc1e4042, 0x9397b554, 0xc2ff98a5, 0x4e35f0ca, 0xaa7ef554,
- 0xb7e969f5, 0xe02b6d7e, 0x6f00dce9, 0xcabdd832, 0xe1cfd989, 0xfda65c21,
- 0x94dcef8a, 0x1444f0cc, 0x476f1673, 0xf0c982f5, 0x4ab7ea1d, 0x5d68db5e,
- 0x3d39723b, 0x3e32fe32, 0x0c779d3e, 0x93a7e7ec, 0xca304148, 0xaa8836fa,
- 0xbafba01c, 0xfc34ce86, 0x7ebff8ce, 0x9577e33d, 0xa73303ff, 0xefe7f941,
- 0x76823e32, 0x79d25fb0, 0xfcb19285, 0xca021de0, 0x45090b07, 0x897af3e3,
- 0xdcbeb9f3, 0xfe742f48, 0x43562166, 0x3c4e3037, 0x5eed01e2, 0xbdb43579,
- 0xb8c2ae56, 0xaafd9eae, 0xe5cf9c7c, 0x9522ddc1, 0xe445d707, 0xe4ccd901,
- 0x977aef40, 0x2258f11f, 0x0a7d9e05, 0xabf297f8, 0x95fe015f, 0x9ffd6172,
- 0xe3fe1e34, 0x3e6f94dd, 0xab7caa09, 0xbe46ab97, 0x2e35d82d, 0xb27edf2a,
- 0xdf3a2321, 0xf951efd2, 0xdbe30376, 0x5572d7ff, 0xa8956385, 0x9caaab97,
- 0x469e0dec, 0x2a269939, 0x9ca35708, 0x92ef3fa4, 0xa8f49eac, 0x7f4aa1d2,
- 0xbd29bf45, 0x3751e406, 0xd874aa9d, 0x1d2aa74d, 0xe89fb0f6, 0xbf2c68e0,
- 0xd2826819, 0xf7deee4b, 0x78a3f6a6, 0xf761692d, 0xebddb450, 0xf2f0a790,
- 0xaa4736e2, 0xa097ef5f, 0xf90c07cd, 0xd7bea1a0, 0xd435cf90, 0x15f219f7,
- 0x6601fa86, 0x2c3e683f, 0x9087a413, 0x92b4beae, 0xb7609df8, 0xdda22fdb,
- 0x79ce8bae, 0xd5df6d0d, 0x53f01e98, 0xc6dab0f9, 0x44e18fce, 0xb3c80d79,
- 0x15d8772e, 0xd31b790f, 0xc372bb7b, 0xfe8d38ae, 0x4445a278, 0x2016dc79,
- 0x8cf6b4d3, 0x21545f08, 0x6f48dafe, 0xd90ecce5, 0x77eec315, 0x691d126f,
- 0x59dce1cb, 0x19287a2d, 0xee2b4590, 0xba898172, 0xadd065ab, 0xc5f7e8b3,
- 0x5aec886f, 0xa735efc4, 0x670dce6a, 0x09f1ff88, 0x6d97dc02, 0x6c2ffc40,
- 0x4588e761, 0x73d3a21b, 0xe7976f11, 0xdc832658, 0x49fffaa4, 0xed559dad,
- 0xe1b360a7, 0x9ccdcb7b, 0x3cf1abee, 0x2faf5457, 0xd0f3f1f7, 0x647e5549,
- 0x1f940c90, 0xf381d070, 0x37bb9738, 0x9d6f2389, 0x75d0f145, 0x37402444,
- 0xc4445a17, 0x764685c3, 0x89fc495f, 0x24653fc8, 0x854ef28c, 0xc7f00757,
- 0x50e5deb0, 0xb30feec7, 0x4a55a41e, 0xf479fcf6, 0xb1da68af, 0xfba183e7,
- 0xfbd2ff20, 0x3d267f69, 0x603e4feb, 0xd76e3b43, 0xbbde2701, 0x337fed74,
- 0xefc841ed, 0xbef078b5, 0xa357c0f9, 0x56ba8e81, 0x8e400a5a, 0xf7600d75,
- 0xbffb55f4, 0xfb86dd1a, 0x9fc42ae7, 0x5fceccd3, 0xf3fe5a17, 0x5fb3dc38,
- 0x02aba168, 0x1d80e0fd, 0x2fe5e1ed, 0xd08ed0db, 0x2cabffb5, 0xb79fe39f,
- 0xbf7e329e, 0xb324e5d2, 0xe2fcc176, 0x7cba5d98, 0x5667f8df, 0xd373fdc0,
- 0x2d217941, 0x37cafc9f, 0x763e41a3, 0x4f7a62ed, 0x34f6d4a7, 0xaca41fdc,
- 0xa242b4ba, 0xe604ee70, 0xf94f4be8, 0xf92672ab, 0xcb834647, 0xb91f6837,
- 0xff5c785a, 0x021e063f, 0xb49623de, 0x01560338, 0xf8e97dd6, 0x1c1e419f,
- 0xaa5d20b0, 0xb824fdeb, 0x2b91f502, 0xac067bad, 0xd37ff13b, 0xd5d085ba,
- 0xbff4bbac, 0xe33fbe39, 0x0f91a8fb, 0xfef9d27a, 0xc3bf31fb, 0x5ef9c1e9,
- 0xe2ffbd25, 0x77de1b7f, 0xaebbbc51, 0xffc6eebc, 0x1deeebe6, 0xe5cc6fef,
- 0xfdc37778, 0xdf2bf97b, 0xabbefce0, 0x3ffa3b9c, 0xbeaafd74, 0xf2933bfe,
- 0x3fad066e, 0x403b548d, 0xe951f8b1, 0x683237a1, 0x1ffaefe9, 0x4ef9838e,
- 0xc635f7e2, 0x66637df9, 0x7049bee7, 0x25c7436f, 0xef3f0271, 0x3f5273b1,
- 0x5bf45fae, 0x487a8796, 0x40bffebf, 0x9598827d, 0xfc0fb81a, 0x0f42da5d,
- 0x319036fa, 0x77907cc7, 0xfaf3c8df, 0x04afe2f3, 0xcaab85e2, 0x1f37697e,
- 0x7fb53d01, 0x58f5117f, 0xfafea29a, 0xfb1a6baa, 0xceeb225e, 0xf4523f33,
- 0x09a99be7, 0x14d073fa, 0x844ddfde, 0x8726ffcd, 0x38500810, 0x58f01a4c,
- 0x2743d802, 0x4088910d, 0x6f8953f3, 0xa61b9c15, 0x7dfdf438, 0xe3c4f700,
- 0xb7cc7022, 0x7f022dee, 0xc047ab3e, 0x987586fe, 0x33589e50, 0xe183a405,
- 0xbfcc66b5, 0x038f7263, 0xe1b8cf38, 0x201e4fa5, 0xcaf55760, 0x65cba14c,
- 0x2faff1f6, 0x05909e5f, 0x03f66fe7, 0x50b778fe, 0x66d17d7d, 0xeba18a12,
- 0xfe266c5d, 0x8bb078d8, 0xcea4e40a, 0xc3cfaa2e, 0x2293f7cf, 0x7ea95cfd,
- 0xcff8746f, 0x74a25f4e, 0x2108727f, 0xfbc5217b, 0x53cf662e, 0x6bdf57cf,
- 0x3f2af061, 0xd903024a, 0xab98b8bd, 0x2c5a3fb9, 0xe97bba31, 0xc2c6bb2f,
- 0xd76266b9, 0x8fc658c8, 0x904fcc99, 0x881797eb, 0x0071eb12, 0xc58a0e3f,
- 0xa223b17b, 0xd9df9a33, 0xfade7e76, 0xd297dc0d, 0x549eabb4, 0x93f7a08b,
- 0xfcf9da30, 0x2db256f5, 0xae427f8a, 0x382ddaa4, 0x988fe8de, 0x367af605,
- 0x34da62fe, 0x8eb78b56, 0xa3cd67e9, 0x7e01e27b, 0x2bee6a4e, 0xc2f851fe,
- 0xbbe00ef9, 0x3536d6dd, 0x2edf0a37, 0x633d9890, 0x784ba1c6, 0x52d11ebe,
- 0x1f3e0267, 0xddd26f51, 0x712dddbb, 0x190c7dfd, 0x719af303, 0x04cce6c8,
- 0x3d111cbc, 0xde57efe0, 0x8beca9f2, 0x84646f72, 0xf60ff427, 0x8dc95ad6,
- 0x8293eee3, 0xfbae010b, 0x9c095bce, 0xd5caf6b7, 0xe9e6d1c5, 0x2e79b0b0,
- 0x46fbc126, 0x83f7ffa7, 0x472ec4ef, 0x579c1268, 0x75f209ea, 0x4823fa4f,
- 0x481a17c7, 0x9c31e400, 0x5c2e406f, 0x1fb82468, 0x02fc9050, 0xdf946bce,
- 0xc73da07f, 0xf9de6b0f, 0xca47d81b, 0x9837045a, 0x6dcccba0, 0xcaedd832,
- 0x9044e39b, 0xea8a19db, 0x751ee90f, 0x6a2f8687, 0xebc23325, 0x39bece70,
- 0x1d67ee30, 0xcd7d8132, 0x05d86afb, 0x96b3ff72, 0xbd07c8b1, 0x95b7ebad,
- 0x048a68a4, 0x6ba410fd, 0x6c8c3d23, 0x6fe5d18c, 0x817d7d10, 0xda5866bf,
- 0xe0a27996, 0x7c66472f, 0x2df2d57a, 0x7c99fff0, 0x6f95577b, 0xc357313e,
- 0xd1992647, 0x25be46bd, 0x4b6f9347, 0xe0192505, 0xa0ff74be, 0xd2ebc064,
- 0x68c4a437, 0x25476df2, 0x917b07bb, 0x3576b1fb, 0xbd76f951, 0x5135be46,
- 0x4fc516f9, 0xf13243a0, 0xf20aedfd, 0xc35ff02d, 0xbe403b7f, 0xbe67a345,
- 0x6df2a83f, 0x9409cb74, 0x4c9ba36f, 0x2fccff3a, 0x84df28af, 0x9f403bc4,
- 0xec79223a, 0x0767e851, 0xe45edfd7, 0x0e30367e, 0xb271b9c8, 0x5abfc71b,
- 0xb5729739, 0x08bfee72, 0x5b9caace, 0x9fa09bba, 0x643a4f6a, 0x5ee96e72,
- 0xa004e72a, 0x96e72647, 0x8ecc27ee, 0xc36f9063, 0x8237c87b, 0xac42cbf5,
- 0xfa73797d, 0xfed0f713, 0x8f2578c6, 0x131fd695, 0xb4e37791, 0x6c9c6ef2,
- 0x90f73846, 0x4eae4777, 0xf2e6edde, 0x81b1ca8e, 0xf48d5f20, 0xfbd169e1,
- 0x7f1beeff, 0xc0b7f1ba, 0x788a6f2f, 0x898ef50f, 0x35bc17dd, 0xd02674fe,
- 0xc99906d7, 0x7b971f5f, 0xec7e959d, 0x6cabf27f, 0xec8da57d, 0x1359413d,
- 0xeacb0fd3, 0x7f4280c5, 0x09739a9d, 0xf70a93ef, 0xe699240b, 0x1faa5a67,
- 0xfd3e8077, 0x3eb8449c, 0x43433d3d, 0x8bb28b0f, 0x655bced1, 0x94256d73,
- 0x8999178f, 0xc5b9ec15, 0x4167a98e, 0x66ce2d9f, 0xfe62dff6, 0x544bf55d,
- 0xf78d33fd, 0x4bcd79e9, 0x7a47ef5e, 0xb0cfabde, 0x78cebc30, 0x1f800846,
- 0xf67bcf61, 0xe285ca00, 0x15f7fd06, 0xc533fd7c, 0x79178436, 0x8b6cf45b,
- 0x8c2b3fc2, 0xe1c23a70, 0x83a2e144, 0x0a884053, 0xe9e98a27, 0xb8114919,
- 0xb6d9be14, 0x85c0ec06, 0x6f780a4f, 0x0ab75c68, 0x55fae337, 0xd176aa38,
- 0x7e5fde62, 0x33be1d4b, 0x8545c231, 0xdd1e11b3, 0xa3c03770, 0xfff6e64a,
- 0xfc16320c, 0xa0dd2858, 0x9bfff19c, 0xb90ffe88, 0xdee88713, 0xf2e7ac43,
- 0xc4f56c7f, 0x3ddd70c9, 0xe182fc13, 0xc976ae3e, 0x37dfe0eb, 0x063298ee,
- 0x721bd3b6, 0x97b83e2c, 0xa30b6edb, 0xf0e9541c, 0xcd874e23, 0xfafbbe1c,
- 0x73c24c56, 0x06e0b361, 0x643ca43d, 0x5396b843, 0x2ad1b47a, 0x72fc9f87,
- 0x1bab872a, 0xf334bbdf, 0xc1e289fd, 0x751fe704, 0xf7b00abf, 0x185b6331,
- 0x181bca5e, 0x1849325e, 0xb565efed, 0xd7442782, 0x04bcd653, 0xf95582fd,
- 0x5a1c7f4c, 0x5fa1453c, 0x25fa3473, 0x8acc9c60, 0xbcc59bec, 0xf54b0cde,
- 0x3f9ec11f, 0x1d47f283, 0xdffd2192, 0x95f7d0b7, 0xf88c45fc, 0x6dc390fa,
- 0x01d5c007, 0xfd330bf0, 0xdf09742b, 0xe5e5a8cd, 0xae0ebf66, 0xc8ba9f93,
- 0xa0bf6fe8, 0x1ba51d80, 0xb4cf406e, 0x370a9c7c, 0x43c067a0, 0xf2117ccb,
- 0x7dde1479, 0x17ae7bd2, 0x7cb4c7ee, 0x04ffb85f, 0xe08b7feb, 0xfdd65121,
- 0x3bfbe99d, 0xfc6f75d2, 0xbe8191fe, 0x8f85b2df, 0xdefa058e, 0x93df202f,
- 0x3dfd3896, 0x4dcecc97, 0x0f946ddb, 0x0de61ee0, 0xe955b3c9, 0x1cc21f29,
- 0x509e70ce, 0x6b927634, 0x57e02161, 0xff4560d8, 0x40c79c30, 0xe56aafa6,
- 0x491b0ef5, 0xf7b323bc, 0xf9c6fffe, 0x497d37ac, 0xf1828fcd, 0xd3368e40,
- 0xc64786f1, 0xaa17ee33, 0xeb4ae01d, 0xb1fe5bb2, 0x7ce3a975, 0x7299ff57,
- 0x28f78ad2, 0xc38d1faa, 0xe0942be4, 0x304d3afc, 0xc2d1fdeb, 0x70ffcf1c,
- 0x2dfcb2ff, 0xab1493fd, 0x4de2fdee, 0x29f883a2, 0x4af33edc, 0xcb542fc8,
- 0xec026f78, 0x3ee8931f, 0x8ecf9348, 0x1eff7b8e, 0x5ef1172c, 0xfb37d6e6,
- 0xd5bdc294, 0x8a67ccad, 0xa0219adc, 0x740ef0fe, 0x70f41e36, 0xf85af12b,
- 0xfb3cb490, 0x7801717b, 0x5f519067, 0x7ca1593d, 0x5021a63d, 0x7267a905,
- 0xc02de138, 0x009144d7, 0x7dbd5abe, 0x7bfec326, 0x06495fdf, 0x9ea8ce98,
- 0x398cfd80, 0x5ea11242, 0x8f11378e, 0x3e9be333, 0x3a76f77f, 0x4547f1bf,
- 0xcdeb428f, 0x0070ec3c, 0x6cdf0d9f, 0x5c0d3e22, 0x0aa04872, 0x4fe347ec,
- 0x79076f79, 0x1ef54050, 0x682ff7f0, 0x4172aba9, 0xed80b37e, 0xa9befdcb,
- 0x1dbf3a2e, 0xbd4e9fb5, 0xad02e40e, 0x6f94dd07, 0xebcaf566, 0xb2b80f05,
- 0x946cb5e6, 0x0bd46e51, 0x476ca0f8, 0xd6562040, 0xfb4ac06f, 0xb699b1dd,
- 0x8bfd84cf, 0xeb7e87b6, 0x76f77d3f, 0x9e743b90, 0xdd91bed8, 0x76d1e6cf,
- 0xfd49f00a, 0x70afec12, 0x5de040b3, 0xdb234142, 0x4a8e0a9f, 0x3a6f281e,
- 0xbbee24f8, 0xa978e9d3, 0x851fb0e9, 0x8efbe0a6, 0xdf1b82b1, 0x43494dd5,
- 0x0b05d5b9, 0x01d60686, 0xe05cbeec, 0x51fe7e79, 0x2d37bff5, 0xcf377fcc,
- 0x43ee42b3, 0x3b2b79fb, 0xf484dd31, 0xfa0ca9f4, 0x6f0a29da, 0x3bf7851f,
- 0x70e17fdc, 0x9b72c7f6, 0x673c7f66, 0xbff48419, 0xfa2279a8, 0xb9262d4b,
- 0x633faf78, 0xdf3bd33c, 0x0016d1be, 0x52dbddbb, 0x3f7c3fb8, 0xbf05a37c,
- 0x7260ee77, 0x1b4073b8, 0x6f4f69da, 0x47bc0896, 0xa22cdaa8, 0x28dd389c,
- 0xb8b5fde1, 0x9db94245, 0x21e983bf, 0x7eb33787, 0xfd30374f, 0x3b96f26d,
- 0x9c3ec2a7, 0xefbd4dbf, 0x3d5a7266, 0x0bb9e687, 0x519bfb75, 0xb872aace,
- 0xa0a3c394, 0x5fef0eba, 0x54b7728d, 0xf20d0fdd, 0x65ee14b6, 0x8435fef1,
- 0x341a547c, 0x983913fa, 0x0d73863c, 0x12e843d0, 0x51d977d2, 0x46b9c089,
- 0x2a63b8f8, 0xec2ce7ac, 0x7c7cb4f7, 0xfb85e08b, 0x966382f0, 0x81e3ea00,
- 0x15fef3f9, 0x2c0f99f6, 0xbfc05044, 0xca83e29d, 0xf84b6ca9, 0xefd18f2f,
- 0x82b1df67, 0x9fa508a7, 0xd57f08f9, 0x1b73342f, 0x7cc8f3f3, 0xde0926a7,
- 0x7d29927f, 0xd7e40e50, 0x91a7c48a, 0xef05671b, 0xfdb377ed, 0xfff5adc1,
- 0xf3ab94cc, 0x6fed9f60, 0xd951f265, 0xddfbe126, 0x447cfcc3, 0xb7e80bcf,
- 0x6377b859, 0x87a1ac92, 0x931bfdc2, 0x6b20e8a8, 0x15447fb8, 0x285bf77f,
- 0x0f0a71b3, 0xcd3aee08, 0x6a3f6a38, 0xd65ef2bf, 0x967ed06e, 0x217fd6f6,
- 0xf9d70fcc, 0xc3720c85, 0xf18f4fd8, 0xfb27e97b, 0xc0d62fdf, 0xb7eced3b,
- 0xce6e7445, 0x20fa78fe, 0x9a80bded, 0x590c7eaa, 0x57889aef, 0xbfecbf03,
- 0x06af10c4, 0x28e34ddf, 0xddfc53ff, 0xb9f4ccd2, 0xe42771a6, 0xbbcc4cd2,
- 0xb8cbdf81, 0x0a6cba3d, 0xca69efbb, 0xf0156778, 0x014cf4ff, 0x7df881e9,
- 0xd4049f72, 0x4ff014df, 0xed64cfce, 0xe07b69f3, 0x1927a6cb, 0xa179529f,
- 0xdb293c80, 0xd62a71bc, 0xe81417af, 0x3e6ea9bf, 0xd90525ea, 0xfaf2c122,
- 0x1527a813, 0x00489f34, 0x5bfca67e, 0xd940fa03, 0xc41b8b04, 0x2a97cab1,
- 0xfdcdbf9f, 0x3dd58989, 0xcbf8fc0a, 0xf0a2a980, 0x709478b7, 0x65f195bd,
- 0xdbe33679, 0xb04877b7, 0x73e1abc2, 0x8f956be4, 0xcce3e045, 0xde1f1f08,
- 0xbe06593c, 0xd0101d3e, 0xc83262ef, 0xedf3e001, 0x31efb702, 0xf96af63d,
- 0x667a4afc, 0xd85fe529, 0x573e552f, 0xcfc8daf9, 0x3bb6e6ad, 0xddf71e60,
- 0x4c75c368, 0x3fdefefe, 0x15e4c7de, 0xfe4dd7de, 0x204903fe, 0xccccf31f,
- 0x6b8547af, 0x81f999a9, 0xcd5798f5, 0x6af5390a, 0xc79867e6, 0x5ede8b46,
- 0xc712d872, 0x25eb9dfc, 0xf12bfba4, 0xbb3e0f67, 0x5abcfe4a, 0x7f12babe,
- 0xfb8be3aa, 0x061cfdf5, 0xd9eb8e20, 0x6385275f, 0x77f1c288, 0x5fa0cf8d,
- 0x4fe7f9d9, 0x143c00cc, 0x0e74a3ef, 0x24e8d5f4, 0xe6739021, 0x455bee00,
- 0xfd17a24d, 0xaca1cd65, 0x3e5a9ddb, 0xc53ffe66, 0x9e913a2f, 0x0259768a,
- 0xa2fb69d3, 0x468f1f3d, 0x61958c3f, 0x3ff24ff4, 0x7f65f5cf, 0x83e068db,
- 0x43f33322, 0x9985ca32, 0x773fa656, 0x82cfb5ec, 0x2c0d09f5, 0xf05140de,
- 0xb9a2c92e, 0x956698a7, 0x2f787ad4, 0x0c74a7e8, 0x7e6131ef, 0xaaee77da,
- 0x76c751ff, 0x9a8a2726, 0x2dc400a5, 0xd9d86a28, 0x45a5fe09, 0xff682cc7,
- 0x14f86f2a, 0xbf27e7fd, 0x2bed03b8, 0xeea2cde5, 0x3f87ad3e, 0xb218835f,
- 0x535a1f80, 0xd1ffde29, 0x07cc09fc, 0x77dcffb9, 0x7e2b37f4, 0x3f1eff71,
- 0x6ff16105, 0x7c81739f, 0xcdbad739, 0x0d7d7e85, 0xdb5feedf, 0xb82f7fc3,
- 0xddeffb9e, 0xb9e09a72, 0xdeffba26, 0x3285f839, 0xbd5683ca, 0xe8691eff,
- 0x9d25fa83, 0x946e5667, 0xfd6e8ffb, 0x4f17c77c, 0xc779ff83, 0x869e4fae,
- 0xedfc9779, 0xafc1a7b3, 0xe1b01c88, 0xfcfe57be, 0xabafe87b, 0x6564dbb6,
- 0xfdb9da74, 0xee77f439, 0x81e2c0fc, 0x9ff73ade, 0xb2ff034e, 0x92979dce,
- 0x6cb99ec0, 0xef684dff, 0x727bb65d, 0x6fb28932, 0x6fd029a8, 0xadfc2ae0,
- 0xdc3b788d, 0x9ffd1874, 0x83bc53ce, 0xcbf6ec1c, 0x7f32960c, 0x63fb8557,
- 0x6ff74636, 0xd97fe1ef, 0x37adfb74, 0x626ffc82, 0xfd15e4fa, 0xf8a5df30,
- 0xf02afebc, 0x6dfdc8d8, 0xab7cb783, 0xf879e61f, 0xc9abe285, 0x9a2fc780,
- 0x29faff16, 0xd3ea6b28, 0xe8661fab, 0xfaa7e02a, 0xdeadfbcf, 0x6fc0ac57,
- 0xfe837ebb, 0xe9bf80af, 0x5f47ec0a, 0x83fbc1a4, 0x2e785233, 0xfde13fec,
- 0x52bf8c16, 0xe47dffb4, 0xefddcea7, 0x709a9da0, 0xd24ef63f, 0x8dfcc3fd,
- 0x7adebe05, 0xe4dff327, 0x4eff0078, 0xb9df85c5, 0x6ba3271f, 0x37b3bfd5,
- 0xacafcebf, 0xfd56ff4c, 0xffeb4bfa, 0x2324fdcc, 0x01b21378, 0xf5be275f,
- 0x070a823d, 0x11cb9737, 0x7ee8e5bf, 0xcb7eddb4, 0x3e01bc06, 0xf6ea9f61,
- 0xfef9a64b, 0xf24ed063, 0xf83f347e, 0xefe63ace, 0xdfe929dc, 0xc4f0468f,
- 0x0d5823df, 0xab81cbfe, 0xd2be5ff3, 0x9c2bbe3a, 0x3452824e, 0x3abc27ae,
- 0xdf2e8ebe, 0x3fc26d13, 0x916d5ef6, 0x931f7c60, 0x7f044b60, 0xcf681390,
- 0xf37f3eec, 0xfb7076f5, 0x22f3c77b, 0x09aebffa, 0x6ef9461e, 0x10651f94,
- 0x7cca2347, 0xbe98d987, 0xf6ccd65e, 0xce5d8e8f, 0xd3f68380, 0xd22f6871,
- 0x09e35975, 0x7bfb4fd9, 0x32b7e1bd, 0x7c62c7bb, 0x4047fb04, 0x178e9eb3,
- 0x7e668e0e, 0x6fdeccda, 0x1f1c671c, 0xfa25bca7, 0x9f8de538, 0xf629c6ea,
- 0xe3b76507, 0x339de3ca, 0xfe82ef7b, 0x3d32b5ce, 0x9c505cf1, 0x587ded16,
- 0xf7e24d8a, 0xa52cd561, 0x25c628fb, 0x2438b271, 0xf5062ba2, 0xecce65ce,
- 0x9009b163, 0x5407e8ca, 0x0dfb82b5, 0x0293ccfd, 0xfe72aef8, 0x577cc098,
- 0xf6357c03, 0x23edc91f, 0x294aafa0, 0x776099b9, 0x391dca30, 0x1a0244c1,
- 0x4e732f7c, 0x5ef0564b, 0xf01fd424, 0xb4e33c79, 0x647efd04, 0x647d5fb0,
- 0xe9926b26, 0x0bf23efc, 0x5fb4159e, 0x03c7f5f2, 0xfb3d9d72, 0x87bef357,
- 0xa9bd9d44, 0x0e3e12cc, 0x8af215e7, 0xc423ef0d, 0xe78c3603, 0x0db4fe50,
- 0xf7787bd7, 0xdea2cf57, 0x610b6bfd, 0x54f443f7, 0xdca47103, 0xbbd38fac,
- 0x3ffa7abf, 0xc686af41, 0xa7fcfc74, 0x4f387d69, 0xfcf1da34, 0x762bb5d3,
- 0xafcfea34, 0xe403383c, 0xd19dbe5a, 0xc98bfe63, 0x5fda2a81, 0xb7cb227b,
- 0xf18018ef, 0x39778a03, 0xf0f11fd1, 0x60ca97ee, 0xd17cea9f, 0xa4066e0e,
- 0xffae15f3, 0x3bc786ff, 0xad1495aa, 0x3121725f, 0x2077da2b, 0xe56790c5,
- 0x7f049ef8, 0x811f38b2, 0x1639ab1d, 0xbd508fdf, 0x79cfd758, 0x07bf7c29,
- 0x97dfd8e9, 0xf5099bbd, 0xac607905, 0x1fff96a7, 0xe5b7931b, 0x11ceda16,
- 0x872e5fa9, 0xbabe58f3, 0xad27932f, 0x2ae7ff58, 0x9ef2f39d, 0xebfab2fd,
- 0xf575036d, 0x3c65f6d4, 0x7e9188de, 0x16fde71f, 0x2c337c37, 0x288d3c5a,
- 0x3fefc7f3, 0x04df8815, 0x1b4ecb7a, 0x778251c6, 0xbf0fe0f8, 0x5ff76647,
- 0xc610ae25, 0xe5c7d933, 0x084c4971, 0xe5f4abe3, 0x90fa80f3, 0x17b6d627,
- 0x2fa5ef00, 0xe7c408d9, 0xe9c57d29, 0xee977c05, 0x57fdaaf9, 0x66efe099,
- 0xe95ebb47, 0x7482ff2b, 0xcd096a50, 0x3b6578c5, 0x99e2042d, 0x237cec75,
- 0x43b5f80d, 0x7fc5a50a, 0x695ebdcb, 0x478862d0, 0x52efe7e0, 0x7de18303,
- 0xb33efabd, 0xd33917a8, 0xdef76365, 0xbdde6cfb, 0x7d77e436, 0x95739edc,
- 0xefb483cd, 0xe8948bb4, 0x9b4df172, 0x69d977f4, 0xa3b8e5bb, 0x37c73bc7,
- 0x49e73e61, 0x2018126b, 0x0e3ea8cb, 0x21a8bcf2, 0x0fd83fbd, 0x77d4d90e,
- 0xec2c4aec, 0x05248747, 0x0687d9cf, 0xfbb5fd28, 0xab4a99cc, 0xaed09662,
- 0xdd576983, 0x097d79a7, 0x66da27f8, 0x1f7b9345, 0x8f08ecd9, 0x1bc5ab22,
- 0x07649ded, 0x02deafdf, 0x1b224063, 0x1d43f817, 0x401490f7, 0x4628bc39,
- 0x0ff4fd61, 0xb8bdf0c8, 0x2d20ef61, 0xd5cd0a1c, 0x29f28f58, 0xd490b3c2,
- 0xf91a99c8, 0xb8578ead, 0xf198a1dc, 0x3ff9ba3d, 0x8c55e9ba, 0xc88d19e0,
- 0x7472789a, 0xb33b45c7, 0x2cc0eefa, 0x7e015ae5, 0x9b75c932, 0x6a952045,
- 0x1218f7e4, 0xd541d4c4, 0xaabf162e, 0x3c9c8082, 0x83471dd3, 0xd7811a60,
- 0xfdf72803, 0x92190803, 0x1286fa0e, 0xefc0d6eb, 0xf385cd92, 0x082b98b1,
- 0xddd31793, 0x7e0a7fa0, 0xe94cb91f, 0x61b2aaa9, 0x40f78b10, 0x0d7ef0bc,
- 0x3f3a5855, 0x4bf5fb97, 0xd5f907a0, 0x27df70b8, 0x620a2a81, 0xbb453370,
- 0xe2c224eb, 0x463bad99, 0xb48fe7b4, 0xffaf8118, 0x0731ca20, 0x6984fc89,
- 0xc82ac41e, 0xbfd8aadb, 0x9cfdc365, 0xa0424dc3, 0x241dda1f, 0x63a9a764,
- 0x969cf9a4, 0x34995dff, 0xf74ba1af, 0x91b97d04, 0x335ca82f, 0xf8441b8c,
- 0x373f7ed1, 0xa1b9fbf4, 0xadbfcfdf, 0xe54e155f, 0x10e941d6, 0x65756087,
- 0x8d8dc390, 0xa370e567, 0x710e19f0, 0xc62988d7, 0x11cdefc3, 0x367c31ae,
- 0xf14fa816, 0x1d26273a, 0xd8f3f4e1, 0xaff06103, 0x04b50925, 0x04abc3ce,
- 0xc922fe35, 0x11da6875, 0x70f915b7, 0x4e671f3d, 0xf577a30c, 0xfacf7c1d,
- 0xe8efbc36, 0x5bd6df51, 0xf5e898fd, 0xc7cdbd9d, 0xdf3e751e, 0xbd94ce55,
- 0x705bfef2, 0x6f2ddb5f, 0xfa9414dc, 0x6273db77, 0x71a5bf68, 0xc36b7fed,
- 0xb46f4c2f, 0x2fe3d7f6, 0xd295e806, 0xfd60cc4f, 0x7bde2377, 0x7cf997a3,
- 0x48ef341d, 0x9bbaeba5, 0x9ea53f8f, 0xb3df77dd, 0xe8e3d98c, 0xf50bcff1,
- 0x77faf0e7, 0xaed1f35b, 0x87e62270, 0x9ee12718, 0xde17a65a, 0xf78890f3,
- 0x08e23dab, 0x7f942fc1, 0x042e5dee, 0xe2d1e942, 0xe3779122, 0xf8f3ff68,
- 0x4338c6f8, 0x5d4ca23e, 0x338b4627, 0x7d4ce8c4, 0x5f8c6587, 0xf2e488b0,
- 0xeffa51f8, 0x933736ed, 0x5c80e687, 0x2fb2323d, 0x3a5237f9, 0xd2927d06,
- 0x8967dc31, 0x712d3dfc, 0xfabfccc9, 0x3c9d788e, 0xb128a0bb, 0xc536bfb8,
- 0x2e1be2eb, 0xc724af1d, 0xf9b5e469, 0xbf175da2, 0xa4f24aa5, 0x2e92bc80,
- 0xca14475e, 0x3ec5f257, 0x5394d144, 0x1999143d, 0xee5136dc, 0x200398a4,
- 0x5ceecce7, 0x6c7a0f92, 0xb54fa31c, 0xa2309cbe, 0x9b7c6f5b, 0x262c7bfe,
- 0xe96cf911, 0xc6192512, 0xeb73da09, 0xcae893e1, 0x3d1cf8f6, 0x83bfc1e9,
- 0xd60abbad, 0x3d73de9d, 0x83c7b255, 0x774e73fa, 0xcc2b1bbc, 0xef28b44f,
- 0xdfbf302b, 0x2aec044b, 0x39e3e13d, 0xbbf0a013, 0x7e87e810, 0xf4ec6221,
- 0xc3afe8a1, 0x1075e4f5, 0xf5ca91cf, 0xe3be3c55, 0xf1cf1e2a, 0x737f1e61,
- 0xa8f38f0d, 0xa9eacfc2, 0xd68238c6, 0xab7facc1, 0xc127e39b, 0x43e3e1c4,
- 0x529ac97d, 0x3684f781, 0xe2084577, 0x74fe9171, 0xbb69809f, 0xb27e11ab,
- 0x927da09b, 0x05bcc7d6, 0x6a9534f2, 0xcc1e2247, 0x4f920aee, 0xfbb61fcb,
- 0xd9b802de, 0x41bc7d14, 0xc340ca4b, 0x9e01b0bd, 0xc93d3d2a, 0xa70262e4,
- 0x127c2327, 0x53df1664, 0xf4dea3a5, 0xcfee2aaa, 0x83d2a9bb, 0x2b8f1569,
- 0x84710555, 0x8f294e20, 0xcfc89423, 0x8e145589, 0xbe09fdf0, 0x6655566f,
- 0x9da67963, 0xa60953ed, 0xc012838a, 0xbb309e25, 0xf49f8267, 0x55cc22cf,
- 0xfc527e14, 0x7abc8144, 0xe7c3588f, 0x7441e9cd, 0xe1710d9b, 0x2f002794,
- 0x26486f35, 0x9715e7b8, 0xd63e4cdf, 0xcb38b3d0, 0x3476071b, 0x6013e1d1,
- 0xe039fbff, 0x2367ce95, 0x59c6179d, 0x9ab0f4e5, 0xa72d7de3, 0xde3cf587,
- 0x5d382fe7, 0x0fd74a3c, 0x7b0f2af9, 0x1a61b037, 0xc84b8bf3, 0x68b8f130,
- 0x3bf5a221, 0x8904f38b, 0x3c89d74c, 0x718a60aa, 0x0b31c8ef, 0x247d8bd2,
- 0x7e508af1, 0x8b0081ec, 0x0a9b9963, 0x1a9c66fb, 0x128272b7, 0xb61f1b37,
- 0x3e3ccc86, 0x1dcec89c, 0x3de351ad, 0x590e7956, 0xdbdefce1, 0xdcce0e7c,
- 0xf6bc6043, 0xd20e8851, 0x7b3b97c7, 0x6a3bcd31, 0x7f4dfea9, 0xda5f1eec,
- 0x5ae7a06a, 0x373f010b, 0xbe7f9d07, 0xf7b1af46, 0xd9080762, 0xa9d8a47f,
- 0x45074b3c, 0x97f7e283, 0x006c83b5, 0x05730a67, 0xa49b1dec, 0x039054dc,
- 0xdba2e29b, 0x4cec626d, 0x8e65765f, 0x8d75d1d0, 0xee76c5e4, 0xf4746309,
- 0x4fe5c35f, 0xdd1c94fc, 0x7cde5577, 0x0bfac31e, 0x30997dda, 0x998ba4af,
- 0xb709bfc8, 0x553f9745, 0x3887ec92, 0x98a35500, 0x94cff3bc, 0x43d59e99,
- 0x7539309e, 0xf8f08c81, 0x86467435, 0xbf07d413, 0xe2eb299c, 0x3e03ae19,
- 0x63710619, 0x02affd19, 0x38a9a07e, 0x89fa4658, 0xf3c26e9f, 0x5fce1aea,
- 0xda7e730f, 0x11e9f9c0, 0xc40b23e0, 0x677c659f, 0xb0e19e26, 0x58b9549f,
- 0xfe012ddc, 0xc5549b4f, 0x7187982c, 0x04598f8e, 0x32a89fb8, 0x4317537b,
- 0x59e2d6be, 0xe31e60a9, 0xed6bfb01, 0xdf7f344a, 0x2ce27d90, 0x6cd7853b,
- 0x6ac7bf8e, 0xacfe22c7, 0xac014f6e, 0xc188eccb, 0x50d57df3, 0x73b4416b,
- 0xb33b74c2, 0x2f78508f, 0x4cfa7e84, 0x873ee9cb, 0x66a19981, 0xfdc21666,
- 0x1d077831, 0xedca7e85, 0xfd218f4c, 0x46b064fd, 0x38f0d40e, 0x93f14471,
- 0xb0791ae1, 0x0254c872, 0x729e9e76, 0xb83917a0, 0x2ac1c98d, 0x062fef81,
- 0xf8f156bc, 0x341caadb, 0xc4a35e03, 0x4d7d5ad7, 0xbe7deeb6, 0xb1b8e5c4,
- 0x3b3b3ade, 0x9e21ad37, 0x59e84fb0, 0x0eb4e14e, 0x3fd914e0, 0xa0e3ba73,
- 0x3aca20fd, 0x0ceff28c, 0x532083ec, 0x338c3ecc, 0x9e5648b2, 0xe5720f18,
- 0x4cbf98df, 0x3a827a6f, 0x42c5fe5e, 0x2ef267dc, 0xbffdc78e, 0x213c76a0,
- 0x2b02ae70, 0xf69de6bd, 0x753fcde9, 0xd74ede01, 0xcdd3fbf2, 0x57fc0052,
- 0x2eaed74e, 0x4db57cc3, 0xfc4c9c01, 0x882e03e5, 0x69e8b2cb, 0xcf53ef11,
- 0xd0d3f8c4, 0xcbebefff, 0x7f8d4597, 0xb5ba8ac4, 0x169f2069, 0xef8b5d6d,
- 0x7bc4ceec, 0xf26ae687, 0xbd415324, 0x96d38d50, 0x0bc58cf7, 0xfb6f5dfa,
- 0xe8e6de52, 0xf82afde7, 0xca5af415, 0x1eb7a02f, 0x4384e574, 0x7e67ff14,
- 0xb27d4369, 0x4277f64a, 0x1dab6abe, 0xf8aa905a, 0x1e3ff1e8, 0x0bb4dfb6,
- 0x76c3c7e4, 0x89483eef, 0xed4bc583, 0xf8ea3e6d, 0x856b60ed, 0x78a7b77b,
- 0xa78a141c, 0x1bbb3a99, 0xe76b77bb, 0xed621476, 0x97863ca5, 0xbb94bd2b,
- 0x710c9f98, 0xe7572f47, 0x1f9f9673, 0x07b56d17, 0x03d14656, 0x84f7f116,
- 0x867df88b, 0xbb672f4a, 0x67462df5, 0x1725ff6a, 0x62f465af, 0xb9e14ba0,
- 0x9f874851, 0x7f70911d, 0x11bb9e11, 0x5d94b4e3, 0x12fd61b4, 0xf828f3d1,
- 0x45b79377, 0xdefbd3a4, 0x59f78718, 0x9078861d, 0x09e983a2, 0xb1779a6a,
- 0xe69fa758, 0xb0ca1605, 0x2c5de79f, 0xf60c7463, 0x93983867, 0x689b5e6f,
- 0x0396f4e6, 0xb4dd2fed, 0x6fcbd692, 0x264ef463, 0xbed0cbf8, 0x3cf76758,
- 0x8a0e451c, 0x3717450e, 0x84adbf34, 0x49f873b5, 0x7ffee682, 0x9e8b8f11,
- 0x45c5917f, 0x493f6e24, 0xf2e73a01, 0xfa9f4229, 0x261db5f8, 0x7ae32f86,
- 0x133af813, 0x437bd7ba, 0x3efdeb2f, 0x0fd72f5b, 0x1bc6dbf2, 0xf1abf5d6,
- 0x5915d6d1, 0x5fac04cf, 0x970de3c2, 0xd5de1898, 0x4c1d1bf2, 0x7b69ab0e,
- 0xa5e22ce5, 0x8f2151fb, 0xb81798ab, 0xcf3e064f, 0x2f171cdb, 0x5f99d668,
- 0xa7e7473b, 0x1f3b5792, 0x6fe570e3, 0xd02f2f9e, 0x9e3755f0, 0x6baf29fc,
- 0x86e374f1, 0x3a57533e, 0xbdca1f60, 0x3ee301d6, 0x65f73a5b, 0xbc32fd02,
- 0xa3fd919d, 0xdd0e502b, 0xcef68ae7, 0xdbc046e5, 0x387ced38, 0xc9fb06de,
- 0xa37bed48, 0x58e3d18b, 0xbe2b6fb6, 0xdbbbee1f, 0x4451649f, 0xd137977a,
- 0xe38469f1, 0x59bf0e2c, 0x8e1c70dd, 0x8657547e, 0x7f3a75e3, 0xc8e15ea9,
- 0x49c2aff1, 0xb0f54efd, 0x18448e99, 0x57f7b097, 0x0aafe3b5, 0x27f1917e,
- 0xa1defaf0, 0xa2fc824f, 0xf4f812f2, 0x1f3fb3ec, 0xb0f76dad, 0x30bde27d,
- 0xbabea90e, 0xd83fb57b, 0xdf50797d, 0x0473c93f, 0xadfe6bce, 0xae8aa7a2,
- 0xa9f630bb, 0x56ae10ce, 0xaeaddfbf, 0x760e186c, 0x20caaad6, 0x40bb54a6,
- 0x8a6a8bbd, 0x685fd01e, 0x78b46f15, 0xbc39eb54, 0x32b65757, 0x4fd5913b,
- 0x240f60dc, 0x99c92f8c, 0x333768b1, 0x837af43b, 0x60dcf92c, 0x7bf993a7,
- 0x5becc967, 0xe7099e97, 0xbf0c84e0, 0x1d6bbe06, 0x4362ffcc, 0xf83f52ca,
- 0x3ec159ed, 0x22ed0839, 0x81767417, 0x9c8bcd57, 0xf0d4ee94, 0xf58331a3,
- 0x904252e5, 0x246e1da0, 0x479daefd, 0x2eceab42, 0xd98b846a, 0x12fbc2ea,
- 0x2ef6e133, 0xeff50f0e, 0x72e5ac64, 0xcddb86b8, 0x197b071e, 0xbb4adf85,
- 0x35a3f70b, 0x39d898d7, 0xf3c66ac3, 0x40f1b835, 0x8fd6397d, 0x7ac1b0eb,
- 0x43f3d044, 0xe4427798, 0x7b43111a, 0x238f9009, 0x3ef9008a, 0xf406b424,
- 0x6d89aed6, 0xd9f7c3f7, 0xe01d5f36, 0xd6d4cbf7, 0x4fd802e3, 0x00c37d73,
- 0x3fa2b5ce, 0x7ff5a143, 0xa033862d, 0x3a2d1a5e, 0x6bd2cf16, 0xa7daafc0,
- 0xf16197b9, 0xb1792340, 0xe59afe67, 0xc53dc366, 0xe5b4c3d7, 0x2d946cfb,
- 0x7bfcf5c6, 0x0b1f0929, 0x74b6ef28, 0xf173c9db, 0x8e51d07d, 0xa00fa44f,
- 0xbf6c23af, 0x625660be, 0x4dfd99e3, 0x67675579, 0x6aaf2ab6, 0xf3f333c6,
- 0x57a53d50, 0x74aba7b0, 0x35ecd832, 0xa90d3d01, 0x74b5dfa6, 0x832f4511,
- 0x72f70671, 0x0fcea11f, 0x3c0007de, 0x6c598bc5, 0xc5d031bf, 0x25fb6ebe,
- 0xb32a7bfb, 0xaf33c255, 0xa238f962, 0xd1fc60fe, 0xe3edba0f, 0xcdde58ab,
- 0xd80be572, 0x05a1dc7d, 0xa6d7e8b1, 0xcb7663ce, 0xc3d056da, 0x2ea4b766,
- 0xd999fb84, 0x0afeebd6, 0x7c293ee9, 0xe2720ec8, 0xe79e2ca7, 0x2abdefdd,
- 0xfbba69d9, 0xdef8addd, 0xcfdf34fa, 0x04b092e6, 0xb711f7f8, 0x01ebeccc,
- 0xc405d3e4, 0x0941f3c3, 0x84f7bdce, 0x42de7702, 0x1abef773, 0x628e05b8,
- 0x5f848f73, 0x82f97403, 0xc368a9ee, 0x7b35db56, 0xd679675e, 0x66fd7bae,
- 0xb227ae2b, 0x5fae2b5e, 0xf6441f5d, 0xb8eef2c4, 0x912e2cc0, 0x0b498f0a,
- 0xdb67bad9, 0x7c98fce7, 0xdb39de8b, 0xccafea3a, 0xc7cd887f, 0xa1cf9f08,
- 0x4ec5ca88, 0xa4e4d787, 0xe1d0ffeb, 0x5eb49d15, 0x669c3589, 0x62fc881e,
- 0xe8997c81, 0xae8926bb, 0xdf00fcff, 0x438044b0, 0xd2ab9f6b, 0xf4e4df2f,
- 0xefa726fd, 0xe3bbd337, 0x1ea02718, 0xae024f7d, 0xb3a7066b, 0x47dfbb35,
- 0x6ff3cc3f, 0xa54b78b0, 0x83eb72a2, 0x49133768, 0x6aac38b4, 0xdfb726fa,
- 0x0e954e28, 0x0dce3c03, 0x4d1997e3, 0x9fbbf476, 0xf4ea2991, 0x029919f0,
- 0x1d6b87f7, 0x2f4e877d, 0xd2f5c55d, 0xff80fd9e, 0x859fb181, 0x39e327cb,
- 0x9eec8f6c, 0xffdff208, 0x85b3a334, 0x293c2853, 0x13ace5dd, 0xfc70def0,
- 0xf20236a9, 0x1c4d6170, 0x85f3fb81, 0x20fbfc0f, 0xd650c788, 0x81b734aa,
- 0x1e080c9c, 0x8b25bfb0, 0x467e324b, 0x10e9b5e7, 0xbf2187db, 0xf0e9e604,
- 0x3d8d0e2a, 0xc8aa43ba, 0xdf5d0370, 0x3c82f0eb, 0xf7877f98, 0x6fe78c03,
- 0x7b041d0e, 0xf99ebab7, 0x00d928f7, 0x9b41f9ff, 0x312b5317, 0x36b950c7,
- 0x90ac4cdf, 0x6cc4cb26, 0x73cb7c83, 0x1e4bb05f, 0x18e4eeb6, 0xdfdf6562,
- 0x72f404b8, 0x5bac835d, 0x3ea0a8f7, 0x3eb37d7f, 0xe7d2119f, 0xe7d11ec7,
- 0x431a83b7, 0xffc395f1, 0xfda1d4ce, 0x877f0216, 0x0b45f8a6, 0x0cbeb3fa,
- 0x05fa007b, 0x4dde50da, 0x82c96e2e, 0x5e4fd6fb, 0x9ce09a70, 0xdf9befbf,
- 0x786d7de2, 0xc9e31d87, 0x0c53fc1f, 0xc07f0189, 0xa15b6d17, 0x04e298bc,
- 0x2fc577ec, 0x0ec0eada, 0x7a8467b2, 0x5fa00d1e, 0x31bf9ec5, 0x76f0f9bf,
- 0x6fee004b, 0xdcfbd93f, 0x9f6f400b, 0xfa87ef6c, 0xdf82cbce, 0xd7f9fd04,
- 0xc4e67c33, 0x272d7db0, 0xde33d286, 0x75cfebbb, 0x1c993bf7, 0x1e6caf69,
- 0x4e59fb01, 0xb47fb33c, 0x011c1e57, 0x8f0e5cfb, 0x49eaae43, 0xbc7e3c39,
- 0x274fea9b, 0xe51439d9, 0x0fce70c2, 0xb2058179, 0xd5fa01d7, 0x5390188a,
- 0x79e5675d, 0xac358fe0, 0x15470f56, 0xf406d7cf, 0x7cf92bdf, 0xf7cd1016,
- 0x56f7b874, 0xbd00a4d6, 0xbea2433d, 0xf9c35c7b, 0x65e7f9e8, 0xf22fbcf5,
- 0xd14468f8, 0xc88acfbc, 0x1facb273, 0xbe0025f8, 0x17be4606, 0xfb55c61b,
- 0xfffbca9f, 0x92fccacc, 0xce1c3813, 0x7d411e55, 0xaddf5ba0, 0x68a77af4,
- 0x07b579f2, 0xfc23e693, 0xd02d260e, 0x1fb6f39e, 0xfe039a4e, 0xfc660d36,
- 0xb32553bb, 0x27247d9f, 0x418bbe01, 0x03942798, 0xaf823b1c, 0xd51ea0b9,
- 0xfd68c767, 0x6f6bf257, 0xecd14ef2, 0xce95dfd7, 0xbb65e3bb, 0xca5e5c19,
- 0x16fdbdce, 0xa2cdbba0, 0x0715aa07, 0x1479bcef, 0x84b37bc0, 0x764b72ef,
- 0xbdb7184a, 0xb406eebc, 0xbe371453, 0xffe31533, 0x03df393d, 0x9332caf3,
- 0x9a0c715c, 0xf480ee18, 0x8c6ecb4c, 0x61fc57af, 0x60566c8d, 0xa3ba7abe,
- 0xa3f08c74, 0x6dd6541a, 0x15de53c0, 0x7eab3fe8, 0x30b7e237, 0xc46f6fa0,
- 0x1ba72b53, 0x8b5c33fa, 0x3ebd636f, 0x8ef8fdd3, 0x953964b2, 0x543b1a63,
- 0xf46aa9c9, 0x038e33d7, 0xa344da37, 0x7703eca7, 0x1dafe01b, 0xfe836fcc,
- 0xee2cd608, 0xe5883ad7, 0xd0200e31, 0x047fac15, 0x3bc0a299, 0x34c8dbcc,
- 0xd1b95548, 0x0d1c1d91, 0xda165ff5, 0xf615fd9e, 0xed7e44e7, 0x2e308770,
- 0x3efe5f62, 0x796143b5, 0xa83aeff5, 0x362d45e5, 0xe4f8f3f4, 0x71f28cbc,
- 0x4197f805, 0x266c17fd, 0x3ebfdd13, 0x1267d9d9, 0x04762df8, 0x73dcbc59,
- 0xe4933ec1, 0x8d77d96f, 0x0fdd4172, 0x74afc04f, 0xe9c2fcdf, 0x4b7ec30d,
- 0xcebf3156, 0x19153ee4, 0xa4f05115, 0x2b904bb6, 0x123ce032, 0xd9e1d7be,
- 0xa7f2708a, 0xc1723ec3, 0x81f68297, 0x121edcf9, 0x06fdceef, 0xbad275fa,
- 0xfe2ffa5e, 0xe815b888, 0x73d163eb, 0xe4507bbf, 0xa6516f9e, 0x90f3df0f,
- 0xb45cec55, 0x66424cd0, 0x842eefaa, 0xe63463fd, 0xb85bbf71, 0xa6ff4059,
- 0xebf41b45, 0xdaad7881, 0x405087bf, 0x22dfb1aa, 0x60b4c412, 0x10bcbeb3,
- 0xf81723f6, 0xfc7bb067, 0xb97d7aa2, 0xa4a84efa, 0x1a25b2f1, 0xea20bedc,
- 0x2ec9bcfa, 0xb36e179a, 0xdbeefce2, 0x35eecb14, 0x7d85e264, 0x89c9bc30,
- 0xf898bc72, 0xbe3f3bd8, 0x303f960f, 0xd288bbdf, 0x85f2d767, 0x307d45de,
- 0x7d81077e, 0xf895b16f, 0x1e58635d, 0x0b2017e2, 0x38b29f21, 0xed4eb051,
- 0x29e2963b, 0x15c03424, 0x53ac2f59, 0x65de4e5b, 0x116e2cf8, 0xbd60a342,
- 0x64427ef0, 0x2bd6d5eb, 0x692870e1, 0x11ece8b4, 0x0a7fe0a5, 0x974d337e,
- 0xb97eba2d, 0x8fdd1f3f, 0x69e28d89, 0x0ddcb753, 0x4fcd1b5c, 0xd78738fe,
- 0x52f33ba6, 0x051f3f81, 0x072fb33d, 0x173d3668, 0x61cc9083, 0x71d2b780,
- 0xe776c662, 0x256b3cb1, 0x647d4fcb, 0x51e90fe0, 0x1bcefe1b, 0x142c6fde,
- 0xf7875f73, 0x7db9cf57, 0x71d1763f, 0x69bc9a16, 0xef53e466, 0x5cd7f450,
- 0xc4ffd6ce, 0x2b6b8a98, 0x557b9ca2, 0x042e3e7c, 0xbfd1bef1, 0xceabed97,
- 0x7da4b0cc, 0xc5c8b45f, 0xa1ec4fe4, 0x10777c36, 0xbbe02dde, 0x138527c7,
- 0xc9f02ef8, 0xce04291f, 0x6f1429e5, 0x149f1f20, 0xbf882ac8, 0x7334d995,
- 0xbf806bc9, 0xa3d418cc, 0x8a269b4a, 0x3f5c0ea5, 0x15eca3d3, 0x99ef7075,
- 0x18f86f3c, 0xeeba6ba0, 0xff01b779, 0x5b8414bb, 0x41d183aa, 0xfa7f4aca,
- 0x7e3091d2, 0x80d792ee, 0xe0c546ef, 0x0a64d93b, 0xa63c672b, 0x4a2f40eb,
- 0x41071921, 0x574ca78e, 0x772d80c6, 0x938d8b93, 0xcde71268, 0x0c6dfd04,
- 0x243fc7cb, 0x7122b778, 0x2575c46d, 0x369fd85b, 0x7fa0ef82, 0x804ec15a,
- 0xe78601e5, 0x301915c9, 0x9620f27e, 0xf421c826, 0x8dda3a53, 0xcdea1f77,
- 0xe504dccb, 0x134bb2f2, 0xfb69e393, 0xc0f41da3, 0xd1d5e54c, 0x1d9eaafe,
- 0x439e8072, 0xf5670f06, 0x2cb15eb9, 0x27e5f983, 0x10faa9a4, 0x7925d7ab,
- 0xfc82c763, 0xdbe9877c, 0xb1bc3b9f, 0x837737e0, 0xb80fdd1c, 0xfca9e386,
- 0x34049da2, 0xd67cbff2, 0xa4def897, 0xf74ba2fc, 0x69c9e21d, 0x0a4b49fd,
- 0xe3dc610e, 0x7e8ad252, 0xbd41a5c9, 0x310debff, 0xe955c7d1, 0x48a2fcbc,
- 0x95c751fc, 0xf62fdff5, 0xd13efe21, 0xbfe925ea, 0xf9f4145f, 0x3d78afe6,
- 0xd9277e33, 0xc7382e6d, 0x077d874d, 0xe4c049e4, 0xe08fae97, 0xa6ddd3a5,
- 0x153a6fdb, 0x71e2ef96, 0xb572d575, 0x3259ceff, 0xc6139f7f, 0xa92a3a71,
- 0x79f0a240, 0xb453e5aa, 0x1cb496a3, 0x74a8f844, 0x9d938111, 0x4a7035f8,
- 0x990d6aaa, 0xfeff8f28, 0x476b4591, 0x72514b5e, 0x3fb3f388, 0xf297ad6f,
- 0x2fc4126f, 0x3db7f0d7, 0x51df9bb3, 0x89326ccc, 0xbf99dedc, 0x4d04ca76,
- 0x6eefd79e, 0x21f82fef, 0x648e6794, 0xa47bdfed, 0x072b77f0, 0x5d13e447,
- 0x53ae5a47, 0xf21ab793, 0xa51f9a0e, 0xe50dbbc9, 0x14f28609, 0xab3fbe43,
- 0xa50ce1df, 0xda421e89, 0x21fd291e, 0x8eb95dfc, 0x885cd0d4, 0xac41b038,
- 0xddfc21f8, 0xf64cd2c9, 0x5acb1477, 0xb3730f04, 0xf32bf062, 0x87307bb0,
- 0x385e4da7, 0xfad0e012, 0x9283c83a, 0xfa0dc166, 0x33b823be, 0xa7687984,
- 0xd905da68, 0xe092ad3b, 0x6bd76c09, 0xc84dc3ff, 0x3f0f0fcf, 0xe4aef589,
- 0xeba644ef, 0xf37be0fd, 0x7c9874b3, 0x53df6117, 0xec770ce3, 0x77f23f7c,
- 0xcef7e8ed, 0x9461ef54, 0xaaf786a7, 0x471f30e5, 0x38545f84, 0x02fc3c3e,
- 0xf3fc5dc6, 0x40f796a8, 0xfb2fb00d, 0x95e80574, 0x1e9e961f, 0xc4167a07,
- 0xe3fd846e, 0x2d702171, 0x114f47ec, 0xee30b5df, 0x0e43a5bd, 0x39949fc2,
- 0x816db52e, 0x1ec31050, 0x3ff08f5d, 0x001b6cee, 0xdae8927f, 0x4f961ad8,
- 0x1008c36c, 0xfd37626b, 0x39fb4cd0, 0x806da03e, 0xc547e689, 0x43e5661e,
- 0xfe40b6da, 0xb0dfd8ce, 0x036d51f2, 0x1d1c3744, 0xdb7f111a, 0x3ef9d1dc,
- 0x1bc9962d, 0x06437e75, 0x4163537b, 0xfb612a8f, 0xb4873c0e, 0xb73ab952,
- 0x6d8edce8, 0xff731e14, 0x6ef28ed5, 0x3fedc75b, 0x3fb1fa66, 0x92a0fc17,
- 0x5f71bc39, 0x466ef944, 0xf61521bd, 0x3e08f8c2, 0x0aad699d, 0x2a231bee,
- 0x905e8276, 0xee24773c, 0xef4e9d1b, 0x9171d8da, 0x9a048bf4, 0x8dac79d2,
- 0x2ef93375, 0x5b3df09a, 0xd44e83f2, 0xf1e51e9f, 0x21df29ba, 0x5e38387d,
- 0x8cf5f2c6, 0xa1e7658d, 0xd84dd744, 0xaf5cddcf, 0xd81f59ad, 0xfff0a36e,
- 0xde0e7a93, 0x39e4f4c8, 0xc4ee5475, 0x37817f82, 0x1cc9e415, 0x8c8f07b0,
- 0xbfbd55e4, 0x1de68326, 0xcd58f391, 0x36aa6f4c, 0x1d4d782e, 0x55e5572b,
- 0xaf6b3a4d, 0x55c95bee, 0x8fc93e0c, 0xd615bb5e, 0xff333761, 0x86b3c581,
- 0x7a815d6e, 0x5f386dc0, 0xc2a6f5e2, 0xe154fcb9, 0xa3e81340, 0x0da67e2a,
- 0xeb82def6, 0x2a38f7e1, 0xd7f1d49e, 0x142f75f2, 0xf6011ea9, 0xe10fb774,
- 0xd18af549, 0xe99d72ec, 0x5ae96b15, 0x7c2a1f01, 0x1c6db989, 0x045fff7c,
- 0x0cffa5a7, 0x7eddfd38, 0xbc7bd3dc, 0xfd0359c7, 0xad3f2e97, 0xe1c38f7f,
- 0x9210b8fe, 0xf1353392, 0x3877e853, 0xf2eade77, 0x735622fd, 0xc1f735bf,
- 0xd53fd452, 0xe5ffd8f5, 0x917769a5, 0xd469fc9e, 0xc9ff8f0f, 0x02ec01ba,
- 0xca20e5c7, 0x263fe3e3, 0x38e42ef8, 0xeaa5678f, 0x5aff59b7, 0x6dce147c,
- 0x222b11ff, 0x7a54d87d, 0xe6777210, 0xa7aef851, 0x3bbc39db, 0xd464fd57,
- 0xc786bafd, 0xe079ada1, 0xd1af7c3a, 0x3cf0da45, 0x2826cfee, 0x67cbbb3f,
- 0x4a72c50f, 0xc81b7e27, 0x8c18c289, 0x41935fc7, 0xcd497df0, 0x0e5811ec,
- 0xc7f458e7, 0x71c56d99, 0x3a32666a, 0x478c29ac, 0x5dc8217b, 0x746f5b80,
- 0xecc55494, 0x1decc41f, 0x7f1fbdad, 0xf9f9962f, 0x76db33db, 0xed7a0fbf,
- 0xb5ea1b06, 0x57bc4280, 0xf1c64ea9, 0x8fec3d28, 0xcd97fdc5, 0xa963e163,
- 0x5c718781, 0xd603da0f, 0x51f3bd3a, 0xaeccfdce, 0xdb37fcc0, 0x18eb3ac8,
- 0x5590e638, 0x7cf92f28, 0xe813f548, 0xeb8f3157, 0x5c151f89, 0x721e8270,
- 0x1edbb634, 0xf9f385e0, 0x17cac202, 0x013f643c, 0x0f05abe7, 0x64b778b1,
- 0xfd5e4ddd, 0x6b9d093d, 0xf9d3d812, 0x09d86d4f, 0x3b41f070, 0x1ffff417,
- 0xe41f784e, 0xc3bd887b, 0x7eda7e25, 0x47fda478, 0x9760f7c0, 0x49fcd917,
- 0x16895da5, 0x58a3f4e7, 0xfd5397ee, 0x9e3b5784, 0x5fb18e3a, 0x036c8e7a,
- 0x0f70a37e, 0xf0a83bc1, 0x59dfd8cf, 0x4137ce30, 0x46c2ff0e, 0x8a56e7cb,
- 0x3c292b71, 0xb89dcb7d, 0xf3be755e, 0xa237c392, 0x7fd0c29d, 0x0b2cbdbb,
- 0x79eae7ec, 0x39a43c88, 0xe45c21ff, 0xf8845e48, 0x573c6101, 0xcfcef8f5,
- 0x2873c6cd, 0x68b37f21, 0x2bbf75eb, 0xfcc30450, 0x82295d39, 0xe3e6f019,
- 0x1cb2fef7, 0xeb720b9e, 0x50eb02ff, 0x8000589e, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dc5ff00, 0xd5547c0b, 0x73b9f899, 0x3332bcef, 0x49324cc9,
- 0x9b8f2126, 0x80402107, 0x52024c49, 0x1878431f, 0xa4076b35, 0x438b5b16,
- 0x921123c2, 0xb175b689, 0x5100cb65, 0x8d042208, 0x41380abc, 0xbb6bba50,
- 0x060222c1, 0xb6a2d11a, 0x6eb42fea, 0xfdfeed57, 0x58f88845, 0x16544649,
- 0xefffad5b, 0x99b9cefb, 0x514493b9, 0x67f4ddbb, 0x739ee72f, 0x77cef9cf,
- 0xcef9f7be, 0xe99a1619, 0xf4662deb, 0xfc3e79f7, 0x33577f87, 0x3034e896,
- 0x7cd8ca96, 0x96773599, 0xeb47df44, 0x6d67aa25, 0x34967d5b, 0x0bbc02c6,
- 0x66f536e6, 0x607da1fb, 0x694df9b9, 0xeb88bc22, 0x6330b19f, 0xb56d8c15,
- 0x993590b2, 0xf4126db1, 0xbbcf0e53, 0x7935e16c, 0x23580d8c, 0xc602b08f,
- 0x59afc782, 0x1bfbef80, 0x4d065412, 0x08589876, 0x8ee3a1cb, 0x576c3ef0,
- 0x64c45bd4, 0x7c1807a8, 0x24be786e, 0x0d248477, 0x5e9ac608, 0x87acf792,
- 0xae47fd76, 0xb2acfde5, 0x41ca0ca9, 0xb8c136a8, 0x575fd0c1, 0xa4c644b2,
- 0xff1a1639, 0x6c2921cc, 0x66c3fac6, 0x85e0d3e6, 0xbfe1faff, 0x2f1832fa,
- 0x2719086c, 0x102b13c1, 0x8236c38e, 0x40da6603, 0x813f7de3, 0x9bf187ad,
- 0x00cf920c, 0x8db74df5, 0xf0e1af0b, 0x67e01858, 0xc9ad0099, 0xe8245ac0,
- 0xb5e0532f, 0xe8ba70c9, 0xa75e128e, 0xf8a5bb40, 0x3dda950f, 0xcb9c012b,
- 0x647a1b2c, 0xe1399380, 0x0dbfa83f, 0xeba2f3eb, 0xbfe1b4d0, 0x3479c33f,
- 0x2db8041d, 0x3d97b851, 0x6dc79fa6, 0x27ad14cc, 0x7eb443b8, 0x2f8e72b6,
- 0x47858336, 0x510ebc03, 0x84f755b6, 0xf2c7c465, 0x65ccece9, 0xef44f4d0,
- 0xeb1dbf2c, 0x3c2d593b, 0x5f30ef83, 0xda9ee018, 0x28ccf1d5, 0xeeaaef68,
- 0x06e9c6c9, 0xa0b1ff97, 0x3ae8b2ef, 0xde5e706b, 0x766659b5, 0x03be8f1a,
- 0xec077c50, 0x9cec6ed4, 0xd5cfb109, 0x41aa5df4, 0xebc715be, 0x881957c5,
- 0x04865f1c, 0xc8696ce3, 0xdabae037, 0xb0057814, 0xb31b6a2e, 0xd9e11567,
- 0xc1c73457, 0xec8983d8, 0xd3e13f56, 0xfe87e95b, 0x2d56751e, 0xe97f4274,
- 0x9d5baaae, 0xbf1c7ca9, 0x029fa703, 0x6ba50d40, 0x47e1a9ed, 0xd05e976b,
- 0x1f6cda5c, 0xc4db9db9, 0x9ed916f1, 0xf083de14, 0x17951228, 0xb1d8deff,
- 0x8853e09e, 0x95d8ee6e, 0xebf84617, 0xe9099b59, 0x9b0b197c, 0x5b178e90,
- 0xe8112858, 0x4b343162, 0x6d92e782, 0xacc6a666, 0x5f58435f, 0xae1ced66,
- 0xd3f74a65, 0x4dd22252, 0x74b3f50f, 0xb2ddbebf, 0x01dbac19, 0xd6168df5,
- 0xa767c36d, 0x4589bebe, 0xe1e08e08, 0xfebacdcf, 0xc3ad1b59, 0xc8632b76,
- 0xbe6549a7, 0xfe01bbbc, 0xef460bc8, 0xb7cfa01e, 0x7868bac4, 0x35567648,
- 0x64139e20, 0xb233cd03, 0x03de16ca, 0xb033ecf3, 0x4de75c7a, 0x1ceb762e,
- 0x64aff678, 0xa12342be, 0x77ae2263, 0x1fd73e3c, 0x7d23d6b5, 0x13f9416c,
- 0x38373f43, 0x5ee7848d, 0xbe47ab13, 0xfd0d5ca9, 0xa6a5c8c5, 0xfc01ec9b,
- 0x9726976e, 0xc46f9d60, 0xa86b6675, 0x9e91ed8c, 0x4fe32e12, 0x83bdbbed,
- 0xa7f337ed, 0x4b7bf9c2, 0xae074243, 0x0cee9453, 0xc4aee88c, 0xf7c00a6f,
- 0x583c8547, 0x38fdf960, 0x40a3f7a4, 0xa1f7c808, 0x0b972b4e, 0x72fe738a,
- 0xa77d1f28, 0x455ebbc4, 0xe272e0fa, 0xd812f7e8, 0xf9f2186a, 0xdef5fef7,
- 0xfcfea197, 0x0cd5263b, 0x46910bf5, 0x4a8f3d60, 0x85e387cc, 0xf787309e,
- 0xc065bbc1, 0xb2cf08b6, 0x28c213e3, 0x02990edf, 0x38e117db, 0xfbbd1b8f,
- 0x8965bbe0, 0x423c5fe1, 0xa05e19f5, 0x9194f644, 0x88e861d3, 0x109f7f8d,
- 0xb95fb7fe, 0x1bdd3eb1, 0xac7bf682, 0x07c81381, 0x09356699, 0x97bf65fb,
- 0xbba71f19, 0x3bf805c8, 0x824af38d, 0x38495427, 0xfa83974e, 0x58cafe01,
- 0x699cfd04, 0x80f9a74d, 0x38e1f4dc, 0xf79a3667, 0x32dcdca0, 0xed44ae38,
- 0xb3fd1b4f, 0xfa7ca032, 0x2aef5289, 0x9bf01aa8, 0x7f404dba, 0x5f4b4dc1,
- 0xea17a064, 0xc46eea0c, 0xa36e3b0f, 0x11eb6879, 0x06a4b8dc, 0xadb783eb,
- 0xdae501b8, 0x7289fc48, 0xbbc8c59a, 0x41c9167e, 0x9f51dffa, 0xfa8dd9df,
- 0x57ac6ba0, 0x2c0f5aa6, 0x9387d03e, 0x7233edb7, 0x198e46fc, 0xb52f4f89,
- 0xa50ba47f, 0x1c0feb92, 0x94f20827, 0xf242fc69, 0x0f2ca634, 0x18ebe657,
- 0xfc4e9a3c, 0xdb3f5f1f, 0xf908f811, 0xfffee9a7, 0x8ab96379, 0x9e4845e3,
- 0xe254b6b1, 0xdbbb8033, 0x6df7df02, 0xe55f1077, 0xf70f50ae, 0x741ebae2,
- 0x335d3cd1, 0xcb03b27c, 0x3ca8f33b, 0x1c6dc855, 0xe2c6f516, 0xcaf48c29,
- 0x58b59962, 0xd17de8ca, 0xf67f6876, 0xcf5a6c89, 0xceb666c5, 0x36ce7c02,
- 0xdb3ffa70, 0xf00a7201, 0x25ee6753, 0x4dfecb39, 0xb518fb62, 0xcb76c16b,
- 0xb28c9060, 0xb94378a1, 0x385bc3a5, 0x7ffa0ca6, 0xe907676a, 0x8a720601,
- 0x9a05d8c5, 0xa4f9431c, 0xcdfd9efb, 0x4863c7ac, 0xc7c4b793, 0xd9f4a930,
- 0x28f2a213, 0x72cfe9d9, 0x30a16055, 0x5677f11d, 0x04e9dc0e, 0x8584b6f9,
- 0xb0363e48, 0xe36a7a6e, 0x72e5bc81, 0x2ee5c2d7, 0x412e133e, 0x3ac6defe,
- 0xa2366e49, 0xee4e1a44, 0x3bb900ae, 0xcbb96471, 0xe2297358, 0xdd8b7835,
- 0x221e788b, 0xd77c857f, 0xc4dd31d6, 0x15d4f0e5, 0x44959961, 0xe89a90f1,
- 0x115a969b, 0x57c1abd5, 0x1275162d, 0x1f2cfd96, 0xda63ade5, 0x7d41a7bf,
- 0x943e6150, 0xe61eb69b, 0xbbf780eb, 0xf3f5fd84, 0xf1fa9534, 0x185d3898,
- 0x852b3f15, 0x9eaacafa, 0x49f2036e, 0xbca2732a, 0xfef0f477, 0xbbe03977,
- 0xcb8efc32, 0x2defc1cd, 0xe62125ac, 0x56a3aafb, 0x470ba3a2, 0xe933611c,
- 0x0bae40c3, 0xb3fb4bfa, 0xfea4ec99, 0xf3920ea3, 0xaf3646fd, 0xd1bbda13,
- 0xbcf5a21e, 0xaefbfa87, 0x219e8f2b, 0x218a3556, 0x8dd74aed, 0xecd65642,
- 0x9ebcc683, 0x1edf489b, 0xc7c8ab30, 0x77bd5c17, 0x63c61962, 0xedbf2728,
- 0xf05da952, 0x9fd2f4e0, 0xdfa0fbc2, 0x0dd8e5ee, 0x98bd2294, 0x64dd1fe5,
- 0x259b7581, 0x05dc88af, 0xdb663670, 0x6787289d, 0x9fd7fee4, 0xbbf2866e,
- 0x8ccc8d07, 0xfa6fbeeb, 0xb23f963c, 0x1b08689c, 0xd0c6f74f, 0xfafdd2eb,
- 0xbea76372, 0x2fac3c1c, 0xb872e1df, 0xde278ecf, 0xf40e7ef4, 0xbf373664,
- 0x9af001d3, 0xdc93329f, 0xf815debc, 0x26e7a467, 0xe224e443, 0xfefb9cd1,
- 0x73ae00c4, 0x3e1207d7, 0x3d2640cd, 0xc8bf1c25, 0x0bac1757, 0xd8c39d72,
- 0x857b51eb, 0x47840c59, 0x513d06b0, 0x20e410f9, 0xdef95f01, 0xbfe61a7d,
- 0x73824e78, 0xd5f1bd35, 0xbda25454, 0xe0b23042, 0x45df6bb6, 0x35da1ebb,
- 0x0d989c90, 0xfaae00ed, 0x2f6e5c6d, 0xc8893d63, 0xd7604d0f, 0x7f096058,
- 0xb1f4e2e7, 0xd95225b4, 0x4f6cff0d, 0x708b1eae, 0x7e299f2a, 0xd8b5ff5c,
- 0xf61d8c6f, 0x1dfb8b90, 0xdb5bf74b, 0xa1f862fa, 0x2ba5d3b1, 0xb4670f07,
- 0x5de2c5f5, 0x25533ff0, 0xb6ded625, 0xb90f021b, 0x7b0f9152, 0xfc60d34d,
- 0x88fb3fab, 0xe592f7f4, 0x0a9d90cf, 0xedc058f3, 0x728aab36, 0x4f5dc975,
- 0x2fcd7bd3, 0x276d9b38, 0xed99e0bf, 0x99765e66, 0x17767ca8, 0x74965bf7,
- 0xa79c614a, 0xca62e734, 0xbba79434, 0x1b334e8c, 0x3c78d78a, 0x3ff3bdbe,
- 0xf54c1913, 0xfa3a426d, 0x1bb71213, 0x6489cd9c, 0x89cdaa9f, 0xb7051f68,
- 0xca2ef35d, 0x64bb25a9, 0x7635ea2f, 0xcd1de1cc, 0xec733cb0, 0xf3f63b22,
- 0x8034ca61, 0x4cf77da3, 0x65ef4ca7, 0x48f9187f, 0x0d5cf5f1, 0x93dd95ef,
- 0x67b7e455, 0x97f87177, 0x208f2cb8, 0x99fd5d1d, 0x62b2764c, 0xcfb40160,
- 0xb1be4dda, 0xceeab7c8, 0x7d70b37d, 0x699d9ede, 0x94bff6a0, 0xe2f11398,
- 0xef869e5a, 0x1f8a4897, 0x5b7eb4f9, 0x7eac4d43, 0x1325d5be, 0x5dcb4dbf,
- 0x276bd691, 0xf509babe, 0xe02ee355, 0xce7f1c23, 0xd9ba7feb, 0x692be51d,
- 0xa61bb6ce, 0x1a8fff62, 0x8377c8bd, 0x3fe7777a, 0x5fe17d11, 0x6dca2577,
- 0xca6faf8e, 0xc69b6667, 0x2845cd27, 0x6eac973f, 0x630e722e, 0xc9f20fcf,
- 0x6f97ce4e, 0xb7ee24b9, 0xeceb2566, 0x00fc91dd, 0x87c1b17b, 0x9978b7f8,
- 0xd33c1f6f, 0x7f430dc1, 0xa159212f, 0x136484fa, 0xe4f949e1, 0xa92ffd8e,
- 0x3e071768, 0x65ccfa44, 0x27d452be, 0x9559c46a, 0xec2b7484, 0xdb93b605,
- 0x907f6081, 0x9525b5bd, 0xc63eb23d, 0xfe8933ff, 0x8a7c4e40, 0xb5ffa272,
- 0x7e224f4f, 0x9fde729b, 0x783afa88, 0x0a9323f1, 0x4977b5f3, 0x5eedbf24,
- 0x09ba433f, 0x0b66cd76, 0x3772a24b, 0x217ae5e8, 0x26375e7e, 0x751cb91b,
- 0xab9fa847, 0xb73f3852, 0xd3d118bb, 0x6409e58e, 0x8770ee97, 0x57f408ad,
- 0x29f65be5, 0xe7587568, 0x675f0b06, 0xfb5fdecb, 0xb0f3a464, 0x658d1ce4,
- 0x40c7f395, 0x0cb0fcfd, 0xb7bbbce3, 0x83e54420, 0xd432bcd3, 0xbc3ef7d9,
- 0x74f11f2e, 0xf6c5e8d8, 0x226f6f76, 0xbdddefce, 0x7e711267, 0x9a657bf5,
- 0x83f87d77, 0x512545b4, 0x2917f139, 0x768c9050, 0xc7b25b82, 0xf7778bca,
- 0xd0b6987e, 0xd253fdce, 0xe3c3e597, 0xad35dd25, 0xfabfbf18, 0xef2ebe2a,
- 0x461cd2fd, 0x159ef839, 0xfc8c59f4, 0xf5c1cf7d, 0xcd64d4db, 0x41cce8cf,
- 0x565833fd, 0xfc701ac6, 0xfcf9391f, 0x1ccea6dd, 0x96ffcbe4, 0xb6dcfdf4,
- 0x9061664e, 0x24eb0d4b, 0xff990616, 0xcc9e2fde, 0xeefff941, 0x6a7327be,
- 0xff8be063, 0xd0ce7b4e, 0x9af113c6, 0xd78da65a, 0xd5e3859d, 0xa26fcd7a,
- 0x66eb619c, 0x26f906fa, 0xdb633f9f, 0x8a3e6db3, 0xd7000ca7, 0xdf6a1d22,
- 0xf827d40d, 0xcc2eb82c, 0x4e90c612, 0x6ddc976d, 0xbe7cfec6, 0xdfda3742,
- 0xfd71f7da, 0x927a0ab7, 0xa7e44b0e, 0x24224ada, 0xfcb6bf9f, 0x13d7e8f7,
- 0x4c98d9d6, 0x72723ff2, 0x30fa2314, 0x4d4cde21, 0x55f50576, 0x5f4e1ada,
- 0xc81b1f91, 0x2427701f, 0x3f60644e, 0x763d3299, 0x17576f94, 0x9218b425,
- 0x184e7df0, 0x166767db, 0x2aa177d3, 0x34a1ff4e, 0x0c9e7146, 0xff212cd6,
- 0x97b72732, 0xe730a6b3, 0x4fee287a, 0x878c76e6, 0x05c9b779, 0xc612feb4,
- 0x68bc3425, 0x08e901fa, 0x927be5e5, 0xea48e885, 0x947ec892, 0xb1f39d0d,
- 0xeae891df, 0x8ad75c6e, 0x960d5d28, 0xb57441ff, 0x086f1b49, 0xa254055d,
- 0x78658f2b, 0xf62552ba, 0x90b3da95, 0x74affd1f, 0x424daf81, 0x6c7e44fe,
- 0x4016f1e1, 0x46b7ce19, 0xb16357f4, 0x47a8cb77, 0x63f7c6bc, 0xc13b8fe3,
- 0x25ff45ee, 0x787ced03, 0x40b35a8e, 0x3d6375a5, 0xdaefe8bd, 0x5f485b26,
- 0xc9e86bde, 0x7d263b43, 0xa401f35c, 0x25f9f48f, 0x6fc86b65, 0x5ea172cb,
- 0x714b5d40, 0xfdd3e587, 0x7e808edc, 0x9b668e91, 0xba6b3fc8, 0xdb9f9a6b,
- 0x2fc4d511, 0x15560dc1, 0xaef4e0f5, 0xf76455bc, 0x335e60af, 0xf6c771d1,
- 0x9c2f18c5, 0xaca2f76b, 0x213c62b3, 0xe7afe705, 0x93a956bb, 0xb5d0f1ec,
- 0x5d728bcc, 0xbbb6478b, 0x14ff777a, 0x09437ff5, 0xf183f7f9, 0x7a4642c9,
- 0xcbe5dda3, 0x1ebc0648, 0xa78f1bfa, 0x194297b5, 0xf5894f9e, 0xcbed9f6c,
- 0x76b94170, 0xdef09583, 0x07ebc1de, 0x49a0801c, 0xfea4a714, 0xeb859258,
- 0x81f2a1a1, 0x53699be2, 0x0db7f698, 0xb95a99cb, 0x41d92b6d, 0xe7b7ff1a,
- 0x251c7871, 0xc8b43cfe, 0xf1dcdf2f, 0x47f0027c, 0xa68dc61a, 0xb42117d2,
- 0xc92e29f7, 0x7cb614cb, 0x648000d0, 0xeb27f162, 0x5b115c67, 0xdfa3ede6,
- 0x7ac7af5b, 0xf583bfd0, 0x65e83608, 0x02b3ecad, 0xd11d6b1c, 0x60ec057a,
- 0x7c4961cb, 0x3375e4ff, 0x92fe610b, 0x93f43f18, 0xafc61f56, 0x5e374cac,
- 0x5c4a7c2c, 0xdfe846ff, 0x77ed6aae, 0x0684cf56, 0xe569960f, 0xb2f9d78f,
- 0xbea33fa0, 0xf8a9423f, 0x78da0b1e, 0x63383dcf, 0xa8ac86fd, 0xc2f6007d,
- 0x34cf2827, 0xebed613b, 0x60936d35, 0x43f39b2c, 0x4d5fea13, 0x12dd07df,
- 0xfcf121d9, 0xbe914b6a, 0x085d7d99, 0xcea575f6, 0x70a5b6be, 0xb2167afb,
- 0x2425f824, 0xfc2b83bf, 0xb05bed0c, 0xbeb0924b, 0xcff7b5ff, 0xfdf50d3e,
- 0x7272fe73, 0x6eed8a94, 0x557e8f9f, 0xf242a2f0, 0x0e5fb837, 0x9637c04b,
- 0x83576e2e, 0xb478a73e, 0x39b73f46, 0x42b8fd05, 0xed6ce30c, 0xa40aa4c7,
- 0x73a3f077, 0xf96b03be, 0x665f14a3, 0x9fd4454a, 0x65f79f8c, 0x189e3c29,
- 0x5edaae2c, 0x95effd84, 0xeb0bda18, 0x2da74f8b, 0xcdea7f24, 0xdf3145b4,
- 0x907e1c35, 0xdfb0d9f0, 0x2f1e2c38, 0x8f09914b, 0xf09e474d, 0x2f78dca1,
- 0xa84c912c, 0x68adc257, 0x1bd7d6d7, 0xe56422d0, 0x533705e1, 0x899e7d7c,
- 0x65f9868d, 0xdc177d08, 0x2a68637f, 0x93fe1bce, 0xff0ed5e0, 0x3b139262,
- 0xb4ec59e6, 0x7b5c514f, 0x99c1e13b, 0xac3c43e0, 0xc0caae2f, 0xcf669a71,
- 0x1e5c5272, 0x6fac39ec, 0x147bebba, 0x5ae0d7a7, 0x8d58d87f, 0xd8254ef6,
- 0xb806bf75, 0xabaf93b3, 0x8f5f02f6, 0xfe940f92, 0x465bca10, 0xba2fe390,
- 0x48b45d39, 0xcbb7d0fe, 0x62c78e29, 0x87b972e3, 0x7d78fdb9, 0x69da898a,
- 0x514fafef, 0x8457af08, 0xb923a67a, 0x6d7a571c, 0x99075768, 0xabf403ef,
- 0xeeaedf99, 0xf2e275a3, 0xa552bdcb, 0xddc59378, 0xac24ef7b, 0x7f2142bf,
- 0x0fbd2986, 0xadfdb8e0, 0x267aef6e, 0x77cb00f8, 0xea1c5095, 0x1e604a68,
- 0xb0a56fae, 0x5c8ffb57, 0x125b5a53, 0xf75abfb5, 0x01abc239, 0xf50ead0f,
- 0x93946afe, 0x2724289f, 0x33d22599, 0xf869fa1d, 0xfbf5326b, 0x0ea05b07,
- 0x86b569fb, 0x420e915b, 0x73b5321d, 0x6374b1cf, 0xe23eef3f, 0xd33b40e8,
- 0x48636ee8, 0x50bee0c7, 0xf6e2c49c, 0xd3ca1533, 0x09140b43, 0x5d9c45f5,
- 0x49e31d33, 0x29b8b7e4, 0xf82558de, 0xc1503463, 0x42b10b59, 0x5129e7cb,
- 0x4ff9e73b, 0x52f82ae7, 0x160c7fb3, 0x319e1f1e, 0xf8e1812f, 0x49c89eec,
- 0xdd9bc603, 0xe1ed0c3d, 0xc6894ec6, 0xdc7e2c69, 0xd2cbfe84, 0x41dfce4e,
- 0xfe006fe1, 0x58aed072, 0x76136291, 0x77a70b66, 0x147273d6, 0xbe31f9e2,
- 0x3b418c9e, 0xb2dfac47, 0xfd69da8a, 0xbc9c4499, 0x4093c451, 0xdafd5213,
- 0x58cecd14, 0xc26d9e2d, 0x6ee3e0ce, 0x327c7a91, 0xd254b3e2, 0xe7b573c5,
- 0x9277216e, 0x2166444e, 0xbe8046ff, 0x5db4ae30, 0x6ffb7d9a, 0x2bdb7e61,
- 0x14d179c6, 0xc93900f3, 0x481ef865, 0x7e5ef011, 0x485983f8, 0x119aac37,
- 0x9e1d36bf, 0xfd8a3726, 0xd217b404, 0x581dcd6d, 0x316b7e9f, 0xef8c67e9,
- 0x5ec0bee3, 0x3b0cd781, 0x5679eb8f, 0x9f70f287, 0xff84e92d, 0xf8e2dff6,
- 0x1f681213, 0xc6d61d23, 0x75cf4c91, 0xb0f2d718, 0x3f51a7d2, 0x32d46a7b,
- 0x4fdb4784, 0xd9a8fdc2, 0xa9c72425, 0x7c95ec9c, 0xabf9e07b, 0x01e11714,
- 0x846abcfc, 0xed87df17, 0xf4adfdd1, 0x38a5cde9, 0xe11fee2e, 0x5ba33fb3,
- 0xeb3538a1, 0xfc8fbddd, 0xf113b37e, 0xb9f87355, 0xd6ff5157, 0xed275858,
- 0x2dd9c5f7, 0xf1bc4e3f, 0x03a39449, 0xbeeecee7, 0xcefae11b, 0xd6806f21,
- 0x5c8f6f47, 0xcfb7157d, 0x5367dbdf, 0x23dc8ed1, 0x8fd836e4, 0x5fa127c4,
- 0xde327f72, 0x45397c8e, 0x960c9fef, 0x2476eeff, 0xf0042f87, 0xef918bed,
- 0x0dffe141, 0x444f9fd4, 0x20faf5fd, 0x2bffa03c, 0xed5076a3, 0x2bed1b5e,
- 0x7117fa0f, 0x8ff3c8f6, 0x0f4842d8, 0x14ad3be7, 0xfec45477, 0xe44739cc,
- 0x8b52444e, 0x284de4eb, 0xbdb7836f, 0xf0032bf7, 0xf7c1d29f, 0xec49143b,
- 0x3320bc87, 0x73e37fbe, 0x294feec6, 0x5f1e59ae, 0x3e47ca09, 0x6e2265ef,
- 0x48b92cb4, 0x7c32fbe5, 0x62596a5f, 0x53da1177, 0xb43d094f, 0xabef812c,
- 0xdd4cb80c, 0xac7baeb8, 0xb429f381, 0x67bfc2ff, 0xb1ab31bf, 0x611d2ffb,
- 0x299dd76e, 0x609b7436, 0x1f681d9e, 0xe06dbae0, 0xfb8330fb, 0x1dcdc7d5,
- 0x51938266, 0xc455a079, 0x95fdb5eb, 0x571e3ce3, 0xce51f627, 0x10fc59cc,
- 0x48b5a96e, 0x9fe8d5cd, 0x8d3f585d, 0xde77d7e2, 0x759e9b3f, 0xf771f4eb,
- 0xde99acc5, 0x5a94fb6b, 0x7996bbbc, 0x8e5edc4d, 0x600d11c6, 0x94eba8bf,
- 0x7997d42a, 0xe51ab9cc, 0xd5821abf, 0x16cf0c9a, 0x2ed1a278, 0x73b42419,
- 0x02775694, 0x16daefae, 0x50a9e903, 0xed87c18b, 0xb8e73c34, 0xd2a91c79,
- 0xb01ae3cd, 0x471c6154, 0x4518b67b, 0xb7f45fdc, 0xf1ba198a, 0x73f89069,
- 0x1ea953ad, 0xfd6b5f4e, 0x2d9b18b5, 0x648ba718, 0x7dae281b, 0x479be4c1,
- 0x22e4e371, 0xb67c0216, 0x55d79a38, 0x9de27af3, 0x9f88d60b, 0xb854afea,
- 0x64d4c921, 0x376e9f94, 0xe3c6538f, 0xbe9b516d, 0xd21fbf1c, 0xeb97d610,
- 0x464c6058, 0x883fdf01, 0x7376ef7d, 0x7d6175f9, 0xd7b7c09e, 0x9b567284,
- 0x8e2caaff, 0x7f364337, 0xcd5767e6, 0x77c83a43, 0x203f2899, 0xabe3c5df,
- 0x3f821330, 0x44b74aff, 0x6f0711f4, 0x486d1a0b, 0xdf7cad5f, 0x1fc2abee,
- 0xee55f70f, 0x7c1fa134, 0xab67dc1e, 0xdf689a73, 0x24e352f4, 0x72f5bab7,
- 0xf7fcb068, 0x9fb967f7, 0x3c8b2ad4, 0xa1c9270e, 0xcb9f275a, 0x48fbc919,
- 0x83b7be37, 0x68f3809d, 0x6ed0cb95, 0x9da37e99, 0xdc74d1e6, 0xc6e0714a,
- 0xa839bd15, 0x7aaa9bc7, 0x203f308b, 0xad08bf1e, 0x682fc9a2, 0xff06eb57,
- 0xd884ed03, 0xc547e476, 0x7efa07ef, 0x3f454ee4, 0xe781cce7, 0xb01d5f50,
- 0x7f82be92, 0x38c66d3d, 0xb23c91cb, 0x023ac6a3, 0x305db02b, 0xa3f77ba1,
- 0x70b76879, 0xcbb1a9bb, 0x617681dc, 0x3ecc4b6d, 0x06dffe1b, 0x5b1bbefd,
- 0x77f14c97, 0x5f7faed6, 0xbbee33bf, 0x6d70fb21, 0x4c5bceb4, 0xefc8b181,
- 0x9f6877a0, 0x81835cfc, 0x64ebb7f6, 0xb79462ef, 0x7b7aace7, 0xaf839cfc,
- 0x9addcfd7, 0xc22de13d, 0x0f2c1e75, 0x116f6759, 0x819d73ae, 0x69fb6205,
- 0xf58675c4, 0xf9d6265d, 0x8b9313dc, 0x3fdf9d70, 0xd708b930, 0xcdb18b79,
- 0xa8f37c87, 0x1b90f033, 0xe99bedfa, 0xf70a7b27, 0x2e8f913d, 0xc40f1e95,
- 0xff81e3d1, 0xefa47a3d, 0xc787d246, 0xebd0e106, 0xcd49b743, 0x6b507942,
- 0x5ea17f31, 0xe361bfc4, 0xc5331678, 0xfa7f8e3b, 0x5047c6e1, 0x64c9740e,
- 0x1dfd688f, 0x68050257, 0xd57f1d0f, 0x23490de3, 0xed18bff7, 0x07da0aad,
- 0x455c610c, 0x7b3403f3, 0x9f1e5e32, 0xc779f312, 0x7b42abed, 0x8dc6ebfc,
- 0x4b3bc5eb, 0xe76e43f8, 0x3cbc95ee, 0x7149dc6e, 0x0b63a6e4, 0x7e27189c,
- 0xc6e3cc27, 0x52944f4d, 0xfc21b8dc, 0x2de6374c, 0x89c92eb1, 0xdec347fe,
- 0xdb171337, 0xf82e7ea3, 0x5f236fb5, 0x3f7e8b31, 0x99f09de9, 0xc13b3ac4,
- 0x71ea157d, 0x42623b9b, 0x7f026fba, 0x9ad4f30f, 0xec49c894, 0x28cdc9b7,
- 0xb0fca31f, 0xf2d3ffde, 0x4df876a2, 0x74777724, 0xd7946149, 0x5e40a669,
- 0x9635ea16, 0x8b6b3ce5, 0x6ec7d9f2, 0x77f71b9f, 0xbedbfba3, 0xe4c771ff,
- 0x4f6ef51b, 0x35edfa22, 0xe5139f32, 0x908776d9, 0xb7c90a67, 0xc2ba778f,
- 0xb788ff3c, 0xedcc38ff, 0xef2d0684, 0x0add6148, 0xb9e2d7ac, 0xbd70d7be,
- 0xc777de51, 0xb2d8fbc9, 0x14bd2fb6, 0xf6e3d1f7, 0x0ddb63bf, 0xecc7e7ee,
- 0x61faeb7f, 0xb96aa5cd, 0x5f5bff7e, 0x327ee21f, 0xb2f2c3f0, 0xeb6afd28,
- 0x936fd1a0, 0xeb074388, 0xf483df4f, 0x392c3c1b, 0xe65bbed1, 0x0cbbf4e5,
- 0xc4f32dfc, 0x3acefca1, 0x238979f5, 0xaa697ff1, 0xcb07ff9e, 0xeaf8a0ff,
- 0x9c9aa915, 0xcdaf7ce4, 0x0fdb8b5f, 0xe24bb3ce, 0xaf37197c, 0x3e353f78,
- 0x99f9aede, 0x6f0f2a97, 0xe387841c, 0x0ffcb063, 0xc6b78796, 0xfda465e1,
- 0x0f2caf8c, 0x35f797ff, 0x35b63a1e, 0xb40efd11, 0x594fd1e3, 0xf3c8cfb7,
- 0xb1fd0023, 0x64b3c5fb, 0x9fef8fbb, 0x7ebd5aca, 0x259d5e1f, 0x5f39e1f6,
- 0x4c84f33f, 0xf628d6eb, 0x398f1b89, 0xdeb4d8bc, 0x69f684be, 0x6f4ff7e3,
- 0xe1660763, 0xa3efc552, 0x2e7e432e, 0xd4fdf2f8, 0xbcc1d4d6, 0x5bcc3c85,
- 0xcbd2aca8, 0x1fec67f9, 0xd66204a6, 0x1c04aabd, 0xdbe86182, 0x725884a2,
- 0xa9adfbcc, 0x467eaedc, 0x4c78f7e4, 0xa5e61d6c, 0x7cd8726c, 0x0c78cfe8,
- 0x47e8ff3c, 0x28edfe29, 0xc0aa2d17, 0x32ef91eb, 0x21e5e003, 0x95c92763,
- 0x8bdda350, 0xdf8b5072, 0x2c7ffd68, 0x592ec1f6, 0xfbd1c7ff, 0x7a65ff81,
- 0x53cfc78f, 0x755f78da, 0xe01b6edf, 0x8c17c746, 0xdc45f8e8, 0x4a1bca5f,
- 0x33f523bf, 0x9cbf1d12, 0x95217fea, 0x226fa2e4, 0xa25c2be5, 0x4795b19c,
- 0x889c60ce, 0x18ab341d, 0x0938c4d7, 0x190dc7e9, 0x5bd26f22, 0x80f29b39,
- 0xbf9895bd, 0xf3fe06f5, 0xc8ed91f2, 0xe1f5c1be, 0x88df6476, 0xecf5f3eb,
- 0xfe9dbbc8, 0x7d6748b3, 0x6f947cd3, 0xf001d6be, 0x0bf87fa3, 0xd3b4779e,
- 0xa773e9ca, 0x2d92e9c4, 0x78a4b94f, 0x7471a7cb, 0x91ffe9f5, 0x8da4b51c,
- 0xbdfe5764, 0x125fe8e5, 0x723a7e31, 0xa79e213f, 0x7843d55b, 0xd8931c8b,
- 0x76b8989e, 0xe0cff310, 0xaf010cfb, 0xe123fef6, 0xf34c2c37, 0xfbc1a665,
- 0x58b35ff7, 0x3e981258, 0x362e5ce5, 0xafb4edf9, 0xf3c9d4d0, 0x30569a5f,
- 0x184de392, 0x78c12d37, 0x98b66ce2, 0x428189e2, 0xfb5b93cc, 0x27243dba,
- 0x0e7dbc61, 0xffaf3b43, 0xdebe5e35, 0xfec62815, 0x697a2b83, 0xce7da31f,
- 0x5587947b, 0xf787f9f9, 0xbc139754, 0x9b704f14, 0x6e25e7f5, 0x0efbe34c,
- 0xa69fd3da, 0xe28fbbad, 0xf3d7eff9, 0xdba0e2bc, 0x84b8c4e7, 0xa9b70f16,
- 0xd0afb43d, 0x6f1b9074, 0x0f9f3295, 0xd11669fb, 0x69c1d353, 0x653718a5,
- 0xb452d69d, 0x6cff2b77, 0xfdefbf27, 0x4f2932bb, 0xe04a68e2, 0x51d7846a,
- 0xed16be1e, 0x07185cd3, 0x0ff7deed, 0x708a5b5c, 0x0b6ff26b, 0xfda1cdc6,
- 0x1e3e8716, 0xdf3c2cce, 0x51d1e1bb, 0x1abcdc5a, 0xf045b3f1, 0x55b7b321,
- 0xef861ece, 0x974f7e35, 0xfa7fd40d, 0x3fb42df7, 0x2d83c9ae, 0x14b01646,
- 0x24c8e544, 0x74183f91, 0xaec5fc8b, 0x453f3cd9, 0xa9e2ed94, 0xf71df3e1,
- 0xaf3849cc, 0x37ca6949, 0x4a72c7db, 0xac7dd8f6, 0xea0148bf, 0xd0c4f317,
- 0xa515874f, 0x22ed8b78, 0x9df3a3b7, 0xc723a226, 0xa7f7c63a, 0x9ed08e80,
- 0x33d222bf, 0x59e6093d, 0x057dded8, 0x45f8f7e2, 0x3293ad03, 0x97da45fb,
- 0x78f89249, 0x5b7a1b05, 0xc61c60c7, 0xb895caf9, 0xb39b6a94, 0x36f8b70a,
- 0xa477fcb9, 0x1737df11, 0xff5578e3, 0x9379e461, 0x5f146cc7, 0x4659cf68,
- 0xaffd9379, 0x3ee7759b, 0xb6219fe2, 0xf324f29a, 0xf691ff0f, 0x25071c07,
- 0xe7b4de1d, 0xbe76697d, 0x99ea156f, 0x5735b945, 0x2abe49b8, 0x421cfec7,
- 0x5569437b, 0x16b0f250, 0x4560cfa3, 0x518ab5f9, 0xbb747f3c, 0x95eb80d3,
- 0x0662f22b, 0x6275ff8e, 0x6d15fc80, 0xf3cc203f, 0xf7bd8c9a, 0xaca61fa0,
- 0x842abdea, 0x65d071eb, 0xa9b8c268, 0xf144d231, 0x8a366396, 0x2e1ee6af,
- 0x282dfd58, 0xd273aee7, 0xd1c0d7fe, 0x6f94b9a5, 0x3d1cf30e, 0x4cef3ccc,
- 0xcd4879e3, 0x63945e82, 0x33ea0336, 0xe2f33365, 0x3e2d79e8, 0x7ef802e7,
- 0x3a2153b4, 0x0816985f, 0x9e0e7ae3, 0xc09e596f, 0x3c28b7cf, 0xfe58e23e,
- 0xdcf12ffa, 0xb7116ec8, 0xfc7c713d, 0xb5f38a1c, 0xfde2122a, 0x51e78b82,
- 0x3fa6963e, 0xf7c51087, 0xcd47ca09, 0xae47f63f, 0xf60da0bf, 0x7d3918af,
- 0x0eeead28, 0x3bf6278c, 0x7b7f9402, 0x4cb74b65, 0xbece63fb, 0x18d5aa07,
- 0xd71b66bf, 0xb9fb4d27, 0xc7ef1e1f, 0xf91e997c, 0xe13ca0ed, 0xfcb0647a,
- 0x7a4fb20f, 0x57c7f4e2, 0xde984ff6, 0x53b78baf, 0x21b8fde2, 0x7f5c7776,
- 0x5a2bd923, 0x745549be, 0x3b376e1c, 0xa4287b34, 0xb2a9c7cb, 0x166bf38b,
- 0x260fff7d, 0x22ff793b, 0x8d6d273f, 0x7d414aba, 0xe28c2ff5, 0x90fe5a73,
- 0xaa142f96, 0x213d79e2, 0xb7ce8583, 0xe51b5879, 0xdd628d09, 0xb4714492,
- 0xa7df865e, 0x7c10be63, 0xf2d2ffff, 0xcc5dffa9, 0x39264ebb, 0xbf084aa9,
- 0x524cf315, 0xf6f0ee10, 0x77de38c5, 0x159e34ec, 0xc8524cf3, 0xcdfe209f,
- 0xd4fcf3f4, 0x7f7cf5e9, 0x30f41321, 0x390b3396, 0x99e75a5d, 0xcb555f28,
- 0x4cf2d11f, 0x0954bc34, 0x598e677c, 0x5072879c, 0x92d947cb, 0xfb44ade0,
- 0x7b0255a7, 0x90d3e71a, 0x784bf220, 0xf90dedbf, 0xaff7a461, 0x8f127f9b,
- 0x650f2d67, 0x3d206272, 0x5e7a22bd, 0xd11fcb4e, 0x3d6626e8, 0xc71dae09,
- 0x555f3db8, 0x0c79a26f, 0x71475c34, 0x030681c9, 0xd55fbd43, 0x1874e665,
- 0x798ede37, 0xfd8dd626, 0xe52b612a, 0xf87a0bd7, 0xd6167b32, 0xbee318b7,
- 0x2fee5627, 0x7fde03e8, 0x3d276576, 0xa752ac07, 0x33ce893c, 0x950947ce,
- 0x5eb8e9e3, 0x6af31cb9, 0x90123922, 0x0fed84d0, 0x353950d7, 0xa79606f2,
- 0x51ae5e7a, 0x8c0c4f40, 0xa096ec8e, 0x2ddb7fbd, 0x99b48cbc, 0x7d3dfa09,
- 0xe4a84d76, 0x363be81b, 0x2aa36f24, 0x37e2953d, 0xbc50f4f7, 0x72bbe848,
- 0x0cd91f2e, 0xabc79873, 0x9d9b8a54, 0x3b23c8ca, 0x7f9c5ec0, 0xb3eb07b0,
- 0x836714cc, 0x53ffa27a, 0x7af1a7a3, 0xcb3faf95, 0x0dfcf072, 0xf9421bd6,
- 0x1a6f2a76, 0x911babc5, 0xb29ec03f, 0x7073023b, 0x3d49cf5d, 0x9c3f2277,
- 0x25cff99a, 0x0ee7e748, 0xe510b4fd, 0xb02635cf, 0x379187d3, 0xde5c1969,
- 0xebed180c, 0x65e7e824, 0xd8fbe07b, 0xf9b6abcf, 0x7cd530b3, 0x1334ca5e,
- 0xa1601d1e, 0xff28c85f, 0xb9fac552, 0xd1fb72e6, 0x612fc335, 0x2b1ae81e,
- 0xa0352387, 0x099ec8f8, 0x03be95cc, 0x09235ff3, 0x49a986fb, 0x6aa887e4,
- 0xcb21fa12, 0x5946b9c4, 0xf82cb7f0, 0x7b2b0ffb, 0xd830150a, 0x2cdcef2e,
- 0xdedfe70f, 0x686fe718, 0x5ce94dcf, 0xd591cf4e, 0x6e1f4809, 0xd7df91e3,
- 0x26c93ac0, 0xbdf1186f, 0xfb41db26, 0x2a3b4fb7, 0xafd0bd3d, 0xe52ffb94,
- 0x26bd5798, 0x71ca5ffb, 0xf64e4d9f, 0xe531fc7a, 0xf52ae94d, 0x21db0337,
- 0xe5cd6cfe, 0xbbfd7f18, 0xfd0497f5, 0xfefd7c95, 0x7331fb06, 0x225996b8,
- 0xddf00a39, 0x03c0d6cd, 0x16177eb8, 0xb3fb49bc, 0x7a9e6677, 0x4e2bf303,
- 0x88cf9919, 0x9c432472, 0x8ebd033f, 0x75cc9ee3, 0xce53f3f1, 0xb113d36d,
- 0xf2e9c05c, 0x7da6165a, 0xfcb99af5, 0xacf5e3bc, 0xda17a5a7, 0xaa31e35d,
- 0x71fc31bd, 0x5f2faaad, 0xd72fac5f, 0x7f8e3c88, 0xdfdfeaf2, 0xd20a22c0,
- 0x7ca7b7e9, 0xfdf62636, 0x2fdf5653, 0x929e8f90, 0xe867de78, 0xfb24e672,
- 0xd0852dd9, 0x64ff199e, 0xc9ff38a6, 0x55ff13f3, 0x4e4f5ff8, 0xb69f5461,
- 0x82c7b2df, 0x2d9e22f5, 0x1ef1fa8b, 0x264dc966, 0x30fa49b9, 0x473c8922,
- 0xb0f1ed37, 0x793bb743, 0x9ada175c, 0x0b439fa0, 0x9a4bc254, 0x42aec0dd,
- 0x10b72bfe, 0xbe7469ff, 0x0af40ac6, 0x651ca978, 0x5dfa4049, 0xc36ef463,
- 0xb304e4be, 0x5a6ffa8a, 0x96fa85a2, 0xfe90a67f, 0x33356558, 0xdc4f9427,
- 0x68654097, 0x44e07247, 0x718c2985, 0xee4235ee, 0x481bf7cb, 0xcc2a567f,
- 0xd01b798f, 0x9fdf1bae, 0x3b50b0c8, 0x7c5cd298, 0xf1a8ca7f, 0xf28534d5,
- 0x1aec0538, 0xf488c13f, 0x57e0ab7e, 0xb3cdf059, 0xfb8d0700, 0x7141dc82,
- 0x05bd5530, 0x632de7cb, 0x70511ce8, 0x629b9cf0, 0x9d8ac1c0, 0xf8bbdf82,
- 0x3f8d3339, 0xd2017935, 0x28b710ad, 0x6d0e3125, 0x3ea1a7af, 0x6b5f6466,
- 0x07edaafc, 0x76b45b66, 0xcffb0f8a, 0x3cd9df10, 0xdcb84279, 0x47fca668,
- 0x7aea5ef1, 0x1fa413ee, 0xaf77af8d, 0x3d7c40bd, 0x3fc5df14, 0x0e75f2a6,
- 0x98f7c727, 0x391fe42c, 0xea164c61, 0xaf2e359f, 0x17298fea, 0x4bcff903,
- 0x3b407c46, 0x7d58df28, 0x918950aa, 0xe70f36f3, 0x4be76857, 0xb09f7c01,
- 0x67c859aa, 0xc8db8cc3, 0x7dfdb5c7, 0xb8c0f5c7, 0x0384eed0, 0x7b7685c6,
- 0x436ee6ad, 0x4fe370e2, 0x2fbc7151, 0x6eb1971b, 0x04eb9e22, 0x420e815e,
- 0xe13a3718, 0x5e3d1030, 0x4f7bf227, 0x58f1f2a4, 0xa65f3eb1, 0x40d0e810,
- 0xfcfa58f9, 0x9da46b98, 0xb6efa82d, 0x20f7135a, 0xe8273ddd, 0x67eda4e2,
- 0x3cef6885, 0x59e8bf37, 0x92b3eb94, 0x9120b556, 0x893ac75c, 0x757935ef,
- 0x4acde321, 0x1adc832c, 0xbff581e7, 0x7cd4ff33, 0xd759fcec, 0x5fd442d6,
- 0x7bc60f20, 0xafc28752, 0x37069fd1, 0xfbd221d2, 0xc1c61d20, 0xbb11d1af,
- 0x0b1293a1, 0x88bd8177, 0x047ecd4f, 0x91e7884f, 0xf9d1d9ab, 0xb2cf1101,
- 0x3479f334, 0x6bee0884, 0x9e500f5c, 0x0199e5d9, 0x69d6079f, 0x720fa4de,
- 0x59ec6c14, 0x76e30630, 0xffb4ef00, 0xede3784b, 0xa7cb2fe5, 0xb58f891e,
- 0xfb39a5f1, 0x383a9f29, 0xd5f94ed7, 0x693e45d3, 0x7140deb0, 0xc8abf074,
- 0x96626f1e, 0xa9ddca30, 0xf2d5bec2, 0x3c4a8ffc, 0xc27a193e, 0xb18beeac,
- 0x59e68793, 0x1dc794ab, 0xb1f3c15a, 0x46e0ed07, 0x9060ec95, 0x0573badb,
- 0x765ca5ed, 0xd2aedfb7, 0x24a79979, 0x80b43ede, 0x7db3dc51, 0xe45fa8b6,
- 0x58f76b0c, 0x7cd16948, 0x460ef6f7, 0xc8eedff4, 0x594cfaa7, 0x16fdcb9c,
- 0x79ed37d7, 0xbf6c4fdc, 0xb7ea88b9, 0x52c78424, 0x87d88f5e, 0xf5fb81df,
- 0x7f1fb05f, 0xe3f3479f, 0xb0751c78, 0xa38a77fc, 0xb40cea3e, 0x2a2dfd21,
- 0x8118e5f1, 0x3c4cea5e, 0xbaf40a9e, 0x7a6187b3, 0xfa21735f, 0xe6b2d73b,
- 0x44050c57, 0x2e905baf, 0x7a078de7, 0xebd1d02d, 0x97054f56, 0x469708db,
- 0x5a7483af, 0x17379f1c, 0x76fb6308, 0x9b9fe757, 0x32e83fd0, 0x30de797b,
- 0x978c83cf, 0x2cf0310f, 0x6e3c3854, 0xf6782659, 0xc1c4ff13, 0x137c2973,
- 0x8ce9a74b, 0xfc48c7f3, 0x90b0ae93, 0x3fca2ca3, 0x4f03594f, 0x7c83b8e2,
- 0x0bf70f74, 0xdb2dc087, 0xba6e9e89, 0x0517ef99, 0xe3ef5c6d, 0x8c0651be,
- 0x7f8c5b3f, 0x867fab53, 0x96cddb0b, 0xe1ba1e38, 0x1cff007f, 0xabbb3f51,
- 0xe6c6f291, 0x8e9e30cc, 0x793473b5, 0xcd53eda9, 0x746fed13, 0x1e6236ce,
- 0xfd1adcf7, 0x5bbcd0fe, 0x4dd4fef8, 0xccfdf573, 0xa03e1b63, 0x6cd646fc,
- 0xbbcdfc44, 0x8aff5f45, 0x695f7067, 0x3d2bee0c, 0x0329e22b, 0x47c827c0,
- 0xb25d4dbf, 0xf3a076f3, 0x292f3f31, 0xcccf38c3, 0x9bbd86b4, 0x8ee8fca1,
- 0x6dfe5471, 0x747ff7da, 0x1777eb0a, 0x41867951, 0x90c7e7e2, 0x8acf810f,
- 0x2ebe6f2b, 0x89f5112f, 0x4676f7e8, 0x81093def, 0xced0d9f6, 0xf29f3133,
- 0xf888673e, 0x5e22c0c0, 0x0724fd7f, 0x55bded4f, 0x8ceaf8a5, 0xe47cc884,
- 0xff4b1783, 0x90f30cb3, 0x728be467, 0xb0e353d9, 0xc1f4acfc, 0xfd67d47c,
- 0xd705768d, 0xc79329a1, 0x4b17c7a5, 0xe22763dd, 0x7fd12c79, 0x4d579f23,
- 0x91322fd9, 0xf154664f, 0xa77bc67e, 0x3b6016b5, 0xf72a79c3, 0x11125a67,
- 0x19bf1aff, 0xd9a41f84, 0x27217e8d, 0xd9bdf49e, 0xfafd0292, 0xa717922d,
- 0x26f29fe8, 0x9d9817c5, 0xfbf3a79f, 0x6b8c14f2, 0x3cf1f74f, 0xd8ab6dd5,
- 0xb6f3b42a, 0xd653e95d, 0x0b74fd40, 0x7a04f5a3, 0xbd206537, 0x2720fe4f,
- 0xaecc8911, 0x9e8d77a7, 0x3e746b66, 0xc0cf4f43, 0xfefc76a7, 0x8eb5e4cb,
- 0x7a51ad9e, 0x09ce291e, 0xa0646570, 0x5e96f85c, 0x138e0d8f, 0xe3f18fc7,
- 0xf027248e, 0x46de562f, 0xbe24ebe1, 0xbfecc2cb, 0x36cbe402, 0xe1c72f8d,
- 0x1e864cfc, 0x2b943f3a, 0x01d1c779, 0x0b5e29dc, 0xfe38b9e9, 0xc6cbe0d4,
- 0x50d972d8, 0xd14ff0b8, 0xe7fe50ec, 0x9643f8c6, 0x7cef87a8, 0x170a392c,
- 0xf1153f8c, 0xf0e1eec0, 0xb99a92ec, 0x867e115c, 0xd268b716, 0x3f587be6,
- 0x7e04cadf, 0x7183df8e, 0x285bda26, 0xf708371d, 0x3683ac25, 0xdfd0a09f,
- 0x877e2d73, 0x1df6e609, 0xcfd11d57, 0xba834177, 0x811d5d70, 0x279c236f,
- 0xe863a10c, 0x3e622d8f, 0xfa065fda, 0x445467f0, 0x37834bd7, 0x234d4f1e,
- 0xf9f8d1c8, 0xba27e3c4, 0xf8193d6e, 0x0de7ced4, 0xe712f7ce, 0xb89f6f19,
- 0x5f78fa4d, 0x25cb88b2, 0xc570e347, 0x12c35f58, 0xf38714bc, 0xd5bfe44a,
- 0x7281bd80, 0x519aa6b9, 0x6ed9243c, 0x669c38a0, 0x27c48c77, 0x48c55f57,
- 0x632cd54e, 0x9f205ce2, 0xa63d3c5f, 0x931fdeb3, 0xb7516bff, 0xaf7e442f,
- 0xf0f2ebb7, 0x6e3cec6b, 0x1b935ebf, 0xf502b7ac, 0x887960fc, 0x40adef9e,
- 0xff7f13b9, 0x1e45cd57, 0x28be4e2f, 0xfbc6b3d1, 0xf9ea0566, 0x0adeeae4,
- 0x240f5f94, 0x75c5eef9, 0xe3c0c37d, 0xdcf8f1ea, 0xe2d0619a, 0xa74497c5,
- 0x78347cf1, 0xd811dace, 0xf168e381, 0x0f5273a4, 0x38a64f8f, 0x3c81ff45,
- 0x4ba067a4, 0x20669a23, 0x1cff3f27, 0x37fc519d, 0xf726ede0, 0x7b9c9aed,
- 0x18dce498, 0x5cfdd7a1, 0xbe9cf89e, 0x4e1c19bd, 0x021dcbc2, 0x9e85332f,
- 0x2653bf3d, 0xaf86643f, 0xa16e2b78, 0xb2379f04, 0x8fb1f130, 0x8f76a3f4,
- 0xa83079d7, 0x63fdb1ba, 0x4bb7d20e, 0xfda3a85e, 0x0cdb31a5, 0x97d18d4c,
- 0xba09c363, 0xefc641fb, 0x2795d64f, 0xdaea6674, 0xaf9c3a4f, 0x1eed2fab,
- 0xecbfaba7, 0xb95d32f9, 0xaeaa67a2, 0xab57e4fd, 0x7bcbe574, 0x7fb5d3af,
- 0xe03df504, 0xccef5bf5, 0xefffbdd1, 0xc79eb31d, 0x232bdcfd, 0x7f7dd3df,
- 0x5819c446, 0x0c53d7c8, 0xd1a85ff3, 0xdd5ac5ef, 0x74d660f7, 0x0728954b,
- 0x0dc2dff8, 0x1a7d4f3c, 0xbfb62c60, 0x7b7a6d45, 0x508b2662, 0x58535f7e,
- 0xcc3376f2, 0x37d7d353, 0xbc20ee1c, 0x013dd97e, 0x0c0bdc63, 0x197d0f48,
- 0x858c6760, 0x14b0a47f, 0x891bb3cc, 0xfd6cbfff, 0xd7e1588b, 0x47b37f5a,
- 0x5556febf, 0x62b6febf, 0xbc3bfafd, 0x9a4ff5fa, 0x977f5fa2, 0x29febf4f,
- 0x4ff5fad5, 0x3fd7ebf5, 0xfd7e9e7d, 0xf5fa0233, 0x5faf551f, 0xfd66ecf7,
- 0xd72ee77a, 0xe85e6baf, 0x36fdfd36, 0xd1a07471, 0x0b4f2693, 0x7711ddd6,
- 0x19818e1f, 0xa342e862, 0x7afe85b3, 0xdd1a5fca, 0x78dd13f6, 0x8631f4f1,
- 0x6fcbbc89, 0x99851f48, 0x7f981740, 0x3f92cc99, 0x1bef3d27, 0xd43a999d,
- 0x56e4d0be, 0xf58f3eac, 0x6792478f, 0xf094f443, 0x53d44797, 0xa35b2fe8,
- 0x7448f2fe, 0xfd031afa, 0xa06f834a, 0x4ecdd838, 0x0489c70e, 0x887fb76e,
- 0x3b439755, 0xe0053368, 0x03e70d7d, 0x3096bfe3, 0xdf1de29e, 0x1c469d63,
- 0x43d616f7, 0x422cf9cf, 0xea7300cf, 0x642c7dce, 0x7f88937e, 0x8159975c,
- 0x4ade9171, 0x1617a394, 0xf6837a9c, 0xb94c5eb3, 0x4e327ba4, 0x68c97ee3,
- 0xb90acec6, 0x26fb87d1, 0x8ab7ee50, 0xa98fa078, 0x9e7c18ee, 0xdacbf115,
- 0x57e912e9, 0x7e502726, 0x2577ed57, 0xffb54fd2, 0x99759fc3, 0xff1eae3c,
- 0xc35cb35c, 0x0bb09b6b, 0x5f707db8, 0xbbf54aa6, 0xb276aa60, 0x944ebd43,
- 0xdf1fd0ff, 0x44d878c7, 0xc2c7b9fe, 0xa29504e1, 0xe3a64c5c, 0xb8eeb474,
- 0xcbee78fe, 0x4df0e163, 0x22e59850, 0x02cf1fbc, 0x95de1764, 0xdffd4f99,
- 0xe38880ab, 0xfec38ffd, 0x15684a3d, 0xc07fd1c5, 0x5bf471f4, 0xa38a259a,
- 0x85e000ff, 0xf5e9c7a7, 0xcad61ea0, 0x33bc05ab, 0x4fbc1db0, 0x184b34f7,
- 0xfdbafaff, 0x78c3f60d, 0x7887f83f, 0x59a1e2d7, 0x58668740, 0x603fbdd7,
- 0x8f8bcf14, 0x41928e8b, 0x93fe63a2, 0xf7ab9f91, 0x9fb8db28, 0xd4ebd27a,
- 0xd1987dc5, 0xbf20e785, 0xbcc2decc, 0xe731b3e5, 0x87bd600c, 0xe9747fbd,
- 0xbf2fbe28, 0x31676566, 0x4fd88dd1, 0x7ee57bbc, 0x978acb2a, 0x3ef10af2,
- 0xf7cc572a, 0xc7d43726, 0x8762bbf0, 0x90e463ef, 0xcba7eed1, 0xd959ee57,
- 0x4678fb43, 0xdad66f71, 0x819c3bac, 0x2fc77898, 0x631d8533, 0x1a673109,
- 0xfc37a613, 0xe19d33bd, 0xe54ecafa, 0xcb5fac6c, 0x886c979e, 0xcf4146b7,
- 0xd7ba092f, 0x607b36e0, 0x5eb818bc, 0xe8def412, 0x3ce131ec, 0xe8b5825e,
- 0xd2b4b8c1, 0xd3fba6e3, 0x1c93716e, 0x83ac41ba, 0x8dd4a0f9, 0x0acc4ae7,
- 0x5ec5f99e, 0x832fda7a, 0x64bcf726, 0x76efb864, 0x2435c54f, 0xcdc94d4f,
- 0x8fa06ede, 0xc8b4be1f, 0xaf061819, 0x51ecd3da, 0xc5cac42e, 0x5f8532e7,
- 0xc64d993e, 0x1e061975, 0x743f93d2, 0x587e6ff2, 0x7e58f3c1, 0xf94603f8,
- 0xfc396ced, 0x94f14655, 0xf724bcca, 0x2f422c5c, 0x0604ac37, 0xe8f6031c,
- 0x980b0b4a, 0x66b21f41, 0x98d2d3b2, 0x4369e88f, 0x3ade8be9, 0xf65ecef8,
- 0xcff462bb, 0xaff8abef, 0x2a3b2c66, 0xf2c7af5f, 0x758fb1fa, 0x1d9a0e62,
- 0xde537161, 0xe0af1850, 0xaff7184c, 0x3b6357fb, 0x1f798f7c, 0xe01ef0d5,
- 0x574277b9, 0x26dbdb04, 0xeb077d1e, 0x96ddec13, 0xe12ef802, 0x0055e616,
- 0xf2dea95f, 0x74f00569, 0xb02f4395, 0xbdf136d4, 0x37ef0a6d, 0xdd26bf7e,
- 0x43df87be, 0xfb130573, 0x045efca2, 0xd5233f6d, 0x0aada7be, 0xbea156e5,
- 0x8f8141fe, 0xcfe3fb14, 0x303d63e7, 0xad1668dc, 0xbbd4407f, 0x54f78fec,
- 0xdd165cf1, 0xff459bf7, 0x97037649, 0xfb132a57, 0x937ebcb6, 0xf56ab7a8,
- 0x65f6261e, 0xa8ab7d79, 0xde79db37, 0xeeb7b012, 0xfc62b5fb, 0x2c0c5bb4,
- 0xeecf4310, 0x102c09b9, 0x35c91f43, 0xd1b2bac9, 0x3b25cfce, 0xbeea6467,
- 0x5bbdfad3, 0x45789b8c, 0x4b3beebe, 0xfb7d38e1, 0xcfa4c9b9, 0x367810ee,
- 0xeae99565, 0xacfef3b5, 0xf273b45d, 0xaa7b8a76, 0xaaf3dfae, 0xe072849a,
- 0xdd1ae5ec, 0xb7482d7a, 0xd3f23877, 0xbc21bf71, 0xa3353a12, 0xa788b13c,
- 0x683d3c53, 0xa553c05c, 0x7b889e72, 0x853959ae, 0x6e807bca, 0x95a1feb1,
- 0x82ef2a5e, 0x9fcf0ab2, 0xbc2a3f43, 0x60fd0edf, 0x83f42b79, 0x1fa107cf,
- 0xe3003e7c, 0xf866fd61, 0xa09bcb0e, 0xb7df2c3f, 0x7be547d2, 0xb9535657,
- 0xca9fa575, 0xa3ce576b, 0x032bdde7, 0xb2b35cf4, 0x8e67ea9e, 0x6bedfae2,
- 0xb39405e7, 0x9980bcf8, 0xe7a22aa3, 0x80bcb43a, 0xfef0d30e, 0xb8a3cddc,
- 0xfe65cc1c, 0xfe9c2da7, 0xecc89ee9, 0xa34f9d0d, 0xe7e29bdf, 0xa1b191eb,
- 0xd55dea99, 0x3bed1c7c, 0xacb10ee6, 0x158c7e4a, 0xea4bf5db, 0x1997ca6a,
- 0xcceae3cb, 0x256a6213, 0xfe974ebf, 0x13e90894, 0x5f2f58a5, 0xdfc3ccf3,
- 0xe3101d53, 0x3ecd85c8, 0x8a658e9c, 0xc4f31bbf, 0x9d00deed, 0x08bdcfef,
- 0x9b1f839d, 0xa62af174, 0xaee2e982, 0xc9d1dbd1, 0x7674ca33, 0x89b17caa,
- 0xbeb259da, 0x72676ba7, 0xd5daead7, 0xc7bbcd2e, 0xc518f883, 0xb0de61e7,
- 0xb8c0658a, 0xd337da8b, 0xbac5ebb8, 0xbdf97cc1, 0x3e2407d6, 0x3dbf615f,
- 0xb5f314ea, 0x3ab9206c, 0x458bc5c6, 0xca032149, 0x9d7ff7c3, 0xc8fafc44,
- 0x478a0643, 0x0361658e, 0x5078d7ae, 0x813f58d3, 0x127952f5, 0x9728574a,
- 0xf2c65532, 0x7e422c65, 0xab6fd82e, 0xe49b9d71, 0x285643c0, 0x3c0ecb9f,
- 0xba91f3ca, 0x8914af49, 0xecd228f5, 0x7c4a6dd8, 0x28dd6f7c, 0xe7f58ff2,
- 0x9bf7e295, 0xd32a3957, 0x1fe8fed1, 0xe6cc7f21, 0x42dcf339, 0xe32dbfc0,
- 0xef6a7a4d, 0xc30d55ef, 0x787de39e, 0xf2cdf494, 0xfbfac33e, 0x1fde81b8,
- 0x2b9c79c6, 0x5e6603f9, 0x08c2a6b1, 0x8c6b09f9, 0x93509c9a, 0xecb63d98,
- 0xf331624d, 0xabe56478, 0xec090a05, 0x764de100, 0xe7cc746a, 0xea527f2b,
- 0x22a63cc4, 0x7fb93791, 0x8ce14665, 0x7befd1d1, 0xb3141d04, 0xc5ff924e,
- 0xfc97836e, 0xe7539f48, 0xdb0b5a77, 0x445e787c, 0x98bcc71e, 0xb5963363,
- 0xf96b39d1, 0x23c9326f, 0x4cb5c4f9, 0xc123bb05, 0x7b216619, 0xfc265fb4,
- 0xf9091fd7, 0x067d91f9, 0x68e72fc1, 0xc8f9e1f7, 0xe9c8f9de, 0xd49e6275,
- 0xfa46ed47, 0xafad3e48, 0x5f7a762f, 0x2e9d000d, 0x22f3683e, 0x6dc50978,
- 0xbca03f74, 0x1259625b, 0x20f3c1c1, 0x6cbdb993, 0x42c956dc, 0x1b579eb0,
- 0xbf098702, 0x8321eabd, 0x5da1fca6, 0xee898a63, 0x78831f67, 0x6e5e23b1,
- 0x43819c2e, 0x1e131617, 0xbf798917, 0x26b1e625, 0x80bfc35b, 0x787cf987,
- 0x76e2e09f, 0xcfd6efcd, 0xaa92def3, 0x4b7d636f, 0xa0f94c8f, 0x973cf8f1,
- 0x44c4a7f8, 0xf1daf058, 0x70046e3c, 0xa0fc85be, 0x8829dc20, 0xb69fbe5f,
- 0xe30a69c4, 0xa97ee039, 0x30f29ab3, 0x7f281827, 0xdf2e9e35, 0xf368f617,
- 0x6d3d2728, 0xcf44b39e, 0x73df72d1, 0x7fc8530b, 0xaed67ae0, 0x9f16bcf0,
- 0xf78d8d4f, 0x28e2d7ad, 0x413f5f22, 0xdf783bc0, 0x479e38d8, 0xdb3d6768,
- 0x24664f30, 0x9590c6bf, 0xc0d7e717, 0x54fd20d2, 0x651f2858, 0xa4e796bd,
- 0x8f29529e, 0xe7989e1b, 0xba741164, 0xb9efc1d6, 0x3a37e6d0, 0xd1d1cb8b,
- 0x06ff9c59, 0x86de5a2c, 0x2634a6af, 0xabb6bfff, 0x6d75fc8e, 0xc4406a3f,
- 0xf4120649, 0x820d47fb, 0x6d9e0614, 0x7dc04aab, 0x1fbe3690, 0x3d75d0d5,
- 0xd8f2efbf, 0x285f7403, 0x3d22a9f4, 0x75f689d4, 0xfafef4eb, 0xe201fda2,
- 0x4078f8d7, 0x980fffbc, 0x1e5da133, 0x67e7ffef, 0xcbdf7f09, 0xe9bf714a,
- 0x938286cc, 0x29b70009, 0xd1b9d18f, 0x74e3f251, 0xa5583bef, 0x26cf786d,
- 0xcaf7e12b, 0x0fffafc4, 0x97844db2, 0xdf5f12fd, 0xf13b68d0, 0x2e0afec1,
- 0x7d3ff607, 0x28d186fe, 0x7d2572cf, 0x91ae713e, 0x818b77df, 0xc9df787e,
- 0xf970f558, 0x0cb23362, 0x5fcf4cdf, 0x8d7b97a1, 0xda4f7b87, 0xd37f9254,
- 0x4f3d70b3, 0x84b125fe, 0xf74228f8, 0x83b9a3e6, 0x78dc21e3, 0xe180e36e,
- 0xf4b1f983, 0x452cddf0, 0x66f86dc0, 0x1e8678f2, 0xaf2573ae, 0xe1c75da4,
- 0xf50b29ba, 0xb4e9f763, 0x0d7c7cd8, 0xc35503ae, 0xf86e2b9f, 0x029a78a6,
- 0x8b0e54f0, 0xc22ffaa7, 0xf0d301d3, 0xc04cfcf0, 0xf2cf6ff3, 0xd6862efb,
- 0x6dfb437f, 0x1efe1c67, 0xc509b9eb, 0x33fbc036, 0x2fa79fc2, 0x04c2f68d,
- 0x05cb3afe, 0xf90b967d, 0x895f25e3, 0x4c9f5f05, 0x0a9d64f9, 0x72c1a94b,
- 0x2aef42e5, 0x4a7f7a35, 0xfca010d0, 0x79baf67c, 0x4477f958, 0x990385c8,
- 0x3878b0d2, 0xf4f9e628, 0xa8b9b58b, 0xd57dee67, 0xb42e50cc, 0x5efdfb08,
- 0xef05a767, 0x88f0d59f, 0x067832e5, 0x5ec5914d, 0x647f972c, 0x8cc3ed51,
- 0x6de3e067, 0x6d1be38a, 0xabf9ed3c, 0x0fae62ac, 0xcc6567a5, 0xc574dfdb,
- 0xd42f742b, 0x648572a6, 0x7fc6d7ef, 0xce5e9ebb, 0x7692bf75, 0x5f97a703,
- 0x4934bd21, 0x1b7e256f, 0xf22941ca, 0xcbee0972, 0xff34029b, 0x43b1e020,
- 0xeda78a1a, 0xf9b45e82, 0xe0d7f369, 0x90b95c76, 0x9af1c1d6, 0x41c69499,
- 0x17d35ed1, 0xe1ff4249, 0x5c5f48bc, 0x0f73f0a1, 0xfbad0a15, 0xe95329a6,
- 0xb101ca5c, 0xdcb91e2f, 0xf83dec34, 0xf76f027d, 0x0f63fc5e, 0x2ea1b5fa,
- 0xc00bdd23, 0x8dcf5e94, 0x4bf12f78, 0x0c33dd0a, 0xf78d54f4, 0xe2fd3d1c,
- 0xf3b444f9, 0xf2e2ccde, 0x2e2ccdec, 0xca2e070f, 0xe45e74d5, 0x729c8fc5,
- 0xce9ffd0c, 0x4d3ec592, 0x039e0f4f, 0xf3c658d9, 0x1ec2eddf, 0x57d8bfb0,
- 0xa7dbf08f, 0xc52cc4fc, 0xb21fdbd0, 0x46d704cc, 0x0bcd2453, 0xc98f05fd,
- 0x82ec9bac, 0x6dafba5e, 0x939b9cf0, 0xfca9a1e3, 0x8ef68659, 0xe3df8bbd,
- 0xe54b3a76, 0x3ee01672, 0xc613ef04, 0xc3ace47e, 0x2f1872fa, 0xc3bdfa3f,
- 0xa133d7c9, 0xb2a3df82, 0x383f8ae9, 0x24b89ef1, 0xc7fdd189, 0xea36c83f,
- 0x57ada1ce, 0x2cec1cb9, 0x3b41e9ef, 0x2854e42e, 0xfbb3a72f, 0xfbda0b0e,
- 0xf2f85f1a, 0x8ad7bcf8, 0x4ed77cfb, 0x39e30e29, 0xd78e8d14, 0x202e0764,
- 0xbe046edf, 0xafec9c78, 0xc274ff1e, 0xf314b38f, 0x1eb0275c, 0x9586afba,
- 0x87c89c9b, 0x8e8306c5, 0xe6c9aedf, 0x413da374, 0xf3dd93fd, 0x9abb4163,
- 0x2c3b97de, 0x7db5cf0c, 0x1276717c, 0xb672a7da, 0x9d79ef66, 0xed8fc788,
- 0x7c4ec973, 0x0df6b7fb, 0xda0779b1, 0x73f02df3, 0xcb44c7bb, 0x59febc8b,
- 0x0b317ed8, 0xe97683dc, 0x775976e2, 0xc16dffde, 0xda2e8be7, 0x9d8c7758,
- 0xf7ca68bf, 0xa2d2bce8, 0xfef4898b, 0xf49f916d, 0x2a4bc8b6, 0x8af0f314,
- 0xdfd915e7, 0xc6f7fed0, 0xff5dcbc9, 0x972d48f9, 0xd0d98597, 0x6bd4a36f,
- 0xe36a7f42, 0xb9d0bfd4, 0x7fc0b791, 0xd17f36ef, 0x7758533c, 0xed83b8cc,
- 0x77595a2e, 0xa8baec4a, 0xbe747704, 0x6b7faa76, 0xf04be7a5, 0xc7874a38,
- 0x3a05ff68, 0xbfed0e3c, 0x5adfea88, 0xfd25fc59, 0xffa11f8f, 0xd1fc1d3c,
- 0x7de90b7e, 0x47da89ff, 0x272fc06d, 0x78ef57ba, 0x8eebf30a, 0x7cfee99b,
- 0x8ab3b876, 0x92fdafce, 0x3bc6b9d1, 0x06f27f8f, 0xb9ddcde6, 0x31c5e4c7,
- 0xf9918c06, 0x43f461de, 0xf0867321, 0x79ed291e, 0xcd017643, 0x45bdfe27,
- 0x0f313b09, 0x38ac52ce, 0x58593f51, 0xf135784f, 0x93e48583, 0xfad79716,
- 0x2672871d, 0xf76a3e46, 0xf62bbc85, 0x0b60ff8d, 0xc0aecc2c, 0x8157f732,
- 0x9c623773, 0xd961e1ad, 0x7421efc9, 0xc5a23f91, 0xf3f415bb, 0xe3d4300a,
- 0xe3fe7867, 0x4b03723f, 0x0e7e6e91, 0xdfe300e2, 0x01bd84f2, 0xff0a4f8a,
- 0x8f6b3eef, 0xf7231bc7, 0xdf2b6456, 0x8b6fdf4c, 0x7f1537d3, 0xeb9ba47a,
- 0x8f38159b, 0x57e7b946, 0x8e7879b5, 0x1bdc57a9, 0x5bdd92a5, 0xee927e5b,
- 0xfcd5ab97, 0xfbf175f9, 0xb42ed9ec, 0x7cf8b583, 0xa13fe622, 0xf3c8dfbe,
- 0xbc6cebef, 0x14fbf75c, 0x4789cf3a, 0xef104a45, 0xdf97b29d, 0xfc24e82b,
- 0x0f30179e, 0x20e63658, 0x9e04077e, 0x433d77cf, 0x5f9e18f7, 0xa0e89a37,
- 0xa53f37ee, 0x640ec97b, 0x63acfc8a, 0x7543d20e, 0xde256f66, 0x93207793,
- 0x4a9d9bdb, 0x8c596277, 0xab36b9fd, 0xfbebe48a, 0xd01b46eb, 0xbaf0d73e,
- 0x8d85c853, 0x89503c5a, 0x6dfde254, 0xbf7797ef, 0xa0f07a4c, 0xc6e77e95,
- 0x4a93e870, 0xa3714fba, 0xafa5ee99, 0xcb76343a, 0x2c6fa83c, 0xa8be5032,
- 0xe09590e1, 0xdf9eb739, 0xa2df84ef, 0x343c6ebe, 0xa80f7e8a, 0xbca116ce,
- 0x6f04c6ae, 0xd497ee11, 0xdd16fa1d, 0xbee67f27, 0x372839b1, 0x39aaa74f,
- 0x7dee7f74, 0xf7987480, 0xf86363e9, 0x74c9d6fb, 0xd1b1d25e, 0xae2e1816,
- 0xf893e9a1, 0x640ea3fb, 0x461ff696, 0x78b58cfc, 0x917940f7, 0xb8b03f76,
- 0xf9eeac0f, 0xf3151cc8, 0x557f85ac, 0x33ef7f67, 0xfdadf7ba, 0x3d385bcd,
- 0xcd027df3, 0xb71f8b3f, 0x039de84e, 0xfc7cc8a6, 0x35baa67d, 0x9e26ff02,
- 0x28675687, 0xd327dfa5, 0xee31bff0, 0x0457d57e, 0x99e7b5de, 0xb7ba1517,
- 0x1c81ec0e, 0x733a57dc, 0x76f44cdc, 0x3a78e366, 0x578dad2f, 0x0271b807,
- 0x564e9e9f, 0xfefae227, 0xbaafc859, 0xd4efdc35, 0x3619d7de, 0x477ae357,
- 0x6f94c98e, 0x248ce033, 0xd6887ee2, 0xce0f2b4e, 0xdfa64ba7, 0xf9903a19,
- 0xd03bad34, 0x32ba4315, 0xfa41c6fc, 0xfe1bf836, 0x97ef457b, 0xf50d90b3,
- 0xf266abf4, 0x331c4ed3, 0xf03c1d93, 0x3b773f1a, 0x7b2f1ee4, 0xadef0724,
- 0x1466fe0c, 0xec81b5c9, 0x376e6ec8, 0xb8dee95b, 0xc9815381, 0x432cff62,
- 0x81978bdc, 0x6385daf6, 0xd7b46ed6, 0x20fb49e0, 0x43d7b621, 0xe8db8fef,
- 0xd2780ffe, 0x1d260939, 0x9cefd0f4, 0x7df136b0, 0x677f7d0f, 0xca0c604e,
- 0xa00b3be9, 0xdf7e3b7f, 0xe42eed47, 0x19612607, 0x78c532fe, 0x766fd499,
- 0x4bde9720, 0xeff8791f, 0xfa89b47b, 0x9a0faa1e, 0x1e699303, 0x8eb0767f,
- 0x4df9e661, 0x2f7b7fef, 0x9be4853b, 0x99e03706, 0xbc78bfec, 0xe20c7278,
- 0x3e385df7, 0x7072e9e2, 0x3e04bf3d, 0x5f90a78c, 0x71d7c5d2, 0x971358fd,
- 0xc9e3ad27, 0x431ba5ce, 0x569af262, 0xe89b7b1d, 0xdbe8c072, 0x72297a8a,
- 0xbdf8c8ca, 0x6019606a, 0x6f0a619c, 0xfce36757, 0x9ef1c1a4, 0x686e6fc8,
- 0xef4f79e5, 0x9cede2fd, 0x273c7605, 0x9ceeb6fb, 0x83f716ac, 0xae31124e,
- 0x89aaf762, 0xdedc25b5, 0xfe2e0996, 0x8d1b4dfb, 0x554efd2a, 0x14b1bee8,
- 0x5263384f, 0x8ebdd10f, 0x901827eb, 0x5cbd5a9e, 0xf8da84f6, 0x9afbb4bc,
- 0xe2977bb4, 0x9cddf2f1, 0x38bbfe02, 0xde2b702c, 0xa99a7dd9, 0x8db36269,
- 0xc7ab9fee, 0xebca017f, 0x2b3e0d0b, 0xbd25bfcf, 0x379ef430, 0x8efc97d3,
- 0xf96dffd5, 0xe68cb907, 0x250dead9, 0xc77d5ea2, 0x583efdc9, 0xbbf4953d,
- 0x7749e7cc, 0xbea066e8, 0x939adff6, 0x0724f54a, 0x7d7891df, 0xf2699d3c,
- 0x903e086e, 0xfc5fb06e, 0x3dbefa0e, 0x48d5c787, 0x79bde058, 0x7ba2642c,
- 0x0abe8461, 0xcf018a4a, 0xd4b9f775, 0xbecba444, 0x55e482d6, 0x52e0a798,
- 0xe862cad3, 0xa32cf824, 0x9e2accf3, 0xbf8c984f, 0x889be273, 0xc903bcf1,
- 0x3c4238fa, 0xeb4f8f3c, 0xff5b1f9d, 0x772e1cd3, 0x1fb8735b, 0x261cebf8,
- 0x3c78feec, 0x22583a72, 0x1bd5a0e8, 0xcafc8ab8, 0xb64b76b8, 0x88fa0925,
- 0xd4f6df7b, 0xcabe533f, 0x85bdfd4e, 0xde3d6235, 0x9214de79, 0x8133e126,
- 0x37eb8df2, 0xff577973, 0x5dd14d42, 0xfce74cbc, 0x4ddc75a7, 0x70b30fbf,
- 0xc622cccf, 0x8bad17e5, 0x730b9f46, 0xdf68457c, 0x4ecbb645, 0x6dfa93e4,
- 0xaad3c132, 0xc3b659b4, 0x8cdbb3fb, 0x0bd5f764, 0x0566ce78, 0x14dd6912,
- 0xef0098a6, 0x22409567, 0xc5dbb5d9, 0xcdc4e0ef, 0xa2bdda03, 0x1f830d94,
- 0xc2675f0b, 0x7430c14f, 0xeb40ca70, 0x898130b4, 0xe89347df, 0xecd9c79c,
- 0xee58adc0, 0xee9e7f03, 0xa06b6e9f, 0xf1e2557b, 0x2012d67d, 0xe6225d7a,
- 0x7e33e1a3, 0x039f0d1c, 0x9fb44f88, 0xfa41df9e, 0x8ca0f82f, 0xee9ecc14,
- 0xecfc90fa, 0xbe66c769, 0xbf7c2df1, 0x1518ec19, 0xcbfe6df5, 0x077d47df,
- 0x98ed0a72, 0x690563da, 0xa36f4e2c, 0xd2fb593f, 0x8c4344dc, 0x976d6cbe,
- 0xb5a59f69, 0x22e24e70, 0x06fe7f6a, 0xaad3afa4, 0xa62cad37, 0x9a392bdd,
- 0xaf5fa93f, 0x4d7fcdba, 0x37ea71c4, 0xda5e6918, 0x4c000cba, 0x6cdb8724,
- 0x81ffa461, 0xabf508ac, 0x7d20d3ad, 0xf4683ae3, 0xcd3eed04, 0x78718a71,
- 0x2f2fb6bc, 0x861de950, 0x003f164e, 0xdb7f62e3, 0xe69f741c, 0xe1ab8ea5,
- 0x05bd7063, 0xd719535f, 0xc51e7771, 0x14a70dc7, 0xdd3f064a, 0xf20e4d76,
- 0x07d81d71, 0x93a88718, 0xbdd06f22, 0x74ccc7a6, 0xe6dd6fef, 0x78e2b7a5,
- 0x0d99af75, 0xfc77df58, 0x5704899a, 0x9e02badc, 0xf7a38672, 0x8e48bc81,
- 0x607f0637, 0x6b7f1057, 0x9b8189f3, 0x8b3f00e0, 0xc819c5ee, 0x918cf583,
- 0xe1cd7f03, 0xef681af1, 0xf37d1134, 0xe706997b, 0xaf9b8ceb, 0xafbe6e33,
- 0xe66fa230, 0x167cd00d, 0xe0366ebe, 0x5ff785fb, 0xb771845f, 0x69d3f5be,
- 0xbec97d5e, 0x7d5fc889, 0x30ffd039, 0xfde172f2, 0x2f92cf30, 0x959b6798,
- 0x79c46bd6, 0xb3764726, 0x27a7982f, 0xb7cf3f57, 0x7e913514, 0xcc88e34f,
- 0xcc128e30, 0x16fc6ff6, 0x97efd32f, 0x1e9c8d05, 0x746d9b82, 0x8bbfaa2e,
- 0xc9af8fdf, 0x12ef1801, 0xf440c1e9, 0x6ea557d0, 0x75f48299, 0xfdc4ec9f,
- 0x97f5be8a, 0x2fbf8cbd, 0x7651b7d7, 0x57d0dda2, 0xf207f1c5, 0x5f78f480,
- 0x2a06ff8e, 0xefd2371f, 0xfb699da4, 0x3ee89feb, 0xfa466382, 0x3c81e23d,
- 0x5879c6ff, 0xae517806, 0xe26e5e01, 0xe691ab76, 0xc1eebadf, 0xda1f5875,
- 0x6fce8936, 0x7ad7d50c, 0x906fd73c, 0x14c87c75, 0xde0bc695, 0x17ee8a3f,
- 0x120cf0d1, 0x23fd08b6, 0x9e581f0d, 0x978a213b, 0x8f7f38a0, 0x8fbf0276,
- 0xc433c84b, 0x13d73e4f, 0xe5058e78, 0x19a79e18, 0xcbc55f49, 0x7bbd789f,
- 0x4fb6ae63, 0x0dc797a9, 0x79afbf71, 0x69795c5b, 0x1658dc9c, 0x5718df57,
- 0x86f9fa0f, 0xcfd2e2e1, 0xa2cf8e0c, 0x1a21927e, 0x4fb81d1f, 0x56b4bf22,
- 0x07e84d51, 0xeb8d3e3d, 0x59853ae7, 0xe4be22ae, 0x156a73e7, 0xc32e62d6,
- 0xac535ef7, 0xb5fd04bf, 0x9ca19398, 0xb410e5c0, 0x94c536ab, 0xc1ab7935,
- 0xa3c04ab3, 0x9c76bf3d, 0x7dc466a0, 0x15b9558c, 0xca31f743, 0xbf5ffce4,
- 0x11d67e88, 0xe0ccfc99, 0xb0ff5c0b, 0xf2dc3f4f, 0x3bef1b98, 0x323ca02e,
- 0x78f1fe6d, 0x61fc381c, 0xe4defd22, 0x5f3a26f3, 0x5295db5e, 0x72587e45,
- 0x6fbc5864, 0x44fae5cd, 0xe95fafeb, 0x6b1d9c4d, 0xc4deb347, 0xadf7dfd8,
- 0x4ae1fc3d, 0x7f016bf4, 0x8e463921, 0x5a96399f, 0xdd65fe85, 0xf0ab32ef,
- 0x5cd1efbc, 0x3ea00e2d, 0xe6f901bc, 0x13e29988, 0x33cc2ffd, 0x2ffdf7e0,
- 0x9de78bd4, 0xff609f74, 0x7072675b, 0xfe8344fc, 0xcf7f89be, 0x9d54f6e5,
- 0x57ddcde1, 0x9a3ffca2, 0x2626b79e, 0x28675d0e, 0x31f8bf23, 0xc23e6463,
- 0x3aff760d, 0xfad503cc, 0x12ab9a39, 0xde47fd1c, 0xe1f28dde, 0x32ecc6cc,
- 0x47fd2b14, 0xdc1f90c6, 0x4565daff, 0xff6b5f78, 0x945e197d, 0xd5198f0b,
- 0xe2dfb93b, 0x8bc9eef0, 0xe0e387f6, 0x91ff63fe, 0x3f1895c9, 0xc38d7fe8,
- 0x278a650b, 0xe610bb40, 0x26fd6a5f, 0x984dd41a, 0x677ece8f, 0x8ee2bf24,
- 0xf1d20acf, 0xd344957e, 0xa050f7f0, 0xc3cfa11f, 0xd6f34d5e, 0xfde37df2,
- 0x37ff2d0c, 0xeed30fde, 0x17f78f8b, 0x3ddb59eb, 0xef1c9798, 0x6e618237,
- 0xdf89a509, 0x4ebfa733, 0xf74bf7d2, 0xdfd66e7f, 0xf6121d9f, 0x71e48580,
- 0x7ae3f02d, 0x79853f8a, 0x3c9d6fdc, 0xc5ec7eec, 0x6fa76e5c, 0x7e6dfdb5,
- 0x9ebacc6f, 0x03c53036, 0x626d3d78, 0x70d94f16, 0x9c85e3fe, 0xc37b925a,
- 0xb1758dfb, 0xa1b1d6f7, 0xaae9e47e, 0x9df9e530, 0xefd32f5e, 0xf5c3c459,
- 0xf8c8fd55, 0xebdfb5ef, 0xc4ed04f8, 0x00938c54, 0xe45fc9a4, 0xd5e1eb3f,
- 0xbf1569f0, 0x01fff2a3, 0x949113dd, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7db5ff00, 0xc5547c0b, 0xbddcf8d5, 0xc3764cfb, 0x083c8426, 0x813bcd84,
- 0x44902c24, 0x8f2ed4ac, 0x0310f0c4, 0x5850822a, 0x89de4020, 0xc5b0fd60,
- 0x40802166, 0x151a86d1, 0x260dda2b, 0x22ec1208, 0x760d1201, 0x4a888941,
- 0xadb45503, 0x202a25f2, 0xd4109204, 0xeb6bfe8f, 0x73339cff, 0xd0820fb3,
- 0xcfe8fbf6, 0x99dee64e, 0x7de733b9, 0xfd999cce, 0xf7f87bfe, 0x17bec613,
- 0x62a2d9a5, 0xc963106c, 0x2d9990ff, 0x43b2b194, 0x891ae71a, 0xafdac0b1,
- 0xf50b999f, 0x398d16ee, 0xf958c2c6, 0x6726d921, 0x659ac630, 0x3e0c4267,
- 0x08a822ff, 0x8f3797de, 0x33cccb31, 0x9cb3795e, 0xac654ce7, 0xd86ae9ab,
- 0x671a54e2, 0xfd88c5ba, 0xa1dab69f, 0xc2acc834, 0x57b4f465, 0x4c8b58ca,
- 0x69de28f3, 0x9932fea8, 0xe1efbfd1, 0xb05752bf, 0x29bcbd4f, 0xbd4bfab2,
- 0x7f8c5ea7, 0x367fc244, 0x8c5967a6, 0xec57f095, 0x6187ea72, 0x5dde6053,
- 0x1912e7b5, 0xb2a8d12c, 0xa1325ac7, 0x169df89e, 0x67b58ceb, 0x7e6899e5,
- 0x67981641, 0x20dbf3b7, 0xb7d2f306, 0xbf9c36c8, 0x2c32fcff, 0xff32c65a,
- 0xc2e5f983, 0xf33cc2fc, 0x5864f983, 0x59e67906, 0xb2d1e966, 0x3e879858,
- 0xc48d9d28, 0xa369b616, 0xfc22fda0, 0x6a2fde13, 0x058d3c59, 0x79a93631,
- 0xe0031ac9, 0xb25abba1, 0x7e79e0ea, 0xf00dc00b, 0x764dbf90, 0x932f005a,
- 0x311d5692, 0xd3f17d40, 0xe6ba1ef0, 0xcf4ee3c8, 0x9ecbf686, 0xb87ea990,
- 0x1ad391f6, 0x0d36ebc4, 0x031e21d3, 0xef8bb682, 0xa15f9c31, 0xcb615f98,
- 0x7c120bd4, 0xd921d96f, 0xf5fec6ea, 0x5f3e2b26, 0x79f341bc, 0x96fad7bb,
- 0xde301fe0, 0xd392ad92, 0xa92de30d, 0x95df7df6, 0x38b2d0e9, 0xefd5bfe8,
- 0x99faed79, 0x54b14247, 0x51d60933, 0x8f7df4e8, 0xf986deff, 0x77bf8b94,
- 0x8c1e6c26, 0x3032e9f8, 0x61f806d6, 0x8630f6ea, 0x1a3dbba5, 0x7cd5d8f1,
- 0x58f11a36, 0x24fffafe, 0xa7f07eb2, 0x14c5ac94, 0xe0102e7a, 0xf7d89169,
- 0xabfba42a, 0x69faf3d3, 0xe7087a3f, 0xc71a9d8b, 0x3fbc2b60, 0x746dfb52,
- 0xb349d23b, 0x1fb9987d, 0x9f1bedfa, 0x08aa0c39, 0x8606dd2c, 0x3ccb8665,
- 0x4de4f905, 0xd213798d, 0x33f5f6c7, 0xf0dd43b7, 0x00660686, 0xf12304f5,
- 0x12c7f20b, 0x3e1571af, 0xd9b129d9, 0x99426654, 0x6892f38a, 0x930fdf5e,
- 0x1e771e88, 0xd09e9dee, 0x69867cdf, 0x21e8dda8, 0x347dda8c, 0xd2356f2c,
- 0x11ca805b, 0x3660f884, 0xe014259b, 0xaafa092b, 0xe121595a, 0x4d5608f3,
- 0xa2e610e5, 0xecc605f2, 0xaccf6c46, 0x63338466, 0x7e118343, 0x5eb4f3c4,
- 0xe6e90abb, 0x9b770267, 0x8e0f4e24, 0x87ace660, 0x3d5ae5bf, 0xa6300793,
- 0xd841ed65, 0xf33694c9, 0xbde0c3d7, 0x255943e6, 0x43c8bd01, 0xcd5a7c15,
- 0x8c6fdf88, 0xc6f00df7, 0x17f7e1df, 0xa578e2e5, 0x83a665fb, 0x6a372ef1,
- 0xed88db98, 0x9da05f81, 0xb5affde6, 0x5a972831, 0xeb009624, 0x3e3a8728,
- 0xb6a71f2f, 0x52e0bd39, 0x78f0e16f, 0xf04892da, 0x8edb52e8, 0x33fa434d,
- 0x2c3ad22f, 0x2e7e4e38, 0x11347183, 0xaf38b48b, 0xd04fefc3, 0x82de20c7,
- 0xeb37c4d5, 0xb6ef945b, 0x64fc7199, 0x78f329d5, 0xa993df78, 0xf1e1db66,
- 0xcdc6a3f9, 0xf7ca47c8, 0x3f1c2cba, 0x12812b67, 0x97cf3c92, 0x8397dc64,
- 0xfb3297fd, 0xa5a3a47a, 0x7b733235, 0x0d79fdd1, 0x6b92f7c7, 0xc63dcc81,
- 0x4cc45fab, 0x6b92d75a, 0xbcfcf441, 0x6f3bb781, 0x9ef174e2, 0xc7c5d385,
- 0x885fbbe2, 0xaf2dbffa, 0xeaf2beac, 0xef1f0bf2, 0xd6e5c458, 0xa547487b,
- 0x44ce7b52, 0x88fac4f8, 0xf5ca2d5e, 0xe66695b3, 0x3ad0fdd6, 0xd7b73207,
- 0x5ddafb77, 0x40f73033, 0x6859b86f, 0x1af59efe, 0xcad9fde9, 0x31c09b88,
- 0x9e8e07ca, 0xe07ce3f1, 0x89f8fd78, 0x656cfef4, 0x1fc64df2, 0x63f18371,
- 0x19efe67c, 0xaf9e9e37, 0x20b1554d, 0x9fb5aba0, 0x6cc49ce8, 0x74a7ae7a,
- 0xbad6ef82, 0xfd2de927, 0x4d83aff0, 0xe163628a, 0x8b9ca37d, 0xbcd97c74,
- 0xae7c8cc8, 0x74b90609, 0xd8d7f41b, 0x7180ef72, 0x0321c175, 0x5aaf7e91,
- 0xdf5d68e2, 0x1d105706, 0xb4743b7f, 0x8fc188ec, 0x7d61e454, 0x997c90ed,
- 0x59fab378, 0x7ae5f392, 0x21d37dfe, 0x9fe44a60, 0xaf42f5db, 0x18bcc9ff,
- 0xd43553be, 0xf4c98fae, 0xf994c7cc, 0xb33c4336, 0x9430fb26, 0x819b8f03,
- 0x801f896f, 0x5abd61af, 0x3bbbfec9, 0x9fd81f80, 0x8a1eac75, 0x24f60d6f,
- 0x471f17b3, 0x09fd70c4, 0x728510dc, 0xa86ac1d1, 0x4aba6f2c, 0xff00b670,
- 0xf794bae2, 0xe087ace5, 0xc2cd7c8e, 0x16d52691, 0x4f64df7a, 0xccf34bca,
- 0x78eecfa3, 0x0150e8c7, 0xfd0ee9ff, 0xd9e10823, 0x6e99eead, 0x22d5d285,
- 0x77c37a07, 0x8fe70c64, 0x4ebf4309, 0x65e7876f, 0xd3e40fd8, 0x27166f23,
- 0xd329fca1, 0xbce3a4f5, 0xf7f9bc8f, 0xdff79474, 0x861e2a1e, 0x7b4277cf,
- 0x3db413b2, 0xf1af5665, 0xa1d999e2, 0x9329eb1a, 0xef88e263, 0x3cef9ffc,
- 0xe7183554, 0x886200d1, 0x5677c085, 0xe5f717be, 0xdb072440, 0x18672853,
- 0x0b7a97c8, 0xcaf74dda, 0x3eca5728, 0xea04db02, 0xbf5ccd19, 0x4e650c67,
- 0x67da0c55, 0x7c46cd1f, 0xcd6a6595, 0xc04a582a, 0x1ae736a8, 0xa9901f78,
- 0x1d1ea337, 0x5f7f843e, 0x0e3cfa8b, 0x440f67fb, 0xe414fdbc, 0x0f247fec,
- 0x2becfcea, 0x06b2a9f7, 0xdca95ef8, 0x00e51d3e, 0x31e985c8, 0x07d97e30,
- 0xb5489f5f, 0x309e8b60, 0xd0b74fc4, 0xe3127f3f, 0x37931a3c, 0xfbaae913,
- 0xe3d777fe, 0xbb2437a3, 0x88e3d71d, 0x5f515bd4, 0xec6708b0, 0xcebc2f4c,
- 0xba09518d, 0xba01ee01, 0xb6e62e1d, 0x796bb067, 0x6725e930, 0xb943d208,
- 0x1e51d98a, 0xd40069b2, 0xf32e91db, 0xf5a666d2, 0xd0d79fa7, 0x6c62cb78,
- 0x4abe708b, 0xcd668ffb, 0xc3f7b34d, 0x04a94887, 0x21ebad4f, 0xa94f679c,
- 0xf01dbad1, 0x82be21f0, 0xd2cd2f7e, 0x93b065b9, 0x0dc635ba, 0x27d1d012,
- 0x075bf381, 0x184ffac1, 0xceb815ed, 0x5e4c0fd9, 0xc8e9758f, 0xa472cb40,
- 0x59ed85cb, 0x06399788, 0xbef8c3fb, 0x161f6f44, 0x3cbc4b06, 0x00349ed4,
- 0x40de6a95, 0x97966f0e, 0xfcefd796, 0x753c7cf9, 0x54b7fa46, 0x31b7a5c0,
- 0x49d9006e, 0x67480daf, 0x152e9f30, 0xd0fd402b, 0x15fbe625, 0x25e623e8,
- 0x279c0ba7, 0x7da10bb5, 0xed49dd61, 0x97f5af22, 0xeae08582, 0x3a7a2ec7,
- 0x1745db86, 0xdbfefdf7, 0x9d50c05f, 0x44481cdf, 0xba58b5bb, 0x76faeb44,
- 0x62f9c9d7, 0xbeb8d57d, 0xa27b7a47, 0x12aeb0b5, 0x972d61d7, 0xea7d621f,
- 0x5a1fc49e, 0x2daa975f, 0x80e2e887, 0xf18fae64, 0x3c6d2bf4, 0xf4051399,
- 0x3c17505e, 0x9674e65a, 0xe8567488, 0xd1788f84, 0x028e32b1, 0xde42e59f,
- 0xf014aef5, 0xb676e009, 0xfbe51f02, 0x33e0fc67, 0x8d93dd5f, 0x2abf98f3,
- 0xa9e5c558, 0x7947e893, 0xefa560bf, 0xfb14ab77, 0x49c931e7, 0x7ebc66f3,
- 0xdcec11d0, 0xea9d7504, 0xa2f787ea, 0xb2a690dd, 0x2db0dda2, 0x68c06400,
- 0xf028fec6, 0x07c802f3, 0xdf3d087d, 0x0223cf80, 0x6788ff78, 0xe82ace54,
- 0x99a1379f, 0x32a5f0e8, 0x6f8655a3, 0x98e0642d, 0x331614c0, 0x67d9d91b,
- 0x50fdffc7, 0x68f3ac3b, 0xf08ddd8c, 0x1550305f, 0xc3cd21fd, 0xda06623e,
- 0x1c38e36f, 0xfd17b3af, 0x99933fe0, 0xb1e46435, 0xfbe42acd, 0x94be6699,
- 0xe3e71225, 0x834d997b, 0xd99fbbdf, 0x2ea9dda9, 0x93fd0dad, 0xc15be853,
- 0x0e601fbc, 0x39873e7a, 0xdccb9ca9, 0xaca7fed4, 0x1f0aea9d, 0x082ffd00,
- 0x3e7ff4e5, 0xf9ba265c, 0x327de718, 0x4ae87d30, 0x678cc758, 0x5fc81293,
- 0xf04419ab, 0x67bcd9b9, 0x8f8e1c48, 0x71dbd8c6, 0x6fdcde9c, 0x7181ac5e,
- 0xd1377a54, 0x989c9f5f, 0xe1d04834, 0xb689cb0f, 0xcc7f3ede, 0xb8700918,
- 0x2ef4a04b, 0x63f9315b, 0x3991b2d9, 0xe36d3f00, 0x53fa2764, 0x43ab6cc7,
- 0x93aa6543, 0xcab36d5e, 0x59dff7a4, 0x50194ccd, 0xc694677f, 0x6b74455a,
- 0x5d3c3d23, 0xcd7d978c, 0x7800f6fe, 0x586e5d3e, 0xdcf50c1b, 0x790fe021,
- 0xd0e4d5d1, 0xb3e46abd, 0xcfbef129, 0xfafaa5a7, 0x6ab3774d, 0x3d3be119,
- 0x61ddb7c3, 0x95d00b84, 0x3ffb962a, 0xfe1b386c, 0x8fe1ecbd, 0x31f9147b,
- 0x1bb6aaed, 0xd62631e6, 0xf585886e, 0xecfbbf2f, 0x532efc7c, 0xa0c60fb3,
- 0xb3213a5e, 0x73fef04d, 0xd81b13e0, 0x82565f4b, 0x397e0306, 0xd61ff607,
- 0x0d3b02bf, 0x16958bcb, 0x5d812f2a, 0x2abbef85, 0x207f54ad, 0x16242f36,
- 0xc368bf40, 0xed1db515, 0xfa2ceafe, 0x5f410afe, 0x2ab72a6d, 0xbb67f910,
- 0xb87d4564, 0x2136d0c2, 0xa2b6e010, 0x180ac63e, 0xae4d4566, 0xbe7e9c56,
- 0xd1072f3b, 0x4558f4b8, 0xd7a5962b, 0xd2076624, 0x8bce417e, 0x3ebbf1c6,
- 0xddd67cfc, 0xe57cfcf0, 0x85fefa58, 0xbf7d1b4a, 0xca9732b3, 0x3c7b588a,
- 0x74b5b3b6, 0x20b40eb4, 0x7d10ae36, 0xa1d0dddc, 0xb67a828e, 0xdf21b24d,
- 0x4e6369dd, 0xab75e027, 0xada9eb86, 0x0f90a7a0, 0x7ccda7c7, 0x7a8661e1,
- 0xe38e9ec4, 0x30a53fdc, 0x3e99c71b, 0xdb1aa176, 0x631df03d, 0x743c6303,
- 0x65ba3376, 0xf2fc727e, 0xddd1129b, 0x1ee59565, 0xc71cabb4, 0x7a0fb265,
- 0x185530d5, 0xe193f7bf, 0x74e0074e, 0x70b8fef9, 0x35cb6794, 0x2f10f096,
- 0x27e9d639, 0xdcf73ac7, 0xdfade116, 0xdf5c433a, 0xd0e505fe, 0x810e5c67,
- 0xb7ee74a5, 0x118ca728, 0x976fc456, 0x520043f0, 0xcb8fa881, 0x406f82b4,
- 0x33bd608e, 0x83c82d80, 0x51abd67a, 0xf00f9013, 0x8f24967b, 0xf57c499c,
- 0x585fd8d9, 0xe9dbdf3c, 0xdf97f25a, 0x53b2fd42, 0x5e80d0e5, 0x5d5cccba,
- 0xeabae3af, 0x17b4568c, 0xc0752593, 0xefec10ca, 0x964bbe24, 0x2095ea2c,
- 0xfabd7647, 0x19e7e0c2, 0x8d8c09da, 0x6c6ff785, 0xf3392409, 0x667ac686,
- 0x817ff625, 0xc9f97ff7, 0xc26f3f47, 0xd1d289f2, 0x1059428f, 0xcd70421b,
- 0x70e14dff, 0x5111b3a4, 0x6f180680, 0x6dc941f7, 0xad2c6748, 0x489af0e6,
- 0x6dc8cf98, 0x50c1aa1d, 0xaa93aa8e, 0xca611cb0, 0xfbc3263d, 0xcd0b58b2,
- 0x8c434c63, 0x32ec851c, 0x9f97f9d8, 0x6be1bd90, 0x5cd6a487, 0x79983099,
- 0x92e191ec, 0xa5e222eb, 0x347a74ca, 0x4d563be9, 0xb96fece3, 0x69734ff7,
- 0xe0e9601d, 0xad6a17bc, 0x8e9c1fa4, 0xcbb3a45a, 0xd92b64f6, 0xe78e79e7,
- 0xed97bf10, 0x17d45661, 0xff5fc007, 0xa33fb611, 0xac1e75a6, 0xf184193b,
- 0x07e0019b, 0xe97de01b, 0x93d21ea8, 0x0c2d43a5, 0xc5f43bbf, 0x3e1172bb,
- 0x6bfb8d65, 0xbd129c69, 0x82d9fd15, 0x515b57fd, 0xccc9b26f, 0xd5f4809a,
- 0x9abfebc8, 0x1ea2b364, 0x86fda82d, 0xa8f2dbd7, 0x83de079e, 0xe62fdb1a,
- 0x42b3d976, 0x74f6b12f, 0xb2445b92, 0x7ebe0f16, 0xfdf1af05, 0x644718d6,
- 0xcfa3d185, 0x416d0f40, 0xf2d488fe, 0xe6136dfe, 0x6e5c1346, 0xe3290f51,
- 0x0e65ab3c, 0x2d45ea03, 0x20f597d7, 0x603e902f, 0x7c7117fc, 0xc9466f45,
- 0xac235a52, 0x1d59ea3b, 0xf8b7b397, 0xd603d99d, 0xec54de93, 0x1f6172b8,
- 0xe8136154, 0xbfb465df, 0x8970f282, 0x6d4cb3d0, 0xe3bb4549, 0x776da333,
- 0x6071d92c, 0x7f48a8e7, 0x65eb1efd, 0x7175d832, 0x319d765e, 0x17f496e4,
- 0xe3f6d933, 0x7db56e7a, 0x9fe798a8, 0x03433cc5, 0x1d2c9da2, 0x87f80afd,
- 0x7858e984, 0x587186d2, 0x447ef1f4, 0xc156eb24, 0xe11d073a, 0x8bb1e3f5,
- 0x1b05acb7, 0x77a47dfd, 0x3382470e, 0xfb430050, 0xca6e794c, 0x6210f4e0,
- 0x11dd93d7, 0x5462b03e, 0x337d1785, 0xc20c7bb5, 0x653fd363, 0xdb7684b7,
- 0xfc5233ff, 0x86de7fc7, 0xfd7fee38, 0x150e624c, 0x2d15d7d2, 0xb4d16bb5,
- 0xf43dfeef, 0xb54c296b, 0x007b3fa2, 0x71c7adf0, 0x8ec96a66, 0x05db416a,
- 0x09ccb7da, 0x86f7b923, 0xc741cb86, 0xdfde009c, 0xf7c10000, 0x689dc3ab,
- 0x55d60da7, 0xe38697bc, 0xdf120557, 0x1b9c68b4, 0xc7fc7162, 0xb2f8d206,
- 0xe8e1bdfe, 0xe4227d7f, 0x9ee49551, 0xc76df18b, 0xefc32d15, 0xa3bb04d5,
- 0x535ea1ca, 0x7fda9c38, 0xed192a02, 0x5b609ac4, 0x03d9ca24, 0xfe4994ff,
- 0xba828cd5, 0xc513e491, 0xd8666a61, 0xfea18322, 0x4d4bc0a0, 0x99feb3ad,
- 0x4c9e7c50, 0xb8c60ce3, 0xe18bb61e, 0xc345fce3, 0x07a7d9fb, 0x075ed1aa,
- 0xf089144d, 0x027e6dfb, 0xe3c2d2c5, 0x0871c826, 0xcfb7e15f, 0x19477216,
- 0xb3e83b1f, 0xffe30ed0, 0x37a92ce6, 0x5fdd7f20, 0x0d00e860, 0x58293ec2,
- 0xf5bf4263, 0xd6ecbb7e, 0xf7605c81, 0xecfadb65, 0xdf1c5882, 0xbd21c726,
- 0x937e2be5, 0xf5c2317b, 0xdb3d1ecd, 0xe0237644, 0xba7aed35, 0x1fdf80bb,
- 0xf8e3fe80, 0xc7fdbca7, 0x9fe71d42, 0x6887480b, 0x43da060f, 0x4de5fe70,
- 0xf6f29f93, 0x592ce72b, 0x40724417, 0xa552f77c, 0x132fa9ed, 0xa5c84ed0,
- 0xf2aef952, 0x7a99dcbd, 0xfe8a149b, 0x7189ce8d, 0x0ec205c0, 0x67b9d72d,
- 0x673e3f21, 0xefa30fb0, 0x474c5d14, 0x6674317b, 0x475c00f2, 0x0e60bbf7,
- 0x0233db41, 0x805067cf, 0x4c2b9e23, 0xd44c3744, 0x4818bfed, 0xdf04b9f6,
- 0x62fa3a41, 0xda3b698d, 0x2dad7673, 0xd1d20972, 0x47b240f2, 0xc1dc80ce,
- 0x0494cf71, 0xfbce1d13, 0xc8fbf175, 0xb4f2676f, 0x5a679f44, 0xe9f7bdb8,
- 0x85add94a, 0xbccd77f5, 0xf4224cf6, 0x45f55aeb, 0xdb2856d6, 0x1a35fcd7,
- 0x35bcd1f5, 0xdfb0d3a5, 0xd355a2bc, 0xe2374e11, 0x3a2579f3, 0x6e1cccc1,
- 0xb76ce353, 0x6742be23, 0x3941cb5e, 0xe4b8b83d, 0x17c18c39, 0xc4efd9c7,
- 0xdb6997f5, 0x651e10cb, 0x8d167c6f, 0xf37773f6, 0xa15b7bcb, 0x27d9336c,
- 0x35b2bf60, 0xc3acc577, 0x55ff84c1, 0x017c06a6, 0x671e7d1d, 0xe5f7c1cf,
- 0xd889dc93, 0x2da692ef, 0x56c6e107, 0x7ddd9add, 0x80fea5b1, 0x40607e84,
- 0xb295194b, 0xd1e71d33, 0xa483b929, 0xd8238438, 0x4beeb00f, 0x70507766,
- 0xc98d452a, 0xe9de289e, 0x5a9a3ebb, 0x403b8898, 0x6c9762bf, 0x32dd2033,
- 0xebe716a7, 0x9e18bedf, 0x7c5bbb53, 0xfc5cc45e, 0x93d37079, 0xab7d2077,
- 0x37f71b99, 0xd84aee2e, 0xbcbff88e, 0x6f44e5ff, 0xbcbfd83f, 0xfd7cbe7e,
- 0x00be9097, 0x89e0978e, 0x41abe906, 0x75ffe3e7, 0xfa248aed, 0xfd11ef82,
- 0x724aed74, 0x8f92f26e, 0x307e425d, 0x066b2bab, 0x95cdbdd2, 0x22967685,
- 0x95de982f, 0xb25bfe4e, 0x15fd1d2b, 0x3cb0de45, 0x773d2257, 0xfdb112ba,
- 0x8d67f401, 0xed16ef9e, 0xc4ddaa8e, 0x550e8ee3, 0x6c47d606, 0xee32bac7,
- 0xb497d6cd, 0x4f53eb55, 0x9fd6fa71, 0x95fcf210, 0x1f8ab457, 0x82bf0b2c,
- 0x5a3c1459, 0x7046fdb8, 0x8156b3f9, 0x5951c3cb, 0xbf803718, 0xdcde6962,
- 0xfb857e6f, 0xd94607cd, 0x2aae50a3, 0x6081f9fe, 0x5ea2a7a8, 0xea56f3e5,
- 0xe7fc1c0a, 0x4bcfe6bd, 0xf7be30a3, 0x1f8f1c46, 0xbcb81955, 0xb97032aa,
- 0x1594dab4, 0x34abef8e, 0xa2a6c760, 0xee2c72bf, 0x0e078d4b, 0x366d2ae7,
- 0xf57dc110, 0xe9475ba5, 0x6d976f91, 0xa6f7a51b, 0x639daa8f, 0xde60598e,
- 0xadaa7697, 0xb52a84b8, 0xd7b449f3, 0x2eca76aa, 0x7af7a307, 0x64bfb41b,
- 0xdb02723c, 0xe3c6dd2d, 0x65ff4a16, 0xf96db35b, 0xb11ef35e, 0x69be17d3,
- 0xc8fadf2e, 0x51fadf26, 0xfd0645b4, 0xb946fdeb, 0x8e63eb7d, 0x7fcfd6f9,
- 0x242cf0f8, 0xf1d902c3, 0xe3f68ca4, 0xa18e735f, 0xc0eaf93e, 0xf78a20c1,
- 0x8adf967c, 0xadb2f176, 0x3c0770be, 0x3827684a, 0x77a44876, 0xfcfe9d0b,
- 0x031f3fd2, 0x5f389446, 0x14dd37b2, 0x3aab4731, 0x9df6fae6, 0x86cb35cc,
- 0x7f95a571, 0x8c72fb8a, 0x5ddbdc67, 0x0fe8b45b, 0x46f77ff9, 0x368ccb7c,
- 0x1637c60b, 0x7eefe58e, 0xfb2272b4, 0x7cdbc702, 0x71e90732, 0xd224afe1,
- 0x25f70bc3, 0xd3748dbd, 0x14ce77b1, 0x12e5672a, 0xcbb8943c, 0x6dc916b2,
- 0x2c79ba82, 0x650fdbeb, 0x6b45ef30, 0xa1f13e75, 0xf3becdfc, 0xfbe35a58,
- 0xe1d3597e, 0x6bbee1bf, 0xda45fe81, 0xa6d82ea7, 0x396b8bf3, 0xbd3b42df,
- 0x7e462be8, 0xf7dd5178, 0x5ee2feba, 0x143ac44b, 0xee3990fb, 0x6e4eb864,
- 0x8edf8202, 0x3d7207ff, 0xc4d76cc4, 0x8dd8f20f, 0x95a9aa3f, 0xcca57e11,
- 0x8e3988fe, 0x207751fc, 0x0ea967cc, 0xa4d1b1ec, 0x577d6987, 0x78a00eb7,
- 0x06673c07, 0xb5957e78, 0xbe7ea165, 0xf2b268da, 0x965b5938, 0xa0cbea19,
- 0x602bf08e, 0x12a704d5, 0xa732cb94, 0xddb79b1b, 0xb3adf4e0, 0x97b76e6a,
- 0x1187dda8, 0x9dacc51e, 0xbd1e21fa, 0xbac095db, 0x3b41093e, 0xb33fafc4,
- 0xdcbc9c52, 0x95fc25a8, 0xf3af7d37, 0x0bf8af7e, 0xc4a2ff8a, 0xf4577ee1,
- 0xb7d20060, 0x3587d846, 0x5b7b9d1b, 0x94eb3d61, 0x0316deb8, 0x6b07a7c9,
- 0x7b07bcb9, 0x59d71130, 0xd68525b3, 0x8b64a0fd, 0xf6b68759, 0x7fd13d0c,
- 0xd3d8304d, 0x924764a1, 0x237600bd, 0x733dadd9, 0x12edceb4, 0x372e8fda,
- 0x4f35c1da, 0xca06f8f3, 0x9f6bb249, 0x527d9030, 0x27db8333, 0xa9c25b35,
- 0xca705fff, 0xf2576891, 0x913cd4f9, 0x995dedc6, 0x8ce163f7, 0x65f607e6,
- 0x5e6bdea2, 0xb2ff5d8a, 0xf1113ed9, 0x26b7acad, 0xfb84c7b8, 0xe060ac1d,
- 0x7af9e92d, 0x007abfa1, 0xff07180e, 0xc56bca52, 0xdda5097d, 0x1f5cf17d,
- 0xedb04d64, 0x5e28ed10, 0xb19aaf9e, 0xa79827e9, 0x52ca8cf0, 0x7f05e315,
- 0xd7112d9b, 0xc316e5ff, 0x99d3c468, 0x679e5c51, 0x05f1e04d, 0xdb6c5bf0,
- 0x5e22ff71, 0xfd7713e5, 0x614ef8a9, 0xf5e685bc, 0x2f8f3665, 0x28f2329a,
- 0xdab6038e, 0xf5f6fe82, 0xbef9e30b, 0xef36be68, 0x99fb8ff8, 0x3617028f,
- 0x5f17fb89, 0xbe91243e, 0x9a24f584, 0x1bf59ea1, 0xbe7fc503, 0xc1477a14,
- 0x2651d007, 0xc72161e9, 0xc67e90c2, 0x19e7e878, 0xa40e1741, 0xfd378b0b,
- 0x83c7d2f8, 0x09ecff02, 0x04d69f6e, 0x13cd7af3, 0x9fa03729, 0x650ffdfe,
- 0xfcb535bd, 0x01dfbfbd, 0xde36b074, 0x74fe9e0b, 0x4cced4c0, 0x7f35fdef,
- 0x8d96c83a, 0x57e728c9, 0xb4560148, 0xfe0857c7, 0x1184b158, 0x0ab1463d,
- 0x8235f909, 0x008f29b9, 0xc70181e4, 0xc00f71fb, 0x7f0f8bdc, 0xbccf4d72,
- 0x1678dff5, 0xa89f53ec, 0x9f69f48f, 0x79f18e6d, 0x8a44577f, 0x96c9fbcf,
- 0xa9f53e51, 0xb4fbb7c9, 0xde3adbbf, 0xd8cf7ea7, 0x67ed3ec9, 0xd4f866d8,
- 0xc6accc6d, 0xee54b7f9, 0xcde0fb24, 0x97dc574a, 0x65c3d709, 0x3ec8ee9c,
- 0xa6b1958b, 0xaa6707ba, 0x0dc61e81, 0x0622b238, 0xede387ea, 0xe4751ebc,
- 0xb1998c6a, 0xf217e2b7, 0x572388fa, 0x347ea163, 0xdfaf117e, 0x7f5fc8c1,
- 0x4cf17e27, 0x15c52a47, 0x667e218f, 0x8a38ab5d, 0xab47e16e, 0x41892e67,
- 0x24c92f1e, 0x67ecae39, 0x3f6313dc, 0xbcacfc84, 0x8d9fda57, 0xafbbfde7,
- 0x7ddff970, 0x2377cb85, 0xfe83291a, 0x32fc12fd, 0x0e04fefa, 0x6f413622,
- 0xa62ffda4, 0x8bea5cd7, 0x94fc8343, 0x3c618c6c, 0xf012a5af, 0xd370809d,
- 0x34aee953, 0x32a47953, 0x2bb7ca82, 0xe01f2c2d, 0x4c995ada, 0x2b4ab1e5,
- 0x395e3f3d, 0x2bf7ca96, 0xa89e546d, 0xadb2a5cc, 0x094a8f32, 0x2879a98c,
- 0x3758763f, 0x0e2e1068, 0xbd39f075, 0xc6e52f27, 0xcecd4c72, 0xc685f829,
- 0x5f6c186f, 0x31dd93c4, 0x71714cc4, 0xd35bbcf1, 0x73d222f3, 0xc16615d5,
- 0xa6c3b87c, 0x9fb416d3, 0x44f532ab, 0x9b4f52ef, 0xb8ebe505, 0xbaaf5e0c,
- 0x675166d2, 0xfdea3af0, 0x28d760ee, 0xa5550bd4, 0x189aeb46, 0x448eef7c,
- 0xa157197e, 0x387fa2b5, 0x3e67a7a9, 0xa338f1f2, 0xf47a82d6, 0x2df5a9b0,
- 0x73ca3df1, 0xdcc2bba9, 0x3457dc2a, 0xe2cc59b4, 0x7c0e383b, 0xc1f50637,
- 0xbbe187b8, 0xed056e34, 0x679b8d07, 0xe4aefbec, 0x0ffd5df7, 0xe4a2777f,
- 0x5ef8ddf5, 0xff3a6ef8, 0xbbe7c5ae, 0xe5ec996e, 0x0fb26e2b, 0x11ad83ba,
- 0xfa955f28, 0x4a9f7c24, 0x33d24271, 0x196e2ce3, 0xe887eff7, 0x070d3cb8,
- 0xa5e0d2f3, 0x6278956f, 0x675f2f5d, 0x08bba557, 0xb0926af9, 0x59692657,
- 0xa993c232, 0x98fe2802, 0x1ad77f2d, 0xcde5f505, 0x9dcc28d2, 0xdbcba498,
- 0x9aae7e46, 0xca161dcb, 0xb75332f5, 0xed0cbe15, 0x5945854e, 0x486adf31,
- 0x0f1601c4, 0x3cbb3872, 0xfaf51537, 0xd4df9129, 0x484f641c, 0x9bdc7980,
- 0x254a720a, 0xd9f71988, 0xde490372, 0xca4a1f77, 0xa67f7b44, 0x019fb2ce,
- 0x3c26a71f, 0x720d5333, 0x4b00e671, 0xfac664a6, 0xb70f5e36, 0xbde097ec,
- 0x73333d99, 0xc1ffedd2, 0x4934fafe, 0x381f97ed, 0xadf80136, 0xc8b2f734,
- 0xfb21ec57, 0xe498c7f6, 0x77e28834, 0x9ec7a46e, 0x03d226c9, 0x8e5b8f18,
- 0x92d53bf2, 0x35a2ed89, 0xff08413d, 0x94d4efee, 0x832d023f, 0xe38af3ee,
- 0xf3c2d8bc, 0xe3f9fc4a, 0xabd70272, 0x9f3cf1e5, 0xaf422ca9, 0x4ae5b2a7,
- 0x8f7ca30e, 0x3ff478bc, 0x57edeac1, 0x0277febf, 0x598e1fdf, 0x47f1e5af,
- 0x6530a114, 0xea53005b, 0xa96bcc0e, 0x3140247d, 0x4e006d46, 0x547ec5a6,
- 0x24cdfa6f, 0x1b7b4fb5, 0x67bcf7b6, 0xd29f0436, 0xcf7ea4bf, 0x8bc6d66f,
- 0x2cbd21ef, 0x825c4e65, 0x4da9febf, 0x0bfc510c, 0xa10bf3c2, 0xe38bf206,
- 0xa057a065, 0x1740a8cf, 0x0ceb33c5, 0xdcc17e9c, 0xc54eb2a0, 0xc0036bdf,
- 0x50fa85fe, 0x9a3ee3a8, 0x22bed13b, 0x67f51071, 0xef2fec66, 0x2291fea5,
- 0x1f794e6f, 0x1979518e, 0x0cdae9f3, 0x55938e58, 0x4e4dc2fd, 0xc46bff1c,
- 0x83a55777, 0x2fd2f59d, 0x2b41815d, 0x8654f1bd, 0xfdde8dfd, 0xa53f5026,
- 0xfdd8297f, 0x9c920767, 0x8d297a26, 0x2b3e5157, 0x4b6fcdf8, 0x36b0d768,
- 0xa561ea2d, 0xab9069df, 0x410fbdf8, 0x09f962ce, 0xc0b3d7c8, 0x9ca97f9b,
- 0x95a7e54d, 0xa67e7a76, 0xf6ca80b2, 0xfe7a0aca, 0x2a4ae579, 0x6535cd67,
- 0x37949f20, 0xbd6766ad, 0xa5d4bae8, 0x4bef7bb1, 0x3fdf1e9e, 0xe04aecbd,
- 0x98e9dd76, 0x95bbdffe, 0xbc7277f7, 0x817d8375, 0xdfd024f6, 0x8dc8735a,
- 0x136e8ced, 0x377abfdf, 0x7773d385, 0x25d7af24, 0x536ea868, 0xffd8adb1,
- 0xd12d14dd, 0xc6448aeb, 0x2c7889db, 0xdf8d1fd0, 0x3e54e707, 0x19ced28e,
- 0x2fedcaaf, 0xf225984f, 0xe89f4476, 0xc63d202f, 0x9967d178, 0x9fd3e885,
- 0x39136a2e, 0x38ebc4df, 0x2ea145dd, 0x708c7dc2, 0x0a731383, 0xdc36be60,
- 0x3893af57, 0x9f475e3d, 0x5d9fee2a, 0x0e309f47, 0x5ce809c1, 0x7ec7f282,
- 0xef94a3f4, 0x0b6fbe0a, 0xe08cfd33, 0xa331a2dc, 0x0cb1f8be, 0xaafec580,
- 0x0f9813de, 0xb266151e, 0xf6489ee0, 0xfe8ac6e3, 0x123fc7e4, 0x6ffd7db8,
- 0x1f8fbfaf, 0xdd7fd77d, 0xd07ec5ba, 0xe49baead, 0xa44bca09, 0xc3e47e9f,
- 0x3e4504a5, 0x1391fa70, 0x3f50e76d, 0x35064b74, 0x0dbbb3c6, 0x83ae2e9c,
- 0x4fa70a5b, 0x056a3e85, 0xbae1447d, 0xe9eb3ce2, 0xdf807f9b, 0xca3196fa,
- 0xa3c7f0eb, 0xd6bc5722, 0x2f04f7f5, 0xd818c279, 0x487fd017, 0x09f69189,
- 0x099a2457, 0xce83dd7e, 0x6f02dfcf, 0xe27a159f, 0xa7df1579, 0xdf76e450,
- 0x305e4973, 0x9e47d523, 0x7a33b433, 0xbf88e90e, 0xf0562adc, 0xf851fa1a,
- 0x70bf2f29, 0xef53c0ac, 0xee154cec, 0x6b7d75bf, 0xcd1e5074, 0x68339ee0,
- 0x056d7447, 0x7ffc8003, 0xf40934db, 0x878c12d9, 0xafbe3058, 0x8be8fda7,
- 0x24b20f60, 0x72bae768, 0xf298ed06, 0x07a664e7, 0x7dcfc9d0, 0x65e90b33,
- 0x998d21e9, 0x4fad9aec, 0x3b7a431d, 0x505928d7, 0xc23577df, 0xb39f71b2,
- 0x4034e4c6, 0x63a81cfb, 0x653b65fb, 0x03522527, 0x14fe907b, 0x286b3bdf,
- 0x777b458b, 0xa33f73e2, 0xb5a5f8fd, 0x71870b12, 0xa2badadf, 0xe7ea1235,
- 0xf9fcf1b6, 0x7fcf032a, 0x6b3791cf, 0xb47c6307, 0x312f3f96, 0x7bfe50e6,
- 0x75662ed1, 0xaf65bc63, 0xa5f3fc89, 0x1579be35, 0xeb7cdb05, 0x5cbe2285,
- 0xbcfbe754, 0x4f37c1a4, 0xc8a24c63, 0xa36148c3, 0x135a5e28, 0x22807642,
- 0x77e46f4f, 0x397396d9, 0x61d7d8c9, 0x0f95ef18, 0xb9fd137d, 0x8867d791,
- 0x2fd4077a, 0xa2f1c37f, 0xc94ca5c0, 0x1964882b, 0x23cc0cae, 0x3f719834,
- 0x8bf9acaa, 0x73f98620, 0x89d3ed01, 0x29975f3f, 0x93636adf, 0xa569fb4c,
- 0x3097862d, 0xff6cb0cf, 0x84c5ad49, 0xec887f70, 0x6398bb80, 0x6e8bfa3d,
- 0x6fe44a95, 0x8ddc51b7, 0x52967ad9, 0x60d9bb7c, 0xf65afd46, 0x73adc7fa,
- 0x625fbeb1, 0xd0e3c406, 0xa593a276, 0x5fb4c9cf, 0xc9f2d0cd, 0x8c89d0f2,
- 0xbb3c4578, 0xcf3ed006, 0xe23bc432, 0xe78ef019, 0x34e7e41b, 0xbba5f784,
- 0xb55f7a64, 0xed8b4ab5, 0x7e3939cf, 0xc8e7bc15, 0x45cf08ab, 0x4e7c702f,
- 0x99feae7c, 0x5d83a400, 0xdf73b21a, 0x79837e82, 0xd03a1f3f, 0x77e3e21e,
- 0xdf144bd5, 0x6683a3ea, 0xe01d1f5d, 0x07466f3c, 0x67a49fc0, 0x0607466f,
- 0x4fe41794, 0x8a1a3b8f, 0xf8cfedf6, 0x9db8947c, 0x1f9b9712, 0x10fa59d2,
- 0xd8884d34, 0x1b2cf647, 0x08955f60, 0xe4cce672, 0x74dc280f, 0x51eeca6a,
- 0xff034f94, 0xbf9461f4, 0xfb7cf047, 0x444b7fe7, 0x331dd079, 0x18c1db63,
- 0xae0767c2, 0x90383ba7, 0x923dd3eb, 0x3ae7a253, 0x93be0eb7, 0xf915720d,
- 0xa3a9bd92, 0xa0f743f8, 0x893e1e07, 0x184f68fb, 0xc92e88ad, 0xe2bafdc6,
- 0xc13e7796, 0xcc6b27f8, 0x7df8f9b6, 0x462b2fc2, 0x37df10bf, 0xb5e85f80,
- 0x3f9928df, 0x4bbf7ea0, 0xcb75a58c, 0xf256eb2a, 0x0598eadf, 0xe5eb95ed,
- 0xaff9233f, 0x686eafc4, 0x01e9f99f, 0x76e7fc8f, 0xf10c7319, 0xe5c0b73b,
- 0xf71132d3, 0x71c8fa3d, 0x675c40f5, 0x53373f1d, 0x297202d8, 0xf8a5ce94,
- 0xd13297c8, 0x19d23cfe, 0x472bf1c0, 0xec9501c5, 0x9d3e472d, 0xec94e384,
- 0x2194e3e2, 0x981c20fd, 0xdc0099fb, 0x28697027, 0x84c4591e, 0x5932695c,
- 0xe47e96dd, 0x7aed5d48, 0xe9fd7f34, 0x37ec18a7, 0x1d3f845c, 0xb6fa3595,
- 0x97ca03fb, 0xd25f2411, 0x077f47be, 0x23d32369, 0xd4e5b247, 0xf5afe801,
- 0xe400cb32, 0xb9e91be3, 0xdac0ada4, 0x38a6e35e, 0xb3ed4cf5, 0xa9f6615f,
- 0x7c22b9a7, 0xb26c8fda, 0xe51fbcf8, 0x3f79f64e, 0xa7d598e6, 0xd636d99e,
- 0x9f6dfda7, 0xb7ea7cd8, 0xb4fae7b7, 0x3cabe3bf, 0x2a6f7a9f, 0xf607e7ac,
- 0x908aeeef, 0xb64fda7c, 0x07c67c18, 0x99f04e0d, 0xf3ec1c9a, 0xe1c8d7bc,
- 0xef71a374, 0xab8efab6, 0x8cf7b9f8, 0x867f1df5, 0x5bdc77cd, 0xd00ec3c5,
- 0x4d106a9b, 0x628f413b, 0xc0254af9, 0x86f1ec1d, 0xbfaa08ca, 0xd2a1695a,
- 0xcf4c9955, 0x52b4ab5f, 0x2c72b1bd, 0x7d800fd5, 0xb026f58f, 0x1d7cb1f7,
- 0x7e7c7cec, 0x8ab57833, 0xdf131eef, 0xcbbe2e3d, 0x076e16d8, 0xef2e04dc,
- 0x4427fe8b, 0xafec36ff, 0x6961d0f1, 0x1aeaa66e, 0x90f8edf0, 0x2f8c5a0b,
- 0xe7b796d8, 0xf3df9fa0, 0x03b6ccae, 0xf3bb305f, 0xea286558, 0x1f3c81a9,
- 0x3de7af21, 0xed97178c, 0xfee3338f, 0x3fa6c6c7, 0x5df7c09d, 0x33c5328d,
- 0x117d348e, 0xba5ce384, 0x503ecc06, 0x97a837e8, 0xfaa24dfc, 0x798f7826,
- 0x82f793f8, 0xcb7a4b61, 0x52eb7a45, 0xd27752bc, 0x86bc8df9, 0xda76dabd,
- 0xef4bdc57, 0xf5be05df, 0xd6b3bf79, 0xdb19bde7, 0xdab67ee3, 0xc5f77e49,
- 0x373c6526, 0x97892fb5, 0xc5d23ce8, 0xc7ad6f9d, 0xbdd2be7c, 0x3ee2070b,
- 0xc9c37160, 0x003fc5b0, 0x7607cbff, 0x2f5ca2a7, 0xf9c5966d, 0x695e3e23,
- 0x891e72b3, 0x7e24bfcf, 0xca084e6f, 0x218906ed, 0x6ab12e7a, 0x6e2a8fca,
- 0x39412faa, 0x573c9c5a, 0x9721f143, 0x3c01e22c, 0xccc4b0df, 0xbae67db8,
- 0x35e7841a, 0x3a3ae0ff, 0xba85f31d, 0xc20ade5b, 0xf9e376ef, 0xdefc2f13,
- 0xdcedc493, 0xdfb8927b, 0x2df1a974, 0xd1b93f3a, 0xbb8716f5, 0x3feb4dda,
- 0x50ddea22, 0x649bbc12, 0x35e17f5a, 0x8ca0f099, 0x4c9260f7, 0x4a6e4de3,
- 0x4ebae130, 0xf2f7f8b9, 0x79fc2c93, 0x9c7cc2fc, 0x3988f1ff, 0x95d93299,
- 0x3ddf2e3c, 0xca3d6a7c, 0xe80fcc51, 0x047b0fcf, 0xb5f985c7, 0x77c63c8a,
- 0x0eb5f7e3, 0xcf1fb806, 0x748a381d, 0x274fe280, 0x473dfb71, 0x3d478f6b,
- 0xa168ca71, 0xdc9af838, 0xf7e21338, 0x3cf89608, 0x57da25f7, 0xdfe46a28,
- 0x0b6e653b, 0xd53bba42, 0x3b464638, 0x40af1946, 0xbe8fb77c, 0x20e6f0fb,
- 0x6b38153c, 0x078e388d, 0x7e79fc7f, 0x71e69992, 0x167279dc, 0x92a74bda,
- 0x68cec903, 0xfcfdf2d5, 0xef6e06e2, 0xaa896a9e, 0x5bf6bd95, 0xba3e05f2,
- 0xd7845593, 0x688d26ae, 0xf99eb737, 0x7c70d3b4, 0xc7cef9d5, 0x1278ecec,
- 0x1792eced, 0x54933a64, 0xc308a9a2, 0xe6df9ff5, 0x0102bf3b, 0x3b8d12e7,
- 0x5e8bcc2c, 0xf8fb9a4b, 0xde7448c6, 0x8589f0ac, 0xf1e0a9f0, 0xc73f3254,
- 0x9f822a72, 0x5bd92a83, 0xd1ed744f, 0x19ae3cf7, 0xbf3c5ff5, 0xae7e66f6,
- 0xf9780f62, 0x3cfd0c49, 0xa65c6e4d, 0xf7a3d62a, 0xbf6d137b, 0xfe841a4b,
- 0x85f91e53, 0x8a26ec40, 0x3c7da08b, 0xa7efe500, 0x7b77e0cf, 0xd879f91b,
- 0x11737d52, 0x5af5fbee, 0xbe604181, 0x4e34dbbd, 0xd118cfe1, 0xec2a5d4e,
- 0x7b16f3d4, 0xa3fb8c96, 0xaeb455ab, 0x89d90692, 0x425d98f9, 0x1bde5dde,
- 0x69d20f73, 0x8cd931c9, 0x5744cdfe, 0x65c7afcc, 0xfb26de90, 0xedc5ccae,
- 0x129db2dc, 0x7d8ab5d9, 0x8bec2a51, 0x3d8ec273, 0xdb87bab7, 0xf62487b7,
- 0xcec78c54, 0x45761528, 0x3d79bca9, 0x9ffb2be6, 0x396c2daf, 0xfd89e74c,
- 0xef16d5cf, 0xba97adf4, 0xbf8aeb7c, 0x9f524ef7, 0xfe82927f, 0x94a7d809,
- 0xc0a9f12f, 0xacafe2a7, 0x2386b348, 0x5b546fbf, 0x037128a6, 0xa1f95784,
- 0x6f38857d, 0x95804967, 0x6f9587fc, 0xbfbb5c10, 0x77497ee6, 0x77f5a304,
- 0xeedf0e33, 0xe5df4e26, 0xc7a9c91a, 0x7023a8fe, 0x5ce4bd3c, 0xa3a8768d,
- 0x12e48837, 0xf7c1e1e6, 0xfee1cf96, 0xa3630da7, 0x855a9530, 0x29fd140f,
- 0xa9decdce, 0xbd83976e, 0x2495c3e4, 0x124e776e, 0x4c2b48f9, 0x835fd256,
- 0xc1ebb9c5, 0x0f6f6e7a, 0x53573b56, 0x6631fe3c, 0xf2714359, 0x4e90a303,
- 0xf14eae30, 0x123d55ff, 0xeb1fc3c5, 0x063f9091, 0x7911ad9b, 0xf849f55e,
- 0x0763d53e, 0x48f6330c, 0xc7ba9df8, 0xd73af894, 0x66d433ef, 0x894fce0d,
- 0x87fb293b, 0x7394fcca, 0xf3e7ff08, 0x8cfcc333, 0xbe01f99e, 0xabff6007,
- 0x0fb25619, 0xe72867a2, 0x1e482afd, 0x04bcf028, 0x70093ef4, 0xa41d3185,
- 0x876d929b, 0x40fe7873, 0xcbdf9d1b, 0xc8ebe209, 0x39e3f911, 0x941cbc01,
- 0x2b35f1cc, 0x9e8bc799, 0x3722a510, 0x85b649df, 0x2fb94325, 0x39322f39,
- 0x62ce73d3, 0x9cfc07f9, 0x87bcbf85, 0x574f44e7, 0xee510f81, 0x3242b4fd,
- 0x63d8fbc7, 0xf9cabf9c, 0x2a3e3ea3, 0xe225e0fe, 0xb5b0e613, 0x9e618725,
- 0x05efe702, 0x78e60d2b, 0x1728be2f, 0xc5a6207e, 0x7297fee2, 0x5cc0be4e,
- 0xec40e748, 0xe8ccc32b, 0x97cb9597, 0xafff5e28, 0x93795df2, 0xe06ddd6f,
- 0x4936eff4, 0x9edcffe4, 0x13cf67dc, 0xfe0b463f, 0xb44bb5a8, 0x9dfb5c2f,
- 0xe6dbc79a, 0xbb5f1449, 0x7cf21e1f, 0x60aed17a, 0xdd9be53c, 0x37da550f,
- 0xfb1509ab, 0x9fb4a1d6, 0xf7589f77, 0xe2df22fd, 0x8315c6a8, 0xa5a3a0f1,
- 0x3f8e2b7a, 0x7f68b987, 0xa36b1e7d, 0xd96074f2, 0xee0d377e, 0xfcfe8a18,
- 0xc51d76c7, 0x6ed76aa1, 0x4f5ca137, 0xb8cd6b67, 0xd8a006cf, 0x5b98fdf9,
- 0xf2538fdf, 0x0e2ec189, 0xfc04fa47, 0x7ffc46cf, 0x1889b805, 0xe2ff7d7d,
- 0x3e53f68f, 0xfbc3e752, 0xd0c03d66, 0xff21eaaf, 0xb562a8a8, 0x1c4df686,
- 0xcb392dac, 0xef055783, 0xf0fade0a, 0x1f16616a, 0x869ac2bc, 0x4be49c20,
- 0xfd2e4833, 0x77a8664e, 0x0557866f, 0xf8113fee, 0xe5ccd659, 0x15be3f97,
- 0xe7803c3c, 0xdf48e2a3, 0x313c236e, 0x7f4bc91d, 0xbe19b87a, 0xe1e73080,
- 0x3aa189ab, 0x54a32ff2, 0x2d469e5c, 0x38be2895, 0xb50fd997, 0xf02b3943,
- 0xbbd10d53, 0x813cdbc0, 0xf3998fb7, 0xff98e4ee, 0x93bdbc3d, 0x3c9d579c,
- 0xf5be7ae8, 0xf11bd3e7, 0xfac58965, 0x3a5f4547, 0x1fa3f219, 0x6bf1fb3f,
- 0xf0ad1e1f, 0xda3c2f3f, 0x5f110657, 0x6e5be1f6, 0x88bd35b8, 0xaa1c607f,
- 0x716bdf89, 0x60957e53, 0x57cf8021, 0xa6f57d93, 0x2e053782, 0x9deb8a37,
- 0xc23b72d6, 0xfb4c88f1, 0xee499f98, 0x639466a3, 0xfce8a729, 0xb3fed29b,
- 0x1f436dd5, 0x1b3e7182, 0x5ad3cbcf, 0xd4a91f9e, 0x3e3c016d, 0xcea459f8,
- 0x4cfdeb81, 0xfa80994a, 0xbfe933e2, 0xb87af3a6, 0x39f582d6, 0x50cc13e1,
- 0xe251ad3f, 0x7c446b89, 0x67e549c0, 0x449b6e73, 0x36f624ed, 0x3f9f8ef3,
- 0x7cfc512a, 0x9c728801, 0x6784cc5f, 0xfeaf3173, 0x46e3cfcc, 0x72df3ed1,
- 0x1f50f1df, 0x921c50c7, 0x5e778bfb, 0xf42cd1eb, 0x7a7d3bd2, 0xfe15d270,
- 0xce933f3c, 0xd808161b, 0xb85242da, 0xe7e4ec7f, 0xd33d1536, 0xd19f6c7b,
- 0x417a4e3b, 0xeafb95c4, 0x7b444f29, 0x3bc3a9eb, 0xe388957e, 0xe91d6814,
- 0xabfb7e78, 0xd1a3e7da, 0xf1d8289e, 0xb7d92278, 0xa226363b, 0xfdb0529f,
- 0xaa368957, 0x4fc9da07, 0x7775f352, 0xa5fdb9ee, 0xe77a5e4d, 0x6fdce1d1,
- 0x9c3fa799, 0x94ee768d, 0x61d79711, 0xe7e13e3c, 0xf387dd12, 0x0eb6d653,
- 0x64fcdff5, 0x46acef4e, 0xe199724f, 0x73c02df9, 0x75ddca7d, 0x93c7a7c8,
- 0x43e4d0bf, 0x9a8a5d3b, 0x399f33e0, 0x7ee38737, 0x5cc906f6, 0x0fdbbccf,
- 0x85cafda5, 0x446d256b, 0xe0b7ea28, 0xea3fe851, 0x1e698252, 0x6a8c368b,
- 0x57f3e7c5, 0x7453e7f1, 0x3853c6ce, 0xca5ab3ce, 0x10f90237, 0xafc79deb,
- 0xf1e7e14b, 0xc8966c17, 0x93be57ae, 0xad584cf0, 0x29753af7, 0xd4672f42,
- 0xce51dc91, 0x755b4e09, 0x1808edf2, 0xbb6a9ff7, 0x39c60529, 0x78b9f4f1,
- 0x149f3c37, 0xfd152172, 0xfdad049b, 0xeeb885b7, 0x83ca3aed, 0x928f48cb,
- 0xe8fda1c3, 0x853fc787, 0x0b5582e5, 0xf2885b7f, 0x147eab71, 0xf3e6174f,
- 0x55592e5b, 0xaadf3f28, 0xc211607d, 0xf5a7abed, 0xaf2f9764, 0xfd670a4d,
- 0xbe528ff0, 0x8dc7f80c, 0x7a955d82, 0x9a57772a, 0x9eda3ce9, 0xffaa08ca,
- 0x2542d2be, 0x6be9cd9b, 0x8dcb99b9, 0xe6378d1b, 0x80b3205a, 0xc1b19abd,
- 0x70632cc0, 0x9c96ce5f, 0x18487002, 0xa37dba5e, 0xa56e1758, 0x4cc4728c,
- 0x6c643844, 0x4d15a87c, 0xee14d0da, 0x6a77bd67, 0xedf23443, 0x2f1d55b2,
- 0x537ae216, 0x7f6146f2, 0x142bb6fd, 0xf9ab7837, 0xef08f9f1, 0xbe3aed82,
- 0xafeeb13e, 0xff0c4e9e, 0x78ef8c2d, 0x7c7e4357, 0x178eb6f9, 0x78b94237,
- 0x6f5a43f3, 0xf5d5bf7a, 0xfbe14c8e, 0xabe3379d, 0x5fe1c11b, 0x455fabe7,
- 0x7f6cff13, 0xf9e1ee9c, 0x7caaf977, 0xdf826ad5, 0xd9bc94ba, 0x695f5f48,
- 0x4fc8d11c, 0x98fca55f, 0x4871dce8, 0xf22bf822, 0x4b3fe955, 0xe558bfc0,
- 0xc62e3cda, 0x61bf5f23, 0xc3df0419, 0xd113e7cd, 0x69a6fdae, 0xfbae0fce,
- 0xb7bf2540, 0xebe009a5, 0x52882f7d, 0x71ed6966, 0x965f5856, 0xffe0c738,
- 0x12a291de, 0x6fdf2cf6, 0x57927fc7, 0x17e8077e, 0x4f9800c7, 0x0ee48b49,
- 0xe9ae3f40, 0x20ea0bae, 0xfb1233d4, 0xc91e27dc, 0x7a5ee7d8, 0xbdf346f6,
- 0xe3865959, 0xeee47824, 0x7ca89f6d, 0xbdb963ee, 0x7ee7c03d, 0x03ff3e93,
- 0x3f69699e, 0x3956b227, 0x4c7980bf, 0x7429cd5d, 0x9682e25e, 0x00ebb1e3,
- 0x3e3c39d8, 0x7baf64c3, 0x77342e22, 0xf59ca3a6, 0xebd96f5f, 0x251f449d,
- 0x215f8f4d, 0xf269b63f, 0xcdfa7505, 0x47787fd7, 0x71dbdd27, 0x859ed341,
- 0xb69754fe, 0x50f11d3d, 0xe79706f6, 0x941c2aff, 0x601b85e7, 0x65e7c021,
- 0x24e89e92, 0x7144be5b, 0x3c63ae81, 0xfcd6502e, 0xded3c912, 0x29971e16,
- 0x84e5b557, 0xa2a31c63, 0x59e515a3, 0x93f7046f, 0x09bdc4ca, 0x1e84e2e3,
- 0xe344f754, 0xd8b70e79, 0x3bfc5627, 0xf90187bc, 0x2ae55cb5, 0xf4a5fca1,
- 0x2dfb8640, 0xe19f9117, 0x3195fcf9, 0xbfce91eb, 0x8d1a0e72, 0xf4bdf1f2,
- 0x1c5197bf, 0x66810fef, 0xd911ec99, 0x6fbc2f27, 0x27994e1d, 0xaec530c8,
- 0x8bc9f409, 0xee5ad72e, 0x38f67b21, 0x1f2b7fdf, 0xbd89f9ce, 0x74a9f9ce,
- 0x846d61ed, 0x820d78d7, 0x6efb149f, 0x4efe1fca, 0xd138797c, 0x92f91c76,
- 0x78e215ce, 0x929c0311, 0x7965da24, 0x2d8d1bf6, 0x95cfafc2, 0x93797de9,
- 0x8e5f70cc, 0x2f289845, 0x53559720, 0xe614e57e, 0x339b471a, 0xf127f6ea,
- 0x7fa99b5e, 0xfe60c790, 0xb441f816, 0x60139d7f, 0xa6fcc78f, 0xc0492ad3,
- 0xc33195d5, 0x87e99f4b, 0x4e353d73, 0xf58f4896, 0x9d920644, 0xe9767932,
- 0x69fb6f3c, 0x83b78ab4, 0x626ec871, 0xae7e1ece, 0xee93ddc6, 0xacc8ef7d,
- 0x9056043f, 0x8cae645e, 0x89df5e59, 0xe6f5ce1c, 0x06ffdc55, 0xfb17293a,
- 0x77f2d9ac, 0xbd3da0cf, 0x5fdf10fc, 0xf98aad3c, 0xe8b3f318, 0xe784b6dc,
- 0x7939f9a3, 0xbc366766, 0x6d2baf67, 0x2a079d10, 0xcc3123df, 0xd66b2b73,
- 0x5138c76d, 0x0c3da699, 0xd36379e9, 0xe7a45a47, 0x4d77dc72, 0x79abe7e3,
- 0x724f5cdc, 0x48ccdcbc, 0x2536957f, 0xbbf18c7d, 0x8b5c63d2, 0x924faa96,
- 0x1b728e7f, 0xb8dc57bf, 0x12f1fc97, 0xbc7f26e6, 0x6e97c1a4, 0x8ffa237a,
- 0xb70e47df, 0x3233dcf8, 0x8fe72b79, 0x325ee259, 0x93b0e226, 0xbd6bc223,
- 0x0a4531cf, 0xcee4d83c, 0x74c76875, 0xbc564ac7, 0xc03ba697, 0x23ed16b1,
- 0x6bb72247, 0x9ddcdfba, 0x8be494b1, 0x34dee333, 0xdb8757bc, 0x6c3793b1,
- 0xf35ecb51, 0xe3ee2c99, 0x05600eeb, 0xf6ef0807, 0x908f8821, 0xe1a8bca4,
- 0x9e3ee883, 0x7c607713, 0xf27b9c48, 0x446fc75f, 0x38b8e85c, 0x7bcca9bf,
- 0x9714546a, 0x7449cc67, 0x19ce2ad4, 0x4a367929, 0x1eb10aff, 0x3d077ec5,
- 0xfb43fe1d, 0x934fb825, 0xf269f62f, 0xbe4d3ec5, 0x17c9a7d8, 0x62f934fb,
- 0xec5f269f, 0x7d8be4d3, 0x4fb17c9a, 0x69f62f93, 0x0d3ec5f2, 0x54e2c3e5,
- 0x11cdff31, 0xd1ea34fb, 0xc1b5e456, 0x10e9fa9e, 0xdf60fabf, 0x2443a7f6,
- 0x8960fadf, 0x257c4fda, 0x118769f6, 0x2166a3e3, 0x547c789f, 0x2a79df39,
- 0xe1193ed0, 0xfce79cac, 0x03a9f72a, 0x42934fc8, 0xd9bf90e6, 0xca26fe0b,
- 0xf6e1caa3, 0xec776c3c, 0x2df8c4d8, 0x140d2724, 0xe0fd3ce7, 0x98739f08,
- 0xacc793e3, 0xc6307bc5, 0x7e71251b, 0x9e647abc, 0x38c1ffe2, 0x66165b13,
- 0x307cb9a8, 0x2d9cbda3, 0x77e3e497, 0xc61a4796, 0x24d61ca0, 0xf70ee7db,
- 0x8339db92, 0x5da3c597, 0x7cb1aad4, 0xc75af18c, 0xbf3a1a07, 0x94f5c4ab,
- 0x8d25ef76, 0x937ec42f, 0x8ed6e393, 0xfcf5f1c6, 0x969b38be, 0x6cfce035,
- 0xee8940aa, 0x3516616e, 0xe1c283ca, 0x58266e9c, 0xd6ec7db8, 0x1821d45a,
- 0x1f18098f, 0xad13798a, 0x04c7cf02, 0x3c0b8f9e, 0xa4d77ee3, 0x85dfbe04,
- 0x6177ee25, 0xd58de4a9, 0x1f2de4a5, 0x27b4f24e, 0xc4ace11a, 0xe728a6fd,
- 0xee8b98fc, 0xd0517c33, 0xbe70d26d, 0x7261f2cf, 0x09c3a3de, 0xb73a2e3f,
- 0x69e22c59, 0x437f629d, 0xcfd2a759, 0xfbf19fd3, 0x0732465c, 0x83b367ee,
- 0x08764f22, 0x9f5023d8, 0xe49c3079, 0x7a1e7290, 0x07ee18e6, 0xfce27db0,
- 0x13258462, 0xc44aa3f9, 0xfc9cbb53, 0x48696d1c, 0x239e225b, 0xa57c12e8,
- 0xd17395d4, 0x6ea1a3a5, 0x284b9cf4, 0x8896d99d, 0x24ba12e7, 0x0dce8a83,
- 0x4fefe76f, 0x8d2bbe09, 0xf729e315, 0xd15de84e, 0x43ee8788, 0xbcf1a307,
- 0x7ba326dd, 0x6efb9729, 0x2811de7e, 0x3a96f316, 0xcc19d725, 0xf7747dcf,
- 0x1e63f71b, 0xf5c6a77d, 0xdb1fd622, 0xcc7ee87d, 0xf694edcf, 0xbf7b319e,
- 0xc68ae41f, 0x7747ddfc, 0x83f7f0b7, 0x6c18bef6, 0x5e6baaf5, 0xb5ef833b,
- 0x8fdd0e6b, 0x7553bcf9, 0x489563ce, 0x74e7bf2f, 0xffb3d865, 0xb8adc21c,
- 0x13eddb99, 0xf4bfecf6, 0xfde5ea1a, 0x3fefda26, 0xe0863c38, 0xf2fcd55d,
- 0xaeb3a466, 0xbfde3cbd, 0x17a3e1a9, 0x74ed417f, 0x54dc0d74, 0xc1832b9d,
- 0x9eecd677, 0x1a9af34b, 0xeb1afae8, 0x46388d4f, 0x903a98f3, 0x11d6f3f3,
- 0xe78fddef, 0xeff6ba01, 0x6ef90479, 0x683000ea, 0xf9bb3e71, 0x7da2a0f9,
- 0xbfd09329, 0xcdb532ef, 0x5ecbf1c7, 0xf339d1d1, 0x74e17da2, 0xc3dbc72f,
- 0x9939f963, 0xa8d1d5e1, 0xefaf5567, 0x508bf1da, 0xfda0676c, 0x6e10f29e,
- 0xb5c915e7, 0xfe110f59, 0x3cf1da5e, 0x81977bce, 0x310b5ff6, 0xc2f502a6,
- 0xa714091d, 0x5f1fe37f, 0x643c47cc, 0x7ce8dbcb, 0x0675d7cf, 0x94e1c215,
- 0xcf0036d6, 0x694e38d3, 0x142cdfc8, 0xfcd3c2f5, 0x60517dbc, 0x2fe10e7b,
- 0xf51a3ab4, 0x47c0d16c, 0xa7bce3a7, 0xa22fd5ca, 0xe65ec3bf, 0xd85dc6f7,
- 0x7e837005, 0x9435ea17, 0xcbb5daad, 0x3be2e744, 0x78f9eaa5, 0x9ea3893f,
- 0x5434ebb7, 0xf51d3c13, 0xb4defc49, 0x48e8305d, 0xe7c5b76c, 0x97fa85f9,
- 0xbd1fd1d3, 0xf254caf8, 0x55fa154b, 0xcea8a5f8, 0x3f1d7cff, 0xfe245ab7,
- 0x33076666, 0x2e93c57a, 0xebae781e, 0xffd3ccb7, 0xce868362, 0xd8ea1779,
- 0x560fcc5a, 0xea28a1f8, 0x5f5c5cae, 0x1136aa91, 0x31c296ed, 0x2f91f3ed,
- 0x3e98182e, 0x27bdda02, 0xe35155f4, 0xff6819ea, 0xa63e68de, 0xbf8f9c11,
- 0xeb7ae089, 0xd383269b, 0xbfd1bf7b, 0x9992b4fc, 0xd4f04fdf, 0x7be15a7f,
- 0xad3df0de, 0xb4fd04ab, 0x3f2e10b2, 0xbc7b40ce, 0x7c502e93, 0xbf4ac167,
- 0x78239273, 0xb699645e, 0x9ef5113d, 0x863ffe32, 0xa85db99b, 0xb7fba76e,
- 0x454dfbfc, 0xc8e50473, 0xb79e7e6e, 0xa0ea51a8, 0x52082273, 0x8b667baf,
- 0xe6270ef4, 0x8787f509, 0x07812c88, 0x11b9eb18, 0xa28f3431, 0x079d0306,
- 0x0f680e2f, 0xc4a93b42, 0xf6841ed4, 0x32ebd74f, 0xe889c3dd, 0x8fc6550b,
- 0x894f7cf5, 0x34ba1613, 0xdf7f4336, 0x1c60e583, 0x0dfe1972, 0x047578a0,
- 0x682a27df, 0xcfe7e40a, 0x1e74edcd, 0x263cffdb, 0xc5ecd3ae, 0x2f4d5d8f,
- 0xe9fb7985, 0x797047a3, 0x10752dd0, 0xe3ff74df, 0x83a468f3, 0x8b5b1522,
- 0x251795fb, 0xea022e7e, 0xa2e21e74, 0xfa2cf7d8, 0xf48018d6, 0x129bf173,
- 0xa92ee3e2, 0xfb5ce49d, 0x7c933fee, 0x93b4d2e8, 0xc468fb9c, 0xe8fc937f,
- 0x8f9f6e0a, 0x447dab72, 0xd91f7f0f, 0x23cf1f3e, 0x7c7589bd, 0x81fff78f,
- 0xfddaeffe, 0xefa8fded, 0x8f3ccaa7, 0x31a4bd82, 0x8710f8f3, 0x270132f7,
- 0xae9c36c6, 0x6343ff24, 0x2dd0fd41, 0x166f03e8, 0x98fe5e64, 0xcc5d4fc2,
- 0xf911a7b2, 0xc7df80b3, 0xc3557603, 0xcdff686b, 0x84fba309, 0xeca6e1fc,
- 0xfc868633, 0x69e2296d, 0xc0fec986, 0x69538008, 0x17f93b6a, 0x87a4ed40,
- 0x91d4deca, 0xe9add99f, 0x2bf281d9, 0x8b9f64c5, 0x6db44aed, 0xbc2433eb,
- 0x15bda0a7, 0xca29fa4d, 0x3997c7f9, 0xbea575bd, 0x884dcfc4, 0x8162ca7d,
- 0xb25bbc07, 0xe243e916, 0x69ab7e78, 0x6f28fbdf, 0x48e2daba, 0xd3f3fb4e,
- 0xe8a7a685, 0x404f8a9e, 0xe2bc3baf, 0x7c2c9f00, 0x6601f299, 0xf1881e63,
- 0xbdbe73fa, 0xfe4bdddf, 0xf5ecdb20, 0xc6b1e91c, 0x170feeb7, 0x0fb74ba4,
- 0xde68381f, 0x00df903b, 0xda13c5fe, 0xbe877ee8, 0xcba84cfa, 0x7e23f55e,
- 0x78f6bf75, 0x0fda005f, 0x505d843b, 0x9a7dd432, 0x3c3df7fc, 0xf40ab76f,
- 0x07f7d51a, 0x6aa57e52, 0x50ade80f, 0x5f50b7ae, 0x51b50714, 0xbf6baadc,
- 0xd779f68e, 0xc68f9f34, 0x523d03f5, 0xf9b8a67c, 0x7ccbdd20, 0x4c87fd10,
- 0x94618fd2, 0x39bfb317, 0xe510fd0c, 0x95ca8979, 0xd3f5f228, 0xcf287e51,
- 0x2277654b, 0xda95f39d, 0x8388fee8, 0x2a25de62, 0x1758cba8, 0xdf3896f3,
- 0x2f7e66b3, 0x5ede3f96, 0x76edc119, 0x9f740f90, 0x79d79ae7, 0x079140dc,
- 0x1cae4285, 0x9ca9e7c1, 0x3ecacdff, 0x442d7411, 0x4e47efbe, 0x0b308f24,
- 0xe282b87f, 0x58463b3a, 0xa7f45d78, 0x89dc7971, 0xd1bd97de, 0x8a9b1e99,
- 0x3dca2cfd, 0x14791e5f, 0x282f91e7, 0x0e482207, 0xc184d1ac, 0x945e8aba,
- 0xc2a2fee8, 0xa073ab79, 0x7ea65b39, 0x2d49ee88, 0xe35bbcc0, 0xa7f2f3f5,
- 0x57b8f1a3, 0xec52f288, 0xe0ed1503, 0x351740fb, 0xe40d1f7c, 0x2ff5e50d,
- 0x073ab49b, 0x68496ff9, 0x4fdbd6a9, 0xd7f8d9be, 0x58af5b9d, 0x0fde139d,
- 0xdcad179f, 0x5d883ad2, 0xbda15e3f, 0x72cc2736, 0xde6573fd, 0x3cca0d17,
- 0x79066827, 0xeaf663c3, 0x734fbc1c, 0x85dffe99, 0xc5f75f07, 0xf51b9d66,
- 0xf697c02e, 0x56bcee83, 0xbd5f13e1, 0xcc8578d9, 0x371ffb49, 0x597fbf9a,
- 0x534fb922, 0x57f02d5e, 0xf9d9f13d, 0xa0fdef68, 0xf6be4229, 0x160a25c5,
- 0x407ba30e, 0x79870bec, 0x4bfc25c7, 0x55839410, 0xa0e23394, 0xbe70f812,
- 0x28781fb5, 0x0467ffed, 0x329a4fcf, 0xe0d5f382, 0xbdcfc5a9, 0xa39e28c6,
- 0xe3741d4e, 0x54a621f3, 0x7cb74fce, 0x2062643e, 0x60c8776f, 0xf74fb8c6,
- 0x5c51bfa1, 0x719d7bb8, 0x306fdf36, 0xdf7848b2, 0xddb6911a, 0x8afbfe3b,
- 0xe7814738, 0x7efce9be, 0xe387e6b2, 0xbea6a94a, 0x1bd912b8, 0xcfb481a9,
- 0x9574d5d2, 0x4b775bf4, 0x43f719a6, 0x469cdaba, 0x7ff2b7e4, 0xea184ffc,
- 0xb396aee1, 0xf5d69794, 0x57ca79dd, 0x06f228db, 0x7c89348f, 0x098b36af,
- 0x7ee7779f, 0x36ed8391, 0x5713d289, 0xa53171e0, 0x2565fc54, 0xff75e07e,
- 0x6b8428d1, 0x93e379bd, 0xa60f3019, 0x1ddfa6af, 0x0439ff00, 0xae2787f5,
- 0xa1ff0960, 0x2b8c4a3c, 0xb8f027c4, 0x57189602, 0xb8f0d788, 0xae31d602,
- 0x15c62580, 0x15c639f0, 0x05718eb0, 0x015c63ac, 0xc05718eb, 0xf80ae312,
- 0x8e716bfc, 0x378c1ba3, 0x9234f71e, 0xcf515ffc, 0x88576bf7, 0xd457a1fb,
- 0x85b7944a, 0x0f5038e7, 0xd3c7975e, 0x5c78f228, 0xb03f685b, 0x456cbf7c,
- 0x0f79e154, 0x79f30e87, 0x3c628e7a, 0x64af7ca8, 0xe7c16d5d, 0x1b1e69b3,
- 0x9e3f325b, 0x35ebcf87, 0xac97bc56, 0x309be5bb, 0xb515778c, 0x6adc53d4,
- 0x2d21f852, 0x6241b9e1, 0xa59d6f18, 0xa9727ee3, 0xd3474f0c, 0xd1d929be,
- 0xf236baa5, 0x4a778a5f, 0xddf3ef66, 0x90af63e5, 0x9bcbe89c, 0xf9cc1972,
- 0xc6d5fa3e, 0x4ff0aef3, 0x57d88fc4, 0xf49bca5e, 0x3d9159e5, 0x2d1f65e2,
- 0x7c64fdc5, 0xe7477f2e, 0xd1c14a4b, 0x93f5281d, 0xcfb7e587, 0x77b2d45c,
- 0xe29bde3d, 0x77dcdfbf, 0x9f6fcf5e, 0xd8aa6579, 0xcfc51e4f, 0x9d3ee489,
- 0x7c3f67bf, 0x475ab7af, 0x70e54af6, 0x266a657b, 0x28d86be6, 0x90f472ee,
- 0x2fadfc81, 0xc4f924b7, 0x21e5b25d, 0xae58f714, 0x6b8f4891, 0xb0ebed92,
- 0xc5dcc4df, 0x18996f14, 0x567e2261, 0xa4bdf0e8, 0xfdf1c7bc, 0xc50b34f2,
- 0xec75b2bb, 0xc89e3467, 0xf89282ef, 0xa24abb2d, 0x3217a97b, 0x597b9d2b,
- 0xf2f7e360, 0x2de8f729, 0x41cf3c60, 0x5be5aba1, 0x282bb224, 0xfb861100,
- 0x0b9e1c9d, 0x7ba1de5a, 0xc4eb164f, 0xbe2a7e3d, 0x89b51e1f, 0xc12cbfe7,
- 0xdef0a41b, 0x58abd010, 0xb37d9e82, 0x03db9e1d, 0x3b734487, 0xe38e12df,
- 0xa1ae3c2f, 0xf0ece13c, 0xa4ed13bb, 0x3e5127ef, 0xf6ef5e03, 0x921f88fd,
- 0x0cf9bea3, 0x43793547, 0x48addd70, 0xb1e714a7, 0xb2bc7953, 0x9e254a80,
- 0x762fe4a3, 0x17b83a1f, 0xce5d9fbf, 0xe1bde5ef, 0xfe80bd79, 0xe729adcf,
- 0xf9145e15, 0x53aa5175, 0x75fcf063, 0x2b46b7d4, 0xfc3b3fae, 0x8af79d10,
- 0x4e1fe313, 0xe5037bcc, 0x39882d8a, 0xcbee1fb0, 0x733c0354, 0xc6120170,
- 0x3c365dcd, 0x4873d337, 0xf51e5332, 0xcb73f275, 0x29efcc3a, 0xdee8978f,
- 0xea809cf0, 0x3f1830ec, 0x8ac63627, 0x89bcbbf2, 0xa0bb5dc7, 0xc3bf78e4,
- 0x3181f749, 0x14d73f7e, 0x2490b781, 0x4cd489fb, 0x82a9f3cf, 0xae5bba6f,
- 0x9be1fcf2, 0xe8eb65c7, 0xb06613be, 0x21b1f72a, 0x188ea7de, 0x8559f14a,
- 0xc21b7a6e, 0x7cdd23b7, 0xbcc3f42e, 0x68352779, 0x6c987c3f, 0x30e10cff,
- 0xbacaff3f, 0xff675a30, 0xcf2531f1, 0xa63e3fde, 0xabffedc8, 0x2bf7fafc,
- 0x513ca82b, 0xb6ca92b9, 0x07bd074a, 0xea75f0bd, 0xff55c5ad, 0x8ff5f08e,
- 0x65bd32ab, 0xe057e900, 0xf6c71e6f, 0x5f02a38b, 0x7af8bcab, 0xa2f04b62,
- 0xd47f680d, 0x4ffee968, 0x615e77cc, 0x49a03924, 0xaa9e37eb, 0xf148cdc0,
- 0x18665ed7, 0x909ff08d, 0xc156a71c, 0x926901fb, 0xf200fecf, 0xf90fae09,
- 0x13e44b04, 0xf3dc57b5, 0x70b02d05, 0x1c07b706, 0x08180f64, 0x8357ebaf,
- 0x1ef090fc, 0xfc8fb325, 0x3f27e4b8, 0x907971c0, 0xf0b57dce, 0xef2526fc,
- 0xd7140273, 0x4f23f746, 0x0c9e5c5c, 0xc2ed700d, 0x0b2d0cef, 0xa3e2bca0,
- 0x475f4e1a, 0xb9bcf237, 0xefc7967c, 0xae5eba6f, 0x163e2104, 0xf339ec0f,
- 0xfc5fb43c, 0x35d9232b, 0x669723eb, 0x257227fd, 0xc3c38d20, 0x63258131,
- 0xcacdf27e, 0xe045ee7e, 0x314e66f7, 0x2e5b9f91, 0x7cb2a0ec, 0x72a7f133,
- 0xed4cb43e, 0xed8f58ea, 0xff3c4d42, 0xbee8cd43, 0xc1aa5396, 0xc1599efc,
- 0xc4a6a767, 0x58605e51, 0xa887bf15, 0xee896ee7, 0xc8149e03, 0x56c857ef,
- 0x0cbc95e5, 0xb956dfef, 0x54c1efc5, 0x122bf8d3, 0x73d15c79, 0x6bdb951e,
- 0xba26b951, 0xbaf6413f, 0xc631a93f, 0x39f45eeb, 0x6ecfbefc, 0x4dff72a7,
- 0xa087bcde, 0x7e1ccd5f, 0xb33766cf, 0x03fb813c, 0x7100828e, 0xb5e8127f,
- 0x99fdcf0c, 0xedc9fe07, 0x15429ebc, 0x19ad539d, 0xeb8d5965, 0x42cc79aa,
- 0x27f73def, 0xe8dcf871, 0x82db9c3e, 0x8369f9ec, 0xe717bfae, 0xce6f2919,
- 0x669fec12, 0xe34ff7e4, 0xeed08de5, 0x4fe19ce8, 0x0e3840ec, 0x3da264b1,
- 0x706c68be, 0x11f40496, 0x06f306a5, 0xd4630fe8, 0x46d05f74, 0x71f313b5,
- 0x7dc5a887, 0xef216a01, 0xd180c861, 0x85a6ded4, 0x96a7c2fa, 0xabea1b31,
- 0xf3f74628, 0xfef9ebc6, 0x5863f438, 0x4646b862, 0x7c78c83d, 0x3e00e168,
- 0x4670c2fe, 0x45a5cfbf, 0x3bf25016, 0x2677f0b3, 0xb0bbc518, 0xea68d07f,
- 0xfef150ef, 0xc3943536, 0x523df8e2, 0xb474eb3d, 0xf1f0ba2f, 0xa71fa4a1,
- 0x773df04d, 0xe78d327f, 0xb8e5282d, 0x9f0f8b74, 0x429b5a2f, 0xd68b8bfb,
- 0x3b4529ce, 0x4810dec4, 0xef3b02e7, 0xef0ba97b, 0x9d962f71, 0xf5823f4b,
- 0x57b74ecc, 0x4a2f7c23, 0xa1fbf996, 0xdffba2c1, 0x8c9e62d2, 0xf2e335dd,
- 0x774e50eb, 0xf7813dec, 0x4fbf4de4, 0x19d3fea6, 0xad9a8fbf, 0xde6cf7e5,
- 0x8ea2b8ed, 0x1eeff180, 0xbcbc5127, 0x468e60c3, 0xc0a16efb, 0x5c69f3d7,
- 0x3f5c2f7e, 0xebfd1134, 0xbddf71bb, 0x5a733d1f, 0x0fde53b4, 0xfc7cc89b,
- 0xfbc54f9b, 0xfef8d34f, 0xfe38b0fc, 0xae837f3e, 0x4b082e23, 0x4a093b8d,
- 0x4ec2758d, 0x58b4cf5c, 0xe115b396, 0x378f28f8, 0x9b981876, 0x8d3eb1e8,
- 0x3d676ae0, 0x3ae38f1d, 0x3ad046ea, 0xa39bc63a, 0x710e5ee9, 0x3312eb7f,
- 0xe31d4f97, 0x98ce77f9, 0xa9214ddb, 0x1ef07f9c, 0xa502c5d7, 0x3d565767,
- 0x5bb41b79, 0xe74f4abc, 0x7d3c9735, 0x8b2bf92f, 0xa73a646b, 0xdefb36c9,
- 0xc4fa0ae3, 0xbff3f38d, 0xdeffd58f, 0xd239c455, 0x8966fe41, 0x955868e8,
- 0xf1fb8b55, 0x4ec05b3d, 0x46f9f780, 0x05da3c77, 0x758356f9, 0xbdcfd48d,
- 0xdc01dfac, 0x6b9ef0b2, 0xcf93f146, 0xe01fedd3, 0x2f561777, 0x03507ba4,
- 0x1714ed53, 0x217e061b, 0x48413fda, 0x69d7003f, 0x7fba5e00, 0x891edd42,
- 0x34facffe, 0x9cc43cf1, 0x34ba2468, 0x0ee7e430, 0xe711398d, 0xa0ceb1d7,
- 0x6d319942, 0xe04fa70d, 0x347abd1b, 0x0160339e, 0x4bbfbfc8, 0x6f3974e3,
- 0x16af3ab5, 0x6d4043ea, 0x6e90429b, 0x4e7d1146, 0x50ebdab6, 0x18f57daf,
- 0x73728b1b, 0x7c2de6f1, 0x4cff025e, 0x34e746dd, 0x198faabf, 0x0a06798d,
- 0x4eb64c3d, 0x4de69b38, 0x8449f707, 0x31cf587f, 0xeb1a37d4, 0x2f5c4ea2,
- 0xf48c3f3c, 0x9b826d31, 0xe5b212f2, 0xbcfdfa12, 0xf74608de, 0xce32f4f2,
- 0xd41bbdaf, 0x391467a4, 0xa003c8a1, 0xd39e1b07, 0x7ffdf055, 0xf2287f65,
- 0x7243e006, 0x8a1b9145, 0x4be8517c, 0x74fe3391, 0x7cc01f35, 0x4fea68e7,
- 0x63914cf2, 0x68d50eb8, 0xf0517c8f, 0x5e30d9ac, 0x81577145, 0xd2f96ce7,
- 0x8708839e, 0x2dd92302, 0xea31707d, 0x5ad12e09, 0xcff784d6, 0xb7943d56,
- 0xe3d22977, 0xd063732f, 0xe05b98fe, 0xa7f29e7b, 0x28e7be15, 0x3df4ac17,
- 0xe56f3947, 0xfc628e9f, 0x0fb00d89, 0x9cfc074b, 0x17b9e5f9, 0xefea863e,
- 0x8131797e, 0xea97d9fb, 0xaeefc59f, 0x68f3100a, 0xa55af3e7, 0x4c31bd25,
- 0x0ff881d8, 0x7188b2f1, 0x13185d3e, 0xdff5027c, 0x093f105f, 0xf1c1ffb8,
- 0x67e04673, 0xe80fc211, 0xae3ae17e, 0x121c3a97, 0xad1623c5, 0xc1ba7c15,
- 0xe7f47cf7, 0x303dac91, 0xfa8e73ce, 0xa312c7f3, 0x7395af91, 0xfc0df6d3,
- 0xf2b4b55c, 0x762fd918, 0x872d7ee5, 0x2b5afddf, 0xebf9f95b, 0xcd73df76,
- 0x2d361981, 0xf7182bc5, 0x1f2516a3, 0xd536f9e1, 0xbbf71992, 0xfcf3c5f3,
- 0xb9cf920d, 0x1e749cb9, 0xa698da17, 0xa3b63c26, 0xcaf1429d, 0x0a2fd26a,
- 0xa0dc829d, 0xd5f97c73, 0xbd4bb4a3, 0xf122e8e4, 0xcab2717c, 0x36d777e7,
- 0xebfdf1a6, 0x181a6476, 0xac725377, 0x3bc90976, 0x9547c50b, 0x47928bf6,
- 0xc1b8c7af, 0xebf8cda2, 0x33fe9e47, 0x367cf9d3, 0xdc94f98a, 0xe5f7ce40,
- 0xb79fe155, 0x9fc9bcd3, 0xf7757a2e, 0x033bf8ab, 0x91d57f45, 0x291a299e,
- 0x9d53d9f6, 0x3ed2f759, 0x55d73f32, 0x693df026, 0xe84167f7, 0xf2379427,
- 0xeca1b2fb, 0x556cb2c0, 0x65fbf901, 0x9087e056, 0xdfbff3eb, 0x41aff57e,
- 0x88ecbe3c, 0x47ffbf12, 0xd65563bf, 0x1fc505f8, 0x64772ed0, 0x4f9478d0,
- 0x5cbfdfee, 0xfb882efa, 0x9704edb1, 0x84df43ec, 0x5ff63cd1, 0xf979b8a5,
- 0xf66175a1, 0xdd7dd67e, 0xcf110139, 0x2af81728, 0xe0af9b67, 0xaaf95afe,
- 0xc82cf3dc, 0xbf7fbe33, 0xce22e975, 0x8dbb1b70, 0x4cd5d6f2, 0x5ccf7de5,
- 0x07e133af, 0xb7cb25f3, 0xbd9d73f2, 0xdc00cb6a, 0xe716eb97, 0x1ddbfcb4,
- 0xc37ee74f, 0x0c27e065, 0xc8377444, 0xddd3cfb4, 0x6578e3c0, 0xe2b54f0d,
- 0x7032d8f9, 0x959d919c, 0x8d654473, 0xeb7bd332, 0x1a47cc35, 0x1679e378,
- 0xfdd136ef, 0xc92e8534, 0xe9f30f56, 0x90697f05, 0x165e7cd7, 0x73ac5574,
- 0xcaf8e165, 0x72105ffc, 0xd857694c, 0xb79d14f2, 0x645d7685, 0x903efc9f,
- 0x9eb2fdf1, 0xcecf3813, 0x7f68636d, 0xb7b5d0ab, 0x0d8fe28c, 0x72b79481,
- 0x7e7be351, 0xdef89f7b, 0x676e74be, 0x24de6274, 0xa6557ff6, 0x13ce19b8,
- 0xe4a2f1f9, 0x2cd1cf9b, 0x73a735fa, 0x3a7e653b, 0x7da503e7, 0x2823aba1,
- 0x6f9fda1e, 0x6f9513fa, 0x6f7c7b61, 0xbd474b6c, 0x9031be79, 0x6f9ed3ce,
- 0x0de73e7c, 0xd765def8, 0x8bc950f8, 0xf3a74ebf, 0x6de5e5f8, 0x73b05ce2,
- 0xe26738a0, 0x3674f5a2, 0x5fe84944, 0xaffc8a96, 0x417dc6ce, 0xc75fe22a,
- 0x627bf67f, 0xefbbafb3, 0x264c77ac, 0xf76cbf9e, 0x7fecefb9, 0xf132fc6b,
- 0x13caa8dc, 0xb7bfe1df, 0x5ddf94ca, 0x4a76f331, 0x48fe763c, 0x0e7803cb,
- 0x7fc7bd97, 0xfeec0d97, 0x9a3fd167, 0xe481c7ff, 0xadefe27f, 0xf7ebfd60,
- 0xfcd9bef9, 0x44ae4231, 0x4cbe53b4, 0x1fb70c47, 0xcc48364a, 0x062b7006,
- 0x680072fa, 0xb3329c4b, 0x231dfde3, 0x2772fef9, 0x2476bfd0, 0x67ca0bc9,
- 0x1dfe0339, 0x6bc10efd, 0x24b93f7c, 0xe7889dd6, 0x5e453b03, 0x3b884941,
- 0x7b8c2071, 0xc949d049, 0xb7a2774c, 0xddb2537f, 0x9735794d, 0xbe1d3e44,
- 0xc95e78c7, 0x23aede68, 0xe745dcc6, 0x189bf638, 0x83aaabda, 0xd2c3a226,
- 0xbddb0d97, 0x4699d5cf, 0x92fffb72, 0xee1bdf96, 0x53e7c1d8, 0xe34d5418,
- 0x5df4125c, 0xf34d5018, 0x29ce233b, 0xbd796a17, 0xbee8c343, 0xfc5d9efe,
- 0x918ba13e, 0x3bf0076d, 0x50a57717, 0x8c4769de, 0xbd136973, 0x452679e7,
- 0x38dce8af, 0x4cbb0baf, 0xf7282e74, 0x9f695b97, 0x274eb7b1, 0xc2e1dc61,
- 0x1ee74620, 0x220fd42e, 0xb2417d7d, 0xc2f37c50, 0xbc6903bb, 0x7495caa2,
- 0xc408a5be, 0x509dda04, 0x76bda2e6, 0x68b9fea1, 0x6fa85fe4, 0x559dbac0,
- 0xf239ffcf, 0xbbfe4ee9, 0xf95f1710, 0xbef78a7b, 0xeffa528f, 0x54f8289f,
- 0xe48da7de, 0x923698fc, 0x91a8f3f3, 0x3bde7e66, 0x2c4cf5d0, 0x37f38fad,
- 0x02fc99c0, 0xafba27e0, 0x39ab8ce7, 0x8a71824c, 0xa86c9a0e, 0xee343bdf,
- 0x0e09e7c4, 0x7877e281, 0x1785f918, 0xbf240c76, 0x1a68ac1c, 0x348ec2e7,
- 0xf252d3ca, 0xada1a64d, 0x234c7846, 0xdbcb66f8, 0xe5fee9d2, 0xc7ca40ba,
- 0x36fc7a29, 0xc89fe515, 0x7a2eeedc, 0x5134f175, 0x4d7ee1b7, 0xa17fcfd1,
- 0x93e28bc0, 0x89695e4a, 0x8fa5a390, 0xf30031df, 0x651fd970, 0xaabb93ca,
- 0xfe8f79e6, 0x48e5f970, 0xbc0f4721, 0x025b7c40, 0xc3bf8e74, 0xc2f22c54,
- 0x71e15f8b, 0x77f5e296, 0xf1f24b3c, 0xde618684, 0x53d725ef, 0x2f70de41,
- 0x96e5c918, 0xda95bfa7, 0xde7b4317, 0x9a20bdff, 0xe50d0ecf, 0xebe3fb29,
- 0x22bffb96, 0x8bfd5bff, 0xf407605c, 0x957c1fb3, 0x57f23db5, 0x060d0394,
- 0xf29e83ab, 0x8d4ebdfc, 0xdf3f296b, 0xd0f92060, 0xaf7e2c19, 0x11e792b5,
- 0xfa9faf14, 0x3857ca6b, 0x699d2f75, 0x7fece65a, 0xa474aebf, 0x0f8bef86,
- 0x3e400eb4, 0xe07c052c, 0x3a1f8078, 0xa8fece5f, 0xebfefea1, 0xcb923a99,
- 0xdc3e3ef5, 0x3ba1f3c3, 0x74bc7307, 0x7a449abe, 0xd39823a7, 0xfc97cc35,
- 0x5e60ced4, 0xe604a252, 0x3d3998df, 0x91778e74, 0xed29ddff, 0xc343b2a5,
- 0x14ad15fb, 0xe6e22bbf, 0x482523f9, 0xff7871b3, 0xb436e6cf, 0x671e503b,
- 0xadd2a68d, 0x1efeb90b, 0xf263a076, 0x7e0a8eef, 0xe870f252, 0xae280177,
- 0x3ca2d2e9, 0xafbb0bb5, 0xdffae1a4, 0xefe7e08b, 0xae43ca25, 0xfb29291b,
- 0x540794ec, 0x2b3c25cc, 0x9fb44876, 0xa1f6bc5f, 0xe2fba442, 0x91732d8a,
- 0x1475941f, 0xfa2e59ab, 0x4c921d49, 0x7ebf01f3, 0xebd4ccc1, 0xf7c0a7bf,
- 0x197ccaf7, 0x3d27cfdf, 0x6fb6bc03, 0x53b145a4, 0x578c3559, 0x4cda56b2,
- 0xfc5189df, 0x053ebe4e, 0x83efb84e, 0x3c4a8cf9, 0x57eb46e0, 0xf9a379e6,
- 0x75e423bc, 0xd7e58c47, 0x1fdf10e3, 0xae4f24c8, 0x4066377e, 0x6dd80fc8,
- 0xcaa14bf4, 0x0fff3078, 0x38c11751, 0x56790acf, 0x79c3f30c, 0xfdf36e26,
- 0x3ae4807d, 0x06f0fadf, 0xa36a7adf, 0xc5bd3d6f, 0xdb7d6eb7, 0xdf82deb7,
- 0x09c0f4cd, 0x073c61fd, 0x879c53b1, 0xcf187f40, 0x8c3fa133, 0xb187f475,
- 0x9f187f44, 0x758c3fa3, 0x8eb187f4, 0x8925b0fe, 0xa258c3fb, 0x65cf8c3f,
- 0x4953872b, 0x023f8f2d, 0x2fb46c1e, 0x5df9473f, 0xd10bf00a, 0x421c2d1e,
- 0x7cc61d76, 0x7e9577e9, 0xd2296d79, 0xfd930cd1, 0xcc4cc8d2, 0x1f5b6ac7,
- 0xf2fded89, 0x1b464a94, 0x686f188c, 0x3d7e775f, 0x2629219a, 0xaf6c15fb,
- 0xae952fe4, 0x4f7e8b7c, 0xe5b57daf, 0x78e13f8f, 0xf287b8a2, 0x78454f7b,
- 0x714cbe4f, 0xf8a33d2e, 0xdfdf559e, 0xf9fedc3d, 0x679ab746, 0x5801fff4,
- 0x00db8bbb, 0x0000db8b, 0x00088b1f, 0x00000000, 0x7ccdff00, 0xd594740b,
- 0xe6feefbd, 0x49324995, 0x41e42126, 0x21e4cc20, 0x49389311, 0x47114bc8,
- 0xa8d53048, 0x684d43c3, 0x4092138c, 0xa3c30480, 0x7b96c4eb, 0xa4401833,
- 0x51b78d70, 0xa13a3951, 0xe85de94a, 0xb6950a09, 0x1006739c, 0x4e6d8ac5,
- 0xb6abad5b, 0xa9078838, 0x68349687, 0x69edec57, 0xdff7ffef, 0xbef997df,
- 0xbc7b5249, 0xacdd77ab, 0x7bfe7ba5, 0xfe3f6fef, 0xeffffdef, 0xfc42108d,
- 0xfb5bfe85, 0xdaf08c7c, 0x85fdff05, 0x442fdfff, 0x59cf10b9, 0x0e9d3247,
- 0xd77c2e21, 0x4f5c5bbe, 0x1868ac65, 0x06e6a42a, 0x09a449bb, 0xb8df11b1,
- 0x5335a884, 0xef0479a7, 0x28c7f651, 0xa4f34c42, 0x885d3108, 0x49f933d1,
- 0x05fffa82, 0x2c4f377f, 0xa8cac75b, 0xadde0eb3, 0x6ccf3098, 0x548af09b,
- 0x735dfb1a, 0x4f1a05f0, 0xa24d79d4, 0xea4d8842, 0x35ece71a, 0x59105109,
- 0x38c1b5ef, 0xbfeb7421, 0x018a60ee, 0x619a1a2e, 0xb1fd7fe8, 0x497b431c,
- 0xbda1ae68, 0x13d6f96d, 0x962144e6, 0xf4332eed, 0xbc116abb, 0xa7cfabcf,
- 0xea6e0307, 0xf0d1bbe7, 0x3aea109d, 0x936eb29d, 0xc3fce475, 0xd1d37fd4,
- 0xe3004f4c, 0x2f0b35ee, 0x8d03b7ed, 0x2b6442a5, 0x4f181d81, 0x179e2a0c,
- 0x6a56bc68, 0xe8bb53f7, 0x9d38f3b1, 0x2c3b7e2a, 0x2da4e022, 0x9bf3447d,
- 0xd1e77fa9, 0xc256e0f4, 0xc9c61f4b, 0xf0a776a4, 0x6b78d326, 0x87170ee6,
- 0x6f359c68, 0xd042bb7e, 0x83ccbb16, 0x215cced9, 0x03c12b36, 0x9f10b34e,
- 0xab4e1ca4, 0xd98776a6, 0xf443c8bf, 0xfca67cb9, 0xe78455c7, 0x1ecc87cb,
- 0x0d6d93cc, 0x291295a5, 0xab268385, 0x038cec06, 0xcdfb07fd, 0x63a24175,
- 0x9cc3ad16, 0xc18fe112, 0x797169fe, 0x35bec88e, 0x0b6d987e, 0x7d84dccd,
- 0x79eb1cbd, 0x0a3f8041, 0x9dbc62ef, 0x8fe02b31, 0x80945b8e, 0x3ec8faed,
- 0x77e53a37, 0xea3e7eda, 0x7c0632a5, 0xdb3e65e6, 0xbe5fb6ac, 0x8bb144f6,
- 0x7bd9d1f6, 0x2c4cdb2c, 0xe874ceb0, 0x01952640, 0xfb19bfbb, 0xffcc18e9,
- 0x679a7cc5, 0x61663bed, 0x3efffea6, 0x9ab128b0, 0x8bc9f7f6, 0xc13d4f56,
- 0xdb7ff70f, 0xac7da616, 0x1e6d04b5, 0x3bbe3b2a, 0x7952f368, 0xae41c1eb,
- 0x65b0755f, 0xb575f831, 0x7d81dee8, 0xbf12b25f, 0xb1d1f0eb, 0xa4e7d950,
- 0x31eebf75, 0xc4777f31, 0x6bda3f09, 0xa74ff3cd, 0x95077f62, 0xb97b2c12,
- 0x85adb0ef, 0x7ed47bea, 0x7a32f2d1, 0x74ed5976, 0xa43a3fea, 0x92a7de30,
- 0xd743bb8f, 0x1b2c7cb2, 0x7cb97373, 0x88213aec, 0xbe11df25, 0xa5744122,
- 0x3ef01ab5, 0xfcccd67a, 0x1cdc7a39, 0x8749f414, 0x0cba942d, 0x2b17f874,
- 0xf88ba1d3, 0xa4f88aa7, 0x40df7e8b, 0xd9be6fa5, 0xd40fbfc0, 0xbdf81bc4,
- 0x88e4e841, 0xcc47bbc6, 0xebcbc030, 0xeffd0d73, 0x945d7e5d, 0xda46943c,
- 0x0dfff8cd, 0xbb827691, 0x4a5c04b6, 0xc685a022, 0x30b72a7a, 0xf866dd9f,
- 0x8d2c4bbe, 0x3f9f03f4, 0x678c6fff, 0x4b6d8621, 0x26bf688b, 0xafd107a2,
- 0xad5e7fc1, 0x6d3d730f, 0xb39720c4, 0x98bf3d73, 0xf2317c4f, 0x47ec55b6,
- 0xdf089fc5, 0x7f46e815, 0x20e913b9, 0x9d5a1104, 0xb1d68937, 0xa9c908fe,
- 0x618a5f41, 0x06eb17d0, 0x74b6ba1d, 0x2a628bd4, 0xb4059be9, 0xb0c0ae8f,
- 0xf8c1dbad, 0x4a1164b7, 0xa22bf7d6, 0xdbfb8527, 0xbc2452b3, 0xac47f505,
- 0xf875861f, 0x686378c3, 0x816e633f, 0xafb744bc, 0xac0b7da7, 0x3dfeec47,
- 0x2dfad5f4, 0xde631f75, 0xea3cdaf5, 0xae9f1af8, 0xebdf4bde, 0x9e3d1dd6,
- 0x72c5c4a3, 0xe1e0f6bd, 0x7e1067d7, 0x4b92f996, 0x439d4720, 0x852dac4b,
- 0xd34df913, 0x9a0f57fb, 0xf06e3183, 0xb7e629df, 0x8f5683d1, 0xb2f01bf8,
- 0x0f182bde, 0x8ab87cd1, 0xf9a765f6, 0x3c511d57, 0x03f64541, 0xf146d67e,
- 0x9acdc627, 0xbe1a6f04, 0xd517f1c6, 0x683f1abe, 0x298fab9d, 0x09cbe841,
- 0xa7c68978, 0x3f2acf3a, 0x0aeb90fd, 0xc6a2baf2, 0xf2d15515, 0xfe86c9b8,
- 0xe114fba3, 0x1f18be54, 0x2c6cc74b, 0xe573b3df, 0x2a8e47fe, 0xddf4fd9e,
- 0xae16633d, 0x1f1fe71f, 0xf214ade1, 0x921f0137, 0x7e527c9f, 0xe34b1eee,
- 0x7c5efeef, 0x34fc45f5, 0xefdc573b, 0x7af44473, 0x621e9e44, 0x49294b3e,
- 0x5b48bd48, 0xace5dfa0, 0x3b3d541f, 0x4d243e95, 0xfc94facf, 0x71e7e603,
- 0xf894e3bb, 0xa57568dc, 0xeb4f8327, 0xd468f68c, 0xd64a4ae2, 0x642d21f9,
- 0xc0d35d67, 0xc2d333bf, 0x609f8e34, 0x4f4d57e8, 0x76f1d5fb, 0x0ecdcb6c,
- 0x6ff3beeb, 0xea09a6b7, 0x1a75bd9f, 0xceb12d97, 0x9691d834, 0xec1f66ad,
- 0xa48f87e3, 0x5f1155a7, 0x9addb87d, 0x7c434f5a, 0x6cbce0f8, 0x96b80451,
- 0xc58f0bcb, 0x131d0434, 0x625d55f7, 0xfd747c62, 0xaed8f7f7, 0x3674d6fd,
- 0xb77201b1, 0x156268fd, 0xfb6eb38d, 0x649c2acf, 0xfe4c87cf, 0xffda12ba,
- 0xdb20ca27, 0x2c1ce173, 0xfc4515f6, 0x6bdbb589, 0x3bf761d3, 0x59ea7cff,
- 0x56ff7dd8, 0xf8899a6b, 0x273f37e8, 0x3db0a87b, 0x52e23f63, 0x4be3e4ac,
- 0xfb07c42f, 0x292fff88, 0xf54b1bc2, 0x8a27cc6b, 0x7afb069d, 0xffcc1efc,
- 0xb79a76cf, 0x0f06f31c, 0x4f5e6064, 0xebcc1ae0, 0xe49f9adf, 0xddfe2bff,
- 0x7fa57b03, 0xe7b54077, 0xa0328857, 0x3b5ec1db, 0x97abffc3, 0x88473d10,
- 0x0c19bd43, 0xe2ebd4bf, 0x80b7a872, 0x3914d7eb, 0x46fbbd25, 0x3cd2364a,
- 0xa0a28581, 0xa3aded9b, 0xdfeb42c0, 0xe079c4a4, 0x3c526c4f, 0xfdd04ee9,
- 0xced2c9e7, 0x5e8bf4aa, 0xe4234dcf, 0xf3f8e983, 0x68bb31e6, 0x2deff1d3,
- 0x2f00d922, 0xfa1a67b2, 0x86dd3ad7, 0xae335bf6, 0xc57fb435, 0x6f806255,
- 0xf436a82f, 0x8b73c3bf, 0xeaabbe01, 0x4bfe862b, 0xf00c4bbc, 0x4346bab2,
- 0x2d7dbbff, 0x1b7bf686, 0x1bda18d6, 0xf00c1bfd, 0x341e3b57, 0x7bafbff4,
- 0x2bdda1ab, 0xbbd8169c, 0x171f44e3, 0x885ffde1, 0xbd37282e, 0xd3d0ef9d,
- 0x5322fe75, 0x7c24d0f7, 0xf48968fb, 0xea517e6f, 0x98fe05dd, 0x487c9265,
- 0xc3ae17a5, 0xd427b033, 0x0a42259e, 0x38622bfb, 0xdd137c13, 0x7e7dba2f,
- 0x2eabc9fc, 0xf4ada1a2, 0xe90b06c3, 0x2795f98d, 0xbe0972cb, 0x1b6be5f3,
- 0xe61fa42d, 0x2af278df, 0xb6951fe0, 0x32fb7235, 0xc345aec1, 0x04376fcb,
- 0x6ff39d68, 0x81edd9ce, 0xe913f3df, 0x9fc54cf7, 0xbe5b77d8, 0x10ca37dc,
- 0x93ca23f1, 0x5f288fc4, 0xb36c7e23, 0xfc47bf92, 0xaf4cf288, 0xd47feb87,
- 0xd9e5c55b, 0x3f972f5e, 0x72e3adee, 0xe5c7d7b8, 0xb81b7b4f, 0x9faf79fc,
- 0xb7b77bbf, 0x7af7cb83, 0x97feb9bb, 0xfe5c3dbd, 0xf5c037aa, 0x2c2896af,
- 0x0102b4ff, 0x037b05bd, 0x776f5dfe, 0x77a4cc84, 0xe5eb31c5, 0xf24abd71,
- 0xdda578ad, 0xa2a95c54, 0x6ebeca89, 0x5c878e11, 0x17c92d86, 0x39f8be89,
- 0x7a237ed9, 0xea2e22d4, 0xc61fadfc, 0xaf424f7a, 0xc9d33108, 0xffad58fa,
- 0x69ef52a7, 0x15ee5fae, 0x977a7d7a, 0xd023ffdb, 0xb2f71dfb, 0xec3332fc,
- 0x24e9f753, 0x24c77a6a, 0x93e3263a, 0x593e5467, 0xc62c4f60, 0x3d816ef9,
- 0xb27b083b, 0x83ee12c0, 0x4cfbea1e, 0x3d221eb8, 0xc6c12274, 0x11efa97a,
- 0xca13fb0b, 0x9be182a7, 0x7dc30552, 0xa19b0d9f, 0x3d381777, 0x54576c19,
- 0x022ecf38, 0xdd722949, 0x4a1e6758, 0xa7cd53c2, 0xf3b045e1, 0x2e6c3937,
- 0x5f9c09e8, 0xcf314a62, 0x02bcdabb, 0xd7bd52e3, 0xff3fdf46, 0x68990899,
- 0x5fa8b35d, 0x10a5f32c, 0x87d81728, 0x87923ecd, 0x276f5499, 0x9bd51678,
- 0x02d7bb65, 0x6c3a7c3a, 0x76a11d86, 0x03db2491, 0x7cc894a6, 0x2c133ada,
- 0xeca97e34, 0xe72a5897, 0x39c0bc01, 0x3ad0a254, 0x1e1cbafb, 0x02dd21e0,
- 0x5efee7de, 0x543f7f33, 0x3a1e04e2, 0xfb411e1d, 0xe2052c20, 0xaf1fb94a,
- 0xd722c133, 0x5fa9f353, 0x432fd178, 0x71d46278, 0x803db2ec, 0x0d4a6e71,
- 0x8f805a65, 0x20279b6e, 0x9d62f1c7, 0xfb2f17e8, 0xb93acc85, 0xad03fbcd,
- 0xacffec97, 0xf4376194, 0x4c43f12e, 0x2bd4f829, 0x539961f9, 0xa97083f2,
- 0x1a1fcab0, 0x4a752cbf, 0xedcafc92, 0x78d29677, 0xafe718be, 0x7fce49e3,
- 0x97e6e4aa, 0x512cdf10, 0x1fbff5fd, 0xfd2578bf, 0x7bbd5267, 0xf468df22,
- 0xe347f8d1, 0xd23e6883, 0xb7a340f8, 0x7f345df6, 0x3455f345, 0x4bb02d3f,
- 0x0f8e833a, 0x49f91329, 0x906874f9, 0x6769dfd7, 0x4fcd16bb, 0x35307cd1,
- 0x4e7dc93f, 0xfd08a3e4, 0xcf2f8f81, 0xde6ec347, 0xa4fb66c7, 0x8ff1a47c,
- 0x1f1a4fc6, 0x16223fdd, 0xcb535127, 0x9475eb98, 0xcffc727b, 0x8ab48f40,
- 0xab33165b, 0xbe45cd38, 0x9efd8984, 0x5bdfa298, 0x501fc4b1, 0x2f73c23c,
- 0x2e3381fc, 0x7ec5d8ab, 0x4251d7b6, 0xeaa45bf4, 0x9ba233d1, 0x8fb91ced,
- 0x46b5d001, 0xc2a2f125, 0xd77fecd5, 0x2c7e8c38, 0x88fc232c, 0x17efd4db,
- 0x0db7c9ff, 0x6a9c58eb, 0x536f6ff4, 0x455be3fd, 0x375f8f3f, 0xf0bdaa33,
- 0x6f9bf656, 0x6fd633cb, 0x5efd5528, 0xcf4370b7, 0x5c8f08d6, 0x7ecdd89f,
- 0x572a8d6b, 0x72fd2a59, 0x9f31665d, 0xfc2b58f0, 0xd7f72816, 0x62f3677e,
- 0x80455bdc, 0x2088afe1, 0x108bb797, 0x1907738f, 0x0977c002, 0x69dc0561,
- 0x91b6c91f, 0xfb37ad48, 0xf85f803f, 0x39fe59db, 0xc636c738, 0xcf20fbfa,
- 0x6cefe2a7, 0x5be6807a, 0x0f28b654, 0x71ac9ddf, 0xd2753fb1, 0x1dfecb9e,
- 0x129ac2e4, 0xc937cf91, 0xfd91e63e, 0x13f6453a, 0x9fb269e5, 0xdec76479,
- 0xf809fb20, 0x02ad82b6, 0x29762ddf, 0xb7dba2c2, 0xceedfdf6, 0x6d32c245,
- 0x7b74fb6a, 0xfa67f7f1, 0x4adf7f89, 0x1223539e, 0x60d65651, 0xa7256fbf,
- 0x6319649b, 0xd5e8b2e3, 0x4ffcc9bc, 0xf322ff8d, 0xa6f9e62d, 0xd786b3c2,
- 0x786a7c68, 0x7d7812fe, 0x3ebc3269, 0xced82253, 0x595fda8f, 0x5755b88f,
- 0xde6fd4bc, 0x06441357, 0xa3c6eff1, 0x1bfd1cf2, 0xe313312c, 0xf7b53c4b,
- 0xe42c28dc, 0x2bdc7f4a, 0xaaf3c002, 0x8fae6a9e, 0xf7898f8e, 0x6bf8616e,
- 0xd9572f2a, 0xdde821fd, 0x6ba1a5cb, 0x1f12c3c8, 0xbc4bebef, 0xedf9e681,
- 0xce0f664b, 0xd7669d27, 0xace20f6e, 0x2f3d996f, 0x9d3ffbe0, 0x724a5eca,
- 0x369f9e25, 0xd3ac39e9, 0x9da8f12e, 0xe39dbec3, 0xce14b963, 0x23c80cb2,
- 0x5f9829fd, 0x92665ff3, 0xfe27692f, 0xe59367dd, 0x454cfe54, 0x529fe91c,
- 0x50facfee, 0xc77d1fa3, 0x538d1670, 0xeb26fa41, 0xaf3e38d1, 0xf7de9d78,
- 0x08d50ed8, 0xc5afbf83, 0x25534623, 0x6b88171e, 0xb03c449e, 0x04558ce6,
- 0x82147da9, 0x250cf68f, 0x7a35bd08, 0xfa19aae6, 0x114136b6, 0x542f60d3,
- 0x6193127d, 0x3e9d2e12, 0x09c57588, 0xe38f8e97, 0x700c520b, 0xa1866782,
- 0x8e55527f, 0x3bd93da1, 0xad3ed0d7, 0x4f00d4ae, 0xe860ddf7, 0xd0b0de9f,
- 0x6ffa6700, 0xeacff433, 0x35806a58, 0xab25957d, 0x15eeacc4, 0xf767ef86,
- 0x77f434ac, 0xda1ad607, 0xfb8971cd, 0xbc068f59, 0x4e3405c3, 0xee4e3a9d,
- 0x7e868dce, 0xaa6dd082, 0xbfc89c80, 0xceeb1267, 0x3acf4428, 0xc87aaac7,
- 0xd7ff7e69, 0xd734eb8d, 0xbca9925b, 0x7fd465d5, 0x784619b5, 0x4284e391,
- 0x4e458b43, 0xeace1ea3, 0x8ce018b6, 0xd79bd232, 0x51628fd1, 0x2f82f1cc,
- 0xae7fbfa2, 0x78d1fe81, 0x84f07e22, 0x69ec9fd0, 0xb37aeb00, 0x8f7b02d5,
- 0x1f7e82fc, 0xf1e82fc8, 0x1e82fc80, 0xdf417e46, 0x7d05f91f, 0xfa0bf23b,
- 0x4633b2f6, 0x1b0f97fa, 0x9ef95fe9, 0x5f1afe91, 0xeaa7454e, 0x843f91b0,
- 0x7f2bf15f, 0x5e374e85, 0x344ff232, 0x37266e7d, 0xf4153927, 0xd7213c50,
- 0x9dd7a797, 0xfa22f451, 0xf7c04c04, 0x9f4904cc, 0xa04975d0, 0xb319ed57,
- 0x8ffc1208, 0xc77cfb51, 0x23286fe2, 0xab86f03d, 0xebfa0334, 0x147ae166,
- 0x9dc5db71, 0x86884f26, 0x7e35115d, 0x7dff0cf5, 0x1a17a465, 0xb6cd5da6,
- 0xfc463f81, 0xdc9e7073, 0xd9ddeaa5, 0xc0fc7271, 0x127cc142, 0xd839baf8,
- 0x339ee347, 0xcfd02bf5, 0xb7f44fdf, 0x0bfbfbe3, 0xd47f79bb, 0xcdf7c143,
- 0x0d931aff, 0xe0b679b8, 0x0c28b073, 0x88492f97, 0x2ce6c5e8, 0xd43b27aa,
- 0xe39ea655, 0xdf4ed43c, 0xb8c99775, 0x69c7824e, 0xa15178e3, 0x444e22f0,
- 0xe6ecafc7, 0x6ce3e022, 0x63e01cec, 0xde41e4c0, 0x25756c20, 0xde051f41,
- 0xbde40b34, 0x9fc217e0, 0x57faa59b, 0x29e46259, 0x5ece73ac, 0xd7abb061,
- 0x62c2ed06, 0x0d397fc8, 0x8650d170, 0xc7f5ffa1, 0x92f6865c, 0xbda18150,
- 0x00c78cec, 0x19570f97, 0xe7be57fa, 0xe1d5c035, 0x1bff433a, 0xf00cf92f,
- 0xef9e456c, 0x239653bf, 0x992e21f3, 0x387e6bdf, 0x6bfa5079, 0xf9afdcf2,
- 0x49ffa2d5, 0x38711daf, 0xbf357f95, 0x6da3f35c, 0xcfd04084, 0xf6c2d3b6,
- 0xfa5da660, 0xf62dfec9, 0x6827c8f3, 0x57e6bafe, 0x08a9fe6b, 0x76f57ad4,
- 0xf693be87, 0x35ebf545, 0x8bf359ff, 0x4c5d8b13, 0xb236eb3f, 0x4b07e0ab,
- 0xae761338, 0x1a4c4639, 0x4cb9790f, 0xd7a25b9e, 0x7a2badaf, 0xa762c4fe,
- 0xdc7517e4, 0x7ee2ec17, 0xccfe24df, 0xf57caabf, 0x63beb99f, 0xad67cfe0,
- 0xbb56f79e, 0xf4f3ebff, 0x1321fc25, 0xf5f352fe, 0x264dfd72, 0xc767c713,
- 0xd72e5fd7, 0x0bf595af, 0xd921dfc9, 0x37e2f359, 0x1fc83af7, 0xc2c7b678,
- 0xaf339671, 0xe40c6c5c, 0x5e121fc1, 0xfc9b338c, 0x3e07d07c, 0x0b07ce05,
- 0xdf3ccdcb, 0x772932a5, 0xcf2cbd11, 0xd242a365, 0xc6c7b47f, 0xe849d479,
- 0xeda07ccd, 0x8b43f107, 0x510dc655, 0xc9686e22, 0xc0437197, 0x44a21b88,
- 0x2ff510dc, 0x3e187af7, 0xf0c55bd2, 0x0cbd7af7, 0xe3adeb1f, 0x3ebd07f2,
- 0x26f8d7ae, 0x79da5f1a, 0xc43fa34b, 0x2f237610, 0x1feb1f8a, 0x6d72f492,
- 0xd3f6fab0, 0xa24deb16, 0xe08d294e, 0x8f151ef3, 0x3c49e633, 0x7fe41fa0,
- 0xe6b57eaa, 0x9bc424c2, 0xc92b8547, 0xaae257f9, 0x687c2f7f, 0x973f1f78,
- 0x949bcb8e, 0x52e4a987, 0xceeb3f3b, 0xd1772cab, 0xb72d18f2, 0x3fe778d1,
- 0xfc7bb9dd, 0x53c5ab5c, 0xe8d53954, 0x55b5c9a2, 0x5fa11b84, 0xce267982,
- 0x609c3f53, 0xf3c5a394, 0x077f7e24, 0xbcf2a239, 0x326699cb, 0xfdb2f847,
- 0x1017f271, 0x4869ef1f, 0x8059e0e4, 0x7dba8fce, 0xd2faf02e, 0x2b7ea06e,
- 0xd062ac07, 0xb0757d85, 0x44096d1d, 0xd8471b9f, 0xaddb6c9f, 0x3e469f38,
- 0xe7e4e77f, 0xd13fce4a, 0x6fc26d38, 0xfbdbbac3, 0xab56fd8d, 0xfce8cae7,
- 0xd53cd54a, 0x878479de, 0x7f351ffd, 0x19f6a1de, 0x6e609fe7, 0x60df1a92,
- 0x1432a479, 0xb9bf3ba3, 0x8b28ef90, 0xb8b784c0, 0x6dc3d802, 0x6bbe4f16,
- 0x7869bf22, 0x97e7989b, 0xf7c41bf7, 0xa0fcf962, 0x232ff9e5, 0x6afa0fcf,
- 0xffb514f9, 0x985980e5, 0x48e0df71, 0x7fa7e70c, 0x4f7b3a6b, 0x7f974b8e,
- 0x11b79099, 0x309fb889, 0x27ba687a, 0xb4bac930, 0x1b361fd2, 0x684c91ee,
- 0x11347adf, 0x17cec9e7, 0xf3a69e65, 0x796953c5, 0x3cd7bd3a, 0x1bfbc2cf,
- 0xe7dbf932, 0x9bdc8f4d, 0x60c7fb58, 0x357aca31, 0x9fbd127e, 0x5f36bd71,
- 0xa519fe61, 0xab5eb1fd, 0xa47f7853, 0x49e40517, 0x112fd7cb, 0x5a9454a1,
- 0xb3bfc43e, 0xe5a0e99a, 0xd5425a43, 0xfbbb8fbc, 0xa8e35b56, 0x2da9f84b,
- 0x48ae71b5, 0x4b3c249e, 0x2a99bfde, 0xac6cb25f, 0x3e5bc784, 0xb38f2376,
- 0xe65b9e6d, 0xd9edb64f, 0xee6fff00, 0x1e056141, 0x4e3956c2, 0x553e9e34,
- 0xdcb924e5, 0x6e37b7a8, 0x6f6f5855, 0xf796ad84, 0x6b6f587c, 0x157ed5f0,
- 0xa6f095ae, 0x5b0e12ed, 0x24953b1d, 0x05c45fb9, 0xd8944fb0, 0x87b1ce0f,
- 0xf60238d4, 0x40fb1281, 0x6015f43d, 0xd0c02be8, 0xafa18057, 0xa15f4250,
- 0x65f0a57e, 0xbc888e23, 0x4e4e8d4e, 0xd1a9d790, 0xebc81ff9, 0x75e461e8,
- 0xd791fdf4, 0xaf23b7d1, 0x5e476fa3, 0xaf230f47, 0xbc8fefa3, 0x5e461e8e,
- 0x791fdf47, 0xbc8c3d1d, 0xf23fbe8e, 0xe476fa3a, 0xc8edf475, 0xe461e8eb,
- 0x91fdf475, 0xdfb7d1d7, 0xf218a3df, 0x9a93f73e, 0xeeb5df06, 0x71fcc69d,
- 0x313bedda, 0x41fbe88f, 0x66bf9ffc, 0x8f9d01cd, 0x6edf01af, 0x48f38aec,
- 0x49d7f73a, 0xa4849bba, 0xd32348f3, 0xc24d8b79, 0xe7749eb5, 0xf20ffe24,
- 0x99563529, 0x7c89414f, 0x53e44a0a, 0x529f2250, 0x29f32f93, 0x414f9128,
- 0x2829f23d, 0x89414f91, 0xe44a0a7c, 0x9f225053, 0x14f91282, 0x0a7c877c,
- 0x5053e44a, 0x4a0a7c8f, 0x7f5053e4, 0xbc81d68e, 0xf82eb68a, 0xf38679cb,
- 0xe1a1f11c, 0xc034e73c, 0xfdf597f0, 0xdbeb2fe1, 0xdbeb2fe1, 0x61eb2fe1,
- 0xfefacbf8, 0xb0f597f0, 0xe58b9e69, 0xfeb37e0c, 0x7acdf83b, 0x703fa8b8,
- 0x3ba0b11a, 0x35eefdf6, 0xe504e194, 0xdf49c559, 0x15b7ff97, 0x638583c8,
- 0x0f64ec95, 0x0fadbfd9, 0xd821a8ad, 0x2ba7deaf, 0xd0262316, 0x44d8f39b,
- 0x04487f37, 0xe8a08f71, 0xd76e4cf3, 0x47fcaaf2, 0x22392f74, 0x535f0fd8,
- 0x7da5d724, 0x334e11ef, 0x047fad4a, 0xf45fbc9e, 0xd63f5afc, 0x9075ba97,
- 0xfdc12c9d, 0x8e2d9286, 0x4fc45dd2, 0xfb0a4c07, 0x9fc807a1, 0x5e893a5a,
- 0xa3fd50aa, 0x27c3a603, 0xa22f70e3, 0xa7ecf145, 0x88b1afa1, 0xe052d633,
- 0xfe14bba9, 0xb2797642, 0xdf75afea, 0xda3f7b80, 0x1db8b5ba, 0xf22f09e9,
- 0x8447f3ef, 0xb9e68dad, 0x6b6153e9, 0x9366df87, 0xc3be02fe, 0x80baedb9,
- 0xe3afdde2, 0x697282ef, 0x0d81fcff, 0xfd51b437, 0x6fba8775, 0x171f8768,
- 0xcefbbf27, 0xc78c8973, 0xfb29b73b, 0xf99fb4cd, 0x90778487, 0xcb9495fa,
- 0x8775dff3, 0x9e36b69c, 0xd76b69d7, 0x97d843df, 0x5ce1736d, 0x8835c228,
- 0x8a7989ff, 0xf0444178, 0x0d7bfb46, 0x4486bbfb, 0x75d7f105, 0x3ffb6307,
- 0xd751f1d2, 0x7e01b250, 0xff6658e0, 0x59fe3a47, 0x72441f87, 0xec206e41,
- 0xf24aa756, 0xc3bd6af5, 0x79c51be4, 0x623ecba2, 0x9a6efe03, 0x7b8b5c97,
- 0xf0b8e26c, 0xe6ef83e4, 0x4e9f6cb5, 0xbd07f2eb, 0xba03dc1e, 0xd3eed3e9,
- 0x63ef3f0c, 0x82a7d998, 0x70f6c7d7, 0xc509404e, 0x0cee2a13, 0x09529a0c,
- 0xd5b023be, 0x87fe869a, 0x00ee0784, 0xa0b12899, 0x42afb234, 0x558a6c31,
- 0xd4e22fc0, 0x91ff1d34, 0x7e0e58e6, 0x0558f129, 0xc58963f8, 0x89be8569,
- 0xefa237f6, 0x71ff907f, 0x6867bcaf, 0x6b1ec0b5, 0x538b51fe, 0x36eaf5ae,
- 0x2d1ffb2b, 0xd0ffc947, 0xfcd52bdd, 0x085eed0d, 0x109e1df9, 0xdb91f8ec,
- 0xb9d42e39, 0x7fbe1de1, 0x783b89f1, 0xfaf89920, 0xf7c39c93, 0xb7e1b954,
- 0xc94fac28, 0x272ce86f, 0x3f6cb63c, 0x55f3889d, 0xfb0af038, 0x3db7571b,
- 0x08e3289e, 0xa6d11f32, 0xcf8b49e2, 0x68f4abb4, 0x7d01ef53, 0x3bcb7a48,
- 0x086eed87, 0xbd6836f7, 0xfb4457ec, 0xb91f9a87, 0x384f1b4e, 0xa45c45df,
- 0x8bb7f683, 0x5bbbd5a0, 0x89886476, 0xd53ae3fe, 0xcdb35caf, 0x3a7ef7ca,
- 0xc2ed9044, 0x3f54609a, 0xbacfbef5, 0x9dfac683, 0xa7fe51e5, 0xeed22e7a,
- 0x7dbcb6e5, 0x7ff66eea, 0x6f9cadba, 0xfd2ada6b, 0x04587121, 0x8bc015f3,
- 0x3704b14c, 0x947af51d, 0x27e7f849, 0x1f545faa, 0x2ebc658e, 0x7d678b19,
- 0x8b2c74b2, 0x32c67be1, 0x4c77bcb9, 0x8a5c8bde, 0x3bd10c58, 0x9104ab5c,
- 0xea99fb4f, 0x7b8ddd0f, 0x2063a092, 0x9479f99d, 0x145319f8, 0xae6a7aab,
- 0x77053957, 0xdfeadeb3, 0xf5987b8e, 0xcbfd8283, 0xd137e03b, 0xa3f00df8,
- 0xdc1e41a6, 0xb73f7cb5, 0x6ef9114e, 0x9506c3c8, 0x041e49ff, 0xeb2f0feb,
- 0x41259ab5, 0xf069afdc, 0xee81361f, 0x03f81c9a, 0xef802de7, 0x57362808,
- 0xf8279f21, 0x79f1acbc, 0xc7343cb4, 0x8725f1ab, 0xfb8d1f8c, 0x9d2c58a7,
- 0xd7e045bb, 0xded4bc2b, 0x0ce0188c, 0xf7081195, 0xfdb28509, 0xaf5fd1e4,
- 0xd3c386d8, 0x343f8c97, 0xaf4c4c99, 0xf6f7f211, 0x70c56043, 0x65e43a6d,
- 0xcbba52b7, 0x53cf5915, 0x572f0b95, 0x2bc5cee8, 0xf922f955, 0x63f9c74b,
- 0xe9f923e3, 0x40ff1262, 0xcf095b2b, 0xa4e6b390, 0xa214d7f0, 0xc2e527cc,
- 0xdb0c435b, 0xe27dd428, 0x73ad0422, 0x7c670a85, 0x9dfdee2f, 0x861f8c85,
- 0x5e5f962f, 0xbffc2811, 0x8a4d87d0, 0xab57ef85, 0xfc9871f8, 0xefc3951f,
- 0x831787b7, 0x2385f1ae, 0x1a2dd036, 0x1eedf73f, 0xf08733da, 0xe9215190,
- 0xb7eb64d7, 0x045179f2, 0xb55f88ad, 0x22fb4a16, 0xafecae2c, 0xc5c43e72,
- 0xdf6d3e71, 0x89f7aa1f, 0xace1f1a3, 0x7e027690, 0xf48e6bb2, 0x4fc25193,
- 0xf81c7dc6, 0x27e180c9, 0x8c9f84a3, 0x80c9f87a, 0x860327e1, 0x7e180c9f,
- 0xc9f84a32, 0xe4c27fa8, 0xd130ff3d, 0xf05369f3, 0xa7c4abf0, 0x4dfaa59f,
- 0xa7feb415, 0xd79b8f71, 0x11fde7ef, 0x195eb0df, 0x5fc453d7, 0x1f088af6,
- 0x70b9ecad, 0xe11394d4, 0xbf9db6a7, 0xe205ea7f, 0x17e4958f, 0x3bfd9e42,
- 0xf14c5095, 0xdcf67cd4, 0x979638da, 0x636ebee7, 0x1b64dbfd, 0x47776d3e,
- 0xcf7ef9f0, 0x7d4ab4ff, 0xd177ca19, 0x63ba2bb8, 0x4fffd03d, 0xb1d2fa55,
- 0x0f42f8de, 0xad32e5d3, 0x251def89, 0xbf50b3fa, 0x9ebf0c52, 0xbf9afd41,
- 0xda3676f1, 0xb6ee381f, 0x1cb70f41, 0xe191d92b, 0x177ef7c2, 0xe1c5b5f8,
- 0x58cfc1b4, 0xed992dbf, 0x8cba736e, 0x73c712db, 0x47a34bde, 0xb78c8555,
- 0xb829527d, 0x979ea2bc, 0x25d64108, 0x6e927e86, 0xc5a6f2d1, 0x58e3a311,
- 0xf3ca7891, 0x0710733b, 0x3e9e1549, 0x217c44d7, 0x8d2b61ce, 0xe3a251c4,
- 0x6af2e31d, 0x9df88613, 0x50a9ae56, 0xdbcef70c, 0x85abcfc7, 0xd7e1d38b,
- 0x1138a63f, 0xb8736e6f, 0xb826adee, 0x37158ced, 0x8a7d4532, 0xf04996cb,
- 0x738a23c8, 0xb9bde83f, 0x1356f584, 0xf78a5268, 0xb72cd50b, 0xcb2a416d,
- 0xafef96a6, 0xd66a763e, 0x90afb1f7, 0xb67586d7, 0x14b6bd39, 0xdad3df9d,
- 0xf7f578af, 0xb1b83520, 0x9b0dc642, 0xfc0118e8, 0x6dd9b7dd, 0x2538895b,
- 0xffb83fb9, 0x13e546b7, 0xc7ea3bed, 0x73ea1ff7, 0xabe0ebc4, 0xf417da11,
- 0xd52be616, 0xe312bf8d, 0xfea7e6eb, 0x56b5b7ec, 0x2d78f024, 0x1bb7da4e,
- 0x49d793a5, 0x8d3c6078, 0x5cf1a1ec, 0xbde30f3c, 0x7ab41435, 0xbbdc1eb0,
- 0x33857820, 0x2b3cc568, 0x7c7095b7, 0xce5bbfdf, 0x6c99dfe3, 0x675f822b,
- 0xe966da71, 0x3be23dfd, 0x0e1365f0, 0x5ebca9f7, 0x08db87f6, 0x43f0294f,
- 0x75ffc853, 0x8b57c44c, 0xfeb6feba, 0xd8ffa364, 0xf41598ff, 0x4aed5469,
- 0x549e1d34, 0xb6e578f9, 0xd7786c5b, 0xf2f166d0, 0x8abf07bb, 0x10df7fef,
- 0x90f90bbb, 0xad2781c6, 0xae1f826e, 0x93f67e90, 0xeadf9215, 0xb8f94273,
- 0x21b231e7, 0x3721ef96, 0xbf79fb3a, 0x9c7ef8e3, 0xc4ff03f0, 0x137c63e9,
- 0x9f70049f, 0x48c06daf, 0x127ac8df, 0x81b6dc78, 0x55bf9616, 0xa9cdbf16,
- 0x13dec75f, 0xa5e10af9, 0x815ee491, 0xb3fa71fd, 0x1f173fc1, 0xf79b37bf,
- 0x7be4eb49, 0xe2d71e54, 0x37cc798c, 0xff1ad7cc, 0x79499734, 0xa97be6d6,
- 0xbdf3c2c2, 0xb4e525f4, 0xdf0b776d, 0x10cd6983, 0x62f9451e, 0x53e4d539,
- 0x3546d793, 0x7bbad92e, 0xf4ebf089, 0xeeefd90d, 0xcfc12797, 0x2b9d7565,
- 0x3e127a54, 0xb8ba135f, 0x3d2abbdd, 0x728c729b, 0xee30f18f, 0x9bee5529,
- 0x37f28616, 0x6bfa4614, 0xc8a536f3, 0xe0ffc0ef, 0xbd2a53b3, 0xf7237fd1,
- 0xeaa4f157, 0xbd71d68d, 0x1a7b6871, 0x8561c6f4, 0xf71b54f3, 0xe36ebf48,
- 0xe71c098b, 0xaf8d8ffa, 0xea1ef8fe, 0x8313c9f7, 0x13f7facd, 0x27a9216d,
- 0x829fc9da, 0xdaa558de, 0xff6286fd, 0x72742b4f, 0x17adf6dc, 0xac5c81af,
- 0xf8b92a18, 0x0efbc14b, 0xeafcdf41, 0x73be1fc5, 0x5f622b83, 0xdcac7db5,
- 0x16d66ff9, 0x726f1e87, 0x560abb9f, 0x493cef0a, 0x5ac39c2f, 0x1df229b7,
- 0xfd8d8f59, 0xd1de8d4f, 0xf242d07c, 0xf088eadb, 0xa9ff4681, 0x78db26fc,
- 0x5fd24e3e, 0x07c6b7a3, 0x3a35bd1a, 0x9d297bf1, 0xfbadafff, 0x2b5e9533,
- 0x531dfe54, 0x87456ee5, 0xe58ab6db, 0x056b6ddd, 0xb1fa6bdf, 0x4e3f58cd,
- 0x7eb8e727, 0xc0b901df, 0x69d022bb, 0xc655b774, 0xa04d0f23, 0xbeec3653,
- 0x6ad58eb6, 0x8d5db1dc, 0xfcd2ae1f, 0x4c7f62e0, 0xab4e8ea5, 0x6a74939f,
- 0x5fede97d, 0xfbc5c0ff, 0x4f6c7a93, 0x2b8bfb0c, 0xbd330e87, 0x663e771a,
- 0xf4bf5375, 0x5f41b74a, 0x389776b7, 0xb15f3711, 0xf90ad073, 0x4d74af4f,
- 0xea4defca, 0xaf0d60bd, 0xce8a3fb0, 0xa1fd69ee, 0x3cd30ef7, 0x26c4379b,
- 0x368d1ee2, 0xf252b78f, 0x72776b75, 0xed6be60a, 0x381ff96e, 0x3f7a68cf,
- 0xc42eee5a, 0x4958794a, 0x2f2e429f, 0xdec9e2dc, 0x3f313858, 0x959595a6,
- 0x10cf6e92, 0x256f717a, 0xbbe87e2b, 0x03d643c0, 0x93e41e71, 0x41c2f2f3,
- 0xc63e0bcc, 0x17a46dba, 0xaf25ff71, 0xac7bfc33, 0xbe745c83, 0x213282ef,
- 0xd23be645, 0x926fde08, 0xcc72b3ef, 0x52afbcb2, 0x0f6a3bda, 0x86a45da1,
- 0x68ffb1cb, 0x5f9535bd, 0x36a7f1a1, 0x9a9eb44e, 0x57777f6a, 0xa2fa794a,
- 0xab705dfd, 0x4f029371, 0x6de69db6, 0x078e747e, 0xda2fa471, 0xe64e2da7,
- 0x4bf7c697, 0x32955acc, 0xe4f37ec9, 0xfdea6839, 0x4da6d40e, 0x7909dfb2,
- 0xb44e555f, 0x79e3efbb, 0x27997e92, 0xdd90a0b9, 0x6c2eefa2, 0x65fbe588,
- 0x38b4beda, 0x5efadffd, 0x14cac1e1, 0x4e14fe35, 0x14d93f80, 0x487fcaa7,
- 0xa25fa8c2, 0xfdecd7ab, 0x21386739, 0x3f9fa745, 0xa1ed56ea, 0x3c81ef08,
- 0x815c9e8b, 0xfeb9c778, 0x42a6090b, 0x9f5ca7f0, 0xab66ddf6, 0xf40f5ce7,
- 0xbe18f6dc, 0xd37e4eef, 0xda93c40e, 0xa71cc903, 0xeca7afb9, 0xe71a5ee2,
- 0xfc596dbe, 0xf3f350de, 0x2ffaa957, 0x8ecb737e, 0xebdff44a, 0x6f8fc276,
- 0x886cf877, 0x2c0fc5c3, 0xdfb0e5b1, 0x5a01cf2b, 0x22b36ade, 0x0c9efc7c,
- 0x657211fa, 0x7b07913a, 0xf4af7ab3, 0x624debff, 0xb39bf227, 0x338b7cfb,
- 0x529e1fa1, 0xc527f03c, 0xdaa3d23e, 0xc7748c79, 0x6fbec587, 0xef68bf41,
- 0xc6c2e6ef, 0x219fb19a, 0x829dce2f, 0x07ec0bfc, 0xa65e01eb, 0x6e71fca9,
- 0xab827ce0, 0x2fcf8230, 0xe3481efb, 0xd67f2d0b, 0x194ff88e, 0x0d29a3f8,
- 0xe6a6d1fc, 0x2c0c76c9, 0x707db862, 0xe9fbbf19, 0x473a6743, 0xfb563db6,
- 0xef08a044, 0xda3e2578, 0x09dd16ba, 0x7f63a8bf, 0x35ce324c, 0xb640d6d9,
- 0x1b6d0fde, 0x01df987c, 0xe58c1a5d, 0xce354077, 0x67b83525, 0x7c9f6ab3,
- 0x3bf5a767, 0xb597eaa1, 0xef0c8b5d, 0x4c69da79, 0xd9ff8d27, 0x5fdf3c50,
- 0x04e9ded3, 0x95e3feec, 0x4ebdf2e5, 0xd3be4bb5, 0xaefee4c9, 0x5af4e349,
- 0xbe57b179, 0x3bbdd0fb, 0xbe91b3ba, 0x257aecef, 0x7bace311, 0x4e1567fc,
- 0xceb7c713, 0x77f1fc60, 0xbbe57b47, 0x27c7f6a3, 0xbe03ff7f, 0x1c767f06,
- 0xc6790c53, 0xec4982fb, 0xc243fa87, 0xdfb6fc86, 0xbdcfd829, 0xb03d1664,
- 0xa25f9aeb, 0xc552ffd5, 0xfea4a5c3, 0xcd7fd06c, 0x61b32781, 0x20937e37,
- 0xf703a6e1, 0xc87a08fe, 0xf48c7cff, 0xfd822dbf, 0xf480d6db, 0x64f7b597,
- 0x38ec7842, 0x19547f87, 0x46b9f2cf, 0xada4977d, 0xae0bfc8b, 0xd4458dff,
- 0x6f781d61, 0xdf7e7e04, 0x3d076a12, 0x147f27df, 0x2a138f79, 0x6fdfbdff,
- 0x87f7cc5e, 0x57e01048, 0x4affdfbc, 0x9a89f202, 0xfe6b561f, 0xb4ef1795,
- 0xef951e37, 0x870be381, 0xd4231cf9, 0xa77ac978, 0xdf8db7e4, 0x4ace2eb7,
- 0x6b8abf65, 0xdb212d3a, 0xab5af464, 0xf0e34dfa, 0x2e7cc391, 0xfd243ceb,
- 0xf3a1ce82, 0x7e6817ec, 0x70bef686, 0xecf3a1dd, 0xaddf6827, 0xd2f1223f,
- 0xb7d64475, 0x78b49814, 0xc3c9578b, 0x38615979, 0xb4d2c2bf, 0x9b9b00d5,
- 0x3a505ab6, 0x08c878d5, 0x0abbe5fb, 0x99e7ca7e, 0xb8ea6dae, 0xf3755b04,
- 0x974d56c5, 0x3ea8daef, 0xa5ef81d7, 0xbbdad73d, 0x50f3c88e, 0x276e2ba8,
- 0xef5d83df, 0xebeca0b0, 0xdf3db072, 0xc02a6dd7, 0x12af757d, 0x71dcfec7,
- 0xf4d6fef5, 0x22c6ef75, 0x4629904e, 0x7cdc994e, 0x15666b6f, 0x022e9b8d,
- 0x7b4b8f7c, 0x9fe5744f, 0xf8c32e3f, 0xafc2620b, 0x5b980220, 0x7909a335,
- 0xe1490593, 0xf73c6032, 0xd384ba58, 0x0e20afc3, 0x37240ce5, 0xa5f28f21,
- 0x8af54ae3, 0x30eece21, 0x0a07aff9, 0xdb2ec6ba, 0xc4635c64, 0x5799b906,
- 0xfa68f925, 0xe2473a49, 0x83b9f51c, 0xd3e981cf, 0x9b9df9ba, 0xa1970c28,
- 0x837c71df, 0x8c7f60fb, 0x420eff93, 0xf6f5979e, 0x027558c6, 0x3de99797,
- 0xa425aeaa, 0x9f0363e6, 0xf7f8829b, 0xa12b8e04, 0xbcfdeb6f, 0x4f292aee,
- 0x979918be, 0xceb14bbd, 0xe4fa27fa, 0x835fdb90, 0xcc72fa75, 0xb8b92545,
- 0x7def2b17, 0xb7f3515f, 0x50bcbf9a, 0x7a96769d, 0xc8cdb3ce, 0xb4fe4070,
- 0xd78a89fb, 0x1f52efcb, 0x8ad93c2a, 0xc4737f75, 0x1620efce, 0x73c9c48e,
- 0xb63a8cd5, 0xd9b17daf, 0x2e283fec, 0xfea2688b, 0x214d0b27, 0xa6ffdfdc,
- 0x599e73b0, 0x6dfca3d8, 0xc3df2c53, 0xf1bf8e56, 0x964dec39, 0x92a7f7f9,
- 0xff599f68, 0x8ba078a0, 0xfe2f479b, 0x6ca84fe3, 0x187fdb1a, 0xfe4911fb,
- 0xb9c3f066, 0x7ef3bad1, 0x9d37f542, 0xb48f7643, 0x8fbf4263, 0x9e7e0fe3,
- 0xac8a6298, 0xc5c8caef, 0x879d5f17, 0xe9f1ced2, 0x32cdc785, 0x9eb5159e,
- 0xbe2e192b, 0x98fd4e0f, 0xa61c573e, 0x0b87ce20, 0x0f7a9f8f, 0x7b885beb,
- 0xd83738ce, 0xf6f597ad, 0x2566b84e, 0x150e7e23, 0x88ac97fa, 0xb540783e,
- 0xae7d694b, 0x7b08dc9f, 0x2059a6f9, 0x651440ee, 0x07d6883e, 0x425f833f,
- 0xaa37c6fe, 0x07ed79e4, 0x546fbe39, 0x67065cb1, 0x9be72e41, 0xb69fbf27,
- 0xe3514aaf, 0xd1ae9259, 0x8ba68b74, 0xe7716f86, 0x8524e9f0, 0xa8f45cf1,
- 0xc62eefc4, 0xb767e7ef, 0x198a9893, 0xc636fbff, 0xf86ffff3, 0xca7de2fd,
- 0xfbe373f7, 0xd3ed3afc, 0x77e7d86d, 0x93ed1ffe, 0xbcdfc0f5, 0x3ee361cf,
- 0xb142fad3, 0x8f37c073, 0x8acfd89b, 0x0a2a37be, 0x66d1eb04, 0x53c71c73,
- 0xddf271fd, 0xd3cfe901, 0xde9a9fd0, 0x2e175d9c, 0x4e71bf82, 0xaeb16788,
- 0xeb8869b0, 0x30e5562f, 0xc314ccdf, 0xc27efc99, 0x3f872e12, 0x35bfb66b,
- 0x4bb223f7, 0x0f048f03, 0xf4e34abf, 0x56a7c129, 0xeddd5f41, 0x95dcfce0,
- 0xa56029a0, 0x45920679, 0x7f9a31f1, 0xce5ccd60, 0xaa115cb3, 0xb1b06a9e,
- 0xecf6a29e, 0xca37b41e, 0xf9fdeff6, 0xa3f81ec2, 0xf782f923, 0xae225033,
- 0xc0f04bd9, 0xff6e0292, 0xf6e7a6a1, 0x97efc824, 0x8193e608, 0xef7c2935,
- 0x83a7e9e4, 0x0e8ec2d7, 0x11337a0c, 0xf44cab57, 0x19c74187, 0x079f6966,
- 0xe54f54dc, 0xb1af8a13, 0xc914e31d, 0xe31b86f5, 0x43403a5e, 0x2a91e6c5,
- 0x3d73faa5, 0xd5cf9c09, 0x638b47e4, 0x7f9c0ecf, 0xded2780a, 0xf2a07f23,
- 0xc5778699, 0xa667df2b, 0xe8d678aa, 0x6a5bf1a0, 0xa6cf7c9c, 0x377c916c,
- 0xbd791f7e, 0x33c8fbe0, 0x27782969, 0x71e31cd7, 0x4adfdf01, 0xfd618ff2,
- 0x3e881b7d, 0xd243ec66, 0x5bde1ce1, 0x997fe24e, 0x7e5a4dab, 0x3463df9f,
- 0x9a5fa90b, 0x3d17f7b5, 0x2217f7c6, 0xef19333c, 0xe89f9891, 0x3edd67fb,
- 0x5fbe355b, 0xd2fb65ee, 0xd9def2ac, 0x7a4f34ff, 0x5aa9286f, 0x623b95da,
- 0x9dfc89fd, 0xf3450efa, 0x7c96cfc3, 0xe4f60b3c, 0xcc6f83dc, 0xa2577944,
- 0xf69ab92f, 0x1fe344f3, 0x7dc4c316, 0xf7e61990, 0xfe341f34, 0xe5c71671,
- 0xfcc1bcb7, 0x57aeb7ff, 0x01ffc75b, 0x0934e170, 0x000048d0
-};
-
-#endif /*__BNX2X_INIT_VALUES_H__*/
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
deleted file mode 100644
index 4ce7fe9c525..00000000000
--- a/drivers/net/bnx2x_link.c
+++ /dev/null
@@ -1,4878 +0,0 @@
-/* Copyright 2008 Broadcom Corporation
- *
- * Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2, available
- * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a
- * license other than the GPL, without Broadcom's express prior written
- * consent.
- *
- * Written by Yaniv Rosner
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-#include <linux/ethtool.h>
-#include <linux/mutex.h>
-
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
-#include "bnx2x.h"
-
-/********************************************************/
-#define SUPPORT_CL73 0 /* Currently no */
-#define ETH_HLEN 14
-#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
-#define ETH_MIN_PACKET_SIZE 60
-#define ETH_MAX_PACKET_SIZE 1500
-#define ETH_MAX_JUMBO_PACKET_SIZE 9600
-#define MDIO_ACCESS_TIMEOUT 1000
-#define BMAC_CONTROL_RX_ENABLE 2
-
-/***********************************************************/
-/* Shortcut definitions */
-/***********************************************************/
-
-#define NIG_STATUS_XGXS0_LINK10G \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
-#define NIG_STATUS_XGXS0_LINK_STATUS \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
-#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
-#define NIG_STATUS_SERDES0_LINK_STATUS \
- NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
-#define NIG_MASK_MI_INT \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
-#define NIG_MASK_XGXS0_LINK10G \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
-#define NIG_MASK_XGXS0_LINK_STATUS \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
-#define NIG_MASK_SERDES0_LINK_STATUS \
- NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
-
-#define MDIO_AN_CL73_OR_37_COMPLETE \
- (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
- MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
-
-#define XGXS_RESET_BITS \
- (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
-
-#define SERDES_RESET_BITS \
- (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
- MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
-
-#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
-#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
-#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
-#define AUTONEG_PARALLEL \
- SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
-#define AUTONEG_SGMII_FIBER_AUTODET \
- SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
-#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
-
-#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
- MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
-#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
- MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
-#define GP_STATUS_SPEED_MASK \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
-#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
-#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
-#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
-#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
-#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
-#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
-#define GP_STATUS_10G_HIG \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
-#define GP_STATUS_10G_CX4 \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
-#define GP_STATUS_12G_HIG \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
-#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
-#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
-#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
-#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
-#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
-#define GP_STATUS_10G_KX4 \
- MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
-
-#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
-#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
-#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
-#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
-#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
-#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
-#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
-#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
-#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
-#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
-#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
-#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
-#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
-#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
-#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
-#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
-#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
-#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
-#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
-#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
-#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
-#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
-#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
-
-#define PHY_XGXS_FLAG 0x1
-#define PHY_SGMII_FLAG 0x2
-#define PHY_SERDES_FLAG 0x4
-
-/**********************************************************/
-/* INTERFACE */
-/**********************************************************/
-#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
- bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
- DEFAULT_PHY_DEV_ADDR, \
- (_bank + (_addr & 0xf)), \
- _val)
-
-#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
- bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
- DEFAULT_PHY_DEV_ADDR, \
- (_bank + (_addr & 0xf)), \
- _val)
-
-static void bnx2x_set_phy_mdio(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
- params->port*0x18, 0);
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
- DEFAULT_PHY_DEV_ADDR);
-}
-
-static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
-{
- u32 val = REG_RD(bp, reg);
-
- val |= bits;
- REG_WR(bp, reg, val);
- return val;
-}
-
-static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
-{
- u32 val = REG_RD(bp, reg);
-
- val &= ~bits;
- REG_WR(bp, reg, val);
- return val;
-}
-
-static void bnx2x_emac_init(struct link_params *params,
- struct link_vars *vars)
-{
- /* reset and unreset the emac core */
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val;
- u16 timeout;
-
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
- udelay(5);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
-
- /* init emac - use read-modify-write */
- /* self clear reset */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
-
- timeout = 200;
- do {
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
- if (!timeout) {
- DP(NETIF_MSG_LINK, "EMAC timeout!\n");
- return;
- }
- timeout--;
- } while (val & EMAC_MODE_RESET);
-
- /* Set mac address */
- val = ((params->mac_addr[0] << 8) |
- params->mac_addr[1]);
- EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
-
- val = ((params->mac_addr[2] << 24) |
- (params->mac_addr[3] << 16) |
- (params->mac_addr[4] << 8) |
- params->mac_addr[5]);
- EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
-}
-
-static u8 bnx2x_emac_enable(struct link_params *params,
- struct link_vars *vars, u8 lb)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u32 val;
-
- DP(NETIF_MSG_LINK, "enabling EMAC\n");
-
- /* enable emac and not bmac */
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
-
- /* for paladium */
- if (CHIP_REV_IS_EMUL(bp)) {
- /* Use lane 1 (of lanes 0-3) */
- REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
- port*4, 1);
- }
- /* for fpga */
- else
-
- if (CHIP_REV_IS_FPGA(bp)) {
- /* Use lane 1 (of lanes 0-3) */
- DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
-
- REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
- 0);
- } else
- /* ASIC */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- u32 ser_lane = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
-
- DP(NETIF_MSG_LINK, "XGXS\n");
- /* select the master lanes (out of 0-3) */
- REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
- port*4, ser_lane);
- /* select XGXS */
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
- port*4, 1);
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes\n");
- /* select SerDes */
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
- port*4, 0);
- }
-
- /* enable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
-
- if (CHIP_REV_IS_SLOW(bp)) {
- /* config GMII mode */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- EMAC_WR(bp, EMAC_REG_EMAC_MODE,
- (val | EMAC_MODE_PORT_GMII));
- } else { /* ASIC */
- /* pause enable/disable */
- bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
- EMAC_RX_MODE_FLOW_EN);
- if (vars->flow_ctrl & FLOW_CTRL_RX)
- bnx2x_bits_en(bp, emac_base +
- EMAC_REG_EMAC_RX_MODE,
- EMAC_RX_MODE_FLOW_EN);
-
- bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
- (EMAC_TX_MODE_EXT_PAUSE_EN |
- EMAC_TX_MODE_FLOW_EN));
- if (vars->flow_ctrl & FLOW_CTRL_TX)
- bnx2x_bits_en(bp, emac_base +
- EMAC_REG_EMAC_TX_MODE,
- (EMAC_TX_MODE_EXT_PAUSE_EN |
- EMAC_TX_MODE_FLOW_EN));
- }
-
- /* KEEP_VLAN_TAG, promiscuous */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
- val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
- EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
-
- /* Set Loopback */
- val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
- if (lb)
- val |= 0x810;
- else
- val &= ~0x810;
- EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
-
- /* enable emac for jumbo packets */
- EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
- (EMAC_RX_MTU_SIZE_JUMBO_ENA |
- (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
-
- /* strip CRC */
- REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
-
- /* disable the NIG in/out to the bmac */
- REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
-
- /* enable the NIG in/out to the emac */
- REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
- val = 0;
- if (vars->flow_ctrl & FLOW_CTRL_TX)
- val = 1;
-
- REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
-
- if (CHIP_REV_IS_EMUL(bp)) {
- /* take the BigMac out of reset */
- REG_WR(bp,
- GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* enable access for bmac registers */
- REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
- }
-
- vars->mac_type = MAC_TYPE_EMAC;
- return 0;
-}
-
-
-
-static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
- u8 is_lb)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
- NIG_REG_INGRESS_BMAC0_MEM;
- u32 wb_data[2];
- u32 val;
-
- DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
- /* reset and unreset the BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- msleep(1);
-
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* enable access for bmac registers */
- REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
-
- /* XGXS control */
- wb_data[0] = 0x3c;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr +
- BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
- wb_data, 2);
-
- /* tx MAC SA */
- wb_data[0] = ((params->mac_addr[2] << 24) |
- (params->mac_addr[3] << 16) |
- (params->mac_addr[4] << 8) |
- params->mac_addr[5]);
- wb_data[1] = ((params->mac_addr[0] << 8) |
- params->mac_addr[1]);
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
- wb_data, 2);
-
- /* tx control */
- val = 0xc0;
- if (vars->flow_ctrl & FLOW_CTRL_TX)
- val |= 0x800000;
- wb_data[0] = val;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
- wb_data, 2);
-
- /* mac control */
- val = 0x3;
- if (is_lb) {
- val |= 0x4;
- DP(NETIF_MSG_LINK, "enable bmac loopback\n");
- }
- wb_data[0] = val;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
- wb_data, 2);
-
-
- /* set rx mtu */
- wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
- wb_data, 2);
-
- /* rx control set to don't strip crc */
- val = 0x14;
- if (vars->flow_ctrl & FLOW_CTRL_RX)
- val |= 0x20;
- wb_data[0] = val;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
- wb_data, 2);
-
- /* set tx mtu */
- wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
- wb_data, 2);
-
- /* set cnt max size */
- wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
- wb_data, 2);
-
- /* configure safc */
- wb_data[0] = 0x1000200;
- wb_data[1] = 0;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
- wb_data, 2);
- /* fix for emulation */
- if (CHIP_REV_IS_EMUL(bp)) {
- wb_data[0] = 0xf000;
- wb_data[1] = 0;
- REG_WR_DMAE(bp,
- bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
- wb_data, 2);
- }
-
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
- REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
- val = 0;
- if (vars->flow_ctrl & FLOW_CTRL_TX)
- val = 1;
- REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
- REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
- REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
-
- vars->mac_type = MAC_TYPE_BMAC;
- return 0;
-}
-
-static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
-{
- struct bnx2x *bp = params->bp;
- u32 val;
-
- if (phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
- val = XGXS_RESET_BITS;
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
- val = SERDES_RESET_BITS;
- }
-
- val = val << (params->port*16);
-
- /* reset and unreset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
- val);
- udelay(500);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
- val);
- bnx2x_set_phy_mdio(params);
-}
-
-void bnx2x_link_status_update(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 link_10g;
- u8 port = params->port;
-
- if (params->switch_cfg == SWITCH_CFG_1G)
- vars->phy_flags = PHY_SERDES_FLAG;
- else
- vars->phy_flags = PHY_XGXS_FLAG;
- vars->link_status = REG_RD(bp, params->shmem_base +
- offsetof(struct shmem_region,
- port_mb[port].link_status));
-
- vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
-
- if (vars->link_up) {
- DP(NETIF_MSG_LINK, "phy link up\n");
-
- vars->phy_link_up = 1;
- vars->duplex = DUPLEX_FULL;
- switch (vars->link_status &
- LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
- case LINK_10THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_10TFD:
- vars->line_speed = SPEED_10;
- break;
-
- case LINK_100TXHD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_100T4:
- case LINK_100TXFD:
- vars->line_speed = SPEED_100;
- break;
-
- case LINK_1000THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_1000TFD:
- vars->line_speed = SPEED_1000;
- break;
-
- case LINK_2500THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_2500TFD:
- vars->line_speed = SPEED_2500;
- break;
-
- case LINK_10GTFD:
- vars->line_speed = SPEED_10000;
- break;
-
- case LINK_12GTFD:
- vars->line_speed = SPEED_12000;
- break;
-
- case LINK_12_5GTFD:
- vars->line_speed = SPEED_12500;
- break;
-
- case LINK_13GTFD:
- vars->line_speed = SPEED_13000;
- break;
-
- case LINK_15GTFD:
- vars->line_speed = SPEED_15000;
- break;
-
- case LINK_16GTFD:
- vars->line_speed = SPEED_16000;
- break;
-
- default:
- break;
- }
-
- if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
- vars->flow_ctrl |= FLOW_CTRL_TX;
- else
- vars->flow_ctrl &= ~FLOW_CTRL_TX;
-
- if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
- vars->flow_ctrl |= FLOW_CTRL_RX;
- else
- vars->flow_ctrl &= ~FLOW_CTRL_RX;
-
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- if (vars->line_speed &&
- ((vars->line_speed == SPEED_10) ||
- (vars->line_speed == SPEED_100))) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- } else {
- vars->phy_flags &= ~PHY_SGMII_FLAG;
- }
- }
-
- /* anything 10 and over uses the bmac */
- link_10g = ((vars->line_speed == SPEED_10000) ||
- (vars->line_speed == SPEED_12000) ||
- (vars->line_speed == SPEED_12500) ||
- (vars->line_speed == SPEED_13000) ||
- (vars->line_speed == SPEED_15000) ||
- (vars->line_speed == SPEED_16000));
- if (link_10g)
- vars->mac_type = MAC_TYPE_BMAC;
- else
- vars->mac_type = MAC_TYPE_EMAC;
-
- } else { /* link down */
- DP(NETIF_MSG_LINK, "phy link down\n");
-
- vars->phy_link_up = 0;
-
- vars->line_speed = 0;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
-
- /* indicate no mac active */
- vars->mac_type = MAC_TYPE_NONE;
- }
-
- DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
- vars->link_status, vars->phy_link_up);
- DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
- vars->line_speed, vars->duplex, vars->flow_ctrl);
-}
-
-static void bnx2x_update_mng(struct link_params *params, u32 link_status)
-{
- struct bnx2x *bp = params->bp;
- REG_WR(bp, params->shmem_base +
- offsetof(struct shmem_region,
- port_mb[params->port].link_status),
- link_status);
-}
-
-static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
-{
- u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
- NIG_REG_INGRESS_BMAC0_MEM;
- u32 wb_data[2];
- u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
-
- /* Only if the bmac is out of reset */
- if (REG_RD(bp, MISC_REG_RESET_REG_2) &
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
- nig_bmac_enable) {
-
- /* Clear Rx Enable bit in BMAC_CONTROL register */
- REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
- wb_data, 2);
- wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
- REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
- wb_data, 2);
-
- msleep(1);
- }
-}
-
-static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
- u32 line_speed)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u32 init_crd, crd;
- u32 count = 1000;
-
- /* disable port */
- REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
-
- /* wait for init credit */
- init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
- crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
- DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
-
- while ((init_crd != crd) && count) {
- msleep(5);
-
- crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
- count--;
- }
- crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
- if (init_crd != crd) {
- DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
- init_crd, crd);
- return -EINVAL;
- }
-
- if (flow_ctrl & FLOW_CTRL_RX ||
- line_speed == SPEED_10 ||
- line_speed == SPEED_100 ||
- line_speed == SPEED_1000 ||
- line_speed == SPEED_2500) {
- REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
- /* update threshold */
- REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
- /* update init credit */
- init_crd = 778; /* (800-18-4) */
-
- } else {
- u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
- ETH_OVREHEAD)/16;
- REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
- /* update threshold */
- REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
- /* update init credit */
- switch (line_speed) {
- case SPEED_10000:
- init_crd = thresh + 553 - 22;
- break;
-
- case SPEED_12000:
- init_crd = thresh + 664 - 22;
- break;
-
- case SPEED_13000:
- init_crd = thresh + 742 - 22;
- break;
-
- case SPEED_16000:
- init_crd = thresh + 778 - 22;
- break;
- default:
- DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
- line_speed);
- return -EINVAL;
- break;
- }
- }
- REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
- DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
- line_speed, init_crd);
-
- /* probe the credit changes */
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
- msleep(5);
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
-
- /* enable port */
- REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
- return 0;
-}
-
-static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
-{
- u32 emac_base;
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- emac_base = GRCBASE_EMAC0;
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
- break;
- default:
- emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- break;
- }
- return emac_base;
-
-}
-
-u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 val)
-{
- u32 tmp, saved_mode;
- u8 i, rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
-
- /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
- * (a value of 49==0x31) and make sure that the AUTO poll is off
- */
- saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
- EMAC_MDIO_MODE_CLOCK_CNT);
- tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
-
- /* address */
-
- tmp = ((phy_addr << 21) | (devad << 16) | reg |
- EMAC_MDIO_COMM_COMMAND_ADDRESS |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- DP(NETIF_MSG_LINK, "write phy register failed\n");
- rc = -EFAULT;
- } else {
- /* data */
- tmp = ((phy_addr << 21) | (devad << 16) | val |
- EMAC_MDIO_COMM_COMMAND_WRITE_45 |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- tmp = REG_RD(bp, mdio_ctrl +
- EMAC_REG_EMAC_MDIO_COMM);
- if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
- if (tmp & EMAC_MDIO_COMM_START_BUSY) {
- DP(NETIF_MSG_LINK, "write phy register failed\n");
- rc = -EFAULT;
- }
- }
-
- /* Restore the saved mode */
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
-
- return rc;
-}
-
-u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
-{
- u32 val, saved_mode;
- u16 i;
- u8 rc = 0;
-
- u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
- /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
- * (a value of 49==0x31) and make sure that the AUTO poll is off
- */
- saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
- EMAC_MDIO_MODE_CLOCK_CNT));
- val |= (EMAC_MDIO_MODE_CLAUSE_45 |
- (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
- REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
- udelay(40);
-
- /* address */
- val = ((phy_addr << 21) | (devad << 16) | reg |
- EMAC_MDIO_COMM_COMMAND_ADDRESS |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- udelay(5);
- break;
- }
- }
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- DP(NETIF_MSG_LINK, "read phy register failed\n");
-
- *ret_val = 0;
- rc = -EFAULT;
-
- } else {
- /* data */
- val = ((phy_addr << 21) | (devad << 16) |
- EMAC_MDIO_COMM_COMMAND_READ_45 |
- EMAC_MDIO_COMM_START_BUSY);
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
-
- for (i = 0; i < 50; i++) {
- udelay(10);
-
- val = REG_RD(bp, mdio_ctrl +
- EMAC_REG_EMAC_MDIO_COMM);
- if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
- *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
- break;
- }
- }
- if (val & EMAC_MDIO_COMM_START_BUSY) {
- DP(NETIF_MSG_LINK, "read phy register failed\n");
-
- *ret_val = 0;
- rc = -EFAULT;
- }
- }
-
- /* Restore the saved mode */
- REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
-
- return rc;
-}
-
-static void bnx2x_set_aer_mmd(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u32 ser_lane;
- u16 offset;
-
- ser_lane = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
-
- offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
- (params->phy_addr + ser_lane) : 0;
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_AER_BLOCK,
- MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
-}
-
-static void bnx2x_set_master_ln(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u16 new_master_ln, ser_lane;
- ser_lane = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
-
- /* set the master_ln for AN */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_XGXS_BLOCK2,
- MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
- &new_master_ln);
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_XGXS_BLOCK2 ,
- MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
- (new_master_ln | ser_lane));
-}
-
-static u8 bnx2x_reset_unicore(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u16 mii_control;
- u16 i;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
-
- /* reset the unicore */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_RESET));
-
- /* wait for the reset to self clear */
- for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
- udelay(5);
-
- /* the reset erased the previous bank value */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
-
- if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
- udelay(5);
- return 0;
- }
- }
-
- DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
- return -EINVAL;
-
-}
-
-static void bnx2x_set_swap_lanes(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- /* Each two bits represents a lane number:
- No swap is 0123 => 0x1b no need to enable the swap */
- u16 ser_lane, rx_lane_swap, tx_lane_swap;
-
- ser_lane = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
- rx_lane_swap = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
- tx_lane_swap = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
-
- if (rx_lane_swap != 0x1b) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_XGXS_BLOCK2,
- MDIO_XGXS_BLOCK2_RX_LN_SWAP,
- (rx_lane_swap |
- MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
- MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
- } else {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_XGXS_BLOCK2,
- MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
- }
-
- if (tx_lane_swap != 0x1b) {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_XGXS_BLOCK2,
- MDIO_XGXS_BLOCK2_TX_LN_SWAP,
- (tx_lane_swap |
- MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
- } else {
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_XGXS_BLOCK2,
- MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
- }
-}
-
-static void bnx2x_set_parallel_detection(struct link_params *params,
- u8 phy_flags)
-{
- struct bnx2x *bp = params->bp;
- u16 control2;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
- &control2);
-
-
- control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
-
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
- control2);
-
- if (phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_10G_PARALLEL_DETECT,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_10G_PARALLEL_DETECT,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- &control2);
-
-
- control2 |=
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_10G_PARALLEL_DETECT,
- MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
- control2);
-
- /* Disable parallel detection of HiG */
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_XGXS_BLOCK2,
- MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
- MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
- MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
- }
-}
-
-static void bnx2x_set_autoneg(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u16 reg_val;
-
- /* CL37 Autoneg */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
-
- /* CL37 Autoneg Enabled */
- if (vars->line_speed == SPEED_AUTO_NEG)
- reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
- else /* CL37 Autoneg Disabled */
- reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
-
- /* Enable/Disable Autodetection */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
- reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
- if (vars->line_speed == SPEED_AUTO_NEG)
- reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
- else
- reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
-
- /* Enable TetonII and BAM autoneg */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_BAM_NEXT_PAGE,
- MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
- &reg_val);
- if (vars->line_speed == SPEED_AUTO_NEG) {
- /* Enable BAM aneg Mode and TetonII aneg Mode */
- reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
- MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
- } else {
- /* TetonII and BAM Autoneg Disabled */
- reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
- MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
- }
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_BAM_NEXT_PAGE,
- MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
- reg_val);
-
- /* Enable Clause 73 Aneg */
- if ((vars->line_speed == SPEED_AUTO_NEG) &&
- (SUPPORT_CL73)) {
- /* Enable BAM Station Manager */
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL1,
- (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
-
- /* Merge CL73 and CL37 aneg resolution */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- &reg_val);
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- (reg_val |
- MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
-
- /* Set the CL73 AN speed */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB1,
- MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
- /* In the SerDes we support only the 1G.
- In the XGXS we support the 10G KX4
- but we currently do not support the KR */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
- /* 10G KX4 */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
- } else {
- DP(NETIF_MSG_LINK, "SerDes\n");
- /* 1000M KX */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
- }
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB1,
- MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
-
- /* CL73 Autoneg Enabled */
- reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
- } else {
- /* CL73 Autoneg Disabled */
- reg_val = 0;
- }
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB0,
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
-}
-
-/* program SerDes, forced speed */
-static void bnx2x_program_serdes(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u16 reg_val;
-
- /* program duplex, disable autoneg */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
- reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
- MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
- if (params->req_duplex == DUPLEX_FULL)
- reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
-
- /* program speed
- - needed only if the speed is greater than 1G (2.5G or 10G) */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_MISC1, &reg_val);
- /* clearing the speed value before setting the right speed */
- DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
-
- reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
- MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
-
- if (!((vars->line_speed == SPEED_1000) ||
- (vars->line_speed == SPEED_100) ||
- (vars->line_speed == SPEED_10))) {
-
- reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
- MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
- if (vars->line_speed == SPEED_10000)
- reg_val |=
- MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
- if (vars->line_speed == SPEED_13000)
- reg_val |=
- MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
- }
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_MISC1, reg_val);
-
-}
-
-static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u16 val = 0;
-
- /* configure the 48 bits for BAM AN */
-
- /* set extended capabilities */
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
- val |= MDIO_OVER_1G_UP1_2_5G;
- if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
- val |= MDIO_OVER_1G_UP1_10G;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_OVER_1G,
- MDIO_OVER_1G_UP1, val);
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_OVER_1G,
- MDIO_OVER_1G_UP3, 0);
-}
-
-static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
-{
- *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
- /* resolve pause mode and advertisement
- * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
-
- switch (params->req_flow_ctrl) {
- case FLOW_CTRL_AUTO:
- if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) {
- *ieee_fc |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- } else {
- *ieee_fc |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- }
- break;
- case FLOW_CTRL_TX:
- *ieee_fc |=
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- break;
-
- case FLOW_CTRL_RX:
- case FLOW_CTRL_BOTH:
- *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- break;
-
- case FLOW_CTRL_NONE:
- default:
- *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
- break;
- }
-}
-
-static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
- u32 ieee_fc)
-{
- struct bnx2x *bp = params->bp;
- /* for AN, we are always publishing full duplex */
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
-}
-
-static void bnx2x_restart_autoneg(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
- if (SUPPORT_CL73) {
- /* enable and restart clause 73 aneg */
- u16 an_ctrl;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB0,
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- &an_ctrl);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB0,
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- (an_ctrl |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
-
- } else {
- /* Enable and restart BAM/CL37 aneg */
- u16 mii_control;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
- DP(NETIF_MSG_LINK,
- "bnx2x_restart_autoneg mii_control before = 0x%x\n",
- mii_control);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
- }
-}
-
-static void bnx2x_initialize_sgmii_process(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u16 control1;
-
- /* in SGMII mode, the unicore is always slave */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
- &control1);
- control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
- /* set sgmii mode (and not fiber) */
- control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_SERDES_DIGITAL,
- MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
- control1);
-
- /* if forced speed */
- if (!(vars->line_speed == SPEED_AUTO_NEG)) {
- /* set speed, disable autoneg */
- u16 mii_control;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
- mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
- MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
-
- switch (vars->line_speed) {
- case SPEED_100:
- mii_control |=
- MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
- break;
- case SPEED_1000:
- mii_control |=
- MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
- break;
- case SPEED_10:
- /* there is nothing to set for 10M */
- break;
- default:
- /* invalid speed for SGMII */
- DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
- vars->line_speed);
- break;
- }
-
- /* setting the full duplex */
- if (params->req_duplex == DUPLEX_FULL)
- mii_control |=
- MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- mii_control);
-
- } else { /* AN mode */
- /* enable and restart AN */
- bnx2x_restart_autoneg(params);
- }
-}
-
-
-/*
- * link management
- */
-
-static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
-{ /* LD LP */
- switch (pause_result) { /* ASYM P ASYM P */
- case 0xb: /* 1 0 1 1 */
- vars->flow_ctrl = FLOW_CTRL_TX;
- break;
-
- case 0xe: /* 1 1 1 0 */
- vars->flow_ctrl = FLOW_CTRL_RX;
- break;
-
- case 0x5: /* 0 1 0 1 */
- case 0x7: /* 0 1 1 1 */
- case 0xd: /* 1 1 0 1 */
- case 0xf: /* 1 1 1 1 */
- vars->flow_ctrl = FLOW_CTRL_BOTH;
- break;
-
- default:
- break;
- }
-}
-
-static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr;
- u16 ld_pause; /* local */
- u16 lp_pause; /* link partner */
- u16 an_complete; /* AN complete */
- u16 pause_result;
- u8 ret = 0;
- u32 ext_phy_type;
- u8 port = params->port;
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* read twice */
-
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_STATUS, &an_complete);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_STATUS, &an_complete);
-
- if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
- ret = 1;
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, &ld_pause);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
- pause_result = (ld_pause &
- MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
- pause_result |= (lp_pause &
- MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
- DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
- pause_result);
- bnx2x_pause_resolve(vars, pause_result);
- if (vars->flow_ctrl == FLOW_CTRL_NONE &&
- ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, &ld_pause);
-
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LP, &lp_pause);
- pause_result = (ld_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
- pause_result |= (lp_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
-
- bnx2x_pause_resolve(vars, pause_result);
- DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
- pause_result);
- }
- }
- return ret;
-}
-
-
-static void bnx2x_flow_ctrl_resolve(struct link_params *params,
- struct link_vars *vars,
- u32 gp_status)
-{
- struct bnx2x *bp = params->bp;
- u16 ld_pause; /* local driver */
- u16 lp_pause; /* link partner */
- u16 pause_result;
-
- vars->flow_ctrl = FLOW_CTRL_NONE;
-
- /* resolve from gp_status in case of AN complete and not sgmii */
- if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
- (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
- (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
- &ld_pause);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
- &lp_pause);
- pause_result = (ld_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
- pause_result |= (lp_pause &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
- DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
- bnx2x_pause_resolve(vars, pause_result);
- } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
- (bnx2x_ext_phy_resove_fc(params, vars))) {
- return;
- } else {
- if (params->req_flow_ctrl == FLOW_CTRL_AUTO)
- vars->flow_ctrl = params->req_fc_auto_adv;
- else
- vars->flow_ctrl = params->req_flow_ctrl;
- }
- DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
-}
-
-
-static u8 bnx2x_link_settings_status(struct link_params *params,
- struct link_vars *vars,
- u32 gp_status)
-{
- struct bnx2x *bp = params->bp;
-
- u8 rc = 0;
- vars->link_status = 0;
-
- if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
- DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
- gp_status);
-
- vars->phy_link_up = 1;
- vars->link_status |= LINK_STATUS_LINK_UP;
-
- if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
- vars->duplex = DUPLEX_FULL;
- else
- vars->duplex = DUPLEX_HALF;
-
- bnx2x_flow_ctrl_resolve(params, vars, gp_status);
-
- switch (gp_status & GP_STATUS_SPEED_MASK) {
- case GP_STATUS_10M:
- vars->line_speed = SPEED_10;
- if (vars->duplex == DUPLEX_FULL)
- vars->link_status |= LINK_10TFD;
- else
- vars->link_status |= LINK_10THD;
- break;
-
- case GP_STATUS_100M:
- vars->line_speed = SPEED_100;
- if (vars->duplex == DUPLEX_FULL)
- vars->link_status |= LINK_100TXFD;
- else
- vars->link_status |= LINK_100TXHD;
- break;
-
- case GP_STATUS_1G:
- case GP_STATUS_1G_KX:
- vars->line_speed = SPEED_1000;
- if (vars->duplex == DUPLEX_FULL)
- vars->link_status |= LINK_1000TFD;
- else
- vars->link_status |= LINK_1000THD;
- break;
-
- case GP_STATUS_2_5G:
- vars->line_speed = SPEED_2500;
- if (vars->duplex == DUPLEX_FULL)
- vars->link_status |= LINK_2500TFD;
- else
- vars->link_status |= LINK_2500THD;
- break;
-
- case GP_STATUS_5G:
- case GP_STATUS_6G:
- DP(NETIF_MSG_LINK,
- "link speed unsupported gp_status 0x%x\n",
- gp_status);
- return -EINVAL;
- break;
- case GP_STATUS_10G_KX4:
- case GP_STATUS_10G_HIG:
- case GP_STATUS_10G_CX4:
- vars->line_speed = SPEED_10000;
- vars->link_status |= LINK_10GTFD;
- break;
-
- case GP_STATUS_12G_HIG:
- vars->line_speed = SPEED_12000;
- vars->link_status |= LINK_12GTFD;
- break;
-
- case GP_STATUS_12_5G:
- vars->line_speed = SPEED_12500;
- vars->link_status |= LINK_12_5GTFD;
- break;
-
- case GP_STATUS_13G:
- vars->line_speed = SPEED_13000;
- vars->link_status |= LINK_13GTFD;
- break;
-
- case GP_STATUS_15G:
- vars->line_speed = SPEED_15000;
- vars->link_status |= LINK_15GTFD;
- break;
-
- case GP_STATUS_16G:
- vars->line_speed = SPEED_16000;
- vars->link_status |= LINK_16GTFD;
- break;
-
- default:
- DP(NETIF_MSG_LINK,
- "link speed unsupported gp_status 0x%x\n",
- gp_status);
- return -EINVAL;
- break;
- }
-
- vars->link_status |= LINK_STATUS_SERDES_LINK;
-
- if ((params->req_line_speed == SPEED_AUTO_NEG) &&
- ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
- vars->autoneg = AUTO_NEG_ENABLED;
-
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
- vars->autoneg |= AUTO_NEG_COMPLETE;
- vars->link_status |=
- LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
- }
-
- vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
- vars->link_status |=
- LINK_STATUS_PARALLEL_DETECTION_USED;
-
- }
- if (vars->flow_ctrl & FLOW_CTRL_TX)
- vars->link_status |=
- LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
-
- if (vars->flow_ctrl & FLOW_CTRL_RX)
- vars->link_status |=
- LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
-
- } else { /* link_down */
- DP(NETIF_MSG_LINK, "phy link down\n");
-
- vars->phy_link_up = 0;
-
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
- vars->autoneg = AUTO_NEG_DISABLED;
- vars->mac_type = MAC_TYPE_NONE;
- }
-
- DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
- gp_status, vars->phy_link_up, vars->line_speed);
- DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
- " autoneg 0x%x\n",
- vars->duplex,
- vars->flow_ctrl, vars->autoneg);
- DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
-
- return rc;
-}
-
-static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u16 lp_up2;
- u16 tx_driver;
-
- /* read precomp */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_OVER_1G,
- MDIO_OVER_1G_LP_UP2, &lp_up2);
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_TX0,
- MDIO_TX0_TX_DRIVER, &tx_driver);
-
- /* bits [10:7] at lp_up2, positioned at [15:12] */
- lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
- MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
- MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
-
- if ((lp_up2 != 0) &&
- (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
- /* replace tx_driver bits [15:12] */
- tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
- tx_driver |= lp_up2;
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_TX0,
- MDIO_TX0_TX_DRIVER, tx_driver);
- }
-}
-
-static u8 bnx2x_emac_program(struct link_params *params,
- u32 line_speed, u32 duplex)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u16 mode = 0;
-
- DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
- bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
- EMAC_REG_EMAC_MODE,
- (EMAC_MODE_25G_MODE |
- EMAC_MODE_PORT_MII_10M |
- EMAC_MODE_HALF_DUPLEX));
- switch (line_speed) {
- case SPEED_10:
- mode |= EMAC_MODE_PORT_MII_10M;
- break;
-
- case SPEED_100:
- mode |= EMAC_MODE_PORT_MII;
- break;
-
- case SPEED_1000:
- mode |= EMAC_MODE_PORT_GMII;
- break;
-
- case SPEED_2500:
- mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
- break;
-
- default:
- /* 10G not valid for EMAC */
- DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
- return -EINVAL;
- }
-
- if (duplex == DUPLEX_HALF)
- mode |= EMAC_MODE_HALF_DUPLEX;
- bnx2x_bits_en(bp,
- GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
- mode);
-
- bnx2x_set_led(bp, params->port, LED_MODE_OPER,
- line_speed, params->hw_led_mode, params->chip_id);
- return 0;
-}
-
-/*****************************************************************************/
-/* External Phy section */
-/*****************************************************************************/
-static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
-{
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- msleep(1);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
-}
-
-static void bnx2x_ext_phy_reset(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* The PHY reset is controled by GPIO 1
- * Give it 1ms of reset pulse
- */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
-
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
-
- /* HW reset */
- bnx2x_hw_reset(bp, params->port);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, 0xa040);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- /* Unset Low Power Mode and SW reset */
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
-
- DP(NETIF_MSG_LINK, "XGXS 8072\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- u16 emac_base;
- emac_base = (params->port) ? GRCBASE_EMAC0 :
- GRCBASE_EMAC1;
-
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
-
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
-
- DP(NETIF_MSG_LINK, "XGXS 8073\n");
- }
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
-
- /* Restore normal power mode*/
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH,
- params->port);
-
- /* HW reset */
- bnx2x_hw_reset(bp, params->port);
-
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- break;
- }
-
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- bnx2x_hw_reset(bp, params->port);
- break;
-
- default:
- DP(NETIF_MSG_LINK,
- "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
- break;
- }
- }
-}
-
-static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- u16 fw_ver1, fw_ver2;
-
- /* Need to wait 200ms after reset */
- msleep(200);
- /* Boot port from external ROM
- * Set ser_boot_ctl bit in the MISC_CTRL1 register
- */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
-
- /* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
- /* set micro reset = 0 */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
- /* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
- /* wait for 100ms for code download via SPI port */
- msleep(100);
-
- /* Clear ser_boot_ctl bit */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
- /* Wait 100ms */
- msleep(100);
-
- /* Print the PHY FW version */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
-}
-
-static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
-{
- /* This is only required for 8073A1, version 102 only */
-
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u16 val;
-
- /* Read 8073 HW revision*/
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc801, &val);
-
- if (val != 1) {
- /* No need to workaround in 8073 A1 */
- return 0;
- }
-
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &val);
-
- /* SNR should be applied only for version 0x102 */
- if (val != 0x102)
- return 0;
-
- return 1;
-}
-
-static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u16 val, cnt, cnt1 ;
-
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc801, &val);
-
- if (val > 0) {
- /* No need to workaround in 8073 A1 */
- return 0;
- }
- /* XAUI workaround in 8073 A0: */
-
- /* After loading the boot ROM and restarting Autoneg,
- poll Dev1, Reg $C820: */
-
- for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc820, &val);
- /* If bit [14] = 0 or bit [13] = 0, continue on with
- system initialization (XAUI work-around not required,
- as these bits indicate 2.5G or 1G link up). */
- if (!(val & (1<<14)) || !(val & (1<<13))) {
- DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
- return 0;
- } else if (!(val & (1<<15))) {
- DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
- /* If bit 15 is 0, then poll Dev1, Reg $C841 until
- it's MSB (bit 15) goes to 1 (indicating that the
- XAUI workaround has completed),
- then continue on with system initialization.*/
- for (cnt1 = 0; cnt1 < 1000; cnt1++) {
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc841, &val);
- if (val & (1<<15)) {
- DP(NETIF_MSG_LINK,
- "XAUI workaround has completed\n");
- return 0;
- }
- msleep(3);
- }
- break;
- }
- msleep(3);
- }
- DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
- return -EINVAL;
-
-}
-
-static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr)
-{
- u16 fw_ver1, fw_ver2;
- /* Boot port from external ROM */
- /* EDC grst */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x0001);
-
- /* ucode reboot and rst */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- 0x008c);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0001);
-
- /* Reset internal microprocessor */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
-
- /* Release srst bit */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_GEN_CTRL,
- MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
-
- /* wait for 100ms for code download via SPI port */
- msleep(100);
-
- /* Clear ser_boot_ctl bit */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL1, 0x0000);
-
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
-
-}
-
-static void bnx2x_bcm807x_force_10G(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Force KR or KX */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 0x2040);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_10G_CTRL2,
- 0x000b);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_BCM_CTRL,
- 0x0000);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL,
- 0x0000);
-}
-static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u16 val;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc801, &val);
-
- if (val == 0) {
- /* Mustn't set low power mode in 8073 A0 */
- return;
- }
-
- /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_PLL_SEQUENCER, &val);
- val &= ~(1<<13);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
-
- /* PLL controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805E, 0x1077);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805D, 0x0000);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805C, 0x030B);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805B, 0x1240);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x805A, 0x2490);
-
- /* Tx Controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A7, 0x0C74);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A6, 0x9041);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80A5, 0x4640);
-
- /* Rx Controls */
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FE, 0x01C4);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FD, 0x9249);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, 0x80FC, 0x2015);
-
- /* Enable PLL sequencer (use read-modify-write to set bit 13) */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_PLL_SEQUENCER, &val);
- val |= (1<<13);
- bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
-}
-
-static void bnx2x_8073_set_pause_cl37(struct link_params *params,
- struct link_vars *vars)
-{
-
- struct bnx2x *bp = params->bp;
- u16 cl37_val;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, &cl37_val);
-
- cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
-
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
- }
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
- }
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
- cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
- }
- DP(NETIF_MSG_LINK,
- "Ext phy AN advertize cl37 0x%x\n", cl37_val);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, cl37_val);
- msleep(500);
-}
-
-static void bnx2x_ext_phy_set_pause(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u16 val;
- u8 ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* read modify write pause advertizing */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, &val);
-
- val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
-
- /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
-
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
- val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
- }
- if ((vars->ieee_fc &
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
- MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
- val |=
- MDIO_AN_REG_ADV_PAUSE_PAUSE;
- }
- DP(NETIF_MSG_LINK,
- "Ext phy AN advertize 0x%x\n", val);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV_PAUSE, val);
-}
-
-
-static void bnx2x_init_internal_phy(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
- u16 bank, rx_eq;
-
- rx_eq = ((params->serdes_config &
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
-
- DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
- for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
- bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
- CL45_WR_OVER_CL22(bp, port,
- params->phy_addr,
- bank ,
- MDIO_RX0_RX_EQ_BOOST,
- ((rx_eq &
- MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
- MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
- }
-
- /* forced speed requested? */
- if (vars->line_speed != SPEED_AUTO_NEG) {
- DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
-
- /* disable autoneg */
- bnx2x_set_autoneg(params, vars);
-
- /* program speed and duplex */
- bnx2x_program_serdes(params, vars);
-
- } else { /* AN_mode */
- DP(NETIF_MSG_LINK, "not SGMII, AN\n");
-
- /* AN enabled */
- bnx2x_set_brcm_cl37_advertisment(params);
-
- /* program duplex & pause advertisement (for aneg) */
- bnx2x_set_ieee_aneg_advertisment(params,
- vars->ieee_fc);
-
- /* enable autoneg */
- bnx2x_set_autoneg(params, vars);
-
- /* enable and restart AN */
- bnx2x_restart_autoneg(params);
- }
-
- } else { /* SGMII mode */
- DP(NETIF_MSG_LINK, "SGMII\n");
-
- bnx2x_initialize_sgmii_process(params, vars);
- }
-}
-
-static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- u16 cnt;
- u16 ctrl = 0;
- u16 val = 0;
- u8 rc = 0;
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* Make sure that the soft reset is off (expect for the 8072:
- * due to the lock, it will be done inside the specific
- * handling)
- */
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
- /* Wait for soft reset to get cleared upto 1 sec */
- for (cnt = 0; cnt < 1000; cnt++) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL, &ctrl);
- if (!(ctrl & (1<<15)))
- break;
- msleep(1);
- }
- DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
- ctrl, cnt);
- }
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_MISC_CTRL,
- 0x8288);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PHY_IDENTIFIER,
- 0x7fbf);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CMU_PLL_BYPASS,
- 0x0100);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_CNTL, 0x1);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
-
- msleep(10);
- /* Force speed */
- /* First enable LASI */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- 0x0400);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x0004);
-
- if (params->req_line_speed == SPEED_10000) {
- DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_DIGITAL_CTRL,
- 0x400);
- } else {
- /* Force 1Gbps using autoneg with 1G
- advertisment */
-
- /* Allow CL37 through CL73 */
- DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_CL73,
- 0x040c);
-
- /* Enable Full-Duplex advertisment on CL37 */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LP,
- 0x0020);
- /* Enable CL37 AN */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN,
- 0x1000);
- /* 1G support */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, (1<<5));
-
- /* Enable clause 73 AN */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL,
- 0x1200);
-
- }
-
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- u16 tmp1;
- u16 rx_alarm_ctrl_val;
- u16 lasi_ctrl_val;
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
- rx_alarm_ctrl_val = 0x400;
- lasi_ctrl_val = 0x0004;
- } else {
- rx_alarm_ctrl_val = (1<<2);
- lasi_ctrl_val = 0x0004;
- }
-
- /* enable LASI */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM_CTRL,
- rx_alarm_ctrl_val);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL,
- lasi_ctrl_val);
-
- bnx2x_8073_set_pause_cl37(params, vars);
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
- bnx2x_bcm8072_external_rom_boot(params);
- } else {
-
- /* In case of 8073 with long xaui lines,
- don't set the 8073 xaui low power*/
- bnx2x_bcm8073_set_xaui_low_power_mode(params);
- }
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xca13,
- &tmp1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &tmp1);
-
- DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
- "0x%x\n", tmp1);
-
- /* If this is forced speed, set to KR or KX
- * (all other are not supported)
- */
- if (params->loopback_mode == LOOPBACK_EXT) {
- bnx2x_bcm807x_force_10G(params);
- DP(NETIF_MSG_LINK,
- "Forced speed 10G on 807X\n");
- break;
- } else {
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_BCM_CTRL,
- 0x0002);
- }
- if (params->req_line_speed != SPEED_AUTO_NEG) {
- if (params->req_line_speed == SPEED_10000) {
- val = (1<<7);
- } else if (params->req_line_speed ==
- SPEED_2500) {
- val = (1<<5);
- /* Note that 2.5G works only
- when used with 1G advertisment */
- } else
- val = (1<<5);
- } else {
-
- val = 0;
- if (params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
- val |= (1<<7);
-
- /* Note that 2.5G works only when
- used with 1G advertisment */
- if (params->speed_cap_mask &
- (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- val |= (1<<5);
- DP(NETIF_MSG_LINK,
- "807x autoneg val = 0x%x\n", val);
- }
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV, val);
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8329, &tmp1);
-
- if (((params->speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
- (params->req_line_speed ==
- SPEED_AUTO_NEG)) ||
- (params->req_line_speed ==
- SPEED_2500)) {
- u16 phy_ver;
- /* Allow 2.5G for A1 and above */
- bnx2x_cl45_read(bp, params->port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc801, &phy_ver);
- DP(NETIF_MSG_LINK, "Add 2.5G\n");
- if (phy_ver > 0)
- tmp1 |= 1;
- else
- tmp1 &= 0xfffe;
- } else {
- DP(NETIF_MSG_LINK, "Disable 2.5G\n");
- tmp1 &= 0xfffe;
- }
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8329, tmp1);
- }
-
- /* Add support for CL37 (passive mode) II */
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD,
- &tmp1);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_FC_LD, (tmp1 |
- ((params->req_duplex == DUPLEX_FULL) ?
- 0x20 : 0x40)));
-
- /* Add support for CL37 (passive mode) III */
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CL37_AN, 0x1000);
-
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- /* The SNR will improve about 2db by changing
- BW and FEE main tap. Rest commands are executed
- after link is up*/
- /*Change FFE main cursor to 5 in EDC register*/
- if (bnx2x_8073_is_snr_needed(params))
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_EDC_FFE_MAIN,
- 0xFB0C);
-
- /* Enable FEC (Forware Error Correction)
- Request in the AN */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV2, &tmp1);
-
- tmp1 |= (1<<15);
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_ADV2, tmp1);
-
- }
-
- bnx2x_ext_phy_set_pause(params, vars);
-
- /* Restart autoneg */
- msleep(500);
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, 0x1200);
- DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
- "Advertise 1G=%x, 10G=%x\n",
- ((val & (1<<5)) > 0),
- ((val & (1<<7)) > 0));
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LASI indication\n");
-
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_CTRL, 0x1);
- DP(NETIF_MSG_LINK,
- "Setting the SFX7101 LED to blink on traffic\n");
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
-
- bnx2x_ext_phy_set_pause(params, vars);
- /* Restart autoneg */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, &val);
- val |= 0x200;
- bnx2x_cl45_write(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_CTRL, val);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK,
- "XGXS PHY Failure detected 0x%x\n",
- params->ext_phy_config);
- rc = -EINVAL;
- break;
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- rc = -EINVAL;
- break;
- }
-
- } else { /* SerDes */
-
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
- break;
- }
- }
- return rc;
-}
-
-
-static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- u16 val1 = 0, val2;
- u16 rx_sd, pcs_status;
- u8 ext_phy_link_up = 0;
- u8 port = params->port;
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "XGXS Direct\n");
- ext_phy_link_up = 1;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "XGXS 8705\n");
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_WIS_DEVAD,
- MDIO_WIS_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_SD, &rx_sd);
- DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
- ext_phy_link_up = (rx_sd & 0x1);
- if (ext_phy_link_up)
- vars->line_speed = SPEED_10000;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_SD, &rx_sd);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &pcs_status);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS, &val2);
-
- DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
- " pcs_status 0x%x 1Gbps link_status 0x%x\n",
- rx_sd, pcs_status, val2);
- /* link is up if both bit 0 of pmd_rx_sd and
- * bit 0 of pcs_status are set, or if the autoneg bit
- 1 is set
- */
- ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
- (val2 & (1<<1)));
- if (ext_phy_link_up) {
- if (val2 & (1<<1))
- vars->line_speed = SPEED_1000;
- else
- vars->line_speed = SPEED_10000;
- }
-
- /* clear LASI indication*/
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &val2);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- u16 link_status = 0;
- u16 an1000_status = 0;
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_LASI_STATUS, &val1);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_LASI_STATUS, &val2);
- DP(NETIF_MSG_LINK,
- "870x LASI status 0x%x->0x%x\n",
- val1, val2);
-
- } else {
- /* In 8073, port1 is directed through emac0 and
- * port0 is directed through emac1
- */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
-
- DP(NETIF_MSG_LINK,
- "8703 LASI status 0x%x\n",
- val1);
- }
-
- /* clear the interrupt LASI status register */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
- val2, val1);
- /* Clear MSG-OUT */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xca13,
- &val1);
-
- /* Check the LASI */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &val2);
-
- DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
-
- /* Check the link status */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &val2);
- DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- ext_phy_link_up = ((val1 & 4) == 4);
- DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
- if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
-
- if (ext_phy_link_up &&
- ((params->req_line_speed !=
- SPEED_10000))) {
- if (bnx2x_bcm8073_xaui_wa(params)
- != 0) {
- ext_phy_link_up = 0;
- break;
- }
- }
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
-
- /* Check the link status on 1.1.2 */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
- "an_link_status=0x%x\n",
- val2, val1, an1000_status);
-
- ext_phy_link_up = (((val1 & 4) == 4) ||
- (an1000_status & (1<<1)));
- if (ext_phy_link_up &&
- bnx2x_8073_is_snr_needed(params)) {
- /* The SNR will improve about 2dbby
- changing the BW and FEE main tap.*/
-
- /* The 1st write to change FFE main
- tap is set before restart AN */
- /* Change PLL Bandwidth in EDC
- register */
- bnx2x_cl45_write(bp, port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_PLL_BANDWIDTH,
- 0x26BC);
-
- /* Change CDR Bandwidth in EDC
- register */
- bnx2x_cl45_write(bp, port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CDR_BANDWIDTH,
- 0x0333);
-
-
- }
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc820,
- &link_status);
-
- /* Bits 0..2 --> speed detected,
- bits 13..15--> link is down */
- if ((link_status & (1<<2)) &&
- (!(link_status & (1<<15)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 10G\n", params->port);
- } else if ((link_status & (1<<1)) &&
- (!(link_status & (1<<14)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_2500;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 2.5G\n", params->port);
- } else if ((link_status & (1<<0)) &&
- (!(link_status & (1<<13)))) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else {
- ext_phy_link_up = 0;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " is down\n", params->port);
- }
- } else {
- /* See if 1G link is up for the 8072 */
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
- if (an1000_status & (1<<1)) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_1000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 1G\n", params->port);
- } else if (ext_phy_link_up) {
- ext_phy_link_up = 1;
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "port %x: External link"
- " up in 10G\n", params->port);
- }
- }
-
-
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T LASI status 0x%x->0x%x\n",
- val2, val1);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val2);
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_STATUS, &val1);
- DP(NETIF_MSG_LINK,
- "10G-base-T PMA status 0x%x->0x%x\n",
- val2, val1);
- ext_phy_link_up = ((val1 & 4) == 4);
- /* if link is up
- * print the AN outcome of the SFX7101 PHY
- */
- if (ext_phy_link_up) {
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_MASTER_STATUS,
- &val2);
- vars->line_speed = SPEED_10000;
- DP(NETIF_MSG_LINK,
- "SFX7101 AN status 0x%x->Master=%x\n",
- val2,
- (val2 & (1<<14)));
- }
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- params->ext_phy_config);
- ext_phy_link_up = 0;
- break;
- }
-
- } else { /* SerDes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- DP(NETIF_MSG_LINK, "SerDes Direct\n");
- ext_phy_link_up = 1;
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- DP(NETIF_MSG_LINK, "SerDes 5482\n");
- ext_phy_link_up = 1;
- break;
-
- default:
- DP(NETIF_MSG_LINK,
- "BAD SerDes ext_phy_config 0x%x\n",
- params->ext_phy_config);
- ext_phy_link_up = 0;
- break;
- }
- }
-
- return ext_phy_link_up;
-}
-
-static void bnx2x_link_int_enable(struct link_params *params)
-{
- u8 port = params->port;
- u32 ext_phy_type;
- u32 mask;
- struct bnx2x *bp = params->bp;
- /* setting the status to report on link up
- for either XGXS or SerDes */
-
- if (params->switch_cfg == SWITCH_CFG_10G) {
- mask = (NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_XGXS0_LINK_STATUS);
- DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
- (ext_phy_type !=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
-
- } else { /* SerDes */
- mask = NIG_MASK_SERDES0_LINK_STATUS;
- DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- if ((ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type !=
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
- mask |= NIG_MASK_MI_INT;
- DP(NETIF_MSG_LINK, "enabled external phy int\n");
- }
- }
- bnx2x_bits_en(bp,
- NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- mask);
- DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
- (params->switch_cfg == SWITCH_CFG_10G),
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
-
- DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
- REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
- REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
- DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
-}
-
-
-/*
- * link management
- */
-static void bnx2x_link_int_ack(struct link_params *params,
- struct link_vars *vars, u8 is_10g)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
-
- /* first reset all status
- * we assume only one line will be change at a time */
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
- if (vars->phy_link_up) {
- if (is_10g) {
- /* Disable the 10G link interrupt
- * by writing 1 to the status register
- */
- DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_XGXS0_LINK10G);
-
- } else if (params->switch_cfg == SWITCH_CFG_10G) {
- /* Disable the link interrupt
- * by writing 1 to the relevant lane
- * in the status register
- */
- u32 ser_lane = ((params->lane_config &
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
- PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
-
- DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- ((1 << ser_lane) <<
- NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
-
- } else { /* SerDes */
- DP(NETIF_MSG_LINK, "SerDes phy link up\n");
- /* Disable the link interrupt
- * by writing 1 to the status register
- */
- bnx2x_bits_en(bp,
- NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- NIG_STATUS_SERDES0_LINK_STATUS);
- }
-
- } else { /* link_down */
- }
-}
-
-static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
-{
- u8 *str_ptr = str;
- u32 mask = 0xf0000000;
- u8 shift = 8*4;
- u8 digit;
- if (len < 10) {
- /* Need more then 10chars for this format */
- *str_ptr = '\0';
- return -EINVAL;
- }
- while (shift > 0) {
-
- shift -= 4;
- digit = ((num & mask) >> shift);
- if (digit < 0xa)
- *str_ptr = digit + '0';
- else
- *str_ptr = digit - 0xa + 'a';
- str_ptr++;
- mask = mask >> 4;
- if (shift == 4*4) {
- *str_ptr = ':';
- str_ptr++;
- }
- }
- *str_ptr = '\0';
- return 0;
-}
-
-
-static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
- u32 ext_phy_type)
-{
- u32 cnt = 0;
- u16 ctrl = 0;
- /* Enable EMAC0 in to enable MDIO */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
- (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
- msleep(5);
-
- /* take ext phy out of reset */
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_HIGH,
- port);
-
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_HIGH,
- port);
-
- /* wait for 5ms */
- msleep(5);
-
- for (cnt = 0; cnt < 1000; cnt++) {
- msleep(1);
- bnx2x_cl45_read(bp, port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- &ctrl);
- if (!(ctrl & (1<<15))) {
- DP(NETIF_MSG_LINK, "Reset completed\n\n");
- break;
- }
- }
-}
-
-static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
-{
- /* put sf to reset */
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_LOW,
- port);
- bnx2x_set_gpio(bp,
- MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_LOW,
- port);
-}
-
-u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
- u8 *version, u16 len)
-{
- struct bnx2x *bp = params->bp;
- u32 ext_phy_type = 0;
- u16 val = 0;
- u8 ext_phy_addr = 0 ;
- u8 status = 0 ;
- u32 ver_num;
-
- if (version == NULL || params == NULL)
- return -EINVAL;
-
- /* reset the returned value to zero */
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
-
- if (len < 5)
- return -EINVAL;
-
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
- ext_phy_type);
-
- /* wait for 1ms */
- msleep(1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER1, &val);
- version[2] = (val & 0xFF);
- version[3] = ((val & 0xFF00)>>8);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
- &val);
- version[0] = (val & 0xFF);
- version[1] = ((val & 0xFF00)>>8);
- version[4] = '\0';
-
- if (!driver_loaded)
- bnx2x_turn_off_sf(bp, params->port);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
- ext_phy_type);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- ver_num = val<<16;
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &val);
- ver_num |= val;
- status = bnx2x_format_ver(ver_num, version, len);
- break;
- }
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- ver_num = val<<16;
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &val);
- ver_num |= val;
- status = bnx2x_format_ver(ver_num, version, len);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
- " type is FAILURE!\n");
- status = -EINVAL;
- break;
-
- default:
- break;
- }
- return status;
-}
-
-static void bnx2x_set_xgxs_loopback(struct link_params *params,
- struct link_vars *vars,
- u8 is_10g)
-{
- u8 port = params->port;
- struct bnx2x *bp = params->bp;
-
- if (is_10g) {
- u32 md_devad;
-
- DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
-
- /* change the uni_phy_addr in the nig */
- md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
- port*0x18));
-
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
-
- bnx2x_cl45_write(bp, port, 0,
- params->phy_addr,
- 5,
- (MDIO_REG_BANK_AER_BLOCK +
- (MDIO_AER_BLOCK_AER_REG & 0xf)),
- 0x2800);
-
- bnx2x_cl45_write(bp, port, 0,
- params->phy_addr,
- 5,
- (MDIO_REG_BANK_CL73_IEEEB0 +
- (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
- 0x6041);
-
- /* set aer mmd back */
- bnx2x_set_aer_mmd(params, vars);
-
- /* and md_devad */
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
- md_devad);
-
- } else {
- u16 mii_control;
-
- DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
-
- CL45_RD_OVER_CL22(bp, port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
-
- CL45_WR_OVER_CL22(bp, port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
- }
-}
-
-
-static void bnx2x_ext_phy_loopback(struct link_params *params)
-{
- struct bnx2x *bp = params->bp;
- u8 ext_phy_addr;
- u32 ext_phy_type;
-
- if (params->switch_cfg == SWITCH_CFG_10G) {
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* CL37 Autoneg Enabled */
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
- DP(NETIF_MSG_LINK,
- "ext_phy_loopback: We should not get here\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* SFX7101_XGXS_TEST1 */
- bnx2x_cl45_write(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_XS_DEVAD,
- MDIO_XS_SFX7101_XGXS_TEST1,
- 0x100);
- DP(NETIF_MSG_LINK,
- "ext_phy_loopback: set ext phy loopback\n");
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
-
- break;
- } /* switch external PHY type */
- } else {
- /* serdes */
- ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = (params->ext_phy_config &
- PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
- >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
- }
-}
-
-
-/*
- *------------------------------------------------------------------------
- * bnx2x_override_led_value -
- *
- * Override the led value of the requsted led
- *
- *------------------------------------------------------------------------
- */
-u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
- u32 led_idx, u32 value)
-{
- u32 reg_val;
-
- /* If port 0 then use EMAC0, else use EMAC1*/
- u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
-
- DP(NETIF_MSG_LINK,
- "bnx2x_override_led_value() port %x led_idx %d value %d\n",
- port, led_idx, value);
-
- switch (led_idx) {
- case 0: /* 10MB led */
- /* Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 10M_OVERRIDE bit,
- otherwise reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_10MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- break;
- case 1: /*100MB led */
- /*Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 100M_OVERRIDE bit,
- otherwise reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_100MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- break;
- case 2: /* 1000MB led */
- /* Read the current value of the LED register in the
- EMAC block */
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
- reset it. */
- reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- break;
- case 3: /* 2500MB led */
- /* Read the current value of the LED register in the
- EMAC block*/
- reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
- /* Set the OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
- reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
- (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- break;
- case 4: /*10G led */
- if (port == 0) {
- REG_WR(bp, NIG_REG_LED_10G_P0,
- value);
- } else {
- REG_WR(bp, NIG_REG_LED_10G_P1,
- value);
- }
- break;
- case 5: /* TRAFFIC led */
- /* Find if the traffic control is via BMAC or EMAC */
- if (port == 0)
- reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
- else
- reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
-
- /* Override the traffic led in the EMAC:*/
- if (reg_val == 1) {
- /* Read the current value of the LED register in
- the EMAC block */
- reg_val = REG_RD(bp, emac_base +
- EMAC_REG_EMAC_LED);
- /* Set the TRAFFIC_OVERRIDE bit to 1 */
- reg_val |= EMAC_LED_OVERRIDE;
- /* If value is 1, set the TRAFFIC bit, otherwise
- reset it.*/
- reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
- (reg_val & ~EMAC_LED_TRAFFIC);
- REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
- } else { /* Override the traffic led in the BMAC: */
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
- + port*4, 1);
- REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
- value);
- }
- break;
- default:
- DP(NETIF_MSG_LINK,
- "bnx2x_override_led_value() unknown led index %d "
- "(should be 0-5)\n", led_idx);
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
- u16 hw_led_mode, u32 chip_id)
-{
- u8 rc = 0;
- u32 tmp;
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
- DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
- speed, hw_led_mode);
- switch (mode) {
- case LED_MODE_OFF:
- REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
- SHARED_HW_CFG_LED_MAC1);
-
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
- break;
-
- case LED_MODE_OPER:
- REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
- port*4, 0);
- /* Set blinking rate to ~15.9Hz */
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
- LED_BLINK_RATE_VAL);
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
- port*4, 1);
- tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
- EMAC_WR(bp, EMAC_REG_EMAC_LED,
- (tmp & (~EMAC_LED_OVERRIDE)));
-
- if (!CHIP_IS_E1H(bp) &&
- ((speed == SPEED_2500) ||
- (speed == SPEED_1000) ||
- (speed == SPEED_100) ||
- (speed == SPEED_10))) {
- /* On Everest 1 Ax chip versions for speeds less than
- 10G LED scheme is different */
- REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
- + port*4, 1);
- REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
- port*4, 0);
- REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
- port*4, 1);
- }
- break;
-
- default:
- rc = -EINVAL;
- DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
- mode);
- break;
- }
- return rc;
-
-}
-
-u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u16 gp_status = 0;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_GP_STATUS,
- MDIO_GP_STATUS_TOP_AN_STATUS1,
- &gp_status);
- /* link is up only if both local phy and external phy are up */
- if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
- bnx2x_ext_phy_is_link_up(params, vars))
- return 0;
-
- return -ESRCH;
-}
-
-static u8 bnx2x_link_initialize(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 rc = 0;
- u8 non_ext_phy;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- /* Activate the external PHY */
- bnx2x_ext_phy_reset(params, vars);
-
- bnx2x_set_aer_mmd(params, vars);
-
- if (vars->phy_flags & PHY_XGXS_FLAG)
- bnx2x_set_master_ln(params);
-
- rc = bnx2x_reset_unicore(params);
- /* reset the SerDes and wait for reset bit return low */
- if (rc != 0)
- return rc;
-
- bnx2x_set_aer_mmd(params, vars);
-
- /* setting the masterLn_def again after the reset */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- bnx2x_set_master_ln(params);
- bnx2x_set_swap_lanes(params);
- }
-
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- if (params->req_line_speed &&
- ((params->req_line_speed == SPEED_100) ||
- (params->req_line_speed == SPEED_10))) {
- vars->phy_flags |= PHY_SGMII_FLAG;
- } else {
- vars->phy_flags &= ~PHY_SGMII_FLAG;
- }
- }
- /* In case of external phy existance, the line speed would be the
- line speed linked up by the external phy. In case it is direct only,
- then the line_speed during initialization will be equal to the
- req_line_speed*/
- vars->line_speed = params->req_line_speed;
-
- bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
-
- /* init ext phy and enable link state int */
- non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (params->loopback_mode == LOOPBACK_XGXS_10) ||
- (params->loopback_mode == LOOPBACK_EXT_PHY));
-
- if (non_ext_phy ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
- if (params->req_line_speed == SPEED_AUTO_NEG)
- bnx2x_set_parallel_detection(params, vars->phy_flags);
- bnx2x_init_internal_phy(params, vars);
- }
-
- if (!non_ext_phy)
- rc |= bnx2x_ext_phy_init(params, vars);
-
- bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
- (NIG_STATUS_XGXS0_LINK10G |
- NIG_STATUS_XGXS0_LINK_STATUS |
- NIG_STATUS_SERDES0_LINK_STATUS));
-
- return rc;
-
-}
-
-
-u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
-
- u32 val;
- DP(NETIF_MSG_LINK, "Phy Initialization started \n");
- DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
- params->req_line_speed, params->req_flow_ctrl);
- vars->link_status = 0;
- vars->phy_link_up = 0;
- vars->link_up = 0;
- vars->line_speed = 0;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
- vars->mac_type = MAC_TYPE_NONE;
-
- if (params->switch_cfg == SWITCH_CFG_1G)
- vars->phy_flags = PHY_SERDES_FLAG;
- else
- vars->phy_flags = PHY_XGXS_FLAG;
-
-
- /* disable attentions */
- bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_SERDES0_LINK_STATUS |
- NIG_MASK_MI_INT));
-
- bnx2x_emac_init(params, vars);
-
- if (CHIP_REV_IS_FPGA(bp)) {
- vars->link_up = 1;
- vars->line_speed = SPEED_10000;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
- vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
- /* enable on E1.5 FPGA */
- if (CHIP_IS_E1H(bp)) {
- vars->flow_ctrl |=
- (FLOW_CTRL_TX | FLOW_CTRL_RX);
- vars->link_status |=
- (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
- LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
- }
-
- bnx2x_emac_enable(params, vars, 0);
- bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
- /* disable drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
- + params->port*4, 0);
-
- /* update shared memory */
- bnx2x_update_mng(params, vars->link_status);
-
- return 0;
-
- } else
- if (CHIP_REV_IS_EMUL(bp)) {
-
- vars->link_up = 1;
- vars->line_speed = SPEED_10000;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
- vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
-
- bnx2x_bmac_enable(params, vars, 0);
-
- bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
- /* Disable drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
- + params->port*4, 0);
-
- /* update shared memory */
- bnx2x_update_mng(params, vars->link_status);
-
- return 0;
-
- } else
- if (params->loopback_mode == LOOPBACK_BMAC) {
- vars->link_up = 1;
- vars->line_speed = SPEED_10000;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
- vars->mac_type = MAC_TYPE_BMAC;
-
- vars->phy_flags = PHY_XGXS_FLAG;
-
- bnx2x_phy_deassert(params, vars->phy_flags);
- /* set bmac loopback */
- bnx2x_bmac_enable(params, vars, 1);
-
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
- params->port*4, 0);
- } else if (params->loopback_mode == LOOPBACK_EMAC) {
- vars->link_up = 1;
- vars->line_speed = SPEED_1000;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
- vars->mac_type = MAC_TYPE_EMAC;
-
- vars->phy_flags = PHY_XGXS_FLAG;
-
- bnx2x_phy_deassert(params, vars->phy_flags);
- /* set bmac loopback */
- bnx2x_emac_enable(params, vars, 1);
- bnx2x_emac_program(params, vars->line_speed,
- vars->duplex);
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
- params->port*4, 0);
- } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
- (params->loopback_mode == LOOPBACK_EXT_PHY)) {
- vars->link_up = 1;
- vars->line_speed = SPEED_10000;
- vars->duplex = DUPLEX_FULL;
- vars->flow_ctrl = FLOW_CTRL_NONE;
-
- vars->phy_flags = PHY_XGXS_FLAG;
-
- val = REG_RD(bp,
- NIG_REG_XGXS0_CTRL_PHY_ADDR+
- params->port*0x18);
- params->phy_addr = (u8)val;
-
- bnx2x_phy_deassert(params, vars->phy_flags);
- bnx2x_link_initialize(params, vars);
-
- vars->mac_type = MAC_TYPE_BMAC;
-
- bnx2x_bmac_enable(params, vars, 0);
-
- if (params->loopback_mode == LOOPBACK_XGXS_10) {
- /* set 10G XGXS loopback */
- bnx2x_set_xgxs_loopback(params, vars, 1);
- } else {
- /* set external phy loopback */
- bnx2x_ext_phy_loopback(params);
- }
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
- params->port*4, 0);
- } else
- /* No loopback */
- {
-
- bnx2x_phy_deassert(params, vars->phy_flags);
- switch (params->switch_cfg) {
- case SWITCH_CFG_1G:
- vars->phy_flags |= PHY_SERDES_FLAG;
- if ((params->ext_phy_config &
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
- vars->phy_flags |=
- PHY_SGMII_FLAG;
- }
-
- val = REG_RD(bp,
- NIG_REG_SERDES0_CTRL_PHY_ADDR+
- params->port*0x10);
-
- params->phy_addr = (u8)val;
-
- break;
- case SWITCH_CFG_10G:
- vars->phy_flags |= PHY_XGXS_FLAG;
- val = REG_RD(bp,
- NIG_REG_XGXS0_CTRL_PHY_ADDR+
- params->port*0x18);
- params->phy_addr = (u8)val;
-
- break;
- default:
- DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
- return -EINVAL;
- break;
- }
-
- bnx2x_link_initialize(params, vars);
- msleep(30);
- bnx2x_link_int_enable(params);
- }
- return 0;
-}
-
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
-{
-
- struct bnx2x *bp = params->bp;
- u32 ext_phy_config = params->ext_phy_config;
- u16 hw_led_mode = params->hw_led_mode;
- u32 chip_id = params->chip_id;
- u8 port = params->port;
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
- /* disable attentions */
-
- vars->link_status = 0;
- bnx2x_update_mng(params, vars->link_status);
- bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_SERDES0_LINK_STATUS |
- NIG_MASK_MI_INT));
-
- /* activate nig drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
-
- /* disable nig egress interface */
- REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
-
- /* Stop BigMac rx */
- bnx2x_bmac_rx_disable(bp, port);
-
- /* disable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
-
- msleep(10);
- /* The PHY reset is controled by GPIO 1
- * Hold it as vars low
- */
- /* clear link led */
- bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
- if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
- /* HW reset */
-
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
-
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
-
- DP(NETIF_MSG_LINK, "reset external PHY\n");
- } else if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
- "low power mode\n",
- port);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
- }
- }
- /* reset the SerDes/XGXS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
- (0x1ff << (port*16)));
-
- /* reset BigMac */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
- /* disable nig ingress interface */
- REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
- REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
- REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
- REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
- vars->link_up = 0;
- return 0;
-}
-
-static u8 bnx2x_update_link_down(struct link_params *params,
- struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
- bnx2x_set_led(bp, port, LED_MODE_OFF,
- 0, params->hw_led_mode,
- params->chip_id);
-
- /* indicate no mac active */
- vars->mac_type = MAC_TYPE_NONE;
-
- /* update shared memory */
- vars->link_status = 0;
- vars->line_speed = 0;
- bnx2x_update_mng(params, vars->link_status);
-
- /* activate nig drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
-
- /* reset BigMac */
- bnx2x_bmac_rx_disable(bp, params->port);
- REG_WR(bp, GRCBASE_MISC +
- MISC_REGISTERS_RESET_REG_2_CLEAR,
- (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
- return 0;
-}
-
-static u8 bnx2x_update_link_up(struct link_params *params,
- struct link_vars *vars,
- u8 link_10g, u32 gp_status)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u8 rc = 0;
- vars->link_status |= LINK_STATUS_LINK_UP;
- if (link_10g) {
- bnx2x_bmac_enable(params, vars, 0);
- bnx2x_set_led(bp, port, LED_MODE_OPER,
- SPEED_10000, params->hw_led_mode,
- params->chip_id);
-
- } else {
- bnx2x_emac_enable(params, vars, 0);
- rc = bnx2x_emac_program(params, vars->line_speed,
- vars->duplex);
-
- /* AN complete? */
- if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
- if (!(vars->phy_flags &
- PHY_SGMII_FLAG))
- bnx2x_set_sgmii_tx_driver(params);
- }
- }
-
- /* PBF - link up */
- rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
- vars->line_speed);
-
- /* disable drain */
- REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
-
- /* update shared memory */
- bnx2x_update_mng(params, vars->link_status);
- return rc;
-}
-/* This function should called upon link interrupt */
-/* In case vars->link_up, driver needs to
- 1. Update the pbf
- 2. Disable drain
- 3. Update the shared memory
- 4. Indicate link up
- 5. Set LEDs
- Otherwise,
- 1. Update shared memory
- 2. Reset BigMac
- 3. Report link down
- 4. Unset LEDs
-*/
-u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
-{
- struct bnx2x *bp = params->bp;
- u8 port = params->port;
- u16 gp_status;
- u8 link_10g;
- u8 ext_phy_link_up, rc = 0;
- u32 ext_phy_type;
-
- DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
- port,
- (vars->phy_flags & PHY_XGXS_FLAG),
- REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
-
- DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
- REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
- REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
- REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
-
- DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
- REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
- /* Check external link change only for non-direct */
- ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
-
- /* Read gp_status */
- CL45_RD_OVER_CL22(bp, port, params->phy_addr,
- MDIO_REG_BANK_GP_STATUS,
- MDIO_GP_STATUS_TOP_AN_STATUS1,
- &gp_status);
-
- rc = bnx2x_link_settings_status(params, vars, gp_status);
- if (rc != 0)
- return rc;
-
- /* anything 10 and over uses the bmac */
- link_10g = ((vars->line_speed == SPEED_10000) ||
- (vars->line_speed == SPEED_12000) ||
- (vars->line_speed == SPEED_12500) ||
- (vars->line_speed == SPEED_13000) ||
- (vars->line_speed == SPEED_15000) ||
- (vars->line_speed == SPEED_16000));
-
- bnx2x_link_int_ack(params, vars, link_10g);
-
- /* In case external phy link is up, and internal link is down
- ( not initialized yet probably after link initialization, it needs
- to be initialized.
- Note that after link down-up as result of cable plug,
- the xgxs link would probably become up again without the need to
- initialize it*/
-
- if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
- (ext_phy_link_up && !vars->phy_link_up))
- bnx2x_init_internal_phy(params, vars);
-
- /* link is up only if both local phy and external phy are up */
- vars->link_up = (ext_phy_link_up && vars->phy_link_up);
-
- if (vars->link_up)
- rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
- else
- rc = bnx2x_update_link_down(params, vars);
-
- return rc;
-}
-
-static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
-{
- u8 ext_phy_addr[PORT_MAX];
- u16 val;
- s8 port;
-
- /* PART1 - Reset both phys */
- for (port = PORT_MAX - 1; port >= PORT_0; port--) {
- /* Extract the ext phy address for the port */
- u32 ext_phy_config = REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[port].external_phy_config));
-
- /* disable attentions */
- bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
- (NIG_MASK_XGXS0_LINK_STATUS |
- NIG_MASK_XGXS0_LINK10G |
- NIG_MASK_SERDES0_LINK_STATUS |
- NIG_MASK_MI_INT));
-
- ext_phy_addr[port] =
- ((ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- /* Need to take the phy out of low power mode in order
- to write to access its registers */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
-
- /* Reset the phy */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_CTRL,
- 1<<15);
- }
-
- /* Add delay of 150ms after reset */
- msleep(150);
-
- /* PART2 - Download firmware to both phys */
- for (port = PORT_MAX - 1; port >= PORT_0; port--) {
- u16 fw_ver1;
-
- bnx2x_bcm8073_external_rom_boot(bp, port,
- ext_phy_addr[port]);
-
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- if (fw_ver1 == 0) {
- DP(NETIF_MSG_LINK,
- "bnx2x_8073_common_init_phy port %x "
- "fw Download failed\n", port);
- return -EINVAL;
- }
-
- /* Only set bit 10 = 1 (Tx power down) */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_TX_POWER_DOWN, &val);
-
- /* Phase1 of TX_POWER_DOWN reset */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_TX_POWER_DOWN,
- (val | 1<<10));
- }
-
- /* Toggle Transmitter: Power down and then up with 600ms
- delay between */
- msleep(600);
-
- /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
- for (port = PORT_MAX - 1; port >= PORT_0; port--) {
- /* Phase2 of POWER_DOWN_RESET*/
- /* Release bit 10 (Release Tx power down) */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_TX_POWER_DOWN, &val);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
- msleep(15);
-
- /* Read modify write the SPI-ROM version select register */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_EDC_FFE_MAIN, &val);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
- ext_phy_addr[port],
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
-
- /* set GPIO2 back to LOW */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- }
- return 0;
-
-}
-
-u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
-{
- u8 rc = 0;
- u32 ext_phy_type;
-
- DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
-
- /* Read the ext_phy_type for arbitrary port(0) */
- ext_phy_type = XGXS_EXT_PHY_TYPE(
- REG_RD(bp, shmem_base +
- offsetof(struct shmem_region,
- dev_info.port_hw_config[0].external_phy_config)));
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- rc = bnx2x_8073_common_init_phy(bp, shmem_base);
- break;
- }
- default:
- DP(NETIF_MSG_LINK,
- "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
- ext_phy_type);
- break;
- }
-
- return rc;
-}
-
-
-
-static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
-{
- u16 val, cnt;
-
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET, &val);
-
- for (cnt = 0; cnt < 10; cnt++) {
- msleep(50);
- /* Writes a self-clearing reset */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET,
- (val | (1<<15)));
- /* Wait for clear */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_RESET, &val);
-
- if ((val & (1<<15)) == 0)
- break;
- }
-}
-#define RESERVED_SIZE 256
-/* max application is 160K bytes - data at end of RAM */
-#define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
-
-/* Header is 14 bytes */
-#define HEADER_SIZE 14
-#define DATA_OFFSET HEADER_SIZE
-
-#define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
- bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
- ext_phy_addr, \
- MDIO_PCS_DEVAD, \
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
-
-/* Programs an image to DSP's flash via the SPI port*/
-static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr,
- char data[], u32 size)
-{
- const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
- /* Doesn't include last trans!*/
- const u16 last_trans_size = size%4; /* Num bytes on last trans */
- u16 trans_cnt, byte_cnt;
- u32 data_index;
- u16 tmp;
- u16 code_started = 0;
- u16 image_revision1, image_revision2;
- u16 cnt;
-
- DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
- /* Going to flash*/
- if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
- /* This very often will be the case, because the image is built
- with 160Kbytes size whereas the total image size must actually
- be 160Kbytes-RESERVED_SIZE */
- DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
- "truncated to %d bytes\n", size, MAX_APP_SIZE);
- size = MAX_APP_SIZE+HEADER_SIZE;
- }
- DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
- DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
- /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
- and issuing a reset.*/
-
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
- MISC_REGISTERS_GPIO_HIGH, port);
-
- bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
-
- /* wait 0.5 sec */
- for (cnt = 0; cnt < 100; cnt++)
- msleep(5);
-
- /* Make sure we can access the DSP
- And it's in the correct mode (waiting for download) */
-
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
-
- if (tmp != 0x000A) {
- DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
- "Expected 0x000A, read 0x%04X\n", tmp);
- DP(NETIF_MSG_LINK, "Download failed\n");
- return -EINVAL;
- }
-
- /* Mux the SPI interface away from the internal processor */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_MUX, 1);
-
- /* Reset the SPI port */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
- (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
-
- /* Erase the flash */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
- /* Wait 10 seconds, the maximum time for the erase to complete */
- DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
- for (cnt = 0; cnt < 1000; cnt++)
- msleep(10);
-
- DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
- data_index = 0;
- for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
-
- /* Bits 23-16 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>16));
- /* Bits 15-8 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>8));
-
- /* Bits 7-0 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- ((u16)data_index));
-
- byte_cnt = 0;
- while (byte_cnt < 4 && data_index < size) {
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- data[data_index++]);
- byte_cnt++;
- }
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- byte_cnt+4);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
- msleep(5); /* Wait 5 ms minimum between transs */
-
- /* Let the user know something's going on.*/
- /* a pacifier ever 4K */
- if ((data_index % 1023) == 0)
- DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
- }
-
- DP(NETIF_MSG_LINK, "\n");
- /* Transfer the last block if there is data remaining */
- if (last_trans_size) {
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- 1);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
-
- /* Bits 23-16 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>16));
- /* Bits 15-8 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- (data_index>>8));
-
- /* Bits 7-0 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- ((u16)data_index));
-
- byte_cnt = 0;
- while (byte_cnt < last_trans_size && data_index < size) {
- /* Bits 7-0 of address */
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
- data[data_index++]);
- byte_cnt++;
- }
-
- bnx2x_cl45_write(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
- byte_cnt+4);
-
- SPI_START_TRANSFER(bp, port, ext_phy_addr);
- }
-
- /* DSP Remove Download Mode */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
- MISC_REGISTERS_GPIO_LOW, port);
-
- bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
-
- /* wait 0.5 sec to allow it to run */
- for (cnt = 0; cnt < 100; cnt++)
- msleep(5);
-
- bnx2x_hw_reset(bp, port);
-
- for (cnt = 0; cnt < 100; cnt++)
- msleep(5);
-
- /* Check that the code is started. In case the download
- checksum failed, the code won't be started. */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_7101_DSP_ACCESS,
- &tmp);
-
- code_started = (tmp & (1<<4));
- if (!code_started) {
- DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
- return -EINVAL;
- }
-
- /* Verify that the file revision is now equal to the image
- revision within the DSP */
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER1,
- &image_revision1);
-
- bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER2,
- &image_revision2);
-
- if (data[0x14e] != (image_revision2&0xFF) ||
- data[0x14f] != ((image_revision2&0xFF00)>>8) ||
- data[0x150] != (image_revision1&0xFF) ||
- data[0x151] != ((image_revision1&0xFF00)>>8)) {
- DP(NETIF_MSG_LINK, "Download failed.\n");
- return -EINVAL;
- }
- DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
- return 0;
-}
-
-u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
- u8 driver_loaded, char data[], u32 size)
-{
- u8 rc = 0;
- u32 ext_phy_type;
- u8 ext_phy_addr;
- ext_phy_addr = ((ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
- ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK,
- "Flash download not supported for this ext phy\n");
- rc = -EINVAL;
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
- rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
- data, size);
- if (!driver_loaded)
- bnx2x_turn_off_sf(bp, port);
- break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
- default:
- DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
- rc = -EINVAL;
- break;
- }
- return rc;
-}
-
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h
deleted file mode 100644
index 86d54a17b41..00000000000
--- a/drivers/net/bnx2x_link.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright 2008 Broadcom Corporation
- *
- * Unless you and Broadcom execute a separate written software license
- * agreement governing use of this software, this software is licensed to you
- * under the terms of the GNU General Public License version 2, available
- * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
- *
- * Notwithstanding the above, under no circumstances may you combine this
- * software in any way with any other Broadcom software provided under a
- * license other than the GPL, without Broadcom's express prior written
- * consent.
- *
- * Written by Yaniv Rosner
- *
- */
-
-#ifndef BNX2X_LINK_H
-#define BNX2X_LINK_H
-
-
-
-/***********************************************************/
-/* Defines */
-/***********************************************************/
-#define DEFAULT_PHY_DEV_ADDR 3
-
-
-
-#define FLOW_CTRL_AUTO PORT_FEATURE_FLOW_CONTROL_AUTO
-#define FLOW_CTRL_TX PORT_FEATURE_FLOW_CONTROL_TX
-#define FLOW_CTRL_RX PORT_FEATURE_FLOW_CONTROL_RX
-#define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
-#define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
-
-#define SPEED_AUTO_NEG 0
-#define SPEED_12000 12000
-#define SPEED_12500 12500
-#define SPEED_13000 13000
-#define SPEED_15000 15000
-#define SPEED_16000 16000
-
-
-/***********************************************************/
-/* Structs */
-/***********************************************************/
-/* Inputs parameters to the CLC */
-struct link_params {
-
- u8 port;
-
- /* Default / User Configuration */
- u8 loopback_mode;
-#define LOOPBACK_NONE 0
-#define LOOPBACK_EMAC 1
-#define LOOPBACK_BMAC 2
-#define LOOPBACK_XGXS_10 3
-#define LOOPBACK_EXT_PHY 4
-#define LOOPBACK_EXT 5
-
- u16 req_duplex;
- u16 req_flow_ctrl;
- u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
- req_flow_ctrl is set to AUTO */
- u16 req_line_speed; /* Also determine AutoNeg */
-
- /* Device parameters */
- u8 mac_addr[6];
-
-
-
- /* shmem parameters */
- u32 shmem_base;
- u32 speed_cap_mask;
- u32 switch_cfg;
-#define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
-#define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
-#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
-
- u16 hw_led_mode; /* part of the hw_config read from the shmem */
- u32 serdes_config;
- u32 lane_config;
- u32 ext_phy_config;
-#define XGXS_EXT_PHY_TYPE(ext_phy_config) (ext_phy_config & \
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
-#define SERDES_EXT_PHY_TYPE(ext_phy_config) (ext_phy_config & \
- PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
- /* Phy register parameter */
- u32 chip_id;
-
- /* phy_addr populated by the CLC */
- u8 phy_addr;
- /* Device pointer passed to all callback functions */
- struct bnx2x *bp;
-};
-
-/* Output parameters */
-struct link_vars {
- u8 phy_link_up; /* internal phy link indication */
- u8 link_up;
- u16 duplex;
- u16 flow_ctrl;
- u32 ieee_fc;
- u8 mac_type;
-
-#define MAC_TYPE_NONE 0
-#define MAC_TYPE_EMAC 1
-#define MAC_TYPE_BMAC 2
- u16 line_speed;
- u32 autoneg;
-#define AUTO_NEG_DISABLED 0x0
-#define AUTO_NEG_ENABLED 0x1
-#define AUTO_NEG_COMPLETE 0x2
-#define AUTO_NEG_PARALLEL_DETECTION_USED 0x3
-
- u8 phy_flags;
-
- /* The same definitions as the shmem parameter */
- u32 link_status;
-};
-
-/***********************************************************/
-/* Functions */
-/***********************************************************/
-
-/* Initialize the phy */
-u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
-
-/* Reset the link. Should be called when driver or interface goes down */
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars);
-
-/* bnx2x_link_update should be called upon link interrupt */
-u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
-
-/* use the following cl45 functions to read/write from external_phy
- In order to use it to read/write internal phy registers, use
- DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as
- Use ext_phy_type of 0 in case of cl22 over cl45
- the register */
-u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 *ret_val);
-
-u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
- u8 phy_addr, u8 devad, u16 reg, u16 val);
-
-/* Reads the link_status from the shmem,
- and update the link vars accordingly */
-void bnx2x_link_status_update(struct link_params *input,
- struct link_vars *output);
-/* returns string representing the fw_version of the external phy */
-u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
- u8 *version, u16 len);
-
-/* Set/Unset the led
- Basically, the CLC takes care of the led for the link, but in case one needs
- to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to
- blink the led, and LED_MODE_OFF to set the led off.*/
-u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
- u16 hw_led_mode, u32 chip_id);
-#define LED_MODE_OFF 0
-#define LED_MODE_OPER 2
-
-u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
-
-u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
- u8 driver_loaded, char data[], u32 size);
-/* Get the actual link status. In case it returns 0, link is up,
- otherwise link is down*/
-u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
-
-/* One-time initialization for external phy after power up */
-u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
-
-#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
deleted file mode 100644
index a8eb3c4a47c..00000000000
--- a/drivers/net/bnx2x_main.c
+++ /dev/null
@@ -1,10459 +0,0 @@
-/* bnx2x_main.c: Broadcom Everest network driver.
- *
- * Copyright (c) 2007-2008 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * Maintained by: Eilon Greenstein <eilong@broadcom.com>
- * Written by: Eliezer Tamir
- * Based on code from Michael Chan's bnx2 driver
- * UDP CSUM errata workaround by Arik Gendelman
- * Slowpath rework by Vladislav Zolotarov
- * Statistics and Link management by Yitchak Gertner
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/device.h> /* for dev_info() */
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/dma-mapping.h>
-#include <linux/bitops.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <asm/byteorder.h>
-#include <linux/time.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#ifdef NETIF_F_HW_VLAN_TX
- #include <linux/if_vlan.h>
-#endif
-#include <net/ip.h>
-#include <net/tcp.h>
-#include <net/checksum.h>
-#include <net/ip6_checksum.h>
-#include <linux/workqueue.h>
-#include <linux/crc32.h>
-#include <linux/crc32c.h>
-#include <linux/prefetch.h>
-#include <linux/zlib.h>
-#include <linux/io.h>
-
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
-#include "bnx2x.h"
-#include "bnx2x_init.h"
-
-#define DRV_MODULE_VERSION "1.45.21"
-#define DRV_MODULE_RELDATE "2008/09/03"
-#define BNX2X_BC_VER 0x040200
-
-/* Time in jiffies before concluding the transmitter is hung */
-#define TX_TIMEOUT (5*HZ)
-
-static char version[] __devinitdata =
- "Broadcom NetXtreme II 5771x 10Gigabit Ethernet Driver "
- DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-
-MODULE_AUTHOR("Eliezer Tamir");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_MODULE_VERSION);
-
-static int disable_tpa;
-static int use_inta;
-static int poll;
-static int debug;
-static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
-static int use_multi;
-
-module_param(disable_tpa, int, 0);
-module_param(use_inta, int, 0);
-module_param(poll, int, 0);
-module_param(debug, int, 0);
-MODULE_PARM_DESC(disable_tpa, "disable the TPA (LRO) feature");
-MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
-MODULE_PARM_DESC(poll, "use polling (for debug)");
-MODULE_PARM_DESC(debug, "default debug msglevel");
-
-#ifdef BNX2X_MULTI
-module_param(use_multi, int, 0);
-MODULE_PARM_DESC(use_multi, "use per-CPU queues");
-#endif
-
-enum bnx2x_board_type {
- BCM57710 = 0,
- BCM57711 = 1,
- BCM57711E = 2,
-};
-
-/* indexed by board_type, above */
-static struct {
- char *name;
-} board_info[] __devinitdata = {
- { "Broadcom NetXtreme II BCM57710 XGb" },
- { "Broadcom NetXtreme II BCM57711 XGb" },
- { "Broadcom NetXtreme II BCM57711E XGb" }
-};
-
-
-static const struct pci_device_id bnx2x_pci_tbl[] = {
- { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 },
- { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711 },
- { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711E,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711E },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
-
-/****************************************************************************
-* General service functions
-****************************************************************************/
-
-/* used only at init
- * locking is done by mcp
- */
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
-{
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
- pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val);
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
- PCICFG_VENDOR_ID_OFFSET);
-}
-
-static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
-{
- u32 val;
-
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
- pci_read_config_dword(bp->pdev, PCICFG_GRC_DATA, &val);
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
- PCICFG_VENDOR_ID_OFFSET);
-
- return val;
-}
-
-static const u32 dmae_reg_go_c[] = {
- DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
- DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
- DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11,
- DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15
-};
-
-/* copy command into DMAE command memory and set DMAE command go */
-static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
- int idx)
-{
- u32 cmd_offset;
- int i;
-
- cmd_offset = (DMAE_REG_CMD_MEM + sizeof(struct dmae_command) * idx);
- for (i = 0; i < (sizeof(struct dmae_command)/4); i++) {
- REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i));
-
- DP(BNX2X_MSG_OFF, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n",
- idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i));
- }
- REG_WR(bp, dmae_reg_go_c[idx], 1);
-}
-
-void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
- u32 len32)
-{
- struct dmae_command *dmae = &bp->init_dmae;
- u32 *wb_comp = bnx2x_sp(bp, wb_comp);
- int cnt = 200;
-
- if (!bp->dmae_ready) {
- u32 *data = bnx2x_sp(bp, wb_data[0]);
-
- DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)"
- " using indirect\n", dst_addr, len32);
- bnx2x_init_ind_wr(bp, dst_addr, data, len32);
- return;
- }
-
- mutex_lock(&bp->dmae_mutex);
-
- memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
- dmae->src_addr_lo = U64_LO(dma_addr);
- dmae->src_addr_hi = U64_HI(dma_addr);
- dmae->dst_addr_lo = dst_addr >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = len32;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_val = DMAE_COMP_VAL;
-
- DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
- DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
- "dst_addr [%x:%08x (%08x)]\n"
- DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
- dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
- dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
- DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
- bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
- bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
-
- *wb_comp = 0;
-
- bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
-
- udelay(5);
-
- while (*wb_comp != DMAE_COMP_VAL) {
- DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
-
- if (!cnt) {
- BNX2X_ERR("dmae timeout!\n");
- break;
- }
- cnt--;
- /* adjust delay for emulation/FPGA */
- if (CHIP_REV_IS_SLOW(bp))
- msleep(100);
- else
- udelay(5);
- }
-
- mutex_unlock(&bp->dmae_mutex);
-}
-
-void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
-{
- struct dmae_command *dmae = &bp->init_dmae;
- u32 *wb_comp = bnx2x_sp(bp, wb_comp);
- int cnt = 200;
-
- if (!bp->dmae_ready) {
- u32 *data = bnx2x_sp(bp, wb_data[0]);
- int i;
-
- DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x len32 %d)"
- " using indirect\n", src_addr, len32);
- for (i = 0; i < len32; i++)
- data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4);
- return;
- }
-
- mutex_lock(&bp->dmae_mutex);
-
- memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
- memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
- dmae->src_addr_lo = src_addr >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
- dmae->len = len32;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
- dmae->comp_val = DMAE_COMP_VAL;
-
- DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
- DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
- "dst_addr [%x:%08x (%08x)]\n"
- DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
- dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
- dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
-
- *wb_comp = 0;
-
- bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
-
- udelay(5);
-
- while (*wb_comp != DMAE_COMP_VAL) {
-
- if (!cnt) {
- BNX2X_ERR("dmae timeout!\n");
- break;
- }
- cnt--;
- /* adjust delay for emulation/FPGA */
- if (CHIP_REV_IS_SLOW(bp))
- msleep(100);
- else
- udelay(5);
- }
- DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
- bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
- bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
-
- mutex_unlock(&bp->dmae_mutex);
-}
-
-/* used only for slowpath so not inlined */
-static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
-{
- u32 wb_write[2];
-
- wb_write[0] = val_hi;
- wb_write[1] = val_lo;
- REG_WR_DMAE(bp, reg, wb_write, 2);
-}
-
-#ifdef USE_WB_RD
-static u64 bnx2x_wb_rd(struct bnx2x *bp, int reg)
-{
- u32 wb_data[2];
-
- REG_RD_DMAE(bp, reg, wb_data, 2);
-
- return HILO_U64(wb_data[0], wb_data[1]);
-}
-#endif
-
-static int bnx2x_mc_assert(struct bnx2x *bp)
-{
- char last_idx;
- int i, rc = 0;
- u32 row0, row1, row2, row3;
-
- /* XSTORM */
- last_idx = REG_RD8(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ASSERT_LIST_INDEX_OFFSET);
- if (last_idx)
- BNX2X_ERR("XSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
-
- /* print the asserts */
- for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
-
- row0 = REG_RD(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ASSERT_LIST_OFFSET(i));
- row1 = REG_RD(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ASSERT_LIST_OFFSET(i) + 4);
- row2 = REG_RD(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ASSERT_LIST_OFFSET(i) + 8);
- row3 = REG_RD(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ASSERT_LIST_OFFSET(i) + 12);
-
- if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_ERR("XSTORM_ASSERT_INDEX 0x%x = 0x%08x"
- " 0x%08x 0x%08x 0x%08x\n",
- i, row3, row2, row1, row0);
- rc++;
- } else {
- break;
- }
- }
-
- /* TSTORM */
- last_idx = REG_RD8(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ASSERT_LIST_INDEX_OFFSET);
- if (last_idx)
- BNX2X_ERR("TSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
-
- /* print the asserts */
- for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
-
- row0 = REG_RD(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ASSERT_LIST_OFFSET(i));
- row1 = REG_RD(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ASSERT_LIST_OFFSET(i) + 4);
- row2 = REG_RD(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ASSERT_LIST_OFFSET(i) + 8);
- row3 = REG_RD(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ASSERT_LIST_OFFSET(i) + 12);
-
- if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_ERR("TSTORM_ASSERT_INDEX 0x%x = 0x%08x"
- " 0x%08x 0x%08x 0x%08x\n",
- i, row3, row2, row1, row0);
- rc++;
- } else {
- break;
- }
- }
-
- /* CSTORM */
- last_idx = REG_RD8(bp, BAR_CSTRORM_INTMEM +
- CSTORM_ASSERT_LIST_INDEX_OFFSET);
- if (last_idx)
- BNX2X_ERR("CSTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
-
- /* print the asserts */
- for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
-
- row0 = REG_RD(bp, BAR_CSTRORM_INTMEM +
- CSTORM_ASSERT_LIST_OFFSET(i));
- row1 = REG_RD(bp, BAR_CSTRORM_INTMEM +
- CSTORM_ASSERT_LIST_OFFSET(i) + 4);
- row2 = REG_RD(bp, BAR_CSTRORM_INTMEM +
- CSTORM_ASSERT_LIST_OFFSET(i) + 8);
- row3 = REG_RD(bp, BAR_CSTRORM_INTMEM +
- CSTORM_ASSERT_LIST_OFFSET(i) + 12);
-
- if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_ERR("CSTORM_ASSERT_INDEX 0x%x = 0x%08x"
- " 0x%08x 0x%08x 0x%08x\n",
- i, row3, row2, row1, row0);
- rc++;
- } else {
- break;
- }
- }
-
- /* USTORM */
- last_idx = REG_RD8(bp, BAR_USTRORM_INTMEM +
- USTORM_ASSERT_LIST_INDEX_OFFSET);
- if (last_idx)
- BNX2X_ERR("USTORM_ASSERT_LIST_INDEX 0x%x\n", last_idx);
-
- /* print the asserts */
- for (i = 0; i < STROM_ASSERT_ARRAY_SIZE; i++) {
-
- row0 = REG_RD(bp, BAR_USTRORM_INTMEM +
- USTORM_ASSERT_LIST_OFFSET(i));
- row1 = REG_RD(bp, BAR_USTRORM_INTMEM +
- USTORM_ASSERT_LIST_OFFSET(i) + 4);
- row2 = REG_RD(bp, BAR_USTRORM_INTMEM +
- USTORM_ASSERT_LIST_OFFSET(i) + 8);
- row3 = REG_RD(bp, BAR_USTRORM_INTMEM +
- USTORM_ASSERT_LIST_OFFSET(i) + 12);
-
- if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
- BNX2X_ERR("USTORM_ASSERT_INDEX 0x%x = 0x%08x"
- " 0x%08x 0x%08x 0x%08x\n",
- i, row3, row2, row1, row0);
- rc++;
- } else {
- break;
- }
- }
-
- return rc;
-}
-
-static void bnx2x_fw_dump(struct bnx2x *bp)
-{
- u32 mark, offset;
- u32 data[9];
- int word;
-
- mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
- mark = ((mark + 0x3) & ~0x3);
- printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n" KERN_ERR, mark);
-
- for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
- for (word = 0; word < 8; word++)
- data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
- offset + 4*word));
- data[8] = 0x0;
- printk(KERN_CONT "%s", (char *)data);
- }
- for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
- for (word = 0; word < 8; word++)
- data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
- offset + 4*word));
- data[8] = 0x0;
- printk(KERN_CONT "%s", (char *)data);
- }
- printk("\n" KERN_ERR PFX "end of fw dump\n");
-}
-
-static void bnx2x_panic_dump(struct bnx2x *bp)
-{
- int i;
- u16 j, start, end;
-
- bp->stats_state = STATS_STATE_DISABLED;
- DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
-
- BNX2X_ERR("begin crash dump -----------------\n");
-
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
- struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
-
- BNX2X_ERR("queue[%d]: tx_pkt_prod(%x) tx_pkt_cons(%x)"
- " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n",
- i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
- fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
- BNX2X_ERR(" rx_bd_prod(%x) rx_bd_cons(%x)"
- " *rx_bd_cons_sb(%x) rx_comp_prod(%x)"
- " rx_comp_cons(%x) *rx_cons_sb(%x)\n",
- fp->rx_bd_prod, fp->rx_bd_cons,
- le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod,
- fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb));
- BNX2X_ERR(" rx_sge_prod(%x) last_max_sge(%x)"
- " fp_c_idx(%x) *sb_c_idx(%x) fp_u_idx(%x)"
- " *sb_u_idx(%x) bd data(%x,%x)\n",
- fp->rx_sge_prod, fp->last_max_sge, fp->fp_c_idx,
- fp->status_blk->c_status_block.status_block_index,
- fp->fp_u_idx,
- fp->status_blk->u_status_block.status_block_index,
- hw_prods->packets_prod, hw_prods->bds_prod);
-
- start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
- end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
- for (j = start; j < end; j++) {
- struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
-
- BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
- sw_bd->skb, sw_bd->first_bd);
- }
-
- start = TX_BD(fp->tx_bd_cons - 10);
- end = TX_BD(fp->tx_bd_cons + 254);
- for (j = start; j < end; j++) {
- u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
-
- BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
- j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
- }
-
- start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
- end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
- for (j = start; j < end; j++) {
- u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
- struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
-
- BNX2X_ERR("rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
- j, rx_bd[1], rx_bd[0], sw_bd->skb);
- }
-
- start = RX_SGE(fp->rx_sge_prod);
- end = RX_SGE(fp->last_max_sge);
- for (j = start; j < end; j++) {
- u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j];
- struct sw_rx_page *sw_page = &fp->rx_page_ring[j];
-
- BNX2X_ERR("rx_sge[%x]=[%x:%x] sw_page=[%p]\n",
- j, rx_sge[1], rx_sge[0], sw_page->page);
- }
-
- start = RCQ_BD(fp->rx_comp_cons - 10);
- end = RCQ_BD(fp->rx_comp_cons + 503);
- for (j = start; j < end; j++) {
- u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
-
- BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
- j, cqe[0], cqe[1], cqe[2], cqe[3]);
- }
- }
-
- BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
- " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
- " spq_prod_idx(%u)\n",
- bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
- bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
-
- bnx2x_fw_dump(bp);
- bnx2x_mc_assert(bp);
- BNX2X_ERR("end crash dump -----------------\n");
-}
-
-static void bnx2x_int_enable(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
- u32 val = REG_RD(bp, addr);
- int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
-
- if (msix) {
- val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0;
- val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
- HC_CONFIG_0_REG_ATTN_BIT_EN_0);
- } else {
- val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
- HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
- HC_CONFIG_0_REG_INT_LINE_EN_0 |
- HC_CONFIG_0_REG_ATTN_BIT_EN_0);
-
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
-
- REG_WR(bp, addr, val);
-
- val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
- }
-
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
-
- REG_WR(bp, addr, val);
-
- if (CHIP_IS_E1H(bp)) {
- /* init leading/trailing edge */
- if (IS_E1HMF(bp)) {
- val = (0xfe0f | (1 << (BP_E1HVN(bp) + 4)));
- if (bp->port.pmf)
- /* enable nig attention */
- val |= 0x0100;
- } else
- val = 0xffff;
-
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
- }
-}
-
-static void bnx2x_int_disable(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
- u32 val = REG_RD(bp, addr);
-
- val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
- HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
- HC_CONFIG_0_REG_INT_LINE_EN_0 |
- HC_CONFIG_0_REG_ATTN_BIT_EN_0);
-
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
- val, port, addr);
-
- REG_WR(bp, addr, val);
- if (REG_RD(bp, addr) != val)
- BNX2X_ERR("BUG! proper val not read from IGU!\n");
-}
-
-static void bnx2x_int_disable_sync(struct bnx2x *bp)
-{
- int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
- int i;
-
- /* disable interrupt handling */
- atomic_inc(&bp->intr_sem);
- /* prevent the HW from sending interrupts */
- bnx2x_int_disable(bp);
-
- /* make sure all ISRs are done */
- if (msix) {
- for_each_queue(bp, i)
- synchronize_irq(bp->msix_table[i].vector);
-
- /* one more for the Slow Path IRQ */
- synchronize_irq(bp->msix_table[i].vector);
- } else
- synchronize_irq(bp->pdev->irq);
-
- /* make sure sp_task is not running */
- cancel_work_sync(&bp->sp_task);
-}
-
-/* fast path */
-
-/*
- * General service functions
- */
-
-static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
- u8 storm, u16 index, u8 op, u8 update)
-{
- u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
- COMMAND_REG_INT_ACK);
- struct igu_ack_register igu_ack;
-
- igu_ack.status_block_index = index;
- igu_ack.sb_id_and_flags =
- ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
- (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) |
- (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
- (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
-
- DP(BNX2X_MSG_OFF, "write 0x%08x to HC addr 0x%x\n",
- (*(u32 *)&igu_ack), hc_addr);
- REG_WR(bp, hc_addr, (*(u32 *)&igu_ack));
-}
-
-static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
-{
- struct host_status_block *fpsb = fp->status_blk;
- u16 rc = 0;
-
- barrier(); /* status block is written to by the chip */
- if (fp->fp_c_idx != fpsb->c_status_block.status_block_index) {
- fp->fp_c_idx = fpsb->c_status_block.status_block_index;
- rc |= 1;
- }
- if (fp->fp_u_idx != fpsb->u_status_block.status_block_index) {
- fp->fp_u_idx = fpsb->u_status_block.status_block_index;
- rc |= 2;
- }
- return rc;
-}
-
-static u16 bnx2x_ack_int(struct bnx2x *bp)
-{
- u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
- COMMAND_REG_SIMD_MASK);
- u32 result = REG_RD(bp, hc_addr);
-
- DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n",
- result, hc_addr);
-
- return result;
-}
-
-
-/*
- * fast path service functions
- */
-
-/* free skb in the packet ring at pos idx
- * return idx of last bd freed
- */
-static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
- u16 idx)
-{
- struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx];
- struct eth_tx_bd *tx_bd;
- struct sk_buff *skb = tx_buf->skb;
- u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
- int nbd;
-
- DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n",
- idx, tx_buf, skb);
-
- /* unmap first bd */
- DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx);
- tx_bd = &fp->tx_desc_ring[bd_idx];
- pci_unmap_single(bp->pdev, BD_UNMAP_ADDR(tx_bd),
- BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
-
- nbd = le16_to_cpu(tx_bd->nbd) - 1;
- new_cons = nbd + tx_buf->first_bd;
-#ifdef BNX2X_STOP_ON_ERROR
- if (nbd > (MAX_SKB_FRAGS + 2)) {
- BNX2X_ERR("BAD nbd!\n");
- bnx2x_panic();
- }
-#endif
-
- /* Skip a parse bd and the TSO split header bd
- since they have no mapping */
- if (nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
-
- if (tx_bd->bd_flags.as_bitfield & (ETH_TX_BD_FLAGS_IP_CSUM |
- ETH_TX_BD_FLAGS_TCP_CSUM |
- ETH_TX_BD_FLAGS_SW_LSO)) {
- if (--nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
- tx_bd = &fp->tx_desc_ring[bd_idx];
- /* is this a TSO split header bd? */
- if (tx_bd->bd_flags.as_bitfield & ETH_TX_BD_FLAGS_SW_LSO) {
- if (--nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
- }
- }
-
- /* now free frags */
- while (nbd > 0) {
-
- DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx);
- tx_bd = &fp->tx_desc_ring[bd_idx];
- pci_unmap_page(bp->pdev, BD_UNMAP_ADDR(tx_bd),
- BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
- if (--nbd)
- bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
- }
-
- /* release skb */
- WARN_ON(!skb);
- dev_kfree_skb(skb);
- tx_buf->first_bd = 0;
- tx_buf->skb = NULL;
-
- return new_cons;
-}
-
-static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
-{
- s16 used;
- u16 prod;
- u16 cons;
-
- barrier(); /* Tell compiler that prod and cons can change */
- prod = fp->tx_bd_prod;
- cons = fp->tx_bd_cons;
-
- /* NUM_TX_RINGS = number of "next-page" entries
- It will be used as a threshold */
- used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS;
-
-#ifdef BNX2X_STOP_ON_ERROR
- WARN_ON(used < 0);
- WARN_ON(used > fp->bp->tx_ring_size);
- WARN_ON((fp->bp->tx_ring_size - used) > MAX_TX_AVAIL);
-#endif
-
- return (s16)(fp->bp->tx_ring_size) - used;
-}
-
-static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
-{
- struct bnx2x *bp = fp->bp;
- u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons;
- int done = 0;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return;
-#endif
-
- hw_cons = le16_to_cpu(*fp->tx_cons_sb);
- sw_cons = fp->tx_pkt_cons;
-
- while (sw_cons != hw_cons) {
- u16 pkt_cons;
-
- pkt_cons = TX_BD(sw_cons);
-
- /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */
-
- DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n",
- hw_cons, sw_cons, pkt_cons);
-
-/* if (NEXT_TX_IDX(sw_cons) != hw_cons) {
- rmb();
- prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb);
- }
-*/
- bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
- sw_cons++;
- done++;
-
- if (done == work)
- break;
- }
-
- fp->tx_pkt_cons = sw_cons;
- fp->tx_bd_cons = bd_cons;
-
- /* Need to make the tx_cons update visible to start_xmit()
- * before checking for netif_queue_stopped(). Without the
- * memory barrier, there is a small possibility that start_xmit()
- * will miss it and cause the queue to be stopped forever.
- */
- smp_mb();
-
- /* TBD need a thresh? */
- if (unlikely(netif_queue_stopped(bp->dev))) {
-
- netif_tx_lock(bp->dev);
-
- if (netif_queue_stopped(bp->dev) &&
- (bp->state == BNX2X_STATE_OPEN) &&
- (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
- netif_wake_queue(bp->dev);
-
- netif_tx_unlock(bp->dev);
- }
-}
-
-
-static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
- union eth_rx_cqe *rr_cqe)
-{
- struct bnx2x *bp = fp->bp;
- int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data);
- int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data);
-
- DP(BNX2X_MSG_SP,
- "fp %d cid %d got ramrod #%d state is %x type is %d\n",
- FP_IDX(fp), cid, command, bp->state,
- rr_cqe->ramrod_cqe.ramrod_type);
-
- bp->spq_left++;
-
- if (FP_IDX(fp)) {
- switch (command | fp->state) {
- case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
- BNX2X_FP_STATE_OPENING):
- DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n",
- cid);
- fp->state = BNX2X_FP_STATE_OPEN;
- break;
-
- case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING):
- DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n",
- cid);
- fp->state = BNX2X_FP_STATE_HALTED;
- break;
-
- default:
- BNX2X_ERR("unexpected MC reply (%d) "
- "fp->state is %x\n", command, fp->state);
- break;
- }
- mb(); /* force bnx2x_wait_ramrod() to see the change */
- return;
- }
-
- switch (command | bp->state) {
- case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
- DP(NETIF_MSG_IFUP, "got setup ramrod\n");
- bp->state = BNX2X_STATE_OPEN;
- break;
-
- case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got halt ramrod\n");
- bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE;
- fp->state = BNX2X_FP_STATE_HALTED;
- break;
-
- case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
- bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED;
- break;
-
-
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG):
- DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
- bp->set_mac_pending = 0;
- break;
-
- case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
- DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
- break;
-
- default:
- BNX2X_ERR("unexpected MC reply (%d) bp->state is %x\n",
- command, bp->state);
- break;
- }
- mb(); /* force bnx2x_wait_ramrod() to see the change */
-}
-
-static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
- struct bnx2x_fastpath *fp, u16 index)
-{
- struct sw_rx_page *sw_buf = &fp->rx_page_ring[index];
- struct page *page = sw_buf->page;
- struct eth_rx_sge *sge = &fp->rx_sge_ring[index];
-
- /* Skip "next page" elements */
- if (!page)
- return;
-
- pci_unmap_page(bp->pdev, pci_unmap_addr(sw_buf, mapping),
- BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE);
- __free_pages(page, PAGES_PER_SGE_SHIFT);
-
- sw_buf->page = NULL;
- sge->addr_hi = 0;
- sge->addr_lo = 0;
-}
-
-static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
- struct bnx2x_fastpath *fp, int last)
-{
- int i;
-
- for (i = 0; i < last; i++)
- bnx2x_free_rx_sge(bp, fp, i);
-}
-
-static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp,
- struct bnx2x_fastpath *fp, u16 index)
-{
- struct page *page = alloc_pages(GFP_ATOMIC, PAGES_PER_SGE_SHIFT);
- struct sw_rx_page *sw_buf = &fp->rx_page_ring[index];
- struct eth_rx_sge *sge = &fp->rx_sge_ring[index];
- dma_addr_t mapping;
-
- if (unlikely(page == NULL))
- return -ENOMEM;
-
- mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE,
- PCI_DMA_FROMDEVICE);
- if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
- __free_pages(page, PAGES_PER_SGE_SHIFT);
- return -ENOMEM;
- }
-
- sw_buf->page = page;
- pci_unmap_addr_set(sw_buf, mapping, mapping);
-
- sge->addr_hi = cpu_to_le32(U64_HI(mapping));
- sge->addr_lo = cpu_to_le32(U64_LO(mapping));
-
- return 0;
-}
-
-static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
- struct bnx2x_fastpath *fp, u16 index)
-{
- struct sk_buff *skb;
- struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index];
- struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
- dma_addr_t mapping;
-
- skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
- if (unlikely(skb == NULL))
- return -ENOMEM;
-
- mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
- if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
- dev_kfree_skb(skb);
- return -ENOMEM;
- }
-
- rx_buf->skb = skb;
- pci_unmap_addr_set(rx_buf, mapping, mapping);
-
- rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
-
- return 0;
-}
-
-/* note that we are not allocating a new skb,
- * we are just moving one from cons to prod
- * we are not creating a new mapping,
- * so there is no need to check for dma_mapping_error().
- */
-static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
- struct sk_buff *skb, u16 cons, u16 prod)
-{
- struct bnx2x *bp = fp->bp;
- struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
- struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
- struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons];
- struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
-
- pci_dma_sync_single_for_device(bp->pdev,
- pci_unmap_addr(cons_rx_buf, mapping),
- bp->rx_offset + RX_COPY_THRESH,
- PCI_DMA_FROMDEVICE);
-
- prod_rx_buf->skb = cons_rx_buf->skb;
- pci_unmap_addr_set(prod_rx_buf, mapping,
- pci_unmap_addr(cons_rx_buf, mapping));
- *prod_bd = *cons_bd;
-}
-
-static inline void bnx2x_update_last_max_sge(struct bnx2x_fastpath *fp,
- u16 idx)
-{
- u16 last_max = fp->last_max_sge;
-
- if (SUB_S16(idx, last_max) > 0)
- fp->last_max_sge = idx;
-}
-
-static void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp)
-{
- int i, j;
-
- for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
- int idx = RX_SGE_CNT * i - 1;
-
- for (j = 0; j < 2; j++) {
- SGE_MASK_CLEAR_BIT(fp, idx);
- idx--;
- }
- }
-}
-
-static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp,
- struct eth_fast_path_rx_cqe *fp_cqe)
-{
- struct bnx2x *bp = fp->bp;
- u16 sge_len = BCM_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) -
- le16_to_cpu(fp_cqe->len_on_bd)) >>
- BCM_PAGE_SHIFT;
- u16 last_max, last_elem, first_elem;
- u16 delta = 0;
- u16 i;
-
- if (!sge_len)
- return;
-
- /* First mark all used pages */
- for (i = 0; i < sge_len; i++)
- SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i])));
-
- DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n",
- sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1]));
-
- /* Here we assume that the last SGE index is the biggest */
- prefetch((void *)(fp->sge_mask));
- bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1]));
-
- last_max = RX_SGE(fp->last_max_sge);
- last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT;
- first_elem = RX_SGE(fp->rx_sge_prod) >> RX_SGE_MASK_ELEM_SHIFT;
-
- /* If ring is not full */
- if (last_elem + 1 != first_elem)
- last_elem++;
-
- /* Now update the prod */
- for (i = first_elem; i != last_elem; i = NEXT_SGE_MASK_ELEM(i)) {
- if (likely(fp->sge_mask[i]))
- break;
-
- fp->sge_mask[i] = RX_SGE_MASK_ELEM_ONE_MASK;
- delta += RX_SGE_MASK_ELEM_SZ;
- }
-
- if (delta > 0) {
- fp->rx_sge_prod += delta;
- /* clear page-end entries */
- bnx2x_clear_sge_mask_next_elems(fp);
- }
-
- DP(NETIF_MSG_RX_STATUS,
- "fp->last_max_sge = %d fp->rx_sge_prod = %d\n",
- fp->last_max_sge, fp->rx_sge_prod);
-}
-
-static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp)
-{
- /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */
- memset(fp->sge_mask, 0xff,
- (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64));
-
- /* Clear the two last indices in the page to 1:
- these are the indices that correspond to the "next" element,
- hence will never be indicated and should be removed from
- the calculations. */
- bnx2x_clear_sge_mask_next_elems(fp);
-}
-
-static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
- struct sk_buff *skb, u16 cons, u16 prod)
-{
- struct bnx2x *bp = fp->bp;
- struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
- struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
- struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
- dma_addr_t mapping;
-
- /* move empty skb from pool to prod and map it */
- prod_rx_buf->skb = fp->tpa_pool[queue].skb;
- mapping = pci_map_single(bp->pdev, fp->tpa_pool[queue].skb->data,
- bp->rx_buf_size, PCI_DMA_FROMDEVICE);
- pci_unmap_addr_set(prod_rx_buf, mapping, mapping);
-
- /* move partial skb from cons to pool (don't unmap yet) */
- fp->tpa_pool[queue] = *cons_rx_buf;
-
- /* mark bin state as start - print error if current state != stop */
- if (fp->tpa_state[queue] != BNX2X_TPA_STOP)
- BNX2X_ERR("start of bin not in stop [%d]\n", queue);
-
- fp->tpa_state[queue] = BNX2X_TPA_START;
-
- /* point prod_bd to new skb */
- prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
-
-#ifdef BNX2X_STOP_ON_ERROR
- fp->tpa_queue_used |= (1 << queue);
-#ifdef __powerpc64__
- DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n",
-#else
- DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n",
-#endif
- fp->tpa_queue_used);
-#endif
-}
-
-static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
- struct sk_buff *skb,
- struct eth_fast_path_rx_cqe *fp_cqe,
- u16 cqe_idx)
-{
- struct sw_rx_page *rx_pg, old_rx_pg;
- struct page *sge;
- u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd);
- u32 i, frag_len, frag_size, pages;
- int err;
- int j;
-
- frag_size = le16_to_cpu(fp_cqe->pkt_len) - len_on_bd;
- pages = BCM_PAGE_ALIGN(frag_size) >> BCM_PAGE_SHIFT;
-
- /* This is needed in order to enable forwarding support */
- if (frag_size)
- skb_shinfo(skb)->gso_size = min((u32)BCM_PAGE_SIZE,
- max(frag_size, (u32)len_on_bd));
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (pages > 8*PAGES_PER_SGE) {
- BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n",
- pages, cqe_idx);
- BNX2X_ERR("fp_cqe->pkt_len = %d fp_cqe->len_on_bd = %d\n",
- fp_cqe->pkt_len, len_on_bd);
- bnx2x_panic();
- return -EINVAL;
- }
-#endif
-
- /* Run through the SGL and compose the fragmented skb */
- for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) {
- u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j]));
-
- /* FW gives the indices of the SGE as if the ring is an array
- (meaning that "next" element will consume 2 indices) */
- frag_len = min(frag_size, (u32)(BCM_PAGE_SIZE*PAGES_PER_SGE));
- rx_pg = &fp->rx_page_ring[sge_idx];
- sge = rx_pg->page;
- old_rx_pg = *rx_pg;
-
- /* If we fail to allocate a substitute page, we simply stop
- where we are and drop the whole packet */
- err = bnx2x_alloc_rx_sge(bp, fp, sge_idx);
- if (unlikely(err)) {
- bp->eth_stats.rx_skb_alloc_failed++;
- return err;
- }
-
- /* Unmap the page as we r going to pass it to the stack */
- pci_unmap_page(bp->pdev, pci_unmap_addr(&old_rx_pg, mapping),
- BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE);
-
- /* Add one frag and update the appropriate fields in the skb */
- skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len);
-
- skb->data_len += frag_len;
- skb->truesize += frag_len;
- skb->len += frag_len;
-
- frag_size -= frag_len;
- }
-
- return 0;
-}
-
-static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
- u16 queue, int pad, int len, union eth_rx_cqe *cqe,
- u16 cqe_idx)
-{
- struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue];
- struct sk_buff *skb = rx_buf->skb;
- /* alloc new skb */
- struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
-
- /* Unmap skb in the pool anyway, as we are going to change
- pool entry status to BNX2X_TPA_STOP even if new skb allocation
- fails. */
- pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size, PCI_DMA_FROMDEVICE);
-
- if (likely(new_skb)) {
- /* fix ip xsum and give it to the stack */
- /* (no need to map the new skb) */
-
- prefetch(skb);
- prefetch(((char *)(skb)) + 128);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (pad + len > bp->rx_buf_size) {
- BNX2X_ERR("skb_put is about to fail... "
- "pad %d len %d rx_buf_size %d\n",
- pad, len, bp->rx_buf_size);
- bnx2x_panic();
- return;
- }
-#endif
-
- skb_reserve(skb, pad);
- skb_put(skb, len);
-
- skb->protocol = eth_type_trans(skb, bp->dev);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-
- {
- struct iphdr *iph;
-
- iph = (struct iphdr *)skb->data;
- iph->check = 0;
- iph->check = ip_fast_csum((u8 *)iph, iph->ihl);
- }
-
- if (!bnx2x_fill_frag_skb(bp, fp, skb,
- &cqe->fast_path_cqe, cqe_idx)) {
-#ifdef BCM_VLAN
- if ((bp->vlgrp != NULL) &&
- (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
- PARSING_FLAGS_VLAN))
- vlan_hwaccel_receive_skb(skb, bp->vlgrp,
- le16_to_cpu(cqe->fast_path_cqe.
- vlan_tag));
- else
-#endif
- netif_receive_skb(skb);
- } else {
- DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages"
- " - dropping packet!\n");
- dev_kfree_skb(skb);
- }
-
- bp->dev->last_rx = jiffies;
-
- /* put new skb in bin */
- fp->tpa_pool[queue].skb = new_skb;
-
- } else {
- /* else drop the packet and keep the buffer in the bin */
- DP(NETIF_MSG_RX_STATUS,
- "Failed to allocate new skb - dropping packet!\n");
- bp->eth_stats.rx_skb_alloc_failed++;
- }
-
- fp->tpa_state[queue] = BNX2X_TPA_STOP;
-}
-
-static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
- struct bnx2x_fastpath *fp,
- u16 bd_prod, u16 rx_comp_prod,
- u16 rx_sge_prod)
-{
- struct tstorm_eth_rx_producers rx_prods = {0};
- int i;
-
- /* Update producers */
- rx_prods.bd_prod = bd_prod;
- rx_prods.cqe_prod = rx_comp_prod;
- rx_prods.sge_prod = rx_sge_prod;
-
- for (i = 0; i < sizeof(struct tstorm_eth_rx_producers)/4; i++)
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4,
- ((u32 *)&rx_prods)[i]);
-
- DP(NETIF_MSG_RX_STATUS,
- "Wrote: bd_prod %u cqe_prod %u sge_prod %u\n",
- bd_prod, rx_comp_prod, rx_sge_prod);
-}
-
-static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
-{
- struct bnx2x *bp = fp->bp;
- u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons;
- u16 hw_comp_cons, sw_comp_cons, sw_comp_prod;
- int rx_pkt = 0;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return 0;
-#endif
-
- /* CQ "next element" is of the size of the regular element,
- that's why it's ok here */
- hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb);
- if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- hw_comp_cons++;
-
- bd_cons = fp->rx_bd_cons;
- bd_prod = fp->rx_bd_prod;
- bd_prod_fw = bd_prod;
- sw_comp_cons = fp->rx_comp_cons;
- sw_comp_prod = fp->rx_comp_prod;
-
- /* Memory barrier necessary as speculative reads of the rx
- * buffer can be ahead of the index in the status block
- */
- rmb();
-
- DP(NETIF_MSG_RX_STATUS,
- "queue[%d]: hw_comp_cons %u sw_comp_cons %u\n",
- FP_IDX(fp), hw_comp_cons, sw_comp_cons);
-
- while (sw_comp_cons != hw_comp_cons) {
- struct sw_rx_bd *rx_buf = NULL;
- struct sk_buff *skb;
- union eth_rx_cqe *cqe;
- u8 cqe_fp_flags;
- u16 len, pad;
-
- comp_ring_cons = RCQ_BD(sw_comp_cons);
- bd_prod = RX_BD(bd_prod);
- bd_cons = RX_BD(bd_cons);
-
- cqe = &fp->rx_comp_ring[comp_ring_cons];
- cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
-
- DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x"
- " queue %x vlan %x len %u\n", CQE_TYPE(cqe_fp_flags),
- cqe_fp_flags, cqe->fast_path_cqe.status_flags,
- cqe->fast_path_cqe.rss_hash_result,
- le16_to_cpu(cqe->fast_path_cqe.vlan_tag),
- le16_to_cpu(cqe->fast_path_cqe.pkt_len));
-
- /* is this a slowpath msg? */
- if (unlikely(CQE_TYPE(cqe_fp_flags))) {
- bnx2x_sp_event(fp, cqe);
- goto next_cqe;
-
- /* this is an rx packet */
- } else {
- rx_buf = &fp->rx_buf_ring[bd_cons];
- skb = rx_buf->skb;
- len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
- pad = cqe->fast_path_cqe.placement_offset;
-
- /* If CQE is marked both TPA_START and TPA_END
- it is a non-TPA CQE */
- if ((!fp->disable_tpa) &&
- (TPA_TYPE(cqe_fp_flags) !=
- (TPA_TYPE_START | TPA_TYPE_END))) {
- u16 queue = cqe->fast_path_cqe.queue_index;
-
- if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_START) {
- DP(NETIF_MSG_RX_STATUS,
- "calling tpa_start on queue %d\n",
- queue);
-
- bnx2x_tpa_start(fp, queue, skb,
- bd_cons, bd_prod);
- goto next_rx;
- }
-
- if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) {
- DP(NETIF_MSG_RX_STATUS,
- "calling tpa_stop on queue %d\n",
- queue);
-
- if (!BNX2X_RX_SUM_FIX(cqe))
- BNX2X_ERR("STOP on none TCP "
- "data\n");
-
- /* This is a size of the linear data
- on this skb */
- len = le16_to_cpu(cqe->fast_path_cqe.
- len_on_bd);
- bnx2x_tpa_stop(bp, fp, queue, pad,
- len, cqe, comp_ring_cons);
-#ifdef BNX2X_STOP_ON_ERROR
- if (bp->panic)
- return -EINVAL;
-#endif
-
- bnx2x_update_sge_prod(fp,
- &cqe->fast_path_cqe);
- goto next_cqe;
- }
- }
-
- pci_dma_sync_single_for_device(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- pad + RX_COPY_THRESH,
- PCI_DMA_FROMDEVICE);
- prefetch(skb);
- prefetch(((char *)(skb)) + 128);
-
- /* is this an error packet? */
- if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
- DP(NETIF_MSG_RX_ERR,
- "ERROR flags %x rx packet %u\n",
- cqe_fp_flags, sw_comp_cons);
- bp->eth_stats.rx_err_discard_pkt++;
- goto reuse_rx;
- }
-
- /* Since we don't have a jumbo ring
- * copy small packets if mtu > 1500
- */
- if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) &&
- (len <= RX_COPY_THRESH)) {
- struct sk_buff *new_skb;
-
- new_skb = netdev_alloc_skb(bp->dev,
- len + pad);
- if (new_skb == NULL) {
- DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped "
- "because of alloc failure\n");
- bp->eth_stats.rx_skb_alloc_failed++;
- goto reuse_rx;
- }
-
- /* aligned copy */
- skb_copy_from_linear_data_offset(skb, pad,
- new_skb->data + pad, len);
- skb_reserve(new_skb, pad);
- skb_put(new_skb, len);
-
- bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
-
- skb = new_skb;
-
- } else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) {
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
- skb_reserve(skb, pad);
- skb_put(skb, len);
-
- } else {
- DP(NETIF_MSG_RX_ERR,
- "ERROR packet dropped because "
- "of alloc failure\n");
- bp->eth_stats.rx_skb_alloc_failed++;
-reuse_rx:
- bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
- goto next_rx;
- }
-
- skb->protocol = eth_type_trans(skb, bp->dev);
-
- skb->ip_summed = CHECKSUM_NONE;
- if (bp->rx_csum) {
- if (likely(BNX2X_RX_CSUM_OK(cqe)))
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- bp->eth_stats.hw_csum_err++;
- }
- }
-
-#ifdef BCM_VLAN
- if ((bp->vlgrp != NULL) &&
- (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
- PARSING_FLAGS_VLAN))
- vlan_hwaccel_receive_skb(skb, bp->vlgrp,
- le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
- else
-#endif
- netif_receive_skb(skb);
-
- bp->dev->last_rx = jiffies;
-
-next_rx:
- rx_buf->skb = NULL;
-
- bd_cons = NEXT_RX_IDX(bd_cons);
- bd_prod = NEXT_RX_IDX(bd_prod);
- bd_prod_fw = NEXT_RX_IDX(bd_prod_fw);
- rx_pkt++;
-next_cqe:
- sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod);
- sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons);
-
- if (rx_pkt == budget)
- break;
- } /* while */
-
- fp->rx_bd_cons = bd_cons;
- fp->rx_bd_prod = bd_prod_fw;
- fp->rx_comp_cons = sw_comp_cons;
- fp->rx_comp_prod = sw_comp_prod;
-
- /* Update producers */
- bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod,
- fp->rx_sge_prod);
- mmiowb(); /* keep prod updates ordered */
-
- fp->rx_pkt += rx_pkt;
- fp->rx_calls++;
-
- return rx_pkt;
-}
-
-static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
-{
- struct bnx2x_fastpath *fp = fp_cookie;
- struct bnx2x *bp = fp->bp;
- struct net_device *dev = bp->dev;
- int index = FP_IDX(fp);
-
- /* Return here if interrupt is disabled */
- if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
- return IRQ_HANDLED;
- }
-
- DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
- index, FP_SB_ID(fp));
- bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return IRQ_HANDLED;
-#endif
-
- prefetch(fp->rx_cons_sb);
- prefetch(fp->tx_cons_sb);
- prefetch(&fp->status_blk->c_status_block.status_block_index);
- prefetch(&fp->status_blk->u_status_block.status_block_index);
-
- netif_rx_schedule(dev, &bnx2x_fp(bp, index, napi));
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
-{
- struct net_device *dev = dev_instance;
- struct bnx2x *bp = netdev_priv(dev);
- u16 status = bnx2x_ack_int(bp);
- u16 mask;
-
- /* Return here if interrupt is shared and it's not for us */
- if (unlikely(status == 0)) {
- DP(NETIF_MSG_INTR, "not our interrupt!\n");
- return IRQ_NONE;
- }
- DP(NETIF_MSG_INTR, "got an interrupt status %u\n", status);
-
- /* Return here if interrupt is disabled */
- if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
- return IRQ_HANDLED;
- }
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return IRQ_HANDLED;
-#endif
-
- mask = 0x2 << bp->fp[0].sb_id;
- if (status & mask) {
- struct bnx2x_fastpath *fp = &bp->fp[0];
-
- prefetch(fp->rx_cons_sb);
- prefetch(fp->tx_cons_sb);
- prefetch(&fp->status_blk->c_status_block.status_block_index);
- prefetch(&fp->status_blk->u_status_block.status_block_index);
-
- netif_rx_schedule(dev, &bnx2x_fp(bp, 0, napi));
-
- status &= ~mask;
- }
-
-
- if (unlikely(status & 0x1)) {
- schedule_work(&bp->sp_task);
-
- status &= ~0x1;
- if (!status)
- return IRQ_HANDLED;
- }
-
- if (status)
- DP(NETIF_MSG_INTR, "got an unknown interrupt! (status %u)\n",
- status);
-
- return IRQ_HANDLED;
-}
-
-/* end of fast path */
-
-static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
-
-/* Link */
-
-/*
- * General service functions
- */
-
-static int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource)
-{
- u32 lock_status;
- u32 resource_bit = (1 << resource);
- int func = BP_FUNC(bp);
- u32 hw_lock_control_reg;
- int cnt;
-
- /* Validating that the resource is within range */
- if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
- DP(NETIF_MSG_HW,
- "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
- resource, HW_LOCK_MAX_RESOURCE_VALUE);
- return -EINVAL;
- }
-
- if (func <= 5) {
- hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8);
- } else {
- hw_lock_control_reg =
- (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8);
- }
-
- /* Validating that the resource is not already taken */
- lock_status = REG_RD(bp, hw_lock_control_reg);
- if (lock_status & resource_bit) {
- DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
- lock_status, resource_bit);
- return -EEXIST;
- }
-
- /* Try for 5 second every 5ms */
- for (cnt = 0; cnt < 1000; cnt++) {
- /* Try to acquire the lock */
- REG_WR(bp, hw_lock_control_reg + 4, resource_bit);
- lock_status = REG_RD(bp, hw_lock_control_reg);
- if (lock_status & resource_bit)
- return 0;
-
- msleep(5);
- }
- DP(NETIF_MSG_HW, "Timeout\n");
- return -EAGAIN;
-}
-
-static int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource)
-{
- u32 lock_status;
- u32 resource_bit = (1 << resource);
- int func = BP_FUNC(bp);
- u32 hw_lock_control_reg;
-
- /* Validating that the resource is within range */
- if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
- DP(NETIF_MSG_HW,
- "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n",
- resource, HW_LOCK_MAX_RESOURCE_VALUE);
- return -EINVAL;
- }
-
- if (func <= 5) {
- hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + func*8);
- } else {
- hw_lock_control_reg =
- (MISC_REG_DRIVER_CONTROL_7 + (func - 6)*8);
- }
-
- /* Validating that the resource is currently taken */
- lock_status = REG_RD(bp, hw_lock_control_reg);
- if (!(lock_status & resource_bit)) {
- DP(NETIF_MSG_HW, "lock_status 0x%x resource_bit 0x%x\n",
- lock_status, resource_bit);
- return -EFAULT;
- }
-
- REG_WR(bp, hw_lock_control_reg, resource_bit);
- return 0;
-}
-
-/* HW Lock for shared dual port PHYs */
-static void bnx2x_acquire_phy_lock(struct bnx2x *bp)
-{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- mutex_lock(&bp->port.phy_mutex);
-
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
-}
-
-static void bnx2x_release_phy_lock(struct bnx2x *bp)
-{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
-
- mutex_unlock(&bp->port.phy_mutex);
-}
-
-int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
-{
- /* The GPIO should be swapped if swap register is set and active */
- int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
- REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
- int gpio_shift = gpio_num +
- (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
- u32 gpio_mask = (1 << gpio_shift);
- u32 gpio_reg;
-
- if (gpio_num > MISC_REGISTERS_GPIO_3) {
- BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
- return -EINVAL;
- }
-
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
- /* read GPIO and mask except the float bits */
- gpio_reg = (REG_RD(bp, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
-
- switch (mode) {
- case MISC_REGISTERS_GPIO_OUTPUT_LOW:
- DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output low\n",
- gpio_num, gpio_shift);
- /* clear FLOAT and set CLR */
- gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
- gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
- break;
-
- case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
- DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> output high\n",
- gpio_num, gpio_shift);
- /* clear FLOAT and set SET */
- gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
- gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
- break;
-
- case MISC_REGISTERS_GPIO_INPUT_HI_Z:
- DP(NETIF_MSG_LINK, "Set GPIO %d (shift %d) -> input\n",
- gpio_num, gpio_shift);
- /* set FLOAT */
- gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
- break;
-
- default:
- break;
- }
-
- REG_WR(bp, MISC_REG_GPIO, gpio_reg);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
-
- return 0;
-}
-
-static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
-{
- u32 spio_mask = (1 << spio_num);
- u32 spio_reg;
-
- if ((spio_num < MISC_REGISTERS_SPIO_4) ||
- (spio_num > MISC_REGISTERS_SPIO_7)) {
- BNX2X_ERR("Invalid SPIO %d\n", spio_num);
- return -EINVAL;
- }
-
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
- /* read SPIO and mask except the float bits */
- spio_reg = (REG_RD(bp, MISC_REG_SPIO) & MISC_REGISTERS_SPIO_FLOAT);
-
- switch (mode) {
- case MISC_REGISTERS_SPIO_OUTPUT_LOW:
- DP(NETIF_MSG_LINK, "Set SPIO %d -> output low\n", spio_num);
- /* clear FLOAT and set CLR */
- spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
- spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_CLR_POS);
- break;
-
- case MISC_REGISTERS_SPIO_OUTPUT_HIGH:
- DP(NETIF_MSG_LINK, "Set SPIO %d -> output high\n", spio_num);
- /* clear FLOAT and set SET */
- spio_reg &= ~(spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
- spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_SET_POS);
- break;
-
- case MISC_REGISTERS_SPIO_INPUT_HI_Z:
- DP(NETIF_MSG_LINK, "Set SPIO %d -> input\n", spio_num);
- /* set FLOAT */
- spio_reg |= (spio_mask << MISC_REGISTERS_SPIO_FLOAT_POS);
- break;
-
- default:
- break;
- }
-
- REG_WR(bp, MISC_REG_SPIO, spio_reg);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_SPIO);
-
- return 0;
-}
-
-static void bnx2x_calc_fc_adv(struct bnx2x *bp)
-{
- switch (bp->link_vars.ieee_fc) {
- case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE:
- bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
- ADVERTISED_Pause);
- break;
- case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
- bp->port.advertising |= (ADVERTISED_Asym_Pause |
- ADVERTISED_Pause);
- break;
- case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
- bp->port.advertising |= ADVERTISED_Asym_Pause;
- break;
- default:
- bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
- ADVERTISED_Pause);
- break;
- }
-}
-
-static void bnx2x_link_report(struct bnx2x *bp)
-{
- if (bp->link_vars.link_up) {
- if (bp->state == BNX2X_STATE_OPEN)
- netif_carrier_on(bp->dev);
- printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
-
- printk("%d Mbps ", bp->link_vars.line_speed);
-
- if (bp->link_vars.duplex == DUPLEX_FULL)
- printk("full duplex");
- else
- printk("half duplex");
-
- if (bp->link_vars.flow_ctrl != FLOW_CTRL_NONE) {
- if (bp->link_vars.flow_ctrl & FLOW_CTRL_RX) {
- printk(", receive ");
- if (bp->link_vars.flow_ctrl & FLOW_CTRL_TX)
- printk("& transmit ");
- } else {
- printk(", transmit ");
- }
- printk("flow control ON");
- }
- printk("\n");
-
- } else { /* link_down */
- netif_carrier_off(bp->dev);
- printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
- }
-}
-
-static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
-{
- if (!BP_NOMCP(bp)) {
- u8 rc;
-
- /* Initialize link parameters structure variables */
- /* It is recommended to turn off RX FC for jumbo frames
- for better performance */
- if (IS_E1HMF(bp))
- bp->link_params.req_fc_auto_adv = FLOW_CTRL_BOTH;
- else if (bp->dev->mtu > 5000)
- bp->link_params.req_fc_auto_adv = FLOW_CTRL_TX;
- else
- bp->link_params.req_fc_auto_adv = FLOW_CTRL_BOTH;
-
- bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
-
- if (bp->link_vars.link_up)
- bnx2x_link_report(bp);
-
- bnx2x_calc_fc_adv(bp);
-
- return rc;
- }
- BNX2X_ERR("Bootcode is missing -not initializing link\n");
- return -EINVAL;
-}
-
-static void bnx2x_link_set(struct bnx2x *bp)
-{
- if (!BP_NOMCP(bp)) {
- bnx2x_acquire_phy_lock(bp);
- bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
-
- bnx2x_calc_fc_adv(bp);
- } else
- BNX2X_ERR("Bootcode is missing -not setting link\n");
-}
-
-static void bnx2x__link_reset(struct bnx2x *bp)
-{
- if (!BP_NOMCP(bp)) {
- bnx2x_acquire_phy_lock(bp);
- bnx2x_link_reset(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
- } else
- BNX2X_ERR("Bootcode is missing -not resetting link\n");
-}
-
-static u8 bnx2x_link_test(struct bnx2x *bp)
-{
- u8 rc;
-
- bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_test_link(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
-
- return rc;
-}
-
-/* Calculates the sum of vn_min_rates.
- It's needed for further normalizing of the min_rates.
-
- Returns:
- sum of vn_min_rates
- or
- 0 - if all the min_rates are 0.
- In the later case fairness algorithm should be deactivated.
- If not all min_rates are zero then those that are zeroes will
- be set to 1.
- */
-static u32 bnx2x_calc_vn_wsum(struct bnx2x *bp)
-{
- int i, port = BP_PORT(bp);
- u32 wsum = 0;
- int all_zero = 1;
-
- for (i = 0; i < E1HVN_MAX; i++) {
- u32 vn_cfg =
- SHMEM_RD(bp, mf_cfg.func_mf_config[2*i + port].config);
- u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
- FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- if (!(vn_cfg & FUNC_MF_CFG_FUNC_HIDE)) {
- /* If min rate is zero - set it to 1 */
- if (!vn_min_rate)
- vn_min_rate = DEF_MIN_RATE;
- else
- all_zero = 0;
-
- wsum += vn_min_rate;
- }
- }
-
- /* ... only if all min rates are zeros - disable FAIRNESS */
- if (all_zero)
- return 0;
-
- return wsum;
-}
-
-static void bnx2x_init_port_minmax(struct bnx2x *bp,
- int en_fness,
- u16 port_rate,
- struct cmng_struct_per_port *m_cmng_port)
-{
- u32 r_param = port_rate / 8;
- int port = BP_PORT(bp);
- int i;
-
- memset(m_cmng_port, 0, sizeof(struct cmng_struct_per_port));
-
- /* Enable minmax only if we are in e1hmf mode */
- if (IS_E1HMF(bp)) {
- u32 fair_periodic_timeout_usec;
- u32 t_fair;
-
- /* Enable rate shaping and fairness */
- m_cmng_port->flags.cmng_vn_enable = 1;
- m_cmng_port->flags.fairness_enable = en_fness ? 1 : 0;
- m_cmng_port->flags.rate_shaping_enable = 1;
-
- if (!en_fness)
- DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
- " fairness will be disabled\n");
-
- /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
- m_cmng_port->rs_vars.rs_periodic_timeout =
- RS_PERIODIC_TIMEOUT_USEC / 4;
-
- /* this is the threshold below which no timer arming will occur
- 1.25 coefficient is for the threshold to be a little bigger
- than the real time, to compensate for timer in-accuracy */
- m_cmng_port->rs_vars.rs_threshold =
- (RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
-
- /* resolution of fairness timer */
- fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
- /* for 10G it is 1000usec. for 1G it is 10000usec. */
- t_fair = T_FAIR_COEF / port_rate;
-
- /* this is the threshold below which we won't arm
- the timer anymore */
- m_cmng_port->fair_vars.fair_threshold = QM_ARB_BYTES;
-
- /* we multiply by 1e3/8 to get bytes/msec.
- We don't want the credits to pass a credit
- of the T_FAIR*FAIR_MEM (algorithm resolution) */
- m_cmng_port->fair_vars.upper_bound =
- r_param * t_fair * FAIR_MEM;
- /* since each tick is 4 usec */
- m_cmng_port->fair_vars.fairness_timeout =
- fair_periodic_timeout_usec / 4;
-
- } else {
- /* Disable rate shaping and fairness */
- m_cmng_port->flags.cmng_vn_enable = 0;
- m_cmng_port->flags.fairness_enable = 0;
- m_cmng_port->flags.rate_shaping_enable = 0;
-
- DP(NETIF_MSG_IFUP,
- "Single function mode minmax will be disabled\n");
- }
-
- /* Store it to internal memory */
- for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
- ((u32 *)(m_cmng_port))[i]);
-}
-
-static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
- u32 wsum, u16 port_rate,
- struct cmng_struct_per_port *m_cmng_port)
-{
- struct rate_shaping_vars_per_vn m_rs_vn;
- struct fairness_vars_per_vn m_fair_vn;
- u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
- u16 vn_min_rate, vn_max_rate;
- int i;
-
- /* If function is hidden - set min and max to zeroes */
- if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) {
- vn_min_rate = 0;
- vn_max_rate = 0;
-
- } else {
- vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
- FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- /* If FAIRNESS is enabled (not all min rates are zeroes) and
- if current min rate is zero - set it to 1.
- This is a requirement of the algorithm. */
- if ((vn_min_rate == 0) && wsum)
- vn_min_rate = DEF_MIN_RATE;
- vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
- FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
- }
-
- DP(NETIF_MSG_IFUP, "func %d: vn_min_rate=%d vn_max_rate=%d "
- "wsum=%d\n", func, vn_min_rate, vn_max_rate, wsum);
-
- memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
- memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
-
- /* global vn counter - maximal Mbps for this vn */
- m_rs_vn.vn_counter.rate = vn_max_rate;
-
- /* quota - number of bytes transmitted in this period */
- m_rs_vn.vn_counter.quota =
- (vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
-
-#ifdef BNX2X_PER_PROT_QOS
- /* per protocol counter */
- for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++) {
- /* maximal Mbps for this protocol */
- m_rs_vn.protocol_counters[protocol].rate =
- protocol_max_rate[protocol];
- /* the quota in each timer period -
- number of bytes transmitted in this period */
- m_rs_vn.protocol_counters[protocol].quota =
- (u32)(rs_periodic_timeout_usec *
- ((double)m_rs_vn.
- protocol_counters[protocol].rate/8));
- }
-#endif
-
- if (wsum) {
- /* credit for each period of the fairness algorithm:
- number of bytes in T_FAIR (the vn share the port rate).
- wsum should not be larger than 10000, thus
- T_FAIR_COEF / (8 * wsum) will always be grater than zero */
- m_fair_vn.vn_credit_delta =
- max((u64)(vn_min_rate * (T_FAIR_COEF / (8 * wsum))),
- (u64)(m_cmng_port->fair_vars.fair_threshold * 2));
- DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta=%d\n",
- m_fair_vn.vn_credit_delta);
- }
-
-#ifdef BNX2X_PER_PROT_QOS
- do {
- u32 protocolWeightSum = 0;
-
- for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++)
- protocolWeightSum +=
- drvInit.protocol_min_rate[protocol];
- /* per protocol counter -
- NOT NEEDED IF NO PER-PROTOCOL CONGESTION MANAGEMENT */
- if (protocolWeightSum > 0) {
- for (protocol = 0;
- protocol < NUM_OF_PROTOCOLS; protocol++)
- /* credit for each period of the
- fairness algorithm - number of bytes in
- T_FAIR (the protocol share the vn rate) */
- m_fair_vn.protocol_credit_delta[protocol] =
- (u32)((vn_min_rate / 8) * t_fair *
- protocol_min_rate / protocolWeightSum);
- }
- } while (0);
-#endif
-
- /* Store it to internal memory */
- for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func) + i * 4,
- ((u32 *)(&m_rs_vn))[i]);
-
- for (i = 0; i < sizeof(struct fairness_vars_per_vn)/4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4,
- ((u32 *)(&m_fair_vn))[i]);
-}
-
-/* This function is called upon link interrupt */
-static void bnx2x_link_attn(struct bnx2x *bp)
-{
- int vn;
-
- /* Make sure that we are synced with the current statistics */
- bnx2x_stats_handle(bp, STATS_EVENT_STOP);
-
- bnx2x_acquire_phy_lock(bp);
- bnx2x_link_update(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
-
- if (bp->link_vars.link_up) {
-
- if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
- struct host_port_stats *pstats;
-
- pstats = bnx2x_sp(bp, port_stats);
- /* reset old bmac stats */
- memset(&(pstats->mac_stx[0]), 0,
- sizeof(struct mac_stx));
- }
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED))
- bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
- }
-
- /* indicate link status */
- bnx2x_link_report(bp);
-
- if (IS_E1HMF(bp)) {
- int func;
-
- for (vn = VN_0; vn < E1HVN_MAX; vn++) {
- if (vn == BP_E1HVN(bp))
- continue;
-
- func = ((vn << 1) | BP_PORT(bp));
-
- /* Set the attention towards other drivers
- on the same port */
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
- (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
- }
- }
-
- if (CHIP_IS_E1H(bp) && (bp->link_vars.line_speed > 0)) {
- struct cmng_struct_per_port m_cmng_port;
- u32 wsum;
- int port = BP_PORT(bp);
-
- /* Init RATE SHAPING and FAIRNESS contexts */
- wsum = bnx2x_calc_vn_wsum(bp);
- bnx2x_init_port_minmax(bp, (int)wsum,
- bp->link_vars.line_speed,
- &m_cmng_port);
- if (IS_E1HMF(bp))
- for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port,
- wsum, bp->link_vars.line_speed,
- &m_cmng_port);
- }
-}
-
-static void bnx2x__link_status_update(struct bnx2x *bp)
-{
- if (bp->state != BNX2X_STATE_OPEN)
- return;
-
- bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
-
- if (bp->link_vars.link_up)
- bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
- else
- bnx2x_stats_handle(bp, STATS_EVENT_STOP);
-
- /* indicate link status */
- bnx2x_link_report(bp);
-}
-
-static void bnx2x_pmf_update(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- u32 val;
-
- bp->port.pmf = 1;
- DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
-
- /* enable nig attention */
- val = (0xff0f | (1 << (BP_E1HVN(bp) + 4)));
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
-
- bnx2x_stats_handle(bp, STATS_EVENT_PMF);
-}
-
-/* end of Link */
-
-/* slow path */
-
-/*
- * General service functions
- */
-
-/* the slow path queue is odd since completions arrive on the fastpath ring */
-static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
- u32 data_hi, u32 data_lo, int common)
-{
- int func = BP_FUNC(bp);
-
- DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
- "SPQE (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n",
- (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) +
- (void *)bp->spq_prod_bd - (void *)bp->spq), command,
- HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return -EIO;
-#endif
-
- spin_lock_bh(&bp->spq_lock);
-
- if (!bp->spq_left) {
- BNX2X_ERR("BUG! SPQ ring full!\n");
- spin_unlock_bh(&bp->spq_lock);
- bnx2x_panic();
- return -EBUSY;
- }
-
- /* CID needs port number to be encoded int it */
- bp->spq_prod_bd->hdr.conn_and_cmd_data =
- cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
- HW_CID(bp, cid)));
- bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
- if (common)
- bp->spq_prod_bd->hdr.type |=
- cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
-
- bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi);
- bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo);
-
- bp->spq_left--;
-
- if (bp->spq_prod_bd == bp->spq_last_bd) {
- bp->spq_prod_bd = bp->spq;
- bp->spq_prod_idx = 0;
- DP(NETIF_MSG_TIMER, "end of spq\n");
-
- } else {
- bp->spq_prod_bd++;
- bp->spq_prod_idx++;
- }
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
- bp->spq_prod_idx);
-
- spin_unlock_bh(&bp->spq_lock);
- return 0;
-}
-
-/* acquire split MCP access lock register */
-static int bnx2x_acquire_alr(struct bnx2x *bp)
-{
- u32 i, j, val;
- int rc = 0;
-
- might_sleep();
- i = 100;
- for (j = 0; j < i*10; j++) {
- val = (1UL << 31);
- REG_WR(bp, GRCBASE_MCP + 0x9c, val);
- val = REG_RD(bp, GRCBASE_MCP + 0x9c);
- if (val & (1L << 31))
- break;
-
- msleep(5);
- }
- if (!(val & (1L << 31))) {
- BNX2X_ERR("Cannot acquire MCP access lock register\n");
- rc = -EBUSY;
- }
-
- return rc;
-}
-
-/* release split MCP access lock register */
-static void bnx2x_release_alr(struct bnx2x *bp)
-{
- u32 val = 0;
-
- REG_WR(bp, GRCBASE_MCP + 0x9c, val);
-}
-
-static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
-{
- struct host_def_status_block *def_sb = bp->def_status_blk;
- u16 rc = 0;
-
- barrier(); /* status block is written to by the chip */
- if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) {
- bp->def_att_idx = def_sb->atten_status_block.attn_bits_index;
- rc |= 1;
- }
- if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) {
- bp->def_c_idx = def_sb->c_def_status_block.status_block_index;
- rc |= 2;
- }
- if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) {
- bp->def_u_idx = def_sb->u_def_status_block.status_block_index;
- rc |= 4;
- }
- if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) {
- bp->def_x_idx = def_sb->x_def_status_block.status_block_index;
- rc |= 8;
- }
- if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) {
- bp->def_t_idx = def_sb->t_def_status_block.status_block_index;
- rc |= 16;
- }
- return rc;
-}
-
-/*
- * slow path service functions
- */
-
-static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
-{
- int port = BP_PORT(bp);
- u32 hc_addr = (HC_REG_COMMAND_REG + port*32 +
- COMMAND_REG_ATTN_BITS_SET);
- u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
- MISC_REG_AEU_MASK_ATTN_FUNC_0;
- u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
- NIG_REG_MASK_INTERRUPT_PORT0;
- u32 aeu_mask;
-
- if (bp->attn_state & asserted)
- BNX2X_ERR("IGU ERROR\n");
-
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
- aeu_mask = REG_RD(bp, aeu_addr);
-
- DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n",
- aeu_mask, asserted);
- aeu_mask &= ~(asserted & 0xff);
- DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask);
-
- REG_WR(bp, aeu_addr, aeu_mask);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
-
- DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state);
- bp->attn_state |= asserted;
- DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state);
-
- if (asserted & ATTN_HARD_WIRED_MASK) {
- if (asserted & ATTN_NIG_FOR_FUNC) {
-
- /* save nig interrupt mask */
- bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
- REG_WR(bp, nig_int_mask_addr, 0);
-
- bnx2x_link_attn(bp);
-
- /* handle unicore attn? */
- }
- if (asserted & ATTN_SW_TIMER_4_FUNC)
- DP(NETIF_MSG_HW, "ATTN_SW_TIMER_4_FUNC!\n");
-
- if (asserted & GPIO_2_FUNC)
- DP(NETIF_MSG_HW, "GPIO_2_FUNC!\n");
-
- if (asserted & GPIO_3_FUNC)
- DP(NETIF_MSG_HW, "GPIO_3_FUNC!\n");
-
- if (asserted & GPIO_4_FUNC)
- DP(NETIF_MSG_HW, "GPIO_4_FUNC!\n");
-
- if (port == 0) {
- if (asserted & ATTN_GENERAL_ATTN_1) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_1!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_1, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_2) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_2!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_2, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_3) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_3!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_3, 0x0);
- }
- } else {
- if (asserted & ATTN_GENERAL_ATTN_4) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_4!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_4, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_5) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_5!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_5, 0x0);
- }
- if (asserted & ATTN_GENERAL_ATTN_6) {
- DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_6!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_6, 0x0);
- }
- }
-
- } /* if hardwired */
-
- DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n",
- asserted, hc_addr);
- REG_WR(bp, hc_addr, asserted);
-
- /* now set back the mask */
- if (asserted & ATTN_NIG_FOR_FUNC)
- REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
-}
-
-static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
-{
- int port = BP_PORT(bp);
- int reg_offset;
- u32 val;
-
- reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
- MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
-
- if (attn & AEU_INPUTS_ATTN_BITS_SPIO5) {
-
- val = REG_RD(bp, reg_offset);
- val &= ~AEU_INPUTS_ATTN_BITS_SPIO5;
- REG_WR(bp, reg_offset, val);
-
- BNX2X_ERR("SPIO5 hw attention\n");
-
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
- /* Fan failure attention */
-
- /* The PHY reset is controlled by GPIO 1 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- /* Low power mode is controlled by GPIO 2 */
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
- /* mark the failure */
- bp->link_params.ext_phy_config &=
- ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
- bp->link_params.ext_phy_config |=
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
- SHMEM_WR(bp,
- dev_info.port_hw_config[port].
- external_phy_config,
- bp->link_params.ext_phy_config);
- /* log the failure */
- printk(KERN_ERR PFX "Fan Failure on Network"
- " Controller %s has caused the driver to"
- " shutdown the card to prevent permanent"
- " damage. Please contact Dell Support for"
- " assistance\n", bp->dev->name);
- break;
-
- default:
- break;
- }
- }
-
- if (attn & HW_INTERRUT_ASSERT_SET_0) {
-
- val = REG_RD(bp, reg_offset);
- val &= ~(attn & HW_INTERRUT_ASSERT_SET_0);
- REG_WR(bp, reg_offset, val);
-
- BNX2X_ERR("FATAL HW block attention set0 0x%x\n",
- (attn & HW_INTERRUT_ASSERT_SET_0));
- bnx2x_panic();
- }
-}
-
-static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
-{
- u32 val;
-
- if (attn & BNX2X_DOORQ_ASSERT) {
-
- val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
- BNX2X_ERR("DB hw attention 0x%x\n", val);
- /* DORQ discard attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from DORQ\n");
- }
-
- if (attn & HW_INTERRUT_ASSERT_SET_1) {
-
- int port = BP_PORT(bp);
- int reg_offset;
-
- reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1 :
- MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1);
-
- val = REG_RD(bp, reg_offset);
- val &= ~(attn & HW_INTERRUT_ASSERT_SET_1);
- REG_WR(bp, reg_offset, val);
-
- BNX2X_ERR("FATAL HW block attention set1 0x%x\n",
- (attn & HW_INTERRUT_ASSERT_SET_1));
- bnx2x_panic();
- }
-}
-
-static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
-{
- u32 val;
-
- if (attn & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
-
- val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
- BNX2X_ERR("CFC hw attention 0x%x\n", val);
- /* CFC error attention */
- if (val & 0x2)
- BNX2X_ERR("FATAL error from CFC\n");
- }
-
- if (attn & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
-
- val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
- BNX2X_ERR("PXP hw attention 0x%x\n", val);
- /* RQ_USDMDP_FIFO_OVERFLOW */
- if (val & 0x18000)
- BNX2X_ERR("FATAL error from PXP\n");
- }
-
- if (attn & HW_INTERRUT_ASSERT_SET_2) {
-
- int port = BP_PORT(bp);
- int reg_offset;
-
- reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_2 :
- MISC_REG_AEU_ENABLE1_FUNC_0_OUT_2);
-
- val = REG_RD(bp, reg_offset);
- val &= ~(attn & HW_INTERRUT_ASSERT_SET_2);
- REG_WR(bp, reg_offset, val);
-
- BNX2X_ERR("FATAL HW block attention set2 0x%x\n",
- (attn & HW_INTERRUT_ASSERT_SET_2));
- bnx2x_panic();
- }
-}
-
-static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
-{
- u32 val;
-
- if (attn & EVEREST_GEN_ATTN_IN_USE_MASK) {
-
- if (attn & BNX2X_PMF_LINK_ASSERT) {
- int func = BP_FUNC(bp);
-
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
- bnx2x__link_status_update(bp);
- if (SHMEM_RD(bp, func_mb[func].drv_status) &
- DRV_STATUS_PMF)
- bnx2x_pmf_update(bp);
-
- } else if (attn & BNX2X_MC_ASSERT_BITS) {
-
- BNX2X_ERR("MC assert!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_10, 0);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_9, 0);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_8, 0);
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_7, 0);
- bnx2x_panic();
-
- } else if (attn & BNX2X_MCP_ASSERT) {
-
- BNX2X_ERR("MCP assert!\n");
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_11, 0);
- bnx2x_fw_dump(bp);
-
- } else
- BNX2X_ERR("Unknown HW assert! (attn 0x%x)\n", attn);
- }
-
- if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) {
- BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn);
- if (attn & BNX2X_GRC_TIMEOUT) {
- val = CHIP_IS_E1H(bp) ?
- REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0;
- BNX2X_ERR("GRC time-out 0x%08x\n", val);
- }
- if (attn & BNX2X_GRC_RSV) {
- val = CHIP_IS_E1H(bp) ?
- REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0;
- BNX2X_ERR("GRC reserved 0x%08x\n", val);
- }
- REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff);
- }
-}
-
-static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
-{
- struct attn_route attn;
- struct attn_route group_mask;
- int port = BP_PORT(bp);
- int index;
- u32 reg_addr;
- u32 val;
- u32 aeu_mask;
-
- /* need to take HW lock because MCP or other port might also
- try to handle this event */
- bnx2x_acquire_alr(bp);
-
- attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4);
- attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4);
- attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4);
- attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4);
- DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n",
- attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]);
-
- for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
- if (deasserted & (1 << index)) {
- group_mask = bp->attn_group[index];
-
- DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n",
- index, group_mask.sig[0], group_mask.sig[1],
- group_mask.sig[2], group_mask.sig[3]);
-
- bnx2x_attn_int_deasserted3(bp,
- attn.sig[3] & group_mask.sig[3]);
- bnx2x_attn_int_deasserted1(bp,
- attn.sig[1] & group_mask.sig[1]);
- bnx2x_attn_int_deasserted2(bp,
- attn.sig[2] & group_mask.sig[2]);
- bnx2x_attn_int_deasserted0(bp,
- attn.sig[0] & group_mask.sig[0]);
-
- if ((attn.sig[0] & group_mask.sig[0] &
- HW_PRTY_ASSERT_SET_0) ||
- (attn.sig[1] & group_mask.sig[1] &
- HW_PRTY_ASSERT_SET_1) ||
- (attn.sig[2] & group_mask.sig[2] &
- HW_PRTY_ASSERT_SET_2))
- BNX2X_ERR("FATAL HW block parity attention\n");
- }
- }
-
- bnx2x_release_alr(bp);
-
- reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR);
-
- val = ~deasserted;
- DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n",
- val, reg_addr);
- REG_WR(bp, reg_addr, val);
-
- if (~bp->attn_state & deasserted)
- BNX2X_ERR("IGU ERROR\n");
-
- reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
- MISC_REG_AEU_MASK_ATTN_FUNC_0;
-
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
- aeu_mask = REG_RD(bp, reg_addr);
-
- DP(NETIF_MSG_HW, "aeu_mask %x newly deasserted %x\n",
- aeu_mask, deasserted);
- aeu_mask |= (deasserted & 0xff);
- DP(NETIF_MSG_HW, "new mask %x\n", aeu_mask);
-
- REG_WR(bp, reg_addr, aeu_mask);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_PORT0_ATT_MASK + port);
-
- DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state);
- bp->attn_state &= ~deasserted;
- DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state);
-}
-
-static void bnx2x_attn_int(struct bnx2x *bp)
-{
- /* read local copy of bits */
- u32 attn_bits = bp->def_status_blk->atten_status_block.attn_bits;
- u32 attn_ack = bp->def_status_blk->atten_status_block.attn_bits_ack;
- u32 attn_state = bp->attn_state;
-
- /* look for changed bits */
- u32 asserted = attn_bits & ~attn_ack & ~attn_state;
- u32 deasserted = ~attn_bits & attn_ack & attn_state;
-
- DP(NETIF_MSG_HW,
- "attn_bits %x attn_ack %x asserted %x deasserted %x\n",
- attn_bits, attn_ack, asserted, deasserted);
-
- if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state))
- BNX2X_ERR("BAD attention state\n");
-
- /* handle bits that were raised */
- if (asserted)
- bnx2x_attn_int_asserted(bp, asserted);
-
- if (deasserted)
- bnx2x_attn_int_deasserted(bp, deasserted);
-}
-
-static void bnx2x_sp_task(struct work_struct *work)
-{
- struct bnx2x *bp = container_of(work, struct bnx2x, sp_task);
- u16 status;
-
-
- /* Return here if interrupt is disabled */
- if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
- return;
- }
-
- status = bnx2x_update_dsb_idx(bp);
-/* if (status == 0) */
-/* BNX2X_ERR("spurious slowpath interrupt!\n"); */
-
- DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status);
-
- /* HW attentions */
- if (status & 0x1)
- bnx2x_attn_int(bp);
-
- /* CStorm events: query_stats, port delete ramrod */
- if (status & 0x2)
- bp->stats_pending = 0;
-
- bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx,
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx),
- IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
- IGU_INT_ENABLE, 1);
-
-}
-
-static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
-{
- struct net_device *dev = dev_instance;
- struct bnx2x *bp = netdev_priv(dev);
-
- /* Return here if interrupt is disabled */
- if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
- DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
- return IRQ_HANDLED;
- }
-
- bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return IRQ_HANDLED;
-#endif
-
- schedule_work(&bp->sp_task);
-
- return IRQ_HANDLED;
-}
-
-/* end of slow path */
-
-/* Statistics */
-
-/****************************************************************************
-* Macros
-****************************************************************************/
-
-/* sum[hi:lo] += add[hi:lo] */
-#define ADD_64(s_hi, a_hi, s_lo, a_lo) \
- do { \
- s_lo += a_lo; \
- s_hi += a_hi + (s_lo < a_lo) ? 1 : 0; \
- } while (0)
-
-/* difference = minuend - subtrahend */
-#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \
- do { \
- if (m_lo < s_lo) { \
- /* underflow */ \
- d_hi = m_hi - s_hi; \
- if (d_hi > 0) { \
- /* we can 'loan' 1 */ \
- d_hi--; \
- d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
- } else { \
- /* m_hi <= s_hi */ \
- d_hi = 0; \
- d_lo = 0; \
- } \
- } else { \
- /* m_lo >= s_lo */ \
- if (m_hi < s_hi) { \
- d_hi = 0; \
- d_lo = 0; \
- } else { \
- /* m_hi >= s_hi */ \
- d_hi = m_hi - s_hi; \
- d_lo = m_lo - s_lo; \
- } \
- } \
- } while (0)
-
-#define UPDATE_STAT64(s, t) \
- do { \
- DIFF_64(diff.hi, new->s##_hi, pstats->mac_stx[0].t##_hi, \
- diff.lo, new->s##_lo, pstats->mac_stx[0].t##_lo); \
- pstats->mac_stx[0].t##_hi = new->s##_hi; \
- pstats->mac_stx[0].t##_lo = new->s##_lo; \
- ADD_64(pstats->mac_stx[1].t##_hi, diff.hi, \
- pstats->mac_stx[1].t##_lo, diff.lo); \
- } while (0)
-
-#define UPDATE_STAT64_NIG(s, t) \
- do { \
- DIFF_64(diff.hi, new->s##_hi, old->s##_hi, \
- diff.lo, new->s##_lo, old->s##_lo); \
- ADD_64(estats->t##_hi, diff.hi, \
- estats->t##_lo, diff.lo); \
- } while (0)
-
-/* sum[hi:lo] += add */
-#define ADD_EXTEND_64(s_hi, s_lo, a) \
- do { \
- s_lo += a; \
- s_hi += (s_lo < a) ? 1 : 0; \
- } while (0)
-
-#define UPDATE_EXTEND_STAT(s) \
- do { \
- ADD_EXTEND_64(pstats->mac_stx[1].s##_hi, \
- pstats->mac_stx[1].s##_lo, \
- new->s); \
- } while (0)
-
-#define UPDATE_EXTEND_TSTAT(s, t) \
- do { \
- diff = le32_to_cpu(tclient->s) - old_tclient->s; \
- old_tclient->s = le32_to_cpu(tclient->s); \
- ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
- } while (0)
-
-#define UPDATE_EXTEND_XSTAT(s, t) \
- do { \
- diff = le32_to_cpu(xclient->s) - old_xclient->s; \
- old_xclient->s = le32_to_cpu(xclient->s); \
- ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
- } while (0)
-
-/*
- * General service functions
- */
-
-static inline long bnx2x_hilo(u32 *hiref)
-{
- u32 lo = *(hiref + 1);
-#if (BITS_PER_LONG == 64)
- u32 hi = *hiref;
-
- return HILO_U64(hi, lo);
-#else
- return lo;
-#endif
-}
-
-/*
- * Init service functions
- */
-
-static void bnx2x_storm_stats_post(struct bnx2x *bp)
-{
- if (!bp->stats_pending) {
- struct eth_query_ramrod_data ramrod_data = {0};
- int rc;
-
- ramrod_data.drv_counter = bp->stats_counter++;
- ramrod_data.collect_port_1b = bp->port.pmf ? 1 : 0;
- ramrod_data.ctr_id_vector = (1 << BP_CL_ID(bp));
-
- rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
- ((u32 *)&ramrod_data)[1],
- ((u32 *)&ramrod_data)[0], 0);
- if (rc == 0) {
- /* stats ramrod has it's own slot on the spq */
- bp->spq_left++;
- bp->stats_pending = 1;
- }
- }
-}
-
-static void bnx2x_stats_init(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
-
- bp->executer_idx = 0;
- bp->stats_counter = 0;
-
- /* port stats */
- if (!BP_NOMCP(bp))
- bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
- else
- bp->port.port_stx = 0;
- DP(BNX2X_MSG_STATS, "port_stx 0x%x\n", bp->port.port_stx);
-
- memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
- bp->port.old_nig_stats.brb_discard =
- REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
- bp->port.old_nig_stats.brb_truncate =
- REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
- REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
- &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
- REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
- &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
-
- /* function stats */
- memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
- memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
- memset(&bp->old_xclient, 0, sizeof(struct xstorm_per_client_stats));
- memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
-
- bp->stats_state = STATS_STATE_DISABLED;
- if (IS_E1HMF(bp) && bp->port.pmf && bp->port.port_stx)
- bnx2x_stats_handle(bp, STATS_EVENT_PMF);
-}
-
-static void bnx2x_hw_stats_post(struct bnx2x *bp)
-{
- struct dmae_command *dmae = &bp->stats_dmae;
- u32 *stats_comp = bnx2x_sp(bp, stats_comp);
-
- *stats_comp = DMAE_COMP_VAL;
-
- /* loader */
- if (bp->executer_idx) {
- int loader_idx = PMF_DMAE_C(bp);
-
- memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 :
- DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
- dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
- sizeof(struct dmae_command) *
- (loader_idx + 1)) >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = sizeof(struct dmae_command) >> 2;
- if (CHIP_IS_E1(bp))
- dmae->len--;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- *stats_comp = 0;
- bnx2x_post_dmae(bp, dmae, loader_idx);
-
- } else if (bp->func_stx) {
- *stats_comp = 0;
- bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
- }
-}
-
-static int bnx2x_stats_comp(struct bnx2x *bp)
-{
- u32 *stats_comp = bnx2x_sp(bp, stats_comp);
- int cnt = 10;
-
- might_sleep();
- while (*stats_comp != DMAE_COMP_VAL) {
- if (!cnt) {
- BNX2X_ERR("timeout waiting for stats finished\n");
- break;
- }
- cnt--;
- msleep(1);
- }
- return 1;
-}
-
-/*
- * Statistics service functions
- */
-
-static void bnx2x_stats_pmf_update(struct bnx2x *bp)
-{
- struct dmae_command *dmae;
- u32 opcode;
- int loader_idx = PMF_DMAE_C(bp);
- u32 *stats_comp = bnx2x_sp(bp, stats_comp);
-
- /* sanity */
- if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) {
- BNX2X_ERR("BUG!\n");
- return;
- }
-
- bp->executer_idx = 0;
-
- opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
- dmae->src_addr_lo = bp->port.port_stx >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
- dmae->len = DMAE_LEN32_RD_MAX;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
- dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) +
- DMAE_LEN32_RD_MAX * 4);
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats) +
- DMAE_LEN32_RD_MAX * 4);
- dmae->len = (sizeof(struct host_port_stats) >> 2) - DMAE_LEN32_RD_MAX;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_val = DMAE_COMP_VAL;
-
- *stats_comp = 0;
- bnx2x_hw_stats_post(bp);
- bnx2x_stats_comp(bp);
-}
-
-static void bnx2x_port_stats_init(struct bnx2x *bp)
-{
- struct dmae_command *dmae;
- int port = BP_PORT(bp);
- int vn = BP_E1HVN(bp);
- u32 opcode;
- int loader_idx = PMF_DMAE_C(bp);
- u32 mac_addr;
- u32 *stats_comp = bnx2x_sp(bp, stats_comp);
-
- /* sanity */
- if (!bp->link_vars.link_up || !bp->port.pmf) {
- BNX2X_ERR("BUG!\n");
- return;
- }
-
- bp->executer_idx = 0;
-
- /* MCP */
- opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (vn << DMAE_CMD_E1HVN_SHIFT));
-
- if (bp->port.port_stx) {
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
- dmae->dst_addr_lo = bp->port.port_stx >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = sizeof(struct host_port_stats) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
- }
-
- if (bp->func_stx) {
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
- dmae->dst_addr_lo = bp->func_stx >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = sizeof(struct host_func_stats) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
- }
-
- /* MAC */
- opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (vn << DMAE_CMD_E1HVN_SHIFT));
-
- if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
-
- mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM :
- NIG_REG_INGRESS_BMAC0_MEM);
-
- /* BIGMAC_REGISTER_TX_STAT_GTPKT ..
- BIGMAC_REGISTER_TX_STAT_GTBYT */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
- dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
- BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- /* BIGMAC_REGISTER_RX_STAT_GR64 ..
- BIGMAC_REGISTER_RX_STAT_GRIPJ */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct bmac_stats, rx_stat_gr64_lo));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct bmac_stats, rx_stat_gr64_lo));
- dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
- BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- } else if (bp->link_vars.mac_type == MAC_TYPE_EMAC) {
-
- mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
-
- /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- EMAC_REG_EMAC_RX_STAT_AC) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
- dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- /* EMAC_REG_EMAC_RX_STAT_AC_28 */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats, rx_stat_falsecarriererrors));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats, rx_stat_falsecarriererrors));
- dmae->len = 1;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (mac_addr +
- EMAC_REG_EMAC_TX_STAT_AC) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
- offsetof(struct emac_stats, tx_stat_ifhcoutoctets));
- dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
- }
-
- /* NIG */
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
- NIG_REG_STAT0_BRB_DISCARD) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats));
- dmae->len = (sizeof(struct nig_stats) - 4*sizeof(u32)) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = opcode;
- dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT0 :
- NIG_REG_STAT0_EGRESS_MAC_PKT0) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
- offsetof(struct nig_stats, egress_mac_pkt0_lo));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
- offsetof(struct nig_stats, egress_mac_pkt0_lo));
- dmae->len = (2*sizeof(u32)) >> 2;
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (vn << DMAE_CMD_E1HVN_SHIFT));
- dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 :
- NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2;
- dmae->src_addr_hi = 0;
- dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig_stats) +
- offsetof(struct nig_stats, egress_mac_pkt1_lo));
- dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig_stats) +
- offsetof(struct nig_stats, egress_mac_pkt1_lo));
- dmae->len = (2*sizeof(u32)) >> 2;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_val = DMAE_COMP_VAL;
-
- *stats_comp = 0;
-}
-
-static void bnx2x_func_stats_init(struct bnx2x *bp)
-{
- struct dmae_command *dmae = &bp->stats_dmae;
- u32 *stats_comp = bnx2x_sp(bp, stats_comp);
-
- /* sanity */
- if (!bp->func_stx) {
- BNX2X_ERR("BUG!\n");
- return;
- }
-
- bp->executer_idx = 0;
- memset(dmae, 0, sizeof(struct dmae_command));
-
- dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
- dmae->dst_addr_lo = bp->func_stx >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = sizeof(struct host_func_stats) >> 2;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_val = DMAE_COMP_VAL;
-
- *stats_comp = 0;
-}
-
-static void bnx2x_stats_start(struct bnx2x *bp)
-{
- if (bp->port.pmf)
- bnx2x_port_stats_init(bp);
-
- else if (bp->func_stx)
- bnx2x_func_stats_init(bp);
-
- bnx2x_hw_stats_post(bp);
- bnx2x_storm_stats_post(bp);
-}
-
-static void bnx2x_stats_pmf_start(struct bnx2x *bp)
-{
- bnx2x_stats_comp(bp);
- bnx2x_stats_pmf_update(bp);
- bnx2x_stats_start(bp);
-}
-
-static void bnx2x_stats_restart(struct bnx2x *bp)
-{
- bnx2x_stats_comp(bp);
- bnx2x_stats_start(bp);
-}
-
-static void bnx2x_bmac_stats_update(struct bnx2x *bp)
-{
- struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
- struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
- struct regpair diff;
-
- UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
- UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
- UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts);
- UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong);
- UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments);
- UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
- UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
- UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
- UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
- UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
- UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
- UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
- UPDATE_STAT64(tx_stat_gt127,
- tx_stat_etherstatspkts65octetsto127octets);
- UPDATE_STAT64(tx_stat_gt255,
- tx_stat_etherstatspkts128octetsto255octets);
- UPDATE_STAT64(tx_stat_gt511,
- tx_stat_etherstatspkts256octetsto511octets);
- UPDATE_STAT64(tx_stat_gt1023,
- tx_stat_etherstatspkts512octetsto1023octets);
- UPDATE_STAT64(tx_stat_gt1518,
- tx_stat_etherstatspkts1024octetsto1522octets);
- UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047);
- UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095);
- UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216);
- UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383);
- UPDATE_STAT64(tx_stat_gterr,
- tx_stat_dot3statsinternalmactransmiterrors);
- UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
-}
-
-static void bnx2x_emac_stats_update(struct bnx2x *bp)
-{
- struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
- struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
-
- UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
- UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
- UPDATE_EXTEND_STAT(rx_stat_dot3statsfcserrors);
- UPDATE_EXTEND_STAT(rx_stat_dot3statsalignmenterrors);
- UPDATE_EXTEND_STAT(rx_stat_dot3statscarriersenseerrors);
- UPDATE_EXTEND_STAT(rx_stat_falsecarriererrors);
- UPDATE_EXTEND_STAT(rx_stat_etherstatsundersizepkts);
- UPDATE_EXTEND_STAT(rx_stat_dot3statsframestoolong);
- UPDATE_EXTEND_STAT(rx_stat_etherstatsfragments);
- UPDATE_EXTEND_STAT(rx_stat_etherstatsjabbers);
- UPDATE_EXTEND_STAT(rx_stat_maccontrolframesreceived);
- UPDATE_EXTEND_STAT(rx_stat_xoffstateentered);
- UPDATE_EXTEND_STAT(rx_stat_xonpauseframesreceived);
- UPDATE_EXTEND_STAT(rx_stat_xoffpauseframesreceived);
- UPDATE_EXTEND_STAT(tx_stat_outxonsent);
- UPDATE_EXTEND_STAT(tx_stat_outxoffsent);
- UPDATE_EXTEND_STAT(tx_stat_flowcontroldone);
- UPDATE_EXTEND_STAT(tx_stat_etherstatscollisions);
- UPDATE_EXTEND_STAT(tx_stat_dot3statssinglecollisionframes);
- UPDATE_EXTEND_STAT(tx_stat_dot3statsmultiplecollisionframes);
- UPDATE_EXTEND_STAT(tx_stat_dot3statsdeferredtransmissions);
- UPDATE_EXTEND_STAT(tx_stat_dot3statsexcessivecollisions);
- UPDATE_EXTEND_STAT(tx_stat_dot3statslatecollisions);
- UPDATE_EXTEND_STAT(tx_stat_etherstatspkts64octets);
- UPDATE_EXTEND_STAT(tx_stat_etherstatspkts65octetsto127octets);
- UPDATE_EXTEND_STAT(tx_stat_etherstatspkts128octetsto255octets);
- UPDATE_EXTEND_STAT(tx_stat_etherstatspkts256octetsto511octets);
- UPDATE_EXTEND_STAT(tx_stat_etherstatspkts512octetsto1023octets);
- UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
- UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
- UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
-}
-
-static int bnx2x_hw_stats_update(struct bnx2x *bp)
-{
- struct nig_stats *new = bnx2x_sp(bp, nig_stats);
- struct nig_stats *old = &(bp->port.old_nig_stats);
- struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
- struct bnx2x_eth_stats *estats = &bp->eth_stats;
- struct regpair diff;
-
- if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
- bnx2x_bmac_stats_update(bp);
-
- else if (bp->link_vars.mac_type == MAC_TYPE_EMAC)
- bnx2x_emac_stats_update(bp);
-
- else { /* unreached */
- BNX2X_ERR("stats updated by dmae but no MAC active\n");
- return -1;
- }
-
- ADD_EXTEND_64(pstats->brb_drop_hi, pstats->brb_drop_lo,
- new->brb_discard - old->brb_discard);
- ADD_EXTEND_64(estats->brb_truncate_hi, estats->brb_truncate_lo,
- new->brb_truncate - old->brb_truncate);
-
- UPDATE_STAT64_NIG(egress_mac_pkt0,
- etherstatspkts1024octetsto1522octets);
- UPDATE_STAT64_NIG(egress_mac_pkt1, etherstatspktsover1522octets);
-
- memcpy(old, new, sizeof(struct nig_stats));
-
- memcpy(&(estats->rx_stat_ifhcinbadoctets_hi), &(pstats->mac_stx[1]),
- sizeof(struct mac_stx));
- estats->brb_drop_hi = pstats->brb_drop_hi;
- estats->brb_drop_lo = pstats->brb_drop_lo;
-
- pstats->host_port_stats_start = ++pstats->host_port_stats_end;
-
- return 0;
-}
-
-static int bnx2x_storm_stats_update(struct bnx2x *bp)
-{
- struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
- int cl_id = BP_CL_ID(bp);
- struct tstorm_per_port_stats *tport =
- &stats->tstorm_common.port_statistics;
- struct tstorm_per_client_stats *tclient =
- &stats->tstorm_common.client_statistics[cl_id];
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
- struct xstorm_per_client_stats *xclient =
- &stats->xstorm_common.client_statistics[cl_id];
- struct xstorm_per_client_stats *old_xclient = &bp->old_xclient;
- struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
- struct bnx2x_eth_stats *estats = &bp->eth_stats;
- u32 diff;
-
- /* are storm stats valid? */
- if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
- bp->stats_counter) {
- DP(BNX2X_MSG_STATS, "stats not updated by tstorm"
- " tstorm counter (%d) != stats_counter (%d)\n",
- tclient->stats_counter, bp->stats_counter);
- return -1;
- }
- if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
- bp->stats_counter) {
- DP(BNX2X_MSG_STATS, "stats not updated by xstorm"
- " xstorm counter (%d) != stats_counter (%d)\n",
- xclient->stats_counter, bp->stats_counter);
- return -2;
- }
-
- fstats->total_bytes_received_hi =
- fstats->valid_bytes_received_hi =
- le32_to_cpu(tclient->total_rcv_bytes.hi);
- fstats->total_bytes_received_lo =
- fstats->valid_bytes_received_lo =
- le32_to_cpu(tclient->total_rcv_bytes.lo);
-
- estats->error_bytes_received_hi =
- le32_to_cpu(tclient->rcv_error_bytes.hi);
- estats->error_bytes_received_lo =
- le32_to_cpu(tclient->rcv_error_bytes.lo);
- ADD_64(estats->error_bytes_received_hi,
- estats->rx_stat_ifhcinbadoctets_hi,
- estats->error_bytes_received_lo,
- estats->rx_stat_ifhcinbadoctets_lo);
-
- ADD_64(fstats->total_bytes_received_hi,
- estats->error_bytes_received_hi,
- fstats->total_bytes_received_lo,
- estats->error_bytes_received_lo);
-
- UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, total_unicast_packets_received);
- UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
- total_multicast_packets_received);
- UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
- total_broadcast_packets_received);
-
- fstats->total_bytes_transmitted_hi =
- le32_to_cpu(xclient->total_sent_bytes.hi);
- fstats->total_bytes_transmitted_lo =
- le32_to_cpu(xclient->total_sent_bytes.lo);
-
- UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
- total_unicast_packets_transmitted);
- UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
- total_multicast_packets_transmitted);
- UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
- total_broadcast_packets_transmitted);
-
- memcpy(estats, &(fstats->total_bytes_received_hi),
- sizeof(struct host_func_stats) - 2*sizeof(u32));
-
- estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard);
- estats->xxoverflow_discard = le32_to_cpu(tport->xxoverflow_discard);
- estats->brb_truncate_discard =
- le32_to_cpu(tport->brb_truncate_discard);
- estats->mac_discard = le32_to_cpu(tport->mac_discard);
-
- old_tclient->rcv_unicast_bytes.hi =
- le32_to_cpu(tclient->rcv_unicast_bytes.hi);
- old_tclient->rcv_unicast_bytes.lo =
- le32_to_cpu(tclient->rcv_unicast_bytes.lo);
- old_tclient->rcv_broadcast_bytes.hi =
- le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
- old_tclient->rcv_broadcast_bytes.lo =
- le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
- old_tclient->rcv_multicast_bytes.hi =
- le32_to_cpu(tclient->rcv_multicast_bytes.hi);
- old_tclient->rcv_multicast_bytes.lo =
- le32_to_cpu(tclient->rcv_multicast_bytes.lo);
- old_tclient->total_rcv_pkts = le32_to_cpu(tclient->total_rcv_pkts);
-
- old_tclient->checksum_discard = le32_to_cpu(tclient->checksum_discard);
- old_tclient->packets_too_big_discard =
- le32_to_cpu(tclient->packets_too_big_discard);
- estats->no_buff_discard =
- old_tclient->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
- old_tclient->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
-
- old_xclient->total_sent_pkts = le32_to_cpu(xclient->total_sent_pkts);
- old_xclient->unicast_bytes_sent.hi =
- le32_to_cpu(xclient->unicast_bytes_sent.hi);
- old_xclient->unicast_bytes_sent.lo =
- le32_to_cpu(xclient->unicast_bytes_sent.lo);
- old_xclient->multicast_bytes_sent.hi =
- le32_to_cpu(xclient->multicast_bytes_sent.hi);
- old_xclient->multicast_bytes_sent.lo =
- le32_to_cpu(xclient->multicast_bytes_sent.lo);
- old_xclient->broadcast_bytes_sent.hi =
- le32_to_cpu(xclient->broadcast_bytes_sent.hi);
- old_xclient->broadcast_bytes_sent.lo =
- le32_to_cpu(xclient->broadcast_bytes_sent.lo);
-
- fstats->host_func_stats_start = ++fstats->host_func_stats_end;
-
- return 0;
-}
-
-static void bnx2x_net_stats_update(struct bnx2x *bp)
-{
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
- struct bnx2x_eth_stats *estats = &bp->eth_stats;
- struct net_device_stats *nstats = &bp->dev->stats;
-
- nstats->rx_packets =
- bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
- bnx2x_hilo(&estats->total_multicast_packets_received_hi) +
- bnx2x_hilo(&estats->total_broadcast_packets_received_hi);
-
- nstats->tx_packets =
- bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) +
- bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
- bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
-
- nstats->rx_bytes = bnx2x_hilo(&estats->valid_bytes_received_hi);
-
- nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
-
- nstats->rx_dropped = old_tclient->checksum_discard +
- estats->mac_discard;
- nstats->tx_dropped = 0;
-
- nstats->multicast =
- bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
-
- nstats->collisions =
- estats->tx_stat_dot3statssinglecollisionframes_lo +
- estats->tx_stat_dot3statsmultiplecollisionframes_lo +
- estats->tx_stat_dot3statslatecollisions_lo +
- estats->tx_stat_dot3statsexcessivecollisions_lo;
-
- estats->jabber_packets_received =
- old_tclient->packets_too_big_discard +
- estats->rx_stat_dot3statsframestoolong_lo;
-
- nstats->rx_length_errors =
- estats->rx_stat_etherstatsundersizepkts_lo +
- estats->jabber_packets_received;
- nstats->rx_over_errors = estats->brb_drop_lo + estats->brb_truncate_lo;
- nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
- nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
- nstats->rx_fifo_errors = old_tclient->no_buff_discard;
- nstats->rx_missed_errors = estats->xxoverflow_discard;
-
- nstats->rx_errors = nstats->rx_length_errors +
- nstats->rx_over_errors +
- nstats->rx_crc_errors +
- nstats->rx_frame_errors +
- nstats->rx_fifo_errors +
- nstats->rx_missed_errors;
-
- nstats->tx_aborted_errors =
- estats->tx_stat_dot3statslatecollisions_lo +
- estats->tx_stat_dot3statsexcessivecollisions_lo;
- nstats->tx_carrier_errors = estats->rx_stat_falsecarriererrors_lo;
- nstats->tx_fifo_errors = 0;
- nstats->tx_heartbeat_errors = 0;
- nstats->tx_window_errors = 0;
-
- nstats->tx_errors = nstats->tx_aborted_errors +
- nstats->tx_carrier_errors;
-}
-
-static void bnx2x_stats_update(struct bnx2x *bp)
-{
- u32 *stats_comp = bnx2x_sp(bp, stats_comp);
- int update = 0;
-
- if (*stats_comp != DMAE_COMP_VAL)
- return;
-
- if (bp->port.pmf)
- update = (bnx2x_hw_stats_update(bp) == 0);
-
- update |= (bnx2x_storm_stats_update(bp) == 0);
-
- if (update)
- bnx2x_net_stats_update(bp);
-
- else {
- if (bp->stats_pending) {
- bp->stats_pending++;
- if (bp->stats_pending == 3) {
- BNX2X_ERR("stats not updated for 3 times\n");
- bnx2x_panic();
- return;
- }
- }
- }
-
- if (bp->msglevel & NETIF_MSG_TIMER) {
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
- struct bnx2x_eth_stats *estats = &bp->eth_stats;
- struct net_device_stats *nstats = &bp->dev->stats;
- int i;
-
- printk(KERN_DEBUG "%s:\n", bp->dev->name);
- printk(KERN_DEBUG " tx avail (%4x) tx hc idx (%x)"
- " tx pkt (%lx)\n",
- bnx2x_tx_avail(bp->fp),
- le16_to_cpu(*bp->fp->tx_cons_sb), nstats->tx_packets);
- printk(KERN_DEBUG " rx usage (%4x) rx hc idx (%x)"
- " rx pkt (%lx)\n",
- (u16)(le16_to_cpu(*bp->fp->rx_cons_sb) -
- bp->fp->rx_comp_cons),
- le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets);
- printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
- netif_queue_stopped(bp->dev) ? "Xoff" : "Xon",
- estats->driver_xoff, estats->brb_drop_lo);
- printk(KERN_DEBUG "tstats: checksum_discard %u "
- "packets_too_big_discard %u no_buff_discard %u "
- "mac_discard %u mac_filter_discard %u "
- "xxovrflow_discard %u brb_truncate_discard %u "
- "ttl0_discard %u\n",
- old_tclient->checksum_discard,
- old_tclient->packets_too_big_discard,
- old_tclient->no_buff_discard, estats->mac_discard,
- estats->mac_filter_discard, estats->xxoverflow_discard,
- estats->brb_truncate_discard,
- old_tclient->ttl0_discard);
-
- for_each_queue(bp, i) {
- printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
- bnx2x_fp(bp, i, tx_pkt),
- bnx2x_fp(bp, i, rx_pkt),
- bnx2x_fp(bp, i, rx_calls));
- }
- }
-
- bnx2x_hw_stats_post(bp);
- bnx2x_storm_stats_post(bp);
-}
-
-static void bnx2x_port_stats_stop(struct bnx2x *bp)
-{
- struct dmae_command *dmae;
- u32 opcode;
- int loader_idx = PMF_DMAE_C(bp);
- u32 *stats_comp = bnx2x_sp(bp, stats_comp);
-
- bp->executer_idx = 0;
-
- opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
- DMAE_CMD_C_ENABLE |
- DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
-#ifdef __BIG_ENDIAN
- DMAE_CMD_ENDIANITY_B_DW_SWAP |
-#else
- DMAE_CMD_ENDIANITY_DW_SWAP |
-#endif
- (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
- (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
-
- if (bp->port.port_stx) {
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- if (bp->func_stx)
- dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC);
- else
- dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
- dmae->dst_addr_lo = bp->port.port_stx >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = sizeof(struct host_port_stats) >> 2;
- if (bp->func_stx) {
- dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
- dmae->comp_addr_hi = 0;
- dmae->comp_val = 1;
- } else {
- dmae->comp_addr_lo =
- U64_LO(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_addr_hi =
- U64_HI(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_val = DMAE_COMP_VAL;
-
- *stats_comp = 0;
- }
- }
-
- if (bp->func_stx) {
-
- dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
- dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI);
- dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
- dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
- dmae->dst_addr_lo = bp->func_stx >> 2;
- dmae->dst_addr_hi = 0;
- dmae->len = sizeof(struct host_func_stats) >> 2;
- dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
- dmae->comp_val = DMAE_COMP_VAL;
-
- *stats_comp = 0;
- }
-}
-
-static void bnx2x_stats_stop(struct bnx2x *bp)
-{
- int update = 0;
-
- bnx2x_stats_comp(bp);
-
- if (bp->port.pmf)
- update = (bnx2x_hw_stats_update(bp) == 0);
-
- update |= (bnx2x_storm_stats_update(bp) == 0);
-
- if (update) {
- bnx2x_net_stats_update(bp);
-
- if (bp->port.pmf)
- bnx2x_port_stats_stop(bp);
-
- bnx2x_hw_stats_post(bp);
- bnx2x_stats_comp(bp);
- }
-}
-
-static void bnx2x_stats_do_nothing(struct bnx2x *bp)
-{
-}
-
-static const struct {
- void (*action)(struct bnx2x *bp);
- enum bnx2x_stats_state next_state;
-} bnx2x_stats_stm[STATS_STATE_MAX][STATS_EVENT_MAX] = {
-/* state event */
-{
-/* DISABLED PMF */ {bnx2x_stats_pmf_update, STATS_STATE_DISABLED},
-/* LINK_UP */ {bnx2x_stats_start, STATS_STATE_ENABLED},
-/* UPDATE */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED},
-/* STOP */ {bnx2x_stats_do_nothing, STATS_STATE_DISABLED}
-},
-{
-/* ENABLED PMF */ {bnx2x_stats_pmf_start, STATS_STATE_ENABLED},
-/* LINK_UP */ {bnx2x_stats_restart, STATS_STATE_ENABLED},
-/* UPDATE */ {bnx2x_stats_update, STATS_STATE_ENABLED},
-/* STOP */ {bnx2x_stats_stop, STATS_STATE_DISABLED}
-}
-};
-
-static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
-{
- enum bnx2x_stats_state state = bp->stats_state;
-
- bnx2x_stats_stm[state][event].action(bp);
- bp->stats_state = bnx2x_stats_stm[state][event].next_state;
-
- if ((event != STATS_EVENT_UPDATE) || (bp->msglevel & NETIF_MSG_TIMER))
- DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
- state, event, bp->stats_state);
-}
-
-static void bnx2x_timer(unsigned long data)
-{
- struct bnx2x *bp = (struct bnx2x *) data;
-
- if (!netif_running(bp->dev))
- return;
-
- if (atomic_read(&bp->intr_sem) != 0)
- goto timer_restart;
-
- if (poll) {
- struct bnx2x_fastpath *fp = &bp->fp[0];
- int rc;
-
- bnx2x_tx_int(fp, 1000);
- rc = bnx2x_rx_int(fp, 1000);
- }
-
- if (!BP_NOMCP(bp)) {
- int func = BP_FUNC(bp);
- u32 drv_pulse;
- u32 mcp_pulse;
-
- ++bp->fw_drv_pulse_wr_seq;
- bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
- /* TBD - add SYSTEM_TIME */
- drv_pulse = bp->fw_drv_pulse_wr_seq;
- SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse);
-
- mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) &
- MCP_PULSE_SEQ_MASK);
- /* The delta between driver pulse and mcp response
- * should be 1 (before mcp response) or 0 (after mcp response)
- */
- if ((drv_pulse != mcp_pulse) &&
- (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) {
- /* someone lost a heartbeat... */
- BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n",
- drv_pulse, mcp_pulse);
- }
- }
-
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED))
- bnx2x_stats_handle(bp, STATS_EVENT_UPDATE);
-
-timer_restart:
- mod_timer(&bp->timer, jiffies + bp->current_interval);
-}
-
-/* end of Statistics */
-
-/* nic init */
-
-/*
- * nic init service functions
- */
-
-static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id)
-{
- int port = BP_PORT(bp);
-
- bnx2x_init_fill(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
- sizeof(struct ustorm_status_block)/4);
- bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
- sizeof(struct cstorm_status_block)/4);
-}
-
-static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
- dma_addr_t mapping, int sb_id)
-{
- int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
- int index;
- u64 section;
-
- /* USTORM */
- section = ((u64)mapping) + offsetof(struct host_status_block,
- u_status_block);
- sb->u_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id), U64_LO(section));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_USTRORM_INTMEM + FP_USB_FUNC_OFF +
- USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
-
- for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_DISABLE_OFFSET(port, sb_id, index), 1);
-
- /* CSTORM */
- section = ((u64)mapping) + offsetof(struct host_status_block,
- c_status_block);
- sb->c_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF +
- CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
-
- for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id, index), 1);
-
- bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-}
-
-static void bnx2x_zero_def_sb(struct bnx2x *bp)
-{
- int func = BP_FUNC(bp);
-
- bnx2x_init_fill(bp, BAR_USTRORM_INTMEM +
- USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
- sizeof(struct ustorm_def_status_block)/4);
- bnx2x_init_fill(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
- sizeof(struct cstorm_def_status_block)/4);
- bnx2x_init_fill(bp, BAR_XSTRORM_INTMEM +
- XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
- sizeof(struct xstorm_def_status_block)/4);
- bnx2x_init_fill(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
- sizeof(struct tstorm_def_status_block)/4);
-}
-
-static void bnx2x_init_def_sb(struct bnx2x *bp,
- struct host_def_status_block *def_sb,
- dma_addr_t mapping, int sb_id)
-{
- int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
- int index, val, reg_offset;
- u64 section;
-
- /* ATTN */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- atten_status_block);
- def_sb->atten_status_block.status_block_id = sb_id;
-
- bp->attn_state = 0;
-
- reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
- MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
-
- for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
- bp->attn_group[index].sig[0] = REG_RD(bp,
- reg_offset + 0x10*index);
- bp->attn_group[index].sig[1] = REG_RD(bp,
- reg_offset + 0x4 + 0x10*index);
- bp->attn_group[index].sig[2] = REG_RD(bp,
- reg_offset + 0x8 + 0x10*index);
- bp->attn_group[index].sig[3] = REG_RD(bp,
- reg_offset + 0xc + 0x10*index);
- }
-
- reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L :
- HC_REG_ATTN_MSG0_ADDR_L);
-
- REG_WR(bp, reg_offset, U64_LO(section));
- REG_WR(bp, reg_offset + 4, U64_HI(section));
-
- reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0);
-
- val = REG_RD(bp, reg_offset);
- val |= sb_id;
- REG_WR(bp, reg_offset, val);
-
- /* USTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- u_def_status_block);
- def_sb->u_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_USTRORM_INTMEM + DEF_USB_FUNC_OFF +
- USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
-
- for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
-
- /* CSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- c_def_status_block);
- def_sb->c_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_CSTRORM_INTMEM +
- ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF +
- CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
-
- for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
-
- /* TSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- t_def_status_block);
- def_sb->t_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF +
- TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
-
- for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_TSTRORM_INTMEM +
- TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
-
- /* XSTORM */
- section = ((u64)mapping) + offsetof(struct host_def_status_block,
- x_def_status_block);
- def_sb->x_def_status_block.status_block_id = sb_id;
-
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
- U64_HI(section));
- REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF +
- XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
-
- for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++)
- REG_WR16(bp, BAR_XSTRORM_INTMEM +
- XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
-
- bp->stats_pending = 0;
- bp->set_mac_pending = 0;
-
- bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-}
-
-static void bnx2x_update_coalesce(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- int i;
-
- for_each_queue(bp, i) {
- int sb_id = bp->fp[i].sb_id;
-
- /* HC_INDEX_U_ETH_RX_CQ_CONS */
- REG_WR8(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
- U_SB_ETH_RX_CQ_INDEX),
- bp->rx_ticks/12);
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
- U_SB_ETH_RX_CQ_INDEX),
- bp->rx_ticks ? 0 : 1);
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
- U_SB_ETH_RX_BD_INDEX),
- bp->rx_ticks ? 0 : 1);
-
- /* HC_INDEX_C_ETH_TX_CQ_CONS */
- REG_WR8(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
- C_SB_ETH_TX_CQ_INDEX),
- bp->tx_ticks/12);
- REG_WR16(bp, BAR_CSTRORM_INTMEM +
- CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
- C_SB_ETH_TX_CQ_INDEX),
- bp->tx_ticks ? 0 : 1);
- }
-}
-
-static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
- struct bnx2x_fastpath *fp, int last)
-{
- int i;
-
- for (i = 0; i < last; i++) {
- struct sw_rx_bd *rx_buf = &(fp->tpa_pool[i]);
- struct sk_buff *skb = rx_buf->skb;
-
- if (skb == NULL) {
- DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i);
- continue;
- }
-
- if (fp->tpa_state[i] == BNX2X_TPA_START)
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
-
- dev_kfree_skb(skb);
- rx_buf->skb = NULL;
- }
-}
-
-static void bnx2x_init_rx_rings(struct bnx2x *bp)
-{
- int func = BP_FUNC(bp);
- int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 :
- ETH_MAX_AGGREGATION_QUEUES_E1H;
- u16 ring_prod, cqe_ring_prod;
- int i, j;
-
- bp->rx_buf_size = bp->dev->mtu;
- bp->rx_buf_size += bp->rx_offset + ETH_OVREHEAD +
- BCM_RX_ETH_PAYLOAD_ALIGN;
-
- if (bp->flags & TPA_ENABLE_FLAG) {
- DP(NETIF_MSG_IFUP,
- "rx_buf_size %d effective_mtu %d\n",
- bp->rx_buf_size, bp->dev->mtu + ETH_OVREHEAD);
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
-
- for (i = 0; i < max_agg_queues; i++) {
- fp->tpa_pool[i].skb =
- netdev_alloc_skb(bp->dev, bp->rx_buf_size);
- if (!fp->tpa_pool[i].skb) {
- BNX2X_ERR("Failed to allocate TPA "
- "skb pool for queue[%d] - "
- "disabling TPA on this "
- "queue!\n", j);
- bnx2x_free_tpa_pool(bp, fp, i);
- fp->disable_tpa = 1;
- break;
- }
- pci_unmap_addr_set((struct sw_rx_bd *)
- &bp->fp->tpa_pool[i],
- mapping, 0);
- fp->tpa_state[i] = BNX2X_TPA_STOP;
- }
- }
- }
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
-
- fp->rx_bd_cons = 0;
- fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
- fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX;
-
- /* "next page" elements initialization */
- /* SGE ring */
- for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
- struct eth_rx_sge *sge;
-
- sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2];
- sge->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_sge_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
- sge->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_sge_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
- }
-
- bnx2x_init_sge_ring_bit_mask(fp);
-
- /* RX BD ring */
- for (i = 1; i <= NUM_RX_RINGS; i++) {
- struct eth_rx_bd *rx_bd;
-
- rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2];
- rx_bd->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
- rx_bd->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
- }
-
- /* CQ ring */
- for (i = 1; i <= NUM_RCQ_RINGS; i++) {
- struct eth_rx_cqe_next_page *nextpg;
-
- nextpg = (struct eth_rx_cqe_next_page *)
- &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1];
- nextpg->addr_hi =
- cpu_to_le32(U64_HI(fp->rx_comp_mapping +
- BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
- nextpg->addr_lo =
- cpu_to_le32(U64_LO(fp->rx_comp_mapping +
- BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
- }
-
- /* Allocate SGEs and initialize the ring elements */
- for (i = 0, ring_prod = 0;
- i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) {
-
- if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) {
- BNX2X_ERR("was only able to allocate "
- "%d rx sges\n", i);
- BNX2X_ERR("disabling TPA for queue[%d]\n", j);
- /* Cleanup already allocated elements */
- bnx2x_free_rx_sge_range(bp, fp, ring_prod);
- bnx2x_free_tpa_pool(bp, fp, max_agg_queues);
- fp->disable_tpa = 1;
- ring_prod = 0;
- break;
- }
- ring_prod = NEXT_SGE_IDX(ring_prod);
- }
- fp->rx_sge_prod = ring_prod;
-
- /* Allocate BDs and initialize BD ring */
- fp->rx_comp_cons = 0;
- cqe_ring_prod = ring_prod = 0;
- for (i = 0; i < bp->rx_ring_size; i++) {
- if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
- BNX2X_ERR("was only able to allocate "
- "%d rx skbs\n", i);
- bp->eth_stats.rx_skb_alloc_failed++;
- break;
- }
- ring_prod = NEXT_RX_IDX(ring_prod);
- cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
- WARN_ON(ring_prod <= i);
- }
-
- fp->rx_bd_prod = ring_prod;
- /* must not have more available CQEs than BDs */
- fp->rx_comp_prod = min((u16)(NUM_RCQ_RINGS*RCQ_DESC_CNT),
- cqe_ring_prod);
- fp->rx_pkt = fp->rx_calls = 0;
-
- /* Warning!
- * this will generate an interrupt (to the TSTORM)
- * must only be done after chip is initialized
- */
- bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod,
- fp->rx_sge_prod);
- if (j != 0)
- continue;
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func),
- U64_LO(fp->rx_comp_mapping));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4,
- U64_HI(fp->rx_comp_mapping));
- }
-}
-
-static void bnx2x_init_tx_ring(struct bnx2x *bp)
-{
- int i, j;
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
-
- for (i = 1; i <= NUM_TX_RINGS; i++) {
- struct eth_tx_bd *tx_bd =
- &fp->tx_desc_ring[TX_DESC_CNT * i - 1];
-
- tx_bd->addr_hi =
- cpu_to_le32(U64_HI(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- tx_bd->addr_lo =
- cpu_to_le32(U64_LO(fp->tx_desc_mapping +
- BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
- }
-
- fp->tx_pkt_prod = 0;
- fp->tx_pkt_cons = 0;
- fp->tx_bd_prod = 0;
- fp->tx_bd_cons = 0;
- fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
- fp->tx_pkt = 0;
- }
-}
-
-static void bnx2x_init_sp_ring(struct bnx2x *bp)
-{
- int func = BP_FUNC(bp);
-
- spin_lock_init(&bp->spq_lock);
-
- bp->spq_left = MAX_SPQ_PENDING;
- bp->spq_prod_idx = 0;
- bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
- bp->spq_prod_bd = bp->spq;
- bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
-
- REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func),
- U64_LO(bp->spq_mapping));
- REG_WR(bp,
- XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4,
- U64_HI(bp->spq_mapping));
-
- REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func),
- bp->spq_prod_idx);
-}
-
-static void bnx2x_init_context(struct bnx2x *bp)
-{
- int i;
-
- for_each_queue(bp, i) {
- struct eth_context *context = bnx2x_sp(bp, context[i].eth);
- struct bnx2x_fastpath *fp = &bp->fp[i];
- u8 sb_id = FP_SB_ID(fp);
-
- context->xstorm_st_context.tx_bd_page_base_hi =
- U64_HI(fp->tx_desc_mapping);
- context->xstorm_st_context.tx_bd_page_base_lo =
- U64_LO(fp->tx_desc_mapping);
- context->xstorm_st_context.db_data_addr_hi =
- U64_HI(fp->tx_prods_mapping);
- context->xstorm_st_context.db_data_addr_lo =
- U64_LO(fp->tx_prods_mapping);
- context->xstorm_st_context.statistics_data = (BP_CL_ID(bp) |
- XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
-
- context->ustorm_st_context.common.sb_index_numbers =
- BNX2X_RX_SB_INDEX_NUM;
- context->ustorm_st_context.common.clientId = FP_CL_ID(fp);
- context->ustorm_st_context.common.status_block_id = sb_id;
- context->ustorm_st_context.common.flags =
- USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT;
- context->ustorm_st_context.common.mc_alignment_size =
- BCM_RX_ETH_PAYLOAD_ALIGN;
- context->ustorm_st_context.common.bd_buff_size =
- bp->rx_buf_size;
- context->ustorm_st_context.common.bd_page_base_hi =
- U64_HI(fp->rx_desc_mapping);
- context->ustorm_st_context.common.bd_page_base_lo =
- U64_LO(fp->rx_desc_mapping);
- if (!fp->disable_tpa) {
- context->ustorm_st_context.common.flags |=
- (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA |
- USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING);
- context->ustorm_st_context.common.sge_buff_size =
- (u16)(BCM_PAGE_SIZE*PAGES_PER_SGE);
- context->ustorm_st_context.common.sge_page_base_hi =
- U64_HI(fp->rx_sge_mapping);
- context->ustorm_st_context.common.sge_page_base_lo =
- U64_LO(fp->rx_sge_mapping);
- }
-
- context->cstorm_st_context.sb_index_number =
- C_SB_ETH_TX_CQ_INDEX;
- context->cstorm_st_context.status_block_id = sb_id;
-
- context->xstorm_ag_context.cdu_reserved =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_XCM_AG,
- ETH_CONNECTION_TYPE);
- context->ustorm_ag_context.cdu_usage =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_UCM_AG,
- ETH_CONNECTION_TYPE);
- }
-}
-
-static void bnx2x_init_ind_table(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- int i;
-
- if (!is_multi(bp))
- return;
-
- DP(NETIF_MSG_IFUP, "Initializing indirection table\n");
- for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
- REG_WR8(bp, BAR_TSTRORM_INTMEM +
- TSTORM_INDIRECTION_TABLE_OFFSET(port) + i,
- i % bp->num_queues);
-
- REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
-}
-
-static void bnx2x_set_client_config(struct bnx2x *bp)
-{
- struct tstorm_eth_client_config tstorm_client = {0};
- int port = BP_PORT(bp);
- int i;
-
- tstorm_client.mtu = bp->dev->mtu + ETH_OVREHEAD;
- tstorm_client.statistics_counter_id = BP_CL_ID(bp);
- tstorm_client.config_flags =
- TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
-#ifdef BCM_VLAN
- if (bp->rx_mode && bp->vlgrp) {
- tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
- DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
- }
-#endif
-
- if (bp->flags & TPA_ENABLE_FLAG) {
- tstorm_client.max_sges_for_packet =
- BCM_PAGE_ALIGN(tstorm_client.mtu) >> BCM_PAGE_SHIFT;
- tstorm_client.max_sges_for_packet =
- ((tstorm_client.max_sges_for_packet +
- PAGES_PER_SGE - 1) & (~(PAGES_PER_SGE - 1))) >>
- PAGES_PER_SGE_SHIFT;
-
- tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING;
- }
-
- for_each_queue(bp, i) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id),
- ((u32 *)&tstorm_client)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4,
- ((u32 *)&tstorm_client)[1]);
- }
-
- DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n",
- ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]);
-}
-
-static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
-{
- struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0};
- int mode = bp->rx_mode;
- int mask = (1 << BP_L_ID(bp));
- int func = BP_FUNC(bp);
- int i;
-
- DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask);
-
- switch (mode) {
- case BNX2X_RX_MODE_NONE: /* no Rx */
- tstorm_mac_filter.ucast_drop_all = mask;
- tstorm_mac_filter.mcast_drop_all = mask;
- tstorm_mac_filter.bcast_drop_all = mask;
- break;
- case BNX2X_RX_MODE_NORMAL:
- tstorm_mac_filter.bcast_accept_all = mask;
- break;
- case BNX2X_RX_MODE_ALLMULTI:
- tstorm_mac_filter.mcast_accept_all = mask;
- tstorm_mac_filter.bcast_accept_all = mask;
- break;
- case BNX2X_RX_MODE_PROMISC:
- tstorm_mac_filter.ucast_accept_all = mask;
- tstorm_mac_filter.mcast_accept_all = mask;
- tstorm_mac_filter.bcast_accept_all = mask;
- break;
- default:
- BNX2X_ERR("BAD rx mode (%d)\n", mode);
- break;
- }
-
- for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4,
- ((u32 *)&tstorm_mac_filter)[i]);
-
-/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
- ((u32 *)&tstorm_mac_filter)[i]); */
- }
-
- if (mode != BNX2X_RX_MODE_NONE)
- bnx2x_set_client_config(bp);
-}
-
-static void bnx2x_init_internal_common(struct bnx2x *bp)
-{
- int i;
-
- if (bp->flags & TPA_ENABLE_FLAG) {
- struct tstorm_eth_tpa_exist tpa = {0};
-
- tpa.tpa_exist = 1;
-
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_TPA_EXIST_OFFSET,
- ((u32 *)&tpa)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_TPA_EXIST_OFFSET + 4,
- ((u32 *)&tpa)[1]);
- }
-
- /* Zero this manually as its initialization is
- currently missing in the initTool */
- for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++)
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_AGG_DATA_OFFSET + i * 4, 0);
-}
-
-static void bnx2x_init_internal_port(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
-
- REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
-}
-
-static void bnx2x_init_internal_func(struct bnx2x *bp)
-{
- struct tstorm_eth_function_common_config tstorm_config = {0};
- struct stats_indication_flags stats_flags = {0};
- int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
- int i;
- u16 max_agg_size;
-
- if (is_multi(bp)) {
- tstorm_config.config_flags = MULTI_FLAGS;
- tstorm_config.rss_result_mask = MULTI_MASK;
- }
-
- tstorm_config.leading_client_id = BP_L_ID(bp);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func),
- (*(u32 *)&tstorm_config));
-
- bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
- bnx2x_set_storm_rx_mode(bp);
-
- /* reset xstorm per client statistics */
- for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) {
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
- i*4, 0);
- }
- /* reset tstorm per client statistics */
- for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
- i*4, 0);
- }
-
- /* Init statistics related context */
- stats_flags.collect_eth = 1;
-
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func),
- ((u32 *)&stats_flags)[0]);
- REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4,
- ((u32 *)&stats_flags)[1]);
-
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
- U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
- U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
-
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
- U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
- U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
-
- if (CHIP_IS_E1H(bp)) {
- REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
- REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
- REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
- REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET,
- IS_E1HMF(bp));
-
- REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func),
- bp->e1hov);
- }
-
- /* Init CQ ring mapping and aggregation size */
- max_agg_size = min((u32)(bp->rx_buf_size +
- 8*BCM_PAGE_SIZE*PAGES_PER_SGE),
- (u32)0xffff);
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)),
- U64_LO(fp->rx_comp_mapping));
- REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4,
- U64_HI(fp->rx_comp_mapping));
-
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
- max_agg_size);
- }
-}
-
-static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
-{
- switch (load_code) {
- case FW_MSG_CODE_DRV_LOAD_COMMON:
- bnx2x_init_internal_common(bp);
- /* no break */
-
- case FW_MSG_CODE_DRV_LOAD_PORT:
- bnx2x_init_internal_port(bp);
- /* no break */
-
- case FW_MSG_CODE_DRV_LOAD_FUNCTION:
- bnx2x_init_internal_func(bp);
- break;
-
- default:
- BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code);
- break;
- }
-}
-
-static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
-{
- int i;
-
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- fp->bp = bp;
- fp->state = BNX2X_FP_STATE_CLOSED;
- fp->index = i;
- fp->cl_id = BP_L_ID(bp) + i;
- fp->sb_id = fp->cl_id;
- DP(NETIF_MSG_IFUP,
- "bnx2x_init_sb(%p,%p) index %d cl_id %d sb %d\n",
- bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp));
- bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping,
- FP_SB_ID(fp));
- bnx2x_update_fpsb_idx(fp);
- }
-
- bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping,
- DEF_SB_ID);
- bnx2x_update_dsb_idx(bp);
- bnx2x_update_coalesce(bp);
- bnx2x_init_rx_rings(bp);
- bnx2x_init_tx_ring(bp);
- bnx2x_init_sp_ring(bp);
- bnx2x_init_context(bp);
- bnx2x_init_internal(bp, load_code);
- bnx2x_init_ind_table(bp);
- bnx2x_int_enable(bp);
-}
-
-/* end of nic init */
-
-/*
- * gzip service functions
- */
-
-static int bnx2x_gunzip_init(struct bnx2x *bp)
-{
- bp->gunzip_buf = pci_alloc_consistent(bp->pdev, FW_BUF_SIZE,
- &bp->gunzip_mapping);
- if (bp->gunzip_buf == NULL)
- goto gunzip_nomem1;
-
- bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL);
- if (bp->strm == NULL)
- goto gunzip_nomem2;
-
- bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(),
- GFP_KERNEL);
- if (bp->strm->workspace == NULL)
- goto gunzip_nomem3;
-
- return 0;
-
-gunzip_nomem3:
- kfree(bp->strm);
- bp->strm = NULL;
-
-gunzip_nomem2:
- pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
- bp->gunzip_mapping);
- bp->gunzip_buf = NULL;
-
-gunzip_nomem1:
- printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for"
- " un-compression\n", bp->dev->name);
- return -ENOMEM;
-}
-
-static void bnx2x_gunzip_end(struct bnx2x *bp)
-{
- kfree(bp->strm->workspace);
-
- kfree(bp->strm);
- bp->strm = NULL;
-
- if (bp->gunzip_buf) {
- pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
- bp->gunzip_mapping);
- bp->gunzip_buf = NULL;
- }
-}
-
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
-{
- int n, rc;
-
- /* check gzip header */
- if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
- return -EINVAL;
-
- n = 10;
-
-#define FNAME 0x8
-
- if (zbuf[3] & FNAME)
- while ((zbuf[n++] != 0) && (n < len));
-
- bp->strm->next_in = zbuf + n;
- bp->strm->avail_in = len - n;
- bp->strm->next_out = bp->gunzip_buf;
- bp->strm->avail_out = FW_BUF_SIZE;
-
- rc = zlib_inflateInit2(bp->strm, -MAX_WBITS);
- if (rc != Z_OK)
- return rc;
-
- rc = zlib_inflate(bp->strm, Z_FINISH);
- if ((rc != Z_OK) && (rc != Z_STREAM_END))
- printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n",
- bp->dev->name, bp->strm->msg);
-
- bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out);
- if (bp->gunzip_outlen & 0x3)
- printk(KERN_ERR PFX "%s: Firmware decompression error:"
- " gunzip_outlen (%d) not aligned\n",
- bp->dev->name, bp->gunzip_outlen);
- bp->gunzip_outlen >>= 2;
-
- zlib_inflateEnd(bp->strm);
-
- if (rc == Z_STREAM_END)
- return 0;
-
- return rc;
-}
-
-/* nic load/unload */
-
-/*
- * General service functions
- */
-
-/* send a NIG loopback debug packet */
-static void bnx2x_lb_pckt(struct bnx2x *bp)
-{
- u32 wb_write[3];
-
- /* Ethernet source and destination addresses */
- wb_write[0] = 0x55555555;
- wb_write[1] = 0x55555555;
- wb_write[2] = 0x20; /* SOP */
- REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
-
- /* NON-IP protocol */
- wb_write[0] = 0x09000000;
- wb_write[1] = 0x55555555;
- wb_write[2] = 0x10; /* EOP, eop_bvalid = 0 */
- REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
-}
-
-/* some of the internal memories
- * are not directly readable from the driver
- * to test them we send debug packets
- */
-static int bnx2x_int_mem_test(struct bnx2x *bp)
-{
- int factor;
- int count, i;
- u32 val = 0;
-
- if (CHIP_REV_IS_FPGA(bp))
- factor = 120;
- else if (CHIP_REV_IS_EMUL(bp))
- factor = 200;
- else
- factor = 1;
-
- DP(NETIF_MSG_HW, "start part1\n");
-
- /* Disable inputs of parser neighbor blocks */
- REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
- REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
- REG_WR(bp, CFC_REG_DEBUG0, 0x1);
- REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0);
-
- /* Write 0 to parser credits for CFC search request */
- REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
-
- /* send Ethernet packet */
- bnx2x_lb_pckt(bp);
-
- /* TODO do i reset NIG statistic? */
- /* Wait until NIG register shows 1 packet of size 0x10 */
- count = 1000 * factor;
- while (count) {
-
- bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
- val = *bnx2x_sp(bp, wb_data[0]);
- if (val == 0x10)
- break;
-
- msleep(10);
- count--;
- }
- if (val != 0x10) {
- BNX2X_ERR("NIG timeout val = 0x%x\n", val);
- return -1;
- }
-
- /* Wait until PRS register shows 1 packet */
- count = 1000 * factor;
- while (count) {
- val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
- if (val == 1)
- break;
-
- msleep(10);
- count--;
- }
- if (val != 0x1) {
- BNX2X_ERR("PRS timeout val = 0x%x\n", val);
- return -2;
- }
-
- /* Reset and init BRB, PRS */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03);
- msleep(50);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
- msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
-
- DP(NETIF_MSG_HW, "part2\n");
-
- /* Disable inputs of parser neighbor blocks */
- REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
- REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
- REG_WR(bp, CFC_REG_DEBUG0, 0x1);
- REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x0);
-
- /* Write 0 to parser credits for CFC search request */
- REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
-
- /* send 10 Ethernet packets */
- for (i = 0; i < 10; i++)
- bnx2x_lb_pckt(bp);
-
- /* Wait until NIG register shows 10 + 1
- packets of size 11*0x10 = 0xb0 */
- count = 1000 * factor;
- while (count) {
-
- bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
- val = *bnx2x_sp(bp, wb_data[0]);
- if (val == 0xb0)
- break;
-
- msleep(10);
- count--;
- }
- if (val != 0xb0) {
- BNX2X_ERR("NIG timeout val = 0x%x\n", val);
- return -3;
- }
-
- /* Wait until PRS register shows 2 packets */
- val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
- if (val != 2)
- BNX2X_ERR("PRS timeout val = 0x%x\n", val);
-
- /* Write 1 to parser credits for CFC search request */
- REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x1);
-
- /* Wait until PRS register shows 3 packets */
- msleep(10 * factor);
- /* Wait until NIG register shows 1 packet of size 0x10 */
- val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
- if (val != 3)
- BNX2X_ERR("PRS timeout val = 0x%x\n", val);
-
- /* clear NIG EOP FIFO */
- for (i = 0; i < 11; i++)
- REG_RD(bp, NIG_REG_INGRESS_EOP_LB_FIFO);
- val = REG_RD(bp, NIG_REG_INGRESS_EOP_LB_EMPTY);
- if (val != 1) {
- BNX2X_ERR("clear of NIG failed\n");
- return -4;
- }
-
- /* Reset and init BRB, PRS, NIG */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03);
- msleep(50);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
- msleep(50);
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
-#ifndef BCM_ISCSI
- /* set NIC mode */
- REG_WR(bp, PRS_REG_NIC_MODE, 1);
-#endif
-
- /* Enable inputs of parser neighbor blocks */
- REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff);
- REG_WR(bp, TCM_REG_PRS_IFEN, 0x1);
- REG_WR(bp, CFC_REG_DEBUG0, 0x0);
- REG_WR(bp, NIG_REG_PRS_REQ_IN_EN, 0x1);
-
- DP(NETIF_MSG_HW, "done\n");
-
- return 0; /* OK */
-}
-
-static void enable_blocks_attention(struct bnx2x *bp)
-{
- REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
- REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0);
- REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
- REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
- REG_WR(bp, QM_REG_QM_INT_MASK, 0);
- REG_WR(bp, TM_REG_TM_INT_MASK, 0);
- REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0);
- REG_WR(bp, XSDM_REG_XSDM_INT_MASK_1, 0);
- REG_WR(bp, XCM_REG_XCM_INT_MASK, 0);
-/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_0, 0); */
-/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_1, 0); */
- REG_WR(bp, USDM_REG_USDM_INT_MASK_0, 0);
- REG_WR(bp, USDM_REG_USDM_INT_MASK_1, 0);
- REG_WR(bp, UCM_REG_UCM_INT_MASK, 0);
-/* REG_WR(bp, USEM_REG_USEM_INT_MASK_0, 0); */
-/* REG_WR(bp, USEM_REG_USEM_INT_MASK_1, 0); */
- REG_WR(bp, GRCBASE_UPB + PB_REG_PB_INT_MASK, 0);
- REG_WR(bp, CSDM_REG_CSDM_INT_MASK_0, 0);
- REG_WR(bp, CSDM_REG_CSDM_INT_MASK_1, 0);
- REG_WR(bp, CCM_REG_CCM_INT_MASK, 0);
-/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */
-/* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */
- if (CHIP_REV_IS_FPGA(bp))
- REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000);
- else
- REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000);
- REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0);
- REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0);
- REG_WR(bp, TCM_REG_TCM_INT_MASK, 0);
-/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */
-/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */
- REG_WR(bp, CDU_REG_CDU_INT_MASK, 0);
- REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0);
-/* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */
- REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18); /* bit 3,4 masked */
-}
-
-
-static int bnx2x_init_common(struct bnx2x *bp)
-{
- u32 val, i;
-
- DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp));
-
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
-
- bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
-
- REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
- msleep(30);
- REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
-
- bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END);
- if (CHIP_IS_E1(bp)) {
- /* enable HW interrupt from PXP on USDM overflow
- bit 16 on INT_MASK_0 */
- REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
- }
-
- bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END);
- bnx2x_init_pxp(bp);
-
-#ifdef __BIG_ENDIAN
- REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
- REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 1);
-
-/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
- REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
- REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1);
- REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1);
- REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
-#endif
-
- REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2);
-#ifdef BCM_ISCSI
- REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5);
- REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5);
- REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5);
-#endif
-
- if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp))
- REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1);
-
- /* let the HW do it's magic ... */
- msleep(100);
- /* finish PXP init */
- val = REG_RD(bp, PXP2_REG_RQ_CFG_DONE);
- if (val != 1) {
- BNX2X_ERR("PXP2 CFG failed\n");
- return -EBUSY;
- }
- val = REG_RD(bp, PXP2_REG_RD_INIT_DONE);
- if (val != 1) {
- BNX2X_ERR("PXP2 RD_INIT failed\n");
- return -EBUSY;
- }
-
- REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
- REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
-
- bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
-
- /* clean the DMAE memory */
- bp->dmae_ready = 1;
- bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
-
- bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END);
- bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END);
- bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END);
- bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END);
-
- bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
- bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
-
- bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
- /* soft reset pulse */
- REG_WR(bp, QM_REG_SOFT_RESET, 1);
- REG_WR(bp, QM_REG_SOFT_RESET, 0);
-
-#ifdef BCM_ISCSI
- bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END);
-#endif
-
- bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
- REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
- if (!CHIP_REV_IS_SLOW(bp)) {
- /* enable hw interrupt from doorbell Q */
- REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
- }
-
- bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- if (CHIP_REV_IS_SLOW(bp)) {
- /* fix for emulation and FPGA for no pause */
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513);
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0);
- }
-
- bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
- /* set NIC mode */
- REG_WR(bp, PRS_REG_NIC_MODE, 1);
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
-
- bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END);
- bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END);
- bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
- bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
-
- if (CHIP_IS_E1H(bp)) {
- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- TSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- CSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- XSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- USTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- } else { /* E1 */
- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- }
-
- bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
- bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
- bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END);
- bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END);
-
- /* sync semi rtc */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0x80000000);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
- 0x80000000);
-
- bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END);
- bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END);
- bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END);
-
- REG_WR(bp, SRC_REG_SOFT_RST, 1);
- for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
- REG_WR(bp, i, 0xc0cac01a);
- /* TODO: replace with something meaningful */
- }
- if (CHIP_IS_E1H(bp))
- bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
- REG_WR(bp, SRC_REG_SOFT_RST, 0);
-
- if (sizeof(union cdu_context) != 1024)
- /* we currently assume that a context is 1024 bytes */
- printk(KERN_ALERT PFX "please adjust the size of"
- " cdu_context(%ld)\n", (long)sizeof(union cdu_context));
-
- bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
- val = (4 << 24) + (0 << 12) + 1024;
- REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
- if (CHIP_IS_E1(bp)) {
- /* !!! fix pxp client crdit until excel update */
- REG_WR(bp, CDU_REG_CDU_DEBUG, 0x264);
- REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
- }
-
- bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
- REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
-
- bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
- bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
-
- /* PXPCS COMMON comes here */
- /* Reset PCIE errors for debug */
- REG_WR(bp, 0x2814, 0xffffffff);
- REG_WR(bp, 0x3820, 0xffffffff);
-
- /* EMAC0 COMMON comes here */
- /* EMAC1 COMMON comes here */
- /* DBU COMMON comes here */
- /* DBG COMMON comes here */
-
- bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
- if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
- REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
- }
-
- if (CHIP_REV_IS_SLOW(bp))
- msleep(200);
-
- /* finish CFC init */
- val = reg_poll(bp, CFC_REG_LL_INIT_DONE, 1, 100, 10);
- if (val != 1) {
- BNX2X_ERR("CFC LL_INIT failed\n");
- return -EBUSY;
- }
- val = reg_poll(bp, CFC_REG_AC_INIT_DONE, 1, 100, 10);
- if (val != 1) {
- BNX2X_ERR("CFC AC_INIT failed\n");
- return -EBUSY;
- }
- val = reg_poll(bp, CFC_REG_CAM_INIT_DONE, 1, 100, 10);
- if (val != 1) {
- BNX2X_ERR("CFC CAM_INIT failed\n");
- return -EBUSY;
- }
- REG_WR(bp, CFC_REG_DEBUG0, 0);
-
- /* read NIG statistic
- to see if this is our first up since powerup */
- bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
- val = *bnx2x_sp(bp, wb_data[0]);
-
- /* do internal memory self test */
- if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) {
- BNX2X_ERR("internal mem self test failed\n");
- return -EBUSY;
- }
-
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
- /* Fan failure is indicated by SPIO 5 */
- bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
- MISC_REGISTERS_SPIO_INPUT_HI_Z);
-
- /* set to active low mode */
- val = REG_RD(bp, MISC_REG_SPIO_INT);
- val |= ((1 << MISC_REGISTERS_SPIO_5) <<
- MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
- REG_WR(bp, MISC_REG_SPIO_INT, val);
-
- /* enable interrupt to signal the IGU */
- val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
- val |= (1 << MISC_REGISTERS_SPIO_5);
- REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
- break;
-
- default:
- break;
- }
-
- /* clear PXP2 attentions */
- REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0);
-
- enable_blocks_attention(bp);
-
- if (!BP_NOMCP(bp)) {
- bnx2x_acquire_phy_lock(bp);
- bnx2x_common_init_phy(bp, bp->common.shmem_base);
- bnx2x_release_phy_lock(bp);
- } else
- BNX2X_ERR("Bootcode is missing - can not initialize link\n");
-
- return 0;
-}
-
-static int bnx2x_init_port(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- u32 val;
-
- DP(BNX2X_MSG_MCP, "starting port init port %x\n", port);
-
- REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
-
- /* Port PXP comes here */
- /* Port PXP2 comes here */
-#ifdef BCM_ISCSI
- /* Port0 1
- * Port1 385 */
- i++;
- wb_write[0] = ONCHIP_ADDR1(bp->timers_mapping);
- wb_write[1] = ONCHIP_ADDR2(bp->timers_mapping);
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
- REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i));
-
- /* Port0 2
- * Port1 386 */
- i++;
- wb_write[0] = ONCHIP_ADDR1(bp->qm_mapping);
- wb_write[1] = ONCHIP_ADDR2(bp->qm_mapping);
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
- REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i));
-
- /* Port0 3
- * Port1 387 */
- i++;
- wb_write[0] = ONCHIP_ADDR1(bp->t1_mapping);
- wb_write[1] = ONCHIP_ADDR2(bp->t1_mapping);
- REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
- REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
-#endif
- /* Port CMs come here */
-
- /* Port QM comes here */
-#ifdef BCM_ISCSI
- REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
- REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
-
- bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START,
- func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
-#endif
- /* Port DQ comes here */
- /* Port BRB1 comes here */
- /* Port PRS comes here */
- /* Port TSDM comes here */
- /* Port CSDM comes here */
- /* Port USDM comes here */
- /* Port XSDM comes here */
- bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
- port ? TSEM_PORT1_END : TSEM_PORT0_END);
- bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
- port ? USEM_PORT1_END : USEM_PORT0_END);
- bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START,
- port ? CSEM_PORT1_END : CSEM_PORT0_END);
- bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
- port ? XSEM_PORT1_END : XSEM_PORT0_END);
- /* Port UPB comes here */
- /* Port XPB comes here */
-
- bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START,
- port ? PBF_PORT1_END : PBF_PORT0_END);
-
- /* configure PBF to work without PAUSE mtu 9000 */
- REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
-
- /* update threshold */
- REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16));
- /* update init credit */
- REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22);
-
- /* probe changes */
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1);
- msleep(5);
- REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0);
-
-#ifdef BCM_ISCSI
- /* tell the searcher where the T2 table is */
- REG_WR(bp, SRC_REG_COUNTFREE0 + func*4, 16*1024/64);
-
- wb_write[0] = U64_LO(bp->t2_mapping);
- wb_write[1] = U64_HI(bp->t2_mapping);
- REG_WR_DMAE(bp, SRC_REG_FIRSTFREE0 + func*4, wb_write, 2);
- wb_write[0] = U64_LO((u64)bp->t2_mapping + 16*1024 - 64);
- wb_write[1] = U64_HI((u64)bp->t2_mapping + 16*1024 - 64);
- REG_WR_DMAE(bp, SRC_REG_LASTFREE0 + func*4, wb_write, 2);
-
- REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + func*4, 10);
- /* Port SRCH comes here */
-#endif
- /* Port CDU comes here */
- /* Port CFC comes here */
-
- if (CHIP_IS_E1(bp)) {
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
- }
- bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START,
- port ? HC_PORT1_END : HC_PORT0_END);
-
- bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START :
- MISC_AEU_PORT0_START,
- port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
- /* init aeu_mask_attn_func_0/1:
- * - SF mode: bits 3-7 are masked. only bits 0-2 are in use
- * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
- * bits 4-7 are used for "per vn group attention" */
- REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4,
- (IS_E1HMF(bp) ? 0xF7 : 0x7));
-
- /* Port PXPCS comes here */
- /* Port EMAC0 comes here */
- /* Port EMAC1 comes here */
- /* Port DBU comes here */
- /* Port DBG comes here */
- bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
- port ? NIG_PORT1_END : NIG_PORT0_END);
-
- REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
-
- if (CHIP_IS_E1H(bp)) {
- u32 wsum;
- struct cmng_struct_per_port m_cmng_port;
- int vn;
-
- /* 0x2 disable e1hov, 0x1 enable */
- REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
- (IS_E1HMF(bp) ? 0x1 : 0x2));
-
- /* Init RATE SHAPING and FAIRNESS contexts.
- Initialize as if there is 10G link. */
- wsum = bnx2x_calc_vn_wsum(bp);
- bnx2x_init_port_minmax(bp, (int)wsum, 10000, &m_cmng_port);
- if (IS_E1HMF(bp))
- for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port,
- wsum, 10000, &m_cmng_port);
- }
-
- /* Port MCP comes here */
- /* Port DMAE comes here */
-
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
- /* add SPIO 5 to group 0 */
- val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
- val |= AEU_INPUTS_ATTN_BITS_SPIO5;
- REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
- break;
-
- default:
- break;
- }
-
- bnx2x__link_reset(bp);
-
- return 0;
-}
-
-#define ILT_PER_FUNC (768/2)
-#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC)
-/* the phys address is shifted right 12 bits and has an added
- 1=valid bit added to the 53rd bit
- then since this is a wide register(TM)
- we split it into two 32 bit writes
- */
-#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
-#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
-#define PXP_ONE_ILT(x) (((x) << 10) | x)
-#define PXP_ILT_RANGE(f, l) (((l) << 10) | f)
-
-#define CNIC_ILT_LINES 0
-
-static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr)
-{
- int reg;
-
- if (CHIP_IS_E1H(bp))
- reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8;
- else /* E1 */
- reg = PXP2_REG_RQ_ONCHIP_AT + index*8;
-
- bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr));
-}
-
-static int bnx2x_init_func(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
- int i;
-
- DP(BNX2X_MSG_MCP, "starting func init func %x\n", func);
-
- i = FUNC_ILT_BASE(func);
-
- bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context));
- if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i);
- REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES);
- } else /* E1 */
- REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4,
- PXP_ILT_RANGE(i, i + CNIC_ILT_LINES));
-
-
- if (CHIP_IS_E1H(bp)) {
- for (i = 0; i < 9; i++)
- bnx2x_init_block(bp,
- cm_start[func][i], cm_end[func][i]);
-
- REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
- REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
- }
-
- /* HC init per function */
- if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
-
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
- }
- bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
-
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, HC_REG_FUNC_NUM_P0 + port*4, func);
-
- /* Reset PCIE errors for debug */
- REG_WR(bp, 0x2114, 0xffffffff);
- REG_WR(bp, 0x2120, 0xffffffff);
-
- return 0;
-}
-
-static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
-{
- int i, rc = 0;
-
- DP(BNX2X_MSG_MCP, "function %d load_code %x\n",
- BP_FUNC(bp), load_code);
-
- bp->dmae_ready = 0;
- mutex_init(&bp->dmae_mutex);
- bnx2x_gunzip_init(bp);
-
- switch (load_code) {
- case FW_MSG_CODE_DRV_LOAD_COMMON:
- rc = bnx2x_init_common(bp);
- if (rc)
- goto init_hw_err;
- /* no break */
-
- case FW_MSG_CODE_DRV_LOAD_PORT:
- bp->dmae_ready = 1;
- rc = bnx2x_init_port(bp);
- if (rc)
- goto init_hw_err;
- /* no break */
-
- case FW_MSG_CODE_DRV_LOAD_FUNCTION:
- bp->dmae_ready = 1;
- rc = bnx2x_init_func(bp);
- if (rc)
- goto init_hw_err;
- break;
-
- default:
- BNX2X_ERR("Unknown load_code (0x%x) from MCP\n", load_code);
- break;
- }
-
- if (!BP_NOMCP(bp)) {
- int func = BP_FUNC(bp);
-
- bp->fw_drv_pulse_wr_seq =
- (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) &
- DRV_PULSE_SEQ_MASK);
- bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
- DP(BNX2X_MSG_MCP, "drv_pulse 0x%x func_stx 0x%x\n",
- bp->fw_drv_pulse_wr_seq, bp->func_stx);
- } else
- bp->func_stx = 0;
-
- /* this needs to be done before gunzip end */
- bnx2x_zero_def_sb(bp);
- for_each_queue(bp, i)
- bnx2x_zero_sb(bp, BP_L_ID(bp) + i);
-
-init_hw_err:
- bnx2x_gunzip_end(bp);
-
- return rc;
-}
-
-/* send the MCP a request, block until there is a reply */
-static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
-{
- int func = BP_FUNC(bp);
- u32 seq = ++bp->fw_seq;
- u32 rc = 0;
- u32 cnt = 1;
- u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
-
- SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
- DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
-
- do {
- /* let the FW do it's magic ... */
- msleep(delay);
-
- rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
-
- /* Give the FW up to 2 second (200*10ms) */
- } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 200));
-
- DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n",
- cnt*delay, rc, seq);
-
- /* is this a reply to our command? */
- if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
- rc &= FW_MSG_CODE_MASK;
-
- } else {
- /* FW BUG! */
- BNX2X_ERR("FW failed to respond!\n");
- bnx2x_fw_dump(bp);
- rc = 0;
- }
-
- return rc;
-}
-
-static void bnx2x_free_mem(struct bnx2x *bp)
-{
-
-#define BNX2X_PCI_FREE(x, y, size) \
- do { \
- if (x) { \
- pci_free_consistent(bp->pdev, size, x, y); \
- x = NULL; \
- y = 0; \
- } \
- } while (0)
-
-#define BNX2X_FREE(x) \
- do { \
- if (x) { \
- vfree(x); \
- x = NULL; \
- } \
- } while (0)
-
- int i;
-
- /* fastpath */
- for_each_queue(bp, i) {
-
- /* Status blocks */
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
- bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_status_block) +
- sizeof(struct eth_tx_db_data));
-
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
- bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
- BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
- bnx2x_fp(bp, i, rx_desc_mapping),
- sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring),
- bnx2x_fp(bp, i, rx_comp_mapping),
- sizeof(struct eth_fast_path_rx_cqe) *
- NUM_RCQ_BD);
-
- /* SGE ring */
- BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring),
- bnx2x_fp(bp, i, rx_sge_mapping),
- BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
- }
- /* end of fastpath */
-
- BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
- sizeof(struct host_def_status_block));
-
- BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
- sizeof(struct bnx2x_slowpath));
-
-#ifdef BCM_ISCSI
- BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024);
- BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024);
- BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024);
- BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024);
-#endif
- BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE);
-
-#undef BNX2X_PCI_FREE
-#undef BNX2X_KFREE
-}
-
-static int bnx2x_alloc_mem(struct bnx2x *bp)
-{
-
-#define BNX2X_PCI_ALLOC(x, y, size) \
- do { \
- x = pci_alloc_consistent(bp->pdev, size, y); \
- if (x == NULL) \
- goto alloc_mem_err; \
- memset(x, 0, size); \
- } while (0)
-
-#define BNX2X_ALLOC(x, size) \
- do { \
- x = vmalloc(size); \
- if (x == NULL) \
- goto alloc_mem_err; \
- memset(x, 0, size); \
- } while (0)
-
- int i;
-
- /* fastpath */
- for_each_queue(bp, i) {
- bnx2x_fp(bp, i, bp) = bp;
-
- /* Status blocks */
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
- &bnx2x_fp(bp, i, status_blk_mapping),
- sizeof(struct host_status_block) +
- sizeof(struct eth_tx_db_data));
-
- bnx2x_fp(bp, i, hw_tx_prods) =
- (void *)(bnx2x_fp(bp, i, status_blk) + 1);
-
- bnx2x_fp(bp, i, tx_prods_mapping) =
- bnx2x_fp(bp, i, status_blk_mapping) +
- sizeof(struct host_status_block);
-
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
- sizeof(struct sw_tx_bd) * NUM_TX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
- &bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
- BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
- sizeof(struct sw_rx_bd) * NUM_RX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
- &bnx2x_fp(bp, i, rx_desc_mapping),
- sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring),
- &bnx2x_fp(bp, i, rx_comp_mapping),
- sizeof(struct eth_fast_path_rx_cqe) *
- NUM_RCQ_BD);
-
- /* SGE ring */
- BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring),
- sizeof(struct sw_rx_page) * NUM_RX_SGE);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring),
- &bnx2x_fp(bp, i, rx_sge_mapping),
- BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
- }
- /* end of fastpath */
-
- BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
- sizeof(struct host_def_status_block));
-
- BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
- sizeof(struct bnx2x_slowpath));
-
-#ifdef BCM_ISCSI
- BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024);
-
- /* Initialize T1 */
- for (i = 0; i < 64*1024; i += 64) {
- *(u64 *)((char *)bp->t1 + i + 56) = 0x0UL;
- *(u64 *)((char *)bp->t1 + i + 3) = 0x0UL;
- }
-
- /* allocate searcher T2 table
- we allocate 1/4 of alloc num for T2
- (which is not entered into the ILT) */
- BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024);
-
- /* Initialize T2 */
- for (i = 0; i < 16*1024; i += 64)
- * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
-
- /* now fixup the last line in the block to point to the next block */
- *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
-
- /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
- BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024);
-
- /* QM queues (128*MAX_CONN) */
- BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024);
-#endif
-
- /* Slow path ring */
- BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE);
-
- return 0;
-
-alloc_mem_err:
- bnx2x_free_mem(bp);
- return -ENOMEM;
-
-#undef BNX2X_PCI_ALLOC
-#undef BNX2X_ALLOC
-}
-
-static void bnx2x_free_tx_skbs(struct bnx2x *bp)
-{
- int i;
-
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- u16 bd_cons = fp->tx_bd_cons;
- u16 sw_prod = fp->tx_pkt_prod;
- u16 sw_cons = fp->tx_pkt_cons;
-
- while (sw_cons != sw_prod) {
- bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons));
- sw_cons++;
- }
- }
-}
-
-static void bnx2x_free_rx_skbs(struct bnx2x *bp)
-{
- int i, j;
-
- for_each_queue(bp, j) {
- struct bnx2x_fastpath *fp = &bp->fp[j];
-
- for (i = 0; i < NUM_RX_BD; i++) {
- struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
- struct sk_buff *skb = rx_buf->skb;
-
- if (skb == NULL)
- continue;
-
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
-
- rx_buf->skb = NULL;
- dev_kfree_skb(skb);
- }
- if (!fp->disable_tpa)
- bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ?
- ETH_MAX_AGGREGATION_QUEUES_E1 :
- ETH_MAX_AGGREGATION_QUEUES_E1H);
- }
-}
-
-static void bnx2x_free_skbs(struct bnx2x *bp)
-{
- bnx2x_free_tx_skbs(bp);
- bnx2x_free_rx_skbs(bp);
-}
-
-static void bnx2x_free_msix_irqs(struct bnx2x *bp)
-{
- int i, offset = 1;
-
- free_irq(bp->msix_table[0].vector, bp->dev);
- DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
- bp->msix_table[0].vector);
-
- for_each_queue(bp, i) {
- DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq "
- "state %x\n", i, bp->msix_table[i + offset].vector,
- bnx2x_fp(bp, i, state));
-
- if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
- BNX2X_ERR("IRQ of fp #%d being freed while "
- "state != closed\n", i);
-
- free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]);
- }
-}
-
-static void bnx2x_free_irq(struct bnx2x *bp)
-{
- if (bp->flags & USING_MSIX_FLAG) {
- bnx2x_free_msix_irqs(bp);
- pci_disable_msix(bp->pdev);
- bp->flags &= ~USING_MSIX_FLAG;
-
- } else
- free_irq(bp->pdev->irq, bp->dev);
-}
-
-static int bnx2x_enable_msix(struct bnx2x *bp)
-{
- int i, rc, offset;
-
- bp->msix_table[0].entry = 0;
- offset = 1;
- DP(NETIF_MSG_IFUP, "msix_table[0].entry = 0 (slowpath)\n");
-
- for_each_queue(bp, i) {
- int igu_vec = offset + i + BP_L_ID(bp);
-
- bp->msix_table[i + offset].entry = igu_vec;
- DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
- "(fastpath #%u)\n", i + offset, igu_vec, i);
- }
-
- rc = pci_enable_msix(bp->pdev, &bp->msix_table[0],
- bp->num_queues + offset);
- if (rc) {
- DP(NETIF_MSG_IFUP, "MSI-X is not attainable\n");
- return -1;
- }
- bp->flags |= USING_MSIX_FLAG;
-
- return 0;
-}
-
-static int bnx2x_req_msix_irqs(struct bnx2x *bp)
-{
- int i, rc, offset = 1;
-
- rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0,
- bp->dev->name, bp->dev);
- if (rc) {
- BNX2X_ERR("request sp irq failed\n");
- return -EBUSY;
- }
-
- for_each_queue(bp, i) {
- rc = request_irq(bp->msix_table[i + offset].vector,
- bnx2x_msix_fp_int, 0,
- bp->dev->name, &bp->fp[i]);
- if (rc) {
- BNX2X_ERR("request fp #%d irq failed rc -%d\n",
- i + offset, -rc);
- bnx2x_free_msix_irqs(bp);
- return -EBUSY;
- }
-
- bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ;
- }
-
- return 0;
-}
-
-static int bnx2x_req_irq(struct bnx2x *bp)
-{
- int rc;
-
- rc = request_irq(bp->pdev->irq, bnx2x_interrupt, IRQF_SHARED,
- bp->dev->name, bp->dev);
- if (!rc)
- bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ;
-
- return rc;
-}
-
-static void bnx2x_napi_enable(struct bnx2x *bp)
-{
- int i;
-
- for_each_queue(bp, i)
- napi_enable(&bnx2x_fp(bp, i, napi));
-}
-
-static void bnx2x_napi_disable(struct bnx2x *bp)
-{
- int i;
-
- for_each_queue(bp, i)
- napi_disable(&bnx2x_fp(bp, i, napi));
-}
-
-static void bnx2x_netif_start(struct bnx2x *bp)
-{
- if (atomic_dec_and_test(&bp->intr_sem)) {
- if (netif_running(bp->dev)) {
- if (bp->state == BNX2X_STATE_OPEN)
- netif_wake_queue(bp->dev);
- bnx2x_napi_enable(bp);
- bnx2x_int_enable(bp);
- }
- }
-}
-
-static void bnx2x_netif_stop(struct bnx2x *bp)
-{
- bnx2x_int_disable_sync(bp);
- if (netif_running(bp->dev)) {
- bnx2x_napi_disable(bp);
- netif_tx_disable(bp->dev);
- bp->dev->trans_start = jiffies; /* prevent tx timeout */
- }
-}
-
-/*
- * Init service functions
- */
-
-static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
-{
- struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
- int port = BP_PORT(bp);
-
- /* CAM allocation
- * unicasts 0-31:port0 32-63:port1
- * multicast 64-127:port0 128-191:port1
- */
- config->hdr.length_6b = 2;
- config->hdr.offset = port ? 31 : 0;
- config->hdr.client_id = BP_CL_ID(bp);
- config->hdr.reserved1 = 0;
-
- /* primary MAC */
- config->config_table[0].cam_entry.msb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[0]);
- config->config_table[0].cam_entry.middle_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[2]);
- config->config_table[0].cam_entry.lsb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[4]);
- config->config_table[0].cam_entry.flags = cpu_to_le16(port);
- if (set)
- config->config_table[0].target_table_entry.flags = 0;
- else
- CAM_INVALIDATE(config->config_table[0]);
- config->config_table[0].target_table_entry.client_id = 0;
- config->config_table[0].target_table_entry.vlan_id = 0;
-
- DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n",
- (set ? "setting" : "clearing"),
- config->config_table[0].cam_entry.msb_mac_addr,
- config->config_table[0].cam_entry.middle_mac_addr,
- config->config_table[0].cam_entry.lsb_mac_addr);
-
- /* broadcast */
- config->config_table[1].cam_entry.msb_mac_addr = 0xffff;
- config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
- config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
- config->config_table[1].cam_entry.flags = cpu_to_le16(port);
- if (set)
- config->config_table[1].target_table_entry.flags =
- TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
- else
- CAM_INVALIDATE(config->config_table[1]);
- config->config_table[1].target_table_entry.client_id = 0;
- config->config_table[1].target_table_entry.vlan_id = 0;
-
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mac_config)),
- U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
-}
-
-static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
-{
- struct mac_configuration_cmd_e1h *config =
- (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config);
-
- if (set && (bp->state != BNX2X_STATE_OPEN)) {
- DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
- return;
- }
-
- /* CAM allocation for E1H
- * unicasts: by func number
- * multicast: 20+FUNC*20, 20 each
- */
- config->hdr.length_6b = 1;
- config->hdr.offset = BP_FUNC(bp);
- config->hdr.client_id = BP_CL_ID(bp);
- config->hdr.reserved1 = 0;
-
- /* primary MAC */
- config->config_table[0].msb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[0]);
- config->config_table[0].middle_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[2]);
- config->config_table[0].lsb_mac_addr =
- swab16(*(u16 *)&bp->dev->dev_addr[4]);
- config->config_table[0].client_id = BP_L_ID(bp);
- config->config_table[0].vlan_id = 0;
- config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov);
- if (set)
- config->config_table[0].flags = BP_PORT(bp);
- else
- config->config_table[0].flags =
- MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE;
-
- DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID %d\n",
- (set ? "setting" : "clearing"),
- config->config_table[0].msb_mac_addr,
- config->config_table[0].middle_mac_addr,
- config->config_table[0].lsb_mac_addr, bp->e1hov, BP_L_ID(bp));
-
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mac_config)),
- U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
-}
-
-static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
- int *state_p, int poll)
-{
- /* can take a while if any port is running */
- int cnt = 500;
-
- DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
- poll ? "polling" : "waiting", state, idx);
-
- might_sleep();
- while (cnt--) {
- if (poll) {
- bnx2x_rx_int(bp->fp, 10);
- /* if index is different from 0
- * the reply for some commands will
- * be on the non default queue
- */
- if (idx)
- bnx2x_rx_int(&bp->fp[idx], 10);
- }
-
- mb(); /* state is changed by bnx2x_sp_event() */
- if (*state_p == state)
- return 0;
-
- msleep(1);
- }
-
- /* timeout! */
- BNX2X_ERR("timeout %s for state %x on IDX [%d]\n",
- poll ? "polling" : "waiting", state, idx);
-#ifdef BNX2X_STOP_ON_ERROR
- bnx2x_panic();
-#endif
-
- return -EBUSY;
-}
-
-static int bnx2x_setup_leading(struct bnx2x *bp)
-{
- int rc;
-
- /* reset IGU state */
- bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-
- /* SETUP ramrod */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0);
-
- /* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0);
-
- return rc;
-}
-
-static int bnx2x_setup_multi(struct bnx2x *bp, int index)
-{
- /* reset IGU state */
- bnx2x_ack_sb(bp, bp->fp[index].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
-
- /* SETUP ramrod */
- bp->fp[index].state = BNX2X_FP_STATE_OPENING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
-
- /* Wait for completion */
- return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
- &(bp->fp[index].state), 0);
-}
-
-static int bnx2x_poll(struct napi_struct *napi, int budget);
-static void bnx2x_set_rx_mode(struct net_device *dev);
-
-/* must be called with rtnl_lock */
-static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
-{
- u32 load_code;
- int i, rc;
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return -EPERM;
-#endif
-
- bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
-
- /* Send LOAD_REQUEST command to MCP
- Returns the type of LOAD command:
- if it is the first port to be initialized
- common blocks should be initialized, otherwise - not
- */
- if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
- if (!load_code) {
- BNX2X_ERR("MCP response failure, aborting\n");
- return -EBUSY;
- }
- if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED)
- return -EBUSY; /* other port in diagnostic mode */
-
- } else {
- int port = BP_PORT(bp);
-
- DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- load_count[0]++;
- load_count[1 + port]++;
- DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- if (load_count[0] == 1)
- load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
- else if (load_count[1 + port] == 1)
- load_code = FW_MSG_CODE_DRV_LOAD_PORT;
- else
- load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION;
- }
-
- if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
- (load_code == FW_MSG_CODE_DRV_LOAD_PORT))
- bp->port.pmf = 1;
- else
- bp->port.pmf = 0;
- DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
-
- /* if we can't use MSI-X we only need one fp,
- * so try to enable MSI-X with the requested number of fp's
- * and fallback to inta with one fp
- */
- if (use_inta) {
- bp->num_queues = 1;
-
- } else {
- if ((use_multi > 1) && (use_multi <= BP_MAX_QUEUES(bp)))
- /* user requested number */
- bp->num_queues = use_multi;
-
- else if (use_multi)
- bp->num_queues = min_t(u32, num_online_cpus(),
- BP_MAX_QUEUES(bp));
- else
- bp->num_queues = 1;
-
- if (bnx2x_enable_msix(bp)) {
- /* failed to enable MSI-X */
- bp->num_queues = 1;
- if (use_multi)
- BNX2X_ERR("Multi requested but failed"
- " to enable MSI-X\n");
- }
- }
- DP(NETIF_MSG_IFUP,
- "set number of queues to %d\n", bp->num_queues);
-
- if (bnx2x_alloc_mem(bp))
- return -ENOMEM;
-
- for_each_queue(bp, i)
- bnx2x_fp(bp, i, disable_tpa) =
- ((bp->flags & TPA_ENABLE_FLAG) == 0);
-
- if (bp->flags & USING_MSIX_FLAG) {
- rc = bnx2x_req_msix_irqs(bp);
- if (rc) {
- pci_disable_msix(bp->pdev);
- goto load_error;
- }
- } else {
- bnx2x_ack_int(bp);
- rc = bnx2x_req_irq(bp);
- if (rc) {
- BNX2X_ERR("IRQ request failed, aborting\n");
- goto load_error;
- }
- }
-
- for_each_queue(bp, i)
- netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
- bnx2x_poll, 128);
-
- /* Initialize HW */
- rc = bnx2x_init_hw(bp, load_code);
- if (rc) {
- BNX2X_ERR("HW init failed, aborting\n");
- goto load_int_disable;
- }
-
- /* Setup NIC internals and enable interrupts */
- bnx2x_nic_init(bp, load_code);
-
- /* Send LOAD_DONE command to MCP */
- if (!BP_NOMCP(bp)) {
- load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
- if (!load_code) {
- BNX2X_ERR("MCP response failure, aborting\n");
- rc = -EBUSY;
- goto load_rings_free;
- }
- }
-
- bnx2x_stats_init(bp);
-
- bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
-
- /* Enable Rx interrupt handling before sending the ramrod
- as it's completed on Rx FP queue */
- bnx2x_napi_enable(bp);
-
- /* Enable interrupt handling */
- atomic_set(&bp->intr_sem, 0);
-
- rc = bnx2x_setup_leading(bp);
- if (rc) {
- BNX2X_ERR("Setup leading failed!\n");
- goto load_netif_stop;
- }
-
- if (CHIP_IS_E1H(bp))
- if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
- BNX2X_ERR("!!! mf_cfg function disabled\n");
- bp->state = BNX2X_STATE_DISABLED;
- }
-
- if (bp->state == BNX2X_STATE_OPEN)
- for_each_nondefault_queue(bp, i) {
- rc = bnx2x_setup_multi(bp, i);
- if (rc)
- goto load_netif_stop;
- }
-
- if (CHIP_IS_E1(bp))
- bnx2x_set_mac_addr_e1(bp, 1);
- else
- bnx2x_set_mac_addr_e1h(bp, 1);
-
- if (bp->port.pmf)
- bnx2x_initial_phy_init(bp);
-
- /* Start fast path */
- switch (load_mode) {
- case LOAD_NORMAL:
- /* Tx queue should be only reenabled */
- netif_wake_queue(bp->dev);
- bnx2x_set_rx_mode(bp->dev);
- break;
-
- case LOAD_OPEN:
- netif_start_queue(bp->dev);
- bnx2x_set_rx_mode(bp->dev);
- if (bp->flags & USING_MSIX_FLAG)
- printk(KERN_INFO PFX "%s: using MSI-X\n",
- bp->dev->name);
- break;
-
- case LOAD_DIAG:
- bnx2x_set_rx_mode(bp->dev);
- bp->state = BNX2X_STATE_DIAG;
- break;
-
- default:
- break;
- }
-
- if (!bp->port.pmf)
- bnx2x__link_status_update(bp);
-
- /* start the timer */
- mod_timer(&bp->timer, jiffies + bp->current_interval);
-
-
- return 0;
-
-load_netif_stop:
- bnx2x_napi_disable(bp);
-load_rings_free:
- /* Free SKBs, SGEs, TPA pool and driver internals */
- bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
- bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
-load_int_disable:
- bnx2x_int_disable_sync(bp);
- /* Release IRQs */
- bnx2x_free_irq(bp);
-load_error:
- bnx2x_free_mem(bp);
-
- /* TBD we really need to reset the chip
- if we want to recover from this */
- return rc;
-}
-
-static int bnx2x_stop_multi(struct bnx2x *bp, int index)
-{
- int rc;
-
- /* halt the connection */
- bp->fp[index].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, index, 0);
-
- /* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
- &(bp->fp[index].state), 1);
- if (rc) /* timeout */
- return rc;
-
- /* delete cfc entry */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
-
- /* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
- &(bp->fp[index].state), 1);
- return rc;
-}
-
-static int bnx2x_stop_leading(struct bnx2x *bp)
-{
- u16 dsb_sp_prod_idx;
- /* if the other port is handling traffic,
- this can take a lot of time */
- int cnt = 500;
- int rc;
-
- might_sleep();
-
- /* Send HALT ramrod */
- bp->fp[0].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, BP_CL_ID(bp), 0);
-
- /* Wait for completion */
- rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
- &(bp->fp[0].state), 1);
- if (rc) /* timeout */
- return rc;
-
- dsb_sp_prod_idx = *bp->dsb_sp_prod;
-
- /* Send PORT_DELETE ramrod */
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
-
- /* Wait for completion to arrive on default status block
- we are going to reset the chip anyway
- so there is not much to do if this times out
- */
- while (dsb_sp_prod_idx == *bp->dsb_sp_prod) {
- if (!cnt) {
- DP(NETIF_MSG_IFDOWN, "timeout waiting for port del "
- "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n",
- *bp->dsb_sp_prod, dsb_sp_prod_idx);
-#ifdef BNX2X_STOP_ON_ERROR
- bnx2x_panic();
-#else
- rc = -EBUSY;
-#endif
- break;
- }
- cnt--;
- msleep(1);
- }
- bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
- bp->fp[0].state = BNX2X_FP_STATE_CLOSED;
-
- return rc;
-}
-
-static void bnx2x_reset_func(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- int func = BP_FUNC(bp);
- int base, i;
-
- /* Configure IGU */
- REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
- REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
-
- REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000);
-
- /* Clear ILT */
- base = FUNC_ILT_BASE(func);
- for (i = base; i < base + ILT_PER_FUNC; i++)
- bnx2x_ilt_wr(bp, i, 0);
-}
-
-static void bnx2x_reset_port(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- u32 val;
-
- REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
-
- /* Do not rcv packets to BRB */
- REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + port*4, 0x0);
- /* Do not direct rcv packets that are not for MCP to the BRB */
- REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP :
- NIG_REG_LLH0_BRB1_NOT_MCP), 0x0);
-
- /* Configure AEU */
- REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, 0);
-
- msleep(100);
- /* Check for BRB port occupancy */
- val = REG_RD(bp, BRB1_REG_PORT_NUM_OCC_BLOCKS_0 + port*4);
- if (val)
- DP(NETIF_MSG_IFDOWN,
- "BRB1 is not empty %d blocks are occupied\n", val);
-
- /* TODO: Close Doorbell port? */
-}
-
-static void bnx2x_reset_common(struct bnx2x *bp)
-{
- /* reset_common */
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0xd3ffff7f);
- REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
-}
-
-static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
-{
- DP(BNX2X_MSG_MCP, "function %d reset_code %x\n",
- BP_FUNC(bp), reset_code);
-
- switch (reset_code) {
- case FW_MSG_CODE_DRV_UNLOAD_COMMON:
- bnx2x_reset_port(bp);
- bnx2x_reset_func(bp);
- bnx2x_reset_common(bp);
- break;
-
- case FW_MSG_CODE_DRV_UNLOAD_PORT:
- bnx2x_reset_port(bp);
- bnx2x_reset_func(bp);
- break;
-
- case FW_MSG_CODE_DRV_UNLOAD_FUNCTION:
- bnx2x_reset_func(bp);
- break;
-
- default:
- BNX2X_ERR("Unknown reset_code (0x%x) from MCP\n", reset_code);
- break;
- }
-}
-
-/* must be called with rtnl_lock */
-static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
-{
- int port = BP_PORT(bp);
- u32 reset_code = 0;
- int i, cnt, rc;
-
- bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
-
- bp->rx_mode = BNX2X_RX_MODE_NONE;
- bnx2x_set_storm_rx_mode(bp);
-
- bnx2x_netif_stop(bp);
- if (!netif_running(bp->dev))
- bnx2x_napi_disable(bp);
- del_timer_sync(&bp->timer);
- SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
- (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
- bnx2x_stats_handle(bp, STATS_EVENT_STOP);
-
- /* Wait until tx fast path tasks complete */
- for_each_queue(bp, i) {
- struct bnx2x_fastpath *fp = &bp->fp[i];
-
- cnt = 1000;
- smp_rmb();
- while (BNX2X_HAS_TX_WORK(fp)) {
-
- bnx2x_tx_int(fp, 1000);
- if (!cnt) {
- BNX2X_ERR("timeout waiting for queue[%d]\n",
- i);
-#ifdef BNX2X_STOP_ON_ERROR
- bnx2x_panic();
- return -EBUSY;
-#else
- break;
-#endif
- }
- cnt--;
- msleep(1);
- smp_rmb();
- }
- }
- /* Give HW time to discard old tx messages */
- msleep(1);
-
- /* Release IRQs */
- bnx2x_free_irq(bp);
-
- if (CHIP_IS_E1(bp)) {
- struct mac_configuration_cmd *config =
- bnx2x_sp(bp, mcast_config);
-
- bnx2x_set_mac_addr_e1(bp, 0);
-
- for (i = 0; i < config->hdr.length_6b; i++)
- CAM_INVALIDATE(config->config_table[i]);
-
- config->hdr.length_6b = i;
- if (CHIP_REV_IS_SLOW(bp))
- config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
- else
- config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port);
- config->hdr.client_id = BP_CL_ID(bp);
- config->hdr.reserved1 = 0;
-
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
- U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);
-
- } else { /* E1H */
- REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
-
- bnx2x_set_mac_addr_e1h(bp, 0);
-
- for (i = 0; i < MC_HASH_SIZE; i++)
- REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
- }
-
- if (unload_mode == UNLOAD_NORMAL)
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
-
- else if (bp->flags & NO_WOL_FLAG) {
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
-
- } else if (bp->wol) {
- u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
- u8 *mac_addr = bp->dev->dev_addr;
- u32 val;
- /* The mac address is written to entries 1-4 to
- preserve entry 0 which is used by the PMF */
- u8 entry = (BP_E1HVN(bp) + 1)*8;
-
- val = (mac_addr[0] << 8) | mac_addr[1];
- EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry, val);
-
- val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
- (mac_addr[4] << 8) | mac_addr[5];
- EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val);
-
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
-
- } else
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
-
- /* Close multi and leading connections
- Completions for ramrods are collected in a synchronous way */
- for_each_nondefault_queue(bp, i)
- if (bnx2x_stop_multi(bp, i))
- goto unload_error;
-
- rc = bnx2x_stop_leading(bp);
- if (rc) {
- BNX2X_ERR("Stop leading failed!\n");
-#ifdef BNX2X_STOP_ON_ERROR
- return -EBUSY;
-#else
- goto unload_error;
-#endif
- }
-
-unload_error:
- if (!BP_NOMCP(bp))
- reset_code = bnx2x_fw_command(bp, reset_code);
- else {
- DP(NETIF_MSG_IFDOWN, "NO MCP load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- load_count[0]--;
- load_count[1 + port]--;
- DP(NETIF_MSG_IFDOWN, "NO MCP new load counts %d, %d, %d\n",
- load_count[0], load_count[1], load_count[2]);
- if (load_count[0] == 0)
- reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
- else if (load_count[1 + port] == 0)
- reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT;
- else
- reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION;
- }
-
- if ((reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) ||
- (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT))
- bnx2x__link_reset(bp);
-
- /* Reset the chip */
- bnx2x_reset_chip(bp, reset_code);
-
- /* Report UNLOAD_DONE to MCP */
- if (!BP_NOMCP(bp))
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
-
- /* Free SKBs, SGEs, TPA pool and driver internals */
- bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
- bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
- bnx2x_free_mem(bp);
-
- bp->state = BNX2X_STATE_CLOSED;
-
- netif_carrier_off(bp->dev);
-
- return 0;
-}
-
-static void bnx2x_reset_task(struct work_struct *work)
-{
- struct bnx2x *bp = container_of(work, struct bnx2x, reset_task);
-
-#ifdef BNX2X_STOP_ON_ERROR
- BNX2X_ERR("reset task called but STOP_ON_ERROR defined"
- " so reset not done to allow debug dump,\n"
- KERN_ERR " you will need to reboot when done\n");
- return;
-#endif
-
- rtnl_lock();
-
- if (!netif_running(bp->dev))
- goto reset_task_exit;
-
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- bnx2x_nic_load(bp, LOAD_NORMAL);
-
-reset_task_exit:
- rtnl_unlock();
-}
-
-/* end of nic load/unload */
-
-/* ethtool_ops */
-
-/*
- * Init service functions
- */
-
-static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
-{
- u32 val;
-
- /* Check if there is any driver already loaded */
- val = REG_RD(bp, MISC_REG_UNPREPARED);
- if (val == 0x1) {
- /* Check if it is the UNDI driver
- * UNDI driver initializes CID offset for normal bell to 0x7
- */
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
- val = REG_RD(bp, DORQ_REG_NORM_CID_OFST);
- if (val == 0x7)
- REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0);
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
-
- if (val == 0x7) {
- u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
- /* save our func */
- int func = BP_FUNC(bp);
- u32 swap_en;
- u32 swap_val;
-
- BNX2X_DEV_INFO("UNDI is active! reset device\n");
-
- /* try unload UNDI on port 0 */
- bp->func = 0;
- bp->fw_seq =
- (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
- DRV_MSG_SEQ_NUMBER_MASK);
- reset_code = bnx2x_fw_command(bp, reset_code);
-
- /* if UNDI is loaded on the other port */
- if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) {
-
- /* send "DONE" for previous unload */
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
-
- /* unload UNDI on port 1 */
- bp->func = 1;
- bp->fw_seq =
- (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
- DRV_MSG_SEQ_NUMBER_MASK);
- reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
-
- bnx2x_fw_command(bp, reset_code);
- }
-
- REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
- HC_REG_CONFIG_0), 0x1000);
-
- /* close input traffic and wait for it */
- /* Do not rcv packets to BRB */
- REG_WR(bp,
- (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK :
- NIG_REG_LLH0_BRB1_DRV_MASK), 0x0);
- /* Do not direct rcv packets that are not for MCP to
- * the BRB */
- REG_WR(bp,
- (BP_PORT(bp) ? NIG_REG_LLH1_BRB1_NOT_MCP :
- NIG_REG_LLH0_BRB1_NOT_MCP), 0x0);
- /* clear AEU */
- REG_WR(bp,
- (BP_PORT(bp) ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
- MISC_REG_AEU_MASK_ATTN_FUNC_0), 0);
- msleep(10);
-
- /* save NIG port swap info */
- swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
- swap_en = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
- /* reset device */
- REG_WR(bp,
- GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
- 0xd3ffffff);
- REG_WR(bp,
- GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
- 0x1403);
- /* take the NIG out of reset and restore swap values */
- REG_WR(bp,
- GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
- MISC_REGISTERS_RESET_REG_1_RST_NIG);
- REG_WR(bp, NIG_REG_PORT_SWAP, swap_val);
- REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en);
-
- /* send unload done to the MCP */
- bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
-
- /* restore our func and fw_seq */
- bp->func = func;
- bp->fw_seq =
- (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
- DRV_MSG_SEQ_NUMBER_MASK);
- }
- }
-}
-
-static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
-{
- u32 val, val2, val3, val4, id;
- u16 pmc;
-
- /* Get the chip revision id and number. */
- /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
- val = REG_RD(bp, MISC_REG_CHIP_NUM);
- id = ((val & 0xffff) << 16);
- val = REG_RD(bp, MISC_REG_CHIP_REV);
- id |= ((val & 0xf) << 12);
- val = REG_RD(bp, MISC_REG_CHIP_METAL);
- id |= ((val & 0xff) << 4);
- REG_RD(bp, MISC_REG_BOND_ID);
- id |= (val & 0xf);
- bp->common.chip_id = id;
- bp->link_params.chip_id = bp->common.chip_id;
- BNX2X_DEV_INFO("chip ID is 0x%x\n", id);
-
- val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4);
- bp->common.flash_size = (NVRAM_1MB_SIZE <<
- (val & MCPR_NVM_CFG4_FLASH_SIZE));
- BNX2X_DEV_INFO("flash_size 0x%x (%d)\n",
- bp->common.flash_size, bp->common.flash_size);
-
- bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
- bp->link_params.shmem_base = bp->common.shmem_base;
- BNX2X_DEV_INFO("shmem offset is 0x%x\n", bp->common.shmem_base);
-
- if (!bp->common.shmem_base ||
- (bp->common.shmem_base < 0xA0000) ||
- (bp->common.shmem_base >= 0xC0000)) {
- BNX2X_DEV_INFO("MCP not active\n");
- bp->flags |= NO_MCP_FLAG;
- return;
- }
-
- val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
- if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
- != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
- BNX2X_ERR("BAD MCP validity signature\n");
-
- bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
- bp->common.board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
-
- BNX2X_DEV_INFO("hw_config 0x%08x board 0x%08x\n",
- bp->common.hw_config, bp->common.board);
-
- bp->link_params.hw_led_mode = ((bp->common.hw_config &
- SHARED_HW_CFG_LED_MODE_MASK) >>
- SHARED_HW_CFG_LED_MODE_SHIFT);
-
- val = SHMEM_RD(bp, dev_info.bc_rev) >> 8;
- bp->common.bc_ver = val;
- BNX2X_DEV_INFO("bc_ver %X\n", val);
- if (val < BNX2X_BC_VER) {
- /* for now only warn
- * later we might need to enforce this */
- BNX2X_ERR("This driver needs bc_ver %X but found %X,"
- " please upgrade BC\n", BNX2X_BC_VER, val);
- }
-
- if (BP_E1HVN(bp) == 0) {
- pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
- bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
- } else {
- /* no WOL capability for E1HVN != 0 */
- bp->flags |= NO_WOL_FLAG;
- }
- BNX2X_DEV_INFO("%sWoL capable\n",
- (bp->flags & NO_WOL_FLAG) ? "Not " : "");
-
- val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
- val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
- val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]);
- val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]);
-
- printk(KERN_INFO PFX "part number %X-%X-%X-%X\n",
- val, val2, val3, val4);
-}
-
-static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
- u32 switch_cfg)
-{
- int port = BP_PORT(bp);
- u32 ext_phy_type;
-
- switch (switch_cfg) {
- case SWITCH_CFG_1G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg);
-
- ext_phy_type =
- SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD SerDes ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
- return;
- }
-
- bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR +
- port*0x10);
- BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
- break;
-
- case SWITCH_CFG_10G:
- BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg);
-
- ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_2500baseX_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
- ext_phy_type);
-
- bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_TP |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause);
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD XGXS ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
- return;
- }
-
- bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR +
- port*0x18);
- BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr);
-
- break;
-
- default:
- BNX2X_ERR("BAD switch_cfg link_config 0x%x\n",
- bp->port.link_config);
- return;
- }
- bp->link_params.phy_addr = bp->port.phy_addr;
-
- /* mask what we support according to speed_cap_mask */
- if (!(bp->link_params.speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
- bp->port.supported &= ~SUPPORTED_10baseT_Half;
-
- if (!(bp->link_params.speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
- bp->port.supported &= ~SUPPORTED_10baseT_Full;
-
- if (!(bp->link_params.speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
- bp->port.supported &= ~SUPPORTED_100baseT_Half;
-
- if (!(bp->link_params.speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
- bp->port.supported &= ~SUPPORTED_100baseT_Full;
-
- if (!(bp->link_params.speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
- bp->port.supported &= ~(SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full);
-
- if (!(bp->link_params.speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
- bp->port.supported &= ~SUPPORTED_2500baseX_Full;
-
- if (!(bp->link_params.speed_cap_mask &
- PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
- bp->port.supported &= ~SUPPORTED_10000baseT_Full;
-
- BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported);
-}
-
-static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
-{
- bp->link_params.req_duplex = DUPLEX_FULL;
-
- switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) {
- case PORT_FEATURE_LINK_SPEED_AUTO:
- if (bp->port.supported & SUPPORTED_Autoneg) {
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->port.advertising = bp->port.supported;
- } else {
- u32 ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- if ((ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
- (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
- /* force 10G, no AN */
- bp->link_params.req_line_speed = SPEED_10000;
- bp->port.advertising =
- (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- break;
- }
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " Autoneg not supported\n",
- bp->port.link_config);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_10M_FULL:
- if (bp->port.supported & SUPPORTED_10baseT_Full) {
- bp->link_params.req_line_speed = SPEED_10;
- bp->port.advertising = (ADVERTISED_10baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_10M_HALF:
- if (bp->port.supported & SUPPORTED_10baseT_Half) {
- bp->link_params.req_line_speed = SPEED_10;
- bp->link_params.req_duplex = DUPLEX_HALF;
- bp->port.advertising = (ADVERTISED_10baseT_Half |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_100M_FULL:
- if (bp->port.supported & SUPPORTED_100baseT_Full) {
- bp->link_params.req_line_speed = SPEED_100;
- bp->port.advertising = (ADVERTISED_100baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_100M_HALF:
- if (bp->port.supported & SUPPORTED_100baseT_Half) {
- bp->link_params.req_line_speed = SPEED_100;
- bp->link_params.req_duplex = DUPLEX_HALF;
- bp->port.advertising = (ADVERTISED_100baseT_Half |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_1G:
- if (bp->port.supported & SUPPORTED_1000baseT_Full) {
- bp->link_params.req_line_speed = SPEED_1000;
- bp->port.advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_2_5G:
- if (bp->port.supported & SUPPORTED_2500baseX_Full) {
- bp->link_params.req_line_speed = SPEED_2500;
- bp->port.advertising = (ADVERTISED_2500baseX_Full |
- ADVERTISED_TP);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
-
- case PORT_FEATURE_LINK_SPEED_10G_CX4:
- case PORT_FEATURE_LINK_SPEED_10G_KX4:
- case PORT_FEATURE_LINK_SPEED_10G_KR:
- if (bp->port.supported & SUPPORTED_10000baseT_Full) {
- bp->link_params.req_line_speed = SPEED_10000;
- bp->port.advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- } else {
- BNX2X_ERR("NVRAM config error. "
- "Invalid link_config 0x%x"
- " speed_cap_mask 0x%x\n",
- bp->port.link_config,
- bp->link_params.speed_cap_mask);
- return;
- }
- break;
-
- default:
- BNX2X_ERR("NVRAM config error. "
- "BAD link speed link_config 0x%x\n",
- bp->port.link_config);
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->port.advertising = bp->port.supported;
- break;
- }
-
- bp->link_params.req_flow_ctrl = (bp->port.link_config &
- PORT_FEATURE_FLOW_CONTROL_MASK);
- if ((bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO) &&
- !(bp->port.supported & SUPPORTED_Autoneg))
- bp->link_params.req_flow_ctrl = FLOW_CTRL_NONE;
-
- BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x"
- " advertising 0x%x\n",
- bp->link_params.req_line_speed,
- bp->link_params.req_duplex,
- bp->link_params.req_flow_ctrl, bp->port.advertising);
-}
-
-static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- u32 val, val2;
-
- bp->link_params.bp = bp;
- bp->link_params.port = port;
-
- bp->link_params.serdes_config =
- SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
- bp->link_params.lane_config =
- SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
- bp->link_params.ext_phy_config =
- SHMEM_RD(bp,
- dev_info.port_hw_config[port].external_phy_config);
- bp->link_params.speed_cap_mask =
- SHMEM_RD(bp,
- dev_info.port_hw_config[port].speed_capability_mask);
-
- bp->port.link_config =
- SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
-
- BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n"
- KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x"
- " link_config 0x%08x\n",
- bp->link_params.serdes_config,
- bp->link_params.lane_config,
- bp->link_params.ext_phy_config,
- bp->link_params.speed_cap_mask, bp->port.link_config);
-
- bp->link_params.switch_cfg = (bp->port.link_config &
- PORT_FEATURE_CONNECTED_SWITCH_MASK);
- bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg);
-
- bnx2x_link_settings_requested(bp);
-
- val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
- val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
- bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
- bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
- bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
- bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
- bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff);
- bp->dev->dev_addr[5] = (u8)(val & 0xff);
- memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
-}
-
-static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
-{
- int func = BP_FUNC(bp);
- u32 val, val2;
- int rc = 0;
-
- bnx2x_get_common_hwinfo(bp);
-
- bp->e1hov = 0;
- bp->e1hmf = 0;
- if (CHIP_IS_E1H(bp)) {
- bp->mf_config =
- SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
-
- val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func].e1hov_tag) &
- FUNC_MF_CFG_E1HOV_TAG_MASK);
- if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
-
- bp->e1hov = val;
- bp->e1hmf = 1;
- BNX2X_DEV_INFO("MF mode E1HOV for func %d is %d "
- "(0x%04x)\n",
- func, bp->e1hov, bp->e1hov);
- } else {
- BNX2X_DEV_INFO("Single function mode\n");
- if (BP_E1HVN(bp)) {
- BNX2X_ERR("!!! No valid E1HOV for func %d,"
- " aborting\n", func);
- rc = -EPERM;
- }
- }
- }
-
- if (!BP_NOMCP(bp)) {
- bnx2x_get_port_hwinfo(bp);
-
- bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) &
- DRV_MSG_SEQ_NUMBER_MASK);
- BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
- }
-
- if (IS_E1HMF(bp)) {
- val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper);
- val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower);
- if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) &&
- (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) {
- bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
- bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
- bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
- bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
- bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff);
- bp->dev->dev_addr[5] = (u8)(val & 0xff);
- memcpy(bp->link_params.mac_addr, bp->dev->dev_addr,
- ETH_ALEN);
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr,
- ETH_ALEN);
- }
-
- return rc;
- }
-
- if (BP_NOMCP(bp)) {
- /* only supposed to happen on emulation/FPGA */
- BNX2X_ERR("warning random MAC workaround active\n");
- random_ether_addr(bp->dev->dev_addr);
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN);
- }
-
- return rc;
-}
-
-static int __devinit bnx2x_init_bp(struct bnx2x *bp)
-{
- int func = BP_FUNC(bp);
- int rc;
-
- /* Disable interrupt handling until HW is initialized */
- atomic_set(&bp->intr_sem, 1);
-
- mutex_init(&bp->port.phy_mutex);
-
- INIT_WORK(&bp->sp_task, bnx2x_sp_task);
- INIT_WORK(&bp->reset_task, bnx2x_reset_task);
-
- rc = bnx2x_get_hwinfo(bp);
-
- /* need to reset chip if undi was active */
- if (!BP_NOMCP(bp))
- bnx2x_undi_unload(bp);
-
- if (CHIP_REV_IS_FPGA(bp))
- printk(KERN_ERR PFX "FPGA detected\n");
-
- if (BP_NOMCP(bp) && (func == 0))
- printk(KERN_ERR PFX
- "MCP disabled, must load devices in order!\n");
-
- /* Set TPA flags */
- if (disable_tpa) {
- bp->flags &= ~TPA_ENABLE_FLAG;
- bp->dev->features &= ~NETIF_F_LRO;
- } else {
- bp->flags |= TPA_ENABLE_FLAG;
- bp->dev->features |= NETIF_F_LRO;
- }
-
-
- bp->tx_ring_size = MAX_TX_AVAIL;
- bp->rx_ring_size = MAX_RX_AVAIL;
-
- bp->rx_csum = 1;
- bp->rx_offset = 0;
-
- bp->tx_ticks = 50;
- bp->rx_ticks = 25;
-
- bp->timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
- bp->current_interval = (poll ? poll : bp->timer_interval);
-
- init_timer(&bp->timer);
- bp->timer.expires = jiffies + bp->current_interval;
- bp->timer.data = (unsigned long) bp;
- bp->timer.function = bnx2x_timer;
-
- return rc;
-}
-
-/*
- * ethtool service functions
- */
-
-/* All ethtool functions called with rtnl_lock */
-
-static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- cmd->supported = bp->port.supported;
- cmd->advertising = bp->port.advertising;
-
- if (netif_carrier_ok(dev)) {
- cmd->speed = bp->link_vars.line_speed;
- cmd->duplex = bp->link_vars.duplex;
- } else {
- cmd->speed = bp->link_params.req_line_speed;
- cmd->duplex = bp->link_params.req_duplex;
- }
- if (IS_E1HMF(bp)) {
- u16 vn_max_rate;
-
- vn_max_rate = ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
- FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
- if (vn_max_rate < cmd->speed)
- cmd->speed = vn_max_rate;
- }
-
- if (bp->link_params.switch_cfg == SWITCH_CFG_10G) {
- u32 ext_phy_type =
- XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- switch (ext_phy_type) {
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- cmd->port = PORT_FIBRE;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
- cmd->port = PORT_TP;
- break;
-
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
- BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
-
- default:
- DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
- bp->link_params.ext_phy_config);
- break;
- }
- } else
- cmd->port = PORT_TP;
-
- cmd->phy_address = bp->port.phy_addr;
- cmd->transceiver = XCVR_INTERNAL;
-
- if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
- cmd->autoneg = AUTONEG_ENABLE;
- else
- cmd->autoneg = AUTONEG_DISABLE;
-
- cmd->maxtxpkt = 0;
- cmd->maxrxpkt = 0;
-
- DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
- DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
- DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
- cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
- cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
-
- return 0;
-}
-
-static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
- struct bnx2x *bp = netdev_priv(dev);
- u32 advertising;
-
- if (IS_E1HMF(bp))
- return 0;
-
- DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
- DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
- DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
- DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
- cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
- cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
- cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
-
- if (cmd->autoneg == AUTONEG_ENABLE) {
- if (!(bp->port.supported & SUPPORTED_Autoneg)) {
- DP(NETIF_MSG_LINK, "Autoneg not supported\n");
- return -EINVAL;
- }
-
- /* advertise the requested speed and duplex if supported */
- cmd->advertising &= bp->port.supported;
-
- bp->link_params.req_line_speed = SPEED_AUTO_NEG;
- bp->link_params.req_duplex = DUPLEX_FULL;
- bp->port.advertising |= (ADVERTISED_Autoneg |
- cmd->advertising);
-
- } else { /* forced speed */
- /* advertise the requested speed and duplex if supported */
- switch (cmd->speed) {
- case SPEED_10:
- if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->port.supported &
- SUPPORTED_10baseT_Full)) {
- DP(NETIF_MSG_LINK,
- "10M full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_10baseT_Full |
- ADVERTISED_TP);
- } else {
- if (!(bp->port.supported &
- SUPPORTED_10baseT_Half)) {
- DP(NETIF_MSG_LINK,
- "10M half not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_10baseT_Half |
- ADVERTISED_TP);
- }
- break;
-
- case SPEED_100:
- if (cmd->duplex == DUPLEX_FULL) {
- if (!(bp->port.supported &
- SUPPORTED_100baseT_Full)) {
- DP(NETIF_MSG_LINK,
- "100M full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_100baseT_Full |
- ADVERTISED_TP);
- } else {
- if (!(bp->port.supported &
- SUPPORTED_100baseT_Half)) {
- DP(NETIF_MSG_LINK,
- "100M half not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_100baseT_Half |
- ADVERTISED_TP);
- }
- break;
-
- case SPEED_1000:
- if (cmd->duplex != DUPLEX_FULL) {
- DP(NETIF_MSG_LINK, "1G half not supported\n");
- return -EINVAL;
- }
-
- if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) {
- DP(NETIF_MSG_LINK, "1G full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_1000baseT_Full |
- ADVERTISED_TP);
- break;
-
- case SPEED_2500:
- if (cmd->duplex != DUPLEX_FULL) {
- DP(NETIF_MSG_LINK,
- "2.5G half not supported\n");
- return -EINVAL;
- }
-
- if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) {
- DP(NETIF_MSG_LINK,
- "2.5G full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_2500baseX_Full |
- ADVERTISED_TP);
- break;
-
- case SPEED_10000:
- if (cmd->duplex != DUPLEX_FULL) {
- DP(NETIF_MSG_LINK, "10G half not supported\n");
- return -EINVAL;
- }
-
- if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) {
- DP(NETIF_MSG_LINK, "10G full not supported\n");
- return -EINVAL;
- }
-
- advertising = (ADVERTISED_10000baseT_Full |
- ADVERTISED_FIBRE);
- break;
-
- default:
- DP(NETIF_MSG_LINK, "Unsupported speed\n");
- return -EINVAL;
- }
-
- bp->link_params.req_line_speed = cmd->speed;
- bp->link_params.req_duplex = cmd->duplex;
- bp->port.advertising = advertising;
- }
-
- DP(NETIF_MSG_LINK, "req_line_speed %d\n"
- DP_LEVEL " req_duplex %d advertising 0x%x\n",
- bp->link_params.req_line_speed, bp->link_params.req_duplex,
- bp->port.advertising);
-
- if (netif_running(dev)) {
- bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- bnx2x_link_set(bp);
- }
-
- return 0;
-}
-
-#define PHY_FW_VER_LEN 10
-
-static void bnx2x_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct bnx2x *bp = netdev_priv(dev);
- u8 phy_fw_ver[PHY_FW_VER_LEN];
-
- strcpy(info->driver, DRV_MODULE_NAME);
- strcpy(info->version, DRV_MODULE_VERSION);
-
- phy_fw_ver[0] = '\0';
- if (bp->port.pmf) {
- bnx2x_acquire_phy_lock(bp);
- bnx2x_get_ext_phy_fw_version(&bp->link_params,
- (bp->state != BNX2X_STATE_CLOSED),
- phy_fw_ver, PHY_FW_VER_LEN);
- bnx2x_release_phy_lock(bp);
- }
-
- snprintf(info->fw_version, 32, "BC:%d.%d.%d%s%s",
- (bp->common.bc_ver & 0xff0000) >> 16,
- (bp->common.bc_ver & 0xff00) >> 8,
- (bp->common.bc_ver & 0xff),
- ((phy_fw_ver[0] != '\0') ? " PHY:" : ""), phy_fw_ver);
- strcpy(info->bus_info, pci_name(bp->pdev));
- info->n_stats = BNX2X_NUM_STATS;
- info->testinfo_len = BNX2X_NUM_TESTS;
- info->eedump_len = bp->common.flash_size;
- info->regdump_len = 0;
-}
-
-static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (bp->flags & NO_WOL_FLAG) {
- wol->supported = 0;
- wol->wolopts = 0;
- } else {
- wol->supported = WAKE_MAGIC;
- if (bp->wol)
- wol->wolopts = WAKE_MAGIC;
- else
- wol->wolopts = 0;
- }
- memset(&wol->sopass, 0, sizeof(wol->sopass));
-}
-
-static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (wol->wolopts & ~WAKE_MAGIC)
- return -EINVAL;
-
- if (wol->wolopts & WAKE_MAGIC) {
- if (bp->flags & NO_WOL_FLAG)
- return -EINVAL;
-
- bp->wol = 1;
- } else
- bp->wol = 0;
-
- return 0;
-}
-
-static u32 bnx2x_get_msglevel(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- return bp->msglevel;
-}
-
-static void bnx2x_set_msglevel(struct net_device *dev, u32 level)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (capable(CAP_NET_ADMIN))
- bp->msglevel = level;
-}
-
-static int bnx2x_nway_reset(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (!bp->port.pmf)
- return 0;
-
- if (netif_running(dev)) {
- bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- bnx2x_link_set(bp);
- }
-
- return 0;
-}
-
-static int bnx2x_get_eeprom_len(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- return bp->common.flash_size;
-}
-
-static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- int count, i;
- u32 val = 0;
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* request access to nvram interface */
- REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
- (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port));
-
- for (i = 0; i < count*10; i++) {
- val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
- if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))
- break;
-
- udelay(5);
- }
-
- if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) {
- DP(BNX2X_MSG_NVM, "cannot get access to nvram interface\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int bnx2x_release_nvram_lock(struct bnx2x *bp)
-{
- int port = BP_PORT(bp);
- int count, i;
- u32 val = 0;
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* relinquish nvram interface */
- REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
- (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port));
-
- for (i = 0; i < count*10; i++) {
- val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
- if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)))
- break;
-
- udelay(5);
- }
-
- if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) {
- DP(BNX2X_MSG_NVM, "cannot free access to nvram interface\n");
- return -EBUSY;
- }
-
- return 0;
-}
-
-static void bnx2x_enable_nvram_access(struct bnx2x *bp)
-{
- u32 val;
-
- val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
-
- /* enable both bits, even on read */
- REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
- (val | MCPR_NVM_ACCESS_ENABLE_EN |
- MCPR_NVM_ACCESS_ENABLE_WR_EN));
-}
-
-static void bnx2x_disable_nvram_access(struct bnx2x *bp)
-{
- u32 val;
-
- val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
-
- /* disable both bits, even after read */
- REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
- (val & ~(MCPR_NVM_ACCESS_ENABLE_EN |
- MCPR_NVM_ACCESS_ENABLE_WR_EN)));
-}
-
-static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
- u32 cmd_flags)
-{
- int count, i, rc;
- u32 val;
-
- /* build the command word */
- cmd_flags |= MCPR_NVM_COMMAND_DOIT;
-
- /* need to clear DONE bit separately */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
-
- /* address of the NVRAM to read from */
- REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
- (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
-
- /* issue a read command */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* wait for completion */
- *ret_val = 0;
- rc = -EBUSY;
- for (i = 0; i < count; i++) {
- udelay(5);
- val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
-
- if (val & MCPR_NVM_COMMAND_DONE) {
- val = REG_RD(bp, MCP_REG_MCPR_NVM_READ);
- /* we read nvram data in cpu order
- * but ethtool sees it as an array of bytes
- * converting to big-endian will do the work */
- val = cpu_to_be32(val);
- *ret_val = val;
- rc = 0;
- break;
- }
- }
-
- return rc;
-}
-
-static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
- int buf_size)
-{
- int rc;
- u32 cmd_flags;
- u32 val;
-
- if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
- DP(BNX2X_MSG_NVM,
- "Invalid parameter: offset 0x%x buf_size 0x%x\n",
- offset, buf_size);
- return -EINVAL;
- }
-
- if (offset + buf_size > bp->common.flash_size) {
- DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
- " buf_size (0x%x) > flash_size (0x%x)\n",
- offset, buf_size, bp->common.flash_size);
- return -EINVAL;
- }
-
- /* request access to nvram interface */
- rc = bnx2x_acquire_nvram_lock(bp);
- if (rc)
- return rc;
-
- /* enable access to nvram interface */
- bnx2x_enable_nvram_access(bp);
-
- /* read the first word(s) */
- cmd_flags = MCPR_NVM_COMMAND_FIRST;
- while ((buf_size > sizeof(u32)) && (rc == 0)) {
- rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
- memcpy(ret_buf, &val, 4);
-
- /* advance to the next dword */
- offset += sizeof(u32);
- ret_buf += sizeof(u32);
- buf_size -= sizeof(u32);
- cmd_flags = 0;
- }
-
- if (rc == 0) {
- cmd_flags |= MCPR_NVM_COMMAND_LAST;
- rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
- memcpy(ret_buf, &val, 4);
- }
-
- /* disable access to nvram interface */
- bnx2x_disable_nvram_access(bp);
- bnx2x_release_nvram_lock(bp);
-
- return rc;
-}
-
-static int bnx2x_get_eeprom(struct net_device *dev,
- struct ethtool_eeprom *eeprom, u8 *eebuf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc;
-
- DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
- DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
- eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
- eeprom->len, eeprom->len);
-
- /* parameters already validated in ethtool_get_eeprom */
-
- rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
-
- return rc;
-}
-
-static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
- u32 cmd_flags)
-{
- int count, i, rc;
-
- /* build the command word */
- cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
-
- /* need to clear DONE bit separately */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
-
- /* write the data */
- REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val);
-
- /* address of the NVRAM to write to */
- REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
- (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
-
- /* issue the write command */
- REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
-
- /* adjust timeout for emulation/FPGA */
- count = NVRAM_TIMEOUT_COUNT;
- if (CHIP_REV_IS_SLOW(bp))
- count *= 100;
-
- /* wait for completion */
- rc = -EBUSY;
- for (i = 0; i < count; i++) {
- udelay(5);
- val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
- if (val & MCPR_NVM_COMMAND_DONE) {
- rc = 0;
- break;
- }
- }
-
- return rc;
-}
-
-#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
-
-static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
- int buf_size)
-{
- int rc;
- u32 cmd_flags;
- u32 align_offset;
- u32 val;
-
- if (offset + buf_size > bp->common.flash_size) {
- DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
- " buf_size (0x%x) > flash_size (0x%x)\n",
- offset, buf_size, bp->common.flash_size);
- return -EINVAL;
- }
-
- /* request access to nvram interface */
- rc = bnx2x_acquire_nvram_lock(bp);
- if (rc)
- return rc;
-
- /* enable access to nvram interface */
- bnx2x_enable_nvram_access(bp);
-
- cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST);
- align_offset = (offset & ~0x03);
- rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags);
-
- if (rc == 0) {
- val &= ~(0xff << BYTE_OFFSET(offset));
- val |= (*data_buf << BYTE_OFFSET(offset));
-
- /* nvram data is returned as an array of bytes
- * convert it back to cpu order */
- val = be32_to_cpu(val);
-
- rc = bnx2x_nvram_write_dword(bp, align_offset, val,
- cmd_flags);
- }
-
- /* disable access to nvram interface */
- bnx2x_disable_nvram_access(bp);
- bnx2x_release_nvram_lock(bp);
-
- return rc;
-}
-
-static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
- int buf_size)
-{
- int rc;
- u32 cmd_flags;
- u32 val;
- u32 written_so_far;
-
- if (buf_size == 1) /* ethtool */
- return bnx2x_nvram_write1(bp, offset, data_buf, buf_size);
-
- if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
- DP(BNX2X_MSG_NVM,
- "Invalid parameter: offset 0x%x buf_size 0x%x\n",
- offset, buf_size);
- return -EINVAL;
- }
-
- if (offset + buf_size > bp->common.flash_size) {
- DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
- " buf_size (0x%x) > flash_size (0x%x)\n",
- offset, buf_size, bp->common.flash_size);
- return -EINVAL;
- }
-
- /* request access to nvram interface */
- rc = bnx2x_acquire_nvram_lock(bp);
- if (rc)
- return rc;
-
- /* enable access to nvram interface */
- bnx2x_enable_nvram_access(bp);
-
- written_so_far = 0;
- cmd_flags = MCPR_NVM_COMMAND_FIRST;
- while ((written_so_far < buf_size) && (rc == 0)) {
- if (written_so_far == (buf_size - sizeof(u32)))
- cmd_flags |= MCPR_NVM_COMMAND_LAST;
- else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0)
- cmd_flags |= MCPR_NVM_COMMAND_LAST;
- else if ((offset % NVRAM_PAGE_SIZE) == 0)
- cmd_flags |= MCPR_NVM_COMMAND_FIRST;
-
- memcpy(&val, data_buf, 4);
-
- rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags);
-
- /* advance to the next dword */
- offset += sizeof(u32);
- data_buf += sizeof(u32);
- written_so_far += sizeof(u32);
- cmd_flags = 0;
- }
-
- /* disable access to nvram interface */
- bnx2x_disable_nvram_access(bp);
- bnx2x_release_nvram_lock(bp);
-
- return rc;
-}
-
-static int bnx2x_set_eeprom(struct net_device *dev,
- struct ethtool_eeprom *eeprom, u8 *eebuf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc;
-
- DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
- DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
- eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
- eeprom->len, eeprom->len);
-
- /* parameters already validated in ethtool_set_eeprom */
-
- /* If the magic number is PHY (0x00504859) upgrade the PHY FW */
- if (eeprom->magic == 0x00504859)
- if (bp->port.pmf) {
-
- bnx2x_acquire_phy_lock(bp);
- rc = bnx2x_flash_download(bp, BP_PORT(bp),
- bp->link_params.ext_phy_config,
- (bp->state != BNX2X_STATE_CLOSED),
- eebuf, eeprom->len);
- if ((bp->state == BNX2X_STATE_OPEN) ||
- (bp->state == BNX2X_STATE_DISABLED)) {
- rc |= bnx2x_link_reset(&bp->link_params,
- &bp->link_vars);
- rc |= bnx2x_phy_init(&bp->link_params,
- &bp->link_vars);
- }
- bnx2x_release_phy_lock(bp);
-
- } else /* Only the PMF can access the PHY */
- return -EINVAL;
- else
- rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
-
- return rc;
-}
-
-static int bnx2x_get_coalesce(struct net_device *dev,
- struct ethtool_coalesce *coal)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- memset(coal, 0, sizeof(struct ethtool_coalesce));
-
- coal->rx_coalesce_usecs = bp->rx_ticks;
- coal->tx_coalesce_usecs = bp->tx_ticks;
-
- return 0;
-}
-
-static int bnx2x_set_coalesce(struct net_device *dev,
- struct ethtool_coalesce *coal)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
- if (bp->rx_ticks > 3000)
- bp->rx_ticks = 3000;
-
- bp->tx_ticks = (u16) coal->tx_coalesce_usecs;
- if (bp->tx_ticks > 0x3000)
- bp->tx_ticks = 0x3000;
-
- if (netif_running(dev))
- bnx2x_update_coalesce(bp);
-
- return 0;
-}
-
-static void bnx2x_get_ringparam(struct net_device *dev,
- struct ethtool_ringparam *ering)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- ering->rx_max_pending = MAX_RX_AVAIL;
- ering->rx_mini_max_pending = 0;
- ering->rx_jumbo_max_pending = 0;
-
- ering->rx_pending = bp->rx_ring_size;
- ering->rx_mini_pending = 0;
- ering->rx_jumbo_pending = 0;
-
- ering->tx_max_pending = MAX_TX_AVAIL;
- ering->tx_pending = bp->tx_ring_size;
-}
-
-static int bnx2x_set_ringparam(struct net_device *dev,
- struct ethtool_ringparam *ering)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc = 0;
-
- if ((ering->rx_pending > MAX_RX_AVAIL) ||
- (ering->tx_pending > MAX_TX_AVAIL) ||
- (ering->tx_pending <= MAX_SKB_FRAGS + 4))
- return -EINVAL;
-
- bp->rx_ring_size = ering->rx_pending;
- bp->tx_ring_size = ering->tx_pending;
-
- if (netif_running(dev)) {
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- rc = bnx2x_nic_load(bp, LOAD_NORMAL);
- }
-
- return rc;
-}
-
-static void bnx2x_get_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *epause)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- epause->autoneg = (bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO) &&
- (bp->link_params.req_line_speed == SPEED_AUTO_NEG);
-
- epause->rx_pause = ((bp->link_vars.flow_ctrl & FLOW_CTRL_RX) ==
- FLOW_CTRL_RX);
- epause->tx_pause = ((bp->link_vars.flow_ctrl & FLOW_CTRL_TX) ==
- FLOW_CTRL_TX);
-
- DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
- DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
- epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
-}
-
-static int bnx2x_set_pauseparam(struct net_device *dev,
- struct ethtool_pauseparam *epause)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- if (IS_E1HMF(bp))
- return 0;
-
- DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
- DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n",
- epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
-
- bp->link_params.req_flow_ctrl = FLOW_CTRL_AUTO;
-
- if (epause->rx_pause)
- bp->link_params.req_flow_ctrl |= FLOW_CTRL_RX;
-
- if (epause->tx_pause)
- bp->link_params.req_flow_ctrl |= FLOW_CTRL_TX;
-
- if (bp->link_params.req_flow_ctrl == FLOW_CTRL_AUTO)
- bp->link_params.req_flow_ctrl = FLOW_CTRL_NONE;
-
- if (epause->autoneg) {
- if (!(bp->port.supported & SUPPORTED_Autoneg)) {
- DP(NETIF_MSG_LINK, "autoneg not supported\n");
- return -EINVAL;
- }
-
- if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
- bp->link_params.req_flow_ctrl = FLOW_CTRL_AUTO;
- }
-
- DP(NETIF_MSG_LINK,
- "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl);
-
- if (netif_running(dev)) {
- bnx2x_stats_handle(bp, STATS_EVENT_STOP);
- bnx2x_link_set(bp);
- }
-
- return 0;
-}
-
-static int bnx2x_set_flags(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int changed = 0;
- int rc = 0;
-
- /* TPA requires Rx CSUM offloading */
- if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
- if (!(dev->features & NETIF_F_LRO)) {
- dev->features |= NETIF_F_LRO;
- bp->flags |= TPA_ENABLE_FLAG;
- changed = 1;
- }
-
- } else if (dev->features & NETIF_F_LRO) {
- dev->features &= ~NETIF_F_LRO;
- bp->flags &= ~TPA_ENABLE_FLAG;
- changed = 1;
- }
-
- if (changed && netif_running(dev)) {
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- rc = bnx2x_nic_load(bp, LOAD_NORMAL);
- }
-
- return rc;
-}
-
-static u32 bnx2x_get_rx_csum(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- return bp->rx_csum;
-}
-
-static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc = 0;
-
- bp->rx_csum = data;
-
- /* Disable TPA, when Rx CSUM is disabled. Otherwise all
- TPA'ed packets will be discarded due to wrong TCP CSUM */
- if (!data) {
- u32 flags = ethtool_op_get_flags(dev);
-
- rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
- }
-
- return rc;
-}
-
-static int bnx2x_set_tso(struct net_device *dev, u32 data)
-{
- if (data) {
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features |= NETIF_F_TSO6;
- } else {
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features &= ~NETIF_F_TSO6;
- }
-
- return 0;
-}
-
-static const struct {
- char string[ETH_GSTRING_LEN];
-} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
- { "register_test (offline)" },
- { "memory_test (offline)" },
- { "loopback_test (offline)" },
- { "nvram_test (online)" },
- { "interrupt_test (online)" },
- { "link_test (online)" },
- { "idle check (online)" },
- { "MC errors (online)" }
-};
-
-static int bnx2x_self_test_count(struct net_device *dev)
-{
- return BNX2X_NUM_TESTS;
-}
-
-static int bnx2x_test_registers(struct bnx2x *bp)
-{
- int idx, i, rc = -ENODEV;
- u32 wr_val = 0;
- int port = BP_PORT(bp);
- static const struct {
- u32 offset0;
- u32 offset1;
- u32 mask;
- } reg_tbl[] = {
-/* 0 */ { BRB1_REG_PAUSE_LOW_THRESHOLD_0, 4, 0x000003ff },
- { DORQ_REG_DB_ADDR0, 4, 0xffffffff },
- { HC_REG_AGG_INT_0, 4, 0x000003ff },
- { PBF_REG_MAC_IF0_ENABLE, 4, 0x00000001 },
- { PBF_REG_P0_INIT_CRD, 4, 0x000007ff },
- { PRS_REG_CID_PORT_0, 4, 0x00ffffff },
- { PXP2_REG_PSWRQ_CDU0_L2P, 4, 0x000fffff },
- { PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR, 8, 0x0003ffff },
- { PXP2_REG_PSWRQ_TM0_L2P, 4, 0x000fffff },
- { PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR, 8, 0x0003ffff },
-/* 10 */ { PXP2_REG_PSWRQ_TSDM0_L2P, 4, 0x000fffff },
- { QM_REG_CONNNUM_0, 4, 0x000fffff },
- { TM_REG_LIN0_MAX_ACTIVE_CID, 4, 0x0003ffff },
- { SRC_REG_KEYRSS0_0, 40, 0xffffffff },
- { SRC_REG_KEYRSS0_7, 40, 0xffffffff },
- { XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 },
- { XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 },
- { XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff },
- { NIG_REG_EGRESS_MNG0_FIFO, 20, 0xffffffff },
- { NIG_REG_LLH0_T_BIT, 4, 0x00000001 },
-/* 20 */ { NIG_REG_EMAC0_IN_EN, 4, 0x00000001 },
- { NIG_REG_BMAC0_IN_EN, 4, 0x00000001 },
- { NIG_REG_XCM0_OUT_EN, 4, 0x00000001 },
- { NIG_REG_BRB0_OUT_EN, 4, 0x00000001 },
- { NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 },
- { NIG_REG_LLH0_ACPI_PAT_6_LEN, 68, 0x000000ff },
- { NIG_REG_LLH0_ACPI_PAT_0_CRC, 68, 0xffffffff },
- { NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff },
- { NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff },
- { NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 },
-/* 30 */ { NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff },
- { NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff },
- { NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff },
- { NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 },
- { NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 },
- { NIG_REG_STATUS_INTERRUPT_PORT0, 4, 0x07ffffff },
- { NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 },
- { NIG_REG_SERDES0_CTRL_PHY_ADDR, 16, 0x0000001f },
-
- { 0xffffffff, 0, 0x00000000 }
- };
-
- if (!netif_running(bp->dev))
- return rc;
-
- /* Repeat the test twice:
- First by writing 0x00000000, second by writing 0xffffffff */
- for (idx = 0; idx < 2; idx++) {
-
- switch (idx) {
- case 0:
- wr_val = 0;
- break;
- case 1:
- wr_val = 0xffffffff;
- break;
- }
-
- for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
- u32 offset, mask, save_val, val;
-
- offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
- mask = reg_tbl[i].mask;
-
- save_val = REG_RD(bp, offset);
-
- REG_WR(bp, offset, wr_val);
- val = REG_RD(bp, offset);
-
- /* Restore the original register's value */
- REG_WR(bp, offset, save_val);
-
- /* verify that value is as expected value */
- if ((val & mask) != (wr_val & mask))
- goto test_reg_exit;
- }
- }
-
- rc = 0;
-
-test_reg_exit:
- return rc;
-}
-
-static int bnx2x_test_memory(struct bnx2x *bp)
-{
- int i, j, rc = -ENODEV;
- u32 val;
- static const struct {
- u32 offset;
- int size;
- } mem_tbl[] = {
- { CCM_REG_XX_DESCR_TABLE, CCM_REG_XX_DESCR_TABLE_SIZE },
- { CFC_REG_ACTIVITY_COUNTER, CFC_REG_ACTIVITY_COUNTER_SIZE },
- { CFC_REG_LINK_LIST, CFC_REG_LINK_LIST_SIZE },
- { DMAE_REG_CMD_MEM, DMAE_REG_CMD_MEM_SIZE },
- { TCM_REG_XX_DESCR_TABLE, TCM_REG_XX_DESCR_TABLE_SIZE },
- { UCM_REG_XX_DESCR_TABLE, UCM_REG_XX_DESCR_TABLE_SIZE },
- { XCM_REG_XX_DESCR_TABLE, XCM_REG_XX_DESCR_TABLE_SIZE },
-
- { 0xffffffff, 0 }
- };
- static const struct {
- char *name;
- u32 offset;
- u32 e1_mask;
- u32 e1h_mask;
- } prty_tbl[] = {
- { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 },
- { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 },
- { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 },
- { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 },
- { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 },
- { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 },
-
- { NULL, 0xffffffff, 0, 0 }
- };
-
- if (!netif_running(bp->dev))
- return rc;
-
- /* Go through all the memories */
- for (i = 0; mem_tbl[i].offset != 0xffffffff; i++)
- for (j = 0; j < mem_tbl[i].size; j++)
- REG_RD(bp, mem_tbl[i].offset + j*4);
-
- /* Check the parity status */
- for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
- val = REG_RD(bp, prty_tbl[i].offset);
- if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
- (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) {
- DP(NETIF_MSG_HW,
- "%s is 0x%x\n", prty_tbl[i].name, val);
- goto test_mem_exit;
- }
- }
-
- rc = 0;
-
-test_mem_exit:
- return rc;
-}
-
-static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up)
-{
- int cnt = 1000;
-
- if (link_up)
- while (bnx2x_link_test(bp) && cnt--)
- msleep(10);
-}
-
-static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
-{
- unsigned int pkt_size, num_pkts, i;
- struct sk_buff *skb;
- unsigned char *packet;
- struct bnx2x_fastpath *fp = &bp->fp[0];
- u16 tx_start_idx, tx_idx;
- u16 rx_start_idx, rx_idx;
- u16 pkt_prod;
- struct sw_tx_bd *tx_buf;
- struct eth_tx_bd *tx_bd;
- dma_addr_t mapping;
- union eth_rx_cqe *cqe;
- u8 cqe_fp_flags;
- struct sw_rx_bd *rx_buf;
- u16 len;
- int rc = -ENODEV;
-
- if (loopback_mode == BNX2X_MAC_LOOPBACK) {
- bp->link_params.loopback_mode = LOOPBACK_BMAC;
- bnx2x_acquire_phy_lock(bp);
- bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
-
- } else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
- bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
- bnx2x_acquire_phy_lock(bp);
- bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- bnx2x_release_phy_lock(bp);
- /* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
-
- } else
- return -EINVAL;
-
- pkt_size = 1514;
- skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
- if (!skb) {
- rc = -ENOMEM;
- goto test_loopback_exit;
- }
- packet = skb_put(skb, pkt_size);
- memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
- memset(packet + ETH_ALEN, 0, (ETH_HLEN - ETH_ALEN));
- for (i = ETH_HLEN; i < pkt_size; i++)
- packet[i] = (unsigned char) (i & 0xff);
-
- num_pkts = 0;
- tx_start_idx = le16_to_cpu(*fp->tx_cons_sb);
- rx_start_idx = le16_to_cpu(*fp->rx_cons_sb);
-
- pkt_prod = fp->tx_pkt_prod++;
- tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
- tx_buf->first_bd = fp->tx_bd_prod;
- tx_buf->skb = skb;
-
- tx_bd = &fp->tx_desc_ring[TX_BD(fp->tx_bd_prod)];
- mapping = pci_map_single(bp->pdev, skb->data,
- skb_headlen(skb), PCI_DMA_TODEVICE);
- tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
- tx_bd->nbd = cpu_to_le16(1);
- tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
- tx_bd->vlan = cpu_to_le16(pkt_prod);
- tx_bd->bd_flags.as_bitfield = (ETH_TX_BD_FLAGS_START_BD |
- ETH_TX_BD_FLAGS_END_BD);
- tx_bd->general_data = ((UNICAST_ADDRESS <<
- ETH_TX_BD_ETH_ADDR_TYPE_SHIFT) | 1);
-
- fp->hw_tx_prods->bds_prod =
- cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1);
- mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod =
- cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
- DOORBELL(bp, FP_IDX(fp), 0);
-
- mmiowb();
-
- num_pkts++;
- fp->tx_bd_prod++;
- bp->dev->trans_start = jiffies;
-
- udelay(100);
-
- tx_idx = le16_to_cpu(*fp->tx_cons_sb);
- if (tx_idx != tx_start_idx + num_pkts)
- goto test_loopback_exit;
-
- rx_idx = le16_to_cpu(*fp->rx_cons_sb);
- if (rx_idx != rx_start_idx + num_pkts)
- goto test_loopback_exit;
-
- cqe = &fp->rx_comp_ring[RCQ_BD(fp->rx_comp_cons)];
- cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
- if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
- goto test_loopback_rx_exit;
-
- len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
- if (len != pkt_size)
- goto test_loopback_rx_exit;
-
- rx_buf = &fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)];
- skb = rx_buf->skb;
- skb_reserve(skb, cqe->fast_path_cqe.placement_offset);
- for (i = ETH_HLEN; i < pkt_size; i++)
- if (*(skb->data + i) != (unsigned char) (i & 0xff))
- goto test_loopback_rx_exit;
-
- rc = 0;
-
-test_loopback_rx_exit:
- bp->dev->last_rx = jiffies;
-
- fp->rx_bd_cons = NEXT_RX_IDX(fp->rx_bd_cons);
- fp->rx_bd_prod = NEXT_RX_IDX(fp->rx_bd_prod);
- fp->rx_comp_cons = NEXT_RCQ_IDX(fp->rx_comp_cons);
- fp->rx_comp_prod = NEXT_RCQ_IDX(fp->rx_comp_prod);
-
- /* Update producers */
- bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
- fp->rx_sge_prod);
- mmiowb(); /* keep prod updates ordered */
-
-test_loopback_exit:
- bp->link_params.loopback_mode = LOOPBACK_NONE;
-
- return rc;
-}
-
-static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
-{
- int rc = 0;
-
- if (!netif_running(bp->dev))
- return BNX2X_LOOPBACK_FAILED;
-
- bnx2x_netif_stop(bp);
-
- if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
- DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
- rc |= BNX2X_MAC_LOOPBACK_FAILED;
- }
-
- if (bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up)) {
- DP(NETIF_MSG_PROBE, "PHY loopback failed\n");
- rc |= BNX2X_PHY_LOOPBACK_FAILED;
- }
-
- bnx2x_netif_start(bp);
-
- return rc;
-}
-
-#define CRC32_RESIDUAL 0xdebb20e3
-
-static int bnx2x_test_nvram(struct bnx2x *bp)
-{
- static const struct {
- int offset;
- int size;
- } nvram_tbl[] = {
- { 0, 0x14 }, /* bootstrap */
- { 0x14, 0xec }, /* dir */
- { 0x100, 0x350 }, /* manuf_info */
- { 0x450, 0xf0 }, /* feature_info */
- { 0x640, 0x64 }, /* upgrade_key_info */
- { 0x6a4, 0x64 },
- { 0x708, 0x70 }, /* manuf_key_info */
- { 0x778, 0x70 },
- { 0, 0 }
- };
- u32 buf[0x350 / 4];
- u8 *data = (u8 *)buf;
- int i, rc;
- u32 magic, csum;
-
- rc = bnx2x_nvram_read(bp, 0, data, 4);
- if (rc) {
- DP(NETIF_MSG_PROBE, "magic value read (rc -%d)\n", -rc);
- goto test_nvram_exit;
- }
-
- magic = be32_to_cpu(buf[0]);
- if (magic != 0x669955aa) {
- DP(NETIF_MSG_PROBE, "magic value (0x%08x)\n", magic);
- rc = -ENODEV;
- goto test_nvram_exit;
- }
-
- for (i = 0; nvram_tbl[i].size; i++) {
-
- rc = bnx2x_nvram_read(bp, nvram_tbl[i].offset, data,
- nvram_tbl[i].size);
- if (rc) {
- DP(NETIF_MSG_PROBE,
- "nvram_tbl[%d] read data (rc -%d)\n", i, -rc);
- goto test_nvram_exit;
- }
-
- csum = ether_crc_le(nvram_tbl[i].size, data);
- if (csum != CRC32_RESIDUAL) {
- DP(NETIF_MSG_PROBE,
- "nvram_tbl[%d] csum value (0x%08x)\n", i, csum);
- rc = -ENODEV;
- goto test_nvram_exit;
- }
- }
-
-test_nvram_exit:
- return rc;
-}
-
-static int bnx2x_test_intr(struct bnx2x *bp)
-{
- struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
- int i, rc;
-
- if (!netif_running(bp->dev))
- return -ENODEV;
-
- config->hdr.length_6b = 0;
- config->hdr.offset = 0;
- config->hdr.client_id = BP_CL_ID(bp);
- config->hdr.reserved1 = 0;
-
- rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mac_config)),
- U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
- if (rc == 0) {
- bp->set_mac_pending++;
- for (i = 0; i < 10; i++) {
- if (!bp->set_mac_pending)
- break;
- msleep_interruptible(10);
- }
- if (i == 10)
- rc = -ENODEV;
- }
-
- return rc;
-}
-
-static void bnx2x_self_test(struct net_device *dev,
- struct ethtool_test *etest, u64 *buf)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS);
-
- if (!netif_running(dev))
- return;
-
- /* offline tests are not supported in MF mode */
- if (IS_E1HMF(bp))
- etest->flags &= ~ETH_TEST_FL_OFFLINE;
-
- if (etest->flags & ETH_TEST_FL_OFFLINE) {
- u8 link_up;
-
- link_up = bp->link_vars.link_up;
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- bnx2x_nic_load(bp, LOAD_DIAG);
- /* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
-
- if (bnx2x_test_registers(bp) != 0) {
- buf[0] = 1;
- etest->flags |= ETH_TEST_FL_FAILED;
- }
- if (bnx2x_test_memory(bp) != 0) {
- buf[1] = 1;
- etest->flags |= ETH_TEST_FL_FAILED;
- }
- buf[2] = bnx2x_test_loopback(bp, link_up);
- if (buf[2] != 0)
- etest->flags |= ETH_TEST_FL_FAILED;
-
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- bnx2x_nic_load(bp, LOAD_NORMAL);
- /* wait until link state is restored */
- bnx2x_wait_for_link(bp, link_up);
- }
- if (bnx2x_test_nvram(bp) != 0) {
- buf[3] = 1;
- etest->flags |= ETH_TEST_FL_FAILED;
- }
- if (bnx2x_test_intr(bp) != 0) {
- buf[4] = 1;
- etest->flags |= ETH_TEST_FL_FAILED;
- }
- if (bp->port.pmf)
- if (bnx2x_link_test(bp) != 0) {
- buf[5] = 1;
- etest->flags |= ETH_TEST_FL_FAILED;
- }
- buf[7] = bnx2x_mc_assert(bp);
- if (buf[7] != 0)
- etest->flags |= ETH_TEST_FL_FAILED;
-
-#ifdef BNX2X_EXTRA_DEBUG
- bnx2x_panic_dump(bp);
-#endif
-}
-
-static const struct {
- long offset;
- int size;
- u32 flags;
-#define STATS_FLAGS_PORT 1
-#define STATS_FLAGS_FUNC 2
- u8 string[ETH_GSTRING_LEN];
-} bnx2x_stats_arr[BNX2X_NUM_STATS] = {
-/* 1 */ { STATS_OFFSET32(valid_bytes_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_bytes" },
- { STATS_OFFSET32(error_bytes_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_error_bytes" },
- { STATS_OFFSET32(total_bytes_transmitted_hi),
- 8, STATS_FLAGS_FUNC, "tx_bytes" },
- { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
- 8, STATS_FLAGS_PORT, "tx_error_bytes" },
- { STATS_OFFSET32(total_unicast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_ucast_packets" },
- { STATS_OFFSET32(total_multicast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_mcast_packets" },
- { STATS_OFFSET32(total_broadcast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_bcast_packets" },
- { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
- 8, STATS_FLAGS_FUNC, "tx_packets" },
- { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
- 8, STATS_FLAGS_PORT, "tx_mac_errors" },
-/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
- 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
- { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
- 8, STATS_FLAGS_PORT, "rx_crc_errors" },
- { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
- 8, STATS_FLAGS_PORT, "rx_align_errors" },
- { STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
- 8, STATS_FLAGS_PORT, "tx_single_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
- 8, STATS_FLAGS_PORT, "tx_multi_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
- 8, STATS_FLAGS_PORT, "tx_deferred" },
- { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
- 8, STATS_FLAGS_PORT, "tx_excess_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
- 8, STATS_FLAGS_PORT, "tx_late_collisions" },
- { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
- 8, STATS_FLAGS_PORT, "tx_total_collisions" },
- { STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
- 8, STATS_FLAGS_PORT, "rx_fragments" },
-/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
- 8, STATS_FLAGS_PORT, "rx_jabbers" },
- { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
- 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
- { STATS_OFFSET32(jabber_packets_received),
- 4, STATS_FLAGS_FUNC, "rx_oversize_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
- 8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
- 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
- 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
- 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" },
- { STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
- 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
- { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
- 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
- { STATS_OFFSET32(etherstatspktsover1522octets_hi),
- 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
-/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_xon_frames" },
- { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_xoff_frames" },
- { STATS_OFFSET32(tx_stat_outxonsent_hi),
- 8, STATS_FLAGS_PORT, "tx_xon_frames" },
- { STATS_OFFSET32(tx_stat_outxoffsent_hi),
- 8, STATS_FLAGS_PORT, "tx_xoff_frames" },
- { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
- { STATS_OFFSET32(mac_filter_discard),
- 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
- { STATS_OFFSET32(no_buff_discard),
- 4, STATS_FLAGS_FUNC, "rx_discards" },
- { STATS_OFFSET32(xxoverflow_discard),
- 4, STATS_FLAGS_PORT, "rx_fw_discards" },
- { STATS_OFFSET32(brb_drop_hi),
- 8, STATS_FLAGS_PORT, "brb_discard" },
- { STATS_OFFSET32(brb_truncate_hi),
- 8, STATS_FLAGS_PORT, "brb_truncate" },
-/* 40 */{ STATS_OFFSET32(rx_err_discard_pkt),
- 4, STATS_FLAGS_FUNC, "rx_phy_ip_err_discards"},
- { STATS_OFFSET32(rx_skb_alloc_failed),
- 4, STATS_FLAGS_FUNC, "rx_skb_alloc_discard" },
-/* 42 */{ STATS_OFFSET32(hw_csum_err),
- 4, STATS_FLAGS_FUNC, "rx_csum_offload_errors" }
-};
-
-#define IS_NOT_E1HMF_STAT(bp, i) \
- (IS_E1HMF(bp) && (bnx2x_stats_arr[i].flags & STATS_FLAGS_PORT))
-
-static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int i, j;
-
- switch (stringset) {
- case ETH_SS_STATS:
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
- strcpy(buf + j*ETH_GSTRING_LEN,
- bnx2x_stats_arr[i].string);
- j++;
- }
- break;
-
- case ETH_SS_TEST:
- memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr));
- break;
- }
-}
-
-static int bnx2x_get_stats_count(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int i, num_stats = 0;
-
- for (i = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
- num_stats++;
- }
- return num_stats;
-}
-
-static void bnx2x_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *buf)
-{
- struct bnx2x *bp = netdev_priv(dev);
- u32 *hw_stats = (u32 *)&bp->eth_stats;
- int i, j;
-
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
-
- if (bnx2x_stats_arr[i].size == 0) {
- /* skip this counter */
- buf[j] = 0;
- j++;
- continue;
- }
- if (bnx2x_stats_arr[i].size == 4) {
- /* 4-byte counter */
- buf[j] = (u64) *(hw_stats + bnx2x_stats_arr[i].offset);
- j++;
- continue;
- }
- /* 8-byte counter */
- buf[j] = HILO_U64(*(hw_stats + bnx2x_stats_arr[i].offset),
- *(hw_stats + bnx2x_stats_arr[i].offset + 1));
- j++;
- }
-}
-
-static int bnx2x_phys_id(struct net_device *dev, u32 data)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int port = BP_PORT(bp);
- int i;
-
- if (!netif_running(dev))
- return 0;
-
- if (!bp->port.pmf)
- return 0;
-
- if (data == 0)
- data = 2;
-
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0)
- bnx2x_set_led(bp, port, LED_MODE_OPER, SPEED_1000,
- bp->link_params.hw_led_mode,
- bp->link_params.chip_id);
- else
- bnx2x_set_led(bp, port, LED_MODE_OFF, 0,
- bp->link_params.hw_led_mode,
- bp->link_params.chip_id);
-
- msleep_interruptible(500);
- if (signal_pending(current))
- break;
- }
-
- if (bp->link_vars.link_up)
- bnx2x_set_led(bp, port, LED_MODE_OPER,
- bp->link_vars.line_speed,
- bp->link_params.hw_led_mode,
- bp->link_params.chip_id);
-
- return 0;
-}
-
-static struct ethtool_ops bnx2x_ethtool_ops = {
- .get_settings = bnx2x_get_settings,
- .set_settings = bnx2x_set_settings,
- .get_drvinfo = bnx2x_get_drvinfo,
- .get_wol = bnx2x_get_wol,
- .set_wol = bnx2x_set_wol,
- .get_msglevel = bnx2x_get_msglevel,
- .set_msglevel = bnx2x_set_msglevel,
- .nway_reset = bnx2x_nway_reset,
- .get_link = ethtool_op_get_link,
- .get_eeprom_len = bnx2x_get_eeprom_len,
- .get_eeprom = bnx2x_get_eeprom,
- .set_eeprom = bnx2x_set_eeprom,
- .get_coalesce = bnx2x_get_coalesce,
- .set_coalesce = bnx2x_set_coalesce,
- .get_ringparam = bnx2x_get_ringparam,
- .set_ringparam = bnx2x_set_ringparam,
- .get_pauseparam = bnx2x_get_pauseparam,
- .set_pauseparam = bnx2x_set_pauseparam,
- .get_rx_csum = bnx2x_get_rx_csum,
- .set_rx_csum = bnx2x_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .set_flags = bnx2x_set_flags,
- .get_flags = ethtool_op_get_flags,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = bnx2x_set_tso,
- .self_test_count = bnx2x_self_test_count,
- .self_test = bnx2x_self_test,
- .get_strings = bnx2x_get_strings,
- .phys_id = bnx2x_phys_id,
- .get_stats_count = bnx2x_get_stats_count,
- .get_ethtool_stats = bnx2x_get_ethtool_stats,
-};
-
-/* end of ethtool_ops */
-
-/****************************************************************************
-* General service functions
-****************************************************************************/
-
-static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
-{
- u16 pmcsr;
-
- pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
-
- switch (state) {
- case PCI_D0:
- pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
- ((pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
- PCI_PM_CTRL_PME_STATUS));
-
- if (pmcsr & PCI_PM_CTRL_STATE_MASK)
- /* delay required during transition out of D3hot */
- msleep(20);
- break;
-
- case PCI_D3hot:
- pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
- pmcsr |= 3;
-
- if (bp->wol)
- pmcsr |= PCI_PM_CTRL_PME_ENABLE;
-
- pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
- pmcsr);
-
- /* No more memory access after this point until
- * device is brought back to D0.
- */
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * net_device service functions
- */
-
-static int bnx2x_poll(struct napi_struct *napi, int budget)
-{
- struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
- napi);
- struct bnx2x *bp = fp->bp;
- int work_done = 0;
- u16 rx_cons_sb;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- goto poll_panic;
-#endif
-
- prefetch(fp->tx_buf_ring[TX_BD(fp->tx_pkt_cons)].skb);
- prefetch(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb);
- prefetch((char *)(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb) + 256);
-
- bnx2x_update_fpsb_idx(fp);
-
- if (BNX2X_HAS_TX_WORK(fp))
- bnx2x_tx_int(fp, budget);
-
- rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
- if (BNX2X_HAS_RX_WORK(fp))
- work_done = bnx2x_rx_int(fp, budget);
-
- rmb(); /* BNX2X_HAS_WORK() reads the status block */
- rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
- if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
- rx_cons_sb++;
-
- /* must not complete if we consumed full budget */
- if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
-
-#ifdef BNX2X_STOP_ON_ERROR
-poll_panic:
-#endif
- netif_rx_complete(bp->dev, napi);
-
- bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID,
- le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, FP_SB_ID(fp), CSTORM_ID,
- le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
- }
- return work_done;
-}
-
-
-/* we split the first BD into headers and data BDs
- * to ease the pain of our fellow microcode engineers
- * we use one mapping for both BDs
- * So far this has only been observed to happen
- * in Other Operating Systems(TM)
- */
-static noinline u16 bnx2x_tx_split(struct bnx2x *bp,
- struct bnx2x_fastpath *fp,
- struct eth_tx_bd **tx_bd, u16 hlen,
- u16 bd_prod, int nbd)
-{
- struct eth_tx_bd *h_tx_bd = *tx_bd;
- struct eth_tx_bd *d_tx_bd;
- dma_addr_t mapping;
- int old_len = le16_to_cpu(h_tx_bd->nbytes);
-
- /* first fix first BD */
- h_tx_bd->nbd = cpu_to_le16(nbd);
- h_tx_bd->nbytes = cpu_to_le16(hlen);
-
- DP(NETIF_MSG_TX_QUEUED, "TSO split header size is %d "
- "(%x:%x) nbd %d\n", h_tx_bd->nbytes, h_tx_bd->addr_hi,
- h_tx_bd->addr_lo, h_tx_bd->nbd);
-
- /* now get a new data BD
- * (after the pbd) and fill it */
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- d_tx_bd = &fp->tx_desc_ring[bd_prod];
-
- mapping = HILO_U64(le32_to_cpu(h_tx_bd->addr_hi),
- le32_to_cpu(h_tx_bd->addr_lo)) + hlen;
-
- d_tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- d_tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
- d_tx_bd->nbytes = cpu_to_le16(old_len - hlen);
- d_tx_bd->vlan = 0;
- /* this marks the BD as one that has no individual mapping
- * the FW ignores this flag in a BD not marked start
- */
- d_tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO;
- DP(NETIF_MSG_TX_QUEUED,
- "TSO split data size is %d (%x:%x)\n",
- d_tx_bd->nbytes, d_tx_bd->addr_hi, d_tx_bd->addr_lo);
-
- /* update tx_bd for marking the last BD flag */
- *tx_bd = d_tx_bd;
-
- return bd_prod;
-}
-
-static inline u16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix)
-{
- if (fix > 0)
- csum = (u16) ~csum_fold(csum_sub(csum,
- csum_partial(t_header - fix, fix, 0)));
-
- else if (fix < 0)
- csum = (u16) ~csum_fold(csum_add(csum,
- csum_partial(t_header, -fix, 0)));
-
- return swab16(csum);
-}
-
-static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
-{
- u32 rc;
-
- if (skb->ip_summed != CHECKSUM_PARTIAL)
- rc = XMIT_PLAIN;
-
- else {
- if (skb->protocol == ntohs(ETH_P_IPV6)) {
- rc = XMIT_CSUM_V6;
- if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
- rc |= XMIT_CSUM_TCP;
-
- } else {
- rc = XMIT_CSUM_V4;
- if (ip_hdr(skb)->protocol == IPPROTO_TCP)
- rc |= XMIT_CSUM_TCP;
- }
- }
-
- if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
- rc |= XMIT_GSO_V4;
-
- else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
- rc |= XMIT_GSO_V6;
-
- return rc;
-}
-
-/* check if packet requires linearization (packet is too fragmented) */
-static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
- u32 xmit_type)
-{
- int to_copy = 0;
- int hlen = 0;
- int first_bd_sz = 0;
-
- /* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
- if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) {
-
- if (xmit_type & XMIT_GSO) {
- unsigned short lso_mss = skb_shinfo(skb)->gso_size;
- /* Check if LSO packet needs to be copied:
- 3 = 1 (for headers BD) + 2 (for PBD and last BD) */
- int wnd_size = MAX_FETCH_BD - 3;
- /* Number of windows to check */
- int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
- int wnd_idx = 0;
- int frag_idx = 0;
- u32 wnd_sum = 0;
-
- /* Headers length */
- hlen = (int)(skb_transport_header(skb) - skb->data) +
- tcp_hdrlen(skb);
-
- /* Amount of data (w/o headers) on linear part of SKB*/
- first_bd_sz = skb_headlen(skb) - hlen;
-
- wnd_sum = first_bd_sz;
-
- /* Calculate the first sum - it's special */
- for (frag_idx = 0; frag_idx < wnd_size - 1; frag_idx++)
- wnd_sum +=
- skb_shinfo(skb)->frags[frag_idx].size;
-
- /* If there was data on linear skb data - check it */
- if (first_bd_sz > 0) {
- if (unlikely(wnd_sum < lso_mss)) {
- to_copy = 1;
- goto exit_lbl;
- }
-
- wnd_sum -= first_bd_sz;
- }
-
- /* Others are easier: run through the frag list and
- check all windows */
- for (wnd_idx = 0; wnd_idx <= num_wnds; wnd_idx++) {
- wnd_sum +=
- skb_shinfo(skb)->frags[wnd_idx + wnd_size - 1].size;
-
- if (unlikely(wnd_sum < lso_mss)) {
- to_copy = 1;
- break;
- }
- wnd_sum -=
- skb_shinfo(skb)->frags[wnd_idx].size;
- }
-
- } else {
- /* in non-LSO too fragmented packet should always
- be linearized */
- to_copy = 1;
- }
- }
-
-exit_lbl:
- if (unlikely(to_copy))
- DP(NETIF_MSG_TX_QUEUED,
- "Linearization IS REQUIRED for %s packet. "
- "num_frags %d hlen %d first_bd_sz %d\n",
- (xmit_type & XMIT_GSO) ? "LSO" : "non-LSO",
- skb_shinfo(skb)->nr_frags, hlen, first_bd_sz);
-
- return to_copy;
-}
-
-/* called with netif_tx_lock
- * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
- * netif_wake_queue()
- */
-static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
- struct bnx2x_fastpath *fp;
- struct sw_tx_bd *tx_buf;
- struct eth_tx_bd *tx_bd;
- struct eth_tx_parse_bd *pbd = NULL;
- u16 pkt_prod, bd_prod;
- int nbd, fp_index;
- dma_addr_t mapping;
- u32 xmit_type = bnx2x_xmit_type(bp, skb);
- int vlan_off = (bp->e1hov ? 4 : 0);
- int i;
- u8 hlen = 0;
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (unlikely(bp->panic))
- return NETDEV_TX_BUSY;
-#endif
-
- fp_index = (smp_processor_id() % bp->num_queues);
- fp = &bp->fp[fp_index];
-
- if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) {
- bp->eth_stats.driver_xoff++,
- netif_stop_queue(dev);
- BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
- return NETDEV_TX_BUSY;
- }
-
- DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)"
- " gso type %x xmit_type %x\n",
- skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
- ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
-
- /* First, check if we need to linearize the skb
- (due to FW restrictions) */
- if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
- /* Statistics of linearization */
- bp->lin_cnt++;
- if (skb_linearize(skb) != 0) {
- DP(NETIF_MSG_TX_QUEUED, "SKB linearization failed - "
- "silently dropping this SKB\n");
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
- }
-
- /*
- Please read carefully. First we use one BD which we mark as start,
- then for TSO or xsum we have a parsing info BD,
- and only then we have the rest of the TSO BDs.
- (don't forget to mark the last one as last,
- and to unmap only AFTER you write to the BD ...)
- And above all, all pdb sizes are in words - NOT DWORDS!
- */
-
- pkt_prod = fp->tx_pkt_prod++;
- bd_prod = TX_BD(fp->tx_bd_prod);
-
- /* get a tx_buf and first BD */
- tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
- tx_bd = &fp->tx_desc_ring[bd_prod];
-
- tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
- tx_bd->general_data = (UNICAST_ADDRESS <<
- ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
- /* header nbd */
- tx_bd->general_data |= (1 << ETH_TX_BD_HDR_NBDS_SHIFT);
-
- /* remember the first BD of the packet */
- tx_buf->first_bd = fp->tx_bd_prod;
- tx_buf->skb = skb;
-
- DP(NETIF_MSG_TX_QUEUED,
- "sending pkt %u @%p next_idx %u bd %u @%p\n",
- pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd);
-
- if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) {
- tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
- vlan_off += 4;
- } else
- tx_bd->vlan = cpu_to_le16(pkt_prod);
-
- if (xmit_type) {
- /* turn on parsing and get a BD */
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- pbd = (void *)&fp->tx_desc_ring[bd_prod];
-
- memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
- }
-
- if (xmit_type & XMIT_CSUM) {
- hlen = (skb_network_header(skb) - skb->data + vlan_off) / 2;
-
- /* for now NS flag is not used in Linux */
- pbd->global_data = (hlen |
- ((skb->protocol == ntohs(ETH_P_8021Q)) <<
- ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
-
- pbd->ip_hlen = (skb_transport_header(skb) -
- skb_network_header(skb)) / 2;
-
- hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2;
-
- pbd->total_hlen = cpu_to_le16(hlen);
- hlen = hlen*2 - vlan_off;
-
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_TCP_CSUM;
-
- if (xmit_type & XMIT_CSUM_V4)
- tx_bd->bd_flags.as_bitfield |=
- ETH_TX_BD_FLAGS_IP_CSUM;
- else
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IPV6;
-
- if (xmit_type & XMIT_CSUM_TCP) {
- pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check);
-
- } else {
- s8 fix = SKB_CS_OFF(skb); /* signed! */
-
- pbd->global_data |= ETH_TX_PARSE_BD_CS_ANY_FLG;
- pbd->cs_offset = fix / 2;
-
- DP(NETIF_MSG_TX_QUEUED,
- "hlen %d offset %d fix %d csum before fix %x\n",
- le16_to_cpu(pbd->total_hlen), pbd->cs_offset, fix,
- SKB_CS(skb));
-
- /* HW bug: fixup the CSUM */
- pbd->tcp_pseudo_csum =
- bnx2x_csum_fix(skb_transport_header(skb),
- SKB_CS(skb), fix);
-
- DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n",
- pbd->tcp_pseudo_csum);
- }
- }
-
- mapping = pci_map_single(bp->pdev, skb->data,
- skb_headlen(skb), PCI_DMA_TODEVICE);
-
- tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
- nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL) ? 1 : 2);
- tx_bd->nbd = cpu_to_le16(nbd);
- tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
-
- DP(NETIF_MSG_TX_QUEUED, "first bd @%p addr (%x:%x) nbd %d"
- " nbytes %d flags %x vlan %x\n",
- tx_bd, tx_bd->addr_hi, tx_bd->addr_lo, le16_to_cpu(tx_bd->nbd),
- le16_to_cpu(tx_bd->nbytes), tx_bd->bd_flags.as_bitfield,
- le16_to_cpu(tx_bd->vlan));
-
- if (xmit_type & XMIT_GSO) {
-
- DP(NETIF_MSG_TX_QUEUED,
- "TSO packet len %d hlen %d total len %d tso size %d\n",
- skb->len, hlen, skb_headlen(skb),
- skb_shinfo(skb)->gso_size);
-
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO;
-
- if (unlikely(skb_headlen(skb) > hlen))
- bd_prod = bnx2x_tx_split(bp, fp, &tx_bd, hlen,
- bd_prod, ++nbd);
-
- pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
- pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq);
- pbd->tcp_flags = pbd_tcp_flags(skb);
-
- if (xmit_type & XMIT_GSO_V4) {
- pbd->ip_id = swab16(ip_hdr(skb)->id);
- pbd->tcp_pseudo_csum =
- swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
- ip_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0));
-
- } else
- pbd->tcp_pseudo_csum =
- swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0));
-
- pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN;
- }
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
- tx_bd = &fp->tx_desc_ring[bd_prod];
-
- mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
- frag->size, PCI_DMA_TODEVICE);
-
- tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
- tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
- tx_bd->nbytes = cpu_to_le16(frag->size);
- tx_bd->vlan = cpu_to_le16(pkt_prod);
- tx_bd->bd_flags.as_bitfield = 0;
-
- DP(NETIF_MSG_TX_QUEUED,
- "frag %d bd @%p addr (%x:%x) nbytes %d flags %x\n",
- i, tx_bd, tx_bd->addr_hi, tx_bd->addr_lo,
- le16_to_cpu(tx_bd->nbytes), tx_bd->bd_flags.as_bitfield);
- }
-
- /* now at last mark the BD as the last BD */
- tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_END_BD;
-
- DP(NETIF_MSG_TX_QUEUED, "last bd @%p flags %x\n",
- tx_bd, tx_bd->bd_flags.as_bitfield);
-
- bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
-
- /* now send a tx doorbell, counting the next BD
- * if the packet contains or ends with it
- */
- if (TX_BD_POFF(bd_prod) < nbd)
- nbd++;
-
- if (pbd)
- DP(NETIF_MSG_TX_QUEUED,
- "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u"
- " tcp_flags %x xsum %x seq %u hlen %u\n",
- pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id,
- pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum,
- pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen));
-
- DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod);
-
- fp->hw_tx_prods->bds_prod =
- cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
- mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod =
- cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
- DOORBELL(bp, FP_IDX(fp), 0);
-
- mmiowb();
-
- fp->tx_bd_prod += nbd;
- dev->trans_start = jiffies;
-
- if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
- netif_stop_queue(dev);
- bp->eth_stats.driver_xoff++;
- if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
- netif_wake_queue(dev);
- }
- fp->tx_pkt++;
-
- return NETDEV_TX_OK;
-}
-
-/* called with rtnl_lock */
-static int bnx2x_open(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bnx2x_set_power_state(bp, PCI_D0);
-
- return bnx2x_nic_load(bp, LOAD_OPEN);
-}
-
-/* called with rtnl_lock */
-static int bnx2x_close(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- /* Unload the driver, release IRQs */
- bnx2x_nic_unload(bp, UNLOAD_CLOSE);
- if (atomic_read(&bp->pdev->enable_cnt) == 1)
- if (!CHIP_REV_IS_SLOW(bp))
- bnx2x_set_power_state(bp, PCI_D3hot);
-
- return 0;
-}
-
-/* called with netif_tx_lock from set_multicast */
-static void bnx2x_set_rx_mode(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
- u32 rx_mode = BNX2X_RX_MODE_NORMAL;
- int port = BP_PORT(bp);
-
- if (bp->state != BNX2X_STATE_OPEN) {
- DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
- return;
- }
-
- DP(NETIF_MSG_IFUP, "dev->flags = %x\n", dev->flags);
-
- if (dev->flags & IFF_PROMISC)
- rx_mode = BNX2X_RX_MODE_PROMISC;
-
- else if ((dev->flags & IFF_ALLMULTI) ||
- ((dev->mc_count > BNX2X_MAX_MULTICAST) && CHIP_IS_E1(bp)))
- rx_mode = BNX2X_RX_MODE_ALLMULTI;
-
- else { /* some multicasts */
- if (CHIP_IS_E1(bp)) {
- int i, old, offset;
- struct dev_mc_list *mclist;
- struct mac_configuration_cmd *config =
- bnx2x_sp(bp, mcast_config);
-
- for (i = 0, mclist = dev->mc_list;
- mclist && (i < dev->mc_count);
- i++, mclist = mclist->next) {
-
- config->config_table[i].
- cam_entry.msb_mac_addr =
- swab16(*(u16 *)&mclist->dmi_addr[0]);
- config->config_table[i].
- cam_entry.middle_mac_addr =
- swab16(*(u16 *)&mclist->dmi_addr[2]);
- config->config_table[i].
- cam_entry.lsb_mac_addr =
- swab16(*(u16 *)&mclist->dmi_addr[4]);
- config->config_table[i].cam_entry.flags =
- cpu_to_le16(port);
- config->config_table[i].
- target_table_entry.flags = 0;
- config->config_table[i].
- target_table_entry.client_id = 0;
- config->config_table[i].
- target_table_entry.vlan_id = 0;
-
- DP(NETIF_MSG_IFUP,
- "setting MCAST[%d] (%04x:%04x:%04x)\n", i,
- config->config_table[i].
- cam_entry.msb_mac_addr,
- config->config_table[i].
- cam_entry.middle_mac_addr,
- config->config_table[i].
- cam_entry.lsb_mac_addr);
- }
- old = config->hdr.length_6b;
- if (old > i) {
- for (; i < old; i++) {
- if (CAM_IS_INVALID(config->
- config_table[i])) {
- i--; /* already invalidated */
- break;
- }
- /* invalidate */
- CAM_INVALIDATE(config->
- config_table[i]);
- }
- }
-
- if (CHIP_REV_IS_SLOW(bp))
- offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
- else
- offset = BNX2X_MAX_MULTICAST*(1 + port);
-
- config->hdr.length_6b = i;
- config->hdr.offset = offset;
- config->hdr.client_id = BP_CL_ID(bp);
- config->hdr.reserved1 = 0;
-
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
- U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
- U64_LO(bnx2x_sp_mapping(bp, mcast_config)),
- 0);
- } else { /* E1H */
- /* Accept one or more multicasts */
- struct dev_mc_list *mclist;
- u32 mc_filter[MC_HASH_SIZE];
- u32 crc, bit, regidx;
- int i;
-
- memset(mc_filter, 0, 4 * MC_HASH_SIZE);
-
- for (i = 0, mclist = dev->mc_list;
- mclist && (i < dev->mc_count);
- i++, mclist = mclist->next) {
-
- DP(NETIF_MSG_IFUP, "Adding mcast MAC: "
- "%02x:%02x:%02x:%02x:%02x:%02x\n",
- mclist->dmi_addr[0], mclist->dmi_addr[1],
- mclist->dmi_addr[2], mclist->dmi_addr[3],
- mclist->dmi_addr[4], mclist->dmi_addr[5]);
-
- crc = crc32c_le(0, mclist->dmi_addr, ETH_ALEN);
- bit = (crc >> 24) & 0xff;
- regidx = bit >> 5;
- bit &= 0x1f;
- mc_filter[regidx] |= (1 << bit);
- }
-
- for (i = 0; i < MC_HASH_SIZE; i++)
- REG_WR(bp, MC_HASH_OFFSET(bp, i),
- mc_filter[i]);
- }
- }
-
- bp->rx_mode = rx_mode;
- bnx2x_set_storm_rx_mode(bp);
-}
-
-/* called with rtnl_lock */
-static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
-{
- struct sockaddr *addr = p;
- struct bnx2x *bp = netdev_priv(dev);
-
- if (!is_valid_ether_addr((u8 *)(addr->sa_data)))
- return -EINVAL;
-
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- if (netif_running(dev)) {
- if (CHIP_IS_E1(bp))
- bnx2x_set_mac_addr_e1(bp, 1);
- else
- bnx2x_set_mac_addr_e1h(bp, 1);
- }
-
- return 0;
-}
-
-/* called with rtnl_lock */
-static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
- struct mii_ioctl_data *data = if_mii(ifr);
- struct bnx2x *bp = netdev_priv(dev);
- int port = BP_PORT(bp);
- int err;
-
- switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = bp->port.phy_addr;
-
- /* fallthrough */
-
- case SIOCGMIIREG: {
- u16 mii_regval;
-
- if (!netif_running(dev))
- return -EAGAIN;
-
- mutex_lock(&bp->port.phy_mutex);
- err = bnx2x_cl45_read(bp, port, 0, bp->port.phy_addr,
- DEFAULT_PHY_DEV_ADDR,
- (data->reg_num & 0x1f), &mii_regval);
- data->val_out = mii_regval;
- mutex_unlock(&bp->port.phy_mutex);
- return err;
- }
-
- case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (!netif_running(dev))
- return -EAGAIN;
-
- mutex_lock(&bp->port.phy_mutex);
- err = bnx2x_cl45_write(bp, port, 0, bp->port.phy_addr,
- DEFAULT_PHY_DEV_ADDR,
- (data->reg_num & 0x1f), data->val_in);
- mutex_unlock(&bp->port.phy_mutex);
- return err;
-
- default:
- /* do nothing */
- break;
- }
-
- return -EOPNOTSUPP;
-}
-
-/* called with rtnl_lock */
-static int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct bnx2x *bp = netdev_priv(dev);
- int rc = 0;
-
- if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) ||
- ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE))
- return -EINVAL;
-
- /* This does not race with packet allocation
- * because the actual alloc size is
- * only updated as part of load
- */
- dev->mtu = new_mtu;
-
- if (netif_running(dev)) {
- bnx2x_nic_unload(bp, UNLOAD_NORMAL);
- rc = bnx2x_nic_load(bp, LOAD_NORMAL);
- }
-
- return rc;
-}
-
-static void bnx2x_tx_timeout(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
-#ifdef BNX2X_STOP_ON_ERROR
- if (!bp->panic)
- bnx2x_panic();
-#endif
- /* This allows the netif to be shutdown gracefully before resetting */
- schedule_work(&bp->reset_task);
-}
-
-#ifdef BCM_VLAN
-/* called with rtnl_lock */
-static void bnx2x_vlan_rx_register(struct net_device *dev,
- struct vlan_group *vlgrp)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- bp->vlgrp = vlgrp;
- if (netif_running(dev))
- bnx2x_set_client_config(bp);
-}
-
-#endif
-
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
-static void poll_bnx2x(struct net_device *dev)
-{
- struct bnx2x *bp = netdev_priv(dev);
-
- disable_irq(bp->pdev->irq);
- bnx2x_interrupt(bp->pdev->irq, dev);
- enable_irq(bp->pdev->irq);
-}
-#endif
-
-static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
- struct net_device *dev)
-{
- struct bnx2x *bp;
- int rc;
-
- SET_NETDEV_DEV(dev, &pdev->dev);
- bp = netdev_priv(dev);
-
- bp->dev = dev;
- bp->pdev = pdev;
- bp->flags = 0;
- bp->func = PCI_FUNC(pdev->devfn);
-
- rc = pci_enable_device(pdev);
- if (rc) {
- printk(KERN_ERR PFX "Cannot enable PCI device, aborting\n");
- goto err_out;
- }
-
- if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
- printk(KERN_ERR PFX "Cannot find PCI device base address,"
- " aborting\n");
- rc = -ENODEV;
- goto err_out_disable;
- }
-
- if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
- printk(KERN_ERR PFX "Cannot find second PCI device"
- " base address, aborting\n");
- rc = -ENODEV;
- goto err_out_disable;
- }
-
- if (atomic_read(&pdev->enable_cnt) == 1) {
- rc = pci_request_regions(pdev, DRV_MODULE_NAME);
- if (rc) {
- printk(KERN_ERR PFX "Cannot obtain PCI resources,"
- " aborting\n");
- goto err_out_disable;
- }
-
- pci_set_master(pdev);
- pci_save_state(pdev);
- }
-
- bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
- if (bp->pm_cap == 0) {
- printk(KERN_ERR PFX "Cannot find power management"
- " capability, aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- bp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (bp->pcie_cap == 0) {
- printk(KERN_ERR PFX "Cannot find PCI Express capability,"
- " aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
- bp->flags |= USING_DAC_FLAG;
- if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
- printk(KERN_ERR PFX "pci_set_consistent_dma_mask"
- " failed, aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
- printk(KERN_ERR PFX "System does not support DMA,"
- " aborting\n");
- rc = -EIO;
- goto err_out_release;
- }
-
- dev->mem_start = pci_resource_start(pdev, 0);
- dev->base_addr = dev->mem_start;
- dev->mem_end = pci_resource_end(pdev, 0);
-
- dev->irq = pdev->irq;
-
- bp->regview = ioremap_nocache(dev->base_addr,
- pci_resource_len(pdev, 0));
- if (!bp->regview) {
- printk(KERN_ERR PFX "Cannot map register space, aborting\n");
- rc = -ENOMEM;
- goto err_out_release;
- }
-
- bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2),
- min_t(u64, BNX2X_DB_SIZE,
- pci_resource_len(pdev, 2)));
- if (!bp->doorbells) {
- printk(KERN_ERR PFX "Cannot map doorbell space, aborting\n");
- rc = -ENOMEM;
- goto err_out_unmap;
- }
-
- bnx2x_set_power_state(bp, PCI_D0);
-
- /* clean indirect addresses */
- pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
- PCICFG_VENDOR_ID_OFFSET);
- REG_WR(bp, PXP2_REG_PGL_ADDR_88_F0 + BP_PORT(bp)*16, 0);
- REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F0 + BP_PORT(bp)*16, 0);
- REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(bp)*16, 0);
- REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(bp)*16, 0);
-
- dev->hard_start_xmit = bnx2x_start_xmit;
- dev->watchdog_timeo = TX_TIMEOUT;
-
- dev->ethtool_ops = &bnx2x_ethtool_ops;
- dev->open = bnx2x_open;
- dev->stop = bnx2x_close;
- dev->set_multicast_list = bnx2x_set_rx_mode;
- dev->set_mac_address = bnx2x_change_mac_addr;
- dev->do_ioctl = bnx2x_ioctl;
- dev->change_mtu = bnx2x_change_mtu;
- dev->tx_timeout = bnx2x_tx_timeout;
-#ifdef BCM_VLAN
- dev->vlan_rx_register = bnx2x_vlan_rx_register;
-#endif
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
- dev->poll_controller = poll_bnx2x;
-#endif
- dev->features |= NETIF_F_SG;
- dev->features |= NETIF_F_HW_CSUM;
- if (bp->flags & USING_DAC_FLAG)
- dev->features |= NETIF_F_HIGHDMA;
-#ifdef BCM_VLAN
- dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
-#endif
- dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
- dev->features |= NETIF_F_TSO6;
-
- return 0;
-
-err_out_unmap:
- if (bp->regview) {
- iounmap(bp->regview);
- bp->regview = NULL;
- }
- if (bp->doorbells) {
- iounmap(bp->doorbells);
- bp->doorbells = NULL;
- }
-
-err_out_release:
- if (atomic_read(&pdev->enable_cnt) == 1)
- pci_release_regions(pdev);
-
-err_out_disable:
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
-
-err_out:
- return rc;
-}
-
-static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp)
-{
- u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
-
- val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
- return val;
-}
-
-/* return value of 1=2.5GHz 2=5GHz */
-static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
-{
- u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
-
- val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
- return val;
-}
-
-static int __devinit bnx2x_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- static int version_printed;
- struct net_device *dev = NULL;
- struct bnx2x *bp;
- int rc;
- DECLARE_MAC_BUF(mac);
-
- if (version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-
- /* dev zeroed in init_etherdev */
- dev = alloc_etherdev(sizeof(*bp));
- if (!dev) {
- printk(KERN_ERR PFX "Cannot allocate net device\n");
- return -ENOMEM;
- }
-
- netif_carrier_off(dev);
-
- bp = netdev_priv(dev);
- bp->msglevel = debug;
-
- rc = bnx2x_init_dev(pdev, dev);
- if (rc < 0) {
- free_netdev(dev);
- return rc;
- }
-
- rc = register_netdev(dev);
- if (rc) {
- dev_err(&pdev->dev, "Cannot register net device\n");
- goto init_one_exit;
- }
-
- pci_set_drvdata(pdev, dev);
-
- rc = bnx2x_init_bp(bp);
- if (rc) {
- unregister_netdev(dev);
- goto init_one_exit;
- }
-
- bp->common.name = board_info[ent->driver_data].name;
- printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
- " IRQ %d, ", dev->name, bp->common.name,
- (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
- bnx2x_get_pcie_width(bp),
- (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
- dev->base_addr, bp->pdev->irq);
- printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr));
- return 0;
-
-init_one_exit:
- if (bp->regview)
- iounmap(bp->regview);
-
- if (bp->doorbells)
- iounmap(bp->doorbells);
-
- free_netdev(dev);
-
- if (atomic_read(&pdev->enable_cnt) == 1)
- pci_release_regions(pdev);
-
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
-
- return rc;
-}
-
-static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp;
-
- if (!dev) {
- printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
- return;
- }
- bp = netdev_priv(dev);
-
- unregister_netdev(dev);
-
- if (bp->regview)
- iounmap(bp->regview);
-
- if (bp->doorbells)
- iounmap(bp->doorbells);
-
- free_netdev(dev);
-
- if (atomic_read(&pdev->enable_cnt) == 1)
- pci_release_regions(pdev);
-
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
-}
-
-static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp;
-
- if (!dev) {
- printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
- return -ENODEV;
- }
- bp = netdev_priv(dev);
-
- rtnl_lock();
-
- pci_save_state(pdev);
-
- if (!netif_running(dev)) {
- rtnl_unlock();
- return 0;
- }
-
- netif_device_detach(dev);
-
- bnx2x_nic_unload(bp, UNLOAD_CLOSE);
-
- bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
-
- rtnl_unlock();
-
- return 0;
-}
-
-static int bnx2x_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp;
- int rc;
-
- if (!dev) {
- printk(KERN_ERR PFX "BAD net device from bnx2x_init_one\n");
- return -ENODEV;
- }
- bp = netdev_priv(dev);
-
- rtnl_lock();
-
- pci_restore_state(pdev);
-
- if (!netif_running(dev)) {
- rtnl_unlock();
- return 0;
- }
-
- bnx2x_set_power_state(bp, PCI_D0);
- netif_device_attach(dev);
-
- rc = bnx2x_nic_load(bp, LOAD_OPEN);
-
- rtnl_unlock();
-
- return rc;
-}
-
-/**
- * bnx2x_io_error_detected - called when PCI error is detected
- * @pdev: Pointer to PCI device
- * @state: The current pci connection state
- *
- * This function is called after a PCI bus error affecting
- * this device has been detected.
- */
-static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
-
- rtnl_lock();
-
- netif_device_detach(dev);
-
- if (netif_running(dev))
- bnx2x_nic_unload(bp, UNLOAD_CLOSE);
-
- pci_disable_device(pdev);
-
- rtnl_unlock();
-
- /* Request a slot reset */
- return PCI_ERS_RESULT_NEED_RESET;
-}
-
-/**
- * bnx2x_io_slot_reset - called after the PCI bus has been reset
- * @pdev: Pointer to PCI device
- *
- * Restart the card from scratch, as if from a cold-boot.
- */
-static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
-
- rtnl_lock();
-
- if (pci_enable_device(pdev)) {
- dev_err(&pdev->dev,
- "Cannot re-enable PCI device after reset\n");
- rtnl_unlock();
- return PCI_ERS_RESULT_DISCONNECT;
- }
-
- pci_set_master(pdev);
- pci_restore_state(pdev);
-
- if (netif_running(dev))
- bnx2x_set_power_state(bp, PCI_D0);
-
- rtnl_unlock();
-
- return PCI_ERS_RESULT_RECOVERED;
-}
-
-/**
- * bnx2x_io_resume - called when traffic can start flowing again
- * @pdev: Pointer to PCI device
- *
- * This callback is called when the error recovery driver tells us that
- * its OK to resume normal operation.
- */
-static void bnx2x_io_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct bnx2x *bp = netdev_priv(dev);
-
- rtnl_lock();
-
- if (netif_running(dev))
- bnx2x_nic_load(bp, LOAD_OPEN);
-
- netif_device_attach(dev);
-
- rtnl_unlock();
-}
-
-static struct pci_error_handlers bnx2x_err_handler = {
- .error_detected = bnx2x_io_error_detected,
- .slot_reset = bnx2x_io_slot_reset,
- .resume = bnx2x_io_resume,
-};
-
-static struct pci_driver bnx2x_pci_driver = {
- .name = DRV_MODULE_NAME,
- .id_table = bnx2x_pci_tbl,
- .probe = bnx2x_init_one,
- .remove = __devexit_p(bnx2x_remove_one),
- .suspend = bnx2x_suspend,
- .resume = bnx2x_resume,
- .err_handler = &bnx2x_err_handler,
-};
-
-static int __init bnx2x_init(void)
-{
- return pci_register_driver(&bnx2x_pci_driver);
-}
-
-static void __exit bnx2x_cleanup(void)
-{
- pci_unregister_driver(&bnx2x_pci_driver);
-}
-
-module_init(bnx2x_init);
-module_exit(bnx2x_cleanup);
-
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 5cdae2bc055..6f4e80853ed 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -4,5 +4,8 @@
obj-$(CONFIG_BONDING) += bonding.o
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_sysfs_slave.o bond_debugfs.o bond_netlink.o bond_options.o
+
+proc-$(CONFIG_PROC_FS) += bond_procfs.o
+bonding-objs += $(proc-y)
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6106660a4a4..0dfeaf5da3f 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -20,27 +20,28 @@
*
*/
-//#define BONDING_DEBUG 1
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
+#include <linux/etherdevice.h>
#include <linux/if_bonding.h>
#include <linux/pkt_sched.h>
#include <net/net_namespace.h>
#include "bonding.h"
#include "bond_3ad.h"
-// General definitions
+/* General definitions */
#define AD_SHORT_TIMEOUT 1
#define AD_LONG_TIMEOUT 0
#define AD_STANDBY 0x2
#define AD_MAX_TX_IN_SECOND 3
#define AD_COLLECTOR_MAX_DELAY 0
-// Timer definitions(43.4.4 in the 802.3ad standard)
+/* Timer definitions (43.4.4 in the 802.3ad standard) */
#define AD_FAST_PERIODIC_TIME 1
#define AD_SLOW_PERIODIC_TIME 30
#define AD_SHORT_TIMEOUT_TIME (3*AD_FAST_PERIODIC_TIME)
@@ -48,7 +49,7 @@
#define AD_CHURN_DETECTION_TIME 60
#define AD_AGGREGATE_WAIT_TIME 2
-// Port state definitions(43.4.2.2 in the 802.3ad standard)
+/* Port state definitions (43.4.2.2 in the 802.3ad standard) */
#define AD_STATE_LACP_ACTIVITY 0x1
#define AD_STATE_LACP_TIMEOUT 0x2
#define AD_STATE_AGGREGATION 0x4
@@ -58,7 +59,9 @@
#define AD_STATE_DEFAULTED 0x40
#define AD_STATE_EXPIRED 0x80
-// Port Variables definitions used by the State Machines(43.4.7 in the 802.3ad standard)
+/* Port Variables definitions used by the State Machines (43.4.7 in the
+ * 802.3ad standard)
+ */
#define AD_PORT_BEGIN 0x1
#define AD_PORT_LACP_ENABLED 0x2
#define AD_PORT_ACTOR_CHURN 0x4
@@ -70,61 +73,35 @@
#define AD_PORT_SELECTED 0x100
#define AD_PORT_MOVED 0x200
-// Port Key definitions
-// key is determined according to the link speed, duplex and
-// user key(which is yet not supported)
-// ------------------------------------------------------------
-// Port key : | User key | Speed |Duplex|
-// ------------------------------------------------------------
-// 16 6 1 0
+/* Port Key definitions
+ * key is determined according to the link speed, duplex and
+ * user key (which is yet not supported)
+ * --------------------------------------------------------------
+ * Port key : | User key | Speed | Duplex |
+ * --------------------------------------------------------------
+ * 16 6 1 0
+ */
#define AD_DUPLEX_KEY_BITS 0x1
#define AD_SPEED_KEY_BITS 0x3E
#define AD_USER_KEY_BITS 0xFFC0
-//dalloun
#define AD_LINK_SPEED_BITMASK_1MBPS 0x1
#define AD_LINK_SPEED_BITMASK_10MBPS 0x2
#define AD_LINK_SPEED_BITMASK_100MBPS 0x4
#define AD_LINK_SPEED_BITMASK_1000MBPS 0x8
#define AD_LINK_SPEED_BITMASK_10000MBPS 0x10
-//endalloun
-// compare MAC addresses
-#define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN)
+/* compare MAC addresses */
+#define MAC_ADDRESS_EQUAL(A, B) \
+ ether_addr_equal_64bits((const u8 *)A, (const u8 *)B)
-static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}};
+static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } };
static u16 ad_ticks_per_sec;
static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
-// ================= 3AD api to bonding and kernel code ==================
-static u16 __get_link_speed(struct port *port);
-static u8 __get_duplex(struct port *port);
-static inline void __initialize_port_locks(struct port *port);
-//conversions
-static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par);
-
-
-// ================= ad code helper functions ==================
-//needed by ad_rx_machine(...)
-static void __record_pdu(struct lacpdu *lacpdu, struct port *port);
-static void __record_default(struct port *port);
-static void __update_selected(struct lacpdu *lacpdu, struct port *port);
-static void __update_default_selected(struct port *port);
-static void __choose_matched(struct lacpdu *lacpdu, struct port *port);
-static void __update_ntt(struct lacpdu *lacpdu, struct port *port);
-
-//needed for ad_mux_machine(..)
-static void __attach_bond_to_agg(struct port *port);
-static void __detach_bond_from_agg(struct port *port);
-static int __agg_ports_are_ready(struct aggregator *aggregator);
-static void __set_agg_ports_ready(struct aggregator *aggregator, int val);
-
-//needed for ad_agg_selection_logic(...)
-static u32 __get_agg_bandwidth(struct aggregator *aggregator);
-static struct aggregator *__get_active_agg(struct aggregator *aggregator);
-
+static const u8 lacpdu_mcast_addr[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
-// ================= main 802.3ad protocol functions ==================
+/* ================= main 802.3ad protocol functions ================== */
static int ad_lacpdu_send(struct port *port);
static int ad_marker_send(struct port *port, struct bond_marker *marker);
static void ad_mux_machine(struct port *port);
@@ -136,16 +113,15 @@ static void ad_agg_selection_logic(struct aggregator *aggregator);
static void ad_clear_agg(struct aggregator *aggregator);
static void ad_initialize_agg(struct aggregator *aggregator);
static void ad_initialize_port(struct port *port, int lacp_fast);
-static void ad_initialize_lacpdu(struct lacpdu *Lacpdu);
static void ad_enable_collecting_distributing(struct port *port);
static void ad_disable_collecting_distributing(struct port *port);
-static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port);
-static void ad_marker_response_received(struct bond_marker *marker, struct port *port);
+static void ad_marker_info_received(struct bond_marker *marker_info,
+ struct port *port);
+static void ad_marker_response_received(struct bond_marker *marker,
+ struct port *port);
-/////////////////////////////////////////////////////////////////////////////////
-// ================= api to bonding and kernel code ==================
-/////////////////////////////////////////////////////////////////////////////////
+/* ================= api to bonding and kernel code ================== */
/**
* __get_bond_by_port - get the port's bonding struct
@@ -155,172 +131,126 @@ static void ad_marker_response_received(struct bond_marker *marker, struct port
*/
static inline struct bonding *__get_bond_by_port(struct port *port)
{
- if (port->slave == NULL) {
+ if (port->slave == NULL)
return NULL;
- }
return bond_get_bond_by_slave(port->slave);
}
/**
- * __get_first_port - get the first port in the bond
- * @bond: the bond we're looking at
- *
- * Return the port of the first slave in @bond, or %NULL if it can't be found.
- */
-static inline struct port *__get_first_port(struct bonding *bond)
-{
- if (bond->slave_cnt == 0) {
- return NULL;
- }
-
- return &(SLAVE_AD_INFO(bond->first_slave).port);
-}
-
-/**
- * __get_next_port - get the next port in the bond
- * @port: the port we're looking at
- *
- * Return the port of the slave that is next in line of @port's slave in the
- * bond, or %NULL if it can't be found.
- */
-static inline struct port *__get_next_port(struct port *port)
-{
- struct bonding *bond = __get_bond_by_port(port);
- struct slave *slave = port->slave;
-
- // If there's no bond for this port, or this is the last slave
- if ((bond == NULL) || (slave->next == bond->first_slave)) {
- return NULL;
- }
-
- return &(SLAVE_AD_INFO(slave->next).port);
-}
-
-/**
* __get_first_agg - get the first aggregator in the bond
* @bond: the bond we're looking at
*
* Return the aggregator of the first slave in @bond, or %NULL if it can't be
* found.
+ * The caller must hold RCU or RTNL lock.
*/
static inline struct aggregator *__get_first_agg(struct port *port)
{
struct bonding *bond = __get_bond_by_port(port);
+ struct slave *first_slave;
+ struct aggregator *agg;
- // If there's no bond for this port, or bond has no slaves
- if ((bond == NULL) || (bond->slave_cnt == 0)) {
+ /* If there's no bond for this port, or bond has no slaves */
+ if (bond == NULL)
return NULL;
- }
- return &(SLAVE_AD_INFO(bond->first_slave).aggregator);
+ rcu_read_lock();
+ first_slave = bond_first_slave_rcu(bond);
+ agg = first_slave ? &(SLAVE_AD_INFO(first_slave)->aggregator) : NULL;
+ rcu_read_unlock();
+
+ return agg;
}
/**
- * __get_next_agg - get the next aggregator in the bond
- * @aggregator: the aggregator we're looking at
+ * __agg_has_partner - see if we have a partner
+ * @agg: the agregator we're looking at
*
- * Return the aggregator of the slave that is next in line of @aggregator's
- * slave in the bond, or %NULL if it can't be found.
+ * Return nonzero if aggregator has a partner (denoted by a non-zero ether
+ * address for the partner). Return 0 if not.
*/
-static inline struct aggregator *__get_next_agg(struct aggregator *aggregator)
+static inline int __agg_has_partner(struct aggregator *agg)
{
- struct slave *slave = aggregator->slave;
- struct bonding *bond = bond_get_bond_by_slave(slave);
-
- // If there's no bond for this aggregator, or this is the last slave
- if ((bond == NULL) || (slave->next == bond->first_slave)) {
- return NULL;
- }
-
- return &(SLAVE_AD_INFO(slave->next).aggregator);
+ return !is_zero_ether_addr(agg->partner_system.mac_addr_value);
}
/**
* __disable_port - disable the port's slave
* @port: the port we're looking at
- *
*/
static inline void __disable_port(struct port *port)
{
- bond_set_slave_inactive_flags(port->slave);
+ bond_set_slave_inactive_flags(port->slave, BOND_SLAVE_NOTIFY_LATER);
}
/**
* __enable_port - enable the port's slave, if it's up
* @port: the port we're looking at
- *
*/
static inline void __enable_port(struct port *port)
{
struct slave *slave = port->slave;
- if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) {
- bond_set_slave_active_flags(slave);
- }
+ if ((slave->link == BOND_LINK_UP) && bond_slave_is_up(slave))
+ bond_set_slave_active_flags(slave, BOND_SLAVE_NOTIFY_LATER);
}
/**
* __port_is_enabled - check if the port's slave is in active state
* @port: the port we're looking at
- *
*/
static inline int __port_is_enabled(struct port *port)
{
- return(port->slave->state == BOND_STATE_ACTIVE);
+ return bond_is_active_slave(port->slave);
}
/**
* __get_agg_selection_mode - get the aggregator selection mode
* @port: the port we're looking at
*
- * Get the aggregator selection mode. Can be %BANDWIDTH or %COUNT.
+ * Get the aggregator selection mode. Can be %STABLE, %BANDWIDTH or %COUNT.
*/
static inline u32 __get_agg_selection_mode(struct port *port)
{
struct bonding *bond = __get_bond_by_port(port);
- if (bond == NULL) {
- return AD_BANDWIDTH;
- }
+ if (bond == NULL)
+ return BOND_AD_STABLE;
- return BOND_AD_INFO(bond).agg_select_mode;
+ return bond->params.ad_select;
}
/**
* __check_agg_selection_timer - check if the selection timer has expired
* @port: the port we're looking at
- *
*/
static inline int __check_agg_selection_timer(struct port *port)
{
struct bonding *bond = __get_bond_by_port(port);
- if (bond == NULL) {
+ if (bond == NULL)
return 0;
- }
return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0;
}
/**
- * __get_rx_machine_lock - lock the port's RX machine
+ * __get_state_machine_lock - lock the port's state machines
* @port: the port we're looking at
- *
*/
-static inline void __get_rx_machine_lock(struct port *port)
+static inline void __get_state_machine_lock(struct port *port)
{
- spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
+ spin_lock_bh(&(SLAVE_AD_INFO(port->slave)->state_machine_lock));
}
/**
- * __release_rx_machine_lock - unlock the port's RX machine
+ * __release_state_machine_lock - unlock the port's state machines
* @port: the port we're looking at
- *
*/
-static inline void __release_rx_machine_lock(struct port *port)
+static inline void __release_state_machine_lock(struct port *port)
{
- spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
+ spin_unlock_bh(&(SLAVE_AD_INFO(port->slave)->state_machine_lock));
}
/**
@@ -339,13 +269,14 @@ static u16 __get_link_speed(struct port *port)
struct slave *slave = port->slave;
u16 speed;
- /* this if covers only a special case: when the configuration starts with
- * link down, it sets the speed to 0.
- * This is done in spite of the fact that the e100 driver reports 0 to be
- * compatible with MVT in the future.*/
- if (slave->link != BOND_LINK_UP) {
- speed=0;
- } else {
+ /* this if covers only a special case: when the configuration starts
+ * with link down, it sets the speed to 0.
+ * This is done in spite of the fact that the e100 driver reports 0
+ * to be compatible with MVT in the future.
+ */
+ if (slave->link != BOND_LINK_UP)
+ speed = 0;
+ else {
switch (slave->speed) {
case SPEED_10:
speed = AD_LINK_SPEED_BITMASK_10MBPS;
@@ -364,12 +295,14 @@ static u16 __get_link_speed(struct port *port)
break;
default:
- speed = 0; // unknown speed value from ethtool. shouldn't happen
+ /* unknown speed value from ethtool. shouldn't happen */
+ speed = 0;
break;
}
}
- dprintk("Port %d Received link speed %d update from adapter\n", port->actor_port_number, speed);
+ pr_debug("Port %d Received link speed %d update from adapter\n",
+ port->actor_port_number, speed);
return speed;
}
@@ -387,20 +320,23 @@ static u8 __get_duplex(struct port *port)
u8 retval;
- // handling a special case: when the configuration starts with
- // link down, it sets the duplex to 0.
- if (slave->link != BOND_LINK_UP) {
- retval=0x0;
- } else {
+ /* handling a special case: when the configuration starts with
+ * link down, it sets the duplex to 0.
+ */
+ if (slave->link != BOND_LINK_UP)
+ retval = 0x0;
+ else {
switch (slave->duplex) {
case DUPLEX_FULL:
- retval=0x1;
- dprintk("Port %d Received status full duplex update from adapter\n", port->actor_port_number);
+ retval = 0x1;
+ pr_debug("Port %d Received status full duplex update from adapter\n",
+ port->actor_port_number);
break;
case DUPLEX_HALF:
default:
- retval=0x0;
- dprintk("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number);
+ retval = 0x0;
+ pr_debug("Port %d Received status NOT full duplex update from adapter\n",
+ port->actor_port_number);
break;
}
}
@@ -408,17 +344,16 @@ static u8 __get_duplex(struct port *port)
}
/**
- * __initialize_port_locks - initialize a port's RX machine spinlock
- * @port: the port we're looking at
- *
+ * __initialize_port_locks - initialize a port's STATE machine spinlock
+ * @port: the slave of the port we're looking at
*/
-static inline void __initialize_port_locks(struct port *port)
+static inline void __initialize_port_locks(struct slave *slave)
{
- // make sure it isn't called twice
- spin_lock_init(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
+ /* make sure it isn't called twice */
+ spin_lock_init(&(SLAVE_AD_INFO(slave)->state_machine_lock));
}
-//conversions
+/* Conversions */
/**
* __ad_timer_to_ticks - convert a given timer type to AD module ticks
@@ -427,40 +362,81 @@ static inline void __initialize_port_locks(struct port *port)
*
* If @timer_type is %current_while_timer, @par indicates long/short timer.
* If @timer_type is %periodic_timer, @par is one of %FAST_PERIODIC_TIME,
- * %SLOW_PERIODIC_TIME.
+ * %SLOW_PERIODIC_TIME.
*/
static u16 __ad_timer_to_ticks(u16 timer_type, u16 par)
{
- u16 retval=0; //to silence the compiler
+ u16 retval = 0; /* to silence the compiler */
switch (timer_type) {
- case AD_CURRENT_WHILE_TIMER: // for rx machine usage
- if (par) { // for short or long timeout
- retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout
- } else {
- retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout
- }
+ case AD_CURRENT_WHILE_TIMER: /* for rx machine usage */
+ if (par)
+ retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec);
+ else
+ retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec);
break;
- case AD_ACTOR_CHURN_TIMER: // for local churn machine
+ case AD_ACTOR_CHURN_TIMER: /* for local churn machine */
retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec);
break;
- case AD_PERIODIC_TIMER: // for periodic machine
- retval = (par*ad_ticks_per_sec); // long timeout
+ case AD_PERIODIC_TIMER: /* for periodic machine */
+ retval = (par*ad_ticks_per_sec); /* long timeout */
break;
- case AD_PARTNER_CHURN_TIMER: // for remote churn machine
+ case AD_PARTNER_CHURN_TIMER: /* for remote churn machine */
retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec);
break;
- case AD_WAIT_WHILE_TIMER: // for selection machine
+ case AD_WAIT_WHILE_TIMER: /* for selection machine */
retval = (AD_AGGREGATE_WAIT_TIME*ad_ticks_per_sec);
break;
}
+
return retval;
}
-/////////////////////////////////////////////////////////////////////////////////
-// ================= ad_rx_machine helper functions ==================
-/////////////////////////////////////////////////////////////////////////////////
+/* ================= ad_rx_machine helper functions ================== */
+
+/**
+ * __choose_matched - update a port's matched variable from a received lacpdu
+ * @lacpdu: the lacpdu we've received
+ * @port: the port we're looking at
+ *
+ * Update the value of the matched variable, using parameter values from a
+ * newly received lacpdu. Parameter values for the partner carried in the
+ * received PDU are compared with the corresponding operational parameter
+ * values for the actor. Matched is set to TRUE if all of these parameters
+ * match and the PDU parameter partner_state.aggregation has the same value as
+ * actor_oper_port_state.aggregation and lacp will actively maintain the link
+ * in the aggregation. Matched is also set to TRUE if the value of
+ * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates
+ * an individual link and lacp will actively maintain the link. Otherwise,
+ * matched is set to FALSE. LACP is considered to be actively maintaining the
+ * link if either the PDU's actor_state.lacp_activity variable is TRUE or both
+ * the actor's actor_oper_port_state.lacp_activity and the PDU's
+ * partner_state.lacp_activity variables are TRUE.
+ *
+ * Note: the AD_PORT_MATCHED "variable" is not specified by 802.3ad; it is
+ * used here to implement the language from 802.3ad 43.4.9 that requires
+ * recordPDU to "match" the LACPDU parameters to the stored values.
+ */
+static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
+{
+ /* check if all parameters are alike
+ * or this is individual link(aggregation == FALSE)
+ * then update the state machine Matched variable.
+ */
+ if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
+ (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
+ MAC_ADDRESS_EQUAL(&(lacpdu->partner_system), &(port->actor_system)) &&
+ (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
+ (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
+ ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
+ ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
+ ) {
+ port->sm_vars |= AD_PORT_MATCHED;
+ } else {
+ port->sm_vars &= ~AD_PORT_MATCHED;
+ }
+}
/**
* __record_pdu - record parameters from a received lacpdu
@@ -473,34 +449,31 @@ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par)
*/
static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
{
- // validate lacpdu and port
if (lacpdu && port) {
- // record the new parameter values for the partner operational
- port->partner_oper_port_number = ntohs(lacpdu->actor_port);
- port->partner_oper_port_priority = ntohs(lacpdu->actor_port_priority);
- port->partner_oper_system = lacpdu->actor_system;
- port->partner_oper_system_priority = ntohs(lacpdu->actor_system_priority);
- port->partner_oper_key = ntohs(lacpdu->actor_key);
- // zero partener's lase states
- port->partner_oper_port_state = 0;
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY);
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_TIMEOUT);
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_AGGREGATION);
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION);
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_COLLECTING);
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DISTRIBUTING);
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_DEFAULTED);
- port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_EXPIRED);
-
- // set actor_oper_port_state.defaulted to FALSE
+ struct port_params *partner = &port->partner_oper;
+
+ __choose_matched(lacpdu, port);
+ /* record the new parameter values for the partner
+ * operational
+ */
+ partner->port_number = ntohs(lacpdu->actor_port);
+ partner->port_priority = ntohs(lacpdu->actor_port_priority);
+ partner->system = lacpdu->actor_system;
+ partner->system_priority = ntohs(lacpdu->actor_system_priority);
+ partner->key = ntohs(lacpdu->actor_key);
+ partner->port_state = lacpdu->actor_state;
+
+ /* set actor_oper_port_state.defaulted to FALSE */
port->actor_oper_port_state &= ~AD_STATE_DEFAULTED;
- // set the partner sync. to on if the partner is sync. and the port is matched
- if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) {
- port->partner_oper_port_state |= AD_STATE_SYNCHRONIZATION;
- } else {
- port->partner_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;
- }
+ /* set the partner sync. to on if the partner is sync,
+ * and the port is matched
+ */
+ if ((port->sm_vars & AD_PORT_MATCHED)
+ && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION))
+ partner->port_state |= AD_STATE_SYNCHRONIZATION;
+ else
+ partner->port_state &= ~AD_STATE_SYNCHRONIZATION;
}
}
@@ -514,17 +487,12 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port)
*/
static void __record_default(struct port *port)
{
- // validate the port
if (port) {
- // record the partner admin parameters
- port->partner_oper_port_number = port->partner_admin_port_number;
- port->partner_oper_port_priority = port->partner_admin_port_priority;
- port->partner_oper_system = port->partner_admin_system;
- port->partner_oper_system_priority = port->partner_admin_system_priority;
- port->partner_oper_key = port->partner_admin_key;
- port->partner_oper_port_state = port->partner_admin_port_state;
-
- // set actor_oper_port_state.defaulted to true
+ /* record the partner admin parameters */
+ memcpy(&port->partner_oper, &port->partner_admin,
+ sizeof(struct port_params));
+
+ /* set actor_oper_port_state.defaulted to true */
port->actor_oper_port_state |= AD_STATE_DEFAULTED;
}
}
@@ -544,17 +512,18 @@ static void __record_default(struct port *port)
*/
static void __update_selected(struct lacpdu *lacpdu, struct port *port)
{
- // validate lacpdu and port
if (lacpdu && port) {
- // check if any parameter is different
- if ((ntohs(lacpdu->actor_port) != port->partner_oper_port_number) ||
- (ntohs(lacpdu->actor_port_priority) != port->partner_oper_port_priority) ||
- MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) ||
- (ntohs(lacpdu->actor_system_priority) != port->partner_oper_system_priority) ||
- (ntohs(lacpdu->actor_key) != port->partner_oper_key) ||
- ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION))
- ) {
- // update the state machine Selected variable
+ const struct port_params *partner = &port->partner_oper;
+
+ /* check if any parameter is different then
+ * update the state machine selected variable.
+ */
+ if (ntohs(lacpdu->actor_port) != partner->port_number ||
+ ntohs(lacpdu->actor_port_priority) != partner->port_priority ||
+ !MAC_ADDRESS_EQUAL(&lacpdu->actor_system, &partner->system) ||
+ ntohs(lacpdu->actor_system_priority) != partner->system_priority ||
+ ntohs(lacpdu->actor_key) != partner->key ||
+ (lacpdu->actor_state & AD_STATE_AGGREGATION) != (partner->port_state & AD_STATE_AGGREGATION)) {
port->sm_vars &= ~AD_PORT_SELECTED;
}
}
@@ -574,64 +543,26 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port)
*/
static void __update_default_selected(struct port *port)
{
- // validate the port
if (port) {
- // check if any parameter is different
- if ((port->partner_admin_port_number != port->partner_oper_port_number) ||
- (port->partner_admin_port_priority != port->partner_oper_port_priority) ||
- MAC_ADDRESS_COMPARE(&(port->partner_admin_system), &(port->partner_oper_system)) ||
- (port->partner_admin_system_priority != port->partner_oper_system_priority) ||
- (port->partner_admin_key != port->partner_oper_key) ||
- ((port->partner_admin_port_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION))
- ) {
- // update the state machine Selected variable
+ const struct port_params *admin = &port->partner_admin;
+ const struct port_params *oper = &port->partner_oper;
+
+ /* check if any parameter is different then
+ * update the state machine selected variable.
+ */
+ if (admin->port_number != oper->port_number ||
+ admin->port_priority != oper->port_priority ||
+ !MAC_ADDRESS_EQUAL(&admin->system, &oper->system) ||
+ admin->system_priority != oper->system_priority ||
+ admin->key != oper->key ||
+ (admin->port_state & AD_STATE_AGGREGATION)
+ != (oper->port_state & AD_STATE_AGGREGATION)) {
port->sm_vars &= ~AD_PORT_SELECTED;
}
}
}
/**
- * __choose_matched - update a port's matched variable from a received lacpdu
- * @lacpdu: the lacpdu we've received
- * @port: the port we're looking at
- *
- * Update the value of the matched variable, using parameter values from a
- * newly received lacpdu. Parameter values for the partner carried in the
- * received PDU are compared with the corresponding operational parameter
- * values for the actor. Matched is set to TRUE if all of these parameters
- * match and the PDU parameter partner_state.aggregation has the same value as
- * actor_oper_port_state.aggregation and lacp will actively maintain the link
- * in the aggregation. Matched is also set to TRUE if the value of
- * actor_state.aggregation in the received PDU is set to FALSE, i.e., indicates
- * an individual link and lacp will actively maintain the link. Otherwise,
- * matched is set to FALSE. LACP is considered to be actively maintaining the
- * link if either the PDU's actor_state.lacp_activity variable is TRUE or both
- * the actor's actor_oper_port_state.lacp_activity and the PDU's
- * partner_state.lacp_activity variables are TRUE.
- */
-static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
-{
- // validate lacpdu and port
- if (lacpdu && port) {
- // check if all parameters are alike
- if (((ntohs(lacpdu->partner_port) == port->actor_port_number) &&
- (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) &&
- !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) &&
- (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) &&
- (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) &&
- ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) ||
- // or this is individual link(aggregation == FALSE)
- ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0)
- ) {
- // update the state machine Matched variable
- port->sm_vars |= AD_PORT_MATCHED;
- } else {
- port->sm_vars &= ~AD_PORT_MATCHED;
- }
- }
-}
-
-/**
* __update_ntt - update a port's ntt variable from a received lacpdu
* @lacpdu: the lacpdu we've received
* @port: the port we're looking at
@@ -645,12 +576,14 @@ static void __choose_matched(struct lacpdu *lacpdu, struct port *port)
*/
static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
{
- // validate lacpdu and port
+ /* validate lacpdu and port */
if (lacpdu && port) {
- // check if any parameter is different
+ /* check if any parameter is different then
+ * update the port->ntt.
+ */
if ((ntohs(lacpdu->partner_port) != port->actor_port_number) ||
(ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) ||
- MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) ||
+ !MAC_ADDRESS_EQUAL(&(lacpdu->partner_system), &(port->actor_system)) ||
(ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) ||
(ntohs(lacpdu->partner_key) != port->actor_oper_port_key) ||
((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) ||
@@ -658,43 +591,12 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port)
((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) ||
((lacpdu->partner_state & AD_STATE_AGGREGATION) != (port->actor_oper_port_state & AD_STATE_AGGREGATION))
) {
- // set ntt to be TRUE
- port->ntt = 1;
+ port->ntt = true;
}
}
}
/**
- * __attach_bond_to_agg
- * @port: the port we're looking at
- *
- * Handle the attaching of the port's control parser/multiplexer and the
- * aggregator. This function does nothing since the parser/multiplexer of the
- * receive and the parser/multiplexer of the aggregator are already combined.
- */
-static void __attach_bond_to_agg(struct port *port)
-{
- port=NULL; // just to satisfy the compiler
- // This function does nothing since the parser/multiplexer of the receive
- // and the parser/multiplexer of the aggregator are already combined
-}
-
-/**
- * __detach_bond_from_agg
- * @port: the port we're looking at
- *
- * Handle the detaching of the port's control parser/multiplexer from the
- * aggregator. This function does nothing since the parser/multiplexer of the
- * receive and the parser/multiplexer of the aggregator are already combined.
- */
-static void __detach_bond_from_agg(struct port *port)
-{
- port=NULL; // just to satisfy the compiler
- // This function does nothing sience the parser/multiplexer of the receive
- // and the parser/multiplexer of the aggregator are already combined
-}
-
-/**
* __agg_ports_are_ready - check if all ports in an aggregator are ready
* @aggregator: the aggregator we're looking at
*
@@ -705,8 +607,12 @@ static int __agg_ports_are_ready(struct aggregator *aggregator)
int retval = 1;
if (aggregator) {
- // scan all ports in this aggregator to verfy if they are all ready
- for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
+ /* scan all ports in this aggregator to verfy if they are
+ * all ready.
+ */
+ for (port = aggregator->lag_ports;
+ port;
+ port = port->next_port_in_aggregator) {
if (!(port->sm_vars & AD_PORT_READY_N)) {
retval = 0;
break;
@@ -727,12 +633,12 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
{
struct port *port;
- for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
- if (val) {
+ for (port = aggregator->lag_ports; port;
+ port = port->next_port_in_aggregator) {
+ if (val)
port->sm_vars |= AD_PORT_READY;
- } else {
+ else
port->sm_vars &= ~AD_PORT_READY;
- }
}
}
@@ -743,12 +649,10 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
*/
static u32 __get_agg_bandwidth(struct aggregator *aggregator)
{
- u32 bandwidth=0;
- u32 basic_speed;
+ u32 bandwidth = 0;
if (aggregator->num_of_ports) {
- basic_speed = __get_link_speed(aggregator->lag_ports);
- switch (basic_speed) {
+ switch (__get_link_speed(aggregator->lag_ports)) {
case AD_LINK_SPEED_BITMASK_1MBPS:
bandwidth = aggregator->num_of_ports;
break;
@@ -765,7 +669,7 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
bandwidth = aggregator->num_of_ports * 10000;
break;
default:
- bandwidth=0; // to silent the compilor ....
+ bandwidth = 0; /* to silence the compiler */
}
}
return bandwidth;
@@ -775,32 +679,32 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator)
* __get_active_agg - get the current active aggregator
* @aggregator: the aggregator we're looking at
*
+ * Caller must hold RCU lock.
*/
static struct aggregator *__get_active_agg(struct aggregator *aggregator)
{
- struct aggregator *retval = NULL;
+ struct bonding *bond = aggregator->slave->bond;
+ struct list_head *iter;
+ struct slave *slave;
- for (; aggregator; aggregator = __get_next_agg(aggregator)) {
- if (aggregator->is_active) {
- retval = aggregator;
- break;
- }
- }
+ bond_for_each_slave_rcu(bond, slave, iter)
+ if (SLAVE_AD_INFO(slave)->aggregator.is_active)
+ return &(SLAVE_AD_INFO(slave)->aggregator);
- return retval;
+ return NULL;
}
/**
* __update_lacpdu_from_port - update a port's lacpdu fields
* @port: the port we're looking at
- *
*/
static inline void __update_lacpdu_from_port(struct port *port)
{
struct lacpdu *lacpdu = &port->lacpdu;
+ const struct port_params *partner = &port->partner_oper;
- /* update current actual Actor parameters */
- /* lacpdu->subtype initialized
+ /* update current actual Actor parameters
+ * lacpdu->subtype initialized
* lacpdu->version_number initialized
* lacpdu->tlv_type_actor_info initialized
* lacpdu->actor_information_length initialized
@@ -818,12 +722,12 @@ static inline void __update_lacpdu_from_port(struct port *port)
* lacpdu->partner_information_length initialized
*/
- lacpdu->partner_system_priority = htons(port->partner_oper_system_priority);
- lacpdu->partner_system = port->partner_oper_system;
- lacpdu->partner_key = htons(port->partner_oper_key);
- lacpdu->partner_port_priority = htons(port->partner_oper_port_priority);
- lacpdu->partner_port = htons(port->partner_oper_port_number);
- lacpdu->partner_state = port->partner_oper_port_state;
+ lacpdu->partner_system_priority = htons(partner->system_priority);
+ lacpdu->partner_system = partner->system;
+ lacpdu->partner_key = htons(partner->key);
+ lacpdu->partner_port_priority = htons(partner->port_priority);
+ lacpdu->partner_port = htons(partner->port_number);
+ lacpdu->partner_state = partner->port_state;
/* lacpdu->reserved_3_2 initialized
* lacpdu->tlv_type_collector_info initialized
@@ -836,9 +740,7 @@ static inline void __update_lacpdu_from_port(struct port *port)
*/
}
-//////////////////////////////////////////////////////////////////////////////////////
-// ================= main 802.3ad protocol code ======================================
-//////////////////////////////////////////////////////////////////////////////////////
+/* ================= main 802.3ad protocol code ========================= */
/**
* ad_lacpdu_send - send out a lacpdu packet on a given port
@@ -853,12 +755,10 @@ static int ad_lacpdu_send(struct port *port)
struct sk_buff *skb;
struct lacpdu_header *lacpdu_header;
int length = sizeof(struct lacpdu_header);
- struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;
skb = dev_alloc_skb(length);
- if (!skb) {
+ if (!skb)
return -ENOMEM;
- }
skb->dev = slave->dev;
skb_reset_mac_header(skb);
@@ -868,13 +768,14 @@ static int ad_lacpdu_send(struct port *port)
lacpdu_header = (struct lacpdu_header *)skb_put(skb, length);
- lacpdu_header->ad_header.destination_address = lacpdu_multicast_address;
- /* Note: source addres is set to be the member's PERMANENT address, because we use it
- to identify loopback lacpdus in receive. */
- lacpdu_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr));
- lacpdu_header->ad_header.length_type = PKT_TYPE_LACPDU;
+ ether_addr_copy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr);
+ /* Note: source address is set to be the member's PERMANENT address,
+ * because we use it to identify loopback lacpdus in receive.
+ */
+ ether_addr_copy(lacpdu_header->hdr.h_source, slave->perm_hwaddr);
+ lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU;
- lacpdu_header->lacpdu = port->lacpdu; // struct copy
+ lacpdu_header->lacpdu = port->lacpdu;
dev_queue_xmit(skb);
@@ -895,12 +796,10 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)
struct sk_buff *skb;
struct bond_marker_header *marker_header;
int length = sizeof(struct bond_marker_header);
- struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;
skb = dev_alloc_skb(length + 16);
- if (!skb) {
+ if (!skb)
return -ENOMEM;
- }
skb_reserve(skb, 16);
@@ -911,13 +810,14 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)
marker_header = (struct bond_marker_header *)skb_put(skb, length);
- marker_header->ad_header.destination_address = lacpdu_multicast_address;
- /* Note: source addres is set to be the member's PERMANENT address, because we use it
- to identify loopback MARKERs in receive. */
- marker_header->ad_header.source_address = *((struct mac_addr *)(slave->perm_hwaddr));
- marker_header->ad_header.length_type = PKT_TYPE_LACPDU;
+ ether_addr_copy(marker_header->hdr.h_dest, lacpdu_mcast_addr);
+ /* Note: source address is set to be the member's PERMANENT address,
+ * because we use it to identify loopback MARKERs in receive.
+ */
+ ether_addr_copy(marker_header->hdr.h_source, slave->perm_hwaddr);
+ marker_header->hdr.h_proto = PKT_TYPE_LACPDU;
- marker_header->marker = *marker; // struct copy
+ marker_header->marker = *marker;
dev_queue_xmit(skb);
@@ -927,71 +827,90 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)
/**
* ad_mux_machine - handle a port's mux state machine
* @port: the port we're looking at
- *
*/
static void ad_mux_machine(struct port *port)
{
mux_states_t last_state;
- // keep current State Machine state to compare later if it was changed
+ /* keep current State Machine state to compare later if it was
+ * changed
+ */
last_state = port->sm_mux_state;
if (port->sm_vars & AD_PORT_BEGIN) {
- port->sm_mux_state = AD_MUX_DETACHED; // next state
+ port->sm_mux_state = AD_MUX_DETACHED;
} else {
switch (port->sm_mux_state) {
case AD_MUX_DETACHED:
- if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY
- port->sm_mux_state = AD_MUX_WAITING; // next state
- }
+ if ((port->sm_vars & AD_PORT_SELECTED)
+ || (port->sm_vars & AD_PORT_STANDBY))
+ /* if SELECTED or STANDBY */
+ port->sm_mux_state = AD_MUX_WAITING;
break;
case AD_MUX_WAITING:
- // if SELECTED == FALSE return to DETACH state
- if (!(port->sm_vars & AD_PORT_SELECTED)) { // if UNSELECTED
+ /* if SELECTED == FALSE return to DETACH state */
+ if (!(port->sm_vars & AD_PORT_SELECTED)) {
port->sm_vars &= ~AD_PORT_READY_N;
- // in order to withhold the Selection Logic to check all ports READY_N value
- // every callback cycle to update ready variable, we check READY_N and update READY here
+ /* in order to withhold the Selection Logic to
+ * check all ports READY_N value every callback
+ * cycle to update ready variable, we check
+ * READY_N and update READY here
+ */
__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
- port->sm_mux_state = AD_MUX_DETACHED; // next state
+ port->sm_mux_state = AD_MUX_DETACHED;
break;
}
- // check if the wait_while_timer expired
- if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) {
+ /* check if the wait_while_timer expired */
+ if (port->sm_mux_timer_counter
+ && !(--port->sm_mux_timer_counter))
port->sm_vars |= AD_PORT_READY_N;
- }
- // in order to withhold the selection logic to check all ports READY_N value
- // every callback cycle to update ready variable, we check READY_N and update READY here
+ /* in order to withhold the selection logic to check
+ * all ports READY_N value every callback cycle to
+ * update ready variable, we check READY_N and update
+ * READY here
+ */
__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
- // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state
- if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) {
- port->sm_mux_state = AD_MUX_ATTACHED; // next state
- }
+ /* if the wait_while_timer expired, and the port is
+ * in READY state, move to ATTACHED state
+ */
+ if ((port->sm_vars & AD_PORT_READY)
+ && !port->sm_mux_timer_counter)
+ port->sm_mux_state = AD_MUX_ATTACHED;
break;
case AD_MUX_ATTACHED:
- // check also if agg_select_timer expired(so the edable port will take place only after this timer)
- if ((port->sm_vars & AD_PORT_SELECTED) && (port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION) && !__check_agg_selection_timer(port)) {
- port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;// next state
- } else if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if UNSELECTED or STANDBY
+ /* check also if agg_select_timer expired (so the
+ * edable port will take place only after this timer)
+ */
+ if ((port->sm_vars & AD_PORT_SELECTED) &&
+ (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) &&
+ !__check_agg_selection_timer(port)) {
+ port->sm_mux_state = AD_MUX_COLLECTING_DISTRIBUTING;
+ } else if (!(port->sm_vars & AD_PORT_SELECTED) ||
+ (port->sm_vars & AD_PORT_STANDBY)) {
+ /* if UNSELECTED or STANDBY */
port->sm_vars &= ~AD_PORT_READY_N;
- // in order to withhold the selection logic to check all ports READY_N value
- // every callback cycle to update ready variable, we check READY_N and update READY here
+ /* in order to withhold the selection logic to
+ * check all ports READY_N value every callback
+ * cycle to update ready variable, we check
+ * READY_N and update READY here
+ */
__set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
- port->sm_mux_state = AD_MUX_DETACHED;// next state
+ port->sm_mux_state = AD_MUX_DETACHED;
}
break;
case AD_MUX_COLLECTING_DISTRIBUTING:
- if (!(port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY) ||
- !(port->partner_oper_port_state & AD_STATE_SYNCHRONIZATION)
- ) {
- port->sm_mux_state = AD_MUX_ATTACHED;// next state
-
+ if (!(port->sm_vars & AD_PORT_SELECTED) ||
+ (port->sm_vars & AD_PORT_STANDBY) ||
+ !(port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION)) {
+ port->sm_mux_state = AD_MUX_ATTACHED;
} else {
- // if port state hasn't changed make
- // sure that a collecting distributing
- // port in an active aggregator is enabled
+ /* if port state hasn't changed make
+ * sure that a collecting distributing
+ * port in an active aggregator is enabled
+ */
if (port->aggregator &&
port->aggregator->is_active &&
!__port_is_enabled(port)) {
@@ -1000,41 +919,41 @@ static void ad_mux_machine(struct port *port)
}
}
break;
- default: //to silence the compiler
+ default:
break;
}
}
- // check if the state machine was changed
+ /* check if the state machine was changed */
if (port->sm_mux_state != last_state) {
- dprintk("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_mux_state);
+ pr_debug("Mux Machine: Port=%d, Last State=%d, Curr State=%d\n",
+ port->actor_port_number, last_state,
+ port->sm_mux_state);
switch (port->sm_mux_state) {
case AD_MUX_DETACHED:
- __detach_bond_from_agg(port);
port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;
ad_disable_collecting_distributing(port);
port->actor_oper_port_state &= ~AD_STATE_COLLECTING;
port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING;
- port->ntt = 1;
+ port->ntt = true;
break;
case AD_MUX_WAITING:
port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0);
break;
case AD_MUX_ATTACHED:
- __attach_bond_to_agg(port);
port->actor_oper_port_state |= AD_STATE_SYNCHRONIZATION;
port->actor_oper_port_state &= ~AD_STATE_COLLECTING;
port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING;
ad_disable_collecting_distributing(port);
- port->ntt = 1;
+ port->ntt = true;
break;
case AD_MUX_COLLECTING_DISTRIBUTING:
port->actor_oper_port_state |= AD_STATE_COLLECTING;
port->actor_oper_port_state |= AD_STATE_DISTRIBUTING;
ad_enable_collecting_distributing(port);
- port->ntt = 1;
+ port->ntt = true;
break;
- default: //to silence the compiler
+ default:
break;
}
}
@@ -1053,92 +972,100 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
{
rx_states_t last_state;
- // Lock to prevent 2 instances of this function to run simultaneously(rx interrupt and periodic machine callback)
- __get_rx_machine_lock(port);
-
- // keep current State Machine state to compare later if it was changed
+ /* keep current State Machine state to compare later if it was
+ * changed
+ */
last_state = port->sm_rx_state;
- // check if state machine should change state
- // first, check if port was reinitialized
- if (port->sm_vars & AD_PORT_BEGIN) {
- port->sm_rx_state = AD_RX_INITIALIZE; // next state
- }
- // check if port is not enabled
- else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) {
- port->sm_rx_state = AD_RX_PORT_DISABLED; // next state
- }
- // check if new lacpdu arrived
- else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) {
- port->sm_rx_timer_counter = 0; // zero timer
+ /* check if state machine should change state */
+
+ /* first, check if port was reinitialized */
+ if (port->sm_vars & AD_PORT_BEGIN)
+ port->sm_rx_state = AD_RX_INITIALIZE;
+ /* check if port is not enabled */
+ else if (!(port->sm_vars & AD_PORT_BEGIN)
+ && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED))
+ port->sm_rx_state = AD_RX_PORT_DISABLED;
+ /* check if new lacpdu arrived */
+ else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) ||
+ (port->sm_rx_state == AD_RX_DEFAULTED) ||
+ (port->sm_rx_state == AD_RX_CURRENT))) {
+ port->sm_rx_timer_counter = 0;
port->sm_rx_state = AD_RX_CURRENT;
} else {
- // if timer is on, and if it is expired
- if (port->sm_rx_timer_counter && !(--port->sm_rx_timer_counter)) {
+ /* if timer is on, and if it is expired */
+ if (port->sm_rx_timer_counter &&
+ !(--port->sm_rx_timer_counter)) {
switch (port->sm_rx_state) {
case AD_RX_EXPIRED:
- port->sm_rx_state = AD_RX_DEFAULTED; // next state
+ port->sm_rx_state = AD_RX_DEFAULTED;
break;
case AD_RX_CURRENT:
- port->sm_rx_state = AD_RX_EXPIRED; // next state
+ port->sm_rx_state = AD_RX_EXPIRED;
break;
- default: //to silence the compiler
+ default:
break;
}
} else {
- // if no lacpdu arrived and no timer is on
+ /* if no lacpdu arrived and no timer is on */
switch (port->sm_rx_state) {
case AD_RX_PORT_DISABLED:
- if (port->sm_vars & AD_PORT_MOVED) {
- port->sm_rx_state = AD_RX_INITIALIZE; // next state
- } else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) {
- port->sm_rx_state = AD_RX_EXPIRED; // next state
- } else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) {
- port->sm_rx_state = AD_RX_LACP_DISABLED; // next state
- }
+ if (port->sm_vars & AD_PORT_MOVED)
+ port->sm_rx_state = AD_RX_INITIALIZE;
+ else if (port->is_enabled
+ && (port->sm_vars
+ & AD_PORT_LACP_ENABLED))
+ port->sm_rx_state = AD_RX_EXPIRED;
+ else if (port->is_enabled
+ && ((port->sm_vars
+ & AD_PORT_LACP_ENABLED) == 0))
+ port->sm_rx_state = AD_RX_LACP_DISABLED;
break;
- default: //to silence the compiler
+ default:
break;
}
}
}
- // check if the State machine was changed or new lacpdu arrived
+ /* check if the State machine was changed or new lacpdu arrived */
if ((port->sm_rx_state != last_state) || (lacpdu)) {
- dprintk("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_rx_state);
+ pr_debug("Rx Machine: Port=%d, Last State=%d, Curr State=%d\n",
+ port->actor_port_number, last_state,
+ port->sm_rx_state);
switch (port->sm_rx_state) {
case AD_RX_INITIALIZE:
- if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
+ if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS))
port->sm_vars &= ~AD_PORT_LACP_ENABLED;
- } else {
+ else
port->sm_vars |= AD_PORT_LACP_ENABLED;
- }
port->sm_vars &= ~AD_PORT_SELECTED;
__record_default(port);
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
port->sm_vars &= ~AD_PORT_MOVED;
- port->sm_rx_state = AD_RX_PORT_DISABLED; // next state
-
- /*- Fall Through -*/
+ port->sm_rx_state = AD_RX_PORT_DISABLED;
+ /* Fall Through */
case AD_RX_PORT_DISABLED:
port->sm_vars &= ~AD_PORT_MATCHED;
break;
case AD_RX_LACP_DISABLED:
port->sm_vars &= ~AD_PORT_SELECTED;
__record_default(port);
- port->partner_oper_port_state &= ~AD_STATE_AGGREGATION;
+ port->partner_oper.port_state &= ~AD_STATE_AGGREGATION;
port->sm_vars |= AD_PORT_MATCHED;
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
break;
case AD_RX_EXPIRED:
- //Reset of the Synchronization flag. (Standard 43.4.12)
- //This reset cause to disable this port in the COLLECTING_DISTRIBUTING state of the
- //mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port.
- port->partner_oper_port_state &= ~AD_STATE_SYNCHRONIZATION;
+ /* Reset of the Synchronization flag (Standard 43.4.12)
+ * This reset cause to disable this port in the
+ * COLLECTING_DISTRIBUTING state of the mux machine in
+ * case of EXPIRED even if LINK_DOWN didn't arrive for
+ * the port.
+ */
+ port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION;
port->sm_vars &= ~AD_PORT_MATCHED;
- port->partner_oper_port_state |= AD_SHORT_TIMEOUT;
+ port->partner_oper.port_state |= AD_STATE_LACP_ACTIVITY;
port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT));
port->actor_oper_port_state |= AD_STATE_EXPIRED;
break;
@@ -1149,57 +1076,55 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
break;
case AD_RX_CURRENT:
- // detect loopback situation
- if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
- // INFO_RECEIVED_LOOPBACK_FRAMES
- printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
- "adapter (%s). Check the configuration to verify that all "
- "Adapters are connected to 802.3ad compliant switch ports\n",
- port->slave->dev->master->name, port->slave->dev->name);
- __release_rx_machine_lock(port);
+ /* detect loopback situation */
+ if (MAC_ADDRESS_EQUAL(&(lacpdu->actor_system),
+ &(port->actor_system))) {
+ pr_err("%s: An illegal loopback occurred on adapter (%s)\n"
+ "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n",
+ port->slave->bond->dev->name,
+ port->slave->dev->name);
return;
}
__update_selected(lacpdu, port);
__update_ntt(lacpdu, port);
__record_pdu(lacpdu, port);
- __choose_matched(lacpdu, port);
port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT));
port->actor_oper_port_state &= ~AD_STATE_EXPIRED;
- // verify that if the aggregator is enabled, the port is enabled too.
- //(because if the link goes down for a short time, the 802.3ad will not
- // catch it, and the port will continue to be disabled)
- if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) {
- __enable_port(port);
- }
break;
- default: //to silence the compiler
+ default:
break;
}
}
- __release_rx_machine_lock(port);
}
/**
* ad_tx_machine - handle a port's tx state machine
* @port: the port we're looking at
- *
*/
static void ad_tx_machine(struct port *port)
{
- // check if tx timer expired, to verify that we do not send more than 3 packets per second
+ /* check if tx timer expired, to verify that we do not send more than
+ * 3 packets per second
+ */
if (port->sm_tx_timer_counter && !(--port->sm_tx_timer_counter)) {
- // check if there is something to send
+ /* check if there is something to send */
if (port->ntt && (port->sm_vars & AD_PORT_LACP_ENABLED)) {
__update_lacpdu_from_port(port);
- // send the lacpdu
+
if (ad_lacpdu_send(port) >= 0) {
- dprintk("Sent LACPDU on port %d\n", port->actor_port_number);
- // mark ntt as false, so it will not be sent again until demanded
- port->ntt = 0;
+ pr_debug("Sent LACPDU on port %d\n",
+ port->actor_port_number);
+
+ /* mark ntt as false, so it will not be sent
+ * again until demanded
+ */
+ port->ntt = false;
}
}
- // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND
- port->sm_tx_timer_counter=ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
+ /* restart tx timer(to verify that we will not exceed
+ * AD_MAX_TX_IN_SECOND
+ */
+ port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
}
}
@@ -1213,74 +1138,79 @@ static void ad_periodic_machine(struct port *port)
{
periodic_states_t last_state;
- // keep current state machine state to compare later if it was changed
+ /* keep current state machine state to compare later if it was changed */
last_state = port->sm_periodic_state;
- // check if port was reinitialized
+ /* check if port was reinitialized */
if (((port->sm_vars & AD_PORT_BEGIN) || !(port->sm_vars & AD_PORT_LACP_ENABLED) || !port->is_enabled) ||
- (!(port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY) && !(port->partner_oper_port_state & AD_STATE_LACP_ACTIVITY))
+ (!(port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY) && !(port->partner_oper.port_state & AD_STATE_LACP_ACTIVITY))
) {
- port->sm_periodic_state = AD_NO_PERIODIC; // next state
+ port->sm_periodic_state = AD_NO_PERIODIC;
}
- // check if state machine should change state
+ /* check if state machine should change state */
else if (port->sm_periodic_timer_counter) {
- // check if periodic state machine expired
+ /* check if periodic state machine expired */
if (!(--port->sm_periodic_timer_counter)) {
- // if expired then do tx
- port->sm_periodic_state = AD_PERIODIC_TX; // next state
+ /* if expired then do tx */
+ port->sm_periodic_state = AD_PERIODIC_TX;
} else {
- // If not expired, check if there is some new timeout parameter from the partner state
+ /* If not expired, check if there is some new timeout
+ * parameter from the partner state
+ */
switch (port->sm_periodic_state) {
case AD_FAST_PERIODIC:
- if (!(port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) {
- port->sm_periodic_state = AD_SLOW_PERIODIC; // next state
- }
+ if (!(port->partner_oper.port_state
+ & AD_STATE_LACP_TIMEOUT))
+ port->sm_periodic_state = AD_SLOW_PERIODIC;
break;
case AD_SLOW_PERIODIC:
- if ((port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) {
- // stop current timer
+ if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) {
port->sm_periodic_timer_counter = 0;
- port->sm_periodic_state = AD_PERIODIC_TX; // next state
+ port->sm_periodic_state = AD_PERIODIC_TX;
}
break;
- default: //to silence the compiler
+ default:
break;
}
}
} else {
switch (port->sm_periodic_state) {
case AD_NO_PERIODIC:
- port->sm_periodic_state = AD_FAST_PERIODIC; // next state
+ port->sm_periodic_state = AD_FAST_PERIODIC;
break;
case AD_PERIODIC_TX:
- if (!(port->partner_oper_port_state & AD_STATE_LACP_TIMEOUT)) {
- port->sm_periodic_state = AD_SLOW_PERIODIC; // next state
- } else {
- port->sm_periodic_state = AD_FAST_PERIODIC; // next state
- }
+ if (!(port->partner_oper.port_state &
+ AD_STATE_LACP_TIMEOUT))
+ port->sm_periodic_state = AD_SLOW_PERIODIC;
+ else
+ port->sm_periodic_state = AD_FAST_PERIODIC;
break;
- default: //to silence the compiler
+ default:
break;
}
}
- // check if the state machine was changed
+ /* check if the state machine was changed */
if (port->sm_periodic_state != last_state) {
- dprintk("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n", port->actor_port_number, last_state, port->sm_periodic_state);
+ pr_debug("Periodic Machine: Port=%d, Last State=%d, Curr State=%d\n",
+ port->actor_port_number, last_state,
+ port->sm_periodic_state);
switch (port->sm_periodic_state) {
case AD_NO_PERIODIC:
- port->sm_periodic_timer_counter = 0; // zero timer
+ port->sm_periodic_timer_counter = 0;
break;
case AD_FAST_PERIODIC:
- port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_FAST_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle
+ /* decrement 1 tick we lost in the PERIODIC_TX cycle */
+ port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_FAST_PERIODIC_TIME))-1;
break;
case AD_SLOW_PERIODIC:
- port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_SLOW_PERIODIC_TIME))-1; // decrement 1 tick we lost in the PERIODIC_TX cycle
+ /* decrement 1 tick we lost in the PERIODIC_TX cycle */
+ port->sm_periodic_timer_counter = __ad_timer_to_ticks(AD_PERIODIC_TIMER, (u16)(AD_SLOW_PERIODIC_TIME))-1;
break;
case AD_PERIODIC_TX:
- port->ntt = 1;
+ port->ntt = true;
break;
- default: //to silence the compiler
+ default:
break;
}
}
@@ -1298,125 +1228,241 @@ static void ad_port_selection_logic(struct port *port)
{
struct aggregator *aggregator, *free_aggregator = NULL, *temp_aggregator;
struct port *last_port = NULL, *curr_port;
+ struct list_head *iter;
+ struct bonding *bond;
+ struct slave *slave;
int found = 0;
- // if the port is already Selected, do nothing
- if (port->sm_vars & AD_PORT_SELECTED) {
+ /* if the port is already Selected, do nothing */
+ if (port->sm_vars & AD_PORT_SELECTED)
return;
- }
- // if the port is connected to other aggregator, detach it
+ bond = __get_bond_by_port(port);
+
+ /* if the port is connected to other aggregator, detach it */
if (port->aggregator) {
- // detach the port from its former aggregator
- temp_aggregator=port->aggregator;
- for (curr_port=temp_aggregator->lag_ports; curr_port; last_port=curr_port, curr_port=curr_port->next_port_in_aggregator) {
+ /* detach the port from its former aggregator */
+ temp_aggregator = port->aggregator;
+ for (curr_port = temp_aggregator->lag_ports; curr_port;
+ last_port = curr_port,
+ curr_port = curr_port->next_port_in_aggregator) {
if (curr_port == port) {
temp_aggregator->num_of_ports--;
- if (!last_port) {// if it is the first port attached to the aggregator
- temp_aggregator->lag_ports=port->next_port_in_aggregator;
- } else {// not the first port attached to the aggregator
- last_port->next_port_in_aggregator=port->next_port_in_aggregator;
+ /* if it is the first port attached to the
+ * aggregator
+ */
+ if (!last_port) {
+ temp_aggregator->lag_ports =
+ port->next_port_in_aggregator;
+ } else {
+ /* not the first port attached to the
+ * aggregator
+ */
+ last_port->next_port_in_aggregator =
+ port->next_port_in_aggregator;
}
- // clear the port's relations to this aggregator
+ /* clear the port's relations to this
+ * aggregator
+ */
port->aggregator = NULL;
- port->next_port_in_aggregator=NULL;
- port->actor_port_aggregator_identifier=0;
-
- dprintk("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier);
- // if the aggregator is empty, clear its parameters, and set it ready to be attached
- if (!temp_aggregator->lag_ports) {
+ port->next_port_in_aggregator = NULL;
+ port->actor_port_aggregator_identifier = 0;
+
+ pr_debug("Port %d left LAG %d\n",
+ port->actor_port_number,
+ temp_aggregator->aggregator_identifier);
+ /* if the aggregator is empty, clear its
+ * parameters, and set it ready to be attached
+ */
+ if (!temp_aggregator->lag_ports)
ad_clear_agg(temp_aggregator);
- }
break;
}
}
- if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
- printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
- "related to aggregator %d but was not on its port list\n",
- port->slave->dev->master->name,
- port->actor_port_number, port->slave->dev->name,
- port->aggregator->aggregator_identifier);
+ if (!curr_port) {
+ /* meaning: the port was related to an aggregator
+ * but was not on the aggregator port list
+ */
+ pr_warn_ratelimited("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n",
+ port->slave->bond->dev->name,
+ port->actor_port_number,
+ port->slave->dev->name,
+ port->aggregator->aggregator_identifier);
}
}
- // search on all aggregators for a suitable aggregator for this port
- for (aggregator = __get_first_agg(port); aggregator;
- aggregator = __get_next_agg(aggregator)) {
+ /* search on all aggregators for a suitable aggregator for this port */
+ bond_for_each_slave(bond, slave, iter) {
+ aggregator = &(SLAVE_AD_INFO(slave)->aggregator);
- // keep a free aggregator for later use(if needed)
+ /* keep a free aggregator for later use(if needed) */
if (!aggregator->lag_ports) {
- if (!free_aggregator) {
- free_aggregator=aggregator;
- }
+ if (!free_aggregator)
+ free_aggregator = aggregator;
continue;
}
- // check if current aggregator suits us
- if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) && // if all parameters match AND
- !MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(port->partner_oper_system)) &&
- (aggregator->partner_system_priority == port->partner_oper_system_priority) &&
- (aggregator->partner_oper_aggregator_key == port->partner_oper_key)
+ /* check if current aggregator suits us */
+ if (((aggregator->actor_oper_aggregator_key == port->actor_oper_port_key) && /* if all parameters match AND */
+ MAC_ADDRESS_EQUAL(&(aggregator->partner_system), &(port->partner_oper.system)) &&
+ (aggregator->partner_system_priority == port->partner_oper.system_priority) &&
+ (aggregator->partner_oper_aggregator_key == port->partner_oper.key)
) &&
- ((MAC_ADDRESS_COMPARE(&(port->partner_oper_system), &(null_mac_addr)) && // partner answers
- !aggregator->is_individual) // but is not individual OR
+ ((!MAC_ADDRESS_EQUAL(&(port->partner_oper.system), &(null_mac_addr)) && /* partner answers */
+ !aggregator->is_individual) /* but is not individual OR */
)
) {
- // attach to the founded aggregator
+ /* attach to the founded aggregator */
port->aggregator = aggregator;
- port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier;
- port->next_port_in_aggregator=aggregator->lag_ports;
+ port->actor_port_aggregator_identifier =
+ port->aggregator->aggregator_identifier;
+ port->next_port_in_aggregator = aggregator->lag_ports;
port->aggregator->num_of_ports++;
- aggregator->lag_ports=port;
- dprintk("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+ aggregator->lag_ports = port;
+ pr_debug("Port %d joined LAG %d(existing LAG)\n",
+ port->actor_port_number,
+ port->aggregator->aggregator_identifier);
- // mark this port as selected
+ /* mark this port as selected */
port->sm_vars |= AD_PORT_SELECTED;
found = 1;
break;
}
}
- // the port couldn't find an aggregator - attach it to a new aggregator
+ /* the port couldn't find an aggregator - attach it to a new
+ * aggregator
+ */
if (!found) {
if (free_aggregator) {
- // assign port a new aggregator
+ /* assign port a new aggregator */
port->aggregator = free_aggregator;
- port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier;
-
- // update the new aggregator's parameters
- // if port was responsed from the end-user
- if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) {// if port is full duplex
- port->aggregator->is_individual = 0;
- } else {
- port->aggregator->is_individual = 1;
- }
+ port->actor_port_aggregator_identifier =
+ port->aggregator->aggregator_identifier;
+
+ /* update the new aggregator's parameters
+ * if port was responsed from the end-user
+ */
+ if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)
+ /* if port is full duplex */
+ port->aggregator->is_individual = false;
+ else
+ port->aggregator->is_individual = true;
port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key;
port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key;
- port->aggregator->partner_system=port->partner_oper_system;
- port->aggregator->partner_system_priority = port->partner_oper_system_priority;
- port->aggregator->partner_oper_aggregator_key = port->partner_oper_key;
+ port->aggregator->partner_system =
+ port->partner_oper.system;
+ port->aggregator->partner_system_priority =
+ port->partner_oper.system_priority;
+ port->aggregator->partner_oper_aggregator_key = port->partner_oper.key;
port->aggregator->receive_state = 1;
port->aggregator->transmit_state = 1;
port->aggregator->lag_ports = port;
port->aggregator->num_of_ports++;
- // mark this port as selected
+ /* mark this port as selected */
port->sm_vars |= AD_PORT_SELECTED;
- dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+ pr_debug("Port %d joined LAG %d(new LAG)\n",
+ port->actor_port_number,
+ port->aggregator->aggregator_identifier);
} else {
- printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
- port->slave->dev->master->name,
+ pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n",
+ port->slave->bond->dev->name,
port->actor_port_number, port->slave->dev->name);
}
}
- // if all aggregator's ports are READY_N == TRUE, set ready=TRUE in all aggregator's ports
- // else set ready=FALSE in all aggregator's ports
- __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
+ /* if all aggregator's ports are READY_N == TRUE, set ready=TRUE
+ * in all aggregator's ports, else set ready=FALSE in all
+ * aggregator's ports
+ */
+ __set_agg_ports_ready(port->aggregator,
+ __agg_ports_are_ready(port->aggregator));
+
+ aggregator = __get_first_agg(port);
+ ad_agg_selection_logic(aggregator);
+}
- if (!__check_agg_selection_timer(port) && (aggregator = __get_first_agg(port))) {
- ad_agg_selection_logic(aggregator);
+/* Decide if "agg" is a better choice for the new active aggregator that
+ * the current best, according to the ad_select policy.
+ */
+static struct aggregator *ad_agg_selection_test(struct aggregator *best,
+ struct aggregator *curr)
+{
+ /* 0. If no best, select current.
+ *
+ * 1. If the current agg is not individual, and the best is
+ * individual, select current.
+ *
+ * 2. If current agg is individual and the best is not, keep best.
+ *
+ * 3. Therefore, current and best are both individual or both not
+ * individual, so:
+ *
+ * 3a. If current agg partner replied, and best agg partner did not,
+ * select current.
+ *
+ * 3b. If current agg partner did not reply and best agg partner
+ * did reply, keep best.
+ *
+ * 4. Therefore, current and best both have partner replies or
+ * both do not, so perform selection policy:
+ *
+ * BOND_AD_COUNT: Select by count of ports. If count is equal,
+ * select by bandwidth.
+ *
+ * BOND_AD_STABLE, BOND_AD_BANDWIDTH: Select by bandwidth.
+ */
+ if (!best)
+ return curr;
+
+ if (!curr->is_individual && best->is_individual)
+ return curr;
+
+ if (curr->is_individual && !best->is_individual)
+ return best;
+
+ if (__agg_has_partner(curr) && !__agg_has_partner(best))
+ return curr;
+
+ if (!__agg_has_partner(curr) && __agg_has_partner(best))
+ return best;
+
+ switch (__get_agg_selection_mode(curr->lag_ports)) {
+ case BOND_AD_COUNT:
+ if (curr->num_of_ports > best->num_of_ports)
+ return curr;
+
+ if (curr->num_of_ports < best->num_of_ports)
+ return best;
+
+ /*FALLTHROUGH*/
+ case BOND_AD_STABLE:
+ case BOND_AD_BANDWIDTH:
+ if (__get_agg_bandwidth(curr) > __get_agg_bandwidth(best))
+ return curr;
+
+ break;
+
+ default:
+ pr_warn_ratelimited("%s: Impossible agg select mode %d\n",
+ curr->slave->bond->dev->name,
+ __get_agg_selection_mode(curr->lag_ports));
+ break;
}
+
+ return best;
+}
+
+static int agg_device_up(const struct aggregator *agg)
+{
+ struct port *port = agg->lag_ports;
+
+ if (!port)
+ return 0;
+
+ return netif_running(port->slave->dev) &&
+ netif_carrier_ok(port->slave->dev);
}
/**
@@ -1424,167 +1470,148 @@ static void ad_port_selection_logic(struct port *port)
* @aggregator: the aggregator we're looking at
*
* It is assumed that only one aggregator may be selected for a team.
- * The logic of this function is to select (at first time) the aggregator with
- * the most ports attached to it, and to reselect the active aggregator only if
- * the previous aggregator has no more ports related to it.
+ *
+ * The logic of this function is to select the aggregator according to
+ * the ad_select policy:
+ *
+ * BOND_AD_STABLE: select the aggregator with the most ports attached to
+ * it, and to reselect the active aggregator only if the previous
+ * aggregator has no more ports related to it.
+ *
+ * BOND_AD_BANDWIDTH: select the aggregator with the highest total
+ * bandwidth, and reselect whenever a link state change takes place or the
+ * set of slaves in the bond changes.
+ *
+ * BOND_AD_COUNT: select the aggregator with largest number of ports
+ * (slaves), and reselect whenever a link state change takes place or the
+ * set of slaves in the bond changes.
*
* FIXME: this function MUST be called with the first agg in the bond, or
* __get_active_agg() won't work correctly. This function should be better
* called with the bond itself, and retrieve the first agg from it.
*/
-static void ad_agg_selection_logic(struct aggregator *aggregator)
+static void ad_agg_selection_logic(struct aggregator *agg)
{
- struct aggregator *best_aggregator = NULL, *active_aggregator = NULL;
- struct aggregator *last_active_aggregator = NULL, *origin_aggregator;
+ struct aggregator *best, *active, *origin;
+ struct bonding *bond = agg->slave->bond;
+ struct list_head *iter;
+ struct slave *slave;
struct port *port;
- u16 num_of_aggs=0;
-
- origin_aggregator = aggregator;
-
- //get current active aggregator
- last_active_aggregator = __get_active_agg(aggregator);
- // search for the aggregator with the most ports attached to it.
- do {
- // count how many candidate lag's we have
- if (aggregator->lag_ports) {
- num_of_aggs++;
- }
- if (aggregator->is_active && !aggregator->is_individual && // if current aggregator is the active aggregator
- MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr))) { // and partner answers to 802.3ad PDUs
- if (aggregator->num_of_ports) { // if any ports attached to the current aggregator
- best_aggregator=NULL; // disregard the best aggregator that was chosen by now
- break; // stop the selection of other aggregator if there are any ports attached to this active aggregator
- } else { // no ports attached to this active aggregator
- aggregator->is_active = 0; // mark this aggregator as not active anymore
- }
- }
- if (aggregator->num_of_ports) { // if any ports attached
- if (best_aggregator) { // if there is a candidte aggregator
- //The reasons for choosing new best aggregator:
- // 1. if current agg is NOT individual and the best agg chosen so far is individual OR
- // current and best aggs are both individual or both not individual, AND
- // 2a. current agg partner reply but best agg partner do not reply OR
- // 2b. current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply AND
- // current has more ports/bandwidth, or same amount of ports but current has faster ports, THEN
- // current agg become best agg so far
-
- //if current agg is NOT individual and the best agg chosen so far is individual change best_aggregator
- if (!aggregator->is_individual && best_aggregator->is_individual) {
- best_aggregator=aggregator;
- }
- // current and best aggs are both individual or both not individual
- else if ((aggregator->is_individual && best_aggregator->is_individual) ||
- (!aggregator->is_individual && !best_aggregator->is_individual)) {
- // current and best aggs are both individual or both not individual AND
- // current agg partner reply but best agg partner do not reply
- if ((MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) &&
- !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) {
- best_aggregator=aggregator;
- }
- // current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply
- else if (! (!MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) &&
- MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) {
- if ((__get_agg_selection_mode(aggregator->lag_ports) == AD_BANDWIDTH)&&
- (__get_agg_bandwidth(aggregator) > __get_agg_bandwidth(best_aggregator))) {
- best_aggregator=aggregator;
- } else if (__get_agg_selection_mode(aggregator->lag_ports) == AD_COUNT) {
- if (((aggregator->num_of_ports > best_aggregator->num_of_ports) &&
- (aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS))||
- ((aggregator->num_of_ports == best_aggregator->num_of_ports) &&
- ((u16)(aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS) >
- (u16)(best_aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS)))) {
- best_aggregator=aggregator;
- }
- }
- }
- }
- } else {
- best_aggregator=aggregator;
+ rcu_read_lock();
+ origin = agg;
+ active = __get_active_agg(agg);
+ best = (active && agg_device_up(active)) ? active : NULL;
+
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ agg = &(SLAVE_AD_INFO(slave)->aggregator);
+
+ agg->is_active = 0;
+
+ if (agg->num_of_ports && agg_device_up(agg))
+ best = ad_agg_selection_test(best, agg);
+ }
+
+ if (best &&
+ __get_agg_selection_mode(best->lag_ports) == BOND_AD_STABLE) {
+ /* For the STABLE policy, don't replace the old active
+ * aggregator if it's still active (it has an answering
+ * partner) or if both the best and active don't have an
+ * answering partner.
+ */
+ if (active && active->lag_ports &&
+ active->lag_ports->is_enabled &&
+ (__agg_has_partner(active) ||
+ (!__agg_has_partner(active) &&
+ !__agg_has_partner(best)))) {
+ if (!(!active->actor_oper_aggregator_key &&
+ best->actor_oper_aggregator_key)) {
+ best = NULL;
+ active->is_active = 1;
}
}
- aggregator->is_active = 0; // mark all aggregators as not active anymore
- } while ((aggregator = __get_next_agg(aggregator)));
-
- // if we have new aggregator selected, don't replace the old aggregator if it has an answering partner,
- // or if both old aggregator and new aggregator don't have answering partner
- if (best_aggregator) {
- if (last_active_aggregator && last_active_aggregator->lag_ports && last_active_aggregator->lag_ports->is_enabled &&
- (MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) || // partner answers OR
- (!MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) && // both old and new
- !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) // partner do not answer
- ) {
- // if new aggregator has link, and old aggregator does not, replace old aggregator.(do nothing)
- // -> don't replace otherwise.
- if (!(!last_active_aggregator->actor_oper_aggregator_key && best_aggregator->actor_oper_aggregator_key)) {
- best_aggregator=NULL;
- last_active_aggregator->is_active = 1; // don't replace good old aggregator
+ }
- }
- }
+ if (best && (best == active)) {
+ best = NULL;
+ active->is_active = 1;
}
- // if there is new best aggregator, activate it
- if (best_aggregator) {
- for (aggregator = __get_first_agg(best_aggregator->lag_ports);
- aggregator;
- aggregator = __get_next_agg(aggregator)) {
+ /* if there is new best aggregator, activate it */
+ if (best) {
+ pr_debug("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+ best->aggregator_identifier, best->num_of_ports,
+ best->actor_oper_aggregator_key,
+ best->partner_oper_aggregator_key,
+ best->is_individual, best->is_active);
+ pr_debug("best ports %p slave %p %s\n",
+ best->lag_ports, best->slave,
+ best->slave ? best->slave->dev->name : "NULL");
- dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
- aggregator->aggregator_identifier, aggregator->num_of_ports,
- aggregator->actor_oper_aggregator_key, aggregator->partner_oper_aggregator_key,
- aggregator->is_individual, aggregator->is_active);
- }
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ agg = &(SLAVE_AD_INFO(slave)->aggregator);
- // check if any partner replys
- if (best_aggregator->is_individual) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
- "the link partner for any adapters in the bond\n",
- best_aggregator->slave->dev->master->name);
+ pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+ agg->aggregator_identifier, agg->num_of_ports,
+ agg->actor_oper_aggregator_key,
+ agg->partner_oper_aggregator_key,
+ agg->is_individual, agg->is_active);
}
- // check if there are more than one aggregator
- if (num_of_aggs > 1) {
- dprintk("Warning: More than one Link Aggregation Group was "
- "found in the bond. Only one group will function in the bond\n");
+ /* check if any partner replys */
+ if (best->is_individual) {
+ pr_warn_ratelimited("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n",
+ best->slave ?
+ best->slave->bond->dev->name : "NULL");
}
- best_aggregator->is_active = 1;
- dprintk("LAG %d choosed as the active LAG\n", best_aggregator->aggregator_identifier);
- dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
- best_aggregator->aggregator_identifier, best_aggregator->num_of_ports,
- best_aggregator->actor_oper_aggregator_key, best_aggregator->partner_oper_aggregator_key,
- best_aggregator->is_individual, best_aggregator->is_active);
-
- // disable the ports that were related to the former active_aggregator
- if (last_active_aggregator) {
- for (port=last_active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
+ best->is_active = 1;
+ pr_debug("LAG %d chosen as the active LAG\n",
+ best->aggregator_identifier);
+ pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+ best->aggregator_identifier, best->num_of_ports,
+ best->actor_oper_aggregator_key,
+ best->partner_oper_aggregator_key,
+ best->is_individual, best->is_active);
+
+ /* disable the ports that were related to the former
+ * active_aggregator
+ */
+ if (active) {
+ for (port = active->lag_ports; port;
+ port = port->next_port_in_aggregator) {
__disable_port(port);
}
}
}
- // if the selected aggregator is of join individuals(partner_system is NULL), enable their ports
- active_aggregator = __get_active_agg(origin_aggregator);
+ /* if the selected aggregator is of join individuals
+ * (partner_system is NULL), enable their ports
+ */
+ active = __get_active_agg(origin);
- if (active_aggregator) {
- if (!MAC_ADDRESS_COMPARE(&(active_aggregator->partner_system), &(null_mac_addr))) {
- for (port=active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
+ if (active) {
+ if (!__agg_has_partner(active)) {
+ for (port = active->lag_ports; port;
+ port = port->next_port_in_aggregator) {
__enable_port(port);
}
}
}
+
+ rcu_read_unlock();
+
+ bond_3ad_set_carrier(bond);
}
/**
* ad_clear_agg - clear a given aggregator's parameters
* @aggregator: the aggregator we're looking at
- *
*/
static void ad_clear_agg(struct aggregator *aggregator)
{
if (aggregator) {
- aggregator->is_individual = 0;
+ aggregator->is_individual = false;
aggregator->actor_admin_aggregator_key = 0;
aggregator->actor_oper_aggregator_key = 0;
aggregator->partner_system = null_mac_addr;
@@ -1595,14 +1622,14 @@ static void ad_clear_agg(struct aggregator *aggregator)
aggregator->lag_ports = NULL;
aggregator->is_active = 0;
aggregator->num_of_ports = 0;
- dprintk("LAG %d was cleared\n", aggregator->aggregator_identifier);
+ pr_debug("LAG %d was cleared\n",
+ aggregator->aggregator_identifier);
}
}
/**
* ad_initialize_agg - initialize a given aggregator's parameters
* @aggregator: the aggregator we're looking at
- *
*/
static void ad_initialize_agg(struct aggregator *aggregator)
{
@@ -1619,40 +1646,50 @@ static void ad_initialize_agg(struct aggregator *aggregator)
* ad_initialize_port - initialize a given port's parameters
* @aggregator: the aggregator we're looking at
* @lacp_fast: boolean. whether fast periodic should be used
- *
*/
static void ad_initialize_port(struct port *port, int lacp_fast)
{
+ static const struct port_params tmpl = {
+ .system_priority = 0xffff,
+ .key = 1,
+ .port_number = 1,
+ .port_priority = 0xff,
+ .port_state = 1,
+ };
+ static const struct lacpdu lacpdu = {
+ .subtype = 0x01,
+ .version_number = 0x01,
+ .tlv_type_actor_info = 0x01,
+ .actor_information_length = 0x14,
+ .tlv_type_partner_info = 0x02,
+ .partner_information_length = 0x14,
+ .tlv_type_collector_info = 0x03,
+ .collector_information_length = 0x10,
+ .collector_max_delay = htons(AD_COLLECTOR_MAX_DELAY),
+ };
+
if (port) {
port->actor_port_number = 1;
port->actor_port_priority = 0xff;
port->actor_system = null_mac_addr;
port->actor_system_priority = 0xffff;
port->actor_port_aggregator_identifier = 0;
- port->ntt = 0;
+ port->ntt = false;
port->actor_admin_port_key = 1;
port->actor_oper_port_key = 1;
- port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
- port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY;
+ port->actor_admin_port_state = AD_STATE_AGGREGATION |
+ AD_STATE_LACP_ACTIVITY;
+ port->actor_oper_port_state = AD_STATE_AGGREGATION |
+ AD_STATE_LACP_ACTIVITY;
- if (lacp_fast) {
+ if (lacp_fast)
port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
- }
- port->partner_admin_system = null_mac_addr;
- port->partner_oper_system = null_mac_addr;
- port->partner_admin_system_priority = 0xffff;
- port->partner_oper_system_priority = 0xffff;
- port->partner_admin_key = 1;
- port->partner_oper_key = 1;
- port->partner_admin_port_number = 1;
- port->partner_oper_port_number = 1;
- port->partner_admin_port_priority = 0xff;
- port->partner_oper_port_priority = 0xff;
- port->partner_admin_port_state = 1;
- port->partner_oper_port_state = 1;
- port->is_enabled = 1;
- // ****** private parameters ******
+ memcpy(&port->partner_admin, &tmpl, sizeof(tmpl));
+ memcpy(&port->partner_oper, &tmpl, sizeof(tmpl));
+
+ port->is_enabled = true;
+ /* private parameters */
port->sm_vars = 0x3;
port->sm_rx_state = 0;
port->sm_rx_timer_counter = 0;
@@ -1667,7 +1704,7 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
port->next_port_in_aggregator = NULL;
port->transaction_id = 0;
- ad_initialize_lacpdu(&(port->lacpdu));
+ memcpy(&port->lacpdu, &lacpdu, sizeof(lacpdu));
}
}
@@ -1680,7 +1717,9 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
static void ad_enable_collecting_distributing(struct port *port)
{
if (port->aggregator->is_active) {
- dprintk("Enabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+ pr_debug("Enabling port %d(LAG %d)\n",
+ port->actor_port_number,
+ port->aggregator->aggregator_identifier);
__enable_port(port);
}
}
@@ -1688,74 +1727,38 @@ static void ad_enable_collecting_distributing(struct port *port)
/**
* ad_disable_collecting_distributing - disable a port's transmit/receive
* @port: the port we're looking at
- *
*/
static void ad_disable_collecting_distributing(struct port *port)
{
- if (port->aggregator && MAC_ADDRESS_COMPARE(&(port->aggregator->partner_system), &(null_mac_addr))) {
- dprintk("Disabling port %d(LAG %d)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
+ if (port->aggregator &&
+ !MAC_ADDRESS_EQUAL(&(port->aggregator->partner_system),
+ &(null_mac_addr))) {
+ pr_debug("Disabling port %d(LAG %d)\n",
+ port->actor_port_number,
+ port->aggregator->aggregator_identifier);
__disable_port(port);
}
}
-#if 0
-/**
- * ad_marker_info_send - send a marker information frame
- * @port: the port we're looking at
- *
- * This function does nothing since we decided not to implement send and handle
- * response for marker PDU's, in this stage, but only to respond to marker
- * information.
- */
-static void ad_marker_info_send(struct port *port)
-{
- struct bond_marker marker;
- u16 index;
-
- // fill the marker PDU with the appropriate values
- marker.subtype = 0x02;
- marker.version_number = 0x01;
- marker.tlv_type = AD_MARKER_INFORMATION_SUBTYPE;
- marker.marker_length = 0x16;
- // convert requester_port to Big Endian
- marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8));
- marker.requester_system = port->actor_system;
- // convert requester_port(u32) to Big Endian
- marker.requester_transaction_id = (((++port->transaction_id & 0xFF) << 24) |((port->transaction_id & 0xFF00) << 8) |((port->transaction_id & 0xFF0000) >> 8) |((port->transaction_id & 0xFF000000) >> 24));
- marker.pad = 0;
- marker.tlv_type_terminator = 0x00;
- marker.terminator_length = 0x00;
- for (index=0; index<90; index++) {
- marker.reserved_90[index]=0;
- }
-
- // send the marker information
- if (ad_marker_send(port, &marker) >= 0) {
- dprintk("Sent Marker Information on port %d\n", port->actor_port_number);
- }
-}
-#endif
-
/**
* ad_marker_info_received - handle receive of a Marker information frame
* @marker_info: Marker info received
* @port: the port we're looking at
- *
*/
static void ad_marker_info_received(struct bond_marker *marker_info,
struct port *port)
{
struct bond_marker marker;
- // copy the received marker data to the response marker
- //marker = *marker_info;
+ /* copy the received marker data to the response marker */
memcpy(&marker, marker_info, sizeof(struct bond_marker));
- // change the marker subtype to marker response
- marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE;
- // send the marker response
+ /* change the marker subtype to marker response */
+ marker.tlv_type = AD_MARKER_RESPONSE_SUBTYPE;
+ /* send the marker response */
if (ad_marker_send(port, &marker) >= 0) {
- dprintk("Sent Marker Response on port %d\n", port->actor_port_number);
+ pr_debug("Sent Marker Response on port %d\n",
+ port->actor_port_number);
}
}
@@ -1769,94 +1772,57 @@ static void ad_marker_info_received(struct bond_marker *marker_info,
* information.
*/
static void ad_marker_response_received(struct bond_marker *marker,
- struct port *port)
+ struct port *port)
{
- marker=NULL; // just to satisfy the compiler
- port=NULL; // just to satisfy the compiler
- // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW
+ marker = NULL;
+ port = NULL;
+ /* DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW */
}
+/* ========= AD exported functions to the main bonding code ========= */
+
+/* Check aggregators status in team every T seconds */
+#define AD_AGGREGATOR_SELECTION_TIMER 8
+
/**
- * ad_initialize_lacpdu - initialize a given lacpdu structure
- * @lacpdu: lacpdu structure to initialize
+ * bond_3ad_initiate_agg_selection - initate aggregator selection
+ * @bond: bonding struct
*
+ * Set the aggregation selection timer, to initiate an agg selection in
+ * the very near future. Called during first initialization, and during
+ * any down to up transitions of the bond.
*/
-static void ad_initialize_lacpdu(struct lacpdu *lacpdu)
+void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout)
{
- u16 index;
-
- // initialize lacpdu data
- lacpdu->subtype = 0x01;
- lacpdu->version_number = 0x01;
- lacpdu->tlv_type_actor_info = 0x01;
- lacpdu->actor_information_length = 0x14;
- // lacpdu->actor_system_priority updated on send
- // lacpdu->actor_system updated on send
- // lacpdu->actor_key updated on send
- // lacpdu->actor_port_priority updated on send
- // lacpdu->actor_port updated on send
- // lacpdu->actor_state updated on send
- lacpdu->tlv_type_partner_info = 0x02;
- lacpdu->partner_information_length = 0x14;
- for (index=0; index<=2; index++) {
- lacpdu->reserved_3_1[index]=0;
- }
- // lacpdu->partner_system_priority updated on send
- // lacpdu->partner_system updated on send
- // lacpdu->partner_key updated on send
- // lacpdu->partner_port_priority updated on send
- // lacpdu->partner_port updated on send
- // lacpdu->partner_state updated on send
- for (index=0; index<=2; index++) {
- lacpdu->reserved_3_2[index]=0;
- }
- lacpdu->tlv_type_collector_info = 0x03;
- lacpdu->collector_information_length= 0x10;
- lacpdu->collector_max_delay = htons(AD_COLLECTOR_MAX_DELAY);
- for (index=0; index<=11; index++) {
- lacpdu->reserved_12[index]=0;
- }
- lacpdu->tlv_type_terminator = 0x00;
- lacpdu->terminator_length = 0;
- for (index=0; index<=49; index++) {
- lacpdu->reserved_50[index]=0;
- }
+ BOND_AD_INFO(bond).agg_select_timer = timeout;
}
-//////////////////////////////////////////////////////////////////////////////////////
-// ================= AD exported functions to the main bonding code ==================
-//////////////////////////////////////////////////////////////////////////////////////
-
-// Check aggregators status in team every T seconds
-#define AD_AGGREGATOR_SELECTION_TIMER 8
-
-static u16 aggregator_identifier;
-
/**
* bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures
* @bond: bonding struct to work on
* @tick_resolution: tick duration (millisecond resolution)
- * @lacp_fast: boolean. whether fast periodic should be used
*
* Can be called only after the mac address of the bond is set.
*/
-void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
-{
- // check that the bond is not initialized yet
- if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
+void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
+{
+ /* check that the bond is not initialized yet */
+ if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr),
+ bond->dev->dev_addr)) {
- aggregator_identifier = 0;
+ BOND_AD_INFO(bond).aggregator_identifier = 0;
- BOND_AD_INFO(bond).lacp_fast = lacp_fast;
BOND_AD_INFO(bond).system.sys_priority = 0xFFFF;
BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
- // initialize how many times this module is called in one second(should be about every 100ms)
+ /* initialize how many times this module is called in one
+ * second (should be about every 100ms)
+ */
ad_ticks_per_sec = tick_resolution;
- // initialize the aggregator selection timer(to activate an aggregation selection after initialize)
- BOND_AD_INFO(bond).agg_select_timer = (AD_AGGREGATOR_SELECTION_TIMER * ad_ticks_per_sec);
- BOND_AD_INFO(bond).agg_select_mode = AD_BANDWIDTH;
+ bond_3ad_initiate_agg_selection(bond,
+ AD_AGGREGATOR_SELECTION_TIMER *
+ ad_ticks_per_sec);
}
}
@@ -1867,65 +1833,57 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fas
* Returns: 0 on success
* < 0 on error
*/
-int bond_3ad_bind_slave(struct slave *slave)
+void bond_3ad_bind_slave(struct slave *slave)
{
struct bonding *bond = bond_get_bond_by_slave(slave);
struct port *port;
struct aggregator *aggregator;
- if (bond == NULL) {
- printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
- slave->dev->master->name, slave->dev->name);
- return -1;
- }
-
- //check that the slave has not been intialized yet.
- if (SLAVE_AD_INFO(slave).port.slave != slave) {
+ /* check that the slave has not been initialized yet. */
+ if (SLAVE_AD_INFO(slave)->port.slave != slave) {
- // port initialization
- port = &(SLAVE_AD_INFO(slave).port);
+ /* port initialization */
+ port = &(SLAVE_AD_INFO(slave)->port);
- ad_initialize_port(port, BOND_AD_INFO(bond).lacp_fast);
+ ad_initialize_port(port, bond->params.lacp_fast);
+ __initialize_port_locks(slave);
port->slave = slave;
- port->actor_port_number = SLAVE_AD_INFO(slave).id;
- // key is determined according to the link speed, duplex and user key(which is yet not supported)
- // ------------------------------------------------------------
- // Port key : | User key | Speed |Duplex|
- // ------------------------------------------------------------
- // 16 6 1 0
- port->actor_admin_port_key = 0; // initialize this parameter
+ port->actor_port_number = SLAVE_AD_INFO(slave)->id;
+ /* key is determined according to the link speed, duplex and user key(which
+ * is yet not supported)
+ */
+ port->actor_admin_port_key = 0;
port->actor_admin_port_key |= __get_duplex(port);
port->actor_admin_port_key |= (__get_link_speed(port) << 1);
port->actor_oper_port_key = port->actor_admin_port_key;
- // if the port is not full duplex, then the port should be not lacp Enabled
- if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) {
+ /* if the port is not full duplex, then the port should be not
+ * lacp Enabled
+ */
+ if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS))
port->sm_vars &= ~AD_PORT_LACP_ENABLED;
- }
- // actor system is the bond's system
+ /* actor system is the bond's system */
port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
- // tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second)
+ /* tx timer(to verify that no more than MAX_TX_IN_SECOND
+ * lacpdu's are sent in one second)
+ */
port->sm_tx_timer_counter = ad_ticks_per_sec/AD_MAX_TX_IN_SECOND;
port->aggregator = NULL;
port->next_port_in_aggregator = NULL;
__disable_port(port);
- __initialize_port_locks(port);
-
- // aggregator initialization
- aggregator = &(SLAVE_AD_INFO(slave).aggregator);
+ /* aggregator initialization */
+ aggregator = &(SLAVE_AD_INFO(slave)->aggregator);
ad_initialize_agg(aggregator);
aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr);
- aggregator->aggregator_identifier = (++aggregator_identifier);
+ aggregator->aggregator_identifier = ++BOND_AD_INFO(bond).aggregator_identifier;
aggregator->slave = slave;
aggregator->is_active = 0;
aggregator->num_of_ports = 0;
}
-
- return 0;
}
/**
@@ -1941,51 +1899,64 @@ void bond_3ad_unbind_slave(struct slave *slave)
struct port *port, *prev_port, *temp_port;
struct aggregator *aggregator, *new_aggregator, *temp_aggregator;
int select_new_active_agg = 0;
-
- // find the aggregator related to this slave
- aggregator = &(SLAVE_AD_INFO(slave).aggregator);
+ struct bonding *bond = slave->bond;
+ struct slave *slave_iter;
+ struct list_head *iter;
- // find the port related to this slave
- port = &(SLAVE_AD_INFO(slave).port);
+ aggregator = &(SLAVE_AD_INFO(slave)->aggregator);
+ port = &(SLAVE_AD_INFO(slave)->port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
- "unbind an uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ pr_warn("Warning: %s: Trying to unbind an uninitialized port on %s\n",
+ slave->bond->dev->name, slave->dev->name);
return;
}
- dprintk("Unbinding Link Aggregation Group %d\n", aggregator->aggregator_identifier);
+ pr_debug("Unbinding Link Aggregation Group %d\n",
+ aggregator->aggregator_identifier);
/* Tell the partner that this port is not suitable for aggregation */
port->actor_oper_port_state &= ~AD_STATE_AGGREGATION;
__update_lacpdu_from_port(port);
ad_lacpdu_send(port);
- // check if this aggregator is occupied
+ /* check if this aggregator is occupied */
if (aggregator->lag_ports) {
- // check if there are other ports related to this aggregator except
- // the port related to this slave(thats ensure us that there is a
- // reason to search for new aggregator, and that we will find one
- if ((aggregator->lag_ports != port) || (aggregator->lag_ports->next_port_in_aggregator)) {
- // find new aggregator for the related port(s)
- new_aggregator = __get_first_agg(port);
- for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) {
- // if the new aggregator is empty, or it connected to to our port only
- if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) {
+ /* check if there are other ports related to this aggregator
+ * except the port related to this slave(thats ensure us that
+ * there is a reason to search for new aggregator, and that we
+ * will find one
+ */
+ if ((aggregator->lag_ports != port) ||
+ (aggregator->lag_ports->next_port_in_aggregator)) {
+ /* find new aggregator for the related port(s) */
+ bond_for_each_slave(bond, slave_iter, iter) {
+ new_aggregator = &(SLAVE_AD_INFO(slave_iter)->aggregator);
+ /* if the new aggregator is empty, or it is
+ * connected to our port only
+ */
+ if (!new_aggregator->lag_ports ||
+ ((new_aggregator->lag_ports == port) &&
+ !new_aggregator->lag_ports->next_port_in_aggregator))
break;
- }
}
- // if new aggregator found, copy the aggregator's parameters
- // and connect the related lag_ports to the new aggregator
- if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
- dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
+ if (!slave_iter)
+ new_aggregator = NULL;
- if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
- printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
- aggregator->slave->dev->master->name);
- // select new active aggregator
+ /* if new aggregator found, copy the aggregator's
+ * parameters and connect the related lag_ports to the
+ * new aggregator
+ */
+ if ((new_aggregator) && ((!new_aggregator->lag_ports) || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator))) {
+ pr_debug("Some port(s) related to LAG %d - replacing with LAG %d\n",
+ aggregator->aggregator_identifier,
+ new_aggregator->aggregator_identifier);
+
+ if ((new_aggregator->lag_ports == port) &&
+ new_aggregator->is_active) {
+ pr_info("%s: Removing an active aggregator\n",
+ aggregator->slave->bond->dev->name);
select_new_active_agg = 1;
}
@@ -2001,58 +1972,66 @@ void bond_3ad_unbind_slave(struct slave *slave)
new_aggregator->is_active = aggregator->is_active;
new_aggregator->num_of_ports = aggregator->num_of_ports;
- // update the information that is written on the ports about the aggregator
- for (temp_port=aggregator->lag_ports; temp_port; temp_port=temp_port->next_port_in_aggregator) {
- temp_port->aggregator=new_aggregator;
+ /* update the information that is written on
+ * the ports about the aggregator
+ */
+ for (temp_port = aggregator->lag_ports; temp_port;
+ temp_port = temp_port->next_port_in_aggregator) {
+ temp_port->aggregator = new_aggregator;
temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier;
}
- // clear the aggregator
ad_clear_agg(aggregator);
-
- if (select_new_active_agg) {
+
+ if (select_new_active_agg)
ad_agg_selection_logic(__get_first_agg(port));
- }
} else {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
- "and could not find a new aggregator for its ports\n",
- slave->dev->master->name);
+ pr_warn("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n",
+ slave->bond->dev->name);
}
- } else { // in case that the only port related to this aggregator is the one we want to remove
+ } else {
+ /* in case that the only port related to this
+ * aggregator is the one we want to remove
+ */
select_new_active_agg = aggregator->is_active;
- // clear the aggregator
ad_clear_agg(aggregator);
if (select_new_active_agg) {
- printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
- slave->dev->master->name);
- // select new active aggregator
- ad_agg_selection_logic(__get_first_agg(port));
+ pr_info("%s: Removing an active aggregator\n",
+ slave->bond->dev->name);
+ /* select new active aggregator */
+ temp_aggregator = __get_first_agg(port);
+ if (temp_aggregator)
+ ad_agg_selection_logic(temp_aggregator);
}
}
}
- dprintk("Unbinding port %d\n", port->actor_port_number);
- // find the aggregator that this port is connected to
- temp_aggregator = __get_first_agg(port);
- for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) {
+ pr_debug("Unbinding port %d\n", port->actor_port_number);
+
+ /* find the aggregator that this port is connected to */
+ bond_for_each_slave(bond, slave_iter, iter) {
+ temp_aggregator = &(SLAVE_AD_INFO(slave_iter)->aggregator);
prev_port = NULL;
- // search the port in the aggregator's related ports
- for (temp_port=temp_aggregator->lag_ports; temp_port; prev_port=temp_port, temp_port=temp_port->next_port_in_aggregator) {
- if (temp_port == port) { // the aggregator found - detach the port from this aggregator
- if (prev_port) {
+ /* search the port in the aggregator's related ports */
+ for (temp_port = temp_aggregator->lag_ports; temp_port;
+ prev_port = temp_port,
+ temp_port = temp_port->next_port_in_aggregator) {
+ if (temp_port == port) {
+ /* the aggregator found - detach the port from
+ * this aggregator
+ */
+ if (prev_port)
prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator;
- } else {
+ else
temp_aggregator->lag_ports = temp_port->next_port_in_aggregator;
- }
temp_aggregator->num_of_ports--;
- if (temp_aggregator->num_of_ports==0) {
+ if (temp_aggregator->num_of_ports == 0) {
select_new_active_agg = temp_aggregator->is_active;
- // clear the aggregator
ad_clear_agg(temp_aggregator);
if (select_new_active_agg) {
- printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
- slave->dev->master->name);
- // select new active aggregator
+ pr_info("%s: Removing an active aggregator\n",
+ slave->bond->dev->name);
+ /* select new active aggregator */
ad_agg_selection_logic(__get_first_agg(port));
}
}
@@ -2060,7 +2039,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
}
}
}
- port->slave=NULL;
+ port->slave = NULL;
}
/**
@@ -2080,27 +2059,30 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
ad_work.work);
- struct port *port;
struct aggregator *aggregator;
+ struct list_head *iter;
+ struct slave *slave;
+ struct port *port;
+ bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER;
read_lock(&bond->lock);
+ rcu_read_lock();
- if (bond->kill_timers) {
- goto out;
- }
-
- //check if there are any slaves
- if (bond->slave_cnt == 0) {
+ /* check if there are any slaves */
+ if (!bond_has_slaves(bond))
goto re_arm;
- }
- // check if agg_select_timer timer after initialize is timed out
- if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) {
- // select the active aggregator for the bond
- if ((port = __get_first_port(bond))) {
+ /* check if agg_select_timer timer after initialize is timed out */
+ if (BOND_AD_INFO(bond).agg_select_timer &&
+ !(--BOND_AD_INFO(bond).agg_select_timer)) {
+ slave = bond_first_slave_rcu(bond);
+ port = slave ? &(SLAVE_AD_INFO(slave)->port) : NULL;
+
+ /* select the active aggregator for the bond */
+ if (port) {
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
- "uninitialized\n", bond->dev->name);
+ pr_warn_ratelimited("%s: Warning: bond's first port is uninitialized\n",
+ bond->dev->name);
goto re_arm;
}
@@ -2110,30 +2092,49 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
bond_3ad_set_carrier(bond);
}
- // for each port run the state machines
- for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
+ /* for each port run the state machines */
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ port = &(SLAVE_AD_INFO(slave)->port);
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
- "port\n", bond->dev->name);
+ pr_warn_ratelimited("%s: Warning: Found an uninitialized port\n",
+ bond->dev->name);
goto re_arm;
}
+ /* Lock around state machines to protect data accessed
+ * by all (e.g., port->sm_vars). ad_rx_machine may run
+ * concurrently due to incoming LACPDU.
+ */
+ __get_state_machine_lock(port);
+
ad_rx_machine(NULL, port);
ad_periodic_machine(port);
ad_port_selection_logic(port);
ad_mux_machine(port);
ad_tx_machine(port);
- // turn off the BEGIN bit, since we already handled it
- if (port->sm_vars & AD_PORT_BEGIN) {
+ /* turn off the BEGIN bit, since we already handled it */
+ if (port->sm_vars & AD_PORT_BEGIN)
port->sm_vars &= ~AD_PORT_BEGIN;
- }
+
+ __release_state_machine_lock(port);
}
re_arm:
- queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks);
-out:
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (slave->should_notify) {
+ should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW;
+ break;
+ }
+ }
+ rcu_read_unlock();
read_unlock(&bond->lock);
+
+ if (should_notify_rtnl && rtnl_trylock()) {
+ bond_slave_state_notify(bond);
+ rtnl_unlock();
+ }
+ queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks);
}
/**
@@ -2146,45 +2147,59 @@ out:
* received frames (loopback). Since only the payload is given to this
* function, it check for loopback.
*/
-static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
+static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave,
+ u16 length)
{
struct port *port;
+ int ret = RX_HANDLER_ANOTHER;
if (length >= sizeof(struct lacpdu)) {
- port = &(SLAVE_AD_INFO(slave).port);
+ port = &(SLAVE_AD_INFO(slave)->port);
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
- "uninitialized\n", slave->dev->name, slave->dev->master->name);
- return;
+ pr_warn_ratelimited("%s: Warning: port of slave %s is uninitialized\n",
+ slave->dev->name, slave->bond->dev->name);
+ return ret;
}
switch (lacpdu->subtype) {
case AD_TYPE_LACPDU:
- dprintk("Received LACPDU on port %d\n", port->actor_port_number);
+ ret = RX_HANDLER_CONSUMED;
+ pr_debug("Received LACPDU on port %d\n",
+ port->actor_port_number);
+ /* Protect against concurrent state machines */
+ __get_state_machine_lock(port);
ad_rx_machine(lacpdu, port);
+ __release_state_machine_lock(port);
break;
case AD_TYPE_MARKER:
- // No need to convert fields to Little Endian since we don't use the marker's fields.
+ ret = RX_HANDLER_CONSUMED;
+ /* No need to convert fields to Little Endian since we
+ * don't use the marker's fields.
+ */
switch (((struct bond_marker *)lacpdu)->tlv_type) {
case AD_MARKER_INFORMATION_SUBTYPE:
- dprintk("Received Marker Information on port %d\n", port->actor_port_number);
+ pr_debug("Received Marker Information on port %d\n",
+ port->actor_port_number);
ad_marker_info_received((struct bond_marker *)lacpdu, port);
break;
case AD_MARKER_RESPONSE_SUBTYPE:
- dprintk("Received Marker Response on port %d\n", port->actor_port_number);
+ pr_debug("Received Marker Response on port %d\n",
+ port->actor_port_number);
ad_marker_response_received((struct bond_marker *)lacpdu, port);
break;
default:
- dprintk("Received an unknown Marker subtype on slot %d\n", port->actor_port_number);
+ pr_debug("Received an unknown Marker subtype on slot %d\n",
+ port->actor_port_number);
}
}
}
+ return ret;
}
/**
@@ -2197,22 +2212,27 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
{
struct port *port;
- port = &(SLAVE_AD_INFO(slave).port);
+ port = &(SLAVE_AD_INFO(slave)->port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
- "changed for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ pr_warn("Warning: %s: speed changed for uninitialized port on %s\n",
+ slave->bond->dev->name, slave->dev->name);
return;
}
+ __get_state_machine_lock(port);
+
port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
- dprintk("Port %d changed speed\n", port->actor_port_number);
- // there is no need to reselect a new aggregator, just signal the
- // state machines to reinitialize
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ (__get_link_speed(port) << 1);
+ pr_debug("Port %d changed speed\n", port->actor_port_number);
+ /* there is no need to reselect a new aggregator, just signal the
+ * state machines to reinitialize
+ */
port->sm_vars |= AD_PORT_BEGIN;
+
+ __release_state_machine_lock(port);
}
/**
@@ -2225,22 +2245,27 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
{
struct port *port;
- port=&(SLAVE_AD_INFO(slave).port);
+ port = &(SLAVE_AD_INFO(slave)->port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
- "for uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ pr_warn("%s: Warning: duplex changed for uninitialized port on %s\n",
+ slave->bond->dev->name, slave->dev->name);
return;
}
+ __get_state_machine_lock(port);
+
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
- dprintk("Port %d changed duplex\n", port->actor_port_number);
- // there is no need to reselect a new aggregator, just signal the
- // state machines to reinitialize
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ __get_duplex(port);
+ pr_debug("Port %d changed duplex\n", port->actor_port_number);
+ /* there is no need to reselect a new aggregator, just signal the
+ * state machines to reinitialize
+ */
port->sm_vars |= AD_PORT_BEGIN;
+
+ __release_state_machine_lock(port);
}
/**
@@ -2254,40 +2279,56 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
{
struct port *port;
- port = &(SLAVE_AD_INFO(slave).port);
+ port = &(SLAVE_AD_INFO(slave)->port);
- // if slave is null, the whole port is not initialized
+ /* if slave is null, the whole port is not initialized */
if (!port->slave) {
- printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
- "uninitialized port on %s\n",
- slave->dev->master->name, slave->dev->name);
+ pr_warn("Warning: %s: link status changed for uninitialized port on %s\n",
+ slave->bond->dev->name, slave->dev->name);
return;
}
- // on link down we are zeroing duplex and speed since some of the adaptors(ce1000.lan) report full duplex/speed instead of N/A(duplex) / 0(speed)
- // on link up we are forcing recheck on the duplex and speed since some of he adaptors(ce1000.lan) report
+ __get_state_machine_lock(port);
+ /* on link down we are zeroing duplex and speed since
+ * some of the adaptors(ce1000.lan) report full duplex/speed
+ * instead of N/A(duplex) / 0(speed).
+ *
+ * on link up we are forcing recheck on the duplex and speed since
+ * some of he adaptors(ce1000.lan) report.
+ */
if (link == BOND_LINK_UP) {
- port->is_enabled = 1;
+ port->is_enabled = true;
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port);
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ __get_duplex(port);
port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS;
- port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1);
+ port->actor_oper_port_key = port->actor_admin_port_key |=
+ (__get_link_speed(port) << 1);
} else {
/* link has failed */
- port->is_enabled = 0;
+ port->is_enabled = false;
port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS;
- port->actor_oper_port_key= (port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS);
- }
- //BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN")));
- // there is no need to reselect a new aggregator, just signal the
- // state machines to reinitialize
+ port->actor_oper_port_key = (port->actor_admin_port_key &=
+ ~AD_SPEED_KEY_BITS);
+ }
+ pr_debug("Port %d changed link status to %s\n",
+ port->actor_port_number,
+ link == BOND_LINK_UP ? "UP" : "DOWN");
+ /* there is no need to reselect a new aggregator, just signal the
+ * state machines to reinitialize
+ */
port->sm_vars |= AD_PORT_BEGIN;
+
+ __release_state_machine_lock(port);
}
-/*
- * set link state for bonding master: if we have an active
- * aggregator, we're up, if not, we're down. Presumes that we cannot
- * have an active aggregator if there are no slaves with link up.
+/**
+ * bond_3ad_set_carrier - set link state for bonding master
+ * @bond - bonding structure
+ *
+ * if we have an active aggregator, we're up, if not, we're down.
+ * Presumes that we cannot have an active aggregator if there are
+ * no slaves with link up.
*
* This behavior complies with IEEE 802.3 section 43.3.9.
*
@@ -2296,160 +2337,197 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
*/
int bond_3ad_set_carrier(struct bonding *bond)
{
- if (__get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator))) {
- if (!netif_carrier_ok(bond->dev)) {
+ struct aggregator *active;
+ struct slave *first_slave;
+ int ret = 1;
+
+ rcu_read_lock();
+ first_slave = bond_first_slave_rcu(bond);
+ if (!first_slave) {
+ ret = 0;
+ goto out;
+ }
+ active = __get_active_agg(&(SLAVE_AD_INFO(first_slave)->aggregator));
+ if (active) {
+ /* are enough slaves available to consider link up? */
+ if (active->num_of_ports < bond->params.min_links) {
+ if (netif_carrier_ok(bond->dev)) {
+ netif_carrier_off(bond->dev);
+ goto out;
+ }
+ } else if (!netif_carrier_ok(bond->dev)) {
netif_carrier_on(bond->dev);
- return 1;
+ goto out;
}
- return 0;
- }
-
- if (netif_carrier_ok(bond->dev)) {
+ } else if (netif_carrier_ok(bond->dev)) {
netif_carrier_off(bond->dev);
- return 1;
}
- return 0;
+out:
+ rcu_read_unlock();
+ return ret;
}
/**
- * bond_3ad_get_active_agg_info - get information of the active aggregator
+ * __bond_3ad_get_active_agg_info - get information of the active aggregator
* @bond: bonding struct to work on
* @ad_info: ad_info struct to fill with the bond's info
*
* Returns: 0 on success
* < 0 on error
*/
-int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
+int __bond_3ad_get_active_agg_info(struct bonding *bond,
+ struct ad_info *ad_info)
{
struct aggregator *aggregator = NULL;
+ struct list_head *iter;
+ struct slave *slave;
struct port *port;
- for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ port = &(SLAVE_AD_INFO(slave)->port);
if (port->aggregator && port->aggregator->is_active) {
aggregator = port->aggregator;
break;
}
}
- if (aggregator) {
- ad_info->aggregator_id = aggregator->aggregator_identifier;
- ad_info->ports = aggregator->num_of_ports;
- ad_info->actor_key = aggregator->actor_oper_aggregator_key;
- ad_info->partner_key = aggregator->partner_oper_aggregator_key;
- memcpy(ad_info->partner_system, aggregator->partner_system.mac_addr_value, ETH_ALEN);
- return 0;
- }
+ if (!aggregator)
+ return -1;
- return -1;
+ ad_info->aggregator_id = aggregator->aggregator_identifier;
+ ad_info->ports = aggregator->num_of_ports;
+ ad_info->actor_key = aggregator->actor_oper_aggregator_key;
+ ad_info->partner_key = aggregator->partner_oper_aggregator_key;
+ ether_addr_copy(ad_info->partner_system,
+ aggregator->partner_system.mac_addr_value);
+ return 0;
+}
+
+/* Wrapper used to hold bond->lock so no slave manipulation can occur */
+int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
+{
+ int ret;
+
+ rcu_read_lock();
+ ret = __bond_3ad_get_active_agg_info(bond, ad_info);
+ rcu_read_unlock();
+
+ return ret;
}
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
{
- struct slave *slave, *start_at;
- struct bonding *bond = dev->priv;
- int slave_agg_no;
+ struct bonding *bond = netdev_priv(dev);
+ struct slave *slave, *first_ok_slave;
+ struct aggregator *agg;
+ struct ad_info ad_info;
+ struct list_head *iter;
int slaves_in_agg;
+ int slave_agg_no;
int agg_id;
- int i;
- struct ad_info ad_info;
- int res = 1;
-
- /* make sure that the slaves list will
- * not change during tx
- */
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
- if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
- printk(KERN_DEBUG DRV_NAME ": %s: Error: "
- "bond_3ad_get_active_agg_info failed\n", dev->name);
- goto out;
+ if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
+ pr_debug("%s: Error: __bond_3ad_get_active_agg_info failed\n",
+ dev->name);
+ goto err_free;
}
slaves_in_agg = ad_info.ports;
agg_id = ad_info.aggregator_id;
if (slaves_in_agg == 0) {
- /*the aggregator is empty*/
- printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
- "aggregator is empty\n",
- dev->name);
- goto out;
+ pr_debug("%s: Error: active aggregator is empty\n", dev->name);
+ goto err_free;
}
- slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg);
+ slave_agg_no = bond_xmit_hash(bond, skb) % slaves_in_agg;
+ first_ok_slave = NULL;
- bond_for_each_slave(bond, slave, i) {
- struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ agg = SLAVE_AD_INFO(slave)->port.aggregator;
+ if (!agg || agg->aggregator_identifier != agg_id)
+ continue;
- if (agg && (agg->aggregator_identifier == agg_id)) {
+ if (slave_agg_no >= 0) {
+ if (!first_ok_slave && bond_slave_can_tx(slave))
+ first_ok_slave = slave;
slave_agg_no--;
- if (slave_agg_no < 0) {
- break;
- }
+ continue;
+ }
+
+ if (bond_slave_can_tx(slave)) {
+ bond_dev_queue_xmit(bond, skb, slave->dev);
+ goto out;
}
}
if (slave_agg_no >= 0) {
- printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
- "for aggregator ID %d\n", dev->name, agg_id);
- goto out;
+ pr_err("%s: Error: Couldn't find a slave to tx on for aggregator ID %d\n",
+ dev->name, agg_id);
+ goto err_free;
}
- start_at = slave;
-
- bond_for_each_slave_from(bond, slave, i, start_at) {
- int slave_agg_id = 0;
- struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
-
- if (agg) {
- slave_agg_id = agg->aggregator_identifier;
- }
-
- if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) {
- res = bond_dev_queue_xmit(bond, skb, slave->dev);
- break;
- }
- }
+ /* we couldn't find any suitable slave after the agg_no, so use the
+ * first suitable found, if found.
+ */
+ if (first_ok_slave)
+ bond_dev_queue_xmit(bond, skb, first_ok_slave->dev);
+ else
+ goto err_free;
out:
- if (res) {
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
- }
- read_unlock(&bond->lock);
- return 0;
+ return NETDEV_TX_OK;
+err_free:
+ /* no suitable interface, frame not sent */
+ dev_kfree_skb_any(skb);
+ goto out;
}
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
+int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct bonding *bond = dev->priv;
- struct slave *slave = NULL;
- int ret = NET_RX_DROP;
+ int ret = RX_HANDLER_ANOTHER;
+ struct lacpdu *lacpdu, _lacpdu;
- if (dev_net(dev) != &init_net)
- goto out;
+ if (skb->protocol != PKT_TYPE_LACPDU)
+ return ret;
- if (!(dev->flags & IFF_MASTER))
- goto out;
+ lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu);
+ if (!lacpdu)
+ return ret;
read_lock(&bond->lock);
- slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
- if (!slave)
- goto out_unlock;
-
- bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
-
- ret = NET_RX_SUCCESS;
-
-out_unlock:
+ ret = bond_3ad_rx_indication(lacpdu, slave, skb->len);
read_unlock(&bond->lock);
-out:
- dev_kfree_skb(skb);
-
return ret;
}
+/**
+ * bond_3ad_update_lacp_rate - change the lacp rate
+ * @bond - bonding struct
+ *
+ * When modify lacp_rate parameter via sysfs,
+ * update actor_oper_port_state of each port.
+ *
+ * Hold slave->state_machine_lock,
+ * so we can modify port->actor_oper_port_state,
+ * no matter bond is up or down.
+ */
+void bond_3ad_update_lacp_rate(struct bonding *bond)
+{
+ struct port *port = NULL;
+ struct list_head *iter;
+ struct slave *slave;
+ int lacp_fast;
+
+ lacp_fast = bond->params.lacp_fast;
+ bond_for_each_slave(bond, slave, iter) {
+ port = &(SLAVE_AD_INFO(slave)->port);
+ __get_state_machine_lock(port);
+ if (lacp_fast)
+ port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT;
+ else
+ port->actor_oper_port_state &= ~AD_STATE_LACP_TIMEOUT;
+ __release_state_machine_lock(port);
+ }
+}
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index b5ee45f6d55..bb03b1df2f3 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -26,75 +26,75 @@
#include <asm/byteorder.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/if_ether.h>
-// General definitions
-#define BOND_ETH_P_LACPDU 0x8809
-#define PKT_TYPE_LACPDU __constant_htons(BOND_ETH_P_LACPDU)
+/* General definitions */
+#define PKT_TYPE_LACPDU cpu_to_be16(ETH_P_SLOW)
#define AD_TIMER_INTERVAL 100 /*msec*/
#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
-#define AD_MULTICAST_LACPDU_ADDR {MULTICAST_LACPDU_ADDR}
#define AD_LACP_SLOW 0
#define AD_LACP_FAST 1
typedef struct mac_addr {
u8 mac_addr_value[ETH_ALEN];
-} mac_addr_t;
+} __packed mac_addr_t;
-typedef enum {
- AD_BANDWIDTH = 0,
- AD_COUNT
-} agg_selection_t;
+enum {
+ BOND_AD_STABLE = 0,
+ BOND_AD_BANDWIDTH = 1,
+ BOND_AD_COUNT = 2,
+};
-// rx machine states(43.4.11 in the 802.3ad standard)
+/* rx machine states(43.4.11 in the 802.3ad standard) */
typedef enum {
AD_RX_DUMMY,
- AD_RX_INITIALIZE, // rx Machine
- AD_RX_PORT_DISABLED, // rx Machine
- AD_RX_LACP_DISABLED, // rx Machine
- AD_RX_EXPIRED, // rx Machine
- AD_RX_DEFAULTED, // rx Machine
- AD_RX_CURRENT // rx Machine
+ AD_RX_INITIALIZE, /* rx Machine */
+ AD_RX_PORT_DISABLED, /* rx Machine */
+ AD_RX_LACP_DISABLED, /* rx Machine */
+ AD_RX_EXPIRED, /* rx Machine */
+ AD_RX_DEFAULTED, /* rx Machine */
+ AD_RX_CURRENT /* rx Machine */
} rx_states_t;
-// periodic machine states(43.4.12 in the 802.3ad standard)
+/* periodic machine states(43.4.12 in the 802.3ad standard) */
typedef enum {
AD_PERIODIC_DUMMY,
- AD_NO_PERIODIC, // periodic machine
- AD_FAST_PERIODIC, // periodic machine
- AD_SLOW_PERIODIC, // periodic machine
- AD_PERIODIC_TX // periodic machine
+ AD_NO_PERIODIC, /* periodic machine */
+ AD_FAST_PERIODIC, /* periodic machine */
+ AD_SLOW_PERIODIC, /* periodic machine */
+ AD_PERIODIC_TX /* periodic machine */
} periodic_states_t;
-// mux machine states(43.4.13 in the 802.3ad standard)
+/* mux machine states(43.4.13 in the 802.3ad standard) */
typedef enum {
AD_MUX_DUMMY,
- AD_MUX_DETACHED, // mux machine
- AD_MUX_WAITING, // mux machine
- AD_MUX_ATTACHED, // mux machine
- AD_MUX_COLLECTING_DISTRIBUTING // mux machine
+ AD_MUX_DETACHED, /* mux machine */
+ AD_MUX_WAITING, /* mux machine */
+ AD_MUX_ATTACHED, /* mux machine */
+ AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */
} mux_states_t;
-// tx machine states(43.4.15 in the 802.3ad standard)
+/* tx machine states(43.4.15 in the 802.3ad standard) */
typedef enum {
AD_TX_DUMMY,
- AD_TRANSMIT // tx Machine
+ AD_TRANSMIT /* tx Machine */
} tx_states_t;
-// rx indication types
+/* rx indication types */
typedef enum {
- AD_TYPE_LACPDU = 1, // type lacpdu
- AD_TYPE_MARKER // type marker
+ AD_TYPE_LACPDU = 1, /* type lacpdu */
+ AD_TYPE_MARKER /* type marker */
} pdu_type_t;
-// rx marker indication types
+/* rx marker indication types */
typedef enum {
- AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype
- AD_MARKER_RESPONSE_SUBTYPE // marker response subtype
+ AD_MARKER_INFORMATION_SUBTYPE = 1, /* marker imformation subtype */
+ AD_MARKER_RESPONSE_SUBTYPE /* marker response subtype */
} bond_marker_subtype_t;
-// timers types(43.4.9 in the 802.3ad standard)
+/* timers types(43.4.9 in the 802.3ad standard) */
typedef enum {
AD_CURRENT_WHILE_TIMER,
AD_ACTOR_CHURN_TIMER,
@@ -105,68 +105,62 @@ typedef enum {
#pragma pack(1)
-typedef struct ad_header {
- struct mac_addr destination_address;
- struct mac_addr source_address;
- __be16 length_type;
-} ad_header_t;
-
-// Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard)
+/* Link Aggregation Control Protocol(LACP) data unit structure(43.4.2.2 in the 802.3ad standard) */
typedef struct lacpdu {
- u8 subtype; // = LACP(= 0x01)
+ u8 subtype; /* = LACP(= 0x01) */
u8 version_number;
- u8 tlv_type_actor_info; // = actor information(type/length/value)
- u8 actor_information_length; // = 20
+ u8 tlv_type_actor_info; /* = actor information(type/length/value) */
+ u8 actor_information_length; /* = 20 */
__be16 actor_system_priority;
struct mac_addr actor_system;
__be16 actor_key;
__be16 actor_port_priority;
__be16 actor_port;
u8 actor_state;
- u8 reserved_3_1[3]; // = 0
- u8 tlv_type_partner_info; // = partner information
- u8 partner_information_length; // = 20
+ u8 reserved_3_1[3]; /* = 0 */
+ u8 tlv_type_partner_info; /* = partner information */
+ u8 partner_information_length; /* = 20 */
__be16 partner_system_priority;
struct mac_addr partner_system;
__be16 partner_key;
__be16 partner_port_priority;
__be16 partner_port;
u8 partner_state;
- u8 reserved_3_2[3]; // = 0
- u8 tlv_type_collector_info; // = collector information
- u8 collector_information_length; // = 16
+ u8 reserved_3_2[3]; /* = 0 */
+ u8 tlv_type_collector_info; /* = collector information */
+ u8 collector_information_length;/* = 16 */
__be16 collector_max_delay;
u8 reserved_12[12];
- u8 tlv_type_terminator; // = terminator
- u8 terminator_length; // = 0
- u8 reserved_50[50]; // = 0
-} lacpdu_t;
+ u8 tlv_type_terminator; /* = terminator */
+ u8 terminator_length; /* = 0 */
+ u8 reserved_50[50]; /* = 0 */
+} __packed lacpdu_t;
typedef struct lacpdu_header {
- struct ad_header ad_header;
+ struct ethhdr hdr;
struct lacpdu lacpdu;
-} lacpdu_header_t;
+} __packed lacpdu_header_t;
-// Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard)
+/* Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) */
typedef struct bond_marker {
- u8 subtype; // = 0x02 (marker PDU)
- u8 version_number; // = 0x01
- u8 tlv_type; // = 0x01 (marker information)
- // = 0x02 (marker response information)
- u8 marker_length; // = 0x16
- u16 requester_port; // The number assigned to the port by the requester
- struct mac_addr requester_system; // The requester's system id
- u32 requester_transaction_id; // The transaction id allocated by the requester,
- u16 pad; // = 0
- u8 tlv_type_terminator; // = 0x00
- u8 terminator_length; // = 0x00
- u8 reserved_90[90]; // = 0
-} bond_marker_t;
+ u8 subtype; /* = 0x02 (marker PDU) */
+ u8 version_number; /* = 0x01 */
+ u8 tlv_type; /* = 0x01 (marker information) */
+ /* = 0x02 (marker response information) */
+ u8 marker_length; /* = 0x16 */
+ u16 requester_port; /* The number assigned to the port by the requester */
+ struct mac_addr requester_system; /* The requester's system id */
+ u32 requester_transaction_id; /* The transaction id allocated by the requester, */
+ u16 pad; /* = 0 */
+ u8 tlv_type_terminator; /* = 0x00 */
+ u8 terminator_length; /* = 0x00 */
+ u8 reserved_90[90]; /* = 0 */
+} __packed bond_marker_t;
typedef struct bond_marker_header {
- struct ad_header ad_header;
+ struct ethhdr hdr;
struct bond_marker marker;
-} bond_marker_header_t;
+} __packed bond_marker_header_t;
#pragma pack()
@@ -179,110 +173,112 @@ struct port;
#pragma pack(8)
#endif
-// aggregator structure(43.4.5 in the 802.3ad standard)
+/* aggregator structure(43.4.5 in the 802.3ad standard) */
typedef struct aggregator {
struct mac_addr aggregator_mac_address;
u16 aggregator_identifier;
- u16 is_individual; // BOOLEAN
+ bool is_individual;
u16 actor_admin_aggregator_key;
u16 actor_oper_aggregator_key;
struct mac_addr partner_system;
u16 partner_system_priority;
u16 partner_oper_aggregator_key;
- u16 receive_state; // BOOLEAN
- u16 transmit_state; // BOOLEAN
+ u16 receive_state; /* BOOLEAN */
+ u16 transmit_state; /* BOOLEAN */
struct port *lag_ports;
- // ****** PRIVATE PARAMETERS ******
- struct slave *slave; // pointer to the bond slave that this aggregator belongs to
- u16 is_active; // BOOLEAN. Indicates if this aggregator is active
+ /* ****** PRIVATE PARAMETERS ****** */
+ struct slave *slave; /* pointer to the bond slave that this aggregator belongs to */
+ u16 is_active; /* BOOLEAN. Indicates if this aggregator is active */
u16 num_of_ports;
} aggregator_t;
-// port structure(43.4.6 in the 802.3ad standard)
+struct port_params {
+ struct mac_addr system;
+ u16 system_priority;
+ u16 key;
+ u16 port_number;
+ u16 port_priority;
+ u16 port_state;
+};
+
+/* port structure(43.4.6 in the 802.3ad standard) */
typedef struct port {
u16 actor_port_number;
u16 actor_port_priority;
- struct mac_addr actor_system; // This parameter is added here although it is not specified in the standard, just for simplification
- u16 actor_system_priority; // This parameter is added here although it is not specified in the standard, just for simplification
+ struct mac_addr actor_system; /* This parameter is added here although it is not specified in the standard, just for simplification */
+ u16 actor_system_priority; /* This parameter is added here although it is not specified in the standard, just for simplification */
u16 actor_port_aggregator_identifier;
- u16 ntt; // BOOLEAN
+ bool ntt;
u16 actor_admin_port_key;
u16 actor_oper_port_key;
u8 actor_admin_port_state;
u8 actor_oper_port_state;
- struct mac_addr partner_admin_system;
- struct mac_addr partner_oper_system;
- u16 partner_admin_system_priority;
- u16 partner_oper_system_priority;
- u16 partner_admin_key;
- u16 partner_oper_key;
- u16 partner_admin_port_number;
- u16 partner_oper_port_number;
- u16 partner_admin_port_priority;
- u16 partner_oper_port_priority;
- u8 partner_admin_port_state;
- u8 partner_oper_port_state;
- u16 is_enabled; // BOOLEAN
- // ****** PRIVATE PARAMETERS ******
- u16 sm_vars; // all state machines variables for this port
- rx_states_t sm_rx_state; // state machine rx state
- u16 sm_rx_timer_counter; // state machine rx timer counter
- periodic_states_t sm_periodic_state;// state machine periodic state
- u16 sm_periodic_timer_counter; // state machine periodic timer counter
- mux_states_t sm_mux_state; // state machine mux state
- u16 sm_mux_timer_counter; // state machine mux timer counter
- tx_states_t sm_tx_state; // state machine tx state
- u16 sm_tx_timer_counter; // state machine tx timer counter(allways on - enter to transmit state 3 time per second)
- struct slave *slave; // pointer to the bond slave that this port belongs to
- struct aggregator *aggregator; // pointer to an aggregator that this port related to
- struct port *next_port_in_aggregator; // Next port on the linked list of the parent aggregator
- u32 transaction_id; // continuous number for identification of Marker PDU's;
- struct lacpdu lacpdu; // the lacpdu that will be sent for this port
+
+ struct port_params partner_admin;
+ struct port_params partner_oper;
+
+ bool is_enabled;
+
+ /* ****** PRIVATE PARAMETERS ****** */
+ u16 sm_vars; /* all state machines variables for this port */
+ rx_states_t sm_rx_state; /* state machine rx state */
+ u16 sm_rx_timer_counter; /* state machine rx timer counter */
+ periodic_states_t sm_periodic_state; /* state machine periodic state */
+ u16 sm_periodic_timer_counter; /* state machine periodic timer counter */
+ mux_states_t sm_mux_state; /* state machine mux state */
+ u16 sm_mux_timer_counter; /* state machine mux timer counter */
+ tx_states_t sm_tx_state; /* state machine tx state */
+ u16 sm_tx_timer_counter; /* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */
+ struct slave *slave; /* pointer to the bond slave that this port belongs to */
+ struct aggregator *aggregator; /* pointer to an aggregator that this port related to */
+ struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */
+ u32 transaction_id; /* continuous number for identification of Marker PDU's; */
+ struct lacpdu lacpdu; /* the lacpdu that will be sent for this port */
} port_t;
-// system structure
-typedef struct ad_system {
+/* system structure */
+struct ad_system {
u16 sys_priority;
struct mac_addr sys_mac_addr;
-} ad_system_t;
+};
#ifdef __ia64__
#pragma pack()
#endif
-// ================= AD Exported structures to the main bonding code ==================
+/* ========== AD Exported structures to the main bonding code ========== */
#define BOND_AD_INFO(bond) ((bond)->ad_info)
#define SLAVE_AD_INFO(slave) ((slave)->ad_info)
struct ad_bond_info {
- ad_system_t system; // 802.3ad system structure
- u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes
- u32 agg_select_mode; // Mode of selection of active aggregator(bandwidth/count)
- int lacp_fast; /* whether fast periodic tx should be
- * requested
- */
- struct timer_list ad_timer;
- struct packet_type ad_pkt_type;
+ struct ad_system system; /* 802.3ad system structure */
+ u32 agg_select_timer; /* Timer to select aggregator after all adapter's hand shakes */
+ u16 aggregator_identifier;
};
struct ad_slave_info {
- struct aggregator aggregator; // 802.3ad aggregator structure
- struct port port; // 802.3ad port structure
- spinlock_t rx_machine_lock; // To avoid race condition between callback and receive interrupt
+ struct aggregator aggregator; /* 802.3ad aggregator structure */
+ struct port port; /* 802.3ad port structure */
+ spinlock_t state_machine_lock; /* mutex state machines vs. incoming LACPDU */
u16 id;
};
-// ================= AD Exported functions to the main bonding code ==================
-void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast);
-int bond_3ad_bind_slave(struct slave *slave);
+/* ========== AD Exported functions to the main bonding code ========== */
+void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
+void bond_3ad_bind_slave(struct slave *slave);
void bond_3ad_unbind_slave(struct slave *slave);
void bond_3ad_state_machine_handler(struct work_struct *);
+void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout);
void bond_3ad_adapter_speed_changed(struct slave *slave);
void bond_3ad_adapter_duplex_changed(struct slave *slave);
void bond_3ad_handle_link_change(struct slave *slave, char link);
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
+int __bond_3ad_get_active_agg_info(struct bonding *bond,
+ struct ad_info *ad_info);
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
+int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave);
int bond_3ad_set_carrier(struct bonding *bond);
-#endif //__BOND_3AD_H__
+void bond_3ad_update_lacp_rate(struct bonding *bond);
+#endif /* __BOND_3AD_H__ */
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index b211486a0ca..76c0dade233 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -12,15 +12,14 @@
* for more details.
*
* You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
*/
-//#define BONDING_DEBUG 1
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/skbuff.h>
#include <linux/netdevice.h>
@@ -38,49 +37,22 @@
#include <linux/in.h>
#include <net/ipx.h>
#include <net/arp.h>
+#include <net/ipv6.h>
#include <asm/byteorder.h>
#include "bonding.h"
#include "bond_alb.h"
-#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */
-#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing.
- * Used for division - never set
- * to zero !!!
- */
-#define BOND_ALB_LP_INTERVAL 1 /* In seconds, periodic send of
- * learning packets to the switch
- */
-
-#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
- * ALB_TIMER_TICKS_PER_SEC)
-
-#define BOND_ALB_LP_TICKS (BOND_ALB_LP_INTERVAL \
- * ALB_TIMER_TICKS_PER_SEC)
-
-#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table.
- * Note that this value MUST NOT be smaller
- * because the key hash table is BYTE wide !
- */
-
-#define TLB_NULL_INDEX 0xffffffff
-#define MAX_LP_BURST 3
-
-/* rlb defs */
-#define RLB_HASH_TABLE_SIZE 256
-#define RLB_NULL_INDEX 0xffffffff
-#define RLB_UPDATE_DELAY 2*ALB_TIMER_TICKS_PER_SEC /* 2 seconds */
-#define RLB_ARP_BURST_SIZE 2
-#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb
- * rebalance interval (5 min).
- */
-/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
- * promiscuous after failover
- */
-#define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC
-
-static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+#ifndef __long_aligned
+#define __long_aligned __attribute__((aligned((sizeof(long)))))
+#endif
+static const u8 mac_bcast[ETH_ALEN] __long_aligned = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+static const u8 mac_v6_allmcast[ETH_ALEN] __long_aligned = {
+ 0x33, 0x33, 0x00, 0x00, 0x00, 0x01
+};
static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
#pragma pack(1)
@@ -110,32 +82,46 @@ static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb)
}
/* Forward declaration */
-static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]);
+static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
+ bool strict_match);
+static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp);
+static void rlb_src_unlink(struct bonding *bond, u32 index);
+static void rlb_src_link(struct bonding *bond, u32 ip_src_hash,
+ u32 ip_dst_hash);
static inline u8 _simple_hash(const u8 *hash_start, int hash_size)
{
int i;
u8 hash = 0;
- for (i = 0; i < hash_size; i++) {
+ for (i = 0; i < hash_size; i++)
hash ^= hash_start[i];
- }
return hash;
}
/*********************** tlb specific functions ***************************/
-static inline void _lock_tx_hashtbl(struct bonding *bond)
+static inline void _lock_tx_hashtbl_bh(struct bonding *bond)
{
spin_lock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
}
-static inline void _unlock_tx_hashtbl(struct bonding *bond)
+static inline void _unlock_tx_hashtbl_bh(struct bonding *bond)
{
spin_unlock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
}
+static inline void _lock_tx_hashtbl(struct bonding *bond)
+{
+ spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
+}
+
+static inline void _unlock_tx_hashtbl(struct bonding *bond)
+{
+ spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
+}
+
/* Caller must hold tx_hashtbl lock */
static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load)
{
@@ -156,27 +142,36 @@ static inline void tlb_init_slave(struct slave *slave)
SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX;
}
-/* Caller must hold bond lock for read */
-static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_load)
+/* Caller must hold bond lock for read, BH disabled */
+static void __tlb_clear_slave(struct bonding *bond, struct slave *slave,
+ int save_load)
{
struct tlb_client_info *tx_hash_table;
u32 index;
- _lock_tx_hashtbl(bond);
-
/* clear slave from tx_hashtbl */
tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl;
- index = SLAVE_TLB_INFO(slave).head;
- while (index != TLB_NULL_INDEX) {
- u32 next_index = tx_hash_table[index].next;
- tlb_init_table_entry(&tx_hash_table[index], save_load);
- index = next_index;
+ /* skip this if we've already freed the tx hash table */
+ if (tx_hash_table) {
+ index = SLAVE_TLB_INFO(slave).head;
+ while (index != TLB_NULL_INDEX) {
+ u32 next_index = tx_hash_table[index].next;
+ tlb_init_table_entry(&tx_hash_table[index], save_load);
+ index = next_index;
+ }
}
tlb_init_slave(slave);
+}
- _unlock_tx_hashtbl(bond);
+/* Caller must hold bond lock for read */
+static void tlb_clear_slave(struct bonding *bond, struct slave *slave,
+ int save_load)
+{
+ _lock_tx_hashtbl_bh(bond);
+ __tlb_clear_slave(bond, slave, save_load);
+ _unlock_tx_hashtbl_bh(bond);
}
/* Must be called before starting the monitor timer */
@@ -187,24 +182,18 @@ static int tlb_initialize(struct bonding *bond)
struct tlb_client_info *new_hashtbl;
int i;
- spin_lock_init(&(bond_info->tx_hashtbl_lock));
-
new_hashtbl = kzalloc(size, GFP_KERNEL);
- if (!new_hashtbl) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to allocate TLB hash table\n",
- bond->dev->name);
+ if (!new_hashtbl)
return -1;
- }
- _lock_tx_hashtbl(bond);
+
+ _lock_tx_hashtbl_bh(bond);
bond_info->tx_hashtbl = new_hashtbl;
- for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) {
- tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1);
- }
+ for (i = 0; i < TLB_HASH_TABLE_SIZE; i++)
+ tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0);
- _unlock_tx_hashtbl(bond);
+ _unlock_tx_hashtbl_bh(bond);
return 0;
}
@@ -214,42 +203,35 @@ static void tlb_deinitialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- _lock_tx_hashtbl(bond);
+ _lock_tx_hashtbl_bh(bond);
kfree(bond_info->tx_hashtbl);
bond_info->tx_hashtbl = NULL;
- _unlock_tx_hashtbl(bond);
+ _unlock_tx_hashtbl_bh(bond);
+}
+
+static long long compute_gap(struct slave *slave)
+{
+ return (s64) (slave->speed << 20) - /* Convert to Megabit per sec */
+ (s64) (SLAVE_TLB_INFO(slave).load << 3); /* Bytes to bits */
}
/* Caller must hold bond lock for read */
static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
{
struct slave *slave, *least_loaded;
- s64 max_gap;
- int i, found = 0;
+ struct list_head *iter;
+ long long max_gap;
- /* Find the first enabled slave */
- bond_for_each_slave(bond, slave, i) {
- if (SLAVE_IS_OK(slave)) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- return NULL;
- }
-
- least_loaded = slave;
- max_gap = (s64)(slave->speed << 20) - /* Convert to Megabit per sec */
- (s64)(SLAVE_TLB_INFO(slave).load << 3); /* Bytes to bits */
+ least_loaded = NULL;
+ max_gap = LLONG_MIN;
/* Find the slave with the largest gap */
- bond_for_each_slave_from(bond, slave, i, least_loaded) {
- if (SLAVE_IS_OK(slave)) {
- s64 gap = (s64)(slave->speed << 20) -
- (s64)(SLAVE_TLB_INFO(slave).load << 3);
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (bond_slave_can_tx(slave)) {
+ long long gap = compute_gap(slave);
+
if (max_gap < gap) {
least_loaded = slave;
max_gap = gap;
@@ -260,15 +242,13 @@ static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
return least_loaded;
}
-/* Caller must hold bond lock for read */
-static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
+static struct slave *__tlb_choose_channel(struct bonding *bond, u32 hash_index,
+ u32 skb_len)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct tlb_client_info *hash_table;
struct slave *assigned_slave;
- _lock_tx_hashtbl(bond);
-
hash_table = bond_info->tx_hashtbl;
assigned_slave = hash_table[hash_index].tx_slave;
if (!assigned_slave) {
@@ -283,9 +263,8 @@ static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u3
hash_table[hash_index].next = next_index;
hash_table[hash_index].prev = TLB_NULL_INDEX;
- if (next_index != TLB_NULL_INDEX) {
+ if (next_index != TLB_NULL_INDEX)
hash_table[next_index].prev = hash_index;
- }
slave_info->head = hash_index;
slave_info->load +=
@@ -293,26 +272,49 @@ static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u3
}
}
- if (assigned_slave) {
+ if (assigned_slave)
hash_table[hash_index].tx_bytes += skb_len;
- }
-
- _unlock_tx_hashtbl(bond);
return assigned_slave;
}
+/* Caller must hold bond lock for read */
+static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index,
+ u32 skb_len)
+{
+ struct slave *tx_slave;
+ /*
+ * We don't need to disable softirq here, becase
+ * tlb_choose_channel() is only called by bond_alb_xmit()
+ * which already has softirq disabled.
+ */
+ _lock_tx_hashtbl(bond);
+ tx_slave = __tlb_choose_channel(bond, hash_index, skb_len);
+ _unlock_tx_hashtbl(bond);
+ return tx_slave;
+}
+
/*********************** rlb specific functions ***************************/
-static inline void _lock_rx_hashtbl(struct bonding *bond)
+static inline void _lock_rx_hashtbl_bh(struct bonding *bond)
{
spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
}
-static inline void _unlock_rx_hashtbl(struct bonding *bond)
+static inline void _unlock_rx_hashtbl_bh(struct bonding *bond)
{
spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
}
+static inline void _lock_rx_hashtbl(struct bonding *bond)
+{
+ spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+}
+
+static inline void _unlock_rx_hashtbl(struct bonding *bond)
+{
+ spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+}
+
/* when an ARP REPLY is received from a client update its info
* in the rx_hashtbl
*/
@@ -322,87 +324,119 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
struct rlb_client_info *client_info;
u32 hash_index;
- _lock_rx_hashtbl(bond);
+ _lock_rx_hashtbl_bh(bond);
- hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src));
+ hash_index = _simple_hash((u8 *)&(arp->ip_src), sizeof(arp->ip_src));
client_info = &(bond_info->rx_hashtbl[hash_index]);
if ((client_info->assigned) &&
(client_info->ip_src == arp->ip_dst) &&
- (client_info->ip_dst == arp->ip_src)) {
+ (client_info->ip_dst == arp->ip_src) &&
+ (!ether_addr_equal_64bits(client_info->mac_dst, arp->mac_src))) {
/* update the clients MAC address */
- memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
+ ether_addr_copy(client_info->mac_dst, arp->mac_src);
client_info->ntt = 1;
bond_info->rx_ntt = 1;
}
- _unlock_rx_hashtbl(bond);
+ _unlock_rx_hashtbl_bh(bond);
}
-static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev)
+static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct bonding *bond = bond_dev->priv;
- struct arp_pkt *arp = (struct arp_pkt *)skb->data;
- int res = NET_RX_DROP;
-
- if (dev_net(bond_dev) != &init_net)
- goto out;
+ struct arp_pkt *arp, _arp;
- if (!(bond_dev->flags & IFF_MASTER))
+ if (skb->protocol != cpu_to_be16(ETH_P_ARP))
goto out;
- if (!arp) {
- dprintk("Packet has no ARP data\n");
+ arp = skb_header_pointer(skb, 0, sizeof(_arp), &_arp);
+ if (!arp)
goto out;
- }
- if (skb->len < sizeof(struct arp_pkt)) {
- dprintk("Packet is too small to be an ARP\n");
- goto out;
- }
+ /* We received an ARP from arp->ip_src.
+ * We might have used this IP address previously (on the bonding host
+ * itself or on a system that is bridged together with the bond).
+ * However, if arp->mac_src is different than what is stored in
+ * rx_hashtbl, some other host is now using the IP and we must prevent
+ * sending out client updates with this IP address and the old MAC
+ * address.
+ * Clean up all hash table entries that have this address as ip_src but
+ * have a different mac_src.
+ */
+ rlb_purge_src_ip(bond, arp);
if (arp->op_code == htons(ARPOP_REPLY)) {
/* update rx hash table for this ARP */
rlb_update_entry_from_arp(bond, arp);
- dprintk("Server received an ARP Reply from client\n");
+ pr_debug("Server received an ARP Reply from client\n");
}
-
- res = NET_RX_SUCCESS;
-
out:
- dev_kfree_skb(skb);
-
- return res;
+ return RX_HANDLER_ANOTHER;
}
/* Caller must hold bond lock for read */
static struct slave *rlb_next_rx_slave(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- struct slave *rx_slave, *slave, *start_at;
- int i = 0;
+ struct slave *before = NULL, *rx_slave = NULL, *slave;
+ struct list_head *iter;
+ bool found = false;
- if (bond_info->next_rx_slave) {
- start_at = bond_info->next_rx_slave;
- } else {
- start_at = bond->first_slave;
+ bond_for_each_slave(bond, slave, iter) {
+ if (!bond_slave_can_tx(slave))
+ continue;
+ if (!found) {
+ if (!before || before->speed < slave->speed)
+ before = slave;
+ } else {
+ if (!rx_slave || rx_slave->speed < slave->speed)
+ rx_slave = slave;
+ }
+ if (slave == bond_info->rx_slave)
+ found = true;
}
+ /* we didn't find anything after the current or we have something
+ * better before and up to the current slave
+ */
+ if (!rx_slave || (before && rx_slave->speed < before->speed))
+ rx_slave = before;
- rx_slave = NULL;
+ if (rx_slave)
+ bond_info->rx_slave = rx_slave;
- bond_for_each_slave_from(bond, slave, i, start_at) {
- if (SLAVE_IS_OK(slave)) {
- if (!rx_slave) {
- rx_slave = slave;
- } else if (slave->speed > rx_slave->speed) {
+ return rx_slave;
+}
+
+/* Caller must hold rcu_read_lock() for read */
+static struct slave *__rlb_next_rx_slave(struct bonding *bond)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct slave *before = NULL, *rx_slave = NULL, *slave;
+ struct list_head *iter;
+ bool found = false;
+
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (!bond_slave_can_tx(slave))
+ continue;
+ if (!found) {
+ if (!before || before->speed < slave->speed)
+ before = slave;
+ } else {
+ if (!rx_slave || rx_slave->speed < slave->speed)
rx_slave = slave;
- }
}
+ if (slave == bond_info->rx_slave)
+ found = true;
}
+ /* we didn't find anything after the current or we have something
+ * better before and up to the current slave
+ */
+ if (!rx_slave || (before && rx_slave->speed < before->speed))
+ rx_slave = before;
- if (rx_slave) {
- bond_info->next_rx_slave = rx_slave->next;
- }
+ if (rx_slave)
+ bond_info->rx_slave = rx_slave;
return rx_slave;
}
@@ -414,9 +448,8 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond)
*/
static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
{
- if (!bond->curr_active_slave) {
+ if (!bond->curr_active_slave)
return;
- }
if (!bond->alb_info.primary_is_promisc) {
if (!dev_set_promiscuity(bond->curr_active_slave->dev, 1))
@@ -427,12 +460,12 @@ static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[])
bond->alb_info.rlb_promisc_timeout_counter = 0;
- alb_send_learning_packets(bond->curr_active_slave, addr);
+ alb_send_learning_packets(bond->curr_active_slave, addr, true);
}
/* slave being removed should not be active at this point
*
- * Caller must hold bond lock for read
+ * Caller must hold rtnl.
*/
static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
{
@@ -441,19 +474,19 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
u32 index, next_index;
/* clear slave from rx_hashtbl */
- _lock_rx_hashtbl(bond);
+ _lock_rx_hashtbl_bh(bond);
rx_hash_table = bond_info->rx_hashtbl;
- index = bond_info->rx_hashtbl_head;
+ index = bond_info->rx_hashtbl_used_head;
for (; index != RLB_NULL_INDEX; index = next_index) {
- next_index = rx_hash_table[index].next;
+ next_index = rx_hash_table[index].used_next;
if (rx_hash_table[index].slave == slave) {
struct slave *assigned_slave = rlb_next_rx_slave(bond);
if (assigned_slave) {
rx_hash_table[index].slave = assigned_slave;
- if (memcmp(rx_hash_table[index].mac_dst,
- mac_bcast, ETH_ALEN)) {
+ if (!ether_addr_equal_64bits(rx_hash_table[index].mac_dst,
+ mac_bcast)) {
bond_info->rx_hashtbl[index].ntt = 1;
bond_info->rx_ntt = 1;
/* A slave has been removed from the
@@ -472,13 +505,12 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
}
}
- _unlock_rx_hashtbl(bond);
+ _unlock_rx_hashtbl_bh(bond);
write_lock_bh(&bond->curr_slave_lock);
- if (slave != bond->curr_active_slave) {
+ if (slave != bond->curr_active_slave)
rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr);
- }
write_unlock_bh(&bond->curr_slave_lock);
}
@@ -487,9 +519,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
{
int i;
- if (!client_info->slave) {
+ if (!client_info->slave)
return;
- }
for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
struct sk_buff *skb;
@@ -502,20 +533,18 @@ static void rlb_update_client(struct rlb_client_info *client_info)
client_info->slave->dev->dev_addr,
client_info->mac_dst);
if (!skb) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: failed to create an ARP packet\n",
- client_info->slave->dev->master->name);
+ pr_err("%s: Error: failed to create an ARP packet\n",
+ client_info->slave->bond->dev->name);
continue;
}
skb->dev = client_info->slave->dev;
- if (client_info->tag) {
- skb = vlan_put_tag(skb, client_info->vlan_id);
+ if (client_info->vlan_id) {
+ skb = vlan_put_tag(skb, htons(ETH_P_8021Q), client_info->vlan_id);
if (!skb) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: failed to insert VLAN tag\n",
- client_info->slave->dev->master->name);
+ pr_err("%s: Error: failed to insert VLAN tag\n",
+ client_info->slave->bond->dev->name);
continue;
}
}
@@ -531,25 +560,25 @@ static void rlb_update_rx_clients(struct bonding *bond)
struct rlb_client_info *client_info;
u32 hash_index;
- _lock_rx_hashtbl(bond);
+ _lock_rx_hashtbl_bh(bond);
- hash_index = bond_info->rx_hashtbl_head;
- for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+ hash_index = bond_info->rx_hashtbl_used_head;
+ for (; hash_index != RLB_NULL_INDEX;
+ hash_index = client_info->used_next) {
client_info = &(bond_info->rx_hashtbl[hash_index]);
if (client_info->ntt) {
rlb_update_client(client_info);
- if (bond_info->rlb_update_retry_counter == 0) {
+ if (bond_info->rlb_update_retry_counter == 0)
client_info->ntt = 0;
- }
}
}
- /* do not update the entries again untill this counter is zero so that
+ /* do not update the entries again until this counter is zero so that
* not to confuse the clients.
*/
bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY;
- _unlock_rx_hashtbl(bond);
+ _unlock_rx_hashtbl_bh(bond);
}
/* The slave was assigned a new mac address - update the clients */
@@ -560,27 +589,28 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla
int ntt = 0;
u32 hash_index;
- _lock_rx_hashtbl(bond);
+ _lock_rx_hashtbl_bh(bond);
- hash_index = bond_info->rx_hashtbl_head;
- for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+ hash_index = bond_info->rx_hashtbl_used_head;
+ for (; hash_index != RLB_NULL_INDEX;
+ hash_index = client_info->used_next) {
client_info = &(bond_info->rx_hashtbl[hash_index]);
if ((client_info->slave == slave) &&
- memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+ !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) {
client_info->ntt = 1;
ntt = 1;
}
}
- // update the team's flag only after the whole iteration
+ /* update the team's flag only after the whole iteration */
if (ntt) {
bond_info->rx_ntt = 1;
- //fasten the change
+ /* fasten the change */
bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY;
}
- _unlock_rx_hashtbl(bond);
+ _unlock_rx_hashtbl_bh(bond);
}
/* mark all clients using src_ip to be updated */
@@ -592,14 +622,13 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
_lock_rx_hashtbl(bond);
- hash_index = bond_info->rx_hashtbl_head;
- for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+ hash_index = bond_info->rx_hashtbl_used_head;
+ for (; hash_index != RLB_NULL_INDEX;
+ hash_index = client_info->used_next) {
client_info = &(bond_info->rx_hashtbl[hash_index]);
if (!client_info->slave) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: found a client with no channel in "
- "the client's hash table\n",
+ pr_err("%s: Error: found a client with no channel in the client's hash table\n",
bond->dev->name);
continue;
}
@@ -608,9 +637,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
* unicast mac address.
*/
if ((client_info->ip_src == src_ip) &&
- memcmp(client_info->slave->dev->dev_addr,
- bond->dev->dev_addr, ETH_ALEN) &&
- memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+ !ether_addr_equal_64bits(client_info->slave->dev->dev_addr,
+ bond->dev->dev_addr) &&
+ !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) {
client_info->ntt = 1;
bond_info->rx_ntt = 1;
}
@@ -624,23 +653,26 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct arp_pkt *arp = arp_pkt(skb);
- struct slave *assigned_slave;
+ struct slave *assigned_slave, *curr_active_slave;
struct rlb_client_info *client_info;
u32 hash_index = 0;
_lock_rx_hashtbl(bond);
- hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_src));
+ curr_active_slave = rcu_dereference(bond->curr_active_slave);
+
+ hash_index = _simple_hash((u8 *)&arp->ip_dst, sizeof(arp->ip_dst));
client_info = &(bond_info->rx_hashtbl[hash_index]);
if (client_info->assigned) {
if ((client_info->ip_src == arp->ip_src) &&
(client_info->ip_dst == arp->ip_dst)) {
/* the entry is already assigned to this client */
- if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) {
+ if (!ether_addr_equal_64bits(arp->mac_dst, mac_bcast)) {
/* update mac address from arp */
- memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
+ ether_addr_copy(client_info->mac_dst, arp->mac_dst);
}
+ ether_addr_copy(client_info->mac_src, arp->mac_src);
assigned_slave = client_info->slave;
if (assigned_slave) {
@@ -653,43 +685,53 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
* that the new client can be assigned to this entry.
*/
if (bond->curr_active_slave &&
- client_info->slave != bond->curr_active_slave) {
- client_info->slave = bond->curr_active_slave;
+ client_info->slave != curr_active_slave) {
+ client_info->slave = curr_active_slave;
rlb_update_client(client_info);
}
}
}
/* assign a new slave */
- assigned_slave = rlb_next_rx_slave(bond);
+ assigned_slave = __rlb_next_rx_slave(bond);
if (assigned_slave) {
+ if (!(client_info->assigned &&
+ client_info->ip_src == arp->ip_src)) {
+ /* ip_src is going to be updated,
+ * fix the src hash list
+ */
+ u32 hash_src = _simple_hash((u8 *)&arp->ip_src,
+ sizeof(arp->ip_src));
+ rlb_src_unlink(bond, hash_index);
+ rlb_src_link(bond, hash_src, hash_index);
+ }
+
client_info->ip_src = arp->ip_src;
client_info->ip_dst = arp->ip_dst;
/* arp->mac_dst is broadcast for arp reqeusts.
* will be updated with clients actual unicast mac address
* upon receiving an arp reply.
*/
- memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
+ ether_addr_copy(client_info->mac_dst, arp->mac_dst);
+ ether_addr_copy(client_info->mac_src, arp->mac_src);
client_info->slave = assigned_slave;
- if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+ if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) {
client_info->ntt = 1;
bond->alb_info.rx_ntt = 1;
} else {
client_info->ntt = 0;
}
- if (!list_empty(&bond->vlan_list)) {
- if (!vlan_get_tag(skb, &client_info->vlan_id))
- client_info->tag = 1;
- }
+ if (vlan_get_tag(skb, &client_info->vlan_id))
+ client_info->vlan_id = 0;
if (!client_info->assigned) {
- u32 prev_tbl_head = bond_info->rx_hashtbl_head;
- bond_info->rx_hashtbl_head = hash_index;
- client_info->next = prev_tbl_head;
+ u32 prev_tbl_head = bond_info->rx_hashtbl_used_head;
+ bond_info->rx_hashtbl_used_head = hash_index;
+ client_info->used_next = prev_tbl_head;
if (prev_tbl_head != RLB_NULL_INDEX) {
- bond_info->rx_hashtbl[prev_tbl_head].prev =
+ bond_info->rx_hashtbl[prev_tbl_head].used_prev =
hash_index;
}
client_info->assigned = 1;
@@ -710,16 +752,21 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
struct arp_pkt *arp = arp_pkt(skb);
struct slave *tx_slave = NULL;
- if (arp->op_code == __constant_htons(ARPOP_REPLY)) {
+ /* Don't modify or load balance ARPs that do not originate locally
+ * (e.g.,arrive via a bridge).
+ */
+ if (!bond_slave_has_mac_rx(bond, arp->mac_src))
+ return NULL;
+
+ if (arp->op_code == htons(ARPOP_REPLY)) {
/* the arp must be sent on the selected
* rx channel
*/
tx_slave = rlb_choose_channel(skb, bond);
- if (tx_slave) {
- memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN);
- }
- dprintk("Server sent ARP Reply packet\n");
- } else if (arp->op_code == __constant_htons(ARPOP_REQUEST)) {
+ if (tx_slave)
+ ether_addr_copy(arp->mac_src, tx_slave->dev->dev_addr);
+ pr_debug("Server sent ARP Reply packet\n");
+ } else if (arp->op_code == htons(ARPOP_REQUEST)) {
/* Create an entry in the rx_hashtbl for this client as a
* place holder.
* When the arp reply is received the entry will be updated
@@ -727,7 +774,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
*/
rlb_choose_channel(skb, bond);
- /* The ARP relpy packets must be delayed so that
+ /* The ARP reply packets must be delayed so that
* they can cancel out the influence of the ARP request.
*/
bond->alb_info.rlb_update_delay_counter = RLB_UPDATE_DELAY;
@@ -738,7 +785,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
* updated with their assigned mac.
*/
rlb_req_update_subnet_clients(bond, arp->ip_src);
- dprintk("Server sent ARP Request packet\n");
+ pr_debug("Server sent ARP Request packet\n");
}
return tx_slave;
@@ -753,13 +800,14 @@ static void rlb_rebalance(struct bonding *bond)
int ntt;
u32 hash_index;
- _lock_rx_hashtbl(bond);
+ _lock_rx_hashtbl_bh(bond);
ntt = 0;
- hash_index = bond_info->rx_hashtbl_head;
- for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
+ hash_index = bond_info->rx_hashtbl_used_head;
+ for (; hash_index != RLB_NULL_INDEX;
+ hash_index = client_info->used_next) {
client_info = &(bond_info->rx_hashtbl[hash_index]);
- assigned_slave = rlb_next_rx_slave(bond);
+ assigned_slave = __rlb_next_rx_slave(bond);
if (assigned_slave && (client_info->slave != assigned_slave)) {
client_info->slave = assigned_slave;
client_info->ntt = 1;
@@ -768,56 +816,145 @@ static void rlb_rebalance(struct bonding *bond)
}
/* update the team's flag only after the whole iteration */
- if (ntt) {
+ if (ntt)
bond_info->rx_ntt = 1;
- }
- _unlock_rx_hashtbl(bond);
+ _unlock_rx_hashtbl_bh(bond);
}
/* Caller must hold rx_hashtbl lock */
+static void rlb_init_table_entry_dst(struct rlb_client_info *entry)
+{
+ entry->used_next = RLB_NULL_INDEX;
+ entry->used_prev = RLB_NULL_INDEX;
+ entry->assigned = 0;
+ entry->slave = NULL;
+ entry->vlan_id = 0;
+}
+static void rlb_init_table_entry_src(struct rlb_client_info *entry)
+{
+ entry->src_first = RLB_NULL_INDEX;
+ entry->src_prev = RLB_NULL_INDEX;
+ entry->src_next = RLB_NULL_INDEX;
+}
+
static void rlb_init_table_entry(struct rlb_client_info *entry)
{
memset(entry, 0, sizeof(struct rlb_client_info));
- entry->next = RLB_NULL_INDEX;
- entry->prev = RLB_NULL_INDEX;
+ rlb_init_table_entry_dst(entry);
+ rlb_init_table_entry_src(entry);
+}
+
+static void rlb_delete_table_entry_dst(struct bonding *bond, u32 index)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ u32 next_index = bond_info->rx_hashtbl[index].used_next;
+ u32 prev_index = bond_info->rx_hashtbl[index].used_prev;
+
+ if (index == bond_info->rx_hashtbl_used_head)
+ bond_info->rx_hashtbl_used_head = next_index;
+ if (prev_index != RLB_NULL_INDEX)
+ bond_info->rx_hashtbl[prev_index].used_next = next_index;
+ if (next_index != RLB_NULL_INDEX)
+ bond_info->rx_hashtbl[next_index].used_prev = prev_index;
+}
+
+/* unlink a rlb hash table entry from the src list */
+static void rlb_src_unlink(struct bonding *bond, u32 index)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ u32 next_index = bond_info->rx_hashtbl[index].src_next;
+ u32 prev_index = bond_info->rx_hashtbl[index].src_prev;
+
+ bond_info->rx_hashtbl[index].src_next = RLB_NULL_INDEX;
+ bond_info->rx_hashtbl[index].src_prev = RLB_NULL_INDEX;
+
+ if (next_index != RLB_NULL_INDEX)
+ bond_info->rx_hashtbl[next_index].src_prev = prev_index;
+
+ if (prev_index == RLB_NULL_INDEX)
+ return;
+
+ /* is prev_index pointing to the head of this list? */
+ if (bond_info->rx_hashtbl[prev_index].src_first == index)
+ bond_info->rx_hashtbl[prev_index].src_first = next_index;
+ else
+ bond_info->rx_hashtbl[prev_index].src_next = next_index;
+
+}
+
+static void rlb_delete_table_entry(struct bonding *bond, u32 index)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct rlb_client_info *entry = &(bond_info->rx_hashtbl[index]);
+
+ rlb_delete_table_entry_dst(bond, index);
+ rlb_init_table_entry_dst(entry);
+
+ rlb_src_unlink(bond, index);
+}
+
+/* add the rx_hashtbl[ip_dst_hash] entry to the list
+ * of entries with identical ip_src_hash
+ */
+static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, u32 ip_dst_hash)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ u32 next;
+
+ bond_info->rx_hashtbl[ip_dst_hash].src_prev = ip_src_hash;
+ next = bond_info->rx_hashtbl[ip_src_hash].src_first;
+ bond_info->rx_hashtbl[ip_dst_hash].src_next = next;
+ if (next != RLB_NULL_INDEX)
+ bond_info->rx_hashtbl[next].src_prev = ip_dst_hash;
+ bond_info->rx_hashtbl[ip_src_hash].src_first = ip_dst_hash;
+}
+
+/* deletes all rx_hashtbl entries with arp->ip_src if their mac_src does
+ * not match arp->mac_src */
+static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ u32 ip_src_hash = _simple_hash((u8 *)&(arp->ip_src), sizeof(arp->ip_src));
+ u32 index;
+
+ _lock_rx_hashtbl_bh(bond);
+
+ index = bond_info->rx_hashtbl[ip_src_hash].src_first;
+ while (index != RLB_NULL_INDEX) {
+ struct rlb_client_info *entry = &(bond_info->rx_hashtbl[index]);
+ u32 next_index = entry->src_next;
+ if (entry->ip_src == arp->ip_src &&
+ !ether_addr_equal_64bits(arp->mac_src, entry->mac_src))
+ rlb_delete_table_entry(bond, index);
+ index = next_index;
+ }
+ _unlock_rx_hashtbl_bh(bond);
}
static int rlb_initialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
struct rlb_client_info *new_hashtbl;
int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
int i;
- spin_lock_init(&(bond_info->rx_hashtbl_lock));
-
new_hashtbl = kmalloc(size, GFP_KERNEL);
- if (!new_hashtbl) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to allocate RLB hash table\n",
- bond->dev->name);
+ if (!new_hashtbl)
return -1;
- }
- _lock_rx_hashtbl(bond);
+
+ _lock_rx_hashtbl_bh(bond);
bond_info->rx_hashtbl = new_hashtbl;
- bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
+ bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX;
- for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) {
+ for (i = 0; i < RLB_HASH_TABLE_SIZE; i++)
rlb_init_table_entry(bond_info->rx_hashtbl + i);
- }
-
- _unlock_rx_hashtbl(bond);
- /*initialize packet type*/
- pk_type->type = __constant_htons(ETH_P_ARP);
- pk_type->dev = bond->dev;
- pk_type->func = rlb_arp_recv;
+ _unlock_rx_hashtbl_bh(bond);
/* register to receive ARPs */
- dev_add_pack(pk_type);
+ bond->recv_probe = rlb_arp_recv;
return 0;
}
@@ -826,15 +963,13 @@ static void rlb_deinitialize(struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- dev_remove_pack(&(bond_info->rlb_pkt_type));
-
- _lock_rx_hashtbl(bond);
+ _lock_rx_hashtbl_bh(bond);
kfree(bond_info->rx_hashtbl);
bond_info->rx_hashtbl = NULL;
- bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
+ bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX;
- _unlock_rx_hashtbl(bond);
+ _unlock_rx_hashtbl_bh(bond);
}
static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
@@ -842,101 +977,111 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
u32 curr_index;
- _lock_rx_hashtbl(bond);
+ _lock_rx_hashtbl_bh(bond);
- curr_index = bond_info->rx_hashtbl_head;
+ curr_index = bond_info->rx_hashtbl_used_head;
while (curr_index != RLB_NULL_INDEX) {
struct rlb_client_info *curr = &(bond_info->rx_hashtbl[curr_index]);
- u32 next_index = bond_info->rx_hashtbl[curr_index].next;
- u32 prev_index = bond_info->rx_hashtbl[curr_index].prev;
+ u32 next_index = bond_info->rx_hashtbl[curr_index].used_next;
- if (curr->tag && (curr->vlan_id == vlan_id)) {
- if (curr_index == bond_info->rx_hashtbl_head) {
- bond_info->rx_hashtbl_head = next_index;
- }
- if (prev_index != RLB_NULL_INDEX) {
- bond_info->rx_hashtbl[prev_index].next = next_index;
- }
- if (next_index != RLB_NULL_INDEX) {
- bond_info->rx_hashtbl[next_index].prev = prev_index;
- }
-
- rlb_init_table_entry(curr);
- }
+ if (curr->vlan_id == vlan_id)
+ rlb_delete_table_entry(bond, curr_index);
curr_index = next_index;
}
- _unlock_rx_hashtbl(bond);
+ _unlock_rx_hashtbl_bh(bond);
}
/*********************** tlb/rlb shared functions *********************/
-static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
+static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[],
+ __be16 vlan_proto, u16 vid)
{
- struct bonding *bond = bond_get_bond_by_slave(slave);
struct learning_pkt pkt;
+ struct sk_buff *skb;
int size = sizeof(struct learning_pkt);
- int i;
+ char *data;
memset(&pkt, 0, size);
- memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
- memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
- pkt.type = __constant_htons(ETH_P_LOOP);
+ ether_addr_copy(pkt.mac_dst, mac_addr);
+ ether_addr_copy(pkt.mac_src, mac_addr);
+ pkt.type = cpu_to_be16(ETH_P_LOOPBACK);
- for (i = 0; i < MAX_LP_BURST; i++) {
- struct sk_buff *skb;
- char *data;
+ skb = dev_alloc_skb(size);
+ if (!skb)
+ return;
- skb = dev_alloc_skb(size);
+ data = skb_put(skb, size);
+ memcpy(data, &pkt, size);
+
+ skb_reset_mac_header(skb);
+ skb->network_header = skb->mac_header + ETH_HLEN;
+ skb->protocol = pkt.type;
+ skb->priority = TC_PRIO_CONTROL;
+ skb->dev = slave->dev;
+
+ if (vid) {
+ skb = vlan_put_tag(skb, vlan_proto, vid);
if (!skb) {
+ pr_err("%s: Error: failed to insert VLAN tag\n",
+ slave->bond->dev->name);
return;
}
+ }
- data = skb_put(skb, size);
- memcpy(data, &pkt, size);
-
- skb_reset_mac_header(skb);
- skb->network_header = skb->mac_header + ETH_HLEN;
- skb->protocol = pkt.type;
- skb->priority = TC_PRIO_CONTROL;
- skb->dev = slave->dev;
-
- if (!list_empty(&bond->vlan_list)) {
- struct vlan_entry *vlan;
+ dev_queue_xmit(skb);
+}
- vlan = bond_next_vlan(bond,
- bond->alb_info.current_alb_vlan);
+static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
+ bool strict_match)
+{
+ struct bonding *bond = bond_get_bond_by_slave(slave);
+ struct net_device *upper;
+ struct list_head *iter;
+ struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP];
- bond->alb_info.current_alb_vlan = vlan;
- if (!vlan) {
- kfree_skb(skb);
- continue;
- }
+ /* send untagged */
+ alb_send_lp_vid(slave, mac_addr, 0, 0);
- skb = vlan_put_tag(skb, vlan->vlan_id);
- if (!skb) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: failed to insert VLAN tag\n",
- bond->dev->name);
- continue;
+ /* loop through all devices and see if we need to send a packet
+ * for that device.
+ */
+ rcu_read_lock();
+ netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
+ if (is_vlan_dev(upper) && vlan_get_encap_level(upper) == 0) {
+ if (strict_match &&
+ ether_addr_equal_64bits(mac_addr,
+ upper->dev_addr)) {
+ alb_send_lp_vid(slave, mac_addr,
+ vlan_dev_vlan_proto(upper),
+ vlan_dev_vlan_id(upper));
+ } else if (!strict_match) {
+ alb_send_lp_vid(slave, upper->dev_addr,
+ vlan_dev_vlan_proto(upper),
+ vlan_dev_vlan_id(upper));
}
}
- dev_queue_xmit(skb);
+ /* If this is a macvlan device, then only send updates
+ * when strict_match is turned off.
+ */
+ if (netif_is_macvlan(upper) && !strict_match) {
+ memset(tags, 0, sizeof(tags));
+ bond_verify_device_path(bond->dev, upper, tags);
+ alb_send_lp_vid(slave, upper->dev_addr,
+ tags[0].vlan_proto, tags[0].vlan_id);
+ }
}
+ rcu_read_unlock();
}
-/* hw is a boolean parameter that determines whether we should try and
- * set the hw address of the device as well as the hw address of the
- * net_device
- */
-static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
+static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
{
struct net_device *dev = slave->dev;
struct sockaddr s_addr;
- if (!hw) {
+ if (BOND_MODE(slave->bond) == BOND_MODE_TLB) {
memcpy(dev->dev_addr, addr, dev->addr_len);
return 0;
}
@@ -946,12 +1091,9 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
memcpy(s_addr.sa_data, addr, dev->addr_len);
s_addr.sa_family = dev->type;
if (dev_set_mac_address(dev, &s_addr)) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
- "mode requires that the base driver support setting "
- "the hw address also when the network device's "
- "interface is open\n",
- dev->master->name, dev->name);
+ pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n"
+ "ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n",
+ slave->bond->dev->name, dev->name);
return -EOPNOTSUPP;
}
return 0;
@@ -964,13 +1106,13 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
*
*/
-static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2)
+static void alb_swap_mac_addr(struct slave *slave1, struct slave *slave2)
{
u8 tmp_mac_addr[ETH_ALEN];
- memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
- alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
- alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
+ ether_addr_copy(tmp_mac_addr, slave1->dev->dev_addr);
+ alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr);
+ alb_set_slave_mac_addr(slave2, tmp_mac_addr);
}
@@ -982,14 +1124,14 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
struct slave *slave2)
{
- int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
+ int slaves_state_differ = (bond_slave_can_tx(slave1) != bond_slave_can_tx(slave2));
struct slave *disabled_slave = NULL;
ASSERT_RTNL();
/* fasten the change in the switch */
- if (SLAVE_IS_OK(slave1)) {
- alb_send_learning_packets(slave1, slave1->dev->dev_addr);
+ if (bond_slave_can_tx(slave1)) {
+ alb_send_learning_packets(slave1, slave1->dev->dev_addr, false);
if (bond->alb_info.rlb_enabled) {
/* inform the clients that the mac address
* has changed
@@ -1000,8 +1142,8 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
disabled_slave = slave1;
}
- if (SLAVE_IS_OK(slave2)) {
- alb_send_learning_packets(slave2, slave2->dev->dev_addr);
+ if (bond_slave_can_tx(slave2)) {
+ alb_send_learning_packets(slave2, slave2->dev->dev_addr, false);
if (bond->alb_info.rlb_enabled) {
/* inform the clients that the mac address
* has changed
@@ -1037,31 +1179,20 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
{
int perm_curr_diff;
int perm_bond_diff;
+ struct slave *found_slave;
- perm_curr_diff = memcmp(slave->perm_hwaddr,
- slave->dev->dev_addr,
- ETH_ALEN);
- perm_bond_diff = memcmp(slave->perm_hwaddr,
- bond->dev->dev_addr,
- ETH_ALEN);
+ perm_curr_diff = !ether_addr_equal_64bits(slave->perm_hwaddr,
+ slave->dev->dev_addr);
+ perm_bond_diff = !ether_addr_equal_64bits(slave->perm_hwaddr,
+ bond->dev->dev_addr);
if (perm_curr_diff && perm_bond_diff) {
- struct slave *tmp_slave;
- int i, found = 0;
-
- bond_for_each_slave(bond, tmp_slave, i) {
- if (!memcmp(slave->perm_hwaddr,
- tmp_slave->dev->dev_addr,
- ETH_ALEN)) {
- found = 1;
- break;
- }
- }
+ found_slave = bond_slave_has_mac(bond, slave->perm_hwaddr);
- if (found) {
+ if (found_slave) {
/* locking: needs RTNL and nothing else */
- alb_swap_mac_addr(bond, slave, tmp_slave);
- alb_fasten_mac_swap(bond, slave, tmp_slave);
+ alb_swap_mac_addr(slave, found_slave);
+ alb_fasten_mac_swap(bond, slave, found_slave);
}
}
}
@@ -1076,7 +1207,7 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
*
* If the permanent hw address of @slave is @bond's hw address, we need to
* find a different hw address to give @slave, that isn't in use by any other
- * slave in the bond. This address must be, of course, one of the premanent
+ * slave in the bond. This address must be, of course, one of the permanent
* addresses of the other slaves.
*
* We go over the slave list, and for each slave there we compare its
@@ -1086,18 +1217,15 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
* @slave.
*
* assumption: this function is called before @slave is attached to the
- * bond slave list.
- *
- * caller must hold the bond lock for write since the mac addresses are compared
- * and may be swapped.
+ * bond slave list.
*/
static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
{
- struct slave *tmp_slave1, *tmp_slave2, *free_mac_slave;
struct slave *has_bond_addr = bond->curr_active_slave;
- int i, j, found = 0;
+ struct slave *tmp_slave1, *free_mac_slave = NULL;
+ struct list_head *iter;
- if (bond->slave_cnt == 0) {
+ if (!bond_has_slaves(bond)) {
/* this is the first slave */
return 0;
}
@@ -1106,41 +1234,20 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
* check uniqueness of slave's mac address against the other
* slaves in the bond.
*/
- if (memcmp(slave->perm_hwaddr, bond->dev->dev_addr, ETH_ALEN)) {
- bond_for_each_slave(bond, tmp_slave1, i) {
- if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr,
- ETH_ALEN)) {
- found = 1;
- break;
- }
- }
-
- if (!found)
+ if (!ether_addr_equal_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) {
+ if (!bond_slave_has_mac(bond, slave->dev->dev_addr))
return 0;
/* Try setting slave mac to bond address and fall-through
to code handling that situation below... */
- alb_set_slave_mac_addr(slave, bond->dev->dev_addr,
- bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(slave, bond->dev->dev_addr);
}
/* The slave's address is equal to the address of the bond.
* Search for a spare address in the bond for this slave.
*/
- free_mac_slave = NULL;
-
- bond_for_each_slave(bond, tmp_slave1, i) {
- found = 0;
- bond_for_each_slave(bond, tmp_slave2, j) {
- if (!memcmp(tmp_slave1->perm_hwaddr,
- tmp_slave2->dev->dev_addr,
- ETH_ALEN)) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
+ bond_for_each_slave(bond, tmp_slave1, iter) {
+ if (!bond_slave_has_mac(bond, tmp_slave1->perm_hwaddr)) {
/* no slave has tmp_slave1's perm addr
* as its curr addr
*/
@@ -1149,9 +1256,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
}
if (!has_bond_addr) {
- if (!memcmp(tmp_slave1->dev->dev_addr,
- bond->dev->dev_addr,
- ETH_ALEN)) {
+ if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr,
+ bond->dev->dev_addr)) {
has_bond_addr = tmp_slave1;
}
@@ -1159,19 +1265,14 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
}
if (free_mac_slave) {
- alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
- bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr);
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: the hw address of slave %s is in use by "
- "the bond; giving it the hw address of %s\n",
- bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
+ pr_warn("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n",
+ bond->dev->name, slave->dev->name,
+ free_mac_slave->dev->name);
} else if (has_bond_addr) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: the hw address of slave %s is in use by the "
- "bond; couldn't find a slave with a free hw address to "
- "give it (this should not have happened)\n",
+ pr_err("%s: Error: the hw address of slave %s is in use by the bond; couldn't find a slave with a free hw address to give it (this should not have happened)\n",
bond->dev->name, slave->dev->name);
return -EFAULT;
}
@@ -1195,33 +1296,26 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
*/
static int alb_set_mac_address(struct bonding *bond, void *addr)
{
+ struct slave *slave, *rollback_slave;
+ struct list_head *iter;
struct sockaddr sa;
- struct slave *slave, *stop_at;
char tmp_addr[ETH_ALEN];
int res;
- int i;
- if (bond->alb_info.rlb_enabled) {
+ if (bond->alb_info.rlb_enabled)
return 0;
- }
-
- bond_for_each_slave(bond, slave, i) {
- if (slave->dev->set_mac_address == NULL) {
- res = -EOPNOTSUPP;
- goto unwind;
- }
+ bond_for_each_slave(bond, slave, iter) {
/* save net_device's current hw address */
- memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
+ ether_addr_copy(tmp_addr, slave->dev->dev_addr);
res = dev_set_mac_address(slave->dev, addr);
/* restore net_device's hw address */
- memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
+ ether_addr_copy(slave->dev->dev_addr, tmp_addr);
- if (res) {
+ if (res)
goto unwind;
- }
}
return 0;
@@ -1231,11 +1325,12 @@ unwind:
sa.sa_family = bond->dev->type;
/* unwind from head to the slave that failed */
- stop_at = slave;
- bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
- memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
- dev_set_mac_address(slave->dev, &sa);
- memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
+ bond_for_each_slave(bond, rollback_slave, iter) {
+ if (rollback_slave == slave)
+ break;
+ ether_addr_copy(tmp_addr, rollback_slave->dev->dev_addr);
+ dev_set_mac_address(rollback_slave->dev, &sa);
+ ether_addr_copy(rollback_slave->dev->dev_addr, tmp_addr);
}
return res;
@@ -1248,9 +1343,8 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
int res;
res = tlb_initialize(bond);
- if (res) {
+ if (res)
return res;
- }
if (rlb_enabled) {
bond->alb_info.rlb_enabled = 1;
@@ -1273,45 +1367,105 @@ void bond_alb_deinitialize(struct bonding *bond)
tlb_deinitialize(bond);
- if (bond_info->rlb_enabled) {
+ if (bond_info->rlb_enabled)
rlb_deinitialize(bond);
+}
+
+static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
+ struct slave *tx_slave)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct ethhdr *eth_data = eth_hdr(skb);
+
+ if (!tx_slave) {
+ /* unbalanced or unassigned, send through primary */
+ tx_slave = rcu_dereference(bond->curr_active_slave);
+ if (bond->params.tlb_dynamic_lb)
+ bond_info->unbalanced_load += skb->len;
+ }
+
+ if (tx_slave && bond_slave_can_tx(tx_slave)) {
+ if (tx_slave != rcu_dereference(bond->curr_active_slave)) {
+ ether_addr_copy(eth_data->h_source,
+ tx_slave->dev->dev_addr);
+ }
+
+ bond_dev_queue_xmit(bond, skb, tx_slave->dev);
+ goto out;
+ }
+
+ if (tx_slave && bond->params.tlb_dynamic_lb) {
+ _lock_tx_hashtbl(bond);
+ __tlb_clear_slave(bond, tx_slave, 0);
+ _unlock_tx_hashtbl(bond);
+ }
+
+ /* no suitable interface, frame not sent */
+ dev_kfree_skb_any(skb);
+out:
+ return NETDEV_TX_OK;
+}
+
+int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct ethhdr *eth_data;
+ struct slave *tx_slave = NULL;
+ u32 hash_index;
+
+ skb_reset_mac_header(skb);
+ eth_data = eth_hdr(skb);
+
+ /* Do not TX balance any multicast or broadcast */
+ if (!is_multicast_ether_addr(eth_data->h_dest)) {
+ switch (skb->protocol) {
+ case htons(ETH_P_IP):
+ case htons(ETH_P_IPX):
+ /* In case of IPX, it will falback to L2 hash */
+ case htons(ETH_P_IPV6):
+ hash_index = bond_xmit_hash(bond, skb);
+ if (bond->params.tlb_dynamic_lb) {
+ tx_slave = tlb_choose_channel(bond,
+ hash_index & 0xFF,
+ skb->len);
+ } else {
+ struct list_head *iter;
+ int idx = hash_index % bond->slave_cnt;
+
+ bond_for_each_slave_rcu(bond, tx_slave, iter)
+ if (--idx < 0)
+ break;
+ }
+ break;
+ }
}
+ return bond_do_alb_xmit(skb, bond, tx_slave);
}
int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
struct ethhdr *eth_data;
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct slave *tx_slave = NULL;
static const __be32 ip_bcast = htonl(0xffffffff);
int hash_size = 0;
- int do_tx_balance = 1;
+ bool do_tx_balance = true;
u32 hash_index = 0;
const u8 *hash_start = NULL;
- int res = 1;
+ struct ipv6hdr *ip6hdr;
skb_reset_mac_header(skb);
eth_data = eth_hdr(skb);
- /* make sure that the curr_active_slave and the slaves list do
- * not change during tx
- */
- read_lock(&bond->lock);
- read_lock(&bond->curr_slave_lock);
-
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
-
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
const struct iphdr *iph = ip_hdr(skb);
- if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
+ if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) ||
(iph->daddr == ip_bcast) ||
(iph->protocol == IPPROTO_IGMP)) {
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
hash_start = (char *)&(iph->daddr);
@@ -1319,8 +1473,29 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
}
break;
case ETH_P_IPV6:
- if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
- do_tx_balance = 0;
+ /* IPv6 doesn't really use broadcast mac address, but leave
+ * that here just in case.
+ */
+ if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast)) {
+ do_tx_balance = false;
+ break;
+ }
+
+ /* IPv6 uses all-nodes multicast as an equivalent to
+ * broadcasts in IPv4.
+ */
+ if (ether_addr_equal_64bits(eth_data->h_dest, mac_v6_allmcast)) {
+ do_tx_balance = false;
+ break;
+ }
+
+ /* Additianally, DAD probes should not be tx-balanced as that
+ * will lead to false positives for duplicate addresses and
+ * prevent address configuration from working.
+ */
+ ip6hdr = ipv6_hdr(skb);
+ if (ipv6_addr_any(&ip6hdr->saddr)) {
+ do_tx_balance = false;
break;
}
@@ -1330,7 +1505,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
case ETH_P_IPX:
if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) {
/* something is wrong with this packet */
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1339,21 +1514,20 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
* this family since it has an "ARP" like
* mechanism
*/
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
- hash_start = (char*)eth_data->h_dest;
+ hash_start = (char *)eth_data->h_dest;
hash_size = ETH_ALEN;
break;
case ETH_P_ARP:
- do_tx_balance = 0;
- if (bond_info->rlb_enabled) {
+ do_tx_balance = false;
+ if (bond_info->rlb_enabled)
tx_slave = rlb_arp_xmit(skb, bond);
- }
break;
default:
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1362,34 +1536,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
tx_slave = tlb_choose_channel(bond, hash_index, skb->len);
}
- if (!tx_slave) {
- /* unbalanced or unassigned, send through primary */
- tx_slave = bond->curr_active_slave;
- bond_info->unbalanced_load += skb->len;
- }
-
- if (tx_slave && SLAVE_IS_OK(tx_slave)) {
- if (tx_slave != bond->curr_active_slave) {
- memcpy(eth_data->h_source,
- tx_slave->dev->dev_addr,
- ETH_ALEN);
- }
-
- res = bond_dev_queue_xmit(bond, skb, tx_slave->dev);
- } else {
- if (tx_slave) {
- tlb_clear_slave(bond, tx_slave, 0);
- }
- }
-
-out:
- if (res) {
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
- }
- read_unlock(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
- return 0;
+ return bond_do_alb_xmit(skb, bond, tx_slave);
}
void bond_alb_monitor(struct work_struct *work)
@@ -1397,26 +1544,24 @@ void bond_alb_monitor(struct work_struct *work)
struct bonding *bond = container_of(work, struct bonding,
alb_work.work);
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct list_head *iter;
struct slave *slave;
- int i;
-
- read_lock(&bond->lock);
- if (bond->kill_timers) {
- goto out;
- }
-
- if (bond->slave_cnt == 0) {
+ if (!bond_has_slaves(bond)) {
bond_info->tx_rebalance_counter = 0;
bond_info->lp_counter = 0;
goto re_arm;
}
+ rcu_read_lock();
+
bond_info->tx_rebalance_counter++;
bond_info->lp_counter++;
/* send learning packets */
- if (bond_info->lp_counter >= BOND_ALB_LP_TICKS) {
+ if (bond_info->lp_counter >= BOND_ALB_LP_TICKS(bond)) {
+ bool strict_match;
+
/* change of curr_active_slave involves swapping of mac addresses.
* in order to avoid this swapping from happening while
* sending the learning packets, the curr_slave_lock must be held for
@@ -1424,8 +1569,16 @@ void bond_alb_monitor(struct work_struct *work)
*/
read_lock(&bond->curr_slave_lock);
- bond_for_each_slave(bond, slave, i) {
- alb_send_learning_packets(slave, slave->dev->dev_addr);
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ /* If updating current_active, use all currently
+ * user mac addreses (!strict_match). Otherwise, only
+ * use mac of the slave device.
+ * In RLB mode, we always use strict matches.
+ */
+ strict_match = (slave != bond->curr_active_slave ||
+ bond_info->rlb_enabled);
+ alb_send_learning_packets(slave, slave->dev->dev_addr,
+ strict_match);
}
read_unlock(&bond->curr_slave_lock);
@@ -1438,7 +1591,7 @@ void bond_alb_monitor(struct work_struct *work)
read_lock(&bond->curr_slave_lock);
- bond_for_each_slave(bond, slave, i) {
+ bond_for_each_slave_rcu(bond, slave, iter) {
tlb_clear_slave(bond, slave, 1);
if (slave == bond->curr_active_slave) {
SLAVE_TLB_INFO(slave).load =
@@ -1460,10 +1613,11 @@ void bond_alb_monitor(struct work_struct *work)
/*
* dev_set_promiscuity requires rtnl and
- * nothing else.
+ * nothing else. Avoid race with bond_close.
*/
- read_unlock(&bond->lock);
- rtnl_lock();
+ rcu_read_unlock();
+ if (!rtnl_trylock())
+ goto re_arm;
bond_info->rlb_promisc_timeout_counter = 0;
@@ -1475,7 +1629,7 @@ void bond_alb_monitor(struct work_struct *work)
bond_info->primary_is_promisc = 0;
rtnl_unlock();
- read_lock(&bond->lock);
+ rcu_read_lock();
}
if (bond_info->rlb_rebalance) {
@@ -1489,19 +1643,16 @@ void bond_alb_monitor(struct work_struct *work)
--bond_info->rlb_update_delay_counter;
} else {
rlb_update_rx_clients(bond);
- if (bond_info->rlb_update_retry_counter) {
+ if (bond_info->rlb_update_retry_counter)
--bond_info->rlb_update_retry_counter;
- } else {
+ else
bond_info->rx_ntt = 0;
- }
}
}
}
-
+ rcu_read_unlock();
re_arm:
queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks);
-out:
- read_unlock(&bond->lock);
}
/* assumption: called before the slave is attached to the bond
@@ -1511,33 +1662,21 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
{
int res;
- res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
- bond->alb_info.rlb_enabled);
- if (res) {
+ res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr);
+ if (res)
return res;
- }
-
- /* caller must hold the bond lock for write since the mac addresses
- * are compared and may be swapped.
- */
- read_lock(&bond->lock);
res = alb_handle_addr_collision_on_attach(bond, slave);
-
- read_unlock(&bond->lock);
-
- if (res) {
+ if (res)
return res;
- }
tlb_init_slave(slave);
/* order a rebalance ASAP */
bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
- if (bond->alb_info.rlb_enabled) {
+ if (bond->alb_info.rlb_enabled)
bond->alb_info.rlb_rebalance = 1;
- }
return 0;
}
@@ -1550,14 +1689,13 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
*/
void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
{
- if (bond->slave_cnt > 1) {
+ if (bond_has_slaves(bond))
alb_change_hw_addr_on_detach(bond, slave);
- }
tlb_clear_slave(bond, slave, 0);
if (bond->alb_info.rlb_enabled) {
- bond->alb_info.next_rx_slave = NULL;
+ bond->alb_info.rx_slave = NULL;
rlb_clear_slave(bond, slave);
}
}
@@ -1569,9 +1707,8 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
if (link == BOND_LINK_DOWN) {
tlb_clear_slave(bond, slave, 0);
- if (bond->alb_info.rlb_enabled) {
+ if (bond->alb_info.rlb_enabled)
rlb_clear_slave(bond, slave);
- }
} else if (link == BOND_LINK_UP) {
/* order a rebalance ASAP */
bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS;
@@ -1597,18 +1734,17 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
* If new_slave is NULL, caller must hold curr_slave_lock or
* bond->lock for write.
*
- * If new_slave is not NULL, caller must hold RTNL, bond->lock for
- * read and curr_slave_lock for write. Processing here may sleep, so
- * no other locks may be held.
+ * If new_slave is not NULL, caller must hold RTNL, curr_slave_lock
+ * for write. Processing here may sleep, so no other locks may be held.
*/
void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
+ __releases(&bond->curr_slave_lock)
+ __acquires(&bond->curr_slave_lock)
{
struct slave *swap_slave;
- int i;
- if (bond->curr_active_slave == new_slave) {
+ if (bond->curr_active_slave == new_slave)
return;
- }
if (bond->curr_active_slave && bond->alb_info.primary_is_promisc) {
dev_set_promiscuity(bond->curr_active_slave->dev, -1);
@@ -1617,58 +1753,57 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
}
swap_slave = bond->curr_active_slave;
- bond->curr_active_slave = new_slave;
+ rcu_assign_pointer(bond->curr_active_slave, new_slave);
- if (!new_slave || (bond->slave_cnt == 0)) {
+ if (!new_slave || !bond_has_slaves(bond))
return;
- }
/* set the new curr_active_slave to the bonds mac address
* i.e. swap mac addresses of old curr_active_slave and new curr_active_slave
*/
- if (!swap_slave) {
- struct slave *tmp_slave;
- /* find slave that is holding the bond's mac address */
- bond_for_each_slave(bond, tmp_slave, i) {
- if (!memcmp(tmp_slave->dev->dev_addr,
- bond->dev->dev_addr, ETH_ALEN)) {
- swap_slave = tmp_slave;
- break;
- }
- }
- }
+ if (!swap_slave)
+ swap_slave = bond_slave_has_mac(bond, bond->dev->dev_addr);
/*
* Arrange for swap_slave and new_slave to temporarily be
* ignored so we can mess with their MAC addresses without
* fear of interference from transmit activity.
*/
- if (swap_slave) {
+ if (swap_slave)
tlb_clear_slave(bond, swap_slave, 1);
- }
tlb_clear_slave(bond, new_slave, 1);
write_unlock_bh(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
ASSERT_RTNL();
- /* curr_active_slave must be set before calling alb_swap_mac_addr */
- if (swap_slave) {
- /* swap mac address */
- alb_swap_mac_addr(bond, swap_slave, new_slave);
- } else {
- /* set the new_slave to the bond mac address */
- alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
- bond->alb_info.rlb_enabled);
+ /* in TLB mode, the slave might flip down/up with the old dev_addr,
+ * and thus filter bond->dev_addr's packets, so force bond's mac
+ */
+ if (BOND_MODE(bond) == BOND_MODE_TLB) {
+ struct sockaddr sa;
+ u8 tmp_addr[ETH_ALEN];
+
+ ether_addr_copy(tmp_addr, new_slave->dev->dev_addr);
+
+ memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len);
+ sa.sa_family = bond->dev->type;
+ /* we don't care if it can't change its mac, best effort */
+ dev_set_mac_address(new_slave->dev, &sa);
+
+ ether_addr_copy(new_slave->dev->dev_addr, tmp_addr);
}
+ /* curr_active_slave must be set before calling alb_swap_mac_addr */
if (swap_slave) {
+ /* swap mac address */
+ alb_swap_mac_addr(swap_slave, new_slave);
alb_fasten_mac_swap(bond, swap_slave, new_slave);
- read_lock(&bond->lock);
} else {
- read_lock(&bond->lock);
- alb_send_learning_packets(new_slave, bond->dev->dev_addr);
+ /* set the new_slave to the bond mac address */
+ alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr);
+ alb_send_learning_packets(new_slave, bond->dev->dev_addr,
+ false);
}
write_lock_bh(&bond->curr_slave_lock);
@@ -1678,21 +1813,20 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
* Called with RTNL
*/
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
+ __acquires(&bond->lock)
+ __releases(&bond->lock)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
struct sockaddr *sa = addr;
- struct slave *slave, *swap_slave;
+ struct slave *swap_slave;
int res;
- int i;
- if (!is_valid_ether_addr(sa->sa_data)) {
+ if (!is_valid_ether_addr(sa->sa_data))
return -EADDRNOTAVAIL;
- }
res = alb_set_mac_address(bond, addr);
- if (res) {
+ if (res)
return res;
- }
memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len);
@@ -1700,51 +1834,33 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
* Otherwise we'll need to pass the new address to it and handle
* duplications.
*/
- if (!bond->curr_active_slave) {
+ if (!bond->curr_active_slave)
return 0;
- }
-
- swap_slave = NULL;
-
- bond_for_each_slave(bond, slave, i) {
- if (!memcmp(slave->dev->dev_addr, bond_dev->dev_addr, ETH_ALEN)) {
- swap_slave = slave;
- break;
- }
- }
- write_unlock_bh(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
+ swap_slave = bond_slave_has_mac(bond, bond_dev->dev_addr);
if (swap_slave) {
- alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
+ alb_swap_mac_addr(swap_slave, bond->curr_active_slave);
alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave);
} else {
- alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
- bond->alb_info.rlb_enabled);
+ alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr);
- alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr);
+ read_lock(&bond->lock);
+ alb_send_learning_packets(bond->curr_active_slave,
+ bond_dev->dev_addr, false);
if (bond->alb_info.rlb_enabled) {
/* inform clients mac address has changed */
rlb_req_update_slave_clients(bond, bond->curr_active_slave);
}
+ read_unlock(&bond->lock);
}
- read_lock(&bond->lock);
- write_lock_bh(&bond->curr_slave_lock);
-
return 0;
}
void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
{
- if (bond->alb_info.current_alb_vlan &&
- (bond->alb_info.current_alb_vlan->vlan_id == vlan_id)) {
- bond->alb_info.current_alb_vlan = NULL;
- }
-
- if (bond->alb_info.rlb_enabled) {
+ if (bond->alb_info.rlb_enabled)
rlb_clear_vlan(bond, vlan_id);
- }
}
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 50968f8196c..5fc76c01636 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -12,8 +12,7 @@
* for more details.
*
* You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
@@ -31,14 +30,52 @@ struct slave;
#define BOND_ALB_INFO(bond) ((bond)->alb_info)
#define SLAVE_TLB_INFO(slave) ((slave)->tlb_info)
+#define ALB_TIMER_TICKS_PER_SEC 10 /* should be a divisor of HZ */
+#define BOND_TLB_REBALANCE_INTERVAL 10 /* In seconds, periodic re-balancing.
+ * Used for division - never set
+ * to zero !!!
+ */
+#define BOND_ALB_DEFAULT_LP_INTERVAL 1
+#define BOND_ALB_LP_INTERVAL(bond) (bond->params.lp_interval) /* In seconds, periodic send of
+ * learning packets to the switch
+ */
+
+#define BOND_TLB_REBALANCE_TICKS (BOND_TLB_REBALANCE_INTERVAL \
+ * ALB_TIMER_TICKS_PER_SEC)
+
+#define BOND_ALB_LP_TICKS(bond) (BOND_ALB_LP_INTERVAL(bond) \
+ * ALB_TIMER_TICKS_PER_SEC)
+
+#define TLB_HASH_TABLE_SIZE 256 /* The size of the clients hash table.
+ * Note that this value MUST NOT be smaller
+ * because the key hash table is BYTE wide !
+ */
+
+
+#define TLB_NULL_INDEX 0xffffffff
+
+/* rlb defs */
+#define RLB_HASH_TABLE_SIZE 256
+#define RLB_NULL_INDEX 0xffffffff
+#define RLB_UPDATE_DELAY (2*ALB_TIMER_TICKS_PER_SEC) /* 2 seconds */
+#define RLB_ARP_BURST_SIZE 2
+#define RLB_UPDATE_RETRY 3 /* 3-ticks - must be smaller than the rlb
+ * rebalance interval (5 min).
+ */
+/* RLB_PROMISC_TIMEOUT = 10 sec equals the time that the current slave is
+ * promiscuous after failover
+ */
+#define RLB_PROMISC_TIMEOUT (10*ALB_TIMER_TICKS_PER_SEC)
+
+
struct tlb_client_info {
struct slave *tx_slave; /* A pointer to slave used for transmiting
* packets to a Client that the Hash function
* gave this entry index.
*/
- u32 tx_bytes; /* Each Client acumulates the BytesTx that
- * were tranmitted to it, and after each
- * CallBack the LoadHistory is devided
+ u32 tx_bytes; /* Each Client accumulates the BytesTx that
+ * were transmitted to it, and after each
+ * CallBack the LoadHistory is divided
* by the balance interval
*/
u32 load_history; /* This field contains the amount of Bytes
@@ -56,19 +93,38 @@ struct tlb_client_info {
/* -------------------------------------------------------------------------
* struct rlb_client_info contains all info related to a specific rx client
- * connection. This is the Clients Hash Table entry struct
+ * connection. This is the Clients Hash Table entry struct.
+ * Note that this is not a proper hash table; if a new client's IP address
+ * hash collides with an existing client entry, the old entry is replaced.
+ *
+ * There is a linked list (linked by the used_next and used_prev members)
+ * linking all the used entries of the hash table. This allows updating
+ * all the clients without walking over all the unused elements of the table.
+ *
+ * There are also linked lists of entries with identical hash(ip_src). These
+ * allow cleaning up the table from ip_src<->mac_src associations that have
+ * become outdated and would cause sending out invalid ARP updates to the
+ * network. These are linked by the (src_next and src_prev members).
* -------------------------------------------------------------------------
*/
struct rlb_client_info {
__be32 ip_src; /* the server IP address */
__be32 ip_dst; /* the client IP address */
+ u8 mac_src[ETH_ALEN]; /* the server MAC address */
u8 mac_dst[ETH_ALEN]; /* the client MAC address */
- u32 next; /* The next Hash table entry index */
- u32 prev; /* The previous Hash table entry index */
+
+ /* list of used hash table entries, starting at rx_hashtbl_used_head */
+ u32 used_next;
+ u32 used_prev;
+
+ /* ip_src based hashing */
+ u32 src_next; /* next entry with same hash(ip_src) */
+ u32 src_prev; /* prev entry with same hash(ip_src) */
+ u32 src_first; /* first entry with hash(ip_src) == this entry's index */
+
u8 assigned; /* checking whether this entry is assigned */
u8 ntt; /* flag - need to transmit client info */
struct slave *slave; /* the slave assigned to this client */
- u8 tag; /* flag - need to tag skb */
unsigned short vlan_id; /* VLAN tag associated with IP address */
};
@@ -84,7 +140,6 @@ struct tlb_slave_info {
};
struct alb_bond_info {
- struct timer_list alb_timer;
struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
spinlock_t tx_hashtbl_lock;
u32 unbalanced_load;
@@ -92,17 +147,13 @@ struct alb_bond_info {
int lp_counter;
/* -------- rlb parameters -------- */
int rlb_enabled;
- struct packet_type rlb_pkt_type;
struct rlb_client_info *rx_hashtbl; /* Receive hash table */
spinlock_t rx_hashtbl_lock;
- u32 rx_hashtbl_head;
+ u32 rx_hashtbl_used_head;
u8 rx_ntt; /* flag - need to transmit
* to all rx clients
*/
- struct slave *next_rx_slave;/* next slave to be assigned
- * to a new rx client for
- */
- u32 rlb_interval_counter;
+ struct slave *rx_slave;/* last slave to xmit from */
u8 primary_is_promisc; /* boolean */
u32 rlb_promisc_timeout_counter;/* counts primary
* promiscuity time
@@ -115,7 +166,6 @@ struct alb_bond_info {
* rx traffic should be
* rebalanced
*/
- struct vlan_entry *current_alb_vlan;
};
int bond_alb_initialize(struct bonding *bond, int rlb_enabled);
@@ -125,6 +175,7 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
void bond_alb_monitor(struct work_struct *);
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c
new file mode 100644
index 00000000000..658e761c456
--- /dev/null
+++ b/drivers/net/bonding/bond_debugfs.c
@@ -0,0 +1,145 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+
+#include "bonding.h"
+#include "bond_alb.h"
+
+#if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_NET_NS)
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static struct dentry *bonding_debug_root;
+
+/*
+ * Show RLB hash table
+ */
+static int bond_debug_rlb_hash_show(struct seq_file *m, void *v)
+{
+ struct bonding *bond = m->private;
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct rlb_client_info *client_info;
+ u32 hash_index;
+
+ if (BOND_MODE(bond) != BOND_MODE_ALB)
+ return 0;
+
+ seq_printf(m, "SourceIP DestinationIP "
+ "Destination MAC DEV\n");
+
+ spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+
+ hash_index = bond_info->rx_hashtbl_used_head;
+ for (; hash_index != RLB_NULL_INDEX;
+ hash_index = client_info->used_next) {
+ client_info = &(bond_info->rx_hashtbl[hash_index]);
+ seq_printf(m, "%-15pI4 %-15pI4 %-17pM %s\n",
+ &client_info->ip_src,
+ &client_info->ip_dst,
+ &client_info->mac_dst,
+ client_info->slave->dev->name);
+ }
+
+ spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+
+ return 0;
+}
+
+static int bond_debug_rlb_hash_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, bond_debug_rlb_hash_show, inode->i_private);
+}
+
+static const struct file_operations bond_debug_rlb_hash_fops = {
+ .owner = THIS_MODULE,
+ .open = bond_debug_rlb_hash_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+void bond_debug_register(struct bonding *bond)
+{
+ if (!bonding_debug_root)
+ return;
+
+ bond->debug_dir =
+ debugfs_create_dir(bond->dev->name, bonding_debug_root);
+
+ if (!bond->debug_dir) {
+ pr_warn("%s: Warning: failed to register to debugfs\n",
+ bond->dev->name);
+ return;
+ }
+
+ debugfs_create_file("rlb_hash_table", 0400, bond->debug_dir,
+ bond, &bond_debug_rlb_hash_fops);
+}
+
+void bond_debug_unregister(struct bonding *bond)
+{
+ if (!bonding_debug_root)
+ return;
+
+ debugfs_remove_recursive(bond->debug_dir);
+}
+
+void bond_debug_reregister(struct bonding *bond)
+{
+ struct dentry *d;
+
+ if (!bonding_debug_root)
+ return;
+
+ d = debugfs_rename(bonding_debug_root, bond->debug_dir,
+ bonding_debug_root, bond->dev->name);
+ if (d) {
+ bond->debug_dir = d;
+ } else {
+ pr_warn("%s: Warning: failed to reregister, so just unregister old one\n",
+ bond->dev->name);
+ bond_debug_unregister(bond);
+ }
+}
+
+void bond_create_debugfs(void)
+{
+ bonding_debug_root = debugfs_create_dir("bonding", NULL);
+
+ if (!bonding_debug_root) {
+ pr_warn("Warning: Cannot create bonding directory in debugfs\n");
+ }
+}
+
+void bond_destroy_debugfs(void)
+{
+ debugfs_remove_recursive(bonding_debug_root);
+ bonding_debug_root = NULL;
+}
+
+
+#else /* !CONFIG_DEBUG_FS */
+
+void bond_debug_register(struct bonding *bond)
+{
+}
+
+void bond_debug_unregister(struct bonding *bond)
+{
+}
+
+void bond_debug_reregister(struct bonding *bond)
+{
+}
+
+void bond_create_debugfs(void)
+{
+}
+
+void bond_destroy_debugfs(void)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c792138511e..701f86cd599 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -31,7 +31,7 @@
*
*/
-//#define BONDING_DEBUG 1
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
@@ -53,10 +53,9 @@
#include <linux/ctype.h>
#include <linux/inet.h>
#include <linux/bitops.h>
-#include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/dma.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
@@ -65,8 +64,6 @@
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/rtnetlink.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <linux/smp.h>
#include <linux/if_ether.h>
#include <net/arp.h>
@@ -75,8 +72,13 @@
#include <linux/if_vlan.h>
#include <linux/if_bonding.h>
#include <linux/jiffies.h>
+#include <linux/preempt.h>
#include <net/route.h>
#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+#include <net/pkt_sched.h>
+#include <linux/rculist.h>
+#include <net/flow_keys.h>
#include "bonding.h"
#include "bond_3ad.h"
#include "bond_alb.h"
@@ -84,29 +86,42 @@
/*---------------------------- Module parameters ----------------------------*/
/* monitor all links that often (in milliseconds). <=0 disables monitoring */
-#define BOND_LINK_MON_INTERV 0
-#define BOND_LINK_ARP_INTERV 0
static int max_bonds = BOND_DEFAULT_MAX_BONDS;
-static int num_grat_arp = 1;
-static int miimon = BOND_LINK_MON_INTERV;
-static int updelay = 0;
-static int downdelay = 0;
+static int tx_queues = BOND_DEFAULT_TX_QUEUES;
+static int num_peer_notif = 1;
+static int miimon;
+static int updelay;
+static int downdelay;
static int use_carrier = 1;
-static char *mode = NULL;
-static char *primary = NULL;
-static char *lacp_rate = NULL;
-static char *xmit_hash_policy = NULL;
-static int arp_interval = BOND_LINK_ARP_INTERV;
-static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
-static char *arp_validate = NULL;
-static char *fail_over_mac = NULL;
-struct bond_params bonding_defaults;
+static char *mode;
+static char *primary;
+static char *primary_reselect;
+static char *lacp_rate;
+static int min_links;
+static char *ad_select;
+static char *xmit_hash_policy;
+static int arp_interval;
+static char *arp_ip_target[BOND_MAX_ARP_TARGETS];
+static char *arp_validate;
+static char *arp_all_targets;
+static char *fail_over_mac;
+static int all_slaves_active;
+static struct bond_params bonding_defaults;
+static int resend_igmp = BOND_DEFAULT_RESEND_IGMP;
+static int packets_per_slave = 1;
+static int lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
module_param(max_bonds, int, 0);
MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
-module_param(num_grat_arp, int, 0644);
-MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
+module_param(tx_queues, int, 0);
+MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)");
+module_param_named(num_grat_arp, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on "
+ "failover event (alias of num_unsol_na)");
+module_param_named(num_unsol_na, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on "
+ "failover event (alias of num_grat_arp)");
module_param(miimon, int, 0);
MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
module_param(updelay, int, 0);
@@ -118,314 +133,136 @@ module_param(use_carrier, int, 0);
MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
"0 for off, 1 for on (default)");
module_param(mode, charp, 0);
-MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
+MODULE_PARM_DESC(mode, "Mode of operation; 0 for balance-rr, "
"1 for active-backup, 2 for balance-xor, "
"3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
"6 for balance-alb");
module_param(primary, charp, 0);
MODULE_PARM_DESC(primary, "Primary network device to use");
+module_param(primary_reselect, charp, 0);
+MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
+ "once it comes up; "
+ "0 for always (default), "
+ "1 for only if speed of primary is "
+ "better, "
+ "2 for only on active slave "
+ "failure");
module_param(lacp_rate, charp, 0);
-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
- "(slow/fast)");
+MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner; "
+ "0 for slow, 1 for fast");
+module_param(ad_select, charp, 0);
+MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic; "
+ "0 for stable (default), 1 for bandwidth, "
+ "2 for count");
+module_param(min_links, int, 0);
+MODULE_PARM_DESC(min_links, "Minimum number of available links before turning on carrier");
+
module_param(xmit_hash_policy, charp, 0);
-MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
- ", 1 for layer 3+4");
+MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; "
+ "0 for layer 2 (default), 1 for layer 3+4, "
+ "2 for layer 2+3, 3 for encap layer 2+3, "
+ "4 for encap layer 3+4");
module_param(arp_interval, int, 0);
MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
module_param_array(arp_ip_target, charp, NULL, 0);
MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
module_param(arp_validate, charp, 0);
-MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
+MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes; "
+ "0 for none (default), 1 for active, "
+ "2 for backup, 3 for all");
+module_param(arp_all_targets, charp, 0);
+MODULE_PARM_DESC(arp_all_targets, "fail on any/all arp targets timeout; 0 for any (default), 1 for all");
module_param(fail_over_mac, charp, 0);
-MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow");
+MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to "
+ "the same MAC; 0 for none (default), "
+ "1 for active, 2 for follow");
+module_param(all_slaves_active, int, 0);
+MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface"
+ "by setting active flag for all slaves; "
+ "0 for never (default), 1 for always.");
+module_param(resend_igmp, int, 0);
+MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on "
+ "link failure");
+module_param(packets_per_slave, int, 0);
+MODULE_PARM_DESC(packets_per_slave, "Packets to send per slave in balance-rr "
+ "mode; 0 for a random slave, 1 packet per "
+ "slave (default), >1 packets per slave.");
+module_param(lp_interval, uint, 0);
+MODULE_PARM_DESC(lp_interval, "The number of seconds between instances where "
+ "the bonding driver sends learning packets to "
+ "each slaves peer switch. The default is 1.");
/*----------------------------- Global variables ----------------------------*/
-static const char * const version =
- DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
-
-LIST_HEAD(bond_dev_list);
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *bond_proc_dir = NULL;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+atomic_t netpoll_block_tx = ATOMIC_INIT(0);
#endif
-extern struct rw_semaphore bonding_rwsem;
-static __be32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
-static int arp_ip_count = 0;
-static int bond_mode = BOND_MODE_ROUNDROBIN;
-static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
-static int lacp_fast = 0;
-
-
-struct bond_parm_tbl bond_lacp_tbl[] = {
-{ "slow", AD_LACP_SLOW},
-{ "fast", AD_LACP_FAST},
-{ NULL, -1},
-};
-
-struct bond_parm_tbl bond_mode_tbl[] = {
-{ "balance-rr", BOND_MODE_ROUNDROBIN},
-{ "active-backup", BOND_MODE_ACTIVEBACKUP},
-{ "balance-xor", BOND_MODE_XOR},
-{ "broadcast", BOND_MODE_BROADCAST},
-{ "802.3ad", BOND_MODE_8023AD},
-{ "balance-tlb", BOND_MODE_TLB},
-{ "balance-alb", BOND_MODE_ALB},
-{ NULL, -1},
-};
-
-struct bond_parm_tbl xmit_hashtype_tbl[] = {
-{ "layer2", BOND_XMIT_POLICY_LAYER2},
-{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
-{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
-{ NULL, -1},
-};
-
-struct bond_parm_tbl arp_validate_tbl[] = {
-{ "none", BOND_ARP_VALIDATE_NONE},
-{ "active", BOND_ARP_VALIDATE_ACTIVE},
-{ "backup", BOND_ARP_VALIDATE_BACKUP},
-{ "all", BOND_ARP_VALIDATE_ALL},
-{ NULL, -1},
-};
+int bond_net_id __read_mostly;
-struct bond_parm_tbl fail_over_mac_tbl[] = {
-{ "none", BOND_FOM_NONE},
-{ "active", BOND_FOM_ACTIVE},
-{ "follow", BOND_FOM_FOLLOW},
-{ NULL, -1},
-};
+static __be32 arp_target[BOND_MAX_ARP_TARGETS];
+static int arp_ip_count;
+static int bond_mode = BOND_MODE_ROUNDROBIN;
+static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
+static int lacp_fast;
/*-------------------------- Forward declarations ---------------------------*/
-static void bond_send_gratuitous_arp(struct bonding *bond);
-static void bond_deinit(struct net_device *bond_dev);
+static int bond_init(struct net_device *bond_dev);
+static void bond_uninit(struct net_device *bond_dev);
/*---------------------------- General routines -----------------------------*/
-static const char *bond_mode_name(int mode)
+const char *bond_mode_name(int mode)
{
- switch (mode) {
- case BOND_MODE_ROUNDROBIN :
- return "load balancing (round-robin)";
- case BOND_MODE_ACTIVEBACKUP :
- return "fault-tolerance (active-backup)";
- case BOND_MODE_XOR :
- return "load balancing (xor)";
- case BOND_MODE_BROADCAST :
- return "fault-tolerance (broadcast)";
- case BOND_MODE_8023AD:
- return "IEEE 802.3ad Dynamic link aggregation";
- case BOND_MODE_TLB:
- return "transmit load balancing";
- case BOND_MODE_ALB:
- return "adaptive load balancing";
- default:
+ static const char *names[] = {
+ [BOND_MODE_ROUNDROBIN] = "load balancing (round-robin)",
+ [BOND_MODE_ACTIVEBACKUP] = "fault-tolerance (active-backup)",
+ [BOND_MODE_XOR] = "load balancing (xor)",
+ [BOND_MODE_BROADCAST] = "fault-tolerance (broadcast)",
+ [BOND_MODE_8023AD] = "IEEE 802.3ad Dynamic link aggregation",
+ [BOND_MODE_TLB] = "transmit load balancing",
+ [BOND_MODE_ALB] = "adaptive load balancing",
+ };
+
+ if (mode < BOND_MODE_ROUNDROBIN || mode > BOND_MODE_ALB)
return "unknown";
- }
-}
-
-/*---------------------------------- VLAN -----------------------------------*/
-
-/**
- * bond_add_vlan - add a new vlan id on bond
- * @bond: bond that got the notification
- * @vlan_id: the vlan id to add
- *
- * Returns -ENOMEM if allocation failed.
- */
-static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
-{
- struct vlan_entry *vlan;
-
- dprintk("bond: %s, vlan id %d\n",
- (bond ? bond->dev->name: "None"), vlan_id);
-
- vlan = kmalloc(sizeof(struct vlan_entry), GFP_KERNEL);
- if (!vlan) {
- return -ENOMEM;
- }
-
- INIT_LIST_HEAD(&vlan->vlan_list);
- vlan->vlan_id = vlan_id;
- vlan->vlan_ip = 0;
-
- write_lock_bh(&bond->lock);
-
- list_add_tail(&vlan->vlan_list, &bond->vlan_list);
-
- write_unlock_bh(&bond->lock);
-
- dprintk("added VLAN ID %d on bond %s\n", vlan_id, bond->dev->name);
-
- return 0;
-}
-
-/**
- * bond_del_vlan - delete a vlan id from bond
- * @bond: bond that got the notification
- * @vlan_id: the vlan id to delete
- *
- * returns -ENODEV if @vlan_id was not found in @bond.
- */
-static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id)
-{
- struct vlan_entry *vlan;
- int res = -ENODEV;
-
- dprintk("bond: %s, vlan id %d\n", bond->dev->name, vlan_id);
-
- write_lock_bh(&bond->lock);
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- if (vlan->vlan_id == vlan_id) {
- list_del(&vlan->vlan_list);
-
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
- bond_alb_clear_vlan(bond, vlan_id);
- }
-
- dprintk("removed VLAN ID %d from bond %s\n", vlan_id,
- bond->dev->name);
-
- kfree(vlan);
-
- if (list_empty(&bond->vlan_list) &&
- (bond->slave_cnt == 0)) {
- /* Last VLAN removed and no slaves, so
- * restore block on adding VLANs. This will
- * be removed once new slaves that are not
- * VLAN challenged will be added.
- */
- bond->dev->features |= NETIF_F_VLAN_CHALLENGED;
- }
-
- res = 0;
- goto out;
- }
- }
-
- dprintk("couldn't find VLAN ID %d in bond %s\n", vlan_id,
- bond->dev->name);
-
-out:
- write_unlock_bh(&bond->lock);
- return res;
-}
-
-/**
- * bond_has_challenged_slaves
- * @bond: the bond we're working on
- *
- * Searches the slave list. Returns 1 if a vlan challenged slave
- * was found, 0 otherwise.
- *
- * Assumes bond->lock is held.
- */
-static int bond_has_challenged_slaves(struct bonding *bond)
-{
- struct slave *slave;
- int i;
-
- bond_for_each_slave(bond, slave, i) {
- if (slave->dev->features & NETIF_F_VLAN_CHALLENGED) {
- dprintk("found VLAN challenged slave - %s\n",
- slave->dev->name);
- return 1;
- }
- }
-
- dprintk("no VLAN challenged slaves found\n");
- return 0;
+ return names[mode];
}
-/**
- * bond_next_vlan - safely skip to the next item in the vlans list.
- * @bond: the bond we're working on
- * @curr: item we're advancing from
- *
- * Returns %NULL if list is empty, bond->next_vlan if @curr is %NULL,
- * or @curr->next otherwise (even if it is @curr itself again).
- *
- * Caller must hold bond->lock
- */
-struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
-{
- struct vlan_entry *next, *last;
-
- if (list_empty(&bond->vlan_list)) {
- return NULL;
- }
-
- if (!curr) {
- next = list_entry(bond->vlan_list.next,
- struct vlan_entry, vlan_list);
- } else {
- last = list_entry(bond->vlan_list.prev,
- struct vlan_entry, vlan_list);
- if (last == curr) {
- next = list_entry(bond->vlan_list.next,
- struct vlan_entry, vlan_list);
- } else {
- next = list_entry(curr->vlan_list.next,
- struct vlan_entry, vlan_list);
- }
- }
-
- return next;
-}
+/*---------------------------------- VLAN -----------------------------------*/
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
- *
+ *
* @bond: bond device that got this skb for tx.
* @skb: hw accel VLAN tagged skb to transmit
* @slave_dev: slave that is supposed to xmit this skbuff
- *
- * When the bond gets an skb to transmit that is
- * already hardware accelerated VLAN tagged, and it
- * needs to relay this skb to a slave that is not
- * hw accel capable, the skb needs to be "unaccelerated",
- * i.e. strip the hwaccel tag and re-insert it as part
- * of the payload.
*/
-int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev)
+void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
+ struct net_device *slave_dev)
{
- unsigned short uninitialized_var(vlan_id);
+ skb->dev = slave_dev;
- if (!list_empty(&bond->vlan_list) &&
- !(slave_dev->features & NETIF_F_HW_VLAN_TX) &&
- vlan_get_tag(skb, &vlan_id) == 0) {
- skb->dev = slave_dev;
- skb = vlan_put_tag(skb, vlan_id);
- if (!skb) {
- /* vlan_put_tag() frees the skb in case of error,
- * so return success here so the calling functions
- * won't attempt to free is again.
- */
- return 0;
- }
- } else {
- skb->dev = slave_dev;
- }
+ BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
+ sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
+ skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping;
- skb->priority = 1;
- dev_queue_xmit(skb);
-
- return 0;
+ if (unlikely(netpoll_tx_running(bond->dev)))
+ bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
+ else
+ dev_queue_xmit(skb);
}
/*
- * In the following 3 functions, bond_vlan_rx_register(), bond_vlan_rx_add_vid
- * and bond_vlan_rx_kill_vid, We don't protect the slave list iteration with a
- * lock because:
+ * In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
+ * We don't protect the slave list iteration with a lock because:
* a. This operation is performed in IOCTL context,
* b. The operation is protected by the RTNL semaphore in the 8021q code,
* c. Holding a lock with BH disabled while directly calling a base driver
* entry point is generally a BAD idea.
- *
+ *
* The design of synchronization/protection for this operation in the 8021q
* module is good for one or more VLAN devices over a single physical device
* and cannot be extended for a teaming solution like bonding, so there is a
@@ -436,54 +273,36 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
*/
/**
- * bond_vlan_rx_register - Propagates registration to slaves
+ * bond_vlan_rx_add_vid - Propagates adding an id to slaves
* @bond_dev: bonding net device that got called
- * @grp: vlan group being registered
+ * @vid: vlan id being added
*/
-static void bond_vlan_rx_register(struct net_device *bond_dev, struct vlan_group *grp)
+static int bond_vlan_rx_add_vid(struct net_device *bond_dev,
+ __be16 proto, u16 vid)
{
- struct bonding *bond = bond_dev->priv;
- struct slave *slave;
- int i;
-
- bond->vlgrp = grp;
-
- bond_for_each_slave(bond, slave, i) {
- struct net_device *slave_dev = slave->dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave, *rollback_slave;
+ struct list_head *iter;
+ int res;
- if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
- slave_dev->vlan_rx_register) {
- slave_dev->vlan_rx_register(slave_dev, grp);
- }
+ bond_for_each_slave(bond, slave, iter) {
+ res = vlan_vid_add(slave->dev, proto, vid);
+ if (res)
+ goto unwind;
}
-}
-/**
- * bond_vlan_rx_add_vid - Propagates adding an id to slaves
- * @bond_dev: bonding net device that got called
- * @vid: vlan id being added
- */
-static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
-{
- struct bonding *bond = bond_dev->priv;
- struct slave *slave;
- int i, res;
+ return 0;
- bond_for_each_slave(bond, slave, i) {
- struct net_device *slave_dev = slave->dev;
+unwind:
+ /* unwind to the slave that failed */
+ bond_for_each_slave(bond, rollback_slave, iter) {
+ if (rollback_slave == slave)
+ break;
- if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
- slave_dev->vlan_rx_add_vid) {
- slave_dev->vlan_rx_add_vid(slave_dev, vid);
- }
+ vlan_vid_del(rollback_slave->dev, proto, vid);
}
- res = bond_add_vlan(bond, vid);
- if (res) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to add vlan id %d\n",
- bond_dev->name, vid);
- }
+ return res;
}
/**
@@ -491,96 +310,20 @@ static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
* @bond_dev: bonding net device that got called
* @vid: vlan id being removed
*/
-static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
+static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
+ __be16 proto, u16 vid)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct list_head *iter;
struct slave *slave;
- struct net_device *vlan_dev;
- int i, res;
- bond_for_each_slave(bond, slave, i) {
- struct net_device *slave_dev = slave->dev;
+ bond_for_each_slave(bond, slave, iter)
+ vlan_vid_del(slave->dev, proto, vid);
- if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
- slave_dev->vlan_rx_kill_vid) {
- /* Save and then restore vlan_dev in the grp array,
- * since the slave's driver might clear it.
- */
- vlan_dev = vlan_group_get_device(bond->vlgrp, vid);
- slave_dev->vlan_rx_kill_vid(slave_dev, vid);
- vlan_group_set_device(bond->vlgrp, vid, vlan_dev);
- }
- }
+ if (bond_is_lb(bond))
+ bond_alb_clear_vlan(bond, vid);
- res = bond_del_vlan(bond, vid);
- if (res) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: Failed to remove vlan id %d\n",
- bond_dev->name, vid);
- }
-}
-
-static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *slave_dev)
-{
- struct vlan_entry *vlan;
-
- write_lock_bh(&bond->lock);
-
- if (list_empty(&bond->vlan_list)) {
- goto out;
- }
-
- if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
- slave_dev->vlan_rx_register) {
- slave_dev->vlan_rx_register(slave_dev, bond->vlgrp);
- }
-
- if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
- !(slave_dev->vlan_rx_add_vid)) {
- goto out;
- }
-
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- slave_dev->vlan_rx_add_vid(slave_dev, vlan->vlan_id);
- }
-
-out:
- write_unlock_bh(&bond->lock);
-}
-
-static void bond_del_vlans_from_slave(struct bonding *bond, struct net_device *slave_dev)
-{
- struct vlan_entry *vlan;
- struct net_device *vlan_dev;
-
- write_lock_bh(&bond->lock);
-
- if (list_empty(&bond->vlan_list)) {
- goto out;
- }
-
- if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
- !(slave_dev->vlan_rx_kill_vid)) {
- goto unreg;
- }
-
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- /* Save and then restore vlan_dev in the grp array,
- * since the slave's driver might clear it.
- */
- vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
- slave_dev->vlan_rx_kill_vid(slave_dev, vlan->vlan_id);
- vlan_group_set_device(bond->vlgrp, vlan->vlan_id, vlan_dev);
- }
-
-unreg:
- if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
- slave_dev->vlan_rx_register) {
- slave_dev->vlan_rx_register(slave_dev, NULL);
- }
-
-out:
- write_unlock_bh(&bond->lock);
+ return 0;
}
/*------------------------------- Link status -------------------------------*/
@@ -594,16 +337,16 @@ out:
*/
static int bond_set_carrier(struct bonding *bond)
{
+ struct list_head *iter;
struct slave *slave;
- int i;
- if (bond->slave_cnt == 0)
+ if (!bond_has_slaves(bond))
goto down;
- if (bond->params.mode == BOND_MODE_8023AD)
+ if (BOND_MODE(bond) == BOND_MODE_8023AD)
return bond_3ad_set_carrier(bond);
- bond_for_each_slave(bond, slave, i) {
+ bond_for_each_slave(bond, slave, iter) {
if (slave->link == BOND_LINK_UP) {
if (!netif_carrier_ok(bond->dev)) {
netif_carrier_on(bond->dev);
@@ -624,55 +367,62 @@ down:
/*
* Get link speed and duplex from the slave's base driver
* using ethtool. If for some reason the call fails or the
- * values are invalid, fake speed and duplex to 100/Full
- * and return error.
+ * values are invalid, set speed and duplex to -1,
+ * and return.
*/
-static int bond_update_speed_duplex(struct slave *slave)
+static void bond_update_speed_duplex(struct slave *slave)
{
struct net_device *slave_dev = slave->dev;
- struct ethtool_cmd etool;
+ struct ethtool_cmd ecmd;
+ u32 slave_speed;
int res;
- /* Fake speed and duplex */
- slave->speed = SPEED_100;
- slave->duplex = DUPLEX_FULL;
-
- if (!slave_dev->ethtool_ops || !slave_dev->ethtool_ops->get_settings)
- return -1;
+ slave->speed = SPEED_UNKNOWN;
+ slave->duplex = DUPLEX_UNKNOWN;
- res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool);
+ res = __ethtool_get_settings(slave_dev, &ecmd);
if (res < 0)
- return -1;
+ return;
- switch (etool.speed) {
- case SPEED_10:
- case SPEED_100:
- case SPEED_1000:
- case SPEED_10000:
- break;
- default:
- return -1;
- }
+ slave_speed = ethtool_cmd_speed(&ecmd);
+ if (slave_speed == 0 || slave_speed == ((__u32) -1))
+ return;
- switch (etool.duplex) {
+ switch (ecmd.duplex) {
case DUPLEX_FULL:
case DUPLEX_HALF:
break;
default:
- return -1;
+ return;
}
- slave->speed = etool.speed;
- slave->duplex = etool.duplex;
+ slave->speed = slave_speed;
+ slave->duplex = ecmd.duplex;
- return 0;
+ return;
+}
+
+const char *bond_slave_link_status(s8 link)
+{
+ switch (link) {
+ case BOND_LINK_UP:
+ return "up";
+ case BOND_LINK_FAIL:
+ return "going down";
+ case BOND_LINK_DOWN:
+ return "down";
+ case BOND_LINK_BACK:
+ return "going back";
+ default:
+ return "unknown";
+ }
}
/*
* if <dev> supports MII link status reporting, check its link status.
*
* We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(),
- * depening upon the setting of the use_carrier parameter.
+ * depending upon the setting of the use_carrier parameter.
*
* Return either BMSR_LSTATUS, meaning that the link is up (or we
* can't tell and just pretend it is), or 0, meaning that the link is
@@ -684,17 +434,27 @@ static int bond_update_speed_duplex(struct slave *slave)
* It'd be nice if there was a good way to tell if a driver supports
* netif_carrier, but there really isn't.
*/
-static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_dev, int reporting)
+static int bond_check_dev_link(struct bonding *bond,
+ struct net_device *slave_dev, int reporting)
{
- static int (* ioctl)(struct net_device *, struct ifreq *, int);
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
+ int (*ioctl)(struct net_device *, struct ifreq *, int);
struct ifreq ifr;
struct mii_ioctl_data *mii;
- if (bond->params.use_carrier) {
+ if (!reporting && !netif_running(slave_dev))
+ return 0;
+
+ if (bond->params.use_carrier)
return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
- }
- ioctl = slave_dev->do_ioctl;
+ /* Try to get link status using Ethtool first. */
+ if (slave_dev->ethtool_ops->get_link)
+ return slave_dev->ethtool_ops->get_link(slave_dev) ?
+ BMSR_LSTATUS : 0;
+
+ /* Ethtool can't be used, fallback to MII ioctls. */
+ ioctl = slave_ops->ndo_do_ioctl;
if (ioctl) {
/* TODO: set pointer to correct ioctl on a per team member */
/* bases to make this more efficient. that is, once */
@@ -713,23 +473,8 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
mii = if_mii(&ifr);
if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
mii->reg_num = MII_BMSR;
- if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) {
- return (mii->val_out & BMSR_LSTATUS);
- }
- }
- }
-
- /*
- * Some drivers cache ETHTOOL_GLINK for a period of time so we only
- * attempt to get link status from it if the above MII ioctls fail.
- */
- if (slave_dev->ethtool_ops) {
- if (slave_dev->ethtool_ops->get_link) {
- u32 link;
-
- link = slave_dev->ethtool_ops->get_link(slave_dev);
-
- return link ? BMSR_LSTATUS : 0;
+ if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0)
+ return mii->val_out & BMSR_LSTATUS;
}
}
@@ -739,43 +484,20 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
* cannot report link status). If not reporting, pretend
* we're ok.
*/
- return (reporting ? -1 : BMSR_LSTATUS);
+ return reporting ? -1 : BMSR_LSTATUS;
}
/*----------------------------- Multicast list ------------------------------*/
/*
- * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
- */
-static inline int bond_is_dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
-{
- return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
- dmi1->dmi_addrlen == dmi2->dmi_addrlen;
-}
-
-/*
- * returns dmi entry if found, NULL otherwise
- */
-static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list)
-{
- struct dev_mc_list *idmi;
-
- for (idmi = mc_list; idmi; idmi = idmi->next) {
- if (bond_is_dmi_same(dmi, idmi)) {
- return idmi;
- }
- }
-
- return NULL;
-}
-
-/*
* Push the promiscuity flag down to appropriate slaves
*/
static int bond_set_promiscuity(struct bonding *bond, int inc)
{
+ struct list_head *iter;
int err = 0;
- if (USES_PRIMARY(bond->params.mode)) {
+
+ if (bond_uses_primary(bond)) {
/* write lock already acquired */
if (bond->curr_active_slave) {
err = dev_set_promiscuity(bond->curr_active_slave->dev,
@@ -783,8 +505,8 @@ static int bond_set_promiscuity(struct bonding *bond, int inc)
}
} else {
struct slave *slave;
- int i;
- bond_for_each_slave(bond, slave, i) {
+
+ bond_for_each_slave(bond, slave, iter) {
err = dev_set_promiscuity(slave->dev, inc);
if (err)
return err;
@@ -798,8 +520,10 @@ static int bond_set_promiscuity(struct bonding *bond, int inc)
*/
static int bond_set_allmulti(struct bonding *bond, int inc)
{
+ struct list_head *iter;
int err = 0;
- if (USES_PRIMARY(bond->params.mode)) {
+
+ if (bond_uses_primary(bond)) {
/* write lock already acquired */
if (bond->curr_active_slave) {
err = dev_set_allmulti(bond->curr_active_slave->dev,
@@ -807,8 +531,8 @@ static int bond_set_allmulti(struct bonding *bond, int inc)
}
} else {
struct slave *slave;
- int i;
- bond_for_each_slave(bond, slave, i) {
+
+ bond_for_each_slave(bond, slave, iter) {
err = dev_set_allmulti(slave->dev, inc);
if (err)
return err;
@@ -818,189 +542,112 @@ static int bond_set_allmulti(struct bonding *bond, int inc)
}
/*
- * Add a Multicast address to slaves
- * according to mode
- */
-static void bond_mc_add(struct bonding *bond, void *addr, int alen)
-{
- if (USES_PRIMARY(bond->params.mode)) {
- /* write lock already acquired */
- if (bond->curr_active_slave) {
- dev_mc_add(bond->curr_active_slave->dev, addr, alen, 0);
- }
- } else {
- struct slave *slave;
- int i;
- bond_for_each_slave(bond, slave, i) {
- dev_mc_add(slave->dev, addr, alen, 0);
- }
- }
-}
-
-/*
- * Remove a multicast address from slave
- * according to mode
- */
-static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
-{
- if (USES_PRIMARY(bond->params.mode)) {
- /* write lock already acquired */
- if (bond->curr_active_slave) {
- dev_mc_delete(bond->curr_active_slave->dev, addr, alen, 0);
- }
- } else {
- struct slave *slave;
- int i;
- bond_for_each_slave(bond, slave, i) {
- dev_mc_delete(slave->dev, addr, alen, 0);
- }
- }
-}
-
-
-/*
* Retrieve the list of registered multicast addresses for the bonding
* device and retransmit an IGMP JOIN request to the current active
* slave.
*/
-static void bond_resend_igmp_join_requests(struct bonding *bond)
+static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
{
- struct in_device *in_dev;
- struct ip_mc_list *im;
-
- rcu_read_lock();
- in_dev = __in_dev_get_rcu(bond->dev);
- if (in_dev) {
- for (im = in_dev->mc_list; im; im = im->next) {
- ip_mc_rejoin_group(im);
- }
- }
-
- rcu_read_unlock();
-}
-
-/*
- * Totally destroys the mc_list in bond
- */
-static void bond_mc_list_destroy(struct bonding *bond)
-{
- struct dev_mc_list *dmi;
+ struct bonding *bond = container_of(work, struct bonding,
+ mcast_work.work);
- dmi = bond->mc_list;
- while (dmi) {
- bond->mc_list = dmi->next;
- kfree(dmi);
- dmi = bond->mc_list;
+ if (!rtnl_trylock()) {
+ queue_delayed_work(bond->wq, &bond->mcast_work, 1);
+ return;
}
- bond->mc_list = NULL;
-}
+ call_netdevice_notifiers(NETDEV_RESEND_IGMP, bond->dev);
-/*
- * Copy all the Multicast addresses from src to the bonding device dst
- */
-static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond,
- gfp_t gfp_flag)
-{
- struct dev_mc_list *dmi, *new_dmi;
-
- for (dmi = mc_list; dmi; dmi = dmi->next) {
- new_dmi = kmalloc(sizeof(struct dev_mc_list), gfp_flag);
-
- if (!new_dmi) {
- /* FIXME: Potential memory leak !!! */
- return -ENOMEM;
- }
-
- new_dmi->next = bond->mc_list;
- bond->mc_list = new_dmi;
- new_dmi->dmi_addrlen = dmi->dmi_addrlen;
- memcpy(new_dmi->dmi_addr, dmi->dmi_addr, dmi->dmi_addrlen);
- new_dmi->dmi_users = dmi->dmi_users;
- new_dmi->dmi_gusers = dmi->dmi_gusers;
+ if (bond->igmp_retrans > 1) {
+ bond->igmp_retrans--;
+ queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
}
-
- return 0;
+ rtnl_unlock();
}
-/*
- * flush all members of flush->mc_list from device dev->mc_list
+/* Flush bond's hardware addresses from slave
*/
-static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *slave_dev)
+static void bond_hw_addr_flush(struct net_device *bond_dev,
+ struct net_device *slave_dev)
{
- struct bonding *bond = bond_dev->priv;
- struct dev_mc_list *dmi;
+ struct bonding *bond = netdev_priv(bond_dev);
- for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
- dev_mc_delete(slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
+ dev_uc_unsync(slave_dev, bond_dev);
+ dev_mc_unsync(slave_dev, bond_dev);
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
/* del lacpdu mc addr from mc list */
u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
- dev_mc_delete(slave_dev, lacpdu_multicast, ETH_ALEN, 0);
+ dev_mc_del(slave_dev, lacpdu_multicast);
}
}
/*--------------------------- Active slave change ---------------------------*/
-/*
- * Update the mc list and multicast-related flags for the new and
- * old active slaves (if any) according to the multicast mode, and
- * promiscuous flags unconditionally.
+/* Update the hardware address list and promisc/allmulti for the new and
+ * old active slaves (if any). Modes that are not using primary keep all
+ * slaves up date at all times; only the modes that use primary need to call
+ * this function to swap these settings during a failover.
*/
-static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct slave *old_active)
+static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
+ struct slave *old_active)
{
- struct dev_mc_list *dmi;
-
- if (!USES_PRIMARY(bond->params.mode)) {
- /* nothing to do - mc list is already up-to-date on
- * all slaves
- */
- return;
- }
+ ASSERT_RTNL();
if (old_active) {
- if (bond->dev->flags & IFF_PROMISC) {
+ if (bond->dev->flags & IFF_PROMISC)
dev_set_promiscuity(old_active->dev, -1);
- }
- if (bond->dev->flags & IFF_ALLMULTI) {
+ if (bond->dev->flags & IFF_ALLMULTI)
dev_set_allmulti(old_active->dev, -1);
- }
- for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
- dev_mc_delete(old_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
+ bond_hw_addr_flush(bond->dev, old_active->dev);
}
if (new_active) {
/* FIXME: Signal errors upstream. */
- if (bond->dev->flags & IFF_PROMISC) {
+ if (bond->dev->flags & IFF_PROMISC)
dev_set_promiscuity(new_active->dev, 1);
- }
- if (bond->dev->flags & IFF_ALLMULTI) {
+ if (bond->dev->flags & IFF_ALLMULTI)
dev_set_allmulti(new_active->dev, 1);
- }
- for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
- dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
- bond_resend_igmp_join_requests(bond);
+ netif_addr_lock_bh(bond->dev);
+ dev_uc_sync(new_active->dev, bond->dev);
+ dev_mc_sync(new_active->dev, bond->dev);
+ netif_addr_unlock_bh(bond->dev);
}
}
+/**
+ * bond_set_dev_addr - clone slave's address to bond
+ * @bond_dev: bond net device
+ * @slave_dev: slave net device
+ *
+ * Should be called with RTNL held.
+ */
+static void bond_set_dev_addr(struct net_device *bond_dev,
+ struct net_device *slave_dev)
+{
+ pr_debug("bond_dev=%p slave_dev=%p slave_dev->addr_len=%d\n",
+ bond_dev, slave_dev, slave_dev->addr_len);
+ memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len);
+ bond_dev->addr_assign_type = NET_ADDR_STOLEN;
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev);
+}
+
/*
* bond_do_fail_over_mac
*
* Perform special MAC address swapping for fail_over_mac settings
*
- * Called with RTNL, bond->lock for read, curr_slave_lock for write_bh.
+ * Called with RTNL, curr_slave_lock for write_bh.
*/
static void bond_do_fail_over_mac(struct bonding *bond,
struct slave *new_active,
struct slave *old_active)
+ __releases(&bond->curr_slave_lock)
+ __acquires(&bond->curr_slave_lock)
{
u8 tmp_mac[ETH_ALEN];
struct sockaddr saddr;
@@ -1008,9 +655,11 @@ static void bond_do_fail_over_mac(struct bonding *bond,
switch (bond->params.fail_over_mac) {
case BOND_FOM_ACTIVE:
- if (new_active)
- memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
- new_active->dev->addr_len);
+ if (new_active) {
+ write_unlock_bh(&bond->curr_slave_lock);
+ bond_set_dev_addr(bond->dev, new_active->dev);
+ write_lock_bh(&bond->curr_slave_lock);
+ }
break;
case BOND_FOM_FOLLOW:
/*
@@ -1022,22 +671,20 @@ static void bond_do_fail_over_mac(struct bonding *bond,
return;
write_unlock_bh(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
if (old_active) {
- memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN);
- memcpy(saddr.sa_data, old_active->dev->dev_addr,
- ETH_ALEN);
+ ether_addr_copy(tmp_mac, new_active->dev->dev_addr);
+ ether_addr_copy(saddr.sa_data,
+ old_active->dev->dev_addr);
saddr.sa_family = new_active->dev->type;
} else {
- memcpy(saddr.sa_data, bond->dev->dev_addr, ETH_ALEN);
+ ether_addr_copy(saddr.sa_data, bond->dev->dev_addr);
saddr.sa_family = bond->dev->type;
}
rv = dev_set_mac_address(new_active->dev, &saddr);
if (rv) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error %d setting MAC of slave %s\n",
+ pr_err("%s: Error %d setting MAC of slave %s\n",
bond->dev->name, -rv, new_active->dev->name);
goto out;
}
@@ -1045,82 +692,89 @@ static void bond_do_fail_over_mac(struct bonding *bond,
if (!old_active)
goto out;
- memcpy(saddr.sa_data, tmp_mac, ETH_ALEN);
+ ether_addr_copy(saddr.sa_data, tmp_mac);
saddr.sa_family = old_active->dev->type;
rv = dev_set_mac_address(old_active->dev, &saddr);
if (rv)
- printk(KERN_ERR DRV_NAME
- ": %s: Error %d setting MAC of slave %s\n",
+ pr_err("%s: Error %d setting MAC of slave %s\n",
bond->dev->name, -rv, new_active->dev->name);
out:
- read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
break;
default:
- printk(KERN_ERR DRV_NAME
- ": %s: bond_do_fail_over_mac impossible: bad policy %d\n",
+ pr_err("%s: bond_do_fail_over_mac impossible: bad policy %d\n",
bond->dev->name, bond->params.fail_over_mac);
break;
}
}
+static bool bond_should_change_active(struct bonding *bond)
+{
+ struct slave *prim = bond->primary_slave;
+ struct slave *curr = bond->curr_active_slave;
+
+ if (!prim || !curr || curr->link != BOND_LINK_UP)
+ return true;
+ if (bond->force_primary) {
+ bond->force_primary = false;
+ return true;
+ }
+ if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER &&
+ (prim->speed < curr->speed ||
+ (prim->speed == curr->speed && prim->duplex <= curr->duplex)))
+ return false;
+ if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE)
+ return false;
+ return true;
+}
/**
* find_best_interface - select the best available slave to be the active one
* @bond: our bonding struct
- *
- * Warning: Caller must hold curr_slave_lock for writing.
*/
static struct slave *bond_find_best_slave(struct bonding *bond)
{
- struct slave *new_active, *old_active;
- struct slave *bestslave = NULL;
+ struct slave *slave, *bestslave = NULL;
+ struct list_head *iter;
int mintime = bond->params.updelay;
- int i;
- new_active = old_active = bond->curr_active_slave;
+ if (bond->primary_slave && bond->primary_slave->link == BOND_LINK_UP &&
+ bond_should_change_active(bond))
+ return bond->primary_slave;
- if (!new_active) { /* there were no active slaves left */
- if (bond->slave_cnt > 0) { /* found one slave */
- new_active = bond->first_slave;
- } else {
- return NULL; /* still no slave, return NULL */
- }
- }
-
- /* first try the primary link; if arping, a link must tx/rx traffic
- * before it can be considered the curr_active_slave - also, we would skip
- * slaves between the curr_active_slave and primary_slave that may be up
- * and able to arp
- */
- if ((bond->primary_slave) &&
- (!bond->params.arp_interval) &&
- (IS_UP(bond->primary_slave->dev))) {
- new_active = bond->primary_slave;
- }
-
- /* remember where to stop iterating over the slaves */
- old_active = new_active;
-
- bond_for_each_slave_from(bond, new_active, i, old_active) {
- if (IS_UP(new_active->dev)) {
- if (new_active->link == BOND_LINK_UP) {
- return new_active;
- } else if (new_active->link == BOND_LINK_BACK) {
- /* link up, but waiting for stabilization */
- if (new_active->delay < mintime) {
- mintime = new_active->delay;
- bestslave = new_active;
- }
- }
+ bond_for_each_slave(bond, slave, iter) {
+ if (slave->link == BOND_LINK_UP)
+ return slave;
+ if (slave->link == BOND_LINK_BACK && bond_slave_is_up(slave) &&
+ slave->delay < mintime) {
+ mintime = slave->delay;
+ bestslave = slave;
}
}
return bestslave;
}
+static bool bond_should_notify_peers(struct bonding *bond)
+{
+ struct slave *slave;
+
+ rcu_read_lock();
+ slave = rcu_dereference(bond->curr_active_slave);
+ rcu_read_unlock();
+
+ pr_debug("bond_should_notify_peers: bond %s slave %s\n",
+ bond->dev->name, slave ? slave->dev->name : "NULL");
+
+ if (!slave || !bond->send_peer_notif ||
+ test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
+ return false;
+
+ return true;
+}
+
/**
* change_active_interface - change the active slave into the specified one
* @bond: our bonding struct
@@ -1134,101 +788,111 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
* because it is apparently the best available slave we have, even though its
* updelay hasn't timed out yet.
*
- * If new_active is not NULL, caller must hold bond->lock for read and
- * curr_slave_lock for write_bh.
+ * If new_active is not NULL, caller must hold curr_slave_lock for write_bh.
*/
void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
{
struct slave *old_active = bond->curr_active_slave;
- if (old_active == new_active) {
+ if (old_active == new_active)
return;
- }
if (new_active) {
- new_active->jiffies = jiffies;
+ new_active->last_link_up = jiffies;
if (new_active->link == BOND_LINK_BACK) {
- if (USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
- ": %s: making interface %s the new "
- "active one %d ms earlier.\n",
- bond->dev->name, new_active->dev->name,
- (bond->params.updelay - new_active->delay) * bond->params.miimon);
+ if (bond_uses_primary(bond)) {
+ pr_info("%s: making interface %s the new active one %d ms earlier\n",
+ bond->dev->name, new_active->dev->name,
+ (bond->params.updelay - new_active->delay) * bond->params.miimon);
}
new_active->delay = 0;
new_active->link = BOND_LINK_UP;
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD)
bond_3ad_handle_link_change(new_active, BOND_LINK_UP);
- }
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
+ if (bond_is_lb(bond))
bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
- }
} else {
- if (USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
- ": %s: making interface %s the new "
- "active one.\n",
- bond->dev->name, new_active->dev->name);
+ if (bond_uses_primary(bond)) {
+ pr_info("%s: making interface %s the new active one\n",
+ bond->dev->name, new_active->dev->name);
}
}
}
- if (USES_PRIMARY(bond->params.mode)) {
- bond_mc_swap(bond, new_active, old_active);
- }
+ if (bond_uses_primary(bond))
+ bond_hw_addr_swap(bond, new_active, old_active);
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
+ if (bond_is_lb(bond)) {
bond_alb_handle_active_change(bond, new_active);
if (old_active)
- bond_set_slave_inactive_flags(old_active);
+ bond_set_slave_inactive_flags(old_active,
+ BOND_SLAVE_NOTIFY_NOW);
if (new_active)
- bond_set_slave_active_flags(new_active);
+ bond_set_slave_active_flags(new_active,
+ BOND_SLAVE_NOTIFY_NOW);
} else {
- bond->curr_active_slave = new_active;
+ rcu_assign_pointer(bond->curr_active_slave, new_active);
}
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
- if (old_active) {
- bond_set_slave_inactive_flags(old_active);
- }
+ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) {
+ if (old_active)
+ bond_set_slave_inactive_flags(old_active,
+ BOND_SLAVE_NOTIFY_NOW);
if (new_active) {
- bond_set_slave_active_flags(new_active);
+ bool should_notify_peers = false;
+
+ bond_set_slave_active_flags(new_active,
+ BOND_SLAVE_NOTIFY_NOW);
if (bond->params.fail_over_mac)
bond_do_fail_over_mac(bond, new_active,
old_active);
- bond->send_grat_arp = bond->params.num_grat_arp;
- bond_send_gratuitous_arp(bond);
+ if (netif_running(bond->dev)) {
+ bond->send_peer_notif =
+ bond->params.num_peer_notif;
+ should_notify_peers =
+ bond_should_notify_peers(bond);
+ }
write_unlock_bh(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
- netdev_bonding_change(bond->dev);
+ call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
+ if (should_notify_peers)
+ call_netdevice_notifiers(NETDEV_NOTIFY_PEERS,
+ bond->dev);
- read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
}
}
+
+ /* resend IGMP joins since active slave has changed or
+ * all were sent on curr_active_slave.
+ * resend only if bond is brought up with the affected
+ * bonding modes and the retransmission is enabled */
+ if (netif_running(bond->dev) && (bond->params.resend_igmp > 0) &&
+ ((bond_uses_primary(bond) && new_active) ||
+ BOND_MODE(bond) == BOND_MODE_ROUNDROBIN)) {
+ bond->igmp_retrans = bond->params.resend_igmp;
+ queue_delayed_work(bond->wq, &bond->mcast_work, 1);
+ }
}
/**
* bond_select_active_slave - select a new active slave, if needed
* @bond: our bonding struct
*
- * This functions shoud be called when one of the following occurs:
+ * This functions should be called when one of the following occurs:
* - The old curr_active_slave has been released or lost its link.
* - The primary_slave has got its link back.
* - A slave has got its link back and there's no old curr_active_slave.
*
- * Caller must hold bond->lock for read and curr_slave_lock for write_bh.
+ * Caller must hold curr_slave_lock for write_bh.
*/
void bond_select_active_slave(struct bonding *bond)
{
@@ -1243,129 +907,175 @@ void bond_select_active_slave(struct bonding *bond)
return;
if (netif_carrier_ok(bond->dev)) {
- printk(KERN_INFO DRV_NAME
- ": %s: first active interface up!\n",
- bond->dev->name);
+ pr_info("%s: first active interface up!\n",
+ bond->dev->name);
} else {
- printk(KERN_INFO DRV_NAME ": %s: "
- "now running without any active interface !\n",
- bond->dev->name);
+ pr_info("%s: now running without any active interface!\n",
+ bond->dev->name);
}
}
}
-/*--------------------------- slave list handling ---------------------------*/
-
-/*
- * This function attaches the slave to the end of list.
- *
- * bond->lock held for writing by caller.
- */
-static void bond_attach_slave(struct bonding *bond, struct slave *new_slave)
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static inline int slave_enable_netpoll(struct slave *slave)
{
- if (bond->first_slave == NULL) { /* attaching the first slave */
- new_slave->next = new_slave;
- new_slave->prev = new_slave;
- bond->first_slave = new_slave;
- } else {
- new_slave->next = bond->first_slave;
- new_slave->prev = bond->first_slave->prev;
- new_slave->next->prev = new_slave;
- new_slave->prev->next = new_slave;
+ struct netpoll *np;
+ int err = 0;
+
+ np = kzalloc(sizeof(*np), GFP_KERNEL);
+ err = -ENOMEM;
+ if (!np)
+ goto out;
+
+ err = __netpoll_setup(np, slave->dev);
+ if (err) {
+ kfree(np);
+ goto out;
}
+ slave->np = np;
+out:
+ return err;
+}
+static inline void slave_disable_netpoll(struct slave *slave)
+{
+ struct netpoll *np = slave->np;
- bond->slave_cnt++;
+ if (!np)
+ return;
+
+ slave->np = NULL;
+ __netpoll_free_async(np);
}
-/*
- * This function detaches the slave from the list.
- * WARNING: no check is made to verify if the slave effectively
- * belongs to <bond>.
- * Nothing is freed on return, structures are just unchained.
- * If any slave pointer in bond was pointing to <slave>,
- * it should be changed by the calling function.
- *
- * bond->lock held for writing by caller.
- */
-static void bond_detach_slave(struct bonding *bond, struct slave *slave)
+static void bond_poll_controller(struct net_device *bond_dev)
{
- if (slave->next) {
- slave->next->prev = slave->prev;
- }
-
- if (slave->prev) {
- slave->prev->next = slave->next;
- }
+}
- if (bond->first_slave == slave) { /* slave is the first slave */
- if (bond->slave_cnt > 1) { /* there are more slave */
- bond->first_slave = slave->next;
- } else {
- bond->first_slave = NULL; /* slave was the last one */
- }
- }
+static void bond_netpoll_cleanup(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct list_head *iter;
+ struct slave *slave;
- slave->next = NULL;
- slave->prev = NULL;
- bond->slave_cnt--;
+ bond_for_each_slave(bond, slave, iter)
+ if (bond_slave_is_up(slave))
+ slave_disable_netpoll(slave);
}
-/*---------------------------------- IOCTL ----------------------------------*/
+static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni)
+{
+ struct bonding *bond = netdev_priv(dev);
+ struct list_head *iter;
+ struct slave *slave;
+ int err = 0;
-static int bond_sethwaddr(struct net_device *bond_dev,
- struct net_device *slave_dev)
+ bond_for_each_slave(bond, slave, iter) {
+ err = slave_enable_netpoll(slave);
+ if (err) {
+ bond_netpoll_cleanup(dev);
+ break;
+ }
+ }
+ return err;
+}
+#else
+static inline int slave_enable_netpoll(struct slave *slave)
{
- dprintk("bond_dev=%p\n", bond_dev);
- dprintk("slave_dev=%p\n", slave_dev);
- dprintk("slave_dev->addr_len=%d\n", slave_dev->addr_len);
- memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len);
return 0;
}
+static inline void slave_disable_netpoll(struct slave *slave)
+{
+}
+static void bond_netpoll_cleanup(struct net_device *bond_dev)
+{
+}
+#endif
-#define BOND_VLAN_FEATURES \
- (NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
- NETIF_F_HW_VLAN_FILTER)
+/*---------------------------------- IOCTL ----------------------------------*/
-/*
- * Compute the common dev->feature set available to all slaves. Some
- * feature bits are managed elsewhere, so preserve those feature bits
- * on the master device.
- */
-static int bond_compute_features(struct bonding *bond)
+static netdev_features_t bond_fix_features(struct net_device *dev,
+ netdev_features_t features)
{
+ struct bonding *bond = netdev_priv(dev);
+ struct list_head *iter;
+ netdev_features_t mask;
struct slave *slave;
- struct net_device *bond_dev = bond->dev;
- unsigned long features = bond_dev->features;
- unsigned short max_hard_header_len = max((u16)ETH_HLEN,
- bond_dev->hard_header_len);
- int i;
- features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
- features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
- NETIF_F_GSO_MASK | NETIF_F_NO_CSUM;
+ if (!bond_has_slaves(bond)) {
+ /* Disable adding VLANs to empty bond. But why? --mq */
+ features |= NETIF_F_VLAN_CHALLENGED;
+ return features;
+ }
+
+ mask = features;
+ features &= ~NETIF_F_ONE_FOR_ALL;
+ features |= NETIF_F_ALL_FOR_ALL;
+
+ bond_for_each_slave(bond, slave, iter) {
+ features = netdev_increment_features(features,
+ slave->dev->features,
+ mask);
+ }
+ features = netdev_add_tso_features(features, mask);
+
+ return features;
+}
- bond_for_each_slave(bond, slave, i) {
- features = netdev_compute_features(features,
- slave->dev->features);
+#define BOND_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \
+ NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
+ NETIF_F_HIGHDMA | NETIF_F_LRO)
+
+#define BOND_ENC_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | NETIF_F_RXCSUM |\
+ NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL)
+
+static void bond_compute_features(struct bonding *bond)
+{
+ unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
+ netdev_features_t vlan_features = BOND_VLAN_FEATURES;
+ netdev_features_t enc_features = BOND_ENC_FEATURES;
+ struct net_device *bond_dev = bond->dev;
+ struct list_head *iter;
+ struct slave *slave;
+ unsigned short max_hard_header_len = ETH_HLEN;
+ unsigned int gso_max_size = GSO_MAX_SIZE;
+ u16 gso_max_segs = GSO_MAX_SEGS;
+
+ if (!bond_has_slaves(bond))
+ goto done;
+ vlan_features &= NETIF_F_ALL_FOR_ALL;
+
+ bond_for_each_slave(bond, slave, iter) {
+ vlan_features = netdev_increment_features(vlan_features,
+ slave->dev->vlan_features, BOND_VLAN_FEATURES);
+
+ enc_features = netdev_increment_features(enc_features,
+ slave->dev->hw_enc_features,
+ BOND_ENC_FEATURES);
+ dst_release_flag &= slave->dev->priv_flags;
if (slave->dev->hard_header_len > max_hard_header_len)
max_hard_header_len = slave->dev->hard_header_len;
+
+ gso_max_size = min(gso_max_size, slave->dev->gso_max_size);
+ gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs);
}
- features |= (bond_dev->features & BOND_VLAN_FEATURES);
- bond_dev->features = features;
+done:
+ bond_dev->vlan_features = vlan_features;
+ bond_dev->hw_enc_features = enc_features;
bond_dev->hard_header_len = max_hard_header_len;
+ bond_dev->gso_max_segs = gso_max_segs;
+ netif_set_gso_max_size(bond_dev, gso_max_size);
- return 0;
-}
+ flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE;
+ bond_dev->priv_flags = flags | dst_release_flag;
+ netdev_change_features(bond_dev);
+}
static void bond_setup_by_slave(struct net_device *bond_dev,
struct net_device *slave_dev)
{
- struct bonding *bond = bond_dev->priv;
-
- bond_dev->neigh_setup = slave_dev->neigh_setup;
- bond_dev->header_ops = slave_dev->header_ops;
+ bond_dev->header_ops = slave_dev->header_ops;
bond_dev->type = slave_dev->type;
bond_dev->hard_header_len = slave_dev->hard_header_len;
@@ -1373,79 +1083,177 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
memcpy(bond_dev->broadcast, slave_dev->broadcast,
slave_dev->addr_len);
- bond->setup_by_slave = 1;
+}
+
+/* On bonding slaves other than the currently active slave, suppress
+ * duplicates except for alb non-mcast/bcast.
+ */
+static bool bond_should_deliver_exact_match(struct sk_buff *skb,
+ struct slave *slave,
+ struct bonding *bond)
+{
+ if (bond_is_slave_inactive(slave)) {
+ if (BOND_MODE(bond) == BOND_MODE_ALB &&
+ skb->pkt_type != PACKET_BROADCAST &&
+ skb->pkt_type != PACKET_MULTICAST)
+ return false;
+ return true;
+ }
+ return false;
+}
+
+static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
+{
+ struct sk_buff *skb = *pskb;
+ struct slave *slave;
+ struct bonding *bond;
+ int (*recv_probe)(const struct sk_buff *, struct bonding *,
+ struct slave *);
+ int ret = RX_HANDLER_ANOTHER;
+
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (unlikely(!skb))
+ return RX_HANDLER_CONSUMED;
+
+ *pskb = skb;
+
+ slave = bond_slave_get_rcu(skb->dev);
+ bond = slave->bond;
+
+ recv_probe = ACCESS_ONCE(bond->recv_probe);
+ if (recv_probe) {
+ ret = recv_probe(skb, bond, slave);
+ if (ret == RX_HANDLER_CONSUMED) {
+ consume_skb(skb);
+ return ret;
+ }
+ }
+
+ if (bond_should_deliver_exact_match(skb, slave, bond)) {
+ return RX_HANDLER_EXACT;
+ }
+
+ skb->dev = bond->dev;
+
+ if (BOND_MODE(bond) == BOND_MODE_ALB &&
+ bond->dev->priv_flags & IFF_BRIDGE_PORT &&
+ skb->pkt_type == PACKET_HOST) {
+
+ if (unlikely(skb_cow_head(skb,
+ skb->data - skb_mac_header(skb)))) {
+ kfree_skb(skb);
+ return RX_HANDLER_CONSUMED;
+ }
+ ether_addr_copy(eth_hdr(skb)->h_dest, bond->dev->dev_addr);
+ }
+
+ return ret;
+}
+
+static int bond_master_upper_dev_link(struct net_device *bond_dev,
+ struct net_device *slave_dev,
+ struct slave *slave)
+{
+ int err;
+
+ err = netdev_master_upper_dev_link_private(slave_dev, bond_dev, slave);
+ if (err)
+ return err;
+ slave_dev->flags |= IFF_SLAVE;
+ rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
+ return 0;
+}
+
+static void bond_upper_dev_unlink(struct net_device *bond_dev,
+ struct net_device *slave_dev)
+{
+ netdev_upper_dev_unlink(slave_dev, bond_dev);
+ slave_dev->flags &= ~IFF_SLAVE;
+ rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE, GFP_KERNEL);
+}
+
+static struct slave *bond_alloc_slave(struct bonding *bond)
+{
+ struct slave *slave = NULL;
+
+ slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
+ if (!slave)
+ return NULL;
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+ SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info),
+ GFP_KERNEL);
+ if (!SLAVE_AD_INFO(slave)) {
+ kfree(slave);
+ return NULL;
+ }
+ }
+ return slave;
+}
+
+static void bond_free_slave(struct slave *slave)
+{
+ struct bonding *bond = bond_get_bond_by_slave(slave);
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD)
+ kfree(SLAVE_AD_INFO(slave));
+
+ kfree(slave);
}
/* enslave device <slave> to bond device <master> */
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
{
- struct bonding *bond = bond_dev->priv;
- struct slave *new_slave = NULL;
- struct dev_mc_list *dmi;
+ struct bonding *bond = netdev_priv(bond_dev);
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
+ struct slave *new_slave = NULL, *prev_slave;
struct sockaddr addr;
int link_reporting;
- int old_features = bond_dev->features;
- int res = 0;
+ int res = 0, i;
- if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
- slave_dev->do_ioctl == NULL) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: no link monitoring support for %s\n",
- bond_dev->name, slave_dev->name);
- }
-
- /* bond must be initialized by bond_open() before enslaving */
- if (!(bond_dev->flags & IFF_UP)) {
- printk(KERN_WARNING DRV_NAME
- " %s: master_dev is not up in bond_enslave\n",
- bond_dev->name);
+ if (!bond->params.use_carrier &&
+ slave_dev->ethtool_ops->get_link == NULL &&
+ slave_ops->ndo_do_ioctl == NULL) {
+ pr_warn("%s: Warning: no link monitoring support for %s\n",
+ bond_dev->name, slave_dev->name);
}
/* already enslaved */
if (slave_dev->flags & IFF_SLAVE) {
- dprintk("Error, Device was already enslaved\n");
+ pr_debug("Error: Device was already enslaved\n");
return -EBUSY;
}
+ if (bond_dev == slave_dev) {
+ pr_err("%s: cannot enslave bond to itself.\n", bond_dev->name);
+ return -EPERM;
+ }
+
/* vlan challenged mutual exclusion */
/* no need to lock since we're protected by rtnl_lock */
if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
- dprintk("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
- if (!list_empty(&bond->vlan_list)) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: cannot enslave VLAN "
- "challenged slave %s on VLAN enabled "
- "bond %s\n", bond_dev->name, slave_dev->name,
- bond_dev->name);
+ pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
+ if (vlan_uses_dev(bond_dev)) {
+ pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
+ bond_dev->name, slave_dev->name, bond_dev->name);
return -EPERM;
} else {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: enslaved VLAN challenged "
- "slave %s. Adding VLANs will be blocked as "
- "long as %s is part of bond %s\n",
- bond_dev->name, slave_dev->name, slave_dev->name,
- bond_dev->name);
- bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
+ pr_warn("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n",
+ bond_dev->name, slave_dev->name,
+ slave_dev->name, bond_dev->name);
}
} else {
- dprintk("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
- if (bond->slave_cnt == 0) {
- /* First slave, and it is not VLAN challenged,
- * so remove the block of adding VLANs over the bond.
- */
- bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
- }
+ pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
}
/*
* Old ifenslave binaries are no longer supported. These can
- * be identified with moderate accurary by the state of the slave:
+ * be identified with moderate accuracy by the state of the slave:
* the current ifenslave will set the interface down prior to
* enslaving it; the old ifenslave will not.
*/
if ((slave_dev->flags & IFF_UP)) {
- printk(KERN_ERR DRV_NAME ": %s is up. "
- "This may be due to an out of date ifenslave.\n",
+ pr_err("%s is up - this may be due to an out of date ifenslave\n",
slave_dev->name);
res = -EPERM;
goto err_undo_flags;
@@ -1458,56 +1266,99 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* bond ether type mutual exclusion - don't allow slaves of dissimilar
* ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond
*/
- if (bond->slave_cnt == 0) {
- if (slave_dev->type != ARPHRD_ETHER)
- bond_setup_by_slave(bond_dev, slave_dev);
+ if (!bond_has_slaves(bond)) {
+ if (bond_dev->type != slave_dev->type) {
+ pr_debug("%s: change device type from %d to %d\n",
+ bond_dev->name,
+ bond_dev->type, slave_dev->type);
+
+ res = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE,
+ bond_dev);
+ res = notifier_to_errno(res);
+ if (res) {
+ pr_err("%s: refused to change device type\n",
+ bond_dev->name);
+ res = -EBUSY;
+ goto err_undo_flags;
+ }
+
+ /* Flush unicast and multicast addresses */
+ dev_uc_flush(bond_dev);
+ dev_mc_flush(bond_dev);
+
+ if (slave_dev->type != ARPHRD_ETHER)
+ bond_setup_by_slave(bond_dev, slave_dev);
+ else {
+ ether_setup(bond_dev);
+ bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+ }
+
+ call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE,
+ bond_dev);
+ }
} else if (bond_dev->type != slave_dev->type) {
- printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different "
- "from other slaves (%d), can not enslave it.\n",
- slave_dev->name,
- slave_dev->type, bond_dev->type);
- res = -EINVAL;
- goto err_undo_flags;
+ pr_err("%s ether type (%d) is different from other slaves (%d), can not enslave it\n",
+ slave_dev->name, slave_dev->type, bond_dev->type);
+ res = -EINVAL;
+ goto err_undo_flags;
}
- if (slave_dev->set_mac_address == NULL) {
- if (bond->slave_cnt == 0) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: The first slave device "
- "specified does not support setting the MAC "
- "address. Setting fail_over_mac to active.",
- bond_dev->name);
- bond->params.fail_over_mac = BOND_FOM_ACTIVE;
+ if (slave_ops->ndo_set_mac_address == NULL) {
+ if (!bond_has_slaves(bond)) {
+ pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address\n",
+ bond_dev->name);
+ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) {
+ bond->params.fail_over_mac = BOND_FOM_ACTIVE;
+ pr_warn("%s: Setting fail_over_mac to active for active-backup mode\n",
+ bond_dev->name);
+ }
} else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: The slave device specified "
- "does not support setting the MAC address, "
- "but fail_over_mac is not set to active.\n"
- , bond_dev->name);
+ pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active\n",
+ bond_dev->name);
res = -EOPNOTSUPP;
goto err_undo_flags;
}
}
- new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
+ call_netdevice_notifiers(NETDEV_JOIN, slave_dev);
+
+ /* If this is the first slave, then we need to set the master's hardware
+ * address to be the same as the slave's. */
+ if (!bond_has_slaves(bond) &&
+ bond->dev->addr_assign_type == NET_ADDR_RANDOM)
+ bond_set_dev_addr(bond->dev, slave_dev);
+
+ new_slave = bond_alloc_slave(bond);
if (!new_slave) {
res = -ENOMEM;
goto err_undo_flags;
}
- /* save slave's original flags before calling
- * netdev_set_master and dev_open
+ new_slave->bond = bond;
+ new_slave->dev = slave_dev;
+ /*
+ * Set the new_slave's queue_id to be zero. Queue ID mapping
+ * is set via sysfs or module option if desired.
*/
- new_slave->original_flags = slave_dev->flags;
+ new_slave->queue_id = 0;
+
+ /* Save slave's original mtu and then set it to match the bond */
+ new_slave->original_mtu = slave_dev->mtu;
+ res = dev_set_mtu(slave_dev, bond->dev->mtu);
+ if (res) {
+ pr_debug("Error %d calling dev_set_mtu\n", res);
+ goto err_free;
+ }
/*
* Save slave's original ("permanent") mac address for modes
* that need it, and for restoring it upon release, and then
* set it to the master's address
*/
- memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
+ ether_addr_copy(new_slave->perm_hwaddr, slave_dev->dev_addr);
- if (!bond->params.fail_over_mac) {
+ if (!bond->params.fail_over_mac ||
+ BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
/*
* Set slave to master's mac address. The application already
* set the master's mac address to that of the first slave
@@ -1516,43 +1367,33 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
addr.sa_family = slave_dev->type;
res = dev_set_mac_address(slave_dev, &addr);
if (res) {
- dprintk("Error %d calling set_mac_address\n", res);
- goto err_free;
+ pr_debug("Error %d calling set_mac_address\n", res);
+ goto err_restore_mtu;
}
}
- res = netdev_set_master(slave_dev, bond_dev);
- if (res) {
- dprintk("Error %d calling netdev_set_master\n", res);
- goto err_restore_mac;
- }
/* open the slave since the application closed it */
res = dev_open(slave_dev);
if (res) {
- dprintk("Openning slave %s failed\n", slave_dev->name);
- goto err_unset_master;
+ pr_debug("Opening slave %s failed\n", slave_dev->name);
+ goto err_restore_mac;
}
- new_slave->dev = slave_dev;
slave_dev->priv_flags |= IFF_BONDING;
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
+ if (bond_is_lb(bond)) {
/* bond_alb_init_slave() must be called before all other stages since
* it might fail and we do not want to have to undo everything
*/
res = bond_alb_init_slave(bond, new_slave);
- if (res) {
+ if (res)
goto err_close;
- }
}
- /* If the mode USES_PRIMARY, then the new slave gets the
- * master's promisc (and mc) settings only if it becomes the
- * curr_active_slave, and that is taken care of later when calling
- * bond_change_active()
+ /* If the mode uses primary, then the following is handled by
+ * bond_change_active_slave().
*/
- if (!USES_PRIMARY(bond->params.mode)) {
+ if (!bond_uses_primary(bond)) {
/* set promiscuity level to new slave */
if (bond_dev->flags & IFF_PROMISC) {
res = dev_set_promiscuity(slave_dev, 1);
@@ -1568,36 +1409,38 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
}
netif_addr_lock_bh(bond_dev);
- /* upload master's mc_list to new slave */
- for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
- dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
- }
+
+ dev_mc_sync_multiple(slave_dev, bond_dev);
+ dev_uc_sync_multiple(slave_dev, bond_dev);
+
netif_addr_unlock_bh(bond_dev);
}
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
/* add lacpdu mc addr to mc list */
u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
- dev_mc_add(slave_dev, lacpdu_multicast, ETH_ALEN, 0);
+ dev_mc_add(slave_dev, lacpdu_multicast);
}
- bond_add_vlans_on_slave(bond, slave_dev);
-
- write_lock_bh(&bond->lock);
+ res = vlan_vids_add_by_dev(slave_dev, bond_dev);
+ if (res) {
+ pr_err("%s: Error: Couldn't add bond vlan ids to %s\n",
+ bond_dev->name, slave_dev->name);
+ goto err_close;
+ }
- bond_attach_slave(bond, new_slave);
+ prev_slave = bond_last_slave(bond);
new_slave->delay = 0;
new_slave->link_failure_count = 0;
- bond_compute_features(bond);
-
- write_unlock_bh(&bond->lock);
-
- read_lock(&bond->lock);
+ bond_update_speed_duplex(new_slave);
- new_slave->last_arp_rx = jiffies;
+ new_slave->last_rx = jiffies -
+ (msecs_to_jiffies(bond->params.arp_interval) + 1);
+ for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
+ new_slave->target_last_arp_rx[i] = new_slave->last_rx;
if (bond->params.miimon && !bond->params.use_carrier) {
link_reporting = bond_check_dev_link(bond, slave_dev, 1);
@@ -1612,166 +1455,205 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
* supported); thus, we don't need to change
* the messages for netif_carrier.
*/
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: MII and ETHTOOL support not "
- "available for interface %s, and "
- "arp_interval/arp_ip_target module parameters "
- "not specified, thus bonding will not detect "
- "link failures! see bonding.txt for details.\n",
- bond_dev->name, slave_dev->name);
+ pr_warn("%s: Warning: MII and ETHTOOL support not available for interface %s, and arp_interval/arp_ip_target module parameters not specified, thus bonding will not detect link failures! see bonding.txt for details\n",
+ bond_dev->name, slave_dev->name);
} else if (link_reporting == -1) {
/* unable get link status using mii/ethtool */
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: can't get link status from "
- "interface %s; the network driver associated "
- "with this interface does not support MII or "
- "ETHTOOL link status reporting, thus miimon "
- "has no effect on this interface.\n",
- bond_dev->name, slave_dev->name);
+ pr_warn("%s: Warning: can't get link status from interface %s; the network driver associated with this interface does not support MII or ETHTOOL link status reporting, thus miimon has no effect on this interface\n",
+ bond_dev->name, slave_dev->name);
}
}
/* check for initial state */
- if (!bond->params.miimon ||
- (bond_check_dev_link(bond, slave_dev, 0) == BMSR_LSTATUS)) {
- if (bond->params.updelay) {
- dprintk("Initial state of slave_dev is "
- "BOND_LINK_BACK\n");
- new_slave->link = BOND_LINK_BACK;
- new_slave->delay = bond->params.updelay;
+ if (bond->params.miimon) {
+ if (bond_check_dev_link(bond, slave_dev, 0) == BMSR_LSTATUS) {
+ if (bond->params.updelay) {
+ new_slave->link = BOND_LINK_BACK;
+ new_slave->delay = bond->params.updelay;
+ } else {
+ new_slave->link = BOND_LINK_UP;
+ }
} else {
- dprintk("Initial state of slave_dev is "
- "BOND_LINK_UP\n");
- new_slave->link = BOND_LINK_UP;
+ new_slave->link = BOND_LINK_DOWN;
}
- new_slave->jiffies = jiffies;
+ } else if (bond->params.arp_interval) {
+ new_slave->link = (netif_carrier_ok(slave_dev) ?
+ BOND_LINK_UP : BOND_LINK_DOWN);
} else {
- dprintk("Initial state of slave_dev is "
- "BOND_LINK_DOWN\n");
- new_slave->link = BOND_LINK_DOWN;
- }
-
- if (bond_update_speed_duplex(new_slave) &&
- (new_slave->link != BOND_LINK_DOWN)) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: failed to get speed and duplex from %s, "
- "assumed to be 100Mb/sec and Full.\n",
- bond_dev->name, new_slave->dev->name);
-
- if (bond->params.mode == BOND_MODE_8023AD) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
- "support in base driver for proper aggregator "
- "selection.\n", bond_dev->name);
- }
+ new_slave->link = BOND_LINK_UP;
}
- if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
+ if (new_slave->link != BOND_LINK_DOWN)
+ new_slave->last_link_up = jiffies;
+ pr_debug("Initial state of slave_dev is BOND_LINK_%s\n",
+ new_slave->link == BOND_LINK_DOWN ? "DOWN" :
+ (new_slave->link == BOND_LINK_UP ? "UP" : "BACK"));
+
+ if (bond_uses_primary(bond) && bond->params.primary[0]) {
/* if there is a primary slave, remember it */
if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
bond->primary_slave = new_slave;
+ bond->force_primary = true;
}
}
- write_lock_bh(&bond->curr_slave_lock);
-
- switch (bond->params.mode) {
+ switch (BOND_MODE(bond)) {
case BOND_MODE_ACTIVEBACKUP:
- bond_set_slave_inactive_flags(new_slave);
- bond_select_active_slave(bond);
+ bond_set_slave_inactive_flags(new_slave,
+ BOND_SLAVE_NOTIFY_NOW);
break;
case BOND_MODE_8023AD:
/* in 802.3ad mode, the internal mechanism
* will activate the slaves in the selected
* aggregator
*/
- bond_set_slave_inactive_flags(new_slave);
+ bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW);
/* if this is the first slave */
- if (bond->slave_cnt == 1) {
- SLAVE_AD_INFO(new_slave).id = 1;
+ if (!prev_slave) {
+ SLAVE_AD_INFO(new_slave)->id = 1;
/* Initialize AD with the number of times that the AD timer is called in 1 second
* can be called only after the mac address of the bond is set
*/
- bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL,
- bond->params.lacp_fast);
+ bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL);
} else {
- SLAVE_AD_INFO(new_slave).id =
- SLAVE_AD_INFO(new_slave->prev).id + 1;
+ SLAVE_AD_INFO(new_slave)->id =
+ SLAVE_AD_INFO(prev_slave)->id + 1;
}
bond_3ad_bind_slave(new_slave);
break;
case BOND_MODE_TLB:
case BOND_MODE_ALB:
- new_slave->state = BOND_STATE_ACTIVE;
- bond_set_slave_inactive_flags(new_slave);
+ bond_set_active_slave(new_slave);
+ bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW);
break;
default:
- dprintk("This slave is always active in trunk mode\n");
+ pr_debug("This slave is always active in trunk mode\n");
/* always active in trunk mode */
- new_slave->state = BOND_STATE_ACTIVE;
+ bond_set_active_slave(new_slave);
/* In trunking mode there is little meaning to curr_active_slave
* anyway (it holds no special properties of the bond device),
* so we can change it without calling change_active_interface()
*/
- if (!bond->curr_active_slave) {
- bond->curr_active_slave = new_slave;
- }
+ if (!bond->curr_active_slave && new_slave->link == BOND_LINK_UP)
+ rcu_assign_pointer(bond->curr_active_slave, new_slave);
+
break;
} /* switch(bond_mode) */
- write_unlock_bh(&bond->curr_slave_lock);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ slave_dev->npinfo = bond->dev->npinfo;
+ if (slave_dev->npinfo) {
+ if (slave_enable_netpoll(new_slave)) {
+ pr_info("Error, %s: master_dev is using netpoll, but new slave device does not support netpoll\n",
+ bond_dev->name);
+ res = -EBUSY;
+ goto err_detach;
+ }
+ }
+#endif
- bond_set_carrier(bond);
+ res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
+ new_slave);
+ if (res) {
+ pr_debug("Error %d calling netdev_rx_handler_register\n", res);
+ goto err_detach;
+ }
- read_unlock(&bond->lock);
+ res = bond_master_upper_dev_link(bond_dev, slave_dev, new_slave);
+ if (res) {
+ pr_debug("Error %d calling bond_master_upper_dev_link\n", res);
+ goto err_unregister;
+ }
- res = bond_create_slave_symlinks(bond_dev, slave_dev);
- if (res)
- goto err_close;
+ res = bond_sysfs_slave_add(new_slave);
+ if (res) {
+ pr_debug("Error %d calling bond_sysfs_slave_add\n", res);
+ goto err_upper_unlink;
+ }
+
+ bond->slave_cnt++;
+ bond_compute_features(bond);
+ bond_set_carrier(bond);
+
+ if (bond_uses_primary(bond)) {
+ block_netpoll_tx();
+ write_lock_bh(&bond->curr_slave_lock);
+ bond_select_active_slave(bond);
+ write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
+ }
- printk(KERN_INFO DRV_NAME
- ": %s: enslaving %s as a%s interface with a%s link.\n",
- bond_dev->name, slave_dev->name,
- new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
- new_slave->link != BOND_LINK_DOWN ? "n up" : " down");
+ pr_info("%s: Enslaving %s as %s interface with %s link\n",
+ bond_dev->name, slave_dev->name,
+ bond_is_active_slave(new_slave) ? "an active" : "a backup",
+ new_slave->link != BOND_LINK_DOWN ? "an up" : "a down");
/* enslave is successful */
return 0;
/* Undo stages on error */
+err_upper_unlink:
+ bond_upper_dev_unlink(bond_dev, slave_dev);
+
+err_unregister:
+ netdev_rx_handler_unregister(slave_dev);
+
+err_detach:
+ if (!bond_uses_primary(bond))
+ bond_hw_addr_flush(bond_dev, slave_dev);
+
+ vlan_vids_del_by_dev(slave_dev, bond_dev);
+ if (bond->primary_slave == new_slave)
+ bond->primary_slave = NULL;
+ if (bond->curr_active_slave == new_slave) {
+ block_netpoll_tx();
+ write_lock_bh(&bond->curr_slave_lock);
+ bond_change_active_slave(bond, NULL);
+ bond_select_active_slave(bond);
+ write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
+ }
+ slave_disable_netpoll(new_slave);
+
err_close:
+ slave_dev->priv_flags &= ~IFF_BONDING;
dev_close(slave_dev);
-err_unset_master:
- netdev_set_master(slave_dev, NULL);
-
err_restore_mac:
- if (!bond->params.fail_over_mac) {
+ if (!bond->params.fail_over_mac ||
+ BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
/* XXX TODO - fom follow mode needs to change master's
* MAC if this slave's MAC is in use by the bond, or at
* least print a warning.
*/
- memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
+ ether_addr_copy(addr.sa_data, new_slave->perm_hwaddr);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
}
+err_restore_mtu:
+ dev_set_mtu(slave_dev, new_slave->original_mtu);
+
err_free:
- kfree(new_slave);
+ bond_free_slave(new_slave);
err_undo_flags:
- bond_dev->features = old_features;
-
+ /* Enslave of first slave has failed and we need to fix master's mac */
+ if (!bond_has_slaves(bond) &&
+ ether_addr_equal_64bits(bond_dev->dev_addr, slave_dev->dev_addr))
+ eth_hw_addr_random(bond_dev);
+
return res;
}
/*
* Try to release the slave device <slave> from the bond device <master>
* It is legal to access curr_active_slave without a lock because all the function
- * is write-locked.
+ * is write-locked. If "all" is true it means that the function is being called
+ * while destroying a bond interface and all slaves are being released.
*
* The rules for slave state should be:
* for Active/Backup:
@@ -1779,446 +1661,232 @@ err_undo_flags:
* for Bonded connections:
* The first up interface should be left on and all others downed.
*/
-int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+static int __bond_release_one(struct net_device *bond_dev,
+ struct net_device *slave_dev,
+ bool all)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *oldcurrent;
struct sockaddr addr;
- int mac_addr_differ;
- DECLARE_MAC_BUF(mac);
+ int old_flags = bond_dev->flags;
+ netdev_features_t old_features = bond_dev->features;
/* slave is not a slave or master is not master of this slave */
if (!(slave_dev->flags & IFF_SLAVE) ||
- (slave_dev->master != bond_dev)) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: cannot release %s.\n",
+ !netdev_has_upper_dev(slave_dev, bond_dev)) {
+ pr_err("%s: Error: cannot release %s\n",
bond_dev->name, slave_dev->name);
return -EINVAL;
}
- write_lock_bh(&bond->lock);
+ block_netpoll_tx();
slave = bond_get_slave_by_dev(bond, slave_dev);
if (!slave) {
/* not a slave of this bond */
- printk(KERN_INFO DRV_NAME
- ": %s: %s not enslaved\n",
- bond_dev->name, slave_dev->name);
- write_unlock_bh(&bond->lock);
+ pr_info("%s: %s not enslaved\n",
+ bond_dev->name, slave_dev->name);
+ unblock_netpoll_tx();
return -EINVAL;
}
- if (!bond->params.fail_over_mac) {
- mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
- ETH_ALEN);
- if (!mac_addr_differ && (bond->slave_cnt > 1))
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: the permanent HWaddr of %s - "
- "%s - is still in use by %s. "
- "Set the HWaddr of %s to a different address "
- "to avoid conflicts.\n",
- bond_dev->name, slave_dev->name,
- print_mac(mac, slave->perm_hwaddr),
- bond_dev->name, slave_dev->name);
- }
+ bond_sysfs_slave_del(slave);
+
+ bond_upper_dev_unlink(bond_dev, slave_dev);
+ /* unregister rx_handler early so bond_handle_frame wouldn't be called
+ * for this slave anymore.
+ */
+ netdev_rx_handler_unregister(slave_dev);
+ write_lock_bh(&bond->lock);
/* Inform AD package of unbinding of slave. */
- if (bond->params.mode == BOND_MODE_8023AD) {
- /* must be called before the slave is
- * detached from the list
- */
+ if (BOND_MODE(bond) == BOND_MODE_8023AD)
bond_3ad_unbind_slave(slave);
- }
- printk(KERN_INFO DRV_NAME
- ": %s: releasing %s interface %s\n",
- bond_dev->name,
- (slave->state == BOND_STATE_ACTIVE)
- ? "active" : "backup",
- slave_dev->name);
+ write_unlock_bh(&bond->lock);
+
+ pr_info("%s: Releasing %s interface %s\n",
+ bond_dev->name,
+ bond_is_active_slave(slave) ? "active" : "backup",
+ slave_dev->name);
oldcurrent = bond->curr_active_slave;
bond->current_arp_slave = NULL;
- /* release the slave from its bond */
- bond_detach_slave(bond, slave);
-
- bond_compute_features(bond);
+ if (!all && (!bond->params.fail_over_mac ||
+ BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)) {
+ if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) &&
+ bond_has_slaves(bond))
+ pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s - set the HWaddr of %s to a different address to avoid conflicts\n",
+ bond_dev->name, slave_dev->name,
+ slave->perm_hwaddr,
+ bond_dev->name, slave_dev->name);
+ }
- if (bond->primary_slave == slave) {
+ if (bond->primary_slave == slave)
bond->primary_slave = NULL;
- }
if (oldcurrent == slave) {
+ write_lock_bh(&bond->curr_slave_lock);
bond_change_active_slave(bond, NULL);
+ write_unlock_bh(&bond->curr_slave_lock);
}
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
+ if (bond_is_lb(bond)) {
/* Must be called only after the slave has been
* detached from the list and the curr_active_slave
* has been cleared (if our_slave == old_current),
* but before a new active slave is selected.
*/
- write_unlock_bh(&bond->lock);
bond_alb_deinit_slave(bond, slave);
- write_lock_bh(&bond->lock);
}
- if (oldcurrent == slave) {
+ if (all) {
+ RCU_INIT_POINTER(bond->curr_active_slave, NULL);
+ } else if (oldcurrent == slave) {
/*
* Note that we hold RTNL over this sequence, so there
* is no concern that another slave add/remove event
* will interfere.
*/
- write_unlock_bh(&bond->lock);
- read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
- write_lock_bh(&bond->lock);
}
- if (bond->slave_cnt == 0) {
+ if (!bond_has_slaves(bond)) {
bond_set_carrier(bond);
+ eth_hw_addr_random(bond_dev);
- /* if the last slave was removed, zero the mac address
- * of the master so it will be set by the application
- * to the mac address of the first slave
- */
- memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
-
- if (list_empty(&bond->vlan_list)) {
- bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
- } else {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: clearing HW address of %s while it "
- "still has VLANs.\n",
- bond_dev->name, bond_dev->name);
- printk(KERN_WARNING DRV_NAME
- ": %s: When re-adding slaves, make sure the bond's "
- "HW address matches its VLANs'.\n",
- bond_dev->name);
+ if (vlan_uses_dev(bond_dev)) {
+ pr_warn("%s: Warning: clearing HW address of %s while it still has VLANs\n",
+ bond_dev->name, bond_dev->name);
+ pr_warn("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs\n",
+ bond_dev->name);
}
- } else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
- !bond_has_challenged_slaves(bond)) {
- printk(KERN_INFO DRV_NAME
- ": %s: last VLAN challenged slave %s "
- "left bond %s. VLAN blocking is removed\n",
- bond_dev->name, slave_dev->name, bond_dev->name);
- bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
}
- write_unlock_bh(&bond->lock);
+ unblock_netpoll_tx();
+ synchronize_rcu();
+ bond->slave_cnt--;
- /* must do this from outside any spinlocks */
- bond_destroy_slave_symlinks(bond_dev, slave_dev);
+ if (!bond_has_slaves(bond)) {
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
+ call_netdevice_notifiers(NETDEV_RELEASE, bond->dev);
+ }
+
+ bond_compute_features(bond);
+ if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
+ (old_features & NETIF_F_VLAN_CHALLENGED))
+ pr_info("%s: last VLAN challenged slave %s left bond %s - VLAN blocking is removed\n",
+ bond_dev->name, slave_dev->name, bond_dev->name);
- bond_del_vlans_from_slave(bond, slave_dev);
+ /* must do this from outside any spinlocks */
+ vlan_vids_del_by_dev(slave_dev, bond_dev);
- /* If the mode USES_PRIMARY, then we should only remove its
- * promisc and mc settings if it was the curr_active_slave, but that was
- * already taken care of above when we detached the slave
+ /* If the mode uses primary, then this cases was handled above by
+ * bond_change_active_slave(..., NULL)
*/
- if (!USES_PRIMARY(bond->params.mode)) {
- /* unset promiscuity level from slave */
- if (bond_dev->flags & IFF_PROMISC) {
+ if (!bond_uses_primary(bond)) {
+ /* unset promiscuity level from slave
+ * NOTE: The NETDEV_CHANGEADDR call above may change the value
+ * of the IFF_PROMISC flag in the bond_dev, but we need the
+ * value of that flag before that change, as that was the value
+ * when this slave was attached, so we cache at the start of the
+ * function and use it here. Same goes for ALLMULTI below
+ */
+ if (old_flags & IFF_PROMISC)
dev_set_promiscuity(slave_dev, -1);
- }
/* unset allmulti level from slave */
- if (bond_dev->flags & IFF_ALLMULTI) {
+ if (old_flags & IFF_ALLMULTI)
dev_set_allmulti(slave_dev, -1);
- }
- /* flush master's mc_list from slave */
- netif_addr_lock_bh(bond_dev);
- bond_mc_list_flush(bond_dev, slave_dev);
- netif_addr_unlock_bh(bond_dev);
+ bond_hw_addr_flush(bond_dev, slave_dev);
}
- netdev_set_master(slave_dev, NULL);
+ slave_disable_netpoll(slave);
/* close slave before restoring its mac address */
dev_close(slave_dev);
- if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
+ if (bond->params.fail_over_mac != BOND_FOM_ACTIVE ||
+ BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
/* restore original ("permanent") mac address */
- memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+ ether_addr_copy(addr.sa_data, slave->perm_hwaddr);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
}
- slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
- IFF_SLAVE_INACTIVE | IFF_BONDING |
- IFF_SLAVE_NEEDARP);
+ dev_set_mtu(slave_dev, slave->original_mtu);
- kfree(slave);
+ slave_dev->priv_flags &= ~IFF_BONDING;
+
+ bond_free_slave(slave);
return 0; /* deletion OK */
}
-/*
-* Destroy a bonding device.
-* Must be under rtnl_lock when this function is called.
-*/
-void bond_destroy(struct bonding *bond)
+/* A wrapper used because of ndo_del_link */
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
{
- bond_deinit(bond->dev);
- bond_destroy_sysfs_entry(bond);
- unregister_netdevice(bond->dev);
+ return __bond_release_one(bond_dev, slave_dev, false);
}
/*
-* First release a slave and than destroy the bond if no more slaves iare left.
+* First release a slave and then destroy the bond if no more slaves are left.
* Must be under rtnl_lock when this function is called.
*/
-int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
+static int bond_release_and_destroy(struct net_device *bond_dev,
+ struct net_device *slave_dev)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
int ret;
ret = bond_release(bond_dev, slave_dev);
- if ((ret == 0) && (bond->slave_cnt == 0)) {
- printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
- bond_dev->name, bond_dev->name);
- bond_destroy(bond);
+ if (ret == 0 && !bond_has_slaves(bond)) {
+ bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
+ pr_info("%s: Destroying bond %s\n",
+ bond_dev->name, bond_dev->name);
+ unregister_netdevice(bond_dev);
}
return ret;
}
-/*
- * This function releases all slaves.
- */
-static int bond_release_all(struct net_device *bond_dev)
-{
- struct bonding *bond = bond_dev->priv;
- struct slave *slave;
- struct net_device *slave_dev;
- struct sockaddr addr;
-
- write_lock_bh(&bond->lock);
-
- netif_carrier_off(bond_dev);
-
- if (bond->slave_cnt == 0) {
- goto out;
- }
-
- bond->current_arp_slave = NULL;
- bond->primary_slave = NULL;
- bond_change_active_slave(bond, NULL);
-
- while ((slave = bond->first_slave) != NULL) {
- /* Inform AD package of unbinding of slave
- * before slave is detached from the list.
- */
- if (bond->params.mode == BOND_MODE_8023AD) {
- bond_3ad_unbind_slave(slave);
- }
-
- slave_dev = slave->dev;
- bond_detach_slave(bond, slave);
-
- /* now that the slave is detached, unlock and perform
- * all the undo steps that should not be called from
- * within a lock.
- */
- write_unlock_bh(&bond->lock);
-
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
- /* must be called only after the slave
- * has been detached from the list
- */
- bond_alb_deinit_slave(bond, slave);
- }
-
- bond_compute_features(bond);
-
- bond_destroy_slave_symlinks(bond_dev, slave_dev);
- bond_del_vlans_from_slave(bond, slave_dev);
-
- /* If the mode USES_PRIMARY, then we should only remove its
- * promisc and mc settings if it was the curr_active_slave, but that was
- * already taken care of above when we detached the slave
- */
- if (!USES_PRIMARY(bond->params.mode)) {
- /* unset promiscuity level from slave */
- if (bond_dev->flags & IFF_PROMISC) {
- dev_set_promiscuity(slave_dev, -1);
- }
-
- /* unset allmulti level from slave */
- if (bond_dev->flags & IFF_ALLMULTI) {
- dev_set_allmulti(slave_dev, -1);
- }
-
- /* flush master's mc_list from slave */
- netif_addr_lock_bh(bond_dev);
- bond_mc_list_flush(bond_dev, slave_dev);
- netif_addr_unlock_bh(bond_dev);
- }
-
- netdev_set_master(slave_dev, NULL);
-
- /* close slave before restoring its mac address */
- dev_close(slave_dev);
-
- if (!bond->params.fail_over_mac) {
- /* restore original ("permanent") mac address*/
- memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
- addr.sa_family = slave_dev->type;
- dev_set_mac_address(slave_dev, &addr);
- }
-
- slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
- IFF_SLAVE_INACTIVE);
-
- kfree(slave);
-
- /* re-acquire the lock before getting the next slave */
- write_lock_bh(&bond->lock);
- }
-
- /* zero the mac address of the master so it will be
- * set by the application to the mac address of the
- * first slave
- */
- memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
-
- if (list_empty(&bond->vlan_list)) {
- bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
- } else {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: clearing HW address of %s while it "
- "still has VLANs.\n",
- bond_dev->name, bond_dev->name);
- printk(KERN_WARNING DRV_NAME
- ": %s: When re-adding slaves, make sure the bond's "
- "HW address matches its VLANs'.\n",
- bond_dev->name);
- }
-
- printk(KERN_INFO DRV_NAME
- ": %s: released all slaves\n",
- bond_dev->name);
-
-out:
- write_unlock_bh(&bond->lock);
-
- return 0;
-}
-
-/*
- * This function changes the active slave to slave <slave_dev>.
- * It returns -EINVAL in the following cases.
- * - <slave_dev> is not found in the list.
- * - There is not active slave now.
- * - <slave_dev> is already active.
- * - The link state of <slave_dev> is not BOND_LINK_UP.
- * - <slave_dev> is not running.
- * In these cases, this fuction does nothing.
- * In the other cases, currnt_slave pointer is changed and 0 is returned.
- */
-static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
-{
- struct bonding *bond = bond_dev->priv;
- struct slave *old_active = NULL;
- struct slave *new_active = NULL;
- int res = 0;
-
- if (!USES_PRIMARY(bond->params.mode)) {
- return -EINVAL;
- }
-
- /* Verify that master_dev is indeed the master of slave_dev */
- if (!(slave_dev->flags & IFF_SLAVE) ||
- (slave_dev->master != bond_dev)) {
- return -EINVAL;
- }
-
- read_lock(&bond->lock);
-
- read_lock(&bond->curr_slave_lock);
- old_active = bond->curr_active_slave;
- read_unlock(&bond->curr_slave_lock);
-
- new_active = bond_get_slave_by_dev(bond, slave_dev);
-
- /*
- * Changing to the current active: do nothing; return success.
- */
- if (new_active && (new_active == old_active)) {
- read_unlock(&bond->lock);
- return 0;
- }
-
- if ((new_active) &&
- (old_active) &&
- (new_active->link == BOND_LINK_UP) &&
- IS_UP(new_active->dev)) {
- write_lock_bh(&bond->curr_slave_lock);
- bond_change_active_slave(bond, new_active);
- write_unlock_bh(&bond->curr_slave_lock);
- } else {
- res = -EINVAL;
- }
-
- read_unlock(&bond->lock);
-
- return res;
-}
-
static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
- info->bond_mode = bond->params.mode;
+ info->bond_mode = BOND_MODE(bond);
info->miimon = bond->params.miimon;
- read_lock(&bond->lock);
info->num_slaves = bond->slave_cnt;
- read_unlock(&bond->lock);
return 0;
}
static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *info)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct list_head *iter;
+ int i = 0, res = -ENODEV;
struct slave *slave;
- int i, found = 0;
- if (info->slave_id < 0) {
- return -ENODEV;
- }
-
- read_lock(&bond->lock);
-
- bond_for_each_slave(bond, slave, i) {
- if (i == (int)info->slave_id) {
- found = 1;
+ bond_for_each_slave(bond, slave, iter) {
+ if (i++ == (int)info->slave_id) {
+ res = 0;
+ strcpy(info->slave_name, slave->dev->name);
+ info->link = slave->link;
+ info->state = bond_slave_state(slave);
+ info->link_failure_count = slave->link_failure_count;
break;
}
}
- read_unlock(&bond->lock);
-
- if (found) {
- strcpy(info->slave_name, slave->dev->name);
- info->link = slave->link;
- info->state = slave->state;
- info->link_failure_count = slave->link_failure_count;
- } else {
- return -ENODEV;
- }
-
- return 0;
+ return res;
}
/*-------------------------------- Monitoring -------------------------------*/
@@ -2226,10 +1894,14 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
static int bond_miimon_inspect(struct bonding *bond)
{
+ int link_state, commit = 0;
+ struct list_head *iter;
struct slave *slave;
- int i, link_state, commit = 0;
+ bool ignore_updelay;
+
+ ignore_updelay = !bond->curr_active_slave ? true : false;
- bond_for_each_slave(bond, slave, i) {
+ bond_for_each_slave_rcu(bond, slave, iter) {
slave->new_link = BOND_LINK_NOCHANGE;
link_state = bond_check_dev_link(bond, slave->dev, 0);
@@ -2242,16 +1914,14 @@ static int bond_miimon_inspect(struct bonding *bond)
slave->link = BOND_LINK_FAIL;
slave->delay = bond->params.downdelay;
if (slave->delay) {
- printk(KERN_INFO DRV_NAME
- ": %s: link status down for %s"
- "interface %s, disabling it in %d ms.\n",
- bond->dev->name,
- (bond->params.mode ==
- BOND_MODE_ACTIVEBACKUP) ?
- ((slave->state == BOND_STATE_ACTIVE) ?
- "active " : "backup ") : "",
- slave->dev->name,
- bond->params.downdelay * bond->params.miimon);
+ pr_info("%s: link status down for %sinterface %s, disabling it in %d ms\n",
+ bond->dev->name,
+ (BOND_MODE(bond) ==
+ BOND_MODE_ACTIVEBACKUP) ?
+ (bond_is_active_slave(slave) ?
+ "active " : "backup ") : "",
+ slave->dev->name,
+ bond->params.downdelay * bond->params.miimon);
}
/*FALLTHRU*/
case BOND_LINK_FAIL:
@@ -2260,14 +1930,12 @@ static int bond_miimon_inspect(struct bonding *bond)
* recovered before downdelay expired
*/
slave->link = BOND_LINK_UP;
- slave->jiffies = jiffies;
- printk(KERN_INFO DRV_NAME
- ": %s: link status up again after %d "
- "ms for interface %s.\n",
- bond->dev->name,
- (bond->params.downdelay - slave->delay) *
- bond->params.miimon,
- slave->dev->name);
+ slave->last_link_up = jiffies;
+ pr_info("%s: link status up again after %d ms for interface %s\n",
+ bond->dev->name,
+ (bond->params.downdelay - slave->delay) *
+ bond->params.miimon,
+ slave->dev->name);
continue;
}
@@ -2288,31 +1956,32 @@ static int bond_miimon_inspect(struct bonding *bond)
slave->delay = bond->params.updelay;
if (slave->delay) {
- printk(KERN_INFO DRV_NAME
- ": %s: link status up for "
- "interface %s, enabling it in %d ms.\n",
- bond->dev->name, slave->dev->name,
- bond->params.updelay *
- bond->params.miimon);
+ pr_info("%s: link status up for interface %s, enabling it in %d ms\n",
+ bond->dev->name, slave->dev->name,
+ ignore_updelay ? 0 :
+ bond->params.updelay *
+ bond->params.miimon);
}
/*FALLTHRU*/
case BOND_LINK_BACK:
if (!link_state) {
slave->link = BOND_LINK_DOWN;
- printk(KERN_INFO DRV_NAME
- ": %s: link status down again after %d "
- "ms for interface %s.\n",
- bond->dev->name,
- (bond->params.updelay - slave->delay) *
- bond->params.miimon,
- slave->dev->name);
+ pr_info("%s: link status down again after %d ms for interface %s\n",
+ bond->dev->name,
+ (bond->params.updelay - slave->delay) *
+ bond->params.miimon,
+ slave->dev->name);
continue;
}
+ if (ignore_updelay)
+ slave->delay = 0;
+
if (slave->delay <= 0) {
slave->new_link = BOND_LINK_UP;
commit++;
+ ignore_updelay = false;
continue;
}
@@ -2326,40 +1995,39 @@ static int bond_miimon_inspect(struct bonding *bond)
static void bond_miimon_commit(struct bonding *bond)
{
+ struct list_head *iter;
struct slave *slave;
- int i;
- bond_for_each_slave(bond, slave, i) {
+ bond_for_each_slave(bond, slave, iter) {
switch (slave->new_link) {
case BOND_LINK_NOCHANGE:
continue;
case BOND_LINK_UP:
slave->link = BOND_LINK_UP;
- slave->jiffies = jiffies;
+ slave->last_link_up = jiffies;
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
/* prevent it from being the active one */
- slave->state = BOND_STATE_BACKUP;
- } else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
+ bond_set_backup_slave(slave);
+ } else if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
/* make it immediately active */
- slave->state = BOND_STATE_ACTIVE;
+ bond_set_active_slave(slave);
} else if (slave != bond->primary_slave) {
/* prevent it from being the active one */
- slave->state = BOND_STATE_BACKUP;
+ bond_set_backup_slave(slave);
}
- printk(KERN_INFO DRV_NAME
- ": %s: link status definitely "
- "up for interface %s.\n",
- bond->dev->name, slave->dev->name);
+ pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex\n",
+ bond->dev->name, slave->dev->name,
+ slave->speed == SPEED_UNKNOWN ? 0 : slave->speed,
+ slave->duplex ? "full" : "half");
/* notify ad that the link status has changed */
- if (bond->params.mode == BOND_MODE_8023AD)
+ if (BOND_MODE(bond) == BOND_MODE_8023AD)
bond_3ad_handle_link_change(slave, BOND_LINK_UP);
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB))
+ if (bond_is_lb(bond))
bond_alb_handle_link_change(bond, slave,
BOND_LINK_UP);
@@ -2370,23 +2038,24 @@ static void bond_miimon_commit(struct bonding *bond)
continue;
case BOND_LINK_DOWN:
+ if (slave->link_failure_count < UINT_MAX)
+ slave->link_failure_count++;
+
slave->link = BOND_LINK_DOWN;
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP ||
- bond->params.mode == BOND_MODE_8023AD)
- bond_set_slave_inactive_flags(slave);
+ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP ||
+ BOND_MODE(bond) == BOND_MODE_8023AD)
+ bond_set_slave_inactive_flags(slave,
+ BOND_SLAVE_NOTIFY_NOW);
- printk(KERN_INFO DRV_NAME
- ": %s: link status definitely down for "
- "interface %s, disabling it\n",
- bond->dev->name, slave->dev->name);
+ pr_info("%s: link status definitely down for interface %s, disabling it\n",
+ bond->dev->name, slave->dev->name);
- if (bond->params.mode == BOND_MODE_8023AD)
+ if (BOND_MODE(bond) == BOND_MODE_8023AD)
bond_3ad_handle_link_change(slave,
BOND_LINK_DOWN);
- if (bond->params.mode == BOND_MODE_TLB ||
- bond->params.mode == BOND_MODE_ALB)
+ if (bond_is_lb(bond))
bond_alb_handle_link_change(bond, slave,
BOND_LINK_DOWN);
@@ -2396,8 +2065,7 @@ static void bond_miimon_commit(struct bonding *bond)
continue;
default:
- printk(KERN_ERR DRV_NAME
- ": %s: invalid new link %d on slave %s\n",
+ pr_err("%s: invalid new link %d on slave %s\n",
bond->dev->name, slave->new_link,
slave->dev->name);
slave->new_link = BOND_LINK_NOCHANGE;
@@ -2407,9 +2075,11 @@ static void bond_miimon_commit(struct bonding *bond)
do_failover:
ASSERT_RTNL();
+ block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
}
bond_set_carrier(bond);
@@ -2423,81 +2093,69 @@ do_failover:
* an acquisition of appropriate locks followed by a commit phase to
* implement whatever link state changes are indicated.
*/
-void bond_mii_monitor(struct work_struct *work)
+static void bond_mii_monitor(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
mii_work.work);
+ bool should_notify_peers = false;
+ unsigned long delay;
- read_lock(&bond->lock);
- if (bond->kill_timers)
- goto out;
+ delay = msecs_to_jiffies(bond->params.miimon);
- if (bond->slave_cnt == 0)
+ if (!bond_has_slaves(bond))
goto re_arm;
- if (bond->send_grat_arp) {
- read_lock(&bond->curr_slave_lock);
- bond_send_gratuitous_arp(bond);
- read_unlock(&bond->curr_slave_lock);
- }
+ rcu_read_lock();
+
+ should_notify_peers = bond_should_notify_peers(bond);
if (bond_miimon_inspect(bond)) {
- read_unlock(&bond->lock);
- rtnl_lock();
- read_lock(&bond->lock);
+ rcu_read_unlock();
+
+ /* Race avoidance with bond_close cancel of workqueue */
+ if (!rtnl_trylock()) {
+ delay = 1;
+ should_notify_peers = false;
+ goto re_arm;
+ }
bond_miimon_commit(bond);
- read_unlock(&bond->lock);
rtnl_unlock(); /* might sleep, hold no other locks */
- read_lock(&bond->lock);
- }
+ } else
+ rcu_read_unlock();
re_arm:
if (bond->params.miimon)
- queue_delayed_work(bond->wq, &bond->mii_work,
- msecs_to_jiffies(bond->params.miimon));
-out:
- read_unlock(&bond->lock);
-}
+ queue_delayed_work(bond->wq, &bond->mii_work, delay);
-static __be32 bond_glean_dev_ip(struct net_device *dev)
-{
- struct in_device *idev;
- struct in_ifaddr *ifa;
- __be32 addr = 0;
-
- if (!dev)
- return 0;
-
- rcu_read_lock();
- idev = __in_dev_get_rcu(dev);
- if (!idev)
- goto out;
-
- ifa = idev->ifa_list;
- if (!ifa)
- goto out;
-
- addr = ifa->ifa_local;
-out:
- rcu_read_unlock();
- return addr;
+ if (should_notify_peers) {
+ if (!rtnl_trylock())
+ return;
+ call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev);
+ rtnl_unlock();
+ }
}
-static int bond_has_this_ip(struct bonding *bond, __be32 ip)
+static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
{
- struct vlan_entry *vlan;
+ struct net_device *upper;
+ struct list_head *iter;
+ bool ret = false;
- if (ip == bond->master_ip)
- return 1;
+ if (ip == bond_confirm_addr(bond->dev, 0, ip))
+ return true;
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- if (ip == vlan->vlan_ip)
- return 1;
+ rcu_read_lock();
+ netdev_for_each_all_upper_dev_rcu(bond->dev, upper, iter) {
+ if (ip == bond_confirm_addr(upper, 0, ip)) {
+ ret = true;
+ break;
+ }
}
+ rcu_read_unlock();
- return 0;
+ return ret;
}
/*
@@ -2505,193 +2163,191 @@ static int bond_has_this_ip(struct bonding *bond, __be32 ip)
* switches in VLAN mode (especially if ports are configured as
* "native" to a VLAN) might not pass non-tagged frames.
*/
-static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ip, __be32 src_ip, unsigned short vlan_id)
+static void bond_arp_send(struct net_device *slave_dev, int arp_op,
+ __be32 dest_ip, __be32 src_ip,
+ struct bond_vlan_tag *tags)
{
struct sk_buff *skb;
+ int i;
+
+ pr_debug("arp %d on slave %s: dst %pI4 src %pI4\n",
+ arp_op, slave_dev->name, &dest_ip, &src_ip);
- dprintk("arp %d on slave %s: dst %x src %x vid %d\n", arp_op,
- slave_dev->name, dest_ip, src_ip, vlan_id);
-
skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
NULL, slave_dev->dev_addr, NULL);
if (!skb) {
- printk(KERN_ERR DRV_NAME ": ARP packet allocation failed\n");
+ net_err_ratelimited("ARP packet allocation failed\n");
return;
}
- if (vlan_id) {
- skb = vlan_put_tag(skb, vlan_id);
+
+ /* Go through all the tags backwards and add them to the packet */
+ for (i = BOND_MAX_VLAN_ENCAP - 1; i > 0; i--) {
+ if (!tags[i].vlan_id)
+ continue;
+
+ pr_debug("inner tag: proto %X vid %X\n",
+ ntohs(tags[i].vlan_proto), tags[i].vlan_id);
+ skb = __vlan_put_tag(skb, tags[i].vlan_proto,
+ tags[i].vlan_id);
if (!skb) {
- printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n");
+ net_err_ratelimited("failed to insert inner VLAN tag\n");
+ return;
+ }
+ }
+ /* Set the outer tag */
+ if (tags[0].vlan_id) {
+ pr_debug("outer tag: proto %X vid %X\n",
+ ntohs(tags[0].vlan_proto), tags[0].vlan_id);
+ skb = vlan_put_tag(skb, tags[0].vlan_proto, tags[0].vlan_id);
+ if (!skb) {
+ net_err_ratelimited("failed to insert outer VLAN tag\n");
return;
}
}
arp_xmit(skb);
}
+/* Validate the device path between the @start_dev and the @end_dev.
+ * The path is valid if the @end_dev is reachable through device
+ * stacking.
+ * When the path is validated, collect any vlan information in the
+ * path.
+ */
+bool bond_verify_device_path(struct net_device *start_dev,
+ struct net_device *end_dev,
+ struct bond_vlan_tag *tags)
+{
+ struct net_device *upper;
+ struct list_head *iter;
+ int idx;
+
+ if (start_dev == end_dev)
+ return true;
+
+ netdev_for_each_upper_dev_rcu(start_dev, upper, iter) {
+ if (bond_verify_device_path(upper, end_dev, tags)) {
+ if (is_vlan_dev(upper)) {
+ idx = vlan_get_encap_level(upper);
+ if (idx >= BOND_MAX_VLAN_ENCAP)
+ return false;
+
+ tags[idx].vlan_proto =
+ vlan_dev_vlan_proto(upper);
+ tags[idx].vlan_id = vlan_dev_vlan_id(upper);
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
{
- int i, vlan_id, rv;
- __be32 *targets = bond->params.arp_targets;
- struct vlan_entry *vlan;
- struct net_device *vlan_dev;
- struct flowi fl;
struct rtable *rt;
-
- for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
- if (!targets[i])
- continue;
- dprintk("basa: target %x\n", targets[i]);
- if (list_empty(&bond->vlan_list)) {
- dprintk("basa: empty vlan: arp_send\n");
+ struct bond_vlan_tag tags[BOND_MAX_VLAN_ENCAP];
+ __be32 *targets = bond->params.arp_targets, addr;
+ int i;
+ bool ret;
+
+ for (i = 0; i < BOND_MAX_ARP_TARGETS && targets[i]; i++) {
+ pr_debug("basa: target %pI4\n", &targets[i]);
+ memset(tags, 0, sizeof(tags));
+
+ /* Find out through which dev should the packet go */
+ rt = ip_route_output(dev_net(bond->dev), targets[i], 0,
+ RTO_ONLINK, 0);
+ if (IS_ERR(rt)) {
+ /* there's no route to target - try to send arp
+ * probe to generate any traffic (arp_validate=0)
+ */
+ if (bond->params.arp_validate)
+ net_warn_ratelimited("%s: no route to arp_ip_target %pI4 and arp_validate is set\n",
+ bond->dev->name,
+ &targets[i]);
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
- bond->master_ip, 0);
+ 0, tags);
continue;
}
- /*
- * If VLANs are configured, we do a route lookup to
- * determine which VLAN interface would be used, so we
- * can tag the ARP with the proper VLAN tag.
- */
- memset(&fl, 0, sizeof(fl));
- fl.fl4_dst = targets[i];
- fl.fl4_tos = RTO_ONLINK;
+ /* bond device itself */
+ if (rt->dst.dev == bond->dev)
+ goto found;
- rv = ip_route_output_key(&init_net, &rt, &fl);
- if (rv) {
- if (net_ratelimit()) {
- printk(KERN_WARNING DRV_NAME
- ": %s: no route to arp_ip_target %u.%u.%u.%u\n",
- bond->dev->name, NIPQUAD(fl.fl4_dst));
- }
- continue;
- }
+ rcu_read_lock();
+ ret = bond_verify_device_path(bond->dev, rt->dst.dev, tags);
+ rcu_read_unlock();
- /*
- * This target is not on a VLAN
- */
- if (rt->u.dst.dev == bond->dev) {
- ip_rt_put(rt);
- dprintk("basa: rtdev == bond->dev: arp_send\n");
- bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
- bond->master_ip, 0);
- continue;
- }
+ if (ret)
+ goto found;
- vlan_id = 0;
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
- if (vlan_dev == rt->u.dst.dev) {
- vlan_id = vlan->vlan_id;
- dprintk("basa: vlan match on %s %d\n",
- vlan_dev->name, vlan_id);
- break;
- }
- }
+ /* Not our device - skip */
+ pr_debug("%s: no path to arp_ip_target %pI4 via rt.dev %s\n",
+ bond->dev->name, &targets[i],
+ rt->dst.dev ? rt->dst.dev->name : "NULL");
- if (vlan_id) {
- ip_rt_put(rt);
- bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
- vlan->vlan_ip, vlan_id);
- continue;
- }
+ ip_rt_put(rt);
+ continue;
- if (net_ratelimit()) {
- printk(KERN_WARNING DRV_NAME
- ": %s: no path to arp_ip_target %u.%u.%u.%u via rt.dev %s\n",
- bond->dev->name, NIPQUAD(fl.fl4_dst),
- rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
- }
+found:
+ addr = bond_confirm_addr(rt->dst.dev, targets[i], 0);
ip_rt_put(rt);
+ bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
+ addr, tags);
}
}
-/*
- * Kick out a gratuitous ARP for an IP on the bonding master plus one
- * for each VLAN above us.
- *
- * Caller must hold curr_slave_lock for read or better
- */
-static void bond_send_gratuitous_arp(struct bonding *bond)
+static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
{
- struct slave *slave = bond->curr_active_slave;
- struct vlan_entry *vlan;
- struct net_device *vlan_dev;
-
- dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
- slave ? slave->dev->name : "NULL");
+ int i;
- if (!slave || !bond->send_grat_arp ||
- test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
+ if (!sip || !bond_has_this_ip(bond, tip)) {
+ pr_debug("bva: sip %pI4 tip %pI4 not found\n", &sip, &tip);
return;
-
- bond->send_grat_arp--;
-
- if (bond->master_ip) {
- bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
- bond->master_ip, 0);
- }
-
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
- if (vlan->vlan_ip) {
- bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip,
- vlan->vlan_ip, vlan->vlan_id);
- }
}
-}
-static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
-{
- int i;
- __be32 *targets = bond->params.arp_targets;
-
- targets = bond->params.arp_targets;
- for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
- dprintk("bva: sip %u.%u.%u.%u tip %u.%u.%u.%u t[%d] "
- "%u.%u.%u.%u bhti(tip) %d\n",
- NIPQUAD(sip), NIPQUAD(tip), i, NIPQUAD(targets[i]),
- bond_has_this_ip(bond, tip));
- if (sip == targets[i]) {
- if (bond_has_this_ip(bond, tip))
- slave->last_arp_rx = jiffies;
- return;
- }
+ i = bond_get_targets_ip(bond->params.arp_targets, sip);
+ if (i == -1) {
+ pr_debug("bva: sip %pI4 not found in targets\n", &sip);
+ return;
}
+ slave->last_rx = jiffies;
+ slave->target_last_arp_rx[i] = jiffies;
}
-static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct arphdr *arp;
- struct slave *slave;
- struct bonding *bond;
+ struct arphdr *arp = (struct arphdr *)skb->data;
+ struct slave *curr_active_slave;
unsigned char *arp_ptr;
__be32 sip, tip;
+ int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
- if (dev_net(dev) != &init_net)
- goto out;
-
- if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
- goto out;
-
- bond = dev->priv;
- read_lock(&bond->lock);
+ if (!slave_do_arp_validate(bond, slave)) {
+ if ((slave_do_arp_validate_only(bond) && is_arp) ||
+ !slave_do_arp_validate_only(bond))
+ slave->last_rx = jiffies;
+ return RX_HANDLER_ANOTHER;
+ } else if (!is_arp) {
+ return RX_HANDLER_ANOTHER;
+ }
- dprintk("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
- bond->dev->name, skb->dev ? skb->dev->name : "NULL",
- orig_dev ? orig_dev->name : "NULL");
+ alen = arp_hdr_len(bond->dev);
- slave = bond_get_slave_by_dev(bond, orig_dev);
- if (!slave || !slave_do_arp_validate(bond, slave))
- goto out_unlock;
+ pr_debug("bond_arp_rcv: bond %s skb->dev %s\n",
+ bond->dev->name, skb->dev->name);
- if (!pskb_may_pull(skb, arp_hdr_len(dev)))
- goto out_unlock;
+ if (alen > skb_headlen(skb)) {
+ arp = kmalloc(alen, GFP_ATOMIC);
+ if (!arp)
+ goto out_unlock;
+ if (skb_copy_bits(skb, 0, arp, alen) < 0)
+ goto out_unlock;
+ }
- arp = arp_hdr(skb);
- if (arp->ar_hln != dev->addr_len ||
+ if (arp->ar_hln != bond->dev->addr_len ||
skb->pkt_type == PACKET_OTHERHOST ||
skb->pkt_type == PACKET_LOOPBACK ||
arp->ar_hrd != htons(ARPHRD_ETHER) ||
@@ -2700,15 +2356,17 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
goto out_unlock;
arp_ptr = (unsigned char *)(arp + 1);
- arp_ptr += dev->addr_len;
+ arp_ptr += bond->dev->addr_len;
memcpy(&sip, arp_ptr, 4);
- arp_ptr += 4 + dev->addr_len;
+ arp_ptr += 4 + bond->dev->addr_len;
memcpy(&tip, arp_ptr, 4);
- dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %u.%u.%u.%u"
- " tip %u.%u.%u.%u\n", bond->dev->name, slave->dev->name,
- slave->state, bond->params.arp_validate,
- slave_do_arp_validate(bond, slave), NIPQUAD(sip), NIPQUAD(tip));
+ pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
+ bond->dev->name, slave->dev->name, bond_slave_state(slave),
+ bond->params.arp_validate, slave_do_arp_validate(bond, slave),
+ &sip, &tip);
+
+ curr_active_slave = rcu_dereference(bond->curr_active_slave);
/*
* Backup slaves won't see the ARP reply, but do come through
@@ -2717,17 +2375,38 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
* configuration, the ARP probe will (hopefully) travel from
* the active, through one switch, the router, then the other
* switch before reaching the backup.
+ *
+ * We 'trust' the arp requests if there is an active slave and
+ * it received valid arp reply(s) after it became active. This
+ * is done to avoid endless looping when we can't reach the
+ * arp_ip_target and fool ourselves with our own arp requests.
*/
- if (slave->state == BOND_STATE_ACTIVE)
+
+ if (bond_is_active_slave(slave))
bond_validate_arp(bond, slave, sip, tip);
- else
+ else if (curr_active_slave &&
+ time_after(slave_last_rx(bond, curr_active_slave),
+ curr_active_slave->last_link_up))
bond_validate_arp(bond, slave, tip, sip);
out_unlock:
- read_unlock(&bond->lock);
-out:
- dev_kfree_skb(skb);
- return NET_RX_SUCCESS;
+ if (arp != (struct arphdr *)skb->data)
+ kfree(arp);
+ return RX_HANDLER_ANOTHER;
+}
+
+/* function to verify if we're in the arp_interval timeslice, returns true if
+ * (last_act - arp_interval) <= jiffies <= (last_act + mod * arp_interval +
+ * arp_interval/2) . the arp_interval/2 is needed for really fast networks.
+ */
+static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act,
+ int mod)
+{
+ int delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
+
+ return time_in_range(jiffies,
+ last_act - delta_in_ticks,
+ last_act + mod * delta_in_ticks + delta_in_ticks/2);
}
/*
@@ -2737,46 +2416,37 @@ out:
* arp is transmitted to generate traffic. see activebackup_arp_monitor for
* arp monitoring in active backup mode.
*/
-void bond_loadbalance_arp_mon(struct work_struct *work)
+static void bond_loadbalance_arp_mon(struct work_struct *work)
{
struct bonding *bond = container_of(work, struct bonding,
arp_work.work);
struct slave *slave, *oldcurrent;
- int do_failover = 0;
- int delta_in_ticks;
- int i;
+ struct list_head *iter;
+ int do_failover = 0, slave_state_changed = 0;
- read_lock(&bond->lock);
-
- delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
-
- if (bond->kill_timers) {
- goto out;
- }
-
- if (bond->slave_cnt == 0) {
+ if (!bond_has_slaves(bond))
goto re_arm;
- }
- read_lock(&bond->curr_slave_lock);
- oldcurrent = bond->curr_active_slave;
- read_unlock(&bond->curr_slave_lock);
+ rcu_read_lock();
+ oldcurrent = ACCESS_ONCE(bond->curr_active_slave);
/* see if any of the previous devices are up now (i.e. they have
* xmt and rcv traffic). the curr_active_slave does not come into
- * the picture unless it is null. also, slave->jiffies is not needed
- * here because we send an arp on each slave and give a slave as
- * long as it needs to get the tx/rx within the delta.
+ * the picture unless it is null. also, slave->last_link_up is not
+ * needed here because we send an arp on each slave and give a slave
+ * as long as it needs to get the tx/rx within the delta.
* TODO: what about up/down delay in arp mode? it wasn't here before
* so it can wait
*/
- bond_for_each_slave(bond, slave, i) {
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ unsigned long trans_start = dev_trans_start(slave->dev);
+
if (slave->link != BOND_LINK_UP) {
- if (time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks) &&
- time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) {
+ if (bond_time_in_interval(bond, trans_start, 1) &&
+ bond_time_in_interval(bond, slave->last_rx, 1)) {
slave->link = BOND_LINK_UP;
- slave->state = BOND_STATE_ACTIVE;
+ slave_state_changed = 1;
/* primary_slave has no meaning in round-robin
* mode. the window of a slave being up and
@@ -2784,17 +2454,14 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* is closed.
*/
if (!oldcurrent) {
- printk(KERN_INFO DRV_NAME
- ": %s: link status definitely "
- "up for interface %s, ",
- bond->dev->name,
- slave->dev->name);
+ pr_info("%s: link status definitely up for interface %s\n",
+ bond->dev->name,
+ slave->dev->name);
do_failover = 1;
} else {
- printk(KERN_INFO DRV_NAME
- ": %s: interface %s is now up\n",
- bond->dev->name,
- slave->dev->name);
+ pr_info("%s: interface %s is now up\n",
+ bond->dev->name,
+ slave->dev->name);
}
}
} else {
@@ -2804,24 +2471,20 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* when the source ip is 0, so don't take the link down
* if we don't know our ip yet
*/
- if (time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) ||
- (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks))) {
+ if (!bond_time_in_interval(bond, trans_start, 2) ||
+ !bond_time_in_interval(bond, slave->last_rx, 2)) {
slave->link = BOND_LINK_DOWN;
- slave->state = BOND_STATE_BACKUP;
+ slave_state_changed = 1;
- if (slave->link_failure_count < UINT_MAX) {
+ if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
- }
- printk(KERN_INFO DRV_NAME
- ": %s: interface %s is now down.\n",
- bond->dev->name,
- slave->dev->name);
+ pr_info("%s: interface %s is now down\n",
+ bond->dev->name, slave->dev->name);
- if (slave == oldcurrent) {
+ if (slave == oldcurrent)
do_failover = 1;
- }
}
}
@@ -2832,24 +2495,37 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
* do - all replies will be rx'ed on same link causing slaves
* to be unstable during low/no traffic periods
*/
- if (IS_UP(slave->dev)) {
+ if (bond_slave_is_up(slave))
bond_arp_send_all(bond, slave);
- }
}
- if (do_failover) {
- write_lock_bh(&bond->curr_slave_lock);
+ rcu_read_unlock();
- bond_select_active_slave(bond);
+ if (do_failover || slave_state_changed) {
+ if (!rtnl_trylock())
+ goto re_arm;
- write_unlock_bh(&bond->curr_slave_lock);
+ if (slave_state_changed) {
+ bond_slave_state_change(bond);
+ } else if (do_failover) {
+ /* the bond_select_active_slave must hold RTNL
+ * and curr_slave_lock for write.
+ */
+ block_netpoll_tx();
+ write_lock_bh(&bond->curr_slave_lock);
+
+ bond_select_active_slave(bond);
+
+ write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
+ }
+ rtnl_unlock();
}
re_arm:
if (bond->params.arp_interval)
- queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
-out:
- read_unlock(&bond->lock);
+ queue_delayed_work(bond->wq, &bond->arp_work,
+ msecs_to_jiffies(bond->params.arp_interval));
}
/*
@@ -2858,23 +2534,24 @@ out:
* place for the slave. Returns 0 if no changes are found, >0 if changes
* to link states must be committed.
*
- * Called with bond->lock held for read.
+ * Called with rcu_read_lock hold.
*/
-static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
+static int bond_ab_arp_inspect(struct bonding *bond)
{
+ unsigned long trans_start, last_rx;
+ struct list_head *iter;
struct slave *slave;
- int i, commit = 0;
+ int commit = 0;
- bond_for_each_slave(bond, slave, i) {
+ bond_for_each_slave_rcu(bond, slave, iter) {
slave->new_link = BOND_LINK_NOCHANGE;
+ last_rx = slave_last_rx(bond, slave);
if (slave->link != BOND_LINK_UP) {
- if (time_before_eq(jiffies, slave_last_rx(bond, slave) +
- delta_in_ticks)) {
+ if (bond_time_in_interval(bond, last_rx, 1)) {
slave->new_link = BOND_LINK_UP;
commit++;
}
-
continue;
}
@@ -2883,8 +2560,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* active. This avoids bouncing, as the last receive
* times need a full ARP monitor cycle to be updated.
*/
- if (!time_after_eq(jiffies, slave->jiffies +
- 2 * delta_in_ticks))
+ if (bond_time_in_interval(bond, slave->last_link_up, 2))
continue;
/*
@@ -2900,10 +2576,9 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* gives each slave a chance to tx/rx traffic
* before being taken out
*/
- if (slave->state == BOND_STATE_BACKUP &&
+ if (!bond_is_active_slave(slave) &&
!bond->current_arp_slave &&
- time_after(jiffies, slave_last_rx(bond, slave) +
- 3 * delta_in_ticks)) {
+ !bond_time_in_interval(bond, last_rx, 3)) {
slave->new_link = BOND_LINK_DOWN;
commit++;
}
@@ -2914,28 +2589,15 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* - (more than 2*delta since receive AND
* the bond has an IP address)
*/
- if ((slave->state == BOND_STATE_ACTIVE) &&
- (time_after_eq(jiffies, slave->dev->trans_start +
- 2 * delta_in_ticks) ||
- (time_after_eq(jiffies, slave_last_rx(bond, slave)
- + 2 * delta_in_ticks)))) {
+ trans_start = dev_trans_start(slave->dev);
+ if (bond_is_active_slave(slave) &&
+ (!bond_time_in_interval(bond, trans_start, 2) ||
+ !bond_time_in_interval(bond, last_rx, 2))) {
slave->new_link = BOND_LINK_DOWN;
commit++;
}
}
- read_lock(&bond->curr_slave_lock);
-
- /*
- * Trigger a commit if the primary option setting has changed.
- */
- if (bond->primary_slave &&
- (bond->primary_slave != bond->curr_active_slave) &&
- (bond->primary_slave->link == BOND_LINK_UP))
- commit++;
-
- read_unlock(&bond->curr_slave_lock);
-
return commit;
}
@@ -2943,104 +2605,75 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
* Called to commit link state changes noted by inspection step of
* active-backup mode ARP monitor.
*
- * Called with RTNL and bond->lock for read.
+ * Called with RTNL hold.
*/
-static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
+static void bond_ab_arp_commit(struct bonding *bond)
{
+ unsigned long trans_start;
+ struct list_head *iter;
struct slave *slave;
- int i;
- bond_for_each_slave(bond, slave, i) {
+ bond_for_each_slave(bond, slave, iter) {
switch (slave->new_link) {
case BOND_LINK_NOCHANGE:
continue;
case BOND_LINK_UP:
- write_lock_bh(&bond->curr_slave_lock);
-
- if (!bond->curr_active_slave &&
- time_before_eq(jiffies, slave->dev->trans_start +
- delta_in_ticks)) {
+ trans_start = dev_trans_start(slave->dev);
+ if (bond->curr_active_slave != slave ||
+ (!bond->curr_active_slave &&
+ bond_time_in_interval(bond, trans_start, 1))) {
slave->link = BOND_LINK_UP;
- bond_change_active_slave(bond, slave);
- bond->current_arp_slave = NULL;
+ if (bond->current_arp_slave) {
+ bond_set_slave_inactive_flags(
+ bond->current_arp_slave,
+ BOND_SLAVE_NOTIFY_NOW);
+ bond->current_arp_slave = NULL;
+ }
- printk(KERN_INFO DRV_NAME
- ": %s: %s is up and now the "
- "active interface\n",
- bond->dev->name, slave->dev->name);
-
- } else if (bond->curr_active_slave != slave) {
- /* this slave has just come up but we
- * already have a current slave; this can
- * also happen if bond_enslave adds a new
- * slave that is up while we are searching
- * for a new slave
- */
- slave->link = BOND_LINK_UP;
- bond_set_slave_inactive_flags(slave);
- bond->current_arp_slave = NULL;
+ pr_info("%s: link status definitely up for interface %s\n",
+ bond->dev->name, slave->dev->name);
- printk(KERN_INFO DRV_NAME
- ": %s: backup interface %s is now up\n",
- bond->dev->name, slave->dev->name);
- }
+ if (!bond->curr_active_slave ||
+ (slave == bond->primary_slave))
+ goto do_failover;
- write_unlock_bh(&bond->curr_slave_lock);
+ }
- break;
+ continue;
case BOND_LINK_DOWN:
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
slave->link = BOND_LINK_DOWN;
+ bond_set_slave_inactive_flags(slave,
+ BOND_SLAVE_NOTIFY_NOW);
- if (slave == bond->curr_active_slave) {
- printk(KERN_INFO DRV_NAME
- ": %s: link status down for active "
- "interface %s, disabling it\n",
- bond->dev->name, slave->dev->name);
-
- bond_set_slave_inactive_flags(slave);
-
- write_lock_bh(&bond->curr_slave_lock);
-
- bond_select_active_slave(bond);
- if (bond->curr_active_slave)
- bond->curr_active_slave->jiffies =
- jiffies;
-
- write_unlock_bh(&bond->curr_slave_lock);
+ pr_info("%s: link status definitely down for interface %s, disabling it\n",
+ bond->dev->name, slave->dev->name);
+ if (slave == bond->curr_active_slave) {
bond->current_arp_slave = NULL;
-
- } else if (slave->state == BOND_STATE_BACKUP) {
- printk(KERN_INFO DRV_NAME
- ": %s: backup interface %s is now down\n",
- bond->dev->name, slave->dev->name);
-
- bond_set_slave_inactive_flags(slave);
+ goto do_failover;
}
- break;
+
+ continue;
default:
- printk(KERN_ERR DRV_NAME
- ": %s: impossible: new_link %d on slave %s\n",
+ pr_err("%s: impossible: new_link %d on slave %s\n",
bond->dev->name, slave->new_link,
slave->dev->name);
+ continue;
}
- }
- /*
- * No race with changes to primary via sysfs, as we hold rtnl.
- */
- if (bond->primary_slave &&
- (bond->primary_slave != bond->curr_active_slave) &&
- (bond->primary_slave->link == BOND_LINK_UP)) {
+do_failover:
+ ASSERT_RTNL();
+ block_netpoll_tx();
write_lock_bh(&bond->curr_slave_lock);
- bond_change_active_slave(bond, bond->primary_slave);
+ bond_select_active_slave(bond);
write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
}
bond_set_carrier(bond);
@@ -3049,52 +2682,46 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
/*
* Send ARP probes for active-backup mode ARP monitor.
*
- * Called with bond->lock held for read.
+ * Called with rcu_read_lock hold.
*/
-static void bond_ab_arp_probe(struct bonding *bond)
+static bool bond_ab_arp_probe(struct bonding *bond)
{
- struct slave *slave;
- int i;
-
- read_lock(&bond->curr_slave_lock);
+ struct slave *slave, *before = NULL, *new_slave = NULL,
+ *curr_arp_slave = rcu_dereference(bond->current_arp_slave),
+ *curr_active_slave = rcu_dereference(bond->curr_active_slave);
+ struct list_head *iter;
+ bool found = false;
+ bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER;
- if (bond->current_arp_slave && bond->curr_active_slave)
- printk("PROBE: c_arp %s && cas %s BAD\n",
- bond->current_arp_slave->dev->name,
- bond->curr_active_slave->dev->name);
+ if (curr_arp_slave && curr_active_slave)
+ pr_info("PROBE: c_arp %s && cas %s BAD\n",
+ curr_arp_slave->dev->name,
+ curr_active_slave->dev->name);
- if (bond->curr_active_slave) {
- bond_arp_send_all(bond, bond->curr_active_slave);
- read_unlock(&bond->curr_slave_lock);
- return;
+ if (curr_active_slave) {
+ bond_arp_send_all(bond, curr_active_slave);
+ return should_notify_rtnl;
}
- read_unlock(&bond->curr_slave_lock);
-
/* if we don't have a curr_active_slave, search for the next available
* backup slave from the current_arp_slave and make it the candidate
* for becoming the curr_active_slave
*/
- if (!bond->current_arp_slave) {
- bond->current_arp_slave = bond->first_slave;
- if (!bond->current_arp_slave)
- return;
+ if (!curr_arp_slave) {
+ curr_arp_slave = bond_first_slave_rcu(bond);
+ if (!curr_arp_slave)
+ return should_notify_rtnl;
}
- bond_set_slave_inactive_flags(bond->current_arp_slave);
+ bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER);
- /* search for next candidate */
- bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave->next) {
- if (IS_UP(slave->dev)) {
- slave->link = BOND_LINK_BACK;
- bond_set_slave_active_flags(slave);
- bond_arp_send_all(bond, slave);
- slave->jiffies = jiffies;
- bond->current_arp_slave = slave;
- break;
- }
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (!found && !before && bond_slave_is_up(slave))
+ before = slave;
+ if (found && !new_slave && bond_slave_is_up(slave))
+ new_slave = slave;
/* if the link state is up at this point, we
* mark it down - this can happen if we have
* simultaneous link failures and
@@ -3102,366 +2729,96 @@ static void bond_ab_arp_probe(struct bonding *bond)
* one the current slave so it is still marked
* up when it is actually down
*/
- if (slave->link == BOND_LINK_UP) {
+ if (!bond_slave_is_up(slave) && slave->link == BOND_LINK_UP) {
slave->link = BOND_LINK_DOWN;
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
- bond_set_slave_inactive_flags(slave);
+ bond_set_slave_inactive_flags(slave,
+ BOND_SLAVE_NOTIFY_LATER);
- printk(KERN_INFO DRV_NAME
- ": %s: backup interface %s is now down.\n",
- bond->dev->name, slave->dev->name);
+ pr_info("%s: backup interface %s is now down\n",
+ bond->dev->name, slave->dev->name);
}
+ if (slave == curr_arp_slave)
+ found = true;
}
-}
-
-void bond_activebackup_arp_mon(struct work_struct *work)
-{
- struct bonding *bond = container_of(work, struct bonding,
- arp_work.work);
- int delta_in_ticks;
- read_lock(&bond->lock);
+ if (!new_slave && before)
+ new_slave = before;
- if (bond->kill_timers)
- goto out;
+ if (!new_slave)
+ goto check_state;
- delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
+ new_slave->link = BOND_LINK_BACK;
+ bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER);
+ bond_arp_send_all(bond, new_slave);
+ new_slave->last_link_up = jiffies;
+ rcu_assign_pointer(bond->current_arp_slave, new_slave);
- if (bond->slave_cnt == 0)
- goto re_arm;
-
- if (bond->send_grat_arp) {
- read_lock(&bond->curr_slave_lock);
- bond_send_gratuitous_arp(bond);
- read_unlock(&bond->curr_slave_lock);
- }
-
- if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
- read_unlock(&bond->lock);
- rtnl_lock();
- read_lock(&bond->lock);
-
- bond_ab_arp_commit(bond, delta_in_ticks);
-
- read_unlock(&bond->lock);
- rtnl_unlock();
- read_lock(&bond->lock);
- }
-
- bond_ab_arp_probe(bond);
-
-re_arm:
- if (bond->params.arp_interval) {
- queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
- }
-out:
- read_unlock(&bond->lock);
-}
-
-/*------------------------------ proc/seq_file-------------------------------*/
-
-#ifdef CONFIG_PROC_FS
-
-static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
-{
- struct bonding *bond = seq->private;
- loff_t off = 0;
- struct slave *slave;
- int i;
-
- /* make sure the bond won't be taken away */
- read_lock(&dev_base_lock);
- read_lock(&bond->lock);
-
- if (*pos == 0) {
- return SEQ_START_TOKEN;
- }
-
- bond_for_each_slave(bond, slave, i) {
- if (++off == *pos) {
- return slave;
+check_state:
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (slave->should_notify) {
+ should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW;
+ break;
}
}
-
- return NULL;
+ return should_notify_rtnl;
}
-static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static void bond_activebackup_arp_mon(struct work_struct *work)
{
- struct bonding *bond = seq->private;
- struct slave *slave = v;
-
- ++*pos;
- if (v == SEQ_START_TOKEN) {
- return bond->first_slave;
- }
-
- slave = slave->next;
-
- return (slave == bond->first_slave) ? NULL : slave;
-}
-
-static void bond_info_seq_stop(struct seq_file *seq, void *v)
-{
- struct bonding *bond = seq->private;
-
- read_unlock(&bond->lock);
- read_unlock(&dev_base_lock);
-}
-
-static void bond_info_show_master(struct seq_file *seq)
-{
- struct bonding *bond = seq->private;
- struct slave *curr;
- int i;
- u32 target;
-
- read_lock(&bond->curr_slave_lock);
- curr = bond->curr_active_slave;
- read_unlock(&bond->curr_slave_lock);
-
- seq_printf(seq, "Bonding Mode: %s",
- bond_mode_name(bond->params.mode));
-
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
- bond->params.fail_over_mac)
- seq_printf(seq, " (fail_over_mac %s)",
- fail_over_mac_tbl[bond->params.fail_over_mac].modename);
-
- seq_printf(seq, "\n");
-
- if (bond->params.mode == BOND_MODE_XOR ||
- bond->params.mode == BOND_MODE_8023AD) {
- seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
- xmit_hashtype_tbl[bond->params.xmit_policy].modename,
- bond->params.xmit_policy);
- }
-
- if (USES_PRIMARY(bond->params.mode)) {
- seq_printf(seq, "Primary Slave: %s\n",
- (bond->primary_slave) ?
- bond->primary_slave->dev->name : "None");
-
- seq_printf(seq, "Currently Active Slave: %s\n",
- (curr) ? curr->dev->name : "None");
- }
-
- seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
- "up" : "down");
- seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
- seq_printf(seq, "Up Delay (ms): %d\n",
- bond->params.updelay * bond->params.miimon);
- seq_printf(seq, "Down Delay (ms): %d\n",
- bond->params.downdelay * bond->params.miimon);
-
-
- /* ARP information */
- if(bond->params.arp_interval > 0) {
- int printed=0;
- seq_printf(seq, "ARP Polling Interval (ms): %d\n",
- bond->params.arp_interval);
+ struct bonding *bond = container_of(work, struct bonding,
+ arp_work.work);
+ bool should_notify_peers = false;
+ bool should_notify_rtnl = false;
+ int delta_in_ticks;
- seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
+ delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
- for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
- if (!bond->params.arp_targets[i])
- continue;
- if (printed)
- seq_printf(seq, ",");
- target = ntohl(bond->params.arp_targets[i]);
- seq_printf(seq, " %d.%d.%d.%d", HIPQUAD(target));
- printed = 1;
- }
- seq_printf(seq, "\n");
- }
+ if (!bond_has_slaves(bond))
+ goto re_arm;
- if (bond->params.mode == BOND_MODE_8023AD) {
- struct ad_info ad_info;
- DECLARE_MAC_BUF(mac);
+ rcu_read_lock();
- seq_puts(seq, "\n802.3ad info\n");
- seq_printf(seq, "LACP rate: %s\n",
- (bond->params.lacp_fast) ? "fast" : "slow");
+ should_notify_peers = bond_should_notify_peers(bond);
- if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
- seq_printf(seq, "bond %s has no active aggregator\n",
- bond->dev->name);
- } else {
- seq_printf(seq, "Active Aggregator Info:\n");
-
- seq_printf(seq, "\tAggregator ID: %d\n",
- ad_info.aggregator_id);
- seq_printf(seq, "\tNumber of ports: %d\n",
- ad_info.ports);
- seq_printf(seq, "\tActor Key: %d\n",
- ad_info.actor_key);
- seq_printf(seq, "\tPartner Key: %d\n",
- ad_info.partner_key);
- seq_printf(seq, "\tPartner Mac Address: %s\n",
- print_mac(mac, ad_info.partner_system));
- }
- }
-}
+ if (bond_ab_arp_inspect(bond)) {
+ rcu_read_unlock();
-static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
-{
- struct bonding *bond = seq->private;
- DECLARE_MAC_BUF(mac);
-
- seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
- seq_printf(seq, "MII Status: %s\n",
- (slave->link == BOND_LINK_UP) ? "up" : "down");
- seq_printf(seq, "Link Failure Count: %u\n",
- slave->link_failure_count);
-
- seq_printf(seq,
- "Permanent HW addr: %s\n",
- print_mac(mac, slave->perm_hwaddr));
-
- if (bond->params.mode == BOND_MODE_8023AD) {
- const struct aggregator *agg
- = SLAVE_AD_INFO(slave).port.aggregator;
-
- if (agg) {
- seq_printf(seq, "Aggregator ID: %d\n",
- agg->aggregator_identifier);
- } else {
- seq_puts(seq, "Aggregator ID: N/A\n");
+ /* Race avoidance with bond_close flush of workqueue */
+ if (!rtnl_trylock()) {
+ delta_in_ticks = 1;
+ should_notify_peers = false;
+ goto re_arm;
}
- }
-}
-static int bond_info_seq_show(struct seq_file *seq, void *v)
-{
- if (v == SEQ_START_TOKEN) {
- seq_printf(seq, "%s\n", version);
- bond_info_show_master(seq);
- } else {
- bond_info_show_slave(seq, v);
- }
-
- return 0;
-}
-
-static struct seq_operations bond_info_seq_ops = {
- .start = bond_info_seq_start,
- .next = bond_info_seq_next,
- .stop = bond_info_seq_stop,
- .show = bond_info_seq_show,
-};
-
-static int bond_info_open(struct inode *inode, struct file *file)
-{
- struct seq_file *seq;
- struct proc_dir_entry *proc;
- int res;
-
- res = seq_open(file, &bond_info_seq_ops);
- if (!res) {
- /* recover the pointer buried in proc_dir_entry data */
- seq = file->private_data;
- proc = PDE(inode);
- seq->private = proc->data;
- }
-
- return res;
-}
-
-static const struct file_operations bond_info_fops = {
- .owner = THIS_MODULE,
- .open = bond_info_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static int bond_create_proc_entry(struct bonding *bond)
-{
- struct net_device *bond_dev = bond->dev;
-
- if (bond_proc_dir) {
- bond->proc_entry = proc_create_data(bond_dev->name,
- S_IRUGO, bond_proc_dir,
- &bond_info_fops, bond);
- if (bond->proc_entry == NULL) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: Cannot create /proc/net/%s/%s\n",
- DRV_NAME, bond_dev->name);
- } else {
- memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
- }
- }
+ bond_ab_arp_commit(bond);
- return 0;
-}
-
-static void bond_remove_proc_entry(struct bonding *bond)
-{
- if (bond_proc_dir && bond->proc_entry) {
- remove_proc_entry(bond->proc_file_name, bond_proc_dir);
- memset(bond->proc_file_name, 0, IFNAMSIZ);
- bond->proc_entry = NULL;
- }
-}
-
-/* Create the bonding directory under /proc/net, if doesn't exist yet.
- * Caller must hold rtnl_lock.
- */
-static void bond_create_proc_dir(void)
-{
- int len = strlen(DRV_NAME);
-
- for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir;
- bond_proc_dir = bond_proc_dir->next) {
- if ((bond_proc_dir->namelen == len) &&
- !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
- break;
- }
+ rtnl_unlock();
+ rcu_read_lock();
}
- if (!bond_proc_dir) {
- bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
- if (bond_proc_dir) {
- bond_proc_dir->owner = THIS_MODULE;
- } else {
- printk(KERN_WARNING DRV_NAME
- ": Warning: cannot create /proc/net/%s\n",
- DRV_NAME);
- }
- }
-}
+ should_notify_rtnl = bond_ab_arp_probe(bond);
+ rcu_read_unlock();
-/* Destroy the bonding directory under /proc/net, if empty.
- * Caller must hold rtnl_lock.
- */
-static void bond_destroy_proc_dir(void)
-{
- struct proc_dir_entry *de;
+re_arm:
+ if (bond->params.arp_interval)
+ queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
- if (!bond_proc_dir) {
- return;
- }
+ if (should_notify_peers || should_notify_rtnl) {
+ if (!rtnl_trylock())
+ return;
- /* verify that the /proc dir is empty */
- for (de = bond_proc_dir->subdir; de; de = de->next) {
- /* ignore . and .. */
- if (*(de->name) != '.') {
- break;
- }
- }
+ if (should_notify_peers)
+ call_netdevice_notifiers(NETDEV_NOTIFY_PEERS,
+ bond->dev);
+ if (should_notify_rtnl)
+ bond_slave_state_notify(bond);
- if (de) {
- if (bond_proc_dir->owner == THIS_MODULE) {
- bond_proc_dir->owner = NULL;
- }
- } else {
- remove_proc_entry(DRV_NAME, init_net.proc_net);
- bond_proc_dir = NULL;
+ rtnl_unlock();
}
}
-#endif /* CONFIG_PROC_FS */
/*-------------------------- netdev event handling --------------------------*/
@@ -3470,26 +2827,31 @@ static void bond_destroy_proc_dir(void)
*/
static int bond_event_changename(struct bonding *bond)
{
-#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
bond_create_proc_entry(bond);
-#endif
- down_write(&(bonding_rwsem));
- bond_destroy_sysfs_entry(bond);
- bond_create_sysfs_entry(bond);
- up_write(&(bonding_rwsem));
+
+ bond_debug_reregister(bond);
+
return NOTIFY_DONE;
}
-static int bond_master_netdev_event(unsigned long event, struct net_device *bond_dev)
+static int bond_master_netdev_event(unsigned long event,
+ struct net_device *bond_dev)
{
- struct bonding *event_bond = bond_dev->priv;
+ struct bonding *event_bond = netdev_priv(bond_dev);
switch (event) {
case NETDEV_CHANGENAME:
return bond_event_changename(event_bond);
case NETDEV_UNREGISTER:
- bond_release_all(event_bond->dev);
+ bond_remove_proc_entry(event_bond);
+ break;
+ case NETDEV_REGISTER:
+ bond_create_proc_entry(event_bond);
+ break;
+ case NETDEV_NOTIFY_PEERS:
+ if (event_bond->send_peer_notif)
+ event_bond->send_peer_notif--;
break;
default:
break;
@@ -3498,26 +2860,44 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
return NOTIFY_DONE;
}
-static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
+static int bond_slave_netdev_event(unsigned long event,
+ struct net_device *slave_dev)
{
- struct net_device *bond_dev = slave_dev->master;
- struct bonding *bond = bond_dev->priv;
+ struct slave *slave = bond_slave_get_rtnl(slave_dev);
+ struct bonding *bond;
+ struct net_device *bond_dev;
+ u32 old_speed;
+ u8 old_duplex;
+
+ /* A netdev event can be generated while enslaving a device
+ * before netdev_rx_handler_register is called in which case
+ * slave will be NULL
+ */
+ if (!slave)
+ return NOTIFY_DONE;
+ bond_dev = slave->bond->dev;
+ bond = slave->bond;
switch (event) {
case NETDEV_UNREGISTER:
- if (bond_dev) {
- if (bond->setup_by_slave)
- bond_release_and_destroy(bond_dev, slave_dev);
- else
- bond_release(bond_dev, slave_dev);
- }
+ if (bond_dev->type != ARPHRD_ETHER)
+ bond_release_and_destroy(bond_dev, slave_dev);
+ else
+ bond_release(bond_dev, slave_dev);
break;
+ case NETDEV_UP:
case NETDEV_CHANGE:
- /*
- * TODO: is this what we get if somebody
- * sets up a hierarchical bond, then rmmod's
- * one of the slave bonding devices?
- */
+ old_speed = slave->speed;
+ old_duplex = slave->duplex;
+
+ bond_update_speed_duplex(slave);
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+ if (old_speed != slave->speed)
+ bond_3ad_adapter_speed_changed(slave);
+ if (old_duplex != slave->duplex)
+ bond_3ad_adapter_duplex_changed(slave);
+ }
break;
case NETDEV_DOWN:
/*
@@ -3539,13 +2919,38 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
*/
break;
case NETDEV_CHANGENAME:
- /*
- * TODO: handle changing the primary's name
- */
+ /* we don't care if we don't have primary set */
+ if (!bond_uses_primary(bond) ||
+ !bond->params.primary[0])
+ break;
+
+ if (slave == bond->primary_slave) {
+ /* slave's name changed - he's no longer primary */
+ bond->primary_slave = NULL;
+ } else if (!strcmp(slave_dev->name, bond->params.primary)) {
+ /* we have a new primary slave */
+ bond->primary_slave = slave;
+ } else { /* we didn't change primary - exit */
+ break;
+ }
+
+ pr_info("%s: Primary slave changed to %s, reselecting active slave\n",
+ bond->dev->name,
+ bond->primary_slave ? slave_dev->name : "none");
+
+ block_netpoll_tx();
+ write_lock_bh(&bond->curr_slave_lock);
+ bond_select_active_slave(bond);
+ write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
break;
case NETDEV_FEAT_CHANGE:
bond_compute_features(bond);
break;
+ case NETDEV_RESEND_IGMP:
+ /* Propagate to master device */
+ call_netdevice_notifiers(event, slave->bond->dev);
+ break;
default:
break;
}
@@ -3561,238 +2966,188 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
* locks for us to safely manipulate the slave devices (RTNL lock,
* dev_probe_lock).
*/
-static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+static int bond_netdev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
{
- struct net_device *event_dev = (struct net_device *)ptr;
+ struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
- if (dev_net(event_dev) != &init_net)
- return NOTIFY_DONE;
-
- dprintk("event_dev: %s, event: %lx\n",
- (event_dev ? event_dev->name : "None"),
- event);
+ pr_debug("event_dev: %s, event: %lx\n",
+ event_dev ? event_dev->name : "None", event);
if (!(event_dev->priv_flags & IFF_BONDING))
return NOTIFY_DONE;
if (event_dev->flags & IFF_MASTER) {
- dprintk("IFF_MASTER\n");
+ pr_debug("IFF_MASTER\n");
return bond_master_netdev_event(event, event_dev);
}
if (event_dev->flags & IFF_SLAVE) {
- dprintk("IFF_SLAVE\n");
+ pr_debug("IFF_SLAVE\n");
return bond_slave_netdev_event(event, event_dev);
}
return NOTIFY_DONE;
}
-/*
- * bond_inetaddr_event: handle inetaddr notifier chain events.
- *
- * We keep track of device IPs primarily to use as source addresses in
- * ARP monitor probes (rather than spewing out broadcasts all the time).
- *
- * We track one IP for the main device (if it has one), plus one per VLAN.
- */
-static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
- struct in_ifaddr *ifa = ptr;
- struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev;
- struct bonding *bond;
- struct vlan_entry *vlan;
-
- if (dev_net(ifa->ifa_dev->dev) != &init_net)
- return NOTIFY_DONE;
-
- list_for_each_entry(bond, &bond_dev_list, bond_list) {
- if (bond->dev == event_dev) {
- switch (event) {
- case NETDEV_UP:
- bond->master_ip = ifa->ifa_local;
- return NOTIFY_OK;
- case NETDEV_DOWN:
- bond->master_ip = bond_glean_dev_ip(bond->dev);
- return NOTIFY_OK;
- default:
- return NOTIFY_DONE;
- }
- }
-
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
- if (vlan_dev == event_dev) {
- switch (event) {
- case NETDEV_UP:
- vlan->vlan_ip = ifa->ifa_local;
- return NOTIFY_OK;
- case NETDEV_DOWN:
- vlan->vlan_ip =
- bond_glean_dev_ip(vlan_dev);
- return NOTIFY_OK;
- default:
- return NOTIFY_DONE;
- }
- }
- }
- }
- return NOTIFY_DONE;
-}
-
static struct notifier_block bond_netdev_notifier = {
.notifier_call = bond_netdev_event,
};
-static struct notifier_block bond_inetaddr_notifier = {
- .notifier_call = bond_inetaddr_event,
-};
-
-/*-------------------------- Packet type handling ---------------------------*/
-
-/* register to receive lacpdus on a bond */
-static void bond_register_lacpdu(struct bonding *bond)
-{
- struct packet_type *pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
-
- /* initialize packet type */
- pk_type->type = PKT_TYPE_LACPDU;
- pk_type->dev = bond->dev;
- pk_type->func = bond_3ad_lacpdu_recv;
-
- dev_add_pack(pk_type);
-}
-
-/* unregister to receive lacpdus on a bond */
-static void bond_unregister_lacpdu(struct bonding *bond)
-{
- dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
-}
+/*---------------------------- Hashing Policies -----------------------------*/
-void bond_register_arp(struct bonding *bond)
+/* L2 hash helper */
+static inline u32 bond_eth_hash(struct sk_buff *skb)
{
- struct packet_type *pt = &bond->arp_mon_pt;
+ struct ethhdr *data = (struct ethhdr *)skb->data;
- if (pt->type)
- return;
+ if (skb_headlen(skb) >= offsetof(struct ethhdr, h_proto))
+ return data->h_dest[5] ^ data->h_source[5];
- pt->type = htons(ETH_P_ARP);
- pt->dev = bond->dev;
- pt->func = bond_arp_rcv;
- dev_add_pack(pt);
+ return 0;
}
-void bond_unregister_arp(struct bonding *bond)
+/* Extract the appropriate headers based on bond's xmit policy */
+static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb,
+ struct flow_keys *fk)
{
- struct packet_type *pt = &bond->arp_mon_pt;
+ const struct ipv6hdr *iph6;
+ const struct iphdr *iph;
+ int noff, proto = -1;
+
+ if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23)
+ return skb_flow_dissect(skb, fk);
+
+ fk->ports = 0;
+ noff = skb_network_offset(skb);
+ if (skb->protocol == htons(ETH_P_IP)) {
+ if (unlikely(!pskb_may_pull(skb, noff + sizeof(*iph))))
+ return false;
+ iph = ip_hdr(skb);
+ fk->src = iph->saddr;
+ fk->dst = iph->daddr;
+ noff += iph->ihl << 2;
+ if (!ip_is_fragment(iph))
+ proto = iph->protocol;
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ if (unlikely(!pskb_may_pull(skb, noff + sizeof(*iph6))))
+ return false;
+ iph6 = ipv6_hdr(skb);
+ fk->src = (__force __be32)ipv6_addr_hash(&iph6->saddr);
+ fk->dst = (__force __be32)ipv6_addr_hash(&iph6->daddr);
+ noff += sizeof(*iph6);
+ proto = iph6->nexthdr;
+ } else {
+ return false;
+ }
+ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34 && proto >= 0)
+ fk->ports = skb_flow_get_ports(skb, noff, proto);
- dev_remove_pack(pt);
- pt->type = 0;
+ return true;
}
-/*---------------------------- Hashing Policies -----------------------------*/
-
-/*
- * Hash for the output device based upon layer 2 and layer 3 data. If
- * the packet is not IP mimic bond_xmit_hash_policy_l2()
+/**
+ * bond_xmit_hash - generate a hash value based on the xmit policy
+ * @bond: bonding device
+ * @skb: buffer to use for headers
+ *
+ * This function will extract the necessary headers from the skb buffer and use
+ * them to generate a hash based on the xmit_policy set in the bonding device
*/
-static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
- struct net_device *bond_dev, int count)
+u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb)
{
- struct ethhdr *data = (struct ethhdr *)skb->data;
- struct iphdr *iph = ip_hdr(skb);
+ struct flow_keys flow;
+ u32 hash;
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
- return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
- (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count;
- }
+ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 ||
+ !bond_flow_dissect(bond, skb, &flow))
+ return bond_eth_hash(skb);
- return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
-}
+ if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23 ||
+ bond->params.xmit_policy == BOND_XMIT_POLICY_ENCAP23)
+ hash = bond_eth_hash(skb);
+ else
+ hash = (__force u32)flow.ports;
+ hash ^= (__force u32)flow.dst ^ (__force u32)flow.src;
+ hash ^= (hash >> 16);
+ hash ^= (hash >> 8);
-/*
- * Hash for the output device based upon layer 3 and layer 4 data. If
- * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
- * altogether not IP, mimic bond_xmit_hash_policy_l2()
- */
-static int bond_xmit_hash_policy_l34(struct sk_buff *skb,
- struct net_device *bond_dev, int count)
-{
- struct ethhdr *data = (struct ethhdr *)skb->data;
- struct iphdr *iph = ip_hdr(skb);
- __be16 *layer4hdr = (__be16 *)((u32 *)iph + iph->ihl);
- int layer4_xor = 0;
-
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
- if (!(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) &&
- (iph->protocol == IPPROTO_TCP ||
- iph->protocol == IPPROTO_UDP)) {
- layer4_xor = ntohs((*layer4hdr ^ *(layer4hdr + 1)));
- }
- return (layer4_xor ^
- ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
+ return hash;
+}
- }
+/*-------------------------- Device entry points ----------------------------*/
- return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+static void bond_work_init_all(struct bonding *bond)
+{
+ INIT_DELAYED_WORK(&bond->mcast_work,
+ bond_resend_igmp_join_requests_delayed);
+ INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
+ INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP)
+ INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon);
+ else
+ INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon);
+ INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
}
-/*
- * Hash for the output device based upon layer 2 data
- */
-static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
- struct net_device *bond_dev, int count)
+static void bond_work_cancel_all(struct bonding *bond)
{
- struct ethhdr *data = (struct ethhdr *)skb->data;
-
- return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+ cancel_delayed_work_sync(&bond->mii_work);
+ cancel_delayed_work_sync(&bond->arp_work);
+ cancel_delayed_work_sync(&bond->alb_work);
+ cancel_delayed_work_sync(&bond->ad_work);
+ cancel_delayed_work_sync(&bond->mcast_work);
}
-/*-------------------------- Device entry points ----------------------------*/
-
static int bond_open(struct net_device *bond_dev)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct list_head *iter;
+ struct slave *slave;
- bond->kill_timers = 0;
+ /* reset slave->backup and slave->inactive */
+ read_lock(&bond->lock);
+ if (bond_has_slaves(bond)) {
+ read_lock(&bond->curr_slave_lock);
+ bond_for_each_slave(bond, slave, iter) {
+ if (bond_uses_primary(bond)
+ && (slave != bond->curr_active_slave)) {
+ bond_set_slave_inactive_flags(slave,
+ BOND_SLAVE_NOTIFY_NOW);
+ } else {
+ bond_set_slave_active_flags(slave,
+ BOND_SLAVE_NOTIFY_NOW);
+ }
+ }
+ read_unlock(&bond->curr_slave_lock);
+ }
+ read_unlock(&bond->lock);
+
+ bond_work_init_all(bond);
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
+ if (bond_is_lb(bond)) {
/* bond_alb_initialize must be called before the timer
* is started.
*/
- if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) {
- /* something went wrong - fail the open operation */
- return -1;
- }
-
- INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
- queue_delayed_work(bond->wq, &bond->alb_work, 0);
+ if (bond_alb_initialize(bond, (BOND_MODE(bond) == BOND_MODE_ALB)))
+ return -ENOMEM;
+ if (bond->params.tlb_dynamic_lb)
+ queue_delayed_work(bond->wq, &bond->alb_work, 0);
}
- if (bond->params.miimon) { /* link check interval, in milliseconds. */
- INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+ if (bond->params.miimon) /* link check interval, in milliseconds. */
queue_delayed_work(bond->wq, &bond->mii_work, 0);
- }
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
- else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
queue_delayed_work(bond->wq, &bond->arp_work, 0);
- if (bond->params.arp_validate)
- bond_register_arp(bond);
+ bond->recv_probe = bond_arp_rcv;
}
- if (bond->params.mode == BOND_MODE_8023AD) {
- INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
queue_delayed_work(bond->wq, &bond->ad_work, 0);
/* register to receive LACPDUs */
- bond_register_lacpdu(bond);
+ bond->recv_probe = bond_3ad_lacpdu_recv;
+ bond_3ad_initiate_agg_selection(bond, 1);
}
return 0;
@@ -3800,100 +3155,58 @@ static int bond_open(struct net_device *bond_dev)
static int bond_close(struct net_device *bond_dev)
{
- struct bonding *bond = bond_dev->priv;
-
- if (bond->params.mode == BOND_MODE_8023AD) {
- /* Unregister the receive of LACPDUs */
- bond_unregister_lacpdu(bond);
- }
-
- if (bond->params.arp_validate)
- bond_unregister_arp(bond);
-
- write_lock_bh(&bond->lock);
-
- bond->send_grat_arp = 0;
-
- /* signal timers not to re-arm */
- bond->kill_timers = 1;
+ struct bonding *bond = netdev_priv(bond_dev);
- write_unlock_bh(&bond->lock);
-
- if (bond->params.miimon) { /* link check interval, in milliseconds. */
- cancel_delayed_work(&bond->mii_work);
- }
-
- if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
- cancel_delayed_work(&bond->arp_work);
- }
-
- switch (bond->params.mode) {
- case BOND_MODE_8023AD:
- cancel_delayed_work(&bond->ad_work);
- break;
- case BOND_MODE_TLB:
- case BOND_MODE_ALB:
- cancel_delayed_work(&bond->alb_work);
- break;
- default:
- break;
- }
-
-
- if ((bond->params.mode == BOND_MODE_TLB) ||
- (bond->params.mode == BOND_MODE_ALB)) {
- /* Must be called only after all
- * slaves have been released
- */
+ bond_work_cancel_all(bond);
+ bond->send_peer_notif = 0;
+ if (bond_is_lb(bond))
bond_alb_deinitialize(bond);
- }
+ bond->recv_probe = NULL;
return 0;
}
-static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
+static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
+ struct rtnl_link_stats64 *stats)
{
- struct bonding *bond = bond_dev->priv;
- struct net_device_stats *stats = &(bond->stats), *sstats;
- struct net_device_stats local_stats;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct rtnl_link_stats64 temp;
+ struct list_head *iter;
struct slave *slave;
- int i;
- memset(&local_stats, 0, sizeof(struct net_device_stats));
+ memset(stats, 0, sizeof(*stats));
read_lock_bh(&bond->lock);
-
- bond_for_each_slave(bond, slave, i) {
- sstats = slave->dev->get_stats(slave->dev);
- local_stats.rx_packets += sstats->rx_packets;
- local_stats.rx_bytes += sstats->rx_bytes;
- local_stats.rx_errors += sstats->rx_errors;
- local_stats.rx_dropped += sstats->rx_dropped;
-
- local_stats.tx_packets += sstats->tx_packets;
- local_stats.tx_bytes += sstats->tx_bytes;
- local_stats.tx_errors += sstats->tx_errors;
- local_stats.tx_dropped += sstats->tx_dropped;
-
- local_stats.multicast += sstats->multicast;
- local_stats.collisions += sstats->collisions;
-
- local_stats.rx_length_errors += sstats->rx_length_errors;
- local_stats.rx_over_errors += sstats->rx_over_errors;
- local_stats.rx_crc_errors += sstats->rx_crc_errors;
- local_stats.rx_frame_errors += sstats->rx_frame_errors;
- local_stats.rx_fifo_errors += sstats->rx_fifo_errors;
- local_stats.rx_missed_errors += sstats->rx_missed_errors;
-
- local_stats.tx_aborted_errors += sstats->tx_aborted_errors;
- local_stats.tx_carrier_errors += sstats->tx_carrier_errors;
- local_stats.tx_fifo_errors += sstats->tx_fifo_errors;
- local_stats.tx_heartbeat_errors += sstats->tx_heartbeat_errors;
- local_stats.tx_window_errors += sstats->tx_window_errors;
+ bond_for_each_slave(bond, slave, iter) {
+ const struct rtnl_link_stats64 *sstats =
+ dev_get_stats(slave->dev, &temp);
+
+ stats->rx_packets += sstats->rx_packets;
+ stats->rx_bytes += sstats->rx_bytes;
+ stats->rx_errors += sstats->rx_errors;
+ stats->rx_dropped += sstats->rx_dropped;
+
+ stats->tx_packets += sstats->tx_packets;
+ stats->tx_bytes += sstats->tx_bytes;
+ stats->tx_errors += sstats->tx_errors;
+ stats->tx_dropped += sstats->tx_dropped;
+
+ stats->multicast += sstats->multicast;
+ stats->collisions += sstats->collisions;
+
+ stats->rx_length_errors += sstats->rx_length_errors;
+ stats->rx_over_errors += sstats->rx_over_errors;
+ stats->rx_crc_errors += sstats->rx_crc_errors;
+ stats->rx_frame_errors += sstats->rx_frame_errors;
+ stats->rx_fifo_errors += sstats->rx_fifo_errors;
+ stats->rx_missed_errors += sstats->rx_missed_errors;
+
+ stats->tx_aborted_errors += sstats->tx_aborted_errors;
+ stats->tx_carrier_errors += sstats->tx_carrier_errors;
+ stats->tx_fifo_errors += sstats->tx_fifo_errors;
+ stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
+ stats->tx_window_errors += sstats->tx_window_errors;
}
-
- memcpy(stats, &local_stats, sizeof(struct net_device_stats));
-
read_unlock_bh(&bond->lock);
return stats;
@@ -3901,23 +3214,25 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
{
+ struct bonding *bond = netdev_priv(bond_dev);
struct net_device *slave_dev = NULL;
struct ifbond k_binfo;
struct ifbond __user *u_binfo = NULL;
struct ifslave k_sinfo;
struct ifslave __user *u_sinfo = NULL;
struct mii_ioctl_data *mii = NULL;
+ struct bond_opt_value newval;
+ struct net *net;
int res = 0;
- dprintk("bond_ioctl: master=%s, cmd=%d\n",
- bond_dev->name, cmd);
+ pr_debug("bond_ioctl: master=%s, cmd=%d\n", bond_dev->name, cmd);
switch (cmd) {
case SIOCGMIIPHY:
mii = if_mii(ifr);
- if (!mii) {
+ if (!mii)
return -EINVAL;
- }
+
mii->phy_id = 0;
/* Fall Through */
case SIOCGMIIREG:
@@ -3926,18 +3241,17 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
* instead of SIOCGMIIPHY.
*/
mii = if_mii(ifr);
- if (!mii) {
+ if (!mii)
return -EINVAL;
- }
+
if (mii->reg_num == 1) {
- struct bonding *bond = bond_dev->priv;
mii->val_out = 0;
read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (netif_carrier_ok(bond->dev)) {
+ if (netif_carrier_ok(bond->dev))
mii->val_out = BMSR_LSTATUS;
- }
+
read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock);
}
@@ -3947,32 +3261,26 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
case SIOCBONDINFOQUERY:
u_binfo = (struct ifbond __user *)ifr->ifr_data;
- if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
+ if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond)))
return -EFAULT;
- }
res = bond_info_query(bond_dev, &k_binfo);
- if (res == 0) {
- if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {
- return -EFAULT;
- }
- }
+ if (res == 0 &&
+ copy_to_user(u_binfo, &k_binfo, sizeof(ifbond)))
+ return -EFAULT;
return res;
case BOND_SLAVE_INFO_QUERY_OLD:
case SIOCBONDSLAVEINFOQUERY:
u_sinfo = (struct ifslave __user *)ifr->ifr_data;
- if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
+ if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave)))
return -EFAULT;
- }
res = bond_slave_info_query(bond_dev, &k_sinfo);
- if (res == 0) {
- if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {
- return -EFAULT;
- }
- }
+ if (res == 0 &&
+ copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave)))
+ return -EFAULT;
return res;
default:
@@ -3980,103 +3288,133 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
break;
}
- if (!capable(CAP_NET_ADMIN)) {
+ net = dev_net(bond_dev);
+
+ if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
- }
- down_write(&(bonding_rwsem));
- slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave);
+ slave_dev = __dev_get_by_name(net, ifr->ifr_slave);
- dprintk("slave_dev=%p: \n", slave_dev);
+ pr_debug("slave_dev=%p:\n", slave_dev);
- if (!slave_dev) {
- res = -ENODEV;
- } else {
- dprintk("slave_dev->name=%s: \n", slave_dev->name);
- switch (cmd) {
- case BOND_ENSLAVE_OLD:
- case SIOCBONDENSLAVE:
- res = bond_enslave(bond_dev, slave_dev);
- break;
- case BOND_RELEASE_OLD:
- case SIOCBONDRELEASE:
- res = bond_release(bond_dev, slave_dev);
- break;
- case BOND_SETHWADDR_OLD:
- case SIOCBONDSETHWADDR:
- res = bond_sethwaddr(bond_dev, slave_dev);
- break;
- case BOND_CHANGE_ACTIVE_OLD:
- case SIOCBONDCHANGEACTIVE:
- res = bond_ioctl_change_active(bond_dev, slave_dev);
- break;
- default:
- res = -EOPNOTSUPP;
- }
+ if (!slave_dev)
+ return -ENODEV;
- dev_put(slave_dev);
+ pr_debug("slave_dev->name=%s:\n", slave_dev->name);
+ switch (cmd) {
+ case BOND_ENSLAVE_OLD:
+ case SIOCBONDENSLAVE:
+ res = bond_enslave(bond_dev, slave_dev);
+ break;
+ case BOND_RELEASE_OLD:
+ case SIOCBONDRELEASE:
+ res = bond_release(bond_dev, slave_dev);
+ break;
+ case BOND_SETHWADDR_OLD:
+ case SIOCBONDSETHWADDR:
+ bond_set_dev_addr(bond_dev, slave_dev);
+ res = 0;
+ break;
+ case BOND_CHANGE_ACTIVE_OLD:
+ case SIOCBONDCHANGEACTIVE:
+ bond_opt_initstr(&newval, slave_dev->name);
+ res = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval);
+ break;
+ default:
+ res = -EOPNOTSUPP;
}
- up_write(&(bonding_rwsem));
return res;
}
-static void bond_set_multicast_list(struct net_device *bond_dev)
+static void bond_change_rx_flags(struct net_device *bond_dev, int change)
{
- struct bonding *bond = bond_dev->priv;
- struct dev_mc_list *dmi;
+ struct bonding *bond = netdev_priv(bond_dev);
- /*
- * Do promisc before checking multicast_mode
- */
- if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
- /*
- * FIXME: Need to handle the error when one of the multi-slaves
- * encounters error.
- */
- bond_set_promiscuity(bond, 1);
- }
+ if (change & IFF_PROMISC)
+ bond_set_promiscuity(bond,
+ bond_dev->flags & IFF_PROMISC ? 1 : -1);
- if (!(bond_dev->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC)) {
- bond_set_promiscuity(bond, -1);
- }
+ if (change & IFF_ALLMULTI)
+ bond_set_allmulti(bond,
+ bond_dev->flags & IFF_ALLMULTI ? 1 : -1);
+}
+
+static void bond_set_rx_mode(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct list_head *iter;
+ struct slave *slave;
- /* set allmulti flag to slaves */
- if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) {
- /*
- * FIXME: Need to handle the error when one of the multi-slaves
- * encounters error.
- */
- bond_set_allmulti(bond, 1);
- }
- if (!(bond_dev->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI)) {
- bond_set_allmulti(bond, -1);
+ rcu_read_lock();
+ if (bond_uses_primary(bond)) {
+ slave = rcu_dereference(bond->curr_active_slave);
+ if (slave) {
+ dev_uc_sync(slave->dev, bond_dev);
+ dev_mc_sync(slave->dev, bond_dev);
+ }
+ } else {
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ dev_uc_sync_multiple(slave->dev, bond_dev);
+ dev_mc_sync_multiple(slave->dev, bond_dev);
+ }
}
+ rcu_read_unlock();
+}
- read_lock(&bond->lock);
+static int bond_neigh_init(struct neighbour *n)
+{
+ struct bonding *bond = netdev_priv(n->dev);
+ const struct net_device_ops *slave_ops;
+ struct neigh_parms parms;
+ struct slave *slave;
+ int ret;
- bond->flags = bond_dev->flags;
+ slave = bond_first_slave(bond);
+ if (!slave)
+ return 0;
+ slave_ops = slave->dev->netdev_ops;
+ if (!slave_ops->ndo_neigh_setup)
+ return 0;
- /* looking for addresses to add to slaves' mc list */
- for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
- if (!bond_mc_list_find_dmi(dmi, bond->mc_list)) {
- bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen);
- }
- }
+ parms.neigh_setup = NULL;
+ parms.neigh_cleanup = NULL;
+ ret = slave_ops->ndo_neigh_setup(slave->dev, &parms);
+ if (ret)
+ return ret;
- /* looking for addresses to delete from slaves' list */
- for (dmi = bond->mc_list; dmi; dmi = dmi->next) {
- if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list)) {
- bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen);
- }
- }
+ /*
+ * Assign slave's neigh_cleanup to neighbour in case cleanup is called
+ * after the last slave has been detached. Assumes that all slaves
+ * utilize the same neigh_cleanup (true at this writing as only user
+ * is ipoib).
+ */
+ n->parms->neigh_cleanup = parms.neigh_cleanup;
+
+ if (!parms.neigh_setup)
+ return 0;
- /* save master's multicast list */
- bond_mc_list_destroy(bond);
- bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC);
+ return parms.neigh_setup(n);
+}
- read_unlock(&bond->lock);
+/*
+ * The bonding ndo_neigh_setup is called at init time beofre any
+ * slave exists. So we must declare proxy setup function which will
+ * be used at run time to resolve the actual slave neigh param setup.
+ *
+ * It's also called by master devices (such as vlans) to setup their
+ * underlying devices. In that case - do nothing, we're already set up from
+ * our init.
+ */
+static int bond_neigh_setup(struct net_device *dev,
+ struct neigh_parms *parms)
+{
+ /* modify only our neigh_parms */
+ if (parms->dev == dev)
+ parms->neigh_setup = bond_neigh_init;
+
+ return 0;
}
/*
@@ -4084,13 +3422,13 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
*/
static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
{
- struct bonding *bond = bond_dev->priv;
- struct slave *slave, *stop_at;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave, *rollback_slave;
+ struct list_head *iter;
int res = 0;
- int i;
- dprintk("bond=%p, name=%s, new_mtu=%d\n", bond,
- (bond_dev ? bond_dev->name : "None"), new_mtu);
+ pr_debug("bond=%p, name=%s, new_mtu=%d\n",
+ bond, bond_dev ? bond_dev->name : "None", new_mtu);
/* Can't hold bond->lock with bh disabled here since
* some base drivers panic. On the other hand we can't
@@ -4107,9 +3445,9 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
* call to the base driver.
*/
- bond_for_each_slave(bond, slave, i) {
- dprintk("s %p s->p %p c_m %p\n", slave,
- slave->prev, slave->dev->change_mtu);
+ bond_for_each_slave(bond, slave, iter) {
+ pr_debug("s %p c_m %p\n",
+ slave, slave->dev->netdev_ops->ndo_change_mtu);
res = dev_set_mtu(slave->dev, new_mtu);
@@ -4122,7 +3460,7 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
* means changing their mtu from timer context, which
* is probably not a good idea.
*/
- dprintk("err %d %s\n", res, slave->dev->name);
+ pr_debug("err %d %s\n", res, slave->dev->name);
goto unwind;
}
}
@@ -4133,14 +3471,16 @@ static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
unwind:
/* unwind from head to the slave that failed */
- stop_at = slave;
- bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
+ bond_for_each_slave(bond, rollback_slave, iter) {
int tmp_res;
- tmp_res = dev_set_mtu(slave->dev, bond_dev->mtu);
+ if (rollback_slave == slave)
+ break;
+
+ tmp_res = dev_set_mtu(rollback_slave->dev, bond_dev->mtu);
if (tmp_res) {
- dprintk("unwind err %d dev %s\n", tmp_res,
- slave->dev->name);
+ pr_debug("unwind err %d dev %s\n",
+ tmp_res, rollback_slave->dev->name);
}
}
@@ -4156,24 +3496,28 @@ unwind:
*/
static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave, *rollback_slave;
struct sockaddr *sa = addr, tmp_sa;
- struct slave *slave, *stop_at;
+ struct list_head *iter;
int res = 0;
- int i;
- dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
+ if (BOND_MODE(bond) == BOND_MODE_ALB)
+ return bond_alb_set_mac_address(bond_dev, addr);
- /*
- * If fail_over_mac is set to active, do nothing and return
- * success. Returning an error causes ifenslave to fail.
+
+ pr_debug("bond=%p, name=%s\n",
+ bond, bond_dev ? bond_dev->name : "None");
+
+ /* If fail_over_mac is enabled, do nothing and return success.
+ * Returning an error causes ifenslave to fail.
*/
- if (bond->params.fail_over_mac == BOND_FOM_ACTIVE)
+ if (bond->params.fail_over_mac &&
+ BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP)
return 0;
- if (!is_valid_ether_addr(sa->sa_data)) {
+ if (!is_valid_ether_addr(sa->sa_data))
return -EADDRNOTAVAIL;
- }
/* Can't hold bond->lock with bh disabled here since
* some base drivers panic. On the other hand we can't
@@ -4190,15 +3534,8 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
* call to the base driver.
*/
- bond_for_each_slave(bond, slave, i) {
- dprintk("slave %p %s\n", slave, slave->dev->name);
-
- if (slave->dev->set_mac_address == NULL) {
- res = -EOPNOTSUPP;
- dprintk("EOPNOTSUPP %s\n", slave->dev->name);
- goto unwind;
- }
-
+ bond_for_each_slave(bond, slave, iter) {
+ pr_debug("slave %p %s\n", slave, slave->dev->name);
res = dev_set_mac_address(slave->dev, addr);
if (res) {
/* TODO: consider downing the slave
@@ -4207,7 +3544,7 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
* breakage anyway until ARP finish
* updating, so...
*/
- dprintk("err %d %s\n", res, slave->dev->name);
+ pr_debug("err %d %s\n", res, slave->dev->name);
goto unwind;
}
}
@@ -4221,64 +3558,121 @@ unwind:
tmp_sa.sa_family = bond_dev->type;
/* unwind from head to the slave that failed */
- stop_at = slave;
- bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
+ bond_for_each_slave(bond, rollback_slave, iter) {
int tmp_res;
- tmp_res = dev_set_mac_address(slave->dev, &tmp_sa);
+ if (rollback_slave == slave)
+ break;
+
+ tmp_res = dev_set_mac_address(rollback_slave->dev, &tmp_sa);
if (tmp_res) {
- dprintk("unwind err %d dev %s\n", tmp_res,
- slave->dev->name);
+ pr_debug("unwind err %d dev %s\n",
+ tmp_res, rollback_slave->dev->name);
}
}
return res;
}
-static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
+/**
+ * bond_xmit_slave_id - transmit skb through slave with slave_id
+ * @bond: bonding device that is transmitting
+ * @skb: buffer to transmit
+ * @slave_id: slave id up to slave_cnt-1 through which to transmit
+ *
+ * This function tries to transmit through slave with slave_id but in case
+ * it fails, it tries to find the first available slave for transmission.
+ * The skb is consumed in all cases, thus the function is void.
+ */
+static void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id)
{
- struct bonding *bond = bond_dev->priv;
- struct slave *slave, *start_at;
- int i, slave_no, res = 1;
-
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
-
- /*
- * Concurrent TX may collide on rr_tx_counter; we accept that
- * as being rare enough not to justify using an atomic op here
- */
- slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
-
- bond_for_each_slave(bond, slave, i) {
- slave_no--;
- if (slave_no < 0) {
- break;
+ struct list_head *iter;
+ struct slave *slave;
+ int i = slave_id;
+
+ /* Here we start from the slave with slave_id */
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (--i < 0) {
+ if (bond_slave_can_tx(slave)) {
+ bond_dev_queue_xmit(bond, skb, slave->dev);
+ return;
+ }
}
}
- start_at = slave;
- bond_for_each_slave_from(bond, slave, i, start_at) {
- if (IS_UP(slave->dev) &&
- (slave->link == BOND_LINK_UP) &&
- (slave->state == BOND_STATE_ACTIVE)) {
- res = bond_dev_queue_xmit(bond, skb, slave->dev);
+ /* Here we start from the first slave up to slave_id */
+ i = slave_id;
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (--i < 0)
break;
+ if (bond_slave_can_tx(slave)) {
+ bond_dev_queue_xmit(bond, skb, slave->dev);
+ return;
}
}
+ /* no slave that can tx has been found */
+ dev_kfree_skb_any(skb);
+}
-out:
- if (res) {
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
+/**
+ * bond_rr_gen_slave_id - generate slave id based on packets_per_slave
+ * @bond: bonding device to use
+ *
+ * Based on the value of the bonding device's packets_per_slave parameter
+ * this function generates a slave id, which is usually used as the next
+ * slave to transmit through.
+ */
+static u32 bond_rr_gen_slave_id(struct bonding *bond)
+{
+ u32 slave_id;
+ struct reciprocal_value reciprocal_packets_per_slave;
+ int packets_per_slave = bond->params.packets_per_slave;
+
+ switch (packets_per_slave) {
+ case 0:
+ slave_id = prandom_u32();
+ break;
+ case 1:
+ slave_id = bond->rr_tx_counter;
+ break;
+ default:
+ reciprocal_packets_per_slave =
+ bond->params.reciprocal_packets_per_slave;
+ slave_id = reciprocal_divide(bond->rr_tx_counter,
+ reciprocal_packets_per_slave);
+ break;
}
- read_unlock(&bond->lock);
- return 0;
+ bond->rr_tx_counter++;
+
+ return slave_id;
}
+static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct iphdr *iph = ip_hdr(skb);
+ struct slave *slave;
+ u32 slave_id;
+
+ /* Start with the curr_active_slave that joined the bond as the
+ * default for sending IGMP traffic. For failover purposes one
+ * needs to maintain some consistency for the interface that will
+ * send the join/membership reports. The curr_active_slave found
+ * will send all of this type of traffic.
+ */
+ if (iph->protocol == IPPROTO_IGMP && skb->protocol == htons(ETH_P_IP)) {
+ slave = rcu_dereference(bond->curr_active_slave);
+ if (slave && bond_slave_can_tx(slave))
+ bond_dev_queue_xmit(bond, skb, slave->dev);
+ else
+ bond_xmit_slave_id(bond, skb, 0);
+ } else {
+ slave_id = bond_rr_gen_slave_id(bond);
+ bond_xmit_slave_id(bond, skb, slave_id % bond->slave_cnt);
+ }
+
+ return NETDEV_TX_OK;
+}
/*
* in active-backup mode, we know that bond->curr_active_slave is always valid if
@@ -4286,264 +3680,281 @@ out:
*/
static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_dev)
{
- struct bonding *bond = bond_dev->priv;
- int res = 1;
-
- read_lock(&bond->lock);
- read_lock(&bond->curr_slave_lock);
-
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
-
- if (!bond->curr_active_slave)
- goto out;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave;
- res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+ slave = rcu_dereference(bond->curr_active_slave);
+ if (slave)
+ bond_dev_queue_xmit(bond, skb, slave->dev);
+ else
+ dev_kfree_skb_any(skb);
-out:
- if (res) {
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
- }
- read_unlock(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
- return 0;
+ return NETDEV_TX_OK;
}
-/*
- * In bond_xmit_xor() , we determine the output device by using a pre-
+/* In bond_xmit_xor() , we determine the output device by using a pre-
* determined xmit_hash_policy(), If the selected device is not enabled,
* find the next active slave.
*/
static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
{
- struct bonding *bond = bond_dev->priv;
- struct slave *slave, *start_at;
- int slave_no;
- int i;
- int res = 1;
+ struct bonding *bond = netdev_priv(bond_dev);
- read_lock(&bond->lock);
+ bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb) % bond->slave_cnt);
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
+ return NETDEV_TX_OK;
+}
- slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt);
+/* in broadcast mode, we send everything to all usable interfaces. */
+static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = NULL;
+ struct list_head *iter;
- bond_for_each_slave(bond, slave, i) {
- slave_no--;
- if (slave_no < 0) {
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (bond_is_last_slave(bond, slave))
break;
- }
- }
-
- start_at = slave;
+ if (bond_slave_is_up(slave) && slave->link == BOND_LINK_UP) {
+ struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
- bond_for_each_slave_from(bond, slave, i, start_at) {
- if (IS_UP(slave->dev) &&
- (slave->link == BOND_LINK_UP) &&
- (slave->state == BOND_STATE_ACTIVE)) {
- res = bond_dev_queue_xmit(bond, skb, slave->dev);
- break;
+ if (!skb2) {
+ net_err_ratelimited("%s: Error: %s: skb_clone() failed\n",
+ bond_dev->name, __func__);
+ continue;
+ }
+ /* bond_dev_queue_xmit always returns 0 */
+ bond_dev_queue_xmit(bond, skb2, slave->dev);
}
}
+ if (slave && bond_slave_is_up(slave) && slave->link == BOND_LINK_UP)
+ bond_dev_queue_xmit(bond, skb, slave->dev);
+ else
+ dev_kfree_skb_any(skb);
-out:
- if (res) {
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
- }
- read_unlock(&bond->lock);
- return 0;
+ return NETDEV_TX_OK;
}
+/*------------------------- Device initialization ---------------------------*/
+
/*
- * in broadcast mode, we send everything to all usable interfaces.
+ * Lookup the slave that corresponds to a qid
*/
-static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
+static inline int bond_slave_override(struct bonding *bond,
+ struct sk_buff *skb)
{
- struct bonding *bond = bond_dev->priv;
- struct slave *slave, *start_at;
- struct net_device *tx_dev = NULL;
- int i;
- int res = 1;
+ struct slave *slave = NULL;
+ struct list_head *iter;
- read_lock(&bond->lock);
-
- if (!BOND_IS_OK(bond)) {
- goto out;
- }
-
- read_lock(&bond->curr_slave_lock);
- start_at = bond->curr_active_slave;
- read_unlock(&bond->curr_slave_lock);
-
- if (!start_at) {
- goto out;
- }
-
- bond_for_each_slave_from(bond, slave, i, start_at) {
- if (IS_UP(slave->dev) &&
- (slave->link == BOND_LINK_UP) &&
- (slave->state == BOND_STATE_ACTIVE)) {
- if (tx_dev) {
- struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
- if (!skb2) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: bond_xmit_broadcast(): "
- "skb_clone() failed\n",
- bond_dev->name);
- continue;
- }
+ if (!skb->queue_mapping)
+ return 1;
- res = bond_dev_queue_xmit(bond, skb2, tx_dev);
- if (res) {
- dev_kfree_skb(skb2);
- continue;
- }
+ /* Find out if any slaves have the same mapping as this skb. */
+ bond_for_each_slave_rcu(bond, slave, iter) {
+ if (slave->queue_id == skb->queue_mapping) {
+ if (bond_slave_can_tx(slave)) {
+ bond_dev_queue_xmit(bond, skb, slave->dev);
+ return 0;
}
- tx_dev = slave->dev;
+ /* If the slave isn't UP, use default transmit policy. */
+ break;
}
}
- if (tx_dev) {
- res = bond_dev_queue_xmit(bond, skb, tx_dev);
- }
-
-out:
- if (res) {
- /* no suitable interface, frame not sent */
- dev_kfree_skb(skb);
- }
- /* frame sent to all suitable interfaces */
- read_unlock(&bond->lock);
- return 0;
+ return 1;
}
-/*------------------------- Device initialization ---------------------------*/
-static void bond_set_xmit_hash_policy(struct bonding *bond)
+static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb,
+ void *accel_priv, select_queue_fallback_t fallback)
{
- switch (bond->params.xmit_policy) {
- case BOND_XMIT_POLICY_LAYER23:
- bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
- break;
- case BOND_XMIT_POLICY_LAYER34:
- bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
- break;
- case BOND_XMIT_POLICY_LAYER2:
- default:
- bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
- break;
+ /*
+ * This helper function exists to help dev_pick_tx get the correct
+ * destination queue. Using a helper function skips a call to
+ * skb_tx_hash and will put the skbs in the queue we expect on their
+ * way down to the bonding driver.
+ */
+ u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
+
+ /*
+ * Save the original txq to restore before passing to the driver
+ */
+ qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
+
+ if (unlikely(txq >= dev->real_num_tx_queues)) {
+ do {
+ txq -= dev->real_num_tx_queues;
+ } while (txq >= dev->real_num_tx_queues);
}
+ return txq;
}
-/*
- * set bond mode specific net device operations
- */
-void bond_set_mode_ops(struct bonding *bond, int mode)
+static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct net_device *bond_dev = bond->dev;
+ struct bonding *bond = netdev_priv(dev);
- switch (mode) {
+ if (bond_should_override_tx_queue(bond) &&
+ !bond_slave_override(bond, skb))
+ return NETDEV_TX_OK;
+
+ switch (BOND_MODE(bond)) {
case BOND_MODE_ROUNDROBIN:
- bond_dev->hard_start_xmit = bond_xmit_roundrobin;
- break;
+ return bond_xmit_roundrobin(skb, dev);
case BOND_MODE_ACTIVEBACKUP:
- bond_dev->hard_start_xmit = bond_xmit_activebackup;
- break;
+ return bond_xmit_activebackup(skb, dev);
case BOND_MODE_XOR:
- bond_dev->hard_start_xmit = bond_xmit_xor;
- bond_set_xmit_hash_policy(bond);
- break;
+ return bond_xmit_xor(skb, dev);
case BOND_MODE_BROADCAST:
- bond_dev->hard_start_xmit = bond_xmit_broadcast;
- break;
+ return bond_xmit_broadcast(skb, dev);
case BOND_MODE_8023AD:
- bond_set_master_3ad_flags(bond);
- bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
- bond_set_xmit_hash_policy(bond);
- break;
+ return bond_3ad_xmit_xor(skb, dev);
case BOND_MODE_ALB:
- bond_set_master_alb_flags(bond);
- /* FALLTHRU */
+ return bond_alb_xmit(skb, dev);
case BOND_MODE_TLB:
- bond_dev->hard_start_xmit = bond_alb_xmit;
- bond_dev->set_mac_address = bond_alb_set_mac_address;
- break;
+ return bond_tlb_xmit(skb, dev);
default:
/* Should never happen, mode already checked */
- printk(KERN_ERR DRV_NAME
- ": %s: Error: Unknown bonding mode %d\n",
- bond_dev->name,
- mode);
- break;
+ pr_err("%s: Error: Unknown bonding mode %d\n",
+ dev->name, BOND_MODE(bond));
+ WARN_ON_ONCE(1);
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+}
+
+static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bonding *bond = netdev_priv(dev);
+ netdev_tx_t ret = NETDEV_TX_OK;
+
+ /*
+ * If we risk deadlock from transmitting this in the
+ * netpoll path, tell netpoll to queue the frame for later tx
+ */
+ if (unlikely(is_netpoll_tx_blocked(dev)))
+ return NETDEV_TX_BUSY;
+
+ rcu_read_lock();
+ if (bond_has_slaves(bond))
+ ret = __bond_start_xmit(skb, dev);
+ else
+ dev_kfree_skb_any(skb);
+ rcu_read_unlock();
+
+ return ret;
+}
+
+static int bond_ethtool_get_settings(struct net_device *bond_dev,
+ struct ethtool_cmd *ecmd)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ unsigned long speed = 0;
+ struct list_head *iter;
+ struct slave *slave;
+
+ ecmd->duplex = DUPLEX_UNKNOWN;
+ ecmd->port = PORT_OTHER;
+
+ /* Since bond_slave_can_tx returns false for all inactive or down slaves, we
+ * do not need to check mode. Though link speed might not represent
+ * the true receive or transmit bandwidth (not all modes are symmetric)
+ * this is an accurate maximum.
+ */
+ read_lock(&bond->lock);
+ bond_for_each_slave(bond, slave, iter) {
+ if (bond_slave_can_tx(slave)) {
+ if (slave->speed != SPEED_UNKNOWN)
+ speed += slave->speed;
+ if (ecmd->duplex == DUPLEX_UNKNOWN &&
+ slave->duplex != DUPLEX_UNKNOWN)
+ ecmd->duplex = slave->duplex;
+ }
}
+ ethtool_cmd_speed_set(ecmd, speed ? : SPEED_UNKNOWN);
+ read_unlock(&bond->lock);
+
+ return 0;
}
static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
- struct ethtool_drvinfo *drvinfo)
+ struct ethtool_drvinfo *drvinfo)
{
- strncpy(drvinfo->driver, DRV_NAME, 32);
- strncpy(drvinfo->version, DRV_VERSION, 32);
- snprintf(drvinfo->fw_version, 32, "%d", BOND_ABI_VERSION);
+ strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d",
+ BOND_ABI_VERSION);
}
static const struct ethtool_ops bond_ethtool_ops = {
.get_drvinfo = bond_ethtool_get_drvinfo,
+ .get_settings = bond_ethtool_get_settings,
+ .get_link = ethtool_op_get_link,
};
-/*
- * Does not allocate but creates a /proc entry.
- * Allowed to fail.
- */
-static int bond_init(struct net_device *bond_dev, struct bond_params *params)
+static const struct net_device_ops bond_netdev_ops = {
+ .ndo_init = bond_init,
+ .ndo_uninit = bond_uninit,
+ .ndo_open = bond_open,
+ .ndo_stop = bond_close,
+ .ndo_start_xmit = bond_start_xmit,
+ .ndo_select_queue = bond_select_queue,
+ .ndo_get_stats64 = bond_get_stats,
+ .ndo_do_ioctl = bond_do_ioctl,
+ .ndo_change_rx_flags = bond_change_rx_flags,
+ .ndo_set_rx_mode = bond_set_rx_mode,
+ .ndo_change_mtu = bond_change_mtu,
+ .ndo_set_mac_address = bond_set_mac_address,
+ .ndo_neigh_setup = bond_neigh_setup,
+ .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_netpoll_setup = bond_netpoll_setup,
+ .ndo_netpoll_cleanup = bond_netpoll_cleanup,
+ .ndo_poll_controller = bond_poll_controller,
+#endif
+ .ndo_add_slave = bond_enslave,
+ .ndo_del_slave = bond_release,
+ .ndo_fix_features = bond_fix_features,
+};
+
+static const struct device_type bond_type = {
+ .name = "bond",
+};
+
+static void bond_destructor(struct net_device *bond_dev)
{
- struct bonding *bond = bond_dev->priv;
+ struct bonding *bond = netdev_priv(bond_dev);
+ if (bond->wq)
+ destroy_workqueue(bond->wq);
+ free_netdev(bond_dev);
+}
- dprintk("Begin bond_init for %s\n", bond_dev->name);
+void bond_setup(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
/* initialize rwlocks */
rwlock_init(&bond->lock);
rwlock_init(&bond->curr_slave_lock);
-
- bond->params = *params; /* copy params struct */
-
- bond->wq = create_singlethread_workqueue(bond_dev->name);
- if (!bond->wq)
- return -ENOMEM;
+ bond->params = bonding_defaults;
/* Initialize pointers */
- bond->first_slave = NULL;
- bond->curr_active_slave = NULL;
- bond->current_arp_slave = NULL;
- bond->primary_slave = NULL;
bond->dev = bond_dev;
- bond->send_grat_arp = 0;
- bond->setup_by_slave = 0;
- INIT_LIST_HEAD(&bond->vlan_list);
/* Initialize the device entry points */
- bond_dev->open = bond_open;
- bond_dev->stop = bond_close;
- bond_dev->get_stats = bond_get_stats;
- bond_dev->do_ioctl = bond_do_ioctl;
+ ether_setup(bond_dev);
+ bond_dev->netdev_ops = &bond_netdev_ops;
bond_dev->ethtool_ops = &bond_ethtool_ops;
- bond_dev->set_multicast_list = bond_set_multicast_list;
- bond_dev->change_mtu = bond_change_mtu;
- bond_dev->set_mac_address = bond_set_mac_address;
- bond_dev->validate_addr = NULL;
- bond_set_mode_ops(bond, bond->params.mode);
+ bond_dev->destructor = bond_destructor;
- bond_dev->destructor = free_netdev;
+ SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
/* Initialize the device options */
bond_dev->tx_queue_len = 0;
bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
- bond_dev->priv_flags |= IFF_BONDING;
+ bond_dev->priv_flags |= IFF_BONDING | IFF_UNICAST_FLT;
+ bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
/* At first, we block adding VLANs. That's the only way to
* prevent problems that occur when adding VLANs over an
@@ -4562,249 +3973,188 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
* when there are slaves that are not hw accel
* capable
*/
- bond_dev->vlan_rx_register = bond_vlan_rx_register;
- bond_dev->vlan_rx_add_vid = bond_vlan_rx_add_vid;
- bond_dev->vlan_rx_kill_vid = bond_vlan_rx_kill_vid;
- bond_dev->features |= (NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER);
-
-#ifdef CONFIG_PROC_FS
- bond_create_proc_entry(bond);
-#endif
- list_add_tail(&bond->bond_list, &bond_dev_list);
- return 0;
-}
+ /* Don't allow bond devices to change network namespaces. */
+ bond_dev->features |= NETIF_F_NETNS_LOCAL;
-/* De-initialize device specific data.
- * Caller must hold rtnl_lock.
- */
-static void bond_deinit(struct net_device *bond_dev)
-{
- struct bonding *bond = bond_dev->priv;
+ bond_dev->hw_features = BOND_VLAN_FEATURES |
+ NETIF_F_HW_VLAN_CTAG_TX |
+ NETIF_F_HW_VLAN_CTAG_RX |
+ NETIF_F_HW_VLAN_CTAG_FILTER;
- list_del(&bond->bond_list);
-
-#ifdef CONFIG_PROC_FS
- bond_remove_proc_entry(bond);
-#endif
+ bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
+ bond_dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+ bond_dev->features |= bond_dev->hw_features;
}
-static void bond_work_cancel_all(struct bonding *bond)
+/*
+* Destroy a bonding device.
+* Must be under rtnl_lock when this function is called.
+*/
+static void bond_uninit(struct net_device *bond_dev)
{
- write_lock_bh(&bond->lock);
- bond->kill_timers = 1;
- write_unlock_bh(&bond->lock);
-
- if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
- cancel_delayed_work(&bond->mii_work);
-
- if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
- cancel_delayed_work(&bond->arp_work);
-
- if (bond->params.mode == BOND_MODE_ALB &&
- delayed_work_pending(&bond->alb_work))
- cancel_delayed_work(&bond->alb_work);
-
- if (bond->params.mode == BOND_MODE_8023AD &&
- delayed_work_pending(&bond->ad_work))
- cancel_delayed_work(&bond->ad_work);
-}
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct list_head *iter;
+ struct slave *slave;
-/* Unregister and free all bond devices.
- * Caller must hold rtnl_lock.
- */
-static void bond_free_all(void)
-{
- struct bonding *bond, *nxt;
+ bond_netpoll_cleanup(bond_dev);
- list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
- struct net_device *bond_dev = bond->dev;
+ /* Release the bonded slaves */
+ bond_for_each_slave(bond, slave, iter)
+ __bond_release_one(bond_dev, slave->dev, true);
+ pr_info("%s: Released all slaves\n", bond_dev->name);
- bond_work_cancel_all(bond);
- netif_addr_lock_bh(bond_dev);
- bond_mc_list_destroy(bond);
- netif_addr_unlock_bh(bond_dev);
- /* Release the bonded slaves */
- bond_release_all(bond_dev);
- bond_destroy(bond);
- }
+ list_del(&bond->bond_list);
-#ifdef CONFIG_PROC_FS
- bond_destroy_proc_dir();
-#endif
+ bond_debug_unregister(bond);
}
/*------------------------- Module initialization ---------------------------*/
-/*
- * Convert string input module parms. Accept either the
- * number of the mode or its string name. A bit complicated because
- * some mode names are substrings of other names, and calls from sysfs
- * may have whitespace in the name (trailing newlines, for example).
- */
-int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
-{
- int mode = -1, i, rv;
- char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
-
- for (p = (char *)buf; *p; p++)
- if (!(isdigit(*p) || isspace(*p)))
- break;
-
- if (*p)
- rv = sscanf(buf, "%20s", modestr);
- else
- rv = sscanf(buf, "%d", &mode);
-
- if (!rv)
- return -1;
-
- for (i = 0; tbl[i].modename; i++) {
- if (mode == tbl[i].mode)
- return tbl[i].mode;
- if (strcmp(modestr, tbl[i].modename) == 0)
- return tbl[i].mode;
- }
-
- return -1;
-}
-
static int bond_check_params(struct bond_params *params)
{
- int arp_validate_value, fail_over_mac_value;
+ int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
+ struct bond_opt_value newval;
+ const struct bond_opt_value *valptr;
+ int arp_all_targets_value;
/*
* Convert string parameters.
*/
if (mode) {
- bond_mode = bond_parse_parm(mode, bond_mode_tbl);
- if (bond_mode == -1) {
- printk(KERN_ERR DRV_NAME
- ": Error: Invalid bonding mode \"%s\"\n",
- mode == NULL ? "NULL" : mode);
+ bond_opt_initstr(&newval, mode);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_MODE), &newval);
+ if (!valptr) {
+ pr_err("Error: Invalid bonding mode \"%s\"\n", mode);
return -EINVAL;
}
+ bond_mode = valptr->value;
}
if (xmit_hash_policy) {
if ((bond_mode != BOND_MODE_XOR) &&
- (bond_mode != BOND_MODE_8023AD)) {
- printk(KERN_INFO DRV_NAME
- ": xor_mode param is irrelevant in mode %s\n",
- bond_mode_name(bond_mode));
+ (bond_mode != BOND_MODE_8023AD) &&
+ (bond_mode != BOND_MODE_TLB)) {
+ pr_info("xmit_hash_policy param is irrelevant in mode %s\n",
+ bond_mode_name(bond_mode));
} else {
- xmit_hashtype = bond_parse_parm(xmit_hash_policy,
- xmit_hashtype_tbl);
- if (xmit_hashtype == -1) {
- printk(KERN_ERR DRV_NAME
- ": Error: Invalid xmit_hash_policy \"%s\"\n",
- xmit_hash_policy == NULL ? "NULL" :
+ bond_opt_initstr(&newval, xmit_hash_policy);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_XMIT_HASH),
+ &newval);
+ if (!valptr) {
+ pr_err("Error: Invalid xmit_hash_policy \"%s\"\n",
xmit_hash_policy);
return -EINVAL;
}
+ xmit_hashtype = valptr->value;
}
}
if (lacp_rate) {
if (bond_mode != BOND_MODE_8023AD) {
- printk(KERN_INFO DRV_NAME
- ": lacp_rate param is irrelevant in mode %s\n",
- bond_mode_name(bond_mode));
+ pr_info("lacp_rate param is irrelevant in mode %s\n",
+ bond_mode_name(bond_mode));
} else {
- lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
- if (lacp_fast == -1) {
- printk(KERN_ERR DRV_NAME
- ": Error: Invalid lacp rate \"%s\"\n",
- lacp_rate == NULL ? "NULL" : lacp_rate);
+ bond_opt_initstr(&newval, lacp_rate);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_LACP_RATE),
+ &newval);
+ if (!valptr) {
+ pr_err("Error: Invalid lacp rate \"%s\"\n",
+ lacp_rate);
return -EINVAL;
}
+ lacp_fast = valptr->value;
}
}
- if (max_bonds < 0 || max_bonds > INT_MAX) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: max_bonds (%d) not in range %d-%d, so it "
- "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
- max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
+ if (ad_select) {
+ bond_opt_initstr(&newval, ad_select);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_AD_SELECT),
+ &newval);
+ if (!valptr) {
+ pr_err("Error: Invalid ad_select \"%s\"\n", ad_select);
+ return -EINVAL;
+ }
+ params->ad_select = valptr->value;
+ if (bond_mode != BOND_MODE_8023AD)
+ pr_warn("ad_select param only affects 802.3ad mode\n");
+ } else {
+ params->ad_select = BOND_AD_STABLE;
+ }
+
+ if (max_bonds < 0) {
+ pr_warn("Warning: max_bonds (%d) not in range %d-%d, so it was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
+ max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
max_bonds = BOND_DEFAULT_MAX_BONDS;
}
if (miimon < 0) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: miimon module parameter (%d), "
- "not in range 0-%d, so it was reset to %d\n",
- miimon, INT_MAX, BOND_LINK_MON_INTERV);
- miimon = BOND_LINK_MON_INTERV;
+ pr_warn("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ miimon, INT_MAX);
+ miimon = 0;
}
if (updelay < 0) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: updelay module parameter (%d), "
- "not in range 0-%d, so it was reset to 0\n",
- updelay, INT_MAX);
+ pr_warn("Warning: updelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ updelay, INT_MAX);
updelay = 0;
}
if (downdelay < 0) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: downdelay module parameter (%d), "
- "not in range 0-%d, so it was reset to 0\n",
- downdelay, INT_MAX);
+ pr_warn("Warning: downdelay module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ downdelay, INT_MAX);
downdelay = 0;
}
if ((use_carrier != 0) && (use_carrier != 1)) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: use_carrier module parameter (%d), "
- "not of valid value (0/1), so it was set to 1\n",
- use_carrier);
+ pr_warn("Warning: use_carrier module parameter (%d), not of valid value (0/1), so it was set to 1\n",
+ use_carrier);
use_carrier = 1;
}
- if (num_grat_arp < 0 || num_grat_arp > 255) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: num_grat_arp (%d) not in range 0-255 so it "
- "was reset to 1 \n", num_grat_arp);
- num_grat_arp = 1;
+ if (num_peer_notif < 0 || num_peer_notif > 255) {
+ pr_warn("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
+ num_peer_notif);
+ num_peer_notif = 1;
}
- /* reset values for 802.3ad */
- if (bond_mode == BOND_MODE_8023AD) {
+ /* reset values for 802.3ad/TLB/ALB */
+ if (!bond_mode_uses_arp(bond_mode)) {
if (!miimon) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: miimon must be specified, "
- "otherwise bonding will not detect link "
- "failure, speed and duplex which are "
- "essential for 802.3ad operation\n");
- printk(KERN_WARNING "Forcing miimon to 100msec\n");
- miimon = 100;
+ pr_warn("Warning: miimon must be specified, otherwise bonding will not detect link failure, speed and duplex which are essential for 802.3ad operation\n");
+ pr_warn("Forcing miimon to 100msec\n");
+ miimon = BOND_DEFAULT_MIIMON;
}
}
- /* reset values for TLB/ALB */
- if ((bond_mode == BOND_MODE_TLB) ||
- (bond_mode == BOND_MODE_ALB)) {
- if (!miimon) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: miimon must be specified, "
- "otherwise bonding will not detect link "
- "failure and link speed which are essential "
- "for TLB/ALB load balancing\n");
- printk(KERN_WARNING "Forcing miimon to 100msec\n");
- miimon = 100;
- }
+ if (tx_queues < 1 || tx_queues > 255) {
+ pr_warn("Warning: tx_queues (%d) should be between 1 and 255, resetting to %d\n",
+ tx_queues, BOND_DEFAULT_TX_QUEUES);
+ tx_queues = BOND_DEFAULT_TX_QUEUES;
+ }
+
+ if ((all_slaves_active != 0) && (all_slaves_active != 1)) {
+ pr_warn("Warning: all_slaves_active module parameter (%d), not of valid value (0/1), so it was set to 0\n",
+ all_slaves_active);
+ all_slaves_active = 0;
+ }
+
+ if (resend_igmp < 0 || resend_igmp > 255) {
+ pr_warn("Warning: resend_igmp (%d) should be between 0 and 255, resetting to %d\n",
+ resend_igmp, BOND_DEFAULT_RESEND_IGMP);
+ resend_igmp = BOND_DEFAULT_RESEND_IGMP;
+ }
+
+ bond_opt_initval(&newval, packets_per_slave);
+ if (!bond_opt_parse(bond_opt_get(BOND_OPT_PACKETS_PER_SLAVE), &newval)) {
+ pr_warn("Warning: packets_per_slave (%d) should be between 0 and %u resetting to 1\n",
+ packets_per_slave, USHRT_MAX);
+ packets_per_slave = 1;
}
if (bond_mode == BOND_MODE_ALB) {
- printk(KERN_NOTICE DRV_NAME
- ": In ALB mode you might experience client "
- "disconnections upon reconnection of a link if the "
- "bonding module updelay parameter (%d msec) is "
- "incompatible with the forwarding delay time of the "
- "switch\n",
- updelay);
+ pr_notice("In ALB mode you might experience client disconnections upon reconnection of a link if the bonding module updelay parameter (%d msec) is incompatible with the forwarding delay time of the switch\n",
+ updelay);
}
if (!miimon) {
@@ -4812,173 +4162,195 @@ static int bond_check_params(struct bond_params *params)
/* just warn the user the up/down delay will have
* no effect since miimon is zero...
*/
- printk(KERN_WARNING DRV_NAME
- ": Warning: miimon module parameter not set "
- "and updelay (%d) or downdelay (%d) module "
- "parameter is set; updelay and downdelay have "
- "no effect unless miimon is set\n",
- updelay, downdelay);
+ pr_warn("Warning: miimon module parameter not set and updelay (%d) or downdelay (%d) module parameter is set; updelay and downdelay have no effect unless miimon is set\n",
+ updelay, downdelay);
}
} else {
/* don't allow arp monitoring */
if (arp_interval) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: miimon (%d) and arp_interval (%d) "
- "can't be used simultaneously, disabling ARP "
- "monitoring\n",
- miimon, arp_interval);
+ pr_warn("Warning: miimon (%d) and arp_interval (%d) can't be used simultaneously, disabling ARP monitoring\n",
+ miimon, arp_interval);
arp_interval = 0;
}
if ((updelay % miimon) != 0) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: updelay (%d) is not a multiple "
- "of miimon (%d), updelay rounded to %d ms\n",
- updelay, miimon, (updelay / miimon) * miimon);
+ pr_warn("Warning: updelay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
+ updelay, miimon, (updelay / miimon) * miimon);
}
updelay /= miimon;
if ((downdelay % miimon) != 0) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: downdelay (%d) is not a multiple "
- "of miimon (%d), downdelay rounded to %d ms\n",
- downdelay, miimon,
- (downdelay / miimon) * miimon);
+ pr_warn("Warning: downdelay (%d) is not a multiple of miimon (%d), downdelay rounded to %d ms\n",
+ downdelay, miimon,
+ (downdelay / miimon) * miimon);
}
downdelay /= miimon;
}
if (arp_interval < 0) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: arp_interval module parameter (%d) "
- ", not in range 0-%d, so it was reset to %d\n",
- arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
- arp_interval = BOND_LINK_ARP_INTERV;
+ pr_warn("Warning: arp_interval module parameter (%d), not in range 0-%d, so it was reset to 0\n",
+ arp_interval, INT_MAX);
+ arp_interval = 0;
}
- for (arp_ip_count = 0;
- (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[arp_ip_count];
- arp_ip_count++) {
+ for (arp_ip_count = 0, i = 0;
+ (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) {
/* not complete check, but should be good enough to
catch mistakes */
- if (!isdigit(arp_ip_target[arp_ip_count][0])) {
- printk(KERN_WARNING DRV_NAME
- ": Warning: bad arp_ip_target module parameter "
- "(%s), ARP monitoring will not be performed\n",
- arp_ip_target[arp_ip_count]);
+ __be32 ip;
+ if (!in4_pton(arp_ip_target[i], -1, (u8 *)&ip, -1, NULL) ||
+ !bond_is_ip_target_ok(ip)) {
+ pr_warn("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n",
+ arp_ip_target[i]);
arp_interval = 0;
} else {
- __be32 ip = in_aton(arp_ip_target[arp_ip_count]);
- arp_target[arp_ip_count] = ip;
+ if (bond_get_targets_ip(arp_target, ip) == -1)
+ arp_target[arp_ip_count++] = ip;
+ else
+ pr_warn("Warning: duplicate address %pI4 in arp_ip_target, skipping\n",
+ &ip);
}
}
if (arp_interval && !arp_ip_count) {
/* don't allow arping if no arp_ip_target given... */
- printk(KERN_WARNING DRV_NAME
- ": Warning: arp_interval module parameter (%d) "
- "specified without providing an arp_ip_target "
- "parameter, arp_interval was reset to 0\n",
- arp_interval);
+ pr_warn("Warning: arp_interval module parameter (%d) specified without providing an arp_ip_target parameter, arp_interval was reset to 0\n",
+ arp_interval);
arp_interval = 0;
}
if (arp_validate) {
- if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
- printk(KERN_ERR DRV_NAME
- ": arp_validate only supported in active-backup mode\n");
- return -EINVAL;
- }
if (!arp_interval) {
- printk(KERN_ERR DRV_NAME
- ": arp_validate requires arp_interval\n");
+ pr_err("arp_validate requires arp_interval\n");
return -EINVAL;
}
- arp_validate_value = bond_parse_parm(arp_validate,
- arp_validate_tbl);
- if (arp_validate_value == -1) {
- printk(KERN_ERR DRV_NAME
- ": Error: invalid arp_validate \"%s\"\n",
- arp_validate == NULL ? "NULL" : arp_validate);
+ bond_opt_initstr(&newval, arp_validate);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_ARP_VALIDATE),
+ &newval);
+ if (!valptr) {
+ pr_err("Error: invalid arp_validate \"%s\"\n",
+ arp_validate);
return -EINVAL;
}
- } else
+ arp_validate_value = valptr->value;
+ } else {
arp_validate_value = 0;
+ }
+
+ arp_all_targets_value = 0;
+ if (arp_all_targets) {
+ bond_opt_initstr(&newval, arp_all_targets);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_ARP_ALL_TARGETS),
+ &newval);
+ if (!valptr) {
+ pr_err("Error: invalid arp_all_targets_value \"%s\"\n",
+ arp_all_targets);
+ arp_all_targets_value = 0;
+ } else {
+ arp_all_targets_value = valptr->value;
+ }
+ }
if (miimon) {
- printk(KERN_INFO DRV_NAME
- ": MII link monitoring set to %d ms\n",
- miimon);
+ pr_info("MII link monitoring set to %d ms\n", miimon);
} else if (arp_interval) {
- int i;
-
- printk(KERN_INFO DRV_NAME
- ": ARP monitoring set to %d ms, validate %s, with %d target(s):",
- arp_interval,
- arp_validate_tbl[arp_validate_value].modename,
- arp_ip_count);
+ valptr = bond_opt_get_val(BOND_OPT_ARP_VALIDATE,
+ arp_validate_value);
+ pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):",
+ arp_interval, valptr->string, arp_ip_count);
for (i = 0; i < arp_ip_count; i++)
- printk (" %s", arp_ip_target[i]);
+ pr_cont(" %s", arp_ip_target[i]);
- printk("\n");
+ pr_cont("\n");
} else if (max_bonds) {
/* miimon and arp_interval not set, we need one so things
* work as expected, see bonding.txt for details
*/
- printk(KERN_WARNING DRV_NAME
- ": Warning: either miimon or arp_interval and "
- "arp_ip_target module parameters must be specified, "
- "otherwise bonding will not detect link failures! see "
- "bonding.txt for details.\n");
+ pr_debug("Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details\n");
}
- if (primary && !USES_PRIMARY(bond_mode)) {
+ if (primary && !bond_mode_uses_primary(bond_mode)) {
/* currently, using a primary only makes sense
* in active backup, TLB or ALB modes
*/
- printk(KERN_WARNING DRV_NAME
- ": Warning: %s primary device specified but has no "
- "effect in %s mode\n",
- primary, bond_mode_name(bond_mode));
+ pr_warn("Warning: %s primary device specified but has no effect in %s mode\n",
+ primary, bond_mode_name(bond_mode));
primary = NULL;
}
- if (fail_over_mac) {
- fail_over_mac_value = bond_parse_parm(fail_over_mac,
- fail_over_mac_tbl);
- if (fail_over_mac_value == -1) {
- printk(KERN_ERR DRV_NAME
- ": Error: invalid fail_over_mac \"%s\"\n",
- arp_validate == NULL ? "NULL" : arp_validate);
+ if (primary && primary_reselect) {
+ bond_opt_initstr(&newval, primary_reselect);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_PRIMARY_RESELECT),
+ &newval);
+ if (!valptr) {
+ pr_err("Error: Invalid primary_reselect \"%s\"\n",
+ primary_reselect);
return -EINVAL;
}
+ primary_reselect_value = valptr->value;
+ } else {
+ primary_reselect_value = BOND_PRI_RESELECT_ALWAYS;
+ }
+ if (fail_over_mac) {
+ bond_opt_initstr(&newval, fail_over_mac);
+ valptr = bond_opt_parse(bond_opt_get(BOND_OPT_FAIL_OVER_MAC),
+ &newval);
+ if (!valptr) {
+ pr_err("Error: invalid fail_over_mac \"%s\"\n",
+ fail_over_mac);
+ return -EINVAL;
+ }
+ fail_over_mac_value = valptr->value;
if (bond_mode != BOND_MODE_ACTIVEBACKUP)
- printk(KERN_WARNING DRV_NAME
- ": Warning: fail_over_mac only affects "
- "active-backup mode.\n");
+ pr_warn("Warning: fail_over_mac only affects active-backup mode\n");
} else {
fail_over_mac_value = BOND_FOM_NONE;
}
+ if (lp_interval == 0) {
+ pr_warn("Warning: ip_interval must be between 1 and %d, so it was reset to %d\n",
+ INT_MAX, BOND_ALB_DEFAULT_LP_INTERVAL);
+ lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
+ }
+
/* fill params struct with the proper values */
params->mode = bond_mode;
params->xmit_policy = xmit_hashtype;
params->miimon = miimon;
- params->num_grat_arp = num_grat_arp;
+ params->num_peer_notif = num_peer_notif;
params->arp_interval = arp_interval;
params->arp_validate = arp_validate_value;
+ params->arp_all_targets = arp_all_targets_value;
params->updelay = updelay;
params->downdelay = downdelay;
params->use_carrier = use_carrier;
params->lacp_fast = lacp_fast;
params->primary[0] = 0;
+ params->primary_reselect = primary_reselect_value;
params->fail_over_mac = fail_over_mac_value;
+ params->tx_queues = tx_queues;
+ params->all_slaves_active = all_slaves_active;
+ params->resend_igmp = resend_igmp;
+ params->min_links = min_links;
+ params->lp_interval = lp_interval;
+ params->packets_per_slave = packets_per_slave;
+ params->tlb_dynamic_lb = 1; /* Default value */
+ if (packets_per_slave > 0) {
+ params->reciprocal_packets_per_slave =
+ reciprocal_value(packets_per_slave);
+ } else {
+ /* reciprocal_packets_per_slave is unused if
+ * packets_per_slave is 0 or 1, just initialize it
+ */
+ params->reciprocal_packets_per_slave =
+ (struct reciprocal_value) { 0 };
+ }
if (primary) {
strncpy(params->primary, primary, IFNAMSIZ);
@@ -4992,6 +4364,7 @@ static int bond_check_params(struct bond_params *params)
static struct lock_class_key bonding_netdev_xmit_lock_key;
static struct lock_class_key bonding_netdev_addr_lock_key;
+static struct lock_class_key bonding_tx_busylock_key;
static void bond_set_lockdep_class_one(struct net_device *dev,
struct netdev_queue *txq,
@@ -5006,6 +4379,52 @@ static void bond_set_lockdep_class(struct net_device *dev)
lockdep_set_class(&dev->addr_list_lock,
&bonding_netdev_addr_lock_key);
netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
+ dev->qdisc_tx_busylock = &bonding_tx_busylock_key;
+}
+
+/*
+ * Called from registration process
+ */
+static int bond_init(struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+
+ pr_debug("Begin bond_init for %s\n", bond_dev->name);
+
+ /*
+ * Initialize locks that may be required during
+ * en/deslave operations. All of the bond_open work
+ * (of which this is part) should really be moved to
+ * a phase prior to dev_open
+ */
+ spin_lock_init(&(bond_info->tx_hashtbl_lock));
+ spin_lock_init(&(bond_info->rx_hashtbl_lock));
+
+ bond->wq = create_singlethread_workqueue(bond_dev->name);
+ if (!bond->wq)
+ return -ENOMEM;
+
+ bond_set_lockdep_class(bond_dev);
+
+ list_add_tail(&bond->bond_list, &bn->dev_list);
+
+ bond_prepare_sysfs_group(bond);
+
+ bond_debug_register(bond);
+
+ /* Ensure valid dev_addr */
+ if (is_zero_ether_addr(bond_dev->dev_addr) &&
+ bond_dev->addr_assign_type == NET_ADDR_PERM)
+ eth_hw_addr_random(bond_dev);
+
+ return 0;
+}
+
+unsigned int bond_get_num_tx_queues(void)
+{
+ return tx_queues;
}
/* Create a new bond based on the specified name and bonding parameters.
@@ -5013,144 +4432,126 @@ static void bond_set_lockdep_class(struct net_device *dev)
* Caller must NOT hold rtnl_lock; we need to release it here before we
* set up our sysfs entries.
*/
-int bond_create(char *name, struct bond_params *params)
+int bond_create(struct net *net, const char *name)
{
struct net_device *bond_dev;
- struct bonding *bond;
int res;
rtnl_lock();
- down_write(&bonding_rwsem);
-
- /* Check to see if the bond already exists. */
- if (name) {
- list_for_each_entry(bond, &bond_dev_list, bond_list)
- if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
- printk(KERN_ERR DRV_NAME
- ": cannot add bond %s; it already exists\n",
- name);
- res = -EPERM;
- goto out_rtnl;
- }
- }
- bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
- ether_setup);
+ bond_dev = alloc_netdev_mq(sizeof(struct bonding),
+ name ? name : "bond%d",
+ bond_setup, tx_queues);
if (!bond_dev) {
- printk(KERN_ERR DRV_NAME
- ": %s: eek! can't alloc netdev!\n",
- name);
- res = -ENOMEM;
- goto out_rtnl;
+ pr_err("%s: eek! can't alloc netdev!\n", name);
+ rtnl_unlock();
+ return -ENOMEM;
}
- if (!name) {
- res = dev_alloc_name(bond_dev, "bond%d");
- if (res < 0)
- goto out_netdev;
- }
+ dev_net_set(bond_dev, net);
+ bond_dev->rtnl_link_ops = &bond_link_ops;
- /* bond_init() must be called after dev_alloc_name() (for the
- * /proc files), but before register_netdevice(), because we
- * need to set function pointers.
- */
+ res = register_netdevice(bond_dev);
- res = bond_init(bond_dev, params);
- if (res < 0) {
- goto out_netdev;
- }
+ netif_carrier_off(bond_dev);
- res = register_netdevice(bond_dev);
- if (res < 0) {
- goto out_bond;
- }
+ rtnl_unlock();
+ if (res < 0)
+ bond_destructor(bond_dev);
+ return res;
+}
- bond_set_lockdep_class(bond_dev);
+static int __net_init bond_net_init(struct net *net)
+{
+ struct bond_net *bn = net_generic(net, bond_net_id);
- netif_carrier_off(bond_dev);
+ bn->net = net;
+ INIT_LIST_HEAD(&bn->dev_list);
- up_write(&bonding_rwsem);
- rtnl_unlock(); /* allows sysfs registration of net device */
- res = bond_create_sysfs_entry(bond_dev->priv);
- if (res < 0) {
- rtnl_lock();
- down_write(&bonding_rwsem);
- bond_deinit(bond_dev);
- unregister_netdevice(bond_dev);
- goto out_rtnl;
- }
+ bond_create_proc_dir(bn);
+ bond_create_sysfs(bn);
return 0;
+}
-out_bond:
- bond_deinit(bond_dev);
-out_netdev:
- free_netdev(bond_dev);
-out_rtnl:
- up_write(&bonding_rwsem);
+static void __net_exit bond_net_exit(struct net *net)
+{
+ struct bond_net *bn = net_generic(net, bond_net_id);
+ struct bonding *bond, *tmp_bond;
+ LIST_HEAD(list);
+
+ bond_destroy_sysfs(bn);
+ bond_destroy_proc_dir(bn);
+
+ /* Kill off any bonds created after unregistering bond rtnl ops */
+ rtnl_lock();
+ list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list)
+ unregister_netdevice_queue(bond->dev, &list);
+ unregister_netdevice_many(&list);
rtnl_unlock();
- return res;
}
+static struct pernet_operations bond_net_ops = {
+ .init = bond_net_init,
+ .exit = bond_net_exit,
+ .id = &bond_net_id,
+ .size = sizeof(struct bond_net),
+};
+
static int __init bonding_init(void)
{
int i;
int res;
- struct bonding *bond;
- printk(KERN_INFO "%s", version);
+ pr_info("%s", bond_version);
res = bond_check_params(&bonding_defaults);
- if (res) {
+ if (res)
goto out;
- }
-#ifdef CONFIG_PROC_FS
- bond_create_proc_dir();
-#endif
+ res = register_pernet_subsys(&bond_net_ops);
+ if (res)
+ goto out;
- init_rwsem(&bonding_rwsem);
+ res = bond_netlink_init();
+ if (res)
+ goto err_link;
+
+ bond_create_debugfs();
for (i = 0; i < max_bonds; i++) {
- res = bond_create(NULL, &bonding_defaults);
+ res = bond_create(&init_net, NULL);
if (res)
goto err;
}
- res = bond_create_sysfs();
- if (res)
- goto err;
-
register_netdevice_notifier(&bond_netdev_notifier);
- register_inetaddr_notifier(&bond_inetaddr_notifier);
-
- goto out;
-err:
- list_for_each_entry(bond, &bond_dev_list, bond_list) {
- bond_work_cancel_all(bond);
- destroy_workqueue(bond->wq);
- }
-
- bond_destroy_sysfs();
-
- rtnl_lock();
- bond_free_all();
- rtnl_unlock();
out:
return res;
+err:
+ bond_destroy_debugfs();
+ bond_netlink_fini();
+err_link:
+ unregister_pernet_subsys(&bond_net_ops);
+ goto out;
}
static void __exit bonding_exit(void)
{
unregister_netdevice_notifier(&bond_netdev_notifier);
- unregister_inetaddr_notifier(&bond_inetaddr_notifier);
- bond_destroy_sysfs();
+ bond_destroy_debugfs();
- rtnl_lock();
- bond_free_all();
- rtnl_unlock();
+ bond_netlink_fini();
+ unregister_pernet_subsys(&bond_net_ops);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ /*
+ * Make sure we don't have an imbalance on our netpoll blocking
+ */
+ WARN_ON(atomic_read(&netpoll_block_tx));
+#endif
}
module_init(bonding_init);
@@ -5159,13 +4560,3 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
-MODULE_SUPPORTED_DEVICE("most ethernet devices");
-
-/*
- * Local variables:
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
-
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
new file mode 100644
index 00000000000..5ab3c1847e6
--- /dev/null
+++ b/drivers/net/bonding/bond_netlink.c
@@ -0,0 +1,573 @@
+/*
+ * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
+ * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_link.h>
+#include <linux/if_ether.h>
+#include <net/netlink.h>
+#include <net/rtnetlink.h>
+#include "bonding.h"
+
+static size_t bond_get_slave_size(const struct net_device *bond_dev,
+ const struct net_device *slave_dev)
+{
+ return nla_total_size(sizeof(u8)) + /* IFLA_BOND_SLAVE_STATE */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_SLAVE_MII_STATUS */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_SLAVE_LINK_FAILURE_COUNT */
+ nla_total_size(MAX_ADDR_LEN) + /* IFLA_BOND_SLAVE_PERM_HWADDR */
+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_QUEUE_ID */
+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_SLAVE_AD_AGGREGATOR_ID */
+ 0;
+}
+
+static int bond_fill_slave_info(struct sk_buff *skb,
+ const struct net_device *bond_dev,
+ const struct net_device *slave_dev)
+{
+ struct slave *slave = bond_slave_get_rtnl(slave_dev);
+
+ if (nla_put_u8(skb, IFLA_BOND_SLAVE_STATE, bond_slave_state(slave)))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_SLAVE_MII_STATUS, slave->link))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
+ slave->link_failure_count))
+ goto nla_put_failure;
+
+ if (nla_put(skb, IFLA_BOND_SLAVE_PERM_HWADDR,
+ slave_dev->addr_len, slave->perm_hwaddr))
+ goto nla_put_failure;
+
+ if (nla_put_u16(skb, IFLA_BOND_SLAVE_QUEUE_ID, slave->queue_id))
+ goto nla_put_failure;
+
+ if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) {
+ const struct aggregator *agg;
+
+ agg = SLAVE_AD_INFO(slave)->port.aggregator;
+ if (agg)
+ if (nla_put_u16(skb, IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
+ agg->aggregator_identifier))
+ goto nla_put_failure;
+ }
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
+ [IFLA_BOND_MODE] = { .type = NLA_U8 },
+ [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
+ [IFLA_BOND_MIIMON] = { .type = NLA_U32 },
+ [IFLA_BOND_UPDELAY] = { .type = NLA_U32 },
+ [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 },
+ [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 },
+ [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 },
+ [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED },
+ [IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 },
+ [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NLA_U32 },
+ [IFLA_BOND_PRIMARY] = { .type = NLA_U32 },
+ [IFLA_BOND_PRIMARY_RESELECT] = { .type = NLA_U8 },
+ [IFLA_BOND_FAIL_OVER_MAC] = { .type = NLA_U8 },
+ [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NLA_U8 },
+ [IFLA_BOND_RESEND_IGMP] = { .type = NLA_U32 },
+ [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NLA_U8 },
+ [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NLA_U8 },
+ [IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 },
+ [IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 },
+ [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 },
+ [IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
+ [IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
+ [IFLA_BOND_AD_INFO] = { .type = NLA_NESTED },
+};
+
+static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ if (tb[IFLA_ADDRESS]) {
+ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+ return -EINVAL;
+ if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
+ return -EADDRNOTAVAIL;
+ }
+ return 0;
+}
+
+static int bond_changelink(struct net_device *bond_dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct bond_opt_value newval;
+ int miimon = 0;
+ int err;
+
+ if (!data)
+ return 0;
+
+ if (data[IFLA_BOND_MODE]) {
+ int mode = nla_get_u8(data[IFLA_BOND_MODE]);
+
+ bond_opt_initval(&newval, mode);
+ err = __bond_opt_set(bond, BOND_OPT_MODE, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_ACTIVE_SLAVE]) {
+ int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
+ struct net_device *slave_dev;
+ char *active_slave = "";
+
+ if (ifindex != 0) {
+ slave_dev = __dev_get_by_index(dev_net(bond_dev),
+ ifindex);
+ if (!slave_dev)
+ return -ENODEV;
+ active_slave = slave_dev->name;
+ }
+ bond_opt_initstr(&newval, active_slave);
+ err = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_MIIMON]) {
+ miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
+
+ bond_opt_initval(&newval, miimon);
+ err = __bond_opt_set(bond, BOND_OPT_MIIMON, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_UPDELAY]) {
+ int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]);
+
+ bond_opt_initval(&newval, updelay);
+ err = __bond_opt_set(bond, BOND_OPT_UPDELAY, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_DOWNDELAY]) {
+ int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]);
+
+ bond_opt_initval(&newval, downdelay);
+ err = __bond_opt_set(bond, BOND_OPT_DOWNDELAY, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_USE_CARRIER]) {
+ int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]);
+
+ bond_opt_initval(&newval, use_carrier);
+ err = __bond_opt_set(bond, BOND_OPT_USE_CARRIER, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_ARP_INTERVAL]) {
+ int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]);
+
+ if (arp_interval && miimon) {
+ pr_err("%s: ARP monitoring cannot be used with MII monitoring\n",
+ bond->dev->name);
+ return -EINVAL;
+ }
+
+ bond_opt_initval(&newval, arp_interval);
+ err = __bond_opt_set(bond, BOND_OPT_ARP_INTERVAL, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_ARP_IP_TARGET]) {
+ struct nlattr *attr;
+ int i = 0, rem;
+
+ bond_option_arp_ip_targets_clear(bond);
+ nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) {
+ __be32 target = nla_get_be32(attr);
+
+ bond_opt_initval(&newval, (__force u64)target);
+ err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS,
+ &newval);
+ if (err)
+ break;
+ i++;
+ }
+ if (i == 0 && bond->params.arp_interval)
+ pr_warn("%s: Removing last arp target with arp_interval on\n",
+ bond->dev->name);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_ARP_VALIDATE]) {
+ int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]);
+
+ if (arp_validate && miimon) {
+ pr_err("%s: ARP validating cannot be used with MII monitoring\n",
+ bond->dev->name);
+ return -EINVAL;
+ }
+
+ bond_opt_initval(&newval, arp_validate);
+ err = __bond_opt_set(bond, BOND_OPT_ARP_VALIDATE, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_ARP_ALL_TARGETS]) {
+ int arp_all_targets =
+ nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]);
+
+ bond_opt_initval(&newval, arp_all_targets);
+ err = __bond_opt_set(bond, BOND_OPT_ARP_ALL_TARGETS, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_PRIMARY]) {
+ int ifindex = nla_get_u32(data[IFLA_BOND_PRIMARY]);
+ struct net_device *dev;
+ char *primary = "";
+
+ dev = __dev_get_by_index(dev_net(bond_dev), ifindex);
+ if (dev)
+ primary = dev->name;
+
+ bond_opt_initstr(&newval, primary);
+ err = __bond_opt_set(bond, BOND_OPT_PRIMARY, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_PRIMARY_RESELECT]) {
+ int primary_reselect =
+ nla_get_u8(data[IFLA_BOND_PRIMARY_RESELECT]);
+
+ bond_opt_initval(&newval, primary_reselect);
+ err = __bond_opt_set(bond, BOND_OPT_PRIMARY_RESELECT, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_FAIL_OVER_MAC]) {
+ int fail_over_mac =
+ nla_get_u8(data[IFLA_BOND_FAIL_OVER_MAC]);
+
+ bond_opt_initval(&newval, fail_over_mac);
+ err = __bond_opt_set(bond, BOND_OPT_FAIL_OVER_MAC, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_XMIT_HASH_POLICY]) {
+ int xmit_hash_policy =
+ nla_get_u8(data[IFLA_BOND_XMIT_HASH_POLICY]);
+
+ bond_opt_initval(&newval, xmit_hash_policy);
+ err = __bond_opt_set(bond, BOND_OPT_XMIT_HASH, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_RESEND_IGMP]) {
+ int resend_igmp =
+ nla_get_u32(data[IFLA_BOND_RESEND_IGMP]);
+
+ bond_opt_initval(&newval, resend_igmp);
+ err = __bond_opt_set(bond, BOND_OPT_RESEND_IGMP, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_NUM_PEER_NOTIF]) {
+ int num_peer_notif =
+ nla_get_u8(data[IFLA_BOND_NUM_PEER_NOTIF]);
+
+ bond_opt_initval(&newval, num_peer_notif);
+ err = __bond_opt_set(bond, BOND_OPT_NUM_PEER_NOTIF, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_ALL_SLAVES_ACTIVE]) {
+ int all_slaves_active =
+ nla_get_u8(data[IFLA_BOND_ALL_SLAVES_ACTIVE]);
+
+ bond_opt_initval(&newval, all_slaves_active);
+ err = __bond_opt_set(bond, BOND_OPT_ALL_SLAVES_ACTIVE, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_MIN_LINKS]) {
+ int min_links =
+ nla_get_u32(data[IFLA_BOND_MIN_LINKS]);
+
+ bond_opt_initval(&newval, min_links);
+ err = __bond_opt_set(bond, BOND_OPT_MINLINKS, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_LP_INTERVAL]) {
+ int lp_interval =
+ nla_get_u32(data[IFLA_BOND_LP_INTERVAL]);
+
+ bond_opt_initval(&newval, lp_interval);
+ err = __bond_opt_set(bond, BOND_OPT_LP_INTERVAL, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_PACKETS_PER_SLAVE]) {
+ int packets_per_slave =
+ nla_get_u32(data[IFLA_BOND_PACKETS_PER_SLAVE]);
+
+ bond_opt_initval(&newval, packets_per_slave);
+ err = __bond_opt_set(bond, BOND_OPT_PACKETS_PER_SLAVE, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_AD_LACP_RATE]) {
+ int lacp_rate =
+ nla_get_u8(data[IFLA_BOND_AD_LACP_RATE]);
+
+ bond_opt_initval(&newval, lacp_rate);
+ err = __bond_opt_set(bond, BOND_OPT_LACP_RATE, &newval);
+ if (err)
+ return err;
+ }
+ if (data[IFLA_BOND_AD_SELECT]) {
+ int ad_select =
+ nla_get_u8(data[IFLA_BOND_AD_SELECT]);
+
+ bond_opt_initval(&newval, ad_select);
+ err = __bond_opt_set(bond, BOND_OPT_AD_SELECT, &newval);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ int err;
+
+ err = bond_changelink(bond_dev, tb, data);
+ if (err < 0)
+ return err;
+
+ return register_netdevice(bond_dev);
+}
+
+static size_t bond_get_size(const struct net_device *bond_dev)
+{
+ return nla_total_size(sizeof(u8)) + /* IFLA_BOND_MODE */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_DOWNDELAY */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_USE_CARRIER */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_INTERVAL */
+ /* IFLA_BOND_ARP_IP_TARGET */
+ nla_total_size(sizeof(struct nlattr)) +
+ nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS +
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_VALIDATE */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_ALL_TARGETS */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_PRIMARY */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_PRIMARY_RESELECT */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_FAIL_OVER_MAC */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_XMIT_HASH_POLICY */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_RESEND_IGMP */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_NUM_PEER_NOTIF */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_ALL_SLAVES_ACTIVE */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIN_LINKS */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_LP_INTERVAL */
+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_PACKETS_PER_SLAVE */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_LACP_RATE */
+ nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_SELECT */
+ nla_total_size(sizeof(struct nlattr)) + /* IFLA_BOND_AD_INFO */
+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_AGGREGATOR */
+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_NUM_PORTS */
+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_ACTOR_KEY */
+ nla_total_size(sizeof(u16)) + /* IFLA_BOND_AD_INFO_PARTNER_KEY*/
+ nla_total_size(ETH_ALEN) + /* IFLA_BOND_AD_INFO_PARTNER_MAC*/
+ 0;
+}
+
+static int bond_fill_info(struct sk_buff *skb,
+ const struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct net_device *slave_dev = bond_option_active_slave_get(bond);
+ struct nlattr *targets;
+ unsigned int packets_per_slave;
+ int i, targets_added;
+
+ if (nla_put_u8(skb, IFLA_BOND_MODE, BOND_MODE(bond)))
+ goto nla_put_failure;
+
+ if (slave_dev &&
+ nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_UPDELAY,
+ bond->params.updelay * bond->params.miimon))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_DOWNDELAY,
+ bond->params.downdelay * bond->params.miimon))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_ARP_INTERVAL, bond->params.arp_interval))
+ goto nla_put_failure;
+
+ targets = nla_nest_start(skb, IFLA_BOND_ARP_IP_TARGET);
+ if (!targets)
+ goto nla_put_failure;
+
+ targets_added = 0;
+ for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
+ if (bond->params.arp_targets[i]) {
+ nla_put_be32(skb, i, bond->params.arp_targets[i]);
+ targets_added = 1;
+ }
+ }
+
+ if (targets_added)
+ nla_nest_end(skb, targets);
+ else
+ nla_nest_cancel(skb, targets);
+
+ if (nla_put_u32(skb, IFLA_BOND_ARP_VALIDATE, bond->params.arp_validate))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_ARP_ALL_TARGETS,
+ bond->params.arp_all_targets))
+ goto nla_put_failure;
+
+ if (bond->primary_slave &&
+ nla_put_u32(skb, IFLA_BOND_PRIMARY,
+ bond->primary_slave->dev->ifindex))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_PRIMARY_RESELECT,
+ bond->params.primary_reselect))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_FAIL_OVER_MAC,
+ bond->params.fail_over_mac))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_XMIT_HASH_POLICY,
+ bond->params.xmit_policy))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_RESEND_IGMP,
+ bond->params.resend_igmp))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_NUM_PEER_NOTIF,
+ bond->params.num_peer_notif))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_ALL_SLAVES_ACTIVE,
+ bond->params.all_slaves_active))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_MIN_LINKS,
+ bond->params.min_links))
+ goto nla_put_failure;
+
+ if (nla_put_u32(skb, IFLA_BOND_LP_INTERVAL,
+ bond->params.lp_interval))
+ goto nla_put_failure;
+
+ packets_per_slave = bond->params.packets_per_slave;
+ if (nla_put_u32(skb, IFLA_BOND_PACKETS_PER_SLAVE,
+ packets_per_slave))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_AD_LACP_RATE,
+ bond->params.lacp_fast))
+ goto nla_put_failure;
+
+ if (nla_put_u8(skb, IFLA_BOND_AD_SELECT,
+ bond->params.ad_select))
+ goto nla_put_failure;
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+ struct ad_info info;
+
+ if (!bond_3ad_get_active_agg_info(bond, &info)) {
+ struct nlattr *nest;
+
+ nest = nla_nest_start(skb, IFLA_BOND_AD_INFO);
+ if (!nest)
+ goto nla_put_failure;
+
+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_AGGREGATOR,
+ info.aggregator_id))
+ goto nla_put_failure;
+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_NUM_PORTS,
+ info.ports))
+ goto nla_put_failure;
+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_ACTOR_KEY,
+ info.actor_key))
+ goto nla_put_failure;
+ if (nla_put_u16(skb, IFLA_BOND_AD_INFO_PARTNER_KEY,
+ info.partner_key))
+ goto nla_put_failure;
+ if (nla_put(skb, IFLA_BOND_AD_INFO_PARTNER_MAC,
+ sizeof(info.partner_system),
+ &info.partner_system))
+ goto nla_put_failure;
+
+ nla_nest_end(skb, nest);
+ }
+ }
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+struct rtnl_link_ops bond_link_ops __read_mostly = {
+ .kind = "bond",
+ .priv_size = sizeof(struct bonding),
+ .setup = bond_setup,
+ .maxtype = IFLA_BOND_MAX,
+ .policy = bond_policy,
+ .validate = bond_validate,
+ .newlink = bond_newlink,
+ .changelink = bond_changelink,
+ .get_size = bond_get_size,
+ .fill_info = bond_fill_info,
+ .get_num_tx_queues = bond_get_num_tx_queues,
+ .get_num_rx_queues = bond_get_num_tx_queues, /* Use the same number
+ as for TX queues */
+ .get_slave_size = bond_get_slave_size,
+ .fill_slave_info = bond_fill_slave_info,
+};
+
+int __init bond_netlink_init(void)
+{
+ return rtnl_link_register(&bond_link_ops);
+}
+
+void bond_netlink_fini(void)
+{
+ rtnl_link_unregister(&bond_link_ops);
+}
+
+MODULE_ALIAS_RTNL_LINK("bond");
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
new file mode 100644
index 00000000000..540e0167bf2
--- /dev/null
+++ b/drivers/net/bonding/bond_options.c
@@ -0,0 +1,1394 @@
+/*
+ * drivers/net/bond/bond_options.c - bonding options
+ * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/errno.h>
+#include <linux/if.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/ctype.h>
+#include <linux/inet.h>
+#include "bonding.h"
+
+static int bond_option_active_slave_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_miimon_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_updelay_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_downdelay_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_use_carrier_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_arp_interval_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target);
+static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target);
+static int bond_option_arp_ip_targets_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_arp_validate_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_arp_all_targets_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_primary_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_primary_reselect_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_fail_over_mac_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_xmit_hash_policy_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_resend_igmp_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_num_peer_notif_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_all_slaves_active_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_min_links_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_lp_interval_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_pps_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_lacp_rate_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_ad_select_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_queue_id_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_mode_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_slaves_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
+
+
+static const struct bond_opt_value bond_mode_tbl[] = {
+ { "balance-rr", BOND_MODE_ROUNDROBIN, BOND_VALFLAG_DEFAULT},
+ { "active-backup", BOND_MODE_ACTIVEBACKUP, 0},
+ { "balance-xor", BOND_MODE_XOR, 0},
+ { "broadcast", BOND_MODE_BROADCAST, 0},
+ { "802.3ad", BOND_MODE_8023AD, 0},
+ { "balance-tlb", BOND_MODE_TLB, 0},
+ { "balance-alb", BOND_MODE_ALB, 0},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_pps_tbl[] = {
+ { "default", 1, BOND_VALFLAG_DEFAULT},
+ { "maxval", USHRT_MAX, BOND_VALFLAG_MAX},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_xmit_hashtype_tbl[] = {
+ { "layer2", BOND_XMIT_POLICY_LAYER2, BOND_VALFLAG_DEFAULT},
+ { "layer3+4", BOND_XMIT_POLICY_LAYER34, 0},
+ { "layer2+3", BOND_XMIT_POLICY_LAYER23, 0},
+ { "encap2+3", BOND_XMIT_POLICY_ENCAP23, 0},
+ { "encap3+4", BOND_XMIT_POLICY_ENCAP34, 0},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_arp_validate_tbl[] = {
+ { "none", BOND_ARP_VALIDATE_NONE, BOND_VALFLAG_DEFAULT},
+ { "active", BOND_ARP_VALIDATE_ACTIVE, 0},
+ { "backup", BOND_ARP_VALIDATE_BACKUP, 0},
+ { "all", BOND_ARP_VALIDATE_ALL, 0},
+ { "filter", BOND_ARP_FILTER, 0},
+ { "filter_active", BOND_ARP_FILTER_ACTIVE, 0},
+ { "filter_backup", BOND_ARP_FILTER_BACKUP, 0},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_arp_all_targets_tbl[] = {
+ { "any", BOND_ARP_TARGETS_ANY, BOND_VALFLAG_DEFAULT},
+ { "all", BOND_ARP_TARGETS_ALL, 0},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_fail_over_mac_tbl[] = {
+ { "none", BOND_FOM_NONE, BOND_VALFLAG_DEFAULT},
+ { "active", BOND_FOM_ACTIVE, 0},
+ { "follow", BOND_FOM_FOLLOW, 0},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_intmax_tbl[] = {
+ { "off", 0, BOND_VALFLAG_DEFAULT},
+ { "maxval", INT_MAX, BOND_VALFLAG_MAX},
+ { NULL, -1, 0}
+};
+
+static const struct bond_opt_value bond_lacp_rate_tbl[] = {
+ { "slow", AD_LACP_SLOW, 0},
+ { "fast", AD_LACP_FAST, 0},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_ad_select_tbl[] = {
+ { "stable", BOND_AD_STABLE, BOND_VALFLAG_DEFAULT},
+ { "bandwidth", BOND_AD_BANDWIDTH, 0},
+ { "count", BOND_AD_COUNT, 0},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_num_peer_notif_tbl[] = {
+ { "off", 0, 0},
+ { "maxval", 255, BOND_VALFLAG_MAX},
+ { "default", 1, BOND_VALFLAG_DEFAULT},
+ { NULL, -1, 0}
+};
+
+static const struct bond_opt_value bond_primary_reselect_tbl[] = {
+ { "always", BOND_PRI_RESELECT_ALWAYS, BOND_VALFLAG_DEFAULT},
+ { "better", BOND_PRI_RESELECT_BETTER, 0},
+ { "failure", BOND_PRI_RESELECT_FAILURE, 0},
+ { NULL, -1},
+};
+
+static const struct bond_opt_value bond_use_carrier_tbl[] = {
+ { "off", 0, 0},
+ { "on", 1, BOND_VALFLAG_DEFAULT},
+ { NULL, -1, 0}
+};
+
+static const struct bond_opt_value bond_all_slaves_active_tbl[] = {
+ { "off", 0, BOND_VALFLAG_DEFAULT},
+ { "on", 1, 0},
+ { NULL, -1, 0}
+};
+
+static const struct bond_opt_value bond_resend_igmp_tbl[] = {
+ { "off", 0, 0},
+ { "maxval", 255, BOND_VALFLAG_MAX},
+ { "default", 1, BOND_VALFLAG_DEFAULT},
+ { NULL, -1, 0}
+};
+
+static const struct bond_opt_value bond_lp_interval_tbl[] = {
+ { "minval", 1, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT},
+ { "maxval", INT_MAX, BOND_VALFLAG_MAX},
+ { NULL, -1, 0},
+};
+
+static const struct bond_opt_value bond_tlb_dynamic_lb_tbl[] = {
+ { "off", 0, 0},
+ { "on", 1, BOND_VALFLAG_DEFAULT},
+ { NULL, -1, 0}
+};
+
+static const struct bond_option bond_opts[] = {
+ [BOND_OPT_MODE] = {
+ .id = BOND_OPT_MODE,
+ .name = "mode",
+ .desc = "bond device mode",
+ .flags = BOND_OPTFLAG_NOSLAVES | BOND_OPTFLAG_IFDOWN,
+ .values = bond_mode_tbl,
+ .set = bond_option_mode_set
+ },
+ [BOND_OPT_PACKETS_PER_SLAVE] = {
+ .id = BOND_OPT_PACKETS_PER_SLAVE,
+ .name = "packets_per_slave",
+ .desc = "Packets to send per slave in RR mode",
+ .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ROUNDROBIN)),
+ .values = bond_pps_tbl,
+ .set = bond_option_pps_set
+ },
+ [BOND_OPT_XMIT_HASH] = {
+ .id = BOND_OPT_XMIT_HASH,
+ .name = "xmit_hash_policy",
+ .desc = "balance-xor, 802.3ad, and tlb hashing method",
+ .values = bond_xmit_hashtype_tbl,
+ .set = bond_option_xmit_hash_policy_set
+ },
+ [BOND_OPT_ARP_VALIDATE] = {
+ .id = BOND_OPT_ARP_VALIDATE,
+ .name = "arp_validate",
+ .desc = "validate src/dst of ARP probes",
+ .unsuppmodes = BIT(BOND_MODE_8023AD) | BIT(BOND_MODE_TLB) |
+ BIT(BOND_MODE_ALB),
+ .values = bond_arp_validate_tbl,
+ .set = bond_option_arp_validate_set
+ },
+ [BOND_OPT_ARP_ALL_TARGETS] = {
+ .id = BOND_OPT_ARP_ALL_TARGETS,
+ .name = "arp_all_targets",
+ .desc = "fail on any/all arp targets timeout",
+ .values = bond_arp_all_targets_tbl,
+ .set = bond_option_arp_all_targets_set
+ },
+ [BOND_OPT_FAIL_OVER_MAC] = {
+ .id = BOND_OPT_FAIL_OVER_MAC,
+ .name = "fail_over_mac",
+ .desc = "For active-backup, do not set all slaves to the same MAC",
+ .flags = BOND_OPTFLAG_NOSLAVES,
+ .values = bond_fail_over_mac_tbl,
+ .set = bond_option_fail_over_mac_set
+ },
+ [BOND_OPT_ARP_INTERVAL] = {
+ .id = BOND_OPT_ARP_INTERVAL,
+ .name = "arp_interval",
+ .desc = "arp interval in milliseconds",
+ .unsuppmodes = BIT(BOND_MODE_8023AD) | BIT(BOND_MODE_TLB) |
+ BIT(BOND_MODE_ALB),
+ .values = bond_intmax_tbl,
+ .set = bond_option_arp_interval_set
+ },
+ [BOND_OPT_ARP_TARGETS] = {
+ .id = BOND_OPT_ARP_TARGETS,
+ .name = "arp_ip_target",
+ .desc = "arp targets in n.n.n.n form",
+ .flags = BOND_OPTFLAG_RAWVAL,
+ .set = bond_option_arp_ip_targets_set
+ },
+ [BOND_OPT_DOWNDELAY] = {
+ .id = BOND_OPT_DOWNDELAY,
+ .name = "downdelay",
+ .desc = "Delay before considering link down, in milliseconds",
+ .values = bond_intmax_tbl,
+ .set = bond_option_downdelay_set
+ },
+ [BOND_OPT_UPDELAY] = {
+ .id = BOND_OPT_UPDELAY,
+ .name = "updelay",
+ .desc = "Delay before considering link up, in milliseconds",
+ .values = bond_intmax_tbl,
+ .set = bond_option_updelay_set
+ },
+ [BOND_OPT_LACP_RATE] = {
+ .id = BOND_OPT_LACP_RATE,
+ .name = "lacp_rate",
+ .desc = "LACPDU tx rate to request from 802.3ad partner",
+ .flags = BOND_OPTFLAG_IFDOWN,
+ .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+ .values = bond_lacp_rate_tbl,
+ .set = bond_option_lacp_rate_set
+ },
+ [BOND_OPT_MINLINKS] = {
+ .id = BOND_OPT_MINLINKS,
+ .name = "min_links",
+ .desc = "Minimum number of available links before turning on carrier",
+ .values = bond_intmax_tbl,
+ .set = bond_option_min_links_set
+ },
+ [BOND_OPT_AD_SELECT] = {
+ .id = BOND_OPT_AD_SELECT,
+ .name = "ad_select",
+ .desc = "803.ad aggregation selection logic",
+ .flags = BOND_OPTFLAG_IFDOWN,
+ .values = bond_ad_select_tbl,
+ .set = bond_option_ad_select_set
+ },
+ [BOND_OPT_NUM_PEER_NOTIF] = {
+ .id = BOND_OPT_NUM_PEER_NOTIF,
+ .name = "num_unsol_na",
+ .desc = "Number of peer notifications to send on failover event",
+ .values = bond_num_peer_notif_tbl,
+ .set = bond_option_num_peer_notif_set
+ },
+ [BOND_OPT_MIIMON] = {
+ .id = BOND_OPT_MIIMON,
+ .name = "miimon",
+ .desc = "Link check interval in milliseconds",
+ .values = bond_intmax_tbl,
+ .set = bond_option_miimon_set
+ },
+ [BOND_OPT_PRIMARY] = {
+ .id = BOND_OPT_PRIMARY,
+ .name = "primary",
+ .desc = "Primary network device to use",
+ .flags = BOND_OPTFLAG_RAWVAL,
+ .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP) |
+ BIT(BOND_MODE_TLB) |
+ BIT(BOND_MODE_ALB)),
+ .set = bond_option_primary_set
+ },
+ [BOND_OPT_PRIMARY_RESELECT] = {
+ .id = BOND_OPT_PRIMARY_RESELECT,
+ .name = "primary_reselect",
+ .desc = "Reselect primary slave once it comes up",
+ .values = bond_primary_reselect_tbl,
+ .set = bond_option_primary_reselect_set
+ },
+ [BOND_OPT_USE_CARRIER] = {
+ .id = BOND_OPT_USE_CARRIER,
+ .name = "use_carrier",
+ .desc = "Use netif_carrier_ok (vs MII ioctls) in miimon",
+ .values = bond_use_carrier_tbl,
+ .set = bond_option_use_carrier_set
+ },
+ [BOND_OPT_ACTIVE_SLAVE] = {
+ .id = BOND_OPT_ACTIVE_SLAVE,
+ .name = "active_slave",
+ .desc = "Currently active slave",
+ .flags = BOND_OPTFLAG_RAWVAL,
+ .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP) |
+ BIT(BOND_MODE_TLB) |
+ BIT(BOND_MODE_ALB)),
+ .set = bond_option_active_slave_set
+ },
+ [BOND_OPT_QUEUE_ID] = {
+ .id = BOND_OPT_QUEUE_ID,
+ .name = "queue_id",
+ .desc = "Set queue id of a slave",
+ .flags = BOND_OPTFLAG_RAWVAL,
+ .set = bond_option_queue_id_set
+ },
+ [BOND_OPT_ALL_SLAVES_ACTIVE] = {
+ .id = BOND_OPT_ALL_SLAVES_ACTIVE,
+ .name = "all_slaves_active",
+ .desc = "Keep all frames received on an interface by setting active flag for all slaves",
+ .values = bond_all_slaves_active_tbl,
+ .set = bond_option_all_slaves_active_set
+ },
+ [BOND_OPT_RESEND_IGMP] = {
+ .id = BOND_OPT_RESEND_IGMP,
+ .name = "resend_igmp",
+ .desc = "Number of IGMP membership reports to send on link failure",
+ .values = bond_resend_igmp_tbl,
+ .set = bond_option_resend_igmp_set
+ },
+ [BOND_OPT_LP_INTERVAL] = {
+ .id = BOND_OPT_LP_INTERVAL,
+ .name = "lp_interval",
+ .desc = "The number of seconds between instances where the bonding driver sends learning packets to each slave's peer switch",
+ .values = bond_lp_interval_tbl,
+ .set = bond_option_lp_interval_set
+ },
+ [BOND_OPT_SLAVES] = {
+ .id = BOND_OPT_SLAVES,
+ .name = "slaves",
+ .desc = "Slave membership management",
+ .flags = BOND_OPTFLAG_RAWVAL,
+ .set = bond_option_slaves_set
+ },
+ [BOND_OPT_TLB_DYNAMIC_LB] = {
+ .id = BOND_OPT_TLB_DYNAMIC_LB,
+ .name = "tlb_dynamic_lb",
+ .desc = "Enable dynamic flow shuffling",
+ .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_TLB)),
+ .values = bond_tlb_dynamic_lb_tbl,
+ .flags = BOND_OPTFLAG_IFDOWN,
+ .set = bond_option_tlb_dynamic_lb_set,
+ },
+ { }
+};
+
+/* Searches for an option by name */
+const struct bond_option *bond_opt_get_by_name(const char *name)
+{
+ const struct bond_option *opt;
+ int option;
+
+ for (option = 0; option < BOND_OPT_LAST; option++) {
+ opt = bond_opt_get(option);
+ if (opt && !strcmp(opt->name, name))
+ return opt;
+ }
+
+ return NULL;
+}
+
+/* Searches for a value in opt's values[] table */
+const struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val)
+{
+ const struct bond_option *opt;
+ int i;
+
+ opt = bond_opt_get(option);
+ if (WARN_ON(!opt))
+ return NULL;
+ for (i = 0; opt->values && opt->values[i].string; i++)
+ if (opt->values[i].value == val)
+ return &opt->values[i];
+
+ return NULL;
+}
+
+/* Searches for a value in opt's values[] table which matches the flagmask */
+static const struct bond_opt_value *bond_opt_get_flags(const struct bond_option *opt,
+ u32 flagmask)
+{
+ int i;
+
+ for (i = 0; opt->values && opt->values[i].string; i++)
+ if (opt->values[i].flags & flagmask)
+ return &opt->values[i];
+
+ return NULL;
+}
+
+/* If maxval is missing then there's no range to check. In case minval is
+ * missing then it's considered to be 0.
+ */
+static bool bond_opt_check_range(const struct bond_option *opt, u64 val)
+{
+ const struct bond_opt_value *minval, *maxval;
+
+ minval = bond_opt_get_flags(opt, BOND_VALFLAG_MIN);
+ maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX);
+ if (!maxval || (minval && val < minval->value) || val > maxval->value)
+ return false;
+
+ return true;
+}
+
+/**
+ * bond_opt_parse - parse option value
+ * @opt: the option to parse against
+ * @val: value to parse
+ *
+ * This function tries to extract the value from @val and check if it's
+ * a possible match for the option and returns NULL if a match isn't found,
+ * or the struct_opt_value that matched. It also strips the new line from
+ * @val->string if it's present.
+ */
+const struct bond_opt_value *bond_opt_parse(const struct bond_option *opt,
+ struct bond_opt_value *val)
+{
+ char *p, valstr[BOND_OPT_MAX_NAMELEN + 1] = { 0, };
+ const struct bond_opt_value *tbl;
+ const struct bond_opt_value *ret = NULL;
+ bool checkval;
+ int i, rv;
+
+ /* No parsing if the option wants a raw val */
+ if (opt->flags & BOND_OPTFLAG_RAWVAL)
+ return val;
+
+ tbl = opt->values;
+ if (!tbl)
+ goto out;
+
+ /* ULLONG_MAX is used to bypass string processing */
+ checkval = val->value != ULLONG_MAX;
+ if (!checkval) {
+ if (!val->string)
+ goto out;
+ p = strchr(val->string, '\n');
+ if (p)
+ *p = '\0';
+ for (p = val->string; *p; p++)
+ if (!(isdigit(*p) || isspace(*p)))
+ break;
+ /* The following code extracts the string to match or the value
+ * and sets checkval appropriately
+ */
+ if (*p) {
+ rv = sscanf(val->string, "%32s", valstr);
+ } else {
+ rv = sscanf(val->string, "%llu", &val->value);
+ checkval = true;
+ }
+ if (!rv)
+ goto out;
+ }
+
+ for (i = 0; tbl[i].string; i++) {
+ /* Check for exact match */
+ if (checkval) {
+ if (val->value == tbl[i].value)
+ ret = &tbl[i];
+ } else {
+ if (!strcmp(valstr, "default") &&
+ (tbl[i].flags & BOND_VALFLAG_DEFAULT))
+ ret = &tbl[i];
+
+ if (!strcmp(valstr, tbl[i].string))
+ ret = &tbl[i];
+ }
+ /* Found an exact match */
+ if (ret)
+ goto out;
+ }
+ /* Possible range match */
+ if (checkval && bond_opt_check_range(opt, val->value))
+ ret = val;
+out:
+ return ret;
+}
+
+/* Check opt's dependencies against bond mode and currently set options */
+static int bond_opt_check_deps(struct bonding *bond,
+ const struct bond_option *opt)
+{
+ struct bond_params *params = &bond->params;
+
+ if (test_bit(params->mode, &opt->unsuppmodes))
+ return -EACCES;
+ if ((opt->flags & BOND_OPTFLAG_NOSLAVES) && bond_has_slaves(bond))
+ return -ENOTEMPTY;
+ if ((opt->flags & BOND_OPTFLAG_IFDOWN) && (bond->dev->flags & IFF_UP))
+ return -EBUSY;
+
+ return 0;
+}
+
+static void bond_opt_dep_print(struct bonding *bond,
+ const struct bond_option *opt)
+{
+ const struct bond_opt_value *modeval;
+ struct bond_params *params;
+
+ params = &bond->params;
+ modeval = bond_opt_get_val(BOND_OPT_MODE, params->mode);
+ if (test_bit(params->mode, &opt->unsuppmodes))
+ pr_err("%s: option %s: mode dependency failed, not supported in mode %s(%llu)\n",
+ bond->dev->name, opt->name,
+ modeval->string, modeval->value);
+}
+
+static void bond_opt_error_interpret(struct bonding *bond,
+ const struct bond_option *opt,
+ int error, const struct bond_opt_value *val)
+{
+ const struct bond_opt_value *minval, *maxval;
+ char *p;
+
+ switch (error) {
+ case -EINVAL:
+ if (val) {
+ if (val->string) {
+ /* sometimes RAWVAL opts may have new lines */
+ p = strchr(val->string, '\n');
+ if (p)
+ *p = '\0';
+ pr_err("%s: option %s: invalid value (%s)\n",
+ bond->dev->name, opt->name, val->string);
+ } else {
+ pr_err("%s: option %s: invalid value (%llu)\n",
+ bond->dev->name, opt->name, val->value);
+ }
+ }
+ minval = bond_opt_get_flags(opt, BOND_VALFLAG_MIN);
+ maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX);
+ if (!maxval)
+ break;
+ pr_err("%s: option %s: allowed values %llu - %llu\n",
+ bond->dev->name, opt->name, minval ? minval->value : 0,
+ maxval->value);
+ break;
+ case -EACCES:
+ bond_opt_dep_print(bond, opt);
+ break;
+ case -ENOTEMPTY:
+ pr_err("%s: option %s: unable to set because the bond device has slaves\n",
+ bond->dev->name, opt->name);
+ break;
+ case -EBUSY:
+ pr_err("%s: option %s: unable to set because the bond device is up\n",
+ bond->dev->name, opt->name);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * __bond_opt_set - set a bonding option
+ * @bond: target bond device
+ * @option: option to set
+ * @val: value to set it to
+ *
+ * This function is used to change the bond's option value, it can be
+ * used for both enabling/changing an option and for disabling it. RTNL lock
+ * must be obtained before calling this function.
+ */
+int __bond_opt_set(struct bonding *bond,
+ unsigned int option, struct bond_opt_value *val)
+{
+ const struct bond_opt_value *retval = NULL;
+ const struct bond_option *opt;
+ int ret = -ENOENT;
+
+ ASSERT_RTNL();
+
+ opt = bond_opt_get(option);
+ if (WARN_ON(!val) || WARN_ON(!opt))
+ goto out;
+ ret = bond_opt_check_deps(bond, opt);
+ if (ret)
+ goto out;
+ retval = bond_opt_parse(opt, val);
+ if (!retval) {
+ ret = -EINVAL;
+ goto out;
+ }
+ ret = opt->set(bond, retval);
+out:
+ if (ret)
+ bond_opt_error_interpret(bond, opt, ret, val);
+
+ return ret;
+}
+
+/**
+ * bond_opt_tryset_rtnl - try to acquire rtnl and call __bond_opt_set
+ * @bond: target bond device
+ * @option: option to set
+ * @buf: value to set it to
+ *
+ * This function tries to acquire RTNL without blocking and if successful
+ * calls __bond_opt_set. It is mainly used for sysfs option manipulation.
+ */
+int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf)
+{
+ struct bond_opt_value optval;
+ int ret;
+
+ if (!rtnl_trylock())
+ return restart_syscall();
+ bond_opt_initstr(&optval, buf);
+ ret = __bond_opt_set(bond, option, &optval);
+ rtnl_unlock();
+
+ return ret;
+}
+
+/**
+ * bond_opt_get - get a pointer to an option
+ * @option: option for which to return a pointer
+ *
+ * This function checks if option is valid and if so returns a pointer
+ * to its entry in the bond_opts[] option array.
+ */
+const struct bond_option *bond_opt_get(unsigned int option)
+{
+ if (!BOND_OPT_VALID(option))
+ return NULL;
+
+ return &bond_opts[option];
+}
+
+int bond_option_mode_set(struct bonding *bond, const struct bond_opt_value *newval)
+{
+ if (!bond_mode_uses_arp(newval->value) && bond->params.arp_interval) {
+ pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
+ bond->dev->name, newval->string);
+ /* disable arp monitoring */
+ bond->params.arp_interval = 0;
+ /* set miimon to default value */
+ bond->params.miimon = BOND_DEFAULT_MIIMON;
+ pr_info("%s: Setting MII monitoring interval to %d\n",
+ bond->dev->name, bond->params.miimon);
+ }
+
+ /* don't cache arp_validate between modes */
+ bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
+ bond->params.mode = newval->value;
+
+ return 0;
+}
+
+static struct net_device *__bond_option_active_slave_get(struct bonding *bond,
+ struct slave *slave)
+{
+ return bond_uses_primary(bond) && slave ? slave->dev : NULL;
+}
+
+struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond)
+{
+ struct slave *slave = rcu_dereference(bond->curr_active_slave);
+
+ return __bond_option_active_slave_get(bond, slave);
+}
+
+struct net_device *bond_option_active_slave_get(struct bonding *bond)
+{
+ return __bond_option_active_slave_get(bond, bond->curr_active_slave);
+}
+
+static int bond_option_active_slave_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ char ifname[IFNAMSIZ] = { 0, };
+ struct net_device *slave_dev;
+ int ret = 0;
+
+ sscanf(newval->string, "%15s", ifname); /* IFNAMSIZ */
+ if (!strlen(ifname) || newval->string[0] == '\n') {
+ slave_dev = NULL;
+ } else {
+ slave_dev = __dev_get_by_name(dev_net(bond->dev), ifname);
+ if (!slave_dev)
+ return -ENODEV;
+ }
+
+ if (slave_dev) {
+ if (!netif_is_bond_slave(slave_dev)) {
+ pr_err("Device %s is not bonding slave\n",
+ slave_dev->name);
+ return -EINVAL;
+ }
+
+ if (bond->dev != netdev_master_upper_dev_get(slave_dev)) {
+ pr_err("%s: Device %s is not our slave\n",
+ bond->dev->name, slave_dev->name);
+ return -EINVAL;
+ }
+ }
+
+ block_netpoll_tx();
+ write_lock_bh(&bond->curr_slave_lock);
+
+ /* check to see if we are clearing active */
+ if (!slave_dev) {
+ pr_info("%s: Clearing current active slave\n", bond->dev->name);
+ RCU_INIT_POINTER(bond->curr_active_slave, NULL);
+ bond_select_active_slave(bond);
+ } else {
+ struct slave *old_active = bond->curr_active_slave;
+ struct slave *new_active = bond_slave_get_rtnl(slave_dev);
+
+ BUG_ON(!new_active);
+
+ if (new_active == old_active) {
+ /* do nothing */
+ pr_info("%s: %s is already the current active slave\n",
+ bond->dev->name, new_active->dev->name);
+ } else {
+ if (old_active && (new_active->link == BOND_LINK_UP) &&
+ bond_slave_is_up(new_active)) {
+ pr_info("%s: Setting %s as active slave\n",
+ bond->dev->name, new_active->dev->name);
+ bond_change_active_slave(bond, new_active);
+ } else {
+ pr_err("%s: Could not set %s as active slave; either %s is down or the link is down\n",
+ bond->dev->name, new_active->dev->name,
+ new_active->dev->name);
+ ret = -EINVAL;
+ }
+ }
+ }
+
+ write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
+
+ return ret;
+}
+
+/* There are two tricky bits here. First, if MII monitoring is activated, then
+ * we must disable ARP monitoring. Second, if the timer isn't running, we must
+ * start it.
+ */
+static int bond_option_miimon_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting MII monitoring interval to %llu\n",
+ bond->dev->name, newval->value);
+ bond->params.miimon = newval->value;
+ if (bond->params.updelay)
+ pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value\n",
+ bond->dev->name,
+ bond->params.updelay * bond->params.miimon);
+ if (bond->params.downdelay)
+ pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value\n",
+ bond->dev->name,
+ bond->params.downdelay * bond->params.miimon);
+ if (newval->value && bond->params.arp_interval) {
+ pr_info("%s: MII monitoring cannot be used with ARP monitoring - disabling ARP monitoring...\n",
+ bond->dev->name);
+ bond->params.arp_interval = 0;
+ if (bond->params.arp_validate)
+ bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
+ }
+ if (bond->dev->flags & IFF_UP) {
+ /* If the interface is up, we may need to fire off
+ * the MII timer. If the interface is down, the
+ * timer will get fired off when the open function
+ * is called.
+ */
+ if (!newval->value) {
+ cancel_delayed_work_sync(&bond->mii_work);
+ } else {
+ cancel_delayed_work_sync(&bond->arp_work);
+ queue_delayed_work(bond->wq, &bond->mii_work, 0);
+ }
+ }
+
+ return 0;
+}
+
+/* Set up and down delays. These must be multiples of the
+ * MII monitoring value, and are stored internally as the multiplier.
+ * Thus, we must translate to MS for the real world.
+ */
+static int bond_option_updelay_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ int value = newval->value;
+
+ if (!bond->params.miimon) {
+ pr_err("%s: Unable to set up delay as MII monitoring is disabled\n",
+ bond->dev->name);
+ return -EPERM;
+ }
+ if ((value % bond->params.miimon) != 0) {
+ pr_warn("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
+ bond->dev->name, value,
+ bond->params.miimon,
+ (value / bond->params.miimon) *
+ bond->params.miimon);
+ }
+ bond->params.updelay = value / bond->params.miimon;
+ pr_info("%s: Setting up delay to %d\n",
+ bond->dev->name, bond->params.updelay * bond->params.miimon);
+
+ return 0;
+}
+
+static int bond_option_downdelay_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ int value = newval->value;
+
+ if (!bond->params.miimon) {
+ pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
+ bond->dev->name);
+ return -EPERM;
+ }
+ if ((value % bond->params.miimon) != 0) {
+ pr_warn("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
+ bond->dev->name, value,
+ bond->params.miimon,
+ (value / bond->params.miimon) *
+ bond->params.miimon);
+ }
+ bond->params.downdelay = value / bond->params.miimon;
+ pr_info("%s: Setting down delay to %d\n",
+ bond->dev->name, bond->params.downdelay * bond->params.miimon);
+
+ return 0;
+}
+
+static int bond_option_use_carrier_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting use_carrier to %llu\n",
+ bond->dev->name, newval->value);
+ bond->params.use_carrier = newval->value;
+
+ return 0;
+}
+
+/* There are two tricky bits here. First, if ARP monitoring is activated, then
+ * we must disable MII monitoring. Second, if the ARP timer isn't running,
+ * we must start it.
+ */
+static int bond_option_arp_interval_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting ARP monitoring interval to %llu\n",
+ bond->dev->name, newval->value);
+ bond->params.arp_interval = newval->value;
+ if (newval->value) {
+ if (bond->params.miimon) {
+ pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring\n",
+ bond->dev->name, bond->dev->name);
+ bond->params.miimon = 0;
+ }
+ if (!bond->params.arp_targets[0])
+ pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified\n",
+ bond->dev->name);
+ }
+ if (bond->dev->flags & IFF_UP) {
+ /* If the interface is up, we may need to fire off
+ * the ARP timer. If the interface is down, the
+ * timer will get fired off when the open function
+ * is called.
+ */
+ if (!newval->value) {
+ if (bond->params.arp_validate)
+ bond->recv_probe = NULL;
+ cancel_delayed_work_sync(&bond->arp_work);
+ } else {
+ /* arp_validate can be set only in active-backup mode */
+ bond->recv_probe = bond_arp_rcv;
+ cancel_delayed_work_sync(&bond->mii_work);
+ queue_delayed_work(bond->wq, &bond->arp_work, 0);
+ }
+ }
+
+ return 0;
+}
+
+static void _bond_options_arp_ip_target_set(struct bonding *bond, int slot,
+ __be32 target,
+ unsigned long last_rx)
+{
+ __be32 *targets = bond->params.arp_targets;
+ struct list_head *iter;
+ struct slave *slave;
+
+ if (slot >= 0 && slot < BOND_MAX_ARP_TARGETS) {
+ bond_for_each_slave(bond, slave, iter)
+ slave->target_last_arp_rx[slot] = last_rx;
+ targets[slot] = target;
+ }
+}
+
+static int _bond_option_arp_ip_target_add(struct bonding *bond, __be32 target)
+{
+ __be32 *targets = bond->params.arp_targets;
+ int ind;
+
+ if (!bond_is_ip_target_ok(target)) {
+ pr_err("%s: invalid ARP target %pI4 specified for addition\n",
+ bond->dev->name, &target);
+ return -EINVAL;
+ }
+
+ if (bond_get_targets_ip(targets, target) != -1) { /* dup */
+ pr_err("%s: ARP target %pI4 is already present\n",
+ bond->dev->name, &target);
+ return -EINVAL;
+ }
+
+ ind = bond_get_targets_ip(targets, 0); /* first free slot */
+ if (ind == -1) {
+ pr_err("%s: ARP target table is full!\n", bond->dev->name);
+ return -EINVAL;
+ }
+
+ pr_info("%s: Adding ARP target %pI4\n", bond->dev->name, &target);
+
+ _bond_options_arp_ip_target_set(bond, ind, target, jiffies);
+
+ return 0;
+}
+
+static int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target)
+{
+ int ret;
+
+ /* not to race with bond_arp_rcv */
+ write_lock_bh(&bond->lock);
+ ret = _bond_option_arp_ip_target_add(bond, target);
+ write_unlock_bh(&bond->lock);
+
+ return ret;
+}
+
+static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target)
+{
+ __be32 *targets = bond->params.arp_targets;
+ struct list_head *iter;
+ struct slave *slave;
+ unsigned long *targets_rx;
+ int ind, i;
+
+ if (!bond_is_ip_target_ok(target)) {
+ pr_err("%s: invalid ARP target %pI4 specified for removal\n",
+ bond->dev->name, &target);
+ return -EINVAL;
+ }
+
+ ind = bond_get_targets_ip(targets, target);
+ if (ind == -1) {
+ pr_err("%s: unable to remove nonexistent ARP target %pI4\n",
+ bond->dev->name, &target);
+ return -EINVAL;
+ }
+
+ if (ind == 0 && !targets[1] && bond->params.arp_interval)
+ pr_warn("%s: Removing last arp target with arp_interval on\n",
+ bond->dev->name);
+
+ pr_info("%s: Removing ARP target %pI4\n", bond->dev->name, &target);
+
+ /* not to race with bond_arp_rcv */
+ write_lock_bh(&bond->lock);
+
+ bond_for_each_slave(bond, slave, iter) {
+ targets_rx = slave->target_last_arp_rx;
+ for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
+ targets_rx[i] = targets_rx[i+1];
+ targets_rx[i] = 0;
+ }
+ for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
+ targets[i] = targets[i+1];
+ targets[i] = 0;
+
+ write_unlock_bh(&bond->lock);
+
+ return 0;
+}
+
+void bond_option_arp_ip_targets_clear(struct bonding *bond)
+{
+ int i;
+
+ /* not to race with bond_arp_rcv */
+ write_lock_bh(&bond->lock);
+ for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
+ _bond_options_arp_ip_target_set(bond, i, 0, 0);
+ write_unlock_bh(&bond->lock);
+}
+
+static int bond_option_arp_ip_targets_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ int ret = -EPERM;
+ __be32 target;
+
+ if (newval->string) {
+ if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) {
+ pr_err("%s: invalid ARP target %pI4 specified\n",
+ bond->dev->name, &target);
+ return ret;
+ }
+ if (newval->string[0] == '+')
+ ret = bond_option_arp_ip_target_add(bond, target);
+ else if (newval->string[0] == '-')
+ ret = bond_option_arp_ip_target_rem(bond, target);
+ else
+ pr_err("no command found in arp_ip_targets file for bond %s - use +<addr> or -<addr>\n",
+ bond->dev->name);
+ } else {
+ target = newval->value;
+ ret = bond_option_arp_ip_target_add(bond, target);
+ }
+
+ return ret;
+}
+
+static int bond_option_arp_validate_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting arp_validate to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+
+ if (bond->dev->flags & IFF_UP) {
+ if (!newval->value)
+ bond->recv_probe = NULL;
+ else if (bond->params.arp_interval)
+ bond->recv_probe = bond_arp_rcv;
+ }
+ bond->params.arp_validate = newval->value;
+
+ return 0;
+}
+
+static int bond_option_arp_all_targets_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting arp_all_targets to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+ bond->params.arp_all_targets = newval->value;
+
+ return 0;
+}
+
+static int bond_option_primary_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ char *p, *primary = newval->string;
+ struct list_head *iter;
+ struct slave *slave;
+
+ block_netpoll_tx();
+ read_lock(&bond->lock);
+ write_lock_bh(&bond->curr_slave_lock);
+
+ p = strchr(primary, '\n');
+ if (p)
+ *p = '\0';
+ /* check to see if we are clearing primary */
+ if (!strlen(primary)) {
+ pr_info("%s: Setting primary slave to None\n", bond->dev->name);
+ bond->primary_slave = NULL;
+ memset(bond->params.primary, 0, sizeof(bond->params.primary));
+ bond_select_active_slave(bond);
+ goto out;
+ }
+
+ bond_for_each_slave(bond, slave, iter) {
+ if (strncmp(slave->dev->name, primary, IFNAMSIZ) == 0) {
+ pr_info("%s: Setting %s as primary slave\n",
+ bond->dev->name, slave->dev->name);
+ bond->primary_slave = slave;
+ strcpy(bond->params.primary, slave->dev->name);
+ bond_select_active_slave(bond);
+ goto out;
+ }
+ }
+
+ if (bond->primary_slave) {
+ pr_info("%s: Setting primary slave to None\n", bond->dev->name);
+ bond->primary_slave = NULL;
+ bond_select_active_slave(bond);
+ }
+ strncpy(bond->params.primary, primary, IFNAMSIZ);
+ bond->params.primary[IFNAMSIZ - 1] = 0;
+
+ pr_info("%s: Recording %s as primary, but it has not been enslaved to %s yet\n",
+ bond->dev->name, primary, bond->dev->name);
+
+out:
+ write_unlock_bh(&bond->curr_slave_lock);
+ read_unlock(&bond->lock);
+ unblock_netpoll_tx();
+
+ return 0;
+}
+
+static int bond_option_primary_reselect_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting primary_reselect to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+ bond->params.primary_reselect = newval->value;
+
+ block_netpoll_tx();
+ write_lock_bh(&bond->curr_slave_lock);
+ bond_select_active_slave(bond);
+ write_unlock_bh(&bond->curr_slave_lock);
+ unblock_netpoll_tx();
+
+ return 0;
+}
+
+static int bond_option_fail_over_mac_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting fail_over_mac to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+ bond->params.fail_over_mac = newval->value;
+
+ return 0;
+}
+
+static int bond_option_xmit_hash_policy_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting xmit hash policy to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+ bond->params.xmit_policy = newval->value;
+
+ return 0;
+}
+
+static int bond_option_resend_igmp_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting resend_igmp to %llu\n",
+ bond->dev->name, newval->value);
+ bond->params.resend_igmp = newval->value;
+
+ return 0;
+}
+
+static int bond_option_num_peer_notif_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ bond->params.num_peer_notif = newval->value;
+
+ return 0;
+}
+
+static int bond_option_all_slaves_active_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ struct list_head *iter;
+ struct slave *slave;
+
+ if (newval->value == bond->params.all_slaves_active)
+ return 0;
+ bond->params.all_slaves_active = newval->value;
+ bond_for_each_slave(bond, slave, iter) {
+ if (!bond_is_active_slave(slave)) {
+ if (newval->value)
+ slave->inactive = 0;
+ else
+ slave->inactive = 1;
+ }
+ }
+
+ return 0;
+}
+
+static int bond_option_min_links_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting min links value to %llu\n",
+ bond->dev->name, newval->value);
+ bond->params.min_links = newval->value;
+
+ return 0;
+}
+
+static int bond_option_lp_interval_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ bond->params.lp_interval = newval->value;
+
+ return 0;
+}
+
+static int bond_option_pps_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ bond->params.packets_per_slave = newval->value;
+ if (newval->value > 0) {
+ bond->params.reciprocal_packets_per_slave =
+ reciprocal_value(newval->value);
+ } else {
+ /* reciprocal_packets_per_slave is unused if
+ * packets_per_slave is 0 or 1, just initialize it
+ */
+ bond->params.reciprocal_packets_per_slave =
+ (struct reciprocal_value) { 0 };
+ }
+
+ return 0;
+}
+
+static int bond_option_lacp_rate_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting LACP rate to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+ bond->params.lacp_fast = newval->value;
+ bond_3ad_update_lacp_rate(bond);
+
+ return 0;
+}
+
+static int bond_option_ad_select_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting ad_select to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+ bond->params.ad_select = newval->value;
+
+ return 0;
+}
+
+static int bond_option_queue_id_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ struct slave *slave, *update_slave;
+ struct net_device *sdev;
+ struct list_head *iter;
+ char *delim;
+ int ret = 0;
+ u16 qid;
+
+ /* delim will point to queue id if successful */
+ delim = strchr(newval->string, ':');
+ if (!delim)
+ goto err_no_cmd;
+
+ /* Terminate string that points to device name and bump it
+ * up one, so we can read the queue id there.
+ */
+ *delim = '\0';
+ if (sscanf(++delim, "%hd\n", &qid) != 1)
+ goto err_no_cmd;
+
+ /* Check buffer length, valid ifname and queue id */
+ if (!dev_valid_name(newval->string) ||
+ qid > bond->dev->real_num_tx_queues)
+ goto err_no_cmd;
+
+ /* Get the pointer to that interface if it exists */
+ sdev = __dev_get_by_name(dev_net(bond->dev), newval->string);
+ if (!sdev)
+ goto err_no_cmd;
+
+ /* Search for thes slave and check for duplicate qids */
+ update_slave = NULL;
+ bond_for_each_slave(bond, slave, iter) {
+ if (sdev == slave->dev)
+ /* We don't need to check the matching
+ * slave for dups, since we're overwriting it
+ */
+ update_slave = slave;
+ else if (qid && qid == slave->queue_id) {
+ goto err_no_cmd;
+ }
+ }
+
+ if (!update_slave)
+ goto err_no_cmd;
+
+ /* Actually set the qids for the slave */
+ update_slave->queue_id = qid;
+
+out:
+ return ret;
+
+err_no_cmd:
+ pr_info("invalid input for queue_id set for %s\n", bond->dev->name);
+ ret = -EPERM;
+ goto out;
+
+}
+
+static int bond_option_slaves_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ char command[IFNAMSIZ + 1] = { 0, };
+ struct net_device *dev;
+ char *ifname;
+ int ret;
+
+ sscanf(newval->string, "%16s", command); /* IFNAMSIZ*/
+ ifname = command + 1;
+ if ((strlen(command) <= 1) ||
+ !dev_valid_name(ifname))
+ goto err_no_cmd;
+
+ dev = __dev_get_by_name(dev_net(bond->dev), ifname);
+ if (!dev) {
+ pr_info("%s: interface %s does not exist!\n",
+ bond->dev->name, ifname);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ switch (command[0]) {
+ case '+':
+ pr_info("%s: Adding slave %s\n", bond->dev->name, dev->name);
+ ret = bond_enslave(bond->dev, dev);
+ break;
+
+ case '-':
+ pr_info("%s: Removing slave %s\n", bond->dev->name, dev->name);
+ ret = bond_release(bond->dev, dev);
+ break;
+
+ default:
+ goto err_no_cmd;
+ }
+
+out:
+ return ret;
+
+err_no_cmd:
+ pr_err("no command found in slaves file for bond %s - use +ifname or -ifname\n",
+ bond->dev->name);
+ ret = -EPERM;
+ goto out;
+}
+
+static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
+ const struct bond_opt_value *newval)
+{
+ pr_info("%s: Setting dynamic-lb to %s (%llu)\n",
+ bond->dev->name, newval->string, newval->value);
+ bond->params.tlb_dynamic_lb = newval->value;
+
+ return 0;
+}
diff --git a/drivers/net/bonding/bond_options.h b/drivers/net/bonding/bond_options.h
new file mode 100644
index 00000000000..17ded5b2917
--- /dev/null
+++ b/drivers/net/bonding/bond_options.h
@@ -0,0 +1,130 @@
+/*
+ * drivers/net/bond/bond_options.h - bonding options
+ * Copyright (c) 2013 Nikolay Aleksandrov <nikolay@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _BOND_OPTIONS_H
+#define _BOND_OPTIONS_H
+
+#define BOND_OPT_MAX_NAMELEN 32
+#define BOND_OPT_VALID(opt) ((opt) < BOND_OPT_LAST)
+#define BOND_MODE_ALL_EX(x) (~(x))
+
+/* Option flags:
+ * BOND_OPTFLAG_NOSLAVES - check if the bond device is empty before setting
+ * BOND_OPTFLAG_IFDOWN - check if the bond device is down before setting
+ * BOND_OPTFLAG_RAWVAL - the option parses the value itself
+ */
+enum {
+ BOND_OPTFLAG_NOSLAVES = BIT(0),
+ BOND_OPTFLAG_IFDOWN = BIT(1),
+ BOND_OPTFLAG_RAWVAL = BIT(2)
+};
+
+/* Value type flags:
+ * BOND_VALFLAG_DEFAULT - mark the value as default
+ * BOND_VALFLAG_(MIN|MAX) - mark the value as min/max
+ */
+enum {
+ BOND_VALFLAG_DEFAULT = BIT(0),
+ BOND_VALFLAG_MIN = BIT(1),
+ BOND_VALFLAG_MAX = BIT(2)
+};
+
+/* Option IDs, their bit positions correspond to their IDs */
+enum {
+ BOND_OPT_MODE,
+ BOND_OPT_PACKETS_PER_SLAVE,
+ BOND_OPT_XMIT_HASH,
+ BOND_OPT_ARP_VALIDATE,
+ BOND_OPT_ARP_ALL_TARGETS,
+ BOND_OPT_FAIL_OVER_MAC,
+ BOND_OPT_ARP_INTERVAL,
+ BOND_OPT_ARP_TARGETS,
+ BOND_OPT_DOWNDELAY,
+ BOND_OPT_UPDELAY,
+ BOND_OPT_LACP_RATE,
+ BOND_OPT_MINLINKS,
+ BOND_OPT_AD_SELECT,
+ BOND_OPT_NUM_PEER_NOTIF,
+ BOND_OPT_MIIMON,
+ BOND_OPT_PRIMARY,
+ BOND_OPT_PRIMARY_RESELECT,
+ BOND_OPT_USE_CARRIER,
+ BOND_OPT_ACTIVE_SLAVE,
+ BOND_OPT_QUEUE_ID,
+ BOND_OPT_ALL_SLAVES_ACTIVE,
+ BOND_OPT_RESEND_IGMP,
+ BOND_OPT_LP_INTERVAL,
+ BOND_OPT_SLAVES,
+ BOND_OPT_TLB_DYNAMIC_LB,
+ BOND_OPT_LAST
+};
+
+/* This structure is used for storing option values and for passing option
+ * values when changing an option. The logic when used as an arg is as follows:
+ * - if string != NULL -> parse it, if the opt is RAW type then return it, else
+ * return the parse result
+ * - if string == NULL -> parse value
+ */
+struct bond_opt_value {
+ char *string;
+ u64 value;
+ u32 flags;
+};
+
+struct bonding;
+
+struct bond_option {
+ int id;
+ const char *name;
+ const char *desc;
+ u32 flags;
+
+ /* unsuppmodes is used to denote modes in which the option isn't
+ * supported.
+ */
+ unsigned long unsuppmodes;
+ /* supported values which this option can have, can be a subset of
+ * BOND_OPTVAL_RANGE's value range
+ */
+ const struct bond_opt_value *values;
+
+ int (*set)(struct bonding *bond, const struct bond_opt_value *val);
+};
+
+int __bond_opt_set(struct bonding *bond, unsigned int option,
+ struct bond_opt_value *val);
+int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf);
+
+const struct bond_opt_value *bond_opt_parse(const struct bond_option *opt,
+ struct bond_opt_value *val);
+const struct bond_option *bond_opt_get(unsigned int option);
+const struct bond_option *bond_opt_get_by_name(const char *name);
+const struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val);
+
+/* This helper is used to initialize a bond_opt_value structure for parameter
+ * passing. There should be either a valid string or value, but not both.
+ * When value is ULLONG_MAX then string will be used.
+ */
+static inline void __bond_opt_init(struct bond_opt_value *optval,
+ char *string, u64 value)
+{
+ memset(optval, 0, sizeof(*optval));
+ optval->value = ULLONG_MAX;
+ if (value == ULLONG_MAX)
+ optval->string = string;
+ else
+ optval->value = value;
+}
+#define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value)
+#define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX)
+
+void bond_option_arp_ip_targets_clear(struct bonding *bond);
+
+#endif /* _BOND_OPTIONS_H */
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
new file mode 100644
index 00000000000..b215b479bb3
--- /dev/null
+++ b/drivers/net/bonding/bond_procfs.c
@@ -0,0 +1,296 @@
+#include <linux/proc_fs.h>
+#include <linux/export.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+#include "bonding.h"
+
+
+static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
+ __acquires(&bond->lock)
+{
+ struct bonding *bond = seq->private;
+ struct list_head *iter;
+ struct slave *slave;
+ loff_t off = 0;
+
+ /* make sure the bond won't be taken away */
+ rcu_read_lock();
+ read_lock(&bond->lock);
+
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+
+ bond_for_each_slave(bond, slave, iter)
+ if (++off == *pos)
+ return slave;
+
+ return NULL;
+}
+
+static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct bonding *bond = seq->private;
+ struct list_head *iter;
+ struct slave *slave;
+ bool found = false;
+
+ ++*pos;
+ if (v == SEQ_START_TOKEN)
+ return bond_first_slave(bond);
+
+ if (bond_is_last_slave(bond, v))
+ return NULL;
+
+ bond_for_each_slave(bond, slave, iter) {
+ if (found)
+ return slave;
+ if (slave == v)
+ found = true;
+ }
+
+ return NULL;
+}
+
+static void bond_info_seq_stop(struct seq_file *seq, void *v)
+ __releases(&bond->lock)
+ __releases(RCU)
+{
+ struct bonding *bond = seq->private;
+
+ read_unlock(&bond->lock);
+ rcu_read_unlock();
+}
+
+static void bond_info_show_master(struct seq_file *seq)
+{
+ struct bonding *bond = seq->private;
+ const struct bond_opt_value *optval;
+ struct slave *curr;
+ int i;
+
+ curr = rcu_dereference(bond->curr_active_slave);
+
+ seq_printf(seq, "Bonding Mode: %s",
+ bond_mode_name(BOND_MODE(bond)));
+
+ if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
+ bond->params.fail_over_mac) {
+ optval = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC,
+ bond->params.fail_over_mac);
+ seq_printf(seq, " (fail_over_mac %s)", optval->string);
+ }
+
+ seq_printf(seq, "\n");
+
+ if (BOND_MODE(bond) == BOND_MODE_XOR ||
+ BOND_MODE(bond) == BOND_MODE_8023AD) {
+ optval = bond_opt_get_val(BOND_OPT_XMIT_HASH,
+ bond->params.xmit_policy);
+ seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
+ optval->string, bond->params.xmit_policy);
+ }
+
+ if (bond_uses_primary(bond)) {
+ seq_printf(seq, "Primary Slave: %s",
+ (bond->primary_slave) ?
+ bond->primary_slave->dev->name : "None");
+ if (bond->primary_slave) {
+ optval = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
+ bond->params.primary_reselect);
+ seq_printf(seq, " (primary_reselect %s)",
+ optval->string);
+ }
+
+ seq_printf(seq, "\nCurrently Active Slave: %s\n",
+ (curr) ? curr->dev->name : "None");
+ }
+
+ seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
+ "up" : "down");
+ seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
+ seq_printf(seq, "Up Delay (ms): %d\n",
+ bond->params.updelay * bond->params.miimon);
+ seq_printf(seq, "Down Delay (ms): %d\n",
+ bond->params.downdelay * bond->params.miimon);
+
+
+ /* ARP information */
+ if (bond->params.arp_interval > 0) {
+ int printed = 0;
+ seq_printf(seq, "ARP Polling Interval (ms): %d\n",
+ bond->params.arp_interval);
+
+ seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
+
+ for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+ if (!bond->params.arp_targets[i])
+ break;
+ if (printed)
+ seq_printf(seq, ",");
+ seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
+ printed = 1;
+ }
+ seq_printf(seq, "\n");
+ }
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+ struct ad_info ad_info;
+
+ seq_puts(seq, "\n802.3ad info\n");
+ seq_printf(seq, "LACP rate: %s\n",
+ (bond->params.lacp_fast) ? "fast" : "slow");
+ seq_printf(seq, "Min links: %d\n", bond->params.min_links);
+ optval = bond_opt_get_val(BOND_OPT_AD_SELECT,
+ bond->params.ad_select);
+ seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
+ optval->string);
+
+ if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
+ seq_printf(seq, "bond %s has no active aggregator\n",
+ bond->dev->name);
+ } else {
+ seq_printf(seq, "Active Aggregator Info:\n");
+
+ seq_printf(seq, "\tAggregator ID: %d\n",
+ ad_info.aggregator_id);
+ seq_printf(seq, "\tNumber of ports: %d\n",
+ ad_info.ports);
+ seq_printf(seq, "\tActor Key: %d\n",
+ ad_info.actor_key);
+ seq_printf(seq, "\tPartner Key: %d\n",
+ ad_info.partner_key);
+ seq_printf(seq, "\tPartner Mac Address: %pM\n",
+ ad_info.partner_system);
+ }
+ }
+}
+
+static void bond_info_show_slave(struct seq_file *seq,
+ const struct slave *slave)
+{
+ struct bonding *bond = seq->private;
+
+ seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
+ seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link));
+ if (slave->speed == SPEED_UNKNOWN)
+ seq_printf(seq, "Speed: %s\n", "Unknown");
+ else
+ seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
+
+ if (slave->duplex == DUPLEX_UNKNOWN)
+ seq_printf(seq, "Duplex: %s\n", "Unknown");
+ else
+ seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
+
+ seq_printf(seq, "Link Failure Count: %u\n",
+ slave->link_failure_count);
+
+ seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
+
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+ const struct aggregator *agg
+ = SLAVE_AD_INFO(slave)->port.aggregator;
+
+ if (agg)
+ seq_printf(seq, "Aggregator ID: %d\n",
+ agg->aggregator_identifier);
+ else
+ seq_puts(seq, "Aggregator ID: N/A\n");
+ }
+ seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
+}
+
+static int bond_info_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq, "%s\n", bond_version);
+ bond_info_show_master(seq);
+ } else
+ bond_info_show_slave(seq, v);
+
+ return 0;
+}
+
+static const struct seq_operations bond_info_seq_ops = {
+ .start = bond_info_seq_start,
+ .next = bond_info_seq_next,
+ .stop = bond_info_seq_stop,
+ .show = bond_info_seq_show,
+};
+
+static int bond_info_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int res;
+
+ res = seq_open(file, &bond_info_seq_ops);
+ if (!res) {
+ /* recover the pointer buried in proc_dir_entry data */
+ seq = file->private_data;
+ seq->private = PDE_DATA(inode);
+ }
+
+ return res;
+}
+
+static const struct file_operations bond_info_fops = {
+ .owner = THIS_MODULE,
+ .open = bond_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+void bond_create_proc_entry(struct bonding *bond)
+{
+ struct net_device *bond_dev = bond->dev;
+ struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
+
+ if (bn->proc_dir) {
+ bond->proc_entry = proc_create_data(bond_dev->name,
+ S_IRUGO, bn->proc_dir,
+ &bond_info_fops, bond);
+ if (bond->proc_entry == NULL)
+ pr_warn("Warning: Cannot create /proc/net/%s/%s\n",
+ DRV_NAME, bond_dev->name);
+ else
+ memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
+ }
+}
+
+void bond_remove_proc_entry(struct bonding *bond)
+{
+ struct net_device *bond_dev = bond->dev;
+ struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
+
+ if (bn->proc_dir && bond->proc_entry) {
+ remove_proc_entry(bond->proc_file_name, bn->proc_dir);
+ memset(bond->proc_file_name, 0, IFNAMSIZ);
+ bond->proc_entry = NULL;
+ }
+}
+
+/* Create the bonding directory under /proc/net, if doesn't exist yet.
+ * Caller must hold rtnl_lock.
+ */
+void __net_init bond_create_proc_dir(struct bond_net *bn)
+{
+ if (!bn->proc_dir) {
+ bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
+ if (!bn->proc_dir)
+ pr_warn("Warning: Cannot create /proc/net/%s\n",
+ DRV_NAME);
+ }
+}
+
+/* Destroy the bonding directory under /proc/net, if empty.
+ * Caller must hold rtnl_lock.
+ */
+void __net_exit bond_destroy_proc_dir(struct bond_net *bn)
+{
+ if (bn->proc_dir) {
+ remove_proc_entry(DRV_NAME, bn->net->proc_net);
+ bn->proc_dir = NULL;
+ }
+}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 3bdb4738252..daed52f68ce 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1,4 +1,3 @@
-
/*
* Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
*
@@ -13,17 +12,19 @@
* for more details.
*
* You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
-#include <linux/sysdev.h>
+#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -34,54 +35,31 @@
#include <linux/ctype.h>
#include <linux/inet.h>
#include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+#include <linux/nsproxy.h>
-/* #define BONDING_DEBUG 1 */
#include "bonding.h"
-#define to_dev(obj) container_of(obj,struct device,kobj)
-#define to_bond(cd) ((struct bonding *)(to_net_dev(cd)->priv))
-
-/*---------------------------- Declarations -------------------------------*/
-
-
-extern struct list_head bond_dev_list;
-extern struct bond_params bonding_defaults;
-extern struct bond_parm_tbl bond_mode_tbl[];
-extern struct bond_parm_tbl bond_lacp_tbl[];
-extern struct bond_parm_tbl xmit_hashtype_tbl[];
-extern struct bond_parm_tbl arp_validate_tbl[];
-extern struct bond_parm_tbl fail_over_mac_tbl[];
-
-static int expected_refcount = -1;
-/*--------------------------- Data Structures -----------------------------*/
-
-/* Bonding sysfs lock. Why can't we just use the subsystem lock?
- * Because kobject_register tries to acquire the subsystem lock. If
- * we already hold the lock (which we would if the user was creating
- * a new bond through the sysfs interface), we deadlock.
- * This lock is only needed when deleting a bond - we need to make sure
- * that we don't collide with an ongoing ioctl.
- */
-
-struct rw_semaphore bonding_rwsem;
-
-
-
-/*------------------------------ Functions --------------------------------*/
+#define to_dev(obj) container_of(obj, struct device, kobj)
+#define to_bond(cd) ((struct bonding *)(netdev_priv(to_net_dev(cd))))
-/*
- * "show" function for the bond_masters attribute.
+/* "show" function for the bond_masters attribute.
* The class parameter is ignored.
*/
-static ssize_t bonding_show_bonds(struct class *cls, char *buf)
+static ssize_t bonding_show_bonds(struct class *cls,
+ struct class_attribute *attr,
+ char *buf)
{
+ struct bond_net *bn =
+ container_of(attr, struct bond_net, class_attr_bonding_masters);
int res = 0;
struct bonding *bond;
- down_read(&(bonding_rwsem));
+ rtnl_lock();
- list_for_each_entry(bond, &bond_dev_list, bond_list) {
+ list_for_each_entry(bond, &bn->dev_list, bond_list) {
if (res > (PAGE_SIZE - IFNAMSIZ)) {
/* not enough space for another interface name */
if ((PAGE_SIZE - res) > 10)
@@ -93,24 +71,37 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
}
if (res)
buf[res-1] = '\n'; /* eat the leftover space */
- up_read(&(bonding_rwsem));
+
+ rtnl_unlock();
return res;
}
-/*
- * "store" function for the bond_masters attribute. This is what
+static struct net_device *bond_get_by_name(struct bond_net *bn, const char *ifname)
+{
+ struct bonding *bond;
+
+ list_for_each_entry(bond, &bn->dev_list, bond_list) {
+ if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
+ return bond->dev;
+ }
+ return NULL;
+}
+
+/* "store" function for the bond_masters attribute. This is what
* creates and deletes entire bonds.
*
* The class parameter is ignored.
*
*/
-
-static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t count)
+static ssize_t bonding_store_bonds(struct class *cls,
+ struct class_attribute *attr,
+ const char *buffer, size_t count)
{
+ struct bond_net *bn =
+ container_of(attr, struct bond_net, class_attr_bonding_masters);
char command[IFNAMSIZ + 1] = {0, };
char *ifname;
int rv, res = count;
- struct bonding *bond;
sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
ifname = command + 1;
@@ -119,106 +110,83 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
goto err_no_cmd;
if (command[0] == '+') {
- printk(KERN_INFO DRV_NAME
- ": %s is being created...\n", ifname);
- rv = bond_create(ifname, &bonding_defaults);
+ pr_info("%s is being created...\n", ifname);
+ rv = bond_create(bn->net, ifname);
if (rv) {
- printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
+ if (rv == -EEXIST)
+ pr_info("%s already exists\n", ifname);
+ else
+ pr_info("%s creation failed\n", ifname);
res = rv;
}
- goto out;
- }
+ } else if (command[0] == '-') {
+ struct net_device *bond_dev;
- if (command[0] == '-') {
rtnl_lock();
- down_write(&bonding_rwsem);
-
- list_for_each_entry(bond, &bond_dev_list, bond_list)
- if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
- /* check the ref count on the bond's kobject.
- * If it's > expected, then there's a file open,
- * and we have to fail.
- */
- if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
- > expected_refcount){
- printk(KERN_INFO DRV_NAME
- ": Unable remove bond %s due to open references.\n",
- ifname);
- res = -EPERM;
- goto out_unlock;
- }
- printk(KERN_INFO DRV_NAME
- ": %s is being deleted...\n",
- bond->dev->name);
- bond_destroy(bond);
- goto out_unlock;
- }
-
- printk(KERN_ERR DRV_NAME
- ": unable to delete non-existent bond %s\n", ifname);
- res = -ENODEV;
- goto out_unlock;
- }
-
-err_no_cmd:
- printk(KERN_ERR DRV_NAME
- ": no command found in bonding_masters. Use +ifname or -ifname.\n");
- return -EPERM;
-
-out_unlock:
- up_write(&bonding_rwsem);
- rtnl_unlock();
+ bond_dev = bond_get_by_name(bn, ifname);
+ if (bond_dev) {
+ pr_info("%s is being deleted...\n", ifname);
+ unregister_netdevice(bond_dev);
+ } else {
+ pr_err("unable to delete non-existent %s\n", ifname);
+ res = -ENODEV;
+ }
+ rtnl_unlock();
+ } else
+ goto err_no_cmd;
/* Always return either count or an error. If you return 0, you'll
* get called forever, which is bad.
*/
-out:
return res;
+
+err_no_cmd:
+ pr_err("no command found in bonding_masters - use +ifname or -ifname\n");
+ return -EPERM;
}
+
/* class attribute for bond_masters file. This ends up in /sys/class/net */
-static CLASS_ATTR(bonding_masters, S_IWUSR | S_IRUGO,
- bonding_show_bonds, bonding_store_bonds);
+static const struct class_attribute class_attr_bonding_masters = {
+ .attr = {
+ .name = "bonding_masters",
+ .mode = S_IWUSR | S_IRUGO,
+ },
+ .show = bonding_show_bonds,
+ .store = bonding_store_bonds,
+};
-int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave)
+/* Generic "store" method for bonding sysfs option setting */
+static ssize_t bonding_sysfs_store_option(struct device *d,
+ struct device_attribute *attr,
+ const char *buffer, size_t count)
{
- char linkname[IFNAMSIZ+7];
- int ret = 0;
-
- /* first, create a link from the slave back to the master */
- ret = sysfs_create_link(&(slave->dev.kobj), &(master->dev.kobj),
- "master");
- if (ret)
- return ret;
- /* next, create a link from the master to the slave */
- sprintf(linkname,"slave_%s",slave->name);
- ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
- linkname);
- return ret;
-
-}
+ struct bonding *bond = to_bond(d);
+ const struct bond_option *opt;
+ int ret;
-void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave)
-{
- char linkname[IFNAMSIZ+7];
+ opt = bond_opt_get_by_name(attr->attr.name);
+ if (WARN_ON(!opt))
+ return -ENOENT;
+ ret = bond_opt_tryset_rtnl(bond, opt->id, (char *)buffer);
+ if (!ret)
+ ret = count;
- sysfs_remove_link(&(slave->dev.kobj), "master");
- sprintf(linkname,"slave_%s",slave->name);
- sysfs_remove_link(&(master->dev.kobj), linkname);
+ return ret;
}
-
-/*
- * Show the slaves in the current bond.
- */
+/* Show the slaves in the current bond. */
static ssize_t bonding_show_slaves(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct slave *slave;
- int i, res = 0;
struct bonding *bond = to_bond(d);
+ struct list_head *iter;
+ struct slave *slave;
+ int res = 0;
- read_lock(&bond->lock);
- bond_for_each_slave(bond, slave, i) {
+ if (!rtnl_trylock())
+ return restart_syscall();
+
+ bond_for_each_slave(bond, slave, iter) {
if (res > (PAGE_SIZE - IFNAMSIZ)) {
/* not enough space for another interface name */
if ((PAGE_SIZE - res) > 10)
@@ -228,363 +196,95 @@ static ssize_t bonding_show_slaves(struct device *d,
}
res += sprintf(buf + res, "%s ", slave->dev->name);
}
- read_unlock(&bond->lock);
- if (res)
- buf[res-1] = '\n'; /* eat the leftover space */
- return res;
-}
-
-/*
- * Set the slaves in the current bond. The bond interface must be
- * up for this to succeed.
- * This function is largely the same flow as bonding_update_bonds().
- */
-static ssize_t bonding_store_slaves(struct device *d,
- struct device_attribute *attr,
- const char *buffer, size_t count)
-{
- char command[IFNAMSIZ + 1] = { 0, };
- char *ifname;
- int i, res, found, ret = count;
- u32 original_mtu;
- struct slave *slave;
- struct net_device *dev = NULL;
- struct bonding *bond = to_bond(d);
-
- /* Quick sanity check -- is the bond interface up? */
- if (!(bond->dev->flags & IFF_UP)) {
- printk(KERN_WARNING DRV_NAME
- ": %s: doing slave updates when interface is down.\n",
- bond->dev->name);
- }
-
- /* Note: We can't hold bond->lock here, as bond_create grabs it. */
-
- rtnl_lock();
- down_write(&(bonding_rwsem));
- sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
- ifname = command + 1;
- if ((strlen(command) <= 1) ||
- !dev_valid_name(ifname))
- goto err_no_cmd;
-
- if (command[0] == '+') {
-
- /* Got a slave name in ifname. Is it already in the list? */
- found = 0;
- read_lock(&bond->lock);
- bond_for_each_slave(bond, slave, i)
- if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Interface %s is already enslaved!\n",
- bond->dev->name, ifname);
- ret = -EPERM;
- read_unlock(&bond->lock);
- goto out;
- }
-
- read_unlock(&bond->lock);
- printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
- bond->dev->name, ifname);
- dev = dev_get_by_name(&init_net, ifname);
- if (!dev) {
- printk(KERN_INFO DRV_NAME
- ": %s: Interface %s does not exist!\n",
- bond->dev->name, ifname);
- ret = -EPERM;
- goto out;
- }
- else
- dev_put(dev);
-
- if (dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
- ": %s: Error: Unable to enslave %s "
- "because it is already up.\n",
- bond->dev->name, dev->name);
- ret = -EPERM;
- goto out;
- }
- /* If this is the first slave, then we need to set
- the master's hardware address to be the same as the
- slave's. */
- if (!(*((u32 *) & (bond->dev->dev_addr[0])))) {
- memcpy(bond->dev->dev_addr, dev->dev_addr,
- dev->addr_len);
- }
-
- /* Set the slave's MTU to match the bond */
- original_mtu = dev->mtu;
- if (dev->mtu != bond->dev->mtu) {
- if (dev->change_mtu) {
- res = dev->change_mtu(dev,
- bond->dev->mtu);
- if (res) {
- ret = res;
- goto out;
- }
- } else {
- dev->mtu = bond->dev->mtu;
- }
- }
- res = bond_enslave(bond->dev, dev);
- bond_for_each_slave(bond, slave, i)
- if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
- slave->original_mtu = original_mtu;
- if (res) {
- ret = res;
- }
- goto out;
- }
-
- if (command[0] == '-') {
- dev = NULL;
- original_mtu = 0;
- bond_for_each_slave(bond, slave, i)
- if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
- dev = slave->dev;
- original_mtu = slave->original_mtu;
- break;
- }
- if (dev) {
- printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
- bond->dev->name, dev->name);
- res = bond_release(bond->dev, dev);
- if (res) {
- ret = res;
- goto out;
- }
- /* set the slave MTU to the default */
- if (dev->change_mtu) {
- dev->change_mtu(dev, original_mtu);
- } else {
- dev->mtu = original_mtu;
- }
- }
- else {
- printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
- ifname, bond->dev->name);
- ret = -ENODEV;
- }
- goto out;
- }
+ rtnl_unlock();
-err_no_cmd:
- printk(KERN_ERR DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
- ret = -EPERM;
+ if (res)
+ buf[res-1] = '\n'; /* eat the leftover space */
-out:
- up_write(&(bonding_rwsem));
- rtnl_unlock();
- return ret;
+ return res;
}
+static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves,
+ bonding_sysfs_store_option);
-static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
-
-/*
- * Show and set the bonding mode. The bond interface must be down to
- * change the mode.
- */
+/* Show the bonding mode. */
static ssize_t bonding_show_mode(struct device *d,
struct device_attribute *attr, char *buf)
{
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
- return sprintf(buf, "%s %d\n",
- bond_mode_tbl[bond->params.mode].modename,
- bond->params.mode);
-}
+ val = bond_opt_get_val(BOND_OPT_MODE, BOND_MODE(bond));
-static ssize_t bonding_store_mode(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
- if (bond->dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
- ": unable to update mode of %s because interface is up.\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
-
- new_value = bond_parse_parm(buf, bond_mode_tbl);
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Ignoring invalid mode value %.*s.\n",
- bond->dev->name,
- (int)strlen(buf) - 1, buf);
- ret = -EINVAL;
- goto out;
- } else {
- if (bond->params.mode == BOND_MODE_8023AD)
- bond_unset_master_3ad_flags(bond);
-
- if (bond->params.mode == BOND_MODE_ALB)
- bond_unset_master_alb_flags(bond);
-
- bond->params.mode = new_value;
- bond_set_mode_ops(bond, bond->params.mode);
- printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
- bond->dev->name, bond_mode_tbl[new_value].modename, new_value);
- }
-out:
- return ret;
+ return sprintf(buf, "%s %d\n", val->string, BOND_MODE(bond));
}
-static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+ bonding_show_mode, bonding_sysfs_store_option);
-/*
- * Show and set the bonding transmit hash method. The bond interface must be down to
- * change the xmit hash policy.
- */
+/* Show the bonding transmit hash method. */
static ssize_t bonding_show_xmit_hash(struct device *d,
struct device_attribute *attr,
char *buf)
{
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
- return sprintf(buf, "%s %d\n",
- xmit_hashtype_tbl[bond->params.xmit_policy].modename,
- bond->params.xmit_policy);
-}
-
-static ssize_t bonding_store_xmit_hash(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
- if (bond->dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
- "%s: Interface is up. Unable to update xmit policy.\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
+ val = bond_opt_get_val(BOND_OPT_XMIT_HASH, bond->params.xmit_policy);
- new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
- bond->dev->name,
- (int)strlen(buf) - 1, buf);
- ret = -EINVAL;
- goto out;
- } else {
- bond->params.xmit_policy = new_value;
- bond_set_mode_ops(bond, bond->params.mode);
- printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
- bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);
- }
-out:
- return ret;
+ return sprintf(buf, "%s %d\n", val->string, bond->params.xmit_policy);
}
-static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
+static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR,
+ bonding_show_xmit_hash, bonding_sysfs_store_option);
-/*
- * Show and set arp_validate.
- */
+/* Show arp_validate. */
static ssize_t bonding_show_arp_validate(struct device *d,
struct device_attribute *attr,
char *buf)
{
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
- return sprintf(buf, "%s %d\n",
- arp_validate_tbl[bond->params.arp_validate].modename,
- bond->params.arp_validate);
-}
-
-static ssize_t bonding_store_arp_validate(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value;
- struct bonding *bond = to_bond(d);
-
- new_value = bond_parse_parm(buf, arp_validate_tbl);
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Ignoring invalid arp_validate value %s\n",
- bond->dev->name, buf);
- return -EINVAL;
- }
- if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
- printk(KERN_ERR DRV_NAME
- ": %s: arp_validate only supported in active-backup mode.\n",
- bond->dev->name);
- return -EINVAL;
- }
- printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
- bond->dev->name, arp_validate_tbl[new_value].modename,
- new_value);
-
- if (!bond->params.arp_validate && new_value) {
- bond_register_arp(bond);
- } else if (bond->params.arp_validate && !new_value) {
- bond_unregister_arp(bond);
- }
-
- bond->params.arp_validate = new_value;
+ val = bond_opt_get_val(BOND_OPT_ARP_VALIDATE,
+ bond->params.arp_validate);
- return count;
+ return sprintf(buf, "%s %d\n", val->string, bond->params.arp_validate);
}
+static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
+ bonding_sysfs_store_option);
-static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
-
-/*
- * Show and store fail_over_mac. User only allowed to change the
- * value when there are no slaves.
- */
-static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf)
+/* Show arp_all_targets. */
+static ssize_t bonding_show_arp_all_targets(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
+ val = bond_opt_get_val(BOND_OPT_ARP_ALL_TARGETS,
+ bond->params.arp_all_targets);
return sprintf(buf, "%s %d\n",
- fail_over_mac_tbl[bond->params.fail_over_mac].modename,
- bond->params.fail_over_mac);
+ val->string, bond->params.arp_all_targets);
}
+static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
+ bonding_show_arp_all_targets, bonding_sysfs_store_option);
-static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
+/* Show fail_over_mac. */
+static ssize_t bonding_show_fail_over_mac(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
- int new_value;
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
- if (bond->slave_cnt != 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Can't alter fail_over_mac with slaves in bond.\n",
- bond->dev->name);
- return -EPERM;
- }
-
- new_value = bond_parse_parm(buf, fail_over_mac_tbl);
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Ignoring invalid fail_over_mac value %s.\n",
- bond->dev->name, buf);
- return -EINVAL;
- }
-
- bond->params.fail_over_mac = new_value;
- printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
- bond->dev->name, fail_over_mac_tbl[new_value].modename,
- new_value);
+ val = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC,
+ bond->params.fail_over_mac);
- return count;
+ return sprintf(buf, "%s %d\n", val->string, bond->params.fail_over_mac);
}
+static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR,
+ bonding_show_fail_over_mac, bonding_sysfs_store_option);
-static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
-
-/*
- * Show and set the arp timer interval. There are two tricky bits
- * here. First, if ARP monitoring is activated, then we must disable
- * MII monitoring. Second, if the ARP timer isn't running, we must
- * start it.
- */
+/* Show the arp timer interval. */
static ssize_t bonding_show_arp_interval(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -593,184 +293,31 @@ static ssize_t bonding_show_arp_interval(struct device *d,
return sprintf(buf, "%d\n", bond->params.arp_interval);
}
+static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
+ bonding_show_arp_interval, bonding_sysfs_store_option);
-static ssize_t bonding_store_arp_interval(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
- ": %s: no arp_interval value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
- bond->dev->name, new_value, INT_MAX);
- ret = -EINVAL;
- goto out;
- }
-
- printk(KERN_INFO DRV_NAME
- ": %s: Setting ARP monitoring interval to %d.\n",
- bond->dev->name, new_value);
- bond->params.arp_interval = new_value;
- if (bond->params.miimon) {
- printk(KERN_INFO DRV_NAME
- ": %s: ARP monitoring cannot be used with MII monitoring. "
- "%s Disabling MII monitoring.\n",
- bond->dev->name, bond->dev->name);
- bond->params.miimon = 0;
- if (delayed_work_pending(&bond->mii_work)) {
- cancel_delayed_work(&bond->mii_work);
- flush_workqueue(bond->wq);
- }
- }
- if (!bond->params.arp_targets[0]) {
- printk(KERN_INFO DRV_NAME
- ": %s: ARP monitoring has been set up, "
- "but no ARP targets have been specified.\n",
- bond->dev->name);
- }
- if (bond->dev->flags & IFF_UP) {
- /* If the interface is up, we may need to fire off
- * the ARP timer. If the interface is down, the
- * timer will get fired off when the open function
- * is called.
- */
- if (!delayed_work_pending(&bond->arp_work)) {
- if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_activebackup_arp_mon);
- else
- INIT_DELAYED_WORK(&bond->arp_work,
- bond_loadbalance_arp_mon);
-
- queue_delayed_work(bond->wq, &bond->arp_work, 0);
- }
- }
-
-out:
- return ret;
-}
-static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
-
-/*
- * Show and set the arp targets.
- */
+/* Show the arp targets. */
static ssize_t bonding_show_arp_targets(struct device *d,
struct device_attribute *attr,
char *buf)
{
- int i, res = 0;
struct bonding *bond = to_bond(d);
+ int i, res = 0;
for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
if (bond->params.arp_targets[i])
- res += sprintf(buf + res, "%u.%u.%u.%u ",
- NIPQUAD(bond->params.arp_targets[i]));
+ res += sprintf(buf + res, "%pI4 ",
+ &bond->params.arp_targets[i]);
}
if (res)
buf[res-1] = '\n'; /* eat the leftover space */
- return res;
-}
-
-static ssize_t bonding_store_arp_targets(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- __be32 newtarget;
- int i = 0, done = 0, ret = count;
- struct bonding *bond = to_bond(d);
- __be32 *targets;
-
- targets = bond->params.arp_targets;
- newtarget = in_aton(buf + 1);
- /* look for adds */
- if (buf[0] == '+') {
- if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
- printk(KERN_ERR DRV_NAME
- ": %s: invalid ARP target %u.%u.%u.%u specified for addition\n",
- bond->dev->name, NIPQUAD(newtarget));
- ret = -EINVAL;
- goto out;
- }
- /* look for an empty slot to put the target in, and check for dupes */
- for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
- if (targets[i] == newtarget) { /* duplicate */
- printk(KERN_ERR DRV_NAME
- ": %s: ARP target %u.%u.%u.%u is already present\n",
- bond->dev->name, NIPQUAD(newtarget));
- if (done)
- targets[i] = 0;
- ret = -EINVAL;
- goto out;
- }
- if (targets[i] == 0 && !done) {
- printk(KERN_INFO DRV_NAME
- ": %s: adding ARP target %d.%d.%d.%d.\n",
- bond->dev->name, NIPQUAD(newtarget));
- done = 1;
- targets[i] = newtarget;
- }
- }
- if (!done) {
- printk(KERN_ERR DRV_NAME
- ": %s: ARP target table is full!\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- }
- else if (buf[0] == '-') {
- if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
- printk(KERN_ERR DRV_NAME
- ": %s: invalid ARP target %d.%d.%d.%d specified for removal\n",
- bond->dev->name, NIPQUAD(newtarget));
- ret = -EINVAL;
- goto out;
- }
-
- for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
- if (targets[i] == newtarget) {
- printk(KERN_INFO DRV_NAME
- ": %s: removing ARP target %d.%d.%d.%d.\n",
- bond->dev->name, NIPQUAD(newtarget));
- targets[i] = 0;
- done = 1;
- }
- }
- if (!done) {
- printk(KERN_INFO DRV_NAME
- ": %s: unable to remove nonexistent ARP target %d.%d.%d.%d.\n",
- bond->dev->name, NIPQUAD(newtarget));
- ret = -EINVAL;
- goto out;
- }
- }
- else {
- printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
-
-out:
- return ret;
+ return res;
}
-static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
+static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR,
+ bonding_show_arp_targets, bonding_sysfs_store_option);
-/*
- * Show and set the up and down delays. These must be multiples of the
- * MII monitoring value, and are stored internally as the multiplier.
- * Thus, we must translate to MS for the real world.
- */
+/* Show the up and down delays. */
static ssize_t bonding_show_downdelay(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -779,54 +326,8 @@ static ssize_t bonding_show_downdelay(struct device *d,
return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon);
}
-
-static ssize_t bonding_store_downdelay(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
- if (!(bond->params.miimon)) {
- printk(KERN_ERR DRV_NAME
- ": %s: Unable to set down delay as MII monitoring is disabled\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
- ": %s: no down delay value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
- bond->dev->name, new_value, 1, INT_MAX);
- ret = -EINVAL;
- goto out;
- } else {
- if ((new_value % bond->params.miimon) != 0) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: down delay (%d) is not a multiple "
- "of miimon (%d), delay rounded to %d ms\n",
- bond->dev->name, new_value, bond->params.miimon,
- (new_value / bond->params.miimon) *
- bond->params.miimon);
- }
- bond->params.downdelay = new_value / bond->params.miimon;
- printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",
- bond->dev->name, bond->params.downdelay * bond->params.miimon);
-
- }
-
-out:
- return ret;
-}
-static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
+static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
+ bonding_show_downdelay, bonding_sysfs_store_option);
static ssize_t bonding_show_updelay(struct device *d,
struct device_attribute *attr,
@@ -837,156 +338,77 @@ static ssize_t bonding_show_updelay(struct device *d,
return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon);
}
+static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
+ bonding_show_updelay, bonding_sysfs_store_option);
-static ssize_t bonding_store_updelay(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
+/* Show the LACP interval. */
+static ssize_t bonding_show_lacp(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
- int new_value, ret = count;
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
- if (!(bond->params.miimon)) {
- printk(KERN_ERR DRV_NAME
- ": %s: Unable to set up delay as MII monitoring is disabled\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
- ": %s: no up delay value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
- bond->dev->name, new_value, 1, INT_MAX);
- ret = -EINVAL;
- goto out;
- } else {
- if ((new_value % bond->params.miimon) != 0) {
- printk(KERN_WARNING DRV_NAME
- ": %s: Warning: up delay (%d) is not a multiple "
- "of miimon (%d), updelay rounded to %d ms\n",
- bond->dev->name, new_value, bond->params.miimon,
- (new_value / bond->params.miimon) *
- bond->params.miimon);
- }
- bond->params.updelay = new_value / bond->params.miimon;
- printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",
- bond->dev->name, bond->params.updelay * bond->params.miimon);
-
- }
+ val = bond_opt_get_val(BOND_OPT_LACP_RATE, bond->params.lacp_fast);
-out:
- return ret;
+ return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_fast);
}
-static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
+static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
+ bonding_show_lacp, bonding_sysfs_store_option);
-/*
- * Show and set the LACP interval. Interface must be down, and the mode
- * must be set to 802.3ad mode.
- */
-static ssize_t bonding_show_lacp(struct device *d,
- struct device_attribute *attr,
- char *buf)
+static ssize_t bonding_show_min_links(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
struct bonding *bond = to_bond(d);
- return sprintf(buf, "%s %d\n",
- bond_lacp_tbl[bond->params.lacp_fast].modename,
- bond->params.lacp_fast);
+ return sprintf(buf, "%u\n", bond->params.min_links);
}
+static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR,
+ bonding_show_min_links, bonding_sysfs_store_option);
-static ssize_t bonding_store_lacp(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t bonding_show_ad_select(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
- int new_value, ret = count;
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
- if (bond->dev->flags & IFF_UP) {
- printk(KERN_ERR DRV_NAME
- ": %s: Unable to update LACP rate because interface is up.\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
-
- if (bond->params.mode != BOND_MODE_8023AD) {
- printk(KERN_ERR DRV_NAME
- ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
- }
+ val = bond_opt_get_val(BOND_OPT_AD_SELECT, bond->params.ad_select);
- new_value = bond_parse_parm(buf, bond_lacp_tbl);
-
- if ((new_value == 1) || (new_value == 0)) {
- bond->params.lacp_fast = new_value;
- printk(KERN_INFO DRV_NAME
- ": %s: Setting LACP rate to %s (%d).\n",
- bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);
- } else {
- printk(KERN_ERR DRV_NAME
- ": %s: Ignoring invalid LACP rate value %.*s.\n",
- bond->dev->name, (int)strlen(buf) - 1, buf);
- ret = -EINVAL;
- }
-out:
- return ret;
+ return sprintf(buf, "%s %d\n", val->string, bond->params.ad_select);
}
-static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
+static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
+ bonding_show_ad_select, bonding_sysfs_store_option);
-/*
- * Show and set the number of grat ARP to send after a failover event.
- */
-static ssize_t bonding_show_n_grat_arp(struct device *d,
- struct device_attribute *attr,
- char *buf)
+/* Show and set the number of peer notifications to send after a failover event. */
+static ssize_t bonding_show_num_peer_notif(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
struct bonding *bond = to_bond(d);
-
- return sprintf(buf, "%d\n", bond->params.num_grat_arp);
+ return sprintf(buf, "%d\n", bond->params.num_peer_notif);
}
-static ssize_t bonding_store_n_grat_arp(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t bonding_store_num_peer_notif(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- int new_value, ret = count;
struct bonding *bond = to_bond(d);
+ int ret;
+
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_NUM_PEER_NOTIF, (char *)buf);
+ if (!ret)
+ ret = count;
- if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
- ": %s: no num_grat_arp value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- if (new_value < 0 || new_value > 255) {
- printk(KERN_ERR DRV_NAME
- ": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
- bond->dev->name, new_value);
- ret = -EINVAL;
- goto out;
- } else {
- bond->params.num_grat_arp = new_value;
- }
-out:
return ret;
}
-static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, bonding_show_n_grat_arp, bonding_store_n_grat_arp);
-/*
- * Show and set the MII monitor interval. There are two tricky bits
- * here. First, if MII monitoring is activated, then we must disable
- * ARP monitoring. Second, if the timer isn't running, we must
- * start it.
- */
+static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
+ bonding_show_num_peer_notif, bonding_store_num_peer_notif);
+static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
+ bonding_show_num_peer_notif, bonding_store_num_peer_notif);
+
+/* Show the MII monitor interval. */
static ssize_t bonding_show_miimon(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -995,87 +417,10 @@ static ssize_t bonding_show_miimon(struct device *d,
return sprintf(buf, "%d\n", bond->params.miimon);
}
+static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
+ bonding_show_miimon, bonding_sysfs_store_option);
-static ssize_t bonding_store_miimon(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
- ": %s: no miimon value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- if (new_value < 0) {
- printk(KERN_ERR DRV_NAME
- ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
- bond->dev->name, new_value, 1, INT_MAX);
- ret = -EINVAL;
- goto out;
- } else {
- printk(KERN_INFO DRV_NAME
- ": %s: Setting MII monitoring interval to %d.\n",
- bond->dev->name, new_value);
- bond->params.miimon = new_value;
- if(bond->params.updelay)
- printk(KERN_INFO DRV_NAME
- ": %s: Note: Updating updelay (to %d) "
- "since it is a multiple of the miimon value.\n",
- bond->dev->name,
- bond->params.updelay * bond->params.miimon);
- if(bond->params.downdelay)
- printk(KERN_INFO DRV_NAME
- ": %s: Note: Updating downdelay (to %d) "
- "since it is a multiple of the miimon value.\n",
- bond->dev->name,
- bond->params.downdelay * bond->params.miimon);
- if (bond->params.arp_interval) {
- printk(KERN_INFO DRV_NAME
- ": %s: MII monitoring cannot be used with "
- "ARP monitoring. Disabling ARP monitoring...\n",
- bond->dev->name);
- bond->params.arp_interval = 0;
- if (bond->params.arp_validate) {
- bond_unregister_arp(bond);
- bond->params.arp_validate =
- BOND_ARP_VALIDATE_NONE;
- }
- if (delayed_work_pending(&bond->arp_work)) {
- cancel_delayed_work(&bond->arp_work);
- flush_workqueue(bond->wq);
- }
- }
-
- if (bond->dev->flags & IFF_UP) {
- /* If the interface is up, we may need to fire off
- * the MII timer. If the interface is down, the
- * timer will get fired off when the open function
- * is called.
- */
- if (!delayed_work_pending(&bond->mii_work)) {
- INIT_DELAYED_WORK(&bond->mii_work,
- bond_mii_monitor);
- queue_delayed_work(bond->wq,
- &bond->mii_work, 0);
- }
- }
- }
-out:
- return ret;
-}
-static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
-
-/*
- * Show and set the primary slave. The store function is much
- * simpler than bonding_store_slaves function because it only needs to
- * handle one interface name.
- * The bond must be a mode that supports a primary for this be
- * set.
- */
+/* Show the primary slave. */
static ssize_t bonding_show_primary(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -1088,63 +433,27 @@ static ssize_t bonding_show_primary(struct device *d,
return count;
}
+static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
+ bonding_show_primary, bonding_sysfs_store_option);
-static ssize_t bonding_store_primary(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
+/* Show the primary_reselect flag. */
+static ssize_t bonding_show_primary_reselect(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
{
- int i;
- struct slave *slave;
struct bonding *bond = to_bond(d);
+ const struct bond_opt_value *val;
- rtnl_lock();
- read_lock(&bond->lock);
- write_lock_bh(&bond->curr_slave_lock);
-
- if (!USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
- ": %s: Unable to set primary slave; %s is in mode %d\n",
- bond->dev->name, bond->dev->name, bond->params.mode);
- } else {
- bond_for_each_slave(bond, slave, i) {
- if (strnicmp
- (slave->dev->name, buf,
- strlen(slave->dev->name)) == 0) {
- printk(KERN_INFO DRV_NAME
- ": %s: Setting %s as primary slave.\n",
- bond->dev->name, slave->dev->name);
- bond->primary_slave = slave;
- bond_select_active_slave(bond);
- goto out;
- }
- }
-
- /* if we got here, then we didn't match the name of any slave */
+ val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
+ bond->params.primary_reselect);
- if (strlen(buf) == 0 || buf[0] == '\n') {
- printk(KERN_INFO DRV_NAME
- ": %s: Setting primary slave to None.\n",
- bond->dev->name);
- bond->primary_slave = NULL;
- bond_select_active_slave(bond);
- } else {
- printk(KERN_INFO DRV_NAME
- ": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
- bond->dev->name, (int)strlen(buf) - 1, buf);
- }
- }
-out:
- write_unlock_bh(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
- rtnl_unlock();
-
- return count;
+ return sprintf(buf, "%s %d\n",
+ val->string, bond->params.primary_reselect);
}
-static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
+static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
+ bonding_show_primary_reselect, bonding_sysfs_store_option);
-/*
- * Show and set the use_carrier flag.
- */
+/* Show the use_carrier flag. */
static ssize_t bonding_show_carrier(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -1153,158 +462,42 @@ static ssize_t bonding_show_carrier(struct device *d,
return sprintf(buf, "%d\n", bond->params.use_carrier);
}
-
-static ssize_t bonding_store_carrier(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- printk(KERN_ERR DRV_NAME
- ": %s: no use_carrier value specified.\n",
- bond->dev->name);
- ret = -EINVAL;
- goto out;
- }
- if ((new_value == 0) || (new_value == 1)) {
- bond->params.use_carrier = new_value;
- printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n",
- bond->dev->name, new_value);
- } else {
- printk(KERN_INFO DRV_NAME
- ": %s: Ignoring invalid use_carrier value %d.\n",
- bond->dev->name, new_value);
- }
-out:
- return count;
-}
-static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
+static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
+ bonding_show_carrier, bonding_sysfs_store_option);
-/*
- * Show and set currently active_slave.
- */
+/* Show currently active_slave. */
static ssize_t bonding_show_active_slave(struct device *d,
struct device_attribute *attr,
char *buf)
{
- struct slave *curr;
struct bonding *bond = to_bond(d);
+ struct net_device *slave_dev;
int count = 0;
- read_lock(&bond->curr_slave_lock);
- curr = bond->curr_active_slave;
- read_unlock(&bond->curr_slave_lock);
-
- if (USES_PRIMARY(bond->params.mode) && curr)
- count = sprintf(buf, "%s\n", curr->dev->name);
- return count;
-}
-
-static ssize_t bonding_store_active_slave(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int i;
- struct slave *slave;
- struct slave *old_active = NULL;
- struct slave *new_active = NULL;
- struct bonding *bond = to_bond(d);
-
- rtnl_lock();
- read_lock(&bond->lock);
- write_lock_bh(&bond->curr_slave_lock);
-
- if (!USES_PRIMARY(bond->params.mode)) {
- printk(KERN_INFO DRV_NAME
- ": %s: Unable to change active slave; %s is in mode %d\n",
- bond->dev->name, bond->dev->name, bond->params.mode);
- } else {
- bond_for_each_slave(bond, slave, i) {
- if (strnicmp
- (slave->dev->name, buf,
- strlen(slave->dev->name)) == 0) {
- old_active = bond->curr_active_slave;
- new_active = slave;
- if (new_active == old_active) {
- /* do nothing */
- printk(KERN_INFO DRV_NAME
- ": %s: %s is already the current active slave.\n",
- bond->dev->name, slave->dev->name);
- goto out;
- }
- else {
- if ((new_active) &&
- (old_active) &&
- (new_active->link == BOND_LINK_UP) &&
- IS_UP(new_active->dev)) {
- printk(KERN_INFO DRV_NAME
- ": %s: Setting %s as active slave.\n",
- bond->dev->name, slave->dev->name);
- bond_change_active_slave(bond, new_active);
- }
- else {
- printk(KERN_INFO DRV_NAME
- ": %s: Could not set %s as active slave; "
- "either %s is down or the link is down.\n",
- bond->dev->name, slave->dev->name,
- slave->dev->name);
- }
- goto out;
- }
- }
- }
-
- /* if we got here, then we didn't match the name of any slave */
-
- if (strlen(buf) == 0 || buf[0] == '\n') {
- printk(KERN_INFO DRV_NAME
- ": %s: Setting active slave to None.\n",
- bond->dev->name);
- bond->primary_slave = NULL;
- bond_select_active_slave(bond);
- } else {
- printk(KERN_INFO DRV_NAME
- ": %s: Unable to set %.*s as active slave as it is not a slave.\n",
- bond->dev->name, (int)strlen(buf) - 1, buf);
- }
- }
-out:
- write_unlock_bh(&bond->curr_slave_lock);
- read_unlock(&bond->lock);
- rtnl_unlock();
+ rcu_read_lock();
+ slave_dev = bond_option_active_slave_get_rcu(bond);
+ if (slave_dev)
+ count = sprintf(buf, "%s\n", slave_dev->name);
+ rcu_read_unlock();
return count;
-
}
-static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
-
+static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
+ bonding_show_active_slave, bonding_sysfs_store_option);
-/*
- * Show link status of the bond interface.
- */
+/* Show link status of the bond interface. */
static ssize_t bonding_show_mii_status(struct device *d,
struct device_attribute *attr,
char *buf)
{
- struct slave *curr;
struct bonding *bond = to_bond(d);
- read_lock(&bond->curr_slave_lock);
- curr = bond->curr_active_slave;
- read_unlock(&bond->curr_slave_lock);
-
- return sprintf(buf, "%s\n", (curr) ? "up" : "down");
+ return sprintf(buf, "%s\n", bond->curr_active_slave ? "up" : "down");
}
static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
-
-/*
- * Show current 802.3ad aggregator ID.
- */
+/* Show current 802.3ad aggregator ID. */
static ssize_t bonding_show_ad_aggregator(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -1312,9 +505,11 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
int count = 0;
struct bonding *bond = to_bond(d);
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id);
+ count = sprintf(buf, "%d\n",
+ bond_3ad_get_active_agg_info(bond, &ad_info)
+ ? 0 : ad_info.aggregator_id);
}
return count;
@@ -1322,9 +517,7 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
-/*
- * Show number of active 802.3ad ports.
- */
+/* Show number of active 802.3ad ports. */
static ssize_t bonding_show_ad_num_ports(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -1332,9 +525,11 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
int count = 0;
struct bonding *bond = to_bond(d);
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports);
+ count = sprintf(buf, "%d\n",
+ bond_3ad_get_active_agg_info(bond, &ad_info)
+ ? 0 : ad_info.ports);
}
return count;
@@ -1342,9 +537,7 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
-/*
- * Show current 802.3ad actor key.
- */
+/* Show current 802.3ad actor key. */
static ssize_t bonding_show_ad_actor_key(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -1352,9 +545,11 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
int count = 0;
struct bonding *bond = to_bond(d);
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key);
+ count = sprintf(buf, "%d\n",
+ bond_3ad_get_active_agg_info(bond, &ad_info)
+ ? 0 : ad_info.actor_key);
}
return count;
@@ -1362,9 +557,7 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
-/*
- * Show current 802.3ad partner key.
- */
+/* Show current 802.3ad partner key. */
static ssize_t bonding_show_ad_partner_key(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -1372,9 +565,11 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
int count = 0;
struct bonding *bond = to_bond(d);
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
struct ad_info ad_info;
- count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key);
+ count = sprintf(buf, "%d\n",
+ bond_3ad_get_active_agg_info(bond, &ad_info)
+ ? 0 : ad_info.partner_key);
}
return count;
@@ -1382,45 +577,135 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
-/*
- * Show current 802.3ad partner mac.
- */
+/* Show current 802.3ad partner mac. */
static ssize_t bonding_show_ad_partner_mac(struct device *d,
struct device_attribute *attr,
char *buf)
{
int count = 0;
struct bonding *bond = to_bond(d);
- DECLARE_MAC_BUF(mac);
- if (bond->params.mode == BOND_MODE_8023AD) {
+ if (BOND_MODE(bond) == BOND_MODE_8023AD) {
struct ad_info ad_info;
- if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
- count = sprintf(buf,"%s\n",
- print_mac(mac, ad_info.partner_system));
- }
+ if (!bond_3ad_get_active_agg_info(bond, &ad_info))
+ count = sprintf(buf, "%pM\n", ad_info.partner_system);
}
return count;
}
static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
+/* Show the queue_ids of the slaves in the current bond. */
+static ssize_t bonding_show_queue_id(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+ struct list_head *iter;
+ struct slave *slave;
+ int res = 0;
+
+ if (!rtnl_trylock())
+ return restart_syscall();
+
+ bond_for_each_slave(bond, slave, iter) {
+ if (res > (PAGE_SIZE - IFNAMSIZ - 6)) {
+ /* not enough space for another interface_name:queue_id pair */
+ if ((PAGE_SIZE - res) > 10)
+ res = PAGE_SIZE - 10;
+ res += sprintf(buf + res, "++more++ ");
+ break;
+ }
+ res += sprintf(buf + res, "%s:%d ",
+ slave->dev->name, slave->queue_id);
+ }
+ if (res)
+ buf[res-1] = '\n'; /* eat the leftover space */
+
+ rtnl_unlock();
+
+ return res;
+}
+static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
+ bonding_sysfs_store_option);
+/* Show the all_slaves_active flag. */
+static ssize_t bonding_show_slaves_active(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+
+ return sprintf(buf, "%d\n", bond->params.all_slaves_active);
+}
+static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
+ bonding_show_slaves_active, bonding_sysfs_store_option);
+
+/* Show the number of IGMP membership reports to send on link failure */
+static ssize_t bonding_show_resend_igmp(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+
+ return sprintf(buf, "%d\n", bond->params.resend_igmp);
+}
+static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
+ bonding_show_resend_igmp, bonding_sysfs_store_option);
+
+
+static ssize_t bonding_show_lp_interval(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+
+ return sprintf(buf, "%d\n", bond->params.lp_interval);
+}
+static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
+ bonding_show_lp_interval, bonding_sysfs_store_option);
+
+static ssize_t bonding_show_tlb_dynamic_lb(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+ return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb);
+}
+static DEVICE_ATTR(tlb_dynamic_lb, S_IRUGO | S_IWUSR,
+ bonding_show_tlb_dynamic_lb, bonding_sysfs_store_option);
+
+static ssize_t bonding_show_packets_per_slave(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+ unsigned int packets_per_slave = bond->params.packets_per_slave;
+
+ return sprintf(buf, "%u\n", packets_per_slave);
+}
+static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
+ bonding_show_packets_per_slave, bonding_sysfs_store_option);
+
static struct attribute *per_bond_attrs[] = {
&dev_attr_slaves.attr,
&dev_attr_mode.attr,
&dev_attr_fail_over_mac.attr,
&dev_attr_arp_validate.attr,
+ &dev_attr_arp_all_targets.attr,
&dev_attr_arp_interval.attr,
&dev_attr_arp_ip_target.attr,
&dev_attr_downdelay.attr,
&dev_attr_updelay.attr,
&dev_attr_lacp_rate.attr,
+ &dev_attr_ad_select.attr,
&dev_attr_xmit_hash_policy.attr,
&dev_attr_num_grat_arp.attr,
+ &dev_attr_num_unsol_na.attr,
&dev_attr_miimon.attr,
&dev_attr_primary.attr,
+ &dev_attr_primary_reselect.attr,
&dev_attr_use_carrier.attr,
&dev_attr_active_slave.attr,
&dev_attr_mii_status.attr,
@@ -1429,6 +714,13 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_ad_actor_key.attr,
&dev_attr_ad_partner_key.attr,
&dev_attr_ad_partner_mac.attr,
+ &dev_attr_queue_id.attr,
+ &dev_attr_all_slaves_active.attr,
+ &dev_attr_resend_igmp.attr,
+ &dev_attr_min_links.attr,
+ &dev_attr_lp_interval.attr,
+ &dev_attr_packets_per_slave.attr,
+ &dev_attr_tlb_dynamic_lb.attr,
NULL,
};
@@ -1437,17 +729,19 @@ static struct attribute_group bonding_group = {
.attrs = per_bond_attrs,
};
-/*
- * Initialize sysfs. This sets up the bonding_masters file in
+/* Initialize sysfs. This sets up the bonding_masters file in
* /sys/class/net.
*/
-int bond_create_sysfs(void)
+int bond_create_sysfs(struct bond_net *bn)
{
int ret;
- ret = netdev_class_create_file(&class_attr_bonding_masters);
- /*
- * Permit multiple loads of the module by ignoring failures to
+ bn->class_attr_bonding_masters = class_attr_bonding_masters;
+ sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
+
+ ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
+ bn->net);
+ /* Permit multiple loads of the module by ignoring failures to
* create the bonding_masters sysfs file. Bonding devices
* created by second or subsequent loads of the module will
* not be listed in, or controllable by, bonding_masters, but
@@ -1459,51 +753,28 @@ int bond_create_sysfs(void)
*/
if (ret == -EEXIST) {
/* Is someone being kinky and naming a device bonding_master? */
- if (__dev_get_by_name(&init_net,
+ if (__dev_get_by_name(bn->net,
class_attr_bonding_masters.attr.name))
- printk(KERN_ERR
- "network device named %s already exists in sysfs",
+ pr_err("network device named %s already exists in sysfs\n",
class_attr_bonding_masters.attr.name);
+ ret = 0;
}
return ret;
}
-/*
- * Remove /sys/class/net/bonding_masters.
- */
-void bond_destroy_sysfs(void)
+/* Remove /sys/class/net/bonding_masters. */
+void bond_destroy_sysfs(struct bond_net *bn)
{
- netdev_class_remove_file(&class_attr_bonding_masters);
+ netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
}
-/*
- * Initialize sysfs for each bond. This sets up and registers
+/* Initialize sysfs for each bond. This sets up and registers
* the 'bondctl' directory for each individual bond under /sys/class/net.
*/
-int bond_create_sysfs_entry(struct bonding *bond)
-{
- struct net_device *dev = bond->dev;
- int err;
-
- err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
- if (err) {
- printk(KERN_EMERG "eek! didn't create group!\n");
- }
-
- if (expected_refcount < 1)
- expected_refcount = atomic_read(&bond->dev->dev.kobj.kref.refcount);
-
- return err;
-}
-/*
- * Remove sysfs entries for each bond.
- */
-void bond_destroy_sysfs_entry(struct bonding *bond)
+void bond_prepare_sysfs_group(struct bonding *bond)
{
- struct net_device *dev = bond->dev;
-
- sysfs_remove_group(&(dev->dev.kobj), &bonding_group);
+ bond->dev->sysfs_groups[0] = &bonding_group;
}
diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c
new file mode 100644
index 00000000000..198677f58ce
--- /dev/null
+++ b/drivers/net/bonding/bond_sysfs_slave.c
@@ -0,0 +1,144 @@
+/* Sysfs attributes of bond slaves
+ *
+ * Copyright (c) 2014 Scott Feldman <sfeldma@cumulusnetworks.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/capability.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+
+#include "bonding.h"
+
+struct slave_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct slave *, char *);
+};
+
+#define SLAVE_ATTR(_name, _mode, _show) \
+const struct slave_attribute slave_attr_##_name = { \
+ .attr = {.name = __stringify(_name), \
+ .mode = _mode }, \
+ .show = _show, \
+};
+#define SLAVE_ATTR_RO(_name) \
+ SLAVE_ATTR(_name, S_IRUGO, _name##_show)
+
+static ssize_t state_show(struct slave *slave, char *buf)
+{
+ switch (bond_slave_state(slave)) {
+ case BOND_STATE_ACTIVE:
+ return sprintf(buf, "active\n");
+ case BOND_STATE_BACKUP:
+ return sprintf(buf, "backup\n");
+ default:
+ return sprintf(buf, "UNKONWN\n");
+ }
+}
+static SLAVE_ATTR_RO(state);
+
+static ssize_t mii_status_show(struct slave *slave, char *buf)
+{
+ return sprintf(buf, "%s\n", bond_slave_link_status(slave->link));
+}
+static SLAVE_ATTR_RO(mii_status);
+
+static ssize_t link_failure_count_show(struct slave *slave, char *buf)
+{
+ return sprintf(buf, "%d\n", slave->link_failure_count);
+}
+static SLAVE_ATTR_RO(link_failure_count);
+
+static ssize_t perm_hwaddr_show(struct slave *slave, char *buf)
+{
+ return sprintf(buf, "%pM\n", slave->perm_hwaddr);
+}
+static SLAVE_ATTR_RO(perm_hwaddr);
+
+static ssize_t queue_id_show(struct slave *slave, char *buf)
+{
+ return sprintf(buf, "%d\n", slave->queue_id);
+}
+static SLAVE_ATTR_RO(queue_id);
+
+static ssize_t ad_aggregator_id_show(struct slave *slave, char *buf)
+{
+ const struct aggregator *agg;
+
+ if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) {
+ agg = SLAVE_AD_INFO(slave)->port.aggregator;
+ if (agg)
+ return sprintf(buf, "%d\n",
+ agg->aggregator_identifier);
+ }
+
+ return sprintf(buf, "N/A\n");
+}
+static SLAVE_ATTR_RO(ad_aggregator_id);
+
+static const struct slave_attribute *slave_attrs[] = {
+ &slave_attr_state,
+ &slave_attr_mii_status,
+ &slave_attr_link_failure_count,
+ &slave_attr_perm_hwaddr,
+ &slave_attr_queue_id,
+ &slave_attr_ad_aggregator_id,
+ NULL
+};
+
+#define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr)
+#define to_slave(obj) container_of(obj, struct slave, kobj)
+
+static ssize_t slave_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct slave_attribute *slave_attr = to_slave_attr(attr);
+ struct slave *slave = to_slave(kobj);
+
+ return slave_attr->show(slave, buf);
+}
+
+static const struct sysfs_ops slave_sysfs_ops = {
+ .show = slave_show,
+};
+
+static struct kobj_type slave_ktype = {
+#ifdef CONFIG_SYSFS
+ .sysfs_ops = &slave_sysfs_ops,
+#endif
+};
+
+int bond_sysfs_slave_add(struct slave *slave)
+{
+ const struct slave_attribute **a;
+ int err;
+
+ err = kobject_init_and_add(&slave->kobj, &slave_ktype,
+ &(slave->dev->dev.kobj), "bonding_slave");
+ if (err)
+ return err;
+
+ for (a = slave_attrs; *a; ++a) {
+ err = sysfs_create_file(&slave->kobj, &((*a)->attr));
+ if (err) {
+ kobject_del(&slave->kobj);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+void bond_sysfs_slave_del(struct slave *slave)
+{
+ const struct slave_attribute **a;
+
+ for (a = slave_attrs; *a; ++a)
+ sysfs_remove_file(&slave->kobj, &((*a)->attr));
+
+ kobject_del(&slave->kobj);
+}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index fb730ec0396..0b4d9cde0b0 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -18,54 +18,28 @@
#include <linux/timer.h>
#include <linux/proc_fs.h>
#include <linux/if_bonding.h>
-#include <linux/kobject.h>
+#include <linux/cpumask.h>
+#include <linux/in6.h>
+#include <linux/netpoll.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/reciprocal_div.h>
+
#include "bond_3ad.h"
#include "bond_alb.h"
+#include "bond_options.h"
-#define DRV_VERSION "3.3.0"
-#define DRV_RELDATE "June 10, 2008"
+#define DRV_VERSION "3.7.1"
+#define DRV_RELDATE "April 27, 2011"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
-#define BOND_MAX_ARP_TARGETS 16
-
-#ifdef BONDING_DEBUG
-#define dprintk(fmt, args...) \
- printk(KERN_DEBUG \
- DRV_NAME ": %s() %d: " fmt, __FUNCTION__, __LINE__ , ## args )
-#else
-#define dprintk(fmt, args...)
-#endif /* BONDING_DEBUG */
-
-#define IS_UP(dev) \
- ((((dev)->flags & IFF_UP) == IFF_UP) && \
- netif_running(dev) && \
- netif_carrier_ok(dev))
-
-/*
- * Checks whether bond is ready for transmit.
- *
- * Caller must hold bond->lock
- */
-#define BOND_IS_OK(bond) \
- (((bond)->dev->flags & IFF_UP) && \
- netif_running((bond)->dev) && \
- ((bond)->slave_cnt > 0))
-
-/*
- * Checks whether slave is ready for transmit.
- */
-#define SLAVE_IS_OK(slave) \
- (((slave)->dev->flags & IFF_UP) && \
- netif_running((slave)->dev) && \
- ((slave)->link == BOND_LINK_UP) && \
- ((slave)->state == BOND_STATE_ACTIVE))
+#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"
+#define BOND_MAX_VLAN_ENCAP 2
+#define BOND_MAX_ARP_TARGETS 16
-#define USES_PRIMARY(mode) \
- (((mode) == BOND_MODE_ACTIVEBACKUP) || \
- ((mode) == BOND_MODE_TLB) || \
- ((mode) == BOND_MODE_ALB))
+#define BOND_DEFAULT_MIIMON 100
/*
* Less bad way to call ioctl from within the kernel; this needs to be
@@ -80,61 +54,95 @@
set_fs(fs); \
res; })
-/**
- * bond_for_each_slave_from - iterate the slaves list from a starting point
- * @bond: the bond holding this list.
- * @pos: current slave.
- * @cnt: counter for max number of moves
- * @start: starting point.
- *
- * Caller must hold bond->lock
- */
-#define bond_for_each_slave_from(bond, pos, cnt, start) \
- for (cnt = 0, pos = start; \
- cnt < (bond)->slave_cnt; \
- cnt++, pos = (pos)->next)
+#define BOND_MODE(bond) ((bond)->params.mode)
-/**
- * bond_for_each_slave_from_to - iterate the slaves list from start point to stop point
- * @bond: the bond holding this list.
- * @pos: current slave.
- * @cnt: counter for number max of moves
- * @start: start point.
- * @stop: stop point.
- *
- * Caller must hold bond->lock
- */
-#define bond_for_each_slave_from_to(bond, pos, cnt, start, stop) \
- for (cnt = 0, pos = start; \
- ((cnt < (bond)->slave_cnt) && (pos != (stop)->next)); \
- cnt++, pos = (pos)->next)
+/* slave list primitives */
+#define bond_slave_list(bond) (&(bond)->dev->adj_list.lower)
+
+#define bond_has_slaves(bond) !list_empty(bond_slave_list(bond))
+
+/* IMPORTANT: bond_first/last_slave can return NULL in case of an empty list */
+#define bond_first_slave(bond) \
+ (bond_has_slaves(bond) ? \
+ netdev_adjacent_get_private(bond_slave_list(bond)->next) : \
+ NULL)
+#define bond_last_slave(bond) \
+ (bond_has_slaves(bond) ? \
+ netdev_adjacent_get_private(bond_slave_list(bond)->prev) : \
+ NULL)
+
+/* Caller must have rcu_read_lock */
+#define bond_first_slave_rcu(bond) \
+ netdev_lower_get_first_private_rcu(bond->dev)
+
+#define bond_is_first_slave(bond, pos) (pos == bond_first_slave(bond))
+#define bond_is_last_slave(bond, pos) (pos == bond_last_slave(bond))
/**
- * bond_for_each_slave - iterate the slaves list from head
- * @bond: the bond holding this list.
- * @pos: current slave.
- * @cnt: counter for max number of moves
+ * bond_for_each_slave - iterate over all slaves
+ * @bond: the bond holding this list
+ * @pos: current slave
+ * @iter: list_head * iterator
*
* Caller must hold bond->lock
*/
-#define bond_for_each_slave(bond, pos, cnt) \
- bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave)
+#define bond_for_each_slave(bond, pos, iter) \
+ netdev_for_each_lower_private((bond)->dev, pos, iter)
+
+/* Caller must have rcu_read_lock */
+#define bond_for_each_slave_rcu(bond, pos, iter) \
+ netdev_for_each_lower_private_rcu((bond)->dev, pos, iter)
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+extern atomic_t netpoll_block_tx;
+
+static inline void block_netpoll_tx(void)
+{
+ atomic_inc(&netpoll_block_tx);
+}
+static inline void unblock_netpoll_tx(void)
+{
+ atomic_dec(&netpoll_block_tx);
+}
+
+static inline int is_netpoll_tx_blocked(struct net_device *dev)
+{
+ if (unlikely(netpoll_tx_running(dev)))
+ return atomic_read(&netpoll_block_tx);
+ return 0;
+}
+#else
+#define block_netpoll_tx()
+#define unblock_netpoll_tx()
+#define is_netpoll_tx_blocked(dev) (0)
+#endif
struct bond_params {
int mode;
int xmit_policy;
int miimon;
- int num_grat_arp;
+ u8 num_peer_notif;
int arp_interval;
int arp_validate;
+ int arp_all_targets;
int use_carrier;
int fail_over_mac;
int updelay;
int downdelay;
int lacp_fast;
+ unsigned int min_links;
+ int ad_select;
char primary[IFNAMSIZ];
+ int primary_reselect;
__be32 arp_targets[BOND_MAX_ARP_TARGETS];
+ int tx_queues;
+ int all_slaves_active;
+ int resend_igmp;
+ int lp_interval;
+ int packets_per_slave;
+ int tlb_dynamic_lb;
+ struct reciprocal_value reciprocal_packets_per_slave;
};
struct bond_parm_tbl {
@@ -142,32 +150,32 @@ struct bond_parm_tbl {
int mode;
};
-#define BOND_MAX_MODENAME_LEN 20
-
-struct vlan_entry {
- struct list_head vlan_list;
- __be32 vlan_ip;
- unsigned short vlan_id;
-};
-
struct slave {
struct net_device *dev; /* first - useful for panic debug */
- struct slave *next;
- struct slave *prev;
+ struct bonding *bond; /* our master */
int delay;
- unsigned long jiffies;
- unsigned long last_arp_rx;
+ /* all three in jiffies */
+ unsigned long last_link_up;
+ unsigned long last_rx;
+ unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
s8 link; /* one of BOND_LINK_XXXX */
s8 new_link;
- s8 state; /* one of BOND_STATE_XXXX */
- u32 original_flags;
+ u8 backup:1, /* indicates backup slave. Value corresponds with
+ BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
+ inactive:1, /* indicates inactive slave */
+ should_notify:1; /* indicateds whether the state changed */
+ u8 duplex;
u32 original_mtu;
u32 link_failure_count;
- u16 speed;
- u8 duplex;
+ u32 speed;
+ u16 queue_id;
u8 perm_hwaddr[ETH_ALEN];
- struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
+ struct ad_slave_info *ad_info;
struct tlb_slave_info tlb_info;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ struct netpoll *np;
+#endif
+ struct kobject kobj;
};
/*
@@ -186,38 +194,47 @@ struct slave {
*/
struct bonding {
struct net_device *dev; /* first - useful for panic debug */
- struct slave *first_slave;
struct slave *curr_active_slave;
struct slave *current_arp_slave;
struct slave *primary_slave;
+ bool force_primary;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
+ int (*recv_probe)(const struct sk_buff *, struct bonding *,
+ struct slave *);
rwlock_t lock;
rwlock_t curr_slave_lock;
- s8 kill_timers;
- s8 send_grat_arp;
- s8 setup_by_slave;
- struct net_device_stats stats;
+ u8 send_peer_notif;
+ u8 igmp_retrans;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry;
char proc_file_name[IFNAMSIZ];
#endif /* CONFIG_PROC_FS */
struct list_head bond_list;
- struct dev_mc_list *mc_list;
- int (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int);
- __be32 master_ip;
- u16 flags;
- u16 rr_tx_counter;
+ u32 rr_tx_counter;
struct ad_bond_info ad_info;
struct alb_bond_info alb_info;
struct bond_params params;
- struct list_head vlan_list;
- struct vlan_group *vlgrp;
- struct packet_type arp_mon_pt;
struct workqueue_struct *wq;
struct delayed_work mii_work;
struct delayed_work arp_work;
struct delayed_work alb_work;
struct delayed_work ad_work;
+ struct delayed_work mcast_work;
+#ifdef CONFIG_DEBUG_FS
+ /* debugging support via debugfs */
+ struct dentry *debug_dir;
+#endif /* CONFIG_DEBUG_FS */
+};
+
+#define bond_slave_get_rcu(dev) \
+ ((struct slave *) rcu_dereference(dev->rx_handler_data))
+
+#define bond_slave_get_rtnl(dev) \
+ ((struct slave *) rtnl_dereference(dev->rx_handler_data))
+
+struct bond_vlan_tag {
+ __be16 vlan_proto;
+ unsigned short vlan_id;
};
/**
@@ -225,113 +242,382 @@ struct bonding {
*
* Caller must hold bond lock for read
*/
-static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
+static inline struct slave *bond_get_slave_by_dev(struct bonding *bond,
+ struct net_device *slave_dev)
{
- struct slave *slave = NULL;
- int i;
+ return netdev_lower_dev_get_private(bond->dev, slave_dev);
+}
- bond_for_each_slave(bond, slave, i) {
- if (slave->dev == slave_dev) {
- break;
- }
+static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
+{
+ return slave->bond;
+}
+
+static inline bool bond_should_override_tx_queue(struct bonding *bond)
+{
+ return BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP ||
+ BOND_MODE(bond) == BOND_MODE_ROUNDROBIN;
+}
+
+static inline bool bond_is_lb(const struct bonding *bond)
+{
+ return BOND_MODE(bond) == BOND_MODE_TLB ||
+ BOND_MODE(bond) == BOND_MODE_ALB;
+}
+
+static inline bool bond_mode_uses_arp(int mode)
+{
+ return mode != BOND_MODE_8023AD && mode != BOND_MODE_TLB &&
+ mode != BOND_MODE_ALB;
+}
+
+static inline bool bond_mode_uses_primary(int mode)
+{
+ return mode == BOND_MODE_ACTIVEBACKUP || mode == BOND_MODE_TLB ||
+ mode == BOND_MODE_ALB;
+}
+
+static inline bool bond_uses_primary(struct bonding *bond)
+{
+ return bond_mode_uses_primary(BOND_MODE(bond));
+}
+
+static inline bool bond_slave_is_up(struct slave *slave)
+{
+ return netif_running(slave->dev) && netif_carrier_ok(slave->dev);
+}
+
+static inline void bond_set_active_slave(struct slave *slave)
+{
+ if (slave->backup) {
+ slave->backup = 0;
+ rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
}
+}
- return slave;
+static inline void bond_set_backup_slave(struct slave *slave)
+{
+ if (!slave->backup) {
+ slave->backup = 1;
+ rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
+ }
}
-static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
+static inline void bond_set_slave_state(struct slave *slave,
+ int slave_state, bool notify)
+{
+ if (slave->backup == slave_state)
+ return;
+
+ slave->backup = slave_state;
+ if (notify) {
+ rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_ATOMIC);
+ slave->should_notify = 0;
+ } else {
+ if (slave->should_notify)
+ slave->should_notify = 0;
+ else
+ slave->should_notify = 1;
+ }
+}
+
+static inline void bond_slave_state_change(struct bonding *bond)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave(bond, tmp, iter) {
+ if (tmp->link == BOND_LINK_UP)
+ bond_set_active_slave(tmp);
+ else if (tmp->link == BOND_LINK_DOWN)
+ bond_set_backup_slave(tmp);
+ }
+}
+
+static inline void bond_slave_state_notify(struct bonding *bond)
{
- if (!slave || !slave->dev->master) {
- return NULL;
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave(bond, tmp, iter) {
+ if (tmp->should_notify) {
+ rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_ATOMIC);
+ tmp->should_notify = 0;
+ }
}
+}
+
+static inline int bond_slave_state(struct slave *slave)
+{
+ return slave->backup;
+}
- return (struct bonding *)slave->dev->master->priv;
+static inline bool bond_is_active_slave(struct slave *slave)
+{
+ return !bond_slave_state(slave);
+}
+
+static inline bool bond_slave_can_tx(struct slave *slave)
+{
+ return bond_slave_is_up(slave) && slave->link == BOND_LINK_UP &&
+ bond_is_active_slave(slave);
}
+#define BOND_PRI_RESELECT_ALWAYS 0
+#define BOND_PRI_RESELECT_BETTER 1
+#define BOND_PRI_RESELECT_FAILURE 2
+
#define BOND_FOM_NONE 0
#define BOND_FOM_ACTIVE 1
#define BOND_FOM_FOLLOW 2
+#define BOND_ARP_TARGETS_ANY 0
+#define BOND_ARP_TARGETS_ALL 1
+
#define BOND_ARP_VALIDATE_NONE 0
#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
#define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \
BOND_ARP_VALIDATE_BACKUP)
+#define BOND_ARP_FILTER (BOND_ARP_VALIDATE_ALL + 1)
+#define BOND_ARP_FILTER_ACTIVE (BOND_ARP_VALIDATE_ACTIVE | \
+ BOND_ARP_FILTER)
+#define BOND_ARP_FILTER_BACKUP (BOND_ARP_VALIDATE_BACKUP | \
+ BOND_ARP_FILTER)
+
+#define BOND_SLAVE_NOTIFY_NOW true
+#define BOND_SLAVE_NOTIFY_LATER false
static inline int slave_do_arp_validate(struct bonding *bond,
struct slave *slave)
{
- return bond->params.arp_validate & (1 << slave->state);
+ return bond->params.arp_validate & (1 << bond_slave_state(slave));
+}
+
+static inline int slave_do_arp_validate_only(struct bonding *bond)
+{
+ return bond->params.arp_validate & BOND_ARP_FILTER;
+}
+
+static inline int bond_is_ip_target_ok(__be32 addr)
+{
+ return !ipv4_is_lbcast(addr) && !ipv4_is_zeronet(addr);
+}
+
+/* Get the oldest arp which we've received on this slave for bond's
+ * arp_targets.
+ */
+static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
+ struct slave *slave)
+{
+ int i = 1;
+ unsigned long ret = slave->target_last_arp_rx[0];
+
+ for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
+ if (time_before(slave->target_last_arp_rx[i], ret))
+ ret = slave->target_last_arp_rx[i];
+
+ return ret;
}
static inline unsigned long slave_last_rx(struct bonding *bond,
struct slave *slave)
{
- if (slave_do_arp_validate(bond, slave))
- return slave->last_arp_rx;
+ if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
+ return slave_oldest_target_arp_rx(bond, slave);
- return slave->dev->last_rx;
+ return slave->last_rx;
}
-static inline void bond_set_slave_inactive_flags(struct slave *slave)
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static inline void bond_netpoll_send_skb(const struct slave *slave,
+ struct sk_buff *skb)
{
- struct bonding *bond = slave->dev->master->priv;
- if (bond->params.mode != BOND_MODE_TLB &&
- bond->params.mode != BOND_MODE_ALB)
- slave->state = BOND_STATE_BACKUP;
- slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
- if (slave_do_arp_validate(bond, slave))
- slave->dev->priv_flags |= IFF_SLAVE_NEEDARP;
-}
+ struct netpoll *np = slave->np;
-static inline void bond_set_slave_active_flags(struct slave *slave)
+ if (np)
+ netpoll_send_skb(np, skb);
+}
+#else
+static inline void bond_netpoll_send_skb(const struct slave *slave,
+ struct sk_buff *skb)
{
- slave->state = BOND_STATE_ACTIVE;
- slave->dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_SLAVE_NEEDARP);
}
+#endif
-static inline void bond_set_master_3ad_flags(struct bonding *bond)
+static inline void bond_set_slave_inactive_flags(struct slave *slave,
+ bool notify)
{
- bond->dev->priv_flags |= IFF_MASTER_8023AD;
+ if (!bond_is_lb(slave->bond))
+ bond_set_slave_state(slave, BOND_STATE_BACKUP, notify);
+ if (!slave->bond->params.all_slaves_active)
+ slave->inactive = 1;
}
-static inline void bond_unset_master_3ad_flags(struct bonding *bond)
+static inline void bond_set_slave_active_flags(struct slave *slave,
+ bool notify)
{
- bond->dev->priv_flags &= ~IFF_MASTER_8023AD;
+ bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify);
+ slave->inactive = 0;
}
-static inline void bond_set_master_alb_flags(struct bonding *bond)
+static inline bool bond_is_slave_inactive(struct slave *slave)
{
- bond->dev->priv_flags |= IFF_MASTER_ALB;
+ return slave->inactive;
}
-static inline void bond_unset_master_alb_flags(struct bonding *bond)
+static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be32 local)
{
- bond->dev->priv_flags &= ~IFF_MASTER_ALB;
+ struct in_device *in_dev;
+ __be32 addr = 0;
+
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(dev);
+
+ if (in_dev)
+ addr = inet_confirm_addr(dev_net(dev), in_dev, dst, local,
+ RT_SCOPE_HOST);
+ rcu_read_unlock();
+ return addr;
}
-struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
-int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
-int bond_create(char *name, struct bond_params *params);
-void bond_destroy(struct bonding *bond);
-int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
-int bond_create_sysfs(void);
-void bond_destroy_sysfs(void);
-void bond_destroy_sysfs_entry(struct bonding *bond);
-int bond_create_sysfs_entry(struct bonding *bond);
-int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
-void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
+struct bond_net {
+ struct net *net; /* Associated network namespace */
+ struct list_head dev_list;
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *proc_dir;
+#endif
+ struct class_attribute class_attr_bonding_masters;
+};
+
+int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave);
+void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
+int bond_create(struct net *net, const char *name);
+int bond_create_sysfs(struct bond_net *net);
+void bond_destroy_sysfs(struct bond_net *net);
+void bond_prepare_sysfs_group(struct bonding *bond);
+int bond_sysfs_slave_add(struct slave *slave);
+void bond_sysfs_slave_del(struct slave *slave);
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-void bond_mii_monitor(struct work_struct *);
-void bond_loadbalance_arp_mon(struct work_struct *);
-void bond_activebackup_arp_mon(struct work_struct *);
-void bond_set_mode_ops(struct bonding *bond, int mode);
-int bond_parse_parm(const char *mode_arg, struct bond_parm_tbl *tbl);
+u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
-void bond_register_arp(struct bonding *);
-void bond_unregister_arp(struct bonding *);
+void bond_create_debugfs(void);
+void bond_destroy_debugfs(void);
+void bond_debug_register(struct bonding *bond);
+void bond_debug_unregister(struct bonding *bond);
+void bond_debug_reregister(struct bonding *bond);
+const char *bond_mode_name(int mode);
+void bond_setup(struct net_device *bond_dev);
+unsigned int bond_get_num_tx_queues(void);
+int bond_netlink_init(void);
+void bond_netlink_fini(void);
+struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
+struct net_device *bond_option_active_slave_get(struct bonding *bond);
+const char *bond_slave_link_status(s8 link);
+bool bond_verify_device_path(struct net_device *start_dev,
+ struct net_device *end_dev,
+ struct bond_vlan_tag *tags);
-#endif /* _LINUX_BONDING_H */
+#ifdef CONFIG_PROC_FS
+void bond_create_proc_entry(struct bonding *bond);
+void bond_remove_proc_entry(struct bonding *bond);
+void bond_create_proc_dir(struct bond_net *bn);
+void bond_destroy_proc_dir(struct bond_net *bn);
+#else
+static inline void bond_create_proc_entry(struct bonding *bond)
+{
+}
+
+static inline void bond_remove_proc_entry(struct bonding *bond)
+{
+}
+
+static inline void bond_create_proc_dir(struct bond_net *bn)
+{
+}
+
+static inline void bond_destroy_proc_dir(struct bond_net *bn)
+{
+}
+#endif
+
+static inline struct slave *bond_slave_has_mac(struct bonding *bond,
+ const u8 *mac)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave(bond, tmp, iter)
+ if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
+ return tmp;
+
+ return NULL;
+}
+
+/* Caller must hold rcu_read_lock() for read */
+static inline struct slave *bond_slave_has_mac_rcu(struct bonding *bond,
+ const u8 *mac)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+
+ bond_for_each_slave_rcu(bond, tmp, iter)
+ if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
+ return tmp;
+ return NULL;
+}
+
+/* Caller must hold rcu_read_lock() for read */
+static inline bool bond_slave_has_mac_rx(struct bonding *bond, const u8 *mac)
+{
+ struct list_head *iter;
+ struct slave *tmp;
+ struct netdev_hw_addr *ha;
+
+ bond_for_each_slave_rcu(bond, tmp, iter)
+ if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
+ return true;
+
+ if (netdev_uc_empty(bond->dev))
+ return false;
+
+ netdev_for_each_uc_addr(ha, bond->dev)
+ if (ether_addr_equal_64bits(mac, ha->addr))
+ return true;
+
+ return false;
+}
+
+/* Check if the ip is present in arp ip list, or first free slot if ip == 0
+ * Returns -1 if not found, index if found
+ */
+static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
+{
+ int i;
+
+ for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
+ if (targets[i] == ip)
+ return i;
+ else if (targets[i] == 0)
+ break;
+
+ return -1;
+}
+
+/* exported from bond_main.c */
+extern int bond_net_id;
+extern const struct bond_parm_tbl bond_lacp_tbl[];
+extern const struct bond_parm_tbl xmit_hashtype_tbl[];
+extern const struct bond_parm_tbl arp_validate_tbl[];
+extern const struct bond_parm_tbl arp_all_targets_tbl[];
+extern const struct bond_parm_tbl fail_over_mac_tbl[];
+extern const struct bond_parm_tbl pri_reselect_tbl[];
+extern struct bond_parm_tbl ad_select_tbl[];
+
+/* exported from bond_netlink.c */
+extern struct rtnl_link_ops bond_link_ops;
+
+#endif /* _LINUX_BONDING_H */
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
new file mode 100644
index 00000000000..54709808677
--- /dev/null
+++ b/drivers/net/caif/Kconfig
@@ -0,0 +1,56 @@
+#
+# CAIF physical drivers
+#
+
+comment "CAIF transport drivers"
+
+config CAIF_TTY
+ tristate "CAIF TTY transport driver"
+ depends on CAIF && TTY
+ default n
+ ---help---
+ The CAIF TTY transport driver is a Line Discipline (ldisc)
+ identified as N_CAIF. When this ldisc is opened from user space
+ it will redirect the TTY's traffic into the CAIF stack.
+
+config CAIF_SPI_SLAVE
+ tristate "CAIF SPI transport driver for slave interface"
+ depends on CAIF && HAS_DMA
+ default n
+ ---help---
+ The CAIF Link layer SPI Protocol driver for Slave SPI interface.
+ This driver implements a platform driver to accommodate for a
+ platform specific SPI device. A sample CAIF SPI Platform device is
+ provided in Documentation/networking/caif/spi_porting.txt
+
+config CAIF_SPI_SYNC
+ bool "Next command and length in start of frame"
+ depends on CAIF_SPI_SLAVE
+ default n
+ ---help---
+ Putting the next command and length in the start of the frame can
+ help to synchronize to the next transfer in case of over or under-runs.
+ This option also needs to be enabled on the modem.
+
+config CAIF_HSI
+ tristate "CAIF HSI transport driver"
+ depends on CAIF
+ default n
+ ---help---
+ The caif low level driver for CAIF over HSI.
+ Be aware that if you enable this then you also need to
+ enable a low-level HSI driver.
+
+config CAIF_VIRTIO
+ tristate "CAIF virtio transport driver"
+ depends on CAIF && HAS_DMA
+ select VHOST_RING
+ select VIRTIO
+ select GENERIC_ALLOCATOR
+ default n
+ ---help---
+ The caif driver for CAIF over Virtio.
+
+if CAIF_VIRTIO
+source "drivers/vhost/Kconfig"
+endif
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
new file mode 100644
index 00000000000..9bbd45391f6
--- /dev/null
+++ b/drivers/net/caif/Makefile
@@ -0,0 +1,14 @@
+ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
+
+# Serial interface
+obj-$(CONFIG_CAIF_TTY) += caif_serial.o
+
+# SPI slave physical interfaces module
+cfspi_slave-objs := caif_spi.o caif_spi_slave.o
+obj-$(CONFIG_CAIF_SPI_SLAVE) += cfspi_slave.o
+
+# HSI interface
+obj-$(CONFIG_CAIF_HSI) += caif_hsi.o
+
+# Virtio interface
+obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
new file mode 100644
index 00000000000..5e40a8b68cb
--- /dev/null
+++ b/drivers/net/caif/caif_hsi.c
@@ -0,0 +1,1482 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author: Daniel Martensson
+ * Dmitry.Tarnyagin / dmitry.tarnyagin@lockless.no
+ * License terms: GNU General Public License (GPL) version 2.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/if_arp.h>
+#include <linux/timer.h>
+#include <net/rtnetlink.h>
+#include <linux/pkt_sched.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/caif_hsi.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel Martensson");
+MODULE_DESCRIPTION("CAIF HSI driver");
+
+/* Returns the number of padding bytes for alignment. */
+#define PAD_POW2(x, pow) ((((x)&((pow)-1)) == 0) ? 0 :\
+ (((pow)-((x)&((pow)-1)))))
+
+static const struct cfhsi_config hsi_default_config = {
+
+ /* Inactivity timeout on HSI, ms */
+ .inactivity_timeout = HZ,
+
+ /* Aggregation timeout (ms) of zero means no aggregation is done*/
+ .aggregation_timeout = 1,
+
+ /*
+ * HSI link layer flow-control thresholds.
+ * Threshold values for the HSI packet queue. Flow-control will be
+ * asserted when the number of packets exceeds q_high_mark. It will
+ * not be de-asserted before the number of packets drops below
+ * q_low_mark.
+ * Warning: A high threshold value might increase throughput but it
+ * will at the same time prevent channel prioritization and increase
+ * the risk of flooding the modem. The high threshold should be above
+ * the low.
+ */
+ .q_high_mark = 100,
+ .q_low_mark = 50,
+
+ /*
+ * HSI padding options.
+ * Warning: must be a base of 2 (& operation used) and can not be zero !
+ */
+ .head_align = 4,
+ .tail_align = 4,
+};
+
+#define ON 1
+#define OFF 0
+
+static LIST_HEAD(cfhsi_list);
+
+static void cfhsi_inactivity_tout(unsigned long arg)
+{
+ struct cfhsi *cfhsi = (struct cfhsi *)arg;
+
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ /* Schedule power down work queue. */
+ if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ queue_work(cfhsi->wq, &cfhsi->wake_down_work);
+}
+
+static void cfhsi_update_aggregation_stats(struct cfhsi *cfhsi,
+ const struct sk_buff *skb,
+ int direction)
+{
+ struct caif_payload_info *info;
+ int hpad, tpad, len;
+
+ info = (struct caif_payload_info *)&skb->cb;
+ hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
+ tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
+ len = skb->len + hpad + tpad;
+
+ if (direction > 0)
+ cfhsi->aggregation_len += len;
+ else if (direction < 0)
+ cfhsi->aggregation_len -= len;
+}
+
+static bool cfhsi_can_send_aggregate(struct cfhsi *cfhsi)
+{
+ int i;
+
+ if (cfhsi->cfg.aggregation_timeout == 0)
+ return true;
+
+ for (i = 0; i < CFHSI_PRIO_BEBK; ++i) {
+ if (cfhsi->qhead[i].qlen)
+ return true;
+ }
+
+ /* TODO: Use aggregation_len instead */
+ if (cfhsi->qhead[CFHSI_PRIO_BEBK].qlen >= CFHSI_MAX_PKTS)
+ return true;
+
+ return false;
+}
+
+static struct sk_buff *cfhsi_dequeue(struct cfhsi *cfhsi)
+{
+ struct sk_buff *skb;
+ int i;
+
+ for (i = 0; i < CFHSI_PRIO_LAST; ++i) {
+ skb = skb_dequeue(&cfhsi->qhead[i]);
+ if (skb)
+ break;
+ }
+
+ return skb;
+}
+
+static int cfhsi_tx_queue_len(struct cfhsi *cfhsi)
+{
+ int i, len = 0;
+ for (i = 0; i < CFHSI_PRIO_LAST; ++i)
+ len += skb_queue_len(&cfhsi->qhead[i]);
+ return len;
+}
+
+static void cfhsi_abort_tx(struct cfhsi *cfhsi)
+{
+ struct sk_buff *skb;
+
+ for (;;) {
+ spin_lock_bh(&cfhsi->lock);
+ skb = cfhsi_dequeue(cfhsi);
+ if (!skb)
+ break;
+
+ cfhsi->ndev->stats.tx_errors++;
+ cfhsi->ndev->stats.tx_dropped++;
+ cfhsi_update_aggregation_stats(cfhsi, skb, -1);
+ spin_unlock_bh(&cfhsi->lock);
+ kfree_skb(skb);
+ }
+ cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
+ if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ mod_timer(&cfhsi->inactivity_timer,
+ jiffies + cfhsi->cfg.inactivity_timeout);
+ spin_unlock_bh(&cfhsi->lock);
+}
+
+static int cfhsi_flush_fifo(struct cfhsi *cfhsi)
+{
+ char buffer[32]; /* Any reasonable value */
+ size_t fifo_occupancy;
+ int ret;
+
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ do {
+ ret = cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
+ &fifo_occupancy);
+ if (ret) {
+ netdev_warn(cfhsi->ndev,
+ "%s: can't get FIFO occupancy: %d.\n",
+ __func__, ret);
+ break;
+ } else if (!fifo_occupancy)
+ /* No more data, exitting normally */
+ break;
+
+ fifo_occupancy = min(sizeof(buffer), fifo_occupancy);
+ set_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits);
+ ret = cfhsi->ops->cfhsi_rx(buffer, fifo_occupancy,
+ cfhsi->ops);
+ if (ret) {
+ clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits);
+ netdev_warn(cfhsi->ndev,
+ "%s: can't read data: %d.\n",
+ __func__, ret);
+ break;
+ }
+
+ ret = 5 * HZ;
+ ret = wait_event_interruptible_timeout(cfhsi->flush_fifo_wait,
+ !test_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits), ret);
+
+ if (ret < 0) {
+ netdev_warn(cfhsi->ndev,
+ "%s: can't wait for flush complete: %d.\n",
+ __func__, ret);
+ break;
+ } else if (!ret) {
+ ret = -ETIMEDOUT;
+ netdev_warn(cfhsi->ndev,
+ "%s: timeout waiting for flush complete.\n",
+ __func__);
+ break;
+ }
+ } while (1);
+
+ return ret;
+}
+
+static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
+{
+ int nfrms = 0;
+ int pld_len = 0;
+ struct sk_buff *skb;
+ u8 *pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ;
+
+ skb = cfhsi_dequeue(cfhsi);
+ if (!skb)
+ return 0;
+
+ /* Clear offset. */
+ desc->offset = 0;
+
+ /* Check if we can embed a CAIF frame. */
+ if (skb->len < CFHSI_MAX_EMB_FRM_SZ) {
+ struct caif_payload_info *info;
+ int hpad;
+ int tpad;
+
+ /* Calculate needed head alignment and tail alignment. */
+ info = (struct caif_payload_info *)&skb->cb;
+
+ hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
+ tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
+
+ /* Check if frame still fits with added alignment. */
+ if ((skb->len + hpad + tpad) <= CFHSI_MAX_EMB_FRM_SZ) {
+ u8 *pemb = desc->emb_frm;
+ desc->offset = CFHSI_DESC_SHORT_SZ;
+ *pemb = (u8)(hpad - 1);
+ pemb += hpad;
+
+ /* Update network statistics. */
+ spin_lock_bh(&cfhsi->lock);
+ cfhsi->ndev->stats.tx_packets++;
+ cfhsi->ndev->stats.tx_bytes += skb->len;
+ cfhsi_update_aggregation_stats(cfhsi, skb, -1);
+ spin_unlock_bh(&cfhsi->lock);
+
+ /* Copy in embedded CAIF frame. */
+ skb_copy_bits(skb, 0, pemb, skb->len);
+
+ /* Consume the SKB */
+ consume_skb(skb);
+ skb = NULL;
+ }
+ }
+
+ /* Create payload CAIF frames. */
+ pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ;
+ while (nfrms < CFHSI_MAX_PKTS) {
+ struct caif_payload_info *info;
+ int hpad;
+ int tpad;
+
+ if (!skb)
+ skb = cfhsi_dequeue(cfhsi);
+
+ if (!skb)
+ break;
+
+ /* Calculate needed head alignment and tail alignment. */
+ info = (struct caif_payload_info *)&skb->cb;
+
+ hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
+ tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
+
+ /* Fill in CAIF frame length in descriptor. */
+ desc->cffrm_len[nfrms] = hpad + skb->len + tpad;
+
+ /* Fill head padding information. */
+ *pfrm = (u8)(hpad - 1);
+ pfrm += hpad;
+
+ /* Update network statistics. */
+ spin_lock_bh(&cfhsi->lock);
+ cfhsi->ndev->stats.tx_packets++;
+ cfhsi->ndev->stats.tx_bytes += skb->len;
+ cfhsi_update_aggregation_stats(cfhsi, skb, -1);
+ spin_unlock_bh(&cfhsi->lock);
+
+ /* Copy in CAIF frame. */
+ skb_copy_bits(skb, 0, pfrm, skb->len);
+
+ /* Update payload length. */
+ pld_len += desc->cffrm_len[nfrms];
+
+ /* Update frame pointer. */
+ pfrm += skb->len + tpad;
+
+ /* Consume the SKB */
+ consume_skb(skb);
+ skb = NULL;
+
+ /* Update number of frames. */
+ nfrms++;
+ }
+
+ /* Unused length fields should be zero-filled (according to SPEC). */
+ while (nfrms < CFHSI_MAX_PKTS) {
+ desc->cffrm_len[nfrms] = 0x0000;
+ nfrms++;
+ }
+
+ /* Check if we can piggy-back another descriptor. */
+ if (cfhsi_can_send_aggregate(cfhsi))
+ desc->header |= CFHSI_PIGGY_DESC;
+ else
+ desc->header &= ~CFHSI_PIGGY_DESC;
+
+ return CFHSI_DESC_SZ + pld_len;
+}
+
+static void cfhsi_start_tx(struct cfhsi *cfhsi)
+{
+ struct cfhsi_desc *desc = (struct cfhsi_desc *)cfhsi->tx_buf;
+ int len, res;
+
+ netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+
+ do {
+ /* Create HSI frame. */
+ len = cfhsi_tx_frm(desc, cfhsi);
+ if (!len) {
+ spin_lock_bh(&cfhsi->lock);
+ if (unlikely(cfhsi_tx_queue_len(cfhsi))) {
+ spin_unlock_bh(&cfhsi->lock);
+ res = -EAGAIN;
+ continue;
+ }
+ cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
+ /* Start inactivity timer. */
+ mod_timer(&cfhsi->inactivity_timer,
+ jiffies + cfhsi->cfg.inactivity_timeout);
+ spin_unlock_bh(&cfhsi->lock);
+ break;
+ }
+
+ /* Set up new transfer. */
+ res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
+ if (WARN_ON(res < 0))
+ netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
+ __func__, res);
+ } while (res < 0);
+}
+
+static void cfhsi_tx_done(struct cfhsi *cfhsi)
+{
+ netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+
+ /*
+ * Send flow on if flow off has been previously signalled
+ * and number of packets is below low water mark.
+ */
+ spin_lock_bh(&cfhsi->lock);
+ if (cfhsi->flow_off_sent &&
+ cfhsi_tx_queue_len(cfhsi) <= cfhsi->cfg.q_low_mark &&
+ cfhsi->cfdev.flowctrl) {
+
+ cfhsi->flow_off_sent = 0;
+ cfhsi->cfdev.flowctrl(cfhsi->ndev, ON);
+ }
+
+ if (cfhsi_can_send_aggregate(cfhsi)) {
+ spin_unlock_bh(&cfhsi->lock);
+ cfhsi_start_tx(cfhsi);
+ } else {
+ mod_timer(&cfhsi->aggregation_timer,
+ jiffies + cfhsi->cfg.aggregation_timeout);
+ spin_unlock_bh(&cfhsi->lock);
+ }
+
+ return;
+}
+
+static void cfhsi_tx_done_cb(struct cfhsi_cb_ops *cb_ops)
+{
+ struct cfhsi *cfhsi;
+
+ cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+ cfhsi_tx_done(cfhsi);
+}
+
+static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
+{
+ int xfer_sz = 0;
+ int nfrms = 0;
+ u16 *plen = NULL;
+ u8 *pfrm = NULL;
+
+ if ((desc->header & ~CFHSI_PIGGY_DESC) ||
+ (desc->offset > CFHSI_MAX_EMB_FRM_SZ)) {
+ netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n",
+ __func__);
+ return -EPROTO;
+ }
+
+ /* Check for embedded CAIF frame. */
+ if (desc->offset) {
+ struct sk_buff *skb;
+ u8 *dst = NULL;
+ int len = 0;
+ pfrm = ((u8 *)desc) + desc->offset;
+
+ /* Remove offset padding. */
+ pfrm += *pfrm + 1;
+
+ /* Read length of CAIF frame (little endian). */
+ len = *pfrm;
+ len |= ((*(pfrm+1)) << 8) & 0xFF00;
+ len += 2; /* Add FCS fields. */
+
+ /* Sanity check length of CAIF frame. */
+ if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) {
+ netdev_err(cfhsi->ndev, "%s: Invalid length.\n",
+ __func__);
+ return -EPROTO;
+ }
+
+ /* Allocate SKB (OK even in IRQ context). */
+ skb = alloc_skb(len + 1, GFP_ATOMIC);
+ if (!skb) {
+ netdev_err(cfhsi->ndev, "%s: Out of memory !\n",
+ __func__);
+ return -ENOMEM;
+ }
+ caif_assert(skb != NULL);
+
+ dst = skb_put(skb, len);
+ memcpy(dst, pfrm, len);
+
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+ skb->dev = cfhsi->ndev;
+
+ /*
+ * We are in a callback handler and
+ * unfortunately we don't know what context we're
+ * running in.
+ */
+ if (in_interrupt())
+ netif_rx(skb);
+ else
+ netif_rx_ni(skb);
+
+ /* Update network statistics. */
+ cfhsi->ndev->stats.rx_packets++;
+ cfhsi->ndev->stats.rx_bytes += len;
+ }
+
+ /* Calculate transfer length. */
+ plen = desc->cffrm_len;
+ while (nfrms < CFHSI_MAX_PKTS && *plen) {
+ xfer_sz += *plen;
+ plen++;
+ nfrms++;
+ }
+
+ /* Check for piggy-backed descriptor. */
+ if (desc->header & CFHSI_PIGGY_DESC)
+ xfer_sz += CFHSI_DESC_SZ;
+
+ if ((xfer_sz % 4) || (xfer_sz > (CFHSI_BUF_SZ_RX - CFHSI_DESC_SZ))) {
+ netdev_err(cfhsi->ndev,
+ "%s: Invalid payload len: %d, ignored.\n",
+ __func__, xfer_sz);
+ return -EPROTO;
+ }
+ return xfer_sz;
+}
+
+static int cfhsi_rx_desc_len(struct cfhsi_desc *desc)
+{
+ int xfer_sz = 0;
+ int nfrms = 0;
+ u16 *plen;
+
+ if ((desc->header & ~CFHSI_PIGGY_DESC) ||
+ (desc->offset > CFHSI_MAX_EMB_FRM_SZ)) {
+
+ pr_err("Invalid descriptor. %x %x\n", desc->header,
+ desc->offset);
+ return -EPROTO;
+ }
+
+ /* Calculate transfer length. */
+ plen = desc->cffrm_len;
+ while (nfrms < CFHSI_MAX_PKTS && *plen) {
+ xfer_sz += *plen;
+ plen++;
+ nfrms++;
+ }
+
+ if (xfer_sz % 4) {
+ pr_err("Invalid payload len: %d, ignored.\n", xfer_sz);
+ return -EPROTO;
+ }
+ return xfer_sz;
+}
+
+static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
+{
+ int rx_sz = 0;
+ int nfrms = 0;
+ u16 *plen = NULL;
+ u8 *pfrm = NULL;
+
+ /* Sanity check header and offset. */
+ if (WARN_ON((desc->header & ~CFHSI_PIGGY_DESC) ||
+ (desc->offset > CFHSI_MAX_EMB_FRM_SZ))) {
+ netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n",
+ __func__);
+ return -EPROTO;
+ }
+
+ /* Set frame pointer to start of payload. */
+ pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ;
+ plen = desc->cffrm_len;
+
+ /* Skip already processed frames. */
+ while (nfrms < cfhsi->rx_state.nfrms) {
+ pfrm += *plen;
+ rx_sz += *plen;
+ plen++;
+ nfrms++;
+ }
+
+ /* Parse payload. */
+ while (nfrms < CFHSI_MAX_PKTS && *plen) {
+ struct sk_buff *skb;
+ u8 *dst = NULL;
+ u8 *pcffrm = NULL;
+ int len;
+
+ /* CAIF frame starts after head padding. */
+ pcffrm = pfrm + *pfrm + 1;
+
+ /* Read length of CAIF frame (little endian). */
+ len = *pcffrm;
+ len |= ((*(pcffrm + 1)) << 8) & 0xFF00;
+ len += 2; /* Add FCS fields. */
+
+ /* Sanity check length of CAIF frames. */
+ if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) {
+ netdev_err(cfhsi->ndev, "%s: Invalid length.\n",
+ __func__);
+ return -EPROTO;
+ }
+
+ /* Allocate SKB (OK even in IRQ context). */
+ skb = alloc_skb(len + 1, GFP_ATOMIC);
+ if (!skb) {
+ netdev_err(cfhsi->ndev, "%s: Out of memory !\n",
+ __func__);
+ cfhsi->rx_state.nfrms = nfrms;
+ return -ENOMEM;
+ }
+ caif_assert(skb != NULL);
+
+ dst = skb_put(skb, len);
+ memcpy(dst, pcffrm, len);
+
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+ skb->dev = cfhsi->ndev;
+
+ /*
+ * We're called in callback from HSI
+ * and don't know the context we're running in.
+ */
+ if (in_interrupt())
+ netif_rx(skb);
+ else
+ netif_rx_ni(skb);
+
+ /* Update network statistics. */
+ cfhsi->ndev->stats.rx_packets++;
+ cfhsi->ndev->stats.rx_bytes += len;
+
+ pfrm += *plen;
+ rx_sz += *plen;
+ plen++;
+ nfrms++;
+ }
+
+ return rx_sz;
+}
+
+static void cfhsi_rx_done(struct cfhsi *cfhsi)
+{
+ int res;
+ int desc_pld_len = 0, rx_len, rx_state;
+ struct cfhsi_desc *desc = NULL;
+ u8 *rx_ptr, *rx_buf;
+ struct cfhsi_desc *piggy_desc = NULL;
+
+ desc = (struct cfhsi_desc *)cfhsi->rx_buf;
+
+ netdev_dbg(cfhsi->ndev, "%s\n", __func__);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+
+ /* Update inactivity timer if pending. */
+ spin_lock_bh(&cfhsi->lock);
+ mod_timer_pending(&cfhsi->inactivity_timer,
+ jiffies + cfhsi->cfg.inactivity_timeout);
+ spin_unlock_bh(&cfhsi->lock);
+
+ if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
+ desc_pld_len = cfhsi_rx_desc_len(desc);
+
+ if (desc_pld_len < 0)
+ goto out_of_sync;
+
+ rx_buf = cfhsi->rx_buf;
+ rx_len = desc_pld_len;
+ if (desc_pld_len > 0 && (desc->header & CFHSI_PIGGY_DESC))
+ rx_len += CFHSI_DESC_SZ;
+ if (desc_pld_len == 0)
+ rx_buf = cfhsi->rx_flip_buf;
+ } else {
+ rx_buf = cfhsi->rx_flip_buf;
+
+ rx_len = CFHSI_DESC_SZ;
+ if (cfhsi->rx_state.pld_len > 0 &&
+ (desc->header & CFHSI_PIGGY_DESC)) {
+
+ piggy_desc = (struct cfhsi_desc *)
+ (desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ +
+ cfhsi->rx_state.pld_len);
+
+ cfhsi->rx_state.piggy_desc = true;
+
+ /* Extract payload len from piggy-backed descriptor. */
+ desc_pld_len = cfhsi_rx_desc_len(piggy_desc);
+ if (desc_pld_len < 0)
+ goto out_of_sync;
+
+ if (desc_pld_len > 0) {
+ rx_len = desc_pld_len;
+ if (piggy_desc->header & CFHSI_PIGGY_DESC)
+ rx_len += CFHSI_DESC_SZ;
+ }
+
+ /*
+ * Copy needed information from the piggy-backed
+ * descriptor to the descriptor in the start.
+ */
+ memcpy(rx_buf, (u8 *)piggy_desc,
+ CFHSI_DESC_SHORT_SZ);
+ }
+ }
+
+ if (desc_pld_len) {
+ rx_state = CFHSI_RX_STATE_PAYLOAD;
+ rx_ptr = rx_buf + CFHSI_DESC_SZ;
+ } else {
+ rx_state = CFHSI_RX_STATE_DESC;
+ rx_ptr = rx_buf;
+ rx_len = CFHSI_DESC_SZ;
+ }
+
+ /* Initiate next read */
+ if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) {
+ /* Set up new transfer. */
+ netdev_dbg(cfhsi->ndev, "%s: Start RX.\n",
+ __func__);
+
+ res = cfhsi->ops->cfhsi_rx(rx_ptr, rx_len,
+ cfhsi->ops);
+ if (WARN_ON(res < 0)) {
+ netdev_err(cfhsi->ndev, "%s: RX error %d.\n",
+ __func__, res);
+ cfhsi->ndev->stats.rx_errors++;
+ cfhsi->ndev->stats.rx_dropped++;
+ }
+ }
+
+ if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
+ /* Extract payload from descriptor */
+ if (cfhsi_rx_desc(desc, cfhsi) < 0)
+ goto out_of_sync;
+ } else {
+ /* Extract payload */
+ if (cfhsi_rx_pld(desc, cfhsi) < 0)
+ goto out_of_sync;
+ if (piggy_desc) {
+ /* Extract any payload in piggyback descriptor. */
+ if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0)
+ goto out_of_sync;
+ /* Mark no embedded frame after extracting it */
+ piggy_desc->offset = 0;
+ }
+ }
+
+ /* Update state info */
+ memset(&cfhsi->rx_state, 0, sizeof(cfhsi->rx_state));
+ cfhsi->rx_state.state = rx_state;
+ cfhsi->rx_ptr = rx_ptr;
+ cfhsi->rx_len = rx_len;
+ cfhsi->rx_state.pld_len = desc_pld_len;
+ cfhsi->rx_state.piggy_desc = desc->header & CFHSI_PIGGY_DESC;
+
+ if (rx_buf != cfhsi->rx_buf)
+ swap(cfhsi->rx_buf, cfhsi->rx_flip_buf);
+ return;
+
+out_of_sync:
+ netdev_err(cfhsi->ndev, "%s: Out of sync.\n", __func__);
+ print_hex_dump_bytes("--> ", DUMP_PREFIX_NONE,
+ cfhsi->rx_buf, CFHSI_DESC_SZ);
+ schedule_work(&cfhsi->out_of_sync_work);
+}
+
+static void cfhsi_rx_slowpath(unsigned long arg)
+{
+ struct cfhsi *cfhsi = (struct cfhsi *)arg;
+
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ cfhsi_rx_done(cfhsi);
+}
+
+static void cfhsi_rx_done_cb(struct cfhsi_cb_ops *cb_ops)
+{
+ struct cfhsi *cfhsi;
+
+ cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+
+ if (test_and_clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits))
+ wake_up_interruptible(&cfhsi->flush_fifo_wait);
+ else
+ cfhsi_rx_done(cfhsi);
+}
+
+static void cfhsi_wake_up(struct work_struct *work)
+{
+ struct cfhsi *cfhsi = NULL;
+ int res;
+ int len;
+ long ret;
+
+ cfhsi = container_of(work, struct cfhsi, wake_up_work);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+
+ if (unlikely(test_bit(CFHSI_AWAKE, &cfhsi->bits))) {
+ /* It happenes when wakeup is requested by
+ * both ends at the same time. */
+ clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
+ clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
+ return;
+ }
+
+ /* Activate wake line. */
+ cfhsi->ops->cfhsi_wake_up(cfhsi->ops);
+
+ netdev_dbg(cfhsi->ndev, "%s: Start waiting.\n",
+ __func__);
+
+ /* Wait for acknowledge. */
+ ret = CFHSI_WAKE_TOUT;
+ ret = wait_event_interruptible_timeout(cfhsi->wake_up_wait,
+ test_and_clear_bit(CFHSI_WAKE_UP_ACK,
+ &cfhsi->bits), ret);
+ if (unlikely(ret < 0)) {
+ /* Interrupted by signal. */
+ netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n",
+ __func__, ret);
+
+ clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
+ cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
+ return;
+ } else if (!ret) {
+ bool ca_wake = false;
+ size_t fifo_occupancy = 0;
+
+ /* Wakeup timeout */
+ netdev_dbg(cfhsi->ndev, "%s: Timeout.\n",
+ __func__);
+
+ /* Check FIFO to check if modem has sent something. */
+ WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
+ &fifo_occupancy));
+
+ netdev_dbg(cfhsi->ndev, "%s: Bytes in FIFO: %u.\n",
+ __func__, (unsigned) fifo_occupancy);
+
+ /* Check if we misssed the interrupt. */
+ WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops,
+ &ca_wake));
+
+ if (ca_wake) {
+ netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n",
+ __func__);
+
+ /* Clear the CFHSI_WAKE_UP_ACK bit to prevent race. */
+ clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
+
+ /* Continue execution. */
+ goto wake_ack;
+ }
+
+ clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
+ cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
+ return;
+ }
+wake_ack:
+ netdev_dbg(cfhsi->ndev, "%s: Woken.\n",
+ __func__);
+
+ /* Clear power up bit. */
+ set_bit(CFHSI_AWAKE, &cfhsi->bits);
+ clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
+
+ /* Resume read operation. */
+ netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__);
+ res = cfhsi->ops->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->ops);
+
+ if (WARN_ON(res < 0))
+ netdev_err(cfhsi->ndev, "%s: RX err %d.\n", __func__, res);
+
+ /* Clear power up acknowledment. */
+ clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
+
+ spin_lock_bh(&cfhsi->lock);
+
+ /* Resume transmit if queues are not empty. */
+ if (!cfhsi_tx_queue_len(cfhsi)) {
+ netdev_dbg(cfhsi->ndev, "%s: Peer wake, start timer.\n",
+ __func__);
+ /* Start inactivity timer. */
+ mod_timer(&cfhsi->inactivity_timer,
+ jiffies + cfhsi->cfg.inactivity_timeout);
+ spin_unlock_bh(&cfhsi->lock);
+ return;
+ }
+
+ netdev_dbg(cfhsi->ndev, "%s: Host wake.\n",
+ __func__);
+
+ spin_unlock_bh(&cfhsi->lock);
+
+ /* Create HSI frame. */
+ len = cfhsi_tx_frm((struct cfhsi_desc *)cfhsi->tx_buf, cfhsi);
+
+ if (likely(len > 0)) {
+ /* Set up new transfer. */
+ res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
+ if (WARN_ON(res < 0)) {
+ netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
+ __func__, res);
+ cfhsi_abort_tx(cfhsi);
+ }
+ } else {
+ netdev_err(cfhsi->ndev,
+ "%s: Failed to create HSI frame: %d.\n",
+ __func__, len);
+ }
+}
+
+static void cfhsi_wake_down(struct work_struct *work)
+{
+ long ret;
+ struct cfhsi *cfhsi = NULL;
+ size_t fifo_occupancy = 0;
+ int retry = CFHSI_WAKE_TOUT;
+
+ cfhsi = container_of(work, struct cfhsi, wake_down_work);
+ netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+
+ /* Deactivate wake line. */
+ cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
+
+ /* Wait for acknowledge. */
+ ret = CFHSI_WAKE_TOUT;
+ ret = wait_event_interruptible_timeout(cfhsi->wake_down_wait,
+ test_and_clear_bit(CFHSI_WAKE_DOWN_ACK,
+ &cfhsi->bits), ret);
+ if (ret < 0) {
+ /* Interrupted by signal. */
+ netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n",
+ __func__, ret);
+ return;
+ } else if (!ret) {
+ bool ca_wake = true;
+
+ /* Timeout */
+ netdev_err(cfhsi->ndev, "%s: Timeout.\n", __func__);
+
+ /* Check if we misssed the interrupt. */
+ WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops,
+ &ca_wake));
+ if (!ca_wake)
+ netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n",
+ __func__);
+ }
+
+ /* Check FIFO occupancy. */
+ while (retry) {
+ WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
+ &fifo_occupancy));
+
+ if (!fifo_occupancy)
+ break;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ retry--;
+ }
+
+ if (!retry)
+ netdev_err(cfhsi->ndev, "%s: FIFO Timeout.\n", __func__);
+
+ /* Clear AWAKE condition. */
+ clear_bit(CFHSI_AWAKE, &cfhsi->bits);
+
+ /* Cancel pending RX requests. */
+ cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops);
+}
+
+static void cfhsi_out_of_sync(struct work_struct *work)
+{
+ struct cfhsi *cfhsi = NULL;
+
+ cfhsi = container_of(work, struct cfhsi, out_of_sync_work);
+
+ rtnl_lock();
+ dev_close(cfhsi->ndev);
+ rtnl_unlock();
+}
+
+static void cfhsi_wake_up_cb(struct cfhsi_cb_ops *cb_ops)
+{
+ struct cfhsi *cfhsi = NULL;
+
+ cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ set_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
+ wake_up_interruptible(&cfhsi->wake_up_wait);
+
+ if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
+ return;
+
+ /* Schedule wake up work queue if the peer initiates. */
+ if (!test_and_set_bit(CFHSI_WAKE_UP, &cfhsi->bits))
+ queue_work(cfhsi->wq, &cfhsi->wake_up_work);
+}
+
+static void cfhsi_wake_down_cb(struct cfhsi_cb_ops *cb_ops)
+{
+ struct cfhsi *cfhsi = NULL;
+
+ cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ /* Initiating low power is only permitted by the host (us). */
+ set_bit(CFHSI_WAKE_DOWN_ACK, &cfhsi->bits);
+ wake_up_interruptible(&cfhsi->wake_down_wait);
+}
+
+static void cfhsi_aggregation_tout(unsigned long arg)
+{
+ struct cfhsi *cfhsi = (struct cfhsi *)arg;
+
+ netdev_dbg(cfhsi->ndev, "%s.\n",
+ __func__);
+
+ cfhsi_start_tx(cfhsi);
+}
+
+static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct cfhsi *cfhsi = NULL;
+ int start_xfer = 0;
+ int timer_active;
+ int prio;
+
+ if (!dev)
+ return -EINVAL;
+
+ cfhsi = netdev_priv(dev);
+
+ switch (skb->priority) {
+ case TC_PRIO_BESTEFFORT:
+ case TC_PRIO_FILLER:
+ case TC_PRIO_BULK:
+ prio = CFHSI_PRIO_BEBK;
+ break;
+ case TC_PRIO_INTERACTIVE_BULK:
+ prio = CFHSI_PRIO_VI;
+ break;
+ case TC_PRIO_INTERACTIVE:
+ prio = CFHSI_PRIO_VO;
+ break;
+ case TC_PRIO_CONTROL:
+ default:
+ prio = CFHSI_PRIO_CTL;
+ break;
+ }
+
+ spin_lock_bh(&cfhsi->lock);
+
+ /* Update aggregation statistics */
+ cfhsi_update_aggregation_stats(cfhsi, skb, 1);
+
+ /* Queue the SKB */
+ skb_queue_tail(&cfhsi->qhead[prio], skb);
+
+ /* Sanity check; xmit should not be called after unregister_netdev */
+ if (WARN_ON(test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))) {
+ spin_unlock_bh(&cfhsi->lock);
+ cfhsi_abort_tx(cfhsi);
+ return -EINVAL;
+ }
+
+ /* Send flow off if number of packets is above high water mark. */
+ if (!cfhsi->flow_off_sent &&
+ cfhsi_tx_queue_len(cfhsi) > cfhsi->cfg.q_high_mark &&
+ cfhsi->cfdev.flowctrl) {
+ cfhsi->flow_off_sent = 1;
+ cfhsi->cfdev.flowctrl(cfhsi->ndev, OFF);
+ }
+
+ if (cfhsi->tx_state == CFHSI_TX_STATE_IDLE) {
+ cfhsi->tx_state = CFHSI_TX_STATE_XFER;
+ start_xfer = 1;
+ }
+
+ if (!start_xfer) {
+ /* Send aggregate if it is possible */
+ bool aggregate_ready =
+ cfhsi_can_send_aggregate(cfhsi) &&
+ del_timer(&cfhsi->aggregation_timer) > 0;
+ spin_unlock_bh(&cfhsi->lock);
+ if (aggregate_ready)
+ cfhsi_start_tx(cfhsi);
+ return 0;
+ }
+
+ /* Delete inactivity timer if started. */
+ timer_active = del_timer_sync(&cfhsi->inactivity_timer);
+
+ spin_unlock_bh(&cfhsi->lock);
+
+ if (timer_active) {
+ struct cfhsi_desc *desc = (struct cfhsi_desc *)cfhsi->tx_buf;
+ int len;
+ int res;
+
+ /* Create HSI frame. */
+ len = cfhsi_tx_frm(desc, cfhsi);
+ WARN_ON(!len);
+
+ /* Set up new transfer. */
+ res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
+ if (WARN_ON(res < 0)) {
+ netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
+ __func__, res);
+ cfhsi_abort_tx(cfhsi);
+ }
+ } else {
+ /* Schedule wake up work queue if the we initiate. */
+ if (!test_and_set_bit(CFHSI_WAKE_UP, &cfhsi->bits))
+ queue_work(cfhsi->wq, &cfhsi->wake_up_work);
+ }
+
+ return 0;
+}
+
+static const struct net_device_ops cfhsi_netdevops;
+
+static void cfhsi_setup(struct net_device *dev)
+{
+ int i;
+ struct cfhsi *cfhsi = netdev_priv(dev);
+ dev->features = 0;
+ dev->type = ARPHRD_CAIF;
+ dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
+ dev->tx_queue_len = 0;
+ dev->destructor = free_netdev;
+ dev->netdev_ops = &cfhsi_netdevops;
+ for (i = 0; i < CFHSI_PRIO_LAST; ++i)
+ skb_queue_head_init(&cfhsi->qhead[i]);
+ cfhsi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
+ cfhsi->cfdev.use_frag = false;
+ cfhsi->cfdev.use_stx = false;
+ cfhsi->cfdev.use_fcs = false;
+ cfhsi->ndev = dev;
+ cfhsi->cfg = hsi_default_config;
+}
+
+static int cfhsi_open(struct net_device *ndev)
+{
+ struct cfhsi *cfhsi = netdev_priv(ndev);
+ int res;
+
+ clear_bit(CFHSI_SHUTDOWN, &cfhsi->bits);
+
+ /* Initialize state vaiables. */
+ cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
+ cfhsi->rx_state.state = CFHSI_RX_STATE_DESC;
+
+ /* Set flow info */
+ cfhsi->flow_off_sent = 0;
+
+ /*
+ * Allocate a TX buffer with the size of a HSI packet descriptors
+ * and the necessary room for CAIF payload frames.
+ */
+ cfhsi->tx_buf = kzalloc(CFHSI_BUF_SZ_TX, GFP_KERNEL);
+ if (!cfhsi->tx_buf) {
+ res = -ENODEV;
+ goto err_alloc_tx;
+ }
+
+ /*
+ * Allocate a RX buffer with the size of two HSI packet descriptors and
+ * the necessary room for CAIF payload frames.
+ */
+ cfhsi->rx_buf = kzalloc(CFHSI_BUF_SZ_RX, GFP_KERNEL);
+ if (!cfhsi->rx_buf) {
+ res = -ENODEV;
+ goto err_alloc_rx;
+ }
+
+ cfhsi->rx_flip_buf = kzalloc(CFHSI_BUF_SZ_RX, GFP_KERNEL);
+ if (!cfhsi->rx_flip_buf) {
+ res = -ENODEV;
+ goto err_alloc_rx_flip;
+ }
+
+ /* Initialize aggregation timeout */
+ cfhsi->cfg.aggregation_timeout = hsi_default_config.aggregation_timeout;
+
+ /* Initialize recieve vaiables. */
+ cfhsi->rx_ptr = cfhsi->rx_buf;
+ cfhsi->rx_len = CFHSI_DESC_SZ;
+
+ /* Initialize spin locks. */
+ spin_lock_init(&cfhsi->lock);
+
+ /* Set up the driver. */
+ cfhsi->cb_ops.tx_done_cb = cfhsi_tx_done_cb;
+ cfhsi->cb_ops.rx_done_cb = cfhsi_rx_done_cb;
+ cfhsi->cb_ops.wake_up_cb = cfhsi_wake_up_cb;
+ cfhsi->cb_ops.wake_down_cb = cfhsi_wake_down_cb;
+
+ /* Initialize the work queues. */
+ INIT_WORK(&cfhsi->wake_up_work, cfhsi_wake_up);
+ INIT_WORK(&cfhsi->wake_down_work, cfhsi_wake_down);
+ INIT_WORK(&cfhsi->out_of_sync_work, cfhsi_out_of_sync);
+
+ /* Clear all bit fields. */
+ clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
+ clear_bit(CFHSI_WAKE_DOWN_ACK, &cfhsi->bits);
+ clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
+ clear_bit(CFHSI_AWAKE, &cfhsi->bits);
+
+ /* Create work thread. */
+ cfhsi->wq = create_singlethread_workqueue(cfhsi->ndev->name);
+ if (!cfhsi->wq) {
+ netdev_err(cfhsi->ndev, "%s: Failed to create work queue.\n",
+ __func__);
+ res = -ENODEV;
+ goto err_create_wq;
+ }
+
+ /* Initialize wait queues. */
+ init_waitqueue_head(&cfhsi->wake_up_wait);
+ init_waitqueue_head(&cfhsi->wake_down_wait);
+ init_waitqueue_head(&cfhsi->flush_fifo_wait);
+
+ /* Setup the inactivity timer. */
+ init_timer(&cfhsi->inactivity_timer);
+ cfhsi->inactivity_timer.data = (unsigned long)cfhsi;
+ cfhsi->inactivity_timer.function = cfhsi_inactivity_tout;
+ /* Setup the slowpath RX timer. */
+ init_timer(&cfhsi->rx_slowpath_timer);
+ cfhsi->rx_slowpath_timer.data = (unsigned long)cfhsi;
+ cfhsi->rx_slowpath_timer.function = cfhsi_rx_slowpath;
+ /* Setup the aggregation timer. */
+ init_timer(&cfhsi->aggregation_timer);
+ cfhsi->aggregation_timer.data = (unsigned long)cfhsi;
+ cfhsi->aggregation_timer.function = cfhsi_aggregation_tout;
+
+ /* Activate HSI interface. */
+ res = cfhsi->ops->cfhsi_up(cfhsi->ops);
+ if (res) {
+ netdev_err(cfhsi->ndev,
+ "%s: can't activate HSI interface: %d.\n",
+ __func__, res);
+ goto err_activate;
+ }
+
+ /* Flush FIFO */
+ res = cfhsi_flush_fifo(cfhsi);
+ if (res) {
+ netdev_err(cfhsi->ndev, "%s: Can't flush FIFO: %d.\n",
+ __func__, res);
+ goto err_net_reg;
+ }
+ return res;
+
+ err_net_reg:
+ cfhsi->ops->cfhsi_down(cfhsi->ops);
+ err_activate:
+ destroy_workqueue(cfhsi->wq);
+ err_create_wq:
+ kfree(cfhsi->rx_flip_buf);
+ err_alloc_rx_flip:
+ kfree(cfhsi->rx_buf);
+ err_alloc_rx:
+ kfree(cfhsi->tx_buf);
+ err_alloc_tx:
+ return res;
+}
+
+static int cfhsi_close(struct net_device *ndev)
+{
+ struct cfhsi *cfhsi = netdev_priv(ndev);
+ u8 *tx_buf, *rx_buf, *flip_buf;
+
+ /* going to shutdown driver */
+ set_bit(CFHSI_SHUTDOWN, &cfhsi->bits);
+
+ /* Flush workqueue */
+ flush_workqueue(cfhsi->wq);
+
+ /* Delete timers if pending */
+ del_timer_sync(&cfhsi->inactivity_timer);
+ del_timer_sync(&cfhsi->rx_slowpath_timer);
+ del_timer_sync(&cfhsi->aggregation_timer);
+
+ /* Cancel pending RX request (if any) */
+ cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops);
+
+ /* Destroy workqueue */
+ destroy_workqueue(cfhsi->wq);
+
+ /* Store bufferes: will be freed later. */
+ tx_buf = cfhsi->tx_buf;
+ rx_buf = cfhsi->rx_buf;
+ flip_buf = cfhsi->rx_flip_buf;
+ /* Flush transmit queues. */
+ cfhsi_abort_tx(cfhsi);
+
+ /* Deactivate interface */
+ cfhsi->ops->cfhsi_down(cfhsi->ops);
+
+ /* Free buffers. */
+ kfree(tx_buf);
+ kfree(rx_buf);
+ kfree(flip_buf);
+ return 0;
+}
+
+static void cfhsi_uninit(struct net_device *dev)
+{
+ struct cfhsi *cfhsi = netdev_priv(dev);
+ ASSERT_RTNL();
+ symbol_put(cfhsi_get_device);
+ list_del(&cfhsi->list);
+}
+
+static const struct net_device_ops cfhsi_netdevops = {
+ .ndo_uninit = cfhsi_uninit,
+ .ndo_open = cfhsi_open,
+ .ndo_stop = cfhsi_close,
+ .ndo_start_xmit = cfhsi_xmit
+};
+
+static void cfhsi_netlink_parms(struct nlattr *data[], struct cfhsi *cfhsi)
+{
+ int i;
+
+ if (!data) {
+ pr_debug("no params data found\n");
+ return;
+ }
+
+ i = __IFLA_CAIF_HSI_INACTIVITY_TOUT;
+ /*
+ * Inactivity timeout in millisecs. Lowest possible value is 1,
+ * and highest possible is NEXT_TIMER_MAX_DELTA.
+ */
+ if (data[i]) {
+ u32 inactivity_timeout = nla_get_u32(data[i]);
+ /* Pre-calculate inactivity timeout. */
+ cfhsi->cfg.inactivity_timeout = inactivity_timeout * HZ / 1000;
+ if (cfhsi->cfg.inactivity_timeout == 0)
+ cfhsi->cfg.inactivity_timeout = 1;
+ else if (cfhsi->cfg.inactivity_timeout > NEXT_TIMER_MAX_DELTA)
+ cfhsi->cfg.inactivity_timeout = NEXT_TIMER_MAX_DELTA;
+ }
+
+ i = __IFLA_CAIF_HSI_AGGREGATION_TOUT;
+ if (data[i])
+ cfhsi->cfg.aggregation_timeout = nla_get_u32(data[i]);
+
+ i = __IFLA_CAIF_HSI_HEAD_ALIGN;
+ if (data[i])
+ cfhsi->cfg.head_align = nla_get_u32(data[i]);
+
+ i = __IFLA_CAIF_HSI_TAIL_ALIGN;
+ if (data[i])
+ cfhsi->cfg.tail_align = nla_get_u32(data[i]);
+
+ i = __IFLA_CAIF_HSI_QHIGH_WATERMARK;
+ if (data[i])
+ cfhsi->cfg.q_high_mark = nla_get_u32(data[i]);
+
+ i = __IFLA_CAIF_HSI_QLOW_WATERMARK;
+ if (data[i])
+ cfhsi->cfg.q_low_mark = nla_get_u32(data[i]);
+}
+
+static int caif_hsi_changelink(struct net_device *dev, struct nlattr *tb[],
+ struct nlattr *data[])
+{
+ cfhsi_netlink_parms(data, netdev_priv(dev));
+ netdev_state_change(dev);
+ return 0;
+}
+
+static const struct nla_policy caif_hsi_policy[__IFLA_CAIF_HSI_MAX + 1] = {
+ [__IFLA_CAIF_HSI_INACTIVITY_TOUT] = { .type = NLA_U32, .len = 4 },
+ [__IFLA_CAIF_HSI_AGGREGATION_TOUT] = { .type = NLA_U32, .len = 4 },
+ [__IFLA_CAIF_HSI_HEAD_ALIGN] = { .type = NLA_U32, .len = 4 },
+ [__IFLA_CAIF_HSI_TAIL_ALIGN] = { .type = NLA_U32, .len = 4 },
+ [__IFLA_CAIF_HSI_QHIGH_WATERMARK] = { .type = NLA_U32, .len = 4 },
+ [__IFLA_CAIF_HSI_QLOW_WATERMARK] = { .type = NLA_U32, .len = 4 },
+};
+
+static size_t caif_hsi_get_size(const struct net_device *dev)
+{
+ int i;
+ size_t s = 0;
+ for (i = __IFLA_CAIF_HSI_UNSPEC + 1; i < __IFLA_CAIF_HSI_MAX; i++)
+ s += nla_total_size(caif_hsi_policy[i].len);
+ return s;
+}
+
+static int caif_hsi_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct cfhsi *cfhsi = netdev_priv(dev);
+
+ if (nla_put_u32(skb, __IFLA_CAIF_HSI_INACTIVITY_TOUT,
+ cfhsi->cfg.inactivity_timeout) ||
+ nla_put_u32(skb, __IFLA_CAIF_HSI_AGGREGATION_TOUT,
+ cfhsi->cfg.aggregation_timeout) ||
+ nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN,
+ cfhsi->cfg.head_align) ||
+ nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN,
+ cfhsi->cfg.tail_align) ||
+ nla_put_u32(skb, __IFLA_CAIF_HSI_QHIGH_WATERMARK,
+ cfhsi->cfg.q_high_mark) ||
+ nla_put_u32(skb, __IFLA_CAIF_HSI_QLOW_WATERMARK,
+ cfhsi->cfg.q_low_mark))
+ return -EMSGSIZE;
+
+ return 0;
+}
+
+static int caif_hsi_newlink(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ struct cfhsi *cfhsi = NULL;
+ struct cfhsi_ops *(*get_ops)(void);
+
+ ASSERT_RTNL();
+
+ cfhsi = netdev_priv(dev);
+ cfhsi_netlink_parms(data, cfhsi);
+ dev_net_set(cfhsi->ndev, src_net);
+
+ get_ops = symbol_get(cfhsi_get_ops);
+ if (!get_ops) {
+ pr_err("%s: failed to get the cfhsi_ops\n", __func__);
+ return -ENODEV;
+ }
+
+ /* Assign the HSI device. */
+ cfhsi->ops = (*get_ops)();
+ if (!cfhsi->ops) {
+ pr_err("%s: failed to get the cfhsi_ops\n", __func__);
+ goto err;
+ }
+
+ /* Assign the driver to this HSI device. */
+ cfhsi->ops->cb_ops = &cfhsi->cb_ops;
+ if (register_netdevice(dev)) {
+ pr_warn("%s: caif_hsi device registration failed\n", __func__);
+ goto err;
+ }
+ /* Add CAIF HSI device to list. */
+ list_add_tail(&cfhsi->list, &cfhsi_list);
+
+ return 0;
+err:
+ symbol_put(cfhsi_get_ops);
+ return -ENODEV;
+}
+
+static struct rtnl_link_ops caif_hsi_link_ops __read_mostly = {
+ .kind = "cfhsi",
+ .priv_size = sizeof(struct cfhsi),
+ .setup = cfhsi_setup,
+ .maxtype = __IFLA_CAIF_HSI_MAX,
+ .policy = caif_hsi_policy,
+ .newlink = caif_hsi_newlink,
+ .changelink = caif_hsi_changelink,
+ .get_size = caif_hsi_get_size,
+ .fill_info = caif_hsi_fill_info,
+};
+
+static void __exit cfhsi_exit_module(void)
+{
+ struct list_head *list_node;
+ struct list_head *n;
+ struct cfhsi *cfhsi;
+
+ rtnl_link_unregister(&caif_hsi_link_ops);
+
+ rtnl_lock();
+ list_for_each_safe(list_node, n, &cfhsi_list) {
+ cfhsi = list_entry(list_node, struct cfhsi, list);
+ unregister_netdev(cfhsi->ndev);
+ }
+ rtnl_unlock();
+}
+
+static int __init cfhsi_init_module(void)
+{
+ return rtnl_link_register(&caif_hsi_link_ops);
+}
+
+module_init(cfhsi_init_module);
+module_exit(cfhsi_exit_module);
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
new file mode 100644
index 00000000000..fc73865bb83
--- /dev/null
+++ b/drivers/net/caif/caif_serial.c
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author: Sjur Brendeland
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/hardirq.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/tty.h>
+#include <linux/file.h>
+#include <linux/if_arp.h>
+#include <net/caif/caif_device.h>
+#include <net/caif/cfcnfg.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sjur Brendeland");
+MODULE_DESCRIPTION("CAIF serial device TTY line discipline");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_CAIF);
+
+#define SEND_QUEUE_LOW 10
+#define SEND_QUEUE_HIGH 100
+#define CAIF_SENDING 1 /* Bit 1 = 0x02*/
+#define CAIF_FLOW_OFF_SENT 4 /* Bit 4 = 0x10 */
+#define MAX_WRITE_CHUNK 4096
+#define ON 1
+#define OFF 0
+#define CAIF_MAX_MTU 4096
+
+static DEFINE_SPINLOCK(ser_lock);
+static LIST_HEAD(ser_list);
+static LIST_HEAD(ser_release_list);
+
+static bool ser_loop;
+module_param(ser_loop, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode.");
+
+static bool ser_use_stx = true;
+module_param(ser_use_stx, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_use_stx, "STX enabled or not.");
+
+static bool ser_use_fcs = true;
+
+module_param(ser_use_fcs, bool, S_IRUGO);
+MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not.");
+
+static int ser_write_chunk = MAX_WRITE_CHUNK;
+module_param(ser_write_chunk, int, S_IRUGO);
+
+MODULE_PARM_DESC(ser_write_chunk, "Maximum size of data written to UART.");
+
+static struct dentry *debugfsdir;
+
+static int caif_net_open(struct net_device *dev);
+static int caif_net_close(struct net_device *dev);
+
+struct ser_device {
+ struct caif_dev_common common;
+ struct list_head node;
+ struct net_device *dev;
+ struct sk_buff_head head;
+ struct tty_struct *tty;
+ bool tx_started;
+ unsigned long state;
+ char *tty_name;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_tty_dir;
+ struct debugfs_blob_wrapper tx_blob;
+ struct debugfs_blob_wrapper rx_blob;
+ u8 rx_data[128];
+ u8 tx_data[128];
+ u8 tty_status;
+
+#endif
+};
+
+static void caifdev_setup(struct net_device *dev);
+static void ldisc_tx_wakeup(struct tty_struct *tty);
+#ifdef CONFIG_DEBUG_FS
+static inline void update_tty_status(struct ser_device *ser)
+{
+ ser->tty_status =
+ ser->tty->stopped << 5 |
+ ser->tty->flow_stopped << 3 |
+ ser->tty->packet << 2 |
+ ser->tty->port->low_latency << 1;
+}
+static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
+{
+ ser->debugfs_tty_dir =
+ debugfs_create_dir(tty->name, debugfsdir);
+ if (!IS_ERR(ser->debugfs_tty_dir)) {
+ debugfs_create_blob("last_tx_msg", S_IRUSR,
+ ser->debugfs_tty_dir,
+ &ser->tx_blob);
+
+ debugfs_create_blob("last_rx_msg", S_IRUSR,
+ ser->debugfs_tty_dir,
+ &ser->rx_blob);
+
+ debugfs_create_x32("ser_state", S_IRUSR,
+ ser->debugfs_tty_dir,
+ (u32 *)&ser->state);
+
+ debugfs_create_x8("tty_status", S_IRUSR,
+ ser->debugfs_tty_dir,
+ &ser->tty_status);
+
+ }
+ ser->tx_blob.data = ser->tx_data;
+ ser->tx_blob.size = 0;
+ ser->rx_blob.data = ser->rx_data;
+ ser->rx_blob.size = 0;
+}
+
+static inline void debugfs_deinit(struct ser_device *ser)
+{
+ debugfs_remove_recursive(ser->debugfs_tty_dir);
+}
+
+static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
+{
+ if (size > sizeof(ser->rx_data))
+ size = sizeof(ser->rx_data);
+ memcpy(ser->rx_data, data, size);
+ ser->rx_blob.data = ser->rx_data;
+ ser->rx_blob.size = size;
+}
+
+static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
+{
+ if (size > sizeof(ser->tx_data))
+ size = sizeof(ser->tx_data);
+ memcpy(ser->tx_data, data, size);
+ ser->tx_blob.data = ser->tx_data;
+ ser->tx_blob.size = size;
+}
+#else
+static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
+{
+}
+
+static inline void debugfs_deinit(struct ser_device *ser)
+{
+}
+
+static inline void update_tty_status(struct ser_device *ser)
+{
+}
+
+static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
+{
+}
+
+static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
+{
+}
+
+#endif
+
+static void ldisc_receive(struct tty_struct *tty, const u8 *data,
+ char *flags, int count)
+{
+ struct sk_buff *skb = NULL;
+ struct ser_device *ser;
+ int ret;
+ u8 *p;
+
+ ser = tty->disc_data;
+
+ /*
+ * NOTE: flags may contain information about break or overrun.
+ * This is not yet handled.
+ */
+
+
+ /*
+ * Workaround for garbage at start of transmission,
+ * only enable if STX handling is not enabled.
+ */
+ if (!ser->common.use_stx && !ser->tx_started) {
+ dev_info(&ser->dev->dev,
+ "Bytes received before initial transmission -"
+ "bytes discarded.\n");
+ return;
+ }
+
+ BUG_ON(ser->dev == NULL);
+
+ /* Get a suitable caif packet and copy in data. */
+ skb = netdev_alloc_skb(ser->dev, count+1);
+ if (skb == NULL)
+ return;
+ p = skb_put(skb, count);
+ memcpy(p, data, count);
+
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+ debugfs_rx(ser, data, count);
+ /* Push received packet up the stack. */
+ ret = netif_rx_ni(skb);
+ if (!ret) {
+ ser->dev->stats.rx_packets++;
+ ser->dev->stats.rx_bytes += count;
+ } else
+ ++ser->dev->stats.rx_dropped;
+ update_tty_status(ser);
+}
+
+static int handle_tx(struct ser_device *ser)
+{
+ struct tty_struct *tty;
+ struct sk_buff *skb;
+ int tty_wr, len, room;
+
+ tty = ser->tty;
+ ser->tx_started = true;
+
+ /* Enter critical section */
+ if (test_and_set_bit(CAIF_SENDING, &ser->state))
+ return 0;
+
+ /* skb_peek is safe because handle_tx is called after skb_queue_tail */
+ while ((skb = skb_peek(&ser->head)) != NULL) {
+
+ /* Make sure you don't write too much */
+ len = skb->len;
+ room = tty_write_room(tty);
+ if (!room)
+ break;
+ if (room > ser_write_chunk)
+ room = ser_write_chunk;
+ if (len > room)
+ len = room;
+
+ /* Write to tty or loopback */
+ if (!ser_loop) {
+ tty_wr = tty->ops->write(tty, skb->data, len);
+ update_tty_status(ser);
+ } else {
+ tty_wr = len;
+ ldisc_receive(tty, skb->data, NULL, len);
+ }
+ ser->dev->stats.tx_packets++;
+ ser->dev->stats.tx_bytes += tty_wr;
+
+ /* Error on TTY ?! */
+ if (tty_wr < 0)
+ goto error;
+ /* Reduce buffer written, and discard if empty */
+ skb_pull(skb, tty_wr);
+ if (skb->len == 0) {
+ struct sk_buff *tmp = skb_dequeue(&ser->head);
+ WARN_ON(tmp != skb);
+ if (in_interrupt())
+ dev_kfree_skb_irq(skb);
+ else
+ kfree_skb(skb);
+ }
+ }
+ /* Send flow off if queue is empty */
+ if (ser->head.qlen <= SEND_QUEUE_LOW &&
+ test_and_clear_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
+ ser->common.flowctrl != NULL)
+ ser->common.flowctrl(ser->dev, ON);
+ clear_bit(CAIF_SENDING, &ser->state);
+ return 0;
+error:
+ clear_bit(CAIF_SENDING, &ser->state);
+ return tty_wr;
+}
+
+static int caif_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct ser_device *ser;
+
+ BUG_ON(dev == NULL);
+ ser = netdev_priv(dev);
+
+ /* Send flow off once, on high water mark */
+ if (ser->head.qlen > SEND_QUEUE_HIGH &&
+ !test_and_set_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
+ ser->common.flowctrl != NULL)
+
+ ser->common.flowctrl(ser->dev, OFF);
+
+ skb_queue_tail(&ser->head, skb);
+ return handle_tx(ser);
+}
+
+
+static void ldisc_tx_wakeup(struct tty_struct *tty)
+{
+ struct ser_device *ser;
+
+ ser = tty->disc_data;
+ BUG_ON(ser == NULL);
+ WARN_ON(ser->tty != tty);
+ handle_tx(ser);
+}
+
+
+static void ser_release(struct work_struct *work)
+{
+ struct list_head list;
+ struct ser_device *ser, *tmp;
+
+ spin_lock(&ser_lock);
+ list_replace_init(&ser_release_list, &list);
+ spin_unlock(&ser_lock);
+
+ if (!list_empty(&list)) {
+ rtnl_lock();
+ list_for_each_entry_safe(ser, tmp, &list, node) {
+ dev_close(ser->dev);
+ unregister_netdevice(ser->dev);
+ debugfs_deinit(ser);
+ }
+ rtnl_unlock();
+ }
+}
+
+static DECLARE_WORK(ser_release_work, ser_release);
+
+static int ldisc_open(struct tty_struct *tty)
+{
+ struct ser_device *ser;
+ struct net_device *dev;
+ char name[64];
+ int result;
+
+ /* No write no play */
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_TTY_CONFIG))
+ return -EPERM;
+
+ /* release devices to avoid name collision */
+ ser_release(NULL);
+
+ result = snprintf(name, sizeof(name), "cf%s", tty->name);
+ if (result >= IFNAMSIZ)
+ return -EINVAL;
+ dev = alloc_netdev(sizeof(*ser), name, caifdev_setup);
+ if (!dev)
+ return -ENOMEM;
+
+ ser = netdev_priv(dev);
+ ser->tty = tty_kref_get(tty);
+ ser->dev = dev;
+ debugfs_init(ser, tty);
+ tty->receive_room = N_TTY_BUF_SIZE;
+ tty->disc_data = ser;
+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ rtnl_lock();
+ result = register_netdevice(dev);
+ if (result) {
+ rtnl_unlock();
+ free_netdev(dev);
+ return -ENODEV;
+ }
+
+ spin_lock(&ser_lock);
+ list_add(&ser->node, &ser_list);
+ spin_unlock(&ser_lock);
+ rtnl_unlock();
+ netif_stop_queue(dev);
+ update_tty_status(ser);
+ return 0;
+}
+
+static void ldisc_close(struct tty_struct *tty)
+{
+ struct ser_device *ser = tty->disc_data;
+
+ tty_kref_put(ser->tty);
+
+ spin_lock(&ser_lock);
+ list_move(&ser->node, &ser_release_list);
+ spin_unlock(&ser_lock);
+ schedule_work(&ser_release_work);
+}
+
+/* The line discipline structure. */
+static struct tty_ldisc_ops caif_ldisc = {
+ .owner = THIS_MODULE,
+ .magic = TTY_LDISC_MAGIC,
+ .name = "n_caif",
+ .open = ldisc_open,
+ .close = ldisc_close,
+ .receive_buf = ldisc_receive,
+ .write_wakeup = ldisc_tx_wakeup
+};
+
+static int register_ldisc(void)
+{
+ int result;
+
+ result = tty_register_ldisc(N_CAIF, &caif_ldisc);
+ if (result < 0) {
+ pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF,
+ result);
+ return result;
+ }
+ return result;
+}
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = caif_net_open,
+ .ndo_stop = caif_net_close,
+ .ndo_start_xmit = caif_xmit
+};
+
+static void caifdev_setup(struct net_device *dev)
+{
+ struct ser_device *serdev = netdev_priv(dev);
+
+ dev->features = 0;
+ dev->netdev_ops = &netdev_ops;
+ dev->type = ARPHRD_CAIF;
+ dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->mtu = CAIF_MAX_MTU;
+ dev->tx_queue_len = 0;
+ dev->destructor = free_netdev;
+ skb_queue_head_init(&serdev->head);
+ serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
+ serdev->common.use_frag = true;
+ serdev->common.use_stx = ser_use_stx;
+ serdev->common.use_fcs = ser_use_fcs;
+ serdev->dev = dev;
+}
+
+
+static int caif_net_open(struct net_device *dev)
+{
+ netif_wake_queue(dev);
+ return 0;
+}
+
+static int caif_net_close(struct net_device *dev)
+{
+ netif_stop_queue(dev);
+ return 0;
+}
+
+static int __init caif_ser_init(void)
+{
+ int ret;
+
+ ret = register_ldisc();
+ debugfsdir = debugfs_create_dir("caif_serial", NULL);
+ return ret;
+}
+
+static void __exit caif_ser_exit(void)
+{
+ spin_lock(&ser_lock);
+ list_splice(&ser_list, &ser_release_list);
+ spin_unlock(&ser_lock);
+ ser_release(NULL);
+ cancel_work_sync(&ser_release_work);
+ tty_unregister_ldisc(N_CAIF);
+ debugfs_remove_recursive(debugfsdir);
+}
+
+module_init(caif_ser_init);
+module_exit(caif_ser_exit);
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c
new file mode 100644
index 00000000000..ff54c0eb205
--- /dev/null
+++ b/drivers/net/caif/caif_spi.c
@@ -0,0 +1,871 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author: Daniel Martensson
+ * License terms: GNU General Public License (GPL) version 2.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/debugfs.h>
+#include <linux/if_arp.h>
+#include <net/caif/caif_layer.h>
+#include <net/caif/caif_spi.h>
+
+#ifndef CONFIG_CAIF_SPI_SYNC
+#define FLAVOR "Flavour: Vanilla.\n"
+#else
+#define FLAVOR "Flavour: Master CMD&LEN at start.\n"
+#endif /* CONFIG_CAIF_SPI_SYNC */
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel Martensson");
+MODULE_DESCRIPTION("CAIF SPI driver");
+
+/* Returns the number of padding bytes for alignment. */
+#define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1)))))
+
+static bool spi_loop;
+module_param(spi_loop, bool, S_IRUGO);
+MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode.");
+
+/* SPI frame alignment. */
+module_param(spi_frm_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment.");
+
+/*
+ * SPI padding options.
+ * Warning: must be a base of 2 (& operation used) and can not be zero !
+ */
+module_param(spi_up_head_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment.");
+
+module_param(spi_up_tail_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_up_tail_align, "SPI uplink tail alignment.");
+
+module_param(spi_down_head_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_down_head_align, "SPI downlink head alignment.");
+
+module_param(spi_down_tail_align, int, S_IRUGO);
+MODULE_PARM_DESC(spi_down_tail_align, "SPI downlink tail alignment.");
+
+#ifdef CONFIG_ARM
+#define BYTE_HEX_FMT "%02X"
+#else
+#define BYTE_HEX_FMT "%02hhX"
+#endif
+
+#define SPI_MAX_PAYLOAD_SIZE 4096
+/*
+ * Threshold values for the SPI packet queue. Flowcontrol will be asserted
+ * when the number of packets exceeds HIGH_WATER_MARK. It will not be
+ * deasserted before the number of packets drops below LOW_WATER_MARK.
+ */
+#define LOW_WATER_MARK 100
+#define HIGH_WATER_MARK (LOW_WATER_MARK*5)
+
+#ifdef CONFIG_UML
+
+/*
+ * We sometimes use UML for debugging, but it cannot handle
+ * dma_alloc_coherent so we have to wrap it.
+ */
+static inline void *dma_alloc(dma_addr_t *daddr)
+{
+ return kmalloc(SPI_DMA_BUF_LEN, GFP_KERNEL);
+}
+
+static inline void dma_free(void *cpu_addr, dma_addr_t handle)
+{
+ kfree(cpu_addr);
+}
+
+#else
+
+static inline void *dma_alloc(dma_addr_t *daddr)
+{
+ return dma_alloc_coherent(NULL, SPI_DMA_BUF_LEN, daddr,
+ GFP_KERNEL);
+}
+
+static inline void dma_free(void *cpu_addr, dma_addr_t handle)
+{
+ dma_free_coherent(NULL, SPI_DMA_BUF_LEN, cpu_addr, handle);
+}
+#endif /* CONFIG_UML */
+
+#ifdef CONFIG_DEBUG_FS
+
+#define DEBUGFS_BUF_SIZE 4096
+
+static struct dentry *dbgfs_root;
+
+static inline void driver_debugfs_create(void)
+{
+ dbgfs_root = debugfs_create_dir(cfspi_spi_driver.driver.name, NULL);
+}
+
+static inline void driver_debugfs_remove(void)
+{
+ debugfs_remove(dbgfs_root);
+}
+
+static inline void dev_debugfs_rem(struct cfspi *cfspi)
+{
+ debugfs_remove(cfspi->dbgfs_frame);
+ debugfs_remove(cfspi->dbgfs_state);
+ debugfs_remove(cfspi->dbgfs_dir);
+}
+
+static ssize_t dbgfs_state(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int len = 0;
+ ssize_t size;
+ struct cfspi *cfspi = file->private_data;
+
+ buf = kzalloc(DEBUGFS_BUF_SIZE, GFP_KERNEL);
+ if (!buf)
+ return 0;
+
+ /* Print out debug information. */
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "CAIF SPI debug information:\n");
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), FLAVOR);
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "STATE: %d\n", cfspi->dbg_state);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Previous CMD: 0x%x\n", cfspi->pcmd);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current CMD: 0x%x\n", cfspi->cmd);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Previous TX len: %d\n", cfspi->tx_ppck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Previous RX len: %d\n", cfspi->rx_ppck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current TX len: %d\n", cfspi->tx_cpck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current RX len: %d\n", cfspi->rx_cpck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Next TX len: %d\n", cfspi->tx_npck_len);
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Next RX len: %d\n", cfspi->rx_npck_len);
+
+ if (len > DEBUGFS_BUF_SIZE)
+ len = DEBUGFS_BUF_SIZE;
+
+ size = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return size;
+}
+
+static ssize_t print_frame(char *buf, size_t size, char *frm,
+ size_t count, size_t cut)
+{
+ int len = 0;
+ int i;
+ for (i = 0; i < count; i++) {
+ len += snprintf((buf + len), (size - len),
+ "[0x" BYTE_HEX_FMT "]",
+ frm[i]);
+ if ((i == cut) && (count > (cut * 2))) {
+ /* Fast forward. */
+ i = count - cut;
+ len += snprintf((buf + len), (size - len),
+ "--- %u bytes skipped ---\n",
+ (int)(count - (cut * 2)));
+ }
+
+ if ((!(i % 10)) && i) {
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "\n");
+ }
+ }
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len), "\n");
+ return len;
+}
+
+static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char *buf;
+ int len = 0;
+ ssize_t size;
+ struct cfspi *cfspi;
+
+ cfspi = file->private_data;
+ buf = kzalloc(DEBUGFS_BUF_SIZE, GFP_KERNEL);
+ if (!buf)
+ return 0;
+
+ /* Print out debug information. */
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Current frame:\n");
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Tx data (Len: %d):\n", cfspi->tx_cpck_len);
+
+ len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
+ cfspi->xfer.va_tx[0],
+ (cfspi->tx_cpck_len + SPI_CMD_SZ), 100);
+
+ len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
+ "Rx data (Len: %d):\n", cfspi->rx_cpck_len);
+
+ len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
+ cfspi->xfer.va_rx,
+ (cfspi->rx_cpck_len + SPI_CMD_SZ), 100);
+
+ size = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return size;
+}
+
+static const struct file_operations dbgfs_state_fops = {
+ .open = simple_open,
+ .read = dbgfs_state,
+ .owner = THIS_MODULE
+};
+
+static const struct file_operations dbgfs_frame_fops = {
+ .open = simple_open,
+ .read = dbgfs_frame,
+ .owner = THIS_MODULE
+};
+
+static inline void dev_debugfs_add(struct cfspi *cfspi)
+{
+ cfspi->dbgfs_dir = debugfs_create_dir(cfspi->pdev->name, dbgfs_root);
+ cfspi->dbgfs_state = debugfs_create_file("state", S_IRUGO,
+ cfspi->dbgfs_dir, cfspi,
+ &dbgfs_state_fops);
+ cfspi->dbgfs_frame = debugfs_create_file("frame", S_IRUGO,
+ cfspi->dbgfs_dir, cfspi,
+ &dbgfs_frame_fops);
+}
+
+inline void cfspi_dbg_state(struct cfspi *cfspi, int state)
+{
+ cfspi->dbg_state = state;
+};
+#else
+
+static inline void driver_debugfs_create(void)
+{
+}
+
+static inline void driver_debugfs_remove(void)
+{
+}
+
+static inline void dev_debugfs_add(struct cfspi *cfspi)
+{
+}
+
+static inline void dev_debugfs_rem(struct cfspi *cfspi)
+{
+}
+
+inline void cfspi_dbg_state(struct cfspi *cfspi, int state)
+{
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static LIST_HEAD(cfspi_list);
+static spinlock_t cfspi_list_lock;
+
+/* SPI uplink head alignment. */
+static ssize_t show_up_head_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_up_head_align);
+}
+
+static DRIVER_ATTR(up_head_align, S_IRUSR, show_up_head_align, NULL);
+
+/* SPI uplink tail alignment. */
+static ssize_t show_up_tail_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_up_tail_align);
+}
+
+static DRIVER_ATTR(up_tail_align, S_IRUSR, show_up_tail_align, NULL);
+
+/* SPI downlink head alignment. */
+static ssize_t show_down_head_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_down_head_align);
+}
+
+static DRIVER_ATTR(down_head_align, S_IRUSR, show_down_head_align, NULL);
+
+/* SPI downlink tail alignment. */
+static ssize_t show_down_tail_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_down_tail_align);
+}
+
+static DRIVER_ATTR(down_tail_align, S_IRUSR, show_down_tail_align, NULL);
+
+/* SPI frame alignment. */
+static ssize_t show_frame_align(struct device_driver *driver, char *buf)
+{
+ return sprintf(buf, "%d\n", spi_frm_align);
+}
+
+static DRIVER_ATTR(frame_align, S_IRUSR, show_frame_align, NULL);
+
+int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len)
+{
+ u8 *dst = buf;
+ caif_assert(buf);
+
+ if (cfspi->slave && !cfspi->slave_talked)
+ cfspi->slave_talked = true;
+
+ do {
+ struct sk_buff *skb;
+ struct caif_payload_info *info;
+ int spad = 0;
+ int epad;
+
+ skb = skb_dequeue(&cfspi->chead);
+ if (!skb)
+ break;
+
+ /*
+ * Calculate length of frame including SPI padding.
+ * The payload position is found in the control buffer.
+ */
+ info = (struct caif_payload_info *)&skb->cb;
+
+ /*
+ * Compute head offset i.e. number of bytes to add to
+ * get the start of the payload aligned.
+ */
+ if (spi_up_head_align > 1) {
+ spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align);
+ *dst = (u8)(spad - 1);
+ dst += spad;
+ }
+
+ /* Copy in CAIF frame. */
+ skb_copy_bits(skb, 0, dst, skb->len);
+ dst += skb->len;
+ cfspi->ndev->stats.tx_packets++;
+ cfspi->ndev->stats.tx_bytes += skb->len;
+
+ /*
+ * Compute tail offset i.e. number of bytes to add to
+ * get the complete CAIF frame aligned.
+ */
+ epad = PAD_POW2((skb->len + spad), spi_up_tail_align);
+ dst += epad;
+
+ dev_kfree_skb(skb);
+
+ } while ((dst - buf) < len);
+
+ return dst - buf;
+}
+
+int cfspi_xmitlen(struct cfspi *cfspi)
+{
+ struct sk_buff *skb = NULL;
+ int frm_len = 0;
+ int pkts = 0;
+
+ /*
+ * Decommit previously committed frames.
+ * skb_queue_splice_tail(&cfspi->chead,&cfspi->qhead)
+ */
+ while (skb_peek(&cfspi->chead)) {
+ skb = skb_dequeue_tail(&cfspi->chead);
+ skb_queue_head(&cfspi->qhead, skb);
+ }
+
+ do {
+ struct caif_payload_info *info = NULL;
+ int spad = 0;
+ int epad = 0;
+
+ skb = skb_dequeue(&cfspi->qhead);
+ if (!skb)
+ break;
+
+ /*
+ * Calculate length of frame including SPI padding.
+ * The payload position is found in the control buffer.
+ */
+ info = (struct caif_payload_info *)&skb->cb;
+
+ /*
+ * Compute head offset i.e. number of bytes to add to
+ * get the start of the payload aligned.
+ */
+ if (spi_up_head_align > 1)
+ spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align);
+
+ /*
+ * Compute tail offset i.e. number of bytes to add to
+ * get the complete CAIF frame aligned.
+ */
+ epad = PAD_POW2((skb->len + spad), spi_up_tail_align);
+
+ if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) {
+ skb_queue_tail(&cfspi->chead, skb);
+ pkts++;
+ frm_len += skb->len + spad + epad;
+ } else {
+ /* Put back packet. */
+ skb_queue_head(&cfspi->qhead, skb);
+ break;
+ }
+ } while (pkts <= CAIF_MAX_SPI_PKTS);
+
+ /*
+ * Send flow on if previously sent flow off
+ * and now go below the low water mark
+ */
+ if (cfspi->flow_off_sent && cfspi->qhead.qlen < cfspi->qd_low_mark &&
+ cfspi->cfdev.flowctrl) {
+ cfspi->flow_off_sent = 0;
+ cfspi->cfdev.flowctrl(cfspi->ndev, 1);
+ }
+
+ return frm_len;
+}
+
+static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc)
+{
+ struct cfspi *cfspi = (struct cfspi *)ifc->priv;
+
+ /*
+ * The slave device is the master on the link. Interrupts before the
+ * slave has transmitted are considered spurious.
+ */
+ if (cfspi->slave && !cfspi->slave_talked) {
+ printk(KERN_WARNING "CFSPI: Spurious SS interrupt.\n");
+ return;
+ }
+
+ if (!in_interrupt())
+ spin_lock(&cfspi->lock);
+ if (assert) {
+ set_bit(SPI_SS_ON, &cfspi->state);
+ set_bit(SPI_XFER, &cfspi->state);
+ } else {
+ set_bit(SPI_SS_OFF, &cfspi->state);
+ }
+ if (!in_interrupt())
+ spin_unlock(&cfspi->lock);
+
+ /* Wake up the xfer thread. */
+ if (assert)
+ wake_up_interruptible(&cfspi->wait);
+}
+
+static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc)
+{
+ struct cfspi *cfspi = (struct cfspi *)ifc->priv;
+
+ /* Transfer done, complete work queue */
+ complete(&cfspi->comp);
+}
+
+static int cfspi_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct cfspi *cfspi = NULL;
+ unsigned long flags;
+ if (!dev)
+ return -EINVAL;
+
+ cfspi = netdev_priv(dev);
+
+ skb_queue_tail(&cfspi->qhead, skb);
+
+ spin_lock_irqsave(&cfspi->lock, flags);
+ if (!test_and_set_bit(SPI_XFER, &cfspi->state)) {
+ /* Wake up xfer thread. */
+ wake_up_interruptible(&cfspi->wait);
+ }
+ spin_unlock_irqrestore(&cfspi->lock, flags);
+
+ /* Send flow off if number of bytes is above high water mark */
+ if (!cfspi->flow_off_sent &&
+ cfspi->qhead.qlen > cfspi->qd_high_mark &&
+ cfspi->cfdev.flowctrl) {
+ cfspi->flow_off_sent = 1;
+ cfspi->cfdev.flowctrl(cfspi->ndev, 0);
+ }
+
+ return 0;
+}
+
+int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len)
+{
+ u8 *src = buf;
+
+ caif_assert(buf != NULL);
+
+ do {
+ int res;
+ struct sk_buff *skb = NULL;
+ int spad = 0;
+ int epad = 0;
+ u8 *dst = NULL;
+ int pkt_len = 0;
+
+ /*
+ * Compute head offset i.e. number of bytes added to
+ * get the start of the payload aligned.
+ */
+ if (spi_down_head_align > 1) {
+ spad = 1 + *src;
+ src += spad;
+ }
+
+ /* Read length of CAIF frame (little endian). */
+ pkt_len = *src;
+ pkt_len |= ((*(src+1)) << 8) & 0xFF00;
+ pkt_len += 2; /* Add FCS fields. */
+
+ /* Get a suitable caif packet and copy in data. */
+
+ skb = netdev_alloc_skb(cfspi->ndev, pkt_len + 1);
+ caif_assert(skb != NULL);
+
+ dst = skb_put(skb, pkt_len);
+ memcpy(dst, src, pkt_len);
+ src += pkt_len;
+
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+
+ /*
+ * Push received packet up the stack.
+ */
+ if (!spi_loop)
+ res = netif_rx_ni(skb);
+ else
+ res = cfspi_xmit(skb, cfspi->ndev);
+
+ if (!res) {
+ cfspi->ndev->stats.rx_packets++;
+ cfspi->ndev->stats.rx_bytes += pkt_len;
+ } else
+ cfspi->ndev->stats.rx_dropped++;
+
+ /*
+ * Compute tail offset i.e. number of bytes added to
+ * get the complete CAIF frame aligned.
+ */
+ epad = PAD_POW2((pkt_len + spad), spi_down_tail_align);
+ src += epad;
+ } while ((src - buf) < len);
+
+ return src - buf;
+}
+
+static int cfspi_open(struct net_device *dev)
+{
+ netif_wake_queue(dev);
+ return 0;
+}
+
+static int cfspi_close(struct net_device *dev)
+{
+ netif_stop_queue(dev);
+ return 0;
+}
+
+static int cfspi_init(struct net_device *dev)
+{
+ int res = 0;
+ struct cfspi *cfspi = netdev_priv(dev);
+
+ /* Set flow info. */
+ cfspi->flow_off_sent = 0;
+ cfspi->qd_low_mark = LOW_WATER_MARK;
+ cfspi->qd_high_mark = HIGH_WATER_MARK;
+
+ /* Set slave info. */
+ if (!strncmp(cfspi_spi_driver.driver.name, "cfspi_sspi", 10)) {
+ cfspi->slave = true;
+ cfspi->slave_talked = false;
+ } else {
+ cfspi->slave = false;
+ cfspi->slave_talked = false;
+ }
+
+ /* Allocate DMA buffers. */
+ cfspi->xfer.va_tx[0] = dma_alloc(&cfspi->xfer.pa_tx[0]);
+ if (!cfspi->xfer.va_tx[0]) {
+ res = -ENODEV;
+ goto err_dma_alloc_tx_0;
+ }
+
+ cfspi->xfer.va_rx = dma_alloc(&cfspi->xfer.pa_rx);
+
+ if (!cfspi->xfer.va_rx) {
+ res = -ENODEV;
+ goto err_dma_alloc_rx;
+ }
+
+ /* Initialize the work queue. */
+ INIT_WORK(&cfspi->work, cfspi_xfer);
+
+ /* Initialize spin locks. */
+ spin_lock_init(&cfspi->lock);
+
+ /* Initialize flow control state. */
+ cfspi->flow_stop = false;
+
+ /* Initialize wait queue. */
+ init_waitqueue_head(&cfspi->wait);
+
+ /* Create work thread. */
+ cfspi->wq = create_singlethread_workqueue(dev->name);
+ if (!cfspi->wq) {
+ printk(KERN_WARNING "CFSPI: failed to create work queue.\n");
+ res = -ENODEV;
+ goto err_create_wq;
+ }
+
+ /* Initialize work queue. */
+ init_completion(&cfspi->comp);
+
+ /* Create debugfs entries. */
+ dev_debugfs_add(cfspi);
+
+ /* Set up the ifc. */
+ cfspi->ifc.ss_cb = cfspi_ss_cb;
+ cfspi->ifc.xfer_done_cb = cfspi_xfer_done_cb;
+ cfspi->ifc.priv = cfspi;
+
+ /* Add CAIF SPI device to list. */
+ spin_lock(&cfspi_list_lock);
+ list_add_tail(&cfspi->list, &cfspi_list);
+ spin_unlock(&cfspi_list_lock);
+
+ /* Schedule the work queue. */
+ queue_work(cfspi->wq, &cfspi->work);
+
+ return 0;
+
+ err_create_wq:
+ dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
+ err_dma_alloc_rx:
+ dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]);
+ err_dma_alloc_tx_0:
+ return res;
+}
+
+static void cfspi_uninit(struct net_device *dev)
+{
+ struct cfspi *cfspi = netdev_priv(dev);
+
+ /* Remove from list. */
+ spin_lock(&cfspi_list_lock);
+ list_del(&cfspi->list);
+ spin_unlock(&cfspi_list_lock);
+
+ cfspi->ndev = NULL;
+ /* Free DMA buffers. */
+ dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
+ dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]);
+ set_bit(SPI_TERMINATE, &cfspi->state);
+ wake_up_interruptible(&cfspi->wait);
+ destroy_workqueue(cfspi->wq);
+ /* Destroy debugfs directory and files. */
+ dev_debugfs_rem(cfspi);
+ return;
+}
+
+static const struct net_device_ops cfspi_ops = {
+ .ndo_open = cfspi_open,
+ .ndo_stop = cfspi_close,
+ .ndo_init = cfspi_init,
+ .ndo_uninit = cfspi_uninit,
+ .ndo_start_xmit = cfspi_xmit
+};
+
+static void cfspi_setup(struct net_device *dev)
+{
+ struct cfspi *cfspi = netdev_priv(dev);
+ dev->features = 0;
+ dev->netdev_ops = &cfspi_ops;
+ dev->type = ARPHRD_CAIF;
+ dev->flags = IFF_NOARP | IFF_POINTOPOINT;
+ dev->tx_queue_len = 0;
+ dev->mtu = SPI_MAX_PAYLOAD_SIZE;
+ dev->destructor = free_netdev;
+ skb_queue_head_init(&cfspi->qhead);
+ skb_queue_head_init(&cfspi->chead);
+ cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
+ cfspi->cfdev.use_frag = false;
+ cfspi->cfdev.use_stx = false;
+ cfspi->cfdev.use_fcs = false;
+ cfspi->ndev = dev;
+}
+
+int cfspi_spi_probe(struct platform_device *pdev)
+{
+ struct cfspi *cfspi = NULL;
+ struct net_device *ndev;
+ struct cfspi_dev *dev;
+ int res;
+ dev = (struct cfspi_dev *)pdev->dev.platform_data;
+
+ ndev = alloc_netdev(sizeof(struct cfspi),
+ "cfspi%d", cfspi_setup);
+ if (!dev)
+ return -ENODEV;
+
+ cfspi = netdev_priv(ndev);
+ netif_stop_queue(ndev);
+ cfspi->ndev = ndev;
+ cfspi->pdev = pdev;
+
+ /* Assign the SPI device. */
+ cfspi->dev = dev;
+ /* Assign the device ifc to this SPI interface. */
+ dev->ifc = &cfspi->ifc;
+
+ /* Register network device. */
+ res = register_netdev(ndev);
+ if (res) {
+ printk(KERN_ERR "CFSPI: Reg. error: %d.\n", res);
+ goto err_net_reg;
+ }
+ return res;
+
+ err_net_reg:
+ free_netdev(ndev);
+
+ return res;
+}
+
+int cfspi_spi_remove(struct platform_device *pdev)
+{
+ /* Everything is done in cfspi_uninit(). */
+ return 0;
+}
+
+static void __exit cfspi_exit_module(void)
+{
+ struct list_head *list_node;
+ struct list_head *n;
+ struct cfspi *cfspi = NULL;
+
+ list_for_each_safe(list_node, n, &cfspi_list) {
+ cfspi = list_entry(list_node, struct cfspi, list);
+ unregister_netdev(cfspi->ndev);
+ }
+
+ /* Destroy sysfs files. */
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_head_align);
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_tail_align);
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_head_align);
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_tail_align);
+ driver_remove_file(&cfspi_spi_driver.driver, &driver_attr_frame_align);
+ /* Unregister platform driver. */
+ platform_driver_unregister(&cfspi_spi_driver);
+ /* Destroy debugfs root directory. */
+ driver_debugfs_remove();
+}
+
+static int __init cfspi_init_module(void)
+{
+ int result;
+
+ /* Initialize spin lock. */
+ spin_lock_init(&cfspi_list_lock);
+
+ /* Register platform driver. */
+ result = platform_driver_register(&cfspi_spi_driver);
+ if (result) {
+ printk(KERN_ERR "Could not register platform SPI driver.\n");
+ goto err_dev_register;
+ }
+
+ /* Create sysfs files. */
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_head_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 1.\n");
+ goto err_create_up_head_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_tail_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 2.\n");
+ goto err_create_up_tail_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_head_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 3.\n");
+ goto err_create_down_head_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_tail_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 4.\n");
+ goto err_create_down_tail_align;
+ }
+
+ result =
+ driver_create_file(&cfspi_spi_driver.driver,
+ &driver_attr_frame_align);
+ if (result) {
+ printk(KERN_ERR "Sysfs creation failed 5.\n");
+ goto err_create_frame_align;
+ }
+ driver_debugfs_create();
+ return result;
+
+ err_create_frame_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_tail_align);
+ err_create_down_tail_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_down_head_align);
+ err_create_down_head_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_tail_align);
+ err_create_up_tail_align:
+ driver_remove_file(&cfspi_spi_driver.driver,
+ &driver_attr_up_head_align);
+ err_create_up_head_align:
+ platform_driver_unregister(&cfspi_spi_driver);
+ err_dev_register:
+ return result;
+}
+
+module_init(cfspi_init_module);
+module_exit(cfspi_exit_module);
diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c
new file mode 100644
index 00000000000..39ba2f892ad
--- /dev/null
+++ b/drivers/net/caif/caif_spi_slave.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ * Author: Daniel Martensson
+ * License terms: GNU General Public License (GPL) version 2.
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <linux/semaphore.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/debugfs.h>
+#include <net/caif/caif_spi.h>
+
+#ifndef CONFIG_CAIF_SPI_SYNC
+#define SPI_DATA_POS 0
+static inline int forward_to_spi_cmd(struct cfspi *cfspi)
+{
+ return cfspi->rx_cpck_len;
+}
+#else
+#define SPI_DATA_POS SPI_CMD_SZ
+static inline int forward_to_spi_cmd(struct cfspi *cfspi)
+{
+ return 0;
+}
+#endif
+
+int spi_frm_align = 2;
+
+/*
+ * SPI padding options.
+ * Warning: must be a base of 2 (& operation used) and can not be zero !
+ */
+int spi_up_head_align = 1 << 1;
+int spi_up_tail_align = 1 << 0;
+int spi_down_head_align = 1 << 2;
+int spi_down_tail_align = 1 << 1;
+
+#ifdef CONFIG_DEBUG_FS
+static inline void debugfs_store_prev(struct cfspi *cfspi)
+{
+ /* Store previous command for debugging reasons.*/
+ cfspi->pcmd = cfspi->cmd;
+ /* Store previous transfer. */
+ cfspi->tx_ppck_len = cfspi->tx_cpck_len;
+ cfspi->rx_ppck_len = cfspi->rx_cpck_len;
+}
+#else
+static inline void debugfs_store_prev(struct cfspi *cfspi)
+{
+}
+#endif
+
+void cfspi_xfer(struct work_struct *work)
+{
+ struct cfspi *cfspi;
+ u8 *ptr = NULL;
+ unsigned long flags;
+ int ret;
+ cfspi = container_of(work, struct cfspi, work);
+
+ /* Initialize state. */
+ cfspi->cmd = SPI_CMD_EOT;
+
+ for (;;) {
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAITING);
+
+ /* Wait for master talk or transmit event. */
+ wait_event_interruptible(cfspi->wait,
+ test_bit(SPI_XFER, &cfspi->state) ||
+ test_bit(SPI_TERMINATE, &cfspi->state));
+
+ if (test_bit(SPI_TERMINATE, &cfspi->state))
+ return;
+
+#if CFSPI_DBG_PREFILL
+ /* Prefill buffers for easier debugging. */
+ memset(cfspi->xfer.va_tx, 0xFF, SPI_DMA_BUF_LEN);
+ memset(cfspi->xfer.va_rx, 0xFF, SPI_DMA_BUF_LEN);
+#endif /* CFSPI_DBG_PREFILL */
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_AWAKE);
+
+ /* Check whether we have a committed frame. */
+ if (cfspi->tx_cpck_len) {
+ int len;
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_FETCH_PKT);
+
+ /* Copy committed SPI frames after the SPI indication. */
+ ptr = (u8 *) cfspi->xfer.va_tx;
+ ptr += SPI_IND_SZ;
+ len = cfspi_xmitfrm(cfspi, ptr, cfspi->tx_cpck_len);
+ WARN_ON(len != cfspi->tx_cpck_len);
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_GET_NEXT);
+
+ /* Get length of next frame to commit. */
+ cfspi->tx_npck_len = cfspi_xmitlen(cfspi);
+
+ WARN_ON(cfspi->tx_npck_len > SPI_DMA_BUF_LEN);
+
+ /*
+ * Add indication and length at the beginning of the frame,
+ * using little endian.
+ */
+ ptr = (u8 *) cfspi->xfer.va_tx;
+ *ptr++ = SPI_CMD_IND;
+ *ptr++ = (SPI_CMD_IND & 0xFF00) >> 8;
+ *ptr++ = cfspi->tx_npck_len & 0x00FF;
+ *ptr++ = (cfspi->tx_npck_len & 0xFF00) >> 8;
+
+ /* Calculate length of DMAs. */
+ cfspi->xfer.tx_dma_len = cfspi->tx_cpck_len + SPI_IND_SZ;
+ cfspi->xfer.rx_dma_len = cfspi->rx_cpck_len + SPI_CMD_SZ;
+
+ /* Add SPI TX frame alignment padding, if necessary. */
+ if (cfspi->tx_cpck_len &&
+ (cfspi->xfer.tx_dma_len % spi_frm_align)) {
+
+ cfspi->xfer.tx_dma_len += spi_frm_align -
+ (cfspi->xfer.tx_dma_len % spi_frm_align);
+ }
+
+ /* Add SPI RX frame alignment padding, if necessary. */
+ if (cfspi->rx_cpck_len &&
+ (cfspi->xfer.rx_dma_len % spi_frm_align)) {
+
+ cfspi->xfer.rx_dma_len += spi_frm_align -
+ (cfspi->xfer.rx_dma_len % spi_frm_align);
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_INIT_XFER);
+
+ /* Start transfer. */
+ ret = cfspi->dev->init_xfer(&cfspi->xfer, cfspi->dev);
+ WARN_ON(ret);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_ACTIVE);
+
+ /*
+ * TODO: We might be able to make an assumption if this is the
+ * first loop. Make sure that minimum toggle time is respected.
+ */
+ udelay(MIN_TRANSITION_TIME_USEC);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_SIG_ACTIVE);
+
+ /* Signal that we are ready to receive data. */
+ cfspi->dev->sig_xfer(true, cfspi->dev);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_XFER_DONE);
+
+ /* Wait for transfer completion. */
+ wait_for_completion(&cfspi->comp);
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_XFER_DONE);
+
+ if (cfspi->cmd == SPI_CMD_EOT) {
+ /*
+ * Clear the master talk bit. A xfer is always at
+ * least two bursts.
+ */
+ clear_bit(SPI_SS_ON, &cfspi->state);
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_INACTIVE);
+
+ /* Make sure that the minimum toggle time is respected. */
+ if (SPI_XFER_TIME_USEC(cfspi->xfer.tx_dma_len,
+ cfspi->dev->clk_mhz) <
+ MIN_TRANSITION_TIME_USEC) {
+
+ udelay(MIN_TRANSITION_TIME_USEC -
+ SPI_XFER_TIME_USEC
+ (cfspi->xfer.tx_dma_len, cfspi->dev->clk_mhz));
+ }
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_SIG_INACTIVE);
+
+ /* De-assert transfer signal. */
+ cfspi->dev->sig_xfer(false, cfspi->dev);
+
+ /* Check whether we received a CAIF packet. */
+ if (cfspi->rx_cpck_len) {
+ int len;
+
+ cfspi_dbg_state(cfspi, CFSPI_STATE_DELIVER_PKT);
+
+ /* Parse SPI frame. */
+ ptr = ((u8 *)(cfspi->xfer.va_rx + SPI_DATA_POS));
+
+ len = cfspi_rxfrm(cfspi, ptr, cfspi->rx_cpck_len);
+ WARN_ON(len != cfspi->rx_cpck_len);
+ }
+
+ /* Check the next SPI command and length. */
+ ptr = (u8 *) cfspi->xfer.va_rx;
+
+ ptr += forward_to_spi_cmd(cfspi);
+
+ cfspi->cmd = *ptr++;
+ cfspi->cmd |= ((*ptr++) << 8) & 0xFF00;
+ cfspi->rx_npck_len = *ptr++;
+ cfspi->rx_npck_len |= ((*ptr++) << 8) & 0xFF00;
+
+ WARN_ON(cfspi->rx_npck_len > SPI_DMA_BUF_LEN);
+ WARN_ON(cfspi->cmd > SPI_CMD_EOT);
+
+ debugfs_store_prev(cfspi);
+
+ /* Check whether the master issued an EOT command. */
+ if (cfspi->cmd == SPI_CMD_EOT) {
+ /* Reset state. */
+ cfspi->tx_cpck_len = 0;
+ cfspi->rx_cpck_len = 0;
+ } else {
+ /* Update state. */
+ cfspi->tx_cpck_len = cfspi->tx_npck_len;
+ cfspi->rx_cpck_len = cfspi->rx_npck_len;
+ }
+
+ /*
+ * Check whether we need to clear the xfer bit.
+ * Spin lock needed for packet insertion.
+ * Test and clear of different bits
+ * are not supported.
+ */
+ spin_lock_irqsave(&cfspi->lock, flags);
+ if (cfspi->cmd == SPI_CMD_EOT && !cfspi_xmitlen(cfspi)
+ && !test_bit(SPI_SS_ON, &cfspi->state))
+ clear_bit(SPI_XFER, &cfspi->state);
+
+ spin_unlock_irqrestore(&cfspi->lock, flags);
+ }
+}
+
+struct platform_driver cfspi_spi_driver = {
+ .probe = cfspi_spi_probe,
+ .remove = cfspi_spi_remove,
+ .driver = {
+ .name = "cfspi_sspi",
+ .owner = THIS_MODULE,
+ },
+};
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c
new file mode 100644
index 00000000000..985608634f8
--- /dev/null
+++ b/drivers/net/caif/caif_virtio.c
@@ -0,0 +1,791 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2013
+ * Authors: Vicram Arv
+ * Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
+ * Sjur Brendeland
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/module.h>
+#include <linux/if_arp.h>
+#include <linux/virtio.h>
+#include <linux/vringh.h>
+#include <linux/debugfs.h>
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_caif.h>
+#include <linux/virtio_ring.h>
+#include <linux/dma-mapping.h>
+#include <net/caif/caif_dev.h>
+#include <linux/virtio_config.h>
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Vicram Arv");
+MODULE_AUTHOR("Sjur Brendeland");
+MODULE_DESCRIPTION("Virtio CAIF Driver");
+
+/* NAPI schedule quota */
+#define CFV_DEFAULT_QUOTA 32
+
+/* Defaults used if virtio config space is unavailable */
+#define CFV_DEF_MTU_SIZE 4096
+#define CFV_DEF_HEADROOM 32
+#define CFV_DEF_TAILROOM 32
+
+/* Required IP header alignment */
+#define IP_HDR_ALIGN 4
+
+/* struct cfv_napi_contxt - NAPI context info
+ * @riov: IOV holding data read from the ring. Note that riov may
+ * still hold data when cfv_rx_poll() returns.
+ * @head: Last descriptor ID we received from vringh_getdesc_kern.
+ * We use this to put descriptor back on the used ring. USHRT_MAX is
+ * used to indicate invalid head-id.
+ */
+struct cfv_napi_context {
+ struct vringh_kiov riov;
+ unsigned short head;
+};
+
+/* struct cfv_stats - statistics for debugfs
+ * @rx_napi_complete: Number of NAPI completions (RX)
+ * @rx_napi_resched: Number of calls where the full quota was used (RX)
+ * @rx_nomem: Number of SKB alloc failures (RX)
+ * @rx_kicks: Number of RX kicks
+ * @tx_full_ring: Number times TX ring was full
+ * @tx_no_mem: Number of times TX went out of memory
+ * @tx_flow_on: Number of flow on (TX)
+ * @tx_kicks: Number of TX kicks
+ */
+struct cfv_stats {
+ u32 rx_napi_complete;
+ u32 rx_napi_resched;
+ u32 rx_nomem;
+ u32 rx_kicks;
+ u32 tx_full_ring;
+ u32 tx_no_mem;
+ u32 tx_flow_on;
+ u32 tx_kicks;
+};
+
+/* struct cfv_info - Caif Virtio control structure
+ * @cfdev: caif common header
+ * @vdev: Associated virtio device
+ * @vr_rx: rx/downlink host vring
+ * @vq_tx: tx/uplink virtqueue
+ * @ndev: CAIF link layer device
+ * @watermark_tx: indicates number of free descriptors we need
+ * to reopen the tx-queues after overload.
+ * @tx_lock: protects vq_tx from concurrent use
+ * @tx_release_tasklet: Tasklet for freeing consumed TX buffers
+ * @napi: Napi context used in cfv_rx_poll()
+ * @ctx: Context data used in cfv_rx_poll()
+ * @tx_hr: transmit headroom
+ * @rx_hr: receive headroom
+ * @tx_tr: transmit tail room
+ * @rx_tr: receive tail room
+ * @mtu: transmit max size
+ * @mru: receive max size
+ * @allocsz: size of dma memory reserved for TX buffers
+ * @alloc_addr: virtual address to dma memory for TX buffers
+ * @alloc_dma: dma address to dma memory for TX buffers
+ * @genpool: Gen Pool used for allocating TX buffers
+ * @reserved_mem: Pointer to memory reserve allocated from genpool
+ * @reserved_size: Size of memory reserve allocated from genpool
+ * @stats: Statistics exposed in sysfs
+ * @debugfs: Debugfs dentry for statistic counters
+ */
+struct cfv_info {
+ struct caif_dev_common cfdev;
+ struct virtio_device *vdev;
+ struct vringh *vr_rx;
+ struct virtqueue *vq_tx;
+ struct net_device *ndev;
+ unsigned int watermark_tx;
+ /* Protect access to vq_tx */
+ spinlock_t tx_lock;
+ struct tasklet_struct tx_release_tasklet;
+ struct napi_struct napi;
+ struct cfv_napi_context ctx;
+ u16 tx_hr;
+ u16 rx_hr;
+ u16 tx_tr;
+ u16 rx_tr;
+ u32 mtu;
+ u32 mru;
+ size_t allocsz;
+ void *alloc_addr;
+ dma_addr_t alloc_dma;
+ struct gen_pool *genpool;
+ unsigned long reserved_mem;
+ size_t reserved_size;
+ struct cfv_stats stats;
+ struct dentry *debugfs;
+};
+
+/* struct buf_info - maintains transmit buffer data handle
+ * @size: size of transmit buffer
+ * @dma_handle: handle to allocated dma device memory area
+ * @vaddr: virtual address mapping to allocated memory area
+ */
+struct buf_info {
+ size_t size;
+ u8 *vaddr;
+};
+
+/* Called from virtio device, in IRQ context */
+static void cfv_release_cb(struct virtqueue *vq_tx)
+{
+ struct cfv_info *cfv = vq_tx->vdev->priv;
+
+ ++cfv->stats.tx_kicks;
+ tasklet_schedule(&cfv->tx_release_tasklet);
+}
+
+static void free_buf_info(struct cfv_info *cfv, struct buf_info *buf_info)
+{
+ if (!buf_info)
+ return;
+ gen_pool_free(cfv->genpool, (unsigned long) buf_info->vaddr,
+ buf_info->size);
+ kfree(buf_info);
+}
+
+/* This is invoked whenever the remote processor completed processing
+ * a TX msg we just sent, and the buffer is put back to the used ring.
+ */
+static void cfv_release_used_buf(struct virtqueue *vq_tx)
+{
+ struct cfv_info *cfv = vq_tx->vdev->priv;
+ unsigned long flags;
+
+ BUG_ON(vq_tx != cfv->vq_tx);
+
+ for (;;) {
+ unsigned int len;
+ struct buf_info *buf_info;
+
+ /* Get used buffer from used ring to recycle used descriptors */
+ spin_lock_irqsave(&cfv->tx_lock, flags);
+ buf_info = virtqueue_get_buf(vq_tx, &len);
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+
+ /* Stop looping if there are no more buffers to free */
+ if (!buf_info)
+ break;
+
+ free_buf_info(cfv, buf_info);
+
+ /* watermark_tx indicates if we previously stopped the tx
+ * queues. If we have enough free stots in the virtio ring,
+ * re-establish memory reserved and open up tx queues.
+ */
+ if (cfv->vq_tx->num_free <= cfv->watermark_tx)
+ continue;
+
+ /* Re-establish memory reserve */
+ if (cfv->reserved_mem == 0 && cfv->genpool)
+ cfv->reserved_mem =
+ gen_pool_alloc(cfv->genpool,
+ cfv->reserved_size);
+
+ /* Open up the tx queues */
+ if (cfv->reserved_mem) {
+ cfv->watermark_tx =
+ virtqueue_get_vring_size(cfv->vq_tx);
+ netif_tx_wake_all_queues(cfv->ndev);
+ /* Buffers are recycled in cfv_netdev_tx, so
+ * disable notifications when queues are opened.
+ */
+ virtqueue_disable_cb(cfv->vq_tx);
+ ++cfv->stats.tx_flow_on;
+ } else {
+ /* if no memory reserve, wait for more free slots */
+ WARN_ON(cfv->watermark_tx >
+ virtqueue_get_vring_size(cfv->vq_tx));
+ cfv->watermark_tx +=
+ virtqueue_get_vring_size(cfv->vq_tx) / 4;
+ }
+ }
+}
+
+/* Allocate a SKB and copy packet data to it */
+static struct sk_buff *cfv_alloc_and_copy_skb(int *err,
+ struct cfv_info *cfv,
+ u8 *frm, u32 frm_len)
+{
+ struct sk_buff *skb;
+ u32 cfpkt_len, pad_len;
+
+ *err = 0;
+ /* Verify that packet size with down-link header and mtu size */
+ if (frm_len > cfv->mru || frm_len <= cfv->rx_hr + cfv->rx_tr) {
+ netdev_err(cfv->ndev,
+ "Invalid frmlen:%u mtu:%u hr:%d tr:%d\n",
+ frm_len, cfv->mru, cfv->rx_hr,
+ cfv->rx_tr);
+ *err = -EPROTO;
+ return NULL;
+ }
+
+ cfpkt_len = frm_len - (cfv->rx_hr + cfv->rx_tr);
+ pad_len = (unsigned long)(frm + cfv->rx_hr) & (IP_HDR_ALIGN - 1);
+
+ skb = netdev_alloc_skb(cfv->ndev, frm_len + pad_len);
+ if (!skb) {
+ *err = -ENOMEM;
+ return NULL;
+ }
+
+ skb_reserve(skb, cfv->rx_hr + pad_len);
+
+ memcpy(skb_put(skb, cfpkt_len), frm + cfv->rx_hr, cfpkt_len);
+ return skb;
+}
+
+/* Get packets from the host vring */
+static int cfv_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct cfv_info *cfv = container_of(napi, struct cfv_info, napi);
+ int rxcnt = 0;
+ int err = 0;
+ void *buf;
+ struct sk_buff *skb;
+ struct vringh_kiov *riov = &cfv->ctx.riov;
+ unsigned int skb_len;
+
+again:
+ do {
+ skb = NULL;
+
+ /* Put the previous iovec back on the used ring and
+ * fetch a new iovec if we have processed all elements.
+ */
+ if (riov->i == riov->used) {
+ if (cfv->ctx.head != USHRT_MAX) {
+ vringh_complete_kern(cfv->vr_rx,
+ cfv->ctx.head,
+ 0);
+ cfv->ctx.head = USHRT_MAX;
+ }
+
+ err = vringh_getdesc_kern(
+ cfv->vr_rx,
+ riov,
+ NULL,
+ &cfv->ctx.head,
+ GFP_ATOMIC);
+
+ if (err <= 0)
+ goto exit;
+ }
+
+ buf = phys_to_virt((unsigned long) riov->iov[riov->i].iov_base);
+ /* TODO: Add check on valid buffer address */
+
+ skb = cfv_alloc_and_copy_skb(&err, cfv, buf,
+ riov->iov[riov->i].iov_len);
+ if (unlikely(err))
+ goto exit;
+
+ /* Push received packet up the stack. */
+ skb_len = skb->len;
+ skb->protocol = htons(ETH_P_CAIF);
+ skb_reset_mac_header(skb);
+ skb->dev = cfv->ndev;
+ err = netif_receive_skb(skb);
+ if (unlikely(err)) {
+ ++cfv->ndev->stats.rx_dropped;
+ } else {
+ ++cfv->ndev->stats.rx_packets;
+ cfv->ndev->stats.rx_bytes += skb_len;
+ }
+
+ ++riov->i;
+ ++rxcnt;
+ } while (rxcnt < quota);
+
+ ++cfv->stats.rx_napi_resched;
+ goto out;
+
+exit:
+ switch (err) {
+ case 0:
+ ++cfv->stats.rx_napi_complete;
+
+ /* Really out of patckets? (stolen from virtio_net)*/
+ napi_complete(napi);
+ if (unlikely(!vringh_notify_enable_kern(cfv->vr_rx)) &&
+ napi_schedule_prep(napi)) {
+ vringh_notify_disable_kern(cfv->vr_rx);
+ __napi_schedule(napi);
+ goto again;
+ }
+ break;
+
+ case -ENOMEM:
+ ++cfv->stats.rx_nomem;
+ dev_kfree_skb(skb);
+ /* Stop NAPI poll on OOM, we hope to be polled later */
+ napi_complete(napi);
+ vringh_notify_enable_kern(cfv->vr_rx);
+ break;
+
+ default:
+ /* We're doomed, any modem fault is fatal */
+ netdev_warn(cfv->ndev, "Bad ring, disable device\n");
+ cfv->ndev->stats.rx_dropped = riov->used - riov->i;
+ napi_complete(napi);
+ vringh_notify_disable_kern(cfv->vr_rx);
+ netif_carrier_off(cfv->ndev);
+ break;
+ }
+out:
+ if (rxcnt && vringh_need_notify_kern(cfv->vr_rx) > 0)
+ vringh_notify(cfv->vr_rx);
+ return rxcnt;
+}
+
+static void cfv_recv(struct virtio_device *vdev, struct vringh *vr_rx)
+{
+ struct cfv_info *cfv = vdev->priv;
+
+ ++cfv->stats.rx_kicks;
+ vringh_notify_disable_kern(cfv->vr_rx);
+ napi_schedule(&cfv->napi);
+}
+
+static void cfv_destroy_genpool(struct cfv_info *cfv)
+{
+ if (cfv->alloc_addr)
+ dma_free_coherent(cfv->vdev->dev.parent->parent,
+ cfv->allocsz, cfv->alloc_addr,
+ cfv->alloc_dma);
+
+ if (!cfv->genpool)
+ return;
+ gen_pool_free(cfv->genpool, cfv->reserved_mem,
+ cfv->reserved_size);
+ gen_pool_destroy(cfv->genpool);
+ cfv->genpool = NULL;
+}
+
+static int cfv_create_genpool(struct cfv_info *cfv)
+{
+ int err;
+
+ /* dma_alloc can only allocate whole pages, and we need a more
+ * fine graned allocation so we use genpool. We ask for space needed
+ * by IP and a full ring. If the dma allcoation fails we retry with a
+ * smaller allocation size.
+ */
+ err = -ENOMEM;
+ cfv->allocsz = (virtqueue_get_vring_size(cfv->vq_tx) *
+ (ETH_DATA_LEN + cfv->tx_hr + cfv->tx_tr) * 11)/10;
+ if (cfv->allocsz <= (num_possible_cpus() + 1) * cfv->ndev->mtu)
+ return -EINVAL;
+
+ for (;;) {
+ if (cfv->allocsz <= num_possible_cpus() * cfv->ndev->mtu) {
+ netdev_info(cfv->ndev, "Not enough device memory\n");
+ return -ENOMEM;
+ }
+
+ cfv->alloc_addr = dma_alloc_coherent(
+ cfv->vdev->dev.parent->parent,
+ cfv->allocsz, &cfv->alloc_dma,
+ GFP_ATOMIC);
+ if (cfv->alloc_addr)
+ break;
+
+ cfv->allocsz = (cfv->allocsz * 3) >> 2;
+ }
+
+ netdev_dbg(cfv->ndev, "Allocated %zd bytes from dma-memory\n",
+ cfv->allocsz);
+
+ /* Allocate on 128 bytes boundaries (1 << 7)*/
+ cfv->genpool = gen_pool_create(7, -1);
+ if (!cfv->genpool)
+ goto err;
+
+ err = gen_pool_add_virt(cfv->genpool, (unsigned long)cfv->alloc_addr,
+ (phys_addr_t)virt_to_phys(cfv->alloc_addr),
+ cfv->allocsz, -1);
+ if (err)
+ goto err;
+
+ /* Reserve some memory for low memory situations. If we hit the roof
+ * in the memory pool, we stop TX flow and release the reserve.
+ */
+ cfv->reserved_size = num_possible_cpus() * cfv->ndev->mtu;
+ cfv->reserved_mem = gen_pool_alloc(cfv->genpool,
+ cfv->reserved_size);
+ if (!cfv->reserved_mem) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx);
+ return 0;
+err:
+ cfv_destroy_genpool(cfv);
+ return err;
+}
+
+/* Enable the CAIF interface and allocate the memory-pool */
+static int cfv_netdev_open(struct net_device *netdev)
+{
+ struct cfv_info *cfv = netdev_priv(netdev);
+
+ if (cfv_create_genpool(cfv))
+ return -ENOMEM;
+
+ netif_carrier_on(netdev);
+ napi_enable(&cfv->napi);
+
+ /* Schedule NAPI to read any pending packets */
+ napi_schedule(&cfv->napi);
+ return 0;
+}
+
+/* Disable the CAIF interface and free the memory-pool */
+static int cfv_netdev_close(struct net_device *netdev)
+{
+ struct cfv_info *cfv = netdev_priv(netdev);
+ unsigned long flags;
+ struct buf_info *buf_info;
+
+ /* Disable interrupts, queues and NAPI polling */
+ netif_carrier_off(netdev);
+ virtqueue_disable_cb(cfv->vq_tx);
+ vringh_notify_disable_kern(cfv->vr_rx);
+ napi_disable(&cfv->napi);
+
+ /* Release any TX buffers on both used and avilable rings */
+ cfv_release_used_buf(cfv->vq_tx);
+ spin_lock_irqsave(&cfv->tx_lock, flags);
+ while ((buf_info = virtqueue_detach_unused_buf(cfv->vq_tx)))
+ free_buf_info(cfv, buf_info);
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+
+ /* Release all dma allocated memory and destroy the pool */
+ cfv_destroy_genpool(cfv);
+ return 0;
+}
+
+/* Allocate a buffer in dma-memory and copy skb to it */
+static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv,
+ struct sk_buff *skb,
+ struct scatterlist *sg)
+{
+ struct caif_payload_info *info = (void *)&skb->cb;
+ struct buf_info *buf_info = NULL;
+ u8 pad_len, hdr_ofs;
+
+ if (!cfv->genpool)
+ goto err;
+
+ if (unlikely(cfv->tx_hr + skb->len + cfv->tx_tr > cfv->mtu)) {
+ netdev_warn(cfv->ndev, "Invalid packet len (%d > %d)\n",
+ cfv->tx_hr + skb->len + cfv->tx_tr, cfv->mtu);
+ goto err;
+ }
+
+ buf_info = kmalloc(sizeof(struct buf_info), GFP_ATOMIC);
+ if (unlikely(!buf_info))
+ goto err;
+
+ /* Make the IP header aligned in tbe buffer */
+ hdr_ofs = cfv->tx_hr + info->hdr_len;
+ pad_len = hdr_ofs & (IP_HDR_ALIGN - 1);
+ buf_info->size = cfv->tx_hr + skb->len + cfv->tx_tr + pad_len;
+
+ /* allocate dma memory buffer */
+ buf_info->vaddr = (void *)gen_pool_alloc(cfv->genpool, buf_info->size);
+ if (unlikely(!buf_info->vaddr))
+ goto err;
+
+ /* copy skbuf contents to send buffer */
+ skb_copy_bits(skb, 0, buf_info->vaddr + cfv->tx_hr + pad_len, skb->len);
+ sg_init_one(sg, buf_info->vaddr + pad_len,
+ skb->len + cfv->tx_hr + cfv->rx_hr);
+
+ return buf_info;
+err:
+ kfree(buf_info);
+ return NULL;
+}
+
+/* Put the CAIF packet on the virtio ring and kick the receiver */
+static int cfv_netdev_tx(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct cfv_info *cfv = netdev_priv(netdev);
+ struct buf_info *buf_info;
+ struct scatterlist sg;
+ unsigned long flags;
+ bool flow_off = false;
+ int ret;
+
+ /* garbage collect released buffers */
+ cfv_release_used_buf(cfv->vq_tx);
+ spin_lock_irqsave(&cfv->tx_lock, flags);
+
+ /* Flow-off check takes into account number of cpus to make sure
+ * virtqueue will not be overfilled in any possible smp conditions.
+ *
+ * Flow-on is triggered when sufficient buffers are freed
+ */
+ if (unlikely(cfv->vq_tx->num_free <= num_present_cpus())) {
+ flow_off = true;
+ cfv->stats.tx_full_ring++;
+ }
+
+ /* If we run out of memory, we release the memory reserve and retry
+ * allocation.
+ */
+ buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
+ if (unlikely(!buf_info)) {
+ cfv->stats.tx_no_mem++;
+ flow_off = true;
+
+ if (cfv->reserved_mem && cfv->genpool) {
+ gen_pool_free(cfv->genpool, cfv->reserved_mem,
+ cfv->reserved_size);
+ cfv->reserved_mem = 0;
+ buf_info = cfv_alloc_and_copy_to_shm(cfv, skb, &sg);
+ }
+ }
+
+ if (unlikely(flow_off)) {
+ /* Turn flow on when a 1/4 of the descriptors are released */
+ cfv->watermark_tx = virtqueue_get_vring_size(cfv->vq_tx) / 4;
+ /* Enable notifications of recycled TX buffers */
+ virtqueue_enable_cb(cfv->vq_tx);
+ netif_tx_stop_all_queues(netdev);
+ }
+
+ if (unlikely(!buf_info)) {
+ /* If the memory reserve does it's job, this shouldn't happen */
+ netdev_warn(cfv->ndev, "Out of gen_pool memory\n");
+ goto err;
+ }
+
+ ret = virtqueue_add_outbuf(cfv->vq_tx, &sg, 1, buf_info, GFP_ATOMIC);
+ if (unlikely((ret < 0))) {
+ /* If flow control works, this shouldn't happen */
+ netdev_warn(cfv->ndev, "Failed adding buffer to TX vring:%d\n",
+ ret);
+ goto err;
+ }
+
+ /* update netdev statistics */
+ cfv->ndev->stats.tx_packets++;
+ cfv->ndev->stats.tx_bytes += skb->len;
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+
+ /* tell the remote processor it has a pending message to read */
+ virtqueue_kick(cfv->vq_tx);
+
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+err:
+ spin_unlock_irqrestore(&cfv->tx_lock, flags);
+ cfv->ndev->stats.tx_dropped++;
+ free_buf_info(cfv, buf_info);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+static void cfv_tx_release_tasklet(unsigned long drv)
+{
+ struct cfv_info *cfv = (struct cfv_info *)drv;
+ cfv_release_used_buf(cfv->vq_tx);
+}
+
+static const struct net_device_ops cfv_netdev_ops = {
+ .ndo_open = cfv_netdev_open,
+ .ndo_stop = cfv_netdev_close,
+ .ndo_start_xmit = cfv_netdev_tx,
+};
+
+static void cfv_netdev_setup(struct net_device *netdev)
+{
+ netdev->netdev_ops = &cfv_netdev_ops;
+ netdev->type = ARPHRD_CAIF;
+ netdev->tx_queue_len = 100;
+ netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ netdev->mtu = CFV_DEF_MTU_SIZE;
+ netdev->destructor = free_netdev;
+}
+
+/* Create debugfs counters for the device */
+static inline void debugfs_init(struct cfv_info *cfv)
+{
+ cfv->debugfs =
+ debugfs_create_dir(netdev_name(cfv->ndev), NULL);
+
+ if (IS_ERR(cfv->debugfs))
+ return;
+
+ debugfs_create_u32("rx-napi-complete", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_napi_complete);
+ debugfs_create_u32("rx-napi-resched", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_napi_resched);
+ debugfs_create_u32("rx-nomem", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_nomem);
+ debugfs_create_u32("rx-kicks", S_IRUSR, cfv->debugfs,
+ &cfv->stats.rx_kicks);
+ debugfs_create_u32("tx-full-ring", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_full_ring);
+ debugfs_create_u32("tx-no-mem", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_no_mem);
+ debugfs_create_u32("tx-kicks", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_kicks);
+ debugfs_create_u32("tx-flow-on", S_IRUSR, cfv->debugfs,
+ &cfv->stats.tx_flow_on);
+}
+
+/* Setup CAIF for the a virtio device */
+static int cfv_probe(struct virtio_device *vdev)
+{
+ vq_callback_t *vq_cbs = cfv_release_cb;
+ vrh_callback_t *vrh_cbs = cfv_recv;
+ const char *names = "output";
+ const char *cfv_netdev_name = "cfvrt";
+ struct net_device *netdev;
+ struct cfv_info *cfv;
+ int err = -EINVAL;
+
+ netdev = alloc_netdev(sizeof(struct cfv_info), cfv_netdev_name,
+ cfv_netdev_setup);
+ if (!netdev)
+ return -ENOMEM;
+
+ cfv = netdev_priv(netdev);
+ cfv->vdev = vdev;
+ cfv->ndev = netdev;
+
+ spin_lock_init(&cfv->tx_lock);
+
+ /* Get the RX virtio ring. This is a "host side vring". */
+ err = -ENODEV;
+ if (!vdev->vringh_config || !vdev->vringh_config->find_vrhs)
+ goto err;
+
+ err = vdev->vringh_config->find_vrhs(vdev, 1, &cfv->vr_rx, &vrh_cbs);
+ if (err)
+ goto err;
+
+ /* Get the TX virtio ring. This is a "guest side vring". */
+ err = vdev->config->find_vqs(vdev, 1, &cfv->vq_tx, &vq_cbs, &names);
+ if (err)
+ goto err;
+
+ /* Get the CAIF configuration from virtio config space, if available */
+ if (vdev->config->get) {
+ virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
+ &cfv->tx_hr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, headroom,
+ &cfv->rx_hr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
+ &cfv->tx_tr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, tailroom,
+ &cfv->rx_tr);
+ virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
+ &cfv->mtu);
+ virtio_cread(vdev, struct virtio_caif_transf_config, mtu,
+ &cfv->mru);
+ } else {
+ cfv->tx_hr = CFV_DEF_HEADROOM;
+ cfv->rx_hr = CFV_DEF_HEADROOM;
+ cfv->tx_tr = CFV_DEF_TAILROOM;
+ cfv->rx_tr = CFV_DEF_TAILROOM;
+ cfv->mtu = CFV_DEF_MTU_SIZE;
+ cfv->mru = CFV_DEF_MTU_SIZE;
+ }
+
+ netdev->needed_headroom = cfv->tx_hr;
+ netdev->needed_tailroom = cfv->tx_tr;
+
+ /* Disable buffer release interrupts unless we have stopped TX queues */
+ virtqueue_disable_cb(cfv->vq_tx);
+
+ netdev->mtu = cfv->mtu - cfv->tx_tr;
+ vdev->priv = cfv;
+
+ /* Initialize NAPI poll context data */
+ vringh_kiov_init(&cfv->ctx.riov, NULL, 0);
+ cfv->ctx.head = USHRT_MAX;
+ netif_napi_add(netdev, &cfv->napi, cfv_rx_poll, CFV_DEFAULT_QUOTA);
+
+ tasklet_init(&cfv->tx_release_tasklet,
+ cfv_tx_release_tasklet,
+ (unsigned long)cfv);
+
+ /* Carrier is off until netdevice is opened */
+ netif_carrier_off(netdev);
+
+ /* register Netdev */
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err);
+ goto err;
+ }
+
+ debugfs_init(cfv);
+
+ return 0;
+err:
+ netdev_warn(cfv->ndev, "CAIF Virtio probe failed:%d\n", err);
+
+ if (cfv->vr_rx)
+ vdev->vringh_config->del_vrhs(cfv->vdev);
+ if (cfv->vdev)
+ vdev->config->del_vqs(cfv->vdev);
+ free_netdev(netdev);
+ return err;
+}
+
+static void cfv_remove(struct virtio_device *vdev)
+{
+ struct cfv_info *cfv = vdev->priv;
+
+ rtnl_lock();
+ dev_close(cfv->ndev);
+ rtnl_unlock();
+
+ tasklet_kill(&cfv->tx_release_tasklet);
+ debugfs_remove_recursive(cfv->debugfs);
+
+ vringh_kiov_cleanup(&cfv->ctx.riov);
+ vdev->config->reset(vdev);
+ vdev->vringh_config->del_vrhs(cfv->vdev);
+ cfv->vr_rx = NULL;
+ vdev->config->del_vqs(cfv->vdev);
+ unregister_netdev(cfv->ndev);
+}
+
+static struct virtio_device_id id_table[] = {
+ { VIRTIO_ID_CAIF, VIRTIO_DEV_ANY_ID },
+ { 0 },
+};
+
+static unsigned int features[] = {
+};
+
+static struct virtio_driver caif_virtio_driver = {
+ .feature_table = features,
+ .feature_table_size = ARRAY_SIZE(features),
+ .driver.name = KBUILD_MODNAME,
+ .driver.owner = THIS_MODULE,
+ .id_table = id_table,
+ .probe = cfv_probe,
+ .remove = cfv_remove,
+};
+
+module_virtio_driver(caif_virtio_driver);
+MODULE_DEVICE_TABLE(virtio, id_table);
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 57def0d5737..41688229c57 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -1,10 +1,7 @@
menu "CAN Device Drivers"
- depends on CAN
config CAN_VCAN
tristate "Virtual Local CAN Interface (vcan)"
- depends on CAN
- default N
---help---
Similar to the network loopback devices, vcan offers a
virtual local CAN interface.
@@ -12,10 +9,152 @@ config CAN_VCAN
This driver can also be built as a module. If so, the module
will be called vcan.
+config CAN_SLCAN
+ tristate "Serial / USB serial CAN Adaptors (slcan)"
+ depends on TTY
+ ---help---
+ CAN driver for several 'low cost' CAN interfaces that are attached
+ via serial lines or via USB-to-serial adapters using the LAWICEL
+ ASCII protocol. The driver implements the tty linediscipline N_SLCAN.
+
+ As only the sending and receiving of CAN frames is implemented, this
+ driver should work with the (serial/USB) CAN hardware from:
+ www.canusb.com / www.can232.com / www.mictronics.de / www.canhack.de
+
+ Userspace tools to attach the SLCAN line discipline (slcan_attach,
+ slcand) can be found in the can-utils at the SocketCAN SVN, see
+ http://developer.berlios.de/projects/socketcan for details.
+
+ The slcan driver supports up to 10 CAN netdevices by default which
+ can be changed by the 'maxdev=xx' module option. This driver can
+ also be built as a module. If so, the module will be called slcan.
+
+config CAN_DEV
+ tristate "Platform CAN drivers with Netlink support"
+ default y
+ ---help---
+ Enables the common framework for platform CAN drivers with Netlink
+ support. This is the standard library for CAN drivers.
+ If unsure, say Y.
+
+if CAN_DEV
+
+config CAN_CALC_BITTIMING
+ bool "CAN bit-timing calculation"
+ default y
+ ---help---
+ If enabled, CAN bit-timing parameters will be calculated for the
+ bit-rate specified via Netlink argument "bitrate" when the device
+ get started. This works fine for the most common CAN controllers
+ with standard bit-rates but may fail for exotic bit-rates or CAN
+ source clock frequencies. Disabling saves some space, but then the
+ bit-timing parameters must be specified directly using the Netlink
+ arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw".
+ If unsure, say Y.
+
+config CAN_LEDS
+ bool "Enable LED triggers for Netlink based drivers"
+ depends on LEDS_CLASS
+ select LEDS_TRIGGERS
+ ---help---
+ This option adds two LED triggers for packet receive and transmit
+ events on each supported CAN device.
+
+ Say Y here if you are working on a system with led-class supported
+ LEDs and you want to use them as canbus activity indicators.
+
+config CAN_AT91
+ tristate "Atmel AT91 onchip CAN controller"
+ depends on ARCH_AT91 || COMPILE_TEST
+ ---help---
+ This is a driver for the SoC CAN controller in Atmel's AT91SAM9263
+ and AT91SAM9X5 processors.
+
+config CAN_TI_HECC
+ depends on ARM
+ tristate "TI High End CAN Controller"
+ ---help---
+ Driver for TI HECC (High End CAN Controller) module found on many
+ TI devices. The device specifications are available from www.ti.com
+
+config CAN_BFIN
+ depends on BF534 || BF536 || BF537 || BF538 || BF539 || BF54x
+ tristate "Analog Devices Blackfin on-chip CAN"
+ ---help---
+ Driver for the Analog Devices Blackfin on-chip CAN controllers
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin_can.
+
+config CAN_JANZ_ICAN3
+ tristate "Janz VMOD-ICAN3 Intelligent CAN controller"
+ depends on MFD_JANZ_CMODIO
+ ---help---
+ Driver for Janz VMOD-ICAN3 Intelligent CAN controller module, which
+ connects to a MODULbus carrier board.
+
+ This driver can also be built as a module. If so, the module will be
+ called janz-ican3.ko.
+
+config CAN_FLEXCAN
+ tristate "Support for Freescale FLEXCAN based chips"
+ depends on ARM || PPC
+ ---help---
+ Say Y here if you want to support for Freescale FlexCAN.
+
+config PCH_CAN
+ tristate "Intel EG20T PCH CAN controller"
+ depends on PCI && (X86_32 || COMPILE_TEST)
+ ---help---
+ This driver is for PCH CAN of Topcliff (Intel EG20T PCH) which
+ is an IOH for x86 embedded processor (Intel Atom E6xx series).
+ This driver can access CAN bus.
+
+config CAN_GRCAN
+ tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
+ depends on OF
+ ---help---
+ Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
+ Note that the driver supports little endian, even though little
+ endian syntheses of the cores would need some modifications on
+ the hardware level to work.
+
+config CAN_RCAR
+ tristate "Renesas R-Car CAN controller"
+ depends on ARM
+ ---help---
+ Say Y here if you want to use CAN controller found on Renesas R-Car
+ SoCs.
+
+ To compile this driver as a module, choose M here: the module will
+ be called rcar_can.
+
+config CAN_XILINXCAN
+ tristate "Xilinx CAN"
+ depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
+ depends on COMMON_CLK && HAS_IOMEM
+ ---help---
+ Xilinx CAN driver. This driver supports both soft AXI CAN IP and
+ Zynq CANPS IP.
+
+source "drivers/net/can/mscan/Kconfig"
+
+source "drivers/net/can/sja1000/Kconfig"
+
+source "drivers/net/can/c_can/Kconfig"
+
+source "drivers/net/can/cc770/Kconfig"
+
+source "drivers/net/can/spi/Kconfig"
+
+source "drivers/net/can/usb/Kconfig"
+
+source "drivers/net/can/softing/Kconfig"
+
+endif
+
config CAN_DEBUG_DEVICES
bool "CAN devices debugging messages"
- depends on CAN
- default N
---help---
Say Y here if you want the CAN device drivers to produce a bunch of
debug messages to the system log. Select this if you are having
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index c4bead705cd..1697f22353a 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -3,3 +3,29 @@
#
obj-$(CONFIG_CAN_VCAN) += vcan.o
+obj-$(CONFIG_CAN_SLCAN) += slcan.o
+
+obj-$(CONFIG_CAN_DEV) += can-dev.o
+can-dev-y := dev.o
+
+can-dev-$(CONFIG_CAN_LEDS) += led.o
+
+obj-y += spi/
+obj-y += usb/
+obj-y += softing/
+
+obj-$(CONFIG_CAN_SJA1000) += sja1000/
+obj-$(CONFIG_CAN_MSCAN) += mscan/
+obj-$(CONFIG_CAN_C_CAN) += c_can/
+obj-$(CONFIG_CAN_CC770) += cc770/
+obj-$(CONFIG_CAN_AT91) += at91_can.o
+obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
+obj-$(CONFIG_CAN_BFIN) += bfin_can.o
+obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
+obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
+obj-$(CONFIG_PCH_CAN) += pch_can.o
+obj-$(CONFIG_CAN_GRCAN) += grcan.o
+obj-$(CONFIG_CAN_RCAR) += rcar_can.o
+obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
new file mode 100644
index 00000000000..f07fa89b5fd
--- /dev/null
+++ b/drivers/net/can/at91_can.c
@@ -0,0 +1,1439 @@
+/*
+ * at91_can.c - CAN network driver for AT91 SoC CAN controller
+ *
+ * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
+ * (C) 2008, 2009, 2010, 2011 by Marc Kleine-Budde <kernel@pengutronix.de>
+ *
+ * This software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2 as distributed in the 'COPYING'
+ * file from the main directory of the linux kernel source.
+ *
+ *
+ * Your platform definition file should specify something like:
+ *
+ * static struct at91_can_data ek_can_data = {
+ * transceiver_switch = sam9263ek_transceiver_switch,
+ * };
+ *
+ * at91_add_device_can(&ek_can_data);
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/rtnetlink.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/platform_data/atmel.h>
+
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+
+#define AT91_MB_MASK(i) ((1 << (i)) - 1)
+
+/* Common registers */
+enum at91_reg {
+ AT91_MR = 0x000,
+ AT91_IER = 0x004,
+ AT91_IDR = 0x008,
+ AT91_IMR = 0x00C,
+ AT91_SR = 0x010,
+ AT91_BR = 0x014,
+ AT91_TIM = 0x018,
+ AT91_TIMESTP = 0x01C,
+ AT91_ECR = 0x020,
+ AT91_TCR = 0x024,
+ AT91_ACR = 0x028,
+};
+
+/* Mailbox registers (0 <= i <= 15) */
+#define AT91_MMR(i) (enum at91_reg)(0x200 + ((i) * 0x20))
+#define AT91_MAM(i) (enum at91_reg)(0x204 + ((i) * 0x20))
+#define AT91_MID(i) (enum at91_reg)(0x208 + ((i) * 0x20))
+#define AT91_MFID(i) (enum at91_reg)(0x20C + ((i) * 0x20))
+#define AT91_MSR(i) (enum at91_reg)(0x210 + ((i) * 0x20))
+#define AT91_MDL(i) (enum at91_reg)(0x214 + ((i) * 0x20))
+#define AT91_MDH(i) (enum at91_reg)(0x218 + ((i) * 0x20))
+#define AT91_MCR(i) (enum at91_reg)(0x21C + ((i) * 0x20))
+
+/* Register bits */
+#define AT91_MR_CANEN BIT(0)
+#define AT91_MR_LPM BIT(1)
+#define AT91_MR_ABM BIT(2)
+#define AT91_MR_OVL BIT(3)
+#define AT91_MR_TEOF BIT(4)
+#define AT91_MR_TTM BIT(5)
+#define AT91_MR_TIMFRZ BIT(6)
+#define AT91_MR_DRPT BIT(7)
+
+#define AT91_SR_RBSY BIT(29)
+
+#define AT91_MMR_PRIO_SHIFT (16)
+
+#define AT91_MID_MIDE BIT(29)
+
+#define AT91_MSR_MRTR BIT(20)
+#define AT91_MSR_MABT BIT(22)
+#define AT91_MSR_MRDY BIT(23)
+#define AT91_MSR_MMI BIT(24)
+
+#define AT91_MCR_MRTR BIT(20)
+#define AT91_MCR_MTCR BIT(23)
+
+/* Mailbox Modes */
+enum at91_mb_mode {
+ AT91_MB_MODE_DISABLED = 0,
+ AT91_MB_MODE_RX = 1,
+ AT91_MB_MODE_RX_OVRWR = 2,
+ AT91_MB_MODE_TX = 3,
+ AT91_MB_MODE_CONSUMER = 4,
+ AT91_MB_MODE_PRODUCER = 5,
+};
+
+/* Interrupt mask bits */
+#define AT91_IRQ_ERRA (1 << 16)
+#define AT91_IRQ_WARN (1 << 17)
+#define AT91_IRQ_ERRP (1 << 18)
+#define AT91_IRQ_BOFF (1 << 19)
+#define AT91_IRQ_SLEEP (1 << 20)
+#define AT91_IRQ_WAKEUP (1 << 21)
+#define AT91_IRQ_TOVF (1 << 22)
+#define AT91_IRQ_TSTP (1 << 23)
+#define AT91_IRQ_CERR (1 << 24)
+#define AT91_IRQ_SERR (1 << 25)
+#define AT91_IRQ_AERR (1 << 26)
+#define AT91_IRQ_FERR (1 << 27)
+#define AT91_IRQ_BERR (1 << 28)
+
+#define AT91_IRQ_ERR_ALL (0x1fff0000)
+#define AT91_IRQ_ERR_FRAME (AT91_IRQ_CERR | AT91_IRQ_SERR | \
+ AT91_IRQ_AERR | AT91_IRQ_FERR | AT91_IRQ_BERR)
+#define AT91_IRQ_ERR_LINE (AT91_IRQ_ERRA | AT91_IRQ_WARN | \
+ AT91_IRQ_ERRP | AT91_IRQ_BOFF)
+
+#define AT91_IRQ_ALL (0x1fffffff)
+
+enum at91_devtype {
+ AT91_DEVTYPE_SAM9263,
+ AT91_DEVTYPE_SAM9X5,
+};
+
+struct at91_devtype_data {
+ unsigned int rx_first;
+ unsigned int rx_split;
+ unsigned int rx_last;
+ unsigned int tx_shift;
+ enum at91_devtype type;
+};
+
+struct at91_priv {
+ struct can_priv can; /* must be the first member! */
+ struct net_device *dev;
+ struct napi_struct napi;
+
+ void __iomem *reg_base;
+
+ u32 reg_sr;
+ unsigned int tx_next;
+ unsigned int tx_echo;
+ unsigned int rx_next;
+ struct at91_devtype_data devtype_data;
+
+ struct clk *clk;
+ struct at91_can_data *pdata;
+
+ canid_t mb0_id;
+};
+
+static const struct at91_devtype_data at91_at91sam9263_data = {
+ .rx_first = 1,
+ .rx_split = 8,
+ .rx_last = 11,
+ .tx_shift = 2,
+ .type = AT91_DEVTYPE_SAM9263,
+};
+
+static const struct at91_devtype_data at91_at91sam9x5_data = {
+ .rx_first = 0,
+ .rx_split = 4,
+ .rx_last = 5,
+ .tx_shift = 1,
+ .type = AT91_DEVTYPE_SAM9X5,
+};
+
+static const struct can_bittiming_const at91_bittiming_const = {
+ .name = KBUILD_MODNAME,
+ .tseg1_min = 4,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 2,
+ .brp_max = 128,
+ .brp_inc = 1,
+};
+
+#define AT91_IS(_model) \
+static inline int at91_is_sam##_model(const struct at91_priv *priv) \
+{ \
+ return priv->devtype_data.type == AT91_DEVTYPE_SAM##_model; \
+}
+
+AT91_IS(9263);
+AT91_IS(9X5);
+
+static inline unsigned int get_mb_rx_first(const struct at91_priv *priv)
+{
+ return priv->devtype_data.rx_first;
+}
+
+static inline unsigned int get_mb_rx_last(const struct at91_priv *priv)
+{
+ return priv->devtype_data.rx_last;
+}
+
+static inline unsigned int get_mb_rx_split(const struct at91_priv *priv)
+{
+ return priv->devtype_data.rx_split;
+}
+
+static inline unsigned int get_mb_rx_num(const struct at91_priv *priv)
+{
+ return get_mb_rx_last(priv) - get_mb_rx_first(priv) + 1;
+}
+
+static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv)
+{
+ return get_mb_rx_split(priv) - 1;
+}
+
+static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv)
+{
+ return AT91_MB_MASK(get_mb_rx_split(priv)) &
+ ~AT91_MB_MASK(get_mb_rx_first(priv));
+}
+
+static inline unsigned int get_mb_tx_shift(const struct at91_priv *priv)
+{
+ return priv->devtype_data.tx_shift;
+}
+
+static inline unsigned int get_mb_tx_num(const struct at91_priv *priv)
+{
+ return 1 << get_mb_tx_shift(priv);
+}
+
+static inline unsigned int get_mb_tx_first(const struct at91_priv *priv)
+{
+ return get_mb_rx_last(priv) + 1;
+}
+
+static inline unsigned int get_mb_tx_last(const struct at91_priv *priv)
+{
+ return get_mb_tx_first(priv) + get_mb_tx_num(priv) - 1;
+}
+
+static inline unsigned int get_next_prio_shift(const struct at91_priv *priv)
+{
+ return get_mb_tx_shift(priv);
+}
+
+static inline unsigned int get_next_prio_mask(const struct at91_priv *priv)
+{
+ return 0xf << get_mb_tx_shift(priv);
+}
+
+static inline unsigned int get_next_mb_mask(const struct at91_priv *priv)
+{
+ return AT91_MB_MASK(get_mb_tx_shift(priv));
+}
+
+static inline unsigned int get_next_mask(const struct at91_priv *priv)
+{
+ return get_next_mb_mask(priv) | get_next_prio_mask(priv);
+}
+
+static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv)
+{
+ return AT91_MB_MASK(get_mb_rx_last(priv) + 1) &
+ ~AT91_MB_MASK(get_mb_rx_first(priv));
+}
+
+static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv)
+{
+ return AT91_MB_MASK(get_mb_tx_last(priv) + 1) &
+ ~AT91_MB_MASK(get_mb_tx_first(priv));
+}
+
+static inline unsigned int get_tx_next_mb(const struct at91_priv *priv)
+{
+ return (priv->tx_next & get_next_mb_mask(priv)) + get_mb_tx_first(priv);
+}
+
+static inline unsigned int get_tx_next_prio(const struct at91_priv *priv)
+{
+ return (priv->tx_next >> get_next_prio_shift(priv)) & 0xf;
+}
+
+static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv)
+{
+ return (priv->tx_echo & get_next_mb_mask(priv)) + get_mb_tx_first(priv);
+}
+
+static inline u32 at91_read(const struct at91_priv *priv, enum at91_reg reg)
+{
+ return __raw_readl(priv->reg_base + reg);
+}
+
+static inline void at91_write(const struct at91_priv *priv, enum at91_reg reg,
+ u32 value)
+{
+ __raw_writel(value, priv->reg_base + reg);
+}
+
+static inline void set_mb_mode_prio(const struct at91_priv *priv,
+ unsigned int mb, enum at91_mb_mode mode, int prio)
+{
+ at91_write(priv, AT91_MMR(mb), (mode << 24) | (prio << 16));
+}
+
+static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb,
+ enum at91_mb_mode mode)
+{
+ set_mb_mode_prio(priv, mb, mode, 0);
+}
+
+static inline u32 at91_can_id_to_reg_mid(canid_t can_id)
+{
+ u32 reg_mid;
+
+ if (can_id & CAN_EFF_FLAG)
+ reg_mid = (can_id & CAN_EFF_MASK) | AT91_MID_MIDE;
+ else
+ reg_mid = (can_id & CAN_SFF_MASK) << 18;
+
+ return reg_mid;
+}
+
+/*
+ * Swtich transceiver on or off
+ */
+static void at91_transceiver_switch(const struct at91_priv *priv, int on)
+{
+ if (priv->pdata && priv->pdata->transceiver_switch)
+ priv->pdata->transceiver_switch(on);
+}
+
+static void at91_setup_mailboxes(struct net_device *dev)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ unsigned int i;
+ u32 reg_mid;
+
+ /*
+ * Due to a chip bug (errata 50.2.6.3 & 50.3.5.3) the first
+ * mailbox is disabled. The next 11 mailboxes are used as a
+ * reception FIFO. The last mailbox is configured with
+ * overwrite option. The overwrite flag indicates a FIFO
+ * overflow.
+ */
+ reg_mid = at91_can_id_to_reg_mid(priv->mb0_id);
+ for (i = 0; i < get_mb_rx_first(priv); i++) {
+ set_mb_mode(priv, i, AT91_MB_MODE_DISABLED);
+ at91_write(priv, AT91_MID(i), reg_mid);
+ at91_write(priv, AT91_MCR(i), 0x0); /* clear dlc */
+ }
+
+ for (i = get_mb_rx_first(priv); i < get_mb_rx_last(priv); i++)
+ set_mb_mode(priv, i, AT91_MB_MODE_RX);
+ set_mb_mode(priv, get_mb_rx_last(priv), AT91_MB_MODE_RX_OVRWR);
+
+ /* reset acceptance mask and id register */
+ for (i = get_mb_rx_first(priv); i <= get_mb_rx_last(priv); i++) {
+ at91_write(priv, AT91_MAM(i), 0x0);
+ at91_write(priv, AT91_MID(i), AT91_MID_MIDE);
+ }
+
+ /* The last 4 mailboxes are used for transmitting. */
+ for (i = get_mb_tx_first(priv); i <= get_mb_tx_last(priv); i++)
+ set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
+
+ /* Reset tx and rx helper pointers */
+ priv->tx_next = priv->tx_echo = 0;
+ priv->rx_next = get_mb_rx_first(priv);
+}
+
+static int at91_set_bittiming(struct net_device *dev)
+{
+ const struct at91_priv *priv = netdev_priv(dev);
+ const struct can_bittiming *bt = &priv->can.bittiming;
+ u32 reg_br;
+
+ reg_br = ((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 << 24 : 0) |
+ ((bt->brp - 1) << 16) | ((bt->sjw - 1) << 12) |
+ ((bt->prop_seg - 1) << 8) | ((bt->phase_seg1 - 1) << 4) |
+ ((bt->phase_seg2 - 1) << 0);
+
+ netdev_info(dev, "writing AT91_BR: 0x%08x\n", reg_br);
+
+ at91_write(priv, AT91_BR, reg_br);
+
+ return 0;
+}
+
+static int at91_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ const struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_ecr = at91_read(priv, AT91_ECR);
+
+ bec->rxerr = reg_ecr & 0xff;
+ bec->txerr = reg_ecr >> 16;
+
+ return 0;
+}
+
+static void at91_chip_start(struct net_device *dev)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_mr, reg_ier;
+
+ /* disable interrupts */
+ at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
+
+ /* disable chip */
+ reg_mr = at91_read(priv, AT91_MR);
+ at91_write(priv, AT91_MR, reg_mr & ~AT91_MR_CANEN);
+
+ at91_set_bittiming(dev);
+ at91_setup_mailboxes(dev);
+ at91_transceiver_switch(priv, 1);
+
+ /* enable chip */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ reg_mr = AT91_MR_CANEN | AT91_MR_ABM;
+ else
+ reg_mr = AT91_MR_CANEN;
+ at91_write(priv, AT91_MR, reg_mr);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ /* Enable interrupts */
+ reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
+ at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
+ at91_write(priv, AT91_IER, reg_ier);
+}
+
+static void at91_chip_stop(struct net_device *dev, enum can_state state)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_mr;
+
+ /* disable interrupts */
+ at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
+
+ reg_mr = at91_read(priv, AT91_MR);
+ at91_write(priv, AT91_MR, reg_mr & ~AT91_MR_CANEN);
+
+ at91_transceiver_switch(priv, 0);
+ priv->can.state = state;
+}
+
+/*
+ * theory of operation:
+ *
+ * According to the datasheet priority 0 is the highest priority, 15
+ * is the lowest. If two mailboxes have the same priority level the
+ * message of the mailbox with the lowest number is sent first.
+ *
+ * We use the first TX mailbox (AT91_MB_TX_FIRST) with prio 0, then
+ * the next mailbox with prio 0, and so on, until all mailboxes are
+ * used. Then we start from the beginning with mailbox
+ * AT91_MB_TX_FIRST, but with prio 1, mailbox AT91_MB_TX_FIRST + 1
+ * prio 1. When we reach the last mailbox with prio 15, we have to
+ * stop sending, waiting for all messages to be delivered, then start
+ * again with mailbox AT91_MB_TX_FIRST prio 0.
+ *
+ * We use the priv->tx_next as counter for the next transmission
+ * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits
+ * encode the mailbox number, the upper 4 bits the mailbox priority:
+ *
+ * priv->tx_next = (prio << get_next_prio_shift(priv)) |
+ * (mb - get_mb_tx_first(priv));
+ *
+ */
+static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ unsigned int mb, prio;
+ u32 reg_mid, reg_mcr;
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ mb = get_tx_next_mb(priv);
+ prio = get_tx_next_prio(priv);
+
+ if (unlikely(!(at91_read(priv, AT91_MSR(mb)) & AT91_MSR_MRDY))) {
+ netif_stop_queue(dev);
+
+ netdev_err(dev, "BUG! TX buffer full when queue awake!\n");
+ return NETDEV_TX_BUSY;
+ }
+ reg_mid = at91_can_id_to_reg_mid(cf->can_id);
+ reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) |
+ (cf->can_dlc << 16) | AT91_MCR_MTCR;
+
+ /* disable MB while writing ID (see datasheet) */
+ set_mb_mode(priv, mb, AT91_MB_MODE_DISABLED);
+ at91_write(priv, AT91_MID(mb), reg_mid);
+ set_mb_mode_prio(priv, mb, AT91_MB_MODE_TX, prio);
+
+ at91_write(priv, AT91_MDL(mb), *(u32 *)(cf->data + 0));
+ at91_write(priv, AT91_MDH(mb), *(u32 *)(cf->data + 4));
+
+ /* This triggers transmission */
+ at91_write(priv, AT91_MCR(mb), reg_mcr);
+
+ stats->tx_bytes += cf->can_dlc;
+
+ /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */
+ can_put_echo_skb(skb, dev, mb - get_mb_tx_first(priv));
+
+ /*
+ * we have to stop the queue and deliver all messages in case
+ * of a prio+mb counter wrap around. This is the case if
+ * tx_next buffer prio and mailbox equals 0.
+ *
+ * also stop the queue if next buffer is still in use
+ * (== not ready)
+ */
+ priv->tx_next++;
+ if (!(at91_read(priv, AT91_MSR(get_tx_next_mb(priv))) &
+ AT91_MSR_MRDY) ||
+ (priv->tx_next & get_next_mask(priv)) == 0)
+ netif_stop_queue(dev);
+
+ /* Enable interrupt for this mailbox */
+ at91_write(priv, AT91_IER, 1 << mb);
+
+ return NETDEV_TX_OK;
+}
+
+/**
+ * at91_activate_rx_low - activate lower rx mailboxes
+ * @priv: a91 context
+ *
+ * Reenables the lower mailboxes for reception of new CAN messages
+ */
+static inline void at91_activate_rx_low(const struct at91_priv *priv)
+{
+ u32 mask = get_mb_rx_low_mask(priv);
+ at91_write(priv, AT91_TCR, mask);
+}
+
+/**
+ * at91_activate_rx_mb - reactive single rx mailbox
+ * @priv: a91 context
+ * @mb: mailbox to reactivate
+ *
+ * Reenables given mailbox for reception of new CAN messages
+ */
+static inline void at91_activate_rx_mb(const struct at91_priv *priv,
+ unsigned int mb)
+{
+ u32 mask = 1 << mb;
+ at91_write(priv, AT91_TCR, mask);
+}
+
+/**
+ * at91_rx_overflow_err - send error frame due to rx overflow
+ * @dev: net device
+ */
+static void at91_rx_overflow_err(struct net_device *dev)
+{
+ struct net_device_stats *stats = &dev->stats;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ netdev_dbg(dev, "RX buffer overflow\n");
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+ return;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ netif_receive_skb(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+/**
+ * at91_read_mb - read CAN msg from mailbox (lowlevel impl)
+ * @dev: net device
+ * @mb: mailbox number to read from
+ * @cf: can frame where to store message
+ *
+ * Reads a CAN message from the given mailbox and stores data into
+ * given can frame. "mb" and "cf" must be valid.
+ */
+static void at91_read_mb(struct net_device *dev, unsigned int mb,
+ struct can_frame *cf)
+{
+ const struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_msr, reg_mid;
+
+ reg_mid = at91_read(priv, AT91_MID(mb));
+ if (reg_mid & AT91_MID_MIDE)
+ cf->can_id = ((reg_mid >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ else
+ cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK;
+
+ reg_msr = at91_read(priv, AT91_MSR(mb));
+ cf->can_dlc = get_can_dlc((reg_msr >> 16) & 0xf);
+
+ if (reg_msr & AT91_MSR_MRTR)
+ cf->can_id |= CAN_RTR_FLAG;
+ else {
+ *(u32 *)(cf->data + 0) = at91_read(priv, AT91_MDL(mb));
+ *(u32 *)(cf->data + 4) = at91_read(priv, AT91_MDH(mb));
+ }
+
+ /* allow RX of extended frames */
+ at91_write(priv, AT91_MID(mb), AT91_MID_MIDE);
+
+ if (unlikely(mb == get_mb_rx_last(priv) && reg_msr & AT91_MSR_MMI))
+ at91_rx_overflow_err(dev);
+}
+
+/**
+ * at91_read_msg - read CAN message from mailbox
+ * @dev: net device
+ * @mb: mail box to read from
+ *
+ * Reads a CAN message from given mailbox, and put into linux network
+ * RX queue, does all housekeeping chores (stats, ...)
+ */
+static void at91_read_msg(struct net_device *dev, unsigned int mb)
+{
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+
+ skb = alloc_can_skb(dev, &cf);
+ if (unlikely(!skb)) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ at91_read_mb(dev, mb, cf);
+ netif_receive_skb(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ can_led_event(dev, CAN_LED_EVENT_RX);
+}
+
+/**
+ * at91_poll_rx - read multiple CAN messages from mailboxes
+ * @dev: net device
+ * @quota: max number of pkgs we're allowed to receive
+ *
+ * Theory of Operation:
+ *
+ * About 3/4 of the mailboxes (get_mb_rx_first()...get_mb_rx_last())
+ * on the chip are reserved for RX. We split them into 2 groups. The
+ * lower group ranges from get_mb_rx_first() to get_mb_rx_low_last().
+ *
+ * Like it or not, but the chip always saves a received CAN message
+ * into the first free mailbox it finds (starting with the
+ * lowest). This makes it very difficult to read the messages in the
+ * right order from the chip. This is how we work around that problem:
+ *
+ * The first message goes into mb nr. 1 and issues an interrupt. All
+ * rx ints are disabled in the interrupt handler and a napi poll is
+ * scheduled. We read the mailbox, but do _not_ reenable the mb (to
+ * receive another message).
+ *
+ * lower mbxs upper
+ * ____^______ __^__
+ * / \ / \
+ * +-+-+-+-+-+-+-+-++-+-+-+-+
+ * | |x|x|x|x|x|x|x|| | | | |
+ * +-+-+-+-+-+-+-+-++-+-+-+-+
+ * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail
+ * 0 1 2 3 4 5 6 7 8 9 0 1 / box
+ * ^
+ * |
+ * \
+ * unused, due to chip bug
+ *
+ * The variable priv->rx_next points to the next mailbox to read a
+ * message from. As long we're in the lower mailboxes we just read the
+ * mailbox but not reenable it.
+ *
+ * With completion of the last of the lower mailboxes, we reenable the
+ * whole first group, but continue to look for filled mailboxes in the
+ * upper mailboxes. Imagine the second group like overflow mailboxes,
+ * which takes CAN messages if the lower goup is full. While in the
+ * upper group we reenable the mailbox right after reading it. Giving
+ * the chip more room to store messages.
+ *
+ * After finishing we look again in the lower group if we've still
+ * quota.
+ *
+ */
+static int at91_poll_rx(struct net_device *dev, int quota)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_sr = at91_read(priv, AT91_SR);
+ const unsigned long *addr = (unsigned long *)&reg_sr;
+ unsigned int mb;
+ int received = 0;
+
+ if (priv->rx_next > get_mb_rx_low_last(priv) &&
+ reg_sr & get_mb_rx_low_mask(priv))
+ netdev_info(dev,
+ "order of incoming frames cannot be guaranteed\n");
+
+ again:
+ for (mb = find_next_bit(addr, get_mb_tx_first(priv), priv->rx_next);
+ mb < get_mb_tx_first(priv) && quota > 0;
+ reg_sr = at91_read(priv, AT91_SR),
+ mb = find_next_bit(addr, get_mb_tx_first(priv), ++priv->rx_next)) {
+ at91_read_msg(dev, mb);
+
+ /* reactivate mailboxes */
+ if (mb == get_mb_rx_low_last(priv))
+ /* all lower mailboxed, if just finished it */
+ at91_activate_rx_low(priv);
+ else if (mb > get_mb_rx_low_last(priv))
+ /* only the mailbox we read */
+ at91_activate_rx_mb(priv, mb);
+
+ received++;
+ quota--;
+ }
+
+ /* upper group completed, look again in lower */
+ if (priv->rx_next > get_mb_rx_low_last(priv) &&
+ quota > 0 && mb > get_mb_rx_last(priv)) {
+ priv->rx_next = get_mb_rx_first(priv);
+ goto again;
+ }
+
+ return received;
+}
+
+static void at91_poll_err_frame(struct net_device *dev,
+ struct can_frame *cf, u32 reg_sr)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+
+ /* CRC error */
+ if (reg_sr & AT91_IRQ_CERR) {
+ netdev_dbg(dev, "CERR irq\n");
+ dev->stats.rx_errors++;
+ priv->can.can_stats.bus_error++;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ }
+
+ /* Stuffing Error */
+ if (reg_sr & AT91_IRQ_SERR) {
+ netdev_dbg(dev, "SERR irq\n");
+ dev->stats.rx_errors++;
+ priv->can.can_stats.bus_error++;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ }
+
+ /* Acknowledgement Error */
+ if (reg_sr & AT91_IRQ_AERR) {
+ netdev_dbg(dev, "AERR irq\n");
+ dev->stats.tx_errors++;
+ cf->can_id |= CAN_ERR_ACK;
+ }
+
+ /* Form error */
+ if (reg_sr & AT91_IRQ_FERR) {
+ netdev_dbg(dev, "FERR irq\n");
+ dev->stats.rx_errors++;
+ priv->can.can_stats.bus_error++;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ }
+
+ /* Bit Error */
+ if (reg_sr & AT91_IRQ_BERR) {
+ netdev_dbg(dev, "BERR irq\n");
+ dev->stats.tx_errors++;
+ priv->can.can_stats.bus_error++;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ }
+}
+
+static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
+{
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ if (quota == 0)
+ return 0;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+ return 0;
+
+ at91_poll_err_frame(dev, cf, reg_sr);
+ netif_receive_skb(skb);
+
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += cf->can_dlc;
+
+ return 1;
+}
+
+static int at91_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *dev = napi->dev;
+ const struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_sr = at91_read(priv, AT91_SR);
+ int work_done = 0;
+
+ if (reg_sr & get_irq_mb_rx(priv))
+ work_done += at91_poll_rx(dev, quota - work_done);
+
+ /*
+ * The error bits are clear on read,
+ * so use saved value from irq handler.
+ */
+ reg_sr |= priv->reg_sr;
+ if (reg_sr & AT91_IRQ_ERR_FRAME)
+ work_done += at91_poll_err(dev, quota - work_done, reg_sr);
+
+ if (work_done < quota) {
+ /* enable IRQs for frame errors and all mailboxes >= rx_next */
+ u32 reg_ier = AT91_IRQ_ERR_FRAME;
+ reg_ier |= get_irq_mb_rx(priv) & ~AT91_MB_MASK(priv->rx_next);
+
+ napi_complete(napi);
+ at91_write(priv, AT91_IER, reg_ier);
+ }
+
+ return work_done;
+}
+
+/*
+ * theory of operation:
+ *
+ * priv->tx_echo holds the number of the oldest can_frame put for
+ * transmission into the hardware, but not yet ACKed by the CAN tx
+ * complete IRQ.
+ *
+ * We iterate from priv->tx_echo to priv->tx_next and check if the
+ * packet has been transmitted, echo it back to the CAN framework. If
+ * we discover a not yet transmitted package, stop looking for more.
+ *
+ */
+static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_msr;
+ unsigned int mb;
+
+ /* masking of reg_sr not needed, already done by at91_irq */
+
+ for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
+ mb = get_tx_echo_mb(priv);
+
+ /* no event in mailbox? */
+ if (!(reg_sr & (1 << mb)))
+ break;
+
+ /* Disable irq for this TX mailbox */
+ at91_write(priv, AT91_IDR, 1 << mb);
+
+ /*
+ * only echo if mailbox signals us a transfer
+ * complete (MSR_MRDY). Otherwise it's a tansfer
+ * abort. "can_bus_off()" takes care about the skbs
+ * parked in the echo queue.
+ */
+ reg_msr = at91_read(priv, AT91_MSR(mb));
+ if (likely(reg_msr & AT91_MSR_MRDY &&
+ ~reg_msr & AT91_MSR_MABT)) {
+ /* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */
+ can_get_echo_skb(dev, mb - get_mb_tx_first(priv));
+ dev->stats.tx_packets++;
+ can_led_event(dev, CAN_LED_EVENT_TX);
+ }
+ }
+
+ /*
+ * restart queue if we don't have a wrap around but restart if
+ * we get a TX int for the last can frame directly before a
+ * wrap around.
+ */
+ if ((priv->tx_next & get_next_mask(priv)) != 0 ||
+ (priv->tx_echo & get_next_mask(priv)) == 0)
+ netif_wake_queue(dev);
+}
+
+static void at91_irq_err_state(struct net_device *dev,
+ struct can_frame *cf, enum can_state new_state)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ u32 reg_idr = 0, reg_ier = 0;
+ struct can_berr_counter bec;
+
+ at91_get_berr_counter(dev, &bec);
+
+ switch (priv->can.state) {
+ case CAN_STATE_ERROR_ACTIVE:
+ /*
+ * from: ERROR_ACTIVE
+ * to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF
+ * => : there was a warning int
+ */
+ if (new_state >= CAN_STATE_ERROR_WARNING &&
+ new_state <= CAN_STATE_BUS_OFF) {
+ netdev_dbg(dev, "Error Warning IRQ\n");
+ priv->can.can_stats.error_warning++;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (bec.txerr > bec.rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ }
+ case CAN_STATE_ERROR_WARNING: /* fallthrough */
+ /*
+ * from: ERROR_ACTIVE, ERROR_WARNING
+ * to : ERROR_PASSIVE, BUS_OFF
+ * => : error passive int
+ */
+ if (new_state >= CAN_STATE_ERROR_PASSIVE &&
+ new_state <= CAN_STATE_BUS_OFF) {
+ netdev_dbg(dev, "Error Passive IRQ\n");
+ priv->can.can_stats.error_passive++;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (bec.txerr > bec.rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ break;
+ case CAN_STATE_BUS_OFF:
+ /*
+ * from: BUS_OFF
+ * to : ERROR_ACTIVE, ERROR_WARNING, ERROR_PASSIVE
+ */
+ if (new_state <= CAN_STATE_ERROR_PASSIVE) {
+ cf->can_id |= CAN_ERR_RESTARTED;
+
+ netdev_dbg(dev, "restarted\n");
+ priv->can.can_stats.restarts++;
+
+ netif_carrier_on(dev);
+ netif_wake_queue(dev);
+ }
+ break;
+ default:
+ break;
+ }
+
+
+ /* process state changes depending on the new state */
+ switch (new_state) {
+ case CAN_STATE_ERROR_ACTIVE:
+ /*
+ * actually we want to enable AT91_IRQ_WARN here, but
+ * it screws up the system under certain
+ * circumstances. so just enable AT91_IRQ_ERRP, thus
+ * the "fallthrough"
+ */
+ netdev_dbg(dev, "Error Active\n");
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_ACTIVE;
+ case CAN_STATE_ERROR_WARNING: /* fallthrough */
+ reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_BOFF;
+ reg_ier = AT91_IRQ_ERRP;
+ break;
+ case CAN_STATE_ERROR_PASSIVE:
+ reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_ERRP;
+ reg_ier = AT91_IRQ_BOFF;
+ break;
+ case CAN_STATE_BUS_OFF:
+ reg_idr = AT91_IRQ_ERRA | AT91_IRQ_ERRP |
+ AT91_IRQ_WARN | AT91_IRQ_BOFF;
+ reg_ier = 0;
+
+ cf->can_id |= CAN_ERR_BUSOFF;
+
+ netdev_dbg(dev, "bus-off\n");
+ netif_carrier_off(dev);
+ priv->can.can_stats.bus_off++;
+
+ /* turn off chip, if restart is disabled */
+ if (!priv->can.restart_ms) {
+ at91_chip_stop(dev, CAN_STATE_BUS_OFF);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ at91_write(priv, AT91_IDR, reg_idr);
+ at91_write(priv, AT91_IER, reg_ier);
+}
+
+static int at91_get_state_by_bec(const struct net_device *dev,
+ enum can_state *state)
+{
+ struct can_berr_counter bec;
+ int err;
+
+ err = at91_get_berr_counter(dev, &bec);
+ if (err)
+ return err;
+
+ if (bec.txerr < 96 && bec.rxerr < 96)
+ *state = CAN_STATE_ERROR_ACTIVE;
+ else if (bec.txerr < 128 && bec.rxerr < 128)
+ *state = CAN_STATE_ERROR_WARNING;
+ else if (bec.txerr < 256 && bec.rxerr < 256)
+ *state = CAN_STATE_ERROR_PASSIVE;
+ else
+ *state = CAN_STATE_BUS_OFF;
+
+ return 0;
+}
+
+
+static void at91_irq_err(struct net_device *dev)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ enum can_state new_state;
+ u32 reg_sr;
+ int err;
+
+ if (at91_is_sam9263(priv)) {
+ reg_sr = at91_read(priv, AT91_SR);
+
+ /* we need to look at the unmasked reg_sr */
+ if (unlikely(reg_sr & AT91_IRQ_BOFF))
+ new_state = CAN_STATE_BUS_OFF;
+ else if (unlikely(reg_sr & AT91_IRQ_ERRP))
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ else if (unlikely(reg_sr & AT91_IRQ_WARN))
+ new_state = CAN_STATE_ERROR_WARNING;
+ else if (likely(reg_sr & AT91_IRQ_ERRA))
+ new_state = CAN_STATE_ERROR_ACTIVE;
+ else {
+ netdev_err(dev, "BUG! hardware in undefined state\n");
+ return;
+ }
+ } else {
+ err = at91_get_state_by_bec(dev, &new_state);
+ if (err)
+ return;
+ }
+
+ /* state hasn't changed */
+ if (likely(new_state == priv->can.state))
+ return;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+ return;
+
+ at91_irq_err_state(dev, cf, new_state);
+ netif_rx(skb);
+
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += cf->can_dlc;
+
+ priv->can.state = new_state;
+}
+
+/*
+ * interrupt handler
+ */
+static irqreturn_t at91_irq(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct at91_priv *priv = netdev_priv(dev);
+ irqreturn_t handled = IRQ_NONE;
+ u32 reg_sr, reg_imr;
+
+ reg_sr = at91_read(priv, AT91_SR);
+ reg_imr = at91_read(priv, AT91_IMR);
+
+ /* Ignore masked interrupts */
+ reg_sr &= reg_imr;
+ if (!reg_sr)
+ goto exit;
+
+ handled = IRQ_HANDLED;
+
+ /* Receive or error interrupt? -> napi */
+ if (reg_sr & (get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME)) {
+ /*
+ * The error bits are clear on read,
+ * save for later use.
+ */
+ priv->reg_sr = reg_sr;
+ at91_write(priv, AT91_IDR,
+ get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME);
+ napi_schedule(&priv->napi);
+ }
+
+ /* Transmission complete interrupt */
+ if (reg_sr & get_irq_mb_tx(priv))
+ at91_irq_tx(dev, reg_sr);
+
+ at91_irq_err(dev);
+
+ exit:
+ return handled;
+}
+
+static int at91_open(struct net_device *dev)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+ int err;
+
+ clk_enable(priv->clk);
+
+ /* check or determine and set bittime */
+ err = open_candev(dev);
+ if (err)
+ goto out;
+
+ /* register interrupt handler */
+ if (request_irq(dev->irq, at91_irq, IRQF_SHARED,
+ dev->name, dev)) {
+ err = -EAGAIN;
+ goto out_close;
+ }
+
+ can_led_event(dev, CAN_LED_EVENT_OPEN);
+
+ /* start chip and queuing */
+ at91_chip_start(dev);
+ napi_enable(&priv->napi);
+ netif_start_queue(dev);
+
+ return 0;
+
+ out_close:
+ close_candev(dev);
+ out:
+ clk_disable(priv->clk);
+
+ return err;
+}
+
+/*
+ * stop CAN bus activity
+ */
+static int at91_close(struct net_device *dev)
+{
+ struct at91_priv *priv = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+ at91_chip_stop(dev, CAN_STATE_STOPPED);
+
+ free_irq(dev->irq, dev);
+ clk_disable(priv->clk);
+
+ close_candev(dev);
+
+ can_led_event(dev, CAN_LED_EVENT_STOP);
+
+ return 0;
+}
+
+static int at91_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ at91_chip_start(dev);
+ netif_wake_queue(dev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static const struct net_device_ops at91_netdev_ops = {
+ .ndo_open = at91_open,
+ .ndo_stop = at91_close,
+ .ndo_start_xmit = at91_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static ssize_t at91_sysfs_show_mb0_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct at91_priv *priv = netdev_priv(to_net_dev(dev));
+
+ if (priv->mb0_id & CAN_EFF_FLAG)
+ return snprintf(buf, PAGE_SIZE, "0x%08x\n", priv->mb0_id);
+ else
+ return snprintf(buf, PAGE_SIZE, "0x%03x\n", priv->mb0_id);
+}
+
+static ssize_t at91_sysfs_set_mb0_id(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct net_device *ndev = to_net_dev(dev);
+ struct at91_priv *priv = netdev_priv(ndev);
+ unsigned long can_id;
+ ssize_t ret;
+ int err;
+
+ rtnl_lock();
+
+ if (ndev->flags & IFF_UP) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ err = kstrtoul(buf, 0, &can_id);
+ if (err) {
+ ret = err;
+ goto out;
+ }
+
+ if (can_id & CAN_EFF_FLAG)
+ can_id &= CAN_EFF_MASK | CAN_EFF_FLAG;
+ else
+ can_id &= CAN_SFF_MASK;
+
+ priv->mb0_id = can_id;
+ ret = count;
+
+ out:
+ rtnl_unlock();
+ return ret;
+}
+
+static DEVICE_ATTR(mb0_id, S_IWUSR | S_IRUGO,
+ at91_sysfs_show_mb0_id, at91_sysfs_set_mb0_id);
+
+static struct attribute *at91_sysfs_attrs[] = {
+ &dev_attr_mb0_id.attr,
+ NULL,
+};
+
+static struct attribute_group at91_sysfs_attr_group = {
+ .attrs = at91_sysfs_attrs,
+};
+
+#if defined(CONFIG_OF)
+static const struct of_device_id at91_can_dt_ids[] = {
+ {
+ .compatible = "atmel,at91sam9x5-can",
+ .data = &at91_at91sam9x5_data,
+ }, {
+ .compatible = "atmel,at91sam9263-can",
+ .data = &at91_at91sam9263_data,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, at91_can_dt_ids);
+#endif
+
+static const struct at91_devtype_data *at91_can_get_driver_data(struct platform_device *pdev)
+{
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+
+ match = of_match_node(at91_can_dt_ids, pdev->dev.of_node);
+ if (!match) {
+ dev_err(&pdev->dev, "no matching node found in dtb\n");
+ return NULL;
+ }
+ return (const struct at91_devtype_data *)match->data;
+ }
+ return (const struct at91_devtype_data *)
+ platform_get_device_id(pdev)->driver_data;
+}
+
+static int at91_can_probe(struct platform_device *pdev)
+{
+ const struct at91_devtype_data *devtype_data;
+ struct net_device *dev;
+ struct at91_priv *priv;
+ struct resource *res;
+ struct clk *clk;
+ void __iomem *addr;
+ int err, irq;
+
+ devtype_data = at91_can_get_driver_data(pdev);
+ if (!devtype_data) {
+ dev_err(&pdev->dev, "no driver data\n");
+ err = -ENODEV;
+ goto exit;
+ }
+
+ clk = clk_get(&pdev->dev, "can_clk");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "no clock defined\n");
+ err = -ENODEV;
+ goto exit;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res || irq <= 0) {
+ err = -ENODEV;
+ goto exit_put;
+ }
+
+ if (!request_mem_region(res->start,
+ resource_size(res),
+ pdev->name)) {
+ err = -EBUSY;
+ goto exit_put;
+ }
+
+ addr = ioremap_nocache(res->start, resource_size(res));
+ if (!addr) {
+ err = -ENOMEM;
+ goto exit_release;
+ }
+
+ dev = alloc_candev(sizeof(struct at91_priv),
+ 1 << devtype_data->tx_shift);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_iounmap;
+ }
+
+ dev->netdev_ops = &at91_netdev_ops;
+ dev->irq = irq;
+ dev->flags |= IFF_ECHO;
+
+ priv = netdev_priv(dev);
+ priv->can.clock.freq = clk_get_rate(clk);
+ priv->can.bittiming_const = &at91_bittiming_const;
+ priv->can.do_set_mode = at91_set_mode;
+ priv->can.do_get_berr_counter = at91_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_LISTENONLY;
+ priv->dev = dev;
+ priv->reg_base = addr;
+ priv->devtype_data = *devtype_data;
+ priv->clk = clk;
+ priv->pdata = dev_get_platdata(&pdev->dev);
+ priv->mb0_id = 0x7ff;
+
+ netif_napi_add(dev, &priv->napi, at91_poll, get_mb_rx_num(priv));
+
+ if (at91_is_sam9263(priv))
+ dev->sysfs_groups[0] = &at91_sysfs_attr_group;
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = register_candev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "registering netdev failed\n");
+ goto exit_free;
+ }
+
+ devm_can_led_init(dev);
+
+ dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n",
+ priv->reg_base, dev->irq);
+
+ return 0;
+
+ exit_free:
+ free_candev(dev);
+ exit_iounmap:
+ iounmap(addr);
+ exit_release:
+ release_mem_region(res->start, resource_size(res));
+ exit_put:
+ clk_put(clk);
+ exit:
+ return err;
+}
+
+static int at91_can_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct at91_priv *priv = netdev_priv(dev);
+ struct resource *res;
+
+ unregister_netdev(dev);
+
+ iounmap(priv->reg_base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ clk_put(priv->clk);
+
+ free_candev(dev);
+
+ return 0;
+}
+
+static const struct platform_device_id at91_can_id_table[] = {
+ {
+ .name = "at91sam9x5_can",
+ .driver_data = (kernel_ulong_t)&at91_at91sam9x5_data,
+ }, {
+ .name = "at91_can",
+ .driver_data = (kernel_ulong_t)&at91_at91sam9263_data,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, at91_can_id_table);
+
+static struct platform_driver at91_can_driver = {
+ .probe = at91_can_probe,
+ .remove = at91_can_remove,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(at91_can_dt_ids),
+ },
+ .id_table = at91_can_id_table,
+};
+
+module_platform_driver(at91_can_driver);
+
+MODULE_AUTHOR("Marc Kleine-Budde <mkl@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(KBUILD_MODNAME " CAN netdevice driver");
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c
new file mode 100644
index 00000000000..543ecceb33e
--- /dev/null
+++ b/drivers/net/can/bfin_can.c
@@ -0,0 +1,692 @@
+/*
+ * Blackfin On-Chip CAN Driver
+ *
+ * Copyright 2004-2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#include <asm/bfin_can.h>
+#include <asm/portmux.h>
+
+#define DRV_NAME "bfin_can"
+#define BFIN_CAN_TIMEOUT 100
+#define TX_ECHO_SKB_MAX 1
+
+/*
+ * bfin can private data
+ */
+struct bfin_can_priv {
+ struct can_priv can; /* must be the first member */
+ struct net_device *dev;
+ void __iomem *membase;
+ int rx_irq;
+ int tx_irq;
+ int err_irq;
+ unsigned short *pin_list;
+};
+
+/*
+ * bfin can timing parameters
+ */
+static const struct can_bittiming_const bfin_can_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ /*
+ * Although the BRP field can be set to any value, it is recommended
+ * that the value be greater than or equal to 4, as restrictions
+ * apply to the bit timing configuration when BRP is less than 4.
+ */
+ .brp_min = 4,
+ .brp_max = 1024,
+ .brp_inc = 1,
+};
+
+static int bfin_can_set_bittiming(struct net_device *dev)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u16 clk, timing;
+
+ clk = bt->brp - 1;
+ timing = ((bt->sjw - 1) << 8) | (bt->prop_seg + bt->phase_seg1 - 1) |
+ ((bt->phase_seg2 - 1) << 4);
+
+ /*
+ * If the SAM bit is set, the input signal is oversampled three times
+ * at the SCLK rate.
+ */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ timing |= SAM;
+
+ bfin_write(&reg->clock, clk);
+ bfin_write(&reg->timing, timing);
+
+ netdev_info(dev, "setting CLOCK=0x%04x TIMING=0x%04x\n", clk, timing);
+
+ return 0;
+}
+
+static void bfin_can_set_reset_mode(struct net_device *dev)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ int timeout = BFIN_CAN_TIMEOUT;
+ int i;
+
+ /* disable interrupts */
+ bfin_write(&reg->mbim1, 0);
+ bfin_write(&reg->mbim2, 0);
+ bfin_write(&reg->gim, 0);
+
+ /* reset can and enter configuration mode */
+ bfin_write(&reg->control, SRS | CCR);
+ SSYNC();
+ bfin_write(&reg->control, CCR);
+ SSYNC();
+ while (!(bfin_read(&reg->control) & CCA)) {
+ udelay(10);
+ if (--timeout == 0) {
+ netdev_err(dev, "fail to enter configuration mode\n");
+ BUG();
+ }
+ }
+
+ /*
+ * All mailbox configurations are marked as inactive
+ * by writing to CAN Mailbox Configuration Registers 1 and 2
+ * For all bits: 0 - Mailbox disabled, 1 - Mailbox enabled
+ */
+ bfin_write(&reg->mc1, 0);
+ bfin_write(&reg->mc2, 0);
+
+ /* Set Mailbox Direction */
+ bfin_write(&reg->md1, 0xFFFF); /* mailbox 1-16 are RX */
+ bfin_write(&reg->md2, 0); /* mailbox 17-32 are TX */
+
+ /* RECEIVE_STD_CHL */
+ for (i = 0; i < 2; i++) {
+ bfin_write(&reg->chl[RECEIVE_STD_CHL + i].id0, 0);
+ bfin_write(&reg->chl[RECEIVE_STD_CHL + i].id1, AME);
+ bfin_write(&reg->chl[RECEIVE_STD_CHL + i].dlc, 0);
+ bfin_write(&reg->msk[RECEIVE_STD_CHL + i].amh, 0x1FFF);
+ bfin_write(&reg->msk[RECEIVE_STD_CHL + i].aml, 0xFFFF);
+ }
+
+ /* RECEIVE_EXT_CHL */
+ for (i = 0; i < 2; i++) {
+ bfin_write(&reg->chl[RECEIVE_EXT_CHL + i].id0, 0);
+ bfin_write(&reg->chl[RECEIVE_EXT_CHL + i].id1, AME | IDE);
+ bfin_write(&reg->chl[RECEIVE_EXT_CHL + i].dlc, 0);
+ bfin_write(&reg->msk[RECEIVE_EXT_CHL + i].amh, 0x1FFF);
+ bfin_write(&reg->msk[RECEIVE_EXT_CHL + i].aml, 0xFFFF);
+ }
+
+ bfin_write(&reg->mc2, BIT(TRANSMIT_CHL - 16));
+ bfin_write(&reg->mc1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL));
+ SSYNC();
+
+ priv->can.state = CAN_STATE_STOPPED;
+}
+
+static void bfin_can_set_normal_mode(struct net_device *dev)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ int timeout = BFIN_CAN_TIMEOUT;
+
+ /*
+ * leave configuration mode
+ */
+ bfin_write(&reg->control, bfin_read(&reg->control) & ~CCR);
+
+ while (bfin_read(&reg->status) & CCA) {
+ udelay(10);
+ if (--timeout == 0) {
+ netdev_err(dev, "fail to leave configuration mode\n");
+ BUG();
+ }
+ }
+
+ /*
+ * clear _All_ tx and rx interrupts
+ */
+ bfin_write(&reg->mbtif1, 0xFFFF);
+ bfin_write(&reg->mbtif2, 0xFFFF);
+ bfin_write(&reg->mbrif1, 0xFFFF);
+ bfin_write(&reg->mbrif2, 0xFFFF);
+
+ /*
+ * clear global interrupt status register
+ */
+ bfin_write(&reg->gis, 0x7FF); /* overwrites with '1' */
+
+ /*
+ * Initialize Interrupts
+ * - set bits in the mailbox interrupt mask register
+ * - global interrupt mask
+ */
+ bfin_write(&reg->mbim1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL));
+ bfin_write(&reg->mbim2, BIT(TRANSMIT_CHL - 16));
+
+ bfin_write(&reg->gim, EPIM | BOIM | RMLIM);
+ SSYNC();
+}
+
+static void bfin_can_start(struct net_device *dev)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+
+ /* enter reset mode */
+ if (priv->can.state != CAN_STATE_STOPPED)
+ bfin_can_set_reset_mode(dev);
+
+ /* leave reset mode */
+ bfin_can_set_normal_mode(dev);
+}
+
+static int bfin_can_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ bfin_can_start(dev);
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int bfin_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+
+ u16 cec = bfin_read(&reg->cec);
+
+ bec->txerr = cec >> 8;
+ bec->rxerr = cec;
+
+ return 0;
+}
+
+static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u8 dlc = cf->can_dlc;
+ canid_t id = cf->can_id;
+ u8 *data = cf->data;
+ u16 val;
+ int i;
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(dev);
+
+ /* fill id */
+ if (id & CAN_EFF_FLAG) {
+ bfin_write(&reg->chl[TRANSMIT_CHL].id0, id);
+ val = ((id & 0x1FFF0000) >> 16) | IDE;
+ } else
+ val = (id << 2);
+ if (id & CAN_RTR_FLAG)
+ val |= RTR;
+ bfin_write(&reg->chl[TRANSMIT_CHL].id1, val | AME);
+
+ /* fill payload */
+ for (i = 0; i < 8; i += 2) {
+ val = ((7 - i) < dlc ? (data[7 - i]) : 0) +
+ ((6 - i) < dlc ? (data[6 - i] << 8) : 0);
+ bfin_write(&reg->chl[TRANSMIT_CHL].data[i], val);
+ }
+
+ /* fill data length code */
+ bfin_write(&reg->chl[TRANSMIT_CHL].dlc, dlc);
+
+ can_put_echo_skb(skb, dev, 0);
+
+ /* set transmit request */
+ bfin_write(&reg->trs2, BIT(TRANSMIT_CHL - 16));
+
+ return 0;
+}
+
+static void bfin_can_rx(struct net_device *dev, u16 isrc)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ int obj;
+ int i;
+ u16 val;
+
+ skb = alloc_can_skb(dev, &cf);
+ if (skb == NULL)
+ return;
+
+ /* get id */
+ if (isrc & BIT(RECEIVE_EXT_CHL)) {
+ /* extended frame format (EFF) */
+ cf->can_id = ((bfin_read(&reg->chl[RECEIVE_EXT_CHL].id1)
+ & 0x1FFF) << 16)
+ + bfin_read(&reg->chl[RECEIVE_EXT_CHL].id0);
+ cf->can_id |= CAN_EFF_FLAG;
+ obj = RECEIVE_EXT_CHL;
+ } else {
+ /* standard frame format (SFF) */
+ cf->can_id = (bfin_read(&reg->chl[RECEIVE_STD_CHL].id1)
+ & 0x1ffc) >> 2;
+ obj = RECEIVE_STD_CHL;
+ }
+ if (bfin_read(&reg->chl[obj].id1) & RTR)
+ cf->can_id |= CAN_RTR_FLAG;
+
+ /* get data length code */
+ cf->can_dlc = get_can_dlc(bfin_read(&reg->chl[obj].dlc) & 0xF);
+
+ /* get payload */
+ for (i = 0; i < 8; i += 2) {
+ val = bfin_read(&reg->chl[obj].data[i]);
+ cf->data[7 - i] = (7 - i) < cf->can_dlc ? val : 0;
+ cf->data[6 - i] = (6 - i) < cf->can_dlc ? (val >> 8) : 0;
+ }
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ enum can_state state = priv->can.state;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (skb == NULL)
+ return -ENOMEM;
+
+ if (isrc & RMLIS) {
+ /* data overrun interrupt */
+ netdev_dbg(dev, "data overrun interrupt\n");
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ }
+
+ if (isrc & BOIS) {
+ netdev_dbg(dev, "bus-off mode interrupt\n");
+ state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(dev);
+ }
+
+ if (isrc & EPIS) {
+ /* error passive interrupt */
+ netdev_dbg(dev, "error passive interrupt\n");
+ state = CAN_STATE_ERROR_PASSIVE;
+ }
+
+ if ((isrc & EWTIS) || (isrc & EWRIS)) {
+ netdev_dbg(dev, "Error Warning Transmit/Receive Interrupt\n");
+ state = CAN_STATE_ERROR_WARNING;
+ }
+
+ if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
+ state == CAN_STATE_ERROR_PASSIVE)) {
+ u16 cec = bfin_read(&reg->cec);
+ u8 rxerr = cec;
+ u8 txerr = cec >> 8;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ if (state == CAN_STATE_ERROR_WARNING) {
+ priv->can.can_stats.error_warning++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ } else {
+ priv->can.can_stats.error_passive++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ }
+
+ if (status) {
+ priv->can.can_stats.bus_error++;
+
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ if (status & BEF)
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ else if (status & FER)
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ else if (status & SER)
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ else
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ }
+
+ priv->can.state = state;
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ return 0;
+}
+
+static irqreturn_t bfin_can_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ struct net_device_stats *stats = &dev->stats;
+ u16 status, isrc;
+
+ if ((irq == priv->tx_irq) && bfin_read(&reg->mbtif2)) {
+ /* transmission complete interrupt */
+ bfin_write(&reg->mbtif2, 0xFFFF);
+ stats->tx_packets++;
+ stats->tx_bytes += bfin_read(&reg->chl[TRANSMIT_CHL].dlc);
+ can_get_echo_skb(dev, 0);
+ netif_wake_queue(dev);
+ } else if ((irq == priv->rx_irq) && bfin_read(&reg->mbrif1)) {
+ /* receive interrupt */
+ isrc = bfin_read(&reg->mbrif1);
+ bfin_write(&reg->mbrif1, 0xFFFF);
+ bfin_can_rx(dev, isrc);
+ } else if ((irq == priv->err_irq) && bfin_read(&reg->gis)) {
+ /* error interrupt */
+ isrc = bfin_read(&reg->gis);
+ status = bfin_read(&reg->esr);
+ bfin_write(&reg->gis, 0x7FF);
+ bfin_can_err(dev, isrc, status);
+ } else {
+ return IRQ_NONE;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int bfin_can_open(struct net_device *dev)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* set chip into reset mode */
+ bfin_can_set_reset_mode(dev);
+
+ /* common open */
+ err = open_candev(dev);
+ if (err)
+ goto exit_open;
+
+ /* register interrupt handler */
+ err = request_irq(priv->rx_irq, &bfin_can_interrupt, 0,
+ "bfin-can-rx", dev);
+ if (err)
+ goto exit_rx_irq;
+ err = request_irq(priv->tx_irq, &bfin_can_interrupt, 0,
+ "bfin-can-tx", dev);
+ if (err)
+ goto exit_tx_irq;
+ err = request_irq(priv->err_irq, &bfin_can_interrupt, 0,
+ "bfin-can-err", dev);
+ if (err)
+ goto exit_err_irq;
+
+ bfin_can_start(dev);
+
+ netif_start_queue(dev);
+
+ return 0;
+
+exit_err_irq:
+ free_irq(priv->tx_irq, dev);
+exit_tx_irq:
+ free_irq(priv->rx_irq, dev);
+exit_rx_irq:
+ close_candev(dev);
+exit_open:
+ return err;
+}
+
+static int bfin_can_close(struct net_device *dev)
+{
+ struct bfin_can_priv *priv = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ bfin_can_set_reset_mode(dev);
+
+ close_candev(dev);
+
+ free_irq(priv->rx_irq, dev);
+ free_irq(priv->tx_irq, dev);
+ free_irq(priv->err_irq, dev);
+
+ return 0;
+}
+
+static struct net_device *alloc_bfin_candev(void)
+{
+ struct net_device *dev;
+ struct bfin_can_priv *priv;
+
+ dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
+ if (!dev)
+ return NULL;
+
+ priv = netdev_priv(dev);
+
+ priv->dev = dev;
+ priv->can.bittiming_const = &bfin_can_bittiming_const;
+ priv->can.do_set_bittiming = bfin_can_set_bittiming;
+ priv->can.do_set_mode = bfin_can_set_mode;
+ priv->can.do_get_berr_counter = bfin_can_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+
+ return dev;
+}
+
+static const struct net_device_ops bfin_can_netdev_ops = {
+ .ndo_open = bfin_can_open,
+ .ndo_stop = bfin_can_close,
+ .ndo_start_xmit = bfin_can_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static int bfin_can_probe(struct platform_device *pdev)
+{
+ int err;
+ struct net_device *dev;
+ struct bfin_can_priv *priv;
+ struct resource *res_mem, *rx_irq, *tx_irq, *err_irq;
+ unsigned short *pdata;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data provided!\n");
+ err = -EINVAL;
+ goto exit;
+ }
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ rx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ tx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ err_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
+ if (!res_mem || !rx_irq || !tx_irq || !err_irq) {
+ err = -EINVAL;
+ goto exit;
+ }
+
+ if (!request_mem_region(res_mem->start, resource_size(res_mem),
+ dev_name(&pdev->dev))) {
+ err = -EBUSY;
+ goto exit;
+ }
+
+ /* request peripheral pins */
+ err = peripheral_request_list(pdata, dev_name(&pdev->dev));
+ if (err)
+ goto exit_mem_release;
+
+ dev = alloc_bfin_candev();
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_peri_pin_free;
+ }
+
+ priv = netdev_priv(dev);
+ priv->membase = (void __iomem *)res_mem->start;
+ priv->rx_irq = rx_irq->start;
+ priv->tx_irq = tx_irq->start;
+ priv->err_irq = err_irq->start;
+ priv->pin_list = pdata;
+ priv->can.clock.freq = get_sclk();
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ dev->flags |= IFF_ECHO; /* we support local echo */
+ dev->netdev_ops = &bfin_can_netdev_ops;
+
+ bfin_can_set_reset_mode(dev);
+
+ err = register_candev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "registering failed (err=%d)\n", err);
+ goto exit_candev_free;
+ }
+
+ dev_info(&pdev->dev,
+ "%s device registered"
+ "(&reg_base=%p, rx_irq=%d, tx_irq=%d, err_irq=%d, sclk=%d)\n",
+ DRV_NAME, priv->membase, priv->rx_irq,
+ priv->tx_irq, priv->err_irq, priv->can.clock.freq);
+ return 0;
+
+exit_candev_free:
+ free_candev(dev);
+exit_peri_pin_free:
+ peripheral_free_list(pdata);
+exit_mem_release:
+ release_mem_region(res_mem->start, resource_size(res_mem));
+exit:
+ return err;
+}
+
+static int bfin_can_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct resource *res;
+
+ bfin_can_set_reset_mode(dev);
+
+ unregister_candev(dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ peripheral_free_list(priv->pin_list);
+
+ free_candev(dev);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+ int timeout = BFIN_CAN_TIMEOUT;
+
+ if (netif_running(dev)) {
+ /* enter sleep mode */
+ bfin_write(&reg->control, bfin_read(&reg->control) | SMR);
+ SSYNC();
+ while (!(bfin_read(&reg->intr) & SMACK)) {
+ udelay(10);
+ if (--timeout == 0) {
+ netdev_err(dev, "fail to enter sleep mode\n");
+ BUG();
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int bfin_can_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct bfin_can_priv *priv = netdev_priv(dev);
+ struct bfin_can_regs __iomem *reg = priv->membase;
+
+ if (netif_running(dev)) {
+ /* leave sleep mode */
+ bfin_write(&reg->intr, 0);
+ SSYNC();
+ }
+
+ return 0;
+}
+#else
+#define bfin_can_suspend NULL
+#define bfin_can_resume NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver bfin_can_driver = {
+ .probe = bfin_can_probe,
+ .remove = bfin_can_remove,
+ .suspend = bfin_can_suspend,
+ .resume = bfin_can_resume,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(bfin_can_driver);
+
+MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Blackfin on-chip CAN netdevice driver");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig
new file mode 100644
index 00000000000..61ffc12d8fd
--- /dev/null
+++ b/drivers/net/can/c_can/Kconfig
@@ -0,0 +1,23 @@
+menuconfig CAN_C_CAN
+ tristate "Bosch C_CAN/D_CAN devices"
+ depends on HAS_IOMEM
+
+if CAN_C_CAN
+
+config CAN_C_CAN_PLATFORM
+ tristate "Generic Platform Bus based C_CAN/D_CAN driver"
+ ---help---
+ This driver adds support for the C_CAN/D_CAN chips connected
+ to the "platform bus" (Linux abstraction for directly to the
+ processor attached devices) which can be found on various
+ boards from ST Microelectronics (http://www.st.com) like the
+ SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com)
+ boards like am335x, dm814x, dm813x and dm811x.
+
+config CAN_C_CAN_PCI
+ tristate "Generic PCI Bus based C_CAN/D_CAN driver"
+ depends on PCI
+ ---help---
+ This driver adds support for the C_CAN/D_CAN chips connected
+ to the PCI bus.
+endif
diff --git a/drivers/net/can/c_can/Makefile b/drivers/net/can/c_can/Makefile
new file mode 100644
index 00000000000..ad1cc842170
--- /dev/null
+++ b/drivers/net/can/c_can/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the Bosch C_CAN controller drivers.
+#
+
+obj-$(CONFIG_CAN_C_CAN) += c_can.o
+obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o
+obj-$(CONFIG_CAN_C_CAN_PCI) += c_can_pci.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
new file mode 100644
index 00000000000..8e78bb48f5a
--- /dev/null
+++ b/drivers/net/can/c_can/c_can.c
@@ -0,0 +1,1274 @@
+/*
+ * CAN bus driver for Bosch C_CAN controller
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Bhupesh Sharma <bhupesh.sharma@st.com>
+ *
+ * Borrowed heavily from the C_CAN driver originally written by:
+ * Copyright (C) 2007
+ * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de>
+ * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch>
+ *
+ * TX and RX NAPI implementation has been borrowed from at91 CAN driver
+ * written by:
+ * Copyright
+ * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
+ * (C) 2008, 2009 by Marc Kleine-Budde <kernel@pengutronix.de>
+ *
+ * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B.
+ * Bosch C_CAN user manual can be obtained from:
+ * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/
+ * users_manual_c_can.pdf
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+
+#include "c_can.h"
+
+/* Number of interface registers */
+#define IF_ENUM_REG_LEN 11
+#define C_CAN_IFACE(reg, iface) (C_CAN_IF1_##reg + (iface) * IF_ENUM_REG_LEN)
+
+/* control extension register D_CAN specific */
+#define CONTROL_EX_PDR BIT(8)
+
+/* control register */
+#define CONTROL_TEST BIT(7)
+#define CONTROL_CCE BIT(6)
+#define CONTROL_DISABLE_AR BIT(5)
+#define CONTROL_ENABLE_AR (0 << 5)
+#define CONTROL_EIE BIT(3)
+#define CONTROL_SIE BIT(2)
+#define CONTROL_IE BIT(1)
+#define CONTROL_INIT BIT(0)
+
+#define CONTROL_IRQMSK (CONTROL_EIE | CONTROL_IE | CONTROL_SIE)
+
+/* test register */
+#define TEST_RX BIT(7)
+#define TEST_TX1 BIT(6)
+#define TEST_TX2 BIT(5)
+#define TEST_LBACK BIT(4)
+#define TEST_SILENT BIT(3)
+#define TEST_BASIC BIT(2)
+
+/* status register */
+#define STATUS_PDA BIT(10)
+#define STATUS_BOFF BIT(7)
+#define STATUS_EWARN BIT(6)
+#define STATUS_EPASS BIT(5)
+#define STATUS_RXOK BIT(4)
+#define STATUS_TXOK BIT(3)
+
+/* error counter register */
+#define ERR_CNT_TEC_MASK 0xff
+#define ERR_CNT_TEC_SHIFT 0
+#define ERR_CNT_REC_SHIFT 8
+#define ERR_CNT_REC_MASK (0x7f << ERR_CNT_REC_SHIFT)
+#define ERR_CNT_RP_SHIFT 15
+#define ERR_CNT_RP_MASK (0x1 << ERR_CNT_RP_SHIFT)
+
+/* bit-timing register */
+#define BTR_BRP_MASK 0x3f
+#define BTR_BRP_SHIFT 0
+#define BTR_SJW_SHIFT 6
+#define BTR_SJW_MASK (0x3 << BTR_SJW_SHIFT)
+#define BTR_TSEG1_SHIFT 8
+#define BTR_TSEG1_MASK (0xf << BTR_TSEG1_SHIFT)
+#define BTR_TSEG2_SHIFT 12
+#define BTR_TSEG2_MASK (0x7 << BTR_TSEG2_SHIFT)
+
+/* brp extension register */
+#define BRP_EXT_BRPE_MASK 0x0f
+#define BRP_EXT_BRPE_SHIFT 0
+
+/* IFx command request */
+#define IF_COMR_BUSY BIT(15)
+
+/* IFx command mask */
+#define IF_COMM_WR BIT(7)
+#define IF_COMM_MASK BIT(6)
+#define IF_COMM_ARB BIT(5)
+#define IF_COMM_CONTROL BIT(4)
+#define IF_COMM_CLR_INT_PND BIT(3)
+#define IF_COMM_TXRQST BIT(2)
+#define IF_COMM_CLR_NEWDAT IF_COMM_TXRQST
+#define IF_COMM_DATAA BIT(1)
+#define IF_COMM_DATAB BIT(0)
+
+/* TX buffer setup */
+#define IF_COMM_TX (IF_COMM_ARB | IF_COMM_CONTROL | \
+ IF_COMM_TXRQST | \
+ IF_COMM_DATAA | IF_COMM_DATAB)
+
+/* For the low buffers we clear the interrupt bit, but keep newdat */
+#define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \
+ IF_COMM_CONTROL | IF_COMM_CLR_INT_PND | \
+ IF_COMM_DATAA | IF_COMM_DATAB)
+
+/* For the high buffers we clear the interrupt bit and newdat */
+#define IF_COMM_RCV_HIGH (IF_COMM_RCV_LOW | IF_COMM_CLR_NEWDAT)
+
+
+/* Receive setup of message objects */
+#define IF_COMM_RCV_SETUP (IF_COMM_MASK | IF_COMM_ARB | IF_COMM_CONTROL)
+
+/* Invalidation of message objects */
+#define IF_COMM_INVAL (IF_COMM_ARB | IF_COMM_CONTROL)
+
+/* IFx arbitration */
+#define IF_ARB_MSGVAL BIT(31)
+#define IF_ARB_MSGXTD BIT(30)
+#define IF_ARB_TRANSMIT BIT(29)
+
+/* IFx message control */
+#define IF_MCONT_NEWDAT BIT(15)
+#define IF_MCONT_MSGLST BIT(14)
+#define IF_MCONT_INTPND BIT(13)
+#define IF_MCONT_UMASK BIT(12)
+#define IF_MCONT_TXIE BIT(11)
+#define IF_MCONT_RXIE BIT(10)
+#define IF_MCONT_RMTEN BIT(9)
+#define IF_MCONT_TXRQST BIT(8)
+#define IF_MCONT_EOB BIT(7)
+#define IF_MCONT_DLC_MASK 0xf
+
+#define IF_MCONT_RCV (IF_MCONT_RXIE | IF_MCONT_UMASK)
+#define IF_MCONT_RCV_EOB (IF_MCONT_RCV | IF_MCONT_EOB)
+
+#define IF_MCONT_TX (IF_MCONT_TXIE | IF_MCONT_EOB)
+
+/*
+ * Use IF1 for RX and IF2 for TX
+ */
+#define IF_RX 0
+#define IF_TX 1
+
+/* minimum timeout for checking BUSY status */
+#define MIN_TIMEOUT_VALUE 6
+
+/* Wait for ~1 sec for INIT bit */
+#define INIT_WAIT_MS 1000
+
+/* napi related */
+#define C_CAN_NAPI_WEIGHT C_CAN_MSG_OBJ_RX_NUM
+
+/* c_can lec values */
+enum c_can_lec_type {
+ LEC_NO_ERROR = 0,
+ LEC_STUFF_ERROR,
+ LEC_FORM_ERROR,
+ LEC_ACK_ERROR,
+ LEC_BIT1_ERROR,
+ LEC_BIT0_ERROR,
+ LEC_CRC_ERROR,
+ LEC_UNUSED,
+ LEC_MASK = LEC_UNUSED,
+};
+
+/*
+ * c_can error types:
+ * Bus errors (BUS_OFF, ERROR_WARNING, ERROR_PASSIVE) are supported
+ */
+enum c_can_bus_error_types {
+ C_CAN_NO_ERROR = 0,
+ C_CAN_BUS_OFF,
+ C_CAN_ERROR_WARNING,
+ C_CAN_ERROR_PASSIVE,
+};
+
+static const struct can_bittiming_const c_can_bittiming_const = {
+ .name = KBUILD_MODNAME,
+ .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */
+ .tseg1_max = 16,
+ .tseg2_min = 1, /* Time segment 2 = phase_seg2 */
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 1024, /* 6-bit BRP field + 4-bit BRPE field*/
+ .brp_inc = 1,
+};
+
+static inline void c_can_pm_runtime_enable(const struct c_can_priv *priv)
+{
+ if (priv->device)
+ pm_runtime_enable(priv->device);
+}
+
+static inline void c_can_pm_runtime_disable(const struct c_can_priv *priv)
+{
+ if (priv->device)
+ pm_runtime_disable(priv->device);
+}
+
+static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv)
+{
+ if (priv->device)
+ pm_runtime_get_sync(priv->device);
+}
+
+static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
+{
+ if (priv->device)
+ pm_runtime_put_sync(priv->device);
+}
+
+static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
+{
+ if (priv->raminit)
+ priv->raminit(priv, enable);
+}
+
+static void c_can_irq_control(struct c_can_priv *priv, bool enable)
+{
+ u32 ctrl = priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_IRQMSK;
+
+ if (enable)
+ ctrl |= CONTROL_IRQMSK;
+
+ priv->write_reg(priv, C_CAN_CTRL_REG, ctrl);
+}
+
+static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
+
+ priv->write_reg32(priv, reg, (cmd << 16) | obj);
+
+ for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
+ if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
+ return;
+ udelay(1);
+ }
+ netdev_err(dev, "Updating object timed out\n");
+
+}
+
+static inline void c_can_object_get(struct net_device *dev, int iface,
+ u32 obj, u32 cmd)
+{
+ c_can_obj_update(dev, iface, cmd, obj);
+}
+
+static inline void c_can_object_put(struct net_device *dev, int iface,
+ u32 obj, u32 cmd)
+{
+ c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj);
+}
+
+/*
+ * Note: According to documentation clearing TXIE while MSGVAL is set
+ * is not allowed, but works nicely on C/DCAN. And that lowers the I/O
+ * load significantly.
+ */
+static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
+ c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
+}
+
+static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
+ priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0);
+ c_can_inval_tx_object(dev, iface, obj);
+}
+
+static void c_can_setup_tx_object(struct net_device *dev, int iface,
+ struct can_frame *frame, int idx)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ u16 ctrl = IF_MCONT_TX | frame->can_dlc;
+ bool rtr = frame->can_id & CAN_RTR_FLAG;
+ u32 arb = IF_ARB_MSGVAL;
+ int i;
+
+ if (frame->can_id & CAN_EFF_FLAG) {
+ arb |= frame->can_id & CAN_EFF_MASK;
+ arb |= IF_ARB_MSGXTD;
+ } else {
+ arb |= (frame->can_id & CAN_SFF_MASK) << 18;
+ }
+
+ if (!rtr)
+ arb |= IF_ARB_TRANSMIT;
+
+ /*
+ * If we change the DIR bit, we need to invalidate the buffer
+ * first, i.e. clear the MSGVAL flag in the arbiter.
+ */
+ if (rtr != (bool)test_bit(idx, &priv->tx_dir)) {
+ u32 obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
+
+ c_can_inval_msg_object(dev, iface, obj);
+ change_bit(idx, &priv->tx_dir);
+ }
+
+ priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
+
+ priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
+
+ for (i = 0; i < frame->can_dlc; i += 2) {
+ priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
+ frame->data[i] | (frame->data[i + 1] << 8));
+ }
+}
+
+static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev,
+ int iface)
+{
+ int i;
+
+ for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++)
+ c_can_object_get(dev, iface, i, IF_COMM_CLR_NEWDAT);
+}
+
+static int c_can_handle_lost_msg_obj(struct net_device *dev,
+ int iface, int objno, u32 ctrl)
+{
+ struct net_device_stats *stats = &dev->stats;
+ struct c_can_priv *priv = netdev_priv(dev);
+ struct can_frame *frame;
+ struct sk_buff *skb;
+
+ ctrl &= ~(IF_MCONT_MSGLST | IF_MCONT_INTPND | IF_MCONT_NEWDAT);
+ priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
+ c_can_object_put(dev, iface, objno, IF_COMM_CONTROL);
+
+ stats->rx_errors++;
+ stats->rx_over_errors++;
+
+ /* create an error msg */
+ skb = alloc_can_err_skb(dev, &frame);
+ if (unlikely(!skb))
+ return 0;
+
+ frame->can_id |= CAN_ERR_CRTL;
+ frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+
+ netif_receive_skb(skb);
+ return 1;
+}
+
+static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
+{
+ struct net_device_stats *stats = &dev->stats;
+ struct c_can_priv *priv = netdev_priv(dev);
+ struct can_frame *frame;
+ struct sk_buff *skb;
+ u32 arb, data;
+
+ skb = alloc_can_skb(dev, &frame);
+ if (!skb) {
+ stats->rx_dropped++;
+ return -ENOMEM;
+ }
+
+ frame->can_dlc = get_can_dlc(ctrl & 0x0F);
+
+ arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
+
+ if (arb & IF_ARB_MSGXTD)
+ frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ else
+ frame->can_id = (arb >> 18) & CAN_SFF_MASK;
+
+ if (arb & IF_ARB_TRANSMIT) {
+ frame->can_id |= CAN_RTR_FLAG;
+ } else {
+ int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
+
+ for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
+ data = priv->read_reg(priv, dreg);
+ frame->data[i] = data;
+ frame->data[i + 1] = data >> 8;
+ }
+ }
+
+ stats->rx_packets++;
+ stats->rx_bytes += frame->can_dlc;
+
+ netif_receive_skb(skb);
+ return 0;
+}
+
+static void c_can_setup_receive_object(struct net_device *dev, int iface,
+ u32 obj, u32 mask, u32 id, u32 mcont)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ mask |= BIT(29);
+ priv->write_reg32(priv, C_CAN_IFACE(MASK1_REG, iface), mask);
+
+ id |= IF_ARB_MSGVAL;
+ priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), id);
+
+ priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont);
+ c_can_object_put(dev, iface, obj, IF_COMM_RCV_SETUP);
+}
+
+static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct can_frame *frame = (struct can_frame *)skb->data;
+ struct c_can_priv *priv = netdev_priv(dev);
+ u32 idx, obj;
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+ /*
+ * This is not a FIFO. C/D_CAN sends out the buffers
+ * prioritized. The lowest buffer number wins.
+ */
+ idx = fls(atomic_read(&priv->tx_active));
+ obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
+
+ /* If this is the last buffer, stop the xmit queue */
+ if (idx == C_CAN_MSG_OBJ_TX_NUM - 1)
+ netif_stop_queue(dev);
+ /*
+ * Store the message in the interface so we can call
+ * can_put_echo_skb(). We must do this before we enable
+ * transmit as we might race against do_tx().
+ */
+ c_can_setup_tx_object(dev, IF_TX, frame, idx);
+ priv->dlc[idx] = frame->can_dlc;
+ can_put_echo_skb(skb, dev, idx);
+
+ /* Update the active bits */
+ atomic_add((1 << idx), &priv->tx_active);
+ /* Start transmission */
+ c_can_object_put(dev, IF_TX, obj, IF_COMM_TX);
+
+ return NETDEV_TX_OK;
+}
+
+static int c_can_wait_for_ctrl_init(struct net_device *dev,
+ struct c_can_priv *priv, u32 init)
+{
+ int retry = 0;
+
+ while (init != (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_INIT)) {
+ udelay(10);
+ if (retry++ > 1000) {
+ netdev_err(dev, "CCTRL: set CONTROL_INIT failed\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
+static int c_can_set_bittiming(struct net_device *dev)
+{
+ unsigned int reg_btr, reg_brpe, ctrl_save;
+ u8 brp, brpe, sjw, tseg1, tseg2;
+ u32 ten_bit_brp;
+ struct c_can_priv *priv = netdev_priv(dev);
+ const struct can_bittiming *bt = &priv->can.bittiming;
+ int res;
+
+ /* c_can provides a 6-bit brp and 4-bit brpe fields */
+ ten_bit_brp = bt->brp - 1;
+ brp = ten_bit_brp & BTR_BRP_MASK;
+ brpe = ten_bit_brp >> 6;
+
+ sjw = bt->sjw - 1;
+ tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
+ tseg2 = bt->phase_seg2 - 1;
+ reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) |
+ (tseg2 << BTR_TSEG2_SHIFT);
+ reg_brpe = brpe & BRP_EXT_BRPE_MASK;
+
+ netdev_info(dev,
+ "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe);
+
+ ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG);
+ ctrl_save &= ~CONTROL_INIT;
+ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_CCE | CONTROL_INIT);
+ res = c_can_wait_for_ctrl_init(dev, priv, CONTROL_INIT);
+ if (res)
+ return res;
+
+ priv->write_reg(priv, C_CAN_BTR_REG, reg_btr);
+ priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe);
+ priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save);
+
+ return c_can_wait_for_ctrl_init(dev, priv, 0);
+}
+
+/*
+ * Configure C_CAN message objects for Tx and Rx purposes:
+ * C_CAN provides a total of 32 message objects that can be configured
+ * either for Tx or Rx purposes. Here the first 16 message objects are used as
+ * a reception FIFO. The end of reception FIFO is signified by the EoB bit
+ * being SET. The remaining 16 message objects are kept aside for Tx purposes.
+ * See user guide document for further details on configuring message
+ * objects.
+ */
+static void c_can_configure_msg_objects(struct net_device *dev)
+{
+ int i;
+
+ /* first invalidate all message objects */
+ for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
+ c_can_inval_msg_object(dev, IF_RX, i);
+
+ /* setup receive message objects */
+ for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
+ c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV);
+
+ c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0,
+ IF_MCONT_RCV_EOB);
+}
+
+/*
+ * Configure C_CAN chip:
+ * - enable/disable auto-retransmission
+ * - set operating mode
+ * - configure message objects
+ */
+static int c_can_chip_config(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ /* enable automatic retransmission */
+ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
+
+ if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) &&
+ (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) {
+ /* loopback + silent mode : useful for hot self-test */
+ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
+ priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT);
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+ /* loopback mode : useful for self-test function */
+ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
+ priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK);
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+ /* silent mode : bus-monitoring mode */
+ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST);
+ priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT);
+ }
+
+ /* configure message objects */
+ c_can_configure_msg_objects(dev);
+
+ /* set a `lec` value so that we can check for updates later */
+ priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
+
+ /* Clear all internal status */
+ atomic_set(&priv->tx_active, 0);
+ priv->rxmasked = 0;
+ priv->tx_dir = 0;
+
+ /* set bittiming params */
+ return c_can_set_bittiming(dev);
+}
+
+static int c_can_start(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* basic c_can configuration */
+ err = c_can_chip_config(dev);
+ if (err)
+ return err;
+
+ /* Setup the command for new messages */
+ priv->comm_rcv_high = priv->type != BOSCH_D_CAN ?
+ IF_COMM_RCV_LOW : IF_COMM_RCV_HIGH;
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ return 0;
+}
+
+static void c_can_stop(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ c_can_irq_control(priv, false);
+ priv->can.state = CAN_STATE_STOPPED;
+}
+
+static int c_can_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ err = c_can_start(dev);
+ if (err)
+ return err;
+ netif_wake_queue(dev);
+ c_can_irq_control(priv, true);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int __c_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ unsigned int reg_err_counter;
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
+ bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
+ ERR_CNT_REC_SHIFT;
+ bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;
+
+ return 0;
+}
+
+static int c_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ c_can_pm_runtime_get_sync(priv);
+ err = __c_can_get_berr_counter(dev, bec);
+ c_can_pm_runtime_put_sync(priv);
+
+ return err;
+}
+
+static void c_can_do_tx(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ u32 idx, obj, pkts = 0, bytes = 0, pend, clr;
+
+ clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG);
+
+ while ((idx = ffs(pend))) {
+ idx--;
+ pend &= ~(1 << idx);
+ obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
+ c_can_inval_tx_object(dev, IF_RX, obj);
+ can_get_echo_skb(dev, idx);
+ bytes += priv->dlc[idx];
+ pkts++;
+ }
+
+ /* Clear the bits in the tx_active mask */
+ atomic_sub(clr, &priv->tx_active);
+
+ if (clr & (1 << (C_CAN_MSG_OBJ_TX_NUM - 1)))
+ netif_wake_queue(dev);
+
+ if (pkts) {
+ stats->tx_bytes += bytes;
+ stats->tx_packets += pkts;
+ can_led_event(dev, CAN_LED_EVENT_TX);
+ }
+}
+
+/*
+ * If we have a gap in the pending bits, that means we either
+ * raced with the hardware or failed to readout all upper
+ * objects in the last run due to quota limit.
+ */
+static u32 c_can_adjust_pending(u32 pend)
+{
+ u32 weight, lasts;
+
+ if (pend == RECEIVE_OBJECT_BITS)
+ return pend;
+
+ /*
+ * If the last set bit is larger than the number of pending
+ * bits we have a gap.
+ */
+ weight = hweight32(pend);
+ lasts = fls(pend);
+
+ /* If the bits are linear, nothing to do */
+ if (lasts == weight)
+ return pend;
+
+ /*
+ * Find the first set bit after the gap. We walk backwards
+ * from the last set bit.
+ */
+ for (lasts--; pend & (1 << (lasts - 1)); lasts--);
+
+ return pend & ~((1 << lasts) - 1);
+}
+
+static inline void c_can_rx_object_get(struct net_device *dev,
+ struct c_can_priv *priv, u32 obj)
+{
+ c_can_object_get(dev, IF_RX, obj, priv->comm_rcv_high);
+}
+
+static inline void c_can_rx_finalize(struct net_device *dev,
+ struct c_can_priv *priv, u32 obj)
+{
+ if (priv->type != BOSCH_D_CAN)
+ c_can_object_get(dev, IF_RX, obj, IF_COMM_CLR_NEWDAT);
+}
+
+static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv,
+ u32 pend, int quota)
+{
+ u32 pkts = 0, ctrl, obj;
+
+ while ((obj = ffs(pend)) && quota > 0) {
+ pend &= ~BIT(obj - 1);
+
+ c_can_rx_object_get(dev, priv, obj);
+ ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX));
+
+ if (ctrl & IF_MCONT_MSGLST) {
+ int n = c_can_handle_lost_msg_obj(dev, IF_RX, obj, ctrl);
+
+ pkts += n;
+ quota -= n;
+ continue;
+ }
+
+ /*
+ * This really should not happen, but this covers some
+ * odd HW behaviour. Do not remove that unless you
+ * want to brick your machine.
+ */
+ if (!(ctrl & IF_MCONT_NEWDAT))
+ continue;
+
+ /* read the data from the message object */
+ c_can_read_msg_object(dev, IF_RX, ctrl);
+
+ c_can_rx_finalize(dev, priv, obj);
+
+ pkts++;
+ quota--;
+ }
+
+ return pkts;
+}
+
+static inline u32 c_can_get_pending(struct c_can_priv *priv)
+{
+ u32 pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG);
+
+ return pend;
+}
+
+/*
+ * theory of operation:
+ *
+ * c_can core saves a received CAN message into the first free message
+ * object it finds free (starting with the lowest). Bits NEWDAT and
+ * INTPND are set for this message object indicating that a new message
+ * has arrived. To work-around this issue, we keep two groups of message
+ * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT.
+ *
+ * We clear the newdat bit right away.
+ *
+ * This can result in packet reordering when the readout is slow.
+ */
+static int c_can_do_rx_poll(struct net_device *dev, int quota)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ u32 pkts = 0, pend = 0, toread, n;
+
+ /*
+ * It is faster to read only one 16bit register. This is only possible
+ * for a maximum number of 16 objects.
+ */
+ BUILD_BUG_ON_MSG(C_CAN_MSG_OBJ_RX_LAST > 16,
+ "Implementation does not support more message objects than 16");
+
+ while (quota > 0) {
+ if (!pend) {
+ pend = c_can_get_pending(priv);
+ if (!pend)
+ break;
+ /*
+ * If the pending field has a gap, handle the
+ * bits above the gap first.
+ */
+ toread = c_can_adjust_pending(pend);
+ } else {
+ toread = pend;
+ }
+ /* Remove the bits from pend */
+ pend &= ~toread;
+ /* Read the objects */
+ n = c_can_read_objects(dev, priv, toread, quota);
+ pkts += n;
+ quota -= n;
+ }
+
+ if (pkts)
+ can_led_event(dev, CAN_LED_EVENT_RX);
+
+ return pkts;
+}
+
+static int c_can_handle_state_change(struct net_device *dev,
+ enum c_can_bus_error_types error_type)
+{
+ unsigned int reg_err_counter;
+ unsigned int rx_err_passive;
+ struct c_can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct can_berr_counter bec;
+
+ switch (error_type) {
+ case C_CAN_ERROR_WARNING:
+ /* error warning state */
+ priv->can.can_stats.error_warning++;
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ break;
+ case C_CAN_ERROR_PASSIVE:
+ /* error passive state */
+ priv->can.can_stats.error_passive++;
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ break;
+ case C_CAN_BUS_OFF:
+ /* bus-off state */
+ priv->can.state = CAN_STATE_BUS_OFF;
+ can_bus_off(dev);
+ break;
+ default:
+ break;
+ }
+
+ /* propagate the error condition to the CAN stack */
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+ return 0;
+
+ __c_can_get_berr_counter(dev, &bec);
+ reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
+ rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >>
+ ERR_CNT_RP_SHIFT;
+
+ switch (error_type) {
+ case C_CAN_ERROR_WARNING:
+ /* error warning state */
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (bec.txerr > bec.rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ cf->data[6] = bec.txerr;
+ cf->data[7] = bec.rxerr;
+
+ break;
+ case C_CAN_ERROR_PASSIVE:
+ /* error passive state */
+ cf->can_id |= CAN_ERR_CRTL;
+ if (rx_err_passive)
+ cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+ if (bec.txerr > 127)
+ cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+
+ cf->data[6] = bec.txerr;
+ cf->data[7] = bec.rxerr;
+ break;
+ case C_CAN_BUS_OFF:
+ /* bus-off state */
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(dev);
+ break;
+ default:
+ break;
+ }
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ netif_receive_skb(skb);
+
+ return 1;
+}
+
+static int c_can_handle_bus_err(struct net_device *dev,
+ enum c_can_lec_type lec_type)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+
+ /*
+ * early exit if no lec update or no error.
+ * no lec update means that no CAN bus event has been detected
+ * since CPU wrote 0x7 value to status reg.
+ */
+ if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR)
+ return 0;
+
+ if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
+ return 0;
+
+ /* common for all type of bus errors */
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ /* propagate the error condition to the CAN stack */
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+ return 0;
+
+ /*
+ * check for 'last error code' which tells us the
+ * type of the last error to occur on the CAN bus
+ */
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+
+ switch (lec_type) {
+ case LEC_STUFF_ERROR:
+ netdev_dbg(dev, "stuff error\n");
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ case LEC_FORM_ERROR:
+ netdev_dbg(dev, "form error\n");
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case LEC_ACK_ERROR:
+ netdev_dbg(dev, "ack error\n");
+ cf->data[3] |= (CAN_ERR_PROT_LOC_ACK |
+ CAN_ERR_PROT_LOC_ACK_DEL);
+ break;
+ case LEC_BIT1_ERROR:
+ netdev_dbg(dev, "bit1 error\n");
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ break;
+ case LEC_BIT0_ERROR:
+ netdev_dbg(dev, "bit0 error\n");
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ break;
+ case LEC_CRC_ERROR:
+ netdev_dbg(dev, "CRC error\n");
+ cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL);
+ break;
+ default:
+ break;
+ }
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ netif_receive_skb(skb);
+ return 1;
+}
+
+static int c_can_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *dev = napi->dev;
+ struct c_can_priv *priv = netdev_priv(dev);
+ u16 curr, last = priv->last_status;
+ int work_done = 0;
+
+ priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG);
+ /* Ack status on C_CAN. D_CAN is self clearing */
+ if (priv->type != BOSCH_D_CAN)
+ priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
+
+ /* handle state changes */
+ if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) {
+ netdev_dbg(dev, "entered error warning state\n");
+ work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
+ }
+
+ if ((curr & STATUS_EPASS) && (!(last & STATUS_EPASS))) {
+ netdev_dbg(dev, "entered error passive state\n");
+ work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
+ }
+
+ if ((curr & STATUS_BOFF) && (!(last & STATUS_BOFF))) {
+ netdev_dbg(dev, "entered bus off state\n");
+ work_done += c_can_handle_state_change(dev, C_CAN_BUS_OFF);
+ goto end;
+ }
+
+ /* handle bus recovery events */
+ if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
+ netdev_dbg(dev, "left bus off state\n");
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ }
+ if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
+ netdev_dbg(dev, "left error passive state\n");
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ }
+
+ /* handle lec errors on the bus */
+ work_done += c_can_handle_bus_err(dev, curr & LEC_MASK);
+
+ /* Handle Tx/Rx events. We do this unconditionally */
+ work_done += c_can_do_rx_poll(dev, (quota - work_done));
+ c_can_do_tx(dev);
+
+end:
+ if (work_done < quota) {
+ napi_complete(napi);
+ /* enable all IRQs if we are not in bus off state */
+ if (priv->can.state != CAN_STATE_BUS_OFF)
+ c_can_irq_control(priv, true);
+ }
+
+ return work_done;
+}
+
+static irqreturn_t c_can_isr(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ if (!priv->read_reg(priv, C_CAN_INT_REG))
+ return IRQ_NONE;
+
+ /* disable all interrupts and schedule the NAPI */
+ c_can_irq_control(priv, false);
+ napi_schedule(&priv->napi);
+
+ return IRQ_HANDLED;
+}
+
+static int c_can_open(struct net_device *dev)
+{
+ int err;
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ c_can_pm_runtime_get_sync(priv);
+ c_can_reset_ram(priv, true);
+
+ /* open the can device */
+ err = open_candev(dev);
+ if (err) {
+ netdev_err(dev, "failed to open can device\n");
+ goto exit_open_fail;
+ }
+
+ /* register interrupt handler */
+ err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name,
+ dev);
+ if (err < 0) {
+ netdev_err(dev, "failed to request interrupt\n");
+ goto exit_irq_fail;
+ }
+
+ /* start the c_can controller */
+ err = c_can_start(dev);
+ if (err)
+ goto exit_start_fail;
+
+ can_led_event(dev, CAN_LED_EVENT_OPEN);
+
+ napi_enable(&priv->napi);
+ /* enable status change, error and module interrupts */
+ c_can_irq_control(priv, true);
+ netif_start_queue(dev);
+
+ return 0;
+
+exit_start_fail:
+ free_irq(dev->irq, dev);
+exit_irq_fail:
+ close_candev(dev);
+exit_open_fail:
+ c_can_reset_ram(priv, false);
+ c_can_pm_runtime_put_sync(priv);
+ return err;
+}
+
+static int c_can_close(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+ c_can_stop(dev);
+ free_irq(dev->irq, dev);
+ close_candev(dev);
+
+ c_can_reset_ram(priv, false);
+ c_can_pm_runtime_put_sync(priv);
+
+ can_led_event(dev, CAN_LED_EVENT_STOP);
+
+ return 0;
+}
+
+struct net_device *alloc_c_can_dev(void)
+{
+ struct net_device *dev;
+ struct c_can_priv *priv;
+
+ dev = alloc_candev(sizeof(struct c_can_priv), C_CAN_MSG_OBJ_TX_NUM);
+ if (!dev)
+ return NULL;
+
+ priv = netdev_priv(dev);
+ netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT);
+
+ priv->dev = dev;
+ priv->can.bittiming_const = &c_can_bittiming_const;
+ priv->can.do_set_mode = c_can_set_mode;
+ priv->can.do_get_berr_counter = c_can_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+ CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_BERR_REPORTING;
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_c_can_dev);
+
+#ifdef CONFIG_PM
+int c_can_power_down(struct net_device *dev)
+{
+ u32 val;
+ unsigned long time_out;
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ if (!(dev->flags & IFF_UP))
+ return 0;
+
+ WARN_ON(priv->type != BOSCH_D_CAN);
+
+ /* set PDR value so the device goes to power down mode */
+ val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
+ val |= CONTROL_EX_PDR;
+ priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
+
+ /* Wait for the PDA bit to get set */
+ time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
+ while (!(priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
+ time_after(time_out, jiffies))
+ cpu_relax();
+
+ if (time_after(jiffies, time_out))
+ return -ETIMEDOUT;
+
+ c_can_stop(dev);
+
+ c_can_reset_ram(priv, false);
+ c_can_pm_runtime_put_sync(priv);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(c_can_power_down);
+
+int c_can_power_up(struct net_device *dev)
+{
+ u32 val;
+ unsigned long time_out;
+ struct c_can_priv *priv = netdev_priv(dev);
+ int ret;
+
+ if (!(dev->flags & IFF_UP))
+ return 0;
+
+ WARN_ON(priv->type != BOSCH_D_CAN);
+
+ c_can_pm_runtime_get_sync(priv);
+ c_can_reset_ram(priv, true);
+
+ /* Clear PDR and INIT bits */
+ val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
+ val &= ~CONTROL_EX_PDR;
+ priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
+ val = priv->read_reg(priv, C_CAN_CTRL_REG);
+ val &= ~CONTROL_INIT;
+ priv->write_reg(priv, C_CAN_CTRL_REG, val);
+
+ /* Wait for the PDA bit to get clear */
+ time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
+ while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
+ time_after(time_out, jiffies))
+ cpu_relax();
+
+ if (time_after(jiffies, time_out))
+ return -ETIMEDOUT;
+
+ ret = c_can_start(dev);
+ if (!ret)
+ c_can_irq_control(priv, true);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(c_can_power_up);
+#endif
+
+void free_c_can_dev(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ netif_napi_del(&priv->napi);
+ free_candev(dev);
+}
+EXPORT_SYMBOL_GPL(free_c_can_dev);
+
+static const struct net_device_ops c_can_netdev_ops = {
+ .ndo_open = c_can_open,
+ .ndo_stop = c_can_close,
+ .ndo_start_xmit = c_can_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+int register_c_can_dev(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ c_can_pm_runtime_enable(priv);
+
+ dev->flags |= IFF_ECHO; /* we support local echo */
+ dev->netdev_ops = &c_can_netdev_ops;
+
+ err = register_candev(dev);
+ if (err)
+ c_can_pm_runtime_disable(priv);
+ else
+ devm_can_led_init(dev);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(register_c_can_dev);
+
+void unregister_c_can_dev(struct net_device *dev)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ unregister_candev(dev);
+
+ c_can_pm_runtime_disable(priv);
+}
+EXPORT_SYMBOL_GPL(unregister_c_can_dev);
+
+MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CAN bus driver for Bosch C_CAN controller");
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
new file mode 100644
index 00000000000..99ad1aa576b
--- /dev/null
+++ b/drivers/net/can/c_can/c_can.h
@@ -0,0 +1,207 @@
+/*
+ * CAN bus driver for Bosch C_CAN controller
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Bhupesh Sharma <bhupesh.sharma@st.com>
+ *
+ * Borrowed heavily from the C_CAN driver originally written by:
+ * Copyright (C) 2007
+ * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de>
+ * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch>
+ *
+ * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B.
+ * Bosch C_CAN user manual can be obtained from:
+ * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/
+ * users_manual_c_can.pdf
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef C_CAN_H
+#define C_CAN_H
+
+/* message object split */
+#define C_CAN_NO_OF_OBJECTS 32
+#define C_CAN_MSG_OBJ_RX_NUM 16
+#define C_CAN_MSG_OBJ_TX_NUM 16
+
+#define C_CAN_MSG_OBJ_RX_FIRST 1
+#define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \
+ C_CAN_MSG_OBJ_RX_NUM - 1)
+
+#define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1)
+#define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \
+ C_CAN_MSG_OBJ_TX_NUM - 1)
+
+#define C_CAN_MSG_OBJ_RX_SPLIT 9
+#define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1)
+#define RECEIVE_OBJECT_BITS 0x0000ffff
+
+enum reg {
+ C_CAN_CTRL_REG = 0,
+ C_CAN_CTRL_EX_REG,
+ C_CAN_STS_REG,
+ C_CAN_ERR_CNT_REG,
+ C_CAN_BTR_REG,
+ C_CAN_INT_REG,
+ C_CAN_TEST_REG,
+ C_CAN_BRPEXT_REG,
+ C_CAN_IF1_COMREQ_REG,
+ C_CAN_IF1_COMMSK_REG,
+ C_CAN_IF1_MASK1_REG,
+ C_CAN_IF1_MASK2_REG,
+ C_CAN_IF1_ARB1_REG,
+ C_CAN_IF1_ARB2_REG,
+ C_CAN_IF1_MSGCTRL_REG,
+ C_CAN_IF1_DATA1_REG,
+ C_CAN_IF1_DATA2_REG,
+ C_CAN_IF1_DATA3_REG,
+ C_CAN_IF1_DATA4_REG,
+ C_CAN_IF2_COMREQ_REG,
+ C_CAN_IF2_COMMSK_REG,
+ C_CAN_IF2_MASK1_REG,
+ C_CAN_IF2_MASK2_REG,
+ C_CAN_IF2_ARB1_REG,
+ C_CAN_IF2_ARB2_REG,
+ C_CAN_IF2_MSGCTRL_REG,
+ C_CAN_IF2_DATA1_REG,
+ C_CAN_IF2_DATA2_REG,
+ C_CAN_IF2_DATA3_REG,
+ C_CAN_IF2_DATA4_REG,
+ C_CAN_TXRQST1_REG,
+ C_CAN_TXRQST2_REG,
+ C_CAN_NEWDAT1_REG,
+ C_CAN_NEWDAT2_REG,
+ C_CAN_INTPND1_REG,
+ C_CAN_INTPND2_REG,
+ C_CAN_MSGVAL1_REG,
+ C_CAN_MSGVAL2_REG,
+ C_CAN_FUNCTION_REG,
+};
+
+static const u16 reg_map_c_can[] = {
+ [C_CAN_CTRL_REG] = 0x00,
+ [C_CAN_STS_REG] = 0x02,
+ [C_CAN_ERR_CNT_REG] = 0x04,
+ [C_CAN_BTR_REG] = 0x06,
+ [C_CAN_INT_REG] = 0x08,
+ [C_CAN_TEST_REG] = 0x0A,
+ [C_CAN_BRPEXT_REG] = 0x0C,
+ [C_CAN_IF1_COMREQ_REG] = 0x10,
+ [C_CAN_IF1_COMMSK_REG] = 0x12,
+ [C_CAN_IF1_MASK1_REG] = 0x14,
+ [C_CAN_IF1_MASK2_REG] = 0x16,
+ [C_CAN_IF1_ARB1_REG] = 0x18,
+ [C_CAN_IF1_ARB2_REG] = 0x1A,
+ [C_CAN_IF1_MSGCTRL_REG] = 0x1C,
+ [C_CAN_IF1_DATA1_REG] = 0x1E,
+ [C_CAN_IF1_DATA2_REG] = 0x20,
+ [C_CAN_IF1_DATA3_REG] = 0x22,
+ [C_CAN_IF1_DATA4_REG] = 0x24,
+ [C_CAN_IF2_COMREQ_REG] = 0x40,
+ [C_CAN_IF2_COMMSK_REG] = 0x42,
+ [C_CAN_IF2_MASK1_REG] = 0x44,
+ [C_CAN_IF2_MASK2_REG] = 0x46,
+ [C_CAN_IF2_ARB1_REG] = 0x48,
+ [C_CAN_IF2_ARB2_REG] = 0x4A,
+ [C_CAN_IF2_MSGCTRL_REG] = 0x4C,
+ [C_CAN_IF2_DATA1_REG] = 0x4E,
+ [C_CAN_IF2_DATA2_REG] = 0x50,
+ [C_CAN_IF2_DATA3_REG] = 0x52,
+ [C_CAN_IF2_DATA4_REG] = 0x54,
+ [C_CAN_TXRQST1_REG] = 0x80,
+ [C_CAN_TXRQST2_REG] = 0x82,
+ [C_CAN_NEWDAT1_REG] = 0x90,
+ [C_CAN_NEWDAT2_REG] = 0x92,
+ [C_CAN_INTPND1_REG] = 0xA0,
+ [C_CAN_INTPND2_REG] = 0xA2,
+ [C_CAN_MSGVAL1_REG] = 0xB0,
+ [C_CAN_MSGVAL2_REG] = 0xB2,
+};
+
+static const u16 reg_map_d_can[] = {
+ [C_CAN_CTRL_REG] = 0x00,
+ [C_CAN_CTRL_EX_REG] = 0x02,
+ [C_CAN_STS_REG] = 0x04,
+ [C_CAN_ERR_CNT_REG] = 0x08,
+ [C_CAN_BTR_REG] = 0x0C,
+ [C_CAN_BRPEXT_REG] = 0x0E,
+ [C_CAN_INT_REG] = 0x10,
+ [C_CAN_TEST_REG] = 0x14,
+ [C_CAN_FUNCTION_REG] = 0x18,
+ [C_CAN_TXRQST1_REG] = 0x88,
+ [C_CAN_TXRQST2_REG] = 0x8A,
+ [C_CAN_NEWDAT1_REG] = 0x9C,
+ [C_CAN_NEWDAT2_REG] = 0x9E,
+ [C_CAN_INTPND1_REG] = 0xB0,
+ [C_CAN_INTPND2_REG] = 0xB2,
+ [C_CAN_MSGVAL1_REG] = 0xC4,
+ [C_CAN_MSGVAL2_REG] = 0xC6,
+ [C_CAN_IF1_COMREQ_REG] = 0x100,
+ [C_CAN_IF1_COMMSK_REG] = 0x102,
+ [C_CAN_IF1_MASK1_REG] = 0x104,
+ [C_CAN_IF1_MASK2_REG] = 0x106,
+ [C_CAN_IF1_ARB1_REG] = 0x108,
+ [C_CAN_IF1_ARB2_REG] = 0x10A,
+ [C_CAN_IF1_MSGCTRL_REG] = 0x10C,
+ [C_CAN_IF1_DATA1_REG] = 0x110,
+ [C_CAN_IF1_DATA2_REG] = 0x112,
+ [C_CAN_IF1_DATA3_REG] = 0x114,
+ [C_CAN_IF1_DATA4_REG] = 0x116,
+ [C_CAN_IF2_COMREQ_REG] = 0x120,
+ [C_CAN_IF2_COMMSK_REG] = 0x122,
+ [C_CAN_IF2_MASK1_REG] = 0x124,
+ [C_CAN_IF2_MASK2_REG] = 0x126,
+ [C_CAN_IF2_ARB1_REG] = 0x128,
+ [C_CAN_IF2_ARB2_REG] = 0x12A,
+ [C_CAN_IF2_MSGCTRL_REG] = 0x12C,
+ [C_CAN_IF2_DATA1_REG] = 0x130,
+ [C_CAN_IF2_DATA2_REG] = 0x132,
+ [C_CAN_IF2_DATA3_REG] = 0x134,
+ [C_CAN_IF2_DATA4_REG] = 0x136,
+};
+
+enum c_can_dev_id {
+ BOSCH_C_CAN_PLATFORM,
+ BOSCH_C_CAN,
+ BOSCH_D_CAN,
+};
+
+/* c_can private data structure */
+struct c_can_priv {
+ struct can_priv can; /* must be the first member */
+ struct napi_struct napi;
+ struct net_device *dev;
+ struct device *device;
+ atomic_t tx_active;
+ unsigned long tx_dir;
+ int last_status;
+ u16 (*read_reg) (const struct c_can_priv *priv, enum reg index);
+ void (*write_reg) (const struct c_can_priv *priv, enum reg index, u16 val);
+ u32 (*read_reg32) (const struct c_can_priv *priv, enum reg index);
+ void (*write_reg32) (const struct c_can_priv *priv, enum reg index, u32 val);
+ void __iomem *base;
+ const u16 *regs;
+ void *priv; /* for board-specific data */
+ enum c_can_dev_id type;
+ u32 __iomem *raminit_ctrlreg;
+ int instance;
+ void (*raminit) (const struct c_can_priv *priv, bool enable);
+ u32 comm_rcv_high;
+ u32 rxmasked;
+ u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
+};
+
+struct net_device *alloc_c_can_dev(void);
+void free_c_can_dev(struct net_device *dev);
+int register_c_can_dev(struct net_device *dev);
+void unregister_c_can_dev(struct net_device *dev);
+
+#ifdef CONFIG_PM
+int c_can_power_up(struct net_device *dev);
+int c_can_power_down(struct net_device *dev);
+#endif
+
+#endif /* C_CAN_H */
diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c
new file mode 100644
index 00000000000..5d11e0e4225
--- /dev/null
+++ b/drivers/net/can/c_can/c_can_pci.c
@@ -0,0 +1,292 @@
+/*
+ * PCI bus driver for Bosch C_CAN/D_CAN controller
+ *
+ * Copyright (C) 2012 Federico Vaga <federico.vaga@gmail.com>
+ *
+ * Borrowed from c_can_platform.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+
+#include <linux/can/dev.h>
+
+#include "c_can.h"
+
+#define PCI_DEVICE_ID_PCH_CAN 0x8818
+#define PCH_PCI_SOFT_RESET 0x01fc
+
+enum c_can_pci_reg_align {
+ C_CAN_REG_ALIGN_16,
+ C_CAN_REG_ALIGN_32,
+ C_CAN_REG_32,
+};
+
+struct c_can_pci_data {
+ /* Specify if is C_CAN or D_CAN */
+ enum c_can_dev_id type;
+ /* Set the register alignment in the memory */
+ enum c_can_pci_reg_align reg_align;
+ /* Set the frequency */
+ unsigned int freq;
+ /* PCI bar number */
+ int bar;
+ /* Callback for reset */
+ void (*init)(const struct c_can_priv *priv, bool enable);
+};
+
+/*
+ * 16-bit c_can registers can be arranged differently in the memory
+ * architecture of different implementations. For example: 16-bit
+ * registers can be aligned to a 16-bit boundary or 32-bit boundary etc.
+ * Handle the same by providing a common read/write interface.
+ */
+static u16 c_can_pci_read_reg_aligned_to_16bit(const struct c_can_priv *priv,
+ enum reg index)
+{
+ return readw(priv->base + priv->regs[index]);
+}
+
+static void c_can_pci_write_reg_aligned_to_16bit(const struct c_can_priv *priv,
+ enum reg index, u16 val)
+{
+ writew(val, priv->base + priv->regs[index]);
+}
+
+static u16 c_can_pci_read_reg_aligned_to_32bit(const struct c_can_priv *priv,
+ enum reg index)
+{
+ return readw(priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_pci_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
+ enum reg index, u16 val)
+{
+ writew(val, priv->base + 2 * priv->regs[index]);
+}
+
+static u16 c_can_pci_read_reg_32bit(const struct c_can_priv *priv,
+ enum reg index)
+{
+ return (u16)ioread32(priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_pci_write_reg_32bit(const struct c_can_priv *priv,
+ enum reg index, u16 val)
+{
+ iowrite32((u32)val, priv->base + 2 * priv->regs[index]);
+}
+
+static u32 c_can_pci_read_reg32(const struct c_can_priv *priv, enum reg index)
+{
+ u32 val;
+
+ val = priv->read_reg(priv, index);
+ val |= ((u32) priv->read_reg(priv, index + 1)) << 16;
+
+ return val;
+}
+
+static void c_can_pci_write_reg32(const struct c_can_priv *priv, enum reg index,
+ u32 val)
+{
+ priv->write_reg(priv, index + 1, val >> 16);
+ priv->write_reg(priv, index, val);
+}
+
+static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable)
+{
+ if (enable) {
+ u32 __iomem *addr = priv->base + PCH_PCI_SOFT_RESET;
+
+ /* write to sw reset register */
+ iowrite32(1, addr);
+ iowrite32(0, addr);
+ }
+}
+
+static int c_can_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct c_can_pci_data *c_can_pci_data = (void *)ent->driver_data;
+ struct c_can_priv *priv;
+ struct net_device *dev;
+ void __iomem *addr;
+ int ret;
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "pci_enable_device FAILED\n");
+ goto out;
+ }
+
+ ret = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (ret) {
+ dev_err(&pdev->dev, "pci_request_regions FAILED\n");
+ goto out_disable_device;
+ }
+
+ ret = pci_enable_msi(pdev);
+ if (!ret) {
+ dev_info(&pdev->dev, "MSI enabled\n");
+ pci_set_master(pdev);
+ }
+
+ addr = pci_iomap(pdev, c_can_pci_data->bar,
+ pci_resource_len(pdev, c_can_pci_data->bar));
+ if (!addr) {
+ dev_err(&pdev->dev,
+ "device has no PCI memory resources, "
+ "failing adapter\n");
+ ret = -ENOMEM;
+ goto out_release_regions;
+ }
+
+ /* allocate the c_can device */
+ dev = alloc_c_can_dev();
+ if (!dev) {
+ ret = -ENOMEM;
+ goto out_iounmap;
+ }
+
+ priv = netdev_priv(dev);
+ pci_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ dev->irq = pdev->irq;
+ priv->base = addr;
+
+ if (!c_can_pci_data->freq) {
+ dev_err(&pdev->dev, "no clock frequency defined\n");
+ ret = -ENODEV;
+ goto out_free_c_can;
+ } else {
+ priv->can.clock.freq = c_can_pci_data->freq;
+ }
+
+ /* Configure CAN type */
+ switch (c_can_pci_data->type) {
+ case BOSCH_C_CAN:
+ priv->regs = reg_map_c_can;
+ break;
+ case BOSCH_D_CAN:
+ priv->regs = reg_map_d_can;
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+ break;
+ default:
+ ret = -EINVAL;
+ goto out_free_c_can;
+ }
+
+ priv->type = c_can_pci_data->type;
+
+ /* Configure access to registers */
+ switch (c_can_pci_data->reg_align) {
+ case C_CAN_REG_ALIGN_32:
+ priv->read_reg = c_can_pci_read_reg_aligned_to_32bit;
+ priv->write_reg = c_can_pci_write_reg_aligned_to_32bit;
+ break;
+ case C_CAN_REG_ALIGN_16:
+ priv->read_reg = c_can_pci_read_reg_aligned_to_16bit;
+ priv->write_reg = c_can_pci_write_reg_aligned_to_16bit;
+ break;
+ case C_CAN_REG_32:
+ priv->read_reg = c_can_pci_read_reg_32bit;
+ priv->write_reg = c_can_pci_write_reg_32bit;
+ break;
+ default:
+ ret = -EINVAL;
+ goto out_free_c_can;
+ }
+ priv->read_reg32 = c_can_pci_read_reg32;
+ priv->write_reg32 = c_can_pci_write_reg32;
+
+ priv->raminit = c_can_pci_data->init;
+
+ ret = register_c_can_dev(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ KBUILD_MODNAME, ret);
+ goto out_free_c_can;
+ }
+
+ dev_dbg(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n",
+ KBUILD_MODNAME, priv->regs, dev->irq);
+
+ return 0;
+
+out_free_c_can:
+ free_c_can_dev(dev);
+out_iounmap:
+ pci_iounmap(pdev, addr);
+out_release_regions:
+ pci_disable_msi(pdev);
+ pci_clear_master(pdev);
+ pci_release_regions(pdev);
+out_disable_device:
+ pci_disable_device(pdev);
+out:
+ return ret;
+}
+
+static void c_can_pci_remove(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ unregister_c_can_dev(dev);
+
+ free_c_can_dev(dev);
+
+ pci_iounmap(pdev, priv->base);
+ pci_disable_msi(pdev);
+ pci_clear_master(pdev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+static struct c_can_pci_data c_can_sta2x11= {
+ .type = BOSCH_C_CAN,
+ .reg_align = C_CAN_REG_ALIGN_32,
+ .freq = 52000000, /* 52 Mhz */
+ .bar = 0,
+};
+
+static struct c_can_pci_data c_can_pch = {
+ .type = BOSCH_C_CAN,
+ .reg_align = C_CAN_REG_32,
+ .freq = 50000000, /* 50 MHz */
+ .init = c_can_pci_reset_pch,
+ .bar = 1,
+};
+
+#define C_CAN_ID(_vend, _dev, _driverdata) { \
+ PCI_DEVICE(_vend, _dev), \
+ .driver_data = (unsigned long)&_driverdata, \
+}
+static DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = {
+ C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN,
+ c_can_sta2x11),
+ C_CAN_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_CAN,
+ c_can_pch),
+ {},
+};
+static struct pci_driver c_can_pci_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = c_can_pci_tbl,
+ .probe = c_can_pci_probe,
+ .remove = c_can_pci_remove,
+};
+
+module_pci_driver(c_can_pci_driver);
+
+MODULE_AUTHOR("Federico Vaga <federico.vaga@gmail.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PCI CAN bus driver for Bosch C_CAN/D_CAN controller");
+MODULE_DEVICE_TABLE(pci, c_can_pci_tbl);
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
new file mode 100644
index 00000000000..12430be6448
--- /dev/null
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -0,0 +1,432 @@
+/*
+ * Platform CAN bus driver for Bosch C_CAN controller
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Bhupesh Sharma <bhupesh.sharma@st.com>
+ *
+ * Borrowed heavily from the C_CAN driver originally written by:
+ * Copyright (C) 2007
+ * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de>
+ * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch>
+ *
+ * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B.
+ * Bosch C_CAN user manual can be obtained from:
+ * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/
+ * users_manual_c_can.pdf
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <linux/can/dev.h>
+
+#include "c_can.h"
+
+#define CAN_RAMINIT_START_MASK(i) (0x001 << (i))
+#define CAN_RAMINIT_DONE_MASK(i) (0x100 << (i))
+#define CAN_RAMINIT_ALL_MASK(i) (0x101 << (i))
+#define DCAN_RAM_INIT_BIT (1 << 3)
+static DEFINE_SPINLOCK(raminit_lock);
+/*
+ * 16-bit c_can registers can be arranged differently in the memory
+ * architecture of different implementations. For example: 16-bit
+ * registers can be aligned to a 16-bit boundary or 32-bit boundary etc.
+ * Handle the same by providing a common read/write interface.
+ */
+static u16 c_can_plat_read_reg_aligned_to_16bit(const struct c_can_priv *priv,
+ enum reg index)
+{
+ return readw(priv->base + priv->regs[index]);
+}
+
+static void c_can_plat_write_reg_aligned_to_16bit(const struct c_can_priv *priv,
+ enum reg index, u16 val)
+{
+ writew(val, priv->base + priv->regs[index]);
+}
+
+static u16 c_can_plat_read_reg_aligned_to_32bit(const struct c_can_priv *priv,
+ enum reg index)
+{
+ return readw(priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
+ enum reg index, u16 val)
+{
+ writew(val, priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
+ u32 val)
+{
+ /* We look only at the bits of our instance. */
+ val &= mask;
+ while ((readl(priv->raminit_ctrlreg) & mask) != val)
+ udelay(1);
+}
+
+static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
+{
+ u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance);
+ u32 ctrl;
+
+ spin_lock(&raminit_lock);
+
+ ctrl = readl(priv->raminit_ctrlreg);
+ /* We clear the done and start bit first. The start bit is
+ * looking at the 0 -> transition, but is not self clearing;
+ * And we clear the init done bit as well.
+ */
+ ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance);
+ ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
+ writel(ctrl, priv->raminit_ctrlreg);
+ ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance);
+ c_can_hw_raminit_wait_ti(priv, ctrl, mask);
+
+ if (enable) {
+ /* Set start bit and wait for the done bit. */
+ ctrl |= CAN_RAMINIT_START_MASK(priv->instance);
+ writel(ctrl, priv->raminit_ctrlreg);
+ ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
+ c_can_hw_raminit_wait_ti(priv, ctrl, mask);
+ }
+ spin_unlock(&raminit_lock);
+}
+
+static u32 c_can_plat_read_reg32(const struct c_can_priv *priv, enum reg index)
+{
+ u32 val;
+
+ val = priv->read_reg(priv, index);
+ val |= ((u32) priv->read_reg(priv, index + 1)) << 16;
+
+ return val;
+}
+
+static void c_can_plat_write_reg32(const struct c_can_priv *priv, enum reg index,
+ u32 val)
+{
+ priv->write_reg(priv, index + 1, val >> 16);
+ priv->write_reg(priv, index, val);
+}
+
+static u32 d_can_plat_read_reg32(const struct c_can_priv *priv, enum reg index)
+{
+ return readl(priv->base + priv->regs[index]);
+}
+
+static void d_can_plat_write_reg32(const struct c_can_priv *priv, enum reg index,
+ u32 val)
+{
+ writel(val, priv->base + priv->regs[index]);
+}
+
+static void c_can_hw_raminit_wait(const struct c_can_priv *priv, u32 mask)
+{
+ while (priv->read_reg32(priv, C_CAN_FUNCTION_REG) & mask)
+ udelay(1);
+}
+
+static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable)
+{
+ u32 ctrl;
+
+ ctrl = priv->read_reg32(priv, C_CAN_FUNCTION_REG);
+ ctrl &= ~DCAN_RAM_INIT_BIT;
+ priv->write_reg32(priv, C_CAN_FUNCTION_REG, ctrl);
+ c_can_hw_raminit_wait(priv, ctrl);
+
+ if (enable) {
+ ctrl |= DCAN_RAM_INIT_BIT;
+ priv->write_reg32(priv, C_CAN_FUNCTION_REG, ctrl);
+ c_can_hw_raminit_wait(priv, ctrl);
+ }
+}
+
+static struct platform_device_id c_can_id_table[] = {
+ [BOSCH_C_CAN_PLATFORM] = {
+ .name = KBUILD_MODNAME,
+ .driver_data = BOSCH_C_CAN,
+ },
+ [BOSCH_C_CAN] = {
+ .name = "c_can",
+ .driver_data = BOSCH_C_CAN,
+ },
+ [BOSCH_D_CAN] = {
+ .name = "d_can",
+ .driver_data = BOSCH_D_CAN,
+ }, {
+ }
+};
+MODULE_DEVICE_TABLE(platform, c_can_id_table);
+
+static const struct of_device_id c_can_of_table[] = {
+ { .compatible = "bosch,c_can", .data = &c_can_id_table[BOSCH_C_CAN] },
+ { .compatible = "bosch,d_can", .data = &c_can_id_table[BOSCH_D_CAN] },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, c_can_of_table);
+
+static int c_can_plat_probe(struct platform_device *pdev)
+{
+ int ret;
+ void __iomem *addr;
+ struct net_device *dev;
+ struct c_can_priv *priv;
+ const struct of_device_id *match;
+ const struct platform_device_id *id;
+ struct resource *mem, *res;
+ int irq;
+ struct clk *clk;
+
+ if (pdev->dev.of_node) {
+ match = of_match_device(c_can_of_table, &pdev->dev);
+ if (!match) {
+ dev_err(&pdev->dev, "Failed to find matching dt id\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+ id = match->data;
+ } else {
+ id = platform_get_device_id(pdev);
+ }
+
+ /* get the appropriate clk */
+ clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "no clock defined\n");
+ ret = -ENODEV;
+ goto exit;
+ }
+
+ /* get the platform data */
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!mem || irq <= 0) {
+ ret = -ENODEV;
+ goto exit_free_clk;
+ }
+
+ if (!request_mem_region(mem->start, resource_size(mem),
+ KBUILD_MODNAME)) {
+ dev_err(&pdev->dev, "resource unavailable\n");
+ ret = -ENODEV;
+ goto exit_free_clk;
+ }
+
+ addr = ioremap(mem->start, resource_size(mem));
+ if (!addr) {
+ dev_err(&pdev->dev, "failed to map can port\n");
+ ret = -ENOMEM;
+ goto exit_release_mem;
+ }
+
+ /* allocate the c_can device */
+ dev = alloc_c_can_dev();
+ if (!dev) {
+ ret = -ENOMEM;
+ goto exit_iounmap;
+ }
+
+ priv = netdev_priv(dev);
+ switch (id->driver_data) {
+ case BOSCH_C_CAN:
+ priv->regs = reg_map_c_can;
+ switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
+ case IORESOURCE_MEM_32BIT:
+ priv->read_reg = c_can_plat_read_reg_aligned_to_32bit;
+ priv->write_reg = c_can_plat_write_reg_aligned_to_32bit;
+ priv->read_reg32 = c_can_plat_read_reg32;
+ priv->write_reg32 = c_can_plat_write_reg32;
+ break;
+ case IORESOURCE_MEM_16BIT:
+ default:
+ priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
+ priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
+ priv->read_reg32 = c_can_plat_read_reg32;
+ priv->write_reg32 = c_can_plat_write_reg32;
+ break;
+ }
+ break;
+ case BOSCH_D_CAN:
+ priv->regs = reg_map_d_can;
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+ priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
+ priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
+ priv->read_reg32 = d_can_plat_read_reg32;
+ priv->write_reg32 = d_can_plat_write_reg32;
+
+ if (pdev->dev.of_node)
+ priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
+ else
+ priv->instance = pdev->id;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ /* Not all D_CAN modules have a separate register for the D_CAN
+ * RAM initialization. Use default RAM init bit in D_CAN module
+ * if not specified in DT.
+ */
+ if (!res) {
+ priv->raminit = c_can_hw_raminit;
+ break;
+ }
+
+ priv->raminit_ctrlreg = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0)
+ dev_info(&pdev->dev, "control memory is not used for raminit\n");
+ else
+ priv->raminit = c_can_hw_raminit_ti;
+ break;
+ default:
+ ret = -EINVAL;
+ goto exit_free_device;
+ }
+
+ dev->irq = irq;
+ priv->base = addr;
+ priv->device = &pdev->dev;
+ priv->can.clock.freq = clk_get_rate(clk);
+ priv->priv = clk;
+ priv->type = id->driver_data;
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ ret = register_c_can_dev(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ KBUILD_MODNAME, ret);
+ goto exit_free_device;
+ }
+
+ dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n",
+ KBUILD_MODNAME, priv->base, dev->irq);
+ return 0;
+
+exit_free_device:
+ free_c_can_dev(dev);
+exit_iounmap:
+ iounmap(addr);
+exit_release_mem:
+ release_mem_region(mem->start, resource_size(mem));
+exit_free_clk:
+ clk_put(clk);
+exit:
+ dev_err(&pdev->dev, "probe failed\n");
+
+ return ret;
+}
+
+static int c_can_plat_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct c_can_priv *priv = netdev_priv(dev);
+ struct resource *mem;
+
+ unregister_c_can_dev(dev);
+
+ free_c_can_dev(dev);
+ iounmap(priv->base);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+
+ clk_put(priv->priv);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int c_can_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ int ret;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct c_can_priv *priv = netdev_priv(ndev);
+
+ if (priv->type != BOSCH_D_CAN) {
+ dev_warn(&pdev->dev, "Not supported\n");
+ return 0;
+ }
+
+ if (netif_running(ndev)) {
+ netif_stop_queue(ndev);
+ netif_device_detach(ndev);
+ }
+
+ ret = c_can_power_down(ndev);
+ if (ret) {
+ netdev_err(ndev, "failed to enter power down mode\n");
+ return ret;
+ }
+
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ return 0;
+}
+
+static int c_can_resume(struct platform_device *pdev)
+{
+ int ret;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct c_can_priv *priv = netdev_priv(ndev);
+
+ if (priv->type != BOSCH_D_CAN) {
+ dev_warn(&pdev->dev, "Not supported\n");
+ return 0;
+ }
+
+ ret = c_can_power_up(ndev);
+ if (ret) {
+ netdev_err(ndev, "Still in power down mode\n");
+ return ret;
+ }
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_running(ndev)) {
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
+
+ return 0;
+}
+#else
+#define c_can_suspend NULL
+#define c_can_resume NULL
+#endif
+
+static struct platform_driver c_can_plat_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .of_match_table = c_can_of_table,
+ },
+ .probe = c_can_plat_probe,
+ .remove = c_can_plat_remove,
+ .suspend = c_can_suspend,
+ .resume = c_can_resume,
+ .id_table = c_can_id_table,
+};
+
+module_platform_driver(c_can_plat_driver);
+
+MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Platform CAN bus driver for Bosch C_CAN controller");
diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
new file mode 100644
index 00000000000..6a9a5ba7922
--- /dev/null
+++ b/drivers/net/can/cc770/Kconfig
@@ -0,0 +1,21 @@
+menuconfig CAN_CC770
+ tristate "Bosch CC770 and Intel AN82527 devices"
+ depends on HAS_IOMEM
+
+if CAN_CC770
+
+config CAN_CC770_ISA
+ tristate "ISA Bus based legacy CC770 driver"
+ ---help---
+ This driver adds legacy support for CC770 and AN82527 chips
+ connected to the ISA bus using I/O port, memory mapped or
+ indirect access.
+
+config CAN_CC770_PLATFORM
+ tristate "Generic Platform Bus based CC770 driver"
+ ---help---
+ This driver adds support for the CC770 and AN82527 chips
+ connected to the "platform bus" (Linux abstraction for directly
+ to the processor attached devices).
+
+endif
diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
new file mode 100644
index 00000000000..9fb8321b33e
--- /dev/null
+++ b/drivers/net/can/cc770/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the Bosch CC770 CAN controller drivers.
+#
+
+obj-$(CONFIG_CAN_CC770) += cc770.o
+obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
+obj-$(CONFIG_CAN_CC770_PLATFORM) += cc770_platform.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
new file mode 100644
index 00000000000..d8379278d64
--- /dev/null
+++ b/drivers/net/can/cc770/cc770.c
@@ -0,0 +1,883 @@
+/*
+ * Core driver for the CC770 and AN82527 CAN controllers
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/platform/cc770.h>
+
+#include "cc770.h"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(KBUILD_MODNAME "CAN netdevice driver");
+
+/*
+ * The CC770 is a CAN controller from Bosch, which is 100% compatible
+ * with the AN82527 from Intel, but with "bugs" being fixed and some
+ * additional functionality, mainly:
+ *
+ * 1. RX and TX error counters are readable.
+ * 2. Support of silent (listen-only) mode.
+ * 3. Message object 15 can receive all types of frames, also RTR and EFF.
+ *
+ * Details are available from Bosch's "CC770_Product_Info_2007-01.pdf",
+ * which explains in detail the compatibility between the CC770 and the
+ * 82527. This driver use the additional functionality 3. on real CC770
+ * devices. Unfortunately, the CC770 does still not store the message
+ * identifier of received remote transmission request frames and
+ * therefore it's set to 0.
+ *
+ * The message objects 1..14 can be used for TX and RX while the message
+ * objects 15 is optimized for RX. It has a shadow register for reliable
+ * data receiption under heavy bus load. Therefore it makes sense to use
+ * this message object for the needed use case. The frame type (EFF/SFF)
+ * for the message object 15 can be defined via kernel module parameter
+ * "msgobj15_eff". If not equal 0, it will receive 29-bit EFF frames,
+ * otherwise 11 bit SFF messages.
+ */
+static int msgobj15_eff;
+module_param(msgobj15_eff, int, S_IRUGO);
+MODULE_PARM_DESC(msgobj15_eff, "Extended 29-bit frames for message object 15 "
+ "(default: 11-bit standard frames)");
+
+static int i82527_compat;
+module_param(i82527_compat, int, S_IRUGO);
+MODULE_PARM_DESC(i82527_compat, "Strict Intel 82527 comptibility mode "
+ "without using additional functions");
+
+/*
+ * This driver uses the last 5 message objects 11..15. The definitions
+ * and structure below allows to configure and assign them to the real
+ * message object.
+ */
+static unsigned char cc770_obj_flags[CC770_OBJ_MAX] = {
+ [CC770_OBJ_RX0] = CC770_OBJ_FLAG_RX,
+ [CC770_OBJ_RX1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_EFF,
+ [CC770_OBJ_RX_RTR0] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR,
+ [CC770_OBJ_RX_RTR1] = CC770_OBJ_FLAG_RX | CC770_OBJ_FLAG_RTR |
+ CC770_OBJ_FLAG_EFF,
+ [CC770_OBJ_TX] = 0,
+};
+
+static const struct can_bittiming_const cc770_bittiming_const = {
+ .name = KBUILD_MODNAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+};
+
+static inline int intid2obj(unsigned int intid)
+{
+ if (intid == 2)
+ return 0;
+ else
+ return MSGOBJ_LAST + 2 - intid;
+}
+
+static void enable_all_objs(const struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ u8 msgcfg;
+ unsigned char obj_flags;
+ unsigned int o, mo;
+
+ for (o = 0; o < ARRAY_SIZE(priv->obj_flags); o++) {
+ obj_flags = priv->obj_flags[o];
+ mo = obj2msgobj(o);
+
+ if (obj_flags & CC770_OBJ_FLAG_RX) {
+ /*
+ * We don't need extra objects for RTR and EFF if
+ * the additional CC770 functions are enabled.
+ */
+ if (priv->control_normal_mode & CTRL_EAF) {
+ if (o > 0)
+ continue;
+ netdev_dbg(dev, "Message object %d for "
+ "RX data, RTR, SFF and EFF\n", mo);
+ } else {
+ netdev_dbg(dev,
+ "Message object %d for RX %s %s\n",
+ mo, obj_flags & CC770_OBJ_FLAG_RTR ?
+ "RTR" : "data",
+ obj_flags & CC770_OBJ_FLAG_EFF ?
+ "EFF" : "SFF");
+ }
+
+ if (obj_flags & CC770_OBJ_FLAG_EFF)
+ msgcfg = MSGCFG_XTD;
+ else
+ msgcfg = 0;
+ if (obj_flags & CC770_OBJ_FLAG_RTR)
+ msgcfg |= MSGCFG_DIR;
+
+ cc770_write_reg(priv, msgobj[mo].config, msgcfg);
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_SET | TXIE_RES |
+ RXIE_SET | INTPND_RES);
+
+ if (obj_flags & CC770_OBJ_FLAG_RTR)
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ NEWDAT_RES | CPUUPD_SET |
+ TXRQST_RES | RMTPND_RES);
+ else
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ NEWDAT_RES | MSGLST_RES |
+ TXRQST_RES | RMTPND_RES);
+ } else {
+ netdev_dbg(dev, "Message object %d for "
+ "TX data, RTR, SFF and EFF\n", mo);
+
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ RMTPND_RES | TXRQST_RES |
+ CPUUPD_RES | NEWDAT_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_RES | TXIE_RES |
+ RXIE_RES | INTPND_RES);
+ }
+ }
+}
+
+static void disable_all_objs(const struct cc770_priv *priv)
+{
+ int o, mo;
+
+ for (o = 0; o < ARRAY_SIZE(priv->obj_flags); o++) {
+ mo = obj2msgobj(o);
+
+ if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX) {
+ if (o > 0 && priv->control_normal_mode & CTRL_EAF)
+ continue;
+
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ NEWDAT_RES | MSGLST_RES |
+ TXRQST_RES | RMTPND_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_RES | TXIE_RES |
+ RXIE_RES | INTPND_RES);
+ } else {
+ /* Clear message object for send */
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ RMTPND_RES | TXRQST_RES |
+ CPUUPD_RES | NEWDAT_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_RES | TXIE_RES |
+ RXIE_RES | INTPND_RES);
+ }
+ }
+}
+
+static void set_reset_mode(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+
+ /* Enable configuration and puts chip in bus-off, disable interrupts */
+ cc770_write_reg(priv, control, CTRL_CCE | CTRL_INI);
+
+ priv->can.state = CAN_STATE_STOPPED;
+
+ /* Clear interrupts */
+ cc770_read_reg(priv, interrupt);
+
+ /* Clear status register */
+ cc770_write_reg(priv, status, 0);
+
+ /* Disable all used message objects */
+ disable_all_objs(priv);
+}
+
+static void set_normal_mode(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+
+ /* Clear interrupts */
+ cc770_read_reg(priv, interrupt);
+
+ /* Clear status register and pre-set last error code */
+ cc770_write_reg(priv, status, STAT_LEC_MASK);
+
+ /* Enable all used message objects*/
+ enable_all_objs(dev);
+
+ /*
+ * Clear bus-off, interrupts only for errors,
+ * not for status change
+ */
+ cc770_write_reg(priv, control, priv->control_normal_mode);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+}
+
+static void chipset_init(struct cc770_priv *priv)
+{
+ int mo, id, data;
+
+ /* Enable configuration and put chip in bus-off, disable interrupts */
+ cc770_write_reg(priv, control, (CTRL_CCE | CTRL_INI));
+
+ /* Set CLKOUT divider and slew rates */
+ cc770_write_reg(priv, clkout, priv->clkout);
+
+ /* Configure CPU interface / CLKOUT enable */
+ cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
+
+ /* Set bus configuration */
+ cc770_write_reg(priv, bus_config, priv->bus_config);
+
+ /* Clear interrupts */
+ cc770_read_reg(priv, interrupt);
+
+ /* Clear status register */
+ cc770_write_reg(priv, status, 0);
+
+ /* Clear and invalidate message objects */
+ for (mo = MSGOBJ_FIRST; mo <= MSGOBJ_LAST; mo++) {
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ INTPND_UNC | RXIE_RES |
+ TXIE_RES | MSGVAL_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ INTPND_RES | RXIE_RES |
+ TXIE_RES | MSGVAL_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ NEWDAT_RES | MSGLST_RES |
+ TXRQST_RES | RMTPND_RES);
+ for (data = 0; data < 8; data++)
+ cc770_write_reg(priv, msgobj[mo].data[data], 0);
+ for (id = 0; id < 4; id++)
+ cc770_write_reg(priv, msgobj[mo].id[id], 0);
+ cc770_write_reg(priv, msgobj[mo].config, 0);
+ }
+
+ /* Set all global ID masks to "don't care" */
+ cc770_write_reg(priv, global_mask_std[0], 0);
+ cc770_write_reg(priv, global_mask_std[1], 0);
+ cc770_write_reg(priv, global_mask_ext[0], 0);
+ cc770_write_reg(priv, global_mask_ext[1], 0);
+ cc770_write_reg(priv, global_mask_ext[2], 0);
+ cc770_write_reg(priv, global_mask_ext[3], 0);
+
+}
+
+static int cc770_probe_chip(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+
+ /* Enable configuration, put chip in bus-off, disable ints */
+ cc770_write_reg(priv, control, CTRL_CCE | CTRL_EAF | CTRL_INI);
+ /* Configure cpu interface / CLKOUT disable */
+ cc770_write_reg(priv, cpu_interface, priv->cpu_interface);
+
+ /*
+ * Check if hardware reset is still inactive or maybe there
+ * is no chip in this address space
+ */
+ if (cc770_read_reg(priv, cpu_interface) & CPUIF_RST) {
+ netdev_info(dev, "probing @0x%p failed (reset)\n",
+ priv->reg_base);
+ return -ENODEV;
+ }
+
+ /* Write and read back test pattern (some arbitrary values) */
+ cc770_write_reg(priv, msgobj[1].data[1], 0x25);
+ cc770_write_reg(priv, msgobj[2].data[3], 0x52);
+ cc770_write_reg(priv, msgobj[10].data[6], 0xc3);
+ if ((cc770_read_reg(priv, msgobj[1].data[1]) != 0x25) ||
+ (cc770_read_reg(priv, msgobj[2].data[3]) != 0x52) ||
+ (cc770_read_reg(priv, msgobj[10].data[6]) != 0xc3)) {
+ netdev_info(dev, "probing @0x%p failed (pattern)\n",
+ priv->reg_base);
+ return -ENODEV;
+ }
+
+ /* Check if this chip is a CC770 supporting additional functions */
+ if (cc770_read_reg(priv, control) & CTRL_EAF)
+ priv->control_normal_mode |= CTRL_EAF;
+
+ return 0;
+}
+
+static void cc770_start(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+
+ /* leave reset mode */
+ if (priv->can.state != CAN_STATE_STOPPED)
+ set_reset_mode(dev);
+
+ /* leave reset mode */
+ set_normal_mode(dev);
+}
+
+static int cc770_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ cc770_start(dev);
+ netif_wake_queue(dev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int cc770_set_bittiming(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u8 btr0, btr1;
+
+ btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+ btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+ (((bt->phase_seg2 - 1) & 0x7) << 4);
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ btr1 |= 0x80;
+
+ netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+ cc770_write_reg(priv, bit_timing_0, btr0);
+ cc770_write_reg(priv, bit_timing_1, btr1);
+
+ return 0;
+}
+
+static int cc770_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+
+ bec->txerr = cc770_read_reg(priv, tx_error_counter);
+ bec->rxerr = cc770_read_reg(priv, rx_error_counter);
+
+ return 0;
+}
+
+static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ unsigned int mo = obj2msgobj(CC770_OBJ_TX);
+ u8 dlc, rtr;
+ u32 id;
+ int i;
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ if ((cc770_read_reg(priv,
+ msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) {
+ netdev_err(dev, "TX register is still occupied!\n");
+ return NETDEV_TX_BUSY;
+ }
+
+ netif_stop_queue(dev);
+
+ dlc = cf->can_dlc;
+ id = cf->can_id;
+ if (cf->can_id & CAN_RTR_FLAG)
+ rtr = 0;
+ else
+ rtr = MSGCFG_DIR;
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES);
+ if (id & CAN_EFF_FLAG) {
+ id &= CAN_EFF_MASK;
+ cc770_write_reg(priv, msgobj[mo].config,
+ (dlc << 4) | rtr | MSGCFG_XTD);
+ cc770_write_reg(priv, msgobj[mo].id[3], id << 3);
+ cc770_write_reg(priv, msgobj[mo].id[2], id >> 5);
+ cc770_write_reg(priv, msgobj[mo].id[1], id >> 13);
+ cc770_write_reg(priv, msgobj[mo].id[0], id >> 21);
+ } else {
+ id &= CAN_SFF_MASK;
+ cc770_write_reg(priv, msgobj[mo].config, (dlc << 4) | rtr);
+ cc770_write_reg(priv, msgobj[mo].id[0], id >> 3);
+ cc770_write_reg(priv, msgobj[mo].id[1], id << 5);
+ }
+
+ for (i = 0; i < dlc; i++)
+ cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]);
+
+ /* Store echo skb before starting the transfer */
+ can_put_echo_skb(skb, dev, 0);
+
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC);
+
+ stats->tx_bytes += dlc;
+
+
+ /*
+ * HM: We had some cases of repeated IRQs so make sure the
+ * INT is acknowledged I know it's already further up, but
+ * doing again fixed the issue
+ */
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+
+ return NETDEV_TX_OK;
+}
+
+static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u8 config;
+ u32 id;
+ int i;
+
+ skb = alloc_can_skb(dev, &cf);
+ if (!skb)
+ return;
+
+ config = cc770_read_reg(priv, msgobj[mo].config);
+
+ if (ctrl1 & RMTPND_SET) {
+ /*
+ * Unfortunately, the chip does not store the real message
+ * identifier of the received remote transmission request
+ * frame. Therefore we set it to 0.
+ */
+ cf->can_id = CAN_RTR_FLAG;
+ if (config & MSGCFG_XTD)
+ cf->can_id |= CAN_EFF_FLAG;
+ cf->can_dlc = 0;
+ } else {
+ if (config & MSGCFG_XTD) {
+ id = cc770_read_reg(priv, msgobj[mo].id[3]);
+ id |= cc770_read_reg(priv, msgobj[mo].id[2]) << 8;
+ id |= cc770_read_reg(priv, msgobj[mo].id[1]) << 16;
+ id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 24;
+ id >>= 3;
+ id |= CAN_EFF_FLAG;
+ } else {
+ id = cc770_read_reg(priv, msgobj[mo].id[1]);
+ id |= cc770_read_reg(priv, msgobj[mo].id[0]) << 8;
+ id >>= 5;
+ }
+
+ cf->can_id = id;
+ cf->can_dlc = get_can_dlc((config & 0xf0) >> 4);
+ for (i = 0; i < cf->can_dlc; i++)
+ cf->data[i] = cc770_read_reg(priv, msgobj[mo].data[i]);
+ }
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static int cc770_err(struct net_device *dev, u8 status)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u8 lec;
+
+ netdev_dbg(dev, "status interrupt (%#x)\n", status);
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (!skb)
+ return -ENOMEM;
+
+ /* Use extended functions of the CC770 */
+ if (priv->control_normal_mode & CTRL_EAF) {
+ cf->data[6] = cc770_read_reg(priv, tx_error_counter);
+ cf->data[7] = cc770_read_reg(priv, rx_error_counter);
+ }
+
+ if (status & STAT_BOFF) {
+ /* Disable interrupts */
+ cc770_write_reg(priv, control, CTRL_INI);
+ cf->can_id |= CAN_ERR_BUSOFF;
+ priv->can.state = CAN_STATE_BUS_OFF;
+ can_bus_off(dev);
+ } else if (status & STAT_WARN) {
+ cf->can_id |= CAN_ERR_CRTL;
+ /* Only the CC770 does show error passive */
+ if (cf->data[7] > 127) {
+ cf->data[1] = CAN_ERR_CRTL_RX_PASSIVE |
+ CAN_ERR_CRTL_TX_PASSIVE;
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ priv->can.can_stats.error_passive++;
+ } else {
+ cf->data[1] = CAN_ERR_CRTL_RX_WARNING |
+ CAN_ERR_CRTL_TX_WARNING;
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ priv->can.can_stats.error_warning++;
+ }
+ } else {
+ /* Back to error avtive */
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_ACTIVE;
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ }
+
+ lec = status & STAT_LEC_MASK;
+ if (lec < 7 && lec > 0) {
+ if (lec == STAT_LEC_ACK) {
+ cf->can_id |= CAN_ERR_ACK;
+ } else {
+ cf->can_id |= CAN_ERR_PROT;
+ switch (lec) {
+ case STAT_LEC_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ case STAT_LEC_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case STAT_LEC_BIT1:
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ break;
+ case STAT_LEC_BIT0:
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ break;
+ case STAT_LEC_CRC:
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+ break;
+ }
+ }
+ }
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ return 0;
+}
+
+static int cc770_status_interrupt(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ u8 status;
+
+ status = cc770_read_reg(priv, status);
+ /* Reset the status register including RXOK and TXOK */
+ cc770_write_reg(priv, status, STAT_LEC_MASK);
+
+ if (status & (STAT_WARN | STAT_BOFF) ||
+ (status & STAT_LEC_MASK) != STAT_LEC_MASK) {
+ cc770_err(dev, status);
+ return status & STAT_BOFF;
+ }
+
+ return 0;
+}
+
+static void cc770_rx_interrupt(struct net_device *dev, unsigned int o)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ unsigned int mo = obj2msgobj(o);
+ u8 ctrl1;
+ int n = CC770_MAX_MSG;
+
+ while (n--) {
+ ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
+
+ if (!(ctrl1 & NEWDAT_SET)) {
+ /* Check for RTR if additional functions are enabled */
+ if (priv->control_normal_mode & CTRL_EAF) {
+ if (!(cc770_read_reg(priv, msgobj[mo].ctrl0) &
+ INTPND_SET))
+ break;
+ } else {
+ break;
+ }
+ }
+
+ if (ctrl1 & MSGLST_SET) {
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ }
+ if (mo < MSGOBJ_LAST)
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ NEWDAT_RES | MSGLST_RES |
+ TXRQST_UNC | RMTPND_UNC);
+ cc770_rx(dev, mo, ctrl1);
+
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_SET | TXIE_RES |
+ RXIE_SET | INTPND_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ NEWDAT_RES | MSGLST_RES |
+ TXRQST_RES | RMTPND_RES);
+ }
+}
+
+static void cc770_rtr_interrupt(struct net_device *dev, unsigned int o)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ unsigned int mo = obj2msgobj(o);
+ u8 ctrl0, ctrl1;
+ int n = CC770_MAX_MSG;
+
+ while (n--) {
+ ctrl0 = cc770_read_reg(priv, msgobj[mo].ctrl0);
+ if (!(ctrl0 & INTPND_SET))
+ break;
+
+ ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1);
+ cc770_rx(dev, mo, ctrl1);
+
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_SET | TXIE_RES |
+ RXIE_SET | INTPND_RES);
+ cc770_write_reg(priv, msgobj[mo].ctrl1,
+ NEWDAT_RES | CPUUPD_SET |
+ TXRQST_RES | RMTPND_RES);
+ }
+}
+
+static void cc770_tx_interrupt(struct net_device *dev, unsigned int o)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ unsigned int mo = obj2msgobj(o);
+
+ /* Nothing more to send, switch off interrupts */
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES);
+ /*
+ * We had some cases of repeated IRQ so make sure the
+ * INT is acknowledged
+ */
+ cc770_write_reg(priv, msgobj[mo].ctrl0,
+ MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES);
+
+ stats->tx_packets++;
+ can_get_echo_skb(dev, 0);
+ netif_wake_queue(dev);
+}
+
+static irqreturn_t cc770_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct cc770_priv *priv = netdev_priv(dev);
+ u8 intid;
+ int o, n = 0;
+
+ /* Shared interrupts and IRQ off? */
+ if (priv->can.state == CAN_STATE_STOPPED)
+ return IRQ_NONE;
+
+ if (priv->pre_irq)
+ priv->pre_irq(priv);
+
+ while (n < CC770_MAX_IRQ) {
+ /* Read the highest pending interrupt request */
+ intid = cc770_read_reg(priv, interrupt);
+ if (!intid)
+ break;
+ n++;
+
+ if (intid == 1) {
+ /* Exit in case of bus-off */
+ if (cc770_status_interrupt(dev))
+ break;
+ } else {
+ o = intid2obj(intid);
+
+ if (o >= CC770_OBJ_MAX) {
+ netdev_err(dev, "Unexpected interrupt id %d\n",
+ intid);
+ continue;
+ }
+
+ if (priv->obj_flags[o] & CC770_OBJ_FLAG_RTR)
+ cc770_rtr_interrupt(dev, o);
+ else if (priv->obj_flags[o] & CC770_OBJ_FLAG_RX)
+ cc770_rx_interrupt(dev, o);
+ else
+ cc770_tx_interrupt(dev, o);
+ }
+ }
+
+ if (priv->post_irq)
+ priv->post_irq(priv);
+
+ if (n >= CC770_MAX_IRQ)
+ netdev_dbg(dev, "%d messages handled in ISR", n);
+
+ return (n) ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int cc770_open(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* set chip into reset mode */
+ set_reset_mode(dev);
+
+ /* common open */
+ err = open_candev(dev);
+ if (err)
+ return err;
+
+ err = request_irq(dev->irq, &cc770_interrupt, priv->irq_flags,
+ dev->name, dev);
+ if (err) {
+ close_candev(dev);
+ return -EAGAIN;
+ }
+
+ /* init and start chip */
+ cc770_start(dev);
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static int cc770_close(struct net_device *dev)
+{
+ netif_stop_queue(dev);
+ set_reset_mode(dev);
+
+ free_irq(dev->irq, dev);
+ close_candev(dev);
+
+ return 0;
+}
+
+struct net_device *alloc_cc770dev(int sizeof_priv)
+{
+ struct net_device *dev;
+ struct cc770_priv *priv;
+
+ dev = alloc_candev(sizeof(struct cc770_priv) + sizeof_priv,
+ CC770_ECHO_SKB_MAX);
+ if (!dev)
+ return NULL;
+
+ priv = netdev_priv(dev);
+
+ priv->dev = dev;
+ priv->can.bittiming_const = &cc770_bittiming_const;
+ priv->can.do_set_bittiming = cc770_set_bittiming;
+ priv->can.do_set_mode = cc770_set_mode;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+
+ memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags));
+
+ if (sizeof_priv)
+ priv->priv = (void *)priv + sizeof(struct cc770_priv);
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_cc770dev);
+
+void free_cc770dev(struct net_device *dev)
+{
+ free_candev(dev);
+}
+EXPORT_SYMBOL_GPL(free_cc770dev);
+
+static const struct net_device_ops cc770_netdev_ops = {
+ .ndo_open = cc770_open,
+ .ndo_stop = cc770_close,
+ .ndo_start_xmit = cc770_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+int register_cc770dev(struct net_device *dev)
+{
+ struct cc770_priv *priv = netdev_priv(dev);
+ int err;
+
+ err = cc770_probe_chip(dev);
+ if (err)
+ return err;
+
+ dev->netdev_ops = &cc770_netdev_ops;
+
+ dev->flags |= IFF_ECHO; /* we support local echo */
+
+ /* Should we use additional functions? */
+ if (!i82527_compat && priv->control_normal_mode & CTRL_EAF) {
+ priv->can.do_get_berr_counter = cc770_get_berr_counter;
+ priv->control_normal_mode = CTRL_IE | CTRL_EAF | CTRL_EIE;
+ netdev_dbg(dev, "i82527 mode with additional functions\n");
+ } else {
+ priv->control_normal_mode = CTRL_IE | CTRL_EIE;
+ netdev_dbg(dev, "strict i82527 compatibility mode\n");
+ }
+
+ chipset_init(priv);
+ set_reset_mode(dev);
+
+ return register_candev(dev);
+}
+EXPORT_SYMBOL_GPL(register_cc770dev);
+
+void unregister_cc770dev(struct net_device *dev)
+{
+ set_reset_mode(dev);
+ unregister_candev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_cc770dev);
+
+static __init int cc770_init(void)
+{
+ if (msgobj15_eff) {
+ cc770_obj_flags[CC770_OBJ_RX0] |= CC770_OBJ_FLAG_EFF;
+ cc770_obj_flags[CC770_OBJ_RX1] &= ~CC770_OBJ_FLAG_EFF;
+ }
+
+ pr_info("CAN netdevice driver\n");
+
+ return 0;
+}
+module_init(cc770_init);
+
+static __exit void cc770_exit(void)
+{
+ pr_info("driver removed\n");
+}
+module_exit(cc770_exit);
diff --git a/drivers/net/can/cc770/cc770.h b/drivers/net/can/cc770/cc770.h
new file mode 100644
index 00000000000..a1739db98d9
--- /dev/null
+++ b/drivers/net/can/cc770/cc770.h
@@ -0,0 +1,203 @@
+/*
+ * Core driver for the CC770 and AN82527 CAN controllers
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef CC770_DEV_H
+#define CC770_DEV_H
+
+#include <linux/can/dev.h>
+
+struct cc770_msgobj {
+ u8 ctrl0;
+ u8 ctrl1;
+ u8 id[4];
+ u8 config;
+ u8 data[8];
+ u8 dontuse; /* padding */
+} __packed;
+
+struct cc770_regs {
+ union {
+ struct cc770_msgobj msgobj[16]; /* Message object 1..15 */
+ struct {
+ u8 control; /* Control Register */
+ u8 status; /* Status Register */
+ u8 cpu_interface; /* CPU Interface Register */
+ u8 dontuse1;
+ u8 high_speed_read[2]; /* High Speed Read */
+ u8 global_mask_std[2]; /* Standard Global Mask */
+ u8 global_mask_ext[4]; /* Extended Global Mask */
+ u8 msg15_mask[4]; /* Message 15 Mask */
+ u8 dontuse2[15];
+ u8 clkout; /* Clock Out Register */
+ u8 dontuse3[15];
+ u8 bus_config; /* Bus Configuration Register */
+ u8 dontuse4[15];
+ u8 bit_timing_0; /* Bit Timing Register byte 0 */
+ u8 dontuse5[15];
+ u8 bit_timing_1; /* Bit Timing Register byte 1 */
+ u8 dontuse6[15];
+ u8 interrupt; /* Interrupt Register */
+ u8 dontuse7[15];
+ u8 rx_error_counter; /* Receive Error Counter */
+ u8 dontuse8[15];
+ u8 tx_error_counter; /* Transmit Error Counter */
+ u8 dontuse9[31];
+ u8 p1_conf;
+ u8 dontuse10[15];
+ u8 p2_conf;
+ u8 dontuse11[15];
+ u8 p1_in;
+ u8 dontuse12[15];
+ u8 p2_in;
+ u8 dontuse13[15];
+ u8 p1_out;
+ u8 dontuse14[15];
+ u8 p2_out;
+ u8 dontuse15[15];
+ u8 serial_reset_addr;
+ };
+ };
+} __packed;
+
+/* Control Register (0x00) */
+#define CTRL_INI 0x01 /* Initialization */
+#define CTRL_IE 0x02 /* Interrupt Enable */
+#define CTRL_SIE 0x04 /* Status Interrupt Enable */
+#define CTRL_EIE 0x08 /* Error Interrupt Enable */
+#define CTRL_EAF 0x20 /* Enable additional functions */
+#define CTRL_CCE 0x40 /* Change Configuration Enable */
+
+/* Status Register (0x01) */
+#define STAT_LEC_STUFF 0x01 /* Stuff error */
+#define STAT_LEC_FORM 0x02 /* Form error */
+#define STAT_LEC_ACK 0x03 /* Acknowledgement error */
+#define STAT_LEC_BIT1 0x04 /* Bit1 error */
+#define STAT_LEC_BIT0 0x05 /* Bit0 error */
+#define STAT_LEC_CRC 0x06 /* CRC error */
+#define STAT_LEC_MASK 0x07 /* Last Error Code mask */
+#define STAT_TXOK 0x08 /* Transmit Message Successfully */
+#define STAT_RXOK 0x10 /* Receive Message Successfully */
+#define STAT_WAKE 0x20 /* Wake Up Status */
+#define STAT_WARN 0x40 /* Warning Status */
+#define STAT_BOFF 0x80 /* Bus Off Status */
+
+/*
+ * CPU Interface Register (0x02)
+ * Clock Out Register (0x1f)
+ * Bus Configuration Register (0x2f)
+ *
+ * see include/linux/can/platform/cc770.h
+ */
+
+/* Message Control Register 0 (Base Address + 0x0) */
+#define INTPND_RES 0x01 /* No Interrupt pending */
+#define INTPND_SET 0x02 /* Interrupt pending */
+#define INTPND_UNC 0x03
+#define RXIE_RES 0x04 /* Receive Interrupt Disable */
+#define RXIE_SET 0x08 /* Receive Interrupt Enable */
+#define RXIE_UNC 0x0c
+#define TXIE_RES 0x10 /* Transmit Interrupt Disable */
+#define TXIE_SET 0x20 /* Transmit Interrupt Enable */
+#define TXIE_UNC 0x30
+#define MSGVAL_RES 0x40 /* Message Invalid */
+#define MSGVAL_SET 0x80 /* Message Valid */
+#define MSGVAL_UNC 0xc0
+
+/* Message Control Register 1 (Base Address + 0x01) */
+#define NEWDAT_RES 0x01 /* No New Data */
+#define NEWDAT_SET 0x02 /* New Data */
+#define NEWDAT_UNC 0x03
+#define MSGLST_RES 0x04 /* No Message Lost */
+#define MSGLST_SET 0x08 /* Message Lost */
+#define MSGLST_UNC 0x0c
+#define CPUUPD_RES 0x04 /* No CPU Updating */
+#define CPUUPD_SET 0x08 /* CPU Updating */
+#define CPUUPD_UNC 0x0c
+#define TXRQST_RES 0x10 /* No Transmission Request */
+#define TXRQST_SET 0x20 /* Transmission Request */
+#define TXRQST_UNC 0x30
+#define RMTPND_RES 0x40 /* No Remote Request Pending */
+#define RMTPND_SET 0x80 /* Remote Request Pending */
+#define RMTPND_UNC 0xc0
+
+/* Message Configuration Register (Base Address + 0x06) */
+#define MSGCFG_XTD 0x04 /* Extended Identifier */
+#define MSGCFG_DIR 0x08 /* Direction is Transmit */
+
+#define MSGOBJ_FIRST 1
+#define MSGOBJ_LAST 15
+
+#define CC770_IO_SIZE 0x100
+#define CC770_MAX_IRQ 20 /* max. number of interrupts handled in ISR */
+#define CC770_MAX_MSG 4 /* max. number of messages handled in ISR */
+
+#define CC770_ECHO_SKB_MAX 1
+
+#define cc770_read_reg(priv, member) \
+ priv->read_reg(priv, offsetof(struct cc770_regs, member))
+
+#define cc770_write_reg(priv, member, value) \
+ priv->write_reg(priv, offsetof(struct cc770_regs, member), value)
+
+/*
+ * Message objects and flags used by this driver
+ */
+#define CC770_OBJ_FLAG_RX 0x01
+#define CC770_OBJ_FLAG_RTR 0x02
+#define CC770_OBJ_FLAG_EFF 0x04
+
+enum {
+ CC770_OBJ_RX0 = 0, /* for receiving normal messages */
+ CC770_OBJ_RX1, /* for receiving normal messages */
+ CC770_OBJ_RX_RTR0, /* for receiving remote transmission requests */
+ CC770_OBJ_RX_RTR1, /* for receiving remote transmission requests */
+ CC770_OBJ_TX, /* for sending messages */
+ CC770_OBJ_MAX
+};
+
+#define obj2msgobj(o) (MSGOBJ_LAST - (o)) /* message object 11..15 */
+
+/*
+ * CC770 private data structure
+ */
+struct cc770_priv {
+ struct can_priv can; /* must be the first member */
+ struct sk_buff *echo_skb;
+
+ /* the lower-layer is responsible for appropriate locking */
+ u8 (*read_reg)(const struct cc770_priv *priv, int reg);
+ void (*write_reg)(const struct cc770_priv *priv, int reg, u8 val);
+ void (*pre_irq)(const struct cc770_priv *priv);
+ void (*post_irq)(const struct cc770_priv *priv);
+
+ void *priv; /* for board-specific data */
+ struct net_device *dev;
+
+ void __iomem *reg_base; /* ioremap'ed address to registers */
+ unsigned long irq_flags; /* for request_irq() */
+
+ unsigned char obj_flags[CC770_OBJ_MAX];
+ u8 control_normal_mode; /* Control register for normal mode */
+ u8 cpu_interface; /* CPU interface register */
+ u8 clkout; /* Clock out register */
+ u8 bus_config; /* Bus conffiguration register */
+};
+
+struct net_device *alloc_cc770dev(int sizeof_priv);
+void free_cc770dev(struct net_device *dev);
+int register_cc770dev(struct net_device *dev);
+void unregister_cc770dev(struct net_device *dev);
+
+#endif /* CC770_DEV_H */
diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
new file mode 100644
index 00000000000..87a47c0cfd4
--- /dev/null
+++ b/drivers/net/can/cc770/cc770_isa.c
@@ -0,0 +1,380 @@
+/*
+ * Driver for CC770 and AN82527 CAN controllers on the legacy ISA bus
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Bosch CC770 and Intel AN82527 CAN controllers on the ISA or PC-104 bus.
+ * The I/O port or memory address and the IRQ number must be specified via
+ * module parameters:
+ *
+ * insmod cc770_isa.ko port=0x310,0x380 irq=7,11
+ *
+ * for ISA devices using I/O ports or:
+ *
+ * insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11
+ *
+ * for memory mapped ISA devices.
+ *
+ * Indirect access via address and data port is supported as well:
+ *
+ * insmod cc770_isa.ko port=0x310,0x380 indirect=1 irq=7,11
+ *
+ * Furthermore, the following mode parameter can be defined:
+ *
+ * clk: External oscillator clock frequency (default=16000000 [16 MHz])
+ * cir: CPU interface register (default=0x40 [DSC])
+ * bcr: Bus configuration register (default=0x40 [CBY])
+ * cor: Clockout register (default=0x00)
+ *
+ * Note: for clk, cir, bcr and cor, the first argument re-defines the
+ * default for all other devices, e.g.:
+ *
+ * insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000
+ *
+ * is equivalent to
+ *
+ * insmod cc770_isa.ko mem=0xd1000,0xd1000 irq=7,11 clk=24000000,24000000
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/cc770.h>
+
+#include "cc770.h"
+
+#define MAXDEV 8
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the ISA bus");
+MODULE_LICENSE("GPL v2");
+
+#define CLK_DEFAULT 16000000 /* 16 MHz */
+#define COR_DEFAULT 0x00
+#define BCR_DEFAULT BUSCFG_CBY
+
+static unsigned long port[MAXDEV];
+static unsigned long mem[MAXDEV];
+static int irq[MAXDEV];
+static int clk[MAXDEV];
+static u8 cir[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static u8 cor[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static u8 bcr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
+
+module_param_array(port, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(port, "I/O port number");
+
+module_param_array(mem, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(mem, "I/O memory address");
+
+module_param_array(indirect, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(indirect, "Indirect access via address and data port");
+
+module_param_array(irq, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(irq, "IRQ number");
+
+module_param_array(clk, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(clk, "External oscillator clock frequency "
+ "(default=16000000 [16 MHz])");
+
+module_param_array(cir, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(cir, "CPU interface register (default=0x40 [DSC])");
+
+module_param_array(cor, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(cor, "Clockout register (default=0x00)");
+
+module_param_array(bcr, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(bcr, "Bus configuration register (default=0x40 [CBY])");
+
+#define CC770_IOSIZE 0x20
+#define CC770_IOSIZE_INDIRECT 0x02
+
+/* Spinlock for cc770_isa_port_write_reg_indirect
+ * and cc770_isa_port_read_reg_indirect
+ */
+static DEFINE_SPINLOCK(cc770_isa_port_lock);
+
+static struct platform_device *cc770_isa_devs[MAXDEV];
+
+static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
+{
+ return readb(priv->reg_base + reg);
+}
+
+static void cc770_isa_mem_write_reg(const struct cc770_priv *priv,
+ int reg, u8 val)
+{
+ writeb(val, priv->reg_base + reg);
+}
+
+static u8 cc770_isa_port_read_reg(const struct cc770_priv *priv, int reg)
+{
+ return inb((unsigned long)priv->reg_base + reg);
+}
+
+static void cc770_isa_port_write_reg(const struct cc770_priv *priv,
+ int reg, u8 val)
+{
+ outb(val, (unsigned long)priv->reg_base + reg);
+}
+
+static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
+ int reg)
+{
+ unsigned long base = (unsigned long)priv->reg_base;
+ unsigned long flags;
+ u8 val;
+
+ spin_lock_irqsave(&cc770_isa_port_lock, flags);
+ outb(reg, base);
+ val = inb(base + 1);
+ spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
+
+ return val;
+}
+
+static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
+ int reg, u8 val)
+{
+ unsigned long base = (unsigned long)priv->reg_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cc770_isa_port_lock, flags);
+ outb(reg, base);
+ outb(val, base + 1);
+ spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
+}
+
+static int cc770_isa_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct cc770_priv *priv;
+ void __iomem *base = NULL;
+ int iosize = CC770_IOSIZE;
+ int idx = pdev->id;
+ int err;
+ u32 clktmp;
+
+ dev_dbg(&pdev->dev, "probing idx=%d: port=%#lx, mem=%#lx, irq=%d\n",
+ idx, port[idx], mem[idx], irq[idx]);
+ if (mem[idx]) {
+ if (!request_mem_region(mem[idx], iosize, KBUILD_MODNAME)) {
+ err = -EBUSY;
+ goto exit;
+ }
+ base = ioremap_nocache(mem[idx], iosize);
+ if (!base) {
+ err = -ENOMEM;
+ goto exit_release;
+ }
+ } else {
+ if (indirect[idx] > 0 ||
+ (indirect[idx] == -1 && indirect[0] > 0))
+ iosize = CC770_IOSIZE_INDIRECT;
+ if (!request_region(port[idx], iosize, KBUILD_MODNAME)) {
+ err = -EBUSY;
+ goto exit;
+ }
+ }
+
+ dev = alloc_cc770dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_unmap;
+ }
+ priv = netdev_priv(dev);
+
+ dev->irq = irq[idx];
+ priv->irq_flags = IRQF_SHARED;
+ if (mem[idx]) {
+ priv->reg_base = base;
+ dev->base_addr = mem[idx];
+ priv->read_reg = cc770_isa_mem_read_reg;
+ priv->write_reg = cc770_isa_mem_write_reg;
+ } else {
+ priv->reg_base = (void __iomem *)port[idx];
+ dev->base_addr = port[idx];
+
+ if (iosize == CC770_IOSIZE_INDIRECT) {
+ priv->read_reg = cc770_isa_port_read_reg_indirect;
+ priv->write_reg = cc770_isa_port_write_reg_indirect;
+ } else {
+ priv->read_reg = cc770_isa_port_read_reg;
+ priv->write_reg = cc770_isa_port_write_reg;
+ }
+ }
+
+ if (clk[idx])
+ clktmp = clk[idx];
+ else if (clk[0])
+ clktmp = clk[0];
+ else
+ clktmp = CLK_DEFAULT;
+ priv->can.clock.freq = clktmp;
+
+ if (cir[idx] != 0xff) {
+ priv->cpu_interface = cir[idx];
+ } else if (cir[0] != 0xff) {
+ priv->cpu_interface = cir[0];
+ } else {
+ /* The system clock may not exceed 10 MHz */
+ if (clktmp > 10000000) {
+ priv->cpu_interface |= CPUIF_DSC;
+ clktmp /= 2;
+ }
+ /* The memory clock may not exceed 8 MHz */
+ if (clktmp > 8000000)
+ priv->cpu_interface |= CPUIF_DMC;
+ }
+
+ if (priv->cpu_interface & CPUIF_DSC)
+ priv->can.clock.freq /= 2;
+
+ if (bcr[idx] != 0xff)
+ priv->bus_config = bcr[idx];
+ else if (bcr[0] != 0xff)
+ priv->bus_config = bcr[0];
+ else
+ priv->bus_config = BCR_DEFAULT;
+
+ if (cor[idx] != 0xff)
+ priv->clkout = cor[idx];
+ else if (cor[0] != 0xff)
+ priv->clkout = cor[0];
+ else
+ priv->clkout = COR_DEFAULT;
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = register_cc770dev(dev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "couldn't register device (err=%d)\n", err);
+ goto exit_unmap;
+ }
+
+ dev_info(&pdev->dev, "device registered (reg_base=0x%p, irq=%d)\n",
+ priv->reg_base, dev->irq);
+ return 0;
+
+ exit_unmap:
+ if (mem[idx])
+ iounmap(base);
+ exit_release:
+ if (mem[idx])
+ release_mem_region(mem[idx], iosize);
+ else
+ release_region(port[idx], iosize);
+ exit:
+ return err;
+}
+
+static int cc770_isa_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct cc770_priv *priv = netdev_priv(dev);
+ int idx = pdev->id;
+
+ unregister_cc770dev(dev);
+
+ if (mem[idx]) {
+ iounmap(priv->reg_base);
+ release_mem_region(mem[idx], CC770_IOSIZE);
+ } else {
+ if (priv->read_reg == cc770_isa_port_read_reg_indirect)
+ release_region(port[idx], CC770_IOSIZE_INDIRECT);
+ else
+ release_region(port[idx], CC770_IOSIZE);
+ }
+ free_cc770dev(dev);
+
+ return 0;
+}
+
+static struct platform_driver cc770_isa_driver = {
+ .probe = cc770_isa_probe,
+ .remove = cc770_isa_remove,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init cc770_isa_init(void)
+{
+ int idx, err;
+
+ for (idx = 0; idx < ARRAY_SIZE(cc770_isa_devs); idx++) {
+ if ((port[idx] || mem[idx]) && irq[idx]) {
+ cc770_isa_devs[idx] =
+ platform_device_alloc(KBUILD_MODNAME, idx);
+ if (!cc770_isa_devs[idx]) {
+ err = -ENOMEM;
+ goto exit_free_devices;
+ }
+ err = platform_device_add(cc770_isa_devs[idx]);
+ if (err) {
+ platform_device_put(cc770_isa_devs[idx]);
+ goto exit_free_devices;
+ }
+ pr_debug("platform device %d: port=%#lx, mem=%#lx, "
+ "irq=%d\n",
+ idx, port[idx], mem[idx], irq[idx]);
+ } else if (idx == 0 || port[idx] || mem[idx]) {
+ pr_err("insufficient parameters supplied\n");
+ err = -EINVAL;
+ goto exit_free_devices;
+ }
+ }
+
+ err = platform_driver_register(&cc770_isa_driver);
+ if (err)
+ goto exit_free_devices;
+
+ pr_info("driver for max. %d devices registered\n", MAXDEV);
+
+ return 0;
+
+exit_free_devices:
+ while (--idx >= 0) {
+ if (cc770_isa_devs[idx])
+ platform_device_unregister(cc770_isa_devs[idx]);
+ }
+
+ return err;
+}
+module_init(cc770_isa_init);
+
+static void __exit cc770_isa_exit(void)
+{
+ int idx;
+
+ platform_driver_unregister(&cc770_isa_driver);
+ for (idx = 0; idx < ARRAY_SIZE(cc770_isa_devs); idx++) {
+ if (cc770_isa_devs[idx])
+ platform_device_unregister(cc770_isa_devs[idx]);
+ }
+}
+module_exit(cc770_isa_exit);
diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c
new file mode 100644
index 00000000000..ad76734b3ec
--- /dev/null
+++ b/drivers/net/can/cc770/cc770_platform.c
@@ -0,0 +1,274 @@
+/*
+ * Driver for CC770 and AN82527 CAN controllers on the platform bus
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * If platform data are used you should have similar definitions
+ * in your board-specific code:
+ *
+ * static struct cc770_platform_data myboard_cc770_pdata = {
+ * .osc_freq = 16000000,
+ * .cir = 0x41,
+ * .cor = 0x20,
+ * .bcr = 0x40,
+ * };
+ *
+ * Please see include/linux/can/platform/cc770.h for description of
+ * above fields.
+ *
+ * If the device tree is used, you need a CAN node definition in your
+ * DTS file similar to:
+ *
+ * can@3,100 {
+ * compatible = "bosch,cc770";
+ * reg = <3 0x100 0x80>;
+ * interrupts = <2 0>;
+ * interrupt-parent = <&mpic>;
+ * bosch,external-clock-frequency = <16000000>;
+ * };
+ *
+ * See "Documentation/devicetree/bindings/net/can/cc770.txt" for further
+ * information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/cc770.h>
+
+#include "cc770.h"
+
+#define DRV_NAME "cc770_platform"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the platform bus");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+
+#define CC770_PLATFORM_CAN_CLOCK 16000000
+
+static u8 cc770_platform_read_reg(const struct cc770_priv *priv, int reg)
+{
+ return ioread8(priv->reg_base + reg);
+}
+
+static void cc770_platform_write_reg(const struct cc770_priv *priv, int reg,
+ u8 val)
+{
+ iowrite8(val, priv->reg_base + reg);
+}
+
+static int cc770_get_of_node_data(struct platform_device *pdev,
+ struct cc770_priv *priv)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const u32 *prop;
+ int prop_size;
+ u32 clkext;
+
+ prop = of_get_property(np, "bosch,external-clock-frequency",
+ &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ clkext = *prop;
+ else
+ clkext = CC770_PLATFORM_CAN_CLOCK; /* default */
+ priv->can.clock.freq = clkext;
+
+ /* The system clock may not exceed 10 MHz */
+ if (priv->can.clock.freq > 10000000) {
+ priv->cpu_interface |= CPUIF_DSC;
+ priv->can.clock.freq /= 2;
+ }
+
+ /* The memory clock may not exceed 8 MHz */
+ if (priv->can.clock.freq > 8000000)
+ priv->cpu_interface |= CPUIF_DMC;
+
+ if (of_get_property(np, "bosch,divide-memory-clock", NULL))
+ priv->cpu_interface |= CPUIF_DMC;
+ if (of_get_property(np, "bosch,iso-low-speed-mux", NULL))
+ priv->cpu_interface |= CPUIF_MUX;
+
+ if (!of_get_property(np, "bosch,no-comperator-bypass", NULL))
+ priv->bus_config |= BUSCFG_CBY;
+ if (of_get_property(np, "bosch,disconnect-rx0-input", NULL))
+ priv->bus_config |= BUSCFG_DR0;
+ if (of_get_property(np, "bosch,disconnect-rx1-input", NULL))
+ priv->bus_config |= BUSCFG_DR1;
+ if (of_get_property(np, "bosch,disconnect-tx1-output", NULL))
+ priv->bus_config |= BUSCFG_DT1;
+ if (of_get_property(np, "bosch,polarity-dominant", NULL))
+ priv->bus_config |= BUSCFG_POL;
+
+ prop = of_get_property(np, "bosch,clock-out-frequency", &prop_size);
+ if (prop && (prop_size == sizeof(u32)) && *prop > 0) {
+ u32 cdv = clkext / *prop;
+ int slew;
+
+ if (cdv > 0 && cdv < 16) {
+ priv->cpu_interface |= CPUIF_CEN;
+ priv->clkout |= (cdv - 1) & CLKOUT_CD_MASK;
+
+ prop = of_get_property(np, "bosch,slew-rate",
+ &prop_size);
+ if (prop && (prop_size == sizeof(u32))) {
+ slew = *prop;
+ } else {
+ /* Determine default slew rate */
+ slew = (CLKOUT_SL_MASK >>
+ CLKOUT_SL_SHIFT) -
+ ((cdv * clkext - 1) / 8000000);
+ if (slew < 0)
+ slew = 0;
+ }
+ priv->clkout |= (slew << CLKOUT_SL_SHIFT) &
+ CLKOUT_SL_MASK;
+ } else {
+ dev_dbg(&pdev->dev, "invalid clock-out-frequency\n");
+ }
+ }
+
+ return 0;
+}
+
+static int cc770_get_platform_data(struct platform_device *pdev,
+ struct cc770_priv *priv)
+{
+
+ struct cc770_platform_data *pdata = dev_get_platdata(&pdev->dev);
+
+ priv->can.clock.freq = pdata->osc_freq;
+ if (priv->cpu_interface & CPUIF_DSC)
+ priv->can.clock.freq /= 2;
+ priv->clkout = pdata->cor;
+ priv->bus_config = pdata->bcr;
+ priv->cpu_interface = pdata->cir;
+
+ return 0;
+}
+
+static int cc770_platform_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct cc770_priv *priv;
+ struct resource *mem;
+ resource_size_t mem_size;
+ void __iomem *base;
+ int err, irq;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!mem || irq <= 0)
+ return -ENODEV;
+
+ mem_size = resource_size(mem);
+ if (!request_mem_region(mem->start, mem_size, pdev->name))
+ return -EBUSY;
+
+ base = ioremap(mem->start, mem_size);
+ if (!base) {
+ err = -ENOMEM;
+ goto exit_release_mem;
+ }
+
+ dev = alloc_cc770dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_unmap_mem;
+ }
+
+ dev->irq = irq;
+ priv = netdev_priv(dev);
+ priv->read_reg = cc770_platform_read_reg;
+ priv->write_reg = cc770_platform_write_reg;
+ priv->irq_flags = IRQF_SHARED;
+ priv->reg_base = base;
+
+ if (pdev->dev.of_node)
+ err = cc770_get_of_node_data(pdev, priv);
+ else if (dev_get_platdata(&pdev->dev))
+ err = cc770_get_platform_data(pdev, priv);
+ else
+ err = -ENODEV;
+ if (err)
+ goto exit_free_cc770;
+
+ dev_dbg(&pdev->dev,
+ "reg_base=0x%p irq=%d clock=%d cpu_interface=0x%02x "
+ "bus_config=0x%02x clkout=0x%02x\n",
+ priv->reg_base, dev->irq, priv->can.clock.freq,
+ priv->cpu_interface, priv->bus_config, priv->clkout);
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = register_cc770dev(dev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "couldn't register CC700 device (err=%d)\n", err);
+ goto exit_free_cc770;
+ }
+
+ return 0;
+
+exit_free_cc770:
+ free_cc770dev(dev);
+exit_unmap_mem:
+ iounmap(base);
+exit_release_mem:
+ release_mem_region(mem->start, mem_size);
+
+ return err;
+}
+
+static int cc770_platform_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct resource *mem;
+
+ unregister_cc770dev(dev);
+ iounmap(priv->reg_base);
+ free_cc770dev(dev);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+
+ return 0;
+}
+
+static struct of_device_id cc770_platform_table[] = {
+ {.compatible = "bosch,cc770"}, /* CC770 from Bosch */
+ {.compatible = "intc,82527"}, /* AN82527 from Intel CP */
+ {},
+};
+MODULE_DEVICE_TABLE(of, cc770_platform_table);
+
+static struct platform_driver cc770_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = cc770_platform_table,
+ },
+ .probe = cc770_platform_probe,
+ .remove = cc770_platform_remove,
+};
+
+module_platform_driver(cc770_platform_driver);
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
new file mode 100644
index 00000000000..e318e87e2bf
--- /dev/null
+++ b/drivers/net/can/dev.c
@@ -0,0 +1,939 @@
+/*
+ * Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
+ * Copyright (C) 2006 Andrey Volkov, Varma Electronics
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/skb.h>
+#include <linux/can/netlink.h>
+#include <linux/can/led.h>
+#include <net/rtnetlink.h>
+
+#define MOD_DESC "CAN device driver interface"
+
+MODULE_DESCRIPTION(MOD_DESC);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+
+/* CAN DLC to real data length conversion helpers */
+
+static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 12, 16, 20, 24, 32, 48, 64};
+
+/* get data length from can_dlc with sanitized can_dlc */
+u8 can_dlc2len(u8 can_dlc)
+{
+ return dlc2len[can_dlc & 0x0F];
+}
+EXPORT_SYMBOL_GPL(can_dlc2len);
+
+static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */
+ 9, 9, 9, 9, /* 9 - 12 */
+ 10, 10, 10, 10, /* 13 - 16 */
+ 11, 11, 11, 11, /* 17 - 20 */
+ 12, 12, 12, 12, /* 21 - 24 */
+ 13, 13, 13, 13, 13, 13, 13, 13, /* 25 - 32 */
+ 14, 14, 14, 14, 14, 14, 14, 14, /* 33 - 40 */
+ 14, 14, 14, 14, 14, 14, 14, 14, /* 41 - 48 */
+ 15, 15, 15, 15, 15, 15, 15, 15, /* 49 - 56 */
+ 15, 15, 15, 15, 15, 15, 15, 15}; /* 57 - 64 */
+
+/* map the sanitized data length to an appropriate data length code */
+u8 can_len2dlc(u8 len)
+{
+ if (unlikely(len > 64))
+ return 0xF;
+
+ return len2dlc[len];
+}
+EXPORT_SYMBOL_GPL(can_len2dlc);
+
+#ifdef CONFIG_CAN_CALC_BITTIMING
+#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
+
+/*
+ * Bit-timing calculation derived from:
+ *
+ * Code based on LinCAN sources and H8S2638 project
+ * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
+ * Copyright 2005 Stanislav Marek
+ * email: pisa@cmp.felk.cvut.cz
+ *
+ * Calculates proper bit-timing parameters for a specified bit-rate
+ * and sample-point, which can then be used to set the bit-timing
+ * registers of the CAN controller. You can find more information
+ * in the header file linux/can/netlink.h.
+ */
+static int can_update_spt(const struct can_bittiming_const *btc,
+ int sampl_pt, int tseg, int *tseg1, int *tseg2)
+{
+ *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
+ if (*tseg2 < btc->tseg2_min)
+ *tseg2 = btc->tseg2_min;
+ if (*tseg2 > btc->tseg2_max)
+ *tseg2 = btc->tseg2_max;
+ *tseg1 = tseg - *tseg2;
+ if (*tseg1 > btc->tseg1_max) {
+ *tseg1 = btc->tseg1_max;
+ *tseg2 = tseg - *tseg1;
+ }
+ return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
+}
+
+static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
+ const struct can_bittiming_const *btc)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ long rate, best_rate = 0;
+ long best_error = 1000000000, error = 0;
+ int best_tseg = 0, best_brp = 0, brp = 0;
+ int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
+ int spt_error = 1000, spt = 0, sampl_pt;
+ u64 v64;
+
+ /* Use CIA recommended sample points */
+ if (bt->sample_point) {
+ sampl_pt = bt->sample_point;
+ } else {
+ if (bt->bitrate > 800000)
+ sampl_pt = 750;
+ else if (bt->bitrate > 500000)
+ sampl_pt = 800;
+ else
+ sampl_pt = 875;
+ }
+
+ /* tseg even = round down, odd = round up */
+ for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1;
+ tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
+ tsegall = 1 + tseg / 2;
+ /* Compute all possible tseg choices (tseg=tseg1+tseg2) */
+ brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2;
+ /* chose brp step which is possible in system */
+ brp = (brp / btc->brp_inc) * btc->brp_inc;
+ if ((brp < btc->brp_min) || (brp > btc->brp_max))
+ continue;
+ rate = priv->clock.freq / (brp * tsegall);
+ error = bt->bitrate - rate;
+ /* tseg brp biterror */
+ if (error < 0)
+ error = -error;
+ if (error > best_error)
+ continue;
+ best_error = error;
+ if (error == 0) {
+ spt = can_update_spt(btc, sampl_pt, tseg / 2,
+ &tseg1, &tseg2);
+ error = sampl_pt - spt;
+ if (error < 0)
+ error = -error;
+ if (error > spt_error)
+ continue;
+ spt_error = error;
+ }
+ best_tseg = tseg / 2;
+ best_brp = brp;
+ best_rate = rate;
+ if (error == 0)
+ break;
+ }
+
+ if (best_error) {
+ /* Error in one-tenth of a percent */
+ error = (best_error * 1000) / bt->bitrate;
+ if (error > CAN_CALC_MAX_ERROR) {
+ netdev_err(dev,
+ "bitrate error %ld.%ld%% too high\n",
+ error / 10, error % 10);
+ return -EDOM;
+ } else {
+ netdev_warn(dev, "bitrate error %ld.%ld%%\n",
+ error / 10, error % 10);
+ }
+ }
+
+ /* real sample point */
+ bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg,
+ &tseg1, &tseg2);
+
+ v64 = (u64)best_brp * 1000000000UL;
+ do_div(v64, priv->clock.freq);
+ bt->tq = (u32)v64;
+ bt->prop_seg = tseg1 / 2;
+ bt->phase_seg1 = tseg1 - bt->prop_seg;
+ bt->phase_seg2 = tseg2;
+
+ /* check for sjw user settings */
+ if (!bt->sjw || !btc->sjw_max)
+ bt->sjw = 1;
+ else {
+ /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
+ if (bt->sjw > btc->sjw_max)
+ bt->sjw = btc->sjw_max;
+ /* bt->sjw must not be higher than tseg2 */
+ if (tseg2 < bt->sjw)
+ bt->sjw = tseg2;
+ }
+
+ bt->brp = best_brp;
+ /* real bit-rate */
+ bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1));
+
+ return 0;
+}
+#else /* !CONFIG_CAN_CALC_BITTIMING */
+static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
+ const struct can_bittiming_const *btc)
+{
+ netdev_err(dev, "bit-timing calculation not available\n");
+ return -EINVAL;
+}
+#endif /* CONFIG_CAN_CALC_BITTIMING */
+
+/*
+ * Checks the validity of the specified bit-timing parameters prop_seg,
+ * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate
+ * prescaler value brp. You can find more information in the header
+ * file linux/can/netlink.h.
+ */
+static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt,
+ const struct can_bittiming_const *btc)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ int tseg1, alltseg;
+ u64 brp64;
+
+ tseg1 = bt->prop_seg + bt->phase_seg1;
+ if (!bt->sjw)
+ bt->sjw = 1;
+ if (bt->sjw > btc->sjw_max ||
+ tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
+ bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
+ return -ERANGE;
+
+ brp64 = (u64)priv->clock.freq * (u64)bt->tq;
+ if (btc->brp_inc > 1)
+ do_div(brp64, btc->brp_inc);
+ brp64 += 500000000UL - 1;
+ do_div(brp64, 1000000000UL); /* the practicable BRP */
+ if (btc->brp_inc > 1)
+ brp64 *= btc->brp_inc;
+ bt->brp = (u32)brp64;
+
+ if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
+ return -EINVAL;
+
+ alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
+ bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
+ bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
+
+ return 0;
+}
+
+static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
+ const struct can_bittiming_const *btc)
+{
+ int err;
+
+ /* Check if the CAN device has bit-timing parameters */
+ if (!btc)
+ return -EOPNOTSUPP;
+
+ /*
+ * Depending on the given can_bittiming parameter structure the CAN
+ * timing parameters are calculated based on the provided bitrate OR
+ * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
+ * provided directly which are then checked and fixed up.
+ */
+ if (!bt->tq && bt->bitrate)
+ err = can_calc_bittiming(dev, bt, btc);
+ else if (bt->tq && !bt->bitrate)
+ err = can_fixup_bittiming(dev, bt, btc);
+ else
+ err = -EINVAL;
+
+ return err;
+}
+
+/*
+ * Local echo of CAN messages
+ *
+ * CAN network devices *should* support a local echo functionality
+ * (see Documentation/networking/can.txt). To test the handling of CAN
+ * interfaces that do not support the local echo both driver types are
+ * implemented. In the case that the driver does not support the echo
+ * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core
+ * to perform the echo as a fallback solution.
+ */
+static void can_flush_echo_skb(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ int i;
+
+ for (i = 0; i < priv->echo_skb_max; i++) {
+ if (priv->echo_skb[i]) {
+ kfree_skb(priv->echo_skb[i]);
+ priv->echo_skb[i] = NULL;
+ stats->tx_dropped++;
+ stats->tx_aborted_errors++;
+ }
+ }
+}
+
+/*
+ * Put the skb on the stack to be looped backed locally lateron
+ *
+ * The function is typically called in the start_xmit function
+ * of the device driver. The driver must protect access to
+ * priv->echo_skb, if necessary.
+ */
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
+ unsigned int idx)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ BUG_ON(idx >= priv->echo_skb_max);
+
+ /* check flag whether this packet has to be looped back */
+ if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK ||
+ (skb->protocol != htons(ETH_P_CAN) &&
+ skb->protocol != htons(ETH_P_CANFD))) {
+ kfree_skb(skb);
+ return;
+ }
+
+ if (!priv->echo_skb[idx]) {
+
+ skb = can_create_echo_skb(skb);
+ if (!skb)
+ return;
+
+ /* make settings for echo to reduce code in irq context */
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->dev = dev;
+
+ /* save this skb for tx interrupt echo handling */
+ priv->echo_skb[idx] = skb;
+ } else {
+ /* locking problem with netif_stop_queue() ?? */
+ netdev_err(dev, "%s: BUG! echo_skb is occupied!\n", __func__);
+ kfree_skb(skb);
+ }
+}
+EXPORT_SYMBOL_GPL(can_put_echo_skb);
+
+/*
+ * Get the skb from the stack and loop it back locally
+ *
+ * The function is typically called when the TX done interrupt
+ * is handled in the device driver. The driver must protect
+ * access to priv->echo_skb, if necessary.
+ */
+unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ BUG_ON(idx >= priv->echo_skb_max);
+
+ if (priv->echo_skb[idx]) {
+ struct sk_buff *skb = priv->echo_skb[idx];
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u8 dlc = cf->can_dlc;
+
+ netif_rx(priv->echo_skb[idx]);
+ priv->echo_skb[idx] = NULL;
+
+ return dlc;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(can_get_echo_skb);
+
+/*
+ * Remove the skb from the stack and free it.
+ *
+ * The function is typically called when TX failed.
+ */
+void can_free_echo_skb(struct net_device *dev, unsigned int idx)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ BUG_ON(idx >= priv->echo_skb_max);
+
+ if (priv->echo_skb[idx]) {
+ kfree_skb(priv->echo_skb[idx]);
+ priv->echo_skb[idx] = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(can_free_echo_skb);
+
+/*
+ * CAN device restart for bus-off recovery
+ */
+static void can_restart(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct can_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ int err;
+
+ BUG_ON(netif_carrier_ok(dev));
+
+ /*
+ * No synchronization needed because the device is bus-off and
+ * no messages can come in or go out.
+ */
+ can_flush_echo_skb(dev);
+
+ /* send restart message upstream */
+ skb = alloc_can_err_skb(dev, &cf);
+ if (skb == NULL) {
+ err = -ENOMEM;
+ goto restart;
+ }
+ cf->can_id |= CAN_ERR_RESTARTED;
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+restart:
+ netdev_dbg(dev, "restarted\n");
+ priv->can_stats.restarts++;
+
+ /* Now restart the device */
+ err = priv->do_set_mode(dev, CAN_MODE_START);
+
+ netif_carrier_on(dev);
+ if (err)
+ netdev_err(dev, "Error %d during restart", err);
+}
+
+int can_restart_now(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ /*
+ * A manual restart is only permitted if automatic restart is
+ * disabled and the device is in the bus-off state
+ */
+ if (priv->restart_ms)
+ return -EINVAL;
+ if (priv->state != CAN_STATE_BUS_OFF)
+ return -EBUSY;
+
+ /* Runs as soon as possible in the timer context */
+ mod_timer(&priv->restart_timer, jiffies);
+
+ return 0;
+}
+
+/*
+ * CAN bus-off
+ *
+ * This functions should be called when the device goes bus-off to
+ * tell the netif layer that no more packets can be sent or received.
+ * If enabled, a timer is started to trigger bus-off recovery.
+ */
+void can_bus_off(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ netdev_dbg(dev, "bus-off\n");
+
+ netif_carrier_off(dev);
+ priv->can_stats.bus_off++;
+
+ if (priv->restart_ms)
+ mod_timer(&priv->restart_timer,
+ jiffies + (priv->restart_ms * HZ) / 1000);
+}
+EXPORT_SYMBOL_GPL(can_bus_off);
+
+static void can_setup(struct net_device *dev)
+{
+ dev->type = ARPHRD_CAN;
+ dev->mtu = CAN_MTU;
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->tx_queue_len = 10;
+
+ /* New-style flags. */
+ dev->flags = IFF_NOARP;
+ dev->features = NETIF_F_HW_CSUM;
+}
+
+struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
+{
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
+ sizeof(struct can_frame));
+ if (unlikely(!skb))
+ return NULL;
+
+ skb->protocol = htons(ETH_P_CAN);
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ can_skb_reserve(skb);
+ can_skb_prv(skb)->ifindex = dev->ifindex;
+
+ *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+ memset(*cf, 0, sizeof(struct can_frame));
+
+ return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_skb);
+
+struct sk_buff *alloc_canfd_skb(struct net_device *dev,
+ struct canfd_frame **cfd)
+{
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) +
+ sizeof(struct canfd_frame));
+ if (unlikely(!skb))
+ return NULL;
+
+ skb->protocol = htons(ETH_P_CANFD);
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ can_skb_reserve(skb);
+ can_skb_prv(skb)->ifindex = dev->ifindex;
+
+ *cfd = (struct canfd_frame *)skb_put(skb, sizeof(struct canfd_frame));
+ memset(*cfd, 0, sizeof(struct canfd_frame));
+
+ return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_canfd_skb);
+
+struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
+{
+ struct sk_buff *skb;
+
+ skb = alloc_can_skb(dev, cf);
+ if (unlikely(!skb))
+ return NULL;
+
+ (*cf)->can_id = CAN_ERR_FLAG;
+ (*cf)->can_dlc = CAN_ERR_DLC;
+
+ return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_err_skb);
+
+/*
+ * Allocate and setup space for the CAN network device
+ */
+struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
+{
+ struct net_device *dev;
+ struct can_priv *priv;
+ int size;
+
+ if (echo_skb_max)
+ size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) +
+ echo_skb_max * sizeof(struct sk_buff *);
+ else
+ size = sizeof_priv;
+
+ dev = alloc_netdev(size, "can%d", can_setup);
+ if (!dev)
+ return NULL;
+
+ priv = netdev_priv(dev);
+
+ if (echo_skb_max) {
+ priv->echo_skb_max = echo_skb_max;
+ priv->echo_skb = (void *)priv +
+ ALIGN(sizeof_priv, sizeof(struct sk_buff *));
+ }
+
+ priv->state = CAN_STATE_STOPPED;
+
+ init_timer(&priv->restart_timer);
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_candev);
+
+/*
+ * Free space of the CAN network device
+ */
+void free_candev(struct net_device *dev)
+{
+ free_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(free_candev);
+
+/*
+ * changing MTU and control mode for CAN/CANFD devices
+ */
+int can_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ /* Do not allow changing the MTU while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+ /* allow change of MTU according to the CANFD ability of the device */
+ switch (new_mtu) {
+ case CAN_MTU:
+ priv->ctrlmode &= ~CAN_CTRLMODE_FD;
+ break;
+
+ case CANFD_MTU:
+ if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD))
+ return -EINVAL;
+
+ priv->ctrlmode |= CAN_CTRLMODE_FD;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ dev->mtu = new_mtu;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(can_change_mtu);
+
+/*
+ * Common open function when the device gets opened.
+ *
+ * This function should be called in the open function of the device
+ * driver.
+ */
+int open_candev(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ if (!priv->bittiming.bitrate) {
+ netdev_err(dev, "bit-timing not yet defined\n");
+ return -EINVAL;
+ }
+
+ /* For CAN FD the data bitrate has to be >= the arbitration bitrate */
+ if ((priv->ctrlmode & CAN_CTRLMODE_FD) &&
+ (!priv->data_bittiming.bitrate ||
+ (priv->data_bittiming.bitrate < priv->bittiming.bitrate))) {
+ netdev_err(dev, "incorrect/missing data bit-timing\n");
+ return -EINVAL;
+ }
+
+ /* Switch carrier on if device was stopped while in bus-off state */
+ if (!netif_carrier_ok(dev))
+ netif_carrier_on(dev);
+
+ setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(open_candev);
+
+/*
+ * Common close function for cleanup before the device gets closed.
+ *
+ * This function should be called in the close function of the device
+ * driver.
+ */
+void close_candev(struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ del_timer_sync(&priv->restart_timer);
+ can_flush_echo_skb(dev);
+}
+EXPORT_SYMBOL_GPL(close_candev);
+
+/*
+ * CAN netlink interface
+ */
+static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
+ [IFLA_CAN_STATE] = { .type = NLA_U32 },
+ [IFLA_CAN_CTRLMODE] = { .len = sizeof(struct can_ctrlmode) },
+ [IFLA_CAN_RESTART_MS] = { .type = NLA_U32 },
+ [IFLA_CAN_RESTART] = { .type = NLA_U32 },
+ [IFLA_CAN_BITTIMING] = { .len = sizeof(struct can_bittiming) },
+ [IFLA_CAN_BITTIMING_CONST]
+ = { .len = sizeof(struct can_bittiming_const) },
+ [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
+ [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) },
+ [IFLA_CAN_DATA_BITTIMING]
+ = { .len = sizeof(struct can_bittiming) },
+ [IFLA_CAN_DATA_BITTIMING_CONST]
+ = { .len = sizeof(struct can_bittiming_const) },
+};
+
+static int can_changelink(struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ struct can_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* We need synchronization with dev->stop() */
+ ASSERT_RTNL();
+
+ if (data[IFLA_CAN_BITTIMING]) {
+ struct can_bittiming bt;
+
+ /* Do not allow changing bittiming while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+ memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
+ err = can_get_bittiming(dev, &bt, priv->bittiming_const);
+ if (err)
+ return err;
+ memcpy(&priv->bittiming, &bt, sizeof(bt));
+
+ if (priv->do_set_bittiming) {
+ /* Finally, set the bit-timing registers */
+ err = priv->do_set_bittiming(dev);
+ if (err)
+ return err;
+ }
+ }
+
+ if (data[IFLA_CAN_CTRLMODE]) {
+ struct can_ctrlmode *cm;
+
+ /* Do not allow changing controller mode while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+ cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+ if (cm->flags & ~priv->ctrlmode_supported)
+ return -EOPNOTSUPP;
+ priv->ctrlmode &= ~cm->mask;
+ priv->ctrlmode |= cm->flags;
+
+ /* CAN_CTRLMODE_FD can only be set when driver supports FD */
+ if (priv->ctrlmode & CAN_CTRLMODE_FD)
+ dev->mtu = CANFD_MTU;
+ else
+ dev->mtu = CAN_MTU;
+ }
+
+ if (data[IFLA_CAN_RESTART_MS]) {
+ /* Do not allow changing restart delay while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+ priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]);
+ }
+
+ if (data[IFLA_CAN_RESTART]) {
+ /* Do not allow a restart while not running */
+ if (!(dev->flags & IFF_UP))
+ return -EINVAL;
+ err = can_restart_now(dev);
+ if (err)
+ return err;
+ }
+
+ if (data[IFLA_CAN_DATA_BITTIMING]) {
+ struct can_bittiming dbt;
+
+ /* Do not allow changing bittiming while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+ memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]),
+ sizeof(dbt));
+ err = can_get_bittiming(dev, &dbt, priv->data_bittiming_const);
+ if (err)
+ return err;
+ memcpy(&priv->data_bittiming, &dbt, sizeof(dbt));
+
+ if (priv->do_set_data_bittiming) {
+ /* Finally, set the bit-timing registers */
+ err = priv->do_set_data_bittiming(dev);
+ if (err)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static size_t can_get_size(const struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ size_t size = 0;
+
+ if (priv->bittiming.bitrate) /* IFLA_CAN_BITTIMING */
+ size += nla_total_size(sizeof(struct can_bittiming));
+ if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */
+ size += nla_total_size(sizeof(struct can_bittiming_const));
+ size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */
+ size += nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */
+ size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */
+ size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
+ if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */
+ size += nla_total_size(sizeof(struct can_berr_counter));
+ if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */
+ size += nla_total_size(sizeof(struct can_bittiming));
+ if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */
+ size += nla_total_size(sizeof(struct can_bittiming_const));
+
+ return size;
+}
+
+static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+ struct can_ctrlmode cm = {.flags = priv->ctrlmode};
+ struct can_berr_counter bec;
+ enum can_state state = priv->state;
+
+ if (priv->do_get_state)
+ priv->do_get_state(dev, &state);
+
+ if ((priv->bittiming.bitrate &&
+ nla_put(skb, IFLA_CAN_BITTIMING,
+ sizeof(priv->bittiming), &priv->bittiming)) ||
+
+ (priv->bittiming_const &&
+ nla_put(skb, IFLA_CAN_BITTIMING_CONST,
+ sizeof(*priv->bittiming_const), priv->bittiming_const)) ||
+
+ nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) ||
+ nla_put_u32(skb, IFLA_CAN_STATE, state) ||
+ nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
+ nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||
+
+ (priv->do_get_berr_counter &&
+ !priv->do_get_berr_counter(dev, &bec) &&
+ nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) ||
+
+ (priv->data_bittiming.bitrate &&
+ nla_put(skb, IFLA_CAN_DATA_BITTIMING,
+ sizeof(priv->data_bittiming), &priv->data_bittiming)) ||
+
+ (priv->data_bittiming_const &&
+ nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST,
+ sizeof(*priv->data_bittiming_const),
+ priv->data_bittiming_const)))
+ return -EMSGSIZE;
+
+ return 0;
+}
+
+static size_t can_get_xstats_size(const struct net_device *dev)
+{
+ return sizeof(struct can_device_stats);
+}
+
+static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
+{
+ struct can_priv *priv = netdev_priv(dev);
+
+ if (nla_put(skb, IFLA_INFO_XSTATS,
+ sizeof(priv->can_stats), &priv->can_stats))
+ goto nla_put_failure;
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+static int can_newlink(struct net *src_net, struct net_device *dev,
+ struct nlattr *tb[], struct nlattr *data[])
+{
+ return -EOPNOTSUPP;
+}
+
+static struct rtnl_link_ops can_link_ops __read_mostly = {
+ .kind = "can",
+ .maxtype = IFLA_CAN_MAX,
+ .policy = can_policy,
+ .setup = can_setup,
+ .newlink = can_newlink,
+ .changelink = can_changelink,
+ .get_size = can_get_size,
+ .fill_info = can_fill_info,
+ .get_xstats_size = can_get_xstats_size,
+ .fill_xstats = can_fill_xstats,
+};
+
+/*
+ * Register the CAN network device
+ */
+int register_candev(struct net_device *dev)
+{
+ dev->rtnl_link_ops = &can_link_ops;
+ return register_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(register_candev);
+
+/*
+ * Unregister the CAN network device
+ */
+void unregister_candev(struct net_device *dev)
+{
+ unregister_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_candev);
+
+/*
+ * Test if a network device is a candev based device
+ * and return the can_priv* if so.
+ */
+struct can_priv *safe_candev_priv(struct net_device *dev)
+{
+ if ((dev->type != ARPHRD_CAN) || (dev->rtnl_link_ops != &can_link_ops))
+ return NULL;
+
+ return netdev_priv(dev);
+}
+EXPORT_SYMBOL_GPL(safe_candev_priv);
+
+static __init int can_dev_init(void)
+{
+ int err;
+
+ can_led_notifier_init();
+
+ err = rtnl_link_register(&can_link_ops);
+ if (!err)
+ printk(KERN_INFO MOD_DESC "\n");
+
+ return err;
+}
+module_init(can_dev_init);
+
+static __exit void can_dev_exit(void)
+{
+ rtnl_link_unregister(&can_link_ops);
+
+ can_led_notifier_exit();
+}
+module_exit(can_dev_exit);
+
+MODULE_ALIAS_RTNL_LINK("can");
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
new file mode 100644
index 00000000000..f425ec2c783
--- /dev/null
+++ b/drivers/net/can/flexcan.c
@@ -0,0 +1,1256 @@
+/*
+ * flexcan.c - FLEXCAN CAN controller driver
+ *
+ * Copyright (c) 2005-2006 Varma Electronics Oy
+ * Copyright (c) 2009 Sascha Hauer, Pengutronix
+ * Copyright (c) 2010 Marc Kleine-Budde, Pengutronix
+ *
+ * Based on code originally by Andrey Volkov <avolkov@varma-el.com>
+ *
+ * LICENCE:
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#define DRV_NAME "flexcan"
+
+/* 8 for RX fifo and 2 error handling */
+#define FLEXCAN_NAPI_WEIGHT (8 + 2)
+
+/* FLEXCAN module configuration register (CANMCR) bits */
+#define FLEXCAN_MCR_MDIS BIT(31)
+#define FLEXCAN_MCR_FRZ BIT(30)
+#define FLEXCAN_MCR_FEN BIT(29)
+#define FLEXCAN_MCR_HALT BIT(28)
+#define FLEXCAN_MCR_NOT_RDY BIT(27)
+#define FLEXCAN_MCR_WAK_MSK BIT(26)
+#define FLEXCAN_MCR_SOFTRST BIT(25)
+#define FLEXCAN_MCR_FRZ_ACK BIT(24)
+#define FLEXCAN_MCR_SUPV BIT(23)
+#define FLEXCAN_MCR_SLF_WAK BIT(22)
+#define FLEXCAN_MCR_WRN_EN BIT(21)
+#define FLEXCAN_MCR_LPM_ACK BIT(20)
+#define FLEXCAN_MCR_WAK_SRC BIT(19)
+#define FLEXCAN_MCR_DOZE BIT(18)
+#define FLEXCAN_MCR_SRX_DIS BIT(17)
+#define FLEXCAN_MCR_BCC BIT(16)
+#define FLEXCAN_MCR_LPRIO_EN BIT(13)
+#define FLEXCAN_MCR_AEN BIT(12)
+#define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f)
+#define FLEXCAN_MCR_IDAM_A (0 << 8)
+#define FLEXCAN_MCR_IDAM_B (1 << 8)
+#define FLEXCAN_MCR_IDAM_C (2 << 8)
+#define FLEXCAN_MCR_IDAM_D (3 << 8)
+
+/* FLEXCAN control register (CANCTRL) bits */
+#define FLEXCAN_CTRL_PRESDIV(x) (((x) & 0xff) << 24)
+#define FLEXCAN_CTRL_RJW(x) (((x) & 0x03) << 22)
+#define FLEXCAN_CTRL_PSEG1(x) (((x) & 0x07) << 19)
+#define FLEXCAN_CTRL_PSEG2(x) (((x) & 0x07) << 16)
+#define FLEXCAN_CTRL_BOFF_MSK BIT(15)
+#define FLEXCAN_CTRL_ERR_MSK BIT(14)
+#define FLEXCAN_CTRL_CLK_SRC BIT(13)
+#define FLEXCAN_CTRL_LPB BIT(12)
+#define FLEXCAN_CTRL_TWRN_MSK BIT(11)
+#define FLEXCAN_CTRL_RWRN_MSK BIT(10)
+#define FLEXCAN_CTRL_SMP BIT(7)
+#define FLEXCAN_CTRL_BOFF_REC BIT(6)
+#define FLEXCAN_CTRL_TSYN BIT(5)
+#define FLEXCAN_CTRL_LBUF BIT(4)
+#define FLEXCAN_CTRL_LOM BIT(3)
+#define FLEXCAN_CTRL_PROPSEG(x) ((x) & 0x07)
+#define FLEXCAN_CTRL_ERR_BUS (FLEXCAN_CTRL_ERR_MSK)
+#define FLEXCAN_CTRL_ERR_STATE \
+ (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \
+ FLEXCAN_CTRL_BOFF_MSK)
+#define FLEXCAN_CTRL_ERR_ALL \
+ (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
+
+/* FLEXCAN error and status register (ESR) bits */
+#define FLEXCAN_ESR_TWRN_INT BIT(17)
+#define FLEXCAN_ESR_RWRN_INT BIT(16)
+#define FLEXCAN_ESR_BIT1_ERR BIT(15)
+#define FLEXCAN_ESR_BIT0_ERR BIT(14)
+#define FLEXCAN_ESR_ACK_ERR BIT(13)
+#define FLEXCAN_ESR_CRC_ERR BIT(12)
+#define FLEXCAN_ESR_FRM_ERR BIT(11)
+#define FLEXCAN_ESR_STF_ERR BIT(10)
+#define FLEXCAN_ESR_TX_WRN BIT(9)
+#define FLEXCAN_ESR_RX_WRN BIT(8)
+#define FLEXCAN_ESR_IDLE BIT(7)
+#define FLEXCAN_ESR_TXRX BIT(6)
+#define FLEXCAN_EST_FLT_CONF_SHIFT (4)
+#define FLEXCAN_ESR_FLT_CONF_MASK (0x3 << FLEXCAN_EST_FLT_CONF_SHIFT)
+#define FLEXCAN_ESR_FLT_CONF_ACTIVE (0x0 << FLEXCAN_EST_FLT_CONF_SHIFT)
+#define FLEXCAN_ESR_FLT_CONF_PASSIVE (0x1 << FLEXCAN_EST_FLT_CONF_SHIFT)
+#define FLEXCAN_ESR_BOFF_INT BIT(2)
+#define FLEXCAN_ESR_ERR_INT BIT(1)
+#define FLEXCAN_ESR_WAK_INT BIT(0)
+#define FLEXCAN_ESR_ERR_BUS \
+ (FLEXCAN_ESR_BIT1_ERR | FLEXCAN_ESR_BIT0_ERR | \
+ FLEXCAN_ESR_ACK_ERR | FLEXCAN_ESR_CRC_ERR | \
+ FLEXCAN_ESR_FRM_ERR | FLEXCAN_ESR_STF_ERR)
+#define FLEXCAN_ESR_ERR_STATE \
+ (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT)
+#define FLEXCAN_ESR_ERR_ALL \
+ (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE)
+#define FLEXCAN_ESR_ALL_INT \
+ (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \
+ FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT)
+
+/* FLEXCAN interrupt flag register (IFLAG) bits */
+#define FLEXCAN_TX_BUF_ID 8
+#define FLEXCAN_IFLAG_BUF(x) BIT(x)
+#define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
+#define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
+#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
+#define FLEXCAN_IFLAG_DEFAULT \
+ (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \
+ FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID))
+
+/* FLEXCAN message buffers */
+#define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24)
+#define FLEXCAN_MB_CNT_SRR BIT(22)
+#define FLEXCAN_MB_CNT_IDE BIT(21)
+#define FLEXCAN_MB_CNT_RTR BIT(20)
+#define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
+#define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
+
+#define FLEXCAN_MB_CODE_MASK (0xf0ffffff)
+
+#define FLEXCAN_TIMEOUT_US (50)
+
+/*
+ * FLEXCAN hardware feature flags
+ *
+ * Below is some version info we got:
+ * SOC Version IP-Version Glitch- [TR]WRN_INT
+ * Filter? connected?
+ * MX25 FlexCAN2 03.00.00.00 no no
+ * MX28 FlexCAN2 03.00.04.00 yes yes
+ * MX35 FlexCAN2 03.00.00.00 no no
+ * MX53 FlexCAN2 03.00.00.00 yes no
+ * MX6s FlexCAN3 10.00.12.00 yes yes
+ *
+ * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
+ */
+#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
+#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
+
+/* Structure of the message buffer */
+struct flexcan_mb {
+ u32 can_ctrl;
+ u32 can_id;
+ u32 data[2];
+};
+
+/* Structure of the hardware registers */
+struct flexcan_regs {
+ u32 mcr; /* 0x00 */
+ u32 ctrl; /* 0x04 */
+ u32 timer; /* 0x08 */
+ u32 _reserved1; /* 0x0c */
+ u32 rxgmask; /* 0x10 */
+ u32 rx14mask; /* 0x14 */
+ u32 rx15mask; /* 0x18 */
+ u32 ecr; /* 0x1c */
+ u32 esr; /* 0x20 */
+ u32 imask2; /* 0x24 */
+ u32 imask1; /* 0x28 */
+ u32 iflag2; /* 0x2c */
+ u32 iflag1; /* 0x30 */
+ u32 crl2; /* 0x34 */
+ u32 esr2; /* 0x38 */
+ u32 imeur; /* 0x3c */
+ u32 lrfr; /* 0x40 */
+ u32 crcr; /* 0x44 */
+ u32 rxfgmask; /* 0x48 */
+ u32 rxfir; /* 0x4c */
+ u32 _reserved3[12];
+ struct flexcan_mb cantxfg[64];
+};
+
+struct flexcan_devtype_data {
+ u32 features; /* hardware controller features */
+};
+
+struct flexcan_priv {
+ struct can_priv can;
+ struct net_device *dev;
+ struct napi_struct napi;
+
+ void __iomem *base;
+ u32 reg_esr;
+ u32 reg_ctrl_default;
+
+ struct clk *clk_ipg;
+ struct clk *clk_per;
+ struct flexcan_platform_data *pdata;
+ const struct flexcan_devtype_data *devtype_data;
+ struct regulator *reg_xceiver;
+};
+
+static struct flexcan_devtype_data fsl_p1010_devtype_data = {
+ .features = FLEXCAN_HAS_BROKEN_ERR_STATE,
+};
+static struct flexcan_devtype_data fsl_imx28_devtype_data;
+static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
+ .features = FLEXCAN_HAS_V10_FEATURES,
+};
+
+static const struct can_bittiming_const flexcan_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 4,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 256,
+ .brp_inc = 1,
+};
+
+/*
+ * Abstract off the read/write for arm versus ppc. This
+ * assumes that PPC uses big-endian registers and everything
+ * else uses little-endian registers, independent of CPU
+ * endianess.
+ */
+#if defined(CONFIG_PPC)
+static inline u32 flexcan_read(void __iomem *addr)
+{
+ return in_be32(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+ out_be32(addr, val);
+}
+#else
+static inline u32 flexcan_read(void __iomem *addr)
+{
+ return readl(addr);
+}
+
+static inline void flexcan_write(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+}
+#endif
+
+static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
+{
+ if (!priv->reg_xceiver)
+ return 0;
+
+ return regulator_enable(priv->reg_xceiver);
+}
+
+static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
+{
+ if (!priv->reg_xceiver)
+ return 0;
+
+ return regulator_disable(priv->reg_xceiver);
+}
+
+static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
+ u32 reg_esr)
+{
+ return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) &&
+ (reg_esr & FLEXCAN_ESR_ERR_BUS);
+}
+
+static int flexcan_chip_enable(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->base;
+ unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
+ u32 reg;
+
+ reg = flexcan_read(&regs->mcr);
+ reg &= ~FLEXCAN_MCR_MDIS;
+ flexcan_write(reg, &regs->mcr);
+
+ while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+ usleep_range(10, 20);
+
+ if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int flexcan_chip_disable(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->base;
+ unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
+ u32 reg;
+
+ reg = flexcan_read(&regs->mcr);
+ reg |= FLEXCAN_MCR_MDIS;
+ flexcan_write(reg, &regs->mcr);
+
+ while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+ usleep_range(10, 20);
+
+ if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int flexcan_chip_freeze(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->base;
+ unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
+ u32 reg;
+
+ reg = flexcan_read(&regs->mcr);
+ reg |= FLEXCAN_MCR_HALT;
+ flexcan_write(reg, &regs->mcr);
+
+ while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ usleep_range(100, 200);
+
+ if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->base;
+ unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
+ u32 reg;
+
+ reg = flexcan_read(&regs->mcr);
+ reg &= ~FLEXCAN_MCR_HALT;
+ flexcan_write(reg, &regs->mcr);
+
+ while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+ usleep_range(10, 20);
+
+ if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int flexcan_chip_softreset(struct flexcan_priv *priv)
+{
+ struct flexcan_regs __iomem *regs = priv->base;
+ unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
+
+ flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
+ while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
+ usleep_range(10, 20);
+
+ if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int flexcan_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ const struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg = flexcan_read(&regs->ecr);
+
+ bec->txerr = (reg >> 0) & 0xff;
+ bec->rxerr = (reg >> 8) & 0xff;
+
+ return 0;
+}
+
+static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ const struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 can_id;
+ u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16);
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(dev);
+
+ if (cf->can_id & CAN_EFF_FLAG) {
+ can_id = cf->can_id & CAN_EFF_MASK;
+ ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR;
+ } else {
+ can_id = (cf->can_id & CAN_SFF_MASK) << 18;
+ }
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ ctrl |= FLEXCAN_MB_CNT_RTR;
+
+ if (cf->can_dlc > 0) {
+ u32 data = be32_to_cpup((__be32 *)&cf->data[0]);
+ flexcan_write(data, &regs->cantxfg[FLEXCAN_TX_BUF_ID].data[0]);
+ }
+ if (cf->can_dlc > 3) {
+ u32 data = be32_to_cpup((__be32 *)&cf->data[4]);
+ flexcan_write(data, &regs->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
+ }
+
+ can_put_echo_skb(skb, dev, 0);
+
+ flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
+ flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
+
+ return NETDEV_TX_OK;
+}
+
+static void do_bus_err(struct net_device *dev,
+ struct can_frame *cf, u32 reg_esr)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+ int rx_errors = 0, tx_errors = 0;
+
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ if (reg_esr & FLEXCAN_ESR_BIT1_ERR) {
+ netdev_dbg(dev, "BIT1_ERR irq\n");
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ tx_errors = 1;
+ }
+ if (reg_esr & FLEXCAN_ESR_BIT0_ERR) {
+ netdev_dbg(dev, "BIT0_ERR irq\n");
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ tx_errors = 1;
+ }
+ if (reg_esr & FLEXCAN_ESR_ACK_ERR) {
+ netdev_dbg(dev, "ACK_ERR irq\n");
+ cf->can_id |= CAN_ERR_ACK;
+ cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+ tx_errors = 1;
+ }
+ if (reg_esr & FLEXCAN_ESR_CRC_ERR) {
+ netdev_dbg(dev, "CRC_ERR irq\n");
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+ rx_errors = 1;
+ }
+ if (reg_esr & FLEXCAN_ESR_FRM_ERR) {
+ netdev_dbg(dev, "FRM_ERR irq\n");
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ rx_errors = 1;
+ }
+ if (reg_esr & FLEXCAN_ESR_STF_ERR) {
+ netdev_dbg(dev, "STF_ERR irq\n");
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ rx_errors = 1;
+ }
+
+ priv->can.can_stats.bus_error++;
+ if (rx_errors)
+ dev->stats.rx_errors++;
+ if (tx_errors)
+ dev->stats.tx_errors++;
+}
+
+static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr)
+{
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+ return 0;
+
+ do_bus_err(dev, cf, reg_esr);
+ netif_receive_skb(skb);
+
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += cf->can_dlc;
+
+ return 1;
+}
+
+static void do_state(struct net_device *dev,
+ struct can_frame *cf, enum can_state new_state)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct can_berr_counter bec;
+
+ flexcan_get_berr_counter(dev, &bec);
+
+ switch (priv->can.state) {
+ case CAN_STATE_ERROR_ACTIVE:
+ /*
+ * from: ERROR_ACTIVE
+ * to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF
+ * => : there was a warning int
+ */
+ if (new_state >= CAN_STATE_ERROR_WARNING &&
+ new_state <= CAN_STATE_BUS_OFF) {
+ netdev_dbg(dev, "Error Warning IRQ\n");
+ priv->can.can_stats.error_warning++;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (bec.txerr > bec.rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ }
+ case CAN_STATE_ERROR_WARNING: /* fallthrough */
+ /*
+ * from: ERROR_ACTIVE, ERROR_WARNING
+ * to : ERROR_PASSIVE, BUS_OFF
+ * => : error passive int
+ */
+ if (new_state >= CAN_STATE_ERROR_PASSIVE &&
+ new_state <= CAN_STATE_BUS_OFF) {
+ netdev_dbg(dev, "Error Passive IRQ\n");
+ priv->can.can_stats.error_passive++;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (bec.txerr > bec.rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ break;
+ case CAN_STATE_BUS_OFF:
+ netdev_err(dev, "BUG! "
+ "hardware recovered automatically from BUS_OFF\n");
+ break;
+ default:
+ break;
+ }
+
+ /* process state changes depending on the new state */
+ switch (new_state) {
+ case CAN_STATE_ERROR_ACTIVE:
+ netdev_dbg(dev, "Error Active\n");
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_ACTIVE;
+ break;
+ case CAN_STATE_BUS_OFF:
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(dev);
+ break;
+ default:
+ break;
+ }
+}
+
+static int flexcan_poll_state(struct net_device *dev, u32 reg_esr)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ enum can_state new_state;
+ int flt;
+
+ flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK;
+ if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) {
+ if (likely(!(reg_esr & (FLEXCAN_ESR_TX_WRN |
+ FLEXCAN_ESR_RX_WRN))))
+ new_state = CAN_STATE_ERROR_ACTIVE;
+ else
+ new_state = CAN_STATE_ERROR_WARNING;
+ } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE))
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ else
+ new_state = CAN_STATE_BUS_OFF;
+
+ /* state hasn't changed */
+ if (likely(new_state == priv->can.state))
+ return 0;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (unlikely(!skb))
+ return 0;
+
+ do_state(dev, cf, new_state);
+ priv->can.state = new_state;
+ netif_receive_skb(skb);
+
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += cf->can_dlc;
+
+ return 1;
+}
+
+static void flexcan_read_fifo(const struct net_device *dev,
+ struct can_frame *cf)
+{
+ const struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ struct flexcan_mb __iomem *mb = &regs->cantxfg[0];
+ u32 reg_ctrl, reg_id;
+
+ reg_ctrl = flexcan_read(&mb->can_ctrl);
+ reg_id = flexcan_read(&mb->can_id);
+ if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
+ cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ else
+ cf->can_id = (reg_id >> 18) & CAN_SFF_MASK;
+
+ if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
+ cf->can_id |= CAN_RTR_FLAG;
+ cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
+
+ *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
+ *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
+
+ /* mark as read */
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->iflag1);
+ flexcan_read(&regs->timer);
+}
+
+static int flexcan_read_frame(struct net_device *dev)
+{
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+
+ skb = alloc_can_skb(dev, &cf);
+ if (unlikely(!skb)) {
+ stats->rx_dropped++;
+ return 0;
+ }
+
+ flexcan_read_fifo(dev, cf);
+ netif_receive_skb(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ can_led_event(dev, CAN_LED_EVENT_RX);
+
+ return 1;
+}
+
+static int flexcan_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *dev = napi->dev;
+ const struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg_iflag1, reg_esr;
+ int work_done = 0;
+
+ /*
+ * The error bits are cleared on read,
+ * use saved value from irq handler.
+ */
+ reg_esr = flexcan_read(&regs->esr) | priv->reg_esr;
+
+ /* handle state changes */
+ work_done += flexcan_poll_state(dev, reg_esr);
+
+ /* handle RX-FIFO */
+ reg_iflag1 = flexcan_read(&regs->iflag1);
+ while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
+ work_done < quota) {
+ work_done += flexcan_read_frame(dev);
+ reg_iflag1 = flexcan_read(&regs->iflag1);
+ }
+
+ /* report bus errors */
+ if (flexcan_has_and_handle_berr(priv, reg_esr) && work_done < quota)
+ work_done += flexcan_poll_bus_err(dev, reg_esr);
+
+ if (work_done < quota) {
+ napi_complete(napi);
+ /* enable IRQs */
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
+ flexcan_write(priv->reg_ctrl_default, &regs->ctrl);
+ }
+
+ return work_done;
+}
+
+static irqreturn_t flexcan_irq(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct net_device_stats *stats = &dev->stats;
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg_iflag1, reg_esr;
+
+ reg_iflag1 = flexcan_read(&regs->iflag1);
+ reg_esr = flexcan_read(&regs->esr);
+ /* ACK all bus error and state change IRQ sources */
+ if (reg_esr & FLEXCAN_ESR_ALL_INT)
+ flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
+
+ /*
+ * schedule NAPI in case of:
+ * - rx IRQ
+ * - state change IRQ
+ * - bus error IRQ and bus error reporting is activated
+ */
+ if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) ||
+ (reg_esr & FLEXCAN_ESR_ERR_STATE) ||
+ flexcan_has_and_handle_berr(priv, reg_esr)) {
+ /*
+ * The error bits are cleared on read,
+ * save them for later use.
+ */
+ priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT &
+ ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, &regs->imask1);
+ flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+ &regs->ctrl);
+ napi_schedule(&priv->napi);
+ }
+
+ /* FIFO overflow */
+ if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
+ flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
+ dev->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
+ }
+
+ /* transmission complete interrupt */
+ if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
+ stats->tx_bytes += can_get_echo_skb(dev, 0);
+ stats->tx_packets++;
+ can_led_event(dev, CAN_LED_EVENT_TX);
+ flexcan_write((1 << FLEXCAN_TX_BUF_ID), &regs->iflag1);
+ netif_wake_queue(dev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void flexcan_set_bittiming(struct net_device *dev)
+{
+ const struct flexcan_priv *priv = netdev_priv(dev);
+ const struct can_bittiming *bt = &priv->can.bittiming;
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ reg = flexcan_read(&regs->ctrl);
+ reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
+ FLEXCAN_CTRL_RJW(0x3) |
+ FLEXCAN_CTRL_PSEG1(0x7) |
+ FLEXCAN_CTRL_PSEG2(0x7) |
+ FLEXCAN_CTRL_PROPSEG(0x7) |
+ FLEXCAN_CTRL_LPB |
+ FLEXCAN_CTRL_SMP |
+ FLEXCAN_CTRL_LOM);
+
+ reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) |
+ FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) |
+ FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) |
+ FLEXCAN_CTRL_RJW(bt->sjw - 1) |
+ FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1);
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
+ reg |= FLEXCAN_CTRL_LPB;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ reg |= FLEXCAN_CTRL_LOM;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ reg |= FLEXCAN_CTRL_SMP;
+
+ netdev_info(dev, "writing ctrl=0x%08x\n", reg);
+ flexcan_write(reg, &regs->ctrl);
+
+ /* print chip status */
+ netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
+ flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+}
+
+/*
+ * flexcan_chip_start
+ *
+ * this functions is entered with clocks enabled
+ *
+ */
+static int flexcan_chip_start(struct net_device *dev)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ int err;
+ u32 reg_mcr, reg_ctrl;
+
+ /* enable module */
+ err = flexcan_chip_enable(priv);
+ if (err)
+ return err;
+
+ /* soft reset */
+ err = flexcan_chip_softreset(priv);
+ if (err)
+ goto out_chip_disable;
+
+ flexcan_set_bittiming(dev);
+
+ /*
+ * MCR
+ *
+ * enable freeze
+ * enable fifo
+ * halt now
+ * only supervisor access
+ * enable warning int
+ * choose format C
+ * disable local echo
+ *
+ */
+ reg_mcr = flexcan_read(&regs->mcr);
+ reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
+ reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
+ FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
+ FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS |
+ FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
+ netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
+ flexcan_write(reg_mcr, &regs->mcr);
+
+ /*
+ * CTRL
+ *
+ * disable timer sync feature
+ *
+ * disable auto busoff recovery
+ * transmit lowest buffer first
+ *
+ * enable tx and rx warning interrupt
+ * enable bus off interrupt
+ * (== FLEXCAN_CTRL_ERR_STATE)
+ */
+ reg_ctrl = flexcan_read(&regs->ctrl);
+ reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
+ reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
+ FLEXCAN_CTRL_ERR_STATE;
+ /*
+ * enable the "error interrupt" (FLEXCAN_CTRL_ERR_MSK),
+ * on most Flexcan cores, too. Otherwise we don't get
+ * any error warning or passive interrupts.
+ */
+ if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE ||
+ priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+ reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
+
+ /* save for later use */
+ priv->reg_ctrl_default = reg_ctrl;
+ netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
+ flexcan_write(reg_ctrl, &regs->ctrl);
+
+ /* Abort any pending TX, mark Mailbox as INACTIVE */
+ flexcan_write(FLEXCAN_MB_CNT_CODE(0x4),
+ &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
+
+ /* acceptance mask/acceptance code (accept everything) */
+ flexcan_write(0x0, &regs->rxgmask);
+ flexcan_write(0x0, &regs->rx14mask);
+ flexcan_write(0x0, &regs->rx15mask);
+
+ if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
+ flexcan_write(0x0, &regs->rxfgmask);
+
+ err = flexcan_transceiver_enable(priv);
+ if (err)
+ goto out_chip_disable;
+
+ /* synchronize with the can bus */
+ err = flexcan_chip_unfreeze(priv);
+ if (err)
+ goto out_transceiver_disable;
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ /* enable FIFO interrupts */
+ flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
+
+ /* print chip status */
+ netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
+ flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+
+ return 0;
+
+ out_transceiver_disable:
+ flexcan_transceiver_disable(priv);
+ out_chip_disable:
+ flexcan_chip_disable(priv);
+ return err;
+}
+
+/*
+ * flexcan_chip_stop
+ *
+ * this functions is entered with clocks enabled
+ *
+ */
+static void flexcan_chip_stop(struct net_device *dev)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+
+ /* freeze + disable module */
+ flexcan_chip_freeze(priv);
+ flexcan_chip_disable(priv);
+
+ /* Disable all interrupts */
+ flexcan_write(0, &regs->imask1);
+ flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+ &regs->ctrl);
+
+ flexcan_transceiver_disable(priv);
+ priv->can.state = CAN_STATE_STOPPED;
+
+ return;
+}
+
+static int flexcan_open(struct net_device *dev)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+ int err;
+
+ err = clk_prepare_enable(priv->clk_ipg);
+ if (err)
+ return err;
+
+ err = clk_prepare_enable(priv->clk_per);
+ if (err)
+ goto out_disable_ipg;
+
+ err = open_candev(dev);
+ if (err)
+ goto out_disable_per;
+
+ err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
+ if (err)
+ goto out_close;
+
+ /* start chip and queuing */
+ err = flexcan_chip_start(dev);
+ if (err)
+ goto out_free_irq;
+
+ can_led_event(dev, CAN_LED_EVENT_OPEN);
+
+ napi_enable(&priv->napi);
+ netif_start_queue(dev);
+
+ return 0;
+
+ out_free_irq:
+ free_irq(dev->irq, dev);
+ out_close:
+ close_candev(dev);
+ out_disable_per:
+ clk_disable_unprepare(priv->clk_per);
+ out_disable_ipg:
+ clk_disable_unprepare(priv->clk_ipg);
+
+ return err;
+}
+
+static int flexcan_close(struct net_device *dev)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+ flexcan_chip_stop(dev);
+
+ free_irq(dev->irq, dev);
+ clk_disable_unprepare(priv->clk_per);
+ clk_disable_unprepare(priv->clk_ipg);
+
+ close_candev(dev);
+
+ can_led_event(dev, CAN_LED_EVENT_STOP);
+
+ return 0;
+}
+
+static int flexcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ int err;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ err = flexcan_chip_start(dev);
+ if (err)
+ return err;
+
+ netif_wake_queue(dev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static const struct net_device_ops flexcan_netdev_ops = {
+ .ndo_open = flexcan_open,
+ .ndo_stop = flexcan_close,
+ .ndo_start_xmit = flexcan_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static int register_flexcandev(struct net_device *dev)
+{
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg, err;
+
+ err = clk_prepare_enable(priv->clk_ipg);
+ if (err)
+ return err;
+
+ err = clk_prepare_enable(priv->clk_per);
+ if (err)
+ goto out_disable_ipg;
+
+ /* select "bus clock", chip must be disabled */
+ err = flexcan_chip_disable(priv);
+ if (err)
+ goto out_disable_per;
+ reg = flexcan_read(&regs->ctrl);
+ reg |= FLEXCAN_CTRL_CLK_SRC;
+ flexcan_write(reg, &regs->ctrl);
+
+ err = flexcan_chip_enable(priv);
+ if (err)
+ goto out_chip_disable;
+
+ /* set freeze, halt and activate FIFO, restrict register access */
+ reg = flexcan_read(&regs->mcr);
+ reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
+ FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
+ flexcan_write(reg, &regs->mcr);
+
+ /*
+ * Currently we only support newer versions of this core
+ * featuring a RX FIFO. Older cores found on some Coldfire
+ * derivates are not yet supported.
+ */
+ reg = flexcan_read(&regs->mcr);
+ if (!(reg & FLEXCAN_MCR_FEN)) {
+ netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
+ err = -ENODEV;
+ goto out_chip_disable;
+ }
+
+ err = register_candev(dev);
+
+ /* disable core and turn off clocks */
+ out_chip_disable:
+ flexcan_chip_disable(priv);
+ out_disable_per:
+ clk_disable_unprepare(priv->clk_per);
+ out_disable_ipg:
+ clk_disable_unprepare(priv->clk_ipg);
+
+ return err;
+}
+
+static void unregister_flexcandev(struct net_device *dev)
+{
+ unregister_candev(dev);
+}
+
+static const struct of_device_id flexcan_of_match[] = {
+ { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
+ { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
+ { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, flexcan_of_match);
+
+static const struct platform_device_id flexcan_id_table[] = {
+ { .name = "flexcan", .driver_data = (kernel_ulong_t)&fsl_p1010_devtype_data, },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, flexcan_id_table);
+
+static int flexcan_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id;
+ const struct flexcan_devtype_data *devtype_data;
+ struct net_device *dev;
+ struct flexcan_priv *priv;
+ struct resource *mem;
+ struct clk *clk_ipg = NULL, *clk_per = NULL;
+ void __iomem *base;
+ int err, irq;
+ u32 clock_freq = 0;
+
+ if (pdev->dev.of_node)
+ of_property_read_u32(pdev->dev.of_node,
+ "clock-frequency", &clock_freq);
+
+ if (!clock_freq) {
+ clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(clk_ipg)) {
+ dev_err(&pdev->dev, "no ipg clock defined\n");
+ return PTR_ERR(clk_ipg);
+ }
+
+ clk_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(clk_per)) {
+ dev_err(&pdev->dev, "no per clock defined\n");
+ return PTR_ERR(clk_per);
+ }
+ clock_freq = clk_get_rate(clk_per);
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0)
+ return -ENODEV;
+
+ base = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ of_id = of_match_device(flexcan_of_match, &pdev->dev);
+ if (of_id) {
+ devtype_data = of_id->data;
+ } else if (platform_get_device_id(pdev)->driver_data) {
+ devtype_data = (struct flexcan_devtype_data *)
+ platform_get_device_id(pdev)->driver_data;
+ } else {
+ return -ENODEV;
+ }
+
+ dev = alloc_candev(sizeof(struct flexcan_priv), 1);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->netdev_ops = &flexcan_netdev_ops;
+ dev->irq = irq;
+ dev->flags |= IFF_ECHO;
+
+ priv = netdev_priv(dev);
+ priv->can.clock.freq = clock_freq;
+ priv->can.bittiming_const = &flexcan_bittiming_const;
+ priv->can.do_set_mode = flexcan_set_mode;
+ priv->can.do_get_berr_counter = flexcan_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+ CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_BERR_REPORTING;
+ priv->base = base;
+ priv->dev = dev;
+ priv->clk_ipg = clk_ipg;
+ priv->clk_per = clk_per;
+ priv->pdata = dev_get_platdata(&pdev->dev);
+ priv->devtype_data = devtype_data;
+
+ priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver");
+ if (IS_ERR(priv->reg_xceiver))
+ priv->reg_xceiver = NULL;
+
+ netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = register_flexcandev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "registering netdev failed\n");
+ goto failed_register;
+ }
+
+ devm_can_led_init(dev);
+
+ dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n",
+ priv->base, dev->irq);
+
+ return 0;
+
+ failed_register:
+ free_candev(dev);
+ return err;
+}
+
+static int flexcan_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ unregister_flexcandev(dev);
+ netif_napi_del(&priv->napi);
+ free_candev(dev);
+
+ return 0;
+}
+
+static int __maybe_unused flexcan_suspend(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+ int err;
+
+ err = flexcan_chip_disable(priv);
+ if (err)
+ return err;
+
+ if (netif_running(dev)) {
+ netif_stop_queue(dev);
+ netif_device_detach(dev);
+ }
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ return 0;
+}
+
+static int __maybe_unused flexcan_resume(struct device *device)
+{
+ struct net_device *dev = dev_get_drvdata(device);
+ struct flexcan_priv *priv = netdev_priv(dev);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ if (netif_running(dev)) {
+ netif_device_attach(dev);
+ netif_start_queue(dev);
+ }
+ return flexcan_chip_enable(priv);
+}
+
+static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume);
+
+static struct platform_driver flexcan_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &flexcan_pm_ops,
+ .of_match_table = flexcan_of_match,
+ },
+ .probe = flexcan_probe,
+ .remove = flexcan_remove,
+ .id_table = flexcan_id_table,
+};
+
+module_platform_driver(flexcan_driver);
+
+MODULE_AUTHOR("Sascha Hauer <kernel@pengutronix.de>, "
+ "Marc Kleine-Budde <kernel@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CAN port driver for flexcan based chip");
diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
new file mode 100644
index 00000000000..3fd9fd942c6
--- /dev/null
+++ b/drivers/net/can/grcan.c
@@ -0,0 +1,1752 @@
+/*
+ * Socket CAN driver for Aeroflex Gaisler GRCAN and GRHCAN.
+ *
+ * 2012 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRCAN and GRHCAN CAN controllers available in the GRLIB
+ * VHDL IP core library.
+ *
+ * Full documentation of the GRCAN core can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * See "Documentation/devicetree/bindings/net/can/grcan.txt" for information on
+ * open firmware properties.
+ *
+ * See "Documentation/ABI/testing/sysfs-class-net-grcan" for information on the
+ * sysfs interface.
+ *
+ * See "Documentation/kernel-parameters.txt" for information on the module
+ * parameters.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Andreas Larsson <andreas@gaisler.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/spinlock.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+
+#include <linux/dma-mapping.h>
+
+#define DRV_NAME "grcan"
+
+#define GRCAN_NAPI_WEIGHT 32
+
+#define GRCAN_RESERVE_SIZE(slot1, slot2) (((slot2) - (slot1)) / 4 - 1)
+
+struct grcan_registers {
+ u32 conf; /* 0x00 */
+ u32 stat; /* 0x04 */
+ u32 ctrl; /* 0x08 */
+ u32 __reserved1[GRCAN_RESERVE_SIZE(0x08, 0x18)];
+ u32 smask; /* 0x18 - CanMASK */
+ u32 scode; /* 0x1c - CanCODE */
+ u32 __reserved2[GRCAN_RESERVE_SIZE(0x1c, 0x100)];
+ u32 pimsr; /* 0x100 */
+ u32 pimr; /* 0x104 */
+ u32 pisr; /* 0x108 */
+ u32 pir; /* 0x10C */
+ u32 imr; /* 0x110 */
+ u32 picr; /* 0x114 */
+ u32 __reserved3[GRCAN_RESERVE_SIZE(0x114, 0x200)];
+ u32 txctrl; /* 0x200 */
+ u32 txaddr; /* 0x204 */
+ u32 txsize; /* 0x208 */
+ u32 txwr; /* 0x20C */
+ u32 txrd; /* 0x210 */
+ u32 txirq; /* 0x214 */
+ u32 __reserved4[GRCAN_RESERVE_SIZE(0x214, 0x300)];
+ u32 rxctrl; /* 0x300 */
+ u32 rxaddr; /* 0x304 */
+ u32 rxsize; /* 0x308 */
+ u32 rxwr; /* 0x30C */
+ u32 rxrd; /* 0x310 */
+ u32 rxirq; /* 0x314 */
+ u32 rxmask; /* 0x318 */
+ u32 rxcode; /* 0x31C */
+};
+
+#define GRCAN_CONF_ABORT 0x00000001
+#define GRCAN_CONF_ENABLE0 0x00000002
+#define GRCAN_CONF_ENABLE1 0x00000004
+#define GRCAN_CONF_SELECT 0x00000008
+#define GRCAN_CONF_SILENT 0x00000010
+#define GRCAN_CONF_SAM 0x00000020 /* Available in some hardware */
+#define GRCAN_CONF_BPR 0x00000300 /* Note: not BRP */
+#define GRCAN_CONF_RSJ 0x00007000
+#define GRCAN_CONF_PS1 0x00f00000
+#define GRCAN_CONF_PS2 0x000f0000
+#define GRCAN_CONF_SCALER 0xff000000
+#define GRCAN_CONF_OPERATION \
+ (GRCAN_CONF_ABORT | GRCAN_CONF_ENABLE0 | GRCAN_CONF_ENABLE1 \
+ | GRCAN_CONF_SELECT | GRCAN_CONF_SILENT | GRCAN_CONF_SAM)
+#define GRCAN_CONF_TIMING \
+ (GRCAN_CONF_BPR | GRCAN_CONF_RSJ | GRCAN_CONF_PS1 \
+ | GRCAN_CONF_PS2 | GRCAN_CONF_SCALER)
+
+#define GRCAN_CONF_RSJ_MIN 1
+#define GRCAN_CONF_RSJ_MAX 4
+#define GRCAN_CONF_PS1_MIN 1
+#define GRCAN_CONF_PS1_MAX 15
+#define GRCAN_CONF_PS2_MIN 2
+#define GRCAN_CONF_PS2_MAX 8
+#define GRCAN_CONF_SCALER_MIN 0
+#define GRCAN_CONF_SCALER_MAX 255
+#define GRCAN_CONF_SCALER_INC 1
+
+#define GRCAN_CONF_BPR_BIT 8
+#define GRCAN_CONF_RSJ_BIT 12
+#define GRCAN_CONF_PS1_BIT 20
+#define GRCAN_CONF_PS2_BIT 16
+#define GRCAN_CONF_SCALER_BIT 24
+
+#define GRCAN_STAT_PASS 0x000001
+#define GRCAN_STAT_OFF 0x000002
+#define GRCAN_STAT_OR 0x000004
+#define GRCAN_STAT_AHBERR 0x000008
+#define GRCAN_STAT_ACTIVE 0x000010
+#define GRCAN_STAT_RXERRCNT 0x00ff00
+#define GRCAN_STAT_TXERRCNT 0xff0000
+
+#define GRCAN_STAT_ERRCTR_RELATED (GRCAN_STAT_PASS | GRCAN_STAT_OFF)
+
+#define GRCAN_STAT_RXERRCNT_BIT 8
+#define GRCAN_STAT_TXERRCNT_BIT 16
+
+#define GRCAN_STAT_ERRCNT_WARNING_LIMIT 96
+#define GRCAN_STAT_ERRCNT_PASSIVE_LIMIT 127
+
+#define GRCAN_CTRL_RESET 0x2
+#define GRCAN_CTRL_ENABLE 0x1
+
+#define GRCAN_TXCTRL_ENABLE 0x1
+#define GRCAN_TXCTRL_ONGOING 0x2
+#define GRCAN_TXCTRL_SINGLE 0x4
+
+#define GRCAN_RXCTRL_ENABLE 0x1
+#define GRCAN_RXCTRL_ONGOING 0x2
+
+/* Relative offset of IRQ sources to AMBA Plug&Play */
+#define GRCAN_IRQIX_IRQ 0
+#define GRCAN_IRQIX_TXSYNC 1
+#define GRCAN_IRQIX_RXSYNC 2
+
+#define GRCAN_IRQ_PASS 0x00001
+#define GRCAN_IRQ_OFF 0x00002
+#define GRCAN_IRQ_OR 0x00004
+#define GRCAN_IRQ_RXAHBERR 0x00008
+#define GRCAN_IRQ_TXAHBERR 0x00010
+#define GRCAN_IRQ_RXIRQ 0x00020
+#define GRCAN_IRQ_TXIRQ 0x00040
+#define GRCAN_IRQ_RXFULL 0x00080
+#define GRCAN_IRQ_TXEMPTY 0x00100
+#define GRCAN_IRQ_RX 0x00200
+#define GRCAN_IRQ_TX 0x00400
+#define GRCAN_IRQ_RXSYNC 0x00800
+#define GRCAN_IRQ_TXSYNC 0x01000
+#define GRCAN_IRQ_RXERRCTR 0x02000
+#define GRCAN_IRQ_TXERRCTR 0x04000
+#define GRCAN_IRQ_RXMISS 0x08000
+#define GRCAN_IRQ_TXLOSS 0x10000
+
+#define GRCAN_IRQ_NONE 0
+#define GRCAN_IRQ_ALL \
+ (GRCAN_IRQ_PASS | GRCAN_IRQ_OFF | GRCAN_IRQ_OR \
+ | GRCAN_IRQ_RXAHBERR | GRCAN_IRQ_TXAHBERR \
+ | GRCAN_IRQ_RXIRQ | GRCAN_IRQ_TXIRQ \
+ | GRCAN_IRQ_RXFULL | GRCAN_IRQ_TXEMPTY \
+ | GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_RXSYNC \
+ | GRCAN_IRQ_TXSYNC | GRCAN_IRQ_RXERRCTR \
+ | GRCAN_IRQ_TXERRCTR | GRCAN_IRQ_RXMISS \
+ | GRCAN_IRQ_TXLOSS)
+
+#define GRCAN_IRQ_ERRCTR_RELATED (GRCAN_IRQ_RXERRCTR | GRCAN_IRQ_TXERRCTR \
+ | GRCAN_IRQ_PASS | GRCAN_IRQ_OFF)
+#define GRCAN_IRQ_ERRORS (GRCAN_IRQ_ERRCTR_RELATED | GRCAN_IRQ_OR \
+ | GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR \
+ | GRCAN_IRQ_TXLOSS)
+#define GRCAN_IRQ_DEFAULT (GRCAN_IRQ_RX | GRCAN_IRQ_TX | GRCAN_IRQ_ERRORS)
+
+#define GRCAN_MSG_SIZE 16
+
+#define GRCAN_MSG_IDE 0x80000000
+#define GRCAN_MSG_RTR 0x40000000
+#define GRCAN_MSG_BID 0x1ffc0000
+#define GRCAN_MSG_EID 0x1fffffff
+#define GRCAN_MSG_IDE_BIT 31
+#define GRCAN_MSG_RTR_BIT 30
+#define GRCAN_MSG_BID_BIT 18
+#define GRCAN_MSG_EID_BIT 0
+
+#define GRCAN_MSG_DLC 0xf0000000
+#define GRCAN_MSG_TXERRC 0x00ff0000
+#define GRCAN_MSG_RXERRC 0x0000ff00
+#define GRCAN_MSG_DLC_BIT 28
+#define GRCAN_MSG_TXERRC_BIT 16
+#define GRCAN_MSG_RXERRC_BIT 8
+#define GRCAN_MSG_AHBERR 0x00000008
+#define GRCAN_MSG_OR 0x00000004
+#define GRCAN_MSG_OFF 0x00000002
+#define GRCAN_MSG_PASS 0x00000001
+
+#define GRCAN_MSG_DATA_SLOT_INDEX(i) (2 + (i) / 4)
+#define GRCAN_MSG_DATA_SHIFT(i) ((3 - (i) % 4) * 8)
+
+#define GRCAN_BUFFER_ALIGNMENT 1024
+#define GRCAN_DEFAULT_BUFFER_SIZE 1024
+#define GRCAN_VALID_TR_SIZE_MASK 0x001fffc0
+
+#define GRCAN_INVALID_BUFFER_SIZE(s) \
+ ((s) == 0 || ((s) & ~GRCAN_VALID_TR_SIZE_MASK))
+
+#if GRCAN_INVALID_BUFFER_SIZE(GRCAN_DEFAULT_BUFFER_SIZE)
+#error "Invalid default buffer size"
+#endif
+
+struct grcan_dma_buffer {
+ size_t size;
+ void *buf;
+ dma_addr_t handle;
+};
+
+struct grcan_dma {
+ size_t base_size;
+ void *base_buf;
+ dma_addr_t base_handle;
+ struct grcan_dma_buffer tx;
+ struct grcan_dma_buffer rx;
+};
+
+/* GRCAN configuration parameters */
+struct grcan_device_config {
+ unsigned short enable0;
+ unsigned short enable1;
+ unsigned short select;
+ unsigned int txsize;
+ unsigned int rxsize;
+};
+
+#define GRCAN_DEFAULT_DEVICE_CONFIG { \
+ .enable0 = 0, \
+ .enable1 = 0, \
+ .select = 0, \
+ .txsize = GRCAN_DEFAULT_BUFFER_SIZE, \
+ .rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \
+ }
+
+#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100
+#define GRLIB_VERSION_MASK 0xffff
+
+/* GRCAN private data structure */
+struct grcan_priv {
+ struct can_priv can; /* must be the first member */
+ struct net_device *dev;
+ struct napi_struct napi;
+
+ struct grcan_registers __iomem *regs; /* ioremap'ed registers */
+ struct grcan_device_config config;
+ struct grcan_dma dma;
+
+ struct sk_buff **echo_skb; /* We allocate this on our own */
+ u8 *txdlc; /* Length of queued frames */
+
+ /* The echo skb pointer, pointing into echo_skb and indicating which
+ * frames can be echoed back. See the "Notes on the tx cyclic buffer
+ * handling"-comment for grcan_start_xmit for more details.
+ */
+ u32 eskbp;
+
+ /* Lock for controlling changes to the netif tx queue state, accesses to
+ * the echo_skb pointer eskbp and for making sure that a running reset
+ * and/or a close of the interface is done without interference from
+ * other parts of the code.
+ *
+ * The echo_skb pointer, eskbp, should only be accessed under this lock
+ * as it can be changed in several places and together with decisions on
+ * whether to wake up the tx queue.
+ *
+ * The tx queue must never be woken up if there is a running reset or
+ * close in progress.
+ *
+ * A running reset (see below on need_txbug_workaround) should never be
+ * done if the interface is closing down and several running resets
+ * should never be scheduled simultaneously.
+ */
+ spinlock_t lock;
+
+ /* Whether a workaround is needed due to a bug in older hardware. In
+ * this case, the driver both tries to prevent the bug from being
+ * triggered and recovers, if the bug nevertheless happens, by doing a
+ * running reset. A running reset, resets the device and continues from
+ * where it were without being noticeable from outside the driver (apart
+ * from slight delays).
+ */
+ bool need_txbug_workaround;
+
+ /* To trigger initization of running reset and to trigger running reset
+ * respectively in the case of a hanged device due to a txbug.
+ */
+ struct timer_list hang_timer;
+ struct timer_list rr_timer;
+
+ /* To avoid waking up the netif queue and restarting timers
+ * when a reset is scheduled or when closing of the device is
+ * undergoing
+ */
+ bool resetting;
+ bool closing;
+};
+
+/* Wait time for a short wait for ongoing to clear */
+#define GRCAN_SHORTWAIT_USECS 10
+
+/* Limit on the number of transmitted bits of an eff frame according to the CAN
+ * specification: 1 bit start of frame, 32 bits arbitration field, 6 bits
+ * control field, 8 bytes data field, 16 bits crc field, 2 bits ACK field and 7
+ * bits end of frame
+ */
+#define GRCAN_EFF_FRAME_MAX_BITS (1+32+6+8*8+16+2+7)
+
+#if defined(__BIG_ENDIAN)
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+ return ioread32be(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+ iowrite32be(val, reg);
+}
+#else
+static inline u32 grcan_read_reg(u32 __iomem *reg)
+{
+ return ioread32(reg);
+}
+
+static inline void grcan_write_reg(u32 __iomem *reg, u32 val)
+{
+ iowrite32(val, reg);
+}
+#endif
+
+static inline void grcan_clear_bits(u32 __iomem *reg, u32 mask)
+{
+ grcan_write_reg(reg, grcan_read_reg(reg) & ~mask);
+}
+
+static inline void grcan_set_bits(u32 __iomem *reg, u32 mask)
+{
+ grcan_write_reg(reg, grcan_read_reg(reg) | mask);
+}
+
+static inline u32 grcan_read_bits(u32 __iomem *reg, u32 mask)
+{
+ return grcan_read_reg(reg) & mask;
+}
+
+static inline void grcan_write_bits(u32 __iomem *reg, u32 value, u32 mask)
+{
+ u32 old = grcan_read_reg(reg);
+
+ grcan_write_reg(reg, (old & ~mask) | (value & mask));
+}
+
+/* a and b should both be in [0,size] and a == b == size should not hold */
+static inline u32 grcan_ring_add(u32 a, u32 b, u32 size)
+{
+ u32 sum = a + b;
+
+ if (sum < size)
+ return sum;
+ else
+ return sum - size;
+}
+
+/* a and b should both be in [0,size) */
+static inline u32 grcan_ring_sub(u32 a, u32 b, u32 size)
+{
+ return grcan_ring_add(a, size - b, size);
+}
+
+/* Available slots for new transmissions */
+static inline u32 grcan_txspace(size_t txsize, u32 txwr, u32 eskbp)
+{
+ u32 slots = txsize / GRCAN_MSG_SIZE - 1;
+ u32 used = grcan_ring_sub(txwr, eskbp, txsize) / GRCAN_MSG_SIZE;
+
+ return slots - used;
+}
+
+/* Configuration parameters that can be set via module parameters */
+static struct grcan_device_config grcan_module_config =
+ GRCAN_DEFAULT_DEVICE_CONFIG;
+
+static const struct can_bittiming_const grcan_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = GRCAN_CONF_PS1_MIN + 1,
+ .tseg1_max = GRCAN_CONF_PS1_MAX + 1,
+ .tseg2_min = GRCAN_CONF_PS2_MIN,
+ .tseg2_max = GRCAN_CONF_PS2_MAX,
+ .sjw_max = GRCAN_CONF_RSJ_MAX,
+ .brp_min = GRCAN_CONF_SCALER_MIN + 1,
+ .brp_max = GRCAN_CONF_SCALER_MAX + 1,
+ .brp_inc = GRCAN_CONF_SCALER_INC,
+};
+
+static int grcan_set_bittiming(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u32 timing = 0;
+ int bpr, rsj, ps1, ps2, scaler;
+
+ /* Should never happen - function will not be called when
+ * device is up
+ */
+ if (grcan_read_bits(&regs->ctrl, GRCAN_CTRL_ENABLE))
+ return -EBUSY;
+
+ bpr = 0; /* Note bpr and brp are different concepts */
+ rsj = bt->sjw;
+ ps1 = (bt->prop_seg + bt->phase_seg1) - 1; /* tseg1 - 1 */
+ ps2 = bt->phase_seg2;
+ scaler = (bt->brp - 1);
+ netdev_dbg(dev, "Request for BPR=%d, RSJ=%d, PS1=%d, PS2=%d, SCALER=%d",
+ bpr, rsj, ps1, ps2, scaler);
+ if (!(ps1 > ps2)) {
+ netdev_err(dev, "PS1 > PS2 must hold: PS1=%d, PS2=%d\n",
+ ps1, ps2);
+ return -EINVAL;
+ }
+ if (!(ps2 >= rsj)) {
+ netdev_err(dev, "PS2 >= RSJ must hold: PS2=%d, RSJ=%d\n",
+ ps2, rsj);
+ return -EINVAL;
+ }
+
+ timing |= (bpr << GRCAN_CONF_BPR_BIT) & GRCAN_CONF_BPR;
+ timing |= (rsj << GRCAN_CONF_RSJ_BIT) & GRCAN_CONF_RSJ;
+ timing |= (ps1 << GRCAN_CONF_PS1_BIT) & GRCAN_CONF_PS1;
+ timing |= (ps2 << GRCAN_CONF_PS2_BIT) & GRCAN_CONF_PS2;
+ timing |= (scaler << GRCAN_CONF_SCALER_BIT) & GRCAN_CONF_SCALER;
+ netdev_info(dev, "setting timing=0x%x\n", timing);
+ grcan_write_bits(&regs->conf, timing, GRCAN_CONF_TIMING);
+
+ return 0;
+}
+
+static int grcan_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ u32 status = grcan_read_reg(&regs->stat);
+
+ bec->txerr = (status & GRCAN_STAT_TXERRCNT) >> GRCAN_STAT_TXERRCNT_BIT;
+ bec->rxerr = (status & GRCAN_STAT_RXERRCNT) >> GRCAN_STAT_RXERRCNT_BIT;
+ return 0;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget);
+
+/* Reset device, but keep configuration information */
+static void grcan_reset(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ u32 config = grcan_read_reg(&regs->conf);
+
+ grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+ grcan_write_reg(&regs->conf, config);
+
+ priv->eskbp = grcan_read_reg(&regs->txrd);
+ priv->can.state = CAN_STATE_STOPPED;
+
+ /* Turn off hardware filtering - regs->rxcode set to 0 by reset */
+ grcan_write_reg(&regs->rxmask, 0);
+}
+
+/* stop device without changing any configurations */
+static void grcan_stop_hardware(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+
+ grcan_write_reg(&regs->imr, GRCAN_IRQ_NONE);
+ grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+ grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+ grcan_clear_bits(&regs->ctrl, GRCAN_CTRL_ENABLE);
+}
+
+/* Let priv->eskbp catch up to regs->txrd and echo back the skbs if echo
+ * is true and free them otherwise.
+ *
+ * If budget is >= 0, stop after handling at most budget skbs. Otherwise,
+ * continue until priv->eskbp catches up to regs->txrd.
+ *
+ * priv->lock *must* be held when calling this function
+ */
+static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ struct grcan_dma *dma = &priv->dma;
+ struct net_device_stats *stats = &dev->stats;
+ int i, work_done;
+
+ /* Updates to priv->eskbp and wake-ups of the queue needs to
+ * be atomic towards the reads of priv->eskbp and shut-downs
+ * of the queue in grcan_start_xmit.
+ */
+ u32 txrd = grcan_read_reg(&regs->txrd);
+
+ for (work_done = 0; work_done < budget || budget < 0; work_done++) {
+ if (priv->eskbp == txrd)
+ break;
+ i = priv->eskbp / GRCAN_MSG_SIZE;
+ if (echo) {
+ /* Normal echo of messages */
+ stats->tx_packets++;
+ stats->tx_bytes += priv->txdlc[i];
+ priv->txdlc[i] = 0;
+ can_get_echo_skb(dev, i);
+ } else {
+ /* For cleanup of untransmitted messages */
+ can_free_echo_skb(dev, i);
+ }
+
+ priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
+ dma->tx.size);
+ txrd = grcan_read_reg(&regs->txrd);
+ }
+ return work_done;
+}
+
+static void grcan_lost_one_shot_frame(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ struct grcan_dma *dma = &priv->dma;
+ u32 txrd;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ catch_up_echo_skb(dev, -1, true);
+
+ if (unlikely(grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE))) {
+ /* Should never happen */
+ netdev_err(dev, "TXCTRL enabled at TXLOSS in one shot mode\n");
+ } else {
+ /* By the time an GRCAN_IRQ_TXLOSS is generated in
+ * one-shot mode there is no problem in writing
+ * to TXRD even in versions of the hardware in
+ * which GRCAN_TXCTRL_ONGOING is not cleared properly
+ * in one-shot mode.
+ */
+
+ /* Skip message and discard echo-skb */
+ txrd = grcan_read_reg(&regs->txrd);
+ txrd = grcan_ring_add(txrd, GRCAN_MSG_SIZE, dma->tx.size);
+ grcan_write_reg(&regs->txrd, txrd);
+ catch_up_echo_skb(dev, -1, false);
+
+ if (!priv->resetting && !priv->closing &&
+ !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) {
+ netif_wake_queue(dev);
+ grcan_set_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+ }
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_err(struct net_device *dev, u32 sources, u32 status)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ struct grcan_dma *dma = &priv->dma;
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame cf;
+
+ /* Zero potential error_frame */
+ memset(&cf, 0, sizeof(cf));
+
+ /* Message lost interrupt. This might be due to arbitration error, but
+ * is also triggered when there is no one else on the can bus or when
+ * there is a problem with the hardware interface or the bus itself. As
+ * arbitration errors can not be singled out, no error frames are
+ * generated reporting this event as an arbitration error.
+ */
+ if (sources & GRCAN_IRQ_TXLOSS) {
+ /* Take care of failed one-shot transmit */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+ grcan_lost_one_shot_frame(dev);
+
+ /* Stop printing as soon as error passive or bus off is in
+ * effect to limit the amount of txloss debug printouts.
+ */
+ if (!(status & GRCAN_STAT_ERRCTR_RELATED)) {
+ netdev_dbg(dev, "tx message lost\n");
+ stats->tx_errors++;
+ }
+ }
+
+ /* Conditions dealing with the error counters. There is no interrupt for
+ * error warning, but there are interrupts for increases of the error
+ * counters.
+ */
+ if ((sources & GRCAN_IRQ_ERRCTR_RELATED) ||
+ (status & GRCAN_STAT_ERRCTR_RELATED)) {
+ enum can_state state = priv->can.state;
+ enum can_state oldstate = state;
+ u32 txerr = (status & GRCAN_STAT_TXERRCNT)
+ >> GRCAN_STAT_TXERRCNT_BIT;
+ u32 rxerr = (status & GRCAN_STAT_RXERRCNT)
+ >> GRCAN_STAT_RXERRCNT_BIT;
+
+ /* Figure out current state */
+ if (status & GRCAN_STAT_OFF) {
+ state = CAN_STATE_BUS_OFF;
+ } else if (status & GRCAN_STAT_PASS) {
+ state = CAN_STATE_ERROR_PASSIVE;
+ } else if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT ||
+ rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT) {
+ state = CAN_STATE_ERROR_WARNING;
+ } else {
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
+
+ /* Handle and report state changes */
+ if (state != oldstate) {
+ switch (state) {
+ case CAN_STATE_BUS_OFF:
+ netdev_dbg(dev, "bus-off\n");
+ netif_carrier_off(dev);
+ priv->can.can_stats.bus_off++;
+
+ /* Prevent the hardware from recovering from bus
+ * off on its own if restart is disabled.
+ */
+ if (!priv->can.restart_ms)
+ grcan_stop_hardware(dev);
+
+ cf.can_id |= CAN_ERR_BUSOFF;
+ break;
+
+ case CAN_STATE_ERROR_PASSIVE:
+ netdev_dbg(dev, "Error passive condition\n");
+ priv->can.can_stats.error_passive++;
+
+ cf.can_id |= CAN_ERR_CRTL;
+ if (txerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+ cf.data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+ if (rxerr >= GRCAN_STAT_ERRCNT_PASSIVE_LIMIT)
+ cf.data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+ break;
+
+ case CAN_STATE_ERROR_WARNING:
+ netdev_dbg(dev, "Error warning condition\n");
+ priv->can.can_stats.error_warning++;
+
+ cf.can_id |= CAN_ERR_CRTL;
+ if (txerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+ cf.data[1] |= CAN_ERR_CRTL_TX_WARNING;
+ if (rxerr >= GRCAN_STAT_ERRCNT_WARNING_LIMIT)
+ cf.data[1] |= CAN_ERR_CRTL_RX_WARNING;
+ break;
+
+ case CAN_STATE_ERROR_ACTIVE:
+ netdev_dbg(dev, "Error active condition\n");
+ cf.can_id |= CAN_ERR_CRTL;
+ break;
+
+ default:
+ /* There are no others at this point */
+ break;
+ }
+ cf.data[6] = txerr;
+ cf.data[7] = rxerr;
+ priv->can.state = state;
+ }
+
+ /* Report automatic restarts */
+ if (priv->can.restart_ms && oldstate == CAN_STATE_BUS_OFF) {
+ unsigned long flags;
+
+ cf.can_id |= CAN_ERR_RESTARTED;
+ netdev_dbg(dev, "restarted\n");
+ priv->can.can_stats.restarts++;
+ netif_carrier_on(dev);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (!priv->resetting && !priv->closing) {
+ u32 txwr = grcan_read_reg(&regs->txwr);
+
+ if (grcan_txspace(dma->tx.size, txwr,
+ priv->eskbp))
+ netif_wake_queue(dev);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+ }
+
+ /* Data overrun interrupt */
+ if ((sources & GRCAN_IRQ_OR) || (status & GRCAN_STAT_OR)) {
+ netdev_dbg(dev, "got data overrun interrupt\n");
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+
+ cf.can_id |= CAN_ERR_CRTL;
+ cf.data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+ }
+
+ /* AHB bus error interrupts (not CAN bus errors) - shut down the
+ * device.
+ */
+ if (sources & (GRCAN_IRQ_TXAHBERR | GRCAN_IRQ_RXAHBERR) ||
+ (status & GRCAN_STAT_AHBERR)) {
+ char *txrx = "";
+ unsigned long flags;
+
+ if (sources & GRCAN_IRQ_TXAHBERR) {
+ txrx = "on tx ";
+ stats->tx_errors++;
+ } else if (sources & GRCAN_IRQ_RXAHBERR) {
+ txrx = "on rx ";
+ stats->rx_errors++;
+ }
+ netdev_err(dev, "Fatal AHB buss error %s- halting device\n",
+ txrx);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Prevent anything to be enabled again and halt device */
+ priv->closing = true;
+ netif_stop_queue(dev);
+ grcan_stop_hardware(dev);
+ priv->can.state = CAN_STATE_STOPPED;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ /* Pass on error frame if something to report,
+ * i.e. id contains some information
+ */
+ if (cf.can_id) {
+ struct can_frame *skb_cf;
+ struct sk_buff *skb = alloc_can_err_skb(dev, &skb_cf);
+
+ if (skb == NULL) {
+ netdev_dbg(dev, "could not allocate error frame\n");
+ return;
+ }
+ skb_cf->can_id |= cf.can_id;
+ memcpy(skb_cf->data, cf.data, sizeof(cf.data));
+
+ netif_rx(skb);
+ }
+}
+
+static irqreturn_t grcan_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ u32 sources, status;
+
+ /* Find out the source */
+ sources = grcan_read_reg(&regs->pimsr);
+ if (!sources)
+ return IRQ_NONE;
+ grcan_write_reg(&regs->picr, sources);
+ status = grcan_read_reg(&regs->stat);
+
+ /* If we got TX progress, the device has not hanged,
+ * so disable the hang timer
+ */
+ if (priv->need_txbug_workaround &&
+ (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_TXLOSS))) {
+ del_timer(&priv->hang_timer);
+ }
+
+ /* Frame(s) received or transmitted */
+ if (sources & (GRCAN_IRQ_TX | GRCAN_IRQ_RX)) {
+ /* Disable tx/rx interrupts and schedule poll(). No need for
+ * locking as interference from a running reset at worst leads
+ * to an extra interrupt.
+ */
+ grcan_clear_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+ napi_schedule(&priv->napi);
+ }
+
+ /* (Potential) error conditions to take care of */
+ if (sources & GRCAN_IRQ_ERRORS)
+ grcan_err(dev, sources, status);
+
+ return IRQ_HANDLED;
+}
+
+/* Reset device and restart operations from where they were.
+ *
+ * This assumes that RXCTRL & RXCTRL is properly disabled and that RX
+ * is not ONGOING (TX might be stuck in ONGOING due to a harwrware bug
+ * for single shot)
+ */
+static void grcan_running_reset(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ unsigned long flags;
+
+ /* This temporarily messes with eskbp, so we need to lock
+ * priv->lock
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+
+ priv->resetting = false;
+ del_timer(&priv->hang_timer);
+ del_timer(&priv->rr_timer);
+
+ if (!priv->closing) {
+ /* Save and reset - config register preserved by grcan_reset */
+ u32 imr = grcan_read_reg(&regs->imr);
+
+ u32 txaddr = grcan_read_reg(&regs->txaddr);
+ u32 txsize = grcan_read_reg(&regs->txsize);
+ u32 txwr = grcan_read_reg(&regs->txwr);
+ u32 txrd = grcan_read_reg(&regs->txrd);
+ u32 eskbp = priv->eskbp;
+
+ u32 rxaddr = grcan_read_reg(&regs->rxaddr);
+ u32 rxsize = grcan_read_reg(&regs->rxsize);
+ u32 rxwr = grcan_read_reg(&regs->rxwr);
+ u32 rxrd = grcan_read_reg(&regs->rxrd);
+
+ grcan_reset(dev);
+
+ /* Restore */
+ grcan_write_reg(&regs->txaddr, txaddr);
+ grcan_write_reg(&regs->txsize, txsize);
+ grcan_write_reg(&regs->txwr, txwr);
+ grcan_write_reg(&regs->txrd, txrd);
+ priv->eskbp = eskbp;
+
+ grcan_write_reg(&regs->rxaddr, rxaddr);
+ grcan_write_reg(&regs->rxsize, rxsize);
+ grcan_write_reg(&regs->rxwr, rxwr);
+ grcan_write_reg(&regs->rxrd, rxrd);
+
+ /* Turn on device again */
+ grcan_write_reg(&regs->imr, imr);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ grcan_write_reg(&regs->txctrl, GRCAN_TXCTRL_ENABLE
+ | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+ ? GRCAN_TXCTRL_SINGLE : 0));
+ grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+ grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+ /* Start queue if there is size and listen-onle mode is not
+ * enabled
+ */
+ if (grcan_txspace(priv->dma.tx.size, txwr, priv->eskbp) &&
+ !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+ netif_wake_queue(dev);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ netdev_err(dev, "Device reset and restored\n");
+}
+
+/* Waiting time in usecs corresponding to the transmission of three maximum
+ * sized can frames in the given bitrate (in bits/sec). Waiting for this amount
+ * of time makes sure that the can controller have time to finish sending or
+ * receiving a frame with a good margin.
+ *
+ * usecs/sec * number of frames * bits/frame / bits/sec
+ */
+static inline u32 grcan_ongoing_wait_usecs(__u32 bitrate)
+{
+ return 1000000 * 3 * GRCAN_EFF_FRAME_MAX_BITS / bitrate;
+}
+
+/* Set timer so that it will not fire until after a period in which the can
+ * controller have a good margin to finish transmitting a frame unless it has
+ * hanged
+ */
+static inline void grcan_reset_timer(struct timer_list *timer, __u32 bitrate)
+{
+ u32 wait_jiffies = usecs_to_jiffies(grcan_ongoing_wait_usecs(bitrate));
+
+ mod_timer(timer, jiffies + wait_jiffies);
+}
+
+/* Disable channels and schedule a running reset */
+static void grcan_initiate_running_reset(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ unsigned long flags;
+
+ netdev_err(dev, "Device seems hanged - reset scheduled\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* The main body of this function must never be executed again
+ * until after an execution of grcan_running_reset
+ */
+ if (!priv->resetting && !priv->closing) {
+ priv->resetting = true;
+ netif_stop_queue(dev);
+ grcan_clear_bits(&regs->txctrl, GRCAN_TXCTRL_ENABLE);
+ grcan_clear_bits(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+ grcan_reset_timer(&priv->rr_timer, priv->can.bittiming.bitrate);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void grcan_free_dma_buffers(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_dma *dma = &priv->dma;
+
+ dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
+ dma->base_handle);
+ memset(dma, 0, sizeof(*dma));
+}
+
+static int grcan_allocate_dma_buffers(struct net_device *dev,
+ size_t tsize, size_t rsize)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_dma *dma = &priv->dma;
+ struct grcan_dma_buffer *large = rsize > tsize ? &dma->rx : &dma->tx;
+ struct grcan_dma_buffer *small = rsize > tsize ? &dma->tx : &dma->rx;
+ size_t shift;
+
+ /* Need a whole number of GRCAN_BUFFER_ALIGNMENT for the large,
+ * i.e. first buffer
+ */
+ size_t maxs = max(tsize, rsize);
+ size_t lsize = ALIGN(maxs, GRCAN_BUFFER_ALIGNMENT);
+
+ /* Put the small buffer after that */
+ size_t ssize = min(tsize, rsize);
+
+ /* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
+ dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
+ dma->base_buf = dma_alloc_coherent(&dev->dev,
+ dma->base_size,
+ &dma->base_handle,
+ GFP_KERNEL);
+
+ if (!dma->base_buf)
+ return -ENOMEM;
+
+ dma->tx.size = tsize;
+ dma->rx.size = rsize;
+
+ large->handle = ALIGN(dma->base_handle, GRCAN_BUFFER_ALIGNMENT);
+ small->handle = large->handle + lsize;
+ shift = large->handle - dma->base_handle;
+
+ large->buf = dma->base_buf + shift;
+ small->buf = large->buf + lsize;
+
+ return 0;
+}
+
+/* priv->lock *must* be held when calling this function */
+static int grcan_start(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ u32 confop, txctrl;
+
+ grcan_reset(dev);
+
+ grcan_write_reg(&regs->txaddr, priv->dma.tx.handle);
+ grcan_write_reg(&regs->txsize, priv->dma.tx.size);
+ /* regs->txwr, regs->txrd and priv->eskbp already set to 0 by reset */
+
+ grcan_write_reg(&regs->rxaddr, priv->dma.rx.handle);
+ grcan_write_reg(&regs->rxsize, priv->dma.rx.size);
+ /* regs->rxwr and regs->rxrd already set to 0 by reset */
+
+ /* Enable interrupts */
+ grcan_read_reg(&regs->pir);
+ grcan_write_reg(&regs->imr, GRCAN_IRQ_DEFAULT);
+
+ /* Enable interfaces, channels and device */
+ confop = GRCAN_CONF_ABORT
+ | (priv->config.enable0 ? GRCAN_CONF_ENABLE0 : 0)
+ | (priv->config.enable1 ? GRCAN_CONF_ENABLE1 : 0)
+ | (priv->config.select ? GRCAN_CONF_SELECT : 0)
+ | (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY ?
+ GRCAN_CONF_SILENT : 0)
+ | (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+ GRCAN_CONF_SAM : 0);
+ grcan_write_bits(&regs->conf, confop, GRCAN_CONF_OPERATION);
+ txctrl = GRCAN_TXCTRL_ENABLE
+ | (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT
+ ? GRCAN_TXCTRL_SINGLE : 0);
+ grcan_write_reg(&regs->txctrl, txctrl);
+ grcan_write_reg(&regs->rxctrl, GRCAN_RXCTRL_ENABLE);
+ grcan_write_reg(&regs->ctrl, GRCAN_CTRL_ENABLE);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ return 0;
+}
+
+static int grcan_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err = 0;
+
+ if (mode == CAN_MODE_START) {
+ /* This might be called to restart the device to recover from
+ * bus off errors
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->closing || priv->resetting) {
+ err = -EBUSY;
+ } else {
+ netdev_info(dev, "Restarting device\n");
+ grcan_start(dev);
+ if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+ netif_wake_queue(dev);
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return err;
+ }
+ return -EOPNOTSUPP;
+}
+
+static int grcan_open(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_dma *dma = &priv->dma;
+ unsigned long flags;
+ int err;
+
+ /* Allocate memory */
+ err = grcan_allocate_dma_buffers(dev, priv->config.txsize,
+ priv->config.rxsize);
+ if (err) {
+ netdev_err(dev, "could not allocate DMA buffers\n");
+ return err;
+ }
+
+ priv->echo_skb = kzalloc(dma->tx.size * sizeof(*priv->echo_skb),
+ GFP_KERNEL);
+ if (!priv->echo_skb) {
+ err = -ENOMEM;
+ goto exit_free_dma_buffers;
+ }
+ priv->can.echo_skb_max = dma->tx.size;
+ priv->can.echo_skb = priv->echo_skb;
+
+ priv->txdlc = kzalloc(dma->tx.size * sizeof(*priv->txdlc), GFP_KERNEL);
+ if (!priv->txdlc) {
+ err = -ENOMEM;
+ goto exit_free_echo_skb;
+ }
+
+ /* Get can device up */
+ err = open_candev(dev);
+ if (err)
+ goto exit_free_txdlc;
+
+ err = request_irq(dev->irq, grcan_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (err)
+ goto exit_close_candev;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ napi_enable(&priv->napi);
+ grcan_start(dev);
+ if (!(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+ netif_start_queue(dev);
+ priv->resetting = false;
+ priv->closing = false;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+
+exit_close_candev:
+ close_candev(dev);
+exit_free_txdlc:
+ kfree(priv->txdlc);
+exit_free_echo_skb:
+ kfree(priv->echo_skb);
+exit_free_dma_buffers:
+ grcan_free_dma_buffers(dev);
+ return err;
+}
+
+static int grcan_close(struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ napi_disable(&priv->napi);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ priv->closing = true;
+ if (priv->need_txbug_workaround) {
+ del_timer_sync(&priv->hang_timer);
+ del_timer_sync(&priv->rr_timer);
+ }
+ netif_stop_queue(dev);
+ grcan_stop_hardware(dev);
+ priv->can.state = CAN_STATE_STOPPED;
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ free_irq(dev->irq, dev);
+ close_candev(dev);
+
+ grcan_free_dma_buffers(dev);
+ priv->can.echo_skb_max = 0;
+ priv->can.echo_skb = NULL;
+ kfree(priv->echo_skb);
+ kfree(priv->txdlc);
+
+ return 0;
+}
+
+static int grcan_transmit_catch_up(struct net_device *dev, int budget)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ unsigned long flags;
+ int work_done;
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ work_done = catch_up_echo_skb(dev, budget, true);
+ if (work_done) {
+ if (!priv->resetting && !priv->closing &&
+ !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+ netif_wake_queue(dev);
+
+ /* With napi we don't get TX interrupts for a while,
+ * so prevent a running reset while catching up
+ */
+ if (priv->need_txbug_workaround)
+ del_timer(&priv->hang_timer);
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return work_done;
+}
+
+static int grcan_receive(struct net_device *dev, int budget)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ struct grcan_dma *dma = &priv->dma;
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 wr, rd, startrd;
+ u32 *slot;
+ u32 i, rtr, eff, j, shift;
+ int work_done = 0;
+
+ rd = grcan_read_reg(&regs->rxrd);
+ startrd = rd;
+ for (work_done = 0; work_done < budget; work_done++) {
+ /* Check for packet to receive */
+ wr = grcan_read_reg(&regs->rxwr);
+ if (rd == wr)
+ break;
+
+ /* Take care of packet */
+ skb = alloc_can_skb(dev, &cf);
+ if (skb == NULL) {
+ netdev_err(dev,
+ "dropping frame: skb allocation failed\n");
+ stats->rx_dropped++;
+ continue;
+ }
+
+ slot = dma->rx.buf + rd;
+ eff = slot[0] & GRCAN_MSG_IDE;
+ rtr = slot[0] & GRCAN_MSG_RTR;
+ if (eff) {
+ cf->can_id = ((slot[0] & GRCAN_MSG_EID)
+ >> GRCAN_MSG_EID_BIT);
+ cf->can_id |= CAN_EFF_FLAG;
+ } else {
+ cf->can_id = ((slot[0] & GRCAN_MSG_BID)
+ >> GRCAN_MSG_BID_BIT);
+ }
+ cf->can_dlc = get_can_dlc((slot[1] & GRCAN_MSG_DLC)
+ >> GRCAN_MSG_DLC_BIT);
+ if (rtr) {
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ for (i = 0; i < cf->can_dlc; i++) {
+ j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+ shift = GRCAN_MSG_DATA_SHIFT(i);
+ cf->data[i] = (u8)(slot[j] >> shift);
+ }
+ }
+ netif_receive_skb(skb);
+
+ /* Update statistics and read pointer */
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ rd = grcan_ring_add(rd, GRCAN_MSG_SIZE, dma->rx.size);
+ }
+
+ /* Make sure everything is read before allowing hardware to
+ * use the memory
+ */
+ mb();
+
+ /* Update read pointer - no need to check for ongoing */
+ if (likely(rd != startrd))
+ grcan_write_reg(&regs->rxrd, rd);
+
+ return work_done;
+}
+
+static int grcan_poll(struct napi_struct *napi, int budget)
+{
+ struct grcan_priv *priv = container_of(napi, struct grcan_priv, napi);
+ struct net_device *dev = priv->dev;
+ struct grcan_registers __iomem *regs = priv->regs;
+ unsigned long flags;
+ int tx_work_done, rx_work_done;
+ int rx_budget = budget / 2;
+ int tx_budget = budget - rx_budget;
+
+ /* Half of the budget for receiveing messages */
+ rx_work_done = grcan_receive(dev, rx_budget);
+
+ /* Half of the budget for transmitting messages as that can trigger echo
+ * frames being received
+ */
+ tx_work_done = grcan_transmit_catch_up(dev, tx_budget);
+
+ if (rx_work_done < rx_budget && tx_work_done < tx_budget) {
+ napi_complete(napi);
+
+ /* Guarantee no interference with a running reset that otherwise
+ * could turn off interrupts.
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* Enable tx and rx interrupts again. No need to check
+ * priv->closing as napi_disable in grcan_close is waiting for
+ * scheduled napi calls to finish.
+ */
+ grcan_set_bits(&regs->imr, GRCAN_IRQ_TX | GRCAN_IRQ_RX);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
+ return rx_work_done + tx_work_done;
+}
+
+/* Work tx bug by waiting while for the risky situation to clear. If that fails,
+ * drop a frame in one-shot mode or indicate a busy device otherwise.
+ *
+ * Returns 0 on successful wait. Otherwise it sets *netdev_tx_status to the
+ * value that should be returned by grcan_start_xmit when aborting the xmit.
+ */
+static int grcan_txbug_workaround(struct net_device *dev, struct sk_buff *skb,
+ u32 txwr, u32 oneshotmode,
+ netdev_tx_t *netdev_tx_status)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ struct grcan_dma *dma = &priv->dma;
+ int i;
+ unsigned long flags;
+
+ /* Wait a while for ongoing to be cleared or read pointer to catch up to
+ * write pointer. The latter is needed due to a bug in older versions of
+ * GRCAN in which ONGOING is not cleared properly one-shot mode when a
+ * transmission fails.
+ */
+ for (i = 0; i < GRCAN_SHORTWAIT_USECS; i++) {
+ udelay(1);
+ if (!grcan_read_bits(&regs->txctrl, GRCAN_TXCTRL_ONGOING) ||
+ grcan_read_reg(&regs->txrd) == txwr) {
+ return 0;
+ }
+ }
+
+ /* Clean up, in case the situation was not resolved */
+ spin_lock_irqsave(&priv->lock, flags);
+ if (!priv->resetting && !priv->closing) {
+ /* Queue might have been stopped earlier in grcan_start_xmit */
+ if (grcan_txspace(dma->tx.size, txwr, priv->eskbp))
+ netif_wake_queue(dev);
+ /* Set a timer to resolve a hanged tx controller */
+ if (!timer_pending(&priv->hang_timer))
+ grcan_reset_timer(&priv->hang_timer,
+ priv->can.bittiming.bitrate);
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ if (oneshotmode) {
+ /* In one-shot mode we should never end up here because
+ * then the interrupt handler increases txrd on TXLOSS,
+ * but it is consistent with one-shot mode to drop the
+ * frame in this case.
+ */
+ kfree_skb(skb);
+ *netdev_tx_status = NETDEV_TX_OK;
+ } else {
+ /* In normal mode the socket-can transmission queue get
+ * to keep the frame so that it can be retransmitted
+ * later
+ */
+ *netdev_tx_status = NETDEV_TX_BUSY;
+ }
+ return -EBUSY;
+}
+
+/* Notes on the tx cyclic buffer handling:
+ *
+ * regs->txwr - the next slot for the driver to put data to be sent
+ * regs->txrd - the next slot for the device to read data
+ * priv->eskbp - the next slot for the driver to call can_put_echo_skb for
+ *
+ * grcan_start_xmit can enter more messages as long as regs->txwr does
+ * not reach priv->eskbp (within 1 message gap)
+ *
+ * The device sends messages until regs->txrd reaches regs->txwr
+ *
+ * The interrupt calls handler calls can_put_echo_skb until
+ * priv->eskbp reaches regs->txrd
+ */
+static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct grcan_priv *priv = netdev_priv(dev);
+ struct grcan_registers __iomem *regs = priv->regs;
+ struct grcan_dma *dma = &priv->dma;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 id, txwr, txrd, space, txctrl;
+ int slotindex;
+ u32 *slot;
+ u32 i, rtr, eff, dlc, tmp, err;
+ int j, shift;
+ unsigned long flags;
+ u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ /* Trying to transmit in silent mode will generate error interrupts, but
+ * this should never happen - the queue should not have been started.
+ */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ return NETDEV_TX_BUSY;
+
+ /* Reads of priv->eskbp and shut-downs of the queue needs to
+ * be atomic towards the updates to priv->eskbp and wake-ups
+ * of the queue in the interrupt handler.
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+
+ txwr = grcan_read_reg(&regs->txwr);
+ space = grcan_txspace(dma->tx.size, txwr, priv->eskbp);
+
+ slotindex = txwr / GRCAN_MSG_SIZE;
+ slot = dma->tx.buf + txwr;
+
+ if (unlikely(space == 1))
+ netif_stop_queue(dev);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ /* End of critical section*/
+
+ /* This should never happen. If circular buffer is full, the
+ * netif_stop_queue should have been stopped already.
+ */
+ if (unlikely(!space)) {
+ netdev_err(dev, "No buffer space, but queue is non-stopped.\n");
+ return NETDEV_TX_BUSY;
+ }
+
+ /* Convert and write CAN message to DMA buffer */
+ eff = cf->can_id & CAN_EFF_FLAG;
+ rtr = cf->can_id & CAN_RTR_FLAG;
+ id = cf->can_id & (eff ? CAN_EFF_MASK : CAN_SFF_MASK);
+ dlc = cf->can_dlc;
+ if (eff)
+ tmp = (id << GRCAN_MSG_EID_BIT) & GRCAN_MSG_EID;
+ else
+ tmp = (id << GRCAN_MSG_BID_BIT) & GRCAN_MSG_BID;
+ slot[0] = (eff ? GRCAN_MSG_IDE : 0) | (rtr ? GRCAN_MSG_RTR : 0) | tmp;
+
+ slot[1] = ((dlc << GRCAN_MSG_DLC_BIT) & GRCAN_MSG_DLC);
+ slot[2] = 0;
+ slot[3] = 0;
+ for (i = 0; i < dlc; i++) {
+ j = GRCAN_MSG_DATA_SLOT_INDEX(i);
+ shift = GRCAN_MSG_DATA_SHIFT(i);
+ slot[j] |= cf->data[i] << shift;
+ }
+
+ /* Checking that channel has not been disabled. These cases
+ * should never happen
+ */
+ txctrl = grcan_read_reg(&regs->txctrl);
+ if (!(txctrl & GRCAN_TXCTRL_ENABLE))
+ netdev_err(dev, "tx channel spuriously disabled\n");
+
+ if (oneshotmode && !(txctrl & GRCAN_TXCTRL_SINGLE))
+ netdev_err(dev, "one-shot mode spuriously disabled\n");
+
+ /* Bug workaround for old version of grcan where updating txwr
+ * in the same clock cycle as the controller updates txrd to
+ * the current txwr could hang the can controller
+ */
+ if (priv->need_txbug_workaround) {
+ txrd = grcan_read_reg(&regs->txrd);
+ if (unlikely(grcan_ring_sub(txwr, txrd, dma->tx.size) == 1)) {
+ netdev_tx_t txstatus;
+
+ err = grcan_txbug_workaround(dev, skb, txwr,
+ oneshotmode, &txstatus);
+ if (err)
+ return txstatus;
+ }
+ }
+
+ /* Prepare skb for echoing. This must be after the bug workaround above
+ * as ownership of the skb is passed on by calling can_put_echo_skb.
+ * Returning NETDEV_TX_BUSY or accessing skb or cf after a call to
+ * can_put_echo_skb would be an error unless other measures are
+ * taken.
+ */
+ priv->txdlc[slotindex] = cf->can_dlc; /* Store dlc for statistics */
+ can_put_echo_skb(skb, dev, slotindex);
+
+ /* Make sure everything is written before allowing hardware to
+ * read from the memory
+ */
+ wmb();
+
+ /* Update write pointer to start transmission */
+ grcan_write_reg(&regs->txwr,
+ grcan_ring_add(txwr, GRCAN_MSG_SIZE, dma->tx.size));
+
+ return NETDEV_TX_OK;
+}
+
+/* ========== Setting up sysfs interface and module parameters ========== */
+
+#define GRCAN_NOT_BOOL(unsigned_val) ((unsigned_val) > 1)
+
+#define GRCAN_MODULE_PARAM(name, mtype, valcheckf, desc) \
+ static void grcan_sanitize_##name(struct platform_device *pd) \
+ { \
+ struct grcan_device_config grcan_default_config \
+ = GRCAN_DEFAULT_DEVICE_CONFIG; \
+ if (valcheckf(grcan_module_config.name)) { \
+ dev_err(&pd->dev, \
+ "Invalid module parameter value for " \
+ #name " - setting default\n"); \
+ grcan_module_config.name = \
+ grcan_default_config.name; \
+ } \
+ } \
+ module_param_named(name, grcan_module_config.name, \
+ mtype, S_IRUGO); \
+ MODULE_PARM_DESC(name, desc)
+
+#define GRCAN_CONFIG_ATTR(name, desc) \
+ static ssize_t grcan_store_##name(struct device *sdev, \
+ struct device_attribute *att, \
+ const char *buf, \
+ size_t count) \
+ { \
+ struct net_device *dev = to_net_dev(sdev); \
+ struct grcan_priv *priv = netdev_priv(dev); \
+ u8 val; \
+ int ret; \
+ if (dev->flags & IFF_UP) \
+ return -EBUSY; \
+ ret = kstrtou8(buf, 0, &val); \
+ if (ret < 0 || val > 1) \
+ return -EINVAL; \
+ priv->config.name = val; \
+ return count; \
+ } \
+ static ssize_t grcan_show_##name(struct device *sdev, \
+ struct device_attribute *att, \
+ char *buf) \
+ { \
+ struct net_device *dev = to_net_dev(sdev); \
+ struct grcan_priv *priv = netdev_priv(dev); \
+ return sprintf(buf, "%d\n", priv->config.name); \
+ } \
+ static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \
+ grcan_show_##name, \
+ grcan_store_##name); \
+ GRCAN_MODULE_PARAM(name, ushort, GRCAN_NOT_BOOL, desc)
+
+/* The following configuration options are made available both via module
+ * parameters and writable sysfs files. See the chapter about GRCAN in the
+ * documentation for the GRLIB VHDL library for further details.
+ */
+GRCAN_CONFIG_ATTR(enable0,
+ "Configuration of physical interface 0. Determines\n" \
+ "the \"Enable 0\" bit of the configuration register.\n" \
+ "Format: 0 | 1\nDefault: 0\n");
+
+GRCAN_CONFIG_ATTR(enable1,
+ "Configuration of physical interface 1. Determines\n" \
+ "the \"Enable 1\" bit of the configuration register.\n" \
+ "Format: 0 | 1\nDefault: 0\n");
+
+GRCAN_CONFIG_ATTR(select,
+ "Select which physical interface to use.\n" \
+ "Format: 0 | 1\nDefault: 0\n");
+
+/* The tx and rx buffer size configuration options are only available via module
+ * parameters.
+ */
+GRCAN_MODULE_PARAM(txsize, uint, GRCAN_INVALID_BUFFER_SIZE,
+ "Sets the size of the tx buffer.\n" \
+ "Format: <unsigned int> where (txsize & ~0x1fffc0) == 0\n" \
+ "Default: 1024\n");
+GRCAN_MODULE_PARAM(rxsize, uint, GRCAN_INVALID_BUFFER_SIZE,
+ "Sets the size of the rx buffer.\n" \
+ "Format: <unsigned int> where (size & ~0x1fffc0) == 0\n" \
+ "Default: 1024\n");
+
+/* Function that makes sure that configuration done using
+ * module parameters are set to valid values
+ */
+static void grcan_sanitize_module_config(struct platform_device *ofdev)
+{
+ grcan_sanitize_enable0(ofdev);
+ grcan_sanitize_enable1(ofdev);
+ grcan_sanitize_select(ofdev);
+ grcan_sanitize_txsize(ofdev);
+ grcan_sanitize_rxsize(ofdev);
+}
+
+static const struct attribute *const sysfs_grcan_attrs[] = {
+ /* Config attrs */
+ &dev_attr_enable0.attr,
+ &dev_attr_enable1.attr,
+ &dev_attr_select.attr,
+ NULL,
+};
+
+static const struct attribute_group sysfs_grcan_group = {
+ .name = "grcan",
+ .attrs = (struct attribute **)sysfs_grcan_attrs,
+};
+
+/* ========== Setting up the driver ========== */
+
+static const struct net_device_ops grcan_netdev_ops = {
+ .ndo_open = grcan_open,
+ .ndo_stop = grcan_close,
+ .ndo_start_xmit = grcan_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static int grcan_setup_netdev(struct platform_device *ofdev,
+ void __iomem *base,
+ int irq, u32 ambafreq, bool txbug)
+{
+ struct net_device *dev;
+ struct grcan_priv *priv;
+ struct grcan_registers __iomem *regs;
+ int err;
+
+ dev = alloc_candev(sizeof(struct grcan_priv), 0);
+ if (!dev)
+ return -ENOMEM;
+
+ dev->irq = irq;
+ dev->flags |= IFF_ECHO;
+ dev->netdev_ops = &grcan_netdev_ops;
+ dev->sysfs_groups[0] = &sysfs_grcan_group;
+
+ priv = netdev_priv(dev);
+ memcpy(&priv->config, &grcan_module_config,
+ sizeof(struct grcan_device_config));
+ priv->dev = dev;
+ priv->regs = base;
+ priv->can.bittiming_const = &grcan_bittiming_const;
+ priv->can.do_set_bittiming = grcan_set_bittiming;
+ priv->can.do_set_mode = grcan_set_mode;
+ priv->can.do_get_berr_counter = grcan_get_berr_counter;
+ priv->can.clock.freq = ambafreq;
+ priv->can.ctrlmode_supported =
+ CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_ONE_SHOT;
+ priv->need_txbug_workaround = txbug;
+
+ /* Discover if triple sampling is supported by hardware */
+ regs = priv->regs;
+ grcan_set_bits(&regs->ctrl, GRCAN_CTRL_RESET);
+ grcan_set_bits(&regs->conf, GRCAN_CONF_SAM);
+ if (grcan_read_bits(&regs->conf, GRCAN_CONF_SAM)) {
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+ dev_dbg(&ofdev->dev, "Hardware supports triple-sampling\n");
+ }
+
+ spin_lock_init(&priv->lock);
+
+ if (priv->need_txbug_workaround) {
+ init_timer(&priv->rr_timer);
+ priv->rr_timer.function = grcan_running_reset;
+ priv->rr_timer.data = (unsigned long)dev;
+
+ init_timer(&priv->hang_timer);
+ priv->hang_timer.function = grcan_initiate_running_reset;
+ priv->hang_timer.data = (unsigned long)dev;
+ }
+
+ netif_napi_add(dev, &priv->napi, grcan_poll, GRCAN_NAPI_WEIGHT);
+
+ SET_NETDEV_DEV(dev, &ofdev->dev);
+ dev_info(&ofdev->dev, "regs=0x%p, irq=%d, clock=%d\n",
+ priv->regs, dev->irq, priv->can.clock.freq);
+
+ err = register_candev(dev);
+ if (err)
+ goto exit_free_candev;
+
+ platform_set_drvdata(ofdev, dev);
+
+ /* Reset device to allow bit-timing to be set. No need to call
+ * grcan_reset at this stage. That is done in grcan_open.
+ */
+ grcan_write_reg(&regs->ctrl, GRCAN_CTRL_RESET);
+
+ return 0;
+exit_free_candev:
+ free_candev(dev);
+ return err;
+}
+
+static int grcan_probe(struct platform_device *ofdev)
+{
+ struct device_node *np = ofdev->dev.of_node;
+ struct resource *res;
+ u32 sysid, ambafreq;
+ int irq, err;
+ void __iomem *base;
+ bool txbug = true;
+
+ /* Compare GRLIB version number with the first that does not
+ * have the tx bug (see start_xmit)
+ */
+ err = of_property_read_u32(np, "systemid", &sysid);
+ if (!err && ((sysid & GRLIB_VERSION_MASK)
+ >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
+ txbug = false;
+
+ err = of_property_read_u32(np, "freq", &ambafreq);
+ if (err) {
+ dev_err(&ofdev->dev, "unable to fetch \"freq\" property\n");
+ goto exit_error;
+ }
+
+ res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&ofdev->dev, res);
+ if (IS_ERR(base)) {
+ err = PTR_ERR(base);
+ goto exit_error;
+ }
+
+ irq = irq_of_parse_and_map(np, GRCAN_IRQIX_IRQ);
+ if (!irq) {
+ dev_err(&ofdev->dev, "no irq found\n");
+ err = -ENODEV;
+ goto exit_error;
+ }
+
+ grcan_sanitize_module_config(ofdev);
+
+ err = grcan_setup_netdev(ofdev, base, irq, ambafreq, txbug);
+ if (err)
+ goto exit_dispose_irq;
+
+ return 0;
+
+exit_dispose_irq:
+ irq_dispose_mapping(irq);
+exit_error:
+ dev_err(&ofdev->dev,
+ "%s socket CAN driver initialization failed with error %d\n",
+ DRV_NAME, err);
+ return err;
+}
+
+static int grcan_remove(struct platform_device *ofdev)
+{
+ struct net_device *dev = platform_get_drvdata(ofdev);
+ struct grcan_priv *priv = netdev_priv(dev);
+
+ unregister_candev(dev); /* Will in turn call grcan_close */
+
+ irq_dispose_mapping(dev->irq);
+ netif_napi_del(&priv->napi);
+ free_candev(dev);
+
+ return 0;
+}
+
+static struct of_device_id grcan_match[] = {
+ {.name = "GAISLER_GRCAN"},
+ {.name = "01_03d"},
+ {.name = "GAISLER_GRHCAN"},
+ {.name = "01_034"},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, grcan_match);
+
+static struct platform_driver grcan_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = grcan_match,
+ },
+ .probe = grcan_probe,
+ .remove = grcan_remove,
+};
+
+module_platform_driver(grcan_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Socket CAN driver for Aeroflex Gaisler GRCAN");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
new file mode 100644
index 00000000000..2382c04dc78
--- /dev/null
+++ b/drivers/net/can/janz-ican3.c
@@ -0,0 +1,1924 @@
+/*
+ * Janz MODULbus VMOD-ICAN3 CAN Interface Driver
+ *
+ * Copyright (c) 2010 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <linux/netdevice.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/skb.h>
+#include <linux/can/error.h>
+
+#include <linux/mfd/janz.h>
+#include <asm/io.h>
+
+/* the DPM has 64k of memory, organized into 256x 256 byte pages */
+#define DPM_NUM_PAGES 256
+#define DPM_PAGE_SIZE 256
+#define DPM_PAGE_ADDR(p) ((p) * DPM_PAGE_SIZE)
+
+/* JANZ ICAN3 "old-style" host interface queue page numbers */
+#define QUEUE_OLD_CONTROL 0
+#define QUEUE_OLD_RB0 1
+#define QUEUE_OLD_RB1 2
+#define QUEUE_OLD_WB0 3
+#define QUEUE_OLD_WB1 4
+
+/* Janz ICAN3 "old-style" host interface control registers */
+#define MSYNC_PEER 0x00 /* ICAN only */
+#define MSYNC_LOCL 0x01 /* host only */
+#define TARGET_RUNNING 0x02
+
+#define MSYNC_RB0 0x01
+#define MSYNC_RB1 0x02
+#define MSYNC_RBLW 0x04
+#define MSYNC_RB_MASK (MSYNC_RB0 | MSYNC_RB1)
+
+#define MSYNC_WB0 0x10
+#define MSYNC_WB1 0x20
+#define MSYNC_WBLW 0x40
+#define MSYNC_WB_MASK (MSYNC_WB0 | MSYNC_WB1)
+
+/* Janz ICAN3 "new-style" host interface queue page numbers */
+#define QUEUE_TOHOST 5
+#define QUEUE_FROMHOST_MID 6
+#define QUEUE_FROMHOST_HIGH 7
+#define QUEUE_FROMHOST_LOW 8
+
+/* The first free page in the DPM is #9 */
+#define DPM_FREE_START 9
+
+/* Janz ICAN3 "new-style" and "fast" host interface descriptor flags */
+#define DESC_VALID 0x80
+#define DESC_WRAP 0x40
+#define DESC_INTERRUPT 0x20
+#define DESC_IVALID 0x10
+#define DESC_LEN(len) (len)
+
+/* Janz ICAN3 Firmware Messages */
+#define MSG_CONNECTI 0x02
+#define MSG_DISCONNECT 0x03
+#define MSG_IDVERS 0x04
+#define MSG_MSGLOST 0x05
+#define MSG_NEWHOSTIF 0x08
+#define MSG_INQUIRY 0x0a
+#define MSG_SETAFILMASK 0x10
+#define MSG_INITFDPMQUEUE 0x11
+#define MSG_HWCONF 0x12
+#define MSG_FMSGLOST 0x15
+#define MSG_CEVTIND 0x37
+#define MSG_CBTRREQ 0x41
+#define MSG_COFFREQ 0x42
+#define MSG_CONREQ 0x43
+#define MSG_CCONFREQ 0x47
+
+/*
+ * Janz ICAN3 CAN Inquiry Message Types
+ *
+ * NOTE: there appears to be a firmware bug here. You must send
+ * NOTE: INQUIRY_STATUS and expect to receive an INQUIRY_EXTENDED
+ * NOTE: response. The controller never responds to a message with
+ * NOTE: the INQUIRY_EXTENDED subspec :(
+ */
+#define INQUIRY_STATUS 0x00
+#define INQUIRY_TERMINATION 0x01
+#define INQUIRY_EXTENDED 0x04
+
+/* Janz ICAN3 CAN Set Acceptance Filter Mask Message Types */
+#define SETAFILMASK_REJECT 0x00
+#define SETAFILMASK_FASTIF 0x02
+
+/* Janz ICAN3 CAN Hardware Configuration Message Types */
+#define HWCONF_TERMINATE_ON 0x01
+#define HWCONF_TERMINATE_OFF 0x00
+
+/* Janz ICAN3 CAN Event Indication Message Types */
+#define CEVTIND_EI 0x01
+#define CEVTIND_DOI 0x02
+#define CEVTIND_LOST 0x04
+#define CEVTIND_FULL 0x08
+#define CEVTIND_BEI 0x10
+
+#define CEVTIND_CHIP_SJA1000 0x02
+
+#define ICAN3_BUSERR_QUOTA_MAX 255
+
+/* Janz ICAN3 CAN Frame Conversion */
+#define ICAN3_SNGL 0x02
+#define ICAN3_ECHO 0x10
+#define ICAN3_EFF_RTR 0x40
+#define ICAN3_SFF_RTR 0x10
+#define ICAN3_EFF 0x80
+
+#define ICAN3_CAN_TYPE_MASK 0x0f
+#define ICAN3_CAN_TYPE_SFF 0x00
+#define ICAN3_CAN_TYPE_EFF 0x01
+
+#define ICAN3_CAN_DLC_MASK 0x0f
+
+/*
+ * SJA1000 Status and Error Register Definitions
+ *
+ * Copied from drivers/net/can/sja1000/sja1000.h
+ */
+
+/* status register content */
+#define SR_BS 0x80
+#define SR_ES 0x40
+#define SR_TS 0x20
+#define SR_RS 0x10
+#define SR_TCS 0x08
+#define SR_TBS 0x04
+#define SR_DOS 0x02
+#define SR_RBS 0x01
+
+#define SR_CRIT (SR_BS|SR_ES)
+
+/* ECC register */
+#define ECC_SEG 0x1F
+#define ECC_DIR 0x20
+#define ECC_ERR 6
+#define ECC_BIT 0x00
+#define ECC_FORM 0x40
+#define ECC_STUFF 0x80
+#define ECC_MASK 0xc0
+
+/* Number of buffers for use in the "new-style" host interface */
+#define ICAN3_NEW_BUFFERS 16
+
+/* Number of buffers for use in the "fast" host interface */
+#define ICAN3_TX_BUFFERS 512
+#define ICAN3_RX_BUFFERS 1024
+
+/* SJA1000 Clock Input */
+#define ICAN3_CAN_CLOCK 8000000
+
+/* Driver Name */
+#define DRV_NAME "janz-ican3"
+
+/* DPM Control Registers -- starts at offset 0x100 in the MODULbus registers */
+struct ican3_dpm_control {
+ /* window address register */
+ u8 window_address;
+ u8 unused1;
+
+ /*
+ * Read access: clear interrupt from microcontroller
+ * Write access: send interrupt to microcontroller
+ */
+ u8 interrupt;
+ u8 unused2;
+
+ /* write-only: reset all hardware on the module */
+ u8 hwreset;
+ u8 unused3;
+
+ /* write-only: generate an interrupt to the TPU */
+ u8 tpuinterrupt;
+};
+
+struct ican3_dev {
+
+ /* must be the first member */
+ struct can_priv can;
+
+ /* CAN network device */
+ struct net_device *ndev;
+ struct napi_struct napi;
+
+ /* module number */
+ unsigned int num;
+
+ /* base address of registers and IRQ */
+ struct janz_cmodio_onboard_regs __iomem *ctrl;
+ struct ican3_dpm_control __iomem *dpmctrl;
+ void __iomem *dpm;
+ int irq;
+
+ /* CAN bus termination status */
+ struct completion termination_comp;
+ bool termination_enabled;
+
+ /* CAN bus error status registers */
+ struct completion buserror_comp;
+ struct can_berr_counter bec;
+
+ /* old and new style host interface */
+ unsigned int iftype;
+
+ /* queue for echo packets */
+ struct sk_buff_head echoq;
+
+ /*
+ * Any function which changes the current DPM page must hold this
+ * lock while it is performing data accesses. This ensures that the
+ * function will not be preempted and end up reading data from a
+ * different DPM page than it expects.
+ */
+ spinlock_t lock;
+
+ /* new host interface */
+ unsigned int rx_int;
+ unsigned int rx_num;
+ unsigned int tx_num;
+
+ /* fast host interface */
+ unsigned int fastrx_start;
+ unsigned int fastrx_num;
+ unsigned int fasttx_start;
+ unsigned int fasttx_num;
+
+ /* first free DPM page */
+ unsigned int free_page;
+};
+
+struct ican3_msg {
+ u8 control;
+ u8 spec;
+ __le16 len;
+ u8 data[252];
+};
+
+struct ican3_new_desc {
+ u8 control;
+ u8 pointer;
+};
+
+struct ican3_fast_desc {
+ u8 control;
+ u8 command;
+ u8 data[14];
+};
+
+/* write to the window basic address register */
+static inline void ican3_set_page(struct ican3_dev *mod, unsigned int page)
+{
+ BUG_ON(page >= DPM_NUM_PAGES);
+ iowrite8(page, &mod->dpmctrl->window_address);
+}
+
+/*
+ * ICAN3 "old-style" host interface
+ */
+
+/*
+ * Receive a message from the ICAN3 "old-style" firmware interface
+ *
+ * LOCKING: must hold mod->lock
+ *
+ * returns 0 on success, -ENOMEM when no message exists
+ */
+static int ican3_old_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ unsigned int mbox, mbox_page;
+ u8 locl, peer, xord;
+
+ /* get the MSYNC registers */
+ ican3_set_page(mod, QUEUE_OLD_CONTROL);
+ peer = ioread8(mod->dpm + MSYNC_PEER);
+ locl = ioread8(mod->dpm + MSYNC_LOCL);
+ xord = locl ^ peer;
+
+ if ((xord & MSYNC_RB_MASK) == 0x00) {
+ netdev_dbg(mod->ndev, "no mbox for reading\n");
+ return -ENOMEM;
+ }
+
+ /* find the first free mbox to read */
+ if ((xord & MSYNC_RB_MASK) == MSYNC_RB_MASK)
+ mbox = (xord & MSYNC_RBLW) ? MSYNC_RB0 : MSYNC_RB1;
+ else
+ mbox = (xord & MSYNC_RB0) ? MSYNC_RB0 : MSYNC_RB1;
+
+ /* copy the message */
+ mbox_page = (mbox == MSYNC_RB0) ? QUEUE_OLD_RB0 : QUEUE_OLD_RB1;
+ ican3_set_page(mod, mbox_page);
+ memcpy_fromio(msg, mod->dpm, sizeof(*msg));
+
+ /*
+ * notify the firmware that the read buffer is available
+ * for it to fill again
+ */
+ locl ^= mbox;
+
+ ican3_set_page(mod, QUEUE_OLD_CONTROL);
+ iowrite8(locl, mod->dpm + MSYNC_LOCL);
+ return 0;
+}
+
+/*
+ * Send a message through the "old-style" firmware interface
+ *
+ * LOCKING: must hold mod->lock
+ *
+ * returns 0 on success, -ENOMEM when no free space exists
+ */
+static int ican3_old_send_msg(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ unsigned int mbox, mbox_page;
+ u8 locl, peer, xord;
+
+ /* get the MSYNC registers */
+ ican3_set_page(mod, QUEUE_OLD_CONTROL);
+ peer = ioread8(mod->dpm + MSYNC_PEER);
+ locl = ioread8(mod->dpm + MSYNC_LOCL);
+ xord = locl ^ peer;
+
+ if ((xord & MSYNC_WB_MASK) == MSYNC_WB_MASK) {
+ netdev_err(mod->ndev, "no mbox for writing\n");
+ return -ENOMEM;
+ }
+
+ /* calculate a free mbox to use */
+ mbox = (xord & MSYNC_WB0) ? MSYNC_WB1 : MSYNC_WB0;
+
+ /* copy the message to the DPM */
+ mbox_page = (mbox == MSYNC_WB0) ? QUEUE_OLD_WB0 : QUEUE_OLD_WB1;
+ ican3_set_page(mod, mbox_page);
+ memcpy_toio(mod->dpm, msg, sizeof(*msg));
+
+ locl ^= mbox;
+ if (mbox == MSYNC_WB1)
+ locl |= MSYNC_WBLW;
+
+ ican3_set_page(mod, QUEUE_OLD_CONTROL);
+ iowrite8(locl, mod->dpm + MSYNC_LOCL);
+ return 0;
+}
+
+/*
+ * ICAN3 "new-style" Host Interface Setup
+ */
+
+static void ican3_init_new_host_interface(struct ican3_dev *mod)
+{
+ struct ican3_new_desc desc;
+ unsigned long flags;
+ void __iomem *dst;
+ int i;
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ /* setup the internal datastructures for RX */
+ mod->rx_num = 0;
+ mod->rx_int = 0;
+
+ /* tohost queue descriptors are in page 5 */
+ ican3_set_page(mod, QUEUE_TOHOST);
+ dst = mod->dpm;
+
+ /* initialize the tohost (rx) queue descriptors: pages 9-24 */
+ for (i = 0; i < ICAN3_NEW_BUFFERS; i++) {
+ desc.control = DESC_INTERRUPT | DESC_LEN(1); /* I L=1 */
+ desc.pointer = mod->free_page;
+
+ /* set wrap flag on last buffer */
+ if (i == ICAN3_NEW_BUFFERS - 1)
+ desc.control |= DESC_WRAP;
+
+ memcpy_toio(dst, &desc, sizeof(desc));
+ dst += sizeof(desc);
+ mod->free_page++;
+ }
+
+ /* fromhost (tx) mid queue descriptors are in page 6 */
+ ican3_set_page(mod, QUEUE_FROMHOST_MID);
+ dst = mod->dpm;
+
+ /* setup the internal datastructures for TX */
+ mod->tx_num = 0;
+
+ /* initialize the fromhost mid queue descriptors: pages 25-40 */
+ for (i = 0; i < ICAN3_NEW_BUFFERS; i++) {
+ desc.control = DESC_VALID | DESC_LEN(1); /* V L=1 */
+ desc.pointer = mod->free_page;
+
+ /* set wrap flag on last buffer */
+ if (i == ICAN3_NEW_BUFFERS - 1)
+ desc.control |= DESC_WRAP;
+
+ memcpy_toio(dst, &desc, sizeof(desc));
+ dst += sizeof(desc);
+ mod->free_page++;
+ }
+
+ /* fromhost hi queue descriptors are in page 7 */
+ ican3_set_page(mod, QUEUE_FROMHOST_HIGH);
+ dst = mod->dpm;
+
+ /* initialize only a single buffer in the fromhost hi queue (unused) */
+ desc.control = DESC_VALID | DESC_WRAP | DESC_LEN(1); /* VW L=1 */
+ desc.pointer = mod->free_page;
+ memcpy_toio(dst, &desc, sizeof(desc));
+ mod->free_page++;
+
+ /* fromhost low queue descriptors are in page 8 */
+ ican3_set_page(mod, QUEUE_FROMHOST_LOW);
+ dst = mod->dpm;
+
+ /* initialize only a single buffer in the fromhost low queue (unused) */
+ desc.control = DESC_VALID | DESC_WRAP | DESC_LEN(1); /* VW L=1 */
+ desc.pointer = mod->free_page;
+ memcpy_toio(dst, &desc, sizeof(desc));
+ mod->free_page++;
+
+ spin_unlock_irqrestore(&mod->lock, flags);
+}
+
+/*
+ * ICAN3 Fast Host Interface Setup
+ */
+
+static void ican3_init_fast_host_interface(struct ican3_dev *mod)
+{
+ struct ican3_fast_desc desc;
+ unsigned long flags;
+ unsigned int addr;
+ void __iomem *dst;
+ int i;
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ /* save the start recv page */
+ mod->fastrx_start = mod->free_page;
+ mod->fastrx_num = 0;
+
+ /* build a single fast tohost queue descriptor */
+ memset(&desc, 0, sizeof(desc));
+ desc.control = 0x00;
+ desc.command = 1;
+
+ /* build the tohost queue descriptor ring in memory */
+ addr = 0;
+ for (i = 0; i < ICAN3_RX_BUFFERS; i++) {
+
+ /* set the wrap bit on the last buffer */
+ if (i == ICAN3_RX_BUFFERS - 1)
+ desc.control |= DESC_WRAP;
+
+ /* switch to the correct page */
+ ican3_set_page(mod, mod->free_page);
+
+ /* copy the descriptor to the DPM */
+ dst = mod->dpm + addr;
+ memcpy_toio(dst, &desc, sizeof(desc));
+ addr += sizeof(desc);
+
+ /* move to the next page if necessary */
+ if (addr >= DPM_PAGE_SIZE) {
+ addr = 0;
+ mod->free_page++;
+ }
+ }
+
+ /* make sure we page-align the next queue */
+ if (addr != 0)
+ mod->free_page++;
+
+ /* save the start xmit page */
+ mod->fasttx_start = mod->free_page;
+ mod->fasttx_num = 0;
+
+ /* build a single fast fromhost queue descriptor */
+ memset(&desc, 0, sizeof(desc));
+ desc.control = DESC_VALID;
+ desc.command = 1;
+
+ /* build the fromhost queue descriptor ring in memory */
+ addr = 0;
+ for (i = 0; i < ICAN3_TX_BUFFERS; i++) {
+
+ /* set the wrap bit on the last buffer */
+ if (i == ICAN3_TX_BUFFERS - 1)
+ desc.control |= DESC_WRAP;
+
+ /* switch to the correct page */
+ ican3_set_page(mod, mod->free_page);
+
+ /* copy the descriptor to the DPM */
+ dst = mod->dpm + addr;
+ memcpy_toio(dst, &desc, sizeof(desc));
+ addr += sizeof(desc);
+
+ /* move to the next page if necessary */
+ if (addr >= DPM_PAGE_SIZE) {
+ addr = 0;
+ mod->free_page++;
+ }
+ }
+
+ spin_unlock_irqrestore(&mod->lock, flags);
+}
+
+/*
+ * ICAN3 "new-style" Host Interface Message Helpers
+ */
+
+/*
+ * LOCKING: must hold mod->lock
+ */
+static int ican3_new_send_msg(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ struct ican3_new_desc desc;
+ void __iomem *desc_addr = mod->dpm + (mod->tx_num * sizeof(desc));
+
+ /* switch to the fromhost mid queue, and read the buffer descriptor */
+ ican3_set_page(mod, QUEUE_FROMHOST_MID);
+ memcpy_fromio(&desc, desc_addr, sizeof(desc));
+
+ if (!(desc.control & DESC_VALID)) {
+ netdev_dbg(mod->ndev, "%s: no free buffers\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* switch to the data page, copy the data */
+ ican3_set_page(mod, desc.pointer);
+ memcpy_toio(mod->dpm, msg, sizeof(*msg));
+
+ /* switch back to the descriptor, set the valid bit, write it back */
+ ican3_set_page(mod, QUEUE_FROMHOST_MID);
+ desc.control ^= DESC_VALID;
+ memcpy_toio(desc_addr, &desc, sizeof(desc));
+
+ /* update the tx number */
+ mod->tx_num = (desc.control & DESC_WRAP) ? 0 : (mod->tx_num + 1);
+ return 0;
+}
+
+/*
+ * LOCKING: must hold mod->lock
+ */
+static int ican3_new_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ struct ican3_new_desc desc;
+ void __iomem *desc_addr = mod->dpm + (mod->rx_num * sizeof(desc));
+
+ /* switch to the tohost queue, and read the buffer descriptor */
+ ican3_set_page(mod, QUEUE_TOHOST);
+ memcpy_fromio(&desc, desc_addr, sizeof(desc));
+
+ if (!(desc.control & DESC_VALID)) {
+ netdev_dbg(mod->ndev, "%s: no buffers to recv\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* switch to the data page, copy the data */
+ ican3_set_page(mod, desc.pointer);
+ memcpy_fromio(msg, mod->dpm, sizeof(*msg));
+
+ /* switch back to the descriptor, toggle the valid bit, write it back */
+ ican3_set_page(mod, QUEUE_TOHOST);
+ desc.control ^= DESC_VALID;
+ memcpy_toio(desc_addr, &desc, sizeof(desc));
+
+ /* update the rx number */
+ mod->rx_num = (desc.control & DESC_WRAP) ? 0 : (mod->rx_num + 1);
+ return 0;
+}
+
+/*
+ * Message Send / Recv Helpers
+ */
+
+static int ican3_send_msg(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ if (mod->iftype == 0)
+ ret = ican3_old_send_msg(mod, msg);
+ else
+ ret = ican3_new_send_msg(mod, msg);
+
+ spin_unlock_irqrestore(&mod->lock, flags);
+ return ret;
+}
+
+static int ican3_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ if (mod->iftype == 0)
+ ret = ican3_old_recv_msg(mod, msg);
+ else
+ ret = ican3_new_recv_msg(mod, msg);
+
+ spin_unlock_irqrestore(&mod->lock, flags);
+ return ret;
+}
+
+/*
+ * Quick Pre-constructed Messages
+ */
+
+static int ican3_msg_connect(struct ican3_dev *mod)
+{
+ struct ican3_msg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_CONNECTI;
+ msg.len = cpu_to_le16(0);
+
+ return ican3_send_msg(mod, &msg);
+}
+
+static int ican3_msg_disconnect(struct ican3_dev *mod)
+{
+ struct ican3_msg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_DISCONNECT;
+ msg.len = cpu_to_le16(0);
+
+ return ican3_send_msg(mod, &msg);
+}
+
+static int ican3_msg_newhostif(struct ican3_dev *mod)
+{
+ struct ican3_msg msg;
+ int ret;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_NEWHOSTIF;
+ msg.len = cpu_to_le16(0);
+
+ /* If we're not using the old interface, switching seems bogus */
+ WARN_ON(mod->iftype != 0);
+
+ ret = ican3_send_msg(mod, &msg);
+ if (ret)
+ return ret;
+
+ /* mark the module as using the new host interface */
+ mod->iftype = 1;
+ return 0;
+}
+
+static int ican3_msg_fasthostif(struct ican3_dev *mod)
+{
+ struct ican3_msg msg;
+ unsigned int addr;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_INITFDPMQUEUE;
+ msg.len = cpu_to_le16(8);
+
+ /* write the tohost queue start address */
+ addr = DPM_PAGE_ADDR(mod->fastrx_start);
+ msg.data[0] = addr & 0xff;
+ msg.data[1] = (addr >> 8) & 0xff;
+ msg.data[2] = (addr >> 16) & 0xff;
+ msg.data[3] = (addr >> 24) & 0xff;
+
+ /* write the fromhost queue start address */
+ addr = DPM_PAGE_ADDR(mod->fasttx_start);
+ msg.data[4] = addr & 0xff;
+ msg.data[5] = (addr >> 8) & 0xff;
+ msg.data[6] = (addr >> 16) & 0xff;
+ msg.data[7] = (addr >> 24) & 0xff;
+
+ /* If we're not using the new interface yet, we cannot do this */
+ WARN_ON(mod->iftype != 1);
+
+ return ican3_send_msg(mod, &msg);
+}
+
+/*
+ * Setup the CAN filter to either accept or reject all
+ * messages from the CAN bus.
+ */
+static int ican3_set_id_filter(struct ican3_dev *mod, bool accept)
+{
+ struct ican3_msg msg;
+ int ret;
+
+ /* Standard Frame Format */
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_SETAFILMASK;
+ msg.len = cpu_to_le16(5);
+ msg.data[0] = 0x00; /* IDLo LSB */
+ msg.data[1] = 0x00; /* IDLo MSB */
+ msg.data[2] = 0xff; /* IDHi LSB */
+ msg.data[3] = 0x07; /* IDHi MSB */
+
+ /* accept all frames for fast host if, or reject all frames */
+ msg.data[4] = accept ? SETAFILMASK_FASTIF : SETAFILMASK_REJECT;
+
+ ret = ican3_send_msg(mod, &msg);
+ if (ret)
+ return ret;
+
+ /* Extended Frame Format */
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_SETAFILMASK;
+ msg.len = cpu_to_le16(13);
+ msg.data[0] = 0; /* MUX = 0 */
+ msg.data[1] = 0x00; /* IDLo LSB */
+ msg.data[2] = 0x00;
+ msg.data[3] = 0x00;
+ msg.data[4] = 0x20; /* IDLo MSB */
+ msg.data[5] = 0xff; /* IDHi LSB */
+ msg.data[6] = 0xff;
+ msg.data[7] = 0xff;
+ msg.data[8] = 0x3f; /* IDHi MSB */
+
+ /* accept all frames for fast host if, or reject all frames */
+ msg.data[9] = accept ? SETAFILMASK_FASTIF : SETAFILMASK_REJECT;
+
+ return ican3_send_msg(mod, &msg);
+}
+
+/*
+ * Bring the CAN bus online or offline
+ */
+static int ican3_set_bus_state(struct ican3_dev *mod, bool on)
+{
+ struct ican3_msg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = on ? MSG_CONREQ : MSG_COFFREQ;
+ msg.len = cpu_to_le16(0);
+
+ return ican3_send_msg(mod, &msg);
+}
+
+static int ican3_set_termination(struct ican3_dev *mod, bool on)
+{
+ struct ican3_msg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_HWCONF;
+ msg.len = cpu_to_le16(2);
+ msg.data[0] = 0x00;
+ msg.data[1] = on ? HWCONF_TERMINATE_ON : HWCONF_TERMINATE_OFF;
+
+ return ican3_send_msg(mod, &msg);
+}
+
+static int ican3_send_inquiry(struct ican3_dev *mod, u8 subspec)
+{
+ struct ican3_msg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_INQUIRY;
+ msg.len = cpu_to_le16(2);
+ msg.data[0] = subspec;
+ msg.data[1] = 0x00;
+
+ return ican3_send_msg(mod, &msg);
+}
+
+static int ican3_set_buserror(struct ican3_dev *mod, u8 quota)
+{
+ struct ican3_msg msg;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_CCONFREQ;
+ msg.len = cpu_to_le16(2);
+ msg.data[0] = 0x00;
+ msg.data[1] = quota;
+
+ return ican3_send_msg(mod, &msg);
+}
+
+/*
+ * ICAN3 to Linux CAN Frame Conversion
+ */
+
+static void ican3_to_can_frame(struct ican3_dev *mod,
+ struct ican3_fast_desc *desc,
+ struct can_frame *cf)
+{
+ if ((desc->command & ICAN3_CAN_TYPE_MASK) == ICAN3_CAN_TYPE_SFF) {
+ if (desc->data[1] & ICAN3_SFF_RTR)
+ cf->can_id |= CAN_RTR_FLAG;
+
+ cf->can_id |= desc->data[0] << 3;
+ cf->can_id |= (desc->data[1] & 0xe0) >> 5;
+ cf->can_dlc = get_can_dlc(desc->data[1] & ICAN3_CAN_DLC_MASK);
+ memcpy(cf->data, &desc->data[2], cf->can_dlc);
+ } else {
+ cf->can_dlc = get_can_dlc(desc->data[0] & ICAN3_CAN_DLC_MASK);
+ if (desc->data[0] & ICAN3_EFF_RTR)
+ cf->can_id |= CAN_RTR_FLAG;
+
+ if (desc->data[0] & ICAN3_EFF) {
+ cf->can_id |= CAN_EFF_FLAG;
+ cf->can_id |= desc->data[2] << 21; /* 28-21 */
+ cf->can_id |= desc->data[3] << 13; /* 20-13 */
+ cf->can_id |= desc->data[4] << 5; /* 12-5 */
+ cf->can_id |= (desc->data[5] & 0xf8) >> 3;
+ } else {
+ cf->can_id |= desc->data[2] << 3; /* 10-3 */
+ cf->can_id |= desc->data[3] >> 5; /* 2-0 */
+ }
+
+ memcpy(cf->data, &desc->data[6], cf->can_dlc);
+ }
+}
+
+static void can_frame_to_ican3(struct ican3_dev *mod,
+ struct can_frame *cf,
+ struct ican3_fast_desc *desc)
+{
+ /* clear out any stale data in the descriptor */
+ memset(desc->data, 0, sizeof(desc->data));
+
+ /* we always use the extended format, with the ECHO flag set */
+ desc->command = ICAN3_CAN_TYPE_EFF;
+ desc->data[0] |= cf->can_dlc;
+ desc->data[1] |= ICAN3_ECHO;
+
+ /* support single transmission (no retries) mode */
+ if (mod->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+ desc->data[1] |= ICAN3_SNGL;
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ desc->data[0] |= ICAN3_EFF_RTR;
+
+ /* pack the id into the correct places */
+ if (cf->can_id & CAN_EFF_FLAG) {
+ desc->data[0] |= ICAN3_EFF;
+ desc->data[2] = (cf->can_id & 0x1fe00000) >> 21; /* 28-21 */
+ desc->data[3] = (cf->can_id & 0x001fe000) >> 13; /* 20-13 */
+ desc->data[4] = (cf->can_id & 0x00001fe0) >> 5; /* 12-5 */
+ desc->data[5] = (cf->can_id & 0x0000001f) << 3; /* 4-0 */
+ } else {
+ desc->data[2] = (cf->can_id & 0x7F8) >> 3; /* bits 10-3 */
+ desc->data[3] = (cf->can_id & 0x007) << 5; /* bits 2-0 */
+ }
+
+ /* copy the data bits into the descriptor */
+ memcpy(&desc->data[6], cf->data, cf->can_dlc);
+}
+
+/*
+ * Interrupt Handling
+ */
+
+/*
+ * Handle an ID + Version message response from the firmware. We never generate
+ * this message in production code, but it is very useful when debugging to be
+ * able to display this message.
+ */
+static void ican3_handle_idvers(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ netdev_dbg(mod->ndev, "IDVERS response: %s\n", msg->data);
+}
+
+static void ican3_handle_msglost(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ struct net_device *dev = mod->ndev;
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+
+ /*
+ * Report that communication messages with the microcontroller firmware
+ * are being lost. These are never CAN frames, so we do not generate an
+ * error frame for userspace
+ */
+ if (msg->spec == MSG_MSGLOST) {
+ netdev_err(mod->ndev, "lost %d control messages\n", msg->data[0]);
+ return;
+ }
+
+ /*
+ * Oops, this indicates that we have lost messages in the fast queue,
+ * which are exclusively CAN messages. Our driver isn't reading CAN
+ * frames fast enough.
+ *
+ * We'll pretend that the SJA1000 told us that it ran out of buffer
+ * space, because there is not a better message for this.
+ */
+ skb = alloc_can_err_skb(dev, &cf);
+ if (skb) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ netif_rx(skb);
+ }
+}
+
+/*
+ * Handle CAN Event Indication Messages from the firmware
+ *
+ * The ICAN3 firmware provides the values of some SJA1000 registers when it
+ * generates this message. The code below is largely copied from the
+ * drivers/net/can/sja1000/sja1000.c file, and adapted as necessary
+ */
+static int ican3_handle_cevtind(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ struct net_device *dev = mod->ndev;
+ struct net_device_stats *stats = &dev->stats;
+ enum can_state state = mod->can.state;
+ u8 isrc, ecc, status, rxerr, txerr;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+
+ /* we can only handle the SJA1000 part */
+ if (msg->data[1] != CEVTIND_CHIP_SJA1000) {
+ netdev_err(mod->ndev, "unable to handle errors on non-SJA1000\n");
+ return -ENODEV;
+ }
+
+ /* check the message length for sanity */
+ if (le16_to_cpu(msg->len) < 6) {
+ netdev_err(mod->ndev, "error message too short\n");
+ return -EINVAL;
+ }
+
+ isrc = msg->data[0];
+ ecc = msg->data[2];
+ status = msg->data[3];
+ rxerr = msg->data[4];
+ txerr = msg->data[5];
+
+ /*
+ * This hardware lacks any support other than bus error messages to
+ * determine if packet transmission has failed.
+ *
+ * When TX errors happen, one echo skb needs to be dropped from the
+ * front of the queue.
+ *
+ * A small bit of code is duplicated here and below, to avoid error
+ * skb allocation when it will just be freed immediately.
+ */
+ if (isrc == CEVTIND_BEI) {
+ int ret;
+ netdev_dbg(mod->ndev, "bus error interrupt\n");
+
+ /* TX error */
+ if (!(ecc & ECC_DIR)) {
+ kfree_skb(skb_dequeue(&mod->echoq));
+ stats->tx_errors++;
+ } else {
+ stats->rx_errors++;
+ }
+
+ /*
+ * The controller automatically disables bus-error interrupts
+ * and therefore we must re-enable them.
+ */
+ ret = ican3_set_buserror(mod, 1);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to re-enable bus-error\n");
+ return ret;
+ }
+
+ /* bus error reporting is off, return immediately */
+ if (!(mod->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
+ return 0;
+ }
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (skb == NULL)
+ return -ENOMEM;
+
+ /* data overrun interrupt */
+ if (isrc == CEVTIND_DOI || isrc == CEVTIND_LOST) {
+ netdev_dbg(mod->ndev, "data overrun interrupt\n");
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ }
+
+ /* error warning + passive interrupt */
+ if (isrc == CEVTIND_EI) {
+ netdev_dbg(mod->ndev, "error warning + passive interrupt\n");
+ if (status & SR_BS) {
+ state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(dev);
+ } else if (status & SR_ES) {
+ if (rxerr >= 128 || txerr >= 128)
+ state = CAN_STATE_ERROR_PASSIVE;
+ else
+ state = CAN_STATE_ERROR_WARNING;
+ } else {
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
+ }
+
+ /* bus error interrupt */
+ if (isrc == CEVTIND_BEI) {
+ mod->can.can_stats.bus_error++;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (ecc & ECC_MASK) {
+ case ECC_BIT:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ break;
+ case ECC_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case ECC_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ default:
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ cf->data[3] = ecc & ECC_SEG;
+ break;
+ }
+
+ if (!(ecc & ECC_DIR))
+ cf->data[2] |= CAN_ERR_PROT_TX;
+
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+
+ if (state != mod->can.state && (state == CAN_STATE_ERROR_WARNING ||
+ state == CAN_STATE_ERROR_PASSIVE)) {
+ cf->can_id |= CAN_ERR_CRTL;
+ if (state == CAN_STATE_ERROR_WARNING) {
+ mod->can.can_stats.error_warning++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ } else {
+ mod->can.can_stats.error_passive++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+
+ mod->can.state = state;
+ netif_rx(skb);
+ return 0;
+}
+
+static void ican3_handle_inquiry(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ switch (msg->data[0]) {
+ case INQUIRY_STATUS:
+ case INQUIRY_EXTENDED:
+ mod->bec.rxerr = msg->data[5];
+ mod->bec.txerr = msg->data[6];
+ complete(&mod->buserror_comp);
+ break;
+ case INQUIRY_TERMINATION:
+ mod->termination_enabled = msg->data[6] & HWCONF_TERMINATE_ON;
+ complete(&mod->termination_comp);
+ break;
+ default:
+ netdev_err(mod->ndev, "received an unknown inquiry response\n");
+ break;
+ }
+}
+
+static void ican3_handle_unknown_message(struct ican3_dev *mod,
+ struct ican3_msg *msg)
+{
+ netdev_warn(mod->ndev, "received unknown message: spec 0x%.2x length %d\n",
+ msg->spec, le16_to_cpu(msg->len));
+}
+
+/*
+ * Handle a control message from the firmware
+ */
+static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg)
+{
+ netdev_dbg(mod->ndev, "%s: modno %d spec 0x%.2x len %d bytes\n", __func__,
+ mod->num, msg->spec, le16_to_cpu(msg->len));
+
+ switch (msg->spec) {
+ case MSG_IDVERS:
+ ican3_handle_idvers(mod, msg);
+ break;
+ case MSG_MSGLOST:
+ case MSG_FMSGLOST:
+ ican3_handle_msglost(mod, msg);
+ break;
+ case MSG_CEVTIND:
+ ican3_handle_cevtind(mod, msg);
+ break;
+ case MSG_INQUIRY:
+ ican3_handle_inquiry(mod, msg);
+ break;
+ default:
+ ican3_handle_unknown_message(mod, msg);
+ break;
+ }
+}
+
+/*
+ * The ican3 needs to store all echo skbs, and therefore cannot
+ * use the generic infrastructure for this.
+ */
+static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb)
+{
+ skb = can_create_echo_skb(skb);
+ if (!skb)
+ return;
+
+ /* save this skb for tx interrupt echo handling */
+ skb_queue_tail(&mod->echoq, skb);
+}
+
+static unsigned int ican3_get_echo_skb(struct ican3_dev *mod)
+{
+ struct sk_buff *skb = skb_dequeue(&mod->echoq);
+ struct can_frame *cf;
+ u8 dlc;
+
+ /* this should never trigger unless there is a driver bug */
+ if (!skb) {
+ netdev_err(mod->ndev, "BUG: echo skb not occupied\n");
+ return 0;
+ }
+
+ cf = (struct can_frame *)skb->data;
+ dlc = cf->can_dlc;
+
+ /* check flag whether this packet has to be looped back */
+ if (skb->pkt_type != PACKET_LOOPBACK) {
+ kfree_skb(skb);
+ return dlc;
+ }
+
+ skb->protocol = htons(ETH_P_CAN);
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->dev = mod->ndev;
+ netif_receive_skb(skb);
+ return dlc;
+}
+
+/*
+ * Compare an skb with an existing echo skb
+ *
+ * This function will be used on devices which have a hardware loopback.
+ * On these devices, this function can be used to compare a received skb
+ * with the saved echo skbs so that the hardware echo skb can be dropped.
+ *
+ * Returns true if the skb's are identical, false otherwise.
+ */
+static bool ican3_echo_skb_matches(struct ican3_dev *mod, struct sk_buff *skb)
+{
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ struct sk_buff *echo_skb = skb_peek(&mod->echoq);
+ struct can_frame *echo_cf;
+
+ if (!echo_skb)
+ return false;
+
+ echo_cf = (struct can_frame *)echo_skb->data;
+ if (cf->can_id != echo_cf->can_id)
+ return false;
+
+ if (cf->can_dlc != echo_cf->can_dlc)
+ return false;
+
+ return memcmp(cf->data, echo_cf->data, cf->can_dlc) == 0;
+}
+
+/*
+ * Check that there is room in the TX ring to transmit another skb
+ *
+ * LOCKING: must hold mod->lock
+ */
+static bool ican3_txok(struct ican3_dev *mod)
+{
+ struct ican3_fast_desc __iomem *desc;
+ u8 control;
+
+ /* check that we have echo queue space */
+ if (skb_queue_len(&mod->echoq) >= ICAN3_TX_BUFFERS)
+ return false;
+
+ /* copy the control bits of the descriptor */
+ ican3_set_page(mod, mod->fasttx_start + (mod->fasttx_num / 16));
+ desc = mod->dpm + ((mod->fasttx_num % 16) * sizeof(*desc));
+ control = ioread8(&desc->control);
+
+ /* if the control bits are not valid, then we have no more space */
+ if (!(control & DESC_VALID))
+ return false;
+
+ return true;
+}
+
+/*
+ * Receive one CAN frame from the hardware
+ *
+ * CONTEXT: must be called from user context
+ */
+static int ican3_recv_skb(struct ican3_dev *mod)
+{
+ struct net_device *ndev = mod->ndev;
+ struct net_device_stats *stats = &ndev->stats;
+ struct ican3_fast_desc desc;
+ void __iomem *desc_addr;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ /* copy the whole descriptor */
+ ican3_set_page(mod, mod->fastrx_start + (mod->fastrx_num / 16));
+ desc_addr = mod->dpm + ((mod->fastrx_num % 16) * sizeof(desc));
+ memcpy_fromio(&desc, desc_addr, sizeof(desc));
+
+ spin_unlock_irqrestore(&mod->lock, flags);
+
+ /* check that we actually have a CAN frame */
+ if (!(desc.control & DESC_VALID))
+ return -ENOBUFS;
+
+ /* allocate an skb */
+ skb = alloc_can_skb(ndev, &cf);
+ if (unlikely(skb == NULL)) {
+ stats->rx_dropped++;
+ goto err_noalloc;
+ }
+
+ /* convert the ICAN3 frame into Linux CAN format */
+ ican3_to_can_frame(mod, &desc, cf);
+
+ /*
+ * If this is an ECHO frame received from the hardware loopback
+ * feature, use the skb saved in the ECHO stack instead. This allows
+ * the Linux CAN core to support CAN_RAW_RECV_OWN_MSGS correctly.
+ *
+ * Since this is a confirmation of a successfully transmitted packet
+ * sent from this host, update the transmit statistics.
+ *
+ * Also, the netdevice queue needs to be allowed to send packets again.
+ */
+ if (ican3_echo_skb_matches(mod, skb)) {
+ stats->tx_packets++;
+ stats->tx_bytes += ican3_get_echo_skb(mod);
+ kfree_skb(skb);
+ goto err_noalloc;
+ }
+
+ /* update statistics, receive the skb */
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ netif_receive_skb(skb);
+
+err_noalloc:
+ /* toggle the valid bit and return the descriptor to the ring */
+ desc.control ^= DESC_VALID;
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ ican3_set_page(mod, mod->fastrx_start + (mod->fastrx_num / 16));
+ memcpy_toio(desc_addr, &desc, 1);
+
+ /* update the next buffer pointer */
+ mod->fastrx_num = (desc.control & DESC_WRAP) ? 0
+ : (mod->fastrx_num + 1);
+
+ /* there are still more buffers to process */
+ spin_unlock_irqrestore(&mod->lock, flags);
+ return 0;
+}
+
+static int ican3_napi(struct napi_struct *napi, int budget)
+{
+ struct ican3_dev *mod = container_of(napi, struct ican3_dev, napi);
+ unsigned long flags;
+ int received = 0;
+ int ret;
+
+ /* process all communication messages */
+ while (true) {
+ struct ican3_msg uninitialized_var(msg);
+ ret = ican3_recv_msg(mod, &msg);
+ if (ret)
+ break;
+
+ ican3_handle_message(mod, &msg);
+ }
+
+ /* process all CAN frames from the fast interface */
+ while (received < budget) {
+ ret = ican3_recv_skb(mod);
+ if (ret)
+ break;
+
+ received++;
+ }
+
+ /* We have processed all packets that the adapter had, but it
+ * was less than our budget, stop polling */
+ if (received < budget)
+ napi_complete(napi);
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ /* Wake up the transmit queue if necessary */
+ if (netif_queue_stopped(mod->ndev) && ican3_txok(mod))
+ netif_wake_queue(mod->ndev);
+
+ spin_unlock_irqrestore(&mod->lock, flags);
+
+ /* re-enable interrupt generation */
+ iowrite8(1 << mod->num, &mod->ctrl->int_enable);
+ return received;
+}
+
+static irqreturn_t ican3_irq(int irq, void *dev_id)
+{
+ struct ican3_dev *mod = dev_id;
+ u8 stat;
+
+ /*
+ * The interrupt status register on this device reports interrupts
+ * as zeroes instead of using ones like most other devices
+ */
+ stat = ioread8(&mod->ctrl->int_disable) & (1 << mod->num);
+ if (stat == (1 << mod->num))
+ return IRQ_NONE;
+
+ /* clear the MODULbus interrupt from the microcontroller */
+ ioread8(&mod->dpmctrl->interrupt);
+
+ /* disable interrupt generation, schedule the NAPI poller */
+ iowrite8(1 << mod->num, &mod->ctrl->int_disable);
+ napi_schedule(&mod->napi);
+ return IRQ_HANDLED;
+}
+
+/*
+ * Firmware reset, startup, and shutdown
+ */
+
+/*
+ * Reset an ICAN module to its power-on state
+ *
+ * CONTEXT: no network device registered
+ */
+static int ican3_reset_module(struct ican3_dev *mod)
+{
+ unsigned long start;
+ u8 runold, runnew;
+
+ /* disable interrupts so no more work is scheduled */
+ iowrite8(1 << mod->num, &mod->ctrl->int_disable);
+
+ /* the first unallocated page in the DPM is #9 */
+ mod->free_page = DPM_FREE_START;
+
+ ican3_set_page(mod, QUEUE_OLD_CONTROL);
+ runold = ioread8(mod->dpm + TARGET_RUNNING);
+
+ /* reset the module */
+ iowrite8(0x00, &mod->dpmctrl->hwreset);
+
+ /* wait until the module has finished resetting and is running */
+ start = jiffies;
+ do {
+ ican3_set_page(mod, QUEUE_OLD_CONTROL);
+ runnew = ioread8(mod->dpm + TARGET_RUNNING);
+ if (runnew == (runold ^ 0xff))
+ return 0;
+
+ msleep(10);
+ } while (time_before(jiffies, start + HZ / 4));
+
+ netdev_err(mod->ndev, "failed to reset CAN module\n");
+ return -ETIMEDOUT;
+}
+
+static void ican3_shutdown_module(struct ican3_dev *mod)
+{
+ ican3_msg_disconnect(mod);
+ ican3_reset_module(mod);
+}
+
+/*
+ * Startup an ICAN module, bringing it into fast mode
+ */
+static int ican3_startup_module(struct ican3_dev *mod)
+{
+ int ret;
+
+ ret = ican3_reset_module(mod);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to reset module\n");
+ return ret;
+ }
+
+ /* re-enable interrupts so we can send messages */
+ iowrite8(1 << mod->num, &mod->ctrl->int_enable);
+
+ ret = ican3_msg_connect(mod);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to connect to module\n");
+ return ret;
+ }
+
+ ican3_init_new_host_interface(mod);
+ ret = ican3_msg_newhostif(mod);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to switch to new-style interface\n");
+ return ret;
+ }
+
+ /* default to "termination on" */
+ ret = ican3_set_termination(mod, true);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to enable termination\n");
+ return ret;
+ }
+
+ /* default to "bus errors enabled" */
+ ret = ican3_set_buserror(mod, 1);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to set bus-error\n");
+ return ret;
+ }
+
+ ican3_init_fast_host_interface(mod);
+ ret = ican3_msg_fasthostif(mod);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to switch to fast host interface\n");
+ return ret;
+ }
+
+ ret = ican3_set_id_filter(mod, true);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to set acceptance filter\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * CAN Network Device
+ */
+
+static int ican3_open(struct net_device *ndev)
+{
+ struct ican3_dev *mod = netdev_priv(ndev);
+ int ret;
+
+ /* open the CAN layer */
+ ret = open_candev(ndev);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to start CAN layer\n");
+ return ret;
+ }
+
+ /* bring the bus online */
+ ret = ican3_set_bus_state(mod, true);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to set bus-on\n");
+ close_candev(ndev);
+ return ret;
+ }
+
+ /* start up the network device */
+ mod->can.state = CAN_STATE_ERROR_ACTIVE;
+ netif_start_queue(ndev);
+
+ return 0;
+}
+
+static int ican3_stop(struct net_device *ndev)
+{
+ struct ican3_dev *mod = netdev_priv(ndev);
+ int ret;
+
+ /* stop the network device xmit routine */
+ netif_stop_queue(ndev);
+ mod->can.state = CAN_STATE_STOPPED;
+
+ /* bring the bus offline, stop receiving packets */
+ ret = ican3_set_bus_state(mod, false);
+ if (ret) {
+ netdev_err(mod->ndev, "unable to set bus-off\n");
+ return ret;
+ }
+
+ /* drop all outstanding echo skbs */
+ skb_queue_purge(&mod->echoq);
+
+ /* close the CAN layer */
+ close_candev(ndev);
+ return 0;
+}
+
+static int ican3_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct ican3_dev *mod = netdev_priv(ndev);
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ struct ican3_fast_desc desc;
+ void __iomem *desc_addr;
+ unsigned long flags;
+
+ if (can_dropped_invalid_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ spin_lock_irqsave(&mod->lock, flags);
+
+ /* check that we can actually transmit */
+ if (!ican3_txok(mod)) {
+ netdev_err(mod->ndev, "BUG: no free descriptors\n");
+ spin_unlock_irqrestore(&mod->lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+ /* copy the control bits of the descriptor */
+ ican3_set_page(mod, mod->fasttx_start + (mod->fasttx_num / 16));
+ desc_addr = mod->dpm + ((mod->fasttx_num % 16) * sizeof(desc));
+ memset(&desc, 0, sizeof(desc));
+ memcpy_fromio(&desc, desc_addr, 1);
+
+ /* convert the Linux CAN frame into ICAN3 format */
+ can_frame_to_ican3(mod, cf, &desc);
+
+ /*
+ * This hardware doesn't have TX-done notifications, so we'll try and
+ * emulate it the best we can using ECHO skbs. Add the skb to the ECHO
+ * stack. Upon packet reception, check if the ECHO skb and received
+ * skb match, and use that to wake the queue.
+ */
+ ican3_put_echo_skb(mod, skb);
+
+ /*
+ * the programming manual says that you must set the IVALID bit, then
+ * interrupt, then set the valid bit. Quite weird, but it seems to be
+ * required for this to work
+ */
+ desc.control |= DESC_IVALID;
+ memcpy_toio(desc_addr, &desc, sizeof(desc));
+
+ /* generate a MODULbus interrupt to the microcontroller */
+ iowrite8(0x01, &mod->dpmctrl->interrupt);
+
+ desc.control ^= DESC_VALID;
+ memcpy_toio(desc_addr, &desc, sizeof(desc));
+
+ /* update the next buffer pointer */
+ mod->fasttx_num = (desc.control & DESC_WRAP) ? 0
+ : (mod->fasttx_num + 1);
+
+ /* if there is no free descriptor space, stop the transmit queue */
+ if (!ican3_txok(mod))
+ netif_stop_queue(ndev);
+
+ spin_unlock_irqrestore(&mod->lock, flags);
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops ican3_netdev_ops = {
+ .ndo_open = ican3_open,
+ .ndo_stop = ican3_stop,
+ .ndo_start_xmit = ican3_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+/*
+ * Low-level CAN Device
+ */
+
+/* This structure was stolen from drivers/net/can/sja1000/sja1000.c */
+static const struct can_bittiming_const ican3_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+};
+
+/*
+ * This routine was stolen from drivers/net/can/sja1000/sja1000.c
+ *
+ * The bittiming register command for the ICAN3 just sets the bit timing
+ * registers on the SJA1000 chip directly
+ */
+static int ican3_set_bittiming(struct net_device *ndev)
+{
+ struct ican3_dev *mod = netdev_priv(ndev);
+ struct can_bittiming *bt = &mod->can.bittiming;
+ struct ican3_msg msg;
+ u8 btr0, btr1;
+
+ btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+ btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+ (((bt->phase_seg2 - 1) & 0x7) << 4);
+ if (mod->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ btr1 |= 0x80;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.spec = MSG_CBTRREQ;
+ msg.len = cpu_to_le16(4);
+ msg.data[0] = 0x00;
+ msg.data[1] = 0x00;
+ msg.data[2] = btr0;
+ msg.data[3] = btr1;
+
+ return ican3_send_msg(mod, &msg);
+}
+
+static int ican3_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ struct ican3_dev *mod = netdev_priv(ndev);
+ int ret;
+
+ if (mode != CAN_MODE_START)
+ return -ENOTSUPP;
+
+ /* bring the bus online */
+ ret = ican3_set_bus_state(mod, true);
+ if (ret) {
+ netdev_err(ndev, "unable to set bus-on\n");
+ return ret;
+ }
+
+ /* start up the network device */
+ mod->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_queue_stopped(ndev))
+ netif_wake_queue(ndev);
+
+ return 0;
+}
+
+static int ican3_get_berr_counter(const struct net_device *ndev,
+ struct can_berr_counter *bec)
+{
+ struct ican3_dev *mod = netdev_priv(ndev);
+ int ret;
+
+ ret = ican3_send_inquiry(mod, INQUIRY_STATUS);
+ if (ret)
+ return ret;
+
+ ret = wait_for_completion_timeout(&mod->buserror_comp, HZ);
+ if (ret == 0) {
+ netdev_info(mod->ndev, "%s timed out\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ bec->rxerr = mod->bec.rxerr;
+ bec->txerr = mod->bec.txerr;
+ return 0;
+}
+
+/*
+ * Sysfs Attributes
+ */
+
+static ssize_t ican3_sysfs_show_term(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct ican3_dev *mod = netdev_priv(to_net_dev(dev));
+ int ret;
+
+ ret = ican3_send_inquiry(mod, INQUIRY_TERMINATION);
+ if (ret)
+ return ret;
+
+ ret = wait_for_completion_timeout(&mod->termination_comp, HZ);
+ if (ret == 0) {
+ netdev_info(mod->ndev, "%s timed out\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", mod->termination_enabled);
+}
+
+static ssize_t ican3_sysfs_set_term(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ican3_dev *mod = netdev_priv(to_net_dev(dev));
+ unsigned long enable;
+ int ret;
+
+ if (kstrtoul(buf, 0, &enable))
+ return -EINVAL;
+
+ ret = ican3_set_termination(mod, enable);
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term,
+ ican3_sysfs_set_term);
+
+static struct attribute *ican3_sysfs_attrs[] = {
+ &dev_attr_termination.attr,
+ NULL,
+};
+
+static struct attribute_group ican3_sysfs_attr_group = {
+ .attrs = ican3_sysfs_attrs,
+};
+
+/*
+ * PCI Subsystem
+ */
+
+static int ican3_probe(struct platform_device *pdev)
+{
+ struct janz_platform_data *pdata;
+ struct net_device *ndev;
+ struct ican3_dev *mod;
+ struct resource *res;
+ struct device *dev;
+ int ret;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata)
+ return -ENXIO;
+
+ dev_dbg(&pdev->dev, "probe: module number %d\n", pdata->modno);
+
+ /* save the struct device for printing */
+ dev = &pdev->dev;
+
+ /* allocate the CAN device and private data */
+ ndev = alloc_candev(sizeof(*mod), 0);
+ if (!ndev) {
+ dev_err(dev, "unable to allocate CANdev\n");
+ ret = -ENOMEM;
+ goto out_return;
+ }
+
+ platform_set_drvdata(pdev, ndev);
+ mod = netdev_priv(ndev);
+ mod->ndev = ndev;
+ mod->num = pdata->modno;
+ netif_napi_add(ndev, &mod->napi, ican3_napi, ICAN3_RX_BUFFERS);
+ skb_queue_head_init(&mod->echoq);
+ spin_lock_init(&mod->lock);
+ init_completion(&mod->termination_comp);
+ init_completion(&mod->buserror_comp);
+
+ /* setup device-specific sysfs attributes */
+ ndev->sysfs_groups[0] = &ican3_sysfs_attr_group;
+
+ /* the first unallocated page in the DPM is 9 */
+ mod->free_page = DPM_FREE_START;
+
+ ndev->netdev_ops = &ican3_netdev_ops;
+ ndev->flags |= IFF_ECHO;
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ mod->can.clock.freq = ICAN3_CAN_CLOCK;
+ mod->can.bittiming_const = &ican3_bittiming_const;
+ mod->can.do_set_bittiming = ican3_set_bittiming;
+ mod->can.do_set_mode = ican3_set_mode;
+ mod->can.do_get_berr_counter = ican3_get_berr_counter;
+ mod->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES
+ | CAN_CTRLMODE_BERR_REPORTING
+ | CAN_CTRLMODE_ONE_SHOT;
+
+ /* find our IRQ number */
+ mod->irq = platform_get_irq(pdev, 0);
+ if (mod->irq < 0) {
+ dev_err(dev, "IRQ line not found\n");
+ ret = -ENODEV;
+ goto out_free_ndev;
+ }
+
+ ndev->irq = mod->irq;
+
+ /* get access to the MODULbus registers for this module */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "MODULbus registers not found\n");
+ ret = -ENODEV;
+ goto out_free_ndev;
+ }
+
+ mod->dpm = ioremap(res->start, resource_size(res));
+ if (!mod->dpm) {
+ dev_err(dev, "MODULbus registers not ioremap\n");
+ ret = -ENOMEM;
+ goto out_free_ndev;
+ }
+
+ mod->dpmctrl = mod->dpm + DPM_PAGE_SIZE;
+
+ /* get access to the control registers for this module */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(dev, "CONTROL registers not found\n");
+ ret = -ENODEV;
+ goto out_iounmap_dpm;
+ }
+
+ mod->ctrl = ioremap(res->start, resource_size(res));
+ if (!mod->ctrl) {
+ dev_err(dev, "CONTROL registers not ioremap\n");
+ ret = -ENOMEM;
+ goto out_iounmap_dpm;
+ }
+
+ /* disable our IRQ, then hookup the IRQ handler */
+ iowrite8(1 << mod->num, &mod->ctrl->int_disable);
+ ret = request_irq(mod->irq, ican3_irq, IRQF_SHARED, DRV_NAME, mod);
+ if (ret) {
+ dev_err(dev, "unable to request IRQ\n");
+ goto out_iounmap_ctrl;
+ }
+
+ /* reset and initialize the CAN controller into fast mode */
+ napi_enable(&mod->napi);
+ ret = ican3_startup_module(mod);
+ if (ret) {
+ dev_err(dev, "%s: unable to start CANdev\n", __func__);
+ goto out_free_irq;
+ }
+
+ /* register with the Linux CAN layer */
+ ret = register_candev(ndev);
+ if (ret) {
+ dev_err(dev, "%s: unable to register CANdev\n", __func__);
+ goto out_free_irq;
+ }
+
+ dev_info(dev, "module %d: registered CAN device\n", pdata->modno);
+ return 0;
+
+out_free_irq:
+ napi_disable(&mod->napi);
+ iowrite8(1 << mod->num, &mod->ctrl->int_disable);
+ free_irq(mod->irq, mod);
+out_iounmap_ctrl:
+ iounmap(mod->ctrl);
+out_iounmap_dpm:
+ iounmap(mod->dpm);
+out_free_ndev:
+ free_candev(ndev);
+out_return:
+ return ret;
+}
+
+static int ican3_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ican3_dev *mod = netdev_priv(ndev);
+
+ /* unregister the netdevice, stop interrupts */
+ unregister_netdev(ndev);
+ napi_disable(&mod->napi);
+ iowrite8(1 << mod->num, &mod->ctrl->int_disable);
+ free_irq(mod->irq, mod);
+
+ /* put the module into reset */
+ ican3_shutdown_module(mod);
+
+ /* unmap all registers */
+ iounmap(mod->ctrl);
+ iounmap(mod->dpm);
+
+ free_candev(ndev);
+
+ return 0;
+}
+
+static struct platform_driver ican3_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ican3_probe,
+ .remove = ican3_remove,
+};
+
+module_platform_driver(ican3_driver);
+
+MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
+MODULE_DESCRIPTION("Janz MODULbus VMOD-ICAN3 Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:janz-ican3");
diff --git a/drivers/net/can/led.c b/drivers/net/can/led.c
new file mode 100644
index 00000000000..ab7f1b01be4
--- /dev/null
+++ b/drivers/net/can/led.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com>
+ * Copyright 2012, Kurt Van Dijck <kurt.van.dijck@eia.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/can/dev.h>
+
+#include <linux/can/led.h>
+
+static unsigned long led_delay = 50;
+module_param(led_delay, ulong, 0644);
+MODULE_PARM_DESC(led_delay,
+ "blink delay time for activity leds (msecs, default: 50).");
+
+/* Trigger a LED event in response to a CAN device event */
+void can_led_event(struct net_device *netdev, enum can_led_event event)
+{
+ struct can_priv *priv = netdev_priv(netdev);
+
+ switch (event) {
+ case CAN_LED_EVENT_OPEN:
+ led_trigger_event(priv->tx_led_trig, LED_FULL);
+ led_trigger_event(priv->rx_led_trig, LED_FULL);
+ break;
+ case CAN_LED_EVENT_STOP:
+ led_trigger_event(priv->tx_led_trig, LED_OFF);
+ led_trigger_event(priv->rx_led_trig, LED_OFF);
+ break;
+ case CAN_LED_EVENT_TX:
+ if (led_delay)
+ led_trigger_blink_oneshot(priv->tx_led_trig,
+ &led_delay, &led_delay, 1);
+ break;
+ case CAN_LED_EVENT_RX:
+ if (led_delay)
+ led_trigger_blink_oneshot(priv->rx_led_trig,
+ &led_delay, &led_delay, 1);
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(can_led_event);
+
+static void can_led_release(struct device *gendev, void *res)
+{
+ struct can_priv *priv = netdev_priv(to_net_dev(gendev));
+
+ led_trigger_unregister_simple(priv->tx_led_trig);
+ led_trigger_unregister_simple(priv->rx_led_trig);
+}
+
+/* Register CAN LED triggers for a CAN device
+ *
+ * This is normally called from a driver's probe function
+ */
+void devm_can_led_init(struct net_device *netdev)
+{
+ struct can_priv *priv = netdev_priv(netdev);
+ void *res;
+
+ res = devres_alloc(can_led_release, 0, GFP_KERNEL);
+ if (!res) {
+ netdev_err(netdev, "cannot register LED triggers\n");
+ return;
+ }
+
+ snprintf(priv->tx_led_trig_name, sizeof(priv->tx_led_trig_name),
+ "%s-tx", netdev->name);
+ snprintf(priv->rx_led_trig_name, sizeof(priv->rx_led_trig_name),
+ "%s-rx", netdev->name);
+
+ led_trigger_register_simple(priv->tx_led_trig_name,
+ &priv->tx_led_trig);
+ led_trigger_register_simple(priv->rx_led_trig_name,
+ &priv->rx_led_trig);
+
+ devres_add(&netdev->dev, res);
+}
+EXPORT_SYMBOL_GPL(devm_can_led_init);
+
+/* NETDEV rename notifier to rename the associated led triggers too */
+static int can_led_notifier(struct notifier_block *nb, unsigned long msg,
+ void *ptr)
+{
+ struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
+ struct can_priv *priv = safe_candev_priv(netdev);
+ char name[CAN_LED_NAME_SZ];
+
+ if (!priv)
+ return NOTIFY_DONE;
+
+ if (!priv->tx_led_trig || !priv->rx_led_trig)
+ return NOTIFY_DONE;
+
+ if (msg == NETDEV_CHANGENAME) {
+ snprintf(name, sizeof(name), "%s-tx", netdev->name);
+ led_trigger_rename_static(name, priv->tx_led_trig);
+
+ snprintf(name, sizeof(name), "%s-rx", netdev->name);
+ led_trigger_rename_static(name, priv->rx_led_trig);
+ }
+
+ return NOTIFY_DONE;
+}
+
+/* notifier block for netdevice event */
+static struct notifier_block can_netdev_notifier __read_mostly = {
+ .notifier_call = can_led_notifier,
+};
+
+int __init can_led_notifier_init(void)
+{
+ return register_netdevice_notifier(&can_netdev_notifier);
+}
+
+void __exit can_led_notifier_exit(void)
+{
+ unregister_netdevice_notifier(&can_netdev_notifier);
+}
diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig
new file mode 100644
index 00000000000..81c71171949
--- /dev/null
+++ b/drivers/net/can/mscan/Kconfig
@@ -0,0 +1,24 @@
+config CAN_MSCAN
+ depends on PPC
+ tristate "Support for Freescale MSCAN based chips"
+ ---help---
+ The Motorola Scalable Controller Area Network (MSCAN) definition
+ is based on the MSCAN12 definition which is the specific
+ implementation of the Motorola Scalable CAN concept targeted for
+ the Motorola MC68HC12 Microcontroller Family.
+
+if CAN_MSCAN
+
+config CAN_MPC5XXX
+ tristate "Freescale MPC5xxx onboard CAN controller"
+ depends on (PPC_MPC52xx || PPC_MPC512x)
+ ---help---
+ If you say yes here you get support for Freescale's MPC5xxx
+ onboard CAN controller. Currently, the MPC5200, MPC5200B and
+ MPC5121 (Rev. 2 and later) are supported.
+
+ This driver can also be built as a module. If so, the module
+ will be called mscan-mpc5xxx.ko.
+
+endif
+
diff --git a/drivers/net/can/mscan/Makefile b/drivers/net/can/mscan/Makefile
new file mode 100644
index 00000000000..c9fab17cd8b
--- /dev/null
+++ b/drivers/net/can/mscan/Makefile
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_CAN_MPC5XXX) += mscan-mpc5xxx.o
+mscan-mpc5xxx-objs := mscan.o mpc5xxx_can.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
new file mode 100644
index 00000000000..44725296f72
--- /dev/null
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -0,0 +1,459 @@
+/*
+ * CAN bus driver for the Freescale MPC5xxx embedded CPU.
+ *
+ * Copyright (C) 2004-2005 Andrey Volkov <avolkov@varma-el.com>,
+ * Varma Electronics Oy
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2009 Wolfram Sang, Pengutronix <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/can/dev.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <asm/mpc52xx.h>
+
+#include "mscan.h"
+
+#define DRV_NAME "mpc5xxx_can"
+
+struct mpc5xxx_can_data {
+ unsigned int type;
+ u32 (*get_clock)(struct platform_device *ofdev, const char *clock_name,
+ int *mscan_clksrc);
+ void (*put_clock)(struct platform_device *ofdev);
+};
+
+#ifdef CONFIG_PPC_MPC52xx
+static struct of_device_id mpc52xx_cdm_ids[] = {
+ { .compatible = "fsl,mpc5200-cdm", },
+ {}
+};
+
+static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
+ const char *clock_name, int *mscan_clksrc)
+{
+ unsigned int pvr;
+ struct mpc52xx_cdm __iomem *cdm;
+ struct device_node *np_cdm;
+ unsigned int freq;
+ u32 val;
+
+ pvr = mfspr(SPRN_PVR);
+
+ /*
+ * Either the oscillator clock (SYS_XTAL_IN) or the IP bus clock
+ * (IP_CLK) can be selected as MSCAN clock source. According to
+ * the MPC5200 user's manual, the oscillator clock is the better
+ * choice as it has less jitter. For this reason, it is selected
+ * by default. Unfortunately, it can not be selected for the old
+ * MPC5200 Rev. A chips due to a hardware bug (check errata).
+ */
+ if (clock_name && strcmp(clock_name, "ip") == 0)
+ *mscan_clksrc = MSCAN_CLKSRC_BUS;
+ else
+ *mscan_clksrc = MSCAN_CLKSRC_XTAL;
+
+ freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
+ if (!freq)
+ return 0;
+
+ if (*mscan_clksrc == MSCAN_CLKSRC_BUS || pvr == 0x80822011)
+ return freq;
+
+ /* Determine SYS_XTAL_IN frequency from the clock domain settings */
+ np_cdm = of_find_matching_node(NULL, mpc52xx_cdm_ids);
+ if (!np_cdm) {
+ dev_err(&ofdev->dev, "can't get clock node!\n");
+ return 0;
+ }
+ cdm = of_iomap(np_cdm, 0);
+
+ if (in_8(&cdm->ipb_clk_sel) & 0x1)
+ freq *= 2;
+ val = in_be32(&cdm->rstcfg);
+
+ freq *= (val & (1 << 5)) ? 8 : 4;
+ freq /= (val & (1 << 6)) ? 12 : 16;
+
+ of_node_put(np_cdm);
+ iounmap(cdm);
+
+ return freq;
+}
+#else /* !CONFIG_PPC_MPC52xx */
+static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
+ const char *clock_name, int *mscan_clksrc)
+{
+ return 0;
+}
+#endif /* CONFIG_PPC_MPC52xx */
+
+#ifdef CONFIG_PPC_MPC512x
+static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
+ const char *clock_source, int *mscan_clksrc)
+{
+ struct device_node *np;
+ u32 clockdiv;
+ enum {
+ CLK_FROM_AUTO,
+ CLK_FROM_IPS,
+ CLK_FROM_SYS,
+ CLK_FROM_REF,
+ } clk_from;
+ struct clk *clk_in, *clk_can;
+ unsigned long freq_calc;
+ struct mscan_priv *priv;
+ struct clk *clk_ipg;
+
+ /* the caller passed in the clock source spec that was read from
+ * the device tree, get the optional clock divider as well
+ */
+ np = ofdev->dev.of_node;
+ clockdiv = 1;
+ of_property_read_u32(np, "fsl,mscan-clock-divider", &clockdiv);
+ dev_dbg(&ofdev->dev, "device tree specs: clk src[%s] div[%d]\n",
+ clock_source ? clock_source : "<NULL>", clockdiv);
+
+ /* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to
+ * get set, and the 'ips' clock is the input to the MSCAN
+ * component
+ *
+ * for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC]
+ * bit needs to get cleared, an optional clock-divider may have
+ * been specified (the default value is 1), the appropriate
+ * MSCAN related MCLK is the input to the MSCAN component
+ *
+ * in the absence of a clock-source spec, first an optimal clock
+ * gets determined based on the 'sys' clock, if that fails the
+ * 'ref' clock is used
+ */
+ clk_from = CLK_FROM_AUTO;
+ if (clock_source) {
+ /* interpret the device tree's spec for the clock source */
+ if (!strcmp(clock_source, "ip"))
+ clk_from = CLK_FROM_IPS;
+ else if (!strcmp(clock_source, "sys"))
+ clk_from = CLK_FROM_SYS;
+ else if (!strcmp(clock_source, "ref"))
+ clk_from = CLK_FROM_REF;
+ else
+ goto err_invalid;
+ dev_dbg(&ofdev->dev, "got a clk source spec[%d]\n", clk_from);
+ }
+ if (clk_from == CLK_FROM_AUTO) {
+ /* no spec so far, try the 'sys' clock; round to the
+ * next MHz and see if we can get a multiple of 16MHz
+ */
+ dev_dbg(&ofdev->dev, "no clk source spec, trying SYS\n");
+ clk_in = devm_clk_get(&ofdev->dev, "sys");
+ if (IS_ERR(clk_in))
+ goto err_notavail;
+ freq_calc = clk_get_rate(clk_in);
+ freq_calc += 499999;
+ freq_calc /= 1000000;
+ freq_calc *= 1000000;
+ if ((freq_calc % 16000000) == 0) {
+ clk_from = CLK_FROM_SYS;
+ clockdiv = freq_calc / 16000000;
+ dev_dbg(&ofdev->dev,
+ "clk fit, sys[%lu] div[%d] freq[%lu]\n",
+ freq_calc, clockdiv, freq_calc / clockdiv);
+ }
+ }
+ if (clk_from == CLK_FROM_AUTO) {
+ /* no spec so far, use the 'ref' clock */
+ dev_dbg(&ofdev->dev, "no clk source spec, trying REF\n");
+ clk_in = devm_clk_get(&ofdev->dev, "ref");
+ if (IS_ERR(clk_in))
+ goto err_notavail;
+ clk_from = CLK_FROM_REF;
+ freq_calc = clk_get_rate(clk_in);
+ dev_dbg(&ofdev->dev,
+ "clk fit, ref[%lu] (no div) freq[%lu]\n",
+ freq_calc, freq_calc);
+ }
+
+ /* select IPS or MCLK as the MSCAN input (returned to the caller),
+ * setup the MCLK mux source and rate if applicable, apply the
+ * optionally specified or derived above divider, and determine
+ * the actual resulting clock rate to return to the caller
+ */
+ switch (clk_from) {
+ case CLK_FROM_IPS:
+ clk_can = devm_clk_get(&ofdev->dev, "ips");
+ if (IS_ERR(clk_can))
+ goto err_notavail;
+ priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+ priv->clk_can = clk_can;
+ freq_calc = clk_get_rate(clk_can);
+ *mscan_clksrc = MSCAN_CLKSRC_IPS;
+ dev_dbg(&ofdev->dev, "clk from IPS, clksrc[%d] freq[%lu]\n",
+ *mscan_clksrc, freq_calc);
+ break;
+ case CLK_FROM_SYS:
+ case CLK_FROM_REF:
+ clk_can = devm_clk_get(&ofdev->dev, "mclk");
+ if (IS_ERR(clk_can))
+ goto err_notavail;
+ priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+ priv->clk_can = clk_can;
+ if (clk_from == CLK_FROM_SYS)
+ clk_in = devm_clk_get(&ofdev->dev, "sys");
+ if (clk_from == CLK_FROM_REF)
+ clk_in = devm_clk_get(&ofdev->dev, "ref");
+ if (IS_ERR(clk_in))
+ goto err_notavail;
+ clk_set_parent(clk_can, clk_in);
+ freq_calc = clk_get_rate(clk_in);
+ freq_calc /= clockdiv;
+ clk_set_rate(clk_can, freq_calc);
+ freq_calc = clk_get_rate(clk_can);
+ *mscan_clksrc = MSCAN_CLKSRC_BUS;
+ dev_dbg(&ofdev->dev, "clk from MCLK, clksrc[%d] freq[%lu]\n",
+ *mscan_clksrc, freq_calc);
+ break;
+ default:
+ goto err_invalid;
+ }
+
+ /* the above clk_can item is used for the bitrate, access to
+ * the peripheral's register set needs the clk_ipg item
+ */
+ clk_ipg = devm_clk_get(&ofdev->dev, "ipg");
+ if (IS_ERR(clk_ipg))
+ goto err_notavail_ipg;
+ if (clk_prepare_enable(clk_ipg))
+ goto err_notavail_ipg;
+ priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+ priv->clk_ipg = clk_ipg;
+
+ /* return the determined clock source rate */
+ return freq_calc;
+
+err_invalid:
+ dev_err(&ofdev->dev, "invalid clock source specification\n");
+ /* clock source rate could not get determined */
+ return 0;
+
+err_notavail:
+ dev_err(&ofdev->dev, "cannot acquire or setup bitrate clock source\n");
+ /* clock source rate could not get determined */
+ return 0;
+
+err_notavail_ipg:
+ dev_err(&ofdev->dev, "cannot acquire or setup register clock\n");
+ /* clock source rate could not get determined */
+ return 0;
+}
+
+static void mpc512x_can_put_clock(struct platform_device *ofdev)
+{
+ struct mscan_priv *priv;
+
+ priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+ if (priv->clk_ipg)
+ clk_disable_unprepare(priv->clk_ipg);
+}
+#else /* !CONFIG_PPC_MPC512x */
+static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
+ const char *clock_name, int *mscan_clksrc)
+{
+ return 0;
+}
+#define mpc512x_can_put_clock NULL
+#endif /* CONFIG_PPC_MPC512x */
+
+static const struct of_device_id mpc5xxx_can_table[];
+static int mpc5xxx_can_probe(struct platform_device *ofdev)
+{
+ const struct of_device_id *match;
+ const struct mpc5xxx_can_data *data;
+ struct device_node *np = ofdev->dev.of_node;
+ struct net_device *dev;
+ struct mscan_priv *priv;
+ void __iomem *base;
+ const char *clock_name = NULL;
+ int irq, mscan_clksrc = 0;
+ int err = -ENOMEM;
+
+ match = of_match_device(mpc5xxx_can_table, &ofdev->dev);
+ if (!match)
+ return -EINVAL;
+ data = match->data;
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ dev_err(&ofdev->dev, "couldn't ioremap\n");
+ return err;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+ dev_err(&ofdev->dev, "no irq found\n");
+ err = -ENODEV;
+ goto exit_unmap_mem;
+ }
+
+ dev = alloc_mscandev();
+ if (!dev)
+ goto exit_dispose_irq;
+ platform_set_drvdata(ofdev, dev);
+ SET_NETDEV_DEV(dev, &ofdev->dev);
+
+ priv = netdev_priv(dev);
+ priv->reg_base = base;
+ dev->irq = irq;
+
+ clock_name = of_get_property(np, "fsl,mscan-clock-source", NULL);
+
+ BUG_ON(!data);
+ priv->type = data->type;
+ priv->can.clock.freq = data->get_clock(ofdev, clock_name,
+ &mscan_clksrc);
+ if (!priv->can.clock.freq) {
+ dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n");
+ goto exit_free_mscan;
+ }
+
+ err = register_mscandev(dev, mscan_clksrc);
+ if (err) {
+ dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+ goto exit_free_mscan;
+ }
+
+ dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
+ priv->reg_base, dev->irq, priv->can.clock.freq);
+
+ return 0;
+
+exit_free_mscan:
+ free_candev(dev);
+exit_dispose_irq:
+ irq_dispose_mapping(irq);
+exit_unmap_mem:
+ iounmap(base);
+
+ return err;
+}
+
+static int mpc5xxx_can_remove(struct platform_device *ofdev)
+{
+ const struct of_device_id *match;
+ const struct mpc5xxx_can_data *data;
+ struct net_device *dev = platform_get_drvdata(ofdev);
+ struct mscan_priv *priv = netdev_priv(dev);
+
+ match = of_match_device(mpc5xxx_can_table, &ofdev->dev);
+ data = match ? match->data : NULL;
+
+ unregister_mscandev(dev);
+ if (data && data->put_clock)
+ data->put_clock(ofdev);
+ iounmap(priv->reg_base);
+ irq_dispose_mapping(dev->irq);
+ free_candev(dev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static struct mscan_regs saved_regs;
+static int mpc5xxx_can_suspend(struct platform_device *ofdev, pm_message_t state)
+{
+ struct net_device *dev = platform_get_drvdata(ofdev);
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+
+ _memcpy_fromio(&saved_regs, regs, sizeof(*regs));
+
+ return 0;
+}
+
+static int mpc5xxx_can_resume(struct platform_device *ofdev)
+{
+ struct net_device *dev = platform_get_drvdata(ofdev);
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs *regs = (struct mscan_regs *)priv->reg_base;
+
+ regs->canctl0 |= MSCAN_INITRQ;
+ while (!(regs->canctl1 & MSCAN_INITAK))
+ udelay(10);
+
+ regs->canctl1 = saved_regs.canctl1;
+ regs->canbtr0 = saved_regs.canbtr0;
+ regs->canbtr1 = saved_regs.canbtr1;
+ regs->canidac = saved_regs.canidac;
+
+ /* restore masks, buffers etc. */
+ _memcpy_toio(&regs->canidar1_0, (void *)&saved_regs.canidar1_0,
+ sizeof(*regs) - offsetof(struct mscan_regs, canidar1_0));
+
+ regs->canctl0 &= ~MSCAN_INITRQ;
+ regs->cantbsel = saved_regs.cantbsel;
+ regs->canrier = saved_regs.canrier;
+ regs->cantier = saved_regs.cantier;
+ regs->canctl0 = saved_regs.canctl0;
+
+ return 0;
+}
+#endif
+
+static const struct mpc5xxx_can_data mpc5200_can_data = {
+ .type = MSCAN_TYPE_MPC5200,
+ .get_clock = mpc52xx_can_get_clock,
+ /* .put_clock not applicable */
+};
+
+static const struct mpc5xxx_can_data mpc5121_can_data = {
+ .type = MSCAN_TYPE_MPC5121,
+ .get_clock = mpc512x_can_get_clock,
+ .put_clock = mpc512x_can_put_clock,
+};
+
+static const struct of_device_id mpc5xxx_can_table[] = {
+ { .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, },
+ /* Note that only MPC5121 Rev. 2 (and later) is supported */
+ { .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mpc5xxx_can_table);
+
+static struct platform_driver mpc5xxx_can_driver = {
+ .driver = {
+ .name = "mpc5xxx_can",
+ .owner = THIS_MODULE,
+ .of_match_table = mpc5xxx_can_table,
+ },
+ .probe = mpc5xxx_can_probe,
+ .remove = mpc5xxx_can_remove,
+#ifdef CONFIG_PM
+ .suspend = mpc5xxx_can_suspend,
+ .resume = mpc5xxx_can_resume,
+#endif
+};
+
+module_platform_driver(mpc5xxx_can_driver);
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Freescale MPC5xxx CAN driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
new file mode 100644
index 00000000000..e0c9be5e2ab
--- /dev/null
+++ b/drivers/net/can/mscan/mscan.c
@@ -0,0 +1,737 @@
+/*
+ * CAN bus driver for the alone generic (as possible as) MSCAN controller.
+ *
+ * Copyright (C) 2005-2006 Andrey Volkov <avolkov@varma-el.com>,
+ * Varma Electronics Oy
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2008-2009 Pengutronix <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/list.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/io.h>
+
+#include "mscan.h"
+
+static const struct can_bittiming_const mscan_bittiming_const = {
+ .name = "mscan",
+ .tseg1_min = 4,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+};
+
+struct mscan_state {
+ u8 mode;
+ u8 canrier;
+ u8 cantier;
+};
+
+static enum can_state state_map[] = {
+ CAN_STATE_ERROR_ACTIVE,
+ CAN_STATE_ERROR_WARNING,
+ CAN_STATE_ERROR_PASSIVE,
+ CAN_STATE_BUS_OFF
+};
+
+static int mscan_set_mode(struct net_device *dev, u8 mode)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ int ret = 0;
+ int i;
+ u8 canctl1;
+
+ if (mode != MSCAN_NORMAL_MODE) {
+ if (priv->tx_active) {
+ /* Abort transfers before going to sleep */#
+ out_8(&regs->cantarq, priv->tx_active);
+ /* Suppress TX done interrupts */
+ out_8(&regs->cantier, 0);
+ }
+
+ canctl1 = in_8(&regs->canctl1);
+ if ((mode & MSCAN_SLPRQ) && !(canctl1 & MSCAN_SLPAK)) {
+ setbits8(&regs->canctl0, MSCAN_SLPRQ);
+ for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
+ if (in_8(&regs->canctl1) & MSCAN_SLPAK)
+ break;
+ udelay(100);
+ }
+ /*
+ * The mscan controller will fail to enter sleep mode,
+ * while there are irregular activities on bus, like
+ * somebody keeps retransmitting. This behavior is
+ * undocumented and seems to differ between mscan built
+ * in mpc5200b and mpc5200. We proceed in that case,
+ * since otherwise the slprq will be kept set and the
+ * controller will get stuck. NOTE: INITRQ or CSWAI
+ * will abort all active transmit actions, if still
+ * any, at once.
+ */
+ if (i >= MSCAN_SET_MODE_RETRIES)
+ netdev_dbg(dev,
+ "device failed to enter sleep mode. "
+ "We proceed anyhow.\n");
+ else
+ priv->can.state = CAN_STATE_SLEEPING;
+ }
+
+ if ((mode & MSCAN_INITRQ) && !(canctl1 & MSCAN_INITAK)) {
+ setbits8(&regs->canctl0, MSCAN_INITRQ);
+ for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
+ if (in_8(&regs->canctl1) & MSCAN_INITAK)
+ break;
+ }
+ if (i >= MSCAN_SET_MODE_RETRIES)
+ ret = -ENODEV;
+ }
+ if (!ret)
+ priv->can.state = CAN_STATE_STOPPED;
+
+ if (mode & MSCAN_CSWAI)
+ setbits8(&regs->canctl0, MSCAN_CSWAI);
+
+ } else {
+ canctl1 = in_8(&regs->canctl1);
+ if (canctl1 & (MSCAN_SLPAK | MSCAN_INITAK)) {
+ clrbits8(&regs->canctl0, MSCAN_SLPRQ | MSCAN_INITRQ);
+ for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
+ canctl1 = in_8(&regs->canctl1);
+ if (!(canctl1 & (MSCAN_INITAK | MSCAN_SLPAK)))
+ break;
+ }
+ if (i >= MSCAN_SET_MODE_RETRIES)
+ ret = -ENODEV;
+ else
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ }
+ }
+ return ret;
+}
+
+static int mscan_start(struct net_device *dev)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ u8 canrflg;
+ int err;
+
+ out_8(&regs->canrier, 0);
+
+ INIT_LIST_HEAD(&priv->tx_head);
+ priv->prev_buf_id = 0;
+ priv->cur_pri = 0;
+ priv->tx_active = 0;
+ priv->shadow_canrier = 0;
+ priv->flags = 0;
+
+ if (priv->type == MSCAN_TYPE_MPC5121) {
+ /* Clear pending bus-off condition */
+ if (in_8(&regs->canmisc) & MSCAN_BOHOLD)
+ out_8(&regs->canmisc, MSCAN_BOHOLD);
+ }
+
+ err = mscan_set_mode(dev, MSCAN_NORMAL_MODE);
+ if (err)
+ return err;
+
+ canrflg = in_8(&regs->canrflg);
+ priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
+ priv->can.state = state_map[max(MSCAN_STATE_RX(canrflg),
+ MSCAN_STATE_TX(canrflg))];
+ out_8(&regs->cantier, 0);
+
+ /* Enable receive interrupts. */
+ out_8(&regs->canrier, MSCAN_RX_INTS_ENABLE);
+
+ return 0;
+}
+
+static int mscan_restart(struct net_device *dev)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+
+ if (priv->type == MSCAN_TYPE_MPC5121) {
+ struct mscan_regs __iomem *regs = priv->reg_base;
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ WARN(!(in_8(&regs->canmisc) & MSCAN_BOHOLD),
+ "bus-off state expected\n");
+ out_8(&regs->canmisc, MSCAN_BOHOLD);
+ /* Re-enable receive interrupts. */
+ out_8(&regs->canrier, MSCAN_RX_INTS_ENABLE);
+ } else {
+ if (priv->can.state <= CAN_STATE_BUS_OFF)
+ mscan_set_mode(dev, MSCAN_INIT_MODE);
+ return mscan_start(dev);
+ }
+
+ return 0;
+}
+
+static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct can_frame *frame = (struct can_frame *)skb->data;
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ int i, rtr, buf_id;
+ u32 can_id;
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ out_8(&regs->cantier, 0);
+
+ i = ~priv->tx_active & MSCAN_TXE;
+ buf_id = ffs(i) - 1;
+ switch (hweight8(i)) {
+ case 0:
+ netif_stop_queue(dev);
+ netdev_err(dev, "Tx Ring full when queue awake!\n");
+ return NETDEV_TX_BUSY;
+ case 1:
+ /*
+ * if buf_id < 3, then current frame will be send out of order,
+ * since buffer with lower id have higher priority (hell..)
+ */
+ netif_stop_queue(dev);
+ case 2:
+ if (buf_id < priv->prev_buf_id) {
+ priv->cur_pri++;
+ if (priv->cur_pri == 0xff) {
+ set_bit(F_TX_WAIT_ALL, &priv->flags);
+ netif_stop_queue(dev);
+ }
+ }
+ set_bit(F_TX_PROGRESS, &priv->flags);
+ break;
+ }
+ priv->prev_buf_id = buf_id;
+ out_8(&regs->cantbsel, i);
+
+ rtr = frame->can_id & CAN_RTR_FLAG;
+
+ /* RTR is always the lowest bit of interest, then IDs follow */
+ if (frame->can_id & CAN_EFF_FLAG) {
+ can_id = (frame->can_id & CAN_EFF_MASK)
+ << (MSCAN_EFF_RTR_SHIFT + 1);
+ if (rtr)
+ can_id |= 1 << MSCAN_EFF_RTR_SHIFT;
+ out_be16(&regs->tx.idr3_2, can_id);
+
+ can_id >>= 16;
+ /* EFF_FLAGS are between the IDs :( */
+ can_id = (can_id & 0x7) | ((can_id << 2) & 0xffe0)
+ | MSCAN_EFF_FLAGS;
+ } else {
+ can_id = (frame->can_id & CAN_SFF_MASK)
+ << (MSCAN_SFF_RTR_SHIFT + 1);
+ if (rtr)
+ can_id |= 1 << MSCAN_SFF_RTR_SHIFT;
+ }
+ out_be16(&regs->tx.idr1_0, can_id);
+
+ if (!rtr) {
+ void __iomem *data = &regs->tx.dsr1_0;
+ u16 *payload = (u16 *)frame->data;
+
+ for (i = 0; i < frame->can_dlc / 2; i++) {
+ out_be16(data, *payload++);
+ data += 2 + _MSCAN_RESERVED_DSR_SIZE;
+ }
+ /* write remaining byte if necessary */
+ if (frame->can_dlc & 1)
+ out_8(data, frame->data[frame->can_dlc - 1]);
+ }
+
+ out_8(&regs->tx.dlr, frame->can_dlc);
+ out_8(&regs->tx.tbpr, priv->cur_pri);
+
+ /* Start transmission. */
+ out_8(&regs->cantflg, 1 << buf_id);
+
+ if (!test_bit(F_TX_PROGRESS, &priv->flags))
+ dev->trans_start = jiffies;
+
+ list_add_tail(&priv->tx_queue[buf_id].list, &priv->tx_head);
+
+ can_put_echo_skb(skb, dev, buf_id);
+
+ /* Enable interrupt. */
+ priv->tx_active |= 1 << buf_id;
+ out_8(&regs->cantier, priv->tx_active);
+
+ return NETDEV_TX_OK;
+}
+
+/* This function returns the old state to see where we came from */
+static enum can_state check_set_state(struct net_device *dev, u8 canrflg)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ enum can_state state, old_state = priv->can.state;
+
+ if (canrflg & MSCAN_CSCIF && old_state <= CAN_STATE_BUS_OFF) {
+ state = state_map[max(MSCAN_STATE_RX(canrflg),
+ MSCAN_STATE_TX(canrflg))];
+ priv->can.state = state;
+ }
+ return old_state;
+}
+
+static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ u32 can_id;
+ int i;
+
+ can_id = in_be16(&regs->rx.idr1_0);
+ if (can_id & (1 << 3)) {
+ frame->can_id = CAN_EFF_FLAG;
+ can_id = ((can_id << 16) | in_be16(&regs->rx.idr3_2));
+ can_id = ((can_id & 0xffe00000) |
+ ((can_id & 0x7ffff) << 2)) >> 2;
+ } else {
+ can_id >>= 4;
+ frame->can_id = 0;
+ }
+
+ frame->can_id |= can_id >> 1;
+ if (can_id & 1)
+ frame->can_id |= CAN_RTR_FLAG;
+
+ frame->can_dlc = get_can_dlc(in_8(&regs->rx.dlr) & 0xf);
+
+ if (!(frame->can_id & CAN_RTR_FLAG)) {
+ void __iomem *data = &regs->rx.dsr1_0;
+ u16 *payload = (u16 *)frame->data;
+
+ for (i = 0; i < frame->can_dlc / 2; i++) {
+ *payload++ = in_be16(data);
+ data += 2 + _MSCAN_RESERVED_DSR_SIZE;
+ }
+ /* read remaining byte if necessary */
+ if (frame->can_dlc & 1)
+ frame->data[frame->can_dlc - 1] = in_8(data);
+ }
+
+ out_8(&regs->canrflg, MSCAN_RXF);
+}
+
+static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
+ u8 canrflg)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ struct net_device_stats *stats = &dev->stats;
+ enum can_state old_state;
+
+ netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg);
+ frame->can_id = CAN_ERR_FLAG;
+
+ if (canrflg & MSCAN_OVRIF) {
+ frame->can_id |= CAN_ERR_CRTL;
+ frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ } else {
+ frame->data[1] = 0;
+ }
+
+ old_state = check_set_state(dev, canrflg);
+ /* State changed */
+ if (old_state != priv->can.state) {
+ switch (priv->can.state) {
+ case CAN_STATE_ERROR_WARNING:
+ frame->can_id |= CAN_ERR_CRTL;
+ priv->can.can_stats.error_warning++;
+ if ((priv->shadow_statflg & MSCAN_RSTAT_MSK) <
+ (canrflg & MSCAN_RSTAT_MSK))
+ frame->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+ if ((priv->shadow_statflg & MSCAN_TSTAT_MSK) <
+ (canrflg & MSCAN_TSTAT_MSK))
+ frame->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+ break;
+ case CAN_STATE_ERROR_PASSIVE:
+ frame->can_id |= CAN_ERR_CRTL;
+ priv->can.can_stats.error_passive++;
+ frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+ break;
+ case CAN_STATE_BUS_OFF:
+ frame->can_id |= CAN_ERR_BUSOFF;
+ /*
+ * The MSCAN on the MPC5200 does recover from bus-off
+ * automatically. To avoid that we stop the chip doing
+ * a light-weight stop (we are in irq-context).
+ */
+ if (priv->type != MSCAN_TYPE_MPC5121) {
+ out_8(&regs->cantier, 0);
+ out_8(&regs->canrier, 0);
+ setbits8(&regs->canctl0,
+ MSCAN_SLPRQ | MSCAN_INITRQ);
+ }
+ can_bus_off(dev);
+ break;
+ default:
+ break;
+ }
+ }
+ priv->shadow_statflg = canrflg & MSCAN_STAT_MSK;
+ frame->can_dlc = CAN_ERR_DLC;
+ out_8(&regs->canrflg, MSCAN_ERR_IF);
+}
+
+static int mscan_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct mscan_priv *priv = container_of(napi, struct mscan_priv, napi);
+ struct net_device *dev = napi->dev;
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ struct net_device_stats *stats = &dev->stats;
+ int npackets = 0;
+ int ret = 1;
+ struct sk_buff *skb;
+ struct can_frame *frame;
+ u8 canrflg;
+
+ while (npackets < quota) {
+ canrflg = in_8(&regs->canrflg);
+ if (!(canrflg & (MSCAN_RXF | MSCAN_ERR_IF)))
+ break;
+
+ skb = alloc_can_skb(dev, &frame);
+ if (!skb) {
+ if (printk_ratelimit())
+ netdev_notice(dev, "packet dropped\n");
+ stats->rx_dropped++;
+ out_8(&regs->canrflg, canrflg);
+ continue;
+ }
+
+ if (canrflg & MSCAN_RXF)
+ mscan_get_rx_frame(dev, frame);
+ else if (canrflg & MSCAN_ERR_IF)
+ mscan_get_err_frame(dev, frame, canrflg);
+
+ stats->rx_packets++;
+ stats->rx_bytes += frame->can_dlc;
+ npackets++;
+ netif_receive_skb(skb);
+ }
+
+ if (!(in_8(&regs->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) {
+ napi_complete(&priv->napi);
+ clear_bit(F_RX_PROGRESS, &priv->flags);
+ if (priv->can.state < CAN_STATE_BUS_OFF)
+ out_8(&regs->canrier, priv->shadow_canrier);
+ ret = 0;
+ }
+ return ret;
+}
+
+static irqreturn_t mscan_isr(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ struct net_device_stats *stats = &dev->stats;
+ u8 cantier, cantflg, canrflg;
+ irqreturn_t ret = IRQ_NONE;
+
+ cantier = in_8(&regs->cantier) & MSCAN_TXE;
+ cantflg = in_8(&regs->cantflg) & cantier;
+
+ if (cantier && cantflg) {
+ struct list_head *tmp, *pos;
+
+ list_for_each_safe(pos, tmp, &priv->tx_head) {
+ struct tx_queue_entry *entry =
+ list_entry(pos, struct tx_queue_entry, list);
+ u8 mask = entry->mask;
+
+ if (!(cantflg & mask))
+ continue;
+
+ out_8(&regs->cantbsel, mask);
+ stats->tx_bytes += in_8(&regs->tx.dlr);
+ stats->tx_packets++;
+ can_get_echo_skb(dev, entry->id);
+ priv->tx_active &= ~mask;
+ list_del(pos);
+ }
+
+ if (list_empty(&priv->tx_head)) {
+ clear_bit(F_TX_WAIT_ALL, &priv->flags);
+ clear_bit(F_TX_PROGRESS, &priv->flags);
+ priv->cur_pri = 0;
+ } else {
+ dev->trans_start = jiffies;
+ }
+
+ if (!test_bit(F_TX_WAIT_ALL, &priv->flags))
+ netif_wake_queue(dev);
+
+ out_8(&regs->cantier, priv->tx_active);
+ ret = IRQ_HANDLED;
+ }
+
+ canrflg = in_8(&regs->canrflg);
+ if ((canrflg & ~MSCAN_STAT_MSK) &&
+ !test_and_set_bit(F_RX_PROGRESS, &priv->flags)) {
+ if (canrflg & ~MSCAN_STAT_MSK) {
+ priv->shadow_canrier = in_8(&regs->canrier);
+ out_8(&regs->canrier, 0);
+ napi_schedule(&priv->napi);
+ ret = IRQ_HANDLED;
+ } else {
+ clear_bit(F_RX_PROGRESS, &priv->flags);
+ }
+ }
+ return ret;
+}
+
+static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ int ret = 0;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ ret = mscan_restart(dev);
+ if (ret)
+ break;
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ return ret;
+}
+
+static int mscan_do_set_bittiming(struct net_device *dev)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u8 btr0, btr1;
+
+ btr0 = BTR0_SET_BRP(bt->brp) | BTR0_SET_SJW(bt->sjw);
+ btr1 = (BTR1_SET_TSEG1(bt->prop_seg + bt->phase_seg1) |
+ BTR1_SET_TSEG2(bt->phase_seg2) |
+ BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES));
+
+ netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+ out_8(&regs->canbtr0, btr0);
+ out_8(&regs->canbtr1, btr1);
+
+ return 0;
+}
+
+static int mscan_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+
+ bec->txerr = in_8(&regs->cantxerr);
+ bec->rxerr = in_8(&regs->canrxerr);
+
+ return 0;
+}
+
+static int mscan_open(struct net_device *dev)
+{
+ int ret;
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+
+ if (priv->clk_ipg) {
+ ret = clk_prepare_enable(priv->clk_ipg);
+ if (ret)
+ goto exit_retcode;
+ }
+ if (priv->clk_can) {
+ ret = clk_prepare_enable(priv->clk_can);
+ if (ret)
+ goto exit_dis_ipg_clock;
+ }
+
+ /* common open */
+ ret = open_candev(dev);
+ if (ret)
+ goto exit_dis_can_clock;
+
+ napi_enable(&priv->napi);
+
+ ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev);
+ if (ret < 0) {
+ netdev_err(dev, "failed to attach interrupt\n");
+ goto exit_napi_disable;
+ }
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ setbits8(&regs->canctl1, MSCAN_LISTEN);
+ else
+ clrbits8(&regs->canctl1, MSCAN_LISTEN);
+
+ ret = mscan_start(dev);
+ if (ret)
+ goto exit_free_irq;
+
+ netif_start_queue(dev);
+
+ return 0;
+
+exit_free_irq:
+ free_irq(dev->irq, dev);
+exit_napi_disable:
+ napi_disable(&priv->napi);
+ close_candev(dev);
+exit_dis_can_clock:
+ if (priv->clk_can)
+ clk_disable_unprepare(priv->clk_can);
+exit_dis_ipg_clock:
+ if (priv->clk_ipg)
+ clk_disable_unprepare(priv->clk_ipg);
+exit_retcode:
+ return ret;
+}
+
+static int mscan_close(struct net_device *dev)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+
+ out_8(&regs->cantier, 0);
+ out_8(&regs->canrier, 0);
+ mscan_set_mode(dev, MSCAN_INIT_MODE);
+ close_candev(dev);
+ free_irq(dev->irq, dev);
+
+ if (priv->clk_can)
+ clk_disable_unprepare(priv->clk_can);
+ if (priv->clk_ipg)
+ clk_disable_unprepare(priv->clk_ipg);
+
+ return 0;
+}
+
+static const struct net_device_ops mscan_netdev_ops = {
+ .ndo_open = mscan_open,
+ .ndo_stop = mscan_close,
+ .ndo_start_xmit = mscan_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+int register_mscandev(struct net_device *dev, int mscan_clksrc)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ u8 ctl1;
+
+ ctl1 = in_8(&regs->canctl1);
+ if (mscan_clksrc)
+ ctl1 |= MSCAN_CLKSRC;
+ else
+ ctl1 &= ~MSCAN_CLKSRC;
+
+ if (priv->type == MSCAN_TYPE_MPC5121) {
+ priv->can.do_get_berr_counter = mscan_get_berr_counter;
+ ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */
+ }
+
+ ctl1 |= MSCAN_CANE;
+ out_8(&regs->canctl1, ctl1);
+ udelay(100);
+
+ /* acceptance mask/acceptance code (accept everything) */
+ out_be16(&regs->canidar1_0, 0);
+ out_be16(&regs->canidar3_2, 0);
+ out_be16(&regs->canidar5_4, 0);
+ out_be16(&regs->canidar7_6, 0);
+
+ out_be16(&regs->canidmr1_0, 0xffff);
+ out_be16(&regs->canidmr3_2, 0xffff);
+ out_be16(&regs->canidmr5_4, 0xffff);
+ out_be16(&regs->canidmr7_6, 0xffff);
+ /* Two 32 bit Acceptance Filters */
+ out_8(&regs->canidac, MSCAN_AF_32BIT);
+
+ mscan_set_mode(dev, MSCAN_INIT_MODE);
+
+ return register_candev(dev);
+}
+
+void unregister_mscandev(struct net_device *dev)
+{
+ struct mscan_priv *priv = netdev_priv(dev);
+ struct mscan_regs __iomem *regs = priv->reg_base;
+ mscan_set_mode(dev, MSCAN_INIT_MODE);
+ clrbits8(&regs->canctl1, MSCAN_CANE);
+ unregister_candev(dev);
+}
+
+struct net_device *alloc_mscandev(void)
+{
+ struct net_device *dev;
+ struct mscan_priv *priv;
+ int i;
+
+ dev = alloc_candev(sizeof(struct mscan_priv), MSCAN_ECHO_SKB_MAX);
+ if (!dev)
+ return NULL;
+ priv = netdev_priv(dev);
+
+ dev->netdev_ops = &mscan_netdev_ops;
+
+ dev->flags |= IFF_ECHO; /* we support local echo */
+
+ netif_napi_add(dev, &priv->napi, mscan_rx_poll, 8);
+
+ priv->can.bittiming_const = &mscan_bittiming_const;
+ priv->can.do_set_bittiming = mscan_do_set_bittiming;
+ priv->can.do_set_mode = mscan_do_set_mode;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_LISTENONLY;
+
+ for (i = 0; i < TX_QUEUE_SIZE; i++) {
+ priv->tx_queue[i].id = i;
+ priv->tx_queue[i].mask = 1 << i;
+ }
+
+ return dev;
+}
+
+MODULE_AUTHOR("Andrey Volkov <avolkov@varma-el.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CAN port driver for a MSCAN based chips");
diff --git a/drivers/net/can/mscan/mscan.h b/drivers/net/can/mscan/mscan.h
new file mode 100644
index 00000000000..ad8e08f9c49
--- /dev/null
+++ b/drivers/net/can/mscan/mscan.h
@@ -0,0 +1,303 @@
+/*
+ * Definitions of consts/structs to drive the Freescale MSCAN.
+ *
+ * Copyright (C) 2005-2006 Andrey Volkov <avolkov@varma-el.com>,
+ * Varma Electronics Oy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MSCAN_H__
+#define __MSCAN_H__
+
+#include <linux/clk.h>
+#include <linux/types.h>
+
+/* MSCAN control register 0 (CANCTL0) bits */
+#define MSCAN_RXFRM 0x80
+#define MSCAN_RXACT 0x40
+#define MSCAN_CSWAI 0x20
+#define MSCAN_SYNCH 0x10
+#define MSCAN_TIME 0x08
+#define MSCAN_WUPE 0x04
+#define MSCAN_SLPRQ 0x02
+#define MSCAN_INITRQ 0x01
+
+/* MSCAN control register 1 (CANCTL1) bits */
+#define MSCAN_CANE 0x80
+#define MSCAN_CLKSRC 0x40
+#define MSCAN_LOOPB 0x20
+#define MSCAN_LISTEN 0x10
+#define MSCAN_BORM 0x08
+#define MSCAN_WUPM 0x04
+#define MSCAN_SLPAK 0x02
+#define MSCAN_INITAK 0x01
+
+/* Use the MPC5XXX MSCAN variant? */
+#ifdef CONFIG_PPC
+#define MSCAN_FOR_MPC5XXX
+#endif
+
+#ifdef MSCAN_FOR_MPC5XXX
+#define MSCAN_CLKSRC_BUS 0
+#define MSCAN_CLKSRC_XTAL MSCAN_CLKSRC
+#define MSCAN_CLKSRC_IPS MSCAN_CLKSRC
+#else
+#define MSCAN_CLKSRC_BUS MSCAN_CLKSRC
+#define MSCAN_CLKSRC_XTAL 0
+#endif
+
+/* MSCAN receiver flag register (CANRFLG) bits */
+#define MSCAN_WUPIF 0x80
+#define MSCAN_CSCIF 0x40
+#define MSCAN_RSTAT1 0x20
+#define MSCAN_RSTAT0 0x10
+#define MSCAN_TSTAT1 0x08
+#define MSCAN_TSTAT0 0x04
+#define MSCAN_OVRIF 0x02
+#define MSCAN_RXF 0x01
+#define MSCAN_ERR_IF (MSCAN_OVRIF | MSCAN_CSCIF)
+#define MSCAN_RSTAT_MSK (MSCAN_RSTAT1 | MSCAN_RSTAT0)
+#define MSCAN_TSTAT_MSK (MSCAN_TSTAT1 | MSCAN_TSTAT0)
+#define MSCAN_STAT_MSK (MSCAN_RSTAT_MSK | MSCAN_TSTAT_MSK)
+
+#define MSCAN_STATE_BUS_OFF (MSCAN_RSTAT1 | MSCAN_RSTAT0 | \
+ MSCAN_TSTAT1 | MSCAN_TSTAT0)
+#define MSCAN_STATE_TX(canrflg) (((canrflg)&MSCAN_TSTAT_MSK)>>2)
+#define MSCAN_STATE_RX(canrflg) (((canrflg)&MSCAN_RSTAT_MSK)>>4)
+#define MSCAN_STATE_ACTIVE 0
+#define MSCAN_STATE_WARNING 1
+#define MSCAN_STATE_PASSIVE 2
+#define MSCAN_STATE_BUSOFF 3
+
+/* MSCAN receiver interrupt enable register (CANRIER) bits */
+#define MSCAN_WUPIE 0x80
+#define MSCAN_CSCIE 0x40
+#define MSCAN_RSTATE1 0x20
+#define MSCAN_RSTATE0 0x10
+#define MSCAN_TSTATE1 0x08
+#define MSCAN_TSTATE0 0x04
+#define MSCAN_OVRIE 0x02
+#define MSCAN_RXFIE 0x01
+
+/* MSCAN transmitter flag register (CANTFLG) bits */
+#define MSCAN_TXE2 0x04
+#define MSCAN_TXE1 0x02
+#define MSCAN_TXE0 0x01
+#define MSCAN_TXE (MSCAN_TXE2 | MSCAN_TXE1 | MSCAN_TXE0)
+
+/* MSCAN transmitter interrupt enable register (CANTIER) bits */
+#define MSCAN_TXIE2 0x04
+#define MSCAN_TXIE1 0x02
+#define MSCAN_TXIE0 0x01
+#define MSCAN_TXIE (MSCAN_TXIE2 | MSCAN_TXIE1 | MSCAN_TXIE0)
+
+/* MSCAN transmitter message abort request (CANTARQ) bits */
+#define MSCAN_ABTRQ2 0x04
+#define MSCAN_ABTRQ1 0x02
+#define MSCAN_ABTRQ0 0x01
+
+/* MSCAN transmitter message abort ack (CANTAAK) bits */
+#define MSCAN_ABTAK2 0x04
+#define MSCAN_ABTAK1 0x02
+#define MSCAN_ABTAK0 0x01
+
+/* MSCAN transmit buffer selection (CANTBSEL) bits */
+#define MSCAN_TX2 0x04
+#define MSCAN_TX1 0x02
+#define MSCAN_TX0 0x01
+
+/* MSCAN ID acceptance control register (CANIDAC) bits */
+#define MSCAN_IDAM1 0x20
+#define MSCAN_IDAM0 0x10
+#define MSCAN_IDHIT2 0x04
+#define MSCAN_IDHIT1 0x02
+#define MSCAN_IDHIT0 0x01
+
+#define MSCAN_AF_32BIT 0x00
+#define MSCAN_AF_16BIT MSCAN_IDAM0
+#define MSCAN_AF_8BIT MSCAN_IDAM1
+#define MSCAN_AF_CLOSED (MSCAN_IDAM0|MSCAN_IDAM1)
+#define MSCAN_AF_MASK (~(MSCAN_IDAM0|MSCAN_IDAM1))
+
+/* MSCAN Miscellaneous Register (CANMISC) bits */
+#define MSCAN_BOHOLD 0x01
+
+/* MSCAN Identifier Register (IDR) bits */
+#define MSCAN_SFF_RTR_SHIFT 4
+#define MSCAN_EFF_RTR_SHIFT 0
+#define MSCAN_EFF_FLAGS 0x18 /* IDE + SRR */
+
+#ifdef MSCAN_FOR_MPC5XXX
+#define _MSCAN_RESERVED_(n, num) u8 _res##n[num]
+#define _MSCAN_RESERVED_DSR_SIZE 2
+#else
+#define _MSCAN_RESERVED_(n, num)
+#define _MSCAN_RESERVED_DSR_SIZE 0
+#endif
+
+/* Structure of the hardware registers */
+struct mscan_regs {
+ /* (see doc S12MSCANV3/D) MPC5200 MSCAN */
+ u8 canctl0; /* + 0x00 0x00 */
+ u8 canctl1; /* + 0x01 0x01 */
+ _MSCAN_RESERVED_(1, 2); /* + 0x02 */
+ u8 canbtr0; /* + 0x04 0x02 */
+ u8 canbtr1; /* + 0x05 0x03 */
+ _MSCAN_RESERVED_(2, 2); /* + 0x06 */
+ u8 canrflg; /* + 0x08 0x04 */
+ u8 canrier; /* + 0x09 0x05 */
+ _MSCAN_RESERVED_(3, 2); /* + 0x0a */
+ u8 cantflg; /* + 0x0c 0x06 */
+ u8 cantier; /* + 0x0d 0x07 */
+ _MSCAN_RESERVED_(4, 2); /* + 0x0e */
+ u8 cantarq; /* + 0x10 0x08 */
+ u8 cantaak; /* + 0x11 0x09 */
+ _MSCAN_RESERVED_(5, 2); /* + 0x12 */
+ u8 cantbsel; /* + 0x14 0x0a */
+ u8 canidac; /* + 0x15 0x0b */
+ u8 reserved; /* + 0x16 0x0c */
+ _MSCAN_RESERVED_(6, 2); /* + 0x17 */
+ u8 canmisc; /* + 0x19 0x0d */
+ _MSCAN_RESERVED_(7, 2); /* + 0x1a */
+ u8 canrxerr; /* + 0x1c 0x0e */
+ u8 cantxerr; /* + 0x1d 0x0f */
+ _MSCAN_RESERVED_(8, 2); /* + 0x1e */
+ u16 canidar1_0; /* + 0x20 0x10 */
+ _MSCAN_RESERVED_(9, 2); /* + 0x22 */
+ u16 canidar3_2; /* + 0x24 0x12 */
+ _MSCAN_RESERVED_(10, 2); /* + 0x26 */
+ u16 canidmr1_0; /* + 0x28 0x14 */
+ _MSCAN_RESERVED_(11, 2); /* + 0x2a */
+ u16 canidmr3_2; /* + 0x2c 0x16 */
+ _MSCAN_RESERVED_(12, 2); /* + 0x2e */
+ u16 canidar5_4; /* + 0x30 0x18 */
+ _MSCAN_RESERVED_(13, 2); /* + 0x32 */
+ u16 canidar7_6; /* + 0x34 0x1a */
+ _MSCAN_RESERVED_(14, 2); /* + 0x36 */
+ u16 canidmr5_4; /* + 0x38 0x1c */
+ _MSCAN_RESERVED_(15, 2); /* + 0x3a */
+ u16 canidmr7_6; /* + 0x3c 0x1e */
+ _MSCAN_RESERVED_(16, 2); /* + 0x3e */
+ struct {
+ u16 idr1_0; /* + 0x40 0x20 */
+ _MSCAN_RESERVED_(17, 2); /* + 0x42 */
+ u16 idr3_2; /* + 0x44 0x22 */
+ _MSCAN_RESERVED_(18, 2); /* + 0x46 */
+ u16 dsr1_0; /* + 0x48 0x24 */
+ _MSCAN_RESERVED_(19, 2); /* + 0x4a */
+ u16 dsr3_2; /* + 0x4c 0x26 */
+ _MSCAN_RESERVED_(20, 2); /* + 0x4e */
+ u16 dsr5_4; /* + 0x50 0x28 */
+ _MSCAN_RESERVED_(21, 2); /* + 0x52 */
+ u16 dsr7_6; /* + 0x54 0x2a */
+ _MSCAN_RESERVED_(22, 2); /* + 0x56 */
+ u8 dlr; /* + 0x58 0x2c */
+ u8 reserved; /* + 0x59 0x2d */
+ _MSCAN_RESERVED_(23, 2); /* + 0x5a */
+ u16 time; /* + 0x5c 0x2e */
+ } rx;
+ _MSCAN_RESERVED_(24, 2); /* + 0x5e */
+ struct {
+ u16 idr1_0; /* + 0x60 0x30 */
+ _MSCAN_RESERVED_(25, 2); /* + 0x62 */
+ u16 idr3_2; /* + 0x64 0x32 */
+ _MSCAN_RESERVED_(26, 2); /* + 0x66 */
+ u16 dsr1_0; /* + 0x68 0x34 */
+ _MSCAN_RESERVED_(27, 2); /* + 0x6a */
+ u16 dsr3_2; /* + 0x6c 0x36 */
+ _MSCAN_RESERVED_(28, 2); /* + 0x6e */
+ u16 dsr5_4; /* + 0x70 0x38 */
+ _MSCAN_RESERVED_(29, 2); /* + 0x72 */
+ u16 dsr7_6; /* + 0x74 0x3a */
+ _MSCAN_RESERVED_(30, 2); /* + 0x76 */
+ u8 dlr; /* + 0x78 0x3c */
+ u8 tbpr; /* + 0x79 0x3d */
+ _MSCAN_RESERVED_(31, 2); /* + 0x7a */
+ u16 time; /* + 0x7c 0x3e */
+ } tx;
+ _MSCAN_RESERVED_(32, 2); /* + 0x7e */
+} __packed;
+
+#undef _MSCAN_RESERVED_
+#define MSCAN_REGION sizeof(struct mscan)
+
+#define MSCAN_NORMAL_MODE 0
+#define MSCAN_SLEEP_MODE MSCAN_SLPRQ
+#define MSCAN_INIT_MODE (MSCAN_INITRQ | MSCAN_SLPRQ)
+#define MSCAN_POWEROFF_MODE (MSCAN_CSWAI | MSCAN_SLPRQ)
+#define MSCAN_SET_MODE_RETRIES 255
+#define MSCAN_ECHO_SKB_MAX 3
+#define MSCAN_RX_INTS_ENABLE (MSCAN_OVRIE | MSCAN_RXFIE | MSCAN_CSCIE | \
+ MSCAN_RSTATE1 | MSCAN_RSTATE0 | \
+ MSCAN_TSTATE1 | MSCAN_TSTATE0)
+
+/* MSCAN type variants */
+enum {
+ MSCAN_TYPE_MPC5200,
+ MSCAN_TYPE_MPC5121
+};
+
+#define BTR0_BRP_MASK 0x3f
+#define BTR0_SJW_SHIFT 6
+#define BTR0_SJW_MASK (0x3 << BTR0_SJW_SHIFT)
+
+#define BTR1_TSEG1_MASK 0xf
+#define BTR1_TSEG2_SHIFT 4
+#define BTR1_TSEG2_MASK (0x7 << BTR1_TSEG2_SHIFT)
+#define BTR1_SAM_SHIFT 7
+
+#define BTR0_SET_BRP(brp) (((brp) - 1) & BTR0_BRP_MASK)
+#define BTR0_SET_SJW(sjw) ((((sjw) - 1) << BTR0_SJW_SHIFT) & \
+ BTR0_SJW_MASK)
+
+#define BTR1_SET_TSEG1(tseg1) (((tseg1) - 1) & BTR1_TSEG1_MASK)
+#define BTR1_SET_TSEG2(tseg2) ((((tseg2) - 1) << BTR1_TSEG2_SHIFT) & \
+ BTR1_TSEG2_MASK)
+#define BTR1_SET_SAM(sam) ((sam) ? 1 << BTR1_SAM_SHIFT : 0)
+
+#define F_RX_PROGRESS 0
+#define F_TX_PROGRESS 1
+#define F_TX_WAIT_ALL 2
+
+#define TX_QUEUE_SIZE 3
+
+struct tx_queue_entry {
+ struct list_head list;
+ u8 mask;
+ u8 id;
+};
+
+struct mscan_priv {
+ struct can_priv can; /* must be the first member */
+ unsigned int type; /* MSCAN type variants */
+ unsigned long flags;
+ void __iomem *reg_base; /* ioremap'ed address to registers */
+ struct clk *clk_ipg; /* clock for registers */
+ struct clk *clk_can; /* clock for bitrates */
+ u8 shadow_statflg;
+ u8 shadow_canrier;
+ u8 cur_pri;
+ u8 prev_buf_id;
+ u8 tx_active;
+
+ struct list_head tx_head;
+ struct tx_queue_entry tx_queue[TX_QUEUE_SIZE];
+ struct napi_struct napi;
+};
+
+struct net_device *alloc_mscandev(void);
+int register_mscandev(struct net_device *dev, int mscan_clksrc);
+void unregister_mscandev(struct net_device *dev);
+
+#endif /* __MSCAN_H__ */
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
new file mode 100644
index 00000000000..6472562efed
--- /dev/null
+++ b/drivers/net/can/pch_can.c
@@ -0,0 +1,1279 @@
+/*
+ * Copyright (C) 1999 - 2010 Intel Corporation.
+ * Copyright (C) 2010 LAPIS SEMICONDUCTOR CO., LTD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#define PCH_CTRL_INIT BIT(0) /* The INIT bit of CANCONT register. */
+#define PCH_CTRL_IE BIT(1) /* The IE bit of CAN control register */
+#define PCH_CTRL_IE_SIE_EIE (BIT(3) | BIT(2) | BIT(1))
+#define PCH_CTRL_CCE BIT(6)
+#define PCH_CTRL_OPT BIT(7) /* The OPT bit of CANCONT register. */
+#define PCH_OPT_SILENT BIT(3) /* The Silent bit of CANOPT reg. */
+#define PCH_OPT_LBACK BIT(4) /* The LoopBack bit of CANOPT reg. */
+
+#define PCH_CMASK_RX_TX_SET 0x00f3
+#define PCH_CMASK_RX_TX_GET 0x0073
+#define PCH_CMASK_ALL 0xff
+#define PCH_CMASK_NEWDAT BIT(2)
+#define PCH_CMASK_CLRINTPND BIT(3)
+#define PCH_CMASK_CTRL BIT(4)
+#define PCH_CMASK_ARB BIT(5)
+#define PCH_CMASK_MASK BIT(6)
+#define PCH_CMASK_RDWR BIT(7)
+#define PCH_IF_MCONT_NEWDAT BIT(15)
+#define PCH_IF_MCONT_MSGLOST BIT(14)
+#define PCH_IF_MCONT_INTPND BIT(13)
+#define PCH_IF_MCONT_UMASK BIT(12)
+#define PCH_IF_MCONT_TXIE BIT(11)
+#define PCH_IF_MCONT_RXIE BIT(10)
+#define PCH_IF_MCONT_RMTEN BIT(9)
+#define PCH_IF_MCONT_TXRQXT BIT(8)
+#define PCH_IF_MCONT_EOB BIT(7)
+#define PCH_IF_MCONT_DLC (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+#define PCH_MASK2_MDIR_MXTD (BIT(14) | BIT(15))
+#define PCH_ID2_DIR BIT(13)
+#define PCH_ID2_XTD BIT(14)
+#define PCH_ID_MSGVAL BIT(15)
+#define PCH_IF_CREQ_BUSY BIT(15)
+
+#define PCH_STATUS_INT 0x8000
+#define PCH_RP 0x00008000
+#define PCH_REC 0x00007f00
+#define PCH_TEC 0x000000ff
+
+#define PCH_TX_OK BIT(3)
+#define PCH_RX_OK BIT(4)
+#define PCH_EPASSIV BIT(5)
+#define PCH_EWARN BIT(6)
+#define PCH_BUS_OFF BIT(7)
+
+/* bit position of certain controller bits. */
+#define PCH_BIT_BRP_SHIFT 0
+#define PCH_BIT_SJW_SHIFT 6
+#define PCH_BIT_TSEG1_SHIFT 8
+#define PCH_BIT_TSEG2_SHIFT 12
+#define PCH_BIT_BRPE_BRPE_SHIFT 6
+
+#define PCH_MSK_BITT_BRP 0x3f
+#define PCH_MSK_BRPE_BRPE 0x3c0
+#define PCH_MSK_CTRL_IE_SIE_EIE 0x07
+#define PCH_COUNTER_LIMIT 10
+
+#define PCH_CAN_CLK 50000000 /* 50MHz */
+
+/*
+ * Define the number of message object.
+ * PCH CAN communications are done via Message RAM.
+ * The Message RAM consists of 32 message objects.
+ */
+#define PCH_RX_OBJ_NUM 26
+#define PCH_TX_OBJ_NUM 6
+#define PCH_RX_OBJ_START 1
+#define PCH_RX_OBJ_END PCH_RX_OBJ_NUM
+#define PCH_TX_OBJ_START (PCH_RX_OBJ_END + 1)
+#define PCH_TX_OBJ_END (PCH_RX_OBJ_NUM + PCH_TX_OBJ_NUM)
+
+#define PCH_FIFO_THRESH 16
+
+/* TxRqst2 show status of MsgObjNo.17~32 */
+#define PCH_TREQ2_TX_MASK (((1 << PCH_TX_OBJ_NUM) - 1) <<\
+ (PCH_RX_OBJ_END - 16))
+
+enum pch_ifreg {
+ PCH_RX_IFREG,
+ PCH_TX_IFREG,
+};
+
+enum pch_can_err {
+ PCH_STUF_ERR = 1,
+ PCH_FORM_ERR,
+ PCH_ACK_ERR,
+ PCH_BIT1_ERR,
+ PCH_BIT0_ERR,
+ PCH_CRC_ERR,
+ PCH_LEC_ALL,
+};
+
+enum pch_can_mode {
+ PCH_CAN_ENABLE,
+ PCH_CAN_DISABLE,
+ PCH_CAN_ALL,
+ PCH_CAN_NONE,
+ PCH_CAN_STOP,
+ PCH_CAN_RUN,
+};
+
+struct pch_can_if_regs {
+ u32 creq;
+ u32 cmask;
+ u32 mask1;
+ u32 mask2;
+ u32 id1;
+ u32 id2;
+ u32 mcont;
+ u32 data[4];
+ u32 rsv[13];
+};
+
+struct pch_can_regs {
+ u32 cont;
+ u32 stat;
+ u32 errc;
+ u32 bitt;
+ u32 intr;
+ u32 opt;
+ u32 brpe;
+ u32 reserve;
+ struct pch_can_if_regs ifregs[2]; /* [0]=if1 [1]=if2 */
+ u32 reserve1[8];
+ u32 treq1;
+ u32 treq2;
+ u32 reserve2[6];
+ u32 data1;
+ u32 data2;
+ u32 reserve3[6];
+ u32 canipend1;
+ u32 canipend2;
+ u32 reserve4[6];
+ u32 canmval1;
+ u32 canmval2;
+ u32 reserve5[37];
+ u32 srst;
+};
+
+struct pch_can_priv {
+ struct can_priv can;
+ struct pci_dev *dev;
+ u32 tx_enable[PCH_TX_OBJ_END];
+ u32 rx_enable[PCH_TX_OBJ_END];
+ u32 rx_link[PCH_TX_OBJ_END];
+ u32 int_enables;
+ struct net_device *ndev;
+ struct pch_can_regs __iomem *regs;
+ struct napi_struct napi;
+ int tx_obj; /* Point next Tx Obj index */
+ int use_msi;
+};
+
+static const struct can_bittiming_const pch_can_bittiming_const = {
+ .name = KBUILD_MODNAME,
+ .tseg1_min = 2,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 1024, /* 6bit + extended 4bit */
+ .brp_inc = 1,
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pch_pci_tbl) = {
+ {PCI_VENDOR_ID_INTEL, 0x8818, PCI_ANY_ID, PCI_ANY_ID,},
+ {0,}
+};
+MODULE_DEVICE_TABLE(pci, pch_pci_tbl);
+
+static inline void pch_can_bit_set(void __iomem *addr, u32 mask)
+{
+ iowrite32(ioread32(addr) | mask, addr);
+}
+
+static inline void pch_can_bit_clear(void __iomem *addr, u32 mask)
+{
+ iowrite32(ioread32(addr) & ~mask, addr);
+}
+
+static void pch_can_set_run_mode(struct pch_can_priv *priv,
+ enum pch_can_mode mode)
+{
+ switch (mode) {
+ case PCH_CAN_RUN:
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_INIT);
+ break;
+
+ case PCH_CAN_STOP:
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_INIT);
+ break;
+
+ default:
+ netdev_err(priv->ndev, "%s -> Invalid Mode.\n", __func__);
+ break;
+ }
+}
+
+static void pch_can_set_optmode(struct pch_can_priv *priv)
+{
+ u32 reg_val = ioread32(&priv->regs->opt);
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ reg_val |= PCH_OPT_SILENT;
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
+ reg_val |= PCH_OPT_LBACK;
+
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_OPT);
+ iowrite32(reg_val, &priv->regs->opt);
+}
+
+static void pch_can_rw_msg_obj(void __iomem *creq_addr, u32 num)
+{
+ int counter = PCH_COUNTER_LIMIT;
+ u32 ifx_creq;
+
+ iowrite32(num, creq_addr);
+ while (counter) {
+ ifx_creq = ioread32(creq_addr) & PCH_IF_CREQ_BUSY;
+ if (!ifx_creq)
+ break;
+ counter--;
+ udelay(1);
+ }
+ if (!counter)
+ pr_err("%s:IF1 BUSY Flag is set forever.\n", __func__);
+}
+
+static void pch_can_set_int_enables(struct pch_can_priv *priv,
+ enum pch_can_mode interrupt_no)
+{
+ switch (interrupt_no) {
+ case PCH_CAN_DISABLE:
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE);
+ break;
+
+ case PCH_CAN_ALL:
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE);
+ break;
+
+ case PCH_CAN_NONE:
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE);
+ break;
+
+ default:
+ netdev_err(priv->ndev, "Invalid interrupt number.\n");
+ break;
+ }
+}
+
+static void pch_can_set_rxtx(struct pch_can_priv *priv, u32 buff_num,
+ int set, enum pch_ifreg dir)
+{
+ u32 ie;
+
+ if (dir)
+ ie = PCH_IF_MCONT_TXIE;
+ else
+ ie = PCH_IF_MCONT_RXIE;
+
+ /* Reading the Msg buffer from Message RAM to IF1/2 registers. */
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num);
+
+ /* Setting the IF1/2MASK1 register to access MsgVal and RxIE bits */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_ARB | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[dir].cmask);
+
+ if (set) {
+ /* Setting the MsgVal and RxIE/TxIE bits */
+ pch_can_bit_set(&priv->regs->ifregs[dir].mcont, ie);
+ pch_can_bit_set(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL);
+ } else {
+ /* Clearing the MsgVal and RxIE/TxIE bits */
+ pch_can_bit_clear(&priv->regs->ifregs[dir].mcont, ie);
+ pch_can_bit_clear(&priv->regs->ifregs[dir].id2, PCH_ID_MSGVAL);
+ }
+
+ pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num);
+}
+
+static void pch_can_set_rx_all(struct pch_can_priv *priv, int set)
+{
+ int i;
+
+ /* Traversing to obtain the object configured as receivers. */
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++)
+ pch_can_set_rxtx(priv, i, set, PCH_RX_IFREG);
+}
+
+static void pch_can_set_tx_all(struct pch_can_priv *priv, int set)
+{
+ int i;
+
+ /* Traversing to obtain the object configured as transmit object. */
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++)
+ pch_can_set_rxtx(priv, i, set, PCH_TX_IFREG);
+}
+
+static u32 pch_can_int_pending(struct pch_can_priv *priv)
+{
+ return ioread32(&priv->regs->intr) & 0xffff;
+}
+
+static void pch_can_clear_if_buffers(struct pch_can_priv *priv)
+{
+ int i; /* Msg Obj ID (1~32) */
+
+ for (i = PCH_RX_OBJ_START; i <= PCH_TX_OBJ_END; i++) {
+ iowrite32(PCH_CMASK_RX_TX_SET, &priv->regs->ifregs[0].cmask);
+ iowrite32(0xffff, &priv->regs->ifregs[0].mask1);
+ iowrite32(0xffff, &priv->regs->ifregs[0].mask2);
+ iowrite32(0x0, &priv->regs->ifregs[0].id1);
+ iowrite32(0x0, &priv->regs->ifregs[0].id2);
+ iowrite32(0x0, &priv->regs->ifregs[0].mcont);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[0]);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[1]);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[2]);
+ iowrite32(0x0, &priv->regs->ifregs[0].data[3]);
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK |
+ PCH_CMASK_ARB | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i);
+ }
+}
+
+static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv)
+{
+ int i;
+
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) {
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i);
+
+ iowrite32(0x0, &priv->regs->ifregs[0].id1);
+ iowrite32(0x0, &priv->regs->ifregs[0].id2);
+
+ pch_can_bit_set(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_UMASK);
+
+ /* In case FIFO mode, Last EoB of Rx Obj must be 1 */
+ if (i == PCH_RX_OBJ_END)
+ pch_can_bit_set(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_EOB);
+ else
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_EOB);
+
+ iowrite32(0, &priv->regs->ifregs[0].mask1);
+ pch_can_bit_clear(&priv->regs->ifregs[0].mask2,
+ 0x1fff | PCH_MASK2_MDIR_MXTD);
+
+ /* Setting CMASK for writing */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB |
+ PCH_CMASK_CTRL, &priv->regs->ifregs[0].cmask);
+
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, i);
+ }
+
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++) {
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[1].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i);
+
+ /* Resetting DIR bit for reception */
+ iowrite32(0x0, &priv->regs->ifregs[1].id1);
+ iowrite32(PCH_ID2_DIR, &priv->regs->ifregs[1].id2);
+
+ /* Setting EOB bit for transmitter */
+ iowrite32(PCH_IF_MCONT_EOB | PCH_IF_MCONT_UMASK,
+ &priv->regs->ifregs[1].mcont);
+
+ iowrite32(0, &priv->regs->ifregs[1].mask1);
+ pch_can_bit_clear(&priv->regs->ifregs[1].mask2, 0x1fff);
+
+ /* Setting CMASK for writing */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_MASK | PCH_CMASK_ARB |
+ PCH_CMASK_CTRL, &priv->regs->ifregs[1].cmask);
+
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, i);
+ }
+}
+
+static void pch_can_init(struct pch_can_priv *priv)
+{
+ /* Stopping the Can device. */
+ pch_can_set_run_mode(priv, PCH_CAN_STOP);
+
+ /* Clearing all the message object buffers. */
+ pch_can_clear_if_buffers(priv);
+
+ /* Configuring the respective message object as either rx/tx object. */
+ pch_can_config_rx_tx_buffers(priv);
+
+ /* Enabling the interrupts. */
+ pch_can_set_int_enables(priv, PCH_CAN_ALL);
+}
+
+static void pch_can_release(struct pch_can_priv *priv)
+{
+ /* Stooping the CAN device. */
+ pch_can_set_run_mode(priv, PCH_CAN_STOP);
+
+ /* Disabling the interrupts. */
+ pch_can_set_int_enables(priv, PCH_CAN_NONE);
+
+ /* Disabling all the receive object. */
+ pch_can_set_rx_all(priv, 0);
+
+ /* Disabling all the transmit object. */
+ pch_can_set_tx_all(priv, 0);
+}
+
+/* This function clears interrupt(s) from the CAN device. */
+static void pch_can_int_clr(struct pch_can_priv *priv, u32 mask)
+{
+ /* Clear interrupt for transmit object */
+ if ((mask >= PCH_RX_OBJ_START) && (mask <= PCH_RX_OBJ_END)) {
+ /* Setting CMASK for clearing the reception interrupts. */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB,
+ &priv->regs->ifregs[0].cmask);
+
+ /* Clearing the Dir bit. */
+ pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR);
+
+ /* Clearing NewDat & IntPnd */
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND);
+
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, mask);
+ } else if ((mask >= PCH_TX_OBJ_START) && (mask <= PCH_TX_OBJ_END)) {
+ /*
+ * Setting CMASK for clearing interrupts for frame transmission.
+ */
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL | PCH_CMASK_ARB,
+ &priv->regs->ifregs[1].cmask);
+
+ /* Resetting the ID registers. */
+ pch_can_bit_set(&priv->regs->ifregs[1].id2,
+ PCH_ID2_DIR | (0x7ff << 2));
+ iowrite32(0x0, &priv->regs->ifregs[1].id1);
+
+ /* Claring NewDat, TxRqst & IntPnd */
+ pch_can_bit_clear(&priv->regs->ifregs[1].mcont,
+ PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_INTPND |
+ PCH_IF_MCONT_TXRQXT);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, mask);
+ }
+}
+
+static void pch_can_reset(struct pch_can_priv *priv)
+{
+ /* write to sw reset register */
+ iowrite32(1, &priv->regs->srst);
+ iowrite32(0, &priv->regs->srst);
+}
+
+static void pch_can_error(struct net_device *ndev, u32 status)
+{
+ struct sk_buff *skb;
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ struct can_frame *cf;
+ u32 errc, lec;
+ struct net_device_stats *stats = &(priv->ndev->stats);
+ enum can_state state = priv->can.state;
+
+ skb = alloc_can_err_skb(ndev, &cf);
+ if (!skb)
+ return;
+
+ if (status & PCH_BUS_OFF) {
+ pch_can_set_tx_all(priv, 0);
+ pch_can_set_rx_all(priv, 0);
+ state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(ndev);
+ }
+
+ errc = ioread32(&priv->regs->errc);
+ /* Warning interrupt. */
+ if (status & PCH_EWARN) {
+ state = CAN_STATE_ERROR_WARNING;
+ priv->can.can_stats.error_warning++;
+ cf->can_id |= CAN_ERR_CRTL;
+ if (((errc & PCH_REC) >> 8) > 96)
+ cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+ if ((errc & PCH_TEC) > 96)
+ cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+ netdev_dbg(ndev,
+ "%s -> Error Counter is more than 96.\n", __func__);
+ }
+ /* Error passive interrupt. */
+ if (status & PCH_EPASSIV) {
+ priv->can.can_stats.error_passive++;
+ state = CAN_STATE_ERROR_PASSIVE;
+ cf->can_id |= CAN_ERR_CRTL;
+ if (errc & PCH_RP)
+ cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+ if ((errc & PCH_TEC) > 127)
+ cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+ netdev_dbg(ndev,
+ "%s -> CAN controller is ERROR PASSIVE .\n", __func__);
+ }
+
+ lec = status & PCH_LEC_ALL;
+ switch (lec) {
+ case PCH_STUF_ERR:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_FORM_ERR:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_ACK_ERR:
+ cf->can_id |= CAN_ERR_ACK;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_BIT1_ERR:
+ case PCH_BIT0_ERR:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_CRC_ERR:
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL;
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+ break;
+ case PCH_LEC_ALL: /* Written by CPU. No error status */
+ break;
+ }
+
+ cf->data[6] = errc & PCH_TEC;
+ cf->data[7] = (errc & PCH_REC) >> 8;
+
+ priv->can.state = state;
+ netif_receive_skb(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static irqreturn_t pch_can_interrupt(int irq, void *dev_id)
+{
+ struct net_device *ndev = (struct net_device *)dev_id;
+ struct pch_can_priv *priv = netdev_priv(ndev);
+
+ if (!pch_can_int_pending(priv))
+ return IRQ_NONE;
+
+ pch_can_set_int_enables(priv, PCH_CAN_NONE);
+ napi_schedule(&priv->napi);
+ return IRQ_HANDLED;
+}
+
+static void pch_fifo_thresh(struct pch_can_priv *priv, int obj_id)
+{
+ if (obj_id < PCH_FIFO_THRESH) {
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL |
+ PCH_CMASK_ARB, &priv->regs->ifregs[0].cmask);
+
+ /* Clearing the Dir bit. */
+ pch_can_bit_clear(&priv->regs->ifregs[0].id2, PCH_ID2_DIR);
+
+ /* Clearing NewDat & IntPnd */
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_INTPND);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id);
+ } else if (obj_id > PCH_FIFO_THRESH) {
+ pch_can_int_clr(priv, obj_id);
+ } else if (obj_id == PCH_FIFO_THRESH) {
+ int cnt;
+ for (cnt = 0; cnt < PCH_FIFO_THRESH; cnt++)
+ pch_can_int_clr(priv, cnt + 1);
+ }
+}
+
+static void pch_can_rx_msg_lost(struct net_device *ndev, int obj_id)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &(priv->ndev->stats);
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ netdev_dbg(priv->ndev, "Msg Obj is overwritten.\n");
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_MSGLOST);
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_id);
+
+ skb = alloc_can_err_skb(ndev, &cf);
+ if (!skb)
+ return;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+
+ netif_receive_skb(skb);
+}
+
+static int pch_can_rx_normal(struct net_device *ndev, u32 obj_num, int quota)
+{
+ u32 reg;
+ canid_t id;
+ int rcv_pkts = 0;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &(priv->ndev->stats);
+ int i;
+ u32 id2;
+ u16 data_reg;
+
+ do {
+ /* Reading the message object from the Message RAM */
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_num);
+
+ /* Reading the MCONT register. */
+ reg = ioread32(&priv->regs->ifregs[0].mcont);
+
+ if (reg & PCH_IF_MCONT_EOB)
+ break;
+
+ /* If MsgLost bit set. */
+ if (reg & PCH_IF_MCONT_MSGLOST) {
+ pch_can_rx_msg_lost(ndev, obj_num);
+ rcv_pkts++;
+ quota--;
+ obj_num++;
+ continue;
+ } else if (!(reg & PCH_IF_MCONT_NEWDAT)) {
+ obj_num++;
+ continue;
+ }
+
+ skb = alloc_can_skb(priv->ndev, &cf);
+ if (!skb) {
+ netdev_err(ndev, "alloc_can_skb Failed\n");
+ return rcv_pkts;
+ }
+
+ /* Get Received data */
+ id2 = ioread32(&priv->regs->ifregs[0].id2);
+ if (id2 & PCH_ID2_XTD) {
+ id = (ioread32(&priv->regs->ifregs[0].id1) & 0xffff);
+ id |= (((id2) & 0x1fff) << 16);
+ cf->can_id = id | CAN_EFF_FLAG;
+ } else {
+ id = (id2 >> 2) & CAN_SFF_MASK;
+ cf->can_id = id;
+ }
+
+ if (id2 & PCH_ID2_DIR)
+ cf->can_id |= CAN_RTR_FLAG;
+
+ cf->can_dlc = get_can_dlc((ioread32(&priv->regs->
+ ifregs[0].mcont)) & 0xF);
+
+ for (i = 0; i < cf->can_dlc; i += 2) {
+ data_reg = ioread16(&priv->regs->ifregs[0].data[i / 2]);
+ cf->data[i] = data_reg;
+ cf->data[i + 1] = data_reg >> 8;
+ }
+
+ netif_receive_skb(skb);
+ rcv_pkts++;
+ stats->rx_packets++;
+ quota--;
+ stats->rx_bytes += cf->can_dlc;
+
+ pch_fifo_thresh(priv, obj_num);
+ obj_num++;
+ } while (quota > 0);
+
+ return rcv_pkts;
+}
+
+static void pch_can_tx_complete(struct net_device *ndev, u32 int_stat)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &(priv->ndev->stats);
+ u32 dlc;
+
+ can_get_echo_skb(ndev, int_stat - PCH_RX_OBJ_END - 1);
+ iowrite32(PCH_CMASK_RX_TX_GET | PCH_CMASK_CLRINTPND,
+ &priv->regs->ifregs[1].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, int_stat);
+ dlc = get_can_dlc(ioread32(&priv->regs->ifregs[1].mcont) &
+ PCH_IF_MCONT_DLC);
+ stats->tx_bytes += dlc;
+ stats->tx_packets++;
+ if (int_stat == PCH_TX_OBJ_END)
+ netif_wake_queue(ndev);
+}
+
+static int pch_can_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *ndev = napi->dev;
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ u32 int_stat;
+ u32 reg_stat;
+ int quota_save = quota;
+
+ int_stat = pch_can_int_pending(priv);
+ if (!int_stat)
+ goto end;
+
+ if (int_stat == PCH_STATUS_INT) {
+ reg_stat = ioread32(&priv->regs->stat);
+
+ if ((reg_stat & (PCH_BUS_OFF | PCH_LEC_ALL)) &&
+ ((reg_stat & PCH_LEC_ALL) != PCH_LEC_ALL)) {
+ pch_can_error(ndev, reg_stat);
+ quota--;
+ }
+
+ if (reg_stat & (PCH_TX_OK | PCH_RX_OK))
+ pch_can_bit_clear(&priv->regs->stat,
+ reg_stat & (PCH_TX_OK | PCH_RX_OK));
+
+ int_stat = pch_can_int_pending(priv);
+ }
+
+ if (quota == 0)
+ goto end;
+
+ if ((int_stat >= PCH_RX_OBJ_START) && (int_stat <= PCH_RX_OBJ_END)) {
+ quota -= pch_can_rx_normal(ndev, int_stat, quota);
+ } else if ((int_stat >= PCH_TX_OBJ_START) &&
+ (int_stat <= PCH_TX_OBJ_END)) {
+ /* Handle transmission interrupt */
+ pch_can_tx_complete(ndev, int_stat);
+ }
+
+end:
+ napi_complete(napi);
+ pch_can_set_int_enables(priv, PCH_CAN_ALL);
+
+ return quota_save - quota;
+}
+
+static int pch_set_bittiming(struct net_device *ndev)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ const struct can_bittiming *bt = &priv->can.bittiming;
+ u32 canbit;
+ u32 bepe;
+
+ /* Setting the CCE bit for accessing the Can Timing register. */
+ pch_can_bit_set(&priv->regs->cont, PCH_CTRL_CCE);
+
+ canbit = (bt->brp - 1) & PCH_MSK_BITT_BRP;
+ canbit |= (bt->sjw - 1) << PCH_BIT_SJW_SHIFT;
+ canbit |= (bt->phase_seg1 + bt->prop_seg - 1) << PCH_BIT_TSEG1_SHIFT;
+ canbit |= (bt->phase_seg2 - 1) << PCH_BIT_TSEG2_SHIFT;
+ bepe = ((bt->brp - 1) & PCH_MSK_BRPE_BRPE) >> PCH_BIT_BRPE_BRPE_SHIFT;
+ iowrite32(canbit, &priv->regs->bitt);
+ iowrite32(bepe, &priv->regs->brpe);
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_CCE);
+
+ return 0;
+}
+
+static void pch_can_start(struct net_device *ndev)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+
+ if (priv->can.state != CAN_STATE_STOPPED)
+ pch_can_reset(priv);
+
+ pch_set_bittiming(ndev);
+ pch_can_set_optmode(priv);
+
+ pch_can_set_tx_all(priv, 1);
+ pch_can_set_rx_all(priv, 1);
+
+ /* Setting the CAN to run mode. */
+ pch_can_set_run_mode(priv, PCH_CAN_RUN);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ return;
+}
+
+static int pch_can_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ int ret = 0;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ pch_can_start(ndev);
+ netif_wake_queue(ndev);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
+static int pch_can_open(struct net_device *ndev)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ int retval;
+
+ /* Regstering the interrupt. */
+ retval = request_irq(priv->dev->irq, pch_can_interrupt, IRQF_SHARED,
+ ndev->name, ndev);
+ if (retval) {
+ netdev_err(ndev, "request_irq failed.\n");
+ goto req_irq_err;
+ }
+
+ /* Open common can device */
+ retval = open_candev(ndev);
+ if (retval) {
+ netdev_err(ndev, "open_candev() failed %d\n", retval);
+ goto err_open_candev;
+ }
+
+ pch_can_init(priv);
+ pch_can_start(ndev);
+ napi_enable(&priv->napi);
+ netif_start_queue(ndev);
+
+ return 0;
+
+err_open_candev:
+ free_irq(priv->dev->irq, ndev);
+req_irq_err:
+ pch_can_release(priv);
+
+ return retval;
+}
+
+static int pch_close(struct net_device *ndev)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+ pch_can_release(priv);
+ free_irq(priv->dev->irq, ndev);
+ close_candev(ndev);
+ priv->can.state = CAN_STATE_STOPPED;
+ return 0;
+}
+
+static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct pch_can_priv *priv = netdev_priv(ndev);
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ int tx_obj_no;
+ int i;
+ u32 id2;
+
+ if (can_dropped_invalid_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ tx_obj_no = priv->tx_obj;
+ if (priv->tx_obj == PCH_TX_OBJ_END) {
+ if (ioread32(&priv->regs->treq2) & PCH_TREQ2_TX_MASK)
+ netif_stop_queue(ndev);
+
+ priv->tx_obj = PCH_TX_OBJ_START;
+ } else {
+ priv->tx_obj++;
+ }
+
+ /* Setting the CMASK register. */
+ pch_can_bit_set(&priv->regs->ifregs[1].cmask, PCH_CMASK_ALL);
+
+ /* If ID extended is set. */
+ if (cf->can_id & CAN_EFF_FLAG) {
+ iowrite32(cf->can_id & 0xffff, &priv->regs->ifregs[1].id1);
+ id2 = ((cf->can_id >> 16) & 0x1fff) | PCH_ID2_XTD;
+ } else {
+ iowrite32(0, &priv->regs->ifregs[1].id1);
+ id2 = (cf->can_id & CAN_SFF_MASK) << 2;
+ }
+
+ id2 |= PCH_ID_MSGVAL;
+
+ /* If remote frame has to be transmitted.. */
+ if (!(cf->can_id & CAN_RTR_FLAG))
+ id2 |= PCH_ID2_DIR;
+
+ iowrite32(id2, &priv->regs->ifregs[1].id2);
+
+ /* Copy data to register */
+ for (i = 0; i < cf->can_dlc; i += 2) {
+ iowrite16(cf->data[i] | (cf->data[i + 1] << 8),
+ &priv->regs->ifregs[1].data[i / 2]);
+ }
+
+ can_put_echo_skb(skb, ndev, tx_obj_no - PCH_RX_OBJ_END - 1);
+
+ /* Set the size of the data. Update if2_mcont */
+ iowrite32(cf->can_dlc | PCH_IF_MCONT_NEWDAT | PCH_IF_MCONT_TXRQXT |
+ PCH_IF_MCONT_TXIE, &priv->regs->ifregs[1].mcont);
+
+ pch_can_rw_msg_obj(&priv->regs->ifregs[1].creq, tx_obj_no);
+
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops pch_can_netdev_ops = {
+ .ndo_open = pch_can_open,
+ .ndo_stop = pch_close,
+ .ndo_start_xmit = pch_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static void pch_can_remove(struct pci_dev *pdev)
+{
+ struct net_device *ndev = pci_get_drvdata(pdev);
+ struct pch_can_priv *priv = netdev_priv(ndev);
+
+ unregister_candev(priv->ndev);
+ if (priv->use_msi)
+ pci_disable_msi(priv->dev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pch_can_reset(priv);
+ pci_iounmap(pdev, priv->regs);
+ free_candev(priv->ndev);
+}
+
+#ifdef CONFIG_PM
+static void pch_can_set_int_custom(struct pch_can_priv *priv)
+{
+ /* Clearing the IE, SIE and EIE bits of Can control register. */
+ pch_can_bit_clear(&priv->regs->cont, PCH_CTRL_IE_SIE_EIE);
+
+ /* Appropriately setting them. */
+ pch_can_bit_set(&priv->regs->cont,
+ ((priv->int_enables & PCH_MSK_CTRL_IE_SIE_EIE) << 1));
+}
+
+/* This function retrieves interrupt enabled for the CAN device. */
+static u32 pch_can_get_int_enables(struct pch_can_priv *priv)
+{
+ /* Obtaining the status of IE, SIE and EIE interrupt bits. */
+ return (ioread32(&priv->regs->cont) & PCH_CTRL_IE_SIE_EIE) >> 1;
+}
+
+static u32 pch_can_get_rxtx_ir(struct pch_can_priv *priv, u32 buff_num,
+ enum pch_ifreg dir)
+{
+ u32 ie, enable;
+
+ if (dir)
+ ie = PCH_IF_MCONT_RXIE;
+ else
+ ie = PCH_IF_MCONT_TXIE;
+
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[dir].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[dir].creq, buff_num);
+
+ if (((ioread32(&priv->regs->ifregs[dir].id2)) & PCH_ID_MSGVAL) &&
+ ((ioread32(&priv->regs->ifregs[dir].mcont)) & ie))
+ enable = 1;
+ else
+ enable = 0;
+
+ return enable;
+}
+
+static void pch_can_set_rx_buffer_link(struct pch_can_priv *priv,
+ u32 buffer_num, int set)
+{
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
+ iowrite32(PCH_CMASK_RDWR | PCH_CMASK_CTRL,
+ &priv->regs->ifregs[0].cmask);
+ if (set)
+ pch_can_bit_clear(&priv->regs->ifregs[0].mcont,
+ PCH_IF_MCONT_EOB);
+ else
+ pch_can_bit_set(&priv->regs->ifregs[0].mcont, PCH_IF_MCONT_EOB);
+
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
+}
+
+static u32 pch_can_get_rx_buffer_link(struct pch_can_priv *priv, u32 buffer_num)
+{
+ u32 link;
+
+ iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
+ pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, buffer_num);
+
+ if (ioread32(&priv->regs->ifregs[0].mcont) & PCH_IF_MCONT_EOB)
+ link = 0;
+ else
+ link = 1;
+ return link;
+}
+
+static int pch_can_get_buffer_status(struct pch_can_priv *priv)
+{
+ return (ioread32(&priv->regs->treq1) & 0xffff) |
+ (ioread32(&priv->regs->treq2) << 16);
+}
+
+static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ int i;
+ int retval;
+ u32 buf_stat; /* Variable for reading the transmit buffer status. */
+ int counter = PCH_COUNTER_LIMIT;
+
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct pch_can_priv *priv = netdev_priv(dev);
+
+ /* Stop the CAN controller */
+ pch_can_set_run_mode(priv, PCH_CAN_STOP);
+
+ /* Indicate that we are aboutto/in suspend */
+ priv->can.state = CAN_STATE_STOPPED;
+
+ /* Waiting for all transmission to complete. */
+ while (counter) {
+ buf_stat = pch_can_get_buffer_status(priv);
+ if (!buf_stat)
+ break;
+ counter--;
+ udelay(1);
+ }
+ if (!counter)
+ dev_err(&pdev->dev, "%s -> Transmission time out.\n", __func__);
+
+ /* Save interrupt configuration and then disable them */
+ priv->int_enables = pch_can_get_int_enables(priv);
+ pch_can_set_int_enables(priv, PCH_CAN_DISABLE);
+
+ /* Save Tx buffer enable state */
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++)
+ priv->tx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i,
+ PCH_TX_IFREG);
+
+ /* Disable all Transmit buffers */
+ pch_can_set_tx_all(priv, 0);
+
+ /* Save Rx buffer enable state */
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) {
+ priv->rx_enable[i - 1] = pch_can_get_rxtx_ir(priv, i,
+ PCH_RX_IFREG);
+ priv->rx_link[i - 1] = pch_can_get_rx_buffer_link(priv, i);
+ }
+
+ /* Disable all Receive buffers */
+ pch_can_set_rx_all(priv, 0);
+ retval = pci_save_state(pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "pci_save_state failed.\n");
+ } else {
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ }
+
+ return retval;
+}
+
+static int pch_can_resume(struct pci_dev *pdev)
+{
+ int i;
+ int retval;
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct pch_can_priv *priv = netdev_priv(dev);
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "pci_enable_device failed.\n");
+ return retval;
+ }
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ /* Disabling all interrupts. */
+ pch_can_set_int_enables(priv, PCH_CAN_DISABLE);
+
+ /* Setting the CAN device in Stop Mode. */
+ pch_can_set_run_mode(priv, PCH_CAN_STOP);
+
+ /* Configuring the transmit and receive buffers. */
+ pch_can_config_rx_tx_buffers(priv);
+
+ /* Restore the CAN state */
+ pch_set_bittiming(dev);
+
+ /* Listen/Active */
+ pch_can_set_optmode(priv);
+
+ /* Enabling the transmit buffer. */
+ for (i = PCH_TX_OBJ_START; i <= PCH_TX_OBJ_END; i++)
+ pch_can_set_rxtx(priv, i, priv->tx_enable[i - 1], PCH_TX_IFREG);
+
+ /* Configuring the receive buffer and enabling them. */
+ for (i = PCH_RX_OBJ_START; i <= PCH_RX_OBJ_END; i++) {
+ /* Restore buffer link */
+ pch_can_set_rx_buffer_link(priv, i, priv->rx_link[i - 1]);
+
+ /* Restore buffer enables */
+ pch_can_set_rxtx(priv, i, priv->rx_enable[i - 1], PCH_RX_IFREG);
+ }
+
+ /* Enable CAN Interrupts */
+ pch_can_set_int_custom(priv);
+
+ /* Restore Run Mode */
+ pch_can_set_run_mode(priv, PCH_CAN_RUN);
+
+ return retval;
+}
+#else
+#define pch_can_suspend NULL
+#define pch_can_resume NULL
+#endif
+
+static int pch_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct pch_can_priv *priv = netdev_priv(dev);
+ u32 errc = ioread32(&priv->regs->errc);
+
+ bec->txerr = errc & PCH_TEC;
+ bec->rxerr = (errc & PCH_REC) >> 8;
+
+ return 0;
+}
+
+static int pch_can_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct net_device *ndev;
+ struct pch_can_priv *priv;
+ int rc;
+ void __iomem *addr;
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ dev_err(&pdev->dev, "Failed pci_enable_device %d\n", rc);
+ goto probe_exit_endev;
+ }
+
+ rc = pci_request_regions(pdev, KBUILD_MODNAME);
+ if (rc) {
+ dev_err(&pdev->dev, "Failed pci_request_regions %d\n", rc);
+ goto probe_exit_pcireq;
+ }
+
+ addr = pci_iomap(pdev, 1, 0);
+ if (!addr) {
+ rc = -EIO;
+ dev_err(&pdev->dev, "Failed pci_iomap\n");
+ goto probe_exit_ipmap;
+ }
+
+ ndev = alloc_candev(sizeof(struct pch_can_priv), PCH_TX_OBJ_END);
+ if (!ndev) {
+ rc = -ENOMEM;
+ dev_err(&pdev->dev, "Failed alloc_candev\n");
+ goto probe_exit_alloc_candev;
+ }
+
+ priv = netdev_priv(ndev);
+ priv->ndev = ndev;
+ priv->regs = addr;
+ priv->dev = pdev;
+ priv->can.bittiming_const = &pch_can_bittiming_const;
+ priv->can.do_set_mode = pch_can_do_set_mode;
+ priv->can.do_get_berr_counter = pch_can_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_LOOPBACK;
+ priv->tx_obj = PCH_TX_OBJ_START; /* Point head of Tx Obj */
+
+ ndev->irq = pdev->irq;
+ ndev->flags |= IFF_ECHO;
+
+ pci_set_drvdata(pdev, ndev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ ndev->netdev_ops = &pch_can_netdev_ops;
+ priv->can.clock.freq = PCH_CAN_CLK; /* Hz */
+
+ netif_napi_add(ndev, &priv->napi, pch_can_poll, PCH_RX_OBJ_END);
+
+ rc = pci_enable_msi(priv->dev);
+ if (rc) {
+ netdev_err(ndev, "PCH CAN opened without MSI\n");
+ priv->use_msi = 0;
+ } else {
+ netdev_err(ndev, "PCH CAN opened with MSI\n");
+ pci_set_master(pdev);
+ priv->use_msi = 1;
+ }
+
+ rc = register_candev(ndev);
+ if (rc) {
+ dev_err(&pdev->dev, "Failed register_candev %d\n", rc);
+ goto probe_exit_reg_candev;
+ }
+
+ return 0;
+
+probe_exit_reg_candev:
+ if (priv->use_msi)
+ pci_disable_msi(priv->dev);
+ free_candev(ndev);
+probe_exit_alloc_candev:
+ pci_iounmap(pdev, addr);
+probe_exit_ipmap:
+ pci_release_regions(pdev);
+probe_exit_pcireq:
+ pci_disable_device(pdev);
+probe_exit_endev:
+ return rc;
+}
+
+static struct pci_driver pch_can_pci_driver = {
+ .name = "pch_can",
+ .id_table = pch_pci_tbl,
+ .probe = pch_can_probe,
+ .remove = pch_can_remove,
+ .suspend = pch_can_suspend,
+ .resume = pch_can_resume,
+};
+
+module_pci_driver(pch_can_pci_driver);
+
+MODULE_DESCRIPTION("Intel EG20T PCH CAN(Controller Area Network) Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.94");
diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c
new file mode 100644
index 00000000000..5268d216ecf
--- /dev/null
+++ b/drivers/net/can/rcar_can.c
@@ -0,0 +1,876 @@
+/* Renesas R-Car CAN device driver
+ *
+ * Copyright (C) 2013 Cogent Embedded, Inc. <source@cogentembedded.com>
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/can/led.h>
+#include <linux/can/dev.h>
+#include <linux/clk.h>
+#include <linux/can/platform/rcar_can.h>
+
+#define RCAR_CAN_DRV_NAME "rcar_can"
+
+/* Mailbox configuration:
+ * mailbox 60 - 63 - Rx FIFO mailboxes
+ * mailbox 56 - 59 - Tx FIFO mailboxes
+ * non-FIFO mailboxes are not used
+ */
+#define RCAR_CAN_N_MBX 64 /* Number of mailboxes in non-FIFO mode */
+#define RCAR_CAN_RX_FIFO_MBX 60 /* Mailbox - window to Rx FIFO */
+#define RCAR_CAN_TX_FIFO_MBX 56 /* Mailbox - window to Tx FIFO */
+#define RCAR_CAN_FIFO_DEPTH 4
+
+/* Mailbox registers structure */
+struct rcar_can_mbox_regs {
+ u32 id; /* IDE and RTR bits, SID and EID */
+ u8 stub; /* Not used */
+ u8 dlc; /* Data Length Code - bits [0..3] */
+ u8 data[8]; /* Data Bytes */
+ u8 tsh; /* Time Stamp Higher Byte */
+ u8 tsl; /* Time Stamp Lower Byte */
+};
+
+struct rcar_can_regs {
+ struct rcar_can_mbox_regs mb[RCAR_CAN_N_MBX]; /* Mailbox registers */
+ u32 mkr_2_9[8]; /* Mask Registers 2-9 */
+ u32 fidcr[2]; /* FIFO Received ID Compare Register */
+ u32 mkivlr1; /* Mask Invalid Register 1 */
+ u32 mier1; /* Mailbox Interrupt Enable Register 1 */
+ u32 mkr_0_1[2]; /* Mask Registers 0-1 */
+ u32 mkivlr0; /* Mask Invalid Register 0*/
+ u32 mier0; /* Mailbox Interrupt Enable Register 0 */
+ u8 pad_440[0x3c0];
+ u8 mctl[64]; /* Message Control Registers */
+ u16 ctlr; /* Control Register */
+ u16 str; /* Status register */
+ u8 bcr[3]; /* Bit Configuration Register */
+ u8 clkr; /* Clock Select Register */
+ u8 rfcr; /* Receive FIFO Control Register */
+ u8 rfpcr; /* Receive FIFO Pointer Control Register */
+ u8 tfcr; /* Transmit FIFO Control Register */
+ u8 tfpcr; /* Transmit FIFO Pointer Control Register */
+ u8 eier; /* Error Interrupt Enable Register */
+ u8 eifr; /* Error Interrupt Factor Judge Register */
+ u8 recr; /* Receive Error Count Register */
+ u8 tecr; /* Transmit Error Count Register */
+ u8 ecsr; /* Error Code Store Register */
+ u8 cssr; /* Channel Search Support Register */
+ u8 mssr; /* Mailbox Search Status Register */
+ u8 msmr; /* Mailbox Search Mode Register */
+ u16 tsr; /* Time Stamp Register */
+ u8 afsr; /* Acceptance Filter Support Register */
+ u8 pad_857;
+ u8 tcr; /* Test Control Register */
+ u8 pad_859[7];
+ u8 ier; /* Interrupt Enable Register */
+ u8 isr; /* Interrupt Status Register */
+ u8 pad_862;
+ u8 mbsmr; /* Mailbox Search Mask Register */
+};
+
+struct rcar_can_priv {
+ struct can_priv can; /* Must be the first member! */
+ struct net_device *ndev;
+ struct napi_struct napi;
+ struct rcar_can_regs __iomem *regs;
+ struct clk *clk;
+ u8 tx_dlc[RCAR_CAN_FIFO_DEPTH];
+ u32 tx_head;
+ u32 tx_tail;
+ u8 clock_select;
+ u8 ier;
+};
+
+static const struct can_bittiming_const rcar_can_bittiming_const = {
+ .name = RCAR_CAN_DRV_NAME,
+ .tseg1_min = 4,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 1024,
+ .brp_inc = 1,
+};
+
+/* Control Register bits */
+#define RCAR_CAN_CTLR_BOM (3 << 11) /* Bus-Off Recovery Mode Bits */
+#define RCAR_CAN_CTLR_BOM_ENT (1 << 11) /* Entry to halt mode */
+ /* at bus-off entry */
+#define RCAR_CAN_CTLR_SLPM (1 << 10)
+#define RCAR_CAN_CTLR_CANM (3 << 8) /* Operating Mode Select Bit */
+#define RCAR_CAN_CTLR_CANM_HALT (1 << 9)
+#define RCAR_CAN_CTLR_CANM_RESET (1 << 8)
+#define RCAR_CAN_CTLR_CANM_FORCE_RESET (3 << 8)
+#define RCAR_CAN_CTLR_MLM (1 << 3) /* Message Lost Mode Select */
+#define RCAR_CAN_CTLR_IDFM (3 << 1) /* ID Format Mode Select Bits */
+#define RCAR_CAN_CTLR_IDFM_MIXED (1 << 2) /* Mixed ID mode */
+#define RCAR_CAN_CTLR_MBM (1 << 0) /* Mailbox Mode select */
+
+/* Status Register bits */
+#define RCAR_CAN_STR_RSTST (1 << 8) /* Reset Status Bit */
+
+/* FIFO Received ID Compare Registers 0 and 1 bits */
+#define RCAR_CAN_FIDCR_IDE (1 << 31) /* ID Extension Bit */
+#define RCAR_CAN_FIDCR_RTR (1 << 30) /* Remote Transmission Request Bit */
+
+/* Receive FIFO Control Register bits */
+#define RCAR_CAN_RFCR_RFEST (1 << 7) /* Receive FIFO Empty Status Flag */
+#define RCAR_CAN_RFCR_RFE (1 << 0) /* Receive FIFO Enable */
+
+/* Transmit FIFO Control Register bits */
+#define RCAR_CAN_TFCR_TFUST (7 << 1) /* Transmit FIFO Unsent Message */
+ /* Number Status Bits */
+#define RCAR_CAN_TFCR_TFUST_SHIFT 1 /* Offset of Transmit FIFO Unsent */
+ /* Message Number Status Bits */
+#define RCAR_CAN_TFCR_TFE (1 << 0) /* Transmit FIFO Enable */
+
+#define RCAR_CAN_N_RX_MKREGS1 2 /* Number of mask registers */
+ /* for Rx mailboxes 0-31 */
+#define RCAR_CAN_N_RX_MKREGS2 8
+
+/* Bit Configuration Register settings */
+#define RCAR_CAN_BCR_TSEG1(x) (((x) & 0x0f) << 20)
+#define RCAR_CAN_BCR_BPR(x) (((x) & 0x3ff) << 8)
+#define RCAR_CAN_BCR_SJW(x) (((x) & 0x3) << 4)
+#define RCAR_CAN_BCR_TSEG2(x) ((x) & 0x07)
+
+/* Mailbox and Mask Registers bits */
+#define RCAR_CAN_IDE (1 << 31)
+#define RCAR_CAN_RTR (1 << 30)
+#define RCAR_CAN_SID_SHIFT 18
+
+/* Mailbox Interrupt Enable Register 1 bits */
+#define RCAR_CAN_MIER1_RXFIE (1 << 28) /* Receive FIFO Interrupt Enable */
+#define RCAR_CAN_MIER1_TXFIE (1 << 24) /* Transmit FIFO Interrupt Enable */
+
+/* Interrupt Enable Register bits */
+#define RCAR_CAN_IER_ERSIE (1 << 5) /* Error (ERS) Interrupt Enable Bit */
+#define RCAR_CAN_IER_RXFIE (1 << 4) /* Reception FIFO Interrupt */
+ /* Enable Bit */
+#define RCAR_CAN_IER_TXFIE (1 << 3) /* Transmission FIFO Interrupt */
+ /* Enable Bit */
+/* Interrupt Status Register bits */
+#define RCAR_CAN_ISR_ERSF (1 << 5) /* Error (ERS) Interrupt Status Bit */
+#define RCAR_CAN_ISR_RXFF (1 << 4) /* Reception FIFO Interrupt */
+ /* Status Bit */
+#define RCAR_CAN_ISR_TXFF (1 << 3) /* Transmission FIFO Interrupt */
+ /* Status Bit */
+
+/* Error Interrupt Enable Register bits */
+#define RCAR_CAN_EIER_BLIE (1 << 7) /* Bus Lock Interrupt Enable */
+#define RCAR_CAN_EIER_OLIE (1 << 6) /* Overload Frame Transmit */
+ /* Interrupt Enable */
+#define RCAR_CAN_EIER_ORIE (1 << 5) /* Receive Overrun Interrupt Enable */
+#define RCAR_CAN_EIER_BORIE (1 << 4) /* Bus-Off Recovery Interrupt Enable */
+#define RCAR_CAN_EIER_BOEIE (1 << 3) /* Bus-Off Entry Interrupt Enable */
+#define RCAR_CAN_EIER_EPIE (1 << 2) /* Error Passive Interrupt Enable */
+#define RCAR_CAN_EIER_EWIE (1 << 1) /* Error Warning Interrupt Enable */
+#define RCAR_CAN_EIER_BEIE (1 << 0) /* Bus Error Interrupt Enable */
+
+/* Error Interrupt Factor Judge Register bits */
+#define RCAR_CAN_EIFR_BLIF (1 << 7) /* Bus Lock Detect Flag */
+#define RCAR_CAN_EIFR_OLIF (1 << 6) /* Overload Frame Transmission */
+ /* Detect Flag */
+#define RCAR_CAN_EIFR_ORIF (1 << 5) /* Receive Overrun Detect Flag */
+#define RCAR_CAN_EIFR_BORIF (1 << 4) /* Bus-Off Recovery Detect Flag */
+#define RCAR_CAN_EIFR_BOEIF (1 << 3) /* Bus-Off Entry Detect Flag */
+#define RCAR_CAN_EIFR_EPIF (1 << 2) /* Error Passive Detect Flag */
+#define RCAR_CAN_EIFR_EWIF (1 << 1) /* Error Warning Detect Flag */
+#define RCAR_CAN_EIFR_BEIF (1 << 0) /* Bus Error Detect Flag */
+
+/* Error Code Store Register bits */
+#define RCAR_CAN_ECSR_EDPM (1 << 7) /* Error Display Mode Select Bit */
+#define RCAR_CAN_ECSR_ADEF (1 << 6) /* ACK Delimiter Error Flag */
+#define RCAR_CAN_ECSR_BE0F (1 << 5) /* Bit Error (dominant) Flag */
+#define RCAR_CAN_ECSR_BE1F (1 << 4) /* Bit Error (recessive) Flag */
+#define RCAR_CAN_ECSR_CEF (1 << 3) /* CRC Error Flag */
+#define RCAR_CAN_ECSR_AEF (1 << 2) /* ACK Error Flag */
+#define RCAR_CAN_ECSR_FEF (1 << 1) /* Form Error Flag */
+#define RCAR_CAN_ECSR_SEF (1 << 0) /* Stuff Error Flag */
+
+#define RCAR_CAN_NAPI_WEIGHT 4
+#define MAX_STR_READS 0x100
+
+static void tx_failure_cleanup(struct net_device *ndev)
+{
+ int i;
+
+ for (i = 0; i < RCAR_CAN_FIFO_DEPTH; i++)
+ can_free_echo_skb(ndev, i);
+}
+
+static void rcar_can_error(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u8 eifr, txerr = 0, rxerr = 0;
+
+ /* Propagate the error condition to the CAN stack */
+ skb = alloc_can_err_skb(ndev, &cf);
+
+ eifr = readb(&priv->regs->eifr);
+ if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) {
+ txerr = readb(&priv->regs->tecr);
+ rxerr = readb(&priv->regs->recr);
+ if (skb) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+ }
+ if (eifr & RCAR_CAN_EIFR_BEIF) {
+ int rx_errors = 0, tx_errors = 0;
+ u8 ecsr;
+
+ netdev_dbg(priv->ndev, "Bus error interrupt:\n");
+ if (skb) {
+ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_UNSPEC;
+ }
+ ecsr = readb(&priv->regs->ecsr);
+ if (ecsr & RCAR_CAN_ECSR_ADEF) {
+ netdev_dbg(priv->ndev, "ACK Delimiter Error\n");
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_ADEF, &priv->regs->ecsr);
+ if (skb)
+ cf->data[3] |= CAN_ERR_PROT_LOC_ACK_DEL;
+ }
+ if (ecsr & RCAR_CAN_ECSR_BE0F) {
+ netdev_dbg(priv->ndev, "Bit Error (dominant)\n");
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_BE0F, &priv->regs->ecsr);
+ if (skb)
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ }
+ if (ecsr & RCAR_CAN_ECSR_BE1F) {
+ netdev_dbg(priv->ndev, "Bit Error (recessive)\n");
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_BE1F, &priv->regs->ecsr);
+ if (skb)
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ }
+ if (ecsr & RCAR_CAN_ECSR_CEF) {
+ netdev_dbg(priv->ndev, "CRC Error\n");
+ rx_errors++;
+ writeb(~RCAR_CAN_ECSR_CEF, &priv->regs->ecsr);
+ if (skb)
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+ }
+ if (ecsr & RCAR_CAN_ECSR_AEF) {
+ netdev_dbg(priv->ndev, "ACK Error\n");
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_AEF, &priv->regs->ecsr);
+ if (skb) {
+ cf->can_id |= CAN_ERR_ACK;
+ cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+ }
+ }
+ if (ecsr & RCAR_CAN_ECSR_FEF) {
+ netdev_dbg(priv->ndev, "Form Error\n");
+ rx_errors++;
+ writeb(~RCAR_CAN_ECSR_FEF, &priv->regs->ecsr);
+ if (skb)
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ }
+ if (ecsr & RCAR_CAN_ECSR_SEF) {
+ netdev_dbg(priv->ndev, "Stuff Error\n");
+ rx_errors++;
+ writeb(~RCAR_CAN_ECSR_SEF, &priv->regs->ecsr);
+ if (skb)
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ }
+
+ priv->can.can_stats.bus_error++;
+ ndev->stats.rx_errors += rx_errors;
+ ndev->stats.tx_errors += tx_errors;
+ writeb(~RCAR_CAN_EIFR_BEIF, &priv->regs->eifr);
+ }
+ if (eifr & RCAR_CAN_EIFR_EWIF) {
+ netdev_dbg(priv->ndev, "Error warning interrupt\n");
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ priv->can.can_stats.error_warning++;
+ /* Clear interrupt condition */
+ writeb(~RCAR_CAN_EIFR_EWIF, &priv->regs->eifr);
+ if (skb)
+ cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ }
+ if (eifr & RCAR_CAN_EIFR_EPIF) {
+ netdev_dbg(priv->ndev, "Error passive interrupt\n");
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ priv->can.can_stats.error_passive++;
+ /* Clear interrupt condition */
+ writeb(~RCAR_CAN_EIFR_EPIF, &priv->regs->eifr);
+ if (skb)
+ cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ if (eifr & RCAR_CAN_EIFR_BOEIF) {
+ netdev_dbg(priv->ndev, "Bus-off entry interrupt\n");
+ tx_failure_cleanup(ndev);
+ priv->ier = RCAR_CAN_IER_ERSIE;
+ writeb(priv->ier, &priv->regs->ier);
+ priv->can.state = CAN_STATE_BUS_OFF;
+ /* Clear interrupt condition */
+ writeb(~RCAR_CAN_EIFR_BOEIF, &priv->regs->eifr);
+ can_bus_off(ndev);
+ if (skb)
+ cf->can_id |= CAN_ERR_BUSOFF;
+ }
+ if (eifr & RCAR_CAN_EIFR_ORIF) {
+ netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
+ ndev->stats.rx_over_errors++;
+ ndev->stats.rx_errors++;
+ writeb(~RCAR_CAN_EIFR_ORIF, &priv->regs->eifr);
+ if (skb) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ }
+ }
+ if (eifr & RCAR_CAN_EIFR_OLIF) {
+ netdev_dbg(priv->ndev,
+ "Overload Frame Transmission error interrupt\n");
+ ndev->stats.rx_over_errors++;
+ ndev->stats.rx_errors++;
+ writeb(~RCAR_CAN_EIFR_OLIF, &priv->regs->eifr);
+ if (skb) {
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
+ }
+ }
+
+ if (skb) {
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ netif_rx(skb);
+ }
+}
+
+static void rcar_can_tx_done(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ u8 isr;
+
+ while (1) {
+ u8 unsent = readb(&priv->regs->tfcr);
+
+ unsent = (unsent & RCAR_CAN_TFCR_TFUST) >>
+ RCAR_CAN_TFCR_TFUST_SHIFT;
+ if (priv->tx_head - priv->tx_tail <= unsent)
+ break;
+ stats->tx_packets++;
+ stats->tx_bytes += priv->tx_dlc[priv->tx_tail %
+ RCAR_CAN_FIFO_DEPTH];
+ priv->tx_dlc[priv->tx_tail % RCAR_CAN_FIFO_DEPTH] = 0;
+ can_get_echo_skb(ndev, priv->tx_tail % RCAR_CAN_FIFO_DEPTH);
+ priv->tx_tail++;
+ netif_wake_queue(ndev);
+ }
+ /* Clear interrupt */
+ isr = readb(&priv->regs->isr);
+ writeb(isr & ~RCAR_CAN_ISR_TXFF, &priv->regs->isr);
+ can_led_event(ndev, CAN_LED_EVENT_TX);
+}
+
+static irqreturn_t rcar_can_interrupt(int irq, void *dev_id)
+{
+ struct net_device *ndev = dev_id;
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u8 isr;
+
+ isr = readb(&priv->regs->isr);
+ if (!(isr & priv->ier))
+ return IRQ_NONE;
+
+ if (isr & RCAR_CAN_ISR_ERSF)
+ rcar_can_error(ndev);
+
+ if (isr & RCAR_CAN_ISR_TXFF)
+ rcar_can_tx_done(ndev);
+
+ if (isr & RCAR_CAN_ISR_RXFF) {
+ if (napi_schedule_prep(&priv->napi)) {
+ /* Disable Rx FIFO interrupts */
+ priv->ier &= ~RCAR_CAN_IER_RXFIE;
+ writeb(priv->ier, &priv->regs->ier);
+ __napi_schedule(&priv->napi);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void rcar_can_set_bittiming(struct net_device *dev)
+{
+ struct rcar_can_priv *priv = netdev_priv(dev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u32 bcr;
+
+ bcr = RCAR_CAN_BCR_TSEG1(bt->phase_seg1 + bt->prop_seg - 1) |
+ RCAR_CAN_BCR_BPR(bt->brp - 1) | RCAR_CAN_BCR_SJW(bt->sjw - 1) |
+ RCAR_CAN_BCR_TSEG2(bt->phase_seg2 - 1);
+ /* Don't overwrite CLKR with 32-bit BCR access; CLKR has 8-bit access.
+ * All the registers are big-endian but they get byte-swapped on 32-bit
+ * read/write (but not on 8-bit, contrary to the manuals)...
+ */
+ writel((bcr << 8) | priv->clock_select, &priv->regs->bcr);
+}
+
+static void rcar_can_start(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+ int i;
+
+ /* Set controller to known mode:
+ * - FIFO mailbox mode
+ * - accept all messages
+ * - overrun mode
+ * CAN is in sleep mode after MCU hardware or software reset.
+ */
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr &= ~RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ /* Go to reset mode */
+ ctlr |= RCAR_CAN_CTLR_CANM_FORCE_RESET;
+ writew(ctlr, &priv->regs->ctlr);
+ for (i = 0; i < MAX_STR_READS; i++) {
+ if (readw(&priv->regs->str) & RCAR_CAN_STR_RSTST)
+ break;
+ }
+ rcar_can_set_bittiming(ndev);
+ ctlr |= RCAR_CAN_CTLR_IDFM_MIXED; /* Select mixed ID mode */
+ ctlr |= RCAR_CAN_CTLR_BOM_ENT; /* Entry to halt mode automatically */
+ /* at bus-off */
+ ctlr |= RCAR_CAN_CTLR_MBM; /* Select FIFO mailbox mode */
+ ctlr |= RCAR_CAN_CTLR_MLM; /* Overrun mode */
+ writew(ctlr, &priv->regs->ctlr);
+
+ /* Accept all SID and EID */
+ writel(0, &priv->regs->mkr_2_9[6]);
+ writel(0, &priv->regs->mkr_2_9[7]);
+ /* In FIFO mailbox mode, write "0" to bits 24 to 31 */
+ writel(0, &priv->regs->mkivlr1);
+ /* Accept all frames */
+ writel(0, &priv->regs->fidcr[0]);
+ writel(RCAR_CAN_FIDCR_IDE | RCAR_CAN_FIDCR_RTR, &priv->regs->fidcr[1]);
+ /* Enable and configure FIFO mailbox interrupts */
+ writel(RCAR_CAN_MIER1_RXFIE | RCAR_CAN_MIER1_TXFIE, &priv->regs->mier1);
+
+ priv->ier = RCAR_CAN_IER_ERSIE | RCAR_CAN_IER_RXFIE |
+ RCAR_CAN_IER_TXFIE;
+ writeb(priv->ier, &priv->regs->ier);
+
+ /* Accumulate error codes */
+ writeb(RCAR_CAN_ECSR_EDPM, &priv->regs->ecsr);
+ /* Enable error interrupts */
+ writeb(RCAR_CAN_EIER_EWIE | RCAR_CAN_EIER_EPIE | RCAR_CAN_EIER_BOEIE |
+ (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING ?
+ RCAR_CAN_EIER_BEIE : 0) | RCAR_CAN_EIER_ORIE |
+ RCAR_CAN_EIER_OLIE, &priv->regs->eier);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ /* Go to operation mode */
+ writew(ctlr & ~RCAR_CAN_CTLR_CANM, &priv->regs->ctlr);
+ for (i = 0; i < MAX_STR_READS; i++) {
+ if (!(readw(&priv->regs->str) & RCAR_CAN_STR_RSTST))
+ break;
+ }
+ /* Enable Rx and Tx FIFO */
+ writeb(RCAR_CAN_RFCR_RFE, &priv->regs->rfcr);
+ writeb(RCAR_CAN_TFCR_TFE, &priv->regs->tfcr);
+}
+
+static int rcar_can_open(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ int err;
+
+ err = clk_prepare_enable(priv->clk);
+ if (err) {
+ netdev_err(ndev, "clk_prepare_enable() failed, error %d\n",
+ err);
+ goto out;
+ }
+ err = open_candev(ndev);
+ if (err) {
+ netdev_err(ndev, "open_candev() failed, error %d\n", err);
+ goto out_clock;
+ }
+ napi_enable(&priv->napi);
+ err = request_irq(ndev->irq, rcar_can_interrupt, 0, ndev->name, ndev);
+ if (err) {
+ netdev_err(ndev, "error requesting interrupt %x\n", ndev->irq);
+ goto out_close;
+ }
+ can_led_event(ndev, CAN_LED_EVENT_OPEN);
+ rcar_can_start(ndev);
+ netif_start_queue(ndev);
+ return 0;
+out_close:
+ napi_disable(&priv->napi);
+ close_candev(ndev);
+out_clock:
+ clk_disable_unprepare(priv->clk);
+out:
+ return err;
+}
+
+static void rcar_can_stop(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+ int i;
+
+ /* Go to (force) reset mode */
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr |= RCAR_CAN_CTLR_CANM_FORCE_RESET;
+ writew(ctlr, &priv->regs->ctlr);
+ for (i = 0; i < MAX_STR_READS; i++) {
+ if (readw(&priv->regs->str) & RCAR_CAN_STR_RSTST)
+ break;
+ }
+ writel(0, &priv->regs->mier0);
+ writel(0, &priv->regs->mier1);
+ writeb(0, &priv->regs->ier);
+ writeb(0, &priv->regs->eier);
+ /* Go to sleep mode */
+ ctlr |= RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ priv->can.state = CAN_STATE_STOPPED;
+}
+
+static int rcar_can_close(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ rcar_can_stop(ndev);
+ free_irq(ndev->irq, ndev);
+ napi_disable(&priv->napi);
+ clk_disable_unprepare(priv->clk);
+ close_candev(ndev);
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
+ return 0;
+}
+
+static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb,
+ struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 data, i;
+
+ if (can_dropped_invalid_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */
+ data = (cf->can_id & CAN_EFF_MASK) | RCAR_CAN_IDE;
+ else /* Standard frame format */
+ data = (cf->can_id & CAN_SFF_MASK) << RCAR_CAN_SID_SHIFT;
+
+ if (cf->can_id & CAN_RTR_FLAG) { /* Remote transmission request */
+ data |= RCAR_CAN_RTR;
+ } else {
+ for (i = 0; i < cf->can_dlc; i++)
+ writeb(cf->data[i],
+ &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].data[i]);
+ }
+
+ writel(data, &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].id);
+
+ writeb(cf->can_dlc, &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].dlc);
+
+ priv->tx_dlc[priv->tx_head % RCAR_CAN_FIFO_DEPTH] = cf->can_dlc;
+ can_put_echo_skb(skb, ndev, priv->tx_head % RCAR_CAN_FIFO_DEPTH);
+ priv->tx_head++;
+ /* Start Tx: write 0xff to the TFPCR register to increment
+ * the CPU-side pointer for the transmit FIFO to the next
+ * mailbox location
+ */
+ writeb(0xff, &priv->regs->tfpcr);
+ /* Stop the queue if we've filled all FIFO entries */
+ if (priv->tx_head - priv->tx_tail >= RCAR_CAN_FIFO_DEPTH)
+ netif_stop_queue(ndev);
+
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops rcar_can_netdev_ops = {
+ .ndo_open = rcar_can_open,
+ .ndo_stop = rcar_can_close,
+ .ndo_start_xmit = rcar_can_start_xmit,
+};
+
+static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
+{
+ struct net_device_stats *stats = &priv->ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 data;
+ u8 dlc;
+
+ skb = alloc_can_skb(priv->ndev, &cf);
+ if (!skb) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ data = readl(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].id);
+ if (data & RCAR_CAN_IDE)
+ cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ else
+ cf->can_id = (data >> RCAR_CAN_SID_SHIFT) & CAN_SFF_MASK;
+
+ dlc = readb(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].dlc);
+ cf->can_dlc = get_can_dlc(dlc);
+ if (data & RCAR_CAN_RTR) {
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ for (dlc = 0; dlc < cf->can_dlc; dlc++)
+ cf->data[dlc] =
+ readb(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].data[dlc]);
+ }
+
+ can_led_event(priv->ndev, CAN_LED_EVENT_RX);
+
+ stats->rx_bytes += cf->can_dlc;
+ stats->rx_packets++;
+ netif_receive_skb(skb);
+}
+
+static int rcar_can_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct rcar_can_priv *priv = container_of(napi,
+ struct rcar_can_priv, napi);
+ int num_pkts;
+
+ for (num_pkts = 0; num_pkts < quota; num_pkts++) {
+ u8 rfcr, isr;
+
+ isr = readb(&priv->regs->isr);
+ /* Clear interrupt bit */
+ if (isr & RCAR_CAN_ISR_RXFF)
+ writeb(isr & ~RCAR_CAN_ISR_RXFF, &priv->regs->isr);
+ rfcr = readb(&priv->regs->rfcr);
+ if (rfcr & RCAR_CAN_RFCR_RFEST)
+ break;
+ rcar_can_rx_pkt(priv);
+ /* Write 0xff to the RFPCR register to increment
+ * the CPU-side pointer for the receive FIFO
+ * to the next mailbox location
+ */
+ writeb(0xff, &priv->regs->rfpcr);
+ }
+ /* All packets processed */
+ if (num_pkts < quota) {
+ napi_complete(napi);
+ priv->ier |= RCAR_CAN_IER_RXFIE;
+ writeb(priv->ier, &priv->regs->ier);
+ }
+ return num_pkts;
+}
+
+static int rcar_can_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ rcar_can_start(ndev);
+ netif_wake_queue(ndev);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int rcar_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct rcar_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ err = clk_prepare_enable(priv->clk);
+ if (err)
+ return err;
+ bec->txerr = readb(&priv->regs->tecr);
+ bec->rxerr = readb(&priv->regs->recr);
+ clk_disable_unprepare(priv->clk);
+ return 0;
+}
+
+static int rcar_can_probe(struct platform_device *pdev)
+{
+ struct rcar_can_platform_data *pdata;
+ struct rcar_can_priv *priv;
+ struct net_device *ndev;
+ struct resource *mem;
+ void __iomem *addr;
+ int err = -ENODEV;
+ int irq;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data provided!\n");
+ goto fail;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (!irq) {
+ dev_err(&pdev->dev, "No IRQ resource\n");
+ goto fail;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ addr = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(addr)) {
+ err = PTR_ERR(addr);
+ goto fail;
+ }
+
+ ndev = alloc_candev(sizeof(struct rcar_can_priv), RCAR_CAN_FIFO_DEPTH);
+ if (!ndev) {
+ dev_err(&pdev->dev, "alloc_candev() failed\n");
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ priv = netdev_priv(ndev);
+
+ priv->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ err = PTR_ERR(priv->clk);
+ dev_err(&pdev->dev, "cannot get clock: %d\n", err);
+ goto fail_clk;
+ }
+
+ ndev->netdev_ops = &rcar_can_netdev_ops;
+ ndev->irq = irq;
+ ndev->flags |= IFF_ECHO;
+ priv->ndev = ndev;
+ priv->regs = addr;
+ priv->clock_select = pdata->clock_select;
+ priv->can.clock.freq = clk_get_rate(priv->clk);
+ priv->can.bittiming_const = &rcar_can_bittiming_const;
+ priv->can.do_set_mode = rcar_can_do_set_mode;
+ priv->can.do_get_berr_counter = rcar_can_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING;
+ platform_set_drvdata(pdev, ndev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ netif_napi_add(ndev, &priv->napi, rcar_can_rx_poll,
+ RCAR_CAN_NAPI_WEIGHT);
+ err = register_candev(ndev);
+ if (err) {
+ dev_err(&pdev->dev, "register_candev() failed, error %d\n",
+ err);
+ goto fail_candev;
+ }
+
+ devm_can_led_init(ndev);
+
+ dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n",
+ priv->regs, ndev->irq);
+
+ return 0;
+fail_candev:
+ netif_napi_del(&priv->napi);
+fail_clk:
+ free_candev(ndev);
+fail:
+ return err;
+}
+
+static int rcar_can_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+
+ unregister_candev(ndev);
+ netif_napi_del(&priv->napi);
+ free_candev(ndev);
+ return 0;
+}
+
+static int __maybe_unused rcar_can_suspend(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+
+ if (netif_running(ndev)) {
+ netif_stop_queue(ndev);
+ netif_device_detach(ndev);
+ }
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr |= RCAR_CAN_CTLR_CANM_HALT;
+ writew(ctlr, &priv->regs->ctlr);
+ ctlr |= RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ clk_disable(priv->clk);
+ return 0;
+}
+
+static int __maybe_unused rcar_can_resume(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+ int err;
+
+ err = clk_enable(priv->clk);
+ if (err) {
+ netdev_err(ndev, "clk_enable() failed, error %d\n", err);
+ return err;
+ }
+
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr &= ~RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ ctlr &= ~RCAR_CAN_CTLR_CANM;
+ writew(ctlr, &priv->regs->ctlr);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_running(ndev)) {
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(rcar_can_pm_ops, rcar_can_suspend, rcar_can_resume);
+
+static struct platform_driver rcar_can_driver = {
+ .driver = {
+ .name = RCAR_CAN_DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &rcar_can_pm_ops,
+ },
+ .probe = rcar_can_probe,
+ .remove = rcar_can_remove,
+};
+
+module_platform_driver(rcar_can_driver);
+
+MODULE_AUTHOR("Cogent Embedded, Inc.");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CAN driver for Renesas R-Car SoC");
+MODULE_ALIAS("platform:" RCAR_CAN_DRV_NAME);
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
new file mode 100644
index 00000000000..1e65cb6c259
--- /dev/null
+++ b/drivers/net/can/sja1000/Kconfig
@@ -0,0 +1,103 @@
+menuconfig CAN_SJA1000
+ tristate "Philips/NXP SJA1000 devices"
+ depends on HAS_IOMEM
+
+if CAN_SJA1000
+
+config CAN_SJA1000_ISA
+ tristate "ISA Bus based legacy SJA1000 driver"
+ ---help---
+ This driver adds legacy support for SJA1000 chips connected to
+ the ISA bus using I/O port, memory mapped or indirect access.
+
+config CAN_SJA1000_PLATFORM
+ tristate "Generic Platform Bus based SJA1000 driver"
+ ---help---
+ This driver adds support for the SJA1000 chips connected to
+ the "platform bus" (Linux abstraction for directly to the
+ processor attached devices). Which can be found on various
+ boards from Phytec (http://www.phytec.de) like the PCM027,
+ PCM038. It also provides the OpenFirmware "platform bus" found
+ on embedded systems with OpenFirmware bindings, e.g. if you
+ have a PowerPC based system you may want to enable this option.
+
+config CAN_EMS_PCMCIA
+ tristate "EMS CPC-CARD Card"
+ depends on PCMCIA
+ ---help---
+ This driver is for the one or two channel CPC-CARD cards from
+ EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+
+config CAN_EMS_PCI
+ tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
+ depends on PCI
+ ---help---
+ This driver is for the one, two or four channel CPC-PCI,
+ CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
+ (http://www.ems-wuensche.de).
+
+config CAN_PEAK_PCMCIA
+ tristate "PEAK PCAN-PC Card"
+ depends on PCMCIA
+ depends on HAS_IOPORT_MAP
+ ---help---
+ This driver is for the PCAN-PC Card PCMCIA adapter (1 or 2 channels)
+ from PEAK-System (http://www.peak-system.com). To compile this
+ driver as a module, choose M here: the module will be called
+ peak_pcmcia.
+
+config CAN_PEAK_PCI
+ tristate "PEAK PCAN-PCI/PCIe/miniPCI Cards"
+ depends on PCI
+ ---help---
+ This driver is for the PCAN-PCI/PCIe/miniPCI cards
+ (1, 2, 3 or 4 channels) from PEAK-System Technik
+ (http://www.peak-system.com).
+
+config CAN_PEAK_PCIEC
+ bool "PEAK PCAN-ExpressCard Cards"
+ depends on CAN_PEAK_PCI
+ select I2C
+ select I2C_ALGOBIT
+ default y
+ ---help---
+ Say Y here if you want to use a PCAN-ExpressCard from PEAK-System
+ Technik. This will also automatically select I2C and I2C_ALGO
+ configuration options.
+
+config CAN_KVASER_PCI
+ tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
+ depends on PCI
+ ---help---
+ This driver is for the PCIcanx and PCIcan cards (1, 2 or
+ 4 channel) from Kvaser (http://www.kvaser.com).
+
+config CAN_PLX_PCI
+ tristate "PLX90xx PCI-bridge based Cards"
+ depends on PCI
+ ---help---
+ This driver is for CAN interface cards based on
+ the PLX90xx PCI bridge.
+ Driver supports now:
+ - Adlink PCI-7841/cPCI-7841 card (http://www.adlinktech.com/)
+ - Adlink PCI-7841/cPCI-7841 SE card
+ - esd CAN-PCI/CPCI/PCI104/200 (http://www.esd.eu/)
+ - esd CAN-PCI/PMC/266
+ - esd CAN-PCIe/2000
+ - Marathon CAN-bus-PCI card (http://www.marathon.ru/)
+ - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
+ - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
+ - Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
+
+config CAN_TSCAN1
+ tristate "TS-CAN1 PC104 boards"
+ depends on ISA
+ help
+ This driver is for Technologic Systems' TSCAN-1 PC104 boards.
+ http://www.embeddedarm.com/products/board-detail.php?product=TS-CAN1
+ The driver supports multiple boards and automatically configures them:
+ PLD IO base addresses are read from jumpers JP1 and JP2,
+ IRQ numbers are read from jumpers JP4 and JP5,
+ SJA1000 IO base addresses are chosen heuristically (first that works).
+
+endif
diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile
new file mode 100644
index 00000000000..531d5fcc97e
--- /dev/null
+++ b/drivers/net/can/sja1000/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the SJA1000 CAN controller drivers.
+#
+
+obj-$(CONFIG_CAN_SJA1000) += sja1000.o
+obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o
+obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
+obj-$(CONFIG_CAN_EMS_PCMCIA) += ems_pcmcia.o
+obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
+obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
+obj-$(CONFIG_CAN_PEAK_PCMCIA) += peak_pcmcia.o
+obj-$(CONFIG_CAN_PEAK_PCI) += peak_pci.o
+obj-$(CONFIG_CAN_PLX_PCI) += plx_pci.o
+obj-$(CONFIG_CAN_TSCAN1) += tscan1.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c
new file mode 100644
index 00000000000..fd13dbf07d9
--- /dev/null
+++ b/drivers/net/can/sja1000/ems_pci.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2008 Markus Plessing <plessing@ems-wuensche.com>
+ * Copyright (C) 2008 Sebastian Haas <haas@ems-wuensche.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "ems_pci"
+
+MODULE_AUTHOR("Sebastian Haas <haas@ems-wuenche.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe/104P CAN cards");
+MODULE_SUPPORTED_DEVICE("EMS CPC-PCI/PCIe/104P CAN card");
+MODULE_LICENSE("GPL v2");
+
+#define EMS_PCI_V1_MAX_CHAN 2
+#define EMS_PCI_V2_MAX_CHAN 4
+#define EMS_PCI_MAX_CHAN EMS_PCI_V2_MAX_CHAN
+
+struct ems_pci_card {
+ int version;
+ int channels;
+
+ struct pci_dev *pci_dev;
+ struct net_device *net_dev[EMS_PCI_MAX_CHAN];
+
+ void __iomem *conf_addr;
+ void __iomem *base_addr;
+};
+
+#define EMS_PCI_CAN_CLOCK (16000000 / 2)
+
+/*
+ * Register definitions and descriptions are from LinCAN 0.3.3.
+ *
+ * PSB4610 PITA-2 bridge control registers
+ */
+#define PITA2_ICR 0x00 /* Interrupt Control Register */
+#define PITA2_ICR_INT0 0x00000002 /* [RC] INT0 Active/Clear */
+#define PITA2_ICR_INT0_EN 0x00020000 /* [RW] Enable INT0 */
+
+#define PITA2_MISC 0x1c /* Miscellaneous Register */
+#define PITA2_MISC_CONFIG 0x04000000 /* Multiplexed parallel interface */
+
+/*
+ * Register definitions for the PLX 9030
+ */
+#define PLX_ICSR 0x4c /* Interrupt Control/Status register */
+#define PLX_ICSR_LINTI1_ENA 0x0001 /* LINTi1 Enable */
+#define PLX_ICSR_PCIINT_ENA 0x0040 /* PCI Interrupt Enable */
+#define PLX_ICSR_LINTI1_CLR 0x0400 /* Local Edge Triggerable Interrupt Clear */
+#define PLX_ICSR_ENA_CLR (PLX_ICSR_LINTI1_ENA | PLX_ICSR_PCIINT_ENA | \
+ PLX_ICSR_LINTI1_CLR)
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode, push-pull and the correct polarity.
+ */
+#define EMS_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 7
+ * (meaning direct oscillator output) because the second SJA1000 chip
+ * is driven by the first one CLKOUT output.
+ */
+#define EMS_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+
+#define EMS_PCI_V1_BASE_BAR 1
+#define EMS_PCI_V1_CONF_SIZE 4096 /* size of PITA control area */
+#define EMS_PCI_V2_BASE_BAR 2
+#define EMS_PCI_V2_CONF_SIZE 128 /* size of PLX control area */
+#define EMS_PCI_CAN_BASE_OFFSET 0x400 /* offset where the controllers starts */
+#define EMS_PCI_CAN_CTRL_SIZE 0x200 /* memory size for each controller */
+
+#define EMS_PCI_BASE_SIZE 4096 /* size of controller area */
+
+static DEFINE_PCI_DEVICE_TABLE(ems_pci_tbl) = {
+ /* CPC-PCI v1 */
+ {PCI_VENDOR_ID_SIEMENS, 0x2104, PCI_ANY_ID, PCI_ANY_ID,},
+ /* CPC-PCI v2 */
+ {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_PLX, 0x4000},
+ /* CPC-104P v2 */
+ {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_PLX, 0x4002},
+ {0,}
+};
+MODULE_DEVICE_TABLE(pci, ems_pci_tbl);
+
+/*
+ * Helper to read internal registers from card logic (not CAN)
+ */
+static u8 ems_pci_v1_readb(struct ems_pci_card *card, unsigned int port)
+{
+ return readb(card->base_addr + (port * 4));
+}
+
+static u8 ems_pci_v1_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return readb(priv->reg_base + (port * 4));
+}
+
+static void ems_pci_v1_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val)
+{
+ writeb(val, priv->reg_base + (port * 4));
+}
+
+static void ems_pci_v1_post_irq(const struct sja1000_priv *priv)
+{
+ struct ems_pci_card *card = (struct ems_pci_card *)priv->priv;
+
+ /* reset int flag of pita */
+ writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0,
+ card->conf_addr + PITA2_ICR);
+}
+
+static u8 ems_pci_v2_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return readb(priv->reg_base + port);
+}
+
+static void ems_pci_v2_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val)
+{
+ writeb(val, priv->reg_base + port);
+}
+
+static void ems_pci_v2_post_irq(const struct sja1000_priv *priv)
+{
+ struct ems_pci_card *card = (struct ems_pci_card *)priv->priv;
+
+ writel(PLX_ICSR_ENA_CLR, card->conf_addr + PLX_ICSR);
+}
+
+/*
+ * Check if a CAN controller is present at the specified location
+ * by trying to set 'em into the PeliCAN mode
+ */
+static inline int ems_pci_check_chan(const struct sja1000_priv *priv)
+{
+ unsigned char res;
+
+ /* Make sure SJA1000 is in reset mode */
+ priv->write_reg(priv, SJA1000_MOD, 1);
+
+ priv->write_reg(priv, SJA1000_CDR, CDR_PELICAN);
+
+ /* read reset-values */
+ res = priv->read_reg(priv, SJA1000_CDR);
+
+ if (res == CDR_PELICAN)
+ return 1;
+
+ return 0;
+}
+
+static void ems_pci_del_card(struct pci_dev *pdev)
+{
+ struct ems_pci_card *card = pci_get_drvdata(pdev);
+ struct net_device *dev;
+ int i = 0;
+
+ for (i = 0; i < card->channels; i++) {
+ dev = card->net_dev[i];
+
+ if (!dev)
+ continue;
+
+ dev_info(&pdev->dev, "Removing %s.\n", dev->name);
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+ }
+
+ if (card->base_addr != NULL)
+ pci_iounmap(card->pci_dev, card->base_addr);
+
+ if (card->conf_addr != NULL)
+ pci_iounmap(card->pci_dev, card->conf_addr);
+
+ kfree(card);
+
+ pci_disable_device(pdev);
+}
+
+static void ems_pci_card_reset(struct ems_pci_card *card)
+{
+ /* Request board reset */
+ writeb(0, card->base_addr);
+}
+
+/*
+ * Probe PCI device for EMS CAN signature and register each available
+ * CAN channel to SJA1000 Socket-CAN subsystem.
+ */
+static int ems_pci_add_card(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct sja1000_priv *priv;
+ struct net_device *dev;
+ struct ems_pci_card *card;
+ int max_chan, conf_size, base_bar;
+ int err, i;
+
+ /* Enabling PCI device */
+ if (pci_enable_device(pdev) < 0) {
+ dev_err(&pdev->dev, "Enabling PCI device failed\n");
+ return -ENODEV;
+ }
+
+ /* Allocating card structures to hold addresses, ... */
+ card = kzalloc(sizeof(struct ems_pci_card), GFP_KERNEL);
+ if (card == NULL) {
+ pci_disable_device(pdev);
+ return -ENOMEM;
+ }
+
+ pci_set_drvdata(pdev, card);
+
+ card->pci_dev = pdev;
+
+ card->channels = 0;
+
+ if (pdev->vendor == PCI_VENDOR_ID_PLX) {
+ card->version = 2; /* CPC-PCI v2 */
+ max_chan = EMS_PCI_V2_MAX_CHAN;
+ base_bar = EMS_PCI_V2_BASE_BAR;
+ conf_size = EMS_PCI_V2_CONF_SIZE;
+ } else {
+ card->version = 1; /* CPC-PCI v1 */
+ max_chan = EMS_PCI_V1_MAX_CHAN;
+ base_bar = EMS_PCI_V1_BASE_BAR;
+ conf_size = EMS_PCI_V1_CONF_SIZE;
+ }
+
+ /* Remap configuration space and controller memory area */
+ card->conf_addr = pci_iomap(pdev, 0, conf_size);
+ if (card->conf_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ card->base_addr = pci_iomap(pdev, base_bar, EMS_PCI_BASE_SIZE);
+ if (card->base_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ if (card->version == 1) {
+ /* Configure PITA-2 parallel interface (enable MUX) */
+ writel(PITA2_MISC_CONFIG, card->conf_addr + PITA2_MISC);
+
+ /* Check for unique EMS CAN signature */
+ if (ems_pci_v1_readb(card, 0) != 0x55 ||
+ ems_pci_v1_readb(card, 1) != 0xAA ||
+ ems_pci_v1_readb(card, 2) != 0x01 ||
+ ems_pci_v1_readb(card, 3) != 0xCB ||
+ ems_pci_v1_readb(card, 4) != 0x11) {
+ dev_err(&pdev->dev,
+ "Not EMS Dr. Thomas Wuensche interface\n");
+ err = -ENODEV;
+ goto failure_cleanup;
+ }
+ }
+
+ ems_pci_card_reset(card);
+
+ /* Detect available channels */
+ for (i = 0; i < max_chan; i++) {
+ dev = alloc_sja1000dev(0);
+ if (dev == NULL) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ card->net_dev[i] = dev;
+ priv = netdev_priv(dev);
+ priv->priv = card;
+ priv->irq_flags = IRQF_SHARED;
+
+ dev->irq = pdev->irq;
+ priv->reg_base = card->base_addr + EMS_PCI_CAN_BASE_OFFSET
+ + (i * EMS_PCI_CAN_CTRL_SIZE);
+ if (card->version == 1) {
+ priv->read_reg = ems_pci_v1_read_reg;
+ priv->write_reg = ems_pci_v1_write_reg;
+ priv->post_irq = ems_pci_v1_post_irq;
+ } else {
+ priv->read_reg = ems_pci_v2_read_reg;
+ priv->write_reg = ems_pci_v2_write_reg;
+ priv->post_irq = ems_pci_v2_post_irq;
+ }
+
+ /* Check if channel is present */
+ if (ems_pci_check_chan(priv)) {
+ priv->can.clock.freq = EMS_PCI_CAN_CLOCK;
+ priv->ocr = EMS_PCI_OCR;
+ priv->cdr = EMS_PCI_CDR;
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev->dev_id = i;
+
+ if (card->version == 1)
+ /* reset int flag of pita */
+ writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0,
+ card->conf_addr + PITA2_ICR);
+ else
+ /* enable IRQ in PLX 9030 */
+ writel(PLX_ICSR_ENA_CLR,
+ card->conf_addr + PLX_ICSR);
+
+ /* Register SJA1000 device */
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Registering device failed "
+ "(err=%d)\n", err);
+ free_sja1000dev(dev);
+ goto failure_cleanup;
+ }
+
+ card->channels++;
+
+ dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d\n",
+ i + 1, priv->reg_base, dev->irq);
+ } else {
+ free_sja1000dev(dev);
+ }
+ }
+
+ return 0;
+
+failure_cleanup:
+ dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err);
+
+ ems_pci_del_card(pdev);
+
+ return err;
+}
+
+static struct pci_driver ems_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = ems_pci_tbl,
+ .probe = ems_pci_add_card,
+ .remove = ems_pci_del_card,
+};
+
+module_pci_driver(ems_pci_driver);
diff --git a/drivers/net/can/sja1000/ems_pcmcia.c b/drivers/net/can/sja1000/ems_pcmcia.c
new file mode 100644
index 00000000000..381de998d2f
--- /dev/null
+++ b/drivers/net/can/sja1000/ems_pcmcia.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2008 Sebastian Haas (initial chardev implementation)
+ * Copyright (C) 2010 Markus Plessing <plessing@ems-wuensche.com>
+ * Rework for mainline by Oliver Hartkopp <socketcan@hartkopp.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include "sja1000.h"
+
+#define DRV_NAME "ems_pcmcia"
+
+MODULE_AUTHOR("Markus Plessing <plessing@ems-wuensche.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-CARD cards");
+MODULE_SUPPORTED_DEVICE("EMS CPC-CARD CAN card");
+MODULE_LICENSE("GPL v2");
+
+#define EMS_PCMCIA_MAX_CHAN 2
+
+struct ems_pcmcia_card {
+ int channels;
+ struct pcmcia_device *pcmcia_dev;
+ struct net_device *net_dev[EMS_PCMCIA_MAX_CHAN];
+ void __iomem *base_addr;
+};
+
+#define EMS_PCMCIA_CAN_CLOCK (16000000 / 2)
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode , push-pull and the correct polarity.
+ */
+#define EMS_PCMCIA_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 7
+ * (meaning direct oscillator output) because the second SJA1000 chip
+ * is driven by the first one CLKOUT output.
+ */
+#define EMS_PCMCIA_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+#define EMS_PCMCIA_MEM_SIZE 4096 /* Size of the remapped io-memory */
+#define EMS_PCMCIA_CAN_BASE_OFFSET 0x100 /* Offset where controllers starts */
+#define EMS_PCMCIA_CAN_CTRL_SIZE 0x80 /* Memory size for each controller */
+
+#define EMS_CMD_RESET 0x00 /* Perform a reset of the card */
+#define EMS_CMD_MAP 0x03 /* Map CAN controllers into card' memory */
+#define EMS_CMD_UMAP 0x02 /* Unmap CAN controllers from card' memory */
+
+static struct pcmcia_device_id ems_pcmcia_tbl[] = {
+ PCMCIA_DEVICE_PROD_ID123("EMS_T_W", "CPC-Card", "V2.0", 0xeab1ea23,
+ 0xa338573f, 0xe4575800),
+ PCMCIA_DEVICE_NULL,
+};
+
+MODULE_DEVICE_TABLE(pcmcia, ems_pcmcia_tbl);
+
+static u8 ems_pcmcia_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return readb(priv->reg_base + port);
+}
+
+static void ems_pcmcia_write_reg(const struct sja1000_priv *priv, int port,
+ u8 val)
+{
+ writeb(val, priv->reg_base + port);
+}
+
+static irqreturn_t ems_pcmcia_interrupt(int irq, void *dev_id)
+{
+ struct ems_pcmcia_card *card = dev_id;
+ struct net_device *dev;
+ irqreturn_t retval = IRQ_NONE;
+ int i, again;
+
+ /* Card not present */
+ if (readw(card->base_addr) != 0xAA55)
+ return IRQ_HANDLED;
+
+ do {
+ again = 0;
+
+ /* Check interrupt for each channel */
+ for (i = 0; i < card->channels; i++) {
+ dev = card->net_dev[i];
+ if (!dev)
+ continue;
+
+ if (sja1000_interrupt(irq, dev) == IRQ_HANDLED)
+ again = 1;
+ }
+ /* At least one channel handled the interrupt */
+ if (again)
+ retval = IRQ_HANDLED;
+
+ } while (again);
+
+ return retval;
+}
+
+/*
+ * Check if a CAN controller is present at the specified location
+ * by trying to set 'em into the PeliCAN mode
+ */
+static inline int ems_pcmcia_check_chan(struct sja1000_priv *priv)
+{
+ /* Make sure SJA1000 is in reset mode */
+ ems_pcmcia_write_reg(priv, SJA1000_MOD, 1);
+ ems_pcmcia_write_reg(priv, SJA1000_CDR, CDR_PELICAN);
+
+ /* read reset-values */
+ if (ems_pcmcia_read_reg(priv, SJA1000_CDR) == CDR_PELICAN)
+ return 1;
+
+ return 0;
+}
+
+static void ems_pcmcia_del_card(struct pcmcia_device *pdev)
+{
+ struct ems_pcmcia_card *card = pdev->priv;
+ struct net_device *dev;
+ int i;
+
+ free_irq(pdev->irq, card);
+
+ for (i = 0; i < card->channels; i++) {
+ dev = card->net_dev[i];
+ if (!dev)
+ continue;
+
+ printk(KERN_INFO "%s: removing %s on channel #%d\n",
+ DRV_NAME, dev->name, i);
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+ }
+
+ writeb(EMS_CMD_UMAP, card->base_addr);
+ iounmap(card->base_addr);
+ kfree(card);
+
+ pdev->priv = NULL;
+}
+
+/*
+ * Probe PCI device for EMS CAN signature and register each available
+ * CAN channel to SJA1000 Socket-CAN subsystem.
+ */
+static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base)
+{
+ struct sja1000_priv *priv;
+ struct net_device *dev;
+ struct ems_pcmcia_card *card;
+ int err, i;
+
+ /* Allocating card structures to hold addresses, ... */
+ card = kzalloc(sizeof(struct ems_pcmcia_card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+
+ pdev->priv = card;
+ card->channels = 0;
+
+ card->base_addr = ioremap(base, EMS_PCMCIA_MEM_SIZE);
+ if (!card->base_addr) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ /* Check for unique EMS CAN signature */
+ if (readw(card->base_addr) != 0xAA55) {
+ err = -ENODEV;
+ goto failure_cleanup;
+ }
+
+ /* Request board reset */
+ writeb(EMS_CMD_RESET, card->base_addr);
+
+ /* Make sure CAN controllers are mapped into card's memory space */
+ writeb(EMS_CMD_MAP, card->base_addr);
+
+ /* Detect available channels */
+ for (i = 0; i < EMS_PCMCIA_MAX_CHAN; i++) {
+ dev = alloc_sja1000dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ card->net_dev[i] = dev;
+ priv = netdev_priv(dev);
+ priv->priv = card;
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev->dev_id = i;
+
+ priv->irq_flags = IRQF_SHARED;
+ dev->irq = pdev->irq;
+ priv->reg_base = card->base_addr + EMS_PCMCIA_CAN_BASE_OFFSET +
+ (i * EMS_PCMCIA_CAN_CTRL_SIZE);
+
+ /* Check if channel is present */
+ if (ems_pcmcia_check_chan(priv)) {
+ priv->read_reg = ems_pcmcia_read_reg;
+ priv->write_reg = ems_pcmcia_write_reg;
+ priv->can.clock.freq = EMS_PCMCIA_CAN_CLOCK;
+ priv->ocr = EMS_PCMCIA_OCR;
+ priv->cdr = EMS_PCMCIA_CDR;
+ priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER;
+
+ /* Register SJA1000 device */
+ err = register_sja1000dev(dev);
+ if (err) {
+ free_sja1000dev(dev);
+ goto failure_cleanup;
+ }
+
+ card->channels++;
+
+ printk(KERN_INFO "%s: registered %s on channel "
+ "#%d at 0x%p, irq %d\n", DRV_NAME, dev->name,
+ i, priv->reg_base, dev->irq);
+ } else
+ free_sja1000dev(dev);
+ }
+
+ err = request_irq(dev->irq, &ems_pcmcia_interrupt, IRQF_SHARED,
+ DRV_NAME, card);
+ if (!err)
+ return 0;
+
+failure_cleanup:
+ ems_pcmcia_del_card(pdev);
+ return err;
+}
+
+/*
+ * Setup PCMCIA socket and probe for EMS CPC-CARD
+ */
+static int ems_pcmcia_probe(struct pcmcia_device *dev)
+{
+ int csval;
+
+ /* General socket configuration */
+ dev->config_flags |= CONF_ENABLE_IRQ;
+ dev->config_index = 1;
+ dev->config_regs = PRESENT_OPTION;
+
+ /* The io structure describes IO port mapping */
+ dev->resource[0]->end = 16;
+ dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ dev->resource[1]->end = 16;
+ dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
+ dev->io_lines = 5;
+
+ /* Allocate a memory window */
+ dev->resource[2]->flags =
+ (WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE);
+ dev->resource[2]->start = dev->resource[2]->end = 0;
+
+ csval = pcmcia_request_window(dev, dev->resource[2], 0);
+ if (csval) {
+ dev_err(&dev->dev, "pcmcia_request_window failed (err=%d)\n",
+ csval);
+ return 0;
+ }
+
+ csval = pcmcia_map_mem_page(dev, dev->resource[2], dev->config_base);
+ if (csval) {
+ dev_err(&dev->dev, "pcmcia_map_mem_page failed (err=%d)\n",
+ csval);
+ return 0;
+ }
+
+ csval = pcmcia_enable_device(dev);
+ if (csval) {
+ dev_err(&dev->dev, "pcmcia_enable_device failed (err=%d)\n",
+ csval);
+ return 0;
+ }
+
+ ems_pcmcia_add_card(dev, dev->resource[2]->start);
+ return 0;
+}
+
+/*
+ * Release claimed resources
+ */
+static void ems_pcmcia_remove(struct pcmcia_device *dev)
+{
+ ems_pcmcia_del_card(dev);
+ pcmcia_disable_device(dev);
+}
+
+static struct pcmcia_driver ems_pcmcia_driver = {
+ .name = DRV_NAME,
+ .probe = ems_pcmcia_probe,
+ .remove = ems_pcmcia_remove,
+ .id_table = ems_pcmcia_tbl,
+};
+module_pcmcia_driver(ems_pcmcia_driver);
diff --git a/drivers/net/can/sja1000/kvaser_pci.c b/drivers/net/can/sja1000/kvaser_pci.c
new file mode 100644
index 00000000000..23b8e1324e2
--- /dev/null
+++ b/drivers/net/can/sja1000/kvaser_pci.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2008 Per Dalen <per.dalen@cnw.se>
+ *
+ * Parts of this software are based on (derived) the following:
+ *
+ * - Kvaser linux driver, version 4.72 BETA
+ * Copyright (C) 2002-2007 KVASER AB
+ *
+ * - Lincan driver, version 0.3.3, OCERA project
+ * Copyright (C) 2004 Pavel Pisa
+ * Copyright (C) 2001 Arnaud Westenberg
+ *
+ * - Socketcan SJA1000 drivers
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "kvaser_pci"
+
+MODULE_AUTHOR("Per Dalen <per.dalen@cnw.se>");
+MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards");
+MODULE_SUPPORTED_DEVICE("KVASER PCAN PCI CAN card");
+MODULE_LICENSE("GPL v2");
+
+#define MAX_NO_OF_CHANNELS 4 /* max no of channels on a single card */
+
+struct kvaser_pci {
+ int channel;
+ struct pci_dev *pci_dev;
+ struct net_device *slave_dev[MAX_NO_OF_CHANNELS-1];
+ void __iomem *conf_addr;
+ void __iomem *res_addr;
+ int no_channels;
+ u8 xilinx_ver;
+};
+
+#define KVASER_PCI_CAN_CLOCK (16000000 / 2)
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode , push-pull and the correct polarity.
+ */
+#define KVASER_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 0
+ * (meaning divide-by-2), the Pelican bit, and the clock-off bit
+ * (you will have no need for CLKOUT anyway).
+ */
+#define KVASER_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+
+/*
+ * These register values are valid for revision 14 of the Xilinx logic.
+ */
+#define XILINX_VERINT 7 /* Lower nibble simulate interrupts,
+ high nibble version number. */
+
+#define XILINX_PRESUMED_VERSION 14
+
+/*
+ * Important S5920 registers
+ */
+#define S5920_INTCSR 0x38
+#define S5920_PTCR 0x60
+#define INTCSR_ADDON_INTENABLE_M 0x2000
+
+
+#define KVASER_PCI_PORT_BYTES 0x20
+
+#define PCI_CONFIG_PORT_SIZE 0x80 /* size of the config io-memory */
+#define PCI_PORT_SIZE 0x80 /* size of a channel io-memory */
+#define PCI_PORT_XILINX_SIZE 0x08 /* size of a xilinx io-memory */
+
+#define KVASER_PCI_VENDOR_ID1 0x10e8 /* the PCI device and vendor IDs */
+#define KVASER_PCI_DEVICE_ID1 0x8406
+
+#define KVASER_PCI_VENDOR_ID2 0x1a07 /* the PCI device and vendor IDs */
+#define KVASER_PCI_DEVICE_ID2 0x0008
+
+static DEFINE_PCI_DEVICE_TABLE(kvaser_pci_tbl) = {
+ {KVASER_PCI_VENDOR_ID1, KVASER_PCI_DEVICE_ID1, PCI_ANY_ID, PCI_ANY_ID,},
+ {KVASER_PCI_VENDOR_ID2, KVASER_PCI_DEVICE_ID2, PCI_ANY_ID, PCI_ANY_ID,},
+ { 0,}
+};
+
+MODULE_DEVICE_TABLE(pci, kvaser_pci_tbl);
+
+static u8 kvaser_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return ioread8(priv->reg_base + port);
+}
+
+static void kvaser_pci_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val)
+{
+ iowrite8(val, priv->reg_base + port);
+}
+
+static void kvaser_pci_disable_irq(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct kvaser_pci *board = priv->priv;
+ u32 intcsr;
+
+ /* Disable interrupts from card */
+ intcsr = ioread32(board->conf_addr + S5920_INTCSR);
+ intcsr &= ~INTCSR_ADDON_INTENABLE_M;
+ iowrite32(intcsr, board->conf_addr + S5920_INTCSR);
+}
+
+static void kvaser_pci_enable_irq(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct kvaser_pci *board = priv->priv;
+ u32 tmp_en_io;
+
+ /* Enable interrupts from card */
+ tmp_en_io = ioread32(board->conf_addr + S5920_INTCSR);
+ tmp_en_io |= INTCSR_ADDON_INTENABLE_M;
+ iowrite32(tmp_en_io, board->conf_addr + S5920_INTCSR);
+}
+
+static int number_of_sja1000_chip(void __iomem *base_addr)
+{
+ u8 status;
+ int i;
+
+ for (i = 0; i < MAX_NO_OF_CHANNELS; i++) {
+ /* reset chip */
+ iowrite8(MOD_RM, base_addr +
+ (i * KVASER_PCI_PORT_BYTES) + SJA1000_MOD);
+ status = ioread8(base_addr +
+ (i * KVASER_PCI_PORT_BYTES) + SJA1000_MOD);
+ /* check reset bit */
+ if (!(status & MOD_RM))
+ break;
+ }
+
+ return i;
+}
+
+static void kvaser_pci_del_chan(struct net_device *dev)
+{
+ struct sja1000_priv *priv;
+ struct kvaser_pci *board;
+ int i;
+
+ if (!dev)
+ return;
+ priv = netdev_priv(dev);
+ board = priv->priv;
+ if (!board)
+ return;
+
+ dev_info(&board->pci_dev->dev, "Removing device %s\n",
+ dev->name);
+
+ /* Disable PCI interrupts */
+ kvaser_pci_disable_irq(dev);
+
+ for (i = 0; i < board->no_channels - 1; i++) {
+ if (board->slave_dev[i]) {
+ dev_info(&board->pci_dev->dev, "Removing device %s\n",
+ board->slave_dev[i]->name);
+ unregister_sja1000dev(board->slave_dev[i]);
+ free_sja1000dev(board->slave_dev[i]);
+ }
+ }
+ unregister_sja1000dev(dev);
+
+ pci_iounmap(board->pci_dev, priv->reg_base);
+ pci_iounmap(board->pci_dev, board->conf_addr);
+ pci_iounmap(board->pci_dev, board->res_addr);
+
+ free_sja1000dev(dev);
+}
+
+static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
+ struct net_device **master_dev,
+ void __iomem *conf_addr,
+ void __iomem *res_addr,
+ void __iomem *base_addr)
+{
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ struct kvaser_pci *board;
+ int err, init_step;
+
+ dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
+ if (dev == NULL)
+ return -ENOMEM;
+
+ priv = netdev_priv(dev);
+ board = priv->priv;
+
+ board->pci_dev = pdev;
+ board->channel = channel;
+
+ /* S5920 */
+ board->conf_addr = conf_addr;
+
+ /* XILINX board wide address */
+ board->res_addr = res_addr;
+
+ if (channel == 0) {
+ board->xilinx_ver =
+ ioread8(board->res_addr + XILINX_VERINT) >> 4;
+ init_step = 2;
+
+ /* Assert PTADR# - we're in passive mode so the other bits are
+ not important */
+ iowrite32(0x80808080UL, board->conf_addr + S5920_PTCR);
+
+ /* Enable interrupts from card */
+ kvaser_pci_enable_irq(dev);
+ } else {
+ struct sja1000_priv *master_priv = netdev_priv(*master_dev);
+ struct kvaser_pci *master_board = master_priv->priv;
+ master_board->slave_dev[channel - 1] = dev;
+ master_board->no_channels = channel + 1;
+ board->xilinx_ver = master_board->xilinx_ver;
+ }
+
+ priv->reg_base = base_addr + channel * KVASER_PCI_PORT_BYTES;
+
+ priv->read_reg = kvaser_pci_read_reg;
+ priv->write_reg = kvaser_pci_write_reg;
+
+ priv->can.clock.freq = KVASER_PCI_CAN_CLOCK;
+
+ priv->ocr = KVASER_PCI_OCR;
+ priv->cdr = KVASER_PCI_CDR;
+
+ priv->irq_flags = IRQF_SHARED;
+ dev->irq = pdev->irq;
+
+ init_step = 4;
+
+ dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
+ priv->reg_base, board->conf_addr, dev->irq);
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev->dev_id = channel;
+
+ /* Register SJA1000 device */
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Registering device failed (err=%d)\n",
+ err);
+ goto failure;
+ }
+
+ if (channel == 0)
+ *master_dev = dev;
+
+ return 0;
+
+failure:
+ kvaser_pci_del_chan(dev);
+ return err;
+}
+
+static int kvaser_pci_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int err;
+ struct net_device *master_dev = NULL;
+ struct sja1000_priv *priv;
+ struct kvaser_pci *board;
+ int no_channels;
+ void __iomem *base_addr = NULL;
+ void __iomem *conf_addr = NULL;
+ void __iomem *res_addr = NULL;
+ int i;
+
+ dev_info(&pdev->dev, "initializing device %04x:%04x\n",
+ pdev->vendor, pdev->device);
+
+ err = pci_enable_device(pdev);
+ if (err)
+ goto failure;
+
+ err = pci_request_regions(pdev, DRV_NAME);
+ if (err)
+ goto failure_release_pci;
+
+ /* S5920 */
+ conf_addr = pci_iomap(pdev, 0, PCI_CONFIG_PORT_SIZE);
+ if (conf_addr == NULL) {
+ err = -ENODEV;
+ goto failure_release_regions;
+ }
+
+ /* XILINX board wide address */
+ res_addr = pci_iomap(pdev, 2, PCI_PORT_XILINX_SIZE);
+ if (res_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_iounmap;
+ }
+
+ base_addr = pci_iomap(pdev, 1, PCI_PORT_SIZE);
+ if (base_addr == NULL) {
+ err = -ENOMEM;
+ goto failure_iounmap;
+ }
+
+ no_channels = number_of_sja1000_chip(base_addr);
+ if (no_channels == 0) {
+ err = -ENOMEM;
+ goto failure_iounmap;
+ }
+
+ for (i = 0; i < no_channels; i++) {
+ err = kvaser_pci_add_chan(pdev, i, &master_dev,
+ conf_addr, res_addr,
+ base_addr);
+ if (err)
+ goto failure_cleanup;
+ }
+
+ priv = netdev_priv(master_dev);
+ board = priv->priv;
+
+ dev_info(&pdev->dev, "xilinx version=%d number of channels=%d\n",
+ board->xilinx_ver, board->no_channels);
+
+ pci_set_drvdata(pdev, master_dev);
+ return 0;
+
+failure_cleanup:
+ kvaser_pci_del_chan(master_dev);
+
+failure_iounmap:
+ if (conf_addr != NULL)
+ pci_iounmap(pdev, conf_addr);
+ if (res_addr != NULL)
+ pci_iounmap(pdev, res_addr);
+ if (base_addr != NULL)
+ pci_iounmap(pdev, base_addr);
+
+failure_release_regions:
+ pci_release_regions(pdev);
+
+failure_release_pci:
+ pci_disable_device(pdev);
+
+failure:
+ return err;
+
+}
+
+static void kvaser_pci_remove_one(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ kvaser_pci_del_chan(dev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+static struct pci_driver kvaser_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = kvaser_pci_tbl,
+ .probe = kvaser_pci_init_one,
+ .remove = kvaser_pci_remove_one,
+};
+
+module_pci_driver(kvaser_pci_driver);
diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c
new file mode 100644
index 00000000000..564933ae218
--- /dev/null
+++ b/drivers/net/can/sja1000/peak_pci.c
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) 2007, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2012 Stephane Grosjean <s.grosjean@peak-system.com>
+ *
+ * Derived from the PCAN project file driver/src/pcan_pci.c:
+ *
+ * Copyright (C) 2001-2006 PEAK System-Technik GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+
+#include "sja1000.h"
+
+MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards");
+MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards");
+MODULE_SUPPORTED_DEVICE("PEAK PCAN miniPCIe/cPCI PC/104+ PCI/104e CAN Cards");
+MODULE_LICENSE("GPL v2");
+
+#define DRV_NAME "peak_pci"
+
+struct peak_pciec_card;
+struct peak_pci_chan {
+ void __iomem *cfg_base; /* Common for all channels */
+ struct net_device *prev_dev; /* Chain of network devices */
+ u16 icr_mask; /* Interrupt mask for fast ack */
+ struct peak_pciec_card *pciec_card; /* only for PCIeC LEDs */
+};
+
+#define PEAK_PCI_CAN_CLOCK (16000000 / 2)
+
+#define PEAK_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+#define PEAK_PCI_OCR OCR_TX0_PUSHPULL
+
+/*
+ * Important PITA registers
+ */
+#define PITA_ICR 0x00 /* Interrupt control register */
+#define PITA_GPIOICR 0x18 /* GPIO interface control register */
+#define PITA_MISC 0x1C /* Miscellaneous register */
+
+#define PEAK_PCI_CFG_SIZE 0x1000 /* Size of the config PCI bar */
+#define PEAK_PCI_CHAN_SIZE 0x0400 /* Size used by the channel */
+
+#define PEAK_PCI_VENDOR_ID 0x001C /* The PCI device and vendor IDs */
+#define PEAK_PCI_DEVICE_ID 0x0001 /* for PCI/PCIe slot cards */
+#define PEAK_PCIEC_DEVICE_ID 0x0002 /* for ExpressCard slot cards */
+#define PEAK_PCIE_DEVICE_ID 0x0003 /* for nextgen PCIe slot cards */
+#define PEAK_CPCI_DEVICE_ID 0x0004 /* for nextgen cPCI slot cards */
+#define PEAK_MPCI_DEVICE_ID 0x0005 /* for nextgen miniPCI slot cards */
+#define PEAK_PC_104P_DEVICE_ID 0x0006 /* PCAN-PC/104+ cards */
+#define PEAK_PCI_104E_DEVICE_ID 0x0007 /* PCAN-PCI/104 Express cards */
+#define PEAK_MPCIE_DEVICE_ID 0x0008 /* The miniPCIe slot cards */
+
+#define PEAK_PCI_CHAN_MAX 4
+
+static const u16 peak_pci_icr_masks[PEAK_PCI_CHAN_MAX] = {
+ 0x02, 0x01, 0x40, 0x80
+};
+
+static DEFINE_PCI_DEVICE_TABLE(peak_pci_tbl) = {
+ {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+ {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+#ifdef CONFIG_CAN_PEAK_PCIEC
+ {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+#endif
+ {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, peak_pci_tbl);
+
+#ifdef CONFIG_CAN_PEAK_PCIEC
+/*
+ * PCAN-ExpressCard needs I2C bit-banging configuration option.
+ */
+
+/* GPIOICR byte access offsets */
+#define PITA_GPOUT 0x18 /* GPx output value */
+#define PITA_GPIN 0x19 /* GPx input value */
+#define PITA_GPOEN 0x1A /* configure GPx as ouput pin */
+
+/* I2C GP bits */
+#define PITA_GPIN_SCL 0x01 /* Serial Clock Line */
+#define PITA_GPIN_SDA 0x04 /* Serial DAta line */
+
+#define PCA9553_1_SLAVEADDR (0xC4 >> 1)
+
+/* PCA9553 LS0 fields values */
+enum {
+ PCA9553_LOW,
+ PCA9553_HIGHZ,
+ PCA9553_PWM0,
+ PCA9553_PWM1
+};
+
+/* LEDs control */
+#define PCA9553_ON PCA9553_LOW
+#define PCA9553_OFF PCA9553_HIGHZ
+#define PCA9553_SLOW PCA9553_PWM0
+#define PCA9553_FAST PCA9553_PWM1
+
+#define PCA9553_LED(c) (1 << (c))
+#define PCA9553_LED_STATE(s, c) ((s) << ((c) << 1))
+
+#define PCA9553_LED_ON(c) PCA9553_LED_STATE(PCA9553_ON, c)
+#define PCA9553_LED_OFF(c) PCA9553_LED_STATE(PCA9553_OFF, c)
+#define PCA9553_LED_SLOW(c) PCA9553_LED_STATE(PCA9553_SLOW, c)
+#define PCA9553_LED_FAST(c) PCA9553_LED_STATE(PCA9553_FAST, c)
+#define PCA9553_LED_MASK(c) PCA9553_LED_STATE(0x03, c)
+
+#define PCA9553_LED_OFF_ALL (PCA9553_LED_OFF(0) | PCA9553_LED_OFF(1))
+
+#define PCA9553_LS0_INIT 0x40 /* initial value (!= from 0x00) */
+
+struct peak_pciec_chan {
+ struct net_device *netdev;
+ unsigned long prev_rx_bytes;
+ unsigned long prev_tx_bytes;
+};
+
+struct peak_pciec_card {
+ void __iomem *cfg_base; /* Common for all channels */
+ void __iomem *reg_base; /* first channel base address */
+ u8 led_cache; /* leds state cache */
+
+ /* PCIExpressCard i2c data */
+ struct i2c_algo_bit_data i2c_bit;
+ struct i2c_adapter led_chip;
+ struct delayed_work led_work; /* led delayed work */
+ int chan_count;
+ struct peak_pciec_chan channel[PEAK_PCI_CHAN_MAX];
+};
+
+/* "normal" pci register write callback is overloaded for leds control */
+static void peak_pci_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val);
+
+static inline void pita_set_scl_highz(struct peak_pciec_card *card)
+{
+ u8 gp_outen = readb(card->cfg_base + PITA_GPOEN) & ~PITA_GPIN_SCL;
+ writeb(gp_outen, card->cfg_base + PITA_GPOEN);
+}
+
+static inline void pita_set_sda_highz(struct peak_pciec_card *card)
+{
+ u8 gp_outen = readb(card->cfg_base + PITA_GPOEN) & ~PITA_GPIN_SDA;
+ writeb(gp_outen, card->cfg_base + PITA_GPOEN);
+}
+
+static void peak_pciec_init_pita_gpio(struct peak_pciec_card *card)
+{
+ /* raise SCL & SDA GPIOs to high-Z */
+ pita_set_scl_highz(card);
+ pita_set_sda_highz(card);
+}
+
+static void pita_setsda(void *data, int state)
+{
+ struct peak_pciec_card *card = (struct peak_pciec_card *)data;
+ u8 gp_out, gp_outen;
+
+ /* set output sda always to 0 */
+ gp_out = readb(card->cfg_base + PITA_GPOUT) & ~PITA_GPIN_SDA;
+ writeb(gp_out, card->cfg_base + PITA_GPOUT);
+
+ /* control output sda with GPOEN */
+ gp_outen = readb(card->cfg_base + PITA_GPOEN);
+ if (state)
+ gp_outen &= ~PITA_GPIN_SDA;
+ else
+ gp_outen |= PITA_GPIN_SDA;
+
+ writeb(gp_outen, card->cfg_base + PITA_GPOEN);
+}
+
+static void pita_setscl(void *data, int state)
+{
+ struct peak_pciec_card *card = (struct peak_pciec_card *)data;
+ u8 gp_out, gp_outen;
+
+ /* set output scl always to 0 */
+ gp_out = readb(card->cfg_base + PITA_GPOUT) & ~PITA_GPIN_SCL;
+ writeb(gp_out, card->cfg_base + PITA_GPOUT);
+
+ /* control output scl with GPOEN */
+ gp_outen = readb(card->cfg_base + PITA_GPOEN);
+ if (state)
+ gp_outen &= ~PITA_GPIN_SCL;
+ else
+ gp_outen |= PITA_GPIN_SCL;
+
+ writeb(gp_outen, card->cfg_base + PITA_GPOEN);
+}
+
+static int pita_getsda(void *data)
+{
+ struct peak_pciec_card *card = (struct peak_pciec_card *)data;
+
+ /* set tristate */
+ pita_set_sda_highz(card);
+
+ return (readb(card->cfg_base + PITA_GPIN) & PITA_GPIN_SDA) ? 1 : 0;
+}
+
+static int pita_getscl(void *data)
+{
+ struct peak_pciec_card *card = (struct peak_pciec_card *)data;
+
+ /* set tristate */
+ pita_set_scl_highz(card);
+
+ return (readb(card->cfg_base + PITA_GPIN) & PITA_GPIN_SCL) ? 1 : 0;
+}
+
+/*
+ * write commands to the LED chip though the I2C-bus of the PCAN-PCIeC
+ */
+static int peak_pciec_write_pca9553(struct peak_pciec_card *card,
+ u8 offset, u8 data)
+{
+ u8 buffer[2] = {
+ offset,
+ data
+ };
+ struct i2c_msg msg = {
+ .addr = PCA9553_1_SLAVEADDR,
+ .len = 2,
+ .buf = buffer,
+ };
+ int ret;
+
+ /* cache led mask */
+ if ((offset == 5) && (data == card->led_cache))
+ return 0;
+
+ ret = i2c_transfer(&card->led_chip, &msg, 1);
+ if (ret < 0)
+ return ret;
+
+ if (offset == 5)
+ card->led_cache = data;
+
+ return 0;
+}
+
+/*
+ * delayed work callback used to control the LEDs
+ */
+static void peak_pciec_led_work(struct work_struct *work)
+{
+ struct peak_pciec_card *card =
+ container_of(work, struct peak_pciec_card, led_work.work);
+ struct net_device *netdev;
+ u8 new_led = card->led_cache;
+ int i, up_count = 0;
+
+ /* first check what is to do */
+ for (i = 0; i < card->chan_count; i++) {
+ /* default is: not configured */
+ new_led &= ~PCA9553_LED_MASK(i);
+ new_led |= PCA9553_LED_ON(i);
+
+ netdev = card->channel[i].netdev;
+ if (!netdev || !(netdev->flags & IFF_UP))
+ continue;
+
+ up_count++;
+
+ /* no activity (but configured) */
+ new_led &= ~PCA9553_LED_MASK(i);
+ new_led |= PCA9553_LED_SLOW(i);
+
+ /* if bytes counters changed, set fast blinking led */
+ if (netdev->stats.rx_bytes != card->channel[i].prev_rx_bytes) {
+ card->channel[i].prev_rx_bytes = netdev->stats.rx_bytes;
+ new_led &= ~PCA9553_LED_MASK(i);
+ new_led |= PCA9553_LED_FAST(i);
+ }
+ if (netdev->stats.tx_bytes != card->channel[i].prev_tx_bytes) {
+ card->channel[i].prev_tx_bytes = netdev->stats.tx_bytes;
+ new_led &= ~PCA9553_LED_MASK(i);
+ new_led |= PCA9553_LED_FAST(i);
+ }
+ }
+
+ /* check if LS0 settings changed, only update i2c if so */
+ peak_pciec_write_pca9553(card, 5, new_led);
+
+ /* restart timer (except if no more configured channels) */
+ if (up_count)
+ schedule_delayed_work(&card->led_work, HZ);
+}
+
+/*
+ * set LEDs blinking state
+ */
+static void peak_pciec_set_leds(struct peak_pciec_card *card, u8 led_mask, u8 s)
+{
+ u8 new_led = card->led_cache;
+ int i;
+
+ /* first check what is to do */
+ for (i = 0; i < card->chan_count; i++)
+ if (led_mask & PCA9553_LED(i)) {
+ new_led &= ~PCA9553_LED_MASK(i);
+ new_led |= PCA9553_LED_STATE(s, i);
+ }
+
+ /* check if LS0 settings changed, only update i2c if so */
+ peak_pciec_write_pca9553(card, 5, new_led);
+}
+
+/*
+ * start one second delayed work to control LEDs
+ */
+static void peak_pciec_start_led_work(struct peak_pciec_card *card)
+{
+ schedule_delayed_work(&card->led_work, HZ);
+}
+
+/*
+ * stop LEDs delayed work
+ */
+static void peak_pciec_stop_led_work(struct peak_pciec_card *card)
+{
+ cancel_delayed_work_sync(&card->led_work);
+}
+
+/*
+ * initialize the PCA9553 4-bit I2C-bus LED chip
+ */
+static int peak_pciec_init_leds(struct peak_pciec_card *card)
+{
+ int err;
+
+ /* prescaler for frequency 0: "SLOW" = 1 Hz = "44" */
+ err = peak_pciec_write_pca9553(card, 1, 44 / 1);
+ if (err)
+ return err;
+
+ /* duty cycle 0: 50% */
+ err = peak_pciec_write_pca9553(card, 2, 0x80);
+ if (err)
+ return err;
+
+ /* prescaler for frequency 1: "FAST" = 5 Hz */
+ err = peak_pciec_write_pca9553(card, 3, 44 / 5);
+ if (err)
+ return err;
+
+ /* duty cycle 1: 50% */
+ err = peak_pciec_write_pca9553(card, 4, 0x80);
+ if (err)
+ return err;
+
+ /* switch LEDs to initial state */
+ return peak_pciec_write_pca9553(card, 5, PCA9553_LS0_INIT);
+}
+
+/*
+ * restore LEDs state to off peak_pciec_leds_exit
+ */
+static void peak_pciec_leds_exit(struct peak_pciec_card *card)
+{
+ /* switch LEDs to off */
+ peak_pciec_write_pca9553(card, 5, PCA9553_LED_OFF_ALL);
+}
+
+/*
+ * normal write sja1000 register method overloaded to catch when controller
+ * is started or stopped, to control leds
+ */
+static void peak_pciec_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val)
+{
+ struct peak_pci_chan *chan = priv->priv;
+ struct peak_pciec_card *card = chan->pciec_card;
+ int c = (priv->reg_base - card->reg_base) / PEAK_PCI_CHAN_SIZE;
+
+ /* sja1000 register changes control the leds state */
+ if (port == SJA1000_MOD)
+ switch (val) {
+ case MOD_RM:
+ /* Reset Mode: set led on */
+ peak_pciec_set_leds(card, PCA9553_LED(c), PCA9553_ON);
+ break;
+ case 0x00:
+ /* Normal Mode: led slow blinking and start led timer */
+ peak_pciec_set_leds(card, PCA9553_LED(c), PCA9553_SLOW);
+ peak_pciec_start_led_work(card);
+ break;
+ default:
+ break;
+ }
+
+ /* call base function */
+ peak_pci_write_reg(priv, port, val);
+}
+
+static struct i2c_algo_bit_data peak_pciec_i2c_bit_ops = {
+ .setsda = pita_setsda,
+ .setscl = pita_setscl,
+ .getsda = pita_getsda,
+ .getscl = pita_getscl,
+ .udelay = 10,
+ .timeout = HZ,
+};
+
+static int peak_pciec_probe(struct pci_dev *pdev, struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct peak_pci_chan *chan = priv->priv;
+ struct peak_pciec_card *card;
+ int err;
+
+ /* copy i2c object address from 1st channel */
+ if (chan->prev_dev) {
+ struct sja1000_priv *prev_priv = netdev_priv(chan->prev_dev);
+ struct peak_pci_chan *prev_chan = prev_priv->priv;
+
+ card = prev_chan->pciec_card;
+ if (!card)
+ return -ENODEV;
+
+ /* channel is the first one: do the init part */
+ } else {
+ /* create the bit banging I2C adapter structure */
+ card = kzalloc(sizeof(struct peak_pciec_card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+
+ card->cfg_base = chan->cfg_base;
+ card->reg_base = priv->reg_base;
+
+ card->led_chip.owner = THIS_MODULE;
+ card->led_chip.dev.parent = &pdev->dev;
+ card->led_chip.algo_data = &card->i2c_bit;
+ strncpy(card->led_chip.name, "peak_i2c",
+ sizeof(card->led_chip.name));
+
+ card->i2c_bit = peak_pciec_i2c_bit_ops;
+ card->i2c_bit.udelay = 10;
+ card->i2c_bit.timeout = HZ;
+ card->i2c_bit.data = card;
+
+ peak_pciec_init_pita_gpio(card);
+
+ err = i2c_bit_add_bus(&card->led_chip);
+ if (err) {
+ dev_err(&pdev->dev, "i2c init failed\n");
+ goto pciec_init_err_1;
+ }
+
+ err = peak_pciec_init_leds(card);
+ if (err) {
+ dev_err(&pdev->dev, "leds hardware init failed\n");
+ goto pciec_init_err_2;
+ }
+
+ INIT_DELAYED_WORK(&card->led_work, peak_pciec_led_work);
+ /* PCAN-ExpressCard needs its own callback for leds */
+ priv->write_reg = peak_pciec_write_reg;
+ }
+
+ chan->pciec_card = card;
+ card->channel[card->chan_count++].netdev = dev;
+
+ return 0;
+
+pciec_init_err_2:
+ i2c_del_adapter(&card->led_chip);
+
+pciec_init_err_1:
+ peak_pciec_init_pita_gpio(card);
+ kfree(card);
+
+ return err;
+}
+
+static void peak_pciec_remove(struct peak_pciec_card *card)
+{
+ peak_pciec_stop_led_work(card);
+ peak_pciec_leds_exit(card);
+ i2c_del_adapter(&card->led_chip);
+ peak_pciec_init_pita_gpio(card);
+ kfree(card);
+}
+
+#else /* CONFIG_CAN_PEAK_PCIEC */
+
+/*
+ * Placebo functions when PCAN-ExpressCard support is not selected
+ */
+static inline int peak_pciec_probe(struct pci_dev *pdev, struct net_device *dev)
+{
+ return -ENODEV;
+}
+
+static inline void peak_pciec_remove(struct peak_pciec_card *card)
+{
+}
+#endif /* CONFIG_CAN_PEAK_PCIEC */
+
+static u8 peak_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return readb(priv->reg_base + (port << 2));
+}
+
+static void peak_pci_write_reg(const struct sja1000_priv *priv,
+ int port, u8 val)
+{
+ writeb(val, priv->reg_base + (port << 2));
+}
+
+static void peak_pci_post_irq(const struct sja1000_priv *priv)
+{
+ struct peak_pci_chan *chan = priv->priv;
+ u16 icr;
+
+ /* Select and clear in PITA stored interrupt */
+ icr = readw(chan->cfg_base + PITA_ICR);
+ if (icr & chan->icr_mask)
+ writew(chan->icr_mask, chan->cfg_base + PITA_ICR);
+}
+
+static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct sja1000_priv *priv;
+ struct peak_pci_chan *chan;
+ struct net_device *dev, *prev_dev;
+ void __iomem *cfg_base, *reg_base;
+ u16 sub_sys_id, icr;
+ int i, err, channels;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+
+ err = pci_request_regions(pdev, DRV_NAME);
+ if (err)
+ goto failure_disable_pci;
+
+ err = pci_read_config_word(pdev, 0x2e, &sub_sys_id);
+ if (err)
+ goto failure_release_regions;
+
+ dev_dbg(&pdev->dev, "probing device %04x:%04x:%04x\n",
+ pdev->vendor, pdev->device, sub_sys_id);
+
+ err = pci_write_config_word(pdev, 0x44, 0);
+ if (err)
+ goto failure_release_regions;
+
+ if (sub_sys_id >= 12)
+ channels = 4;
+ else if (sub_sys_id >= 10)
+ channels = 3;
+ else if (sub_sys_id >= 4)
+ channels = 2;
+ else
+ channels = 1;
+
+ cfg_base = pci_iomap(pdev, 0, PEAK_PCI_CFG_SIZE);
+ if (!cfg_base) {
+ dev_err(&pdev->dev, "failed to map PCI resource #0\n");
+ err = -ENOMEM;
+ goto failure_release_regions;
+ }
+
+ reg_base = pci_iomap(pdev, 1, PEAK_PCI_CHAN_SIZE * channels);
+ if (!reg_base) {
+ dev_err(&pdev->dev, "failed to map PCI resource #1\n");
+ err = -ENOMEM;
+ goto failure_unmap_cfg_base;
+ }
+
+ /* Set GPIO control register */
+ writew(0x0005, cfg_base + PITA_GPIOICR + 2);
+ /* Enable all channels of this card */
+ writeb(0x00, cfg_base + PITA_GPIOICR);
+ /* Toggle reset */
+ writeb(0x05, cfg_base + PITA_MISC + 3);
+ mdelay(5);
+ /* Leave parport mux mode */
+ writeb(0x04, cfg_base + PITA_MISC + 3);
+
+ icr = readw(cfg_base + PITA_ICR + 2);
+
+ for (i = 0; i < channels; i++) {
+ dev = alloc_sja1000dev(sizeof(struct peak_pci_chan));
+ if (!dev) {
+ err = -ENOMEM;
+ goto failure_remove_channels;
+ }
+
+ priv = netdev_priv(dev);
+ chan = priv->priv;
+
+ chan->cfg_base = cfg_base;
+ priv->reg_base = reg_base + i * PEAK_PCI_CHAN_SIZE;
+
+ priv->read_reg = peak_pci_read_reg;
+ priv->write_reg = peak_pci_write_reg;
+ priv->post_irq = peak_pci_post_irq;
+
+ priv->can.clock.freq = PEAK_PCI_CAN_CLOCK;
+ priv->ocr = PEAK_PCI_OCR;
+ priv->cdr = PEAK_PCI_CDR;
+ /* Neither a slave nor a single device distributes the clock */
+ if (channels == 1 || i > 0)
+ priv->cdr |= CDR_CLK_OFF;
+
+ /* Setup interrupt handling */
+ priv->irq_flags = IRQF_SHARED;
+ dev->irq = pdev->irq;
+
+ chan->icr_mask = peak_pci_icr_masks[i];
+ icr |= chan->icr_mask;
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev->dev_id = i;
+
+ /* Create chain of SJA1000 devices */
+ chan->prev_dev = pci_get_drvdata(pdev);
+ pci_set_drvdata(pdev, dev);
+
+ /*
+ * PCAN-ExpressCard needs some additional i2c init.
+ * This must be done *before* register_sja1000dev() but
+ * *after* devices linkage
+ */
+ if (pdev->device == PEAK_PCIEC_DEVICE_ID) {
+ err = peak_pciec_probe(pdev, dev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "failed to probe device (err %d)\n",
+ err);
+ goto failure_free_dev;
+ }
+ }
+
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register device\n");
+ goto failure_free_dev;
+ }
+
+ dev_info(&pdev->dev,
+ "%s at reg_base=0x%p cfg_base=0x%p irq=%d\n",
+ dev->name, priv->reg_base, chan->cfg_base, dev->irq);
+ }
+
+ /* Enable interrupts */
+ writew(icr, cfg_base + PITA_ICR + 2);
+
+ return 0;
+
+failure_free_dev:
+ pci_set_drvdata(pdev, chan->prev_dev);
+ free_sja1000dev(dev);
+
+failure_remove_channels:
+ /* Disable interrupts */
+ writew(0x0, cfg_base + PITA_ICR + 2);
+
+ chan = NULL;
+ for (dev = pci_get_drvdata(pdev); dev; dev = prev_dev) {
+ priv = netdev_priv(dev);
+ chan = priv->priv;
+ prev_dev = chan->prev_dev;
+
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+ }
+
+ /* free any PCIeC resources too */
+ if (chan && chan->pciec_card)
+ peak_pciec_remove(chan->pciec_card);
+
+ pci_iounmap(pdev, reg_base);
+
+failure_unmap_cfg_base:
+ pci_iounmap(pdev, cfg_base);
+
+failure_release_regions:
+ pci_release_regions(pdev);
+
+failure_disable_pci:
+ pci_disable_device(pdev);
+
+ return err;
+}
+
+static void peak_pci_remove(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev); /* Last device */
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct peak_pci_chan *chan = priv->priv;
+ void __iomem *cfg_base = chan->cfg_base;
+ void __iomem *reg_base = priv->reg_base;
+
+ /* Disable interrupts */
+ writew(0x0, cfg_base + PITA_ICR + 2);
+
+ /* Loop over all registered devices */
+ while (1) {
+ struct net_device *prev_dev = chan->prev_dev;
+
+ dev_info(&pdev->dev, "removing device %s\n", dev->name);
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+ dev = prev_dev;
+
+ if (!dev) {
+ /* do that only for first channel */
+ if (chan->pciec_card)
+ peak_pciec_remove(chan->pciec_card);
+ break;
+ }
+ priv = netdev_priv(dev);
+ chan = priv->priv;
+ }
+
+ pci_iounmap(pdev, reg_base);
+ pci_iounmap(pdev, cfg_base);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+static struct pci_driver peak_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = peak_pci_tbl,
+ .probe = peak_pci_probe,
+ .remove = peak_pci_remove,
+};
+
+module_pci_driver(peak_pci_driver);
diff --git a/drivers/net/can/sja1000/peak_pcmcia.c b/drivers/net/can/sja1000/peak_pcmcia.c
new file mode 100644
index 00000000000..dd56133cc46
--- /dev/null
+++ b/drivers/net/can/sja1000/peak_pcmcia.c
@@ -0,0 +1,744 @@
+/*
+ * Copyright (C) 2010-2012 Stephane Grosjean <s.grosjean@peak-system.com>
+ *
+ * CAN driver for PEAK-System PCAN-PC Card
+ * Derived from the PCAN project file driver/src/pcan_pccard.c
+ * Copyright (C) 2006-2010 PEAK System-Technik GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include "sja1000.h"
+
+MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>");
+MODULE_DESCRIPTION("CAN driver for PEAK-System PCAN-PC Cards");
+MODULE_LICENSE("GPL v2");
+MODULE_SUPPORTED_DEVICE("PEAK PCAN-PC Card");
+
+/* PEAK-System PCMCIA driver name */
+#define PCC_NAME "peak_pcmcia"
+
+#define PCC_CHAN_MAX 2
+
+#define PCC_CAN_CLOCK (16000000 / 2)
+
+#define PCC_MANF_ID 0x0377
+#define PCC_CARD_ID 0x0001
+
+#define PCC_CHAN_SIZE 0x20
+#define PCC_CHAN_OFF(c) ((c) * PCC_CHAN_SIZE)
+#define PCC_COMN_OFF (PCC_CHAN_OFF(PCC_CHAN_MAX))
+#define PCC_COMN_SIZE 0x40
+
+/* common area registers */
+#define PCC_CCR 0x00
+#define PCC_CSR 0x02
+#define PCC_CPR 0x04
+#define PCC_SPI_DIR 0x06
+#define PCC_SPI_DOR 0x08
+#define PCC_SPI_ADR 0x0a
+#define PCC_SPI_IR 0x0c
+#define PCC_FW_MAJOR 0x10
+#define PCC_FW_MINOR 0x12
+
+/* CCR bits */
+#define PCC_CCR_CLK_16 0x00
+#define PCC_CCR_CLK_10 0x01
+#define PCC_CCR_CLK_21 0x02
+#define PCC_CCR_CLK_8 0x03
+#define PCC_CCR_CLK_MASK PCC_CCR_CLK_8
+
+#define PCC_CCR_RST_CHAN(c) (0x01 << ((c) + 2))
+#define PCC_CCR_RST_ALL (PCC_CCR_RST_CHAN(0) | PCC_CCR_RST_CHAN(1))
+#define PCC_CCR_RST_MASK PCC_CCR_RST_ALL
+
+/* led selection bits */
+#define PCC_LED(c) (1 << (c))
+#define PCC_LED_ALL (PCC_LED(0) | PCC_LED(1))
+
+/* led state value */
+#define PCC_LED_ON 0x00
+#define PCC_LED_FAST 0x01
+#define PCC_LED_SLOW 0x02
+#define PCC_LED_OFF 0x03
+
+#define PCC_CCR_LED_CHAN(s, c) ((s) << (((c) + 2) << 1))
+
+#define PCC_CCR_LED_ON_CHAN(c) PCC_CCR_LED_CHAN(PCC_LED_ON, c)
+#define PCC_CCR_LED_FAST_CHAN(c) PCC_CCR_LED_CHAN(PCC_LED_FAST, c)
+#define PCC_CCR_LED_SLOW_CHAN(c) PCC_CCR_LED_CHAN(PCC_LED_SLOW, c)
+#define PCC_CCR_LED_OFF_CHAN(c) PCC_CCR_LED_CHAN(PCC_LED_OFF, c)
+#define PCC_CCR_LED_MASK_CHAN(c) PCC_CCR_LED_OFF_CHAN(c)
+#define PCC_CCR_LED_OFF_ALL (PCC_CCR_LED_OFF_CHAN(0) | \
+ PCC_CCR_LED_OFF_CHAN(1))
+#define PCC_CCR_LED_MASK PCC_CCR_LED_OFF_ALL
+
+#define PCC_CCR_INIT (PCC_CCR_CLK_16 | PCC_CCR_RST_ALL | PCC_CCR_LED_OFF_ALL)
+
+/* CSR bits */
+#define PCC_CSR_SPI_BUSY 0x04
+
+/* time waiting for SPI busy (prevent from infinite loop) */
+#define PCC_SPI_MAX_BUSY_WAIT_MS 3
+
+/* max count of reading the SPI status register waiting for a change */
+/* (prevent from infinite loop) */
+#define PCC_WRITE_MAX_LOOP 1000
+
+/* max nb of int handled by that isr in one shot (prevent from infinite loop) */
+#define PCC_ISR_MAX_LOOP 10
+
+/* EEPROM chip instruction set */
+/* note: EEPROM Read/Write instructions include A8 bit */
+#define PCC_EEP_WRITE(a) (0x02 | (((a) & 0x100) >> 5))
+#define PCC_EEP_READ(a) (0x03 | (((a) & 0x100) >> 5))
+#define PCC_EEP_WRDI 0x04 /* EEPROM Write Disable */
+#define PCC_EEP_RDSR 0x05 /* EEPROM Read Status Register */
+#define PCC_EEP_WREN 0x06 /* EEPROM Write Enable */
+
+/* EEPROM Status Register bits */
+#define PCC_EEP_SR_WEN 0x02 /* EEPROM SR Write Enable bit */
+#define PCC_EEP_SR_WIP 0x01 /* EEPROM SR Write In Progress bit */
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode, push-pull and the correct polarity.
+ */
+#define PCC_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 7
+ * (meaning direct oscillator output) because the second SJA1000 chip
+ * is driven by the first one CLKOUT output.
+ */
+#define PCC_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+
+struct pcan_channel {
+ struct net_device *netdev;
+ unsigned long prev_rx_bytes;
+ unsigned long prev_tx_bytes;
+};
+
+/* PCAN-PC Card private structure */
+struct pcan_pccard {
+ struct pcmcia_device *pdev;
+ int chan_count;
+ struct pcan_channel channel[PCC_CHAN_MAX];
+ u8 ccr;
+ u8 fw_major;
+ u8 fw_minor;
+ void __iomem *ioport_addr;
+ struct timer_list led_timer;
+};
+
+static struct pcmcia_device_id pcan_table[] = {
+ PCMCIA_DEVICE_MANF_CARD(PCC_MANF_ID, PCC_CARD_ID),
+ PCMCIA_DEVICE_NULL,
+};
+
+MODULE_DEVICE_TABLE(pcmcia, pcan_table);
+
+static void pcan_set_leds(struct pcan_pccard *card, u8 mask, u8 state);
+
+/*
+ * start timer which controls leds state
+ */
+static void pcan_start_led_timer(struct pcan_pccard *card)
+{
+ if (!timer_pending(&card->led_timer))
+ mod_timer(&card->led_timer, jiffies + HZ);
+}
+
+/*
+ * stop the timer which controls leds state
+ */
+static void pcan_stop_led_timer(struct pcan_pccard *card)
+{
+ del_timer_sync(&card->led_timer);
+}
+
+/*
+ * read a sja1000 register
+ */
+static u8 pcan_read_canreg(const struct sja1000_priv *priv, int port)
+{
+ return ioread8(priv->reg_base + port);
+}
+
+/*
+ * write a sja1000 register
+ */
+static void pcan_write_canreg(const struct sja1000_priv *priv, int port, u8 v)
+{
+ struct pcan_pccard *card = priv->priv;
+ int c = (priv->reg_base - card->ioport_addr) / PCC_CHAN_SIZE;
+
+ /* sja1000 register changes control the leds state */
+ if (port == SJA1000_MOD)
+ switch (v) {
+ case MOD_RM:
+ /* Reset Mode: set led on */
+ pcan_set_leds(card, PCC_LED(c), PCC_LED_ON);
+ break;
+ case 0x00:
+ /* Normal Mode: led slow blinking and start led timer */
+ pcan_set_leds(card, PCC_LED(c), PCC_LED_SLOW);
+ pcan_start_led_timer(card);
+ break;
+ default:
+ break;
+ }
+
+ iowrite8(v, priv->reg_base + port);
+}
+
+/*
+ * read a register from the common area
+ */
+static u8 pcan_read_reg(struct pcan_pccard *card, int port)
+{
+ return ioread8(card->ioport_addr + PCC_COMN_OFF + port);
+}
+
+/*
+ * write a register into the common area
+ */
+static void pcan_write_reg(struct pcan_pccard *card, int port, u8 v)
+{
+ /* cache ccr value */
+ if (port == PCC_CCR) {
+ if (card->ccr == v)
+ return;
+ card->ccr = v;
+ }
+
+ iowrite8(v, card->ioport_addr + PCC_COMN_OFF + port);
+}
+
+/*
+ * check whether the card is present by checking its fw version numbers
+ * against values read at probing time.
+ */
+static inline int pcan_pccard_present(struct pcan_pccard *card)
+{
+ return ((pcan_read_reg(card, PCC_FW_MAJOR) == card->fw_major) &&
+ (pcan_read_reg(card, PCC_FW_MINOR) == card->fw_minor));
+}
+
+/*
+ * wait for SPI engine while it is busy
+ */
+static int pcan_wait_spi_busy(struct pcan_pccard *card)
+{
+ unsigned long timeout = jiffies +
+ msecs_to_jiffies(PCC_SPI_MAX_BUSY_WAIT_MS) + 1;
+
+ /* be sure to read status at least once after sleeping */
+ while (pcan_read_reg(card, PCC_CSR) & PCC_CSR_SPI_BUSY) {
+ if (time_after(jiffies, timeout))
+ return -EBUSY;
+ schedule();
+ }
+
+ return 0;
+}
+
+/*
+ * write data in device eeprom
+ */
+static int pcan_write_eeprom(struct pcan_pccard *card, u16 addr, u8 v)
+{
+ u8 status;
+ int err, i;
+
+ /* write instruction enabling write */
+ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WREN);
+ err = pcan_wait_spi_busy(card);
+ if (err)
+ goto we_spi_err;
+
+ /* wait until write enabled */
+ for (i = 0; i < PCC_WRITE_MAX_LOOP; i++) {
+ /* write instruction reading the status register */
+ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_RDSR);
+ err = pcan_wait_spi_busy(card);
+ if (err)
+ goto we_spi_err;
+
+ /* get status register value and check write enable bit */
+ status = pcan_read_reg(card, PCC_SPI_DIR);
+ if (status & PCC_EEP_SR_WEN)
+ break;
+ }
+
+ if (i >= PCC_WRITE_MAX_LOOP) {
+ dev_err(&card->pdev->dev,
+ "stop waiting to be allowed to write in eeprom\n");
+ return -EIO;
+ }
+
+ /* set address and data */
+ pcan_write_reg(card, PCC_SPI_ADR, addr & 0xff);
+ pcan_write_reg(card, PCC_SPI_DOR, v);
+
+ /*
+ * write instruction with bit[3] set according to address value:
+ * if addr refers to upper half of the memory array: bit[3] = 1
+ */
+ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WRITE(addr));
+ err = pcan_wait_spi_busy(card);
+ if (err)
+ goto we_spi_err;
+
+ /* wait while write in progress */
+ for (i = 0; i < PCC_WRITE_MAX_LOOP; i++) {
+ /* write instruction reading the status register */
+ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_RDSR);
+ err = pcan_wait_spi_busy(card);
+ if (err)
+ goto we_spi_err;
+
+ /* get status register value and check write in progress bit */
+ status = pcan_read_reg(card, PCC_SPI_DIR);
+ if (!(status & PCC_EEP_SR_WIP))
+ break;
+ }
+
+ if (i >= PCC_WRITE_MAX_LOOP) {
+ dev_err(&card->pdev->dev,
+ "stop waiting for write in eeprom to complete\n");
+ return -EIO;
+ }
+
+ /* write instruction disabling write */
+ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WRDI);
+ err = pcan_wait_spi_busy(card);
+ if (err)
+ goto we_spi_err;
+
+ return 0;
+
+we_spi_err:
+ dev_err(&card->pdev->dev,
+ "stop waiting (spi engine always busy) err %d\n", err);
+
+ return err;
+}
+
+static void pcan_set_leds(struct pcan_pccard *card, u8 led_mask, u8 state)
+{
+ u8 ccr = card->ccr;
+ int i;
+
+ for (i = 0; i < card->chan_count; i++)
+ if (led_mask & PCC_LED(i)) {
+ /* clear corresponding led bits in ccr */
+ ccr &= ~PCC_CCR_LED_MASK_CHAN(i);
+ /* then set new bits */
+ ccr |= PCC_CCR_LED_CHAN(state, i);
+ }
+
+ /* real write only if something has changed in ccr */
+ pcan_write_reg(card, PCC_CCR, ccr);
+}
+
+/*
+ * enable/disable CAN connectors power
+ */
+static inline void pcan_set_can_power(struct pcan_pccard *card, int onoff)
+{
+ int err;
+
+ err = pcan_write_eeprom(card, 0, !!onoff);
+ if (err)
+ dev_err(&card->pdev->dev,
+ "failed setting power %s to can connectors (err %d)\n",
+ (onoff) ? "on" : "off", err);
+}
+
+/*
+ * set leds state according to channel activity
+ */
+static void pcan_led_timer(unsigned long arg)
+{
+ struct pcan_pccard *card = (struct pcan_pccard *)arg;
+ struct net_device *netdev;
+ int i, up_count = 0;
+ u8 ccr;
+
+ ccr = card->ccr;
+ for (i = 0; i < card->chan_count; i++) {
+ /* default is: not configured */
+ ccr &= ~PCC_CCR_LED_MASK_CHAN(i);
+ ccr |= PCC_CCR_LED_ON_CHAN(i);
+
+ netdev = card->channel[i].netdev;
+ if (!netdev || !(netdev->flags & IFF_UP))
+ continue;
+
+ up_count++;
+
+ /* no activity (but configured) */
+ ccr &= ~PCC_CCR_LED_MASK_CHAN(i);
+ ccr |= PCC_CCR_LED_SLOW_CHAN(i);
+
+ /* if bytes counters changed, set fast blinking led */
+ if (netdev->stats.rx_bytes != card->channel[i].prev_rx_bytes) {
+ card->channel[i].prev_rx_bytes = netdev->stats.rx_bytes;
+ ccr &= ~PCC_CCR_LED_MASK_CHAN(i);
+ ccr |= PCC_CCR_LED_FAST_CHAN(i);
+ }
+ if (netdev->stats.tx_bytes != card->channel[i].prev_tx_bytes) {
+ card->channel[i].prev_tx_bytes = netdev->stats.tx_bytes;
+ ccr &= ~PCC_CCR_LED_MASK_CHAN(i);
+ ccr |= PCC_CCR_LED_FAST_CHAN(i);
+ }
+ }
+
+ /* write the new leds state */
+ pcan_write_reg(card, PCC_CCR, ccr);
+
+ /* restart timer (except if no more configured channels) */
+ if (up_count)
+ mod_timer(&card->led_timer, jiffies + HZ);
+}
+
+/*
+ * interrupt service routine
+ */
+static irqreturn_t pcan_isr(int irq, void *dev_id)
+{
+ struct pcan_pccard *card = dev_id;
+ int irq_handled;
+
+ /* prevent from infinite loop */
+ for (irq_handled = 0; irq_handled < PCC_ISR_MAX_LOOP; irq_handled++) {
+ /* handle shared interrupt and next loop */
+ int nothing_to_handle = 1;
+ int i;
+
+ /* check interrupt for each channel */
+ for (i = 0; i < card->chan_count; i++) {
+ struct net_device *netdev;
+
+ /*
+ * check whether the card is present before calling
+ * sja1000_interrupt() to speed up hotplug detection
+ */
+ if (!pcan_pccard_present(card)) {
+ /* card unplugged during isr */
+ return IRQ_NONE;
+ }
+
+ /*
+ * should check whether all or SJA1000_MAX_IRQ
+ * interrupts have been handled: loop again to be sure.
+ */
+ netdev = card->channel[i].netdev;
+ if (netdev &&
+ sja1000_interrupt(irq, netdev) == IRQ_HANDLED)
+ nothing_to_handle = 0;
+ }
+
+ if (nothing_to_handle)
+ break;
+ }
+
+ return (irq_handled) ? IRQ_HANDLED : IRQ_NONE;
+}
+
+/*
+ * free all resources used by the channels and switch off leds and can power
+ */
+static void pcan_free_channels(struct pcan_pccard *card)
+{
+ int i;
+ u8 led_mask = 0;
+
+ for (i = 0; i < card->chan_count; i++) {
+ struct net_device *netdev;
+ char name[IFNAMSIZ];
+
+ led_mask |= PCC_LED(i);
+
+ netdev = card->channel[i].netdev;
+ if (!netdev)
+ continue;
+
+ strncpy(name, netdev->name, IFNAMSIZ);
+
+ unregister_sja1000dev(netdev);
+
+ free_sja1000dev(netdev);
+
+ dev_info(&card->pdev->dev, "%s removed\n", name);
+ }
+
+ /* do it only if device not removed */
+ if (pcan_pccard_present(card)) {
+ pcan_set_leds(card, led_mask, PCC_LED_OFF);
+ pcan_set_can_power(card, 0);
+ }
+}
+
+/*
+ * check if a CAN controller is present at the specified location
+ */
+static inline int pcan_channel_present(struct sja1000_priv *priv)
+{
+ /* make sure SJA1000 is in reset mode */
+ pcan_write_canreg(priv, SJA1000_MOD, 1);
+ pcan_write_canreg(priv, SJA1000_CDR, CDR_PELICAN);
+
+ /* read reset-values */
+ if (pcan_read_canreg(priv, SJA1000_CDR) == CDR_PELICAN)
+ return 1;
+
+ return 0;
+}
+
+static int pcan_add_channels(struct pcan_pccard *card)
+{
+ struct pcmcia_device *pdev = card->pdev;
+ int i, err = 0;
+ u8 ccr = PCC_CCR_INIT;
+
+ /* init common registers (reset channels and leds off) */
+ card->ccr = ~ccr;
+ pcan_write_reg(card, PCC_CCR, ccr);
+
+ /* wait 2ms before unresetting channels */
+ mdelay(2);
+
+ ccr &= ~PCC_CCR_RST_ALL;
+ pcan_write_reg(card, PCC_CCR, ccr);
+
+ /* create one network device per channel detected */
+ for (i = 0; i < ARRAY_SIZE(card->channel); i++) {
+ struct net_device *netdev;
+ struct sja1000_priv *priv;
+
+ netdev = alloc_sja1000dev(0);
+ if (!netdev) {
+ err = -ENOMEM;
+ break;
+ }
+
+ /* update linkages */
+ priv = netdev_priv(netdev);
+ priv->priv = card;
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ netdev->dev_id = i;
+
+ priv->irq_flags = IRQF_SHARED;
+ netdev->irq = pdev->irq;
+ priv->reg_base = card->ioport_addr + PCC_CHAN_OFF(i);
+
+ /* check if channel is present */
+ if (!pcan_channel_present(priv)) {
+ dev_err(&pdev->dev, "channel %d not present\n", i);
+ free_sja1000dev(netdev);
+ continue;
+ }
+
+ priv->read_reg = pcan_read_canreg;
+ priv->write_reg = pcan_write_canreg;
+ priv->can.clock.freq = PCC_CAN_CLOCK;
+ priv->ocr = PCC_OCR;
+ priv->cdr = PCC_CDR;
+
+ /* Neither a slave device distributes the clock */
+ if (i > 0)
+ priv->cdr |= CDR_CLK_OFF;
+
+ priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER;
+
+ /* register SJA1000 device */
+ err = register_sja1000dev(netdev);
+ if (err) {
+ free_sja1000dev(netdev);
+ continue;
+ }
+
+ card->channel[i].netdev = netdev;
+ card->chan_count++;
+
+ /* set corresponding led on in the new ccr */
+ ccr &= ~PCC_CCR_LED_OFF_CHAN(i);
+
+ dev_info(&pdev->dev,
+ "%s on channel %d at 0x%p irq %d\n",
+ netdev->name, i, priv->reg_base, pdev->irq);
+ }
+
+ /* write new ccr (change leds state) */
+ pcan_write_reg(card, PCC_CCR, ccr);
+
+ return err;
+}
+
+static int pcan_conf_check(struct pcmcia_device *pdev, void *priv_data)
+{
+ pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; /* only */
+ pdev->io_lines = 10;
+
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(pdev);
+}
+
+/*
+ * free all resources used by the device
+ */
+static void pcan_free(struct pcmcia_device *pdev)
+{
+ struct pcan_pccard *card = pdev->priv;
+
+ if (!card)
+ return;
+
+ free_irq(pdev->irq, card);
+ pcan_stop_led_timer(card);
+
+ pcan_free_channels(card);
+
+ ioport_unmap(card->ioport_addr);
+
+ kfree(card);
+ pdev->priv = NULL;
+}
+
+/*
+ * setup PCMCIA socket and probe for PEAK-System PC-CARD
+ */
+static int pcan_probe(struct pcmcia_device *pdev)
+{
+ struct pcan_pccard *card;
+ int err;
+
+ pdev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+
+ err = pcmcia_loop_config(pdev, pcan_conf_check, NULL);
+ if (err) {
+ dev_err(&pdev->dev, "pcmcia_loop_config() error %d\n", err);
+ goto probe_err_1;
+ }
+
+ if (!pdev->irq) {
+ dev_err(&pdev->dev, "no irq assigned\n");
+ err = -ENODEV;
+ goto probe_err_1;
+ }
+
+ err = pcmcia_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pcmcia_enable_device failed err=%d\n",
+ err);
+ goto probe_err_1;
+ }
+
+ card = kzalloc(sizeof(struct pcan_pccard), GFP_KERNEL);
+ if (!card) {
+ err = -ENOMEM;
+ goto probe_err_2;
+ }
+
+ card->pdev = pdev;
+ pdev->priv = card;
+
+ /* sja1000 api uses iomem */
+ card->ioport_addr = ioport_map(pdev->resource[0]->start,
+ resource_size(pdev->resource[0]));
+ if (!card->ioport_addr) {
+ dev_err(&pdev->dev, "couldn't map io port into io memory\n");
+ err = -ENOMEM;
+ goto probe_err_3;
+ }
+ card->fw_major = pcan_read_reg(card, PCC_FW_MAJOR);
+ card->fw_minor = pcan_read_reg(card, PCC_FW_MINOR);
+
+ /* display board name and firware version */
+ dev_info(&pdev->dev, "PEAK-System pcmcia card %s fw %d.%d\n",
+ pdev->prod_id[1] ? pdev->prod_id[1] : "PCAN-PC Card",
+ card->fw_major, card->fw_minor);
+
+ /* detect available channels */
+ pcan_add_channels(card);
+ if (!card->chan_count) {
+ err = -ENOMEM;
+ goto probe_err_4;
+ }
+
+ /* init the timer which controls the leds */
+ init_timer(&card->led_timer);
+ card->led_timer.function = pcan_led_timer;
+ card->led_timer.data = (unsigned long)card;
+
+ /* request the given irq */
+ err = request_irq(pdev->irq, &pcan_isr, IRQF_SHARED, PCC_NAME, card);
+ if (err) {
+ dev_err(&pdev->dev, "couldn't request irq%d\n", pdev->irq);
+ goto probe_err_5;
+ }
+
+ /* power on the connectors */
+ pcan_set_can_power(card, 1);
+
+ return 0;
+
+probe_err_5:
+ /* unregister can devices from network */
+ pcan_free_channels(card);
+
+probe_err_4:
+ ioport_unmap(card->ioport_addr);
+
+probe_err_3:
+ kfree(card);
+ pdev->priv = NULL;
+
+probe_err_2:
+ pcmcia_disable_device(pdev);
+
+probe_err_1:
+ return err;
+}
+
+/*
+ * release claimed resources
+ */
+static void pcan_remove(struct pcmcia_device *pdev)
+{
+ pcan_free(pdev);
+ pcmcia_disable_device(pdev);
+}
+
+static struct pcmcia_driver pcan_driver = {
+ .name = PCC_NAME,
+ .probe = pcan_probe,
+ .remove = pcan_remove,
+ .id_table = pcan_table,
+};
+module_pcmcia_driver(pcan_driver);
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
new file mode 100644
index 00000000000..ec39b7cb228
--- /dev/null
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -0,0 +1,650 @@
+/*
+ * Copyright (C) 2008-2010 Pavel Cheblakov <P.B.Cheblakov@inp.nsk.su>
+ *
+ * Derived from the ems_pci.c driver:
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2008 Markus Plessing <plessing@ems-wuensche.com>
+ * Copyright (C) 2008 Sebastian Haas <haas@ems-wuensche.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_plx_pci"
+
+MODULE_AUTHOR("Pavel Cheblakov <P.B.Cheblakov@inp.nsk.su>");
+MODULE_DESCRIPTION("Socket-CAN driver for PLX90xx PCI-bridge cards with "
+ "the SJA1000 chips");
+MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
+ "Adlink PCI-7841/cPCI-7841 SE, "
+ "Marathon CAN-bus-PCI, "
+ "TEWS TECHNOLOGIES TPMC810, "
+ "esd CAN-PCI/CPCI/PCI104/200, "
+ "esd CAN-PCI/PMC/266, "
+ "esd CAN-PCIe/2000, "
+ "Connect Tech Inc. CANpro/104-Plus Opto (CRG001), "
+ "IXXAT PC-I 04/PCI, "
+ "ELCUS CAN-200-PCI")
+MODULE_LICENSE("GPL v2");
+
+#define PLX_PCI_MAX_CHAN 2
+
+struct plx_pci_card {
+ int channels; /* detected channels count */
+ struct net_device *net_dev[PLX_PCI_MAX_CHAN];
+ void __iomem *conf_addr;
+
+ /* Pointer to device-dependent reset function */
+ void (*reset_func)(struct pci_dev *pdev);
+};
+
+#define PLX_PCI_CAN_CLOCK (16000000 / 2)
+
+/* PLX9030/9050/9052 registers */
+#define PLX_INTCSR 0x4c /* Interrupt Control/Status */
+#define PLX_CNTRL 0x50 /* User I/O, Direct Slave Response,
+ * Serial EEPROM, and Initialization
+ * Control register
+ */
+
+#define PLX_LINT1_EN 0x1 /* Local interrupt 1 enable */
+#define PLX_LINT2_EN (1 << 3) /* Local interrupt 2 enable */
+#define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */
+#define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */
+
+/* PLX9056 registers */
+#define PLX9056_INTCSR 0x68 /* Interrupt Control/Status */
+#define PLX9056_CNTRL 0x6c /* Control / Software Reset */
+
+#define PLX9056_LINTI (1 << 11)
+#define PLX9056_PCI_INT_EN (1 << 8)
+#define PLX9056_PCI_RCR (1 << 29) /* Read Configuration Registers */
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means normal output mode, push-pull and the correct polarity.
+ */
+#define PLX_PCI_OCR (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 7
+ * (meaning direct oscillator output) because the second SJA1000 chip
+ * is driven by the first one CLKOUT output.
+ */
+#define PLX_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
+
+/* SJA1000 Control Register in the BasicCAN Mode */
+#define REG_CR 0x00
+
+/* States of some SJA1000 registers after hardware reset in the BasicCAN mode*/
+#define REG_CR_BASICCAN_INITIAL 0x21
+#define REG_CR_BASICCAN_INITIAL_MASK 0xa1
+#define REG_SR_BASICCAN_INITIAL 0x0c
+#define REG_IR_BASICCAN_INITIAL 0xe0
+
+/* States of some SJA1000 registers after hardware reset in the PeliCAN mode*/
+#define REG_MOD_PELICAN_INITIAL 0x01
+#define REG_SR_PELICAN_INITIAL 0x3c
+#define REG_IR_PELICAN_INITIAL 0x00
+
+#define ADLINK_PCI_VENDOR_ID 0x144A
+#define ADLINK_PCI_DEVICE_ID 0x7841
+
+#define ESD_PCI_SUB_SYS_ID_PCI200 0x0004
+#define ESD_PCI_SUB_SYS_ID_PCI266 0x0009
+#define ESD_PCI_SUB_SYS_ID_PMC266 0x000e
+#define ESD_PCI_SUB_SYS_ID_CPCI200 0x010b
+#define ESD_PCI_SUB_SYS_ID_PCIE2000 0x0200
+#define ESD_PCI_SUB_SYS_ID_PCI104200 0x0501
+
+#define CAN200PCI_DEVICE_ID 0x9030
+#define CAN200PCI_VENDOR_ID 0x10b5
+#define CAN200PCI_SUB_DEVICE_ID 0x0301
+#define CAN200PCI_SUB_VENDOR_ID 0xe1c5
+
+#define IXXAT_PCI_VENDOR_ID 0x10b5
+#define IXXAT_PCI_DEVICE_ID 0x9050
+#define IXXAT_PCI_SUB_SYS_ID 0x2540
+
+#define MARATHON_PCI_DEVICE_ID 0x2715
+
+#define TEWS_PCI_VENDOR_ID 0x1498
+#define TEWS_PCI_DEVICE_ID_TMPC810 0x032A
+
+#define CTI_PCI_VENDOR_ID 0x12c4
+#define CTI_PCI_DEVICE_ID_CRG001 0x0900
+
+static void plx_pci_reset_common(struct pci_dev *pdev);
+static void plx_pci_reset_marathon(struct pci_dev *pdev);
+static void plx9056_pci_reset_common(struct pci_dev *pdev);
+
+struct plx_pci_channel_map {
+ u32 bar;
+ u32 offset;
+ u32 size; /* 0x00 - auto, e.g. length of entire bar */
+};
+
+struct plx_pci_card_info {
+ const char *name;
+ int channel_count;
+ u32 can_clock;
+ u8 ocr; /* output control register */
+ u8 cdr; /* clock divider register */
+
+ /* Parameters for mapping local configuration space */
+ struct plx_pci_channel_map conf_map;
+
+ /* Parameters for mapping the SJA1000 chips */
+ struct plx_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CHAN];
+
+ /* Pointer to device-dependent reset function */
+ void (*reset_func)(struct pci_dev *pdev);
+};
+
+static struct plx_pci_card_info plx_pci_card_info_adlink = {
+ "Adlink PCI-7841/cPCI-7841", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {1, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x80, 0x80} },
+ &plx_pci_reset_common
+ /* based on PLX9052 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_adlink_se = {
+ "Adlink PCI-7841/cPCI-7841 SE", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x80, 0x80} },
+ &plx_pci_reset_common
+ /* based on PLX9052 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_esd200 = {
+ "esd CAN-PCI/CPCI/PCI104/200", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} },
+ &plx_pci_reset_common
+ /* based on PLX9030/9050 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_esd266 = {
+ "esd CAN-PCI/PMC/266", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} },
+ &plx9056_pci_reset_common
+ /* based on PLX9056 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_esd2000 = {
+ "esd CAN-PCIe/2000", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} },
+ &plx9056_pci_reset_common
+ /* based on PEX8311 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_ixxat = {
+ "IXXAT PC-I 04/PCI", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x200, 0x80} },
+ &plx_pci_reset_common
+ /* based on PLX9050 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_marathon = {
+ "Marathon CAN-bus-PCI", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x00, 0x00}, {4, 0x00, 0x00} },
+ &plx_pci_reset_marathon
+ /* based on PLX9052 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_tews = {
+ "TEWS TECHNOLOGIES TPMC810", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x000, 0x80}, {2, 0x100, 0x80} },
+ &plx_pci_reset_common
+ /* based on PLX9030 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_cti = {
+ "Connect Tech Inc. CANpro/104-Plus Opto (CRG001)", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {0, 0x00, 0x00}, { {2, 0x000, 0x80}, {2, 0x100, 0x80} },
+ &plx_pci_reset_common
+ /* based on PLX9030 */
+};
+
+static struct plx_pci_card_info plx_pci_card_info_elcus = {
+ "Eclus CAN-200-PCI", 2,
+ PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+ {1, 0x00, 0x00}, { {2, 0x00, 0x80}, {3, 0x00, 0x80} },
+ &plx_pci_reset_common
+ /* based on PLX9030 */
+};
+
+static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = {
+ {
+ /* Adlink PCI-7841/cPCI-7841 */
+ ADLINK_PCI_VENDOR_ID, ADLINK_PCI_DEVICE_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_NETWORK_OTHER << 8, ~0,
+ (kernel_ulong_t)&plx_pci_card_info_adlink
+ },
+ {
+ /* Adlink PCI-7841/cPCI-7841 SE */
+ ADLINK_PCI_VENDOR_ID, ADLINK_PCI_DEVICE_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_OTHER << 8, ~0,
+ (kernel_ulong_t)&plx_pci_card_info_adlink_se
+ },
+ {
+ /* esd CAN-PCI/200 */
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI200,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_esd200
+ },
+ {
+ /* esd CAN-CPCI/200 */
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_CPCI200,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_esd200
+ },
+ {
+ /* esd CAN-PCI104/200 */
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI104200,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_esd200
+ },
+ {
+ /* esd CAN-PCI/266 */
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056,
+ PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI266,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_esd266
+ },
+ {
+ /* esd CAN-PMC/266 */
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056,
+ PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PMC266,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_esd266
+ },
+ {
+ /* esd CAN-PCIE/2000 */
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056,
+ PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCIE2000,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_esd2000
+ },
+ {
+ /* IXXAT PC-I 04/PCI card */
+ IXXAT_PCI_VENDOR_ID, IXXAT_PCI_DEVICE_ID,
+ PCI_ANY_ID, IXXAT_PCI_SUB_SYS_ID,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_ixxat
+ },
+ {
+ /* Marathon CAN-bus-PCI card */
+ PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_marathon
+ },
+ {
+ /* TEWS TECHNOLOGIES TPMC810 card */
+ TEWS_PCI_VENDOR_ID, TEWS_PCI_DEVICE_ID_TMPC810,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_tews
+ },
+ {
+ /* Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card */
+ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ CTI_PCI_VENDOR_ID, CTI_PCI_DEVICE_ID_CRG001,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_cti
+ },
+ {
+ /* Elcus CAN-200-PCI */
+ CAN200PCI_VENDOR_ID, CAN200PCI_DEVICE_ID,
+ CAN200PCI_SUB_VENDOR_ID, CAN200PCI_SUB_DEVICE_ID,
+ 0, 0,
+ (kernel_ulong_t)&plx_pci_card_info_elcus
+ },
+ { 0,}
+};
+MODULE_DEVICE_TABLE(pci, plx_pci_tbl);
+
+static u8 plx_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+ return ioread8(priv->reg_base + port);
+}
+
+static void plx_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val)
+{
+ iowrite8(val, priv->reg_base + port);
+}
+
+/*
+ * Check if a CAN controller is present at the specified location
+ * by trying to switch 'em from the Basic mode into the PeliCAN mode.
+ * Also check states of some registers in reset mode.
+ */
+static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv)
+{
+ int flag = 0;
+
+ /*
+ * Check registers after hardware reset (the Basic mode)
+ * See states on p. 10 of the Datasheet.
+ */
+ if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) ==
+ REG_CR_BASICCAN_INITIAL &&
+ (priv->read_reg(priv, SJA1000_SR) == REG_SR_BASICCAN_INITIAL) &&
+ (priv->read_reg(priv, SJA1000_IR) == REG_IR_BASICCAN_INITIAL))
+ flag = 1;
+
+ /* Bring the SJA1000 into the PeliCAN mode*/
+ priv->write_reg(priv, SJA1000_CDR, CDR_PELICAN);
+
+ /*
+ * Check registers after reset in the PeliCAN mode.
+ * See states on p. 23 of the Datasheet.
+ */
+ if (priv->read_reg(priv, SJA1000_MOD) == REG_MOD_PELICAN_INITIAL &&
+ priv->read_reg(priv, SJA1000_SR) == REG_SR_PELICAN_INITIAL &&
+ priv->read_reg(priv, SJA1000_IR) == REG_IR_PELICAN_INITIAL)
+ return flag;
+
+ return 0;
+}
+
+/*
+ * PLX9030/50/52 software reset
+ * Also LRESET# asserts and brings to reset device on the Local Bus (if wired).
+ * For most cards it's enough for reset the SJA1000 chips.
+ */
+static void plx_pci_reset_common(struct pci_dev *pdev)
+{
+ struct plx_pci_card *card = pci_get_drvdata(pdev);
+ u32 cntrl;
+
+ cntrl = ioread32(card->conf_addr + PLX_CNTRL);
+ cntrl |= PLX_PCI_RESET;
+ iowrite32(cntrl, card->conf_addr + PLX_CNTRL);
+ udelay(100);
+ cntrl ^= PLX_PCI_RESET;
+ iowrite32(cntrl, card->conf_addr + PLX_CNTRL);
+};
+
+/*
+ * PLX9056 software reset
+ * Assert LRESET# and reset device(s) on the Local Bus (if wired).
+ */
+static void plx9056_pci_reset_common(struct pci_dev *pdev)
+{
+ struct plx_pci_card *card = pci_get_drvdata(pdev);
+ u32 cntrl;
+
+ /* issue a local bus reset */
+ cntrl = ioread32(card->conf_addr + PLX9056_CNTRL);
+ cntrl |= PLX_PCI_RESET;
+ iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
+ udelay(100);
+ cntrl ^= PLX_PCI_RESET;
+ iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
+
+ /* reload local configuration from EEPROM */
+ cntrl |= PLX9056_PCI_RCR;
+ iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
+
+ /*
+ * There is no safe way to poll for the end
+ * of reconfiguration process. Waiting for 10ms
+ * is safe.
+ */
+ mdelay(10);
+
+ cntrl ^= PLX9056_PCI_RCR;
+ iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL);
+};
+
+/* Special reset function for Marathon card */
+static void plx_pci_reset_marathon(struct pci_dev *pdev)
+{
+ void __iomem *reset_addr;
+ int i;
+ static const int reset_bar[2] = {3, 5};
+
+ plx_pci_reset_common(pdev);
+
+ for (i = 0; i < 2; i++) {
+ reset_addr = pci_iomap(pdev, reset_bar[i], 0);
+ if (!reset_addr) {
+ dev_err(&pdev->dev, "Failed to remap reset "
+ "space %d (BAR%d)\n", i, reset_bar[i]);
+ } else {
+ /* reset the SJA1000 chip */
+ iowrite8(0x1, reset_addr);
+ udelay(100);
+ pci_iounmap(pdev, reset_addr);
+ }
+ }
+}
+
+static void plx_pci_del_card(struct pci_dev *pdev)
+{
+ struct plx_pci_card *card = pci_get_drvdata(pdev);
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ int i = 0;
+
+ for (i = 0; i < PLX_PCI_MAX_CHAN; i++) {
+ dev = card->net_dev[i];
+ if (!dev)
+ continue;
+
+ dev_info(&pdev->dev, "Removing %s\n", dev->name);
+ unregister_sja1000dev(dev);
+ priv = netdev_priv(dev);
+ if (priv->reg_base)
+ pci_iounmap(pdev, priv->reg_base);
+ free_sja1000dev(dev);
+ }
+
+ card->reset_func(pdev);
+
+ /*
+ * Disable interrupts from PCI-card and disable local
+ * interrupts
+ */
+ if (pdev->device != PCI_DEVICE_ID_PLX_9056)
+ iowrite32(0x0, card->conf_addr + PLX_INTCSR);
+ else
+ iowrite32(0x0, card->conf_addr + PLX9056_INTCSR);
+
+ if (card->conf_addr)
+ pci_iounmap(pdev, card->conf_addr);
+
+ kfree(card);
+
+ pci_disable_device(pdev);
+}
+
+/*
+ * Probe PLX90xx based device for the SJA1000 chips and register each
+ * available CAN channel to SJA1000 Socket-CAN subsystem.
+ */
+static int plx_pci_add_card(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct sja1000_priv *priv;
+ struct net_device *dev;
+ struct plx_pci_card *card;
+ struct plx_pci_card_info *ci;
+ int err, i;
+ u32 val;
+ void __iomem *addr;
+
+ ci = (struct plx_pci_card_info *)ent->driver_data;
+
+ if (pci_enable_device(pdev) < 0) {
+ dev_err(&pdev->dev, "Failed to enable PCI device\n");
+ return -ENODEV;
+ }
+
+ dev_info(&pdev->dev, "Detected \"%s\" card at slot #%i\n",
+ ci->name, PCI_SLOT(pdev->devfn));
+
+ /* Allocate card structures to hold addresses, ... */
+ card = kzalloc(sizeof(*card), GFP_KERNEL);
+ if (!card) {
+ pci_disable_device(pdev);
+ return -ENOMEM;
+ }
+
+ pci_set_drvdata(pdev, card);
+
+ card->channels = 0;
+
+ /* Remap PLX90xx configuration space */
+ addr = pci_iomap(pdev, ci->conf_map.bar, ci->conf_map.size);
+ if (!addr) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "Failed to remap configuration space "
+ "(BAR%d)\n", ci->conf_map.bar);
+ goto failure_cleanup;
+ }
+ card->conf_addr = addr + ci->conf_map.offset;
+
+ ci->reset_func(pdev);
+ card->reset_func = ci->reset_func;
+
+ /* Detect available channels */
+ for (i = 0; i < ci->channel_count; i++) {
+ struct plx_pci_channel_map *cm = &ci->chan_map_tbl[i];
+
+ dev = alloc_sja1000dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto failure_cleanup;
+ }
+
+ card->net_dev[i] = dev;
+ priv = netdev_priv(dev);
+ priv->priv = card;
+ priv->irq_flags = IRQF_SHARED;
+
+ dev->irq = pdev->irq;
+
+ /*
+ * Remap IO space of the SJA1000 chips
+ * This is device-dependent mapping
+ */
+ addr = pci_iomap(pdev, cm->bar, cm->size);
+ if (!addr) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "Failed to remap BAR%d\n", cm->bar);
+ goto failure_cleanup;
+ }
+
+ priv->reg_base = addr + cm->offset;
+ priv->read_reg = plx_pci_read_reg;
+ priv->write_reg = plx_pci_write_reg;
+
+ /* Check if channel is present */
+ if (plx_pci_check_sja1000(priv)) {
+ priv->can.clock.freq = ci->can_clock;
+ priv->ocr = ci->ocr;
+ priv->cdr = ci->cdr;
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev->dev_id = i;
+
+ /* Register SJA1000 device */
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "Registering device failed "
+ "(err=%d)\n", err);
+ goto failure_cleanup;
+ }
+
+ card->channels++;
+
+ dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d "
+ "registered as %s\n", i + 1, priv->reg_base,
+ dev->irq, dev->name);
+ } else {
+ dev_err(&pdev->dev, "Channel #%d not detected\n",
+ i + 1);
+ free_sja1000dev(dev);
+ card->net_dev[i] = NULL;
+ }
+ }
+
+ if (!card->channels) {
+ err = -ENODEV;
+ goto failure_cleanup;
+ }
+
+ /*
+ * Enable interrupts from PCI-card (PLX90xx) and enable Local_1,
+ * Local_2 interrupts from the SJA1000 chips
+ */
+ if (pdev->device != PCI_DEVICE_ID_PLX_9056) {
+ val = ioread32(card->conf_addr + PLX_INTCSR);
+ if (pdev->subsystem_vendor == PCI_VENDOR_ID_ESDGMBH)
+ val |= PLX_LINT1_EN | PLX_PCI_INT_EN;
+ else
+ val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN;
+ iowrite32(val, card->conf_addr + PLX_INTCSR);
+ } else {
+ iowrite32(PLX9056_LINTI | PLX9056_PCI_INT_EN,
+ card->conf_addr + PLX9056_INTCSR);
+ }
+ return 0;
+
+failure_cleanup:
+ dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err);
+
+ plx_pci_del_card(pdev);
+
+ return err;
+}
+
+static struct pci_driver plx_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = plx_pci_tbl,
+ .probe = plx_pci_add_card,
+ .remove = plx_pci_del_card,
+};
+
+module_pci_driver(plx_pci_driver);
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
new file mode 100644
index 00000000000..f31499a32d7
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -0,0 +1,694 @@
+/*
+ * sja1000.c - Philips SJA1000 network device driver
+ *
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000"
+
+MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION(DRV_NAME "CAN netdevice driver");
+
+static const struct can_bittiming_const sja1000_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+};
+
+static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
+{
+ unsigned long flags;
+
+ /*
+ * The command register needs some locking and time to settle
+ * the write_reg() operation - especially on SMP systems.
+ */
+ spin_lock_irqsave(&priv->cmdreg_lock, flags);
+ priv->write_reg(priv, SJA1000_CMR, val);
+ priv->read_reg(priv, SJA1000_SR);
+ spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
+}
+
+static int sja1000_is_absent(struct sja1000_priv *priv)
+{
+ return (priv->read_reg(priv, SJA1000_MOD) == 0xFF);
+}
+
+static int sja1000_probe_chip(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ if (priv->reg_base && sja1000_is_absent(priv)) {
+ netdev_err(dev, "probing failed\n");
+ return 0;
+ }
+ return -1;
+}
+
+static void set_reset_mode(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ unsigned char status = priv->read_reg(priv, SJA1000_MOD);
+ int i;
+
+ /* disable interrupts */
+ priv->write_reg(priv, SJA1000_IER, IRQ_OFF);
+
+ for (i = 0; i < 100; i++) {
+ /* check reset bit */
+ if (status & MOD_RM) {
+ priv->can.state = CAN_STATE_STOPPED;
+ return;
+ }
+
+ /* reset chip */
+ priv->write_reg(priv, SJA1000_MOD, MOD_RM);
+ udelay(10);
+ status = priv->read_reg(priv, SJA1000_MOD);
+ }
+
+ netdev_err(dev, "setting SJA1000 into reset mode failed!\n");
+}
+
+static void set_normal_mode(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ unsigned char status = priv->read_reg(priv, SJA1000_MOD);
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ /* check reset bit */
+ if ((status & MOD_RM) == 0) {
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ /* enable interrupts */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+ priv->write_reg(priv, SJA1000_IER, IRQ_ALL);
+ else
+ priv->write_reg(priv, SJA1000_IER,
+ IRQ_ALL & ~IRQ_BEI);
+ return;
+ }
+
+ /* set chip to normal mode */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ priv->write_reg(priv, SJA1000_MOD, MOD_LOM);
+ else
+ priv->write_reg(priv, SJA1000_MOD, 0x00);
+
+ udelay(10);
+
+ status = priv->read_reg(priv, SJA1000_MOD);
+ }
+
+ netdev_err(dev, "setting SJA1000 into normal mode failed!\n");
+}
+
+static void sja1000_start(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ /* leave reset mode */
+ if (priv->can.state != CAN_STATE_STOPPED)
+ set_reset_mode(dev);
+
+ /* Clear error counters and error code capture */
+ priv->write_reg(priv, SJA1000_TXERR, 0x0);
+ priv->write_reg(priv, SJA1000_RXERR, 0x0);
+ priv->read_reg(priv, SJA1000_ECC);
+
+ /* leave reset mode */
+ set_normal_mode(dev);
+}
+
+static int sja1000_set_mode(struct net_device *dev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ sja1000_start(dev);
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int sja1000_set_bittiming(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u8 btr0, btr1;
+
+ btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+ btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+ (((bt->phase_seg2 - 1) & 0x7) << 4);
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ btr1 |= 0x80;
+
+ netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+ priv->write_reg(priv, SJA1000_BTR0, btr0);
+ priv->write_reg(priv, SJA1000_BTR1, btr1);
+
+ return 0;
+}
+
+static int sja1000_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ bec->txerr = priv->read_reg(priv, SJA1000_TXERR);
+ bec->rxerr = priv->read_reg(priv, SJA1000_RXERR);
+
+ return 0;
+}
+
+/*
+ * initialize SJA1000 chip:
+ * - reset chip
+ * - set output mode
+ * - set baudrate
+ * - enable interrupts
+ * - start operating mode
+ */
+static void chipset_init(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ /* set clock divider and output control register */
+ priv->write_reg(priv, SJA1000_CDR, priv->cdr | CDR_PELICAN);
+
+ /* set acceptance filter (accept all) */
+ priv->write_reg(priv, SJA1000_ACCC0, 0x00);
+ priv->write_reg(priv, SJA1000_ACCC1, 0x00);
+ priv->write_reg(priv, SJA1000_ACCC2, 0x00);
+ priv->write_reg(priv, SJA1000_ACCC3, 0x00);
+
+ priv->write_reg(priv, SJA1000_ACCM0, 0xFF);
+ priv->write_reg(priv, SJA1000_ACCM1, 0xFF);
+ priv->write_reg(priv, SJA1000_ACCM2, 0xFF);
+ priv->write_reg(priv, SJA1000_ACCM3, 0xFF);
+
+ priv->write_reg(priv, SJA1000_OCR, priv->ocr | OCR_MODE_NORMAL);
+}
+
+/*
+ * transmit a CAN message
+ * message layout in the sk_buff should be like this:
+ * xx xx xx xx ff ll 00 11 22 33 44 55 66 77
+ * [ can-id ] [flags] [len] [can data (up to 8 bytes]
+ */
+static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ uint8_t fi;
+ uint8_t dlc;
+ canid_t id;
+ uint8_t dreg;
+ int i;
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(dev);
+
+ fi = dlc = cf->can_dlc;
+ id = cf->can_id;
+
+ if (id & CAN_RTR_FLAG)
+ fi |= SJA1000_FI_RTR;
+
+ if (id & CAN_EFF_FLAG) {
+ fi |= SJA1000_FI_FF;
+ dreg = SJA1000_EFF_BUF;
+ priv->write_reg(priv, SJA1000_FI, fi);
+ priv->write_reg(priv, SJA1000_ID1, (id & 0x1fe00000) >> 21);
+ priv->write_reg(priv, SJA1000_ID2, (id & 0x001fe000) >> 13);
+ priv->write_reg(priv, SJA1000_ID3, (id & 0x00001fe0) >> 5);
+ priv->write_reg(priv, SJA1000_ID4, (id & 0x0000001f) << 3);
+ } else {
+ dreg = SJA1000_SFF_BUF;
+ priv->write_reg(priv, SJA1000_FI, fi);
+ priv->write_reg(priv, SJA1000_ID1, (id & 0x000007f8) >> 3);
+ priv->write_reg(priv, SJA1000_ID2, (id & 0x00000007) << 5);
+ }
+
+ for (i = 0; i < dlc; i++)
+ priv->write_reg(priv, dreg++, cf->data[i]);
+
+ can_put_echo_skb(skb, dev, 0);
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+ sja1000_write_cmdreg(priv, CMD_TR | CMD_AT);
+ else
+ sja1000_write_cmdreg(priv, CMD_TR);
+
+ return NETDEV_TX_OK;
+}
+
+static void sja1000_rx(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ uint8_t fi;
+ uint8_t dreg;
+ canid_t id;
+ int i;
+
+ /* create zero'ed CAN frame buffer */
+ skb = alloc_can_skb(dev, &cf);
+ if (skb == NULL)
+ return;
+
+ fi = priv->read_reg(priv, SJA1000_FI);
+
+ if (fi & SJA1000_FI_FF) {
+ /* extended frame format (EFF) */
+ dreg = SJA1000_EFF_BUF;
+ id = (priv->read_reg(priv, SJA1000_ID1) << 21)
+ | (priv->read_reg(priv, SJA1000_ID2) << 13)
+ | (priv->read_reg(priv, SJA1000_ID3) << 5)
+ | (priv->read_reg(priv, SJA1000_ID4) >> 3);
+ id |= CAN_EFF_FLAG;
+ } else {
+ /* standard frame format (SFF) */
+ dreg = SJA1000_SFF_BUF;
+ id = (priv->read_reg(priv, SJA1000_ID1) << 3)
+ | (priv->read_reg(priv, SJA1000_ID2) >> 5);
+ }
+
+ cf->can_dlc = get_can_dlc(fi & 0x0F);
+ if (fi & SJA1000_FI_RTR) {
+ id |= CAN_RTR_FLAG;
+ } else {
+ for (i = 0; i < cf->can_dlc; i++)
+ cf->data[i] = priv->read_reg(priv, dreg++);
+ }
+
+ cf->can_id = id;
+
+ /* release receive buffer */
+ sja1000_write_cmdreg(priv, CMD_RRB);
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ can_led_event(dev, CAN_LED_EVENT_RX);
+}
+
+static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ enum can_state state = priv->can.state;
+ uint8_t ecc, alc;
+
+ skb = alloc_can_err_skb(dev, &cf);
+ if (skb == NULL)
+ return -ENOMEM;
+
+ if (isrc & IRQ_DOI) {
+ /* data overrun interrupt */
+ netdev_dbg(dev, "data overrun interrupt\n");
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ sja1000_write_cmdreg(priv, CMD_CDO); /* clear bit */
+ }
+
+ if (isrc & IRQ_EI) {
+ /* error warning interrupt */
+ netdev_dbg(dev, "error warning interrupt\n");
+
+ if (status & SR_BS) {
+ state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(dev);
+ } else if (status & SR_ES) {
+ state = CAN_STATE_ERROR_WARNING;
+ } else
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
+ if (isrc & IRQ_BEI) {
+ /* bus error interrupt */
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ ecc = priv->read_reg(priv, SJA1000_ECC);
+
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (ecc & ECC_MASK) {
+ case ECC_BIT:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ break;
+ case ECC_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case ECC_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ default:
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ cf->data[3] = ecc & ECC_SEG;
+ break;
+ }
+ /* Error occurred during transmission? */
+ if ((ecc & ECC_DIR) == 0)
+ cf->data[2] |= CAN_ERR_PROT_TX;
+ }
+ if (isrc & IRQ_EPI) {
+ /* error passive interrupt */
+ netdev_dbg(dev, "error passive interrupt\n");
+ if (status & SR_ES)
+ state = CAN_STATE_ERROR_PASSIVE;
+ else
+ state = CAN_STATE_ERROR_ACTIVE;
+ }
+ if (isrc & IRQ_ALI) {
+ /* arbitration lost interrupt */
+ netdev_dbg(dev, "arbitration lost interrupt\n");
+ alc = priv->read_reg(priv, SJA1000_ALC);
+ priv->can.can_stats.arbitration_lost++;
+ stats->tx_errors++;
+ cf->can_id |= CAN_ERR_LOSTARB;
+ cf->data[0] = alc & 0x1f;
+ }
+
+ if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
+ state == CAN_STATE_ERROR_PASSIVE)) {
+ uint8_t rxerr = priv->read_reg(priv, SJA1000_RXERR);
+ uint8_t txerr = priv->read_reg(priv, SJA1000_TXERR);
+ cf->can_id |= CAN_ERR_CRTL;
+ if (state == CAN_STATE_ERROR_WARNING) {
+ priv->can.can_stats.error_warning++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ } else {
+ priv->can.can_stats.error_passive++;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+
+ priv->can.state = state;
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ return 0;
+}
+
+irqreturn_t sja1000_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct sja1000_priv *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ uint8_t isrc, status;
+ int n = 0;
+
+ if (priv->pre_irq)
+ priv->pre_irq(priv);
+
+ /* Shared interrupts and IRQ off? */
+ if (priv->read_reg(priv, SJA1000_IER) == IRQ_OFF)
+ goto out;
+
+ while ((isrc = priv->read_reg(priv, SJA1000_IR)) &&
+ (n < SJA1000_MAX_IRQ)) {
+
+ status = priv->read_reg(priv, SJA1000_SR);
+ /* check for absent controller due to hw unplug */
+ if (status == 0xFF && sja1000_is_absent(priv))
+ goto out;
+
+ if (isrc & IRQ_WUI)
+ netdev_warn(dev, "wakeup interrupt\n");
+
+ if (isrc & IRQ_TI) {
+ /* transmission buffer released */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT &&
+ !(status & SR_TCS)) {
+ stats->tx_errors++;
+ can_free_echo_skb(dev, 0);
+ } else {
+ /* transmission complete */
+ stats->tx_bytes +=
+ priv->read_reg(priv, SJA1000_FI) & 0xf;
+ stats->tx_packets++;
+ can_get_echo_skb(dev, 0);
+ }
+ netif_wake_queue(dev);
+ can_led_event(dev, CAN_LED_EVENT_TX);
+ }
+ if (isrc & IRQ_RI) {
+ /* receive interrupt */
+ while (status & SR_RBS) {
+ sja1000_rx(dev);
+ status = priv->read_reg(priv, SJA1000_SR);
+ /* check for absent controller */
+ if (status == 0xFF && sja1000_is_absent(priv))
+ goto out;
+ }
+ }
+ if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
+ /* error interrupt */
+ if (sja1000_err(dev, isrc, status))
+ break;
+ }
+ n++;
+ }
+out:
+ if (priv->post_irq)
+ priv->post_irq(priv);
+
+ if (n >= SJA1000_MAX_IRQ)
+ netdev_dbg(dev, "%d messages handled in ISR", n);
+
+ return (n) ? IRQ_HANDLED : IRQ_NONE;
+}
+EXPORT_SYMBOL_GPL(sja1000_interrupt);
+
+static int sja1000_open(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+ int err;
+
+ /* set chip into reset mode */
+ set_reset_mode(dev);
+
+ /* common open */
+ err = open_candev(dev);
+ if (err)
+ return err;
+
+ /* register interrupt handler, if not done by the device driver */
+ if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) {
+ err = request_irq(dev->irq, sja1000_interrupt, priv->irq_flags,
+ dev->name, (void *)dev);
+ if (err) {
+ close_candev(dev);
+ return -EAGAIN;
+ }
+ }
+
+ /* init and start chi */
+ sja1000_start(dev);
+
+ can_led_event(dev, CAN_LED_EVENT_OPEN);
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static int sja1000_close(struct net_device *dev)
+{
+ struct sja1000_priv *priv = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+ set_reset_mode(dev);
+
+ if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER))
+ free_irq(dev->irq, (void *)dev);
+
+ close_candev(dev);
+
+ can_led_event(dev, CAN_LED_EVENT_STOP);
+
+ return 0;
+}
+
+struct net_device *alloc_sja1000dev(int sizeof_priv)
+{
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+
+ dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv,
+ SJA1000_ECHO_SKB_MAX);
+ if (!dev)
+ return NULL;
+
+ priv = netdev_priv(dev);
+
+ priv->dev = dev;
+ priv->can.bittiming_const = &sja1000_bittiming_const;
+ priv->can.do_set_bittiming = sja1000_set_bittiming;
+ priv->can.do_set_mode = sja1000_set_mode;
+ priv->can.do_get_berr_counter = sja1000_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_ONE_SHOT;
+
+ spin_lock_init(&priv->cmdreg_lock);
+
+ if (sizeof_priv)
+ priv->priv = (void *)priv + sizeof(struct sja1000_priv);
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_sja1000dev);
+
+void free_sja1000dev(struct net_device *dev)
+{
+ free_candev(dev);
+}
+EXPORT_SYMBOL_GPL(free_sja1000dev);
+
+static const struct net_device_ops sja1000_netdev_ops = {
+ .ndo_open = sja1000_open,
+ .ndo_stop = sja1000_close,
+ .ndo_start_xmit = sja1000_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+int register_sja1000dev(struct net_device *dev)
+{
+ int ret;
+
+ if (!sja1000_probe_chip(dev))
+ return -ENODEV;
+
+ dev->flags |= IFF_ECHO; /* we support local echo */
+ dev->netdev_ops = &sja1000_netdev_ops;
+
+ set_reset_mode(dev);
+ chipset_init(dev);
+
+ ret = register_candev(dev);
+
+ if (!ret)
+ devm_can_led_init(dev);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(register_sja1000dev);
+
+void unregister_sja1000dev(struct net_device *dev)
+{
+ set_reset_mode(dev);
+ unregister_candev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_sja1000dev);
+
+static __init int sja1000_init(void)
+{
+ printk(KERN_INFO "%s CAN netdevice driver\n", DRV_NAME);
+
+ return 0;
+}
+
+module_init(sja1000_init);
+
+static __exit void sja1000_exit(void)
+{
+ printk(KERN_INFO "%s: driver removed\n", DRV_NAME);
+}
+
+module_exit(sja1000_exit);
diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h
new file mode 100644
index 00000000000..9d46398f815
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000.h
@@ -0,0 +1,182 @@
+/*
+ * sja1000.h - Philips SJA1000 network device driver
+ *
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef SJA1000_DEV_H
+#define SJA1000_DEV_H
+
+#include <linux/irqreturn.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+
+#define SJA1000_ECHO_SKB_MAX 1 /* the SJA1000 has one TX buffer object */
+
+#define SJA1000_MAX_IRQ 20 /* max. number of interrupts handled in ISR */
+
+/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
+#define SJA1000_MOD 0x00
+#define SJA1000_CMR 0x01
+#define SJA1000_SR 0x02
+#define SJA1000_IR 0x03
+#define SJA1000_IER 0x04
+#define SJA1000_ALC 0x0B
+#define SJA1000_ECC 0x0C
+#define SJA1000_EWL 0x0D
+#define SJA1000_RXERR 0x0E
+#define SJA1000_TXERR 0x0F
+#define SJA1000_ACCC0 0x10
+#define SJA1000_ACCC1 0x11
+#define SJA1000_ACCC2 0x12
+#define SJA1000_ACCC3 0x13
+#define SJA1000_ACCM0 0x14
+#define SJA1000_ACCM1 0x15
+#define SJA1000_ACCM2 0x16
+#define SJA1000_ACCM3 0x17
+#define SJA1000_RMC 0x1D
+#define SJA1000_RBSA 0x1E
+
+/* Common registers - manual section 6.5 */
+#define SJA1000_BTR0 0x06
+#define SJA1000_BTR1 0x07
+#define SJA1000_OCR 0x08
+#define SJA1000_CDR 0x1F
+
+#define SJA1000_FI 0x10
+#define SJA1000_SFF_BUF 0x13
+#define SJA1000_EFF_BUF 0x15
+
+#define SJA1000_FI_FF 0x80
+#define SJA1000_FI_RTR 0x40
+
+#define SJA1000_ID1 0x11
+#define SJA1000_ID2 0x12
+#define SJA1000_ID3 0x13
+#define SJA1000_ID4 0x14
+
+#define SJA1000_CAN_RAM 0x20
+
+/* mode register */
+#define MOD_RM 0x01
+#define MOD_LOM 0x02
+#define MOD_STM 0x04
+#define MOD_AFM 0x08
+#define MOD_SM 0x10
+
+/* commands */
+#define CMD_SRR 0x10
+#define CMD_CDO 0x08
+#define CMD_RRB 0x04
+#define CMD_AT 0x02
+#define CMD_TR 0x01
+
+/* interrupt sources */
+#define IRQ_BEI 0x80
+#define IRQ_ALI 0x40
+#define IRQ_EPI 0x20
+#define IRQ_WUI 0x10
+#define IRQ_DOI 0x08
+#define IRQ_EI 0x04
+#define IRQ_TI 0x02
+#define IRQ_RI 0x01
+#define IRQ_ALL 0xFF
+#define IRQ_OFF 0x00
+
+/* status register content */
+#define SR_BS 0x80
+#define SR_ES 0x40
+#define SR_TS 0x20
+#define SR_RS 0x10
+#define SR_TCS 0x08
+#define SR_TBS 0x04
+#define SR_DOS 0x02
+#define SR_RBS 0x01
+
+#define SR_CRIT (SR_BS|SR_ES)
+
+/* ECC register */
+#define ECC_SEG 0x1F
+#define ECC_DIR 0x20
+#define ECC_ERR 6
+#define ECC_BIT 0x00
+#define ECC_FORM 0x40
+#define ECC_STUFF 0x80
+#define ECC_MASK 0xc0
+
+/*
+ * Flags for sja1000priv.flags
+ */
+#define SJA1000_CUSTOM_IRQ_HANDLER 0x1
+
+/*
+ * SJA1000 private data structure
+ */
+struct sja1000_priv {
+ struct can_priv can; /* must be the first member */
+ struct sk_buff *echo_skb;
+
+ /* the lower-layer is responsible for appropriate locking */
+ u8 (*read_reg) (const struct sja1000_priv *priv, int reg);
+ void (*write_reg) (const struct sja1000_priv *priv, int reg, u8 val);
+ void (*pre_irq) (const struct sja1000_priv *priv);
+ void (*post_irq) (const struct sja1000_priv *priv);
+
+ void *priv; /* for board-specific data */
+ struct net_device *dev;
+
+ void __iomem *reg_base; /* ioremap'ed address to registers */
+ unsigned long irq_flags; /* for request_irq() */
+ spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */
+
+ u16 flags; /* custom mode flags */
+ u8 ocr; /* output control register */
+ u8 cdr; /* clock divider register */
+};
+
+struct net_device *alloc_sja1000dev(int sizeof_priv);
+void free_sja1000dev(struct net_device *dev);
+int register_sja1000dev(struct net_device *dev);
+void unregister_sja1000dev(struct net_device *dev);
+
+irqreturn_t sja1000_interrupt(int irq, void *dev_id);
+
+#endif /* SJA1000_DEV_H */
diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c
new file mode 100644
index 00000000000..014695d7e6a
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000_isa.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_isa"
+
+#define MAXDEV 8
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the ISA bus");
+MODULE_LICENSE("GPL v2");
+
+#define CLK_DEFAULT 16000000 /* 16 MHz */
+#define CDR_DEFAULT (CDR_CBP | CDR_CLK_OFF)
+#define OCR_DEFAULT OCR_TX0_PUSHPULL
+
+static unsigned long port[MAXDEV];
+static unsigned long mem[MAXDEV];
+static int irq[MAXDEV];
+static int clk[MAXDEV];
+static unsigned char cdr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static unsigned char ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
+static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
+static spinlock_t indirect_lock[MAXDEV]; /* lock for indirect access mode */
+
+module_param_array(port, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(port, "I/O port number");
+
+module_param_array(mem, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(mem, "I/O memory address");
+
+module_param_array(indirect, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(indirect, "Indirect access via address and data port");
+
+module_param_array(irq, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(irq, "IRQ number");
+
+module_param_array(clk, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(clk, "External oscillator clock frequency "
+ "(default=16000000 [16 MHz])");
+
+module_param_array(cdr, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(cdr, "Clock divider register "
+ "(default=0x48 [CDR_CBP | CDR_CLK_OFF])");
+
+module_param_array(ocr, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(ocr, "Output control register "
+ "(default=0x18 [OCR_TX0_PUSHPULL])");
+
+#define SJA1000_IOSIZE 0x20
+#define SJA1000_IOSIZE_INDIRECT 0x02
+
+static struct platform_device *sja1000_isa_devs[MAXDEV];
+
+static u8 sja1000_isa_mem_read_reg(const struct sja1000_priv *priv, int reg)
+{
+ return readb(priv->reg_base + reg);
+}
+
+static void sja1000_isa_mem_write_reg(const struct sja1000_priv *priv,
+ int reg, u8 val)
+{
+ writeb(val, priv->reg_base + reg);
+}
+
+static u8 sja1000_isa_port_read_reg(const struct sja1000_priv *priv, int reg)
+{
+ return inb((unsigned long)priv->reg_base + reg);
+}
+
+static void sja1000_isa_port_write_reg(const struct sja1000_priv *priv,
+ int reg, u8 val)
+{
+ outb(val, (unsigned long)priv->reg_base + reg);
+}
+
+static u8 sja1000_isa_port_read_reg_indirect(const struct sja1000_priv *priv,
+ int reg)
+{
+ unsigned long flags, base = (unsigned long)priv->reg_base;
+ u8 readval;
+
+ spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags);
+ outb(reg, base);
+ readval = inb(base + 1);
+ spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags);
+
+ return readval;
+}
+
+static void sja1000_isa_port_write_reg_indirect(const struct sja1000_priv *priv,
+ int reg, u8 val)
+{
+ unsigned long flags, base = (unsigned long)priv->reg_base;
+
+ spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags);
+ outb(reg, base);
+ outb(val, base + 1);
+ spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags);
+}
+
+static int sja1000_isa_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ void __iomem *base = NULL;
+ int iosize = SJA1000_IOSIZE;
+ int idx = pdev->id;
+ int err;
+
+ dev_dbg(&pdev->dev, "probing idx=%d: port=%#lx, mem=%#lx, irq=%d\n",
+ idx, port[idx], mem[idx], irq[idx]);
+
+ if (mem[idx]) {
+ if (!request_mem_region(mem[idx], iosize, DRV_NAME)) {
+ err = -EBUSY;
+ goto exit;
+ }
+ base = ioremap_nocache(mem[idx], iosize);
+ if (!base) {
+ err = -ENOMEM;
+ goto exit_release;
+ }
+ } else {
+ if (indirect[idx] > 0 ||
+ (indirect[idx] == -1 && indirect[0] > 0))
+ iosize = SJA1000_IOSIZE_INDIRECT;
+ if (!request_region(port[idx], iosize, DRV_NAME)) {
+ err = -EBUSY;
+ goto exit;
+ }
+ }
+
+ dev = alloc_sja1000dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_unmap;
+ }
+ priv = netdev_priv(dev);
+
+ dev->irq = irq[idx];
+ priv->irq_flags = IRQF_SHARED;
+ if (mem[idx]) {
+ priv->reg_base = base;
+ dev->base_addr = mem[idx];
+ priv->read_reg = sja1000_isa_mem_read_reg;
+ priv->write_reg = sja1000_isa_mem_write_reg;
+ } else {
+ priv->reg_base = (void __iomem *)port[idx];
+ dev->base_addr = port[idx];
+
+ if (iosize == SJA1000_IOSIZE_INDIRECT) {
+ priv->read_reg = sja1000_isa_port_read_reg_indirect;
+ priv->write_reg = sja1000_isa_port_write_reg_indirect;
+ spin_lock_init(&indirect_lock[idx]);
+ } else {
+ priv->read_reg = sja1000_isa_port_read_reg;
+ priv->write_reg = sja1000_isa_port_write_reg;
+ }
+ }
+
+ if (clk[idx])
+ priv->can.clock.freq = clk[idx] / 2;
+ else if (clk[0])
+ priv->can.clock.freq = clk[0] / 2;
+ else
+ priv->can.clock.freq = CLK_DEFAULT / 2;
+
+ if (ocr[idx] != 0xff)
+ priv->ocr = ocr[idx];
+ else if (ocr[0] != 0xff)
+ priv->ocr = ocr[0];
+ else
+ priv->ocr = OCR_DEFAULT;
+
+ if (cdr[idx] != 0xff)
+ priv->cdr = cdr[idx];
+ else if (cdr[0] != 0xff)
+ priv->cdr = cdr[0];
+ else
+ priv->cdr = CDR_DEFAULT;
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev->dev_id = idx;
+
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+ goto exit_unmap;
+ }
+
+ dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n",
+ DRV_NAME, priv->reg_base, dev->irq);
+ return 0;
+
+ exit_unmap:
+ if (mem[idx])
+ iounmap(base);
+ exit_release:
+ if (mem[idx])
+ release_mem_region(mem[idx], iosize);
+ else
+ release_region(port[idx], iosize);
+ exit:
+ return err;
+}
+
+static int sja1000_isa_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct sja1000_priv *priv = netdev_priv(dev);
+ int idx = pdev->id;
+
+ unregister_sja1000dev(dev);
+
+ if (mem[idx]) {
+ iounmap(priv->reg_base);
+ release_mem_region(mem[idx], SJA1000_IOSIZE);
+ } else {
+ if (priv->read_reg == sja1000_isa_port_read_reg_indirect)
+ release_region(port[idx], SJA1000_IOSIZE_INDIRECT);
+ else
+ release_region(port[idx], SJA1000_IOSIZE);
+ }
+ free_sja1000dev(dev);
+
+ return 0;
+}
+
+static struct platform_driver sja1000_isa_driver = {
+ .probe = sja1000_isa_probe,
+ .remove = sja1000_isa_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init sja1000_isa_init(void)
+{
+ int idx, err;
+
+ for (idx = 0; idx < MAXDEV; idx++) {
+ if ((port[idx] || mem[idx]) && irq[idx]) {
+ sja1000_isa_devs[idx] =
+ platform_device_alloc(DRV_NAME, idx);
+ if (!sja1000_isa_devs[idx]) {
+ err = -ENOMEM;
+ goto exit_free_devices;
+ }
+ err = platform_device_add(sja1000_isa_devs[idx]);
+ if (err) {
+ platform_device_put(sja1000_isa_devs[idx]);
+ goto exit_free_devices;
+ }
+ pr_debug("%s: platform device %d: port=%#lx, mem=%#lx, "
+ "irq=%d\n",
+ DRV_NAME, idx, port[idx], mem[idx], irq[idx]);
+ } else if (idx == 0 || port[idx] || mem[idx]) {
+ pr_err("%s: insufficient parameters supplied\n",
+ DRV_NAME);
+ err = -EINVAL;
+ goto exit_free_devices;
+ }
+ }
+
+ err = platform_driver_register(&sja1000_isa_driver);
+ if (err)
+ goto exit_free_devices;
+
+ pr_info("Legacy %s driver for max. %d devices registered\n",
+ DRV_NAME, MAXDEV);
+
+ return 0;
+
+exit_free_devices:
+ while (--idx >= 0) {
+ if (sja1000_isa_devs[idx])
+ platform_device_unregister(sja1000_isa_devs[idx]);
+ }
+
+ return err;
+}
+
+static void __exit sja1000_isa_exit(void)
+{
+ int idx;
+
+ platform_driver_unregister(&sja1000_isa_driver);
+ for (idx = 0; idx < MAXDEV; idx++) {
+ if (sja1000_isa_devs[idx])
+ platform_device_unregister(sja1000_isa_devs[idx]);
+ }
+}
+
+module_init(sja1000_isa_init);
+module_exit(sja1000_isa_exit);
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
new file mode 100644
index 00000000000..95a844a7ee7
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000_platform.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2005 Sascha Hauer, Pengutronix
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_platform"
+#define SP_CAN_CLOCK (16000000 / 2)
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_LICENSE("GPL v2");
+
+static u8 sp_read_reg8(const struct sja1000_priv *priv, int reg)
+{
+ return ioread8(priv->reg_base + reg);
+}
+
+static void sp_write_reg8(const struct sja1000_priv *priv, int reg, u8 val)
+{
+ iowrite8(val, priv->reg_base + reg);
+}
+
+static u8 sp_read_reg16(const struct sja1000_priv *priv, int reg)
+{
+ return ioread8(priv->reg_base + reg * 2);
+}
+
+static void sp_write_reg16(const struct sja1000_priv *priv, int reg, u8 val)
+{
+ iowrite8(val, priv->reg_base + reg * 2);
+}
+
+static u8 sp_read_reg32(const struct sja1000_priv *priv, int reg)
+{
+ return ioread8(priv->reg_base + reg * 4);
+}
+
+static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val)
+{
+ iowrite8(val, priv->reg_base + reg * 4);
+}
+
+static void sp_populate(struct sja1000_priv *priv,
+ struct sja1000_platform_data *pdata,
+ unsigned long resource_mem_flags)
+{
+ /* The CAN clock frequency is half the oscillator clock frequency */
+ priv->can.clock.freq = pdata->osc_freq / 2;
+ priv->ocr = pdata->ocr;
+ priv->cdr = pdata->cdr;
+
+ switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) {
+ case IORESOURCE_MEM_32BIT:
+ priv->read_reg = sp_read_reg32;
+ priv->write_reg = sp_write_reg32;
+ break;
+ case IORESOURCE_MEM_16BIT:
+ priv->read_reg = sp_read_reg16;
+ priv->write_reg = sp_write_reg16;
+ break;
+ case IORESOURCE_MEM_8BIT:
+ default:
+ priv->read_reg = sp_read_reg8;
+ priv->write_reg = sp_write_reg8;
+ break;
+ }
+}
+
+static void sp_populate_of(struct sja1000_priv *priv, struct device_node *of)
+{
+ int err;
+ u32 prop;
+
+ err = of_property_read_u32(of, "reg-io-width", &prop);
+ if (err)
+ prop = 1; /* 8 bit is default */
+
+ switch (prop) {
+ case 4:
+ priv->read_reg = sp_read_reg32;
+ priv->write_reg = sp_write_reg32;
+ break;
+ case 2:
+ priv->read_reg = sp_read_reg16;
+ priv->write_reg = sp_write_reg16;
+ break;
+ case 1: /* fallthrough */
+ default:
+ priv->read_reg = sp_read_reg8;
+ priv->write_reg = sp_write_reg8;
+ }
+
+ err = of_property_read_u32(of, "nxp,external-clock-frequency", &prop);
+ if (!err)
+ priv->can.clock.freq = prop / 2;
+ else
+ priv->can.clock.freq = SP_CAN_CLOCK; /* default */
+
+ err = of_property_read_u32(of, "nxp,tx-output-mode", &prop);
+ if (!err)
+ priv->ocr |= prop & OCR_MODE_MASK;
+ else
+ priv->ocr |= OCR_MODE_NORMAL; /* default */
+
+ err = of_property_read_u32(of, "nxp,tx-output-config", &prop);
+ if (!err)
+ priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+ else
+ priv->ocr |= OCR_TX0_PULLDOWN; /* default */
+
+ err = of_property_read_u32(of, "nxp,clock-out-frequency", &prop);
+ if (!err && prop) {
+ u32 divider = priv->can.clock.freq * 2 / prop;
+
+ if (divider > 1)
+ priv->cdr |= divider / 2 - 1;
+ else
+ priv->cdr |= CDR_CLKOUT_MASK;
+ } else {
+ priv->cdr |= CDR_CLK_OFF; /* default */
+ }
+
+ if (!of_property_read_bool(of, "nxp,no-comparator-bypass"))
+ priv->cdr |= CDR_CBP; /* default */
+}
+
+static int sp_probe(struct platform_device *pdev)
+{
+ int err, irq = 0;
+ void __iomem *addr;
+ struct net_device *dev;
+ struct sja1000_priv *priv;
+ struct resource *res_mem, *res_irq = NULL;
+ struct sja1000_platform_data *pdata;
+ struct device_node *of = pdev->dev.of_node;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata && !of) {
+ dev_err(&pdev->dev, "No platform data provided!\n");
+ return -ENODEV;
+ }
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res_mem)
+ return -ENODEV;
+
+ if (!devm_request_mem_region(&pdev->dev, res_mem->start,
+ resource_size(res_mem), DRV_NAME))
+ return -EBUSY;
+
+ addr = devm_ioremap_nocache(&pdev->dev, res_mem->start,
+ resource_size(res_mem));
+ if (!addr)
+ return -ENOMEM;
+
+ if (of)
+ irq = irq_of_parse_and_map(of, 0);
+ else
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (!irq && !res_irq)
+ return -ENODEV;
+
+ dev = alloc_sja1000dev(0);
+ if (!dev)
+ return -ENOMEM;
+ priv = netdev_priv(dev);
+
+ if (res_irq) {
+ irq = res_irq->start;
+ priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
+ if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE)
+ priv->irq_flags |= IRQF_SHARED;
+ } else {
+ priv->irq_flags = IRQF_SHARED;
+ }
+
+ dev->irq = irq;
+ priv->reg_base = addr;
+
+ if (of)
+ sp_populate_of(priv, of);
+ else
+ sp_populate(priv, pdata, res_mem->flags);
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = register_sja1000dev(dev);
+ if (err) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ DRV_NAME, err);
+ goto exit_free;
+ }
+
+ dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n",
+ DRV_NAME, priv->reg_base, dev->irq);
+ return 0;
+
+ exit_free:
+ free_sja1000dev(dev);
+ return err;
+}
+
+static int sp_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ unregister_sja1000dev(dev);
+ free_sja1000dev(dev);
+
+ return 0;
+}
+
+static struct of_device_id sp_of_table[] = {
+ {.compatible = "nxp,sja1000"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, sp_of_table);
+
+static struct platform_driver sp_driver = {
+ .probe = sp_probe,
+ .remove = sp_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sp_of_table,
+ },
+};
+
+module_platform_driver(sp_driver);
diff --git a/drivers/net/can/sja1000/tscan1.c b/drivers/net/can/sja1000/tscan1.c
new file mode 100644
index 00000000000..76513dd780c
--- /dev/null
+++ b/drivers/net/can/sja1000/tscan1.c
@@ -0,0 +1,216 @@
+/*
+ * tscan1.c: driver for Technologic Systems TS-CAN1 PC104 boards
+ *
+ * Copyright 2010 Andre B. Oliveira
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * References:
+ * - Getting started with TS-CAN1, Technologic Systems, Jun 2009
+ * http://www.embeddedarm.com/documentation/ts-can1-manual.pdf
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/isa.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include "sja1000.h"
+
+MODULE_DESCRIPTION("Driver for Technologic Systems TS-CAN1 PC104 boards");
+MODULE_AUTHOR("Andre B. Oliveira <anbadeol@gmail.com>");
+MODULE_LICENSE("GPL");
+
+/* Maximum number of boards (one in each JP1:JP2 setting of IO address) */
+#define TSCAN1_MAXDEV 4
+
+/* PLD registers address offsets */
+#define TSCAN1_ID1 0
+#define TSCAN1_ID2 1
+#define TSCAN1_VERSION 2
+#define TSCAN1_LED 3
+#define TSCAN1_PAGE 4
+#define TSCAN1_MODE 5
+#define TSCAN1_JUMPERS 6
+
+/* PLD board identifier registers magic values */
+#define TSCAN1_ID1_VALUE 0xf6
+#define TSCAN1_ID2_VALUE 0xb9
+
+/* PLD mode register SJA1000 IO enable bit */
+#define TSCAN1_MODE_ENABLE 0x40
+
+/* PLD jumpers register bits */
+#define TSCAN1_JP4 0x10
+#define TSCAN1_JP5 0x20
+
+/* PLD IO base addresses start */
+#define TSCAN1_PLD_ADDRESS 0x150
+
+/* PLD register space size */
+#define TSCAN1_PLD_SIZE 8
+
+/* SJA1000 register space size */
+#define TSCAN1_SJA1000_SIZE 32
+
+/* SJA1000 crystal frequency (16MHz) */
+#define TSCAN1_SJA1000_XTAL 16000000
+
+/* SJA1000 IO base addresses */
+static const unsigned short tscan1_sja1000_addresses[] = {
+ 0x100, 0x120, 0x180, 0x1a0, 0x200, 0x240, 0x280, 0x320
+};
+
+/* Read SJA1000 register */
+static u8 tscan1_read(const struct sja1000_priv *priv, int reg)
+{
+ return inb((unsigned long)priv->reg_base + reg);
+}
+
+/* Write SJA1000 register */
+static void tscan1_write(const struct sja1000_priv *priv, int reg, u8 val)
+{
+ outb(val, (unsigned long)priv->reg_base + reg);
+}
+
+/* Probe for a TS-CAN1 board with JP2:JP1 jumper setting ID */
+static int tscan1_probe(struct device *dev, unsigned id)
+{
+ struct net_device *netdev;
+ struct sja1000_priv *priv;
+ unsigned long pld_base, sja1000_base;
+ int irq, i;
+
+ pld_base = TSCAN1_PLD_ADDRESS + id * TSCAN1_PLD_SIZE;
+ if (!request_region(pld_base, TSCAN1_PLD_SIZE, dev_name(dev)))
+ return -EBUSY;
+
+ if (inb(pld_base + TSCAN1_ID1) != TSCAN1_ID1_VALUE ||
+ inb(pld_base + TSCAN1_ID2) != TSCAN1_ID2_VALUE) {
+ release_region(pld_base, TSCAN1_PLD_SIZE);
+ return -ENODEV;
+ }
+
+ switch (inb(pld_base + TSCAN1_JUMPERS) & (TSCAN1_JP4 | TSCAN1_JP5)) {
+ case TSCAN1_JP4:
+ irq = 6;
+ break;
+ case TSCAN1_JP5:
+ irq = 7;
+ break;
+ case TSCAN1_JP4 | TSCAN1_JP5:
+ irq = 5;
+ break;
+ default:
+ dev_err(dev, "invalid JP4:JP5 setting (no IRQ)\n");
+ release_region(pld_base, TSCAN1_PLD_SIZE);
+ return -EINVAL;
+ }
+
+ netdev = alloc_sja1000dev(0);
+ if (!netdev) {
+ release_region(pld_base, TSCAN1_PLD_SIZE);
+ return -ENOMEM;
+ }
+
+ dev_set_drvdata(dev, netdev);
+ SET_NETDEV_DEV(netdev, dev);
+
+ netdev->base_addr = pld_base;
+ netdev->irq = irq;
+
+ priv = netdev_priv(netdev);
+ priv->read_reg = tscan1_read;
+ priv->write_reg = tscan1_write;
+ priv->can.clock.freq = TSCAN1_SJA1000_XTAL / 2;
+ priv->cdr = CDR_CBP | CDR_CLK_OFF;
+ priv->ocr = OCR_TX0_PUSHPULL;
+
+ /* Select the first SJA1000 IO address that is free and that works */
+ for (i = 0; i < ARRAY_SIZE(tscan1_sja1000_addresses); i++) {
+ sja1000_base = tscan1_sja1000_addresses[i];
+ if (!request_region(sja1000_base, TSCAN1_SJA1000_SIZE,
+ dev_name(dev)))
+ continue;
+
+ /* Set SJA1000 IO base address and enable it */
+ outb(TSCAN1_MODE_ENABLE | i, pld_base + TSCAN1_MODE);
+
+ priv->reg_base = (void __iomem *)sja1000_base;
+ if (!register_sja1000dev(netdev)) {
+ /* SJA1000 probe succeeded; turn LED off and return */
+ outb(0, pld_base + TSCAN1_LED);
+ netdev_info(netdev, "TS-CAN1 at 0x%lx 0x%lx irq %d\n",
+ pld_base, sja1000_base, irq);
+ return 0;
+ }
+
+ /* SJA1000 probe failed; release and try next address */
+ outb(0, pld_base + TSCAN1_MODE);
+ release_region(sja1000_base, TSCAN1_SJA1000_SIZE);
+ }
+
+ dev_err(dev, "failed to assign SJA1000 IO address\n");
+ dev_set_drvdata(dev, NULL);
+ free_sja1000dev(netdev);
+ release_region(pld_base, TSCAN1_PLD_SIZE);
+ return -ENXIO;
+}
+
+static int tscan1_remove(struct device *dev, unsigned id /*unused*/)
+{
+ struct net_device *netdev;
+ struct sja1000_priv *priv;
+ unsigned long pld_base, sja1000_base;
+
+ netdev = dev_get_drvdata(dev);
+ unregister_sja1000dev(netdev);
+ dev_set_drvdata(dev, NULL);
+
+ priv = netdev_priv(netdev);
+ pld_base = netdev->base_addr;
+ sja1000_base = (unsigned long)priv->reg_base;
+
+ outb(0, pld_base + TSCAN1_MODE); /* disable SJA1000 IO space */
+
+ release_region(sja1000_base, TSCAN1_SJA1000_SIZE);
+ release_region(pld_base, TSCAN1_PLD_SIZE);
+
+ free_sja1000dev(netdev);
+
+ return 0;
+}
+
+static struct isa_driver tscan1_isa_driver = {
+ .probe = tscan1_probe,
+ .remove = tscan1_remove,
+ .driver = {
+ .name = "tscan1",
+ },
+};
+
+static int __init tscan1_init(void)
+{
+ return isa_register_driver(&tscan1_isa_driver, TSCAN1_MAXDEV);
+}
+module_init(tscan1_init);
+
+static void __exit tscan1_exit(void)
+{
+ isa_unregister_driver(&tscan1_isa_driver);
+}
+module_exit(tscan1_exit);
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
new file mode 100644
index 00000000000..ea4d4f1a641
--- /dev/null
+++ b/drivers/net/can/slcan.c
@@ -0,0 +1,782 @@
+/*
+ * slcan.c - serial line CAN interface driver (using tty line discipline)
+ *
+ * This file is derived from linux/drivers/net/slip/slip.c
+ *
+ * slip.c Authors : Laurence Culhane <loz@holmes.demon.co.uk>
+ * Fred N. van Kempen <waltje@uwalt.nl.mugnet.org>
+ * slcan.c Author : Oliver Hartkopp <socketcan@hartkopp.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see http://www.gnu.org/licenses/gpl.html
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
+#include <linux/can.h>
+#include <linux/can/skb.h>
+
+static __initconst const char banner[] =
+ KERN_INFO "slcan: serial line CAN interface driver\n";
+
+MODULE_ALIAS_LDISC(N_SLCAN);
+MODULE_DESCRIPTION("serial line CAN interface");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
+
+#define SLCAN_MAGIC 0x53CA
+
+static int maxdev = 10; /* MAX number of SLCAN channels;
+ This can be overridden with
+ insmod slcan.ko maxdev=nnn */
+module_param(maxdev, int, 0);
+MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces");
+
+/* maximum rx buffer len: extended CAN frame with timestamp */
+#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
+
+#define SLC_CMD_LEN 1
+#define SLC_SFF_ID_LEN 3
+#define SLC_EFF_ID_LEN 8
+
+struct slcan {
+ int magic;
+
+ /* Various fields. */
+ struct tty_struct *tty; /* ptr to TTY structure */
+ struct net_device *dev; /* easy for intr handling */
+ spinlock_t lock;
+ struct work_struct tx_work; /* Flushes transmit buffer */
+
+ /* These are pointers to the malloc()ed frame buffers. */
+ unsigned char rbuff[SLC_MTU]; /* receiver buffer */
+ int rcount; /* received chars counter */
+ unsigned char xbuff[SLC_MTU]; /* transmitter buffer */
+ unsigned char *xhead; /* pointer to next XMIT byte */
+ int xleft; /* bytes left in XMIT queue */
+
+ unsigned long flags; /* Flag values/ mode etc */
+#define SLF_INUSE 0 /* Channel in use */
+#define SLF_ERROR 1 /* Parity, etc. error */
+};
+
+static struct net_device **slcan_devs;
+
+ /************************************************************************
+ * SLCAN ENCAPSULATION FORMAT *
+ ************************************************************************/
+
+/*
+ * A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
+ * frame format) a data length code (can_dlc) which can be from 0 to 8
+ * and up to <can_dlc> data bytes as payload.
+ * Additionally a CAN frame may become a remote transmission frame if the
+ * RTR-bit is set. This causes another ECU to send a CAN frame with the
+ * given can_id.
+ *
+ * The SLCAN ASCII representation of these different frame types is:
+ * <type> <id> <dlc> <data>*
+ *
+ * Extended frames (29 bit) are defined by capital characters in the type.
+ * RTR frames are defined as 'r' types - normal frames have 't' type:
+ * t => 11 bit data frame
+ * r => 11 bit RTR frame
+ * T => 29 bit data frame
+ * R => 29 bit RTR frame
+ *
+ * The <id> is 3 (standard) or 8 (extended) bytes in ASCII Hex (base64).
+ * The <dlc> is a one byte ASCII number ('0' - '8')
+ * The <data> section has at much ASCII Hex bytes as defined by the <dlc>
+ *
+ * Examples:
+ *
+ * t1230 : can_id 0x123, can_dlc 0, no data
+ * t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33
+ * T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55
+ * r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request
+ *
+ */
+
+ /************************************************************************
+ * STANDARD SLCAN DECAPSULATION *
+ ************************************************************************/
+
+/* Send one completely decapsulated can_frame to the network layer */
+static void slc_bump(struct slcan *sl)
+{
+ struct sk_buff *skb;
+ struct can_frame cf;
+ int i, tmp;
+ u32 tmpid;
+ char *cmd = sl->rbuff;
+
+ cf.can_id = 0;
+
+ switch (*cmd) {
+ case 'r':
+ cf.can_id = CAN_RTR_FLAG;
+ /* fallthrough */
+ case 't':
+ /* store dlc ASCII value and terminate SFF CAN ID string */
+ cf.can_dlc = sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN];
+ sl->rbuff[SLC_CMD_LEN + SLC_SFF_ID_LEN] = 0;
+ /* point to payload data behind the dlc */
+ cmd += SLC_CMD_LEN + SLC_SFF_ID_LEN + 1;
+ break;
+ case 'R':
+ cf.can_id = CAN_RTR_FLAG;
+ /* fallthrough */
+ case 'T':
+ cf.can_id |= CAN_EFF_FLAG;
+ /* store dlc ASCII value and terminate EFF CAN ID string */
+ cf.can_dlc = sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN];
+ sl->rbuff[SLC_CMD_LEN + SLC_EFF_ID_LEN] = 0;
+ /* point to payload data behind the dlc */
+ cmd += SLC_CMD_LEN + SLC_EFF_ID_LEN + 1;
+ break;
+ default:
+ return;
+ }
+
+ if (kstrtou32(sl->rbuff + SLC_CMD_LEN, 16, &tmpid))
+ return;
+
+ cf.can_id |= tmpid;
+
+ /* get can_dlc from sanitized ASCII value */
+ if (cf.can_dlc >= '0' && cf.can_dlc < '9')
+ cf.can_dlc -= '0';
+ else
+ return;
+
+ *(u64 *) (&cf.data) = 0; /* clear payload */
+
+ /* RTR frames may have a dlc > 0 but they never have any data bytes */
+ if (!(cf.can_id & CAN_RTR_FLAG)) {
+ for (i = 0; i < cf.can_dlc; i++) {
+ tmp = hex_to_bin(*cmd++);
+ if (tmp < 0)
+ return;
+ cf.data[i] = (tmp << 4);
+ tmp = hex_to_bin(*cmd++);
+ if (tmp < 0)
+ return;
+ cf.data[i] |= tmp;
+ }
+ }
+
+ skb = dev_alloc_skb(sizeof(struct can_frame) +
+ sizeof(struct can_skb_priv));
+ if (!skb)
+ return;
+
+ skb->dev = sl->dev;
+ skb->protocol = htons(ETH_P_CAN);
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ can_skb_reserve(skb);
+ can_skb_prv(skb)->ifindex = sl->dev->ifindex;
+
+ memcpy(skb_put(skb, sizeof(struct can_frame)),
+ &cf, sizeof(struct can_frame));
+ netif_rx_ni(skb);
+
+ sl->dev->stats.rx_packets++;
+ sl->dev->stats.rx_bytes += cf.can_dlc;
+}
+
+/* parse tty input stream */
+static void slcan_unesc(struct slcan *sl, unsigned char s)
+{
+ if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
+ if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
+ (sl->rcount > 4)) {
+ slc_bump(sl);
+ }
+ sl->rcount = 0;
+ } else {
+ if (!test_bit(SLF_ERROR, &sl->flags)) {
+ if (sl->rcount < SLC_MTU) {
+ sl->rbuff[sl->rcount++] = s;
+ return;
+ } else {
+ sl->dev->stats.rx_over_errors++;
+ set_bit(SLF_ERROR, &sl->flags);
+ }
+ }
+ }
+}
+
+ /************************************************************************
+ * STANDARD SLCAN ENCAPSULATION *
+ ************************************************************************/
+
+/* Encapsulate one can_frame and stuff into a TTY queue. */
+static void slc_encaps(struct slcan *sl, struct can_frame *cf)
+{
+ int actual, i;
+ unsigned char *pos;
+ unsigned char *endpos;
+ canid_t id = cf->can_id;
+
+ pos = sl->xbuff;
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ *pos = 'R'; /* becomes 'r' in standard frame format (SFF) */
+ else
+ *pos = 'T'; /* becomes 't' in standard frame format (SSF) */
+
+ /* determine number of chars for the CAN-identifier */
+ if (cf->can_id & CAN_EFF_FLAG) {
+ id &= CAN_EFF_MASK;
+ endpos = pos + SLC_EFF_ID_LEN;
+ } else {
+ *pos |= 0x20; /* convert R/T to lower case for SFF */
+ id &= CAN_SFF_MASK;
+ endpos = pos + SLC_SFF_ID_LEN;
+ }
+
+ /* build 3 (SFF) or 8 (EFF) digit CAN identifier */
+ pos++;
+ while (endpos >= pos) {
+ *endpos-- = hex_asc_upper[id & 0xf];
+ id >>= 4;
+ }
+
+ pos += (cf->can_id & CAN_EFF_FLAG) ? SLC_EFF_ID_LEN : SLC_SFF_ID_LEN;
+
+ *pos++ = cf->can_dlc + '0';
+
+ /* RTR frames may have a dlc > 0 but they never have any data bytes */
+ if (!(cf->can_id & CAN_RTR_FLAG)) {
+ for (i = 0; i < cf->can_dlc; i++)
+ pos = hex_byte_pack_upper(pos, cf->data[i]);
+ }
+
+ *pos++ = '\r';
+
+ /* Order of next two lines is *very* important.
+ * When we are sending a little amount of data,
+ * the transfer may be completed inside the ops->write()
+ * routine, because it's running with interrupts enabled.
+ * In this case we *never* got WRITE_WAKEUP event,
+ * if we did not request it before write operation.
+ * 14 Oct 1994 Dmitry Gorodchanin.
+ */
+ set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+ actual = sl->tty->ops->write(sl->tty, sl->xbuff, pos - sl->xbuff);
+ sl->xleft = (pos - sl->xbuff) - actual;
+ sl->xhead = sl->xbuff + actual;
+ sl->dev->stats.tx_bytes += cf->can_dlc;
+}
+
+/* Write out any remaining transmit buffer. Scheduled when tty is writable */
+static void slcan_transmit(struct work_struct *work)
+{
+ struct slcan *sl = container_of(work, struct slcan, tx_work);
+ int actual;
+
+ spin_lock_bh(&sl->lock);
+ /* First make sure we're connected. */
+ if (!sl->tty || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) {
+ spin_unlock_bh(&sl->lock);
+ return;
+ }
+
+ if (sl->xleft <= 0) {
+ /* Now serial buffer is almost free & we can start
+ * transmission of another packet */
+ sl->dev->stats.tx_packets++;
+ clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+ spin_unlock_bh(&sl->lock);
+ netif_wake_queue(sl->dev);
+ return;
+ }
+
+ actual = sl->tty->ops->write(sl->tty, sl->xhead, sl->xleft);
+ sl->xleft -= actual;
+ sl->xhead += actual;
+ spin_unlock_bh(&sl->lock);
+}
+
+/*
+ * Called by the driver when there's room for more data.
+ * Schedule the transmit.
+ */
+static void slcan_write_wakeup(struct tty_struct *tty)
+{
+ struct slcan *sl = tty->disc_data;
+
+ schedule_work(&sl->tx_work);
+}
+
+/* Send a can_frame to a TTY queue. */
+static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct slcan *sl = netdev_priv(dev);
+
+ if (skb->len != sizeof(struct can_frame))
+ goto out;
+
+ spin_lock(&sl->lock);
+ if (!netif_running(dev)) {
+ spin_unlock(&sl->lock);
+ printk(KERN_WARNING "%s: xmit: iface is down\n", dev->name);
+ goto out;
+ }
+ if (sl->tty == NULL) {
+ spin_unlock(&sl->lock);
+ goto out;
+ }
+
+ netif_stop_queue(sl->dev);
+ slc_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */
+ spin_unlock(&sl->lock);
+
+out:
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+
+/******************************************
+ * Routines looking at netdevice side.
+ ******************************************/
+
+/* Netdevice UP -> DOWN routine */
+static int slc_close(struct net_device *dev)
+{
+ struct slcan *sl = netdev_priv(dev);
+
+ spin_lock_bh(&sl->lock);
+ if (sl->tty) {
+ /* TTY discipline is running. */
+ clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+ }
+ netif_stop_queue(dev);
+ sl->rcount = 0;
+ sl->xleft = 0;
+ spin_unlock_bh(&sl->lock);
+
+ return 0;
+}
+
+/* Netdevice DOWN -> UP routine */
+static int slc_open(struct net_device *dev)
+{
+ struct slcan *sl = netdev_priv(dev);
+
+ if (sl->tty == NULL)
+ return -ENODEV;
+
+ sl->flags &= (1 << SLF_INUSE);
+ netif_start_queue(dev);
+ return 0;
+}
+
+/* Hook the destructor so we can free slcan devs at the right point in time */
+static void slc_free_netdev(struct net_device *dev)
+{
+ int i = dev->base_addr;
+ free_netdev(dev);
+ slcan_devs[i] = NULL;
+}
+
+static int slcan_change_mtu(struct net_device *dev, int new_mtu)
+{
+ return -EINVAL;
+}
+
+static const struct net_device_ops slc_netdev_ops = {
+ .ndo_open = slc_open,
+ .ndo_stop = slc_close,
+ .ndo_start_xmit = slc_xmit,
+ .ndo_change_mtu = slcan_change_mtu,
+};
+
+static void slc_setup(struct net_device *dev)
+{
+ dev->netdev_ops = &slc_netdev_ops;
+ dev->destructor = slc_free_netdev;
+
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->tx_queue_len = 10;
+
+ dev->mtu = sizeof(struct can_frame);
+ dev->type = ARPHRD_CAN;
+
+ /* New-style flags. */
+ dev->flags = IFF_NOARP;
+ dev->features = NETIF_F_HW_CSUM;
+}
+
+/******************************************
+ Routines looking at TTY side.
+ ******************************************/
+
+/*
+ * Handle the 'receiver data ready' interrupt.
+ * This function is called by the 'tty_io' module in the kernel when
+ * a block of SLCAN data has been received, which can now be decapsulated
+ * and sent on to some IP layer for further processing. This will not
+ * be re-entered while running but other ldisc functions may be called
+ * in parallel
+ */
+
+static void slcan_receive_buf(struct tty_struct *tty,
+ const unsigned char *cp, char *fp, int count)
+{
+ struct slcan *sl = (struct slcan *) tty->disc_data;
+
+ if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
+ return;
+
+ /* Read the characters out of the buffer */
+ while (count--) {
+ if (fp && *fp++) {
+ if (!test_and_set_bit(SLF_ERROR, &sl->flags))
+ sl->dev->stats.rx_errors++;
+ cp++;
+ continue;
+ }
+ slcan_unesc(sl, *cp++);
+ }
+}
+
+/************************************
+ * slcan_open helper routines.
+ ************************************/
+
+/* Collect hanged up channels */
+static void slc_sync(void)
+{
+ int i;
+ struct net_device *dev;
+ struct slcan *sl;
+
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (dev == NULL)
+ break;
+
+ sl = netdev_priv(dev);
+ if (sl->tty)
+ continue;
+ if (dev->flags & IFF_UP)
+ dev_close(dev);
+ }
+}
+
+/* Find a free SLCAN channel, and link in this `tty' line. */
+static struct slcan *slc_alloc(dev_t line)
+{
+ int i;
+ char name[IFNAMSIZ];
+ struct net_device *dev = NULL;
+ struct slcan *sl;
+
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (dev == NULL)
+ break;
+
+ }
+
+ /* Sorry, too many, all slots in use */
+ if (i >= maxdev)
+ return NULL;
+
+ sprintf(name, "slcan%d", i);
+ dev = alloc_netdev(sizeof(*sl), name, slc_setup);
+ if (!dev)
+ return NULL;
+
+ dev->base_addr = i;
+ sl = netdev_priv(dev);
+
+ /* Initialize channel control data */
+ sl->magic = SLCAN_MAGIC;
+ sl->dev = dev;
+ spin_lock_init(&sl->lock);
+ INIT_WORK(&sl->tx_work, slcan_transmit);
+ slcan_devs[i] = dev;
+
+ return sl;
+}
+
+/*
+ * Open the high-level part of the SLCAN channel.
+ * This function is called by the TTY module when the
+ * SLCAN line discipline is called for. Because we are
+ * sure the tty line exists, we only have to link it to
+ * a free SLCAN channel...
+ *
+ * Called in process context serialized from other ldisc calls.
+ */
+
+static int slcan_open(struct tty_struct *tty)
+{
+ struct slcan *sl;
+ int err;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (tty->ops->write == NULL)
+ return -EOPNOTSUPP;
+
+ /* RTnetlink lock is misused here to serialize concurrent
+ opens of slcan channels. There are better ways, but it is
+ the simplest one.
+ */
+ rtnl_lock();
+
+ /* Collect hanged up channels. */
+ slc_sync();
+
+ sl = tty->disc_data;
+
+ err = -EEXIST;
+ /* First make sure we're not already connected. */
+ if (sl && sl->magic == SLCAN_MAGIC)
+ goto err_exit;
+
+ /* OK. Find a free SLCAN channel to use. */
+ err = -ENFILE;
+ sl = slc_alloc(tty_devnum(tty));
+ if (sl == NULL)
+ goto err_exit;
+
+ sl->tty = tty;
+ tty->disc_data = sl;
+
+ if (!test_bit(SLF_INUSE, &sl->flags)) {
+ /* Perform the low-level SLCAN initialization. */
+ sl->rcount = 0;
+ sl->xleft = 0;
+
+ set_bit(SLF_INUSE, &sl->flags);
+
+ err = register_netdevice(sl->dev);
+ if (err)
+ goto err_free_chan;
+ }
+
+ /* Done. We have linked the TTY line to a channel. */
+ rtnl_unlock();
+ tty->receive_room = 65536; /* We don't flow control */
+
+ /* TTY layer expects 0 on success */
+ return 0;
+
+err_free_chan:
+ sl->tty = NULL;
+ tty->disc_data = NULL;
+ clear_bit(SLF_INUSE, &sl->flags);
+
+err_exit:
+ rtnl_unlock();
+
+ /* Count references from TTY module */
+ return err;
+}
+
+/*
+ * Close down a SLCAN channel.
+ * This means flushing out any pending queues, and then returning. This
+ * call is serialized against other ldisc functions.
+ *
+ * We also use this method for a hangup event.
+ */
+
+static void slcan_close(struct tty_struct *tty)
+{
+ struct slcan *sl = (struct slcan *) tty->disc_data;
+
+ /* First make sure we're connected. */
+ if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
+ return;
+
+ spin_lock_bh(&sl->lock);
+ tty->disc_data = NULL;
+ sl->tty = NULL;
+ spin_unlock_bh(&sl->lock);
+
+ flush_work(&sl->tx_work);
+
+ /* Flush network side */
+ unregister_netdev(sl->dev);
+ /* This will complete via sl_free_netdev */
+}
+
+static int slcan_hangup(struct tty_struct *tty)
+{
+ slcan_close(tty);
+ return 0;
+}
+
+/* Perform I/O control on an active SLCAN channel. */
+static int slcan_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct slcan *sl = (struct slcan *) tty->disc_data;
+ unsigned int tmp;
+
+ /* First make sure we're connected. */
+ if (!sl || sl->magic != SLCAN_MAGIC)
+ return -EINVAL;
+
+ switch (cmd) {
+ case SIOCGIFNAME:
+ tmp = strlen(sl->dev->name) + 1;
+ if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
+ return -EFAULT;
+ return 0;
+
+ case SIOCSIFHWADDR:
+ return -EINVAL;
+
+ default:
+ return tty_mode_ioctl(tty, file, cmd, arg);
+ }
+}
+
+static struct tty_ldisc_ops slc_ldisc = {
+ .owner = THIS_MODULE,
+ .magic = TTY_LDISC_MAGIC,
+ .name = "slcan",
+ .open = slcan_open,
+ .close = slcan_close,
+ .hangup = slcan_hangup,
+ .ioctl = slcan_ioctl,
+ .receive_buf = slcan_receive_buf,
+ .write_wakeup = slcan_write_wakeup,
+};
+
+static int __init slcan_init(void)
+{
+ int status;
+
+ if (maxdev < 4)
+ maxdev = 4; /* Sanity */
+
+ printk(banner);
+ printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev);
+
+ slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
+ if (!slcan_devs)
+ return -ENOMEM;
+
+ /* Fill in our line protocol discipline, and register it */
+ status = tty_register_ldisc(N_SLCAN, &slc_ldisc);
+ if (status) {
+ printk(KERN_ERR "slcan: can't register line discipline\n");
+ kfree(slcan_devs);
+ }
+ return status;
+}
+
+static void __exit slcan_exit(void)
+{
+ int i;
+ struct net_device *dev;
+ struct slcan *sl;
+ unsigned long timeout = jiffies + HZ;
+ int busy = 0;
+
+ if (slcan_devs == NULL)
+ return;
+
+ /* First of all: check for active disciplines and hangup them.
+ */
+ do {
+ if (busy)
+ msleep_interruptible(100);
+
+ busy = 0;
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (!dev)
+ continue;
+ sl = netdev_priv(dev);
+ spin_lock_bh(&sl->lock);
+ if (sl->tty) {
+ busy++;
+ tty_hangup(sl->tty);
+ }
+ spin_unlock_bh(&sl->lock);
+ }
+ } while (busy && time_before(jiffies, timeout));
+
+ /* FIXME: hangup is async so we should wait when doing this second
+ phase */
+
+ for (i = 0; i < maxdev; i++) {
+ dev = slcan_devs[i];
+ if (!dev)
+ continue;
+ slcan_devs[i] = NULL;
+
+ sl = netdev_priv(dev);
+ if (sl->tty) {
+ printk(KERN_ERR "%s: tty discipline still running\n",
+ dev->name);
+ /* Intentionally leak the control block. */
+ dev->destructor = NULL;
+ }
+
+ unregister_netdev(dev);
+ }
+
+ kfree(slcan_devs);
+ slcan_devs = NULL;
+
+ i = tty_unregister_ldisc(N_SLCAN);
+ if (i)
+ printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i);
+}
+
+module_init(slcan_init);
+module_exit(slcan_exit);
diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig
new file mode 100644
index 00000000000..96b6fe158b5
--- /dev/null
+++ b/drivers/net/can/softing/Kconfig
@@ -0,0 +1,30 @@
+config CAN_SOFTING
+ tristate "Softing Gmbh CAN generic support"
+ depends on HAS_IOMEM
+ ---help---
+ Support for CAN cards from Softing Gmbh & some cards
+ from Vector Gmbh.
+ Softing Gmbh CAN cards come with 1 or 2 physical busses.
+ Those cards typically use Dual Port RAM to communicate
+ with the host CPU. The interface is then identical for PCI
+ and PCMCIA cards. This driver operates on a platform device,
+ which has been created by softing_cs or softing_pci driver.
+ Warning:
+ The API of the card does not allow fine control per bus, but
+ controls the 2 busses on the card together.
+ As such, some actions (start/stop/busoff recovery) on 1 bus
+ must bring down the other bus too temporarily.
+
+config CAN_SOFTING_CS
+ tristate "Softing Gmbh CAN pcmcia cards"
+ depends on PCMCIA
+ depends on CAN_SOFTING
+ ---help---
+ Support for PCMCIA cards from Softing Gmbh & some cards
+ from Vector Gmbh.
+ You need firmware for these, which you can get at
+ http://developer.berlios.de/projects/socketcan/
+ This version of the driver is written against
+ firmware version 4.6 (softing-fw-4.6-binaries.tar.gz)
+ In order to use the card as CAN device, you need the Softing generic
+ support too.
diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile
new file mode 100644
index 00000000000..c5e5016c742
--- /dev/null
+++ b/drivers/net/can/softing/Makefile
@@ -0,0 +1,6 @@
+
+softing-y := softing_main.o softing_fw.o
+obj-$(CONFIG_CAN_SOFTING) += softing.o
+obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h
new file mode 100644
index 00000000000..35f062282db
--- /dev/null
+++ b/drivers/net/can/softing/softing.h
@@ -0,0 +1,167 @@
+/*
+ * softing common interfaces
+ *
+ * by Kurt Van Dijck, 2008-2010
+ */
+
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+#include <linux/ktime.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+
+#include "softing_platform.h"
+
+struct softing;
+
+struct softing_priv {
+ struct can_priv can; /* must be the first member! */
+ struct net_device *netdev;
+ struct softing *card;
+ struct {
+ int pending;
+ /* variables which hold the circular buffer */
+ int echo_put;
+ int echo_get;
+ } tx;
+ struct can_bittiming_const btr_const;
+ int index;
+ uint8_t output;
+ uint16_t chip;
+};
+#define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev))
+
+struct softing {
+ const struct softing_platform_data *pdat;
+ struct platform_device *pdev;
+ struct net_device *net[2];
+ spinlock_t spin; /* protect this structure & DPRAM access */
+ ktime_t ts_ref;
+ ktime_t ts_overflow; /* timestamp overflow value, in ktime */
+
+ struct {
+ /* indication of firmware status */
+ int up;
+ /* protection of the 'up' variable */
+ struct mutex lock;
+ } fw;
+ struct {
+ int nr;
+ int requested;
+ int svc_count;
+ unsigned int dpram_position;
+ } irq;
+ struct {
+ int pending;
+ int last_bus;
+ /*
+ * keep the bus that last tx'd a message,
+ * in order to let every netdev queue resume
+ */
+ } tx;
+ __iomem uint8_t *dpram;
+ unsigned long dpram_phys;
+ unsigned long dpram_size;
+ struct {
+ uint16_t fw_version, hw_version, license, serial;
+ uint16_t chip[2];
+ unsigned int freq; /* remote cpu's operating frequency */
+ } id;
+};
+
+int softing_default_output(struct net_device *netdev);
+
+ktime_t softing_raw2ktime(struct softing *card, u32 raw);
+
+int softing_chip_poweron(struct softing *card);
+
+int softing_bootloader_command(struct softing *card, int16_t cmd,
+ const char *msg);
+
+/* Load firmware after reset */
+int softing_load_fw(const char *file, struct softing *card,
+ __iomem uint8_t *virt, unsigned int size, int offset);
+
+/* Load final application firmware after bootloader */
+int softing_load_app_fw(const char *file, struct softing *card);
+
+/*
+ * enable or disable irq
+ * only called with fw.lock locked
+ */
+int softing_enable_irq(struct softing *card, int enable);
+
+/* start/stop 1 bus on card */
+int softing_startstop(struct net_device *netdev, int up);
+
+/* netif_rx() */
+int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg,
+ ktime_t ktime);
+
+/* SOFTING DPRAM mappings */
+#define DPRAM_RX 0x0000
+ #define DPRAM_RX_SIZE 32
+ #define DPRAM_RX_CNT 16
+#define DPRAM_RX_RD 0x0201 /* uint8_t */
+#define DPRAM_RX_WR 0x0205 /* uint8_t */
+#define DPRAM_RX_LOST 0x0207 /* uint8_t */
+
+#define DPRAM_FCT_PARAM 0x0300 /* int16_t [20] */
+#define DPRAM_FCT_RESULT 0x0328 /* int16_t */
+#define DPRAM_FCT_HOST 0x032b /* uint16_t */
+
+#define DPRAM_INFO_BUSSTATE 0x0331 /* uint16_t */
+#define DPRAM_INFO_BUSSTATE2 0x0335 /* uint16_t */
+#define DPRAM_INFO_ERRSTATE 0x0339 /* uint16_t */
+#define DPRAM_INFO_ERRSTATE2 0x033d /* uint16_t */
+#define DPRAM_RESET 0x0341 /* uint16_t */
+#define DPRAM_CLR_RECV_FIFO 0x0345 /* uint16_t */
+#define DPRAM_RESET_TIME 0x034d /* uint16_t */
+#define DPRAM_TIME 0x0350 /* uint64_t */
+#define DPRAM_WR_START 0x0358 /* uint8_t */
+#define DPRAM_WR_END 0x0359 /* uint8_t */
+#define DPRAM_RESET_RX_FIFO 0x0361 /* uint16_t */
+#define DPRAM_RESET_TX_FIFO 0x0364 /* uint8_t */
+#define DPRAM_READ_FIFO_LEVEL 0x0365 /* uint8_t */
+#define DPRAM_RX_FIFO_LEVEL 0x0366 /* uint16_t */
+#define DPRAM_TX_FIFO_LEVEL 0x0366 /* uint16_t */
+
+#define DPRAM_TX 0x0400 /* uint16_t */
+ #define DPRAM_TX_SIZE 16
+ #define DPRAM_TX_CNT 32
+#define DPRAM_TX_RD 0x0601 /* uint8_t */
+#define DPRAM_TX_WR 0x0605 /* uint8_t */
+
+#define DPRAM_COMMAND 0x07e0 /* uint16_t */
+#define DPRAM_RECEIPT 0x07f0 /* uint16_t */
+#define DPRAM_IRQ_TOHOST 0x07fe /* uint8_t */
+#define DPRAM_IRQ_TOCARD 0x07ff /* uint8_t */
+
+#define DPRAM_V2_RESET 0x0e00 /* uint8_t */
+#define DPRAM_V2_IRQ_TOHOST 0x0e02 /* uint8_t */
+
+#define TXMAX (DPRAM_TX_CNT - 1)
+
+/* DPRAM return codes */
+#define RES_NONE 0
+#define RES_OK 1
+#define RES_NOK 2
+#define RES_UNKNOWN 3
+/* DPRAM flags */
+#define CMD_TX 0x01
+#define CMD_ACK 0x02
+#define CMD_XTD 0x04
+#define CMD_RTR 0x08
+#define CMD_ERR 0x10
+#define CMD_BUS2 0x80
+
+/* returned fifo entry bus state masks */
+#define SF_MASK_BUSOFF 0x80
+#define SF_MASK_EPASSIVE 0x60
+
+/* bus states */
+#define STATE_BUSOFF 2
+#define STATE_EPASSIVE 1
+#define STATE_EACTIVE 0
diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c
new file mode 100644
index 00000000000..cdc0c7433a4
--- /dev/null
+++ b/drivers/net/can/softing/softing_cs.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2008-2010
+ *
+ * - Kurt Van Dijck, EIA Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "softing_platform.h"
+
+static int softingcs_index;
+static DEFINE_SPINLOCK(softingcs_index_lock);
+
+static int softingcs_reset(struct platform_device *pdev, int v);
+static int softingcs_enable_irq(struct platform_device *pdev, int v);
+
+/*
+ * platform_data descriptions
+ */
+#define MHZ (1000*1000)
+static const struct softing_platform_data softingcs_platform_data[] = {
+{
+ .name = "CANcard",
+ .manf = 0x0168, .prod = 0x001,
+ .generation = 1,
+ .nbus = 2,
+ .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4,
+ .dpram_size = 0x0800,
+ .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = softingcs_enable_irq,
+}, {
+ .name = "CANcard-NEC",
+ .manf = 0x0168, .prod = 0x002,
+ .generation = 1,
+ .nbus = 2,
+ .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4,
+ .dpram_size = 0x0800,
+ .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = softingcs_enable_irq,
+}, {
+ .name = "CANcard-SJA",
+ .manf = 0x0168, .prod = 0x004,
+ .generation = 1,
+ .nbus = 2,
+ .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4,
+ .dpram_size = 0x0800,
+ .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = softingcs_enable_irq,
+}, {
+ .name = "CANcard-2",
+ .manf = 0x0168, .prod = 0x005,
+ .generation = 2,
+ .nbus = 2,
+ .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
+ .dpram_size = 0x1000,
+ .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = NULL,
+}, {
+ .name = "Vector-CANcard",
+ .manf = 0x0168, .prod = 0x081,
+ .generation = 1,
+ .nbus = 2,
+ .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4,
+ .dpram_size = 0x0800,
+ .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = softingcs_enable_irq,
+}, {
+ .name = "Vector-CANcard-SJA",
+ .manf = 0x0168, .prod = 0x084,
+ .generation = 1,
+ .nbus = 2,
+ .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4,
+ .dpram_size = 0x0800,
+ .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = softingcs_enable_irq,
+}, {
+ .name = "Vector-CANcard-2",
+ .manf = 0x0168, .prod = 0x085,
+ .generation = 2,
+ .nbus = 2,
+ .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
+ .dpram_size = 0x1000,
+ .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = NULL,
+}, {
+ .name = "EDICcard-NEC",
+ .manf = 0x0168, .prod = 0x102,
+ .generation = 1,
+ .nbus = 2,
+ .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4,
+ .dpram_size = 0x0800,
+ .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = softingcs_enable_irq,
+}, {
+ .name = "EDICcard-2",
+ .manf = 0x0168, .prod = 0x105,
+ .generation = 2,
+ .nbus = 2,
+ .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
+ .dpram_size = 0x1000,
+ .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
+ .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
+ .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
+ .reset = softingcs_reset,
+ .enable_irq = NULL,
+}, {
+ 0, 0,
+},
+};
+
+MODULE_FIRMWARE(fw_dir "bcard.bin");
+MODULE_FIRMWARE(fw_dir "ldcard.bin");
+MODULE_FIRMWARE(fw_dir "cancard.bin");
+MODULE_FIRMWARE(fw_dir "cansja.bin");
+
+MODULE_FIRMWARE(fw_dir "bcard2.bin");
+MODULE_FIRMWARE(fw_dir "ldcard2.bin");
+MODULE_FIRMWARE(fw_dir "cancrd2.bin");
+
+static const struct softing_platform_data
+*softingcs_find_platform_data(unsigned int manf, unsigned int prod)
+{
+ const struct softing_platform_data *lp;
+
+ for (lp = softingcs_platform_data; lp->manf; ++lp) {
+ if ((lp->manf == manf) && (lp->prod == prod))
+ return lp;
+ }
+ return NULL;
+}
+
+/*
+ * platformdata callbacks
+ */
+static int softingcs_reset(struct platform_device *pdev, int v)
+{
+ struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);
+
+ dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20);
+ return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20);
+}
+
+static int softingcs_enable_irq(struct platform_device *pdev, int v)
+{
+ struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);
+
+ dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0);
+ return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0);
+}
+
+/*
+ * pcmcia check
+ */
+static int softingcs_probe_config(struct pcmcia_device *pcmcia, void *priv_data)
+{
+ struct softing_platform_data *pdat = priv_data;
+ struct resource *pres;
+ int memspeed = 0;
+
+ WARN_ON(!pdat);
+ pres = pcmcia->resource[PCMCIA_IOMEM_0];
+ if (resource_size(pres) < 0x1000)
+ return -ERANGE;
+
+ pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
+ if (pdat->generation < 2) {
+ pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8;
+ memspeed = 3;
+ } else {
+ pres->flags |= WIN_DATA_WIDTH_16;
+ }
+ return pcmcia_request_window(pcmcia, pres, memspeed);
+}
+
+static void softingcs_remove(struct pcmcia_device *pcmcia)
+{
+ struct platform_device *pdev = pcmcia->priv;
+
+ /* free bits */
+ platform_device_unregister(pdev);
+ /* release pcmcia stuff */
+ pcmcia_disable_device(pcmcia);
+}
+
+/*
+ * platform_device wrapper
+ * pdev->resource has 2 entries: io & irq
+ */
+static void softingcs_pdev_release(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ kfree(pdev);
+}
+
+static int softingcs_probe(struct pcmcia_device *pcmcia)
+{
+ int ret;
+ struct platform_device *pdev;
+ const struct softing_platform_data *pdat;
+ struct resource *pres;
+ struct dev {
+ struct platform_device pdev;
+ struct resource res[2];
+ } *dev;
+
+ /* find matching platform_data */
+ pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id);
+ if (!pdat)
+ return -ENOTTY;
+
+ /* setup pcmcia device */
+ pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM |
+ CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
+ ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat);
+ if (ret)
+ goto pcmcia_failed;
+
+ ret = pcmcia_enable_device(pcmcia);
+ if (ret < 0)
+ goto pcmcia_failed;
+
+ pres = pcmcia->resource[PCMCIA_IOMEM_0];
+ if (!pres) {
+ ret = -EBADF;
+ goto pcmcia_bad;
+ }
+
+ /* create softing platform device */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto mem_failed;
+ }
+ dev->pdev.resource = dev->res;
+ dev->pdev.num_resources = ARRAY_SIZE(dev->res);
+ dev->pdev.dev.release = softingcs_pdev_release;
+
+ pdev = &dev->pdev;
+ pdev->dev.platform_data = (void *)pdat;
+ pdev->dev.parent = &pcmcia->dev;
+ pcmcia->priv = pdev;
+
+ /* platform device resources */
+ pdev->resource[0].flags = IORESOURCE_MEM;
+ pdev->resource[0].start = pres->start;
+ pdev->resource[0].end = pres->end;
+
+ pdev->resource[1].flags = IORESOURCE_IRQ;
+ pdev->resource[1].start = pcmcia->irq;
+ pdev->resource[1].end = pdev->resource[1].start;
+
+ /* platform device setup */
+ spin_lock(&softingcs_index_lock);
+ pdev->id = softingcs_index++;
+ spin_unlock(&softingcs_index_lock);
+ pdev->name = "softing";
+ dev_set_name(&pdev->dev, "softingcs.%i", pdev->id);
+ ret = platform_device_register(pdev);
+ if (ret < 0)
+ goto platform_failed;
+
+ dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev));
+ return 0;
+
+platform_failed:
+ kfree(dev);
+mem_failed:
+pcmcia_bad:
+pcmcia_failed:
+ pcmcia_disable_device(pcmcia);
+ pcmcia->priv = NULL;
+ return ret ?: -ENODEV;
+}
+
+static const struct pcmcia_device_id softingcs_ids[] = {
+ /* softing */
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001),
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002),
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004),
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005),
+ /* vector, manufacturer? */
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081),
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084),
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085),
+ /* EDIC */
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102),
+ PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105),
+ PCMCIA_DEVICE_NULL,
+};
+
+MODULE_DEVICE_TABLE(pcmcia, softingcs_ids);
+
+static struct pcmcia_driver softingcs_driver = {
+ .owner = THIS_MODULE,
+ .name = "softingcs",
+ .id_table = softingcs_ids,
+ .probe = softingcs_probe,
+ .remove = softingcs_remove,
+};
+
+module_pcmcia_driver(softingcs_driver);
+
+MODULE_DESCRIPTION("softing CANcard driver"
+ ", links PCMCIA card to softing driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c
new file mode 100644
index 00000000000..52fe50725d7
--- /dev/null
+++ b/drivers/net/can/softing/softing_fw.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright (C) 2008-2010
+ *
+ * - Kurt Van Dijck, EIA Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/firmware.h>
+#include <linux/sched.h>
+#include <asm/div64.h>
+#include <asm/io.h>
+
+#include "softing.h"
+
+/*
+ * low level DPRAM command.
+ * Make sure that card->dpram[DPRAM_FCT_HOST] is preset
+ */
+static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector,
+ const char *msg)
+{
+ int ret;
+ unsigned long stamp;
+
+ iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]);
+ iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]);
+ iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]);
+ /* be sure to flush this to the card */
+ wmb();
+ stamp = jiffies + 1 * HZ;
+ /* wait for card */
+ do {
+ /* DPRAM_FCT_HOST is _not_ aligned */
+ ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) +
+ (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8);
+ /* don't have any cached variables */
+ rmb();
+ if (ret == RES_OK)
+ /* read return-value now */
+ return ioread16(&card->dpram[DPRAM_FCT_RESULT]);
+
+ if ((ret != vector) || time_after(jiffies, stamp))
+ break;
+ /* process context => relax */
+ usleep_range(500, 10000);
+ } while (1);
+
+ ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED;
+ dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret);
+ return ret;
+}
+
+static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg)
+{
+ int ret;
+
+ ret = _softing_fct_cmd(card, cmd, 0, msg);
+ if (ret > 0) {
+ dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret);
+ ret = -EIO;
+ }
+ return ret;
+}
+
+int softing_bootloader_command(struct softing *card, int16_t cmd,
+ const char *msg)
+{
+ int ret;
+ unsigned long stamp;
+
+ iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]);
+ iowrite16(cmd, &card->dpram[DPRAM_COMMAND]);
+ /* be sure to flush this to the card */
+ wmb();
+ stamp = jiffies + 3 * HZ;
+ /* wait for card */
+ do {
+ ret = ioread16(&card->dpram[DPRAM_RECEIPT]);
+ /* don't have any cached variables */
+ rmb();
+ if (ret == RES_OK)
+ return 0;
+ if (time_after(jiffies, stamp))
+ break;
+ /* process context => relax */
+ usleep_range(500, 10000);
+ } while (!signal_pending(current));
+
+ ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED;
+ dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret);
+ return ret;
+}
+
+static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr,
+ uint16_t *plen, const uint8_t **pdat)
+{
+ uint16_t checksum[2];
+ const uint8_t *mem;
+ const uint8_t *end;
+
+ /*
+ * firmware records are a binary, unaligned stream composed of:
+ * uint16_t type;
+ * uint32_t addr;
+ * uint16_t len;
+ * uint8_t dat[len];
+ * uint16_t checksum;
+ * all values in little endian.
+ * We could define a struct for this, with __attribute__((packed)),
+ * but would that solve the alignment in _all_ cases (cfr. the
+ * struct itself may be an odd address)?
+ *
+ * I chose to use leXX_to_cpup() since this solves both
+ * endianness & alignment.
+ */
+ mem = *pmem;
+ *ptype = le16_to_cpup((void *)&mem[0]);
+ *paddr = le32_to_cpup((void *)&mem[2]);
+ *plen = le16_to_cpup((void *)&mem[6]);
+ *pdat = &mem[8];
+ /* verify checksum */
+ end = &mem[8 + *plen];
+ checksum[0] = le16_to_cpup((void *)end);
+ for (checksum[1] = 0; mem < end; ++mem)
+ checksum[1] += *mem;
+ if (checksum[0] != checksum[1])
+ return -EINVAL;
+ /* increment */
+ *pmem += 10 + *plen;
+ return 0;
+}
+
+int softing_load_fw(const char *file, struct softing *card,
+ __iomem uint8_t *dpram, unsigned int size, int offset)
+{
+ const struct firmware *fw;
+ int ret;
+ const uint8_t *mem, *end, *dat;
+ uint16_t type, len;
+ uint32_t addr;
+ uint8_t *buf = NULL, *new_buf;
+ int buflen = 0;
+ int8_t type_end = 0;
+
+ ret = request_firmware(&fw, file, &card->pdev->dev);
+ if (ret < 0)
+ return ret;
+ dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes"
+ ", offset %c0x%04x\n",
+ card->pdat->name, file, (unsigned int)fw->size,
+ (offset >= 0) ? '+' : '-', (unsigned int)abs(offset));
+ /* parse the firmware */
+ mem = fw->data;
+ end = &mem[fw->size];
+ /* look for header record */
+ ret = fw_parse(&mem, &type, &addr, &len, &dat);
+ if (ret < 0)
+ goto failed;
+ if (type != 0xffff)
+ goto failed;
+ if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) {
+ ret = -EINVAL;
+ goto failed;
+ }
+ /* ok, we had a header */
+ while (mem < end) {
+ ret = fw_parse(&mem, &type, &addr, &len, &dat);
+ if (ret < 0)
+ goto failed;
+ if (type == 3) {
+ /* start address, not used here */
+ continue;
+ } else if (type == 1) {
+ /* eof */
+ type_end = 1;
+ break;
+ } else if (type != 0) {
+ ret = -EINVAL;
+ goto failed;
+ }
+
+ if ((addr + len + offset) > size)
+ goto failed;
+ memcpy_toio(&dpram[addr + offset], dat, len);
+ /* be sure to flush caches from IO space */
+ mb();
+ if (len > buflen) {
+ /* align buflen */
+ buflen = (len + (1024-1)) & ~(1024-1);
+ new_buf = krealloc(buf, buflen, GFP_KERNEL);
+ if (!new_buf) {
+ ret = -ENOMEM;
+ goto failed;
+ }
+ buf = new_buf;
+ }
+ /* verify record data */
+ memcpy_fromio(buf, &dpram[addr + offset], len);
+ if (memcmp(buf, dat, len)) {
+ /* is not ok */
+ dev_alert(&card->pdev->dev, "DPRAM readback failed\n");
+ ret = -EIO;
+ goto failed;
+ }
+ }
+ if (!type_end)
+ /* no end record seen */
+ goto failed;
+ ret = 0;
+failed:
+ kfree(buf);
+ release_firmware(fw);
+ if (ret < 0)
+ dev_info(&card->pdev->dev, "firmware %s failed\n", file);
+ return ret;
+}
+
+int softing_load_app_fw(const char *file, struct softing *card)
+{
+ const struct firmware *fw;
+ const uint8_t *mem, *end, *dat;
+ int ret, j;
+ uint16_t type, len;
+ uint32_t addr, start_addr = 0;
+ unsigned int sum, rx_sum;
+ int8_t type_end = 0, type_entrypoint = 0;
+
+ ret = request_firmware(&fw, file, &card->pdev->dev);
+ if (ret) {
+ dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n",
+ file, ret);
+ return ret;
+ }
+ dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n",
+ file, (unsigned long)fw->size);
+ /* parse the firmware */
+ mem = fw->data;
+ end = &mem[fw->size];
+ /* look for header record */
+ ret = fw_parse(&mem, &type, &addr, &len, &dat);
+ if (ret)
+ goto failed;
+ ret = -EINVAL;
+ if (type != 0xffff) {
+ dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n",
+ type);
+ goto failed;
+ }
+ if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) {
+ dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n",
+ len, dat);
+ goto failed;
+ }
+ /* ok, we had a header */
+ while (mem < end) {
+ ret = fw_parse(&mem, &type, &addr, &len, &dat);
+ if (ret)
+ goto failed;
+
+ if (type == 3) {
+ /* start address */
+ start_addr = addr;
+ type_entrypoint = 1;
+ continue;
+ } else if (type == 1) {
+ /* eof */
+ type_end = 1;
+ break;
+ } else if (type != 0) {
+ dev_alert(&card->pdev->dev,
+ "unknown record type 0x%04x\n", type);
+ ret = -EINVAL;
+ goto failed;
+ }
+
+ /* regualar data */
+ for (sum = 0, j = 0; j < len; ++j)
+ sum += dat[j];
+ /* work in 16bit (target) */
+ sum &= 0xffff;
+
+ memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len);
+ iowrite32(card->pdat->app.offs + card->pdat->app.addr,
+ &card->dpram[DPRAM_COMMAND + 2]);
+ iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]);
+ iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]);
+ iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]);
+ ret = softing_bootloader_command(card, 1, "loading app.");
+ if (ret < 0)
+ goto failed;
+ /* verify checksum */
+ rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]);
+ if (rx_sum != sum) {
+ dev_alert(&card->pdev->dev, "SRAM seems to be damaged"
+ ", wanted 0x%04x, got 0x%04x\n", sum, rx_sum);
+ ret = -EIO;
+ goto failed;
+ }
+ }
+ if (!type_end || !type_entrypoint)
+ goto failed;
+ /* start application in card */
+ iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]);
+ iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]);
+ ret = softing_bootloader_command(card, 3, "start app.");
+ if (ret < 0)
+ goto failed;
+ ret = 0;
+failed:
+ release_firmware(fw);
+ if (ret < 0)
+ dev_info(&card->pdev->dev, "firmware %s failed\n", file);
+ return ret;
+}
+
+static int softing_reset_chip(struct softing *card)
+{
+ int ret;
+
+ do {
+ /* reset chip */
+ iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]);
+ iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]);
+ iowrite8(1, &card->dpram[DPRAM_RESET]);
+ iowrite8(0, &card->dpram[DPRAM_RESET+1]);
+
+ ret = softing_fct_cmd(card, 0, "reset_can");
+ if (!ret)
+ break;
+ if (signal_pending(current))
+ /* don't wait any longer */
+ break;
+ } while (1);
+ card->tx.pending = 0;
+ return ret;
+}
+
+int softing_chip_poweron(struct softing *card)
+{
+ int ret;
+ /* sync */
+ ret = _softing_fct_cmd(card, 99, 0x55, "sync-a");
+ if (ret < 0)
+ goto failed;
+
+ ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b");
+ if (ret < 0)
+ goto failed;
+
+ ret = softing_reset_chip(card);
+ if (ret < 0)
+ goto failed;
+ /* get_serial */
+ ret = softing_fct_cmd(card, 43, "get_serial_number");
+ if (ret < 0)
+ goto failed;
+ card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]);
+ /* get_version */
+ ret = softing_fct_cmd(card, 12, "get_version");
+ if (ret < 0)
+ goto failed;
+ card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]);
+ card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]);
+ card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]);
+ card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]);
+ card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]);
+ return 0;
+failed:
+ return ret;
+}
+
+static void softing_initialize_timestamp(struct softing *card)
+{
+ uint64_t ovf;
+
+ card->ts_ref = ktime_get();
+
+ /* 16MHz is the reference */
+ ovf = 0x100000000ULL * 16;
+ do_div(ovf, card->pdat->freq ?: 16);
+
+ card->ts_overflow = ktime_add_us(ktime_set(0, 0), ovf);
+}
+
+ktime_t softing_raw2ktime(struct softing *card, u32 raw)
+{
+ uint64_t rawl;
+ ktime_t now, real_offset;
+ ktime_t target;
+ ktime_t tmp;
+
+ now = ktime_get();
+ real_offset = ktime_sub(ktime_get_real(), now);
+
+ /* find nsec from card */
+ rawl = raw * 16;
+ do_div(rawl, card->pdat->freq ?: 16);
+ target = ktime_add_us(card->ts_ref, rawl);
+ /* test for overflows */
+ tmp = ktime_add(target, card->ts_overflow);
+ while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) {
+ card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow);
+ target = tmp;
+ tmp = ktime_add(target, card->ts_overflow);
+ }
+ return ktime_add(target, real_offset);
+}
+
+static inline int softing_error_reporting(struct net_device *netdev)
+{
+ struct softing_priv *priv = netdev_priv(netdev);
+
+ return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+ ? 1 : 0;
+}
+
+int softing_startstop(struct net_device *dev, int up)
+{
+ int ret;
+ struct softing *card;
+ struct softing_priv *priv;
+ struct net_device *netdev;
+ int bus_bitmask_start;
+ int j, error_reporting;
+ struct can_frame msg;
+ const struct can_bittiming *bt;
+
+ priv = netdev_priv(dev);
+ card = priv->card;
+
+ if (!card->fw.up)
+ return -EIO;
+
+ ret = mutex_lock_interruptible(&card->fw.lock);
+ if (ret)
+ return ret;
+
+ bus_bitmask_start = 0;
+ if (dev && up)
+ /* prepare to start this bus as well */
+ bus_bitmask_start |= (1 << priv->index);
+ /* bring netdevs down */
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ netdev = card->net[j];
+ if (!netdev)
+ continue;
+ priv = netdev_priv(netdev);
+
+ if (dev != netdev)
+ netif_stop_queue(netdev);
+
+ if (netif_running(netdev)) {
+ if (dev != netdev)
+ bus_bitmask_start |= (1 << j);
+ priv->tx.pending = 0;
+ priv->tx.echo_put = 0;
+ priv->tx.echo_get = 0;
+ /*
+ * this bus' may just have called open_candev()
+ * which is rather stupid to call close_candev()
+ * already
+ * but we may come here from busoff recovery too
+ * in which case the echo_skb _needs_ flushing too.
+ * just be sure to call open_candev() again
+ */
+ close_candev(netdev);
+ }
+ priv->can.state = CAN_STATE_STOPPED;
+ }
+ card->tx.pending = 0;
+
+ softing_enable_irq(card, 0);
+ ret = softing_reset_chip(card);
+ if (ret)
+ goto failed;
+ if (!bus_bitmask_start)
+ /* no busses to be brought up */
+ goto card_done;
+
+ if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2)
+ && (softing_error_reporting(card->net[0])
+ != softing_error_reporting(card->net[1]))) {
+ dev_alert(&card->pdev->dev,
+ "err_reporting flag differs for busses\n");
+ goto invalid;
+ }
+ error_reporting = 0;
+ if (bus_bitmask_start & 1) {
+ netdev = card->net[0];
+ priv = netdev_priv(netdev);
+ error_reporting += softing_error_reporting(netdev);
+ /* init chip 1 */
+ bt = &priv->can.bittiming;
+ iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]);
+ iowrite16(bt->phase_seg1 + bt->prop_seg,
+ &card->dpram[DPRAM_FCT_PARAM + 6]);
+ iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]);
+ iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0,
+ &card->dpram[DPRAM_FCT_PARAM + 10]);
+ ret = softing_fct_cmd(card, 1, "initialize_chip[0]");
+ if (ret < 0)
+ goto failed;
+ /* set mode */
+ iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]);
+ ret = softing_fct_cmd(card, 3, "set_mode[0]");
+ if (ret < 0)
+ goto failed;
+ /* set filter */
+ /* 11bit id & mask */
+ iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]);
+ /* 29bit id.lo & mask.lo & id.hi & mask.hi */
+ iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]);
+ iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]);
+ iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]);
+ iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]);
+ ret = softing_fct_cmd(card, 7, "set_filter[0]");
+ if (ret < 0)
+ goto failed;
+ /* set output control */
+ iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ ret = softing_fct_cmd(card, 5, "set_output[0]");
+ if (ret < 0)
+ goto failed;
+ }
+ if (bus_bitmask_start & 2) {
+ netdev = card->net[1];
+ priv = netdev_priv(netdev);
+ error_reporting += softing_error_reporting(netdev);
+ /* init chip2 */
+ bt = &priv->can.bittiming;
+ iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]);
+ iowrite16(bt->phase_seg1 + bt->prop_seg,
+ &card->dpram[DPRAM_FCT_PARAM + 6]);
+ iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]);
+ iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0,
+ &card->dpram[DPRAM_FCT_PARAM + 10]);
+ ret = softing_fct_cmd(card, 2, "initialize_chip[1]");
+ if (ret < 0)
+ goto failed;
+ /* set mode2 */
+ iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]);
+ ret = softing_fct_cmd(card, 4, "set_mode[1]");
+ if (ret < 0)
+ goto failed;
+ /* set filter2 */
+ /* 11bit id & mask */
+ iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]);
+ /* 29bit id.lo & mask.lo & id.hi & mask.hi */
+ iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]);
+ iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]);
+ iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]);
+ iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]);
+ ret = softing_fct_cmd(card, 8, "set_filter[1]");
+ if (ret < 0)
+ goto failed;
+ /* set output control2 */
+ iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ ret = softing_fct_cmd(card, 6, "set_output[1]");
+ if (ret < 0)
+ goto failed;
+ }
+ /* enable_error_frame */
+ /*
+ * Error reporting is switched off at the moment since
+ * the receiving of them is not yet 100% verified
+ * This should be enabled sooner or later
+ *
+ if (error_reporting) {
+ ret = softing_fct_cmd(card, 51, "enable_error_frame");
+ if (ret < 0)
+ goto failed;
+ }
+ */
+ /* initialize interface */
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]);
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]);
+ ret = softing_fct_cmd(card, 17, "initialize_interface");
+ if (ret < 0)
+ goto failed;
+ /* enable_fifo */
+ ret = softing_fct_cmd(card, 36, "enable_fifo");
+ if (ret < 0)
+ goto failed;
+ /* enable fifo tx ack */
+ ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]");
+ if (ret < 0)
+ goto failed;
+ /* enable fifo tx ack2 */
+ ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]");
+ if (ret < 0)
+ goto failed;
+ /* start_chip */
+ ret = softing_fct_cmd(card, 11, "start_chip");
+ if (ret < 0)
+ goto failed;
+ iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]);
+ iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]);
+ if (card->pdat->generation < 2) {
+ iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]);
+ /* flush the DPRAM caches */
+ wmb();
+ }
+
+ softing_initialize_timestamp(card);
+
+ /*
+ * do socketcan notifications/status changes
+ * from here, no errors should occur, or the failed: part
+ * must be reviewed
+ */
+ memset(&msg, 0, sizeof(msg));
+ msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
+ msg.can_dlc = CAN_ERR_DLC;
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ if (!(bus_bitmask_start & (1 << j)))
+ continue;
+ netdev = card->net[j];
+ if (!netdev)
+ continue;
+ priv = netdev_priv(netdev);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ open_candev(netdev);
+ if (dev != netdev) {
+ /* notify other busses on the restart */
+ softing_netdev_rx(netdev, &msg, ktime_set(0, 0));
+ ++priv->can.can_stats.restarts;
+ }
+ netif_wake_queue(netdev);
+ }
+
+ /* enable interrupts */
+ ret = softing_enable_irq(card, 1);
+ if (ret)
+ goto failed;
+card_done:
+ mutex_unlock(&card->fw.lock);
+ return 0;
+invalid:
+ ret = -EINVAL;
+failed:
+ softing_enable_irq(card, 0);
+ softing_reset_chip(card);
+ mutex_unlock(&card->fw.lock);
+ /* bring all other interfaces down */
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ netdev = card->net[j];
+ if (!netdev)
+ continue;
+ dev_close(netdev);
+ }
+ return ret;
+}
+
+int softing_default_output(struct net_device *netdev)
+{
+ struct softing_priv *priv = netdev_priv(netdev);
+ struct softing *card = priv->card;
+
+ switch (priv->chip) {
+ case 1000:
+ return (card->pdat->generation < 2) ? 0xfb : 0xfa;
+ case 5:
+ return 0x60;
+ default:
+ return 0x40;
+ }
+}
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
new file mode 100644
index 00000000000..bacd236ce30
--- /dev/null
+++ b/drivers/net/can/softing/softing_main.c
@@ -0,0 +1,870 @@
+/*
+ * Copyright (C) 2008-2010
+ *
+ * - Kurt Van Dijck, EIA Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+
+#include "softing.h"
+
+#define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1)
+
+/*
+ * test is a specific CAN netdev
+ * is online (ie. up 'n running, not sleeping, not busoff
+ */
+static inline int canif_is_active(struct net_device *netdev)
+{
+ struct can_priv *can = netdev_priv(netdev);
+
+ if (!netif_running(netdev))
+ return 0;
+ return (can->state <= CAN_STATE_ERROR_PASSIVE);
+}
+
+/* reset DPRAM */
+static inline void softing_set_reset_dpram(struct softing *card)
+{
+ if (card->pdat->generation >= 2) {
+ spin_lock_bh(&card->spin);
+ iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1,
+ &card->dpram[DPRAM_V2_RESET]);
+ spin_unlock_bh(&card->spin);
+ }
+}
+
+static inline void softing_clr_reset_dpram(struct softing *card)
+{
+ if (card->pdat->generation >= 2) {
+ spin_lock_bh(&card->spin);
+ iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1,
+ &card->dpram[DPRAM_V2_RESET]);
+ spin_unlock_bh(&card->spin);
+ }
+}
+
+/* trigger the tx queue-ing */
+static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct softing_priv *priv = netdev_priv(dev);
+ struct softing *card = priv->card;
+ int ret;
+ uint8_t *ptr;
+ uint8_t fifo_wr, fifo_rd;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ uint8_t buf[DPRAM_TX_SIZE];
+
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
+ spin_lock(&card->spin);
+
+ ret = NETDEV_TX_BUSY;
+ if (!card->fw.up ||
+ (card->tx.pending >= TXMAX) ||
+ (priv->tx.pending >= TX_ECHO_SKB_MAX))
+ goto xmit_done;
+ fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]);
+ fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]);
+ if (fifo_wr == fifo_rd)
+ /* fifo full */
+ goto xmit_done;
+ memset(buf, 0, sizeof(buf));
+ ptr = buf;
+ *ptr = CMD_TX;
+ if (cf->can_id & CAN_RTR_FLAG)
+ *ptr |= CMD_RTR;
+ if (cf->can_id & CAN_EFF_FLAG)
+ *ptr |= CMD_XTD;
+ if (priv->index)
+ *ptr |= CMD_BUS2;
+ ++ptr;
+ *ptr++ = cf->can_dlc;
+ *ptr++ = (cf->can_id >> 0);
+ *ptr++ = (cf->can_id >> 8);
+ if (cf->can_id & CAN_EFF_FLAG) {
+ *ptr++ = (cf->can_id >> 16);
+ *ptr++ = (cf->can_id >> 24);
+ } else {
+ /* increment 1, not 2 as you might think */
+ ptr += 1;
+ }
+ if (!(cf->can_id & CAN_RTR_FLAG))
+ memcpy(ptr, &cf->data[0], cf->can_dlc);
+ memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr],
+ buf, DPRAM_TX_SIZE);
+ if (++fifo_wr >= DPRAM_TX_CNT)
+ fifo_wr = 0;
+ iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]);
+ card->tx.last_bus = priv->index;
+ ++card->tx.pending;
+ ++priv->tx.pending;
+ can_put_echo_skb(skb, dev, priv->tx.echo_put);
+ ++priv->tx.echo_put;
+ if (priv->tx.echo_put >= TX_ECHO_SKB_MAX)
+ priv->tx.echo_put = 0;
+ /* can_put_echo_skb() saves the skb, safe to return TX_OK */
+ ret = NETDEV_TX_OK;
+xmit_done:
+ spin_unlock(&card->spin);
+ if (card->tx.pending >= TXMAX) {
+ int j;
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ if (card->net[j])
+ netif_stop_queue(card->net[j]);
+ }
+ }
+ if (ret != NETDEV_TX_OK)
+ netif_stop_queue(dev);
+
+ return ret;
+}
+
+/*
+ * shortcut for skb delivery
+ */
+int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg,
+ ktime_t ktime)
+{
+ struct sk_buff *skb;
+ struct can_frame *cf;
+
+ skb = alloc_can_skb(netdev, &cf);
+ if (!skb)
+ return -ENOMEM;
+ memcpy(cf, msg, sizeof(*msg));
+ skb->tstamp = ktime;
+ return netif_rx(skb);
+}
+
+/*
+ * softing_handle_1
+ * pop 1 entry from the DPRAM queue, and process
+ */
+static int softing_handle_1(struct softing *card)
+{
+ struct net_device *netdev;
+ struct softing_priv *priv;
+ ktime_t ktime;
+ struct can_frame msg;
+ int cnt = 0, lost_msg;
+ uint8_t fifo_rd, fifo_wr, cmd;
+ uint8_t *ptr;
+ uint32_t tmp_u32;
+ uint8_t buf[DPRAM_RX_SIZE];
+
+ memset(&msg, 0, sizeof(msg));
+ /* test for lost msgs */
+ lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]);
+ if (lost_msg) {
+ int j;
+ /* reset condition */
+ iowrite8(0, &card->dpram[DPRAM_RX_LOST]);
+ /* prepare msg */
+ msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL;
+ msg.can_dlc = CAN_ERR_DLC;
+ msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ /*
+ * service to all busses, we don't know which it was applicable
+ * but only service busses that are online
+ */
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ netdev = card->net[j];
+ if (!netdev)
+ continue;
+ if (!canif_is_active(netdev))
+ /* a dead bus has no overflows */
+ continue;
+ ++netdev->stats.rx_over_errors;
+ softing_netdev_rx(netdev, &msg, ktime_set(0, 0));
+ }
+ /* prepare for other use */
+ memset(&msg, 0, sizeof(msg));
+ ++cnt;
+ }
+
+ fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]);
+ fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]);
+
+ if (++fifo_rd >= DPRAM_RX_CNT)
+ fifo_rd = 0;
+ if (fifo_wr == fifo_rd)
+ return cnt;
+
+ memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd],
+ DPRAM_RX_SIZE);
+ mb();
+ /* trigger dual port RAM */
+ iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]);
+
+ ptr = buf;
+ cmd = *ptr++;
+ if (cmd == 0xff)
+ /* not quite useful, probably the card has got out */
+ return 0;
+ netdev = card->net[0];
+ if (cmd & CMD_BUS2)
+ netdev = card->net[1];
+ priv = netdev_priv(netdev);
+
+ if (cmd & CMD_ERR) {
+ uint8_t can_state, state;
+
+ state = *ptr++;
+
+ msg.can_id = CAN_ERR_FLAG;
+ msg.can_dlc = CAN_ERR_DLC;
+
+ if (state & SF_MASK_BUSOFF) {
+ can_state = CAN_STATE_BUS_OFF;
+ msg.can_id |= CAN_ERR_BUSOFF;
+ state = STATE_BUSOFF;
+ } else if (state & SF_MASK_EPASSIVE) {
+ can_state = CAN_STATE_ERROR_PASSIVE;
+ msg.can_id |= CAN_ERR_CRTL;
+ msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE;
+ state = STATE_EPASSIVE;
+ } else {
+ can_state = CAN_STATE_ERROR_ACTIVE;
+ msg.can_id |= CAN_ERR_CRTL;
+ state = STATE_EACTIVE;
+ }
+ /* update DPRAM */
+ iowrite8(state, &card->dpram[priv->index ?
+ DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]);
+ /* timestamp */
+ tmp_u32 = le32_to_cpup((void *)ptr);
+ ptr += 4;
+ ktime = softing_raw2ktime(card, tmp_u32);
+
+ ++netdev->stats.rx_errors;
+ /* update internal status */
+ if (can_state != priv->can.state) {
+ priv->can.state = can_state;
+ if (can_state == CAN_STATE_ERROR_PASSIVE)
+ ++priv->can.can_stats.error_passive;
+ else if (can_state == CAN_STATE_BUS_OFF) {
+ /* this calls can_close_cleanup() */
+ can_bus_off(netdev);
+ netif_stop_queue(netdev);
+ }
+ /* trigger socketcan */
+ softing_netdev_rx(netdev, &msg, ktime);
+ }
+
+ } else {
+ if (cmd & CMD_RTR)
+ msg.can_id |= CAN_RTR_FLAG;
+ msg.can_dlc = get_can_dlc(*ptr++);
+ if (cmd & CMD_XTD) {
+ msg.can_id |= CAN_EFF_FLAG;
+ msg.can_id |= le32_to_cpup((void *)ptr);
+ ptr += 4;
+ } else {
+ msg.can_id |= le16_to_cpup((void *)ptr);
+ ptr += 2;
+ }
+ /* timestamp */
+ tmp_u32 = le32_to_cpup((void *)ptr);
+ ptr += 4;
+ ktime = softing_raw2ktime(card, tmp_u32);
+ if (!(msg.can_id & CAN_RTR_FLAG))
+ memcpy(&msg.data[0], ptr, 8);
+ ptr += 8;
+ /* update socket */
+ if (cmd & CMD_ACK) {
+ /* acknowledge, was tx msg */
+ struct sk_buff *skb;
+ skb = priv->can.echo_skb[priv->tx.echo_get];
+ if (skb)
+ skb->tstamp = ktime;
+ can_get_echo_skb(netdev, priv->tx.echo_get);
+ ++priv->tx.echo_get;
+ if (priv->tx.echo_get >= TX_ECHO_SKB_MAX)
+ priv->tx.echo_get = 0;
+ if (priv->tx.pending)
+ --priv->tx.pending;
+ if (card->tx.pending)
+ --card->tx.pending;
+ ++netdev->stats.tx_packets;
+ if (!(msg.can_id & CAN_RTR_FLAG))
+ netdev->stats.tx_bytes += msg.can_dlc;
+ } else {
+ int ret;
+
+ ret = softing_netdev_rx(netdev, &msg, ktime);
+ if (ret == NET_RX_SUCCESS) {
+ ++netdev->stats.rx_packets;
+ if (!(msg.can_id & CAN_RTR_FLAG))
+ netdev->stats.rx_bytes += msg.can_dlc;
+ } else {
+ ++netdev->stats.rx_dropped;
+ }
+ }
+ }
+ ++cnt;
+ return cnt;
+}
+
+/*
+ * real interrupt handler
+ */
+static irqreturn_t softing_irq_thread(int irq, void *dev_id)
+{
+ struct softing *card = (struct softing *)dev_id;
+ struct net_device *netdev;
+ struct softing_priv *priv;
+ int j, offset, work_done;
+
+ work_done = 0;
+ spin_lock_bh(&card->spin);
+ while (softing_handle_1(card) > 0) {
+ ++card->irq.svc_count;
+ ++work_done;
+ }
+ spin_unlock_bh(&card->spin);
+ /* resume tx queue's */
+ offset = card->tx.last_bus;
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ if (card->tx.pending >= TXMAX)
+ break;
+ netdev = card->net[(j + offset + 1) % card->pdat->nbus];
+ if (!netdev)
+ continue;
+ priv = netdev_priv(netdev);
+ if (!canif_is_active(netdev))
+ /* it makes no sense to wake dead busses */
+ continue;
+ if (priv->tx.pending >= TX_ECHO_SKB_MAX)
+ continue;
+ ++work_done;
+ netif_wake_queue(netdev);
+ }
+ return work_done ? IRQ_HANDLED : IRQ_NONE;
+}
+
+/*
+ * interrupt routines:
+ * schedule the 'real interrupt handler'
+ */
+static irqreturn_t softing_irq_v2(int irq, void *dev_id)
+{
+ struct softing *card = (struct softing *)dev_id;
+ uint8_t ir;
+
+ ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]);
+ iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]);
+ return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE;
+}
+
+static irqreturn_t softing_irq_v1(int irq, void *dev_id)
+{
+ struct softing *card = (struct softing *)dev_id;
+ uint8_t ir;
+
+ ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]);
+ iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]);
+ return ir ? IRQ_WAKE_THREAD : IRQ_NONE;
+}
+
+/*
+ * netdev/candev inter-operability
+ */
+static int softing_netdev_open(struct net_device *ndev)
+{
+ int ret;
+
+ /* check or determine and set bittime */
+ ret = open_candev(ndev);
+ if (!ret)
+ ret = softing_startstop(ndev, 1);
+ return ret;
+}
+
+static int softing_netdev_stop(struct net_device *ndev)
+{
+ int ret;
+
+ netif_stop_queue(ndev);
+
+ /* softing cycle does close_candev() */
+ ret = softing_startstop(ndev, 0);
+ return ret;
+}
+
+static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ int ret;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ /* softing_startstop does close_candev() */
+ ret = softing_startstop(ndev, 1);
+ return ret;
+ case CAN_MODE_STOP:
+ case CAN_MODE_SLEEP:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+/*
+ * Softing device management helpers
+ */
+int softing_enable_irq(struct softing *card, int enable)
+{
+ int ret;
+
+ if (!card->irq.nr) {
+ return 0;
+ } else if (card->irq.requested && !enable) {
+ free_irq(card->irq.nr, card);
+ card->irq.requested = 0;
+ } else if (!card->irq.requested && enable) {
+ ret = request_threaded_irq(card->irq.nr,
+ (card->pdat->generation >= 2) ?
+ softing_irq_v2 : softing_irq_v1,
+ softing_irq_thread, IRQF_SHARED,
+ dev_name(&card->pdev->dev), card);
+ if (ret) {
+ dev_alert(&card->pdev->dev,
+ "request_threaded_irq(%u) failed\n",
+ card->irq.nr);
+ return ret;
+ }
+ card->irq.requested = 1;
+ }
+ return 0;
+}
+
+static void softing_card_shutdown(struct softing *card)
+{
+ int fw_up = 0;
+
+ if (mutex_lock_interruptible(&card->fw.lock))
+ /* return -ERESTARTSYS */;
+ fw_up = card->fw.up;
+ card->fw.up = 0;
+
+ if (card->irq.requested && card->irq.nr) {
+ free_irq(card->irq.nr, card);
+ card->irq.requested = 0;
+ }
+ if (fw_up) {
+ if (card->pdat->enable_irq)
+ card->pdat->enable_irq(card->pdev, 0);
+ softing_set_reset_dpram(card);
+ if (card->pdat->reset)
+ card->pdat->reset(card->pdev, 1);
+ }
+ mutex_unlock(&card->fw.lock);
+}
+
+static int softing_card_boot(struct softing *card)
+{
+ int ret, j;
+ static const uint8_t stream[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, };
+ unsigned char back[sizeof(stream)];
+
+ if (mutex_lock_interruptible(&card->fw.lock))
+ return -ERESTARTSYS;
+ if (card->fw.up) {
+ mutex_unlock(&card->fw.lock);
+ return 0;
+ }
+ /* reset board */
+ if (card->pdat->enable_irq)
+ card->pdat->enable_irq(card->pdev, 1);
+ /* boot card */
+ softing_set_reset_dpram(card);
+ if (card->pdat->reset)
+ card->pdat->reset(card->pdev, 1);
+ for (j = 0; (j + sizeof(stream)) < card->dpram_size;
+ j += sizeof(stream)) {
+
+ memcpy_toio(&card->dpram[j], stream, sizeof(stream));
+ /* flush IO cache */
+ mb();
+ memcpy_fromio(back, &card->dpram[j], sizeof(stream));
+
+ if (!memcmp(back, stream, sizeof(stream)))
+ continue;
+ /* memory is not equal */
+ dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j);
+ ret = -EIO;
+ goto failed;
+ }
+ wmb();
+ /* load boot firmware */
+ ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram,
+ card->dpram_size,
+ card->pdat->boot.offs - card->pdat->boot.addr);
+ if (ret < 0)
+ goto failed;
+ /* load loader firmware */
+ ret = softing_load_fw(card->pdat->load.fw, card, card->dpram,
+ card->dpram_size,
+ card->pdat->load.offs - card->pdat->load.addr);
+ if (ret < 0)
+ goto failed;
+
+ if (card->pdat->reset)
+ card->pdat->reset(card->pdev, 0);
+ softing_clr_reset_dpram(card);
+ ret = softing_bootloader_command(card, 0, "card boot");
+ if (ret < 0)
+ goto failed;
+ ret = softing_load_app_fw(card->pdat->app.fw, card);
+ if (ret < 0)
+ goto failed;
+
+ ret = softing_chip_poweron(card);
+ if (ret < 0)
+ goto failed;
+
+ card->fw.up = 1;
+ mutex_unlock(&card->fw.lock);
+ return 0;
+failed:
+ card->fw.up = 0;
+ if (card->pdat->enable_irq)
+ card->pdat->enable_irq(card->pdev, 0);
+ softing_set_reset_dpram(card);
+ if (card->pdat->reset)
+ card->pdat->reset(card->pdev, 1);
+ mutex_unlock(&card->fw.lock);
+ return ret;
+}
+
+/*
+ * netdev sysfs
+ */
+static ssize_t show_chip(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct net_device *ndev = to_net_dev(dev);
+ struct softing_priv *priv = netdev2softing(ndev);
+
+ return sprintf(buf, "%i\n", priv->chip);
+}
+
+static ssize_t show_output(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct net_device *ndev = to_net_dev(dev);
+ struct softing_priv *priv = netdev2softing(ndev);
+
+ return sprintf(buf, "0x%02x\n", priv->output);
+}
+
+static ssize_t store_output(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct net_device *ndev = to_net_dev(dev);
+ struct softing_priv *priv = netdev2softing(ndev);
+ struct softing *card = priv->card;
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+ val &= 0xFF;
+
+ ret = mutex_lock_interruptible(&card->fw.lock);
+ if (ret)
+ return -ERESTARTSYS;
+ if (netif_running(ndev)) {
+ mutex_unlock(&card->fw.lock);
+ return -EBUSY;
+ }
+ priv->output = val;
+ mutex_unlock(&card->fw.lock);
+ return count;
+}
+
+static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL);
+static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output);
+
+static const struct attribute *const netdev_sysfs_attrs[] = {
+ &dev_attr_chip.attr,
+ &dev_attr_output.attr,
+ NULL,
+};
+static const struct attribute_group netdev_sysfs_group = {
+ .name = NULL,
+ .attrs = (struct attribute **)netdev_sysfs_attrs,
+};
+
+static const struct net_device_ops softing_netdev_ops = {
+ .ndo_open = softing_netdev_open,
+ .ndo_stop = softing_netdev_stop,
+ .ndo_start_xmit = softing_netdev_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static const struct can_bittiming_const softing_btr_const = {
+ .name = "softing",
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4, /* overruled */
+ .brp_min = 1,
+ .brp_max = 32, /* overruled */
+ .brp_inc = 1,
+};
+
+
+static struct net_device *softing_netdev_create(struct softing *card,
+ uint16_t chip_id)
+{
+ struct net_device *netdev;
+ struct softing_priv *priv;
+
+ netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
+ if (!netdev) {
+ dev_alert(&card->pdev->dev, "alloc_candev failed\n");
+ return NULL;
+ }
+ priv = netdev_priv(netdev);
+ priv->netdev = netdev;
+ priv->card = card;
+ memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const));
+ priv->btr_const.brp_max = card->pdat->max_brp;
+ priv->btr_const.sjw_max = card->pdat->max_sjw;
+ priv->can.bittiming_const = &priv->btr_const;
+ priv->can.clock.freq = 8000000;
+ priv->chip = chip_id;
+ priv->output = softing_default_output(netdev);
+ SET_NETDEV_DEV(netdev, &card->pdev->dev);
+
+ netdev->flags |= IFF_ECHO;
+ netdev->netdev_ops = &softing_netdev_ops;
+ priv->can.do_set_mode = softing_candev_set_mode;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+
+ return netdev;
+}
+
+static int softing_netdev_register(struct net_device *netdev)
+{
+ int ret;
+
+ ret = register_candev(netdev);
+ if (ret) {
+ dev_alert(&netdev->dev, "register failed\n");
+ return ret;
+ }
+ if (sysfs_create_group(&netdev->dev.kobj, &netdev_sysfs_group) < 0)
+ netdev_alert(netdev, "sysfs group failed\n");
+
+ return 0;
+}
+
+static void softing_netdev_cleanup(struct net_device *netdev)
+{
+ sysfs_remove_group(&netdev->dev.kobj, &netdev_sysfs_group);
+ unregister_candev(netdev);
+ free_candev(netdev);
+}
+
+/*
+ * sysfs for Platform device
+ */
+#define DEV_ATTR_RO(name, member) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct softing *card = platform_get_drvdata(to_platform_device(dev)); \
+ return sprintf(buf, "%u\n", card->member); \
+} \
+static DEVICE_ATTR(name, 0444, show_##name, NULL)
+
+#define DEV_ATTR_RO_STR(name, member) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct softing *card = platform_get_drvdata(to_platform_device(dev)); \
+ return sprintf(buf, "%s\n", card->member); \
+} \
+static DEVICE_ATTR(name, 0444, show_##name, NULL)
+
+DEV_ATTR_RO(serial, id.serial);
+DEV_ATTR_RO_STR(firmware, pdat->app.fw);
+DEV_ATTR_RO(firmware_version, id.fw_version);
+DEV_ATTR_RO_STR(hardware, pdat->name);
+DEV_ATTR_RO(hardware_version, id.hw_version);
+DEV_ATTR_RO(license, id.license);
+
+static struct attribute *softing_pdev_attrs[] = {
+ &dev_attr_serial.attr,
+ &dev_attr_firmware.attr,
+ &dev_attr_firmware_version.attr,
+ &dev_attr_hardware.attr,
+ &dev_attr_hardware_version.attr,
+ &dev_attr_license.attr,
+ NULL,
+};
+
+static const struct attribute_group softing_pdev_group = {
+ .name = NULL,
+ .attrs = softing_pdev_attrs,
+};
+
+/*
+ * platform driver
+ */
+static int softing_pdev_remove(struct platform_device *pdev)
+{
+ struct softing *card = platform_get_drvdata(pdev);
+ int j;
+
+ /* first, disable card*/
+ softing_card_shutdown(card);
+
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ if (!card->net[j])
+ continue;
+ softing_netdev_cleanup(card->net[j]);
+ card->net[j] = NULL;
+ }
+ sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
+
+ iounmap(card->dpram);
+ kfree(card);
+ return 0;
+}
+
+static int softing_pdev_probe(struct platform_device *pdev)
+{
+ const struct softing_platform_data *pdat = dev_get_platdata(&pdev->dev);
+ struct softing *card;
+ struct net_device *netdev;
+ struct softing_priv *priv;
+ struct resource *pres;
+ int ret;
+ int j;
+
+ if (!pdat) {
+ dev_warn(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+ if (pdat->nbus > ARRAY_SIZE(card->net)) {
+ dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus);
+ return -EINVAL;
+ }
+
+ card = kzalloc(sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+ card->pdat = pdat;
+ card->pdev = pdev;
+ platform_set_drvdata(pdev, card);
+ mutex_init(&card->fw.lock);
+ spin_lock_init(&card->spin);
+
+ ret = -EINVAL;
+ pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!pres)
+ goto platform_resource_failed;
+ card->dpram_phys = pres->start;
+ card->dpram_size = resource_size(pres);
+ card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size);
+ if (!card->dpram) {
+ dev_alert(&card->pdev->dev, "dpram ioremap failed\n");
+ goto ioremap_failed;
+ }
+
+ pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (pres)
+ card->irq.nr = pres->start;
+
+ /* reset card */
+ ret = softing_card_boot(card);
+ if (ret < 0) {
+ dev_alert(&pdev->dev, "failed to boot\n");
+ goto boot_failed;
+ }
+
+ /* only now, the chip's are known */
+ card->id.freq = card->pdat->freq;
+
+ ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group);
+ if (ret < 0) {
+ dev_alert(&card->pdev->dev, "sysfs failed\n");
+ goto sysfs_failed;
+ }
+
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ card->net[j] = netdev =
+ softing_netdev_create(card, card->id.chip[j]);
+ if (!netdev) {
+ dev_alert(&pdev->dev, "failed to make can[%i]", j);
+ ret = -ENOMEM;
+ goto netdev_failed;
+ }
+ netdev->dev_id = j;
+ priv = netdev_priv(card->net[j]);
+ priv->index = j;
+ ret = softing_netdev_register(netdev);
+ if (ret) {
+ free_candev(netdev);
+ card->net[j] = NULL;
+ dev_alert(&card->pdev->dev,
+ "failed to register can[%i]\n", j);
+ goto netdev_failed;
+ }
+ }
+ dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name);
+ return 0;
+
+netdev_failed:
+ for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+ if (!card->net[j])
+ continue;
+ softing_netdev_cleanup(card->net[j]);
+ }
+ sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
+sysfs_failed:
+ softing_card_shutdown(card);
+boot_failed:
+ iounmap(card->dpram);
+ioremap_failed:
+platform_resource_failed:
+ kfree(card);
+ return ret;
+}
+
+static struct platform_driver softing_driver = {
+ .driver = {
+ .name = "softing",
+ .owner = THIS_MODULE,
+ },
+ .probe = softing_pdev_probe,
+ .remove = softing_pdev_remove,
+};
+
+module_platform_driver(softing_driver);
+
+MODULE_ALIAS("platform:softing");
+MODULE_DESCRIPTION("Softing DPRAM CAN driver");
+MODULE_AUTHOR("Kurt Van Dijck <kurt.van.dijck@eia.be>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/softing/softing_platform.h b/drivers/net/can/softing/softing_platform.h
new file mode 100644
index 00000000000..ebbf6981562
--- /dev/null
+++ b/drivers/net/can/softing/softing_platform.h
@@ -0,0 +1,40 @@
+
+#include <linux/platform_device.h>
+
+#ifndef _SOFTING_DEVICE_H_
+#define _SOFTING_DEVICE_H_
+
+/* softing firmware directory prefix */
+#define fw_dir "softing-4.6/"
+
+struct softing_platform_data {
+ unsigned int manf;
+ unsigned int prod;
+ /*
+ * generation
+ * 1st with NEC or SJA1000
+ * 8bit, exclusive interrupt, ...
+ * 2nd only SJA1000
+ * 16bit, shared interrupt
+ */
+ int generation;
+ int nbus; /* # busses on device */
+ unsigned int freq; /* operating frequency in Hz */
+ unsigned int max_brp;
+ unsigned int max_sjw;
+ unsigned long dpram_size;
+ const char *name;
+ struct {
+ unsigned long offs;
+ unsigned long addr;
+ const char *fw;
+ } boot, load, app;
+ /*
+ * reset() function
+ * bring pdev in or out of reset, depending on value
+ */
+ int (*reset)(struct platform_device *pdev, int value);
+ int (*enable_irq)(struct platform_device *pdev, int value);
+};
+
+#endif
diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig
new file mode 100644
index 00000000000..148cae5871a
--- /dev/null
+++ b/drivers/net/can/spi/Kconfig
@@ -0,0 +1,10 @@
+menu "CAN SPI interfaces"
+ depends on SPI
+
+config CAN_MCP251X
+ tristate "Microchip MCP251x SPI CAN controllers"
+ depends on HAS_DMA
+ ---help---
+ Driver for the Microchip MCP251x SPI CAN controllers.
+
+endmenu
diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile
new file mode 100644
index 00000000000..90bcacffbc6
--- /dev/null
+++ b/drivers/net/can/spi/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the Linux Controller Area Network SPI drivers.
+#
+
+
+obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
new file mode 100644
index 00000000000..5df239e6881
--- /dev/null
+++ b/drivers/net/can/spi/mcp251x.c
@@ -0,0 +1,1266 @@
+/*
+ * CAN bus driver for Microchip 251x CAN Controller with SPI Interface
+ *
+ * MCP2510 support and bug fixes by Christian Pellegrin
+ * <chripell@evolware.org>
+ *
+ * Copyright 2009 Christian Pellegrin EVOL S.r.l.
+ *
+ * Copyright 2007 Raymarine UK, Ltd. All Rights Reserved.
+ * Written under contract by:
+ * Chris Elston, Katalix Systems, Ltd.
+ *
+ * Based on Microchip MCP251x CAN controller driver written by
+ * David Vrabel, Copyright 2006 Arcom Control Systems Ltd.
+ *
+ * Based on CAN bus driver for the CCAN controller written by
+ * - Sascha Hauer, Marc Kleine-Budde, Pengutronix
+ * - Simon Kallweit, intefo AG
+ * Copyright 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ *
+ * Your platform definition file should specify something like:
+ *
+ * static struct mcp251x_platform_data mcp251x_info = {
+ * .oscillator_frequency = 8000000,
+ * };
+ *
+ * static struct spi_board_info spi_board_info[] = {
+ * {
+ * .modalias = "mcp2510",
+ * // or "mcp2515" depending on your controller
+ * .platform_data = &mcp251x_info,
+ * .irq = IRQ_EINT13,
+ * .max_speed_hz = 2*1000*1000,
+ * .chip_select = 2,
+ * },
+ * };
+ *
+ * Please see mcp251x.h for a description of the fields in
+ * struct mcp251x_platform_data.
+ *
+ */
+
+#include <linux/can/core.h>
+#include <linux/can/dev.h>
+#include <linux/can/led.h>
+#include <linux/can/platform/mcp251x.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/freezer.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/uaccess.h>
+#include <linux/regulator/consumer.h>
+
+/* SPI interface instruction set */
+#define INSTRUCTION_WRITE 0x02
+#define INSTRUCTION_READ 0x03
+#define INSTRUCTION_BIT_MODIFY 0x05
+#define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n))
+#define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94)
+#define INSTRUCTION_RESET 0xC0
+#define RTS_TXB0 0x01
+#define RTS_TXB1 0x02
+#define RTS_TXB2 0x04
+#define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07))
+
+
+/* MPC251x registers */
+#define CANSTAT 0x0e
+#define CANCTRL 0x0f
+# define CANCTRL_REQOP_MASK 0xe0
+# define CANCTRL_REQOP_CONF 0x80
+# define CANCTRL_REQOP_LISTEN_ONLY 0x60
+# define CANCTRL_REQOP_LOOPBACK 0x40
+# define CANCTRL_REQOP_SLEEP 0x20
+# define CANCTRL_REQOP_NORMAL 0x00
+# define CANCTRL_OSM 0x08
+# define CANCTRL_ABAT 0x10
+#define TEC 0x1c
+#define REC 0x1d
+#define CNF1 0x2a
+# define CNF1_SJW_SHIFT 6
+#define CNF2 0x29
+# define CNF2_BTLMODE 0x80
+# define CNF2_SAM 0x40
+# define CNF2_PS1_SHIFT 3
+#define CNF3 0x28
+# define CNF3_SOF 0x08
+# define CNF3_WAKFIL 0x04
+# define CNF3_PHSEG2_MASK 0x07
+#define CANINTE 0x2b
+# define CANINTE_MERRE 0x80
+# define CANINTE_WAKIE 0x40
+# define CANINTE_ERRIE 0x20
+# define CANINTE_TX2IE 0x10
+# define CANINTE_TX1IE 0x08
+# define CANINTE_TX0IE 0x04
+# define CANINTE_RX1IE 0x02
+# define CANINTE_RX0IE 0x01
+#define CANINTF 0x2c
+# define CANINTF_MERRF 0x80
+# define CANINTF_WAKIF 0x40
+# define CANINTF_ERRIF 0x20
+# define CANINTF_TX2IF 0x10
+# define CANINTF_TX1IF 0x08
+# define CANINTF_TX0IF 0x04
+# define CANINTF_RX1IF 0x02
+# define CANINTF_RX0IF 0x01
+# define CANINTF_RX (CANINTF_RX0IF | CANINTF_RX1IF)
+# define CANINTF_TX (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)
+# define CANINTF_ERR (CANINTF_ERRIF)
+#define EFLG 0x2d
+# define EFLG_EWARN 0x01
+# define EFLG_RXWAR 0x02
+# define EFLG_TXWAR 0x04
+# define EFLG_RXEP 0x08
+# define EFLG_TXEP 0x10
+# define EFLG_TXBO 0x20
+# define EFLG_RX0OVR 0x40
+# define EFLG_RX1OVR 0x80
+#define TXBCTRL(n) (((n) * 0x10) + 0x30 + TXBCTRL_OFF)
+# define TXBCTRL_ABTF 0x40
+# define TXBCTRL_MLOA 0x20
+# define TXBCTRL_TXERR 0x10
+# define TXBCTRL_TXREQ 0x08
+#define TXBSIDH(n) (((n) * 0x10) + 0x30 + TXBSIDH_OFF)
+# define SIDH_SHIFT 3
+#define TXBSIDL(n) (((n) * 0x10) + 0x30 + TXBSIDL_OFF)
+# define SIDL_SID_MASK 7
+# define SIDL_SID_SHIFT 5
+# define SIDL_EXIDE_SHIFT 3
+# define SIDL_EID_SHIFT 16
+# define SIDL_EID_MASK 3
+#define TXBEID8(n) (((n) * 0x10) + 0x30 + TXBEID8_OFF)
+#define TXBEID0(n) (((n) * 0x10) + 0x30 + TXBEID0_OFF)
+#define TXBDLC(n) (((n) * 0x10) + 0x30 + TXBDLC_OFF)
+# define DLC_RTR_SHIFT 6
+#define TXBCTRL_OFF 0
+#define TXBSIDH_OFF 1
+#define TXBSIDL_OFF 2
+#define TXBEID8_OFF 3
+#define TXBEID0_OFF 4
+#define TXBDLC_OFF 5
+#define TXBDAT_OFF 6
+#define RXBCTRL(n) (((n) * 0x10) + 0x60 + RXBCTRL_OFF)
+# define RXBCTRL_BUKT 0x04
+# define RXBCTRL_RXM0 0x20
+# define RXBCTRL_RXM1 0x40
+#define RXBSIDH(n) (((n) * 0x10) + 0x60 + RXBSIDH_OFF)
+# define RXBSIDH_SHIFT 3
+#define RXBSIDL(n) (((n) * 0x10) + 0x60 + RXBSIDL_OFF)
+# define RXBSIDL_IDE 0x08
+# define RXBSIDL_SRR 0x10
+# define RXBSIDL_EID 3
+# define RXBSIDL_SHIFT 5
+#define RXBEID8(n) (((n) * 0x10) + 0x60 + RXBEID8_OFF)
+#define RXBEID0(n) (((n) * 0x10) + 0x60 + RXBEID0_OFF)
+#define RXBDLC(n) (((n) * 0x10) + 0x60 + RXBDLC_OFF)
+# define RXBDLC_LEN_MASK 0x0f
+# define RXBDLC_RTR 0x40
+#define RXBCTRL_OFF 0
+#define RXBSIDH_OFF 1
+#define RXBSIDL_OFF 2
+#define RXBEID8_OFF 3
+#define RXBEID0_OFF 4
+#define RXBDLC_OFF 5
+#define RXBDAT_OFF 6
+#define RXFSIDH(n) ((n) * 4)
+#define RXFSIDL(n) ((n) * 4 + 1)
+#define RXFEID8(n) ((n) * 4 + 2)
+#define RXFEID0(n) ((n) * 4 + 3)
+#define RXMSIDH(n) ((n) * 4 + 0x20)
+#define RXMSIDL(n) ((n) * 4 + 0x21)
+#define RXMEID8(n) ((n) * 4 + 0x22)
+#define RXMEID0(n) ((n) * 4 + 0x23)
+
+#define GET_BYTE(val, byte) \
+ (((val) >> ((byte) * 8)) & 0xff)
+#define SET_BYTE(val, byte) \
+ (((val) & 0xff) << ((byte) * 8))
+
+/*
+ * Buffer size required for the largest SPI transfer (i.e., reading a
+ * frame)
+ */
+#define CAN_FRAME_MAX_DATA_LEN 8
+#define SPI_TRANSFER_BUF_LEN (6 + CAN_FRAME_MAX_DATA_LEN)
+#define CAN_FRAME_MAX_BITS 128
+
+#define TX_ECHO_SKB_MAX 1
+
+#define MCP251X_OST_DELAY_MS (5)
+
+#define DEVICE_NAME "mcp251x"
+
+static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
+module_param(mcp251x_enable_dma, int, S_IRUGO);
+MODULE_PARM_DESC(mcp251x_enable_dma, "Enable SPI DMA. Default: 0 (Off)");
+
+static const struct can_bittiming_const mcp251x_bittiming_const = {
+ .name = DEVICE_NAME,
+ .tseg1_min = 3,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+};
+
+enum mcp251x_model {
+ CAN_MCP251X_MCP2510 = 0x2510,
+ CAN_MCP251X_MCP2515 = 0x2515,
+};
+
+struct mcp251x_priv {
+ struct can_priv can;
+ struct net_device *net;
+ struct spi_device *spi;
+ enum mcp251x_model model;
+
+ struct mutex mcp_lock; /* SPI device lock */
+
+ u8 *spi_tx_buf;
+ u8 *spi_rx_buf;
+ dma_addr_t spi_tx_dma;
+ dma_addr_t spi_rx_dma;
+
+ struct sk_buff *tx_skb;
+ int tx_len;
+
+ struct workqueue_struct *wq;
+ struct work_struct tx_work;
+ struct work_struct restart_work;
+
+ int force_quit;
+ int after_suspend;
+#define AFTER_SUSPEND_UP 1
+#define AFTER_SUSPEND_DOWN 2
+#define AFTER_SUSPEND_POWER 4
+#define AFTER_SUSPEND_RESTART 8
+ int restart_tx;
+ struct regulator *power;
+ struct regulator *transceiver;
+ struct clk *clk;
+};
+
+#define MCP251X_IS(_model) \
+static inline int mcp251x_is_##_model(struct spi_device *spi) \
+{ \
+ struct mcp251x_priv *priv = spi_get_drvdata(spi); \
+ return priv->model == CAN_MCP251X_MCP##_model; \
+}
+
+MCP251X_IS(2510);
+MCP251X_IS(2515);
+
+static void mcp251x_clean(struct net_device *net)
+{
+ struct mcp251x_priv *priv = netdev_priv(net);
+
+ if (priv->tx_skb || priv->tx_len)
+ net->stats.tx_errors++;
+ if (priv->tx_skb)
+ dev_kfree_skb(priv->tx_skb);
+ if (priv->tx_len)
+ can_free_echo_skb(priv->net, 0);
+ priv->tx_skb = NULL;
+ priv->tx_len = 0;
+}
+
+/*
+ * Note about handling of error return of mcp251x_spi_trans: accessing
+ * registers via SPI is not really different conceptually than using
+ * normal I/O assembler instructions, although it's much more
+ * complicated from a practical POV. So it's not advisable to always
+ * check the return value of this function. Imagine that every
+ * read{b,l}, write{b,l} and friends would be bracketed in "if ( < 0)
+ * error();", it would be a great mess (well there are some situation
+ * when exception handling C++ like could be useful after all). So we
+ * just check that transfers are OK at the beginning of our
+ * conversation with the chip and to avoid doing really nasty things
+ * (like injecting bogus packets in the network stack).
+ */
+static int mcp251x_spi_trans(struct spi_device *spi, int len)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ struct spi_transfer t = {
+ .tx_buf = priv->spi_tx_buf,
+ .rx_buf = priv->spi_rx_buf,
+ .len = len,
+ .cs_change = 0,
+ };
+ struct spi_message m;
+ int ret;
+
+ spi_message_init(&m);
+
+ if (mcp251x_enable_dma) {
+ t.tx_dma = priv->spi_tx_dma;
+ t.rx_dma = priv->spi_rx_dma;
+ m.is_dma_mapped = 1;
+ }
+
+ spi_message_add_tail(&t, &m);
+
+ ret = spi_sync(spi, &m);
+ if (ret)
+ dev_err(&spi->dev, "spi transfer failed: ret = %d\n", ret);
+ return ret;
+}
+
+static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ u8 val = 0;
+
+ priv->spi_tx_buf[0] = INSTRUCTION_READ;
+ priv->spi_tx_buf[1] = reg;
+
+ mcp251x_spi_trans(spi, 3);
+ val = priv->spi_rx_buf[2];
+
+ return val;
+}
+
+static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg,
+ uint8_t *v1, uint8_t *v2)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+
+ priv->spi_tx_buf[0] = INSTRUCTION_READ;
+ priv->spi_tx_buf[1] = reg;
+
+ mcp251x_spi_trans(spi, 4);
+
+ *v1 = priv->spi_rx_buf[2];
+ *v2 = priv->spi_rx_buf[3];
+}
+
+static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+
+ priv->spi_tx_buf[0] = INSTRUCTION_WRITE;
+ priv->spi_tx_buf[1] = reg;
+ priv->spi_tx_buf[2] = val;
+
+ mcp251x_spi_trans(spi, 3);
+}
+
+static void mcp251x_write_bits(struct spi_device *spi, u8 reg,
+ u8 mask, uint8_t val)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+
+ priv->spi_tx_buf[0] = INSTRUCTION_BIT_MODIFY;
+ priv->spi_tx_buf[1] = reg;
+ priv->spi_tx_buf[2] = mask;
+ priv->spi_tx_buf[3] = val;
+
+ mcp251x_spi_trans(spi, 4);
+}
+
+static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
+ int len, int tx_buf_idx)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+
+ if (mcp251x_is_2510(spi)) {
+ int i;
+
+ for (i = 1; i < TXBDAT_OFF + len; i++)
+ mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx) + i,
+ buf[i]);
+ } else {
+ memcpy(priv->spi_tx_buf, buf, TXBDAT_OFF + len);
+ mcp251x_spi_trans(spi, TXBDAT_OFF + len);
+ }
+}
+
+static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
+ int tx_buf_idx)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ u32 sid, eid, exide, rtr;
+ u8 buf[SPI_TRANSFER_BUF_LEN];
+
+ exide = (frame->can_id & CAN_EFF_FLAG) ? 1 : 0; /* Extended ID Enable */
+ if (exide)
+ sid = (frame->can_id & CAN_EFF_MASK) >> 18;
+ else
+ sid = frame->can_id & CAN_SFF_MASK; /* Standard ID */
+ eid = frame->can_id & CAN_EFF_MASK; /* Extended ID */
+ rtr = (frame->can_id & CAN_RTR_FLAG) ? 1 : 0; /* Remote transmission */
+
+ buf[TXBCTRL_OFF] = INSTRUCTION_LOAD_TXB(tx_buf_idx);
+ buf[TXBSIDH_OFF] = sid >> SIDH_SHIFT;
+ buf[TXBSIDL_OFF] = ((sid & SIDL_SID_MASK) << SIDL_SID_SHIFT) |
+ (exide << SIDL_EXIDE_SHIFT) |
+ ((eid >> SIDL_EID_SHIFT) & SIDL_EID_MASK);
+ buf[TXBEID8_OFF] = GET_BYTE(eid, 1);
+ buf[TXBEID0_OFF] = GET_BYTE(eid, 0);
+ buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
+ memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
+ mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
+
+ /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */
+ priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
+ mcp251x_spi_trans(priv->spi, 1);
+}
+
+static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
+ int buf_idx)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+
+ if (mcp251x_is_2510(spi)) {
+ int i, len;
+
+ for (i = 1; i < RXBDAT_OFF; i++)
+ buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
+
+ len = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
+ for (; i < (RXBDAT_OFF + len); i++)
+ buf[i] = mcp251x_read_reg(spi, RXBCTRL(buf_idx) + i);
+ } else {
+ priv->spi_tx_buf[RXBCTRL_OFF] = INSTRUCTION_READ_RXB(buf_idx);
+ mcp251x_spi_trans(spi, SPI_TRANSFER_BUF_LEN);
+ memcpy(buf, priv->spi_rx_buf, SPI_TRANSFER_BUF_LEN);
+ }
+}
+
+static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ struct sk_buff *skb;
+ struct can_frame *frame;
+ u8 buf[SPI_TRANSFER_BUF_LEN];
+
+ skb = alloc_can_skb(priv->net, &frame);
+ if (!skb) {
+ dev_err(&spi->dev, "cannot allocate RX skb\n");
+ priv->net->stats.rx_dropped++;
+ return;
+ }
+
+ mcp251x_hw_rx_frame(spi, buf, buf_idx);
+ if (buf[RXBSIDL_OFF] & RXBSIDL_IDE) {
+ /* Extended ID format */
+ frame->can_id = CAN_EFF_FLAG;
+ frame->can_id |=
+ /* Extended ID part */
+ SET_BYTE(buf[RXBSIDL_OFF] & RXBSIDL_EID, 2) |
+ SET_BYTE(buf[RXBEID8_OFF], 1) |
+ SET_BYTE(buf[RXBEID0_OFF], 0) |
+ /* Standard ID part */
+ (((buf[RXBSIDH_OFF] << RXBSIDH_SHIFT) |
+ (buf[RXBSIDL_OFF] >> RXBSIDL_SHIFT)) << 18);
+ /* Remote transmission request */
+ if (buf[RXBDLC_OFF] & RXBDLC_RTR)
+ frame->can_id |= CAN_RTR_FLAG;
+ } else {
+ /* Standard ID format */
+ frame->can_id =
+ (buf[RXBSIDH_OFF] << RXBSIDH_SHIFT) |
+ (buf[RXBSIDL_OFF] >> RXBSIDL_SHIFT);
+ if (buf[RXBSIDL_OFF] & RXBSIDL_SRR)
+ frame->can_id |= CAN_RTR_FLAG;
+ }
+ /* Data length */
+ frame->can_dlc = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK);
+ memcpy(frame->data, buf + RXBDAT_OFF, frame->can_dlc);
+
+ priv->net->stats.rx_packets++;
+ priv->net->stats.rx_bytes += frame->can_dlc;
+
+ can_led_event(priv->net, CAN_LED_EVENT_RX);
+
+ netif_rx_ni(skb);
+}
+
+static void mcp251x_hw_sleep(struct spi_device *spi)
+{
+ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_SLEEP);
+}
+
+static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
+ struct net_device *net)
+{
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+
+ if (priv->tx_skb || priv->tx_len) {
+ dev_warn(&spi->dev, "hard_xmit called while tx busy\n");
+ return NETDEV_TX_BUSY;
+ }
+
+ if (can_dropped_invalid_skb(net, skb))
+ return NETDEV_TX_OK;
+
+ netif_stop_queue(net);
+ priv->tx_skb = skb;
+ queue_work(priv->wq, &priv->tx_work);
+
+ return NETDEV_TX_OK;
+}
+
+static int mcp251x_do_set_mode(struct net_device *net, enum can_mode mode)
+{
+ struct mcp251x_priv *priv = netdev_priv(net);
+
+ switch (mode) {
+ case CAN_MODE_START:
+ mcp251x_clean(net);
+ /* We have to delay work since SPI I/O may sleep */
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ priv->restart_tx = 1;
+ if (priv->can.restart_ms == 0)
+ priv->after_suspend = AFTER_SUSPEND_RESTART;
+ queue_work(priv->wq, &priv->restart_work);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int mcp251x_set_normal_mode(struct spi_device *spi)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ unsigned long timeout;
+
+ /* Enable interrupts */
+ mcp251x_write_reg(spi, CANINTE,
+ CANINTE_ERRIE | CANINTE_TX2IE | CANINTE_TX1IE |
+ CANINTE_TX0IE | CANINTE_RX1IE | CANINTE_RX0IE);
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+ /* Put device into loopback mode */
+ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+ /* Put device into listen-only mode */
+ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
+ } else {
+ /* Put device into normal mode */
+ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
+
+ /* Wait for the device to enter normal mode */
+ timeout = jiffies + HZ;
+ while (mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK) {
+ schedule();
+ if (time_after(jiffies, timeout)) {
+ dev_err(&spi->dev, "MCP251x didn't"
+ " enter in normal mode\n");
+ return -EBUSY;
+ }
+ }
+ }
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ return 0;
+}
+
+static int mcp251x_do_set_bittiming(struct net_device *net)
+{
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ struct spi_device *spi = priv->spi;
+
+ mcp251x_write_reg(spi, CNF1, ((bt->sjw - 1) << CNF1_SJW_SHIFT) |
+ (bt->brp - 1));
+ mcp251x_write_reg(spi, CNF2, CNF2_BTLMODE |
+ (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES ?
+ CNF2_SAM : 0) |
+ ((bt->phase_seg1 - 1) << CNF2_PS1_SHIFT) |
+ (bt->prop_seg - 1));
+ mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK,
+ (bt->phase_seg2 - 1));
+ dev_dbg(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n",
+ mcp251x_read_reg(spi, CNF1),
+ mcp251x_read_reg(spi, CNF2),
+ mcp251x_read_reg(spi, CNF3));
+
+ return 0;
+}
+
+static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
+ struct spi_device *spi)
+{
+ mcp251x_do_set_bittiming(net);
+
+ mcp251x_write_reg(spi, RXBCTRL(0),
+ RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1);
+ mcp251x_write_reg(spi, RXBCTRL(1),
+ RXBCTRL_RXM0 | RXBCTRL_RXM1);
+ return 0;
+}
+
+static int mcp251x_hw_reset(struct spi_device *spi)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ u8 reg;
+ int ret;
+
+ /* Wait for oscillator startup timer after power up */
+ mdelay(MCP251X_OST_DELAY_MS);
+
+ priv->spi_tx_buf[0] = INSTRUCTION_RESET;
+ ret = mcp251x_spi_trans(spi, 1);
+ if (ret)
+ return ret;
+
+ /* Wait for oscillator startup timer after reset */
+ mdelay(MCP251X_OST_DELAY_MS);
+
+ reg = mcp251x_read_reg(spi, CANSTAT);
+ if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
+ return -ENODEV;
+
+ return 0;
+}
+
+static int mcp251x_hw_probe(struct spi_device *spi)
+{
+ u8 ctrl;
+ int ret;
+
+ ret = mcp251x_hw_reset(spi);
+ if (ret)
+ return ret;
+
+ ctrl = mcp251x_read_reg(spi, CANCTRL);
+
+ dev_dbg(&spi->dev, "CANCTRL 0x%02x\n", ctrl);
+
+ /* Check for power up default value */
+ if ((ctrl & 0x17) != 0x07)
+ return -ENODEV;
+
+ return 0;
+}
+
+static int mcp251x_power_enable(struct regulator *reg, int enable)
+{
+ if (IS_ERR_OR_NULL(reg))
+ return 0;
+
+ if (enable)
+ return regulator_enable(reg);
+ else
+ return regulator_disable(reg);
+}
+
+static void mcp251x_open_clean(struct net_device *net)
+{
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+
+ free_irq(spi->irq, priv);
+ mcp251x_hw_sleep(spi);
+ mcp251x_power_enable(priv->transceiver, 0);
+ close_candev(net);
+}
+
+static int mcp251x_stop(struct net_device *net)
+{
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+
+ close_candev(net);
+
+ priv->force_quit = 1;
+ free_irq(spi->irq, priv);
+ destroy_workqueue(priv->wq);
+ priv->wq = NULL;
+
+ mutex_lock(&priv->mcp_lock);
+
+ /* Disable and clear pending interrupts */
+ mcp251x_write_reg(spi, CANINTE, 0x00);
+ mcp251x_write_reg(spi, CANINTF, 0x00);
+
+ mcp251x_write_reg(spi, TXBCTRL(0), 0);
+ mcp251x_clean(net);
+
+ mcp251x_hw_sleep(spi);
+
+ mcp251x_power_enable(priv->transceiver, 0);
+
+ priv->can.state = CAN_STATE_STOPPED;
+
+ mutex_unlock(&priv->mcp_lock);
+
+ can_led_event(net, CAN_LED_EVENT_STOP);
+
+ return 0;
+}
+
+static void mcp251x_error_skb(struct net_device *net, int can_id, int data1)
+{
+ struct sk_buff *skb;
+ struct can_frame *frame;
+
+ skb = alloc_can_err_skb(net, &frame);
+ if (skb) {
+ frame->can_id |= can_id;
+ frame->data[1] = data1;
+ netif_rx_ni(skb);
+ } else {
+ netdev_err(net, "cannot allocate error skb\n");
+ }
+}
+
+static void mcp251x_tx_work_handler(struct work_struct *ws)
+{
+ struct mcp251x_priv *priv = container_of(ws, struct mcp251x_priv,
+ tx_work);
+ struct spi_device *spi = priv->spi;
+ struct net_device *net = priv->net;
+ struct can_frame *frame;
+
+ mutex_lock(&priv->mcp_lock);
+ if (priv->tx_skb) {
+ if (priv->can.state == CAN_STATE_BUS_OFF) {
+ mcp251x_clean(net);
+ } else {
+ frame = (struct can_frame *)priv->tx_skb->data;
+
+ if (frame->can_dlc > CAN_FRAME_MAX_DATA_LEN)
+ frame->can_dlc = CAN_FRAME_MAX_DATA_LEN;
+ mcp251x_hw_tx(spi, frame, 0);
+ priv->tx_len = 1 + frame->can_dlc;
+ can_put_echo_skb(priv->tx_skb, net, 0);
+ priv->tx_skb = NULL;
+ }
+ }
+ mutex_unlock(&priv->mcp_lock);
+}
+
+static void mcp251x_restart_work_handler(struct work_struct *ws)
+{
+ struct mcp251x_priv *priv = container_of(ws, struct mcp251x_priv,
+ restart_work);
+ struct spi_device *spi = priv->spi;
+ struct net_device *net = priv->net;
+
+ mutex_lock(&priv->mcp_lock);
+ if (priv->after_suspend) {
+ mcp251x_hw_reset(spi);
+ mcp251x_setup(net, priv, spi);
+ if (priv->after_suspend & AFTER_SUSPEND_RESTART) {
+ mcp251x_set_normal_mode(spi);
+ } else if (priv->after_suspend & AFTER_SUSPEND_UP) {
+ netif_device_attach(net);
+ mcp251x_clean(net);
+ mcp251x_set_normal_mode(spi);
+ netif_wake_queue(net);
+ } else {
+ mcp251x_hw_sleep(spi);
+ }
+ priv->after_suspend = 0;
+ priv->force_quit = 0;
+ }
+
+ if (priv->restart_tx) {
+ priv->restart_tx = 0;
+ mcp251x_write_reg(spi, TXBCTRL(0), 0);
+ mcp251x_clean(net);
+ netif_wake_queue(net);
+ mcp251x_error_skb(net, CAN_ERR_RESTARTED, 0);
+ }
+ mutex_unlock(&priv->mcp_lock);
+}
+
+static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
+{
+ struct mcp251x_priv *priv = dev_id;
+ struct spi_device *spi = priv->spi;
+ struct net_device *net = priv->net;
+
+ mutex_lock(&priv->mcp_lock);
+ while (!priv->force_quit) {
+ enum can_state new_state;
+ u8 intf, eflag;
+ u8 clear_intf = 0;
+ int can_id = 0, data1 = 0;
+
+ mcp251x_read_2regs(spi, CANINTF, &intf, &eflag);
+
+ /* mask out flags we don't care about */
+ intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
+
+ /* receive buffer 0 */
+ if (intf & CANINTF_RX0IF) {
+ mcp251x_hw_rx(spi, 0);
+ /*
+ * Free one buffer ASAP
+ * (The MCP2515 does this automatically.)
+ */
+ if (mcp251x_is_2510(spi))
+ mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00);
+ }
+
+ /* receive buffer 1 */
+ if (intf & CANINTF_RX1IF) {
+ mcp251x_hw_rx(spi, 1);
+ /* the MCP2515 does this automatically */
+ if (mcp251x_is_2510(spi))
+ clear_intf |= CANINTF_RX1IF;
+ }
+
+ /* any error or tx interrupt we need to clear? */
+ if (intf & (CANINTF_ERR | CANINTF_TX))
+ clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
+ if (clear_intf)
+ mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00);
+
+ if (eflag)
+ mcp251x_write_bits(spi, EFLG, eflag, 0x00);
+
+ /* Update can state */
+ if (eflag & EFLG_TXBO) {
+ new_state = CAN_STATE_BUS_OFF;
+ can_id |= CAN_ERR_BUSOFF;
+ } else if (eflag & EFLG_TXEP) {
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_TX_PASSIVE;
+ } else if (eflag & EFLG_RXEP) {
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_RX_PASSIVE;
+ } else if (eflag & EFLG_TXWAR) {
+ new_state = CAN_STATE_ERROR_WARNING;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_TX_WARNING;
+ } else if (eflag & EFLG_RXWAR) {
+ new_state = CAN_STATE_ERROR_WARNING;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_RX_WARNING;
+ } else {
+ new_state = CAN_STATE_ERROR_ACTIVE;
+ }
+
+ /* Update can state statistics */
+ switch (priv->can.state) {
+ case CAN_STATE_ERROR_ACTIVE:
+ if (new_state >= CAN_STATE_ERROR_WARNING &&
+ new_state <= CAN_STATE_BUS_OFF)
+ priv->can.can_stats.error_warning++;
+ case CAN_STATE_ERROR_WARNING: /* fallthrough */
+ if (new_state >= CAN_STATE_ERROR_PASSIVE &&
+ new_state <= CAN_STATE_BUS_OFF)
+ priv->can.can_stats.error_passive++;
+ break;
+ default:
+ break;
+ }
+ priv->can.state = new_state;
+
+ if (intf & CANINTF_ERRIF) {
+ /* Handle overflow counters */
+ if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) {
+ if (eflag & EFLG_RX0OVR) {
+ net->stats.rx_over_errors++;
+ net->stats.rx_errors++;
+ }
+ if (eflag & EFLG_RX1OVR) {
+ net->stats.rx_over_errors++;
+ net->stats.rx_errors++;
+ }
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_RX_OVERFLOW;
+ }
+ mcp251x_error_skb(net, can_id, data1);
+ }
+
+ if (priv->can.state == CAN_STATE_BUS_OFF) {
+ if (priv->can.restart_ms == 0) {
+ priv->force_quit = 1;
+ can_bus_off(net);
+ mcp251x_hw_sleep(spi);
+ break;
+ }
+ }
+
+ if (intf == 0)
+ break;
+
+ if (intf & CANINTF_TX) {
+ net->stats.tx_packets++;
+ net->stats.tx_bytes += priv->tx_len - 1;
+ can_led_event(net, CAN_LED_EVENT_TX);
+ if (priv->tx_len) {
+ can_get_echo_skb(net, 0);
+ priv->tx_len = 0;
+ }
+ netif_wake_queue(net);
+ }
+
+ }
+ mutex_unlock(&priv->mcp_lock);
+ return IRQ_HANDLED;
+}
+
+static int mcp251x_open(struct net_device *net)
+{
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+ unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_FALLING;
+ int ret;
+
+ ret = open_candev(net);
+ if (ret) {
+ dev_err(&spi->dev, "unable to set initial baudrate!\n");
+ return ret;
+ }
+
+ mutex_lock(&priv->mcp_lock);
+ mcp251x_power_enable(priv->transceiver, 1);
+
+ priv->force_quit = 0;
+ priv->tx_skb = NULL;
+ priv->tx_len = 0;
+
+ ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
+ flags | IRQF_ONESHOT, DEVICE_NAME, priv);
+ if (ret) {
+ dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
+ mcp251x_power_enable(priv->transceiver, 0);
+ close_candev(net);
+ goto open_unlock;
+ }
+
+ priv->wq = create_freezable_workqueue("mcp251x_wq");
+ INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
+ INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);
+
+ ret = mcp251x_hw_reset(spi);
+ if (ret) {
+ mcp251x_open_clean(net);
+ goto open_unlock;
+ }
+ ret = mcp251x_setup(net, priv, spi);
+ if (ret) {
+ mcp251x_open_clean(net);
+ goto open_unlock;
+ }
+ ret = mcp251x_set_normal_mode(spi);
+ if (ret) {
+ mcp251x_open_clean(net);
+ goto open_unlock;
+ }
+
+ can_led_event(net, CAN_LED_EVENT_OPEN);
+
+ netif_wake_queue(net);
+
+open_unlock:
+ mutex_unlock(&priv->mcp_lock);
+ return ret;
+}
+
+static const struct net_device_ops mcp251x_netdev_ops = {
+ .ndo_open = mcp251x_open,
+ .ndo_stop = mcp251x_stop,
+ .ndo_start_xmit = mcp251x_hard_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static const struct of_device_id mcp251x_of_match[] = {
+ {
+ .compatible = "microchip,mcp2510",
+ .data = (void *)CAN_MCP251X_MCP2510,
+ },
+ {
+ .compatible = "microchip,mcp2515",
+ .data = (void *)CAN_MCP251X_MCP2515,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mcp251x_of_match);
+
+static const struct spi_device_id mcp251x_id_table[] = {
+ {
+ .name = "mcp2510",
+ .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2510,
+ },
+ {
+ .name = "mcp2515",
+ .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
+
+static int mcp251x_can_probe(struct spi_device *spi)
+{
+ const struct of_device_id *of_id = of_match_device(mcp251x_of_match,
+ &spi->dev);
+ struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev);
+ struct net_device *net;
+ struct mcp251x_priv *priv;
+ struct clk *clk;
+ int freq, ret;
+
+ clk = devm_clk_get(&spi->dev, NULL);
+ if (IS_ERR(clk)) {
+ if (pdata)
+ freq = pdata->oscillator_frequency;
+ else
+ return PTR_ERR(clk);
+ } else {
+ freq = clk_get_rate(clk);
+ }
+
+ /* Sanity check */
+ if (freq < 1000000 || freq > 25000000)
+ return -ERANGE;
+
+ /* Allocate can/net device */
+ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX);
+ if (!net)
+ return -ENOMEM;
+
+ if (!IS_ERR(clk)) {
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ goto out_free;
+ }
+
+ net->netdev_ops = &mcp251x_netdev_ops;
+ net->flags |= IFF_ECHO;
+
+ priv = netdev_priv(net);
+ priv->can.bittiming_const = &mcp251x_bittiming_const;
+ priv->can.do_set_mode = mcp251x_do_set_mode;
+ priv->can.clock.freq = freq / 2;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
+ if (of_id)
+ priv->model = (enum mcp251x_model)of_id->data;
+ else
+ priv->model = spi_get_device_id(spi)->driver_data;
+ priv->net = net;
+ priv->clk = clk;
+
+ spi_set_drvdata(spi, priv);
+
+ /* Configure the SPI bus */
+ spi->bits_per_word = 8;
+ if (mcp251x_is_2510(spi))
+ spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
+ else
+ spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
+ ret = spi_setup(spi);
+ if (ret)
+ goto out_clk;
+
+ priv->power = devm_regulator_get(&spi->dev, "vdd");
+ priv->transceiver = devm_regulator_get(&spi->dev, "xceiver");
+ if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
+ (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) {
+ ret = -EPROBE_DEFER;
+ goto out_clk;
+ }
+
+ ret = mcp251x_power_enable(priv->power, 1);
+ if (ret)
+ goto out_clk;
+
+ priv->spi = spi;
+ mutex_init(&priv->mcp_lock);
+
+ /* If requested, allocate DMA buffers */
+ if (mcp251x_enable_dma) {
+ spi->dev.coherent_dma_mask = ~0;
+
+ /*
+ * Minimum coherent DMA allocation is PAGE_SIZE, so allocate
+ * that much and share it between Tx and Rx DMA buffers.
+ */
+ priv->spi_tx_buf = dma_alloc_coherent(&spi->dev,
+ PAGE_SIZE,
+ &priv->spi_tx_dma,
+ GFP_DMA);
+
+ if (priv->spi_tx_buf) {
+ priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2));
+ priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma +
+ (PAGE_SIZE / 2));
+ } else {
+ /* Fall back to non-DMA */
+ mcp251x_enable_dma = 0;
+ }
+ }
+
+ /* Allocate non-DMA buffers */
+ if (!mcp251x_enable_dma) {
+ priv->spi_tx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN,
+ GFP_KERNEL);
+ if (!priv->spi_tx_buf) {
+ ret = -ENOMEM;
+ goto error_probe;
+ }
+ priv->spi_rx_buf = devm_kzalloc(&spi->dev, SPI_TRANSFER_BUF_LEN,
+ GFP_KERNEL);
+ if (!priv->spi_rx_buf) {
+ ret = -ENOMEM;
+ goto error_probe;
+ }
+ }
+
+ SET_NETDEV_DEV(net, &spi->dev);
+
+ /* Here is OK to not lock the MCP, no one knows about it yet */
+ ret = mcp251x_hw_probe(spi);
+ if (ret)
+ goto error_probe;
+
+ mcp251x_hw_sleep(spi);
+
+ ret = register_candev(net);
+ if (ret)
+ goto error_probe;
+
+ devm_can_led_init(net);
+
+ return 0;
+
+error_probe:
+ if (mcp251x_enable_dma)
+ dma_free_coherent(&spi->dev, PAGE_SIZE,
+ priv->spi_tx_buf, priv->spi_tx_dma);
+ mcp251x_power_enable(priv->power, 0);
+
+out_clk:
+ if (!IS_ERR(clk))
+ clk_disable_unprepare(clk);
+
+out_free:
+ free_candev(net);
+
+ return ret;
+}
+
+static int mcp251x_can_remove(struct spi_device *spi)
+{
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ struct net_device *net = priv->net;
+
+ unregister_candev(net);
+
+ if (mcp251x_enable_dma) {
+ dma_free_coherent(&spi->dev, PAGE_SIZE,
+ priv->spi_tx_buf, priv->spi_tx_dma);
+ }
+
+ mcp251x_power_enable(priv->power, 0);
+
+ if (!IS_ERR(priv->clk))
+ clk_disable_unprepare(priv->clk);
+
+ free_candev(net);
+
+ return 0;
+}
+
+static int __maybe_unused mcp251x_can_suspend(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ struct net_device *net = priv->net;
+
+ priv->force_quit = 1;
+ disable_irq(spi->irq);
+ /*
+ * Note: at this point neither IST nor workqueues are running.
+ * open/stop cannot be called anyway so locking is not needed
+ */
+ if (netif_running(net)) {
+ netif_device_detach(net);
+
+ mcp251x_hw_sleep(spi);
+ mcp251x_power_enable(priv->transceiver, 0);
+ priv->after_suspend = AFTER_SUSPEND_UP;
+ } else {
+ priv->after_suspend = AFTER_SUSPEND_DOWN;
+ }
+
+ if (!IS_ERR_OR_NULL(priv->power)) {
+ regulator_disable(priv->power);
+ priv->after_suspend |= AFTER_SUSPEND_POWER;
+ }
+
+ return 0;
+}
+
+static int __maybe_unused mcp251x_can_resume(struct device *dev)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct mcp251x_priv *priv = spi_get_drvdata(spi);
+
+ if (priv->after_suspend & AFTER_SUSPEND_POWER) {
+ mcp251x_power_enable(priv->power, 1);
+ queue_work(priv->wq, &priv->restart_work);
+ } else {
+ if (priv->after_suspend & AFTER_SUSPEND_UP) {
+ mcp251x_power_enable(priv->transceiver, 1);
+ queue_work(priv->wq, &priv->restart_work);
+ } else {
+ priv->after_suspend = 0;
+ }
+ }
+ priv->force_quit = 0;
+ enable_irq(spi->irq);
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend,
+ mcp251x_can_resume);
+
+static struct spi_driver mcp251x_can_driver = {
+ .driver = {
+ .name = DEVICE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = mcp251x_of_match,
+ .pm = &mcp251x_can_pm_ops,
+ },
+ .id_table = mcp251x_id_table,
+ .probe = mcp251x_can_probe,
+ .remove = mcp251x_can_remove,
+};
+module_spi_driver(mcp251x_can_driver);
+
+MODULE_AUTHOR("Chris Elston <celston@katalix.com>, "
+ "Christian Pellegrin <chripell@evolware.org>");
+MODULE_DESCRIPTION("Microchip 251x CAN driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
new file mode 100644
index 00000000000..258b9c4856e
--- /dev/null
+++ b/drivers/net/can/ti_hecc.c
@@ -0,0 +1,1055 @@
+/*
+ * TI HECC (CAN) device driver
+ *
+ * This driver supports TI's HECC (High End CAN Controller module) and the
+ * specs for the same is available at <http://www.ti.com>
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed as is WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Your platform definitions should specify module ram offsets and interrupt
+ * number to use as follows:
+ *
+ * static struct ti_hecc_platform_data am3517_evm_hecc_pdata = {
+ * .scc_hecc_offset = 0,
+ * .scc_ram_offset = 0x3000,
+ * .hecc_ram_offset = 0x3000,
+ * .mbx_offset = 0x2000,
+ * .int_line = 0,
+ * .revision = 1,
+ * .transceiver_switch = hecc_phy_control,
+ * };
+ *
+ * Please see include/linux/can/platform/ti_hecc.h for description of
+ * above fields.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+#include <linux/can/platform/ti_hecc.h>
+
+#define DRV_NAME "ti_hecc"
+#define HECC_MODULE_VERSION "0.7"
+MODULE_VERSION(HECC_MODULE_VERSION);
+#define DRV_DESC "TI High End CAN Controller Driver " HECC_MODULE_VERSION
+
+/* TX / RX Mailbox Configuration */
+#define HECC_MAX_MAILBOXES 32 /* hardware mailboxes - do not change */
+#define MAX_TX_PRIO 0x3F /* hardware value - do not change */
+
+/*
+ * Important Note: TX mailbox configuration
+ * TX mailboxes should be restricted to the number of SKB buffers to avoid
+ * maintaining SKB buffers separately. TX mailboxes should be a power of 2
+ * for the mailbox logic to work. Top mailbox numbers are reserved for RX
+ * and lower mailboxes for TX.
+ *
+ * HECC_MAX_TX_MBOX HECC_MB_TX_SHIFT
+ * 4 (default) 2
+ * 8 3
+ * 16 4
+ */
+#define HECC_MB_TX_SHIFT 2 /* as per table above */
+#define HECC_MAX_TX_MBOX BIT(HECC_MB_TX_SHIFT)
+
+#define HECC_TX_PRIO_SHIFT (HECC_MB_TX_SHIFT)
+#define HECC_TX_PRIO_MASK (MAX_TX_PRIO << HECC_MB_TX_SHIFT)
+#define HECC_TX_MB_MASK (HECC_MAX_TX_MBOX - 1)
+#define HECC_TX_MASK ((HECC_MAX_TX_MBOX - 1) | HECC_TX_PRIO_MASK)
+#define HECC_TX_MBOX_MASK (~(BIT(HECC_MAX_TX_MBOX) - 1))
+#define HECC_DEF_NAPI_WEIGHT HECC_MAX_RX_MBOX
+
+/*
+ * Important Note: RX mailbox configuration
+ * RX mailboxes are further logically split into two - main and buffer
+ * mailboxes. The goal is to get all packets into main mailboxes as
+ * driven by mailbox number and receive priority (higher to lower) and
+ * buffer mailboxes are used to receive pkts while main mailboxes are being
+ * processed. This ensures in-order packet reception.
+ *
+ * Here are the recommended values for buffer mailbox. Note that RX mailboxes
+ * start after TX mailboxes:
+ *
+ * HECC_MAX_RX_MBOX HECC_RX_BUFFER_MBOX No of buffer mailboxes
+ * 28 12 8
+ * 16 20 4
+ */
+
+#define HECC_MAX_RX_MBOX (HECC_MAX_MAILBOXES - HECC_MAX_TX_MBOX)
+#define HECC_RX_BUFFER_MBOX 12 /* as per table above */
+#define HECC_RX_FIRST_MBOX (HECC_MAX_MAILBOXES - 1)
+#define HECC_RX_HIGH_MBOX_MASK (~(BIT(HECC_RX_BUFFER_MBOX) - 1))
+
+/* TI HECC module registers */
+#define HECC_CANME 0x0 /* Mailbox enable */
+#define HECC_CANMD 0x4 /* Mailbox direction */
+#define HECC_CANTRS 0x8 /* Transmit request set */
+#define HECC_CANTRR 0xC /* Transmit request */
+#define HECC_CANTA 0x10 /* Transmission acknowledge */
+#define HECC_CANAA 0x14 /* Abort acknowledge */
+#define HECC_CANRMP 0x18 /* Receive message pending */
+#define HECC_CANRML 0x1C /* Remote message lost */
+#define HECC_CANRFP 0x20 /* Remote frame pending */
+#define HECC_CANGAM 0x24 /* SECC only:Global acceptance mask */
+#define HECC_CANMC 0x28 /* Master control */
+#define HECC_CANBTC 0x2C /* Bit timing configuration */
+#define HECC_CANES 0x30 /* Error and status */
+#define HECC_CANTEC 0x34 /* Transmit error counter */
+#define HECC_CANREC 0x38 /* Receive error counter */
+#define HECC_CANGIF0 0x3C /* Global interrupt flag 0 */
+#define HECC_CANGIM 0x40 /* Global interrupt mask */
+#define HECC_CANGIF1 0x44 /* Global interrupt flag 1 */
+#define HECC_CANMIM 0x48 /* Mailbox interrupt mask */
+#define HECC_CANMIL 0x4C /* Mailbox interrupt level */
+#define HECC_CANOPC 0x50 /* Overwrite protection control */
+#define HECC_CANTIOC 0x54 /* Transmit I/O control */
+#define HECC_CANRIOC 0x58 /* Receive I/O control */
+#define HECC_CANLNT 0x5C /* HECC only: Local network time */
+#define HECC_CANTOC 0x60 /* HECC only: Time-out control */
+#define HECC_CANTOS 0x64 /* HECC only: Time-out status */
+#define HECC_CANTIOCE 0x68 /* SCC only:Enhanced TX I/O control */
+#define HECC_CANRIOCE 0x6C /* SCC only:Enhanced RX I/O control */
+
+/* Mailbox registers */
+#define HECC_CANMID 0x0
+#define HECC_CANMCF 0x4
+#define HECC_CANMDL 0x8
+#define HECC_CANMDH 0xC
+
+#define HECC_SET_REG 0xFFFFFFFF
+#define HECC_CANID_MASK 0x3FF /* 18 bits mask for extended id's */
+#define HECC_CCE_WAIT_COUNT 100 /* Wait for ~1 sec for CCE bit */
+
+#define HECC_CANMC_SCM BIT(13) /* SCC compat mode */
+#define HECC_CANMC_CCR BIT(12) /* Change config request */
+#define HECC_CANMC_PDR BIT(11) /* Local Power down - for sleep mode */
+#define HECC_CANMC_ABO BIT(7) /* Auto Bus On */
+#define HECC_CANMC_STM BIT(6) /* Self test mode - loopback */
+#define HECC_CANMC_SRES BIT(5) /* Software reset */
+
+#define HECC_CANTIOC_EN BIT(3) /* Enable CAN TX I/O pin */
+#define HECC_CANRIOC_EN BIT(3) /* Enable CAN RX I/O pin */
+
+#define HECC_CANMID_IDE BIT(31) /* Extended frame format */
+#define HECC_CANMID_AME BIT(30) /* Acceptance mask enable */
+#define HECC_CANMID_AAM BIT(29) /* Auto answer mode */
+
+#define HECC_CANES_FE BIT(24) /* form error */
+#define HECC_CANES_BE BIT(23) /* bit error */
+#define HECC_CANES_SA1 BIT(22) /* stuck at dominant error */
+#define HECC_CANES_CRCE BIT(21) /* CRC error */
+#define HECC_CANES_SE BIT(20) /* stuff bit error */
+#define HECC_CANES_ACKE BIT(19) /* ack error */
+#define HECC_CANES_BO BIT(18) /* Bus off status */
+#define HECC_CANES_EP BIT(17) /* Error passive status */
+#define HECC_CANES_EW BIT(16) /* Error warning status */
+#define HECC_CANES_SMA BIT(5) /* suspend mode ack */
+#define HECC_CANES_CCE BIT(4) /* Change config enabled */
+#define HECC_CANES_PDA BIT(3) /* Power down mode ack */
+
+#define HECC_CANBTC_SAM BIT(7) /* sample points */
+
+#define HECC_BUS_ERROR (HECC_CANES_FE | HECC_CANES_BE |\
+ HECC_CANES_CRCE | HECC_CANES_SE |\
+ HECC_CANES_ACKE)
+
+#define HECC_CANMCF_RTR BIT(4) /* Remote transmit request */
+
+#define HECC_CANGIF_MAIF BIT(17) /* Message alarm interrupt */
+#define HECC_CANGIF_TCOIF BIT(16) /* Timer counter overflow int */
+#define HECC_CANGIF_GMIF BIT(15) /* Global mailbox interrupt */
+#define HECC_CANGIF_AAIF BIT(14) /* Abort ack interrupt */
+#define HECC_CANGIF_WDIF BIT(13) /* Write denied interrupt */
+#define HECC_CANGIF_WUIF BIT(12) /* Wake up interrupt */
+#define HECC_CANGIF_RMLIF BIT(11) /* Receive message lost interrupt */
+#define HECC_CANGIF_BOIF BIT(10) /* Bus off interrupt */
+#define HECC_CANGIF_EPIF BIT(9) /* Error passive interrupt */
+#define HECC_CANGIF_WLIF BIT(8) /* Warning level interrupt */
+#define HECC_CANGIF_MBOX_MASK 0x1F /* Mailbox number mask */
+#define HECC_CANGIM_I1EN BIT(1) /* Int line 1 enable */
+#define HECC_CANGIM_I0EN BIT(0) /* Int line 0 enable */
+#define HECC_CANGIM_DEF_MASK 0x700 /* only busoff/warning/passive */
+#define HECC_CANGIM_SIL BIT(2) /* system interrupts to int line 1 */
+
+/* CAN Bittiming constants as per HECC specs */
+static const struct can_bittiming_const ti_hecc_bittiming_const = {
+ .name = DRV_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 256,
+ .brp_inc = 1,
+};
+
+struct ti_hecc_priv {
+ struct can_priv can; /* MUST be first member/field */
+ struct napi_struct napi;
+ struct net_device *ndev;
+ struct clk *clk;
+ void __iomem *base;
+ u32 scc_ram_offset;
+ u32 hecc_ram_offset;
+ u32 mbx_offset;
+ u32 int_line;
+ spinlock_t mbx_lock; /* CANME register needs protection */
+ u32 tx_head;
+ u32 tx_tail;
+ u32 rx_next;
+ void (*transceiver_switch)(int);
+};
+
+static inline int get_tx_head_mb(struct ti_hecc_priv *priv)
+{
+ return priv->tx_head & HECC_TX_MB_MASK;
+}
+
+static inline int get_tx_tail_mb(struct ti_hecc_priv *priv)
+{
+ return priv->tx_tail & HECC_TX_MB_MASK;
+}
+
+static inline int get_tx_head_prio(struct ti_hecc_priv *priv)
+{
+ return (priv->tx_head >> HECC_TX_PRIO_SHIFT) & MAX_TX_PRIO;
+}
+
+static inline void hecc_write_lam(struct ti_hecc_priv *priv, u32 mbxno, u32 val)
+{
+ __raw_writel(val, priv->base + priv->hecc_ram_offset + mbxno * 4);
+}
+
+static inline void hecc_write_mbx(struct ti_hecc_priv *priv, u32 mbxno,
+ u32 reg, u32 val)
+{
+ __raw_writel(val, priv->base + priv->mbx_offset + mbxno * 0x10 +
+ reg);
+}
+
+static inline u32 hecc_read_mbx(struct ti_hecc_priv *priv, u32 mbxno, u32 reg)
+{
+ return __raw_readl(priv->base + priv->mbx_offset + mbxno * 0x10 +
+ reg);
+}
+
+static inline void hecc_write(struct ti_hecc_priv *priv, u32 reg, u32 val)
+{
+ __raw_writel(val, priv->base + reg);
+}
+
+static inline u32 hecc_read(struct ti_hecc_priv *priv, int reg)
+{
+ return __raw_readl(priv->base + reg);
+}
+
+static inline void hecc_set_bit(struct ti_hecc_priv *priv, int reg,
+ u32 bit_mask)
+{
+ hecc_write(priv, reg, hecc_read(priv, reg) | bit_mask);
+}
+
+static inline void hecc_clear_bit(struct ti_hecc_priv *priv, int reg,
+ u32 bit_mask)
+{
+ hecc_write(priv, reg, hecc_read(priv, reg) & ~bit_mask);
+}
+
+static inline u32 hecc_get_bit(struct ti_hecc_priv *priv, int reg, u32 bit_mask)
+{
+ return (hecc_read(priv, reg) & bit_mask) ? 1 : 0;
+}
+
+static int ti_hecc_set_btc(struct ti_hecc_priv *priv)
+{
+ struct can_bittiming *bit_timing = &priv->can.bittiming;
+ u32 can_btc;
+
+ can_btc = (bit_timing->phase_seg2 - 1) & 0x7;
+ can_btc |= ((bit_timing->phase_seg1 + bit_timing->prop_seg - 1)
+ & 0xF) << 3;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) {
+ if (bit_timing->brp > 4)
+ can_btc |= HECC_CANBTC_SAM;
+ else
+ netdev_warn(priv->ndev, "WARN: Triple"
+ "sampling not set due to h/w limitations");
+ }
+ can_btc |= ((bit_timing->sjw - 1) & 0x3) << 8;
+ can_btc |= ((bit_timing->brp - 1) & 0xFF) << 16;
+
+ /* ERM being set to 0 by default meaning resync at falling edge */
+
+ hecc_write(priv, HECC_CANBTC, can_btc);
+ netdev_info(priv->ndev, "setting CANBTC=%#x\n", can_btc);
+
+ return 0;
+}
+
+static void ti_hecc_transceiver_switch(const struct ti_hecc_priv *priv,
+ int on)
+{
+ if (priv->transceiver_switch)
+ priv->transceiver_switch(on);
+}
+
+static void ti_hecc_reset(struct net_device *ndev)
+{
+ u32 cnt;
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+ netdev_dbg(ndev, "resetting hecc ...\n");
+ hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_SRES);
+
+ /* Set change control request and wait till enabled */
+ hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+
+ /*
+ * INFO: It has been observed that at times CCE bit may not be
+ * set and hw seems to be ok even if this bit is not set so
+ * timing out with a timing of 1ms to respect the specs
+ */
+ cnt = HECC_CCE_WAIT_COUNT;
+ while (!hecc_get_bit(priv, HECC_CANES, HECC_CANES_CCE) && cnt != 0) {
+ --cnt;
+ udelay(10);
+ }
+
+ /*
+ * Note: On HECC, BTC can be programmed only in initialization mode, so
+ * it is expected that the can bittiming parameters are set via ip
+ * utility before the device is opened
+ */
+ ti_hecc_set_btc(priv);
+
+ /* Clear CCR (and CANMC register) and wait for CCE = 0 enable */
+ hecc_write(priv, HECC_CANMC, 0);
+
+ /*
+ * INFO: CAN net stack handles bus off and hence disabling auto-bus-on
+ * hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_ABO);
+ */
+
+ /*
+ * INFO: It has been observed that at times CCE bit may not be
+ * set and hw seems to be ok even if this bit is not set so
+ */
+ cnt = HECC_CCE_WAIT_COUNT;
+ while (hecc_get_bit(priv, HECC_CANES, HECC_CANES_CCE) && cnt != 0) {
+ --cnt;
+ udelay(10);
+ }
+
+ /* Enable TX and RX I/O Control pins */
+ hecc_write(priv, HECC_CANTIOC, HECC_CANTIOC_EN);
+ hecc_write(priv, HECC_CANRIOC, HECC_CANRIOC_EN);
+
+ /* Clear registers for clean operation */
+ hecc_write(priv, HECC_CANTA, HECC_SET_REG);
+ hecc_write(priv, HECC_CANRMP, HECC_SET_REG);
+ hecc_write(priv, HECC_CANGIF0, HECC_SET_REG);
+ hecc_write(priv, HECC_CANGIF1, HECC_SET_REG);
+ hecc_write(priv, HECC_CANME, 0);
+ hecc_write(priv, HECC_CANMD, 0);
+
+ /* SCC compat mode NOT supported (and not needed too) */
+ hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_SCM);
+}
+
+static void ti_hecc_start(struct net_device *ndev)
+{
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+ u32 cnt, mbxno, mbx_mask;
+
+ /* put HECC in initialization mode and set btc */
+ ti_hecc_reset(ndev);
+
+ priv->tx_head = priv->tx_tail = HECC_TX_MASK;
+ priv->rx_next = HECC_RX_FIRST_MBOX;
+
+ /* Enable local and global acceptance mask registers */
+ hecc_write(priv, HECC_CANGAM, HECC_SET_REG);
+
+ /* Prepare configured mailboxes to receive messages */
+ for (cnt = 0; cnt < HECC_MAX_RX_MBOX; cnt++) {
+ mbxno = HECC_MAX_MAILBOXES - 1 - cnt;
+ mbx_mask = BIT(mbxno);
+ hecc_clear_bit(priv, HECC_CANME, mbx_mask);
+ hecc_write_mbx(priv, mbxno, HECC_CANMID, HECC_CANMID_AME);
+ hecc_write_lam(priv, mbxno, HECC_SET_REG);
+ hecc_set_bit(priv, HECC_CANMD, mbx_mask);
+ hecc_set_bit(priv, HECC_CANME, mbx_mask);
+ hecc_set_bit(priv, HECC_CANMIM, mbx_mask);
+ }
+
+ /* Prevent message over-write & Enable interrupts */
+ hecc_write(priv, HECC_CANOPC, HECC_SET_REG);
+ if (priv->int_line) {
+ hecc_write(priv, HECC_CANMIL, HECC_SET_REG);
+ hecc_write(priv, HECC_CANGIM, HECC_CANGIM_DEF_MASK |
+ HECC_CANGIM_I1EN | HECC_CANGIM_SIL);
+ } else {
+ hecc_write(priv, HECC_CANMIL, 0);
+ hecc_write(priv, HECC_CANGIM,
+ HECC_CANGIM_DEF_MASK | HECC_CANGIM_I0EN);
+ }
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+}
+
+static void ti_hecc_stop(struct net_device *ndev)
+{
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+ /* Disable interrupts and disable mailboxes */
+ hecc_write(priv, HECC_CANGIM, 0);
+ hecc_write(priv, HECC_CANMIM, 0);
+ hecc_write(priv, HECC_CANME, 0);
+ priv->can.state = CAN_STATE_STOPPED;
+}
+
+static int ti_hecc_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ int ret = 0;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ ti_hecc_start(ndev);
+ netif_wake_queue(ndev);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
+static int ti_hecc_get_berr_counter(const struct net_device *ndev,
+ struct can_berr_counter *bec)
+{
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+ bec->txerr = hecc_read(priv, HECC_CANTEC);
+ bec->rxerr = hecc_read(priv, HECC_CANREC);
+
+ return 0;
+}
+
+/*
+ * ti_hecc_xmit: HECC Transmit
+ *
+ * The transmit mailboxes start from 0 to HECC_MAX_TX_MBOX. In HECC the
+ * priority of the mailbox for tranmission is dependent upon priority setting
+ * field in mailbox registers. The mailbox with highest value in priority field
+ * is transmitted first. Only when two mailboxes have the same value in
+ * priority field the highest numbered mailbox is transmitted first.
+ *
+ * To utilize the HECC priority feature as described above we start with the
+ * highest numbered mailbox with highest priority level and move on to the next
+ * mailbox with the same priority level and so on. Once we loop through all the
+ * transmit mailboxes we choose the next priority level (lower) and so on
+ * until we reach the lowest priority level on the lowest numbered mailbox
+ * when we stop transmission until all mailboxes are transmitted and then
+ * restart at highest numbered mailbox with highest priority.
+ *
+ * Two counters (head and tail) are used to track the next mailbox to transmit
+ * and to track the echo buffer for already transmitted mailbox. The queue
+ * is stopped when all the mailboxes are busy or when there is a priority
+ * value roll-over happens.
+ */
+static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 mbxno, mbx_mask, data;
+ unsigned long flags;
+
+ if (can_dropped_invalid_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ mbxno = get_tx_head_mb(priv);
+ mbx_mask = BIT(mbxno);
+ spin_lock_irqsave(&priv->mbx_lock, flags);
+ if (unlikely(hecc_read(priv, HECC_CANME) & mbx_mask)) {
+ spin_unlock_irqrestore(&priv->mbx_lock, flags);
+ netif_stop_queue(ndev);
+ netdev_err(priv->ndev,
+ "BUG: TX mbx not ready tx_head=%08X, tx_tail=%08X\n",
+ priv->tx_head, priv->tx_tail);
+ return NETDEV_TX_BUSY;
+ }
+ spin_unlock_irqrestore(&priv->mbx_lock, flags);
+
+ /* Prepare mailbox for transmission */
+ data = cf->can_dlc | (get_tx_head_prio(priv) << 8);
+ if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
+ data |= HECC_CANMCF_RTR;
+ hecc_write_mbx(priv, mbxno, HECC_CANMCF, data);
+
+ if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */
+ data = (cf->can_id & CAN_EFF_MASK) | HECC_CANMID_IDE;
+ else /* Standard frame format */
+ data = (cf->can_id & CAN_SFF_MASK) << 18;
+ hecc_write_mbx(priv, mbxno, HECC_CANMID, data);
+ hecc_write_mbx(priv, mbxno, HECC_CANMDL,
+ be32_to_cpu(*(__be32 *)(cf->data)));
+ if (cf->can_dlc > 4)
+ hecc_write_mbx(priv, mbxno, HECC_CANMDH,
+ be32_to_cpu(*(__be32 *)(cf->data + 4)));
+ else
+ *(u32 *)(cf->data + 4) = 0;
+ can_put_echo_skb(skb, ndev, mbxno);
+
+ spin_lock_irqsave(&priv->mbx_lock, flags);
+ --priv->tx_head;
+ if ((hecc_read(priv, HECC_CANME) & BIT(get_tx_head_mb(priv))) ||
+ (priv->tx_head & HECC_TX_MASK) == HECC_TX_MASK) {
+ netif_stop_queue(ndev);
+ }
+ hecc_set_bit(priv, HECC_CANME, mbx_mask);
+ spin_unlock_irqrestore(&priv->mbx_lock, flags);
+
+ hecc_clear_bit(priv, HECC_CANMD, mbx_mask);
+ hecc_set_bit(priv, HECC_CANMIM, mbx_mask);
+ hecc_write(priv, HECC_CANTRS, mbx_mask);
+
+ return NETDEV_TX_OK;
+}
+
+static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno)
+{
+ struct net_device_stats *stats = &priv->ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 data, mbx_mask;
+ unsigned long flags;
+
+ skb = alloc_can_skb(priv->ndev, &cf);
+ if (!skb) {
+ if (printk_ratelimit())
+ netdev_err(priv->ndev,
+ "ti_hecc_rx_pkt: alloc_can_skb() failed\n");
+ return -ENOMEM;
+ }
+
+ mbx_mask = BIT(mbxno);
+ data = hecc_read_mbx(priv, mbxno, HECC_CANMID);
+ if (data & HECC_CANMID_IDE)
+ cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ else
+ cf->can_id = (data >> 18) & CAN_SFF_MASK;
+ data = hecc_read_mbx(priv, mbxno, HECC_CANMCF);
+ if (data & HECC_CANMCF_RTR)
+ cf->can_id |= CAN_RTR_FLAG;
+ cf->can_dlc = get_can_dlc(data & 0xF);
+ data = hecc_read_mbx(priv, mbxno, HECC_CANMDL);
+ *(__be32 *)(cf->data) = cpu_to_be32(data);
+ if (cf->can_dlc > 4) {
+ data = hecc_read_mbx(priv, mbxno, HECC_CANMDH);
+ *(__be32 *)(cf->data + 4) = cpu_to_be32(data);
+ }
+ spin_lock_irqsave(&priv->mbx_lock, flags);
+ hecc_clear_bit(priv, HECC_CANME, mbx_mask);
+ hecc_write(priv, HECC_CANRMP, mbx_mask);
+ /* enable mailbox only if it is part of rx buffer mailboxes */
+ if (priv->rx_next < HECC_RX_BUFFER_MBOX)
+ hecc_set_bit(priv, HECC_CANME, mbx_mask);
+ spin_unlock_irqrestore(&priv->mbx_lock, flags);
+
+ stats->rx_bytes += cf->can_dlc;
+ can_led_event(priv->ndev, CAN_LED_EVENT_RX);
+ netif_receive_skb(skb);
+ stats->rx_packets++;
+
+ return 0;
+}
+
+/*
+ * ti_hecc_rx_poll - HECC receive pkts
+ *
+ * The receive mailboxes start from highest numbered mailbox till last xmit
+ * mailbox. On CAN frame reception the hardware places the data into highest
+ * numbered mailbox that matches the CAN ID filter. Since all receive mailboxes
+ * have same filtering (ALL CAN frames) packets will arrive in the highest
+ * available RX mailbox and we need to ensure in-order packet reception.
+ *
+ * To ensure the packets are received in the right order we logically divide
+ * the RX mailboxes into main and buffer mailboxes. Packets are received as per
+ * mailbox priotity (higher to lower) in the main bank and once it is full we
+ * disable further reception into main mailboxes. While the main mailboxes are
+ * processed in NAPI, further packets are received in buffer mailboxes.
+ *
+ * We maintain a RX next mailbox counter to process packets and once all main
+ * mailboxe packets are passed to the upper stack we enable all of them but
+ * continue to process packets received in buffer mailboxes. With each packet
+ * received from buffer mailbox we enable it immediately so as to handle the
+ * overflow from higher mailboxes.
+ */
+static int ti_hecc_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *ndev = napi->dev;
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+ u32 num_pkts = 0;
+ u32 mbx_mask;
+ unsigned long pending_pkts, flags;
+
+ if (!netif_running(ndev))
+ return 0;
+
+ while ((pending_pkts = hecc_read(priv, HECC_CANRMP)) &&
+ num_pkts < quota) {
+ mbx_mask = BIT(priv->rx_next); /* next rx mailbox to process */
+ if (mbx_mask & pending_pkts) {
+ if (ti_hecc_rx_pkt(priv, priv->rx_next) < 0)
+ return num_pkts;
+ ++num_pkts;
+ } else if (priv->rx_next > HECC_RX_BUFFER_MBOX) {
+ break; /* pkt not received yet */
+ }
+ --priv->rx_next;
+ if (priv->rx_next == HECC_RX_BUFFER_MBOX) {
+ /* enable high bank mailboxes */
+ spin_lock_irqsave(&priv->mbx_lock, flags);
+ mbx_mask = hecc_read(priv, HECC_CANME);
+ mbx_mask |= HECC_RX_HIGH_MBOX_MASK;
+ hecc_write(priv, HECC_CANME, mbx_mask);
+ spin_unlock_irqrestore(&priv->mbx_lock, flags);
+ } else if (priv->rx_next == HECC_MAX_TX_MBOX - 1) {
+ priv->rx_next = HECC_RX_FIRST_MBOX;
+ break;
+ }
+ }
+
+ /* Enable packet interrupt if all pkts are handled */
+ if (hecc_read(priv, HECC_CANRMP) == 0) {
+ napi_complete(napi);
+ /* Re-enable RX mailbox interrupts */
+ mbx_mask = hecc_read(priv, HECC_CANMIM);
+ mbx_mask |= HECC_TX_MBOX_MASK;
+ hecc_write(priv, HECC_CANMIM, mbx_mask);
+ }
+
+ return num_pkts;
+}
+
+static int ti_hecc_error(struct net_device *ndev, int int_status,
+ int err_status)
+{
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+
+ /* propagate the error condition to the can stack */
+ skb = alloc_can_err_skb(ndev, &cf);
+ if (!skb) {
+ if (printk_ratelimit())
+ netdev_err(priv->ndev,
+ "ti_hecc_error: alloc_can_err_skb() failed\n");
+ return -ENOMEM;
+ }
+
+ if (int_status & HECC_CANGIF_WLIF) { /* warning level int */
+ if ((int_status & HECC_CANGIF_BOIF) == 0) {
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ ++priv->can.can_stats.error_warning;
+ cf->can_id |= CAN_ERR_CRTL;
+ if (hecc_read(priv, HECC_CANTEC) > 96)
+ cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+ if (hecc_read(priv, HECC_CANREC) > 96)
+ cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+ }
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_EW);
+ netdev_dbg(priv->ndev, "Error Warning interrupt\n");
+ hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+ }
+
+ if (int_status & HECC_CANGIF_EPIF) { /* error passive int */
+ if ((int_status & HECC_CANGIF_BOIF) == 0) {
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ ++priv->can.can_stats.error_passive;
+ cf->can_id |= CAN_ERR_CRTL;
+ if (hecc_read(priv, HECC_CANTEC) > 127)
+ cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+ if (hecc_read(priv, HECC_CANREC) > 127)
+ cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_EP);
+ netdev_dbg(priv->ndev, "Error passive interrupt\n");
+ hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+ }
+
+ /*
+ * Need to check busoff condition in error status register too to
+ * ensure warning interrupts don't hog the system
+ */
+ if ((int_status & HECC_CANGIF_BOIF) || (err_status & HECC_CANES_BO)) {
+ priv->can.state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_BO);
+ hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
+ /* Disable all interrupts in bus-off to avoid int hog */
+ hecc_write(priv, HECC_CANGIM, 0);
+ can_bus_off(ndev);
+ }
+
+ if (err_status & HECC_BUS_ERROR) {
+ ++priv->can.can_stats.bus_error;
+ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ if (err_status & HECC_CANES_FE) {
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_FE);
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ }
+ if (err_status & HECC_CANES_BE) {
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_BE);
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ }
+ if (err_status & HECC_CANES_SE) {
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_SE);
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ }
+ if (err_status & HECC_CANES_CRCE) {
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE);
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL;
+ }
+ if (err_status & HECC_CANES_ACKE) {
+ hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE);
+ cf->data[3] |= CAN_ERR_PROT_LOC_ACK |
+ CAN_ERR_PROT_LOC_ACK_DEL;
+ }
+ }
+
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ return 0;
+}
+
+static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
+{
+ struct net_device *ndev = (struct net_device *)dev_id;
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ u32 mbxno, mbx_mask, int_status, err_status;
+ unsigned long ack, flags;
+
+ int_status = hecc_read(priv,
+ (priv->int_line) ? HECC_CANGIF1 : HECC_CANGIF0);
+
+ if (!int_status)
+ return IRQ_NONE;
+
+ err_status = hecc_read(priv, HECC_CANES);
+ if (err_status & (HECC_BUS_ERROR | HECC_CANES_BO |
+ HECC_CANES_EP | HECC_CANES_EW))
+ ti_hecc_error(ndev, int_status, err_status);
+
+ if (int_status & HECC_CANGIF_GMIF) {
+ while (priv->tx_tail - priv->tx_head > 0) {
+ mbxno = get_tx_tail_mb(priv);
+ mbx_mask = BIT(mbxno);
+ if (!(mbx_mask & hecc_read(priv, HECC_CANTA)))
+ break;
+ hecc_clear_bit(priv, HECC_CANMIM, mbx_mask);
+ hecc_write(priv, HECC_CANTA, mbx_mask);
+ spin_lock_irqsave(&priv->mbx_lock, flags);
+ hecc_clear_bit(priv, HECC_CANME, mbx_mask);
+ spin_unlock_irqrestore(&priv->mbx_lock, flags);
+ stats->tx_bytes += hecc_read_mbx(priv, mbxno,
+ HECC_CANMCF) & 0xF;
+ stats->tx_packets++;
+ can_led_event(ndev, CAN_LED_EVENT_TX);
+ can_get_echo_skb(ndev, mbxno);
+ --priv->tx_tail;
+ }
+
+ /* restart queue if wrap-up or if queue stalled on last pkt */
+ if (((priv->tx_head == priv->tx_tail) &&
+ ((priv->tx_head & HECC_TX_MASK) != HECC_TX_MASK)) ||
+ (((priv->tx_tail & HECC_TX_MASK) == HECC_TX_MASK) &&
+ ((priv->tx_head & HECC_TX_MASK) == HECC_TX_MASK)))
+ netif_wake_queue(ndev);
+
+ /* Disable RX mailbox interrupts and let NAPI reenable them */
+ if (hecc_read(priv, HECC_CANRMP)) {
+ ack = hecc_read(priv, HECC_CANMIM);
+ ack &= BIT(HECC_MAX_TX_MBOX) - 1;
+ hecc_write(priv, HECC_CANMIM, ack);
+ napi_schedule(&priv->napi);
+ }
+ }
+
+ /* clear all interrupt conditions - read back to avoid spurious ints */
+ if (priv->int_line) {
+ hecc_write(priv, HECC_CANGIF1, HECC_SET_REG);
+ int_status = hecc_read(priv, HECC_CANGIF1);
+ } else {
+ hecc_write(priv, HECC_CANGIF0, HECC_SET_REG);
+ int_status = hecc_read(priv, HECC_CANGIF0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ti_hecc_open(struct net_device *ndev)
+{
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+ int err;
+
+ err = request_irq(ndev->irq, ti_hecc_interrupt, IRQF_SHARED,
+ ndev->name, ndev);
+ if (err) {
+ netdev_err(ndev, "error requesting interrupt\n");
+ return err;
+ }
+
+ ti_hecc_transceiver_switch(priv, 1);
+
+ /* Open common can device */
+ err = open_candev(ndev);
+ if (err) {
+ netdev_err(ndev, "open_candev() failed %d\n", err);
+ ti_hecc_transceiver_switch(priv, 0);
+ free_irq(ndev->irq, ndev);
+ return err;
+ }
+
+ can_led_event(ndev, CAN_LED_EVENT_OPEN);
+
+ ti_hecc_start(ndev);
+ napi_enable(&priv->napi);
+ netif_start_queue(ndev);
+
+ return 0;
+}
+
+static int ti_hecc_close(struct net_device *ndev)
+{
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+ ti_hecc_stop(ndev);
+ free_irq(ndev->irq, ndev);
+ close_candev(ndev);
+ ti_hecc_transceiver_switch(priv, 0);
+
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
+
+ return 0;
+}
+
+static const struct net_device_ops ti_hecc_netdev_ops = {
+ .ndo_open = ti_hecc_open,
+ .ndo_stop = ti_hecc_close,
+ .ndo_start_xmit = ti_hecc_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static int ti_hecc_probe(struct platform_device *pdev)
+{
+ struct net_device *ndev = (struct net_device *)0;
+ struct ti_hecc_priv *priv;
+ struct ti_hecc_platform_data *pdata;
+ struct resource *mem, *irq;
+ void __iomem *addr;
+ int err = -ENODEV;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data\n");
+ goto probe_exit;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "No mem resources\n");
+ goto probe_exit;
+ }
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq) {
+ dev_err(&pdev->dev, "No irq resource\n");
+ goto probe_exit;
+ }
+ if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
+ dev_err(&pdev->dev, "HECC region already claimed\n");
+ err = -EBUSY;
+ goto probe_exit;
+ }
+ addr = ioremap(mem->start, resource_size(mem));
+ if (!addr) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ err = -ENOMEM;
+ goto probe_exit_free_region;
+ }
+
+ ndev = alloc_candev(sizeof(struct ti_hecc_priv), HECC_MAX_TX_MBOX);
+ if (!ndev) {
+ dev_err(&pdev->dev, "alloc_candev failed\n");
+ err = -ENOMEM;
+ goto probe_exit_iounmap;
+ }
+
+ priv = netdev_priv(ndev);
+ priv->ndev = ndev;
+ priv->base = addr;
+ priv->scc_ram_offset = pdata->scc_ram_offset;
+ priv->hecc_ram_offset = pdata->hecc_ram_offset;
+ priv->mbx_offset = pdata->mbx_offset;
+ priv->int_line = pdata->int_line;
+ priv->transceiver_switch = pdata->transceiver_switch;
+
+ priv->can.bittiming_const = &ti_hecc_bittiming_const;
+ priv->can.do_set_mode = ti_hecc_do_set_mode;
+ priv->can.do_get_berr_counter = ti_hecc_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+
+ spin_lock_init(&priv->mbx_lock);
+ ndev->irq = irq->start;
+ ndev->flags |= IFF_ECHO;
+ platform_set_drvdata(pdev, ndev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ ndev->netdev_ops = &ti_hecc_netdev_ops;
+
+ priv->clk = clk_get(&pdev->dev, "hecc_ck");
+ if (IS_ERR(priv->clk)) {
+ dev_err(&pdev->dev, "No clock available\n");
+ err = PTR_ERR(priv->clk);
+ priv->clk = NULL;
+ goto probe_exit_candev;
+ }
+ priv->can.clock.freq = clk_get_rate(priv->clk);
+ netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
+ HECC_DEF_NAPI_WEIGHT);
+
+ clk_enable(priv->clk);
+ err = register_candev(ndev);
+ if (err) {
+ dev_err(&pdev->dev, "register_candev() failed\n");
+ goto probe_exit_clk;
+ }
+
+ devm_can_led_init(ndev);
+
+ dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n",
+ priv->base, (u32) ndev->irq);
+
+ return 0;
+
+probe_exit_clk:
+ clk_put(priv->clk);
+probe_exit_candev:
+ free_candev(ndev);
+probe_exit_iounmap:
+ iounmap(addr);
+probe_exit_free_region:
+ release_mem_region(mem->start, resource_size(mem));
+probe_exit:
+ return err;
+}
+
+static int ti_hecc_remove(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+ unregister_candev(ndev);
+ clk_disable(priv->clk);
+ clk_put(priv->clk);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ iounmap(priv->base);
+ release_mem_region(res->start, resource_size(res));
+ free_candev(ndev);
+
+ return 0;
+}
+
+
+#ifdef CONFIG_PM
+static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct ti_hecc_priv *priv = netdev_priv(dev);
+
+ if (netif_running(dev)) {
+ netif_stop_queue(dev);
+ netif_device_detach(dev);
+ }
+
+ hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ clk_disable(priv->clk);
+
+ return 0;
+}
+
+static int ti_hecc_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct ti_hecc_priv *priv = netdev_priv(dev);
+
+ clk_enable(priv->clk);
+
+ hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_running(dev)) {
+ netif_device_attach(dev);
+ netif_start_queue(dev);
+ }
+
+ return 0;
+}
+#else
+#define ti_hecc_suspend NULL
+#define ti_hecc_resume NULL
+#endif
+
+/* TI HECC netdevice driver: platform driver structure */
+static struct platform_driver ti_hecc_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ti_hecc_probe,
+ .remove = ti_hecc_remove,
+ .suspend = ti_hecc_suspend,
+ .resume = ti_hecc_resume,
+};
+
+module_platform_driver(ti_hecc_driver);
+
+MODULE_AUTHOR("Anant Gole <anantgole@ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig
new file mode 100644
index 00000000000..a77db919363
--- /dev/null
+++ b/drivers/net/can/usb/Kconfig
@@ -0,0 +1,67 @@
+menu "CAN USB interfaces"
+ depends on USB
+
+config CAN_EMS_USB
+ tristate "EMS CPC-USB/ARM7 CAN/USB interface"
+ ---help---
+ This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
+ from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+
+config CAN_ESD_USB2
+ tristate "ESD USB/2 CAN/USB interface"
+ ---help---
+ This driver supports the CAN-USB/2 interface
+ from esd electronic system design gmbh (http://www.esd.eu).
+
+config CAN_GS_USB
+ tristate "Geschwister Schneider UG interfaces"
+ ---help---
+ This driver supports the Geschwister Schneider USB/CAN devices.
+ If unsure choose N,
+ choose Y for built in support,
+ M to compile as module (module will be named: gs_usb).
+
+config CAN_KVASER_USB
+ tristate "Kvaser CAN/USB interface"
+ ---help---
+ This driver adds support for Kvaser CAN/USB devices like Kvaser
+ Leaf Light.
+
+ The driver provides support for the following devices:
+ - Kvaser Leaf Light
+ - Kvaser Leaf Professional HS
+ - Kvaser Leaf SemiPro HS
+ - Kvaser Leaf Professional LS
+ - Kvaser Leaf Professional SWC
+ - Kvaser Leaf Professional LIN
+ - Kvaser Leaf SemiPro LS
+ - Kvaser Leaf SemiPro SWC
+ - Kvaser Memorator II HS/HS
+ - Kvaser USBcan Professional HS/HS
+ - Kvaser Leaf Light GI
+ - Kvaser Leaf Professional HS (OBD-II connector)
+ - Kvaser Memorator Professional HS/LS
+ - Kvaser Leaf Light "China"
+ - Kvaser BlackBird SemiPro
+ - Kvaser USBcan R
+ - Kvaser Leaf Light v2
+ - Kvaser Mini PCI Express HS
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called kvaser_usb.
+
+config CAN_PEAK_USB
+ tristate "PEAK PCAN-USB/USB Pro interfaces"
+ ---help---
+ This driver supports the PCAN-USB and PCAN-USB Pro adapters
+ from PEAK-System Technik (http://www.peak-system.com).
+
+config CAN_8DEV_USB
+ tristate "8 devices USB2CAN interface"
+ ---help---
+ This driver supports the USB2CAN interface
+ from 8 devices (http://www.8devices.com).
+
+endmenu
diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile
new file mode 100644
index 00000000000..7b9a393b1ac
--- /dev/null
+++ b/drivers/net/can/usb/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the Linux Controller Area Network USB drivers.
+#
+
+obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
+obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o
+obj-$(CONFIG_CAN_GS_USB) += gs_usb.o
+obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o
+obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/
+obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
new file mode 100644
index 00000000000..00f2534dde7
--- /dev/null
+++ b/drivers/net/can/usb/ems_usb.c
@@ -0,0 +1,1090 @@
+/*
+ * CAN driver for EMS Dr. Thomas Wuensche CPC-USB/ARM7
+ *
+ * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+MODULE_AUTHOR("Sebastian Haas <haas@ems-wuensche.com>");
+MODULE_DESCRIPTION("CAN driver for EMS Dr. Thomas Wuensche CAN/USB interfaces");
+MODULE_LICENSE("GPL v2");
+
+/* Control-Values for CPC_Control() Command Subject Selection */
+#define CONTR_CAN_MESSAGE 0x04
+#define CONTR_CAN_STATE 0x0C
+#define CONTR_BUS_ERROR 0x1C
+
+/* Control Command Actions */
+#define CONTR_CONT_OFF 0
+#define CONTR_CONT_ON 1
+#define CONTR_ONCE 2
+
+/* Messages from CPC to PC */
+#define CPC_MSG_TYPE_CAN_FRAME 1 /* CAN data frame */
+#define CPC_MSG_TYPE_RTR_FRAME 8 /* CAN remote frame */
+#define CPC_MSG_TYPE_CAN_PARAMS 12 /* Actual CAN parameters */
+#define CPC_MSG_TYPE_CAN_STATE 14 /* CAN state message */
+#define CPC_MSG_TYPE_EXT_CAN_FRAME 16 /* Extended CAN data frame */
+#define CPC_MSG_TYPE_EXT_RTR_FRAME 17 /* Extended remote frame */
+#define CPC_MSG_TYPE_CONTROL 19 /* change interface behavior */
+#define CPC_MSG_TYPE_CONFIRM 20 /* command processed confirmation */
+#define CPC_MSG_TYPE_OVERRUN 21 /* overrun events */
+#define CPC_MSG_TYPE_CAN_FRAME_ERROR 23 /* detected bus errors */
+#define CPC_MSG_TYPE_ERR_COUNTER 25 /* RX/TX error counter */
+
+/* Messages from the PC to the CPC interface */
+#define CPC_CMD_TYPE_CAN_FRAME 1 /* CAN data frame */
+#define CPC_CMD_TYPE_CONTROL 3 /* control of interface behavior */
+#define CPC_CMD_TYPE_CAN_PARAMS 6 /* set CAN parameters */
+#define CPC_CMD_TYPE_RTR_FRAME 13 /* CAN remote frame */
+#define CPC_CMD_TYPE_CAN_STATE 14 /* CAN state message */
+#define CPC_CMD_TYPE_EXT_CAN_FRAME 15 /* Extended CAN data frame */
+#define CPC_CMD_TYPE_EXT_RTR_FRAME 16 /* Extended CAN remote frame */
+#define CPC_CMD_TYPE_CAN_EXIT 200 /* exit the CAN */
+
+#define CPC_CMD_TYPE_INQ_ERR_COUNTER 25 /* request the CAN error counters */
+#define CPC_CMD_TYPE_CLEAR_MSG_QUEUE 8 /* clear CPC_MSG queue */
+#define CPC_CMD_TYPE_CLEAR_CMD_QUEUE 28 /* clear CPC_CMD queue */
+
+#define CPC_CC_TYPE_SJA1000 2 /* Philips basic CAN controller */
+
+#define CPC_CAN_ECODE_ERRFRAME 0x01 /* Ecode type */
+
+/* Overrun types */
+#define CPC_OVR_EVENT_CAN 0x01
+#define CPC_OVR_EVENT_CANSTATE 0x02
+#define CPC_OVR_EVENT_BUSERROR 0x04
+
+/*
+ * If the CAN controller lost a message we indicate it with the highest bit
+ * set in the count field.
+ */
+#define CPC_OVR_HW 0x80
+
+/* Size of the "struct ems_cpc_msg" without the union */
+#define CPC_MSG_HEADER_LEN 11
+#define CPC_CAN_MSG_MIN_SIZE 5
+
+/* Define these values to match your devices */
+#define USB_CPCUSB_VENDOR_ID 0x12D6
+
+#define USB_CPCUSB_ARM7_PRODUCT_ID 0x0444
+
+/* Mode register NXP LPC2119/SJA1000 CAN Controller */
+#define SJA1000_MOD_NORMAL 0x00
+#define SJA1000_MOD_RM 0x01
+
+/* ECC register NXP LPC2119/SJA1000 CAN Controller */
+#define SJA1000_ECC_SEG 0x1F
+#define SJA1000_ECC_DIR 0x20
+#define SJA1000_ECC_ERR 0x06
+#define SJA1000_ECC_BIT 0x00
+#define SJA1000_ECC_FORM 0x40
+#define SJA1000_ECC_STUFF 0x80
+#define SJA1000_ECC_MASK 0xc0
+
+/* Status register content */
+#define SJA1000_SR_BS 0x80
+#define SJA1000_SR_ES 0x40
+
+#define SJA1000_DEFAULT_OUTPUT_CONTROL 0xDA
+
+/*
+ * The device actually uses a 16MHz clock to generate the CAN clock
+ * but it expects SJA1000 bit settings based on 8MHz (is internally
+ * converted).
+ */
+#define EMS_USB_ARM7_CLOCK 8000000
+
+/*
+ * CAN-Message representation in a CPC_MSG. Message object type is
+ * CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or
+ * CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME.
+ */
+struct cpc_can_msg {
+ u32 id;
+ u8 length;
+ u8 msg[8];
+};
+
+/* Representation of the CAN parameters for the SJA1000 controller */
+struct cpc_sja1000_params {
+ u8 mode;
+ u8 acc_code0;
+ u8 acc_code1;
+ u8 acc_code2;
+ u8 acc_code3;
+ u8 acc_mask0;
+ u8 acc_mask1;
+ u8 acc_mask2;
+ u8 acc_mask3;
+ u8 btr0;
+ u8 btr1;
+ u8 outp_contr;
+};
+
+/* CAN params message representation */
+struct cpc_can_params {
+ u8 cc_type;
+
+ /* Will support M16C CAN controller in the future */
+ union {
+ struct cpc_sja1000_params sja1000;
+ } cc_params;
+};
+
+/* Structure for confirmed message handling */
+struct cpc_confirm {
+ u8 error; /* error code */
+};
+
+/* Structure for overrun conditions */
+struct cpc_overrun {
+ u8 event;
+ u8 count;
+};
+
+/* SJA1000 CAN errors (compatible to NXP LPC2119) */
+struct cpc_sja1000_can_error {
+ u8 ecc;
+ u8 rxerr;
+ u8 txerr;
+};
+
+/* structure for CAN error conditions */
+struct cpc_can_error {
+ u8 ecode;
+
+ struct {
+ u8 cc_type;
+
+ /* Other controllers may also provide error code capture regs */
+ union {
+ struct cpc_sja1000_can_error sja1000;
+ } regs;
+ } cc;
+};
+
+/*
+ * Structure containing RX/TX error counter. This structure is used to request
+ * the values of the CAN controllers TX and RX error counter.
+ */
+struct cpc_can_err_counter {
+ u8 rx;
+ u8 tx;
+};
+
+/* Main message type used between library and application */
+struct __packed ems_cpc_msg {
+ u8 type; /* type of message */
+ u8 length; /* length of data within union 'msg' */
+ u8 msgid; /* confirmation handle */
+ u32 ts_sec; /* timestamp in seconds */
+ u32 ts_nsec; /* timestamp in nano seconds */
+
+ union {
+ u8 generic[64];
+ struct cpc_can_msg can_msg;
+ struct cpc_can_params can_params;
+ struct cpc_confirm confirmation;
+ struct cpc_overrun overrun;
+ struct cpc_can_error error;
+ struct cpc_can_err_counter err_counter;
+ u8 can_state;
+ } msg;
+};
+
+/*
+ * Table of devices that work with this driver
+ * NOTE: This driver supports only CPC-USB/ARM7 (LPC2119) yet.
+ */
+static struct usb_device_id ems_usb_table[] = {
+ {USB_DEVICE(USB_CPCUSB_VENDOR_ID, USB_CPCUSB_ARM7_PRODUCT_ID)},
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, ems_usb_table);
+
+#define RX_BUFFER_SIZE 64
+#define CPC_HEADER_SIZE 4
+#define INTR_IN_BUFFER_SIZE 4
+
+#define MAX_RX_URBS 10
+#define MAX_TX_URBS 10
+
+struct ems_usb;
+
+struct ems_tx_urb_context {
+ struct ems_usb *dev;
+
+ u32 echo_index;
+ u8 dlc;
+};
+
+struct ems_usb {
+ struct can_priv can; /* must be the first member */
+
+ struct sk_buff *echo_skb[MAX_TX_URBS];
+
+ struct usb_device *udev;
+ struct net_device *netdev;
+
+ atomic_t active_tx_urbs;
+ struct usb_anchor tx_submitted;
+ struct ems_tx_urb_context tx_contexts[MAX_TX_URBS];
+
+ struct usb_anchor rx_submitted;
+
+ struct urb *intr_urb;
+
+ u8 *tx_msg_buffer;
+
+ u8 *intr_in_buffer;
+ unsigned int free_slots; /* remember number of available slots */
+
+ struct ems_cpc_msg active_params; /* active controller parameters */
+};
+
+static void ems_usb_read_interrupt_callback(struct urb *urb)
+{
+ struct ems_usb *dev = urb->context;
+ struct net_device *netdev = dev->netdev;
+ int err;
+
+ if (!netif_device_present(netdev))
+ return;
+
+ switch (urb->status) {
+ case 0:
+ dev->free_slots = dev->intr_in_buffer[1];
+ break;
+
+ case -ECONNRESET: /* unlink */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ netdev_info(netdev, "Rx interrupt aborted %d\n", urb->status);
+ break;
+ }
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ else if (err)
+ netdev_err(netdev, "failed resubmitting intr urb: %d\n", err);
+}
+
+static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ int i;
+ struct net_device_stats *stats = &dev->netdev->stats;
+
+ skb = alloc_can_skb(dev->netdev, &cf);
+ if (skb == NULL)
+ return;
+
+ cf->can_id = le32_to_cpu(msg->msg.can_msg.id);
+ cf->can_dlc = get_can_dlc(msg->msg.can_msg.length & 0xF);
+
+ if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME ||
+ msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME)
+ cf->can_id |= CAN_EFF_FLAG;
+
+ if (msg->type == CPC_MSG_TYPE_RTR_FRAME ||
+ msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) {
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ for (i = 0; i < cf->can_dlc; i++)
+ cf->data[i] = msg->msg.can_msg.msg[i];
+ }
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct net_device_stats *stats = &dev->netdev->stats;
+
+ skb = alloc_can_err_skb(dev->netdev, &cf);
+ if (skb == NULL)
+ return;
+
+ if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
+ u8 state = msg->msg.can_state;
+
+ if (state & SJA1000_SR_BS) {
+ dev->can.state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+
+ can_bus_off(dev->netdev);
+ } else if (state & SJA1000_SR_ES) {
+ dev->can.state = CAN_STATE_ERROR_WARNING;
+ dev->can.can_stats.error_warning++;
+ } else {
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+ dev->can.can_stats.error_passive++;
+ }
+ } else if (msg->type == CPC_MSG_TYPE_CAN_FRAME_ERROR) {
+ u8 ecc = msg->msg.error.cc.regs.sja1000.ecc;
+ u8 txerr = msg->msg.error.cc.regs.sja1000.txerr;
+ u8 rxerr = msg->msg.error.cc.regs.sja1000.rxerr;
+
+ /* bus error interrupt */
+ dev->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (ecc & SJA1000_ECC_MASK) {
+ case SJA1000_ECC_BIT:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ break;
+ case SJA1000_ECC_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case SJA1000_ECC_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ default:
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ cf->data[3] = ecc & SJA1000_ECC_SEG;
+ break;
+ }
+
+ /* Error occurred during transmission? */
+ if ((ecc & SJA1000_ECC_DIR) == 0)
+ cf->data[2] |= CAN_ERR_PROT_TX;
+
+ if (dev->can.state == CAN_STATE_ERROR_WARNING ||
+ dev->can.state == CAN_STATE_ERROR_PASSIVE) {
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ } else if (msg->type == CPC_MSG_TYPE_OVERRUN) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ }
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+/*
+ * callback for bulk IN urb
+ */
+static void ems_usb_read_bulk_callback(struct urb *urb)
+{
+ struct ems_usb *dev = urb->context;
+ struct net_device *netdev;
+ int retval;
+
+ netdev = dev->netdev;
+
+ if (!netif_device_present(netdev))
+ return;
+
+ switch (urb->status) {
+ case 0: /* success */
+ break;
+
+ case -ENOENT:
+ return;
+
+ default:
+ netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status);
+ goto resubmit_urb;
+ }
+
+ if (urb->actual_length > CPC_HEADER_SIZE) {
+ struct ems_cpc_msg *msg;
+ u8 *ibuf = urb->transfer_buffer;
+ u8 msg_count, again, start;
+
+ msg_count = ibuf[0] & ~0x80;
+ again = ibuf[0] & 0x80;
+
+ start = CPC_HEADER_SIZE;
+
+ while (msg_count) {
+ msg = (struct ems_cpc_msg *)&ibuf[start];
+
+ switch (msg->type) {
+ case CPC_MSG_TYPE_CAN_STATE:
+ /* Process CAN state changes */
+ ems_usb_rx_err(dev, msg);
+ break;
+
+ case CPC_MSG_TYPE_CAN_FRAME:
+ case CPC_MSG_TYPE_EXT_CAN_FRAME:
+ case CPC_MSG_TYPE_RTR_FRAME:
+ case CPC_MSG_TYPE_EXT_RTR_FRAME:
+ ems_usb_rx_can_msg(dev, msg);
+ break;
+
+ case CPC_MSG_TYPE_CAN_FRAME_ERROR:
+ /* Process errorframe */
+ ems_usb_rx_err(dev, msg);
+ break;
+
+ case CPC_MSG_TYPE_OVERRUN:
+ /* Message lost while receiving */
+ ems_usb_rx_err(dev, msg);
+ break;
+ }
+
+ start += CPC_MSG_HEADER_LEN + msg->length;
+ msg_count--;
+
+ if (start > urb->transfer_buffer_length) {
+ netdev_err(netdev, "format error\n");
+ break;
+ }
+ }
+ }
+
+resubmit_urb:
+ usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2),
+ urb->transfer_buffer, RX_BUFFER_SIZE,
+ ems_usb_read_bulk_callback, dev);
+
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (retval == -ENODEV)
+ netif_device_detach(netdev);
+ else if (retval)
+ netdev_err(netdev,
+ "failed resubmitting read bulk urb: %d\n", retval);
+}
+
+/*
+ * callback for bulk IN urb
+ */
+static void ems_usb_write_bulk_callback(struct urb *urb)
+{
+ struct ems_tx_urb_context *context = urb->context;
+ struct ems_usb *dev;
+ struct net_device *netdev;
+
+ BUG_ON(!context);
+
+ dev = context->dev;
+ netdev = dev->netdev;
+
+ /* free up our allocated buffer */
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+
+ atomic_dec(&dev->active_tx_urbs);
+
+ if (!netif_device_present(netdev))
+ return;
+
+ if (urb->status)
+ netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
+
+ netdev->trans_start = jiffies;
+
+ /* transmission complete interrupt */
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += context->dlc;
+
+ can_get_echo_skb(netdev, context->echo_index);
+
+ /* Release context */
+ context->echo_index = MAX_TX_URBS;
+
+ if (netif_queue_stopped(netdev))
+ netif_wake_queue(netdev);
+}
+
+/*
+ * Send the given CPC command synchronously
+ */
+static int ems_usb_command_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
+{
+ int actual_length;
+
+ /* Copy payload */
+ memcpy(&dev->tx_msg_buffer[CPC_HEADER_SIZE], msg,
+ msg->length + CPC_MSG_HEADER_LEN);
+
+ /* Clear header */
+ memset(&dev->tx_msg_buffer[0], 0, CPC_HEADER_SIZE);
+
+ return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
+ &dev->tx_msg_buffer[0],
+ msg->length + CPC_MSG_HEADER_LEN + CPC_HEADER_SIZE,
+ &actual_length, 1000);
+}
+
+/*
+ * Change CAN controllers' mode register
+ */
+static int ems_usb_write_mode(struct ems_usb *dev, u8 mode)
+{
+ dev->active_params.msg.can_params.cc_params.sja1000.mode = mode;
+
+ return ems_usb_command_msg(dev, &dev->active_params);
+}
+
+/*
+ * Send a CPC_Control command to change behaviour when interface receives a CAN
+ * message, bus error or CAN state changed notifications.
+ */
+static int ems_usb_control_cmd(struct ems_usb *dev, u8 val)
+{
+ struct ems_cpc_msg cmd;
+
+ cmd.type = CPC_CMD_TYPE_CONTROL;
+ cmd.length = CPC_MSG_HEADER_LEN + 1;
+
+ cmd.msgid = 0;
+
+ cmd.msg.generic[0] = val;
+
+ return ems_usb_command_msg(dev, &cmd);
+}
+
+/*
+ * Start interface
+ */
+static int ems_usb_start(struct ems_usb *dev)
+{
+ struct net_device *netdev = dev->netdev;
+ int err, i;
+
+ dev->intr_in_buffer[0] = 0;
+ dev->free_slots = 15; /* initial size */
+
+ for (i = 0; i < MAX_RX_URBS; i++) {
+ struct urb *urb = NULL;
+ u8 *buf = NULL;
+
+ /* create a URB, and a buffer for it */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ err = -ENOMEM;
+ break;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ usb_free_urb(urb);
+ err = -ENOMEM;
+ break;
+ }
+
+ usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2),
+ buf, RX_BUFFER_SIZE,
+ ems_usb_read_bulk_callback, dev);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
+ urb->transfer_dma);
+ usb_free_urb(urb);
+ break;
+ }
+
+ /* Drop reference, USB core will take care of freeing it */
+ usb_free_urb(urb);
+ }
+
+ /* Did we submit any URBs */
+ if (i == 0) {
+ netdev_warn(netdev, "couldn't setup read URBs\n");
+ return err;
+ }
+
+ /* Warn if we've couldn't transmit all the URBs */
+ if (i < MAX_RX_URBS)
+ netdev_warn(netdev, "rx performance may be slow\n");
+
+ /* Setup and start interrupt URB */
+ usb_fill_int_urb(dev->intr_urb, dev->udev,
+ usb_rcvintpipe(dev->udev, 1),
+ dev->intr_in_buffer,
+ INTR_IN_BUFFER_SIZE,
+ ems_usb_read_interrupt_callback, dev, 1);
+
+ err = usb_submit_urb(dev->intr_urb, GFP_KERNEL);
+ if (err) {
+ netdev_warn(netdev, "intr URB submit failed: %d\n", err);
+
+ return err;
+ }
+
+ /* CPC-USB will transfer received message to host */
+ err = ems_usb_control_cmd(dev, CONTR_CAN_MESSAGE | CONTR_CONT_ON);
+ if (err)
+ goto failed;
+
+ /* CPC-USB will transfer CAN state changes to host */
+ err = ems_usb_control_cmd(dev, CONTR_CAN_STATE | CONTR_CONT_ON);
+ if (err)
+ goto failed;
+
+ /* CPC-USB will transfer bus errors to host */
+ err = ems_usb_control_cmd(dev, CONTR_BUS_ERROR | CONTR_CONT_ON);
+ if (err)
+ goto failed;
+
+ err = ems_usb_write_mode(dev, SJA1000_MOD_NORMAL);
+ if (err)
+ goto failed;
+
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ return 0;
+
+failed:
+ netdev_warn(netdev, "couldn't submit control: %d\n", err);
+
+ return err;
+}
+
+static void unlink_all_urbs(struct ems_usb *dev)
+{
+ int i;
+
+ usb_unlink_urb(dev->intr_urb);
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+
+ usb_kill_anchored_urbs(&dev->tx_submitted);
+ atomic_set(&dev->active_tx_urbs, 0);
+
+ for (i = 0; i < MAX_TX_URBS; i++)
+ dev->tx_contexts[i].echo_index = MAX_TX_URBS;
+}
+
+static int ems_usb_open(struct net_device *netdev)
+{
+ struct ems_usb *dev = netdev_priv(netdev);
+ int err;
+
+ err = ems_usb_write_mode(dev, SJA1000_MOD_RM);
+ if (err)
+ return err;
+
+ /* common open */
+ err = open_candev(netdev);
+ if (err)
+ return err;
+
+ /* finally start device */
+ err = ems_usb_start(dev);
+ if (err) {
+ if (err == -ENODEV)
+ netif_device_detach(dev->netdev);
+
+ netdev_warn(netdev, "couldn't start device: %d\n", err);
+
+ close_candev(netdev);
+
+ return err;
+ }
+
+
+ netif_start_queue(netdev);
+
+ return 0;
+}
+
+static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct ems_usb *dev = netdev_priv(netdev);
+ struct ems_tx_urb_context *context = NULL;
+ struct net_device_stats *stats = &netdev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ struct ems_cpc_msg *msg;
+ struct urb *urb;
+ u8 *buf;
+ int i, err;
+ size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN
+ + sizeof(struct cpc_can_msg);
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* create a URB, and a buffer for it, and copy the data to the URB */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ goto nomem;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma);
+ if (!buf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ usb_free_urb(urb);
+ goto nomem;
+ }
+
+ msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE];
+
+ msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK;
+ msg->msg.can_msg.length = cf->can_dlc;
+
+ if (cf->can_id & CAN_RTR_FLAG) {
+ msg->type = cf->can_id & CAN_EFF_FLAG ?
+ CPC_CMD_TYPE_EXT_RTR_FRAME : CPC_CMD_TYPE_RTR_FRAME;
+
+ msg->length = CPC_CAN_MSG_MIN_SIZE;
+ } else {
+ msg->type = cf->can_id & CAN_EFF_FLAG ?
+ CPC_CMD_TYPE_EXT_CAN_FRAME : CPC_CMD_TYPE_CAN_FRAME;
+
+ for (i = 0; i < cf->can_dlc; i++)
+ msg->msg.can_msg.msg[i] = cf->data[i];
+
+ msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc;
+ }
+
+ /* Respect byte order */
+ msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id);
+
+ for (i = 0; i < MAX_TX_URBS; i++) {
+ if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) {
+ context = &dev->tx_contexts[i];
+ break;
+ }
+ }
+
+ /*
+ * May never happen! When this happens we'd more URBs in flight as
+ * allowed (MAX_TX_URBS).
+ */
+ if (!context) {
+ usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
+ usb_free_urb(urb);
+
+ netdev_warn(netdev, "couldn't find free context\n");
+
+ return NETDEV_TX_BUSY;
+ }
+
+ context->dev = dev;
+ context->echo_index = i;
+ context->dlc = cf->can_dlc;
+
+ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
+ size, ems_usb_write_bulk_callback, context);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &dev->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, context->echo_index);
+
+ atomic_inc(&dev->active_tx_urbs);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err)) {
+ can_free_echo_skb(netdev, context->echo_index);
+
+ usb_unanchor_urb(urb);
+ usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
+ dev_kfree_skb(skb);
+
+ atomic_dec(&dev->active_tx_urbs);
+
+ if (err == -ENODEV) {
+ netif_device_detach(netdev);
+ } else {
+ netdev_warn(netdev, "failed tx_urb %d\n", err);
+
+ stats->tx_dropped++;
+ }
+ } else {
+ netdev->trans_start = jiffies;
+
+ /* Slow down tx path */
+ if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS ||
+ dev->free_slots < 5) {
+ netif_stop_queue(netdev);
+ }
+ }
+
+ /*
+ * Release our reference to this URB, the USB core will eventually free
+ * it entirely.
+ */
+ usb_free_urb(urb);
+
+ return NETDEV_TX_OK;
+
+nomem:
+ dev_kfree_skb(skb);
+ stats->tx_dropped++;
+
+ return NETDEV_TX_OK;
+}
+
+static int ems_usb_close(struct net_device *netdev)
+{
+ struct ems_usb *dev = netdev_priv(netdev);
+
+ /* Stop polling */
+ unlink_all_urbs(dev);
+
+ netif_stop_queue(netdev);
+
+ /* Set CAN controller to reset mode */
+ if (ems_usb_write_mode(dev, SJA1000_MOD_RM))
+ netdev_warn(netdev, "couldn't stop device");
+
+ close_candev(netdev);
+
+ return 0;
+}
+
+static const struct net_device_ops ems_usb_netdev_ops = {
+ .ndo_open = ems_usb_open,
+ .ndo_stop = ems_usb_close,
+ .ndo_start_xmit = ems_usb_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static const struct can_bittiming_const ems_usb_bittiming_const = {
+ .name = "ems_usb",
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+};
+
+static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode)
+{
+ struct ems_usb *dev = netdev_priv(netdev);
+
+ switch (mode) {
+ case CAN_MODE_START:
+ if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL))
+ netdev_warn(netdev, "couldn't start device");
+
+ if (netif_queue_stopped(netdev))
+ netif_wake_queue(netdev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int ems_usb_set_bittiming(struct net_device *netdev)
+{
+ struct ems_usb *dev = netdev_priv(netdev);
+ struct can_bittiming *bt = &dev->can.bittiming;
+ u8 btr0, btr1;
+
+ btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+ btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+ (((bt->phase_seg2 - 1) & 0x7) << 4);
+ if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ btr1 |= 0x80;
+
+ netdev_info(netdev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+ dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0;
+ dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1;
+
+ return ems_usb_command_msg(dev, &dev->active_params);
+}
+
+static void init_params_sja1000(struct ems_cpc_msg *msg)
+{
+ struct cpc_sja1000_params *sja1000 =
+ &msg->msg.can_params.cc_params.sja1000;
+
+ msg->type = CPC_CMD_TYPE_CAN_PARAMS;
+ msg->length = sizeof(struct cpc_can_params);
+ msg->msgid = 0;
+
+ msg->msg.can_params.cc_type = CPC_CC_TYPE_SJA1000;
+
+ /* Acceptance filter open */
+ sja1000->acc_code0 = 0x00;
+ sja1000->acc_code1 = 0x00;
+ sja1000->acc_code2 = 0x00;
+ sja1000->acc_code3 = 0x00;
+
+ /* Acceptance filter open */
+ sja1000->acc_mask0 = 0xFF;
+ sja1000->acc_mask1 = 0xFF;
+ sja1000->acc_mask2 = 0xFF;
+ sja1000->acc_mask3 = 0xFF;
+
+ sja1000->btr0 = 0;
+ sja1000->btr1 = 0;
+
+ sja1000->outp_contr = SJA1000_DEFAULT_OUTPUT_CONTROL;
+ sja1000->mode = SJA1000_MOD_RM;
+}
+
+/*
+ * probe function for new CPC-USB devices
+ */
+static int ems_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct net_device *netdev;
+ struct ems_usb *dev;
+ int i, err = -ENOMEM;
+
+ netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
+ if (!netdev) {
+ dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n");
+ return -ENOMEM;
+ }
+
+ dev = netdev_priv(netdev);
+
+ dev->udev = interface_to_usbdev(intf);
+ dev->netdev = netdev;
+
+ dev->can.state = CAN_STATE_STOPPED;
+ dev->can.clock.freq = EMS_USB_ARM7_CLOCK;
+ dev->can.bittiming_const = &ems_usb_bittiming_const;
+ dev->can.do_set_bittiming = ems_usb_set_bittiming;
+ dev->can.do_set_mode = ems_usb_set_mode;
+ dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+
+ netdev->netdev_ops = &ems_usb_netdev_ops;
+
+ netdev->flags |= IFF_ECHO; /* we support local echo */
+
+ init_usb_anchor(&dev->rx_submitted);
+
+ init_usb_anchor(&dev->tx_submitted);
+ atomic_set(&dev->active_tx_urbs, 0);
+
+ for (i = 0; i < MAX_TX_URBS; i++)
+ dev->tx_contexts[i].echo_index = MAX_TX_URBS;
+
+ dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->intr_urb) {
+ dev_err(&intf->dev, "Couldn't alloc intr URB\n");
+ goto cleanup_candev;
+ }
+
+ dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL);
+ if (!dev->intr_in_buffer)
+ goto cleanup_intr_urb;
+
+ dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE +
+ sizeof(struct ems_cpc_msg), GFP_KERNEL);
+ if (!dev->tx_msg_buffer)
+ goto cleanup_intr_in_buffer;
+
+ usb_set_intfdata(intf, dev);
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+
+ init_params_sja1000(&dev->active_params);
+
+ err = ems_usb_command_msg(dev, &dev->active_params);
+ if (err) {
+ netdev_err(netdev, "couldn't initialize controller: %d\n", err);
+ goto cleanup_tx_msg_buffer;
+ }
+
+ err = register_candev(netdev);
+ if (err) {
+ netdev_err(netdev, "couldn't register CAN device: %d\n", err);
+ goto cleanup_tx_msg_buffer;
+ }
+
+ return 0;
+
+cleanup_tx_msg_buffer:
+ kfree(dev->tx_msg_buffer);
+
+cleanup_intr_in_buffer:
+ kfree(dev->intr_in_buffer);
+
+cleanup_intr_urb:
+ usb_free_urb(dev->intr_urb);
+
+cleanup_candev:
+ free_candev(netdev);
+
+ return err;
+}
+
+/*
+ * called by the usb core when the device is removed from the system
+ */
+static void ems_usb_disconnect(struct usb_interface *intf)
+{
+ struct ems_usb *dev = usb_get_intfdata(intf);
+
+ usb_set_intfdata(intf, NULL);
+
+ if (dev) {
+ unregister_netdev(dev->netdev);
+ free_candev(dev->netdev);
+
+ unlink_all_urbs(dev);
+
+ usb_free_urb(dev->intr_urb);
+
+ kfree(dev->intr_in_buffer);
+ }
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver ems_usb_driver = {
+ .name = "ems_usb",
+ .probe = ems_usb_probe,
+ .disconnect = ems_usb_disconnect,
+ .id_table = ems_usb_table,
+};
+
+module_usb_driver(ems_usb_driver);
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
new file mode 100644
index 00000000000..b7c9e8b1146
--- /dev/null
+++ b/drivers/net/can/usb/esd_usb2.c
@@ -0,0 +1,1157 @@
+/*
+ * CAN driver for esd CAN-USB/2 and CAN-USB/Micro
+ *
+ * Copyright (C) 2010-2012 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd.eu>");
+MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2 and CAN-USB/Micro interfaces");
+MODULE_LICENSE("GPL v2");
+
+/* Define these values to match your devices */
+#define USB_ESDGMBH_VENDOR_ID 0x0ab4
+#define USB_CANUSB2_PRODUCT_ID 0x0010
+#define USB_CANUSBM_PRODUCT_ID 0x0011
+
+#define ESD_USB2_CAN_CLOCK 60000000
+#define ESD_USBM_CAN_CLOCK 36000000
+#define ESD_USB2_MAX_NETS 2
+
+/* USB2 commands */
+#define CMD_VERSION 1 /* also used for VERSION_REPLY */
+#define CMD_CAN_RX 2 /* device to host only */
+#define CMD_CAN_TX 3 /* also used for TX_DONE */
+#define CMD_SETBAUD 4 /* also used for SETBAUD_REPLY */
+#define CMD_TS 5 /* also used for TS_REPLY */
+#define CMD_IDADD 6 /* also used for IDADD_REPLY */
+
+/* esd CAN message flags - dlc field */
+#define ESD_RTR 0x10
+
+/* esd CAN message flags - id field */
+#define ESD_EXTID 0x20000000
+#define ESD_EVENT 0x40000000
+#define ESD_IDMASK 0x1fffffff
+
+/* esd CAN event ids used by this driver */
+#define ESD_EV_CAN_ERROR_EXT 2
+
+/* baudrate message flags */
+#define ESD_USB2_UBR 0x80000000
+#define ESD_USB2_LOM 0x40000000
+#define ESD_USB2_NO_BAUDRATE 0x7fffffff
+#define ESD_USB2_TSEG1_MIN 1
+#define ESD_USB2_TSEG1_MAX 16
+#define ESD_USB2_TSEG1_SHIFT 16
+#define ESD_USB2_TSEG2_MIN 1
+#define ESD_USB2_TSEG2_MAX 8
+#define ESD_USB2_TSEG2_SHIFT 20
+#define ESD_USB2_SJW_MAX 4
+#define ESD_USB2_SJW_SHIFT 14
+#define ESD_USBM_SJW_SHIFT 24
+#define ESD_USB2_BRP_MIN 1
+#define ESD_USB2_BRP_MAX 1024
+#define ESD_USB2_BRP_INC 1
+#define ESD_USB2_3_SAMPLES 0x00800000
+
+/* esd IDADD message */
+#define ESD_ID_ENABLE 0x80
+#define ESD_MAX_ID_SEGMENT 64
+
+/* SJA1000 ECC register (emulated by usb2 firmware) */
+#define SJA1000_ECC_SEG 0x1F
+#define SJA1000_ECC_DIR 0x20
+#define SJA1000_ECC_ERR 0x06
+#define SJA1000_ECC_BIT 0x00
+#define SJA1000_ECC_FORM 0x40
+#define SJA1000_ECC_STUFF 0x80
+#define SJA1000_ECC_MASK 0xc0
+
+/* esd bus state event codes */
+#define ESD_BUSSTATE_MASK 0xc0
+#define ESD_BUSSTATE_WARN 0x40
+#define ESD_BUSSTATE_ERRPASSIVE 0x80
+#define ESD_BUSSTATE_BUSOFF 0xc0
+
+#define RX_BUFFER_SIZE 1024
+#define MAX_RX_URBS 4
+#define MAX_TX_URBS 16 /* must be power of 2 */
+
+struct header_msg {
+ u8 len; /* len is always the total message length in 32bit words */
+ u8 cmd;
+ u8 rsvd[2];
+};
+
+struct version_msg {
+ u8 len;
+ u8 cmd;
+ u8 rsvd;
+ u8 flags;
+ __le32 drv_version;
+};
+
+struct version_reply_msg {
+ u8 len;
+ u8 cmd;
+ u8 nets;
+ u8 features;
+ __le32 version;
+ u8 name[16];
+ __le32 rsvd;
+ __le32 ts;
+};
+
+struct rx_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 dlc;
+ __le32 ts;
+ __le32 id; /* upper 3 bits contain flags */
+ u8 data[8];
+};
+
+struct tx_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 dlc;
+ __le32 hnd;
+ __le32 id; /* upper 3 bits contain flags */
+ u8 data[8];
+};
+
+struct tx_done_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 status;
+ __le32 hnd;
+ __le32 ts;
+};
+
+struct id_filter_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 option;
+ __le32 mask[ESD_MAX_ID_SEGMENT + 1];
+};
+
+struct set_baudrate_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 rsvd;
+ __le32 baud;
+};
+
+/* Main message type used between library and application */
+struct __attribute__ ((packed)) esd_usb2_msg {
+ union {
+ struct header_msg hdr;
+ struct version_msg version;
+ struct version_reply_msg version_reply;
+ struct rx_msg rx;
+ struct tx_msg tx;
+ struct tx_done_msg txdone;
+ struct set_baudrate_msg setbaud;
+ struct id_filter_msg filter;
+ } msg;
+};
+
+static struct usb_device_id esd_usb2_table[] = {
+ {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSB2_PRODUCT_ID)},
+ {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSBM_PRODUCT_ID)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, esd_usb2_table);
+
+struct esd_usb2_net_priv;
+
+struct esd_tx_urb_context {
+ struct esd_usb2_net_priv *priv;
+ u32 echo_index;
+ int dlc;
+};
+
+struct esd_usb2 {
+ struct usb_device *udev;
+ struct esd_usb2_net_priv *nets[ESD_USB2_MAX_NETS];
+
+ struct usb_anchor rx_submitted;
+
+ int net_count;
+ u32 version;
+ int rxinitdone;
+};
+
+struct esd_usb2_net_priv {
+ struct can_priv can; /* must be the first member */
+
+ atomic_t active_tx_jobs;
+ struct usb_anchor tx_submitted;
+ struct esd_tx_urb_context tx_contexts[MAX_TX_URBS];
+
+ struct esd_usb2 *usb2;
+ struct net_device *netdev;
+ int index;
+ u8 old_state;
+ struct can_berr_counter bec;
+};
+
+static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
+ struct esd_usb2_msg *msg)
+{
+ struct net_device_stats *stats = &priv->netdev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 id = le32_to_cpu(msg->msg.rx.id) & ESD_IDMASK;
+
+ if (id == ESD_EV_CAN_ERROR_EXT) {
+ u8 state = msg->msg.rx.data[0];
+ u8 ecc = msg->msg.rx.data[1];
+ u8 txerr = msg->msg.rx.data[2];
+ u8 rxerr = msg->msg.rx.data[3];
+
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (skb == NULL) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ if (state != priv->old_state) {
+ priv->old_state = state;
+
+ switch (state & ESD_BUSSTATE_MASK) {
+ case ESD_BUSSTATE_BUSOFF:
+ priv->can.state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(priv->netdev);
+ break;
+ case ESD_BUSSTATE_WARN:
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ priv->can.can_stats.error_warning++;
+ break;
+ case ESD_BUSSTATE_ERRPASSIVE:
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ priv->can.can_stats.error_passive++;
+ break;
+ default:
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ break;
+ }
+ } else {
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (ecc & SJA1000_ECC_MASK) {
+ case SJA1000_ECC_BIT:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ break;
+ case SJA1000_ECC_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case SJA1000_ECC_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ default:
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ cf->data[3] = ecc & SJA1000_ECC_SEG;
+ break;
+ }
+
+ /* Error occurred during transmission? */
+ if (!(ecc & SJA1000_ECC_DIR))
+ cf->data[2] |= CAN_ERR_PROT_TX;
+
+ if (priv->can.state == CAN_STATE_ERROR_WARNING ||
+ priv->can.state == CAN_STATE_ERROR_PASSIVE) {
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+
+ netif_rx(skb);
+
+ priv->bec.txerr = txerr;
+ priv->bec.rxerr = rxerr;
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ }
+}
+
+static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
+ struct esd_usb2_msg *msg)
+{
+ struct net_device_stats *stats = &priv->netdev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ int i;
+ u32 id;
+
+ if (!netif_device_present(priv->netdev))
+ return;
+
+ id = le32_to_cpu(msg->msg.rx.id);
+
+ if (id & ESD_EVENT) {
+ esd_usb2_rx_event(priv, msg);
+ } else {
+ skb = alloc_can_skb(priv->netdev, &cf);
+ if (skb == NULL) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ cf->can_id = id & ESD_IDMASK;
+ cf->can_dlc = get_can_dlc(msg->msg.rx.dlc);
+
+ if (id & ESD_EXTID)
+ cf->can_id |= CAN_EFF_FLAG;
+
+ if (msg->msg.rx.dlc & ESD_RTR) {
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ for (i = 0; i < cf->can_dlc; i++)
+ cf->data[i] = msg->msg.rx.data[i];
+ }
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ }
+
+ return;
+}
+
+static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv,
+ struct esd_usb2_msg *msg)
+{
+ struct net_device_stats *stats = &priv->netdev->stats;
+ struct net_device *netdev = priv->netdev;
+ struct esd_tx_urb_context *context;
+
+ if (!netif_device_present(netdev))
+ return;
+
+ context = &priv->tx_contexts[msg->msg.txdone.hnd & (MAX_TX_URBS - 1)];
+
+ if (!msg->msg.txdone.status) {
+ stats->tx_packets++;
+ stats->tx_bytes += context->dlc;
+ can_get_echo_skb(netdev, context->echo_index);
+ } else {
+ stats->tx_errors++;
+ can_free_echo_skb(netdev, context->echo_index);
+ }
+
+ /* Release context */
+ context->echo_index = MAX_TX_URBS;
+ atomic_dec(&priv->active_tx_jobs);
+
+ netif_wake_queue(netdev);
+}
+
+static void esd_usb2_read_bulk_callback(struct urb *urb)
+{
+ struct esd_usb2 *dev = urb->context;
+ int retval;
+ int pos = 0;
+ int i;
+
+ switch (urb->status) {
+ case 0: /* success */
+ break;
+
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ dev_info(dev->udev->dev.parent,
+ "Rx URB aborted (%d)\n", urb->status);
+ goto resubmit_urb;
+ }
+
+ while (pos < urb->actual_length) {
+ struct esd_usb2_msg *msg;
+
+ msg = (struct esd_usb2_msg *)(urb->transfer_buffer + pos);
+
+ switch (msg->msg.hdr.cmd) {
+ case CMD_CAN_RX:
+ if (msg->msg.rx.net >= dev->net_count) {
+ dev_err(dev->udev->dev.parent, "format error\n");
+ break;
+ }
+
+ esd_usb2_rx_can_msg(dev->nets[msg->msg.rx.net], msg);
+ break;
+
+ case CMD_CAN_TX:
+ if (msg->msg.txdone.net >= dev->net_count) {
+ dev_err(dev->udev->dev.parent, "format error\n");
+ break;
+ }
+
+ esd_usb2_tx_done_msg(dev->nets[msg->msg.txdone.net],
+ msg);
+ break;
+ }
+
+ pos += msg->msg.hdr.len << 2;
+
+ if (pos > urb->actual_length) {
+ dev_err(dev->udev->dev.parent, "format error\n");
+ break;
+ }
+ }
+
+resubmit_urb:
+ usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
+ urb->transfer_buffer, RX_BUFFER_SIZE,
+ esd_usb2_read_bulk_callback, dev);
+
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval == -ENODEV) {
+ for (i = 0; i < dev->net_count; i++) {
+ if (dev->nets[i])
+ netif_device_detach(dev->nets[i]->netdev);
+ }
+ } else if (retval) {
+ dev_err(dev->udev->dev.parent,
+ "failed resubmitting read bulk urb: %d\n", retval);
+ }
+
+ return;
+}
+
+/*
+ * callback for bulk IN urb
+ */
+static void esd_usb2_write_bulk_callback(struct urb *urb)
+{
+ struct esd_tx_urb_context *context = urb->context;
+ struct esd_usb2_net_priv *priv;
+ struct esd_usb2 *dev;
+ struct net_device *netdev;
+ size_t size = sizeof(struct esd_usb2_msg);
+
+ WARN_ON(!context);
+
+ priv = context->priv;
+ netdev = priv->netdev;
+ dev = priv->usb2;
+
+ /* free up our allocated buffer */
+ usb_free_coherent(urb->dev, size,
+ urb->transfer_buffer, urb->transfer_dma);
+
+ if (!netif_device_present(netdev))
+ return;
+
+ if (urb->status)
+ netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
+
+ netdev->trans_start = jiffies;
+}
+
+static ssize_t show_firmware(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(d);
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+
+ return sprintf(buf, "%d.%d.%d\n",
+ (dev->version >> 12) & 0xf,
+ (dev->version >> 8) & 0xf,
+ dev->version & 0xff);
+}
+static DEVICE_ATTR(firmware, S_IRUGO, show_firmware, NULL);
+
+static ssize_t show_hardware(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(d);
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+
+ return sprintf(buf, "%d.%d.%d\n",
+ (dev->version >> 28) & 0xf,
+ (dev->version >> 24) & 0xf,
+ (dev->version >> 16) & 0xff);
+}
+static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
+
+static ssize_t show_nets(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(d);
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+
+ return sprintf(buf, "%d", dev->net_count);
+}
+static DEVICE_ATTR(nets, S_IRUGO, show_nets, NULL);
+
+static int esd_usb2_send_msg(struct esd_usb2 *dev, struct esd_usb2_msg *msg)
+{
+ int actual_length;
+
+ return usb_bulk_msg(dev->udev,
+ usb_sndbulkpipe(dev->udev, 2),
+ msg,
+ msg->msg.hdr.len << 2,
+ &actual_length,
+ 1000);
+}
+
+static int esd_usb2_wait_msg(struct esd_usb2 *dev,
+ struct esd_usb2_msg *msg)
+{
+ int actual_length;
+
+ return usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev, 1),
+ msg,
+ sizeof(*msg),
+ &actual_length,
+ 1000);
+}
+
+static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)
+{
+ int i, err = 0;
+
+ if (dev->rxinitdone)
+ return 0;
+
+ for (i = 0; i < MAX_RX_URBS; i++) {
+ struct urb *urb = NULL;
+ u8 *buf = NULL;
+
+ /* create a URB, and a buffer for it */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ dev_warn(dev->udev->dev.parent,
+ "No memory left for URBs\n");
+ err = -ENOMEM;
+ break;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buf) {
+ dev_warn(dev->udev->dev.parent,
+ "No memory left for USB buffer\n");
+ err = -ENOMEM;
+ goto freeurb;
+ }
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev, 1),
+ buf, RX_BUFFER_SIZE,
+ esd_usb2_read_bulk_callback, dev);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
+ urb->transfer_dma);
+ }
+
+freeurb:
+ /* Drop reference, USB core will take care of freeing it */
+ usb_free_urb(urb);
+ if (err)
+ break;
+ }
+
+ /* Did we submit any URBs */
+ if (i == 0) {
+ dev_err(dev->udev->dev.parent, "couldn't setup read URBs\n");
+ return err;
+ }
+
+ /* Warn if we've couldn't transmit all the URBs */
+ if (i < MAX_RX_URBS) {
+ dev_warn(dev->udev->dev.parent,
+ "rx performance may be slow\n");
+ }
+
+ dev->rxinitdone = 1;
+ return 0;
+}
+
+/*
+ * Start interface
+ */
+static int esd_usb2_start(struct esd_usb2_net_priv *priv)
+{
+ struct esd_usb2 *dev = priv->usb2;
+ struct net_device *netdev = priv->netdev;
+ struct esd_usb2_msg *msg;
+ int err, i;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Enable all IDs
+ * The IDADD message takes up to 64 32 bit bitmasks (2048 bits).
+ * Each bit represents one 11 bit CAN identifier. A set bit
+ * enables reception of the corresponding CAN identifier. A cleared
+ * bit disabled this identifier. An additional bitmask value
+ * following the CAN 2.0A bits is used to enable reception of
+ * extended CAN frames. Only the LSB of this final mask is checked
+ * for the complete 29 bit ID range. The IDADD message also allows
+ * filter configuration for an ID subset. In this case you can add
+ * the number of the starting bitmask (0..64) to the filter.option
+ * field followed by only some bitmasks.
+ */
+ msg->msg.hdr.cmd = CMD_IDADD;
+ msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+ msg->msg.filter.net = priv->index;
+ msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+ for (i = 0; i < ESD_MAX_ID_SEGMENT; i++)
+ msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff);
+ /* enable 29bit extended IDs */
+ msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
+
+ err = esd_usb2_send_msg(dev, msg);
+ if (err)
+ goto out;
+
+ err = esd_usb2_setup_rx_urbs(dev);
+ if (err)
+ goto out;
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+out:
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ if (err)
+ netdev_err(netdev, "couldn't start device: %d\n", err);
+
+ kfree(msg);
+ return err;
+}
+
+static void unlink_all_urbs(struct esd_usb2 *dev)
+{
+ struct esd_usb2_net_priv *priv;
+ int i, j;
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+ for (i = 0; i < dev->net_count; i++) {
+ priv = dev->nets[i];
+ if (priv) {
+ usb_kill_anchored_urbs(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_jobs, 0);
+
+ for (j = 0; j < MAX_TX_URBS; j++)
+ priv->tx_contexts[j].echo_index = MAX_TX_URBS;
+ }
+ }
+}
+
+static int esd_usb2_open(struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ int err;
+
+ /* common open */
+ err = open_candev(netdev);
+ if (err)
+ return err;
+
+ /* finally start device */
+ err = esd_usb2_start(priv);
+ if (err) {
+ netdev_warn(netdev, "couldn't start device: %d\n", err);
+ close_candev(netdev);
+ return err;
+ }
+
+ netif_start_queue(netdev);
+
+ return 0;
+}
+
+static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ struct esd_usb2 *dev = priv->usb2;
+ struct esd_tx_urb_context *context = NULL;
+ struct net_device_stats *stats = &netdev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ struct esd_usb2_msg *msg;
+ struct urb *urb;
+ u8 *buf;
+ int i, err;
+ int ret = NETDEV_TX_OK;
+ size_t size = sizeof(struct esd_usb2_msg);
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* create a URB, and a buffer for it, and copy the data to the URB */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ stats->tx_dropped++;
+ dev_kfree_skb(skb);
+ goto nourbmem;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC,
+ &urb->transfer_dma);
+ if (!buf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ stats->tx_dropped++;
+ dev_kfree_skb(skb);
+ goto nobufmem;
+ }
+
+ msg = (struct esd_usb2_msg *)buf;
+
+ msg->msg.hdr.len = 3; /* minimal length */
+ msg->msg.hdr.cmd = CMD_CAN_TX;
+ msg->msg.tx.net = priv->index;
+ msg->msg.tx.dlc = cf->can_dlc;
+ msg->msg.tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ msg->msg.tx.dlc |= ESD_RTR;
+
+ if (cf->can_id & CAN_EFF_FLAG)
+ msg->msg.tx.id |= cpu_to_le32(ESD_EXTID);
+
+ for (i = 0; i < cf->can_dlc; i++)
+ msg->msg.tx.data[i] = cf->data[i];
+
+ msg->msg.hdr.len += (cf->can_dlc + 3) >> 2;
+
+ for (i = 0; i < MAX_TX_URBS; i++) {
+ if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
+ context = &priv->tx_contexts[i];
+ break;
+ }
+ }
+
+ /*
+ * This may never happen.
+ */
+ if (!context) {
+ netdev_warn(netdev, "couldn't find free context\n");
+ ret = NETDEV_TX_BUSY;
+ goto releasebuf;
+ }
+
+ context->priv = priv;
+ context->echo_index = i;
+ context->dlc = cf->can_dlc;
+
+ /* hnd must not be 0 - MSB is stripped in txdone handling */
+ msg->msg.tx.hnd = 0x80000000 | i; /* returned in TX done message */
+
+ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
+ msg->msg.hdr.len << 2,
+ esd_usb2_write_bulk_callback, context);
+
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ usb_anchor_urb(urb, &priv->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, context->echo_index);
+
+ atomic_inc(&priv->active_tx_jobs);
+
+ /* Slow down tx path */
+ if (atomic_read(&priv->active_tx_jobs) >= MAX_TX_URBS)
+ netif_stop_queue(netdev);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err) {
+ can_free_echo_skb(netdev, context->echo_index);
+
+ atomic_dec(&priv->active_tx_jobs);
+ usb_unanchor_urb(urb);
+
+ stats->tx_dropped++;
+
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ else
+ netdev_warn(netdev, "failed tx_urb %d\n", err);
+
+ goto releasebuf;
+ }
+
+ netdev->trans_start = jiffies;
+
+ /*
+ * Release our reference to this URB, the USB core will eventually free
+ * it entirely.
+ */
+ usb_free_urb(urb);
+
+ return NETDEV_TX_OK;
+
+releasebuf:
+ usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
+
+nobufmem:
+ usb_free_urb(urb);
+
+nourbmem:
+ return ret;
+}
+
+static int esd_usb2_close(struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ struct esd_usb2_msg *msg;
+ int i;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ /* Disable all IDs (see esd_usb2_start()) */
+ msg->msg.hdr.cmd = CMD_IDADD;
+ msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+ msg->msg.filter.net = priv->index;
+ msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+ for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++)
+ msg->msg.filter.mask[i] = 0;
+ if (esd_usb2_send_msg(priv->usb2, msg) < 0)
+ netdev_err(netdev, "sending idadd message failed\n");
+
+ /* set CAN controller to reset mode */
+ msg->msg.hdr.len = 2;
+ msg->msg.hdr.cmd = CMD_SETBAUD;
+ msg->msg.setbaud.net = priv->index;
+ msg->msg.setbaud.rsvd = 0;
+ msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
+ if (esd_usb2_send_msg(priv->usb2, msg) < 0)
+ netdev_err(netdev, "sending setbaud message failed\n");
+
+ priv->can.state = CAN_STATE_STOPPED;
+
+ netif_stop_queue(netdev);
+
+ close_candev(netdev);
+
+ kfree(msg);
+
+ return 0;
+}
+
+static const struct net_device_ops esd_usb2_netdev_ops = {
+ .ndo_open = esd_usb2_open,
+ .ndo_stop = esd_usb2_close,
+ .ndo_start_xmit = esd_usb2_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static const struct can_bittiming_const esd_usb2_bittiming_const = {
+ .name = "esd_usb2",
+ .tseg1_min = ESD_USB2_TSEG1_MIN,
+ .tseg1_max = ESD_USB2_TSEG1_MAX,
+ .tseg2_min = ESD_USB2_TSEG2_MIN,
+ .tseg2_max = ESD_USB2_TSEG2_MAX,
+ .sjw_max = ESD_USB2_SJW_MAX,
+ .brp_min = ESD_USB2_BRP_MIN,
+ .brp_max = ESD_USB2_BRP_MAX,
+ .brp_inc = ESD_USB2_BRP_INC,
+};
+
+static int esd_usb2_set_bittiming(struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ struct esd_usb2_msg *msg;
+ int err;
+ u32 canbtr;
+ int sjw_shift;
+
+ canbtr = ESD_USB2_UBR;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ canbtr |= ESD_USB2_LOM;
+
+ canbtr |= (bt->brp - 1) & (ESD_USB2_BRP_MAX - 1);
+
+ if (le16_to_cpu(priv->usb2->udev->descriptor.idProduct) ==
+ USB_CANUSBM_PRODUCT_ID)
+ sjw_shift = ESD_USBM_SJW_SHIFT;
+ else
+ sjw_shift = ESD_USB2_SJW_SHIFT;
+
+ canbtr |= ((bt->sjw - 1) & (ESD_USB2_SJW_MAX - 1))
+ << sjw_shift;
+ canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1)
+ & (ESD_USB2_TSEG1_MAX - 1))
+ << ESD_USB2_TSEG1_SHIFT;
+ canbtr |= ((bt->phase_seg2 - 1) & (ESD_USB2_TSEG2_MAX - 1))
+ << ESD_USB2_TSEG2_SHIFT;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ canbtr |= ESD_USB2_3_SAMPLES;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ msg->msg.hdr.len = 2;
+ msg->msg.hdr.cmd = CMD_SETBAUD;
+ msg->msg.setbaud.net = priv->index;
+ msg->msg.setbaud.rsvd = 0;
+ msg->msg.setbaud.baud = cpu_to_le32(canbtr);
+
+ netdev_info(netdev, "setting BTR=%#x\n", canbtr);
+
+ err = esd_usb2_send_msg(priv->usb2, msg);
+
+ kfree(msg);
+ return err;
+}
+
+static int esd_usb2_get_berr_counter(const struct net_device *netdev,
+ struct can_berr_counter *bec)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+
+ bec->txerr = priv->bec.txerr;
+ bec->rxerr = priv->bec.rxerr;
+
+ return 0;
+}
+
+static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ netif_wake_queue(netdev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int esd_usb2_probe_one_net(struct usb_interface *intf, int index)
+{
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+ struct net_device *netdev;
+ struct esd_usb2_net_priv *priv;
+ int err = 0;
+ int i;
+
+ netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
+ if (!netdev) {
+ dev_err(&intf->dev, "couldn't alloc candev\n");
+ err = -ENOMEM;
+ goto done;
+ }
+
+ priv = netdev_priv(netdev);
+
+ init_usb_anchor(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_jobs, 0);
+
+ for (i = 0; i < MAX_TX_URBS; i++)
+ priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+
+ priv->usb2 = dev;
+ priv->netdev = netdev;
+ priv->index = index;
+
+ priv->can.state = CAN_STATE_STOPPED;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY;
+
+ if (le16_to_cpu(dev->udev->descriptor.idProduct) ==
+ USB_CANUSBM_PRODUCT_ID)
+ priv->can.clock.freq = ESD_USBM_CAN_CLOCK;
+ else {
+ priv->can.clock.freq = ESD_USB2_CAN_CLOCK;
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+ }
+
+ priv->can.bittiming_const = &esd_usb2_bittiming_const;
+ priv->can.do_set_bittiming = esd_usb2_set_bittiming;
+ priv->can.do_set_mode = esd_usb2_set_mode;
+ priv->can.do_get_berr_counter = esd_usb2_get_berr_counter;
+
+ netdev->flags |= IFF_ECHO; /* we support local echo */
+
+ netdev->netdev_ops = &esd_usb2_netdev_ops;
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+ netdev->dev_id = index;
+
+ err = register_candev(netdev);
+ if (err) {
+ dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
+ free_candev(netdev);
+ err = -ENOMEM;
+ goto done;
+ }
+
+ dev->nets[index] = priv;
+ netdev_info(netdev, "device %s registered\n", netdev->name);
+
+done:
+ return err;
+}
+
+/*
+ * probe function for new USB2 devices
+ *
+ * check version information and number of available
+ * CAN interfaces
+ */
+static int esd_usb2_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct esd_usb2 *dev;
+ struct esd_usb2_msg *msg;
+ int i, err;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ dev->udev = interface_to_usbdev(intf);
+
+ init_usb_anchor(&dev->rx_submitted);
+
+ usb_set_intfdata(intf, dev);
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg) {
+ err = -ENOMEM;
+ goto free_msg;
+ }
+
+ /* query number of CAN interfaces (nets) */
+ msg->msg.hdr.cmd = CMD_VERSION;
+ msg->msg.hdr.len = 2;
+ msg->msg.version.rsvd = 0;
+ msg->msg.version.flags = 0;
+ msg->msg.version.drv_version = 0;
+
+ err = esd_usb2_send_msg(dev, msg);
+ if (err < 0) {
+ dev_err(&intf->dev, "sending version message failed\n");
+ goto free_msg;
+ }
+
+ err = esd_usb2_wait_msg(dev, msg);
+ if (err < 0) {
+ dev_err(&intf->dev, "no version message answer\n");
+ goto free_msg;
+ }
+
+ dev->net_count = (int)msg->msg.version_reply.nets;
+ dev->version = le32_to_cpu(msg->msg.version_reply.version);
+
+ if (device_create_file(&intf->dev, &dev_attr_firmware))
+ dev_err(&intf->dev,
+ "Couldn't create device file for firmware\n");
+
+ if (device_create_file(&intf->dev, &dev_attr_hardware))
+ dev_err(&intf->dev,
+ "Couldn't create device file for hardware\n");
+
+ if (device_create_file(&intf->dev, &dev_attr_nets))
+ dev_err(&intf->dev,
+ "Couldn't create device file for nets\n");
+
+ /* do per device probing */
+ for (i = 0; i < dev->net_count; i++)
+ esd_usb2_probe_one_net(intf, i);
+
+free_msg:
+ kfree(msg);
+ if (err)
+ kfree(dev);
+done:
+ return err;
+}
+
+/*
+ * called by the usb core when the device is removed from the system
+ */
+static void esd_usb2_disconnect(struct usb_interface *intf)
+{
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+ struct net_device *netdev;
+ int i;
+
+ device_remove_file(&intf->dev, &dev_attr_firmware);
+ device_remove_file(&intf->dev, &dev_attr_hardware);
+ device_remove_file(&intf->dev, &dev_attr_nets);
+
+ usb_set_intfdata(intf, NULL);
+
+ if (dev) {
+ for (i = 0; i < dev->net_count; i++) {
+ if (dev->nets[i]) {
+ netdev = dev->nets[i]->netdev;
+ unregister_netdev(netdev);
+ free_candev(netdev);
+ }
+ }
+ unlink_all_urbs(dev);
+ }
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver esd_usb2_driver = {
+ .name = "esd_usb2",
+ .probe = esd_usb2_probe,
+ .disconnect = esd_usb2_disconnect,
+ .id_table = esd_usb2_table,
+};
+
+module_usb_driver(esd_usb2_driver);
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
new file mode 100644
index 00000000000..04b0f84612f
--- /dev/null
+++ b/drivers/net/can/usb/gs_usb.c
@@ -0,0 +1,971 @@
+/* CAN driver for Geschwister Schneider USB/CAN devices.
+ *
+ * Copyright (C) 2013 Geschwister Schneider Technologie-,
+ * Entwicklungs- und Vertriebs UG (Haftungsbeschränkt).
+ *
+ * Many thanks to all socketcan devs!
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+/* Device specific constants */
+#define USB_GSUSB_1_VENDOR_ID 0x1d50
+#define USB_GSUSB_1_PRODUCT_ID 0x606f
+
+#define GSUSB_ENDPOINT_IN 1
+#define GSUSB_ENDPOINT_OUT 2
+
+/* Device specific constants */
+enum gs_usb_breq {
+ GS_USB_BREQ_HOST_FORMAT = 0,
+ GS_USB_BREQ_BITTIMING,
+ GS_USB_BREQ_MODE,
+ GS_USB_BREQ_BERR,
+ GS_USB_BREQ_BT_CONST,
+ GS_USB_BREQ_DEVICE_CONFIG
+};
+
+enum gs_can_mode {
+ /* reset a channel. turns it off */
+ GS_CAN_MODE_RESET = 0,
+ /* starts a channel */
+ GS_CAN_MODE_START
+};
+
+enum gs_can_state {
+ GS_CAN_STATE_ERROR_ACTIVE = 0,
+ GS_CAN_STATE_ERROR_WARNING,
+ GS_CAN_STATE_ERROR_PASSIVE,
+ GS_CAN_STATE_BUS_OFF,
+ GS_CAN_STATE_STOPPED,
+ GS_CAN_STATE_SLEEPING
+};
+
+/* data types passed between host and device */
+struct gs_host_config {
+ u32 byte_order;
+} __packed;
+/* All data exchanged between host and device is exchanged in host byte order,
+ * thanks to the struct gs_host_config byte_order member, which is sent first
+ * to indicate the desired byte order.
+ */
+
+struct gs_device_config {
+ u8 reserved1;
+ u8 reserved2;
+ u8 reserved3;
+ u8 icount;
+ u32 sw_version;
+ u32 hw_version;
+} __packed;
+
+#define GS_CAN_MODE_NORMAL 0
+#define GS_CAN_MODE_LISTEN_ONLY (1<<0)
+#define GS_CAN_MODE_LOOP_BACK (1<<1)
+#define GS_CAN_MODE_TRIPLE_SAMPLE (1<<2)
+#define GS_CAN_MODE_ONE_SHOT (1<<3)
+
+struct gs_device_mode {
+ u32 mode;
+ u32 flags;
+} __packed;
+
+struct gs_device_state {
+ u32 state;
+ u32 rxerr;
+ u32 txerr;
+} __packed;
+
+struct gs_device_bittiming {
+ u32 prop_seg;
+ u32 phase_seg1;
+ u32 phase_seg2;
+ u32 sjw;
+ u32 brp;
+} __packed;
+
+#define GS_CAN_FEATURE_LISTEN_ONLY (1<<0)
+#define GS_CAN_FEATURE_LOOP_BACK (1<<1)
+#define GS_CAN_FEATURE_TRIPLE_SAMPLE (1<<2)
+#define GS_CAN_FEATURE_ONE_SHOT (1<<3)
+
+struct gs_device_bt_const {
+ u32 feature;
+ u32 fclk_can;
+ u32 tseg1_min;
+ u32 tseg1_max;
+ u32 tseg2_min;
+ u32 tseg2_max;
+ u32 sjw_max;
+ u32 brp_min;
+ u32 brp_max;
+ u32 brp_inc;
+} __packed;
+
+#define GS_CAN_FLAG_OVERFLOW 1
+
+struct gs_host_frame {
+ u32 echo_id;
+ u32 can_id;
+
+ u8 can_dlc;
+ u8 channel;
+ u8 flags;
+ u8 reserved;
+
+ u8 data[8];
+} __packed;
+/* The GS USB devices make use of the same flags and masks as in
+ * linux/can.h and linux/can/error.h, and no additional mapping is necessary.
+ */
+
+/* Only send a max of GS_MAX_TX_URBS frames per channel at a time. */
+#define GS_MAX_TX_URBS 10
+/* Only launch a max of GS_MAX_RX_URBS usb requests at a time. */
+#define GS_MAX_RX_URBS 30
+/* Maximum number of interfaces the driver supports per device.
+ * Current hardware only supports 2 interfaces. The future may vary.
+ */
+#define GS_MAX_INTF 2
+
+struct gs_tx_context {
+ struct gs_can *dev;
+ unsigned int echo_id;
+};
+
+struct gs_can {
+ struct can_priv can; /* must be the first member */
+
+ struct gs_usb *parent;
+
+ struct net_device *netdev;
+ struct usb_device *udev;
+ struct usb_interface *iface;
+
+ struct can_bittiming_const bt_const;
+ unsigned int channel; /* channel number */
+
+ /* This lock prevents a race condition between xmit and recieve. */
+ spinlock_t tx_ctx_lock;
+ struct gs_tx_context tx_context[GS_MAX_TX_URBS];
+
+ struct usb_anchor tx_submitted;
+ atomic_t active_tx_urbs;
+};
+
+/* usb interface struct */
+struct gs_usb {
+ struct gs_can *canch[GS_MAX_INTF];
+ struct usb_anchor rx_submitted;
+ atomic_t active_channels;
+ struct usb_device *udev;
+};
+
+/* 'allocate' a tx context.
+ * returns a valid tx context or NULL if there is no space.
+ */
+static struct gs_tx_context *gs_alloc_tx_context(struct gs_can *dev)
+{
+ int i = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->tx_ctx_lock, flags);
+
+ for (; i < GS_MAX_TX_URBS; i++) {
+ if (dev->tx_context[i].echo_id == GS_MAX_TX_URBS) {
+ dev->tx_context[i].echo_id = i;
+ spin_unlock_irqrestore(&dev->tx_ctx_lock, flags);
+ return &dev->tx_context[i];
+ }
+ }
+
+ spin_unlock_irqrestore(&dev->tx_ctx_lock, flags);
+ return NULL;
+}
+
+/* releases a tx context
+ */
+static void gs_free_tx_context(struct gs_tx_context *txc)
+{
+ txc->echo_id = GS_MAX_TX_URBS;
+}
+
+/* Get a tx context by id.
+ */
+static struct gs_tx_context *gs_get_tx_context(struct gs_can *dev, unsigned int id)
+{
+ unsigned long flags;
+
+ if (id < GS_MAX_TX_URBS) {
+ spin_lock_irqsave(&dev->tx_ctx_lock, flags);
+ if (dev->tx_context[id].echo_id == id) {
+ spin_unlock_irqrestore(&dev->tx_ctx_lock, flags);
+ return &dev->tx_context[id];
+ }
+ spin_unlock_irqrestore(&dev->tx_ctx_lock, flags);
+ }
+ return NULL;
+}
+
+static int gs_cmd_reset(struct gs_usb *gsusb, struct gs_can *gsdev)
+{
+ struct gs_device_mode *dm;
+ struct usb_interface *intf = gsdev->iface;
+ int rc;
+
+ dm = kzalloc(sizeof(*dm), GFP_KERNEL);
+ if (!dm)
+ return -ENOMEM;
+
+ dm->mode = GS_CAN_MODE_RESET;
+
+ rc = usb_control_msg(interface_to_usbdev(intf),
+ usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+ GS_USB_BREQ_MODE,
+ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ gsdev->channel,
+ 0,
+ dm,
+ sizeof(*dm),
+ 1000);
+
+ return rc;
+}
+
+static void gs_update_state(struct gs_can *dev, struct can_frame *cf)
+{
+ struct can_device_stats *can_stats = &dev->can.can_stats;
+
+ if (cf->can_id & CAN_ERR_RESTARTED) {
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+ can_stats->restarts++;
+ } else if (cf->can_id & CAN_ERR_BUSOFF) {
+ dev->can.state = CAN_STATE_BUS_OFF;
+ can_stats->bus_off++;
+ } else if (cf->can_id & CAN_ERR_CRTL) {
+ if ((cf->data[1] & CAN_ERR_CRTL_TX_WARNING) ||
+ (cf->data[1] & CAN_ERR_CRTL_RX_WARNING)) {
+ dev->can.state = CAN_STATE_ERROR_WARNING;
+ can_stats->error_warning++;
+ } else if ((cf->data[1] & CAN_ERR_CRTL_TX_PASSIVE) ||
+ (cf->data[1] & CAN_ERR_CRTL_RX_PASSIVE)) {
+ dev->can.state = CAN_STATE_ERROR_PASSIVE;
+ can_stats->error_passive++;
+ } else {
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+ }
+ }
+}
+
+static void gs_usb_recieve_bulk_callback(struct urb *urb)
+{
+ struct gs_usb *usbcan = urb->context;
+ struct gs_can *dev;
+ struct net_device *netdev;
+ int rc;
+ struct net_device_stats *stats;
+ struct gs_host_frame *hf = urb->transfer_buffer;
+ struct gs_tx_context *txc;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+
+ BUG_ON(!usbcan);
+
+ switch (urb->status) {
+ case 0: /* success */
+ break;
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default:
+ /* do not resubmit aborted urbs. eg: when device goes down */
+ return;
+ }
+
+ /* device reports out of range channel id */
+ if (hf->channel >= GS_MAX_INTF)
+ goto resubmit_urb;
+
+ dev = usbcan->canch[hf->channel];
+
+ netdev = dev->netdev;
+ stats = &netdev->stats;
+
+ if (!netif_device_present(netdev))
+ return;
+
+ if (hf->echo_id == -1) { /* normal rx */
+ skb = alloc_can_skb(dev->netdev, &cf);
+ if (!skb)
+ return;
+
+ cf->can_id = hf->can_id;
+
+ cf->can_dlc = get_can_dlc(hf->can_dlc);
+ memcpy(cf->data, hf->data, 8);
+
+ /* ERROR frames tell us information about the controller */
+ if (hf->can_id & CAN_ERR_FLAG)
+ gs_update_state(dev, cf);
+
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += hf->can_dlc;
+
+ netif_rx(skb);
+ } else { /* echo_id == hf->echo_id */
+ if (hf->echo_id >= GS_MAX_TX_URBS) {
+ netdev_err(netdev,
+ "Unexpected out of range echo id %d\n",
+ hf->echo_id);
+ goto resubmit_urb;
+ }
+
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += hf->can_dlc;
+
+ txc = gs_get_tx_context(dev, hf->echo_id);
+
+ /* bad devices send bad echo_ids. */
+ if (!txc) {
+ netdev_err(netdev,
+ "Unexpected unused echo id %d\n",
+ hf->echo_id);
+ goto resubmit_urb;
+ }
+
+ can_get_echo_skb(netdev, hf->echo_id);
+
+ gs_free_tx_context(txc);
+
+ netif_wake_queue(netdev);
+ }
+
+ if (hf->flags & GS_CAN_FLAG_OVERFLOW) {
+ skb = alloc_can_err_skb(netdev, &cf);
+ if (!skb)
+ goto resubmit_urb;
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->can_dlc = CAN_ERR_DLC;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ netif_rx(skb);
+ }
+
+ resubmit_urb:
+ usb_fill_bulk_urb(urb,
+ usbcan->udev,
+ usb_rcvbulkpipe(usbcan->udev, GSUSB_ENDPOINT_IN),
+ hf,
+ sizeof(struct gs_host_frame),
+ gs_usb_recieve_bulk_callback,
+ usbcan
+ );
+
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+
+ /* USB failure take down all interfaces */
+ if (rc == -ENODEV) {
+ for (rc = 0; rc < GS_MAX_INTF; rc++) {
+ if (usbcan->canch[rc])
+ netif_device_detach(usbcan->canch[rc]->netdev);
+ }
+ }
+}
+
+static int gs_usb_set_bittiming(struct net_device *netdev)
+{
+ struct gs_can *dev = netdev_priv(netdev);
+ struct can_bittiming *bt = &dev->can.bittiming;
+ struct usb_interface *intf = dev->iface;
+ int rc;
+ struct gs_device_bittiming *dbt;
+
+ dbt = kmalloc(sizeof(*dbt), GFP_KERNEL);
+ if (!dbt)
+ return -ENOMEM;
+
+ dbt->prop_seg = bt->prop_seg;
+ dbt->phase_seg1 = bt->phase_seg1;
+ dbt->phase_seg2 = bt->phase_seg2;
+ dbt->sjw = bt->sjw;
+ dbt->brp = bt->brp;
+
+ /* request bit timings */
+ rc = usb_control_msg(interface_to_usbdev(intf),
+ usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+ GS_USB_BREQ_BITTIMING,
+ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ dev->channel,
+ 0,
+ dbt,
+ sizeof(*dbt),
+ 1000);
+
+ kfree(dbt);
+
+ if (rc < 0)
+ dev_err(netdev->dev.parent, "Couldn't set bittimings (err=%d)",
+ rc);
+
+ return rc;
+}
+
+static void gs_usb_xmit_callback(struct urb *urb)
+{
+ struct gs_tx_context *txc = urb->context;
+ struct gs_can *dev = txc->dev;
+ struct net_device *netdev = dev->netdev;
+
+ if (urb->status)
+ netdev_info(netdev, "usb xmit fail %d\n", txc->echo_id);
+
+ usb_free_coherent(urb->dev,
+ urb->transfer_buffer_length,
+ urb->transfer_buffer,
+ urb->transfer_dma);
+
+ atomic_dec(&dev->active_tx_urbs);
+
+ if (!netif_device_present(netdev))
+ return;
+
+ if (netif_queue_stopped(netdev))
+ netif_wake_queue(netdev);
+}
+
+static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct gs_can *dev = netdev_priv(netdev);
+ struct net_device_stats *stats = &dev->netdev->stats;
+ struct urb *urb;
+ struct gs_host_frame *hf;
+ struct can_frame *cf;
+ int rc;
+ unsigned int idx;
+ struct gs_tx_context *txc;
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* find an empty context to keep track of transmission */
+ txc = gs_alloc_tx_context(dev);
+ if (!txc)
+ return NETDEV_TX_BUSY;
+
+ /* create a URB, and a buffer for it */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URB\n");
+ goto nomem_urb;
+ }
+
+ hf = usb_alloc_coherent(dev->udev, sizeof(*hf), GFP_ATOMIC,
+ &urb->transfer_dma);
+ if (!hf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ goto nomem_hf;
+ }
+
+ idx = txc->echo_id;
+
+ if (idx >= GS_MAX_TX_URBS) {
+ netdev_err(netdev, "Invalid tx context %d\n", idx);
+ goto badidx;
+ }
+
+ hf->echo_id = idx;
+ hf->channel = dev->channel;
+
+ cf = (struct can_frame *)skb->data;
+
+ hf->can_id = cf->can_id;
+ hf->can_dlc = cf->can_dlc;
+ memcpy(hf->data, cf->data, cf->can_dlc);
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev, GSUSB_ENDPOINT_OUT),
+ hf,
+ sizeof(*hf),
+ gs_usb_xmit_callback,
+ txc);
+
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &dev->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, idx);
+
+ atomic_inc(&dev->active_tx_urbs);
+
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(rc)) { /* usb send failed */
+ atomic_dec(&dev->active_tx_urbs);
+
+ can_free_echo_skb(netdev, idx);
+ gs_free_tx_context(txc);
+
+ usb_unanchor_urb(urb);
+ usb_free_coherent(dev->udev,
+ sizeof(*hf),
+ hf,
+ urb->transfer_dma);
+
+
+ if (rc == -ENODEV) {
+ netif_device_detach(netdev);
+ } else {
+ netdev_err(netdev, "usb_submit failed (err=%d)\n", rc);
+ stats->tx_dropped++;
+ }
+ } else {
+ /* Slow down tx path */
+ if (atomic_read(&dev->active_tx_urbs) >= GS_MAX_TX_URBS)
+ netif_stop_queue(netdev);
+ }
+
+ /* let usb core take care of this urb */
+ usb_free_urb(urb);
+
+ return NETDEV_TX_OK;
+
+ badidx:
+ usb_free_coherent(dev->udev,
+ sizeof(*hf),
+ hf,
+ urb->transfer_dma);
+ nomem_hf:
+ usb_free_urb(urb);
+
+ nomem_urb:
+ gs_free_tx_context(txc);
+ dev_kfree_skb(skb);
+ stats->tx_dropped++;
+ return NETDEV_TX_OK;
+}
+
+static int gs_can_open(struct net_device *netdev)
+{
+ struct gs_can *dev = netdev_priv(netdev);
+ struct gs_usb *parent = dev->parent;
+ int rc, i;
+ struct gs_device_mode *dm;
+ u32 ctrlmode;
+
+ rc = open_candev(netdev);
+ if (rc)
+ return rc;
+
+ if (atomic_add_return(1, &parent->active_channels) == 1) {
+ for (i = 0; i < GS_MAX_RX_URBS; i++) {
+ struct urb *urb;
+ u8 *buf;
+
+ /* alloc rx urb */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ netdev_err(netdev,
+ "No memory left for URB\n");
+ return -ENOMEM;
+ }
+
+ /* alloc rx buffer */
+ buf = usb_alloc_coherent(dev->udev,
+ sizeof(struct gs_host_frame),
+ GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buf) {
+ netdev_err(netdev,
+ "No memory left for USB buffer\n");
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ /* fill, anchor, and submit rx urb */
+ usb_fill_bulk_urb(urb,
+ dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ GSUSB_ENDPOINT_IN),
+ buf,
+ sizeof(struct gs_host_frame),
+ gs_usb_recieve_bulk_callback,
+ parent);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ usb_anchor_urb(urb, &parent->rx_submitted);
+
+ rc = usb_submit_urb(urb, GFP_KERNEL);
+ if (rc) {
+ if (rc == -ENODEV)
+ netif_device_detach(dev->netdev);
+
+ netdev_err(netdev,
+ "usb_submit failed (err=%d)\n",
+ rc);
+
+ usb_unanchor_urb(urb);
+ break;
+ }
+
+ /* Drop reference,
+ * USB core will take care of freeing it
+ */
+ usb_free_urb(urb);
+ }
+ }
+
+ dm = kmalloc(sizeof(*dm), GFP_KERNEL);
+ if (!dm)
+ return -ENOMEM;
+
+ /* flags */
+ ctrlmode = dev->can.ctrlmode;
+ dm->flags = 0;
+
+ if (ctrlmode & CAN_CTRLMODE_LOOPBACK)
+ dm->flags |= GS_CAN_MODE_LOOP_BACK;
+ else if (ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ dm->flags |= GS_CAN_MODE_LISTEN_ONLY;
+
+ /* Controller is not allowed to retry TX
+ * this mode is unavailable on atmels uc3c hardware
+ */
+ if (ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+ dm->flags |= GS_CAN_MODE_ONE_SHOT;
+
+ if (ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ dm->flags |= GS_CAN_MODE_TRIPLE_SAMPLE;
+
+ /* finally start device */
+ dm->mode = GS_CAN_MODE_START;
+ rc = usb_control_msg(interface_to_usbdev(dev->iface),
+ usb_sndctrlpipe(interface_to_usbdev(dev->iface), 0),
+ GS_USB_BREQ_MODE,
+ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ dev->channel,
+ 0,
+ dm,
+ sizeof(*dm),
+ 1000);
+
+ if (rc < 0) {
+ netdev_err(netdev, "Couldn't start device (err=%d)\n", rc);
+ kfree(dm);
+ return rc;
+ }
+
+ kfree(dm);
+
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
+ netif_start_queue(netdev);
+
+ return 0;
+}
+
+static int gs_can_close(struct net_device *netdev)
+{
+ int rc;
+ struct gs_can *dev = netdev_priv(netdev);
+ struct gs_usb *parent = dev->parent;
+
+ netif_stop_queue(netdev);
+
+ /* Stop polling */
+ if (atomic_dec_and_test(&parent->active_channels))
+ usb_kill_anchored_urbs(&parent->rx_submitted);
+
+ /* Stop sending URBs */
+ usb_kill_anchored_urbs(&dev->tx_submitted);
+ atomic_set(&dev->active_tx_urbs, 0);
+
+ /* reset the device */
+ rc = gs_cmd_reset(parent, dev);
+ if (rc < 0)
+ netdev_warn(netdev, "Couldn't shutdown device (err=%d)", rc);
+
+ /* reset tx contexts */
+ for (rc = 0; rc < GS_MAX_TX_URBS; rc++) {
+ dev->tx_context[rc].dev = dev;
+ dev->tx_context[rc].echo_id = GS_MAX_TX_URBS;
+ }
+
+ /* close the netdev */
+ close_candev(netdev);
+
+ return 0;
+}
+
+static const struct net_device_ops gs_usb_netdev_ops = {
+ .ndo_open = gs_can_open,
+ .ndo_stop = gs_can_close,
+ .ndo_start_xmit = gs_can_start_xmit,
+};
+
+static struct gs_can *gs_make_candev(unsigned int channel, struct usb_interface *intf)
+{
+ struct gs_can *dev;
+ struct net_device *netdev;
+ int rc;
+ struct gs_device_bt_const *bt_const;
+
+ bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL);
+ if (!bt_const)
+ return ERR_PTR(-ENOMEM);
+
+ /* fetch bit timing constants */
+ rc = usb_control_msg(interface_to_usbdev(intf),
+ usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
+ GS_USB_BREQ_BT_CONST,
+ USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ channel,
+ 0,
+ bt_const,
+ sizeof(*bt_const),
+ 1000);
+
+ if (rc < 0) {
+ dev_err(&intf->dev,
+ "Couldn't get bit timing const for channel (err=%d)\n",
+ rc);
+ kfree(bt_const);
+ return ERR_PTR(rc);
+ }
+
+ /* create netdev */
+ netdev = alloc_candev(sizeof(struct gs_can), GS_MAX_TX_URBS);
+ if (!netdev) {
+ dev_err(&intf->dev, "Couldn't allocate candev\n");
+ kfree(bt_const);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ dev = netdev_priv(netdev);
+
+ netdev->netdev_ops = &gs_usb_netdev_ops;
+
+ netdev->flags |= IFF_ECHO; /* we support full roundtrip echo */
+
+ /* dev settup */
+ strcpy(dev->bt_const.name, "gs_usb");
+ dev->bt_const.tseg1_min = bt_const->tseg1_min;
+ dev->bt_const.tseg1_max = bt_const->tseg1_max;
+ dev->bt_const.tseg2_min = bt_const->tseg2_min;
+ dev->bt_const.tseg2_max = bt_const->tseg2_max;
+ dev->bt_const.sjw_max = bt_const->sjw_max;
+ dev->bt_const.brp_min = bt_const->brp_min;
+ dev->bt_const.brp_max = bt_const->brp_max;
+ dev->bt_const.brp_inc = bt_const->brp_inc;
+
+ dev->udev = interface_to_usbdev(intf);
+ dev->iface = intf;
+ dev->netdev = netdev;
+ dev->channel = channel;
+
+ init_usb_anchor(&dev->tx_submitted);
+ atomic_set(&dev->active_tx_urbs, 0);
+ spin_lock_init(&dev->tx_ctx_lock);
+ for (rc = 0; rc < GS_MAX_TX_URBS; rc++) {
+ dev->tx_context[rc].dev = dev;
+ dev->tx_context[rc].echo_id = GS_MAX_TX_URBS;
+ }
+
+ /* can settup */
+ dev->can.state = CAN_STATE_STOPPED;
+ dev->can.clock.freq = bt_const->fclk_can;
+ dev->can.bittiming_const = &dev->bt_const;
+ dev->can.do_set_bittiming = gs_usb_set_bittiming;
+
+ dev->can.ctrlmode_supported = 0;
+
+ if (bt_const->feature & GS_CAN_FEATURE_LISTEN_ONLY)
+ dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY;
+
+ if (bt_const->feature & GS_CAN_FEATURE_LOOP_BACK)
+ dev->can.ctrlmode_supported |= CAN_CTRLMODE_LOOPBACK;
+
+ if (bt_const->feature & GS_CAN_FEATURE_TRIPLE_SAMPLE)
+ dev->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+
+ if (bt_const->feature & GS_CAN_FEATURE_ONE_SHOT)
+ dev->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
+
+ kfree(bt_const);
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+
+ rc = register_candev(dev->netdev);
+ if (rc) {
+ free_candev(dev->netdev);
+ dev_err(&intf->dev, "Couldn't register candev (err=%d)\n", rc);
+ return ERR_PTR(rc);
+ }
+
+ return dev;
+}
+
+static void gs_destroy_candev(struct gs_can *dev)
+{
+ unregister_candev(dev->netdev);
+ free_candev(dev->netdev);
+ usb_kill_anchored_urbs(&dev->tx_submitted);
+ kfree(dev);
+}
+
+static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct gs_usb *dev;
+ int rc = -ENOMEM;
+ unsigned int icount, i;
+ struct gs_host_config *hconf;
+ struct gs_device_config *dconf;
+
+ hconf = kmalloc(sizeof(*hconf), GFP_KERNEL);
+ if (!hconf)
+ return -ENOMEM;
+
+ hconf->byte_order = 0x0000beef;
+
+ /* send host config */
+ rc = usb_control_msg(interface_to_usbdev(intf),
+ usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+ GS_USB_BREQ_HOST_FORMAT,
+ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ 1,
+ intf->altsetting[0].desc.bInterfaceNumber,
+ hconf,
+ sizeof(*hconf),
+ 1000);
+
+ kfree(hconf);
+
+ if (rc < 0) {
+ dev_err(&intf->dev, "Couldn't send data format (err=%d)\n",
+ rc);
+ return rc;
+ }
+
+ dconf = kmalloc(sizeof(*dconf), GFP_KERNEL);
+ if (!dconf)
+ return -ENOMEM;
+
+ /* read device config */
+ rc = usb_control_msg(interface_to_usbdev(intf),
+ usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
+ GS_USB_BREQ_DEVICE_CONFIG,
+ USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ 1,
+ intf->altsetting[0].desc.bInterfaceNumber,
+ dconf,
+ sizeof(*dconf),
+ 1000);
+ if (rc < 0) {
+ dev_err(&intf->dev, "Couldn't get device config: (err=%d)\n",
+ rc);
+
+ kfree(dconf);
+
+ return rc;
+ }
+
+ icount = dconf->icount+1;
+
+ kfree(dconf);
+
+ dev_info(&intf->dev, "Configuring for %d interfaces\n", icount);
+
+ if (icount > GS_MAX_INTF) {
+ dev_err(&intf->dev,
+ "Driver cannot handle more that %d CAN interfaces\n",
+ GS_MAX_INTF);
+ return -EINVAL;
+ }
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ init_usb_anchor(&dev->rx_submitted);
+
+ atomic_set(&dev->active_channels, 0);
+
+ usb_set_intfdata(intf, dev);
+ dev->udev = interface_to_usbdev(intf);
+
+ for (i = 0; i < icount; i++) {
+ dev->canch[i] = gs_make_candev(i, intf);
+ if (IS_ERR_OR_NULL(dev->canch[i])) {
+ /* on failure destroy previously created candevs */
+ icount = i;
+ for (i = 0; i < icount; i++) {
+ gs_destroy_candev(dev->canch[i]);
+ dev->canch[i] = NULL;
+ }
+ kfree(dev);
+ return rc;
+ }
+ dev->canch[i]->parent = dev;
+ }
+
+ return 0;
+}
+
+static void gs_usb_disconnect(struct usb_interface *intf)
+{
+ unsigned i;
+ struct gs_usb *dev = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);
+
+ if (!dev) {
+ dev_err(&intf->dev, "Disconnect (nodata)\n");
+ return;
+ }
+
+ for (i = 0; i < GS_MAX_INTF; i++) {
+ struct gs_can *can = dev->canch[i];
+
+ if (!can)
+ continue;
+
+ gs_destroy_candev(can);
+ }
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+}
+
+static const struct usb_device_id gs_usb_table[] = {
+ {USB_DEVICE(USB_GSUSB_1_VENDOR_ID, USB_GSUSB_1_PRODUCT_ID)},
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, gs_usb_table);
+
+static struct usb_driver gs_usb_driver = {
+ .name = "gs_usb",
+ .probe = gs_usb_probe,
+ .disconnect = gs_usb_disconnect,
+ .id_table = gs_usb_table,
+};
+
+module_usb_driver(gs_usb_driver);
+
+MODULE_AUTHOR("Maximilian Schneider <mws@schneidersoft.net>");
+MODULE_DESCRIPTION(
+"Socket CAN device driver for Geschwister Schneider Technologie-, "
+"Entwicklungs- und Vertriebs UG. USB2.0 to CAN interfaces.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
new file mode 100644
index 00000000000..541fb7a0562
--- /dev/null
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -0,0 +1,1665 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * Parts of this driver are based on the following:
+ * - Kvaser linux leaf driver (version 4.78)
+ * - CAN driver for esd CAN-USB/2
+ *
+ * Copyright (C) 2002-2006 KVASER AB, Sweden. All rights reserved.
+ * Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
+ * Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be>
+ */
+
+#include <linux/completion.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#define MAX_TX_URBS 16
+#define MAX_RX_URBS 4
+#define START_TIMEOUT 1000 /* msecs */
+#define STOP_TIMEOUT 1000 /* msecs */
+#define USB_SEND_TIMEOUT 1000 /* msecs */
+#define USB_RECV_TIMEOUT 1000 /* msecs */
+#define RX_BUFFER_SIZE 3072
+#define CAN_USB_CLOCK 8000000
+#define MAX_NET_DEVICES 3
+
+/* Kvaser USB devices */
+#define KVASER_VENDOR_ID 0x0bfd
+#define USB_LEAF_DEVEL_PRODUCT_ID 10
+#define USB_LEAF_LITE_PRODUCT_ID 11
+#define USB_LEAF_PRO_PRODUCT_ID 12
+#define USB_LEAF_SPRO_PRODUCT_ID 14
+#define USB_LEAF_PRO_LS_PRODUCT_ID 15
+#define USB_LEAF_PRO_SWC_PRODUCT_ID 16
+#define USB_LEAF_PRO_LIN_PRODUCT_ID 17
+#define USB_LEAF_SPRO_LS_PRODUCT_ID 18
+#define USB_LEAF_SPRO_SWC_PRODUCT_ID 19
+#define USB_MEMO2_DEVEL_PRODUCT_ID 22
+#define USB_MEMO2_HSHS_PRODUCT_ID 23
+#define USB_UPRO_HSHS_PRODUCT_ID 24
+#define USB_LEAF_LITE_GI_PRODUCT_ID 25
+#define USB_LEAF_PRO_OBDII_PRODUCT_ID 26
+#define USB_MEMO2_HSLS_PRODUCT_ID 27
+#define USB_LEAF_LITE_CH_PRODUCT_ID 28
+#define USB_BLACKBIRD_SPRO_PRODUCT_ID 29
+#define USB_OEM_MERCURY_PRODUCT_ID 34
+#define USB_OEM_LEAF_PRODUCT_ID 35
+#define USB_CAN_R_PRODUCT_ID 39
+#define USB_LEAF_LITE_V2_PRODUCT_ID 288
+#define USB_MINI_PCIE_HS_PRODUCT_ID 289
+
+/* USB devices features */
+#define KVASER_HAS_SILENT_MODE BIT(0)
+#define KVASER_HAS_TXRX_ERRORS BIT(1)
+
+/* Message header size */
+#define MSG_HEADER_LEN 2
+
+/* Can message flags */
+#define MSG_FLAG_ERROR_FRAME BIT(0)
+#define MSG_FLAG_OVERRUN BIT(1)
+#define MSG_FLAG_NERR BIT(2)
+#define MSG_FLAG_WAKEUP BIT(3)
+#define MSG_FLAG_REMOTE_FRAME BIT(4)
+#define MSG_FLAG_RESERVED BIT(5)
+#define MSG_FLAG_TX_ACK BIT(6)
+#define MSG_FLAG_TX_REQUEST BIT(7)
+
+/* Can states */
+#define M16C_STATE_BUS_RESET BIT(0)
+#define M16C_STATE_BUS_ERROR BIT(4)
+#define M16C_STATE_BUS_PASSIVE BIT(5)
+#define M16C_STATE_BUS_OFF BIT(6)
+
+/* Can msg ids */
+#define CMD_RX_STD_MESSAGE 12
+#define CMD_TX_STD_MESSAGE 13
+#define CMD_RX_EXT_MESSAGE 14
+#define CMD_TX_EXT_MESSAGE 15
+#define CMD_SET_BUS_PARAMS 16
+#define CMD_GET_BUS_PARAMS 17
+#define CMD_GET_BUS_PARAMS_REPLY 18
+#define CMD_GET_CHIP_STATE 19
+#define CMD_CHIP_STATE_EVENT 20
+#define CMD_SET_CTRL_MODE 21
+#define CMD_GET_CTRL_MODE 22
+#define CMD_GET_CTRL_MODE_REPLY 23
+#define CMD_RESET_CHIP 24
+#define CMD_RESET_CARD 25
+#define CMD_START_CHIP 26
+#define CMD_START_CHIP_REPLY 27
+#define CMD_STOP_CHIP 28
+#define CMD_STOP_CHIP_REPLY 29
+#define CMD_GET_CARD_INFO2 32
+#define CMD_GET_CARD_INFO 34
+#define CMD_GET_CARD_INFO_REPLY 35
+#define CMD_GET_SOFTWARE_INFO 38
+#define CMD_GET_SOFTWARE_INFO_REPLY 39
+#define CMD_ERROR_EVENT 45
+#define CMD_FLUSH_QUEUE 48
+#define CMD_RESET_ERROR_COUNTER 49
+#define CMD_TX_ACKNOWLEDGE 50
+#define CMD_CAN_ERROR_EVENT 51
+#define CMD_USB_THROTTLE 77
+#define CMD_LOG_MESSAGE 106
+
+/* error factors */
+#define M16C_EF_ACKE BIT(0)
+#define M16C_EF_CRCE BIT(1)
+#define M16C_EF_FORME BIT(2)
+#define M16C_EF_STFE BIT(3)
+#define M16C_EF_BITE0 BIT(4)
+#define M16C_EF_BITE1 BIT(5)
+#define M16C_EF_RCVE BIT(6)
+#define M16C_EF_TRE BIT(7)
+
+/* bittiming parameters */
+#define KVASER_USB_TSEG1_MIN 1
+#define KVASER_USB_TSEG1_MAX 16
+#define KVASER_USB_TSEG2_MIN 1
+#define KVASER_USB_TSEG2_MAX 8
+#define KVASER_USB_SJW_MAX 4
+#define KVASER_USB_BRP_MIN 1
+#define KVASER_USB_BRP_MAX 64
+#define KVASER_USB_BRP_INC 1
+
+/* ctrl modes */
+#define KVASER_CTRL_MODE_NORMAL 1
+#define KVASER_CTRL_MODE_SILENT 2
+#define KVASER_CTRL_MODE_SELFRECEPTION 3
+#define KVASER_CTRL_MODE_OFF 4
+
+/* log message */
+#define KVASER_EXTENDED_FRAME BIT(31)
+
+struct kvaser_msg_simple {
+ u8 tid;
+ u8 channel;
+} __packed;
+
+struct kvaser_msg_cardinfo {
+ u8 tid;
+ u8 nchannels;
+ __le32 serial_number;
+ __le32 padding;
+ __le32 clock_resolution;
+ __le32 mfgdate;
+ u8 ean[8];
+ u8 hw_revision;
+ u8 usb_hs_mode;
+ __le16 padding2;
+} __packed;
+
+struct kvaser_msg_cardinfo2 {
+ u8 tid;
+ u8 channel;
+ u8 pcb_id[24];
+ __le32 oem_unlock_code;
+} __packed;
+
+struct kvaser_msg_softinfo {
+ u8 tid;
+ u8 channel;
+ __le32 sw_options;
+ __le32 fw_version;
+ __le16 max_outstanding_tx;
+ __le16 padding[9];
+} __packed;
+
+struct kvaser_msg_busparams {
+ u8 tid;
+ u8 channel;
+ __le32 bitrate;
+ u8 tseg1;
+ u8 tseg2;
+ u8 sjw;
+ u8 no_samp;
+} __packed;
+
+struct kvaser_msg_tx_can {
+ u8 channel;
+ u8 tid;
+ u8 msg[14];
+ u8 padding;
+ u8 flags;
+} __packed;
+
+struct kvaser_msg_rx_can {
+ u8 channel;
+ u8 flag;
+ __le16 time[3];
+ u8 msg[14];
+} __packed;
+
+struct kvaser_msg_chip_state_event {
+ u8 tid;
+ u8 channel;
+ __le16 time[3];
+ u8 tx_errors_count;
+ u8 rx_errors_count;
+ u8 status;
+ u8 padding[3];
+} __packed;
+
+struct kvaser_msg_tx_acknowledge {
+ u8 channel;
+ u8 tid;
+ __le16 time[3];
+ u8 flags;
+ u8 time_offset;
+} __packed;
+
+struct kvaser_msg_error_event {
+ u8 tid;
+ u8 flags;
+ __le16 time[3];
+ u8 channel;
+ u8 padding;
+ u8 tx_errors_count;
+ u8 rx_errors_count;
+ u8 status;
+ u8 error_factor;
+} __packed;
+
+struct kvaser_msg_ctrl_mode {
+ u8 tid;
+ u8 channel;
+ u8 ctrl_mode;
+ u8 padding[3];
+} __packed;
+
+struct kvaser_msg_flush_queue {
+ u8 tid;
+ u8 channel;
+ u8 flags;
+ u8 padding[3];
+} __packed;
+
+struct kvaser_msg_log_message {
+ u8 channel;
+ u8 flags;
+ __le16 time[3];
+ u8 dlc;
+ u8 time_offset;
+ __le32 id;
+ u8 data[8];
+} __packed;
+
+struct kvaser_msg {
+ u8 len;
+ u8 id;
+ union {
+ struct kvaser_msg_simple simple;
+ struct kvaser_msg_cardinfo cardinfo;
+ struct kvaser_msg_cardinfo2 cardinfo2;
+ struct kvaser_msg_softinfo softinfo;
+ struct kvaser_msg_busparams busparams;
+ struct kvaser_msg_tx_can tx_can;
+ struct kvaser_msg_rx_can rx_can;
+ struct kvaser_msg_chip_state_event chip_state_event;
+ struct kvaser_msg_tx_acknowledge tx_acknowledge;
+ struct kvaser_msg_error_event error_event;
+ struct kvaser_msg_ctrl_mode ctrl_mode;
+ struct kvaser_msg_flush_queue flush_queue;
+ struct kvaser_msg_log_message log_message;
+ } u;
+} __packed;
+
+struct kvaser_usb_tx_urb_context {
+ struct kvaser_usb_net_priv *priv;
+ u32 echo_index;
+ int dlc;
+};
+
+struct kvaser_usb {
+ struct usb_device *udev;
+ struct kvaser_usb_net_priv *nets[MAX_NET_DEVICES];
+
+ struct usb_endpoint_descriptor *bulk_in, *bulk_out;
+ struct usb_anchor rx_submitted;
+
+ u32 fw_version;
+ unsigned int nchannels;
+
+ bool rxinitdone;
+ void *rxbuf[MAX_RX_URBS];
+ dma_addr_t rxbuf_dma[MAX_RX_URBS];
+};
+
+struct kvaser_usb_net_priv {
+ struct can_priv can;
+
+ atomic_t active_tx_urbs;
+ struct usb_anchor tx_submitted;
+ struct kvaser_usb_tx_urb_context tx_contexts[MAX_TX_URBS];
+
+ struct completion start_comp, stop_comp;
+
+ struct kvaser_usb *dev;
+ struct net_device *netdev;
+ int channel;
+
+ struct can_berr_counter bec;
+};
+
+static const struct usb_device_id kvaser_usb_table[] = {
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LS_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_SWC_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LIN_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_LS_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_SWC_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_DEVEL_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSHS_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_UPRO_HSHS_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID) },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_OBDII_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS |
+ KVASER_HAS_SILENT_MODE },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSLS_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_CH_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_SPRO_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_MERCURY_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_LEAF_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, kvaser_usb_table);
+
+static inline int kvaser_usb_send_msg(const struct kvaser_usb *dev,
+ struct kvaser_msg *msg)
+{
+ int actual_len;
+
+ return usb_bulk_msg(dev->udev,
+ usb_sndbulkpipe(dev->udev,
+ dev->bulk_out->bEndpointAddress),
+ msg, msg->len, &actual_len,
+ USB_SEND_TIMEOUT);
+}
+
+static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id,
+ struct kvaser_msg *msg)
+{
+ struct kvaser_msg *tmp;
+ void *buf;
+ int actual_len;
+ int err;
+ int pos;
+ unsigned long to = jiffies + msecs_to_jiffies(USB_RECV_TIMEOUT);
+
+ buf = kzalloc(RX_BUFFER_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ do {
+ err = usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in->bEndpointAddress),
+ buf, RX_BUFFER_SIZE, &actual_len,
+ USB_RECV_TIMEOUT);
+ if (err < 0)
+ goto end;
+
+ pos = 0;
+ while (pos <= actual_len - MSG_HEADER_LEN) {
+ tmp = buf + pos;
+
+ if (!tmp->len)
+ break;
+
+ if (pos + tmp->len > actual_len) {
+ dev_err(dev->udev->dev.parent,
+ "Format error\n");
+ break;
+ }
+
+ if (tmp->id == id) {
+ memcpy(msg, tmp, tmp->len);
+ goto end;
+ }
+
+ pos += tmp->len;
+ }
+ } while (time_before(jiffies, to));
+
+ err = -EINVAL;
+
+end:
+ kfree(buf);
+
+ return err;
+}
+
+static int kvaser_usb_send_simple_msg(const struct kvaser_usb *dev,
+ u8 msg_id, int channel)
+{
+ struct kvaser_msg *msg;
+ int rc;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ msg->id = msg_id;
+ msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_simple);
+ msg->u.simple.channel = channel;
+ msg->u.simple.tid = 0xff;
+
+ rc = kvaser_usb_send_msg(dev, msg);
+
+ kfree(msg);
+ return rc;
+}
+
+static int kvaser_usb_get_software_info(struct kvaser_usb *dev)
+{
+ struct kvaser_msg msg;
+ int err;
+
+ err = kvaser_usb_send_simple_msg(dev, CMD_GET_SOFTWARE_INFO, 0);
+ if (err)
+ return err;
+
+ err = kvaser_usb_wait_msg(dev, CMD_GET_SOFTWARE_INFO_REPLY, &msg);
+ if (err)
+ return err;
+
+ dev->fw_version = le32_to_cpu(msg.u.softinfo.fw_version);
+
+ return 0;
+}
+
+static int kvaser_usb_get_card_info(struct kvaser_usb *dev)
+{
+ struct kvaser_msg msg;
+ int err;
+
+ err = kvaser_usb_send_simple_msg(dev, CMD_GET_CARD_INFO, 0);
+ if (err)
+ return err;
+
+ err = kvaser_usb_wait_msg(dev, CMD_GET_CARD_INFO_REPLY, &msg);
+ if (err)
+ return err;
+
+ dev->nchannels = msg.u.cardinfo.nchannels;
+ if (dev->nchannels > MAX_NET_DEVICES)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ struct net_device_stats *stats;
+ struct kvaser_usb_tx_urb_context *context;
+ struct kvaser_usb_net_priv *priv;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ u8 channel = msg->u.tx_acknowledge.channel;
+ u8 tid = msg->u.tx_acknowledge.tid;
+
+ if (channel >= dev->nchannels) {
+ dev_err(dev->udev->dev.parent,
+ "Invalid channel number (%d)\n", channel);
+ return;
+ }
+
+ priv = dev->nets[channel];
+
+ if (!netif_device_present(priv->netdev))
+ return;
+
+ stats = &priv->netdev->stats;
+
+ context = &priv->tx_contexts[tid % MAX_TX_URBS];
+
+ /* Sometimes the state change doesn't come after a bus-off event */
+ if (priv->can.restart_ms &&
+ (priv->can.state >= CAN_STATE_BUS_OFF)) {
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (skb) {
+ cf->can_id |= CAN_ERR_RESTARTED;
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ } else {
+ netdev_err(priv->netdev,
+ "No memory left for err_skb\n");
+ }
+
+ priv->can.can_stats.restarts++;
+ netif_carrier_on(priv->netdev);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ }
+
+ stats->tx_packets++;
+ stats->tx_bytes += context->dlc;
+ can_get_echo_skb(priv->netdev, context->echo_index);
+
+ context->echo_index = MAX_TX_URBS;
+ atomic_dec(&priv->active_tx_urbs);
+
+ netif_wake_queue(priv->netdev);
+}
+
+static void kvaser_usb_simple_msg_callback(struct urb *urb)
+{
+ struct net_device *netdev = urb->context;
+
+ kfree(urb->transfer_buffer);
+
+ if (urb->status)
+ netdev_warn(netdev, "urb status received: %d\n",
+ urb->status);
+}
+
+static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
+ u8 msg_id)
+{
+ struct kvaser_usb *dev = priv->dev;
+ struct net_device *netdev = priv->netdev;
+ struct kvaser_msg *msg;
+ struct urb *urb;
+ void *buf;
+ int err;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ return -ENOMEM;
+ }
+
+ buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
+ if (!buf) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ msg = (struct kvaser_msg *)buf;
+ msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_simple);
+ msg->id = msg_id;
+ msg->u.simple.channel = priv->channel;
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev,
+ dev->bulk_out->bEndpointAddress),
+ buf, msg->len,
+ kvaser_usb_simple_msg_callback, priv);
+ usb_anchor_urb(urb, &priv->tx_submitted);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err) {
+ netdev_err(netdev, "Error transmitting URB\n");
+ usb_unanchor_urb(urb);
+ usb_free_urb(urb);
+ kfree(buf);
+ return err;
+ }
+
+ usb_free_urb(urb);
+
+ return 0;
+}
+
+static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
+{
+ int i;
+
+ usb_kill_anchored_urbs(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_urbs, 0);
+
+ for (i = 0; i < MAX_TX_URBS; i++)
+ priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+}
+
+static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct net_device_stats *stats;
+ struct kvaser_usb_net_priv *priv;
+ unsigned int new_state;
+ u8 channel, status, txerr, rxerr, error_factor;
+
+ switch (msg->id) {
+ case CMD_CAN_ERROR_EVENT:
+ channel = msg->u.error_event.channel;
+ status = msg->u.error_event.status;
+ txerr = msg->u.error_event.tx_errors_count;
+ rxerr = msg->u.error_event.rx_errors_count;
+ error_factor = msg->u.error_event.error_factor;
+ break;
+ case CMD_LOG_MESSAGE:
+ channel = msg->u.log_message.channel;
+ status = msg->u.log_message.data[0];
+ txerr = msg->u.log_message.data[2];
+ rxerr = msg->u.log_message.data[3];
+ error_factor = msg->u.log_message.data[1];
+ break;
+ case CMD_CHIP_STATE_EVENT:
+ channel = msg->u.chip_state_event.channel;
+ status = msg->u.chip_state_event.status;
+ txerr = msg->u.chip_state_event.tx_errors_count;
+ rxerr = msg->u.chip_state_event.rx_errors_count;
+ error_factor = 0;
+ break;
+ default:
+ dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n",
+ msg->id);
+ return;
+ }
+
+ if (channel >= dev->nchannels) {
+ dev_err(dev->udev->dev.parent,
+ "Invalid channel number (%d)\n", channel);
+ return;
+ }
+
+ priv = dev->nets[channel];
+ stats = &priv->netdev->stats;
+
+ if (status & M16C_STATE_BUS_RESET) {
+ kvaser_usb_unlink_tx_urbs(priv);
+ return;
+ }
+
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (!skb) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ new_state = priv->can.state;
+
+ netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status);
+
+ if (status & M16C_STATE_BUS_OFF) {
+ cf->can_id |= CAN_ERR_BUSOFF;
+
+ priv->can.can_stats.bus_off++;
+ if (!priv->can.restart_ms)
+ kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP);
+
+ netif_carrier_off(priv->netdev);
+
+ new_state = CAN_STATE_BUS_OFF;
+ } else if (status & M16C_STATE_BUS_PASSIVE) {
+ if (priv->can.state != CAN_STATE_ERROR_PASSIVE) {
+ cf->can_id |= CAN_ERR_CRTL;
+
+ if (txerr || rxerr)
+ cf->data[1] = (txerr > rxerr)
+ ? CAN_ERR_CRTL_TX_PASSIVE
+ : CAN_ERR_CRTL_RX_PASSIVE;
+ else
+ cf->data[1] = CAN_ERR_CRTL_TX_PASSIVE |
+ CAN_ERR_CRTL_RX_PASSIVE;
+
+ priv->can.can_stats.error_passive++;
+ }
+
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ }
+
+ if (status == M16C_STATE_BUS_ERROR) {
+ if ((priv->can.state < CAN_STATE_ERROR_WARNING) &&
+ ((txerr >= 96) || (rxerr >= 96))) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (txerr > rxerr)
+ ? CAN_ERR_CRTL_TX_WARNING
+ : CAN_ERR_CRTL_RX_WARNING;
+
+ priv->can.can_stats.error_warning++;
+ new_state = CAN_STATE_ERROR_WARNING;
+ } else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) {
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_ACTIVE;
+
+ new_state = CAN_STATE_ERROR_ACTIVE;
+ }
+ }
+
+ if (!status) {
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_ACTIVE;
+
+ new_state = CAN_STATE_ERROR_ACTIVE;
+ }
+
+ if (priv->can.restart_ms &&
+ (priv->can.state >= CAN_STATE_BUS_OFF) &&
+ (new_state < CAN_STATE_BUS_OFF)) {
+ cf->can_id |= CAN_ERR_RESTARTED;
+ netif_carrier_on(priv->netdev);
+
+ priv->can.can_stats.restarts++;
+ }
+
+ if (error_factor) {
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+
+ if (error_factor & M16C_EF_ACKE)
+ cf->data[3] |= (CAN_ERR_PROT_LOC_ACK);
+ if (error_factor & M16C_EF_CRCE)
+ cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL);
+ if (error_factor & M16C_EF_FORME)
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ if (error_factor & M16C_EF_STFE)
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ if (error_factor & M16C_EF_BITE0)
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ if (error_factor & M16C_EF_BITE1)
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ if (error_factor & M16C_EF_TRE)
+ cf->data[2] |= CAN_ERR_PROT_TX;
+ }
+
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+
+ priv->bec.txerr = txerr;
+ priv->bec.rxerr = rxerr;
+
+ priv->can.state = new_state;
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
+ const struct kvaser_msg *msg)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct net_device_stats *stats = &priv->netdev->stats;
+
+ if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
+ MSG_FLAG_NERR)) {
+ netdev_err(priv->netdev, "Unknow error (flags: 0x%02x)\n",
+ msg->u.rx_can.flag);
+
+ stats->rx_errors++;
+ return;
+ }
+
+ if (msg->u.rx_can.flag & MSG_FLAG_OVERRUN) {
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (!skb) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ }
+}
+
+static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ struct kvaser_usb_net_priv *priv;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct net_device_stats *stats;
+ u8 channel = msg->u.rx_can.channel;
+
+ if (channel >= dev->nchannels) {
+ dev_err(dev->udev->dev.parent,
+ "Invalid channel number (%d)\n", channel);
+ return;
+ }
+
+ priv = dev->nets[channel];
+ stats = &priv->netdev->stats;
+
+ if ((msg->u.rx_can.flag & MSG_FLAG_ERROR_FRAME) &&
+ (msg->id == CMD_LOG_MESSAGE)) {
+ kvaser_usb_rx_error(dev, msg);
+ return;
+ } else if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
+ MSG_FLAG_NERR |
+ MSG_FLAG_OVERRUN)) {
+ kvaser_usb_rx_can_err(priv, msg);
+ return;
+ } else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) {
+ netdev_warn(priv->netdev,
+ "Unhandled frame (flags: 0x%02x)",
+ msg->u.rx_can.flag);
+ return;
+ }
+
+ skb = alloc_can_skb(priv->netdev, &cf);
+ if (!skb) {
+ stats->tx_dropped++;
+ return;
+ }
+
+ if (msg->id == CMD_LOG_MESSAGE) {
+ cf->can_id = le32_to_cpu(msg->u.log_message.id);
+ if (cf->can_id & KVASER_EXTENDED_FRAME)
+ cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG;
+ else
+ cf->can_id &= CAN_SFF_MASK;
+
+ cf->can_dlc = get_can_dlc(msg->u.log_message.dlc);
+
+ if (msg->u.log_message.flags & MSG_FLAG_REMOTE_FRAME)
+ cf->can_id |= CAN_RTR_FLAG;
+ else
+ memcpy(cf->data, &msg->u.log_message.data,
+ cf->can_dlc);
+ } else {
+ cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) |
+ (msg->u.rx_can.msg[1] & 0x3f);
+
+ if (msg->id == CMD_RX_EXT_MESSAGE) {
+ cf->can_id <<= 18;
+ cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) |
+ ((msg->u.rx_can.msg[3] & 0xff) << 6) |
+ (msg->u.rx_can.msg[4] & 0x3f);
+ cf->can_id |= CAN_EFF_FLAG;
+ }
+
+ cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]);
+
+ if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME)
+ cf->can_id |= CAN_RTR_FLAG;
+ else
+ memcpy(cf->data, &msg->u.rx_can.msg[6],
+ cf->can_dlc);
+ }
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ struct kvaser_usb_net_priv *priv;
+ u8 channel = msg->u.simple.channel;
+
+ if (channel >= dev->nchannels) {
+ dev_err(dev->udev->dev.parent,
+ "Invalid channel number (%d)\n", channel);
+ return;
+ }
+
+ priv = dev->nets[channel];
+
+ if (completion_done(&priv->start_comp) &&
+ netif_queue_stopped(priv->netdev)) {
+ netif_wake_queue(priv->netdev);
+ } else {
+ netif_start_queue(priv->netdev);
+ complete(&priv->start_comp);
+ }
+}
+
+static void kvaser_usb_stop_chip_reply(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ struct kvaser_usb_net_priv *priv;
+ u8 channel = msg->u.simple.channel;
+
+ if (channel >= dev->nchannels) {
+ dev_err(dev->udev->dev.parent,
+ "Invalid channel number (%d)\n", channel);
+ return;
+ }
+
+ priv = dev->nets[channel];
+
+ complete(&priv->stop_comp);
+}
+
+static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ switch (msg->id) {
+ case CMD_START_CHIP_REPLY:
+ kvaser_usb_start_chip_reply(dev, msg);
+ break;
+
+ case CMD_STOP_CHIP_REPLY:
+ kvaser_usb_stop_chip_reply(dev, msg);
+ break;
+
+ case CMD_RX_STD_MESSAGE:
+ case CMD_RX_EXT_MESSAGE:
+ case CMD_LOG_MESSAGE:
+ kvaser_usb_rx_can_msg(dev, msg);
+ break;
+
+ case CMD_CHIP_STATE_EVENT:
+ case CMD_CAN_ERROR_EVENT:
+ kvaser_usb_rx_error(dev, msg);
+ break;
+
+ case CMD_TX_ACKNOWLEDGE:
+ kvaser_usb_tx_acknowledge(dev, msg);
+ break;
+
+ default:
+ dev_warn(dev->udev->dev.parent,
+ "Unhandled message (%d)\n", msg->id);
+ break;
+ }
+}
+
+static void kvaser_usb_read_bulk_callback(struct urb *urb)
+{
+ struct kvaser_usb *dev = urb->context;
+ struct kvaser_msg *msg;
+ int pos = 0;
+ int err, i;
+
+ switch (urb->status) {
+ case 0:
+ break;
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default:
+ dev_info(dev->udev->dev.parent, "Rx URB aborted (%d)\n",
+ urb->status);
+ goto resubmit_urb;
+ }
+
+ while (pos <= urb->actual_length - MSG_HEADER_LEN) {
+ msg = urb->transfer_buffer + pos;
+
+ if (!msg->len)
+ break;
+
+ if (pos + msg->len > urb->actual_length) {
+ dev_err(dev->udev->dev.parent, "Format error\n");
+ break;
+ }
+
+ kvaser_usb_handle_message(dev, msg);
+
+ pos += msg->len;
+ }
+
+resubmit_urb:
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in->bEndpointAddress),
+ urb->transfer_buffer, RX_BUFFER_SIZE,
+ kvaser_usb_read_bulk_callback, dev);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err == -ENODEV) {
+ for (i = 0; i < dev->nchannels; i++) {
+ if (!dev->nets[i])
+ continue;
+
+ netif_device_detach(dev->nets[i]->netdev);
+ }
+ } else if (err) {
+ dev_err(dev->udev->dev.parent,
+ "Failed resubmitting read bulk urb: %d\n", err);
+ }
+
+ return;
+}
+
+static int kvaser_usb_setup_rx_urbs(struct kvaser_usb *dev)
+{
+ int i, err = 0;
+
+ if (dev->rxinitdone)
+ return 0;
+
+ for (i = 0; i < MAX_RX_URBS; i++) {
+ struct urb *urb = NULL;
+ u8 *buf = NULL;
+ dma_addr_t buf_dma;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ dev_warn(dev->udev->dev.parent,
+ "No memory left for URBs\n");
+ err = -ENOMEM;
+ break;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE,
+ GFP_KERNEL, &buf_dma);
+ if (!buf) {
+ dev_warn(dev->udev->dev.parent,
+ "No memory left for USB buffer\n");
+ usb_free_urb(urb);
+ err = -ENOMEM;
+ break;
+ }
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in->bEndpointAddress),
+ buf, RX_BUFFER_SIZE,
+ kvaser_usb_read_bulk_callback,
+ dev);
+ urb->transfer_dma = buf_dma;
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
+ buf_dma);
+ usb_free_urb(urb);
+ break;
+ }
+
+ dev->rxbuf[i] = buf;
+ dev->rxbuf_dma[i] = buf_dma;
+
+ usb_free_urb(urb);
+ }
+
+ if (i == 0) {
+ dev_warn(dev->udev->dev.parent,
+ "Cannot setup read URBs, error %d\n", err);
+ return err;
+ } else if (i < MAX_RX_URBS) {
+ dev_warn(dev->udev->dev.parent,
+ "RX performances may be slow\n");
+ }
+
+ dev->rxinitdone = true;
+
+ return 0;
+}
+
+static int kvaser_usb_set_opt_mode(const struct kvaser_usb_net_priv *priv)
+{
+ struct kvaser_msg *msg;
+ int rc;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ msg->id = CMD_SET_CTRL_MODE;
+ msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_ctrl_mode);
+ msg->u.ctrl_mode.tid = 0xff;
+ msg->u.ctrl_mode.channel = priv->channel;
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ msg->u.ctrl_mode.ctrl_mode = KVASER_CTRL_MODE_SILENT;
+ else
+ msg->u.ctrl_mode.ctrl_mode = KVASER_CTRL_MODE_NORMAL;
+
+ rc = kvaser_usb_send_msg(priv->dev, msg);
+
+ kfree(msg);
+ return rc;
+}
+
+static int kvaser_usb_start_chip(struct kvaser_usb_net_priv *priv)
+{
+ int err;
+
+ init_completion(&priv->start_comp);
+
+ err = kvaser_usb_send_simple_msg(priv->dev, CMD_START_CHIP,
+ priv->channel);
+ if (err)
+ return err;
+
+ if (!wait_for_completion_timeout(&priv->start_comp,
+ msecs_to_jiffies(START_TIMEOUT)))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int kvaser_usb_open(struct net_device *netdev)
+{
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ struct kvaser_usb *dev = priv->dev;
+ int err;
+
+ err = open_candev(netdev);
+ if (err)
+ return err;
+
+ err = kvaser_usb_setup_rx_urbs(dev);
+ if (err)
+ goto error;
+
+ err = kvaser_usb_set_opt_mode(priv);
+ if (err)
+ goto error;
+
+ err = kvaser_usb_start_chip(priv);
+ if (err) {
+ netdev_warn(netdev, "Cannot start device, error %d\n", err);
+ goto error;
+ }
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ return 0;
+
+error:
+ close_candev(netdev);
+ return err;
+}
+
+static void kvaser_usb_unlink_all_urbs(struct kvaser_usb *dev)
+{
+ int i;
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+
+ for (i = 0; i < MAX_RX_URBS; i++)
+ usb_free_coherent(dev->udev, RX_BUFFER_SIZE,
+ dev->rxbuf[i],
+ dev->rxbuf_dma[i]);
+
+ for (i = 0; i < MAX_NET_DEVICES; i++) {
+ struct kvaser_usb_net_priv *priv = dev->nets[i];
+
+ if (priv)
+ kvaser_usb_unlink_tx_urbs(priv);
+ }
+}
+
+static int kvaser_usb_stop_chip(struct kvaser_usb_net_priv *priv)
+{
+ int err;
+
+ init_completion(&priv->stop_comp);
+
+ err = kvaser_usb_send_simple_msg(priv->dev, CMD_STOP_CHIP,
+ priv->channel);
+ if (err)
+ return err;
+
+ if (!wait_for_completion_timeout(&priv->stop_comp,
+ msecs_to_jiffies(STOP_TIMEOUT)))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int kvaser_usb_flush_queue(struct kvaser_usb_net_priv *priv)
+{
+ struct kvaser_msg *msg;
+ int rc;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ msg->id = CMD_FLUSH_QUEUE;
+ msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_flush_queue);
+ msg->u.flush_queue.channel = priv->channel;
+ msg->u.flush_queue.flags = 0x00;
+
+ rc = kvaser_usb_send_msg(priv->dev, msg);
+
+ kfree(msg);
+ return rc;
+}
+
+static int kvaser_usb_close(struct net_device *netdev)
+{
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ struct kvaser_usb *dev = priv->dev;
+ int err;
+
+ netif_stop_queue(netdev);
+
+ err = kvaser_usb_flush_queue(priv);
+ if (err)
+ netdev_warn(netdev, "Cannot flush queue, error %d\n", err);
+
+ if (kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, priv->channel))
+ netdev_warn(netdev, "Cannot reset card, error %d\n", err);
+
+ err = kvaser_usb_stop_chip(priv);
+ if (err)
+ netdev_warn(netdev, "Cannot stop device, error %d\n", err);
+
+ priv->can.state = CAN_STATE_STOPPED;
+ close_candev(priv->netdev);
+
+ return 0;
+}
+
+static void kvaser_usb_write_bulk_callback(struct urb *urb)
+{
+ struct kvaser_usb_tx_urb_context *context = urb->context;
+ struct kvaser_usb_net_priv *priv;
+ struct net_device *netdev;
+
+ if (WARN_ON(!context))
+ return;
+
+ priv = context->priv;
+ netdev = priv->netdev;
+
+ kfree(urb->transfer_buffer);
+
+ if (!netif_device_present(netdev))
+ return;
+
+ if (urb->status)
+ netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
+}
+
+static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ struct kvaser_usb *dev = priv->dev;
+ struct net_device_stats *stats = &netdev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ struct kvaser_usb_tx_urb_context *context = NULL;
+ struct urb *urb;
+ void *buf;
+ struct kvaser_msg *msg;
+ int i, err;
+ int ret = NETDEV_TX_OK;
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ stats->tx_dropped++;
+ goto nourbmem;
+ }
+
+ buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC);
+ if (!buf) {
+ stats->tx_dropped++;
+ goto nobufmem;
+ }
+
+ msg = buf;
+ msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_tx_can);
+ msg->u.tx_can.flags = 0;
+ msg->u.tx_can.channel = priv->channel;
+
+ if (cf->can_id & CAN_EFF_FLAG) {
+ msg->id = CMD_TX_EXT_MESSAGE;
+ msg->u.tx_can.msg[0] = (cf->can_id >> 24) & 0x1f;
+ msg->u.tx_can.msg[1] = (cf->can_id >> 18) & 0x3f;
+ msg->u.tx_can.msg[2] = (cf->can_id >> 14) & 0x0f;
+ msg->u.tx_can.msg[3] = (cf->can_id >> 6) & 0xff;
+ msg->u.tx_can.msg[4] = cf->can_id & 0x3f;
+ } else {
+ msg->id = CMD_TX_STD_MESSAGE;
+ msg->u.tx_can.msg[0] = (cf->can_id >> 6) & 0x1f;
+ msg->u.tx_can.msg[1] = cf->can_id & 0x3f;
+ }
+
+ msg->u.tx_can.msg[5] = cf->can_dlc;
+ memcpy(&msg->u.tx_can.msg[6], cf->data, cf->can_dlc);
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ msg->u.tx_can.flags |= MSG_FLAG_REMOTE_FRAME;
+
+ for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) {
+ if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
+ context = &priv->tx_contexts[i];
+ break;
+ }
+ }
+
+ if (!context) {
+ netdev_warn(netdev, "cannot find free context\n");
+ ret = NETDEV_TX_BUSY;
+ goto releasebuf;
+ }
+
+ context->priv = priv;
+ context->echo_index = i;
+ context->dlc = cf->can_dlc;
+
+ msg->u.tx_can.tid = context->echo_index;
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev,
+ dev->bulk_out->bEndpointAddress),
+ buf, msg->len,
+ kvaser_usb_write_bulk_callback, context);
+ usb_anchor_urb(urb, &priv->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, context->echo_index);
+
+ atomic_inc(&priv->active_tx_urbs);
+
+ if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
+ netif_stop_queue(netdev);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err)) {
+ can_free_echo_skb(netdev, context->echo_index);
+
+ skb = NULL; /* set to NULL to avoid double free in
+ * dev_kfree_skb(skb) */
+
+ atomic_dec(&priv->active_tx_urbs);
+ usb_unanchor_urb(urb);
+
+ stats->tx_dropped++;
+
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ else
+ netdev_warn(netdev, "Failed tx_urb %d\n", err);
+
+ goto releasebuf;
+ }
+
+ usb_free_urb(urb);
+
+ return NETDEV_TX_OK;
+
+releasebuf:
+ kfree(buf);
+nobufmem:
+ usb_free_urb(urb);
+nourbmem:
+ dev_kfree_skb(skb);
+ return ret;
+}
+
+static const struct net_device_ops kvaser_usb_netdev_ops = {
+ .ndo_open = kvaser_usb_open,
+ .ndo_stop = kvaser_usb_close,
+ .ndo_start_xmit = kvaser_usb_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static const struct can_bittiming_const kvaser_usb_bittiming_const = {
+ .name = "kvaser_usb",
+ .tseg1_min = KVASER_USB_TSEG1_MIN,
+ .tseg1_max = KVASER_USB_TSEG1_MAX,
+ .tseg2_min = KVASER_USB_TSEG2_MIN,
+ .tseg2_max = KVASER_USB_TSEG2_MAX,
+ .sjw_max = KVASER_USB_SJW_MAX,
+ .brp_min = KVASER_USB_BRP_MIN,
+ .brp_max = KVASER_USB_BRP_MAX,
+ .brp_inc = KVASER_USB_BRP_INC,
+};
+
+static int kvaser_usb_set_bittiming(struct net_device *netdev)
+{
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ struct kvaser_usb *dev = priv->dev;
+ struct kvaser_msg *msg;
+ int rc;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ msg->id = CMD_SET_BUS_PARAMS;
+ msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_busparams);
+ msg->u.busparams.channel = priv->channel;
+ msg->u.busparams.tid = 0xff;
+ msg->u.busparams.bitrate = cpu_to_le32(bt->bitrate);
+ msg->u.busparams.sjw = bt->sjw;
+ msg->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1;
+ msg->u.busparams.tseg2 = bt->phase_seg2;
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ msg->u.busparams.no_samp = 3;
+ else
+ msg->u.busparams.no_samp = 1;
+
+ rc = kvaser_usb_send_msg(dev, msg);
+
+ kfree(msg);
+ return rc;
+}
+
+static int kvaser_usb_set_mode(struct net_device *netdev,
+ enum can_mode mode)
+{
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+ int err;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ err = kvaser_usb_simple_msg_async(priv, CMD_START_CHIP);
+ if (err)
+ return err;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int kvaser_usb_get_berr_counter(const struct net_device *netdev,
+ struct can_berr_counter *bec)
+{
+ struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+
+ *bec = priv->bec;
+
+ return 0;
+}
+
+static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+{
+ int i;
+
+ for (i = 0; i < dev->nchannels; i++) {
+ if (!dev->nets[i])
+ continue;
+
+ unregister_netdev(dev->nets[i]->netdev);
+ }
+
+ kvaser_usb_unlink_all_urbs(dev);
+
+ for (i = 0; i < dev->nchannels; i++) {
+ if (!dev->nets[i])
+ continue;
+
+ free_candev(dev->nets[i]->netdev);
+ }
+}
+
+static int kvaser_usb_init_one(struct usb_interface *intf,
+ const struct usb_device_id *id, int channel)
+{
+ struct kvaser_usb *dev = usb_get_intfdata(intf);
+ struct net_device *netdev;
+ struct kvaser_usb_net_priv *priv;
+ int i, err;
+
+ netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
+ if (!netdev) {
+ dev_err(&intf->dev, "Cannot alloc candev\n");
+ return -ENOMEM;
+ }
+
+ priv = netdev_priv(netdev);
+
+ init_completion(&priv->start_comp);
+ init_completion(&priv->stop_comp);
+
+ init_usb_anchor(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_urbs, 0);
+
+ for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++)
+ priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+
+ priv->dev = dev;
+ priv->netdev = netdev;
+ priv->channel = channel;
+
+ priv->can.state = CAN_STATE_STOPPED;
+ priv->can.clock.freq = CAN_USB_CLOCK;
+ priv->can.bittiming_const = &kvaser_usb_bittiming_const;
+ priv->can.do_set_bittiming = kvaser_usb_set_bittiming;
+ priv->can.do_set_mode = kvaser_usb_set_mode;
+ if (id->driver_info & KVASER_HAS_TXRX_ERRORS)
+ priv->can.do_get_berr_counter = kvaser_usb_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+ if (id->driver_info & KVASER_HAS_SILENT_MODE)
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY;
+
+ netdev->flags |= IFF_ECHO;
+
+ netdev->netdev_ops = &kvaser_usb_netdev_ops;
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+ netdev->dev_id = channel;
+
+ dev->nets[channel] = priv;
+
+ err = register_candev(netdev);
+ if (err) {
+ dev_err(&intf->dev, "Failed to register can device\n");
+ free_candev(netdev);
+ dev->nets[channel] = NULL;
+ return err;
+ }
+
+ netdev_dbg(netdev, "device registered\n");
+
+ return 0;
+}
+
+static int kvaser_usb_get_endpoints(const struct usb_interface *intf,
+ struct usb_endpoint_descriptor **in,
+ struct usb_endpoint_descriptor **out)
+{
+ const struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int i;
+
+ iface_desc = &intf->altsetting[0];
+
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (!*in && usb_endpoint_is_bulk_in(endpoint))
+ *in = endpoint;
+
+ if (!*out && usb_endpoint_is_bulk_out(endpoint))
+ *out = endpoint;
+
+ /* use first bulk endpoint for in and out */
+ if (*in && *out)
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+static int kvaser_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct kvaser_usb *dev;
+ int err = -ENOMEM;
+ int i;
+
+ dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ err = kvaser_usb_get_endpoints(intf, &dev->bulk_in, &dev->bulk_out);
+ if (err) {
+ dev_err(&intf->dev, "Cannot get usb endpoint(s)");
+ return err;
+ }
+
+ dev->udev = interface_to_usbdev(intf);
+
+ init_usb_anchor(&dev->rx_submitted);
+
+ usb_set_intfdata(intf, dev);
+
+ for (i = 0; i < MAX_NET_DEVICES; i++)
+ kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i);
+
+ err = kvaser_usb_get_software_info(dev);
+ if (err) {
+ dev_err(&intf->dev,
+ "Cannot get software infos, error %d\n", err);
+ return err;
+ }
+
+ err = kvaser_usb_get_card_info(dev);
+ if (err) {
+ dev_err(&intf->dev,
+ "Cannot get card infos, error %d\n", err);
+ return err;
+ }
+
+ dev_dbg(&intf->dev, "Firmware version: %d.%d.%d\n",
+ ((dev->fw_version >> 24) & 0xff),
+ ((dev->fw_version >> 16) & 0xff),
+ (dev->fw_version & 0xffff));
+
+ for (i = 0; i < dev->nchannels; i++) {
+ err = kvaser_usb_init_one(intf, id, i);
+ if (err) {
+ kvaser_usb_remove_interfaces(dev);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+static void kvaser_usb_disconnect(struct usb_interface *intf)
+{
+ struct kvaser_usb *dev = usb_get_intfdata(intf);
+
+ usb_set_intfdata(intf, NULL);
+
+ if (!dev)
+ return;
+
+ kvaser_usb_remove_interfaces(dev);
+}
+
+static struct usb_driver kvaser_usb_driver = {
+ .name = "kvaser_usb",
+ .probe = kvaser_usb_probe,
+ .disconnect = kvaser_usb_disconnect,
+ .id_table = kvaser_usb_table,
+};
+
+module_usb_driver(kvaser_usb_driver);
+
+MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
+MODULE_DESCRIPTION("CAN driver for Kvaser CAN/USB devices");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/usb/peak_usb/Makefile b/drivers/net/can/usb/peak_usb/Makefile
new file mode 100644
index 00000000000..1aefbc88d64
--- /dev/null
+++ b/drivers/net/can/usb/peak_usb/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CAN_PEAK_USB) += peak_usb.o
+peak_usb-y = pcan_usb_core.o pcan_usb.o pcan_usb_pro.o
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
new file mode 100644
index 00000000000..925ab8ec932
--- /dev/null
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -0,0 +1,903 @@
+/*
+ * CAN driver for PEAK System PCAN-USB adapter
+ * Derived from the PCAN project file driver/src/pcan_usb.c
+ *
+ * Copyright (C) 2003-2010 PEAK System-Technik GmbH
+ * Copyright (C) 2011-2012 Stephane Grosjean <s.grosjean@peak-system.com>
+ *
+ * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+#include <linux/module.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#include "pcan_usb_core.h"
+
+MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB adapter");
+
+/* PCAN-USB Endpoints */
+#define PCAN_USB_EP_CMDOUT 1
+#define PCAN_USB_EP_CMDIN (PCAN_USB_EP_CMDOUT | USB_DIR_IN)
+#define PCAN_USB_EP_MSGOUT 2
+#define PCAN_USB_EP_MSGIN (PCAN_USB_EP_MSGOUT | USB_DIR_IN)
+
+/* PCAN-USB command struct */
+#define PCAN_USB_CMD_FUNC 0
+#define PCAN_USB_CMD_NUM 1
+#define PCAN_USB_CMD_ARGS 2
+#define PCAN_USB_CMD_ARGS_LEN 14
+#define PCAN_USB_CMD_LEN (PCAN_USB_CMD_ARGS + \
+ PCAN_USB_CMD_ARGS_LEN)
+
+/* PCAN-USB command timeout (ms.) */
+#define PCAN_USB_COMMAND_TIMEOUT 1000
+
+/* PCAN-USB startup timeout (ms.) */
+#define PCAN_USB_STARTUP_TIMEOUT 10
+
+/* PCAN-USB rx/tx buffers size */
+#define PCAN_USB_RX_BUFFER_SIZE 64
+#define PCAN_USB_TX_BUFFER_SIZE 64
+
+#define PCAN_USB_MSG_HEADER_LEN 2
+
+/* PCAN-USB adapter internal clock (MHz) */
+#define PCAN_USB_CRYSTAL_HZ 16000000
+
+/* PCAN-USB USB message record status/len field */
+#define PCAN_USB_STATUSLEN_TIMESTAMP (1 << 7)
+#define PCAN_USB_STATUSLEN_INTERNAL (1 << 6)
+#define PCAN_USB_STATUSLEN_EXT_ID (1 << 5)
+#define PCAN_USB_STATUSLEN_RTR (1 << 4)
+#define PCAN_USB_STATUSLEN_DLC (0xf)
+
+/* PCAN-USB error flags */
+#define PCAN_USB_ERROR_TXFULL 0x01
+#define PCAN_USB_ERROR_RXQOVR 0x02
+#define PCAN_USB_ERROR_BUS_LIGHT 0x04
+#define PCAN_USB_ERROR_BUS_HEAVY 0x08
+#define PCAN_USB_ERROR_BUS_OFF 0x10
+#define PCAN_USB_ERROR_RXQEMPTY 0x20
+#define PCAN_USB_ERROR_QOVR 0x40
+#define PCAN_USB_ERROR_TXQFULL 0x80
+
+/* SJA1000 modes */
+#define SJA1000_MODE_NORMAL 0x00
+#define SJA1000_MODE_INIT 0x01
+
+/*
+ * tick duration = 42.666 us =>
+ * (tick_number * 44739243) >> 20 ~ (tick_number * 42666) / 1000
+ * accuracy = 10^-7
+ */
+#define PCAN_USB_TS_DIV_SHIFTER 20
+#define PCAN_USB_TS_US_PER_TICK 44739243
+
+/* PCAN-USB messages record types */
+#define PCAN_USB_REC_ERROR 1
+#define PCAN_USB_REC_ANALOG 2
+#define PCAN_USB_REC_BUSLOAD 3
+#define PCAN_USB_REC_TS 4
+#define PCAN_USB_REC_BUSEVT 5
+
+/* private to PCAN-USB adapter */
+struct pcan_usb {
+ struct peak_usb_device dev;
+ struct peak_time_ref time_ref;
+ struct timer_list restart_timer;
+};
+
+/* incoming message context for decoding */
+struct pcan_usb_msg_context {
+ u16 ts16;
+ u8 prev_ts8;
+ u8 *ptr;
+ u8 *end;
+ u8 rec_cnt;
+ u8 rec_idx;
+ u8 rec_data_idx;
+ struct net_device *netdev;
+ struct pcan_usb *pdev;
+};
+
+/*
+ * send a command
+ */
+static int pcan_usb_send_cmd(struct peak_usb_device *dev, u8 f, u8 n, u8 *p)
+{
+ int err;
+ int actual_length;
+
+ /* usb device unregistered? */
+ if (!(dev->state & PCAN_USB_STATE_CONNECTED))
+ return 0;
+
+ dev->cmd_buf[PCAN_USB_CMD_FUNC] = f;
+ dev->cmd_buf[PCAN_USB_CMD_NUM] = n;
+
+ if (p)
+ memcpy(dev->cmd_buf + PCAN_USB_CMD_ARGS,
+ p, PCAN_USB_CMD_ARGS_LEN);
+
+ err = usb_bulk_msg(dev->udev,
+ usb_sndbulkpipe(dev->udev, PCAN_USB_EP_CMDOUT),
+ dev->cmd_buf, PCAN_USB_CMD_LEN, &actual_length,
+ PCAN_USB_COMMAND_TIMEOUT);
+ if (err)
+ netdev_err(dev->netdev,
+ "sending cmd f=0x%x n=0x%x failure: %d\n",
+ f, n, err);
+ return err;
+}
+
+/*
+ * send a command then wait for its response
+ */
+static int pcan_usb_wait_rsp(struct peak_usb_device *dev, u8 f, u8 n, u8 *p)
+{
+ int err;
+ int actual_length;
+
+ /* usb device unregistered? */
+ if (!(dev->state & PCAN_USB_STATE_CONNECTED))
+ return 0;
+
+ /* first, send command */
+ err = pcan_usb_send_cmd(dev, f, n, NULL);
+ if (err)
+ return err;
+
+ err = usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev, PCAN_USB_EP_CMDIN),
+ dev->cmd_buf, PCAN_USB_CMD_LEN, &actual_length,
+ PCAN_USB_COMMAND_TIMEOUT);
+ if (err)
+ netdev_err(dev->netdev,
+ "waiting rsp f=0x%x n=0x%x failure: %d\n", f, n, err);
+ else if (p)
+ memcpy(p, dev->cmd_buf + PCAN_USB_CMD_ARGS,
+ PCAN_USB_CMD_ARGS_LEN);
+
+ return err;
+}
+
+static int pcan_usb_set_sja1000(struct peak_usb_device *dev, u8 mode)
+{
+ u8 args[PCAN_USB_CMD_ARGS_LEN] = {
+ [1] = mode,
+ };
+
+ return pcan_usb_send_cmd(dev, 9, 2, args);
+}
+
+static int pcan_usb_set_bus(struct peak_usb_device *dev, u8 onoff)
+{
+ u8 args[PCAN_USB_CMD_ARGS_LEN] = {
+ [0] = !!onoff,
+ };
+
+ return pcan_usb_send_cmd(dev, 3, 2, args);
+}
+
+static int pcan_usb_set_silent(struct peak_usb_device *dev, u8 onoff)
+{
+ u8 args[PCAN_USB_CMD_ARGS_LEN] = {
+ [0] = !!onoff,
+ };
+
+ return pcan_usb_send_cmd(dev, 3, 3, args);
+}
+
+static int pcan_usb_set_ext_vcc(struct peak_usb_device *dev, u8 onoff)
+{
+ u8 args[PCAN_USB_CMD_ARGS_LEN] = {
+ [0] = !!onoff,
+ };
+
+ return pcan_usb_send_cmd(dev, 10, 2, args);
+}
+
+/*
+ * set bittiming value to can
+ */
+static int pcan_usb_set_bittiming(struct peak_usb_device *dev,
+ struct can_bittiming *bt)
+{
+ u8 args[PCAN_USB_CMD_ARGS_LEN];
+ u8 btr0, btr1;
+
+ btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+ btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+ (((bt->phase_seg2 - 1) & 0x7) << 4);
+ if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ btr1 |= 0x80;
+
+ netdev_info(dev->netdev, "setting BTR0=0x%02x BTR1=0x%02x\n",
+ btr0, btr1);
+
+ args[0] = btr1;
+ args[1] = btr0;
+
+ return pcan_usb_send_cmd(dev, 1, 2, args);
+}
+
+/*
+ * init/reset can
+ */
+static int pcan_usb_write_mode(struct peak_usb_device *dev, u8 onoff)
+{
+ int err;
+
+ err = pcan_usb_set_bus(dev, onoff);
+ if (err)
+ return err;
+
+ if (!onoff) {
+ err = pcan_usb_set_sja1000(dev, SJA1000_MODE_INIT);
+ } else {
+ /* the PCAN-USB needs time to init */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(PCAN_USB_STARTUP_TIMEOUT));
+ }
+
+ return err;
+}
+
+/*
+ * handle end of waiting for the device to reset
+ */
+static void pcan_usb_restart(unsigned long arg)
+{
+ /* notify candev and netdev */
+ peak_usb_restart_complete((struct peak_usb_device *)arg);
+}
+
+/*
+ * handle the submission of the restart urb
+ */
+static void pcan_usb_restart_pending(struct urb *urb)
+{
+ struct pcan_usb *pdev = urb->context;
+
+ /* the PCAN-USB needs time to restart */
+ mod_timer(&pdev->restart_timer,
+ jiffies + msecs_to_jiffies(PCAN_USB_STARTUP_TIMEOUT));
+
+ /* can delete usb resources */
+ peak_usb_async_complete(urb);
+}
+
+/*
+ * handle asynchronous restart
+ */
+static int pcan_usb_restart_async(struct peak_usb_device *dev, struct urb *urb,
+ u8 *buf)
+{
+ struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev);
+
+ if (timer_pending(&pdev->restart_timer))
+ return -EBUSY;
+
+ /* set bus on */
+ buf[PCAN_USB_CMD_FUNC] = 3;
+ buf[PCAN_USB_CMD_NUM] = 2;
+ buf[PCAN_USB_CMD_ARGS] = 1;
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev, PCAN_USB_EP_CMDOUT),
+ buf, PCAN_USB_CMD_LEN,
+ pcan_usb_restart_pending, pdev);
+
+ return usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+/*
+ * read serial number from device
+ */
+static int pcan_usb_get_serial(struct peak_usb_device *dev, u32 *serial_number)
+{
+ u8 args[PCAN_USB_CMD_ARGS_LEN];
+ int err;
+
+ err = pcan_usb_wait_rsp(dev, 6, 1, args);
+ if (err) {
+ netdev_err(dev->netdev, "getting serial failure: %d\n", err);
+ } else if (serial_number) {
+ u32 tmp32;
+
+ memcpy(&tmp32, args, 4);
+ *serial_number = le32_to_cpu(tmp32);
+ }
+
+ return err;
+}
+
+/*
+ * read device id from device
+ */
+static int pcan_usb_get_device_id(struct peak_usb_device *dev, u32 *device_id)
+{
+ u8 args[PCAN_USB_CMD_ARGS_LEN];
+ int err;
+
+ err = pcan_usb_wait_rsp(dev, 4, 1, args);
+ if (err)
+ netdev_err(dev->netdev, "getting device id failure: %d\n", err);
+ else if (device_id)
+ *device_id = args[0];
+
+ return err;
+}
+
+/*
+ * update current time ref with received timestamp
+ */
+static int pcan_usb_update_ts(struct pcan_usb_msg_context *mc)
+{
+ u16 tmp16;
+
+ if ((mc->ptr+2) > mc->end)
+ return -EINVAL;
+
+ memcpy(&tmp16, mc->ptr, 2);
+
+ mc->ts16 = le16_to_cpu(tmp16);
+
+ if (mc->rec_idx > 0)
+ peak_usb_update_ts_now(&mc->pdev->time_ref, mc->ts16);
+ else
+ peak_usb_set_ts_now(&mc->pdev->time_ref, mc->ts16);
+
+ return 0;
+}
+
+/*
+ * decode received timestamp
+ */
+static int pcan_usb_decode_ts(struct pcan_usb_msg_context *mc, u8 first_packet)
+{
+ /* only 1st packet supplies a word timestamp */
+ if (first_packet) {
+ u16 tmp16;
+
+ if ((mc->ptr + 2) > mc->end)
+ return -EINVAL;
+
+ memcpy(&tmp16, mc->ptr, 2);
+ mc->ptr += 2;
+
+ mc->ts16 = le16_to_cpu(tmp16);
+ mc->prev_ts8 = mc->ts16 & 0x00ff;
+ } else {
+ u8 ts8;
+
+ if ((mc->ptr + 1) > mc->end)
+ return -EINVAL;
+
+ ts8 = *mc->ptr++;
+
+ if (ts8 < mc->prev_ts8)
+ mc->ts16 += 0x100;
+
+ mc->ts16 &= 0xff00;
+ mc->ts16 |= ts8;
+ mc->prev_ts8 = ts8;
+ }
+
+ return 0;
+}
+
+static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
+ u8 status_len)
+{
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ struct timeval tv;
+ enum can_state new_state;
+
+ /* ignore this error until 1st ts received */
+ if (n == PCAN_USB_ERROR_QOVR)
+ if (!mc->pdev->time_ref.tick_count)
+ return 0;
+
+ new_state = mc->pdev->dev.can.state;
+
+ switch (mc->pdev->dev.can.state) {
+ case CAN_STATE_ERROR_ACTIVE:
+ if (n & PCAN_USB_ERROR_BUS_LIGHT) {
+ new_state = CAN_STATE_ERROR_WARNING;
+ break;
+ }
+
+ case CAN_STATE_ERROR_WARNING:
+ if (n & PCAN_USB_ERROR_BUS_HEAVY) {
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ break;
+ }
+ if (n & PCAN_USB_ERROR_BUS_OFF) {
+ new_state = CAN_STATE_BUS_OFF;
+ break;
+ }
+ if (n & (PCAN_USB_ERROR_RXQOVR | PCAN_USB_ERROR_QOVR)) {
+ /*
+ * trick to bypass next comparison and process other
+ * errors
+ */
+ new_state = CAN_STATE_MAX;
+ break;
+ }
+ if ((n & PCAN_USB_ERROR_BUS_LIGHT) == 0) {
+ /* no error (back to active state) */
+ mc->pdev->dev.can.state = CAN_STATE_ERROR_ACTIVE;
+ return 0;
+ }
+ break;
+
+ case CAN_STATE_ERROR_PASSIVE:
+ if (n & PCAN_USB_ERROR_BUS_OFF) {
+ new_state = CAN_STATE_BUS_OFF;
+ break;
+ }
+ if (n & PCAN_USB_ERROR_BUS_LIGHT) {
+ new_state = CAN_STATE_ERROR_WARNING;
+ break;
+ }
+ if (n & (PCAN_USB_ERROR_RXQOVR | PCAN_USB_ERROR_QOVR)) {
+ /*
+ * trick to bypass next comparison and process other
+ * errors
+ */
+ new_state = CAN_STATE_MAX;
+ break;
+ }
+
+ if ((n & PCAN_USB_ERROR_BUS_HEAVY) == 0) {
+ /* no error (back to active state) */
+ mc->pdev->dev.can.state = CAN_STATE_ERROR_ACTIVE;
+ return 0;
+ }
+ break;
+
+ default:
+ /* do nothing waiting for restart */
+ return 0;
+ }
+
+ /* donot post any error if current state didn't change */
+ if (mc->pdev->dev.can.state == new_state)
+ return 0;
+
+ /* allocate an skb to store the error frame */
+ skb = alloc_can_err_skb(mc->netdev, &cf);
+ if (!skb)
+ return -ENOMEM;
+
+ switch (new_state) {
+ case CAN_STATE_BUS_OFF:
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(mc->netdev);
+ break;
+
+ case CAN_STATE_ERROR_PASSIVE:
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE |
+ CAN_ERR_CRTL_RX_PASSIVE;
+ mc->pdev->dev.can.can_stats.error_passive++;
+ break;
+
+ case CAN_STATE_ERROR_WARNING:
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] |= CAN_ERR_CRTL_TX_WARNING |
+ CAN_ERR_CRTL_RX_WARNING;
+ mc->pdev->dev.can.can_stats.error_warning++;
+ break;
+
+ default:
+ /* CAN_STATE_MAX (trick to handle other errors) */
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+ mc->netdev->stats.rx_over_errors++;
+ mc->netdev->stats.rx_errors++;
+
+ new_state = mc->pdev->dev.can.state;
+ break;
+ }
+
+ mc->pdev->dev.can.state = new_state;
+
+ if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
+ struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb);
+
+ peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv);
+ hwts->hwtstamp = timeval_to_ktime(tv);
+ }
+
+ netif_rx(skb);
+ mc->netdev->stats.rx_packets++;
+ mc->netdev->stats.rx_bytes += cf->can_dlc;
+
+ return 0;
+}
+
+/*
+ * decode non-data usb message
+ */
+static int pcan_usb_decode_status(struct pcan_usb_msg_context *mc,
+ u8 status_len)
+{
+ u8 rec_len = status_len & PCAN_USB_STATUSLEN_DLC;
+ u8 f, n;
+ int err;
+
+ /* check whether function and number can be read */
+ if ((mc->ptr + 2) > mc->end)
+ return -EINVAL;
+
+ f = mc->ptr[PCAN_USB_CMD_FUNC];
+ n = mc->ptr[PCAN_USB_CMD_NUM];
+ mc->ptr += PCAN_USB_CMD_ARGS;
+
+ if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
+ int err = pcan_usb_decode_ts(mc, !mc->rec_idx);
+
+ if (err)
+ return err;
+ }
+
+ switch (f) {
+ case PCAN_USB_REC_ERROR:
+ err = pcan_usb_decode_error(mc, n, status_len);
+ if (err)
+ return err;
+ break;
+
+ case PCAN_USB_REC_ANALOG:
+ /* analog values (ignored) */
+ rec_len = 2;
+ break;
+
+ case PCAN_USB_REC_BUSLOAD:
+ /* bus load (ignored) */
+ rec_len = 1;
+ break;
+
+ case PCAN_USB_REC_TS:
+ /* only timestamp */
+ if (pcan_usb_update_ts(mc))
+ return -EINVAL;
+ break;
+
+ case PCAN_USB_REC_BUSEVT:
+ /* error frame/bus event */
+ if (n & PCAN_USB_ERROR_TXQFULL)
+ netdev_dbg(mc->netdev, "device Tx queue full)\n");
+ break;
+ default:
+ netdev_err(mc->netdev, "unexpected function %u\n", f);
+ break;
+ }
+
+ if ((mc->ptr + rec_len) > mc->end)
+ return -EINVAL;
+
+ mc->ptr += rec_len;
+
+ return 0;
+}
+
+/*
+ * decode data usb message
+ */
+static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
+{
+ u8 rec_len = status_len & PCAN_USB_STATUSLEN_DLC;
+ struct sk_buff *skb;
+ struct can_frame *cf;
+ struct timeval tv;
+ struct skb_shared_hwtstamps *hwts;
+
+ skb = alloc_can_skb(mc->netdev, &cf);
+ if (!skb)
+ return -ENOMEM;
+
+ if (status_len & PCAN_USB_STATUSLEN_EXT_ID) {
+ u32 tmp32;
+
+ if ((mc->ptr + 4) > mc->end)
+ goto decode_failed;
+
+ memcpy(&tmp32, mc->ptr, 4);
+ mc->ptr += 4;
+
+ cf->can_id = le32_to_cpu(tmp32 >> 3) | CAN_EFF_FLAG;
+ } else {
+ u16 tmp16;
+
+ if ((mc->ptr + 2) > mc->end)
+ goto decode_failed;
+
+ memcpy(&tmp16, mc->ptr, 2);
+ mc->ptr += 2;
+
+ cf->can_id = le16_to_cpu(tmp16 >> 5);
+ }
+
+ cf->can_dlc = get_can_dlc(rec_len);
+
+ /* first data packet timestamp is a word */
+ if (pcan_usb_decode_ts(mc, !mc->rec_data_idx))
+ goto decode_failed;
+
+ /* read data */
+ memset(cf->data, 0x0, sizeof(cf->data));
+ if (status_len & PCAN_USB_STATUSLEN_RTR) {
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ if ((mc->ptr + rec_len) > mc->end)
+ goto decode_failed;
+
+ memcpy(cf->data, mc->ptr, cf->can_dlc);
+ mc->ptr += rec_len;
+ }
+
+ /* convert timestamp into kernel time */
+ peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv);
+ hwts = skb_hwtstamps(skb);
+ hwts->hwtstamp = timeval_to_ktime(tv);
+
+ /* push the skb */
+ netif_rx(skb);
+
+ /* update statistics */
+ mc->netdev->stats.rx_packets++;
+ mc->netdev->stats.rx_bytes += cf->can_dlc;
+
+ return 0;
+
+decode_failed:
+ dev_kfree_skb(skb);
+ return -EINVAL;
+}
+
+/*
+ * process incoming message
+ */
+static int pcan_usb_decode_msg(struct peak_usb_device *dev, u8 *ibuf, u32 lbuf)
+{
+ struct pcan_usb_msg_context mc = {
+ .rec_cnt = ibuf[1],
+ .ptr = ibuf + PCAN_USB_MSG_HEADER_LEN,
+ .end = ibuf + lbuf,
+ .netdev = dev->netdev,
+ .pdev = container_of(dev, struct pcan_usb, dev),
+ };
+ int err;
+
+ for (err = 0; mc.rec_idx < mc.rec_cnt && !err; mc.rec_idx++) {
+ u8 sl = *mc.ptr++;
+
+ /* handle status and error frames here */
+ if (sl & PCAN_USB_STATUSLEN_INTERNAL) {
+ err = pcan_usb_decode_status(&mc, sl);
+ /* handle normal can frames here */
+ } else {
+ err = pcan_usb_decode_data(&mc, sl);
+ mc.rec_data_idx++;
+ }
+ }
+
+ return err;
+}
+
+/*
+ * process any incoming buffer
+ */
+static int pcan_usb_decode_buf(struct peak_usb_device *dev, struct urb *urb)
+{
+ int err = 0;
+
+ if (urb->actual_length > PCAN_USB_MSG_HEADER_LEN) {
+ err = pcan_usb_decode_msg(dev, urb->transfer_buffer,
+ urb->actual_length);
+
+ } else if (urb->actual_length > 0) {
+ netdev_err(dev->netdev, "usb message length error (%u)\n",
+ urb->actual_length);
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+/*
+ * process outgoing packet
+ */
+static int pcan_usb_encode_msg(struct peak_usb_device *dev, struct sk_buff *skb,
+ u8 *obuf, size_t *size)
+{
+ struct net_device *netdev = dev->netdev;
+ struct net_device_stats *stats = &netdev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u8 *pc;
+
+ obuf[0] = 2;
+ obuf[1] = 1;
+
+ pc = obuf + PCAN_USB_MSG_HEADER_LEN;
+
+ /* status/len byte */
+ *pc = cf->can_dlc;
+ if (cf->can_id & CAN_RTR_FLAG)
+ *pc |= PCAN_USB_STATUSLEN_RTR;
+
+ /* can id */
+ if (cf->can_id & CAN_EFF_FLAG) {
+ __le32 tmp32 = cpu_to_le32((cf->can_id & CAN_ERR_MASK) << 3);
+
+ *pc |= PCAN_USB_STATUSLEN_EXT_ID;
+ memcpy(++pc, &tmp32, 4);
+ pc += 4;
+ } else {
+ __le16 tmp16 = cpu_to_le16((cf->can_id & CAN_ERR_MASK) << 5);
+
+ memcpy(++pc, &tmp16, 2);
+ pc += 2;
+ }
+
+ /* can data */
+ if (!(cf->can_id & CAN_RTR_FLAG)) {
+ memcpy(pc, cf->data, cf->can_dlc);
+ pc += cf->can_dlc;
+ }
+
+ obuf[(*size)-1] = (u8)(stats->tx_packets & 0xff);
+
+ return 0;
+}
+
+/*
+ * start interface
+ */
+static int pcan_usb_start(struct peak_usb_device *dev)
+{
+ struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev);
+
+ /* number of bits used in timestamps read from adapter struct */
+ peak_usb_init_time_ref(&pdev->time_ref, &pcan_usb);
+
+ /* if revision greater than 3, can put silent mode on/off */
+ if (dev->device_rev > 3) {
+ int err;
+
+ err = pcan_usb_set_silent(dev,
+ dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY);
+ if (err)
+ return err;
+ }
+
+ return pcan_usb_set_ext_vcc(dev, 0);
+}
+
+static int pcan_usb_init(struct peak_usb_device *dev)
+{
+ struct pcan_usb *pdev = container_of(dev, struct pcan_usb, dev);
+ u32 serial_number;
+ int err;
+
+ /* initialize a timer needed to wait for hardware restart */
+ init_timer(&pdev->restart_timer);
+ pdev->restart_timer.function = pcan_usb_restart;
+ pdev->restart_timer.data = (unsigned long)dev;
+
+ /*
+ * explicit use of dev_xxx() instead of netdev_xxx() here:
+ * information displayed are related to the device itself, not
+ * to the canx netdevice.
+ */
+ err = pcan_usb_get_serial(dev, &serial_number);
+ if (err) {
+ dev_err(dev->netdev->dev.parent,
+ "unable to read %s serial number (err %d)\n",
+ pcan_usb.name, err);
+ return err;
+ }
+
+ dev_info(dev->netdev->dev.parent,
+ "PEAK-System %s adapter hwrev %u serial %08X (%u channel)\n",
+ pcan_usb.name, dev->device_rev, serial_number,
+ pcan_usb.ctrl_count);
+
+ return 0;
+}
+
+/*
+ * probe function for new PCAN-USB usb interface
+ */
+static int pcan_usb_probe(struct usb_interface *intf)
+{
+ struct usb_host_interface *if_desc;
+ int i;
+
+ if_desc = intf->altsetting;
+
+ /* check interface endpoint addresses */
+ for (i = 0; i < if_desc->desc.bNumEndpoints; i++) {
+ struct usb_endpoint_descriptor *ep = &if_desc->endpoint[i].desc;
+
+ switch (ep->bEndpointAddress) {
+ case PCAN_USB_EP_CMDOUT:
+ case PCAN_USB_EP_CMDIN:
+ case PCAN_USB_EP_MSGOUT:
+ case PCAN_USB_EP_MSGIN:
+ break;
+ default:
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * describe the PCAN-USB adapter
+ */
+struct peak_usb_adapter pcan_usb = {
+ .name = "PCAN-USB",
+ .device_id = PCAN_USB_PRODUCT_ID,
+ .ctrl_count = 1,
+ .clock = {
+ .freq = PCAN_USB_CRYSTAL_HZ / 2 ,
+ },
+ .bittiming_const = {
+ .name = "pcan_usb",
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 64,
+ .brp_inc = 1,
+ },
+
+ /* size of device private data */
+ .sizeof_dev_private = sizeof(struct pcan_usb),
+
+ /* timestamps usage */
+ .ts_used_bits = 16,
+ .ts_period = 24575, /* calibration period in ts. */
+ .us_per_ts_scale = PCAN_USB_TS_US_PER_TICK, /* us=(ts*scale) */
+ .us_per_ts_shift = PCAN_USB_TS_DIV_SHIFTER, /* >> shift */
+
+ /* give here messages in/out endpoints */
+ .ep_msg_in = PCAN_USB_EP_MSGIN,
+ .ep_msg_out = {PCAN_USB_EP_MSGOUT},
+
+ /* size of rx/tx usb buffers */
+ .rx_buffer_size = PCAN_USB_RX_BUFFER_SIZE,
+ .tx_buffer_size = PCAN_USB_TX_BUFFER_SIZE,
+
+ /* device callbacks */
+ .intf_probe = pcan_usb_probe,
+ .dev_init = pcan_usb_init,
+ .dev_set_bus = pcan_usb_write_mode,
+ .dev_set_bittiming = pcan_usb_set_bittiming,
+ .dev_get_device_id = pcan_usb_get_device_id,
+ .dev_decode_buf = pcan_usb_decode_buf,
+ .dev_encode_msg = pcan_usb_encode_msg,
+ .dev_start = pcan_usb_start,
+ .dev_restart_async = pcan_usb_restart_async,
+};
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
new file mode 100644
index 00000000000..644e6ab8a48
--- /dev/null
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -0,0 +1,950 @@
+/*
+ * CAN driver for PEAK System USB adapters
+ * Derived from the PCAN project file driver/src/pcan_usb_core.c
+ *
+ * Copyright (C) 2003-2010 PEAK System-Technik GmbH
+ * Copyright (C) 2010-2012 Stephane Grosjean <s.grosjean@peak-system.com>
+ *
+ * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#include "pcan_usb_core.h"
+
+MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>");
+MODULE_DESCRIPTION("CAN driver for PEAK-System USB adapters");
+MODULE_LICENSE("GPL v2");
+
+/* Table of devices that work with this driver */
+static struct usb_device_id peak_usb_table[] = {
+ {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USB_PRODUCT_ID)},
+ {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPRO_PRODUCT_ID)},
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, peak_usb_table);
+
+/* List of supported PCAN-USB adapters (NULL terminated list) */
+static struct peak_usb_adapter *peak_usb_adapters_list[] = {
+ &pcan_usb,
+ &pcan_usb_pro,
+ NULL,
+};
+
+/*
+ * dump memory
+ */
+#define DUMP_WIDTH 16
+void pcan_dump_mem(char *prompt, void *p, int l)
+{
+ pr_info("%s dumping %s (%d bytes):\n",
+ PCAN_USB_DRIVER_NAME, prompt ? prompt : "memory", l);
+ print_hex_dump(KERN_INFO, PCAN_USB_DRIVER_NAME " ", DUMP_PREFIX_NONE,
+ DUMP_WIDTH, 1, p, l, false);
+}
+
+/*
+ * initialize a time_ref object with usb adapter own settings
+ */
+void peak_usb_init_time_ref(struct peak_time_ref *time_ref,
+ struct peak_usb_adapter *adapter)
+{
+ if (time_ref) {
+ memset(time_ref, 0, sizeof(struct peak_time_ref));
+ time_ref->adapter = adapter;
+ }
+}
+
+static void peak_usb_add_us(struct timeval *tv, u32 delta_us)
+{
+ /* number of s. to add to final time */
+ u32 delta_s = delta_us / 1000000;
+
+ delta_us -= delta_s * 1000000;
+
+ tv->tv_usec += delta_us;
+ if (tv->tv_usec >= 1000000) {
+ tv->tv_usec -= 1000000;
+ delta_s++;
+ }
+ tv->tv_sec += delta_s;
+}
+
+/*
+ * sometimes, another now may be more recent than current one...
+ */
+void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now)
+{
+ time_ref->ts_dev_2 = ts_now;
+
+ /* should wait at least two passes before computing */
+ if (time_ref->tv_host.tv_sec > 0) {
+ u32 delta_ts = time_ref->ts_dev_2 - time_ref->ts_dev_1;
+
+ if (time_ref->ts_dev_2 < time_ref->ts_dev_1)
+ delta_ts &= (1 << time_ref->adapter->ts_used_bits) - 1;
+
+ time_ref->ts_total += delta_ts;
+ }
+}
+
+/*
+ * register device timestamp as now
+ */
+void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now)
+{
+ if (time_ref->tv_host_0.tv_sec == 0) {
+ /* use monotonic clock to correctly compute further deltas */
+ time_ref->tv_host_0 = ktime_to_timeval(ktime_get());
+ time_ref->tv_host.tv_sec = 0;
+ } else {
+ /*
+ * delta_us should not be >= 2^32 => delta_s should be < 4294
+ * handle 32-bits wrapping here: if count of s. reaches 4200,
+ * reset counters and change time base
+ */
+ if (time_ref->tv_host.tv_sec != 0) {
+ u32 delta_s = time_ref->tv_host.tv_sec
+ - time_ref->tv_host_0.tv_sec;
+ if (delta_s > 4200) {
+ time_ref->tv_host_0 = time_ref->tv_host;
+ time_ref->ts_total = 0;
+ }
+ }
+
+ time_ref->tv_host = ktime_to_timeval(ktime_get());
+ time_ref->tick_count++;
+ }
+
+ time_ref->ts_dev_1 = time_ref->ts_dev_2;
+ peak_usb_update_ts_now(time_ref, ts_now);
+}
+
+/*
+ * compute timeval according to current ts and time_ref data
+ */
+void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts,
+ struct timeval *tv)
+{
+ /* protect from getting timeval before setting now */
+ if (time_ref->tv_host.tv_sec > 0) {
+ u64 delta_us;
+
+ delta_us = ts - time_ref->ts_dev_2;
+ if (ts < time_ref->ts_dev_2)
+ delta_us &= (1 << time_ref->adapter->ts_used_bits) - 1;
+
+ delta_us += time_ref->ts_total;
+
+ delta_us *= time_ref->adapter->us_per_ts_scale;
+ delta_us >>= time_ref->adapter->us_per_ts_shift;
+
+ *tv = time_ref->tv_host_0;
+ peak_usb_add_us(tv, (u32)delta_us);
+ } else {
+ *tv = ktime_to_timeval(ktime_get());
+ }
+}
+
+/*
+ * callback for bulk Rx urb
+ */
+static void peak_usb_read_bulk_callback(struct urb *urb)
+{
+ struct peak_usb_device *dev = urb->context;
+ struct net_device *netdev;
+ int err;
+
+ netdev = dev->netdev;
+
+ if (!netif_device_present(netdev))
+ return;
+
+ /* check reception status */
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+
+ case -EILSEQ:
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ if (net_ratelimit())
+ netdev_err(netdev,
+ "Rx urb aborted (%d)\n", urb->status);
+ goto resubmit_urb;
+ }
+
+ /* protect from any incoming empty msgs */
+ if ((urb->actual_length > 0) && (dev->adapter->dev_decode_buf)) {
+ /* handle these kinds of msgs only if _start callback called */
+ if (dev->state & PCAN_USB_STATE_STARTED) {
+ err = dev->adapter->dev_decode_buf(dev, urb);
+ if (err)
+ pcan_dump_mem("received usb message",
+ urb->transfer_buffer,
+ urb->transfer_buffer_length);
+ }
+ }
+
+resubmit_urb:
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev, dev->ep_msg_in),
+ urb->transfer_buffer, dev->adapter->rx_buffer_size,
+ peak_usb_read_bulk_callback, dev);
+
+ usb_anchor_urb(urb, &dev->rx_submitted);
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!err)
+ return;
+
+ usb_unanchor_urb(urb);
+
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ else
+ netdev_err(netdev, "failed resubmitting read bulk urb: %d\n",
+ err);
+}
+
+/*
+ * callback for bulk Tx urb
+ */
+static void peak_usb_write_bulk_callback(struct urb *urb)
+{
+ struct peak_tx_urb_context *context = urb->context;
+ struct peak_usb_device *dev;
+ struct net_device *netdev;
+
+ BUG_ON(!context);
+
+ dev = context->dev;
+ netdev = dev->netdev;
+
+ atomic_dec(&dev->active_tx_urbs);
+
+ if (!netif_device_present(netdev))
+ return;
+
+ /* check tx status */
+ switch (urb->status) {
+ case 0:
+ /* transmission complete */
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += context->dlc;
+
+ /* prevent tx timeout */
+ netdev->trans_start = jiffies;
+ break;
+
+ default:
+ if (net_ratelimit())
+ netdev_err(netdev, "Tx urb aborted (%d)\n",
+ urb->status);
+ case -EPROTO:
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ESHUTDOWN:
+
+ break;
+ }
+
+ /* should always release echo skb and corresponding context */
+ can_get_echo_skb(netdev, context->echo_index);
+ context->echo_index = PCAN_USB_MAX_TX_URBS;
+
+ /* do wakeup tx queue in case of success only */
+ if (!urb->status)
+ netif_wake_queue(netdev);
+}
+
+/*
+ * called by netdev to send one skb on the CAN interface.
+ */
+static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct peak_usb_device *dev = netdev_priv(netdev);
+ struct peak_tx_urb_context *context = NULL;
+ struct net_device_stats *stats = &netdev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ struct urb *urb;
+ u8 *obuf;
+ int i, err;
+ size_t size = dev->adapter->tx_buffer_size;
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++)
+ if (dev->tx_contexts[i].echo_index == PCAN_USB_MAX_TX_URBS) {
+ context = dev->tx_contexts + i;
+ break;
+ }
+
+ if (!context) {
+ /* should not occur except during restart */
+ return NETDEV_TX_BUSY;
+ }
+
+ urb = context->urb;
+ obuf = urb->transfer_buffer;
+
+ err = dev->adapter->dev_encode_msg(dev, skb, obuf, &size);
+ if (err) {
+ if (net_ratelimit())
+ netdev_err(netdev, "packet dropped\n");
+ dev_kfree_skb(skb);
+ stats->tx_dropped++;
+ return NETDEV_TX_OK;
+ }
+
+ context->echo_index = i;
+ context->dlc = cf->can_dlc;
+
+ usb_anchor_urb(urb, &dev->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, context->echo_index);
+
+ atomic_inc(&dev->active_tx_urbs);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err) {
+ can_free_echo_skb(netdev, context->echo_index);
+
+ usb_unanchor_urb(urb);
+
+ /* this context is not used in fact */
+ context->echo_index = PCAN_USB_MAX_TX_URBS;
+
+ atomic_dec(&dev->active_tx_urbs);
+
+ switch (err) {
+ case -ENODEV:
+ netif_device_detach(netdev);
+ break;
+ default:
+ netdev_warn(netdev, "tx urb submitting failed err=%d\n",
+ err);
+ case -ENOENT:
+ /* cable unplugged */
+ stats->tx_dropped++;
+ }
+ } else {
+ netdev->trans_start = jiffies;
+
+ /* slow down tx path */
+ if (atomic_read(&dev->active_tx_urbs) >= PCAN_USB_MAX_TX_URBS)
+ netif_stop_queue(netdev);
+ }
+
+ return NETDEV_TX_OK;
+}
+
+/*
+ * start the CAN interface.
+ * Rx and Tx urbs are allocated here. Rx urbs are submitted here.
+ */
+static int peak_usb_start(struct peak_usb_device *dev)
+{
+ struct net_device *netdev = dev->netdev;
+ int err, i;
+
+ for (i = 0; i < PCAN_USB_MAX_RX_URBS; i++) {
+ struct urb *urb;
+ u8 *buf;
+
+ /* create a URB, and a buffer for it, to receive usb messages */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ err = -ENOMEM;
+ break;
+ }
+
+ buf = kmalloc(dev->adapter->rx_buffer_size, GFP_KERNEL);
+ if (!buf) {
+ usb_free_urb(urb);
+ err = -ENOMEM;
+ break;
+ }
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev, dev->ep_msg_in),
+ buf, dev->adapter->rx_buffer_size,
+ peak_usb_read_bulk_callback, dev);
+
+ /* ask last usb_free_urb() to also kfree() transfer_buffer */
+ urb->transfer_flags |= URB_FREE_BUFFER;
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ if (err == -ENODEV)
+ netif_device_detach(dev->netdev);
+
+ usb_unanchor_urb(urb);
+ kfree(buf);
+ usb_free_urb(urb);
+ break;
+ }
+
+ /* drop reference, USB core will take care of freeing it */
+ usb_free_urb(urb);
+ }
+
+ /* did we submit any URBs? Warn if we was not able to submit all urbs */
+ if (i < PCAN_USB_MAX_RX_URBS) {
+ if (i == 0) {
+ netdev_err(netdev, "couldn't setup any rx URB\n");
+ return err;
+ }
+
+ netdev_warn(netdev, "rx performance may be slow\n");
+ }
+
+ /* pre-alloc tx buffers and corresponding urbs */
+ for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) {
+ struct peak_tx_urb_context *context;
+ struct urb *urb;
+ u8 *buf;
+
+ /* create a URB and a buffer for it, to transmit usb messages */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ err = -ENOMEM;
+ break;
+ }
+
+ buf = kmalloc(dev->adapter->tx_buffer_size, GFP_KERNEL);
+ if (!buf) {
+ usb_free_urb(urb);
+ err = -ENOMEM;
+ break;
+ }
+
+ context = dev->tx_contexts + i;
+ context->dev = dev;
+ context->urb = urb;
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev, dev->ep_msg_out),
+ buf, dev->adapter->tx_buffer_size,
+ peak_usb_write_bulk_callback, context);
+
+ /* ask last usb_free_urb() to also kfree() transfer_buffer */
+ urb->transfer_flags |= URB_FREE_BUFFER;
+ }
+
+ /* warn if we were not able to allocate enough tx contexts */
+ if (i < PCAN_USB_MAX_TX_URBS) {
+ if (i == 0) {
+ netdev_err(netdev, "couldn't setup any tx URB\n");
+ goto err_tx;
+ }
+
+ netdev_warn(netdev, "tx performance may be slow\n");
+ }
+
+ if (dev->adapter->dev_start) {
+ err = dev->adapter->dev_start(dev);
+ if (err)
+ goto err_adapter;
+ }
+
+ dev->state |= PCAN_USB_STATE_STARTED;
+
+ /* can set bus on now */
+ if (dev->adapter->dev_set_bus) {
+ err = dev->adapter->dev_set_bus(dev, 1);
+ if (err)
+ goto err_adapter;
+ }
+
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ return 0;
+
+err_adapter:
+ if (err == -ENODEV)
+ netif_device_detach(dev->netdev);
+
+ netdev_warn(netdev, "couldn't submit control: %d\n", err);
+
+ for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) {
+ usb_free_urb(dev->tx_contexts[i].urb);
+ dev->tx_contexts[i].urb = NULL;
+ }
+err_tx:
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+
+ return err;
+}
+
+/*
+ * called by netdev to open the corresponding CAN interface.
+ */
+static int peak_usb_ndo_open(struct net_device *netdev)
+{
+ struct peak_usb_device *dev = netdev_priv(netdev);
+ int err;
+
+ /* common open */
+ err = open_candev(netdev);
+ if (err)
+ return err;
+
+ /* finally start device */
+ err = peak_usb_start(dev);
+ if (err) {
+ netdev_err(netdev, "couldn't start device: %d\n", err);
+ close_candev(netdev);
+ return err;
+ }
+
+ netif_start_queue(netdev);
+
+ return 0;
+}
+
+/*
+ * unlink in-flight Rx and Tx urbs and free their memory.
+ */
+static void peak_usb_unlink_all_urbs(struct peak_usb_device *dev)
+{
+ int i;
+
+ /* free all Rx (submitted) urbs */
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+
+ /* free unsubmitted Tx urbs first */
+ for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) {
+ struct urb *urb = dev->tx_contexts[i].urb;
+
+ if (!urb ||
+ dev->tx_contexts[i].echo_index != PCAN_USB_MAX_TX_URBS) {
+ /*
+ * this urb is already released or always submitted,
+ * let usb core free by itself
+ */
+ continue;
+ }
+
+ usb_free_urb(urb);
+ dev->tx_contexts[i].urb = NULL;
+ }
+
+ /* then free all submitted Tx urbs */
+ usb_kill_anchored_urbs(&dev->tx_submitted);
+ atomic_set(&dev->active_tx_urbs, 0);
+}
+
+/*
+ * called by netdev to close the corresponding CAN interface.
+ */
+static int peak_usb_ndo_stop(struct net_device *netdev)
+{
+ struct peak_usb_device *dev = netdev_priv(netdev);
+
+ dev->state &= ~PCAN_USB_STATE_STARTED;
+ netif_stop_queue(netdev);
+
+ /* unlink all pending urbs and free used memory */
+ peak_usb_unlink_all_urbs(dev);
+
+ if (dev->adapter->dev_stop)
+ dev->adapter->dev_stop(dev);
+
+ close_candev(netdev);
+
+ dev->can.state = CAN_STATE_STOPPED;
+
+ /* can set bus off now */
+ if (dev->adapter->dev_set_bus) {
+ int err = dev->adapter->dev_set_bus(dev, 0);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+/*
+ * handle end of waiting for the device to reset
+ */
+void peak_usb_restart_complete(struct peak_usb_device *dev)
+{
+ /* finally MUST update can state */
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ /* netdev queue can be awaken now */
+ netif_wake_queue(dev->netdev);
+}
+
+void peak_usb_async_complete(struct urb *urb)
+{
+ kfree(urb->transfer_buffer);
+ usb_free_urb(urb);
+}
+
+/*
+ * device (auto-)restart mechanism runs in a timer context =>
+ * MUST handle restart with asynchronous usb transfers
+ */
+static int peak_usb_restart(struct peak_usb_device *dev)
+{
+ struct urb *urb;
+ int err;
+ u8 *buf;
+
+ /*
+ * if device doesn't define any asynchronous restart handler, simply
+ * wake the netdev queue up
+ */
+ if (!dev->adapter->dev_restart_async) {
+ peak_usb_restart_complete(dev);
+ return 0;
+ }
+
+ /* first allocate a urb to handle the asynchronous steps */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(dev->netdev, "no memory left for urb\n");
+ return -ENOMEM;
+ }
+
+ /* also allocate enough space for the commands to send */
+ buf = kmalloc(PCAN_USB_MAX_CMD_LEN, GFP_ATOMIC);
+ if (!buf) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ /* call the device specific handler for the restart */
+ err = dev->adapter->dev_restart_async(dev, urb, buf);
+ if (!err)
+ return 0;
+
+ kfree(buf);
+ usb_free_urb(urb);
+
+ return err;
+}
+
+/*
+ * candev callback used to change CAN mode.
+ * Warning: this is called from a timer context!
+ */
+static int peak_usb_set_mode(struct net_device *netdev, enum can_mode mode)
+{
+ struct peak_usb_device *dev = netdev_priv(netdev);
+ int err = 0;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ err = peak_usb_restart(dev);
+ if (err)
+ netdev_err(netdev, "couldn't start device (err %d)\n",
+ err);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return err;
+}
+
+/*
+ * candev callback used to set device bitrate.
+ */
+static int peak_usb_set_bittiming(struct net_device *netdev)
+{
+ struct peak_usb_device *dev = netdev_priv(netdev);
+ struct can_bittiming *bt = &dev->can.bittiming;
+
+ if (dev->adapter->dev_set_bittiming) {
+ int err = dev->adapter->dev_set_bittiming(dev, bt);
+
+ if (err)
+ netdev_info(netdev, "couldn't set bitrate (err %d)\n",
+ err);
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct net_device_ops peak_usb_netdev_ops = {
+ .ndo_open = peak_usb_ndo_open,
+ .ndo_stop = peak_usb_ndo_stop,
+ .ndo_start_xmit = peak_usb_ndo_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+/*
+ * create one device which is attached to CAN controller #ctrl_idx of the
+ * usb adapter.
+ */
+static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter,
+ struct usb_interface *intf, int ctrl_idx)
+{
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ int sizeof_candev = peak_usb_adapter->sizeof_dev_private;
+ struct peak_usb_device *dev;
+ struct net_device *netdev;
+ int i, err;
+ u16 tmp16;
+
+ if (sizeof_candev < sizeof(struct peak_usb_device))
+ sizeof_candev = sizeof(struct peak_usb_device);
+
+ netdev = alloc_candev(sizeof_candev, PCAN_USB_MAX_TX_URBS);
+ if (!netdev) {
+ dev_err(&intf->dev, "%s: couldn't alloc candev\n",
+ PCAN_USB_DRIVER_NAME);
+ return -ENOMEM;
+ }
+
+ dev = netdev_priv(netdev);
+
+ /* allocate a buffer large enough to send commands */
+ dev->cmd_buf = kmalloc(PCAN_USB_MAX_CMD_LEN, GFP_KERNEL);
+ if (!dev->cmd_buf) {
+ err = -ENOMEM;
+ goto lbl_set_intf_data;
+ }
+
+ dev->udev = usb_dev;
+ dev->netdev = netdev;
+ dev->adapter = peak_usb_adapter;
+ dev->ctrl_idx = ctrl_idx;
+ dev->state = PCAN_USB_STATE_CONNECTED;
+
+ dev->ep_msg_in = peak_usb_adapter->ep_msg_in;
+ dev->ep_msg_out = peak_usb_adapter->ep_msg_out[ctrl_idx];
+
+ dev->can.clock = peak_usb_adapter->clock;
+ dev->can.bittiming_const = &peak_usb_adapter->bittiming_const;
+ dev->can.do_set_bittiming = peak_usb_set_bittiming;
+ dev->can.do_set_mode = peak_usb_set_mode;
+ dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_LISTENONLY;
+
+ netdev->netdev_ops = &peak_usb_netdev_ops;
+
+ netdev->flags |= IFF_ECHO; /* we support local echo */
+
+ init_usb_anchor(&dev->rx_submitted);
+
+ init_usb_anchor(&dev->tx_submitted);
+ atomic_set(&dev->active_tx_urbs, 0);
+
+ for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++)
+ dev->tx_contexts[i].echo_index = PCAN_USB_MAX_TX_URBS;
+
+ dev->prev_siblings = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, dev);
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+ netdev->dev_id = ctrl_idx;
+
+ err = register_candev(netdev);
+ if (err) {
+ dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
+ goto lbl_free_cmd_buf;
+ }
+
+ if (dev->prev_siblings)
+ (dev->prev_siblings)->next_siblings = dev;
+
+ /* keep hw revision into the netdevice */
+ tmp16 = le16_to_cpu(usb_dev->descriptor.bcdDevice);
+ dev->device_rev = tmp16 >> 8;
+
+ if (dev->adapter->dev_init) {
+ err = dev->adapter->dev_init(dev);
+ if (err)
+ goto lbl_free_cmd_buf;
+ }
+
+ /* set bus off */
+ if (dev->adapter->dev_set_bus) {
+ err = dev->adapter->dev_set_bus(dev, 0);
+ if (err)
+ goto lbl_free_cmd_buf;
+ }
+
+ /* get device number early */
+ if (dev->adapter->dev_get_device_id)
+ dev->adapter->dev_get_device_id(dev, &dev->device_number);
+
+ netdev_info(netdev, "attached to %s channel %u (device %u)\n",
+ peak_usb_adapter->name, ctrl_idx, dev->device_number);
+
+ return 0;
+
+lbl_free_cmd_buf:
+ kfree(dev->cmd_buf);
+
+lbl_set_intf_data:
+ usb_set_intfdata(intf, dev->prev_siblings);
+ free_candev(netdev);
+
+ return err;
+}
+
+/*
+ * called by the usb core when the device is unplugged from the system
+ */
+static void peak_usb_disconnect(struct usb_interface *intf)
+{
+ struct peak_usb_device *dev;
+
+ /* unregister as many netdev devices as siblings */
+ for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) {
+ struct net_device *netdev = dev->netdev;
+ char name[IFNAMSIZ];
+
+ dev->state &= ~PCAN_USB_STATE_CONNECTED;
+ strncpy(name, netdev->name, IFNAMSIZ);
+
+ unregister_netdev(netdev);
+ free_candev(netdev);
+
+ kfree(dev->cmd_buf);
+ dev->next_siblings = NULL;
+ if (dev->adapter->dev_free)
+ dev->adapter->dev_free(dev);
+
+ dev_info(&intf->dev, "%s removed\n", name);
+ }
+
+ usb_set_intfdata(intf, NULL);
+}
+
+/*
+ * probe function for new PEAK-System devices
+ */
+static int peak_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
+ struct peak_usb_adapter *peak_usb_adapter, **pp;
+ int i, err = -ENOMEM;
+
+ usb_dev = interface_to_usbdev(intf);
+
+ /* get corresponding PCAN-USB adapter */
+ for (pp = peak_usb_adapters_list; *pp; pp++)
+ if ((*pp)->device_id == usb_dev->descriptor.idProduct)
+ break;
+
+ peak_usb_adapter = *pp;
+ if (!peak_usb_adapter) {
+ /* should never come except device_id bad usage in this file */
+ pr_err("%s: didn't find device id. 0x%x in devices list\n",
+ PCAN_USB_DRIVER_NAME, usb_dev->descriptor.idProduct);
+ return -ENODEV;
+ }
+
+ /* got corresponding adapter: check if it handles current interface */
+ if (peak_usb_adapter->intf_probe) {
+ err = peak_usb_adapter->intf_probe(intf);
+ if (err)
+ return err;
+ }
+
+ for (i = 0; i < peak_usb_adapter->ctrl_count; i++) {
+ err = peak_usb_create_dev(peak_usb_adapter, intf, i);
+ if (err) {
+ /* deregister already created devices */
+ peak_usb_disconnect(intf);
+ break;
+ }
+ }
+
+ return err;
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver peak_usb_driver = {
+ .name = PCAN_USB_DRIVER_NAME,
+ .disconnect = peak_usb_disconnect,
+ .probe = peak_usb_probe,
+ .id_table = peak_usb_table,
+};
+
+static int __init peak_usb_init(void)
+{
+ int err;
+
+ /* register this driver with the USB subsystem */
+ err = usb_register(&peak_usb_driver);
+ if (err)
+ pr_err("%s: usb_register failed (err %d)\n",
+ PCAN_USB_DRIVER_NAME, err);
+
+ return err;
+}
+
+static int peak_usb_do_device_exit(struct device *d, void *arg)
+{
+ struct usb_interface *intf = to_usb_interface(d);
+ struct peak_usb_device *dev;
+
+ /* stop as many netdev devices as siblings */
+ for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) {
+ struct net_device *netdev = dev->netdev;
+
+ if (netif_device_present(netdev))
+ if (dev->adapter->dev_exit)
+ dev->adapter->dev_exit(dev);
+ }
+
+ return 0;
+}
+
+static void __exit peak_usb_exit(void)
+{
+ int err;
+
+ /* last chance do send any synchronous commands here */
+ err = driver_for_each_device(&peak_usb_driver.drvwrap.driver, NULL,
+ NULL, peak_usb_do_device_exit);
+ if (err)
+ pr_err("%s: failed to stop all can devices (err %d)\n",
+ PCAN_USB_DRIVER_NAME, err);
+
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&peak_usb_driver);
+
+ pr_info("%s: PCAN-USB interfaces driver unloaded\n",
+ PCAN_USB_DRIVER_NAME);
+}
+
+module_init(peak_usb_init);
+module_exit(peak_usb_exit);
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
new file mode 100644
index 00000000000..073b47ff8ee
--- /dev/null
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -0,0 +1,145 @@
+/*
+ * CAN driver for PEAK System USB adapters
+ * Derived from the PCAN project file driver/src/pcan_usb_core.c
+ *
+ * Copyright (C) 2003-2010 PEAK System-Technik GmbH
+ * Copyright (C) 2010-2012 Stephane Grosjean <s.grosjean@peak-system.com>
+ *
+ * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#ifndef PCAN_USB_CORE_H
+#define PCAN_USB_CORE_H
+
+/* PEAK-System vendor id. */
+#define PCAN_USB_VENDOR_ID 0x0c72
+
+/* supported device ids. */
+#define PCAN_USB_PRODUCT_ID 0x000c
+#define PCAN_USBPRO_PRODUCT_ID 0x000d
+
+#define PCAN_USB_DRIVER_NAME "peak_usb"
+
+/* number of urbs that are submitted for rx/tx per channel */
+#define PCAN_USB_MAX_RX_URBS 4
+#define PCAN_USB_MAX_TX_URBS 10
+
+/* usb adapters maximum channels per usb interface */
+#define PCAN_USB_MAX_CHANNEL 2
+
+/* maximum length of the usb commands sent to/received from the devices */
+#define PCAN_USB_MAX_CMD_LEN 32
+
+struct peak_usb_device;
+
+/* PEAK-System USB adapter descriptor */
+struct peak_usb_adapter {
+ char *name;
+ u32 device_id;
+ struct can_clock clock;
+ const struct can_bittiming_const bittiming_const;
+ unsigned int ctrl_count;
+
+ int (*intf_probe)(struct usb_interface *intf);
+
+ int (*dev_init)(struct peak_usb_device *dev);
+ void (*dev_exit)(struct peak_usb_device *dev);
+ void (*dev_free)(struct peak_usb_device *dev);
+ int (*dev_open)(struct peak_usb_device *dev);
+ int (*dev_close)(struct peak_usb_device *dev);
+ int (*dev_set_bittiming)(struct peak_usb_device *dev,
+ struct can_bittiming *bt);
+ int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff);
+ int (*dev_get_device_id)(struct peak_usb_device *dev, u32 *device_id);
+ int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb);
+ int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb,
+ u8 *obuf, size_t *size);
+ int (*dev_start)(struct peak_usb_device *dev);
+ int (*dev_stop)(struct peak_usb_device *dev);
+ int (*dev_restart_async)(struct peak_usb_device *dev, struct urb *urb,
+ u8 *buf);
+ u8 ep_msg_in;
+ u8 ep_msg_out[PCAN_USB_MAX_CHANNEL];
+ u8 ts_used_bits;
+ u32 ts_period;
+ u8 us_per_ts_shift;
+ u32 us_per_ts_scale;
+
+ int rx_buffer_size;
+ int tx_buffer_size;
+ int sizeof_dev_private;
+};
+
+extern struct peak_usb_adapter pcan_usb;
+extern struct peak_usb_adapter pcan_usb_pro;
+
+struct peak_time_ref {
+ struct timeval tv_host_0, tv_host;
+ u32 ts_dev_1, ts_dev_2;
+ u64 ts_total;
+ u32 tick_count;
+ struct peak_usb_adapter *adapter;
+};
+
+struct peak_tx_urb_context {
+ struct peak_usb_device *dev;
+ u32 echo_index;
+ u8 dlc;
+ struct urb *urb;
+};
+
+#define PCAN_USB_STATE_CONNECTED 0x00000001
+#define PCAN_USB_STATE_STARTED 0x00000002
+
+/* PEAK-System USB device */
+struct peak_usb_device {
+ struct can_priv can;
+ struct peak_usb_adapter *adapter;
+ unsigned int ctrl_idx;
+ u32 state;
+
+ struct sk_buff *echo_skb[PCAN_USB_MAX_TX_URBS];
+
+ struct usb_device *udev;
+ struct net_device *netdev;
+
+ atomic_t active_tx_urbs;
+ struct usb_anchor tx_submitted;
+ struct peak_tx_urb_context tx_contexts[PCAN_USB_MAX_TX_URBS];
+
+ u8 *cmd_buf;
+ struct usb_anchor rx_submitted;
+
+ u32 device_number;
+ u8 device_rev;
+
+ u8 ep_msg_in;
+ u8 ep_msg_out;
+
+ u16 bus_load;
+
+ struct peak_usb_device *prev_siblings;
+ struct peak_usb_device *next_siblings;
+};
+
+void pcan_dump_mem(char *prompt, void *p, int l);
+
+/* common timestamp management */
+void peak_usb_init_time_ref(struct peak_time_ref *time_ref,
+ struct peak_usb_adapter *adapter);
+void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now);
+void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now);
+void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts,
+ struct timeval *tv);
+
+void peak_usb_async_complete(struct urb *urb);
+void peak_usb_restart_complete(struct peak_usb_device *dev);
+#endif
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
new file mode 100644
index 00000000000..263dd921edc
--- /dev/null
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -0,0 +1,1064 @@
+/*
+ * CAN driver for PEAK System PCAN-USB Pro adapter
+ * Derived from the PCAN project file driver/src/pcan_usbpro.c
+ *
+ * Copyright (C) 2003-2011 PEAK System-Technik GmbH
+ * Copyright (C) 2011-2012 Stephane Grosjean <s.grosjean@peak-system.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+#include <linux/module.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#include "pcan_usb_core.h"
+#include "pcan_usb_pro.h"
+
+MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB Pro adapter");
+
+/* PCAN-USB Pro Endpoints */
+#define PCAN_USBPRO_EP_CMDOUT 1
+#define PCAN_USBPRO_EP_CMDIN (PCAN_USBPRO_EP_CMDOUT | USB_DIR_IN)
+#define PCAN_USBPRO_EP_MSGOUT_0 2
+#define PCAN_USBPRO_EP_MSGIN (PCAN_USBPRO_EP_MSGOUT_0 | USB_DIR_IN)
+#define PCAN_USBPRO_EP_MSGOUT_1 3
+#define PCAN_USBPRO_EP_UNUSED (PCAN_USBPRO_EP_MSGOUT_1 | USB_DIR_IN)
+
+#define PCAN_USBPRO_CHANNEL_COUNT 2
+
+/* PCAN-USB Pro adapter internal clock (MHz) */
+#define PCAN_USBPRO_CRYSTAL_HZ 56000000
+
+/* PCAN-USB Pro command timeout (ms.) */
+#define PCAN_USBPRO_COMMAND_TIMEOUT 1000
+
+/* PCAN-USB Pro rx/tx buffers size */
+#define PCAN_USBPRO_RX_BUFFER_SIZE 1024
+#define PCAN_USBPRO_TX_BUFFER_SIZE 64
+
+#define PCAN_USBPRO_MSG_HEADER_LEN 4
+
+/* some commands responses need to be re-submitted */
+#define PCAN_USBPRO_RSP_SUBMIT_MAX 2
+
+#define PCAN_USBPRO_RTR 0x01
+#define PCAN_USBPRO_EXT 0x02
+
+#define PCAN_USBPRO_CMD_BUFFER_SIZE 512
+
+/* handle device specific info used by the netdevices */
+struct pcan_usb_pro_interface {
+ struct peak_usb_device *dev[PCAN_USBPRO_CHANNEL_COUNT];
+ struct peak_time_ref time_ref;
+ int cm_ignore_count;
+ int dev_opened_count;
+};
+
+/* device information */
+struct pcan_usb_pro_device {
+ struct peak_usb_device dev;
+ struct pcan_usb_pro_interface *usb_if;
+ u32 cached_ccbt;
+};
+
+/* internal structure used to handle messages sent to bulk urb */
+struct pcan_usb_pro_msg {
+ u8 *rec_ptr;
+ int rec_buffer_size;
+ int rec_buffer_len;
+ union {
+ u16 *rec_cnt_rd;
+ u32 *rec_cnt;
+ u8 *rec_buffer;
+ } u;
+};
+
+/* records sizes table indexed on message id. (8-bits value) */
+static u16 pcan_usb_pro_sizeof_rec[256] = {
+ [PCAN_USBPRO_SETBTR] = sizeof(struct pcan_usb_pro_btr),
+ [PCAN_USBPRO_SETBUSACT] = sizeof(struct pcan_usb_pro_busact),
+ [PCAN_USBPRO_SETSILENT] = sizeof(struct pcan_usb_pro_silent),
+ [PCAN_USBPRO_SETFILTR] = sizeof(struct pcan_usb_pro_filter),
+ [PCAN_USBPRO_SETTS] = sizeof(struct pcan_usb_pro_setts),
+ [PCAN_USBPRO_GETDEVID] = sizeof(struct pcan_usb_pro_devid),
+ [PCAN_USBPRO_SETLED] = sizeof(struct pcan_usb_pro_setled),
+ [PCAN_USBPRO_RXMSG8] = sizeof(struct pcan_usb_pro_rxmsg),
+ [PCAN_USBPRO_RXMSG4] = sizeof(struct pcan_usb_pro_rxmsg) - 4,
+ [PCAN_USBPRO_RXMSG0] = sizeof(struct pcan_usb_pro_rxmsg) - 8,
+ [PCAN_USBPRO_RXRTR] = sizeof(struct pcan_usb_pro_rxmsg) - 8,
+ [PCAN_USBPRO_RXSTATUS] = sizeof(struct pcan_usb_pro_rxstatus),
+ [PCAN_USBPRO_RXTS] = sizeof(struct pcan_usb_pro_rxts),
+ [PCAN_USBPRO_TXMSG8] = sizeof(struct pcan_usb_pro_txmsg),
+ [PCAN_USBPRO_TXMSG4] = sizeof(struct pcan_usb_pro_txmsg) - 4,
+ [PCAN_USBPRO_TXMSG0] = sizeof(struct pcan_usb_pro_txmsg) - 8,
+};
+
+/*
+ * initialize PCAN-USB Pro message data structure
+ */
+static u8 *pcan_msg_init(struct pcan_usb_pro_msg *pm, void *buffer_addr,
+ int buffer_size)
+{
+ if (buffer_size < PCAN_USBPRO_MSG_HEADER_LEN)
+ return NULL;
+
+ pm->u.rec_buffer = (u8 *)buffer_addr;
+ pm->rec_buffer_size = pm->rec_buffer_len = buffer_size;
+ pm->rec_ptr = pm->u.rec_buffer + PCAN_USBPRO_MSG_HEADER_LEN;
+
+ return pm->rec_ptr;
+}
+
+static u8 *pcan_msg_init_empty(struct pcan_usb_pro_msg *pm,
+ void *buffer_addr, int buffer_size)
+{
+ u8 *pr = pcan_msg_init(pm, buffer_addr, buffer_size);
+
+ if (pr) {
+ pm->rec_buffer_len = PCAN_USBPRO_MSG_HEADER_LEN;
+ *pm->u.rec_cnt = 0;
+ }
+ return pr;
+}
+
+/*
+ * add one record to a message being built
+ */
+static int pcan_msg_add_rec(struct pcan_usb_pro_msg *pm, u8 id, ...)
+{
+ int len, i;
+ u8 *pc;
+ va_list ap;
+
+ va_start(ap, id);
+
+ pc = pm->rec_ptr + 1;
+
+ i = 0;
+ switch (id) {
+ case PCAN_USBPRO_TXMSG8:
+ i += 4;
+ case PCAN_USBPRO_TXMSG4:
+ i += 4;
+ case PCAN_USBPRO_TXMSG0:
+ *pc++ = va_arg(ap, int);
+ *pc++ = va_arg(ap, int);
+ *pc++ = va_arg(ap, int);
+ *(u32 *)pc = cpu_to_le32(va_arg(ap, u32));
+ pc += 4;
+ memcpy(pc, va_arg(ap, int *), i);
+ pc += i;
+ break;
+
+ case PCAN_USBPRO_SETBTR:
+ case PCAN_USBPRO_GETDEVID:
+ *pc++ = va_arg(ap, int);
+ pc += 2;
+ *(u32 *)pc = cpu_to_le32(va_arg(ap, u32));
+ pc += 4;
+ break;
+
+ case PCAN_USBPRO_SETFILTR:
+ case PCAN_USBPRO_SETBUSACT:
+ case PCAN_USBPRO_SETSILENT:
+ *pc++ = va_arg(ap, int);
+ *(u16 *)pc = cpu_to_le16(va_arg(ap, int));
+ pc += 2;
+ break;
+
+ case PCAN_USBPRO_SETLED:
+ *pc++ = va_arg(ap, int);
+ *(u16 *)pc = cpu_to_le16(va_arg(ap, int));
+ pc += 2;
+ *(u32 *)pc = cpu_to_le32(va_arg(ap, u32));
+ pc += 4;
+ break;
+
+ case PCAN_USBPRO_SETTS:
+ pc++;
+ *(u16 *)pc = cpu_to_le16(va_arg(ap, int));
+ pc += 2;
+ break;
+
+ default:
+ pr_err("%s: %s(): unknown data type %02Xh (%d)\n",
+ PCAN_USB_DRIVER_NAME, __func__, id, id);
+ pc--;
+ break;
+ }
+
+ len = pc - pm->rec_ptr;
+ if (len > 0) {
+ *pm->u.rec_cnt = cpu_to_le32(*pm->u.rec_cnt+1);
+ *pm->rec_ptr = id;
+
+ pm->rec_ptr = pc;
+ pm->rec_buffer_len += len;
+ }
+
+ va_end(ap);
+
+ return len;
+}
+
+/*
+ * send PCAN-USB Pro command synchronously
+ */
+static int pcan_usb_pro_send_cmd(struct peak_usb_device *dev,
+ struct pcan_usb_pro_msg *pum)
+{
+ int actual_length;
+ int err;
+
+ /* usb device unregistered? */
+ if (!(dev->state & PCAN_USB_STATE_CONNECTED))
+ return 0;
+
+ err = usb_bulk_msg(dev->udev,
+ usb_sndbulkpipe(dev->udev, PCAN_USBPRO_EP_CMDOUT),
+ pum->u.rec_buffer, pum->rec_buffer_len,
+ &actual_length, PCAN_USBPRO_COMMAND_TIMEOUT);
+ if (err)
+ netdev_err(dev->netdev, "sending command failure: %d\n", err);
+
+ return err;
+}
+
+/*
+ * wait for PCAN-USB Pro command response
+ */
+static int pcan_usb_pro_wait_rsp(struct peak_usb_device *dev,
+ struct pcan_usb_pro_msg *pum)
+{
+ u8 req_data_type, req_channel;
+ int actual_length;
+ int i, err = 0;
+
+ /* usb device unregistered? */
+ if (!(dev->state & PCAN_USB_STATE_CONNECTED))
+ return 0;
+
+ req_data_type = pum->u.rec_buffer[4];
+ req_channel = pum->u.rec_buffer[5];
+
+ *pum->u.rec_cnt = 0;
+ for (i = 0; !err && i < PCAN_USBPRO_RSP_SUBMIT_MAX; i++) {
+ struct pcan_usb_pro_msg rsp;
+ union pcan_usb_pro_rec *pr;
+ u32 r, rec_cnt;
+ u16 rec_len;
+ u8 *pc;
+
+ err = usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev, PCAN_USBPRO_EP_CMDIN),
+ pum->u.rec_buffer, pum->rec_buffer_len,
+ &actual_length, PCAN_USBPRO_COMMAND_TIMEOUT);
+ if (err) {
+ netdev_err(dev->netdev, "waiting rsp error %d\n", err);
+ break;
+ }
+
+ if (actual_length == 0)
+ continue;
+
+ err = -EBADMSG;
+ if (actual_length < PCAN_USBPRO_MSG_HEADER_LEN) {
+ netdev_err(dev->netdev,
+ "got abnormal too small rsp (len=%d)\n",
+ actual_length);
+ break;
+ }
+
+ pc = pcan_msg_init(&rsp, pum->u.rec_buffer,
+ actual_length);
+
+ rec_cnt = le32_to_cpu(*rsp.u.rec_cnt);
+
+ /* loop on records stored into message */
+ for (r = 0; r < rec_cnt; r++) {
+ pr = (union pcan_usb_pro_rec *)pc;
+ rec_len = pcan_usb_pro_sizeof_rec[pr->data_type];
+ if (!rec_len) {
+ netdev_err(dev->netdev,
+ "got unprocessed record in msg\n");
+ pcan_dump_mem("rcvd rsp msg", pum->u.rec_buffer,
+ actual_length);
+ break;
+ }
+
+ /* check if response corresponds to request */
+ if (pr->data_type != req_data_type)
+ netdev_err(dev->netdev,
+ "got unwanted rsp %xh: ignored\n",
+ pr->data_type);
+
+ /* check if channel in response corresponds too */
+ else if ((req_channel != 0xff) && \
+ (pr->bus_act.channel != req_channel))
+ netdev_err(dev->netdev,
+ "got rsp %xh but on chan%u: ignored\n",
+ req_data_type, pr->bus_act.channel);
+
+ /* got the response */
+ else
+ return 0;
+
+ /* otherwise, go on with next record in message */
+ pc += rec_len;
+ }
+ }
+
+ return (i >= PCAN_USBPRO_RSP_SUBMIT_MAX) ? -ERANGE : err;
+}
+
+static int pcan_usb_pro_send_req(struct peak_usb_device *dev, int req_id,
+ int req_value, void *req_addr, int req_size)
+{
+ int err;
+ u8 req_type;
+ unsigned int p;
+
+ /* usb device unregistered? */
+ if (!(dev->state & PCAN_USB_STATE_CONNECTED))
+ return 0;
+
+ memset(req_addr, '\0', req_size);
+
+ req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER;
+
+ switch (req_id) {
+ case PCAN_USBPRO_REQ_FCT:
+ p = usb_sndctrlpipe(dev->udev, 0);
+ break;
+
+ default:
+ p = usb_rcvctrlpipe(dev->udev, 0);
+ req_type |= USB_DIR_IN;
+ break;
+ }
+
+ err = usb_control_msg(dev->udev, p, req_id, req_type, req_value, 0,
+ req_addr, req_size, 2 * USB_CTRL_GET_TIMEOUT);
+ if (err < 0) {
+ netdev_info(dev->netdev,
+ "unable to request usb[type=%d value=%d] err=%d\n",
+ req_id, req_value, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int pcan_usb_pro_set_ts(struct peak_usb_device *dev, u16 onoff)
+{
+ struct pcan_usb_pro_msg um;
+
+ pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_SETTS, onoff);
+
+ return pcan_usb_pro_send_cmd(dev, &um);
+}
+
+static int pcan_usb_pro_set_bitrate(struct peak_usb_device *dev, u32 ccbt)
+{
+ struct pcan_usb_pro_device *pdev =
+ container_of(dev, struct pcan_usb_pro_device, dev);
+ struct pcan_usb_pro_msg um;
+
+ pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_SETBTR, dev->ctrl_idx, ccbt);
+
+ /* cache the CCBT value to reuse it before next buson */
+ pdev->cached_ccbt = ccbt;
+
+ return pcan_usb_pro_send_cmd(dev, &um);
+}
+
+static int pcan_usb_pro_set_bus(struct peak_usb_device *dev, u8 onoff)
+{
+ struct pcan_usb_pro_msg um;
+
+ /* if bus=on, be sure the bitrate being set before! */
+ if (onoff) {
+ struct pcan_usb_pro_device *pdev =
+ container_of(dev, struct pcan_usb_pro_device, dev);
+
+ pcan_usb_pro_set_bitrate(dev, pdev->cached_ccbt);
+ }
+
+ pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_SETBUSACT, dev->ctrl_idx, onoff);
+
+ return pcan_usb_pro_send_cmd(dev, &um);
+}
+
+static int pcan_usb_pro_set_silent(struct peak_usb_device *dev, u8 onoff)
+{
+ struct pcan_usb_pro_msg um;
+
+ pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_SETSILENT, dev->ctrl_idx, onoff);
+
+ return pcan_usb_pro_send_cmd(dev, &um);
+}
+
+static int pcan_usb_pro_set_filter(struct peak_usb_device *dev, u16 filter_mode)
+{
+ struct pcan_usb_pro_msg um;
+
+ pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_SETFILTR, dev->ctrl_idx, filter_mode);
+
+ return pcan_usb_pro_send_cmd(dev, &um);
+}
+
+static int pcan_usb_pro_set_led(struct peak_usb_device *dev, u8 mode,
+ u32 timeout)
+{
+ struct pcan_usb_pro_msg um;
+
+ pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_SETLED, dev->ctrl_idx, mode, timeout);
+
+ return pcan_usb_pro_send_cmd(dev, &um);
+}
+
+static int pcan_usb_pro_get_device_id(struct peak_usb_device *dev,
+ u32 *device_id)
+{
+ struct pcan_usb_pro_devid *pdn;
+ struct pcan_usb_pro_msg um;
+ int err;
+ u8 *pc;
+
+ pc = pcan_msg_init_empty(&um, dev->cmd_buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_GETDEVID, dev->ctrl_idx);
+
+ err = pcan_usb_pro_send_cmd(dev, &um);
+ if (err)
+ return err;
+
+ err = pcan_usb_pro_wait_rsp(dev, &um);
+ if (err)
+ return err;
+
+ pdn = (struct pcan_usb_pro_devid *)pc;
+ if (device_id)
+ *device_id = le32_to_cpu(pdn->serial_num);
+
+ return err;
+}
+
+static int pcan_usb_pro_set_bittiming(struct peak_usb_device *dev,
+ struct can_bittiming *bt)
+{
+ u32 ccbt;
+
+ ccbt = (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 0x00800000 : 0;
+ ccbt |= (bt->sjw - 1) << 24;
+ ccbt |= (bt->phase_seg2 - 1) << 20;
+ ccbt |= (bt->prop_seg + bt->phase_seg1 - 1) << 16; /* = tseg1 */
+ ccbt |= bt->brp - 1;
+
+ netdev_info(dev->netdev, "setting ccbt=0x%08x\n", ccbt);
+
+ return pcan_usb_pro_set_bitrate(dev, ccbt);
+}
+
+static void pcan_usb_pro_restart_complete(struct urb *urb)
+{
+ /* can delete usb resources */
+ peak_usb_async_complete(urb);
+
+ /* notify candev and netdev */
+ peak_usb_restart_complete(urb->context);
+}
+
+/*
+ * handle restart but in asynchronously way
+ */
+static int pcan_usb_pro_restart_async(struct peak_usb_device *dev,
+ struct urb *urb, u8 *buf)
+{
+ struct pcan_usb_pro_msg um;
+
+ pcan_msg_init_empty(&um, buf, PCAN_USB_MAX_CMD_LEN);
+ pcan_msg_add_rec(&um, PCAN_USBPRO_SETBUSACT, dev->ctrl_idx, 1);
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_sndbulkpipe(dev->udev, PCAN_USBPRO_EP_CMDOUT),
+ buf, PCAN_USB_MAX_CMD_LEN,
+ pcan_usb_pro_restart_complete, dev);
+
+ return usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static int pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded)
+{
+ u8 *buffer;
+ int err;
+
+ buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ buffer[0] = 0;
+ buffer[1] = !!loaded;
+
+ err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_FCT,
+ PCAN_USBPRO_FCT_DRVLD, buffer,
+ PCAN_USBPRO_FCT_DRVLD_REQ_LEN);
+ kfree(buffer);
+
+ return err;
+}
+
+static inline
+struct pcan_usb_pro_interface *pcan_usb_pro_dev_if(struct peak_usb_device *dev)
+{
+ struct pcan_usb_pro_device *pdev =
+ container_of(dev, struct pcan_usb_pro_device, dev);
+ return pdev->usb_if;
+}
+
+static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if,
+ struct pcan_usb_pro_rxmsg *rx)
+{
+ const unsigned int ctrl_idx = (rx->len >> 4) & 0x0f;
+ struct peak_usb_device *dev = usb_if->dev[ctrl_idx];
+ struct net_device *netdev = dev->netdev;
+ struct can_frame *can_frame;
+ struct sk_buff *skb;
+ struct timeval tv;
+ struct skb_shared_hwtstamps *hwts;
+
+ skb = alloc_can_skb(netdev, &can_frame);
+ if (!skb)
+ return -ENOMEM;
+
+ can_frame->can_id = le32_to_cpu(rx->id);
+ can_frame->can_dlc = rx->len & 0x0f;
+
+ if (rx->flags & PCAN_USBPRO_EXT)
+ can_frame->can_id |= CAN_EFF_FLAG;
+
+ if (rx->flags & PCAN_USBPRO_RTR)
+ can_frame->can_id |= CAN_RTR_FLAG;
+ else
+ memcpy(can_frame->data, rx->data, can_frame->can_dlc);
+
+ peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv);
+ hwts = skb_hwtstamps(skb);
+ hwts->hwtstamp = timeval_to_ktime(tv);
+
+ netif_rx(skb);
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += can_frame->can_dlc;
+
+ return 0;
+}
+
+static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
+ struct pcan_usb_pro_rxstatus *er)
+{
+ const u32 raw_status = le32_to_cpu(er->status);
+ const unsigned int ctrl_idx = (er->channel >> 4) & 0x0f;
+ struct peak_usb_device *dev = usb_if->dev[ctrl_idx];
+ struct net_device *netdev = dev->netdev;
+ struct can_frame *can_frame;
+ enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
+ u8 err_mask = 0;
+ struct sk_buff *skb;
+ struct timeval tv;
+ struct skb_shared_hwtstamps *hwts;
+
+ /* nothing should be sent while in BUS_OFF state */
+ if (dev->can.state == CAN_STATE_BUS_OFF)
+ return 0;
+
+ if (!raw_status) {
+ /* no error bit (back to active state) */
+ dev->can.state = CAN_STATE_ERROR_ACTIVE;
+ return 0;
+ }
+
+ if (raw_status & (PCAN_USBPRO_STATUS_OVERRUN |
+ PCAN_USBPRO_STATUS_QOVERRUN)) {
+ /* trick to bypass next comparison and process other errors */
+ new_state = CAN_STATE_MAX;
+ }
+
+ if (raw_status & PCAN_USBPRO_STATUS_BUS) {
+ new_state = CAN_STATE_BUS_OFF;
+ } else if (raw_status & PCAN_USBPRO_STATUS_ERROR) {
+ u32 rx_err_cnt = (le32_to_cpu(er->err_frm) & 0x00ff0000) >> 16;
+ u32 tx_err_cnt = (le32_to_cpu(er->err_frm) & 0xff000000) >> 24;
+
+ if (rx_err_cnt > 127)
+ err_mask |= CAN_ERR_CRTL_RX_PASSIVE;
+ else if (rx_err_cnt > 96)
+ err_mask |= CAN_ERR_CRTL_RX_WARNING;
+
+ if (tx_err_cnt > 127)
+ err_mask |= CAN_ERR_CRTL_TX_PASSIVE;
+ else if (tx_err_cnt > 96)
+ err_mask |= CAN_ERR_CRTL_TX_WARNING;
+
+ if (err_mask & (CAN_ERR_CRTL_RX_WARNING |
+ CAN_ERR_CRTL_TX_WARNING))
+ new_state = CAN_STATE_ERROR_WARNING;
+ else if (err_mask & (CAN_ERR_CRTL_RX_PASSIVE |
+ CAN_ERR_CRTL_TX_PASSIVE))
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ }
+
+ /* donot post any error if current state didn't change */
+ if (dev->can.state == new_state)
+ return 0;
+
+ /* allocate an skb to store the error frame */
+ skb = alloc_can_err_skb(netdev, &can_frame);
+ if (!skb)
+ return -ENOMEM;
+
+ switch (new_state) {
+ case CAN_STATE_BUS_OFF:
+ can_frame->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(netdev);
+ break;
+
+ case CAN_STATE_ERROR_PASSIVE:
+ can_frame->can_id |= CAN_ERR_CRTL;
+ can_frame->data[1] |= err_mask;
+ dev->can.can_stats.error_passive++;
+ break;
+
+ case CAN_STATE_ERROR_WARNING:
+ can_frame->can_id |= CAN_ERR_CRTL;
+ can_frame->data[1] |= err_mask;
+ dev->can.can_stats.error_warning++;
+ break;
+
+ case CAN_STATE_ERROR_ACTIVE:
+ break;
+
+ default:
+ /* CAN_STATE_MAX (trick to handle other errors) */
+ if (raw_status & PCAN_USBPRO_STATUS_OVERRUN) {
+ can_frame->can_id |= CAN_ERR_PROT;
+ can_frame->data[2] |= CAN_ERR_PROT_OVERLOAD;
+ netdev->stats.rx_over_errors++;
+ netdev->stats.rx_errors++;
+ }
+
+ if (raw_status & PCAN_USBPRO_STATUS_QOVERRUN) {
+ can_frame->can_id |= CAN_ERR_CRTL;
+ can_frame->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+ netdev->stats.rx_over_errors++;
+ netdev->stats.rx_errors++;
+ }
+
+ new_state = CAN_STATE_ERROR_ACTIVE;
+ break;
+ }
+
+ dev->can.state = new_state;
+
+ peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv);
+ hwts = skb_hwtstamps(skb);
+ hwts->hwtstamp = timeval_to_ktime(tv);
+ netif_rx(skb);
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += can_frame->can_dlc;
+
+ return 0;
+}
+
+static void pcan_usb_pro_handle_ts(struct pcan_usb_pro_interface *usb_if,
+ struct pcan_usb_pro_rxts *ts)
+{
+ /* should wait until clock is stabilized */
+ if (usb_if->cm_ignore_count > 0)
+ usb_if->cm_ignore_count--;
+ else
+ peak_usb_set_ts_now(&usb_if->time_ref,
+ le32_to_cpu(ts->ts64[1]));
+}
+
+/*
+ * callback for bulk IN urb
+ */
+static int pcan_usb_pro_decode_buf(struct peak_usb_device *dev, struct urb *urb)
+{
+ struct pcan_usb_pro_interface *usb_if = pcan_usb_pro_dev_if(dev);
+ struct net_device *netdev = dev->netdev;
+ struct pcan_usb_pro_msg usb_msg;
+ u8 *rec_ptr, *msg_end;
+ u16 rec_cnt;
+ int err = 0;
+
+ rec_ptr = pcan_msg_init(&usb_msg, urb->transfer_buffer,
+ urb->actual_length);
+ if (!rec_ptr) {
+ netdev_err(netdev, "bad msg hdr len %d\n", urb->actual_length);
+ return -EINVAL;
+ }
+
+ /* loop reading all the records from the incoming message */
+ msg_end = urb->transfer_buffer + urb->actual_length;
+ rec_cnt = le16_to_cpu(*usb_msg.u.rec_cnt_rd);
+ for (; rec_cnt > 0; rec_cnt--) {
+ union pcan_usb_pro_rec *pr = (union pcan_usb_pro_rec *)rec_ptr;
+ u16 sizeof_rec = pcan_usb_pro_sizeof_rec[pr->data_type];
+
+ if (!sizeof_rec) {
+ netdev_err(netdev,
+ "got unsupported rec in usb msg:\n");
+ err = -ENOTSUPP;
+ break;
+ }
+
+ /* check if the record goes out of current packet */
+ if (rec_ptr + sizeof_rec > msg_end) {
+ netdev_err(netdev,
+ "got frag rec: should inc usb rx buf size\n");
+ err = -EBADMSG;
+ break;
+ }
+
+ switch (pr->data_type) {
+ case PCAN_USBPRO_RXMSG8:
+ case PCAN_USBPRO_RXMSG4:
+ case PCAN_USBPRO_RXMSG0:
+ case PCAN_USBPRO_RXRTR:
+ err = pcan_usb_pro_handle_canmsg(usb_if, &pr->rx_msg);
+ if (err < 0)
+ goto fail;
+ break;
+
+ case PCAN_USBPRO_RXSTATUS:
+ err = pcan_usb_pro_handle_error(usb_if, &pr->rx_status);
+ if (err < 0)
+ goto fail;
+ break;
+
+ case PCAN_USBPRO_RXTS:
+ pcan_usb_pro_handle_ts(usb_if, &pr->rx_ts);
+ break;
+
+ default:
+ netdev_err(netdev,
+ "unhandled rec type 0x%02x (%d): ignored\n",
+ pr->data_type, pr->data_type);
+ break;
+ }
+
+ rec_ptr += sizeof_rec;
+ }
+
+fail:
+ if (err)
+ pcan_dump_mem("received msg",
+ urb->transfer_buffer, urb->actual_length);
+
+ return err;
+}
+
+static int pcan_usb_pro_encode_msg(struct peak_usb_device *dev,
+ struct sk_buff *skb, u8 *obuf, size_t *size)
+{
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u8 data_type, len, flags;
+ struct pcan_usb_pro_msg usb_msg;
+
+ pcan_msg_init_empty(&usb_msg, obuf, *size);
+
+ if ((cf->can_id & CAN_RTR_FLAG) || (cf->can_dlc == 0))
+ data_type = PCAN_USBPRO_TXMSG0;
+ else if (cf->can_dlc <= 4)
+ data_type = PCAN_USBPRO_TXMSG4;
+ else
+ data_type = PCAN_USBPRO_TXMSG8;
+
+ len = (dev->ctrl_idx << 4) | (cf->can_dlc & 0x0f);
+
+ flags = 0;
+ if (cf->can_id & CAN_EFF_FLAG)
+ flags |= 0x02;
+ if (cf->can_id & CAN_RTR_FLAG)
+ flags |= 0x01;
+
+ pcan_msg_add_rec(&usb_msg, data_type, 0, flags, len, cf->can_id,
+ cf->data);
+
+ *size = usb_msg.rec_buffer_len;
+
+ return 0;
+}
+
+static int pcan_usb_pro_start(struct peak_usb_device *dev)
+{
+ struct pcan_usb_pro_device *pdev =
+ container_of(dev, struct pcan_usb_pro_device, dev);
+ int err;
+
+ err = pcan_usb_pro_set_silent(dev,
+ dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY);
+ if (err)
+ return err;
+
+ /* filter mode: 0-> All OFF; 1->bypass */
+ err = pcan_usb_pro_set_filter(dev, 1);
+ if (err)
+ return err;
+
+ /* opening first device: */
+ if (pdev->usb_if->dev_opened_count == 0) {
+ /* reset time_ref */
+ peak_usb_init_time_ref(&pdev->usb_if->time_ref, &pcan_usb_pro);
+
+ /* ask device to send ts messages */
+ err = pcan_usb_pro_set_ts(dev, 1);
+ }
+
+ pdev->usb_if->dev_opened_count++;
+
+ return err;
+}
+
+/*
+ * stop interface
+ * (last chance before set bus off)
+ */
+static int pcan_usb_pro_stop(struct peak_usb_device *dev)
+{
+ struct pcan_usb_pro_device *pdev =
+ container_of(dev, struct pcan_usb_pro_device, dev);
+
+ /* turn off ts msgs for that interface if no other dev opened */
+ if (pdev->usb_if->dev_opened_count == 1)
+ pcan_usb_pro_set_ts(dev, 0);
+
+ pdev->usb_if->dev_opened_count--;
+
+ return 0;
+}
+
+/*
+ * called when probing to initialize a device object.
+ */
+static int pcan_usb_pro_init(struct peak_usb_device *dev)
+{
+ struct pcan_usb_pro_device *pdev =
+ container_of(dev, struct pcan_usb_pro_device, dev);
+ struct pcan_usb_pro_interface *usb_if = NULL;
+ struct pcan_usb_pro_fwinfo *fi = NULL;
+ struct pcan_usb_pro_blinfo *bi = NULL;
+ int err;
+
+ /* do this for 1st channel only */
+ if (!dev->prev_siblings) {
+ /* allocate netdevices common structure attached to first one */
+ usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface),
+ GFP_KERNEL);
+ fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL);
+ bi = kmalloc(sizeof(struct pcan_usb_pro_blinfo), GFP_KERNEL);
+ if (!usb_if || !fi || !bi) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ /* number of ts msgs to ignore before taking one into account */
+ usb_if->cm_ignore_count = 5;
+
+ /*
+ * explicit use of dev_xxx() instead of netdev_xxx() here:
+ * information displayed are related to the device itself, not
+ * to the canx netdevices.
+ */
+ err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
+ PCAN_USBPRO_INFO_FW,
+ fi, sizeof(*fi));
+ if (err) {
+ dev_err(dev->netdev->dev.parent,
+ "unable to read %s firmware info (err %d)\n",
+ pcan_usb_pro.name, err);
+ goto err_out;
+ }
+
+ err = pcan_usb_pro_send_req(dev, PCAN_USBPRO_REQ_INFO,
+ PCAN_USBPRO_INFO_BL,
+ bi, sizeof(*bi));
+ if (err) {
+ dev_err(dev->netdev->dev.parent,
+ "unable to read %s bootloader info (err %d)\n",
+ pcan_usb_pro.name, err);
+ goto err_out;
+ }
+
+ /* tell the device the can driver is running */
+ err = pcan_usb_pro_drv_loaded(dev, 1);
+ if (err)
+ goto err_out;
+
+ dev_info(dev->netdev->dev.parent,
+ "PEAK-System %s hwrev %u serial %08X.%08X (%u channels)\n",
+ pcan_usb_pro.name,
+ bi->hw_rev, bi->serial_num_hi, bi->serial_num_lo,
+ pcan_usb_pro.ctrl_count);
+ } else {
+ usb_if = pcan_usb_pro_dev_if(dev->prev_siblings);
+ }
+
+ pdev->usb_if = usb_if;
+ usb_if->dev[dev->ctrl_idx] = dev;
+
+ /* set LED in default state (end of init phase) */
+ pcan_usb_pro_set_led(dev, 0, 1);
+
+ kfree(bi);
+ kfree(fi);
+
+ return 0;
+
+ err_out:
+ kfree(bi);
+ kfree(fi);
+ kfree(usb_if);
+
+ return err;
+}
+
+static void pcan_usb_pro_exit(struct peak_usb_device *dev)
+{
+ struct pcan_usb_pro_device *pdev =
+ container_of(dev, struct pcan_usb_pro_device, dev);
+
+ /*
+ * when rmmod called before unplug and if down, should reset things
+ * before leaving
+ */
+ if (dev->can.state != CAN_STATE_STOPPED) {
+ /* set bus off on the corresponding channel */
+ pcan_usb_pro_set_bus(dev, 0);
+ }
+
+ /* if channel #0 (only) */
+ if (dev->ctrl_idx == 0) {
+ /* turn off calibration message if any device were opened */
+ if (pdev->usb_if->dev_opened_count > 0)
+ pcan_usb_pro_set_ts(dev, 0);
+
+ /* tell the PCAN-USB Pro device the driver is being unloaded */
+ pcan_usb_pro_drv_loaded(dev, 0);
+ }
+}
+
+/*
+ * called when PCAN-USB Pro adapter is unplugged
+ */
+static void pcan_usb_pro_free(struct peak_usb_device *dev)
+{
+ /* last device: can free pcan_usb_pro_interface object now */
+ if (!dev->prev_siblings && !dev->next_siblings)
+ kfree(pcan_usb_pro_dev_if(dev));
+}
+
+/*
+ * probe function for new PCAN-USB Pro usb interface
+ */
+static int pcan_usb_pro_probe(struct usb_interface *intf)
+{
+ struct usb_host_interface *if_desc;
+ int i;
+
+ if_desc = intf->altsetting;
+
+ /* check interface endpoint addresses */
+ for (i = 0; i < if_desc->desc.bNumEndpoints; i++) {
+ struct usb_endpoint_descriptor *ep = &if_desc->endpoint[i].desc;
+
+ /*
+ * below is the list of valid ep addreses. Any other ep address
+ * is considered as not-CAN interface address => no dev created
+ */
+ switch (ep->bEndpointAddress) {
+ case PCAN_USBPRO_EP_CMDOUT:
+ case PCAN_USBPRO_EP_CMDIN:
+ case PCAN_USBPRO_EP_MSGOUT_0:
+ case PCAN_USBPRO_EP_MSGOUT_1:
+ case PCAN_USBPRO_EP_MSGIN:
+ case PCAN_USBPRO_EP_UNUSED:
+ break;
+ default:
+ return -ENODEV;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * describe the PCAN-USB Pro adapter
+ */
+struct peak_usb_adapter pcan_usb_pro = {
+ .name = "PCAN-USB Pro",
+ .device_id = PCAN_USBPRO_PRODUCT_ID,
+ .ctrl_count = PCAN_USBPRO_CHANNEL_COUNT,
+ .clock = {
+ .freq = PCAN_USBPRO_CRYSTAL_HZ,
+ },
+ .bittiming_const = {
+ .name = "pcan_usb_pro",
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 1024,
+ .brp_inc = 1,
+ },
+
+ /* size of device private data */
+ .sizeof_dev_private = sizeof(struct pcan_usb_pro_device),
+
+ /* timestamps usage */
+ .ts_used_bits = 32,
+ .ts_period = 1000000, /* calibration period in ts. */
+ .us_per_ts_scale = 1, /* us = (ts * scale) >> shift */
+ .us_per_ts_shift = 0,
+
+ /* give here messages in/out endpoints */
+ .ep_msg_in = PCAN_USBPRO_EP_MSGIN,
+ .ep_msg_out = {PCAN_USBPRO_EP_MSGOUT_0, PCAN_USBPRO_EP_MSGOUT_1},
+
+ /* size of rx/tx usb buffers */
+ .rx_buffer_size = PCAN_USBPRO_RX_BUFFER_SIZE,
+ .tx_buffer_size = PCAN_USBPRO_TX_BUFFER_SIZE,
+
+ /* device callbacks */
+ .intf_probe = pcan_usb_pro_probe,
+ .dev_init = pcan_usb_pro_init,
+ .dev_exit = pcan_usb_pro_exit,
+ .dev_free = pcan_usb_pro_free,
+ .dev_set_bus = pcan_usb_pro_set_bus,
+ .dev_set_bittiming = pcan_usb_pro_set_bittiming,
+ .dev_get_device_id = pcan_usb_pro_get_device_id,
+ .dev_decode_buf = pcan_usb_pro_decode_buf,
+ .dev_encode_msg = pcan_usb_pro_encode_msg,
+ .dev_start = pcan_usb_pro_start,
+ .dev_stop = pcan_usb_pro_stop,
+ .dev_restart_async = pcan_usb_pro_restart_async,
+};
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.h b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
new file mode 100644
index 00000000000..32275af547e
--- /dev/null
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.h
@@ -0,0 +1,179 @@
+/*
+ * CAN driver for PEAK System PCAN-USB Pro adapter
+ * Derived from the PCAN project file driver/src/pcan_usbpro_fw.h
+ *
+ * Copyright (C) 2003-2011 PEAK System-Technik GmbH
+ * Copyright (C) 2011-2012 Stephane Grosjean <s.grosjean@peak-system.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#ifndef PCAN_USB_PRO_H
+#define PCAN_USB_PRO_H
+
+/*
+ * USB Vendor request data types
+ */
+#define PCAN_USBPRO_REQ_INFO 0
+#define PCAN_USBPRO_REQ_FCT 2
+
+/* Vendor Request value for XXX_INFO */
+#define PCAN_USBPRO_INFO_BL 0
+#define PCAN_USBPRO_INFO_FW 1
+
+/* Vendor Request value for XXX_FCT */
+#define PCAN_USBPRO_FCT_DRVLD 5 /* tell device driver is loaded */
+#define PCAN_USBPRO_FCT_DRVLD_REQ_LEN 16
+
+/* PCAN_USBPRO_INFO_BL vendor request record type */
+struct __packed pcan_usb_pro_blinfo {
+ u32 ctrl_type;
+ u8 version[4];
+ u8 day;
+ u8 month;
+ u8 year;
+ u8 dummy;
+ u32 serial_num_hi;
+ u32 serial_num_lo;
+ u32 hw_type;
+ u32 hw_rev;
+};
+
+/* PCAN_USBPRO_INFO_FW vendor request record type */
+struct __packed pcan_usb_pro_fwinfo {
+ u32 ctrl_type;
+ u8 version[4];
+ u8 day;
+ u8 month;
+ u8 year;
+ u8 dummy;
+ u32 fw_type;
+};
+
+/*
+ * USB Command record types
+ */
+#define PCAN_USBPRO_SETBTR 0x02
+#define PCAN_USBPRO_SETBUSACT 0x04
+#define PCAN_USBPRO_SETSILENT 0x05
+#define PCAN_USBPRO_SETFILTR 0x0a
+#define PCAN_USBPRO_SETTS 0x10
+#define PCAN_USBPRO_GETDEVID 0x12
+#define PCAN_USBPRO_SETLED 0x1C
+#define PCAN_USBPRO_RXMSG8 0x80
+#define PCAN_USBPRO_RXMSG4 0x81
+#define PCAN_USBPRO_RXMSG0 0x82
+#define PCAN_USBPRO_RXRTR 0x83
+#define PCAN_USBPRO_RXSTATUS 0x84
+#define PCAN_USBPRO_RXTS 0x85
+#define PCAN_USBPRO_TXMSG8 0x41
+#define PCAN_USBPRO_TXMSG4 0x42
+#define PCAN_USBPRO_TXMSG0 0x43
+
+/* record structures */
+struct __packed pcan_usb_pro_btr {
+ u8 data_type;
+ u8 channel;
+ u16 dummy;
+ u32 CCBT;
+};
+
+struct __packed pcan_usb_pro_busact {
+ u8 data_type;
+ u8 channel;
+ u16 onoff;
+};
+
+struct __packed pcan_usb_pro_silent {
+ u8 data_type;
+ u8 channel;
+ u16 onoff;
+};
+
+struct __packed pcan_usb_pro_filter {
+ u8 data_type;
+ u8 dummy;
+ u16 filter_mode;
+};
+
+struct __packed pcan_usb_pro_setts {
+ u8 data_type;
+ u8 dummy;
+ u16 mode;
+};
+
+struct __packed pcan_usb_pro_devid {
+ u8 data_type;
+ u8 channel;
+ u16 dummy;
+ u32 serial_num;
+};
+
+struct __packed pcan_usb_pro_setled {
+ u8 data_type;
+ u8 channel;
+ u16 mode;
+ u32 timeout;
+};
+
+struct __packed pcan_usb_pro_rxmsg {
+ u8 data_type;
+ u8 client;
+ u8 flags;
+ u8 len;
+ u32 ts32;
+ u32 id;
+
+ u8 data[8];
+};
+
+#define PCAN_USBPRO_STATUS_ERROR 0x0001
+#define PCAN_USBPRO_STATUS_BUS 0x0002
+#define PCAN_USBPRO_STATUS_OVERRUN 0x0004
+#define PCAN_USBPRO_STATUS_QOVERRUN 0x0008
+
+struct __packed pcan_usb_pro_rxstatus {
+ u8 data_type;
+ u8 channel;
+ u16 status;
+ u32 ts32;
+ u32 err_frm;
+};
+
+struct __packed pcan_usb_pro_rxts {
+ u8 data_type;
+ u8 dummy[3];
+ u32 ts64[2];
+};
+
+struct __packed pcan_usb_pro_txmsg {
+ u8 data_type;
+ u8 client;
+ u8 flags;
+ u8 len;
+ u32 id;
+ u8 data[8];
+};
+
+union pcan_usb_pro_rec {
+ u8 data_type;
+ struct pcan_usb_pro_btr btr;
+ struct pcan_usb_pro_busact bus_act;
+ struct pcan_usb_pro_silent silent_mode;
+ struct pcan_usb_pro_filter filter_mode;
+ struct pcan_usb_pro_setts ts;
+ struct pcan_usb_pro_devid dev_id;
+ struct pcan_usb_pro_setled set_led;
+ struct pcan_usb_pro_rxmsg rx_msg;
+ struct pcan_usb_pro_rxstatus rx_status;
+ struct pcan_usb_pro_rxts rx_ts;
+ struct pcan_usb_pro_txmsg tx_msg;
+};
+
+#endif
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
new file mode 100644
index 00000000000..ef674ecb82f
--- /dev/null
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -0,0 +1,1035 @@
+/*
+ * CAN driver for "8 devices" USB2CAN converter
+ *
+ * Copyright (C) 2012 Bernd Krumboeck (krumboeck@universalnet.at)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.
+ *
+ * This driver is inspired by the 3.2.0 version of drivers/net/can/usb/ems_usb.c
+ * and drivers/net/can/usb/esd_usb2.c
+ *
+ * Many thanks to Gerhard Bertelsmann (info@gerhard-bertelsmann.de)
+ * for testing and fixing this driver. Also many thanks to "8 devices",
+ * who were very cooperative and answered my questions.
+ */
+
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+
+/* driver constants */
+#define MAX_RX_URBS 20
+#define MAX_TX_URBS 20
+#define RX_BUFFER_SIZE 64
+
+/* vendor and product id */
+#define USB_8DEV_VENDOR_ID 0x0483
+#define USB_8DEV_PRODUCT_ID 0x1234
+
+/* endpoints */
+enum usb_8dev_endpoint {
+ USB_8DEV_ENDP_DATA_RX = 1,
+ USB_8DEV_ENDP_DATA_TX,
+ USB_8DEV_ENDP_CMD_RX,
+ USB_8DEV_ENDP_CMD_TX
+};
+
+/* device CAN clock */
+#define USB_8DEV_ABP_CLOCK 32000000
+
+/* setup flags */
+#define USB_8DEV_SILENT 0x01
+#define USB_8DEV_LOOPBACK 0x02
+#define USB_8DEV_DISABLE_AUTO_RESTRANS 0x04
+#define USB_8DEV_STATUS_FRAME 0x08
+
+/* commands */
+enum usb_8dev_cmd {
+ USB_8DEV_RESET = 1,
+ USB_8DEV_OPEN,
+ USB_8DEV_CLOSE,
+ USB_8DEV_SET_SPEED,
+ USB_8DEV_SET_MASK_FILTER,
+ USB_8DEV_GET_STATUS,
+ USB_8DEV_GET_STATISTICS,
+ USB_8DEV_GET_SERIAL,
+ USB_8DEV_GET_SOFTW_VER,
+ USB_8DEV_GET_HARDW_VER,
+ USB_8DEV_RESET_TIMESTAMP,
+ USB_8DEV_GET_SOFTW_HARDW_VER
+};
+
+/* command options */
+#define USB_8DEV_BAUD_MANUAL 0x09
+#define USB_8DEV_CMD_START 0x11
+#define USB_8DEV_CMD_END 0x22
+
+#define USB_8DEV_CMD_SUCCESS 0
+#define USB_8DEV_CMD_ERROR 255
+
+#define USB_8DEV_CMD_TIMEOUT 1000
+
+/* frames */
+#define USB_8DEV_DATA_START 0x55
+#define USB_8DEV_DATA_END 0xAA
+
+#define USB_8DEV_TYPE_CAN_FRAME 0
+#define USB_8DEV_TYPE_ERROR_FRAME 3
+
+#define USB_8DEV_EXTID 0x01
+#define USB_8DEV_RTR 0x02
+#define USB_8DEV_ERR_FLAG 0x04
+
+/* status */
+#define USB_8DEV_STATUSMSG_OK 0x00 /* Normal condition. */
+#define USB_8DEV_STATUSMSG_OVERRUN 0x01 /* Overrun occured when sending */
+#define USB_8DEV_STATUSMSG_BUSLIGHT 0x02 /* Error counter has reached 96 */
+#define USB_8DEV_STATUSMSG_BUSHEAVY 0x03 /* Error count. has reached 128 */
+#define USB_8DEV_STATUSMSG_BUSOFF 0x04 /* Device is in BUSOFF */
+#define USB_8DEV_STATUSMSG_STUFF 0x20 /* Stuff Error */
+#define USB_8DEV_STATUSMSG_FORM 0x21 /* Form Error */
+#define USB_8DEV_STATUSMSG_ACK 0x23 /* Ack Error */
+#define USB_8DEV_STATUSMSG_BIT0 0x24 /* Bit1 Error */
+#define USB_8DEV_STATUSMSG_BIT1 0x25 /* Bit0 Error */
+#define USB_8DEV_STATUSMSG_CRC 0x27 /* CRC Error */
+
+#define USB_8DEV_RP_MASK 0x7F /* Mask for Receive Error Bit */
+
+
+/* table of devices that work with this driver */
+static const struct usb_device_id usb_8dev_table[] = {
+ { USB_DEVICE(USB_8DEV_VENDOR_ID, USB_8DEV_PRODUCT_ID) },
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, usb_8dev_table);
+
+struct usb_8dev_tx_urb_context {
+ struct usb_8dev_priv *priv;
+
+ u32 echo_index;
+ u8 dlc;
+};
+
+/* Structure to hold all of our device specific stuff */
+struct usb_8dev_priv {
+ struct can_priv can; /* must be the first member */
+
+ struct sk_buff *echo_skb[MAX_TX_URBS];
+
+ struct usb_device *udev;
+ struct net_device *netdev;
+
+ atomic_t active_tx_urbs;
+ struct usb_anchor tx_submitted;
+ struct usb_8dev_tx_urb_context tx_contexts[MAX_TX_URBS];
+
+ struct usb_anchor rx_submitted;
+
+ struct can_berr_counter bec;
+
+ u8 *cmd_msg_buffer;
+
+ struct mutex usb_8dev_cmd_lock;
+
+};
+
+/* tx frame */
+struct __packed usb_8dev_tx_msg {
+ u8 begin;
+ u8 flags; /* RTR and EXT_ID flag */
+ __be32 id; /* upper 3 bits not used */
+ u8 dlc; /* data length code 0-8 bytes */
+ u8 data[8]; /* 64-bit data */
+ u8 end;
+};
+
+/* rx frame */
+struct __packed usb_8dev_rx_msg {
+ u8 begin;
+ u8 type; /* frame type */
+ u8 flags; /* RTR and EXT_ID flag */
+ __be32 id; /* upper 3 bits not used */
+ u8 dlc; /* data length code 0-8 bytes */
+ u8 data[8]; /* 64-bit data */
+ __be32 timestamp; /* 32-bit timestamp */
+ u8 end;
+};
+
+/* command frame */
+struct __packed usb_8dev_cmd_msg {
+ u8 begin;
+ u8 channel; /* unkown - always 0 */
+ u8 command; /* command to execute */
+ u8 opt1; /* optional parameter / return value */
+ u8 opt2; /* optional parameter 2 */
+ u8 data[10]; /* optional parameter and data */
+ u8 end;
+};
+
+static int usb_8dev_send_cmd_msg(struct usb_8dev_priv *priv, u8 *msg, int size)
+{
+ int actual_length;
+
+ return usb_bulk_msg(priv->udev,
+ usb_sndbulkpipe(priv->udev, USB_8DEV_ENDP_CMD_TX),
+ msg, size, &actual_length, USB_8DEV_CMD_TIMEOUT);
+}
+
+static int usb_8dev_wait_cmd_msg(struct usb_8dev_priv *priv, u8 *msg, int size,
+ int *actual_length)
+{
+ return usb_bulk_msg(priv->udev,
+ usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_CMD_RX),
+ msg, size, actual_length, USB_8DEV_CMD_TIMEOUT);
+}
+
+/* Send command to device and receive result.
+ * Command was successful when opt1 = 0.
+ */
+static int usb_8dev_send_cmd(struct usb_8dev_priv *priv,
+ struct usb_8dev_cmd_msg *out,
+ struct usb_8dev_cmd_msg *in)
+{
+ int err;
+ int num_bytes_read;
+ struct net_device *netdev;
+
+ netdev = priv->netdev;
+
+ out->begin = USB_8DEV_CMD_START;
+ out->end = USB_8DEV_CMD_END;
+
+ mutex_lock(&priv->usb_8dev_cmd_lock);
+
+ memcpy(priv->cmd_msg_buffer, out,
+ sizeof(struct usb_8dev_cmd_msg));
+
+ err = usb_8dev_send_cmd_msg(priv, priv->cmd_msg_buffer,
+ sizeof(struct usb_8dev_cmd_msg));
+ if (err < 0) {
+ netdev_err(netdev, "sending command message failed\n");
+ goto failed;
+ }
+
+ err = usb_8dev_wait_cmd_msg(priv, priv->cmd_msg_buffer,
+ sizeof(struct usb_8dev_cmd_msg),
+ &num_bytes_read);
+ if (err < 0) {
+ netdev_err(netdev, "no command message answer\n");
+ goto failed;
+ }
+
+ memcpy(in, priv->cmd_msg_buffer, sizeof(struct usb_8dev_cmd_msg));
+
+ if (in->begin != USB_8DEV_CMD_START || in->end != USB_8DEV_CMD_END ||
+ num_bytes_read != 16 || in->opt1 != 0)
+ err = -EPROTO;
+
+failed:
+ mutex_unlock(&priv->usb_8dev_cmd_lock);
+ return err;
+}
+
+/* Send open command to device */
+static int usb_8dev_cmd_open(struct usb_8dev_priv *priv)
+{
+ struct can_bittiming *bt = &priv->can.bittiming;
+ struct usb_8dev_cmd_msg outmsg;
+ struct usb_8dev_cmd_msg inmsg;
+ u32 ctrlmode = priv->can.ctrlmode;
+ u32 flags = USB_8DEV_STATUS_FRAME;
+ __be32 beflags;
+ __be16 bebrp;
+
+ memset(&outmsg, 0, sizeof(outmsg));
+ outmsg.command = USB_8DEV_OPEN;
+ outmsg.opt1 = USB_8DEV_BAUD_MANUAL;
+ outmsg.data[0] = bt->prop_seg + bt->phase_seg1;
+ outmsg.data[1] = bt->phase_seg2;
+ outmsg.data[2] = bt->sjw;
+
+ /* BRP */
+ bebrp = cpu_to_be16((u16)bt->brp);
+ memcpy(&outmsg.data[3], &bebrp, sizeof(bebrp));
+
+ /* flags */
+ if (ctrlmode & CAN_CTRLMODE_LOOPBACK)
+ flags |= USB_8DEV_LOOPBACK;
+ if (ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ flags |= USB_8DEV_SILENT;
+ if (ctrlmode & CAN_CTRLMODE_ONE_SHOT)
+ flags |= USB_8DEV_DISABLE_AUTO_RESTRANS;
+
+ beflags = cpu_to_be32(flags);
+ memcpy(&outmsg.data[5], &beflags, sizeof(beflags));
+
+ return usb_8dev_send_cmd(priv, &outmsg, &inmsg);
+}
+
+/* Send close command to device */
+static int usb_8dev_cmd_close(struct usb_8dev_priv *priv)
+{
+ struct usb_8dev_cmd_msg inmsg;
+ struct usb_8dev_cmd_msg outmsg = {
+ .channel = 0,
+ .command = USB_8DEV_CLOSE,
+ .opt1 = 0,
+ .opt2 = 0
+ };
+
+ return usb_8dev_send_cmd(priv, &outmsg, &inmsg);
+}
+
+/* Get firmware and hardware version */
+static int usb_8dev_cmd_version(struct usb_8dev_priv *priv, u32 *res)
+{
+ struct usb_8dev_cmd_msg inmsg;
+ struct usb_8dev_cmd_msg outmsg = {
+ .channel = 0,
+ .command = USB_8DEV_GET_SOFTW_HARDW_VER,
+ .opt1 = 0,
+ .opt2 = 0
+ };
+
+ int err = usb_8dev_send_cmd(priv, &outmsg, &inmsg);
+ if (err)
+ return err;
+
+ *res = be32_to_cpup((__be32 *)inmsg.data);
+
+ return err;
+}
+
+/* Set network device mode
+ *
+ * Maybe we should leave this function empty, because the device
+ * set mode variable with open command.
+ */
+static int usb_8dev_set_mode(struct net_device *netdev, enum can_mode mode)
+{
+ struct usb_8dev_priv *priv = netdev_priv(netdev);
+ int err = 0;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ err = usb_8dev_cmd_open(priv);
+ if (err)
+ netdev_warn(netdev, "couldn't start device");
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return err;
+}
+
+/* Read error/status frames */
+static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
+ struct usb_8dev_rx_msg *msg)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct net_device_stats *stats = &priv->netdev->stats;
+
+ /* Error message:
+ * byte 0: Status
+ * byte 1: bit 7: Receive Passive
+ * byte 1: bit 0-6: Receive Error Counter
+ * byte 2: Transmit Error Counter
+ * byte 3: Always 0 (maybe reserved for future use)
+ */
+
+ u8 state = msg->data[0];
+ u8 rxerr = msg->data[1] & USB_8DEV_RP_MASK;
+ u8 txerr = msg->data[2];
+ int rx_errors = 0;
+ int tx_errors = 0;
+
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (!skb)
+ return;
+
+ switch (state) {
+ case USB_8DEV_STATUSMSG_OK:
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_ACTIVE;
+ break;
+ case USB_8DEV_STATUSMSG_BUSOFF:
+ priv->can.state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ can_bus_off(priv->netdev);
+ break;
+ case USB_8DEV_STATUSMSG_OVERRUN:
+ case USB_8DEV_STATUSMSG_BUSLIGHT:
+ case USB_8DEV_STATUSMSG_BUSHEAVY:
+ cf->can_id |= CAN_ERR_CRTL;
+ break;
+ default:
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ priv->can.can_stats.bus_error++;
+ break;
+ }
+
+ switch (state) {
+ case USB_8DEV_STATUSMSG_OK:
+ case USB_8DEV_STATUSMSG_BUSOFF:
+ break;
+ case USB_8DEV_STATUSMSG_ACK:
+ cf->can_id |= CAN_ERR_ACK;
+ tx_errors = 1;
+ break;
+ case USB_8DEV_STATUSMSG_CRC:
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL;
+ rx_errors = 1;
+ break;
+ case USB_8DEV_STATUSMSG_BIT0:
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ tx_errors = 1;
+ break;
+ case USB_8DEV_STATUSMSG_BIT1:
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ tx_errors = 1;
+ break;
+ case USB_8DEV_STATUSMSG_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ rx_errors = 1;
+ break;
+ case USB_8DEV_STATUSMSG_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ rx_errors = 1;
+ break;
+ case USB_8DEV_STATUSMSG_OVERRUN:
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ stats->rx_over_errors++;
+ rx_errors = 1;
+ break;
+ case USB_8DEV_STATUSMSG_BUSLIGHT:
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ priv->can.can_stats.error_warning++;
+ break;
+ case USB_8DEV_STATUSMSG_BUSHEAVY:
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ priv->can.can_stats.error_passive++;
+ break;
+ default:
+ netdev_warn(priv->netdev,
+ "Unknown status/error message (%d)\n", state);
+ break;
+ }
+
+ if (tx_errors) {
+ cf->data[2] |= CAN_ERR_PROT_TX;
+ stats->tx_errors++;
+ }
+
+ if (rx_errors)
+ stats->rx_errors++;
+
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+
+ priv->bec.txerr = txerr;
+ priv->bec.rxerr = rxerr;
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+/* Read data and status frames */
+static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv,
+ struct usb_8dev_rx_msg *msg)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct net_device_stats *stats = &priv->netdev->stats;
+
+ if (msg->type == USB_8DEV_TYPE_ERROR_FRAME &&
+ msg->flags == USB_8DEV_ERR_FLAG) {
+ usb_8dev_rx_err_msg(priv, msg);
+ } else if (msg->type == USB_8DEV_TYPE_CAN_FRAME) {
+ skb = alloc_can_skb(priv->netdev, &cf);
+ if (!skb)
+ return;
+
+ cf->can_id = be32_to_cpu(msg->id);
+ cf->can_dlc = get_can_dlc(msg->dlc & 0xF);
+
+ if (msg->flags & USB_8DEV_EXTID)
+ cf->can_id |= CAN_EFF_FLAG;
+
+ if (msg->flags & USB_8DEV_RTR)
+ cf->can_id |= CAN_RTR_FLAG;
+ else
+ memcpy(cf->data, msg->data, cf->can_dlc);
+
+ netif_rx(skb);
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+
+ can_led_event(priv->netdev, CAN_LED_EVENT_RX);
+ } else {
+ netdev_warn(priv->netdev, "frame type %d unknown",
+ msg->type);
+ }
+
+}
+
+/* Callback for reading data from device
+ *
+ * Check urb status, call read function and resubmit urb read operation.
+ */
+static void usb_8dev_read_bulk_callback(struct urb *urb)
+{
+ struct usb_8dev_priv *priv = urb->context;
+ struct net_device *netdev;
+ int retval;
+ int pos = 0;
+
+ netdev = priv->netdev;
+
+ if (!netif_device_present(netdev))
+ return;
+
+ switch (urb->status) {
+ case 0: /* success */
+ break;
+
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ netdev_info(netdev, "Rx URB aborted (%d)\n",
+ urb->status);
+ goto resubmit_urb;
+ }
+
+ while (pos < urb->actual_length) {
+ struct usb_8dev_rx_msg *msg;
+
+ if (pos + sizeof(struct usb_8dev_rx_msg) > urb->actual_length) {
+ netdev_err(priv->netdev, "format error\n");
+ break;
+ }
+
+ msg = (struct usb_8dev_rx_msg *)(urb->transfer_buffer + pos);
+ usb_8dev_rx_can_msg(priv, msg);
+
+ pos += sizeof(struct usb_8dev_rx_msg);
+ }
+
+resubmit_urb:
+ usb_fill_bulk_urb(urb, priv->udev,
+ usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_RX),
+ urb->transfer_buffer, RX_BUFFER_SIZE,
+ usb_8dev_read_bulk_callback, priv);
+
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (retval == -ENODEV)
+ netif_device_detach(netdev);
+ else if (retval)
+ netdev_err(netdev,
+ "failed resubmitting read bulk urb: %d\n", retval);
+}
+
+/* Callback handler for write operations
+ *
+ * Free allocated buffers, check transmit status and
+ * calculate statistic.
+ */
+static void usb_8dev_write_bulk_callback(struct urb *urb)
+{
+ struct usb_8dev_tx_urb_context *context = urb->context;
+ struct usb_8dev_priv *priv;
+ struct net_device *netdev;
+
+ BUG_ON(!context);
+
+ priv = context->priv;
+ netdev = priv->netdev;
+
+ /* free up our allocated buffer */
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+
+ atomic_dec(&priv->active_tx_urbs);
+
+ if (!netif_device_present(netdev))
+ return;
+
+ if (urb->status)
+ netdev_info(netdev, "Tx URB aborted (%d)\n",
+ urb->status);
+
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += context->dlc;
+
+ can_get_echo_skb(netdev, context->echo_index);
+
+ can_led_event(netdev, CAN_LED_EVENT_TX);
+
+ /* Release context */
+ context->echo_index = MAX_TX_URBS;
+
+ netif_wake_queue(netdev);
+}
+
+/* Send data to device */
+static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct usb_8dev_priv *priv = netdev_priv(netdev);
+ struct net_device_stats *stats = &netdev->stats;
+ struct can_frame *cf = (struct can_frame *) skb->data;
+ struct usb_8dev_tx_msg *msg;
+ struct urb *urb;
+ struct usb_8dev_tx_urb_context *context = NULL;
+ u8 *buf;
+ int i, err;
+ size_t size = sizeof(struct usb_8dev_tx_msg);
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* create a URB, and a buffer for it, and copy the data to the URB */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ goto nomem;
+ }
+
+ buf = usb_alloc_coherent(priv->udev, size, GFP_ATOMIC,
+ &urb->transfer_dma);
+ if (!buf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ goto nomembuf;
+ }
+
+ memset(buf, 0, size);
+
+ msg = (struct usb_8dev_tx_msg *)buf;
+ msg->begin = USB_8DEV_DATA_START;
+ msg->flags = 0x00;
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ msg->flags |= USB_8DEV_RTR;
+
+ if (cf->can_id & CAN_EFF_FLAG)
+ msg->flags |= USB_8DEV_EXTID;
+
+ msg->id = cpu_to_be32(cf->can_id & CAN_ERR_MASK);
+ msg->dlc = cf->can_dlc;
+ memcpy(msg->data, cf->data, cf->can_dlc);
+ msg->end = USB_8DEV_DATA_END;
+
+ for (i = 0; i < MAX_TX_URBS; i++) {
+ if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
+ context = &priv->tx_contexts[i];
+ break;
+ }
+ }
+
+ /* May never happen! When this happens we'd more URBs in flight as
+ * allowed (MAX_TX_URBS).
+ */
+ if (!context)
+ goto nofreecontext;
+
+ context->priv = priv;
+ context->echo_index = i;
+ context->dlc = cf->can_dlc;
+
+ usb_fill_bulk_urb(urb, priv->udev,
+ usb_sndbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_TX),
+ buf, size, usb_8dev_write_bulk_callback, context);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &priv->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, context->echo_index);
+
+ atomic_inc(&priv->active_tx_urbs);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err))
+ goto failed;
+ else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
+ /* Slow down tx path */
+ netif_stop_queue(netdev);
+
+ /* Release our reference to this URB, the USB core will eventually free
+ * it entirely.
+ */
+ usb_free_urb(urb);
+
+ return NETDEV_TX_OK;
+
+nofreecontext:
+ usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
+ usb_free_urb(urb);
+
+ netdev_warn(netdev, "couldn't find free context");
+
+ return NETDEV_TX_BUSY;
+
+failed:
+ can_free_echo_skb(netdev, context->echo_index);
+
+ usb_unanchor_urb(urb);
+ usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
+
+ atomic_dec(&priv->active_tx_urbs);
+
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ else
+ netdev_warn(netdev, "failed tx_urb %d\n", err);
+
+nomembuf:
+ usb_free_urb(urb);
+
+nomem:
+ dev_kfree_skb(skb);
+ stats->tx_dropped++;
+
+ return NETDEV_TX_OK;
+}
+
+static int usb_8dev_get_berr_counter(const struct net_device *netdev,
+ struct can_berr_counter *bec)
+{
+ struct usb_8dev_priv *priv = netdev_priv(netdev);
+
+ bec->txerr = priv->bec.txerr;
+ bec->rxerr = priv->bec.rxerr;
+
+ return 0;
+}
+
+/* Start USB device */
+static int usb_8dev_start(struct usb_8dev_priv *priv)
+{
+ struct net_device *netdev = priv->netdev;
+ int err, i;
+
+ for (i = 0; i < MAX_RX_URBS; i++) {
+ struct urb *urb = NULL;
+ u8 *buf;
+
+ /* create a URB, and a buffer for it */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ netdev_err(netdev, "No memory left for URBs\n");
+ err = -ENOMEM;
+ break;
+ }
+
+ buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!buf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ usb_free_urb(urb);
+ err = -ENOMEM;
+ break;
+ }
+
+ usb_fill_bulk_urb(urb, priv->udev,
+ usb_rcvbulkpipe(priv->udev,
+ USB_8DEV_ENDP_DATA_RX),
+ buf, RX_BUFFER_SIZE,
+ usb_8dev_read_bulk_callback, priv);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &priv->rx_submitted);
+
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_free_coherent(priv->udev, RX_BUFFER_SIZE, buf,
+ urb->transfer_dma);
+ usb_free_urb(urb);
+ break;
+ }
+
+ /* Drop reference, USB core will take care of freeing it */
+ usb_free_urb(urb);
+ }
+
+ /* Did we submit any URBs */
+ if (i == 0) {
+ netdev_warn(netdev, "couldn't setup read URBs\n");
+ return err;
+ }
+
+ /* Warn if we've couldn't transmit all the URBs */
+ if (i < MAX_RX_URBS)
+ netdev_warn(netdev, "rx performance may be slow\n");
+
+ err = usb_8dev_cmd_open(priv);
+ if (err)
+ goto failed;
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ return 0;
+
+failed:
+ if (err == -ENODEV)
+ netif_device_detach(priv->netdev);
+
+ netdev_warn(netdev, "couldn't submit control: %d\n", err);
+
+ return err;
+}
+
+/* Open USB device */
+static int usb_8dev_open(struct net_device *netdev)
+{
+ struct usb_8dev_priv *priv = netdev_priv(netdev);
+ int err;
+
+ /* common open */
+ err = open_candev(netdev);
+ if (err)
+ return err;
+
+ can_led_event(netdev, CAN_LED_EVENT_OPEN);
+
+ /* finally start device */
+ err = usb_8dev_start(priv);
+ if (err) {
+ if (err == -ENODEV)
+ netif_device_detach(priv->netdev);
+
+ netdev_warn(netdev, "couldn't start device: %d\n",
+ err);
+
+ close_candev(netdev);
+
+ return err;
+ }
+
+ netif_start_queue(netdev);
+
+ return 0;
+}
+
+static void unlink_all_urbs(struct usb_8dev_priv *priv)
+{
+ int i;
+
+ usb_kill_anchored_urbs(&priv->rx_submitted);
+
+ usb_kill_anchored_urbs(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_urbs, 0);
+
+ for (i = 0; i < MAX_TX_URBS; i++)
+ priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+}
+
+/* Close USB device */
+static int usb_8dev_close(struct net_device *netdev)
+{
+ struct usb_8dev_priv *priv = netdev_priv(netdev);
+ int err = 0;
+
+ /* Send CLOSE command to CAN controller */
+ err = usb_8dev_cmd_close(priv);
+ if (err)
+ netdev_warn(netdev, "couldn't stop device");
+
+ priv->can.state = CAN_STATE_STOPPED;
+
+ netif_stop_queue(netdev);
+
+ /* Stop polling */
+ unlink_all_urbs(priv);
+
+ close_candev(netdev);
+
+ can_led_event(netdev, CAN_LED_EVENT_STOP);
+
+ return err;
+}
+
+static const struct net_device_ops usb_8dev_netdev_ops = {
+ .ndo_open = usb_8dev_open,
+ .ndo_stop = usb_8dev_close,
+ .ndo_start_xmit = usb_8dev_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static const struct can_bittiming_const usb_8dev_bittiming_const = {
+ .name = "usb_8dev",
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 1024,
+ .brp_inc = 1,
+};
+
+/* Probe USB device
+ *
+ * Check device and firmware.
+ * Set supported modes and bittiming constants.
+ * Allocate some memory.
+ */
+static int usb_8dev_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct net_device *netdev;
+ struct usb_8dev_priv *priv;
+ int i, err = -ENOMEM;
+ u32 version;
+ char buf[18];
+ struct usb_device *usbdev = interface_to_usbdev(intf);
+
+ /* product id looks strange, better we also check iProduct string */
+ if (usb_string(usbdev, usbdev->descriptor.iProduct, buf,
+ sizeof(buf)) > 0 && strcmp(buf, "USB2CAN converter")) {
+ dev_info(&usbdev->dev, "ignoring: not an USB2CAN converter\n");
+ return -ENODEV;
+ }
+
+ netdev = alloc_candev(sizeof(struct usb_8dev_priv), MAX_TX_URBS);
+ if (!netdev) {
+ dev_err(&intf->dev, "Couldn't alloc candev\n");
+ return -ENOMEM;
+ }
+
+ priv = netdev_priv(netdev);
+
+ priv->udev = usbdev;
+ priv->netdev = netdev;
+
+ priv->can.state = CAN_STATE_STOPPED;
+ priv->can.clock.freq = USB_8DEV_ABP_CLOCK;
+ priv->can.bittiming_const = &usb_8dev_bittiming_const;
+ priv->can.do_set_mode = usb_8dev_set_mode;
+ priv->can.do_get_berr_counter = usb_8dev_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+ CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_ONE_SHOT;
+
+ netdev->netdev_ops = &usb_8dev_netdev_ops;
+
+ netdev->flags |= IFF_ECHO; /* we support local echo */
+
+ init_usb_anchor(&priv->rx_submitted);
+
+ init_usb_anchor(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_urbs, 0);
+
+ for (i = 0; i < MAX_TX_URBS; i++)
+ priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+
+ priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg),
+ GFP_KERNEL);
+ if (!priv->cmd_msg_buffer)
+ goto cleanup_candev;
+
+ usb_set_intfdata(intf, priv);
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+
+ mutex_init(&priv->usb_8dev_cmd_lock);
+
+ err = register_candev(netdev);
+ if (err) {
+ netdev_err(netdev,
+ "couldn't register CAN device: %d\n", err);
+ goto cleanup_cmd_msg_buffer;
+ }
+
+ err = usb_8dev_cmd_version(priv, &version);
+ if (err) {
+ netdev_err(netdev, "can't get firmware version\n");
+ goto cleanup_unregister_candev;
+ } else {
+ netdev_info(netdev,
+ "firmware: %d.%d, hardware: %d.%d\n",
+ (version>>24) & 0xff, (version>>16) & 0xff,
+ (version>>8) & 0xff, version & 0xff);
+ }
+
+ devm_can_led_init(netdev);
+
+ return 0;
+
+cleanup_unregister_candev:
+ unregister_netdev(priv->netdev);
+
+cleanup_cmd_msg_buffer:
+ kfree(priv->cmd_msg_buffer);
+
+cleanup_candev:
+ free_candev(netdev);
+
+ return err;
+
+}
+
+/* Called by the usb core when driver is unloaded or device is removed */
+static void usb_8dev_disconnect(struct usb_interface *intf)
+{
+ struct usb_8dev_priv *priv = usb_get_intfdata(intf);
+
+ usb_set_intfdata(intf, NULL);
+
+ if (priv) {
+ netdev_info(priv->netdev, "device disconnected\n");
+
+ unregister_netdev(priv->netdev);
+ free_candev(priv->netdev);
+
+ unlink_all_urbs(priv);
+ }
+
+}
+
+static struct usb_driver usb_8dev_driver = {
+ .name = "usb_8dev",
+ .probe = usb_8dev_probe,
+ .disconnect = usb_8dev_disconnect,
+ .id_table = usb_8dev_table,
+};
+
+module_usb_driver(usb_8dev_driver);
+
+MODULE_AUTHOR("Bernd Krumboeck <krumboeck@universalnet.at>");
+MODULE_DESCRIPTION("CAN driver for 8 devices USB2CAN interfaces");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 103f0f1df28..4e94057ef5c 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -37,8 +37,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
- * Send feedback to <socketcan-users@lists.berlios.de>
- *
*/
#include <linux/module.h>
@@ -47,9 +45,12 @@
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/skb.h>
+#include <linux/slab.h>
#include <net/rtnetlink.h>
-static __initdata const char banner[] =
+static __initconst const char banner[] =
KERN_INFO "vcan: Virtual CAN interface driver\n";
MODULE_DESCRIPTION("virtual CAN interface");
@@ -63,33 +64,37 @@ MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
* See Documentation/networking/can.txt for details.
*/
-static int echo; /* echo testing. Default: 0 (Off) */
+static bool echo; /* echo testing. Default: 0 (Off) */
module_param(echo, bool, S_IRUGO);
MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
{
+ struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
struct net_device_stats *stats = &dev->stats;
stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ stats->rx_bytes += cfd->len;
- skb->protocol = htons(ETH_P_CAN);
skb->pkt_type = PACKET_BROADCAST;
skb->dev = dev;
skb->ip_summed = CHECKSUM_UNNECESSARY;
- netif_rx(skb);
+ netif_rx_ni(skb);
}
-static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
{
+ struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
struct net_device_stats *stats = &dev->stats;
int loop;
+ if (can_dropped_invalid_skb(dev, skb))
+ return NETDEV_TX_OK;
+
stats->tx_packets++;
- stats->tx_bytes += skb->len;
+ stats->tx_bytes += cfd->len;
/* set flag whether this packet has to be looped back */
loop = skb->pkt_type == PACKET_LOOPBACK;
@@ -103,51 +108,67 @@ static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
* CAN core already did the echo for us
*/
stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ stats->rx_bytes += cfd->len;
}
- kfree_skb(skb);
+ consume_skb(skb);
return NETDEV_TX_OK;
}
/* perform standard echo handling for CAN network interfaces */
if (loop) {
- struct sock *srcsk = skb->sk;
- skb = skb_share_check(skb, GFP_ATOMIC);
+ skb = can_create_echo_skb(skb);
if (!skb)
return NETDEV_TX_OK;
/* receive with packet counting */
- skb->sk = srcsk;
vcan_rx(skb, dev);
} else {
/* no looped packets => no counting */
- kfree_skb(skb);
+ consume_skb(skb);
}
return NETDEV_TX_OK;
}
+static int vcan_change_mtu(struct net_device *dev, int new_mtu)
+{
+ /* Do not allow changing the MTU while running */
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+ if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU)
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+ return 0;
+}
+
+static const struct net_device_ops vcan_netdev_ops = {
+ .ndo_start_xmit = vcan_tx,
+ .ndo_change_mtu = vcan_change_mtu,
+};
+
static void vcan_setup(struct net_device *dev)
{
- dev->type = ARPHRD_CAN;
- dev->mtu = sizeof(struct can_frame);
- dev->hard_header_len = 0;
- dev->addr_len = 0;
- dev->tx_queue_len = 0;
- dev->flags = IFF_NOARP;
+ dev->type = ARPHRD_CAN;
+ dev->mtu = CAN_MTU;
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->tx_queue_len = 0;
+ dev->flags = IFF_NOARP;
/* set flags according to driver capabilities */
if (echo)
dev->flags |= IFF_ECHO;
- dev->hard_start_xmit = vcan_tx;
- dev->destructor = free_netdev;
+ dev->netdev_ops = &vcan_netdev_ops;
+ dev->destructor = free_netdev;
}
static struct rtnl_link_ops vcan_link_ops __read_mostly = {
- .kind = "vcan",
- .setup = vcan_setup,
+ .kind = "vcan",
+ .setup = vcan_setup,
};
static __init int vcan_init_module(void)
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
new file mode 100644
index 00000000000..5e8b5609c06
--- /dev/null
+++ b/drivers/net/can/xilinx_can.c
@@ -0,0 +1,1208 @@
+/* Xilinx CAN device driver
+ *
+ * Copyright (C) 2012 - 2014 Xilinx, Inc.
+ * Copyright (C) 2009 PetaLogix. All rights reserved.
+ *
+ * Description:
+ * This driver is developed for Axi CAN IP and for Zynq CANPS Controller.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/led.h>
+
+#define DRIVER_NAME "xilinx_can"
+
+/* CAN registers set */
+enum xcan_reg {
+ XCAN_SRR_OFFSET = 0x00, /* Software reset */
+ XCAN_MSR_OFFSET = 0x04, /* Mode select */
+ XCAN_BRPR_OFFSET = 0x08, /* Baud rate prescaler */
+ XCAN_BTR_OFFSET = 0x0C, /* Bit timing */
+ XCAN_ECR_OFFSET = 0x10, /* Error counter */
+ XCAN_ESR_OFFSET = 0x14, /* Error status */
+ XCAN_SR_OFFSET = 0x18, /* Status */
+ XCAN_ISR_OFFSET = 0x1C, /* Interrupt status */
+ XCAN_IER_OFFSET = 0x20, /* Interrupt enable */
+ XCAN_ICR_OFFSET = 0x24, /* Interrupt clear */
+ XCAN_TXFIFO_ID_OFFSET = 0x30,/* TX FIFO ID */
+ XCAN_TXFIFO_DLC_OFFSET = 0x34, /* TX FIFO DLC */
+ XCAN_TXFIFO_DW1_OFFSET = 0x38, /* TX FIFO Data Word 1 */
+ XCAN_TXFIFO_DW2_OFFSET = 0x3C, /* TX FIFO Data Word 2 */
+ XCAN_RXFIFO_ID_OFFSET = 0x50, /* RX FIFO ID */
+ XCAN_RXFIFO_DLC_OFFSET = 0x54, /* RX FIFO DLC */
+ XCAN_RXFIFO_DW1_OFFSET = 0x58, /* RX FIFO Data Word 1 */
+ XCAN_RXFIFO_DW2_OFFSET = 0x5C, /* RX FIFO Data Word 2 */
+};
+
+/* CAN register bit masks - XCAN_<REG>_<BIT>_MASK */
+#define XCAN_SRR_CEN_MASK 0x00000002 /* CAN enable */
+#define XCAN_SRR_RESET_MASK 0x00000001 /* Soft Reset the CAN core */
+#define XCAN_MSR_LBACK_MASK 0x00000002 /* Loop back mode select */
+#define XCAN_MSR_SLEEP_MASK 0x00000001 /* Sleep mode select */
+#define XCAN_BRPR_BRP_MASK 0x000000FF /* Baud rate prescaler */
+#define XCAN_BTR_SJW_MASK 0x00000180 /* Synchronous jump width */
+#define XCAN_BTR_TS2_MASK 0x00000070 /* Time segment 2 */
+#define XCAN_BTR_TS1_MASK 0x0000000F /* Time segment 1 */
+#define XCAN_ECR_REC_MASK 0x0000FF00 /* Receive error counter */
+#define XCAN_ECR_TEC_MASK 0x000000FF /* Transmit error counter */
+#define XCAN_ESR_ACKER_MASK 0x00000010 /* ACK error */
+#define XCAN_ESR_BERR_MASK 0x00000008 /* Bit error */
+#define XCAN_ESR_STER_MASK 0x00000004 /* Stuff error */
+#define XCAN_ESR_FMER_MASK 0x00000002 /* Form error */
+#define XCAN_ESR_CRCER_MASK 0x00000001 /* CRC error */
+#define XCAN_SR_TXFLL_MASK 0x00000400 /* TX FIFO is full */
+#define XCAN_SR_ESTAT_MASK 0x00000180 /* Error status */
+#define XCAN_SR_ERRWRN_MASK 0x00000040 /* Error warning */
+#define XCAN_SR_NORMAL_MASK 0x00000008 /* Normal mode */
+#define XCAN_SR_LBACK_MASK 0x00000002 /* Loop back mode */
+#define XCAN_SR_CONFIG_MASK 0x00000001 /* Configuration mode */
+#define XCAN_IXR_TXFEMP_MASK 0x00004000 /* TX FIFO Empty */
+#define XCAN_IXR_WKUP_MASK 0x00000800 /* Wake up interrupt */
+#define XCAN_IXR_SLP_MASK 0x00000400 /* Sleep interrupt */
+#define XCAN_IXR_BSOFF_MASK 0x00000200 /* Bus off interrupt */
+#define XCAN_IXR_ERROR_MASK 0x00000100 /* Error interrupt */
+#define XCAN_IXR_RXNEMP_MASK 0x00000080 /* RX FIFO NotEmpty intr */
+#define XCAN_IXR_RXOFLW_MASK 0x00000040 /* RX FIFO Overflow intr */
+#define XCAN_IXR_RXOK_MASK 0x00000010 /* Message received intr */
+#define XCAN_IXR_TXFLL_MASK 0x00000004 /* Tx FIFO Full intr */
+#define XCAN_IXR_TXOK_MASK 0x00000002 /* TX successful intr */
+#define XCAN_IXR_ARBLST_MASK 0x00000001 /* Arbitration lost intr */
+#define XCAN_IDR_ID1_MASK 0xFFE00000 /* Standard msg identifier */
+#define XCAN_IDR_SRR_MASK 0x00100000 /* Substitute remote TXreq */
+#define XCAN_IDR_IDE_MASK 0x00080000 /* Identifier extension */
+#define XCAN_IDR_ID2_MASK 0x0007FFFE /* Extended message ident */
+#define XCAN_IDR_RTR_MASK 0x00000001 /* Remote TX request */
+#define XCAN_DLCR_DLC_MASK 0xF0000000 /* Data length code */
+
+#define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\
+ XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \
+ XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \
+ XCAN_IXR_ARBLST_MASK | XCAN_IXR_RXOK_MASK)
+
+/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
+#define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */
+#define XCAN_BTR_TS2_SHIFT 4 /* Time segment 2 */
+#define XCAN_IDR_ID1_SHIFT 21 /* Standard Messg Identifier */
+#define XCAN_IDR_ID2_SHIFT 1 /* Extended Message Identifier */
+#define XCAN_DLCR_DLC_SHIFT 28 /* Data length code */
+#define XCAN_ESR_REC_SHIFT 8 /* Rx Error Count */
+
+/* CAN frame length constants */
+#define XCAN_FRAME_MAX_DATA_LEN 8
+#define XCAN_TIMEOUT (1 * HZ)
+
+/**
+ * struct xcan_priv - This definition define CAN driver instance
+ * @can: CAN private data structure.
+ * @tx_head: Tx CAN packets ready to send on the queue
+ * @tx_tail: Tx CAN packets successfully sended on the queue
+ * @tx_max: Maximum number packets the driver can send
+ * @napi: NAPI structure
+ * @read_reg: For reading data from CAN registers
+ * @write_reg: For writing data to CAN registers
+ * @dev: Network device data structure
+ * @reg_base: Ioremapped address to registers
+ * @irq_flags: For request_irq()
+ * @bus_clk: Pointer to struct clk
+ * @can_clk: Pointer to struct clk
+ */
+struct xcan_priv {
+ struct can_priv can;
+ unsigned int tx_head;
+ unsigned int tx_tail;
+ unsigned int tx_max;
+ struct napi_struct napi;
+ u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg);
+ void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg,
+ u32 val);
+ struct net_device *dev;
+ void __iomem *reg_base;
+ unsigned long irq_flags;
+ struct clk *bus_clk;
+ struct clk *can_clk;
+};
+
+/* CAN Bittiming constants as per Xilinx CAN specs */
+static const struct can_bittiming_const xcan_bittiming_const = {
+ .name = DRIVER_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 1,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 256,
+ .brp_inc = 1,
+};
+
+/**
+ * xcan_write_reg_le - Write a value to the device register little endian
+ * @priv: Driver private data structure
+ * @reg: Register offset
+ * @val: Value to write at the Register offset
+ *
+ * Write data to the paricular CAN register
+ */
+static void xcan_write_reg_le(const struct xcan_priv *priv, enum xcan_reg reg,
+ u32 val)
+{
+ iowrite32(val, priv->reg_base + reg);
+}
+
+/**
+ * xcan_read_reg_le - Read a value from the device register little endian
+ * @priv: Driver private data structure
+ * @reg: Register offset
+ *
+ * Read data from the particular CAN register
+ * Return: value read from the CAN register
+ */
+static u32 xcan_read_reg_le(const struct xcan_priv *priv, enum xcan_reg reg)
+{
+ return ioread32(priv->reg_base + reg);
+}
+
+/**
+ * xcan_write_reg_be - Write a value to the device register big endian
+ * @priv: Driver private data structure
+ * @reg: Register offset
+ * @val: Value to write at the Register offset
+ *
+ * Write data to the paricular CAN register
+ */
+static void xcan_write_reg_be(const struct xcan_priv *priv, enum xcan_reg reg,
+ u32 val)
+{
+ iowrite32be(val, priv->reg_base + reg);
+}
+
+/**
+ * xcan_read_reg_be - Read a value from the device register big endian
+ * @priv: Driver private data structure
+ * @reg: Register offset
+ *
+ * Read data from the particular CAN register
+ * Return: value read from the CAN register
+ */
+static u32 xcan_read_reg_be(const struct xcan_priv *priv, enum xcan_reg reg)
+{
+ return ioread32be(priv->reg_base + reg);
+}
+
+/**
+ * set_reset_mode - Resets the CAN device mode
+ * @ndev: Pointer to net_device structure
+ *
+ * This is the driver reset mode routine.The driver
+ * enters into configuration mode.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int set_reset_mode(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ unsigned long timeout;
+
+ priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
+
+ timeout = jiffies + XCAN_TIMEOUT;
+ while (!(priv->read_reg(priv, XCAN_SR_OFFSET) & XCAN_SR_CONFIG_MASK)) {
+ if (time_after(jiffies, timeout)) {
+ netdev_warn(ndev, "timed out for config mode\n");
+ return -ETIMEDOUT;
+ }
+ usleep_range(500, 10000);
+ }
+
+ return 0;
+}
+
+/**
+ * xcan_set_bittiming - CAN set bit timing routine
+ * @ndev: Pointer to net_device structure
+ *
+ * This is the driver set bittiming routine.
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_set_bittiming(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u32 btr0, btr1;
+ u32 is_config_mode;
+
+ /* Check whether Xilinx CAN is in configuration mode.
+ * It cannot set bit timing if Xilinx CAN is not in configuration mode.
+ */
+ is_config_mode = priv->read_reg(priv, XCAN_SR_OFFSET) &
+ XCAN_SR_CONFIG_MASK;
+ if (!is_config_mode) {
+ netdev_alert(ndev,
+ "BUG! Cannot set bittiming - CAN is not in config mode\n");
+ return -EPERM;
+ }
+
+ /* Setting Baud Rate prescalar value in BRPR Register */
+ btr0 = (bt->brp - 1);
+
+ /* Setting Time Segment 1 in BTR Register */
+ btr1 = (bt->prop_seg + bt->phase_seg1 - 1);
+
+ /* Setting Time Segment 2 in BTR Register */
+ btr1 |= (bt->phase_seg2 - 1) << XCAN_BTR_TS2_SHIFT;
+
+ /* Setting Synchronous jump width in BTR Register */
+ btr1 |= (bt->sjw - 1) << XCAN_BTR_SJW_SHIFT;
+
+ priv->write_reg(priv, XCAN_BRPR_OFFSET, btr0);
+ priv->write_reg(priv, XCAN_BTR_OFFSET, btr1);
+
+ netdev_dbg(ndev, "BRPR=0x%08x, BTR=0x%08x\n",
+ priv->read_reg(priv, XCAN_BRPR_OFFSET),
+ priv->read_reg(priv, XCAN_BTR_OFFSET));
+
+ return 0;
+}
+
+/**
+ * xcan_chip_start - This the drivers start routine
+ * @ndev: Pointer to net_device structure
+ *
+ * This is the drivers start routine.
+ * Based on the State of the CAN device it puts
+ * the CAN device into a proper mode.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_chip_start(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ u32 err, reg_msr, reg_sr_mask;
+ unsigned long timeout;
+
+ /* Check if it is in reset mode */
+ err = set_reset_mode(ndev);
+ if (err < 0)
+ return err;
+
+ err = xcan_set_bittiming(ndev);
+ if (err < 0)
+ return err;
+
+ /* Enable interrupts */
+ priv->write_reg(priv, XCAN_IER_OFFSET, XCAN_INTR_ALL);
+
+ /* Check whether it is loopback mode or normal mode */
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+ reg_msr = XCAN_MSR_LBACK_MASK;
+ reg_sr_mask = XCAN_SR_LBACK_MASK;
+ } else {
+ reg_msr = 0x0;
+ reg_sr_mask = XCAN_SR_NORMAL_MASK;
+ }
+
+ priv->write_reg(priv, XCAN_MSR_OFFSET, reg_msr);
+ priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
+
+ timeout = jiffies + XCAN_TIMEOUT;
+ while (!(priv->read_reg(priv, XCAN_SR_OFFSET) & reg_sr_mask)) {
+ if (time_after(jiffies, timeout)) {
+ netdev_warn(ndev,
+ "timed out for correct mode\n");
+ return -ETIMEDOUT;
+ }
+ }
+ netdev_dbg(ndev, "status:#x%08x\n",
+ priv->read_reg(priv, XCAN_SR_OFFSET));
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ return 0;
+}
+
+/**
+ * xcan_do_set_mode - This sets the mode of the driver
+ * @ndev: Pointer to net_device structure
+ * @mode: Tells the mode of the driver
+ *
+ * This check the drivers state and calls the
+ * the corresponding modes to set.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ int ret;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ ret = xcan_chip_start(ndev);
+ if (ret < 0) {
+ netdev_err(ndev, "xcan_chip_start failed!\n");
+ return ret;
+ }
+ netif_wake_queue(ndev);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * xcan_start_xmit - Starts the transmission
+ * @skb: sk_buff pointer that contains data to be Txed
+ * @ndev: Pointer to net_device structure
+ *
+ * This function is invoked from upper layers to initiate transmission. This
+ * function uses the next available free txbuff and populates their fields to
+ * start the transmission.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 id, dlc, data[2] = {0, 0};
+
+ if (can_dropped_invalid_skb(ndev, skb))
+ return NETDEV_TX_OK;
+
+ /* Check if the TX buffer is full */
+ if (unlikely(priv->read_reg(priv, XCAN_SR_OFFSET) &
+ XCAN_SR_TXFLL_MASK)) {
+ netif_stop_queue(ndev);
+ netdev_err(ndev, "BUG!, TX FIFO full when queue awake!\n");
+ return NETDEV_TX_BUSY;
+ }
+
+ /* Watch carefully on the bit sequence */
+ if (cf->can_id & CAN_EFF_FLAG) {
+ /* Extended CAN ID format */
+ id = ((cf->can_id & CAN_EFF_MASK) << XCAN_IDR_ID2_SHIFT) &
+ XCAN_IDR_ID2_MASK;
+ id |= (((cf->can_id & CAN_EFF_MASK) >>
+ (CAN_EFF_ID_BITS-CAN_SFF_ID_BITS)) <<
+ XCAN_IDR_ID1_SHIFT) & XCAN_IDR_ID1_MASK;
+
+ /* The substibute remote TX request bit should be "1"
+ * for extended frames as in the Xilinx CAN datasheet
+ */
+ id |= XCAN_IDR_IDE_MASK | XCAN_IDR_SRR_MASK;
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ /* Extended frames remote TX request */
+ id |= XCAN_IDR_RTR_MASK;
+ } else {
+ /* Standard CAN ID format */
+ id = ((cf->can_id & CAN_SFF_MASK) << XCAN_IDR_ID1_SHIFT) &
+ XCAN_IDR_ID1_MASK;
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ /* Standard frames remote TX request */
+ id |= XCAN_IDR_SRR_MASK;
+ }
+
+ dlc = cf->can_dlc << XCAN_DLCR_DLC_SHIFT;
+
+ if (cf->can_dlc > 0)
+ data[0] = be32_to_cpup((__be32 *)(cf->data + 0));
+ if (cf->can_dlc > 4)
+ data[1] = be32_to_cpup((__be32 *)(cf->data + 4));
+
+ can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
+ priv->tx_head++;
+
+ /* Write the Frame to Xilinx CAN TX FIFO */
+ priv->write_reg(priv, XCAN_TXFIFO_ID_OFFSET, id);
+ /* If the CAN frame is RTR frame this write triggers tranmission */
+ priv->write_reg(priv, XCAN_TXFIFO_DLC_OFFSET, dlc);
+ if (!(cf->can_id & CAN_RTR_FLAG)) {
+ priv->write_reg(priv, XCAN_TXFIFO_DW1_OFFSET, data[0]);
+ /* If the CAN frame is Standard/Extended frame this
+ * write triggers tranmission
+ */
+ priv->write_reg(priv, XCAN_TXFIFO_DW2_OFFSET, data[1]);
+ stats->tx_bytes += cf->can_dlc;
+ }
+
+ /* Check if the TX buffer is full */
+ if ((priv->tx_head - priv->tx_tail) == priv->tx_max)
+ netif_stop_queue(ndev);
+
+ return NETDEV_TX_OK;
+}
+
+/**
+ * xcan_rx - Is called from CAN isr to complete the received
+ * frame processing
+ * @ndev: Pointer to net_device structure
+ *
+ * This function is invoked from the CAN isr(poll) to process the Rx frames. It
+ * does minimal processing and invokes "netif_receive_skb" to complete further
+ * processing.
+ * Return: 1 on success and 0 on failure.
+ */
+static int xcan_rx(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 id_xcan, dlc, data[2] = {0, 0};
+
+ skb = alloc_can_skb(ndev, &cf);
+ if (unlikely(!skb)) {
+ stats->rx_dropped++;
+ return 0;
+ }
+
+ /* Read a frame from Xilinx zynq CANPS */
+ id_xcan = priv->read_reg(priv, XCAN_RXFIFO_ID_OFFSET);
+ dlc = priv->read_reg(priv, XCAN_RXFIFO_DLC_OFFSET) >>
+ XCAN_DLCR_DLC_SHIFT;
+
+ /* Change Xilinx CAN data length format to socketCAN data format */
+ cf->can_dlc = get_can_dlc(dlc);
+
+ /* Change Xilinx CAN ID format to socketCAN ID format */
+ if (id_xcan & XCAN_IDR_IDE_MASK) {
+ /* The received frame is an Extended format frame */
+ cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >> 3;
+ cf->can_id |= (id_xcan & XCAN_IDR_ID2_MASK) >>
+ XCAN_IDR_ID2_SHIFT;
+ cf->can_id |= CAN_EFF_FLAG;
+ if (id_xcan & XCAN_IDR_RTR_MASK)
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ /* The received frame is a standard format frame */
+ cf->can_id = (id_xcan & XCAN_IDR_ID1_MASK) >>
+ XCAN_IDR_ID1_SHIFT;
+ if (id_xcan & XCAN_IDR_SRR_MASK)
+ cf->can_id |= CAN_RTR_FLAG;
+ }
+
+ if (!(id_xcan & XCAN_IDR_SRR_MASK)) {
+ data[0] = priv->read_reg(priv, XCAN_RXFIFO_DW1_OFFSET);
+ data[1] = priv->read_reg(priv, XCAN_RXFIFO_DW2_OFFSET);
+
+ /* Change Xilinx CAN data format to socketCAN data format */
+ if (cf->can_dlc > 0)
+ *(__be32 *)(cf->data) = cpu_to_be32(data[0]);
+ if (cf->can_dlc > 4)
+ *(__be32 *)(cf->data + 4) = cpu_to_be32(data[1]);
+ }
+
+ stats->rx_bytes += cf->can_dlc;
+ stats->rx_packets++;
+ netif_receive_skb(skb);
+
+ return 1;
+}
+
+/**
+ * xcan_err_interrupt - error frame Isr
+ * @ndev: net_device pointer
+ * @isr: interrupt status register value
+ *
+ * This is the CAN error interrupt and it will
+ * check the the type of error and forward the error
+ * frame to upper layers.
+ */
+static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 err_status, status, txerr = 0, rxerr = 0;
+
+ skb = alloc_can_err_skb(ndev, &cf);
+
+ err_status = priv->read_reg(priv, XCAN_ESR_OFFSET);
+ priv->write_reg(priv, XCAN_ESR_OFFSET, err_status);
+ txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
+ rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
+ XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
+ status = priv->read_reg(priv, XCAN_SR_OFFSET);
+
+ if (isr & XCAN_IXR_BSOFF_MASK) {
+ priv->can.state = CAN_STATE_BUS_OFF;
+ priv->can.can_stats.bus_off++;
+ /* Leave device in Config Mode in bus-off state */
+ priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
+ can_bus_off(ndev);
+ if (skb)
+ cf->can_id |= CAN_ERR_BUSOFF;
+ } else if ((status & XCAN_SR_ESTAT_MASK) == XCAN_SR_ESTAT_MASK) {
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ priv->can.can_stats.error_passive++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = (rxerr > 127) ?
+ CAN_ERR_CRTL_RX_PASSIVE :
+ CAN_ERR_CRTL_TX_PASSIVE;
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+ } else if (status & XCAN_SR_ERRWRN_MASK) {
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ priv->can.can_stats.error_warning++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] |= (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+ }
+
+ /* Check for Arbitration lost interrupt */
+ if (isr & XCAN_IXR_ARBLST_MASK) {
+ priv->can.can_stats.arbitration_lost++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_LOSTARB;
+ cf->data[0] = CAN_ERR_LOSTARB_UNSPEC;
+ }
+ }
+
+ /* Check for RX FIFO Overflow interrupt */
+ if (isr & XCAN_IXR_RXOFLW_MASK) {
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
+ if (skb) {
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+ }
+ }
+
+ /* Check for error interrupt */
+ if (isr & XCAN_IXR_ERROR_MASK) {
+ if (skb) {
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+ }
+
+ /* Check for Ack error interrupt */
+ if (err_status & XCAN_ESR_ACKER_MASK) {
+ stats->tx_errors++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_ACK;
+ cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+ }
+ }
+
+ /* Check for Bit error interrupt */
+ if (err_status & XCAN_ESR_BERR_MASK) {
+ stats->tx_errors++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_BIT;
+ }
+ }
+
+ /* Check for Stuff error interrupt */
+ if (err_status & XCAN_ESR_STER_MASK) {
+ stats->rx_errors++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_STUFF;
+ }
+ }
+
+ /* Check for Form error interrupt */
+ if (err_status & XCAN_ESR_FMER_MASK) {
+ stats->rx_errors++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_FORM;
+ }
+ }
+
+ /* Check for CRC error interrupt */
+ if (err_status & XCAN_ESR_CRCER_MASK) {
+ stats->rx_errors++;
+ if (skb) {
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL;
+ }
+ }
+ priv->can.can_stats.bus_error++;
+ }
+
+ if (skb) {
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+ netif_rx(skb);
+ }
+
+ netdev_dbg(ndev, "%s: error status register:0x%x\n",
+ __func__, priv->read_reg(priv, XCAN_ESR_OFFSET));
+}
+
+/**
+ * xcan_state_interrupt - It will check the state of the CAN device
+ * @ndev: net_device pointer
+ * @isr: interrupt status register value
+ *
+ * This will checks the state of the CAN device
+ * and puts the device into appropriate state.
+ */
+static void xcan_state_interrupt(struct net_device *ndev, u32 isr)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+
+ /* Check for Sleep interrupt if set put CAN device in sleep state */
+ if (isr & XCAN_IXR_SLP_MASK)
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ /* Check for Wake up interrupt if set put CAN device in Active state */
+ if (isr & XCAN_IXR_WKUP_MASK)
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+}
+
+/**
+ * xcan_rx_poll - Poll routine for rx packets (NAPI)
+ * @napi: napi structure pointer
+ * @quota: Max number of rx packets to be processed.
+ *
+ * This is the poll routine for rx part.
+ * It will process the packets maximux quota value.
+ *
+ * Return: number of packets received
+ */
+static int xcan_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *ndev = napi->dev;
+ struct xcan_priv *priv = netdev_priv(ndev);
+ u32 isr, ier;
+ int work_done = 0;
+
+ isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
+ while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) {
+ if (isr & XCAN_IXR_RXOK_MASK) {
+ priv->write_reg(priv, XCAN_ICR_OFFSET,
+ XCAN_IXR_RXOK_MASK);
+ work_done += xcan_rx(ndev);
+ } else {
+ priv->write_reg(priv, XCAN_ICR_OFFSET,
+ XCAN_IXR_RXNEMP_MASK);
+ break;
+ }
+ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK);
+ isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
+ }
+
+ if (work_done)
+ can_led_event(ndev, CAN_LED_EVENT_RX);
+
+ if (work_done < quota) {
+ napi_complete(napi);
+ ier = priv->read_reg(priv, XCAN_IER_OFFSET);
+ ier |= (XCAN_IXR_RXOK_MASK | XCAN_IXR_RXNEMP_MASK);
+ priv->write_reg(priv, XCAN_IER_OFFSET, ier);
+ }
+ return work_done;
+}
+
+/**
+ * xcan_tx_interrupt - Tx Done Isr
+ * @ndev: net_device pointer
+ * @isr: Interrupt status register value
+ */
+static void xcan_tx_interrupt(struct net_device *ndev, u32 isr)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+
+ while ((priv->tx_head - priv->tx_tail > 0) &&
+ (isr & XCAN_IXR_TXOK_MASK)) {
+ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXOK_MASK);
+ can_get_echo_skb(ndev, priv->tx_tail %
+ priv->tx_max);
+ priv->tx_tail++;
+ stats->tx_packets++;
+ isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
+ }
+ can_led_event(ndev, CAN_LED_EVENT_TX);
+ netif_wake_queue(ndev);
+}
+
+/**
+ * xcan_interrupt - CAN Isr
+ * @irq: irq number
+ * @dev_id: device id poniter
+ *
+ * This is the xilinx CAN Isr. It checks for the type of interrupt
+ * and invokes the corresponding ISR.
+ *
+ * Return:
+ * IRQ_NONE - If CAN device is in sleep mode, IRQ_HANDLED otherwise
+ */
+static irqreturn_t xcan_interrupt(int irq, void *dev_id)
+{
+ struct net_device *ndev = (struct net_device *)dev_id;
+ struct xcan_priv *priv = netdev_priv(ndev);
+ u32 isr, ier;
+
+ /* Get the interrupt status from Xilinx CAN */
+ isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
+ if (!isr)
+ return IRQ_NONE;
+
+ /* Check for the type of interrupt and Processing it */
+ if (isr & (XCAN_IXR_SLP_MASK | XCAN_IXR_WKUP_MASK)) {
+ priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_SLP_MASK |
+ XCAN_IXR_WKUP_MASK));
+ xcan_state_interrupt(ndev, isr);
+ }
+
+ /* Check for Tx interrupt and Processing it */
+ if (isr & XCAN_IXR_TXOK_MASK)
+ xcan_tx_interrupt(ndev, isr);
+
+ /* Check for the type of error interrupt and Processing it */
+ if (isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK |
+ XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK)) {
+ priv->write_reg(priv, XCAN_ICR_OFFSET, (XCAN_IXR_ERROR_MASK |
+ XCAN_IXR_RXOFLW_MASK | XCAN_IXR_BSOFF_MASK |
+ XCAN_IXR_ARBLST_MASK));
+ xcan_err_interrupt(ndev, isr);
+ }
+
+ /* Check for the type of receive interrupt and Processing it */
+ if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) {
+ ier = priv->read_reg(priv, XCAN_IER_OFFSET);
+ ier &= ~(XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK);
+ priv->write_reg(priv, XCAN_IER_OFFSET, ier);
+ napi_schedule(&priv->napi);
+ }
+ return IRQ_HANDLED;
+}
+
+/**
+ * xcan_chip_stop - Driver stop routine
+ * @ndev: Pointer to net_device structure
+ *
+ * This is the drivers stop routine. It will disable the
+ * interrupts and put the device into configuration mode.
+ */
+static void xcan_chip_stop(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ u32 ier;
+
+ /* Disable interrupts and leave the can in configuration mode */
+ ier = priv->read_reg(priv, XCAN_IER_OFFSET);
+ ier &= ~XCAN_INTR_ALL;
+ priv->write_reg(priv, XCAN_IER_OFFSET, ier);
+ priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
+ priv->can.state = CAN_STATE_STOPPED;
+}
+
+/**
+ * xcan_open - Driver open routine
+ * @ndev: Pointer to net_device structure
+ *
+ * This is the driver open routine.
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_open(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ int ret;
+
+ ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags,
+ ndev->name, ndev);
+ if (ret < 0) {
+ netdev_err(ndev, "irq allocation for CAN failed\n");
+ goto err;
+ }
+
+ ret = clk_prepare_enable(priv->can_clk);
+ if (ret) {
+ netdev_err(ndev, "unable to enable device clock\n");
+ goto err_irq;
+ }
+
+ ret = clk_prepare_enable(priv->bus_clk);
+ if (ret) {
+ netdev_err(ndev, "unable to enable bus clock\n");
+ goto err_can_clk;
+ }
+
+ /* Set chip into reset mode */
+ ret = set_reset_mode(ndev);
+ if (ret < 0) {
+ netdev_err(ndev, "mode resetting failed!\n");
+ goto err_bus_clk;
+ }
+
+ /* Common open */
+ ret = open_candev(ndev);
+ if (ret)
+ goto err_bus_clk;
+
+ ret = xcan_chip_start(ndev);
+ if (ret < 0) {
+ netdev_err(ndev, "xcan_chip_start failed!\n");
+ goto err_candev;
+ }
+
+ can_led_event(ndev, CAN_LED_EVENT_OPEN);
+ napi_enable(&priv->napi);
+ netif_start_queue(ndev);
+
+ return 0;
+
+err_candev:
+ close_candev(ndev);
+err_bus_clk:
+ clk_disable_unprepare(priv->bus_clk);
+err_can_clk:
+ clk_disable_unprepare(priv->can_clk);
+err_irq:
+ free_irq(ndev->irq, ndev);
+err:
+ return ret;
+}
+
+/**
+ * xcan_close - Driver close routine
+ * @ndev: Pointer to net_device structure
+ *
+ * Return: 0 always
+ */
+static int xcan_close(struct net_device *ndev)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+ xcan_chip_stop(ndev);
+ clk_disable_unprepare(priv->bus_clk);
+ clk_disable_unprepare(priv->can_clk);
+ free_irq(ndev->irq, ndev);
+ close_candev(ndev);
+
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
+
+ return 0;
+}
+
+/**
+ * xcan_get_berr_counter - error counter routine
+ * @ndev: Pointer to net_device structure
+ * @bec: Pointer to can_berr_counter structure
+ *
+ * This is the driver error counter routine.
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_get_berr_counter(const struct net_device *ndev,
+ struct can_berr_counter *bec)
+{
+ struct xcan_priv *priv = netdev_priv(ndev);
+ int ret;
+
+ ret = clk_prepare_enable(priv->can_clk);
+ if (ret)
+ goto err;
+
+ ret = clk_prepare_enable(priv->bus_clk);
+ if (ret)
+ goto err_clk;
+
+ bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
+ bec->rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
+ XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
+
+ clk_disable_unprepare(priv->bus_clk);
+ clk_disable_unprepare(priv->can_clk);
+
+ return 0;
+
+err_clk:
+ clk_disable_unprepare(priv->can_clk);
+err:
+ return ret;
+}
+
+
+static const struct net_device_ops xcan_netdev_ops = {
+ .ndo_open = xcan_open,
+ .ndo_stop = xcan_close,
+ .ndo_start_xmit = xcan_start_xmit,
+};
+
+/**
+ * xcan_suspend - Suspend method for the driver
+ * @dev: Address of the platform_device structure
+ *
+ * Put the driver into low power mode.
+ * Return: 0 always
+ */
+static int __maybe_unused xcan_suspend(struct device *dev)
+{
+ struct platform_device *pdev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct xcan_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ netif_stop_queue(ndev);
+ netif_device_detach(ndev);
+ }
+
+ priv->write_reg(priv, XCAN_MSR_OFFSET, XCAN_MSR_SLEEP_MASK);
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ clk_disable(priv->bus_clk);
+ clk_disable(priv->can_clk);
+
+ return 0;
+}
+
+/**
+ * xcan_resume - Resume from suspend
+ * @dev: Address of the platformdevice structure
+ *
+ * Resume operation after suspend.
+ * Return: 0 on success and failure value on error
+ */
+static int __maybe_unused xcan_resume(struct device *dev)
+{
+ struct platform_device *pdev = dev_get_drvdata(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct xcan_priv *priv = netdev_priv(ndev);
+ int ret;
+
+ ret = clk_enable(priv->bus_clk);
+ if (ret) {
+ dev_err(dev, "Cannot enable clock.\n");
+ return ret;
+ }
+ ret = clk_enable(priv->can_clk);
+ if (ret) {
+ dev_err(dev, "Cannot enable clock.\n");
+ clk_disable_unprepare(priv->bus_clk);
+ return ret;
+ }
+
+ priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
+ priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_running(ndev)) {
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
+
+/**
+ * xcan_probe - Platform registration call
+ * @pdev: Handle to the platform device structure
+ *
+ * This function does all the memory allocation and registration for the CAN
+ * device.
+ *
+ * Return: 0 on success and failure value on error
+ */
+static int xcan_probe(struct platform_device *pdev)
+{
+ struct resource *res; /* IO mem resources */
+ struct net_device *ndev;
+ struct xcan_priv *priv;
+ void __iomem *addr;
+ int ret, rx_max, tx_max;
+
+ /* Get the virtual base address for the device */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ addr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(addr)) {
+ ret = PTR_ERR(addr);
+ goto err;
+ }
+
+ ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", &tx_max);
+ if (ret < 0)
+ goto err;
+
+ ret = of_property_read_u32(pdev->dev.of_node, "rx-fifo-depth", &rx_max);
+ if (ret < 0)
+ goto err;
+
+ /* Create a CAN device instance */
+ ndev = alloc_candev(sizeof(struct xcan_priv), tx_max);
+ if (!ndev)
+ return -ENOMEM;
+
+ priv = netdev_priv(ndev);
+ priv->dev = ndev;
+ priv->can.bittiming_const = &xcan_bittiming_const;
+ priv->can.do_set_mode = xcan_do_set_mode;
+ priv->can.do_get_berr_counter = xcan_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+ CAN_CTRLMODE_BERR_REPORTING;
+ priv->reg_base = addr;
+ priv->tx_max = tx_max;
+
+ /* Get IRQ for the device */
+ ndev->irq = platform_get_irq(pdev, 0);
+ ndev->flags |= IFF_ECHO; /* We support local echo */
+
+ platform_set_drvdata(pdev, ndev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ ndev->netdev_ops = &xcan_netdev_ops;
+
+ /* Getting the CAN can_clk info */
+ priv->can_clk = devm_clk_get(&pdev->dev, "can_clk");
+ if (IS_ERR(priv->can_clk)) {
+ dev_err(&pdev->dev, "Device clock not found.\n");
+ ret = PTR_ERR(priv->can_clk);
+ goto err_free;
+ }
+ /* Check for type of CAN device */
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "xlnx,zynq-can-1.0")) {
+ priv->bus_clk = devm_clk_get(&pdev->dev, "pclk");
+ if (IS_ERR(priv->bus_clk)) {
+ dev_err(&pdev->dev, "bus clock not found\n");
+ ret = PTR_ERR(priv->bus_clk);
+ goto err_free;
+ }
+ } else {
+ priv->bus_clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
+ if (IS_ERR(priv->bus_clk)) {
+ dev_err(&pdev->dev, "bus clock not found\n");
+ ret = PTR_ERR(priv->bus_clk);
+ goto err_free;
+ }
+ }
+
+ ret = clk_prepare_enable(priv->can_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to enable device clock\n");
+ goto err_free;
+ }
+
+ ret = clk_prepare_enable(priv->bus_clk);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to enable bus clock\n");
+ goto err_unprepare_disable_dev;
+ }
+
+ priv->write_reg = xcan_write_reg_le;
+ priv->read_reg = xcan_read_reg_le;
+
+ if (priv->read_reg(priv, XCAN_SR_OFFSET) != XCAN_SR_CONFIG_MASK) {
+ priv->write_reg = xcan_write_reg_be;
+ priv->read_reg = xcan_read_reg_be;
+ }
+
+ priv->can.clock.freq = clk_get_rate(priv->can_clk);
+
+ netif_napi_add(ndev, &priv->napi, xcan_rx_poll, rx_max);
+
+ ret = register_candev(ndev);
+ if (ret) {
+ dev_err(&pdev->dev, "fail to register failed (err=%d)\n", ret);
+ goto err_unprepare_disable_busclk;
+ }
+
+ devm_can_led_init(ndev);
+ clk_disable_unprepare(priv->bus_clk);
+ clk_disable_unprepare(priv->can_clk);
+ netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
+ priv->reg_base, ndev->irq, priv->can.clock.freq,
+ priv->tx_max);
+
+ return 0;
+
+err_unprepare_disable_busclk:
+ clk_disable_unprepare(priv->bus_clk);
+err_unprepare_disable_dev:
+ clk_disable_unprepare(priv->can_clk);
+err_free:
+ free_candev(ndev);
+err:
+ return ret;
+}
+
+/**
+ * xcan_remove - Unregister the device after releasing the resources
+ * @pdev: Handle to the platform device structure
+ *
+ * This function frees all the resources allocated to the device.
+ * Return: 0 always
+ */
+static int xcan_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct xcan_priv *priv = netdev_priv(ndev);
+
+ if (set_reset_mode(ndev) < 0)
+ netdev_err(ndev, "mode resetting failed!\n");
+
+ unregister_candev(ndev);
+ netif_napi_del(&priv->napi);
+ free_candev(ndev);
+
+ return 0;
+}
+
+/* Match table for OF platform binding */
+static struct of_device_id xcan_of_match[] = {
+ { .compatible = "xlnx,zynq-can-1.0", },
+ { .compatible = "xlnx,axi-can-1.00.a", },
+ { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, xcan_of_match);
+
+static struct platform_driver xcan_driver = {
+ .probe = xcan_probe,
+ .remove = xcan_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .pm = &xcan_dev_pm_ops,
+ .of_match_table = xcan_of_match,
+ },
+};
+
+module_platform_driver(xcan_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Xilinx Inc");
+MODULE_DESCRIPTION("Xilinx CAN interface");
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 65d0a910329..29e272cc7a9 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -18,7 +18,6 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
@@ -32,14 +31,13 @@
#include <linux/skbuff.h>
#include <linux/ethtool.h>
-#include <asm/arch/svinto.h>/* DMA and register descriptions */
+#include <arch/svinto.h>/* DMA and register descriptions */
#include <asm/io.h> /* CRIS_LED_* I/O functions */
#include <asm/irq.h>
#include <asm/dma.h>
-#include <asm/system.h>
#include <asm/ethernet.h>
#include <asm/cache.h>
-#include <asm/arch/io_interface_mux.h>
+#include <arch/io_interface_mux.h>
//#define ETHDEBUG
#define D(x)
@@ -60,7 +58,6 @@ static struct sockaddr default_mac = {
/* Information that need to be kept for each board. */
struct net_local {
- struct net_device_stats stats;
struct mii_if_info mii_if;
/* Tx control lock. This protects the transmit buffer ring
@@ -257,6 +254,23 @@ struct transceiver_ops transceivers[] =
struct transceiver_ops* transceiver = &transceivers[0];
+static const struct net_device_ops e100_netdev_ops = {
+ .ndo_open = e100_open,
+ .ndo_stop = e100_close,
+ .ndo_start_xmit = e100_send_packet,
+ .ndo_tx_timeout = e100_tx_timeout,
+ .ndo_get_stats = e100_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_do_ioctl = e100_ioctl,
+ .ndo_set_mac_address = e100_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_config = e100_set_config,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = e100_netpoll,
+#endif
+};
+
#define tx_done(dev) (*R_DMA_CH0_CMD == 0)
/*
@@ -300,19 +314,8 @@ etrax_ethernet_init(void)
/* fill in our handlers so the network layer can talk to us in the future */
- dev->open = e100_open;
- dev->hard_start_xmit = e100_send_packet;
- dev->stop = e100_close;
- dev->get_stats = e100_get_stats;
- dev->set_multicast_list = set_multicast_list;
- dev->set_mac_address = e100_set_mac_address;
dev->ethtool_ops = &e100_ethtool_ops;
- dev->do_ioctl = e100_ioctl;
- dev->set_config = e100_set_config;
- dev->tx_timeout = e100_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = e100_netpoll;
-#endif
+ dev->netdev_ops = &e100_netdev_ops;
spin_lock_init(&np->lock);
spin_lock_init(&np->led_lock);
@@ -419,7 +422,6 @@ e100_set_mac_address(struct net_device *dev, void *p)
{
struct net_local *np = netdev_priv(dev);
struct sockaddr *addr = p;
- DECLARE_MAC_BUF(mac);
spin_lock(&np->lock); /* preemption protection */
@@ -440,8 +442,7 @@ e100_set_mac_address(struct net_device *dev, void *p)
/* show it in the log as well */
- printk(KERN_INFO "%s: changed MAC to %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
+ printk(KERN_INFO "%s: changed MAC to %pM\n", dev->name, dev->dev_addr);
spin_unlock(&np->lock);
@@ -489,8 +490,8 @@ e100_open(struct net_device *dev)
/* allocate the irq corresponding to the receiving DMA */
- if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt,
- IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) {
+ if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, 0, cardname,
+ (void *)dev)) {
goto grace_exit0;
}
@@ -764,10 +765,24 @@ e100_negotiate(struct net_device* dev)
e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE, data);
- /* Renegotiate with link partner */
+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR);
if (autoneg_normal) {
- data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR);
- data |= BMCR_ANENABLE | BMCR_ANRESTART;
+ /* Renegotiate with link partner */
+ data |= BMCR_ANENABLE | BMCR_ANRESTART;
+ } else {
+ /* Don't negotiate speed or duplex */
+ data &= ~(BMCR_ANENABLE | BMCR_ANRESTART);
+
+ /* Set speed and duplex static */
+ if (current_speed_selection == 10)
+ data &= ~BMCR_SPEED100;
+ else
+ data |= BMCR_SPEED100;
+
+ if (current_duplex != full)
+ data &= ~BMCR_FULLDPLX;
+ else
+ data |= BMCR_FULLDPLX;
}
e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR, data);
}
@@ -993,7 +1008,7 @@ e100_send_mdio_bit(unsigned char bit)
}
static unsigned char
-e100_receive_mdio_bit()
+e100_receive_mdio_bit(void)
{
unsigned char bit;
*R_NETWORK_MGM_CTRL = 0;
@@ -1042,7 +1057,7 @@ e100_tx_timeout(struct net_device *dev)
/* remember we got an error */
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* reset the TX DMA in case it has hung on something */
@@ -1091,7 +1106,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
myNextTxDesc->skb = skb;
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
e100_hardware_send_packet(np, buf, skb->len);
@@ -1104,7 +1119,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&np->lock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -1116,7 +1131,6 @@ static irqreturn_t
e100rxtx_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
- struct net_local *np = netdev_priv(dev);
unsigned long irqbits;
/*
@@ -1140,7 +1154,7 @@ e100rxtx_interrupt(int irq, void *dev_id)
* allocate a new buffer to put a packet in.
*/
e100_rx(dev);
- np->stats.rx_packets++;
+ dev->stats.rx_packets++;
/* restart/continue on the channel, for safety */
*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart);
/* clear dma channel 1 eop/descr irq bits */
@@ -1156,8 +1170,8 @@ e100rxtx_interrupt(int irq, void *dev_id)
/* Report any packets that have been sent */
while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST &&
(netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) {
- np->stats.tx_bytes += myFirstTxDesc->skb->len;
- np->stats.tx_packets++;
+ dev->stats.tx_bytes += myFirstTxDesc->skb->len;
+ dev->stats.tx_packets++;
/* dma is ready with the transmission of the data in tx_skb, so now
we can release the skb memory */
@@ -1180,7 +1194,6 @@ static irqreturn_t
e100nw_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
- struct net_local *np = netdev_priv(dev);
unsigned long irqbits = *R_IRQ_MASK0_RD;
/* check for underrun irq */
@@ -1188,13 +1201,13 @@ e100nw_interrupt(int irq, void *dev_id)
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
D(printk("ethernet receiver underrun!\n"));
}
/* check for overrun irq */
if (irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) {
- update_rx_stats(&np->stats); /* this will ack the irq */
+ update_rx_stats(&dev->stats); /* this will ack the irq */
D(printk("ethernet receiver overrun!\n"));
}
/* check for excessive collision irq */
@@ -1202,7 +1215,7 @@ e100nw_interrupt(int irq, void *dev_id)
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
D(printk("ethernet excessive collisions!\n"));
}
return IRQ_HANDLED;
@@ -1233,7 +1246,7 @@ e100_rx(struct net_device *dev)
spin_unlock(&np->led_lock);
length = myNextRxDesc->descr.hw_len - 4;
- np->stats.rx_bytes += length;
+ dev->stats.rx_bytes += length;
#ifdef ETHDEBUG
printk("Got a packet of length %d:\n", length);
@@ -1251,7 +1264,7 @@ e100_rx(struct net_device *dev)
/* Small packet, copy data */
skb = dev_alloc_skb(length - ETHER_HEAD_LEN);
if (!skb) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
goto update_nextrxdesc;
}
@@ -1277,7 +1290,7 @@ e100_rx(struct net_device *dev)
int align;
struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
if (!new_skb) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
goto update_nextrxdesc;
}
@@ -1316,8 +1329,6 @@ e100_rx(struct net_device *dev)
static int
e100_close(struct net_device *dev)
{
- struct net_local *np = netdev_priv(dev);
-
printk(KERN_INFO "Closing %s.\n", dev->name);
netif_stop_queue(dev);
@@ -1349,8 +1360,8 @@ e100_close(struct net_device *dev)
/* Update the statistics here. */
- update_rx_stats(&np->stats);
- update_tx_stats(&np->stats);
+ update_rx_stats(&dev->stats);
+ update_tx_stats(&dev->stats);
/* Stop speed/duplex timers */
del_timer(&speed_timer);
@@ -1370,7 +1381,7 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
spin_lock(&np->lock); /* Preempt protection */
switch (cmd) {
/* The ioctls below should be considered obsolete but are */
- /* still present for compatability with old scripts/apps */
+ /* still present for compatibility with old scripts/apps */
case SET_ETH_SPEED_10: /* 10 Mbps */
e100_set_speed(dev, 10);
break;
@@ -1437,10 +1448,10 @@ static int e100_set_settings(struct net_device *dev,
static void e100_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
- strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
- strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
- strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
+ strlcpy(info->driver, "ETRAX 100LX", sizeof(info->driver));
+ strlcpy(info->version, "$Revision: 1.31 $", sizeof(info->version));
+ strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
+ strlcpy(info->bus_info, "N/A", sizeof(info->bus_info));
}
static int e100_nway_reset(struct net_device *dev)
@@ -1528,11 +1539,11 @@ e100_get_stats(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- update_rx_stats(&lp->stats);
- update_tx_stats(&lp->stats);
+ update_rx_stats(&dev->stats);
+ update_tx_stats(&dev->stats);
spin_unlock_irqrestore(&lp->lock, flags);
- return &lp->stats;
+ return &dev->stats;
}
/*
@@ -1546,7 +1557,7 @@ static void
set_multicast_list(struct net_device *dev)
{
struct net_local *lp = netdev_priv(dev);
- int num_addr = dev->mc_count;
+ int num_addr = netdev_mc_count(dev);
unsigned long int lo_bits;
unsigned long int hi_bits;
@@ -1578,17 +1589,16 @@ set_multicast_list(struct net_device *dev)
} else {
/* MC mode, receive normal and MC packets */
char hash_ix;
- struct dev_mc_list *dmi = dev->mc_list;
- int i;
+ struct netdev_hw_addr *ha;
char *baddr;
lo_bits = 0x00000000ul;
hi_bits = 0x00000000ul;
- for (i = 0; i < num_addr; i++) {
+ netdev_for_each_mc_addr(ha, dev) {
/* Calculate the hash index for the GA registers */
hash_ix = 0;
- baddr = dmi->dmi_addr;
+ baddr = ha->addr;
hash_ix ^= (*baddr) & 0x3f;
hash_ix ^= ((*baddr) >> 6) & 0x03;
++baddr;
@@ -1614,7 +1624,6 @@ set_multicast_list(struct net_device *dev)
} else {
lo_bits |= (1 << hash_ix);
}
- dmi = dmi->next;
}
/* Disable individual receive */
SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, individual, discard);
@@ -1687,11 +1696,7 @@ e100_set_network_leds(int active)
if (!current_speed) {
/* Make LED red, link is down */
-#if defined(CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION)
- CRIS_LED_NETWORK_SET(CRIS_LED_RED);
-#else
CRIS_LED_NETWORK_SET(CRIS_LED_OFF);
-#endif
} else if (light_leds) {
if (current_speed == 10) {
CRIS_LED_NETWORK_SET(CRIS_LED_ORANGE);
@@ -1707,7 +1712,7 @@ e100_set_network_leds(int active)
static void
e100_netpoll(struct net_device* netdev)
{
- e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL);
+ e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev);
}
#endif
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
deleted file mode 100644
index ea6144a9565..00000000000
--- a/drivers/net/cs89x0.c
+++ /dev/null
@@ -1,1991 +0,0 @@
-/* cs89x0.c: A Crystal Semiconductor (Now Cirrus Logic) CS89[02]0
- * driver for linux.
- */
-
-/*
- Written 1996 by Russell Nelson, with reference to skeleton.c
- written 1993-1994 by Donald Becker.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached at nelson@crynwr.com, Crynwr
- Software, 521 Pleasant Valley Rd., Potsdam, NY 13676
-
- Changelog:
-
- Mike Cruse : mcruse@cti-ltd.com
- : Changes for Linux 2.0 compatibility.
- : Added dev_id parameter in net_interrupt(),
- : request_irq() and free_irq(). Just NULL for now.
-
- Mike Cruse : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros
- : in net_open() and net_close() so kerneld would know
- : that the module is in use and wouldn't eject the
- : driver prematurely.
-
- Mike Cruse : Rewrote init_module() and cleanup_module using 8390.c
- : as an example. Disabled autoprobing in init_module(),
- : not a good thing to do to other devices while Linux
- : is running from all accounts.
-
- Russ Nelson : Jul 13 1998. Added RxOnly DMA support.
-
- Melody Lee : Aug 10 1999. Changes for Linux 2.2.5 compatibility.
- : email: ethernet@crystal.cirrus.com
-
- Alan Cox : Removed 1.2 support, added 2.1 extra counters.
-
- Andrew Morton : andrewm@uow.edu.au
- : Kernel 2.3.48
- : Handle kmalloc() failures
- : Other resource allocation fixes
- : Add SMP locks
- : Integrate Russ Nelson's ALLOW_DMA functionality back in.
- : If ALLOW_DMA is true, make DMA runtime selectable
- : Folded in changes from Cirrus (Melody Lee
- : <klee@crystal.cirrus.com>)
- : Don't call netif_wake_queue() in net_send_packet()
- : Fixed an out-of-mem bug in dma_rx()
- : Updated Documentation/networking/cs89x0.txt
-
- Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre1
- : Use skb_reserve to longword align IP header (two places)
- : Remove a delay loop from dma_rx()
- : Replace '100' with HZ
- : Clean up a couple of skb API abuses
- : Added 'cs89x0_dma=N' kernel boot option
- : Correctly initialise lp->lock in non-module compile
-
- Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre4-1
- : MOD_INC/DEC race fix (see
- : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html)
-
- Andrew Morton : andrewm@uow.edu.au / Kernel 2.4.0-test7-pre2
- : Enhanced EEPROM support to cover more devices,
- : abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch
- : (Jason Gunthorpe <jgg@ualberta.ca>)
-
- Andrew Morton : Kernel 2.4.0-test11-pre4
- : Use dev->name in request_*() (Andrey Panin)
- : Fix an error-path memleak in init_module()
- : Preserve return value from request_irq()
- : Fix type of `media' module parm (Keith Owens)
- : Use SET_MODULE_OWNER()
- : Tidied up strange request_irq() abuse in net_open().
-
- Andrew Morton : Kernel 2.4.3-pre1
- : Request correct number of pages for DMA (Hugh Dickens)
- : Select PP_ChipID _after_ unregister_netdev in cleanup_module()
- : because unregister_netdev() calls get_stats.
- : Make `version[]' __initdata
- : Uninlined the read/write reg/word functions.
-
- Oskar Schirmer : oskar@scara.com
- : HiCO.SH4 (superh) support added (irq#1, cs89x0_media=)
-
- Deepak Saxena : dsaxena@plexity.net
- : Intel IXDP2x01 (XScale ixp2x00 NPU) platform support
-
- Dmitry Pervushin : dpervushin@ru.mvista.com
- : PNX010X platform support
-
- Deepak Saxena : dsaxena@plexity.net
- : Intel IXDP2351 platform support
-
- Dmitry Pervushin : dpervushin@ru.mvista.com
- : PNX010X platform support
-
-*/
-
-/* Always include 'config.h' first in case the user wants to turn on
- or override something. */
-#include <linux/module.h>
-
-/*
- * Set this to zero to disable DMA code
- *
- * Note that even if DMA is turned off we still support the 'dma' and 'use_dma'
- * module options so we don't break any startup scripts.
- */
-#ifndef CONFIG_ISA_DMA_API
-#define ALLOW_DMA 0
-#else
-#define ALLOW_DMA 1
-#endif
-
-/*
- * Set this to zero to remove all the debug statements via
- * dead code elimination
- */
-#define DEBUGGING 1
-
-/*
- Sources:
-
- Crynwr packet driver epktisa.
-
- Crystal Semiconductor data sheets.
-
-*/
-
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <linux/delay.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#if ALLOW_DMA
-#include <asm/dma.h>
-#endif
-
-#include "cs89x0.h"
-
-static char version[] __initdata =
-"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
-
-#define DRV_NAME "cs89x0"
-
-/* First, a few definitions that the brave might change.
- A zero-terminated list of I/O addresses to be probed. Some special flags..
- Addr & 1 = Read back the address port, look for signature and reset
- the page window before probing
- Addr & 3 = Reset the page window and probe
- The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,
- but it is possible that a Cirrus board could be plugged into the ISA
- slots. */
-/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
- them to system IRQ numbers. This mapping is card specific and is set to
- the configuration of the Cirrus Eval board for this chip. */
-#ifdef CONFIG_ARCH_CLPS7500
-static unsigned int netcard_portlist[] __used __initdata =
- { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
-static unsigned int cs8900_irq_map[] = {12,0,0,0};
-#elif defined(CONFIG_SH_HICOSH4)
-static unsigned int netcard_portlist[] __used __initdata =
- { 0x0300, 0};
-static unsigned int cs8900_irq_map[] = {1,0,0,0};
-#elif defined(CONFIG_MACH_IXDP2351)
-static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
-static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
-#include <asm/irq.h>
-#elif defined(CONFIG_ARCH_IXDP2X01)
-#include <asm/irq.h>
-static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
-static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
-#elif defined(CONFIG_ARCH_PNX010X)
-#include <asm/irq.h>
-#include <mach/gpio.h>
-#define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */
-#define CIRRUS_DEFAULT_IRQ VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
-static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
-static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
-#else
-static unsigned int netcard_portlist[] __used __initdata =
- { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
-static unsigned int cs8900_irq_map[] = {10,11,12,5};
-#endif
-
-#if DEBUGGING
-static unsigned int net_debug = DEBUGGING;
-#else
-#define net_debug 0 /* gcc will remove all the debug code for us */
-#endif
-
-/* The number of low I/O ports used by the ethercard. */
-#define NETCARD_IO_EXTENT 16
-
-/* we allow the user to override various values normally set in the EEPROM */
-#define FORCE_RJ45 0x0001 /* pick one of these three */
-#define FORCE_AUI 0x0002
-#define FORCE_BNC 0x0004
-
-#define FORCE_AUTO 0x0010 /* pick one of these three */
-#define FORCE_HALF 0x0020
-#define FORCE_FULL 0x0030
-
-/* Information that need to be kept for each board. */
-struct net_local {
- struct net_device_stats stats;
- int chip_type; /* one of: CS8900, CS8920, CS8920M */
- char chip_revision; /* revision letter of the chip ('A'...) */
- int send_cmd; /* the proper send command: TX_NOW, TX_AFTER_381, or TX_AFTER_ALL */
- int auto_neg_cnf; /* auto-negotiation word from EEPROM */
- int adapter_cnf; /* adapter configuration from EEPROM */
- int isa_config; /* ISA configuration from EEPROM */
- int irq_map; /* IRQ map from EEPROM */
- int rx_mode; /* what mode are we in? 0, RX_MULTCAST_ACCEPT, or RX_ALL_ACCEPT */
- int curr_rx_cfg; /* a copy of PP_RxCFG */
- int linectl; /* either 0 or LOW_RX_SQUELCH, depending on configuration. */
- int send_underrun; /* keep track of how many underruns in a row we get */
- int force; /* force various values; see FORCE* above. */
- spinlock_t lock;
-#if ALLOW_DMA
- int use_dma; /* Flag: we're using dma */
- int dma; /* DMA channel */
- int dmasize; /* 16 or 64 */
- unsigned char *dma_buff; /* points to the beginning of the buffer */
- unsigned char *end_dma_buff; /* points to the end of the buffer */
- unsigned char *rx_dma_ptr; /* points to the next packet */
-#endif
-};
-
-/* Index to functions, as function prototypes. */
-
-static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
-static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id);
-static void set_multicast_list(struct net_device *dev);
-static void net_timeout(struct net_device *dev);
-static void net_rx(struct net_device *dev);
-static int net_close(struct net_device *dev);
-static struct net_device_stats *net_get_stats(struct net_device *dev);
-static void reset_chip(struct net_device *dev);
-static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer);
-static int get_eeprom_cksum(int off, int len, int *buffer);
-static int set_mac_address(struct net_device *dev, void *addr);
-static void count_rx_errors(int status, struct net_local *lp);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void net_poll_controller(struct net_device *dev);
-#endif
-#if ALLOW_DMA
-static void get_dma_channel(struct net_device *dev);
-static void release_dma_buff(struct net_local *lp);
-#endif
-
-/* Example routines you must write ;->. */
-#define tx_done(dev) 1
-
-/*
- * Permit 'cs89x0_dma=N' in the kernel boot environment
- */
-#if !defined(MODULE) && (ALLOW_DMA != 0)
-static int g_cs89x0_dma;
-
-static int __init dma_fn(char *str)
-{
- g_cs89x0_dma = simple_strtol(str,NULL,0);
- return 1;
-}
-
-__setup("cs89x0_dma=", dma_fn);
-#endif /* !defined(MODULE) && (ALLOW_DMA != 0) */
-
-#ifndef MODULE
-static int g_cs89x0_media__force;
-
-static int __init media_fn(char *str)
-{
- if (!strcmp(str, "rj45")) g_cs89x0_media__force = FORCE_RJ45;
- else if (!strcmp(str, "aui")) g_cs89x0_media__force = FORCE_AUI;
- else if (!strcmp(str, "bnc")) g_cs89x0_media__force = FORCE_BNC;
- return 1;
-}
-
-__setup("cs89x0_media=", media_fn);
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- Return 0 on success.
- */
-
-struct net_device * __init cs89x0_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- unsigned *port;
- int err = 0;
- int irq;
- int io;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
-
- if (net_debug)
- printk("cs89x0:cs89x0_probe(0x%x)\n", io);
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = cs89x0_probe1(dev, io, 0);
- } else if (io != 0) { /* Don't probe at all. */
- err = -ENXIO;
- } else {
- for (port = netcard_portlist; *port; port++) {
- if (cs89x0_probe1(dev, *port, 0) == 0)
- break;
- dev->irq = irq;
- }
- if (!*port)
- err = -ENODEV;
- }
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
- return ERR_PTR(err);
-}
-#endif
-
-#if defined(CONFIG_MACH_IXDP2351)
-static u16
-readword(unsigned long base_addr, int portno)
-{
- return __raw_readw(base_addr + (portno << 1));
-}
-
-static void
-writeword(unsigned long base_addr, int portno, u16 value)
-{
- __raw_writew(value, base_addr + (portno << 1));
-}
-#elif defined(CONFIG_ARCH_IXDP2X01)
-static u16
-readword(unsigned long base_addr, int portno)
-{
- return __raw_readl(base_addr + (portno << 1));
-}
-
-static void
-writeword(unsigned long base_addr, int portno, u16 value)
-{
- __raw_writel(value, base_addr + (portno << 1));
-}
-#elif defined(CONFIG_ARCH_PNX010X)
-static u16
-readword(unsigned long base_addr, int portno)
-{
- return inw(base_addr + (portno << 1));
-}
-
-static void
-writeword(unsigned long base_addr, int portno, u16 value)
-{
- outw(value, base_addr + (portno << 1));
-}
-#else
-static u16
-readword(unsigned long base_addr, int portno)
-{
- return inw(base_addr + portno);
-}
-
-static void
-writeword(unsigned long base_addr, int portno, u16 value)
-{
- outw(value, base_addr + portno);
-}
-#endif
-
-static void
-readwords(unsigned long base_addr, int portno, void *buf, int length)
-{
- u8 *buf8 = (u8 *)buf;
-
- do {
- u16 tmp16;
-
- tmp16 = readword(base_addr, portno);
- *buf8++ = (u8)tmp16;
- *buf8++ = (u8)(tmp16 >> 8);
- } while (--length);
-}
-
-static void
-writewords(unsigned long base_addr, int portno, void *buf, int length)
-{
- u8 *buf8 = (u8 *)buf;
-
- do {
- u16 tmp16;
-
- tmp16 = *buf8++;
- tmp16 |= (*buf8++) << 8;
- writeword(base_addr, portno, tmp16);
- } while (--length);
-}
-
-static u16
-readreg(struct net_device *dev, u16 regno)
-{
- writeword(dev->base_addr, ADD_PORT, regno);
- return readword(dev->base_addr, DATA_PORT);
-}
-
-static void
-writereg(struct net_device *dev, u16 regno, u16 value)
-{
- writeword(dev->base_addr, ADD_PORT, regno);
- writeword(dev->base_addr, DATA_PORT, value);
-}
-
-static int __init
-wait_eeprom_ready(struct net_device *dev)
-{
- int timeout = jiffies;
- /* check to see if the EEPROM is ready, a timeout is used -
- just in case EEPROM is ready when SI_BUSY in the
- PP_SelfST is clear */
- while(readreg(dev, PP_SelfST) & SI_BUSY)
- if (jiffies - timeout >= 40)
- return -1;
- return 0;
-}
-
-static int __init
-get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
-{
- int i;
-
- if (net_debug > 3) printk("EEPROM data from %x for %x:\n",off,len);
- for (i = 0; i < len; i++) {
- if (wait_eeprom_ready(dev) < 0) return -1;
- /* Now send the EEPROM read command and EEPROM location to read */
- writereg(dev, PP_EECMD, (off + i) | EEPROM_READ_CMD);
- if (wait_eeprom_ready(dev) < 0) return -1;
- buffer[i] = readreg(dev, PP_EEData);
- if (net_debug > 3) printk("%04x ", buffer[i]);
- }
- if (net_debug > 3) printk("\n");
- return 0;
-}
-
-static int __init
-get_eeprom_cksum(int off, int len, int *buffer)
-{
- int i, cksum;
-
- cksum = 0;
- for (i = 0; i < len; i++)
- cksum += buffer[i];
- cksum &= 0xffff;
- if (cksum == 0)
- return 0;
- return -1;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling receive - used by netconsole and other diagnostic tools
- * to allow network i/o with interrupts disabled.
- */
-static void net_poll_controller(struct net_device *dev)
-{
- disable_irq(dev->irq);
- net_interrupt(dev->irq, dev);
- enable_irq(dev->irq);
-}
-#endif
-
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probes avoids doing writes, and
- verifies that the correct device exists and functions.
- Return 0 on success.
- */
-
-static int __init
-cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
-{
- struct net_local *lp = netdev_priv(dev);
- static unsigned version_printed;
- int i;
- int tmp;
- unsigned rev_type = 0;
- int eeprom_buff[CHKSUM_LEN];
- int retval;
- DECLARE_MAC_BUF(mac);
-
- /* Initialize the device structure. */
- if (!modular) {
- memset(lp, 0, sizeof(*lp));
- spin_lock_init(&lp->lock);
-#ifndef MODULE
-#if ALLOW_DMA
- if (g_cs89x0_dma) {
- lp->use_dma = 1;
- lp->dma = g_cs89x0_dma;
- lp->dmasize = 16; /* Could make this an option... */
- }
-#endif
- lp->force = g_cs89x0_media__force;
-#endif
- }
-
-#ifdef CONFIG_ARCH_PNX010X
- initialize_ebi();
-
- /* Map GPIO registers for the pins connected to the CS8900a. */
- if (map_cirrus_gpio() < 0)
- return -ENODEV;
-
- reset_cirrus();
-
- /* Map event-router registers. */
- if (map_event_router() < 0)
- return -ENODEV;
-
- enable_cirrus_irq();
-
- unmap_cirrus_gpio();
- unmap_event_router();
-
- dev->base_addr = ioaddr;
-
- for (i = 0 ; i < 3 ; i++)
- readreg(dev, 0);
-#endif
-
- /* Grab the region so we can find another board if autoIRQ fails. */
- /* WTF is going on here? */
- if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
- printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
- DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
- retval = -EBUSY;
- goto out1;
- }
-
-#ifdef CONFIG_SH_HICOSH4
- /* truely reset the chip */
- writeword(ioaddr, ADD_PORT, 0x0114);
- writeword(ioaddr, DATA_PORT, 0x0040);
-#endif
-
- /* if they give us an odd I/O address, then do ONE write to
- the address port, to get it back to address zero, where we
- expect to find the EISA signature word. An IO with a base of 0x3
- will skip the test for the ADD_PORT. */
- if (ioaddr & 1) {
- if (net_debug > 1)
- printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr);
- if ((ioaddr & 2) != 2)
- if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
- printk(KERN_ERR "%s: bad signature 0x%x\n",
- dev->name, readword(ioaddr & ~3, ADD_PORT));
- retval = -ENODEV;
- goto out2;
- }
- }
-
- ioaddr &= ~3;
- printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n",
- ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
- writeword(ioaddr, ADD_PORT, PP_ChipID);
-
- tmp = readword(ioaddr, DATA_PORT);
- if (tmp != CHIP_EISA_ID_SIG) {
- printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!="
- CHIP_EISA_ID_SIG_STR "\n",
- dev->name, ioaddr, DATA_PORT, tmp);
- retval = -ENODEV;
- goto out2;
- }
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = ioaddr;
-
- /* get the chip type */
- rev_type = readreg(dev, PRODUCT_ID_ADD);
- lp->chip_type = rev_type &~ REVISON_BITS;
- lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
-
- /* Check the chip type and revision in order to set the correct send command
- CS8920 revision C and CS8900 revision F can use the faster send. */
- lp->send_cmd = TX_AFTER_381;
- if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
- lp->send_cmd = TX_NOW;
- if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
- lp->send_cmd = TX_NOW;
-
- if (net_debug && version_printed++ == 0)
- printk(version);
-
- printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#3lx ",
- dev->name,
- lp->chip_type==CS8900?'0':'2',
- lp->chip_type==CS8920M?"M":"",
- lp->chip_revision,
- dev->base_addr);
-
- reset_chip(dev);
-
- /* Here we read the current configuration of the chip. If there
- is no Extended EEPROM then the idea is to not disturb the chip
- configuration, it should have been correctly setup by automatic
- EEPROM read on reset. So, if the chip says it read the EEPROM
- the driver will always do *something* instead of complain that
- adapter_cnf is 0. */
-
-#ifdef CONFIG_SH_HICOSH4
- if (1) {
- /* For the HiCO.SH4 board, things are different: we don't
- have EEPROM, but there is some data in flash, so we go
- get it there directly (MAC). */
- __u16 *confd;
- short cnt;
- if (((* (volatile __u32 *) 0xa0013ff0) & 0x00ffffff)
- == 0x006c3000) {
- confd = (__u16*) 0xa0013fc0;
- } else {
- confd = (__u16*) 0xa001ffc0;
- }
- cnt = (*confd++ & 0x00ff) >> 1;
- while (--cnt > 0) {
- __u16 j = *confd++;
-
- switch (j & 0x0fff) {
- case PP_IA:
- for (i = 0; i < ETH_ALEN/2; i++) {
- dev->dev_addr[i*2] = confd[i] & 0xFF;
- dev->dev_addr[i*2+1] = confd[i] >> 8;
- }
- break;
- }
- j = (j >> 12) + 1;
- confd += j;
- cnt -= j;
- }
- } else
-#endif
-
- if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
- (EEPROM_OK|EEPROM_PRESENT)) {
- /* Load the MAC. */
- for (i=0; i < ETH_ALEN/2; i++) {
- unsigned int Addr;
- Addr = readreg(dev, PP_IA+i*2);
- dev->dev_addr[i*2] = Addr & 0xFF;
- dev->dev_addr[i*2+1] = Addr >> 8;
- }
-
- /* Load the Adapter Configuration.
- Note: Barring any more specific information from some
- other source (ie EEPROM+Schematics), we would not know
- how to operate a 10Base2 interface on the AUI port.
- However, since we do read the status of HCB1 and use
- settings that always result in calls to control_dc_dc(dev,0)
- a BNC interface should work if the enable pin
- (dc/dc converter) is on HCB1. It will be called AUI
- however. */
-
- lp->adapter_cnf = 0;
- i = readreg(dev, PP_LineCTL);
- /* Preserve the setting of the HCB1 pin. */
- if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL))
- lp->adapter_cnf |= A_CNF_DC_DC_POLARITY;
- /* Save the sqelch bit */
- if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH)
- lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH;
- /* Check if the card is in 10Base-t only mode */
- if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0)
- lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T;
- /* Check if the card is in AUI only mode */
- if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY)
- lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI;
- /* Check if the card is in Auto mode. */
- if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET)
- lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T |
- A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO;
-
- if (net_debug > 1)
- printk(KERN_INFO "%s: PP_LineCTL=0x%x, adapter_cnf=0x%x\n",
- dev->name, i, lp->adapter_cnf);
-
- /* IRQ. Other chips already probe, see below. */
- if (lp->chip_type == CS8900)
- lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK;
-
- printk( "[Cirrus EEPROM] ");
- }
-
- printk("\n");
-
- /* First check to see if an EEPROM is attached. */
-#ifdef CONFIG_SH_HICOSH4 /* no EEPROM on HiCO, don't hazzle with it here */
- if (1) {
- printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n");
- } else
-#endif
- if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
- printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
- else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
- printk(KERN_WARNING "\ncs89x0: EEPROM read failed, relying on command line.\n");
- } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
- /* Check if the chip was able to read its own configuration starting
- at 0 in the EEPROM*/
- if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) !=
- (EEPROM_OK|EEPROM_PRESENT))
- printk(KERN_WARNING "cs89x0: Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n");
-
- } else {
- /* This reads an extended EEPROM that is not documented
- in the CS8900 datasheet. */
-
- /* get transmission control word but keep the autonegotiation bits */
- if (!lp->auto_neg_cnf) lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
- /* Store adapter configuration */
- if (!lp->adapter_cnf) lp->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
- /* Store ISA configuration */
- lp->isa_config = eeprom_buff[ISA_CNF_OFFSET/2];
- dev->mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
-
- /* eeprom_buff has 32-bit ints, so we can't just memcpy it */
- /* store the initial memory base address */
- for (i = 0; i < ETH_ALEN/2; i++) {
- dev->dev_addr[i*2] = eeprom_buff[i];
- dev->dev_addr[i*2+1] = eeprom_buff[i] >> 8;
- }
- if (net_debug > 1)
- printk(KERN_DEBUG "%s: new adapter_cnf: 0x%x\n",
- dev->name, lp->adapter_cnf);
- }
-
- /* allow them to force multiple transceivers. If they force multiple, autosense */
- {
- int count = 0;
- if (lp->force & FORCE_RJ45) {lp->adapter_cnf |= A_CNF_10B_T; count++; }
- if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_AUI; count++; }
- if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_10B_2; count++; }
- if (count > 1) {lp->adapter_cnf |= A_CNF_MEDIA_AUTO; }
- else if (lp->force & FORCE_RJ45){lp->adapter_cnf |= A_CNF_MEDIA_10B_T; }
- else if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_MEDIA_AUI; }
- else if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_MEDIA_10B_2; }
- }
-
- if (net_debug > 1)
- printk(KERN_DEBUG "%s: after force 0x%x, adapter_cnf=0x%x\n",
- dev->name, lp->force, lp->adapter_cnf);
-
- /* FIXME: We don't let you set dc-dc polarity or low RX squelch from the command line: add it here */
-
- /* FIXME: We don't let you set the IMM bit from the command line: add it to lp->auto_neg_cnf here */
-
- /* FIXME: we don't set the Ethernet address on the command line. Use
- ifconfig IFACE hw ether AABBCCDDEEFF */
-
- printk(KERN_INFO "cs89x0 media %s%s%s",
- (lp->adapter_cnf & A_CNF_10B_T)?"RJ-45,":"",
- (lp->adapter_cnf & A_CNF_AUI)?"AUI,":"",
- (lp->adapter_cnf & A_CNF_10B_2)?"BNC,":"");
-
- lp->irq_map = 0xffff;
-
- /* If this is a CS8900 then no pnp soft */
- if (lp->chip_type != CS8900 &&
- /* Check if the ISA IRQ has been set */
- (i = readreg(dev, PP_CS8920_ISAINT) & 0xff,
- (i != 0 && i < CS8920_NO_INTS))) {
- if (!dev->irq)
- dev->irq = i;
- } else {
- i = lp->isa_config & INT_NO_MASK;
- if (lp->chip_type == CS8900) {
-#if defined(CONFIG_MACH_IXDP2351) || defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X)
- i = cs8900_irq_map[0];
-#else
- /* Translate the IRQ using the IRQ mapping table. */
- if (i >= ARRAY_SIZE(cs8900_irq_map))
- printk("\ncs89x0: invalid ISA interrupt number %d\n", i);
- else
- i = cs8900_irq_map[i];
-
- lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */
- } else {
- int irq_map_buff[IRQ_MAP_LEN/2];
-
- if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA,
- IRQ_MAP_LEN/2,
- irq_map_buff) >= 0) {
- if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT)
- lp->irq_map = (irq_map_buff[0]>>8) | (irq_map_buff[1] << 8);
- }
-#endif
- }
- if (!dev->irq)
- dev->irq = i;
- }
-
- printk(" IRQ %d", dev->irq);
-
-#if ALLOW_DMA
- if (lp->use_dma) {
- get_dma_channel(dev);
- printk(", DMA %d", dev->dma);
- }
- else
-#endif
- {
- printk(", programmed I/O");
- }
-
- /* print the ethernet address. */
- printk(", MAC %s", print_mac(mac, dev->dev_addr));
-
- dev->open = net_open;
- dev->stop = net_close;
- dev->tx_timeout = net_timeout;
- dev->watchdog_timeo = HZ;
- dev->hard_start_xmit = net_send_packet;
- dev->get_stats = net_get_stats;
- dev->set_multicast_list = set_multicast_list;
- dev->set_mac_address = set_mac_address;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = net_poll_controller;
-#endif
-
- printk("\n");
- if (net_debug)
- printk("cs89x0_probe1() successful\n");
-
- retval = register_netdev(dev);
- if (retval)
- goto out3;
- return 0;
-out3:
- writeword(dev->base_addr, ADD_PORT, PP_ChipID);
-out2:
- release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
-out1:
- return retval;
-}
-
-
-/*********************************
- * This page contains DMA routines
-**********************************/
-
-#if ALLOW_DMA
-
-#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
-
-static void
-get_dma_channel(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-
- if (lp->dma) {
- dev->dma = lp->dma;
- lp->isa_config |= ISA_RxDMA;
- } else {
- if ((lp->isa_config & ANY_ISA_DMA) == 0)
- return;
- dev->dma = lp->isa_config & DMA_NO_MASK;
- if (lp->chip_type == CS8900)
- dev->dma += 5;
- if (dev->dma < 5 || dev->dma > 7) {
- lp->isa_config &= ~ANY_ISA_DMA;
- return;
- }
- }
- return;
-}
-
-static void
-write_dma(struct net_device *dev, int chip_type, int dma)
-{
- struct net_local *lp = netdev_priv(dev);
- if ((lp->isa_config & ANY_ISA_DMA) == 0)
- return;
- if (chip_type == CS8900) {
- writereg(dev, PP_CS8900_ISADMA, dma-5);
- } else {
- writereg(dev, PP_CS8920_ISADMA, dma);
- }
-}
-
-static void
-set_dma_cfg(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-
- if (lp->use_dma) {
- if ((lp->isa_config & ANY_ISA_DMA) == 0) {
- if (net_debug > 3)
- printk("set_dma_cfg(): no DMA\n");
- return;
- }
- if (lp->isa_config & ISA_RxDMA) {
- lp->curr_rx_cfg |= RX_DMA_ONLY;
- if (net_debug > 3)
- printk("set_dma_cfg(): RX_DMA_ONLY\n");
- } else {
- lp->curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */
- if (net_debug > 3)
- printk("set_dma_cfg(): AUTO_RX_DMA\n");
- }
- }
-}
-
-static int
-dma_bufcfg(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- if (lp->use_dma)
- return (lp->isa_config & ANY_ISA_DMA)? RX_DMA_ENBL : 0;
- else
- return 0;
-}
-
-static int
-dma_busctl(struct net_device *dev)
-{
- int retval = 0;
- struct net_local *lp = netdev_priv(dev);
- if (lp->use_dma) {
- if (lp->isa_config & ANY_ISA_DMA)
- retval |= RESET_RX_DMA; /* Reset the DMA pointer */
- if (lp->isa_config & DMA_BURST)
- retval |= DMA_BURST_MODE; /* Does ISA config specify DMA burst ? */
- if (lp->dmasize == 64)
- retval |= RX_DMA_SIZE_64K; /* did they ask for 64K? */
- retval |= MEMORY_ON; /* we need memory enabled to use DMA. */
- }
- return retval;
-}
-
-static void
-dma_rx(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- struct sk_buff *skb;
- int status, length;
- unsigned char *bp = lp->rx_dma_ptr;
-
- status = bp[0] + (bp[1]<<8);
- length = bp[2] + (bp[3]<<8);
- bp += 4;
- if (net_debug > 5) {
- printk( "%s: receiving DMA packet at %lx, status %x, length %x\n",
- dev->name, (unsigned long)bp, status, length);
- }
- if ((status & RX_OK) == 0) {
- count_rx_errors(status, lp);
- goto skip_this_frame;
- }
-
- /* Malloc up new buffer. */
- skb = dev_alloc_skb(length + 2);
- if (skb == NULL) {
- if (net_debug) /* I don't think we want to do this to a stressed system */
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
-
- /* AKPM: advance bp to the next frame */
-skip_this_frame:
- bp += (length + 3) & ~3;
- if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024;
- lp->rx_dma_ptr = bp;
- return;
- }
- skb_reserve(skb, 2); /* longword align L3 header */
-
- if (bp + length > lp->end_dma_buff) {
- int semi_cnt = lp->end_dma_buff - bp;
- memcpy(skb_put(skb,semi_cnt), bp, semi_cnt);
- memcpy(skb_put(skb,length - semi_cnt), lp->dma_buff,
- length - semi_cnt);
- } else {
- memcpy(skb_put(skb,length), bp, length);
- }
- bp += (length + 3) & ~3;
- if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024;
- lp->rx_dma_ptr = bp;
-
- if (net_debug > 3) {
- printk( "%s: received %d byte DMA packet of type %x\n",
- dev->name, length,
- (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
- }
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += length;
-}
-
-#endif /* ALLOW_DMA */
-
-void __init reset_chip(struct net_device *dev)
-{
-#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01)
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-#endif
- int reset_start_time;
-
- writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
-
- /* wait 30 ms */
- msleep(30);
-
-#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01)
- if (lp->chip_type != CS8900) {
- /* Hardware problem requires PNP registers to be reconfigured after a reset */
- writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT);
- outb(dev->irq, ioaddr + DATA_PORT);
- outb(0, ioaddr + DATA_PORT + 1);
-
- writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB);
- outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT);
- outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1);
- }
-#endif /* IXDP2x01 */
-
- /* Wait until the chip is reset */
- reset_start_time = jiffies;
- while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
- ;
-}
-
-
-static void
-control_dc_dc(struct net_device *dev, int on_not_off)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned int selfcontrol;
- int timenow = jiffies;
- /* control the DC to DC convertor in the SelfControl register.
- Note: This is hooked up to a general purpose pin, might not
- always be a DC to DC convertor. */
-
- selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
- if (((lp->adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
- selfcontrol |= HCB1;
- else
- selfcontrol &= ~HCB1;
- writereg(dev, PP_SelfCTL, selfcontrol);
-
- /* Wait for the DC/DC converter to power up - 500ms */
- while (jiffies - timenow < HZ)
- ;
-}
-
-#define DETECTED_NONE 0
-#define DETECTED_RJ45H 1
-#define DETECTED_RJ45F 2
-#define DETECTED_AUI 3
-#define DETECTED_BNC 4
-
-static int
-detect_tp(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int timenow = jiffies;
- int fdx;
-
- if (net_debug > 1) printk("%s: Attempting TP\n", dev->name);
-
- /* If connected to another full duplex capable 10-Base-T card the link pulses
- seem to be lost when the auto detect bit in the LineCTL is set.
- To overcome this the auto detect bit will be cleared whilst testing the
- 10-Base-T interface. This would not be necessary for the sparrow chip but
- is simpler to do it anyway. */
- writereg(dev, PP_LineCTL, lp->linectl &~ AUI_ONLY);
- control_dc_dc(dev, 0);
-
- /* Delay for the hardware to work out if the TP cable is present - 150ms */
- for (timenow = jiffies; jiffies - timenow < 15; )
- ;
- if ((readreg(dev, PP_LineST) & LINK_OK) == 0)
- return DETECTED_NONE;
-
- if (lp->chip_type == CS8900) {
- switch (lp->force & 0xf0) {
-#if 0
- case FORCE_AUTO:
- printk("%s: cs8900 doesn't autonegotiate\n",dev->name);
- return DETECTED_NONE;
-#endif
- /* CS8900 doesn't support AUTO, change to HALF*/
- case FORCE_AUTO:
- lp->force &= ~FORCE_AUTO;
- lp->force |= FORCE_HALF;
- break;
- case FORCE_HALF:
- break;
- case FORCE_FULL:
- writereg(dev, PP_TestCTL, readreg(dev, PP_TestCTL) | FDX_8900);
- break;
- }
- fdx = readreg(dev, PP_TestCTL) & FDX_8900;
- } else {
- switch (lp->force & 0xf0) {
- case FORCE_AUTO:
- lp->auto_neg_cnf = AUTO_NEG_ENABLE;
- break;
- case FORCE_HALF:
- lp->auto_neg_cnf = 0;
- break;
- case FORCE_FULL:
- lp->auto_neg_cnf = RE_NEG_NOW | ALLOW_FDX;
- break;
- }
-
- writereg(dev, PP_AutoNegCTL, lp->auto_neg_cnf & AUTO_NEG_MASK);
-
- if ((lp->auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
- printk(KERN_INFO "%s: negotiating duplex...\n",dev->name);
- while (readreg(dev, PP_AutoNegST) & AUTO_NEG_BUSY) {
- if (jiffies - timenow > 4000) {
- printk(KERN_ERR "**** Full / half duplex auto-negotiation timed out ****\n");
- break;
- }
- }
- }
- fdx = readreg(dev, PP_AutoNegST) & FDX_ACTIVE;
- }
- if (fdx)
- return DETECTED_RJ45F;
- else
- return DETECTED_RJ45H;
-}
-
-/* send a test packet - return true if carrier bits are ok */
-static int
-send_test_pkt(struct net_device *dev)
-{
- char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
- 0, 46, /* A 46 in network order */
- 0, 0, /* DSAP=0 & SSAP=0 fields */
- 0xf3, 0 /* Control (Test Req + P bit set) */ };
- long timenow = jiffies;
-
- writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);
-
- memcpy(test_packet, dev->dev_addr, ETH_ALEN);
- memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN);
-
- writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL);
- writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN);
-
- /* Test to see if the chip has allocated memory for the packet */
- while (jiffies - timenow < 5)
- if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW)
- break;
- if (jiffies - timenow >= 5)
- return 0; /* this shouldn't happen */
-
- /* Write the contents of the packet */
- writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1);
-
- if (net_debug > 1) printk("Sending test packet ");
- /* wait a couple of jiffies for packet to be received */
- for (timenow = jiffies; jiffies - timenow < 3; )
- ;
- if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
- if (net_debug > 1) printk("succeeded\n");
- return 1;
- }
- if (net_debug > 1) printk("failed\n");
- return 0;
-}
-
-
-static int
-detect_aui(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-
- if (net_debug > 1) printk("%s: Attempting AUI\n", dev->name);
- control_dc_dc(dev, 0);
-
- writereg(dev, PP_LineCTL, (lp->linectl &~ AUTO_AUI_10BASET) | AUI_ONLY);
-
- if (send_test_pkt(dev))
- return DETECTED_AUI;
- else
- return DETECTED_NONE;
-}
-
-static int
-detect_bnc(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-
- if (net_debug > 1) printk("%s: Attempting BNC\n", dev->name);
- control_dc_dc(dev, 1);
-
- writereg(dev, PP_LineCTL, (lp->linectl &~ AUTO_AUI_10BASET) | AUI_ONLY);
-
- if (send_test_pkt(dev))
- return DETECTED_BNC;
- else
- return DETECTED_NONE;
-}
-
-
-static void
-write_irq(struct net_device *dev, int chip_type, int irq)
-{
- int i;
-
- if (chip_type == CS8900) {
- /* Search the mapping table for the corresponding IRQ pin. */
- for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
- if (cs8900_irq_map[i] == irq)
- break;
- /* Not found */
- if (i == ARRAY_SIZE(cs8900_irq_map))
- i = 3;
- writereg(dev, PP_CS8900_ISAINT, i);
- } else {
- writereg(dev, PP_CS8920_ISAINT, irq);
- }
-}
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine should set everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
- */
-
-/* AKPM: do we need to do any locking here? */
-
-static int
-net_open(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- int result = 0;
- int i;
- int ret;
-
-#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
- if (dev->irq < 2) {
- /* Allow interrupts to be generated by the chip */
-/* Cirrus' release had this: */
-#if 0
- writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
-#endif
-/* And 2.3.47 had this: */
- writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
-
- for (i = 2; i < CS8920_NO_INTS; i++) {
- if ((1 << i) & lp->irq_map) {
- if (request_irq(i, net_interrupt, 0, dev->name, dev) == 0) {
- dev->irq = i;
- write_irq(dev, lp->chip_type, i);
- /* writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); */
- break;
- }
- }
- }
-
- if (i >= CS8920_NO_INTS) {
- writereg(dev, PP_BusCTL, 0); /* disable interrupts. */
- printk(KERN_ERR "cs89x0: can't get an interrupt\n");
- ret = -EAGAIN;
- goto bad_out;
- }
- }
- else
-#endif
- {
-#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
- if (((1 << dev->irq) & lp->irq_map) == 0) {
- printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
- dev->name, dev->irq, lp->irq_map);
- ret = -EAGAIN;
- goto bad_out;
- }
-#endif
-/* FIXME: Cirrus' release had this: */
- writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
-/* And 2.3.47 had this: */
-#if 0
- writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
-#endif
- write_irq(dev, lp->chip_type, dev->irq);
- ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
- if (ret) {
- if (net_debug)
- printk(KERN_DEBUG "cs89x0: request_irq(%d) failed\n", dev->irq);
- goto bad_out;
- }
- }
-
-#if ALLOW_DMA
- if (lp->use_dma) {
- if (lp->isa_config & ANY_ISA_DMA) {
- unsigned long flags;
- lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,
- get_order(lp->dmasize * 1024));
-
- if (!lp->dma_buff) {
- printk(KERN_ERR "%s: cannot get %dK memory for DMA\n", dev->name, lp->dmasize);
- goto release_irq;
- }
- if (net_debug > 1) {
- printk( "%s: dma %lx %lx\n",
- dev->name,
- (unsigned long)lp->dma_buff,
- (unsigned long)isa_virt_to_bus(lp->dma_buff));
- }
- if ((unsigned long) lp->dma_buff >= MAX_DMA_ADDRESS ||
- !dma_page_eq(lp->dma_buff, lp->dma_buff+lp->dmasize*1024-1)) {
- printk(KERN_ERR "%s: not usable as DMA buffer\n", dev->name);
- goto release_irq;
- }
- memset(lp->dma_buff, 0, lp->dmasize * 1024); /* Why? */
- if (request_dma(dev->dma, dev->name)) {
- printk(KERN_ERR "%s: cannot get dma channel %d\n", dev->name, dev->dma);
- goto release_irq;
- }
- write_dma(dev, lp->chip_type, dev->dma);
- lp->rx_dma_ptr = lp->dma_buff;
- lp->end_dma_buff = lp->dma_buff + lp->dmasize*1024;
- spin_lock_irqsave(&lp->lock, flags);
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, 0x14); /* auto_init as well */
- set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
- set_dma_count(dev->dma, lp->dmasize*1024);
- enable_dma(dev->dma);
- spin_unlock_irqrestore(&lp->lock, flags);
- }
- }
-#endif /* ALLOW_DMA */
-
- /* set the Ethernet address */
- for (i=0; i < ETH_ALEN/2; i++)
- writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
-
- /* while we're testing the interface, leave interrupts disabled */
- writereg(dev, PP_BusCTL, MEMORY_ON);
-
- /* Set the LineCTL quintuplet based on adapter configuration read from EEPROM */
- if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) && (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH))
- lp->linectl = LOW_RX_SQUELCH;
- else
- lp->linectl = 0;
-
- /* check to make sure that they have the "right" hardware available */
- switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
- case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break;
- case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break;
- case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
- default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
- }
-#ifdef CONFIG_ARCH_PNX010X
- result = A_CNF_10B_T;
-#endif
- if (!result) {
- printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name);
-release_dma:
-#if ALLOW_DMA
- free_dma(dev->dma);
-#endif
-release_irq:
-#if ALLOW_DMA
- release_dma_buff(lp);
-#endif
- writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
- free_irq(dev->irq, dev);
- ret = -EAGAIN;
- goto bad_out;
- }
-
- /* set the hardware to the configured choice */
- switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
- case A_CNF_MEDIA_10B_T:
- result = detect_tp(dev);
- if (result==DETECTED_NONE) {
- printk(KERN_WARNING "%s: 10Base-T (RJ-45) has no cable\n", dev->name);
- if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
- result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */
- }
- break;
- case A_CNF_MEDIA_AUI:
- result = detect_aui(dev);
- if (result==DETECTED_NONE) {
- printk(KERN_WARNING "%s: 10Base-5 (AUI) has no cable\n", dev->name);
- if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
- result = DETECTED_AUI; /* Yes! I don't care if I see a carrrier */
- }
- break;
- case A_CNF_MEDIA_10B_2:
- result = detect_bnc(dev);
- if (result==DETECTED_NONE) {
- printk(KERN_WARNING "%s: 10Base-2 (BNC) has no cable\n", dev->name);
- if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
- result = DETECTED_BNC; /* Yes! I don't care if I can xmit a packet */
- }
- break;
- case A_CNF_MEDIA_AUTO:
- writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET);
- if (lp->adapter_cnf & A_CNF_10B_T)
- if ((result = detect_tp(dev)) != DETECTED_NONE)
- break;
- if (lp->adapter_cnf & A_CNF_AUI)
- if ((result = detect_aui(dev)) != DETECTED_NONE)
- break;
- if (lp->adapter_cnf & A_CNF_10B_2)
- if ((result = detect_bnc(dev)) != DETECTED_NONE)
- break;
- printk(KERN_ERR "%s: no media detected\n", dev->name);
- goto release_dma;
- }
- switch(result) {
- case DETECTED_NONE:
- printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name);
- goto release_dma;
- case DETECTED_RJ45H:
- printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name);
- break;
- case DETECTED_RJ45F:
- printk(KERN_INFO "%s: using full-duplex 10Base-T (RJ-45)\n", dev->name);
- break;
- case DETECTED_AUI:
- printk(KERN_INFO "%s: using 10Base-5 (AUI)\n", dev->name);
- break;
- case DETECTED_BNC:
- printk(KERN_INFO "%s: using 10Base-2 (BNC)\n", dev->name);
- break;
- }
-
- /* Turn on both receive and transmit operations */
- writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
-
- /* Receive only error free packets addressed to this card */
- lp->rx_mode = 0;
- writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
-
- lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
-
- if (lp->isa_config & STREAM_TRANSFER)
- lp->curr_rx_cfg |= RX_STREAM_ENBL;
-#if ALLOW_DMA
- set_dma_cfg(dev);
-#endif
- writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
-
- writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
- TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
-
- writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
-#if ALLOW_DMA
- dma_bufcfg(dev) |
-#endif
- TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
-
- /* now that we've got our act together, enable everything */
- writereg(dev, PP_BusCTL, ENABLE_IRQ
- | (dev->mem_start?MEMORY_ON : 0) /* turn memory on */
-#if ALLOW_DMA
- | dma_busctl(dev)
-#endif
- );
- netif_start_queue(dev);
- if (net_debug > 1)
- printk("cs89x0: net_open() succeeded\n");
- return 0;
-bad_out:
- return ret;
-}
-
-static void net_timeout(struct net_device *dev)
-{
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict ?" : "network cable problem");
- /* Try to restart the adaptor. */
- netif_wake_queue(dev);
-}
-
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-
- if (net_debug > 3) {
- printk("%s: sent %d byte packet of type %x\n",
- dev->name, skb->len,
- (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
- }
-
- /* keep the upload from being interrupted, since we
- ask the chip to start transmitting before the
- whole packet has been completely uploaded. */
-
- spin_lock_irq(&lp->lock);
- netif_stop_queue(dev);
-
- /* initiate a transmit sequence */
- writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd);
- writeword(dev->base_addr, TX_LEN_PORT, skb->len);
-
- /* Test to see if the chip has allocated memory for the packet */
- if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
- /*
- * Gasp! It hasn't. But that shouldn't happen since
- * we're waiting for TxOk, so return 1 and requeue this packet.
- */
-
- spin_unlock_irq(&lp->lock);
- if (net_debug) printk("cs89x0: Tx buffer not free!\n");
- return 1;
- }
- /* Write the contents of the packet */
- writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
- spin_unlock_irq(&lp->lock);
- lp->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
- dev_kfree_skb (skb);
-
- /*
- * We DO NOT call netif_wake_queue() here.
- * We also DO NOT call netif_start_queue().
- *
- * Either of these would cause another bottom half run through
- * net_send_packet() before this packet has fully gone out. That causes
- * us to hit the "Gasp!" above and the send is rescheduled. it runs like
- * a dog. We just return and wait for the Tx completion interrupt handler
- * to restart the netdevice layer
- */
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-
-static irqreturn_t net_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr, status;
- int handled = 0;
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- /* we MUST read all the events out of the ISQ, otherwise we'll never
- get interrupted again. As a consequence, we can't have any limit
- on the number of times we loop in the interrupt handler. The
- hardware guarantees that eventually we'll run out of events. Of
- course, if you're on a slow machine, and packets are arriving
- faster than you can read them off, you're screwed. Hasta la
- vista, baby! */
- while ((status = readword(dev->base_addr, ISQ_PORT))) {
- if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
- handled = 1;
- switch(status & ISQ_EVENT_MASK) {
- case ISQ_RECEIVER_EVENT:
- /* Got a packet(s). */
- net_rx(dev);
- break;
- case ISQ_TRANSMITTER_EVENT:
- lp->stats.tx_packets++;
- netif_wake_queue(dev); /* Inform upper layers. */
- if ((status & ( TX_OK |
- TX_LOST_CRS |
- TX_SQE_ERROR |
- TX_LATE_COL |
- TX_16_COL)) != TX_OK) {
- if ((status & TX_OK) == 0) lp->stats.tx_errors++;
- if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
- if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
- if (status & TX_LATE_COL) lp->stats.tx_window_errors++;
- if (status & TX_16_COL) lp->stats.tx_aborted_errors++;
- }
- break;
- case ISQ_BUFFER_EVENT:
- if (status & READY_FOR_TX) {
- /* we tried to transmit a packet earlier,
- but inexplicably ran out of buffers.
- That shouldn't happen since we only ever
- load one packet. Shrug. Do the right
- thing anyway. */
- netif_wake_queue(dev); /* Inform upper layers. */
- }
- if (status & TX_UNDERRUN) {
- if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
- lp->send_underrun++;
- if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
- else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
- /* transmit cycle is done, although
- frame wasn't transmitted - this
- avoids having to wait for the upper
- layers to timeout on us, in the
- event of a tx underrun */
- netif_wake_queue(dev); /* Inform upper layers. */
- }
-#if ALLOW_DMA
- if (lp->use_dma && (status & RX_DMA)) {
- int count = readreg(dev, PP_DmaFrameCnt);
- while(count) {
- if (net_debug > 5)
- printk("%s: receiving %d DMA frames\n", dev->name, count);
- if (net_debug > 2 && count >1)
- printk("%s: receiving %d DMA frames\n", dev->name, count);
- dma_rx(dev);
- if (--count == 0)
- count = readreg(dev, PP_DmaFrameCnt);
- if (net_debug > 2 && count > 0)
- printk("%s: continuing with %d DMA frames\n", dev->name, count);
- }
- }
-#endif
- break;
- case ISQ_RX_MISS_EVENT:
- lp->stats.rx_missed_errors += (status >>6);
- break;
- case ISQ_TX_COL_EVENT:
- lp->stats.collisions += (status >>6);
- break;
- }
- }
- return IRQ_RETVAL(handled);
-}
-
-static void
-count_rx_errors(int status, struct net_local *lp)
-{
- lp->stats.rx_errors++;
- if (status & RX_RUNT) lp->stats.rx_length_errors++;
- if (status & RX_EXTRA_DATA) lp->stats.rx_length_errors++;
- if (status & RX_CRC_ERROR) if (!(status & (RX_EXTRA_DATA|RX_RUNT)))
- /* per str 172 */
- lp->stats.rx_crc_errors++;
- if (status & RX_DRIBBLE) lp->stats.rx_frame_errors++;
- return;
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-net_rx(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- struct sk_buff *skb;
- int status, length;
-
- int ioaddr = dev->base_addr;
- status = readword(ioaddr, RX_FRAME_PORT);
- length = readword(ioaddr, RX_FRAME_PORT);
-
- if ((status & RX_OK) == 0) {
- count_rx_errors(status, lp);
- return;
- }
-
- /* Malloc up new buffer. */
- skb = dev_alloc_skb(length + 2);
- if (skb == NULL) {
-#if 0 /* Again, this seems a cruel thing to do */
- printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
-#endif
- lp->stats.rx_dropped++;
- return;
- }
- skb_reserve(skb, 2); /* longword align L3 header */
-
- readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
- if (length & 1)
- skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT);
-
- if (net_debug > 3) {
- printk( "%s: received %d byte packet of type %x\n",
- dev->name, length,
- (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
- }
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += length;
-}
-
-#if ALLOW_DMA
-static void release_dma_buff(struct net_local *lp)
-{
- if (lp->dma_buff) {
- free_pages((unsigned long)(lp->dma_buff), get_order(lp->dmasize * 1024));
- lp->dma_buff = NULL;
- }
-}
-#endif
-
-/* The inverse routine to net_open(). */
-static int
-net_close(struct net_device *dev)
-{
-#if ALLOW_DMA
- struct net_local *lp = netdev_priv(dev);
-#endif
-
- netif_stop_queue(dev);
-
- writereg(dev, PP_RxCFG, 0);
- writereg(dev, PP_TxCFG, 0);
- writereg(dev, PP_BufCFG, 0);
- writereg(dev, PP_BusCTL, 0);
-
- free_irq(dev->irq, dev);
-
-#if ALLOW_DMA
- if (lp->use_dma && lp->dma) {
- free_dma(dev->dma);
- release_dma_buff(lp);
- }
-#endif
-
- /* Update the statistics here. */
- return 0;
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct net_device_stats *
-net_get_stats(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&lp->lock, flags);
- /* Update the statistics from the device registers. */
- lp->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
- lp->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- return &lp->stats;
-}
-
-static void set_multicast_list(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&lp->lock, flags);
- if(dev->flags&IFF_PROMISC)
- {
- lp->rx_mode = RX_ALL_ACCEPT;
- }
- else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
- {
- /* The multicast-accept list is initialized to accept-all, and we
- rely on higher-level filtering for now. */
- lp->rx_mode = RX_MULTCAST_ACCEPT;
- }
- else
- lp->rx_mode = 0;
-
- writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
-
- /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
- writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
- (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
- spin_unlock_irqrestore(&lp->lock, flags);
-}
-
-
-static int set_mac_address(struct net_device *dev, void *p)
-{
- int i;
- struct sockaddr *addr = p;
-
- if (netif_running(dev))
- return -EBUSY;
-
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
- if (net_debug) {
- DECLARE_MAC_BUF(mac);
- printk("%s: Setting MAC address to %s.\n",
- dev->name, print_mac(mac, dev->dev_addr));
- }
- /* set the Ethernet address */
- for (i=0; i < ETH_ALEN/2; i++)
- writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
-
- return 0;
-}
-
-#ifdef MODULE
-
-static struct net_device *dev_cs89x0;
-
-/*
- * Support the 'debug' module parm even if we're compiled for non-debug to
- * avoid breaking someone's startup scripts
- */
-
-static int io;
-static int irq;
-static int debug;
-static char media[8];
-static int duplex=-1;
-
-static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */
-static int dma;
-static int dmasize=16; /* or 64 */
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(debug, int, 0);
-module_param_string(media, media, sizeof(media), 0);
-module_param(duplex, int, 0);
-module_param(dma , int, 0);
-module_param(dmasize , int, 0);
-module_param(use_dma , int, 0);
-MODULE_PARM_DESC(io, "cs89x0 I/O base address");
-MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
-#if DEBUGGING
-MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
-#else
-MODULE_PARM_DESC(debug, "(ignored)");
-#endif
-MODULE_PARM_DESC(media, "Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)");
-/* No other value than -1 for duplex seems to be currently interpreted */
-MODULE_PARM_DESC(duplex, "(ignored)");
-#if ALLOW_DMA
-MODULE_PARM_DESC(dma , "cs89x0 ISA DMA channel; ignored if use_dma=0");
-MODULE_PARM_DESC(dmasize , "cs89x0 DMA size in kB (16,64); ignored if use_dma=0");
-MODULE_PARM_DESC(use_dma , "cs89x0 using DMA (0-1)");
-#else
-MODULE_PARM_DESC(dma , "(ignored)");
-MODULE_PARM_DESC(dmasize , "(ignored)");
-MODULE_PARM_DESC(use_dma , "(ignored)");
-#endif
-
-MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>");
-MODULE_LICENSE("GPL");
-
-
-/*
-* media=t - specify media type
- or media=2
- or media=aui
- or medai=auto
-* duplex=0 - specify forced half/full/autonegotiate duplex
-* debug=# - debug level
-
-
-* Default Chip Configuration:
- * DMA Burst = enabled
- * IOCHRDY Enabled = enabled
- * UseSA = enabled
- * CS8900 defaults to half-duplex if not specified on command-line
- * CS8920 defaults to autoneg if not specified on command-line
- * Use reset defaults for other config parameters
-
-* Assumptions:
- * media type specified is supported (circuitry is present)
- * if memory address is > 1MB, then required mem decode hw is present
- * if 10B-2, then agent other than driver will enable DC/DC converter
- (hw or software util)
-
-
-*/
-
-int __init init_module(void)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- struct net_local *lp;
- int ret = 0;
-
-#if DEBUGGING
- net_debug = debug;
-#else
- debug = 0;
-#endif
- if (!dev)
- return -ENOMEM;
-
- dev->irq = irq;
- dev->base_addr = io;
- lp = netdev_priv(dev);
-
-#if ALLOW_DMA
- if (use_dma) {
- lp->use_dma = use_dma;
- lp->dma = dma;
- lp->dmasize = dmasize;
- }
-#endif
-
- spin_lock_init(&lp->lock);
-
- /* boy, they'd better get these right */
- if (!strcmp(media, "rj45"))
- lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
- else if (!strcmp(media, "aui"))
- lp->adapter_cnf = A_CNF_MEDIA_AUI | A_CNF_AUI;
- else if (!strcmp(media, "bnc"))
- lp->adapter_cnf = A_CNF_MEDIA_10B_2 | A_CNF_10B_2;
- else
- lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
-
- if (duplex==-1)
- lp->auto_neg_cnf = AUTO_NEG_ENABLE;
-
- if (io == 0) {
- printk(KERN_ERR "cs89x0.c: Module autoprobing not allowed.\n");
- printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n");
- ret = -EPERM;
- goto out;
- } else if (io <= 0x1ff) {
- ret = -ENXIO;
- goto out;
- }
-
-#if ALLOW_DMA
- if (use_dma && dmasize != 16 && dmasize != 64) {
- printk(KERN_ERR "cs89x0.c: dma size must be either 16K or 64K, not %dK\n", dmasize);
- ret = -EPERM;
- goto out;
- }
-#endif
- ret = cs89x0_probe1(dev, io, 1);
- if (ret)
- goto out;
-
- dev_cs89x0 = dev;
- return 0;
-out:
- free_netdev(dev);
- return ret;
-}
-
-void __exit
-cleanup_module(void)
-{
- unregister_netdev(dev_cs89x0);
- writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID);
- release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
- free_netdev(dev_cs89x0);
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * version-control: t
- * kept-new-versions: 5
- * c-indent-level: 8
- * tab-width: 8
- * End:
- *
- */
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
deleted file mode 100644
index ee140e63ddc..00000000000
--- a/drivers/net/cxgb3/ael1002.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#include "common.h"
-#include "regs.h"
-
-enum {
- AEL100X_TX_DISABLE = 9,
- AEL100X_TX_CONFIG1 = 0xc002,
- AEL1002_PWR_DOWN_HI = 0xc011,
- AEL1002_PWR_DOWN_LO = 0xc012,
- AEL1002_XFI_EQL = 0xc015,
- AEL1002_LB_EN = 0xc017,
-
- LASI_CTRL = 0x9002,
- LASI_STAT = 0x9005
-};
-
-static void ael100x_txon(struct cphy *phy)
-{
- int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
-
- msleep(100);
- t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
- msleep(30);
-}
-
-static int ael1002_power_down(struct cphy *phy, int enable)
-{
- int err;
-
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
- if (!err)
- err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
- BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
- return err;
-}
-
-static int ael1002_reset(struct cphy *phy, int wait)
-{
- int err;
-
- if ((err = ael1002_power_down(phy, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
- (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
- (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
- 0, 1 << 5)))
- return err;
- return 0;
-}
-
-static int ael1002_intr_noop(struct cphy *phy)
-{
- return 0;
-}
-
-static int ael100x_get_link_status(struct cphy *phy, int *link_ok,
- int *speed, int *duplex, int *fc)
-{
- if (link_ok) {
- unsigned int status;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &status);
-
- /*
- * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
- * once more to get the current link state.
- */
- if (!err && !(status & BMSR_LSTATUS))
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR,
- &status);
- if (err)
- return err;
- *link_ok = !!(status & BMSR_LSTATUS);
- }
- if (speed)
- *speed = SPEED_10000;
- if (duplex)
- *duplex = DUPLEX_FULL;
- return 0;
-}
-
-static struct cphy_ops ael1002_ops = {
- .reset = ael1002_reset,
- .intr_enable = ael1002_intr_noop,
- .intr_disable = ael1002_intr_noop,
- .intr_clear = ael1002_intr_noop,
- .intr_handler = ael1002_intr_noop,
- .get_link_status = ael100x_get_link_status,
- .power_down = ael1002_power_down,
-};
-
-void t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
- int phy_addr, const struct mdio_ops *mdio_ops)
-{
- cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops);
- ael100x_txon(phy);
-}
-
-static int ael1006_reset(struct cphy *phy, int wait)
-{
- return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
-}
-
-static int ael1006_intr_enable(struct cphy *phy)
-{
- return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
-}
-
-static int ael1006_intr_disable(struct cphy *phy)
-{
- return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
-}
-
-static int ael1006_intr_clear(struct cphy *phy)
-{
- u32 val;
-
- return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
-}
-
-static int ael1006_intr_handler(struct cphy *phy)
-{
- unsigned int status;
- int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
-
- if (err)
- return err;
- return (status & 1) ? cphy_cause_link_change : 0;
-}
-
-static int ael1006_power_down(struct cphy *phy, int enable)
-{
- return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
- BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
-}
-
-static struct cphy_ops ael1006_ops = {
- .reset = ael1006_reset,
- .intr_enable = ael1006_intr_enable,
- .intr_disable = ael1006_intr_disable,
- .intr_clear = ael1006_intr_clear,
- .intr_handler = ael1006_intr_handler,
- .get_link_status = ael100x_get_link_status,
- .power_down = ael1006_power_down,
-};
-
-void t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
- int phy_addr, const struct mdio_ops *mdio_ops)
-{
- cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops);
- ael100x_txon(phy);
-}
-
-static struct cphy_ops qt2045_ops = {
- .reset = ael1006_reset,
- .intr_enable = ael1006_intr_enable,
- .intr_disable = ael1006_intr_disable,
- .intr_clear = ael1006_intr_clear,
- .intr_handler = ael1006_intr_handler,
- .get_link_status = ael100x_get_link_status,
- .power_down = ael1006_power_down,
-};
-
-void t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
- int phy_addr, const struct mdio_ops *mdio_ops)
-{
- unsigned int stat;
-
- cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops);
-
- /*
- * Some cards where the PHY is supposed to be at address 0 actually
- * have it at 1.
- */
- if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
- stat == 0xffff)
- phy->addr = 1;
-}
-
-static int xaui_direct_reset(struct cphy *phy, int wait)
-{
- return 0;
-}
-
-static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
- int *speed, int *duplex, int *fc)
-{
- if (link_ok) {
- unsigned int status;
-
- status = t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
- t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
- t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
- t3_read_reg(phy->adapter,
- XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
- *link_ok = !(status & F_LOWSIG0);
- }
- if (speed)
- *speed = SPEED_10000;
- if (duplex)
- *duplex = DUPLEX_FULL;
- return 0;
-}
-
-static int xaui_direct_power_down(struct cphy *phy, int enable)
-{
- return 0;
-}
-
-static struct cphy_ops xaui_direct_ops = {
- .reset = xaui_direct_reset,
- .intr_enable = ael1002_intr_noop,
- .intr_disable = ael1002_intr_noop,
- .intr_clear = ael1002_intr_noop,
- .intr_handler = ael1002_intr_noop,
- .get_link_status = xaui_direct_get_link_status,
- .power_down = xaui_direct_power_down,
-};
-
-void t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
- int phy_addr, const struct mdio_ops *mdio_ops)
-{
- cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops);
-}
diff --git a/drivers/net/cxgb3/vsc8211.c b/drivers/net/cxgb3/vsc8211.c
deleted file mode 100644
index eee4285b31b..00000000000
--- a/drivers/net/cxgb3/vsc8211.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#include "common.h"
-
-/* VSC8211 PHY specific registers. */
-enum {
- VSC8211_INTR_ENABLE = 25,
- VSC8211_INTR_STATUS = 26,
- VSC8211_AUX_CTRL_STAT = 28,
-};
-
-enum {
- VSC_INTR_RX_ERR = 1 << 0,
- VSC_INTR_MS_ERR = 1 << 1, /* master/slave resolution error */
- VSC_INTR_CABLE = 1 << 2, /* cable impairment */
- VSC_INTR_FALSE_CARR = 1 << 3, /* false carrier */
- VSC_INTR_MEDIA_CHG = 1 << 4, /* AMS media change */
- VSC_INTR_RX_FIFO = 1 << 5, /* Rx FIFO over/underflow */
- VSC_INTR_TX_FIFO = 1 << 6, /* Tx FIFO over/underflow */
- VSC_INTR_DESCRAMBL = 1 << 7, /* descrambler lock-lost */
- VSC_INTR_SYMBOL_ERR = 1 << 8, /* symbol error */
- VSC_INTR_NEG_DONE = 1 << 10, /* autoneg done */
- VSC_INTR_NEG_ERR = 1 << 11, /* autoneg error */
- VSC_INTR_LINK_CHG = 1 << 13, /* link change */
- VSC_INTR_ENABLE = 1 << 15, /* interrupt enable */
-};
-
-#define CFG_CHG_INTR_MASK (VSC_INTR_LINK_CHG | VSC_INTR_NEG_ERR | \
- VSC_INTR_NEG_DONE)
-#define INTR_MASK (CFG_CHG_INTR_MASK | VSC_INTR_TX_FIFO | VSC_INTR_RX_FIFO | \
- VSC_INTR_ENABLE)
-
-/* PHY specific auxiliary control & status register fields */
-#define S_ACSR_ACTIPHY_TMR 0
-#define M_ACSR_ACTIPHY_TMR 0x3
-#define V_ACSR_ACTIPHY_TMR(x) ((x) << S_ACSR_ACTIPHY_TMR)
-
-#define S_ACSR_SPEED 3
-#define M_ACSR_SPEED 0x3
-#define G_ACSR_SPEED(x) (((x) >> S_ACSR_SPEED) & M_ACSR_SPEED)
-
-#define S_ACSR_DUPLEX 5
-#define F_ACSR_DUPLEX (1 << S_ACSR_DUPLEX)
-
-#define S_ACSR_ACTIPHY 6
-#define F_ACSR_ACTIPHY (1 << S_ACSR_ACTIPHY)
-
-/*
- * Reset the PHY. This PHY completes reset immediately so we never wait.
- */
-static int vsc8211_reset(struct cphy *cphy, int wait)
-{
- return t3_phy_reset(cphy, 0, 0);
-}
-
-static int vsc8211_intr_enable(struct cphy *cphy)
-{
- return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK);
-}
-
-static int vsc8211_intr_disable(struct cphy *cphy)
-{
- return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0);
-}
-
-static int vsc8211_intr_clear(struct cphy *cphy)
-{
- u32 val;
-
- /* Clear PHY interrupts by reading the register. */
- return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val);
-}
-
-static int vsc8211_autoneg_enable(struct cphy *cphy)
-{
- return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
- BMCR_ANENABLE | BMCR_ANRESTART);
-}
-
-static int vsc8211_autoneg_restart(struct cphy *cphy)
-{
- return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
- BMCR_ANRESTART);
-}
-
-static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
- int *speed, int *duplex, int *fc)
-{
- unsigned int bmcr, status, lpa, adv;
- int err, sp = -1, dplx = -1, pause = 0;
-
- err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
- if (!err)
- err = mdio_read(cphy, 0, MII_BMSR, &status);
- if (err)
- return err;
-
- if (link_ok) {
- /*
- * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
- * once more to get the current link state.
- */
- if (!(status & BMSR_LSTATUS))
- err = mdio_read(cphy, 0, MII_BMSR, &status);
- if (err)
- return err;
- *link_ok = (status & BMSR_LSTATUS) != 0;
- }
- if (!(bmcr & BMCR_ANENABLE)) {
- dplx = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
- if (bmcr & BMCR_SPEED1000)
- sp = SPEED_1000;
- else if (bmcr & BMCR_SPEED100)
- sp = SPEED_100;
- else
- sp = SPEED_10;
- } else if (status & BMSR_ANEGCOMPLETE) {
- err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status);
- if (err)
- return err;
-
- dplx = (status & F_ACSR_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF;
- sp = G_ACSR_SPEED(status);
- if (sp == 0)
- sp = SPEED_10;
- else if (sp == 1)
- sp = SPEED_100;
- else
- sp = SPEED_1000;
-
- if (fc && dplx == DUPLEX_FULL) {
- err = mdio_read(cphy, 0, MII_LPA, &lpa);
- if (!err)
- err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
- if (err)
- return err;
-
- if (lpa & adv & ADVERTISE_PAUSE_CAP)
- pause = PAUSE_RX | PAUSE_TX;
- else if ((lpa & ADVERTISE_PAUSE_CAP) &&
- (lpa & ADVERTISE_PAUSE_ASYM) &&
- (adv & ADVERTISE_PAUSE_ASYM))
- pause = PAUSE_TX;
- else if ((lpa & ADVERTISE_PAUSE_ASYM) &&
- (adv & ADVERTISE_PAUSE_CAP))
- pause = PAUSE_RX;
- }
- }
- if (speed)
- *speed = sp;
- if (duplex)
- *duplex = dplx;
- if (fc)
- *fc = pause;
- return 0;
-}
-
-static int vsc8211_power_down(struct cphy *cphy, int enable)
-{
- return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN,
- enable ? BMCR_PDOWN : 0);
-}
-
-static int vsc8211_intr_handler(struct cphy *cphy)
-{
- unsigned int cause;
- int err, cphy_cause = 0;
-
- err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause);
- if (err)
- return err;
-
- cause &= INTR_MASK;
- if (cause & CFG_CHG_INTR_MASK)
- cphy_cause |= cphy_cause_link_change;
- if (cause & (VSC_INTR_RX_FIFO | VSC_INTR_TX_FIFO))
- cphy_cause |= cphy_cause_fifo_error;
- return cphy_cause;
-}
-
-static struct cphy_ops vsc8211_ops = {
- .reset = vsc8211_reset,
- .intr_enable = vsc8211_intr_enable,
- .intr_disable = vsc8211_intr_disable,
- .intr_clear = vsc8211_intr_clear,
- .intr_handler = vsc8211_intr_handler,
- .autoneg_enable = vsc8211_autoneg_enable,
- .autoneg_restart = vsc8211_autoneg_restart,
- .advertise = t3_phy_advertise,
- .set_speed_duplex = t3_set_phy_speed_duplex,
- .get_link_status = vsc8211_get_link_status,
- .power_down = vsc8211_power_down,
-};
-
-void t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
- int phy_addr, const struct mdio_ops *mdio_ops)
-{
- cphy_init(phy, adapter, phy_addr, &vsc8211_ops, mdio_ops);
-}
diff --git a/drivers/net/de600.c b/drivers/net/de600.c
deleted file mode 100644
index cb849b091f9..00000000000
--- a/drivers/net/de600.c
+++ /dev/null
@@ -1,537 +0,0 @@
-static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj0rn@blox.se)\n";
-/*
- * de600.c
- *
- * Linux driver for the D-Link DE-600 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
- * The Author may be reached as bj0rn@blox.se
- *
- * Based on adapter information gathered from DE600.ASM by D-Link Inc.,
- * as included on disk C in the v.2.11 of PC/TCP from FTP Software.
- * For DE600.asm:
- * Portions (C) Copyright 1990 D-Link, Inc.
- * Copyright, 1988-1992, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * (Now at <becker@scyld.com>)
- *
- **************************************************************/
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- **************************************************************/
-
-/* Add more time here if your adapter won't work OK: */
-#define DE600_SLOW_DOWN udelay(delay_time)
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifdef DE600_DEBUG
-#define PRINTK(x) if (de600_debug >= 2) printk x
-#else
-#define DE600_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <asm/system.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/io.h>
-
-#include "de600.h"
-
-static unsigned int de600_debug = DE600_DEBUG;
-module_param(de600_debug, int, 0);
-MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
-
-static unsigned int check_lost = 1;
-module_param(check_lost, bool, 0);
-MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
-
-static unsigned int delay_time = 10;
-module_param(delay_time, int, 0);
-MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
-
-
-/*
- * D-Link driver variables:
- */
-
-static volatile int rx_page;
-
-#define TX_PAGES 2
-static volatile int tx_fifo[TX_PAGES];
-static volatile int tx_fifo_in;
-static volatile int tx_fifo_out;
-static volatile int free_tx_pages = TX_PAGES;
-static int was_down;
-static DEFINE_SPINLOCK(de600_lock);
-
-static inline u8 de600_read_status(struct net_device *dev)
-{
- u8 status;
-
- outb_p(STATUS, DATA_PORT);
- status = inb(STATUS_PORT);
- outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
-
- return status;
-}
-
-static inline u8 de600_read_byte(unsigned char type, struct net_device *dev)
-{
- /* dev used by macros */
- u8 lo;
- outb_p((type), DATA_PORT);
- lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
- outb_p((type) | HI_NIBBLE, DATA_PORT);
- return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- */
-
-static int de600_open(struct net_device *dev)
-{
- unsigned long flags;
- int ret = request_irq(DE600_IRQ, de600_interrupt, 0, dev->name, dev);
- if (ret) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
- return ret;
- }
- spin_lock_irqsave(&de600_lock, flags);
- ret = adapter_init(dev);
- spin_unlock_irqrestore(&de600_lock, flags);
- return ret;
-}
-
-/*
- * The inverse routine to de600_open().
- */
-
-static int de600_close(struct net_device *dev)
-{
- select_nic();
- rx_page = 0;
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- de600_put_command(0);
- select_prn();
- free_irq(DE600_IRQ, dev);
- return 0;
-}
-
-static inline void trigger_interrupt(struct net_device *dev)
-{
- de600_put_command(FLIP_IRQ);
- select_prn();
- DE600_SLOW_DOWN;
- select_nic();
- de600_put_command(0);
-}
-
-/*
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-
-static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- int transmit_from;
- int len;
- int tickssofar;
- u8 *buffer = skb->data;
- int i;
-
- if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */
- tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- /* else */
- printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
- /* Restart the adapter. */
- spin_lock_irqsave(&de600_lock, flags);
- if (adapter_init(dev)) {
- spin_unlock_irqrestore(&de600_lock, flags);
- return 1;
- }
- spin_unlock_irqrestore(&de600_lock, flags);
- }
-
- /* Start real output */
- PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
-
- spin_lock_irqsave(&de600_lock, flags);
- select_nic();
- tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
- tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
-
- if(check_lost)
- {
- /* This costs about 40 instructions per packet... */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
- if (adapter_init(dev)) {
- spin_unlock_irqrestore(&de600_lock, flags);
- return 1;
- }
- }
- }
-
- de600_setup_address(transmit_from, RW_ADDR);
- for (i = 0; i < skb->len ; ++i, ++buffer)
- de600_put_byte(*buffer);
- for (; i < len; ++i)
- de600_put_byte(0);
-
- if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
- dev->trans_start = jiffies;
- netif_start_queue(dev); /* allow more packets into adapter */
- /* Send page and generate a faked interrupt */
- de600_setup_address(transmit_from, TX_ADDR);
- de600_put_command(TX_ENABLE);
- }
- else {
- if (free_tx_pages)
- netif_start_queue(dev);
- else
- netif_stop_queue(dev);
- select_prn();
- }
- spin_unlock_irqrestore(&de600_lock, flags);
- dev_kfree_skb(skb);
- return 0;
-}
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-
-static irqreturn_t de600_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- u8 irq_status;
- int retrig = 0;
- int boguscount = 0;
-
- spin_lock(&de600_lock);
-
- select_nic();
- irq_status = de600_read_status(dev);
-
- do {
- PRINTK(("de600_interrupt (%02X)\n", irq_status));
-
- if (irq_status & RX_GOOD)
- de600_rx_intr(dev);
- else if (!(irq_status & RX_BUSY))
- de600_put_command(RX_ENABLE);
-
- /* Any transmission in progress? */
- if (free_tx_pages < TX_PAGES)
- retrig = de600_tx_intr(dev, irq_status);
- else
- retrig = 0;
-
- irq_status = de600_read_status(dev);
- } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
- /*
- * Yeah, it _looks_ like busy waiting, smells like busy waiting
- * and I know it's not PC, but please, it will only occur once
- * in a while and then only for a loop or so (< 1ms for sure!)
- */
-
- /* Enable adapter interrupts */
- select_prn();
- if (retrig)
- trigger_interrupt(dev);
- spin_unlock(&de600_lock);
- return IRQ_HANDLED;
-}
-
-static int de600_tx_intr(struct net_device *dev, int irq_status)
-{
- /*
- * Returns 1 if tx still not done
- */
-
- /* Check if current transmission is done yet */
- if (irq_status & TX_BUSY)
- return 1; /* tx not done, try again */
-
- /* else */
- /* If last transmission OK then bump fifo index */
- if (!(irq_status & TX_FAILED16)) {
- tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
- ++free_tx_pages;
- dev->stats.tx_packets++;
- netif_wake_queue(dev);
- }
-
- /* More to send, or resend last packet? */
- if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
- dev->trans_start = jiffies;
- de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
- de600_put_command(TX_ENABLE);
- return 1;
- }
- /* else */
-
- return 0;
-}
-
-/*
- * We have a good packet, get it out of the adapter.
- */
-static void de600_rx_intr(struct net_device *dev)
-{
- struct sk_buff *skb;
- int i;
- int read_from;
- int size;
- unsigned char *buffer;
-
- /* Get size of received packet */
- size = de600_read_byte(RX_LEN, dev); /* low byte */
- size += (de600_read_byte(RX_LEN, dev) << 8); /* high byte */
- size -= 4; /* Ignore trailing 4 CRC-bytes */
-
- /* Tell adapter where to store next incoming packet, enable receiver */
- read_from = rx_page_adr();
- next_rx_page();
- de600_put_command(RX_ENABLE);
-
- if ((size < 32) || (size > 1535)) {
- printk(KERN_WARNING "%s: Bogus packet size %d.\n", dev->name, size);
- if (size > 10000)
- adapter_init(dev);
- return;
- }
-
- skb = dev_alloc_skb(size+2);
- if (skb == NULL) {
- printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
- return;
- }
- /* else */
-
- skb_reserve(skb,2); /* Align */
-
- /* 'skb->data' points to the start of sk_buff data area. */
- buffer = skb_put(skb,size);
-
- /* copy the packet into the buffer */
- de600_setup_address(read_from, RW_ADDR);
- for (i = size; i > 0; --i, ++buffer)
- *buffer = de600_read_byte(READ_DATA, dev);
-
- skb->protocol=eth_type_trans(skb,dev);
-
- netif_rx(skb);
-
- /* update stats */
- dev->last_rx = jiffies;
- dev->stats.rx_packets++; /* count all receives */
- dev->stats.rx_bytes += size; /* count all received bytes */
-
- /*
- * If any worth-while packets have been received, netif_rx()
- * will work on them when we get to the tasklets.
- */
-}
-
-static struct net_device * __init de600_probe(void)
-{
- int i;
- struct net_device *dev;
- int err;
- DECLARE_MAC_BUF(mac);
-
- dev = alloc_etherdev(0);
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
-
- if (!request_region(DE600_IO, 3, "de600")) {
- printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
- err = -EBUSY;
- goto out;
- }
-
- printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
- /* Alpha testers must have the version number to report bugs. */
- if (de600_debug > 1)
- printk(version);
-
- /* probe for adapter */
- err = -ENODEV;
- rx_page = 0;
- select_nic();
- (void)de600_read_status(dev);
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- if (de600_read_status(dev) & 0xf0) {
- printk(": not at I/O %#3x.\n", DATA_PORT);
- goto out1;
- }
-
- /*
- * Maybe we found one,
- * have to check if it is a D-Link DE-600 adapter...
- */
-
- /* Get the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
- dev->broadcast[i] = 0xff;
- }
-
- /* Check magic code */
- if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
- /* OK, install real address */
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x80;
- dev->dev_addr[2] = 0xc8;
- dev->dev_addr[3] &= 0x0f;
- dev->dev_addr[3] |= 0x70;
- } else {
- printk(" not identified in the printer port\n");
- goto out1;
- }
-
- printk(", Ethernet Address: %s\n", print_mac(mac, dev->dev_addr));
-
- dev->open = de600_open;
- dev->stop = de600_close;
- dev->hard_start_xmit = &de600_start_xmit;
-
- dev->flags&=~IFF_MULTICAST;
-
- select_prn();
-
- err = register_netdev(dev);
- if (err)
- goto out1;
-
- return dev;
-
-out1:
- release_region(DE600_IO, 3);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static int adapter_init(struct net_device *dev)
-{
- int i;
-
- select_nic();
- rx_page = 0; /* used by RESET */
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
-
- /* Check if it is still there... */
- /* Get the some bytes of the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
- (de600_read_byte(READ_DATA, dev) != 0x15)) {
- /* was: if (de600_read_status(dev) & 0xf0) { */
- printk("Something has happened to the DE-600! Please check it and do a new ifconfig!\n");
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de600_close(dev);
- was_down = 1;
- netif_stop_queue(dev); /* Transmit busy... */
- return 1; /* failed */
- }
-
- if (was_down) {
- printk(KERN_INFO "%s: Thanks, I feel much better now!\n", dev->name);
- was_down = 0;
- }
-
- tx_fifo_in = 0;
- tx_fifo_out = 0;
- free_tx_pages = TX_PAGES;
-
-
- /* set the ether address. */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++)
- de600_put_byte(dev->dev_addr[i]);
-
- /* where to start saving incoming packets */
- rx_page = RX_BP | RX_BASE_PAGE;
- de600_setup_address(MEM_4K, RW_ADDR);
- /* Enable receiver */
- de600_put_command(RX_ENABLE);
- select_prn();
-
- netif_start_queue(dev);
-
- return 0; /* OK */
-}
-
-static struct net_device *de600_dev;
-
-static int __init de600_init(void)
-{
- de600_dev = de600_probe();
- if (IS_ERR(de600_dev))
- return PTR_ERR(de600_dev);
- return 0;
-}
-
-static void __exit de600_exit(void)
-{
- unregister_netdev(de600_dev);
- release_region(DE600_IO, 3);
- free_netdev(de600_dev);
-}
-
-module_init(de600_init);
-module_exit(de600_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/de600.h b/drivers/net/de600.h
deleted file mode 100644
index e80ecbabcf4..00000000000
--- a/drivers/net/de600.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/**************************************************
- * *
- * Definition of D-Link Ethernet Pocket adapter *
- * *
- **************************************************/
-/*
- * D-Link Ethernet pocket adapter ports
- */
-/*
- * OK, so I'm cheating, but there are an awful lot of
- * reads and writes in order to get anything in and out
- * of the DE-600 with 4 bits at a time in the parallel port,
- * so every saved instruction really helps :-)
- */
-
-#ifndef DE600_IO
-#define DE600_IO 0x378
-#endif
-
-#define DATA_PORT (DE600_IO)
-#define STATUS_PORT (DE600_IO + 1)
-#define COMMAND_PORT (DE600_IO + 2)
-
-#ifndef DE600_IRQ
-#define DE600_IRQ 7
-#endif
-/*
- * It really should look like this, and autoprobing as well...
- *
-#define DATA_PORT (dev->base_addr + 0)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-#define DE600_IRQ dev->irq
- */
-
-/*
- * D-Link COMMAND_PORT commands
- */
-#define SELECT_NIC 0x04 /* select Network Interface Card */
-#define SELECT_PRN 0x1c /* select Printer */
-#define NML_PRN 0xec /* normal Printer situation */
-#define IRQEN 0x10 /* enable IRQ line */
-
-/*
- * D-Link STATUS_PORT
- */
-#define RX_BUSY 0x80
-#define RX_GOOD 0x40
-#define TX_FAILED16 0x10
-#define TX_BUSY 0x08
-
-/*
- * D-Link DATA_PORT commands
- * command in low 4 bits
- * data in high 4 bits
- * select current data nibble with HI_NIBBLE bit
- */
-#define WRITE_DATA 0x00 /* write memory */
-#define READ_DATA 0x01 /* read memory */
-#define STATUS 0x02 /* read status register */
-#define COMMAND 0x03 /* write command register (see COMMAND below) */
-#define NULL_COMMAND 0x04 /* null command */
-#define RX_LEN 0x05 /* read received packet length */
-#define TX_ADDR 0x06 /* set adapter transmit memory address */
-#define RW_ADDR 0x07 /* set adapter read/write memory address */
-#define HI_NIBBLE 0x08 /* read/write the high nibble of data,
- or-ed with rest of command */
-
-/*
- * command register, accessed through DATA_PORT with low bits = COMMAND
- */
-#define RX_ALL 0x01 /* PROMISCUOUS */
-#define RX_BP 0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
-#define RX_MBP 0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
-
-#define TX_ENABLE 0x04 /* bit 2 */
-#define RX_ENABLE 0x08 /* bit 3 */
-
-#define RESET 0x80 /* set bit 7 high */
-#define STOP_RESET 0x00 /* set bit 7 low */
-
-/*
- * data to command register
- * (high 4 bits in write to DATA_PORT)
- */
-#define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
-#define RX_BASE_PAGE 0x20 /* bit 5, always set when specifying RX_ADDR */
-#define FLIP_IRQ 0x40 /* bit 6 */
-
-/*
- * D-Link adapter internal memory:
- *
- * 0-2K 1:st transmit page (send from pointer up to 2K)
- * 2-4K 2:nd transmit page (send from pointer up to 4K)
- *
- * 4-6K 1:st receive page (data from 4K upwards)
- * 6-8K 2:nd receive page (data from 6K upwards)
- *
- * 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
- */
-#define MEM_2K 0x0800 /* 2048 */
-#define MEM_4K 0x1000 /* 4096 */
-#define MEM_6K 0x1800 /* 6144 */
-#define NODE_ADDRESS 0x2000 /* 8192 */
-
-#define RUNT 60 /* Too small Ethernet packet */
-
-/**************************************************
- * *
- * End of definition *
- * *
- **************************************************/
-
-/*
- * Index to functions, as function prototypes.
- */
-/* Routines used internally. (See "convenience macros") */
-static u8 de600_read_status(struct net_device *dev);
-static u8 de600_read_byte(unsigned char type, struct net_device *dev);
-
-/* Put in the device structure. */
-static int de600_open(struct net_device *dev);
-static int de600_close(struct net_device *dev);
-static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev);
-
-/* Dispatch from interrupts. */
-static irqreturn_t de600_interrupt(int irq, void *dev_id);
-static int de600_tx_intr(struct net_device *dev, int irq_status);
-static void de600_rx_intr(struct net_device *dev);
-
-/* Initialization */
-static void trigger_interrupt(struct net_device *dev);
-static int adapter_init(struct net_device *dev);
-
-/*
- * Convenience macros/functions for D-Link adapter
- */
-
-#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
-#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
-
-/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
-#define de600_put_byte(data) ( \
- outb_p(((data) << 4) | WRITE_DATA , DATA_PORT), \
- outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
-
-/*
- * The first two outb_p()'s below could perhaps be deleted if there
- * would be more delay in the last two. Not certain about it yet...
- */
-#define de600_put_command(cmd) ( \
- outb_p(( rx_page << 4) | COMMAND , DATA_PORT), \
- outb_p(( rx_page & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
- outb_p(((rx_page | cmd) << 4) | COMMAND , DATA_PORT), \
- outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
-
-#define de600_setup_address(addr,type) ( \
- outb_p((((addr) << 4) & 0xf0) | type , DATA_PORT), \
- outb_p(( (addr) & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
- outb_p((((addr) >> 4) & 0xf0) | type , DATA_PORT), \
- outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
-
-#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
-
-/* Flip bit, only 2 pages */
-#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
-
-#define tx_page_adr(a) (((a) + 1) * MEM_2K)
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
deleted file mode 100644
index d454e143483..00000000000
--- a/drivers/net/de620.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * de620.c $Revision: 1.40 $ BETA
- *
- *
- * Linux driver for the D-Link DE-620 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <bj0rn@blox.se>
- *
- * Based on adapter information gathered from DOS packetdriver
- * sources from D-Link Inc: (Special thanks to Henry Ngai of D-Link.)
- * Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992
- * Copyright, 1988, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * (Now at <becker@scyld.com>)
- *
- * Valuable assistance from:
- * J. Joshua Kopper <kopper@rtsg.mot.com>
- * Olav Kvittem <Olav.Kvittem@uninett.no>
- * Germano Caronni <caronni@nessie.cs.id.ethz.ch>
- * Jeremy Fitzhardinge <jeremy@suite.sw.oz.au>
- *
- *****************************************************************************/
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *****************************************************************************/
-static const char version[] =
- "de620.c: $Revision: 1.40 $, Bjorn Ekwall <bj0rn@blox.se>\n";
-
-/***********************************************************************
- *
- * "Tuning" section.
- *
- * Compile-time options: (see below for descriptions)
- * -DDE620_IO=0x378 (lpt1)
- * -DDE620_IRQ=7 (lpt1)
- * -DDE602_DEBUG=...
- * -DSHUTDOWN_WHEN_LOST
- * -DCOUNT_LOOPS
- * -DLOWSPEED
- * -DREAD_DELAY
- * -DWRITE_DELAY
- */
-
-/*
- * This driver assumes that the printer port is a "normal",
- * dumb, uni-directional port!
- * If your port is "fancy" in any way, please try to set it to "normal"
- * with your BIOS setup. I have no access to machines with bi-directional
- * ports, so I can't test such a driver :-(
- * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...)
- *
- * There are some clones of DE620 out there, with different names.
- * If the current driver does not recognize a clone, try to change
- * the following #define to:
- *
- * #define DE620_CLONE 1
- */
-#define DE620_CLONE 0
-
-/*
- * If the adapter has problems with high speeds, enable this #define
- * otherwise full printerport speed will be attempted.
- *
- * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
- *
-#define LOWSPEED
- */
-
-#ifndef READ_DELAY
-#define READ_DELAY 100 /* adapter internal read delay in 100ns units */
-#endif
-
-#ifndef WRITE_DELAY
-#define WRITE_DELAY 100 /* adapter internal write delay in 100ns units */
-#endif
-
-/*
- * Enable this #define if you want the adapter to do a "ifconfig down" on
- * itself when we have detected that something is possibly wrong with it.
- * The default behaviour is to retry with "adapter_init()" until success.
- * This should be used for debugging purposes only.
- *
-#define SHUTDOWN_WHEN_LOST
- */
-
-/*
- * Enable debugging by "-DDE620_DEBUG=3" when compiling,
- * OR by enabling the following #define
- *
- * use 0 for production, 1 for verification, >2 for debug
- *
-#define DE620_DEBUG 3
- */
-
-#ifdef LOWSPEED
-/*
- * Enable this #define if you want to see debugging output that show how long
- * we have to wait before the DE-620 is ready for the next read/write/command.
- *
-#define COUNT_LOOPS
- */
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-
-/* Constant definitions for the DE-620 registers, commands and bits */
-#include "de620.h"
-
-typedef unsigned char byte;
-
-/*******************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * See also "de620.h" *
- * *
- *******************************************************/
-#ifndef DE620_IO /* Compile-time configurable */
-#define DE620_IO 0x378
-#endif
-
-#ifndef DE620_IRQ /* Compile-time configurable */
-#define DE620_IRQ 7
-#endif
-
-#define DATA_PORT (dev->base_addr)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-
-#define RUNT 60 /* Too small Ethernet packet */
-#define GIANT 1514 /* largest legal size packet, no fcs */
-
-#ifdef DE620_DEBUG /* Compile-time configurable */
-#define PRINTK(x) if (de620_debug >= 2) printk x
-#else
-#define DE620_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-
-
-/*
- * Force media with insmod:
- * insmod de620.o bnc=1
- * or
- * insmod de620.o utp=1
- *
- * Force io and/or irq with insmod:
- * insmod de620.o io=0x378 irq=7
- *
- * Make a clone skip the Ethernet-address range check:
- * insmod de620.o clone=1
- */
-static int bnc;
-static int utp;
-static int io = DE620_IO;
-static int irq = DE620_IRQ;
-static int clone = DE620_CLONE;
-
-static unsigned int de620_debug = DE620_DEBUG;
-
-static spinlock_t de620_lock;
-
-module_param(bnc, int, 0);
-module_param(utp, int, 0);
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(clone, int, 0);
-module_param(de620_debug, int, 0);
-MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
-MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
-MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
-MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
-MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
-MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)");
-
-/***********************************************
- * *
- * Index to functions, as function prototypes. *
- * *
- ***********************************************/
-
-/*
- * Routines used internally. (See also "convenience macros.. below")
- */
-
-/* Put in the device structure. */
-static int de620_open(struct net_device *);
-static int de620_close(struct net_device *);
-static void de620_set_multicast_list(struct net_device *);
-static int de620_start_xmit(struct sk_buff *, struct net_device *);
-
-/* Dispatch from interrupts. */
-static irqreturn_t de620_interrupt(int, void *);
-static int de620_rx_intr(struct net_device *);
-
-/* Initialization */
-static int adapter_init(struct net_device *);
-static int read_eeprom(struct net_device *);
-
-
-/*
- * D-Link driver variables:
- */
-#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
-#define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */
-#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */
-#define DEF_NIC_CMD IRQEN | ICEN | DS1
-
-static volatile byte NIC_Cmd;
-static volatile byte next_rx_page;
-static byte first_rx_page;
-static byte last_rx_page;
-static byte EIPRegister;
-
-static struct nic {
- byte NodeID[6];
- byte RAM_Size;
- byte Model;
- byte Media;
- byte SCR;
-} nic_data;
-
-/**********************************************************
- * *
- * Convenience macros/functions for D-Link DE-620 adapter *
- * *
- **********************************************************/
-#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
-#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
-
-/* Check for ready-status, and return a nibble (high 4 bits) for data input */
-#ifdef COUNT_LOOPS
-static int tot_cnt;
-#endif
-static inline byte
-de620_ready(struct net_device *dev)
-{
- byte value;
- register short int cnt = 0;
-
- while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
- ++cnt;
-
-#ifdef COUNT_LOOPS
- tot_cnt += cnt;
-#endif
- return value & 0xf0; /* nibble */
-}
-
-static inline void
-de620_send_command(struct net_device *dev, byte cmd)
-{
- de620_ready(dev);
- if (cmd == W_DUMMY)
- outb(NIC_Cmd, COMMAND_PORT);
-
- outb(cmd, DATA_PORT);
-
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
- de620_ready(dev);
- outb(NIC_Cmd, COMMAND_PORT);
-}
-
-static inline void
-de620_put_byte(struct net_device *dev, byte value)
-{
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- de620_ready(dev);
- outb(value, DATA_PORT);
- de620_flip_ds(dev);
-}
-
-static inline byte
-de620_read_byte(struct net_device *dev)
-{
- byte value;
-
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- value = de620_ready(dev); /* High nibble */
- de620_flip_ds(dev);
- value |= de620_ready(dev) >> 4; /* Low nibble */
- return value;
-}
-
-static inline void
-de620_write_block(struct net_device *dev, byte *buffer, int count, int pad)
-{
-#ifndef LOWSPEED
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
-#ifdef COUNT_LOOPS
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
- /* No further optimization useful, the limit is in the adapter. */
- for ( ; count > 0; --count, ++buffer) {
- de620_put_byte(dev,*buffer);
- }
- for ( count = pad ; count > 0; --count, ++buffer) {
- de620_put_byte(dev, 0);
- }
- de620_send_command(dev,W_DUMMY);
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- for ( ; count > 0; count -=2) {
- outb(*buffer++, DATA_PORT);
- outb(uflip, COMMAND_PORT);
- outb(*buffer++, DATA_PORT);
- outb(dflip, COMMAND_PORT);
- }
- de620_send_command(dev,W_DUMMY);
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_read_block(struct net_device *dev, byte *data, int count)
-{
-#ifndef LOWSPEED
- byte value;
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
- /* No further optimization useful, the limit is in the adapter. */
- while (count-- > 0) {
- *data++ = de620_read_byte(dev);
- de620_flip_ds(dev);
- }
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- while (count-- > 0) {
- value = inb(STATUS_PORT) & 0xf0; /* High nibble */
- outb(uflip, COMMAND_PORT);
- *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
- outb(dflip , COMMAND_PORT);
- }
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_set_delay(struct net_device *dev)
-{
- de620_ready(dev);
- outb(W_DFR, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(WRITE_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(READ_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-}
-
-static inline void
-de620_set_register(struct net_device *dev, byte reg, byte value)
-{
- de620_ready(dev);
- outb(reg, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_put_byte(dev, value);
-}
-
-static inline byte
-de620_get_register(struct net_device *dev, byte reg)
-{
- byte value;
-
- de620_send_command(dev,reg);
- value = de620_read_byte(dev);
- de620_send_command(dev,W_DUMMY);
-
- return value;
-}
-
-/*********************************************************************
- *
- * Open/initialize the board.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- *
- */
-static int de620_open(struct net_device *dev)
-{
- int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev);
- if (ret) {
- printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
- return ret;
- }
-
- if (adapter_init(dev)) {
- ret = -EIO;
- goto out_free_irq;
- }
-
- netif_start_queue(dev);
- return 0;
-
-out_free_irq:
- free_irq(dev->irq, dev);
- return ret;
-}
-
-/************************************************
- *
- * The inverse routine to de620_open().
- *
- */
-
-static int de620_close(struct net_device *dev)
-{
- netif_stop_queue(dev);
- /* disable recv */
- de620_set_register(dev, W_TCR, RXOFF);
- free_irq(dev->irq, dev);
- return 0;
-}
-
-/*********************************************
- *
- * Set or clear the multicast filter for this adaptor.
- * (no real multicast implemented for the DE-620, but she can be promiscuous...)
- *
- */
-
-static void de620_set_multicast_list(struct net_device *dev)
-{
- if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- { /* Enable promiscuous mode */
- de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
- }
- else
- { /* Disable promiscuous mode, use normal mode */
- de620_set_register(dev, W_TCR, TCR_DEF);
- }
-}
-
-/*******************************************************
- *
- * Handle timeouts on transmit
- */
-
-static void de620_timeout(struct net_device *dev)
-{
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem");
- /* Restart the adapter. */
- if (!adapter_init(dev)) /* maybe close it */
- netif_wake_queue(dev);
-}
-
-/*******************************************************
- *
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- unsigned long flags;
- int len;
- byte *buffer = skb->data;
- byte using_txbuf;
-
- using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
-
- netif_stop_queue(dev);
-
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
- if (len & 1) /* send an even number of bytes */
- ++len;
-
- /* Start real output */
-
- spin_lock_irqsave(&de620_lock, flags)
- PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
- (int)skb->len, using_txbuf));
-
- /* select a free tx buffer. if there is one... */
- switch (using_txbuf) {
- default: /* both are free: use TXBF0 */
- case TXBF1: /* use TXBF0 */
- de620_send_command(dev,W_CR | RW0);
- using_txbuf |= TXBF0;
- break;
-
- case TXBF0: /* use TXBF1 */
- de620_send_command(dev,W_CR | RW1);
- using_txbuf |= TXBF1;
- break;
-
- case (TXBF0 | TXBF1): /* NONE!!! */
- printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
- spin_unlock_irqrestore(&de620_lock, flags);
- return 1;
- }
- de620_write_block(dev, buffer, skb->len, len-skb->len);
-
- dev->trans_start = jiffies;
- if(!(using_txbuf == (TXBF0 | TXBF1)))
- netif_wake_queue(dev);
-
- dev->stats.tx_packets++;
- spin_unlock_irqrestore(&de620_lock, flags);
- dev_kfree_skb (skb);
- return 0;
-}
-
-/*****************************************************
- *
- * Handle the network interface interrupts.
- *
- */
-static irqreturn_t
-de620_interrupt(int irq_in, void *dev_id)
-{
- struct net_device *dev = dev_id;
- byte irq_status;
- int bogus_count = 0;
- int again = 0;
-
- spin_lock(&de620_lock);
-
- /* Read the status register (_not_ the status port) */
- irq_status = de620_get_register(dev, R_STS);
-
- PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
-
- if (irq_status & RXGOOD) {
- do {
- again = de620_rx_intr(dev);
- PRINTK(("again=%d\n", again));
- }
- while (again && (++bogus_count < 100));
- }
-
- if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
- netif_wake_queue(dev);
-
- spin_unlock(&de620_lock);
- return IRQ_HANDLED;
-}
-
-/**************************************
- *
- * Get a packet from the adapter
- *
- * Send it "upstairs"
- *
- */
-static int de620_rx_intr(struct net_device *dev)
-{
- struct header_buf {
- byte status;
- byte Rx_NextPage;
- unsigned short Rx_ByteCount;
- } header_buf;
- struct sk_buff *skb;
- int size;
- byte *buffer;
- byte pagelink;
- byte curr_page;
-
- PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
-
- /* Tell the adapter that we are going to read data, and from where */
- de620_send_command(dev, W_CR | RRN);
- de620_set_register(dev, W_RSA1, next_rx_page);
- de620_set_register(dev, W_RSA0, 0);
-
- /* Deep breath, and away we goooooo */
- de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
- PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
- header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
-
- /* Plausible page header? */
- pagelink = header_buf.Rx_NextPage;
- if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
- /* Ouch... Forget it! Skip all and start afresh... */
- printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
- /* You win some, you lose some. And sometimes plenty... */
- adapter_init(dev);
- netif_wake_queue(dev);
- dev->stats.rx_over_errors++;
- return 0;
- }
-
- /* OK, this look good, so far. Let's see if it's consistent... */
- /* Let's compute the start of the next packet, based on where we are */
- pagelink = next_rx_page +
- ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
-
- /* Are we going to wrap around the page counter? */
- if (pagelink > last_rx_page)
- pagelink -= (last_rx_page - first_rx_page + 1);
-
- /* Is the _computed_ next page number equal to what the adapter says? */
- if (pagelink != header_buf.Rx_NextPage) {
- /* Naah, we'll skip this packet. Probably bogus data as well */
- printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
- next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
- de620_send_command(dev, W_DUMMY);
- de620_set_register(dev, W_NPRF, next_rx_page);
- dev->stats.rx_over_errors++;
- return 0;
- }
- next_rx_page = pagelink;
-
- size = header_buf.Rx_ByteCount - 4;
- if ((size < RUNT) || (GIANT < size)) {
- printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
- }
- else { /* Good packet? */
- skb = dev_alloc_skb(size+2);
- if (skb == NULL) { /* Yeah, but no place to put it... */
- printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
- dev->stats.rx_dropped++;
- }
- else { /* Yep! Go get it! */
- skb_reserve(skb,2); /* Align */
- /* skb->data points to the start of sk_buff data area */
- buffer = skb_put(skb,size);
- /* copy the packet into the buffer */
- de620_read_block(dev, buffer, size);
- PRINTK(("Read %d bytes\n", size));
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb); /* deliver it "upstairs" */
- dev->last_rx = jiffies;
- /* count all receives */
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += size;
- }
- }
-
- /* Let's peek ahead to see if we have read the last current packet */
- /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
- curr_page = de620_get_register(dev, R_CPR);
- de620_set_register(dev, W_NPRF, next_rx_page);
- PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
-
- return (next_rx_page != curr_page); /* That was slightly tricky... */
-}
-
-/*********************************************
- *
- * Reset the adapter to a known state
- *
- */
-static int adapter_init(struct net_device *dev)
-{
- int i;
- static int was_down;
-
- if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
- EIPRegister = NCTL0;
- if (nic_data.Media != 1)
- EIPRegister |= NIS0; /* not BNC */
- }
- else if (nic_data.Model == 2) { /* UTP */
- EIPRegister = NCTL0 | NIS0;
- }
-
- if (utp)
- EIPRegister = NCTL0 | NIS0;
- if (bnc)
- EIPRegister = NCTL0;
-
- de620_send_command(dev, W_CR | RNOP | CLEAR);
- de620_send_command(dev, W_CR | RNOP);
-
- de620_set_register(dev, W_SCR, SCR_DEF);
- /* disable recv to wait init */
- de620_set_register(dev, W_TCR, RXOFF);
-
- /* Set the node ID in the adapter */
- for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
- de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
- }
-
- de620_set_register(dev, W_EIP, EIPRegister);
-
- next_rx_page = first_rx_page = DE620_RX_START_PAGE;
- if (nic_data.RAM_Size)
- last_rx_page = nic_data.RAM_Size - 1;
- else /* 64k RAM */
- last_rx_page = 255;
-
- de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
- de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */
- de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
- de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
- de620_send_command(dev, W_DUMMY);
- de620_set_delay(dev);
-
- /* Final sanity check: Anybody out there? */
- /* Let's hope some bits from the statusregister make a good check */
-#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 )
-#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 )
- /* success: X 0 0 X 0 0 X X */
- /* ignore: EEDI RXGOOD COLS LNKS*/
-
- if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
- printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it"
-#ifdef SHUTDOWN_WHEN_LOST
- " and do a new ifconfig"
-#endif
- "! (%02x)\n", dev->name, i);
-#ifdef SHUTDOWN_WHEN_LOST
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de620_close(dev);
-#endif
- was_down = 1;
- return 1; /* failed */
- }
- if (was_down) {
- printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
- was_down = 0;
- }
-
- /* All OK, go ahead... */
- de620_set_register(dev, W_TCR, TCR_DEF);
-
- return 0; /* all ok */
-}
-
-/******************************************************************************
- *
- * Only start-up code below
- *
- */
-/****************************************
- *
- * Check if there is a DE-620 connected
- */
-struct net_device * __init de620_probe(int unit)
-{
- byte checkbyte = 0xa5;
- struct net_device *dev;
- int err = -ENOMEM;
- int i;
- DECLARE_MAC_BUF(mac);
-
- dev = alloc_etherdev(0);
- if (!dev)
- goto out;
-
- spin_lock_init(&de620_lock);
-
- /*
- * This is where the base_addr and irq gets set.
- * Tunable at compile-time and insmod-time
- */
- dev->base_addr = io;
- dev->irq = irq;
-
- /* allow overriding parameters on command line */
- if (unit >= 0) {
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- }
-
- if (de620_debug)
- printk(version);
-
- printk(KERN_INFO "D-Link DE-620 pocket adapter");
-
- if (!request_region(dev->base_addr, 3, "de620")) {
- printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
- err = -EBUSY;
- goto out1;
- }
-
- /* Initially, configure basic nibble mode, so we can read the EEPROM */
- NIC_Cmd = DEF_NIC_CMD;
- de620_set_register(dev, W_EIP, EIPRegister);
-
- /* Anybody out there? */
- de620_set_register(dev, W_CPR, checkbyte);
- checkbyte = de620_get_register(dev, R_CPR);
-
- if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
- printk(" not identified in the printer port\n");
- err = -ENODEV;
- goto out2;
- }
-
- /* else, got it! */
- dev->dev_addr[0] = nic_data.NodeID[0];
- for (i = 1; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = nic_data.NodeID[i];
- dev->broadcast[i] = 0xff;
- }
-
- printk(", Ethernet Address: %s", print_mac(mac, dev->dev_addr));
-
- printk(" (%dk RAM,",
- (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
-
- if (nic_data.Media == 1)
- printk(" BNC)\n");
- else
- printk(" UTP)\n");
-
- dev->open = de620_open;
- dev->stop = de620_close;
- dev->hard_start_xmit = de620_start_xmit;
- dev->tx_timeout = de620_timeout;
- dev->watchdog_timeo = HZ*2;
- dev->set_multicast_list = de620_set_multicast_list;
-
- /* base_addr and irq are already set, see above! */
-
- /* dump eeprom */
- if (de620_debug) {
- printk("\nEEPROM contents:\n");
- printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
- printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n",
- nic_data.NodeID[0], nic_data.NodeID[1],
- nic_data.NodeID[2], nic_data.NodeID[3],
- nic_data.NodeID[4], nic_data.NodeID[5]);
- printk("Model = %d\n", nic_data.Model);
- printk("Media = %d\n", nic_data.Media);
- printk("SCR = 0x%02x\n", nic_data.SCR);
- }
-
- err = register_netdev(dev);
- if (err)
- goto out2;
- return dev;
-
-out2:
- release_region(dev->base_addr, 3);
-out1:
- free_netdev(dev);
-out:
- return ERR_PTR(err);
-}
-
-/**********************************
- *
- * Read info from on-board EEPROM
- *
- * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
- */
-#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
-
-static unsigned short __init ReadAWord(struct net_device *dev, int from)
-{
- unsigned short data;
- int nbits;
-
- /* cs [__~~] SET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
-
- /* Send the 9-bit address from where we want to read the 16-bit word */
- for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
- if (from & 0x0100) { /* bit set? */
- /* cs [~~~~] SEND 1 */
- /* di [~~~~] */
- /* sck [_~~_] */
- sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
- }
- else {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- }
- }
-
- /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
- for (data = 0, nbits = 16; nbits > 0; --nbits) {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
- }
- /* cs [____] RESET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
-
- return data;
-}
-
-static int __init read_eeprom(struct net_device *dev)
-{
- unsigned short wrd;
-
- /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */
- wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */
- if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[0] = wrd & 0xff;
- nic_data.NodeID[1] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */
- if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[2] = wrd & 0xff;
- nic_data.NodeID[3] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */
- nic_data.NodeID[4] = wrd & 0xff;
- nic_data.NodeID[5] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */
- nic_data.RAM_Size = (wrd >> 8);
-
- wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */
- nic_data.Model = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
- nic_data.Media = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
- nic_data.SCR = (wrd >> 8);
-
- return 0; /* no errors */
-}
-
-/******************************************************************************
- *
- * Loadable module skeleton
- *
- */
-#ifdef MODULE
-static struct net_device *de620_dev;
-
-int __init init_module(void)
-{
- de620_dev = de620_probe(-1);
- if (IS_ERR(de620_dev))
- return PTR_ERR(de620_dev);
- return 0;
-}
-
-void cleanup_module(void)
-{
- unregister_netdev(de620_dev);
- release_region(de620_dev->base_addr, 3);
- free_netdev(de620_dev);
-}
-#endif /* MODULE */
-MODULE_LICENSE("GPL");
-
-
-/*
- * (add '-DMODULE' when compiling as loadable module)
- *
- * compile-command:
- * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \
- * -fomit-frame-pointer -m486 \
- * -I/usr/src/linux/include -I../../net/inet -c de620.c
-*/
-/*
- * Local variables:
- * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
- * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
- * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
- * End:
- */
diff --git a/drivers/net/de620.h b/drivers/net/de620.h
deleted file mode 100644
index e8d9a88f4cb..00000000000
--- a/drivers/net/de620.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*********************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * *
- *********************************************************/
-
-/* DE-620's CMD port Command */
-#define CS0 0x08 /* 1->0 command strobe */
-#define ICEN 0x04 /* 0=enable DL3520 host interface */
-#define DS0 0x02 /* 1->0 data strobe 0 */
-#define DS1 0x01 /* 1->0 data strobe 1 */
-
-#define WDIR 0x20 /* general 0=read 1=write */
-#define RDIR 0x00 /* (not 100% confirm ) */
-#define PS2WDIR 0x00 /* ps/2 mode 1=read, 0=write */
-#define PS2RDIR 0x20
-
-#define IRQEN 0x10 /* 1 = enable printer IRQ line */
-#define SELECTIN 0x08 /* 1 = select printer */
-#define INITP 0x04 /* 0 = initial printer */
-#define AUTOFEED 0x02 /* 1 = printer auto form feed */
-#define STROBE 0x01 /* 0->1 data strobe */
-
-#define RESET 0x08
-#define NIS0 0x20 /* 0 = BNC, 1 = UTP */
-#define NCTL0 0x10
-
-/* DE-620 DIC Command */
-#define W_DUMMY 0x00 /* DIC reserved command */
-#define W_CR 0x20 /* DIC write command register */
-#define W_NPR 0x40 /* DIC write Next Page Register */
-#define W_TBR 0x60 /* DIC write Tx Byte Count 1 reg */
-#define W_RSA 0x80 /* DIC write Remote Start Addr 1 */
-
-/* DE-620's STAT port bits 7-4 */
-#define EMPTY 0x80 /* 1 = receive buffer empty */
-#define INTLEVEL 0x40 /* 1 = interrupt level is high */
-#define TXBF1 0x20 /* 1 = transmit buffer 1 is in use */
-#define TXBF0 0x10 /* 1 = transmit buffer 0 is in use */
-#define READY 0x08 /* 1 = h/w ready to accept cmd/data */
-
-/* IDC 1 Command */
-#define W_RSA1 0xa0 /* write remote start address 1 */
-#define W_RSA0 0xa1 /* write remote start address 0 */
-#define W_NPRF 0xa2 /* write next page register NPR15-NPR8 */
-#define W_DFR 0xa3 /* write delay factor register */
-#define W_CPR 0xa4 /* write current page register */
-#define W_SPR 0xa5 /* write start page register */
-#define W_EPR 0xa6 /* write end page register */
-#define W_SCR 0xa7 /* write system configuration register */
-#define W_TCR 0xa8 /* write Transceiver Configuration reg */
-#define W_EIP 0xa9 /* write EEPM Interface port */
-#define W_PAR0 0xaa /* write physical address register 0 */
-#define W_PAR1 0xab /* write physical address register 1 */
-#define W_PAR2 0xac /* write physical address register 2 */
-#define W_PAR3 0xad /* write physical address register 3 */
-#define W_PAR4 0xae /* write physical address register 4 */
-#define W_PAR5 0xaf /* write physical address register 5 */
-
-/* IDC 2 Command */
-#define R_STS 0xc0 /* read status register */
-#define R_CPR 0xc1 /* read current page register */
-#define R_BPR 0xc2 /* read boundary page register */
-#define R_TDR 0xc3 /* read time domain reflectometry reg */
-
-/* STATUS Register */
-#define EEDI 0x80 /* EEPM DO pin */
-#define TXSUC 0x40 /* tx success */
-#define T16 0x20 /* tx fail 16 times */
-#define TS1 0x40 /* 0=Tx success, 1=T16 */
-#define TS0 0x20 /* 0=Tx success, 1=T16 */
-#define RXGOOD 0x10 /* rx a good packet */
-#define RXCRC 0x08 /* rx a CRC error packet */
-#define RXSHORT 0x04 /* rx a short packet */
-#define COLS 0x02 /* coaxial collision status */
-#define LNKS 0x01 /* UTP link status */
-
-/* Command Register */
-#define CLEAR 0x10 /* reset part of hardware */
-#define NOPER 0x08 /* No Operation */
-#define RNOP 0x08
-#define RRA 0x06 /* After RR then auto-advance NPR & BPR(=NPR-1) */
-#define RRN 0x04 /* Normal Remote Read mode */
-#define RW1 0x02 /* Remote Write tx buffer 1 ( page 6 - 11 ) */
-#define RW0 0x00 /* Remote Write tx buffer 0 ( page 0 - 5 ) */
-#define TXEN 0x01 /* 0->1 tx enable */
-
-/* System Configuration Register */
-#define TESTON 0x80 /* test host data transfer reliability */
-#define SLEEP 0x40 /* sleep mode */
-#if 0
-#define FASTMODE 0x04 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x02 /* byte mode */
-#else
-#define FASTMODE 0x20 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x10 /* byte mode */
-#endif
-#define NIBBLEMODE 0x00 /* nibble mode */
-#define IRQINV 0x08 /* turn off IRQ line inverter */
-#define IRQNML 0x00 /* turn on IRQ line inverter */
-#define INTON 0x04
-#define AUTOFFSET 0x02 /* auto shift address to TPR+12 */
-#define AUTOTX 0x01 /* auto tx when leave RW mode */
-
-/* Transceiver Configuration Register */
-#define JABBER 0x80 /* generate jabber condition */
-#define TXSUCINT 0x40 /* enable tx success interrupt */
-#define T16INT 0x20 /* enable T16 interrupt */
-#define RXERRPKT 0x10 /* accept CRC error or short packet */
-#define EXTERNALB2 0x0C /* external loopback 2 */
-#define EXTERNALB1 0x08 /* external loopback 1 */
-#define INTERNALB 0x04 /* internal loopback */
-#define NMLOPERATE 0x00 /* normal operation */
-#define RXPBM 0x03 /* rx physical, broadcast, multicast */
-#define RXPB 0x02 /* rx physical, broadcast */
-#define RXALL 0x01 /* rx all packet */
-#define RXOFF 0x00 /* rx disable */
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
deleted file mode 100644
index ace39ec0a36..00000000000
--- a/drivers/net/depca.c
+++ /dev/null
@@ -1,2095 +0,0 @@
-/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
-
- Written 1994, 1995 by David C. Davies.
-
-
- Copyright 1994 David C. Davies
- and
- United States Government
- (as represented by the Director, National Security Agency).
-
- Copyright 1995 Digital Equipment Corporation.
-
-
- This software may be used and distributed according to the terms of
- the GNU General Public License, incorporated herein by reference.
-
- This driver is written for the Digital Equipment Corporation series
- of DEPCA and EtherWORKS ethernet cards:
-
- DEPCA (the original)
- DE100
- DE101
- DE200 Turbo
- DE201 Turbo
- DE202 Turbo (TP BNC)
- DE210
- DE422 (EISA)
-
- The driver has been tested on DE100, DE200 and DE202 cards in a
- relatively busy network. The DE422 has been tested a little.
-
- This driver will NOT work for the DE203, DE204 and DE205 series of
- cards, since they have a new custom ASIC in place of the AMD LANCE
- chip. See the 'ewrk3.c' driver in the Linux source tree for running
- those cards.
-
- I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
- a DECstation 5000/200.
-
- The author may be reached at davies@maniac.ultranet.com
-
- =========================================================================
-
- The driver was originally based on the 'lance.c' driver from Donald
- Becker which is included with the standard driver distribution for
- linux. V0.4 is a complete re-write with only the kernel interface
- remaining from the original code.
-
- 1) Lance.c code in /linux/drivers/net/
- 2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
- AMD, 1992 [(800) 222-9323].
- 3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
- AMD, Pub. #17881, May 1993.
- 4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
- AMD, Pub. #16907, May 1992
- 5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
- 6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
- 7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
- Digital Equipment Corporation, 1989
- 8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
-
-
- Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
- driver.
-
- The original DEPCA card requires that the ethernet ROM address counter
- be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
- only done when a 0x08 is read as the first address octet (to minimise
- the chances of writing over some other hardware's I/O register). The
- NICSR accesses have been changed to byte accesses for all the cards
- supported by this driver, since there is only one useful bit in the MSB
- (remote boot timeout) and it is not used. Also, there is a maximum of
- only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
- help debugging all this (and holding my feet to the fire until I got it
- right).
-
- The DE200 series boards have on-board 64kB RAM for use as a shared
- memory network buffer. Only the DE100 cards make use of a 2kB buffer
- mode which has not been implemented in this driver (only the 32kB and
- 64kB modes are supported [16kB/48kB for the original DEPCA]).
-
- At the most only 2 DEPCA cards can be supported on the ISA bus because
- there is only provision for two I/O base addresses on each card (0x300
- and 0x200). The I/O address is detected by searching for a byte sequence
- in the Ethernet station address PROM at the expected I/O address for the
- Ethernet PROM. The shared memory base address is 'autoprobed' by
- looking for the self test PROM and detecting the card name. When a
- second DEPCA is detected, information is placed in the base_addr
- variable of the next device structure (which is created if necessary),
- thus enabling ethif_probe initialization for the device. More than 2
- EISA cards can be supported, but care will be needed assigning the
- shared memory to ensure that each slot has the correct IRQ, I/O address
- and shared memory address assigned.
-
- ************************************************************************
-
- NOTE: If you are using two ISA DEPCAs, it is important that you assign
- the base memory addresses correctly. The driver autoprobes I/O 0x300
- then 0x200. The base memory address for the first device must be less
- than that of the second so that the auto probe will correctly assign the
- I/O and memory addresses on the same card. I can't think of a way to do
- this unambiguously at the moment, since there is nothing on the cards to
- tie I/O and memory information together.
-
- I am unable to test 2 cards together for now, so this code is
- unchecked. All reports, good or bad, are welcome.
-
- ************************************************************************
-
- The board IRQ setting must be at an unused IRQ which is auto-probed
- using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
- {2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
- really IRQ9 in machines with 16 IRQ lines.
-
- No 16MB memory limitation should exist with this driver as DMA is not
- used and the common memory area is in low memory on the network card (my
- current system has 20MB and I've not had problems yet).
-
- The ability to load this driver as a loadable module has been added. To
- utilise this ability, you have to do <8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy depca.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) if you wish, edit the source code near line 1530 to reflect the I/O
- address and IRQ you're using (see also 5).
- 3) compile depca.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the depca configuration turned off and reboot.
- 5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
- [Alan Cox: Changed the code to allow command line irq/io assignments]
- [Dave Davies: Changed the code to allow command line mem/name
- assignments]
- 6) run the net startup bits for your eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod depca'.
-
- To assign a base memory address for the shared memory when running as a
- loadable module, see 5 above. To include the adapter name (if you have
- no PROM but know the card name) also see 5 above. Note that this last
- option will not work with kernel built-in depca's.
-
- The shared memory assignment for a loadable module makes sense to avoid
- the 'memory autoprobe' picking the wrong shared memory (for the case of
- 2 depca's in a PC).
-
- ************************************************************************
- Support for MCA EtherWORKS cards added 11-3-98.
- Verified to work with up to 2 DE212 cards in a system (although not
- fully stress-tested).
-
- Currently known bugs/limitations:
-
- Note: with the MCA stuff as a module, it trusts the MCA configuration,
- not the command line for IRQ and memory address. You can
- specify them if you want, but it will throw your values out.
- You still have to pass the IO address it was configured as
- though.
-
- ************************************************************************
- TO DO:
- ------
-
-
- Revision History
- ----------------
-
- Version Date Description
-
- 0.1 25-jan-94 Initial writing.
- 0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
- 0.3 1-feb-94 Added multiple DEPCA support.
- 0.31 4-feb-94 Added DE202 recognition.
- 0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
- 0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
- Add jabber packet fix from murf@perftech.com
- and becker@super.org
- 0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
- 0.35 8-mar-94 Added DE201 recognition. Tidied up.
- 0.351 30-apr-94 Added EISA support. Added DE422 recognition.
- 0.36 16-may-94 DE422 fix released.
- 0.37 22-jul-94 Added MODULE support
- 0.38 15-aug-94 Added DBR ROM switch in depca_close().
- Multi DEPCA bug fix.
- 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
- 0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
- 0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
- 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
- <stromain@alf.dec.com>
- 0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
- 0.385 3-apr-95 Fix a recognition bug reported by
- <ryan.niemi@lastfrontier.com>
- 0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
- 0.40 25-May-95 Rewrite for portability & updated.
- ALPHA support from <jestabro@amt.tay1.dec.com>
- 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
- suggestion by <heiko@colossus.escape.de>
- 0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable
- modules.
- Add 'adapter_name' for loadable modules when no PROM.
- Both above from a suggestion by
- <pchen@woodruffs121.residence.gatech.edu>.
- Add new multicasting code.
- 0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
- 0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
- 0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
- 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
- 0.44 1-Sep-97 Fix *_probe() to test check_region() first - bug
- reported by <mmogilvi@elbert.uccs.edu>
- 0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards
- by <tymm@computer.org>
- 0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. <tymm@computer.org>
- 0.5 14-Nov-98 Re-spin for 2.1.x kernels.
- 0.51 27-Jun-99 Correct received packet length for CRC from
- report by <worm@dkik.dk>
- 0.52 16-Oct-00 Fixes for 2.3 io memory accesses
- Fix show-stopper (ints left masked) in depca_interrupt
- by <peterd@pnd-pc.demon.co.uk>
- 0.53 12-Jan-01 Release resources on failure, bss tidbits
- by acme@conectiva.com.br
- 0.54 08-Nov-01 use library crc32 functions
- by Matt_Domsch@dell.com
- 0.55 01-Mar-03 Use EISA/sysfs framework <maz@wild-wind.fr.eu.org>
-
- =========================================================================
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/crc32.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/unistd.h>
-#include <linux/ctype.h>
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#ifdef CONFIG_MCA
-#include <linux/mca.h>
-#endif
-
-#ifdef CONFIG_EISA
-#include <linux/eisa.h>
-#endif
-
-#include "depca.h"
-
-static char version[] __initdata = "depca.c:v0.53 2001/1/12 davies@maniac.ultranet.com\n";
-
-#ifdef DEPCA_DEBUG
-static int depca_debug = DEPCA_DEBUG;
-#else
-static int depca_debug = 1;
-#endif
-
-#define DEPCA_NDA 0xffe0 /* No Device Address */
-
-#define TX_TIMEOUT (1*HZ)
-
-/*
-** Ethernet PROM defines
-*/
-#define PROBE_LENGTH 32
-#define ETH_PROM_SIG 0xAA5500FFUL
-
-/*
-** Set the number of Tx and Rx buffers. Ensure that the memory requested
-** here is <= to the amount of shared memory set up by the board switches.
-** The number of descriptors MUST BE A POWER OF 2.
-**
-** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
-*/
-#define NUM_RX_DESC 8 /* Number of RX descriptors */
-#define NUM_TX_DESC 8 /* Number of TX descriptors */
-#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
-#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
-
-/*
-** EISA bus defines
-*/
-#define DEPCA_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
-
-/*
-** ISA Bus defines
-*/
-#define DEPCA_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0xe0000,0x00000}
-#define DEPCA_TOTAL_SIZE 0x10
-
-static struct {
- u_long iobase;
- struct platform_device *device;
-} depca_io_ports[] = {
- { 0x300, NULL },
- { 0x200, NULL },
- { 0 , NULL },
-};
-
-/*
-** Name <-> Adapter mapping
-*/
-#define DEPCA_SIGNATURE {"DEPCA",\
- "DE100","DE101",\
- "DE200","DE201","DE202",\
- "DE210","DE212",\
- "DE422",\
- ""}
-
-static char* __initdata depca_signature[] = DEPCA_SIGNATURE;
-
-enum depca_type {
- DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
-};
-
-static char depca_string[] = "depca";
-
-static int depca_device_remove (struct device *device);
-
-#ifdef CONFIG_EISA
-static struct eisa_device_id depca_eisa_ids[] = {
- { "DEC4220", de422 },
- { "" }
-};
-MODULE_DEVICE_TABLE(eisa, depca_eisa_ids);
-
-static int depca_eisa_probe (struct device *device);
-
-static struct eisa_driver depca_eisa_driver = {
- .id_table = depca_eisa_ids,
- .driver = {
- .name = depca_string,
- .probe = depca_eisa_probe,
- .remove = __devexit_p (depca_device_remove)
- }
-};
-#endif
-
-#ifdef CONFIG_MCA
-/*
-** Adapter ID for the MCA EtherWORKS DE210/212 adapter
-*/
-#define DE210_ID 0x628d
-#define DE212_ID 0x6def
-
-static short depca_mca_adapter_ids[] = {
- DE210_ID,
- DE212_ID,
- 0x0000
-};
-
-static char *depca_mca_adapter_name[] = {
- "DEC EtherWORKS MC Adapter (DE210)",
- "DEC EtherWORKS MC Adapter (DE212)",
- NULL
-};
-
-static enum depca_type depca_mca_adapter_type[] = {
- de210,
- de212,
- 0
-};
-
-static int depca_mca_probe (struct device *);
-
-static struct mca_driver depca_mca_driver = {
- .id_table = depca_mca_adapter_ids,
- .driver = {
- .name = depca_string,
- .bus = &mca_bus_type,
- .probe = depca_mca_probe,
- .remove = __devexit_p(depca_device_remove),
- },
-};
-#endif
-
-static int depca_isa_probe (struct platform_device *);
-
-static int __devexit depca_isa_remove(struct platform_device *pdev)
-{
- return depca_device_remove(&pdev->dev);
-}
-
-static struct platform_driver depca_isa_driver = {
- .probe = depca_isa_probe,
- .remove = __devexit_p(depca_isa_remove),
- .driver = {
- .name = depca_string,
- },
-};
-
-/*
-** Miscellaneous info...
-*/
-#define DEPCA_STRLEN 16
-
-/*
-** Memory Alignment. Each descriptor is 4 longwords long. To force a
-** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
-** DESC_ALIGN. DEPCA_ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry.
-*/
-#define DEPCA_ALIGN4 ((u_long)4 - 1) /* 1 longword align */
-#define DEPCA_ALIGN8 ((u_long)8 - 1) /* 2 longword (quadword) align */
-#define DEPCA_ALIGN DEPCA_ALIGN8 /* Keep the LANCE happy... */
-
-/*
-** The DEPCA Rx and Tx ring descriptors.
-*/
-struct depca_rx_desc {
- volatile s32 base;
- s16 buf_length; /* This length is negative 2's complement! */
- s16 msg_length; /* This length is "normal". */
-};
-
-struct depca_tx_desc {
- volatile s32 base;
- s16 length; /* This length is negative 2's complement! */
- s16 misc; /* Errors and TDR info */
-};
-
-#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
- to LANCE memory address space */
-
-/*
-** The Lance initialization block, described in databook, in common memory.
-*/
-struct depca_init {
- u16 mode; /* Mode register */
- u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
- u8 mcast_table[8]; /* Multicast Hash Table. */
- u32 rx_ring; /* Rx ring base pointer & ring length */
- u32 tx_ring; /* Tx ring base pointer & ring length */
-};
-
-#define DEPCA_PKT_STAT_SZ 16
-#define DEPCA_PKT_BIN_SZ 128 /* Should be >=100 unless you
- increase DEPCA_PKT_STAT_SZ */
-struct depca_private {
- char adapter_name[DEPCA_STRLEN]; /* /proc/ioports string */
- enum depca_type adapter; /* Adapter type */
- enum {
- DEPCA_BUS_MCA = 1,
- DEPCA_BUS_ISA,
- DEPCA_BUS_EISA,
- } depca_bus; /* type of bus */
- struct depca_init init_block; /* Shadow Initialization block */
-/* CPU address space fields */
- struct depca_rx_desc __iomem *rx_ring; /* Pointer to start of RX descriptor ring */
- struct depca_tx_desc __iomem *tx_ring; /* Pointer to start of TX descriptor ring */
- void __iomem *rx_buff[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */
- void __iomem *tx_buff[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */
- void __iomem *sh_mem; /* CPU mapped virt address of device RAM */
- u_long mem_start; /* Bus address of device RAM (before remap) */
- u_long mem_len; /* device memory size */
-/* Device address space fields */
- u_long device_ram_start; /* Start of RAM in device addr space */
-/* Offsets used in both address spaces */
- u_long rx_ring_offset; /* Offset from start of RAM to rx_ring */
- u_long tx_ring_offset; /* Offset from start of RAM to tx_ring */
- u_long buffs_offset; /* LANCE Rx and Tx buffers start address. */
-/* Kernel-only (not device) fields */
- int rx_new, tx_new; /* The next free ring entry */
- int rx_old, tx_old; /* The ring entries to be free()ed. */
- spinlock_t lock;
- struct { /* Private stats counters */
- u32 bins[DEPCA_PKT_STAT_SZ];
- u32 unicast;
- u32 multicast;
- u32 broadcast;
- u32 excessive_collisions;
- u32 tx_underruns;
- u32 excessive_underruns;
- } pktStats;
- int txRingMask; /* TX ring mask */
- int rxRingMask; /* RX ring mask */
- s32 rx_rlen; /* log2(rxRingMask+1) for the descriptors */
- s32 tx_rlen; /* log2(txRingMask+1) for the descriptors */
-};
-
-/*
-** The transmit ring full condition is described by the tx_old and tx_new
-** pointers by:
-** tx_old = tx_new Empty ring
-** tx_old = tx_new+1 Full ring
-** tx_old+txRingMask = tx_new Full ring (wrapped condition)
-*/
-#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
- lp->tx_old+lp->txRingMask-lp->tx_new:\
- lp->tx_old -lp->tx_new-1)
-
-/*
-** Public Functions
-*/
-static int depca_open(struct net_device *dev);
-static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t depca_interrupt(int irq, void *dev_id);
-static int depca_close(struct net_device *dev);
-static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void depca_tx_timeout(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-
-/*
-** Private functions
-*/
-static void depca_init_ring(struct net_device *dev);
-static int depca_rx(struct net_device *dev);
-static int depca_tx(struct net_device *dev);
-
-static void LoadCSRs(struct net_device *dev);
-static int InitRestartDepca(struct net_device *dev);
-static int DepcaSignature(char *name, u_long paddr);
-static int DevicePresent(u_long ioaddr);
-static int get_hw_addr(struct net_device *dev);
-static void SetMulticastFilter(struct net_device *dev);
-static int load_packet(struct net_device *dev, struct sk_buff *skb);
-static void depca_dbg_open(struct net_device *dev);
-
-static u_char de1xx_irq[] __initdata = { 2, 3, 4, 5, 7, 9, 0 };
-static u_char de2xx_irq[] __initdata = { 5, 9, 10, 11, 15, 0 };
-static u_char de422_irq[] __initdata = { 5, 9, 10, 11, 0 };
-static u_char *depca_irq;
-
-static int irq;
-static int io;
-static char *adapter_name;
-static int mem; /* For loadable module assignment
- use insmod mem=0x????? .... */
-module_param (irq, int, 0);
-module_param (io, int, 0);
-module_param (adapter_name, charp, 0);
-module_param (mem, int, 0);
-MODULE_PARM_DESC(irq, "DEPCA IRQ number");
-MODULE_PARM_DESC(io, "DEPCA I/O base address");
-MODULE_PARM_DESC(adapter_name, "DEPCA adapter name");
-MODULE_PARM_DESC(mem, "DEPCA shared memory address");
-MODULE_LICENSE("GPL");
-
-/*
-** Miscellaneous defines...
-*/
-#define STOP_DEPCA \
- outw(CSR0, DEPCA_ADDR);\
- outw(STOP, DEPCA_DATA)
-
-static int __init depca_hw_init (struct net_device *dev, struct device *device)
-{
- struct depca_private *lp;
- int i, j, offset, netRAM, mem_len, status = 0;
- s16 nicsr;
- u_long ioaddr;
- u_long mem_start;
- DECLARE_MAC_BUF(mac);
-
- /*
- * We are now supposed to enter this function with the
- * following fields filled with proper values :
- *
- * dev->base_addr
- * lp->mem_start
- * lp->depca_bus
- * lp->adapter
- *
- * dev->irq can be set if known from device configuration (on
- * MCA or EISA) or module option. Otherwise, it will be auto
- * detected.
- */
-
- ioaddr = dev->base_addr;
-
- STOP_DEPCA;
-
- nicsr = inb(DEPCA_NICSR);
- nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
- outb(nicsr, DEPCA_NICSR);
-
- if (inw(DEPCA_DATA) != STOP) {
- return -ENXIO;
- }
-
- lp = (struct depca_private *) dev->priv;
- mem_start = lp->mem_start;
-
- if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
- return -ENXIO;
-
- printk ("%s: %s at 0x%04lx",
- device->bus_id, depca_signature[lp->adapter], ioaddr);
-
- switch (lp->depca_bus) {
-#ifdef CONFIG_MCA
- case DEPCA_BUS_MCA:
- printk(" (MCA slot %d)", to_mca_device(device)->slot + 1);
- break;
-#endif
-
-#ifdef CONFIG_EISA
- case DEPCA_BUS_EISA:
- printk(" (EISA slot %d)", to_eisa_device(device)->slot);
- break;
-#endif
-
- case DEPCA_BUS_ISA:
- break;
-
- default:
- printk("Unknown DEPCA bus %d\n", lp->depca_bus);
- return -ENXIO;
- }
-
- printk(", h/w address ");
- status = get_hw_addr(dev);
- printk("%s", print_mac(mac, dev->dev_addr));
- if (status != 0) {
- printk(" which has an Ethernet PROM CRC error.\n");
- return -ENXIO;
- }
-
- /* Set up the maximum amount of network RAM(kB) */
- netRAM = ((lp->adapter != DEPCA) ? 64 : 48);
- if ((nicsr & _128KB) && (lp->adapter == de422))
- netRAM = 128;
-
- /* Shared Memory Base Address */
- if (nicsr & BUF) {
- nicsr &= ~BS; /* DEPCA RAM in top 32k */
- netRAM -= 32;
-
- /* Only EISA/ISA needs start address to be re-computed */
- if (lp->depca_bus != DEPCA_BUS_MCA)
- mem_start += 0x8000;
- }
-
- if ((mem_len = (NUM_RX_DESC * (sizeof(struct depca_rx_desc) + RX_BUFF_SZ) + NUM_TX_DESC * (sizeof(struct depca_tx_desc) + TX_BUFF_SZ) + sizeof(struct depca_init)))
- > (netRAM << 10)) {
- printk(",\n requests %dkB RAM: only %dkB is available!\n", (mem_len >> 10), netRAM);
- return -ENXIO;
- }
-
- printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start);
-
- /* Enable the shadow RAM. */
- if (lp->adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- spin_lock_init(&lp->lock);
- sprintf(lp->adapter_name, "%s (%s)",
- depca_signature[lp->adapter], device->bus_id);
- status = -EBUSY;
-
- /* Initialisation Block */
- if (!request_mem_region (mem_start, mem_len, lp->adapter_name)) {
- printk(KERN_ERR "depca: cannot request ISA memory, aborting\n");
- goto out_priv;
- }
-
- status = -EIO;
- lp->sh_mem = ioremap(mem_start, mem_len);
- if (lp->sh_mem == NULL) {
- printk(KERN_ERR "depca: cannot remap ISA memory, aborting\n");
- goto out1;
- }
-
- lp->mem_start = mem_start;
- lp->mem_len = mem_len;
- lp->device_ram_start = mem_start & LA_MASK;
-
- offset = 0;
- offset += sizeof(struct depca_init);
-
- /* Tx & Rx descriptors (aligned to a quadword boundary) */
- offset = (offset + DEPCA_ALIGN) & ~DEPCA_ALIGN;
- lp->rx_ring = (struct depca_rx_desc __iomem *) (lp->sh_mem + offset);
- lp->rx_ring_offset = offset;
-
- offset += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
- lp->tx_ring = (struct depca_tx_desc __iomem *) (lp->sh_mem + offset);
- lp->tx_ring_offset = offset;
-
- offset += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
-
- lp->buffs_offset = offset;
-
- /* Finish initialising the ring information. */
- lp->rxRingMask = NUM_RX_DESC - 1;
- lp->txRingMask = NUM_TX_DESC - 1;
-
- /* Calculate Tx/Rx RLEN size for the descriptors. */
- for (i = 0, j = lp->rxRingMask; j > 0; i++) {
- j >>= 1;
- }
- lp->rx_rlen = (s32) (i << 29);
- for (i = 0, j = lp->txRingMask; j > 0; i++) {
- j >>= 1;
- }
- lp->tx_rlen = (s32) (i << 29);
-
- /* Load the initialisation block */
- depca_init_ring(dev);
-
- /* Initialise the control and status registers */
- LoadCSRs(dev);
-
- /* Enable DEPCA board interrupts for autoprobing */
- nicsr = ((nicsr & ~IM) | IEN);
- outb(nicsr, DEPCA_NICSR);
-
- /* To auto-IRQ we enable the initialization-done and DMA err,
- interrupts. For now we will always get a DMA error. */
- if (dev->irq < 2) {
- unsigned char irqnum;
- unsigned long irq_mask, delay;
-
- irq_mask = probe_irq_on();
-
- /* Assign the correct irq list */
- switch (lp->adapter) {
- case DEPCA:
- case de100:
- case de101:
- depca_irq = de1xx_irq;
- break;
- case de200:
- case de201:
- case de202:
- case de210:
- case de212:
- depca_irq = de2xx_irq;
- break;
- case de422:
- depca_irq = de422_irq;
- break;
-
- default:
- break; /* Not reached */
- }
-
- /* Trigger an initialization just for the interrupt. */
- outw(INEA | INIT, DEPCA_DATA);
-
- delay = jiffies + HZ/50;
- while (time_before(jiffies, delay))
- yield();
-
- irqnum = probe_irq_off(irq_mask);
-
- status = -ENXIO;
- if (!irqnum) {
- printk(" and failed to detect IRQ line.\n");
- goto out2;
- } else {
- for (dev->irq = 0, i = 0; (depca_irq[i]) && (!dev->irq); i++)
- if (irqnum == depca_irq[i]) {
- dev->irq = irqnum;
- printk(" and uses IRQ%d.\n", dev->irq);
- }
-
- if (!dev->irq) {
- printk(" but incorrect IRQ line detected.\n");
- goto out2;
- }
- }
- } else {
- printk(" and assigned IRQ%d.\n", dev->irq);
- }
-
- if (depca_debug > 1) {
- printk(version);
- }
-
- /* The DEPCA-specific entries in the device structure. */
- dev->open = &depca_open;
- dev->hard_start_xmit = &depca_start_xmit;
- dev->stop = &depca_close;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &depca_ioctl;
- dev->tx_timeout = depca_tx_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
-
- dev->mem_start = 0;
-
- device->driver_data = dev;
- SET_NETDEV_DEV (dev, device);
-
- status = register_netdev(dev);
- if (status == 0)
- return 0;
-out2:
- iounmap(lp->sh_mem);
-out1:
- release_mem_region (mem_start, mem_len);
-out_priv:
- return status;
-}
-
-
-static int depca_open(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- s16 nicsr;
- int status = 0;
-
- STOP_DEPCA;
- nicsr = inb(DEPCA_NICSR);
-
- /* Make sure the shadow RAM is enabled */
- if (lp->adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- /* Re-initialize the DEPCA... */
- depca_init_ring(dev);
- LoadCSRs(dev);
-
- depca_dbg_open(dev);
-
- if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name, dev)) {
- printk("depca_open(): Requested IRQ%d is busy\n", dev->irq);
- status = -EAGAIN;
- } else {
-
- /* Enable DEPCA board interrupts and turn off LED */
- nicsr = ((nicsr & ~IM & ~LED) | IEN);
- outb(nicsr, DEPCA_NICSR);
- outw(CSR0, DEPCA_ADDR);
-
- netif_start_queue(dev);
-
- status = InitRestartDepca(dev);
-
- if (depca_debug > 1) {
- printk("CSR0: 0x%4.4x\n", inw(DEPCA_DATA));
- printk("nicsr: 0x%02x\n", inb(DEPCA_NICSR));
- }
- }
- return status;
-}
-
-/* Initialize the lance Rx and Tx descriptor rings. */
-static void depca_init_ring(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_int i;
- u_long offset;
-
- /* Lock out other processes whilst setting up the hardware */
- netif_stop_queue(dev);
-
- lp->rx_new = lp->tx_new = 0;
- lp->rx_old = lp->tx_old = 0;
-
- /* Initialize the base address and length of each buffer in the ring */
- for (i = 0; i <= lp->rxRingMask; i++) {
- offset = lp->buffs_offset + i * RX_BUFF_SZ;
- writel((lp->device_ram_start + offset) | R_OWN, &lp->rx_ring[i].base);
- writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length);
- lp->rx_buff[i] = lp->sh_mem + offset;
- }
-
- for (i = 0; i <= lp->txRingMask; i++) {
- offset = lp->buffs_offset + (i + lp->rxRingMask + 1) * TX_BUFF_SZ;
- writel((lp->device_ram_start + offset) & 0x00ffffff, &lp->tx_ring[i].base);
- lp->tx_buff[i] = lp->sh_mem + offset;
- }
-
- /* Set up the initialization block */
- lp->init_block.rx_ring = (lp->device_ram_start + lp->rx_ring_offset) | lp->rx_rlen;
- lp->init_block.tx_ring = (lp->device_ram_start + lp->tx_ring_offset) | lp->tx_rlen;
-
- SetMulticastFilter(dev);
-
- for (i = 0; i < ETH_ALEN; i++) {
- lp->init_block.phys_addr[i] = dev->dev_addr[i];
- }
-
- lp->init_block.mode = 0x0000; /* Enable the Tx and Rx */
-}
-
-
-static void depca_tx_timeout(struct net_device *dev)
-{
- u_long ioaddr = dev->base_addr;
-
- printk("%s: transmit timed out, status %04x, resetting.\n", dev->name, inw(DEPCA_DATA));
-
- STOP_DEPCA;
- depca_init_ring(dev);
- LoadCSRs(dev);
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
- InitRestartDepca(dev);
-}
-
-
-/*
-** Writes a socket buffer to TX descriptor ring and starts transmission
-*/
-static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- int status = 0;
-
- /* Transmitter timeout, serious problems. */
- if (skb->len < 1)
- goto out;
-
- if (skb_padto(skb, ETH_ZLEN))
- goto out;
-
- netif_stop_queue(dev);
-
- if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */
- status = load_packet(dev, skb);
-
- if (!status) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
-
- dev->trans_start = jiffies;
- dev_kfree_skb(skb);
- }
- if (TX_BUFFS_AVAIL)
- netif_start_queue(dev);
- } else
- status = -1;
-
- out:
- return status;
-}
-
-/*
-** The DEPCA interrupt handler.
-*/
-static irqreturn_t depca_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct depca_private *lp;
- s16 csr0, nicsr;
- u_long ioaddr;
-
- if (dev == NULL) {
- printk("depca_interrupt(): irq %d for unknown device.\n", irq);
- return IRQ_NONE;
- }
-
- lp = (struct depca_private *) dev->priv;
- ioaddr = dev->base_addr;
-
- spin_lock(&lp->lock);
-
- /* mask the DEPCA board interrupts and turn on the LED */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= (IM | LED);
- outb(nicsr, DEPCA_NICSR);
-
- outw(CSR0, DEPCA_ADDR);
- csr0 = inw(DEPCA_DATA);
-
- /* Acknowledge all of the current interrupt sources ASAP. */
- outw(csr0 & INTE, DEPCA_DATA);
-
- if (csr0 & RINT) /* Rx interrupt (packet arrived) */
- depca_rx(dev);
-
- if (csr0 & TINT) /* Tx interrupt (packet sent) */
- depca_tx(dev);
-
- /* Any resources available? */
- if ((TX_BUFFS_AVAIL >= 0) && netif_queue_stopped(dev)) {
- netif_wake_queue(dev);
- }
-
- /* Unmask the DEPCA board interrupts and turn off the LED */
- nicsr = (nicsr & ~IM & ~LED);
- outb(nicsr, DEPCA_NICSR);
-
- spin_unlock(&lp->lock);
- return IRQ_HANDLED;
-}
-
-/* Called with lp->lock held */
-static int depca_rx(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- int i, entry;
- s32 status;
-
- for (entry = lp->rx_new; !(readl(&lp->rx_ring[entry].base) & R_OWN); entry = lp->rx_new) {
- status = readl(&lp->rx_ring[entry].base) >> 16;
- if (status & R_STP) { /* Remember start of frame */
- lp->rx_old = entry;
- }
- if (status & R_ENP) { /* Valid frame status */
- if (status & R_ERR) { /* There was an error. */
- dev->stats.rx_errors++; /* Update the error stats. */
- if (status & R_FRAM)
- dev->stats.rx_frame_errors++;
- if (status & R_OFLO)
- dev->stats.rx_over_errors++;
- if (status & R_CRC)
- dev->stats.rx_crc_errors++;
- if (status & R_BUFF)
- dev->stats.rx_fifo_errors++;
- } else {
- short len, pkt_len = readw(&lp->rx_ring[entry].msg_length) - 4;
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len + 2);
- if (skb != NULL) {
- unsigned char *buf;
- skb_reserve(skb, 2); /* 16 byte align the IP header */
- buf = skb_put(skb, pkt_len);
- if (entry < lp->rx_old) { /* Wrapped buffer */
- len = (lp->rxRingMask - lp->rx_old + 1) * RX_BUFF_SZ;
- memcpy_fromio(buf, lp->rx_buff[lp->rx_old], len);
- memcpy_fromio(buf + len, lp->rx_buff[0], pkt_len - len);
- } else { /* Linear buffer */
- memcpy_fromio(buf, lp->rx_buff[lp->rx_old], pkt_len);
- }
-
- /*
- ** Notify the upper protocol layers that there is another
- ** packet to handle
- */
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
-
- /*
- ** Update stats
- */
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- for (i = 1; i < DEPCA_PKT_STAT_SZ - 1; i++) {
- if (pkt_len < (i * DEPCA_PKT_BIN_SZ)) {
- lp->pktStats.bins[i]++;
- i = DEPCA_PKT_STAT_SZ;
- }
- }
- if (buf[0] & 0x01) { /* Multicast/Broadcast */
- if ((*(s16 *) & buf[0] == -1) && (*(s16 *) & buf[2] == -1) && (*(s16 *) & buf[4] == -1)) {
- lp->pktStats.broadcast++;
- } else {
- lp->pktStats.multicast++;
- }
- } else if ((*(s16 *) & buf[0] == *(s16 *) & dev->dev_addr[0]) && (*(s16 *) & buf[2] == *(s16 *) & dev->dev_addr[2]) && (*(s16 *) & buf[4] == *(s16 *) & dev->dev_addr[4])) {
- lp->pktStats.unicast++;
- }
-
- lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
- if (lp->pktStats.bins[0] == 0) { /* Reset counters */
- memset((char *) &lp->pktStats, 0, sizeof(lp->pktStats));
- }
- } else {
- printk("%s: Memory squeeze, deferring packet.\n", dev->name);
- dev->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- }
- /* Change buffer ownership for this last frame, back to the adapter */
- for (; lp->rx_old != entry; lp->rx_old = (++lp->rx_old) & lp->rxRingMask) {
- writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, &lp->rx_ring[lp->rx_old].base);
- }
- writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base);
- }
-
- /*
- ** Update entry information
- */
- lp->rx_new = (++lp->rx_new) & lp->rxRingMask;
- }
-
- return 0;
-}
-
-/*
-** Buffer sent - check for buffer errors.
-** Called with lp->lock held
-*/
-static int depca_tx(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- int entry;
- s32 status;
- u_long ioaddr = dev->base_addr;
-
- for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
- status = readl(&lp->tx_ring[entry].base) >> 16;
-
- if (status < 0) { /* Packet not yet sent! */
- break;
- } else if (status & T_ERR) { /* An error occurred. */
- status = readl(&lp->tx_ring[entry].misc);
- dev->stats.tx_errors++;
- if (status & TMD3_RTRY)
- dev->stats.tx_aborted_errors++;
- if (status & TMD3_LCAR)
- dev->stats.tx_carrier_errors++;
- if (status & TMD3_LCOL)
- dev->stats.tx_window_errors++;
- if (status & TMD3_UFLO)
- dev->stats.tx_fifo_errors++;
- if (status & (TMD3_BUFF | TMD3_UFLO)) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
- }
- } else if (status & (T_MORE | T_ONE)) {
- dev->stats.collisions++;
- } else {
- dev->stats.tx_packets++;
- }
-
- /* Update all the pointers */
- lp->tx_old = (++lp->tx_old) & lp->txRingMask;
- }
-
- return 0;
-}
-
-static int depca_close(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- s16 nicsr;
- u_long ioaddr = dev->base_addr;
-
- netif_stop_queue(dev);
-
- outw(CSR0, DEPCA_ADDR);
-
- if (depca_debug > 1) {
- printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name, inw(DEPCA_DATA));
- }
-
- /*
- ** We stop the DEPCA here -- it occasionally polls
- ** memory if we don't.
- */
- outw(STOP, DEPCA_DATA);
-
- /*
- ** Give back the ROM in case the user wants to go to DOS
- */
- if (lp->adapter != DEPCA) {
- nicsr = inb(DEPCA_NICSR);
- nicsr &= ~SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- /*
- ** Free the associated irq
- */
- free_irq(dev->irq, dev);
- return 0;
-}
-
-static void LoadCSRs(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
-
- outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
- outw((u16) lp->device_ram_start, DEPCA_DATA);
- outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
- outw((u16) (lp->device_ram_start >> 16), DEPCA_DATA);
- outw(CSR3, DEPCA_ADDR); /* ALE control */
- outw(ACON, DEPCA_DATA);
-
- outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
-
- return;
-}
-
-static int InitRestartDepca(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- int i, status = 0;
-
- /* Copy the shadow init_block to shared memory */
- memcpy_toio(lp->sh_mem, &lp->init_block, sizeof(struct depca_init));
-
- outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
- outw(INIT, DEPCA_DATA); /* initialize DEPCA */
-
- /* wait for lance to complete initialisation */
- for (i = 0; (i < 100) && !(inw(DEPCA_DATA) & IDON); i++);
-
- if (i != 100) {
- /* clear IDON by writing a "1", enable interrupts and start lance */
- outw(IDON | INEA | STRT, DEPCA_DATA);
- if (depca_debug > 2) {
- printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
- }
- } else {
- printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
- status = -1;
- }
-
- return status;
-}
-
-/*
-** Set or clear the multicast filter for this adaptor.
-*/
-static void set_multicast_list(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
-
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
-
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous mode */
- lp->init_block.mode |= PROM;
- } else {
- SetMulticastFilter(dev);
- lp->init_block.mode &= ~PROM; /* Unset promiscuous mode */
- }
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
-}
-
-/*
-** Calculate the hash code and update the logical address filter
-** from a list of ethernet multicast addresses.
-** Big endian crc one liner is mine, all mine, ha ha ha ha!
-** LANCE calculates its hash codes big endian.
-*/
-static void SetMulticastFilter(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- struct dev_mc_list *dmi = dev->mc_list;
- char *addrs;
- int i, j, bit, byte;
- u16 hashcode;
- u32 crc;
-
- if (dev->flags & IFF_ALLMULTI) { /* Set all multicast bits */
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) {
- lp->init_block.mcast_table[i] = (char) 0xff;
- }
- } else {
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) { /* Clear the multicast table */
- lp->init_block.mcast_table[i] = 0;
- }
- /* Add multicast addresses */
- for (i = 0; i < dev->mc_count; i++) { /* for each address in the list */
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
- if ((*addrs & 0x01) == 1) { /* multicast address? */
- crc = ether_crc(ETH_ALEN, addrs);
- hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */
- for (j = 0; j < 5; j++) { /* ... in reverse order. */
- hashcode = (hashcode << 1) | ((crc >>= 1) & 1);
- }
-
-
- byte = hashcode >> 3; /* bit[3-5] -> byte in filter */
- bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
- lp->init_block.mcast_table[byte] |= bit;
- }
- }
- }
-
- return;
-}
-
-static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
-{
- int status = 0;
-
- if (!request_region (ioaddr, DEPCA_TOTAL_SIZE, depca_string)) {
- status = -EBUSY;
- goto out;
- }
-
- if (DevicePresent(ioaddr)) {
- status = -ENODEV;
- goto out_release;
- }
-
- if (!(*devp = alloc_etherdev (sizeof (struct depca_private)))) {
- status = -ENOMEM;
- goto out_release;
- }
-
- return 0;
-
- out_release:
- release_region (ioaddr, DEPCA_TOTAL_SIZE);
- out:
- return status;
-}
-
-#ifdef CONFIG_MCA
-/*
-** Microchannel bus I/O device probe
-*/
-static int __init depca_mca_probe(struct device *device)
-{
- unsigned char pos[2];
- unsigned char where;
- unsigned long iobase, mem_start;
- int irq, err;
- struct mca_device *mdev = to_mca_device (device);
- struct net_device *dev;
- struct depca_private *lp;
-
- /*
- ** Search for the adapter. If an address has been given, search
- ** specifically for the card at that address. Otherwise find the
- ** first card in the system.
- */
-
- pos[0] = mca_device_read_stored_pos(mdev, 2);
- pos[1] = mca_device_read_stored_pos(mdev, 3);
-
- /*
- ** IO of card is handled by bits 1 and 2 of pos0.
- **
- ** bit2 bit1 IO
- ** 0 0 0x2c00
- ** 0 1 0x2c10
- ** 1 0 0x2c20
- ** 1 1 0x2c30
- */
- where = (pos[0] & 6) >> 1;
- iobase = 0x2c00 + (0x10 * where);
-
- /*
- ** Found the adapter we were looking for. Now start setting it up.
- **
- ** First work on decoding the IRQ. It's stored in the lower 4 bits
- ** of pos1. Bits are as follows (from the ADF file):
- **
- ** Bits
- ** 3 2 1 0 IRQ
- ** --------------------
- ** 0 0 1 0 5
- ** 0 0 0 1 9
- ** 0 1 0 0 10
- ** 1 0 0 0 11
- */
- where = pos[1] & 0x0f;
- switch (where) {
- case 1:
- irq = 9;
- break;
- case 2:
- irq = 5;
- break;
- case 4:
- irq = 10;
- break;
- case 8:
- irq = 11;
- break;
- default:
- printk("%s: mca_probe IRQ error. You should never get here (%d).\n", mdev->name, where);
- return -EINVAL;
- }
-
- /*
- ** Shared memory address of adapter is stored in bits 3-5 of pos0.
- ** They are mapped as follows:
- **
- ** Bit
- ** 5 4 3 Memory Addresses
- ** 0 0 0 C0000-CFFFF (64K)
- ** 1 0 0 C8000-CFFFF (32K)
- ** 0 0 1 D0000-DFFFF (64K)
- ** 1 0 1 D8000-DFFFF (32K)
- ** 0 1 0 E0000-EFFFF (64K)
- ** 1 1 0 E8000-EFFFF (32K)
- */
- where = (pos[0] & 0x18) >> 3;
- mem_start = 0xc0000 + (where * 0x10000);
- if (pos[0] & 0x20) {
- mem_start += 0x8000;
- }
-
- /* claim the slot */
- strncpy(mdev->name, depca_mca_adapter_name[mdev->index],
- sizeof(mdev->name));
- mca_device_set_claim(mdev, 1);
-
- /*
- ** Get everything allocated and initialized... (almost just
- ** like the ISA and EISA probes)
- */
- irq = mca_device_transform_irq(mdev, irq);
- iobase = mca_device_transform_ioport(mdev, iobase);
-
- if ((err = depca_common_init (iobase, &dev)))
- goto out_unclaim;
-
- dev->irq = irq;
- dev->base_addr = iobase;
- lp = dev->priv;
- lp->depca_bus = DEPCA_BUS_MCA;
- lp->adapter = depca_mca_adapter_type[mdev->index];
- lp->mem_start = mem_start;
-
- if ((err = depca_hw_init(dev, device)))
- goto out_free;
-
- return 0;
-
- out_free:
- free_netdev (dev);
- release_region (iobase, DEPCA_TOTAL_SIZE);
- out_unclaim:
- mca_device_set_claim(mdev, 0);
-
- return err;
-}
-#endif
-
-/*
-** ISA bus I/O device probe
-*/
-
-static void __init depca_platform_probe (void)
-{
- int i;
- struct platform_device *pldev;
-
- for (i = 0; depca_io_ports[i].iobase; i++) {
- depca_io_ports[i].device = NULL;
-
- /* if an address has been specified on the command
- * line, use it (if valid) */
- if (io && io != depca_io_ports[i].iobase)
- continue;
-
- pldev = platform_device_alloc(depca_string, i);
- if (!pldev)
- continue;
-
- pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
- depca_io_ports[i].device = pldev;
-
- if (platform_device_add(pldev)) {
- depca_io_ports[i].device = NULL;
- pldev->dev.platform_data = NULL;
- platform_device_put(pldev);
- continue;
- }
-
- if (!pldev->dev.driver) {
- /* The driver was not bound to this device, there was
- * no hardware at this address. Unregister it, as the
- * release fuction will take care of freeing the
- * allocated structure */
-
- depca_io_ports[i].device = NULL;
- pldev->dev.platform_data = NULL;
- platform_device_unregister (pldev);
- }
- }
-}
-
-static enum depca_type __init depca_shmem_probe (ulong *mem_start)
-{
- u_long mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
- enum depca_type adapter = unknown;
- int i;
-
- for (i = 0; mem_base[i]; i++) {
- *mem_start = mem ? mem : mem_base[i];
- adapter = DepcaSignature (adapter_name, *mem_start);
- if (adapter != unknown)
- break;
- }
-
- return adapter;
-}
-
-static int __init depca_isa_probe (struct platform_device *device)
-{
- struct net_device *dev;
- struct depca_private *lp;
- u_long ioaddr, mem_start = 0;
- enum depca_type adapter = unknown;
- int status = 0;
-
- ioaddr = (u_long) device->dev.platform_data;
-
- if ((status = depca_common_init (ioaddr, &dev)))
- goto out;
-
- adapter = depca_shmem_probe (&mem_start);
-
- if (adapter == unknown) {
- status = -ENODEV;
- goto out_free;
- }
-
- dev->base_addr = ioaddr;
- dev->irq = irq; /* Use whatever value the user gave
- * us, and 0 if he didn't. */
- lp = dev->priv;
- lp->depca_bus = DEPCA_BUS_ISA;
- lp->adapter = adapter;
- lp->mem_start = mem_start;
-
- if ((status = depca_hw_init(dev, &device->dev)))
- goto out_free;
-
- return 0;
-
- out_free:
- free_netdev (dev);
- release_region (ioaddr, DEPCA_TOTAL_SIZE);
- out:
- return status;
-}
-
-/*
-** EISA callbacks from sysfs.
-*/
-
-#ifdef CONFIG_EISA
-static int __init depca_eisa_probe (struct device *device)
-{
- struct eisa_device *edev;
- struct net_device *dev;
- struct depca_private *lp;
- u_long ioaddr, mem_start;
- int status = 0;
-
- edev = to_eisa_device (device);
- ioaddr = edev->base_addr + DEPCA_EISA_IO_PORTS;
-
- if ((status = depca_common_init (ioaddr, &dev)))
- goto out;
-
- /* It would have been nice to get card configuration from the
- * card. Unfortunately, this register is write-only (shares
- * it's address with the ethernet prom)... As we don't parse
- * the EISA configuration structures (yet... :-), just rely on
- * the ISA probing to sort it out... */
-
- depca_shmem_probe (&mem_start);
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
- lp = dev->priv;
- lp->depca_bus = DEPCA_BUS_EISA;
- lp->adapter = edev->id.driver_data;
- lp->mem_start = mem_start;
-
- if ((status = depca_hw_init(dev, device)))
- goto out_free;
-
- return 0;
-
- out_free:
- free_netdev (dev);
- release_region (ioaddr, DEPCA_TOTAL_SIZE);
- out:
- return status;
-}
-#endif
-
-static int __devexit depca_device_remove (struct device *device)
-{
- struct net_device *dev;
- struct depca_private *lp;
- int bus;
-
- dev = device->driver_data;
- lp = dev->priv;
-
- unregister_netdev (dev);
- iounmap (lp->sh_mem);
- release_mem_region (lp->mem_start, lp->mem_len);
- release_region (dev->base_addr, DEPCA_TOTAL_SIZE);
- bus = lp->depca_bus;
- free_netdev (dev);
-
- return 0;
-}
-
-/*
-** Look for a particular board name in the on-board Remote Diagnostics
-** and Boot (readb) ROM. This will also give us a clue to the network RAM
-** base address.
-*/
-static int __init DepcaSignature(char *name, u_long base_addr)
-{
- u_int i, j, k;
- void __iomem *ptr;
- char tmpstr[16];
- u_long prom_addr = base_addr + 0xc000;
- u_long mem_addr = base_addr + 0x8000; /* 32KB */
-
- /* Can't reserve the prom region, it is already marked as
- * used, at least on x86. Instead, reserve a memory region a
- * board would certainly use. If it works, go ahead. If not,
- * run like hell... */
-
- if (!request_mem_region (mem_addr, 16, depca_string))
- return unknown;
-
- /* Copy the first 16 bytes of ROM */
-
- ptr = ioremap(prom_addr, 16);
- if (ptr == NULL) {
- printk(KERN_ERR "depca: I/O remap failed at %lx\n", prom_addr);
- return unknown;
- }
- for (i = 0; i < 16; i++) {
- tmpstr[i] = readb(ptr + i);
- }
- iounmap(ptr);
-
- release_mem_region (mem_addr, 16);
-
- /* Check if PROM contains a valid string */
- for (i = 0; *depca_signature[i] != '\0'; i++) {
- for (j = 0, k = 0; j < 16 && k < strlen(depca_signature[i]); j++) {
- if (depca_signature[i][k] == tmpstr[j]) { /* track signature */
- k++;
- } else { /* lost signature; begin search again */
- k = 0;
- }
- }
- if (k == strlen(depca_signature[i]))
- break;
- }
-
- /* Check if name string is valid, provided there's no PROM */
- if (name && *name && (i == unknown)) {
- for (i = 0; *depca_signature[i] != '\0'; i++) {
- if (strcmp(name, depca_signature[i]) == 0)
- break;
- }
- }
-
- return i;
-}
-
-/*
-** Look for a special sequence in the Ethernet station address PROM that
-** is common across all DEPCA products. Note that the original DEPCA needs
-** its ROM address counter to be initialized and enabled. Only enable
-** if the first address octet is a 0x08 - this minimises the chances of
-** messing around with some other hardware, but it assumes that this DEPCA
-** card initialized itself correctly.
-**
-** Search the Ethernet address ROM for the signature. Since the ROM address
-** counter can start at an arbitrary point, the search must include the entire
-** probe sequence length plus the (length_of_the_signature - 1).
-** Stop the search IMMEDIATELY after the signature is found so that the
-** PROM address counter is correctly positioned at the start of the
-** ethernet address for later read out.
-*/
-static int __init DevicePresent(u_long ioaddr)
-{
- union {
- struct {
- u32 a;
- u32 b;
- } llsig;
- char Sig[sizeof(u32) << 1];
- }
- dev;
- short sigLength = 0;
- s8 data;
- s16 nicsr;
- int i, j, status = 0;
-
- data = inb(DEPCA_PROM); /* clear counter on DEPCA */
- data = inb(DEPCA_PROM); /* read data */
-
- if (data == 0x08) { /* Enable counter on DEPCA */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= AAC;
- outb(nicsr, DEPCA_NICSR);
- }
-
- dev.llsig.a = ETH_PROM_SIG;
- dev.llsig.b = ETH_PROM_SIG;
- sigLength = sizeof(u32) << 1;
-
- for (i = 0, j = 0; j < sigLength && i < PROBE_LENGTH + sigLength - 1; i++) {
- data = inb(DEPCA_PROM);
- if (dev.Sig[j] == data) { /* track signature */
- j++;
- } else { /* lost signature; begin search again */
- if (data == dev.Sig[0]) { /* rare case.... */
- j = 1;
- } else {
- j = 0;
- }
- }
- }
-
- if (j != sigLength) {
- status = -ENODEV; /* search failed */
- }
-
- return status;
-}
-
-/*
-** The DE100 and DE101 PROM accesses were made non-standard for some bizarre
-** reason: access the upper half of the PROM with x=0; access the lower half
-** with x=1.
-*/
-static int __init get_hw_addr(struct net_device *dev)
-{
- u_long ioaddr = dev->base_addr;
- struct depca_private *lp = dev->priv;
- int i, k, tmp, status = 0;
- u_short j, x, chksum;
-
- x = (((lp->adapter == de100) || (lp->adapter == de101)) ? 1 : 0);
-
- for (i = 0, k = 0, j = 0; j < 3; j++) {
- k <<= 1;
- if (k > 0xffff)
- k -= 0xffff;
-
- k += (u_char) (tmp = inb(DEPCA_PROM + x));
- dev->dev_addr[i++] = (u_char) tmp;
- k += (u_short) ((tmp = inb(DEPCA_PROM + x)) << 8);
- dev->dev_addr[i++] = (u_char) tmp;
-
- if (k > 0xffff)
- k -= 0xffff;
- }
- if (k == 0xffff)
- k = 0;
-
- chksum = (u_char) inb(DEPCA_PROM + x);
- chksum |= (u_short) (inb(DEPCA_PROM + x) << 8);
- if (k != chksum)
- status = -1;
-
- return status;
-}
-
-/*
-** Load a packet into the shared memory
-*/
-static int load_packet(struct net_device *dev, struct sk_buff *skb)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- int i, entry, end, len, status = 0;
-
- entry = lp->tx_new; /* Ring around buffer number. */
- end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
- if (!(readl(&lp->tx_ring[end].base) & T_OWN)) { /* Enough room? */
- /*
- ** Caution: the write order is important here... don't set up the
- ** ownership rights until all the other information is in place.
- */
- if (end < entry) { /* wrapped buffer */
- len = (lp->txRingMask - entry + 1) * TX_BUFF_SZ;
- memcpy_toio(lp->tx_buff[entry], skb->data, len);
- memcpy_toio(lp->tx_buff[0], skb->data + len, skb->len - len);
- } else { /* linear buffer */
- memcpy_toio(lp->tx_buff[entry], skb->data, skb->len);
- }
-
- /* set up the buffer descriptors */
- len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
- for (i = entry; i != end; i = (i+1) & lp->txRingMask) {
- /* clean out flags */
- writel(readl(&lp->tx_ring[i].base) & ~T_FLAGS, &lp->tx_ring[i].base);
- writew(0x0000, &lp->tx_ring[i].misc); /* clears other error flags */
- writew(-TX_BUFF_SZ, &lp->tx_ring[i].length); /* packet length in buffer */
- len -= TX_BUFF_SZ;
- }
- /* clean out flags */
- writel(readl(&lp->tx_ring[end].base) & ~T_FLAGS, &lp->tx_ring[end].base);
- writew(0x0000, &lp->tx_ring[end].misc); /* clears other error flags */
- writew(-len, &lp->tx_ring[end].length); /* packet length in last buff */
-
- /* start of packet */
- writel(readl(&lp->tx_ring[entry].base) | T_STP, &lp->tx_ring[entry].base);
- /* end of packet */
- writel(readl(&lp->tx_ring[end].base) | T_ENP, &lp->tx_ring[end].base);
-
- for (i = end; i != entry; --i) {
- /* ownership of packet */
- writel(readl(&lp->tx_ring[i].base) | T_OWN, &lp->tx_ring[i].base);
- if (i == 0)
- i = lp->txRingMask + 1;
- }
- writel(readl(&lp->tx_ring[entry].base) | T_OWN, &lp->tx_ring[entry].base);
-
- lp->tx_new = (++end) & lp->txRingMask; /* update current pointers */
- } else {
- status = -1;
- }
-
- return status;
-}
-
-static void depca_dbg_open(struct net_device *dev)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- struct depca_init *p = &lp->init_block;
- int i;
- DECLARE_MAC_BUF(mac);
-
- if (depca_debug > 1) {
- /* Do not copy the shadow init block into shared memory */
- /* Debugging should not affect normal operation! */
- /* The shadow init block will get copied across during InitRestartDepca */
- printk("%s: depca open with irq %d\n", dev->name, dev->irq);
- printk("Descriptor head addresses (CPU):\n");
- printk(" 0x%lx 0x%lx\n", (u_long) lp->rx_ring, (u_long) lp->tx_ring);
- printk("Descriptor addresses (CPU):\nRX: ");
- for (i = 0; i < lp->rxRingMask; i++) {
- if (i < 3) {
- printk("%p ", &lp->rx_ring[i].base);
- }
- }
- printk("...%p\n", &lp->rx_ring[i].base);
- printk("TX: ");
- for (i = 0; i < lp->txRingMask; i++) {
- if (i < 3) {
- printk("%p ", &lp->tx_ring[i].base);
- }
- }
- printk("...%p\n", &lp->tx_ring[i].base);
- printk("\nDescriptor buffers (Device):\nRX: ");
- for (i = 0; i < lp->rxRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8x ", readl(&lp->rx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", readl(&lp->rx_ring[i].base));
- printk("TX: ");
- for (i = 0; i < lp->txRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8x ", readl(&lp->tx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base));
- printk("Initialisation block at 0x%8.8lx(Phys)\n", lp->mem_start);
- printk(" mode: 0x%4.4x\n", p->mode);
- printk(" physical address: %s\n", print_mac(mac, p->phys_addr));
- printk(" multicast hash table: ");
- for (i = 0; i < (HASH_TABLE_LEN >> 3) - 1; i++) {
- printk("%2.2x:", p->mcast_table[i]);
- }
- printk("%2.2x\n", p->mcast_table[i]);
- printk(" rx_ring at: 0x%8.8x\n", p->rx_ring);
- printk(" tx_ring at: 0x%8.8x\n", p->tx_ring);
- printk("buffers (Phys): 0x%8.8lx\n", lp->mem_start + lp->buffs_offset);
- printk("Ring size:\nRX: %d Log2(rxRingMask): 0x%8.8x\n", (int) lp->rxRingMask + 1, lp->rx_rlen);
- printk("TX: %d Log2(txRingMask): 0x%8.8x\n", (int) lp->txRingMask + 1, lp->tx_rlen);
- outw(CSR2, DEPCA_ADDR);
- printk("CSR2&1: 0x%4.4x", inw(DEPCA_DATA));
- outw(CSR1, DEPCA_ADDR);
- printk("%4.4x\n", inw(DEPCA_DATA));
- outw(CSR3, DEPCA_ADDR);
- printk("CSR3: 0x%4.4x\n", inw(DEPCA_DATA));
- }
-
- return;
-}
-
-/*
-** Perform IOCTL call functions here. Some are privileged operations and the
-** effective uid is checked in those cases.
-** All multicast IOCTLs will not work here and are for testing purposes only.
-*/
-static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_ifru;
- int i, status = 0;
- u_long ioaddr = dev->base_addr;
- union {
- u8 addr[(HASH_TABLE_LEN * ETH_ALEN)];
- u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
- u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
- } tmp;
- unsigned long flags;
- void *buf;
-
- switch (ioc->cmd) {
- case DEPCA_GET_HWADDR: /* Get the hardware address */
- for (i = 0; i < ETH_ALEN; i++) {
- tmp.addr[i] = dev->dev_addr[i];
- }
- ioc->len = ETH_ALEN;
- if (copy_to_user(ioc->data, tmp.addr, ioc->len))
- return -EFAULT;
- break;
-
- case DEPCA_SET_HWADDR: /* Set the hardware address */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN))
- return -EFAULT;
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = tmp.addr[i];
- }
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new)
- cpu_relax(); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
- break;
-
- case DEPCA_SET_PROM: /* Set Promiscuous Mode */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new)
- cpu_relax(); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode |= PROM; /* Set promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
- break;
-
- case DEPCA_CLR_PROM: /* Clear Promiscuous Mode */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- netif_stop_queue(dev);
- while (lp->tx_old != lp->tx_new)
- cpu_relax(); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode &= ~PROM; /* Clear promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- netif_start_queue(dev); /* Unlock the TX ring */
- break;
-
- case DEPCA_SAY_BOO: /* Say "Boo!" to the kernel log file */
- if(!capable(CAP_NET_ADMIN))
- return -EPERM;
- printk("%s: Boo!\n", dev->name);
- break;
-
- case DEPCA_GET_MCA: /* Get the multicast address table */
- ioc->len = (HASH_TABLE_LEN >> 3);
- if (copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len))
- return -EFAULT;
- break;
-
- case DEPCA_SET_MCA: /* Set a multicast address */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- if (ioc->len >= HASH_TABLE_LEN)
- return -EINVAL;
- if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len))
- return -EFAULT;
- set_multicast_list(dev);
- break;
-
- case DEPCA_CLR_MCA: /* Clear all multicast addresses */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- set_multicast_list(dev);
- break;
-
- case DEPCA_MCA_EN: /* Enable pass all multicast addressing */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- set_multicast_list(dev);
- break;
-
- case DEPCA_GET_STATS: /* Get the driver statistics */
- ioc->len = sizeof(lp->pktStats);
- buf = kmalloc(ioc->len, GFP_KERNEL);
- if(!buf)
- return -ENOMEM;
- spin_lock_irqsave(&lp->lock, flags);
- memcpy(buf, &lp->pktStats, ioc->len);
- spin_unlock_irqrestore(&lp->lock, flags);
- if (copy_to_user(ioc->data, buf, ioc->len))
- status = -EFAULT;
- kfree(buf);
- break;
-
- case DEPCA_CLR_STATS: /* Zero out the driver statistics */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- spin_lock_irqsave(&lp->lock, flags);
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- spin_unlock_irqrestore(&lp->lock, flags);
- break;
-
- case DEPCA_GET_REG: /* Get the DEPCA Registers */
- i = 0;
- tmp.sval[i++] = inw(DEPCA_NICSR);
- outw(CSR0, DEPCA_ADDR); /* status register */
- tmp.sval[i++] = inw(DEPCA_DATA);
- memcpy(&tmp.sval[i], &lp->init_block, sizeof(struct depca_init));
- ioc->len = i + sizeof(struct depca_init);
- if (copy_to_user(ioc->data, tmp.addr, ioc->len))
- return -EFAULT;
- break;
-
- default:
- return -EOPNOTSUPP;
- }
-
- return status;
-}
-
-static int __init depca_module_init (void)
-{
- int err = 0;
-
-#ifdef CONFIG_MCA
- err = mca_register_driver (&depca_mca_driver);
-#endif
-#ifdef CONFIG_EISA
- err |= eisa_driver_register (&depca_eisa_driver);
-#endif
- err |= platform_driver_register (&depca_isa_driver);
- depca_platform_probe ();
-
- return err;
-}
-
-static void __exit depca_module_exit (void)
-{
- int i;
-#ifdef CONFIG_MCA
- mca_unregister_driver (&depca_mca_driver);
-#endif
-#ifdef CONFIG_EISA
- eisa_driver_unregister (&depca_eisa_driver);
-#endif
- platform_driver_unregister (&depca_isa_driver);
-
- for (i = 0; depca_io_ports[i].iobase; i++) {
- if (depca_io_ports[i].device) {
- depca_io_ports[i].device->dev.platform_data = NULL;
- platform_device_unregister (depca_io_ports[i].device);
- depca_io_ports[i].device = NULL;
- }
- }
-}
-
-module_init (depca_module_init);
-module_exit (depca_module_exit);
diff --git a/drivers/net/depca.h b/drivers/net/depca.h
deleted file mode 100644
index ee42648dbde..00000000000
--- a/drivers/net/depca.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- Written 1994 by David C. Davies.
-
- Copyright 1994 David C. Davies. This software may be used and distributed
- according to the terms of the GNU General Public License, incorporated herein by
- reference.
-*/
-
-/*
-** I/O addresses. Note that the 2k buffer option is not supported in
-** this driver.
-*/
-#define DEPCA_NICSR ioaddr+0x00 /* Network interface CSR */
-#define DEPCA_RBI ioaddr+0x02 /* RAM buffer index (2k buffer mode) */
-#define DEPCA_DATA ioaddr+0x04 /* LANCE registers' data port */
-#define DEPCA_ADDR ioaddr+0x06 /* LANCE registers' address port */
-#define DEPCA_HBASE ioaddr+0x08 /* EISA high memory base address reg. */
-#define DEPCA_PROM ioaddr+0x0c /* Ethernet address ROM data port */
-#define DEPCA_CNFG ioaddr+0x0c /* EISA Configuration port */
-#define DEPCA_RBSA ioaddr+0x0e /* RAM buffer starting address (2k buff.) */
-
-/*
-** These are LANCE registers addressable through DEPCA_ADDR
-*/
-#define CSR0 0
-#define CSR1 1
-#define CSR2 2
-#define CSR3 3
-
-/*
-** NETWORK INTERFACE CSR (NI_CSR) bit definitions
-*/
-
-#define TO 0x0100 /* Time Out for remote boot */
-#define SHE 0x0080 /* SHadow memory Enable */
-#define BS 0x0040 /* Bank Select */
-#define BUF 0x0020 /* BUFfer size (1->32k, 0->64k) */
-#define RBE 0x0010 /* Remote Boot Enable (1->net boot) */
-#define AAC 0x0008 /* Address ROM Address Counter (1->enable) */
-#define _128KB 0x0008 /* 128kB Network RAM (1->enable) */
-#define IM 0x0004 /* Interrupt Mask (1->mask) */
-#define IEN 0x0002 /* Interrupt tristate ENable (1->enable) */
-#define LED 0x0001 /* LED control */
-
-/*
-** Control and Status Register 0 (CSR0) bit definitions
-*/
-
-#define ERR 0x8000 /* Error summary */
-#define BABL 0x4000 /* Babble transmitter timeout error */
-#define CERR 0x2000 /* Collision Error */
-#define MISS 0x1000 /* Missed packet */
-#define MERR 0x0800 /* Memory Error */
-#define RINT 0x0400 /* Receiver Interrupt */
-#define TINT 0x0200 /* Transmit Interrupt */
-#define IDON 0x0100 /* Initialization Done */
-#define INTR 0x0080 /* Interrupt Flag */
-#define INEA 0x0040 /* Interrupt Enable */
-#define RXON 0x0020 /* Receiver on */
-#define TXON 0x0010 /* Transmitter on */
-#define TDMD 0x0008 /* Transmit Demand */
-#define STOP 0x0004 /* Stop */
-#define STRT 0x0002 /* Start */
-#define INIT 0x0001 /* Initialize */
-#define INTM 0xff00 /* Interrupt Mask */
-#define INTE 0xfff0 /* Interrupt Enable */
-
-/*
-** CONTROL AND STATUS REGISTER 3 (CSR3)
-*/
-
-#define BSWP 0x0004 /* Byte SWaP */
-#define ACON 0x0002 /* ALE control */
-#define BCON 0x0001 /* Byte CONtrol */
-
-/*
-** Initialization Block Mode Register
-*/
-
-#define PROM 0x8000 /* Promiscuous Mode */
-#define EMBA 0x0080 /* Enable Modified Back-off Algorithm */
-#define INTL 0x0040 /* Internal Loopback */
-#define DRTY 0x0020 /* Disable Retry */
-#define COLL 0x0010 /* Force Collision */
-#define DTCR 0x0008 /* Disable Transmit CRC */
-#define LOOP 0x0004 /* Loopback */
-#define DTX 0x0002 /* Disable the Transmitter */
-#define DRX 0x0001 /* Disable the Receiver */
-
-/*
-** Receive Message Descriptor 1 (RMD1) bit definitions.
-*/
-
-#define R_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
-#define R_ERR 0x4000 /* Error Summary */
-#define R_FRAM 0x2000 /* Framing Error */
-#define R_OFLO 0x1000 /* Overflow Error */
-#define R_CRC 0x0800 /* CRC Error */
-#define R_BUFF 0x0400 /* Buffer Error */
-#define R_STP 0x0200 /* Start of Packet */
-#define R_ENP 0x0100 /* End of Packet */
-
-/*
-** Transmit Message Descriptor 1 (TMD1) bit definitions.
-*/
-
-#define T_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
-#define T_ERR 0x4000 /* Error Summary */
-#define T_ADD_FCS 0x2000 /* More the 1 retry needed to Xmit */
-#define T_MORE 0x1000 /* >1 retry to transmit packet */
-#define T_ONE 0x0800 /* 1 try needed to transmit the packet */
-#define T_DEF 0x0400 /* Deferred */
-#define T_STP 0x02000000 /* Start of Packet */
-#define T_ENP 0x01000000 /* End of Packet */
-#define T_FLAGS 0xff000000 /* TX Flags Field */
-
-/*
-** Transmit Message Descriptor 3 (TMD3) bit definitions.
-*/
-
-#define TMD3_BUFF 0x8000 /* BUFFer error */
-#define TMD3_UFLO 0x4000 /* UnderFLOw error */
-#define TMD3_RES 0x2000 /* REServed */
-#define TMD3_LCOL 0x1000 /* Late COLlision */
-#define TMD3_LCAR 0x0800 /* Loss of CARrier */
-#define TMD3_RTRY 0x0400 /* ReTRY error */
-
-/*
-** EISA configuration Register (CNFG) bit definitions
-*/
-
-#define TIMEOUT 0x0100 /* 0:2.5 mins, 1: 30 secs */
-#define REMOTE 0x0080 /* Remote Boot Enable -> 1 */
-#define IRQ11 0x0040 /* Enable -> 1 */
-#define IRQ10 0x0020 /* Enable -> 1 */
-#define IRQ9 0x0010 /* Enable -> 1 */
-#define IRQ5 0x0008 /* Enable -> 1 */
-#define BUFF 0x0004 /* 0: 64kB or 128kB, 1: 32kB */
-#define PADR16 0x0002 /* RAM on 64kB boundary */
-#define PADR17 0x0001 /* RAM on 128kB boundary */
-
-/*
-** Miscellaneous
-*/
-#define HASH_TABLE_LEN 64 /* Bits */
-#define HASH_BITS 0x003f /* 6 LS bits */
-
-#define MASK_INTERRUPTS 1
-#define UNMASK_INTERRUPTS 0
-
-#define EISA_EN 0x0001 /* Enable EISA bus buffers */
-#define EISA_ID iobase+0x0080 /* ID long word for EISA card */
-#define EISA_CTRL iobase+0x0084 /* Control word for EISA card */
-
-/*
-** Include the IOCTL stuff
-*/
-#include <linux/sockios.h>
-
-#define DEPCAIOCTL SIOCDEVPRIVATE
-
-struct depca_ioctl {
- unsigned short cmd; /* Command to run */
- unsigned short len; /* Length of the data buffer */
- unsigned char __user *data; /* Pointer to the data buffer */
-};
-
-/*
-** Recognised commands for the driver
-*/
-#define DEPCA_GET_HWADDR 0x01 /* Get the hardware address */
-#define DEPCA_SET_HWADDR 0x02 /* Get the hardware address */
-#define DEPCA_SET_PROM 0x03 /* Set Promiscuous Mode */
-#define DEPCA_CLR_PROM 0x04 /* Clear Promiscuous Mode */
-#define DEPCA_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
-#define DEPCA_GET_MCA 0x06 /* Get a multicast address */
-#define DEPCA_SET_MCA 0x07 /* Set a multicast address */
-#define DEPCA_CLR_MCA 0x08 /* Clear a multicast address */
-#define DEPCA_MCA_EN 0x09 /* Enable a multicast address group */
-#define DEPCA_GET_STATS 0x0a /* Get the driver statistics */
-#define DEPCA_CLR_STATS 0x0b /* Zero out the driver statistics */
-#define DEPCA_GET_REG 0x0c /* Get the Register contents */
-#define DEPCA_SET_REG 0x0d /* Set the Register contents */
-#define DEPCA_DUMP 0x0f /* Dump the DEPCA Status */
-
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
new file mode 100644
index 00000000000..b8fe808b795
--- /dev/null
+++ b/drivers/net/dsa/Kconfig
@@ -0,0 +1,39 @@
+menu "Distributed Switch Architecture drivers"
+ depends on HAVE_NET_DSA
+
+config NET_DSA_MV88E6XXX
+ tristate
+ default n
+
+config NET_DSA_MV88E6060
+ tristate "Marvell 88E6060 ethernet switch chip support"
+ select NET_DSA
+ select NET_DSA_TAG_TRAILER
+ ---help---
+ This enables support for the Marvell 88E6060 ethernet switch
+ chip.
+
+config NET_DSA_MV88E6XXX_NEED_PPU
+ bool
+ default n
+
+config NET_DSA_MV88E6131
+ tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support"
+ select NET_DSA
+ select NET_DSA_MV88E6XXX
+ select NET_DSA_MV88E6XXX_NEED_PPU
+ select NET_DSA_TAG_DSA
+ ---help---
+ This enables support for the Marvell 88E6085/6095/6095F/6131
+ ethernet switch chips.
+
+config NET_DSA_MV88E6123_61_65
+ tristate "Marvell 88E6123/6161/6165 ethernet switch chip support"
+ select NET_DSA
+ select NET_DSA_MV88E6XXX
+ select NET_DSA_TAG_EDSA
+ ---help---
+ This enables support for the Marvell 88E6123/6161/6165
+ ethernet switch chips.
+
+endmenu
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
new file mode 100644
index 00000000000..f3bda05536c
--- /dev/null
+++ b/drivers/net/dsa/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
+obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o
+mv88e6xxx_drv-y += mv88e6xxx.o
+ifdef CONFIG_NET_DSA_MV88E6123_61_65
+mv88e6xxx_drv-y += mv88e6123_61_65.o
+endif
+ifdef CONFIG_NET_DSA_MV88E6131
+mv88e6xxx_drv-y += mv88e6131.o
+endif
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
new file mode 100644
index 00000000000..7a54ec04b41
--- /dev/null
+++ b/drivers/net/dsa/mv88e6060.c
@@ -0,0 +1,286 @@
+/*
+ * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
+ * Copyright (c) 2008-2009 Marvell Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <net/dsa.h>
+
+#define REG_PORT(p) (8 + (p))
+#define REG_GLOBAL 0x0f
+
+static int reg_read(struct dsa_switch *ds, int addr, int reg)
+{
+ return mdiobus_read(ds->master_mii_bus, ds->pd->sw_addr + addr, reg);
+}
+
+#define REG_READ(addr, reg) \
+ ({ \
+ int __ret; \
+ \
+ __ret = reg_read(ds, addr, reg); \
+ if (__ret < 0) \
+ return __ret; \
+ __ret; \
+ })
+
+
+static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
+{
+ return mdiobus_write(ds->master_mii_bus, ds->pd->sw_addr + addr,
+ reg, val);
+}
+
+#define REG_WRITE(addr, reg, val) \
+ ({ \
+ int __ret; \
+ \
+ __ret = reg_write(ds, addr, reg, val); \
+ if (__ret < 0) \
+ return __ret; \
+ })
+
+static char *mv88e6060_probe(struct mii_bus *bus, int sw_addr)
+{
+ int ret;
+
+ ret = mdiobus_read(bus, sw_addr + REG_PORT(0), 0x03);
+ if (ret >= 0) {
+ ret &= 0xfff0;
+ if (ret == 0x0600)
+ return "Marvell 88E6060";
+ }
+
+ return NULL;
+}
+
+static int mv88e6060_switch_reset(struct dsa_switch *ds)
+{
+ int i;
+ int ret;
+ unsigned long timeout;
+
+ /* Set all ports to the disabled state. */
+ for (i = 0; i < 6; i++) {
+ ret = REG_READ(REG_PORT(i), 0x04);
+ REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
+ }
+
+ /* Wait for transmit queues to drain. */
+ usleep_range(2000, 4000);
+
+ /* Reset the switch. */
+ REG_WRITE(REG_GLOBAL, 0x0a, 0xa130);
+
+ /* Wait up to one second for reset to complete. */
+ timeout = jiffies + 1 * HZ;
+ while (time_before(jiffies, timeout)) {
+ ret = REG_READ(REG_GLOBAL, 0x00);
+ if ((ret & 0x8000) == 0x0000)
+ break;
+
+ usleep_range(1000, 2000);
+ }
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int mv88e6060_setup_global(struct dsa_switch *ds)
+{
+ /* Disable discarding of frames with excessive collisions,
+ * set the maximum frame size to 1536 bytes, and mask all
+ * interrupt sources.
+ */
+ REG_WRITE(REG_GLOBAL, 0x04, 0x0800);
+
+ /* Enable automatic address learning, set the address
+ * database size to 1024 entries, and set the default aging
+ * time to 5 minutes.
+ */
+ REG_WRITE(REG_GLOBAL, 0x0a, 0x2130);
+
+ return 0;
+}
+
+static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
+{
+ int addr = REG_PORT(p);
+
+ /* Do not force flow control, disable Ingress and Egress
+ * Header tagging, disable VLAN tunneling, and set the port
+ * state to Forwarding. Additionally, if this is the CPU
+ * port, enable Ingress and Egress Trailer tagging mode.
+ */
+ REG_WRITE(addr, 0x04, dsa_is_cpu_port(ds, p) ? 0x4103 : 0x0003);
+
+ /* Port based VLAN map: give each port its own address
+ * database, allow the CPU port to talk to each of the 'real'
+ * ports, and allow each of the 'real' ports to only talk to
+ * the CPU port.
+ */
+ REG_WRITE(addr, 0x06,
+ ((p & 0xf) << 12) |
+ (dsa_is_cpu_port(ds, p) ?
+ ds->phys_port_mask :
+ (1 << ds->dst->cpu_port)));
+
+ /* Port Association Vector: when learning source addresses
+ * of packets, add the address to the address database using
+ * a port bitmap that has only the bit for this port set and
+ * the other bits clear.
+ */
+ REG_WRITE(addr, 0x0b, 1 << p);
+
+ return 0;
+}
+
+static int mv88e6060_setup(struct dsa_switch *ds)
+{
+ int i;
+ int ret;
+
+ ret = mv88e6060_switch_reset(ds);
+ if (ret < 0)
+ return ret;
+
+ /* @@@ initialise atu */
+
+ ret = mv88e6060_setup_global(ds);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < 6; i++) {
+ ret = mv88e6060_setup_port(ds, i);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mv88e6060_set_addr(struct dsa_switch *ds, u8 *addr)
+{
+ REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
+ REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
+ REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
+
+ return 0;
+}
+
+static int mv88e6060_port_to_phy_addr(int port)
+{
+ if (port >= 0 && port <= 5)
+ return port;
+ return -1;
+}
+
+static int mv88e6060_phy_read(struct dsa_switch *ds, int port, int regnum)
+{
+ int addr;
+
+ addr = mv88e6060_port_to_phy_addr(port);
+ if (addr == -1)
+ return 0xffff;
+
+ return reg_read(ds, addr, regnum);
+}
+
+static int
+mv88e6060_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
+{
+ int addr;
+
+ addr = mv88e6060_port_to_phy_addr(port);
+ if (addr == -1)
+ return 0xffff;
+
+ return reg_write(ds, addr, regnum, val);
+}
+
+static void mv88e6060_poll_link(struct dsa_switch *ds)
+{
+ int i;
+
+ for (i = 0; i < DSA_MAX_PORTS; i++) {
+ struct net_device *dev;
+ int uninitialized_var(port_status);
+ int link;
+ int speed;
+ int duplex;
+ int fc;
+
+ dev = ds->ports[i];
+ if (dev == NULL)
+ continue;
+
+ link = 0;
+ if (dev->flags & IFF_UP) {
+ port_status = reg_read(ds, REG_PORT(i), 0x00);
+ if (port_status < 0)
+ continue;
+
+ link = !!(port_status & 0x1000);
+ }
+
+ if (!link) {
+ if (netif_carrier_ok(dev)) {
+ netdev_info(dev, "link down\n");
+ netif_carrier_off(dev);
+ }
+ continue;
+ }
+
+ speed = (port_status & 0x0100) ? 100 : 10;
+ duplex = (port_status & 0x0200) ? 1 : 0;
+ fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0;
+
+ if (!netif_carrier_ok(dev)) {
+ netdev_info(dev,
+ "link up, %d Mb/s, %s duplex, flow control %sabled\n",
+ speed,
+ duplex ? "full" : "half",
+ fc ? "en" : "dis");
+ netif_carrier_on(dev);
+ }
+ }
+}
+
+static struct dsa_switch_driver mv88e6060_switch_driver = {
+ .tag_protocol = htons(ETH_P_TRAILER),
+ .probe = mv88e6060_probe,
+ .setup = mv88e6060_setup,
+ .set_addr = mv88e6060_set_addr,
+ .phy_read = mv88e6060_phy_read,
+ .phy_write = mv88e6060_phy_write,
+ .poll_link = mv88e6060_poll_link,
+};
+
+static int __init mv88e6060_init(void)
+{
+ register_switch_driver(&mv88e6060_switch_driver);
+ return 0;
+}
+module_init(mv88e6060_init);
+
+static void __exit mv88e6060_cleanup(void)
+{
+ unregister_switch_driver(&mv88e6060_switch_driver);
+}
+module_exit(mv88e6060_cleanup);
+
+MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
+MODULE_DESCRIPTION("Driver for Marvell 88E6060 ethernet switch chip");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mv88e6060");
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
new file mode 100644
index 00000000000..69c42513dd7
--- /dev/null
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -0,0 +1,409 @@
+/*
+ * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
+ * Copyright (c) 2008-2009 Marvell Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <net/dsa.h>
+#include "mv88e6xxx.h"
+
+static char *mv88e6123_61_65_probe(struct mii_bus *bus, int sw_addr)
+{
+ int ret;
+
+ ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
+ if (ret >= 0) {
+ if (ret == 0x1212)
+ return "Marvell 88E6123 (A1)";
+ if (ret == 0x1213)
+ return "Marvell 88E6123 (A2)";
+ if ((ret & 0xfff0) == 0x1210)
+ return "Marvell 88E6123";
+
+ if (ret == 0x1612)
+ return "Marvell 88E6161 (A1)";
+ if (ret == 0x1613)
+ return "Marvell 88E6161 (A2)";
+ if ((ret & 0xfff0) == 0x1610)
+ return "Marvell 88E6161";
+
+ if (ret == 0x1652)
+ return "Marvell 88E6165 (A1)";
+ if (ret == 0x1653)
+ return "Marvell 88e6165 (A2)";
+ if ((ret & 0xfff0) == 0x1650)
+ return "Marvell 88E6165";
+ }
+
+ return NULL;
+}
+
+static int mv88e6123_61_65_switch_reset(struct dsa_switch *ds)
+{
+ int i;
+ int ret;
+ unsigned long timeout;
+
+ /* Set all ports to the disabled state. */
+ for (i = 0; i < 8; i++) {
+ ret = REG_READ(REG_PORT(i), 0x04);
+ REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
+ }
+
+ /* Wait for transmit queues to drain. */
+ usleep_range(2000, 4000);
+
+ /* Reset the switch. */
+ REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
+
+ /* Wait up to one second for reset to complete. */
+ timeout = jiffies + 1 * HZ;
+ while (time_before(jiffies, timeout)) {
+ ret = REG_READ(REG_GLOBAL, 0x00);
+ if ((ret & 0xc800) == 0xc800)
+ break;
+
+ usleep_range(1000, 2000);
+ }
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int mv88e6123_61_65_setup_global(struct dsa_switch *ds)
+{
+ int ret;
+ int i;
+
+ /* Disable the PHY polling unit (since there won't be any
+ * external PHYs to poll), don't discard packets with
+ * excessive collisions, and mask all interrupt sources.
+ */
+ REG_WRITE(REG_GLOBAL, 0x04, 0x0000);
+
+ /* Set the default address aging time to 5 minutes, and
+ * enable address learn messages to be sent to all message
+ * ports.
+ */
+ REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
+
+ /* Configure the priority mapping registers. */
+ ret = mv88e6xxx_config_prio(ds);
+ if (ret < 0)
+ return ret;
+
+ /* Configure the upstream port, and configure the upstream
+ * port as the port to which ingress and egress monitor frames
+ * are to be sent.
+ */
+ REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1110));
+
+ /* Disable remote management for now, and set the switch's
+ * DSA device number.
+ */
+ REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f);
+
+ /* Send all frames with destination addresses matching
+ * 01:80:c2:00:00:2x to the CPU port.
+ */
+ REG_WRITE(REG_GLOBAL2, 0x02, 0xffff);
+
+ /* Send all frames with destination addresses matching
+ * 01:80:c2:00:00:0x to the CPU port.
+ */
+ REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
+
+ /* Disable the loopback filter, disable flow control
+ * messages, disable flood broadcast override, disable
+ * removing of provider tags, disable ATU age violation
+ * interrupts, disable tag flow control, force flow
+ * control priority to the highest, and send all special
+ * multicast frames to the CPU at the highest priority.
+ */
+ REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
+
+ /* Program the DSA routing table. */
+ for (i = 0; i < 32; i++) {
+ int nexthop;
+
+ nexthop = 0x1f;
+ if (i != ds->index && i < ds->dst->pd->nr_chips)
+ nexthop = ds->pd->rtable[i] & 0x1f;
+
+ REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
+ }
+
+ /* Clear all trunk masks. */
+ for (i = 0; i < 8; i++)
+ REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0xff);
+
+ /* Clear all trunk mappings. */
+ for (i = 0; i < 16; i++)
+ REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
+
+ /* Disable ingress rate limiting by resetting all ingress
+ * rate limit registers to their initial state.
+ */
+ for (i = 0; i < 6; i++)
+ REG_WRITE(REG_GLOBAL2, 0x09, 0x9000 | (i << 8));
+
+ /* Initialise cross-chip port VLAN table to reset defaults. */
+ REG_WRITE(REG_GLOBAL2, 0x0b, 0x9000);
+
+ /* Clear the priority override table. */
+ for (i = 0; i < 16; i++)
+ REG_WRITE(REG_GLOBAL2, 0x0f, 0x8000 | (i << 8));
+
+ /* @@@ initialise AVB (22/23) watchdog (27) sdet (29) registers */
+
+ return 0;
+}
+
+static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
+{
+ int addr = REG_PORT(p);
+ u16 val;
+
+ /* MAC Forcing register: don't force link, speed, duplex
+ * or flow control state to any particular values on physical
+ * ports, but force the CPU port and all DSA ports to 1000 Mb/s
+ * full duplex.
+ */
+ if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
+ REG_WRITE(addr, 0x01, 0x003e);
+ else
+ REG_WRITE(addr, 0x01, 0x0003);
+
+ /* Do not limit the period of time that this port can be
+ * paused for by the remote end or the period of time that
+ * this port can pause the remote end.
+ */
+ REG_WRITE(addr, 0x02, 0x0000);
+
+ /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
+ * disable Header mode, enable IGMP/MLD snooping, disable VLAN
+ * tunneling, determine priority by looking at 802.1p and IP
+ * priority fields (IP prio has precedence), and set STP state
+ * to Forwarding.
+ *
+ * If this is the CPU link, use DSA or EDSA tagging depending
+ * on which tagging mode was configured.
+ *
+ * If this is a link to another switch, use DSA tagging mode.
+ *
+ * If this is the upstream port for this switch, enable
+ * forwarding of unknown unicasts and multicasts.
+ */
+ val = 0x0433;
+ if (dsa_is_cpu_port(ds, p)) {
+ if (ds->dst->tag_protocol == htons(ETH_P_EDSA))
+ val |= 0x3300;
+ else
+ val |= 0x0100;
+ }
+ if (ds->dsa_port_mask & (1 << p))
+ val |= 0x0100;
+ if (p == dsa_upstream_port(ds))
+ val |= 0x000c;
+ REG_WRITE(addr, 0x04, val);
+
+ /* Port Control 1: disable trunking. Also, if this is the
+ * CPU port, enable learn messages to be sent to this port.
+ */
+ REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
+
+ /* Port based VLAN map: give each port its own address
+ * database, allow the CPU port to talk to each of the 'real'
+ * ports, and allow each of the 'real' ports to only talk to
+ * the upstream port.
+ */
+ val = (p & 0xf) << 12;
+ if (dsa_is_cpu_port(ds, p))
+ val |= ds->phys_port_mask;
+ else
+ val |= 1 << dsa_upstream_port(ds);
+ REG_WRITE(addr, 0x06, val);
+
+ /* Default VLAN ID and priority: don't set a default VLAN
+ * ID, and set the default packet priority to zero.
+ */
+ REG_WRITE(addr, 0x07, 0x0000);
+
+ /* Port Control 2: don't force a good FCS, set the maximum
+ * frame size to 10240 bytes, don't let the switch add or
+ * strip 802.1q tags, don't discard tagged or untagged frames
+ * on this port, do a destination address lookup on all
+ * received packets as usual, disable ARP mirroring and don't
+ * send a copy of all transmitted/received frames on this port
+ * to the CPU.
+ */
+ REG_WRITE(addr, 0x08, 0x2080);
+
+ /* Egress rate control: disable egress rate control. */
+ REG_WRITE(addr, 0x09, 0x0001);
+
+ /* Egress rate control 2: disable egress rate control. */
+ REG_WRITE(addr, 0x0a, 0x0000);
+
+ /* Port Association Vector: when learning source addresses
+ * of packets, add the address to the address database using
+ * a port bitmap that has only the bit for this port set and
+ * the other bits clear.
+ */
+ REG_WRITE(addr, 0x0b, 1 << p);
+
+ /* Port ATU control: disable limiting the number of address
+ * database entries that this port is allowed to use.
+ */
+ REG_WRITE(addr, 0x0c, 0x0000);
+
+ /* Priority Override: disable DA, SA and VTU priority override. */
+ REG_WRITE(addr, 0x0d, 0x0000);
+
+ /* Port Ethertype: use the Ethertype DSA Ethertype value. */
+ REG_WRITE(addr, 0x0f, ETH_P_EDSA);
+
+ /* Tag Remap: use an identity 802.1p prio -> switch prio
+ * mapping.
+ */
+ REG_WRITE(addr, 0x18, 0x3210);
+
+ /* Tag Remap 2: use an identity 802.1p prio -> switch prio
+ * mapping.
+ */
+ REG_WRITE(addr, 0x19, 0x7654);
+
+ return 0;
+}
+
+static int mv88e6123_61_65_setup(struct dsa_switch *ds)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int i;
+ int ret;
+
+ mutex_init(&ps->smi_mutex);
+ mutex_init(&ps->stats_mutex);
+
+ ret = mv88e6123_61_65_switch_reset(ds);
+ if (ret < 0)
+ return ret;
+
+ /* @@@ initialise vtu and atu */
+
+ ret = mv88e6123_61_65_setup_global(ds);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < 6; i++) {
+ ret = mv88e6123_61_65_setup_port(ds, i);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mv88e6123_61_65_port_to_phy_addr(int port)
+{
+ if (port >= 0 && port <= 4)
+ return port;
+ return -1;
+}
+
+static int
+mv88e6123_61_65_phy_read(struct dsa_switch *ds, int port, int regnum)
+{
+ int addr = mv88e6123_61_65_port_to_phy_addr(port);
+ return mv88e6xxx_phy_read(ds, addr, regnum);
+}
+
+static int
+mv88e6123_61_65_phy_write(struct dsa_switch *ds,
+ int port, int regnum, u16 val)
+{
+ int addr = mv88e6123_61_65_port_to_phy_addr(port);
+ return mv88e6xxx_phy_write(ds, addr, regnum, val);
+}
+
+static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = {
+ { "in_good_octets", 8, 0x00, },
+ { "in_bad_octets", 4, 0x02, },
+ { "in_unicast", 4, 0x04, },
+ { "in_broadcasts", 4, 0x06, },
+ { "in_multicasts", 4, 0x07, },
+ { "in_pause", 4, 0x16, },
+ { "in_undersize", 4, 0x18, },
+ { "in_fragments", 4, 0x19, },
+ { "in_oversize", 4, 0x1a, },
+ { "in_jabber", 4, 0x1b, },
+ { "in_rx_error", 4, 0x1c, },
+ { "in_fcs_error", 4, 0x1d, },
+ { "out_octets", 8, 0x0e, },
+ { "out_unicast", 4, 0x10, },
+ { "out_broadcasts", 4, 0x13, },
+ { "out_multicasts", 4, 0x12, },
+ { "out_pause", 4, 0x15, },
+ { "excessive", 4, 0x11, },
+ { "collisions", 4, 0x1e, },
+ { "deferred", 4, 0x05, },
+ { "single", 4, 0x14, },
+ { "multiple", 4, 0x17, },
+ { "out_fcs_error", 4, 0x03, },
+ { "late", 4, 0x1f, },
+ { "hist_64bytes", 4, 0x08, },
+ { "hist_65_127bytes", 4, 0x09, },
+ { "hist_128_255bytes", 4, 0x0a, },
+ { "hist_256_511bytes", 4, 0x0b, },
+ { "hist_512_1023bytes", 4, 0x0c, },
+ { "hist_1024_max_bytes", 4, 0x0d, },
+};
+
+static void
+mv88e6123_61_65_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
+{
+ mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6123_61_65_hw_stats),
+ mv88e6123_61_65_hw_stats, port, data);
+}
+
+static void
+mv88e6123_61_65_get_ethtool_stats(struct dsa_switch *ds,
+ int port, uint64_t *data)
+{
+ mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6123_61_65_hw_stats),
+ mv88e6123_61_65_hw_stats, port, data);
+}
+
+static int mv88e6123_61_65_get_sset_count(struct dsa_switch *ds)
+{
+ return ARRAY_SIZE(mv88e6123_61_65_hw_stats);
+}
+
+struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
+ .tag_protocol = cpu_to_be16(ETH_P_EDSA),
+ .priv_size = sizeof(struct mv88e6xxx_priv_state),
+ .probe = mv88e6123_61_65_probe,
+ .setup = mv88e6123_61_65_setup,
+ .set_addr = mv88e6xxx_set_addr_indirect,
+ .phy_read = mv88e6123_61_65_phy_read,
+ .phy_write = mv88e6123_61_65_phy_write,
+ .poll_link = mv88e6xxx_poll_link,
+ .get_strings = mv88e6123_61_65_get_strings,
+ .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats,
+ .get_sset_count = mv88e6123_61_65_get_sset_count,
+};
+
+MODULE_ALIAS("platform:mv88e6123");
+MODULE_ALIAS("platform:mv88e6161");
+MODULE_ALIAS("platform:mv88e6165");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
new file mode 100644
index 00000000000..953bc6a49e5
--- /dev/null
+++ b/drivers/net/dsa/mv88e6131.c
@@ -0,0 +1,398 @@
+/*
+ * net/dsa/mv88e6131.c - Marvell 88e6095/6095f/6131 switch chip support
+ * Copyright (c) 2008-2009 Marvell Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <net/dsa.h>
+#include "mv88e6xxx.h"
+
+/* Switch product IDs */
+#define ID_6085 0x04a0
+#define ID_6095 0x0950
+#define ID_6131 0x1060
+
+static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr)
+{
+ int ret;
+
+ ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
+ if (ret >= 0) {
+ ret &= 0xfff0;
+ if (ret == ID_6085)
+ return "Marvell 88E6085";
+ if (ret == ID_6095)
+ return "Marvell 88E6095/88E6095F";
+ if (ret == ID_6131)
+ return "Marvell 88E6131";
+ }
+
+ return NULL;
+}
+
+static int mv88e6131_switch_reset(struct dsa_switch *ds)
+{
+ int i;
+ int ret;
+ unsigned long timeout;
+
+ /* Set all ports to the disabled state. */
+ for (i = 0; i < 11; i++) {
+ ret = REG_READ(REG_PORT(i), 0x04);
+ REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
+ }
+
+ /* Wait for transmit queues to drain. */
+ usleep_range(2000, 4000);
+
+ /* Reset the switch. */
+ REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
+
+ /* Wait up to one second for reset to complete. */
+ timeout = jiffies + 1 * HZ;
+ while (time_before(jiffies, timeout)) {
+ ret = REG_READ(REG_GLOBAL, 0x00);
+ if ((ret & 0xc800) == 0xc800)
+ break;
+
+ usleep_range(1000, 2000);
+ }
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int mv88e6131_setup_global(struct dsa_switch *ds)
+{
+ int ret;
+ int i;
+
+ /* Enable the PHY polling unit, don't discard packets with
+ * excessive collisions, use a weighted fair queueing scheme
+ * to arbitrate between packet queues, set the maximum frame
+ * size to 1632, and mask all interrupt sources.
+ */
+ REG_WRITE(REG_GLOBAL, 0x04, 0x4400);
+
+ /* Set the default address aging time to 5 minutes, and
+ * enable address learn messages to be sent to all message
+ * ports.
+ */
+ REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
+
+ /* Configure the priority mapping registers. */
+ ret = mv88e6xxx_config_prio(ds);
+ if (ret < 0)
+ return ret;
+
+ /* Set the VLAN ethertype to 0x8100. */
+ REG_WRITE(REG_GLOBAL, 0x19, 0x8100);
+
+ /* Disable ARP mirroring, and configure the upstream port as
+ * the port to which ingress and egress monitor frames are to
+ * be sent.
+ */
+ REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1100) | 0x00f0);
+
+ /* Disable cascade port functionality unless this device
+ * is used in a cascade configuration, and set the switch's
+ * DSA device number.
+ */
+ if (ds->dst->pd->nr_chips > 1)
+ REG_WRITE(REG_GLOBAL, 0x1c, 0xf000 | (ds->index & 0x1f));
+ else
+ REG_WRITE(REG_GLOBAL, 0x1c, 0xe000 | (ds->index & 0x1f));
+
+ /* Send all frames with destination addresses matching
+ * 01:80:c2:00:00:0x to the CPU port.
+ */
+ REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
+
+ /* Ignore removed tag data on doubly tagged packets, disable
+ * flow control messages, force flow control priority to the
+ * highest, and send all special multicast frames to the CPU
+ * port at the highest priority.
+ */
+ REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
+
+ /* Program the DSA routing table. */
+ for (i = 0; i < 32; i++) {
+ int nexthop;
+
+ nexthop = 0x1f;
+ if (i != ds->index && i < ds->dst->pd->nr_chips)
+ nexthop = ds->pd->rtable[i] & 0x1f;
+
+ REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
+ }
+
+ /* Clear all trunk masks. */
+ for (i = 0; i < 8; i++)
+ REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0x7ff);
+
+ /* Clear all trunk mappings. */
+ for (i = 0; i < 16; i++)
+ REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
+
+ /* Force the priority of IGMP/MLD snoop frames and ARP frames
+ * to the highest setting.
+ */
+ REG_WRITE(REG_GLOBAL2, 0x0f, 0x00ff);
+
+ return 0;
+}
+
+static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int addr = REG_PORT(p);
+ u16 val;
+
+ /* MAC Forcing register: don't force link, speed, duplex
+ * or flow control state to any particular values on physical
+ * ports, but force the CPU port and all DSA ports to 1000 Mb/s
+ * (100 Mb/s on 6085) full duplex.
+ */
+ if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
+ if (ps->id == ID_6085)
+ REG_WRITE(addr, 0x01, 0x003d); /* 100 Mb/s */
+ else
+ REG_WRITE(addr, 0x01, 0x003e); /* 1000 Mb/s */
+ else
+ REG_WRITE(addr, 0x01, 0x0003);
+
+ /* Port Control: disable Core Tag, disable Drop-on-Lock,
+ * transmit frames unmodified, disable Header mode,
+ * enable IGMP/MLD snoop, disable DoubleTag, disable VLAN
+ * tunneling, determine priority by looking at 802.1p and
+ * IP priority fields (IP prio has precedence), and set STP
+ * state to Forwarding.
+ *
+ * If this is the upstream port for this switch, enable
+ * forwarding of unknown unicasts, and enable DSA tagging
+ * mode.
+ *
+ * If this is the link to another switch, use DSA tagging
+ * mode, but do not enable forwarding of unknown unicasts.
+ */
+ val = 0x0433;
+ if (p == dsa_upstream_port(ds)) {
+ val |= 0x0104;
+ /* On 6085, unknown multicast forward is controlled
+ * here rather than in Port Control 2 register.
+ */
+ if (ps->id == ID_6085)
+ val |= 0x0008;
+ }
+ if (ds->dsa_port_mask & (1 << p))
+ val |= 0x0100;
+ REG_WRITE(addr, 0x04, val);
+
+ /* Port Control 1: disable trunking. Also, if this is the
+ * CPU port, enable learn messages to be sent to this port.
+ */
+ REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
+
+ /* Port based VLAN map: give each port its own address
+ * database, allow the CPU port to talk to each of the 'real'
+ * ports, and allow each of the 'real' ports to only talk to
+ * the upstream port.
+ */
+ val = (p & 0xf) << 12;
+ if (dsa_is_cpu_port(ds, p))
+ val |= ds->phys_port_mask;
+ else
+ val |= 1 << dsa_upstream_port(ds);
+ REG_WRITE(addr, 0x06, val);
+
+ /* Default VLAN ID and priority: don't set a default VLAN
+ * ID, and set the default packet priority to zero.
+ */
+ REG_WRITE(addr, 0x07, 0x0000);
+
+ /* Port Control 2: don't force a good FCS, don't use
+ * VLAN-based, source address-based or destination
+ * address-based priority overrides, don't let the switch
+ * add or strip 802.1q tags, don't discard tagged or
+ * untagged frames on this port, do a destination address
+ * lookup on received packets as usual, don't send a copy
+ * of all transmitted/received frames on this port to the
+ * CPU, and configure the upstream port number.
+ *
+ * If this is the upstream port for this switch, enable
+ * forwarding of unknown multicast addresses.
+ */
+ if (ps->id == ID_6085)
+ /* on 6085, bits 3:0 are reserved, bit 6 control ARP
+ * mirroring, and multicast forward is handled in
+ * Port Control register.
+ */
+ REG_WRITE(addr, 0x08, 0x0080);
+ else {
+ val = 0x0080 | dsa_upstream_port(ds);
+ if (p == dsa_upstream_port(ds))
+ val |= 0x0040;
+ REG_WRITE(addr, 0x08, val);
+ }
+
+ /* Rate Control: disable ingress rate limiting. */
+ REG_WRITE(addr, 0x09, 0x0000);
+
+ /* Rate Control 2: disable egress rate limiting. */
+ REG_WRITE(addr, 0x0a, 0x0000);
+
+ /* Port Association Vector: when learning source addresses
+ * of packets, add the address to the address database using
+ * a port bitmap that has only the bit for this port set and
+ * the other bits clear.
+ */
+ REG_WRITE(addr, 0x0b, 1 << p);
+
+ /* Tag Remap: use an identity 802.1p prio -> switch prio
+ * mapping.
+ */
+ REG_WRITE(addr, 0x18, 0x3210);
+
+ /* Tag Remap 2: use an identity 802.1p prio -> switch prio
+ * mapping.
+ */
+ REG_WRITE(addr, 0x19, 0x7654);
+
+ return 0;
+}
+
+static int mv88e6131_setup(struct dsa_switch *ds)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int i;
+ int ret;
+
+ mutex_init(&ps->smi_mutex);
+ mv88e6xxx_ppu_state_init(ds);
+ mutex_init(&ps->stats_mutex);
+
+ ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
+
+ ret = mv88e6131_switch_reset(ds);
+ if (ret < 0)
+ return ret;
+
+ /* @@@ initialise vtu and atu */
+
+ ret = mv88e6131_setup_global(ds);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < 11; i++) {
+ ret = mv88e6131_setup_port(ds, i);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mv88e6131_port_to_phy_addr(int port)
+{
+ if (port >= 0 && port <= 11)
+ return port;
+ return -1;
+}
+
+static int
+mv88e6131_phy_read(struct dsa_switch *ds, int port, int regnum)
+{
+ int addr = mv88e6131_port_to_phy_addr(port);
+ return mv88e6xxx_phy_read_ppu(ds, addr, regnum);
+}
+
+static int
+mv88e6131_phy_write(struct dsa_switch *ds,
+ int port, int regnum, u16 val)
+{
+ int addr = mv88e6131_port_to_phy_addr(port);
+ return mv88e6xxx_phy_write_ppu(ds, addr, regnum, val);
+}
+
+static struct mv88e6xxx_hw_stat mv88e6131_hw_stats[] = {
+ { "in_good_octets", 8, 0x00, },
+ { "in_bad_octets", 4, 0x02, },
+ { "in_unicast", 4, 0x04, },
+ { "in_broadcasts", 4, 0x06, },
+ { "in_multicasts", 4, 0x07, },
+ { "in_pause", 4, 0x16, },
+ { "in_undersize", 4, 0x18, },
+ { "in_fragments", 4, 0x19, },
+ { "in_oversize", 4, 0x1a, },
+ { "in_jabber", 4, 0x1b, },
+ { "in_rx_error", 4, 0x1c, },
+ { "in_fcs_error", 4, 0x1d, },
+ { "out_octets", 8, 0x0e, },
+ { "out_unicast", 4, 0x10, },
+ { "out_broadcasts", 4, 0x13, },
+ { "out_multicasts", 4, 0x12, },
+ { "out_pause", 4, 0x15, },
+ { "excessive", 4, 0x11, },
+ { "collisions", 4, 0x1e, },
+ { "deferred", 4, 0x05, },
+ { "single", 4, 0x14, },
+ { "multiple", 4, 0x17, },
+ { "out_fcs_error", 4, 0x03, },
+ { "late", 4, 0x1f, },
+ { "hist_64bytes", 4, 0x08, },
+ { "hist_65_127bytes", 4, 0x09, },
+ { "hist_128_255bytes", 4, 0x0a, },
+ { "hist_256_511bytes", 4, 0x0b, },
+ { "hist_512_1023bytes", 4, 0x0c, },
+ { "hist_1024_max_bytes", 4, 0x0d, },
+};
+
+static void
+mv88e6131_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
+{
+ mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6131_hw_stats),
+ mv88e6131_hw_stats, port, data);
+}
+
+static void
+mv88e6131_get_ethtool_stats(struct dsa_switch *ds,
+ int port, uint64_t *data)
+{
+ mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6131_hw_stats),
+ mv88e6131_hw_stats, port, data);
+}
+
+static int mv88e6131_get_sset_count(struct dsa_switch *ds)
+{
+ return ARRAY_SIZE(mv88e6131_hw_stats);
+}
+
+struct dsa_switch_driver mv88e6131_switch_driver = {
+ .tag_protocol = cpu_to_be16(ETH_P_DSA),
+ .priv_size = sizeof(struct mv88e6xxx_priv_state),
+ .probe = mv88e6131_probe,
+ .setup = mv88e6131_setup,
+ .set_addr = mv88e6xxx_set_addr_direct,
+ .phy_read = mv88e6131_phy_read,
+ .phy_write = mv88e6131_phy_write,
+ .poll_link = mv88e6xxx_poll_link,
+ .get_strings = mv88e6131_get_strings,
+ .get_ethtool_stats = mv88e6131_get_ethtool_stats,
+ .get_sset_count = mv88e6131_get_sset_count,
+};
+
+MODULE_ALIAS("platform:mv88e6085");
+MODULE_ALIAS("platform:mv88e6095");
+MODULE_ALIAS("platform:mv88e6095f");
+MODULE_ALIAS("platform:mv88e6131");
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
new file mode 100644
index 00000000000..9ce2146346b
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -0,0 +1,521 @@
+/*
+ * net/dsa/mv88e6xxx.c - Marvell 88e6xxx switch chip support
+ * Copyright (c) 2008 Marvell Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <net/dsa.h>
+#include "mv88e6xxx.h"
+
+/* If the switch's ADDR[4:0] strap pins are strapped to zero, it will
+ * use all 32 SMI bus addresses on its SMI bus, and all switch registers
+ * will be directly accessible on some {device address,register address}
+ * pair. If the ADDR[4:0] pins are not strapped to zero, the switch
+ * will only respond to SMI transactions to that specific address, and
+ * an indirect addressing mechanism needs to be used to access its
+ * registers.
+ */
+static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ ret = mdiobus_read(bus, sw_addr, 0);
+ if (ret < 0)
+ return ret;
+
+ if ((ret & 0x8000) == 0)
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
+{
+ int ret;
+
+ if (sw_addr == 0)
+ return mdiobus_read(bus, addr, reg);
+
+ /* Wait for the bus to become free. */
+ ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
+ if (ret < 0)
+ return ret;
+
+ /* Transmit the read command. */
+ ret = mdiobus_write(bus, sw_addr, 0, 0x9800 | (addr << 5) | reg);
+ if (ret < 0)
+ return ret;
+
+ /* Wait for the read command to complete. */
+ ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
+ if (ret < 0)
+ return ret;
+
+ /* Read the data. */
+ ret = mdiobus_read(bus, sw_addr, 1);
+ if (ret < 0)
+ return ret;
+
+ return ret & 0xffff;
+}
+
+int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int ret;
+
+ mutex_lock(&ps->smi_mutex);
+ ret = __mv88e6xxx_reg_read(ds->master_mii_bus,
+ ds->pd->sw_addr, addr, reg);
+ mutex_unlock(&ps->smi_mutex);
+
+ return ret;
+}
+
+int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
+ int reg, u16 val)
+{
+ int ret;
+
+ if (sw_addr == 0)
+ return mdiobus_write(bus, addr, reg, val);
+
+ /* Wait for the bus to become free. */
+ ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
+ if (ret < 0)
+ return ret;
+
+ /* Transmit the data to write. */
+ ret = mdiobus_write(bus, sw_addr, 1, val);
+ if (ret < 0)
+ return ret;
+
+ /* Transmit the write command. */
+ ret = mdiobus_write(bus, sw_addr, 0, 0x9400 | (addr << 5) | reg);
+ if (ret < 0)
+ return ret;
+
+ /* Wait for the write command to complete. */
+ ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int ret;
+
+ mutex_lock(&ps->smi_mutex);
+ ret = __mv88e6xxx_reg_write(ds->master_mii_bus,
+ ds->pd->sw_addr, addr, reg, val);
+ mutex_unlock(&ps->smi_mutex);
+
+ return ret;
+}
+
+int mv88e6xxx_config_prio(struct dsa_switch *ds)
+{
+ /* Configure the IP ToS mapping registers. */
+ REG_WRITE(REG_GLOBAL, 0x10, 0x0000);
+ REG_WRITE(REG_GLOBAL, 0x11, 0x0000);
+ REG_WRITE(REG_GLOBAL, 0x12, 0x5555);
+ REG_WRITE(REG_GLOBAL, 0x13, 0x5555);
+ REG_WRITE(REG_GLOBAL, 0x14, 0xaaaa);
+ REG_WRITE(REG_GLOBAL, 0x15, 0xaaaa);
+ REG_WRITE(REG_GLOBAL, 0x16, 0xffff);
+ REG_WRITE(REG_GLOBAL, 0x17, 0xffff);
+
+ /* Configure the IEEE 802.1p priority mapping register. */
+ REG_WRITE(REG_GLOBAL, 0x18, 0xfa41);
+
+ return 0;
+}
+
+int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
+{
+ REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
+ REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
+ REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
+
+ return 0;
+}
+
+int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
+{
+ int i;
+ int ret;
+
+ for (i = 0; i < 6; i++) {
+ int j;
+
+ /* Write the MAC address byte. */
+ REG_WRITE(REG_GLOBAL2, 0x0d, 0x8000 | (i << 8) | addr[i]);
+
+ /* Wait for the write to complete. */
+ for (j = 0; j < 16; j++) {
+ ret = REG_READ(REG_GLOBAL2, 0x0d);
+ if ((ret & 0x8000) == 0)
+ break;
+ }
+ if (j == 16)
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
+{
+ if (addr >= 0)
+ return mv88e6xxx_reg_read(ds, addr, regnum);
+ return 0xffff;
+}
+
+int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val)
+{
+ if (addr >= 0)
+ return mv88e6xxx_reg_write(ds, addr, regnum, val);
+ return 0;
+}
+
+#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
+static int mv88e6xxx_ppu_disable(struct dsa_switch *ds)
+{
+ int ret;
+ unsigned long timeout;
+
+ ret = REG_READ(REG_GLOBAL, 0x04);
+ REG_WRITE(REG_GLOBAL, 0x04, ret & ~0x4000);
+
+ timeout = jiffies + 1 * HZ;
+ while (time_before(jiffies, timeout)) {
+ ret = REG_READ(REG_GLOBAL, 0x00);
+ usleep_range(1000, 2000);
+ if ((ret & 0xc000) != 0xc000)
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int mv88e6xxx_ppu_enable(struct dsa_switch *ds)
+{
+ int ret;
+ unsigned long timeout;
+
+ ret = REG_READ(REG_GLOBAL, 0x04);
+ REG_WRITE(REG_GLOBAL, 0x04, ret | 0x4000);
+
+ timeout = jiffies + 1 * HZ;
+ while (time_before(jiffies, timeout)) {
+ ret = REG_READ(REG_GLOBAL, 0x00);
+ usleep_range(1000, 2000);
+ if ((ret & 0xc000) == 0xc000)
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
+{
+ struct mv88e6xxx_priv_state *ps;
+
+ ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
+ if (mutex_trylock(&ps->ppu_mutex)) {
+ struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1;
+
+ if (mv88e6xxx_ppu_enable(ds) == 0)
+ ps->ppu_disabled = 0;
+ mutex_unlock(&ps->ppu_mutex);
+ }
+}
+
+static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
+{
+ struct mv88e6xxx_priv_state *ps = (void *)_ps;
+
+ schedule_work(&ps->ppu_work);
+}
+
+static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int ret;
+
+ mutex_lock(&ps->ppu_mutex);
+
+ /* If the PHY polling unit is enabled, disable it so that
+ * we can access the PHY registers. If it was already
+ * disabled, cancel the timer that is going to re-enable
+ * it.
+ */
+ if (!ps->ppu_disabled) {
+ ret = mv88e6xxx_ppu_disable(ds);
+ if (ret < 0) {
+ mutex_unlock(&ps->ppu_mutex);
+ return ret;
+ }
+ ps->ppu_disabled = 1;
+ } else {
+ del_timer(&ps->ppu_timer);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+ /* Schedule a timer to re-enable the PHY polling unit. */
+ mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
+ mutex_unlock(&ps->ppu_mutex);
+}
+
+void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+ mutex_init(&ps->ppu_mutex);
+ INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
+ init_timer(&ps->ppu_timer);
+ ps->ppu_timer.data = (unsigned long)ps;
+ ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
+}
+
+int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
+{
+ int ret;
+
+ ret = mv88e6xxx_ppu_access_get(ds);
+ if (ret >= 0) {
+ ret = mv88e6xxx_reg_read(ds, addr, regnum);
+ mv88e6xxx_ppu_access_put(ds);
+ }
+
+ return ret;
+}
+
+int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
+ int regnum, u16 val)
+{
+ int ret;
+
+ ret = mv88e6xxx_ppu_access_get(ds);
+ if (ret >= 0) {
+ ret = mv88e6xxx_reg_write(ds, addr, regnum, val);
+ mv88e6xxx_ppu_access_put(ds);
+ }
+
+ return ret;
+}
+#endif
+
+void mv88e6xxx_poll_link(struct dsa_switch *ds)
+{
+ int i;
+
+ for (i = 0; i < DSA_MAX_PORTS; i++) {
+ struct net_device *dev;
+ int uninitialized_var(port_status);
+ int link;
+ int speed;
+ int duplex;
+ int fc;
+
+ dev = ds->ports[i];
+ if (dev == NULL)
+ continue;
+
+ link = 0;
+ if (dev->flags & IFF_UP) {
+ port_status = mv88e6xxx_reg_read(ds, REG_PORT(i), 0x00);
+ if (port_status < 0)
+ continue;
+
+ link = !!(port_status & 0x0800);
+ }
+
+ if (!link) {
+ if (netif_carrier_ok(dev)) {
+ netdev_info(dev, "link down\n");
+ netif_carrier_off(dev);
+ }
+ continue;
+ }
+
+ switch (port_status & 0x0300) {
+ case 0x0000:
+ speed = 10;
+ break;
+ case 0x0100:
+ speed = 100;
+ break;
+ case 0x0200:
+ speed = 1000;
+ break;
+ default:
+ speed = -1;
+ break;
+ }
+ duplex = (port_status & 0x0400) ? 1 : 0;
+ fc = (port_status & 0x8000) ? 1 : 0;
+
+ if (!netif_carrier_ok(dev)) {
+ netdev_info(dev,
+ "link up, %d Mb/s, %s duplex, flow control %sabled\n",
+ speed,
+ duplex ? "full" : "half",
+ fc ? "en" : "dis");
+ netif_carrier_on(dev);
+ }
+ }
+}
+
+static int mv88e6xxx_stats_wait(struct dsa_switch *ds)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ ret = REG_READ(REG_GLOBAL, 0x1d);
+ if ((ret & 0x8000) == 0)
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port)
+{
+ int ret;
+
+ /* Snapshot the hardware statistics counters for this port. */
+ REG_WRITE(REG_GLOBAL, 0x1d, 0xdc00 | port);
+
+ /* Wait for the snapshotting to complete. */
+ ret = mv88e6xxx_stats_wait(ds);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val)
+{
+ u32 _val;
+ int ret;
+
+ *val = 0;
+
+ ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1d, 0xcc00 | stat);
+ if (ret < 0)
+ return;
+
+ ret = mv88e6xxx_stats_wait(ds);
+ if (ret < 0)
+ return;
+
+ ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1e);
+ if (ret < 0)
+ return;
+
+ _val = ret << 16;
+
+ ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1f);
+ if (ret < 0)
+ return;
+
+ *val = _val | ret;
+}
+
+void mv88e6xxx_get_strings(struct dsa_switch *ds,
+ int nr_stats, struct mv88e6xxx_hw_stat *stats,
+ int port, uint8_t *data)
+{
+ int i;
+
+ for (i = 0; i < nr_stats; i++) {
+ memcpy(data + i * ETH_GSTRING_LEN,
+ stats[i].string, ETH_GSTRING_LEN);
+ }
+}
+
+void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
+ int nr_stats, struct mv88e6xxx_hw_stat *stats,
+ int port, uint64_t *data)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int ret;
+ int i;
+
+ mutex_lock(&ps->stats_mutex);
+
+ ret = mv88e6xxx_stats_snapshot(ds, port);
+ if (ret < 0) {
+ mutex_unlock(&ps->stats_mutex);
+ return;
+ }
+
+ /* Read each of the counters. */
+ for (i = 0; i < nr_stats; i++) {
+ struct mv88e6xxx_hw_stat *s = stats + i;
+ u32 low;
+ u32 high;
+
+ mv88e6xxx_stats_read(ds, s->reg, &low);
+ if (s->sizeof_stat == 8)
+ mv88e6xxx_stats_read(ds, s->reg + 1, &high);
+ else
+ high = 0;
+
+ data[i] = (((u64)high) << 32) | low;
+ }
+
+ mutex_unlock(&ps->stats_mutex);
+}
+
+static int __init mv88e6xxx_init(void)
+{
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
+ register_switch_driver(&mv88e6131_switch_driver);
+#endif
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
+ register_switch_driver(&mv88e6123_61_65_switch_driver);
+#endif
+ return 0;
+}
+module_init(mv88e6xxx_init);
+
+static void __exit mv88e6xxx_cleanup(void)
+{
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
+ unregister_switch_driver(&mv88e6123_61_65_switch_driver);
+#endif
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
+ unregister_switch_driver(&mv88e6131_switch_driver);
+#endif
+}
+module_exit(mv88e6xxx_cleanup);
+
+MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
+MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
new file mode 100644
index 00000000000..911ede58dd1
--- /dev/null
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -0,0 +1,95 @@
+/*
+ * net/dsa/mv88e6xxx.h - Marvell 88e6xxx switch chip support
+ * Copyright (c) 2008 Marvell Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MV88E6XXX_H
+#define __MV88E6XXX_H
+
+#define REG_PORT(p) (0x10 + (p))
+#define REG_GLOBAL 0x1b
+#define REG_GLOBAL2 0x1c
+
+struct mv88e6xxx_priv_state {
+ /* When using multi-chip addressing, this mutex protects
+ * access to the indirect access registers. (In single-chip
+ * mode, this mutex is effectively useless.)
+ */
+ struct mutex smi_mutex;
+
+#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
+ /* Handles automatic disabling and re-enabling of the PHY
+ * polling unit.
+ */
+ struct mutex ppu_mutex;
+ int ppu_disabled;
+ struct work_struct ppu_work;
+ struct timer_list ppu_timer;
+#endif
+
+ /* This mutex serialises access to the statistics unit.
+ * Hold this mutex over snapshot + dump sequences.
+ */
+ struct mutex stats_mutex;
+
+ int id; /* switch product id */
+};
+
+struct mv88e6xxx_hw_stat {
+ char string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int reg;
+};
+
+int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg);
+int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg);
+int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
+ int reg, u16 val);
+int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val);
+int mv88e6xxx_config_prio(struct dsa_switch *ds);
+int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
+int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
+int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum);
+int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val);
+void mv88e6xxx_ppu_state_init(struct dsa_switch *ds);
+int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum);
+int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
+ int regnum, u16 val);
+void mv88e6xxx_poll_link(struct dsa_switch *ds);
+void mv88e6xxx_get_strings(struct dsa_switch *ds,
+ int nr_stats, struct mv88e6xxx_hw_stat *stats,
+ int port, uint8_t *data);
+void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
+ int nr_stats, struct mv88e6xxx_hw_stat *stats,
+ int port, uint64_t *data);
+
+extern struct dsa_switch_driver mv88e6131_switch_driver;
+extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;
+
+#define REG_READ(addr, reg) \
+ ({ \
+ int __ret; \
+ \
+ __ret = mv88e6xxx_reg_read(ds, addr, reg); \
+ if (__ret < 0) \
+ return __ret; \
+ __ret; \
+ })
+
+#define REG_WRITE(addr, reg, val) \
+ ({ \
+ int __ret; \
+ \
+ __ret = mv88e6xxx_reg_write(ds, addr, reg, val); \
+ if (__ret < 0) \
+ return __ret; \
+ })
+
+
+
+#endif
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 84e14f397d9..0932ffbf381 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -36,51 +36,106 @@
#include <linux/moduleparam.h>
#include <linux/rtnetlink.h>
#include <net/rtnetlink.h>
+#include <linux/u64_stats_sync.h>
static int numdummies = 1;
-static int dummy_xmit(struct sk_buff *skb, struct net_device *dev);
+/* fake multicast ability */
+static void set_multicast_list(struct net_device *dev)
+{
+}
+
+struct pcpu_dstats {
+ u64 tx_packets;
+ u64 tx_bytes;
+ struct u64_stats_sync syncp;
+};
+
+static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *stats)
+{
+ int i;
+
+ for_each_possible_cpu(i) {
+ const struct pcpu_dstats *dstats;
+ u64 tbytes, tpackets;
+ unsigned int start;
+
+ dstats = per_cpu_ptr(dev->dstats, i);
+ do {
+ start = u64_stats_fetch_begin_irq(&dstats->syncp);
+ tbytes = dstats->tx_bytes;
+ tpackets = dstats->tx_packets;
+ } while (u64_stats_fetch_retry_irq(&dstats->syncp, start));
+ stats->tx_bytes += tbytes;
+ stats->tx_packets += tpackets;
+ }
+ return stats;
+}
-static int dummy_set_address(struct net_device *dev, void *p)
+static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct sockaddr *sa = p;
+ struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
- if (!is_valid_ether_addr(sa->sa_data))
- return -EADDRNOTAVAIL;
+ u64_stats_update_begin(&dstats->syncp);
+ dstats->tx_packets++;
+ dstats->tx_bytes += skb->len;
+ u64_stats_update_end(&dstats->syncp);
+
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+static int dummy_dev_init(struct net_device *dev)
+{
+ dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
+ if (!dev->dstats)
+ return -ENOMEM;
- memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
return 0;
}
-/* fake multicast ability */
-static void set_multicast_list(struct net_device *dev)
+static void dummy_dev_uninit(struct net_device *dev)
{
+ free_percpu(dev->dstats);
}
+static int dummy_change_carrier(struct net_device *dev, bool new_carrier)
+{
+ if (new_carrier)
+ netif_carrier_on(dev);
+ else
+ netif_carrier_off(dev);
+ return 0;
+}
+
+static const struct net_device_ops dummy_netdev_ops = {
+ .ndo_init = dummy_dev_init,
+ .ndo_uninit = dummy_dev_uninit,
+ .ndo_start_xmit = dummy_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_get_stats64 = dummy_get_stats64,
+ .ndo_change_carrier = dummy_change_carrier,
+};
+
static void dummy_setup(struct net_device *dev)
{
+ ether_setup(dev);
+
/* Initialize the device structure. */
- dev->hard_start_xmit = dummy_xmit;
- dev->set_multicast_list = set_multicast_list;
- dev->set_mac_address = dummy_set_address;
+ dev->netdev_ops = &dummy_netdev_ops;
dev->destructor = free_netdev;
/* Fill in device structure with ethernet-generic values. */
- ether_setup(dev);
dev->tx_queue_len = 0;
- dev->change_mtu = NULL;
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
- random_ether_addr(dev->dev_addr);
-}
-
-static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
-
- dev_kfree_skb(skb);
- return 0;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO;
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
+ eth_hw_addr_random(dev);
}
static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -113,10 +168,6 @@ static int __init dummy_init_one(void)
if (!dev_dummy)
return -ENOMEM;
- err = dev_alloc_name(dev_dummy, dev_dummy->name);
- if (err < 0)
- goto err;
-
dev_dummy->rtnl_link_ops = &dummy_link_ops;
err = register_netdevice(dev_dummy);
if (err < 0)
@@ -134,11 +185,17 @@ static int __init dummy_init_module(void)
rtnl_lock();
err = __rtnl_link_register(&dummy_link_ops);
+ if (err < 0)
+ goto out;
- for (i = 0; i < numdummies && !err; i++)
+ for (i = 0; i < numdummies && !err; i++) {
err = dummy_init_one();
+ cond_resched();
+ }
if (err < 0)
__rtnl_link_unregister(&dummy_link_ops);
+
+out:
rtnl_unlock();
return err;
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
deleted file mode 100644
index d04eef53571..00000000000
--- a/drivers/net/e1000/e1000_hw.c
+++ /dev/null
@@ -1,8878 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* e1000_hw.c
- * Shared functions for accessing and configuring the MAC
- */
-
-
-#include "e1000_hw.h"
-
-static s32 e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask);
-static void e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask);
-static s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 *data);
-static s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 data);
-static s32 e1000_get_software_semaphore(struct e1000_hw *hw);
-static void e1000_release_software_semaphore(struct e1000_hw *hw);
-
-static u8 e1000_arc_subsystem_valid(struct e1000_hw *hw);
-static s32 e1000_check_downshift(struct e1000_hw *hw);
-static s32 e1000_check_polarity(struct e1000_hw *hw,
- e1000_rev_polarity *polarity);
-static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
-static void e1000_clear_vfta(struct e1000_hw *hw);
-static s32 e1000_commit_shadow_ram(struct e1000_hw *hw);
-static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
- bool link_up);
-static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw);
-static s32 e1000_detect_gig_phy(struct e1000_hw *hw);
-static s32 e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank);
-static s32 e1000_get_auto_rd_done(struct e1000_hw *hw);
-static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
- u16 *max_length);
-static s32 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
-static s32 e1000_get_software_flag(struct e1000_hw *hw);
-static s32 e1000_ich8_cycle_init(struct e1000_hw *hw);
-static s32 e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout);
-static s32 e1000_id_led_init(struct e1000_hw *hw);
-static s32 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
- u32 cnf_base_addr,
- u32 cnf_size);
-static s32 e1000_init_lcd_from_nvm(struct e1000_hw *hw);
-static void e1000_init_rx_addrs(struct e1000_hw *hw);
-static void e1000_initialize_hardware_bits(struct e1000_hw *hw);
-static bool e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-static s32 e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
-static s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
-static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
- u16 offset, u8 *sum);
-static s32 e1000_mng_write_cmd_header(struct e1000_hw* hw,
- struct e1000_host_mng_command_header
- *hdr);
-static s32 e1000_mng_write_commit(struct e1000_hw *hw);
-static s32 e1000_phy_ife_get_info(struct e1000_hw *hw,
- struct e1000_phy_info *phy_info);
-static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
- struct e1000_phy_info *phy_info);
-static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data);
-static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data);
-static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
-static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
- struct e1000_phy_info *phy_info);
-static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-static s32 e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8 *data);
-static s32 e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index,
- u8 byte);
-static s32 e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte);
-static s32 e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data);
-static s32 e1000_read_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
- u16 *data);
-static s32 e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
- u16 data);
-static s32 e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data);
-static s32 e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data);
-static void e1000_release_software_flag(struct e1000_hw *hw);
-static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
-static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
-static s32 e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop);
-static void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
-static s32 e1000_wait_autoneg(struct e1000_hw *hw);
-static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value);
-static s32 e1000_set_phy_type(struct e1000_hw *hw);
-static void e1000_phy_init_script(struct e1000_hw *hw);
-static s32 e1000_setup_copper_link(struct e1000_hw *hw);
-static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
-static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
-static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
-static s32 e1000_config_mac_to_phy(struct e1000_hw *hw);
-static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
-static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl);
-static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data,
- u16 count);
-static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw);
-static s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
-static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset,
- u16 words, u16 *data);
-static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
- u16 words, u16 *data);
-static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw);
-static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd);
-static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd);
-static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count);
-static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
- u16 phy_data);
-static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw,u32 reg_addr,
- u16 *phy_data);
-static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count);
-static s32 e1000_acquire_eeprom(struct e1000_hw *hw);
-static void e1000_release_eeprom(struct e1000_hw *hw);
-static void e1000_standby_eeprom(struct e1000_hw *hw);
-static s32 e1000_set_vco_speed(struct e1000_hw *hw);
-static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw);
-static s32 e1000_set_phy_mode(struct e1000_hw *hw);
-static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer);
-static u8 e1000_calculate_mng_checksum(char *buffer, u32 length);
-static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex);
-static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
-static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-
-/* IGP cable length table */
-static const
-u16 e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
- 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
- 90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
-
-static const
-u16 e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
- { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
- 0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
- 6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
- 21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
- 40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
- 60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
- 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
- 104, 109, 114, 118, 121, 124};
-
-static DEFINE_SPINLOCK(e1000_eeprom_lock);
-
-/******************************************************************************
- * Set the phy type member in the hw struct.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static s32 e1000_set_phy_type(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_set_phy_type");
-
- if (hw->mac_type == e1000_undefined)
- return -E1000_ERR_PHY_TYPE;
-
- switch (hw->phy_id) {
- case M88E1000_E_PHY_ID:
- case M88E1000_I_PHY_ID:
- case M88E1011_I_PHY_ID:
- case M88E1111_I_PHY_ID:
- hw->phy_type = e1000_phy_m88;
- break;
- case IGP01E1000_I_PHY_ID:
- if (hw->mac_type == e1000_82541 ||
- hw->mac_type == e1000_82541_rev_2 ||
- hw->mac_type == e1000_82547 ||
- hw->mac_type == e1000_82547_rev_2) {
- hw->phy_type = e1000_phy_igp;
- break;
- }
- case IGP03E1000_E_PHY_ID:
- hw->phy_type = e1000_phy_igp_3;
- break;
- case IFE_E_PHY_ID:
- case IFE_PLUS_E_PHY_ID:
- case IFE_C_E_PHY_ID:
- hw->phy_type = e1000_phy_ife;
- break;
- case GG82563_E_PHY_ID:
- if (hw->mac_type == e1000_80003es2lan) {
- hw->phy_type = e1000_phy_gg82563;
- break;
- }
- /* Fall Through */
- default:
- /* Should never have loaded on this device */
- hw->phy_type = e1000_phy_undefined;
- return -E1000_ERR_PHY_TYPE;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * IGP phy init script - initializes the GbE PHY
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void e1000_phy_init_script(struct e1000_hw *hw)
-{
- u32 ret_val;
- u16 phy_saved_data;
-
- DEBUGFUNC("e1000_phy_init_script");
-
- if (hw->phy_init_script) {
- msleep(20);
-
- /* Save off the current value of register 0x2F5B to be restored at
- * the end of this routine. */
- ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-
- /* Disabled the PHY transmitter */
- e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
-
- msleep(20);
-
- e1000_write_phy_reg(hw,0x0000,0x0140);
-
- msleep(5);
-
- switch (hw->mac_type) {
- case e1000_82541:
- case e1000_82547:
- e1000_write_phy_reg(hw, 0x1F95, 0x0001);
-
- e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
-
- e1000_write_phy_reg(hw, 0x1F79, 0x0018);
-
- e1000_write_phy_reg(hw, 0x1F30, 0x1600);
-
- e1000_write_phy_reg(hw, 0x1F31, 0x0014);
-
- e1000_write_phy_reg(hw, 0x1F32, 0x161C);
-
- e1000_write_phy_reg(hw, 0x1F94, 0x0003);
-
- e1000_write_phy_reg(hw, 0x1F96, 0x003F);
-
- e1000_write_phy_reg(hw, 0x2010, 0x0008);
- break;
-
- case e1000_82541_rev_2:
- case e1000_82547_rev_2:
- e1000_write_phy_reg(hw, 0x1F73, 0x0099);
- break;
- default:
- break;
- }
-
- e1000_write_phy_reg(hw, 0x0000, 0x3300);
-
- msleep(20);
-
- /* Now enable the transmitter */
- e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-
- if (hw->mac_type == e1000_82547) {
- u16 fused, fine, coarse;
-
- /* Move to analog registers page */
- e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
-
- if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
- e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);
-
- fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
- coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
-
- if (coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
- coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
- fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
- } else if (coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
- fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
-
- fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
- (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
- (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
-
- e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
- e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
- IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
- }
- }
- }
-}
-
-/******************************************************************************
- * Set the mac type member in the hw struct.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_set_mac_type(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_set_mac_type");
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82542:
- switch (hw->revision_id) {
- case E1000_82542_2_0_REV_ID:
- hw->mac_type = e1000_82542_rev2_0;
- break;
- case E1000_82542_2_1_REV_ID:
- hw->mac_type = e1000_82542_rev2_1;
- break;
- default:
- /* Invalid 82542 revision ID */
- return -E1000_ERR_MAC_TYPE;
- }
- break;
- case E1000_DEV_ID_82543GC_FIBER:
- case E1000_DEV_ID_82543GC_COPPER:
- hw->mac_type = e1000_82543;
- break;
- case E1000_DEV_ID_82544EI_COPPER:
- case E1000_DEV_ID_82544EI_FIBER:
- case E1000_DEV_ID_82544GC_COPPER:
- case E1000_DEV_ID_82544GC_LOM:
- hw->mac_type = e1000_82544;
- break;
- case E1000_DEV_ID_82540EM:
- case E1000_DEV_ID_82540EM_LOM:
- case E1000_DEV_ID_82540EP:
- case E1000_DEV_ID_82540EP_LOM:
- case E1000_DEV_ID_82540EP_LP:
- hw->mac_type = e1000_82540;
- break;
- case E1000_DEV_ID_82545EM_COPPER:
- case E1000_DEV_ID_82545EM_FIBER:
- hw->mac_type = e1000_82545;
- break;
- case E1000_DEV_ID_82545GM_COPPER:
- case E1000_DEV_ID_82545GM_FIBER:
- case E1000_DEV_ID_82545GM_SERDES:
- hw->mac_type = e1000_82545_rev_3;
- break;
- case E1000_DEV_ID_82546EB_COPPER:
- case E1000_DEV_ID_82546EB_FIBER:
- case E1000_DEV_ID_82546EB_QUAD_COPPER:
- hw->mac_type = e1000_82546;
- break;
- case E1000_DEV_ID_82546GB_COPPER:
- case E1000_DEV_ID_82546GB_FIBER:
- case E1000_DEV_ID_82546GB_SERDES:
- case E1000_DEV_ID_82546GB_PCIE:
- case E1000_DEV_ID_82546GB_QUAD_COPPER:
- case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
- hw->mac_type = e1000_82546_rev_3;
- break;
- case E1000_DEV_ID_82541EI:
- case E1000_DEV_ID_82541EI_MOBILE:
- case E1000_DEV_ID_82541ER_LOM:
- hw->mac_type = e1000_82541;
- break;
- case E1000_DEV_ID_82541ER:
- case E1000_DEV_ID_82541GI:
- case E1000_DEV_ID_82541GI_LF:
- case E1000_DEV_ID_82541GI_MOBILE:
- hw->mac_type = e1000_82541_rev_2;
- break;
- case E1000_DEV_ID_82547EI:
- case E1000_DEV_ID_82547EI_MOBILE:
- hw->mac_type = e1000_82547;
- break;
- case E1000_DEV_ID_82547GI:
- hw->mac_type = e1000_82547_rev_2;
- break;
- case E1000_DEV_ID_82571EB_COPPER:
- case E1000_DEV_ID_82571EB_FIBER:
- case E1000_DEV_ID_82571EB_SERDES:
- case E1000_DEV_ID_82571EB_SERDES_DUAL:
- case E1000_DEV_ID_82571EB_SERDES_QUAD:
- case E1000_DEV_ID_82571EB_QUAD_COPPER:
- case E1000_DEV_ID_82571PT_QUAD_COPPER:
- case E1000_DEV_ID_82571EB_QUAD_FIBER:
- case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
- hw->mac_type = e1000_82571;
- break;
- case E1000_DEV_ID_82572EI_COPPER:
- case E1000_DEV_ID_82572EI_FIBER:
- case E1000_DEV_ID_82572EI_SERDES:
- case E1000_DEV_ID_82572EI:
- hw->mac_type = e1000_82572;
- break;
- case E1000_DEV_ID_82573E:
- case E1000_DEV_ID_82573E_IAMT:
- case E1000_DEV_ID_82573L:
- hw->mac_type = e1000_82573;
- break;
- case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
- case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
- case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
- case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
- hw->mac_type = e1000_80003es2lan;
- break;
- case E1000_DEV_ID_ICH8_IGP_M_AMT:
- case E1000_DEV_ID_ICH8_IGP_AMT:
- case E1000_DEV_ID_ICH8_IGP_C:
- case E1000_DEV_ID_ICH8_IFE:
- case E1000_DEV_ID_ICH8_IFE_GT:
- case E1000_DEV_ID_ICH8_IFE_G:
- case E1000_DEV_ID_ICH8_IGP_M:
- hw->mac_type = e1000_ich8lan;
- break;
- default:
- /* Should never have loaded on this device */
- return -E1000_ERR_MAC_TYPE;
- }
-
- switch (hw->mac_type) {
- case e1000_ich8lan:
- hw->swfwhw_semaphore_present = true;
- hw->asf_firmware_present = true;
- break;
- case e1000_80003es2lan:
- hw->swfw_sync_present = true;
- /* fall through */
- case e1000_82571:
- case e1000_82572:
- case e1000_82573:
- hw->eeprom_semaphore_present = true;
- /* fall through */
- case e1000_82541:
- case e1000_82547:
- case e1000_82541_rev_2:
- case e1000_82547_rev_2:
- hw->asf_firmware_present = true;
- break;
- default:
- break;
- }
-
- /* The 82543 chip does not count tx_carrier_errors properly in
- * FD mode
- */
- if (hw->mac_type == e1000_82543)
- hw->bad_tx_carr_stats_fd = true;
-
- /* capable of receiving management packets to the host */
- if (hw->mac_type >= e1000_82571)
- hw->has_manc2h = true;
-
- /* In rare occasions, ESB2 systems would end up started without
- * the RX unit being turned on.
- */
- if (hw->mac_type == e1000_80003es2lan)
- hw->rx_needs_kicking = true;
-
- if (hw->mac_type > e1000_82544)
- hw->has_smbus = true;
-
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- * Set media type and TBI compatibility.
- *
- * hw - Struct containing variables accessed by shared code
- * **************************************************************************/
-void e1000_set_media_type(struct e1000_hw *hw)
-{
- u32 status;
-
- DEBUGFUNC("e1000_set_media_type");
-
- if (hw->mac_type != e1000_82543) {
- /* tbi_compatibility is only valid on 82543 */
- hw->tbi_compatibility_en = false;
- }
-
- switch (hw->device_id) {
- case E1000_DEV_ID_82545GM_SERDES:
- case E1000_DEV_ID_82546GB_SERDES:
- case E1000_DEV_ID_82571EB_SERDES:
- case E1000_DEV_ID_82571EB_SERDES_DUAL:
- case E1000_DEV_ID_82571EB_SERDES_QUAD:
- case E1000_DEV_ID_82572EI_SERDES:
- case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
- hw->media_type = e1000_media_type_internal_serdes;
- break;
- default:
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- hw->media_type = e1000_media_type_fiber;
- break;
- case e1000_ich8lan:
- case e1000_82573:
- /* The STATUS_TBIMODE bit is reserved or reused for the this
- * device.
- */
- hw->media_type = e1000_media_type_copper;
- break;
- default:
- status = er32(STATUS);
- if (status & E1000_STATUS_TBIMODE) {
- hw->media_type = e1000_media_type_fiber;
- /* tbi_compatibility not valid on fiber */
- hw->tbi_compatibility_en = false;
- } else {
- hw->media_type = e1000_media_type_copper;
- }
- break;
- }
- }
-}
-
-/******************************************************************************
- * Reset the transmit and receive units; mask and clear all interrupts.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_reset_hw(struct e1000_hw *hw)
-{
- u32 ctrl;
- u32 ctrl_ext;
- u32 icr;
- u32 manc;
- u32 led_ctrl;
- u32 timeout;
- u32 extcnf_ctrl;
- s32 ret_val;
-
- DEBUGFUNC("e1000_reset_hw");
-
- /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
- if (hw->mac_type == e1000_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- e1000_pci_clear_mwi(hw);
- }
-
- if (hw->bus_type == e1000_bus_type_pci_express) {
- /* Prevent the PCI-E bus from sticking if there is no TLP connection
- * on the last TLP read/write transaction when MAC is reset.
- */
- if (e1000_disable_pciex_master(hw) != E1000_SUCCESS) {
- DEBUGOUT("PCI-E Master disable polling has failed.\n");
- }
- }
-
- /* Clear interrupt mask to stop board from generating interrupts */
- DEBUGOUT("Masking off all interrupts\n");
- ew32(IMC, 0xffffffff);
-
- /* Disable the Transmit and Receive units. Then delay to allow
- * any pending transactions to complete before we hit the MAC with
- * the global reset.
- */
- ew32(RCTL, 0);
- ew32(TCTL, E1000_TCTL_PSP);
- E1000_WRITE_FLUSH();
-
- /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
- hw->tbi_compatibility_on = false;
-
- /* Delay to allow any outstanding PCI transactions to complete before
- * resetting the device
- */
- msleep(10);
-
- ctrl = er32(CTRL);
-
- /* Must reset the PHY before resetting the MAC */
- if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
- msleep(5);
- }
-
- /* Must acquire the MDIO ownership before MAC reset.
- * Ownership defaults to firmware after a reset. */
- if (hw->mac_type == e1000_82573) {
- timeout = 10;
-
- extcnf_ctrl = er32(EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- do {
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- extcnf_ctrl = er32(EXTCNF_CTRL);
-
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
- break;
- else
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- msleep(2);
- timeout--;
- } while (timeout);
- }
-
- /* Workaround for ICH8 bit corruption issue in FIFO memory */
- if (hw->mac_type == e1000_ich8lan) {
- /* Set Tx and Rx buffer allocation to 8k apiece. */
- ew32(PBA, E1000_PBA_8K);
- /* Set Packet Buffer Size to 16k. */
- ew32(PBS, E1000_PBS_16K);
- }
-
- /* Issue a global reset to the MAC. This will reset the chip's
- * transmit, receive, DMA, and link units. It will not effect
- * the current PCI configuration. The global reset bit is self-
- * clearing, and should clear within a microsecond.
- */
- DEBUGOUT("Issuing a global reset to MAC\n");
-
- switch (hw->mac_type) {
- case e1000_82544:
- case e1000_82540:
- case e1000_82545:
- case e1000_82546:
- case e1000_82541:
- case e1000_82541_rev_2:
- /* These controllers can't ack the 64-bit write when issuing the
- * reset, so use IO-mapping as a workaround to issue the reset */
- E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
- break;
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- /* Reset is performed on a shadow of the control register */
- ew32(CTRL_DUP, (ctrl | E1000_CTRL_RST));
- break;
- case e1000_ich8lan:
- if (!hw->phy_reset_disable &&
- e1000_check_phy_reset_block(hw) == E1000_SUCCESS) {
- /* e1000_ich8lan PHY HW reset requires MAC CORE reset
- * at the same time to make sure the interface between
- * MAC and the external PHY is reset.
- */
- ctrl |= E1000_CTRL_PHY_RST;
- }
-
- e1000_get_software_flag(hw);
- ew32(CTRL, (ctrl | E1000_CTRL_RST));
- msleep(5);
- break;
- default:
- ew32(CTRL, (ctrl | E1000_CTRL_RST));
- break;
- }
-
- /* After MAC reset, force reload of EEPROM to restore power-on settings to
- * device. Later controllers reload the EEPROM automatically, so just wait
- * for reload to complete.
- */
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- case e1000_82544:
- /* Wait for reset to complete */
- udelay(10);
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- ew32(CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH();
- /* Wait for EEPROM reload */
- msleep(2);
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
- /* Wait for EEPROM reload */
- msleep(20);
- break;
- case e1000_82573:
- if (!e1000_is_onboard_nvm_eeprom(hw)) {
- udelay(10);
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- ew32(CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH();
- }
- /* fall through */
- default:
- /* Auto read done will delay 5ms or poll based on mac type */
- ret_val = e1000_get_auto_rd_done(hw);
- if (ret_val)
- return ret_val;
- break;
- }
-
- /* Disable HW ARPs on ASF enabled adapters */
- if (hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) {
- manc = er32(MANC);
- manc &= ~(E1000_MANC_ARP_EN);
- ew32(MANC, manc);
- }
-
- if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- e1000_phy_init_script(hw);
-
- /* Configure activity LED after PHY reset */
- led_ctrl = er32(LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- ew32(LEDCTL, led_ctrl);
- }
-
- /* Clear interrupt mask to stop board from generating interrupts */
- DEBUGOUT("Masking off all interrupts\n");
- ew32(IMC, 0xffffffff);
-
- /* Clear any pending interrupt events. */
- icr = er32(ICR);
-
- /* If MWI was previously enabled, reenable it. */
- if (hw->mac_type == e1000_82542_rev2_0) {
- if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
- e1000_pci_set_mwi(hw);
- }
-
- if (hw->mac_type == e1000_ich8lan) {
- u32 kab = er32(KABGTXD);
- kab |= E1000_KABGTXD_BGSQLBIAS;
- ew32(KABGTXD, kab);
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- *
- * Initialize a number of hardware-dependent bits
- *
- * hw: Struct containing variables accessed by shared code
- *
- * This function contains hardware limitation workarounds for PCI-E adapters
- *
- *****************************************************************************/
-static void e1000_initialize_hardware_bits(struct e1000_hw *hw)
-{
- if ((hw->mac_type >= e1000_82571) && (!hw->initialize_hw_bits_disable)) {
- /* Settings common to all PCI-express silicon */
- u32 reg_ctrl, reg_ctrl_ext;
- u32 reg_tarc0, reg_tarc1;
- u32 reg_tctl;
- u32 reg_txdctl, reg_txdctl1;
-
- /* link autonegotiation/sync workarounds */
- reg_tarc0 = er32(TARC0);
- reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27));
-
- /* Enable not-done TX descriptor counting */
- reg_txdctl = er32(TXDCTL);
- reg_txdctl |= E1000_TXDCTL_COUNT_DESC;
- ew32(TXDCTL, reg_txdctl);
- reg_txdctl1 = er32(TXDCTL1);
- reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC;
- ew32(TXDCTL1, reg_txdctl1);
-
- switch (hw->mac_type) {
- case e1000_82571:
- case e1000_82572:
- /* Clear PHY TX compatible mode bits */
- reg_tarc1 = er32(TARC1);
- reg_tarc1 &= ~((1 << 30)|(1 << 29));
-
- /* link autonegotiation/sync workarounds */
- reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23));
-
- /* TX ring control fixes */
- reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24));
-
- /* Multiple read bit is reversed polarity */
- reg_tctl = er32(TCTL);
- if (reg_tctl & E1000_TCTL_MULR)
- reg_tarc1 &= ~(1 << 28);
- else
- reg_tarc1 |= (1 << 28);
-
- ew32(TARC1, reg_tarc1);
- break;
- case e1000_82573:
- reg_ctrl_ext = er32(CTRL_EXT);
- reg_ctrl_ext &= ~(1 << 23);
- reg_ctrl_ext |= (1 << 22);
-
- /* TX byte count fix */
- reg_ctrl = er32(CTRL);
- reg_ctrl &= ~(1 << 29);
-
- ew32(CTRL_EXT, reg_ctrl_ext);
- ew32(CTRL, reg_ctrl);
- break;
- case e1000_80003es2lan:
- /* improve small packet performace for fiber/serdes */
- if ((hw->media_type == e1000_media_type_fiber) ||
- (hw->media_type == e1000_media_type_internal_serdes)) {
- reg_tarc0 &= ~(1 << 20);
- }
-
- /* Multiple read bit is reversed polarity */
- reg_tctl = er32(TCTL);
- reg_tarc1 = er32(TARC1);
- if (reg_tctl & E1000_TCTL_MULR)
- reg_tarc1 &= ~(1 << 28);
- else
- reg_tarc1 |= (1 << 28);
-
- ew32(TARC1, reg_tarc1);
- break;
- case e1000_ich8lan:
- /* Reduce concurrent DMA requests to 3 from 4 */
- if ((hw->revision_id < 3) ||
- ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
- (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))
- reg_tarc0 |= ((1 << 29)|(1 << 28));
-
- reg_ctrl_ext = er32(CTRL_EXT);
- reg_ctrl_ext |= (1 << 22);
- ew32(CTRL_EXT, reg_ctrl_ext);
-
- /* workaround TX hang with TSO=on */
- reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23));
-
- /* Multiple read bit is reversed polarity */
- reg_tctl = er32(TCTL);
- reg_tarc1 = er32(TARC1);
- if (reg_tctl & E1000_TCTL_MULR)
- reg_tarc1 &= ~(1 << 28);
- else
- reg_tarc1 |= (1 << 28);
-
- /* workaround TX hang with TSO=on */
- reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24));
-
- ew32(TARC1, reg_tarc1);
- break;
- default:
- break;
- }
-
- ew32(TARC0, reg_tarc0);
- }
-}
-
-/******************************************************************************
- * Performs basic configuration of the adapter.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Assumes that the controller has previously been reset and is in a
- * post-reset uninitialized state. Initializes the receive address registers,
- * multicast table, and VLAN filter table. Calls routines to setup link
- * configuration and flow control settings. Clears all on-chip counters. Leaves
- * the transmit and receive units disabled and uninitialized.
- *****************************************************************************/
-s32 e1000_init_hw(struct e1000_hw *hw)
-{
- u32 ctrl;
- u32 i;
- s32 ret_val;
- u32 mta_size;
- u32 reg_data;
- u32 ctrl_ext;
-
- DEBUGFUNC("e1000_init_hw");
-
- /* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */
- if ((hw->mac_type == e1000_ich8lan) &&
- ((hw->revision_id < 3) ||
- ((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) &&
- (hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) {
- reg_data = er32(STATUS);
- reg_data &= ~0x80000000;
- ew32(STATUS, reg_data);
- }
-
- /* Initialize Identification LED */
- ret_val = e1000_id_led_init(hw);
- if (ret_val) {
- DEBUGOUT("Error Initializing Identification LED\n");
- return ret_val;
- }
-
- /* Set the media type and TBI compatibility */
- e1000_set_media_type(hw);
-
- /* Must be called after e1000_set_media_type because media_type is used */
- e1000_initialize_hardware_bits(hw);
-
- /* Disabling VLAN filtering. */
- DEBUGOUT("Initializing the IEEE VLAN\n");
- /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
- if (hw->mac_type != e1000_ich8lan) {
- if (hw->mac_type < e1000_82545_rev_3)
- ew32(VET, 0);
- e1000_clear_vfta(hw);
- }
-
- /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
- if (hw->mac_type == e1000_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- e1000_pci_clear_mwi(hw);
- ew32(RCTL, E1000_RCTL_RST);
- E1000_WRITE_FLUSH();
- msleep(5);
- }
-
- /* Setup the receive address. This involves initializing all of the Receive
- * Address Registers (RARs 0 - 15).
- */
- e1000_init_rx_addrs(hw);
-
- /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
- if (hw->mac_type == e1000_82542_rev2_0) {
- ew32(RCTL, 0);
- E1000_WRITE_FLUSH();
- msleep(1);
- if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
- e1000_pci_set_mwi(hw);
- }
-
- /* Zero out the Multicast HASH table */
- DEBUGOUT("Zeroing the MTA\n");
- mta_size = E1000_MC_TBL_SIZE;
- if (hw->mac_type == e1000_ich8lan)
- mta_size = E1000_MC_TBL_SIZE_ICH8LAN;
- for (i = 0; i < mta_size; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
- /* use write flush to prevent Memory Write Block (MWB) from
- * occuring when accessing our register space */
- E1000_WRITE_FLUSH();
- }
-
- /* Set the PCI priority bit correctly in the CTRL register. This
- * determines if the adapter gives priority to receives, or if it
- * gives equal priority to transmits and receives. Valid only on
- * 82542 and 82543 silicon.
- */
- if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
- ctrl = er32(CTRL);
- ew32(CTRL, ctrl | E1000_CTRL_PRIOR);
- }
-
- switch (hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
- default:
- /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
- if (hw->bus_type == e1000_bus_type_pcix && e1000_pcix_get_mmrbc(hw) > 2048)
- e1000_pcix_set_mmrbc(hw, 2048);
- break;
- }
-
- /* More time needed for PHY to initialize */
- if (hw->mac_type == e1000_ich8lan)
- msleep(15);
-
- /* Call a subroutine to configure the link and setup flow control. */
- ret_val = e1000_setup_link(hw);
-
- /* Set the transmit descriptor write-back policy */
- if (hw->mac_type > e1000_82544) {
- ctrl = er32(TXDCTL);
- ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- ew32(TXDCTL, ctrl);
- }
-
- if (hw->mac_type == e1000_82573) {
- e1000_enable_tx_pkt_filtering(hw);
- }
-
- switch (hw->mac_type) {
- default:
- break;
- case e1000_80003es2lan:
- /* Enable retransmit on late collisions */
- reg_data = er32(TCTL);
- reg_data |= E1000_TCTL_RTLC;
- ew32(TCTL, reg_data);
-
- /* Configure Gigabit Carry Extend Padding */
- reg_data = er32(TCTL_EXT);
- reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;
- reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX;
- ew32(TCTL_EXT, reg_data);
-
- /* Configure Transmit Inter-Packet Gap */
- reg_data = er32(TIPG);
- reg_data &= ~E1000_TIPG_IPGT_MASK;
- reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
- ew32(TIPG, reg_data);
-
- reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001);
- reg_data &= ~0x00100000;
- E1000_WRITE_REG_ARRAY(hw, FFLT, 0x0001, reg_data);
- /* Fall through */
- case e1000_82571:
- case e1000_82572:
- case e1000_ich8lan:
- ctrl = er32(TXDCTL1);
- ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
- ew32(TXDCTL1, ctrl);
- break;
- }
-
-
- if (hw->mac_type == e1000_82573) {
- u32 gcr = er32(GCR);
- gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
- ew32(GCR, gcr);
- }
-
- /* Clear all of the statistics registers (clear on read). It is
- * important that we do this after we have tried to establish link
- * because the symbol error count will increment wildly if there
- * is no link.
- */
- e1000_clear_hw_cntrs(hw);
-
- /* ICH8 No-snoop bits are opposite polarity.
- * Set to snoop by default after reset. */
- if (hw->mac_type == e1000_ich8lan)
- e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL);
-
- if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
- hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
- ctrl_ext = er32(CTRL_EXT);
- /* Relaxed ordering must be disabled to avoid a parity
- * error crash in a PCI slot. */
- ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
- ew32(CTRL_EXT, ctrl_ext);
- }
-
- return ret_val;
-}
-
-/******************************************************************************
- * Adjust SERDES output amplitude based on EEPROM setting.
- *
- * hw - Struct containing variables accessed by shared code.
- *****************************************************************************/
-static s32 e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
-{
- u16 eeprom_data;
- s32 ret_val;
-
- DEBUGFUNC("e1000_adjust_serdes_amplitude");
-
- if (hw->media_type != e1000_media_type_internal_serdes)
- return E1000_SUCCESS;
-
- switch (hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
- default:
- return E1000_SUCCESS;
- }
-
- ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1, &eeprom_data);
- if (ret_val) {
- return ret_val;
- }
-
- if (eeprom_data != EEPROM_RESERVED_WORD) {
- /* Adjust SERDES output amplitude only. */
- eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
- if (ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Configures flow control and link settings.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Determines which flow control settings to use. Calls the apropriate media-
- * specific link configuration function. Configures the flow control settings.
- * Assuming the adapter has a valid link partner, a valid link should be
- * established. Assumes the hardware has previously been reset and the
- * transmitter and receiver are not enabled.
- *****************************************************************************/
-s32 e1000_setup_link(struct e1000_hw *hw)
-{
- u32 ctrl_ext;
- s32 ret_val;
- u16 eeprom_data;
-
- DEBUGFUNC("e1000_setup_link");
-
- /* In the case of the phy reset being blocked, we already have a link.
- * We do not have to set it up again. */
- if (e1000_check_phy_reset_block(hw))
- return E1000_SUCCESS;
-
- /* Read and store word 0x0F of the EEPROM. This word contains bits
- * that determine the hardware's default PAUSE (flow control) mode,
- * a bit that determines whether the HW defaults to enabling or
- * disabling auto-negotiation, and the direction of the
- * SW defined pins. If there is no SW over-ride of the flow
- * control setting, then the variable hw->fc will
- * be initialized based on a value in the EEPROM.
- */
- if (hw->fc == E1000_FC_DEFAULT) {
- switch (hw->mac_type) {
- case e1000_ich8lan:
- case e1000_82573:
- hw->fc = E1000_FC_FULL;
- break;
- default:
- ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
- 1, &eeprom_data);
- if (ret_val) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
- hw->fc = E1000_FC_NONE;
- else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
- EEPROM_WORD0F_ASM_DIR)
- hw->fc = E1000_FC_TX_PAUSE;
- else
- hw->fc = E1000_FC_FULL;
- break;
- }
- }
-
- /* We want to save off the original Flow Control configuration just
- * in case we get disconnected and then reconnected into a different
- * hub or switch with different Flow Control capabilities.
- */
- if (hw->mac_type == e1000_82542_rev2_0)
- hw->fc &= (~E1000_FC_TX_PAUSE);
-
- if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
- hw->fc &= (~E1000_FC_RX_PAUSE);
-
- hw->original_fc = hw->fc;
-
- DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc);
-
- /* Take the 4 bits from EEPROM word 0x0F that determine the initial
- * polarity value for the SW controlled pins, and setup the
- * Extended Device Control reg with that info.
- * This is needed because one of the SW controlled pins is used for
- * signal detection. So this should be done before e1000_setup_pcs_link()
- * or e1000_phy_setup() is called.
- */
- if (hw->mac_type == e1000_82543) {
- ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
- 1, &eeprom_data);
- if (ret_val) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
- SWDPIO__EXT_SHIFT);
- ew32(CTRL_EXT, ctrl_ext);
- }
-
- /* Call the necessary subroutine to configure the link. */
- ret_val = (hw->media_type == e1000_media_type_copper) ?
- e1000_setup_copper_link(hw) :
- e1000_setup_fiber_serdes_link(hw);
-
- /* Initialize the flow control address, type, and PAUSE timer
- * registers to their default values. This is done even if flow
- * control is disabled, because it does not hurt anything to
- * initialize these registers.
- */
- DEBUGOUT("Initializing the Flow Control address, type and timer regs\n");
-
- /* FCAL/H and FCT are hardcoded to standard values in e1000_ich8lan. */
- if (hw->mac_type != e1000_ich8lan) {
- ew32(FCT, FLOW_CONTROL_TYPE);
- ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
- ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
- }
-
- ew32(FCTTV, hw->fc_pause_time);
-
- /* Set the flow control receive threshold registers. Normally,
- * these registers will be set to a default threshold that may be
- * adjusted later by the driver's runtime code. However, if the
- * ability to transmit pause frames in not enabled, then these
- * registers will be set to 0.
- */
- if (!(hw->fc & E1000_FC_TX_PAUSE)) {
- ew32(FCRTL, 0);
- ew32(FCRTH, 0);
- } else {
- /* We need to set up the Receive Threshold high and low water marks
- * as well as (optionally) enabling the transmission of XON frames.
- */
- if (hw->fc_send_xon) {
- ew32(FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
- ew32(FCRTH, hw->fc_high_water);
- } else {
- ew32(FCRTL, hw->fc_low_water);
- ew32(FCRTH, hw->fc_high_water);
- }
- }
- return ret_val;
-}
-
-/******************************************************************************
- * Sets up link for a fiber based or serdes based adapter
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Manipulates Physical Coding Sublayer functions in order to configure
- * link. Assumes the hardware has been previously reset and the transmitter
- * and receiver are not enabled.
- *****************************************************************************/
-static s32 e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
-{
- u32 ctrl;
- u32 status;
- u32 txcw = 0;
- u32 i;
- u32 signal = 0;
- s32 ret_val;
-
- DEBUGFUNC("e1000_setup_fiber_serdes_link");
-
- /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
- * until explicitly turned off or a power cycle is performed. A read to
- * the register does not indicate its status. Therefore, we ensure
- * loopback mode is disabled during initialization.
- */
- if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
- ew32(SCTL, E1000_DISABLE_SERDES_LOOPBACK);
-
- /* On adapters with a MAC newer than 82544, SWDP 1 will be
- * set when the optics detect a signal. On older adapters, it will be
- * cleared when there is a signal. This applies to fiber media only.
- * If we're on serdes media, adjust the output amplitude to value
- * set in the EEPROM.
- */
- ctrl = er32(CTRL);
- if (hw->media_type == e1000_media_type_fiber)
- signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
-
- ret_val = e1000_adjust_serdes_amplitude(hw);
- if (ret_val)
- return ret_val;
-
- /* Take the link out of reset */
- ctrl &= ~(E1000_CTRL_LRST);
-
- /* Adjust VCO speed to improve BER performance */
- ret_val = e1000_set_vco_speed(hw);
- if (ret_val)
- return ret_val;
-
- e1000_config_collision_dist(hw);
-
- /* Check for a software override of the flow control settings, and setup
- * the device accordingly. If auto-negotiation is enabled, then software
- * will have to set the "PAUSE" bits to the correct value in the Tranmsit
- * Config Word Register (TXCW) and re-start auto-negotiation. However, if
- * auto-negotiation is disabled, then software will have to manually
- * configure the two flow control enable bits in the CTRL register.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames, but
- * not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but we do
- * not support receiving pause frames).
- * 3: Both Rx and TX flow control (symmetric) are enabled.
- */
- switch (hw->fc) {
- case E1000_FC_NONE:
- /* Flow control is completely disabled by a software over-ride. */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
- break;
- case E1000_FC_RX_PAUSE:
- /* RX Flow control is enabled and TX Flow control is disabled by a
- * software over-ride. Since there really isn't a way to advertise
- * that we are capable of RX Pause ONLY, we will advertise that we
- * support both symmetric and asymmetric RX PAUSE. Later, we will
- * disable the adapter's ability to send PAUSE frames.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- case E1000_FC_TX_PAUSE:
- /* TX Flow control is enabled, and RX Flow control is disabled, by a
- * software over-ride.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
- break;
- case E1000_FC_FULL:
- /* Flow control (both RX and TX) is enabled by a software over-ride. */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- break;
- }
-
- /* Since auto-negotiation is enabled, take the link out of reset (the link
- * will be in reset, because we previously reset the chip). This will
- * restart auto-negotiation. If auto-neogtiation is successful then the
- * link-up status bit will be set and the flow control enable bits (RFCE
- * and TFCE) will be set according to their negotiated value.
- */
- DEBUGOUT("Auto-negotiation enabled\n");
-
- ew32(TXCW, txcw);
- ew32(CTRL, ctrl);
- E1000_WRITE_FLUSH();
-
- hw->txcw = txcw;
- msleep(1);
-
- /* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
- * indication in the Device Status Register. Time-out if a link isn't
- * seen in 500 milliseconds seconds (Auto-negotiation should complete in
- * less than 500 milliseconds even if the other end is doing it in SW).
- * For internal serdes, we just assume a signal is present, then poll.
- */
- if (hw->media_type == e1000_media_type_internal_serdes ||
- (er32(CTRL) & E1000_CTRL_SWDPIN1) == signal) {
- DEBUGOUT("Looking for Link\n");
- for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
- msleep(10);
- status = er32(STATUS);
- if (status & E1000_STATUS_LU) break;
- }
- if (i == (LINK_UP_TIMEOUT / 10)) {
- DEBUGOUT("Never got a valid link from auto-neg!!!\n");
- hw->autoneg_failed = 1;
- /* AutoNeg failed to achieve a link, so we'll call
- * e1000_check_for_link. This routine will force the link up if
- * we detect a signal. This will allow us to communicate with
- * non-autonegotiating link partners.
- */
- ret_val = e1000_check_for_link(hw);
- if (ret_val) {
- DEBUGOUT("Error while checking for link\n");
- return ret_val;
- }
- hw->autoneg_failed = 0;
- } else {
- hw->autoneg_failed = 0;
- DEBUGOUT("Valid Link Found\n");
- }
- } else {
- DEBUGOUT("No Signal Detected\n");
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Make sure we have a valid PHY and change PHY mode before link setup.
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_copper_link_preconfig(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_copper_link_preconfig");
-
- ctrl = er32(CTRL);
- /* With 82543, we need to force speed and duplex on the MAC equal to what
- * the PHY speed and duplex configuration is. In addition, we need to
- * perform a hardware reset on the PHY to take it out of reset.
- */
- if (hw->mac_type > e1000_82543) {
- ctrl |= E1000_CTRL_SLU;
- ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ew32(CTRL, ctrl);
- } else {
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
- ew32(CTRL, ctrl);
- ret_val = e1000_phy_hw_reset(hw);
- if (ret_val)
- return ret_val;
- }
-
- /* Make sure we have a valid PHY */
- ret_val = e1000_detect_gig_phy(hw);
- if (ret_val) {
- DEBUGOUT("Error, did not detect valid phy.\n");
- return ret_val;
- }
- DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
-
- /* Set PHY to class A mode (if necessary) */
- ret_val = e1000_set_phy_mode(hw);
- if (ret_val)
- return ret_val;
-
- if ((hw->mac_type == e1000_82545_rev_3) ||
- (hw->mac_type == e1000_82546_rev_3)) {
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- phy_data |= 0x00000008;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- }
-
- if (hw->mac_type <= e1000_82543 ||
- hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
- hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
- hw->phy_reset_disable = false;
-
- return E1000_SUCCESS;
-}
-
-
-/********************************************************************
-* Copper link setup for e1000_phy_igp series.
-*
-* hw - Struct containing variables accessed by shared code
-*********************************************************************/
-static s32 e1000_copper_link_igp_setup(struct e1000_hw *hw)
-{
- u32 led_ctrl;
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_copper_link_igp_setup");
-
- if (hw->phy_reset_disable)
- return E1000_SUCCESS;
-
- ret_val = e1000_phy_reset(hw);
- if (ret_val) {
- DEBUGOUT("Error Resetting the PHY\n");
- return ret_val;
- }
-
- /* Wait 15ms for MAC to configure PHY from eeprom settings */
- msleep(15);
- if (hw->mac_type != e1000_ich8lan) {
- /* Configure activity LED after PHY reset */
- led_ctrl = er32(LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- ew32(LEDCTL, led_ctrl);
- }
-
- /* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
- if (hw->phy_type == e1000_phy_igp) {
- /* disable lplu d3 during driver init */
- ret_val = e1000_set_d3_lplu_state(hw, false);
- if (ret_val) {
- DEBUGOUT("Error Disabling LPLU D3\n");
- return ret_val;
- }
- }
-
- /* disable lplu d0 during driver init */
- ret_val = e1000_set_d0_lplu_state(hw, false);
- if (ret_val) {
- DEBUGOUT("Error Disabling LPLU D0\n");
- return ret_val;
- }
- /* Configure mdi-mdix settings */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- hw->dsp_config_state = e1000_dsp_config_disabled;
- /* Force MDI for earlier revs of the IGP PHY */
- phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX);
- hw->mdix = 1;
-
- } else {
- hw->dsp_config_state = e1000_dsp_config_enabled;
- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
-
- switch (hw->mdix) {
- case 1:
- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 2:
- phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 0:
- default:
- phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
- break;
- }
- }
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* set auto-master slave resolution settings */
- if (hw->autoneg) {
- e1000_ms_type phy_ms_setting = hw->master_slave;
-
- if (hw->ffe_config_state == e1000_ffe_config_active)
- hw->ffe_config_state = e1000_ffe_config_enabled;
-
- if (hw->dsp_config_state == e1000_dsp_config_activated)
- hw->dsp_config_state = e1000_dsp_config_enabled;
-
- /* when autonegotiation advertisment is only 1000Mbps then we
- * should disable SmartSpeed and enable Auto MasterSlave
- * resolution as hardware default. */
- if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
- /* Disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if (ret_val)
- return ret_val;
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if (ret_val)
- return ret_val;
- /* Set auto Master/Slave resolution process */
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
- phy_data &= ~CR_1000T_MS_ENABLE;
- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
- if (ret_val)
- return ret_val;
- }
-
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- /* load defaults for future use */
- hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
- ((phy_data & CR_1000T_MS_VALUE) ?
- e1000_ms_force_master :
- e1000_ms_force_slave) :
- e1000_ms_auto;
-
- switch (phy_ms_setting) {
- case e1000_ms_force_master:
- phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
- break;
- case e1000_ms_force_slave:
- phy_data |= CR_1000T_MS_ENABLE;
- phy_data &= ~(CR_1000T_MS_VALUE);
- break;
- case e1000_ms_auto:
- phy_data &= ~CR_1000T_MS_ENABLE;
- default:
- break;
- }
- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
- if (ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/********************************************************************
-* Copper link setup for e1000_phy_gg82563 series.
-*
-* hw - Struct containing variables accessed by shared code
-*********************************************************************/
-static s32 e1000_copper_link_ggp_setup(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_data;
- u32 reg_data;
-
- DEBUGFUNC("e1000_copper_link_ggp_setup");
-
- if (!hw->phy_reset_disable) {
-
- /* Enable CRS on TX for half-duplex operation. */
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
- /* Use 25MHz for both link down and 1000BASE-T for Tx clock */
- phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
-
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
- phy_data);
- if (ret_val)
- return ret_val;
-
- /* Options:
- * MDI/MDI-X = 0 (default)
- * 0 - Auto for all speeds
- * 1 - MDI mode
- * 2 - MDI-X mode
- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
- */
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
-
- switch (hw->mdix) {
- case 1:
- phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
- break;
- case 2:
- phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDIX;
- break;
- case 0:
- default:
- phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
- break;
- }
-
- /* Options:
- * disable_polarity_correction = 0 (default)
- * Automatic Correction for Reversed Cable Polarity
- * 0 - Disabled
- * 1 - Enabled
- */
- phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
- if (hw->disable_polarity_correction == 1)
- phy_data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data);
-
- if (ret_val)
- return ret_val;
-
- /* SW Reset the PHY so all changes take effect */
- ret_val = e1000_phy_reset(hw);
- if (ret_val) {
- DEBUGOUT("Error Resetting the PHY\n");
- return ret_val;
- }
- } /* phy_reset_disable */
-
- if (hw->mac_type == e1000_80003es2lan) {
- /* Bypass RX and TX FIFO's */
- ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL,
- E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS |
- E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, phy_data);
-
- if (ret_val)
- return ret_val;
-
- reg_data = er32(CTRL_EXT);
- reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
- ew32(CTRL_EXT, reg_data);
-
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Do not init these registers when the HW is in IAMT mode, since the
- * firmware will have already initialized them. We only initialize
- * them if the HW is not in IAMT mode.
- */
- if (!e1000_check_mng_mode(hw)) {
- /* Enable Electrical Idle on the PHY */
- phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
- phy_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
- phy_data);
-
- if (ret_val)
- return ret_val;
- }
-
- /* Workaround: Disable padding in Kumeran interface in the MAC
- * and in the PHY to avoid CRC errors.
- */
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_INBAND_CTRL,
- &phy_data);
- if (ret_val)
- return ret_val;
- phy_data |= GG82563_ICR_DIS_PADDING;
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_INBAND_CTRL,
- phy_data);
- if (ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/********************************************************************
-* Copper link setup for e1000_phy_m88 series.
-*
-* hw - Struct containing variables accessed by shared code
-*********************************************************************/
-static s32 e1000_copper_link_mgp_setup(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_copper_link_mgp_setup");
-
- if (hw->phy_reset_disable)
- return E1000_SUCCESS;
-
- /* Enable CRS on TX. This must be set for half-duplex operation. */
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-
- /* Options:
- * MDI/MDI-X = 0 (default)
- * 0 - Auto for all speeds
- * 1 - MDI mode
- * 2 - MDI-X mode
- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-
- switch (hw->mdix) {
- case 1:
- phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
- break;
- case 2:
- phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
- break;
- case 3:
- phy_data |= M88E1000_PSCR_AUTO_X_1000T;
- break;
- case 0:
- default:
- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
- break;
- }
-
- /* Options:
- * disable_polarity_correction = 0 (default)
- * Automatic Correction for Reversed Cable Polarity
- * 0 - Disabled
- * 1 - Enabled
- */
- phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
- if (hw->disable_polarity_correction == 1)
- phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- if (hw->phy_revision < M88E1011_I_REV_4) {
- /* Force TX_CLK in the Extended PHY Specific Control Register
- * to 25MHz clock.
- */
- ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
-
- if ((hw->phy_revision == E1000_REVISION_2) &&
- (hw->phy_id == M88E1111_I_PHY_ID)) {
- /* Vidalia Phy, set the downshift counter to 5x */
- phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
- phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
- ret_val = e1000_write_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
- } else {
- /* Configure Master and Slave downshift values */
- phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
- phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
- ret_val = e1000_write_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
- }
- }
-
- /* SW Reset the PHY so all changes take effect */
- ret_val = e1000_phy_reset(hw);
- if (ret_val) {
- DEBUGOUT("Error Resetting the PHY\n");
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/********************************************************************
-* Setup auto-negotiation and flow control advertisements,
-* and then perform auto-negotiation.
-*
-* hw - Struct containing variables accessed by shared code
-*********************************************************************/
-static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_copper_link_autoneg");
-
- /* Perform some bounds checking on the hw->autoneg_advertised
- * parameter. If this variable is zero, then set it to the default.
- */
- hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
-
- /* If autoneg_advertised is zero, we assume it was not defaulted
- * by the calling code so we set to advertise full capability.
- */
- if (hw->autoneg_advertised == 0)
- hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-
- /* IFE phy only supports 10/100 */
- if (hw->phy_type == e1000_phy_ife)
- hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL;
-
- DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
- ret_val = e1000_phy_setup_autoneg(hw);
- if (ret_val) {
- DEBUGOUT("Error Setting up Auto-Negotiation\n");
- return ret_val;
- }
- DEBUGOUT("Restarting Auto-Neg\n");
-
- /* Restart auto-negotiation by setting the Auto Neg Enable bit and
- * the Auto Neg Restart bit in the PHY control register.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* Does the user want to wait for Auto-Neg to complete here, or
- * check at a later time (for example, callback routine).
- */
- if (hw->wait_autoneg_complete) {
- ret_val = e1000_wait_autoneg(hw);
- if (ret_val) {
- DEBUGOUT("Error while waiting for autoneg to complete\n");
- return ret_val;
- }
- }
-
- hw->get_link_status = true;
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Config the MAC and the PHY after link is up.
-* 1) Set up the MAC to the current PHY speed/duplex
-* if we are on 82543. If we
-* are on newer silicon, we only need to configure
-* collision distance in the Transmit Control Register.
-* 2) Set up flow control on the MAC to that established with
-* the link partner.
-* 3) Config DSP to improve Gigabit link quality for some PHY revisions.
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_copper_link_postconfig(struct e1000_hw *hw)
-{
- s32 ret_val;
- DEBUGFUNC("e1000_copper_link_postconfig");
-
- if (hw->mac_type >= e1000_82544) {
- e1000_config_collision_dist(hw);
- } else {
- ret_val = e1000_config_mac_to_phy(hw);
- if (ret_val) {
- DEBUGOUT("Error configuring MAC to PHY settings\n");
- return ret_val;
- }
- }
- ret_val = e1000_config_fc_after_link_up(hw);
- if (ret_val) {
- DEBUGOUT("Error Configuring Flow Control\n");
- return ret_val;
- }
-
- /* Config DSP to improve Giga link quality */
- if (hw->phy_type == e1000_phy_igp) {
- ret_val = e1000_config_dsp_after_link_change(hw, true);
- if (ret_val) {
- DEBUGOUT("Error Configuring DSP after link up\n");
- return ret_val;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Detects which PHY is present and setup the speed and duplex
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_setup_copper_link(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 i;
- u16 phy_data;
- u16 reg_data;
-
- DEBUGFUNC("e1000_setup_copper_link");
-
- switch (hw->mac_type) {
- case e1000_80003es2lan:
- case e1000_ich8lan:
- /* Set the mac to wait the maximum time between each
- * iteration and increase the max iterations when
- * polling the phy; this fixes erroneous timeouts at 10Mbps. */
- ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
- if (ret_val)
- return ret_val;
- ret_val = e1000_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);
- if (ret_val)
- return ret_val;
- reg_data |= 0x3F;
- ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);
- if (ret_val)
- return ret_val;
- default:
- break;
- }
-
- /* Check if it is a valid PHY and set PHY mode if necessary. */
- ret_val = e1000_copper_link_preconfig(hw);
- if (ret_val)
- return ret_val;
-
- switch (hw->mac_type) {
- case e1000_80003es2lan:
- /* Kumeran registers are written-only */
- reg_data = E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT;
- reg_data |= E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING;
- ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_INB_CTRL,
- reg_data);
- if (ret_val)
- return ret_val;
- break;
- default:
- break;
- }
-
- if (hw->phy_type == e1000_phy_igp ||
- hw->phy_type == e1000_phy_igp_3 ||
- hw->phy_type == e1000_phy_igp_2) {
- ret_val = e1000_copper_link_igp_setup(hw);
- if (ret_val)
- return ret_val;
- } else if (hw->phy_type == e1000_phy_m88) {
- ret_val = e1000_copper_link_mgp_setup(hw);
- if (ret_val)
- return ret_val;
- } else if (hw->phy_type == e1000_phy_gg82563) {
- ret_val = e1000_copper_link_ggp_setup(hw);
- if (ret_val)
- return ret_val;
- }
-
- if (hw->autoneg) {
- /* Setup autoneg and flow control advertisement
- * and perform autonegotiation */
- ret_val = e1000_copper_link_autoneg(hw);
- if (ret_val)
- return ret_val;
- } else {
- /* PHY will be set to 10H, 10F, 100H,or 100F
- * depending on value from forced_speed_duplex. */
- DEBUGOUT("Forcing speed and duplex\n");
- ret_val = e1000_phy_force_speed_duplex(hw);
- if (ret_val) {
- DEBUGOUT("Error Forcing Speed and Duplex\n");
- return ret_val;
- }
- }
-
- /* Check link status. Wait up to 100 microseconds for link to become
- * valid.
- */
- for (i = 0; i < 10; i++) {
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- if (phy_data & MII_SR_LINK_STATUS) {
- /* Config the MAC and PHY after link is up */
- ret_val = e1000_copper_link_postconfig(hw);
- if (ret_val)
- return ret_val;
-
- DEBUGOUT("Valid link established!!!\n");
- return E1000_SUCCESS;
- }
- udelay(10);
- }
-
- DEBUGOUT("Unable to establish link!!!\n");
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Configure the MAC-to-PHY interface for 10/100Mbps
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex)
-{
- s32 ret_val = E1000_SUCCESS;
- u32 tipg;
- u16 reg_data;
-
- DEBUGFUNC("e1000_configure_kmrn_for_10_100");
-
- reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT;
- ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL,
- reg_data);
- if (ret_val)
- return ret_val;
-
- /* Configure Transmit Inter-Packet Gap */
- tipg = er32(TIPG);
- tipg &= ~E1000_TIPG_IPGT_MASK;
- tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100;
- ew32(TIPG, tipg);
-
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
-
- if (ret_val)
- return ret_val;
-
- if (duplex == HALF_DUPLEX)
- reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
- else
- reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
-
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
-
- return ret_val;
-}
-
-static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
- u16 reg_data;
- u32 tipg;
-
- DEBUGFUNC("e1000_configure_kmrn_for_1000");
-
- reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT;
- ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL,
- reg_data);
- if (ret_val)
- return ret_val;
-
- /* Configure Transmit Inter-Packet Gap */
- tipg = er32(TIPG);
- tipg &= ~E1000_TIPG_IPGT_MASK;
- tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
- ew32(TIPG, tipg);
-
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
-
- if (ret_val)
- return ret_val;
-
- reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
-
- return ret_val;
-}
-
-/******************************************************************************
-* Configures PHY autoneg and flow control advertisement settings
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 mii_autoneg_adv_reg;
- u16 mii_1000t_ctrl_reg;
-
- DEBUGFUNC("e1000_phy_setup_autoneg");
-
- /* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
- if (ret_val)
- return ret_val;
-
- if (hw->phy_type != e1000_phy_ife) {
- /* Read the MII 1000Base-T Control Register (Address 9). */
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
- if (ret_val)
- return ret_val;
- } else
- mii_1000t_ctrl_reg=0;
-
- /* Need to parse both autoneg_advertised and fc and set up
- * the appropriate PHY registers. First we will parse for
- * autoneg_advertised software override. Since we can advertise
- * a plethora of combinations, we need to check each bit
- * individually.
- */
-
- /* First we clear all the 10/100 mb speed bits in the Auto-Neg
- * Advertisement Register (Address 4) and the 1000 mb speed bits in
- * the 1000Base-T Control Register (Address 9).
- */
- mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
- mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
-
- DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised);
-
- /* Do we want to advertise 10 Mb Half Duplex? */
- if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
- DEBUGOUT("Advertise 10mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
- }
-
- /* Do we want to advertise 10 Mb Full Duplex? */
- if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
- DEBUGOUT("Advertise 10mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Half Duplex? */
- if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
- DEBUGOUT("Advertise 100mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Full Duplex? */
- if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
- DEBUGOUT("Advertise 100mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
- }
-
- /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
- if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
- DEBUGOUT("Advertise 1000mb Half duplex requested, request denied!\n");
- }
-
- /* Do we want to advertise 1000 Mb Full Duplex? */
- if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
- DEBUGOUT("Advertise 1000mb Full duplex\n");
- mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
- if (hw->phy_type == e1000_phy_ife) {
- DEBUGOUT("e1000_phy_ife is a 10/100 PHY. Gigabit speed is not supported.\n");
- }
- }
-
- /* Check for a software override of the flow control settings, and
- * setup the PHY advertisement registers accordingly. If
- * auto-negotiation is enabled, then software will have to set the
- * "PAUSE" bits to the correct value in the Auto-Negotiation
- * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * but we do not support receiving pause frames).
- * 3: Both Rx and TX flow control (symmetric) are enabled.
- * other: No software override. The flow control configuration
- * in the EEPROM is used.
- */
- switch (hw->fc) {
- case E1000_FC_NONE: /* 0 */
- /* Flow control (RX & TX) is completely disabled by a
- * software over-ride.
- */
- mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case E1000_FC_RX_PAUSE: /* 1 */
- /* RX Flow control is enabled, and TX Flow control is
- * disabled, by a software over-ride.
- */
- /* Since there really isn't a way to advertise that we are
- * capable of RX Pause ONLY, we will advertise that we
- * support both symmetric and asymmetric RX PAUSE. Later
- * (in e1000_config_fc_after_link_up) we will disable the
- *hw's ability to send PAUSE frames.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case E1000_FC_TX_PAUSE: /* 2 */
- /* TX Flow control is enabled, and RX Flow control is
- * disabled, by a software over-ride.
- */
- mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
- mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
- break;
- case E1000_FC_FULL: /* 3 */
- /* Flow control (both RX and TX) is enabled by a software
- * over-ride.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
- if (ret_val)
- return ret_val;
-
- DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
-
- if (hw->phy_type != e1000_phy_ife) {
- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
- if (ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Force PHY speed and duplex settings to hw->forced_speed_duplex
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
- u16 mii_ctrl_reg;
- u16 mii_status_reg;
- u16 phy_data;
- u16 i;
-
- DEBUGFUNC("e1000_phy_force_speed_duplex");
-
- /* Turn off Flow control if we are forcing speed and duplex. */
- hw->fc = E1000_FC_NONE;
-
- DEBUGOUT1("hw->fc = %d\n", hw->fc);
-
- /* Read the Device Control Register. */
- ctrl = er32(CTRL);
-
- /* Set the bits to Force Speed and Duplex in the Device Ctrl Reg. */
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ctrl &= ~(DEVICE_SPEED_MASK);
-
- /* Clear the Auto Speed Detect Enable bit. */
- ctrl &= ~E1000_CTRL_ASDE;
-
- /* Read the MII Control Register. */
- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
- if (ret_val)
- return ret_val;
-
- /* We need to disable autoneg in order to force link and duplex. */
-
- mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
-
- /* Are we forcing Full or Half Duplex? */
- if (hw->forced_speed_duplex == e1000_100_full ||
- hw->forced_speed_duplex == e1000_10_full) {
- /* We want to force full duplex so we SET the full duplex bits in the
- * Device and MII Control Registers.
- */
- ctrl |= E1000_CTRL_FD;
- mii_ctrl_reg |= MII_CR_FULL_DUPLEX;
- DEBUGOUT("Full Duplex\n");
- } else {
- /* We want to force half duplex so we CLEAR the full duplex bits in
- * the Device and MII Control Registers.
- */
- ctrl &= ~E1000_CTRL_FD;
- mii_ctrl_reg &= ~MII_CR_FULL_DUPLEX;
- DEBUGOUT("Half Duplex\n");
- }
-
- /* Are we forcing 100Mbps??? */
- if (hw->forced_speed_duplex == e1000_100_full ||
- hw->forced_speed_duplex == e1000_100_half) {
- /* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
- ctrl |= E1000_CTRL_SPD_100;
- mii_ctrl_reg |= MII_CR_SPEED_100;
- mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
- DEBUGOUT("Forcing 100mb ");
- } else {
- /* Set the 10Mb bit and turn off the 1000Mb and 100Mb bits. */
- ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
- mii_ctrl_reg |= MII_CR_SPEED_10;
- mii_ctrl_reg &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
- DEBUGOUT("Forcing 10mb ");
- }
-
- e1000_config_collision_dist(hw);
-
- /* Write the configured values back to the Device Control Reg. */
- ew32(CTRL, ctrl);
-
- if ((hw->phy_type == e1000_phy_m88) ||
- (hw->phy_type == e1000_phy_gg82563)) {
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
- * forced whenever speed are duplex are forced.
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
-
- /* Need to reset the PHY or these changes will be ignored */
- mii_ctrl_reg |= MII_CR_RESET;
-
- /* Disable MDI-X support for 10/100 */
- } else if (hw->phy_type == e1000_phy_ife) {
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IFE_PMC_AUTO_MDIX;
- phy_data &= ~IFE_PMC_FORCE_MDIX;
-
- ret_val = e1000_write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- } else {
- /* Clear Auto-Crossover to force MDI manually. IGP requires MDI
- * forced whenever speed or duplex are forced.
- */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
- if (ret_val)
- return ret_val;
- }
-
- /* Write back the modified PHY MII control register. */
- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
- if (ret_val)
- return ret_val;
-
- udelay(1);
-
- /* The wait_autoneg_complete flag may be a little misleading here.
- * Since we are forcing speed and duplex, Auto-Neg is not enabled.
- * But we do want to delay for a period while forcing only so we
- * don't generate false No Link messages. So we will wait here
- * only if the user has set wait_autoneg_complete to 1, which is
- * the default.
- */
- if (hw->wait_autoneg_complete) {
- /* We will wait for autoneg to complete. */
- DEBUGOUT("Waiting for forced speed/duplex link.\n");
- mii_status_reg = 0;
-
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
- for (i = PHY_FORCE_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Auto-Neg Complete bit
- * to be set.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- if (mii_status_reg & MII_SR_LINK_STATUS) break;
- msleep(100);
- }
- if ((i == 0) &&
- ((hw->phy_type == e1000_phy_m88) ||
- (hw->phy_type == e1000_phy_gg82563))) {
- /* We didn't get link. Reset the DSP and wait again for link. */
- ret_val = e1000_phy_reset_dsp(hw);
- if (ret_val) {
- DEBUGOUT("Error Resetting PHY DSP\n");
- return ret_val;
- }
- }
- /* This loop will early-out if the link condition has been met. */
- for (i = PHY_FORCE_TIME; i > 0; i--) {
- if (mii_status_reg & MII_SR_LINK_STATUS) break;
- msleep(100);
- /* Read the MII Status Register and wait for Auto-Neg Complete bit
- * to be set.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
- }
- }
-
- if (hw->phy_type == e1000_phy_m88) {
- /* Because we reset the PHY above, we need to re-force TX_CLK in the
- * Extended PHY Specific Control Register to 25MHz clock. This value
- * defaults back to a 2.5MHz clock when the PHY is reset.
- */
- ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* In addition, because of the s/w reset above, we need to enable CRS on
- * TX. This must be set for both full and half duplex operation.
- */
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
- (!hw->autoneg) && (hw->forced_speed_duplex == e1000_10_full ||
- hw->forced_speed_duplex == e1000_10_half)) {
- ret_val = e1000_polarity_reversal_workaround(hw);
- if (ret_val)
- return ret_val;
- }
- } else if (hw->phy_type == e1000_phy_gg82563) {
- /* The TX_CLK of the Extended PHY Specific Control Register defaults
- * to 2.5MHz on a reset. We need to re-force it back to 25MHz, if
- * we're not in a forced 10/duplex configuration. */
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
- if ((hw->forced_speed_duplex == e1000_10_full) ||
- (hw->forced_speed_duplex == e1000_10_half))
- phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ;
- else
- phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25MHZ;
-
- /* Also due to the reset, we need to enable CRS on Tx. */
- phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
-
- ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Sets the collision distance in the Transmit Control register
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Link should have been established previously. Reads the speed and duplex
-* information from the Device Status register.
-******************************************************************************/
-void e1000_config_collision_dist(struct e1000_hw *hw)
-{
- u32 tctl, coll_dist;
-
- DEBUGFUNC("e1000_config_collision_dist");
-
- if (hw->mac_type < e1000_82543)
- coll_dist = E1000_COLLISION_DISTANCE_82542;
- else
- coll_dist = E1000_COLLISION_DISTANCE;
-
- tctl = er32(TCTL);
-
- tctl &= ~E1000_TCTL_COLD;
- tctl |= coll_dist << E1000_COLD_SHIFT;
-
- ew32(TCTL, tctl);
- E1000_WRITE_FLUSH();
-}
-
-/******************************************************************************
-* Sets MAC speed and duplex settings to reflect the those in the PHY
-*
-* hw - Struct containing variables accessed by shared code
-* mii_reg - data to write to the MII control register
-*
-* The contents of the PHY register containing the needed information need to
-* be passed in.
-******************************************************************************/
-static s32 e1000_config_mac_to_phy(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_config_mac_to_phy");
-
- /* 82544 or newer MAC, Auto Speed Detection takes care of
- * MAC speed/duplex configuration.*/
- if (hw->mac_type >= e1000_82544)
- return E1000_SUCCESS;
-
- /* Read the Device Control Register and set the bits to Force Speed
- * and Duplex.
- */
- ctrl = er32(CTRL);
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
-
- /* Set up duplex in the Device Control and Transmit Control
- * registers depending on negotiated values.
- */
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- if (phy_data & M88E1000_PSSR_DPLX)
- ctrl |= E1000_CTRL_FD;
- else
- ctrl &= ~E1000_CTRL_FD;
-
- e1000_config_collision_dist(hw);
-
- /* Set up speed in the Device Control register depending on
- * negotiated values.
- */
- if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
- ctrl |= E1000_CTRL_SPD_1000;
- else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
- ctrl |= E1000_CTRL_SPD_100;
-
- /* Write the configured values back to the Device Control Reg. */
- ew32(CTRL, ctrl);
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Forces the MAC's flow control settings.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Sets the TFCE and RFCE bits in the device control register to reflect
- * the adapter settings. TFCE and RFCE need to be explicitly set by
- * software when a Copper PHY is used because autonegotiation is managed
- * by the PHY rather than the MAC. Software must also configure these
- * bits when link is forced on a fiber connection.
- *****************************************************************************/
-s32 e1000_force_mac_fc(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- DEBUGFUNC("e1000_force_mac_fc");
-
- /* Get the current configuration of the Device Control Register */
- ctrl = er32(CTRL);
-
- /* Because we didn't get link via the internal auto-negotiation
- * mechanism (we either forced link or we got link via PHY
- * auto-neg), we have to manually enable/disable transmit an
- * receive flow control.
- *
- * The "Case" statement below enables/disable flow control
- * according to the "hw->fc" parameter.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause
- * frames but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * frames but we do not receive pause frames).
- * 3: Both Rx and TX flow control (symmetric) is enabled.
- * other: No other values should be possible at this point.
- */
-
- switch (hw->fc) {
- case E1000_FC_NONE:
- ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
- break;
- case E1000_FC_RX_PAUSE:
- ctrl &= (~E1000_CTRL_TFCE);
- ctrl |= E1000_CTRL_RFCE;
- break;
- case E1000_FC_TX_PAUSE:
- ctrl &= (~E1000_CTRL_RFCE);
- ctrl |= E1000_CTRL_TFCE;
- break;
- case E1000_FC_FULL:
- ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
- break;
- default:
- DEBUGOUT("Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- }
-
- /* Disable TX Flow Control for 82542 (rev 2.0) */
- if (hw->mac_type == e1000_82542_rev2_0)
- ctrl &= (~E1000_CTRL_TFCE);
-
- ew32(CTRL, ctrl);
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Configures flow control settings after link is established
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Should be called immediately after a valid link has been established.
- * Forces MAC flow control settings if link was forced. When in MII/GMII mode
- * and autonegotiation is enabled, the MAC flow control settings will be set
- * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
- * and RFCE bits will be automaticaly set to the negotiated flow control mode.
- *****************************************************************************/
-static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 mii_status_reg;
- u16 mii_nway_adv_reg;
- u16 mii_nway_lp_ability_reg;
- u16 speed;
- u16 duplex;
-
- DEBUGFUNC("e1000_config_fc_after_link_up");
-
- /* Check for the case where we have fiber media and auto-neg failed
- * so we had to force link. In this case, we need to force the
- * configuration of the MAC to match the "fc" parameter.
- */
- if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
- ((hw->media_type == e1000_media_type_internal_serdes) &&
- (hw->autoneg_failed)) ||
- ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) {
- ret_val = e1000_force_mac_fc(hw);
- if (ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
- }
-
- /* Check for the case where we have copper media and auto-neg is
- * enabled. In this case, we need to check and see if Auto-Neg
- * has completed, and if so, how the PHY and link partner has
- * flow control configured.
- */
- if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
- /* Read the MII Status Register and check to see if AutoNeg
- * has completed. We read this twice because this reg has
- * some "sticky" (latched) bits.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
- /* The AutoNeg process has completed, so we now need to
- * read both the Auto Negotiation Advertisement Register
- * (Address 4) and the Auto_Negotiation Base Page Ability
- * Register (Address 5) to determine how flow control was
- * negotiated.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
- &mii_nway_adv_reg);
- if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
- &mii_nway_lp_ability_reg);
- if (ret_val)
- return ret_val;
-
- /* Two bits in the Auto Negotiation Advertisement Register
- * (Address 4) and two bits in the Auto Negotiation Base
- * Page Ability Register (Address 5) determine flow control
- * for both the PHY and the link partner. The following
- * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
- * 1999, describes these PAUSE resolution bits and how flow
- * control is determined based upon these settings.
- * NOTE: DC = Don't Care
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
- *-------|---------|-------|---------|--------------------
- * 0 | 0 | DC | DC | E1000_FC_NONE
- * 0 | 1 | 0 | DC | E1000_FC_NONE
- * 0 | 1 | 1 | 0 | E1000_FC_NONE
- * 0 | 1 | 1 | 1 | E1000_FC_TX_PAUSE
- * 1 | 0 | 0 | DC | E1000_FC_NONE
- * 1 | DC | 1 | DC | E1000_FC_FULL
- * 1 | 1 | 0 | 0 | E1000_FC_NONE
- * 1 | 1 | 0 | 1 | E1000_FC_RX_PAUSE
- *
- */
- /* Are both PAUSE bits set to 1? If so, this implies
- * Symmetric Flow Control is enabled at both ends. The
- * ASM_DIR bits are irrelevant per the spec.
- *
- * For Symmetric Flow Control:
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | DC | 1 | DC | E1000_FC_FULL
- *
- */
- if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
- /* Now we need to check if the user selected RX ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise RX
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
- */
- if (hw->original_fc == E1000_FC_FULL) {
- hw->fc = E1000_FC_FULL;
- DEBUGOUT("Flow Control = FULL.\n");
- } else {
- hw->fc = E1000_FC_RX_PAUSE;
- DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
- }
- }
- /* For receiving PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 0 | 1 | 1 | 1 | E1000_FC_TX_PAUSE
- *
- */
- else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = E1000_FC_TX_PAUSE;
- DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
- }
- /* For transmitting PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | 1 | 0 | 1 | E1000_FC_RX_PAUSE
- *
- */
- else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = E1000_FC_RX_PAUSE;
- DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
- }
- /* Per the IEEE spec, at this point flow control should be
- * disabled. However, we want to consider that we could
- * be connected to a legacy switch that doesn't advertise
- * desired flow control, but can be forced on the link
- * partner. So if we advertised no flow control, that is
- * what we will resolve to. If we advertised some kind of
- * receive capability (Rx Pause Only or Full Flow Control)
- * and the link partner advertised none, we will configure
- * ourselves to enable Rx Flow Control only. We can do
- * this safely for two reasons: If the link partner really
- * didn't want flow control enabled, and we enable Rx, no
- * harm done since we won't be receiving any PAUSE frames
- * anyway. If the intent on the link partner was to have
- * flow control enabled, then by us enabling RX only, we
- * can at least receive pause frames and process them.
- * This is a good idea because in most cases, since we are
- * predominantly a server NIC, more times than not we will
- * be asked to delay transmission of packets than asking
- * our link partner to pause transmission of frames.
- */
- else if ((hw->original_fc == E1000_FC_NONE ||
- hw->original_fc == E1000_FC_TX_PAUSE) ||
- hw->fc_strict_ieee) {
- hw->fc = E1000_FC_NONE;
- DEBUGOUT("Flow Control = NONE.\n");
- } else {
- hw->fc = E1000_FC_RX_PAUSE;
- DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
- }
-
- /* Now we need to do one last check... If we auto-
- * negotiated to HALF DUPLEX, flow control should not be
- * enabled per IEEE 802.3 spec.
- */
- ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
- if (ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
-
- if (duplex == HALF_DUPLEX)
- hw->fc = E1000_FC_NONE;
-
- /* Now we call a subroutine to actually force the MAC
- * controller to use the correct flow control settings.
- */
- ret_val = e1000_force_mac_fc(hw);
- if (ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
- } else {
- DEBUGOUT("Copper PHY and Auto Neg has not completed.\n");
- }
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Checks to see if the link status of the hardware has changed.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Called by any function that needs to check the link status of the adapter.
- *****************************************************************************/
-s32 e1000_check_for_link(struct e1000_hw *hw)
-{
- u32 rxcw = 0;
- u32 ctrl;
- u32 status;
- u32 rctl;
- u32 icr;
- u32 signal = 0;
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_check_for_link");
-
- ctrl = er32(CTRL);
- status = er32(STATUS);
-
- /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
- * set when the optics detect a signal. On older adapters, it will be
- * cleared when there is a signal. This applies to fiber media only.
- */
- if ((hw->media_type == e1000_media_type_fiber) ||
- (hw->media_type == e1000_media_type_internal_serdes)) {
- rxcw = er32(RXCW);
-
- if (hw->media_type == e1000_media_type_fiber) {
- signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
- if (status & E1000_STATUS_LU)
- hw->get_link_status = false;
- }
- }
-
- /* If we have a copper PHY then we only want to go out to the PHY
- * registers to see if Auto-Neg has completed and/or if our link
- * status has changed. The get_link_status flag will be set if we
- * receive a Link Status Change interrupt or we have Rx Sequence
- * Errors.
- */
- if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
- /* First we want to see if the MII Status Register reports
- * link. If so, then we want to get the current speed/duplex
- * of the PHY.
- * Read the register twice since the link bit is sticky.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- if (phy_data & MII_SR_LINK_STATUS) {
- hw->get_link_status = false;
- /* Check if there was DownShift, must be checked immediately after
- * link-up */
- e1000_check_downshift(hw);
-
- /* If we are on 82544 or 82543 silicon and speed/duplex
- * are forced to 10H or 10F, then we will implement the polarity
- * reversal workaround. We disable interrupts first, and upon
- * returning, place the devices interrupt state to its previous
- * value except for the link status change interrupt which will
- * happen due to the execution of this workaround.
- */
-
- if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
- (!hw->autoneg) &&
- (hw->forced_speed_duplex == e1000_10_full ||
- hw->forced_speed_duplex == e1000_10_half)) {
- ew32(IMC, 0xffffffff);
- ret_val = e1000_polarity_reversal_workaround(hw);
- icr = er32(ICR);
- ew32(ICS, (icr & ~E1000_ICS_LSC));
- ew32(IMS, IMS_ENABLE_MASK);
- }
-
- } else {
- /* No link detected */
- e1000_config_dsp_after_link_change(hw, false);
- return 0;
- }
-
- /* If we are forcing speed/duplex, then we simply return since
- * we have already determined whether we have link or not.
- */
- if (!hw->autoneg) return -E1000_ERR_CONFIG;
-
- /* optimize the dsp settings for the igp phy */
- e1000_config_dsp_after_link_change(hw, true);
-
- /* We have a M88E1000 PHY and Auto-Neg is enabled. If we
- * have Si on board that is 82544 or newer, Auto
- * Speed Detection takes care of MAC speed/duplex
- * configuration. So we only need to configure Collision
- * Distance in the MAC. Otherwise, we need to force
- * speed/duplex on the MAC to the current PHY speed/duplex
- * settings.
- */
- if (hw->mac_type >= e1000_82544)
- e1000_config_collision_dist(hw);
- else {
- ret_val = e1000_config_mac_to_phy(hw);
- if (ret_val) {
- DEBUGOUT("Error configuring MAC to PHY settings\n");
- return ret_val;
- }
- }
-
- /* Configure Flow Control now that Auto-Neg has completed. First, we
- * need to restore the desired flow control settings because we may
- * have had to re-autoneg with a different link partner.
- */
- ret_val = e1000_config_fc_after_link_up(hw);
- if (ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
-
- /* At this point we know that we are on copper and we have
- * auto-negotiated link. These are conditions for checking the link
- * partner capability register. We use the link speed to determine if
- * TBI compatibility needs to be turned on or off. If the link is not
- * at gigabit speed, then TBI compatibility is not needed. If we are
- * at gigabit speed, we turn on TBI compatibility.
- */
- if (hw->tbi_compatibility_en) {
- u16 speed, duplex;
- ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
- if (ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
- if (speed != SPEED_1000) {
- /* If link speed is not set to gigabit speed, we do not need
- * to enable TBI compatibility.
- */
- if (hw->tbi_compatibility_on) {
- /* If we previously were in the mode, turn it off. */
- rctl = er32(RCTL);
- rctl &= ~E1000_RCTL_SBP;
- ew32(RCTL, rctl);
- hw->tbi_compatibility_on = false;
- }
- } else {
- /* If TBI compatibility is was previously off, turn it on. For
- * compatibility with a TBI link partner, we will store bad
- * packets. Some frames have an additional byte on the end and
- * will look like CRC errors to to the hardware.
- */
- if (!hw->tbi_compatibility_on) {
- hw->tbi_compatibility_on = true;
- rctl = er32(RCTL);
- rctl |= E1000_RCTL_SBP;
- ew32(RCTL, rctl);
- }
- }
- }
- }
- /* If we don't have link (auto-negotiation failed or link partner cannot
- * auto-negotiate), the cable is plugged in (we have signal), and our
- * link partner is not trying to auto-negotiate with us (we are receiving
- * idles or data), we need to force link up. We also need to give
- * auto-negotiation time to complete, in case the cable was just plugged
- * in. The autoneg_failed flag does this.
- */
- else if ((((hw->media_type == e1000_media_type_fiber) &&
- ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
- (hw->media_type == e1000_media_type_internal_serdes)) &&
- (!(status & E1000_STATUS_LU)) &&
- (!(rxcw & E1000_RXCW_C))) {
- if (hw->autoneg_failed == 0) {
- hw->autoneg_failed = 1;
- return 0;
- }
- DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
-
- /* Disable auto-negotiation in the TXCW register */
- ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
-
- /* Force link-up and also force full-duplex. */
- ctrl = er32(CTRL);
- ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
- ew32(CTRL, ctrl);
-
- /* Configure Flow Control after forcing link up. */
- ret_val = e1000_config_fc_after_link_up(hw);
- if (ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
- }
- /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
- * auto-negotiation in the TXCW register and disable forced link in the
- * Device Control register in an attempt to auto-negotiate with our link
- * partner.
- */
- else if (((hw->media_type == e1000_media_type_fiber) ||
- (hw->media_type == e1000_media_type_internal_serdes)) &&
- (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
- DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
- ew32(TXCW, hw->txcw);
- ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
-
- hw->serdes_link_down = false;
- }
- /* If we force link for non-auto-negotiation switch, check link status
- * based on MAC synchronization for internal serdes media type.
- */
- else if ((hw->media_type == e1000_media_type_internal_serdes) &&
- !(E1000_TXCW_ANE & er32(TXCW))) {
- /* SYNCH bit and IV bit are sticky. */
- udelay(10);
- if (E1000_RXCW_SYNCH & er32(RXCW)) {
- if (!(rxcw & E1000_RXCW_IV)) {
- hw->serdes_link_down = false;
- DEBUGOUT("SERDES: Link is up.\n");
- }
- } else {
- hw->serdes_link_down = true;
- DEBUGOUT("SERDES: Link is down.\n");
- }
- }
- if ((hw->media_type == e1000_media_type_internal_serdes) &&
- (E1000_TXCW_ANE & er32(TXCW))) {
- hw->serdes_link_down = !(E1000_STATUS_LU & er32(STATUS));
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Detects the current speed and duplex settings of the hardware.
- *
- * hw - Struct containing variables accessed by shared code
- * speed - Speed of the connection
- * duplex - Duplex setting of the connection
- *****************************************************************************/
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
-{
- u32 status;
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_get_speed_and_duplex");
-
- if (hw->mac_type >= e1000_82543) {
- status = er32(STATUS);
- if (status & E1000_STATUS_SPEED_1000) {
- *speed = SPEED_1000;
- DEBUGOUT("1000 Mbs, ");
- } else if (status & E1000_STATUS_SPEED_100) {
- *speed = SPEED_100;
- DEBUGOUT("100 Mbs, ");
- } else {
- *speed = SPEED_10;
- DEBUGOUT("10 Mbs, ");
- }
-
- if (status & E1000_STATUS_FD) {
- *duplex = FULL_DUPLEX;
- DEBUGOUT("Full Duplex\n");
- } else {
- *duplex = HALF_DUPLEX;
- DEBUGOUT(" Half Duplex\n");
- }
- } else {
- DEBUGOUT("1000 Mbs, Full Duplex\n");
- *speed = SPEED_1000;
- *duplex = FULL_DUPLEX;
- }
-
- /* IGP01 PHY may advertise full duplex operation after speed downgrade even
- * if it is operating at half duplex. Here we set the duplex settings to
- * match the duplex in the link partner's capabilities.
- */
- if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
- if (ret_val)
- return ret_val;
-
- if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
- *duplex = HALF_DUPLEX;
- else {
- ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
- if (ret_val)
- return ret_val;
- if ((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
- (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
- *duplex = HALF_DUPLEX;
- }
- }
-
- if ((hw->mac_type == e1000_80003es2lan) &&
- (hw->media_type == e1000_media_type_copper)) {
- if (*speed == SPEED_1000)
- ret_val = e1000_configure_kmrn_for_1000(hw);
- else
- ret_val = e1000_configure_kmrn_for_10_100(hw, *duplex);
- if (ret_val)
- return ret_val;
- }
-
- if ((hw->phy_type == e1000_phy_igp_3) && (*speed == SPEED_1000)) {
- ret_val = e1000_kumeran_lock_loss_workaround(hw);
- if (ret_val)
- return ret_val;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Blocks until autoneg completes or times out (~4.5 seconds)
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_wait_autoneg(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 i;
- u16 phy_data;
-
- DEBUGFUNC("e1000_wait_autoneg");
- DEBUGOUT("Waiting for Auto-Neg to complete.\n");
-
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
- for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Auto-Neg
- * Complete bit to be set.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
- if (phy_data & MII_SR_AUTONEG_COMPLETE) {
- return E1000_SUCCESS;
- }
- msleep(100);
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Raises the Management Data Clock
-*
-* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
-******************************************************************************/
-static void e1000_raise_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
-{
- /* Raise the clock input to the Management Data Clock (by setting the MDC
- * bit), and then delay 10 microseconds.
- */
- ew32(CTRL, (*ctrl | E1000_CTRL_MDC));
- E1000_WRITE_FLUSH();
- udelay(10);
-}
-
-/******************************************************************************
-* Lowers the Management Data Clock
-*
-* hw - Struct containing variables accessed by shared code
-* ctrl - Device control register's current value
-******************************************************************************/
-static void e1000_lower_mdi_clk(struct e1000_hw *hw, u32 *ctrl)
-{
- /* Lower the clock input to the Management Data Clock (by clearing the MDC
- * bit), and then delay 10 microseconds.
- */
- ew32(CTRL, (*ctrl & ~E1000_CTRL_MDC));
- E1000_WRITE_FLUSH();
- udelay(10);
-}
-
-/******************************************************************************
-* Shifts data bits out to the PHY
-*
-* hw - Struct containing variables accessed by shared code
-* data - Data to send out to the PHY
-* count - Number of bits to shift out
-*
-* Bits are shifted out in MSB to LSB order.
-******************************************************************************/
-static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, u32 data, u16 count)
-{
- u32 ctrl;
- u32 mask;
-
- /* We need to shift "count" number of bits out to the PHY. So, the value
- * in the "data" parameter will be shifted out to the PHY one bit at a
- * time. In order to do this, "data" must be broken down into bits.
- */
- mask = 0x01;
- mask <<= (count - 1);
-
- ctrl = er32(CTRL);
-
- /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
- ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
-
- while (mask) {
- /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
- * then raising and lowering the Management Data Clock. A "0" is
- * shifted out to the PHY by setting the MDIO bit to "0" and then
- * raising and lowering the clock.
- */
- if (data & mask)
- ctrl |= E1000_CTRL_MDIO;
- else
- ctrl &= ~E1000_CTRL_MDIO;
-
- ew32(CTRL, ctrl);
- E1000_WRITE_FLUSH();
-
- udelay(10);
-
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
-
- mask = mask >> 1;
- }
-}
-
-/******************************************************************************
-* Shifts data bits in from the PHY
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Bits are shifted in in MSB to LSB order.
-******************************************************************************/
-static u16 e1000_shift_in_mdi_bits(struct e1000_hw *hw)
-{
- u32 ctrl;
- u16 data = 0;
- u8 i;
-
- /* In order to read a register from the PHY, we need to shift in a total
- * of 18 bits from the PHY. The first two bit (turnaround) times are used
- * to avoid contention on the MDIO pin when a read operation is performed.
- * These two bits are ignored by us and thrown away. Bits are "shifted in"
- * by raising the input to the Management Data Clock (setting the MDC bit),
- * and then reading the value of the MDIO bit.
- */
- ctrl = er32(CTRL);
-
- /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
- ctrl &= ~E1000_CTRL_MDIO_DIR;
- ctrl &= ~E1000_CTRL_MDIO;
-
- ew32(CTRL, ctrl);
- E1000_WRITE_FLUSH();
-
- /* Raise and Lower the clock before reading in the data. This accounts for
- * the turnaround bits. The first clock occurred when we clocked out the
- * last bit of the Register Address.
- */
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
-
- for (data = 0, i = 0; i < 16; i++) {
- data = data << 1;
- e1000_raise_mdi_clk(hw, &ctrl);
- ctrl = er32(CTRL);
- /* Check to see if we shifted in a "1". */
- if (ctrl & E1000_CTRL_MDIO)
- data |= 1;
- e1000_lower_mdi_clk(hw, &ctrl);
- }
-
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
-
- return data;
-}
-
-static s32 e1000_swfw_sync_acquire(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync = 0;
- u32 swmask = mask;
- u32 fwmask = mask << 16;
- s32 timeout = 200;
-
- DEBUGFUNC("e1000_swfw_sync_acquire");
-
- if (hw->swfwhw_semaphore_present)
- return e1000_get_software_flag(hw);
-
- if (!hw->swfw_sync_present)
- return e1000_get_hw_eeprom_semaphore(hw);
-
- while (timeout) {
- if (e1000_get_hw_eeprom_semaphore(hw))
- return -E1000_ERR_SWFW_SYNC;
-
- swfw_sync = er32(SW_FW_SYNC);
- if (!(swfw_sync & (fwmask | swmask))) {
- break;
- }
-
- /* firmware currently using resource (fwmask) */
- /* or other software thread currently using resource (swmask) */
- e1000_put_hw_eeprom_semaphore(hw);
- mdelay(5);
- timeout--;
- }
-
- if (!timeout) {
- DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
- return -E1000_ERR_SWFW_SYNC;
- }
-
- swfw_sync |= swmask;
- ew32(SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_eeprom_semaphore(hw);
- return E1000_SUCCESS;
-}
-
-static void e1000_swfw_sync_release(struct e1000_hw *hw, u16 mask)
-{
- u32 swfw_sync;
- u32 swmask = mask;
-
- DEBUGFUNC("e1000_swfw_sync_release");
-
- if (hw->swfwhw_semaphore_present) {
- e1000_release_software_flag(hw);
- return;
- }
-
- if (!hw->swfw_sync_present) {
- e1000_put_hw_eeprom_semaphore(hw);
- return;
- }
-
- /* if (e1000_get_hw_eeprom_semaphore(hw))
- * return -E1000_ERR_SWFW_SYNC; */
- while (e1000_get_hw_eeprom_semaphore(hw) != E1000_SUCCESS);
- /* empty */
-
- swfw_sync = er32(SW_FW_SYNC);
- swfw_sync &= ~swmask;
- ew32(SW_FW_SYNC, swfw_sync);
-
- e1000_put_hw_eeprom_semaphore(hw);
-}
-
-/*****************************************************************************
-* Reads the value from a PHY register, if the value is on a specific non zero
-* page, sets the page first.
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to read
-******************************************************************************/
-s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data)
-{
- u32 ret_val;
- u16 swfw;
-
- DEBUGFUNC("e1000_read_phy_reg");
-
- if ((hw->mac_type == e1000_80003es2lan) &&
- (er32(STATUS) & E1000_STATUS_FUNC_1)) {
- swfw = E1000_SWFW_PHY1_SM;
- } else {
- swfw = E1000_SWFW_PHY0_SM;
- }
- if (e1000_swfw_sync_acquire(hw, swfw))
- return -E1000_ERR_SWFW_SYNC;
-
- if ((hw->phy_type == e1000_phy_igp ||
- hw->phy_type == e1000_phy_igp_3 ||
- hw->phy_type == e1000_phy_igp_2) &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (u16)reg_addr);
- if (ret_val) {
- e1000_swfw_sync_release(hw, swfw);
- return ret_val;
- }
- } else if (hw->phy_type == e1000_phy_gg82563) {
- if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) ||
- (hw->mac_type == e1000_80003es2lan)) {
- /* Select Configuration Page */
- if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
- ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT,
- (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
- } else {
- /* Use Alternative Page Select register to access
- * registers 30 and 31
- */
- ret_val = e1000_write_phy_reg_ex(hw,
- GG82563_PHY_PAGE_SELECT_ALT,
- (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
- }
-
- if (ret_val) {
- e1000_swfw_sync_release(hw, swfw);
- return ret_val;
- }
- }
- }
-
- ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
- phy_data);
-
- e1000_swfw_sync_release(hw, swfw);
- return ret_val;
-}
-
-static s32 e1000_read_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
- u16 *phy_data)
-{
- u32 i;
- u32 mdic = 0;
- const u32 phy_addr = 1;
-
- DEBUGFUNC("e1000_read_phy_reg_ex");
-
- if (reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
- }
-
- if (hw->mac_type > e1000_82543) {
- /* Set up Op-code, Phy Address, and register address in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
- (phy_addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_READ));
-
- ew32(MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed */
- for (i = 0; i < 64; i++) {
- udelay(50);
- mdic = er32(MDIC);
- if (mdic & E1000_MDIC_READY) break;
- }
- if (!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (mdic & E1000_MDIC_ERROR) {
- DEBUGOUT("MDI Error\n");
- return -E1000_ERR_PHY;
- }
- *phy_data = (u16)mdic;
- } else {
- /* We must first send a preamble through the MDIO pin to signal the
- * beginning of an MII instruction. This is done by sending 32
- * consecutive "1" bits.
- */
- e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
-
- /* Now combine the next few fields that are required for a read
- * operation. We use this method instead of calling the
- * e1000_shift_out_mdi_bits routine five different times. The format of
- * a MII read instruction consists of a shift out of 14 bits and is
- * defined as follows:
- * <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
- * followed by a shift in of 18 bits. This first two bits shifted in
- * are TurnAround bits used to avoid contention on the MDIO pin when a
- * READ operation is performed. These two bits are thrown away
- * followed by a shift in of 16 bits which contains the desired data.
- */
- mdic = ((reg_addr) | (phy_addr << 5) |
- (PHY_OP_READ << 10) | (PHY_SOF << 12));
-
- e1000_shift_out_mdi_bits(hw, mdic, 14);
-
- /* Now that we've shifted out the read command to the MII, we need to
- * "shift in" the 16-bit value (18 total bits) of the requested PHY
- * register address.
- */
- *phy_data = e1000_shift_in_mdi_bits(hw);
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Writes a value to a PHY register
-*
-* hw - Struct containing variables accessed by shared code
-* reg_addr - address of the PHY register to write
-* data - data to write to the PHY
-******************************************************************************/
-s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 phy_data)
-{
- u32 ret_val;
- u16 swfw;
-
- DEBUGFUNC("e1000_write_phy_reg");
-
- if ((hw->mac_type == e1000_80003es2lan) &&
- (er32(STATUS) & E1000_STATUS_FUNC_1)) {
- swfw = E1000_SWFW_PHY1_SM;
- } else {
- swfw = E1000_SWFW_PHY0_SM;
- }
- if (e1000_swfw_sync_acquire(hw, swfw))
- return -E1000_ERR_SWFW_SYNC;
-
- if ((hw->phy_type == e1000_phy_igp ||
- hw->phy_type == e1000_phy_igp_3 ||
- hw->phy_type == e1000_phy_igp_2) &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (u16)reg_addr);
- if (ret_val) {
- e1000_swfw_sync_release(hw, swfw);
- return ret_val;
- }
- } else if (hw->phy_type == e1000_phy_gg82563) {
- if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) ||
- (hw->mac_type == e1000_80003es2lan)) {
- /* Select Configuration Page */
- if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
- ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT,
- (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
- } else {
- /* Use Alternative Page Select register to access
- * registers 30 and 31
- */
- ret_val = e1000_write_phy_reg_ex(hw,
- GG82563_PHY_PAGE_SELECT_ALT,
- (u16)((u16)reg_addr >> GG82563_PAGE_SHIFT));
- }
-
- if (ret_val) {
- e1000_swfw_sync_release(hw, swfw);
- return ret_val;
- }
- }
- }
-
- ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
- phy_data);
-
- e1000_swfw_sync_release(hw, swfw);
- return ret_val;
-}
-
-static s32 e1000_write_phy_reg_ex(struct e1000_hw *hw, u32 reg_addr,
- u16 phy_data)
-{
- u32 i;
- u32 mdic = 0;
- const u32 phy_addr = 1;
-
- DEBUGFUNC("e1000_write_phy_reg_ex");
-
- if (reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
- }
-
- if (hw->mac_type > e1000_82543) {
- /* Set up Op-code, Phy Address, register address, and data intended
- * for the PHY register in the MDI Control register. The MAC will take
- * care of interfacing with the PHY to send the desired data.
- */
- mdic = (((u32)phy_data) |
- (reg_addr << E1000_MDIC_REG_SHIFT) |
- (phy_addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_WRITE));
-
- ew32(MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed */
- for (i = 0; i < 641; i++) {
- udelay(5);
- mdic = er32(MDIC);
- if (mdic & E1000_MDIC_READY) break;
- }
- if (!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Write did not complete\n");
- return -E1000_ERR_PHY;
- }
- } else {
- /* We'll need to use the SW defined pins to shift the write command
- * out to the PHY. We first send a preamble to the PHY to signal the
- * beginning of the MII instruction. This is done by sending 32
- * consecutive "1" bits.
- */
- e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
-
- /* Now combine the remaining required fields that will indicate a
- * write operation. We use this method instead of calling the
- * e1000_shift_out_mdi_bits routine for each field in the command. The
- * format of a MII write instruction is as follows:
- * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
- */
- mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
- (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
- mdic <<= 16;
- mdic |= (u32)phy_data;
-
- e1000_shift_out_mdi_bits(hw, mdic, 32);
- }
-
- return E1000_SUCCESS;
-}
-
-static s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 *data)
-{
- u32 reg_val;
- u16 swfw;
- DEBUGFUNC("e1000_read_kmrn_reg");
-
- if ((hw->mac_type == e1000_80003es2lan) &&
- (er32(STATUS) & E1000_STATUS_FUNC_1)) {
- swfw = E1000_SWFW_PHY1_SM;
- } else {
- swfw = E1000_SWFW_PHY0_SM;
- }
- if (e1000_swfw_sync_acquire(hw, swfw))
- return -E1000_ERR_SWFW_SYNC;
-
- /* Write register address */
- reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
- E1000_KUMCTRLSTA_OFFSET) |
- E1000_KUMCTRLSTA_REN;
- ew32(KUMCTRLSTA, reg_val);
- udelay(2);
-
- /* Read the data returned */
- reg_val = er32(KUMCTRLSTA);
- *data = (u16)reg_val;
-
- e1000_swfw_sync_release(hw, swfw);
- return E1000_SUCCESS;
-}
-
-static s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 reg_addr, u16 data)
-{
- u32 reg_val;
- u16 swfw;
- DEBUGFUNC("e1000_write_kmrn_reg");
-
- if ((hw->mac_type == e1000_80003es2lan) &&
- (er32(STATUS) & E1000_STATUS_FUNC_1)) {
- swfw = E1000_SWFW_PHY1_SM;
- } else {
- swfw = E1000_SWFW_PHY0_SM;
- }
- if (e1000_swfw_sync_acquire(hw, swfw))
- return -E1000_ERR_SWFW_SYNC;
-
- reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
- E1000_KUMCTRLSTA_OFFSET) | data;
- ew32(KUMCTRLSTA, reg_val);
- udelay(2);
-
- e1000_swfw_sync_release(hw, swfw);
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Returns the PHY to the power-on reset state
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-s32 e1000_phy_hw_reset(struct e1000_hw *hw)
-{
- u32 ctrl, ctrl_ext;
- u32 led_ctrl;
- s32 ret_val;
- u16 swfw;
-
- DEBUGFUNC("e1000_phy_hw_reset");
-
- /* In the case of the phy reset being blocked, it's not an error, we
- * simply return success without performing the reset. */
- ret_val = e1000_check_phy_reset_block(hw);
- if (ret_val)
- return E1000_SUCCESS;
-
- DEBUGOUT("Resetting Phy...\n");
-
- if (hw->mac_type > e1000_82543) {
- if ((hw->mac_type == e1000_80003es2lan) &&
- (er32(STATUS) & E1000_STATUS_FUNC_1)) {
- swfw = E1000_SWFW_PHY1_SM;
- } else {
- swfw = E1000_SWFW_PHY0_SM;
- }
- if (e1000_swfw_sync_acquire(hw, swfw)) {
- DEBUGOUT("Unable to acquire swfw sync\n");
- return -E1000_ERR_SWFW_SYNC;
- }
- /* Read the device control register and assert the E1000_CTRL_PHY_RST
- * bit. Then, take it out of reset.
- * For pre-e1000_82571 hardware, we delay for 10ms between the assert
- * and deassert. For e1000_82571 hardware and later, we instead delay
- * for 50us between and 10ms after the deassertion.
- */
- ctrl = er32(CTRL);
- ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
- E1000_WRITE_FLUSH();
-
- if (hw->mac_type < e1000_82571)
- msleep(10);
- else
- udelay(100);
-
- ew32(CTRL, ctrl);
- E1000_WRITE_FLUSH();
-
- if (hw->mac_type >= e1000_82571)
- mdelay(10);
-
- e1000_swfw_sync_release(hw, swfw);
- } else {
- /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
- * bit to put the PHY into reset. Then, take it out of reset.
- */
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
- ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
- ew32(CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH();
- msleep(10);
- ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
- ew32(CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH();
- }
- udelay(150);
-
- if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- /* Configure activity LED after PHY reset */
- led_ctrl = er32(LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- ew32(LEDCTL, led_ctrl);
- }
-
- /* Wait for FW to finish PHY configuration. */
- ret_val = e1000_get_phy_cfg_done(hw);
- if (ret_val != E1000_SUCCESS)
- return ret_val;
- e1000_release_software_semaphore(hw);
-
- if ((hw->mac_type == e1000_ich8lan) && (hw->phy_type == e1000_phy_igp_3))
- ret_val = e1000_init_lcd_from_nvm(hw);
-
- return ret_val;
-}
-
-/******************************************************************************
-* Resets the PHY
-*
-* hw - Struct containing variables accessed by shared code
-*
-* Sets bit 15 of the MII Control register
-******************************************************************************/
-s32 e1000_phy_reset(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_phy_reset");
-
- /* In the case of the phy reset being blocked, it's not an error, we
- * simply return success without performing the reset. */
- ret_val = e1000_check_phy_reset_block(hw);
- if (ret_val)
- return E1000_SUCCESS;
-
- switch (hw->phy_type) {
- case e1000_phy_igp:
- case e1000_phy_igp_2:
- case e1000_phy_igp_3:
- case e1000_phy_ife:
- ret_val = e1000_phy_hw_reset(hw);
- if (ret_val)
- return ret_val;
- break;
- default:
- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= MII_CR_RESET;
- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- udelay(1);
- break;
- }
-
- if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2)
- e1000_phy_init_script(hw);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Work-around for 82566 power-down: on D3 entry-
-* 1) disable gigabit link
-* 2) write VR power-down enable
-* 3) read it back
-* if successful continue, else issue LCD reset and repeat
-*
-* hw - struct containing variables accessed by shared code
-******************************************************************************/
-void e1000_phy_powerdown_workaround(struct e1000_hw *hw)
-{
- s32 reg;
- u16 phy_data;
- s32 retry = 0;
-
- DEBUGFUNC("e1000_phy_powerdown_workaround");
-
- if (hw->phy_type != e1000_phy_igp_3)
- return;
-
- do {
- /* Disable link */
- reg = er32(PHY_CTRL);
- ew32(PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
- E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
-
- /* Write VR power-down enable - bits 9:8 should be 10b */
- e1000_read_phy_reg(hw, IGP3_VR_CTRL, &phy_data);
- phy_data |= (1 << 9);
- phy_data &= ~(1 << 8);
- e1000_write_phy_reg(hw, IGP3_VR_CTRL, phy_data);
-
- /* Read it back and test */
- e1000_read_phy_reg(hw, IGP3_VR_CTRL, &phy_data);
- if (((phy_data & IGP3_VR_CTRL_MODE_MASK) == IGP3_VR_CTRL_MODE_SHUT) || retry)
- break;
-
- /* Issue PHY reset and repeat at most one more time */
- reg = er32(CTRL);
- ew32(CTRL, reg | E1000_CTRL_PHY_RST);
- retry++;
- } while (retry);
-
- return;
-
-}
-
-/******************************************************************************
-* Work-around for 82566 Kumeran PCS lock loss:
-* On link status change (i.e. PCI reset, speed change) and link is up and
-* speed is gigabit-
-* 0) if workaround is optionally disabled do nothing
-* 1) wait 1ms for Kumeran link to come up
-* 2) check Kumeran Diagnostic register PCS lock loss bit
-* 3) if not set the link is locked (all is good), otherwise...
-* 4) reset the PHY
-* 5) repeat up to 10 times
-* Note: this is only called for IGP3 copper when speed is 1gb.
-*
-* hw - struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
-{
- s32 ret_val;
- s32 reg;
- s32 cnt;
- u16 phy_data;
-
- if (hw->kmrn_lock_loss_workaround_disabled)
- return E1000_SUCCESS;
-
- /* Make sure link is up before proceeding. If not just return.
- * Attempting this while link is negotiating fouled up link
- * stability */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-
- if (phy_data & MII_SR_LINK_STATUS) {
- for (cnt = 0; cnt < 10; cnt++) {
- /* read once to clear */
- ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &phy_data);
- if (ret_val)
- return ret_val;
- /* and again to get new status */
- ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &phy_data);
- if (ret_val)
- return ret_val;
-
- /* check for PCS lock */
- if (!(phy_data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS))
- return E1000_SUCCESS;
-
- /* Issue PHY reset */
- e1000_phy_hw_reset(hw);
- mdelay(5);
- }
- /* Disable GigE link negotiation */
- reg = er32(PHY_CTRL);
- ew32(PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
- E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
-
- /* unable to acquire PCS lock */
- return E1000_ERR_PHY;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Probes the expected PHY address for known PHY IDs
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_detect_gig_phy(struct e1000_hw *hw)
-{
- s32 phy_init_status, ret_val;
- u16 phy_id_high, phy_id_low;
- bool match = false;
-
- DEBUGFUNC("e1000_detect_gig_phy");
-
- if (hw->phy_id != 0)
- return E1000_SUCCESS;
-
- /* The 82571 firmware may still be configuring the PHY. In this
- * case, we cannot access the PHY until the configuration is done. So
- * we explicitly set the PHY values. */
- if (hw->mac_type == e1000_82571 ||
- hw->mac_type == e1000_82572) {
- hw->phy_id = IGP01E1000_I_PHY_ID;
- hw->phy_type = e1000_phy_igp_2;
- return E1000_SUCCESS;
- }
-
- /* ESB-2 PHY reads require e1000_phy_gg82563 to be set because of a work-
- * around that forces PHY page 0 to be set or the reads fail. The rest of
- * the code in this routine uses e1000_read_phy_reg to read the PHY ID.
- * So for ESB-2 we need to have this set so our reads won't fail. If the
- * attached PHY is not a e1000_phy_gg82563, the routines below will figure
- * this out as well. */
- if (hw->mac_type == e1000_80003es2lan)
- hw->phy_type = e1000_phy_gg82563;
-
- /* Read the PHY ID Registers to identify which PHY is onboard. */
- ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
- if (ret_val)
- return ret_val;
-
- hw->phy_id = (u32)(phy_id_high << 16);
- udelay(20);
- ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
- if (ret_val)
- return ret_val;
-
- hw->phy_id |= (u32)(phy_id_low & PHY_REVISION_MASK);
- hw->phy_revision = (u32)phy_id_low & ~PHY_REVISION_MASK;
-
- switch (hw->mac_type) {
- case e1000_82543:
- if (hw->phy_id == M88E1000_E_PHY_ID) match = true;
- break;
- case e1000_82544:
- if (hw->phy_id == M88E1000_I_PHY_ID) match = true;
- break;
- case e1000_82540:
- case e1000_82545:
- case e1000_82545_rev_3:
- case e1000_82546:
- case e1000_82546_rev_3:
- if (hw->phy_id == M88E1011_I_PHY_ID) match = true;
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
- if (hw->phy_id == IGP01E1000_I_PHY_ID) match = true;
- break;
- case e1000_82573:
- if (hw->phy_id == M88E1111_I_PHY_ID) match = true;
- break;
- case e1000_80003es2lan:
- if (hw->phy_id == GG82563_E_PHY_ID) match = true;
- break;
- case e1000_ich8lan:
- if (hw->phy_id == IGP03E1000_E_PHY_ID) match = true;
- if (hw->phy_id == IFE_E_PHY_ID) match = true;
- if (hw->phy_id == IFE_PLUS_E_PHY_ID) match = true;
- if (hw->phy_id == IFE_C_E_PHY_ID) match = true;
- break;
- default:
- DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
- return -E1000_ERR_CONFIG;
- }
- phy_init_status = e1000_set_phy_type(hw);
-
- if ((match) && (phy_init_status == E1000_SUCCESS)) {
- DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
- return E1000_SUCCESS;
- }
- DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
- return -E1000_ERR_PHY;
-}
-
-/******************************************************************************
-* Resets the PHY's DSP
-*
-* hw - Struct containing variables accessed by shared code
-******************************************************************************/
-static s32 e1000_phy_reset_dsp(struct e1000_hw *hw)
-{
- s32 ret_val;
- DEBUGFUNC("e1000_phy_reset_dsp");
-
- do {
- if (hw->phy_type != e1000_phy_gg82563) {
- ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
- if (ret_val) break;
- }
- ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
- if (ret_val) break;
- ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
- if (ret_val) break;
- ret_val = E1000_SUCCESS;
- } while (0);
-
- return ret_val;
-}
-
-/******************************************************************************
-* Get PHY information from various PHY registers for igp PHY only.
-*
-* hw - Struct containing variables accessed by shared code
-* phy_info - PHY information structure
-******************************************************************************/
-static s32 e1000_phy_igp_get_info(struct e1000_hw *hw,
- struct e1000_phy_info *phy_info)
-{
- s32 ret_val;
- u16 phy_data, min_length, max_length, average;
- e1000_rev_polarity polarity;
-
- DEBUGFUNC("e1000_phy_igp_get_info");
-
- /* The downshift status is checked only once, after link is established,
- * and it stored in the hw->speed_downgraded parameter. */
- phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
-
- /* IGP01E1000 does not need to support it. */
- phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
-
- /* IGP01E1000 always correct polarity reversal */
- phy_info->polarity_correction = e1000_polarity_reversal_enabled;
-
- /* Check polarity status */
- ret_val = e1000_check_polarity(hw, &polarity);
- if (ret_val)
- return ret_val;
-
- phy_info->cable_polarity = polarity;
-
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & IGP01E1000_PSSR_MDIX) >>
- IGP01E1000_PSSR_MDIX_SHIFT);
-
- if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
- /* Local/Remote Receiver Information are only valid at 1000 Mbps */
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
- e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
- phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
- e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
-
- /* Get cable length */
- ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
- if (ret_val)
- return ret_val;
-
- /* Translate to old method */
- average = (max_length + min_length) / 2;
-
- if (average <= e1000_igp_cable_length_50)
- phy_info->cable_length = e1000_cable_length_50;
- else if (average <= e1000_igp_cable_length_80)
- phy_info->cable_length = e1000_cable_length_50_80;
- else if (average <= e1000_igp_cable_length_110)
- phy_info->cable_length = e1000_cable_length_80_110;
- else if (average <= e1000_igp_cable_length_140)
- phy_info->cable_length = e1000_cable_length_110_140;
- else
- phy_info->cable_length = e1000_cable_length_140;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Get PHY information from various PHY registers for ife PHY only.
-*
-* hw - Struct containing variables accessed by shared code
-* phy_info - PHY information structure
-******************************************************************************/
-static s32 e1000_phy_ife_get_info(struct e1000_hw *hw,
- struct e1000_phy_info *phy_info)
-{
- s32 ret_val;
- u16 phy_data;
- e1000_rev_polarity polarity;
-
- DEBUGFUNC("e1000_phy_ife_get_info");
-
- phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
- phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
-
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
- phy_info->polarity_correction =
- ((phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
- IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT) ?
- e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
-
- if (phy_info->polarity_correction == e1000_polarity_reversal_enabled) {
- ret_val = e1000_check_polarity(hw, &polarity);
- if (ret_val)
- return ret_val;
- } else {
- /* Polarity is forced. */
- polarity = ((phy_data & IFE_PSC_FORCE_POLARITY) >>
- IFE_PSC_FORCE_POLARITY_SHIFT) ?
- e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
- }
- phy_info->cable_polarity = polarity;
-
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_info->mdix_mode = (e1000_auto_x_mode)
- ((phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
- IFE_PMC_MDIX_MODE_SHIFT);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Get PHY information from various PHY registers fot m88 PHY only.
-*
-* hw - Struct containing variables accessed by shared code
-* phy_info - PHY information structure
-******************************************************************************/
-static s32 e1000_phy_m88_get_info(struct e1000_hw *hw,
- struct e1000_phy_info *phy_info)
-{
- s32 ret_val;
- u16 phy_data;
- e1000_rev_polarity polarity;
-
- DEBUGFUNC("e1000_phy_m88_get_info");
-
- /* The downshift status is checked only once, after link is established,
- * and it stored in the hw->speed_downgraded parameter. */
- phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_info->extended_10bt_distance =
- ((phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
- M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT) ?
- e1000_10bt_ext_dist_enable_lower : e1000_10bt_ext_dist_enable_normal;
-
- phy_info->polarity_correction =
- ((phy_data & M88E1000_PSCR_POLARITY_REVERSAL) >>
- M88E1000_PSCR_POLARITY_REVERSAL_SHIFT) ?
- e1000_polarity_reversal_disabled : e1000_polarity_reversal_enabled;
-
- /* Check polarity status */
- ret_val = e1000_check_polarity(hw, &polarity);
- if (ret_val)
- return ret_val;
- phy_info->cable_polarity = polarity;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_info->mdix_mode = (e1000_auto_x_mode)((phy_data & M88E1000_PSSR_MDIX) >>
- M88E1000_PSSR_MDIX_SHIFT);
-
- if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
- /* Cable Length Estimation and Local/Remote Receiver Information
- * are only valid at 1000 Mbps.
- */
- if (hw->phy_type != e1000_phy_gg82563) {
- phy_info->cable_length = (e1000_cable_length)((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT);
- } else {
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_info->cable_length = (e1000_cable_length)(phy_data & GG82563_DSPD_CABLE_LENGTH);
- }
-
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_info->local_rx = ((phy_data & SR_1000T_LOCAL_RX_STATUS) >>
- SR_1000T_LOCAL_RX_STATUS_SHIFT) ?
- e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
- phy_info->remote_rx = ((phy_data & SR_1000T_REMOTE_RX_STATUS) >>
- SR_1000T_REMOTE_RX_STATUS_SHIFT) ?
- e1000_1000t_rx_status_ok : e1000_1000t_rx_status_not_ok;
-
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
-* Get PHY information from various PHY registers
-*
-* hw - Struct containing variables accessed by shared code
-* phy_info - PHY information structure
-******************************************************************************/
-s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
-{
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_phy_get_info");
-
- phy_info->cable_length = e1000_cable_length_undefined;
- phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_undefined;
- phy_info->cable_polarity = e1000_rev_polarity_undefined;
- phy_info->downshift = e1000_downshift_undefined;
- phy_info->polarity_correction = e1000_polarity_reversal_undefined;
- phy_info->mdix_mode = e1000_auto_x_mode_undefined;
- phy_info->local_rx = e1000_1000t_rx_status_undefined;
- phy_info->remote_rx = e1000_1000t_rx_status_undefined;
-
- if (hw->media_type != e1000_media_type_copper) {
- DEBUGOUT("PHY info is only valid for copper media\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
- DEBUGOUT("PHY info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- if (hw->phy_type == e1000_phy_igp ||
- hw->phy_type == e1000_phy_igp_3 ||
- hw->phy_type == e1000_phy_igp_2)
- return e1000_phy_igp_get_info(hw, phy_info);
- else if (hw->phy_type == e1000_phy_ife)
- return e1000_phy_ife_get_info(hw, phy_info);
- else
- return e1000_phy_m88_get_info(hw, phy_info);
-}
-
-s32 e1000_validate_mdi_setting(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_validate_mdi_settings");
-
- if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
- DEBUGOUT("Invalid MDI setting detected\n");
- hw->mdix = 1;
- return -E1000_ERR_CONFIG;
- }
- return E1000_SUCCESS;
-}
-
-
-/******************************************************************************
- * Sets up eeprom variables in the hw struct. Must be called after mac_type
- * is configured. Additionally, if this is ICH8, the flash controller GbE
- * registers must be mapped, or this will crash.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_init_eeprom_params(struct e1000_hw *hw)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- u32 eecd = er32(EECD);
- s32 ret_val = E1000_SUCCESS;
- u16 eeprom_size;
-
- DEBUGFUNC("e1000_init_eeprom_params");
-
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- case e1000_82544:
- eeprom->type = e1000_eeprom_microwire;
- eeprom->word_size = 64;
- eeprom->opcode_bits = 3;
- eeprom->address_bits = 6;
- eeprom->delay_usec = 50;
- eeprom->use_eerd = false;
- eeprom->use_eewr = false;
- break;
- case e1000_82540:
- case e1000_82545:
- case e1000_82545_rev_3:
- case e1000_82546:
- case e1000_82546_rev_3:
- eeprom->type = e1000_eeprom_microwire;
- eeprom->opcode_bits = 3;
- eeprom->delay_usec = 50;
- if (eecd & E1000_EECD_SIZE) {
- eeprom->word_size = 256;
- eeprom->address_bits = 8;
- } else {
- eeprom->word_size = 64;
- eeprom->address_bits = 6;
- }
- eeprom->use_eerd = false;
- eeprom->use_eewr = false;
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
- if (eecd & E1000_EECD_TYPE) {
- eeprom->type = e1000_eeprom_spi;
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
- } else {
- eeprom->type = e1000_eeprom_microwire;
- eeprom->opcode_bits = 3;
- eeprom->delay_usec = 50;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->word_size = 256;
- eeprom->address_bits = 8;
- } else {
- eeprom->word_size = 64;
- eeprom->address_bits = 6;
- }
- }
- eeprom->use_eerd = false;
- eeprom->use_eewr = false;
- break;
- case e1000_82571:
- case e1000_82572:
- eeprom->type = e1000_eeprom_spi;
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
- eeprom->use_eerd = false;
- eeprom->use_eewr = false;
- break;
- case e1000_82573:
- eeprom->type = e1000_eeprom_spi;
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
- eeprom->use_eerd = true;
- eeprom->use_eewr = true;
- if (!e1000_is_onboard_nvm_eeprom(hw)) {
- eeprom->type = e1000_eeprom_flash;
- eeprom->word_size = 2048;
-
- /* Ensure that the Autonomous FLASH update bit is cleared due to
- * Flash update issue on parts which use a FLASH for NVM. */
- eecd &= ~E1000_EECD_AUPDEN;
- ew32(EECD, eecd);
- }
- break;
- case e1000_80003es2lan:
- eeprom->type = e1000_eeprom_spi;
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
- if (eecd & E1000_EECD_ADDR_BITS) {
- eeprom->page_size = 32;
- eeprom->address_bits = 16;
- } else {
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
- eeprom->use_eerd = true;
- eeprom->use_eewr = false;
- break;
- case e1000_ich8lan:
- {
- s32 i = 0;
- u32 flash_size = E1000_READ_ICH_FLASH_REG(hw, ICH_FLASH_GFPREG);
-
- eeprom->type = e1000_eeprom_ich8;
- eeprom->use_eerd = false;
- eeprom->use_eewr = false;
- eeprom->word_size = E1000_SHADOW_RAM_WORDS;
-
- /* Zero the shadow RAM structure. But don't load it from NVM
- * so as to save time for driver init */
- if (hw->eeprom_shadow_ram != NULL) {
- for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
- hw->eeprom_shadow_ram[i].modified = false;
- hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
- }
- }
-
- hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) *
- ICH_FLASH_SECTOR_SIZE;
-
- hw->flash_bank_size = ((flash_size >> 16) & ICH_GFPREG_BASE_MASK) + 1;
- hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK);
-
- hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE;
-
- hw->flash_bank_size /= 2 * sizeof(u16);
-
- break;
- }
- default:
- break;
- }
-
- if (eeprom->type == e1000_eeprom_spi) {
- /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
- * 32KB (incremented by powers of 2).
- */
- if (hw->mac_type <= e1000_82547_rev_2) {
- /* Set to default value for initial eeprom read. */
- eeprom->word_size = 64;
- ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
- if (ret_val)
- return ret_val;
- eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
- /* 256B eeprom size was not supported in earlier hardware, so we
- * bump eeprom_size up one to ensure that "1" (which maps to 256B)
- * is never the result used in the shifting logic below. */
- if (eeprom_size)
- eeprom_size++;
- } else {
- eeprom_size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
- E1000_EECD_SIZE_EX_SHIFT);
- }
-
- eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
- }
- return ret_val;
-}
-
-/******************************************************************************
- * Raises the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void e1000_raise_ee_clk(struct e1000_hw *hw, u32 *eecd)
-{
- /* Raise the clock input to the EEPROM (by setting the SK bit), and then
- * wait <delay> microseconds.
- */
- *eecd = *eecd | E1000_EECD_SK;
- ew32(EECD, *eecd);
- E1000_WRITE_FLUSH();
- udelay(hw->eeprom.delay_usec);
-}
-
-/******************************************************************************
- * Lowers the EEPROM's clock input.
- *
- * hw - Struct containing variables accessed by shared code
- * eecd - EECD's current value
- *****************************************************************************/
-static void e1000_lower_ee_clk(struct e1000_hw *hw, u32 *eecd)
-{
- /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
- * wait 50 microseconds.
- */
- *eecd = *eecd & ~E1000_EECD_SK;
- ew32(EECD, *eecd);
- E1000_WRITE_FLUSH();
- udelay(hw->eeprom.delay_usec);
-}
-
-/******************************************************************************
- * Shift data bits out to the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * data - data to send to the EEPROM
- * count - number of bits to shift out
- *****************************************************************************/
-static void e1000_shift_out_ee_bits(struct e1000_hw *hw, u16 data, u16 count)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- u32 eecd;
- u32 mask;
-
- /* We need to shift "count" bits out to the EEPROM. So, value in the
- * "data" parameter will be shifted out to the EEPROM one bit at a time.
- * In order to do this, "data" must be broken down into bits.
- */
- mask = 0x01 << (count - 1);
- eecd = er32(EECD);
- if (eeprom->type == e1000_eeprom_microwire) {
- eecd &= ~E1000_EECD_DO;
- } else if (eeprom->type == e1000_eeprom_spi) {
- eecd |= E1000_EECD_DO;
- }
- do {
- /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
- * and then raising and then lowering the clock (the SK bit controls
- * the clock input to the EEPROM). A "0" is shifted out to the EEPROM
- * by setting "DI" to "0" and then raising and then lowering the clock.
- */
- eecd &= ~E1000_EECD_DI;
-
- if (data & mask)
- eecd |= E1000_EECD_DI;
-
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
-
- udelay(eeprom->delay_usec);
-
- e1000_raise_ee_clk(hw, &eecd);
- e1000_lower_ee_clk(hw, &eecd);
-
- mask = mask >> 1;
-
- } while (mask);
-
- /* We leave the "DI" bit set to "0" when we leave this routine. */
- eecd &= ~E1000_EECD_DI;
- ew32(EECD, eecd);
-}
-
-/******************************************************************************
- * Shift data bits in from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static u16 e1000_shift_in_ee_bits(struct e1000_hw *hw, u16 count)
-{
- u32 eecd;
- u32 i;
- u16 data;
-
- /* In order to read a register from the EEPROM, we need to shift 'count'
- * bits in from the EEPROM. Bits are "shifted in" by raising the clock
- * input to the EEPROM (setting the SK bit), and then reading the value of
- * the "DO" bit. During this "shifting in" process the "DI" bit should
- * always be clear.
- */
-
- eecd = er32(EECD);
-
- eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
- data = 0;
-
- for (i = 0; i < count; i++) {
- data = data << 1;
- e1000_raise_ee_clk(hw, &eecd);
-
- eecd = er32(EECD);
-
- eecd &= ~(E1000_EECD_DI);
- if (eecd & E1000_EECD_DO)
- data |= 1;
-
- e1000_lower_ee_clk(hw, &eecd);
- }
-
- return data;
-}
-
-/******************************************************************************
- * Prepares EEPROM for access
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
- * function should be called before issuing a command to the EEPROM.
- *****************************************************************************/
-static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- u32 eecd, i=0;
-
- DEBUGFUNC("e1000_acquire_eeprom");
-
- if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
- return -E1000_ERR_SWFW_SYNC;
- eecd = er32(EECD);
-
- if (hw->mac_type != e1000_82573) {
- /* Request EEPROM Access */
- if (hw->mac_type > e1000_82544) {
- eecd |= E1000_EECD_REQ;
- ew32(EECD, eecd);
- eecd = er32(EECD);
- while ((!(eecd & E1000_EECD_GNT)) &&
- (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
- i++;
- udelay(5);
- eecd = er32(EECD);
- }
- if (!(eecd & E1000_EECD_GNT)) {
- eecd &= ~E1000_EECD_REQ;
- ew32(EECD, eecd);
- DEBUGOUT("Could not acquire EEPROM grant\n");
- e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
- return -E1000_ERR_EEPROM;
- }
- }
- }
-
- /* Setup EEPROM for Read/Write */
-
- if (eeprom->type == e1000_eeprom_microwire) {
- /* Clear SK and DI */
- eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
- ew32(EECD, eecd);
-
- /* Set CS */
- eecd |= E1000_EECD_CS;
- ew32(EECD, eecd);
- } else if (eeprom->type == e1000_eeprom_spi) {
- /* Clear SK and CS */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- ew32(EECD, eecd);
- udelay(1);
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Returns EEPROM to a "standby" state
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void e1000_standby_eeprom(struct e1000_hw *hw)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- u32 eecd;
-
- eecd = er32(EECD);
-
- if (eeprom->type == e1000_eeprom_microwire) {
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(eeprom->delay_usec);
-
- /* Clock high */
- eecd |= E1000_EECD_SK;
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(eeprom->delay_usec);
-
- /* Select EEPROM */
- eecd |= E1000_EECD_CS;
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(eeprom->delay_usec);
-
- /* Clock low */
- eecd &= ~E1000_EECD_SK;
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(eeprom->delay_usec);
- } else if (eeprom->type == e1000_eeprom_spi) {
- /* Toggle CS to flush commands */
- eecd |= E1000_EECD_CS;
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(eeprom->delay_usec);
- eecd &= ~E1000_EECD_CS;
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(eeprom->delay_usec);
- }
-}
-
-/******************************************************************************
- * Terminates a command by inverting the EEPROM's chip select pin
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void e1000_release_eeprom(struct e1000_hw *hw)
-{
- u32 eecd;
-
- DEBUGFUNC("e1000_release_eeprom");
-
- eecd = er32(EECD);
-
- if (hw->eeprom.type == e1000_eeprom_spi) {
- eecd |= E1000_EECD_CS; /* Pull CS high */
- eecd &= ~E1000_EECD_SK; /* Lower SCK */
-
- ew32(EECD, eecd);
-
- udelay(hw->eeprom.delay_usec);
- } else if (hw->eeprom.type == e1000_eeprom_microwire) {
- /* cleanup eeprom */
-
- /* CS on Microwire is active-high */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
-
- ew32(EECD, eecd);
-
- /* Rising edge of clock */
- eecd |= E1000_EECD_SK;
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(hw->eeprom.delay_usec);
-
- /* Falling edge of clock */
- eecd &= ~E1000_EECD_SK;
- ew32(EECD, eecd);
- E1000_WRITE_FLUSH();
- udelay(hw->eeprom.delay_usec);
- }
-
- /* Stop requesting EEPROM access */
- if (hw->mac_type > e1000_82544) {
- eecd &= ~E1000_EECD_REQ;
- ew32(EECD, eecd);
- }
-
- e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
-}
-
-/******************************************************************************
- * Reads a 16 bit word from the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
-{
- u16 retry_count = 0;
- u8 spi_stat_reg;
-
- DEBUGFUNC("e1000_spi_eeprom_ready");
-
- /* Read "Status Register" repeatedly until the LSB is cleared. The
- * EEPROM will signal that the command has been completed by clearing
- * bit 0 of the internal status register. If it's not cleared within
- * 5 milliseconds, then error out.
- */
- retry_count = 0;
- do {
- e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
- hw->eeprom.opcode_bits);
- spi_stat_reg = (u8)e1000_shift_in_ee_bits(hw, 8);
- if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
- break;
-
- udelay(5);
- retry_count += 5;
-
- e1000_standby_eeprom(hw);
- } while (retry_count < EEPROM_MAX_RETRY_SPI);
-
- /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
- * only 0-5mSec on 5V devices)
- */
- if (retry_count >= EEPROM_MAX_RETRY_SPI) {
- DEBUGOUT("SPI EEPROM Status error\n");
- return -E1000_ERR_EEPROM;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Reads a 16 bit word from the EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- s32 ret;
- spin_lock(&e1000_eeprom_lock);
- ret = e1000_do_read_eeprom(hw, offset, words, data);
- spin_unlock(&e1000_eeprom_lock);
- return ret;
-}
-
-static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- u32 i = 0;
-
- DEBUGFUNC("e1000_read_eeprom");
-
- /* If eeprom is not yet detected, do so now */
- if (eeprom->word_size == 0)
- e1000_init_eeprom_params(hw);
-
- /* A check for invalid values: offset too large, too many words, and not
- * enough words.
- */
- if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
- (words == 0)) {
- DEBUGOUT2("\"words\" parameter out of bounds. Words = %d, size = %d\n", offset, eeprom->word_size);
- return -E1000_ERR_EEPROM;
- }
-
- /* EEPROM's that don't use EERD to read require us to bit-bang the SPI
- * directly. In this case, we need to acquire the EEPROM so that
- * FW or other port software does not interrupt.
- */
- if (e1000_is_onboard_nvm_eeprom(hw) && !hw->eeprom.use_eerd) {
- /* Prepare the EEPROM for bit-bang reading */
- if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
- }
-
- /* Eerd register EEPROM access requires no eeprom aquire/release */
- if (eeprom->use_eerd)
- return e1000_read_eeprom_eerd(hw, offset, words, data);
-
- /* ICH EEPROM access is done via the ICH flash controller */
- if (eeprom->type == e1000_eeprom_ich8)
- return e1000_read_eeprom_ich8(hw, offset, words, data);
-
- /* Set up the SPI or Microwire EEPROM for bit-bang reading. We have
- * acquired the EEPROM at this point, so any returns should relase it */
- if (eeprom->type == e1000_eeprom_spi) {
- u16 word_in;
- u8 read_opcode = EEPROM_READ_OPCODE_SPI;
-
- if (e1000_spi_eeprom_ready(hw)) {
- e1000_release_eeprom(hw);
- return -E1000_ERR_EEPROM;
- }
-
- e1000_standby_eeprom(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the opcode */
- if ((eeprom->address_bits == 8) && (offset >= 128))
- read_opcode |= EEPROM_A8_OPCODE_SPI;
-
- /* Send the READ command (opcode + addr) */
- e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
- e1000_shift_out_ee_bits(hw, (u16)(offset*2), eeprom->address_bits);
-
- /* Read the data. The address of the eeprom internally increments with
- * each byte (spi) being read, saving on the overhead of eeprom setup
- * and tear-down. The address counter will roll over if reading beyond
- * the size of the eeprom, thus allowing the entire memory to be read
- * starting from any offset. */
- for (i = 0; i < words; i++) {
- word_in = e1000_shift_in_ee_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
- } else if (eeprom->type == e1000_eeprom_microwire) {
- for (i = 0; i < words; i++) {
- /* Send the READ command (opcode + addr) */
- e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
- eeprom->opcode_bits);
- e1000_shift_out_ee_bits(hw, (u16)(offset + i),
- eeprom->address_bits);
-
- /* Read the data. For microwire, each word requires the overhead
- * of eeprom setup and tear-down. */
- data[i] = e1000_shift_in_ee_bits(hw, 16);
- e1000_standby_eeprom(hw);
- }
- }
-
- /* End this read operation */
- e1000_release_eeprom(hw);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Reads a 16 bit word from the EEPROM using the EERD register.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-static s32 e1000_read_eeprom_eerd(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- u32 i, eerd = 0;
- s32 error = 0;
-
- for (i = 0; i < words; i++) {
- eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
- E1000_EEPROM_RW_REG_START;
-
- ew32(EERD, eerd);
- error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
-
- if (error) {
- break;
- }
- data[i] = (er32(EERD) >> E1000_EEPROM_RW_REG_DATA);
-
- }
-
- return error;
-}
-
-/******************************************************************************
- * Writes a 16 bit word from the EEPROM using the EEWR register.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-static s32 e1000_write_eeprom_eewr(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- u32 register_value = 0;
- u32 i = 0;
- s32 error = 0;
-
- if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
- return -E1000_ERR_SWFW_SYNC;
-
- for (i = 0; i < words; i++) {
- register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) |
- ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) |
- E1000_EEPROM_RW_REG_START;
-
- error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
- if (error) {
- break;
- }
-
- ew32(EEWR, register_value);
-
- error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
-
- if (error) {
- break;
- }
- }
-
- e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
- return error;
-}
-
-/******************************************************************************
- * Polls the status bit (bit 1) of the EERD to determine when the read is done.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
-{
- u32 attempts = 100000;
- u32 i, reg = 0;
- s32 done = E1000_ERR_EEPROM;
-
- for (i = 0; i < attempts; i++) {
- if (eerd == E1000_EEPROM_POLL_READ)
- reg = er32(EERD);
- else
- reg = er32(EEWR);
-
- if (reg & E1000_EEPROM_RW_REG_DONE) {
- done = E1000_SUCCESS;
- break;
- }
- udelay(5);
- }
-
- return done;
-}
-
-/***************************************************************************
-* Description: Determines if the onboard NVM is FLASH or EEPROM.
-*
-* hw - Struct containing variables accessed by shared code
-****************************************************************************/
-static bool e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
-{
- u32 eecd = 0;
-
- DEBUGFUNC("e1000_is_onboard_nvm_eeprom");
-
- if (hw->mac_type == e1000_ich8lan)
- return false;
-
- if (hw->mac_type == e1000_82573) {
- eecd = er32(EECD);
-
- /* Isolate bits 15 & 16 */
- eecd = ((eecd >> 15) & 0x03);
-
- /* If both bits are set, device is Flash type */
- if (eecd == 0x03) {
- return false;
- }
- }
- return true;
-}
-
-/******************************************************************************
- * Verifies that the EEPROM has a valid checksum
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Reads the first 64 16 bit words of the EEPROM and sums the values read.
- * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
- * valid.
- *****************************************************************************/
-s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw)
-{
- u16 checksum = 0;
- u16 i, eeprom_data;
-
- DEBUGFUNC("e1000_validate_eeprom_checksum");
-
- if ((hw->mac_type == e1000_82573) && !e1000_is_onboard_nvm_eeprom(hw)) {
- /* Check bit 4 of word 10h. If it is 0, firmware is done updating
- * 10h-12h. Checksum may need to be fixed. */
- e1000_read_eeprom(hw, 0x10, 1, &eeprom_data);
- if ((eeprom_data & 0x10) == 0) {
- /* Read 0x23 and check bit 15. This bit is a 1 when the checksum
- * has already been fixed. If the checksum is still wrong and this
- * bit is a 1, we need to return bad checksum. Otherwise, we need
- * to set this bit to a 1 and update the checksum. */
- e1000_read_eeprom(hw, 0x23, 1, &eeprom_data);
- if ((eeprom_data & 0x8000) == 0) {
- eeprom_data |= 0x8000;
- e1000_write_eeprom(hw, 0x23, 1, &eeprom_data);
- e1000_update_eeprom_checksum(hw);
- }
- }
- }
-
- if (hw->mac_type == e1000_ich8lan) {
- /* Drivers must allocate the shadow ram structure for the
- * EEPROM checksum to be updated. Otherwise, this bit as well
- * as the checksum must both be set correctly for this
- * validation to pass.
- */
- e1000_read_eeprom(hw, 0x19, 1, &eeprom_data);
- if ((eeprom_data & 0x40) == 0) {
- eeprom_data |= 0x40;
- e1000_write_eeprom(hw, 0x19, 1, &eeprom_data);
- e1000_update_eeprom_checksum(hw);
- }
- }
-
- for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
- if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
- }
-
- if (checksum == (u16)EEPROM_SUM)
- return E1000_SUCCESS;
- else {
- DEBUGOUT("EEPROM Checksum Invalid\n");
- return -E1000_ERR_EEPROM;
- }
-}
-
-/******************************************************************************
- * Calculates the EEPROM checksum and writes it to the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
- * Writes the difference to word offset 63 of the EEPROM.
- *****************************************************************************/
-s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
-{
- u32 ctrl_ext;
- u16 checksum = 0;
- u16 i, eeprom_data;
-
- DEBUGFUNC("e1000_update_eeprom_checksum");
-
- for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
- if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
- }
- checksum = (u16)EEPROM_SUM - checksum;
- if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
- DEBUGOUT("EEPROM Write Error\n");
- return -E1000_ERR_EEPROM;
- } else if (hw->eeprom.type == e1000_eeprom_flash) {
- e1000_commit_shadow_ram(hw);
- } else if (hw->eeprom.type == e1000_eeprom_ich8) {
- e1000_commit_shadow_ram(hw);
- /* Reload the EEPROM, or else modifications will not appear
- * until after next adapter reset. */
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- ew32(CTRL_EXT, ctrl_ext);
- msleep(10);
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Parent function for writing words to the different EEPROM types.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset within the EEPROM to be written to
- * words - number of words to write
- * data - 16 bit word to be written to the EEPROM
- *
- * If e1000_update_eeprom_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
- *****************************************************************************/
-s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- s32 ret;
- spin_lock(&e1000_eeprom_lock);
- ret = e1000_do_write_eeprom(hw, offset, words, data);
- spin_unlock(&e1000_eeprom_lock);
- return ret;
-}
-
-
-static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- s32 status = 0;
-
- DEBUGFUNC("e1000_write_eeprom");
-
- /* If eeprom is not yet detected, do so now */
- if (eeprom->word_size == 0)
- e1000_init_eeprom_params(hw);
-
- /* A check for invalid values: offset too large, too many words, and not
- * enough words.
- */
- if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
- (words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
- return -E1000_ERR_EEPROM;
- }
-
- /* 82573 writes only through eewr */
- if (eeprom->use_eewr)
- return e1000_write_eeprom_eewr(hw, offset, words, data);
-
- if (eeprom->type == e1000_eeprom_ich8)
- return e1000_write_eeprom_ich8(hw, offset, words, data);
-
- /* Prepare the EEPROM for writing */
- if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
-
- if (eeprom->type == e1000_eeprom_microwire) {
- status = e1000_write_eeprom_microwire(hw, offset, words, data);
- } else {
- status = e1000_write_eeprom_spi(hw, offset, words, data);
- msleep(10);
- }
-
- /* Done with writing */
- e1000_release_eeprom(hw);
-
- return status;
-}
-
-/******************************************************************************
- * Writes a 16 bit word to a given offset in an SPI EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset within the EEPROM to be written to
- * words - number of words to write
- * data - pointer to array of 8 bit words to be written to the EEPROM
- *
- *****************************************************************************/
-static s32 e1000_write_eeprom_spi(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- u16 widx = 0;
-
- DEBUGFUNC("e1000_write_eeprom_spi");
-
- while (widx < words) {
- u8 write_opcode = EEPROM_WRITE_OPCODE_SPI;
-
- if (e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
-
- e1000_standby_eeprom(hw);
-
- /* Send the WRITE ENABLE command (8 bit opcode ) */
- e1000_shift_out_ee_bits(hw, EEPROM_WREN_OPCODE_SPI,
- eeprom->opcode_bits);
-
- e1000_standby_eeprom(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the opcode */
- if ((eeprom->address_bits == 8) && (offset >= 128))
- write_opcode |= EEPROM_A8_OPCODE_SPI;
-
- /* Send the Write command (8-bit opcode + addr) */
- e1000_shift_out_ee_bits(hw, write_opcode, eeprom->opcode_bits);
-
- e1000_shift_out_ee_bits(hw, (u16)((offset + widx)*2),
- eeprom->address_bits);
-
- /* Send the data */
-
- /* Loop to allow for up to whole page write (32 bytes) of eeprom */
- while (widx < words) {
- u16 word_out = data[widx];
- word_out = (word_out >> 8) | (word_out << 8);
- e1000_shift_out_ee_bits(hw, word_out, 16);
- widx++;
-
- /* Some larger eeprom sizes are capable of a 32-byte PAGE WRITE
- * operation, while the smaller eeproms are capable of an 8-byte
- * PAGE WRITE operation. Break the inner loop to pass new address
- */
- if ((((offset + widx)*2) % eeprom->page_size) == 0) {
- e1000_standby_eeprom(hw);
- break;
- }
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Writes a 16 bit word to a given offset in a Microwire EEPROM.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset within the EEPROM to be written to
- * words - number of words to write
- * data - pointer to array of 16 bit words to be written to the EEPROM
- *
- *****************************************************************************/
-static s32 e1000_write_eeprom_microwire(struct e1000_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- u32 eecd;
- u16 words_written = 0;
- u16 i = 0;
-
- DEBUGFUNC("e1000_write_eeprom_microwire");
-
- /* Send the write enable command to the EEPROM (3-bit opcode plus
- * 6/8-bit dummy address beginning with 11). It's less work to include
- * the 11 of the dummy address as part of the opcode than it is to shift
- * it over the correct number of bits for the address. This puts the
- * EEPROM into write/erase mode.
- */
- e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE_MICROWIRE,
- (u16)(eeprom->opcode_bits + 2));
-
- e1000_shift_out_ee_bits(hw, 0, (u16)(eeprom->address_bits - 2));
-
- /* Prepare the EEPROM */
- e1000_standby_eeprom(hw);
-
- while (words_written < words) {
- /* Send the Write command (3-bit opcode + addr) */
- e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE_MICROWIRE,
- eeprom->opcode_bits);
-
- e1000_shift_out_ee_bits(hw, (u16)(offset + words_written),
- eeprom->address_bits);
-
- /* Send the data */
- e1000_shift_out_ee_bits(hw, data[words_written], 16);
-
- /* Toggle the CS line. This in effect tells the EEPROM to execute
- * the previous command.
- */
- e1000_standby_eeprom(hw);
-
- /* Read DO repeatedly until it is high (equal to '1'). The EEPROM will
- * signal that the command has been completed by raising the DO signal.
- * If DO does not go high in 10 milliseconds, then error out.
- */
- for (i = 0; i < 200; i++) {
- eecd = er32(EECD);
- if (eecd & E1000_EECD_DO) break;
- udelay(50);
- }
- if (i == 200) {
- DEBUGOUT("EEPROM Write did not complete\n");
- return -E1000_ERR_EEPROM;
- }
-
- /* Recover from write */
- e1000_standby_eeprom(hw);
-
- words_written++;
- }
-
- /* Send the write disable command to the EEPROM (3-bit opcode plus
- * 6/8-bit dummy address beginning with 10). It's less work to include
- * the 10 of the dummy address as part of the opcode than it is to shift
- * it over the correct number of bits for the address. This takes the
- * EEPROM out of write/erase mode.
- */
- e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE_MICROWIRE,
- (u16)(eeprom->opcode_bits + 2));
-
- e1000_shift_out_ee_bits(hw, 0, (u16)(eeprom->address_bits - 2));
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Flushes the cached eeprom to NVM. This is done by saving the modified values
- * in the eeprom cache and the non modified values in the currently active bank
- * to the new bank.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-static s32 e1000_commit_shadow_ram(struct e1000_hw *hw)
-{
- u32 attempts = 100000;
- u32 eecd = 0;
- u32 flop = 0;
- u32 i = 0;
- s32 error = E1000_SUCCESS;
- u32 old_bank_offset = 0;
- u32 new_bank_offset = 0;
- u8 low_byte = 0;
- u8 high_byte = 0;
- bool sector_write_failed = false;
-
- if (hw->mac_type == e1000_82573) {
- /* The flop register will be used to determine if flash type is STM */
- flop = er32(FLOP);
- for (i=0; i < attempts; i++) {
- eecd = er32(EECD);
- if ((eecd & E1000_EECD_FLUPD) == 0) {
- break;
- }
- udelay(5);
- }
-
- if (i == attempts) {
- return -E1000_ERR_EEPROM;
- }
-
- /* If STM opcode located in bits 15:8 of flop, reset firmware */
- if ((flop & 0xFF00) == E1000_STM_OPCODE) {
- ew32(HICR, E1000_HICR_FW_RESET);
- }
-
- /* Perform the flash update */
- ew32(EECD, eecd | E1000_EECD_FLUPD);
-
- for (i=0; i < attempts; i++) {
- eecd = er32(EECD);
- if ((eecd & E1000_EECD_FLUPD) == 0) {
- break;
- }
- udelay(5);
- }
-
- if (i == attempts) {
- return -E1000_ERR_EEPROM;
- }
- }
-
- if (hw->mac_type == e1000_ich8lan && hw->eeprom_shadow_ram != NULL) {
- /* We're writing to the opposite bank so if we're on bank 1,
- * write to bank 0 etc. We also need to erase the segment that
- * is going to be written */
- if (!(er32(EECD) & E1000_EECD_SEC1VAL)) {
- new_bank_offset = hw->flash_bank_size * 2;
- old_bank_offset = 0;
- e1000_erase_ich8_4k_segment(hw, 1);
- } else {
- old_bank_offset = hw->flash_bank_size * 2;
- new_bank_offset = 0;
- e1000_erase_ich8_4k_segment(hw, 0);
- }
-
- sector_write_failed = false;
- /* Loop for every byte in the shadow RAM,
- * which is in units of words. */
- for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
- /* Determine whether to write the value stored
- * in the other NVM bank or a modified value stored
- * in the shadow RAM */
- if (hw->eeprom_shadow_ram[i].modified) {
- low_byte = (u8)hw->eeprom_shadow_ram[i].eeprom_word;
- udelay(100);
- error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset, low_byte);
-
- if (error != E1000_SUCCESS)
- sector_write_failed = true;
- else {
- high_byte =
- (u8)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
- udelay(100);
- }
- } else {
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
- &low_byte);
- udelay(100);
- error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset, low_byte);
-
- if (error != E1000_SUCCESS)
- sector_write_failed = true;
- else {
- e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
- &high_byte);
- udelay(100);
- }
- }
-
- /* If the write of the low byte was successful, go ahead and
- * write the high byte while checking to make sure that if it
- * is the signature byte, then it is handled properly */
- if (!sector_write_failed) {
- /* If the word is 0x13, then make sure the signature bits
- * (15:14) are 11b until the commit has completed.
- * This will allow us to write 10b which indicates the
- * signature is valid. We want to do this after the write
- * has completed so that we don't mark the segment valid
- * while the write is still in progress */
- if (i == E1000_ICH_NVM_SIG_WORD)
- high_byte = E1000_ICH_NVM_SIG_MASK | high_byte;
-
- error = e1000_verify_write_ich8_byte(hw,
- (i << 1) + new_bank_offset + 1, high_byte);
- if (error != E1000_SUCCESS)
- sector_write_failed = true;
-
- } else {
- /* If the write failed then break from the loop and
- * return an error */
- break;
- }
- }
-
- /* Don't bother writing the segment valid bits if sector
- * programming failed. */
- if (!sector_write_failed) {
- /* Finally validate the new segment by setting bit 15:14
- * to 10b in word 0x13 , this can be done without an
- * erase as well since these bits are 11 to start with
- * and we need to change bit 14 to 0b */
- e1000_read_ich8_byte(hw,
- E1000_ICH_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
- &high_byte);
- high_byte &= 0xBF;
- error = e1000_verify_write_ich8_byte(hw,
- E1000_ICH_NVM_SIG_WORD * 2 + 1 + new_bank_offset, high_byte);
- /* And invalidate the previously valid segment by setting
- * its signature word (0x13) high_byte to 0b. This can be
- * done without an erase because flash erase sets all bits
- * to 1's. We can write 1's to 0's without an erase */
- if (error == E1000_SUCCESS) {
- error = e1000_verify_write_ich8_byte(hw,
- E1000_ICH_NVM_SIG_WORD * 2 + 1 + old_bank_offset, 0);
- }
-
- /* Clear the now not used entry in the cache */
- for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
- hw->eeprom_shadow_ram[i].modified = false;
- hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
- }
- }
- }
-
- return error;
-}
-
-/******************************************************************************
- * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
- * second function of dual function devices
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_read_mac_addr(struct e1000_hw *hw)
-{
- u16 offset;
- u16 eeprom_data, i;
-
- DEBUGFUNC("e1000_read_mac_addr");
-
- for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
- offset = i >> 1;
- if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- hw->perm_mac_addr[i] = (u8)(eeprom_data & 0x00FF);
- hw->perm_mac_addr[i+1] = (u8)(eeprom_data >> 8);
- }
-
- switch (hw->mac_type) {
- default:
- break;
- case e1000_82546:
- case e1000_82546_rev_3:
- case e1000_82571:
- case e1000_80003es2lan:
- if (er32(STATUS) & E1000_STATUS_FUNC_1)
- hw->perm_mac_addr[5] ^= 0x01;
- break;
- }
-
- for (i = 0; i < NODE_ADDRESS_SIZE; i++)
- hw->mac_addr[i] = hw->perm_mac_addr[i];
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Initializes receive address filters.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Places the MAC address in receive address register 0 and clears the rest
- * of the receive addresss registers. Clears the multicast table. Assumes
- * the receiver is in reset when the routine is called.
- *****************************************************************************/
-static void e1000_init_rx_addrs(struct e1000_hw *hw)
-{
- u32 i;
- u32 rar_num;
-
- DEBUGFUNC("e1000_init_rx_addrs");
-
- /* Setup the receive address. */
- DEBUGOUT("Programming MAC Address into RAR[0]\n");
-
- e1000_rar_set(hw, hw->mac_addr, 0);
-
- rar_num = E1000_RAR_ENTRIES;
-
- /* Reserve a spot for the Locally Administered Address to work around
- * an 82571 issue in which a reset on one port will reload the MAC on
- * the other port. */
- if ((hw->mac_type == e1000_82571) && (hw->laa_is_present))
- rar_num -= 1;
- if (hw->mac_type == e1000_ich8lan)
- rar_num = E1000_RAR_ENTRIES_ICH8LAN;
-
- /* Zero out the other 15 receive addresses. */
- DEBUGOUT("Clearing RAR[1-15]\n");
- for (i = 1; i < rar_num; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
- E1000_WRITE_FLUSH();
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
- E1000_WRITE_FLUSH();
- }
-}
-
-/******************************************************************************
- * Hashes an address to determine its location in the multicast table
- *
- * hw - Struct containing variables accessed by shared code
- * mc_addr - the multicast address to hash
- *****************************************************************************/
-u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
-{
- u32 hash_value = 0;
-
- /* The portion of the address that is used for the hash table is
- * determined by the mc_filter_type setting.
- */
- switch (hw->mc_filter_type) {
- /* [0] [1] [2] [3] [4] [5]
- * 01 AA 00 12 34 56
- * LSB MSB
- */
- case 0:
- if (hw->mac_type == e1000_ich8lan) {
- /* [47:38] i.e. 0x158 for above example address */
- hash_value = ((mc_addr[4] >> 6) | (((u16)mc_addr[5]) << 2));
- } else {
- /* [47:36] i.e. 0x563 for above example address */
- hash_value = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
- }
- break;
- case 1:
- if (hw->mac_type == e1000_ich8lan) {
- /* [46:37] i.e. 0x2B1 for above example address */
- hash_value = ((mc_addr[4] >> 5) | (((u16)mc_addr[5]) << 3));
- } else {
- /* [46:35] i.e. 0xAC6 for above example address */
- hash_value = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
- }
- break;
- case 2:
- if (hw->mac_type == e1000_ich8lan) {
- /*[45:36] i.e. 0x163 for above example address */
- hash_value = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
- } else {
- /* [45:34] i.e. 0x5D8 for above example address */
- hash_value = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
- }
- break;
- case 3:
- if (hw->mac_type == e1000_ich8lan) {
- /* [43:34] i.e. 0x18D for above example address */
- hash_value = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
- } else {
- /* [43:32] i.e. 0x634 for above example address */
- hash_value = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
- }
- break;
- }
-
- hash_value &= 0xFFF;
- if (hw->mac_type == e1000_ich8lan)
- hash_value &= 0x3FF;
-
- return hash_value;
-}
-
-/******************************************************************************
- * Sets the bit in the multicast table corresponding to the hash value.
- *
- * hw - Struct containing variables accessed by shared code
- * hash_value - Multicast address hash value
- *****************************************************************************/
-void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
-{
- u32 hash_bit, hash_reg;
- u32 mta;
- u32 temp;
-
- /* The MTA is a register array of 128 32-bit registers.
- * It is treated like an array of 4096 bits. We want to set
- * bit BitArray[hash_value]. So we figure out what register
- * the bit is in, read it, OR in the new bit, then write
- * back the new value. The register is determined by the
- * upper 7 bits of the hash value and the bit within that
- * register are determined by the lower 5 bits of the value.
- */
- hash_reg = (hash_value >> 5) & 0x7F;
- if (hw->mac_type == e1000_ich8lan)
- hash_reg &= 0x1F;
-
- hash_bit = hash_value & 0x1F;
-
- mta = E1000_READ_REG_ARRAY(hw, MTA, hash_reg);
-
- mta |= (1 << hash_bit);
-
- /* If we are on an 82544 and we are trying to write an odd offset
- * in the MTA, save off the previous entry before writing and
- * restore the old value after writing.
- */
- if ((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) {
- temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1));
- E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
- E1000_WRITE_FLUSH();
- E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp);
- E1000_WRITE_FLUSH();
- } else {
- E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
- E1000_WRITE_FLUSH();
- }
-}
-
-/******************************************************************************
- * Puts an ethernet address into a receive address register.
- *
- * hw - Struct containing variables accessed by shared code
- * addr - Address to put into receive address register
- * index - Receive address register to write
- *****************************************************************************/
-void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
-{
- u32 rar_low, rar_high;
-
- /* HW expects these in little endian so we reverse the byte order
- * from network order (big endian) to little endian
- */
- rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
- ((u32)addr[2] << 16) | ((u32)addr[3] << 24));
- rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
-
- /* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
- * unit hang.
- *
- * Description:
- * If there are any Rx frames queued up or otherwise present in the HW
- * before RSS is enabled, and then we enable RSS, the HW Rx unit will
- * hang. To work around this issue, we have to disable receives and
- * flush out all Rx frames before we enable RSS. To do so, we modify we
- * redirect all Rx traffic to manageability and then reset the HW.
- * This flushes away Rx frames, and (since the redirections to
- * manageability persists across resets) keeps new ones from coming in
- * while we work. Then, we clear the Address Valid AV bit for all MAC
- * addresses and undo the re-direction to manageability.
- * Now, frames are coming in again, but the MAC won't accept them, so
- * far so good. We now proceed to initialize RSS (if necessary) and
- * configure the Rx unit. Last, we re-enable the AV bits and continue
- * on our merry way.
- */
- switch (hw->mac_type) {
- case e1000_82571:
- case e1000_82572:
- case e1000_80003es2lan:
- if (hw->leave_av_bit_off)
- break;
- default:
- /* Indicate to hardware the Address is Valid. */
- rar_high |= E1000_RAH_AV;
- break;
- }
-
- E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
- E1000_WRITE_FLUSH();
- E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
- E1000_WRITE_FLUSH();
-}
-
-/******************************************************************************
- * Writes a value to the specified offset in the VLAN filter table.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - Offset in VLAN filer table to write
- * value - Value to write into VLAN filter table
- *****************************************************************************/
-void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
-{
- u32 temp;
-
- if (hw->mac_type == e1000_ich8lan)
- return;
-
- if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
- temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
- E1000_WRITE_FLUSH();
- E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
- E1000_WRITE_FLUSH();
- } else {
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
- E1000_WRITE_FLUSH();
- }
-}
-
-/******************************************************************************
- * Clears the VLAN filer table
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void e1000_clear_vfta(struct e1000_hw *hw)
-{
- u32 offset;
- u32 vfta_value = 0;
- u32 vfta_offset = 0;
- u32 vfta_bit_in_reg = 0;
-
- if (hw->mac_type == e1000_ich8lan)
- return;
-
- if (hw->mac_type == e1000_82573) {
- if (hw->mng_cookie.vlan_id != 0) {
- /* The VFTA is a 4096b bit-field, each identifying a single VLAN
- * ID. The following operations determine which 32b entry
- * (i.e. offset) into the array we want to set the VLAN ID
- * (i.e. bit) of the manageability unit. */
- vfta_offset = (hw->mng_cookie.vlan_id >>
- E1000_VFTA_ENTRY_SHIFT) &
- E1000_VFTA_ENTRY_MASK;
- vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
- E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
- }
- }
- for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
- /* If the offset we want to clear is the same offset of the
- * manageability VLAN ID, then clear all bits except that of the
- * manageability unit */
- vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value);
- E1000_WRITE_FLUSH();
- }
-}
-
-static s32 e1000_id_led_init(struct e1000_hw *hw)
-{
- u32 ledctl;
- const u32 ledctl_mask = 0x000000FF;
- const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
- const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
- u16 eeprom_data, i, temp;
- const u16 led_mask = 0x0F;
-
- DEBUGFUNC("e1000_id_led_init");
-
- if (hw->mac_type < e1000_82540) {
- /* Nothing to do */
- return E1000_SUCCESS;
- }
-
- ledctl = er32(LEDCTL);
- hw->ledctl_default = ledctl;
- hw->ledctl_mode1 = hw->ledctl_default;
- hw->ledctl_mode2 = hw->ledctl_default;
-
- if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
-
- if ((hw->mac_type == e1000_82573) &&
- (eeprom_data == ID_LED_RESERVED_82573))
- eeprom_data = ID_LED_DEFAULT_82573;
- else if ((eeprom_data == ID_LED_RESERVED_0000) ||
- (eeprom_data == ID_LED_RESERVED_FFFF)) {
- if (hw->mac_type == e1000_ich8lan)
- eeprom_data = ID_LED_DEFAULT_ICH8LAN;
- else
- eeprom_data = ID_LED_DEFAULT;
- }
-
- for (i = 0; i < 4; i++) {
- temp = (eeprom_data >> (i << 2)) & led_mask;
- switch (temp) {
- case ID_LED_ON1_DEF2:
- case ID_LED_ON1_ON2:
- case ID_LED_ON1_OFF2:
- hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode1 |= ledctl_on << (i << 3);
- break;
- case ID_LED_OFF1_DEF2:
- case ID_LED_OFF1_ON2:
- case ID_LED_OFF1_OFF2:
- hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode1 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- switch (temp) {
- case ID_LED_DEF1_ON2:
- case ID_LED_ON1_ON2:
- case ID_LED_OFF1_ON2:
- hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode2 |= ledctl_on << (i << 3);
- break;
- case ID_LED_DEF1_OFF2:
- case ID_LED_ON1_OFF2:
- case ID_LED_OFF1_OFF2:
- hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- hw->ledctl_mode2 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Prepares SW controlable LED for use and saves the current state of the LED.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_setup_led(struct e1000_hw *hw)
-{
- u32 ledctl;
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_setup_led");
-
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- case e1000_82544:
- /* No setup necessary */
- break;
- case e1000_82541:
- case e1000_82547:
- case e1000_82541_rev_2:
- case e1000_82547_rev_2:
- /* Turn off PHY Smart Power Down (if enabled) */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
- &hw->phy_spd_default);
- if (ret_val)
- return ret_val;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
- (u16)(hw->phy_spd_default &
- ~IGP01E1000_GMII_SPD));
- if (ret_val)
- return ret_val;
- /* Fall Through */
- default:
- if (hw->media_type == e1000_media_type_fiber) {
- ledctl = er32(LEDCTL);
- /* Save current LEDCTL settings */
- hw->ledctl_default = ledctl;
- /* Turn off LED0 */
- ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
- E1000_LEDCTL_LED0_BLINK |
- E1000_LEDCTL_LED0_MODE_MASK);
- ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
- E1000_LEDCTL_LED0_MODE_SHIFT);
- ew32(LEDCTL, ledctl);
- } else if (hw->media_type == e1000_media_type_copper)
- ew32(LEDCTL, hw->ledctl_mode1);
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-
-/******************************************************************************
- * Used on 82571 and later Si that has LED blink bits.
- * Callers must use their own timer and should have already called
- * e1000_id_led_init()
- * Call e1000_cleanup led() to stop blinking
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_blink_led_start(struct e1000_hw *hw)
-{
- s16 i;
- u32 ledctl_blink = 0;
-
- DEBUGFUNC("e1000_id_led_blink_on");
-
- if (hw->mac_type < e1000_82571) {
- /* Nothing to do */
- return E1000_SUCCESS;
- }
- if (hw->media_type == e1000_media_type_fiber) {
- /* always blink LED0 for PCI-E fiber */
- ledctl_blink = E1000_LEDCTL_LED0_BLINK |
- (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
- } else {
- /* set the blink bit for each LED that's "on" (0x0E) in ledctl_mode2 */
- ledctl_blink = hw->ledctl_mode2;
- for (i=0; i < 4; i++)
- if (((hw->ledctl_mode2 >> (i * 8)) & 0xFF) ==
- E1000_LEDCTL_MODE_LED_ON)
- ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << (i * 8));
- }
-
- ew32(LEDCTL, ledctl_blink);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Restores the saved state of the SW controlable LED.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_cleanup_led(struct e1000_hw *hw)
-{
- s32 ret_val = E1000_SUCCESS;
-
- DEBUGFUNC("e1000_cleanup_led");
-
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- case e1000_82544:
- /* No cleanup necessary */
- break;
- case e1000_82541:
- case e1000_82547:
- case e1000_82541_rev_2:
- case e1000_82547_rev_2:
- /* Turn on PHY Smart Power Down (if previously enabled) */
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
- hw->phy_spd_default);
- if (ret_val)
- return ret_val;
- /* Fall Through */
- default:
- if (hw->phy_type == e1000_phy_ife) {
- e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
- break;
- }
- /* Restore LEDCTL settings */
- ew32(LEDCTL, hw->ledctl_default);
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Turns on the software controllable LED
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_led_on(struct e1000_hw *hw)
-{
- u32 ctrl = er32(CTRL);
-
- DEBUGFUNC("e1000_led_on");
-
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- /* Set SW Defineable Pin 0 to turn on the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- break;
- case e1000_82544:
- if (hw->media_type == e1000_media_type_fiber) {
- /* Set SW Defineable Pin 0 to turn on the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else {
- /* Clear SW Defineable Pin 0 to turn on the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- }
- break;
- default:
- if (hw->media_type == e1000_media_type_fiber) {
- /* Clear SW Defineable Pin 0 to turn on the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else if (hw->phy_type == e1000_phy_ife) {
- e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
- (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));
- } else if (hw->media_type == e1000_media_type_copper) {
- ew32(LEDCTL, hw->ledctl_mode2);
- return E1000_SUCCESS;
- }
- break;
- }
-
- ew32(CTRL, ctrl);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Turns off the software controllable LED
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-s32 e1000_led_off(struct e1000_hw *hw)
-{
- u32 ctrl = er32(CTRL);
-
- DEBUGFUNC("e1000_led_off");
-
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- /* Clear SW Defineable Pin 0 to turn off the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- break;
- case e1000_82544:
- if (hw->media_type == e1000_media_type_fiber) {
- /* Clear SW Defineable Pin 0 to turn off the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else {
- /* Set SW Defineable Pin 0 to turn off the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- }
- break;
- default:
- if (hw->media_type == e1000_media_type_fiber) {
- /* Set SW Defineable Pin 0 to turn off the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- } else if (hw->phy_type == e1000_phy_ife) {
- e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
- (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));
- } else if (hw->media_type == e1000_media_type_copper) {
- ew32(LEDCTL, hw->ledctl_mode1);
- return E1000_SUCCESS;
- }
- break;
- }
-
- ew32(CTRL, ctrl);
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Clears all hardware statistics counters.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static void e1000_clear_hw_cntrs(struct e1000_hw *hw)
-{
- volatile u32 temp;
-
- temp = er32(CRCERRS);
- temp = er32(SYMERRS);
- temp = er32(MPC);
- temp = er32(SCC);
- temp = er32(ECOL);
- temp = er32(MCC);
- temp = er32(LATECOL);
- temp = er32(COLC);
- temp = er32(DC);
- temp = er32(SEC);
- temp = er32(RLEC);
- temp = er32(XONRXC);
- temp = er32(XONTXC);
- temp = er32(XOFFRXC);
- temp = er32(XOFFTXC);
- temp = er32(FCRUC);
-
- if (hw->mac_type != e1000_ich8lan) {
- temp = er32(PRC64);
- temp = er32(PRC127);
- temp = er32(PRC255);
- temp = er32(PRC511);
- temp = er32(PRC1023);
- temp = er32(PRC1522);
- }
-
- temp = er32(GPRC);
- temp = er32(BPRC);
- temp = er32(MPRC);
- temp = er32(GPTC);
- temp = er32(GORCL);
- temp = er32(GORCH);
- temp = er32(GOTCL);
- temp = er32(GOTCH);
- temp = er32(RNBC);
- temp = er32(RUC);
- temp = er32(RFC);
- temp = er32(ROC);
- temp = er32(RJC);
- temp = er32(TORL);
- temp = er32(TORH);
- temp = er32(TOTL);
- temp = er32(TOTH);
- temp = er32(TPR);
- temp = er32(TPT);
-
- if (hw->mac_type != e1000_ich8lan) {
- temp = er32(PTC64);
- temp = er32(PTC127);
- temp = er32(PTC255);
- temp = er32(PTC511);
- temp = er32(PTC1023);
- temp = er32(PTC1522);
- }
-
- temp = er32(MPTC);
- temp = er32(BPTC);
-
- if (hw->mac_type < e1000_82543) return;
-
- temp = er32(ALGNERRC);
- temp = er32(RXERRC);
- temp = er32(TNCRS);
- temp = er32(CEXTERR);
- temp = er32(TSCTC);
- temp = er32(TSCTFC);
-
- if (hw->mac_type <= e1000_82544) return;
-
- temp = er32(MGTPRC);
- temp = er32(MGTPDC);
- temp = er32(MGTPTC);
-
- if (hw->mac_type <= e1000_82547_rev_2) return;
-
- temp = er32(IAC);
- temp = er32(ICRXOC);
-
- if (hw->mac_type == e1000_ich8lan) return;
-
- temp = er32(ICRXPTC);
- temp = er32(ICRXATC);
- temp = er32(ICTXPTC);
- temp = er32(ICTXATC);
- temp = er32(ICTXQEC);
- temp = er32(ICTXQMTC);
- temp = er32(ICRXDMTC);
-}
-
-/******************************************************************************
- * Resets Adaptive IFS to its default state.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * Call this after e1000_init_hw. You may override the IFS defaults by setting
- * hw->ifs_params_forced to true. However, you must initialize hw->
- * current_ifs_val, ifs_min_val, ifs_max_val, ifs_step_size, and ifs_ratio
- * before calling this function.
- *****************************************************************************/
-void e1000_reset_adaptive(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_reset_adaptive");
-
- if (hw->adaptive_ifs) {
- if (!hw->ifs_params_forced) {
- hw->current_ifs_val = 0;
- hw->ifs_min_val = IFS_MIN;
- hw->ifs_max_val = IFS_MAX;
- hw->ifs_step_size = IFS_STEP;
- hw->ifs_ratio = IFS_RATIO;
- }
- hw->in_ifs_mode = false;
- ew32(AIT, 0);
- } else {
- DEBUGOUT("Not in Adaptive IFS mode!\n");
- }
-}
-
-/******************************************************************************
- * Called during the callback/watchdog routine to update IFS value based on
- * the ratio of transmits to collisions.
- *
- * hw - Struct containing variables accessed by shared code
- * tx_packets - Number of transmits since last callback
- * total_collisions - Number of collisions since last callback
- *****************************************************************************/
-void e1000_update_adaptive(struct e1000_hw *hw)
-{
- DEBUGFUNC("e1000_update_adaptive");
-
- if (hw->adaptive_ifs) {
- if ((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
- if (hw->tx_packet_delta > MIN_NUM_XMITS) {
- hw->in_ifs_mode = true;
- if (hw->current_ifs_val < hw->ifs_max_val) {
- if (hw->current_ifs_val == 0)
- hw->current_ifs_val = hw->ifs_min_val;
- else
- hw->current_ifs_val += hw->ifs_step_size;
- ew32(AIT, hw->current_ifs_val);
- }
- }
- } else {
- if (hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
- hw->current_ifs_val = 0;
- hw->in_ifs_mode = false;
- ew32(AIT, 0);
- }
- }
- } else {
- DEBUGOUT("Not in Adaptive IFS mode!\n");
- }
-}
-
-/******************************************************************************
- * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT
- *
- * hw - Struct containing variables accessed by shared code
- * frame_len - The length of the frame in question
- * mac_addr - The Ethernet destination address of the frame in question
- *****************************************************************************/
-void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats,
- u32 frame_len, u8 *mac_addr)
-{
- u64 carry_bit;
-
- /* First adjust the frame length. */
- frame_len--;
- /* We need to adjust the statistics counters, since the hardware
- * counters overcount this packet as a CRC error and undercount
- * the packet as a good packet
- */
- /* This packet should not be counted as a CRC error. */
- stats->crcerrs--;
- /* This packet does count as a Good Packet Received. */
- stats->gprc++;
-
- /* Adjust the Good Octets received counters */
- carry_bit = 0x80000000 & stats->gorcl;
- stats->gorcl += frame_len;
- /* If the high bit of Gorcl (the low 32 bits of the Good Octets
- * Received Count) was one before the addition,
- * AND it is zero after, then we lost the carry out,
- * need to add one to Gorch (Good Octets Received Count High).
- * This could be simplified if all environments supported
- * 64-bit integers.
- */
- if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
- stats->gorch++;
- /* Is this a broadcast or multicast? Check broadcast first,
- * since the test for a multicast frame will test positive on
- * a broadcast frame.
- */
- if ((mac_addr[0] == (u8)0xff) && (mac_addr[1] == (u8)0xff))
- /* Broadcast packet */
- stats->bprc++;
- else if (*mac_addr & 0x01)
- /* Multicast packet */
- stats->mprc++;
-
- if (frame_len == hw->max_frame_size) {
- /* In this case, the hardware has overcounted the number of
- * oversize frames.
- */
- if (stats->roc > 0)
- stats->roc--;
- }
-
- /* Adjust the bin counters when the extra byte put the frame in the
- * wrong bin. Remember that the frame_len was adjusted above.
- */
- if (frame_len == 64) {
- stats->prc64++;
- stats->prc127--;
- } else if (frame_len == 127) {
- stats->prc127++;
- stats->prc255--;
- } else if (frame_len == 255) {
- stats->prc255++;
- stats->prc511--;
- } else if (frame_len == 511) {
- stats->prc511++;
- stats->prc1023--;
- } else if (frame_len == 1023) {
- stats->prc1023++;
- stats->prc1522--;
- } else if (frame_len == 1522) {
- stats->prc1522++;
- }
-}
-
-/******************************************************************************
- * Gets the current PCI bus type, speed, and width of the hardware
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-void e1000_get_bus_info(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 pci_ex_link_status;
- u32 status;
-
- switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- hw->bus_type = e1000_bus_type_pci;
- hw->bus_speed = e1000_bus_speed_unknown;
- hw->bus_width = e1000_bus_width_unknown;
- break;
- case e1000_82571:
- case e1000_82572:
- case e1000_82573:
- case e1000_80003es2lan:
- hw->bus_type = e1000_bus_type_pci_express;
- hw->bus_speed = e1000_bus_speed_2500;
- ret_val = e1000_read_pcie_cap_reg(hw,
- PCI_EX_LINK_STATUS,
- &pci_ex_link_status);
- if (ret_val)
- hw->bus_width = e1000_bus_width_unknown;
- else
- hw->bus_width = (pci_ex_link_status & PCI_EX_LINK_WIDTH_MASK) >>
- PCI_EX_LINK_WIDTH_SHIFT;
- break;
- case e1000_ich8lan:
- hw->bus_type = e1000_bus_type_pci_express;
- hw->bus_speed = e1000_bus_speed_2500;
- hw->bus_width = e1000_bus_width_pciex_1;
- break;
- default:
- status = er32(STATUS);
- hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
- e1000_bus_type_pcix : e1000_bus_type_pci;
-
- if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
- hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
- e1000_bus_speed_66 : e1000_bus_speed_120;
- } else if (hw->bus_type == e1000_bus_type_pci) {
- hw->bus_speed = (status & E1000_STATUS_PCI66) ?
- e1000_bus_speed_66 : e1000_bus_speed_33;
- } else {
- switch (status & E1000_STATUS_PCIX_SPEED) {
- case E1000_STATUS_PCIX_SPEED_66:
- hw->bus_speed = e1000_bus_speed_66;
- break;
- case E1000_STATUS_PCIX_SPEED_100:
- hw->bus_speed = e1000_bus_speed_100;
- break;
- case E1000_STATUS_PCIX_SPEED_133:
- hw->bus_speed = e1000_bus_speed_133;
- break;
- default:
- hw->bus_speed = e1000_bus_speed_reserved;
- break;
- }
- }
- hw->bus_width = (status & E1000_STATUS_BUS64) ?
- e1000_bus_width_64 : e1000_bus_width_32;
- break;
- }
-}
-
-/******************************************************************************
- * Writes a value to one of the devices registers using port I/O (as opposed to
- * memory mapped I/O). Only 82544 and newer devices support port I/O.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset to write to
- * value - value to write
- *****************************************************************************/
-static void e1000_write_reg_io(struct e1000_hw *hw, u32 offset, u32 value)
-{
- unsigned long io_addr = hw->io_base;
- unsigned long io_data = hw->io_base + 4;
-
- e1000_io_write(hw, io_addr, offset);
- e1000_io_write(hw, io_data, value);
-}
-
-/******************************************************************************
- * Estimates the cable length.
- *
- * hw - Struct containing variables accessed by shared code
- * min_length - The estimated minimum length
- * max_length - The estimated maximum length
- *
- * returns: - E1000_ERR_XXX
- * E1000_SUCCESS
- *
- * This function always returns a ranged length (minimum & maximum).
- * So for M88 phy's, this function interprets the one value returned from the
- * register to the minimum and maximum range.
- * For IGP phy's, the function calculates the range by the AGC registers.
- *****************************************************************************/
-static s32 e1000_get_cable_length(struct e1000_hw *hw, u16 *min_length,
- u16 *max_length)
-{
- s32 ret_val;
- u16 agc_value = 0;
- u16 i, phy_data;
- u16 cable_length;
-
- DEBUGFUNC("e1000_get_cable_length");
-
- *min_length = *max_length = 0;
-
- /* Use old method for Phy older than IGP */
- if (hw->phy_type == e1000_phy_m88) {
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
- if (ret_val)
- return ret_val;
- cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT;
-
- /* Convert the enum value to ranged values */
- switch (cable_length) {
- case e1000_cable_length_50:
- *min_length = 0;
- *max_length = e1000_igp_cable_length_50;
- break;
- case e1000_cable_length_50_80:
- *min_length = e1000_igp_cable_length_50;
- *max_length = e1000_igp_cable_length_80;
- break;
- case e1000_cable_length_80_110:
- *min_length = e1000_igp_cable_length_80;
- *max_length = e1000_igp_cable_length_110;
- break;
- case e1000_cable_length_110_140:
- *min_length = e1000_igp_cable_length_110;
- *max_length = e1000_igp_cable_length_140;
- break;
- case e1000_cable_length_140:
- *min_length = e1000_igp_cable_length_140;
- *max_length = e1000_igp_cable_length_170;
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
- } else if (hw->phy_type == e1000_phy_gg82563) {
- ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
- &phy_data);
- if (ret_val)
- return ret_val;
- cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;
-
- switch (cable_length) {
- case e1000_gg_cable_length_60:
- *min_length = 0;
- *max_length = e1000_igp_cable_length_60;
- break;
- case e1000_gg_cable_length_60_115:
- *min_length = e1000_igp_cable_length_60;
- *max_length = e1000_igp_cable_length_115;
- break;
- case e1000_gg_cable_length_115_150:
- *min_length = e1000_igp_cable_length_115;
- *max_length = e1000_igp_cable_length_150;
- break;
- case e1000_gg_cable_length_150:
- *min_length = e1000_igp_cable_length_150;
- *max_length = e1000_igp_cable_length_180;
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
- } else if (hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
- u16 cur_agc_value;
- u16 min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
- u16 agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- {IGP01E1000_PHY_AGC_A,
- IGP01E1000_PHY_AGC_B,
- IGP01E1000_PHY_AGC_C,
- IGP01E1000_PHY_AGC_D};
- /* Read the AGC registers for all channels */
- for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-
- ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
- if (ret_val)
- return ret_val;
-
- cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
-
- /* Value bound check. */
- if ((cur_agc_value >= IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
- (cur_agc_value == 0))
- return -E1000_ERR_PHY;
-
- agc_value += cur_agc_value;
-
- /* Update minimal AGC value. */
- if (min_agc_value > cur_agc_value)
- min_agc_value = cur_agc_value;
- }
-
- /* Remove the minimal AGC result for length < 50m */
- if (agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
- agc_value -= min_agc_value;
-
- /* Get the average length of the remaining 3 channels */
- agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
- } else {
- /* Get the average length of all the 4 channels. */
- agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
- }
-
- /* Set the range of the calculated length. */
- *min_length = ((e1000_igp_cable_length_table[agc_value] -
- IGP01E1000_AGC_RANGE) > 0) ?
- (e1000_igp_cable_length_table[agc_value] -
- IGP01E1000_AGC_RANGE) : 0;
- *max_length = e1000_igp_cable_length_table[agc_value] +
- IGP01E1000_AGC_RANGE;
- } else if (hw->phy_type == e1000_phy_igp_2 ||
- hw->phy_type == e1000_phy_igp_3) {
- u16 cur_agc_index, max_agc_index = 0;
- u16 min_agc_index = IGP02E1000_AGC_LENGTH_TABLE_SIZE - 1;
- u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
- {IGP02E1000_PHY_AGC_A,
- IGP02E1000_PHY_AGC_B,
- IGP02E1000_PHY_AGC_C,
- IGP02E1000_PHY_AGC_D};
- /* Read the AGC registers for all channels */
- for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Getting bits 15:9, which represent the combination of course and
- * fine gain values. The result is a number that can be put into
- * the lookup table to obtain the approximate cable length. */
- cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
- IGP02E1000_AGC_LENGTH_MASK;
-
- /* Array index bound check. */
- if ((cur_agc_index >= IGP02E1000_AGC_LENGTH_TABLE_SIZE) ||
- (cur_agc_index == 0))
- return -E1000_ERR_PHY;
-
- /* Remove min & max AGC values from calculation. */
- if (e1000_igp_2_cable_length_table[min_agc_index] >
- e1000_igp_2_cable_length_table[cur_agc_index])
- min_agc_index = cur_agc_index;
- if (e1000_igp_2_cable_length_table[max_agc_index] <
- e1000_igp_2_cable_length_table[cur_agc_index])
- max_agc_index = cur_agc_index;
-
- agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
- }
-
- agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
- e1000_igp_2_cable_length_table[max_agc_index]);
- agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
-
- /* Calculate cable length with the error range of +/- 10 meters. */
- *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
- (agc_value - IGP02E1000_AGC_RANGE) : 0;
- *max_length = agc_value + IGP02E1000_AGC_RANGE;
- }
-
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Check the cable polarity
- *
- * hw - Struct containing variables accessed by shared code
- * polarity - output parameter : 0 - Polarity is not reversed
- * 1 - Polarity is reversed.
- *
- * returns: - E1000_ERR_XXX
- * E1000_SUCCESS
- *
- * For phy's older then IGP, this function simply reads the polarity bit in the
- * Phy Status register. For IGP phy's, this bit is valid only if link speed is
- * 10 Mbps. If the link speed is 100 Mbps there is no polarity so this bit will
- * return 0. If the link speed is 1000 Mbps the polarity status is in the
- * IGP01E1000_PHY_PCS_INIT_REG.
- *****************************************************************************/
-static s32 e1000_check_polarity(struct e1000_hw *hw,
- e1000_rev_polarity *polarity)
-{
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_check_polarity");
-
- if ((hw->phy_type == e1000_phy_m88) ||
- (hw->phy_type == e1000_phy_gg82563)) {
- /* return the Polarity bit in the Status register. */
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
- if (ret_val)
- return ret_val;
- *polarity = ((phy_data & M88E1000_PSSR_REV_POLARITY) >>
- M88E1000_PSSR_REV_POLARITY_SHIFT) ?
- e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
-
- } else if (hw->phy_type == e1000_phy_igp ||
- hw->phy_type == e1000_phy_igp_3 ||
- hw->phy_type == e1000_phy_igp_2) {
- /* Read the Status register to check the speed */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
- * find the polarity status */
- if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
-
- /* Read the GIG initialization PCS register (0x00B4) */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- /* Check the polarity bits */
- *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ?
- e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
- } else {
- /* For 10 Mbps, read the polarity bit in the status register. (for
- * 100 Mbps this bit is always 0) */
- *polarity = (phy_data & IGP01E1000_PSSR_POLARITY_REVERSED) ?
- e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
- }
- } else if (hw->phy_type == e1000_phy_ife) {
- ret_val = e1000_read_phy_reg(hw, IFE_PHY_EXTENDED_STATUS_CONTROL,
- &phy_data);
- if (ret_val)
- return ret_val;
- *polarity = ((phy_data & IFE_PESC_POLARITY_REVERSED) >>
- IFE_PESC_POLARITY_REVERSED_SHIFT) ?
- e1000_rev_polarity_reversed : e1000_rev_polarity_normal;
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Check if Downshift occured
- *
- * hw - Struct containing variables accessed by shared code
- * downshift - output parameter : 0 - No Downshift ocured.
- * 1 - Downshift ocured.
- *
- * returns: - E1000_ERR_XXX
- * E1000_SUCCESS
- *
- * For phy's older then IGP, this function reads the Downshift bit in the Phy
- * Specific Status register. For IGP phy's, it reads the Downgrade bit in the
- * Link Health register. In IGP this bit is latched high, so the driver must
- * read it immediately after link is established.
- *****************************************************************************/
-static s32 e1000_check_downshift(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_data;
-
- DEBUGFUNC("e1000_check_downshift");
-
- if (hw->phy_type == e1000_phy_igp ||
- hw->phy_type == e1000_phy_igp_3 ||
- hw->phy_type == e1000_phy_igp_2) {
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
- } else if ((hw->phy_type == e1000_phy_m88) ||
- (hw->phy_type == e1000_phy_gg82563)) {
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
- M88E1000_PSSR_DOWNSHIFT_SHIFT;
- } else if (hw->phy_type == e1000_phy_ife) {
- /* e1000_phy_ife supports 10/100 speed only */
- hw->speed_downgraded = false;
- }
-
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- *
- * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
- * gigabit link is achieved to improve link quality.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_PHY if fail to read/write the PHY
- * E1000_SUCCESS at any other case.
- *
- ****************************************************************************/
-
-static s32 e1000_config_dsp_after_link_change(struct e1000_hw *hw, bool link_up)
-{
- s32 ret_val;
- u16 phy_data, phy_saved_data, speed, duplex, i;
- u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- {IGP01E1000_PHY_AGC_PARAM_A,
- IGP01E1000_PHY_AGC_PARAM_B,
- IGP01E1000_PHY_AGC_PARAM_C,
- IGP01E1000_PHY_AGC_PARAM_D};
- u16 min_length, max_length;
-
- DEBUGFUNC("e1000_config_dsp_after_link_change");
-
- if (hw->phy_type != e1000_phy_igp)
- return E1000_SUCCESS;
-
- if (link_up) {
- ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
- if (ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
-
- if (speed == SPEED_1000) {
-
- ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
- if (ret_val)
- return ret_val;
-
- if ((hw->dsp_config_state == e1000_dsp_config_enabled) &&
- min_length >= e1000_igp_cable_length_50) {
-
- for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
-
- ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
- phy_data);
- if (ret_val)
- return ret_val;
- }
- hw->dsp_config_state = e1000_dsp_config_activated;
- }
-
- if ((hw->ffe_config_state == e1000_ffe_config_enabled) &&
- (min_length < e1000_igp_cable_length_50)) {
-
- u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
- u32 idle_errs = 0;
-
- /* clear previous idle error counts */
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- for (i = 0; i < ffe_idle_err_timeout; i++) {
- udelay(1000);
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
- if (idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
- hw->ffe_config_state = e1000_ffe_config_active;
-
- ret_val = e1000_write_phy_reg(hw,
- IGP01E1000_PHY_DSP_FFE,
- IGP01E1000_PHY_DSP_FFE_CM_CP);
- if (ret_val)
- return ret_val;
- break;
- }
-
- if (idle_errs)
- ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100;
- }
- }
- }
- } else {
- if (hw->dsp_config_state == e1000_dsp_config_activated) {
- /* Save off the current value of register 0x2F5B to be restored at
- * the end of the routines. */
- ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-
- if (ret_val)
- return ret_val;
-
- /* Disable the PHY transmitter */
- ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
-
- if (ret_val)
- return ret_val;
-
- mdelay(20);
-
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_FORCE_GIGA);
- if (ret_val)
- return ret_val;
- for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i], &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
- phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
-
- ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i], phy_data);
- if (ret_val)
- return ret_val;
- }
-
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_RESTART_AUTONEG);
- if (ret_val)
- return ret_val;
-
- mdelay(20);
-
- /* Now enable the transmitter */
- ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-
- if (ret_val)
- return ret_val;
-
- hw->dsp_config_state = e1000_dsp_config_enabled;
- }
-
- if (hw->ffe_config_state == e1000_ffe_config_active) {
- /* Save off the current value of register 0x2F5B to be restored at
- * the end of the routines. */
- ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-
- if (ret_val)
- return ret_val;
-
- /* Disable the PHY transmitter */
- ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
-
- if (ret_val)
- return ret_val;
-
- mdelay(20);
-
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_FORCE_GIGA);
- if (ret_val)
- return ret_val;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
- IGP01E1000_PHY_DSP_FFE_DEFAULT);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_RESTART_AUTONEG);
- if (ret_val)
- return ret_val;
-
- mdelay(20);
-
- /* Now enable the transmitter */
- ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-
- if (ret_val)
- return ret_val;
-
- hw->ffe_config_state = e1000_ffe_config_enabled;
- }
- }
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- * Set PHY to class A mode
- * Assumes the following operations will follow to enable the new class mode.
- * 1. Do a PHY soft reset
- * 2. Restart auto-negotiation or force link.
- *
- * hw - Struct containing variables accessed by shared code
- ****************************************************************************/
-static s32 e1000_set_phy_mode(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 eeprom_data;
-
- DEBUGFUNC("e1000_set_phy_mode");
-
- if ((hw->mac_type == e1000_82545_rev_3) &&
- (hw->media_type == e1000_media_type_copper)) {
- ret_val = e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1, &eeprom_data);
- if (ret_val) {
- return ret_val;
- }
-
- if ((eeprom_data != EEPROM_RESERVED_WORD) &&
- (eeprom_data & EEPROM_PHY_CLASS_A)) {
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x000B);
- if (ret_val)
- return ret_val;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x8104);
- if (ret_val)
- return ret_val;
-
- hw->phy_reset_disable = false;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- *
- * This function sets the lplu state according to the active flag. When
- * activating lplu this function also disables smart speed and vise versa.
- * lplu will not be activated unless the device autonegotiation advertisment
- * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
- * hw: Struct containing variables accessed by shared code
- * active - true to enable lplu false to disable lplu.
- *
- * returns: - E1000_ERR_PHY if fail to read/write the PHY
- * E1000_SUCCESS at any other case.
- *
- ****************************************************************************/
-
-static s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
-{
- u32 phy_ctrl = 0;
- s32 ret_val;
- u16 phy_data;
- DEBUGFUNC("e1000_set_d3_lplu_state");
-
- if (hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2
- && hw->phy_type != e1000_phy_igp_3)
- return E1000_SUCCESS;
-
- /* During driver activity LPLU should not be used or it will attain link
- * from the lowest speeds starting from 10Mbps. The capability is used for
- * Dx transitions and states */
- if (hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) {
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
- if (ret_val)
- return ret_val;
- } else if (hw->mac_type == e1000_ich8lan) {
- /* MAC writes into PHY register based on the state transition
- * and start auto-negotiation. SW driver can overwrite the settings
- * in CSR PHY power control E1000_PHY_CTRL register. */
- phy_ctrl = er32(PHY_CTRL);
- } else {
- ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
- if (ret_val)
- return ret_val;
- }
-
- if (!active) {
- if (hw->mac_type == e1000_82541_rev_2 ||
- hw->mac_type == e1000_82547_rev_2) {
- phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
- if (ret_val)
- return ret_val;
- } else {
- if (hw->mac_type == e1000_ich8lan) {
- phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
- } else {
- phy_data &= ~IGP02E1000_PM_D3_LPLU;
- ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- phy_data);
- if (ret_val)
- return ret_val;
- }
- }
-
- /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
- * Dx states where the power conservation is most important. During
- * driver activity we should enable SmartSpeed, so performance is
- * maintained. */
- if (hw->smart_speed == e1000_smart_speed_on) {
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if (ret_val)
- return ret_val;
- } else if (hw->smart_speed == e1000_smart_speed_off) {
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if (ret_val)
- return ret_val;
- }
-
- } else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
- (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
- (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
-
- if (hw->mac_type == e1000_82541_rev_2 ||
- hw->mac_type == e1000_82547_rev_2) {
- phy_data |= IGP01E1000_GMII_FLEX_SPD;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
- if (ret_val)
- return ret_val;
- } else {
- if (hw->mac_type == e1000_ich8lan) {
- phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
- } else {
- phy_data |= IGP02E1000_PM_D3_LPLU;
- ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- phy_data);
- if (ret_val)
- return ret_val;
- }
- }
-
- /* When LPLU is enabled we should disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
- if (ret_val)
- return ret_val;
-
- }
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- *
- * This function sets the lplu d0 state according to the active flag. When
- * activating lplu this function also disables smart speed and vise versa.
- * lplu will not be activated unless the device autonegotiation advertisment
- * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
- * hw: Struct containing variables accessed by shared code
- * active - true to enable lplu false to disable lplu.
- *
- * returns: - E1000_ERR_PHY if fail to read/write the PHY
- * E1000_SUCCESS at any other case.
- *
- ****************************************************************************/
-
-static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
-{
- u32 phy_ctrl = 0;
- s32 ret_val;
- u16 phy_data;
- DEBUGFUNC("e1000_set_d0_lplu_state");
-
- if (hw->mac_type <= e1000_82547_rev_2)
- return E1000_SUCCESS;
-
- if (hw->mac_type == e1000_ich8lan) {
- phy_ctrl = er32(PHY_CTRL);
- } else {
- ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
- if (ret_val)
- return ret_val;
- }
-
- if (!active) {
- if (hw->mac_type == e1000_ich8lan) {
- phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
- } else {
- phy_data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
- if (ret_val)
- return ret_val;
- }
-
- /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
- * Dx states where the power conservation is most important. During
- * driver activity we should enable SmartSpeed, so performance is
- * maintained. */
- if (hw->smart_speed == e1000_smart_speed_on) {
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if (ret_val)
- return ret_val;
- } else if (hw->smart_speed == e1000_smart_speed_off) {
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
- if (ret_val)
- return ret_val;
- }
-
-
- } else {
-
- if (hw->mac_type == e1000_ich8lan) {
- phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
- } else {
- phy_data |= IGP02E1000_PM_D0_LPLU;
- ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
- if (ret_val)
- return ret_val;
- }
-
- /* When LPLU is enabled we should disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
- if (ret_val)
- return ret_val;
-
- }
- return E1000_SUCCESS;
-}
-
-/******************************************************************************
- * Change VCO speed register to improve Bit Error Rate performance of SERDES.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
-static s32 e1000_set_vco_speed(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 default_page = 0;
- u16 phy_data;
-
- DEBUGFUNC("e1000_set_vco_speed");
-
- switch (hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
- default:
- return E1000_SUCCESS;
- }
-
- /* Set PHY register 30, page 5, bit 8 to 0 */
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- /* Set PHY register 30, page 4, bit 11 to 1 */
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PHY_VCO_REG_BIT11;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
- if (ret_val)
- return ret_val;
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function reads the cookie from ARC ram.
- *
- * returns: - E1000_SUCCESS .
- ****************************************************************************/
-static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer)
-{
- u8 i;
- u32 offset = E1000_MNG_DHCP_COOKIE_OFFSET;
- u8 length = E1000_MNG_DHCP_COOKIE_LENGTH;
-
- length = (length >> 2);
- offset = (offset >> 2);
-
- for (i = 0; i < length; i++) {
- *((u32 *)buffer + i) =
- E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
- }
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function checks whether the HOST IF is enabled for command operaton
- * and also checks whether the previous command is completed.
- * It busy waits in case of previous command is not completed.
- *
- * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or
- * timeout
- * - E1000_SUCCESS for success.
- ****************************************************************************/
-static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
-{
- u32 hicr;
- u8 i;
-
- /* Check that the host interface is enabled. */
- hicr = er32(HICR);
- if ((hicr & E1000_HICR_EN) == 0) {
- DEBUGOUT("E1000_HOST_EN bit disabled.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
- /* check the previous command is completed */
- for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
- hicr = er32(HICR);
- if (!(hicr & E1000_HICR_C))
- break;
- mdelay(1);
- }
-
- if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
- DEBUGOUT("Previous command timeout failed .\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
- return E1000_SUCCESS;
-}
-
-/*****************************************************************************
- * This function writes the buffer content at the offset given on the host if.
- * It also does alignment considerations to do the writes in most efficient way.
- * Also fills up the sum of the buffer in *buffer parameter.
- *
- * returns - E1000_SUCCESS for success.
- ****************************************************************************/
-static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
- u16 offset, u8 *sum)
-{
- u8 *tmp;
- u8 *bufptr = buffer;
- u32 data = 0;
- u16 remaining, i, j, prev_bytes;
-
- /* sum = only sum of the data and it is not checksum */
-
- if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
- return -E1000_ERR_PARAM;
- }
-
- tmp = (u8 *)&data;
- prev_bytes = offset & 0x3;
- offset &= 0xFFFC;
- offset >>= 2;
-
- if (prev_bytes) {
- data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset);
- for (j = prev_bytes; j < sizeof(u32); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data);
- length -= j - prev_bytes;
- offset++;
- }
-
- remaining = length & 0x3;
- length -= remaining;
-
- /* Calculate length in DWORDs */
- length >>= 2;
-
- /* The device driver writes the relevant command block into the
- * ram area. */
- for (i = 0; i < length; i++) {
- for (j = 0; j < sizeof(u32); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
-
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
- }
- if (remaining) {
- for (j = 0; j < sizeof(u32); j++) {
- if (j < remaining)
- *(tmp + j) = *bufptr++;
- else
- *(tmp + j) = 0;
-
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
- }
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function writes the command header after does the checksum calculation.
- *
- * returns - E1000_SUCCESS for success.
- ****************************************************************************/
-static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
- struct e1000_host_mng_command_header *hdr)
-{
- u16 i;
- u8 sum;
- u8 *buffer;
-
- /* Write the whole command header structure which includes sum of
- * the buffer */
-
- u16 length = sizeof(struct e1000_host_mng_command_header);
-
- sum = hdr->checksum;
- hdr->checksum = 0;
-
- buffer = (u8 *)hdr;
- i = length;
- while (i--)
- sum += buffer[i];
-
- hdr->checksum = 0 - sum;
-
- length >>= 2;
- /* The device driver writes the relevant command block into the ram area. */
- for (i = 0; i < length; i++) {
- E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((u32 *)hdr + i));
- E1000_WRITE_FLUSH();
- }
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function indicates to ARC that a new command is pending which completes
- * one write operation by the driver.
- *
- * returns - E1000_SUCCESS for success.
- ****************************************************************************/
-static s32 e1000_mng_write_commit(struct e1000_hw *hw)
-{
- u32 hicr;
-
- hicr = er32(HICR);
- /* Setting this bit tells the ARC that a new command is pending. */
- ew32(HICR, hicr | E1000_HICR_C);
-
- return E1000_SUCCESS;
-}
-
-
-/*****************************************************************************
- * This function checks the mode of the firmware.
- *
- * returns - true when the mode is IAMT or false.
- ****************************************************************************/
-bool e1000_check_mng_mode(struct e1000_hw *hw)
-{
- u32 fwsm;
-
- fwsm = er32(FWSM);
-
- if (hw->mac_type == e1000_ich8lan) {
- if ((fwsm & E1000_FWSM_MODE_MASK) ==
- (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
- return true;
- } else if ((fwsm & E1000_FWSM_MODE_MASK) ==
- (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
- return true;
-
- return false;
-}
-
-
-/*****************************************************************************
- * This function writes the dhcp info .
- ****************************************************************************/
-s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
-{
- s32 ret_val;
- struct e1000_host_mng_command_header hdr;
-
- hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
- hdr.command_length = length;
- hdr.reserved1 = 0;
- hdr.reserved2 = 0;
- hdr.checksum = 0;
-
- ret_val = e1000_mng_enable_host_if(hw);
- if (ret_val == E1000_SUCCESS) {
- ret_val = e1000_mng_host_if_write(hw, buffer, length, sizeof(hdr),
- &(hdr.checksum));
- if (ret_val == E1000_SUCCESS) {
- ret_val = e1000_mng_write_cmd_header(hw, &hdr);
- if (ret_val == E1000_SUCCESS)
- ret_val = e1000_mng_write_commit(hw);
- }
- }
- return ret_val;
-}
-
-
-/*****************************************************************************
- * This function calculates the checksum.
- *
- * returns - checksum of buffer contents.
- ****************************************************************************/
-static u8 e1000_calculate_mng_checksum(char *buffer, u32 length)
-{
- u8 sum = 0;
- u32 i;
-
- if (!buffer)
- return 0;
-
- for (i=0; i < length; i++)
- sum += buffer[i];
-
- return (u8)(0 - sum);
-}
-
-/*****************************************************************************
- * This function checks whether tx pkt filtering needs to be enabled or not.
- *
- * returns - true for packet filtering or false.
- ****************************************************************************/
-bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
-{
- /* called in init as well as watchdog timer functions */
-
- s32 ret_val, checksum;
- bool tx_filter = false;
- struct e1000_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie);
- u8 *buffer = (u8 *) &(hw->mng_cookie);
-
- if (e1000_check_mng_mode(hw)) {
- ret_val = e1000_mng_enable_host_if(hw);
- if (ret_val == E1000_SUCCESS) {
- ret_val = e1000_host_if_read_cookie(hw, buffer);
- if (ret_val == E1000_SUCCESS) {
- checksum = hdr->checksum;
- hdr->checksum = 0;
- if ((hdr->signature == E1000_IAMT_SIGNATURE) &&
- checksum == e1000_calculate_mng_checksum((char *)buffer,
- E1000_MNG_DHCP_COOKIE_LENGTH)) {
- if (hdr->status &
- E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT)
- tx_filter = true;
- } else
- tx_filter = true;
- } else
- tx_filter = true;
- }
- }
-
- hw->tx_pkt_filtering = tx_filter;
- return tx_filter;
-}
-
-/******************************************************************************
- * Verifies the hardware needs to allow ARPs to be processed by the host
- *
- * hw - Struct containing variables accessed by shared code
- *
- * returns: - true/false
- *
- *****************************************************************************/
-u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw)
-{
- u32 manc;
- u32 fwsm, factps;
-
- if (hw->asf_firmware_present) {
- manc = er32(MANC);
-
- if (!(manc & E1000_MANC_RCV_TCO_EN) ||
- !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
- return false;
- if (e1000_arc_subsystem_valid(hw)) {
- fwsm = er32(FWSM);
- factps = er32(FACTPS);
-
- if ((((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT) ==
- e1000_mng_mode_pt) && !(factps & E1000_FACTPS_MNGCG))
- return true;
- } else
- if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
- return true;
- }
- return false;
-}
-
-static s32 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 mii_status_reg;
- u16 i;
-
- /* Polarity reversal workaround for forced 10F/10H links. */
-
- /* Disable the transmitter on the PHY */
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
- if (ret_val)
- return ret_val;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
- if (ret_val)
- return ret_val;
-
- /* This loop will early-out if the NO link condition has been met. */
- for (i = PHY_FORCE_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Link Status bit
- * to be clear.
- */
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break;
- mdelay(100);
- }
-
- /* Recommended delay time after link has been lost */
- mdelay(1000);
-
- /* Now we will re-enable th transmitter on the PHY */
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
- if (ret_val)
- return ret_val;
- mdelay(50);
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
- if (ret_val)
- return ret_val;
- mdelay(50);
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
- if (ret_val)
- return ret_val;
- mdelay(50);
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
- if (ret_val)
- return ret_val;
-
- /* This loop will early-out if the link condition has been met. */
- for (i = PHY_FORCE_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Link Status bit
- * to be set.
- */
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- if (mii_status_reg & MII_SR_LINK_STATUS) break;
- mdelay(100);
- }
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- *
- * Disables PCI-Express master access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - none.
- *
- ***************************************************************************/
-static void e1000_set_pci_express_master_disable(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- DEBUGFUNC("e1000_set_pci_express_master_disable");
-
- if (hw->bus_type != e1000_bus_type_pci_express)
- return;
-
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
- ew32(CTRL, ctrl);
-}
-
-/*******************************************************************************
- *
- * Disables PCI-Express master access and verifies there are no pending requests
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't
- * caused the master requests to be disabled.
- * E1000_SUCCESS master requests disabled.
- *
- ******************************************************************************/
-s32 e1000_disable_pciex_master(struct e1000_hw *hw)
-{
- s32 timeout = MASTER_DISABLE_TIMEOUT; /* 80ms */
-
- DEBUGFUNC("e1000_disable_pciex_master");
-
- if (hw->bus_type != e1000_bus_type_pci_express)
- return E1000_SUCCESS;
-
- e1000_set_pci_express_master_disable(hw);
-
- while (timeout) {
- if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
- break;
- else
- udelay(100);
- timeout--;
- }
-
- if (!timeout) {
- DEBUGOUT("Master requests are pending.\n");
- return -E1000_ERR_MASTER_REQUESTS_PENDING;
- }
-
- return E1000_SUCCESS;
-}
-
-/*******************************************************************************
- *
- * Check for EEPROM Auto Read bit done.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_RESET if fail to reset MAC
- * E1000_SUCCESS at any other case.
- *
- ******************************************************************************/
-static s32 e1000_get_auto_rd_done(struct e1000_hw *hw)
-{
- s32 timeout = AUTO_READ_DONE_TIMEOUT;
-
- DEBUGFUNC("e1000_get_auto_rd_done");
-
- switch (hw->mac_type) {
- default:
- msleep(5);
- break;
- case e1000_82571:
- case e1000_82572:
- case e1000_82573:
- case e1000_80003es2lan:
- case e1000_ich8lan:
- while (timeout) {
- if (er32(EECD) & E1000_EECD_AUTO_RD)
- break;
- else msleep(1);
- timeout--;
- }
-
- if (!timeout) {
- DEBUGOUT("Auto read by HW from EEPROM has not completed.\n");
- return -E1000_ERR_RESET;
- }
- break;
- }
-
- /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
- * Need to wait for PHY configuration completion before accessing NVM
- * and PHY. */
- if (hw->mac_type == e1000_82573)
- msleep(25);
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- * Checks if the PHY configuration is done
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_RESET if fail to reset MAC
- * E1000_SUCCESS at any other case.
- *
- ***************************************************************************/
-static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
-{
- s32 timeout = PHY_CFG_TIMEOUT;
- u32 cfg_mask = E1000_EEPROM_CFG_DONE;
-
- DEBUGFUNC("e1000_get_phy_cfg_done");
-
- switch (hw->mac_type) {
- default:
- mdelay(10);
- break;
- case e1000_80003es2lan:
- /* Separate *_CFG_DONE_* bit for each port */
- if (er32(STATUS) & E1000_STATUS_FUNC_1)
- cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1;
- /* Fall Through */
- case e1000_82571:
- case e1000_82572:
- while (timeout) {
- if (er32(EEMNGCTL) & cfg_mask)
- break;
- else
- msleep(1);
- timeout--;
- }
- if (!timeout) {
- DEBUGOUT("MNG configuration cycle has not completed.\n");
- return -E1000_ERR_RESET;
- }
- break;
- }
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- *
- * Using the combination of SMBI and SWESMBI semaphore bits when resetting
- * adapter or Eeprom access.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_EEPROM if fail to access EEPROM.
- * E1000_SUCCESS at any other case.
- *
- ***************************************************************************/
-static s32 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
-{
- s32 timeout;
- u32 swsm;
-
- DEBUGFUNC("e1000_get_hw_eeprom_semaphore");
-
- if (!hw->eeprom_semaphore_present)
- return E1000_SUCCESS;
-
- if (hw->mac_type == e1000_80003es2lan) {
- /* Get the SW semaphore. */
- if (e1000_get_software_semaphore(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
- }
-
- /* Get the FW semaphore. */
- timeout = hw->eeprom.word_size + 1;
- while (timeout) {
- swsm = er32(SWSM);
- swsm |= E1000_SWSM_SWESMBI;
- ew32(SWSM, swsm);
- /* if we managed to set the bit we got the semaphore. */
- swsm = er32(SWSM);
- if (swsm & E1000_SWSM_SWESMBI)
- break;
-
- udelay(50);
- timeout--;
- }
-
- if (!timeout) {
- /* Release semaphores */
- e1000_put_hw_eeprom_semaphore(hw);
- DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n");
- return -E1000_ERR_EEPROM;
- }
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- * This function clears HW semaphore bits.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - None.
- *
- ***************************************************************************/
-static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
-{
- u32 swsm;
-
- DEBUGFUNC("e1000_put_hw_eeprom_semaphore");
-
- if (!hw->eeprom_semaphore_present)
- return;
-
- swsm = er32(SWSM);
- if (hw->mac_type == e1000_80003es2lan) {
- /* Release both semaphores. */
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
- } else
- swsm &= ~(E1000_SWSM_SWESMBI);
- ew32(SWSM, swsm);
-}
-
-/***************************************************************************
- *
- * Obtaining software semaphore bit (SMBI) before resetting PHY.
- *
- * hw: Struct containing variables accessed by shared code
- *
- * returns: - E1000_ERR_RESET if fail to obtain semaphore.
- * E1000_SUCCESS at any other case.
- *
- ***************************************************************************/
-static s32 e1000_get_software_semaphore(struct e1000_hw *hw)
-{
- s32 timeout = hw->eeprom.word_size + 1;
- u32 swsm;
-
- DEBUGFUNC("e1000_get_software_semaphore");
-
- if (hw->mac_type != e1000_80003es2lan) {
- return E1000_SUCCESS;
- }
-
- while (timeout) {
- swsm = er32(SWSM);
- /* If SMBI bit cleared, it is now set and we hold the semaphore */
- if (!(swsm & E1000_SWSM_SMBI))
- break;
- mdelay(1);
- timeout--;
- }
-
- if (!timeout) {
- DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
- return -E1000_ERR_RESET;
- }
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- *
- * Release semaphore bit (SMBI).
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-static void e1000_release_software_semaphore(struct e1000_hw *hw)
-{
- u32 swsm;
-
- DEBUGFUNC("e1000_release_software_semaphore");
-
- if (hw->mac_type != e1000_80003es2lan) {
- return;
- }
-
- swsm = er32(SWSM);
- /* Release the SW semaphores.*/
- swsm &= ~E1000_SWSM_SMBI;
- ew32(SWSM, swsm);
-}
-
-/******************************************************************************
- * Checks if PHY reset is blocked due to SOL/IDER session, for example.
- * Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to
- * the caller to figure out how to deal with it.
- *
- * hw - Struct containing variables accessed by shared code
- *
- * returns: - E1000_BLK_PHY_RESET
- * E1000_SUCCESS
- *
- *****************************************************************************/
-s32 e1000_check_phy_reset_block(struct e1000_hw *hw)
-{
- u32 manc = 0;
- u32 fwsm = 0;
-
- if (hw->mac_type == e1000_ich8lan) {
- fwsm = er32(FWSM);
- return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS
- : E1000_BLK_PHY_RESET;
- }
-
- if (hw->mac_type > e1000_82547_rev_2)
- manc = er32(MANC);
- return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
- E1000_BLK_PHY_RESET : E1000_SUCCESS;
-}
-
-static u8 e1000_arc_subsystem_valid(struct e1000_hw *hw)
-{
- u32 fwsm;
-
- /* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC
- * may not be provided a DMA clock when no manageability features are
- * enabled. We do not want to perform any reads/writes to these registers
- * if this is the case. We read FWSM to determine the manageability mode.
- */
- switch (hw->mac_type) {
- case e1000_82571:
- case e1000_82572:
- case e1000_82573:
- case e1000_80003es2lan:
- fwsm = er32(FWSM);
- if ((fwsm & E1000_FWSM_MODE_MASK) != 0)
- return true;
- break;
- case e1000_ich8lan:
- return true;
- default:
- break;
- }
- return false;
-}
-
-
-/******************************************************************************
- * Configure PCI-Ex no-snoop
- *
- * hw - Struct containing variables accessed by shared code.
- * no_snoop - Bitmap of no-snoop events.
- *
- * returns: E1000_SUCCESS
- *
- *****************************************************************************/
-static s32 e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, u32 no_snoop)
-{
- u32 gcr_reg = 0;
-
- DEBUGFUNC("e1000_set_pci_ex_no_snoop");
-
- if (hw->bus_type == e1000_bus_type_unknown)
- e1000_get_bus_info(hw);
-
- if (hw->bus_type != e1000_bus_type_pci_express)
- return E1000_SUCCESS;
-
- if (no_snoop) {
- gcr_reg = er32(GCR);
- gcr_reg &= ~(PCI_EX_NO_SNOOP_ALL);
- gcr_reg |= no_snoop;
- ew32(GCR, gcr_reg);
- }
- if (hw->mac_type == e1000_ich8lan) {
- u32 ctrl_ext;
-
- ew32(GCR, PCI_EX_82566_SNOOP_ALL);
-
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
- ew32(CTRL_EXT, ctrl_ext);
- }
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- *
- * Get software semaphore FLAG bit (SWFLAG).
- * SWFLAG is used to synchronize the access to all shared resource between
- * SW, FW and HW.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-static s32 e1000_get_software_flag(struct e1000_hw *hw)
-{
- s32 timeout = PHY_CFG_TIMEOUT;
- u32 extcnf_ctrl;
-
- DEBUGFUNC("e1000_get_software_flag");
-
- if (hw->mac_type == e1000_ich8lan) {
- while (timeout) {
- extcnf_ctrl = er32(EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
-
- extcnf_ctrl = er32(EXTCNF_CTRL);
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
- break;
- mdelay(1);
- timeout--;
- }
-
- if (!timeout) {
- DEBUGOUT("FW or HW locks the resource too long.\n");
- return -E1000_ERR_CONFIG;
- }
- }
-
- return E1000_SUCCESS;
-}
-
-/***************************************************************************
- *
- * Release software semaphore FLAG bit (SWFLAG).
- * SWFLAG is used to synchronize the access to all shared resource between
- * SW, FW and HW.
- *
- * hw: Struct containing variables accessed by shared code
- *
- ***************************************************************************/
-static void e1000_release_software_flag(struct e1000_hw *hw)
-{
- u32 extcnf_ctrl;
-
- DEBUGFUNC("e1000_release_software_flag");
-
- if (hw->mac_type == e1000_ich8lan) {
- extcnf_ctrl= er32(EXTCNF_CTRL);
- extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- }
-
- return;
-}
-
-/******************************************************************************
- * Reads a 16 bit word or words from the EEPROM using the ICH8's flash access
- * register.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to read
- * data - word read from the EEPROM
- * words - number of words to read
- *****************************************************************************/
-static s32 e1000_read_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- s32 error = E1000_SUCCESS;
- u32 flash_bank = 0;
- u32 act_offset = 0;
- u32 bank_offset = 0;
- u16 word = 0;
- u16 i = 0;
-
- /* We need to know which is the valid flash bank. In the event
- * that we didn't allocate eeprom_shadow_ram, we may not be
- * managing flash_bank. So it cannot be trusted and needs
- * to be updated with each read.
- */
- /* Value of bit 22 corresponds to the flash bank we're on. */
- flash_bank = (er32(EECD) & E1000_EECD_SEC1VAL) ? 1 : 0;
-
- /* Adjust offset appropriately if we're on bank 1 - adjust for word size */
- bank_offset = flash_bank * (hw->flash_bank_size * 2);
-
- error = e1000_get_software_flag(hw);
- if (error != E1000_SUCCESS)
- return error;
-
- for (i = 0; i < words; i++) {
- if (hw->eeprom_shadow_ram != NULL &&
- hw->eeprom_shadow_ram[offset+i].modified) {
- data[i] = hw->eeprom_shadow_ram[offset+i].eeprom_word;
- } else {
- /* The NVM part needs a byte offset, hence * 2 */
- act_offset = bank_offset + ((offset + i) * 2);
- error = e1000_read_ich8_word(hw, act_offset, &word);
- if (error != E1000_SUCCESS)
- break;
- data[i] = word;
- }
- }
-
- e1000_release_software_flag(hw);
-
- return error;
-}
-
-/******************************************************************************
- * Writes a 16 bit word or words to the EEPROM using the ICH8's flash access
- * register. Actually, writes are written to the shadow ram cache in the hw
- * structure hw->e1000_shadow_ram. e1000_commit_shadow_ram flushes this to
- * the NVM, which occurs when the NVM checksum is updated.
- *
- * hw - Struct containing variables accessed by shared code
- * offset - offset of word in the EEPROM to write
- * words - number of words to write
- * data - words to write to the EEPROM
- *****************************************************************************/
-static s32 e1000_write_eeprom_ich8(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- u32 i = 0;
- s32 error = E1000_SUCCESS;
-
- error = e1000_get_software_flag(hw);
- if (error != E1000_SUCCESS)
- return error;
-
- /* A driver can write to the NVM only if it has eeprom_shadow_ram
- * allocated. Subsequent reads to the modified words are read from
- * this cached structure as well. Writes will only go into this
- * cached structure unless it's followed by a call to
- * e1000_update_eeprom_checksum() where it will commit the changes
- * and clear the "modified" field.
- */
- if (hw->eeprom_shadow_ram != NULL) {
- for (i = 0; i < words; i++) {
- if ((offset + i) < E1000_SHADOW_RAM_WORDS) {
- hw->eeprom_shadow_ram[offset+i].modified = true;
- hw->eeprom_shadow_ram[offset+i].eeprom_word = data[i];
- } else {
- error = -E1000_ERR_EEPROM;
- break;
- }
- }
- } else {
- /* Drivers have the option to not allocate eeprom_shadow_ram as long
- * as they don't perform any NVM writes. An attempt in doing so
- * will result in this error.
- */
- error = -E1000_ERR_EEPROM;
- }
-
- e1000_release_software_flag(hw);
-
- return error;
-}
-
-/******************************************************************************
- * This function does initial flash setup so that a new read/write/erase cycle
- * can be started.
- *
- * hw - The pointer to the hw structure
- ****************************************************************************/
-static s32 e1000_ich8_cycle_init(struct e1000_hw *hw)
-{
- union ich8_hws_flash_status hsfsts;
- s32 error = E1000_ERR_EEPROM;
- s32 i = 0;
-
- DEBUGFUNC("e1000_ich8_cycle_init");
-
- hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
-
- /* May be check the Flash Des Valid bit in Hw status */
- if (hsfsts.hsf_status.fldesvalid == 0) {
- DEBUGOUT("Flash descriptor invalid. SW Sequencing must be used.");
- return error;
- }
-
- /* Clear FCERR in Hw status by writing 1 */
- /* Clear DAEL in Hw status by writing a 1 */
- hsfsts.hsf_status.flcerr = 1;
- hsfsts.hsf_status.dael = 1;
-
- E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
-
- /* Either we should have a hardware SPI cycle in progress bit to check
- * against, in order to start a new cycle or FDONE bit should be changed
- * in the hardware so that it is 1 after harware reset, which can then be
- * used as an indication whether a cycle is in progress or has been
- * completed .. we should also have some software semaphore mechanism to
- * guard FDONE or the cycle in progress bit so that two threads access to
- * those bits can be sequentiallized or a way so that 2 threads dont
- * start the cycle at the same time */
-
- if (hsfsts.hsf_status.flcinprog == 0) {
- /* There is no cycle running at present, so we can start a cycle */
- /* Begin by setting Flash Cycle Done. */
- hsfsts.hsf_status.flcdone = 1;
- E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
- error = E1000_SUCCESS;
- } else {
- /* otherwise poll for sometime so the current cycle has a chance
- * to end before giving up. */
- for (i = 0; i < ICH_FLASH_COMMAND_TIMEOUT; i++) {
- hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcinprog == 0) {
- error = E1000_SUCCESS;
- break;
- }
- udelay(1);
- }
- if (error == E1000_SUCCESS) {
- /* Successful in waiting for previous cycle to timeout,
- * now set the Flash Cycle Done. */
- hsfsts.hsf_status.flcdone = 1;
- E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
- } else {
- DEBUGOUT("Flash controller busy, cannot get access");
- }
- }
- return error;
-}
-
-/******************************************************************************
- * This function starts a flash cycle and waits for its completion
- *
- * hw - The pointer to the hw structure
- ****************************************************************************/
-static s32 e1000_ich8_flash_cycle(struct e1000_hw *hw, u32 timeout)
-{
- union ich8_hws_flash_ctrl hsflctl;
- union ich8_hws_flash_status hsfsts;
- s32 error = E1000_ERR_EEPROM;
- u32 i = 0;
-
- /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
- hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
- hsflctl.hsf_ctrl.flcgo = 1;
- E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
-
- /* wait till FDONE bit is set to 1 */
- do {
- hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcdone == 1)
- break;
- udelay(1);
- i++;
- } while (i < timeout);
- if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0) {
- error = E1000_SUCCESS;
- }
- return error;
-}
-
-/******************************************************************************
- * Reads a byte or word from the NVM using the ICH8 flash access registers.
- *
- * hw - The pointer to the hw structure
- * index - The index of the byte or word to read.
- * size - Size of data to read, 1=byte 2=word
- * data - Pointer to the word to store the value read.
- *****************************************************************************/
-static s32 e1000_read_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
- u16 *data)
-{
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_address;
- u32 flash_data = 0;
- s32 error = -E1000_ERR_EEPROM;
- s32 count = 0;
-
- DEBUGFUNC("e1000_read_ich8_data");
-
- if (size < 1 || size > 2 || data == NULL ||
- index > ICH_FLASH_LINEAR_ADDR_MASK)
- return error;
-
- flash_linear_address = (ICH_FLASH_LINEAR_ADDR_MASK & index) +
- hw->flash_base_addr;
-
- do {
- udelay(1);
- /* Steps */
- error = e1000_ich8_cycle_init(hw);
- if (error != E1000_SUCCESS)
- break;
-
- hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
- /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
- hsflctl.hsf_ctrl.fldbcount = size - 1;
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
- E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
-
- /* Write the last 24 bits of index into Flash Linear address field in
- * Flash Address */
- /* TODO: TBD maybe check the index against the size of flash */
-
- E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_address);
-
- error = e1000_ich8_flash_cycle(hw, ICH_FLASH_COMMAND_TIMEOUT);
-
- /* Check if FCERR is set to 1, if set to 1, clear it and try the whole
- * sequence a few more times, else read in (shift in) the Flash Data0,
- * the order is least significant byte first msb to lsb */
- if (error == E1000_SUCCESS) {
- flash_data = E1000_READ_ICH_FLASH_REG(hw, ICH_FLASH_FDATA0);
- if (size == 1) {
- *data = (u8)(flash_data & 0x000000FF);
- } else if (size == 2) {
- *data = (u16)(flash_data & 0x0000FFFF);
- }
- break;
- } else {
- /* If we've gotten here, then things are probably completely hosed,
- * but if the error condition is detected, it won't hurt to give
- * it another try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
- */
- hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1) {
- /* Repeat for some time before giving up. */
- continue;
- } else if (hsfsts.hsf_status.flcdone == 0) {
- DEBUGOUT("Timeout error - flash cycle did not complete.");
- break;
- }
- }
- } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
-
- return error;
-}
-
-/******************************************************************************
- * Writes One /two bytes to the NVM using the ICH8 flash access registers.
- *
- * hw - The pointer to the hw structure
- * index - The index of the byte/word to read.
- * size - Size of data to read, 1=byte 2=word
- * data - The byte(s) to write to the NVM.
- *****************************************************************************/
-static s32 e1000_write_ich8_data(struct e1000_hw *hw, u32 index, u32 size,
- u16 data)
-{
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_address;
- u32 flash_data = 0;
- s32 error = -E1000_ERR_EEPROM;
- s32 count = 0;
-
- DEBUGFUNC("e1000_write_ich8_data");
-
- if (size < 1 || size > 2 || data > size * 0xff ||
- index > ICH_FLASH_LINEAR_ADDR_MASK)
- return error;
-
- flash_linear_address = (ICH_FLASH_LINEAR_ADDR_MASK & index) +
- hw->flash_base_addr;
-
- do {
- udelay(1);
- /* Steps */
- error = e1000_ich8_cycle_init(hw);
- if (error != E1000_SUCCESS)
- break;
-
- hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
- /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
- hsflctl.hsf_ctrl.fldbcount = size -1;
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
- E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
-
- /* Write the last 24 bits of index into Flash Linear address field in
- * Flash Address */
- E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_address);
-
- if (size == 1)
- flash_data = (u32)data & 0x00FF;
- else
- flash_data = (u32)data;
-
- E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FDATA0, flash_data);
-
- /* check if FCERR is set to 1 , if set to 1, clear it and try the whole
- * sequence a few more times else done */
- error = e1000_ich8_flash_cycle(hw, ICH_FLASH_COMMAND_TIMEOUT);
- if (error == E1000_SUCCESS) {
- break;
- } else {
- /* If we're here, then things are most likely completely hosed,
- * but if the error condition is detected, it won't hurt to give
- * it another try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
- */
- hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1) {
- /* Repeat for some time before giving up. */
- continue;
- } else if (hsfsts.hsf_status.flcdone == 0) {
- DEBUGOUT("Timeout error - flash cycle did not complete.");
- break;
- }
- }
- } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
-
- return error;
-}
-
-/******************************************************************************
- * Reads a single byte from the NVM using the ICH8 flash access registers.
- *
- * hw - pointer to e1000_hw structure
- * index - The index of the byte to read.
- * data - Pointer to a byte to store the value read.
- *****************************************************************************/
-static s32 e1000_read_ich8_byte(struct e1000_hw *hw, u32 index, u8 *data)
-{
- s32 status = E1000_SUCCESS;
- u16 word = 0;
-
- status = e1000_read_ich8_data(hw, index, 1, &word);
- if (status == E1000_SUCCESS) {
- *data = (u8)word;
- }
-
- return status;
-}
-
-/******************************************************************************
- * Writes a single byte to the NVM using the ICH8 flash access registers.
- * Performs verification by reading back the value and then going through
- * a retry algorithm before giving up.
- *
- * hw - pointer to e1000_hw structure
- * index - The index of the byte to write.
- * byte - The byte to write to the NVM.
- *****************************************************************************/
-static s32 e1000_verify_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 byte)
-{
- s32 error = E1000_SUCCESS;
- s32 program_retries = 0;
-
- DEBUGOUT2("Byte := %2.2X Offset := %d\n", byte, index);
-
- error = e1000_write_ich8_byte(hw, index, byte);
-
- if (error != E1000_SUCCESS) {
- for (program_retries = 0; program_retries < 100; program_retries++) {
- DEBUGOUT2("Retrying \t Byte := %2.2X Offset := %d\n", byte, index);
- error = e1000_write_ich8_byte(hw, index, byte);
- udelay(100);
- if (error == E1000_SUCCESS)
- break;
- }
- }
-
- if (program_retries == 100)
- error = E1000_ERR_EEPROM;
-
- return error;
-}
-
-/******************************************************************************
- * Writes a single byte to the NVM using the ICH8 flash access registers.
- *
- * hw - pointer to e1000_hw structure
- * index - The index of the byte to read.
- * data - The byte to write to the NVM.
- *****************************************************************************/
-static s32 e1000_write_ich8_byte(struct e1000_hw *hw, u32 index, u8 data)
-{
- s32 status = E1000_SUCCESS;
- u16 word = (u16)data;
-
- status = e1000_write_ich8_data(hw, index, 1, word);
-
- return status;
-}
-
-/******************************************************************************
- * Reads a word from the NVM using the ICH8 flash access registers.
- *
- * hw - pointer to e1000_hw structure
- * index - The starting byte index of the word to read.
- * data - Pointer to a word to store the value read.
- *****************************************************************************/
-static s32 e1000_read_ich8_word(struct e1000_hw *hw, u32 index, u16 *data)
-{
- s32 status = E1000_SUCCESS;
- status = e1000_read_ich8_data(hw, index, 2, data);
- return status;
-}
-
-/******************************************************************************
- * Erases the bank specified. Each bank may be a 4, 8 or 64k block. Banks are 0
- * based.
- *
- * hw - pointer to e1000_hw structure
- * bank - 0 for first bank, 1 for second bank
- *
- * Note that this function may actually erase as much as 8 or 64 KBytes. The
- * amount of NVM used in each bank is a *minimum* of 4 KBytes, but in fact the
- * bank size may be 4, 8 or 64 KBytes
- *****************************************************************************/
-static s32 e1000_erase_ich8_4k_segment(struct e1000_hw *hw, u32 bank)
-{
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_address;
- s32 count = 0;
- s32 error = E1000_ERR_EEPROM;
- s32 iteration;
- s32 sub_sector_size = 0;
- s32 bank_size;
- s32 j = 0;
- s32 error_flag = 0;
-
- hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
-
- /* Determine HW Sector size: Read BERASE bits of Hw flash Status register */
- /* 00: The Hw sector is 256 bytes, hence we need to erase 16
- * consecutive sectors. The start index for the nth Hw sector can be
- * calculated as bank * 4096 + n * 256
- * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
- * The start index for the nth Hw sector can be calculated
- * as bank * 4096
- * 10: The HW sector is 8K bytes
- * 11: The Hw sector size is 64K bytes */
- if (hsfsts.hsf_status.berasesz == 0x0) {
- /* Hw sector size 256 */
- sub_sector_size = ICH_FLASH_SEG_SIZE_256;
- bank_size = ICH_FLASH_SECTOR_SIZE;
- iteration = ICH_FLASH_SECTOR_SIZE / ICH_FLASH_SEG_SIZE_256;
- } else if (hsfsts.hsf_status.berasesz == 0x1) {
- bank_size = ICH_FLASH_SEG_SIZE_4K;
- iteration = 1;
- } else if (hsfsts.hsf_status.berasesz == 0x3) {
- bank_size = ICH_FLASH_SEG_SIZE_64K;
- iteration = 1;
- } else {
- return error;
- }
-
- for (j = 0; j < iteration ; j++) {
- do {
- count++;
- /* Steps */
- error = e1000_ich8_cycle_init(hw);
- if (error != E1000_SUCCESS) {
- error_flag = 1;
- break;
- }
-
- /* Write a value 11 (block Erase) in Flash Cycle field in Hw flash
- * Control */
- hsflctl.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
- E1000_WRITE_ICH_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
-
- /* Write the last 24 bits of an index within the block into Flash
- * Linear address field in Flash Address. This probably needs to
- * be calculated here based off the on-chip erase sector size and
- * the software bank size (4, 8 or 64 KBytes) */
- flash_linear_address = bank * bank_size + j * sub_sector_size;
- flash_linear_address += hw->flash_base_addr;
- flash_linear_address &= ICH_FLASH_LINEAR_ADDR_MASK;
-
- E1000_WRITE_ICH_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_address);
-
- error = e1000_ich8_flash_cycle(hw, ICH_FLASH_ERASE_TIMEOUT);
- /* Check if FCERR is set to 1. If 1, clear it and try the whole
- * sequence a few more times else Done */
- if (error == E1000_SUCCESS) {
- break;
- } else {
- hsfsts.regval = E1000_READ_ICH_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1) {
- /* repeat for some time before giving up */
- continue;
- } else if (hsfsts.hsf_status.flcdone == 0) {
- error_flag = 1;
- break;
- }
- }
- } while ((count < ICH_FLASH_CYCLE_REPEAT_COUNT) && !error_flag);
- if (error_flag == 1)
- break;
- }
- if (error_flag != 1)
- error = E1000_SUCCESS;
- return error;
-}
-
-static s32 e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
- u32 cnf_base_addr,
- u32 cnf_size)
-{
- u32 ret_val = E1000_SUCCESS;
- u16 word_addr, reg_data, reg_addr;
- u16 i;
-
- /* cnf_base_addr is in DWORD */
- word_addr = (u16)(cnf_base_addr << 1);
-
- /* cnf_size is returned in size of dwords */
- for (i = 0; i < cnf_size; i++) {
- ret_val = e1000_read_eeprom(hw, (word_addr + i*2), 1, &reg_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_eeprom(hw, (word_addr + i*2 + 1), 1, &reg_addr);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_get_software_flag(hw);
- if (ret_val != E1000_SUCCESS)
- return ret_val;
-
- ret_val = e1000_write_phy_reg_ex(hw, (u32)reg_addr, reg_data);
-
- e1000_release_software_flag(hw);
- }
-
- return ret_val;
-}
-
-
-/******************************************************************************
- * This function initializes the PHY from the NVM on ICH8 platforms. This
- * is needed due to an issue where the NVM configuration is not properly
- * autoloaded after power transitions. Therefore, after each PHY reset, we
- * will load the configuration data out of the NVM manually.
- *
- * hw: Struct containing variables accessed by shared code
- *****************************************************************************/
-static s32 e1000_init_lcd_from_nvm(struct e1000_hw *hw)
-{
- u32 reg_data, cnf_base_addr, cnf_size, ret_val, loop;
-
- if (hw->phy_type != e1000_phy_igp_3)
- return E1000_SUCCESS;
-
- /* Check if SW needs configure the PHY */
- reg_data = er32(FEXTNVM);
- if (!(reg_data & FEXTNVM_SW_CONFIG))
- return E1000_SUCCESS;
-
- /* Wait for basic configuration completes before proceeding*/
- loop = 0;
- do {
- reg_data = er32(STATUS) & E1000_STATUS_LAN_INIT_DONE;
- udelay(100);
- loop++;
- } while ((!reg_data) && (loop < 50));
-
- /* Clear the Init Done bit for the next init event */
- reg_data = er32(STATUS);
- reg_data &= ~E1000_STATUS_LAN_INIT_DONE;
- ew32(STATUS, reg_data);
-
- /* Make sure HW does not configure LCD from PHY extended configuration
- before SW configuration */
- reg_data = er32(EXTCNF_CTRL);
- if ((reg_data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) == 0x0000) {
- reg_data = er32(EXTCNF_SIZE);
- cnf_size = reg_data & E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH;
- cnf_size >>= 16;
- if (cnf_size) {
- reg_data = er32(EXTCNF_CTRL);
- cnf_base_addr = reg_data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER;
- /* cnf_base_addr is in DWORD */
- cnf_base_addr >>= 16;
-
- /* Configure LCD from extended configuration region. */
- ret_val = e1000_init_lcd_from_nvm_config_region(hw, cnf_base_addr,
- cnf_size);
- if (ret_val)
- return ret_val;
- }
- }
-
- return E1000_SUCCESS;
-}
-
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
deleted file mode 100644
index 99fce2c5dd2..00000000000
--- a/drivers/net/e1000/e1000_hw.h
+++ /dev/null
@@ -1,3406 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2006 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* e1000_hw.h
- * Structures, enums, and macros for the MAC
- */
-
-#ifndef _E1000_HW_H_
-#define _E1000_HW_H_
-
-#include "e1000_osdep.h"
-
-
-/* Forward declarations of structures used by the shared code */
-struct e1000_hw;
-struct e1000_hw_stats;
-
-/* Enumerated types specific to the e1000 hardware */
-/* Media Access Controlers */
-typedef enum {
- e1000_undefined = 0,
- e1000_82542_rev2_0,
- e1000_82542_rev2_1,
- e1000_82543,
- e1000_82544,
- e1000_82540,
- e1000_82545,
- e1000_82545_rev_3,
- e1000_82546,
- e1000_82546_rev_3,
- e1000_82541,
- e1000_82541_rev_2,
- e1000_82547,
- e1000_82547_rev_2,
- e1000_82571,
- e1000_82572,
- e1000_82573,
- e1000_80003es2lan,
- e1000_ich8lan,
- e1000_num_macs
-} e1000_mac_type;
-
-typedef enum {
- e1000_eeprom_uninitialized = 0,
- e1000_eeprom_spi,
- e1000_eeprom_microwire,
- e1000_eeprom_flash,
- e1000_eeprom_ich8,
- e1000_eeprom_none, /* No NVM support */
- e1000_num_eeprom_types
-} e1000_eeprom_type;
-
-/* Media Types */
-typedef enum {
- e1000_media_type_copper = 0,
- e1000_media_type_fiber = 1,
- e1000_media_type_internal_serdes = 2,
- e1000_num_media_types
-} e1000_media_type;
-
-typedef enum {
- e1000_10_half = 0,
- e1000_10_full = 1,
- e1000_100_half = 2,
- e1000_100_full = 3
-} e1000_speed_duplex_type;
-
-/* Flow Control Settings */
-typedef enum {
- E1000_FC_NONE = 0,
- E1000_FC_RX_PAUSE = 1,
- E1000_FC_TX_PAUSE = 2,
- E1000_FC_FULL = 3,
- E1000_FC_DEFAULT = 0xFF
-} e1000_fc_type;
-
-struct e1000_shadow_ram {
- u16 eeprom_word;
- bool modified;
-};
-
-/* PCI bus types */
-typedef enum {
- e1000_bus_type_unknown = 0,
- e1000_bus_type_pci,
- e1000_bus_type_pcix,
- e1000_bus_type_pci_express,
- e1000_bus_type_reserved
-} e1000_bus_type;
-
-/* PCI bus speeds */
-typedef enum {
- e1000_bus_speed_unknown = 0,
- e1000_bus_speed_33,
- e1000_bus_speed_66,
- e1000_bus_speed_100,
- e1000_bus_speed_120,
- e1000_bus_speed_133,
- e1000_bus_speed_2500,
- e1000_bus_speed_reserved
-} e1000_bus_speed;
-
-/* PCI bus widths */
-typedef enum {
- e1000_bus_width_unknown = 0,
- /* These PCIe values should literally match the possible return values
- * from config space */
- e1000_bus_width_pciex_1 = 1,
- e1000_bus_width_pciex_2 = 2,
- e1000_bus_width_pciex_4 = 4,
- e1000_bus_width_32,
- e1000_bus_width_64,
- e1000_bus_width_reserved
-} e1000_bus_width;
-
-/* PHY status info structure and supporting enums */
-typedef enum {
- e1000_cable_length_50 = 0,
- e1000_cable_length_50_80,
- e1000_cable_length_80_110,
- e1000_cable_length_110_140,
- e1000_cable_length_140,
- e1000_cable_length_undefined = 0xFF
-} e1000_cable_length;
-
-typedef enum {
- e1000_gg_cable_length_60 = 0,
- e1000_gg_cable_length_60_115 = 1,
- e1000_gg_cable_length_115_150 = 2,
- e1000_gg_cable_length_150 = 4
-} e1000_gg_cable_length;
-
-typedef enum {
- e1000_igp_cable_length_10 = 10,
- e1000_igp_cable_length_20 = 20,
- e1000_igp_cable_length_30 = 30,
- e1000_igp_cable_length_40 = 40,
- e1000_igp_cable_length_50 = 50,
- e1000_igp_cable_length_60 = 60,
- e1000_igp_cable_length_70 = 70,
- e1000_igp_cable_length_80 = 80,
- e1000_igp_cable_length_90 = 90,
- e1000_igp_cable_length_100 = 100,
- e1000_igp_cable_length_110 = 110,
- e1000_igp_cable_length_115 = 115,
- e1000_igp_cable_length_120 = 120,
- e1000_igp_cable_length_130 = 130,
- e1000_igp_cable_length_140 = 140,
- e1000_igp_cable_length_150 = 150,
- e1000_igp_cable_length_160 = 160,
- e1000_igp_cable_length_170 = 170,
- e1000_igp_cable_length_180 = 180
-} e1000_igp_cable_length;
-
-typedef enum {
- e1000_10bt_ext_dist_enable_normal = 0,
- e1000_10bt_ext_dist_enable_lower,
- e1000_10bt_ext_dist_enable_undefined = 0xFF
-} e1000_10bt_ext_dist_enable;
-
-typedef enum {
- e1000_rev_polarity_normal = 0,
- e1000_rev_polarity_reversed,
- e1000_rev_polarity_undefined = 0xFF
-} e1000_rev_polarity;
-
-typedef enum {
- e1000_downshift_normal = 0,
- e1000_downshift_activated,
- e1000_downshift_undefined = 0xFF
-} e1000_downshift;
-
-typedef enum {
- e1000_smart_speed_default = 0,
- e1000_smart_speed_on,
- e1000_smart_speed_off
-} e1000_smart_speed;
-
-typedef enum {
- e1000_polarity_reversal_enabled = 0,
- e1000_polarity_reversal_disabled,
- e1000_polarity_reversal_undefined = 0xFF
-} e1000_polarity_reversal;
-
-typedef enum {
- e1000_auto_x_mode_manual_mdi = 0,
- e1000_auto_x_mode_manual_mdix,
- e1000_auto_x_mode_auto1,
- e1000_auto_x_mode_auto2,
- e1000_auto_x_mode_undefined = 0xFF
-} e1000_auto_x_mode;
-
-typedef enum {
- e1000_1000t_rx_status_not_ok = 0,
- e1000_1000t_rx_status_ok,
- e1000_1000t_rx_status_undefined = 0xFF
-} e1000_1000t_rx_status;
-
-typedef enum {
- e1000_phy_m88 = 0,
- e1000_phy_igp,
- e1000_phy_igp_2,
- e1000_phy_gg82563,
- e1000_phy_igp_3,
- e1000_phy_ife,
- e1000_phy_undefined = 0xFF
-} e1000_phy_type;
-
-typedef enum {
- e1000_ms_hw_default = 0,
- e1000_ms_force_master,
- e1000_ms_force_slave,
- e1000_ms_auto
-} e1000_ms_type;
-
-typedef enum {
- e1000_ffe_config_enabled = 0,
- e1000_ffe_config_active,
- e1000_ffe_config_blocked
-} e1000_ffe_config;
-
-typedef enum {
- e1000_dsp_config_disabled = 0,
- e1000_dsp_config_enabled,
- e1000_dsp_config_activated,
- e1000_dsp_config_undefined = 0xFF
-} e1000_dsp_config;
-
-struct e1000_phy_info {
- e1000_cable_length cable_length;
- e1000_10bt_ext_dist_enable extended_10bt_distance;
- e1000_rev_polarity cable_polarity;
- e1000_downshift downshift;
- e1000_polarity_reversal polarity_correction;
- e1000_auto_x_mode mdix_mode;
- e1000_1000t_rx_status local_rx;
- e1000_1000t_rx_status remote_rx;
-};
-
-struct e1000_phy_stats {
- u32 idle_errors;
- u32 receive_errors;
-};
-
-struct e1000_eeprom_info {
- e1000_eeprom_type type;
- u16 word_size;
- u16 opcode_bits;
- u16 address_bits;
- u16 delay_usec;
- u16 page_size;
- bool use_eerd;
- bool use_eewr;
-};
-
-/* Flex ASF Information */
-#define E1000_HOST_IF_MAX_SIZE 2048
-
-typedef enum {
- e1000_byte_align = 0,
- e1000_word_align = 1,
- e1000_dword_align = 2
-} e1000_align_type;
-
-
-
-/* Error Codes */
-#define E1000_SUCCESS 0
-#define E1000_ERR_EEPROM 1
-#define E1000_ERR_PHY 2
-#define E1000_ERR_CONFIG 3
-#define E1000_ERR_PARAM 4
-#define E1000_ERR_MAC_TYPE 5
-#define E1000_ERR_PHY_TYPE 6
-#define E1000_ERR_RESET 9
-#define E1000_ERR_MASTER_REQUESTS_PENDING 10
-#define E1000_ERR_HOST_INTERFACE_COMMAND 11
-#define E1000_BLK_PHY_RESET 12
-#define E1000_ERR_SWFW_SYNC 13
-
-#define E1000_BYTE_SWAP_WORD(_value) ((((_value) & 0x00ff) << 8) | \
- (((_value) & 0xff00) >> 8))
-
-/* Function prototypes */
-/* Initialization */
-s32 e1000_reset_hw(struct e1000_hw *hw);
-s32 e1000_init_hw(struct e1000_hw *hw);
-s32 e1000_set_mac_type(struct e1000_hw *hw);
-void e1000_set_media_type(struct e1000_hw *hw);
-
-/* Link Configuration */
-s32 e1000_setup_link(struct e1000_hw *hw);
-s32 e1000_phy_setup_autoneg(struct e1000_hw *hw);
-void e1000_config_collision_dist(struct e1000_hw *hw);
-s32 e1000_check_for_link(struct e1000_hw *hw);
-s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex);
-s32 e1000_force_mac_fc(struct e1000_hw *hw);
-
-/* PHY */
-s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 *phy_data);
-s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 reg_addr, u16 data);
-s32 e1000_phy_hw_reset(struct e1000_hw *hw);
-s32 e1000_phy_reset(struct e1000_hw *hw);
-s32 e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-s32 e1000_validate_mdi_setting(struct e1000_hw *hw);
-
-void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
-
-/* EEPROM Functions */
-s32 e1000_init_eeprom_params(struct e1000_hw *hw);
-
-/* MNG HOST IF functions */
-u32 e1000_enable_mng_pass_thru(struct e1000_hw *hw);
-
-#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
-#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 /* Host Interface data length */
-
-#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 /* Time in ms to process MNG command */
-#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */
-#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */
-#define E1000_MNG_IAMT_MODE 0x3
-#define E1000_MNG_ICH_IAMT_MODE 0x2
-#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management Technology signature */
-
-#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1 /* DHCP parsing enabled */
-#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT 0x2 /* DHCP parsing enabled */
-#define E1000_VFTA_ENTRY_SHIFT 0x5
-#define E1000_VFTA_ENTRY_MASK 0x7F
-#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
-
-struct e1000_host_mng_command_header {
- u8 command_id;
- u8 checksum;
- u16 reserved1;
- u16 reserved2;
- u16 command_length;
-};
-
-struct e1000_host_mng_command_info {
- struct e1000_host_mng_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
- u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; /* Command data can length 0..0x658*/
-};
-#ifdef __BIG_ENDIAN
-struct e1000_host_mng_dhcp_cookie{
- u32 signature;
- u16 vlan_id;
- u8 reserved0;
- u8 status;
- u32 reserved1;
- u8 checksum;
- u8 reserved3;
- u16 reserved2;
-};
-#else
-struct e1000_host_mng_dhcp_cookie{
- u32 signature;
- u8 status;
- u8 reserved0;
- u16 vlan_id;
- u32 reserved1;
- u16 reserved2;
- u8 reserved3;
- u8 checksum;
-};
-#endif
-
-s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer,
- u16 length);
-bool e1000_check_mng_mode(struct e1000_hw *hw);
-bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
-s32 e1000_read_eeprom(struct e1000_hw *hw, u16 reg, u16 words, u16 *data);
-s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw);
-s32 e1000_update_eeprom_checksum(struct e1000_hw *hw);
-s32 e1000_write_eeprom(struct e1000_hw *hw, u16 reg, u16 words, u16 *data);
-s32 e1000_read_mac_addr(struct e1000_hw * hw);
-
-/* Filters (multicast, vlan, receive) */
-u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 * mc_addr);
-void e1000_mta_set(struct e1000_hw *hw, u32 hash_value);
-void e1000_rar_set(struct e1000_hw *hw, u8 * mc_addr, u32 rar_index);
-void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
-
-/* LED functions */
-s32 e1000_setup_led(struct e1000_hw *hw);
-s32 e1000_cleanup_led(struct e1000_hw *hw);
-s32 e1000_led_on(struct e1000_hw *hw);
-s32 e1000_led_off(struct e1000_hw *hw);
-s32 e1000_blink_led_start(struct e1000_hw *hw);
-
-/* Adaptive IFS Functions */
-
-/* Everything else */
-void e1000_reset_adaptive(struct e1000_hw *hw);
-void e1000_update_adaptive(struct e1000_hw *hw);
-void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, u32 frame_len, u8 * mac_addr);
-void e1000_get_bus_info(struct e1000_hw *hw);
-void e1000_pci_set_mwi(struct e1000_hw *hw);
-void e1000_pci_clear_mwi(struct e1000_hw *hw);
-s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
-void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc);
-int e1000_pcix_get_mmrbc(struct e1000_hw *hw);
-/* Port I/O is only supported on 82544 and newer */
-void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value);
-s32 e1000_disable_pciex_master(struct e1000_hw *hw);
-s32 e1000_check_phy_reset_block(struct e1000_hw *hw);
-
-
-#define E1000_READ_REG_IO(a, reg) \
- e1000_read_reg_io((a), E1000_##reg)
-#define E1000_WRITE_REG_IO(a, reg, val) \
- e1000_write_reg_io((a), E1000_##reg, val)
-
-/* PCI Device IDs */
-#define E1000_DEV_ID_82542 0x1000
-#define E1000_DEV_ID_82543GC_FIBER 0x1001
-#define E1000_DEV_ID_82543GC_COPPER 0x1004
-#define E1000_DEV_ID_82544EI_COPPER 0x1008
-#define E1000_DEV_ID_82544EI_FIBER 0x1009
-#define E1000_DEV_ID_82544GC_COPPER 0x100C
-#define E1000_DEV_ID_82544GC_LOM 0x100D
-#define E1000_DEV_ID_82540EM 0x100E
-#define E1000_DEV_ID_82540EM_LOM 0x1015
-#define E1000_DEV_ID_82540EP_LOM 0x1016
-#define E1000_DEV_ID_82540EP 0x1017
-#define E1000_DEV_ID_82540EP_LP 0x101E
-#define E1000_DEV_ID_82545EM_COPPER 0x100F
-#define E1000_DEV_ID_82545EM_FIBER 0x1011
-#define E1000_DEV_ID_82545GM_COPPER 0x1026
-#define E1000_DEV_ID_82545GM_FIBER 0x1027
-#define E1000_DEV_ID_82545GM_SERDES 0x1028
-#define E1000_DEV_ID_82546EB_COPPER 0x1010
-#define E1000_DEV_ID_82546EB_FIBER 0x1012
-#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
-#define E1000_DEV_ID_82541EI 0x1013
-#define E1000_DEV_ID_82541EI_MOBILE 0x1018
-#define E1000_DEV_ID_82541ER_LOM 0x1014
-#define E1000_DEV_ID_82541ER 0x1078
-#define E1000_DEV_ID_82547GI 0x1075
-#define E1000_DEV_ID_82541GI 0x1076
-#define E1000_DEV_ID_82541GI_MOBILE 0x1077
-#define E1000_DEV_ID_82541GI_LF 0x107C
-#define E1000_DEV_ID_82546GB_COPPER 0x1079
-#define E1000_DEV_ID_82546GB_FIBER 0x107A
-#define E1000_DEV_ID_82546GB_SERDES 0x107B
-#define E1000_DEV_ID_82546GB_PCIE 0x108A
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
-#define E1000_DEV_ID_82547EI 0x1019
-#define E1000_DEV_ID_82547EI_MOBILE 0x101A
-#define E1000_DEV_ID_82571EB_COPPER 0x105E
-#define E1000_DEV_ID_82571EB_FIBER 0x105F
-#define E1000_DEV_ID_82571EB_SERDES 0x1060
-#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
-#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
-#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
-#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC
-#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
-#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
-#define E1000_DEV_ID_82572EI_COPPER 0x107D
-#define E1000_DEV_ID_82572EI_FIBER 0x107E
-#define E1000_DEV_ID_82572EI_SERDES 0x107F
-#define E1000_DEV_ID_82572EI 0x10B9
-#define E1000_DEV_ID_82573E 0x108B
-#define E1000_DEV_ID_82573E_IAMT 0x108C
-#define E1000_DEV_ID_82573L 0x109A
-#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
-#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
-#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
-#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
-#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
-
-#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
-#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
-#define E1000_DEV_ID_ICH8_IGP_C 0x104B
-#define E1000_DEV_ID_ICH8_IFE 0x104C
-#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
-#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
-#define E1000_DEV_ID_ICH8_IGP_M 0x104D
-
-
-#define NODE_ADDRESS_SIZE 6
-#define ETH_LENGTH_OF_ADDRESS 6
-
-/* MAC decode size is 128K - This is the size of BAR0 */
-#define MAC_DECODE_SIZE (128 * 1024)
-
-#define E1000_82542_2_0_REV_ID 2
-#define E1000_82542_2_1_REV_ID 3
-#define E1000_REVISION_0 0
-#define E1000_REVISION_1 1
-#define E1000_REVISION_2 2
-#define E1000_REVISION_3 3
-
-#define SPEED_10 10
-#define SPEED_100 100
-#define SPEED_1000 1000
-#define HALF_DUPLEX 1
-#define FULL_DUPLEX 2
-
-/* The sizes (in bytes) of a ethernet packet */
-#define ENET_HEADER_SIZE 14
-#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* With FCS */
-#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
-#define ETHERNET_FCS_SIZE 4
-#define MAXIMUM_ETHERNET_PACKET_SIZE \
- (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
-#define MINIMUM_ETHERNET_PACKET_SIZE \
- (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
-#define CRC_LENGTH ETHERNET_FCS_SIZE
-#define MAX_JUMBO_FRAME_SIZE 0x3F00
-
-
-/* 802.1q VLAN Packet Sizes */
-#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */
-
-/* Ethertype field values */
-#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
-#define ETHERNET_IP_TYPE 0x0800 /* IP packets */
-#define ETHERNET_ARP_TYPE 0x0806 /* Address Resolution Protocol (ARP) */
-
-/* Packet Header defines */
-#define IP_PROTOCOL_TCP 6
-#define IP_PROTOCOL_UDP 0x11
-
-/* This defines the bits that are set in the Interrupt Mask
- * Set/Read Register. Each bit is documented below:
- * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- * o RXSEQ = Receive Sequence Error
- */
-#define POLL_IMS_ENABLE_MASK ( \
- E1000_IMS_RXDMT0 | \
- E1000_IMS_RXSEQ)
-
-/* This defines the bits that are set in the Interrupt Mask
- * Set/Read Register. Each bit is documented below:
- * o RXT0 = Receiver Timer Interrupt (ring 0)
- * o TXDW = Transmit Descriptor Written Back
- * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
- * o RXSEQ = Receive Sequence Error
- * o LSC = Link Status Change
- */
-#define IMS_ENABLE_MASK ( \
- E1000_IMS_RXT0 | \
- E1000_IMS_TXDW | \
- E1000_IMS_RXDMT0 | \
- E1000_IMS_RXSEQ | \
- E1000_IMS_LSC)
-
-/* Additional interrupts need to be handled for e1000_ich8lan:
- DSW = The FW changed the status of the DISSW bit in FWSM
- PHYINT = The LAN connected device generates an interrupt
- EPRST = Manageability reset event */
-#define IMS_ICH8LAN_ENABLE_MASK (\
- E1000_IMS_DSW | \
- E1000_IMS_PHYINT | \
- E1000_IMS_EPRST)
-
-/* Number of high/low register pairs in the RAR. The RAR (Receive Address
- * Registers) holds the directed and multicast addresses that we monitor. We
- * reserve one of these spots for our directed address, allowing us room for
- * E1000_RAR_ENTRIES - 1 multicast addresses.
- */
-#define E1000_RAR_ENTRIES 15
-
-#define E1000_RAR_ENTRIES_ICH8LAN 6
-
-#define MIN_NUMBER_OF_DESCRIPTORS 8
-#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
-
-/* Receive Descriptor */
-struct e1000_rx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- __le16 length; /* Length of data DMAed into data buffer */
- __le16 csum; /* Packet checksum */
- u8 status; /* Descriptor status */
- u8 errors; /* Descriptor Errors */
- __le16 special;
-};
-
-/* Receive Descriptor - Extended */
-union e1000_rx_desc_extended {
- struct {
- __le64 buffer_addr;
- __le64 reserved;
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length;
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-/* Receive Descriptor - Packet Split */
-union e1000_rx_desc_packet_split {
- struct {
- /* one buffer for protocol header(s), three data buffers */
- __le64 buffer_addr[MAX_PS_BUFFERS];
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length0; /* length of buffer 0 */
- __le16 vlan; /* VLAN tag */
- } middle;
- struct {
- __le16 header_status;
- __le16 length[3]; /* length of buffers 1-3 */
- } upper;
- __le64 reserved;
- } wb; /* writeback */
-};
-
-/* Receive Decriptor bit definitions */
-#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
-#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
-#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
-#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
-#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
-#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
-#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
-#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
-#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
-#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
-#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
-#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
-#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
-#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
-#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
-#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
-#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
-#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
-#define E1000_RXD_SPC_PRI_SHIFT 13
-#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
-#define E1000_RXD_SPC_CFI_SHIFT 12
-
-#define E1000_RXDEXT_STATERR_CE 0x01000000
-#define E1000_RXDEXT_STATERR_SE 0x02000000
-#define E1000_RXDEXT_STATERR_SEQ 0x04000000
-#define E1000_RXDEXT_STATERR_CXE 0x10000000
-#define E1000_RXDEXT_STATERR_TCPE 0x20000000
-#define E1000_RXDEXT_STATERR_IPE 0x40000000
-#define E1000_RXDEXT_STATERR_RXE 0x80000000
-
-#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
-#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
-
-/* mask to determine if packets should be dropped due to frame errors */
-#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
- E1000_RXD_ERR_CE | \
- E1000_RXD_ERR_SE | \
- E1000_RXD_ERR_SEQ | \
- E1000_RXD_ERR_CXE | \
- E1000_RXD_ERR_RXE)
-
-
-/* Same mask, but for extended and packet split descriptors */
-#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
- E1000_RXDEXT_STATERR_CE | \
- E1000_RXDEXT_STATERR_SE | \
- E1000_RXDEXT_STATERR_SEQ | \
- E1000_RXDEXT_STATERR_CXE | \
- E1000_RXDEXT_STATERR_RXE)
-
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 cso; /* Checksum offset */
- u8 cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
- __le16 special;
- } fields;
- } upper;
-};
-
-/* Transmit Descriptor bit definitions */
-#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
-#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
-#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
-#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
-#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
-#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
-#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
-#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
-#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
-#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
-#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
-#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
-#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
-#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
-#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
-#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
-#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
-#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
-#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
-#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
- union {
- __le32 ip_config;
- struct {
- u8 ipcss; /* IP checksum start */
- u8 ipcso; /* IP checksum offset */
- __le16 ipcse; /* IP checksum end */
- } ip_fields;
- } lower_setup;
- union {
- __le32 tcp_config;
- struct {
- u8 tucss; /* TCP checksum start */
- u8 tucso; /* TCP checksum offset */
- __le16 tucse; /* TCP checksum end */
- } tcp_fields;
- } upper_setup;
- __le32 cmd_and_length; /* */
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 hdr_len; /* Header length */
- __le16 mss; /* Maximum segment size */
- } fields;
- } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
- __le64 buffer_addr; /* Address of the descriptor's buffer address */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 typ_len_ext; /* */
- u8 cmd; /* */
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 popts; /* Packet Options */
- __le16 special; /* */
- } fields;
- } upper;
-};
-
-/* Filters */
-#define E1000_NUM_UNICAST 16 /* Unicast filter entries */
-#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
-#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
-
-#define E1000_NUM_UNICAST_ICH8LAN 7
-#define E1000_MC_TBL_SIZE_ICH8LAN 32
-
-
-/* Receive Address Register */
-struct e1000_rar {
- volatile __le32 low; /* receive address low */
- volatile __le32 high; /* receive address high */
-};
-
-/* Number of entries in the Multicast Table Array (MTA). */
-#define E1000_NUM_MTA_REGISTERS 128
-#define E1000_NUM_MTA_REGISTERS_ICH8LAN 32
-
-/* IPv4 Address Table Entry */
-struct e1000_ipv4_at_entry {
- volatile u32 ipv4_addr; /* IP Address (RW) */
- volatile u32 reserved;
-};
-
-/* Four wakeup IP addresses are supported */
-#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
-#define E1000_IP4AT_SIZE E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
-#define E1000_IP4AT_SIZE_ICH8LAN 3
-#define E1000_IP6AT_SIZE 1
-
-/* IPv6 Address Table Entry */
-struct e1000_ipv6_at_entry {
- volatile u8 ipv6_addr[16];
-};
-
-/* Flexible Filter Length Table Entry */
-struct e1000_fflt_entry {
- volatile u32 length; /* Flexible Filter Length (RW) */
- volatile u32 reserved;
-};
-
-/* Flexible Filter Mask Table Entry */
-struct e1000_ffmt_entry {
- volatile u32 mask; /* Flexible Filter Mask (RW) */
- volatile u32 reserved;
-};
-
-/* Flexible Filter Value Table Entry */
-struct e1000_ffvt_entry {
- volatile u32 value; /* Flexible Filter Value (RW) */
- volatile u32 reserved;
-};
-
-/* Four Flexible Filters are supported */
-#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
-
-/* Each Flexible Filter is at most 128 (0x80) bytes in length */
-#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
-
-#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
-#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
-#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
-
-#define E1000_DISABLE_SERDES_LOOPBACK 0x0400
-
-/* Register Set. (82543, 82544)
- *
- * Registers are defined to be 32 bits and should be accessed as 32 bit values.
- * These registers are physically located on the NIC, but are mapped into the
- * host memory address space.
- *
- * RW - register is both readable and writable
- * RO - register is read only
- * WO - register is write only
- * R/clr - register is read only and is cleared when read
- * A - register array
- */
-#define E1000_CTRL 0x00000 /* Device Control - RW */
-#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
-#define E1000_STATUS 0x00008 /* Device Status - RO */
-#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
-#define E1000_EERD 0x00014 /* EEPROM Read - RW */
-#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
-#define E1000_FLA 0x0001C /* Flash Access - RW */
-#define E1000_MDIC 0x00020 /* MDI Control - RW */
-#define E1000_SCTL 0x00024 /* SerDes Control - RW */
-#define E1000_FEXTNVM 0x00028 /* Future Extended NVM register */
-#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
-#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
-#define E1000_FCT 0x00030 /* Flow Control Type - RW */
-#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
-#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
-#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
-#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
-#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
-#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
-#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
-#define E1000_RCTL 0x00100 /* RX Control - RW */
-#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
-#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
-#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
-#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
-#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
-#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
-#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
-#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
-#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
-#define E1000_TCTL 0x00400 /* TX Control - RW */
-#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
-#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
-#define E1000_TBT 0x00448 /* TX Burst Timer - RW */
-#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
-#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
-#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
-#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
-#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
-#define FEXTNVM_SW_CONFIG 0x0001
-#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
-#define E1000_PBS 0x01008 /* Packet Buffer Size */
-#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
-#define E1000_FLASH_UPDATES 1000
-#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
-#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
-#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
-#define E1000_FLSWCTL 0x01030 /* FLASH control register */
-#define E1000_FLSWDATA 0x01034 /* FLASH data register */
-#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
-#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
-#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
-#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
-#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
-#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
-#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
-#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
-#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
-#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
-#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
-#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
-#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
-#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
-#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
-#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
-#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
-#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
-#define E1000_RXDCTL 0x02828 /* RX Descriptor Control queue 0 - RW */
-#define E1000_RXDCTL1 0x02928 /* RX Descriptor Control queue 1 - RW */
-#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
-#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
-#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
-#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
-#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
-#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
-#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
-#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
-#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
-#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
-#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
-#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
-#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
-#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
-#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
-#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */
-#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
-#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
-#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
-#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */
-#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */
-#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */
-#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */
-#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */
-#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
-#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
-#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
-#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
-#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
-#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
-#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
-#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
-#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
-#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
-#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
-#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
-#define E1000_COLC 0x04028 /* Collision Count - R/clr */
-#define E1000_DC 0x04030 /* Defer Count - R/clr */
-#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
-#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
-#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
-#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
-#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
-#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
-#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
-#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
-#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
-#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
-#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
-#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
-#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
-#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
-#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
-#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
-#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
-#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
-#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
-#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
-#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
-#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
-#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
-#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
-#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
-#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
-#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
-#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
-#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
-#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
-#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
-#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
-#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
-#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
-#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
-#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
-#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
-#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
-#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
-#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
-#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
-#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
-#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
-#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
-#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
-#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
-#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
-#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
-#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
-#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
-#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
-#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
-#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
-#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
-#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
-#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
-#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
-#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
-#define E1000_RA 0x05400 /* Receive Address - RW Array */
-#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_WUC 0x05800 /* Wakeup Control - RW */
-#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
-#define E1000_WUS 0x05810 /* Wakeup Status - RO */
-#define E1000_MANC 0x05820 /* Management Control - RW */
-#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
-#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
-#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
-#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
-#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
-#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
-#define E1000_HOST_IF 0x08800 /* Host Interface */
-#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
-#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
-
-#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
-#define E1000_MDPHYA 0x0003C /* PHY address - RW */
-#define E1000_MANC2H 0x05860 /* Managment Control To Host - RW */
-#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
-
-#define E1000_GCR 0x05B00 /* PCI-Ex Control */
-#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
-#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
-#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
-#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
-#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
-#define E1000_SWSM 0x05B50 /* SW Semaphore */
-#define E1000_FWSM 0x05B54 /* FW Semaphore */
-#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
-#define E1000_HICR 0x08F00 /* Host Inteface Control */
-
-/* RSS registers */
-#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
-#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
-#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
-#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
-#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
-#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
-/* Register Set (82542)
- *
- * Some of the 82542 registers are located at different offsets than they are
- * in more current versions of the 8254x. Despite the difference in location,
- * the registers function in the same manner.
- */
-#define E1000_82542_CTRL E1000_CTRL
-#define E1000_82542_CTRL_DUP E1000_CTRL_DUP
-#define E1000_82542_STATUS E1000_STATUS
-#define E1000_82542_EECD E1000_EECD
-#define E1000_82542_EERD E1000_EERD
-#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
-#define E1000_82542_FLA E1000_FLA
-#define E1000_82542_MDIC E1000_MDIC
-#define E1000_82542_SCTL E1000_SCTL
-#define E1000_82542_FEXTNVM E1000_FEXTNVM
-#define E1000_82542_FCAL E1000_FCAL
-#define E1000_82542_FCAH E1000_FCAH
-#define E1000_82542_FCT E1000_FCT
-#define E1000_82542_VET E1000_VET
-#define E1000_82542_RA 0x00040
-#define E1000_82542_ICR E1000_ICR
-#define E1000_82542_ITR E1000_ITR
-#define E1000_82542_ICS E1000_ICS
-#define E1000_82542_IMS E1000_IMS
-#define E1000_82542_IMC E1000_IMC
-#define E1000_82542_RCTL E1000_RCTL
-#define E1000_82542_RDTR 0x00108
-#define E1000_82542_RDBAL 0x00110
-#define E1000_82542_RDBAH 0x00114
-#define E1000_82542_RDLEN 0x00118
-#define E1000_82542_RDH 0x00120
-#define E1000_82542_RDT 0x00128
-#define E1000_82542_RDTR0 E1000_82542_RDTR
-#define E1000_82542_RDBAL0 E1000_82542_RDBAL
-#define E1000_82542_RDBAH0 E1000_82542_RDBAH
-#define E1000_82542_RDLEN0 E1000_82542_RDLEN
-#define E1000_82542_RDH0 E1000_82542_RDH
-#define E1000_82542_RDT0 E1000_82542_RDT
-#define E1000_82542_SRRCTL(_n) (0x280C + ((_n) << 8)) /* Split and Replication
- * RX Control - RW */
-#define E1000_82542_DCA_RXCTRL(_n) (0x02814 + ((_n) << 8))
-#define E1000_82542_RDBAH3 0x02B04 /* RX Desc Base High Queue 3 - RW */
-#define E1000_82542_RDBAL3 0x02B00 /* RX Desc Low Queue 3 - RW */
-#define E1000_82542_RDLEN3 0x02B08 /* RX Desc Length Queue 3 - RW */
-#define E1000_82542_RDH3 0x02B10 /* RX Desc Head Queue 3 - RW */
-#define E1000_82542_RDT3 0x02B18 /* RX Desc Tail Queue 3 - RW */
-#define E1000_82542_RDBAL2 0x02A00 /* RX Desc Base Low Queue 2 - RW */
-#define E1000_82542_RDBAH2 0x02A04 /* RX Desc Base High Queue 2 - RW */
-#define E1000_82542_RDLEN2 0x02A08 /* RX Desc Length Queue 2 - RW */
-#define E1000_82542_RDH2 0x02A10 /* RX Desc Head Queue 2 - RW */
-#define E1000_82542_RDT2 0x02A18 /* RX Desc Tail Queue 2 - RW */
-#define E1000_82542_RDTR1 0x00130
-#define E1000_82542_RDBAL1 0x00138
-#define E1000_82542_RDBAH1 0x0013C
-#define E1000_82542_RDLEN1 0x00140
-#define E1000_82542_RDH1 0x00148
-#define E1000_82542_RDT1 0x00150
-#define E1000_82542_FCRTH 0x00160
-#define E1000_82542_FCRTL 0x00168
-#define E1000_82542_FCTTV E1000_FCTTV
-#define E1000_82542_TXCW E1000_TXCW
-#define E1000_82542_RXCW E1000_RXCW
-#define E1000_82542_MTA 0x00200
-#define E1000_82542_TCTL E1000_TCTL
-#define E1000_82542_TCTL_EXT E1000_TCTL_EXT
-#define E1000_82542_TIPG E1000_TIPG
-#define E1000_82542_TDBAL 0x00420
-#define E1000_82542_TDBAH 0x00424
-#define E1000_82542_TDLEN 0x00428
-#define E1000_82542_TDH 0x00430
-#define E1000_82542_TDT 0x00438
-#define E1000_82542_TIDV 0x00440
-#define E1000_82542_TBT E1000_TBT
-#define E1000_82542_AIT E1000_AIT
-#define E1000_82542_VFTA 0x00600
-#define E1000_82542_LEDCTL E1000_LEDCTL
-#define E1000_82542_PBA E1000_PBA
-#define E1000_82542_PBS E1000_PBS
-#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
-#define E1000_82542_EEARBC E1000_EEARBC
-#define E1000_82542_FLASHT E1000_FLASHT
-#define E1000_82542_EEWR E1000_EEWR
-#define E1000_82542_FLSWCTL E1000_FLSWCTL
-#define E1000_82542_FLSWDATA E1000_FLSWDATA
-#define E1000_82542_FLSWCNT E1000_FLSWCNT
-#define E1000_82542_FLOP E1000_FLOP
-#define E1000_82542_EXTCNF_CTRL E1000_EXTCNF_CTRL
-#define E1000_82542_EXTCNF_SIZE E1000_EXTCNF_SIZE
-#define E1000_82542_PHY_CTRL E1000_PHY_CTRL
-#define E1000_82542_ERT E1000_ERT
-#define E1000_82542_RXDCTL E1000_RXDCTL
-#define E1000_82542_RXDCTL1 E1000_RXDCTL1
-#define E1000_82542_RADV E1000_RADV
-#define E1000_82542_RSRPD E1000_RSRPD
-#define E1000_82542_TXDMAC E1000_TXDMAC
-#define E1000_82542_KABGTXD E1000_KABGTXD
-#define E1000_82542_TDFHS E1000_TDFHS
-#define E1000_82542_TDFTS E1000_TDFTS
-#define E1000_82542_TDFPC E1000_TDFPC
-#define E1000_82542_TXDCTL E1000_TXDCTL
-#define E1000_82542_TADV E1000_TADV
-#define E1000_82542_TSPMT E1000_TSPMT
-#define E1000_82542_CRCERRS E1000_CRCERRS
-#define E1000_82542_ALGNERRC E1000_ALGNERRC
-#define E1000_82542_SYMERRS E1000_SYMERRS
-#define E1000_82542_RXERRC E1000_RXERRC
-#define E1000_82542_MPC E1000_MPC
-#define E1000_82542_SCC E1000_SCC
-#define E1000_82542_ECOL E1000_ECOL
-#define E1000_82542_MCC E1000_MCC
-#define E1000_82542_LATECOL E1000_LATECOL
-#define E1000_82542_COLC E1000_COLC
-#define E1000_82542_DC E1000_DC
-#define E1000_82542_TNCRS E1000_TNCRS
-#define E1000_82542_SEC E1000_SEC
-#define E1000_82542_CEXTERR E1000_CEXTERR
-#define E1000_82542_RLEC E1000_RLEC
-#define E1000_82542_XONRXC E1000_XONRXC
-#define E1000_82542_XONTXC E1000_XONTXC
-#define E1000_82542_XOFFRXC E1000_XOFFRXC
-#define E1000_82542_XOFFTXC E1000_XOFFTXC
-#define E1000_82542_FCRUC E1000_FCRUC
-#define E1000_82542_PRC64 E1000_PRC64
-#define E1000_82542_PRC127 E1000_PRC127
-#define E1000_82542_PRC255 E1000_PRC255
-#define E1000_82542_PRC511 E1000_PRC511
-#define E1000_82542_PRC1023 E1000_PRC1023
-#define E1000_82542_PRC1522 E1000_PRC1522
-#define E1000_82542_GPRC E1000_GPRC
-#define E1000_82542_BPRC E1000_BPRC
-#define E1000_82542_MPRC E1000_MPRC
-#define E1000_82542_GPTC E1000_GPTC
-#define E1000_82542_GORCL E1000_GORCL
-#define E1000_82542_GORCH E1000_GORCH
-#define E1000_82542_GOTCL E1000_GOTCL
-#define E1000_82542_GOTCH E1000_GOTCH
-#define E1000_82542_RNBC E1000_RNBC
-#define E1000_82542_RUC E1000_RUC
-#define E1000_82542_RFC E1000_RFC
-#define E1000_82542_ROC E1000_ROC
-#define E1000_82542_RJC E1000_RJC
-#define E1000_82542_MGTPRC E1000_MGTPRC
-#define E1000_82542_MGTPDC E1000_MGTPDC
-#define E1000_82542_MGTPTC E1000_MGTPTC
-#define E1000_82542_TORL E1000_TORL
-#define E1000_82542_TORH E1000_TORH
-#define E1000_82542_TOTL E1000_TOTL
-#define E1000_82542_TOTH E1000_TOTH
-#define E1000_82542_TPR E1000_TPR
-#define E1000_82542_TPT E1000_TPT
-#define E1000_82542_PTC64 E1000_PTC64
-#define E1000_82542_PTC127 E1000_PTC127
-#define E1000_82542_PTC255 E1000_PTC255
-#define E1000_82542_PTC511 E1000_PTC511
-#define E1000_82542_PTC1023 E1000_PTC1023
-#define E1000_82542_PTC1522 E1000_PTC1522
-#define E1000_82542_MPTC E1000_MPTC
-#define E1000_82542_BPTC E1000_BPTC
-#define E1000_82542_TSCTC E1000_TSCTC
-#define E1000_82542_TSCTFC E1000_TSCTFC
-#define E1000_82542_RXCSUM E1000_RXCSUM
-#define E1000_82542_WUC E1000_WUC
-#define E1000_82542_WUFC E1000_WUFC
-#define E1000_82542_WUS E1000_WUS
-#define E1000_82542_MANC E1000_MANC
-#define E1000_82542_IPAV E1000_IPAV
-#define E1000_82542_IP4AT E1000_IP4AT
-#define E1000_82542_IP6AT E1000_IP6AT
-#define E1000_82542_WUPL E1000_WUPL
-#define E1000_82542_WUPM E1000_WUPM
-#define E1000_82542_FFLT E1000_FFLT
-#define E1000_82542_TDFH 0x08010
-#define E1000_82542_TDFT 0x08018
-#define E1000_82542_FFMT E1000_FFMT
-#define E1000_82542_FFVT E1000_FFVT
-#define E1000_82542_HOST_IF E1000_HOST_IF
-#define E1000_82542_IAM E1000_IAM
-#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
-#define E1000_82542_PSRCTL E1000_PSRCTL
-#define E1000_82542_RAID E1000_RAID
-#define E1000_82542_TARC0 E1000_TARC0
-#define E1000_82542_TDBAL1 E1000_TDBAL1
-#define E1000_82542_TDBAH1 E1000_TDBAH1
-#define E1000_82542_TDLEN1 E1000_TDLEN1
-#define E1000_82542_TDH1 E1000_TDH1
-#define E1000_82542_TDT1 E1000_TDT1
-#define E1000_82542_TXDCTL1 E1000_TXDCTL1
-#define E1000_82542_TARC1 E1000_TARC1
-#define E1000_82542_RFCTL E1000_RFCTL
-#define E1000_82542_GCR E1000_GCR
-#define E1000_82542_GSCL_1 E1000_GSCL_1
-#define E1000_82542_GSCL_2 E1000_GSCL_2
-#define E1000_82542_GSCL_3 E1000_GSCL_3
-#define E1000_82542_GSCL_4 E1000_GSCL_4
-#define E1000_82542_FACTPS E1000_FACTPS
-#define E1000_82542_SWSM E1000_SWSM
-#define E1000_82542_FWSM E1000_FWSM
-#define E1000_82542_FFLT_DBG E1000_FFLT_DBG
-#define E1000_82542_IAC E1000_IAC
-#define E1000_82542_ICRXPTC E1000_ICRXPTC
-#define E1000_82542_ICRXATC E1000_ICRXATC
-#define E1000_82542_ICTXPTC E1000_ICTXPTC
-#define E1000_82542_ICTXATC E1000_ICTXATC
-#define E1000_82542_ICTXQEC E1000_ICTXQEC
-#define E1000_82542_ICTXQMTC E1000_ICTXQMTC
-#define E1000_82542_ICRXDMTC E1000_ICRXDMTC
-#define E1000_82542_ICRXOC E1000_ICRXOC
-#define E1000_82542_HICR E1000_HICR
-
-#define E1000_82542_CPUVEC E1000_CPUVEC
-#define E1000_82542_MRQC E1000_MRQC
-#define E1000_82542_RETA E1000_RETA
-#define E1000_82542_RSSRK E1000_RSSRK
-#define E1000_82542_RSSIM E1000_RSSIM
-#define E1000_82542_RSSIR E1000_RSSIR
-#define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA
-#define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC
-#define E1000_82542_MANC2H E1000_MANC2H
-
-/* Statistics counters collected by the MAC */
-struct e1000_hw_stats {
- u64 crcerrs;
- u64 algnerrc;
- u64 symerrs;
- u64 rxerrc;
- u64 txerrc;
- u64 mpc;
- u64 scc;
- u64 ecol;
- u64 mcc;
- u64 latecol;
- u64 colc;
- u64 dc;
- u64 tncrs;
- u64 sec;
- u64 cexterr;
- u64 rlec;
- u64 xonrxc;
- u64 xontxc;
- u64 xoffrxc;
- u64 xofftxc;
- u64 fcruc;
- u64 prc64;
- u64 prc127;
- u64 prc255;
- u64 prc511;
- u64 prc1023;
- u64 prc1522;
- u64 gprc;
- u64 bprc;
- u64 mprc;
- u64 gptc;
- u64 gorcl;
- u64 gorch;
- u64 gotcl;
- u64 gotch;
- u64 rnbc;
- u64 ruc;
- u64 rfc;
- u64 roc;
- u64 rlerrc;
- u64 rjc;
- u64 mgprc;
- u64 mgpdc;
- u64 mgptc;
- u64 torl;
- u64 torh;
- u64 totl;
- u64 toth;
- u64 tpr;
- u64 tpt;
- u64 ptc64;
- u64 ptc127;
- u64 ptc255;
- u64 ptc511;
- u64 ptc1023;
- u64 ptc1522;
- u64 mptc;
- u64 bptc;
- u64 tsctc;
- u64 tsctfc;
- u64 iac;
- u64 icrxptc;
- u64 icrxatc;
- u64 ictxptc;
- u64 ictxatc;
- u64 ictxqec;
- u64 ictxqmtc;
- u64 icrxdmtc;
- u64 icrxoc;
-};
-
-/* Structure containing variables used by the shared code (e1000_hw.c) */
-struct e1000_hw {
- u8 __iomem *hw_addr;
- u8 __iomem *flash_address;
- e1000_mac_type mac_type;
- e1000_phy_type phy_type;
- u32 phy_init_script;
- e1000_media_type media_type;
- void *back;
- struct e1000_shadow_ram *eeprom_shadow_ram;
- u32 flash_bank_size;
- u32 flash_base_addr;
- e1000_fc_type fc;
- e1000_bus_speed bus_speed;
- e1000_bus_width bus_width;
- e1000_bus_type bus_type;
- struct e1000_eeprom_info eeprom;
- e1000_ms_type master_slave;
- e1000_ms_type original_master_slave;
- e1000_ffe_config ffe_config_state;
- u32 asf_firmware_present;
- u32 eeprom_semaphore_present;
- u32 swfw_sync_present;
- u32 swfwhw_semaphore_present;
- unsigned long io_base;
- u32 phy_id;
- u32 phy_revision;
- u32 phy_addr;
- u32 original_fc;
- u32 txcw;
- u32 autoneg_failed;
- u32 max_frame_size;
- u32 min_frame_size;
- u32 mc_filter_type;
- u32 num_mc_addrs;
- u32 collision_delta;
- u32 tx_packet_delta;
- u32 ledctl_default;
- u32 ledctl_mode1;
- u32 ledctl_mode2;
- bool tx_pkt_filtering;
- struct e1000_host_mng_dhcp_cookie mng_cookie;
- u16 phy_spd_default;
- u16 autoneg_advertised;
- u16 pci_cmd_word;
- u16 fc_high_water;
- u16 fc_low_water;
- u16 fc_pause_time;
- u16 current_ifs_val;
- u16 ifs_min_val;
- u16 ifs_max_val;
- u16 ifs_step_size;
- u16 ifs_ratio;
- u16 device_id;
- u16 vendor_id;
- u16 subsystem_id;
- u16 subsystem_vendor_id;
- u8 revision_id;
- u8 autoneg;
- u8 mdix;
- u8 forced_speed_duplex;
- u8 wait_autoneg_complete;
- u8 dma_fairness;
- u8 mac_addr[NODE_ADDRESS_SIZE];
- u8 perm_mac_addr[NODE_ADDRESS_SIZE];
- bool disable_polarity_correction;
- bool speed_downgraded;
- e1000_smart_speed smart_speed;
- e1000_dsp_config dsp_config_state;
- bool get_link_status;
- bool serdes_link_down;
- bool tbi_compatibility_en;
- bool tbi_compatibility_on;
- bool laa_is_present;
- bool phy_reset_disable;
- bool initialize_hw_bits_disable;
- bool fc_send_xon;
- bool fc_strict_ieee;
- bool report_tx_early;
- bool adaptive_ifs;
- bool ifs_params_forced;
- bool in_ifs_mode;
- bool mng_reg_access_disabled;
- bool leave_av_bit_off;
- bool kmrn_lock_loss_workaround_disabled;
- bool bad_tx_carr_stats_fd;
- bool has_manc2h;
- bool rx_needs_kicking;
- bool has_smbus;
-};
-
-
-#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
-#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
-#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */
-#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
-#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */
-#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
-#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */
-#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */
-/* Register Bit Masks */
-/* Device Control */
-#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
-#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
-#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
-#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
-#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
-#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
-#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
-#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
-#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
-#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
-#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
-#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
-#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
-#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
-#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
-#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
-#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
-#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
-#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
-#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */
-#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
-#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
-#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
-#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
-#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
-#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */
-#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
-#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
-#define E1000_CTRL_RST 0x04000000 /* Global reset */
-#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
-#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
-#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
-#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
-#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
-#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manageability engine */
-
-/* Device Status */
-#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
-#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
-#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
-#define E1000_STATUS_FUNC_SHIFT 2
-#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
-#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
-#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
-#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */
-#define E1000_STATUS_SPEED_MASK 0x000000C0
-#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
-#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
-#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
-#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion
- by EEPROM/Flash */
-#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
-#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */
-#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
-#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
-#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
-#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
-#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
-#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */
-#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disabled */
-#define E1000_STATUS_BMC_SKU_1 0x00200000 /* BMC SRAM disabled */
-#define E1000_STATUS_BMC_SKU_2 0x00400000 /* BMC SDRAM disabled */
-#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */
-#define E1000_STATUS_BMC_LITE 0x01000000 /* BMC external code execution disabled */
-#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */
-#define E1000_STATUS_FUSE_8 0x04000000
-#define E1000_STATUS_FUSE_9 0x08000000
-#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */
-#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */
-
-/* Constants used to intrepret the masked PCI-X bus speed. */
-#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
-#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
-#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
-
-/* EEPROM/Flash Control */
-#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */
-#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
-#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
-#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
-#define E1000_EECD_FWE_MASK 0x00000030
-#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
-#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
-#define E1000_EECD_FWE_SHIFT 4
-#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
-#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
-#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
-#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
-#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
- * (0-small, 1-large) */
-#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
-#ifndef E1000_EEPROM_GRANT_ATTEMPTS
-#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
-#endif
-#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
-#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
-#define E1000_EECD_SIZE_EX_SHIFT 11
-#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */
-#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
-#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
-#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
-#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
-#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
-#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
-#define E1000_EECD_SECVAL_SHIFT 22
-#define E1000_STM_OPCODE 0xDB00
-#define E1000_HICR_FW_RESET 0xC0
-
-#define E1000_SHADOW_RAM_WORDS 2048
-#define E1000_ICH_NVM_SIG_WORD 0x13
-#define E1000_ICH_NVM_SIG_MASK 0xC0
-
-/* EEPROM Read */
-#define E1000_EERD_START 0x00000001 /* Start Read */
-#define E1000_EERD_DONE 0x00000010 /* Read Done */
-#define E1000_EERD_ADDR_SHIFT 8
-#define E1000_EERD_ADDR_MASK 0x0000FF00 /* Read Address */
-#define E1000_EERD_DATA_SHIFT 16
-#define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */
-
-/* SPI EEPROM Status Register */
-#define EEPROM_STATUS_RDY_SPI 0x01
-#define EEPROM_STATUS_WEN_SPI 0x02
-#define EEPROM_STATUS_BP0_SPI 0x04
-#define EEPROM_STATUS_BP1_SPI 0x08
-#define EEPROM_STATUS_WPEN_SPI 0x80
-
-/* Extended Device Control */
-#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */
-#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
-#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
-#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */
-#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
-#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
-#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA
-#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
-#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
-#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */
-#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */
-#define E1000_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */
-#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */
-#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
-#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */
-#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
-#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
-#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
-#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
-#define E1000_CTRL_EXT_LINK_MODE_SERDES 0x00C00000
-#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
-#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000
-#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000
-#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
-#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
-#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
-#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
-#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
-#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
-#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error detection enabled */
-#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity error detection enable */
-#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000
-
-/* MDI Control */
-#define E1000_MDIC_DATA_MASK 0x0000FFFF
-#define E1000_MDIC_REG_MASK 0x001F0000
-#define E1000_MDIC_REG_SHIFT 16
-#define E1000_MDIC_PHY_MASK 0x03E00000
-#define E1000_MDIC_PHY_SHIFT 21
-#define E1000_MDIC_OP_WRITE 0x04000000
-#define E1000_MDIC_OP_READ 0x08000000
-#define E1000_MDIC_READY 0x10000000
-#define E1000_MDIC_INT_EN 0x20000000
-#define E1000_MDIC_ERROR 0x40000000
-
-#define E1000_KUMCTRLSTA_MASK 0x0000FFFF
-#define E1000_KUMCTRLSTA_OFFSET 0x001F0000
-#define E1000_KUMCTRLSTA_OFFSET_SHIFT 16
-#define E1000_KUMCTRLSTA_REN 0x00200000
-
-#define E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL 0x00000000
-#define E1000_KUMCTRLSTA_OFFSET_CTRL 0x00000001
-#define E1000_KUMCTRLSTA_OFFSET_INB_CTRL 0x00000002
-#define E1000_KUMCTRLSTA_OFFSET_DIAG 0x00000003
-#define E1000_KUMCTRLSTA_OFFSET_TIMEOUTS 0x00000004
-#define E1000_KUMCTRLSTA_OFFSET_INB_PARAM 0x00000009
-#define E1000_KUMCTRLSTA_OFFSET_HD_CTRL 0x00000010
-#define E1000_KUMCTRLSTA_OFFSET_M2P_SERDES 0x0000001E
-#define E1000_KUMCTRLSTA_OFFSET_M2P_MODES 0x0000001F
-
-/* FIFO Control */
-#define E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS 0x00000008
-#define E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS 0x00000800
-
-/* In-Band Control */
-#define E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT 0x00000500
-#define E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING 0x00000010
-
-/* Half-Duplex Control */
-#define E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004
-#define E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT 0x00000000
-
-#define E1000_KUMCTRLSTA_OFFSET_K0S_CTRL 0x0000001E
-
-#define E1000_KUMCTRLSTA_DIAG_FELPBK 0x2000
-#define E1000_KUMCTRLSTA_DIAG_NELPBK 0x1000
-
-#define E1000_KUMCTRLSTA_K0S_100_EN 0x2000
-#define E1000_KUMCTRLSTA_K0S_GBE_EN 0x1000
-#define E1000_KUMCTRLSTA_K0S_ENTRY_LATENCY_MASK 0x0003
-
-#define E1000_KABGTXD_BGSQLBIAS 0x00050000
-
-#define E1000_PHY_CTRL_SPD_EN 0x00000001
-#define E1000_PHY_CTRL_D0A_LPLU 0x00000002
-#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004
-#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008
-#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
-#define E1000_PHY_CTRL_B2B_EN 0x00000080
-
-/* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
-#define E1000_LEDCTL_LED0_MODE_SHIFT 0
-#define E1000_LEDCTL_LED0_BLINK_RATE 0x0000020
-#define E1000_LEDCTL_LED0_IVRT 0x00000040
-#define E1000_LEDCTL_LED0_BLINK 0x00000080
-#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
-#define E1000_LEDCTL_LED1_MODE_SHIFT 8
-#define E1000_LEDCTL_LED1_BLINK_RATE 0x0002000
-#define E1000_LEDCTL_LED1_IVRT 0x00004000
-#define E1000_LEDCTL_LED1_BLINK 0x00008000
-#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
-#define E1000_LEDCTL_LED2_MODE_SHIFT 16
-#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000
-#define E1000_LEDCTL_LED2_IVRT 0x00400000
-#define E1000_LEDCTL_LED2_BLINK 0x00800000
-#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
-#define E1000_LEDCTL_LED3_MODE_SHIFT 24
-#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000
-#define E1000_LEDCTL_LED3_IVRT 0x40000000
-#define E1000_LEDCTL_LED3_BLINK 0x80000000
-
-#define E1000_LEDCTL_MODE_LINK_10_1000 0x0
-#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
-#define E1000_LEDCTL_MODE_LINK_UP 0x2
-#define E1000_LEDCTL_MODE_ACTIVITY 0x3
-#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
-#define E1000_LEDCTL_MODE_LINK_10 0x5
-#define E1000_LEDCTL_MODE_LINK_100 0x6
-#define E1000_LEDCTL_MODE_LINK_1000 0x7
-#define E1000_LEDCTL_MODE_PCIX_MODE 0x8
-#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9
-#define E1000_LEDCTL_MODE_COLLISION 0xA
-#define E1000_LEDCTL_MODE_BUS_SPEED 0xB
-#define E1000_LEDCTL_MODE_BUS_SIZE 0xC
-#define E1000_LEDCTL_MODE_PAUSED 0xD
-#define E1000_LEDCTL_MODE_LED_ON 0xE
-#define E1000_LEDCTL_MODE_LED_OFF 0xF
-
-/* Receive Address */
-#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
-
-/* Interrupt Cause Read */
-#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
-#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
-#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
-#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO 0x00000040 /* rx overrun */
-#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
-#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_SRPD 0x00010000
-#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
-#define E1000_ICR_MNG 0x00040000 /* Manageability event */
-#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
-#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
-#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity error */
-#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
-#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
-#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */
-#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */
-#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
-
-/* Interrupt Cause Set */
-#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_ICS_SRPD E1000_ICR_SRPD
-#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICS_DSW E1000_ICR_DSW
-#define E1000_ICS_PHYINT E1000_ICR_PHYINT
-#define E1000_ICS_EPRST E1000_ICR_EPRST
-
-/* Interrupt Mask Set */
-#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMS_SRPD E1000_ICR_SRPD
-#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_IMS_DSW E1000_ICR_DSW
-#define E1000_IMS_PHYINT E1000_ICR_PHYINT
-#define E1000_IMS_EPRST E1000_ICR_EPRST
-
-/* Interrupt Mask Clear */
-#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
-#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
-#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
-#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
-#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
-#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
-#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
-#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMC_SRPD E1000_ICR_SRPD
-#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */
-#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */
-#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */
-#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-#define E1000_IMC_DSW E1000_ICR_DSW
-#define E1000_IMC_PHYINT E1000_ICR_PHYINT
-#define E1000_IMC_EPRST E1000_ICR_EPRST
-
-/* Receive Control */
-#define E1000_RCTL_RST 0x00000001 /* Software reset */
-#define E1000_RCTL_EN 0x00000002 /* enable */
-#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
-#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
-#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
-#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
-#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
-#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
-#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
-#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
-#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
-#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
-#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
-#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
-#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
-#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
-#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
-#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
-#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
-#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
-#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
-#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
-#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
-#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
-#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
-#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
-#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
-#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
-#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
-#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
-#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
-#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
-#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */
-#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */
-
-/* Use byte values for the following shift parameters
- * Usage:
- * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
- * E1000_PSRCTL_BSIZE0_MASK) |
- * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
- * E1000_PSRCTL_BSIZE1_MASK) |
- * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
- * E1000_PSRCTL_BSIZE2_MASK) |
- * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
- * E1000_PSRCTL_BSIZE3_MASK))
- * where value0 = [128..16256], default=256
- * value1 = [1024..64512], default=4096
- * value2 = [0..64512], default=4096
- * value3 = [0..64512], default=0
- */
-
-#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
-#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
-#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
-#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
-
-#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
-#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
-#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
-#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
-
-/* SW_W_SYNC definitions */
-#define E1000_SWFW_EEP_SM 0x0001
-#define E1000_SWFW_PHY0_SM 0x0002
-#define E1000_SWFW_PHY1_SM 0x0004
-#define E1000_SWFW_MAC_CSR_SM 0x0008
-
-/* Receive Descriptor */
-#define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */
-#define E1000_RDT_FPDB 0x80000000 /* Flush descriptor block */
-#define E1000_RDLEN_LEN 0x0007ff80 /* descriptor length */
-#define E1000_RDH_RDH 0x0000ffff /* receive descriptor head */
-#define E1000_RDT_RDT 0x0000ffff /* receive descriptor tail */
-
-/* Flow Control */
-#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
-#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */
-#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
-#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
-
-/* Header split receive */
-#define E1000_RFCTL_ISCSI_DIS 0x00000001
-#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E
-#define E1000_RFCTL_ISCSI_DWC_SHIFT 1
-#define E1000_RFCTL_NFSW_DIS 0x00000040
-#define E1000_RFCTL_NFSR_DIS 0x00000080
-#define E1000_RFCTL_NFS_VER_MASK 0x00000300
-#define E1000_RFCTL_NFS_VER_SHIFT 8
-#define E1000_RFCTL_IPV6_DIS 0x00000400
-#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800
-#define E1000_RFCTL_ACK_DIS 0x00001000
-#define E1000_RFCTL_ACKD_DIS 0x00002000
-#define E1000_RFCTL_IPFRSP_DIS 0x00004000
-#define E1000_RFCTL_EXTEN 0x00008000
-#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
-#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
-
-/* Receive Descriptor Control */
-#define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
-#define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
-#define E1000_RXDCTL_WTHRESH 0x003F0000 /* RXDCTL Writeback Threshold */
-#define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */
-
-/* Transmit Descriptor Control */
-#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
-#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */
-#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
-#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
-#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
-#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
-#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
- still to be processed. */
-/* Transmit Configuration Word */
-#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
-#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */
-#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */
-#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */
-#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */
-#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */
-#define E1000_TXCW_NP 0x00008000 /* TXCW next page */
-#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */
-#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */
-#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
-
-/* Receive Configuration Word */
-#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
-#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */
-#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
-#define E1000_RXCW_CC 0x10000000 /* Receive config change */
-#define E1000_RXCW_C 0x20000000 /* Receive config */
-#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
-#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */
-
-/* Transmit Control */
-#define E1000_TCTL_RST 0x00000001 /* software reset */
-#define E1000_TCTL_EN 0x00000002 /* enable tx */
-#define E1000_TCTL_BCE 0x00000004 /* busy check enable */
-#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
-#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
-#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
-#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
-#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
-#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
-#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
-#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
-/* Extended Transmit Control */
-#define E1000_TCTL_EXT_BST_MASK 0x000003FF /* Backoff Slot Time */
-#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
-
-#define DEFAULT_80003ES2LAN_TCTL_EXT_GCEX 0x00010000
-
-/* Receive Checksum Control */
-#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */
-#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
-#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
-#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */
-#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
-#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
-
-/* Multiple Receive Queue Control */
-#define E1000_MRQC_ENABLE_MASK 0x00000003
-#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001
-#define E1000_MRQC_ENABLE_RSS_INT 0x00000004
-#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
-#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
-#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
-#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
-#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000
-#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
-#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
-
-/* Definitions for power management and wakeup registers */
-/* Wake Up Control */
-#define E1000_WUC_APME 0x00000001 /* APM Enable */
-#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
-#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
-#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
-#define E1000_WUC_SPM 0x80000000 /* Enable SPM */
-
-/* Wake Up Filter Control */
-#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
-#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
-#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
-#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
-#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
-#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
-#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
-#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
-#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
-#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
-#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
-#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
-#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
-#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
-#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
-
-/* Wake Up Status */
-#define E1000_WUS_LNKC 0x00000001 /* Link Status Changed */
-#define E1000_WUS_MAG 0x00000002 /* Magic Packet Received */
-#define E1000_WUS_EX 0x00000004 /* Directed Exact Received */
-#define E1000_WUS_MC 0x00000008 /* Directed Multicast Received */
-#define E1000_WUS_BC 0x00000010 /* Broadcast Received */
-#define E1000_WUS_ARP 0x00000020 /* ARP Request Packet Received */
-#define E1000_WUS_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Received */
-#define E1000_WUS_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Received */
-#define E1000_WUS_FLX0 0x00010000 /* Flexible Filter 0 Match */
-#define E1000_WUS_FLX1 0x00020000 /* Flexible Filter 1 Match */
-#define E1000_WUS_FLX2 0x00040000 /* Flexible Filter 2 Match */
-#define E1000_WUS_FLX3 0x00080000 /* Flexible Filter 3 Match */
-#define E1000_WUS_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
-
-/* Management Control */
-#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
-#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
-#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */
-#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */
-#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */
-#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */
-#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */
-#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */
-#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
-#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
- * Filtering */
-#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */
-#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
-#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
-#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
-#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */
-#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
-#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address
- * filtering */
-#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host
- * memory */
-#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address
- * filtering */
-#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
-#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
-#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
-#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
-#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
-#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */
-#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
-#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
-
-#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
-#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
-
-/* SW Semaphore Register */
-#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
-#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
-#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */
-#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
-
-/* FW Semaphore Register */
-#define E1000_FWSM_MODE_MASK 0x0000000E /* FW mode */
-#define E1000_FWSM_MODE_SHIFT 1
-#define E1000_FWSM_FW_VALID 0x00008000 /* FW established a valid mode */
-
-#define E1000_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI reset */
-#define E1000_FWSM_DISSW 0x10000000 /* FW disable SW Write Access */
-#define E1000_FWSM_SKUSEL_MASK 0x60000000 /* LAN SKU select */
-#define E1000_FWSM_SKUEL_SHIFT 29
-#define E1000_FWSM_SKUSEL_EMB 0x0 /* Embedded SKU */
-#define E1000_FWSM_SKUSEL_CONS 0x1 /* Consumer SKU */
-#define E1000_FWSM_SKUSEL_PERF_100 0x2 /* Perf & Corp 10/100 SKU */
-#define E1000_FWSM_SKUSEL_PERF_GBE 0x3 /* Perf & Copr GbE SKU */
-
-/* FFLT Debug Register */
-#define E1000_FFLT_DBG_INVC 0x00100000 /* Invalid /C/ code handling */
-
-typedef enum {
- e1000_mng_mode_none = 0,
- e1000_mng_mode_asf,
- e1000_mng_mode_pt,
- e1000_mng_mode_ipmi,
- e1000_mng_mode_host_interface_only
-} e1000_mng_mode;
-
-/* Host Inteface Control Register */
-#define E1000_HICR_EN 0x00000001 /* Enable Bit - RO */
-#define E1000_HICR_C 0x00000002 /* Driver sets this bit when done
- * to put command in RAM */
-#define E1000_HICR_SV 0x00000004 /* Status Validity */
-#define E1000_HICR_FWR 0x00000080 /* FW reset. Set by the Host */
-
-/* Host Interface Command Interface - Address range 0x8800-0x8EFF */
-#define E1000_HI_MAX_DATA_LENGTH 252 /* Host Interface data length */
-#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */
-#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */
-#define E1000_HI_COMMAND_TIMEOUT 500 /* Time in ms to process HI command */
-
-struct e1000_host_command_header {
- u8 command_id;
- u8 command_length;
- u8 command_options; /* I/F bits for command, status for return */
- u8 checksum;
-};
-struct e1000_host_command_info {
- struct e1000_host_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
- u8 command_data[E1000_HI_MAX_DATA_LENGTH]; /* Command data can length 0..252 */
-};
-
-/* Host SMB register #0 */
-#define E1000_HSMC0R_CLKIN 0x00000001 /* SMB Clock in */
-#define E1000_HSMC0R_DATAIN 0x00000002 /* SMB Data in */
-#define E1000_HSMC0R_DATAOUT 0x00000004 /* SMB Data out */
-#define E1000_HSMC0R_CLKOUT 0x00000008 /* SMB Clock out */
-
-/* Host SMB register #1 */
-#define E1000_HSMC1R_CLKIN E1000_HSMC0R_CLKIN
-#define E1000_HSMC1R_DATAIN E1000_HSMC0R_DATAIN
-#define E1000_HSMC1R_DATAOUT E1000_HSMC0R_DATAOUT
-#define E1000_HSMC1R_CLKOUT E1000_HSMC0R_CLKOUT
-
-/* FW Status Register */
-#define E1000_FWSTS_FWS_MASK 0x000000FF /* FW Status */
-
-/* Wake Up Packet Length */
-#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */
-
-#define E1000_MDALIGN 4096
-
-/* PCI-Ex registers*/
-
-/* PCI-Ex Control Register */
-#define E1000_GCR_RXD_NO_SNOOP 0x00000001
-#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
-#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
-#define E1000_GCR_TXD_NO_SNOOP 0x00000008
-#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
-#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
-
-#define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
- E1000_GCR_RXDSCW_NO_SNOOP | \
- E1000_GCR_RXDSCR_NO_SNOOP | \
- E1000_GCR_TXD_NO_SNOOP | \
- E1000_GCR_TXDSCW_NO_SNOOP | \
- E1000_GCR_TXDSCR_NO_SNOOP)
-
-#define PCI_EX_82566_SNOOP_ALL PCI_EX_NO_SNOOP_ALL
-
-#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
-/* Function Active and Power State to MNG */
-#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
-#define E1000_FACTPS_LAN0_VALID 0x00000004
-#define E1000_FACTPS_FUNC0_AUX_EN 0x00000008
-#define E1000_FACTPS_FUNC1_POWER_STATE_MASK 0x000000C0
-#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT 6
-#define E1000_FACTPS_LAN1_VALID 0x00000100
-#define E1000_FACTPS_FUNC1_AUX_EN 0x00000200
-#define E1000_FACTPS_FUNC2_POWER_STATE_MASK 0x00003000
-#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT 12
-#define E1000_FACTPS_IDE_ENABLE 0x00004000
-#define E1000_FACTPS_FUNC2_AUX_EN 0x00008000
-#define E1000_FACTPS_FUNC3_POWER_STATE_MASK 0x000C0000
-#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT 18
-#define E1000_FACTPS_SP_ENABLE 0x00100000
-#define E1000_FACTPS_FUNC3_AUX_EN 0x00200000
-#define E1000_FACTPS_FUNC4_POWER_STATE_MASK 0x03000000
-#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT 24
-#define E1000_FACTPS_IPMI_ENABLE 0x04000000
-#define E1000_FACTPS_FUNC4_AUX_EN 0x08000000
-#define E1000_FACTPS_MNGCG 0x20000000
-#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000
-#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000
-
-/* PCI-Ex Config Space */
-#define PCI_EX_LINK_STATUS 0x12
-#define PCI_EX_LINK_WIDTH_MASK 0x3F0
-#define PCI_EX_LINK_WIDTH_SHIFT 4
-
-/* EEPROM Commands - Microwire */
-#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
-#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
-#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
-#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
-#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
-
-/* EEPROM Commands - SPI */
-#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
-#define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */
-#define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */
-#define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
-#define EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Enable latch */
-#define EEPROM_WRDI_OPCODE_SPI 0x04 /* EEPROM reset Write Enable latch */
-#define EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status register */
-#define EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status register */
-#define EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */
-#define EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */
-#define EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */
-
-/* EEPROM Size definitions */
-#define EEPROM_WORD_SIZE_SHIFT 6
-#define EEPROM_SIZE_SHIFT 10
-#define EEPROM_SIZE_MASK 0x1C00
-
-/* EEPROM Word Offsets */
-#define EEPROM_COMPAT 0x0003
-#define EEPROM_ID_LED_SETTINGS 0x0004
-#define EEPROM_VERSION 0x0005
-#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
-#define EEPROM_PHY_CLASS_WORD 0x0007
-#define EEPROM_INIT_CONTROL1_REG 0x000A
-#define EEPROM_INIT_CONTROL2_REG 0x000F
-#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
-#define EEPROM_INIT_CONTROL3_PORT_B 0x0014
-#define EEPROM_INIT_3GIO_3 0x001A
-#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
-#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
-#define EEPROM_CFG 0x0012
-#define EEPROM_FLASH_VERSION 0x0032
-#define EEPROM_CHECKSUM_REG 0x003F
-
-#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
-#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */
-
-/* Word definitions for ID LED Settings */
-#define ID_LED_RESERVED_0000 0x0000
-#define ID_LED_RESERVED_FFFF 0xFFFF
-#define ID_LED_RESERVED_82573 0xF746
-#define ID_LED_DEFAULT_82573 0x1811
-#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
- (ID_LED_OFF1_OFF2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_DEF1_DEF2))
-#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
- (ID_LED_DEF1_OFF2 << 8) | \
- (ID_LED_DEF1_ON2 << 4) | \
- (ID_LED_DEF1_DEF2))
-#define ID_LED_DEF1_DEF2 0x1
-#define ID_LED_DEF1_ON2 0x2
-#define ID_LED_DEF1_OFF2 0x3
-#define ID_LED_ON1_DEF2 0x4
-#define ID_LED_ON1_ON2 0x5
-#define ID_LED_ON1_OFF2 0x6
-#define ID_LED_OFF1_DEF2 0x7
-#define ID_LED_OFF1_ON2 0x8
-#define ID_LED_OFF1_OFF2 0x9
-
-#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
-#define IGP_ACTIVITY_LED_ENABLE 0x0300
-#define IGP_LED3_MODE 0x07000000
-
-
-/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
-#define EEPROM_SERDES_AMPLITUDE_MASK 0x000F
-
-/* Mask bit for PHY class in Word 7 of the EEPROM */
-#define EEPROM_PHY_CLASS_A 0x8000
-
-/* Mask bits for fields in Word 0x0a of the EEPROM */
-#define EEPROM_WORD0A_ILOS 0x0010
-#define EEPROM_WORD0A_SWDPIO 0x01E0
-#define EEPROM_WORD0A_LRST 0x0200
-#define EEPROM_WORD0A_FD 0x0400
-#define EEPROM_WORD0A_66MHZ 0x0800
-
-/* Mask bits for fields in Word 0x0f of the EEPROM */
-#define EEPROM_WORD0F_PAUSE_MASK 0x3000
-#define EEPROM_WORD0F_PAUSE 0x1000
-#define EEPROM_WORD0F_ASM_DIR 0x2000
-#define EEPROM_WORD0F_ANE 0x0800
-#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
-#define EEPROM_WORD0F_LPLU 0x0001
-
-/* Mask bits for fields in Word 0x10/0x20 of the EEPROM */
-#define EEPROM_WORD1020_GIGA_DISABLE 0x0010
-#define EEPROM_WORD1020_GIGA_DISABLE_NON_D0A 0x0008
-
-/* Mask bits for fields in Word 0x1a of the EEPROM */
-#define EEPROM_WORD1A_ASPM_MASK 0x000C
-
-/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
-#define EEPROM_SUM 0xBABA
-
-/* EEPROM Map defines (WORD OFFSETS)*/
-#define EEPROM_NODE_ADDRESS_BYTE_0 0
-#define EEPROM_PBA_BYTE_1 8
-
-#define EEPROM_RESERVED_WORD 0xFFFF
-
-/* EEPROM Map Sizes (Byte Counts) */
-#define PBA_SIZE 4
-
-/* Collision related configuration parameters */
-#define E1000_COLLISION_THRESHOLD 15
-#define E1000_CT_SHIFT 4
-/* Collision distance is a 0-based value that applies to
- * half-duplex-capable hardware only. */
-#define E1000_COLLISION_DISTANCE 63
-#define E1000_COLLISION_DISTANCE_82542 64
-#define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
-#define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
-#define E1000_COLD_SHIFT 12
-
-/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
-#define REQ_TX_DESCRIPTOR_MULTIPLE 8
-#define REQ_RX_DESCRIPTOR_MULTIPLE 8
-
-/* Default values for the transmit IPG register */
-#define DEFAULT_82542_TIPG_IPGT 10
-#define DEFAULT_82543_TIPG_IPGT_FIBER 9
-#define DEFAULT_82543_TIPG_IPGT_COPPER 8
-
-#define E1000_TIPG_IPGT_MASK 0x000003FF
-#define E1000_TIPG_IPGR1_MASK 0x000FFC00
-#define E1000_TIPG_IPGR2_MASK 0x3FF00000
-
-#define DEFAULT_82542_TIPG_IPGR1 2
-#define DEFAULT_82543_TIPG_IPGR1 8
-#define E1000_TIPG_IPGR1_SHIFT 10
-
-#define DEFAULT_82542_TIPG_IPGR2 10
-#define DEFAULT_82543_TIPG_IPGR2 6
-#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7
-#define E1000_TIPG_IPGR2_SHIFT 20
-
-#define DEFAULT_80003ES2LAN_TIPG_IPGT_10_100 0x00000009
-#define DEFAULT_80003ES2LAN_TIPG_IPGT_1000 0x00000008
-#define E1000_TXDMAC_DPP 0x00000001
-
-/* Adaptive IFS defines */
-#define TX_THRESHOLD_START 8
-#define TX_THRESHOLD_INCREMENT 10
-#define TX_THRESHOLD_DECREMENT 1
-#define TX_THRESHOLD_STOP 190
-#define TX_THRESHOLD_DISABLE 0
-#define TX_THRESHOLD_TIMER_MS 10000
-#define MIN_NUM_XMITS 1000
-#define IFS_MAX 80
-#define IFS_STEP 10
-#define IFS_MIN 40
-#define IFS_RATIO 4
-
-/* Extended Configuration Control and Size */
-#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001
-#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE 0x00000002
-#define E1000_EXTCNF_CTRL_D_UD_ENABLE 0x00000004
-#define E1000_EXTCNF_CTRL_D_UD_LATENCY 0x00000008
-#define E1000_EXTCNF_CTRL_D_UD_OWNER 0x00000010
-#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
-#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040
-#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER 0x0FFF0000
-
-#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH 0x000000FF
-#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH 0x0000FF00
-#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH 0x00FF0000
-#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
-#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
-
-/* PBA constants */
-#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */
-#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
-#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
-#define E1000_PBA_20K 0x0014
-#define E1000_PBA_22K 0x0016
-#define E1000_PBA_24K 0x0018
-#define E1000_PBA_30K 0x001E
-#define E1000_PBA_32K 0x0020
-#define E1000_PBA_34K 0x0022
-#define E1000_PBA_38K 0x0026
-#define E1000_PBA_40K 0x0028
-#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
-
-#define E1000_PBS_16K E1000_PBA_16K
-
-/* Flow Control Constants */
-#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
-#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
-#define FLOW_CONTROL_TYPE 0x8808
-
-/* The historical defaults for the flow control values are given below. */
-#define FC_DEFAULT_HI_THRESH (0x8000) /* 32KB */
-#define FC_DEFAULT_LO_THRESH (0x4000) /* 16KB */
-#define FC_DEFAULT_TX_TIMER (0x100) /* ~130 us */
-
-/* PCIX Config space */
-#define PCIX_COMMAND_REGISTER 0xE6
-#define PCIX_STATUS_REGISTER_LO 0xE8
-#define PCIX_STATUS_REGISTER_HI 0xEA
-
-#define PCIX_COMMAND_MMRBC_MASK 0x000C
-#define PCIX_COMMAND_MMRBC_SHIFT 0x2
-#define PCIX_STATUS_HI_MMRBC_MASK 0x0060
-#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5
-#define PCIX_STATUS_HI_MMRBC_4K 0x3
-#define PCIX_STATUS_HI_MMRBC_2K 0x2
-
-
-/* Number of bits required to shift right the "pause" bits from the
- * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
- */
-#define PAUSE_SHIFT 5
-
-/* Number of bits required to shift left the "SWDPIO" bits from the
- * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
- */
-#define SWDPIO_SHIFT 17
-
-/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
- * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
- */
-#define SWDPIO__EXT_SHIFT 4
-
-/* Number of bits required to shift left the "ILOS" bit from the EEPROM
- * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
- */
-#define ILOS_SHIFT 3
-
-
-#define RECEIVE_BUFFER_ALIGN_SIZE (256)
-
-/* Number of milliseconds we wait for auto-negotiation to complete */
-#define LINK_UP_TIMEOUT 500
-
-/* Number of 100 microseconds we wait for PCI Express master disable */
-#define MASTER_DISABLE_TIMEOUT 800
-/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */
-#define AUTO_READ_DONE_TIMEOUT 10
-/* Number of milliseconds we wait for PHY configuration done after MAC reset */
-#define PHY_CFG_TIMEOUT 100
-
-#define E1000_TX_BUFFER_SIZE ((u32)1514)
-
-/* The carrier extension symbol, as received by the NIC. */
-#define CARRIER_EXTENSION 0x0F
-
-/* TBI_ACCEPT macro definition:
- *
- * This macro requires:
- * adapter = a pointer to struct e1000_hw
- * status = the 8 bit status field of the RX descriptor with EOP set
- * error = the 8 bit error field of the RX descriptor with EOP set
- * length = the sum of all the length fields of the RX descriptors that
- * make up the current frame
- * last_byte = the last byte of the frame DMAed by the hardware
- * max_frame_length = the maximum frame length we want to accept.
- * min_frame_length = the minimum frame length we want to accept.
- *
- * This macro is a conditional that should be used in the interrupt
- * handler's Rx processing routine when RxErrors have been detected.
- *
- * Typical use:
- * ...
- * if (TBI_ACCEPT) {
- * accept_frame = true;
- * e1000_tbi_adjust_stats(adapter, MacAddress);
- * frame_length--;
- * } else {
- * accept_frame = false;
- * }
- * ...
- */
-
-#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
- ((adapter)->tbi_compatibility_on && \
- (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
- ((last_byte) == CARRIER_EXTENSION) && \
- (((status) & E1000_RXD_STAT_VP) ? \
- (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
- ((length) <= ((adapter)->max_frame_size + 1))) : \
- (((length) > (adapter)->min_frame_size) && \
- ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))
-
-
-/* Structures, enums, and macros for the PHY */
-
-/* Bit definitions for the Management Data IO (MDIO) and Management Data
- * Clock (MDC) pins in the Device Control Register.
- */
-#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0
-#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0
-#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2
-#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2
-#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3
-#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3
-#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
-#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA
-
-/* PHY 1000 MII Register/Bit Definitions */
-/* PHY Registers defined by IEEE */
-#define PHY_CTRL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Regiser */
-#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
-#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
-#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
-#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
-#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */
-#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
-#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
-#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
-#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
-#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
-
-#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
-#define MAX_PHY_MULTI_PAGE_REG 0xF /* Registers equal on all pages */
-
-/* M88E1000 Specific Registers */
-#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
-#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
-#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */
-#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */
-#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
-#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
-
-#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */
-#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
-#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
-#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
-#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
-
-#define IGP01E1000_IEEE_REGS_PAGE 0x0000
-#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
-#define IGP01E1000_IEEE_FORCE_GIGA 0x0140
-
-/* IGP01E1000 Specific Registers */
-#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
-#define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
-#define IGP01E1000_PHY_PORT_CTRL 0x12 /* PHY Specific Control Register */
-#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
-#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */
-#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
-#define IGP02E1000_PHY_POWER_MGMT 0x19
-#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */
-
-/* IGP01E1000 AGC Registers - stores the cable length values*/
-#define IGP01E1000_PHY_AGC_A 0x1172
-#define IGP01E1000_PHY_AGC_B 0x1272
-#define IGP01E1000_PHY_AGC_C 0x1472
-#define IGP01E1000_PHY_AGC_D 0x1872
-
-/* IGP02E1000 AGC Registers for cable length values */
-#define IGP02E1000_PHY_AGC_A 0x11B1
-#define IGP02E1000_PHY_AGC_B 0x12B1
-#define IGP02E1000_PHY_AGC_C 0x14B1
-#define IGP02E1000_PHY_AGC_D 0x18B1
-
-/* IGP01E1000 DSP Reset Register */
-#define IGP01E1000_PHY_DSP_RESET 0x1F33
-#define IGP01E1000_PHY_DSP_SET 0x1F71
-#define IGP01E1000_PHY_DSP_FFE 0x1F35
-
-#define IGP01E1000_PHY_CHANNEL_NUM 4
-#define IGP02E1000_PHY_CHANNEL_NUM 4
-
-#define IGP01E1000_PHY_AGC_PARAM_A 0x1171
-#define IGP01E1000_PHY_AGC_PARAM_B 0x1271
-#define IGP01E1000_PHY_AGC_PARAM_C 0x1471
-#define IGP01E1000_PHY_AGC_PARAM_D 0x1871
-
-#define IGP01E1000_PHY_EDAC_MU_INDEX 0xC000
-#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
-
-#define IGP01E1000_PHY_ANALOG_TX_STATE 0x2890
-#define IGP01E1000_PHY_ANALOG_CLASS_A 0x2000
-#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE 0x0004
-#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069
-
-#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A
-/* IGP01E1000 PCS Initialization register - stores the polarity status when
- * speed = 1000 Mbps. */
-#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
-#define IGP01E1000_PHY_PCS_CTRL_REG 0x00B5
-
-#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0
-
-/* Bits...
- * 15-5: page
- * 4-0: register offset
- */
-#define GG82563_PAGE_SHIFT 5
-#define GG82563_REG(page, reg) \
- (((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
-#define GG82563_MIN_ALT_REG 30
-
-/* GG82563 Specific Registers */
-#define GG82563_PHY_SPEC_CTRL \
- GG82563_REG(0, 16) /* PHY Specific Control */
-#define GG82563_PHY_SPEC_STATUS \
- GG82563_REG(0, 17) /* PHY Specific Status */
-#define GG82563_PHY_INT_ENABLE \
- GG82563_REG(0, 18) /* Interrupt Enable */
-#define GG82563_PHY_SPEC_STATUS_2 \
- GG82563_REG(0, 19) /* PHY Specific Status 2 */
-#define GG82563_PHY_RX_ERR_CNTR \
- GG82563_REG(0, 21) /* Receive Error Counter */
-#define GG82563_PHY_PAGE_SELECT \
- GG82563_REG(0, 22) /* Page Select */
-#define GG82563_PHY_SPEC_CTRL_2 \
- GG82563_REG(0, 26) /* PHY Specific Control 2 */
-#define GG82563_PHY_PAGE_SELECT_ALT \
- GG82563_REG(0, 29) /* Alternate Page Select */
-#define GG82563_PHY_TEST_CLK_CTRL \
- GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */
-
-#define GG82563_PHY_MAC_SPEC_CTRL \
- GG82563_REG(2, 21) /* MAC Specific Control Register */
-#define GG82563_PHY_MAC_SPEC_CTRL_2 \
- GG82563_REG(2, 26) /* MAC Specific Control 2 */
-
-#define GG82563_PHY_DSP_DISTANCE \
- GG82563_REG(5, 26) /* DSP Distance */
-
-/* Page 193 - Port Control Registers */
-#define GG82563_PHY_KMRN_MODE_CTRL \
- GG82563_REG(193, 16) /* Kumeran Mode Control */
-#define GG82563_PHY_PORT_RESET \
- GG82563_REG(193, 17) /* Port Reset */
-#define GG82563_PHY_REVISION_ID \
- GG82563_REG(193, 18) /* Revision ID */
-#define GG82563_PHY_DEVICE_ID \
- GG82563_REG(193, 19) /* Device ID */
-#define GG82563_PHY_PWR_MGMT_CTRL \
- GG82563_REG(193, 20) /* Power Management Control */
-#define GG82563_PHY_RATE_ADAPT_CTRL \
- GG82563_REG(193, 25) /* Rate Adaptation Control */
-
-/* Page 194 - KMRN Registers */
-#define GG82563_PHY_KMRN_FIFO_CTRL_STAT \
- GG82563_REG(194, 16) /* FIFO's Control/Status */
-#define GG82563_PHY_KMRN_CTRL \
- GG82563_REG(194, 17) /* Control */
-#define GG82563_PHY_INBAND_CTRL \
- GG82563_REG(194, 18) /* Inband Control */
-#define GG82563_PHY_KMRN_DIAGNOSTIC \
- GG82563_REG(194, 19) /* Diagnostic */
-#define GG82563_PHY_ACK_TIMEOUTS \
- GG82563_REG(194, 20) /* Acknowledge Timeouts */
-#define GG82563_PHY_ADV_ABILITY \
- GG82563_REG(194, 21) /* Advertised Ability */
-#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY \
- GG82563_REG(194, 23) /* Link Partner Advertised Ability */
-#define GG82563_PHY_ADV_NEXT_PAGE \
- GG82563_REG(194, 24) /* Advertised Next Page */
-#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE \
- GG82563_REG(194, 25) /* Link Partner Advertised Next page */
-#define GG82563_PHY_KMRN_MISC \
- GG82563_REG(194, 26) /* Misc. */
-
-/* PHY Control Register */
-#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
-#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
-#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
-#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
-#define MII_CR_POWER_DOWN 0x0800 /* Power down */
-#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
-#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
-#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
-
-/* PHY Status Register */
-#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
-#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
-#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
-#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
-#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
-#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
-#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
-#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
-#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
-#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
-#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
-#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
-#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
-#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
-#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
-
-/* Autoneg Advertisement Register */
-#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */
-#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
-#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
-#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
-#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
-#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
-#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */
-#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
-#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
-#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */
-
-/* Link Partner Ability Register (Base Page) */
-#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */
-#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */
-#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */
-#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */
-#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */
-#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */
-#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
-#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
-#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */
-#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */
-#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */
-
-/* Autoneg Expansion Register */
-#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */
-#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */
-#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */
-#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
-#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP is 100TX Full Duplex Capable */
-
-/* Next Page TX Register */
-#define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
-#define NPTX_TOGGLE 0x0800 /* Toggles between exchanges
- * of different NP
- */
-#define NPTX_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
- * 0 = cannot comply with msg
- */
-#define NPTX_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
-#define NPTX_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
- * 0 = sending last NP
- */
-
-/* Link Partner Next Page Register */
-#define LP_RNPR_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
-#define LP_RNPR_TOGGLE 0x0800 /* Toggles between exchanges
- * of different NP
- */
-#define LP_RNPR_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
- * 0 = cannot comply with msg
- */
-#define LP_RNPR_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
-#define LP_RNPR_ACKNOWLDGE 0x4000 /* 1 = ACK / 0 = NO ACK */
-#define LP_RNPR_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
- * 0 = sending last NP
- */
-
-/* 1000BASE-T Control Register */
-#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */
-#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
-#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
-#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */
- /* 0=DTE device */
-#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
- /* 0=Configure PHY as Slave */
-#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
- /* 0=Automatic Master/Slave config */
-#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
-#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
-#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
-#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
-#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
-
-/* 1000BASE-T Status Register */
-#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */
-#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */
-#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
-#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
-#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
-#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
-#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */
-#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
-#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
-#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13
-#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5
-#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20
-#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100
-
-/* Extended Status Register */
-#define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
-#define IEEE_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
-#define IEEE_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
-#define IEEE_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
-
-#define PHY_TX_POLARITY_MASK 0x0100 /* register 10h bit 8 (polarity bit) */
-#define PHY_TX_NORMAL_POLARITY 0 /* register 10h bit 8 (normal polarity) */
-
-#define AUTO_POLARITY_DISABLE 0x0010 /* register 11h bit 4 */
- /* (0=enable, 1=disable) */
-
-/* M88E1000 PHY Specific Control Register */
-#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
-#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
-#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
-#define M88E1000_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low,
- * 0=CLK125 toggling
- */
-#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
- /* Manual MDI configuration */
-#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
-#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover,
- * 100BASE-TX/10BASE-T:
- * MDI Mode
- */
-#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled
- * all speeds.
- */
-#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
- /* 1=Enable Extended 10BASE-T distance
- * (Lower 10BASE-T RX Threshold)
- * 0=Normal 10BASE-T RX Threshold */
-#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100
- /* 1=5-Bit interface in 100BASE-TX
- * 0=MII interface in 100BASE-TX */
-#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */
-#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
-#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
-
-#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT 1
-#define M88E1000_PSCR_AUTO_X_MODE_SHIFT 5
-#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
-
-/* M88E1000 PHY Specific Status Register */
-#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */
-#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
-#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
-#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
-#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M;
- * 3=110-140M;4=>140M */
-#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */
-#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
-#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */
-#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
-#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
-#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */
-#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */
-#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
-
-#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
-#define M88E1000_PSSR_DOWNSHIFT_SHIFT 5
-#define M88E1000_PSSR_MDIX_SHIFT 6
-#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
-
-/* M88E1000 Extended PHY Specific Control Register */
-#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */
-#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 /* 1=Lost lock detect enabled.
- * Will assert lost lock and bring
- * link down if idle not seen
- * within 1ms in 1000BASE-T
- */
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the master */
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800
-#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the slave */
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X 0x0200
-#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X 0x0300
-#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */
-#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
-#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
-
-/* M88EC018 Rev 2 specific DownShift settings */
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X 0x0200
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X 0x0400
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X 0x0600
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X 0x0A00
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00
-#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00
-
-/* IGP01E1000 Specific Port Config Register - R/W */
-#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010
-#define IGP01E1000_PSCFR_PRE_EN 0x0020
-#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
-#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK 0x0100
-#define IGP01E1000_PSCFR_DISABLE_JABBER 0x0400
-#define IGP01E1000_PSCFR_DISABLE_TRANSMIT 0x2000
-
-/* IGP01E1000 Specific Port Status Register - R/O */
-#define IGP01E1000_PSSR_AUTONEG_FAILED 0x0001 /* RO LH SC */
-#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
-#define IGP01E1000_PSSR_CABLE_LENGTH 0x007C
-#define IGP01E1000_PSSR_FULL_DUPLEX 0x0200
-#define IGP01E1000_PSSR_LINK_UP 0x0400
-#define IGP01E1000_PSSR_MDIX 0x0800
-#define IGP01E1000_PSSR_SPEED_MASK 0xC000 /* speed bits mask */
-#define IGP01E1000_PSSR_SPEED_10MBPS 0x4000
-#define IGP01E1000_PSSR_SPEED_100MBPS 0x8000
-#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
-#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT 0x0002 /* shift right 2 */
-#define IGP01E1000_PSSR_MDIX_SHIFT 0x000B /* shift right 11 */
-
-/* IGP01E1000 Specific Port Control Register - R/W */
-#define IGP01E1000_PSCR_TP_LOOPBACK 0x0010
-#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200
-#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400
-#define IGP01E1000_PSCR_FLIP_CHIP 0x0800
-#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
-#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0-MDI, 1-MDIX */
-
-/* IGP01E1000 Specific Port Link Health Register */
-#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
-#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR 0x4000
-#define IGP01E1000_PLHR_MASTER_FAULT 0x2000
-#define IGP01E1000_PLHR_MASTER_RESOLUTION 0x1000
-#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK 0x0800 /* LH */
-#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW 0x0400 /* LH */
-#define IGP01E1000_PLHR_DATA_ERR_1 0x0200 /* LH */
-#define IGP01E1000_PLHR_DATA_ERR_0 0x0100
-#define IGP01E1000_PLHR_AUTONEG_FAULT 0x0040
-#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x0010
-#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x0008
-#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x0004
-#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x0002
-#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x0001
-
-/* IGP01E1000 Channel Quality Register */
-#define IGP01E1000_MSE_CHANNEL_D 0x000F
-#define IGP01E1000_MSE_CHANNEL_C 0x00F0
-#define IGP01E1000_MSE_CHANNEL_B 0x0F00
-#define IGP01E1000_MSE_CHANNEL_A 0xF000
-
-#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
-#define IGP02E1000_PM_D3_LPLU 0x0004 /* Enable LPLU in non-D0a modes */
-#define IGP02E1000_PM_D0_LPLU 0x0002 /* Enable LPLU in D0a mode */
-
-/* IGP01E1000 DSP reset macros */
-#define DSP_RESET_ENABLE 0x0
-#define DSP_RESET_DISABLE 0x2
-#define E1000_MAX_DSP_RESETS 10
-
-/* IGP01E1000 & IGP02E1000 AGC Registers */
-
-#define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */
-#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Coarse - 15:13, Fine - 12:9 */
-
-/* IGP02E1000 AGC Register Length 9-bit mask */
-#define IGP02E1000_AGC_LENGTH_MASK 0x7F
-
-/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
-#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
-#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113
-
-/* The precision error of the cable length is +/- 10 meters */
-#define IGP01E1000_AGC_RANGE 10
-#define IGP02E1000_AGC_RANGE 15
-
-/* IGP01E1000 PCS Initialization register */
-/* bits 3:6 in the PCS registers stores the channels polarity */
-#define IGP01E1000_PHY_POLARITY_MASK 0x0078
-
-/* IGP01E1000 GMII FIFO Register */
-#define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed
- * on Link-Up */
-#define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */
-
-/* IGP01E1000 Analog Register */
-#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1
-#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0
-#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC
-#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE
-
-#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000
-#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80
-#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070
-#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100
-#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002
-
-#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH 0x0040
-#define IGP01E1000_ANALOG_FUSE_COARSE_10 0x0010
-#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080
-#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500
-
-/* GG82563 PHY Specific Status Register (Page 0, Register 16 */
-#define GG82563_PSCR_DISABLE_JABBER 0x0001 /* 1=Disable Jabber */
-#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Polarity Reversal Disabled */
-#define GG82563_PSCR_POWER_DOWN 0x0004 /* 1=Power Down */
-#define GG82563_PSCR_COPPER_TRANSMITER_DISABLE 0x0008 /* 1=Transmitter Disabled */
-#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060
-#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI configuration */
-#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX configuration */
-#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Automatic crossover */
-#define GG82563_PSCR_ENALBE_EXTENDED_DISTANCE 0x0080 /* 1=Enable Extended Distance */
-#define GG82563_PSCR_ENERGY_DETECT_MASK 0x0300
-#define GG82563_PSCR_ENERGY_DETECT_OFF 0x0000 /* 00,01=Off */
-#define GG82563_PSCR_ENERGY_DETECT_RX 0x0200 /* 10=Sense on Rx only (Energy Detect) */
-#define GG82563_PSCR_ENERGY_DETECT_RX_TM 0x0300 /* 11=Sense and Tx NLP */
-#define GG82563_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force Link Good */
-#define GG82563_PSCR_DOWNSHIFT_ENABLE 0x0800 /* 1=Enable Downshift */
-#define GG82563_PSCR_DOWNSHIFT_COUNTER_MASK 0x7000
-#define GG82563_PSCR_DOWNSHIFT_COUNTER_SHIFT 12
-
-/* PHY Specific Status Register (Page 0, Register 17) */
-#define GG82563_PSSR_JABBER 0x0001 /* 1=Jabber */
-#define GG82563_PSSR_POLARITY 0x0002 /* 1=Polarity Reversed */
-#define GG82563_PSSR_LINK 0x0008 /* 1=Link is Up */
-#define GG82563_PSSR_ENERGY_DETECT 0x0010 /* 1=Sleep, 0=Active */
-#define GG82563_PSSR_DOWNSHIFT 0x0020 /* 1=Downshift */
-#define GG82563_PSSR_CROSSOVER_STATUS 0x0040 /* 1=MDIX, 0=MDI */
-#define GG82563_PSSR_RX_PAUSE_ENABLED 0x0100 /* 1=Receive Pause Enabled */
-#define GG82563_PSSR_TX_PAUSE_ENABLED 0x0200 /* 1=Transmit Pause Enabled */
-#define GG82563_PSSR_LINK_UP 0x0400 /* 1=Link Up */
-#define GG82563_PSSR_SPEED_DUPLEX_RESOLVED 0x0800 /* 1=Resolved */
-#define GG82563_PSSR_PAGE_RECEIVED 0x1000 /* 1=Page Received */
-#define GG82563_PSSR_DUPLEX 0x2000 /* 1-Full-Duplex */
-#define GG82563_PSSR_SPEED_MASK 0xC000
-#define GG82563_PSSR_SPEED_10MBPS 0x0000 /* 00=10Mbps */
-#define GG82563_PSSR_SPEED_100MBPS 0x4000 /* 01=100Mbps */
-#define GG82563_PSSR_SPEED_1000MBPS 0x8000 /* 10=1000Mbps */
-
-/* PHY Specific Status Register 2 (Page 0, Register 19) */
-#define GG82563_PSSR2_JABBER 0x0001 /* 1=Jabber */
-#define GG82563_PSSR2_POLARITY_CHANGED 0x0002 /* 1=Polarity Changed */
-#define GG82563_PSSR2_ENERGY_DETECT_CHANGED 0x0010 /* 1=Energy Detect Changed */
-#define GG82563_PSSR2_DOWNSHIFT_INTERRUPT 0x0020 /* 1=Downshift Detected */
-#define GG82563_PSSR2_MDI_CROSSOVER_CHANGE 0x0040 /* 1=Crossover Changed */
-#define GG82563_PSSR2_FALSE_CARRIER 0x0100 /* 1=False Carrier */
-#define GG82563_PSSR2_SYMBOL_ERROR 0x0200 /* 1=Symbol Error */
-#define GG82563_PSSR2_LINK_STATUS_CHANGED 0x0400 /* 1=Link Status Changed */
-#define GG82563_PSSR2_AUTO_NEG_COMPLETED 0x0800 /* 1=Auto-Neg Completed */
-#define GG82563_PSSR2_PAGE_RECEIVED 0x1000 /* 1=Page Received */
-#define GG82563_PSSR2_DUPLEX_CHANGED 0x2000 /* 1=Duplex Changed */
-#define GG82563_PSSR2_SPEED_CHANGED 0x4000 /* 1=Speed Changed */
-#define GG82563_PSSR2_AUTO_NEG_ERROR 0x8000 /* 1=Auto-Neg Error */
-
-/* PHY Specific Control Register 2 (Page 0, Register 26) */
-#define GG82563_PSCR2_10BT_POLARITY_FORCE 0x0002 /* 1=Force Negative Polarity */
-#define GG82563_PSCR2_1000MB_TEST_SELECT_MASK 0x000C
-#define GG82563_PSCR2_1000MB_TEST_SELECT_NORMAL 0x0000 /* 00,01=Normal Operation */
-#define GG82563_PSCR2_1000MB_TEST_SELECT_112NS 0x0008 /* 10=Select 112ns Sequence */
-#define GG82563_PSCR2_1000MB_TEST_SELECT_16NS 0x000C /* 11=Select 16ns Sequence */
-#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Negotiation */
-#define GG82563_PSCR2_1000BT_DISABLE 0x4000 /* 1=Disable 1000BASE-T */
-#define GG82563_PSCR2_TRANSMITER_TYPE_MASK 0x8000
-#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_B 0x0000 /* 0=Class B */
-#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_A 0x8000 /* 1=Class A */
-
-/* MAC Specific Control Register (Page 2, Register 21) */
-/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
-#define GG82563_MSCR_TX_CLK_MASK 0x0007
-#define GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ 0x0004
-#define GG82563_MSCR_TX_CLK_100MBPS_25MHZ 0x0005
-#define GG82563_MSCR_TX_CLK_1000MBPS_2_5MHZ 0x0006
-#define GG82563_MSCR_TX_CLK_1000MBPS_25MHZ 0x0007
-
-#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */
-
-/* DSP Distance Register (Page 5, Register 26) */
-#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M;
- 1 = 50-80M;
- 2 = 80-110M;
- 3 = 110-140M;
- 4 = >140M */
-
-/* Kumeran Mode Control Register (Page 193, Register 16) */
-#define GG82563_KMCR_PHY_LEDS_EN 0x0020 /* 1=PHY LEDs, 0=Kumeran Inband LEDs */
-#define GG82563_KMCR_FORCE_LINK_UP 0x0040 /* 1=Force Link Up */
-#define GG82563_KMCR_SUPPRESS_SGMII_EPD_EXT 0x0080
-#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT_MASK 0x0400
-#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT 0x0400 /* 1=6.25MHz, 0=0.8MHz */
-#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800
-
-/* Power Management Control Register (Page 193, Register 20) */
-#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* 1=Enalbe SERDES Electrical Idle */
-#define GG82563_PMCR_DISABLE_PORT 0x0002 /* 1=Disable Port */
-#define GG82563_PMCR_DISABLE_SERDES 0x0004 /* 1=Disable SERDES */
-#define GG82563_PMCR_REVERSE_AUTO_NEG 0x0008 /* 1=Enable Reverse Auto-Negotiation */
-#define GG82563_PMCR_DISABLE_1000_NON_D0 0x0010 /* 1=Disable 1000Mbps Auto-Neg in non D0 */
-#define GG82563_PMCR_DISABLE_1000 0x0020 /* 1=Disable 1000Mbps Auto-Neg Always */
-#define GG82563_PMCR_REVERSE_AUTO_NEG_D0A 0x0040 /* 1=Enable D0a Reverse Auto-Negotiation */
-#define GG82563_PMCR_FORCE_POWER_STATE 0x0080 /* 1=Force Power State */
-#define GG82563_PMCR_PROGRAMMED_POWER_STATE_MASK 0x0300
-#define GG82563_PMCR_PROGRAMMED_POWER_STATE_DR 0x0000 /* 00=Dr */
-#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0U 0x0100 /* 01=D0u */
-#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0A 0x0200 /* 10=D0a */
-#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D3 0x0300 /* 11=D3 */
-
-/* In-Band Control Register (Page 194, Register 18) */
-#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding Use */
-
-
-/* Bit definitions for valid PHY IDs. */
-/* I = Integrated
- * E = External
- */
-#define M88_VENDOR 0x0141
-#define M88E1000_E_PHY_ID 0x01410C50
-#define M88E1000_I_PHY_ID 0x01410C30
-#define M88E1011_I_PHY_ID 0x01410C20
-#define IGP01E1000_I_PHY_ID 0x02A80380
-#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
-#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
-#define M88E1011_I_REV_4 0x04
-#define M88E1111_I_PHY_ID 0x01410CC0
-#define L1LXT971A_PHY_ID 0x001378E0
-#define GG82563_E_PHY_ID 0x01410CA0
-
-
-/* Bits...
- * 15-5: page
- * 4-0: register offset
- */
-#define PHY_PAGE_SHIFT 5
-#define PHY_REG(page, reg) \
- (((page) << PHY_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
-
-#define IGP3_PHY_PORT_CTRL \
- PHY_REG(769, 17) /* Port General Configuration */
-#define IGP3_PHY_RATE_ADAPT_CTRL \
- PHY_REG(769, 25) /* Rate Adapter Control Register */
-
-#define IGP3_KMRN_FIFO_CTRL_STATS \
- PHY_REG(770, 16) /* KMRN FIFO's control/status register */
-#define IGP3_KMRN_POWER_MNG_CTRL \
- PHY_REG(770, 17) /* KMRN Power Management Control Register */
-#define IGP3_KMRN_INBAND_CTRL \
- PHY_REG(770, 18) /* KMRN Inband Control Register */
-#define IGP3_KMRN_DIAG \
- PHY_REG(770, 19) /* KMRN Diagnostic register */
-#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 /* RX PCS is not synced */
-#define IGP3_KMRN_ACK_TIMEOUT \
- PHY_REG(770, 20) /* KMRN Acknowledge Timeouts register */
-
-#define IGP3_VR_CTRL \
- PHY_REG(776, 18) /* Voltage regulator control register */
-#define IGP3_VR_CTRL_MODE_SHUT 0x0200 /* Enter powerdown, shutdown VRs */
-#define IGP3_VR_CTRL_MODE_MASK 0x0300 /* Shutdown VR Mask */
-
-#define IGP3_CAPABILITY \
- PHY_REG(776, 19) /* IGP3 Capability Register */
-
-/* Capabilities for SKU Control */
-#define IGP3_CAP_INITIATE_TEAM 0x0001 /* Able to initiate a team */
-#define IGP3_CAP_WFM 0x0002 /* Support WoL and PXE */
-#define IGP3_CAP_ASF 0x0004 /* Support ASF */
-#define IGP3_CAP_LPLU 0x0008 /* Support Low Power Link Up */
-#define IGP3_CAP_DC_AUTO_SPEED 0x0010 /* Support AC/DC Auto Link Speed */
-#define IGP3_CAP_SPD 0x0020 /* Support Smart Power Down */
-#define IGP3_CAP_MULT_QUEUE 0x0040 /* Support 2 tx & 2 rx queues */
-#define IGP3_CAP_RSS 0x0080 /* Support RSS */
-#define IGP3_CAP_8021PQ 0x0100 /* Support 802.1Q & 802.1p */
-#define IGP3_CAP_AMT_CB 0x0200 /* Support active manageability and circuit breaker */
-
-#define IGP3_PPC_JORDAN_EN 0x0001
-#define IGP3_PPC_JORDAN_GIGA_SPEED 0x0002
-
-#define IGP3_KMRN_PMC_EE_IDLE_LINK_DIS 0x0001
-#define IGP3_KMRN_PMC_K0S_ENTRY_LATENCY_MASK 0x001E
-#define IGP3_KMRN_PMC_K0S_MODE1_EN_GIGA 0x0020
-#define IGP3_KMRN_PMC_K0S_MODE1_EN_100 0x0040
-
-#define IGP3E1000_PHY_MISC_CTRL 0x1B /* Misc. Ctrl register */
-#define IGP3_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Duplex Manual Set */
-
-#define IGP3_KMRN_EXT_CTRL PHY_REG(770, 18)
-#define IGP3_KMRN_EC_DIS_INBAND 0x0080
-
-#define IGP03E1000_E_PHY_ID 0x02A80390
-#define IFE_E_PHY_ID 0x02A80330 /* 10/100 PHY */
-#define IFE_PLUS_E_PHY_ID 0x02A80320
-#define IFE_C_E_PHY_ID 0x02A80310
-
-#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 /* 100BaseTx Extended Status, Control and Address */
-#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY special control register */
-#define IFE_PHY_RCV_FALSE_CARRIER 0x13 /* 100BaseTx Receive False Carrier Counter */
-#define IFE_PHY_RCV_DISCONNECT 0x14 /* 100BaseTx Receive Disconnet Counter */
-#define IFE_PHY_RCV_ERROT_FRAME 0x15 /* 100BaseTx Receive Error Frame Counter */
-#define IFE_PHY_RCV_SYMBOL_ERR 0x16 /* Receive Symbol Error Counter */
-#define IFE_PHY_PREM_EOF_ERR 0x17 /* 100BaseTx Receive Premature End Of Frame Error Counter */
-#define IFE_PHY_RCV_EOF_ERR 0x18 /* 10BaseT Receive End Of Frame Error Counter */
-#define IFE_PHY_TX_JABBER_DETECT 0x19 /* 10BaseT Transmit Jabber Detect Counter */
-#define IFE_PHY_EQUALIZER 0x1A /* PHY Equalizer Control and Status */
-#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY special control and LED configuration */
-#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control register */
-#define IFE_PHY_HWI_CONTROL 0x1D /* Hardware Integrity Control (HWI) */
-
-#define IFE_PESC_REDUCED_POWER_DOWN_DISABLE 0x2000 /* Defaut 1 = Disable auto reduced power down */
-#define IFE_PESC_100BTX_POWER_DOWN 0x0400 /* Indicates the power state of 100BASE-TX */
-#define IFE_PESC_10BTX_POWER_DOWN 0x0200 /* Indicates the power state of 10BASE-T */
-#define IFE_PESC_POLARITY_REVERSED 0x0100 /* Indicates 10BASE-T polarity */
-#define IFE_PESC_PHY_ADDR_MASK 0x007C /* Bit 6:2 for sampled PHY address */
-#define IFE_PESC_SPEED 0x0002 /* Auto-negotiation speed result 1=100Mbs, 0=10Mbs */
-#define IFE_PESC_DUPLEX 0x0001 /* Auto-negotiation duplex result 1=Full, 0=Half */
-#define IFE_PESC_POLARITY_REVERSED_SHIFT 8
-
-#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100 /* 1 = Dyanmic Power Down disabled */
-#define IFE_PSC_FORCE_POLARITY 0x0020 /* 1=Reversed Polarity, 0=Normal */
-#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 /* 1=Auto Polarity Disabled, 0=Enabled */
-#define IFE_PSC_JABBER_FUNC_DISABLE 0x0001 /* 1=Jabber Disabled, 0=Normal Jabber Operation */
-#define IFE_PSC_FORCE_POLARITY_SHIFT 5
-#define IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT 4
-
-#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable MDI/MDI-X feature, default 0=disabled */
-#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDIX-X, 0=force MDI */
-#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
-#define IFE_PMC_AUTO_MDIX_COMPLETE 0x0010 /* Resolution algorithm is completed */
-#define IFE_PMC_MDIX_MODE_SHIFT 6
-#define IFE_PHC_MDIX_RESET_ALL_MASK 0x0000 /* Disable auto MDI-X */
-
-#define IFE_PHC_HWI_ENABLE 0x8000 /* Enable the HWI feature */
-#define IFE_PHC_ABILITY_CHECK 0x4000 /* 1= Test Passed, 0=failed */
-#define IFE_PHC_TEST_EXEC 0x2000 /* PHY launch test pulses on the wire */
-#define IFE_PHC_HIGHZ 0x0200 /* 1 = Open Circuit */
-#define IFE_PHC_LOWZ 0x0400 /* 1 = Short Circuit */
-#define IFE_PHC_LOW_HIGH_Z_MASK 0x0600 /* Mask for indication type of problem on the line */
-#define IFE_PHC_DISTANCE_MASK 0x01FF /* Mask for distance to the cable problem, in 80cm granularity */
-#define IFE_PHC_RESET_ALL_MASK 0x0000 /* Disable HWI */
-#define IFE_PSCL_PROBE_MODE 0x0020 /* LED Probe mode */
-#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
-#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
-
-#define ICH_FLASH_COMMAND_TIMEOUT 5000 /* 5000 uSecs - adjusted */
-#define ICH_FLASH_ERASE_TIMEOUT 3000000 /* Up to 3 seconds - worst case */
-#define ICH_FLASH_CYCLE_REPEAT_COUNT 10 /* 10 cycles */
-#define ICH_FLASH_SEG_SIZE_256 256
-#define ICH_FLASH_SEG_SIZE_4K 4096
-#define ICH_FLASH_SEG_SIZE_64K 65536
-
-#define ICH_CYCLE_READ 0x0
-#define ICH_CYCLE_RESERVED 0x1
-#define ICH_CYCLE_WRITE 0x2
-#define ICH_CYCLE_ERASE 0x3
-
-#define ICH_FLASH_GFPREG 0x0000
-#define ICH_FLASH_HSFSTS 0x0004
-#define ICH_FLASH_HSFCTL 0x0006
-#define ICH_FLASH_FADDR 0x0008
-#define ICH_FLASH_FDATA0 0x0010
-#define ICH_FLASH_FRACC 0x0050
-#define ICH_FLASH_FREG0 0x0054
-#define ICH_FLASH_FREG1 0x0058
-#define ICH_FLASH_FREG2 0x005C
-#define ICH_FLASH_FREG3 0x0060
-#define ICH_FLASH_FPR0 0x0074
-#define ICH_FLASH_FPR1 0x0078
-#define ICH_FLASH_SSFSTS 0x0090
-#define ICH_FLASH_SSFCTL 0x0092
-#define ICH_FLASH_PREOP 0x0094
-#define ICH_FLASH_OPTYPE 0x0096
-#define ICH_FLASH_OPMENU 0x0098
-
-#define ICH_FLASH_REG_MAPSIZE 0x00A0
-#define ICH_FLASH_SECTOR_SIZE 4096
-#define ICH_GFPREG_BASE_MASK 0x1FFF
-#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
-
-/* ICH8 GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
-/* Offset 04h HSFSTS */
-union ich8_hws_flash_status {
- struct ich8_hsfsts {
-#ifdef __BIG_ENDIAN
- u16 reserved2 :6;
- u16 fldesvalid :1;
- u16 flockdn :1;
- u16 flcdone :1;
- u16 flcerr :1;
- u16 dael :1;
- u16 berasesz :2;
- u16 flcinprog :1;
- u16 reserved1 :2;
-#else
- u16 flcdone :1; /* bit 0 Flash Cycle Done */
- u16 flcerr :1; /* bit 1 Flash Cycle Error */
- u16 dael :1; /* bit 2 Direct Access error Log */
- u16 berasesz :2; /* bit 4:3 Block/Sector Erase Size */
- u16 flcinprog :1; /* bit 5 flash SPI cycle in Progress */
- u16 reserved1 :2; /* bit 13:6 Reserved */
- u16 reserved2 :6; /* bit 13:6 Reserved */
- u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */
- u16 flockdn :1; /* bit 15 Flash Configuration Lock-Down */
-#endif
- } hsf_status;
- u16 regval;
-};
-
-/* ICH8 GbE Flash Hardware Sequencing Flash control Register bit breakdown */
-/* Offset 06h FLCTL */
-union ich8_hws_flash_ctrl {
- struct ich8_hsflctl {
-#ifdef __BIG_ENDIAN
- u16 fldbcount :2;
- u16 flockdn :6;
- u16 flcgo :1;
- u16 flcycle :2;
- u16 reserved :5;
-#else
- u16 flcgo :1; /* 0 Flash Cycle Go */
- u16 flcycle :2; /* 2:1 Flash Cycle */
- u16 reserved :5; /* 7:3 Reserved */
- u16 fldbcount :2; /* 9:8 Flash Data Byte Count */
- u16 flockdn :6; /* 15:10 Reserved */
-#endif
- } hsf_ctrl;
- u16 regval;
-};
-
-/* ICH8 Flash Region Access Permissions */
-union ich8_hws_flash_regacc {
- struct ich8_flracc {
-#ifdef __BIG_ENDIAN
- u32 gmwag :8;
- u32 gmrag :8;
- u32 grwa :8;
- u32 grra :8;
-#else
- u32 grra :8; /* 0:7 GbE region Read Access */
- u32 grwa :8; /* 8:15 GbE region Write Access */
- u32 gmrag :8; /* 23:16 GbE Master Read Access Grant */
- u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */
-#endif
- } hsf_flregacc;
- u16 regval;
-};
-
-/* Miscellaneous PHY bit definitions. */
-#define PHY_PREAMBLE 0xFFFFFFFF
-#define PHY_SOF 0x01
-#define PHY_OP_READ 0x02
-#define PHY_OP_WRITE 0x01
-#define PHY_TURNAROUND 0x02
-#define PHY_PREAMBLE_SIZE 32
-#define MII_CR_SPEED_1000 0x0040
-#define MII_CR_SPEED_100 0x2000
-#define MII_CR_SPEED_10 0x0000
-#define E1000_PHY_ADDRESS 0x01
-#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
-#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
-#define PHY_REVISION_MASK 0xFFFFFFF0
-#define DEVICE_SPEED_MASK 0x00000300 /* Device Ctrl Reg Speed Mask */
-#define REG4_SPEED_MASK 0x01E0
-#define REG9_SPEED_MASK 0x0300
-#define ADVERTISE_10_HALF 0x0001
-#define ADVERTISE_10_FULL 0x0002
-#define ADVERTISE_100_HALF 0x0004
-#define ADVERTISE_100_FULL 0x0008
-#define ADVERTISE_1000_HALF 0x0010
-#define ADVERTISE_1000_FULL 0x0020
-#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
-#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/
-#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/
-
-#endif /* _E1000_HW_H_ */
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
deleted file mode 100644
index 462351ca2c8..00000000000
--- a/drivers/net/e1000e/82571.c
+++ /dev/null
@@ -1,1377 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/*
- * 82571EB Gigabit Ethernet Controller
- * 82571EB Gigabit Ethernet Controller (Fiber)
- * 82571EB Dual Port Gigabit Mezzanine Adapter
- * 82571EB Quad Port Gigabit Mezzanine Adapter
- * 82571PT Gigabit PT Quad Port Server ExpressModule
- * 82572EI Gigabit Ethernet Controller (Copper)
- * 82572EI Gigabit Ethernet Controller (Fiber)
- * 82572EI Gigabit Ethernet Controller
- * 82573V Gigabit Ethernet Controller (Copper)
- * 82573E Gigabit Ethernet Controller (Copper)
- * 82573L Gigabit Ethernet Controller
- */
-
-#include <linux/netdevice.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include "e1000.h"
-
-#define ID_LED_RESERVED_F746 0xF746
-#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
- (ID_LED_OFF1_ON2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_DEF1_DEF2))
-
-#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
-
-static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
-static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
-static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
-static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
- u16 words, u16 *data);
-static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
-static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
-static s32 e1000_setup_link_82571(struct e1000_hw *hw);
-static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
-
-/**
- * e1000_init_phy_params_82571 - Init PHY func ptrs.
- * @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
- **/
-static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
-
- if (hw->phy.media_type != e1000_media_type_copper) {
- phy->type = e1000_phy_none;
- return 0;
- }
-
- phy->addr = 1;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- phy->reset_delay_us = 100;
-
- switch (hw->mac.type) {
- case e1000_82571:
- case e1000_82572:
- phy->type = e1000_phy_igp_2;
- break;
- case e1000_82573:
- phy->type = e1000_phy_m88;
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
-
- /* This can only be done after all function pointers are setup. */
- ret_val = e1000_get_phy_id_82571(hw);
-
- /* Verify phy id */
- switch (hw->mac.type) {
- case e1000_82571:
- case e1000_82572:
- if (phy->id != IGP01E1000_I_PHY_ID)
- return -E1000_ERR_PHY;
- break;
- case e1000_82573:
- if (phy->id != M88E1111_I_PHY_ID)
- return -E1000_ERR_PHY;
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000_init_nvm_params_82571 - Init NVM func ptrs.
- * @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
- **/
-static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = er32(EECD);
- u16 size;
-
- nvm->opcode_bits = 8;
- nvm->delay_usec = 1;
- switch (nvm->override) {
- case e1000_nvm_override_spi_large:
- nvm->page_size = 32;
- nvm->address_bits = 16;
- break;
- case e1000_nvm_override_spi_small:
- nvm->page_size = 8;
- nvm->address_bits = 8;
- break;
- default:
- nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
- nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
- break;
- }
-
- switch (hw->mac.type) {
- case e1000_82573:
- if (((eecd >> 15) & 0x3) == 0x3) {
- nvm->type = e1000_nvm_flash_hw;
- nvm->word_size = 2048;
- /*
- * Autonomous Flash update bit must be cleared due
- * to Flash update issue.
- */
- eecd &= ~E1000_EECD_AUPDEN;
- ew32(EECD, eecd);
- break;
- }
- /* Fall Through */
- default:
- nvm->type = e1000_nvm_eeprom_spi;
- size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
- E1000_EECD_SIZE_EX_SHIFT);
- /*
- * Added to a constant, "size" becomes the left-shift value
- * for setting word_size.
- */
- size += NVM_WORD_SIZE_BASE_SHIFT;
-
- /* EEPROM access above 16k is unsupported */
- if (size > 14)
- size = 14;
- nvm->word_size = 1 << size;
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000_init_mac_params_82571 - Init MAC func ptrs.
- * @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
- **/
-static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_mac_info *mac = &hw->mac;
- struct e1000_mac_operations *func = &mac->ops;
-
- /* Set media type */
- switch (adapter->pdev->device) {
- case E1000_DEV_ID_82571EB_FIBER:
- case E1000_DEV_ID_82572EI_FIBER:
- case E1000_DEV_ID_82571EB_QUAD_FIBER:
- hw->phy.media_type = e1000_media_type_fiber;
- break;
- case E1000_DEV_ID_82571EB_SERDES:
- case E1000_DEV_ID_82572EI_SERDES:
- case E1000_DEV_ID_82571EB_SERDES_DUAL:
- case E1000_DEV_ID_82571EB_SERDES_QUAD:
- hw->phy.media_type = e1000_media_type_internal_serdes;
- break;
- default:
- hw->phy.media_type = e1000_media_type_copper;
- break;
- }
-
- /* Set mta register count */
- mac->mta_reg_count = 128;
- /* Set rar entry count */
- mac->rar_entry_count = E1000_RAR_ENTRIES;
- /* Set if manageability features are enabled. */
- mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;
-
- /* check for link */
- switch (hw->phy.media_type) {
- case e1000_media_type_copper:
- func->setup_physical_interface = e1000_setup_copper_link_82571;
- func->check_for_link = e1000e_check_for_copper_link;
- func->get_link_up_info = e1000e_get_speed_and_duplex_copper;
- break;
- case e1000_media_type_fiber:
- func->setup_physical_interface =
- e1000_setup_fiber_serdes_link_82571;
- func->check_for_link = e1000e_check_for_fiber_link;
- func->get_link_up_info =
- e1000e_get_speed_and_duplex_fiber_serdes;
- break;
- case e1000_media_type_internal_serdes:
- func->setup_physical_interface =
- e1000_setup_fiber_serdes_link_82571;
- func->check_for_link = e1000e_check_for_serdes_link;
- func->get_link_up_info =
- e1000e_get_speed_and_duplex_fiber_serdes;
- break;
- default:
- return -E1000_ERR_CONFIG;
- break;
- }
-
- return 0;
-}
-
-static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- static int global_quad_port_a; /* global port a indication */
- struct pci_dev *pdev = adapter->pdev;
- u16 eeprom_data = 0;
- int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;
- s32 rc;
-
- rc = e1000_init_mac_params_82571(adapter);
- if (rc)
- return rc;
-
- rc = e1000_init_nvm_params_82571(hw);
- if (rc)
- return rc;
-
- rc = e1000_init_phy_params_82571(hw);
- if (rc)
- return rc;
-
- /* tag quad port adapters first, it's used below */
- switch (pdev->device) {
- case E1000_DEV_ID_82571EB_QUAD_COPPER:
- case E1000_DEV_ID_82571EB_QUAD_FIBER:
- case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
- case E1000_DEV_ID_82571PT_QUAD_COPPER:
- adapter->flags |= FLAG_IS_QUAD_PORT;
- /* mark the first port */
- if (global_quad_port_a == 0)
- adapter->flags |= FLAG_IS_QUAD_PORT_A;
- /* Reset for multiple quad port adapters */
- global_quad_port_a++;
- if (global_quad_port_a == 4)
- global_quad_port_a = 0;
- break;
- default:
- break;
- }
-
- switch (adapter->hw.mac.type) {
- case e1000_82571:
- /* these dual ports don't have WoL on port B at all */
- if (((pdev->device == E1000_DEV_ID_82571EB_FIBER) ||
- (pdev->device == E1000_DEV_ID_82571EB_SERDES) ||
- (pdev->device == E1000_DEV_ID_82571EB_COPPER)) &&
- (is_port_b))
- adapter->flags &= ~FLAG_HAS_WOL;
- /* quad ports only support WoL on port A */
- if (adapter->flags & FLAG_IS_QUAD_PORT &&
- (!(adapter->flags & FLAG_IS_QUAD_PORT_A)))
- adapter->flags &= ~FLAG_HAS_WOL;
- /* Does not support WoL on any port */
- if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
- adapter->flags &= ~FLAG_HAS_WOL;
- break;
-
- case e1000_82573:
- if (pdev->device == E1000_DEV_ID_82573L) {
- e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
- &eeprom_data);
- if (eeprom_data & NVM_WORD1A_ASPM_MASK)
- adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
- }
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000_get_phy_id_82571 - Retrieve the PHY ID and revision
- * @hw: pointer to the HW structure
- *
- * Reads the PHY registers and stores the PHY ID and possibly the PHY
- * revision in the hardware structure.
- **/
-static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
-
- switch (hw->mac.type) {
- case e1000_82571:
- case e1000_82572:
- /*
- * The 82571 firmware may still be configuring the PHY.
- * In this case, we cannot access the PHY until the
- * configuration is done. So we explicitly set the
- * PHY ID.
- */
- phy->id = IGP01E1000_I_PHY_ID;
- break;
- case e1000_82573:
- return e1000e_get_phy_id(hw);
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000_get_hw_semaphore_82571 - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM
- **/
-static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
-{
- u32 swsm;
- s32 timeout = hw->nvm.word_size + 1;
- s32 i = 0;
-
- /* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
- swsm = er32(SWSM);
- ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (er32(SWSM) & E1000_SWSM_SWESMBI)
- break;
-
- udelay(50);
- }
-
- if (i == timeout) {
- /* Release semaphores */
- e1000e_put_hw_semaphore(hw);
- hw_dbg(hw, "Driver can't access the NVM\n");
- return -E1000_ERR_NVM;
- }
-
- return 0;
-}
-
-/**
- * e1000_put_hw_semaphore_82571 - Release hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Release hardware semaphore used to access the PHY or NVM
- **/
-static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
-{
- u32 swsm;
-
- swsm = er32(SWSM);
-
- swsm &= ~E1000_SWSM_SWESMBI;
-
- ew32(SWSM, swsm);
-}
-
-/**
- * e1000_acquire_nvm_82571 - Request for access to the EEPROM
- * @hw: pointer to the HW structure
- *
- * To gain access to the EEPROM, first we must obtain a hardware semaphore.
- * Then for non-82573 hardware, set the EEPROM access request bit and wait
- * for EEPROM access grant bit. If the access grant bit is not set, release
- * hardware semaphore.
- **/
-static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- ret_val = e1000_get_hw_semaphore_82571(hw);
- if (ret_val)
- return ret_val;
-
- if (hw->mac.type != e1000_82573)
- ret_val = e1000e_acquire_nvm(hw);
-
- if (ret_val)
- e1000_put_hw_semaphore_82571(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_release_nvm_82571 - Release exclusive access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Stop any current commands to the EEPROM and clear the EEPROM request bit.
- **/
-static void e1000_release_nvm_82571(struct e1000_hw *hw)
-{
- e1000e_release_nvm(hw);
- e1000_put_hw_semaphore_82571(hw);
-}
-
-/**
- * e1000_write_nvm_82571 - Write to EEPROM using appropriate interface
- * @hw: pointer to the HW structure
- * @offset: offset within the EEPROM to be written to
- * @words: number of words to write
- * @data: 16 bit word(s) to be written to the EEPROM
- *
- * For non-82573 silicon, write data to EEPROM at offset using SPI interface.
- *
- * If e1000e_update_nvm_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
- **/
-static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- s32 ret_val;
-
- switch (hw->mac.type) {
- case e1000_82573:
- ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);
- break;
- case e1000_82571:
- case e1000_82572:
- ret_val = e1000e_write_nvm_spi(hw, offset, words, data);
- break;
- default:
- ret_val = -E1000_ERR_NVM;
- break;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_update_nvm_checksum_82571 - Update EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Updates the EEPROM checksum by reading/adding each word of the EEPROM
- * up to the checksum. Then calculates the EEPROM checksum and writes the
- * value to the EEPROM.
- **/
-static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
-{
- u32 eecd;
- s32 ret_val;
- u16 i;
-
- ret_val = e1000e_update_nvm_checksum_generic(hw);
- if (ret_val)
- return ret_val;
-
- /*
- * If our nvm is an EEPROM, then we're done
- * otherwise, commit the checksum to the flash NVM.
- */
- if (hw->nvm.type != e1000_nvm_flash_hw)
- return ret_val;
-
- /* Check for pending operations. */
- for (i = 0; i < E1000_FLASH_UPDATES; i++) {
- msleep(1);
- if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
- break;
- }
-
- if (i == E1000_FLASH_UPDATES)
- return -E1000_ERR_NVM;
-
- /* Reset the firmware if using STM opcode. */
- if ((er32(FLOP) & 0xFF00) == E1000_STM_OPCODE) {
- /*
- * The enabling of and the actual reset must be done
- * in two write cycles.
- */
- ew32(HICR, E1000_HICR_FW_RESET_ENABLE);
- e1e_flush();
- ew32(HICR, E1000_HICR_FW_RESET);
- }
-
- /* Commit the write to flash */
- eecd = er32(EECD) | E1000_EECD_FLUPD;
- ew32(EECD, eecd);
-
- for (i = 0; i < E1000_FLASH_UPDATES; i++) {
- msleep(1);
- if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
- break;
- }
-
- if (i == E1000_FLASH_UPDATES)
- return -E1000_ERR_NVM;
-
- return 0;
-}
-
-/**
- * e1000_validate_nvm_checksum_82571 - Validate EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
- * and then verifies that the sum of the EEPROM is equal to 0xBABA.
- **/
-static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw)
-{
- if (hw->nvm.type == e1000_nvm_flash_hw)
- e1000_fix_nvm_checksum_82571(hw);
-
- return e1000e_validate_nvm_checksum_generic(hw);
-}
-
-/**
- * e1000_write_nvm_eewr_82571 - Write to EEPROM for 82573 silicon
- * @hw: pointer to the HW structure
- * @offset: offset within the EEPROM to be written to
- * @words: number of words to write
- * @data: 16 bit word(s) to be written to the EEPROM
- *
- * After checking for invalid values, poll the EEPROM to ensure the previous
- * command has completed before trying to write the next word. After write
- * poll for completion.
- *
- * If e1000e_update_nvm_checksum is not called after this function, the
- * EEPROM will most likely contain an invalid checksum.
- **/
-static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
- u16 words, u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 i;
- u32 eewr = 0;
- s32 ret_val = 0;
-
- /*
- * A check for invalid values: offset too large, too many words,
- * and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- hw_dbg(hw, "nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- for (i = 0; i < words; i++) {
- eewr = (data[i] << E1000_NVM_RW_REG_DATA) |
- ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
- E1000_NVM_RW_REG_START;
-
- ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);
- if (ret_val)
- break;
-
- ew32(EEWR, eewr);
-
- ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);
- if (ret_val)
- break;
- }
-
- return ret_val;
-}
-
-/**
- * e1000_get_cfg_done_82571 - Poll for configuration done
- * @hw: pointer to the HW structure
- *
- * Reads the management control register for the config done bit to be set.
- **/
-static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw)
-{
- s32 timeout = PHY_CFG_TIMEOUT;
-
- while (timeout) {
- if (er32(EEMNGCTL) &
- E1000_NVM_CFG_DONE_PORT_0)
- break;
- msleep(1);
- timeout--;
- }
- if (!timeout) {
- hw_dbg(hw, "MNG configuration cycle has not completed.\n");
- return -E1000_ERR_RESET;
- }
-
- return 0;
-}
-
-/**
- * e1000_set_d0_lplu_state_82571 - Set Low Power Linkup D0 state
- * @hw: pointer to the HW structure
- * @active: TRUE to enable LPLU, FALSE to disable
- *
- * Sets the LPLU D0 state according to the active flag. When activating LPLU
- * this function also disables smart speed and vice versa. LPLU will not be
- * activated unless the device autonegotiation advertisement meets standards
- * of either 10 or 10/100 or 10/100/1000 at all duplexes. This is a function
- * pointer entry point only called by PHY setup routines.
- **/
-static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data);
- if (ret_val)
- return ret_val;
-
- if (active) {
- data |= IGP02E1000_PM_D0_LPLU;
- ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
- if (ret_val)
- return ret_val;
-
- /* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
- if (ret_val)
- return ret_val;
- } else {
- data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
- /*
- * LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- } else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- }
- }
-
- return 0;
-}
-
-/**
- * e1000_reset_hw_82571 - Reset hardware
- * @hw: pointer to the HW structure
- *
- * This resets the hardware into a known state. This is a
- * function pointer entry point called by the api module.
- **/
-static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
-{
- u32 ctrl;
- u32 extcnf_ctrl;
- u32 ctrl_ext;
- u32 icr;
- s32 ret_val;
- u16 i = 0;
-
- /*
- * Prevent the PCI-E bus from sticking if there is no TLP connection
- * on the last TLP read/write transaction when MAC is reset.
- */
- ret_val = e1000e_disable_pcie_master(hw);
- if (ret_val)
- hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
-
- hw_dbg(hw, "Masking off all interrupts\n");
- ew32(IMC, 0xffffffff);
-
- ew32(RCTL, 0);
- ew32(TCTL, E1000_TCTL_PSP);
- e1e_flush();
-
- msleep(10);
-
- /*
- * Must acquire the MDIO ownership before MAC reset.
- * Ownership defaults to firmware after a reset.
- */
- if (hw->mac.type == e1000_82573) {
- extcnf_ctrl = er32(EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- do {
- ew32(EXTCNF_CTRL, extcnf_ctrl);
- extcnf_ctrl = er32(EXTCNF_CTRL);
-
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
- break;
-
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- msleep(2);
- i++;
- } while (i < MDIO_OWNERSHIP_TIMEOUT);
- }
-
- ctrl = er32(CTRL);
-
- hw_dbg(hw, "Issuing a global reset to MAC\n");
- ew32(CTRL, ctrl | E1000_CTRL_RST);
-
- if (hw->nvm.type == e1000_nvm_flash_hw) {
- udelay(10);
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- ew32(CTRL_EXT, ctrl_ext);
- e1e_flush();
- }
-
- ret_val = e1000e_get_auto_rd_done(hw);
- if (ret_val)
- /* We don't want to continue accessing MAC registers. */
- return ret_val;
-
- /*
- * Phy configuration from NVM just starts after EECD_AUTO_RD is set.
- * Need to wait for Phy configuration completion before accessing
- * NVM and Phy.
- */
- if (hw->mac.type == e1000_82573)
- msleep(25);
-
- /* Clear any pending interrupt events. */
- ew32(IMC, 0xffffffff);
- icr = er32(ICR);
-
- if (hw->mac.type == e1000_82571 &&
- hw->dev_spec.e82571.alt_mac_addr_is_present)
- e1000e_set_laa_state_82571(hw, true);
-
- return 0;
-}
-
-/**
- * e1000_init_hw_82571 - Initialize hardware
- * @hw: pointer to the HW structure
- *
- * This inits the hardware readying it for operation.
- **/
-static s32 e1000_init_hw_82571(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 reg_data;
- s32 ret_val;
- u16 i;
- u16 rar_count = mac->rar_entry_count;
-
- e1000_initialize_hw_bits_82571(hw);
-
- /* Initialize identification LED */
- ret_val = e1000e_id_led_init(hw);
- if (ret_val) {
- hw_dbg(hw, "Error initializing identification LED\n");
- return ret_val;
- }
-
- /* Disabling VLAN filtering */
- hw_dbg(hw, "Initializing the IEEE VLAN\n");
- e1000e_clear_vfta(hw);
-
- /* Setup the receive address. */
- /*
- * If, however, a locally administered address was assigned to the
- * 82571, we must reserve a RAR for it to work around an issue where
- * resetting one port will reload the MAC on the other port.
- */
- if (e1000e_get_laa_state_82571(hw))
- rar_count--;
- e1000e_init_rx_addrs(hw, rar_count);
-
- /* Zero out the Multicast HASH table */
- hw_dbg(hw, "Zeroing the MTA\n");
- for (i = 0; i < mac->mta_reg_count; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
-
- /* Setup link and flow control */
- ret_val = e1000_setup_link_82571(hw);
-
- /* Set the transmit descriptor write-back policy */
- reg_data = er32(TXDCTL(0));
- reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
- E1000_TXDCTL_FULL_TX_DESC_WB |
- E1000_TXDCTL_COUNT_DESC;
- ew32(TXDCTL(0), reg_data);
-
- /* ...for both queues. */
- if (mac->type != e1000_82573) {
- reg_data = er32(TXDCTL(1));
- reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
- E1000_TXDCTL_FULL_TX_DESC_WB |
- E1000_TXDCTL_COUNT_DESC;
- ew32(TXDCTL(1), reg_data);
- } else {
- e1000e_enable_tx_pkt_filtering(hw);
- reg_data = er32(GCR);
- reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
- ew32(GCR, reg_data);
- }
-
- /*
- * Clear all of the statistics registers (clear on read). It is
- * important that we do this after we have tried to establish link
- * because the symbol error count will increment wildly if there
- * is no link.
- */
- e1000_clear_hw_cntrs_82571(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_initialize_hw_bits_82571 - Initialize hardware-dependent bits
- * @hw: pointer to the HW structure
- *
- * Initializes required hardware-dependent bits needed for normal operation.
- **/
-static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
-{
- u32 reg;
-
- /* Transmit Descriptor Control 0 */
- reg = er32(TXDCTL(0));
- reg |= (1 << 22);
- ew32(TXDCTL(0), reg);
-
- /* Transmit Descriptor Control 1 */
- reg = er32(TXDCTL(1));
- reg |= (1 << 22);
- ew32(TXDCTL(1), reg);
-
- /* Transmit Arbitration Control 0 */
- reg = er32(TARC(0));
- reg &= ~(0xF << 27); /* 30:27 */
- switch (hw->mac.type) {
- case e1000_82571:
- case e1000_82572:
- reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26);
- break;
- default:
- break;
- }
- ew32(TARC(0), reg);
-
- /* Transmit Arbitration Control 1 */
- reg = er32(TARC(1));
- switch (hw->mac.type) {
- case e1000_82571:
- case e1000_82572:
- reg &= ~((1 << 29) | (1 << 30));
- reg |= (1 << 22) | (1 << 24) | (1 << 25) | (1 << 26);
- if (er32(TCTL) & E1000_TCTL_MULR)
- reg &= ~(1 << 28);
- else
- reg |= (1 << 28);
- ew32(TARC(1), reg);
- break;
- default:
- break;
- }
-
- /* Device Control */
- if (hw->mac.type == e1000_82573) {
- reg = er32(CTRL);
- reg &= ~(1 << 29);
- ew32(CTRL, reg);
- }
-
- /* Extended Device Control */
- if (hw->mac.type == e1000_82573) {
- reg = er32(CTRL_EXT);
- reg &= ~(1 << 23);
- reg |= (1 << 22);
- ew32(CTRL_EXT, reg);
- }
-}
-
-/**
- * e1000e_clear_vfta - Clear VLAN filter table
- * @hw: pointer to the HW structure
- *
- * Clears the register array which contains the VLAN filter table by
- * setting all the values to 0.
- **/
-void e1000e_clear_vfta(struct e1000_hw *hw)
-{
- u32 offset;
- u32 vfta_value = 0;
- u32 vfta_offset = 0;
- u32 vfta_bit_in_reg = 0;
-
- if (hw->mac.type == e1000_82573) {
- if (hw->mng_cookie.vlan_id != 0) {
- /*
- * The VFTA is a 4096b bit-field, each identifying
- * a single VLAN ID. The following operations
- * determine which 32b entry (i.e. offset) into the
- * array we want to set the VLAN ID (i.e. bit) of
- * the manageability unit.
- */
- vfta_offset = (hw->mng_cookie.vlan_id >>
- E1000_VFTA_ENTRY_SHIFT) &
- E1000_VFTA_ENTRY_MASK;
- vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
- E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
- }
- }
- for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
- /*
- * If the offset we want to clear is the same offset of the
- * manageability VLAN ID, then clear all bits except that of
- * the manageability unit.
- */
- vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
- E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, vfta_value);
- e1e_flush();
- }
-}
-
-/**
- * e1000_update_mc_addr_list_82571 - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
- *
- * Updates the Receive Address Registers and Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this.
- **/
-static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
- u8 *mc_addr_list,
- u32 mc_addr_count,
- u32 rar_used_count,
- u32 rar_count)
-{
- if (e1000e_get_laa_state_82571(hw))
- rar_count--;
-
- e1000e_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count,
- rar_used_count, rar_count);
-}
-
-/**
- * e1000_setup_link_82571 - Setup flow control and link settings
- * @hw: pointer to the HW structure
- *
- * Determines which flow control settings to use, then configures flow
- * control. Calls the appropriate media-specific link configuration
- * function. Assuming the adapter has a valid link partner, a valid link
- * should be established. Assumes the hardware has previously been reset
- * and the transmitter and receiver are not enabled.
- **/
-static s32 e1000_setup_link_82571(struct e1000_hw *hw)
-{
- /*
- * 82573 does not have a word in the NVM to determine
- * the default flow control setting, so we explicitly
- * set it to full.
- */
- if (hw->mac.type == e1000_82573)
- hw->fc.type = e1000_fc_full;
-
- return e1000e_setup_link(hw);
-}
-
-/**
- * e1000_setup_copper_link_82571 - Configure copper link settings
- * @hw: pointer to the HW structure
- *
- * Configures the link for auto-neg or forced speed and duplex. Then we check
- * for link, once link is established calls to configure collision distance
- * and flow control are called.
- **/
-static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
-{
- u32 ctrl;
- u32 led_ctrl;
- s32 ret_val;
-
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_SLU;
- ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ew32(CTRL, ctrl);
-
- switch (hw->phy.type) {
- case e1000_phy_m88:
- ret_val = e1000e_copper_link_setup_m88(hw);
- break;
- case e1000_phy_igp_2:
- ret_val = e1000e_copper_link_setup_igp(hw);
- /* Setup activity LED */
- led_ctrl = er32(LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- ew32(LEDCTL, led_ctrl);
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
-
- if (ret_val)
- return ret_val;
-
- ret_val = e1000e_setup_copper_link(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_setup_fiber_serdes_link_82571 - Setup link for fiber/serdes
- * @hw: pointer to the HW structure
- *
- * Configures collision distance and flow control for fiber and serdes links.
- * Upon successful setup, poll for link.
- **/
-static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
-{
- switch (hw->mac.type) {
- case e1000_82571:
- case e1000_82572:
- /*
- * If SerDes loopback mode is entered, there is no form
- * of reset to take the adapter out of that mode. So we
- * have to explicitly take the adapter out of loopback
- * mode. This prevents drivers from twiddling their thumbs
- * if another tool failed to take it out of loopback mode.
- */
- ew32(SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
- break;
- default:
- break;
- }
-
- return e1000e_setup_fiber_serdes_link(hw);
-}
-
-/**
- * e1000_valid_led_default_82571 - Verify a valid default LED config
- * @hw: pointer to the HW structure
- * @data: pointer to the NVM (EEPROM)
- *
- * Read the EEPROM for the current default LED configuration. If the
- * LED configuration is not valid, set to a valid LED configuration.
- **/
-static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
-{
- s32 ret_val;
-
- ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
-
- if (hw->mac.type == e1000_82573 &&
- *data == ID_LED_RESERVED_F746)
- *data = ID_LED_DEFAULT_82573;
- else if (*data == ID_LED_RESERVED_0000 ||
- *data == ID_LED_RESERVED_FFFF)
- *data = ID_LED_DEFAULT;
-
- return 0;
-}
-
-/**
- * e1000e_get_laa_state_82571 - Get locally administered address state
- * @hw: pointer to the HW structure
- *
- * Retrieve and return the current locally administered address state.
- **/
-bool e1000e_get_laa_state_82571(struct e1000_hw *hw)
-{
- if (hw->mac.type != e1000_82571)
- return 0;
-
- return hw->dev_spec.e82571.laa_is_present;
-}
-
-/**
- * e1000e_set_laa_state_82571 - Set locally administered address state
- * @hw: pointer to the HW structure
- * @state: enable/disable locally administered address
- *
- * Enable/Disable the current locally administers address state.
- **/
-void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state)
-{
- if (hw->mac.type != e1000_82571)
- return;
-
- hw->dev_spec.e82571.laa_is_present = state;
-
- /* If workaround is activated... */
- if (state)
- /*
- * Hold a copy of the LAA in RAR[14] This is done so that
- * between the time RAR[0] gets clobbered and the time it
- * gets fixed, the actual LAA is in one of the RARs and no
- * incoming packets directed to this port are dropped.
- * Eventually the LAA will be in RAR[0] and RAR[14].
- */
- e1000e_rar_set(hw, hw->mac.addr, hw->mac.rar_entry_count - 1);
-}
-
-/**
- * e1000_fix_nvm_checksum_82571 - Fix EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Verifies that the EEPROM has completed the update. After updating the
- * EEPROM, we need to check bit 15 in work 0x23 for the checksum fix. If
- * the checksum fix is not implemented, we need to set the bit and update
- * the checksum. Otherwise, if bit 15 is set and the checksum is incorrect,
- * we need to return bad checksum.
- **/
-static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- s32 ret_val;
- u16 data;
-
- if (nvm->type != e1000_nvm_flash_hw)
- return 0;
-
- /*
- * Check bit 4 of word 10h. If it is 0, firmware is done updating
- * 10h-12h. Checksum may need to be fixed.
- */
- ret_val = e1000_read_nvm(hw, 0x10, 1, &data);
- if (ret_val)
- return ret_val;
-
- if (!(data & 0x10)) {
- /*
- * Read 0x23 and check bit 15. This bit is a 1
- * when the checksum has already been fixed. If
- * the checksum is still wrong and this bit is a
- * 1, we need to return bad checksum. Otherwise,
- * we need to set this bit to a 1 and update the
- * checksum.
- */
- ret_val = e1000_read_nvm(hw, 0x23, 1, &data);
- if (ret_val)
- return ret_val;
-
- if (!(data & 0x8000)) {
- data |= 0x8000;
- ret_val = e1000_write_nvm(hw, 0x23, 1, &data);
- if (ret_val)
- return ret_val;
- ret_val = e1000e_update_nvm_checksum(hw);
- }
- }
-
- return 0;
-}
-
-/**
- * e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters
- * @hw: pointer to the HW structure
- *
- * Clears the hardware counters by reading the counter registers.
- **/
-static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
-{
- u32 temp;
-
- e1000e_clear_hw_cntrs_base(hw);
-
- temp = er32(PRC64);
- temp = er32(PRC127);
- temp = er32(PRC255);
- temp = er32(PRC511);
- temp = er32(PRC1023);
- temp = er32(PRC1522);
- temp = er32(PTC64);
- temp = er32(PTC127);
- temp = er32(PTC255);
- temp = er32(PTC511);
- temp = er32(PTC1023);
- temp = er32(PTC1522);
-
- temp = er32(ALGNERRC);
- temp = er32(RXERRC);
- temp = er32(TNCRS);
- temp = er32(CEXTERR);
- temp = er32(TSCTC);
- temp = er32(TSCTFC);
-
- temp = er32(MGTPRC);
- temp = er32(MGTPDC);
- temp = er32(MGTPTC);
-
- temp = er32(IAC);
- temp = er32(ICRXOC);
-
- temp = er32(ICRXPTC);
- temp = er32(ICRXATC);
- temp = er32(ICTXPTC);
- temp = er32(ICTXATC);
- temp = er32(ICTXQEC);
- temp = er32(ICTXQMTC);
- temp = er32(ICRXDMTC);
-}
-
-static struct e1000_mac_operations e82571_mac_ops = {
- .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT,
- /* .check_for_link: media type dependent */
- .cleanup_led = e1000e_cleanup_led_generic,
- .clear_hw_cntrs = e1000_clear_hw_cntrs_82571,
- .get_bus_info = e1000e_get_bus_info_pcie,
- /* .get_link_up_info: media type dependent */
- .led_on = e1000e_led_on_generic,
- .led_off = e1000e_led_off_generic,
- .update_mc_addr_list = e1000_update_mc_addr_list_82571,
- .reset_hw = e1000_reset_hw_82571,
- .init_hw = e1000_init_hw_82571,
- .setup_link = e1000_setup_link_82571,
- /* .setup_physical_interface: media type dependent */
-};
-
-static struct e1000_phy_operations e82_phy_ops_igp = {
- .acquire_phy = e1000_get_hw_semaphore_82571,
- .check_reset_block = e1000e_check_reset_block_generic,
- .commit_phy = NULL,
- .force_speed_duplex = e1000e_phy_force_speed_duplex_igp,
- .get_cfg_done = e1000_get_cfg_done_82571,
- .get_cable_length = e1000e_get_cable_length_igp_2,
- .get_phy_info = e1000e_get_phy_info_igp,
- .read_phy_reg = e1000e_read_phy_reg_igp,
- .release_phy = e1000_put_hw_semaphore_82571,
- .reset_phy = e1000e_phy_hw_reset_generic,
- .set_d0_lplu_state = e1000_set_d0_lplu_state_82571,
- .set_d3_lplu_state = e1000e_set_d3_lplu_state,
- .write_phy_reg = e1000e_write_phy_reg_igp,
-};
-
-static struct e1000_phy_operations e82_phy_ops_m88 = {
- .acquire_phy = e1000_get_hw_semaphore_82571,
- .check_reset_block = e1000e_check_reset_block_generic,
- .commit_phy = e1000e_phy_sw_reset,
- .force_speed_duplex = e1000e_phy_force_speed_duplex_m88,
- .get_cfg_done = e1000e_get_cfg_done,
- .get_cable_length = e1000e_get_cable_length_m88,
- .get_phy_info = e1000e_get_phy_info_m88,
- .read_phy_reg = e1000e_read_phy_reg_m88,
- .release_phy = e1000_put_hw_semaphore_82571,
- .reset_phy = e1000e_phy_hw_reset_generic,
- .set_d0_lplu_state = e1000_set_d0_lplu_state_82571,
- .set_d3_lplu_state = e1000e_set_d3_lplu_state,
- .write_phy_reg = e1000e_write_phy_reg_m88,
-};
-
-static struct e1000_nvm_operations e82571_nvm_ops = {
- .acquire_nvm = e1000_acquire_nvm_82571,
- .read_nvm = e1000e_read_nvm_eerd,
- .release_nvm = e1000_release_nvm_82571,
- .update_nvm = e1000_update_nvm_checksum_82571,
- .valid_led_default = e1000_valid_led_default_82571,
- .validate_nvm = e1000_validate_nvm_checksum_82571,
- .write_nvm = e1000_write_nvm_82571,
-};
-
-struct e1000_info e1000_82571_info = {
- .mac = e1000_82571,
- .flags = FLAG_HAS_HW_VLAN_FILTER
- | FLAG_HAS_JUMBO_FRAMES
- | FLAG_HAS_WOL
- | FLAG_APME_IN_CTRL3
- | FLAG_RX_CSUM_ENABLED
- | FLAG_HAS_CTRLEXT_ON_LOAD
- | FLAG_HAS_SMART_POWER_DOWN
- | FLAG_RESET_OVERWRITES_LAA /* errata */
- | FLAG_TARC_SPEED_MODE_BIT /* errata */
- | FLAG_APME_CHECK_PORT_B,
- .pba = 38,
- .get_variants = e1000_get_variants_82571,
- .mac_ops = &e82571_mac_ops,
- .phy_ops = &e82_phy_ops_igp,
- .nvm_ops = &e82571_nvm_ops,
-};
-
-struct e1000_info e1000_82572_info = {
- .mac = e1000_82572,
- .flags = FLAG_HAS_HW_VLAN_FILTER
- | FLAG_HAS_JUMBO_FRAMES
- | FLAG_HAS_WOL
- | FLAG_APME_IN_CTRL3
- | FLAG_RX_CSUM_ENABLED
- | FLAG_HAS_CTRLEXT_ON_LOAD
- | FLAG_TARC_SPEED_MODE_BIT, /* errata */
- .pba = 38,
- .get_variants = e1000_get_variants_82571,
- .mac_ops = &e82571_mac_ops,
- .phy_ops = &e82_phy_ops_igp,
- .nvm_ops = &e82571_nvm_ops,
-};
-
-struct e1000_info e1000_82573_info = {
- .mac = e1000_82573,
- .flags = FLAG_HAS_HW_VLAN_FILTER
- | FLAG_HAS_JUMBO_FRAMES
- | FLAG_HAS_WOL
- | FLAG_APME_IN_CTRL3
- | FLAG_RX_CSUM_ENABLED
- | FLAG_HAS_SMART_POWER_DOWN
- | FLAG_HAS_AMT
- | FLAG_HAS_ERT
- | FLAG_HAS_SWSM_ON_LOAD,
- .pba = 20,
- .get_variants = e1000_get_variants_82571,
- .mac_ops = &e82571_mac_ops,
- .phy_ops = &e82_phy_ops_m88,
- .nvm_ops = &e82571_nvm_ops,
-};
-
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
deleted file mode 100644
index 5ea6b60fa37..00000000000
--- a/drivers/net/e1000e/e1000.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/* Linux PRO/1000 Ethernet Driver main header file */
-
-#ifndef _E1000_H_
-#define _E1000_H_
-
-#include <linux/types.h>
-#include <linux/timer.h>
-#include <linux/workqueue.h>
-#include <linux/io.h>
-#include <linux/netdevice.h>
-
-#include "hw.h"
-
-struct e1000_info;
-
-#define e_printk(level, adapter, format, arg...) \
- printk(level "%s: %s: " format, pci_name(adapter->pdev), \
- adapter->netdev->name, ## arg)
-
-#ifdef DEBUG
-#define e_dbg(format, arg...) \
- e_printk(KERN_DEBUG , adapter, format, ## arg)
-#else
-#define e_dbg(format, arg...) do { (void)(adapter); } while (0)
-#endif
-
-#define e_err(format, arg...) \
- e_printk(KERN_ERR, adapter, format, ## arg)
-#define e_info(format, arg...) \
- e_printk(KERN_INFO, adapter, format, ## arg)
-#define e_warn(format, arg...) \
- e_printk(KERN_WARNING, adapter, format, ## arg)
-#define e_notice(format, arg...) \
- e_printk(KERN_NOTICE, adapter, format, ## arg)
-
-
-/* Tx/Rx descriptor defines */
-#define E1000_DEFAULT_TXD 256
-#define E1000_MAX_TXD 4096
-#define E1000_MIN_TXD 64
-
-#define E1000_DEFAULT_RXD 256
-#define E1000_MAX_RXD 4096
-#define E1000_MIN_RXD 64
-
-#define E1000_MIN_ITR_USECS 10 /* 100000 irq/sec */
-#define E1000_MAX_ITR_USECS 10000 /* 100 irq/sec */
-
-/* Early Receive defines */
-#define E1000_ERT_2048 0x100
-
-#define E1000_FC_PAUSE_TIME 0x0680 /* 858 usec */
-
-/* How many Tx Descriptors do we need to call netif_wake_queue ? */
-/* How many Rx Buffers do we bundle into one write to the hardware ? */
-#define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
-
-#define AUTO_ALL_MODES 0
-#define E1000_EEPROM_APME 0x0400
-
-#define E1000_MNG_VLAN_NONE (-1)
-
-/* Number of packet split data buffers (not including the header buffer) */
-#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
-
-enum e1000_boards {
- board_82571,
- board_82572,
- board_82573,
- board_80003es2lan,
- board_ich8lan,
- board_ich9lan,
-};
-
-struct e1000_queue_stats {
- u64 packets;
- u64 bytes;
-};
-
-struct e1000_ps_page {
- struct page *page;
- u64 dma; /* must be u64 - written to hw */
-};
-
-/*
- * wrappers around a pointer to a socket buffer,
- * so a DMA handle can be stored along with the buffer
- */
-struct e1000_buffer {
- dma_addr_t dma;
- struct sk_buff *skb;
- union {
- /* Tx */
- struct {
- unsigned long time_stamp;
- u16 length;
- u16 next_to_watch;
- };
- /* Rx */
- /* arrays of page information for packet split */
- struct e1000_ps_page *ps_pages;
- };
- struct page *page;
-};
-
-struct e1000_ring {
- void *desc; /* pointer to ring memory */
- dma_addr_t dma; /* phys address of ring */
- unsigned int size; /* length of ring in bytes */
- unsigned int count; /* number of desc. in ring */
-
- u16 next_to_use;
- u16 next_to_clean;
-
- u16 head;
- u16 tail;
-
- /* array of buffer information structs */
- struct e1000_buffer *buffer_info;
-
- struct sk_buff *rx_skb_top;
-
- struct e1000_queue_stats stats;
-};
-
-/* PHY register snapshot values */
-struct e1000_phy_regs {
- u16 bmcr; /* basic mode control register */
- u16 bmsr; /* basic mode status register */
- u16 advertise; /* auto-negotiation advertisement */
- u16 lpa; /* link partner ability register */
- u16 expansion; /* auto-negotiation expansion reg */
- u16 ctrl1000; /* 1000BASE-T control register */
- u16 stat1000; /* 1000BASE-T status register */
- u16 estatus; /* extended status register */
-};
-
-/* board specific private data structure */
-struct e1000_adapter {
- struct timer_list watchdog_timer;
- struct timer_list phy_info_timer;
- struct timer_list blink_timer;
-
- struct work_struct reset_task;
- struct work_struct watchdog_task;
-
- const struct e1000_info *ei;
-
- struct vlan_group *vlgrp;
- u32 bd_number;
- u32 rx_buffer_len;
- u16 mng_vlan_id;
- u16 link_speed;
- u16 link_duplex;
-
- spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
-
- /* track device up/down/testing state */
- unsigned long state;
-
- /* Interrupt Throttle Rate */
- u32 itr;
- u32 itr_setting;
- u16 tx_itr;
- u16 rx_itr;
-
- /*
- * Tx
- */
- struct e1000_ring *tx_ring /* One per active queue */
- ____cacheline_aligned_in_smp;
-
- struct napi_struct napi;
-
- unsigned long tx_queue_len;
- unsigned int restart_queue;
- u32 txd_cmd;
-
- bool detect_tx_hung;
- u8 tx_timeout_factor;
-
- u32 tx_int_delay;
- u32 tx_abs_int_delay;
-
- unsigned int total_tx_bytes;
- unsigned int total_tx_packets;
- unsigned int total_rx_bytes;
- unsigned int total_rx_packets;
-
- /* Tx stats */
- u64 tpt_old;
- u64 colc_old;
- u32 gotc;
- u64 gotc_old;
- u32 tx_timeout_count;
- u32 tx_fifo_head;
- u32 tx_head_addr;
- u32 tx_fifo_size;
- u32 tx_dma_failed;
-
- /*
- * Rx
- */
- bool (*clean_rx) (struct e1000_adapter *adapter,
- int *work_done, int work_to_do)
- ____cacheline_aligned_in_smp;
- void (*alloc_rx_buf) (struct e1000_adapter *adapter,
- int cleaned_count);
- struct e1000_ring *rx_ring;
-
- u32 rx_int_delay;
- u32 rx_abs_int_delay;
-
- /* Rx stats */
- u64 hw_csum_err;
- u64 hw_csum_good;
- u64 rx_hdr_split;
- u32 gorc;
- u64 gorc_old;
- u32 alloc_rx_buff_failed;
- u32 rx_dma_failed;
-
- unsigned int rx_ps_pages;
- u16 rx_ps_bsize0;
- u32 max_frame_size;
- u32 min_frame_size;
-
- /* OS defined structs */
- struct net_device *netdev;
- struct pci_dev *pdev;
- struct net_device_stats net_stats;
-
- /* structs defined in e1000_hw.h */
- struct e1000_hw hw;
-
- struct e1000_hw_stats stats;
- struct e1000_phy_info phy_info;
- struct e1000_phy_stats phy_stats;
-
- /* Snapshot of PHY registers */
- struct e1000_phy_regs phy_regs;
-
- struct e1000_ring test_tx_ring;
- struct e1000_ring test_rx_ring;
- u32 test_icr;
-
- u32 msg_enable;
-
- u32 eeprom_wol;
- u32 wol;
- u32 pba;
-
- bool fc_autoneg;
-
- unsigned long led_status;
-
- unsigned int flags;
- struct work_struct downshift_task;
- struct work_struct update_phy_task;
-};
-
-struct e1000_info {
- enum e1000_mac_type mac;
- unsigned int flags;
- u32 pba;
- s32 (*get_variants)(struct e1000_adapter *);
- struct e1000_mac_operations *mac_ops;
- struct e1000_phy_operations *phy_ops;
- struct e1000_nvm_operations *nvm_ops;
-};
-
-/* hardware capability, feature, and workaround flags */
-#define FLAG_HAS_AMT (1 << 0)
-#define FLAG_HAS_FLASH (1 << 1)
-#define FLAG_HAS_HW_VLAN_FILTER (1 << 2)
-#define FLAG_HAS_WOL (1 << 3)
-#define FLAG_HAS_ERT (1 << 4)
-#define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5)
-#define FLAG_HAS_SWSM_ON_LOAD (1 << 6)
-#define FLAG_HAS_JUMBO_FRAMES (1 << 7)
-#define FLAG_READ_ONLY_NVM (1 << 8)
-#define FLAG_IS_ICH (1 << 9)
-#define FLAG_HAS_SMART_POWER_DOWN (1 << 11)
-#define FLAG_IS_QUAD_PORT_A (1 << 12)
-#define FLAG_IS_QUAD_PORT (1 << 13)
-#define FLAG_TIPG_MEDIUM_FOR_80003ESLAN (1 << 14)
-#define FLAG_APME_IN_WUC (1 << 15)
-#define FLAG_APME_IN_CTRL3 (1 << 16)
-#define FLAG_APME_CHECK_PORT_B (1 << 17)
-#define FLAG_DISABLE_FC_PAUSE_TIME (1 << 18)
-#define FLAG_NO_WAKE_UCAST (1 << 19)
-#define FLAG_MNG_PT_ENABLED (1 << 20)
-#define FLAG_RESET_OVERWRITES_LAA (1 << 21)
-#define FLAG_TARC_SPEED_MODE_BIT (1 << 22)
-#define FLAG_TARC_SET_BIT_ZERO (1 << 23)
-#define FLAG_RX_NEEDS_RESTART (1 << 24)
-#define FLAG_LSC_GIG_SPEED_DROP (1 << 25)
-#define FLAG_SMART_POWER_DOWN (1 << 26)
-#define FLAG_MSI_ENABLED (1 << 27)
-#define FLAG_RX_CSUM_ENABLED (1 << 28)
-#define FLAG_TSO_FORCE (1 << 29)
-#define FLAG_RX_RESTART_NOW (1 << 30)
-#define FLAG_MSI_TEST_FAILED (1 << 31)
-
-#define E1000_RX_DESC_PS(R, i) \
- (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
-#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
-#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
-#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
-#define E1000_CONTEXT_DESC(R, i) E1000_GET_DESC(R, i, e1000_context_desc)
-
-enum e1000_state_t {
- __E1000_TESTING,
- __E1000_RESETTING,
- __E1000_DOWN
-};
-
-enum latency_range {
- lowest_latency = 0,
- low_latency = 1,
- bulk_latency = 2,
- latency_invalid = 255
-};
-
-extern char e1000e_driver_name[];
-extern const char e1000e_driver_version[];
-
-extern void e1000e_check_options(struct e1000_adapter *adapter);
-extern void e1000e_set_ethtool_ops(struct net_device *netdev);
-
-extern int e1000e_up(struct e1000_adapter *adapter);
-extern void e1000e_down(struct e1000_adapter *adapter);
-extern void e1000e_reinit_locked(struct e1000_adapter *adapter);
-extern void e1000e_reset(struct e1000_adapter *adapter);
-extern void e1000e_power_up_phy(struct e1000_adapter *adapter);
-extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter);
-extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter);
-extern void e1000e_free_rx_resources(struct e1000_adapter *adapter);
-extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
-extern void e1000e_update_stats(struct e1000_adapter *adapter);
-
-extern unsigned int copybreak;
-
-extern char *e1000e_get_hw_dev_name(struct e1000_hw *hw);
-
-extern struct e1000_info e1000_82571_info;
-extern struct e1000_info e1000_82572_info;
-extern struct e1000_info e1000_82573_info;
-extern struct e1000_info e1000_ich8_info;
-extern struct e1000_info e1000_ich9_info;
-extern struct e1000_info e1000_es2_info;
-
-extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
-
-extern s32 e1000e_commit_phy(struct e1000_hw *hw);
-
-extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw);
-
-extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw);
-extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state);
-
-extern void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw);
-extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
- bool state);
-extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
-extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
-extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
-
-extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
-extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
-extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
-extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
-extern s32 e1000e_led_on_generic(struct e1000_hw *hw);
-extern s32 e1000e_led_off_generic(struct e1000_hw *hw);
-extern s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw);
-extern s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex);
-extern s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex);
-extern s32 e1000e_disable_pcie_master(struct e1000_hw *hw);
-extern s32 e1000e_get_auto_rd_done(struct e1000_hw *hw);
-extern s32 e1000e_id_led_init(struct e1000_hw *hw);
-extern void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw);
-extern s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw);
-extern s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw);
-extern s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
-extern s32 e1000e_setup_link(struct e1000_hw *hw);
-extern void e1000e_clear_vfta(struct e1000_hw *hw);
-extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
-extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
- u8 *mc_addr_list,
- u32 mc_addr_count,
- u32 rar_used_count,
- u32 rar_count);
-extern void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
-extern s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
-extern void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);
-extern s32 e1000e_get_hw_semaphore(struct e1000_hw *hw);
-extern s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data);
-extern void e1000e_config_collision_dist(struct e1000_hw *hw);
-extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
-extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
-extern s32 e1000e_blink_led(struct e1000_hw *hw);
-extern void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
-extern void e1000e_reset_adaptive(struct e1000_hw *hw);
-extern void e1000e_update_adaptive(struct e1000_hw *hw);
-
-extern s32 e1000e_setup_copper_link(struct e1000_hw *hw);
-extern s32 e1000e_get_phy_id(struct e1000_hw *hw);
-extern void e1000e_put_hw_semaphore(struct e1000_hw *hw);
-extern s32 e1000e_check_reset_block_generic(struct e1000_hw *hw);
-extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw);
-extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw);
-extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw);
-extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
-extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw);
-extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active);
-extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
-extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw);
-extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw);
-extern s32 e1000e_get_cfg_done(struct e1000_hw *hw);
-extern s32 e1000e_get_cable_length_m88(struct e1000_hw *hw);
-extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw);
-extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
-extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
-extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
-extern s32 e1000e_determine_phy_address(struct e1000_hw *hw);
-extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
-extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
-extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
-extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
-extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
-extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
- u32 usec_interval, bool *success);
-extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
-extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
-extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
-extern s32 e1000e_check_downshift(struct e1000_hw *hw);
-
-static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
-{
- return hw->phy.ops.reset_phy(hw);
-}
-
-static inline s32 e1000_check_reset_block(struct e1000_hw *hw)
-{
- return hw->phy.ops.check_reset_block(hw);
-}
-
-static inline s32 e1e_rphy(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- return hw->phy.ops.read_phy_reg(hw, offset, data);
-}
-
-static inline s32 e1e_wphy(struct e1000_hw *hw, u32 offset, u16 data)
-{
- return hw->phy.ops.write_phy_reg(hw, offset, data);
-}
-
-static inline s32 e1000_get_cable_length(struct e1000_hw *hw)
-{
- return hw->phy.ops.get_cable_length(hw);
-}
-
-extern s32 e1000e_acquire_nvm(struct e1000_hw *hw);
-extern s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-extern s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw);
-extern s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
-extern s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
-extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw);
-extern void e1000e_release_nvm(struct e1000_hw *hw);
-extern void e1000e_reload_nvm(struct e1000_hw *hw);
-extern s32 e1000e_read_mac_addr(struct e1000_hw *hw);
-
-static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
-{
- return hw->nvm.ops.validate_nvm(hw);
-}
-
-static inline s32 e1000e_update_nvm_checksum(struct e1000_hw *hw)
-{
- return hw->nvm.ops.update_nvm(hw);
-}
-
-static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- return hw->nvm.ops.read_nvm(hw, offset, words, data);
-}
-
-static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- return hw->nvm.ops.write_nvm(hw, offset, words, data);
-}
-
-static inline s32 e1000_get_phy_info(struct e1000_hw *hw)
-{
- return hw->phy.ops.get_phy_info(hw);
-}
-
-extern bool e1000e_check_mng_mode(struct e1000_hw *hw);
-extern bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw);
-extern s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
-
-static inline u32 __er32(struct e1000_hw *hw, unsigned long reg)
-{
- return readl(hw->hw_addr + reg);
-}
-
-static inline void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
-{
- writel(val, hw->hw_addr + reg);
-}
-
-#endif /* _E1000_H_ */
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
deleted file mode 100644
index 74f263acb17..00000000000
--- a/drivers/net/e1000e/hw.h
+++ /dev/null
@@ -1,891 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#ifndef _E1000_HW_H_
-#define _E1000_HW_H_
-
-#include <linux/types.h>
-
-struct e1000_hw;
-struct e1000_adapter;
-
-#include "defines.h"
-
-#define er32(reg) __er32(hw, E1000_##reg)
-#define ew32(reg,val) __ew32(hw, E1000_##reg, (val))
-#define e1e_flush() er32(STATUS)
-
-#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \
- (writel((value), ((a)->hw_addr + reg + ((offset) << 2))))
-
-#define E1000_READ_REG_ARRAY(a, reg, offset) \
- (readl((a)->hw_addr + reg + ((offset) << 2)))
-
-enum e1e_registers {
- E1000_CTRL = 0x00000, /* Device Control - RW */
- E1000_STATUS = 0x00008, /* Device Status - RO */
- E1000_EECD = 0x00010, /* EEPROM/Flash Control - RW */
- E1000_EERD = 0x00014, /* EEPROM Read - RW */
- E1000_CTRL_EXT = 0x00018, /* Extended Device Control - RW */
- E1000_FLA = 0x0001C, /* Flash Access - RW */
- E1000_MDIC = 0x00020, /* MDI Control - RW */
- E1000_SCTL = 0x00024, /* SerDes Control - RW */
- E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */
- E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */
- E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */
- E1000_FCT = 0x00030, /* Flow Control Type - RW */
- E1000_VET = 0x00038, /* VLAN Ether Type - RW */
- E1000_ICR = 0x000C0, /* Interrupt Cause Read - R/clr */
- E1000_ITR = 0x000C4, /* Interrupt Throttling Rate - RW */
- E1000_ICS = 0x000C8, /* Interrupt Cause Set - WO */
- E1000_IMS = 0x000D0, /* Interrupt Mask Set - RW */
- E1000_IMC = 0x000D8, /* Interrupt Mask Clear - WO */
- E1000_IAM = 0x000E0, /* Interrupt Acknowledge Auto Mask */
- E1000_RCTL = 0x00100, /* Rx Control - RW */
- E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value - RW */
- E1000_TXCW = 0x00178, /* Tx Configuration Word - RW */
- E1000_RXCW = 0x00180, /* Rx Configuration Word - RO */
- E1000_TCTL = 0x00400, /* Tx Control - RW */
- E1000_TCTL_EXT = 0x00404, /* Extended Tx Control - RW */
- E1000_TIPG = 0x00410, /* Tx Inter-packet gap -RW */
- E1000_AIT = 0x00458, /* Adaptive Interframe Spacing Throttle -RW */
- E1000_LEDCTL = 0x00E00, /* LED Control - RW */
- E1000_EXTCNF_CTRL = 0x00F00, /* Extended Configuration Control */
- E1000_EXTCNF_SIZE = 0x00F08, /* Extended Configuration Size */
- E1000_PHY_CTRL = 0x00F10, /* PHY Control Register in CSR */
- E1000_PBA = 0x01000, /* Packet Buffer Allocation - RW */
- E1000_PBS = 0x01008, /* Packet Buffer Size */
- E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */
- E1000_EEWR = 0x0102C, /* EEPROM Write Register - RW */
- E1000_FLOP = 0x0103C, /* FLASH Opcode Register */
- E1000_ERT = 0x02008, /* Early Rx Threshold - RW */
- E1000_FCRTL = 0x02160, /* Flow Control Receive Threshold Low - RW */
- E1000_FCRTH = 0x02168, /* Flow Control Receive Threshold High - RW */
- E1000_PSRCTL = 0x02170, /* Packet Split Receive Control - RW */
- E1000_RDBAL = 0x02800, /* Rx Descriptor Base Address Low - RW */
- E1000_RDBAH = 0x02804, /* Rx Descriptor Base Address High - RW */
- E1000_RDLEN = 0x02808, /* Rx Descriptor Length - RW */
- E1000_RDH = 0x02810, /* Rx Descriptor Head - RW */
- E1000_RDT = 0x02818, /* Rx Descriptor Tail - RW */
- E1000_RDTR = 0x02820, /* Rx Delay Timer - RW */
- E1000_RXDCTL_BASE = 0x02828, /* Rx Descriptor Control - RW */
-#define E1000_RXDCTL(_n) (E1000_RXDCTL_BASE + (_n << 8))
- E1000_RADV = 0x0282C, /* RX Interrupt Absolute Delay Timer - RW */
-
-/* Convenience macros
- *
- * Note: "_n" is the queue number of the register to be written to.
- *
- * Example usage:
- * E1000_RDBAL_REG(current_rx_queue)
- *
- */
-#define E1000_RDBAL_REG(_n) (E1000_RDBAL + (_n << 8))
- E1000_KABGTXD = 0x03004, /* AFE Band Gap Transmit Ref Data */
- E1000_TDBAL = 0x03800, /* Tx Descriptor Base Address Low - RW */
- E1000_TDBAH = 0x03804, /* Tx Descriptor Base Address High - RW */
- E1000_TDLEN = 0x03808, /* Tx Descriptor Length - RW */
- E1000_TDH = 0x03810, /* Tx Descriptor Head - RW */
- E1000_TDT = 0x03818, /* Tx Descriptor Tail - RW */
- E1000_TIDV = 0x03820, /* Tx Interrupt Delay Value - RW */
- E1000_TXDCTL_BASE = 0x03828, /* Tx Descriptor Control - RW */
-#define E1000_TXDCTL(_n) (E1000_TXDCTL_BASE + (_n << 8))
- E1000_TADV = 0x0382C, /* Tx Interrupt Absolute Delay Val - RW */
- E1000_TARC_BASE = 0x03840, /* Tx Arbitration Count (0) */
-#define E1000_TARC(_n) (E1000_TARC_BASE + (_n << 8))
- E1000_CRCERRS = 0x04000, /* CRC Error Count - R/clr */
- E1000_ALGNERRC = 0x04004, /* Alignment Error Count - R/clr */
- E1000_SYMERRS = 0x04008, /* Symbol Error Count - R/clr */
- E1000_RXERRC = 0x0400C, /* Receive Error Count - R/clr */
- E1000_MPC = 0x04010, /* Missed Packet Count - R/clr */
- E1000_SCC = 0x04014, /* Single Collision Count - R/clr */
- E1000_ECOL = 0x04018, /* Excessive Collision Count - R/clr */
- E1000_MCC = 0x0401C, /* Multiple Collision Count - R/clr */
- E1000_LATECOL = 0x04020, /* Late Collision Count - R/clr */
- E1000_COLC = 0x04028, /* Collision Count - R/clr */
- E1000_DC = 0x04030, /* Defer Count - R/clr */
- E1000_TNCRS = 0x04034, /* Tx-No CRS - R/clr */
- E1000_SEC = 0x04038, /* Sequence Error Count - R/clr */
- E1000_CEXTERR = 0x0403C, /* Carrier Extension Error Count - R/clr */
- E1000_RLEC = 0x04040, /* Receive Length Error Count - R/clr */
- E1000_XONRXC = 0x04048, /* XON Rx Count - R/clr */
- E1000_XONTXC = 0x0404C, /* XON Tx Count - R/clr */
- E1000_XOFFRXC = 0x04050, /* XOFF Rx Count - R/clr */
- E1000_XOFFTXC = 0x04054, /* XOFF Tx Count - R/clr */
- E1000_FCRUC = 0x04058, /* Flow Control Rx Unsupported Count- R/clr */
- E1000_PRC64 = 0x0405C, /* Packets Rx (64 bytes) - R/clr */
- E1000_PRC127 = 0x04060, /* Packets Rx (65-127 bytes) - R/clr */
- E1000_PRC255 = 0x04064, /* Packets Rx (128-255 bytes) - R/clr */
- E1000_PRC511 = 0x04068, /* Packets Rx (255-511 bytes) - R/clr */
- E1000_PRC1023 = 0x0406C, /* Packets Rx (512-1023 bytes) - R/clr */
- E1000_PRC1522 = 0x04070, /* Packets Rx (1024-1522 bytes) - R/clr */
- E1000_GPRC = 0x04074, /* Good Packets Rx Count - R/clr */
- E1000_BPRC = 0x04078, /* Broadcast Packets Rx Count - R/clr */
- E1000_MPRC = 0x0407C, /* Multicast Packets Rx Count - R/clr */
- E1000_GPTC = 0x04080, /* Good Packets Tx Count - R/clr */
- E1000_GORCL = 0x04088, /* Good Octets Rx Count Low - R/clr */
- E1000_GORCH = 0x0408C, /* Good Octets Rx Count High - R/clr */
- E1000_GOTCL = 0x04090, /* Good Octets Tx Count Low - R/clr */
- E1000_GOTCH = 0x04094, /* Good Octets Tx Count High - R/clr */
- E1000_RNBC = 0x040A0, /* Rx No Buffers Count - R/clr */
- E1000_RUC = 0x040A4, /* Rx Undersize Count - R/clr */
- E1000_RFC = 0x040A8, /* Rx Fragment Count - R/clr */
- E1000_ROC = 0x040AC, /* Rx Oversize Count - R/clr */
- E1000_RJC = 0x040B0, /* Rx Jabber Count - R/clr */
- E1000_MGTPRC = 0x040B4, /* Management Packets Rx Count - R/clr */
- E1000_MGTPDC = 0x040B8, /* Management Packets Dropped Count - R/clr */
- E1000_MGTPTC = 0x040BC, /* Management Packets Tx Count - R/clr */
- E1000_TORL = 0x040C0, /* Total Octets Rx Low - R/clr */
- E1000_TORH = 0x040C4, /* Total Octets Rx High - R/clr */
- E1000_TOTL = 0x040C8, /* Total Octets Tx Low - R/clr */
- E1000_TOTH = 0x040CC, /* Total Octets Tx High - R/clr */
- E1000_TPR = 0x040D0, /* Total Packets Rx - R/clr */
- E1000_TPT = 0x040D4, /* Total Packets Tx - R/clr */
- E1000_PTC64 = 0x040D8, /* Packets Tx (64 bytes) - R/clr */
- E1000_PTC127 = 0x040DC, /* Packets Tx (65-127 bytes) - R/clr */
- E1000_PTC255 = 0x040E0, /* Packets Tx (128-255 bytes) - R/clr */
- E1000_PTC511 = 0x040E4, /* Packets Tx (256-511 bytes) - R/clr */
- E1000_PTC1023 = 0x040E8, /* Packets Tx (512-1023 bytes) - R/clr */
- E1000_PTC1522 = 0x040EC, /* Packets Tx (1024-1522 Bytes) - R/clr */
- E1000_MPTC = 0x040F0, /* Multicast Packets Tx Count - R/clr */
- E1000_BPTC = 0x040F4, /* Broadcast Packets Tx Count - R/clr */
- E1000_TSCTC = 0x040F8, /* TCP Segmentation Context Tx - R/clr */
- E1000_TSCTFC = 0x040FC, /* TCP Segmentation Context Tx Fail - R/clr */
- E1000_IAC = 0x04100, /* Interrupt Assertion Count */
- E1000_ICRXPTC = 0x04104, /* Irq Cause Rx Packet Timer Expire Count */
- E1000_ICRXATC = 0x04108, /* Irq Cause Rx Abs Timer Expire Count */
- E1000_ICTXPTC = 0x0410C, /* Irq Cause Tx Packet Timer Expire Count */
- E1000_ICTXATC = 0x04110, /* Irq Cause Tx Abs Timer Expire Count */
- E1000_ICTXQEC = 0x04118, /* Irq Cause Tx Queue Empty Count */
- E1000_ICTXQMTC = 0x0411C, /* Irq Cause Tx Queue MinThreshold Count */
- E1000_ICRXDMTC = 0x04120, /* Irq Cause Rx Desc MinThreshold Count */
- E1000_ICRXOC = 0x04124, /* Irq Cause Receiver Overrun Count */
- E1000_RXCSUM = 0x05000, /* Rx Checksum Control - RW */
- E1000_RFCTL = 0x05008, /* Receive Filter Control */
- E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */
- E1000_RA = 0x05400, /* Receive Address - RW Array */
- E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */
- E1000_WUC = 0x05800, /* Wakeup Control - RW */
- E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */
- E1000_WUS = 0x05810, /* Wakeup Status - RO */
- E1000_MANC = 0x05820, /* Management Control - RW */
- E1000_FFLT = 0x05F00, /* Flexible Filter Length Table - RW Array */
- E1000_HOST_IF = 0x08800, /* Host Interface */
-
- E1000_KMRNCTRLSTA = 0x00034, /* MAC-PHY interface - RW */
- E1000_MANC2H = 0x05860, /* Management Control To Host - RW */
- E1000_SW_FW_SYNC = 0x05B5C, /* Software-Firmware Synchronization - RW */
- E1000_GCR = 0x05B00, /* PCI-Ex Control */
- E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
- E1000_SWSM = 0x05B50, /* SW Semaphore */
- E1000_FWSM = 0x05B54, /* FW Semaphore */
- E1000_HICR = 0x08F00, /* Host Interface Control */
-};
-
-/* RSS registers */
-
-/* IGP01E1000 Specific Registers */
-#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
-#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
-#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
-#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
-#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
-#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
-#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
-#define IGP_PAGE_SHIFT 5
-#define PHY_REG_MASK 0x1F
-
-#define BM_WUC_PAGE 800
-#define BM_WUC_ADDRESS_OPCODE 0x11
-#define BM_WUC_DATA_OPCODE 0x12
-#define BM_WUC_ENABLE_PAGE 769
-#define BM_WUC_ENABLE_REG 17
-#define BM_WUC_ENABLE_BIT (1 << 2)
-#define BM_WUC_HOST_WU_BIT (1 << 4)
-
-#define BM_WUC PHY_REG(BM_WUC_PAGE, 1)
-#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
-#define BM_WUS PHY_REG(BM_WUC_PAGE, 3)
-
-#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
-#define IGP01E1000_PHY_POLARITY_MASK 0x0078
-
-#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
-#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
-
-#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
-
-#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
-#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
-#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
-
-#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
-
-#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
-#define IGP01E1000_PSSR_MDIX 0x0008
-#define IGP01E1000_PSSR_SPEED_MASK 0xC000
-#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
-
-#define IGP02E1000_PHY_CHANNEL_NUM 4
-#define IGP02E1000_PHY_AGC_A 0x11B1
-#define IGP02E1000_PHY_AGC_B 0x12B1
-#define IGP02E1000_PHY_AGC_C 0x14B1
-#define IGP02E1000_PHY_AGC_D 0x18B1
-
-#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
-#define IGP02E1000_AGC_LENGTH_MASK 0x7F
-#define IGP02E1000_AGC_RANGE 15
-
-/* manage.c */
-#define E1000_VFTA_ENTRY_SHIFT 5
-#define E1000_VFTA_ENTRY_MASK 0x7F
-#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
-
-#define E1000_HICR_EN 0x01 /* Enable bit - RO */
-/* Driver sets this bit when done to put command in RAM */
-#define E1000_HICR_C 0x02
-#define E1000_HICR_FW_RESET_ENABLE 0x40
-#define E1000_HICR_FW_RESET 0x80
-
-#define E1000_FWSM_MODE_MASK 0xE
-#define E1000_FWSM_MODE_SHIFT 1
-
-#define E1000_MNG_IAMT_MODE 0x3
-#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
-#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
-#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
-#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
-#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
-#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
-
-/* nvm.c */
-#define E1000_STM_OPCODE 0xDB00
-
-#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
-#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
-#define E1000_KMRNCTRLSTA_REN 0x00200000
-#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
-#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
-
-#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
-#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */
-#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */
-#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
-
-/* IFE PHY Extended Status Control */
-#define IFE_PESC_POLARITY_REVERSED 0x0100
-
-/* IFE PHY Special Control */
-#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
-#define IFE_PSC_FORCE_POLARITY 0x0020
-
-/* IFE PHY Special Control and LED Control */
-#define IFE_PSCL_PROBE_MODE 0x0020
-#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
-#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
-
-/* IFE PHY MDIX Control */
-#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
-#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
-#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */
-
-#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
-
-#define E1000_DEV_ID_82571EB_COPPER 0x105E
-#define E1000_DEV_ID_82571EB_FIBER 0x105F
-#define E1000_DEV_ID_82571EB_SERDES 0x1060
-#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
-#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
-#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
-#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
-#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
-#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
-#define E1000_DEV_ID_82572EI_COPPER 0x107D
-#define E1000_DEV_ID_82572EI_FIBER 0x107E
-#define E1000_DEV_ID_82572EI_SERDES 0x107F
-#define E1000_DEV_ID_82572EI 0x10B9
-#define E1000_DEV_ID_82573E 0x108B
-#define E1000_DEV_ID_82573E_IAMT 0x108C
-#define E1000_DEV_ID_82573L 0x109A
-
-#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
-#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
-#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
-#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
-
-#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
-#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
-#define E1000_DEV_ID_ICH8_IGP_C 0x104B
-#define E1000_DEV_ID_ICH8_IFE 0x104C
-#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
-#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
-#define E1000_DEV_ID_ICH8_IGP_M 0x104D
-#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD
-#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5
-#define E1000_DEV_ID_ICH9_IGP_M 0x10BF
-#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB
-#define E1000_DEV_ID_ICH9_IGP_C 0x294C
-#define E1000_DEV_ID_ICH9_IFE 0x10C0
-#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3
-#define E1000_DEV_ID_ICH9_IFE_G 0x10C2
-#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC
-#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD
-#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
-
-#define E1000_FUNC_1 1
-
-enum e1000_mac_type {
- e1000_82571,
- e1000_82572,
- e1000_82573,
- e1000_80003es2lan,
- e1000_ich8lan,
- e1000_ich9lan,
-};
-
-enum e1000_media_type {
- e1000_media_type_unknown = 0,
- e1000_media_type_copper = 1,
- e1000_media_type_fiber = 2,
- e1000_media_type_internal_serdes = 3,
- e1000_num_media_types
-};
-
-enum e1000_nvm_type {
- e1000_nvm_unknown = 0,
- e1000_nvm_none,
- e1000_nvm_eeprom_spi,
- e1000_nvm_flash_hw,
- e1000_nvm_flash_sw
-};
-
-enum e1000_nvm_override {
- e1000_nvm_override_none = 0,
- e1000_nvm_override_spi_small,
- e1000_nvm_override_spi_large
-};
-
-enum e1000_phy_type {
- e1000_phy_unknown = 0,
- e1000_phy_none,
- e1000_phy_m88,
- e1000_phy_igp,
- e1000_phy_igp_2,
- e1000_phy_gg82563,
- e1000_phy_igp_3,
- e1000_phy_ife,
- e1000_phy_bm,
-};
-
-enum e1000_bus_width {
- e1000_bus_width_unknown = 0,
- e1000_bus_width_pcie_x1,
- e1000_bus_width_pcie_x2,
- e1000_bus_width_pcie_x4 = 4,
- e1000_bus_width_32,
- e1000_bus_width_64,
- e1000_bus_width_reserved
-};
-
-enum e1000_1000t_rx_status {
- e1000_1000t_rx_status_not_ok = 0,
- e1000_1000t_rx_status_ok,
- e1000_1000t_rx_status_undefined = 0xFF
-};
-
-enum e1000_rev_polarity{
- e1000_rev_polarity_normal = 0,
- e1000_rev_polarity_reversed,
- e1000_rev_polarity_undefined = 0xFF
-};
-
-enum e1000_fc_type {
- e1000_fc_none = 0,
- e1000_fc_rx_pause,
- e1000_fc_tx_pause,
- e1000_fc_full,
- e1000_fc_default = 0xFF
-};
-
-enum e1000_ms_type {
- e1000_ms_hw_default = 0,
- e1000_ms_force_master,
- e1000_ms_force_slave,
- e1000_ms_auto
-};
-
-enum e1000_smart_speed {
- e1000_smart_speed_default = 0,
- e1000_smart_speed_on,
- e1000_smart_speed_off
-};
-
-/* Receive Descriptor */
-struct e1000_rx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- __le16 length; /* Length of data DMAed into data buffer */
- __le16 csum; /* Packet checksum */
- u8 status; /* Descriptor status */
- u8 errors; /* Descriptor Errors */
- __le16 special;
-};
-
-/* Receive Descriptor - Extended */
-union e1000_rx_desc_extended {
- struct {
- __le64 buffer_addr;
- __le64 reserved;
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length;
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-/* Receive Descriptor - Packet Split */
-union e1000_rx_desc_packet_split {
- struct {
- /* one buffer for protocol header(s), three data buffers */
- __le64 buffer_addr[MAX_PS_BUFFERS];
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length0; /* length of buffer 0 */
- __le16 vlan; /* VLAN tag */
- } middle;
- struct {
- __le16 header_status;
- __le16 length[3]; /* length of buffers 1-3 */
- } upper;
- __le64 reserved;
- } wb; /* writeback */
-};
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 cso; /* Checksum offset */
- u8 cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
- __le16 special;
- } fields;
- } upper;
-};
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
- union {
- __le32 ip_config;
- struct {
- u8 ipcss; /* IP checksum start */
- u8 ipcso; /* IP checksum offset */
- __le16 ipcse; /* IP checksum end */
- } ip_fields;
- } lower_setup;
- union {
- __le32 tcp_config;
- struct {
- u8 tucss; /* TCP checksum start */
- u8 tucso; /* TCP checksum offset */
- __le16 tucse; /* TCP checksum end */
- } tcp_fields;
- } upper_setup;
- __le32 cmd_and_length;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 hdr_len; /* Header length */
- __le16 mss; /* Maximum segment size */
- } fields;
- } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
- __le64 buffer_addr; /* Address of the descriptor's buffer address */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 typ_len_ext;
- u8 cmd;
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 popts; /* Packet Options */
- __le16 special; /* */
- } fields;
- } upper;
-};
-
-/* Statistics counters collected by the MAC */
-struct e1000_hw_stats {
- u64 crcerrs;
- u64 algnerrc;
- u64 symerrs;
- u64 rxerrc;
- u64 mpc;
- u64 scc;
- u64 ecol;
- u64 mcc;
- u64 latecol;
- u64 colc;
- u64 dc;
- u64 tncrs;
- u64 sec;
- u64 cexterr;
- u64 rlec;
- u64 xonrxc;
- u64 xontxc;
- u64 xoffrxc;
- u64 xofftxc;
- u64 fcruc;
- u64 prc64;
- u64 prc127;
- u64 prc255;
- u64 prc511;
- u64 prc1023;
- u64 prc1522;
- u64 gprc;
- u64 bprc;
- u64 mprc;
- u64 gptc;
- u64 gorc;
- u64 gotc;
- u64 rnbc;
- u64 ruc;
- u64 rfc;
- u64 roc;
- u64 rjc;
- u64 mgprc;
- u64 mgpdc;
- u64 mgptc;
- u64 tor;
- u64 tot;
- u64 tpr;
- u64 tpt;
- u64 ptc64;
- u64 ptc127;
- u64 ptc255;
- u64 ptc511;
- u64 ptc1023;
- u64 ptc1522;
- u64 mptc;
- u64 bptc;
- u64 tsctc;
- u64 tsctfc;
- u64 iac;
- u64 icrxptc;
- u64 icrxatc;
- u64 ictxptc;
- u64 ictxatc;
- u64 ictxqec;
- u64 ictxqmtc;
- u64 icrxdmtc;
- u64 icrxoc;
-};
-
-struct e1000_phy_stats {
- u32 idle_errors;
- u32 receive_errors;
-};
-
-struct e1000_host_mng_dhcp_cookie {
- u32 signature;
- u8 status;
- u8 reserved0;
- u16 vlan_id;
- u32 reserved1;
- u16 reserved2;
- u8 reserved3;
- u8 checksum;
-};
-
-/* Host Interface "Rev 1" */
-struct e1000_host_command_header {
- u8 command_id;
- u8 command_length;
- u8 command_options;
- u8 checksum;
-};
-
-#define E1000_HI_MAX_DATA_LENGTH 252
-struct e1000_host_command_info {
- struct e1000_host_command_header command_header;
- u8 command_data[E1000_HI_MAX_DATA_LENGTH];
-};
-
-/* Host Interface "Rev 2" */
-struct e1000_host_mng_command_header {
- u8 command_id;
- u8 checksum;
- u16 reserved1;
- u16 reserved2;
- u16 command_length;
-};
-
-#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
-struct e1000_host_mng_command_info {
- struct e1000_host_mng_command_header command_header;
- u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
-};
-
-/* Function pointers and static data for the MAC. */
-struct e1000_mac_operations {
- u32 mng_mode_enab;
-
- s32 (*check_for_link)(struct e1000_hw *);
- s32 (*cleanup_led)(struct e1000_hw *);
- void (*clear_hw_cntrs)(struct e1000_hw *);
- s32 (*get_bus_info)(struct e1000_hw *);
- s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
- s32 (*led_on)(struct e1000_hw *);
- s32 (*led_off)(struct e1000_hw *);
- void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
- s32 (*reset_hw)(struct e1000_hw *);
- s32 (*init_hw)(struct e1000_hw *);
- s32 (*setup_link)(struct e1000_hw *);
- s32 (*setup_physical_interface)(struct e1000_hw *);
-};
-
-/* Function pointers for the PHY. */
-struct e1000_phy_operations {
- s32 (*acquire_phy)(struct e1000_hw *);
- s32 (*check_reset_block)(struct e1000_hw *);
- s32 (*commit_phy)(struct e1000_hw *);
- s32 (*force_speed_duplex)(struct e1000_hw *);
- s32 (*get_cfg_done)(struct e1000_hw *hw);
- s32 (*get_cable_length)(struct e1000_hw *);
- s32 (*get_phy_info)(struct e1000_hw *);
- s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
- void (*release_phy)(struct e1000_hw *);
- s32 (*reset_phy)(struct e1000_hw *);
- s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
- s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
- s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
-};
-
-/* Function pointers for the NVM. */
-struct e1000_nvm_operations {
- s32 (*acquire_nvm)(struct e1000_hw *);
- s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
- void (*release_nvm)(struct e1000_hw *);
- s32 (*update_nvm)(struct e1000_hw *);
- s32 (*valid_led_default)(struct e1000_hw *, u16 *);
- s32 (*validate_nvm)(struct e1000_hw *);
- s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
-};
-
-struct e1000_mac_info {
- struct e1000_mac_operations ops;
-
- u8 addr[6];
- u8 perm_addr[6];
-
- enum e1000_mac_type type;
-
- u32 collision_delta;
- u32 ledctl_default;
- u32 ledctl_mode1;
- u32 ledctl_mode2;
- u32 mc_filter_type;
- u32 tx_packet_delta;
- u32 txcw;
-
- u16 current_ifs_val;
- u16 ifs_max_val;
- u16 ifs_min_val;
- u16 ifs_ratio;
- u16 ifs_step_size;
- u16 mta_reg_count;
- u16 rar_entry_count;
-
- u8 forced_speed_duplex;
-
- bool arc_subsystem_valid;
- bool autoneg;
- bool autoneg_failed;
- bool get_link_status;
- bool in_ifs_mode;
- bool serdes_has_link;
- bool tx_pkt_filtering;
-};
-
-struct e1000_phy_info {
- struct e1000_phy_operations ops;
-
- enum e1000_phy_type type;
-
- enum e1000_1000t_rx_status local_rx;
- enum e1000_1000t_rx_status remote_rx;
- enum e1000_ms_type ms_type;
- enum e1000_ms_type original_ms_type;
- enum e1000_rev_polarity cable_polarity;
- enum e1000_smart_speed smart_speed;
-
- u32 addr;
- u32 id;
- u32 reset_delay_us; /* in usec */
- u32 revision;
-
- enum e1000_media_type media_type;
-
- u16 autoneg_advertised;
- u16 autoneg_mask;
- u16 cable_length;
- u16 max_cable_length;
- u16 min_cable_length;
-
- u8 mdix;
-
- bool disable_polarity_correction;
- bool is_mdix;
- bool polarity_correction;
- bool speed_downgraded;
- bool autoneg_wait_to_complete;
-};
-
-struct e1000_nvm_info {
- struct e1000_nvm_operations ops;
-
- enum e1000_nvm_type type;
- enum e1000_nvm_override override;
-
- u32 flash_bank_size;
- u32 flash_base_addr;
-
- u16 word_size;
- u16 delay_usec;
- u16 address_bits;
- u16 opcode_bits;
- u16 page_size;
-};
-
-struct e1000_bus_info {
- enum e1000_bus_width width;
-
- u16 func;
-};
-
-struct e1000_fc_info {
- u32 high_water; /* Flow control high-water mark */
- u32 low_water; /* Flow control low-water mark */
- u16 pause_time; /* Flow control pause timer */
- bool send_xon; /* Flow control send XON */
- bool strict_ieee; /* Strict IEEE mode */
- enum e1000_fc_type type; /* Type of flow control */
- enum e1000_fc_type original_type;
-};
-
-struct e1000_dev_spec_82571 {
- bool laa_is_present;
- bool alt_mac_addr_is_present;
-};
-
-struct e1000_shadow_ram {
- u16 value;
- bool modified;
-};
-
-#define E1000_ICH8_SHADOW_RAM_WORDS 2048
-
-struct e1000_dev_spec_ich8lan {
- bool kmrn_lock_loss_workaround_enabled;
- struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
-};
-
-struct e1000_hw {
- struct e1000_adapter *adapter;
-
- u8 __iomem *hw_addr;
- u8 __iomem *flash_address;
-
- struct e1000_mac_info mac;
- struct e1000_fc_info fc;
- struct e1000_phy_info phy;
- struct e1000_nvm_info nvm;
- struct e1000_bus_info bus;
- struct e1000_host_mng_dhcp_cookie mng_cookie;
-
- union {
- struct e1000_dev_spec_82571 e82571;
- struct e1000_dev_spec_ich8lan ich8lan;
- } dev_spec;
-};
-
-#ifdef DEBUG
-#define hw_dbg(hw, format, arg...) \
- printk(KERN_DEBUG "%s: " format, e1000e_get_hw_dev_name(hw), ##arg)
-#else
-static inline int __attribute__ ((format (printf, 2, 3)))
-hw_dbg(struct e1000_hw *hw, const char *format, ...)
-{
- return 0;
-}
-#endif
-
-#endif
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
deleted file mode 100644
index bcd2bc477af..00000000000
--- a/drivers/net/e1000e/ich8lan.c
+++ /dev/null
@@ -1,2437 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-/*
- * 82562G-2 10/100 Network Connection
- * 82562GT 10/100 Network Connection
- * 82562GT-2 10/100 Network Connection
- * 82562V 10/100 Network Connection
- * 82562V-2 10/100 Network Connection
- * 82566DC-2 Gigabit Network Connection
- * 82566DC Gigabit Network Connection
- * 82566DM-2 Gigabit Network Connection
- * 82566DM Gigabit Network Connection
- * 82566MC Gigabit Network Connection
- * 82566MM Gigabit Network Connection
- * 82567LM Gigabit Network Connection
- * 82567LF Gigabit Network Connection
- * 82567LM-2 Gigabit Network Connection
- * 82567LF-2 Gigabit Network Connection
- * 82567V-2 Gigabit Network Connection
- * 82562GT-3 10/100 Network Connection
- */
-
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include "e1000.h"
-
-#define ICH_FLASH_GFPREG 0x0000
-#define ICH_FLASH_HSFSTS 0x0004
-#define ICH_FLASH_HSFCTL 0x0006
-#define ICH_FLASH_FADDR 0x0008
-#define ICH_FLASH_FDATA0 0x0010
-#define ICH_FLASH_PR0 0x0074
-
-#define ICH_FLASH_READ_COMMAND_TIMEOUT 500
-#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500
-#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 3000000
-#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
-#define ICH_FLASH_CYCLE_REPEAT_COUNT 10
-
-#define ICH_CYCLE_READ 0
-#define ICH_CYCLE_WRITE 2
-#define ICH_CYCLE_ERASE 3
-
-#define FLASH_GFPREG_BASE_MASK 0x1FFF
-#define FLASH_SECTOR_ADDR_SHIFT 12
-
-#define ICH_FLASH_SEG_SIZE_256 256
-#define ICH_FLASH_SEG_SIZE_4K 4096
-#define ICH_FLASH_SEG_SIZE_8K 8192
-#define ICH_FLASH_SEG_SIZE_64K 65536
-
-
-#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
-
-#define E1000_ICH_MNG_IAMT_MODE 0x2
-
-#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
- (ID_LED_DEF1_OFF2 << 8) | \
- (ID_LED_DEF1_ON2 << 4) | \
- (ID_LED_DEF1_DEF2))
-
-#define E1000_ICH_NVM_SIG_WORD 0x13
-#define E1000_ICH_NVM_SIG_MASK 0xC000
-
-#define E1000_ICH8_LAN_INIT_TIMEOUT 1500
-
-#define E1000_FEXTNVM_SW_CONFIG 1
-#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
-
-#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
-
-#define E1000_ICH_RAR_ENTRIES 7
-
-#define PHY_PAGE_SHIFT 5
-#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
- ((reg) & MAX_PHY_REG_ADDRESS))
-#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
-#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
-
-#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
-#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
-#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
-
-/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
-/* Offset 04h HSFSTS */
-union ich8_hws_flash_status {
- struct ich8_hsfsts {
- u16 flcdone :1; /* bit 0 Flash Cycle Done */
- u16 flcerr :1; /* bit 1 Flash Cycle Error */
- u16 dael :1; /* bit 2 Direct Access error Log */
- u16 berasesz :2; /* bit 4:3 Sector Erase Size */
- u16 flcinprog :1; /* bit 5 flash cycle in Progress */
- u16 reserved1 :2; /* bit 13:6 Reserved */
- u16 reserved2 :6; /* bit 13:6 Reserved */
- u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */
- u16 flockdn :1; /* bit 15 Flash Config Lock-Down */
- } hsf_status;
- u16 regval;
-};
-
-/* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */
-/* Offset 06h FLCTL */
-union ich8_hws_flash_ctrl {
- struct ich8_hsflctl {
- u16 flcgo :1; /* 0 Flash Cycle Go */
- u16 flcycle :2; /* 2:1 Flash Cycle */
- u16 reserved :5; /* 7:3 Reserved */
- u16 fldbcount :2; /* 9:8 Flash Data Byte Count */
- u16 flockdn :6; /* 15:10 Reserved */
- } hsf_ctrl;
- u16 regval;
-};
-
-/* ICH Flash Region Access Permissions */
-union ich8_hws_flash_regacc {
- struct ich8_flracc {
- u32 grra :8; /* 0:7 GbE region Read Access */
- u32 grwa :8; /* 8:15 GbE region Write Access */
- u32 gmrag :8; /* 23:16 GbE Master Read Access Grant */
- u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */
- } hsf_flregacc;
- u16 regval;
-};
-
-/* ICH Flash Protected Region */
-union ich8_flash_protected_range {
- struct ich8_pr {
- u32 base:13; /* 0:12 Protected Range Base */
- u32 reserved1:2; /* 13:14 Reserved */
- u32 rpe:1; /* 15 Read Protection Enable */
- u32 limit:13; /* 16:28 Protected Range Limit */
- u32 reserved2:2; /* 29:30 Reserved */
- u32 wpe:1; /* 31 Write Protection Enable */
- } range;
- u32 regval;
-};
-
-static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw);
-static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
-static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw);
-static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw);
-static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
-static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
- u32 offset, u8 byte);
-static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
- u16 *data);
-static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 size, u16 *data);
-static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
-static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
-
-static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
-{
- return readw(hw->flash_address + reg);
-}
-
-static inline u32 __er32flash(struct e1000_hw *hw, unsigned long reg)
-{
- return readl(hw->flash_address + reg);
-}
-
-static inline void __ew16flash(struct e1000_hw *hw, unsigned long reg, u16 val)
-{
- writew(val, hw->flash_address + reg);
-}
-
-static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
-{
- writel(val, hw->flash_address + reg);
-}
-
-#define er16flash(reg) __er16flash(hw, (reg))
-#define er32flash(reg) __er32flash(hw, (reg))
-#define ew16flash(reg,val) __ew16flash(hw, (reg), (val))
-#define ew32flash(reg,val) __ew32flash(hw, (reg), (val))
-
-/**
- * e1000_init_phy_params_ich8lan - Initialize PHY function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific PHY parameters and function pointers.
- **/
-static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 i = 0;
-
- phy->addr = 1;
- phy->reset_delay_us = 100;
-
- /*
- * We may need to do this twice - once for IGP and if that fails,
- * we'll set BM func pointers and try again
- */
- ret_val = e1000e_determine_phy_address(hw);
- if (ret_val) {
- hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
- hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm;
- ret_val = e1000e_determine_phy_address(hw);
- if (ret_val)
- return ret_val;
- }
-
- phy->id = 0;
- while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
- (i++ < 100)) {
- msleep(1);
- ret_val = e1000e_get_phy_id(hw);
- if (ret_val)
- return ret_val;
- }
-
- /* Verify phy id */
- switch (phy->id) {
- case IGP03E1000_E_PHY_ID:
- phy->type = e1000_phy_igp_3;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- break;
- case IFE_E_PHY_ID:
- case IFE_PLUS_E_PHY_ID:
- case IFE_C_E_PHY_ID:
- phy->type = e1000_phy_ife;
- phy->autoneg_mask = E1000_ALL_NOT_GIG;
- break;
- case BME1000_E_PHY_ID:
- phy->type = e1000_phy_bm;
- phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
- hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm;
- hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
- hw->phy.ops.commit_phy = e1000e_phy_sw_reset;
- break;
- default:
- return -E1000_ERR_PHY;
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000_init_nvm_params_ich8lan - Initialize NVM function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific NVM parameters and function
- * pointers.
- **/
-static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 gfpreg;
- u32 sector_base_addr;
- u32 sector_end_addr;
- u16 i;
-
- /* Can't read flash registers if the register set isn't mapped. */
- if (!hw->flash_address) {
- hw_dbg(hw, "ERROR: Flash registers not mapped\n");
- return -E1000_ERR_CONFIG;
- }
-
- nvm->type = e1000_nvm_flash_sw;
-
- gfpreg = er32flash(ICH_FLASH_GFPREG);
-
- /*
- * sector_X_addr is a "sector"-aligned address (4096 bytes)
- * Add 1 to sector_end_addr since this sector is included in
- * the overall size.
- */
- sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
- sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
-
- /* flash_base_addr is byte-aligned */
- nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
-
- /*
- * find total size of the NVM, then cut in half since the total
- * size represents two separate NVM banks.
- */
- nvm->flash_bank_size = (sector_end_addr - sector_base_addr)
- << FLASH_SECTOR_ADDR_SHIFT;
- nvm->flash_bank_size /= 2;
- /* Adjust to word count */
- nvm->flash_bank_size /= sizeof(u16);
-
- nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;
-
- /* Clear shadow ram */
- for (i = 0; i < nvm->word_size; i++) {
- dev_spec->shadow_ram[i].modified = 0;
- dev_spec->shadow_ram[i].value = 0xFFFF;
- }
-
- return 0;
-}
-
-/**
- * e1000_init_mac_params_ich8lan - Initialize MAC function pointers
- * @hw: pointer to the HW structure
- *
- * Initialize family-specific MAC parameters and function
- * pointers.
- **/
-static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_mac_info *mac = &hw->mac;
-
- /* Set media type function pointer */
- hw->phy.media_type = e1000_media_type_copper;
-
- /* Set mta register count */
- mac->mta_reg_count = 32;
- /* Set rar entry count */
- mac->rar_entry_count = E1000_ICH_RAR_ENTRIES;
- if (mac->type == e1000_ich8lan)
- mac->rar_entry_count--;
- /* Set if manageability features are enabled. */
- mac->arc_subsystem_valid = 1;
-
- /* Enable PCS Lock-loss workaround for ICH8 */
- if (mac->type == e1000_ich8lan)
- e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 1);
-
- return 0;
-}
-
-static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- s32 rc;
-
- rc = e1000_init_mac_params_ich8lan(adapter);
- if (rc)
- return rc;
-
- rc = e1000_init_nvm_params_ich8lan(hw);
- if (rc)
- return rc;
-
- rc = e1000_init_phy_params_ich8lan(hw);
- if (rc)
- return rc;
-
- if ((adapter->hw.mac.type == e1000_ich8lan) &&
- (adapter->hw.phy.type == e1000_phy_igp_3))
- adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
-
- return 0;
-}
-
-static DEFINE_MUTEX(nvm_mutex);
-static pid_t nvm_owner = -1;
-
-/**
- * e1000_acquire_swflag_ich8lan - Acquire software control flag
- * @hw: pointer to the HW structure
- *
- * Acquires the software control flag for performing NVM and PHY
- * operations. This is a function pointer entry point only called by
- * read/write routines for the PHY and NVM parts.
- **/
-static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
-{
- u32 extcnf_ctrl;
- u32 timeout = PHY_CFG_TIMEOUT;
-
- might_sleep();
-
- if (!mutex_trylock(&nvm_mutex)) {
- WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n",
- nvm_owner);
- mutex_lock(&nvm_mutex);
- }
- nvm_owner = current->pid;
-
- while (timeout) {
- extcnf_ctrl = er32(EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
-
- extcnf_ctrl = er32(EXTCNF_CTRL);
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
- break;
- mdelay(1);
- timeout--;
- }
-
- if (!timeout) {
- hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
- nvm_owner = -1;
- mutex_unlock(&nvm_mutex);
- return -E1000_ERR_CONFIG;
- }
-
- return 0;
-}
-
-/**
- * e1000_release_swflag_ich8lan - Release software control flag
- * @hw: pointer to the HW structure
- *
- * Releases the software control flag for performing NVM and PHY operations.
- * This is a function pointer entry point only called by read/write
- * routines for the PHY and NVM parts.
- **/
-static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
-{
- u32 extcnf_ctrl;
-
- extcnf_ctrl = er32(EXTCNF_CTRL);
- extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
- ew32(EXTCNF_CTRL, extcnf_ctrl);
-
- nvm_owner = -1;
- mutex_unlock(&nvm_mutex);
-}
-
-/**
- * e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
- * @hw: pointer to the HW structure
- *
- * Checks if firmware is blocking the reset of the PHY.
- * This is a function pointer entry point only called by
- * reset routines.
- **/
-static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
-{
- u32 fwsm;
-
- fwsm = er32(FWSM);
-
- return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? 0 : E1000_BLK_PHY_RESET;
-}
-
-/**
- * e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex
- * @hw: pointer to the HW structure
- *
- * Forces the speed and duplex settings of the PHY.
- * This is a function pointer entry point only called by
- * PHY setup routines.
- **/
-static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- bool link;
-
- if (phy->type != e1000_phy_ife) {
- ret_val = e1000e_phy_force_speed_duplex_igp(hw);
- return ret_val;
- }
-
- ret_val = e1e_rphy(hw, PHY_CONTROL, &data);
- if (ret_val)
- return ret_val;
-
- e1000e_phy_force_speed_duplex_setup(hw, &data);
-
- ret_val = e1e_wphy(hw, PHY_CONTROL, data);
- if (ret_val)
- return ret_val;
-
- /* Disable MDI-X support for 10/100 */
- ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IFE_PMC_AUTO_MDIX;
- data &= ~IFE_PMC_FORCE_MDIX;
-
- ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
- if (ret_val)
- return ret_val;
-
- hw_dbg(hw, "IFE PMC: %X\n", data);
-
- udelay(1);
-
- if (phy->autoneg_wait_to_complete) {
- hw_dbg(hw, "Waiting for forced speed/duplex link on IFE phy.\n");
-
- ret_val = e1000e_phy_has_link_generic(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
- if (ret_val)
- return ret_val;
-
- if (!link)
- hw_dbg(hw, "Link taking longer than expected.\n");
-
- /* Try once more */
- ret_val = e1000e_phy_has_link_generic(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
- if (ret_val)
- return ret_val;
- }
-
- return 0;
-}
-
-/**
- * e1000_phy_hw_reset_ich8lan - Performs a PHY reset
- * @hw: pointer to the HW structure
- *
- * Resets the PHY
- * This is a function pointer entry point called by drivers
- * or other shared routines.
- **/
-static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i;
- u32 data, cnf_size, cnf_base_addr, sw_cfg_mask;
- s32 ret_val;
- u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT;
- u16 word_addr, reg_data, reg_addr, phy_page = 0;
-
- ret_val = e1000e_phy_hw_reset_generic(hw);
- if (ret_val)
- return ret_val;
-
- /*
- * Initialize the PHY from the NVM on ICH platforms. This
- * is needed due to an issue where the NVM configuration is
- * not properly autoloaded after power transitions.
- * Therefore, after each PHY reset, we will load the
- * configuration data out of the NVM manually.
- */
- if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) {
- struct e1000_adapter *adapter = hw->adapter;
-
- /* Check if SW needs configure the PHY */
- if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
- (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M))
- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
- else
- sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
-
- data = er32(FEXTNVM);
- if (!(data & sw_cfg_mask))
- return 0;
-
- /* Wait for basic configuration completes before proceeding*/
- do {
- data = er32(STATUS);
- data &= E1000_STATUS_LAN_INIT_DONE;
- udelay(100);
- } while ((!data) && --loop);
-
- /*
- * If basic configuration is incomplete before the above loop
- * count reaches 0, loading the configuration from NVM will
- * leave the PHY in a bad state possibly resulting in no link.
- */
- if (loop == 0) {
- hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n");
- }
-
- /* Clear the Init Done bit for the next init event */
- data = er32(STATUS);
- data &= ~E1000_STATUS_LAN_INIT_DONE;
- ew32(STATUS, data);
-
- /*
- * Make sure HW does not configure LCD from PHY
- * extended configuration before SW configuration
- */
- data = er32(EXTCNF_CTRL);
- if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
- return 0;
-
- cnf_size = er32(EXTCNF_SIZE);
- cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
- cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
- if (!cnf_size)
- return 0;
-
- cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
- cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
-
- /* Configure LCD from extended configuration region. */
-
- /* cnf_base_addr is in DWORD */
- word_addr = (u16)(cnf_base_addr << 1);
-
- for (i = 0; i < cnf_size; i++) {
- ret_val = e1000_read_nvm(hw,
- (word_addr + i * 2),
- 1,
- &reg_data);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_nvm(hw,
- (word_addr + i * 2 + 1),
- 1,
- &reg_addr);
- if (ret_val)
- return ret_val;
-
- /* Save off the PHY page for future writes. */
- if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
- phy_page = reg_data;
- continue;
- }
-
- reg_addr |= phy_page;
-
- ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data);
- if (ret_val)
- return ret_val;
- }
- }
-
- return 0;
-}
-
-/**
- * e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states
- * @hw: pointer to the HW structure
- *
- * Populates "phy" structure with various feature states.
- * This function is only called by other family-specific
- * routines.
- **/
-static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- bool link;
-
- ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- hw_dbg(hw, "Phy info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
- if (ret_val)
- return ret_val;
- phy->polarity_correction = (!(data & IFE_PSC_AUTO_POLARITY_DISABLE));
-
- if (phy->polarity_correction) {
- ret_val = e1000_check_polarity_ife_ich8lan(hw);
- if (ret_val)
- return ret_val;
- } else {
- /* Polarity is forced */
- phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal;
- }
-
- ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
- if (ret_val)
- return ret_val;
-
- phy->is_mdix = (data & IFE_PMC_MDIX_STATUS);
-
- /* The following parameters are undefined for 10/100 operation. */
- phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
- phy->local_rx = e1000_1000t_rx_status_undefined;
- phy->remote_rx = e1000_1000t_rx_status_undefined;
-
- return 0;
-}
-
-/**
- * e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_phy_info
- * @hw: pointer to the HW structure
- *
- * Wrapper for calling the get_phy_info routines for the appropriate phy type.
- * This is a function pointer entry point called by drivers
- * or other shared routines.
- **/
-static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
-{
- switch (hw->phy.type) {
- case e1000_phy_ife:
- return e1000_get_phy_info_ife_ich8lan(hw);
- break;
- case e1000_phy_igp_3:
- case e1000_phy_bm:
- return e1000e_get_phy_info_igp(hw);
- break;
- default:
- break;
- }
-
- return -E1000_ERR_PHY_TYPE;
-}
-
-/**
- * e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
- * @hw: pointer to the HW structure
- *
- * Polarity is determined on the polarity reversal feature being enabled.
- * This function is only called by other family-specific
- * routines.
- **/
-static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, offset, mask;
-
- /*
- * Polarity is determined based on the reversal feature being enabled.
- */
- if (phy->polarity_correction) {
- offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
- mask = IFE_PESC_POLARITY_REVERSED;
- } else {
- offset = IFE_PHY_SPECIAL_CONTROL;
- mask = IFE_PSC_FORCE_POLARITY;
- }
-
- ret_val = e1e_rphy(hw, offset, &phy_data);
-
- if (!ret_val)
- phy->cable_polarity = (phy_data & mask)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal;
-
- return ret_val;
-}
-
-/**
- * e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
- * @hw: pointer to the HW structure
- * @active: TRUE to enable LPLU, FALSE to disable
- *
- * Sets the LPLU D0 state according to the active flag. When
- * activating LPLU this function also disables smart speed
- * and vice versa. LPLU will not be activated unless the
- * device autonegotiation advertisement meets standards of
- * either 10 or 10/100 or 10/100/1000 at all duplexes.
- * This is a function pointer entry point only called by
- * PHY setup routines.
- **/
-static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 phy_ctrl;
- s32 ret_val = 0;
- u16 data;
-
- if (phy->type == e1000_phy_ife)
- return ret_val;
-
- phy_ctrl = er32(PHY_CTRL);
-
- if (active) {
- phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
-
- /*
- * Call gig speed drop workaround on LPLU before accessing
- * any PHY registers
- */
- if ((hw->mac.type == e1000_ich8lan) &&
- (hw->phy.type == e1000_phy_igp_3))
- e1000e_gig_downshift_workaround_ich8lan(hw);
-
- /* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
- if (ret_val)
- return ret_val;
- } else {
- phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
-
- /*
- * LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- } else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- }
- }
-
- return 0;
-}
-
-/**
- * e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state
- * @hw: pointer to the HW structure
- * @active: TRUE to enable LPLU, FALSE to disable
- *
- * Sets the LPLU D3 state according to the active flag. When
- * activating LPLU this function also disables smart speed
- * and vice versa. LPLU will not be activated unless the
- * device autonegotiation advertisement meets standards of
- * either 10 or 10/100 or 10/100/1000 at all duplexes.
- * This is a function pointer entry point only called by
- * PHY setup routines.
- **/
-static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 phy_ctrl;
- s32 ret_val;
- u16 data;
-
- phy_ctrl = er32(PHY_CTRL);
-
- if (!active) {
- phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
- /*
- * LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- } else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- }
- } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
- (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
- (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
- phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
- ew32(PHY_CTRL, phy_ctrl);
-
- /*
- * Call gig speed drop workaround on LPLU before accessing
- * any PHY registers
- */
- if ((hw->mac.type == e1000_ich8lan) &&
- (hw->phy.type == e1000_phy_igp_3))
- e1000e_gig_downshift_workaround_ich8lan(hw);
-
- /* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
- }
-
- return 0;
-}
-
-/**
- * e1000_read_nvm_ich8lan - Read word(s) from the NVM
- * @hw: pointer to the HW structure
- * @offset: The offset (in bytes) of the word(s) to read.
- * @words: Size of data to read in words
- * @data: Pointer to the word(s) to read at offset.
- *
- * Reads a word(s) from the NVM using the flash access registers.
- **/
-static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 act_offset;
- s32 ret_val;
- u16 i, word;
-
- if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
- (words == 0)) {
- hw_dbg(hw, "nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- if (ret_val)
- return ret_val;
-
- /* Start with the bank offset, then add the relative offset. */
- act_offset = (er32(EECD) & E1000_EECD_SEC1VAL)
- ? nvm->flash_bank_size
- : 0;
- act_offset += offset;
-
- for (i = 0; i < words; i++) {
- if ((dev_spec->shadow_ram) &&
- (dev_spec->shadow_ram[offset+i].modified)) {
- data[i] = dev_spec->shadow_ram[offset+i].value;
- } else {
- ret_val = e1000_read_flash_word_ich8lan(hw,
- act_offset + i,
- &word);
- if (ret_val)
- break;
- data[i] = word;
- }
- }
-
- e1000_release_swflag_ich8lan(hw);
-
- return ret_val;
-}
-
-/**
- * e1000_flash_cycle_init_ich8lan - Initialize flash
- * @hw: pointer to the HW structure
- *
- * This function does initial flash setup so that a new read/write/erase cycle
- * can be started.
- **/
-static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
-{
- union ich8_hws_flash_status hsfsts;
- s32 ret_val = -E1000_ERR_NVM;
- s32 i = 0;
-
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
-
- /* Check if the flash descriptor is valid */
- if (hsfsts.hsf_status.fldesvalid == 0) {
- hw_dbg(hw, "Flash descriptor invalid. "
- "SW Sequencing must be used.");
- return -E1000_ERR_NVM;
- }
-
- /* Clear FCERR and DAEL in hw status by writing 1 */
- hsfsts.hsf_status.flcerr = 1;
- hsfsts.hsf_status.dael = 1;
-
- ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
-
- /*
- * Either we should have a hardware SPI cycle in progress
- * bit to check against, in order to start a new cycle or
- * FDONE bit should be changed in the hardware so that it
- * is 1 after hardware reset, which can then be used as an
- * indication whether a cycle is in progress or has been
- * completed.
- */
-
- if (hsfsts.hsf_status.flcinprog == 0) {
- /*
- * There is no cycle running at present,
- * so we can start a cycle
- * Begin by setting Flash Cycle Done.
- */
- hsfsts.hsf_status.flcdone = 1;
- ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
- ret_val = 0;
- } else {
- /*
- * otherwise poll for sometime so the current
- * cycle has a chance to end before giving up.
- */
- for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
- hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcinprog == 0) {
- ret_val = 0;
- break;
- }
- udelay(1);
- }
- if (ret_val == 0) {
- /*
- * Successful in waiting for previous cycle to timeout,
- * now set the Flash Cycle Done.
- */
- hsfsts.hsf_status.flcdone = 1;
- ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
- } else {
- hw_dbg(hw, "Flash controller busy, cannot get access");
- }
- }
-
- return ret_val;
-}
-
-/**
- * e1000_flash_cycle_ich8lan - Starts flash cycle (read/write/erase)
- * @hw: pointer to the HW structure
- * @timeout: maximum time to wait for completion
- *
- * This function starts a flash cycle and waits for its completion.
- **/
-static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
-{
- union ich8_hws_flash_ctrl hsflctl;
- union ich8_hws_flash_status hsfsts;
- s32 ret_val = -E1000_ERR_NVM;
- u32 i = 0;
-
- /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
- hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
- hsflctl.hsf_ctrl.flcgo = 1;
- ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
-
- /* wait till FDONE bit is set to 1 */
- do {
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcdone == 1)
- break;
- udelay(1);
- } while (i++ < timeout);
-
- if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0)
- return 0;
-
- return ret_val;
-}
-
-/**
- * e1000_read_flash_word_ich8lan - Read word from flash
- * @hw: pointer to the HW structure
- * @offset: offset to data location
- * @data: pointer to the location for storing the data
- *
- * Reads the flash word at offset into data. Offset is converted
- * to bytes before read.
- **/
-static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset,
- u16 *data)
-{
- /* Must convert offset into bytes. */
- offset <<= 1;
-
- return e1000_read_flash_data_ich8lan(hw, offset, 2, data);
-}
-
-/**
- * e1000_read_flash_data_ich8lan - Read byte or word from NVM
- * @hw: pointer to the HW structure
- * @offset: The offset (in bytes) of the byte or word to read.
- * @size: Size of data to read, 1=byte 2=word
- * @data: Pointer to the word to store the value read.
- *
- * Reads a byte or word from the NVM using the flash access registers.
- **/
-static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 size, u16 *data)
-{
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_addr;
- u32 flash_data = 0;
- s32 ret_val = -E1000_ERR_NVM;
- u8 count = 0;
-
- if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
- return -E1000_ERR_NVM;
-
- flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
- hw->nvm.flash_base_addr;
-
- do {
- udelay(1);
- /* Steps */
- ret_val = e1000_flash_cycle_init_ich8lan(hw);
- if (ret_val != 0)
- break;
-
- hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
- /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
- hsflctl.hsf_ctrl.fldbcount = size - 1;
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
- ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
-
- ew32flash(ICH_FLASH_FADDR, flash_linear_addr);
-
- ret_val = e1000_flash_cycle_ich8lan(hw,
- ICH_FLASH_READ_COMMAND_TIMEOUT);
-
- /*
- * Check if FCERR is set to 1, if set to 1, clear it
- * and try the whole sequence a few more times, else
- * read in (shift in) the Flash Data0, the order is
- * least significant byte first msb to lsb
- */
- if (ret_val == 0) {
- flash_data = er32flash(ICH_FLASH_FDATA0);
- if (size == 1) {
- *data = (u8)(flash_data & 0x000000FF);
- } else if (size == 2) {
- *data = (u16)(flash_data & 0x0000FFFF);
- }
- break;
- } else {
- /*
- * If we've gotten here, then things are probably
- * completely hosed, but if the error condition is
- * detected, it won't hurt to give it another try...
- * ICH_FLASH_CYCLE_REPEAT_COUNT times.
- */
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1) {
- /* Repeat for some time before giving up. */
- continue;
- } else if (hsfsts.hsf_status.flcdone == 0) {
- hw_dbg(hw, "Timeout error - flash cycle "
- "did not complete.");
- break;
- }
- }
- } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
-
- return ret_val;
-}
-
-/**
- * e1000_write_nvm_ich8lan - Write word(s) to the NVM
- * @hw: pointer to the HW structure
- * @offset: The offset (in bytes) of the word(s) to write.
- * @words: Size of data to write in words
- * @data: Pointer to the word(s) to write at offset.
- *
- * Writes a byte or word to the NVM using the flash access registers.
- **/
-static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
- u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- s32 ret_val;
- u16 i;
-
- if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
- (words == 0)) {
- hw_dbg(hw, "nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- if (ret_val)
- return ret_val;
-
- for (i = 0; i < words; i++) {
- dev_spec->shadow_ram[offset+i].modified = 1;
- dev_spec->shadow_ram[offset+i].value = data[i];
- }
-
- e1000_release_swflag_ich8lan(hw);
-
- return 0;
-}
-
-/**
- * e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM
- * @hw: pointer to the HW structure
- *
- * The NVM checksum is updated by calling the generic update_nvm_checksum,
- * which writes the checksum to the shadow ram. The changes in the shadow
- * ram are then committed to the EEPROM by processing each bank at a time
- * checking for the modified bit and writing only the pending changes.
- * After a successful commit, the shadow ram is cleared and is ready for
- * future writes.
- **/
-static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 i, act_offset, new_bank_offset, old_bank_offset;
- s32 ret_val;
- u16 data;
-
- ret_val = e1000e_update_nvm_checksum_generic(hw);
- if (ret_val)
- return ret_val;
-
- if (nvm->type != e1000_nvm_flash_sw)
- return ret_val;
-
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- if (ret_val)
- return ret_val;
-
- /*
- * We're writing to the opposite bank so if we're on bank 1,
- * write to bank 0 etc. We also need to erase the segment that
- * is going to be written
- */
- if (!(er32(EECD) & E1000_EECD_SEC1VAL)) {
- new_bank_offset = nvm->flash_bank_size;
- old_bank_offset = 0;
- e1000_erase_flash_bank_ich8lan(hw, 1);
- } else {
- old_bank_offset = nvm->flash_bank_size;
- new_bank_offset = 0;
- e1000_erase_flash_bank_ich8lan(hw, 0);
- }
-
- for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
- /*
- * Determine whether to write the value stored
- * in the other NVM bank or a modified value stored
- * in the shadow RAM
- */
- if (dev_spec->shadow_ram[i].modified) {
- data = dev_spec->shadow_ram[i].value;
- } else {
- e1000_read_flash_word_ich8lan(hw,
- i + old_bank_offset,
- &data);
- }
-
- /*
- * If the word is 0x13, then make sure the signature bits
- * (15:14) are 11b until the commit has completed.
- * This will allow us to write 10b which indicates the
- * signature is valid. We want to do this after the write
- * has completed so that we don't mark the segment valid
- * while the write is still in progress
- */
- if (i == E1000_ICH_NVM_SIG_WORD)
- data |= E1000_ICH_NVM_SIG_MASK;
-
- /* Convert offset to bytes. */
- act_offset = (i + new_bank_offset) << 1;
-
- udelay(100);
- /* Write the bytes to the new bank. */
- ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
- act_offset,
- (u8)data);
- if (ret_val)
- break;
-
- udelay(100);
- ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
- act_offset + 1,
- (u8)(data >> 8));
- if (ret_val)
- break;
- }
-
- /*
- * Don't bother writing the segment valid bits if sector
- * programming failed.
- */
- if (ret_val) {
- /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
- hw_dbg(hw, "Flash commit failed.\n");
- e1000_release_swflag_ich8lan(hw);
- return ret_val;
- }
-
- /*
- * Finally validate the new segment by setting bit 15:14
- * to 10b in word 0x13 , this can be done without an
- * erase as well since these bits are 11 to start with
- * and we need to change bit 14 to 0b
- */
- act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
- e1000_read_flash_word_ich8lan(hw, act_offset, &data);
- data &= 0xBFFF;
- ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
- act_offset * 2 + 1,
- (u8)(data >> 8));
- if (ret_val) {
- e1000_release_swflag_ich8lan(hw);
- return ret_val;
- }
-
- /*
- * And invalidate the previously valid segment by setting
- * its signature word (0x13) high_byte to 0b. This can be
- * done without an erase because flash erase sets all bits
- * to 1's. We can write 1's to 0's without an erase
- */
- act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
- ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
- if (ret_val) {
- e1000_release_swflag_ich8lan(hw);
- return ret_val;
- }
-
- /* Great! Everything worked, we can now clear the cached entries. */
- for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
- dev_spec->shadow_ram[i].modified = 0;
- dev_spec->shadow_ram[i].value = 0xFFFF;
- }
-
- e1000_release_swflag_ich8lan(hw);
-
- /*
- * Reload the EEPROM, or else modifications will not appear
- * until after the next adapter reset.
- */
- e1000e_reload_nvm(hw);
- msleep(10);
-
- return ret_val;
-}
-
-/**
- * e1000_validate_nvm_checksum_ich8lan - Validate EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Check to see if checksum needs to be fixed by reading bit 6 in word 0x19.
- * If the bit is 0, that the EEPROM had been modified, but the checksum was not
- * calculated, in which case we need to calculate the checksum and set bit 6.
- **/
-static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 data;
-
- /*
- * Read 0x19 and check bit 6. If this bit is 0, the checksum
- * needs to be fixed. This bit is an indication that the NVM
- * was prepared by OEM software and did not calculate the
- * checksum...a likely scenario.
- */
- ret_val = e1000_read_nvm(hw, 0x19, 1, &data);
- if (ret_val)
- return ret_val;
-
- if ((data & 0x40) == 0) {
- data |= 0x40;
- ret_val = e1000_write_nvm(hw, 0x19, 1, &data);
- if (ret_val)
- return ret_val;
- ret_val = e1000e_update_nvm_checksum(hw);
- if (ret_val)
- return ret_val;
- }
-
- return e1000e_validate_nvm_checksum_generic(hw);
-}
-
-/**
- * e1000e_write_protect_nvm_ich8lan - Make the NVM read-only
- * @hw: pointer to the HW structure
- *
- * To prevent malicious write/erase of the NVM, set it to be read-only
- * so that the hardware ignores all write/erase cycles of the NVM via
- * the flash control registers. The shadow-ram copy of the NVM will
- * still be updated, however any updates to this copy will not stick
- * across driver reloads.
- **/
-void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw)
-{
- union ich8_flash_protected_range pr0;
- union ich8_hws_flash_status hsfsts;
- u32 gfpreg;
- s32 ret_val;
-
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- if (ret_val)
- return;
-
- gfpreg = er32flash(ICH_FLASH_GFPREG);
-
- /* Write-protect GbE Sector of NVM */
- pr0.regval = er32flash(ICH_FLASH_PR0);
- pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK;
- pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK);
- pr0.range.wpe = true;
- ew32flash(ICH_FLASH_PR0, pr0.regval);
-
- /*
- * Lock down a subset of GbE Flash Control Registers, e.g.
- * PR0 to prevent the write-protection from being lifted.
- * Once FLOCKDN is set, the registers protected by it cannot
- * be written until FLOCKDN is cleared by a hardware reset.
- */
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
- hsfsts.hsf_status.flockdn = true;
- ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval);
-
- e1000_release_swflag_ich8lan(hw);
-}
-
-/**
- * e1000_write_flash_data_ich8lan - Writes bytes to the NVM
- * @hw: pointer to the HW structure
- * @offset: The offset (in bytes) of the byte/word to read.
- * @size: Size of data to read, 1=byte 2=word
- * @data: The byte(s) to write to the NVM.
- *
- * Writes one/two bytes to the NVM using the flash access registers.
- **/
-static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 size, u16 data)
-{
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_addr;
- u32 flash_data = 0;
- s32 ret_val;
- u8 count = 0;
-
- if (size < 1 || size > 2 || data > size * 0xff ||
- offset > ICH_FLASH_LINEAR_ADDR_MASK)
- return -E1000_ERR_NVM;
-
- flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) +
- hw->nvm.flash_base_addr;
-
- do {
- udelay(1);
- /* Steps */
- ret_val = e1000_flash_cycle_init_ich8lan(hw);
- if (ret_val)
- break;
-
- hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
- /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
- hsflctl.hsf_ctrl.fldbcount = size -1;
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
- ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
-
- ew32flash(ICH_FLASH_FADDR, flash_linear_addr);
-
- if (size == 1)
- flash_data = (u32)data & 0x00FF;
- else
- flash_data = (u32)data;
-
- ew32flash(ICH_FLASH_FDATA0, flash_data);
-
- /*
- * check if FCERR is set to 1 , if set to 1, clear it
- * and try the whole sequence a few more times else done
- */
- ret_val = e1000_flash_cycle_ich8lan(hw,
- ICH_FLASH_WRITE_COMMAND_TIMEOUT);
- if (!ret_val)
- break;
-
- /*
- * If we're here, then things are most likely
- * completely hosed, but if the error condition
- * is detected, it won't hurt to give it another
- * try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
- */
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1)
- /* Repeat for some time before giving up. */
- continue;
- if (hsfsts.hsf_status.flcdone == 0) {
- hw_dbg(hw, "Timeout error - flash cycle "
- "did not complete.");
- break;
- }
- } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
-
- return ret_val;
-}
-
-/**
- * e1000_write_flash_byte_ich8lan - Write a single byte to NVM
- * @hw: pointer to the HW structure
- * @offset: The index of the byte to read.
- * @data: The byte to write to the NVM.
- *
- * Writes a single byte to the NVM using the flash access registers.
- **/
-static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
- u8 data)
-{
- u16 word = (u16)data;
-
- return e1000_write_flash_data_ich8lan(hw, offset, 1, word);
-}
-
-/**
- * e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM
- * @hw: pointer to the HW structure
- * @offset: The offset of the byte to write.
- * @byte: The byte to write to the NVM.
- *
- * Writes a single byte to the NVM using the flash access registers.
- * Goes through a retry algorithm before giving up.
- **/
-static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
- u32 offset, u8 byte)
-{
- s32 ret_val;
- u16 program_retries;
-
- ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte);
- if (!ret_val)
- return ret_val;
-
- for (program_retries = 0; program_retries < 100; program_retries++) {
- hw_dbg(hw, "Retrying Byte %2.2X at offset %u\n", byte, offset);
- udelay(100);
- ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte);
- if (!ret_val)
- break;
- }
- if (program_retries == 100)
- return -E1000_ERR_NVM;
-
- return 0;
-}
-
-/**
- * e1000_erase_flash_bank_ich8lan - Erase a bank (4k) from NVM
- * @hw: pointer to the HW structure
- * @bank: 0 for first bank, 1 for second bank, etc.
- *
- * Erases the bank specified. Each bank is a 4k block. Banks are 0 based.
- * bank N is 4096 * N + flash_reg_addr.
- **/
-static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- union ich8_hws_flash_status hsfsts;
- union ich8_hws_flash_ctrl hsflctl;
- u32 flash_linear_addr;
- /* bank size is in 16bit words - adjust to bytes */
- u32 flash_bank_size = nvm->flash_bank_size * 2;
- s32 ret_val;
- s32 count = 0;
- s32 iteration;
- s32 sector_size;
- s32 j;
-
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
-
- /*
- * Determine HW Sector size: Read BERASE bits of hw flash status
- * register
- * 00: The Hw sector is 256 bytes, hence we need to erase 16
- * consecutive sectors. The start index for the nth Hw sector
- * can be calculated as = bank * 4096 + n * 256
- * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
- * The start index for the nth Hw sector can be calculated
- * as = bank * 4096
- * 10: The Hw sector is 8K bytes, nth sector = bank * 8192
- * (ich9 only, otherwise error condition)
- * 11: The Hw sector is 64K bytes, nth sector = bank * 65536
- */
- switch (hsfsts.hsf_status.berasesz) {
- case 0:
- /* Hw sector size 256 */
- sector_size = ICH_FLASH_SEG_SIZE_256;
- iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256;
- break;
- case 1:
- sector_size = ICH_FLASH_SEG_SIZE_4K;
- iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K;
- break;
- case 2:
- if (hw->mac.type == e1000_ich9lan) {
- sector_size = ICH_FLASH_SEG_SIZE_8K;
- iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K;
- } else {
- return -E1000_ERR_NVM;
- }
- break;
- case 3:
- sector_size = ICH_FLASH_SEG_SIZE_64K;
- iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K;
- break;
- default:
- return -E1000_ERR_NVM;
- }
-
- /* Start with the base address, then add the sector offset. */
- flash_linear_addr = hw->nvm.flash_base_addr;
- flash_linear_addr += (bank) ? (sector_size * iteration) : 0;
-
- for (j = 0; j < iteration ; j++) {
- do {
- /* Steps */
- ret_val = e1000_flash_cycle_init_ich8lan(hw);
- if (ret_val)
- return ret_val;
-
- /*
- * Write a value 11 (block Erase) in Flash
- * Cycle field in hw flash control
- */
- hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
- hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
- ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
-
- /*
- * Write the last 24 bits of an index within the
- * block into Flash Linear address field in Flash
- * Address.
- */
- flash_linear_addr += (j * sector_size);
- ew32flash(ICH_FLASH_FADDR, flash_linear_addr);
-
- ret_val = e1000_flash_cycle_ich8lan(hw,
- ICH_FLASH_ERASE_COMMAND_TIMEOUT);
- if (ret_val == 0)
- break;
-
- /*
- * Check if FCERR is set to 1. If 1,
- * clear it and try the whole sequence
- * a few more times else Done
- */
- hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
- if (hsfsts.hsf_status.flcerr == 1)
- /* repeat for some time before giving up */
- continue;
- else if (hsfsts.hsf_status.flcdone == 0)
- return ret_val;
- } while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT);
- }
-
- return 0;
-}
-
-/**
- * e1000_valid_led_default_ich8lan - Set the default LED settings
- * @hw: pointer to the HW structure
- * @data: Pointer to the LED settings
- *
- * Reads the LED default settings from the NVM to data. If the NVM LED
- * settings is all 0's or F's, set the LED default to a valid LED default
- * setting.
- **/
-static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
-{
- s32 ret_val;
-
- ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
-
- if (*data == ID_LED_RESERVED_0000 ||
- *data == ID_LED_RESERVED_FFFF)
- *data = ID_LED_DEFAULT_ICH8LAN;
-
- return 0;
-}
-
-/**
- * e1000_get_bus_info_ich8lan - Get/Set the bus type and width
- * @hw: pointer to the HW structure
- *
- * ICH8 use the PCI Express bus, but does not contain a PCI Express Capability
- * register, so the the bus width is hard coded.
- **/
-static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_bus_info *bus = &hw->bus;
- s32 ret_val;
-
- ret_val = e1000e_get_bus_info_pcie(hw);
-
- /*
- * ICH devices are "PCI Express"-ish. They have
- * a configuration space, but do not contain
- * PCI Express Capability registers, so bus width
- * must be hardcoded.
- */
- if (bus->width == e1000_bus_width_unknown)
- bus->width = e1000_bus_width_pcie_x1;
-
- return ret_val;
-}
-
-/**
- * e1000_reset_hw_ich8lan - Reset the hardware
- * @hw: pointer to the HW structure
- *
- * Does a full reset of the hardware which includes a reset of the PHY and
- * MAC.
- **/
-static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
-{
- u32 ctrl, icr, kab;
- s32 ret_val;
-
- /*
- * Prevent the PCI-E bus from sticking if there is no TLP connection
- * on the last TLP read/write transaction when MAC is reset.
- */
- ret_val = e1000e_disable_pcie_master(hw);
- if (ret_val) {
- hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
- }
-
- hw_dbg(hw, "Masking off all interrupts\n");
- ew32(IMC, 0xffffffff);
-
- /*
- * Disable the Transmit and Receive units. Then delay to allow
- * any pending transactions to complete before we hit the MAC
- * with the global reset.
- */
- ew32(RCTL, 0);
- ew32(TCTL, E1000_TCTL_PSP);
- e1e_flush();
-
- msleep(10);
-
- /* Workaround for ICH8 bit corruption issue in FIFO memory */
- if (hw->mac.type == e1000_ich8lan) {
- /* Set Tx and Rx buffer allocation to 8k apiece. */
- ew32(PBA, E1000_PBA_8K);
- /* Set Packet Buffer Size to 16k. */
- ew32(PBS, E1000_PBS_16K);
- }
-
- ctrl = er32(CTRL);
-
- if (!e1000_check_reset_block(hw)) {
- /*
- * PHY HW reset requires MAC CORE reset at the same
- * time to make sure the interface between MAC and the
- * external PHY is reset.
- */
- ctrl |= E1000_CTRL_PHY_RST;
- }
- ret_val = e1000_acquire_swflag_ich8lan(hw);
- hw_dbg(hw, "Issuing a global reset to ich8lan");
- ew32(CTRL, (ctrl | E1000_CTRL_RST));
- msleep(20);
-
- /* release the swflag because it is not reset by hardware reset */
- e1000_release_swflag_ich8lan(hw);
-
- ret_val = e1000e_get_auto_rd_done(hw);
- if (ret_val) {
- /*
- * When auto config read does not complete, do not
- * return with an error. This can happen in situations
- * where there is no eeprom and prevents getting link.
- */
- hw_dbg(hw, "Auto Read Done did not complete\n");
- }
-
- ew32(IMC, 0xffffffff);
- icr = er32(ICR);
-
- kab = er32(KABGTXD);
- kab |= E1000_KABGTXD_BGSQLBIAS;
- ew32(KABGTXD, kab);
-
- return ret_val;
-}
-
-/**
- * e1000_init_hw_ich8lan - Initialize the hardware
- * @hw: pointer to the HW structure
- *
- * Prepares the hardware for transmit and receive by doing the following:
- * - initialize hardware bits
- * - initialize LED identification
- * - setup receive address registers
- * - setup flow control
- * - setup transmit descriptors
- * - clear statistics
- **/
-static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 ctrl_ext, txdctl, snoop;
- s32 ret_val;
- u16 i;
-
- e1000_initialize_hw_bits_ich8lan(hw);
-
- /* Initialize identification LED */
- ret_val = e1000e_id_led_init(hw);
- if (ret_val) {
- hw_dbg(hw, "Error initializing identification LED\n");
- return ret_val;
- }
-
- /* Setup the receive address. */
- e1000e_init_rx_addrs(hw, mac->rar_entry_count);
-
- /* Zero out the Multicast HASH table */
- hw_dbg(hw, "Zeroing the MTA\n");
- for (i = 0; i < mac->mta_reg_count; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
-
- /* Setup link and flow control */
- ret_val = e1000_setup_link_ich8lan(hw);
-
- /* Set the transmit descriptor write-back policy for both queues */
- txdctl = er32(TXDCTL(0));
- txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
- E1000_TXDCTL_FULL_TX_DESC_WB;
- txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
- E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
- ew32(TXDCTL(0), txdctl);
- txdctl = er32(TXDCTL(1));
- txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
- E1000_TXDCTL_FULL_TX_DESC_WB;
- txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) |
- E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
- ew32(TXDCTL(1), txdctl);
-
- /*
- * ICH8 has opposite polarity of no_snoop bits.
- * By default, we should use snoop behavior.
- */
- if (mac->type == e1000_ich8lan)
- snoop = PCIE_ICH8_SNOOP_ALL;
- else
- snoop = (u32) ~(PCIE_NO_SNOOP_ALL);
- e1000e_set_pcie_no_snoop(hw, snoop);
-
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
- ew32(CTRL_EXT, ctrl_ext);
-
- /*
- * Clear all of the statistics registers (clear on read). It is
- * important that we do this after we have tried to establish link
- * because the symbol error count will increment wildly if there
- * is no link.
- */
- e1000_clear_hw_cntrs_ich8lan(hw);
-
- return 0;
-}
-/**
- * e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits
- * @hw: pointer to the HW structure
- *
- * Sets/Clears required hardware bits necessary for correctly setting up the
- * hardware for transmit and receive.
- **/
-static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
-{
- u32 reg;
-
- /* Extended Device Control */
- reg = er32(CTRL_EXT);
- reg |= (1 << 22);
- ew32(CTRL_EXT, reg);
-
- /* Transmit Descriptor Control 0 */
- reg = er32(TXDCTL(0));
- reg |= (1 << 22);
- ew32(TXDCTL(0), reg);
-
- /* Transmit Descriptor Control 1 */
- reg = er32(TXDCTL(1));
- reg |= (1 << 22);
- ew32(TXDCTL(1), reg);
-
- /* Transmit Arbitration Control 0 */
- reg = er32(TARC(0));
- if (hw->mac.type == e1000_ich8lan)
- reg |= (1 << 28) | (1 << 29);
- reg |= (1 << 23) | (1 << 24) | (1 << 26) | (1 << 27);
- ew32(TARC(0), reg);
-
- /* Transmit Arbitration Control 1 */
- reg = er32(TARC(1));
- if (er32(TCTL) & E1000_TCTL_MULR)
- reg &= ~(1 << 28);
- else
- reg |= (1 << 28);
- reg |= (1 << 24) | (1 << 26) | (1 << 30);
- ew32(TARC(1), reg);
-
- /* Device Status */
- if (hw->mac.type == e1000_ich8lan) {
- reg = er32(STATUS);
- reg &= ~(1 << 31);
- ew32(STATUS, reg);
- }
-}
-
-/**
- * e1000_setup_link_ich8lan - Setup flow control and link settings
- * @hw: pointer to the HW structure
- *
- * Determines which flow control settings to use, then configures flow
- * control. Calls the appropriate media-specific link configuration
- * function. Assuming the adapter has a valid link partner, a valid link
- * should be established. Assumes the hardware has previously been reset
- * and the transmitter and receiver are not enabled.
- **/
-static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- if (e1000_check_reset_block(hw))
- return 0;
-
- /*
- * ICH parts do not have a word in the NVM to determine
- * the default flow control setting, so we explicitly
- * set it to full.
- */
- if (hw->fc.type == e1000_fc_default)
- hw->fc.type = e1000_fc_full;
-
- hw->fc.original_type = hw->fc.type;
-
- hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
-
- /* Continue to configure the copper link. */
- ret_val = e1000_setup_copper_link_ich8lan(hw);
- if (ret_val)
- return ret_val;
-
- ew32(FCTTV, hw->fc.pause_time);
-
- return e1000e_set_fc_watermarks(hw);
-}
-
-/**
- * e1000_setup_copper_link_ich8lan - Configure MAC/PHY interface
- * @hw: pointer to the HW structure
- *
- * Configures the kumeran interface to the PHY to wait the appropriate time
- * when polling the PHY, then call the generic setup_copper_link to finish
- * configuring the copper link.
- **/
-static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
- u16 reg_data;
-
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_SLU;
- ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ew32(CTRL, ctrl);
-
- /*
- * Set the mac to wait the maximum time between each iteration
- * and increase the max iterations when polling the phy;
- * this fixes erroneous timeouts at 10Mbps.
- */
- ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
- if (ret_val)
- return ret_val;
- ret_val = e1000e_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);
- if (ret_val)
- return ret_val;
- reg_data |= 0x3F;
- ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);
- if (ret_val)
- return ret_val;
-
- if (hw->phy.type == e1000_phy_igp_3) {
- ret_val = e1000e_copper_link_setup_igp(hw);
- if (ret_val)
- return ret_val;
- } else if (hw->phy.type == e1000_phy_bm) {
- ret_val = e1000e_copper_link_setup_m88(hw);
- if (ret_val)
- return ret_val;
- }
-
- if (hw->phy.type == e1000_phy_ife) {
- ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &reg_data);
- if (ret_val)
- return ret_val;
-
- reg_data &= ~IFE_PMC_AUTO_MDIX;
-
- switch (hw->phy.mdix) {
- case 1:
- reg_data &= ~IFE_PMC_FORCE_MDIX;
- break;
- case 2:
- reg_data |= IFE_PMC_FORCE_MDIX;
- break;
- case 0:
- default:
- reg_data |= IFE_PMC_AUTO_MDIX;
- break;
- }
- ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data);
- if (ret_val)
- return ret_val;
- }
- return e1000e_setup_copper_link(hw);
-}
-
-/**
- * e1000_get_link_up_info_ich8lan - Get current link speed and duplex
- * @hw: pointer to the HW structure
- * @speed: pointer to store current link speed
- * @duplex: pointer to store the current link duplex
- *
- * Calls the generic get_speed_and_duplex to retrieve the current link
- * information and then calls the Kumeran lock loss workaround for links at
- * gigabit speeds.
- **/
-static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
- u16 *duplex)
-{
- s32 ret_val;
-
- ret_val = e1000e_get_speed_and_duplex_copper(hw, speed, duplex);
- if (ret_val)
- return ret_val;
-
- if ((hw->mac.type == e1000_ich8lan) &&
- (hw->phy.type == e1000_phy_igp_3) &&
- (*speed == SPEED_1000)) {
- ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround
- * @hw: pointer to the HW structure
- *
- * Work-around for 82566 Kumeran PCS lock loss:
- * On link status change (i.e. PCI reset, speed change) and link is up and
- * speed is gigabit-
- * 0) if workaround is optionally disabled do nothing
- * 1) wait 1ms for Kumeran link to come up
- * 2) check Kumeran Diagnostic register PCS lock loss bit
- * 3) if not set the link is locked (all is good), otherwise...
- * 4) reset the PHY
- * 5) repeat up to 10 times
- * Note: this is only called for IGP3 copper when speed is 1gb.
- **/
-static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
-{
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
- u32 phy_ctrl;
- s32 ret_val;
- u16 i, data;
- bool link;
-
- if (!dev_spec->kmrn_lock_loss_workaround_enabled)
- return 0;
-
- /*
- * Make sure link is up before proceeding. If not just return.
- * Attempting this while link is negotiating fouled up link
- * stability
- */
- ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
- if (!link)
- return 0;
-
- for (i = 0; i < 10; i++) {
- /* read once to clear */
- ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data);
- if (ret_val)
- return ret_val;
- /* and again to get new status */
- ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data);
- if (ret_val)
- return ret_val;
-
- /* check for PCS lock */
- if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS))
- return 0;
-
- /* Issue PHY reset */
- e1000_phy_hw_reset(hw);
- mdelay(5);
- }
- /* Disable GigE link negotiation */
- phy_ctrl = er32(PHY_CTRL);
- phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE |
- E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
- ew32(PHY_CTRL, phy_ctrl);
-
- /*
- * Call gig speed drop workaround on Gig disable before accessing
- * any PHY registers
- */
- e1000e_gig_downshift_workaround_ich8lan(hw);
-
- /* unable to acquire PCS lock */
- return -E1000_ERR_PHY;
-}
-
-/**
- * e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state
- * @hw: pointer to the HW structure
- * @state: boolean value used to set the current Kumeran workaround state
- *
- * If ICH8, set the current Kumeran workaround state (enabled - TRUE
- * /disabled - FALSE).
- **/
-void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
- bool state)
-{
- struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
-
- if (hw->mac.type != e1000_ich8lan) {
- hw_dbg(hw, "Workaround applies to ICH8 only.\n");
- return;
- }
-
- dev_spec->kmrn_lock_loss_workaround_enabled = state;
-}
-
-/**
- * e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3
- * @hw: pointer to the HW structure
- *
- * Workaround for 82566 power-down on D3 entry:
- * 1) disable gigabit link
- * 2) write VR power-down enable
- * 3) read it back
- * Continue if successful, else issue LCD reset and repeat
- **/
-void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
-{
- u32 reg;
- u16 data;
- u8 retry = 0;
-
- if (hw->phy.type != e1000_phy_igp_3)
- return;
-
- /* Try the workaround twice (if needed) */
- do {
- /* Disable link */
- reg = er32(PHY_CTRL);
- reg |= (E1000_PHY_CTRL_GBE_DISABLE |
- E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
- ew32(PHY_CTRL, reg);
-
- /*
- * Call gig speed drop workaround on Gig disable before
- * accessing any PHY registers
- */
- if (hw->mac.type == e1000_ich8lan)
- e1000e_gig_downshift_workaround_ich8lan(hw);
-
- /* Write VR power-down enable */
- e1e_rphy(hw, IGP3_VR_CTRL, &data);
- data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;
- e1e_wphy(hw, IGP3_VR_CTRL, data | IGP3_VR_CTRL_MODE_SHUTDOWN);
-
- /* Read it back and test */
- e1e_rphy(hw, IGP3_VR_CTRL, &data);
- data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK;
- if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry)
- break;
-
- /* Issue PHY reset and repeat at most one more time */
- reg = er32(CTRL);
- ew32(CTRL, reg | E1000_CTRL_PHY_RST);
- retry++;
- } while (retry);
-}
-
-/**
- * e1000e_gig_downshift_workaround_ich8lan - WoL from S5 stops working
- * @hw: pointer to the HW structure
- *
- * Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC),
- * LPLU, Gig disable, MDIC PHY reset):
- * 1) Set Kumeran Near-end loopback
- * 2) Clear Kumeran Near-end loopback
- * Should only be called for ICH8[m] devices with IGP_3 Phy.
- **/
-void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 reg_data;
-
- if ((hw->mac.type != e1000_ich8lan) ||
- (hw->phy.type != e1000_phy_igp_3))
- return;
-
- ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
- &reg_data);
- if (ret_val)
- return;
- reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK;
- ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
- reg_data);
- if (ret_val)
- return;
- reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK;
- ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET,
- reg_data);
-}
-
-/**
- * e1000e_disable_gig_wol_ich8lan - disable gig during WoL
- * @hw: pointer to the HW structure
- *
- * During S0 to Sx transition, it is possible the link remains at gig
- * instead of negotiating to a lower speed. Before going to Sx, set
- * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
- * to a lower speed.
- *
- * Should only be called for ICH9 devices.
- **/
-void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
-{
- u32 phy_ctrl;
-
- if (hw->mac.type == e1000_ich9lan) {
- phy_ctrl = er32(PHY_CTRL);
- phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
- E1000_PHY_CTRL_GBE_DISABLE;
- ew32(PHY_CTRL, phy_ctrl);
- }
-
- return;
-}
-
-/**
- * e1000_cleanup_led_ich8lan - Restore the default LED operation
- * @hw: pointer to the HW structure
- *
- * Return the LED back to the default configuration.
- **/
-static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw)
-{
- if (hw->phy.type == e1000_phy_ife)
- return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
-
- ew32(LEDCTL, hw->mac.ledctl_default);
- return 0;
-}
-
-/**
- * e1000_led_on_ich8lan - Turn LEDs on
- * @hw: pointer to the HW structure
- *
- * Turn on the LEDs.
- **/
-static s32 e1000_led_on_ich8lan(struct e1000_hw *hw)
-{
- if (hw->phy.type == e1000_phy_ife)
- return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED,
- (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));
-
- ew32(LEDCTL, hw->mac.ledctl_mode2);
- return 0;
-}
-
-/**
- * e1000_led_off_ich8lan - Turn LEDs off
- * @hw: pointer to the HW structure
- *
- * Turn off the LEDs.
- **/
-static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
-{
- if (hw->phy.type == e1000_phy_ife)
- return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED,
- (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));
-
- ew32(LEDCTL, hw->mac.ledctl_mode1);
- return 0;
-}
-
-/**
- * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters
- * @hw: pointer to the HW structure
- *
- * Clears hardware counters specific to the silicon family and calls
- * clear_hw_cntrs_generic to clear all general purpose counters.
- **/
-static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
-{
- u32 temp;
-
- e1000e_clear_hw_cntrs_base(hw);
-
- temp = er32(ALGNERRC);
- temp = er32(RXERRC);
- temp = er32(TNCRS);
- temp = er32(CEXTERR);
- temp = er32(TSCTC);
- temp = er32(TSCTFC);
-
- temp = er32(MGTPRC);
- temp = er32(MGTPDC);
- temp = er32(MGTPTC);
-
- temp = er32(IAC);
- temp = er32(ICRXOC);
-
-}
-
-static struct e1000_mac_operations ich8_mac_ops = {
- .mng_mode_enab = E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT,
- .check_for_link = e1000e_check_for_copper_link,
- .cleanup_led = e1000_cleanup_led_ich8lan,
- .clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan,
- .get_bus_info = e1000_get_bus_info_ich8lan,
- .get_link_up_info = e1000_get_link_up_info_ich8lan,
- .led_on = e1000_led_on_ich8lan,
- .led_off = e1000_led_off_ich8lan,
- .update_mc_addr_list = e1000e_update_mc_addr_list_generic,
- .reset_hw = e1000_reset_hw_ich8lan,
- .init_hw = e1000_init_hw_ich8lan,
- .setup_link = e1000_setup_link_ich8lan,
- .setup_physical_interface= e1000_setup_copper_link_ich8lan,
-};
-
-static struct e1000_phy_operations ich8_phy_ops = {
- .acquire_phy = e1000_acquire_swflag_ich8lan,
- .check_reset_block = e1000_check_reset_block_ich8lan,
- .commit_phy = NULL,
- .force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan,
- .get_cfg_done = e1000e_get_cfg_done,
- .get_cable_length = e1000e_get_cable_length_igp_2,
- .get_phy_info = e1000_get_phy_info_ich8lan,
- .read_phy_reg = e1000e_read_phy_reg_igp,
- .release_phy = e1000_release_swflag_ich8lan,
- .reset_phy = e1000_phy_hw_reset_ich8lan,
- .set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan,
- .set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan,
- .write_phy_reg = e1000e_write_phy_reg_igp,
-};
-
-static struct e1000_nvm_operations ich8_nvm_ops = {
- .acquire_nvm = e1000_acquire_swflag_ich8lan,
- .read_nvm = e1000_read_nvm_ich8lan,
- .release_nvm = e1000_release_swflag_ich8lan,
- .update_nvm = e1000_update_nvm_checksum_ich8lan,
- .valid_led_default = e1000_valid_led_default_ich8lan,
- .validate_nvm = e1000_validate_nvm_checksum_ich8lan,
- .write_nvm = e1000_write_nvm_ich8lan,
-};
-
-struct e1000_info e1000_ich8_info = {
- .mac = e1000_ich8lan,
- .flags = FLAG_HAS_WOL
- | FLAG_IS_ICH
- | FLAG_RX_CSUM_ENABLED
- | FLAG_HAS_CTRLEXT_ON_LOAD
- | FLAG_HAS_AMT
- | FLAG_HAS_FLASH
- | FLAG_APME_IN_WUC,
- .pba = 8,
- .get_variants = e1000_get_variants_ich8lan,
- .mac_ops = &ich8_mac_ops,
- .phy_ops = &ich8_phy_ops,
- .nvm_ops = &ich8_nvm_ops,
-};
-
-struct e1000_info e1000_ich9_info = {
- .mac = e1000_ich9lan,
- .flags = FLAG_HAS_JUMBO_FRAMES
- | FLAG_IS_ICH
- | FLAG_HAS_WOL
- | FLAG_RX_CSUM_ENABLED
- | FLAG_HAS_CTRLEXT_ON_LOAD
- | FLAG_HAS_AMT
- | FLAG_HAS_ERT
- | FLAG_HAS_FLASH
- | FLAG_APME_IN_WUC,
- .pba = 10,
- .get_variants = e1000_get_variants_ich8lan,
- .mac_ops = &ich8_mac_ops,
- .phy_ops = &ich8_phy_ops,
- .nvm_ops = &ich8_nvm_ops,
-};
-
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
deleted file mode 100644
index f1f4e9dfd0a..00000000000
--- a/drivers/net/e1000e/lib.c
+++ /dev/null
@@ -1,2500 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include "e1000.h"
-
-enum e1000_mng_mode {
- e1000_mng_mode_none = 0,
- e1000_mng_mode_asf,
- e1000_mng_mode_pt,
- e1000_mng_mode_ipmi,
- e1000_mng_mode_host_if_only
-};
-
-#define E1000_FACTPS_MNGCG 0x20000000
-
-/* Intel(R) Active Management Technology signature */
-#define E1000_IAMT_SIGNATURE 0x544D4149
-
-/**
- * e1000e_get_bus_info_pcie - Get PCIe bus information
- * @hw: pointer to the HW structure
- *
- * Determines and stores the system bus information for a particular
- * network interface. The following bus information is determined and stored:
- * bus speed, bus width, type (PCIe), and PCIe function.
- **/
-s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
-{
- struct e1000_bus_info *bus = &hw->bus;
- struct e1000_adapter *adapter = hw->adapter;
- u32 status;
- u16 pcie_link_status, pci_header_type, cap_offset;
-
- cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
- if (!cap_offset) {
- bus->width = e1000_bus_width_unknown;
- } else {
- pci_read_config_word(adapter->pdev,
- cap_offset + PCIE_LINK_STATUS,
- &pcie_link_status);
- bus->width = (enum e1000_bus_width)((pcie_link_status &
- PCIE_LINK_WIDTH_MASK) >>
- PCIE_LINK_WIDTH_SHIFT);
- }
-
- pci_read_config_word(adapter->pdev, PCI_HEADER_TYPE_REGISTER,
- &pci_header_type);
- if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) {
- status = er32(STATUS);
- bus->func = (status & E1000_STATUS_FUNC_MASK)
- >> E1000_STATUS_FUNC_SHIFT;
- } else {
- bus->func = 0;
- }
-
- return 0;
-}
-
-/**
- * e1000e_write_vfta - Write value to VLAN filter table
- * @hw: pointer to the HW structure
- * @offset: register offset in VLAN filter table
- * @value: register value written to VLAN filter table
- *
- * Writes value at the given offset in the register array which stores
- * the VLAN filter table.
- **/
-void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
-{
- E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
- e1e_flush();
-}
-
-/**
- * e1000e_init_rx_addrs - Initialize receive address's
- * @hw: pointer to the HW structure
- * @rar_count: receive address registers
- *
- * Setups the receive address registers by setting the base receive address
- * register to the devices MAC address and clearing all the other receive
- * address registers to 0.
- **/
-void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
-{
- u32 i;
-
- /* Setup the receive address */
- hw_dbg(hw, "Programming MAC Address into RAR[0]\n");
-
- e1000e_rar_set(hw, hw->mac.addr, 0);
-
- /* Zero out the other (rar_entry_count - 1) receive addresses */
- hw_dbg(hw, "Clearing RAR[1-%u]\n", rar_count-1);
- for (i = 1; i < rar_count; i++) {
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0);
- e1e_flush();
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0);
- e1e_flush();
- }
-}
-
-/**
- * e1000e_rar_set - Set receive address register
- * @hw: pointer to the HW structure
- * @addr: pointer to the receive address
- * @index: receive address array register
- *
- * Sets the receive address array register at index to the address passed
- * in by addr.
- **/
-void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
-{
- u32 rar_low, rar_high;
-
- /*
- * HW expects these in little endian so we reverse the byte order
- * from network order (big endian) to little endian
- */
- rar_low = ((u32) addr[0] |
- ((u32) addr[1] << 8) |
- ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
-
- rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
-
- rar_high |= E1000_RAH_AV;
-
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
-}
-
-/**
- * e1000_mta_set - Set multicast filter table address
- * @hw: pointer to the HW structure
- * @hash_value: determines the MTA register and bit to set
- *
- * The multicast table address is a register array of 32-bit registers.
- * The hash_value is used to determine what register the bit is in, the
- * current value is read, the new bit is OR'd in and the new value is
- * written back into the register.
- **/
-static void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
-{
- u32 hash_bit, hash_reg, mta;
-
- /*
- * The MTA is a register array of 32-bit registers. It is
- * treated like an array of (32*mta_reg_count) bits. We want to
- * set bit BitArray[hash_value]. So we figure out what register
- * the bit is in, read it, OR in the new bit, then write
- * back the new value. The (hw->mac.mta_reg_count - 1) serves as a
- * mask to bits 31:5 of the hash value which gives us the
- * register we're modifying. The hash bit within that register
- * is determined by the lower 5 bits of the hash value.
- */
- hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
- hash_bit = hash_value & 0x1F;
-
- mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg);
-
- mta |= (1 << hash_bit);
-
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta);
- e1e_flush();
-}
-
-/**
- * e1000_hash_mc_addr - Generate a multicast hash value
- * @hw: pointer to the HW structure
- * @mc_addr: pointer to a multicast address
- *
- * Generates a multicast address hash value which is used to determine
- * the multicast filter table array address and new table value. See
- * e1000_mta_set_generic()
- **/
-static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
-{
- u32 hash_value, hash_mask;
- u8 bit_shift = 0;
-
- /* Register count multiplied by bits per register */
- hash_mask = (hw->mac.mta_reg_count * 32) - 1;
-
- /*
- * For a mc_filter_type of 0, bit_shift is the number of left-shifts
- * where 0xFF would still fall within the hash mask.
- */
- while (hash_mask >> bit_shift != 0xFF)
- bit_shift++;
-
- /*
- * The portion of the address that is used for the hash table
- * is determined by the mc_filter_type setting.
- * The algorithm is such that there is a total of 8 bits of shifting.
- * The bit_shift for a mc_filter_type of 0 represents the number of
- * left-shifts where the MSB of mc_addr[5] would still fall within
- * the hash_mask. Case 0 does this exactly. Since there are a total
- * of 8 bits of shifting, then mc_addr[4] will shift right the
- * remaining number of bits. Thus 8 - bit_shift. The rest of the
- * cases are a variation of this algorithm...essentially raising the
- * number of bits to shift mc_addr[5] left, while still keeping the
- * 8-bit shifting total.
- *
- * For example, given the following Destination MAC Address and an
- * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
- * we can see that the bit_shift for case 0 is 4. These are the hash
- * values resulting from each mc_filter_type...
- * [0] [1] [2] [3] [4] [5]
- * 01 AA 00 12 34 56
- * LSB MSB
- *
- * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
- * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
- * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
- * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
- */
- switch (hw->mac.mc_filter_type) {
- default:
- case 0:
- break;
- case 1:
- bit_shift += 1;
- break;
- case 2:
- bit_shift += 2;
- break;
- case 3:
- bit_shift += 4;
- break;
- }
-
- hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
- (((u16) mc_addr[5]) << bit_shift)));
-
- return hash_value;
-}
-
-/**
- * e1000e_update_mc_addr_list_generic - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
- *
- * Updates the Receive Address Registers and Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this.
- **/
-void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count,
- u32 rar_used_count, u32 rar_count)
-{
- u32 hash_value;
- u32 i;
-
- /*
- * Load the first set of multicast addresses into the exact
- * filters (RAR). If there are not enough to fill the RAR
- * array, clear the filters.
- */
- for (i = rar_used_count; i < rar_count; i++) {
- if (mc_addr_count) {
- e1000e_rar_set(hw, mc_addr_list, i);
- mc_addr_count--;
- mc_addr_list += ETH_ALEN;
- } else {
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0);
- e1e_flush();
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0);
- e1e_flush();
- }
- }
-
- /* Clear the old settings from the MTA */
- hw_dbg(hw, "Clearing MTA\n");
- for (i = 0; i < hw->mac.mta_reg_count; i++) {
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
- e1e_flush();
- }
-
- /* Load any remaining multicast addresses into the hash table. */
- for (; mc_addr_count > 0; mc_addr_count--) {
- hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
- hw_dbg(hw, "Hash value = 0x%03X\n", hash_value);
- e1000_mta_set(hw, hash_value);
- mc_addr_list += ETH_ALEN;
- }
-}
-
-/**
- * e1000e_clear_hw_cntrs_base - Clear base hardware counters
- * @hw: pointer to the HW structure
- *
- * Clears the base hardware counters by reading the counter registers.
- **/
-void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
-{
- u32 temp;
-
- temp = er32(CRCERRS);
- temp = er32(SYMERRS);
- temp = er32(MPC);
- temp = er32(SCC);
- temp = er32(ECOL);
- temp = er32(MCC);
- temp = er32(LATECOL);
- temp = er32(COLC);
- temp = er32(DC);
- temp = er32(SEC);
- temp = er32(RLEC);
- temp = er32(XONRXC);
- temp = er32(XONTXC);
- temp = er32(XOFFRXC);
- temp = er32(XOFFTXC);
- temp = er32(FCRUC);
- temp = er32(GPRC);
- temp = er32(BPRC);
- temp = er32(MPRC);
- temp = er32(GPTC);
- temp = er32(GORCL);
- temp = er32(GORCH);
- temp = er32(GOTCL);
- temp = er32(GOTCH);
- temp = er32(RNBC);
- temp = er32(RUC);
- temp = er32(RFC);
- temp = er32(ROC);
- temp = er32(RJC);
- temp = er32(TORL);
- temp = er32(TORH);
- temp = er32(TOTL);
- temp = er32(TOTH);
- temp = er32(TPR);
- temp = er32(TPT);
- temp = er32(MPTC);
- temp = er32(BPTC);
-}
-
-/**
- * e1000e_check_for_copper_link - Check for link (Copper)
- * @hw: pointer to the HW structure
- *
- * Checks to see of the link status of the hardware has changed. If a
- * change in link status has been detected, then we read the PHY registers
- * to get the current speed/duplex if link exists.
- **/
-s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
- bool link;
-
- /*
- * We only want to go out to the PHY registers to see if Auto-Neg
- * has completed and/or if our link status has changed. The
- * get_link_status flag is set upon receiving a Link Status
- * Change or Rx Sequence Error interrupt.
- */
- if (!mac->get_link_status)
- return 0;
-
- /*
- * First we want to see if the MII Status Register reports
- * link. If so, then we want to get the current speed/duplex
- * of the PHY.
- */
- ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link)
- return ret_val; /* No link detected */
-
- mac->get_link_status = 0;
-
- /*
- * Check if there was DownShift, must be checked
- * immediately after link-up
- */
- e1000e_check_downshift(hw);
-
- /*
- * If we are forcing speed/duplex, then we simply return since
- * we have already determined whether we have link or not.
- */
- if (!mac->autoneg) {
- ret_val = -E1000_ERR_CONFIG;
- return ret_val;
- }
-
- /*
- * Auto-Neg is enabled. Auto Speed Detection takes care
- * of MAC speed/duplex configuration. So we only need to
- * configure Collision Distance in the MAC.
- */
- e1000e_config_collision_dist(hw);
-
- /*
- * Configure Flow Control now that Auto-Neg has completed.
- * First, we need to restore the desired flow control
- * settings because we may have had to re-autoneg with a
- * different link partner.
- */
- ret_val = e1000e_config_fc_after_link_up(hw);
- if (ret_val) {
- hw_dbg(hw, "Error configuring flow control\n");
- }
-
- return ret_val;
-}
-
-/**
- * e1000e_check_for_fiber_link - Check for link (Fiber)
- * @hw: pointer to the HW structure
- *
- * Checks for link up on the hardware. If link is not up and we have
- * a signal, then we need to force link up.
- **/
-s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 rxcw;
- u32 ctrl;
- u32 status;
- s32 ret_val;
-
- ctrl = er32(CTRL);
- status = er32(STATUS);
- rxcw = er32(RXCW);
-
- /*
- * If we don't have link (auto-negotiation failed or link partner
- * cannot auto-negotiate), the cable is plugged in (we have signal),
- * and our link partner is not trying to auto-negotiate with us (we
- * are receiving idles or data), we need to force link up. We also
- * need to give auto-negotiation time to complete, in case the cable
- * was just plugged in. The autoneg_failed flag does this.
- */
- /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
- if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) &&
- (!(rxcw & E1000_RXCW_C))) {
- if (mac->autoneg_failed == 0) {
- mac->autoneg_failed = 1;
- return 0;
- }
- hw_dbg(hw, "NOT RXing /C/, disable AutoNeg and force link.\n");
-
- /* Disable auto-negotiation in the TXCW register */
- ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
-
- /* Force link-up and also force full-duplex. */
- ctrl = er32(CTRL);
- ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
- ew32(CTRL, ctrl);
-
- /* Configure Flow Control after forcing link up. */
- ret_val = e1000e_config_fc_after_link_up(hw);
- if (ret_val) {
- hw_dbg(hw, "Error configuring flow control\n");
- return ret_val;
- }
- } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
- /*
- * If we are forcing link and we are receiving /C/ ordered
- * sets, re-enable auto-negotiation in the TXCW register
- * and disable forced link in the Device Control register
- * in an attempt to auto-negotiate with our link partner.
- */
- hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n");
- ew32(TXCW, mac->txcw);
- ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
-
- mac->serdes_has_link = 1;
- }
-
- return 0;
-}
-
-/**
- * e1000e_check_for_serdes_link - Check for link (Serdes)
- * @hw: pointer to the HW structure
- *
- * Checks for link up on the hardware. If link is not up and we have
- * a signal, then we need to force link up.
- **/
-s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 rxcw;
- u32 ctrl;
- u32 status;
- s32 ret_val;
-
- ctrl = er32(CTRL);
- status = er32(STATUS);
- rxcw = er32(RXCW);
-
- /*
- * If we don't have link (auto-negotiation failed or link partner
- * cannot auto-negotiate), and our link partner is not trying to
- * auto-negotiate with us (we are receiving idles or data),
- * we need to force link up. We also need to give auto-negotiation
- * time to complete.
- */
- /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
- if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
- if (mac->autoneg_failed == 0) {
- mac->autoneg_failed = 1;
- return 0;
- }
- hw_dbg(hw, "NOT RXing /C/, disable AutoNeg and force link.\n");
-
- /* Disable auto-negotiation in the TXCW register */
- ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
-
- /* Force link-up and also force full-duplex. */
- ctrl = er32(CTRL);
- ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
- ew32(CTRL, ctrl);
-
- /* Configure Flow Control after forcing link up. */
- ret_val = e1000e_config_fc_after_link_up(hw);
- if (ret_val) {
- hw_dbg(hw, "Error configuring flow control\n");
- return ret_val;
- }
- } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
- /*
- * If we are forcing link and we are receiving /C/ ordered
- * sets, re-enable auto-negotiation in the TXCW register
- * and disable forced link in the Device Control register
- * in an attempt to auto-negotiate with our link partner.
- */
- hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n");
- ew32(TXCW, mac->txcw);
- ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
-
- mac->serdes_has_link = 1;
- } else if (!(E1000_TXCW_ANE & er32(TXCW))) {
- /*
- * If we force link for non-auto-negotiation switch, check
- * link status based on MAC synchronization for internal
- * serdes media type.
- */
- /* SYNCH bit and IV bit are sticky. */
- udelay(10);
- if (E1000_RXCW_SYNCH & er32(RXCW)) {
- if (!(rxcw & E1000_RXCW_IV)) {
- mac->serdes_has_link = 1;
- hw_dbg(hw, "SERDES: Link is up.\n");
- }
- } else {
- mac->serdes_has_link = 0;
- hw_dbg(hw, "SERDES: Link is down.\n");
- }
- }
-
- if (E1000_TXCW_ANE & er32(TXCW)) {
- status = er32(STATUS);
- mac->serdes_has_link = (status & E1000_STATUS_LU);
- }
-
- return 0;
-}
-
-/**
- * e1000_set_default_fc_generic - Set flow control default values
- * @hw: pointer to the HW structure
- *
- * Read the EEPROM for the default values for flow control and store the
- * values.
- **/
-static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 nvm_data;
-
- /*
- * Read and store word 0x0F of the EEPROM. This word contains bits
- * that determine the hardware's default PAUSE (flow control) mode,
- * a bit that determines whether the HW defaults to enabling or
- * disabling auto-negotiation, and the direction of the
- * SW defined pins. If there is no SW over-ride of the flow
- * control setting, then the variable hw->fc will
- * be initialized based on a value in the EEPROM.
- */
- ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
-
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
-
- if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
- hw->fc.type = e1000_fc_none;
- else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
- NVM_WORD0F_ASM_DIR)
- hw->fc.type = e1000_fc_tx_pause;
- else
- hw->fc.type = e1000_fc_full;
-
- return 0;
-}
-
-/**
- * e1000e_setup_link - Setup flow control and link settings
- * @hw: pointer to the HW structure
- *
- * Determines which flow control settings to use, then configures flow
- * control. Calls the appropriate media-specific link configuration
- * function. Assuming the adapter has a valid link partner, a valid link
- * should be established. Assumes the hardware has previously been reset
- * and the transmitter and receiver are not enabled.
- **/
-s32 e1000e_setup_link(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
-
- /*
- * In the case of the phy reset being blocked, we already have a link.
- * We do not need to set it up again.
- */
- if (e1000_check_reset_block(hw))
- return 0;
-
- /*
- * If flow control is set to default, set flow control based on
- * the EEPROM flow control settings.
- */
- if (hw->fc.type == e1000_fc_default) {
- ret_val = e1000_set_default_fc_generic(hw);
- if (ret_val)
- return ret_val;
- }
-
- /*
- * We want to save off the original Flow Control configuration just
- * in case we get disconnected and then reconnected into a different
- * hub or switch with different Flow Control capabilities.
- */
- hw->fc.original_type = hw->fc.type;
-
- hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
-
- /* Call the necessary media_type subroutine to configure the link. */
- ret_val = mac->ops.setup_physical_interface(hw);
- if (ret_val)
- return ret_val;
-
- /*
- * Initialize the flow control address, type, and PAUSE timer
- * registers to their default values. This is done even if flow
- * control is disabled, because it does not hurt anything to
- * initialize these registers.
- */
- hw_dbg(hw, "Initializing the Flow Control address, type and timer regs\n");
- ew32(FCT, FLOW_CONTROL_TYPE);
- ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
- ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
-
- ew32(FCTTV, hw->fc.pause_time);
-
- return e1000e_set_fc_watermarks(hw);
-}
-
-/**
- * e1000_commit_fc_settings_generic - Configure flow control
- * @hw: pointer to the HW structure
- *
- * Write the flow control settings to the Transmit Config Word Register (TXCW)
- * base on the flow control settings in e1000_mac_info.
- **/
-static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 txcw;
-
- /*
- * Check for a software override of the flow control settings, and
- * setup the device accordingly. If auto-negotiation is enabled, then
- * software will have to set the "PAUSE" bits to the correct value in
- * the Transmit Config Word Register (TXCW) and re-start auto-
- * negotiation. However, if auto-negotiation is disabled, then
- * software will have to manually configure the two flow control enable
- * bits in the CTRL register.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames,
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but we
- * do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- */
- switch (hw->fc.type) {
- case e1000_fc_none:
- /* Flow control completely disabled by a software over-ride. */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
- break;
- case e1000_fc_rx_pause:
- /*
- * Rx Flow control is enabled and Tx Flow control is disabled
- * by a software over-ride. Since there really isn't a way to
- * advertise that we are capable of Rx Pause ONLY, we will
- * advertise that we support both symmetric and asymmetric Rx
- * PAUSE. Later, we will disable the adapter's ability to send
- * PAUSE frames.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- case e1000_fc_tx_pause:
- /*
- * Tx Flow control is enabled, and Rx Flow control is disabled,
- * by a software over-ride.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
- break;
- case e1000_fc_full:
- /*
- * Flow control (both Rx and Tx) is enabled by a software
- * over-ride.
- */
- txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
- break;
- default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- break;
- }
-
- ew32(TXCW, txcw);
- mac->txcw = txcw;
-
- return 0;
-}
-
-/**
- * e1000_poll_fiber_serdes_link_generic - Poll for link up
- * @hw: pointer to the HW structure
- *
- * Polls for link up by reading the status register, if link fails to come
- * up with auto-negotiation, then the link is forced if a signal is detected.
- **/
-static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 i, status;
- s32 ret_val;
-
- /*
- * If we have a signal (the cable is plugged in, or assumed true for
- * serdes media) then poll for a "Link-Up" indication in the Device
- * Status Register. Time-out if a link isn't seen in 500 milliseconds
- * seconds (Auto-negotiation should complete in less than 500
- * milliseconds even if the other end is doing it in SW).
- */
- for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
- msleep(10);
- status = er32(STATUS);
- if (status & E1000_STATUS_LU)
- break;
- }
- if (i == FIBER_LINK_UP_LIMIT) {
- hw_dbg(hw, "Never got a valid link from auto-neg!!!\n");
- mac->autoneg_failed = 1;
- /*
- * AutoNeg failed to achieve a link, so we'll call
- * mac->check_for_link. This routine will force the
- * link up if we detect a signal. This will allow us to
- * communicate with non-autonegotiating link partners.
- */
- ret_val = mac->ops.check_for_link(hw);
- if (ret_val) {
- hw_dbg(hw, "Error while checking for link\n");
- return ret_val;
- }
- mac->autoneg_failed = 0;
- } else {
- mac->autoneg_failed = 0;
- hw_dbg(hw, "Valid Link Found\n");
- }
-
- return 0;
-}
-
-/**
- * e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes
- * @hw: pointer to the HW structure
- *
- * Configures collision distance and flow control for fiber and serdes
- * links. Upon successful setup, poll for link.
- **/
-s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 ret_val;
-
- ctrl = er32(CTRL);
-
- /* Take the link out of reset */
- ctrl &= ~E1000_CTRL_LRST;
-
- e1000e_config_collision_dist(hw);
-
- ret_val = e1000_commit_fc_settings_generic(hw);
- if (ret_val)
- return ret_val;
-
- /*
- * Since auto-negotiation is enabled, take the link out of reset (the
- * link will be in reset, because we previously reset the chip). This
- * will restart auto-negotiation. If auto-negotiation is successful
- * then the link-up status bit will be set and the flow control enable
- * bits (RFCE and TFCE) will be set according to their negotiated value.
- */
- hw_dbg(hw, "Auto-negotiation enabled\n");
-
- ew32(CTRL, ctrl);
- e1e_flush();
- msleep(1);
-
- /*
- * For these adapters, the SW definable pin 1 is set when the optics
- * detect a signal. If we have a signal, then poll for a "Link-Up"
- * indication.
- */
- if (hw->phy.media_type == e1000_media_type_internal_serdes ||
- (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
- ret_val = e1000_poll_fiber_serdes_link_generic(hw);
- } else {
- hw_dbg(hw, "No signal detected\n");
- }
-
- return 0;
-}
-
-/**
- * e1000e_config_collision_dist - Configure collision distance
- * @hw: pointer to the HW structure
- *
- * Configures the collision distance to the default value and is used
- * during link setup. Currently no func pointer exists and all
- * implementations are handled in the generic version of this function.
- **/
-void e1000e_config_collision_dist(struct e1000_hw *hw)
-{
- u32 tctl;
-
- tctl = er32(TCTL);
-
- tctl &= ~E1000_TCTL_COLD;
- tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
-
- ew32(TCTL, tctl);
- e1e_flush();
-}
-
-/**
- * e1000e_set_fc_watermarks - Set flow control high/low watermarks
- * @hw: pointer to the HW structure
- *
- * Sets the flow control high/low threshold (watermark) registers. If
- * flow control XON frame transmission is enabled, then set XON frame
- * transmission as well.
- **/
-s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
-{
- u32 fcrtl = 0, fcrth = 0;
-
- /*
- * Set the flow control receive threshold registers. Normally,
- * these registers will be set to a default threshold that may be
- * adjusted later by the driver's runtime code. However, if the
- * ability to transmit pause frames is not enabled, then these
- * registers will be set to 0.
- */
- if (hw->fc.type & e1000_fc_tx_pause) {
- /*
- * We need to set up the Receive Threshold high and low water
- * marks as well as (optionally) enabling the transmission of
- * XON frames.
- */
- fcrtl = hw->fc.low_water;
- fcrtl |= E1000_FCRTL_XONE;
- fcrth = hw->fc.high_water;
- }
- ew32(FCRTL, fcrtl);
- ew32(FCRTH, fcrth);
-
- return 0;
-}
-
-/**
- * e1000e_force_mac_fc - Force the MAC's flow control settings
- * @hw: pointer to the HW structure
- *
- * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the
- * device control register to reflect the adapter settings. TFCE and RFCE
- * need to be explicitly set by software when a copper PHY is used because
- * autonegotiation is managed by the PHY rather than the MAC. Software must
- * also configure these bits when link is forced on a fiber connection.
- **/
-s32 e1000e_force_mac_fc(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- ctrl = er32(CTRL);
-
- /*
- * Because we didn't get link via the internal auto-negotiation
- * mechanism (we either forced link or we got link via PHY
- * auto-neg), we have to manually enable/disable transmit an
- * receive flow control.
- *
- * The "Case" statement below enables/disable flow control
- * according to the "hw->fc.type" parameter.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause
- * frames but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * frames but we do not receive pause frames).
- * 3: Both Rx and Tx flow control (symmetric) is enabled.
- * other: No other values should be possible at this point.
- */
- hw_dbg(hw, "hw->fc.type = %u\n", hw->fc.type);
-
- switch (hw->fc.type) {
- case e1000_fc_none:
- ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
- break;
- case e1000_fc_rx_pause:
- ctrl &= (~E1000_CTRL_TFCE);
- ctrl |= E1000_CTRL_RFCE;
- break;
- case e1000_fc_tx_pause:
- ctrl &= (~E1000_CTRL_RFCE);
- ctrl |= E1000_CTRL_TFCE;
- break;
- case e1000_fc_full:
- ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
- break;
- default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
- return -E1000_ERR_CONFIG;
- }
-
- ew32(CTRL, ctrl);
-
- return 0;
-}
-
-/**
- * e1000e_config_fc_after_link_up - Configures flow control after link
- * @hw: pointer to the HW structure
- *
- * Checks the status of auto-negotiation after link up to ensure that the
- * speed and duplex were not forced. If the link needed to be forced, then
- * flow control needs to be forced also. If auto-negotiation is enabled
- * and did not fail, then we configure flow control based on our link
- * partner.
- **/
-s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val = 0;
- u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
- u16 speed, duplex;
-
- /*
- * Check for the case where we have fiber media and auto-neg failed
- * so we had to force link. In this case, we need to force the
- * configuration of the MAC to match the "fc" parameter.
- */
- if (mac->autoneg_failed) {
- if (hw->phy.media_type == e1000_media_type_fiber ||
- hw->phy.media_type == e1000_media_type_internal_serdes)
- ret_val = e1000e_force_mac_fc(hw);
- } else {
- if (hw->phy.media_type == e1000_media_type_copper)
- ret_val = e1000e_force_mac_fc(hw);
- }
-
- if (ret_val) {
- hw_dbg(hw, "Error forcing flow control settings\n");
- return ret_val;
- }
-
- /*
- * Check for the case where we have copper media and auto-neg is
- * enabled. In this case, we need to check and see if Auto-Neg
- * has completed, and if so, how the PHY and link partner has
- * flow control configured.
- */
- if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
- /*
- * Read the MII Status Register and check to see if AutoNeg
- * has completed. We read this twice because this reg has
- * some "sticky" (latched) bits.
- */
- ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
- ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
- if (ret_val)
- return ret_val;
-
- if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
- hw_dbg(hw, "Copper PHY and Auto Neg "
- "has not completed.\n");
- return ret_val;
- }
-
- /*
- * The AutoNeg process has completed, so we now need to
- * read both the Auto Negotiation Advertisement
- * Register (Address 4) and the Auto_Negotiation Base
- * Page Ability Register (Address 5) to determine how
- * flow control was negotiated.
- */
- ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg);
- if (ret_val)
- return ret_val;
- ret_val = e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg);
- if (ret_val)
- return ret_val;
-
- /*
- * Two bits in the Auto Negotiation Advertisement Register
- * (Address 4) and two bits in the Auto Negotiation Base
- * Page Ability Register (Address 5) determine flow control
- * for both the PHY and the link partner. The following
- * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
- * 1999, describes these PAUSE resolution bits and how flow
- * control is determined based upon these settings.
- * NOTE: DC = Don't Care
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
- *-------|---------|-------|---------|--------------------
- * 0 | 0 | DC | DC | e1000_fc_none
- * 0 | 1 | 0 | DC | e1000_fc_none
- * 0 | 1 | 1 | 0 | e1000_fc_none
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- * 1 | 0 | 0 | DC | e1000_fc_none
- * 1 | DC | 1 | DC | e1000_fc_full
- * 1 | 1 | 0 | 0 | e1000_fc_none
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
- *
- *
- * Are both PAUSE bits set to 1? If so, this implies
- * Symmetric Flow Control is enabled at both ends. The
- * ASM_DIR bits are irrelevant per the spec.
- *
- * For Symmetric Flow Control:
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | DC | 1 | DC | E1000_fc_full
- *
- */
- if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
- /*
- * Now we need to check if the user selected Rx ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise Rx
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
- */
- if (hw->fc.original_type == e1000_fc_full) {
- hw->fc.type = e1000_fc_full;
- hw_dbg(hw, "Flow Control = FULL.\r\n");
- } else {
- hw->fc.type = e1000_fc_rx_pause;
- hw_dbg(hw, "Flow Control = "
- "RX PAUSE frames only.\r\n");
- }
- }
- /*
- * For receiving PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- *
- */
- else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc.type = e1000_fc_tx_pause;
- hw_dbg(hw, "Flow Control = Tx PAUSE frames only.\r\n");
- }
- /*
- * For transmitting PAUSE frames ONLY.
- *
- * LOCAL DEVICE | LINK PARTNER
- * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
- *-------|---------|-------|---------|--------------------
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
- *
- */
- else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
- !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc.type = e1000_fc_rx_pause;
- hw_dbg(hw, "Flow Control = Rx PAUSE frames only.\r\n");
- } else {
- /*
- * Per the IEEE spec, at this point flow control
- * should be disabled.
- */
- hw->fc.type = e1000_fc_none;
- hw_dbg(hw, "Flow Control = NONE.\r\n");
- }
-
- /*
- * Now we need to do one last check... If we auto-
- * negotiated to HALF DUPLEX, flow control should not be
- * enabled per IEEE 802.3 spec.
- */
- ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
- if (ret_val) {
- hw_dbg(hw, "Error getting link speed and duplex\n");
- return ret_val;
- }
-
- if (duplex == HALF_DUPLEX)
- hw->fc.type = e1000_fc_none;
-
- /*
- * Now we call a subroutine to actually force the MAC
- * controller to use the correct flow control settings.
- */
- ret_val = e1000e_force_mac_fc(hw);
- if (ret_val) {
- hw_dbg(hw, "Error forcing flow control settings\n");
- return ret_val;
- }
- }
-
- return 0;
-}
-
-/**
- * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
- * @hw: pointer to the HW structure
- * @speed: stores the current speed
- * @duplex: stores the current duplex
- *
- * Read the status register for the current speed/duplex and store the current
- * speed and duplex for copper connections.
- **/
-s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex)
-{
- u32 status;
-
- status = er32(STATUS);
- if (status & E1000_STATUS_SPEED_1000) {
- *speed = SPEED_1000;
- hw_dbg(hw, "1000 Mbs, ");
- } else if (status & E1000_STATUS_SPEED_100) {
- *speed = SPEED_100;
- hw_dbg(hw, "100 Mbs, ");
- } else {
- *speed = SPEED_10;
- hw_dbg(hw, "10 Mbs, ");
- }
-
- if (status & E1000_STATUS_FD) {
- *duplex = FULL_DUPLEX;
- hw_dbg(hw, "Full Duplex\n");
- } else {
- *duplex = HALF_DUPLEX;
- hw_dbg(hw, "Half Duplex\n");
- }
-
- return 0;
-}
-
-/**
- * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
- * @hw: pointer to the HW structure
- * @speed: stores the current speed
- * @duplex: stores the current duplex
- *
- * Sets the speed and duplex to gigabit full duplex (the only possible option)
- * for fiber/serdes links.
- **/
-s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex)
-{
- *speed = SPEED_1000;
- *duplex = FULL_DUPLEX;
-
- return 0;
-}
-
-/**
- * e1000e_get_hw_semaphore - Acquire hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Acquire the HW semaphore to access the PHY or NVM
- **/
-s32 e1000e_get_hw_semaphore(struct e1000_hw *hw)
-{
- u32 swsm;
- s32 timeout = hw->nvm.word_size + 1;
- s32 i = 0;
-
- /* Get the SW semaphore */
- while (i < timeout) {
- swsm = er32(SWSM);
- if (!(swsm & E1000_SWSM_SMBI))
- break;
-
- udelay(50);
- i++;
- }
-
- if (i == timeout) {
- hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
- return -E1000_ERR_NVM;
- }
-
- /* Get the FW semaphore. */
- for (i = 0; i < timeout; i++) {
- swsm = er32(SWSM);
- ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
-
- /* Semaphore acquired if bit latched */
- if (er32(SWSM) & E1000_SWSM_SWESMBI)
- break;
-
- udelay(50);
- }
-
- if (i == timeout) {
- /* Release semaphores */
- e1000e_put_hw_semaphore(hw);
- hw_dbg(hw, "Driver can't access the NVM\n");
- return -E1000_ERR_NVM;
- }
-
- return 0;
-}
-
-/**
- * e1000e_put_hw_semaphore - Release hardware semaphore
- * @hw: pointer to the HW structure
- *
- * Release hardware semaphore used to access the PHY or NVM
- **/
-void e1000e_put_hw_semaphore(struct e1000_hw *hw)
-{
- u32 swsm;
-
- swsm = er32(SWSM);
- swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
- ew32(SWSM, swsm);
-}
-
-/**
- * e1000e_get_auto_rd_done - Check for auto read completion
- * @hw: pointer to the HW structure
- *
- * Check EEPROM for Auto Read done bit.
- **/
-s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
-{
- s32 i = 0;
-
- while (i < AUTO_READ_DONE_TIMEOUT) {
- if (er32(EECD) & E1000_EECD_AUTO_RD)
- break;
- msleep(1);
- i++;
- }
-
- if (i == AUTO_READ_DONE_TIMEOUT) {
- hw_dbg(hw, "Auto read by HW from NVM has not completed.\n");
- return -E1000_ERR_RESET;
- }
-
- return 0;
-}
-
-/**
- * e1000e_valid_led_default - Verify a valid default LED config
- * @hw: pointer to the HW structure
- * @data: pointer to the NVM (EEPROM)
- *
- * Read the EEPROM for the current default LED configuration. If the
- * LED configuration is not valid, set to a valid LED configuration.
- **/
-s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data)
-{
- s32 ret_val;
-
- ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
-
- if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
- *data = ID_LED_DEFAULT;
-
- return 0;
-}
-
-/**
- * e1000e_id_led_init -
- * @hw: pointer to the HW structure
- *
- **/
-s32 e1000e_id_led_init(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
- const u32 ledctl_mask = 0x000000FF;
- const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
- const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
- u16 data, i, temp;
- const u16 led_mask = 0x0F;
-
- ret_val = hw->nvm.ops.valid_led_default(hw, &data);
- if (ret_val)
- return ret_val;
-
- mac->ledctl_default = er32(LEDCTL);
- mac->ledctl_mode1 = mac->ledctl_default;
- mac->ledctl_mode2 = mac->ledctl_default;
-
- for (i = 0; i < 4; i++) {
- temp = (data >> (i << 2)) & led_mask;
- switch (temp) {
- case ID_LED_ON1_DEF2:
- case ID_LED_ON1_ON2:
- case ID_LED_ON1_OFF2:
- mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode1 |= ledctl_on << (i << 3);
- break;
- case ID_LED_OFF1_DEF2:
- case ID_LED_OFF1_ON2:
- case ID_LED_OFF1_OFF2:
- mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode1 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- switch (temp) {
- case ID_LED_DEF1_ON2:
- case ID_LED_ON1_ON2:
- case ID_LED_OFF1_ON2:
- mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode2 |= ledctl_on << (i << 3);
- break;
- case ID_LED_DEF1_OFF2:
- case ID_LED_ON1_OFF2:
- case ID_LED_OFF1_OFF2:
- mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
- mac->ledctl_mode2 |= ledctl_off << (i << 3);
- break;
- default:
- /* Do nothing */
- break;
- }
- }
-
- return 0;
-}
-
-/**
- * e1000e_cleanup_led_generic - Set LED config to default operation
- * @hw: pointer to the HW structure
- *
- * Remove the current LED configuration and set the LED configuration
- * to the default value, saved from the EEPROM.
- **/
-s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
-{
- ew32(LEDCTL, hw->mac.ledctl_default);
- return 0;
-}
-
-/**
- * e1000e_blink_led - Blink LED
- * @hw: pointer to the HW structure
- *
- * Blink the LEDs which are set to be on.
- **/
-s32 e1000e_blink_led(struct e1000_hw *hw)
-{
- u32 ledctl_blink = 0;
- u32 i;
-
- if (hw->phy.media_type == e1000_media_type_fiber) {
- /* always blink LED0 for PCI-E fiber */
- ledctl_blink = E1000_LEDCTL_LED0_BLINK |
- (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
- } else {
- /*
- * set the blink bit for each LED that's "on" (0x0E)
- * in ledctl_mode2
- */
- ledctl_blink = hw->mac.ledctl_mode2;
- for (i = 0; i < 4; i++)
- if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
- E1000_LEDCTL_MODE_LED_ON)
- ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
- (i * 8));
- }
-
- ew32(LEDCTL, ledctl_blink);
-
- return 0;
-}
-
-/**
- * e1000e_led_on_generic - Turn LED on
- * @hw: pointer to the HW structure
- *
- * Turn LED on.
- **/
-s32 e1000e_led_on_generic(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- switch (hw->phy.media_type) {
- case e1000_media_type_fiber:
- ctrl = er32(CTRL);
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- ew32(CTRL, ctrl);
- break;
- case e1000_media_type_copper:
- ew32(LEDCTL, hw->mac.ledctl_mode2);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000e_led_off_generic - Turn LED off
- * @hw: pointer to the HW structure
- *
- * Turn LED off.
- **/
-s32 e1000e_led_off_generic(struct e1000_hw *hw)
-{
- u32 ctrl;
-
- switch (hw->phy.media_type) {
- case e1000_media_type_fiber:
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
- ew32(CTRL, ctrl);
- break;
- case e1000_media_type_copper:
- ew32(LEDCTL, hw->mac.ledctl_mode1);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/**
- * e1000e_set_pcie_no_snoop - Set PCI-express capabilities
- * @hw: pointer to the HW structure
- * @no_snoop: bitmap of snoop events
- *
- * Set the PCI-express register to snoop for events enabled in 'no_snoop'.
- **/
-void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
-{
- u32 gcr;
-
- if (no_snoop) {
- gcr = er32(GCR);
- gcr &= ~(PCIE_NO_SNOOP_ALL);
- gcr |= no_snoop;
- ew32(GCR, gcr);
- }
-}
-
-/**
- * e1000e_disable_pcie_master - Disables PCI-express master access
- * @hw: pointer to the HW structure
- *
- * Returns 0 if successful, else returns -10
- * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
- * the master requests to be disabled.
- *
- * Disables PCI-Express master access and verifies there are no pending
- * requests.
- **/
-s32 e1000e_disable_pcie_master(struct e1000_hw *hw)
-{
- u32 ctrl;
- s32 timeout = MASTER_DISABLE_TIMEOUT;
-
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
- ew32(CTRL, ctrl);
-
- while (timeout) {
- if (!(er32(STATUS) &
- E1000_STATUS_GIO_MASTER_ENABLE))
- break;
- udelay(100);
- timeout--;
- }
-
- if (!timeout) {
- hw_dbg(hw, "Master requests are pending.\n");
- return -E1000_ERR_MASTER_REQUESTS_PENDING;
- }
-
- return 0;
-}
-
-/**
- * e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
- * @hw: pointer to the HW structure
- *
- * Reset the Adaptive Interframe Spacing throttle to default values.
- **/
-void e1000e_reset_adaptive(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
-
- mac->current_ifs_val = 0;
- mac->ifs_min_val = IFS_MIN;
- mac->ifs_max_val = IFS_MAX;
- mac->ifs_step_size = IFS_STEP;
- mac->ifs_ratio = IFS_RATIO;
-
- mac->in_ifs_mode = 0;
- ew32(AIT, 0);
-}
-
-/**
- * e1000e_update_adaptive - Update Adaptive Interframe Spacing
- * @hw: pointer to the HW structure
- *
- * Update the Adaptive Interframe Spacing Throttle value based on the
- * time between transmitted packets and time between collisions.
- **/
-void e1000e_update_adaptive(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
-
- if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
- if (mac->tx_packet_delta > MIN_NUM_XMITS) {
- mac->in_ifs_mode = 1;
- if (mac->current_ifs_val < mac->ifs_max_val) {
- if (!mac->current_ifs_val)
- mac->current_ifs_val = mac->ifs_min_val;
- else
- mac->current_ifs_val +=
- mac->ifs_step_size;
- ew32(AIT, mac->current_ifs_val);
- }
- }
- } else {
- if (mac->in_ifs_mode &&
- (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
- mac->current_ifs_val = 0;
- mac->in_ifs_mode = 0;
- ew32(AIT, 0);
- }
- }
-}
-
-/**
- * e1000_raise_eec_clk - Raise EEPROM clock
- * @hw: pointer to the HW structure
- * @eecd: pointer to the EEPROM
- *
- * Enable/Raise the EEPROM clock bit.
- **/
-static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
-{
- *eecd = *eecd | E1000_EECD_SK;
- ew32(EECD, *eecd);
- e1e_flush();
- udelay(hw->nvm.delay_usec);
-}
-
-/**
- * e1000_lower_eec_clk - Lower EEPROM clock
- * @hw: pointer to the HW structure
- * @eecd: pointer to the EEPROM
- *
- * Clear/Lower the EEPROM clock bit.
- **/
-static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
-{
- *eecd = *eecd & ~E1000_EECD_SK;
- ew32(EECD, *eecd);
- e1e_flush();
- udelay(hw->nvm.delay_usec);
-}
-
-/**
- * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
- * @hw: pointer to the HW structure
- * @data: data to send to the EEPROM
- * @count: number of bits to shift out
- *
- * We need to shift 'count' bits out to the EEPROM. So, the value in the
- * "data" parameter will be shifted out to the EEPROM one bit at a time.
- * In order to do this, "data" must be broken down into bits.
- **/
-static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = er32(EECD);
- u32 mask;
-
- mask = 0x01 << (count - 1);
- if (nvm->type == e1000_nvm_eeprom_spi)
- eecd |= E1000_EECD_DO;
-
- do {
- eecd &= ~E1000_EECD_DI;
-
- if (data & mask)
- eecd |= E1000_EECD_DI;
-
- ew32(EECD, eecd);
- e1e_flush();
-
- udelay(nvm->delay_usec);
-
- e1000_raise_eec_clk(hw, &eecd);
- e1000_lower_eec_clk(hw, &eecd);
-
- mask >>= 1;
- } while (mask);
-
- eecd &= ~E1000_EECD_DI;
- ew32(EECD, eecd);
-}
-
-/**
- * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
- * @hw: pointer to the HW structure
- * @count: number of bits to shift in
- *
- * In order to read a register from the EEPROM, we need to shift 'count' bits
- * in from the EEPROM. Bits are "shifted in" by raising the clock input to
- * the EEPROM (setting the SK bit), and then reading the value of the data out
- * "DO" bit. During this "shifting in" process the data in "DI" bit should
- * always be clear.
- **/
-static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
-{
- u32 eecd;
- u32 i;
- u16 data;
-
- eecd = er32(EECD);
-
- eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
- data = 0;
-
- for (i = 0; i < count; i++) {
- data <<= 1;
- e1000_raise_eec_clk(hw, &eecd);
-
- eecd = er32(EECD);
-
- eecd &= ~E1000_EECD_DI;
- if (eecd & E1000_EECD_DO)
- data |= 1;
-
- e1000_lower_eec_clk(hw, &eecd);
- }
-
- return data;
-}
-
-/**
- * e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion
- * @hw: pointer to the HW structure
- * @ee_reg: EEPROM flag for polling
- *
- * Polls the EEPROM status bit for either read or write completion based
- * upon the value of 'ee_reg'.
- **/
-s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
-{
- u32 attempts = 100000;
- u32 i, reg = 0;
-
- for (i = 0; i < attempts; i++) {
- if (ee_reg == E1000_NVM_POLL_READ)
- reg = er32(EERD);
- else
- reg = er32(EEWR);
-
- if (reg & E1000_NVM_RW_REG_DONE)
- return 0;
-
- udelay(5);
- }
-
- return -E1000_ERR_NVM;
-}
-
-/**
- * e1000e_acquire_nvm - Generic request for access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Set the EEPROM access request bit and wait for EEPROM access grant bit.
- * Return successful if access grant bit set, else clear the request for
- * EEPROM access and return -E1000_ERR_NVM (-1).
- **/
-s32 e1000e_acquire_nvm(struct e1000_hw *hw)
-{
- u32 eecd = er32(EECD);
- s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
-
- ew32(EECD, eecd | E1000_EECD_REQ);
- eecd = er32(EECD);
-
- while (timeout) {
- if (eecd & E1000_EECD_GNT)
- break;
- udelay(5);
- eecd = er32(EECD);
- timeout--;
- }
-
- if (!timeout) {
- eecd &= ~E1000_EECD_REQ;
- ew32(EECD, eecd);
- hw_dbg(hw, "Could not acquire NVM grant\n");
- return -E1000_ERR_NVM;
- }
-
- return 0;
-}
-
-/**
- * e1000_standby_nvm - Return EEPROM to standby state
- * @hw: pointer to the HW structure
- *
- * Return the EEPROM to a standby state.
- **/
-static void e1000_standby_nvm(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = er32(EECD);
-
- if (nvm->type == e1000_nvm_eeprom_spi) {
- /* Toggle CS to flush commands */
- eecd |= E1000_EECD_CS;
- ew32(EECD, eecd);
- e1e_flush();
- udelay(nvm->delay_usec);
- eecd &= ~E1000_EECD_CS;
- ew32(EECD, eecd);
- e1e_flush();
- udelay(nvm->delay_usec);
- }
-}
-
-/**
- * e1000_stop_nvm - Terminate EEPROM command
- * @hw: pointer to the HW structure
- *
- * Terminates the current command by inverting the EEPROM's chip select pin.
- **/
-static void e1000_stop_nvm(struct e1000_hw *hw)
-{
- u32 eecd;
-
- eecd = er32(EECD);
- if (hw->nvm.type == e1000_nvm_eeprom_spi) {
- /* Pull CS high */
- eecd |= E1000_EECD_CS;
- e1000_lower_eec_clk(hw, &eecd);
- }
-}
-
-/**
- * e1000e_release_nvm - Release exclusive access to EEPROM
- * @hw: pointer to the HW structure
- *
- * Stop any current commands to the EEPROM and clear the EEPROM request bit.
- **/
-void e1000e_release_nvm(struct e1000_hw *hw)
-{
- u32 eecd;
-
- e1000_stop_nvm(hw);
-
- eecd = er32(EECD);
- eecd &= ~E1000_EECD_REQ;
- ew32(EECD, eecd);
-}
-
-/**
- * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
- * @hw: pointer to the HW structure
- *
- * Setups the EEPROM for reading and writing.
- **/
-static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 eecd = er32(EECD);
- u16 timeout = 0;
- u8 spi_stat_reg;
-
- if (nvm->type == e1000_nvm_eeprom_spi) {
- /* Clear SK and CS */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- ew32(EECD, eecd);
- udelay(1);
- timeout = NVM_MAX_RETRY_SPI;
-
- /*
- * Read "Status Register" repeatedly until the LSB is cleared.
- * The EEPROM will signal that the command has been completed
- * by clearing bit 0 of the internal status register. If it's
- * not cleared within 'timeout', then error out.
- */
- while (timeout) {
- e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
- hw->nvm.opcode_bits);
- spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
- if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
- break;
-
- udelay(5);
- e1000_standby_nvm(hw);
- timeout--;
- }
-
- if (!timeout) {
- hw_dbg(hw, "SPI NVM Status error\n");
- return -E1000_ERR_NVM;
- }
- }
-
- return 0;
-}
-
-/**
- * e1000e_read_nvm_eerd - Reads EEPROM using EERD register
- * @hw: pointer to the HW structure
- * @offset: offset of word in the EEPROM to read
- * @words: number of words to read
- * @data: word read from the EEPROM
- *
- * Reads a 16 bit word from the EEPROM using the EERD register.
- **/
-s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 i, eerd = 0;
- s32 ret_val = 0;
-
- /*
- * A check for invalid values: offset too large, too many words,
- * too many words for the offset, and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- hw_dbg(hw, "nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- for (i = 0; i < words; i++) {
- eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
- E1000_NVM_RW_REG_START;
-
- ew32(EERD, eerd);
- ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
- if (ret_val)
- break;
-
- data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
- }
-
- return ret_val;
-}
-
-/**
- * e1000e_write_nvm_spi - Write to EEPROM using SPI
- * @hw: pointer to the HW structure
- * @offset: offset within the EEPROM to be written to
- * @words: number of words to write
- * @data: 16 bit word(s) to be written to the EEPROM
- *
- * Writes data to EEPROM at offset using SPI interface.
- *
- * If e1000e_update_nvm_checksum is not called after this function , the
- * EEPROM will most likely contain an invalid checksum.
- **/
-s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- s32 ret_val;
- u16 widx = 0;
-
- /*
- * A check for invalid values: offset too large, too many words,
- * and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- hw_dbg(hw, "nvm parameter(s) out of bounds\n");
- return -E1000_ERR_NVM;
- }
-
- ret_val = nvm->ops.acquire_nvm(hw);
- if (ret_val)
- return ret_val;
-
- msleep(10);
-
- while (widx < words) {
- u8 write_opcode = NVM_WRITE_OPCODE_SPI;
-
- ret_val = e1000_ready_nvm_eeprom(hw);
- if (ret_val) {
- nvm->ops.release_nvm(hw);
- return ret_val;
- }
-
- e1000_standby_nvm(hw);
-
- /* Send the WRITE ENABLE command (8 bit opcode) */
- e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
- nvm->opcode_bits);
-
- e1000_standby_nvm(hw);
-
- /*
- * Some SPI eeproms use the 8th address bit embedded in the
- * opcode
- */
- if ((nvm->address_bits == 8) && (offset >= 128))
- write_opcode |= NVM_A8_OPCODE_SPI;
-
- /* Send the Write command (8-bit opcode + addr) */
- e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
- e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
- nvm->address_bits);
-
- /* Loop to allow for up to whole page write of eeprom */
- while (widx < words) {
- u16 word_out = data[widx];
- word_out = (word_out >> 8) | (word_out << 8);
- e1000_shift_out_eec_bits(hw, word_out, 16);
- widx++;
-
- if ((((offset + widx) * 2) % nvm->page_size) == 0) {
- e1000_standby_nvm(hw);
- break;
- }
- }
- }
-
- msleep(10);
- return 0;
-}
-
-/**
- * e1000e_read_mac_addr - Read device MAC address
- * @hw: pointer to the HW structure
- *
- * Reads the device MAC address from the EEPROM and stores the value.
- * Since devices with two ports use the same EEPROM, we increment the
- * last bit in the MAC address for the second port.
- **/
-s32 e1000e_read_mac_addr(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 offset, nvm_data, i;
- u16 mac_addr_offset = 0;
-
- if (hw->mac.type == e1000_82571) {
- /* Check for an alternate MAC address. An alternate MAC
- * address can be setup by pre-boot software and must be
- * treated like a permanent address and must override the
- * actual permanent MAC address.*/
- ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
- &mac_addr_offset);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- if (mac_addr_offset == 0xFFFF)
- mac_addr_offset = 0;
-
- if (mac_addr_offset) {
- if (hw->bus.func == E1000_FUNC_1)
- mac_addr_offset += ETH_ALEN/sizeof(u16);
-
- /* make sure we have a valid mac address here
- * before using it */
- ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
- &nvm_data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- if (nvm_data & 0x0001)
- mac_addr_offset = 0;
- }
-
- if (mac_addr_offset)
- hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
- }
-
- for (i = 0; i < ETH_ALEN; i += 2) {
- offset = mac_addr_offset + (i >> 1);
- ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
- hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
- }
-
- /* Flip last bit of mac address if we're on second port */
- if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
- hw->mac.perm_addr[5] ^= 1;
-
- for (i = 0; i < ETH_ALEN; i++)
- hw->mac.addr[i] = hw->mac.perm_addr[i];
-
- return 0;
-}
-
-/**
- * e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
- * and then verifies that the sum of the EEPROM is equal to 0xBABA.
- **/
-s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 checksum = 0;
- u16 i, nvm_data;
-
- for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- checksum += nvm_data;
- }
-
- if (checksum != (u16) NVM_SUM) {
- hw_dbg(hw, "NVM Checksum Invalid\n");
- return -E1000_ERR_NVM;
- }
-
- return 0;
-}
-
-/**
- * e1000e_update_nvm_checksum_generic - Update EEPROM checksum
- * @hw: pointer to the HW structure
- *
- * Updates the EEPROM checksum by reading/adding each word of the EEPROM
- * up to the checksum. Then calculates the EEPROM checksum and writes the
- * value to the EEPROM.
- **/
-s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 checksum = 0;
- u16 i, nvm_data;
-
- for (i = 0; i < NVM_CHECKSUM_REG; i++) {
- ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error while updating checksum.\n");
- return ret_val;
- }
- checksum += nvm_data;
- }
- checksum = (u16) NVM_SUM - checksum;
- ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
- if (ret_val)
- hw_dbg(hw, "NVM Write Error while updating checksum.\n");
-
- return ret_val;
-}
-
-/**
- * e1000e_reload_nvm - Reloads EEPROM
- * @hw: pointer to the HW structure
- *
- * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
- * extended control register.
- **/
-void e1000e_reload_nvm(struct e1000_hw *hw)
-{
- u32 ctrl_ext;
-
- udelay(10);
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- ew32(CTRL_EXT, ctrl_ext);
- e1e_flush();
-}
-
-/**
- * e1000_calculate_checksum - Calculate checksum for buffer
- * @buffer: pointer to EEPROM
- * @length: size of EEPROM to calculate a checksum for
- *
- * Calculates the checksum for some buffer on a specified length. The
- * checksum calculated is returned.
- **/
-static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
-{
- u32 i;
- u8 sum = 0;
-
- if (!buffer)
- return 0;
-
- for (i = 0; i < length; i++)
- sum += buffer[i];
-
- return (u8) (0 - sum);
-}
-
-/**
- * e1000_mng_enable_host_if - Checks host interface is enabled
- * @hw: pointer to the HW structure
- *
- * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
- *
- * This function checks whether the HOST IF is enabled for command operation
- * and also checks whether the previous command is completed. It busy waits
- * in case of previous command is not completed.
- **/
-static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
-{
- u32 hicr;
- u8 i;
-
- /* Check that the host interface is enabled. */
- hicr = er32(HICR);
- if ((hicr & E1000_HICR_EN) == 0) {
- hw_dbg(hw, "E1000_HOST_EN bit disabled.\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
- /* check the previous command is completed */
- for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
- hicr = er32(HICR);
- if (!(hicr & E1000_HICR_C))
- break;
- mdelay(1);
- }
-
- if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
- hw_dbg(hw, "Previous command timeout failed .\n");
- return -E1000_ERR_HOST_INTERFACE_COMMAND;
- }
-
- return 0;
-}
-
-/**
- * e1000e_check_mng_mode - check management mode
- * @hw: pointer to the HW structure
- *
- * Reads the firmware semaphore register and returns true (>0) if
- * manageability is enabled, else false (0).
- **/
-bool e1000e_check_mng_mode(struct e1000_hw *hw)
-{
- u32 fwsm = er32(FWSM);
-
- return (fwsm & E1000_FWSM_MODE_MASK) == hw->mac.ops.mng_mode_enab;
-}
-
-/**
- * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx
- * @hw: pointer to the HW structure
- *
- * Enables packet filtering on transmit packets if manageability is enabled
- * and host interface is enabled.
- **/
-bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
-{
- struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
- u32 *buffer = (u32 *)&hw->mng_cookie;
- u32 offset;
- s32 ret_val, hdr_csum, csum;
- u8 i, len;
-
- /* No manageability, no filtering */
- if (!e1000e_check_mng_mode(hw)) {
- hw->mac.tx_pkt_filtering = 0;
- return 0;
- }
-
- /*
- * If we can't read from the host interface for whatever
- * reason, disable filtering.
- */
- ret_val = e1000_mng_enable_host_if(hw);
- if (ret_val != 0) {
- hw->mac.tx_pkt_filtering = 0;
- return ret_val;
- }
-
- /* Read in the header. Length and offset are in dwords. */
- len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
- offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
- for (i = 0; i < len; i++)
- *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset + i);
- hdr_csum = hdr->checksum;
- hdr->checksum = 0;
- csum = e1000_calculate_checksum((u8 *)hdr,
- E1000_MNG_DHCP_COOKIE_LENGTH);
- /*
- * If either the checksums or signature don't match, then
- * the cookie area isn't considered valid, in which case we
- * take the safe route of assuming Tx filtering is enabled.
- */
- if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
- hw->mac.tx_pkt_filtering = 1;
- return 1;
- }
-
- /* Cookie area is valid, make the final check for filtering. */
- if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
- hw->mac.tx_pkt_filtering = 0;
- return 0;
- }
-
- hw->mac.tx_pkt_filtering = 1;
- return 1;
-}
-
-/**
- * e1000_mng_write_cmd_header - Writes manageability command header
- * @hw: pointer to the HW structure
- * @hdr: pointer to the host interface command header
- *
- * Writes the command header after does the checksum calculation.
- **/
-static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
- struct e1000_host_mng_command_header *hdr)
-{
- u16 i, length = sizeof(struct e1000_host_mng_command_header);
-
- /* Write the whole command header structure with new checksum. */
-
- hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
-
- length >>= 2;
- /* Write the relevant command block into the ram area. */
- for (i = 0; i < length; i++) {
- E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i,
- *((u32 *) hdr + i));
- e1e_flush();
- }
-
- return 0;
-}
-
-/**
- * e1000_mng_host_if_write - Writes to the manageability host interface
- * @hw: pointer to the HW structure
- * @buffer: pointer to the host interface buffer
- * @length: size of the buffer
- * @offset: location in the buffer to write to
- * @sum: sum of the data (not checksum)
- *
- * This function writes the buffer content at the offset given on the host if.
- * It also does alignment considerations to do the writes in most efficient
- * way. Also fills up the sum of the buffer in *buffer parameter.
- **/
-static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer,
- u16 length, u16 offset, u8 *sum)
-{
- u8 *tmp;
- u8 *bufptr = buffer;
- u32 data = 0;
- u16 remaining, i, j, prev_bytes;
-
- /* sum = only sum of the data and it is not checksum */
-
- if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
- return -E1000_ERR_PARAM;
-
- tmp = (u8 *)&data;
- prev_bytes = offset & 0x3;
- offset >>= 2;
-
- if (prev_bytes) {
- data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset);
- for (j = prev_bytes; j < sizeof(u32); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data);
- length -= j - prev_bytes;
- offset++;
- }
-
- remaining = length & 0x3;
- length -= remaining;
-
- /* Calculate length in DWORDs */
- length >>= 2;
-
- /*
- * The device driver writes the relevant command block into the
- * ram area.
- */
- for (i = 0; i < length; i++) {
- for (j = 0; j < sizeof(u32); j++) {
- *(tmp + j) = *bufptr++;
- *sum += *(tmp + j);
- }
-
- E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
- }
- if (remaining) {
- for (j = 0; j < sizeof(u32); j++) {
- if (j < remaining)
- *(tmp + j) = *bufptr++;
- else
- *(tmp + j) = 0;
-
- *sum += *(tmp + j);
- }
- E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
- }
-
- return 0;
-}
-
-/**
- * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
- * @hw: pointer to the HW structure
- * @buffer: pointer to the host interface
- * @length: size of the buffer
- *
- * Writes the DHCP information to the host interface.
- **/
-s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
-{
- struct e1000_host_mng_command_header hdr;
- s32 ret_val;
- u32 hicr;
-
- hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
- hdr.command_length = length;
- hdr.reserved1 = 0;
- hdr.reserved2 = 0;
- hdr.checksum = 0;
-
- /* Enable the host interface */
- ret_val = e1000_mng_enable_host_if(hw);
- if (ret_val)
- return ret_val;
-
- /* Populate the host interface with the contents of "buffer". */
- ret_val = e1000_mng_host_if_write(hw, buffer, length,
- sizeof(hdr), &(hdr.checksum));
- if (ret_val)
- return ret_val;
-
- /* Write the manageability command header */
- ret_val = e1000_mng_write_cmd_header(hw, &hdr);
- if (ret_val)
- return ret_val;
-
- /* Tell the ARC a new command is pending. */
- hicr = er32(HICR);
- ew32(HICR, hicr | E1000_HICR_C);
-
- return 0;
-}
-
-/**
- * e1000e_enable_mng_pass_thru - Enable processing of ARP's
- * @hw: pointer to the HW structure
- *
- * Verifies the hardware needs to allow ARPs to be processed by the host.
- **/
-bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
-{
- u32 manc;
- u32 fwsm, factps;
- bool ret_val = 0;
-
- manc = er32(MANC);
-
- if (!(manc & E1000_MANC_RCV_TCO_EN) ||
- !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
- return ret_val;
-
- if (hw->mac.arc_subsystem_valid) {
- fwsm = er32(FWSM);
- factps = er32(FACTPS);
-
- if (!(factps & E1000_FACTPS_MNGCG) &&
- ((fwsm & E1000_FWSM_MODE_MASK) ==
- (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
- ret_val = 1;
- return ret_val;
- }
- } else {
- if ((manc & E1000_MANC_SMBUS_EN) &&
- !(manc & E1000_MANC_ASF_EN)) {
- ret_val = 1;
- return ret_val;
- }
- }
-
- return ret_val;
-}
-
-s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num)
-{
- s32 ret_val;
- u16 nvm_data;
-
- ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- *pba_num = (u32)(nvm_data << 16);
-
- ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
- if (ret_val) {
- hw_dbg(hw, "NVM Read Error\n");
- return ret_val;
- }
- *pba_num |= nvm_data;
-
- return 0;
-}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
deleted file mode 100644
index b81c4237b5d..00000000000
--- a/drivers/net/e1000e/netdev.c
+++ /dev/null
@@ -1,4835 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/tcp.h>
-#include <linux/ipv6.h>
-#include <net/checksum.h>
-#include <net/ip6_checksum.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/if_vlan.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#include <linux/pm_qos_params.h>
-
-#include "e1000.h"
-
-#define DRV_VERSION "0.3.3.3-k6"
-char e1000e_driver_name[] = "e1000e";
-const char e1000e_driver_version[] = DRV_VERSION;
-
-static const struct e1000_info *e1000_info_tbl[] = {
- [board_82571] = &e1000_82571_info,
- [board_82572] = &e1000_82572_info,
- [board_82573] = &e1000_82573_info,
- [board_80003es2lan] = &e1000_es2_info,
- [board_ich8lan] = &e1000_ich8_info,
- [board_ich9lan] = &e1000_ich9_info,
-};
-
-#ifdef DEBUG
-/**
- * e1000_get_hw_dev_name - return device name string
- * used by hardware layer to print debugging information
- **/
-char *e1000e_get_hw_dev_name(struct e1000_hw *hw)
-{
- return hw->adapter->netdev->name;
-}
-#endif
-
-/**
- * e1000_desc_unused - calculate if we have unused descriptors
- **/
-static int e1000_desc_unused(struct e1000_ring *ring)
-{
- if (ring->next_to_clean > ring->next_to_use)
- return ring->next_to_clean - ring->next_to_use - 1;
-
- return ring->count + ring->next_to_clean - ring->next_to_use - 1;
-}
-
-/**
- * e1000_receive_skb - helper function to handle Rx indications
- * @adapter: board private structure
- * @status: descriptor status field as written by hardware
- * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
- * @skb: pointer to sk_buff to be indicated to stack
- **/
-static void e1000_receive_skb(struct e1000_adapter *adapter,
- struct net_device *netdev,
- struct sk_buff *skb,
- u8 status, __le16 vlan)
-{
- skb->protocol = eth_type_trans(skb, netdev);
-
- if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan));
- else
- netif_receive_skb(skb);
-
- netdev->last_rx = jiffies;
-}
-
-/**
- * e1000_rx_checksum - Receive Checksum Offload for 82543
- * @adapter: board private structure
- * @status_err: receive descriptor status and error fields
- * @csum: receive descriptor csum field
- * @sk_buff: socket buffer with received data
- **/
-static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
- u32 csum, struct sk_buff *skb)
-{
- u16 status = (u16)status_err;
- u8 errors = (u8)(status_err >> 24);
- skb->ip_summed = CHECKSUM_NONE;
-
- /* Ignore Checksum bit is set */
- if (status & E1000_RXD_STAT_IXSM)
- return;
- /* TCP/UDP checksum error bit is set */
- if (errors & E1000_RXD_ERR_TCPE) {
- /* let the stack verify checksum errors */
- adapter->hw_csum_err++;
- return;
- }
-
- /* TCP/UDP Checksum has not been calculated */
- if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
- return;
-
- /* It must be a TCP or UDP packet with a valid checksum */
- if (status & E1000_RXD_STAT_TCPCS) {
- /* TCP checksum is good */
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- } else {
- /*
- * IP fragment with UDP payload
- * Hardware complements the payload checksum, so we undo it
- * and then put the value in host order for further stack use.
- */
- __sum16 sum = (__force __sum16)htons(csum);
- skb->csum = csum_unfold(~sum);
- skb->ip_summed = CHECKSUM_COMPLETE;
- }
- adapter->hw_csum_good++;
-}
-
-/**
- * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
- * @adapter: address of board private structure
- **/
-static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
- int cleaned_count)
-{
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_rx_desc *rx_desc;
- struct e1000_buffer *buffer_info;
- struct sk_buff *skb;
- unsigned int i;
- unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
-
- i = rx_ring->next_to_use;
- buffer_info = &rx_ring->buffer_info[i];
-
- while (cleaned_count--) {
- skb = buffer_info->skb;
- if (skb) {
- skb_trim(skb, 0);
- goto map_skb;
- }
-
- skb = netdev_alloc_skb(netdev, bufsz);
- if (!skb) {
- /* Better luck next round */
- adapter->alloc_rx_buff_failed++;
- break;
- }
-
- /*
- * Make buffer alignment 2 beyond a 16 byte boundary
- * this will result in a 16 byte aligned IP header after
- * the 14 byte MAC header is removed
- */
- skb_reserve(skb, NET_IP_ALIGN);
-
- buffer_info->skb = skb;
-map_skb:
- buffer_info->dma = pci_map_single(pdev, skb->data,
- adapter->rx_buffer_len,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
- dev_err(&pdev->dev, "RX DMA map failed\n");
- adapter->rx_dma_failed++;
- break;
- }
-
- rx_desc = E1000_RX_DESC(*rx_ring, i);
- rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
-
- i++;
- if (i == rx_ring->count)
- i = 0;
- buffer_info = &rx_ring->buffer_info[i];
- }
-
- if (rx_ring->next_to_use != i) {
- rx_ring->next_to_use = i;
- if (i-- == 0)
- i = (rx_ring->count - 1);
-
- /*
- * Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64).
- */
- wmb();
- writel(i, adapter->hw.hw_addr + rx_ring->tail);
- }
-}
-
-/**
- * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
- * @adapter: address of board private structure
- **/
-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
- int cleaned_count)
-{
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- union e1000_rx_desc_packet_split *rx_desc;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_buffer *buffer_info;
- struct e1000_ps_page *ps_page;
- struct sk_buff *skb;
- unsigned int i, j;
-
- i = rx_ring->next_to_use;
- buffer_info = &rx_ring->buffer_info[i];
-
- while (cleaned_count--) {
- rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
-
- for (j = 0; j < PS_PAGE_BUFFERS; j++) {
- ps_page = &buffer_info->ps_pages[j];
- if (j >= adapter->rx_ps_pages) {
- /* all unused desc entries get hw null ptr */
- rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
- continue;
- }
- if (!ps_page->page) {
- ps_page->page = alloc_page(GFP_ATOMIC);
- if (!ps_page->page) {
- adapter->alloc_rx_buff_failed++;
- goto no_buffers;
- }
- ps_page->dma = pci_map_page(pdev,
- ps_page->page,
- 0, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, ps_page->dma)) {
- dev_err(&adapter->pdev->dev,
- "RX DMA page map failed\n");
- adapter->rx_dma_failed++;
- goto no_buffers;
- }
- }
- /*
- * Refresh the desc even if buffer_addrs
- * didn't change because each write-back
- * erases this info.
- */
- rx_desc->read.buffer_addr[j+1] =
- cpu_to_le64(ps_page->dma);
- }
-
- skb = netdev_alloc_skb(netdev,
- adapter->rx_ps_bsize0 + NET_IP_ALIGN);
-
- if (!skb) {
- adapter->alloc_rx_buff_failed++;
- break;
- }
-
- /*
- * Make buffer alignment 2 beyond a 16 byte boundary
- * this will result in a 16 byte aligned IP header after
- * the 14 byte MAC header is removed
- */
- skb_reserve(skb, NET_IP_ALIGN);
-
- buffer_info->skb = skb;
- buffer_info->dma = pci_map_single(pdev, skb->data,
- adapter->rx_ps_bsize0,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
- dev_err(&pdev->dev, "RX DMA map failed\n");
- adapter->rx_dma_failed++;
- /* cleanup skb */
- dev_kfree_skb_any(skb);
- buffer_info->skb = NULL;
- break;
- }
-
- rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
-
- i++;
- if (i == rx_ring->count)
- i = 0;
- buffer_info = &rx_ring->buffer_info[i];
- }
-
-no_buffers:
- if (rx_ring->next_to_use != i) {
- rx_ring->next_to_use = i;
-
- if (!(i--))
- i = (rx_ring->count - 1);
-
- /*
- * Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64).
- */
- wmb();
- /*
- * Hardware increments by 16 bytes, but packet split
- * descriptors are 32 bytes...so we increment tail
- * twice as much.
- */
- writel(i<<1, adapter->hw.hw_addr + rx_ring->tail);
- }
-}
-
-/**
- * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
- * @adapter: address of board private structure
- * @rx_ring: pointer to receive ring structure
- * @cleaned_count: number of buffers to allocate this pass
- **/
-
-static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
- int cleaned_count)
-{
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_rx_desc *rx_desc;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_buffer *buffer_info;
- struct sk_buff *skb;
- unsigned int i;
- unsigned int bufsz = 256 -
- 16 /* for skb_reserve */ -
- NET_IP_ALIGN;
-
- i = rx_ring->next_to_use;
- buffer_info = &rx_ring->buffer_info[i];
-
- while (cleaned_count--) {
- skb = buffer_info->skb;
- if (skb) {
- skb_trim(skb, 0);
- goto check_page;
- }
-
- skb = netdev_alloc_skb(netdev, bufsz);
- if (unlikely(!skb)) {
- /* Better luck next round */
- adapter->alloc_rx_buff_failed++;
- break;
- }
-
- /* Make buffer alignment 2 beyond a 16 byte boundary
- * this will result in a 16 byte aligned IP header after
- * the 14 byte MAC header is removed
- */
- skb_reserve(skb, NET_IP_ALIGN);
-
- buffer_info->skb = skb;
-check_page:
- /* allocate a new page if necessary */
- if (!buffer_info->page) {
- buffer_info->page = alloc_page(GFP_ATOMIC);
- if (unlikely(!buffer_info->page)) {
- adapter->alloc_rx_buff_failed++;
- break;
- }
- }
-
- if (!buffer_info->dma)
- buffer_info->dma = pci_map_page(pdev,
- buffer_info->page, 0,
- PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
-
- rx_desc = E1000_RX_DESC(*rx_ring, i);
- rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
-
- if (unlikely(++i == rx_ring->count))
- i = 0;
- buffer_info = &rx_ring->buffer_info[i];
- }
-
- if (likely(rx_ring->next_to_use != i)) {
- rx_ring->next_to_use = i;
- if (unlikely(i-- == 0))
- i = (rx_ring->count - 1);
-
- /* Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64). */
- wmb();
- writel(i, adapter->hw.hw_addr + rx_ring->tail);
- }
-}
-
-/**
- * e1000_clean_rx_irq - Send received data up the network stack; legacy
- * @adapter: board private structure
- *
- * the return value indicates whether actual cleaning was done, there
- * is no guarantee that everything was cleaned
- **/
-static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
- int *work_done, int work_to_do)
-{
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_rx_desc *rx_desc, *next_rxd;
- struct e1000_buffer *buffer_info, *next_buffer;
- u32 length;
- unsigned int i;
- int cleaned_count = 0;
- bool cleaned = 0;
- unsigned int total_rx_bytes = 0, total_rx_packets = 0;
-
- i = rx_ring->next_to_clean;
- rx_desc = E1000_RX_DESC(*rx_ring, i);
- buffer_info = &rx_ring->buffer_info[i];
-
- while (rx_desc->status & E1000_RXD_STAT_DD) {
- struct sk_buff *skb;
- u8 status;
-
- if (*work_done >= work_to_do)
- break;
- (*work_done)++;
-
- status = rx_desc->status;
- skb = buffer_info->skb;
- buffer_info->skb = NULL;
-
- prefetch(skb->data - NET_IP_ALIGN);
-
- i++;
- if (i == rx_ring->count)
- i = 0;
- next_rxd = E1000_RX_DESC(*rx_ring, i);
- prefetch(next_rxd);
-
- next_buffer = &rx_ring->buffer_info[i];
-
- cleaned = 1;
- cleaned_count++;
- pci_unmap_single(pdev,
- buffer_info->dma,
- adapter->rx_buffer_len,
- PCI_DMA_FROMDEVICE);
- buffer_info->dma = 0;
-
- length = le16_to_cpu(rx_desc->length);
-
- /* !EOP means multiple descriptors were used to store a single
- * packet, also make sure the frame isn't just CRC only */
- if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) {
- /* All receives must fit into a single buffer */
- e_dbg("%s: Receive packet consumed multiple buffers\n",
- netdev->name);
- /* recycle */
- buffer_info->skb = skb;
- goto next_desc;
- }
-
- if (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
- /* recycle */
- buffer_info->skb = skb;
- goto next_desc;
- }
-
- total_rx_bytes += length;
- total_rx_packets++;
-
- /*
- * code added for copybreak, this should improve
- * performance for small packets with large amounts
- * of reassembly being done in the stack
- */
- if (length < copybreak) {
- struct sk_buff *new_skb =
- netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
- if (new_skb) {
- skb_reserve(new_skb, NET_IP_ALIGN);
- skb_copy_to_linear_data_offset(new_skb,
- -NET_IP_ALIGN,
- (skb->data -
- NET_IP_ALIGN),
- (length +
- NET_IP_ALIGN));
- /* save the skb in buffer_info as good */
- buffer_info->skb = skb;
- skb = new_skb;
- }
- /* else just continue with the old one */
- }
- /* end copybreak code */
- skb_put(skb, length);
-
- /* Receive Checksum Offload */
- e1000_rx_checksum(adapter,
- (u32)(status) |
- ((u32)(rx_desc->errors) << 24),
- le16_to_cpu(rx_desc->csum), skb);
-
- e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special);
-
-next_desc:
- rx_desc->status = 0;
-
- /* return some buffers to hardware, one at a time is too slow */
- if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
- adapter->alloc_rx_buf(adapter, cleaned_count);
- cleaned_count = 0;
- }
-
- /* use prefetched values */
- rx_desc = next_rxd;
- buffer_info = next_buffer;
- }
- rx_ring->next_to_clean = i;
-
- cleaned_count = e1000_desc_unused(rx_ring);
- if (cleaned_count)
- adapter->alloc_rx_buf(adapter, cleaned_count);
-
- adapter->total_rx_bytes += total_rx_bytes;
- adapter->total_rx_packets += total_rx_packets;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
- return cleaned;
-}
-
-static void e1000_put_txbuf(struct e1000_adapter *adapter,
- struct e1000_buffer *buffer_info)
-{
- if (buffer_info->dma) {
- pci_unmap_page(adapter->pdev, buffer_info->dma,
- buffer_info->length, PCI_DMA_TODEVICE);
- buffer_info->dma = 0;
- }
- if (buffer_info->skb) {
- dev_kfree_skb_any(buffer_info->skb);
- buffer_info->skb = NULL;
- }
-}
-
-static void e1000_print_tx_hang(struct e1000_adapter *adapter)
-{
- struct e1000_ring *tx_ring = adapter->tx_ring;
- unsigned int i = tx_ring->next_to_clean;
- unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
- struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
-
- /* detected Tx unit hang */
- e_err("Detected Tx Unit Hang:\n"
- " TDH <%x>\n"
- " TDT <%x>\n"
- " next_to_use <%x>\n"
- " next_to_clean <%x>\n"
- "buffer_info[next_to_clean]:\n"
- " time_stamp <%lx>\n"
- " next_to_watch <%x>\n"
- " jiffies <%lx>\n"
- " next_to_watch.status <%x>\n",
- readl(adapter->hw.hw_addr + tx_ring->head),
- readl(adapter->hw.hw_addr + tx_ring->tail),
- tx_ring->next_to_use,
- tx_ring->next_to_clean,
- tx_ring->buffer_info[eop].time_stamp,
- eop,
- jiffies,
- eop_desc->upper.fields.status);
-}
-
-/**
- * e1000_clean_tx_irq - Reclaim resources after transmit completes
- * @adapter: board private structure
- *
- * the return value indicates whether actual cleaning was done, there
- * is no guarantee that everything was cleaned
- **/
-static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_ring *tx_ring = adapter->tx_ring;
- struct e1000_tx_desc *tx_desc, *eop_desc;
- struct e1000_buffer *buffer_info;
- unsigned int i, eop;
- unsigned int count = 0;
- bool cleaned = 0;
- unsigned int total_tx_bytes = 0, total_tx_packets = 0;
-
- i = tx_ring->next_to_clean;
- eop = tx_ring->buffer_info[i].next_to_watch;
- eop_desc = E1000_TX_DESC(*tx_ring, eop);
-
- while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
- for (cleaned = 0; !cleaned; ) {
- tx_desc = E1000_TX_DESC(*tx_ring, i);
- buffer_info = &tx_ring->buffer_info[i];
- cleaned = (i == eop);
-
- if (cleaned) {
- struct sk_buff *skb = buffer_info->skb;
- unsigned int segs, bytecount;
- segs = skb_shinfo(skb)->gso_segs ?: 1;
- /* multiply data chunks by size of headers */
- bytecount = ((segs - 1) * skb_headlen(skb)) +
- skb->len;
- total_tx_packets += segs;
- total_tx_bytes += bytecount;
- }
-
- e1000_put_txbuf(adapter, buffer_info);
- tx_desc->upper.data = 0;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
- }
-
- eop = tx_ring->buffer_info[i].next_to_watch;
- eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
- /* weight of a sort for tx, to avoid endless transmit cleanup */
- if (count++ == E1000_TX_WEIGHT)
- break;
- }
-
- tx_ring->next_to_clean = i;
-
-#define TX_WAKE_THRESHOLD 32
- if (cleaned && netif_carrier_ok(netdev) &&
- e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
- /* Make sure that anybody stopping the queue after this
- * sees the new next_to_clean.
- */
- smp_mb();
-
- if (netif_queue_stopped(netdev) &&
- !(test_bit(__E1000_DOWN, &adapter->state))) {
- netif_wake_queue(netdev);
- ++adapter->restart_queue;
- }
- }
-
- if (adapter->detect_tx_hung) {
- /*
- * Detect a transmit hang in hardware, this serializes the
- * check with the clearing of time_stamp and movement of i
- */
- adapter->detect_tx_hung = 0;
- if (tx_ring->buffer_info[eop].dma &&
- time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
- + (adapter->tx_timeout_factor * HZ))
- && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
- e1000_print_tx_hang(adapter);
- netif_stop_queue(netdev);
- }
- }
- adapter->total_tx_bytes += total_tx_bytes;
- adapter->total_tx_packets += total_tx_packets;
- adapter->net_stats.tx_bytes += total_tx_bytes;
- adapter->net_stats.tx_packets += total_tx_packets;
- return cleaned;
-}
-
-/**
- * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
- * @adapter: board private structure
- *
- * the return value indicates whether actual cleaning was done, there
- * is no guarantee that everything was cleaned
- **/
-static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
- int *work_done, int work_to_do)
-{
- union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_buffer *buffer_info, *next_buffer;
- struct e1000_ps_page *ps_page;
- struct sk_buff *skb;
- unsigned int i, j;
- u32 length, staterr;
- int cleaned_count = 0;
- bool cleaned = 0;
- unsigned int total_rx_bytes = 0, total_rx_packets = 0;
-
- i = rx_ring->next_to_clean;
- rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
- staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
- buffer_info = &rx_ring->buffer_info[i];
-
- while (staterr & E1000_RXD_STAT_DD) {
- if (*work_done >= work_to_do)
- break;
- (*work_done)++;
- skb = buffer_info->skb;
-
- /* in the packet split case this is header only */
- prefetch(skb->data - NET_IP_ALIGN);
-
- i++;
- if (i == rx_ring->count)
- i = 0;
- next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
- prefetch(next_rxd);
-
- next_buffer = &rx_ring->buffer_info[i];
-
- cleaned = 1;
- cleaned_count++;
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_ps_bsize0,
- PCI_DMA_FROMDEVICE);
- buffer_info->dma = 0;
-
- if (!(staterr & E1000_RXD_STAT_EOP)) {
- e_dbg("%s: Packet Split buffers didn't pick up the "
- "full packet\n", netdev->name);
- dev_kfree_skb_irq(skb);
- goto next_desc;
- }
-
- if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
- dev_kfree_skb_irq(skb);
- goto next_desc;
- }
-
- length = le16_to_cpu(rx_desc->wb.middle.length0);
-
- if (!length) {
- e_dbg("%s: Last part of the packet spanning multiple "
- "descriptors\n", netdev->name);
- dev_kfree_skb_irq(skb);
- goto next_desc;
- }
-
- /* Good Receive */
- skb_put(skb, length);
-
- {
- /*
- * this looks ugly, but it seems compiler issues make it
- * more efficient than reusing j
- */
- int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
-
- /*
- * page alloc/put takes too long and effects small packet
- * throughput, so unsplit small packets and save the alloc/put
- * only valid in softirq (napi) context to call kmap_*
- */
- if (l1 && (l1 <= copybreak) &&
- ((length + l1) <= adapter->rx_ps_bsize0)) {
- u8 *vaddr;
-
- ps_page = &buffer_info->ps_pages[0];
-
- /*
- * there is no documentation about how to call
- * kmap_atomic, so we can't hold the mapping
- * very long
- */
- pci_dma_sync_single_for_cpu(pdev, ps_page->dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
- vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);
- memcpy(skb_tail_pointer(skb), vaddr, l1);
- kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
- pci_dma_sync_single_for_device(pdev, ps_page->dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
-
- skb_put(skb, l1);
- goto copydone;
- } /* if */
- }
-
- for (j = 0; j < PS_PAGE_BUFFERS; j++) {
- length = le16_to_cpu(rx_desc->wb.upper.length[j]);
- if (!length)
- break;
-
- ps_page = &buffer_info->ps_pages[j];
- pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- ps_page->dma = 0;
- skb_fill_page_desc(skb, j, ps_page->page, 0, length);
- ps_page->page = NULL;
- skb->len += length;
- skb->data_len += length;
- skb->truesize += length;
- }
-
-copydone:
- total_rx_bytes += skb->len;
- total_rx_packets++;
-
- e1000_rx_checksum(adapter, staterr, le16_to_cpu(
- rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
-
- if (rx_desc->wb.upper.header_status &
- cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
- adapter->rx_hdr_split++;
-
- e1000_receive_skb(adapter, netdev, skb,
- staterr, rx_desc->wb.middle.vlan);
-
-next_desc:
- rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
- buffer_info->skb = NULL;
-
- /* return some buffers to hardware, one at a time is too slow */
- if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
- adapter->alloc_rx_buf(adapter, cleaned_count);
- cleaned_count = 0;
- }
-
- /* use prefetched values */
- rx_desc = next_rxd;
- buffer_info = next_buffer;
-
- staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
- }
- rx_ring->next_to_clean = i;
-
- cleaned_count = e1000_desc_unused(rx_ring);
- if (cleaned_count)
- adapter->alloc_rx_buf(adapter, cleaned_count);
-
- adapter->total_rx_bytes += total_rx_bytes;
- adapter->total_rx_packets += total_rx_packets;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
- return cleaned;
-}
-
-/**
- * e1000_consume_page - helper function
- **/
-static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
- u16 length)
-{
- bi->page = NULL;
- skb->len += length;
- skb->data_len += length;
- skb->truesize += length;
-}
-
-/**
- * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
- * @adapter: board private structure
- *
- * the return value indicates whether actual cleaning was done, there
- * is no guarantee that everything was cleaned
- **/
-
-static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
- int *work_done, int work_to_do)
-{
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_rx_desc *rx_desc, *next_rxd;
- struct e1000_buffer *buffer_info, *next_buffer;
- u32 length;
- unsigned int i;
- int cleaned_count = 0;
- bool cleaned = false;
- unsigned int total_rx_bytes=0, total_rx_packets=0;
-
- i = rx_ring->next_to_clean;
- rx_desc = E1000_RX_DESC(*rx_ring, i);
- buffer_info = &rx_ring->buffer_info[i];
-
- while (rx_desc->status & E1000_RXD_STAT_DD) {
- struct sk_buff *skb;
- u8 status;
-
- if (*work_done >= work_to_do)
- break;
- (*work_done)++;
-
- status = rx_desc->status;
- skb = buffer_info->skb;
- buffer_info->skb = NULL;
-
- ++i;
- if (i == rx_ring->count)
- i = 0;
- next_rxd = E1000_RX_DESC(*rx_ring, i);
- prefetch(next_rxd);
-
- next_buffer = &rx_ring->buffer_info[i];
-
- cleaned = true;
- cleaned_count++;
- pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- buffer_info->dma = 0;
-
- length = le16_to_cpu(rx_desc->length);
-
- /* errors is only valid for DD + EOP descriptors */
- if (unlikely((status & E1000_RXD_STAT_EOP) &&
- (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
- /* recycle both page and skb */
- buffer_info->skb = skb;
- /* an error means any chain goes out the window
- * too */
- if (rx_ring->rx_skb_top)
- dev_kfree_skb(rx_ring->rx_skb_top);
- rx_ring->rx_skb_top = NULL;
- goto next_desc;
- }
-
-#define rxtop rx_ring->rx_skb_top
- if (!(status & E1000_RXD_STAT_EOP)) {
- /* this descriptor is only the beginning (or middle) */
- if (!rxtop) {
- /* this is the beginning of a chain */
- rxtop = skb;
- skb_fill_page_desc(rxtop, 0, buffer_info->page,
- 0, length);
- } else {
- /* this is the middle of a chain */
- skb_fill_page_desc(rxtop,
- skb_shinfo(rxtop)->nr_frags,
- buffer_info->page, 0, length);
- /* re-use the skb, only consumed the page */
- buffer_info->skb = skb;
- }
- e1000_consume_page(buffer_info, rxtop, length);
- goto next_desc;
- } else {
- if (rxtop) {
- /* end of the chain */
- skb_fill_page_desc(rxtop,
- skb_shinfo(rxtop)->nr_frags,
- buffer_info->page, 0, length);
- /* re-use the current skb, we only consumed the
- * page */
- buffer_info->skb = skb;
- skb = rxtop;
- rxtop = NULL;
- e1000_consume_page(buffer_info, skb, length);
- } else {
- /* no chain, got EOP, this buf is the packet
- * copybreak to save the put_page/alloc_page */
- if (length <= copybreak &&
- skb_tailroom(skb) >= length) {
- u8 *vaddr;
- vaddr = kmap_atomic(buffer_info->page,
- KM_SKB_DATA_SOFTIRQ);
- memcpy(skb_tail_pointer(skb), vaddr,
- length);
- kunmap_atomic(vaddr,
- KM_SKB_DATA_SOFTIRQ);
- /* re-use the page, so don't erase
- * buffer_info->page */
- skb_put(skb, length);
- } else {
- skb_fill_page_desc(skb, 0,
- buffer_info->page, 0,
- length);
- e1000_consume_page(buffer_info, skb,
- length);
- }
- }
- }
-
- /* Receive Checksum Offload XXX recompute due to CRC strip? */
- e1000_rx_checksum(adapter,
- (u32)(status) |
- ((u32)(rx_desc->errors) << 24),
- le16_to_cpu(rx_desc->csum), skb);
-
- /* probably a little skewed due to removing CRC */
- total_rx_bytes += skb->len;
- total_rx_packets++;
-
- /* eth type trans needs skb->data to point to something */
- if (!pskb_may_pull(skb, ETH_HLEN)) {
- e_err("pskb_may_pull failed.\n");
- dev_kfree_skb(skb);
- goto next_desc;
- }
-
- e1000_receive_skb(adapter, netdev, skb, status,
- rx_desc->special);
-
-next_desc:
- rx_desc->status = 0;
-
- /* return some buffers to hardware, one at a time is too slow */
- if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
- adapter->alloc_rx_buf(adapter, cleaned_count);
- cleaned_count = 0;
- }
-
- /* use prefetched values */
- rx_desc = next_rxd;
- buffer_info = next_buffer;
- }
- rx_ring->next_to_clean = i;
-
- cleaned_count = e1000_desc_unused(rx_ring);
- if (cleaned_count)
- adapter->alloc_rx_buf(adapter, cleaned_count);
-
- adapter->total_rx_bytes += total_rx_bytes;
- adapter->total_rx_packets += total_rx_packets;
- adapter->net_stats.rx_bytes += total_rx_bytes;
- adapter->net_stats.rx_packets += total_rx_packets;
- return cleaned;
-}
-
-/**
- * e1000_clean_rx_ring - Free Rx Buffers per Queue
- * @adapter: board private structure
- **/
-static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
-{
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_buffer *buffer_info;
- struct e1000_ps_page *ps_page;
- struct pci_dev *pdev = adapter->pdev;
- unsigned int i, j;
-
- /* Free all the Rx ring sk_buffs */
- for (i = 0; i < rx_ring->count; i++) {
- buffer_info = &rx_ring->buffer_info[i];
- if (buffer_info->dma) {
- if (adapter->clean_rx == e1000_clean_rx_irq)
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_buffer_len,
- PCI_DMA_FROMDEVICE);
- else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
- pci_unmap_page(pdev, buffer_info->dma,
- PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_ps_bsize0,
- PCI_DMA_FROMDEVICE);
- buffer_info->dma = 0;
- }
-
- if (buffer_info->page) {
- put_page(buffer_info->page);
- buffer_info->page = NULL;
- }
-
- if (buffer_info->skb) {
- dev_kfree_skb(buffer_info->skb);
- buffer_info->skb = NULL;
- }
-
- for (j = 0; j < PS_PAGE_BUFFERS; j++) {
- ps_page = &buffer_info->ps_pages[j];
- if (!ps_page->page)
- break;
- pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- ps_page->dma = 0;
- put_page(ps_page->page);
- ps_page->page = NULL;
- }
- }
-
- /* there also may be some cached data from a chained receive */
- if (rx_ring->rx_skb_top) {
- dev_kfree_skb(rx_ring->rx_skb_top);
- rx_ring->rx_skb_top = NULL;
- }
-
- /* Zero out the descriptor ring */
- memset(rx_ring->desc, 0, rx_ring->size);
-
- rx_ring->next_to_clean = 0;
- rx_ring->next_to_use = 0;
-
- writel(0, adapter->hw.hw_addr + rx_ring->head);
- writel(0, adapter->hw.hw_addr + rx_ring->tail);
-}
-
-static void e1000e_downshift_workaround(struct work_struct *work)
-{
- struct e1000_adapter *adapter = container_of(work,
- struct e1000_adapter, downshift_task);
-
- e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
-}
-
-/**
- * e1000_intr_msi - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- **/
-static irqreturn_t e1000_intr_msi(int irq, void *data)
-{
- struct net_device *netdev = data;
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 icr = er32(ICR);
-
- /*
- * read ICR disables interrupts using IAM
- */
-
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- hw->mac.get_link_status = 1;
- /*
- * ICH8 workaround-- Call gig speed drop workaround on cable
- * disconnect (LSC) before accessing any PHY registers
- */
- if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
- (!(er32(STATUS) & E1000_STATUS_LU)))
- schedule_work(&adapter->downshift_task);
-
- /*
- * 80003ES2LAN workaround-- For packet buffer work-around on
- * link down event; disable receives here in the ISR and reset
- * adapter in watchdog
- */
- if (netif_carrier_ok(netdev) &&
- adapter->flags & FLAG_RX_NEEDS_RESTART) {
- /* disable receives */
- u32 rctl = er32(RCTL);
- ew32(RCTL, rctl & ~E1000_RCTL_EN);
- adapter->flags |= FLAG_RX_RESTART_NOW;
- }
- /* guard against interrupt when we're going down */
- if (!test_bit(__E1000_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
- }
-
- if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
- adapter->total_tx_bytes = 0;
- adapter->total_tx_packets = 0;
- adapter->total_rx_bytes = 0;
- adapter->total_rx_packets = 0;
- __netif_rx_schedule(netdev, &adapter->napi);
- }
-
- return IRQ_HANDLED;
-}
-
-/**
- * e1000_intr - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- **/
-static irqreturn_t e1000_intr(int irq, void *data)
-{
- struct net_device *netdev = data;
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
- u32 rctl, icr = er32(ICR);
- if (!icr)
- return IRQ_NONE; /* Not our interrupt */
-
- /*
- * IMS will not auto-mask if INT_ASSERTED is not set, and if it is
- * not set, then the adapter didn't send an interrupt
- */
- if (!(icr & E1000_ICR_INT_ASSERTED))
- return IRQ_NONE;
-
- /*
- * Interrupt Auto-Mask...upon reading ICR,
- * interrupts are masked. No need for the
- * IMC write
- */
-
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
- hw->mac.get_link_status = 1;
- /*
- * ICH8 workaround-- Call gig speed drop workaround on cable
- * disconnect (LSC) before accessing any PHY registers
- */
- if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
- (!(er32(STATUS) & E1000_STATUS_LU)))
- schedule_work(&adapter->downshift_task);
-
- /*
- * 80003ES2LAN workaround--
- * For packet buffer work-around on link down event;
- * disable receives here in the ISR and
- * reset adapter in watchdog
- */
- if (netif_carrier_ok(netdev) &&
- (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
- /* disable receives */
- rctl = er32(RCTL);
- ew32(RCTL, rctl & ~E1000_RCTL_EN);
- adapter->flags |= FLAG_RX_RESTART_NOW;
- }
- /* guard against interrupt when we're going down */
- if (!test_bit(__E1000_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
- }
-
- if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
- adapter->total_tx_bytes = 0;
- adapter->total_tx_packets = 0;
- adapter->total_rx_bytes = 0;
- adapter->total_rx_packets = 0;
- __netif_rx_schedule(netdev, &adapter->napi);
- }
-
- return IRQ_HANDLED;
-}
-
-/**
- * e1000_request_irq - initialize interrupts
- *
- * Attempts to configure interrupts using the best available
- * capabilities of the hardware and kernel.
- **/
-static int e1000_request_irq(struct e1000_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- int irq_flags = IRQF_SHARED;
- int err;
-
- if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) {
- err = pci_enable_msi(adapter->pdev);
- if (!err) {
- adapter->flags |= FLAG_MSI_ENABLED;
- irq_flags = 0;
- }
- }
-
- err = request_irq(adapter->pdev->irq,
- ((adapter->flags & FLAG_MSI_ENABLED) ?
- &e1000_intr_msi : &e1000_intr),
- irq_flags, netdev->name, netdev);
- if (err) {
- if (adapter->flags & FLAG_MSI_ENABLED) {
- pci_disable_msi(adapter->pdev);
- adapter->flags &= ~FLAG_MSI_ENABLED;
- }
- e_err("Unable to allocate interrupt, Error: %d\n", err);
- }
-
- return err;
-}
-
-static void e1000_free_irq(struct e1000_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
-
- free_irq(adapter->pdev->irq, netdev);
- if (adapter->flags & FLAG_MSI_ENABLED) {
- pci_disable_msi(adapter->pdev);
- adapter->flags &= ~FLAG_MSI_ENABLED;
- }
-}
-
-/**
- * e1000_irq_disable - Mask off interrupt generation on the NIC
- **/
-static void e1000_irq_disable(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- ew32(IMC, ~0);
- e1e_flush();
- synchronize_irq(adapter->pdev->irq);
-}
-
-/**
- * e1000_irq_enable - Enable default interrupt generation settings
- **/
-static void e1000_irq_enable(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- ew32(IMS, IMS_ENABLE_MASK);
- e1e_flush();
-}
-
-/**
- * e1000_get_hw_control - get control of the h/w from f/w
- * @adapter: address of board private structure
- *
- * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
- * For ASF and Pass Through versions of f/w this means that
- * the driver is loaded. For AMT version (only with 82573)
- * of the f/w this means that the network i/f is open.
- **/
-static void e1000_get_hw_control(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl_ext;
- u32 swsm;
-
- /* Let firmware know the driver has taken over */
- if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
- swsm = er32(SWSM);
- ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
- } else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
- ctrl_ext = er32(CTRL_EXT);
- ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
- }
-}
-
-/**
- * e1000_release_hw_control - release control of the h/w to f/w
- * @adapter: address of board private structure
- *
- * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
- * For ASF and Pass Through versions of f/w this means that the
- * driver is no longer loaded. For AMT version (only with 82573) i
- * of the f/w this means that the network i/f is closed.
- *
- **/
-static void e1000_release_hw_control(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl_ext;
- u32 swsm;
-
- /* Let firmware taken over control of h/w */
- if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
- swsm = er32(SWSM);
- ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
- } else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
- ctrl_ext = er32(CTRL_EXT);
- ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
- }
-}
-
-/**
- * @e1000_alloc_ring - allocate memory for a ring structure
- **/
-static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
- struct e1000_ring *ring)
-{
- struct pci_dev *pdev = adapter->pdev;
-
- ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
- GFP_KERNEL);
- if (!ring->desc)
- return -ENOMEM;
-
- return 0;
-}
-
-/**
- * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
- * @adapter: board private structure
- *
- * Return 0 on success, negative on failure
- **/
-int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
-{
- struct e1000_ring *tx_ring = adapter->tx_ring;
- int err = -ENOMEM, size;
-
- size = sizeof(struct e1000_buffer) * tx_ring->count;
- tx_ring->buffer_info = vmalloc(size);
- if (!tx_ring->buffer_info)
- goto err;
- memset(tx_ring->buffer_info, 0, size);
-
- /* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
- tx_ring->size = ALIGN(tx_ring->size, 4096);
-
- err = e1000_alloc_ring_dma(adapter, tx_ring);
- if (err)
- goto err;
-
- tx_ring->next_to_use = 0;
- tx_ring->next_to_clean = 0;
- spin_lock_init(&adapter->tx_queue_lock);
-
- return 0;
-err:
- vfree(tx_ring->buffer_info);
- e_err("Unable to allocate memory for the transmit descriptor ring\n");
- return err;
-}
-
-/**
- * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
- * @adapter: board private structure
- *
- * Returns 0 on success, negative on failure
- **/
-int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
-{
- struct e1000_ring *rx_ring = adapter->rx_ring;
- struct e1000_buffer *buffer_info;
- int i, size, desc_len, err = -ENOMEM;
-
- size = sizeof(struct e1000_buffer) * rx_ring->count;
- rx_ring->buffer_info = vmalloc(size);
- if (!rx_ring->buffer_info)
- goto err;
- memset(rx_ring->buffer_info, 0, size);
-
- for (i = 0; i < rx_ring->count; i++) {
- buffer_info = &rx_ring->buffer_info[i];
- buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
- sizeof(struct e1000_ps_page),
- GFP_KERNEL);
- if (!buffer_info->ps_pages)
- goto err_pages;
- }
-
- desc_len = sizeof(union e1000_rx_desc_packet_split);
-
- /* Round up to nearest 4K */
- rx_ring->size = rx_ring->count * desc_len;
- rx_ring->size = ALIGN(rx_ring->size, 4096);
-
- err = e1000_alloc_ring_dma(adapter, rx_ring);
- if (err)
- goto err_pages;
-
- rx_ring->next_to_clean = 0;
- rx_ring->next_to_use = 0;
- rx_ring->rx_skb_top = NULL;
-
- return 0;
-
-err_pages:
- for (i = 0; i < rx_ring->count; i++) {
- buffer_info = &rx_ring->buffer_info[i];
- kfree(buffer_info->ps_pages);
- }
-err:
- vfree(rx_ring->buffer_info);
- e_err("Unable to allocate memory for the transmit descriptor ring\n");
- return err;
-}
-
-/**
- * e1000_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
- **/
-static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
-{
- struct e1000_ring *tx_ring = adapter->tx_ring;
- struct e1000_buffer *buffer_info;
- unsigned long size;
- unsigned int i;
-
- for (i = 0; i < tx_ring->count; i++) {
- buffer_info = &tx_ring->buffer_info[i];
- e1000_put_txbuf(adapter, buffer_info);
- }
-
- size = sizeof(struct e1000_buffer) * tx_ring->count;
- memset(tx_ring->buffer_info, 0, size);
-
- memset(tx_ring->desc, 0, tx_ring->size);
-
- tx_ring->next_to_use = 0;
- tx_ring->next_to_clean = 0;
-
- writel(0, adapter->hw.hw_addr + tx_ring->head);
- writel(0, adapter->hw.hw_addr + tx_ring->tail);
-}
-
-/**
- * e1000e_free_tx_resources - Free Tx Resources per Queue
- * @adapter: board private structure
- *
- * Free all transmit software resources
- **/
-void e1000e_free_tx_resources(struct e1000_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_ring *tx_ring = adapter->tx_ring;
-
- e1000_clean_tx_ring(adapter);
-
- vfree(tx_ring->buffer_info);
- tx_ring->buffer_info = NULL;
-
- dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
- tx_ring->dma);
- tx_ring->desc = NULL;
-}
-
-/**
- * e1000e_free_rx_resources - Free Rx Resources
- * @adapter: board private structure
- *
- * Free all receive software resources
- **/
-
-void e1000e_free_rx_resources(struct e1000_adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- int i;
-
- e1000_clean_rx_ring(adapter);
-
- for (i = 0; i < rx_ring->count; i++) {
- kfree(rx_ring->buffer_info[i].ps_pages);
- }
-
- vfree(rx_ring->buffer_info);
- rx_ring->buffer_info = NULL;
-
- dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
- rx_ring->dma);
- rx_ring->desc = NULL;
-}
-
-/**
- * e1000_update_itr - update the dynamic ITR value based on statistics
- * @adapter: pointer to adapter
- * @itr_setting: current adapter->itr
- * @packets: the number of packets during this measurement interval
- * @bytes: the number of bytes during this measurement interval
- *
- * Stores a new ITR value based on packets and byte
- * counts during the last interrupt. The advantage of per interrupt
- * computation is faster updates and more accurate ITR for the current
- * traffic pattern. Constants in this function were computed
- * based on theoretical maximum wire speed and thresholds were set based
- * on testing data as well as attempting to minimize response time
- * while increasing bulk throughput.
- * this functionality is controlled by the InterruptThrottleRate module
- * parameter (see e1000_param.c)
- **/
-static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
- u16 itr_setting, int packets,
- int bytes)
-{
- unsigned int retval = itr_setting;
-
- if (packets == 0)
- goto update_itr_done;
-
- switch (itr_setting) {
- case lowest_latency:
- /* handle TSO and jumbo frames */
- if (bytes/packets > 8000)
- retval = bulk_latency;
- else if ((packets < 5) && (bytes > 512)) {
- retval = low_latency;
- }
- break;
- case low_latency: /* 50 usec aka 20000 ints/s */
- if (bytes > 10000) {
- /* this if handles the TSO accounting */
- if (bytes/packets > 8000) {
- retval = bulk_latency;
- } else if ((packets < 10) || ((bytes/packets) > 1200)) {
- retval = bulk_latency;
- } else if ((packets > 35)) {
- retval = lowest_latency;
- }
- } else if (bytes/packets > 2000) {
- retval = bulk_latency;
- } else if (packets <= 2 && bytes < 512) {
- retval = lowest_latency;
- }
- break;
- case bulk_latency: /* 250 usec aka 4000 ints/s */
- if (bytes > 25000) {
- if (packets > 35) {
- retval = low_latency;
- }
- } else if (bytes < 6000) {
- retval = low_latency;
- }
- break;
- }
-
-update_itr_done:
- return retval;
-}
-
-static void e1000_set_itr(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u16 current_itr;
- u32 new_itr = adapter->itr;
-
- /* for non-gigabit speeds, just fix the interrupt rate at 4000 */
- if (adapter->link_speed != SPEED_1000) {
- current_itr = 0;
- new_itr = 4000;
- goto set_itr_now;
- }
-
- adapter->tx_itr = e1000_update_itr(adapter,
- adapter->tx_itr,
- adapter->total_tx_packets,
- adapter->total_tx_bytes);
- /* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
- adapter->tx_itr = low_latency;
-
- adapter->rx_itr = e1000_update_itr(adapter,
- adapter->rx_itr,
- adapter->total_rx_packets,
- adapter->total_rx_bytes);
- /* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
- adapter->rx_itr = low_latency;
-
- current_itr = max(adapter->rx_itr, adapter->tx_itr);
-
- switch (current_itr) {
- /* counts and packets in update_itr are dependent on these numbers */
- case lowest_latency:
- new_itr = 70000;
- break;
- case low_latency:
- new_itr = 20000; /* aka hwitr = ~200 */
- break;
- case bulk_latency:
- new_itr = 4000;
- break;
- default:
- break;
- }
-
-set_itr_now:
- if (new_itr != adapter->itr) {
- /*
- * this attempts to bias the interrupt rate towards Bulk
- * by adding intermediate steps when interrupt rate is
- * increasing
- */
- new_itr = new_itr > adapter->itr ?
- min(adapter->itr + (new_itr >> 2), new_itr) :
- new_itr;
- adapter->itr = new_itr;
- ew32(ITR, 1000000000 / (new_itr * 256));
- }
-}
-
-/**
- * e1000_clean - NAPI Rx polling callback
- * @napi: struct associated with this polling callback
- * @budget: amount of packets driver is allowed to process this poll
- **/
-static int e1000_clean(struct napi_struct *napi, int budget)
-{
- struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
- struct net_device *poll_dev = adapter->netdev;
- int tx_cleaned = 0, work_done = 0;
-
- /* Must NOT use netdev_priv macro here. */
- adapter = poll_dev->priv;
-
- /*
- * e1000_clean is called per-cpu. This lock protects
- * tx_ring from being cleaned by multiple cpus
- * simultaneously. A failure obtaining the lock means
- * tx_ring is currently being cleaned anyway.
- */
- if (spin_trylock(&adapter->tx_queue_lock)) {
- tx_cleaned = e1000_clean_tx_irq(adapter);
- spin_unlock(&adapter->tx_queue_lock);
- }
-
- adapter->clean_rx(adapter, &work_done, budget);
-
- if (tx_cleaned)
- work_done = budget;
-
- /* If budget not fully consumed, exit the polling mode */
- if (work_done < budget) {
- if (adapter->itr_setting & 3)
- e1000_set_itr(adapter);
- netif_rx_complete(poll_dev, napi);
- e1000_irq_enable(adapter);
- }
-
- return work_done;
-}
-
-static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 vfta, index;
-
- /* don't update vlan cookie if already programmed */
- if ((adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
- (vid == adapter->mng_vlan_id))
- return;
- /* add VID to filter table */
- index = (vid >> 5) & 0x7F;
- vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
- vfta |= (1 << (vid & 0x1F));
- e1000e_write_vfta(hw, index, vfta);
-}
-
-static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 vfta, index;
-
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_disable(adapter);
- vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_enable(adapter);
-
- if ((adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
- (vid == adapter->mng_vlan_id)) {
- /* release control to f/w */
- e1000_release_hw_control(adapter);
- return;
- }
-
- /* remove VID from filter table */
- index = (vid >> 5) & 0x7F;
- vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
- vfta &= ~(1 << (vid & 0x1F));
- e1000e_write_vfta(hw, index, vfta);
-}
-
-static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- u16 vid = adapter->hw.mng_cookie.vlan_id;
- u16 old_vid = adapter->mng_vlan_id;
-
- if (!adapter->vlgrp)
- return;
-
- if (!vlan_group_get_device(adapter->vlgrp, vid)) {
- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
- if (adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
- e1000_vlan_rx_add_vid(netdev, vid);
- adapter->mng_vlan_id = vid;
- }
-
- if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
- (vid != old_vid) &&
- !vlan_group_get_device(adapter->vlgrp, old_vid))
- e1000_vlan_rx_kill_vid(netdev, old_vid);
- } else {
- adapter->mng_vlan_id = vid;
- }
-}
-
-
-static void e1000_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, rctl;
-
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_disable(adapter);
- adapter->vlgrp = grp;
-
- if (grp) {
- /* enable VLAN tag insert/strip */
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_VME;
- ew32(CTRL, ctrl);
-
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- /* enable VLAN receive filtering */
- rctl = er32(RCTL);
- rctl &= ~E1000_RCTL_CFIEN;
- ew32(RCTL, rctl);
- e1000_update_mng_vlan(adapter);
- }
- } else {
- /* disable VLAN tag insert/strip */
- ctrl = er32(CTRL);
- ctrl &= ~E1000_CTRL_VME;
- ew32(CTRL, ctrl);
-
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- if (adapter->mng_vlan_id !=
- (u16)E1000_MNG_VLAN_NONE) {
- e1000_vlan_rx_kill_vid(netdev,
- adapter->mng_vlan_id);
- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
- }
- }
- }
-
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_enable(adapter);
-}
-
-static void e1000_restore_vlan(struct e1000_adapter *adapter)
-{
- u16 vid;
-
- e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-
- if (!adapter->vlgrp)
- return;
-
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
- if (!vlan_group_get_device(adapter->vlgrp, vid))
- continue;
- e1000_vlan_rx_add_vid(adapter->netdev, vid);
- }
-}
-
-static void e1000_init_manageability(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 manc, manc2h;
-
- if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
- return;
-
- manc = er32(MANC);
-
- /*
- * enable receiving management packets to the host. this will probably
- * generate destination unreachable messages from the host OS, but
- * the packets will be handled on SMBUS
- */
- manc |= E1000_MANC_EN_MNG2HOST;
- manc2h = er32(MANC2H);
-#define E1000_MNG2HOST_PORT_623 (1 << 5)
-#define E1000_MNG2HOST_PORT_664 (1 << 6)
- manc2h |= E1000_MNG2HOST_PORT_623;
- manc2h |= E1000_MNG2HOST_PORT_664;
- ew32(MANC2H, manc2h);
- ew32(MANC, manc);
-}
-
-/**
- * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Tx unit of the MAC after a reset.
- **/
-static void e1000_configure_tx(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_ring *tx_ring = adapter->tx_ring;
- u64 tdba;
- u32 tdlen, tctl, tipg, tarc;
- u32 ipgr1, ipgr2;
-
- /* Setup the HW Tx Head and Tail descriptor pointers */
- tdba = tx_ring->dma;
- tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
- ew32(TDBAL, (tdba & DMA_32BIT_MASK));
- ew32(TDBAH, (tdba >> 32));
- ew32(TDLEN, tdlen);
- ew32(TDH, 0);
- ew32(TDT, 0);
- tx_ring->head = E1000_TDH;
- tx_ring->tail = E1000_TDT;
-
- /* Set the default values for the Tx Inter Packet Gap timer */
- tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */
- ipgr1 = DEFAULT_82543_TIPG_IPGR1; /* 8 */
- ipgr2 = DEFAULT_82543_TIPG_IPGR2; /* 6 */
-
- if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN)
- ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /* 7 */
-
- tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
- tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
- ew32(TIPG, tipg);
-
- /* Set the Tx Interrupt Delay register */
- ew32(TIDV, adapter->tx_int_delay);
- /* Tx irq moderation */
- ew32(TADV, adapter->tx_abs_int_delay);
-
- /* Program the Transmit Control Register */
- tctl = er32(TCTL);
- tctl &= ~E1000_TCTL_CT;
- tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
- (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
-
- if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
- tarc = er32(TARC(0));
- /*
- * set the speed mode bit, we'll clear it if we're not at
- * gigabit link later
- */
-#define SPEED_MODE_BIT (1 << 21)
- tarc |= SPEED_MODE_BIT;
- ew32(TARC(0), tarc);
- }
-
- /* errata: program both queues to unweighted RR */
- if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
- tarc = er32(TARC(0));
- tarc |= 1;
- ew32(TARC(0), tarc);
- tarc = er32(TARC(1));
- tarc |= 1;
- ew32(TARC(1), tarc);
- }
-
- e1000e_config_collision_dist(hw);
-
- /* Setup Transmit Descriptor Settings for eop descriptor */
- adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
-
- /* only set IDE if we are delaying interrupts using the timers */
- if (adapter->tx_int_delay)
- adapter->txd_cmd |= E1000_TXD_CMD_IDE;
-
- /* enable Report Status bit */
- adapter->txd_cmd |= E1000_TXD_CMD_RS;
-
- ew32(TCTL, tctl);
-
- adapter->tx_queue_len = adapter->netdev->tx_queue_len;
-}
-
-/**
- * e1000_setup_rctl - configure the receive control registers
- * @adapter: Board private structure
- **/
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
-static void e1000_setup_rctl(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 rctl, rfctl;
- u32 psrctl = 0;
- u32 pages = 0;
-
- /* Program MC offset vector base */
- rctl = er32(RCTL);
- rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
- rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
- E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
- (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
-
- /* Do not Store bad packets */
- rctl &= ~E1000_RCTL_SBP;
-
- /* Enable Long Packet receive */
- if (adapter->netdev->mtu <= ETH_DATA_LEN)
- rctl &= ~E1000_RCTL_LPE;
- else
- rctl |= E1000_RCTL_LPE;
-
- /* Enable hardware CRC frame stripping */
- rctl |= E1000_RCTL_SECRC;
-
- /* Setup buffer sizes */
- rctl &= ~E1000_RCTL_SZ_4096;
- rctl |= E1000_RCTL_BSEX;
- switch (adapter->rx_buffer_len) {
- case 256:
- rctl |= E1000_RCTL_SZ_256;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case 512:
- rctl |= E1000_RCTL_SZ_512;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case 1024:
- rctl |= E1000_RCTL_SZ_1024;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case 2048:
- default:
- rctl |= E1000_RCTL_SZ_2048;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case 4096:
- rctl |= E1000_RCTL_SZ_4096;
- break;
- case 8192:
- rctl |= E1000_RCTL_SZ_8192;
- break;
- case 16384:
- rctl |= E1000_RCTL_SZ_16384;
- break;
- }
-
- /*
- * 82571 and greater support packet-split where the protocol
- * header is placed in skb->data and the packet data is
- * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
- * In the case of a non-split, skb->data is linearly filled,
- * followed by the page buffers. Therefore, skb->data is
- * sized to hold the largest protocol header.
- *
- * allocations using alloc_page take too long for regular MTU
- * so only enable packet split for jumbo frames
- *
- * Using pages when the page size is greater than 16k wastes
- * a lot of memory, since we allocate 3 pages at all times
- * per packet.
- */
- pages = PAGE_USE_COUNT(adapter->netdev->mtu);
- if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) &&
- (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
- adapter->rx_ps_pages = pages;
- else
- adapter->rx_ps_pages = 0;
-
- if (adapter->rx_ps_pages) {
- /* Configure extra packet-split registers */
- rfctl = er32(RFCTL);
- rfctl |= E1000_RFCTL_EXTEN;
- /*
- * disable packet split support for IPv6 extension headers,
- * because some malformed IPv6 headers can hang the Rx
- */
- rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
- E1000_RFCTL_NEW_IPV6_EXT_DIS);
-
- ew32(RFCTL, rfctl);
-
- /* Enable Packet split descriptors */
- rctl |= E1000_RCTL_DTYP_PS;
-
- psrctl |= adapter->rx_ps_bsize0 >>
- E1000_PSRCTL_BSIZE0_SHIFT;
-
- switch (adapter->rx_ps_pages) {
- case 3:
- psrctl |= PAGE_SIZE <<
- E1000_PSRCTL_BSIZE3_SHIFT;
- case 2:
- psrctl |= PAGE_SIZE <<
- E1000_PSRCTL_BSIZE2_SHIFT;
- case 1:
- psrctl |= PAGE_SIZE >>
- E1000_PSRCTL_BSIZE1_SHIFT;
- break;
- }
-
- ew32(PSRCTL, psrctl);
- }
-
- ew32(RCTL, rctl);
- /* just started the receive unit, no need to restart */
- adapter->flags &= ~FLAG_RX_RESTART_NOW;
-}
-
-/**
- * e1000_configure_rx - Configure Receive Unit after Reset
- * @adapter: board private structure
- *
- * Configure the Rx unit of the MAC after a reset.
- **/
-static void e1000_configure_rx(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_ring *rx_ring = adapter->rx_ring;
- u64 rdba;
- u32 rdlen, rctl, rxcsum, ctrl_ext;
-
- if (adapter->rx_ps_pages) {
- /* this is a 32 byte descriptor */
- rdlen = rx_ring->count *
- sizeof(union e1000_rx_desc_packet_split);
- adapter->clean_rx = e1000_clean_rx_irq_ps;
- adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
- } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
- rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
- adapter->clean_rx = e1000_clean_jumbo_rx_irq;
- adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
- } else {
- rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
- adapter->clean_rx = e1000_clean_rx_irq;
- adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
- }
-
- /* disable receives while setting up the descriptors */
- rctl = er32(RCTL);
- ew32(RCTL, rctl & ~E1000_RCTL_EN);
- e1e_flush();
- msleep(10);
-
- /* set the Receive Delay Timer Register */
- ew32(RDTR, adapter->rx_int_delay);
-
- /* irq moderation */
- ew32(RADV, adapter->rx_abs_int_delay);
- if (adapter->itr_setting != 0)
- ew32(ITR, 1000000000 / (adapter->itr * 256));
-
- ctrl_ext = er32(CTRL_EXT);
- /* Reset delay timers after every interrupt */
- ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
- /* Auto-Mask interrupts upon ICR access */
- ctrl_ext |= E1000_CTRL_EXT_IAME;
- ew32(IAM, 0xffffffff);
- ew32(CTRL_EXT, ctrl_ext);
- e1e_flush();
-
- /*
- * Setup the HW Rx Head and Tail Descriptor Pointers and
- * the Base and Length of the Rx Descriptor Ring
- */
- rdba = rx_ring->dma;
- ew32(RDBAL, (rdba & DMA_32BIT_MASK));
- ew32(RDBAH, (rdba >> 32));
- ew32(RDLEN, rdlen);
- ew32(RDH, 0);
- ew32(RDT, 0);
- rx_ring->head = E1000_RDH;
- rx_ring->tail = E1000_RDT;
-
- /* Enable Receive Checksum Offload for TCP and UDP */
- rxcsum = er32(RXCSUM);
- if (adapter->flags & FLAG_RX_CSUM_ENABLED) {
- rxcsum |= E1000_RXCSUM_TUOFL;
-
- /*
- * IPv4 payload checksum for UDP fragments must be
- * used in conjunction with packet-split.
- */
- if (adapter->rx_ps_pages)
- rxcsum |= E1000_RXCSUM_IPPCSE;
- } else {
- rxcsum &= ~E1000_RXCSUM_TUOFL;
- /* no need to clear IPPCSE as it defaults to 0 */
- }
- ew32(RXCSUM, rxcsum);
-
- /*
- * Enable early receives on supported devices, only takes effect when
- * packet size is equal or larger than the specified value (in 8 byte
- * units), e.g. using jumbo frames when setting to E1000_ERT_2048
- */
- if ((adapter->flags & FLAG_HAS_ERT) &&
- (adapter->netdev->mtu > ETH_DATA_LEN)) {
- u32 rxdctl = er32(RXDCTL(0));
- ew32(RXDCTL(0), rxdctl | 0x3);
- ew32(ERT, E1000_ERT_2048 | (1 << 13));
- /*
- * With jumbo frames and early-receive enabled, excessive
- * C4->C2 latencies result in dropped transactions.
- */
- pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
- e1000e_driver_name, 55);
- } else {
- pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
- e1000e_driver_name,
- PM_QOS_DEFAULT_VALUE);
- }
-
- /* Enable Receives */
- ew32(RCTL, rctl);
-}
-
-/**
- * e1000_update_mc_addr_list - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
- *
- * Updates the Receive Address Registers and Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this. Currently no func pointer
- * exists and all implementations are handled in the generic version of this
- * function.
- **/
-static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
- u32 mc_addr_count, u32 rar_used_count,
- u32 rar_count)
-{
- hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count,
- rar_used_count, rar_count);
-}
-
-/**
- * e1000_set_multi - Multicast and Promiscuous mode set
- * @netdev: network interface device structure
- *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated. This routine is
- * responsible for configuring the hardware for proper multicast,
- * promiscuous mode, and all-multi behavior.
- **/
-static void e1000_set_multi(struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_mac_info *mac = &hw->mac;
- struct dev_mc_list *mc_ptr;
- u8 *mta_list;
- u32 rctl;
- int i;
-
- /* Check for Promiscuous and All Multicast modes */
-
- rctl = er32(RCTL);
-
- if (netdev->flags & IFF_PROMISC) {
- rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- rctl &= ~E1000_RCTL_VFE;
- } else {
- if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
- rctl &= ~E1000_RCTL_UPE;
- } else {
- rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
- }
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
- rctl |= E1000_RCTL_VFE;
- }
-
- ew32(RCTL, rctl);
-
- if (netdev->mc_count) {
- mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
- if (!mta_list)
- return;
-
- /* prepare a packed array of only addresses. */
- mc_ptr = netdev->mc_list;
-
- for (i = 0; i < netdev->mc_count; i++) {
- if (!mc_ptr)
- break;
- memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr,
- ETH_ALEN);
- mc_ptr = mc_ptr->next;
- }
-
- e1000_update_mc_addr_list(hw, mta_list, i, 1,
- mac->rar_entry_count);
- kfree(mta_list);
- } else {
- /*
- * if we're called from probe, we might not have
- * anything to do here, so clear out the list
- */
- e1000_update_mc_addr_list(hw, NULL, 0, 1, mac->rar_entry_count);
- }
-}
-
-/**
- * e1000_configure - configure the hardware for Rx and Tx
- * @adapter: private board structure
- **/
-static void e1000_configure(struct e1000_adapter *adapter)
-{
- e1000_set_multi(adapter->netdev);
-
- e1000_restore_vlan(adapter);
- e1000_init_manageability(adapter);
-
- e1000_configure_tx(adapter);
- e1000_setup_rctl(adapter);
- e1000_configure_rx(adapter);
- adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring));
-}
-
-/**
- * e1000e_power_up_phy - restore link in case the phy was powered down
- * @adapter: address of board private structure
- *
- * The phy may be powered down to save power and turn off link when the
- * driver is unloaded and wake on lan is not enabled (among others)
- * *** this routine MUST be followed by a call to e1000e_reset ***
- **/
-void e1000e_power_up_phy(struct e1000_adapter *adapter)
-{
- u16 mii_reg = 0;
-
- /* Just clear the power down bit to wake the phy back up */
- if (adapter->hw.phy.media_type == e1000_media_type_copper) {
- /*
- * According to the manual, the phy will retain its
- * settings across a power-down/up cycle
- */
- e1e_rphy(&adapter->hw, PHY_CONTROL, &mii_reg);
- mii_reg &= ~MII_CR_POWER_DOWN;
- e1e_wphy(&adapter->hw, PHY_CONTROL, mii_reg);
- }
-
- adapter->hw.mac.ops.setup_link(&adapter->hw);
-}
-
-/**
- * e1000_power_down_phy - Power down the PHY
- *
- * Power down the PHY so no link is implied when interface is down
- * The PHY cannot be powered down is management or WoL is active
- */
-static void e1000_power_down_phy(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u16 mii_reg;
-
- /* WoL is enabled */
- if (adapter->wol)
- return;
-
- /* non-copper PHY? */
- if (adapter->hw.phy.media_type != e1000_media_type_copper)
- return;
-
- /* reset is blocked because of a SoL/IDER session */
- if (e1000e_check_mng_mode(hw) || e1000_check_reset_block(hw))
- return;
-
- /* manageability (AMT) is enabled */
- if (er32(MANC) & E1000_MANC_SMBUS_EN)
- return;
-
- /* power down the PHY */
- e1e_rphy(hw, PHY_CONTROL, &mii_reg);
- mii_reg |= MII_CR_POWER_DOWN;
- e1e_wphy(hw, PHY_CONTROL, mii_reg);
- mdelay(1);
-}
-
-/**
- * e1000e_reset - bring the hardware into a known good state
- *
- * This function boots the hardware and enables some settings that
- * require a configuration cycle of the hardware - those cannot be
- * set/changed during runtime. After reset the device needs to be
- * properly configured for Rx, Tx etc.
- */
-void e1000e_reset(struct e1000_adapter *adapter)
-{
- struct e1000_mac_info *mac = &adapter->hw.mac;
- struct e1000_fc_info *fc = &adapter->hw.fc;
- struct e1000_hw *hw = &adapter->hw;
- u32 tx_space, min_tx_space, min_rx_space;
- u32 pba = adapter->pba;
- u16 hwm;
-
- /* reset Packet Buffer Allocation to default */
- ew32(PBA, pba);
-
- if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
- /*
- * To maintain wire speed transmits, the Tx FIFO should be
- * large enough to accommodate two full transmit packets,
- * rounded up to the next 1KB and expressed in KB. Likewise,
- * the Rx FIFO should be large enough to accommodate at least
- * one full receive packet and is similarly rounded up and
- * expressed in KB.
- */
- pba = er32(PBA);
- /* upper 16 bits has Tx packet buffer allocation size in KB */
- tx_space = pba >> 16;
- /* lower 16 bits has Rx packet buffer allocation size in KB */
- pba &= 0xffff;
- /*
- * the Tx fifo also stores 16 bytes of information about the tx
- * but don't include ethernet FCS because hardware appends it
- */
- min_tx_space = (adapter->max_frame_size +
- sizeof(struct e1000_tx_desc) -
- ETH_FCS_LEN) * 2;
- min_tx_space = ALIGN(min_tx_space, 1024);
- min_tx_space >>= 10;
- /* software strips receive CRC, so leave room for it */
- min_rx_space = adapter->max_frame_size;
- min_rx_space = ALIGN(min_rx_space, 1024);
- min_rx_space >>= 10;
-
- /*
- * If current Tx allocation is less than the min Tx FIFO size,
- * and the min Tx FIFO size is less than the current Rx FIFO
- * allocation, take space away from current Rx allocation
- */
- if ((tx_space < min_tx_space) &&
- ((min_tx_space - tx_space) < pba)) {
- pba -= min_tx_space - tx_space;
-
- /*
- * if short on Rx space, Rx wins and must trump tx
- * adjustment or use Early Receive if available
- */
- if ((pba < min_rx_space) &&
- (!(adapter->flags & FLAG_HAS_ERT)))
- /* ERT enabled in e1000_configure_rx */
- pba = min_rx_space;
- }
-
- ew32(PBA, pba);
- }
-
-
- /*
- * flow control settings
- *
- * The high water mark must be low enough to fit one full frame
- * (or the size used for early receive) above it in the Rx FIFO.
- * Set it to the lower of:
- * - 90% of the Rx FIFO size, and
- * - the full Rx FIFO size minus the early receive size (for parts
- * with ERT support assuming ERT set to E1000_ERT_2048), or
- * - the full Rx FIFO size minus one full frame
- */
- if (adapter->flags & FLAG_HAS_ERT)
- hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - (E1000_ERT_2048 << 3)));
- else
- hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - adapter->max_frame_size));
-
- fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
- fc->low_water = fc->high_water - 8;
-
- if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
- fc->pause_time = 0xFFFF;
- else
- fc->pause_time = E1000_FC_PAUSE_TIME;
- fc->send_xon = 1;
- fc->type = fc->original_type;
-
- /* Allow time for pending master requests to run */
- mac->ops.reset_hw(hw);
-
- /*
- * For parts with AMT enabled, let the firmware know
- * that the network interface is in control
- */
- if (adapter->flags & FLAG_HAS_AMT)
- e1000_get_hw_control(adapter);
-
- ew32(WUC, 0);
-
- if (mac->ops.init_hw(hw))
- e_err("Hardware Error\n");
-
- e1000_update_mng_vlan(adapter);
-
- /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
- ew32(VET, ETH_P_8021Q);
-
- e1000e_reset_adaptive(hw);
- e1000_get_phy_info(hw);
-
- if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) {
- u16 phy_data = 0;
- /*
- * speed up time to link by disabling smart power down, ignore
- * the return value of this function because there is nothing
- * different we would do if it failed
- */
- e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
- phy_data &= ~IGP02E1000_PM_SPD;
- e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
- }
-}
-
-int e1000e_up(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- /* hardware has been reset, we need to reload some things */
- e1000_configure(adapter);
-
- clear_bit(__E1000_DOWN, &adapter->state);
-
- napi_enable(&adapter->napi);
- e1000_irq_enable(adapter);
-
- /* fire a link change interrupt to start the watchdog */
- ew32(ICS, E1000_ICS_LSC);
- return 0;
-}
-
-void e1000e_down(struct e1000_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct e1000_hw *hw = &adapter->hw;
- u32 tctl, rctl;
-
- /*
- * signal that we're down so the interrupt handler does not
- * reschedule our watchdog timer
- */
- set_bit(__E1000_DOWN, &adapter->state);
-
- /* disable receives in the hardware */
- rctl = er32(RCTL);
- ew32(RCTL, rctl & ~E1000_RCTL_EN);
- /* flush and sleep below */
-
- netif_tx_stop_all_queues(netdev);
-
- /* disable transmits in the hardware */
- tctl = er32(TCTL);
- tctl &= ~E1000_TCTL_EN;
- ew32(TCTL, tctl);
- /* flush both disables and wait for them to finish */
- e1e_flush();
- msleep(10);
-
- napi_disable(&adapter->napi);
- e1000_irq_disable(adapter);
-
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
-
- netdev->tx_queue_len = adapter->tx_queue_len;
- netif_carrier_off(netdev);
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
-
- if (!pci_channel_offline(adapter->pdev))
- e1000e_reset(adapter);
- e1000_clean_tx_ring(adapter);
- e1000_clean_rx_ring(adapter);
-
- /*
- * TODO: for power management, we could drop the link and
- * pci_disable_device here.
- */
-}
-
-void e1000e_reinit_locked(struct e1000_adapter *adapter)
-{
- might_sleep();
- while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
- e1000e_down(adapter);
- e1000e_up(adapter);
- clear_bit(__E1000_RESETTING, &adapter->state);
-}
-
-/**
- * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
- * @adapter: board private structure to initialize
- *
- * e1000_sw_init initializes the Adapter private data structure.
- * Fields are initialized based on PCI device information and
- * OS network device settings (MTU size).
- **/
-static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
-
- adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
- adapter->rx_ps_bsize0 = 128;
- adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
- adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
-
- adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
- if (!adapter->tx_ring)
- goto err;
-
- adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
- if (!adapter->rx_ring)
- goto err;
-
- spin_lock_init(&adapter->tx_queue_lock);
-
- /* Explicitly disable IRQ since the NIC can be in any state. */
- e1000_irq_disable(adapter);
-
- set_bit(__E1000_DOWN, &adapter->state);
- return 0;
-
-err:
- e_err("Unable to allocate memory for queues\n");
- kfree(adapter->rx_ring);
- kfree(adapter->tx_ring);
- return -ENOMEM;
-}
-
-/**
- * e1000_intr_msi_test - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- **/
-static irqreturn_t e1000_intr_msi_test(int irq, void *data)
-{
- struct net_device *netdev = data;
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 icr = er32(ICR);
-
- e_dbg("%s: icr is %08X\n", netdev->name, icr);
- if (icr & E1000_ICR_RXSEQ) {
- adapter->flags &= ~FLAG_MSI_TEST_FAILED;
- wmb();
- }
-
- return IRQ_HANDLED;
-}
-
-/**
- * e1000_test_msi_interrupt - Returns 0 for successful test
- * @adapter: board private struct
- *
- * code flow taken from tg3.c
- **/
-static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- struct e1000_hw *hw = &adapter->hw;
- int err;
-
- /* poll_enable hasn't been called yet, so don't need disable */
- /* clear any pending events */
- er32(ICR);
-
- /* free the real vector and request a test handler */
- e1000_free_irq(adapter);
-
- /* Assume that the test fails, if it succeeds then the test
- * MSI irq handler will unset this flag */
- adapter->flags |= FLAG_MSI_TEST_FAILED;
-
- err = pci_enable_msi(adapter->pdev);
- if (err)
- goto msi_test_failed;
-
- err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
- netdev->name, netdev);
- if (err) {
- pci_disable_msi(adapter->pdev);
- goto msi_test_failed;
- }
-
- wmb();
-
- e1000_irq_enable(adapter);
-
- /* fire an unusual interrupt on the test handler */
- ew32(ICS, E1000_ICS_RXSEQ);
- e1e_flush();
- msleep(50);
-
- e1000_irq_disable(adapter);
-
- rmb();
-
- if (adapter->flags & FLAG_MSI_TEST_FAILED) {
- err = -EIO;
- e_info("MSI interrupt test failed!\n");
- }
-
- free_irq(adapter->pdev->irq, netdev);
- pci_disable_msi(adapter->pdev);
-
- if (err == -EIO)
- goto msi_test_failed;
-
- /* okay so the test worked, restore settings */
- e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
-msi_test_failed:
- /* restore the original vector, even if it failed */
- e1000_request_irq(adapter);
- return err;
-}
-
-/**
- * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
- * @adapter: board private struct
- *
- * code flow taken from tg3.c, called with e1000 interrupts disabled.
- **/
-static int e1000_test_msi(struct e1000_adapter *adapter)
-{
- int err;
- u16 pci_cmd;
-
- if (!(adapter->flags & FLAG_MSI_ENABLED))
- return 0;
-
- /* disable SERR in case the MSI write causes a master abort */
- pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
- pci_write_config_word(adapter->pdev, PCI_COMMAND,
- pci_cmd & ~PCI_COMMAND_SERR);
-
- err = e1000_test_msi_interrupt(adapter);
-
- /* restore previous setting of command word */
- pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
-
- /* success ! */
- if (!err)
- return 0;
-
- /* EIO means MSI test failed */
- if (err != -EIO)
- return err;
-
- /* back to INTx mode */
- e_warn("MSI interrupt test failed, using legacy interrupt.\n");
-
- e1000_free_irq(adapter);
-
- err = e1000_request_irq(adapter);
-
- return err;
-}
-
-/**
- * e1000_open - Called when a network interface is made active
- * @netdev: network interface device structure
- *
- * Returns 0 on success, negative value on failure
- *
- * The open entry point is called when a network interface is made
- * active by the system (IFF_UP). At this point all resources needed
- * for transmit and receive operations are allocated, the interrupt
- * handler is registered with the OS, the watchdog timer is started,
- * and the stack is notified that the interface is ready.
- **/
-static int e1000_open(struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- int err;
-
- /* disallow open during test */
- if (test_bit(__E1000_TESTING, &adapter->state))
- return -EBUSY;
-
- /* allocate transmit descriptors */
- err = e1000e_setup_tx_resources(adapter);
- if (err)
- goto err_setup_tx;
-
- /* allocate receive descriptors */
- err = e1000e_setup_rx_resources(adapter);
- if (err)
- goto err_setup_rx;
-
- e1000e_power_up_phy(adapter);
-
- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
- if ((adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
- e1000_update_mng_vlan(adapter);
-
- /*
- * If AMT is enabled, let the firmware know that the network
- * interface is now open
- */
- if (adapter->flags & FLAG_HAS_AMT)
- e1000_get_hw_control(adapter);
-
- /*
- * before we allocate an interrupt, we must be ready to handle it.
- * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
- * as soon as we call pci_request_irq, so we have to setup our
- * clean_rx handler before we do so.
- */
- e1000_configure(adapter);
-
- err = e1000_request_irq(adapter);
- if (err)
- goto err_req_irq;
-
- /*
- * Work around PCIe errata with MSI interrupts causing some chipsets to
- * ignore e1000e MSI messages, which means we need to test our MSI
- * interrupt now
- */
- {
- err = e1000_test_msi(adapter);
- if (err) {
- e_err("Interrupt allocation failed\n");
- goto err_req_irq;
- }
- }
-
- /* From here on the code is the same as e1000e_up() */
- clear_bit(__E1000_DOWN, &adapter->state);
-
- napi_enable(&adapter->napi);
-
- e1000_irq_enable(adapter);
-
- netif_tx_start_all_queues(netdev);
-
- /* fire a link status change interrupt to start the watchdog */
- ew32(ICS, E1000_ICS_LSC);
-
- return 0;
-
-err_req_irq:
- e1000_release_hw_control(adapter);
- e1000_power_down_phy(adapter);
- e1000e_free_rx_resources(adapter);
-err_setup_rx:
- e1000e_free_tx_resources(adapter);
-err_setup_tx:
- e1000e_reset(adapter);
-
- return err;
-}
-
-/**
- * e1000_close - Disables a network interface
- * @netdev: network interface device structure
- *
- * Returns 0, this is not allowed to fail
- *
- * The close entry point is called when an interface is de-activated
- * by the OS. The hardware is still under the drivers control, but
- * needs to be disabled. A global MAC reset is issued to stop the
- * hardware, and all transmit and receive resources are freed.
- **/
-static int e1000_close(struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
- e1000e_down(adapter);
- e1000_power_down_phy(adapter);
- e1000_free_irq(adapter);
-
- e1000e_free_tx_resources(adapter);
- e1000e_free_rx_resources(adapter);
-
- /*
- * kill manageability vlan ID if supported, but not if a vlan with
- * the same ID is registered on the host OS (let 8021q kill it)
- */
- if ((adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
- !(adapter->vlgrp &&
- vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
- e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
-
- /*
- * If AMT is enabled, let the firmware know that the network
- * interface is now closed
- */
- if (adapter->flags & FLAG_HAS_AMT)
- e1000_release_hw_control(adapter);
-
- return 0;
-}
-/**
- * e1000_set_mac - Change the Ethernet Address of the NIC
- * @netdev: network interface device structure
- * @p: pointer to an address structure
- *
- * Returns 0 on success, negative on failure
- **/
-static int e1000_set_mac(struct net_device *netdev, void *p)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct sockaddr *addr = p;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
-
- e1000e_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
-
- if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
- /* activate the work around */
- e1000e_set_laa_state_82571(&adapter->hw, 1);
-
- /*
- * Hold a copy of the LAA in RAR[14] This is done so that
- * between the time RAR[0] gets clobbered and the time it
- * gets fixed (in e1000_watchdog), the actual LAA is in one
- * of the RARs and no incoming packets directed to this port
- * are dropped. Eventually the LAA will be in RAR[0] and
- * RAR[14]
- */
- e1000e_rar_set(&adapter->hw,
- adapter->hw.mac.addr,
- adapter->hw.mac.rar_entry_count - 1);
- }
-
- return 0;
-}
-
-/**
- * e1000e_update_phy_task - work thread to update phy
- * @work: pointer to our work struct
- *
- * this worker thread exists because we must acquire a
- * semaphore to read the phy, which we could msleep while
- * waiting for it, and we can't msleep in a timer.
- **/
-static void e1000e_update_phy_task(struct work_struct *work)
-{
- struct e1000_adapter *adapter = container_of(work,
- struct e1000_adapter, update_phy_task);
- e1000_get_phy_info(&adapter->hw);
-}
-
-/*
- * Need to wait a few seconds after link up to get diagnostic information from
- * the phy
- */
-static void e1000_update_phy_info(unsigned long data)
-{
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
- schedule_work(&adapter->update_phy_task);
-}
-
-/**
- * e1000e_update_stats - Update the board statistics counters
- * @adapter: board private structure
- **/
-void e1000e_update_stats(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
-
- /*
- * Prevent stats update while adapter is being reset, or if the pci
- * connection is down.
- */
- if (adapter->link_speed == 0)
- return;
- if (pci_channel_offline(pdev))
- return;
-
- adapter->stats.crcerrs += er32(CRCERRS);
- adapter->stats.gprc += er32(GPRC);
- adapter->stats.gorc += er32(GORCL);
- er32(GORCH); /* Clear gorc */
- adapter->stats.bprc += er32(BPRC);
- adapter->stats.mprc += er32(MPRC);
- adapter->stats.roc += er32(ROC);
-
- adapter->stats.mpc += er32(MPC);
- adapter->stats.scc += er32(SCC);
- adapter->stats.ecol += er32(ECOL);
- adapter->stats.mcc += er32(MCC);
- adapter->stats.latecol += er32(LATECOL);
- adapter->stats.dc += er32(DC);
- adapter->stats.xonrxc += er32(XONRXC);
- adapter->stats.xontxc += er32(XONTXC);
- adapter->stats.xoffrxc += er32(XOFFRXC);
- adapter->stats.xofftxc += er32(XOFFTXC);
- adapter->stats.gptc += er32(GPTC);
- adapter->stats.gotc += er32(GOTCL);
- er32(GOTCH); /* Clear gotc */
- adapter->stats.rnbc += er32(RNBC);
- adapter->stats.ruc += er32(RUC);
-
- adapter->stats.mptc += er32(MPTC);
- adapter->stats.bptc += er32(BPTC);
-
- /* used for adaptive IFS */
-
- hw->mac.tx_packet_delta = er32(TPT);
- adapter->stats.tpt += hw->mac.tx_packet_delta;
- hw->mac.collision_delta = er32(COLC);
- adapter->stats.colc += hw->mac.collision_delta;
-
- adapter->stats.algnerrc += er32(ALGNERRC);
- adapter->stats.rxerrc += er32(RXERRC);
- adapter->stats.tncrs += er32(TNCRS);
- adapter->stats.cexterr += er32(CEXTERR);
- adapter->stats.tsctc += er32(TSCTC);
- adapter->stats.tsctfc += er32(TSCTFC);
-
- /* Fill out the OS statistics structure */
- adapter->net_stats.multicast = adapter->stats.mprc;
- adapter->net_stats.collisions = adapter->stats.colc;
-
- /* Rx Errors */
-
- /*
- * RLEC on some newer hardware can be incorrect so build
- * our own version based on RUC and ROC
- */
- adapter->net_stats.rx_errors = adapter->stats.rxerrc +
- adapter->stats.crcerrs + adapter->stats.algnerrc +
- adapter->stats.ruc + adapter->stats.roc +
- adapter->stats.cexterr;
- adapter->net_stats.rx_length_errors = adapter->stats.ruc +
- adapter->stats.roc;
- adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
- adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
- adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
-
- /* Tx Errors */
- adapter->net_stats.tx_errors = adapter->stats.ecol +
- adapter->stats.latecol;
- adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
- adapter->net_stats.tx_window_errors = adapter->stats.latecol;
- adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
-
- /* Tx Dropped needs to be maintained elsewhere */
-
- /* Management Stats */
- adapter->stats.mgptc += er32(MGTPTC);
- adapter->stats.mgprc += er32(MGTPRC);
- adapter->stats.mgpdc += er32(MGTPDC);
-}
-
-/**
- * e1000_phy_read_status - Update the PHY register status snapshot
- * @adapter: board private structure
- **/
-static void e1000_phy_read_status(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct e1000_phy_regs *phy = &adapter->phy_regs;
- int ret_val;
-
- if ((er32(STATUS) & E1000_STATUS_LU) &&
- (adapter->hw.phy.media_type == e1000_media_type_copper)) {
- ret_val = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
- ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
- ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
- ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa);
- ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion);
- ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000);
- ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
- ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
- if (ret_val)
- e_warn("Error reading PHY register\n");
- } else {
- /*
- * Do not read PHY registers if link is not up
- * Set values to typical power-on defaults
- */
- phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
- phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
- BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
- BMSR_ERCAP);
- phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
- ADVERTISE_ALL | ADVERTISE_CSMA);
- phy->lpa = 0;
- phy->expansion = EXPANSION_ENABLENPAGE;
- phy->ctrl1000 = ADVERTISE_1000FULL;
- phy->stat1000 = 0;
- phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
- }
-}
-
-static void e1000_print_link_info(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl = er32(CTRL);
-
- e_info("Link is Up %d Mbps %s, Flow Control: %s\n",
- adapter->link_speed,
- (adapter->link_duplex == FULL_DUPLEX) ?
- "Full Duplex" : "Half Duplex",
- ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
- "RX/TX" :
- ((ctrl & E1000_CTRL_RFCE) ? "RX" :
- ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
-}
-
-static bool e1000_has_link(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- bool link_active = 0;
- s32 ret_val = 0;
-
- /*
- * get_link_status is set on LSC (link status) interrupt or
- * Rx sequence error interrupt. get_link_status will stay
- * false until the check_for_link establishes link
- * for copper adapters ONLY
- */
- switch (hw->phy.media_type) {
- case e1000_media_type_copper:
- if (hw->mac.get_link_status) {
- ret_val = hw->mac.ops.check_for_link(hw);
- link_active = !hw->mac.get_link_status;
- } else {
- link_active = 1;
- }
- break;
- case e1000_media_type_fiber:
- ret_val = hw->mac.ops.check_for_link(hw);
- link_active = !!(er32(STATUS) & E1000_STATUS_LU);
- break;
- case e1000_media_type_internal_serdes:
- ret_val = hw->mac.ops.check_for_link(hw);
- link_active = adapter->hw.mac.serdes_has_link;
- break;
- default:
- case e1000_media_type_unknown:
- break;
- }
-
- if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
- (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
- /* See e1000_kmrn_lock_loss_workaround_ich8lan() */
- e_info("Gigabit has been disabled, downgrading speed\n");
- }
-
- return link_active;
-}
-
-static void e1000e_enable_receives(struct e1000_adapter *adapter)
-{
- /* make sure the receive unit is started */
- if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
- (adapter->flags & FLAG_RX_RESTART_NOW)) {
- struct e1000_hw *hw = &adapter->hw;
- u32 rctl = er32(RCTL);
- ew32(RCTL, rctl | E1000_RCTL_EN);
- adapter->flags &= ~FLAG_RX_RESTART_NOW;
- }
-}
-
-/**
- * e1000_watchdog - Timer Call-back
- * @data: pointer to adapter cast into an unsigned long
- **/
-static void e1000_watchdog(unsigned long data)
-{
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
-
- /* Do the rest outside of interrupt context */
- schedule_work(&adapter->watchdog_task);
-
- /* TODO: make this use queue_delayed_work() */
-}
-
-static void e1000_watchdog_task(struct work_struct *work)
-{
- struct e1000_adapter *adapter = container_of(work,
- struct e1000_adapter, watchdog_task);
- struct net_device *netdev = adapter->netdev;
- struct e1000_mac_info *mac = &adapter->hw.mac;
- struct e1000_ring *tx_ring = adapter->tx_ring;
- struct e1000_hw *hw = &adapter->hw;
- u32 link, tctl;
- int tx_pending = 0;
-
- link = e1000_has_link(adapter);
- if ((netif_carrier_ok(netdev)) && link) {
- e1000e_enable_receives(adapter);
- goto link_up;
- }
-
- if ((e1000e_enable_tx_pkt_filtering(hw)) &&
- (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
- e1000_update_mng_vlan(adapter);
-
- if (link) {
- if (!netif_carrier_ok(netdev)) {
- bool txb2b = 1;
- /* update snapshot of PHY registers on LSC */
- e1000_phy_read_status(adapter);
- mac->ops.get_link_up_info(&adapter->hw,
- &adapter->link_speed,
- &adapter->link_duplex);
- e1000_print_link_info(adapter);
- /*
- * tweak tx_queue_len according to speed/duplex
- * and adjust the timeout factor
- */
- netdev->tx_queue_len = adapter->tx_queue_len;
- adapter->tx_timeout_factor = 1;
- switch (adapter->link_speed) {
- case SPEED_10:
- txb2b = 0;
- netdev->tx_queue_len = 10;
- adapter->tx_timeout_factor = 16;
- break;
- case SPEED_100:
- txb2b = 0;
- netdev->tx_queue_len = 100;
- /* maybe add some timeout factor ? */
- break;
- }
-
- /*
- * workaround: re-program speed mode bit after
- * link-up event
- */
- if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
- !txb2b) {
- u32 tarc0;
- tarc0 = er32(TARC(0));
- tarc0 &= ~SPEED_MODE_BIT;
- ew32(TARC(0), tarc0);
- }
-
- /*
- * disable TSO for pcie and 10/100 speeds, to avoid
- * some hardware issues
- */
- if (!(adapter->flags & FLAG_TSO_FORCE)) {
- switch (adapter->link_speed) {
- case SPEED_10:
- case SPEED_100:
- e_info("10/100 speed: disabling TSO\n");
- netdev->features &= ~NETIF_F_TSO;
- netdev->features &= ~NETIF_F_TSO6;
- break;
- case SPEED_1000:
- netdev->features |= NETIF_F_TSO;
- netdev->features |= NETIF_F_TSO6;
- break;
- default:
- /* oops */
- break;
- }
- }
-
- /*
- * enable transmits in the hardware, need to do this
- * after setting TARC(0)
- */
- tctl = er32(TCTL);
- tctl |= E1000_TCTL_EN;
- ew32(TCTL, tctl);
-
- netif_carrier_on(netdev);
- netif_tx_wake_all_queues(netdev);
-
- if (!test_bit(__E1000_DOWN, &adapter->state))
- mod_timer(&adapter->phy_info_timer,
- round_jiffies(jiffies + 2 * HZ));
- }
- } else {
- if (netif_carrier_ok(netdev)) {
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
- e_info("Link is Down\n");
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
- if (!test_bit(__E1000_DOWN, &adapter->state))
- mod_timer(&adapter->phy_info_timer,
- round_jiffies(jiffies + 2 * HZ));
-
- if (adapter->flags & FLAG_RX_NEEDS_RESTART)
- schedule_work(&adapter->reset_task);
- }
- }
-
-link_up:
- e1000e_update_stats(adapter);
-
- mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
- adapter->tpt_old = adapter->stats.tpt;
- mac->collision_delta = adapter->stats.colc - adapter->colc_old;
- adapter->colc_old = adapter->stats.colc;
-
- adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
- adapter->gorc_old = adapter->stats.gorc;
- adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
- adapter->gotc_old = adapter->stats.gotc;
-
- e1000e_update_adaptive(&adapter->hw);
-
- if (!netif_carrier_ok(netdev)) {
- tx_pending = (e1000_desc_unused(tx_ring) + 1 <
- tx_ring->count);
- if (tx_pending) {
- /*
- * We've lost link, so the controller stops DMA,
- * but we've got queued Tx work that's never going
- * to get done, so reset controller to flush Tx.
- * (Do the reset outside of interrupt context).
- */
- adapter->tx_timeout_count++;
- schedule_work(&adapter->reset_task);
- }
- }
-
- /* Cause software interrupt to ensure Rx ring is cleaned */
- ew32(ICS, E1000_ICS_RXDMT0);
-
- /* Force detection of hung controller every watchdog period */
- adapter->detect_tx_hung = 1;
-
- /*
- * With 82571 controllers, LAA may be overwritten due to controller
- * reset from the other port. Set the appropriate LAA in RAR[0]
- */
- if (e1000e_get_laa_state_82571(hw))
- e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
-
- /* Reset the timer */
- if (!test_bit(__E1000_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer,
- round_jiffies(jiffies + 2 * HZ));
-}
-
-#define E1000_TX_FLAGS_CSUM 0x00000001
-#define E1000_TX_FLAGS_VLAN 0x00000002
-#define E1000_TX_FLAGS_TSO 0x00000004
-#define E1000_TX_FLAGS_IPV4 0x00000008
-#define E1000_TX_FLAGS_VLAN_MASK 0xffff0000
-#define E1000_TX_FLAGS_VLAN_SHIFT 16
-
-static int e1000_tso(struct e1000_adapter *adapter,
- struct sk_buff *skb)
-{
- struct e1000_ring *tx_ring = adapter->tx_ring;
- struct e1000_context_desc *context_desc;
- struct e1000_buffer *buffer_info;
- unsigned int i;
- u32 cmd_length = 0;
- u16 ipcse = 0, tucse, mss;
- u8 ipcss, ipcso, tucss, tucso, hdr_len;
- int err;
-
- if (skb_is_gso(skb)) {
- if (skb_header_cloned(skb)) {
- err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
- if (err)
- return err;
- }
-
- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- mss = skb_shinfo(skb)->gso_size;
- if (skb->protocol == htons(ETH_P_IP)) {
- struct iphdr *iph = ip_hdr(skb);
- iph->tot_len = 0;
- iph->check = 0;
- tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
- cmd_length = E1000_TXD_CMD_IP;
- ipcse = skb_transport_offset(skb) - 1;
- } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
- ipv6_hdr(skb)->payload_len = 0;
- tcp_hdr(skb)->check =
- ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0);
- ipcse = 0;
- }
- ipcss = skb_network_offset(skb);
- ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
- tucss = skb_transport_offset(skb);
- tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
- tucse = 0;
-
- cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
- E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
-
- i = tx_ring->next_to_use;
- context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
- buffer_info = &tx_ring->buffer_info[i];
-
- context_desc->lower_setup.ip_fields.ipcss = ipcss;
- context_desc->lower_setup.ip_fields.ipcso = ipcso;
- context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse);
- context_desc->upper_setup.tcp_fields.tucss = tucss;
- context_desc->upper_setup.tcp_fields.tucso = tucso;
- context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
- context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss);
- context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
- context_desc->cmd_and_length = cpu_to_le32(cmd_length);
-
- buffer_info->time_stamp = jiffies;
- buffer_info->next_to_watch = i;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
- tx_ring->next_to_use = i;
-
- return 1;
- }
-
- return 0;
-}
-
-static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
-{
- struct e1000_ring *tx_ring = adapter->tx_ring;
- struct e1000_context_desc *context_desc;
- struct e1000_buffer *buffer_info;
- unsigned int i;
- u8 css;
-
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- css = skb_transport_offset(skb);
-
- i = tx_ring->next_to_use;
- buffer_info = &tx_ring->buffer_info[i];
- context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
-
- context_desc->lower_setup.ip_config = 0;
- context_desc->upper_setup.tcp_fields.tucss = css;
- context_desc->upper_setup.tcp_fields.tucso =
- css + skb->csum_offset;
- context_desc->upper_setup.tcp_fields.tucse = 0;
- context_desc->tcp_seg_setup.data = 0;
- context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
-
- buffer_info->time_stamp = jiffies;
- buffer_info->next_to_watch = i;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
- tx_ring->next_to_use = i;
-
- return 1;
- }
-
- return 0;
-}
-
-#define E1000_MAX_PER_TXD 8192
-#define E1000_MAX_TXD_PWR 12
-
-static int e1000_tx_map(struct e1000_adapter *adapter,
- struct sk_buff *skb, unsigned int first,
- unsigned int max_per_txd, unsigned int nr_frags,
- unsigned int mss)
-{
- struct e1000_ring *tx_ring = adapter->tx_ring;
- struct e1000_buffer *buffer_info;
- unsigned int len = skb->len - skb->data_len;
- unsigned int offset = 0, size, count = 0, i;
- unsigned int f;
-
- i = tx_ring->next_to_use;
-
- while (len) {
- buffer_info = &tx_ring->buffer_info[i];
- size = min(len, max_per_txd);
-
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
- if (mss && !nr_frags && size == len && size > 8)
- size -= 4;
-
- buffer_info->length = size;
- /* set time_stamp *before* dma to help avoid a possible race */
- buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_single(adapter->pdev,
- skb->data + offset,
- size,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) {
- dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
- adapter->tx_dma_failed++;
- return -1;
- }
- buffer_info->next_to_watch = i;
-
- len -= size;
- offset += size;
- count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
- }
-
- for (f = 0; f < nr_frags; f++) {
- struct skb_frag_struct *frag;
-
- frag = &skb_shinfo(skb)->frags[f];
- len = frag->size;
- offset = frag->page_offset;
-
- while (len) {
- buffer_info = &tx_ring->buffer_info[i];
- size = min(len, max_per_txd);
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
- if (mss && f == (nr_frags-1) && size == len && size > 8)
- size -= 4;
-
- buffer_info->length = size;
- buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(adapter->pdev,
- buffer_info->dma)) {
- dev_err(&adapter->pdev->dev,
- "TX DMA page map failed\n");
- adapter->tx_dma_failed++;
- return -1;
- }
-
- buffer_info->next_to_watch = i;
-
- len -= size;
- offset += size;
- count++;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
- }
- }
-
- if (i == 0)
- i = tx_ring->count - 1;
- else
- i--;
-
- tx_ring->buffer_info[i].skb = skb;
- tx_ring->buffer_info[first].next_to_watch = i;
-
- return count;
-}
-
-static void e1000_tx_queue(struct e1000_adapter *adapter,
- int tx_flags, int count)
-{
- struct e1000_ring *tx_ring = adapter->tx_ring;
- struct e1000_tx_desc *tx_desc = NULL;
- struct e1000_buffer *buffer_info;
- u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
- unsigned int i;
-
- if (tx_flags & E1000_TX_FLAGS_TSO) {
- txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
- E1000_TXD_CMD_TSE;
- txd_upper |= E1000_TXD_POPTS_TXSM << 8;
-
- if (tx_flags & E1000_TX_FLAGS_IPV4)
- txd_upper |= E1000_TXD_POPTS_IXSM << 8;
- }
-
- if (tx_flags & E1000_TX_FLAGS_CSUM) {
- txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
- txd_upper |= E1000_TXD_POPTS_TXSM << 8;
- }
-
- if (tx_flags & E1000_TX_FLAGS_VLAN) {
- txd_lower |= E1000_TXD_CMD_VLE;
- txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
- }
-
- i = tx_ring->next_to_use;
-
- while (count--) {
- buffer_info = &tx_ring->buffer_info[i];
- tx_desc = E1000_TX_DESC(*tx_ring, i);
- tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
- tx_desc->lower.data =
- cpu_to_le32(txd_lower | buffer_info->length);
- tx_desc->upper.data = cpu_to_le32(txd_upper);
-
- i++;
- if (i == tx_ring->count)
- i = 0;
- }
-
- tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
-
- /*
- * Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64).
- */
- wmb();
-
- tx_ring->next_to_use = i;
- writel(i, adapter->hw.hw_addr + tx_ring->tail);
- /*
- * we need this if more than one processor can write to our tail
- * at a time, it synchronizes IO on IA64/Altix systems
- */
- mmiowb();
-}
-
-#define MINIMUM_DHCP_PACKET_SIZE 282
-static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
- struct sk_buff *skb)
-{
- struct e1000_hw *hw = &adapter->hw;
- u16 length, offset;
-
- if (vlan_tx_tag_present(skb)) {
- if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id)
- && (adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
- return 0;
- }
-
- if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
- return 0;
-
- if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP))
- return 0;
-
- {
- const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
- struct udphdr *udp;
-
- if (ip->protocol != IPPROTO_UDP)
- return 0;
-
- udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
- if (ntohs(udp->dest) != 67)
- return 0;
-
- offset = (u8 *)udp + 8 - skb->data;
- length = skb->len - offset;
- return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
- }
-
- return 0;
-}
-
-static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- netif_stop_queue(netdev);
- /*
- * Herbert's original patch had:
- * smp_mb__after_netif_stop_queue();
- * but since that doesn't exist yet, just open code it.
- */
- smp_mb();
-
- /*
- * We need to check again in a case another CPU has just
- * made room available.
- */
- if (e1000_desc_unused(adapter->tx_ring) < size)
- return -EBUSY;
-
- /* A reprieve! */
- netif_start_queue(netdev);
- ++adapter->restart_queue;
- return 0;
-}
-
-static int e1000_maybe_stop_tx(struct net_device *netdev, int size)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- if (e1000_desc_unused(adapter->tx_ring) >= size)
- return 0;
- return __e1000_maybe_stop_tx(netdev, size);
-}
-
-#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
-static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_ring *tx_ring = adapter->tx_ring;
- unsigned int first;
- unsigned int max_per_txd = E1000_MAX_PER_TXD;
- unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
- unsigned int tx_flags = 0;
- unsigned int len = skb->len - skb->data_len;
- unsigned long irq_flags;
- unsigned int nr_frags;
- unsigned int mss;
- int count = 0;
- int tso;
- unsigned int f;
-
- if (test_bit(__E1000_DOWN, &adapter->state)) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- if (skb->len <= 0) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- mss = skb_shinfo(skb)->gso_size;
- /*
- * The controller does a simple calculation to
- * make sure there is enough room in the FIFO before
- * initiating the DMA for each buffer. The calc is:
- * 4 = ceil(buffer len/mss). To make sure we don't
- * overrun the FIFO, adjust the max buffer len if mss
- * drops.
- */
- if (mss) {
- u8 hdr_len;
- max_per_txd = min(mss << 2, max_per_txd);
- max_txd_pwr = fls(max_per_txd) - 1;
-
- /*
- * TSO Workaround for 82571/2/3 Controllers -- if skb->data
- * points to just header, pull a few bytes of payload from
- * frags into skb->data
- */
- hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- /*
- * we do this workaround for ES2LAN, but it is un-necessary,
- * avoiding it could save a lot of cycles
- */
- if (skb->data_len && (hdr_len == len)) {
- unsigned int pull_size;
-
- pull_size = min((unsigned int)4, skb->data_len);
- if (!__pskb_pull_tail(skb, pull_size)) {
- e_err("__pskb_pull_tail failed.\n");
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
- len = skb->len - skb->data_len;
- }
- }
-
- /* reserve a descriptor for the offload context */
- if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
- count++;
- count++;
-
- count += TXD_USE_COUNT(len, max_txd_pwr);
-
- nr_frags = skb_shinfo(skb)->nr_frags;
- for (f = 0; f < nr_frags; f++)
- count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
- max_txd_pwr);
-
- if (adapter->hw.mac.tx_pkt_filtering)
- e1000_transfer_dhcp_info(adapter, skb);
-
- if (!spin_trylock_irqsave(&adapter->tx_queue_lock, irq_flags))
- /* Collision - tell upper layer to requeue */
- return NETDEV_TX_LOCKED;
-
- /*
- * need: count + 2 desc gap to keep tail from touching
- * head, otherwise try next time
- */
- if (e1000_maybe_stop_tx(netdev, count + 2)) {
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
- return NETDEV_TX_BUSY;
- }
-
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
- tx_flags |= E1000_TX_FLAGS_VLAN;
- tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
- }
-
- first = tx_ring->next_to_use;
-
- tso = e1000_tso(adapter, skb);
- if (tso < 0) {
- dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
- return NETDEV_TX_OK;
- }
-
- if (tso)
- tx_flags |= E1000_TX_FLAGS_TSO;
- else if (e1000_tx_csum(adapter, skb))
- tx_flags |= E1000_TX_FLAGS_CSUM;
-
- /*
- * Old method was to assume IPv4 packet by default if TSO was enabled.
- * 82571 hardware supports TSO capabilities for IPv6 as well...
- * no longer assume, we must.
- */
- if (skb->protocol == htons(ETH_P_IP))
- tx_flags |= E1000_TX_FLAGS_IPV4;
-
- count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
- if (count < 0) {
- /* handle pci_map_single() error in e1000_tx_map */
- dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
- return NETDEV_TX_OK;
- }
-
- e1000_tx_queue(adapter, tx_flags, count);
-
- netdev->trans_start = jiffies;
-
- /* Make sure there is space in the ring for the next send. */
- e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
-
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
- return NETDEV_TX_OK;
-}
-
-/**
- * e1000_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- **/
-static void e1000_tx_timeout(struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- /* Do the reset outside of interrupt context */
- adapter->tx_timeout_count++;
- schedule_work(&adapter->reset_task);
-}
-
-static void e1000_reset_task(struct work_struct *work)
-{
- struct e1000_adapter *adapter;
- adapter = container_of(work, struct e1000_adapter, reset_task);
-
- e1000e_reinit_locked(adapter);
-}
-
-/**
- * e1000_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- **/
-static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- /* only return the current stats */
- return &adapter->net_stats;
-}
-
-/**
- * e1000_change_mtu - Change the Maximum Transfer Unit
- * @netdev: network interface device structure
- * @new_mtu: new value for maximum frame size
- *
- * Returns 0 on success, negative on failure
- **/
-static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
-
- if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
- (max_frame > MAX_JUMBO_FRAME_SIZE)) {
- e_err("Invalid MTU setting\n");
- return -EINVAL;
- }
-
- /* Jumbo frame size limits */
- if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
- if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
- e_err("Jumbo Frames not supported.\n");
- return -EINVAL;
- }
- if (adapter->hw.phy.type == e1000_phy_ife) {
- e_err("Jumbo Frames not supported.\n");
- return -EINVAL;
- }
- }
-
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
- if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
- e_err("MTU > 9216 not supported.\n");
- return -EINVAL;
- }
-
- while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
- /* e1000e_down has a dependency on max_frame_size */
- adapter->max_frame_size = max_frame;
- if (netif_running(netdev))
- e1000e_down(adapter);
-
- /*
- * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
- * means we reserve 2 more, this pushes us to allocate from the next
- * larger slab size.
- * i.e. RXBUFFER_2048 --> size-4096 slab
- * However with the new *_jumbo_rx* routines, jumbo receives will use
- * fragmented skbs
- */
-
- if (max_frame <= 256)
- adapter->rx_buffer_len = 256;
- else if (max_frame <= 512)
- adapter->rx_buffer_len = 512;
- else if (max_frame <= 1024)
- adapter->rx_buffer_len = 1024;
- else if (max_frame <= 2048)
- adapter->rx_buffer_len = 2048;
- else
- adapter->rx_buffer_len = 4096;
-
- /* adjust allocation if LPE protects us, and we aren't using SBP */
- if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
- (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
- adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
- + ETH_FCS_LEN;
-
- e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
- netdev->mtu = new_mtu;
-
- if (netif_running(netdev))
- e1000e_up(adapter);
- else
- e1000e_reset(adapter);
-
- clear_bit(__E1000_RESETTING, &adapter->state);
-
- return 0;
-}
-
-static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
- int cmd)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct mii_ioctl_data *data = if_mii(ifr);
-
- if (adapter->hw.phy.media_type != e1000_media_type_copper)
- return -EOPNOTSUPP;
-
- switch (cmd) {
- case SIOCGMIIPHY:
- data->phy_id = adapter->hw.phy.addr;
- break;
- case SIOCGMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- switch (data->reg_num & 0x1F) {
- case MII_BMCR:
- data->val_out = adapter->phy_regs.bmcr;
- break;
- case MII_BMSR:
- data->val_out = adapter->phy_regs.bmsr;
- break;
- case MII_PHYSID1:
- data->val_out = (adapter->hw.phy.id >> 16);
- break;
- case MII_PHYSID2:
- data->val_out = (adapter->hw.phy.id & 0xFFFF);
- break;
- case MII_ADVERTISE:
- data->val_out = adapter->phy_regs.advertise;
- break;
- case MII_LPA:
- data->val_out = adapter->phy_regs.lpa;
- break;
- case MII_EXPANSION:
- data->val_out = adapter->phy_regs.expansion;
- break;
- case MII_CTRL1000:
- data->val_out = adapter->phy_regs.ctrl1000;
- break;
- case MII_STAT1000:
- data->val_out = adapter->phy_regs.stat1000;
- break;
- case MII_ESTATUS:
- data->val_out = adapter->phy_regs.estatus;
- break;
- default:
- return -EIO;
- }
- break;
- case SIOCSMIIREG:
- default:
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
- switch (cmd) {
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
- return e1000_mii_ioctl(netdev, ifr, cmd);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, ctrl_ext, rctl, status;
- u32 wufc = adapter->wol;
- int retval = 0;
-
- netif_device_detach(netdev);
-
- if (netif_running(netdev)) {
- WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
- e1000e_down(adapter);
- e1000_free_irq(adapter);
- }
-
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
- status = er32(STATUS);
- if (status & E1000_STATUS_LU)
- wufc &= ~E1000_WUFC_LNKC;
-
- if (wufc) {
- e1000_setup_rctl(adapter);
- e1000_set_multi(netdev);
-
- /* turn on all-multi mode if wake on multicast is enabled */
- if (wufc & E1000_WUFC_MC) {
- rctl = er32(RCTL);
- rctl |= E1000_RCTL_MPE;
- ew32(RCTL, rctl);
- }
-
- ctrl = er32(CTRL);
- /* advertise wake from D3Cold */
- #define E1000_CTRL_ADVD3WUC 0x00100000
- /* phy power management enable */
- #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
- ctrl |= E1000_CTRL_ADVD3WUC |
- E1000_CTRL_EN_PHY_PWR_MGMT;
- ew32(CTRL, ctrl);
-
- if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
- adapter->hw.phy.media_type ==
- e1000_media_type_internal_serdes) {
- /* keep the laser running in D3 */
- ctrl_ext = er32(CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
- ew32(CTRL_EXT, ctrl_ext);
- }
-
- if (adapter->flags & FLAG_IS_ICH)
- e1000e_disable_gig_wol_ich8lan(&adapter->hw);
-
- /* Allow time for pending master requests to run */
- e1000e_disable_pcie_master(&adapter->hw);
-
- ew32(WUC, E1000_WUC_PME_EN);
- ew32(WUFC, wufc);
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
- } else {
- ew32(WUC, 0);
- ew32(WUFC, 0);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
- }
-
- /* make sure adapter isn't asleep if manageability is enabled */
- if (adapter->flags & FLAG_MNG_PT_ENABLED) {
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
- }
-
- if (adapter->hw.phy.type == e1000_phy_igp_3)
- e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
-
- /*
- * Release control of h/w to f/w. If f/w is AMT enabled, this
- * would have already happened in close and is redundant.
- */
- e1000_release_hw_control(adapter);
-
- pci_disable_device(pdev);
-
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static void e1000e_disable_l1aspm(struct pci_dev *pdev)
-{
- int pos;
- u16 val;
-
- /*
- * 82573 workaround - disable L1 ASPM on mobile chipsets
- *
- * L1 ASPM on various mobile (ich7) chipsets do not behave properly
- * resulting in lost data or garbage information on the pci-e link
- * level. This could result in (false) bad EEPROM checksum errors,
- * long ping times (up to 2s) or even a system freeze/hang.
- *
- * Unfortunately this feature saves about 1W power consumption when
- * active.
- */
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
- if (val & 0x2) {
- dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
- val &= ~0x2;
- pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
- }
-}
-
-#ifdef CONFIG_PM
-static int e1000_resume(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- u32 err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- e1000e_disable_l1aspm(pdev);
-
- err = pci_enable_device_mem(pdev);
- if (err) {
- dev_err(&pdev->dev,
- "Cannot enable PCI device from suspend\n");
- return err;
- }
-
- pci_set_master(pdev);
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- if (netif_running(netdev)) {
- err = e1000_request_irq(adapter);
- if (err)
- return err;
- }
-
- e1000e_power_up_phy(adapter);
- e1000e_reset(adapter);
- ew32(WUS, ~0);
-
- e1000_init_manageability(adapter);
-
- if (netif_running(netdev))
- e1000e_up(adapter);
-
- netif_device_attach(netdev);
-
- /*
- * If the controller has AMT, do not set DRV_LOAD until the interface
- * is up. For all other cases, let the f/w know that the h/w is now
- * under the control of the driver.
- */
- if (!(adapter->flags & FLAG_HAS_AMT))
- e1000_get_hw_control(adapter);
-
- return 0;
-}
-#endif
-
-static void e1000_shutdown(struct pci_dev *pdev)
-{
- e1000_suspend(pdev, PMSG_SUSPEND);
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void e1000_netpoll(struct net_device *netdev)
-{
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- disable_irq(adapter->pdev->irq);
- e1000_intr(adapter->pdev->irq, netdev);
-
- enable_irq(adapter->pdev->irq);
-}
-#endif
-
-/**
- * e1000_io_error_detected - called when PCI error is detected
- * @pdev: Pointer to PCI device
- * @state: The current pci connection state
- *
- * This function is called after a PCI bus error affecting
- * this device has been detected.
- */
-static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- netif_device_detach(netdev);
-
- if (netif_running(netdev))
- e1000e_down(adapter);
- pci_disable_device(pdev);
-
- /* Request a slot slot reset. */
- return PCI_ERS_RESULT_NEED_RESET;
-}
-
-/**
- * e1000_io_slot_reset - called after the pci bus has been reset.
- * @pdev: Pointer to PCI device
- *
- * Restart the card from scratch, as if from a cold-boot. Implementation
- * resembles the first-half of the e1000_resume routine.
- */
-static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- int err;
-
- e1000e_disable_l1aspm(pdev);
- err = pci_enable_device_mem(pdev);
- if (err) {
- dev_err(&pdev->dev,
- "Cannot re-enable PCI device after reset.\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
- pci_set_master(pdev);
- pci_restore_state(pdev);
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
-
- e1000e_reset(adapter);
- ew32(WUS, ~0);
-
- return PCI_ERS_RESULT_RECOVERED;
-}
-
-/**
- * e1000_io_resume - called when traffic can start flowing again.
- * @pdev: Pointer to PCI device
- *
- * This callback is called when the error recovery driver tells us that
- * its OK to resume normal operation. Implementation resembles the
- * second-half of the e1000_resume routine.
- */
-static void e1000_io_resume(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- e1000_init_manageability(adapter);
-
- if (netif_running(netdev)) {
- if (e1000e_up(adapter)) {
- dev_err(&pdev->dev,
- "can't bring device back up after reset\n");
- return;
- }
- }
-
- netif_device_attach(netdev);
-
- /*
- * If the controller has AMT, do not set DRV_LOAD until the interface
- * is up. For all other cases, let the f/w know that the h/w is now
- * under the control of the driver.
- */
- if (!(adapter->flags & FLAG_HAS_AMT))
- e1000_get_hw_control(adapter);
-
-}
-
-static void e1000_print_device_info(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- u32 pba_num;
-
- /* print bus type/speed/width info */
- e_info("(PCI Express:2.5GB/s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
- /* bus width */
- ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
- "Width x1"),
- /* MAC address */
- netdev->dev_addr[0], netdev->dev_addr[1],
- netdev->dev_addr[2], netdev->dev_addr[3],
- netdev->dev_addr[4], netdev->dev_addr[5]);
- e_info("Intel(R) PRO/%s Network Connection\n",
- (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
- e1000e_read_pba_num(hw, &pba_num);
- e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
- hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));
-}
-
-static void e1000_eeprom_checks(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int ret_val;
- u16 buf = 0;
-
- if (hw->mac.type != e1000_82573)
- return;
-
- ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
- if (!(le16_to_cpu(buf) & (1 << 0))) {
- /* Deep Smart Power Down (DSPD) */
- e_warn("Warning: detected DSPD enabled in EEPROM\n");
- }
-
- ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
- if (le16_to_cpu(buf) & (3 << 2)) {
- /* ASPM enable */
- e_warn("Warning: detected ASPM enabled in EEPROM\n");
- }
-}
-
-/**
- * e1000_probe - Device Initialization Routine
- * @pdev: PCI device information struct
- * @ent: entry in e1000_pci_tbl
- *
- * Returns 0 on success, negative on failure
- *
- * e1000_probe initializes an adapter identified by a pci_dev structure.
- * The OS initialization, configuring of the adapter private structure,
- * and a hardware reset occur.
- **/
-static int __devinit e1000_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct net_device *netdev;
- struct e1000_adapter *adapter;
- struct e1000_hw *hw;
- const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
- resource_size_t mmio_start, mmio_len;
- resource_size_t flash_start, flash_len;
-
- static int cards_found;
- int i, err, pci_using_dac;
- u16 eeprom_data = 0;
- u16 eeprom_apme_mask = E1000_EEPROM_APME;
-
- e1000e_disable_l1aspm(pdev);
-
- err = pci_enable_device_mem(pdev);
- if (err)
- return err;
-
- pci_using_dac = 0;
- err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
- if (!err) {
- err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
- if (!err)
- pci_using_dac = 1;
- } else {
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (err) {
- err = pci_set_consistent_dma_mask(pdev,
- DMA_32BIT_MASK);
- if (err) {
- dev_err(&pdev->dev, "No usable DMA "
- "configuration, aborting\n");
- goto err_dma;
- }
- }
- }
-
- err = pci_request_selected_regions(pdev,
- pci_select_bars(pdev, IORESOURCE_MEM),
- e1000e_driver_name);
- if (err)
- goto err_pci_reg;
-
- pci_set_master(pdev);
- pci_save_state(pdev);
-
- err = -ENOMEM;
- netdev = alloc_etherdev(sizeof(struct e1000_adapter));
- if (!netdev)
- goto err_alloc_etherdev;
-
- SET_NETDEV_DEV(netdev, &pdev->dev);
-
- pci_set_drvdata(pdev, netdev);
- adapter = netdev_priv(netdev);
- hw = &adapter->hw;
- adapter->netdev = netdev;
- adapter->pdev = pdev;
- adapter->ei = ei;
- adapter->pba = ei->pba;
- adapter->flags = ei->flags;
- adapter->hw.adapter = adapter;
- adapter->hw.mac.type = ei->mac;
- adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
-
- mmio_start = pci_resource_start(pdev, 0);
- mmio_len = pci_resource_len(pdev, 0);
-
- err = -EIO;
- adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
- if (!adapter->hw.hw_addr)
- goto err_ioremap;
-
- if ((adapter->flags & FLAG_HAS_FLASH) &&
- (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
- flash_start = pci_resource_start(pdev, 1);
- flash_len = pci_resource_len(pdev, 1);
- adapter->hw.flash_address = ioremap(flash_start, flash_len);
- if (!adapter->hw.flash_address)
- goto err_flashmap;
- }
-
- /* construct the net_device struct */
- netdev->open = &e1000_open;
- netdev->stop = &e1000_close;
- netdev->hard_start_xmit = &e1000_xmit_frame;
- netdev->get_stats = &e1000_get_stats;
- netdev->set_multicast_list = &e1000_set_multi;
- netdev->set_mac_address = &e1000_set_mac;
- netdev->change_mtu = &e1000_change_mtu;
- netdev->do_ioctl = &e1000_ioctl;
- e1000e_set_ethtool_ops(netdev);
- netdev->tx_timeout = &e1000_tx_timeout;
- netdev->watchdog_timeo = 5 * HZ;
- netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
- netdev->vlan_rx_register = e1000_vlan_rx_register;
- netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = e1000_netpoll;
-#endif
- strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
-
- netdev->mem_start = mmio_start;
- netdev->mem_end = mmio_start + mmio_len;
-
- adapter->bd_number = cards_found++;
-
- e1000e_check_options(adapter);
-
- /* setup adapter struct */
- err = e1000_sw_init(adapter);
- if (err)
- goto err_sw_init;
-
- err = -EIO;
-
- memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
- memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
- memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
-
- err = ei->get_variants(adapter);
- if (err)
- goto err_hw_init;
-
- if ((adapter->flags & FLAG_IS_ICH) &&
- (adapter->flags & FLAG_READ_ONLY_NVM))
- e1000e_write_protect_nvm_ich8lan(&adapter->hw);
-
- hw->mac.ops.get_bus_info(&adapter->hw);
-
- adapter->hw.phy.autoneg_wait_to_complete = 0;
-
- /* Copper options */
- if (adapter->hw.phy.media_type == e1000_media_type_copper) {
- adapter->hw.phy.mdix = AUTO_ALL_MODES;
- adapter->hw.phy.disable_polarity_correction = 0;
- adapter->hw.phy.ms_type = e1000_ms_hw_default;
- }
-
- if (e1000_check_reset_block(&adapter->hw))
- e_info("PHY reset is blocked due to SOL/IDER session.\n");
-
- netdev->features = NETIF_F_SG |
- NETIF_F_HW_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX;
-
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
- netdev->features |= NETIF_F_HW_VLAN_FILTER;
-
- netdev->features |= NETIF_F_TSO;
- netdev->features |= NETIF_F_TSO6;
-
- netdev->vlan_features |= NETIF_F_TSO;
- netdev->vlan_features |= NETIF_F_TSO6;
- netdev->vlan_features |= NETIF_F_HW_CSUM;
- netdev->vlan_features |= NETIF_F_SG;
-
- if (pci_using_dac)
- netdev->features |= NETIF_F_HIGHDMA;
-
- /*
- * We should not be using LLTX anymore, but we are still Tx faster with
- * it.
- */
- netdev->features |= NETIF_F_LLTX;
-
- if (e1000e_enable_mng_pass_thru(&adapter->hw))
- adapter->flags |= FLAG_MNG_PT_ENABLED;
-
- /*
- * before reading the NVM, reset the controller to
- * put the device in a known good starting state
- */
- adapter->hw.mac.ops.reset_hw(&adapter->hw);
-
- /*
- * systems with ASPM and others may see the checksum fail on the first
- * attempt. Let's give it a few tries
- */
- for (i = 0;; i++) {
- if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
- break;
- if (i == 2) {
- e_err("The NVM Checksum Is Not Valid\n");
- err = -EIO;
- goto err_eeprom;
- }
- }
-
- e1000_eeprom_checks(adapter);
-
- /* copy the MAC address out of the NVM */
- if (e1000e_read_mac_addr(&adapter->hw))
- e_err("NVM Read Error while reading MAC address\n");
-
- memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
- memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
-
- if (!is_valid_ether_addr(netdev->perm_addr)) {
- e_err("Invalid MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
- netdev->perm_addr[0], netdev->perm_addr[1],
- netdev->perm_addr[2], netdev->perm_addr[3],
- netdev->perm_addr[4], netdev->perm_addr[5]);
- err = -EIO;
- goto err_eeprom;
- }
-
- init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &e1000_watchdog;
- adapter->watchdog_timer.data = (unsigned long) adapter;
-
- init_timer(&adapter->phy_info_timer);
- adapter->phy_info_timer.function = &e1000_update_phy_info;
- adapter->phy_info_timer.data = (unsigned long) adapter;
-
- INIT_WORK(&adapter->reset_task, e1000_reset_task);
- INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
- INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
- INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
-
- /* Initialize link parameters. User can change them with ethtool */
- adapter->hw.mac.autoneg = 1;
- adapter->fc_autoneg = 1;
- adapter->hw.fc.original_type = e1000_fc_default;
- adapter->hw.fc.type = e1000_fc_default;
- adapter->hw.phy.autoneg_advertised = 0x2f;
-
- /* ring size defaults */
- adapter->rx_ring->count = 256;
- adapter->tx_ring->count = 256;
-
- /*
- * Initial Wake on LAN setting - If APM wake is enabled in
- * the EEPROM, enable the ACPI Magic Packet filter
- */
- if (adapter->flags & FLAG_APME_IN_WUC) {
- /* APME bit in EEPROM is mapped to WUC.APME */
- eeprom_data = er32(WUC);
- eeprom_apme_mask = E1000_WUC_APME;
- } else if (adapter->flags & FLAG_APME_IN_CTRL3) {
- if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
- (adapter->hw.bus.func == 1))
- e1000_read_nvm(&adapter->hw,
- NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
- else
- e1000_read_nvm(&adapter->hw,
- NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
- }
-
- /* fetch WoL from EEPROM */
- if (eeprom_data & eeprom_apme_mask)
- adapter->eeprom_wol |= E1000_WUFC_MAG;
-
- /*
- * now that we have the eeprom settings, apply the special cases
- * where the eeprom may be wrong or the board simply won't support
- * wake on lan on a particular port
- */
- if (!(adapter->flags & FLAG_HAS_WOL))
- adapter->eeprom_wol = 0;
-
- /* initialize the wol settings based on the eeprom settings */
- adapter->wol = adapter->eeprom_wol;
-
- /* reset the hardware with the new settings */
- e1000e_reset(adapter);
-
- /*
- * If the controller has AMT, do not set DRV_LOAD until the interface
- * is up. For all other cases, let the f/w know that the h/w is now
- * under the control of the driver.
- */
- if (!(adapter->flags & FLAG_HAS_AMT))
- e1000_get_hw_control(adapter);
-
- /* tell the stack to leave us alone until e1000_open() is called */
- netif_carrier_off(netdev);
- netif_tx_stop_all_queues(netdev);
-
- strcpy(netdev->name, "eth%d");
- err = register_netdev(netdev);
- if (err)
- goto err_register;
-
- e1000_print_device_info(adapter);
-
- return 0;
-
-err_register:
- if (!(adapter->flags & FLAG_HAS_AMT))
- e1000_release_hw_control(adapter);
-err_eeprom:
- if (!e1000_check_reset_block(&adapter->hw))
- e1000_phy_hw_reset(&adapter->hw);
-err_hw_init:
-
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
-err_sw_init:
- if (adapter->hw.flash_address)
- iounmap(adapter->hw.flash_address);
-err_flashmap:
- iounmap(adapter->hw.hw_addr);
-err_ioremap:
- free_netdev(netdev);
-err_alloc_etherdev:
- pci_release_selected_regions(pdev,
- pci_select_bars(pdev, IORESOURCE_MEM));
-err_pci_reg:
-err_dma:
- pci_disable_device(pdev);
- return err;
-}
-
-/**
- * e1000_remove - Device Removal Routine
- * @pdev: PCI device information struct
- *
- * e1000_remove is called by the PCI subsystem to alert the driver
- * that it should release a PCI device. The could be caused by a
- * Hot-Plug event, or because the driver is going to be removed from
- * memory.
- **/
-static void __devexit e1000_remove(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct e1000_adapter *adapter = netdev_priv(netdev);
-
- /*
- * flush_scheduled work may reschedule our watchdog task, so
- * explicitly disable watchdog tasks from being rescheduled
- */
- set_bit(__E1000_DOWN, &adapter->state);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
-
- flush_scheduled_work();
-
- /*
- * Release control of h/w to f/w. If f/w is AMT enabled, this
- * would have already happened in close and is redundant.
- */
- e1000_release_hw_control(adapter);
-
- unregister_netdev(netdev);
-
- if (!e1000_check_reset_block(&adapter->hw))
- e1000_phy_hw_reset(&adapter->hw);
-
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
-
- iounmap(adapter->hw.hw_addr);
- if (adapter->hw.flash_address)
- iounmap(adapter->hw.flash_address);
- pci_release_selected_regions(pdev,
- pci_select_bars(pdev, IORESOURCE_MEM));
-
- free_netdev(netdev);
-
- pci_disable_device(pdev);
-}
-
-/* PCI Error Recovery (ERS) */
-static struct pci_error_handlers e1000_err_handler = {
- .error_detected = e1000_io_error_detected,
- .slot_reset = e1000_io_slot_reset,
- .resume = e1000_io_resume,
-};
-
-static struct pci_device_id e1000_pci_tbl[] = {
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
-
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
-
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
-
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
- board_80003es2lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
- board_80003es2lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
- board_80003es2lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
- board_80003es2lan },
-
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
-
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
-
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
- { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
-
- { } /* terminate list */
-};
-MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
-
-/* PCI Device API Driver */
-static struct pci_driver e1000_driver = {
- .name = e1000e_driver_name,
- .id_table = e1000_pci_tbl,
- .probe = e1000_probe,
- .remove = __devexit_p(e1000_remove),
-#ifdef CONFIG_PM
- /* Power Management Hooks */
- .suspend = e1000_suspend,
- .resume = e1000_resume,
-#endif
- .shutdown = e1000_shutdown,
- .err_handler = &e1000_err_handler
-};
-
-/**
- * e1000_init_module - Driver Registration Routine
- *
- * e1000_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- **/
-static int __init e1000_init_module(void)
-{
- int ret;
- printk(KERN_INFO "%s: Intel(R) PRO/1000 Network Driver - %s\n",
- e1000e_driver_name, e1000e_driver_version);
- printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n",
- e1000e_driver_name);
- ret = pci_register_driver(&e1000_driver);
- pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name,
- PM_QOS_DEFAULT_VALUE);
-
- return ret;
-}
-module_init(e1000_init_module);
-
-/**
- * e1000_exit_module - Driver Exit Cleanup Routine
- *
- * e1000_exit_module is called just before the driver is removed
- * from memory.
- **/
-static void __exit e1000_exit_module(void)
-{
- pci_unregister_driver(&e1000_driver);
- pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name);
-}
-module_exit(e1000_exit_module);
-
-
-MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
-MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-
-/* e1000_main.c */
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
deleted file mode 100644
index d91dbf7ba43..00000000000
--- a/drivers/net/e1000e/param.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-
-#include "e1000.h"
-
-/*
- * This is the only thing that needs to be changed to adjust the
- * maximum number of ports that the driver can manage.
- */
-
-#define E1000_MAX_NIC 32
-
-#define OPTION_UNSET -1
-#define OPTION_DISABLED 0
-#define OPTION_ENABLED 1
-
-#define COPYBREAK_DEFAULT 256
-unsigned int copybreak = COPYBREAK_DEFAULT;
-module_param(copybreak, uint, 0644);
-MODULE_PARM_DESC(copybreak,
- "Maximum size of packet that is copied to a new buffer on receive");
-
-/*
- * All parameters are treated the same, as an integer array of values.
- * This macro just reduces the need to repeat the same declaration code
- * over and over (plus this helps to avoid typo bugs).
- */
-
-#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
-#define E1000_PARAM(X, desc) \
- static int __devinitdata X[E1000_MAX_NIC+1] \
- = E1000_PARAM_INIT; \
- static unsigned int num_##X; \
- module_param_array_named(X, X, int, &num_##X, 0); \
- MODULE_PARM_DESC(X, desc);
-
-
-/*
- * Transmit Interrupt Delay in units of 1.024 microseconds
- * Tx interrupt delay needs to typically be set to something non zero
- *
- * Valid Range: 0-65535
- */
-E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
-#define DEFAULT_TIDV 8
-#define MAX_TXDELAY 0xFFFF
-#define MIN_TXDELAY 0
-
-/*
- * Transmit Absolute Interrupt Delay in units of 1.024 microseconds
- *
- * Valid Range: 0-65535
- */
-E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
-#define DEFAULT_TADV 32
-#define MAX_TXABSDELAY 0xFFFF
-#define MIN_TXABSDELAY 0
-
-/*
- * Receive Interrupt Delay in units of 1.024 microseconds
- * hardware will likely hang if you set this to anything but zero.
- *
- * Valid Range: 0-65535
- */
-E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
-#define DEFAULT_RDTR 0
-#define MAX_RXDELAY 0xFFFF
-#define MIN_RXDELAY 0
-
-/*
- * Receive Absolute Interrupt Delay in units of 1.024 microseconds
- *
- * Valid Range: 0-65535
- */
-E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
-#define DEFAULT_RADV 8
-#define MAX_RXABSDELAY 0xFFFF
-#define MIN_RXABSDELAY 0
-
-/*
- * Interrupt Throttle Rate (interrupts/sec)
- *
- * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
- */
-E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
-#define DEFAULT_ITR 3
-#define MAX_ITR 100000
-#define MIN_ITR 100
-
-/*
- * Enable Smart Power Down of the PHY
- *
- * Valid Range: 0, 1
- *
- * Default Value: 0 (disabled)
- */
-E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
-
-/*
- * Enable Kumeran Lock Loss workaround
- *
- * Valid Range: 0, 1
- *
- * Default Value: 1 (enabled)
- */
-E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
-
-/*
- * Write Protect NVM
- *
- * Valid Range: 0, 1
- *
- * Default Value: 1 (enabled)
- */
-E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");
-
-struct e1000_option {
- enum { enable_option, range_option, list_option } type;
- const char *name;
- const char *err;
- int def;
- union {
- struct { /* range_option info */
- int min;
- int max;
- } r;
- struct { /* list_option info */
- int nr;
- struct e1000_opt_list { int i; char *str; } *p;
- } l;
- } arg;
-};
-
-static int __devinit e1000_validate_option(unsigned int *value,
- const struct e1000_option *opt,
- struct e1000_adapter *adapter)
-{
- if (*value == OPTION_UNSET) {
- *value = opt->def;
- return 0;
- }
-
- switch (opt->type) {
- case enable_option:
- switch (*value) {
- case OPTION_ENABLED:
- e_info("%s Enabled\n", opt->name);
- return 0;
- case OPTION_DISABLED:
- e_info("%s Disabled\n", opt->name);
- return 0;
- }
- break;
- case range_option:
- if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
- e_info("%s set to %i\n", opt->name, *value);
- return 0;
- }
- break;
- case list_option: {
- int i;
- struct e1000_opt_list *ent;
-
- for (i = 0; i < opt->arg.l.nr; i++) {
- ent = &opt->arg.l.p[i];
- if (*value == ent->i) {
- if (ent->str[0] != '\0')
- e_info("%s\n", ent->str);
- return 0;
- }
- }
- }
- break;
- default:
- BUG();
- }
-
- e_info("Invalid %s value specified (%i) %s\n", opt->name, *value,
- opt->err);
- *value = opt->def;
- return -1;
-}
-
-/**
- * e1000e_check_options - Range Checking for Command Line Parameters
- * @adapter: board private structure
- *
- * This routine checks all command line parameters for valid user
- * input. If an invalid value is given, or if no user specified
- * value exists, a default value is used. The final value is stored
- * in a variable in the adapter structure.
- **/
-void __devinit e1000e_check_options(struct e1000_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- int bd = adapter->bd_number;
-
- if (bd >= E1000_MAX_NIC) {
- e_notice("Warning: no configuration for board #%i\n", bd);
- e_notice("Using defaults for all values\n");
- }
-
- { /* Transmit Interrupt Delay */
- const struct e1000_option opt = {
- .type = range_option,
- .name = "Transmit Interrupt Delay",
- .err = "using default of "
- __MODULE_STRING(DEFAULT_TIDV),
- .def = DEFAULT_TIDV,
- .arg = { .r = { .min = MIN_TXDELAY,
- .max = MAX_TXDELAY } }
- };
-
- if (num_TxIntDelay > bd) {
- adapter->tx_int_delay = TxIntDelay[bd];
- e1000_validate_option(&adapter->tx_int_delay, &opt,
- adapter);
- } else {
- adapter->tx_int_delay = opt.def;
- }
- }
- { /* Transmit Absolute Interrupt Delay */
- const struct e1000_option opt = {
- .type = range_option,
- .name = "Transmit Absolute Interrupt Delay",
- .err = "using default of "
- __MODULE_STRING(DEFAULT_TADV),
- .def = DEFAULT_TADV,
- .arg = { .r = { .min = MIN_TXABSDELAY,
- .max = MAX_TXABSDELAY } }
- };
-
- if (num_TxAbsIntDelay > bd) {
- adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
- e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
- adapter);
- } else {
- adapter->tx_abs_int_delay = opt.def;
- }
- }
- { /* Receive Interrupt Delay */
- struct e1000_option opt = {
- .type = range_option,
- .name = "Receive Interrupt Delay",
- .err = "using default of "
- __MODULE_STRING(DEFAULT_RDTR),
- .def = DEFAULT_RDTR,
- .arg = { .r = { .min = MIN_RXDELAY,
- .max = MAX_RXDELAY } }
- };
-
- if (num_RxIntDelay > bd) {
- adapter->rx_int_delay = RxIntDelay[bd];
- e1000_validate_option(&adapter->rx_int_delay, &opt,
- adapter);
- } else {
- adapter->rx_int_delay = opt.def;
- }
- }
- { /* Receive Absolute Interrupt Delay */
- const struct e1000_option opt = {
- .type = range_option,
- .name = "Receive Absolute Interrupt Delay",
- .err = "using default of "
- __MODULE_STRING(DEFAULT_RADV),
- .def = DEFAULT_RADV,
- .arg = { .r = { .min = MIN_RXABSDELAY,
- .max = MAX_RXABSDELAY } }
- };
-
- if (num_RxAbsIntDelay > bd) {
- adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
- e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
- adapter);
- } else {
- adapter->rx_abs_int_delay = opt.def;
- }
- }
- { /* Interrupt Throttling Rate */
- const struct e1000_option opt = {
- .type = range_option,
- .name = "Interrupt Throttling Rate (ints/sec)",
- .err = "using default of "
- __MODULE_STRING(DEFAULT_ITR),
- .def = DEFAULT_ITR,
- .arg = { .r = { .min = MIN_ITR,
- .max = MAX_ITR } }
- };
-
- if (num_InterruptThrottleRate > bd) {
- adapter->itr = InterruptThrottleRate[bd];
- switch (adapter->itr) {
- case 0:
- e_info("%s turned off\n", opt.name);
- break;
- case 1:
- e_info("%s set to dynamic mode\n", opt.name);
- adapter->itr_setting = adapter->itr;
- adapter->itr = 20000;
- break;
- case 3:
- e_info("%s set to dynamic conservative mode\n",
- opt.name);
- adapter->itr_setting = adapter->itr;
- adapter->itr = 20000;
- break;
- default:
- /*
- * Save the setting, because the dynamic bits
- * change itr.
- */
- if (e1000_validate_option(&adapter->itr, &opt,
- adapter) &&
- (adapter->itr == 3)) {
- /*
- * In case of invalid user value,
- * default to conservative mode.
- */
- adapter->itr_setting = adapter->itr;
- adapter->itr = 20000;
- } else {
- /*
- * Clear the lower two bits because
- * they are used as control.
- */
- adapter->itr_setting =
- adapter->itr & ~3;
- }
- break;
- }
- } else {
- adapter->itr_setting = opt.def;
- adapter->itr = 20000;
- }
- }
- { /* Smart Power Down */
- const struct e1000_option opt = {
- .type = enable_option,
- .name = "PHY Smart Power Down",
- .err = "defaulting to Disabled",
- .def = OPTION_DISABLED
- };
-
- if (num_SmartPowerDownEnable > bd) {
- unsigned int spd = SmartPowerDownEnable[bd];
- e1000_validate_option(&spd, &opt, adapter);
- if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN)
- && spd)
- adapter->flags |= FLAG_SMART_POWER_DOWN;
- }
- }
- { /* Kumeran Lock Loss Workaround */
- const struct e1000_option opt = {
- .type = enable_option,
- .name = "Kumeran Lock Loss Workaround",
- .err = "defaulting to Enabled",
- .def = OPTION_ENABLED
- };
-
- if (num_KumeranLockLoss > bd) {
- unsigned int kmrn_lock_loss = KumeranLockLoss[bd];
- e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
- if (hw->mac.type == e1000_ich8lan)
- e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw,
- kmrn_lock_loss);
- } else {
- if (hw->mac.type == e1000_ich8lan)
- e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw,
- opt.def);
- }
- }
- { /* Write-protect NVM */
- const struct e1000_option opt = {
- .type = enable_option,
- .name = "Write-protect NVM",
- .err = "defaulting to Enabled",
- .def = OPTION_ENABLED
- };
-
- if (adapter->flags & FLAG_IS_ICH) {
- if (num_WriteProtectNVM > bd) {
- unsigned int write_protect_nvm = WriteProtectNVM[bd];
- e1000_validate_option(&write_protect_nvm, &opt,
- adapter);
- if (write_protect_nvm)
- adapter->flags |= FLAG_READ_ONLY_NVM;
- } else {
- if (opt.def)
- adapter->flags |= FLAG_READ_ONLY_NVM;
- }
- }
- }
-}
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
deleted file mode 100644
index b133dcf0e95..00000000000
--- a/drivers/net/e1000e/phy.c
+++ /dev/null
@@ -1,2099 +0,0 @@
-/*******************************************************************************
-
- Intel PRO/1000 Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU General Public License,
- version 2, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
- The full GNU General Public License is included in this distribution in
- the file called "COPYING".
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
- e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/delay.h>
-
-#include "e1000.h"
-
-static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
-static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
-static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
-static s32 e1000_wait_autoneg(struct e1000_hw *hw);
-static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
-static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
- u16 *data, bool read);
-
-/* Cable length tables */
-static const u16 e1000_m88_cable_length_table[] =
- { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
-
-static const u16 e1000_igp_2_cable_length_table[] =
- { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3,
- 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22,
- 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, 21, 26, 31, 35, 40,
- 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82, 40, 45, 51, 56, 61,
- 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104, 60, 66, 72, 77, 82,
- 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121, 83, 89, 95,
- 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
- 124};
-#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
- ARRAY_SIZE(e1000_igp_2_cable_length_table)
-
-/**
- * e1000e_check_reset_block_generic - Check if PHY reset is blocked
- * @hw: pointer to the HW structure
- *
- * Read the PHY management control register and check whether a PHY reset
- * is blocked. If a reset is not blocked return 0, otherwise
- * return E1000_BLK_PHY_RESET (12).
- **/
-s32 e1000e_check_reset_block_generic(struct e1000_hw *hw)
-{
- u32 manc;
-
- manc = er32(MANC);
-
- return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
- E1000_BLK_PHY_RESET : 0;
-}
-
-/**
- * e1000e_get_phy_id - Retrieve the PHY ID and revision
- * @hw: pointer to the HW structure
- *
- * Reads the PHY registers and stores the PHY ID and possibly the PHY
- * revision in the hardware structure.
- **/
-s32 e1000e_get_phy_id(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_id;
-
- ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
- if (ret_val)
- return ret_val;
-
- phy->id = (u32)(phy_id << 16);
- udelay(20);
- ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
- if (ret_val)
- return ret_val;
-
- phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
- phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
-
- return 0;
-}
-
-/**
- * e1000e_phy_reset_dsp - Reset PHY DSP
- * @hw: pointer to the HW structure
- *
- * Reset the digital signal processor.
- **/
-s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
-{
- s32 ret_val;
-
- ret_val = e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
- if (ret_val)
- return ret_val;
-
- return e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0);
-}
-
-/**
- * e1000e_read_phy_reg_mdic - Read MDI control register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Reads the MDI control register in the PHY at offset and stores the
- * information read to data.
- **/
-s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, mdic = 0;
-
- if (offset > MAX_PHY_REG_ADDRESS) {
- hw_dbg(hw, "PHY Address %d is out of range\n", offset);
- return -E1000_ERR_PARAM;
- }
-
- /*
- * Set up Op-code, Phy Address, and register offset in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- mdic = ((offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_READ));
-
- ew32(MDIC, mdic);
-
- /*
- * Poll the ready bit to see if the MDI read completed
- * Increasing the time out as testing showed failures with
- * the lower time out
- */
- for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
- udelay(50);
- mdic = er32(MDIC);
- if (mdic & E1000_MDIC_READY)
- break;
- }
- if (!(mdic & E1000_MDIC_READY)) {
- hw_dbg(hw, "MDI Read did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (mdic & E1000_MDIC_ERROR) {
- hw_dbg(hw, "MDI Error\n");
- return -E1000_ERR_PHY;
- }
- *data = (u16) mdic;
-
- return 0;
-}
-
-/**
- * e1000e_write_phy_reg_mdic - Write MDI control register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write to register at offset
- *
- * Writes data to MDI control register in the PHY at offset.
- **/
-s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
-{
- struct e1000_phy_info *phy = &hw->phy;
- u32 i, mdic = 0;
-
- if (offset > MAX_PHY_REG_ADDRESS) {
- hw_dbg(hw, "PHY Address %d is out of range\n", offset);
- return -E1000_ERR_PARAM;
- }
-
- /*
- * Set up Op-code, Phy Address, and register offset in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
- */
- mdic = (((u32)data) |
- (offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_WRITE));
-
- ew32(MDIC, mdic);
-
- /*
- * Poll the ready bit to see if the MDI read completed
- * Increasing the time out as testing showed failures with
- * the lower time out
- */
- for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
- udelay(50);
- mdic = er32(MDIC);
- if (mdic & E1000_MDIC_READY)
- break;
- }
- if (!(mdic & E1000_MDIC_READY)) {
- hw_dbg(hw, "MDI Write did not complete\n");
- return -E1000_ERR_PHY;
- }
- if (mdic & E1000_MDIC_ERROR) {
- hw_dbg(hw, "MDI Error\n");
- return -E1000_ERR_PHY;
- }
-
- return 0;
-}
-
-/**
- * e1000e_read_phy_reg_m88 - Read m88 PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting.
- **/
-s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release_phy(hw);
-
- return ret_val;
-}
-
-/**
- * e1000e_write_phy_reg_m88 - Write m88 PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release_phy(hw);
-
- return ret_val;
-}
-
-/**
- * e1000e_read_phy_reg_igp - Read igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting.
- **/
-s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
- ret_val = e1000e_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (u16)offset);
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- return ret_val;
- }
- }
-
- ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release_phy(hw);
-
- return ret_val;
-}
-
-/**
- * e1000e_write_phy_reg_igp - Write igp PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
- ret_val = e1000e_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (u16)offset);
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- return ret_val;
- }
- }
-
- ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release_phy(hw);
-
- return ret_val;
-}
-
-/**
- * e1000e_read_kmrn_reg - Read kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore, if necessary. Then reads the PHY register at offset
- * using the kumeran interface. The information retrieved is stored in data.
- * Release any acquired semaphores before exiting.
- **/
-s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- u32 kmrnctrlsta;
- s32 ret_val;
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
- kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
- E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
- ew32(KMRNCTRLSTA, kmrnctrlsta);
-
- udelay(2);
-
- kmrnctrlsta = er32(KMRNCTRLSTA);
- *data = (u16)kmrnctrlsta;
-
- hw->phy.ops.release_phy(hw);
-
- return ret_val;
-}
-
-/**
- * e1000e_write_kmrn_reg - Write kumeran register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary. Then write the data to PHY register
- * at the offset using the kumeran interface. Release any acquired semaphores
- * before exiting.
- **/
-s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
-{
- u32 kmrnctrlsta;
- s32 ret_val;
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
- kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
- E1000_KMRNCTRLSTA_OFFSET) | data;
- ew32(KMRNCTRLSTA, kmrnctrlsta);
-
- udelay(2);
- hw->phy.ops.release_phy(hw);
-
- return ret_val;
-}
-
-/**
- * e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link
- * @hw: pointer to the HW structure
- *
- * Sets up MDI/MDI-X and polarity for m88 PHY's. If necessary, transmit clock
- * and downshift values are set also.
- **/
-s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
-
- /* Enable CRS on Tx. This must be set for half-duplex operation. */
- ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- /* For newer PHYs this bit is downshift enable */
- if (phy->type == e1000_phy_m88)
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-
- /*
- * Options:
- * MDI/MDI-X = 0 (default)
- * 0 - Auto for all speeds
- * 1 - MDI mode
- * 2 - MDI-X mode
- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-
- switch (phy->mdix) {
- case 1:
- phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
- break;
- case 2:
- phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
- break;
- case 3:
- phy_data |= M88E1000_PSCR_AUTO_X_1000T;
- break;
- case 0:
- default:
- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
- break;
- }
-
- /*
- * Options:
- * disable_polarity_correction = 0 (default)
- * Automatic Correction for Reversed Cable Polarity
- * 0 - Disabled
- * 1 - Enabled
- */
- phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
- if (phy->disable_polarity_correction == 1)
- phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-
- /* Enable downshift on BM (disabled by default) */
- if (phy->type == e1000_phy_bm)
- phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
-
- ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- if ((phy->type == e1000_phy_m88) && (phy->revision < 4)) {
- /*
- * Force TX_CLK in the Extended PHY Specific Control Register
- * to 25MHz clock.
- */
- ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
-
- if ((phy->revision == 2) &&
- (phy->id == M88E1111_I_PHY_ID)) {
- /* 82573L PHY - set the downshift counter to 5x. */
- phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
- phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
- } else {
- /* Configure Master and Slave downshift values */
- phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
- phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
- M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
- }
- ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
- }
-
- /* Commit the changes. */
- ret_val = e1000e_commit_phy(hw);
- if (ret_val)
- hw_dbg(hw, "Error committing the PHY changes\n");
-
- return ret_val;
-}
-
-/**
- * e1000e_copper_link_setup_igp - Setup igp PHY's for copper link
- * @hw: pointer to the HW structure
- *
- * Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
- * igp PHY's.
- **/
-s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- ret_val = e1000_phy_hw_reset(hw);
- if (ret_val) {
- hw_dbg(hw, "Error resetting the PHY.\n");
- return ret_val;
- }
-
- /*
- * Wait 100ms for MAC to configure PHY from NVM settings, to avoid
- * timeout issues when LFS is enabled.
- */
- msleep(100);
-
- /* disable lplu d0 during driver init */
- ret_val = e1000_set_d0_lplu_state(hw, 0);
- if (ret_val) {
- hw_dbg(hw, "Error Disabling LPLU D0\n");
- return ret_val;
- }
- /* Configure mdi-mdix settings */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCR_AUTO_MDIX;
-
- switch (phy->mdix) {
- case 1:
- data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 2:
- data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
- break;
- case 0:
- default:
- data |= IGP01E1000_PSCR_AUTO_MDIX;
- break;
- }
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, data);
- if (ret_val)
- return ret_val;
-
- /* set auto-master slave resolution settings */
- if (hw->mac.autoneg) {
- /*
- * when autonegotiation advertisement is only 1000Mbps then we
- * should disable SmartSpeed and enable Auto MasterSlave
- * resolution as hardware default.
- */
- if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
- /* Disable SmartSpeed */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
-
- /* Set auto Master/Slave resolution process */
- ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~CR_1000T_MS_ENABLE;
- ret_val = e1e_wphy(hw, PHY_1000T_CTRL, data);
- if (ret_val)
- return ret_val;
- }
-
- ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &data);
- if (ret_val)
- return ret_val;
-
- /* load defaults for future use */
- phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ?
- ((data & CR_1000T_MS_VALUE) ?
- e1000_ms_force_master :
- e1000_ms_force_slave) :
- e1000_ms_auto;
-
- switch (phy->ms_type) {
- case e1000_ms_force_master:
- data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
- break;
- case e1000_ms_force_slave:
- data |= CR_1000T_MS_ENABLE;
- data &= ~(CR_1000T_MS_VALUE);
- break;
- case e1000_ms_auto:
- data &= ~CR_1000T_MS_ENABLE;
- default:
- break;
- }
- ret_val = e1e_wphy(hw, PHY_1000T_CTRL, data);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
- * @hw: pointer to the HW structure
- *
- * Reads the MII auto-neg advertisement register and/or the 1000T control
- * register and if the PHY is already setup for auto-negotiation, then
- * return successful. Otherwise, setup advertisement and flow control to
- * the appropriate values for the wanted auto-negotiation.
- **/
-static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 mii_autoneg_adv_reg;
- u16 mii_1000t_ctrl_reg = 0;
-
- phy->autoneg_advertised &= phy->autoneg_mask;
-
- /* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
- if (ret_val)
- return ret_val;
-
- if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
- /* Read the MII 1000Base-T Control Register (Address 9). */
- ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
- if (ret_val)
- return ret_val;
- }
-
- /*
- * Need to parse both autoneg_advertised and fc and set up
- * the appropriate PHY registers. First we will parse for
- * autoneg_advertised software override. Since we can advertise
- * a plethora of combinations, we need to check each bit
- * individually.
- */
-
- /*
- * First we clear all the 10/100 mb speed bits in the Auto-Neg
- * Advertisement Register (Address 4) and the 1000 mb speed bits in
- * the 1000Base-T Control Register (Address 9).
- */
- mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
- NWAY_AR_100TX_HD_CAPS |
- NWAY_AR_10T_FD_CAPS |
- NWAY_AR_10T_HD_CAPS);
- mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
-
- hw_dbg(hw, "autoneg_advertised %x\n", phy->autoneg_advertised);
-
- /* Do we want to advertise 10 Mb Half Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
- hw_dbg(hw, "Advertise 10mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
- }
-
- /* Do we want to advertise 10 Mb Full Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
- hw_dbg(hw, "Advertise 10mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Half Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
- hw_dbg(hw, "Advertise 100mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Full Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
- hw_dbg(hw, "Advertise 100mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
- }
-
- /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
- if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
- hw_dbg(hw, "Advertise 1000mb Half duplex request denied!\n");
-
- /* Do we want to advertise 1000 Mb Full Duplex? */
- if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
- hw_dbg(hw, "Advertise 1000mb Full duplex\n");
- mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
- }
-
- /*
- * Check for a software override of the flow control settings, and
- * setup the PHY advertisement registers accordingly. If
- * auto-negotiation is enabled, then software will have to set the
- * "PAUSE" bits to the correct value in the Auto-Negotiation
- * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
- * negotiation.
- *
- * The possible values of the "fc" parameter are:
- * 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames
- * but not send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames
- * but we do not support receiving pause frames).
- * 3: Both Rx and Tx flow control (symmetric) are enabled.
- * other: No software override. The flow control configuration
- * in the EEPROM is used.
- */
- switch (hw->fc.type) {
- case e1000_fc_none:
- /*
- * Flow control (Rx & Tx) is completely disabled by a
- * software over-ride.
- */
- mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case e1000_fc_rx_pause:
- /*
- * Rx Flow control is enabled, and Tx Flow control is
- * disabled, by a software over-ride.
- *
- * Since there really isn't a way to advertise that we are
- * capable of Rx Pause ONLY, we will advertise that we
- * support both symmetric and asymmetric Rx PAUSE. Later
- * (in e1000e_config_fc_after_link_up) we will disable the
- * hw's ability to send PAUSE frames.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- case e1000_fc_tx_pause:
- /*
- * Tx Flow control is enabled, and Rx Flow control is
- * disabled, by a software over-ride.
- */
- mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
- mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
- break;
- case e1000_fc_full:
- /*
- * Flow control (both Rx and Tx) is enabled by a software
- * over-ride.
- */
- mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
- break;
- default:
- hw_dbg(hw, "Flow control param set incorrectly\n");
- ret_val = -E1000_ERR_CONFIG;
- return ret_val;
- }
-
- ret_val = e1e_wphy(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
- if (ret_val)
- return ret_val;
-
- hw_dbg(hw, "Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
-
- if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
- ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
- }
-
- return ret_val;
-}
-
-/**
- * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
- * @hw: pointer to the HW structure
- *
- * Performs initial bounds checking on autoneg advertisement parameter, then
- * configure to advertise the full capability. Setup the PHY to autoneg
- * and restart the negotiation process between the link partner. If
- * autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
- **/
-static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_ctrl;
-
- /*
- * Perform some bounds checking on the autoneg advertisement
- * parameter.
- */
- phy->autoneg_advertised &= phy->autoneg_mask;
-
- /*
- * If autoneg_advertised is zero, we assume it was not defaulted
- * by the calling code so we set to advertise full capability.
- */
- if (phy->autoneg_advertised == 0)
- phy->autoneg_advertised = phy->autoneg_mask;
-
- hw_dbg(hw, "Reconfiguring auto-neg advertisement params\n");
- ret_val = e1000_phy_setup_autoneg(hw);
- if (ret_val) {
- hw_dbg(hw, "Error Setting up Auto-Negotiation\n");
- return ret_val;
- }
- hw_dbg(hw, "Restarting Auto-Neg\n");
-
- /*
- * Restart auto-negotiation by setting the Auto Neg Enable bit and
- * the Auto Neg Restart bit in the PHY control register.
- */
- ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
- if (ret_val)
- return ret_val;
-
- phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
- ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
- if (ret_val)
- return ret_val;
-
- /*
- * Does the user want to wait for Auto-Neg to complete here, or
- * check at a later time (for example, callback routine).
- */
- if (phy->autoneg_wait_to_complete) {
- ret_val = e1000_wait_autoneg(hw);
- if (ret_val) {
- hw_dbg(hw, "Error while waiting for "
- "autoneg to complete\n");
- return ret_val;
- }
- }
-
- hw->mac.get_link_status = 1;
-
- return ret_val;
-}
-
-/**
- * e1000e_setup_copper_link - Configure copper link settings
- * @hw: pointer to the HW structure
- *
- * Calls the appropriate function to configure the link for auto-neg or forced
- * speed and duplex. Then we check for link, once link is established calls
- * to configure collision distance and flow control are called. If link is
- * not established, we return -E1000_ERR_PHY (-2).
- **/
-s32 e1000e_setup_copper_link(struct e1000_hw *hw)
-{
- s32 ret_val;
- bool link;
-
- if (hw->mac.autoneg) {
- /*
- * Setup autoneg and flow control advertisement and perform
- * autonegotiation.
- */
- ret_val = e1000_copper_link_autoneg(hw);
- if (ret_val)
- return ret_val;
- } else {
- /*
- * PHY will be set to 10H, 10F, 100H or 100F
- * depending on user settings.
- */
- hw_dbg(hw, "Forcing Speed and Duplex\n");
- ret_val = e1000_phy_force_speed_duplex(hw);
- if (ret_val) {
- hw_dbg(hw, "Error Forcing Speed and Duplex\n");
- return ret_val;
- }
- }
-
- /*
- * Check link status. Wait up to 100 microseconds for link to become
- * valid.
- */
- ret_val = e1000e_phy_has_link_generic(hw,
- COPPER_LINK_UP_LIMIT,
- 10,
- &link);
- if (ret_val)
- return ret_val;
-
- if (link) {
- hw_dbg(hw, "Valid link established!!!\n");
- e1000e_config_collision_dist(hw);
- ret_val = e1000e_config_fc_after_link_up(hw);
- } else {
- hw_dbg(hw, "Unable to establish link!!!\n");
- }
-
- return ret_val;
-}
-
-/**
- * e1000e_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY
- * @hw: pointer to the HW structure
- *
- * Calls the PHY setup function to force speed and duplex. Clears the
- * auto-crossover to force MDI manually. Waits for link and returns
- * successful if link up is successful, else -E1000_ERR_PHY (-2).
- **/
-s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
- bool link;
-
- ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
-
- ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- /*
- * Clear Auto-Crossover to force MDI manually. IGP requires MDI
- * forced whenever speed and duplex are forced.
- */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- hw_dbg(hw, "IGP PSCR: %X\n", phy_data);
-
- udelay(1);
-
- if (phy->autoneg_wait_to_complete) {
- hw_dbg(hw, "Waiting for forced speed/duplex link on IGP phy.\n");
-
- ret_val = e1000e_phy_has_link_generic(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
- if (ret_val)
- return ret_val;
-
- if (!link)
- hw_dbg(hw, "Link taking longer than expected.\n");
-
- /* Try once more */
- ret_val = e1000e_phy_has_link_generic(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
- if (ret_val)
- return ret_val;
- }
-
- return ret_val;
-}
-
-/**
- * e1000e_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY
- * @hw: pointer to the HW structure
- *
- * Calls the PHY setup function to force speed and duplex. Clears the
- * auto-crossover to force MDI manually. Resets the PHY to commit the
- * changes. If time expires while waiting for link up, we reset the DSP.
- * After reset, TX_CLK and CRS on Tx must be set. Return successful upon
- * successful completion, else return corresponding error code.
- **/
-s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
- bool link;
-
- /*
- * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
- * forced whenever speed and duplex are forced.
- */
- ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- hw_dbg(hw, "M88E1000 PSCR: %X\n", phy_data);
-
- ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
- if (ret_val)
- return ret_val;
-
- e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
-
- /* Reset the phy to commit changes. */
- phy_data |= MII_CR_RESET;
-
- ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
- if (ret_val)
- return ret_val;
-
- udelay(1);
-
- if (phy->autoneg_wait_to_complete) {
- hw_dbg(hw, "Waiting for forced speed/duplex link on M88 phy.\n");
-
- ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- /*
- * We didn't get link.
- * Reset the DSP and cross our fingers.
- */
- ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT,
- 0x001d);
- if (ret_val)
- return ret_val;
- ret_val = e1000e_phy_reset_dsp(hw);
- if (ret_val)
- return ret_val;
- }
-
- /* Try once more */
- ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
- 100000, &link);
- if (ret_val)
- return ret_val;
- }
-
- ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- /*
- * Resetting the phy means we need to re-force TX_CLK in the
- * Extended PHY Specific Control Register to 25MHz clock from
- * the reset value of 2.5MHz.
- */
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
- if (ret_val)
- return ret_val;
-
- /*
- * In addition, we must re-enable CRS on Tx for both half and full
- * duplex.
- */
- ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
-
- return ret_val;
-}
-
-/**
- * e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
- * @hw: pointer to the HW structure
- * @phy_ctrl: pointer to current value of PHY_CONTROL
- *
- * Forces speed and duplex on the PHY by doing the following: disable flow
- * control, force speed/duplex on the MAC, disable auto speed detection,
- * disable auto-negotiation, configure duplex, configure speed, configure
- * the collision distance, write configuration to CTRL register. The
- * caller must write to the PHY_CONTROL register for these settings to
- * take affect.
- **/
-void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
-{
- struct e1000_mac_info *mac = &hw->mac;
- u32 ctrl;
-
- /* Turn off flow control when forcing speed/duplex */
- hw->fc.type = e1000_fc_none;
-
- /* Force speed/duplex on the mac */
- ctrl = er32(CTRL);
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- ctrl &= ~E1000_CTRL_SPD_SEL;
-
- /* Disable Auto Speed Detection */
- ctrl &= ~E1000_CTRL_ASDE;
-
- /* Disable autoneg on the phy */
- *phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
-
- /* Forcing Full or Half Duplex? */
- if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
- ctrl &= ~E1000_CTRL_FD;
- *phy_ctrl &= ~MII_CR_FULL_DUPLEX;
- hw_dbg(hw, "Half Duplex\n");
- } else {
- ctrl |= E1000_CTRL_FD;
- *phy_ctrl |= MII_CR_FULL_DUPLEX;
- hw_dbg(hw, "Full Duplex\n");
- }
-
- /* Forcing 10mb or 100mb? */
- if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
- ctrl |= E1000_CTRL_SPD_100;
- *phy_ctrl |= MII_CR_SPEED_100;
- *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
- hw_dbg(hw, "Forcing 100mb\n");
- } else {
- ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
- *phy_ctrl |= MII_CR_SPEED_10;
- *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
- hw_dbg(hw, "Forcing 10mb\n");
- }
-
- e1000e_config_collision_dist(hw);
-
- ew32(CTRL, ctrl);
-}
-
-/**
- * e1000e_set_d3_lplu_state - Sets low power link up state for D3
- * @hw: pointer to the HW structure
- * @active: boolean used to enable/disable lplu
- *
- * Success returns 0, Failure returns 1
- *
- * The low power link up (lplu) state is set to the power management level D3
- * and SmartSpeed is disabled when active is true, else clear lplu for D3
- * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
- * is used during Dx states where the power conservation is most important.
- * During driver activity, SmartSpeed should be enabled so performance is
- * maintained.
- **/
-s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data);
- if (ret_val)
- return ret_val;
-
- if (!active) {
- data &= ~IGP02E1000_PM_D3_LPLU;
- ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
- if (ret_val)
- return ret_val;
- /*
- * LPLU and SmartSpeed are mutually exclusive. LPLU is used
- * during Dx states where the power conservation is most
- * important. During driver activity we should enable
- * SmartSpeed, so performance is maintained.
- */
- if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- } else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
- data);
- if (ret_val)
- return ret_val;
- }
- } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
- (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
- (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
- data |= IGP02E1000_PM_D3_LPLU;
- ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
- if (ret_val)
- return ret_val;
-
- /* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
- if (ret_val)
- return ret_val;
-
- data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
- }
-
- return ret_val;
-}
-
-/**
- * e1000e_check_downshift - Checks whether a downshift in speed occurred
- * @hw: pointer to the HW structure
- *
- * Success returns 0, Failure returns 1
- *
- * A downshift is detected by querying the PHY link health.
- **/
-s32 e1000e_check_downshift(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, offset, mask;
-
- switch (phy->type) {
- case e1000_phy_m88:
- case e1000_phy_gg82563:
- offset = M88E1000_PHY_SPEC_STATUS;
- mask = M88E1000_PSSR_DOWNSHIFT;
- break;
- case e1000_phy_igp_2:
- case e1000_phy_igp_3:
- offset = IGP01E1000_PHY_LINK_HEALTH;
- mask = IGP01E1000_PLHR_SS_DOWNGRADE;
- break;
- default:
- /* speed downshift not supported */
- phy->speed_downgraded = 0;
- return 0;
- }
-
- ret_val = e1e_rphy(hw, offset, &phy_data);
-
- if (!ret_val)
- phy->speed_downgraded = (phy_data & mask);
-
- return ret_val;
-}
-
-/**
- * e1000_check_polarity_m88 - Checks the polarity.
- * @hw: pointer to the HW structure
- *
- * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
- *
- * Polarity is determined based on the PHY specific status register.
- **/
-static s32 e1000_check_polarity_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
-
- ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &data);
-
- if (!ret_val)
- phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal;
-
- return ret_val;
-}
-
-/**
- * e1000_check_polarity_igp - Checks the polarity.
- * @hw: pointer to the HW structure
- *
- * Success returns 0, Failure returns -E1000_ERR_PHY (-2)
- *
- * Polarity is determined based on the PHY port status register, and the
- * current speed (since there is no polarity at 100Mbps).
- **/
-static s32 e1000_check_polarity_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data, offset, mask;
-
- /*
- * Polarity is determined based on the speed of
- * our connection.
- */
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
- offset = IGP01E1000_PHY_PCS_INIT_REG;
- mask = IGP01E1000_PHY_POLARITY_MASK;
- } else {
- /*
- * This really only applies to 10Mbps since
- * there is no polarity for 100Mbps (always 0).
- */
- offset = IGP01E1000_PHY_PORT_STATUS;
- mask = IGP01E1000_PSSR_POLARITY_REVERSED;
- }
-
- ret_val = e1e_rphy(hw, offset, &data);
-
- if (!ret_val)
- phy->cable_polarity = (data & mask)
- ? e1000_rev_polarity_reversed
- : e1000_rev_polarity_normal;
-
- return ret_val;
-}
-
-/**
- * e1000_wait_autoneg - Wait for auto-neg completion
- * @hw: pointer to the HW structure
- *
- * Waits for auto-negotiation to complete or for the auto-negotiation time
- * limit to expire, which ever happens first.
- **/
-static s32 e1000_wait_autoneg(struct e1000_hw *hw)
-{
- s32 ret_val = 0;
- u16 i, phy_status;
-
- /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
- for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
- ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
- ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
- if (phy_status & MII_SR_AUTONEG_COMPLETE)
- break;
- msleep(100);
- }
-
- /*
- * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
- * has completed.
- */
- return ret_val;
-}
-
-/**
- * e1000e_phy_has_link_generic - Polls PHY for link
- * @hw: pointer to the HW structure
- * @iterations: number of times to poll for link
- * @usec_interval: delay between polling attempts
- * @success: pointer to whether polling was successful or not
- *
- * Polls the PHY status register for link, 'iterations' number of times.
- **/
-s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
- u32 usec_interval, bool *success)
-{
- s32 ret_val = 0;
- u16 i, phy_status;
-
- for (i = 0; i < iterations; i++) {
- /*
- * Some PHYs require the PHY_STATUS register to be read
- * twice due to the link bit being sticky. No harm doing
- * it across the board.
- */
- ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
- ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status);
- if (ret_val)
- break;
- if (phy_status & MII_SR_LINK_STATUS)
- break;
- if (usec_interval >= 1000)
- mdelay(usec_interval/1000);
- else
- udelay(usec_interval);
- }
-
- *success = (i < iterations);
-
- return ret_val;
-}
-
-/**
- * e1000e_get_cable_length_m88 - Determine cable length for m88 PHY
- * @hw: pointer to the HW structure
- *
- * Reads the PHY specific status register to retrieve the cable length
- * information. The cable length is determined by averaging the minimum and
- * maximum values to get the "average" cable length. The m88 PHY has four
- * possible cable length values, which are:
- * Register Value Cable Length
- * 0 < 50 meters
- * 1 50 - 80 meters
- * 2 80 - 110 meters
- * 3 110 - 140 meters
- * 4 > 140 meters
- **/
-s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, index;
-
- ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
- M88E1000_PSSR_CABLE_LENGTH_SHIFT;
- phy->min_cable_length = e1000_m88_cable_length_table[index];
- phy->max_cable_length = e1000_m88_cable_length_table[index+1];
-
- phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
-
- return ret_val;
-}
-
-/**
- * e1000e_get_cable_length_igp_2 - Determine cable length for igp2 PHY
- * @hw: pointer to the HW structure
- *
- * The automatic gain control (agc) normalizes the amplitude of the
- * received signal, adjusting for the attenuation produced by the
- * cable. By reading the AGC registers, which represent the
- * combination of course and fine gain value, the value can be put
- * into a lookup table to obtain the approximate cable length
- * for each channel.
- **/
-s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data, i, agc_value = 0;
- u16 cur_agc_index, max_agc_index = 0;
- u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
- u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
- {IGP02E1000_PHY_AGC_A,
- IGP02E1000_PHY_AGC_B,
- IGP02E1000_PHY_AGC_C,
- IGP02E1000_PHY_AGC_D};
-
- /* Read the AGC registers for all channels */
- for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = e1e_rphy(hw, agc_reg_array[i], &phy_data);
- if (ret_val)
- return ret_val;
-
- /*
- * Getting bits 15:9, which represent the combination of
- * course and fine gain values. The result is a number
- * that can be put into the lookup table to obtain the
- * approximate cable length.
- */
- cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
- IGP02E1000_AGC_LENGTH_MASK;
-
- /* Array index bound check. */
- if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
- (cur_agc_index == 0))
- return -E1000_ERR_PHY;
-
- /* Remove min & max AGC values from calculation. */
- if (e1000_igp_2_cable_length_table[min_agc_index] >
- e1000_igp_2_cable_length_table[cur_agc_index])
- min_agc_index = cur_agc_index;
- if (e1000_igp_2_cable_length_table[max_agc_index] <
- e1000_igp_2_cable_length_table[cur_agc_index])
- max_agc_index = cur_agc_index;
-
- agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
- }
-
- agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
- e1000_igp_2_cable_length_table[max_agc_index]);
- agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
-
- /* Calculate cable length with the error range of +/- 10 meters. */
- phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
- (agc_value - IGP02E1000_AGC_RANGE) : 0;
- phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
-
- phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
-
- return ret_val;
-}
-
-/**
- * e1000e_get_phy_info_m88 - Retrieve PHY information
- * @hw: pointer to the HW structure
- *
- * Valid for only copper links. Read the PHY status register (sticky read)
- * to verify that link is up. Read the PHY special control register to
- * determine the polarity and 10base-T extended distance. Read the PHY
- * special status register to determine MDI/MDIx and current speed. If
- * speed is 1000, then determine cable length, local and remote receiver.
- **/
-s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 phy_data;
- bool link;
-
- if (hw->phy.media_type != e1000_media_type_copper) {
- hw_dbg(hw, "Phy info is only valid for copper media\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- hw_dbg(hw, "Phy info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy->polarity_correction = (phy_data &
- M88E1000_PSCR_POLARITY_REVERSAL);
-
- ret_val = e1000_check_polarity_m88(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX);
-
- if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
- ret_val = e1000_get_cable_length(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &phy_data);
- if (ret_val)
- return ret_val;
-
- phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
-
- phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
- } else {
- /* Set values to "undefined" */
- phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
- phy->local_rx = e1000_1000t_rx_status_undefined;
- phy->remote_rx = e1000_1000t_rx_status_undefined;
- }
-
- return ret_val;
-}
-
-/**
- * e1000e_get_phy_info_igp - Retrieve igp PHY information
- * @hw: pointer to the HW structure
- *
- * Read PHY status to determine if link is up. If link is up, then
- * set/determine 10base-T extended distance and polarity correction. Read
- * PHY port status to determine MDI/MDIx and speed. Based on the speed,
- * determine on the cable length, local and remote receiver.
- **/
-s32 e1000e_get_phy_info_igp(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u16 data;
- bool link;
-
- ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
- if (ret_val)
- return ret_val;
-
- if (!link) {
- hw_dbg(hw, "Phy info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
- phy->polarity_correction = 1;
-
- ret_val = e1000_check_polarity_igp(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- phy->is_mdix = (data & IGP01E1000_PSSR_MDIX);
-
- if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
- ret_val = e1000_get_cable_length(hw);
- if (ret_val)
- return ret_val;
-
- ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data);
- if (ret_val)
- return ret_val;
-
- phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
-
- phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
- ? e1000_1000t_rx_status_ok
- : e1000_1000t_rx_status_not_ok;
- } else {
- phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
- phy->local_rx = e1000_1000t_rx_status_undefined;
- phy->remote_rx = e1000_1000t_rx_status_undefined;
- }
-
- return ret_val;
-}
-
-/**
- * e1000e_phy_sw_reset - PHY software reset
- * @hw: pointer to the HW structure
- *
- * Does a software reset of the PHY by reading the PHY control register and
- * setting/write the control register reset bit to the PHY.
- **/
-s32 e1000e_phy_sw_reset(struct e1000_hw *hw)
-{
- s32 ret_val;
- u16 phy_ctrl;
-
- ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
- if (ret_val)
- return ret_val;
-
- phy_ctrl |= MII_CR_RESET;
- ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
- if (ret_val)
- return ret_val;
-
- udelay(1);
-
- return ret_val;
-}
-
-/**
- * e1000e_phy_hw_reset_generic - PHY hardware reset
- * @hw: pointer to the HW structure
- *
- * Verify the reset block is not blocking us from resetting. Acquire
- * semaphore (if necessary) and read/set/write the device control reset
- * bit in the PHY. Wait the appropriate delay time for the device to
- * reset and release the semaphore (if necessary).
- **/
-s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
- u32 ctrl;
-
- ret_val = e1000_check_reset_block(hw);
- if (ret_val)
- return 0;
-
- ret_val = phy->ops.acquire_phy(hw);
- if (ret_val)
- return ret_val;
-
- ctrl = er32(CTRL);
- ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
- e1e_flush();
-
- udelay(phy->reset_delay_us);
-
- ew32(CTRL, ctrl);
- e1e_flush();
-
- udelay(150);
-
- phy->ops.release_phy(hw);
-
- return e1000_get_phy_cfg_done(hw);
-}
-
-/**
- * e1000e_get_cfg_done - Generic configuration done
- * @hw: pointer to the HW structure
- *
- * Generic function to wait 10 milli-seconds for configuration to complete
- * and return success.
- **/
-s32 e1000e_get_cfg_done(struct e1000_hw *hw)
-{
- mdelay(10);
- return 0;
-}
-
-/* Internal function pointers */
-
-/**
- * e1000_get_phy_cfg_done - Generic PHY configuration done
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family did not implement a family specific
- * get_cfg_done function.
- **/
-static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
-{
- if (hw->phy.ops.get_cfg_done)
- return hw->phy.ops.get_cfg_done(hw);
-
- return 0;
-}
-
-/**
- * e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
- * @hw: pointer to the HW structure
- *
- * When the silicon family has not implemented a forced speed/duplex
- * function for the PHY, simply return 0.
- **/
-static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
-{
- if (hw->phy.ops.force_speed_duplex)
- return hw->phy.ops.force_speed_duplex(hw);
-
- return 0;
-}
-
-/**
- * e1000e_get_phy_type_from_id - Get PHY type from id
- * @phy_id: phy_id read from the phy
- *
- * Returns the phy type from the id.
- **/
-enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
-{
- enum e1000_phy_type phy_type = e1000_phy_unknown;
-
- switch (phy_id) {
- case M88E1000_I_PHY_ID:
- case M88E1000_E_PHY_ID:
- case M88E1111_I_PHY_ID:
- case M88E1011_I_PHY_ID:
- phy_type = e1000_phy_m88;
- break;
- case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
- phy_type = e1000_phy_igp_2;
- break;
- case GG82563_E_PHY_ID:
- phy_type = e1000_phy_gg82563;
- break;
- case IGP03E1000_E_PHY_ID:
- phy_type = e1000_phy_igp_3;
- break;
- case IFE_E_PHY_ID:
- case IFE_PLUS_E_PHY_ID:
- case IFE_C_E_PHY_ID:
- phy_type = e1000_phy_ife;
- break;
- case BME1000_E_PHY_ID:
- case BME1000_E_PHY_ID_R2:
- phy_type = e1000_phy_bm;
- break;
- default:
- phy_type = e1000_phy_unknown;
- break;
- }
- return phy_type;
-}
-
-/**
- * e1000e_determine_phy_address - Determines PHY address.
- * @hw: pointer to the HW structure
- *
- * This uses a trial and error method to loop through possible PHY
- * addresses. It tests each by reading the PHY ID registers and
- * checking for a match.
- **/
-s32 e1000e_determine_phy_address(struct e1000_hw *hw)
-{
- s32 ret_val = -E1000_ERR_PHY_TYPE;
- u32 phy_addr= 0;
- u32 i = 0;
- enum e1000_phy_type phy_type = e1000_phy_unknown;
-
- do {
- for (phy_addr = 0; phy_addr < 4; phy_addr++) {
- hw->phy.addr = phy_addr;
- e1000e_get_phy_id(hw);
- phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
-
- /*
- * If phy_type is valid, break - we found our
- * PHY address
- */
- if (phy_type != e1000_phy_unknown) {
- ret_val = 0;
- break;
- }
- }
- i++;
- } while ((ret_val != 0) && (i < 100));
-
- return ret_val;
-}
-
-/**
- * e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
- * @page: page to access
- *
- * Returns the phy address for the page requested.
- **/
-static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
-{
- u32 phy_addr = 2;
-
- if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
- phy_addr = 1;
-
- return phy_addr;
-}
-
-/**
- * e1000e_write_phy_reg_bm - Write BM PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- **/
-s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
- u32 page_select = 0;
- u32 page = offset >> IGP_PAGE_SHIFT;
- u32 page_shift = 0;
-
- /* Page 800 works differently than the rest so it has its own func */
- if (page == BM_WUC_PAGE) {
- ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
- false);
- goto out;
- }
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- goto out;
-
- hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
- /*
- * Page select is register 31 for phy address 1 and 22 for
- * phy address 2 and 3. Page select is shifted only for
- * phy address 1.
- */
- if (hw->phy.addr == 1) {
- page_shift = IGP_PAGE_SHIFT;
- page_select = IGP01E1000_PHY_PAGE_SELECT;
- } else {
- page_shift = 0;
- page_select = BM_PHY_PAGE_SELECT;
- }
-
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
- (page << page_shift));
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- goto out;
- }
- }
-
- ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
-
- hw->phy.ops.release_phy(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000e_read_phy_reg_bm - Read BM PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting.
- **/
-s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
- u32 page_select = 0;
- u32 page = offset >> IGP_PAGE_SHIFT;
- u32 page_shift = 0;
-
- /* Page 800 works differently than the rest so it has its own func */
- if (page == BM_WUC_PAGE) {
- ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
- true);
- goto out;
- }
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val)
- goto out;
-
- hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
- /*
- * Page select is register 31 for phy address 1 and 22 for
- * phy address 2 and 3. Page select is shifted only for
- * phy address 1.
- */
- if (hw->phy.addr == 1) {
- page_shift = IGP_PAGE_SHIFT;
- page_select = IGP01E1000_PHY_PAGE_SELECT;
- } else {
- page_shift = 0;
- page_select = BM_PHY_PAGE_SELECT;
- }
-
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
- (page << page_shift));
- if (ret_val) {
- hw->phy.ops.release_phy(hw);
- goto out;
- }
- }
-
- ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
- hw->phy.ops.release_phy(hw);
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read or written
- * @data: pointer to the data to read or write
- * @read: determines if operation is read or write
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting. Note that procedure to read the wakeup
- * registers are different. It works as such:
- * 1) Set page 769, register 17, bit 2 = 1
- * 2) Set page to 800 for host (801 if we were manageability)
- * 3) Write the address using the address opcode (0x11)
- * 4) Read or write the data using the data opcode (0x12)
- * 5) Restore 769_17.2 to its original value
- **/
-static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
- u16 *data, bool read)
-{
- s32 ret_val;
- u16 reg = ((u16)offset) & PHY_REG_MASK;
- u16 phy_reg = 0;
- u8 phy_acquired = 1;
-
-
- ret_val = hw->phy.ops.acquire_phy(hw);
- if (ret_val) {
- phy_acquired = 0;
- goto out;
- }
-
- /* All operations in this function are phy address 1 */
- hw->phy.addr = 1;
-
- /* Set page 769 */
- e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
- (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
-
- ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
- if (ret_val)
- goto out;
-
- /* First clear bit 4 to avoid a power state change */
- phy_reg &= ~(BM_WUC_HOST_WU_BIT);
- ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
- if (ret_val)
- goto out;
-
- /* Write bit 2 = 1, and clear bit 4 to 769_17 */
- ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
- phy_reg | BM_WUC_ENABLE_BIT);
- if (ret_val)
- goto out;
-
- /* Select page 800 */
- ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
- (BM_WUC_PAGE << IGP_PAGE_SHIFT));
-
- /* Write the page 800 offset value using opcode 0x11 */
- ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
- if (ret_val)
- goto out;
-
- if (read) {
- /* Read the page 800 value using opcode 0x12 */
- ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
- data);
- } else {
- /* Read the page 800 value using opcode 0x12 */
- ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
- *data);
- }
-
- if (ret_val)
- goto out;
-
- /*
- * Restore 769_17.2 to its original value
- * Set page 769
- */
- e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
- (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
-
- /* Clear 769_17.2 */
- ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
-
-out:
- if (phy_acquired == 1)
- hw->phy.ops.release_phy(hw);
- return ret_val;
-}
-
-/**
- * e1000e_commit_phy - Soft PHY reset
- * @hw: pointer to the HW structure
- *
- * Performs a soft PHY reset on those that apply. This is a function pointer
- * entry point called by drivers.
- **/
-s32 e1000e_commit_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.commit_phy)
- return hw->phy.ops.commit_phy(hw);
-
- return 0;
-}
-
-/**
- * e1000_set_d0_lplu_state - Sets low power link up state for D0
- * @hw: pointer to the HW structure
- * @active: boolean used to enable/disable lplu
- *
- * Success returns 0, Failure returns 1
- *
- * The low power link up (lplu) state is set to the power management level D0
- * and SmartSpeed is disabled when active is true, else clear lplu for D0
- * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
- * is used during Dx states where the power conservation is most important.
- * During driver activity, SmartSpeed should be enabled so performance is
- * maintained. This is a function pointer entry point called by drivers.
- **/
-static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
-{
- if (hw->phy.ops.set_d0_lplu_state)
- return hw->phy.ops.set_d0_lplu_state(hw, active);
-
- return 0;
-}
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
deleted file mode 100644
index 6390f51ea6f..00000000000
--- a/drivers/net/e2100.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/* e2100.c: A Cabletron E2100 series ethernet driver for linux. */
-/*
- Written 1993-1994 by Donald Becker.
-
- Copyright 1994 by Donald Becker.
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- This is a driver for the Cabletron E2100 series ethercards.
-
- The Author may be reached as becker@scyld.com, or C/O
- Scyld Computing Corporation
- 410 Severn Ave., Suite 210
- Annapolis MD 21403
-
- The E2100 series ethercard is a fairly generic shared memory 8390
- implementation. The only unusual aspect is the way the shared memory
- registers are set: first you do an inb() in what is normally the
- station address region, and the low three bits of next outb() *address*
- is used as the write value for that register. Either someone wasn't
- too used to dem bit en bites, or they were trying to obfuscate the
- programming interface.
-
- There is an additional complication when setting the window on the packet
- buffer. You must first do a read into the packet buffer region with the
- low 8 address bits the address setting the page for the start of the packet
- buffer window, and then do the above operation. See mem_on() for details.
-
- One bug on the chip is that even a hard reset won't disable the memory
- window, usually resulting in a hung machine if mem_off() isn't called.
- If this happens, you must power down the machine for about 30 seconds.
-*/
-
-static const char version[] =
- "e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "8390.h"
-
-#define DRV_NAME "e2100"
-
-static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
-
-/* Offsets from the base_addr.
- Read from the ASIC register, and the low three bits of the next outb()
- address is used to set the corresponding register. */
-#define E21_NIC_OFFSET 0 /* Offset to the 8390 NIC. */
-#define E21_ASIC 0x10
-#define E21_MEM_ENABLE 0x10
-#define E21_MEM_ON 0x05 /* Enable memory in 16 bit mode. */
-#define E21_MEM_ON_8 0x07 /* Enable memory in 8 bit mode. */
-#define E21_MEM_BASE 0x11
-#define E21_IRQ_LOW 0x12 /* The low three bits of the IRQ number. */
-#define E21_IRQ_HIGH 0x14 /* The high IRQ bit and media select ... */
-#define E21_MEDIA 0x14 /* (alias). */
-#define E21_ALT_IFPORT 0x02 /* Set to use the other (BNC,AUI) port. */
-#define E21_BIG_MEM 0x04 /* Use a bigger (64K) buffer (we don't) */
-#define E21_SAPROM 0x10 /* Offset to station address data. */
-#define E21_IO_EXTENT 0x20
-
-static inline void mem_on(short port, volatile char __iomem *mem_base,
- unsigned char start_page )
-{
- /* This is a little weird: set the shared memory window by doing a
- read. The low address bits specify the starting page. */
- readb(mem_base+start_page);
- inb(port + E21_MEM_ENABLE);
- outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
-}
-
-static inline void mem_off(short port)
-{
- inb(port + E21_MEM_ENABLE);
- outb(0x00, port + E21_MEM_ENABLE);
-}
-
-/* In other drivers I put the TX pages first, but the E2100 window circuitry
- is designed to have a 4K Tx region last. The windowing circuitry wraps the
- window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring
- appear contiguously in the window. */
-#define E21_RX_START_PG 0x00 /* First page of RX buffer */
-#define E21_RX_STOP_PG 0x30 /* Last page +1 of RX ring */
-#define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */
-#define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */
-
-static int e21_probe1(struct net_device *dev, int ioaddr);
-
-static int e21_open(struct net_device *dev);
-static void e21_reset_8390(struct net_device *dev);
-static void e21_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void e21_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page);
-static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-
-static int e21_close(struct net_device *dev);
-
-
-/* Probe for the E2100 series ethercards. These cards have an 8390 at the
- base address and the station address at both offset 0x10 and 0x18. I read
- the station address from offset 0x18 to avoid the dataport of NE2000
- ethercards, and look for Ctron's unique ID (first three octets of the
- station address).
- */
-
-static int __init do_e2100_probe(struct net_device *dev)
-{
- int *port;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return e21_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (port = e21_probe_list; *port; port++) {
- dev->irq = irq;
- if (e21_probe1(dev, *port) == 0)
- return 0;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init e2100_probe(int unit)
-{
- struct net_device *dev = alloc_ei_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_e2100_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static int __init e21_probe1(struct net_device *dev, int ioaddr)
-{
- int i, status, retval;
- unsigned char *station_addr = dev->dev_addr;
- static unsigned version_printed;
-
- if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
- /* First check the station address for the Ctron prefix. */
- if (inb(ioaddr + E21_SAPROM + 0) != 0x00
- || inb(ioaddr + E21_SAPROM + 1) != 0x00
- || inb(ioaddr + E21_SAPROM + 2) != 0x1d) {
- retval = -ENODEV;
- goto out;
- }
-
- /* Verify by making certain that there is a 8390 at there. */
- outb(E8390_NODMA + E8390_STOP, ioaddr);
- udelay(1); /* we want to delay one I/O cycle - which is 2MHz */
- status = inb(ioaddr);
- if (status != 0x21 && status != 0x23) {
- retval = -ENODEV;
- goto out;
- }
-
- /* Read the station address PROM. */
- for (i = 0; i < 6; i++)
- station_addr[i] = inb(ioaddr + E21_SAPROM + i);
-
- inb(ioaddr + E21_MEDIA); /* Point to media selection. */
- outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- for (i = 0; i < 6; i++)
- printk(" %02X", station_addr[i]);
-
- if (dev->irq < 2) {
- int irqlist[] = {15,11,10,12,5,9,3,4}, i;
- for (i = 0; i < 8; i++)
- if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
- dev->irq = irqlist[i];
- break;
- }
- if (i >= 8) {
- printk(" unable to get IRQ %d.\n", dev->irq);
- retval = -EAGAIN;
- goto out;
- }
- } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */
- dev->irq = 9;
-
- /* The 8390 is at the base address. */
- dev->base_addr = ioaddr;
-
- ei_status.name = "E2100";
- ei_status.word16 = 1;
- ei_status.tx_start_page = E21_TX_START_PG;
- ei_status.rx_start_page = E21_RX_START_PG;
- ei_status.stop_page = E21_RX_STOP_PG;
- ei_status.saved_irq = dev->irq;
-
- /* Check the media port used. The port can be passed in on the
- low mem_end bits. */
- if (dev->mem_end & 15)
- dev->if_port = dev->mem_end & 7;
- else {
- dev->if_port = 0;
- inb(ioaddr + E21_MEDIA); /* Turn automatic media detection on. */
- for(i = 0; i < 6; i++)
- if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
- dev->if_port = 1;
- break;
- }
- }
-
- /* Never map in the E21 shared memory unless you are actively using it.
- Also, the shared memory has effective only one setting -- spread all
- over the 128K region! */
- if (dev->mem_start == 0)
- dev->mem_start = 0xd0000;
-
- ei_status.mem = ioremap(dev->mem_start, 2*1024);
- if (!ei_status.mem) {
- printk("unable to remap memory\n");
- retval = -EAGAIN;
- goto out;
- }
-
-#ifdef notdef
- /* These values are unused. The E2100 has a 2K window into the packet
- buffer. The window can be set to start on any page boundary. */
- ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
- dev->mem_end = ei_status.rmem_end = dev->mem_start + 2*1024;
-#endif
-
- printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
- dev->if_port ? "secondary" : "primary", dev->mem_start);
-
- ei_status.reset_8390 = &e21_reset_8390;
- ei_status.block_input = &e21_block_input;
- ei_status.block_output = &e21_block_output;
- ei_status.get_8390_hdr = &e21_get_8390_hdr;
- dev->open = &e21_open;
- dev->stop = &e21_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
- NS8390_init(dev, 0);
-
- retval = register_netdev(dev);
- if (retval)
- goto out;
- return 0;
-out:
- release_region(ioaddr, E21_IO_EXTENT);
- return retval;
-}
-
-static int
-e21_open(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
- int retval;
-
- if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)))
- return retval;
-
- /* Set the interrupt line and memory base on the hardware. */
- inb(ioaddr + E21_IRQ_LOW);
- outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
- inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */
- outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
- + (dev->if_port ? E21_ALT_IFPORT : 0));
- inb(ioaddr + E21_MEM_BASE);
- outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
-
- ei_open(dev);
- return 0;
-}
-
-static void
-e21_reset_8390(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
-
- outb(0x01, ioaddr);
- if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
- ei_status.txing = 0;
-
- /* Set up the ASIC registers, just in case something changed them. */
-
- if (ei_debug > 1) printk("reset done\n");
- return;
-}
-
-/* Grab the 8390 specific header. We put the 2k window so the header page
- appears at the start of the shared memory. */
-
-static void
-e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-
- short ioaddr = dev->base_addr;
- char __iomem *shared_mem = ei_status.mem;
-
- mem_on(ioaddr, shared_mem, ring_page);
-
-#ifdef notdef
- /* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
-#else
- ((unsigned int*)hdr)[0] = readl(shared_mem);
-#endif
-
- /* Turn off memory access: we would need to reprogram the window anyway. */
- mem_off(ioaddr);
-
-}
-
-/* Block input and output are easy on shared memory ethercards.
- The E21xx makes block_input() especially easy by wrapping the top
- ring buffer to the bottom automatically. */
-static void
-e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- short ioaddr = dev->base_addr;
- char __iomem *shared_mem = ei_status.mem;
-
- mem_on(ioaddr, shared_mem, (ring_offset>>8));
-
- memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count);
-
- mem_off(ioaddr);
-}
-
-static void
-e21_block_output(struct net_device *dev, int count, const unsigned char *buf,
- int start_page)
-{
- short ioaddr = dev->base_addr;
- volatile char __iomem *shared_mem = ei_status.mem;
-
- /* Set the shared memory window start by doing a read, with the low address
- bits specifying the starting page. */
- readb(shared_mem + start_page);
- mem_on(ioaddr, shared_mem, start_page);
-
- memcpy_toio(shared_mem, buf, count);
- mem_off(ioaddr);
-}
-
-static int
-e21_close(struct net_device *dev)
-{
- short ioaddr = dev->base_addr;
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
- free_irq(dev->irq, dev);
- dev->irq = ei_status.saved_irq;
-
- /* Shut off the interrupt line and secondary interface. */
- inb(ioaddr + E21_IRQ_LOW);
- outb(0, ioaddr + E21_ASIC);
- inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */
- outb(0, ioaddr + E21_ASIC);
-
- ei_close(dev);
-
- /* Double-check that the memory has been turned off, because really
- really bad things happen if it isn't. */
- mem_off(ioaddr);
-
- return 0;
-}
-
-
-#ifdef MODULE
-#define MAX_E21_CARDS 4 /* Max number of E21 cards per module */
-static struct net_device *dev_e21[MAX_E21_CARDS];
-static int io[MAX_E21_CARDS];
-static int irq[MAX_E21_CARDS];
-static int mem[MAX_E21_CARDS];
-static int xcvr[MAX_E21_CARDS]; /* choose int. or ext. xcvr */
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
-module_param_array(xcvr, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s)");
-MODULE_PARM_DESC(mem, " memory base address(es)");
-MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
-MODULE_DESCRIPTION("Cabletron E2100 ISA ethernet driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-
-int __init init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- dev = alloc_ei_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_start = mem[this_dev];
- dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */
- if (do_e2100_probe(dev) == 0) {
- dev_e21[found++] = dev;
- continue;
- }
- free_netdev(dev);
- printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: e21_close() handles free_irq */
- iounmap(ei_status.mem);
- release_region(dev->base_addr, E21_IO_EXTENT);
-}
-
-void __exit
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
- struct net_device *dev = dev_e21[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
deleted file mode 100644
index 1f11350e16c..00000000000
--- a/drivers/net/eepro.c
+++ /dev/null
@@ -1,1817 +0,0 @@
-/* eepro.c: Intel EtherExpress Pro/10 device driver for Linux. */
-/*
- Written 1994, 1995,1996 by Bao C. Ha.
-
- Copyright (C) 1994, 1995,1996 by Bao C. Ha.
-
- This software may be used and distributed
- according to the terms of the GNU General Public License,
- incorporated herein by reference.
-
- The author may be reached at bao.ha@srs.gov
- or 418 Hastings Place, Martinez, GA 30907.
-
- Things remaining to do:
- Better record keeping of errors.
- Eliminate transmit interrupt to reduce overhead.
- Implement "concurrent processing". I won't be doing it!
-
- Bugs:
-
- If you have a problem of not detecting the 82595 during a
- reboot (warm reset), disable the FLASH memory should fix it.
- This is a compatibility hardware problem.
-
- Versions:
- 0.13b basic ethtool support (aris, 09/13/2004)
- 0.13a in memory shortage, drop packets also in board
- (Michael Westermann <mw@microdata-pos.de>, 07/30/2002)
- 0.13 irq sharing, rewrote probe function, fixed a nasty bug in
- hardware_send_packet and a major cleanup (aris, 11/08/2001)
- 0.12d fixing a problem with single card detected as eight eth devices
- fixing a problem with sudden drop in card performance
- (chris (asdn@go2.pl), 10/29/2001)
- 0.12c fixing some problems with old cards (aris, 01/08/2001)
- 0.12b misc fixes (aris, 06/26/2000)
- 0.12a port of version 0.12a of 2.2.x kernels to 2.3.x
- (aris (aris@conectiva.com.br), 05/19/2000)
- 0.11e some tweaks about multiple cards support (PdP, jul/aug 1999)
- 0.11d added __initdata, __init stuff; call spin_lock_init
- in eepro_probe1. Replaced "eepro" by dev->name. Augmented
- the code protected by spin_lock in interrupt routine
- (PdP, 12/12/1998)
- 0.11c minor cleanup (PdP, RMC, 09/12/1998)
- 0.11b Pascal Dupuis (dupuis@lei.ucl.ac.be): works as a module
- under 2.1.xx. Debug messages are flagged as KERN_DEBUG to
- avoid console flooding. Added locking at critical parts. Now
- the dawn thing is SMP safe.
- 0.11a Attempt to get 2.1.xx support up (RMC)
- 0.11 Brian Candler added support for multiple cards. Tested as
- a module, no idea if it works when compiled into kernel.
-
- 0.10e Rick Bressler notified me that ifconfig up;ifconfig down fails
- because the irq is lost somewhere. Fixed that by moving
- request_irq and free_irq to eepro_open and eepro_close respectively.
- 0.10d Ugh! Now Wakeup works. Was seriously broken in my first attempt.
- I'll need to find a way to specify an ioport other than
- the default one in the PnP case. PnP definitively sucks.
- And, yes, this is not the only reason.
- 0.10c PnP Wakeup Test for 595FX. uncomment #define PnPWakeup;
- to use.
- 0.10b Should work now with (some) Pro/10+. At least for
- me (and my two cards) it does. _No_ guarantee for
- function with non-Pro/10+ cards! (don't have any)
- (RMC, 9/11/96)
-
- 0.10 Added support for the Etherexpress Pro/10+. The
- IRQ map was changed significantly from the old
- pro/10. The new interrupt map was provided by
- Rainer M. Canavan (Canavan@Zeus.cs.bonn.edu).
- (BCH, 9/3/96)
-
- 0.09 Fixed a race condition in the transmit algorithm,
- which causes crashes under heavy load with fast
- pentium computers. The performance should also
- improve a bit. The size of RX buffer, and hence
- TX buffer, can also be changed via lilo or insmod.
- (BCH, 7/31/96)
-
- 0.08 Implement 32-bit I/O for the 82595TX and 82595FX
- based lan cards. Disable full-duplex mode if TPE
- is not used. (BCH, 4/8/96)
-
- 0.07a Fix a stat report which counts every packet as a
- heart-beat failure. (BCH, 6/3/95)
-
- 0.07 Modified to support all other 82595-based lan cards.
- The IRQ vector of the EtherExpress Pro will be set
- according to the value saved in the EEPROM. For other
- cards, I will do autoirq_request() to grab the next
- available interrupt vector. (BCH, 3/17/95)
-
- 0.06a,b Interim released. Minor changes in the comments and
- print out format. (BCH, 3/9/95 and 3/14/95)
-
- 0.06 First stable release that I am comfortable with. (BCH,
- 3/2/95)
-
- 0.05 Complete testing of multicast. (BCH, 2/23/95)
-
- 0.04 Adding multicast support. (BCH, 2/14/95)
-
- 0.03 First widely alpha release for public testing.
- (BCH, 2/14/95)
-
-*/
-
-static const char version[] =
- "eepro.c: v0.13b 09/13/2004 aris@cathedrallabs.org\n";
-
-#include <linux/module.h>
-
-/*
- Sources:
-
- This driver wouldn't have been written without the availability
- of the Crynwr's Lan595 driver source code. It helps me to
- familiarize with the 82595 chipset while waiting for the Intel
- documentation. I also learned how to detect the 82595 using
- the packet driver's technique.
-
- This driver is written by cutting and pasting the skeleton.c driver
- provided by Donald Becker. I also borrowed the EEPROM routine from
- Donald Becker's 82586 driver.
-
- Datasheet for the Intel 82595 (including the TX and FX version). It
- provides just enough info that the casual reader might think that it
- documents the i82595.
-
- The User Manual for the 82595. It provides a lot of the missing
- information.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <linux/ethtool.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define DRV_NAME "eepro"
-#define DRV_VERSION "0.13c"
-
-#define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
-/* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
-#define SLOW_DOWN inb(0x80)
-/* udelay(2) */
-#define compat_init_data __initdata
-enum iftype { AUI=0, BNC=1, TPE=2 };
-
-/* First, a few definitions that the brave might change. */
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int eepro_portlist[] compat_init_data =
- { 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
-/* note: 0x300 is default, the 595FX supports ALL IO Ports
- from 0x000 to 0x3F0, some of which are reserved in PCs */
-
-/* To try the (not-really PnP Wakeup: */
-/*
-#define PnPWakeup
-*/
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 0
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define EEPRO_IO_EXTENT 16
-
-/* Different 82595 chips */
-#define LAN595 0
-#define LAN595TX 1
-#define LAN595FX 2
-#define LAN595FX_10ISA 3
-
-/* Information that need to be kept for each board. */
-struct eepro_local {
- unsigned rx_start;
- unsigned tx_start; /* start of the transmit chain */
- int tx_last; /* pointer to last packet in the transmit chain */
- unsigned tx_end; /* end of the transmit chain (plus 1) */
- int eepro; /* 1 for the EtherExpress Pro/10,
- 2 for the EtherExpress Pro/10+,
- 3 for the EtherExpress 10 (blue cards),
- 0 for other 82595-based lan cards. */
- int version; /* a flag to indicate if this is a TX or FX
- version of the 82595 chip. */
- int stepping;
-
- spinlock_t lock; /* Serializing lock */
-
- unsigned rcv_ram; /* pre-calculated space for rx */
- unsigned xmt_ram; /* pre-calculated space for tx */
- unsigned char xmt_bar;
- unsigned char xmt_lower_limit_reg;
- unsigned char xmt_upper_limit_reg;
- short xmt_lower_limit;
- short xmt_upper_limit;
- short rcv_lower_limit;
- short rcv_upper_limit;
- unsigned char eeprom_reg;
- unsigned short word[8];
-};
-
-/* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00 /* Etherexpress Pro/10 */
-#define SA_ADDR1 0xaa
-#define SA_ADDR2 0x00
-
-#define GetBit(x,y) ((x & (1<<y))>>y)
-
-/* EEPROM Word 0: */
-#define ee_PnP 0 /* Plug 'n Play enable bit */
-#define ee_Word1 1 /* Word 1? */
-#define ee_BusWidth 2 /* 8/16 bit */
-#define ee_FlashAddr 3 /* Flash Address */
-#define ee_FlashMask 0x7 /* Mask */
-#define ee_AutoIO 6 /* */
-#define ee_reserved0 7 /* =0! */
-#define ee_Flash 8 /* Flash there? */
-#define ee_AutoNeg 9 /* Auto Negotiation enabled? */
-#define ee_IO0 10 /* IO Address LSB */
-#define ee_IO0Mask 0x /*...*/
-#define ee_IO1 15 /* IO MSB */
-
-/* EEPROM Word 1: */
-#define ee_IntSel 0 /* Interrupt */
-#define ee_IntMask 0x7
-#define ee_LI 3 /* Link Integrity 0= enabled */
-#define ee_PC 4 /* Polarity Correction 0= enabled */
-#define ee_TPE_AUI 5 /* PortSelection 1=TPE */
-#define ee_Jabber 6 /* Jabber prevention 0= enabled */
-#define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */
-#define ee_SMOUT 8 /* SMout Pin Control 0= Input */
-#define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */
-#define ee_reserved1 10 /* .. 12 =0! */
-#define ee_AltReady 13 /* Alternate Ready, 0=normal */
-#define ee_reserved2 14 /* =0! */
-#define ee_Duplex 15
-
-/* Word2,3,4: */
-#define ee_IA5 0 /*bit start for individual Addr Byte 5 */
-#define ee_IA4 8 /*bit start for individual Addr Byte 5 */
-#define ee_IA3 0 /*bit start for individual Addr Byte 5 */
-#define ee_IA2 8 /*bit start for individual Addr Byte 5 */
-#define ee_IA1 0 /*bit start for individual Addr Byte 5 */
-#define ee_IA0 8 /*bit start for individual Addr Byte 5 */
-
-/* Word 5: */
-#define ee_BNC_TPE 0 /* 0=TPE */
-#define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
-#define ee_BootTypeMask 0x3
-#define ee_NumConn 3 /* Number of Connections 0= One or Two */
-#define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */
-#define ee_PortTPE 5
-#define ee_PortBNC 6
-#define ee_PortAUI 7
-#define ee_PowerMgt 10 /* 0= disabled */
-#define ee_CP 13 /* Concurrent Processing */
-#define ee_CPMask 0x7
-
-/* Word 6: */
-#define ee_Stepping 0 /* Stepping info */
-#define ee_StepMask 0x0F
-#define ee_BoardID 4 /* Manucaturer Board ID, reserved */
-#define ee_BoardMask 0x0FFF
-
-/* Word 7: */
-#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */
-#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
-
-/*..*/
-#define ee_SIZE 0x40 /* total EEprom Size */
-#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
-
-
-/* Card identification via EEprom: */
-#define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */
-#define ee_addr_id 0x11 /* Word offset for Card ID */
-#define ee_addr_SN 0x12 /* Serial Number */
-#define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */
-
-
-#define ee_vendor_intel0 0x25 /* Vendor ID Intel */
-#define ee_vendor_intel1 0xD4
-#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
-#define ee_id_eepro10p1 0x31
-
-#define TX_TIMEOUT 40
-
-/* Index to functions, as function prototypes. */
-
-static int eepro_probe1(struct net_device *dev, int autoprobe);
-static int eepro_open(struct net_device *dev);
-static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t eepro_interrupt(int irq, void *dev_id);
-static void eepro_rx(struct net_device *dev);
-static void eepro_transmit_interrupt(struct net_device *dev);
-static int eepro_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-static void eepro_tx_timeout (struct net_device *dev);
-
-static int read_eeprom(int ioaddr, int location, struct net_device *dev);
-static int hardware_send_packet(struct net_device *dev, void *buf, short length);
-static int eepro_grab_irq(struct net_device *dev);
-
-/*
- Details of the i82595.
-
-You will need either the datasheet or the user manual to understand what
-is going on here. The 82595 is very different from the 82586, 82593.
-
-The receive algorithm in eepro_rx() is just an implementation of the
-RCV ring structure that the Intel 82595 imposes at the hardware level.
-The receive buffer is set at 24K, and the transmit buffer is 8K. I
-am assuming that the total buffer memory is 32K, which is true for the
-Intel EtherExpress Pro/10. If it is less than that on a generic card,
-the driver will be broken.
-
-The transmit algorithm in the hardware_send_packet() is similar to the
-one in the eepro_rx(). The transmit buffer is a ring linked list.
-I just queue the next available packet to the end of the list. In my
-system, the 82595 is so fast that the list seems to always contain a
-single packet. In other systems with faster computers and more congested
-network traffics, the ring linked list should improve performance by
-allowing up to 8K worth of packets to be queued.
-
-The sizes of the receive and transmit buffers can now be changed via lilo
-or insmod. Lilo uses the appended line "ether=io,irq,debug,rx-buffer,eth0"
-where rx-buffer is in KB unit. Modules uses the parameter mem which is
-also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."
-The receive buffer has to be more than 3K or less than 29K. Otherwise,
-it is reset to the default of 24K, and, hence, 8K for the trasnmit
-buffer (transmit-buffer = 32K - receive-buffer).
-
-*/
-#define RAM_SIZE 0x8000
-
-#define RCV_HEADER 8
-#define RCV_DEFAULT_RAM 0x6000
-
-#define XMT_HEADER 8
-#define XMT_DEFAULT_RAM (RAM_SIZE - RCV_DEFAULT_RAM)
-
-#define XMT_START_PRO RCV_DEFAULT_RAM
-#define XMT_START_10 0x0000
-#define RCV_START_PRO 0x0000
-#define RCV_START_10 XMT_DEFAULT_RAM
-
-#define RCV_DONE 0x0008
-#define RX_OK 0x2000
-#define RX_ERROR 0x0d81
-
-#define TX_DONE_BIT 0x0080
-#define TX_OK 0x2000
-#define CHAIN_BIT 0x8000
-#define XMT_STATUS 0x02
-#define XMT_CHAIN 0x04
-#define XMT_COUNT 0x06
-
-#define BANK0_SELECT 0x00
-#define BANK1_SELECT 0x40
-#define BANK2_SELECT 0x80
-
-/* Bank 0 registers */
-#define COMMAND_REG 0x00 /* Register 0 */
-#define MC_SETUP 0x03
-#define XMT_CMD 0x04
-#define DIAGNOSE_CMD 0x07
-#define RCV_ENABLE_CMD 0x08
-#define RCV_DISABLE_CMD 0x0a
-#define STOP_RCV_CMD 0x0b
-#define RESET_CMD 0x0e
-#define POWER_DOWN_CMD 0x18
-#define RESUME_XMT_CMD 0x1c
-#define SEL_RESET_CMD 0x1e
-#define STATUS_REG 0x01 /* Register 1 */
-#define RX_INT 0x02
-#define TX_INT 0x04
-#define EXEC_STATUS 0x30
-#define ID_REG 0x02 /* Register 2 */
-#define R_ROBIN_BITS 0xc0 /* round robin counter */
-#define ID_REG_MASK 0x2c
-#define ID_REG_SIG 0x24
-#define AUTO_ENABLE 0x10
-#define INT_MASK_REG 0x03 /* Register 3 */
-#define RX_STOP_MASK 0x01
-#define RX_MASK 0x02
-#define TX_MASK 0x04
-#define EXEC_MASK 0x08
-#define ALL_MASK 0x0f
-#define IO_32_BIT 0x10
-#define RCV_BAR 0x04 /* The following are word (16-bit) registers */
-#define RCV_STOP 0x06
-
-#define XMT_BAR_PRO 0x0a
-#define XMT_BAR_10 0x0b
-
-#define HOST_ADDRESS_REG 0x0c
-#define IO_PORT 0x0e
-#define IO_PORT_32_BIT 0x0c
-
-/* Bank 1 registers */
-#define REG1 0x01
-#define WORD_WIDTH 0x02
-#define INT_ENABLE 0x80
-#define INT_NO_REG 0x02
-#define RCV_LOWER_LIMIT_REG 0x08
-#define RCV_UPPER_LIMIT_REG 0x09
-
-#define XMT_LOWER_LIMIT_REG_PRO 0x0a
-#define XMT_UPPER_LIMIT_REG_PRO 0x0b
-#define XMT_LOWER_LIMIT_REG_10 0x0b
-#define XMT_UPPER_LIMIT_REG_10 0x0a
-
-/* Bank 2 registers */
-#define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */
-#define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */
-#define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */
-#define REG2 0x02
-#define PRMSC_Mode 0x01
-#define Multi_IA 0x20
-#define REG3 0x03
-#define TPE_BIT 0x04
-#define BNC_BIT 0x20
-#define REG13 0x0d
-#define FDX 0x00
-#define A_N_ENABLE 0x02
-
-#define I_ADD_REG0 0x04
-#define I_ADD_REG1 0x05
-#define I_ADD_REG2 0x06
-#define I_ADD_REG3 0x07
-#define I_ADD_REG4 0x08
-#define I_ADD_REG5 0x09
-
-#define EEPROM_REG_PRO 0x0a
-#define EEPROM_REG_10 0x0b
-
-#define EESK 0x01
-#define EECS 0x02
-#define EEDI 0x04
-#define EEDO 0x08
-
-/* do a full reset */
-#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr)
-
-/* do a nice reset */
-#define eepro_sel_reset(ioaddr) { \
- outb(SEL_RESET_CMD, ioaddr); \
- SLOW_DOWN; \
- SLOW_DOWN; \
- }
-
-/* disable all interrupts */
-#define eepro_dis_int(ioaddr) outb(ALL_MASK, ioaddr + INT_MASK_REG)
-
-/* clear all interrupts */
-#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
-
-/* enable tx/rx */
-#define eepro_en_int(ioaddr) outb(ALL_MASK & ~(RX_MASK | TX_MASK), \
- ioaddr + INT_MASK_REG)
-
-/* enable exec event interrupt */
-#define eepro_en_intexec(ioaddr) outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG)
-
-/* enable rx */
-#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)
-
-/* disable rx */
-#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)
-
-/* switch bank */
-#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
-#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
-#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
-
-/* enable interrupt line */
-#define eepro_en_intline(ioaddr) outb(inb(ioaddr + REG1) | INT_ENABLE,\
- ioaddr + REG1)
-
-/* disable interrupt line */
-#define eepro_dis_intline(ioaddr) outb(inb(ioaddr + REG1) & 0x7f, \
- ioaddr + REG1);
-
-/* set diagnose flag */
-#define eepro_diag(ioaddr) outb(DIAGNOSE_CMD, ioaddr)
-
-/* ack for rx int */
-#define eepro_ack_rx(ioaddr) outb (RX_INT, ioaddr + STATUS_REG)
-
-/* ack for tx int */
-#define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG)
-
-/* a complete sel reset */
-#define eepro_complete_selreset(ioaddr) { \
- dev->stats.tx_errors++;\
- eepro_sel_reset(ioaddr);\
- lp->tx_end = \
- lp->xmt_lower_limit;\
- lp->tx_start = lp->tx_end;\
- lp->tx_last = 0;\
- dev->trans_start = jiffies;\
- netif_wake_queue(dev);\
- eepro_en_rx(ioaddr);\
- }
-
-/* Check for a network adaptor of this type, and return '0' if one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-static int __init do_eepro_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
-
-#ifdef PnPWakeup
- /* XXXX for multiple cards should this only be run once? */
-
- /* Wakeup: */
- #define WakeupPort 0x279
- #define WakeupSeq {0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,\
- 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,\
- 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,\
- 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43}
-
- {
- unsigned short int WS[32]=WakeupSeq;
-
- if (request_region(WakeupPort, 2, "eepro wakeup")) {
- if (net_debug>5)
- printk(KERN_DEBUG "Waking UP\n");
-
- outb_p(0,WakeupPort);
- outb_p(0,WakeupPort);
- for (i=0; i<32; i++) {
- outb_p(WS[i],WakeupPort);
- if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
- }
-
- release_region(WakeupPort, 2);
- } else
- printk(KERN_WARNING "PnP wakeup region busy!\n");
- }
-#endif
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return eepro_probe1(dev, 0);
-
- else if (base_addr != 0) /* Don't probe at all. */
- return -ENXIO;
-
- for (i = 0; eepro_portlist[i]; i++) {
- dev->base_addr = eepro_portlist[i];
- dev->irq = irq;
- if (eepro_probe1(dev, 1) == 0)
- return 0;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init eepro_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct eepro_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_eepro_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static void __init printEEPROMInfo(struct net_device *dev)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
- int ioaddr = dev->base_addr;
- unsigned short Word;
- int i,j;
-
- j = ee_Checksum;
- for (i = 0; i < 8; i++)
- j += lp->word[i];
- for ( ; i < ee_SIZE; i++)
- j += read_eeprom(ioaddr, i, dev);
-
- printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);
-
- Word = lp->word[0];
- printk(KERN_DEBUG "Word0:\n");
- printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
- printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
- printk(KERN_DEBUG " AutoNegotiation: %d\n",GetBit(Word,ee_AutoNeg));
- printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);
-
- if (net_debug>4) {
- Word = lp->word[1];
- printk(KERN_DEBUG "Word1:\n");
- printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask);
- printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI));
- printk(KERN_DEBUG " PC: %d\n", GetBit(Word,ee_PC));
- printk(KERN_DEBUG " TPE/AUI: %d\n", GetBit(Word,ee_TPE_AUI));
- printk(KERN_DEBUG " Jabber: %d\n", GetBit(Word,ee_Jabber));
- printk(KERN_DEBUG " AutoPort: %d\n", !GetBit(Word,ee_AutoPort));
- printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
- }
-
- Word = lp->word[5];
- printk(KERN_DEBUG "Word5:\n");
- printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
- printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
- printk(KERN_DEBUG " Has ");
- if (GetBit(Word,ee_PortTPE)) printk(KERN_DEBUG "TPE ");
- if (GetBit(Word,ee_PortBNC)) printk(KERN_DEBUG "BNC ");
- if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");
- printk(KERN_DEBUG "port(s) \n");
-
- Word = lp->word[6];
- printk(KERN_DEBUG "Word6:\n");
- printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);
- printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);
-
- Word = lp->word[7];
- printk(KERN_DEBUG "Word7:\n");
- printk(KERN_DEBUG " INT to IRQ:\n");
-
- for (i=0, j=0; i<15; i++)
- if (GetBit(Word,i)) printk(KERN_DEBUG " INT%d -> IRQ %d;",j++,i);
-
- printk(KERN_DEBUG "\n");
-}
-
-/* function to recalculate the limits of buffer based on rcv_ram */
-static void eepro_recalc (struct net_device *dev)
-{
- struct eepro_local * lp;
-
- lp = netdev_priv(dev);
- lp->xmt_ram = RAM_SIZE - lp->rcv_ram;
-
- if (lp->eepro == LAN595FX_10ISA) {
- lp->xmt_lower_limit = XMT_START_10;
- lp->xmt_upper_limit = (lp->xmt_ram - 2);
- lp->rcv_lower_limit = lp->xmt_ram;
- lp->rcv_upper_limit = (RAM_SIZE - 2);
- }
- else {
- lp->rcv_lower_limit = RCV_START_PRO;
- lp->rcv_upper_limit = (lp->rcv_ram - 2);
- lp->xmt_lower_limit = lp->rcv_ram;
- lp->xmt_upper_limit = (RAM_SIZE - 2);
- }
-}
-
-/* prints boot-time info */
-static void __init eepro_print_info (struct net_device *dev)
-{
- struct eepro_local * lp = netdev_priv(dev);
- int i;
- const char * ifmap[] = {"AUI", "10Base2", "10BaseT"};
- DECLARE_MAC_BUF(mac);
-
- i = inb(dev->base_addr + ID_REG);
- printk(KERN_DEBUG " id: %#x ",i);
- printk(" io: %#x ", (unsigned)dev->base_addr);
-
- switch (lp->eepro) {
- case LAN595FX_10ISA:
- printk("%s: Intel EtherExpress 10 ISA\n at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- case LAN595FX:
- printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- case LAN595TX:
- printk("%s: Intel EtherExpress Pro/10 ISA at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- case LAN595:
- printk("%s: Intel 82595-based lan card at %#x,",
- dev->name, (unsigned)dev->base_addr);
- break;
- }
-
- printk(" %s", print_mac(mac, dev->dev_addr));
-
- if (net_debug > 3)
- printk(KERN_DEBUG ", %dK RCV buffer",
- (int)(lp->rcv_ram)/1024);
-
- if (dev->irq > 2)
- printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
- else
- printk(", %s.\n", ifmap[dev->if_port]);
-
- if (net_debug > 3) {
- i = lp->word[5];
- if (i & 0x2000) /* bit 13 of EEPROM word 5 */
- printk(KERN_DEBUG "%s: Concurrent Processing is "
- "enabled but not used!\n", dev->name);
- }
-
- /* Check the station address for the manufacturer's code */
- if (net_debug>3)
- printEEPROMInfo(dev);
-}
-
-static const struct ethtool_ops eepro_ethtool_ops;
-
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probe avoids doing writes, and
- verifies that the correct device exists and functions. */
-
-static int __init eepro_probe1(struct net_device *dev, int autoprobe)
-{
- unsigned short station_addr[3], id, counter;
- int i;
- struct eepro_local *lp;
- int ioaddr = dev->base_addr;
- int err;
-
- /* Grab the region so we can find another board if autoIRQ fails. */
- if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
- if (!autoprobe)
- printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
- ioaddr);
- return -EBUSY;
- }
-
- /* Now, we are going to check for the signature of the
- ID_REG (register 2 of bank 0) */
-
- id = inb(ioaddr + ID_REG);
-
- if ((id & ID_REG_MASK) != ID_REG_SIG)
- goto exit;
-
- /* We seem to have the 82595 signature, let's
- play with its counter (last 2 bits of
- register 2 of bank 0) to be sure. */
-
- counter = id & R_ROBIN_BITS;
-
- if ((inb(ioaddr + ID_REG) & R_ROBIN_BITS) != (counter + 0x40))
- goto exit;
-
- lp = netdev_priv(dev);
- memset(lp, 0, sizeof(struct eepro_local));
- lp->xmt_bar = XMT_BAR_PRO;
- lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
- lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
- lp->eeprom_reg = EEPROM_REG_PRO;
- spin_lock_init(&lp->lock);
-
- /* Now, get the ethernet hardware address from
- the EEPROM */
- station_addr[0] = read_eeprom(ioaddr, 2, dev);
-
- /* FIXME - find another way to know that we've found
- * an Etherexpress 10
- */
- if (station_addr[0] == 0x0000 || station_addr[0] == 0xffff) {
- lp->eepro = LAN595FX_10ISA;
- lp->eeprom_reg = EEPROM_REG_10;
- lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
- lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
- lp->xmt_bar = XMT_BAR_10;
- station_addr[0] = read_eeprom(ioaddr, 2, dev);
- }
-
- /* get all words at once. will be used here and for ethtool */
- for (i = 0; i < 8; i++) {
- lp->word[i] = read_eeprom(ioaddr, i, dev);
- }
- station_addr[1] = lp->word[3];
- station_addr[2] = lp->word[4];
-
- if (!lp->eepro) {
- if (lp->word[7] == ee_FX_INT2IRQ)
- lp->eepro = 2;
- else if (station_addr[2] == SA_ADDR1)
- lp->eepro = 1;
- }
-
- /* Fill in the 'dev' fields. */
- for (i=0; i < 6; i++)
- dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
-
- /* RX buffer must be more than 3K and less than 29K */
- if (dev->mem_end < 3072 || dev->mem_end > 29696)
- lp->rcv_ram = RCV_DEFAULT_RAM;
-
- /* calculate {xmt,rcv}_{lower,upper}_limit */
- eepro_recalc(dev);
-
- if (GetBit(lp->word[5], ee_BNC_TPE))
- dev->if_port = BNC;
- else
- dev->if_port = TPE;
-
- if (dev->irq < 2 && lp->eepro != 0) {
- /* Mask off INT number */
- int count = lp->word[1] & 7;
- unsigned irqMask = lp->word[7];
-
- while (count--)
- irqMask &= irqMask - 1;
-
- count = ffs(irqMask);
-
- if (count)
- dev->irq = count - 1;
-
- if (dev->irq < 2) {
- printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
- goto exit;
- } else if (dev->irq == 2) {
- dev->irq = 9;
- }
- }
-
- dev->open = eepro_open;
- dev->stop = eepro_close;
- dev->hard_start_xmit = eepro_send_packet;
- dev->set_multicast_list = &set_multicast_list;
- dev->tx_timeout = eepro_tx_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
- dev->ethtool_ops = &eepro_ethtool_ops;
-
- /* print boot time info */
- eepro_print_info(dev);
-
- /* reset 82595 */
- eepro_reset(ioaddr);
-
- err = register_netdev(dev);
- if (err)
- goto err;
- return 0;
-exit:
- err = -ENODEV;
-err:
- release_region(dev->base_addr, EEPRO_IO_EXTENT);
- return err;
-}
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine should set everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
- */
-
-static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
-static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1};
-static int eepro_grab_irq(struct net_device *dev)
-{
- int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 };
- int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
-
- eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
-
- /* Enable the interrupt line. */
- eepro_en_intline(ioaddr);
-
- /* be CAREFUL, BANK 0 now */
- eepro_sw2bank0(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- /* Let EXEC event to interrupt */
- eepro_en_intexec(ioaddr);
-
- do {
- eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
-
- temp_reg = inb(ioaddr + INT_NO_REG);
- outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG);
-
- eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
-
- if (request_irq (*irqp, NULL, IRQF_SHARED, "bogus", dev) != EBUSY) {
- unsigned long irq_mask;
- /* Twinkle the interrupt, and check if it's seen */
- irq_mask = probe_irq_on();
-
- eepro_diag(ioaddr); /* RESET the 82595 */
- mdelay(20);
-
- if (*irqp == probe_irq_off(irq_mask)) /* It's a good IRQ line */
- break;
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
- }
- } while (*++irqp);
-
- eepro_sw2bank1(ioaddr); /* Switch back to Bank 1 */
-
- /* Disable the physical interrupt line. */
- eepro_dis_intline(ioaddr);
-
- eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
-
- /* Mask all the interrupts. */
- eepro_dis_int(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- return dev->irq;
-}
-
-static int eepro_open(struct net_device *dev)
-{
- unsigned short temp_reg, old8, old9;
- int irqMask;
- int i, ioaddr = dev->base_addr;
- struct eepro_local *lp = netdev_priv(dev);
-
- if (net_debug > 3)
- printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name);
-
- irqMask = lp->word[7];
-
- if (lp->eepro == LAN595FX_10ISA) {
- if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n");
- }
- else if (irqMask == ee_FX_INT2IRQ) /* INT to IRQ Mask */
- {
- lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */
- if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 2;\n");
- }
-
- else if ((dev->dev_addr[0] == SA_ADDR0 &&
- dev->dev_addr[1] == SA_ADDR1 &&
- dev->dev_addr[2] == SA_ADDR2))
- {
- lp->eepro = 1;
- if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 1;\n");
- } /* Yes, an Intel EtherExpress Pro/10 */
-
- else lp->eepro = 0; /* No, it is a generic 82585 lan card */
-
- /* Get the interrupt vector for the 82595 */
- if (dev->irq < 2 && eepro_grab_irq(dev) == 0) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
- return -EAGAIN;
- }
-
- if (request_irq(dev->irq , &eepro_interrupt, 0, dev->name, dev)) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
- return -EAGAIN;
- }
-
- /* Initialize the 82595. */
-
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- temp_reg = inb(ioaddr + lp->eeprom_reg);
-
- lp->stepping = temp_reg >> 5; /* Get the stepping number of the 595 */
-
- if (net_debug > 3)
- printk(KERN_DEBUG "The stepping of the 82595 is %d\n", lp->stepping);
-
- if (temp_reg & 0x10) /* Check the TurnOff Enable bit */
- outb(temp_reg & 0xef, ioaddr + lp->eeprom_reg);
- for (i=0; i < 6; i++)
- outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i);
-
- temp_reg = inb(ioaddr + REG1); /* Setup Transmit Chaining */
- outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */
- | RCV_Discard_BadFrame, ioaddr + REG1);
-
- temp_reg = inb(ioaddr + REG2); /* Match broadcast */
- outb(temp_reg | 0x14, ioaddr + REG2);
-
- temp_reg = inb(ioaddr + REG3);
- outb(temp_reg & 0x3f, ioaddr + REG3); /* clear test mode */
-
- /* Set the receiving mode */
- eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
-
- /* Set the interrupt vector */
- temp_reg = inb(ioaddr + INT_NO_REG);
- if (lp->eepro == LAN595FX || lp->eepro == LAN595FX_10ISA)
- outb((temp_reg & 0xf8) | irqrmap2[dev->irq], ioaddr + INT_NO_REG);
- else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
-
-
- temp_reg = inb(ioaddr + INT_NO_REG);
- if (lp->eepro == LAN595FX || lp->eepro == LAN595FX_10ISA)
- outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG);
- else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
-
- if (net_debug > 3)
- printk(KERN_DEBUG "eepro_open: content of INT Reg is %x\n", temp_reg);
-
-
- /* Initialize the RCV and XMT upper and lower limits */
- outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
- outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
- outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
- outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
-
- /* Enable the interrupt line. */
- eepro_en_intline(ioaddr);
-
- /* Switch back to Bank 0 */
- eepro_sw2bank0(ioaddr);
-
- /* Let RX and TX events to interrupt */
- eepro_en_int(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- /* Initialize RCV */
- outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
- lp->rx_start = lp->rcv_lower_limit;
- outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
-
- /* Initialize XMT */
- outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
- lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
- lp->tx_last = 0;
-
- /* Check for the i82595TX and i82595FX */
- old8 = inb(ioaddr + 8);
- outb(~old8, ioaddr + 8);
-
- if ((temp_reg = inb(ioaddr + 8)) == old8) {
- if (net_debug > 3)
- printk(KERN_DEBUG "i82595 detected!\n");
- lp->version = LAN595;
- }
- else {
- lp->version = LAN595TX;
- outb(old8, ioaddr + 8);
- old9 = inb(ioaddr + 9);
-
- if (irqMask==ee_FX_INT2IRQ) {
- if (net_debug > 3) {
- printk(KERN_DEBUG "IrqMask: %#x\n",irqMask);
- printk(KERN_DEBUG "i82595FX detected!\n");
- }
- lp->version = LAN595FX;
- outb(old9, ioaddr + 9);
- if (dev->if_port != TPE) { /* Hopefully, this will fix the
- problem of using Pentiums and
- pro/10 w/ BNC. */
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- temp_reg = inb(ioaddr + REG13);
- /* disable the full duplex mode since it is not
- applicable with the 10Base2 cable. */
- outb(temp_reg & ~(FDX | A_N_ENABLE), REG13);
- eepro_sw2bank0(ioaddr); /* be CAREFUL, BANK 0 now */
- }
- }
- else if (net_debug > 3) {
- printk(KERN_DEBUG "temp_reg: %#x ~old9: %#x\n",temp_reg,((~old9)&0xff));
- printk(KERN_DEBUG "i82595TX detected!\n");
- }
- }
-
- eepro_sel_reset(ioaddr);
-
- netif_start_queue(dev);
-
- if (net_debug > 3)
- printk(KERN_DEBUG "%s: exiting eepro_open routine.\n", dev->name);
-
- /* enabling rx */
- eepro_en_rx(ioaddr);
-
- return 0;
-}
-
-static void eepro_tx_timeout (struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* if (net_debug > 1) */
- printk (KERN_ERR "%s: transmit timed out, %s?\n", dev->name,
- "network cable problem");
- /* This is not a duplicate. One message for the console,
- one for the log file */
- printk (KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name,
- "network cable problem");
- eepro_complete_selreset(ioaddr);
-}
-
-
-static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- unsigned long flags;
- int ioaddr = dev->base_addr;
- short length = skb->len;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering eepro_send_packet routine.\n", dev->name);
-
- if (length < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- length = ETH_ZLEN;
- }
- netif_stop_queue (dev);
-
- eepro_dis_int(ioaddr);
- spin_lock_irqsave(&lp->lock, flags);
-
- {
- unsigned char *buf = skb->data;
-
- if (hardware_send_packet(dev, buf, length))
- /* we won't wake queue here because we're out of space */
- dev->stats.tx_dropped++;
- else {
- dev->stats.tx_bytes+=skb->len;
- dev->trans_start = jiffies;
- netif_wake_queue(dev);
- }
-
- }
-
- dev_kfree_skb (skb);
-
- /* You might need to clean up and record Tx statistics here. */
- /* dev->stats.tx_aborted_errors++; */
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting eepro_send_packet routine.\n", dev->name);
-
- eepro_en_int(ioaddr);
- spin_unlock_irqrestore(&lp->lock, flags);
-
- return 0;
-}
-
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-
-static irqreturn_t
-eepro_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct eepro_local *lp;
- int ioaddr, status, boguscount = 20;
- int handled = 0;
-
- lp = netdev_priv(dev);
-
- spin_lock(&lp->lock);
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering eepro_interrupt routine.\n", dev->name);
-
- ioaddr = dev->base_addr;
-
- while (((status = inb(ioaddr + STATUS_REG)) & (RX_INT|TX_INT)) && (boguscount--))
- {
- handled = 1;
- if (status & RX_INT) {
- if (net_debug > 4)
- printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name);
-
- eepro_dis_int(ioaddr);
-
- /* Get the received packets */
- eepro_ack_rx(ioaddr);
- eepro_rx(dev);
-
- eepro_en_int(ioaddr);
- }
- if (status & TX_INT) {
- if (net_debug > 4)
- printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name);
-
-
- eepro_dis_int(ioaddr);
-
- /* Process the status of transmitted packets */
- eepro_ack_tx(ioaddr);
- eepro_transmit_interrupt(dev);
-
- eepro_en_int(ioaddr);
- }
- }
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting eepro_interrupt routine.\n", dev->name);
-
- spin_unlock(&lp->lock);
- return IRQ_RETVAL(handled);
-}
-
-static int eepro_close(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- short temp_reg;
-
- netif_stop_queue(dev);
-
- eepro_sw2bank1(ioaddr); /* Switch back to Bank 1 */
-
- /* Disable the physical interrupt line. */
- temp_reg = inb(ioaddr + REG1);
- outb(temp_reg & 0x7f, ioaddr + REG1);
-
- eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
-
- /* Flush the Tx and disable Rx. */
- outb(STOP_RCV_CMD, ioaddr);
- lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
- lp->tx_last = 0;
-
- /* Mask all the interrupts. */
- eepro_dis_int(ioaddr);
-
- /* clear all interrupts */
- eepro_clear_int(ioaddr);
-
- /* Reset the 82595 */
- eepro_reset(ioaddr);
-
- /* release the interrupt */
- free_irq(dev->irq, dev);
-
- /* Update the statistics here. What statistics? */
-
- return 0;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- */
-static void
-set_multicast_list(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- unsigned short mode;
- struct dev_mc_list *dmi=dev->mc_list;
-
- if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
- {
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode | PRMSC_Mode, ioaddr + REG2);
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
- }
-
- else if (dev->mc_count==0 )
- {
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode & 0xd6, ioaddr + REG2); /* Turn off Multi-IA and PRMSC_Mode bits */
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
- }
-
- else
- {
- unsigned short status, *eaddrs;
- int i, boguscount = 0;
-
- /* Disable RX and TX interrupts. Necessary to avoid
- corruption of the HOST_ADDRESS_REG by interrupt
- service routines. */
- eepro_dis_int(ioaddr);
-
- eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode | Multi_IA, ioaddr + REG2);
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
- outw(lp->tx_end, ioaddr + HOST_ADDRESS_REG);
- outw(MC_SETUP, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
-
- for (i = 0; i < dev->mc_count; i++)
- {
- eaddrs=(unsigned short *)dmi->dmi_addr;
- dmi=dmi->next;
- outw(*eaddrs++, ioaddr + IO_PORT);
- outw(*eaddrs++, ioaddr + IO_PORT);
- outw(*eaddrs++, ioaddr + IO_PORT);
- }
-
- eaddrs = (unsigned short *) dev->dev_addr;
- outw(eaddrs[0], ioaddr + IO_PORT);
- outw(eaddrs[1], ioaddr + IO_PORT);
- outw(eaddrs[2], ioaddr + IO_PORT);
- outw(lp->tx_end, ioaddr + lp->xmt_bar);
- outb(MC_SETUP, ioaddr);
-
- /* Update the transmit queue */
- i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
-
- if (lp->tx_start != lp->tx_end)
- {
- /* update the next address and the chain bit in the
- last packet */
- outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
- outw(i, ioaddr + IO_PORT);
- outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
- status = inw(ioaddr + IO_PORT);
- outw(status | CHAIN_BIT, ioaddr + IO_PORT);
- lp->tx_end = i ;
- }
- else {
- lp->tx_start = lp->tx_end = i ;
- }
-
- /* Acknowledge that the MC setup is done */
- do { /* We should be doing this in the eepro_interrupt()! */
- SLOW_DOWN;
- SLOW_DOWN;
- if (inb(ioaddr + STATUS_REG) & 0x08)
- {
- i = inb(ioaddr);
- outb(0x08, ioaddr + STATUS_REG);
-
- if (i & 0x20) { /* command ABORTed */
- printk(KERN_NOTICE "%s: multicast setup failed.\n",
- dev->name);
- break;
- } else if ((i & 0x0f) == 0x03) { /* MC-Done */
- printk(KERN_DEBUG "%s: set Rx mode to %d address%s.\n",
- dev->name, dev->mc_count,
- dev->mc_count > 1 ? "es":"");
- break;
- }
- }
- } while (++boguscount < 100);
-
- /* Re-enable RX and TX interrupts */
- eepro_en_int(ioaddr);
- }
- if (lp->eepro == LAN595FX_10ISA) {
- eepro_complete_selreset(ioaddr);
- }
- else
- eepro_en_rx(ioaddr);
-}
-
-/* The horrible routine to read a word from the serial EEPROM. */
-/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
-
-/* The delay between EEPROM clock transitions. */
-#define eeprom_delay() { udelay(40); }
-#define EE_READ_CMD (6 << 6)
-
-int
-read_eeprom(int ioaddr, int location, struct net_device *dev)
-{
- int i;
- unsigned short retval = 0;
- struct eepro_local *lp = netdev_priv(dev);
- short ee_addr = ioaddr + lp->eeprom_reg;
- int read_cmd = location | EE_READ_CMD;
- short ctrl_val = EECS ;
-
- /* XXXX - black magic */
- eepro_sw2bank1(ioaddr);
- outb(0x00, ioaddr + STATUS_REG);
- /* XXXX - black magic */
-
- eepro_sw2bank2(ioaddr);
- outb(ctrl_val, ee_addr);
-
- /* Shift the read command bits out. */
- for (i = 8; i >= 0; i--) {
- short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI
- : ctrl_val;
- outb(outval, ee_addr);
- outb(outval | EESK, ee_addr); /* EEPROM clock tick. */
- eeprom_delay();
- outb(outval, ee_addr); /* Finish EEPROM a clock tick. */
- eeprom_delay();
- }
- outb(ctrl_val, ee_addr);
-
- for (i = 16; i > 0; i--) {
- outb(ctrl_val | EESK, ee_addr); eeprom_delay();
- retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
- outb(ctrl_val, ee_addr); eeprom_delay();
- }
-
- /* Terminate the EEPROM access. */
- ctrl_val &= ~EECS;
- outb(ctrl_val | EESK, ee_addr);
- eeprom_delay();
- outb(ctrl_val, ee_addr);
- eeprom_delay();
- eepro_sw2bank0(ioaddr);
- return retval;
-}
-
-static int
-hardware_send_packet(struct net_device *dev, void *buf, short length)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- unsigned status, tx_available, last, end;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name);
-
- /* determine how much of the transmit buffer space is available */
- if (lp->tx_end > lp->tx_start)
- tx_available = lp->xmt_ram - (lp->tx_end - lp->tx_start);
- else if (lp->tx_end < lp->tx_start)
- tx_available = lp->tx_start - lp->tx_end;
- else tx_available = lp->xmt_ram;
-
- if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) >= tx_available) {
- /* No space available ??? */
- return 1;
- }
-
- last = lp->tx_end;
- end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
-
- if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
- if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
- /* Arrrr!!!, must keep the xmt header together,
- several days were lost to chase this one down. */
- last = lp->xmt_lower_limit;
- end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
- }
- else end = lp->xmt_lower_limit + (end -
- lp->xmt_upper_limit + 2);
- }
-
- outw(last, ioaddr + HOST_ADDRESS_REG);
- outw(XMT_CMD, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(end, ioaddr + IO_PORT);
- outw(length, ioaddr + IO_PORT);
-
- if (lp->version == LAN595)
- outsw(ioaddr + IO_PORT, buf, (length + 3) >> 1);
- else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
- unsigned short temp = inb(ioaddr + INT_MASK_REG);
- outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
- outsl(ioaddr + IO_PORT_32_BIT, buf, (length + 3) >> 2);
- outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
- }
-
- /* A dummy read to flush the DRAM write pipeline */
- status = inw(ioaddr + IO_PORT);
-
- if (lp->tx_start == lp->tx_end) {
- outw(last, ioaddr + lp->xmt_bar);
- outb(XMT_CMD, ioaddr);
- lp->tx_start = last; /* I don't like to change tx_start here */
- }
- else {
- /* update the next address and the chain bit in the
- last packet */
-
- if (lp->tx_end != last) {
- outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
- outw(last, ioaddr + IO_PORT);
- }
-
- outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
- status = inw(ioaddr + IO_PORT);
- outw(status | CHAIN_BIT, ioaddr + IO_PORT);
-
- /* Continue the transmit command */
- outb(RESUME_XMT_CMD, ioaddr);
- }
-
- lp->tx_last = last;
- lp->tx_end = end;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name);
-
- return 0;
-}
-
-static void
-eepro_rx(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- short boguscount = 20;
- short rcv_car = lp->rx_start;
- unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size;
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name);
-
- /* Set the read pointer to the start of the RCV */
- outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
-
- rcv_event = inw(ioaddr + IO_PORT);
-
- while (rcv_event == RCV_DONE) {
-
- rcv_status = inw(ioaddr + IO_PORT);
- rcv_next_frame = inw(ioaddr + IO_PORT);
- rcv_size = inw(ioaddr + IO_PORT);
-
- if ((rcv_status & (RX_OK | RX_ERROR)) == RX_OK) {
-
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- dev->stats.rx_bytes+=rcv_size;
- rcv_size &= 0x3fff;
- skb = dev_alloc_skb(rcv_size+5);
- if (skb == NULL) {
- printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
- dev->stats.rx_dropped++;
- rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
- lp->rx_start = rcv_next_frame;
- outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
-
- break;
- }
- skb_reserve(skb,2);
-
- if (lp->version == LAN595)
- insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 3) >> 1);
- else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
- unsigned short temp = inb(ioaddr + INT_MASK_REG);
- outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
- insl(ioaddr+IO_PORT_32_BIT, skb_put(skb,rcv_size),
- (rcv_size + 3) >> 2);
- outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
- }
-
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- }
-
- else { /* Not sure will ever reach here,
- I set the 595 to discard bad received frames */
- dev->stats.rx_errors++;
-
- if (rcv_status & 0x0100)
- dev->stats.rx_over_errors++;
-
- else if (rcv_status & 0x0400)
- dev->stats.rx_frame_errors++;
-
- else if (rcv_status & 0x0800)
- dev->stats.rx_crc_errors++;
-
- printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
- dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
- }
-
- if (rcv_status & 0x1000)
- dev->stats.rx_length_errors++;
-
- rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
- lp->rx_start = rcv_next_frame;
-
- if (--boguscount == 0)
- break;
-
- outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
- rcv_event = inw(ioaddr + IO_PORT);
-
- }
- if (rcv_car == 0)
- rcv_car = lp->rcv_upper_limit | 0xff;
-
- outw(rcv_car - 1, ioaddr + RCV_STOP);
-
- if (net_debug > 5)
- printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name);
-}
-
-static void
-eepro_transmit_interrupt(struct net_device *dev)
-{
- struct eepro_local *lp = netdev_priv(dev);
- short ioaddr = dev->base_addr;
- short boguscount = 25;
- short xmt_status;
-
- while ((lp->tx_start != lp->tx_end) && boguscount--) {
-
- outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
- xmt_status = inw(ioaddr+IO_PORT);
-
- if (!(xmt_status & TX_DONE_BIT))
- break;
-
- xmt_status = inw(ioaddr+IO_PORT);
- lp->tx_start = inw(ioaddr+IO_PORT);
-
- netif_wake_queue (dev);
-
- if (xmt_status & TX_OK)
- dev->stats.tx_packets++;
- else {
- dev->stats.tx_errors++;
- if (xmt_status & 0x0400) {
- dev->stats.tx_carrier_errors++;
- printk(KERN_DEBUG "%s: carrier error\n",
- dev->name);
- printk(KERN_DEBUG "%s: XMT status = %#x\n",
- dev->name, xmt_status);
- }
- else {
- printk(KERN_DEBUG "%s: XMT status = %#x\n",
- dev->name, xmt_status);
- printk(KERN_DEBUG "%s: XMT status = %#x\n",
- dev->name, xmt_status);
- }
- }
- if (xmt_status & 0x000f) {
- dev->stats.collisions += (xmt_status & 0x000f);
- }
-
- if ((xmt_status & 0x0040) == 0x0) {
- dev->stats.tx_heartbeat_errors++;
- }
- }
-}
-
-static int eepro_ethtool_get_settings(struct net_device *dev,
- struct ethtool_cmd *cmd)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
-
- cmd->supported = SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_Autoneg;
- cmd->advertising = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_Autoneg;
-
- if (GetBit(lp->word[5], ee_PortTPE)) {
- cmd->supported |= SUPPORTED_TP;
- cmd->advertising |= ADVERTISED_TP;
- }
- if (GetBit(lp->word[5], ee_PortBNC)) {
- cmd->supported |= SUPPORTED_BNC;
- cmd->advertising |= ADVERTISED_BNC;
- }
- if (GetBit(lp->word[5], ee_PortAUI)) {
- cmd->supported |= SUPPORTED_AUI;
- cmd->advertising |= ADVERTISED_AUI;
- }
-
- cmd->speed = SPEED_10;
-
- if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
- cmd->duplex = DUPLEX_FULL;
- }
- else {
- cmd->duplex = DUPLEX_HALF;
- }
-
- cmd->port = dev->if_port;
- cmd->phy_address = dev->base_addr;
- cmd->transceiver = XCVR_INTERNAL;
-
- if (lp->word[0] & ee_AutoNeg) {
- cmd->autoneg = 1;
- }
-
- return 0;
-}
-
-static void eepro_ethtool_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *drvinfo)
-{
- strcpy(drvinfo->driver, DRV_NAME);
- strcpy(drvinfo->version, DRV_VERSION);
- sprintf(drvinfo->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static const struct ethtool_ops eepro_ethtool_ops = {
- .get_settings = eepro_ethtool_get_settings,
- .get_drvinfo = eepro_ethtool_get_drvinfo,
-};
-
-#ifdef MODULE
-
-#define MAX_EEPRO 8
-static struct net_device *dev_eepro[MAX_EEPRO];
-
-static int io[MAX_EEPRO] = {
- [0 ... MAX_EEPRO-1] = -1
-};
-static int irq[MAX_EEPRO];
-static int mem[MAX_EEPRO] = { /* Size of the rx buffer in KB */
- [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024
-};
-static int autodetect;
-
-static int n_eepro;
-/* For linux 2.1.xx */
-
-MODULE_AUTHOR("Pascal Dupuis and others");
-MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
-MODULE_LICENSE("GPL");
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
-module_param(autodetect, int, 0);
-MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
-MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
-MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
-MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)");
-
-int __init init_module(void)
-{
- struct net_device *dev;
- int i;
- if (io[0] == -1 && autodetect == 0) {
- printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
- printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n");
- return -ENODEV;
- }
- else if (autodetect) {
- /* if autodetect is set then we must force detection */
- for (i = 0; i < MAX_EEPRO; i++) {
- io[i] = 0;
- }
-
- printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n");
- }
-
- for (i = 0; io[i] != -1 && i < MAX_EEPRO; i++) {
- dev = alloc_etherdev(sizeof(struct eepro_local));
- if (!dev)
- break;
-
- dev->mem_end = mem[i];
- dev->base_addr = io[i];
- dev->irq = irq[i];
-
- if (do_eepro_probe(dev) == 0) {
- dev_eepro[n_eepro++] = dev;
- continue;
- }
- free_netdev(dev);
- break;
- }
-
- if (n_eepro)
- printk(KERN_INFO "%s", version);
-
- return n_eepro ? 0 : -ENODEV;
-}
-
-void __exit
-cleanup_module(void)
-{
- int i;
-
- for (i=0; i<n_eepro; i++) {
- struct net_device *dev = dev_eepro[i];
- unregister_netdev(dev);
- release_region(dev->base_addr, EEPRO_IO_EXTENT);
- free_netdev(dev);
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
deleted file mode 100644
index e3e26c595fa..00000000000
--- a/drivers/net/eepro100.c
+++ /dev/null
@@ -1,2401 +0,0 @@
-/* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */
-/*
- Written 1996-1999 by Donald Becker.
-
- The driver also contains updates by different kernel developers
- (see incomplete list below).
- Current maintainer is Andrey V. Savochkin <saw@saw.sw.com.sg>.
- Please use this email address and linux-kernel mailing list for bug reports.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- This driver is for the Intel EtherExpress Pro100 (Speedo3) design.
- It should work with all i82557/558/559 boards.
-
- Version history:
- 1998 Apr - 2000 Feb Andrey V. Savochkin <saw@saw.sw.com.sg>
- Serious fixes for multicast filter list setting, TX timeout routine;
- RX ring refilling logic; other stuff
- 2000 Feb Jeff Garzik <jgarzik@pobox.com>
- Convert to new PCI driver interface
- 2000 Mar 24 Dragan Stancevic <visitor@valinux.com>
- Disabled FC and ER, to avoid lockups when when we get FCP interrupts.
- 2000 Jul 17 Goutham Rao <goutham.rao@intel.com>
- PCI DMA API fixes, adding pci_dma_sync_single calls where neccesary
- 2000 Aug 31 David Mosberger <davidm@hpl.hp.com>
- rx_align support: enables rx DMA without causing unaligned accesses.
-*/
-
-static const char * const version =
-"eepro100.c:v1.09j-t 9/29/99 Donald Becker\n"
-"eepro100.c: $Revision: 1.36 $ 2000/11/17 Modified by Andrey V. Savochkin <saw@saw.sw.com.sg> and others\n";
-
-/* A few user-configurable values that apply to all boards.
- First set is undocumented and spelled per Intel recommendations. */
-
-static int congenb /* = 0 */; /* Enable congestion control in the DP83840. */
-static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */
-static int rxfifo = 8; /* Rx FIFO threshold, default 32 bytes. */
-/* Tx/Rx DMA burst length, 0-127, 0 == no preemption, tx==128 -> disabled. */
-static int txdmacount = 128;
-static int rxdmacount /* = 0 */;
-
-#if defined(__ia64__) || defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
- defined(__arm__)
- /* align rx buffers to 2 bytes so that IP header is aligned */
-# define rx_align(skb) skb_reserve((skb), 2)
-# define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
-#else
-# define rx_align(skb)
-# define RxFD_ALIGNMENT
-#endif
-
-/* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
- Lower values use more memory, but are faster. */
-static int rx_copybreak = 200;
-
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
-
-/* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */
-static int multicast_filter_limit = 64;
-
-/* 'options' is used to pass a transceiver override or full-duplex flag
- e.g. "options=16" for FD, "options=32" for 100mbps-only. */
-static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-
-/* A few values that may be tweaked. */
-/* The ring sizes should be a power of two for efficiency. */
-#define TX_RING_SIZE 64
-#define RX_RING_SIZE 64
-/* How much slots multicast filter setup may take.
- Do not descrease without changing set_rx_mode() implementaion. */
-#define TX_MULTICAST_SIZE 2
-#define TX_MULTICAST_RESERV (TX_MULTICAST_SIZE*2)
-/* Actual number of TX packets queued, must be
- <= TX_RING_SIZE-TX_MULTICAST_RESERV. */
-#define TX_QUEUE_LIMIT (TX_RING_SIZE-TX_MULTICAST_RESERV)
-/* Hysteresis marking queue as no longer full. */
-#define TX_QUEUE_UNFULL (TX_QUEUE_LIMIT-4)
-
-/* Operational parameters that usually are not changed. */
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT (2*HZ)
-/* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/
-#define PKT_BUF_SZ 1536
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/mii.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/irq.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-
-static int use_io;
-static int debug = -1;
-#define DEBUG_DEFAULT (NETIF_MSG_DRV | \
- NETIF_MSG_HW | \
- NETIF_MSG_RX_ERR | \
- NETIF_MSG_TX_ERR)
-#define DEBUG ((debug >= 0) ? (1<<debug)-1 : DEBUG_DEFAULT)
-
-
-MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
-MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
-MODULE_LICENSE("GPL");
-module_param(use_io, int, 0);
-module_param(debug, int, 0);
-module_param_array(options, int, NULL, 0);
-module_param_array(full_duplex, int, NULL, 0);
-module_param(congenb, int, 0);
-module_param(txfifo, int, 0);
-module_param(rxfifo, int, 0);
-module_param(txdmacount, int, 0);
-module_param(rxdmacount, int, 0);
-module_param(rx_copybreak, int, 0);
-module_param(max_interrupt_work, int, 0);
-module_param(multicast_filter_limit, int, 0);
-MODULE_PARM_DESC(debug, "debug level (0-6)");
-MODULE_PARM_DESC(options, "Bits 0-3: transceiver type, bit 4: full duplex, bit 5: 100Mbps");
-MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
-MODULE_PARM_DESC(congenb, "Enable congestion control (1)");
-MODULE_PARM_DESC(txfifo, "Tx FIFO threshold in 4 byte units, (0-15)");
-MODULE_PARM_DESC(rxfifo, "Rx FIFO threshold in 4 byte units, (0-15)");
-MODULE_PARM_DESC(txdmacount, "Tx DMA burst length; 128 - disable (0-128)");
-MODULE_PARM_DESC(rxdmacount, "Rx DMA burst length; 128 - disable (0-128)");
-MODULE_PARM_DESC(rx_copybreak, "copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
-MODULE_PARM_DESC(multicast_filter_limit, "maximum number of filtered multicast addresses");
-
-#define RUN_AT(x) (jiffies + (x))
-
-#define netdevice_start(dev)
-#define netdevice_stop(dev)
-#define netif_set_tx_timeout(dev, tf, tm) \
- do { \
- (dev)->tx_timeout = (tf); \
- (dev)->watchdog_timeo = (tm); \
- } while(0)
-
-
-
-/*
- Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the Intel i82557 "Speedo3" chip, Intel's
-single-chip fast Ethernet controller for PCI, as used on the Intel
-EtherExpress Pro 100 adapter.
-
-II. Board-specific settings
-
-PCI bus devices are configured by the system at boot time, so no jumpers
-need to be set on the board. The system BIOS should be set to assign the
-PCI INTA signal to an otherwise unused system IRQ line. While it's
-possible to share PCI interrupt lines, it negatively impacts performance and
-only recent kernels support it.
-
-III. Driver operation
-
-IIIA. General
-The Speedo3 is very similar to other Intel network chips, that is to say
-"apparently designed on a different planet". This chips retains the complex
-Rx and Tx descriptors and multiple buffers pointers as previous chips, but
-also has simplified Tx and Rx buffer modes. This driver uses the "flexible"
-Tx mode, but in a simplified lower-overhead manner: it associates only a
-single buffer descriptor with each frame descriptor.
-
-Despite the extra space overhead in each receive skbuff, the driver must use
-the simplified Rx buffer mode to assure that only a single data buffer is
-associated with each RxFD. The driver implements this by reserving space
-for the Rx descriptor at the head of each Rx skbuff.
-
-The Speedo-3 has receive and command unit base addresses that are added to
-almost all descriptor pointers. The driver sets these to zero, so that all
-pointer fields are absolute addresses.
-
-The System Control Block (SCB) of some previous Intel chips exists on the
-chip in both PCI I/O and memory space. This driver uses the I/O space
-registers, but might switch to memory mapped mode to better support non-x86
-processors.
-
-IIIB. Transmit structure
-
-The driver must use the complex Tx command+descriptor mode in order to
-have a indirect pointer to the skbuff data section. Each Tx command block
-(TxCB) is associated with two immediately appended Tx Buffer Descriptor
-(TxBD). A fixed ring of these TxCB+TxBD pairs are kept as part of the
-speedo_private data structure for each adapter instance.
-
-The newer i82558 explicitly supports this structure, and can read the two
-TxBDs in the same PCI burst as the TxCB.
-
-This ring structure is used for all normal transmit packets, but the
-transmit packet descriptors aren't long enough for most non-Tx commands such
-as CmdConfigure. This is complicated by the possibility that the chip has
-already loaded the link address in the previous descriptor. So for these
-commands we convert the next free descriptor on the ring to a NoOp, and point
-that descriptor's link to the complex command.
-
-An additional complexity of these non-transmit commands are that they may be
-added asynchronous to the normal transmit queue, so we disable interrupts
-whenever the Tx descriptor ring is manipulated.
-
-A notable aspect of these special configure commands is that they do
-work with the normal Tx ring entry scavenge method. The Tx ring scavenge
-is done at interrupt time using the 'dirty_tx' index, and checking for the
-command-complete bit. While the setup frames may have the NoOp command on the
-Tx ring marked as complete, but not have completed the setup command, this
-is not a problem. The tx_ring entry can be still safely reused, as the
-tx_skbuff[] entry is always empty for config_cmd and mc_setup frames.
-
-Commands may have bits set e.g. CmdSuspend in the command word to either
-suspend or stop the transmit/command unit. This driver always flags the last
-command with CmdSuspend, erases the CmdSuspend in the previous command, and
-then issues a CU_RESUME.
-Note: Watch out for the potential race condition here: imagine
- erasing the previous suspend
- the chip processes the previous command
- the chip processes the final command, and suspends
- doing the CU_RESUME
- the chip processes the next-yet-valid post-final-command.
-So blindly sending a CU_RESUME is only safe if we do it immediately after
-after erasing the previous CmdSuspend, without the possibility of an
-intervening delay. Thus the resume command is always within the
-interrupts-disabled region. This is a timing dependence, but handling this
-condition in a timing-independent way would considerably complicate the code.
-
-Note: In previous generation Intel chips, restarting the command unit was a
-notoriously slow process. This is presumably no longer true.
-
-IIIC. Receive structure
-
-Because of the bus-master support on the Speedo3 this driver uses the new
-SKBUFF_RX_COPYBREAK scheme, rather than a fixed intermediate receive buffer.
-This scheme allocates full-sized skbuffs as receive buffers. The value
-SKBUFF_RX_COPYBREAK is used as the copying breakpoint: it is chosen to
-trade-off the memory wasted by passing the full-sized skbuff to the queue
-layer for all frames vs. the copying cost of copying a frame to a
-correctly-sized skbuff.
-
-For small frames the copying cost is negligible (esp. considering that we
-are pre-loading the cache with immediately useful header information), so we
-allocate a new, minimally-sized skbuff. For large frames the copying cost
-is non-trivial, and the larger copy might flush the cache of useful data, so
-we pass up the skbuff the packet was received into.
-
-IV. Notes
-
-Thanks to Steve Williams of Intel for arranging the non-disclosure agreement
-that stated that I could disclose the information. But I still resent
-having to sign an Intel NDA when I'm helping Intel sell their own product!
-
-*/
-
-static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state);
-
-/* Offsets to the various registers.
- All accesses need not be longword aligned. */
-enum speedo_offsets {
- SCBStatus = 0, SCBCmd = 2, /* Rx/Command Unit command and status. */
- SCBIntmask = 3,
- SCBPointer = 4, /* General purpose pointer. */
- SCBPort = 8, /* Misc. commands and operands. */
- SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */
- SCBCtrlMDI = 16, /* MDI interface control. */
- SCBEarlyRx = 20, /* Early receive byte count. */
-};
-/* Commands that can be put in a command list entry. */
-enum commands {
- CmdNOp = 0, CmdIASetup = 0x10000, CmdConfigure = 0x20000,
- CmdMulticastList = 0x30000, CmdTx = 0x40000, CmdTDR = 0x50000,
- CmdDump = 0x60000, CmdDiagnose = 0x70000,
- CmdSuspend = 0x40000000, /* Suspend after completion. */
- CmdIntr = 0x20000000, /* Interrupt after completion. */
- CmdTxFlex = 0x00080000, /* Use "Flexible mode" for CmdTx command. */
-};
-/* Clear CmdSuspend (1<<30) avoiding interference with the card access to the
- status bits. Previous driver versions used separate 16 bit fields for
- commands and statuses. --SAW
- */
-#if defined(__alpha__)
-# define clear_suspend(cmd) clear_bit(30, &(cmd)->cmd_status);
-#else
-# define clear_suspend(cmd) ((__le16 *)&(cmd)->cmd_status)[1] &= ~cpu_to_le16(1<<14)
-#endif
-
-enum SCBCmdBits {
- SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000,
- SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400,
- SCBTriggerIntr=0x0200, SCBMaskAll=0x0100,
- /* The rest are Rx and Tx commands. */
- CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050,
- CUCmdBase=0x0060, /* CU Base address (set to zero) . */
- CUDumpStats=0x0070, /* Dump then reset stats counters. */
- RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006,
- RxResumeNoResources=0x0007,
-};
-
-enum SCBPort_cmds {
- PortReset=0, PortSelfTest=1, PortPartialReset=2, PortDump=3,
-};
-
-/* The Speedo3 Rx and Tx frame/buffer descriptors. */
-struct descriptor { /* A generic descriptor. */
- volatile __le32 cmd_status; /* All command and status fields. */
- __le32 link; /* struct descriptor * */
- unsigned char params[0];
-};
-
-/* The Speedo3 Rx and Tx buffer descriptors. */
-struct RxFD { /* Receive frame descriptor. */
- volatile __le32 status;
- __le32 link; /* struct RxFD * */
- __le32 rx_buf_addr; /* void * */
- __le32 count;
-} RxFD_ALIGNMENT;
-
-/* Selected elements of the Tx/RxFD.status word. */
-enum RxFD_bits {
- RxComplete=0x8000, RxOK=0x2000,
- RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010,
- RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002,
- TxUnderrun=0x1000, StatusComplete=0x8000,
-};
-
-#define CONFIG_DATA_SIZE 22
-struct TxFD { /* Transmit frame descriptor set. */
- __le32 status;
- __le32 link; /* void * */
- __le32 tx_desc_addr; /* Always points to the tx_buf_addr element. */
- __le32 count; /* # of TBD (=1), Tx start thresh., etc. */
- /* This constitutes two "TBD" entries -- we only use one. */
-#define TX_DESCR_BUF_OFFSET 16
- __le32 tx_buf_addr0; /* void *, frame to be transmitted. */
- __le32 tx_buf_size0; /* Length of Tx frame. */
- __le32 tx_buf_addr1; /* void *, frame to be transmitted. */
- __le32 tx_buf_size1; /* Length of Tx frame. */
- /* the structure must have space for at least CONFIG_DATA_SIZE starting
- * from tx_desc_addr field */
-};
-
-/* Multicast filter setting block. --SAW */
-struct speedo_mc_block {
- struct speedo_mc_block *next;
- unsigned int tx;
- dma_addr_t frame_dma;
- unsigned int len;
- struct descriptor frame __attribute__ ((__aligned__(16)));
-};
-
-/* Elements of the dump_statistics block. This block must be lword aligned. */
-struct speedo_stats {
- __le32 tx_good_frames;
- __le32 tx_coll16_errs;
- __le32 tx_late_colls;
- __le32 tx_underruns;
- __le32 tx_lost_carrier;
- __le32 tx_deferred;
- __le32 tx_one_colls;
- __le32 tx_multi_colls;
- __le32 tx_total_colls;
- __le32 rx_good_frames;
- __le32 rx_crc_errs;
- __le32 rx_align_errs;
- __le32 rx_resource_errs;
- __le32 rx_overrun_errs;
- __le32 rx_colls_errs;
- __le32 rx_runt_errs;
- __le32 done_marker;
-};
-
-enum Rx_ring_state_bits {
- RrNoMem=1, RrPostponed=2, RrNoResources=4, RrOOMReported=8,
-};
-
-/* Do not change the position (alignment) of the first few elements!
- The later elements are grouped for cache locality.
-
- Unfortunately, all the positions have been shifted since there.
- A new re-alignment is required. 2000/03/06 SAW */
-struct speedo_private {
- void __iomem *regs;
- struct TxFD *tx_ring; /* Commands (usually CmdTxPacket). */
- struct RxFD *rx_ringp[RX_RING_SIZE]; /* Rx descriptor, used as ring. */
- /* The addresses of a Tx/Rx-in-place packets/buffers. */
- struct sk_buff *tx_skbuff[TX_RING_SIZE];
- struct sk_buff *rx_skbuff[RX_RING_SIZE];
- /* Mapped addresses of the rings. */
- dma_addr_t tx_ring_dma;
-#define TX_RING_ELEM_DMA(sp, n) ((sp)->tx_ring_dma + (n)*sizeof(struct TxFD))
- dma_addr_t rx_ring_dma[RX_RING_SIZE];
- struct descriptor *last_cmd; /* Last command sent. */
- unsigned int cur_tx, dirty_tx; /* The ring entries to be free()ed. */
- spinlock_t lock; /* Group with Tx control cache line. */
- u32 tx_threshold; /* The value for txdesc.count. */
- struct RxFD *last_rxf; /* Last filled RX buffer. */
- dma_addr_t last_rxf_dma;
- unsigned int cur_rx, dirty_rx; /* The next free ring entry */
- long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */
- struct net_device_stats stats;
- struct speedo_stats *lstats;
- dma_addr_t lstats_dma;
- int chip_id;
- struct pci_dev *pdev;
- struct timer_list timer; /* Media selection timer. */
- struct speedo_mc_block *mc_setup_head; /* Multicast setup frame list head. */
- struct speedo_mc_block *mc_setup_tail; /* Multicast setup frame list tail. */
- long in_interrupt; /* Word-aligned dev->interrupt */
- unsigned char acpi_pwr;
- signed char rx_mode; /* Current PROMISC/ALLMULTI setting. */
- unsigned int tx_full:1; /* The Tx queue is full. */
- unsigned int flow_ctrl:1; /* Use 802.3x flow control. */
- unsigned int rx_bug:1; /* Work around receiver hang errata. */
- unsigned char default_port:8; /* Last dev->if_port value. */
- unsigned char rx_ring_state; /* RX ring status flags. */
- unsigned short phy[2]; /* PHY media interfaces available. */
- unsigned short partner; /* Link partner caps. */
- struct mii_if_info mii_if; /* MII API hooks, info */
- u32 msg_enable; /* debug message level */
-};
-
-/* The parameters for a CmdConfigure operation.
- There are so many options that it would be difficult to document each bit.
- We mostly use the default or recommended settings. */
-static const char i82557_config_cmd[CONFIG_DATA_SIZE] = {
- 22, 0x08, 0, 0, 0, 0, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */
- 0, 0x2E, 0, 0x60, 0,
- 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */
- 0x3f, 0x05, };
-static const char i82558_config_cmd[CONFIG_DATA_SIZE] = {
- 22, 0x08, 0, 1, 0, 0, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */
- 0, 0x2E, 0, 0x60, 0x08, 0x88,
- 0x68, 0, 0x40, 0xf2, 0x84, /* Disable FC */
- 0x31, 0x05, };
-
-/* PHY media interface chips. */
-static const char * const phys[] = {
- "None", "i82553-A/B", "i82553-C", "i82503",
- "DP83840", "80c240", "80c24", "i82555",
- "unknown-8", "unknown-9", "DP83840A", "unknown-11",
- "unknown-12", "unknown-13", "unknown-14", "unknown-15", };
-enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
- S80C24, I82555, DP83840A=10, };
-static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 };
-#define EE_READ_CMD (6)
-
-static int eepro100_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent);
-
-static int do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len);
-static int mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
-static int speedo_open(struct net_device *dev);
-static void speedo_resume(struct net_device *dev);
-static void speedo_timer(unsigned long data);
-static void speedo_init_rx_ring(struct net_device *dev);
-static void speedo_tx_timeout(struct net_device *dev);
-static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static void speedo_refill_rx_buffers(struct net_device *dev, int force);
-static int speedo_rx(struct net_device *dev);
-static void speedo_tx_buffer_gc(struct net_device *dev);
-static irqreturn_t speedo_interrupt(int irq, void *dev_instance);
-static int speedo_close(struct net_device *dev);
-static struct net_device_stats *speedo_get_stats(struct net_device *dev);
-static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void set_rx_mode(struct net_device *dev);
-static void speedo_show_state(struct net_device *dev);
-static const struct ethtool_ops ethtool_ops;
-
-
-
-#ifdef honor_default_port
-/* Optional driver feature to allow forcing the transceiver setting.
- Not recommended. */
-static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100,
- 0x2000, 0x2100, 0x0400, 0x3100};
-#endif
-
-/* How to wait for the command unit to accept a command.
- Typically this takes 0 ticks. */
-static inline unsigned char wait_for_cmd_done(struct net_device *dev,
- struct speedo_private *sp)
-{
- int wait = 1000;
- void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
- unsigned char r;
-
- do {
- udelay(1);
- r = ioread8(cmd_ioaddr);
- } while(r && --wait >= 0);
-
- if (wait < 0)
- printk(KERN_ALERT "%s: wait_for_cmd_done timeout!\n", dev->name);
- return r;
-}
-
-static int __devinit eepro100_init_one (struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- void __iomem *ioaddr;
- int irq, pci_bar;
- int acpi_idle_state = 0, pm;
- static int cards_found /* = 0 */;
- unsigned long pci_base;
-
-#ifndef MODULE
- /* when built-in, we only print version if device is found */
- static int did_version;
- if (did_version++ == 0)
- printk(version);
-#endif
-
- /* save power state before pci_enable_device overwrites it */
- pm = pci_find_capability(pdev, PCI_CAP_ID_PM);
- if (pm) {
- u16 pwr_command;
- pci_read_config_word(pdev, pm + PCI_PM_CTRL, &pwr_command);
- acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
- }
-
- if (pci_enable_device(pdev))
- goto err_out_free_mmio_region;
-
- pci_set_master(pdev);
-
- if (!request_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1), "eepro100")) {
- dev_err(&pdev->dev, "eepro100: cannot reserve I/O ports\n");
- goto err_out_none;
- }
- if (!request_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0), "eepro100")) {
- dev_err(&pdev->dev, "eepro100: cannot reserve MMIO region\n");
- goto err_out_free_pio_region;
- }
-
- irq = pdev->irq;
- pci_bar = use_io ? 1 : 0;
- pci_base = pci_resource_start(pdev, pci_bar);
- if (DEBUG & NETIF_MSG_PROBE)
- printk("Found Intel i82557 PCI Speedo at %#lx, IRQ %d.\n",
- pci_base, irq);
-
- ioaddr = pci_iomap(pdev, pci_bar, 0);
- if (!ioaddr) {
- dev_err(&pdev->dev, "eepro100: cannot remap IO\n");
- goto err_out_free_mmio_region;
- }
-
- if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0)
- cards_found++;
- else
- goto err_out_iounmap;
-
- return 0;
-
-err_out_iounmap: ;
- pci_iounmap(pdev, ioaddr);
-err_out_free_mmio_region:
- release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-err_out_free_pio_region:
- release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
-err_out_none:
- return -ENODEV;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-
-static void poll_speedo (struct net_device *dev)
-{
- /* disable_irq is not very nice, but with the funny lockless design
- we have no other choice. */
- disable_irq(dev->irq);
- speedo_interrupt (dev->irq, dev);
- enable_irq(dev->irq);
-}
-#endif
-
-static int __devinit speedo_found1(struct pci_dev *pdev,
- void __iomem *ioaddr, int card_idx, int acpi_idle_state)
-{
- struct net_device *dev;
- struct speedo_private *sp;
- const char *product;
- int i, option;
- u16 eeprom[0x100];
- int size;
- void *tx_ring_space;
- dma_addr_t tx_ring_dma;
- DECLARE_MAC_BUF(mac);
-
- size = TX_RING_SIZE * sizeof(struct TxFD) + sizeof(struct speedo_stats);
- tx_ring_space = pci_alloc_consistent(pdev, size, &tx_ring_dma);
- if (tx_ring_space == NULL)
- return -1;
-
- dev = alloc_etherdev(sizeof(struct speedo_private));
- if (dev == NULL) {
- printk(KERN_ERR "eepro100: Could not allocate ethernet device.\n");
- pci_free_consistent(pdev, size, tx_ring_space, tx_ring_dma);
- return -1;
- }
-
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- if (dev->mem_start > 0)
- option = dev->mem_start;
- else if (card_idx >= 0 && options[card_idx] >= 0)
- option = options[card_idx];
- else
- option = 0;
-
- rtnl_lock();
- if (dev_alloc_name(dev, dev->name) < 0)
- goto err_free_unlock;
-
- /* Read the station address EEPROM before doing the reset.
- Nominally his should even be done before accepting the device, but
- then we wouldn't have a device name with which to report the error.
- The size test is for 6 bit vs. 8 bit address serial EEPROMs.
- */
- {
- void __iomem *iobase;
- int read_cmd, ee_size;
- u16 sum;
- int j;
-
- /* Use IO only to avoid postponed writes and satisfy EEPROM timing
- requirements. */
- iobase = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
- if (!iobase)
- goto err_free_unlock;
- if ((do_eeprom_cmd(iobase, EE_READ_CMD << 24, 27) & 0xffe0000)
- == 0xffe0000) {
- ee_size = 0x100;
- read_cmd = EE_READ_CMD << 24;
- } else {
- ee_size = 0x40;
- read_cmd = EE_READ_CMD << 22;
- }
-
- for (j = 0, i = 0, sum = 0; i < ee_size; i++) {
- u16 value = do_eeprom_cmd(iobase, read_cmd | (i << 16), 27);
- eeprom[i] = value;
- sum += value;
- if (i < 3) {
- dev->dev_addr[j++] = value;
- dev->dev_addr[j++] = value >> 8;
- }
- }
- if (sum != 0xBABA)
- printk(KERN_WARNING "%s: Invalid EEPROM checksum %#4.4x, "
- "check settings before activating this device!\n",
- dev->name, sum);
- /* Don't unregister_netdev(dev); as the EEPro may actually be
- usable, especially if the MAC address is set later.
- On the other hand, it may be unusable if MDI data is corrupted. */
-
- pci_iounmap(pdev, iobase);
- }
-
- /* Reset the chip: stop Tx and Rx processes and clear counters.
- This takes less than 10usec and will easily finish before the next
- action. */
- iowrite32(PortReset, ioaddr + SCBPort);
- ioread32(ioaddr + SCBPort);
- udelay(10);
-
- if (eeprom[3] & 0x0100)
- product = "OEM i82557/i82558 10/100 Ethernet";
- else
- product = pci_name(pdev);
-
- printk(KERN_INFO "%s: %s, %s, IRQ %d.\n", dev->name, product,
- print_mac(mac, dev->dev_addr), pdev->irq);
-
- sp = netdev_priv(dev);
-
- /* we must initialize this early, for mdio_{read,write} */
- sp->regs = ioaddr;
-
-#if 1 || defined(kernel_bloat)
- /* OK, this is pure kernel bloat. I don't like it when other drivers
- waste non-pageable kernel space to emit similar messages, but I need
- them for bug reports. */
- {
- const char *connectors[] = {" RJ45", " BNC", " AUI", " MII"};
- /* The self-test results must be paragraph aligned. */
- volatile s32 *self_test_results;
- int boguscnt = 16000; /* Timeout for set-test. */
- if ((eeprom[3] & 0x03) != 0x03)
- printk(KERN_INFO " Receiver lock-up bug exists -- enabling"
- " work-around.\n");
- printk(KERN_INFO " Board assembly %4.4x%2.2x-%3.3d, Physical"
- " connectors present:",
- eeprom[8], eeprom[9]>>8, eeprom[9] & 0xff);
- for (i = 0; i < 4; i++)
- if (eeprom[5] & (1<<i))
- printk(connectors[i]);
- printk("\n"KERN_INFO" Primary interface chip %s PHY #%d.\n",
- phys[(eeprom[6]>>8)&15], eeprom[6] & 0x1f);
- if (eeprom[7] & 0x0700)
- printk(KERN_INFO " Secondary interface chip %s.\n",
- phys[(eeprom[7]>>8)&7]);
- if (((eeprom[6]>>8) & 0x3f) == DP83840
- || ((eeprom[6]>>8) & 0x3f) == DP83840A) {
- int mdi_reg23 = mdio_read(dev, eeprom[6] & 0x1f, 23) | 0x0422;
- if (congenb)
- mdi_reg23 |= 0x0100;
- printk(KERN_INFO" DP83840 specific setup, setting register 23 to %4.4x.\n",
- mdi_reg23);
- mdio_write(dev, eeprom[6] & 0x1f, 23, mdi_reg23);
- }
- if ((option >= 0) && (option & 0x70)) {
- printk(KERN_INFO " Forcing %dMbs %s-duplex operation.\n",
- (option & 0x20 ? 100 : 10),
- (option & 0x10 ? "full" : "half"));
- mdio_write(dev, eeprom[6] & 0x1f, MII_BMCR,
- ((option & 0x20) ? 0x2000 : 0) | /* 100mbps? */
- ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
- }
-
- /* Perform a system self-test. */
- self_test_results = (s32*) ((((long) tx_ring_space) + 15) & ~0xf);
- self_test_results[0] = 0;
- self_test_results[1] = -1;
- iowrite32(tx_ring_dma | PortSelfTest, ioaddr + SCBPort);
- do {
- udelay(10);
- } while (self_test_results[1] == -1 && --boguscnt >= 0);
-
- if (boguscnt < 0) { /* Test optimized out. */
- printk(KERN_ERR "Self test failed, status %8.8x:\n"
- KERN_ERR " Failure to initialize the i82557.\n"
- KERN_ERR " Verify that the card is a bus-master"
- " capable slot.\n",
- self_test_results[1]);
- } else
- printk(KERN_INFO " General self-test: %s.\n"
- KERN_INFO " Serial sub-system self-test: %s.\n"
- KERN_INFO " Internal registers self-test: %s.\n"
- KERN_INFO " ROM checksum self-test: %s (%#8.8x).\n",
- self_test_results[1] & 0x1000 ? "failed" : "passed",
- self_test_results[1] & 0x0020 ? "failed" : "passed",
- self_test_results[1] & 0x0008 ? "failed" : "passed",
- self_test_results[1] & 0x0004 ? "failed" : "passed",
- self_test_results[0]);
- }
-#endif /* kernel_bloat */
-
- iowrite32(PortReset, ioaddr + SCBPort);
- ioread32(ioaddr + SCBPort);
- udelay(10);
-
- /* Return the chip to its original power state. */
- pci_set_power_state(pdev, acpi_idle_state);
-
- pci_set_drvdata (pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- dev->irq = pdev->irq;
-
- sp->pdev = pdev;
- sp->msg_enable = DEBUG;
- sp->acpi_pwr = acpi_idle_state;
- sp->tx_ring = tx_ring_space;
- sp->tx_ring_dma = tx_ring_dma;
- sp->lstats = (struct speedo_stats *)(sp->tx_ring + TX_RING_SIZE);
- sp->lstats_dma = TX_RING_ELEM_DMA(sp, TX_RING_SIZE);
- init_timer(&sp->timer); /* used in ioctl() */
- spin_lock_init(&sp->lock);
-
- sp->mii_if.full_duplex = option >= 0 && (option & 0x10) ? 1 : 0;
- if (card_idx >= 0) {
- if (full_duplex[card_idx] >= 0)
- sp->mii_if.full_duplex = full_duplex[card_idx];
- }
- sp->default_port = option >= 0 ? (option & 0x0f) : 0;
-
- sp->phy[0] = eeprom[6];
- sp->phy[1] = eeprom[7];
-
- sp->mii_if.phy_id = eeprom[6] & 0x1f;
- sp->mii_if.phy_id_mask = 0x1f;
- sp->mii_if.reg_num_mask = 0x1f;
- sp->mii_if.dev = dev;
- sp->mii_if.mdio_read = mdio_read;
- sp->mii_if.mdio_write = mdio_write;
-
- sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1;
- if (((pdev->device > 0x1030 && (pdev->device < 0x103F)))
- || (pdev->device == 0x2449) || (pdev->device == 0x2459)
- || (pdev->device == 0x245D)) {
- sp->chip_id = 1;
- }
-
- if (sp->rx_bug)
- printk(KERN_INFO " Receiver lock-up workaround activated.\n");
-
- /* The Speedo-specific entries in the device structure. */
- dev->open = &speedo_open;
- dev->hard_start_xmit = &speedo_start_xmit;
- netif_set_tx_timeout(dev, &speedo_tx_timeout, TX_TIMEOUT);
- dev->stop = &speedo_close;
- dev->get_stats = &speedo_get_stats;
- dev->set_multicast_list = &set_rx_mode;
- dev->do_ioctl = &speedo_ioctl;
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = &poll_speedo;
-#endif
-
- if (register_netdevice(dev))
- goto err_free_unlock;
- rtnl_unlock();
-
- return 0;
-
- err_free_unlock:
- rtnl_unlock();
- free_netdev(dev);
- return -1;
-}
-
-static void do_slow_command(struct net_device *dev, struct speedo_private *sp, int cmd)
-{
- void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
- int wait = 0;
- do
- if (ioread8(cmd_ioaddr) == 0) break;
- while(++wait <= 200);
- if (wait > 100)
- printk(KERN_ERR "Command %4.4x never accepted (%d polls)!\n",
- ioread8(cmd_ioaddr), wait);
-
- iowrite8(cmd, cmd_ioaddr);
-
- for (wait = 0; wait <= 100; wait++)
- if (ioread8(cmd_ioaddr) == 0) return;
- for (; wait <= 20000; wait++)
- if (ioread8(cmd_ioaddr) == 0) return;
- else udelay(1);
- printk(KERN_ERR "Command %4.4x was not accepted after %d polls!"
- " Current status %8.8x.\n",
- cmd, wait, ioread32(sp->regs + SCBStatus));
-}
-
-/* Serial EEPROM section.
- A "bit" grungy, but we work our way through bit-by-bit :->. */
-/* EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */
-#define EE_CS 0x02 /* EEPROM chip select. */
-#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
-#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
-#define EE_ENB (0x4800 | EE_CS)
-#define EE_WRITE_0 0x4802
-#define EE_WRITE_1 0x4806
-#define EE_OFFSET SCBeeprom
-
-/* The fixes for the code were kindly provided by Dragan Stancevic
- <visitor@valinux.com> to strictly follow Intel specifications of EEPROM
- access timing.
- The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
- interval for serial EEPROM. However, it looks like that there is an
- additional requirement dictating larger udelay's in the code below.
- 2000/05/24 SAW */
-static int __devinit do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len)
-{
- unsigned retval = 0;
- void __iomem *ee_addr = ioaddr + SCBeeprom;
-
- iowrite16(EE_ENB, ee_addr); udelay(2);
- iowrite16(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
-
- /* Shift the command bits out. */
- do {
- short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
- iowrite16(dataval, ee_addr); udelay(2);
- iowrite16(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
- retval = (retval << 1) | ((ioread16(ee_addr) & EE_DATA_READ) ? 1 : 0);
- } while (--cmd_len >= 0);
- iowrite16(EE_ENB, ee_addr); udelay(2);
-
- /* Terminate the EEPROM access. */
- iowrite16(EE_ENB & ~EE_CS, ee_addr);
- return retval;
-}
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */
- iowrite32(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
- do {
- val = ioread32(ioaddr + SCBCtrlMDI);
- if (--boguscnt < 0) {
- printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val);
- break;
- }
- } while (! (val & 0x10000000));
- return val & 0xffff;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */
- iowrite32(0x04000000 | (location<<16) | (phy_id<<21) | value,
- ioaddr + SCBCtrlMDI);
- do {
- val = ioread32(ioaddr + SCBCtrlMDI);
- if (--boguscnt < 0) {
- printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val);
- break;
- }
- } while (! (val & 0x10000000));
-}
-
-static int
-speedo_open(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int retval;
-
- if (netif_msg_ifup(sp))
- printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
-
- pci_set_power_state(sp->pdev, PCI_D0);
-
- /* Set up the Tx queue early.. */
- sp->cur_tx = 0;
- sp->dirty_tx = 0;
- sp->last_cmd = NULL;
- sp->tx_full = 0;
- sp->in_interrupt = 0;
-
- /* .. we can safely take handler calls during init. */
- retval = request_irq(dev->irq, &speedo_interrupt, IRQF_SHARED, dev->name, dev);
- if (retval) {
- return retval;
- }
-
- dev->if_port = sp->default_port;
-
-#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us
- /* Retrigger negotiation to reset previous errors. */
- if ((sp->phy[0] & 0x8000) == 0) {
- int phy_addr = sp->phy[0] & 0x1f ;
- /* Use 0x3300 for restarting NWay, other values to force xcvr:
- 0x0000 10-HD
- 0x0100 10-FD
- 0x2000 100-HD
- 0x2100 100-FD
- */
-#ifdef honor_default_port
- mdio_write(dev, phy_addr, MII_BMCR, mii_ctrl[dev->default_port & 7]);
-#else
- mdio_write(dev, phy_addr, MII_BMCR, 0x3300);
-#endif
- }
-#endif
-
- speedo_init_rx_ring(dev);
-
- /* Fire up the hardware. */
- iowrite16(SCBMaskAll, ioaddr + SCBCmd);
- speedo_resume(dev);
-
- netdevice_start(dev);
- netif_start_queue(dev);
-
- /* Setup the chip and configure the multicast list. */
- sp->mc_setup_head = NULL;
- sp->mc_setup_tail = NULL;
- sp->flow_ctrl = sp->partner = 0;
- sp->rx_mode = -1; /* Invalid -> always reset the mode. */
- set_rx_mode(dev);
- if ((sp->phy[0] & 0x8000) == 0)
- sp->mii_if.advertising = mdio_read(dev, sp->phy[0] & 0x1f, MII_ADVERTISE);
-
- mii_check_link(&sp->mii_if);
-
- if (netif_msg_ifup(sp)) {
- printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
- dev->name, ioread16(ioaddr + SCBStatus));
- }
-
- /* Set the timer. The timer serves a dual purpose:
- 1) to monitor the media interface (e.g. link beat) and perhaps switch
- to an alternate media type
- 2) to monitor Rx activity, and restart the Rx process if the receiver
- hangs. */
- sp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */
- sp->timer.data = (unsigned long)dev;
- sp->timer.function = &speedo_timer; /* timer handler */
- add_timer(&sp->timer);
-
- /* No need to wait for the command unit to accept here. */
- if ((sp->phy[0] & 0x8000) == 0)
- mdio_read(dev, sp->phy[0] & 0x1f, MII_BMCR);
-
- return 0;
-}
-
-/* Start the chip hardware after a full reset. */
-static void speedo_resume(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
-
- /* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */
- sp->tx_threshold = 0x01208000;
-
- /* Set the segment registers to '0'. */
- if (wait_for_cmd_done(dev, sp) != 0) {
- iowrite32(PortPartialReset, ioaddr + SCBPort);
- udelay(10);
- }
-
- iowrite32(0, ioaddr + SCBPointer);
- ioread32(ioaddr + SCBPointer); /* Flush to PCI. */
- udelay(10); /* Bogus, but it avoids the bug. */
-
- /* Note: these next two operations can take a while. */
- do_slow_command(dev, sp, RxAddrLoad);
- do_slow_command(dev, sp, CUCmdBase);
-
- /* Load the statistics block and rx ring addresses. */
- iowrite32(sp->lstats_dma, ioaddr + SCBPointer);
- ioread32(ioaddr + SCBPointer); /* Flush to PCI */
-
- iowrite8(CUStatsAddr, ioaddr + SCBCmd);
- sp->lstats->done_marker = 0;
- wait_for_cmd_done(dev, sp);
-
- if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {
- if (netif_msg_rx_err(sp))
- printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",
- dev->name);
- } else {
- iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
- ioaddr + SCBPointer);
- ioread32(ioaddr + SCBPointer); /* Flush to PCI */
- }
-
- /* Note: RxStart should complete instantly. */
- do_slow_command(dev, sp, RxStart);
- do_slow_command(dev, sp, CUDumpStats);
-
- /* Fill the first command with our physical address. */
- {
- struct descriptor *ias_cmd;
-
- ias_cmd =
- (struct descriptor *)&sp->tx_ring[sp->cur_tx++ % TX_RING_SIZE];
- /* Avoid a bug(?!) here by marking the command already completed. */
- ias_cmd->cmd_status = cpu_to_le32((CmdSuspend | CmdIASetup) | 0xa000);
- ias_cmd->link =
- cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));
- memcpy(ias_cmd->params, dev->dev_addr, 6);
- if (sp->last_cmd)
- clear_suspend(sp->last_cmd);
- sp->last_cmd = ias_cmd;
- }
-
- /* Start the chip's Tx process and unmask interrupts. */
- iowrite32(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),
- ioaddr + SCBPointer);
- /* We are not ACK-ing FCP and ER in the interrupt handler yet so they should
- remain masked --Dragan */
- iowrite16(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);
-}
-
-/*
- * Sometimes the receiver stops making progress. This routine knows how to
- * get it going again, without losing packets or being otherwise nasty like
- * a chip reset would be. Previously the driver had a whole sequence
- * of if RxSuspended, if it's no buffers do one thing, if it's no resources,
- * do another, etc. But those things don't really matter. Separate logic
- * in the ISR provides for allocating buffers--the other half of operation
- * is just making sure the receiver is active. speedo_rx_soft_reset does that.
- * This problem with the old, more involved algorithm is shown up under
- * ping floods on the order of 60K packets/second on a 100Mbps fdx network.
- */
-static void
-speedo_rx_soft_reset(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- struct RxFD *rfd;
- void __iomem *ioaddr;
-
- ioaddr = sp->regs;
- if (wait_for_cmd_done(dev, sp) != 0) {
- printk("%s: previous command stalled\n", dev->name);
- return;
- }
- /*
- * Put the hardware into a known state.
- */
- iowrite8(RxAbort, ioaddr + SCBCmd);
-
- rfd = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
-
- rfd->rx_buf_addr = cpu_to_le32(0xffffffff);
-
- if (wait_for_cmd_done(dev, sp) != 0) {
- printk("%s: RxAbort command stalled\n", dev->name);
- return;
- }
- iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
- ioaddr + SCBPointer);
- iowrite8(RxStart, ioaddr + SCBCmd);
-}
-
-
-/* Media monitoring and control. */
-static void speedo_timer(unsigned long data)
-{
- struct net_device *dev = (struct net_device *)data;
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int phy_num = sp->phy[0] & 0x1f;
-
- /* We have MII and lost link beat. */
- if ((sp->phy[0] & 0x8000) == 0) {
- int partner = mdio_read(dev, phy_num, MII_LPA);
- if (partner != sp->partner) {
- int flow_ctrl = sp->mii_if.advertising & partner & 0x0400 ? 1 : 0;
- if (netif_msg_link(sp)) {
- printk(KERN_DEBUG "%s: Link status change.\n", dev->name);
- printk(KERN_DEBUG "%s: Old partner %x, new %x, adv %x.\n",
- dev->name, sp->partner, partner, sp->mii_if.advertising);
- }
- sp->partner = partner;
- if (flow_ctrl != sp->flow_ctrl) {
- sp->flow_ctrl = flow_ctrl;
- sp->rx_mode = -1; /* Trigger a reload. */
- }
- }
- }
- mii_check_link(&sp->mii_if);
- if (netif_msg_timer(sp)) {
- printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",
- dev->name, ioread16(ioaddr + SCBStatus));
- }
- if (sp->rx_mode < 0 ||
- (sp->rx_bug && jiffies - sp->last_rx_time > 2*HZ)) {
- /* We haven't received a packet in a Long Time. We might have been
- bitten by the receiver hang bug. This can be cleared by sending
- a set multicast list command. */
- if (netif_msg_timer(sp))
- printk(KERN_DEBUG "%s: Sending a multicast list set command"
- " from a timer routine,"
- " m=%d, j=%ld, l=%ld.\n",
- dev->name, sp->rx_mode, jiffies, sp->last_rx_time);
- set_rx_mode(dev);
- }
- /* We must continue to monitor the media. */
- sp->timer.expires = RUN_AT(2*HZ); /* 2.0 sec. */
- add_timer(&sp->timer);
-}
-
-static void speedo_show_state(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- int i;
-
- if (netif_msg_pktdata(sp)) {
- printk(KERN_DEBUG "%s: Tx ring dump, Tx queue %u / %u:\n",
- dev->name, sp->cur_tx, sp->dirty_tx);
- for (i = 0; i < TX_RING_SIZE; i++)
- printk(KERN_DEBUG "%s: %c%c%2d %8.8x.\n", dev->name,
- i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ',
- i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ',
- i, sp->tx_ring[i].status);
-
- printk(KERN_DEBUG "%s: Printing Rx ring"
- " (next to receive into %u, dirty index %u).\n",
- dev->name, sp->cur_rx, sp->dirty_rx);
- for (i = 0; i < RX_RING_SIZE; i++)
- printk(KERN_DEBUG "%s: %c%c%c%2d %8.8x.\n", dev->name,
- sp->rx_ringp[i] == sp->last_rxf ? 'l' : ' ',
- i == sp->dirty_rx % RX_RING_SIZE ? '*' : ' ',
- i == sp->cur_rx % RX_RING_SIZE ? '=' : ' ',
- i, (sp->rx_ringp[i] != NULL) ?
- (unsigned)sp->rx_ringp[i]->status : 0);
- }
-
-#if 0
- {
- void __iomem *ioaddr = sp->regs;
- int phy_num = sp->phy[0] & 0x1f;
- for (i = 0; i < 16; i++) {
- /* FIXME: what does it mean? --SAW */
- if (i == 6) i = 21;
- printk(KERN_DEBUG "%s: PHY index %d register %d is %4.4x.\n",
- dev->name, phy_num, i, mdio_read(dev, phy_num, i));
- }
- }
-#endif
-
-}
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void
-speedo_init_rx_ring(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- struct RxFD *rxf, *last_rxf = NULL;
- dma_addr_t last_rxf_dma = 0 /* to shut up the compiler */;
- int i;
-
- sp->cur_rx = 0;
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb;
- skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
- if (skb)
- rx_align(skb); /* Align IP on 16 byte boundary */
- sp->rx_skbuff[i] = skb;
- if (skb == NULL)
- break; /* OK. Just initially short of Rx bufs. */
- skb->dev = dev; /* Mark as being used by this device. */
- rxf = (struct RxFD *)skb->data;
- sp->rx_ringp[i] = rxf;
- sp->rx_ring_dma[i] =
- pci_map_single(sp->pdev, rxf,
- PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_BIDIRECTIONAL);
- skb_reserve(skb, sizeof(struct RxFD));
- if (last_rxf) {
- last_rxf->link = cpu_to_le32(sp->rx_ring_dma[i]);
- pci_dma_sync_single_for_device(sp->pdev, last_rxf_dma,
- sizeof(struct RxFD), PCI_DMA_TODEVICE);
- }
- last_rxf = rxf;
- last_rxf_dma = sp->rx_ring_dma[i];
- rxf->status = cpu_to_le32(0x00000001); /* '1' is flag value only. */
- rxf->link = 0; /* None yet. */
- /* This field unused by i82557. */
- rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
- rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
- pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[i],
- sizeof(struct RxFD), PCI_DMA_TODEVICE);
- }
- sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
- /* Mark the last entry as end-of-list. */
- last_rxf->status = cpu_to_le32(0xC0000002); /* '2' is flag value only. */
- pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[RX_RING_SIZE-1],
- sizeof(struct RxFD), PCI_DMA_TODEVICE);
- sp->last_rxf = last_rxf;
- sp->last_rxf_dma = last_rxf_dma;
-}
-
-static void speedo_purge_tx(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- int entry;
-
- while ((int)(sp->cur_tx - sp->dirty_tx) > 0) {
- entry = sp->dirty_tx % TX_RING_SIZE;
- if (sp->tx_skbuff[entry]) {
- sp->stats.tx_errors++;
- pci_unmap_single(sp->pdev,
- le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0),
- sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(sp->tx_skbuff[entry]);
- sp->tx_skbuff[entry] = NULL;
- }
- sp->dirty_tx++;
- }
- while (sp->mc_setup_head != NULL) {
- struct speedo_mc_block *t;
- if (netif_msg_tx_err(sp))
- printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name);
- pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma,
- sp->mc_setup_head->len, PCI_DMA_TODEVICE);
- t = sp->mc_setup_head->next;
- kfree(sp->mc_setup_head);
- sp->mc_setup_head = t;
- }
- sp->mc_setup_tail = NULL;
- sp->tx_full = 0;
- netif_wake_queue(dev);
-}
-
-static void reset_mii(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
-
- /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */
- if ((sp->phy[0] & 0x8000) == 0) {
- int phy_addr = sp->phy[0] & 0x1f;
- int advertising = mdio_read(dev, phy_addr, MII_ADVERTISE);
- int mii_bmcr = mdio_read(dev, phy_addr, MII_BMCR);
- mdio_write(dev, phy_addr, MII_BMCR, 0x0400);
- mdio_write(dev, phy_addr, MII_BMSR, 0x0000);
- mdio_write(dev, phy_addr, MII_ADVERTISE, 0x0000);
- mdio_write(dev, phy_addr, MII_BMCR, 0x8000);
-#ifdef honor_default_port
- mdio_write(dev, phy_addr, MII_BMCR, mii_ctrl[dev->default_port & 7]);
-#else
- mdio_read(dev, phy_addr, MII_BMCR);
- mdio_write(dev, phy_addr, MII_BMCR, mii_bmcr);
- mdio_write(dev, phy_addr, MII_ADVERTISE, advertising);
-#endif
- }
-}
-
-static void speedo_tx_timeout(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int status = ioread16(ioaddr + SCBStatus);
- unsigned long flags;
-
- if (netif_msg_tx_err(sp)) {
- printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
- " %4.4x at %d/%d command %8.8x.\n",
- dev->name, status, ioread16(ioaddr + SCBCmd),
- sp->dirty_tx, sp->cur_tx,
- sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
-
- }
- speedo_show_state(dev);
-#if 0
- if ((status & 0x00C0) != 0x0080
- && (status & 0x003C) == 0x0010) {
- /* Only the command unit has stopped. */
- printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
- dev->name);
- iowrite32(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE]),
- ioaddr + SCBPointer);
- iowrite16(CUStart, ioaddr + SCBCmd);
- reset_mii(dev);
- } else {
-#else
- {
-#endif
- del_timer_sync(&sp->timer);
- /* Reset the Tx and Rx units. */
- iowrite32(PortReset, ioaddr + SCBPort);
- /* We may get spurious interrupts here. But I don't think that they
- may do much harm. 1999/12/09 SAW */
- udelay(10);
- /* Disable interrupts. */
- iowrite16(SCBMaskAll, ioaddr + SCBCmd);
- synchronize_irq(dev->irq);
- speedo_tx_buffer_gc(dev);
- /* Free as much as possible.
- It helps to recover from a hang because of out-of-memory.
- It also simplifies speedo_resume() in case TX ring is full or
- close-to-be full. */
- speedo_purge_tx(dev);
- speedo_refill_rx_buffers(dev, 1);
- spin_lock_irqsave(&sp->lock, flags);
- speedo_resume(dev);
- sp->rx_mode = -1;
- dev->trans_start = jiffies;
- spin_unlock_irqrestore(&sp->lock, flags);
- set_rx_mode(dev); /* it takes the spinlock itself --SAW */
- /* Reset MII transceiver. Do it before starting the timer to serialize
- mdio_xxx operations. Yes, it's a paranoya :-) 2000/05/09 SAW */
- reset_mii(dev);
- sp->timer.expires = RUN_AT(2*HZ);
- add_timer(&sp->timer);
- }
- return;
-}
-
-static int
-speedo_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int entry;
-
- /* Prevent interrupts from changing the Tx ring from underneath us. */
- unsigned long flags;
-
- spin_lock_irqsave(&sp->lock, flags);
-
- /* Check if there are enough space. */
- if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
- printk(KERN_ERR "%s: incorrect tbusy state, fixed.\n", dev->name);
- netif_stop_queue(dev);
- sp->tx_full = 1;
- spin_unlock_irqrestore(&sp->lock, flags);
- return 1;
- }
-
- /* Calculate the Tx descriptor entry. */
- entry = sp->cur_tx++ % TX_RING_SIZE;
-
- sp->tx_skbuff[entry] = skb;
- sp->tx_ring[entry].status =
- cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex);
- if (!(entry & ((TX_RING_SIZE>>2)-1)))
- sp->tx_ring[entry].status |= cpu_to_le32(CmdIntr);
- sp->tx_ring[entry].link =
- cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));
- sp->tx_ring[entry].tx_desc_addr =
- cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET);
- /* The data region is always in one buffer descriptor. */
- sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold);
- sp->tx_ring[entry].tx_buf_addr0 =
- cpu_to_le32(pci_map_single(sp->pdev, skb->data,
- skb->len, PCI_DMA_TODEVICE));
- sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len);
-
- /* workaround for hardware bug on 10 mbit half duplex */
-
- if ((sp->partner == 0) && (sp->chip_id == 1)) {
- wait_for_cmd_done(dev, sp);
- iowrite8(0 , ioaddr + SCBCmd);
- udelay(1);
- }
-
- /* Trigger the command unit resume. */
- wait_for_cmd_done(dev, sp);
- clear_suspend(sp->last_cmd);
- /* We want the time window between clearing suspend flag on the previous
- command and resuming CU to be as small as possible.
- Interrupts in between are very undesired. --SAW */
- iowrite8(CUResume, ioaddr + SCBCmd);
- sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
-
- /* Leave room for set_rx_mode(). If there is no more space than reserved
- for multicast filter mark the ring as full. */
- if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
- netif_stop_queue(dev);
- sp->tx_full = 1;
- }
-
- spin_unlock_irqrestore(&sp->lock, flags);
-
- dev->trans_start = jiffies;
-
- return 0;
-}
-
-static void speedo_tx_buffer_gc(struct net_device *dev)
-{
- unsigned int dirty_tx;
- struct speedo_private *sp = netdev_priv(dev);
-
- dirty_tx = sp->dirty_tx;
- while ((int)(sp->cur_tx - dirty_tx) > 0) {
- int entry = dirty_tx % TX_RING_SIZE;
- int status = le32_to_cpu(sp->tx_ring[entry].status);
-
- if (netif_msg_tx_done(sp))
- printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n",
- entry, status);
- if ((status & StatusComplete) == 0)
- break; /* It still hasn't been processed. */
- if (status & TxUnderrun)
- if (sp->tx_threshold < 0x01e08000) {
- if (netif_msg_tx_err(sp))
- printk(KERN_DEBUG "%s: TX underrun, threshold adjusted.\n",
- dev->name);
- sp->tx_threshold += 0x00040000;
- }
- /* Free the original skb. */
- if (sp->tx_skbuff[entry]) {
- sp->stats.tx_packets++; /* Count only user packets. */
- sp->stats.tx_bytes += sp->tx_skbuff[entry]->len;
- pci_unmap_single(sp->pdev,
- le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0),
- sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(sp->tx_skbuff[entry]);
- sp->tx_skbuff[entry] = NULL;
- }
- dirty_tx++;
- }
-
- if (netif_msg_tx_err(sp) && (int)(sp->cur_tx - dirty_tx) > TX_RING_SIZE) {
- printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d,"
- " full=%d.\n",
- dirty_tx, sp->cur_tx, sp->tx_full);
- dirty_tx += TX_RING_SIZE;
- }
-
- while (sp->mc_setup_head != NULL
- && (int)(dirty_tx - sp->mc_setup_head->tx - 1) > 0) {
- struct speedo_mc_block *t;
- if (netif_msg_tx_err(sp))
- printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name);
- pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma,
- sp->mc_setup_head->len, PCI_DMA_TODEVICE);
- t = sp->mc_setup_head->next;
- kfree(sp->mc_setup_head);
- sp->mc_setup_head = t;
- }
- if (sp->mc_setup_head == NULL)
- sp->mc_setup_tail = NULL;
-
- sp->dirty_tx = dirty_tx;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
- after the Tx thread. */
-static irqreturn_t speedo_interrupt(int irq, void *dev_instance)
-{
- struct net_device *dev = (struct net_device *)dev_instance;
- struct speedo_private *sp;
- void __iomem *ioaddr;
- long boguscnt = max_interrupt_work;
- unsigned short status;
- unsigned int handled = 0;
-
- sp = netdev_priv(dev);
- ioaddr = sp->regs;
-
-#ifndef final_version
- /* A lock to prevent simultaneous entry on SMP machines. */
- if (test_and_set_bit(0, (void*)&sp->in_interrupt)) {
- printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n",
- dev->name);
- sp->in_interrupt = 0; /* Avoid halting machine. */
- return IRQ_NONE;
- }
-#endif
-
- do {
- status = ioread16(ioaddr + SCBStatus);
- /* Acknowledge all of the current interrupt sources ASAP. */
- /* Will change from 0xfc00 to 0xff00 when we start handling
- FCP and ER interrupts --Dragan */
- iowrite16(status & 0xfc00, ioaddr + SCBStatus);
-
- if (netif_msg_intr(sp))
- printk(KERN_DEBUG "%s: interrupt status=%#4.4x.\n",
- dev->name, status);
-
- if ((status & 0xfc00) == 0)
- break;
- handled = 1;
-
-
- if ((status & 0x5000) || /* Packet received, or Rx error. */
- (sp->rx_ring_state&(RrNoMem|RrPostponed)) == RrPostponed)
- /* Need to gather the postponed packet. */
- speedo_rx(dev);
-
- /* Always check if all rx buffers are allocated. --SAW */
- speedo_refill_rx_buffers(dev, 0);
-
- spin_lock(&sp->lock);
- /*
- * The chip may have suspended reception for various reasons.
- * Check for that, and re-prime it should this be the case.
- */
- switch ((status >> 2) & 0xf) {
- case 0: /* Idle */
- break;
- case 1: /* Suspended */
- case 2: /* No resources (RxFDs) */
- case 9: /* Suspended with no more RBDs */
- case 10: /* No resources due to no RBDs */
- case 12: /* Ready with no RBDs */
- speedo_rx_soft_reset(dev);
- break;
- case 3: case 5: case 6: case 7: case 8:
- case 11: case 13: case 14: case 15:
- /* these are all reserved values */
- break;
- }
-
-
- /* User interrupt, Command/Tx unit interrupt or CU not active. */
- if (status & 0xA400) {
- speedo_tx_buffer_gc(dev);
- if (sp->tx_full
- && (int)(sp->cur_tx - sp->dirty_tx) < TX_QUEUE_UNFULL) {
- /* The ring is no longer full. */
- sp->tx_full = 0;
- netif_wake_queue(dev); /* Attention: under a spinlock. --SAW */
- }
- }
-
- spin_unlock(&sp->lock);
-
- if (--boguscnt < 0) {
- printk(KERN_ERR "%s: Too much work at interrupt, status=0x%4.4x.\n",
- dev->name, status);
- /* Clear all interrupt sources. */
- /* Will change from 0xfc00 to 0xff00 when we start handling
- FCP and ER interrupts --Dragan */
- iowrite16(0xfc00, ioaddr + SCBStatus);
- break;
- }
- } while (1);
-
- if (netif_msg_intr(sp))
- printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
- dev->name, ioread16(ioaddr + SCBStatus));
-
- clear_bit(0, (void*)&sp->in_interrupt);
- return IRQ_RETVAL(handled);
-}
-
-static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
-{
- struct speedo_private *sp = netdev_priv(dev);
- struct RxFD *rxf;
- struct sk_buff *skb;
- /* Get a fresh skbuff to replace the consumed one. */
- skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
- if (skb)
- rx_align(skb); /* Align IP on 16 byte boundary */
- sp->rx_skbuff[entry] = skb;
- if (skb == NULL) {
- sp->rx_ringp[entry] = NULL;
- return NULL;
- }
- rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data;
- sp->rx_ring_dma[entry] =
- pci_map_single(sp->pdev, rxf,
- PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
- skb->dev = dev;
- skb_reserve(skb, sizeof(struct RxFD));
- rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
- pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
- sizeof(struct RxFD), PCI_DMA_TODEVICE);
- return rxf;
-}
-
-static inline void speedo_rx_link(struct net_device *dev, int entry,
- struct RxFD *rxf, dma_addr_t rxf_dma)
-{
- struct speedo_private *sp = netdev_priv(dev);
- rxf->status = cpu_to_le32(0xC0000001); /* '1' for driver use only. */
- rxf->link = 0; /* None yet. */
- rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
- sp->last_rxf->link = cpu_to_le32(rxf_dma);
- sp->last_rxf->status &= cpu_to_le32(~0xC0000000);
- pci_dma_sync_single_for_device(sp->pdev, sp->last_rxf_dma,
- sizeof(struct RxFD), PCI_DMA_TODEVICE);
- sp->last_rxf = rxf;
- sp->last_rxf_dma = rxf_dma;
-}
-
-static int speedo_refill_rx_buf(struct net_device *dev, int force)
-{
- struct speedo_private *sp = netdev_priv(dev);
- int entry;
- struct RxFD *rxf;
-
- entry = sp->dirty_rx % RX_RING_SIZE;
- if (sp->rx_skbuff[entry] == NULL) {
- rxf = speedo_rx_alloc(dev, entry);
- if (rxf == NULL) {
- unsigned int forw;
- int forw_entry;
- if (netif_msg_rx_err(sp) || !(sp->rx_ring_state & RrOOMReported)) {
- printk(KERN_WARNING "%s: can't fill rx buffer (force %d)!\n",
- dev->name, force);
- sp->rx_ring_state |= RrOOMReported;
- }
- speedo_show_state(dev);
- if (!force)
- return -1; /* Better luck next time! */
- /* Borrow an skb from one of next entries. */
- for (forw = sp->dirty_rx + 1; forw != sp->cur_rx; forw++)
- if (sp->rx_skbuff[forw % RX_RING_SIZE] != NULL)
- break;
- if (forw == sp->cur_rx)
- return -1;
- forw_entry = forw % RX_RING_SIZE;
- sp->rx_skbuff[entry] = sp->rx_skbuff[forw_entry];
- sp->rx_skbuff[forw_entry] = NULL;
- rxf = sp->rx_ringp[forw_entry];
- sp->rx_ringp[forw_entry] = NULL;
- sp->rx_ringp[entry] = rxf;
- }
- } else {
- rxf = sp->rx_ringp[entry];
- }
- speedo_rx_link(dev, entry, rxf, sp->rx_ring_dma[entry]);
- sp->dirty_rx++;
- sp->rx_ring_state &= ~(RrNoMem|RrOOMReported); /* Mark the progress. */
- return 0;
-}
-
-static void speedo_refill_rx_buffers(struct net_device *dev, int force)
-{
- struct speedo_private *sp = netdev_priv(dev);
-
- /* Refill the RX ring. */
- while ((int)(sp->cur_rx - sp->dirty_rx) > 0 &&
- speedo_refill_rx_buf(dev, force) != -1);
-}
-
-static int
-speedo_rx(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- int entry = sp->cur_rx % RX_RING_SIZE;
- int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx;
- int alloc_ok = 1;
- int npkts = 0;
-
- if (netif_msg_intr(sp))
- printk(KERN_DEBUG " In speedo_rx().\n");
- /* If we own the next entry, it's a new packet. Send it up. */
- while (sp->rx_ringp[entry] != NULL) {
- int status;
- int pkt_len;
-
- pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry],
- sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
- status = le32_to_cpu(sp->rx_ringp[entry]->status);
- pkt_len = le32_to_cpu(sp->rx_ringp[entry]->count) & 0x3fff;
-
- if (!(status & RxComplete))
- break;
-
- if (--rx_work_limit < 0)
- break;
-
- /* Check for a rare out-of-memory case: the current buffer is
- the last buffer allocated in the RX ring. --SAW */
- if (sp->last_rxf == sp->rx_ringp[entry]) {
- /* Postpone the packet. It'll be reaped at an interrupt when this
- packet is no longer the last packet in the ring. */
- if (netif_msg_rx_err(sp))
- printk(KERN_DEBUG "%s: RX packet postponed!\n",
- dev->name);
- sp->rx_ring_state |= RrPostponed;
- break;
- }
-
- if (netif_msg_rx_status(sp))
- printk(KERN_DEBUG " speedo_rx() status %8.8x len %d.\n", status,
- pkt_len);
- if ((status & (RxErrTooBig|RxOK|0x0f90)) != RxOK) {
- if (status & RxErrTooBig)
- printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, "
- "status %8.8x!\n", dev->name, status);
- else if (! (status & RxOK)) {
- /* There was a fatal error. This *should* be impossible. */
- sp->stats.rx_errors++;
- printk(KERN_ERR "%s: Anomalous event in speedo_rx(), "
- "status %8.8x.\n",
- dev->name, status);
- }
- } else {
- struct sk_buff *skb;
-
- /* Check if the packet is long enough to just accept without
- copying to a properly sized skbuff. */
- if (pkt_len < rx_copybreak
- && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
- skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- /* 'skb_put()' points to the start of sk_buff data area. */
- pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry],
- sizeof(struct RxFD) + pkt_len,
- PCI_DMA_FROMDEVICE);
-
-#if 1 || USE_IP_CSUM
- /* Packet is in one chunk -- we can copy + cksum. */
- skb_copy_to_linear_data(skb, sp->rx_skbuff[entry]->data, pkt_len);
- skb_put(skb, pkt_len);
-#else
- skb_copy_from_linear_data(sp->rx_skbuff[entry],
- skb_put(skb, pkt_len),
- pkt_len);
-#endif
- pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
- sizeof(struct RxFD) + pkt_len,
- PCI_DMA_FROMDEVICE);
- npkts++;
- } else {
- /* Pass up the already-filled skbuff. */
- skb = sp->rx_skbuff[entry];
- if (skb == NULL) {
- printk(KERN_ERR "%s: Inconsistent Rx descriptor chain.\n",
- dev->name);
- break;
- }
- sp->rx_skbuff[entry] = NULL;
- skb_put(skb, pkt_len);
- npkts++;
- sp->rx_ringp[entry] = NULL;
- pci_unmap_single(sp->pdev, sp->rx_ring_dma[entry],
- PKT_BUF_SZ + sizeof(struct RxFD),
- PCI_DMA_FROMDEVICE);
- }
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- sp->stats.rx_packets++;
- sp->stats.rx_bytes += pkt_len;
- }
- entry = (++sp->cur_rx) % RX_RING_SIZE;
- sp->rx_ring_state &= ~RrPostponed;
- /* Refill the recently taken buffers.
- Do it one-by-one to handle traffic bursts better. */
- if (alloc_ok && speedo_refill_rx_buf(dev, 0) == -1)
- alloc_ok = 0;
- }
-
- /* Try hard to refill the recently taken buffers. */
- speedo_refill_rx_buffers(dev, 1);
-
- if (npkts)
- sp->last_rx_time = jiffies;
-
- return 0;
-}
-
-static int
-speedo_close(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int i;
-
- netdevice_stop(dev);
- netif_stop_queue(dev);
-
- if (netif_msg_ifdown(sp))
- printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
- dev->name, ioread16(ioaddr + SCBStatus));
-
- /* Shut off the media monitoring timer. */
- del_timer_sync(&sp->timer);
-
- iowrite16(SCBMaskAll, ioaddr + SCBCmd);
-
- /* Shutting down the chip nicely fails to disable flow control. So.. */
- iowrite32(PortPartialReset, ioaddr + SCBPort);
- ioread32(ioaddr + SCBPort); /* flush posted write */
- /*
- * The chip requires a 10 microsecond quiet period. Wait here!
- */
- udelay(10);
-
- free_irq(dev->irq, dev);
- speedo_show_state(dev);
-
- /* Free all the skbuffs in the Rx and Tx queues. */
- for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = sp->rx_skbuff[i];
- sp->rx_skbuff[i] = NULL;
- /* Clear the Rx descriptors. */
- if (skb) {
- pci_unmap_single(sp->pdev,
- sp->rx_ring_dma[i],
- PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
- dev_kfree_skb(skb);
- }
- }
-
- for (i = 0; i < TX_RING_SIZE; i++) {
- struct sk_buff *skb = sp->tx_skbuff[i];
- sp->tx_skbuff[i] = NULL;
- /* Clear the Tx descriptors. */
- if (skb) {
- pci_unmap_single(sp->pdev,
- le32_to_cpu(sp->tx_ring[i].tx_buf_addr0),
- skb->len, PCI_DMA_TODEVICE);
- dev_kfree_skb(skb);
- }
- }
-
- /* Free multicast setting blocks. */
- for (i = 0; sp->mc_setup_head != NULL; i++) {
- struct speedo_mc_block *t;
- t = sp->mc_setup_head->next;
- kfree(sp->mc_setup_head);
- sp->mc_setup_head = t;
- }
- sp->mc_setup_tail = NULL;
- if (netif_msg_ifdown(sp))
- printk(KERN_DEBUG "%s: %d multicast blocks dropped.\n", dev->name, i);
-
- pci_set_power_state(sp->pdev, PCI_D2);
-
- return 0;
-}
-
-/* The Speedo-3 has an especially awkward and unusable method of getting
- statistics out of the chip. It takes an unpredictable length of time
- for the dump-stats command to complete. To avoid a busy-wait loop we
- update the stats with the previous dump results, and then trigger a
- new dump.
-
- Oh, and incoming frames are dropped while executing dump-stats!
- */
-static struct net_device_stats *
-speedo_get_stats(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
-
- /* Update only if the previous dump finished. */
- if (sp->lstats->done_marker == cpu_to_le32(0xA007)) {
- sp->stats.tx_aborted_errors += le32_to_cpu(sp->lstats->tx_coll16_errs);
- sp->stats.tx_window_errors += le32_to_cpu(sp->lstats->tx_late_colls);
- sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_underruns);
- sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_lost_carrier);
- /*sp->stats.tx_deferred += le32_to_cpu(sp->lstats->tx_deferred);*/
- sp->stats.collisions += le32_to_cpu(sp->lstats->tx_total_colls);
- sp->stats.rx_crc_errors += le32_to_cpu(sp->lstats->rx_crc_errs);
- sp->stats.rx_frame_errors += le32_to_cpu(sp->lstats->rx_align_errs);
- sp->stats.rx_over_errors += le32_to_cpu(sp->lstats->rx_resource_errs);
- sp->stats.rx_fifo_errors += le32_to_cpu(sp->lstats->rx_overrun_errs);
- sp->stats.rx_length_errors += le32_to_cpu(sp->lstats->rx_runt_errs);
- sp->lstats->done_marker = 0x0000;
- if (netif_running(dev)) {
- unsigned long flags;
- /* Take a spinlock to make wait_for_cmd_done and sending the
- command atomic. --SAW */
- spin_lock_irqsave(&sp->lock, flags);
- wait_for_cmd_done(dev, sp);
- iowrite8(CUDumpStats, ioaddr + SCBCmd);
- spin_unlock_irqrestore(&sp->lock, flags);
- }
- }
- return &sp->stats;
-}
-
-static void speedo_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct speedo_private *sp = netdev_priv(dev);
- strncpy(info->driver, "eepro100", sizeof(info->driver)-1);
- strncpy(info->version, version, sizeof(info->version)-1);
- if (sp->pdev)
- strcpy(info->bus_info, pci_name(sp->pdev));
-}
-
-static int speedo_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct speedo_private *sp = netdev_priv(dev);
- spin_lock_irq(&sp->lock);
- mii_ethtool_gset(&sp->mii_if, ecmd);
- spin_unlock_irq(&sp->lock);
- return 0;
-}
-
-static int speedo_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
- struct speedo_private *sp = netdev_priv(dev);
- int res;
- spin_lock_irq(&sp->lock);
- res = mii_ethtool_sset(&sp->mii_if, ecmd);
- spin_unlock_irq(&sp->lock);
- return res;
-}
-
-static int speedo_nway_reset(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- return mii_nway_restart(&sp->mii_if);
-}
-
-static u32 speedo_get_link(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- return mii_link_ok(&sp->mii_if);
-}
-
-static u32 speedo_get_msglevel(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- return sp->msg_enable;
-}
-
-static void speedo_set_msglevel(struct net_device *dev, u32 v)
-{
- struct speedo_private *sp = netdev_priv(dev);
- sp->msg_enable = v;
-}
-
-static const struct ethtool_ops ethtool_ops = {
- .get_drvinfo = speedo_get_drvinfo,
- .get_settings = speedo_get_settings,
- .set_settings = speedo_set_settings,
- .nway_reset = speedo_nway_reset,
- .get_link = speedo_get_link,
- .get_msglevel = speedo_get_msglevel,
- .set_msglevel = speedo_set_msglevel,
-};
-
-static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct speedo_private *sp = netdev_priv(dev);
- struct mii_ioctl_data *data = if_mii(rq);
- int phy = sp->phy[0] & 0x1f;
- int saved_acpi;
- int t;
-
- switch(cmd) {
- case SIOCGMIIPHY: /* Get address of MII PHY in use. */
- data->phy_id = phy;
-
- case SIOCGMIIREG: /* Read MII PHY register. */
- /* FIXME: these operations need to be serialized with MDIO
- access from the timeout handler.
- They are currently serialized only with MDIO access from the
- timer routine. 2000/05/09 SAW */
- saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
- t = del_timer_sync(&sp->timer);
- data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
- if (t)
- add_timer(&sp->timer); /* may be set to the past --SAW */
- pci_set_power_state(sp->pdev, saved_acpi);
- return 0;
-
- case SIOCSMIIREG: /* Write MII PHY register. */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
- t = del_timer_sync(&sp->timer);
- mdio_write(dev, data->phy_id, data->reg_num, data->val_in);
- if (t)
- add_timer(&sp->timer); /* may be set to the past --SAW */
- pci_set_power_state(sp->pdev, saved_acpi);
- return 0;
- default:
- return -EOPNOTSUPP;
- }
-}
-
-/* Set or clear the multicast filter for this adaptor.
- This is very ugly with Intel chips -- we usually have to execute an
- entire configuration command, plus process a multicast command.
- This is complicated. We must put a large configuration command and
- an arbitrarily-sized multicast command in the transmit list.
- To minimize the disruption -- the previous command might have already
- loaded the link -- we convert the current command block, normally a Tx
- command, into a no-op and link it to the new command.
-*/
-static void set_rx_mode(struct net_device *dev)
-{
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- struct descriptor *last_cmd;
- char new_rx_mode;
- unsigned long flags;
- int entry, i;
-
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
- new_rx_mode = 3;
- } else if ((dev->flags & IFF_ALLMULTI) ||
- dev->mc_count > multicast_filter_limit) {
- new_rx_mode = 1;
- } else
- new_rx_mode = 0;
-
- if (netif_msg_rx_status(sp))
- printk(KERN_DEBUG "%s: set_rx_mode %d -> %d\n", dev->name,
- sp->rx_mode, new_rx_mode);
-
- if ((int)(sp->cur_tx - sp->dirty_tx) > TX_RING_SIZE - TX_MULTICAST_SIZE) {
- /* The Tx ring is full -- don't add anything! Hope the mode will be
- * set again later. */
- sp->rx_mode = -1;
- return;
- }
-
- if (new_rx_mode != sp->rx_mode) {
- u8 *config_cmd_data;
-
- spin_lock_irqsave(&sp->lock, flags);
- entry = sp->cur_tx++ % TX_RING_SIZE;
- last_cmd = sp->last_cmd;
- sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
-
- sp->tx_skbuff[entry] = NULL; /* Redundant. */
- sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdConfigure);
- sp->tx_ring[entry].link =
- cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
- config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr;
- /* Construct a full CmdConfig frame. */
- memcpy(config_cmd_data, i82558_config_cmd, CONFIG_DATA_SIZE);
- config_cmd_data[1] = (txfifo << 4) | rxfifo;
- config_cmd_data[4] = rxdmacount;
- config_cmd_data[5] = txdmacount + 0x80;
- config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0;
- /* 0x80 doesn't disable FC 0x84 does.
- Disable Flow control since we are not ACK-ing any FC interrupts
- for now. --Dragan */
- config_cmd_data[19] = 0x84;
- config_cmd_data[19] |= sp->mii_if.full_duplex ? 0x40 : 0;
- config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05;
- if (sp->phy[0] & 0x8000) { /* Use the AUI port instead. */
- config_cmd_data[15] |= 0x80;
- config_cmd_data[8] = 0;
- }
- /* Trigger the command unit resume. */
- wait_for_cmd_done(dev, sp);
- clear_suspend(last_cmd);
- iowrite8(CUResume, ioaddr + SCBCmd);
- if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
- netif_stop_queue(dev);
- sp->tx_full = 1;
- }
- spin_unlock_irqrestore(&sp->lock, flags);
- }
-
- if (new_rx_mode == 0 && dev->mc_count < 4) {
- /* The simple case of 0-3 multicast list entries occurs often, and
- fits within one tx_ring[] entry. */
- struct dev_mc_list *mclist;
- __le16 *setup_params, *eaddrs;
-
- spin_lock_irqsave(&sp->lock, flags);
- entry = sp->cur_tx++ % TX_RING_SIZE;
- last_cmd = sp->last_cmd;
- sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
-
- sp->tx_skbuff[entry] = NULL;
- sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdMulticastList);
- sp->tx_ring[entry].link =
- cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
- sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */
- setup_params = (__le16 *)&sp->tx_ring[entry].tx_desc_addr;
- *setup_params++ = cpu_to_le16(dev->mc_count*6);
- /* Fill in the multicast addresses. */
- for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
- i++, mclist = mclist->next) {
- eaddrs = (__le16 *)mclist->dmi_addr;
- *setup_params++ = *eaddrs++;
- *setup_params++ = *eaddrs++;
- *setup_params++ = *eaddrs++;
- }
-
- wait_for_cmd_done(dev, sp);
- clear_suspend(last_cmd);
- /* Immediately trigger the command unit resume. */
- iowrite8(CUResume, ioaddr + SCBCmd);
-
- if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
- netif_stop_queue(dev);
- sp->tx_full = 1;
- }
- spin_unlock_irqrestore(&sp->lock, flags);
- } else if (new_rx_mode == 0) {
- struct dev_mc_list *mclist;
- __le16 *setup_params, *eaddrs;
- struct speedo_mc_block *mc_blk;
- struct descriptor *mc_setup_frm;
- int i;
-
- mc_blk = kmalloc(sizeof(*mc_blk) + 2 + multicast_filter_limit*6,
- GFP_ATOMIC);
- if (mc_blk == NULL) {
- printk(KERN_ERR "%s: Failed to allocate a setup frame.\n",
- dev->name);
- sp->rx_mode = -1; /* We failed, try again. */
- return;
- }
- mc_blk->next = NULL;
- mc_blk->len = 2 + multicast_filter_limit*6;
- mc_blk->frame_dma =
- pci_map_single(sp->pdev, &mc_blk->frame, mc_blk->len,
- PCI_DMA_TODEVICE);
- mc_setup_frm = &mc_blk->frame;
-
- /* Fill the setup frame. */
- if (netif_msg_ifup(sp))
- printk(KERN_DEBUG "%s: Constructing a setup frame at %p.\n",
- dev->name, mc_setup_frm);
- mc_setup_frm->cmd_status =
- cpu_to_le32(CmdSuspend | CmdIntr | CmdMulticastList);
- /* Link set below. */
- setup_params = (__le16 *)&mc_setup_frm->params;
- *setup_params++ = cpu_to_le16(dev->mc_count*6);
- /* Fill in the multicast addresses. */
- for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
- i++, mclist = mclist->next) {
- eaddrs = (__le16 *)mclist->dmi_addr;
- *setup_params++ = *eaddrs++;
- *setup_params++ = *eaddrs++;
- *setup_params++ = *eaddrs++;
- }
-
- /* Disable interrupts while playing with the Tx Cmd list. */
- spin_lock_irqsave(&sp->lock, flags);
-
- if (sp->mc_setup_tail)
- sp->mc_setup_tail->next = mc_blk;
- else
- sp->mc_setup_head = mc_blk;
- sp->mc_setup_tail = mc_blk;
- mc_blk->tx = sp->cur_tx;
-
- entry = sp->cur_tx++ % TX_RING_SIZE;
- last_cmd = sp->last_cmd;
- sp->last_cmd = mc_setup_frm;
-
- /* Change the command to a NoOp, pointing to the CmdMulti command. */
- sp->tx_skbuff[entry] = NULL;
- sp->tx_ring[entry].status = cpu_to_le32(CmdNOp);
- sp->tx_ring[entry].link = cpu_to_le32(mc_blk->frame_dma);
-
- /* Set the link in the setup frame. */
- mc_setup_frm->link =
- cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
-
- pci_dma_sync_single_for_device(sp->pdev, mc_blk->frame_dma,
- mc_blk->len, PCI_DMA_TODEVICE);
-
- wait_for_cmd_done(dev, sp);
- clear_suspend(last_cmd);
- /* Immediately trigger the command unit resume. */
- iowrite8(CUResume, ioaddr + SCBCmd);
-
- if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
- netif_stop_queue(dev);
- sp->tx_full = 1;
- }
- spin_unlock_irqrestore(&sp->lock, flags);
-
- if (netif_msg_rx_status(sp))
- printk(" CmdMCSetup frame length %d in entry %d.\n",
- dev->mc_count, entry);
- }
-
- sp->rx_mode = new_rx_mode;
-}
-
-#ifdef CONFIG_PM
-static int eepro100_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata (pdev);
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
-
- pci_save_state(pdev);
-
- if (!netif_running(dev))
- return 0;
-
- del_timer_sync(&sp->timer);
-
- netif_device_detach(dev);
- iowrite32(PortPartialReset, ioaddr + SCBPort);
-
- /* XXX call pci_set_power_state ()? */
- pci_disable_device(pdev);
- pci_set_power_state (pdev, PCI_D3hot);
- return 0;
-}
-
-static int eepro100_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata (pdev);
- struct speedo_private *sp = netdev_priv(dev);
- void __iomem *ioaddr = sp->regs;
- int rc;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
- rc = pci_enable_device(pdev);
- if (rc)
- return rc;
-
- pci_set_master(pdev);
-
- if (!netif_running(dev))
- return 0;
-
- /* I'm absolutely uncertain if this part of code may work.
- The problems are:
- - correct hardware reinitialization;
- - correct driver behavior between different steps of the
- reinitialization;
- - serialization with other driver calls.
- 2000/03/08 SAW */
- iowrite16(SCBMaskAll, ioaddr + SCBCmd);
- speedo_resume(dev);
- netif_device_attach(dev);
- sp->rx_mode = -1;
- sp->flow_ctrl = sp->partner = 0;
- set_rx_mode(dev);
- sp->timer.expires = RUN_AT(2*HZ);
- add_timer(&sp->timer);
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static void __devexit eepro100_remove_one (struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata (pdev);
- struct speedo_private *sp = netdev_priv(dev);
-
- unregister_netdev(dev);
-
- release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
- release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-
- pci_iounmap(pdev, sp->regs);
- pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD)
- + sizeof(struct speedo_stats),
- sp->tx_ring, sp->tx_ring_dma);
- pci_disable_device(pdev);
- free_netdev(dev);
-}
-
-static struct pci_device_id eepro100_pci_tbl[] = {
- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
- { 0,}
-};
-MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
-
-static struct pci_driver eepro100_driver = {
- .name = "eepro100",
- .id_table = eepro100_pci_tbl,
- .probe = eepro100_init_one,
- .remove = __devexit_p(eepro100_remove_one),
-#ifdef CONFIG_PM
- .suspend = eepro100_suspend,
- .resume = eepro100_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init eepro100_init_module(void)
-{
-#ifdef MODULE
- printk(version);
-#endif
- return pci_register_driver(&eepro100_driver);
-}
-
-static void __exit eepro100_cleanup_module(void)
-{
- pci_unregister_driver(&eepro100_driver);
-}
-
-module_init(eepro100_init_module);
-module_exit(eepro100_cleanup_module);
-
-/*
- * Local variables:
- * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
- * c-indent-level: 4
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
deleted file mode 100644
index 795c594a4b7..00000000000
--- a/drivers/net/eexpress.c
+++ /dev/null
@@ -1,1719 +0,0 @@
-/* Intel EtherExpress 16 device driver for Linux
- *
- * Written by John Sullivan, 1995
- * based on original code by Donald Becker, with changes by
- * Alan Cox and Pauline Middelink.
- *
- * Support for 8-bit mode by Zoltan Szilagyi <zoltans@cs.arizona.edu>
- *
- * Many modifications, and currently maintained, by
- * Philip Blundell <philb@gnu.org>
- * Added the Compaq LTE Alan Cox <alan@redhat.com>
- * Added MCA support Adam Fritzler
- *
- * Note - this driver is experimental still - it has problems on faster
- * machines. Someone needs to sit down and go through it line by line with
- * a databook...
- */
-
-/* The EtherExpress 16 is a fairly simple card, based on a shared-memory
- * design using the i82586 Ethernet coprocessor. It bears no relationship,
- * as far as I know, to the similarly-named "EtherExpress Pro" range.
- *
- * Historically, Linux support for these cards has been very bad. However,
- * things seem to be getting better slowly.
- */
-
-/* If your card is confused about what sort of interface it has (eg it
- * persistently reports "10baseT" when none is fitted), running 'SOFTSET /BART'
- * or 'SOFTSET /LISA' from DOS seems to help.
- */
-
-/* Here's the scoop on memory mapping.
- *
- * There are three ways to access EtherExpress card memory: either using the
- * shared-memory mapping, or using PIO through the dataport, or using PIO
- * through the "shadow memory" ports.
- *
- * The shadow memory system works by having the card map some of its memory
- * as follows:
- *
- * (the low five bits of the SMPTR are ignored)
- *
- * base+0x4000..400f memory at SMPTR+0..15
- * base+0x8000..800f memory at SMPTR+16..31
- * base+0xc000..c007 dubious stuff (memory at SMPTR+16..23 apparently)
- * base+0xc008..c00f memory at 0x0008..0x000f
- *
- * This last set (the one at c008) is particularly handy because the SCB
- * lives at 0x0008. So that set of ports gives us easy random access to data
- * in the SCB without having to mess around setting up pointers and the like.
- * We always use this method to access the SCB (via the scb_xx() functions).
- *
- * Dataport access works by aiming the appropriate (read or write) pointer
- * at the first address you're interested in, and then reading or writing from
- * the dataport. The pointers auto-increment after each transfer. We use
- * this for data transfer.
- *
- * We don't use the shared-memory system because it allegedly doesn't work on
- * all cards, and because it's a bit more prone to go wrong (it's one more
- * thing to configure...).
- */
-
-/* Known bugs:
- *
- * - The card seems to want to give us two interrupts every time something
- * happens, where just one would be better.
- */
-
-/*
- *
- * Note by Zoltan Szilagyi 10-12-96:
- *
- * I've succeeded in eliminating the "CU wedged" messages, and hence the
- * lockups, which were only occurring with cards running in 8-bit mode ("force
- * 8-bit operation" in Intel's SoftSet utility). This version of the driver
- * sets the 82586 and the ASIC to 8-bit mode at startup; it also stops the
- * CU before submitting a packet for transmission, and then restarts it as soon
- * as the process of handing the packet is complete. This is definitely an
- * unnecessary slowdown if the card is running in 16-bit mode; therefore one
- * should detect 16-bit vs 8-bit mode from the EEPROM settings and act
- * accordingly. In 8-bit mode with this bugfix I'm getting about 150 K/s for
- * ftp's, which is significantly better than I get in DOS, so the overhead of
- * stopping and restarting the CU with each transmit is not prohibitive in
- * practice.
- *
- * Update by David Woodhouse 11/5/99:
- *
- * I've seen "CU wedged" messages in 16-bit mode, on the Alpha architecture.
- * I assume that this is because 16-bit accesses are actually handled as two
- * 8-bit accesses.
- */
-
-#ifdef __alpha__
-#define LOCKUP16 1
-#endif
-#ifndef LOCKUP16
-#define LOCKUP16 0
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/mca-legacy.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#ifndef NET_DEBUG
-#define NET_DEBUG 4
-#endif
-
-#include "eexpress.h"
-
-#define EEXP_IO_EXTENT 16
-
-/*
- * Private data declarations
- */
-
-struct net_local
-{
- unsigned long last_tx; /* jiffies when last transmit started */
- unsigned long init_time; /* jiffies when eexp_hw_init586 called */
- unsigned short rx_first; /* first rx buf, same as RX_BUF_START */
- unsigned short rx_last; /* last rx buf */
- unsigned short rx_ptr; /* first rx buf to look at */
- unsigned short tx_head; /* next free tx buf */
- unsigned short tx_reap; /* first in-use tx buf */
- unsigned short tx_tail; /* previous tx buf to tx_head */
- unsigned short tx_link; /* last known-executing tx buf */
- unsigned short last_tx_restart; /* set to tx_link when we
- restart the CU */
- unsigned char started;
- unsigned short rx_buf_start;
- unsigned short rx_buf_end;
- unsigned short num_tx_bufs;
- unsigned short num_rx_bufs;
- unsigned char width; /* 0 for 16bit, 1 for 8bit */
- unsigned char was_promisc;
- unsigned char old_mc_count;
- spinlock_t lock;
-};
-
-/* This is the code and data that is downloaded to the EtherExpress card's
- * memory at boot time.
- */
-
-static unsigned short start_code[] = {
-/* 0x0000 */
- 0x0001, /* ISCP: busy - cleared after reset */
- 0x0008,0x0000,0x0000, /* offset,address (lo,hi) of SCB */
-
- 0x0000,0x0000, /* SCB: status, commands */
- 0x0000,0x0000, /* links to first command block,
- first receive descriptor */
- 0x0000,0x0000, /* CRC error, alignment error counts */
- 0x0000,0x0000, /* out of resources, overrun error counts */
-
- 0x0000,0x0000, /* pad */
- 0x0000,0x0000,
-
-/* 0x20 -- start of 82586 CU program */
-#define CONF_LINK 0x20
- 0x0000,Cmd_Config,
- 0x0032, /* link to next command */
- 0x080c, /* 12 bytes follow : fifo threshold=8 */
- 0x2e40, /* don't rx bad frames
- * SRDY/ARDY => ext. sync. : preamble len=8
- * take addresses from data buffers
- * 6 bytes/address
- */
- 0x6000, /* default backoff method & priority
- * interframe spacing = 0x60 */
- 0xf200, /* slot time=0x200
- * max collision retry = 0xf */
-#define CONF_PROMISC 0x2e
- 0x0000, /* no HDLC : normal CRC : enable broadcast
- * disable promiscuous/multicast modes */
- 0x003c, /* minimum frame length = 60 octets) */
-
- 0x0000,Cmd_SetAddr,
- 0x003e, /* link to next command */
-#define CONF_HWADDR 0x38
- 0x0000,0x0000,0x0000, /* hardware address placed here */
-
- 0x0000,Cmd_MCast,
- 0x0076, /* link to next command */
-#define CONF_NR_MULTICAST 0x44
- 0x0000, /* number of bytes in multicast address(es) */
-#define CONF_MULTICAST 0x46
- 0x0000, 0x0000, 0x0000, /* some addresses */
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000,
-
-#define CONF_DIAG_RESULT 0x76
- 0x0000, Cmd_Diag,
- 0x007c, /* link to next command */
-
- 0x0000,Cmd_TDR|Cmd_INT,
- 0x0084,
-#define CONF_TDR_RESULT 0x82
- 0x0000,
-
- 0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */
- 0x0084 /* dummy link */
-};
-
-/* maps irq number to EtherExpress magic value */
-static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
-
-#ifdef CONFIG_MCA_LEGACY
-/* mapping of the first four bits of the second POS register */
-static unsigned short mca_iomap[] = {
- 0x270, 0x260, 0x250, 0x240, 0x230, 0x220, 0x210, 0x200,
- 0x370, 0x360, 0x350, 0x340, 0x330, 0x320, 0x310, 0x300
-};
-/* bits 5-7 of the second POS register */
-static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 };
-#endif
-
-/*
- * Prototypes for Linux interface
- */
-
-static int eexp_open(struct net_device *dev);
-static int eexp_close(struct net_device *dev);
-static void eexp_timeout(struct net_device *dev);
-static int eexp_xmit(struct sk_buff *buf, struct net_device *dev);
-
-static irqreturn_t eexp_irq(int irq, void *dev_addr);
-static void eexp_set_multicast(struct net_device *dev);
-
-/*
- * Prototypes for hardware access functions
- */
-
-static void eexp_hw_rx_pio(struct net_device *dev);
-static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
- unsigned short len);
-static int eexp_hw_probe(struct net_device *dev,unsigned short ioaddr);
-static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
- unsigned char location);
-
-static unsigned short eexp_hw_lasttxstat(struct net_device *dev);
-static void eexp_hw_txrestart(struct net_device *dev);
-
-static void eexp_hw_txinit (struct net_device *dev);
-static void eexp_hw_rxinit (struct net_device *dev);
-
-static void eexp_hw_init586 (struct net_device *dev);
-static void eexp_setup_filter (struct net_device *dev);
-
-static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"};
-enum eexp_iftype {AUI=0, BNC=1, TPE=2};
-
-#define STARTED_RU 2
-#define STARTED_CU 1
-
-/*
- * Primitive hardware access functions.
- */
-
-static inline unsigned short scb_status(struct net_device *dev)
-{
- return inw(dev->base_addr + 0xc008);
-}
-
-static inline unsigned short scb_rdcmd(struct net_device *dev)
-{
- return inw(dev->base_addr + 0xc00a);
-}
-
-static inline void scb_command(struct net_device *dev, unsigned short cmd)
-{
- outw(cmd, dev->base_addr + 0xc00a);
-}
-
-static inline void scb_wrcbl(struct net_device *dev, unsigned short val)
-{
- outw(val, dev->base_addr + 0xc00c);
-}
-
-static inline void scb_wrrfa(struct net_device *dev, unsigned short val)
-{
- outw(val, dev->base_addr + 0xc00e);
-}
-
-static inline void set_loopback(struct net_device *dev)
-{
- outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config);
-}
-
-static inline void clear_loopback(struct net_device *dev)
-{
- outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
-}
-
-static inline unsigned short int SHADOW(short int addr)
-{
- addr &= 0x1f;
- if (addr > 0xf) addr += 0x3ff0;
- return addr + 0x4000;
-}
-
-/*
- * Linux interface
- */
-
-/*
- * checks for presence of EtherExpress card
- */
-
-static int __init do_express_probe(struct net_device *dev)
-{
- unsigned short *port;
- static unsigned short ports[] = { 0x240,0x300,0x310,0x270,0x320,0x340,0 };
- unsigned short ioaddr = dev->base_addr;
- int dev_irq = dev->irq;
- int err;
-
- dev->if_port = 0xff; /* not set */
-
-#ifdef CONFIG_MCA_LEGACY
- if (MCA_bus) {
- int slot = 0;
-
- /*
- * Only find one card at a time. Subsequent calls
- * will find others, however, proper multicard MCA
- * probing and setup can't be done with the
- * old-style Space.c init routines. -- ASF
- */
- while (slot != MCA_NOTFOUND) {
- int pos0, pos1;
-
- slot = mca_find_unused_adapter(0x628B, slot);
- if (slot == MCA_NOTFOUND)
- break;
-
- pos0 = mca_read_stored_pos(slot, 2);
- pos1 = mca_read_stored_pos(slot, 3);
- ioaddr = mca_iomap[pos1&0xf];
-
- dev->irq = mca_irqmap[(pos1>>4)&0x7];
-
- /*
- * XXX: Transciever selection is done
- * differently on the MCA version.
- * How to get it to select something
- * other than external/AUI is currently
- * unknown. This code is just for looks. -- ASF
- */
- if ((pos0 & 0x7) == 0x1)
- dev->if_port = AUI;
- else if ((pos0 & 0x7) == 0x5) {
- if (pos1 & 0x80)
- dev->if_port = BNC;
- else
- dev->if_port = TPE;
- }
-
- mca_set_adapter_name(slot, "Intel EtherExpress 16 MCA");
- mca_set_adapter_procfn(slot, NULL, dev);
- mca_mark_as_used(slot);
-
- break;
- }
- }
-#endif
- if (ioaddr&0xfe00) {
- if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"))
- return -EBUSY;
- err = eexp_hw_probe(dev,ioaddr);
- release_region(ioaddr, EEXP_IO_EXTENT);
- return err;
- } else if (ioaddr)
- return -ENXIO;
-
- for (port=&ports[0] ; *port ; port++ )
- {
- unsigned short sum = 0;
- int i;
- if (!request_region(*port, EEXP_IO_EXTENT, "EtherExpress"))
- continue;
- for ( i=0 ; i<4 ; i++ )
- {
- unsigned short t;
- t = inb(*port + ID_PORT);
- sum |= (t>>4) << ((t & 0x03)<<2);
- }
- if (sum==0xbaba && !eexp_hw_probe(dev,*port)) {
- release_region(*port, EEXP_IO_EXTENT);
- return 0;
- }
- release_region(*port, EEXP_IO_EXTENT);
- dev->irq = dev_irq;
- }
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init express_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_express_probe(dev);
- if (!err)
- return dev;
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-/*
- * open and initialize the adapter, ready for use
- */
-
-static int eexp_open(struct net_device *dev)
-{
- int ret;
- unsigned short ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
-
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
-#endif
-
- if (!dev->irq || !irqrmap[dev->irq])
- return -ENXIO;
-
- ret = request_irq(dev->irq, &eexp_irq, 0, dev->name, dev);
- if (ret)
- return ret;
-
- if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr);
- goto err_out1;
- }
- if (!request_region(ioaddr+0x4000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr+0x4000);
- goto err_out2;
- }
- if (!request_region(ioaddr+0x8000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr+0x8000);
- goto err_out3;
- }
- if (!request_region(ioaddr+0xc000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
- printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
- , ioaddr+0xc000);
- goto err_out4;
- }
-
- if (lp->width) {
- printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
- outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config);
- }
-
- eexp_hw_init586(dev);
- netif_start_queue(dev);
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
-#endif
- return 0;
-
- err_out4:
- release_region(ioaddr+0x8000, EEXP_IO_EXTENT);
- err_out3:
- release_region(ioaddr+0x4000, EEXP_IO_EXTENT);
- err_out2:
- release_region(ioaddr, EEXP_IO_EXTENT);
- err_out1:
- free_irq(dev->irq, dev);
- return -EBUSY;
-}
-
-/*
- * close and disable the interface, leaving the 586 in reset.
- */
-
-static int eexp_close(struct net_device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
-
- int irq = dev->irq;
-
- netif_stop_queue(dev);
-
- outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
- lp->started = 0;
- scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
- outb(0,ioaddr+SIGNAL_CA);
- free_irq(irq,dev);
- outb(i586_RST,ioaddr+EEPROM_Ctrl);
- release_region(ioaddr, EEXP_IO_EXTENT);
- release_region(ioaddr+0x4000, 16);
- release_region(ioaddr+0x8000, 16);
- release_region(ioaddr+0xc000, 16);
-
- return 0;
-}
-
-/*
- * This gets called when a higher level thinks we are broken. Check that
- * nothing has become jammed in the CU.
- */
-
-static void unstick_cu(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
-
- if (lp->started)
- {
- if (time_after(jiffies, dev->trans_start + 50))
- {
- if (lp->tx_link==lp->last_tx_restart)
- {
- unsigned short boguscount=200,rsst;
- printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
- dev->name, scb_status(dev));
- eexp_hw_txinit(dev);
- lp->last_tx_restart = 0;
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- while (!SCB_complete(rsst=scb_status(dev)))
- {
- if (!--boguscount)
- {
- boguscount=200;
- printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
- dev->name,rsst);
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- }
- }
- netif_wake_queue(dev);
- }
- else
- {
- unsigned short status = scb_status(dev);
- if (SCB_CUdead(status))
- {
- unsigned short txstatus = eexp_hw_lasttxstat(dev);
- printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
- dev->name, status, txstatus);
- eexp_hw_txrestart(dev);
- }
- else
- {
- unsigned short txstatus = eexp_hw_lasttxstat(dev);
- if (netif_queue_stopped(dev) && !txstatus)
- {
- printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
- dev->name,status,txstatus);
- eexp_hw_init586(dev);
- netif_wake_queue(dev);
- }
- else
- {
- printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
- }
- }
- }
- }
- }
- else
- {
- if (time_after(jiffies, lp->init_time + 10))
- {
- unsigned short status = scb_status(dev);
- printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
- dev->name, status);
- eexp_hw_init586(dev);
- netif_wake_queue(dev);
- }
- }
-}
-
-static void eexp_timeout(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
-#ifdef CONFIG_SMP
- unsigned long flags;
-#endif
- int status;
-
- disable_irq(dev->irq);
-
- /*
- * Best would be to use synchronize_irq(); spin_lock() here
- * lets make it work first..
- */
-
-#ifdef CONFIG_SMP
- spin_lock_irqsave(&lp->lock, flags);
-#endif
-
- status = scb_status(dev);
- unstick_cu(dev);
- printk(KERN_INFO "%s: transmit timed out, %s?\n", dev->name,
- (SCB_complete(status)?"lost interrupt":
- "board on fire"));
- dev->stats.tx_errors++;
- lp->last_tx = jiffies;
- if (!SCB_complete(status)) {
- scb_command(dev, SCB_CUabort);
- outb(0,dev->base_addr+SIGNAL_CA);
- }
- netif_wake_queue(dev);
-#ifdef CONFIG_SMP
- spin_unlock_irqrestore(&lp->lock, flags);
-#endif
-}
-
-/*
- * Called to transmit a packet, or to allow us to right ourselves
- * if the kernel thinks we've died.
- */
-static int eexp_xmit(struct sk_buff *buf, struct net_device *dev)
-{
- short length = buf->len;
-#ifdef CONFIG_SMP
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
-#endif
-
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
-#endif
-
- if (buf->len < ETH_ZLEN) {
- if (skb_padto(buf, ETH_ZLEN))
- return 0;
- length = ETH_ZLEN;
- }
-
- disable_irq(dev->irq);
-
- /*
- * Best would be to use synchronize_irq(); spin_lock() here
- * lets make it work first..
- */
-
-#ifdef CONFIG_SMP
- spin_lock_irqsave(&lp->lock, flags);
-#endif
-
- {
- unsigned short *data = (unsigned short *)buf->data;
-
- dev->stats.tx_bytes += length;
-
- eexp_hw_tx_pio(dev,data,length);
- }
- dev_kfree_skb(buf);
-#ifdef CONFIG_SMP
- spin_unlock_irqrestore(&lp->lock, flags);
-#endif
- enable_irq(dev->irq);
- return 0;
-}
-
-/*
- * Handle an EtherExpress interrupt
- * If we've finished initializing, start the RU and CU up.
- * If we've already started, reap tx buffers, handle any received packets,
- * check to make sure we've not become wedged.
- */
-
-static unsigned short eexp_start_irq(struct net_device *dev,
- unsigned short status)
-{
- unsigned short ack_cmd = SCB_ack(status);
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
- if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) {
- short diag_status, tdr_status;
- while (SCB_CUstat(status)==2)
- status = scb_status(dev);
-#if NET_DEBUG > 4
- printk("%s: CU went non-active (status %04x)\n",
- dev->name, status);
-#endif
-
- outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR);
- diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT));
- if (diag_status & 1<<11) {
- printk(KERN_WARNING "%s: 82586 failed self-test\n",
- dev->name);
- } else if (!(diag_status & 1<<13)) {
- printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name);
- }
-
- outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR);
- tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT));
- if (tdr_status & (TDR_SHORT|TDR_OPEN)) {
- printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
- }
- else if (tdr_status & TDR_XCVRPROBLEM) {
- printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name);
- }
- else if (tdr_status & TDR_LINKOK) {
-#if NET_DEBUG > 4
- printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name);
-#endif
- } else {
- printk("%s: TDR is ga-ga (status %04x)\n", dev->name,
- tdr_status);
- }
-
- lp->started |= STARTED_CU;
- scb_wrcbl(dev, lp->tx_link);
- /* if the RU isn't running, start it now */
- if (!(lp->started & STARTED_RU)) {
- ack_cmd |= SCB_RUstart;
- scb_wrrfa(dev, lp->rx_buf_start);
- lp->rx_ptr = lp->rx_buf_start;
- lp->started |= STARTED_RU;
- }
- ack_cmd |= SCB_CUstart | 0x2000;
- }
-
- if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4)
- lp->started|=STARTED_RU;
-
- return ack_cmd;
-}
-
-static void eexp_cmd_clear(struct net_device *dev)
-{
- unsigned long int oldtime = jiffies;
- while (scb_rdcmd(dev) && (time_before(jiffies, oldtime + 10)));
- if (scb_rdcmd(dev)) {
- printk("%s: command didn't clear\n", dev->name);
- }
-}
-
-static irqreturn_t eexp_irq(int dummy, void *dev_info)
-{
- struct net_device *dev = dev_info;
- struct net_local *lp;
- unsigned short ioaddr,status,ack_cmd;
- unsigned short old_read_ptr, old_write_ptr;
-
- lp = netdev_priv(dev);
- ioaddr = dev->base_addr;
-
- spin_lock(&lp->lock);
-
- old_read_ptr = inw(ioaddr+READ_PTR);
- old_write_ptr = inw(ioaddr+WRITE_PTR);
-
- outb(SIRQ_dis|irqrmap[dev->irq], ioaddr+SET_IRQ);
-
- status = scb_status(dev);
-
-#if NET_DEBUG > 4
- printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status);
-#endif
-
- if (lp->started == (STARTED_CU | STARTED_RU)) {
-
- do {
- eexp_cmd_clear(dev);
-
- ack_cmd = SCB_ack(status);
- scb_command(dev, ack_cmd);
- outb(0,ioaddr+SIGNAL_CA);
-
- eexp_cmd_clear(dev);
-
- if (SCB_complete(status)) {
- if (!eexp_hw_lasttxstat(dev)) {
- printk("%s: tx interrupt but no status\n", dev->name);
- }
- }
-
- if (SCB_rxdframe(status))
- eexp_hw_rx_pio(dev);
-
- status = scb_status(dev);
- } while (status & 0xc000);
-
- if (SCB_RUdead(status))
- {
- printk(KERN_WARNING "%s: RU stopped: status %04x\n",
- dev->name,status);
-#if 0
- printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd);
- outw(lp->cur_rfd, ioaddr+READ_PTR);
- printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT));
- outw(lp->cur_rfd+6, ioaddr+READ_PTR);
- printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT));
- outw(rbd, ioaddr+READ_PTR);
- printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT));
- outw(rbd+8, ioaddr+READ_PTR);
- printk("[%04x]\n", inw(ioaddr+DATAPORT));
-#endif
- dev->stats.rx_errors++;
-#if 1
- eexp_hw_rxinit(dev);
-#else
- lp->cur_rfd = lp->first_rfd;
-#endif
- scb_wrrfa(dev, lp->rx_buf_start);
- scb_command(dev, SCB_RUstart);
- outb(0,ioaddr+SIGNAL_CA);
- }
- } else {
- if (status & 0x8000)
- ack_cmd = eexp_start_irq(dev, status);
- else
- ack_cmd = SCB_ack(status);
- scb_command(dev, ack_cmd);
- outb(0,ioaddr+SIGNAL_CA);
- }
-
- eexp_cmd_clear(dev);
-
- outb(SIRQ_en|irqrmap[dev->irq], ioaddr+SET_IRQ);
-
-#if NET_DEBUG > 6
- printk("%s: leaving eexp_irq()\n", dev->name);
-#endif
- outw(old_read_ptr, ioaddr+READ_PTR);
- outw(old_write_ptr, ioaddr+WRITE_PTR);
-
- spin_unlock(&lp->lock);
- return IRQ_HANDLED;
-}
-
-/*
- * Hardware access functions
- */
-
-/*
- * Set the cable type to use.
- */
-
-static void eexp_hw_set_interface(struct net_device *dev)
-{
- unsigned char oldval = inb(dev->base_addr + 0x300e);
- oldval &= ~0x82;
- switch (dev->if_port) {
- case TPE:
- oldval |= 0x2;
- case BNC:
- oldval |= 0x80;
- break;
- }
- outb(oldval, dev->base_addr+0x300e);
- mdelay(20);
-}
-
-/*
- * Check all the receive buffers, and hand any received packets
- * to the upper levels. Basic sanity check on each frame
- * descriptor, though we don't bother trying to fix broken ones.
- */
-
-static void eexp_hw_rx_pio(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short rx_block = lp->rx_ptr;
- unsigned short boguscount = lp->num_rx_bufs;
- unsigned short ioaddr = dev->base_addr;
- unsigned short status;
-
-#if NET_DEBUG > 6
- printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
-#endif
-
- do {
- unsigned short rfd_cmd, rx_next, pbuf, pkt_len;
-
- outw(rx_block, ioaddr + READ_PTR);
- status = inw(ioaddr + DATAPORT);
-
- if (FD_Done(status))
- {
- rfd_cmd = inw(ioaddr + DATAPORT);
- rx_next = inw(ioaddr + DATAPORT);
- pbuf = inw(ioaddr + DATAPORT);
-
- outw(pbuf, ioaddr + READ_PTR);
- pkt_len = inw(ioaddr + DATAPORT);
-
- if (rfd_cmd!=0x0000)
- {
- printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n",
- dev->name, rfd_cmd);
- continue;
- }
- else if (pbuf!=rx_block+0x16)
- {
- printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n",
- dev->name, rx_block+0x16, pbuf);
- continue;
- }
- else if ((pkt_len & 0xc000)!=0xc000)
- {
- printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n",
- dev->name, pkt_len & 0xc000);
- continue;
- }
- else if (!FD_OK(status))
- {
- dev->stats.rx_errors++;
- if (FD_CRC(status))
- dev->stats.rx_crc_errors++;
- if (FD_Align(status))
- dev->stats.rx_frame_errors++;
- if (FD_Resrc(status))
- dev->stats.rx_fifo_errors++;
- if (FD_DMA(status))
- dev->stats.rx_over_errors++;
- if (FD_Short(status))
- dev->stats.rx_length_errors++;
- }
- else
- {
- struct sk_buff *skb;
- pkt_len &= 0x3fff;
- skb = dev_alloc_skb(pkt_len+16);
- if (skb == NULL)
- {
- printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
- dev->stats.rx_dropped++;
- break;
- }
- skb_reserve(skb, 2);
- outw(pbuf+10, ioaddr+READ_PTR);
- insw(ioaddr+DATAPORT, skb_put(skb,pkt_len),(pkt_len+1)>>1);
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
- }
- outw(rx_block, ioaddr+WRITE_PTR);
- outw(0, ioaddr+DATAPORT);
- outw(0, ioaddr+DATAPORT);
- rx_block = rx_next;
- }
- } while (FD_Done(status) && boguscount--);
- lp->rx_ptr = rx_block;
-}
-
-/*
- * Hand a packet to the card for transmission
- * If we get here, we MUST have already checked
- * to make sure there is room in the transmit
- * buffer region.
- */
-
-static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
- unsigned short len)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
-
- if (LOCKUP16 || lp->width) {
- /* Stop the CU so that there is no chance that it
- jumps off to a bogus address while we are writing the
- pointer to the next transmit packet in 8-bit mode --
- this eliminates the "CU wedged" errors in 8-bit mode.
- (Zoltan Szilagyi 10-12-96) */
- scb_command(dev, SCB_CUsuspend);
- outw(0xFFFF, ioaddr+SIGNAL_CA);
- }
-
- outw(lp->tx_head, ioaddr + WRITE_PTR);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
- outw(lp->tx_head+0x08, ioaddr + DATAPORT);
- outw(lp->tx_head+0x0e, ioaddr + DATAPORT);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(0x0000, ioaddr + DATAPORT);
- outw(lp->tx_head+0x08, ioaddr + DATAPORT);
-
- outw(0x8000|len, ioaddr + DATAPORT);
- outw(-1, ioaddr + DATAPORT);
- outw(lp->tx_head+0x16, ioaddr + DATAPORT);
- outw(0, ioaddr + DATAPORT);
-
- outsw(ioaddr + DATAPORT, buf, (len+1)>>1);
-
- outw(lp->tx_tail+0xc, ioaddr + WRITE_PTR);
- outw(lp->tx_head, ioaddr + DATAPORT);
-
- dev->trans_start = jiffies;
- lp->tx_tail = lp->tx_head;
- if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
- lp->tx_head = TX_BUF_START;
- else
- lp->tx_head += TX_BUF_SIZE;
- if (lp->tx_head != lp->tx_reap)
- netif_wake_queue(dev);
-
- if (LOCKUP16 || lp->width) {
- /* Restart the CU so that the packet can actually
- be transmitted. (Zoltan Szilagyi 10-12-96) */
- scb_command(dev, SCB_CUresume);
- outw(0xFFFF, ioaddr+SIGNAL_CA);
- }
-
- dev->stats.tx_packets++;
- lp->last_tx = jiffies;
-}
-
-/*
- * Sanity check the suspected EtherExpress card
- * Read hardware address, reset card, size memory and initialize buffer
- * memory pointers. These are held in dev->priv, in case someone has more
- * than one card in a machine.
- */
-
-static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
-{
- unsigned short hw_addr[3];
- unsigned char buswidth;
- unsigned int memory_size;
- int i;
- unsigned short xsum = 0;
- struct net_local *lp = netdev_priv(dev);
-
- printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
-
- outb(ASIC_RST, ioaddr+EEPROM_Ctrl);
- outb(0, ioaddr+EEPROM_Ctrl);
- udelay(500);
- outb(i586_RST, ioaddr+EEPROM_Ctrl);
-
- hw_addr[0] = eexp_hw_readeeprom(ioaddr,2);
- hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
- hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
-
- /* Standard Address or Compaq LTE Address */
- if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
- (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00))))
- {
- printk(" rejected: invalid address %04x%04x%04x\n",
- hw_addr[2],hw_addr[1],hw_addr[0]);
- return -ENODEV;
- }
-
- /* Calculate the EEPROM checksum. Carry on anyway if it's bad,
- * though.
- */
- for (i = 0; i < 64; i++)
- xsum += eexp_hw_readeeprom(ioaddr, i);
- if (xsum != 0xbaba)
- printk(" (bad EEPROM xsum 0x%02x)", xsum);
-
- dev->base_addr = ioaddr;
- for ( i=0 ; i<6 ; i++ )
- dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
-
- {
- static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
- unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
-
- /* Use the IRQ from EEPROM if none was given */
- if (!dev->irq)
- dev->irq = irqmap[setupval>>13];
-
- if (dev->if_port == 0xff) {
- dev->if_port = !(setupval & 0x1000) ? AUI :
- eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
- }
-
- buswidth = !((setupval & 0x400) >> 10);
- }
-
- memset(lp, 0, sizeof(struct net_local));
- spin_lock_init(&lp->lock);
-
- printk("(IRQ %d, %s connector, %d-bit bus", dev->irq,
- eexp_ifmap[dev->if_port], buswidth?8:16);
-
- if (!request_region(dev->base_addr + 0x300e, 1, "EtherExpress"))
- return -EBUSY;
-
- eexp_hw_set_interface(dev);
-
- release_region(dev->base_addr + 0x300e, 1);
-
- /* Find out how much RAM we have on the card */
- outw(0, dev->base_addr + WRITE_PTR);
- for (i = 0; i < 32768; i++)
- outw(0, dev->base_addr + DATAPORT);
-
- for (memory_size = 0; memory_size < 64; memory_size++)
- {
- outw(memory_size<<10, dev->base_addr + READ_PTR);
- if (inw(dev->base_addr+DATAPORT))
- break;
- outw(memory_size<<10, dev->base_addr + WRITE_PTR);
- outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
- outw(memory_size<<10, dev->base_addr + READ_PTR);
- if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000))
- break;
- }
-
- /* Sort out the number of buffers. We may have 16, 32, 48 or 64k
- * of RAM to play with.
- */
- lp->num_tx_bufs = 4;
- lp->rx_buf_end = 0x3ff6;
- switch (memory_size)
- {
- case 64:
- lp->rx_buf_end += 0x4000;
- case 48:
- lp->num_tx_bufs += 4;
- lp->rx_buf_end += 0x4000;
- case 32:
- lp->rx_buf_end += 0x4000;
- case 16:
- printk(", %dk RAM)\n", memory_size);
- break;
- default:
- printk(") bad memory size (%dk).\n", memory_size);
- return -ENODEV;
- break;
- }
-
- lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
- lp->width = buswidth;
-
- dev->open = eexp_open;
- dev->stop = eexp_close;
- dev->hard_start_xmit = eexp_xmit;
- dev->set_multicast_list = &eexp_set_multicast;
- dev->tx_timeout = eexp_timeout;
- dev->watchdog_timeo = 2*HZ;
-
- return register_netdev(dev);
-}
-
-/*
- * Read a word from the EtherExpress on-board serial EEPROM.
- * The EEPROM contains 64 words of 16 bits.
- */
-static unsigned short __init eexp_hw_readeeprom(unsigned short ioaddr,
- unsigned char location)
-{
- unsigned short cmd = 0x180|(location&0x7f);
- unsigned short rval = 0,wval = EC_CS|i586_RST;
- int i;
-
- outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
- for (i=0x100 ; i ; i>>=1 )
- {
- if (cmd&i)
- wval |= EC_Wr;
- else
- wval &= ~EC_Wr;
-
- outb(wval,ioaddr+EEPROM_Ctrl);
- outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- outb(wval,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- }
- wval &= ~EC_Wr;
- outb(wval,ioaddr+EEPROM_Ctrl);
- for (i=0x8000 ; i ; i>>=1 )
- {
- outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
- rval |= i;
- outb(wval,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- }
- wval &= ~EC_CS;
- outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- outb(wval,ioaddr+EEPROM_Ctrl);
- eeprom_delay();
- return rval;
-}
-
-/*
- * Reap tx buffers and return last transmit status.
- * if ==0 then either:
- * a) we're not transmitting anything, so why are we here?
- * b) we've died.
- * otherwise, Stat_Busy(return) means we've still got some packets
- * to transmit, Stat_Done(return) means our buffers should be empty
- * again
- */
-
-static unsigned short eexp_hw_lasttxstat(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short tx_block = lp->tx_reap;
- unsigned short status;
-
- if (!netif_queue_stopped(dev) && lp->tx_head==lp->tx_reap)
- return 0x0000;
-
- do
- {
- outw(tx_block & ~31, dev->base_addr + SM_PTR);
- status = inw(dev->base_addr + SHADOW(tx_block));
- if (!Stat_Done(status))
- {
- lp->tx_link = tx_block;
- return status;
- }
- else
- {
- lp->last_tx_restart = 0;
- dev->stats.collisions += Stat_NoColl(status);
- if (!Stat_OK(status))
- {
- char *whatsup = NULL;
- dev->stats.tx_errors++;
- if (Stat_Abort(status))
- dev->stats.tx_aborted_errors++;
- if (Stat_TNoCar(status)) {
- whatsup = "aborted, no carrier";
- dev->stats.tx_carrier_errors++;
- }
- if (Stat_TNoCTS(status)) {
- whatsup = "aborted, lost CTS";
- dev->stats.tx_carrier_errors++;
- }
- if (Stat_TNoDMA(status)) {
- whatsup = "FIFO underran";
- dev->stats.tx_fifo_errors++;
- }
- if (Stat_TXColl(status)) {
- whatsup = "aborted, too many collisions";
- dev->stats.tx_aborted_errors++;
- }
- if (whatsup)
- printk(KERN_INFO "%s: transmit %s\n",
- dev->name, whatsup);
- }
- else
- dev->stats.tx_packets++;
- }
- if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
- lp->tx_reap = tx_block = TX_BUF_START;
- else
- lp->tx_reap = tx_block += TX_BUF_SIZE;
- netif_wake_queue(dev);
- }
- while (lp->tx_reap != lp->tx_head);
-
- lp->tx_link = lp->tx_tail + 0x08;
-
- return status;
-}
-
-/*
- * This should never happen. It is called when some higher routine detects
- * that the CU has stopped, to try to restart it from the last packet we knew
- * we were working on, or the idle loop if we had finished for the time.
- */
-
-static void eexp_hw_txrestart(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
-
- lp->last_tx_restart = lp->tx_link;
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
-
- {
- unsigned short boguscount=50,failcount=5;
- while (!scb_status(dev))
- {
- if (!--boguscount)
- {
- if (--failcount)
- {
- printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n", dev->name, scb_status(dev), scb_rdcmd(dev));
- scb_wrcbl(dev, lp->tx_link);
- scb_command(dev, SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- boguscount = 100;
- }
- else
- {
- printk(KERN_WARNING "%s: Failed to restart CU, resetting board...\n",dev->name);
- eexp_hw_init586(dev);
- netif_wake_queue(dev);
- return;
- }
- }
- }
- }
-}
-
-/*
- * Writes down the list of transmit buffers into card memory. Each
- * entry consists of an 82586 transmit command, followed by a jump
- * pointing to itself. When we want to transmit a packet, we write
- * the data into the appropriate transmit buffer and then modify the
- * preceding jump to point at the new transmit command. This means that
- * the 586 command unit is continuously active.
- */
-
-static void eexp_hw_txinit(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short tx_block = TX_BUF_START;
- unsigned short curtbuf;
- unsigned short ioaddr = dev->base_addr;
-
- for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ )
- {
- outw(tx_block, ioaddr + WRITE_PTR);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
- outw(tx_block+0x08, ioaddr + DATAPORT);
- outw(tx_block+0x0e, ioaddr + DATAPORT);
-
- outw(0x0000, ioaddr + DATAPORT);
- outw(0x0000, ioaddr + DATAPORT);
- outw(tx_block+0x08, ioaddr + DATAPORT);
-
- outw(0x8000, ioaddr + DATAPORT);
- outw(-1, ioaddr + DATAPORT);
- outw(tx_block+0x16, ioaddr + DATAPORT);
- outw(0x0000, ioaddr + DATAPORT);
-
- tx_block += TX_BUF_SIZE;
- }
- lp->tx_head = TX_BUF_START;
- lp->tx_reap = TX_BUF_START;
- lp->tx_tail = tx_block - TX_BUF_SIZE;
- lp->tx_link = lp->tx_tail + 0x08;
- lp->rx_buf_start = tx_block;
-
-}
-
-/*
- * Write the circular list of receive buffer descriptors to card memory.
- * The end of the list isn't marked, which means that the 82586 receive
- * unit will loop until buffers become available (this avoids it giving us
- * "out of resources" messages).
- */
-
-static void eexp_hw_rxinit(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short rx_block = lp->rx_buf_start;
- unsigned short ioaddr = dev->base_addr;
-
- lp->num_rx_bufs = 0;
- lp->rx_first = lp->rx_ptr = rx_block;
- do
- {
- lp->num_rx_bufs++;
-
- outw(rx_block, ioaddr + WRITE_PTR);
-
- outw(0, ioaddr + DATAPORT); outw(0, ioaddr+DATAPORT);
- outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT);
- outw(0xffff, ioaddr+DATAPORT);
-
- outw(0x0000, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
- outw(0xdead, ioaddr+DATAPORT);
-
- outw(0x0000, ioaddr+DATAPORT);
- outw(rx_block + RX_BUF_SIZE + 0x16, ioaddr+DATAPORT);
- outw(rx_block + 0x20, ioaddr+DATAPORT);
- outw(0, ioaddr+DATAPORT);
- outw(RX_BUF_SIZE-0x20, ioaddr+DATAPORT);
-
- lp->rx_last = rx_block;
- rx_block += RX_BUF_SIZE;
- } while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE);
-
-
- /* Make first Rx frame descriptor point to first Rx buffer
- descriptor */
- outw(lp->rx_first + 6, ioaddr+WRITE_PTR);
- outw(lp->rx_first + 0x16, ioaddr+DATAPORT);
-
- /* Close Rx frame descriptor ring */
- outw(lp->rx_last + 4, ioaddr+WRITE_PTR);
- outw(lp->rx_first, ioaddr+DATAPORT);
-
- /* Close Rx buffer descriptor ring */
- outw(lp->rx_last + 0x16 + 2, ioaddr+WRITE_PTR);
- outw(lp->rx_first + 0x16, ioaddr+DATAPORT);
-
-}
-
-/*
- * Un-reset the 586, and start the configuration sequence. We don't wait for
- * this to finish, but allow the interrupt handler to start the CU and RU for
- * us. We can't start the receive/transmission system up before we know that
- * the hardware is configured correctly.
- */
-
-static void eexp_hw_init586(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned short ioaddr = dev->base_addr;
- int i;
-
-#if NET_DEBUG > 6
- printk("%s: eexp_hw_init586()\n", dev->name);
-#endif
-
- lp->started = 0;
-
- set_loopback(dev);
-
- outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
-
- /* Download the startup code */
- outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR);
- outw(lp->width?0x0001:0x0000, ioaddr + 0x8006);
- outw(0x0000, ioaddr + 0x8008);
- outw(0x0000, ioaddr + 0x800a);
- outw(0x0000, ioaddr + 0x800c);
- outw(0x0000, ioaddr + 0x800e);
-
- for (i = 0; i < (sizeof(start_code)); i+=32) {
- int j;
- outw(i, ioaddr + SM_PTR);
- for (j = 0; j < 16; j+=2)
- outw(start_code[(i+j)/2],
- ioaddr+0x4000+j);
- for (j = 0; j < 16; j+=2)
- outw(start_code[(i+j+16)/2],
- ioaddr+0x8000+j);
- }
-
- /* Do we want promiscuous mode or multicast? */
- outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
- i = inw(ioaddr+SHADOW(CONF_PROMISC));
- outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1),
- ioaddr+SHADOW(CONF_PROMISC));
- lp->was_promisc = dev->flags & IFF_PROMISC;
-#if 0
- eexp_setup_filter(dev);
-#endif
-
- /* Write our hardware address */
- outw(CONF_HWADDR & ~31, ioaddr+SM_PTR);
- outw(((unsigned short *)dev->dev_addr)[0], ioaddr+SHADOW(CONF_HWADDR));
- outw(((unsigned short *)dev->dev_addr)[1],
- ioaddr+SHADOW(CONF_HWADDR+2));
- outw(((unsigned short *)dev->dev_addr)[2],
- ioaddr+SHADOW(CONF_HWADDR+4));
-
- eexp_hw_txinit(dev);
- eexp_hw_rxinit(dev);
-
- outb(0,ioaddr+EEPROM_Ctrl);
- mdelay(5);
-
- scb_command(dev, 0xf000);
- outb(0,ioaddr+SIGNAL_CA);
-
- outw(0, ioaddr+SM_PTR);
-
- {
- unsigned short rboguscount=50,rfailcount=5;
- while (inw(ioaddr+0x4000))
- {
- if (!--rboguscount)
- {
- printk(KERN_WARNING "%s: i82586 reset timed out, kicking...\n",
- dev->name);
- scb_command(dev, 0);
- outb(0,ioaddr+SIGNAL_CA);
- rboguscount = 100;
- if (!--rfailcount)
- {
- printk(KERN_WARNING "%s: i82586 not responding, giving up.\n",
- dev->name);
- return;
- }
- }
- }
- }
-
- scb_wrcbl(dev, CONF_LINK);
- scb_command(dev, 0xf000|SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
-
- {
- unsigned short iboguscount=50,ifailcount=5;
- while (!scb_status(dev))
- {
- if (!--iboguscount)
- {
- if (--ifailcount)
- {
- printk(KERN_WARNING "%s: i82586 initialization timed out, status %04x, cmd %04x\n",
- dev->name, scb_status(dev), scb_rdcmd(dev));
- scb_wrcbl(dev, CONF_LINK);
- scb_command(dev, 0xf000|SCB_CUstart);
- outb(0,ioaddr+SIGNAL_CA);
- iboguscount = 100;
- }
- else
- {
- printk(KERN_WARNING "%s: Failed to initialize i82586, giving up.\n",dev->name);
- return;
- }
- }
- }
- }
-
- clear_loopback(dev);
- outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
-
- lp->init_time = jiffies;
-#if NET_DEBUG > 6
- printk("%s: leaving eexp_hw_init586()\n", dev->name);
-#endif
- return;
-}
-
-static void eexp_setup_filter(struct net_device *dev)
-{
- struct dev_mc_list *dmi;
- unsigned short ioaddr = dev->base_addr;
- int count = dev->mc_count;
- int i;
- if (count > 8) {
- printk(KERN_INFO "%s: too many multicast addresses (%d)\n",
- dev->name, count);
- count = 8;
- }
-
- outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
- outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST));
- for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) {
- unsigned short *data;
- if (!dmi) {
- printk(KERN_INFO "%s: too few multicast addresses\n", dev->name);
- break;
- }
- if (dmi->dmi_addrlen != ETH_ALEN) {
- printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
- continue;
- }
- data = (unsigned short *)dmi->dmi_addr;
- outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
- outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
- outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
- outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2));
- outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR);
- outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4));
- }
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- */
-static void
-eexp_set_multicast(struct net_device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
- struct net_local *lp = netdev_priv(dev);
- int kick = 0, i;
- if ((dev->flags & IFF_PROMISC) != lp->was_promisc) {
- outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
- i = inw(ioaddr+SHADOW(CONF_PROMISC));
- outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1),
- ioaddr+SHADOW(CONF_PROMISC));
- lp->was_promisc = dev->flags & IFF_PROMISC;
- kick = 1;
- }
- if (!(dev->flags & IFF_PROMISC)) {
- eexp_setup_filter(dev);
- if (lp->old_mc_count != dev->mc_count) {
- kick = 1;
- lp->old_mc_count = dev->mc_count;
- }
- }
- if (kick) {
- unsigned long oj;
- scb_command(dev, SCB_CUsuspend);
- outb(0, ioaddr+SIGNAL_CA);
- outb(0, ioaddr+SIGNAL_CA);
-#if 0
- printk("%s: waiting for CU to go suspended\n", dev->name);
-#endif
- oj = jiffies;
- while ((SCB_CUstat(scb_status(dev)) == 2) &&
- (time_before(jiffies, oj + 2000)));
- if (SCB_CUstat(scb_status(dev)) == 2)
- printk("%s: warning, CU didn't stop\n", dev->name);
- lp->started &= ~(STARTED_CU);
- scb_wrcbl(dev, CONF_LINK);
- scb_command(dev, SCB_CUstart);
- outb(0, ioaddr+SIGNAL_CA);
- }
-}
-
-
-/*
- * MODULE stuff
- */
-
-#ifdef MODULE
-
-#define EEXP_MAX_CARDS 4 /* max number of cards to support */
-
-static struct net_device *dev_eexp[EEXP_MAX_CARDS];
-static int irq[EEXP_MAX_CARDS];
-static int io[EEXP_MAX_CARDS];
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherExpress 16 I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherExpress 16 IRQ number(s)");
-MODULE_LICENSE("GPL");
-
-
-/* Ideally the user would give us io=, irq= for every card. If any parameters
- * are specified, we verify and then use them. If no parameters are given, we
- * autoprobe for one card only.
- */
-int __init init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
- dev = alloc_etherdev(sizeof(struct net_local));
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- if (io[this_dev] == 0) {
- if (this_dev)
- break;
- printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
- }
- if (do_express_probe(dev) == 0) {
- dev_eexp[this_dev] = dev;
- found++;
- continue;
- }
- printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
- free_netdev(dev);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
- struct net_device *dev = dev_eexp[this_dev];
- if (dev) {
- unregister_netdev(dev);
- free_netdev(dev);
- }
- }
-}
-#endif
-
-/*
- * Local Variables:
- * c-file-style: "linux"
- * tab-width: 8
- * End:
- */
diff --git a/drivers/net/eexpress.h b/drivers/net/eexpress.h
deleted file mode 100644
index 707df3fcfe4..00000000000
--- a/drivers/net/eexpress.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * eexpress.h: Intel EtherExpress16 defines
- */
-
-/*
- * EtherExpress card register addresses
- * as offsets from the base IO region (dev->base_addr)
- */
-
-#define DATAPORT 0x0000
-#define WRITE_PTR 0x0002
-#define READ_PTR 0x0004
-#define SIGNAL_CA 0x0006
-#define SET_IRQ 0x0007
-#define SM_PTR 0x0008
-#define MEM_Dec 0x000a
-#define MEM_Ctrl 0x000b
-#define MEM_Page_Ctrl 0x000c
-#define Config 0x000d
-#define EEPROM_Ctrl 0x000e
-#define ID_PORT 0x000f
-#define MEM_ECtrl 0x000f
-
-/*
- * card register defines
- */
-
-/* SET_IRQ */
-#define SIRQ_en 0x08
-#define SIRQ_dis 0x00
-
-/* EEPROM_Ctrl */
-#define EC_Clk 0x01
-#define EC_CS 0x02
-#define EC_Wr 0x04
-#define EC_Rd 0x08
-#define ASIC_RST 0x40
-#define i586_RST 0x80
-
-#define eeprom_delay() { udelay(40); }
-
-/*
- * i82586 Memory Configuration
- */
-
-/* (System Configuration Pointer) System start up block, read after 586_RST */
-#define SCP_START 0xfff6
-
-/* Intermediate System Configuration Pointer */
-#define ISCP_START 0x0000
-
-/* System Command Block */
-#define SCB_START 0x0008
-
-/* Start of buffer region. Everything before this is used for control
- * structures and the CU configuration program. The memory layout is
- * determined in eexp_hw_probe(), once we know how much memory is
- * available on the card.
- */
-
-#define TX_BUF_START 0x0100
-
-#define TX_BUF_SIZE ((24+ETH_FRAME_LEN+31)&~0x1f)
-#define RX_BUF_SIZE ((32+ETH_FRAME_LEN+31)&~0x1f)
-
-/*
- * SCB defines
- */
-
-/* these functions take the SCB status word and test the relevant status bit */
-#define SCB_complete(s) ((s&0x8000)!=0)
-#define SCB_rxdframe(s) ((s&0x4000)!=0)
-#define SCB_CUdead(s) ((s&0x2000)!=0)
-#define SCB_RUdead(s) ((s&0x1000)!=0)
-#define SCB_ack(s) (s & 0xf000)
-
-/* Command unit status: 0=idle, 1=suspended, 2=active */
-#define SCB_CUstat(s) ((s&0x0300)>>8)
-
-/* Receive unit status: 0=idle, 1=suspended, 2=out of resources, 4=ready */
-#define SCB_RUstat(s) ((s&0x0070)>>4)
-
-/* SCB commands */
-#define SCB_CUnop 0x0000
-#define SCB_CUstart 0x0100
-#define SCB_CUresume 0x0200
-#define SCB_CUsuspend 0x0300
-#define SCB_CUabort 0x0400
-#define SCB_resetchip 0x0080
-
-#define SCB_RUnop 0x0000
-#define SCB_RUstart 0x0010
-#define SCB_RUresume 0x0020
-#define SCB_RUsuspend 0x0030
-#define SCB_RUabort 0x0040
-
-/*
- * Command block defines
- */
-
-#define Stat_Done(s) ((s&0x8000)!=0)
-#define Stat_Busy(s) ((s&0x4000)!=0)
-#define Stat_OK(s) ((s&0x2000)!=0)
-#define Stat_Abort(s) ((s&0x1000)!=0)
-#define Stat_STFail ((s&0x0800)!=0)
-#define Stat_TNoCar(s) ((s&0x0400)!=0)
-#define Stat_TNoCTS(s) ((s&0x0200)!=0)
-#define Stat_TNoDMA(s) ((s&0x0100)!=0)
-#define Stat_TDefer(s) ((s&0x0080)!=0)
-#define Stat_TColl(s) ((s&0x0040)!=0)
-#define Stat_TXColl(s) ((s&0x0020)!=0)
-#define Stat_NoColl(s) (s&0x000f)
-
-/* Cmd_END will end AFTER the command if this is the first
- * command block after an SCB_CUstart, but BEFORE the command
- * for all subsequent commands. Best strategy is to place
- * Cmd_INT on the last command in the sequence, followed by a
- * dummy Cmd_Nop with Cmd_END after this.
- */
-
-#define Cmd_END 0x8000
-#define Cmd_SUS 0x4000
-#define Cmd_INT 0x2000
-
-#define Cmd_Nop 0x0000
-#define Cmd_SetAddr 0x0001
-#define Cmd_Config 0x0002
-#define Cmd_MCast 0x0003
-#define Cmd_Xmit 0x0004
-#define Cmd_TDR 0x0005
-#define Cmd_Dump 0x0006
-#define Cmd_Diag 0x0007
-
-
-/*
- * Frame Descriptor (Receive block) defines
- */
-
-#define FD_Done(s) ((s&0x8000)!=0)
-#define FD_Busy(s) ((s&0x4000)!=0)
-#define FD_OK(s) ((s&0x2000)!=0)
-
-#define FD_CRC(s) ((s&0x0800)!=0)
-#define FD_Align(s) ((s&0x0400)!=0)
-#define FD_Resrc(s) ((s&0x0200)!=0)
-#define FD_DMA(s) ((s&0x0100)!=0)
-#define FD_Short(s) ((s&0x0080)!=0)
-#define FD_NoEOF(s) ((s&0x0040)!=0)
-
-struct rfd_header {
- volatile unsigned long flags;
- volatile unsigned short link;
- volatile unsigned short rbd_offset;
- volatile unsigned short dstaddr1;
- volatile unsigned short dstaddr2;
- volatile unsigned short dstaddr3;
- volatile unsigned short srcaddr1;
- volatile unsigned short srcaddr2;
- volatile unsigned short srcaddr3;
- volatile unsigned short length;
-
- /* This is actually a Receive Buffer Descriptor. The way we
- * arrange memory means that an RBD always follows the RFD that
- * points to it, so they might as well be in the same structure.
- */
- volatile unsigned short actual_count;
- volatile unsigned short next_rbd;
- volatile unsigned short buf_addr1;
- volatile unsigned short buf_addr2;
- volatile unsigned short size;
-};
-
-/* Returned data from the Time Domain Reflectometer */
-
-#define TDR_LINKOK (1<<15)
-#define TDR_XCVRPROBLEM (1<<14)
-#define TDR_OPEN (1<<13)
-#define TDR_SHORT (1<<12)
-#define TDR_TIME 0x7ff
diff --git a/drivers/net/ehea/ehea_hcall.h b/drivers/net/ehea/ehea_hcall.h
deleted file mode 100644
index 8e7d1c3edc6..00000000000
--- a/drivers/net/ehea/ehea_hcall.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * linux/drivers/net/ehea/ehea_hcall.h
- *
- * eHEA ethernet device driver for IBM eServer System p
- *
- * (C) Copyright IBM Corp. 2006
- *
- * Authors:
- * Christoph Raisch <raisch@de.ibm.com>
- * Jan-Bernd Themann <themann@de.ibm.com>
- * Thomas Klein <tklein@de.ibm.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __EHEA_HCALL_H__
-#define __EHEA_HCALL_H__
-
-/**
- * This file contains HCALL defines that are to be included in the appropriate
- * kernel files later
- */
-
-#define H_ALLOC_HEA_RESOURCE 0x278
-#define H_MODIFY_HEA_QP 0x250
-#define H_QUERY_HEA_QP 0x254
-#define H_QUERY_HEA 0x258
-#define H_QUERY_HEA_PORT 0x25C
-#define H_MODIFY_HEA_PORT 0x260
-#define H_REG_BCMC 0x264
-#define H_DEREG_BCMC 0x268
-#define H_REGISTER_HEA_RPAGES 0x26C
-#define H_DISABLE_AND_GET_HEA 0x270
-#define H_GET_HEA_INFO 0x274
-#define H_ADD_CONN 0x284
-#define H_DEL_CONN 0x288
-
-#endif /* __EHEA_HCALL_H__ */
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 18f1364d3d5..7a79b604687 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -111,9 +111,13 @@
* Sorry, I had to rewrite most of this for 2.5.x -DaveM
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/capability.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/netdevice.h>
#include <net/net_namespace.h>
@@ -121,13 +125,14 @@
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/if_eql.h>
+#include <linux/pkt_sched.h>
#include <asm/uaccess.h>
static int eql_open(struct net_device *dev);
static int eql_close(struct net_device *dev);
static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t eql_slave_xmit(struct sk_buff *skb, struct net_device *dev);
#define eql_is_slave(dev) ((dev->flags & IFF_SLAVE) == IFF_SLAVE)
#define eql_is_master(dev) ((dev->flags & IFF_MASTER) == IFF_MASTER)
@@ -139,7 +144,7 @@ static void eql_timer(unsigned long param)
equalizer_t *eql = (equalizer_t *) param;
struct list_head *this, *tmp, *head;
- spin_lock_bh(&eql->queue.lock);
+ spin_lock(&eql->queue.lock);
head = &eql->queue.all_slaves;
list_for_each_safe(this, tmp, head) {
slave_t *slave = list_entry(this, slave_t, list);
@@ -153,14 +158,21 @@ static void eql_timer(unsigned long param)
}
}
- spin_unlock_bh(&eql->queue.lock);
+ spin_unlock(&eql->queue.lock);
eql->timer.expires = jiffies + EQL_DEFAULT_RESCHED_IVAL;
add_timer(&eql->timer);
}
-static char version[] __initdata =
- "Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)\n";
+static const char version[] __initconst =
+ "Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)";
+
+static const struct net_device_ops eql_netdev_ops = {
+ .ndo_open = eql_open,
+ .ndo_stop = eql_close,
+ .ndo_do_ioctl = eql_ioctl,
+ .ndo_start_xmit = eql_slave_xmit,
+};
static void __init eql_setup(struct net_device *dev)
{
@@ -175,10 +187,7 @@ static void __init eql_setup(struct net_device *dev)
INIT_LIST_HEAD(&eql->queue.all_slaves);
eql->queue.master_dev = dev;
- dev->open = eql_open;
- dev->stop = eql_close;
- dev->do_ioctl = eql_ioctl;
- dev->hard_start_xmit = eql_slave_xmit;
+ dev->netdev_ops = &eql_netdev_ops;
/*
* Now we undo some of the things that eth_setup does
@@ -190,6 +199,7 @@ static void __init eql_setup(struct net_device *dev)
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 5; /* Hands them off fast */
+ dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
}
static int eql_open(struct net_device *dev)
@@ -197,8 +207,8 @@ static int eql_open(struct net_device *dev)
equalizer_t *eql = netdev_priv(dev);
/* XXX We should force this off automatically for the user. */
- printk(KERN_INFO "%s: remember to turn off Van-Jacobson compression on "
- "your slave devices.\n", dev->name);
+ netdev_info(dev,
+ "remember to turn off Van-Jacobson compression on your slave devices\n");
BUG_ON(!list_empty(&eql->queue.all_slaves));
@@ -281,7 +291,7 @@ static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return eql_s_master_cfg(dev, ifr->ifr_data);
default:
return -EOPNOTSUPP;
- };
+ }
}
/* queue->lock must be held */
@@ -320,7 +330,7 @@ static slave_t *__eql_schedule_slaves(slave_queue_t *queue)
return best_slave;
}
-static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
{
equalizer_t *eql = netdev_priv(dev);
slave_t *slave;
@@ -332,7 +342,7 @@ static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
struct net_device *slave_dev = slave->dev;
skb->dev = slave_dev;
- skb->priority = 1;
+ skb->priority = TC_PRIO_FILLER;
slave->bytes_queued += skb->len;
dev_queue_xmit(skb);
dev->stats.tx_packets++;
@@ -343,7 +353,7 @@ static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock(&eql->queue.lock);
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -385,6 +395,7 @@ static int __eql_insert_slave(slave_queue_t *queue, slave_t *slave)
if (duplicate_slave)
eql_kill_one_slave(queue, duplicate_slave);
+ dev_hold(slave->dev);
list_add(&slave->list, &queue->all_slaves);
queue->num_slaves++;
slave->dev->flags |= IFF_SLAVE;
@@ -403,39 +414,35 @@ static int eql_enslave(struct net_device *master_dev, slaving_request_t __user *
if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
return -EFAULT;
- slave_dev = dev_get_by_name(&init_net, srq.slave_name);
- if (slave_dev) {
- if ((master_dev->flags & IFF_UP) == IFF_UP) {
- /* slave is not a master & not already a slave: */
- if (!eql_is_master(slave_dev) &&
- !eql_is_slave(slave_dev)) {
- slave_t *s = kmalloc(sizeof(*s), GFP_KERNEL);
- equalizer_t *eql = netdev_priv(master_dev);
- int ret;
-
- if (!s) {
- dev_put(slave_dev);
- return -ENOMEM;
- }
-
- memset(s, 0, sizeof(*s));
- s->dev = slave_dev;
- s->priority = srq.priority;
- s->priority_bps = srq.priority;
- s->priority_Bps = srq.priority / 8;
-
- spin_lock_bh(&eql->queue.lock);
- ret = __eql_insert_slave(&eql->queue, s);
- if (ret) {
- dev_put(slave_dev);
- kfree(s);
- }
- spin_unlock_bh(&eql->queue.lock);
-
- return ret;
- }
+ slave_dev = __dev_get_by_name(&init_net, srq.slave_name);
+ if (!slave_dev)
+ return -ENODEV;
+
+ if ((master_dev->flags & IFF_UP) == IFF_UP) {
+ /* slave is not a master & not already a slave: */
+ if (!eql_is_master(slave_dev) && !eql_is_slave(slave_dev)) {
+ slave_t *s = kmalloc(sizeof(*s), GFP_KERNEL);
+ equalizer_t *eql = netdev_priv(master_dev);
+ int ret;
+
+ if (!s)
+ return -ENOMEM;
+
+ memset(s, 0, sizeof(*s));
+ s->dev = slave_dev;
+ s->priority = srq.priority;
+ s->priority_bps = srq.priority;
+ s->priority_Bps = srq.priority / 8;
+
+ spin_lock_bh(&eql->queue.lock);
+ ret = __eql_insert_slave(&eql->queue, s);
+ if (ret)
+ kfree(s);
+
+ spin_unlock_bh(&eql->queue.lock);
+
+ return ret;
}
- dev_put(slave_dev);
}
return -EINVAL;
@@ -451,24 +458,20 @@ static int eql_emancipate(struct net_device *master_dev, slaving_request_t __use
if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
return -EFAULT;
- slave_dev = dev_get_by_name(&init_net, srq.slave_name);
- ret = -EINVAL;
- if (slave_dev) {
- spin_lock_bh(&eql->queue.lock);
-
- if (eql_is_slave(slave_dev)) {
- slave_t *slave = __eql_find_slave_dev(&eql->queue,
- slave_dev);
+ slave_dev = __dev_get_by_name(&init_net, srq.slave_name);
+ if (!slave_dev)
+ return -ENODEV;
- if (slave) {
- eql_kill_one_slave(&eql->queue, slave);
- ret = 0;
- }
+ ret = -EINVAL;
+ spin_lock_bh(&eql->queue.lock);
+ if (eql_is_slave(slave_dev)) {
+ slave_t *slave = __eql_find_slave_dev(&eql->queue, slave_dev);
+ if (slave) {
+ eql_kill_one_slave(&eql->queue, slave);
+ ret = 0;
}
- dev_put(slave_dev);
-
- spin_unlock_bh(&eql->queue.lock);
}
+ spin_unlock_bh(&eql->queue.lock);
return ret;
}
@@ -484,7 +487,7 @@ static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
return -EFAULT;
- slave_dev = dev_get_by_name(&init_net, sc.slave_name);
+ slave_dev = __dev_get_by_name(&init_net, sc.slave_name);
if (!slave_dev)
return -ENODEV;
@@ -500,8 +503,6 @@ static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
}
spin_unlock_bh(&eql->queue.lock);
- dev_put(slave_dev);
-
if (!ret && copy_to_user(scp, &sc, sizeof (slave_config_t)))
ret = -EFAULT;
@@ -519,7 +520,7 @@ static int eql_s_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
if (copy_from_user(&sc, scp, sizeof (slave_config_t)))
return -EFAULT;
- slave_dev = dev_get_by_name(&init_net, sc.slave_name);
+ slave_dev = __dev_get_by_name(&init_net, sc.slave_name);
if (!slave_dev)
return -ENODEV;
@@ -546,6 +547,8 @@ static int eql_g_master_cfg(struct net_device *dev, master_config_t __user *mcp)
equalizer_t *eql;
master_config_t mc;
+ memset(&mc, 0, sizeof(master_config_t));
+
if (eql_is_master(dev)) {
eql = netdev_priv(dev);
mc.max_slaves = eql->max_slaves;
@@ -580,7 +583,7 @@ static int __init eql_init_module(void)
{
int err;
- printk(version);
+ pr_info("%s\n", version);
dev_eql = alloc_netdev(sizeof(equalizer_t), "eql", eql_setup);
if (!dev_eql)
diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c
deleted file mode 100644
index deefa51b8c3..00000000000
--- a/drivers/net/es3210.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- es3210.c
-
- Linux driver for Racal-Interlan ES3210 EISA Network Adapter
-
- Copyright (C) 1996, Paul Gortmaker.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- Information and Code Sources:
-
- 1) The existing myriad of Linux 8390 drivers written by Donald Becker.
-
- 2) Once again Russ Nelson's asm packet driver provided additional info.
-
- 3) Info for getting IRQ and sh-mem gleaned from the EISA cfg files.
- Too bad it doesn't work -- see below.
-
- The ES3210 is an EISA shared memory NS8390 implementation. Note
- that all memory copies to/from the board must be 32bit transfers.
- Which rules out using eth_io_copy_and_sum() in this driver.
-
- Apparently there are two slightly different revisions of the
- card, since there are two distinct EISA cfg files (!rii0101.cfg
- and !rii0102.cfg) One has media select in the cfg file and the
- other doesn't. Hopefully this will work with either.
-
- That is about all I can tell you about it, having never actually
- even seen one of these cards. :) Try http://www.interlan.com
- if you want more info.
-
- Thanks go to Mark Salazar for testing v0.02 of this driver.
-
- Bugs, to-fix, etc:
-
- 1) The EISA cfg ports that are *supposed* to have the IRQ and shared
- mem values just read 0xff all the time. Hrrmpf. Apparently the
- same happens with the packet driver as the code for reading
- these registers is disabled there. In the meantime, boot with:
- ether=<IRQ>,0,0x<shared_mem_addr>,eth0 to override the IRQ and
- shared memory detection. (The i/o port detection is okay.)
-
- 2) Module support currently untested. Probably works though.
-
-*/
-
-static const char version[] =
- "es3210.c: Driver revision v0.03, 14/09/96\n";
-
-#include <linux/module.h>
-#include <linux/eisa.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "8390.h"
-
-static int es_probe1(struct net_device *dev, int ioaddr);
-
-static int es_open(struct net_device *dev);
-static int es_close(struct net_device *dev);
-
-static void es_reset_8390(struct net_device *dev);
-
-static void es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page);
-static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset);
-static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page);
-
-#define ES_START_PG 0x00 /* First page of TX buffer */
-#define ES_STOP_PG 0x40 /* Last page +1 of RX ring */
-
-#define ES_IO_EXTENT 0x37 /* The cfg file says 0xc90 -> 0xcc7 */
-#define ES_ID_PORT 0xc80 /* Same for all EISA cards */
-#define ES_SA_PROM 0xc90 /* Start of e'net addr. */
-#define ES_RESET_PORT 0xc84 /* From the packet driver source */
-#define ES_NIC_OFFSET 0xca0 /* Hello, the 8390 is *here* */
-
-#define ES_ADDR0 0x02 /* 3 byte vendor prefix */
-#define ES_ADDR1 0x07
-#define ES_ADDR2 0x01
-
-/*
- * Two card revisions. EISA ID's are always rev. minor, rev. major,, and
- * then the three vendor letters stored in 5 bits each, with an "a" = 1.
- * For eg: "rii" = 10010 01001 01001 = 0x4929, which is how the EISA
- * config utility determines automagically what config file(s) to use.
- */
-#define ES_EISA_ID1 0x01012949 /* !rii0101.cfg */
-#define ES_EISA_ID2 0x02012949 /* !rii0102.cfg */
-
-#define ES_CFG1 0xcc0 /* IOPORT(1) --> IOPORT(6) in cfg file */
-#define ES_CFG2 0xcc1
-#define ES_CFG3 0xcc2
-#define ES_CFG4 0xcc3
-#define ES_CFG5 0xcc4
-#define ES_CFG6 0xc84 /* NB: 0xc84 is also "reset" port. */
-
-/*
- * You can OR any of the following bits together and assign it
- * to ES_DEBUG to get verbose driver info during operation.
- * Some of these don't do anything yet.
- */
-
-#define ES_D_PROBE 0x01
-#define ES_D_RX_PKT 0x02
-#define ES_D_TX_PKT 0x04
-#define ED_D_IRQ 0x08
-
-#define ES_DEBUG 0
-
-static unsigned char lo_irq_map[] __initdata = {3, 4, 5, 6, 7, 9, 10};
-static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15};
-
-/*
- * Probe for the card. The best way is to read the EISA ID if it
- * is known. Then we check the prefix of the station address
- * PROM for a match against the Racal-Interlan assigned value.
- */
-
-static int __init do_es_probe(struct net_device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
- int irq = dev->irq;
- int mem_start = dev->mem_start;
-
- if (ioaddr > 0x1ff) /* Check a single specified location. */
- return es_probe1(dev, ioaddr);
- else if (ioaddr > 0) /* Don't probe at all. */
- return -ENXIO;
-
- if (!EISA_bus) {
-#if ES_DEBUG & ES_D_PROBE
- printk("es3210.c: Not EISA bus. Not probing high ports.\n");
-#endif
- return -ENXIO;
- }
-
- /* EISA spec allows for up to 16 slots, but 8 is typical. */
- for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- if (es_probe1(dev, ioaddr) == 0)
- return 0;
- dev->irq = irq;
- dev->mem_start = mem_start;
- }
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init es_probe(int unit)
-{
- struct net_device *dev = alloc_ei_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_es_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static int __init es_probe1(struct net_device *dev, int ioaddr)
-{
- int i, retval;
- unsigned long eisa_id;
- DECLARE_MAC_BUF(mac);
-
- if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210"))
- return -ENODEV;
-
-#if ES_DEBUG & ES_D_PROBE
- printk("es3210.c: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + ES_ID_PORT));
- printk("es3210.c: config regs: %#x %#x %#x %#x %#x %#x\n",
- inb(ioaddr + ES_CFG1), inb(ioaddr + ES_CFG2), inb(ioaddr + ES_CFG3),
- inb(ioaddr + ES_CFG4), inb(ioaddr + ES_CFG5), inb(ioaddr + ES_CFG6));
-#endif
-
-/* Check the EISA ID of the card. */
- eisa_id = inl(ioaddr + ES_ID_PORT);
- if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) {
- retval = -ENODEV;
- goto out;
- }
-
- for (i = 0; i < ETHER_ADDR_LEN ; i++)
- dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i);
-
-/* Check the Racal vendor ID as well. */
- if (dev->dev_addr[0] != ES_ADDR0 ||
- dev->dev_addr[1] != ES_ADDR1 ||
- dev->dev_addr[2] != ES_ADDR2) {
- printk("es3210.c: card not found %s (invalid_prefix).\n",
- print_mac(mac, dev->dev_addr));
- retval = -ENODEV;
- goto out;
- }
-
- printk("es3210.c: ES3210 rev. %ld at %#x, node %s",
- eisa_id>>24, ioaddr, print_mac(mac, dev->dev_addr));
-
- /* Snarf the interrupt now. */
- if (dev->irq == 0) {
- unsigned char hi_irq = inb(ioaddr + ES_CFG2) & 0x07;
- unsigned char lo_irq = inb(ioaddr + ES_CFG1) & 0xfe;
-
- if (hi_irq != 0) {
- dev->irq = hi_irq_map[hi_irq - 1];
- } else {
- int i = 0;
- while (lo_irq > (1<<i)) i++;
- dev->irq = lo_irq_map[i];
- }
- printk(" using IRQ %d", dev->irq);
-#if ES_DEBUG & ES_D_PROBE
- printk("es3210.c: hi_irq %#x, lo_irq %#x, dev->irq = %d\n",
- hi_irq, lo_irq, dev->irq);
-#endif
- } else {
- if (dev->irq == 2)
- dev->irq = 9; /* Doh! */
- printk(" assigning IRQ %d", dev->irq);
- }
-
- if (request_irq(dev->irq, ei_interrupt, 0, "es3210", dev)) {
- printk (" unable to get IRQ %d.\n", dev->irq);
- retval = -EAGAIN;
- goto out;
- }
-
- if (dev->mem_start == 0) {
- unsigned char mem_enabled = inb(ioaddr + ES_CFG2) & 0xc0;
- unsigned char mem_bits = inb(ioaddr + ES_CFG3) & 0x07;
-
- if (mem_enabled != 0x80) {
- printk(" shared mem disabled - giving up\n");
- retval = -ENXIO;
- goto out1;
- }
- dev->mem_start = 0xC0000 + mem_bits*0x4000;
- printk(" using ");
- } else {
- printk(" assigning ");
- }
-
- ei_status.mem = ioremap(dev->mem_start, (ES_STOP_PG - ES_START_PG)*256);
- if (!ei_status.mem) {
- printk("ioremap failed - giving up\n");
- retval = -ENXIO;
- goto out1;
- }
-
- dev->mem_end = dev->mem_start + (ES_STOP_PG - ES_START_PG)*256;
-
- printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1);
-
-#if ES_DEBUG & ES_D_PROBE
- if (inb(ioaddr + ES_CFG5))
- printk("es3210: Warning - DMA channel enabled, but not used here.\n");
-#endif
- /* Note, point at the 8390, and not the card... */
- dev->base_addr = ioaddr + ES_NIC_OFFSET;
-
- ei_status.name = "ES3210";
- ei_status.tx_start_page = ES_START_PG;
- ei_status.rx_start_page = ES_START_PG + TX_PAGES;
- ei_status.stop_page = ES_STOP_PG;
- ei_status.word16 = 1;
-
- if (ei_debug > 0)
- printk(version);
-
- ei_status.reset_8390 = &es_reset_8390;
- ei_status.block_input = &es_block_input;
- ei_status.block_output = &es_block_output;
- ei_status.get_8390_hdr = &es_get_8390_hdr;
-
- dev->open = &es_open;
- dev->stop = &es_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
- NS8390_init(dev, 0);
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
- return 0;
-out1:
- free_irq(dev->irq, dev);
-out:
- release_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT);
- return retval;
-}
-
-/*
- * Reset as per the packet driver method. Judging by the EISA cfg
- * file, this just toggles the "Board Enable" bits (bit 2 and 0).
- */
-
-static void es_reset_8390(struct net_device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
- unsigned long end;
-
- outb(0x04, ioaddr + ES_RESET_PORT);
- if (ei_debug > 1) printk("%s: resetting the ES3210...", dev->name);
-
- end = jiffies + 2*HZ/100;
- while ((signed)(end - jiffies) > 0) continue;
-
- ei_status.txing = 0;
- outb(0x01, ioaddr + ES_RESET_PORT);
- if (ei_debug > 1) printk("reset done\n");
-
- return;
-}
-
-/*
- * Note: In the following three functions is the implicit assumption
- * that the associated memcpy will only use "rep; movsl" as long as
- * we keep the counts as some multiple of doublewords. This is a
- * requirement of the hardware, and also prevents us from using
- * eth_io_copy_and_sum() since we can't guarantee it will limit
- * itself to doubleword access.
- */
-
-/*
- * Grab the 8390 specific header. Similar to the block_input routine, but
- * we don't need to be concerned with ring wrap as the header will be at
- * the start of a page, so we optimize accordingly. (A single doubleword.)
- */
-
-static void
-es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- void __iomem *hdr_start = ei_status.mem + ((ring_page - ES_START_PG)<<8);
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
- hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */
-}
-
-/*
- * Block input and output are easy on shared memory ethercards, the only
- * complication is when the ring buffer wraps. The count will already
- * be rounded up to a doubleword value via es_get_8390_hdr() above.
- */
-
-static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb,
- int ring_offset)
-{
- void __iomem *xfer_start = ei_status.mem + ring_offset - ES_START_PG*256;
-
- if (ring_offset + count > ES_STOP_PG*256) {
- /* Packet wraps over end of ring buffer. */
- int semi_count = ES_STOP_PG*256 - ring_offset;
- memcpy_fromio(skb->data, xfer_start, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
- } else {
- /* Packet is in one chunk. */
- memcpy_fromio(skb->data, xfer_start, count);
- }
-}
-
-static void es_block_output(struct net_device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- void __iomem *shmem = ei_status.mem + ((start_page - ES_START_PG)<<8);
-
- count = (count + 3) & ~3; /* Round up to doubleword */
- memcpy_toio(shmem, buf, count);
-}
-
-static int es_open(struct net_device *dev)
-{
- ei_open(dev);
- return 0;
-}
-
-static int es_close(struct net_device *dev)
-{
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
- ei_close(dev);
- return 0;
-}
-
-#ifdef MODULE
-#define MAX_ES_CARDS 4 /* Max number of ES3210 cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static struct net_device *dev_es3210[MAX_ES_CARDS];
-static int io[MAX_ES_CARDS];
-static int irq[MAX_ES_CARDS];
-static int mem[MAX_ES_CARDS];
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s)");
-MODULE_PARM_DESC(mem, "memory base address(es)");
-MODULE_DESCRIPTION("Racal-Interlan ES3210 EISA ethernet driver");
-MODULE_LICENSE("GPL");
-
-int __init init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
- if (io[this_dev] == 0 && this_dev != 0)
- break;
- dev = alloc_ei_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_start = mem[this_dev];
- if (do_es_probe(dev) == 0) {
- dev_es3210[found++] = dev;
- continue;
- }
- free_netdev(dev);
- printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, ES_IO_EXTENT);
- iounmap(ei_status.mem);
-}
-
-void __exit
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
- struct net_device *dev = dev_es3210[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
deleted file mode 100644
index bee8b3fbc56..00000000000
--- a/drivers/net/eth16i.c
+++ /dev/null
@@ -1,1489 +0,0 @@
-/* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
-
- Written 1994-1999 by Mika Kuoppala
-
- Copyright (C) 1994-1999 by Mika Kuoppala
- Based on skeleton.c and heavily on at1700.c by Donald Becker
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as miku@iki.fi
-
- This driver supports following cards :
- - ICL EtherTeam 16i
- - ICL EtherTeam 32 EISA
- (Uses true 32 bit transfers rather than 16i compability mode)
-
- Example Module usage:
- insmod eth16i.o io=0x2a0 mediatype=bnc
-
- mediatype can be one of the following: bnc,tp,dix,auto,eprom
-
- 'auto' will try to autoprobe mediatype.
- 'eprom' will use whatever type defined in eprom.
-
- I have benchmarked driver with PII/300Mhz as a ftp client
- and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec.
-
- Sources:
- - skeleton.c a sample network driver core for linux,
- written by Donald Becker <becker@scyld.com>
- - at1700.c a driver for Allied Telesis AT1700, written
- by Donald Becker.
- - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
- written by Markku Viima
- - The Fujitsu MB86965 databook.
-
- Author thanks following persons due to their valueble assistance:
- Markku Viima (ICL)
- Ari Valve (ICL)
- Donald Becker
- Kurt Huwig <kurt@huwig.de>
-
- Revision history:
-
- Version Date Description
-
- 0.01 15.12-94 Initial version (card detection)
- 0.02 23.01-95 Interrupt is now hooked correctly
- 0.03 01.02-95 Rewrote initialization part
- 0.04 07.02-95 Base skeleton done...
- Made a few changes to signature checking
- to make it a bit reliable.
- - fixed bug in tx_buf mapping
- - fixed bug in initialization (DLC_EN
- wasn't enabled when initialization
- was done.)
- 0.05 08.02-95 If there were more than one packet to send,
- transmit was jammed due to invalid
- register write...now fixed
- 0.06 19.02-95 Rewrote interrupt handling
- 0.07 13.04-95 Wrote EEPROM read routines
- Card configuration now set according to
- data read from EEPROM
- 0.08 23.06-95 Wrote part that tries to probe used interface
- port if AUTO is selected
-
- 0.09 01.09-95 Added module support
-
- 0.10 04.09-95 Fixed receive packet allocation to work
- with kernels > 1.3.x
-
- 0.20 20.09-95 Added support for EtherTeam32 EISA
-
- 0.21 17.10-95 Removed the unnecessary extern
- init_etherdev() declaration. Some
- other cleanups.
-
- 0.22 22.02-96 Receive buffer was not flushed
- correctly when faulty packet was
- received. Now fixed.
-
- 0.23 26.02-96 Made resetting the adapter
- more reliable.
-
- 0.24 27.02-96 Rewrote faulty packet handling in eth16i_rx
-
- 0.25 22.05-96 kfree() was missing from cleanup_module.
-
- 0.26 11.06-96 Sometimes card was not found by
- check_signature(). Now made more reliable.
-
- 0.27 23.06-96 Oops. 16 consecutive collisions halted
- adapter. Now will try to retransmit
- MAX_COL_16 times before finally giving up.
-
- 0.28 28.10-97 Added dev_id parameter (NULL) for free_irq
-
- 0.29 29.10-97 Multiple card support for module users
-
- 0.30 30.10-97 Fixed irq allocation bug.
- (request_irq moved from probe to open)
-
- 0.30a 21.08-98 Card detection made more relaxed. Driver
- had problems with some TCP/IP-PROM boots
- to find the card. Suggested by
- Kurt Huwig <kurt@huwig.de>
-
- 0.31 28.08-98 Media interface port can now be selected
- with module parameters or kernel
- boot parameters.
-
- 0.32 31.08-98 IRQ was never freed if open/close
- pair wasn't called. Now fixed.
-
- 0.33 10.09-98 When eth16i_open() was called after
- eth16i_close() chip never recovered.
- Now more shallow reset is made on
- close.
-
- 0.34 29.06-99 Fixed one bad #ifdef.
- Changed ioaddr -> io for consistency
-
- 0.35 01.07-99 transmit,-receive bytes were never
- updated in stats.
-
- Bugs:
- In some cases the media interface autoprobing code doesn't find
- the correct interface type. In this case you can
- manually choose the interface type in DOS with E16IC.EXE which is
- configuration software for EtherTeam16i and EtherTeam32 cards.
- This is also true for IRQ setting. You cannot use module
- parameter to configure IRQ of the card (yet).
-
- To do:
- - Real multicast support
- - Rewrite the media interface autoprobing code. Its _horrible_ !
- - Possibly merge all the MB86965 specific code to external
- module for use by eth16.c and Donald's at1700.c
- - IRQ configuration with module parameter. I will do
- this when i will get enough info about setting
- irq without configuration utility.
-*/
-
-static char *version =
- "eth16i.c: v0.35 01-Jul-1999 Mika Kuoppala (miku@iki.fi)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/io.h>
-
-#include <asm/system.h>
-#include <asm/dma.h>
-
-
-
-/* Few macros */
-#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
-#define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
-
-/* This is the I/O address space for Etherteam 16i adapter. */
-#define ETH16I_IO_EXTENT 32
-
-/* Ticks before deciding that transmit has timed out */
-#define TX_TIMEOUT (400*HZ/1000)
-
-/* Maximum loop count when receiving packets */
-#define MAX_RX_LOOP 20
-
-/* Some interrupt masks */
-#define ETH16I_INTR_ON 0xef8a /* Higher is receive mask */
-#define ETH16I_INTR_OFF 0x0000
-
-/* Buffers header status byte meanings */
-#define PKT_GOOD BIT(5)
-#define PKT_GOOD_RMT BIT(4)
-#define PKT_SHORT BIT(3)
-#define PKT_ALIGN_ERR BIT(2)
-#define PKT_CRC_ERR BIT(1)
-#define PKT_RX_BUF_OVERFLOW BIT(0)
-
-/* Transmit status register (DLCR0) */
-#define TX_STATUS_REG 0
-#define TX_DONE BIT(7)
-#define NET_BUSY BIT(6)
-#define TX_PKT_RCD BIT(5)
-#define CR_LOST BIT(4)
-#define TX_JABBER_ERR BIT(3)
-#define COLLISION BIT(2)
-#define COLLISIONS_16 BIT(1)
-
-/* Receive status register (DLCR1) */
-#define RX_STATUS_REG 1
-#define RX_PKT BIT(7) /* Packet received */
-#define BUS_RD_ERR BIT(6)
-#define SHORT_PKT_ERR BIT(3)
-#define ALIGN_ERR BIT(2)
-#define CRC_ERR BIT(1)
-#define RX_BUF_OVERFLOW BIT(0)
-
-/* Transmit Interrupt Enable Register (DLCR2) */
-#define TX_INTR_REG 2
-#define TX_INTR_DONE BIT(7)
-#define TX_INTR_COL BIT(2)
-#define TX_INTR_16_COL BIT(1)
-
-/* Receive Interrupt Enable Register (DLCR3) */
-#define RX_INTR_REG 3
-#define RX_INTR_RECEIVE BIT(7)
-#define RX_INTR_SHORT_PKT BIT(3)
-#define RX_INTR_CRC_ERR BIT(1)
-#define RX_INTR_BUF_OVERFLOW BIT(0)
-
-/* Transmit Mode Register (DLCR4) */
-#define TRANSMIT_MODE_REG 4
-#define LOOPBACK_CONTROL BIT(1)
-#define CONTROL_OUTPUT BIT(2)
-
-/* Receive Mode Register (DLCR5) */
-#define RECEIVE_MODE_REG 5
-#define RX_BUFFER_EMPTY BIT(6)
-#define ACCEPT_BAD_PACKETS BIT(5)
-#define RECEIVE_SHORT_ADDR BIT(4)
-#define ACCEPT_SHORT_PACKETS BIT(3)
-#define REMOTE_RESET BIT(2)
-
-#define ADDRESS_FILTER_MODE BIT(1) | BIT(0)
-#define REJECT_ALL 0
-#define ACCEPT_ALL 3
-#define MODE_1 1 /* NODE ID, BC, MC, 2-24th bit */
-#define MODE_2 2 /* NODE ID, BC, MC, Hash Table */
-
-/* Configuration Register 0 (DLCR6) */
-#define CONFIG_REG_0 6
-#define DLC_EN BIT(7)
-#define SRAM_CYCLE_TIME_100NS BIT(6)
-#define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */
-#define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */
-#define TBS1 BIT(3)
-#define TBS0 BIT(2)
-#define SRAM_BS1 BIT(1) /* 00=8kb, 01=16kb */
-#define SRAM_BS0 BIT(0) /* 10=32kb, 11=64kb */
-
-#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */
-#define ETH16I_TX_BUF_SIZE 3 /* 2 = 8kb, 3 = 16kb */
-#endif
-#define TX_BUF_1x2048 0
-#define TX_BUF_2x2048 1
-#define TX_BUF_2x4098 2
-#define TX_BUF_2x8192 3
-
-/* Configuration Register 1 (DLCR7) */
-#define CONFIG_REG_1 7
-#define POWERUP BIT(5)
-
-/* Transmit start register */
-#define TRANSMIT_START_REG 10
-#define TRANSMIT_START_RB 2
-#define TX_START BIT(7) /* Rest of register bit indicate*/
- /* number of packets in tx buffer*/
-/* Node ID registers (DLCR8-13) */
-#define NODE_ID_0 8
-#define NODE_ID_RB 0
-
-/* Hash Table registers (HT8-15) */
-#define HASH_TABLE_0 8
-#define HASH_TABLE_RB 1
-
-/* Buffer memory ports */
-#define BUFFER_MEM_PORT_LB 8
-#define DATAPORT BUFFER_MEM_PORT_LB
-#define BUFFER_MEM_PORT_HB 9
-
-/* 16 Collision control register (BMPR11) */
-#define COL_16_REG 11
-#define HALT_ON_16 0x00
-#define RETRANS_AND_HALT_ON_16 0x02
-
-/* Maximum number of attempts to send after 16 concecutive collisions */
-#define MAX_COL_16 10
-
-/* DMA Burst and Transceiver Mode Register (BMPR13) */
-#define TRANSCEIVER_MODE_REG 13
-#define TRANSCEIVER_MODE_RB 2
-#define IO_BASE_UNLOCK BIT(7)
-#define LOWER_SQUELCH_TRESH BIT(6)
-#define LINK_TEST_DISABLE BIT(5)
-#define AUI_SELECT BIT(4)
-#define DIS_AUTO_PORT_SEL BIT(3)
-
-/* Filter Self Receive Register (BMPR14) */
-#define FILTER_SELF_RX_REG 14
-#define SKIP_RX_PACKET BIT(2)
-#define FILTER_SELF_RECEIVE BIT(0)
-
-/* EEPROM Control Register (BMPR 16) */
-#define EEPROM_CTRL_REG 16
-
-/* EEPROM Data Register (BMPR 17) */
-#define EEPROM_DATA_REG 17
-
-/* NMC93CSx6 EEPROM Control Bits */
-#define CS_0 0x00
-#define CS_1 0x20
-#define SK_0 0x00
-#define SK_1 0x40
-#define DI_0 0x00
-#define DI_1 0x80
-
-/* NMC93CSx6 EEPROM Instructions */
-#define EEPROM_READ 0x80
-
-/* NMC93CSx6 EEPROM Addresses */
-#define E_NODEID_0 0x02
-#define E_NODEID_1 0x03
-#define E_NODEID_2 0x04
-#define E_PORT_SELECT 0x14
- #define E_PORT_BNC 0x00
- #define E_PORT_DIX 0x01
- #define E_PORT_TP 0x02
- #define E_PORT_AUTO 0x03
- #define E_PORT_FROM_EPROM 0x04
-#define E_PRODUCT_CFG 0x30
-
-
-/* Macro to slow down io between EEPROM clock transitions */
-#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0)
-
-/* Jumperless Configuration Register (BMPR19) */
-#define JUMPERLESS_CONFIG 19
-
-/* ID ROM registers, writing to them also resets some parts of chip */
-#define ID_ROM_0 24
-#define ID_ROM_7 31
-#define RESET ID_ROM_0
-
-/* This is the I/O address list to be probed when seeking the card */
-static unsigned int eth16i_portlist[] __initdata = {
- 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
-};
-
-static unsigned int eth32i_portlist[] __initdata = {
- 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
- 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0
-};
-
-/* This is the Interrupt lookup table for Eth16i card */
-static unsigned int eth16i_irqmap[] __initdata = { 9, 10, 5, 15, 0 };
-#define NUM_OF_ISA_IRQS 4
-
-/* This is the Interrupt lookup table for Eth32i card */
-static unsigned int eth32i_irqmap[] __initdata = { 3, 5, 7, 9, 10, 11, 12, 15, 0 };
-#define EISA_IRQ_REG 0xc89
-#define NUM_OF_EISA_IRQS 8
-
-static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
-
-/* Use 0 for production, 1 for verification, >2 for debug */
-#ifndef ETH16I_DEBUG
-#define ETH16I_DEBUG 0
-#endif
-static unsigned int eth16i_debug = ETH16I_DEBUG;
-
-/* Information for each board */
-
-struct eth16i_local {
- unsigned char tx_started;
- unsigned char tx_buf_busy;
- unsigned short tx_queue; /* Number of packets in transmit buffer */
- unsigned short tx_queue_len;
- unsigned int tx_buf_size;
- unsigned long open_time;
- unsigned long tx_buffered_packets;
- unsigned long tx_buffered_bytes;
- unsigned long col_16;
- spinlock_t lock;
-};
-
-/* Function prototypes */
-
-static int eth16i_probe1(struct net_device *dev, int ioaddr);
-static int eth16i_check_signature(int ioaddr);
-static int eth16i_probe_port(int ioaddr);
-static void eth16i_set_port(int ioaddr, int porttype);
-static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l);
-static int eth16i_receive_probe_packet(int ioaddr);
-static int eth16i_get_irq(int ioaddr);
-static int eth16i_read_eeprom(int ioaddr, int offset);
-static int eth16i_read_eeprom_word(int ioaddr);
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command);
-static int eth16i_open(struct net_device *dev);
-static int eth16i_close(struct net_device *dev);
-static int eth16i_tx(struct sk_buff *skb, struct net_device *dev);
-static void eth16i_rx(struct net_device *dev);
-static void eth16i_timeout(struct net_device *dev);
-static irqreturn_t eth16i_interrupt(int irq, void *dev_id);
-static void eth16i_reset(struct net_device *dev);
-static void eth16i_timeout(struct net_device *dev);
-static void eth16i_skip_packet(struct net_device *dev);
-static void eth16i_multicast(struct net_device *dev);
-static void eth16i_select_regbank(unsigned char regbank, int ioaddr);
-static void eth16i_initialize(struct net_device *dev, int boot);
-
-#if 0
-static int eth16i_set_irq(struct net_device *dev);
-#endif
-
-#ifdef MODULE
-static ushort eth16i_parse_mediatype(const char* s);
-#endif
-
-static char cardname[] __initdata = "ICL EtherTeam 16i/32";
-
-static int __init do_eth16i_probe(struct net_device *dev)
-{
- int i;
- int ioaddr;
- int base_addr = dev->base_addr;
-
- if(eth16i_debug > 4)
- printk(KERN_DEBUG "Probing started for %s\n", cardname);
-
- if(base_addr > 0x1ff) /* Check only single location */
- return eth16i_probe1(dev, base_addr);
- else if(base_addr != 0) /* Don't probe at all */
- return -ENXIO;
-
- /* Seek card from the ISA io address space */
- for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++)
- if(eth16i_probe1(dev, ioaddr) == 0)
- return 0;
-
- /* Seek card from the EISA io address space */
- for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++)
- if(eth16i_probe1(dev, ioaddr) == 0)
- return 0;
-
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init eth16i_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct eth16i_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_eth16i_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- static unsigned version_printed;
- int retval;
-
- /* Let's grab the region */
- if (!request_region(ioaddr, ETH16I_IO_EXTENT, cardname))
- return -EBUSY;
-
- /*
- The MB86985 chip has on register which holds information in which
- io address the chip lies. First read this register and compare
- it to our current io address and if match then this could
- be our chip.
- */
-
- if(ioaddr < 0x1000) {
- if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)]
- != ioaddr) {
- retval = -ENODEV;
- goto out;
- }
- }
-
- /* Now we will go a bit deeper and try to find the chip's signature */
-
- if(eth16i_check_signature(ioaddr) != 0) {
- retval = -ENODEV;
- goto out;
- }
-
- /*
- Now it seems that we have found a ethernet chip in this particular
- ioaddr. The MB86985 chip has this feature, that when you read a
- certain register it will increase it's io base address to next
- configurable slot. Now when we have found the chip, first thing is
- to make sure that the chip's ioaddr will hold still here.
- */
-
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
-
- outb(0x00, ioaddr + RESET); /* Reset some parts of chip */
- BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */
-
- if( (eth16i_debug & version_printed++) == 0)
- printk(KERN_INFO "%s", version);
-
- dev->base_addr = ioaddr;
- dev->irq = eth16i_get_irq(ioaddr);
-
- /* Try to obtain interrupt vector */
-
- if ((retval = request_irq(dev->irq, (void *)&eth16i_interrupt, 0, cardname, dev))) {
- printk(KERN_WARNING "%s at %#3x, but is unusable due to conflicting IRQ %d.\n",
- cardname, ioaddr, dev->irq);
- goto out;
- }
-
- printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ",
- dev->name, cardname, ioaddr, dev->irq);
-
-
- /* Now we will have to lock the chip's io address */
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
-
- eth16i_initialize(dev, 1); /* Initialize rest of the chip's registers */
-
- /* Now let's same some energy by shutting down the chip ;) */
- BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
-
- /* Initialize the device structure */
- memset(lp, 0, sizeof(struct eth16i_local));
- dev->open = eth16i_open;
- dev->stop = eth16i_close;
- dev->hard_start_xmit = eth16i_tx;
- dev->set_multicast_list = eth16i_multicast;
- dev->tx_timeout = eth16i_timeout;
- dev->watchdog_timeo = TX_TIMEOUT;
- spin_lock_init(&lp->lock);
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
- return 0;
-out1:
- free_irq(dev->irq, dev);
-out:
- release_region(ioaddr, ETH16I_IO_EXTENT);
- return retval;
-}
-
-
-static void eth16i_initialize(struct net_device *dev, int boot)
-{
- int ioaddr = dev->base_addr;
- int i, node_w = 0;
- unsigned char node_byte = 0;
-
- /* Setup station address */
- eth16i_select_regbank(NODE_ID_RB, ioaddr);
- for(i = 0 ; i < 3 ; i++) {
- unsigned short node_val = eth16i_read_eeprom(ioaddr, E_NODEID_0 + i);
- ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
- }
-
- for(i = 0; i < 6; i++) {
- outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
- if(boot) {
- printk("%02x", inb(ioaddr + NODE_ID_0 + i));
- if(i != 5)
- printk(":");
- }
- }
-
- /* Now we will set multicast addresses to accept none */
- eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
- for(i = 0; i < 8; i++)
- outb(0x00, ioaddr + HASH_TABLE_0 + i);
-
- /*
- Now let's disable the transmitter and receiver, set the buffer ram
- cycle time, bus width and buffer data path width. Also we shall
- set transmit buffer size and total buffer size.
- */
-
- eth16i_select_regbank(2, ioaddr);
-
- node_byte = 0;
- node_w = eth16i_read_eeprom(ioaddr, E_PRODUCT_CFG);
-
- if( (node_w & 0xFF00) == 0x0800)
- node_byte |= BUFFER_WIDTH_8;
-
- node_byte |= SRAM_BS1;
-
- if( (node_w & 0x00FF) == 64)
- node_byte |= SRAM_BS0;
-
- node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
-
- outb(node_byte, ioaddr + CONFIG_REG_0);
-
- /* We shall halt the transmitting, if 16 collisions are detected */
- outb(HALT_ON_16, ioaddr + COL_16_REG);
-
-#ifdef MODULE
- /* if_port already set by init_module() */
-#else
- dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ?
- dev->mem_start : E_PORT_FROM_EPROM;
-#endif
-
- /* Set interface port type */
- if(boot) {
- char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" };
-
- switch(dev->if_port)
- {
-
- case E_PORT_FROM_EPROM:
- dev->if_port = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
- break;
-
- case E_PORT_AUTO:
- dev->if_port = eth16i_probe_port(ioaddr);
- break;
-
- case E_PORT_BNC:
- case E_PORT_TP:
- case E_PORT_DIX:
- break;
- }
-
- printk(" %s interface.\n", porttype[dev->if_port]);
-
- eth16i_set_port(ioaddr, dev->if_port);
- }
-
- /* Set Receive Mode to normal operation */
- outb(MODE_2, ioaddr + RECEIVE_MODE_REG);
-}
-
-static int eth16i_probe_port(int ioaddr)
-{
- int i;
- int retcode;
- unsigned char dummy_packet[64];
-
- /* Powerup the chip */
- outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
-
- eth16i_select_regbank(NODE_ID_RB, ioaddr);
-
- for(i = 0; i < 6; i++) {
- dummy_packet[i] = inb(ioaddr + NODE_ID_0 + i);
- dummy_packet[i+6] = inb(ioaddr + NODE_ID_0 + i);
- }
-
- dummy_packet[12] = 0x00;
- dummy_packet[13] = 0x04;
- memset(dummy_packet + 14, 0, sizeof(dummy_packet) - 14);
-
- eth16i_select_regbank(2, ioaddr);
-
- for(i = 0; i < 3; i++) {
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
- eth16i_set_port(ioaddr, i);
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Set port number %d\n", i);
-
- retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64);
- if(retcode == 0) {
- retcode = eth16i_receive_probe_packet(ioaddr);
- if(retcode != -1) {
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Eth16i interface port found at %d\n", i);
- return i;
- }
- }
- else {
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "TRANSMIT_DONE timeout when probing interface port\n");
- }
- }
-
- if( eth16i_debug > 1)
- printk(KERN_DEBUG "Using default port\n");
-
- return E_PORT_BNC;
-}
-
-static void eth16i_set_port(int ioaddr, int porttype)
-{
- unsigned short temp = 0;
-
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG);
-
- temp |= DIS_AUTO_PORT_SEL;
-
- switch(porttype) {
-
- case E_PORT_BNC :
- temp |= AUI_SELECT;
- break;
-
- case E_PORT_TP :
- break;
-
- case E_PORT_DIX :
- temp |= AUI_SELECT;
- BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
- break;
- }
-
- outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
-
- if(eth16i_debug > 1) {
- printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
- printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n",
- inb(ioaddr+TRANSCEIVER_MODE_REG));
- }
-}
-
-static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l)
-{
- unsigned long starttime;
-
- outb(0xff, ioaddr + TX_STATUS_REG);
-
- outw(l, ioaddr + DATAPORT);
- outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
-
- starttime = jiffies;
- outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
-
- while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
- if( time_after(jiffies, starttime + TX_TIMEOUT)) {
- return -1;
- }
- }
-
- return 0;
-}
-
-static int eth16i_receive_probe_packet(int ioaddr)
-{
- unsigned long starttime;
-
- starttime = jiffies;
-
- while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
- if( time_after(jiffies, starttime + TX_TIMEOUT)) {
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Timeout occurred waiting transmit packet received\n");
- starttime = jiffies;
- while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
- if( time_after(jiffies, starttime + TX_TIMEOUT)) {
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "Timeout occurred waiting receive packet\n");
- return -1;
- }
- }
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "RECEIVE_PACKET\n");
- return(0); /* Found receive packet */
- }
- }
-
- if(eth16i_debug > 1) {
- printk(KERN_DEBUG "TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
- printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
- }
-
- return(0); /* Return success */
-}
-
-#if 0
-static int eth16i_set_irq(struct net_device* dev)
-{
- const int ioaddr = dev->base_addr;
- const int irq = dev->irq;
- int i = 0;
-
- if(ioaddr < 0x1000) {
- while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq)
- i++;
-
- if(i < NUM_OF_ISA_IRQS) {
- u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
- cbyte = (cbyte & 0x3F) | (i << 6);
- outb(cbyte, ioaddr + JUMPERLESS_CONFIG);
- return 0;
- }
- }
- else {
- printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name);
- }
-
- return -1;
-
-}
-#endif
-
-static int __init eth16i_get_irq(int ioaddr)
-{
- unsigned char cbyte;
-
- if( ioaddr < 0x1000) {
- cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
- return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
- } else { /* Oh..the card is EISA so method getting IRQ different */
- unsigned short index = 0;
- cbyte = inb(ioaddr + EISA_IRQ_REG);
- while( (cbyte & 0x01) == 0) {
- cbyte = cbyte >> 1;
- index++;
- }
- return( eth32i_irqmap[ index ] );
- }
-}
-
-static int __init eth16i_check_signature(int ioaddr)
-{
- int i;
- unsigned char creg[4] = { 0 };
-
- for(i = 0; i < 4 ; i++) {
-
- creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
-
- if(eth16i_debug > 1)
- printk("eth16i: read signature byte %x at %x\n",
- creg[i],
- ioaddr + TRANSMIT_MODE_REG + i);
- }
-
- creg[0] &= 0x0F; /* Mask collision cnr */
- creg[2] &= 0x7F; /* Mask DCLEN bit */
-
-#if 0
- /*
- This was removed because the card was sometimes left to state
- from which it couldn't be find anymore. If there is need
- to more strict check still this have to be fixed.
- */
- if( ! ((creg[0] == 0x06) && (creg[1] == 0x41)) ) {
- if(creg[1] != 0x42)
- return -1;
- }
-#endif
-
- if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
- creg[2] &= 0x40;
- creg[3] &= 0x03;
-
- if( !((creg[2] == 0x40) && (creg[3] == 0x00)) )
- return -1;
- }
-
- if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
- return -1;
-
- if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
- return -1;
-
- return 0;
-}
-
-static int eth16i_read_eeprom(int ioaddr, int offset)
-{
- int data = 0;
-
- eth16i_eeprom_cmd(ioaddr, EEPROM_READ | offset);
- outb(CS_1, ioaddr + EEPROM_CTRL_REG);
- data = eth16i_read_eeprom_word(ioaddr);
- outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
-
- return(data);
-}
-
-static int eth16i_read_eeprom_word(int ioaddr)
-{
- int i;
- int data = 0;
-
- for(i = 16; i > 0; i--) {
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- data = (data << 1) |
- ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
-
- eeprom_slow_io();
- }
-
- return(data);
-}
-
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
-{
- int i;
-
- outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
- outb(DI_0, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- outb(DI_1, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
-
- for(i = 7; i >= 0; i--) {
- short cmd = ( (command & (1 << i)) ? DI_1 : DI_0 );
- outb(cmd, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- }
-}
-
-static int eth16i_open(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Powerup the chip */
- outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-
- /* Initialize the chip */
- eth16i_initialize(dev, 0);
-
- /* Set the transmit buffer size */
- lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
-
- if(eth16i_debug > 0)
- printk(KERN_DEBUG "%s: transmit buffer size %d\n",
- dev->name, lp->tx_buf_size);
-
- /* Now enable Transmitter and Receiver sections */
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-
- /* Now switch to register bank 2, for run time operation */
- eth16i_select_regbank(2, ioaddr);
-
- lp->open_time = jiffies;
- lp->tx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- /* Turn on interrupts*/
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- netif_start_queue(dev);
- return 0;
-}
-
-static int eth16i_close(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- eth16i_reset(dev);
-
- /* Turn off interrupts*/
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- netif_stop_queue(dev);
-
- lp->open_time = 0;
-
- /* Disable transmit and receive */
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
-
- /* Reset the chip */
- /* outb(0xff, ioaddr + RESET); */
- /* outw(0xffff, ioaddr + TX_STATUS_REG); */
-
- outb(0x00, ioaddr + CONFIG_REG_1);
-
- return 0;
-}
-
-static void eth16i_timeout(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- /*
- If we get here, some higher level has decided that
- we are broken. There should really be a "kick me"
- function call instead.
- */
-
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
- printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n",
- dev->name,
- inw(ioaddr + TX_STATUS_REG), (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
- "IRQ conflict" : "network cable problem");
-
- dev->trans_start = jiffies;
-
- /* Let's dump all registers */
- if(eth16i_debug > 0) {
- printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
- dev->name, inb(ioaddr + 0),
- inb(ioaddr + 1), inb(ioaddr + 2),
- inb(ioaddr + 3), inb(ioaddr + 4),
- inb(ioaddr + 5),
- inb(ioaddr + 6), inb(ioaddr + 7));
-
- printk(KERN_DEBUG "%s: transmit start reg: %02x. collision reg %02x\n",
- dev->name, inb(ioaddr + TRANSMIT_START_REG),
- inb(ioaddr + COL_16_REG));
- printk(KERN_DEBUG "lp->tx_queue = %d\n", lp->tx_queue);
- printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len);
- printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started);
- }
- dev->stats.tx_errors++;
- eth16i_reset(dev);
- dev->trans_start = jiffies;
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
- netif_wake_queue(dev);
-}
-
-static int eth16i_tx(struct sk_buff *skb, struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int status = 0;
- ushort length = skb->len;
- unsigned char *buf;
- unsigned long flags;
-
- if (length < ETH_ZLEN) {
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- length = ETH_ZLEN;
- }
- buf = skb->data;
-
- netif_stop_queue(dev);
-
- /* Turn off TX interrupts */
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- /* We would be better doing the disable_irq tricks the 3c509 does,
- that would make this suck a lot less */
-
- spin_lock_irqsave(&lp->lock, flags);
-
- if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) {
- if(eth16i_debug > 0)
- printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name);
- }
- else {
- outw(length, ioaddr + DATAPORT);
-
- if( ioaddr < 0x1000 )
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
- else {
- unsigned char frag = length % 4;
- outsl(ioaddr + DATAPORT, buf, length >> 2);
- if( frag != 0 ) {
- outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
- if( frag == 3 )
- outsw(ioaddr + DATAPORT,
- (buf + (length & 0xFFFC) + 2), 1);
- }
- }
- lp->tx_buffered_packets++;
- lp->tx_buffered_bytes = length;
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
- }
- lp->tx_buf_busy = 0;
-
- if(lp->tx_started == 0) {
- /* If the transmitter is idle..always trigger a transmit */
- outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- lp->tx_started = 1;
- netif_wake_queue(dev);
- }
- else if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
- /* There is still more room for one more packet in tx buffer */
- netif_wake_queue(dev);
- }
-
- spin_unlock_irqrestore(&lp->lock, flags);
-
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
- /* Turn TX interrupts back on */
- /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
- status = 0;
- dev_kfree_skb(skb);
- return 0;
-}
-
-static void eth16i_rx(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- int boguscount = MAX_RX_LOOP;
-
- /* Loop until all packets have been read */
- while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
-
- /* Read status byte from receive buffer */
- ushort status = inw(ioaddr + DATAPORT);
-
- /* Get the size of the packet from receive buffer */
- ushort pkt_len = inw(ioaddr + DATAPORT);
-
- if(eth16i_debug > 4)
- printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n",
- dev->name,
- inb(ioaddr + RECEIVE_MODE_REG), status);
-
- if( !(status & PKT_GOOD) ) {
- dev->stats.rx_errors++;
-
- if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) {
- dev->stats.rx_length_errors++;
- eth16i_reset(dev);
- return;
- }
- else {
- eth16i_skip_packet(dev);
- dev->stats.rx_dropped++;
- }
- }
- else { /* Ok so now we should have a good packet */
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len + 3);
- if( skb == NULL ) {
- printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n",
- dev->name, pkt_len);
- eth16i_skip_packet(dev);
- dev->stats.rx_dropped++;
- break;
- }
-
- skb_reserve(skb,2);
-
- /*
- Now let's get the packet out of buffer.
- size is (pkt_len + 1) >> 1, cause we are now reading words
- and it have to be even aligned.
- */
-
- if(ioaddr < 0x1000)
- insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
- (pkt_len + 1) >> 1);
- else {
- unsigned char *buf = skb_put(skb, pkt_len);
- unsigned char frag = pkt_len % 4;
-
- insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
-
- if(frag != 0) {
- unsigned short rest[2];
- rest[0] = inw( ioaddr + DATAPORT );
- if(frag == 3)
- rest[1] = inw( ioaddr + DATAPORT );
-
- memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag);
- }
- }
-
- skb->protocol=eth_type_trans(skb, dev);
-
- if( eth16i_debug > 5 ) {
- int i;
- printk(KERN_DEBUG "%s: Received packet of length %d.\n",
- dev->name, pkt_len);
- for(i = 0; i < 14; i++)
- printk(KERN_DEBUG " %02x", skb->data[i]);
- printk(KERN_DEBUG ".\n");
- }
- netif_rx(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
-
- } /* else */
-
- if(--boguscount <= 0)
- break;
-
- } /* while */
-}
-
-static irqreturn_t eth16i_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct eth16i_local *lp;
- int ioaddr = 0, status;
- int handled = 0;
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- /* Turn off all interrupts from adapter */
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- /* eth16i_tx won't be called */
- spin_lock(&lp->lock);
-
- status = inw(ioaddr + TX_STATUS_REG); /* Get the status */
- outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */
-
- if (status)
- handled = 1;
-
- if(eth16i_debug > 3)
- printk(KERN_DEBUG "%s: Interrupt with status %04x.\n", dev->name, status);
-
- if( status & 0x7f00 ) {
-
- dev->stats.rx_errors++;
-
- if(status & (BUS_RD_ERR << 8) )
- printk(KERN_WARNING "%s: Bus read error.\n",dev->name);
- if(status & (SHORT_PKT_ERR << 8) ) dev->stats.rx_length_errors++;
- if(status & (ALIGN_ERR << 8) ) dev->stats.rx_frame_errors++;
- if(status & (CRC_ERR << 8) ) dev->stats.rx_crc_errors++;
- if(status & (RX_BUF_OVERFLOW << 8) ) dev->stats.rx_over_errors++;
- }
- if( status & 0x001a) {
-
- dev->stats.tx_errors++;
-
- if(status & CR_LOST) dev->stats.tx_carrier_errors++;
- if(status & TX_JABBER_ERR) dev->stats.tx_window_errors++;
-
-#if 0
- if(status & COLLISION) {
- dev->stats.collisions +=
- ((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4);
- }
-#endif
- if(status & COLLISIONS_16) {
- if(lp->col_16 < MAX_COL_16) {
- lp->col_16++;
- dev->stats.collisions++;
- /* Resume transmitting, skip failed packet */
- outb(0x02, ioaddr + COL_16_REG);
- }
- else {
- printk(KERN_WARNING "%s: bailing out due to many consecutive 16-in-a-row collisions. Network cable problem?\n", dev->name);
- }
- }
- }
-
- if( status & 0x00ff ) { /* Let's check the transmit status reg */
-
- if(status & TX_DONE) { /* The transmit has been done */
- dev->stats.tx_packets = lp->tx_buffered_packets;
- dev->stats.tx_bytes += lp->tx_buffered_bytes;
- lp->col_16 = 0;
-
- if(lp->tx_queue) { /* Is there still packets ? */
- /* There was packet(s) so start transmitting and write also
- how many packets there is to be sended */
- outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- lp->tx_started = 1;
- }
- else {
- lp->tx_started = 0;
- }
- netif_wake_queue(dev);
- }
- }
-
- if( ( status & 0x8000 ) ||
- ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
- eth16i_rx(dev); /* We have packet in receive buffer */
- }
-
- /* Turn interrupts back on */
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
- /* There is still more room for one more packet in tx buffer */
- netif_wake_queue(dev);
- }
-
- spin_unlock(&lp->lock);
-
- return IRQ_RETVAL(handled);
-}
-
-static void eth16i_skip_packet(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- inw(ioaddr + DATAPORT);
- inw(ioaddr + DATAPORT);
- inw(ioaddr + DATAPORT);
-
- outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
- while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0);
-}
-
-static void eth16i_reset(struct net_device *dev)
-{
- struct eth16i_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if(eth16i_debug > 1)
- printk(KERN_DEBUG "%s: Resetting device.\n", dev->name);
-
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
- outw(0xffff, ioaddr + TX_STATUS_REG);
- eth16i_select_regbank(2, ioaddr);
-
- lp->tx_started = 0;
- lp->tx_buf_busy = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-}
-
-static void eth16i_multicast(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- {
- outb(3, ioaddr + RECEIVE_MODE_REG);
- } else {
- outb(2, ioaddr + RECEIVE_MODE_REG);
- }
-}
-
-static void eth16i_select_regbank(unsigned char banknbr, int ioaddr)
-{
- unsigned char data;
-
- data = inb(ioaddr + CONFIG_REG_1);
- outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
-}
-
-#ifdef MODULE
-
-static ushort eth16i_parse_mediatype(const char* s)
-{
- if(!s)
- return E_PORT_FROM_EPROM;
-
- if (!strncmp(s, "bnc", 3))
- return E_PORT_BNC;
- else if (!strncmp(s, "tp", 2))
- return E_PORT_TP;
- else if (!strncmp(s, "dix", 3))
- return E_PORT_DIX;
- else if (!strncmp(s, "auto", 4))
- return E_PORT_AUTO;
- else
- return E_PORT_FROM_EPROM;
-}
-
-#define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */
-
-static struct net_device *dev_eth16i[MAX_ETH16I_CARDS];
-static int io[MAX_ETH16I_CARDS];
-#if 0
-static int irq[MAX_ETH16I_CARDS];
-#endif
-static char* mediatype[MAX_ETH16I_CARDS];
-static int debug = -1;
-
-MODULE_AUTHOR("Mika Kuoppala <miku@iki.fi>");
-MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver");
-MODULE_LICENSE("GPL");
-
-
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "eth16i I/O base address(es)");
-
-#if 0
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(irq, "eth16i interrupt request number");
-#endif
-
-module_param_array(mediatype, charp, NULL, 0);
-MODULE_PARM_DESC(mediatype, "eth16i media type of interface(s) (bnc,tp,dix,auto,eprom)");
-
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "eth16i debug level (0-6)");
-
-int __init init_module(void)
-{
- int this_dev, found = 0;
- struct net_device *dev;
-
- for (this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
- dev = alloc_etherdev(sizeof(struct eth16i_local));
- if (!dev)
- break;
-
- dev->base_addr = io[this_dev];
-
- if(debug != -1)
- eth16i_debug = debug;
-
- if(eth16i_debug > 1)
- printk(KERN_NOTICE "eth16i(%d): interface type %s\n", this_dev, mediatype[this_dev] ? mediatype[this_dev] : "none" );
-
- dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
-
- if(io[this_dev] == 0) {
- if(this_dev != 0) /* Only autoprobe 1st one */
- break;
-
- printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
- }
-
- if (do_eth16i_probe(dev) == 0) {
- dev_eth16i[found++] = dev;
- continue;
- }
- printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
- io[this_dev]);
- free_netdev(dev);
- break;
- }
- if (found)
- return 0;
- return -ENXIO;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
-
- for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
- struct net_device *dev = dev_eth16i[this_dev];
-
- if(dev->priv) {
- unregister_netdev(dev);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, ETH16I_IO_EXTENT);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eth16i.c"
- * alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict -prototypes -O6 -c eth16i.c"
- * tab-width: 8
- * c-basic-offset: 8
- * c-indent-level: 8
- * End:
- */
-
-/* End of file eth16i.c */
diff --git a/drivers/net/3c509.c b/drivers/net/ethernet/3com/3c509.c
index b9d097c9f6b..a968654b631 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/ethernet/3com/3c509.c
@@ -40,7 +40,7 @@
v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
v1.15 1/31/98 Faster recovery for Tx errors. -djb
v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
- v1.18 12Mar2001 Andrew Morton <andrewm@uow.edu.au>
+ v1.18 12Mar2001 Andrew Morton
- Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz)
- Reviewed against 1.18 from scyld.com
v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com>
@@ -69,14 +69,12 @@
#define TX_TIMEOUT (400*HZ/1000)
#include <linux/module.h>
-#include <linux/mca.h>
#include <linux/isa.h>
#include <linux/pnp.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/netdevice.h>
@@ -94,7 +92,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-static char version[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
+static char version[] = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
#ifdef EL3_DEBUG
static int el3_debug = EL3_DEBUG;
@@ -103,7 +101,7 @@ static int el3_debug = 2;
#endif
/* Used to do a global count of all the cards in the system. Must be
- * a global variable so that the mca/eisa probe routines can increment
+ * a global variable so that the eisa probe routines can increment
* it */
static int el3_cards = 0;
#define EL3_MAX_CARDS 8
@@ -164,7 +162,7 @@ enum RxFilter {
*/
#define SKB_QUEUE_SIZE 64
-enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA };
+enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_EISA };
struct el3_private {
spinlock_t lock;
@@ -186,12 +184,12 @@ static int max_interrupt_work = 10;
static int nopnp;
#endif
-static int __init el3_common_init(struct net_device *dev);
+static int el3_common_init(struct net_device *dev);
static void el3_common_remove(struct net_device *dev);
static ushort id_read_eeprom(int index);
static ushort read_eeprom(int ioaddr, int index);
static int el3_open(struct net_device *dev);
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t el3_interrupt(int irq, void *dev_id);
static void update_stats(struct net_device *dev);
static struct net_device_stats *el3_get_stats(struct net_device *dev);
@@ -253,11 +251,10 @@ static int el3_isa_id_sequence(__be16 *phys_addr)
This check is needed in order not to register them twice. */
for (i = 0; i < el3_cards; i++) {
struct el3_private *lp = netdev_priv(el3_devs[i]);
- if (lp->type == EL3_PNP
- && !memcmp(phys_addr, el3_devs[i]->dev_addr,
- ETH_ALEN)) {
+ if (lp->type == EL3_PNP &&
+ ether_addr_equal((u8 *)phys_addr, el3_devs[i]->dev_addr)) {
if (el3_debug > 3)
- printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
+ pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
phys_addr[0] & 0xff, phys_addr[0] >> 8,
phys_addr[1] & 0xff, phys_addr[1] >> 8,
phys_addr[2] & 0xff, phys_addr[2] >> 8);
@@ -272,9 +269,8 @@ static int el3_isa_id_sequence(__be16 *phys_addr)
}
-static void __devinit el3_dev_fill(struct net_device *dev, __be16 *phys_addr,
- int ioaddr, int irq, int if_port,
- enum el3_cardtype type)
+static void el3_dev_fill(struct net_device *dev, __be16 *phys_addr, int ioaddr,
+ int irq, int if_port, enum el3_cardtype type)
{
struct el3_private *lp = netdev_priv(dev);
@@ -285,8 +281,7 @@ static void __devinit el3_dev_fill(struct net_device *dev, __be16 *phys_addr,
lp->type = type;
}
-static int __devinit el3_isa_match(struct device *pdev,
- unsigned int ndev)
+static int el3_isa_match(struct device *pdev, unsigned int ndev)
{
struct net_device *dev;
int ioaddr, isa_irq, if_port, err;
@@ -310,6 +305,7 @@ static int __devinit el3_isa_match(struct device *pdev,
if (!dev)
return -ENOMEM;
+ SET_NETDEV_DEV(dev, pdev);
netdev_boot_setup_check(dev);
if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) {
@@ -343,7 +339,7 @@ static int __devinit el3_isa_match(struct device *pdev,
return 1;
}
-static int __devexit el3_isa_remove(struct device *pdev,
+static int el3_isa_remove(struct device *pdev,
unsigned int ndev)
{
el3_device_remove(pdev);
@@ -384,7 +380,7 @@ static int el3_isa_resume(struct device *dev, unsigned int n)
static struct isa_driver el3_isa_driver = {
.match = el3_isa_match,
- .remove = __devexit_p(el3_isa_remove),
+ .remove = el3_isa_remove,
#ifdef CONFIG_PM
.suspend = el3_isa_suspend,
.resume = el3_isa_resume,
@@ -408,8 +404,7 @@ static struct pnp_device_id el3_pnp_ids[] = {
};
MODULE_DEVICE_TABLE(pnp, el3_pnp_ids);
-static int __devinit el3_pnp_probe(struct pnp_dev *pdev,
- const struct pnp_device_id *id)
+static int el3_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)
{
short i;
int ioaddr, irq, if_port;
@@ -447,7 +442,7 @@ static int __devinit el3_pnp_probe(struct pnp_dev *pdev,
return 0;
}
-static void __devexit el3_pnp_remove(struct pnp_dev *pdev)
+static void el3_pnp_remove(struct pnp_dev *pdev)
{
el3_common_remove(pnp_get_drvdata(pdev));
pnp_set_drvdata(pdev, NULL);
@@ -469,7 +464,7 @@ static struct pnp_driver el3_pnp_driver = {
.name = "3c509",
.id_table = el3_pnp_ids,
.probe = el3_pnp_probe,
- .remove = __devexit_p(el3_pnp_remove),
+ .remove = el3_pnp_remove,
#ifdef CONFIG_PM
.suspend = el3_pnp_suspend,
.resume = el3_pnp_resume,
@@ -480,9 +475,13 @@ static int pnp_registered;
#ifdef CONFIG_EISA
static struct eisa_device_id el3_eisa_ids[] = {
+ { "TCM5090" },
+ { "TCM5091" },
{ "TCM5092" },
{ "TCM5093" },
+ { "TCM5094" },
{ "TCM5095" },
+ { "TCM5098" },
{ "" }
};
MODULE_DEVICE_TABLE(eisa, el3_eisa_ids);
@@ -494,7 +493,7 @@ static struct eisa_driver el3_eisa_driver = {
.driver = {
.name = "3c579",
.probe = el3_eisa_probe,
- .remove = __devexit_p (el3_device_remove),
+ .remove = el3_device_remove,
.suspend = el3_suspend,
.resume = el3_resume,
}
@@ -502,46 +501,25 @@ static struct eisa_driver el3_eisa_driver = {
static int eisa_registered;
#endif
-#ifdef CONFIG_MCA
-static int el3_mca_probe(struct device *dev);
-
-static short el3_mca_adapter_ids[] __initdata = {
- 0x627c,
- 0x627d,
- 0x62db,
- 0x62f6,
- 0x62f7,
- 0x0000
-};
-
-static char *el3_mca_adapter_names[] __initdata = {
- "3Com 3c529 EtherLink III (10base2)",
- "3Com 3c529 EtherLink III (10baseT)",
- "3Com 3c529 EtherLink III (test mode)",
- "3Com 3c529 EtherLink III (TP or coax)",
- "3Com 3c529 EtherLink III (TP)",
- NULL
-};
-
-static struct mca_driver el3_mca_driver = {
- .id_table = el3_mca_adapter_ids,
- .driver = {
- .name = "3c529",
- .bus = &mca_bus_type,
- .probe = el3_mca_probe,
- .remove = __devexit_p(el3_device_remove),
- .suspend = el3_suspend,
- .resume = el3_resume,
- },
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = el3_poll_controller,
+#endif
};
-static int mca_registered;
-#endif /* CONFIG_MCA */
-static int __init el3_common_init(struct net_device *dev)
+static int el3_common_init(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
int err;
- DECLARE_MAC_BUF(mac);
const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
spin_lock_init(&lp->lock);
@@ -554,33 +532,24 @@ static int __init el3_common_init(struct net_device *dev)
}
/* The EL3-specific entries in the device structure. */
- dev->open = &el3_open;
- dev->hard_start_xmit = &el3_start_xmit;
- dev->stop = &el3_close;
- dev->get_stats = &el3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->tx_timeout = el3_tx_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = el3_poll_controller;
-#endif
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
+ dev->ethtool_ops = &ethtool_ops;
err = register_netdev(dev);
if (err) {
- printk(KERN_ERR "Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
+ pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
dev->base_addr, dev->irq);
release_region(dev->base_addr, EL3_IO_EXTENT);
return err;
}
- printk(KERN_INFO "%s: 3c5x9 found at %#3.3lx, %s port, "
- "address %s, IRQ %d.\n",
+ pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n",
dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
- print_mac(mac, dev->dev_addr), dev->irq);
+ dev->dev_addr, dev->irq);
if (el3_debug > 0)
- printk(KERN_INFO "%s", version);
+ pr_info("%s", version);
return 0;
}
@@ -592,76 +561,6 @@ static void el3_common_remove (struct net_device *dev)
free_netdev (dev);
}
-#ifdef CONFIG_MCA
-static int __init el3_mca_probe(struct device *device)
-{
- /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
- * heavily modified by Chris Beauregard
- * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA
- * probing.
- *
- * redone for multi-card detection by ZP Gu (zpg@castle.net)
- * now works as a module */
-
- short i;
- int ioaddr, irq, if_port;
- __be16 phys_addr[3];
- struct net_device *dev = NULL;
- u_char pos4, pos5;
- struct mca_device *mdev = to_mca_device(device);
- int slot = mdev->slot;
- int err;
-
- pos4 = mca_device_read_stored_pos(mdev, 4);
- pos5 = mca_device_read_stored_pos(mdev, 5);
-
- ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
- irq = pos5 & 0x0f;
-
-
- printk(KERN_INFO "3c529: found %s at slot %d\n",
- el3_mca_adapter_names[mdev->index], slot + 1);
-
- /* claim the slot */
- strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
- sizeof(mdev->name));
- mca_device_set_claim(mdev, 1);
-
- if_port = pos4 & 0x03;
-
- irq = mca_device_transform_irq(mdev, irq);
- ioaddr = mca_device_transform_ioport(mdev, ioaddr);
- if (el3_debug > 2) {
- printk(KERN_DEBUG "3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
- }
- EL3WINDOW(0);
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
- dev = alloc_etherdev(sizeof (struct el3_private));
- if (dev == NULL) {
- release_region(ioaddr, EL3_IO_EXTENT);
- return -ENOMEM;
- }
-
- netdev_boot_setup_check(dev);
-
- el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
- device->driver_data = dev;
- err = el3_common_init(dev);
-
- if (err) {
- device->driver_data = NULL;
- free_netdev(dev);
- return -ENOMEM;
- }
-
- el3_devs[el3_cards++] = dev;
- return 0;
-}
-
-#endif /* CONFIG_MCA */
-
#ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device)
{
@@ -696,6 +595,7 @@ static int __init el3_eisa_probe (struct device *device)
return -ENOMEM;
}
+ SET_NETDEV_DEV(dev, device);
netdev_boot_setup_check(dev);
el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
@@ -715,12 +615,12 @@ static int __init el3_eisa_probe (struct device *device)
/* This remove works for all device types.
*
- * The net dev must be stored in the driver_data field */
-static int __devexit el3_device_remove (struct device *device)
+ * The net dev must be stored in the driver data field */
+static int el3_device_remove(struct device *device)
{
struct net_device *dev;
- dev = device->driver_data;
+ dev = dev_get_drvdata(device);
el3_common_remove (dev);
return 0;
@@ -755,7 +655,7 @@ static ushort id_read_eeprom(int index)
word = (word << 1) + (inb(id_port) & 0x01);
if (el3_debug > 3)
- printk(KERN_DEBUG " 3c509 EEPROM word %d %#4.4x.\n", index, word);
+ pr_debug(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
return word;
}
@@ -771,19 +671,19 @@ el3_open(struct net_device *dev)
outw(RxReset, ioaddr + EL3_CMD);
outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
- i = request_irq(dev->irq, &el3_interrupt, 0, dev->name, dev);
+ i = request_irq(dev->irq, el3_interrupt, 0, dev->name, dev);
if (i)
return i;
EL3WINDOW(0);
if (el3_debug > 3)
- printk(KERN_DEBUG "%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
+ pr_debug("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
el3_up(dev);
if (el3_debug > 3)
- printk(KERN_DEBUG "%s: Opened 3c509 IRQ %d status %4.4x.\n",
+ pr_debug("%s: Opened 3c509 IRQ %d status %4.4x.\n",
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
return 0;
@@ -795,12 +695,11 @@ el3_tx_timeout (struct net_device *dev)
int ioaddr = dev->base_addr;
/* Transmitter timeout, serious problems. */
- printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x "
- "Tx FIFO room %d.\n",
+ pr_warning("%s: transmit timed out, Tx_status %2.2x status %4.4x Tx FIFO room %d.\n",
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
inw(ioaddr + TX_FREE));
dev->stats.tx_errors++;
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
/* Issue TX_RESET and TX_START commands. */
outw(TxReset, ioaddr + EL3_CMD);
outw(TxEnable, ioaddr + EL3_CMD);
@@ -808,7 +707,7 @@ el3_tx_timeout (struct net_device *dev)
}
-static int
+static netdev_tx_t
el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
@@ -820,28 +719,9 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += skb->len;
if (el3_debug > 4) {
- printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
+ pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
dev->name, skb->len, inw(ioaddr + EL3_STATUS));
}
-#if 0
-#ifndef final_version
- { /* Error-checking code, delete someday. */
- ushort status = inw(ioaddr + EL3_STATUS);
- if (status & 0x0001 /* IRQ line active, missed one. */
- && inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */
- printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x"
- " Tx %2.2x Rx %4.4x.\n", dev->name, status,
- inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
- inw(ioaddr + RX_STATUS));
- /* Fake interrupt trigger by masking, acknowledge interrupts. */
- outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
- outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
- ioaddr + EL3_CMD);
- outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
- }
- }
-#endif
-#endif
/*
* We lock the driver against other processors. Note
* we don't need to lock versus the IRQ as we suspended
@@ -861,7 +741,6 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* ... and the packet rounded to a doubleword. */
outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
- dev->trans_start = jiffies;
if (inw(ioaddr + TX_FREE) > 1536)
netif_start_queue(dev);
else
@@ -870,7 +749,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&lp->lock, flags);
- dev_kfree_skb (skb);
+ dev_consume_skb_any (skb);
/* Clear the Tx status stack. */
{
@@ -884,7 +763,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
}
}
- return 0;
+ return NETDEV_TX_OK;
}
/* The EL3 interrupt handler. */
@@ -903,7 +782,7 @@ el3_interrupt(int irq, void *dev_id)
if (el3_debug > 4) {
status = inw(ioaddr + EL3_STATUS);
- printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status);
+ pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status);
}
while ((status = inw(ioaddr + EL3_STATUS)) &
@@ -914,7 +793,7 @@ el3_interrupt(int irq, void *dev_id)
if (status & TxAvailable) {
if (el3_debug > 5)
- printk(KERN_DEBUG " TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue (dev);
@@ -952,7 +831,7 @@ el3_interrupt(int irq, void *dev_id)
}
if (--i < 0) {
- printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n",
+ pr_err("%s: Infinite loop in interrupt, status %4.4x.\n",
dev->name, status);
/* Clear all interrupts. */
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -963,7 +842,7 @@ el3_interrupt(int irq, void *dev_id)
}
if (el3_debug > 4) {
- printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name,
+ pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name,
inw(ioaddr + EL3_STATUS));
}
spin_unlock(&lp->lock);
@@ -1011,7 +890,7 @@ static void update_stats(struct net_device *dev)
int ioaddr = dev->base_addr;
if (el3_debug > 5)
- printk(" Updating the statistics.\n");
+ pr_debug(" Updating the statistics.\n");
/* Turn off statistics updates while reading. */
outw(StatsDisable, ioaddr + EL3_CMD);
/* Switch to the stats window, and read everything. */
@@ -1031,7 +910,6 @@ static void update_stats(struct net_device *dev)
/* Back to window 1, and turn statistics back on. */
EL3WINDOW(1);
outw(StatsEnable, ioaddr + EL3_CMD);
- return;
}
static int
@@ -1041,7 +919,7 @@ el3_rx(struct net_device *dev)
short rx_status;
if (el3_debug > 5)
- printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
if (rx_status & 0x4000) { /* Error, update stats. */
@@ -1061,9 +939,9 @@ el3_rx(struct net_device *dev)
short pkt_len = rx_status & 0x7ff;
struct sk_buff *skb;
- skb = dev_alloc_skb(pkt_len+5);
+ skb = netdev_alloc_skb(dev, pkt_len + 5);
if (el3_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte */
@@ -1075,7 +953,6 @@ el3_rx(struct net_device *dev)
outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
skb->protocol = eth_type_trans(skb,dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_bytes += pkt_len;
dev->stats.rx_packets++;
continue;
@@ -1083,12 +960,12 @@ el3_rx(struct net_device *dev)
outw(RxDiscard, ioaddr + EL3_CMD);
dev->stats.rx_dropped++;
if (el3_debug)
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
+ pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n",
dev->name, pkt_len);
}
inw(ioaddr + EL3_STATUS); /* Delay. */
while (inw(ioaddr + EL3_STATUS) & 0x1000)
- printk(KERN_DEBUG " Waiting for 3c509 to discard packet, status %x.\n",
+ pr_debug(" Waiting for 3c509 to discard packet, status %x.\n",
inw(ioaddr + EL3_STATUS) );
}
@@ -1104,12 +981,14 @@ set_multicast_list(struct net_device *dev)
unsigned long flags;
struct el3_private *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
+ int mc_count = netdev_mc_count(dev);
if (el3_debug > 1) {
static int old;
- if (old != dev->mc_count) {
- old = dev->mc_count;
- printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
+ if (old != mc_count) {
+ old = mc_count;
+ pr_debug("%s: Setting Rx mode to %d addresses.\n",
+ dev->name, mc_count);
}
}
spin_lock_irqsave(&lp->lock, flags);
@@ -1117,7 +996,7 @@ set_multicast_list(struct net_device *dev)
outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
ioaddr + EL3_CMD);
}
- else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) {
+ else if (mc_count || (dev->flags&IFF_ALLMULTI)) {
outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);
}
else
@@ -1132,7 +1011,7 @@ el3_close(struct net_device *dev)
struct el3_private *lp = netdev_priv(dev);
if (el3_debug > 2)
- printk("%s: Shutting down ethercard.\n", dev->name);
+ pr_debug("%s: Shutting down ethercard.\n", dev->name);
el3_down(dev);
@@ -1201,7 +1080,7 @@ el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->duplex = DUPLEX_FULL;
}
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
EL3WINDOW(1);
return 0;
}
@@ -1264,8 +1143,8 @@ el3_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
static void el3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
}
static int el3_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -1379,30 +1258,30 @@ el3_up(struct net_device *dev)
EL3WINDOW(4);
net_diag = inw(ioaddr + WN4_NETDIAG);
net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
- printk("%s: ", dev->name);
+ pr_info("%s: ", dev->name);
switch (dev->if_port & 0x0c) {
case 12:
/* force full-duplex mode if 3c5x9b */
if (sw_info & 0x000f) {
- printk("Forcing 3c5x9b full-duplex mode");
+ pr_cont("Forcing 3c5x9b full-duplex mode");
break;
}
case 8:
/* set full-duplex mode based on eeprom config setting */
if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
- printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
+ pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
break;
}
default:
/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
- printk("Setting 3c5x9/3c5x9B half-duplex mode");
+ pr_cont("Setting 3c5x9/3c5x9B half-duplex mode");
net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
}
outw(net_diag, ioaddr + WN4_NETDIAG);
- printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
+ pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
if (el3_debug > 3)
- printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
+ pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
/* Enable link beat and jabber check. */
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
}
@@ -1446,7 +1325,7 @@ el3_suspend(struct device *pdev, pm_message_t state)
struct el3_private *lp;
int ioaddr;
- dev = pdev->driver_data;
+ dev = dev_get_drvdata(pdev);
lp = netdev_priv(dev);
ioaddr = dev->base_addr;
@@ -1470,13 +1349,14 @@ el3_resume(struct device *pdev)
struct el3_private *lp;
int ioaddr;
- dev = pdev->driver_data;
+ dev = dev_get_drvdata(pdev);
lp = netdev_priv(dev);
ioaddr = dev->base_addr;
spin_lock_irqsave(&lp->lock, flags);
outw(PowerUp, ioaddr + EL3_CMD);
+ EL3WINDOW(0);
el3_up(dev);
if (netif_running(dev))
@@ -1529,7 +1409,7 @@ static int __init el3_init_module(void)
}
if (id_port >= 0x200) {
id_port = 0;
- printk(KERN_ERR "No I/O port available for 3c509 activation.\n");
+ pr_err("No I/O port available for 3c509 activation.\n");
} else {
ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
if (!ret)
@@ -1540,11 +1420,6 @@ static int __init el3_init_module(void)
if (!ret)
eisa_registered = 1;
#endif
-#ifdef CONFIG_MCA
- ret = mca_register_driver(&el3_mca_driver);
- if (!ret)
- mca_registered = 1;
-#endif
#ifdef CONFIG_PNP
if (pnp_registered)
@@ -1556,10 +1431,6 @@ static int __init el3_init_module(void)
if (eisa_registered)
ret = 0;
#endif
-#ifdef CONFIG_MCA
- if (mca_registered)
- ret = 0;
-#endif
return ret;
}
@@ -1577,10 +1448,6 @@ static void __exit el3_cleanup_module(void)
if (eisa_registered)
eisa_driver_unregister(&el3_eisa_driver);
#endif
-#ifdef CONFIG_MCA
- if (mca_registered)
- mca_unregister_driver(&el3_mca_driver);
-#endif
}
module_init (el3_init_module);
diff --git a/drivers/net/3c515.c b/drivers/net/ethernet/3com/3c515.c
index e4e3241628d..94c656f5a05 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/ethernet/3com/3c515.c
@@ -18,7 +18,7 @@
2001/11/17 - Added ethtool support (jgarzik)
- 2002/10/28 - Locking updates for 2.5 (alan@redhat.com)
+ 2002/10/28 - Locking updates for 2.5 (alan@lxorguk.ukuu.org.uk)
*/
@@ -65,7 +65,6 @@ static int max_interrupt_work = 20;
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
@@ -99,7 +98,7 @@ static int rx_nocopy, rx_copy, queued_packet;
#define WAIT_TX_AVAIL 200
/* Operational parameter that usually are not changed. */
-#define TX_TIMEOUT 40 /* Time in jiffies before concluding Tx hung */
+#define TX_TIMEOUT ((4*HZ)/10) /* Time in jiffies before concluding Tx hung */
/* The size here is somewhat misleading: the Corkscrew also uses the ISA
aliased registers at <base>+0x400.
@@ -369,8 +368,8 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
struct pnp_dev *idev, int card_number);
static int corkscrew_open(struct net_device *dev);
static void corkscrew_timer(unsigned long arg);
-static int corkscrew_start_xmit(struct sk_buff *skb,
- struct net_device *dev);
+static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
static int corkscrew_rx(struct net_device *dev);
static void corkscrew_timeout(struct net_device *dev);
static int boomerang_rx(struct net_device *dev);
@@ -420,7 +419,7 @@ int init_module(void)
if (debug >= 0)
corkscrew_debug = debug;
if (corkscrew_debug)
- printk(version);
+ pr_debug("%s", version);
while (corkscrew_scan(-1))
found++;
return found ? 0 : -ENODEV;
@@ -437,7 +436,7 @@ struct net_device *tc515_probe(int unit)
if (corkscrew_debug > 0 && !printed) {
printed = 1;
- printk(version);
+ pr_debug("%s", version);
}
return dev;
@@ -516,7 +515,7 @@ static struct net_device *corkscrew_scan(int unit)
if (pnp_device_attach(idev) < 0)
continue;
if (pnp_activate_dev(idev) < 0) {
- printk("pnp activate failed (out of resources?)\n");
+ pr_warning("pnp activate failed (out of resources?)\n");
pnp_device_detach(idev);
continue;
}
@@ -531,9 +530,9 @@ static struct net_device *corkscrew_scan(int unit)
continue;
}
if(corkscrew_debug)
- printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
+ pr_debug("ISAPNP reports %s at i/o 0x%x, irq %d\n",
(char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
- printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+ pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
/* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
SET_NETDEV_DEV(dev, &idev->dev);
@@ -552,7 +551,7 @@ no_pnp:
if (!check_device(ioaddr))
continue;
- printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+ pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
if (!err)
@@ -563,6 +562,20 @@ no_pnp:
return NULL;
}
+
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = corkscrew_open,
+ .ndo_stop = corkscrew_close,
+ .ndo_start_xmit = corkscrew_start_xmit,
+ .ndo_tx_timeout = corkscrew_timeout,
+ .ndo_get_stats = corkscrew_get_stats,
+ .ndo_set_rx_mode = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+
static int corkscrew_setup(struct net_device *dev, int ioaddr,
struct pnp_dev *idev, int card_number)
{
@@ -570,7 +583,6 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */
int i;
int irq;
- DECLARE_MAC_BUF(mac);
#ifdef __ISAPNP__
if (idev) {
@@ -612,7 +624,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
list_add(&vp->list, &root_corkscrew_dev);
#endif
- printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
+ pr_info("%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
spin_lock_init(&vp->lock);
@@ -635,30 +647,32 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
}
checksum = (checksum ^ (checksum >> 8)) & 0xff;
if (checksum != 0x00)
- printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
- printk(" %s", print_mac(mac, dev->dev_addr));
+ pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
+ pr_cont(" %pM", dev->dev_addr);
if (eeprom[16] == 0x11c7) { /* Corkscrew */
if (request_dma(dev->dma, "3c515")) {
- printk(", DMA %d allocation failed", dev->dma);
+ pr_cont(", DMA %d allocation failed", dev->dma);
dev->dma = 0;
} else
- printk(", DMA %d", dev->dma);
+ pr_cont(", DMA %d", dev->dma);
}
- printk(", IRQ %d\n", dev->irq);
+ pr_cont(", IRQ %d\n", dev->irq);
/* Tell them about an invalid IRQ. */
if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
- printk(KERN_WARNING " *** Warning: this IRQ is unlikely to work! ***\n");
+ pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n");
{
- char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
+ static const char * const ram_split[] = {
+ "5:3", "3:1", "1:1", "3:5"
+ };
__u32 config;
EL3WINDOW(3);
vp->available_media = inw(ioaddr + Wn3_Options);
config = inl(ioaddr + Wn3_Config);
if (corkscrew_debug > 1)
- printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
+ pr_info(" Internal config register is %4.4x, transceivers %#x.\n",
config, inw(ioaddr + Wn3_Options));
- printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+ pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
8 << config & Ram_size,
config & Ram_width ? "word" : "byte",
ram_split[(config & Ram_split) >> Ram_split_shift],
@@ -669,7 +683,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
dev->if_port = vp->default_media;
}
if (vp->media_override != 7) {
- printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
+ pr_info(" Media override to transceiver type %d (%s).\n",
vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
@@ -682,13 +696,8 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
/* The 3c51x-specific entries in the device structure. */
- dev->open = &corkscrew_open;
- dev->hard_start_xmit = &corkscrew_start_xmit;
- dev->tx_timeout = &corkscrew_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = (400 * HZ) / 1000;
- dev->stop = &corkscrew_close;
- dev->get_stats = &corkscrew_get_stats;
- dev->set_multicast_list = &set_rx_mode;
dev->ethtool_ops = &netdev_ethtool_ops;
return register_netdev(dev);
@@ -710,7 +719,7 @@ static int corkscrew_open(struct net_device *dev)
if (vp->media_override != 7) {
if (corkscrew_debug > 1)
- printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
+ pr_info("%s: Media override to transceiver %d (%s).\n",
dev->name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
@@ -721,13 +730,13 @@ static int corkscrew_open(struct net_device *dev)
dev->if_port = media_tbl[dev->if_port].next;
if (corkscrew_debug > 1)
- printk("%s: Initial media type %s.\n",
+ pr_debug("%s: Initial media type %s.\n",
dev->name, media_tbl[dev->if_port].name);
init_timer(&vp->timer);
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
vp->timer.data = (unsigned long) dev;
- vp->timer.function = &corkscrew_timer; /* timer handler */
+ vp->timer.function = corkscrew_timer; /* timer handler */
add_timer(&vp->timer);
} else
dev->if_port = vp->default_media;
@@ -736,7 +745,7 @@ static int corkscrew_open(struct net_device *dev)
outl(config, ioaddr + Wn3_Config);
if (corkscrew_debug > 1) {
- printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
+ pr_debug("%s: corkscrew_open() InternalConfig %8.8x.\n",
dev->name, config);
}
@@ -756,20 +765,21 @@ static int corkscrew_open(struct net_device *dev)
/* Use the now-standard shared IRQ implementation. */
if (vp->capabilities == 0x11c7) {
/* Corkscrew: Cannot share ISA resources. */
- if (dev->irq == 0
- || dev->dma == 0
- || request_irq(dev->irq, &corkscrew_interrupt, 0,
- vp->product_name, dev)) return -EAGAIN;
+ if (dev->irq == 0 ||
+ dev->dma == 0 ||
+ request_irq(dev->irq, corkscrew_interrupt, 0,
+ vp->product_name, dev))
+ return -EAGAIN;
enable_dma(dev->dma);
set_dma_mode(dev->dma, DMA_MODE_CASCADE);
- } else if (request_irq(dev->irq, &corkscrew_interrupt, IRQF_SHARED,
+ } else if (request_irq(dev->irq, corkscrew_interrupt, IRQF_SHARED,
vp->product_name, dev)) {
return -EAGAIN;
}
if (corkscrew_debug > 1) {
EL3WINDOW(4);
- printk("%s: corkscrew_open() irq %d media status %4.4x.\n",
+ pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
dev->name, dev->irq, inw(ioaddr + Wn4_Media));
}
@@ -806,8 +816,7 @@ static int corkscrew_open(struct net_device *dev)
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
vp->cur_rx = vp->dirty_rx = 0;
if (corkscrew_debug > 2)
- printk("%s: Filling in the Rx ring.\n",
- dev->name);
+ pr_debug("%s: Filling in the Rx ring.\n", dev->name);
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
if (i < (RX_RING_SIZE - 1))
@@ -817,15 +826,16 @@ static int corkscrew_open(struct net_device *dev)
vp->rx_ring[i].next = 0;
vp->rx_ring[i].status = 0; /* Clear complete bit. */
vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;
- skb = dev_alloc_skb(PKT_BUF_SZ);
+ skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
vp->rx_skbuff[i] = skb;
if (skb == NULL)
break; /* Bad news! */
- skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
}
- vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */
+ if (i != 0)
+ vp->rx_ring[i - 1].next =
+ isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */
outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
}
if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */
@@ -869,7 +879,7 @@ static void corkscrew_timer(unsigned long data)
int ok = 0;
if (corkscrew_debug > 1)
- printk("%s: Media selection timer tick happened, %s.\n",
+ pr_debug("%s: Media selection timer tick happened, %s.\n",
dev->name, media_tbl[dev->if_port].name);
spin_lock_irqsave(&vp->lock, flags);
@@ -886,12 +896,12 @@ static void corkscrew_timer(unsigned long data)
if (media_status & Media_LnkBeat) {
ok = 1;
if (corkscrew_debug > 1)
- printk("%s: Media %s has link beat, %x.\n",
+ pr_debug("%s: Media %s has link beat, %x.\n",
dev->name,
media_tbl[dev->if_port].name,
media_status);
} else if (corkscrew_debug > 1)
- printk("%s: Media %s is has no link beat, %x.\n",
+ pr_debug("%s: Media %s is has no link beat, %x.\n",
dev->name,
media_tbl[dev->if_port].name,
media_status);
@@ -899,7 +909,7 @@ static void corkscrew_timer(unsigned long data)
break;
default: /* Other media types handled by Tx timeouts. */
if (corkscrew_debug > 1)
- printk("%s: Media %s is has no indication, %x.\n",
+ pr_debug("%s: Media %s is has no indication, %x.\n",
dev->name,
media_tbl[dev->if_port].name,
media_status);
@@ -917,12 +927,12 @@ static void corkscrew_timer(unsigned long data)
if (dev->if_port == 8) { /* Go back to default. */
dev->if_port = vp->default_media;
if (corkscrew_debug > 1)
- printk("%s: Media selection failing, using default %s port.\n",
+ pr_debug("%s: Media selection failing, using default %s port.\n",
dev->name,
media_tbl[dev->if_port].name);
} else {
if (corkscrew_debug > 1)
- printk("%s: Media selection failed, now trying %s port.\n",
+ pr_debug("%s: Media selection failed, now trying %s port.\n",
dev->name,
media_tbl[dev->if_port].name);
vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
@@ -945,11 +955,10 @@ static void corkscrew_timer(unsigned long data)
spin_unlock_irqrestore(&vp->lock, flags);
if (corkscrew_debug > 1)
- printk("%s: Media selection timer finished, %s.\n",
+ pr_debug("%s: Media selection timer finished, %s.\n",
dev->name, media_tbl[dev->if_port].name);
#endif /* AUTOMEDIA */
- return;
}
static void corkscrew_timeout(struct net_device *dev)
@@ -958,23 +967,21 @@ static void corkscrew_timeout(struct net_device *dev)
struct corkscrew_private *vp = netdev_priv(dev);
int ioaddr = dev->base_addr;
- printk(KERN_WARNING
- "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
+ pr_warning("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
dev->name, inb(ioaddr + TxStatus),
inw(ioaddr + EL3_STATUS));
/* Slight code bloat to be user friendly. */
if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
- printk(KERN_WARNING
- "%s: Transmitter encountered 16 collisions -- network"
+ pr_warning("%s: Transmitter encountered 16 collisions --"
" network cable problem?\n", dev->name);
#ifndef final_version
- printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
+ pr_debug(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
vp->cur_tx);
- printk(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
+ pr_debug(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
&vp->tx_ring[0]);
for (i = 0; i < TX_RING_SIZE; i++) {
- printk(" %d: %p length %8.8x status %8.8x\n", i,
+ pr_debug(" %d: %p length %8.8x status %8.8x\n", i,
&vp->tx_ring[i],
vp->tx_ring[i].length, vp->tx_ring[i].status);
}
@@ -985,14 +992,14 @@ static void corkscrew_timeout(struct net_device *dev)
if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
break;
outw(TxEnable, ioaddr + EL3_CMD);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
dev->stats.tx_errors++;
dev->stats.tx_dropped++;
netif_wake_queue(dev);
}
-static int corkscrew_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
+static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
struct corkscrew_private *vp = netdev_priv(dev);
int ioaddr = dev->base_addr;
@@ -1009,13 +1016,13 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
int i;
if (vp->tx_full) /* No room to transmit with */
- return 1;
+ return NETDEV_TX_BUSY;
if (vp->cur_tx != 0)
prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
else
prev_entry = NULL;
if (corkscrew_debug > 3)
- printk("%s: Trying to send a packet, Tx index %d.\n",
+ pr_debug("%s: Trying to send a packet, Tx index %d.\n",
dev->name, vp->cur_tx);
/* vp->tx_full = 1; */
vp->tx_skbuff[entry] = skb;
@@ -1048,8 +1055,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
prev_entry->status &= ~0x80000000;
netif_wake_queue(dev);
}
- dev->trans_start = jiffies;
- return 0;
+ return NETDEV_TX_OK;
}
/* Put out the doubleword header... */
outl(skb->len, ioaddr + TX_FIFO);
@@ -1084,7 +1090,6 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
#endif /* bus master */
- dev->trans_start = jiffies;
/* Clear the Tx status stack. */
{
@@ -1094,7 +1099,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
if (corkscrew_debug > 2)
- printk("%s: Tx error, status %2.2x.\n",
+ pr_debug("%s: Tx error, status %2.2x.\n",
dev->name, tx_status);
if (tx_status & 0x04)
dev->stats.tx_fifo_errors++;
@@ -1112,7 +1117,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
}
}
- return 0;
+ return NETDEV_TX_OK;
}
/* The interrupt handler does all of the Rx thread work and cleans up
@@ -1135,7 +1140,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
status = inw(ioaddr + EL3_STATUS);
if (corkscrew_debug > 4)
- printk("%s: interrupt, status %4.4x, timer %d.\n",
+ pr_debug("%s: interrupt, status %4.4x, timer %d.\n",
dev->name, status, latency);
if ((status & 0xE000) != 0xE000) {
static int donedidthis;
@@ -1143,7 +1148,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
Ignore a single early interrupt, but don't hang the machine for
other interrupt problems. */
if (donedidthis++ > 100) {
- printk(KERN_ERR "%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
+ pr_err("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
dev->name, status, netif_running(dev));
free_irq(dev->irq, dev);
dev->irq = -1;
@@ -1152,14 +1157,14 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
do {
if (corkscrew_debug > 5)
- printk("%s: In interrupt loop, status %4.4x.\n",
+ pr_debug("%s: In interrupt loop, status %4.4x.\n",
dev->name, status);
if (status & RxComplete)
corkscrew_rx(dev);
if (status & TxAvailable) {
if (corkscrew_debug > 5)
- printk(" TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue(dev);
@@ -1204,19 +1209,20 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
if (status & StatsFull) { /* Empty statistics. */
static int DoneDidThat;
if (corkscrew_debug > 4)
- printk("%s: Updating stats.\n", dev->name);
+ pr_debug("%s: Updating stats.\n", dev->name);
update_stats(ioaddr, dev);
/* DEBUG HACK: Disable statistics as an interrupt source. */
/* This occurs when we have the wrong media type! */
if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
int win, reg;
- printk("%s: Updating stats failed, disabling stats as an"
- " interrupt source.\n", dev->name);
+ pr_notice("%s: Updating stats failed, disabling stats as an interrupt source.\n",
+ dev->name);
for (win = 0; win < 8; win++) {
EL3WINDOW(win);
- printk("\n Vortex window %d:", win);
+ pr_notice("Vortex window %d:", win);
for (reg = 0; reg < 16; reg++)
- printk(" %2.2x", inb(ioaddr + reg));
+ pr_cont(" %2.2x", inb(ioaddr + reg));
+ pr_cont("\n");
}
EL3WINDOW(7);
outw(SetIntrEnb | TxAvailable |
@@ -1238,9 +1244,8 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
}
if (--i < 0) {
- printk(KERN_ERR "%s: Too much work in interrupt, status %4.4x. "
- "Disabling functions (%4.4x).\n", dev->name,
- status, SetStatusEnb | ((~status) & 0x7FE));
+ pr_err("%s: Too much work in interrupt, status %4.4x. Disabling functions (%4.4x).\n",
+ dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
/* Disable all pending interrupts. */
outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
@@ -1254,7 +1259,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
spin_unlock(&lp->lock);
if (corkscrew_debug > 4)
- printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
+ pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
return IRQ_HANDLED;
}
@@ -1265,13 +1270,13 @@ static int corkscrew_rx(struct net_device *dev)
short rx_status;
if (corkscrew_debug > 5)
- printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
if (rx_status & 0x4000) { /* Error, update stats. */
unsigned char rx_error = inb(ioaddr + RxErrors);
if (corkscrew_debug > 2)
- printk(" Rx error: status %2.2x.\n",
+ pr_debug(" Rx error: status %2.2x.\n",
rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01)
@@ -1289,9 +1294,9 @@ static int corkscrew_rx(struct net_device *dev)
short pkt_len = rx_status & 0x1fff;
struct sk_buff *skb;
- skb = dev_alloc_skb(pkt_len + 5 + 2);
+ skb = netdev_alloc_skb(dev, pkt_len + 5 + 2);
if (corkscrew_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
@@ -1302,7 +1307,6 @@ static int corkscrew_rx(struct net_device *dev)
outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
/* Wait a limited time to go to next packet. */
@@ -1311,7 +1315,7 @@ static int corkscrew_rx(struct net_device *dev)
break;
continue;
} else if (corkscrew_debug)
- printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
+ pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
}
outw(RxDiscard, ioaddr + EL3_CMD);
dev->stats.rx_dropped++;
@@ -1331,13 +1335,13 @@ static int boomerang_rx(struct net_device *dev)
int rx_status;
if (corkscrew_debug > 5)
- printk(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
if (rx_status & RxDError) { /* Error, update stats. */
unsigned char rx_error = rx_status >> 16;
if (corkscrew_debug > 2)
- printk(" Rx error: status %2.2x.\n",
+ pr_debug(" Rx error: status %2.2x.\n",
rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01)
@@ -1357,13 +1361,13 @@ static int boomerang_rx(struct net_device *dev)
dev->stats.rx_bytes += pkt_len;
if (corkscrew_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
/* Check if the packet is long enough to just accept without
copying to a properly sized skbuff. */
- if (pkt_len < rx_copybreak
- && (skb = dev_alloc_skb(pkt_len + 4)) != NULL) {
+ if (pkt_len < rx_copybreak &&
+ (skb = netdev_alloc_skb(dev, pkt_len + 4)) != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
/* 'skb_put()' points to the start of sk_buff data area. */
memcpy(skb_put(skb, pkt_len),
@@ -1378,7 +1382,7 @@ static int boomerang_rx(struct net_device *dev)
temp = skb_put(skb, pkt_len);
/* Remove this checking code for final release. */
if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
- printk("%s: Warning -- the skbuff addresses do not match"
+ pr_warning("%s: Warning -- the skbuff addresses do not match"
" in boomerang_rx: %p vs. %p / %p.\n",
dev->name,
isa_bus_to_virt(vp->
@@ -1389,7 +1393,6 @@ static int boomerang_rx(struct net_device *dev)
}
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
}
entry = (++vp->cur_rx) % RX_RING_SIZE;
@@ -1399,10 +1402,9 @@ static int boomerang_rx(struct net_device *dev)
struct sk_buff *skb;
entry = vp->dirty_rx % RX_RING_SIZE;
if (vp->rx_skbuff[entry] == NULL) {
- skb = dev_alloc_skb(PKT_BUF_SZ);
+ skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
if (skb == NULL)
break; /* Bad news! */
- skb->dev = dev; /* Mark as being used by this device. */
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
vp->rx_skbuff[entry] = skb;
@@ -1421,12 +1423,11 @@ static int corkscrew_close(struct net_device *dev)
netif_stop_queue(dev);
if (corkscrew_debug > 1) {
- printk("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
+ pr_debug("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
dev->name, inw(ioaddr + EL3_STATUS),
inb(ioaddr + TxStatus));
- printk("%s: corkscrew close stats: rx_nocopy %d rx_copy %d"
- " tx_queued %d.\n", dev->name, rx_nocopy, rx_copy,
- queued_packet);
+ pr_debug("%s: corkscrew close stats: rx_nocopy %d rx_copy %d tx_queued %d.\n",
+ dev->name, rx_nocopy, rx_copy, queued_packet);
}
del_timer(&vp->timer);
@@ -1514,7 +1515,6 @@ static void update_stats(int ioaddr, struct net_device *dev)
/* We change back to window 7 (not 1) with the Vortex. */
EL3WINDOW(7);
- return;
}
/* This new version of set_rx_mode() supports v1.4 kernels.
@@ -1528,10 +1528,10 @@ static void set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC) {
if (corkscrew_debug > 3)
- printk("%s: Setting promiscuous mode.\n",
+ pr_debug("%s: Setting promiscuous mode.\n",
dev->name);
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
- } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
+ } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast;
} else
new_mode = SetRxFilter | RxStation | RxBroadcast;
@@ -1542,9 +1542,10 @@ static void set_rx_mode(struct net_device *dev)
static void netdev_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx",
+ dev->base_addr);
}
static u32 netdev_get_msglevel(struct net_device *dev)
@@ -1580,11 +1581,3 @@ void cleanup_module(void)
}
}
#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c515.c"
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c
index 7112fd5e0e1..b9948f00c5e 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/ethernet/3com/3c574_cs.c
@@ -62,16 +62,17 @@ invalid ramWidth is Very Bad.
V. References
http://www.scyld.com/expert/NWay.html
-http://www.national.com/pf/DP/DP83840.html
+http://www.national.com/opf/DP/DP83840A.html
Thanks to Terry Murphy of 3Com for providing development information for
earlier 3Com products.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -83,20 +84,16 @@ earlier 3Com products.
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>
-#include <linux/ethtool.h>
#include <linux/bitops.h>
+#include <linux/mii.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
-#include <pcmcia/mem_op.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <asm/system.h>
/*====================================================================*/
@@ -117,14 +114,6 @@ INT_MODULE_PARM(full_duplex, 0);
/* Autodetect link polarity reversal? */
INT_MODULE_PARM(auto_polarity, 1);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"3c574_cs.c 1.65ac1 2003/04/07 Donald Becker/David Hinds, becker@scyld.com.\n";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -207,7 +196,6 @@ enum Window4 { /* Window 4: Xcvr/media bits. */
struct el3_private {
struct pcmcia_device *p_dev;
- dev_node_t node;
u16 advertising, partner; /* NWay media advertisement */
unsigned char phys; /* MII device address */
unsigned int autoselect:1, default_media:3; /* Read from the EEPROM/Wn3_Config. */
@@ -239,7 +227,8 @@ static void tc574_wait_for_completion(struct net_device *dev, int cmd);
static void tc574_reset(struct net_device *dev);
static void media_check(unsigned long arg);
static int el3_open(struct net_device *dev);
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
static irqreturn_t el3_interrupt(int irq, void *dev_id);
static void update_stats(struct net_device *dev);
static struct net_device_stats *el3_get_stats(struct net_device *dev);
@@ -247,8 +236,8 @@ static int el3_rx(struct net_device *dev, int worklimit);
static int el3_close(struct net_device *dev);
static void el3_tx_timeout(struct net_device *dev);
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
static void set_rx_mode(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
static void tc574_detach(struct pcmcia_device *p_dev);
@@ -257,13 +246,25 @@ static void tc574_detach(struct pcmcia_device *p_dev);
local data structures for one device. The device is registered
with Card Services.
*/
+static const struct net_device_ops el3_netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_do_ioctl = el3_ioctl,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int tc574_probe(struct pcmcia_device *link)
{
struct el3_private *lp;
struct net_device *dev;
- DEBUG(0, "3c574_attach()\n");
+ dev_dbg(&link->dev, "3c574_attach()\n");
/* Create the PC card device object. */
dev = alloc_etherdev(sizeof(struct el3_private));
@@ -274,120 +275,89 @@ static int tc574_probe(struct pcmcia_device *link)
lp->p_dev = link;
spin_lock_init(&lp->window_lock);
- link->io.NumPorts1 = 32;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = &el3_interrupt;
- link->irq.Instance = dev;
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.IntType = INT_MEMORY_AND_IO;
- link->conf.ConfigIndex = 1;
-
- /* The EL3-specific entries in the device structure. */
- dev->hard_start_xmit = &el3_start_xmit;
- dev->get_stats = &el3_get_stats;
- dev->do_ioctl = &el3_ioctl;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->set_multicast_list = &set_rx_mode;
- dev->open = &el3_open;
- dev->stop = &el3_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = el3_tx_timeout;
+ link->resource[0]->end = 32;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
+ link->config_flags |= CONF_ENABLE_IRQ;
+ link->config_index = 1;
+
+ dev->netdev_ops = &el3_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
return tc574_config(link);
-} /* tc574_attach */
-
-/*
-
- This deletes a driver "instance". The device is de-registered
- with Card Services. If it has been released, all local data
- structures are freed. Otherwise, the structures will be freed
- when the device is released.
-
-*/
+}
static void tc574_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "3c574_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "3c574_detach()\n");
- if (link->dev_node)
- unregister_netdev(dev);
+ unregister_netdev(dev);
tc574_release(link);
free_netdev(dev);
} /* tc574_detach */
-/*
- tc574_config() is scheduled to run after a CARD_INSERTION event
- is received, to configure the PCMCIA socket, and to make the
- ethernet device available to the system.
-*/
-
-#define CS_CHECK(fn, ret) \
- do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
static int tc574_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
- tuple_t tuple;
- __le16 buf[32];
- int last_fn, last_ret, i, j;
+ int ret, i, j;
unsigned int ioaddr;
__be16 *phys_addr;
char *cardname;
__u32 config;
- DECLARE_MAC_BUF(mac);
+ u8 *buf;
+ size_t len;
phys_addr = (__be16 *)dev->dev_addr;
- DEBUG(0, "3c574_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "3c574_config()\n");
+
+ link->io_lines = 16;
- link->io.IOAddrLines = 16;
for (i = j = 0; j < 0x400; j += 0x20) {
- link->io.BasePort1 = j ^ 0x300;
- i = pcmcia_request_io(link, &link->io);
- if (i == CS_SUCCESS) break;
+ link->resource[0]->start = j ^ 0x300;
+ i = pcmcia_request_io(link);
+ if (i == 0)
+ break;
}
- if (i != CS_SUCCESS) {
- cs_error(link, RequestIO, i);
+ if (i != 0)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
- dev->irq = link->irq.AssignedIRQ;
- dev->base_addr = link->io.BasePort1;
+ ret = pcmcia_request_irq(link, el3_interrupt);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_enable_device(link);
+ if (ret)
+ goto failed;
+
+ dev->irq = link->irq;
+ dev->base_addr = link->resource[0]->start;
ioaddr = dev->base_addr;
/* The 3c574 normally uses an EEPROM for configuration info, including
the hardware address. The future products may include a modem chip
and put the address in the CIS. */
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = 0x88;
- if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) {
- pcmcia_get_tuple_data(link, &tuple);
+
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
for (i = 0; i < 3; i++)
- phys_addr[i] = htons(le16_to_cpu(buf[i]));
+ phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
+ kfree(buf);
} else {
+ kfree(buf); /* 0 < len < 6 */
EL3WINDOW(0);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
if (phys_addr[0] == htons(0x6060)) {
- printk(KERN_NOTICE "3c574_cs: IO port conflict at 0x%03lx"
- "-0x%03lx\n", dev->base_addr, dev->base_addr+15);
+ pr_notice("IO port conflict at 0x%03lx-0x%03lx\n",
+ dev->base_addr, dev->base_addr+15);
goto failed;
}
}
@@ -401,7 +371,7 @@ static int tc574_config(struct pcmcia_device *link)
outw(2<<11, ioaddr + RunnerRdCtrl);
mcr = inb(ioaddr + 2);
outw(0<<11, ioaddr + RunnerRdCtrl);
- printk(KERN_INFO " ASIC rev %d,", mcr>>3);
+ pr_info(" ASIC rev %d,", mcr>>3);
EL3WINDOW(3);
config = inl(ioaddr + Wn3_Config);
lp->default_media = (config & Xcvr) >> Xcvr_shift;
@@ -429,7 +399,8 @@ static int tc574_config(struct pcmcia_device *link)
mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
if (mii_status != 0xffff) {
lp->phys = phy & 0x1f;
- DEBUG(0, " MII transceiver at index %d, status %x.\n",
+ dev_dbg(&link->dev, " MII transceiver at "
+ "index %d, status %x.\n",
phy, mii_status);
if ((mii_status & 0x0040) == 0)
mii_preamble_required = 1;
@@ -437,7 +408,7 @@ static int tc574_config(struct pcmcia_device *link)
}
}
if (phy > 32) {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ pr_notice(" No MII transceivers found!\n");
goto failed;
}
i = mdio_read(ioaddr, lp->phys, 16) | 0x40;
@@ -450,42 +421,28 @@ static int tc574_config(struct pcmcia_device *link)
}
}
- link->dev_node = &lp->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
- link->dev_node = NULL;
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- strcpy(lp->node.dev_name, dev->name);
-
- printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
- "hw_addr %s.\n",
- dev->name, cardname, dev->base_addr, dev->irq,
- print_mac(mac, dev->dev_addr));
- printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
- 8 << config & Ram_size,
- ram_split[(config & Ram_split) >> Ram_split_shift],
- config & Autoselect ? "autoselect " : "");
+ netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n",
+ cardname, dev->base_addr, dev->irq, dev->dev_addr);
+ netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n",
+ 8 << (config & Ram_size),
+ ram_split[(config & Ram_split) >> Ram_split_shift],
+ config & Autoselect ? "autoselect " : "");
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
tc574_release(link);
return -ENODEV;
} /* tc574_config */
-/*
- After a card is removed, tc574_release() will unregister the net
- device, and release the PCMCIA configuration. If the device is
- still open, this will be postponed until it is closed.
-*/
-
static void tc574_release(struct pcmcia_device *link)
{
pcmcia_disable_device(link);
@@ -517,14 +474,14 @@ static void dump_status(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
EL3WINDOW(1);
- printk(KERN_INFO " irq status %04x, rx status %04x, tx status "
- "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS),
- inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
- inw(ioaddr+TxFree));
+ netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x, tx free %04x\n",
+ inw(ioaddr+EL3_STATUS),
+ inw(ioaddr+RxStatus), inb(ioaddr+TxStatus),
+ inw(ioaddr+TxFree));
EL3WINDOW(4);
- printk(KERN_INFO " diagnostics: fifo %04x net %04x ethernet %04x"
- " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06),
- inw(ioaddr+0x08), inw(ioaddr+0x0a));
+ netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n",
+ inw(ioaddr+0x04), inw(ioaddr+0x06),
+ inw(ioaddr+0x08), inw(ioaddr+0x0a));
EL3WINDOW(1);
}
@@ -538,7 +495,7 @@ static void tc574_wait_for_completion(struct net_device *dev, int cmd)
while (--i > 0)
if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break;
if (i == 0)
- printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", dev->name, cmd);
+ netdev_notice(dev, "command 0x%04x did not complete!\n", cmd);
}
/* Read a word from the EEPROM using the regular EEPROM access register.
@@ -628,8 +585,6 @@ static void mdio_write(unsigned int ioaddr, int phy_id, int location, int value)
outw(MDIO_ENB_IN, mdio_addr);
outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
}
-
- return;
}
/* Reset and restore all of the 3c574 registers. */
@@ -727,12 +682,12 @@ static int el3_open(struct net_device *dev)
netif_start_queue(dev);
tc574_reset(dev);
- lp->media.function = &media_check;
+ lp->media.function = media_check;
lp->media.data = (unsigned long) dev;
lp->media.expires = jiffies + HZ;
add_timer(&lp->media);
- DEBUG(2, "%s: opened, status %4.4x.\n",
+ dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
dev->name, inw(dev->base_addr + EL3_STATUS));
return 0;
@@ -742,10 +697,10 @@ static void el3_tx_timeout(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
- printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
+ netdev_notice(dev, "Transmit timed out!\n");
dump_status(dev);
dev->stats.tx_errors++;
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
/* Issue TX_RESET and TX_START commands. */
tc574_wait_for_completion(dev, TxReset);
outw(TxEnable, ioaddr + EL3_CMD);
@@ -766,7 +721,7 @@ static void pop_tx_status(struct net_device *dev)
if (tx_status & 0x30)
tc574_wait_for_completion(dev, TxReset);
if (tx_status & 0x38) {
- DEBUG(1, "%s: transmit error: status 0x%02x\n",
+ pr_debug("%s: transmit error: status 0x%02x\n",
dev->name, tx_status);
outw(TxEnable, ioaddr + EL3_CMD);
dev->stats.tx_aborted_errors++;
@@ -775,23 +730,27 @@ static void pop_tx_status(struct net_device *dev)
}
}
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
struct el3_private *lp = netdev_priv(dev);
unsigned long flags;
- DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
+ pr_debug("%s: el3_start_xmit(length = %ld) called, "
"status %4.4x.\n", dev->name, (long)skb->len,
inw(ioaddr + EL3_STATUS));
spin_lock_irqsave(&lp->window_lock, flags);
+
+ dev->stats.tx_bytes += skb->len;
+
+ /* Put out the doubleword header... */
outw(skb->len, ioaddr + TX_FIFO);
outw(0, ioaddr + TX_FIFO);
+ /* ... and the packet rounded to a doubleword. */
outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
- dev->trans_start = jiffies;
-
/* TxFree appears only in Window 1, not offset 0x1c. */
if (inw(ioaddr + TxFree) <= 1536) {
netif_stop_queue(dev);
@@ -803,7 +762,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
pop_tx_status(dev);
spin_unlock_irqrestore(&lp->window_lock, flags);
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
/* The EL3 interrupt handler. */
@@ -820,7 +779,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
return IRQ_NONE;
ioaddr = dev->base_addr;
- DEBUG(3, "%s: interrupt, status %4.4x.\n",
+ pr_debug("%s: interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
spin_lock(&lp->window_lock);
@@ -829,7 +788,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
(IntLatch | RxComplete | RxEarly | StatsFull)) {
if (!netif_device_present(dev) ||
((status & 0xe000) != 0x2000)) {
- DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
+ pr_debug("%s: Interrupt from dead card\n", dev->name);
break;
}
@@ -839,7 +798,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
work_budget = el3_rx(dev, work_budget);
if (status & TxAvailable) {
- DEBUG(3, " TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue(dev);
@@ -861,8 +820,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
EL3WINDOW(4);
fifo_diag = inw(ioaddr + Wn4_FIFODiag);
EL3WINDOW(1);
- printk(KERN_NOTICE "%s: adapter failure, FIFO diagnostic"
- " register %04x.\n", dev->name, fifo_diag);
+ netdev_notice(dev, "adapter failure, FIFO diagnostic register %04x\n",
+ fifo_diag);
if (fifo_diag & 0x0400) {
/* Tx overrun */
tc574_wait_for_completion(dev, TxReset);
@@ -879,7 +838,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
}
if (--work_budget < 0) {
- DEBUG(0, "%s: Too much work in interrupt, "
+ pr_debug("%s: Too much work in interrupt, "
"status %4.4x.\n", dev->name, status);
/* Clear all interrupts */
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -889,7 +848,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
}
- DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
+ pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, inw(ioaddr + EL3_STATUS));
spin_unlock(&lp->window_lock);
@@ -916,8 +875,12 @@ static void media_check(unsigned long arg)
this, we can limp along even if the interrupt is blocked */
if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
if (!lp->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
+
+ local_irq_save(flags);
el3_interrupt(dev->irq, dev);
+ local_irq_restore(flags);
+
lp->fast_poll = HZ;
}
if (lp->fast_poll) {
@@ -935,23 +898,21 @@ static void media_check(unsigned long arg)
if (media != lp->media_status) {
if ((media ^ lp->media_status) & 0x0004)
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (lp->media_status & 0x0004) ? "lost" : "found");
+ netdev_info(dev, "%s link beat\n",
+ (lp->media_status & 0x0004) ? "lost" : "found");
if ((media ^ lp->media_status) & 0x0020) {
lp->partner = 0;
if (lp->media_status & 0x0020) {
- printk(KERN_INFO "%s: autonegotiation restarted\n",
- dev->name);
+ netdev_info(dev, "autonegotiation restarted\n");
} else if (partner) {
partner &= lp->advertising;
lp->partner = partner;
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((partner & 0x0180) ? "100" : "10"),
- ((partner & 0x0140) ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: "
+ "%dbaseT-%cD selected\n",
+ (partner & 0x0180) ? 100 : 10,
+ (partner & 0x0140) ? 'F' : 'H');
} else {
- printk(KERN_INFO "%s: link partner did not autonegotiate\n",
- dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
}
EL3WINDOW(3);
@@ -961,10 +922,9 @@ static void media_check(unsigned long arg)
}
if (media & 0x0010)
- printk(KERN_INFO "%s: remote fault detected\n",
- dev->name);
+ netdev_info(dev, "remote fault detected\n");
if (media & 0x0002)
- printk(KERN_INFO "%s: jabber detected\n", dev->name);
+ netdev_info(dev, "jabber detected\n");
lp->media_status = media;
}
spin_unlock_irqrestore(&lp->window_lock, flags);
@@ -988,7 +948,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev)
}
/* Update statistics.
- Suprisingly this need not be run single-threaded, but it effectively is.
+ Surprisingly this need not be run single-threaded, but it effectively is.
The counters clear when read, so the adds must merely be atomic.
*/
static void update_stats(struct net_device *dev)
@@ -996,7 +956,7 @@ static void update_stats(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
u8 rx, tx, up;
- DEBUG(2, "%s: updating the statistics.\n", dev->name);
+ pr_debug("%s: updating the statistics.\n", dev->name);
if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
return;
@@ -1022,8 +982,6 @@ static void update_stats(struct net_device *dev)
/* BadSSD */ inb(ioaddr + 12);
up = inb(ioaddr + 13);
- dev->stats.tx_bytes += tx + ((up & 0xf0) << 12);
-
EL3WINDOW(1);
}
@@ -1032,10 +990,11 @@ static int el3_rx(struct net_device *dev, int worklimit)
unsigned int ioaddr = dev->base_addr;
short rx_status;
- DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
- (--worklimit >= 0)) {
+ worklimit > 0) {
+ worklimit--;
if (rx_status & 0x4000) { /* Error, update stats. */
short error = rx_status & 0x3800;
dev->stats.rx_errors++;
@@ -1051,9 +1010,9 @@ static int el3_rx(struct net_device *dev, int worklimit)
short pkt_len = rx_status & 0x7ff;
struct sk_buff *skb;
- skb = dev_alloc_skb(pkt_len+5);
+ skb = netdev_alloc_skb(dev, pkt_len + 5);
- DEBUG(3, " Receiving packet size %d status %4.4x.\n",
+ pr_debug(" Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2);
@@ -1061,11 +1020,10 @@ static int el3_rx(struct net_device *dev, int worklimit)
((pkt_len+3)>>2));
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
} else {
- DEBUG(1, "%s: couldn't allocate a sk_buff of"
+ pr_debug("%s: couldn't allocate a sk_buff of"
" size %d.\n", dev->name, pkt_len);
dev->stats.rx_dropped++;
}
@@ -1076,31 +1034,21 @@ static int el3_rx(struct net_device *dev, int worklimit)
return worklimit;
}
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "3c574_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/* Provide ioctl() calls to examine the MII xcvr state. */
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct el3_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
- u16 *data = (u16 *)&rq->ifr_ifru;
+ struct mii_ioctl_data *data = if_mii(rq);
int phy = lp->phys & 0x1f;
- DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
+ pr_debug("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
- data[0], data[1], data[2], data[3]);
+ data->phy_id, data->reg_num, data->val_in, data->val_out);
switch(cmd) {
case SIOCGMIIPHY: /* Get the address of the PHY in use. */
- data[0] = phy;
+ data->phy_id = phy;
case SIOCGMIIREG: /* Read the specified MII register. */
{
int saved_window;
@@ -1109,7 +1057,8 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
spin_lock_irqsave(&lp->window_lock, flags);
saved_window = inw(ioaddr + EL3_CMD) >> 13;
EL3WINDOW(4);
- data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
+ data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f,
+ data->reg_num & 0x1f);
EL3WINDOW(saved_window);
spin_unlock_irqrestore(&lp->window_lock, flags);
return 0;
@@ -1119,12 +1068,11 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
int saved_window;
unsigned long flags;
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
spin_lock_irqsave(&lp->window_lock, flags);
saved_window = inw(ioaddr + EL3_CMD) >> 13;
EL3WINDOW(4);
- mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+ mdio_write(ioaddr, data->phy_id & 0x1f,
+ data->reg_num & 0x1f, data->val_in);
EL3WINDOW(saved_window);
spin_unlock_irqrestore(&lp->window_lock, flags);
return 0;
@@ -1149,19 +1097,29 @@ static void set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC)
outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
ioaddr + EL3_CMD);
- else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
+ else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI))
outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
else
outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
}
+static void set_multicast_list(struct net_device *dev)
+{
+ struct el3_private *lp = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->window_lock, flags);
+ set_rx_mode(dev);
+ spin_unlock_irqrestore(&lp->window_lock, flags);
+}
+
static int el3_close(struct net_device *dev)
{
unsigned int ioaddr = dev->base_addr;
struct el3_private *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+ dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
if (pcmcia_dev_present(link)) {
unsigned long flags;
@@ -1190,34 +1148,20 @@ static int el3_close(struct net_device *dev)
return 0;
}
-static struct pcmcia_device_id tc574_ids[] = {
+static const struct pcmcia_device_id tc574_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0574),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "3CCFEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, tc574_ids);
static struct pcmcia_driver tc574_driver = {
.owner = THIS_MODULE,
- .drv = {
- .name = "3c574_cs",
- },
+ .name = "3c574_cs",
.probe = tc574_probe,
.remove = tc574_detach,
.id_table = tc574_ids,
.suspend = tc574_suspend,
.resume = tc574_resume,
};
-
-static int __init init_tc574(void)
-{
- return pcmcia_register_driver(&tc574_driver);
-}
-
-static void __exit exit_tc574(void)
-{
- pcmcia_unregister_driver(&tc574_driver);
-}
-
-module_init(init_tc574);
-module_exit(exit_tc574);
+module_pcmcia_driver(tc574_driver);
diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c
new file mode 100644
index 00000000000..f18647c2355
--- /dev/null
+++ b/drivers/net/ethernet/3com/3c589_cs.c
@@ -0,0 +1,971 @@
+/* ======================================================================
+ *
+ * A PCMCIA ethernet driver for the 3com 3c589 card.
+ *
+ * Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
+ *
+ * 3c589_cs.c 1.162 2001/10/13 00:08:50
+ *
+ * The network driver code is based on Donald Becker's 3c589 code:
+ *
+ * Written 1994 by Donald Becker.
+ * Copyright 1993 United States Government as represented by the
+ * Director, National Security Agency. This software may be used and
+ * distributed according to the terms of the GNU General Public License,
+ * incorporated herein by reference.
+ * Donald Becker may be reached at becker@scyld.com
+ *
+ * Updated for 2.5.x by Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * ======================================================================
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#define DRV_NAME "3c589_cs"
+#define DRV_VERSION "1.162-ac"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/bitops.h>
+#include <linux/jiffies.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+
+
+/* To minimize the size of the driver source I only define operating
+ * constants if they are used several times. You'll need the manual
+ * if you want to understand driver details.
+ */
+
+/* Offsets from base I/O address. */
+#define EL3_DATA 0x00
+#define EL3_TIMER 0x0a
+#define EL3_CMD 0x0e
+#define EL3_STATUS 0x0e
+
+#define EEPROM_READ 0x0080
+#define EEPROM_BUSY 0x8000
+
+#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
+
+/* The top five bits written to EL3_CMD are a command, the lower
+ * 11 bits are the parameter, if applicable.
+ */
+
+enum c509cmd {
+ TotalReset = 0<<11,
+ SelectWindow = 1<<11,
+ StartCoax = 2<<11,
+ RxDisable = 3<<11,
+ RxEnable = 4<<11,
+ RxReset = 5<<11,
+ RxDiscard = 8<<11,
+ TxEnable = 9<<11,
+ TxDisable = 10<<11,
+ TxReset = 11<<11,
+ FakeIntr = 12<<11,
+ AckIntr = 13<<11,
+ SetIntrEnb = 14<<11,
+ SetStatusEnb = 15<<11,
+ SetRxFilter = 16<<11,
+ SetRxThreshold = 17<<11,
+ SetTxThreshold = 18<<11,
+ SetTxStart = 19<<11,
+ StatsEnable = 21<<11,
+ StatsDisable = 22<<11,
+ StopCoax = 23<<11
+};
+
+enum c509status {
+ IntLatch = 0x0001,
+ AdapterFailure = 0x0002,
+ TxComplete = 0x0004,
+ TxAvailable = 0x0008,
+ RxComplete = 0x0010,
+ RxEarly = 0x0020,
+ IntReq = 0x0040,
+ StatsFull = 0x0080,
+ CmdBusy = 0x1000
+};
+
+/* The SetRxFilter command accepts the following classes: */
+enum RxFilter {
+ RxStation = 1,
+ RxMulticast = 2,
+ RxBroadcast = 4,
+ RxProm = 8
+};
+
+/* Register window 1 offsets, the window used in normal operation. */
+#define TX_FIFO 0x00
+#define RX_FIFO 0x00
+#define RX_STATUS 0x08
+#define TX_STATUS 0x0B
+#define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */
+
+#define WN0_IRQ 0x08 /* Window 0: Set IRQ line in bits 12-15. */
+#define WN4_MEDIA 0x0A /* Window 4: Various transcvr/media bits. */
+#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
+#define MEDIA_LED 0x0001 /* Enable link light on 3C589E cards. */
+
+/* Time in jiffies before concluding Tx hung */
+#define TX_TIMEOUT ((400*HZ)/1000)
+
+struct el3_private {
+ struct pcmcia_device *p_dev;
+ /* For transceiver monitoring */
+ struct timer_list media;
+ u16 media_status;
+ u16 fast_poll;
+ unsigned long last_irq;
+ spinlock_t lock;
+};
+
+static const char *if_names[] = { "auto", "10baseT", "10base2", "AUI" };
+
+/*====================================================================*/
+
+/* Module parameters */
+
+MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
+MODULE_DESCRIPTION("3Com 3c589 series PCMCIA ethernet driver");
+MODULE_LICENSE("GPL");
+
+#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
+
+/* Special hook for setting if_port when module is loaded */
+INT_MODULE_PARM(if_port, 0);
+
+
+/*====================================================================*/
+
+static int tc589_config(struct pcmcia_device *link);
+static void tc589_release(struct pcmcia_device *link);
+
+static u16 read_eeprom(unsigned int ioaddr, int index);
+static void tc589_reset(struct net_device *dev);
+static void media_check(unsigned long arg);
+static int el3_config(struct net_device *dev, struct ifmap *map);
+static int el3_open(struct net_device *dev);
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+static irqreturn_t el3_interrupt(int irq, void *dev_id);
+static void update_stats(struct net_device *dev);
+static struct net_device_stats *el3_get_stats(struct net_device *dev);
+static int el3_rx(struct net_device *dev);
+static int el3_close(struct net_device *dev);
+static void el3_tx_timeout(struct net_device *dev);
+static void set_rx_mode(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static const struct ethtool_ops netdev_ethtool_ops;
+
+static void tc589_detach(struct pcmcia_device *p_dev);
+
+static const struct net_device_ops el3_netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_set_config = el3_config,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static int tc589_probe(struct pcmcia_device *link)
+{
+ struct el3_private *lp;
+ struct net_device *dev;
+
+ dev_dbg(&link->dev, "3c589_attach()\n");
+
+ /* Create new ethernet device */
+ dev = alloc_etherdev(sizeof(struct el3_private));
+ if (!dev)
+ return -ENOMEM;
+ lp = netdev_priv(dev);
+ link->priv = dev;
+ lp->p_dev = link;
+
+ spin_lock_init(&lp->lock);
+ link->resource[0]->end = 16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
+
+ link->config_flags |= CONF_ENABLE_IRQ;
+ link->config_index = 1;
+
+ dev->netdev_ops = &el3_netdev_ops;
+ dev->watchdog_timeo = TX_TIMEOUT;
+
+ dev->ethtool_ops = &netdev_ethtool_ops;
+
+ return tc589_config(link);
+}
+
+static void tc589_detach(struct pcmcia_device *link)
+{
+ struct net_device *dev = link->priv;
+
+ dev_dbg(&link->dev, "3c589_detach\n");
+
+ unregister_netdev(dev);
+
+ tc589_release(link);
+
+ free_netdev(dev);
+} /* tc589_detach */
+
+static int tc589_config(struct pcmcia_device *link)
+{
+ struct net_device *dev = link->priv;
+ __be16 *phys_addr;
+ int ret, i, j, multi = 0, fifo;
+ unsigned int ioaddr;
+ static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+ u8 *buf;
+ size_t len;
+
+ dev_dbg(&link->dev, "3c589_config\n");
+
+ phys_addr = (__be16 *)dev->dev_addr;
+ /* Is this a 3c562? */
+ if (link->manf_id != MANFID_3COM)
+ dev_info(&link->dev, "hmmm, is this really a 3Com card??\n");
+ multi = (link->card_id == PRODID_3COM_3C562);
+
+ link->io_lines = 16;
+
+ /* For the 3c562, the base address must be xx00-xx7f */
+ for (i = j = 0; j < 0x400; j += 0x10) {
+ if (multi && (j & 0x80))
+ continue;
+ link->resource[0]->start = j ^ 0x300;
+ i = pcmcia_request_io(link);
+ if (i == 0)
+ break;
+ }
+ if (i != 0)
+ goto failed;
+
+ ret = pcmcia_request_irq(link, el3_interrupt);
+ if (ret)
+ goto failed;
+
+ ret = pcmcia_enable_device(link);
+ if (ret)
+ goto failed;
+
+ dev->irq = link->irq;
+ dev->base_addr = link->resource[0]->start;
+ ioaddr = dev->base_addr;
+ EL3WINDOW(0);
+
+ /* The 3c589 has an extra EEPROM for configuration info, including
+ * the hardware address. The 3c562 puts the address in the CIS.
+ */
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
+ kfree(buf);
+ } else {
+ kfree(buf); /* 0 < len < 6 */
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(read_eeprom(ioaddr, i));
+ if (phys_addr[0] == htons(0x6060)) {
+ dev_err(&link->dev, "IO port conflict at 0x%03lx-0x%03lx\n",
+ dev->base_addr, dev->base_addr+15);
+ goto failed;
+ }
+ }
+
+ /* The address and resource configuration register aren't loaded from
+ * the EEPROM and *must* be set to 0 and IRQ3 for the PCMCIA version.
+ */
+
+ outw(0x3f00, ioaddr + 8);
+ fifo = inl(ioaddr);
+
+ /* The if_port symbol can be set when the module is loaded */
+ if ((if_port >= 0) && (if_port <= 3))
+ dev->if_port = if_port;
+ else
+ dev_err(&link->dev, "invalid if_port requested\n");
+
+ SET_NETDEV_DEV(dev, &link->dev);
+
+ if (register_netdev(dev) != 0) {
+ dev_err(&link->dev, "register_netdev() failed\n");
+ goto failed;
+ }
+
+ netdev_info(dev, "3Com 3c%s, io %#3lx, irq %d, hw_addr %pM\n",
+ (multi ? "562" : "589"), dev->base_addr, dev->irq,
+ dev->dev_addr);
+ netdev_info(dev, " %dK FIFO split %s Rx:Tx, %s xcvr\n",
+ (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3],
+ if_names[dev->if_port]);
+ return 0;
+
+failed:
+ tc589_release(link);
+ return -ENODEV;
+} /* tc589_config */
+
+static void tc589_release(struct pcmcia_device *link)
+{
+ pcmcia_disable_device(link);
+}
+
+static int tc589_suspend(struct pcmcia_device *link)
+{
+ struct net_device *dev = link->priv;
+
+ if (link->open)
+ netif_device_detach(dev);
+
+ return 0;
+}
+
+static int tc589_resume(struct pcmcia_device *link)
+{
+ struct net_device *dev = link->priv;
+
+ if (link->open) {
+ tc589_reset(dev);
+ netif_device_attach(dev);
+ }
+
+ return 0;
+}
+
+/*====================================================================*/
+
+/* Use this for commands that may take time to finish */
+
+static void tc589_wait_for_completion(struct net_device *dev, int cmd)
+{
+ int i = 100;
+ outw(cmd, dev->base_addr + EL3_CMD);
+ while (--i > 0)
+ if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000))
+ break;
+ if (i == 0)
+ netdev_warn(dev, "command 0x%04x did not complete!\n", cmd);
+}
+
+/* Read a word from the EEPROM using the regular EEPROM access register.
+ * Assume that we are in register window zero.
+ */
+
+static u16 read_eeprom(unsigned int ioaddr, int index)
+{
+ int i;
+ outw(EEPROM_READ + index, ioaddr + 10);
+ /* Reading the eeprom takes 162 us */
+ for (i = 1620; i >= 0; i--)
+ if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0)
+ break;
+ return inw(ioaddr + 12);
+}
+
+/* Set transceiver type, perhaps to something other than what the user
+ * specified in dev->if_port.
+ */
+
+static void tc589_set_xcvr(struct net_device *dev, int if_port)
+{
+ struct el3_private *lp = netdev_priv(dev);
+ unsigned int ioaddr = dev->base_addr;
+
+ EL3WINDOW(0);
+ switch (if_port) {
+ case 0:
+ case 1:
+ outw(0, ioaddr + 6);
+ break;
+ case 2:
+ outw(3<<14, ioaddr + 6);
+ break;
+ case 3:
+ outw(1<<14, ioaddr + 6);
+ break;
+ }
+ /* On PCMCIA, this just turns on the LED */
+ outw((if_port == 2) ? StartCoax : StopCoax, ioaddr + EL3_CMD);
+ /* 10baseT interface, enable link beat and jabber check. */
+ EL3WINDOW(4);
+ outw(MEDIA_LED | ((if_port < 2) ? MEDIA_TP : 0), ioaddr + WN4_MEDIA);
+ EL3WINDOW(1);
+ if (if_port == 2)
+ lp->media_status = ((dev->if_port == 0) ? 0x8000 : 0x4000);
+ else
+ lp->media_status = ((dev->if_port == 0) ? 0x4010 : 0x8800);
+}
+
+static void dump_status(struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+ EL3WINDOW(1);
+ netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x tx free %04x\n",
+ inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS),
+ inb(ioaddr+TX_STATUS), inw(ioaddr+TX_FREE));
+ EL3WINDOW(4);
+ netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n",
+ inw(ioaddr+0x04), inw(ioaddr+0x06), inw(ioaddr+0x08),
+ inw(ioaddr+0x0a));
+ EL3WINDOW(1);
+}
+
+/* Reset and restore all of the 3c589 registers. */
+static void tc589_reset(struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+ int i;
+
+ EL3WINDOW(0);
+ outw(0x0001, ioaddr + 4); /* Activate board. */
+ outw(0x3f00, ioaddr + 8); /* Set the IRQ line. */
+
+ /* Set the station address in window 2. */
+ EL3WINDOW(2);
+ for (i = 0; i < 6; i++)
+ outb(dev->dev_addr[i], ioaddr + i);
+
+ tc589_set_xcvr(dev, dev->if_port);
+
+ /* Switch to the stats window, and clear all stats by reading. */
+ outw(StatsDisable, ioaddr + EL3_CMD);
+ EL3WINDOW(6);
+ for (i = 0; i < 9; i++)
+ inb(ioaddr+i);
+ inw(ioaddr + 10);
+ inw(ioaddr + 12);
+
+ /* Switch to register set 1 for normal use. */
+ EL3WINDOW(1);
+
+ set_rx_mode(dev);
+ outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+ outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+ outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+ /* Allow status bits to be seen. */
+ outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
+ /* Ack all pending events, and set active indicator mask. */
+ outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+ ioaddr + EL3_CMD);
+ outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
+ | AdapterFailure, ioaddr + EL3_CMD);
+}
+
+static void netdev_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ snprintf(info->bus_info, sizeof(info->bus_info),
+ "PCMCIA 0x%lx", dev->base_addr);
+}
+
+static const struct ethtool_ops netdev_ethtool_ops = {
+ .get_drvinfo = netdev_get_drvinfo,
+};
+
+static int el3_config(struct net_device *dev, struct ifmap *map)
+{
+ if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
+ if (map->port <= 3) {
+ dev->if_port = map->port;
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
+ tc589_set_xcvr(dev, dev->if_port);
+ } else {
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int el3_open(struct net_device *dev)
+{
+ struct el3_private *lp = netdev_priv(dev);
+ struct pcmcia_device *link = lp->p_dev;
+
+ if (!pcmcia_dev_present(link))
+ return -ENODEV;
+
+ link->open++;
+ netif_start_queue(dev);
+
+ tc589_reset(dev);
+ init_timer(&lp->media);
+ lp->media.function = media_check;
+ lp->media.data = (unsigned long) dev;
+ lp->media.expires = jiffies + HZ;
+ add_timer(&lp->media);
+
+ dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
+ dev->name, inw(dev->base_addr + EL3_STATUS));
+
+ return 0;
+}
+
+static void el3_tx_timeout(struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+
+ netdev_warn(dev, "Transmit timed out!\n");
+ dump_status(dev);
+ dev->stats.tx_errors++;
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ /* Issue TX_RESET and TX_START commands. */
+ tc589_wait_for_completion(dev, TxReset);
+ outw(TxEnable, ioaddr + EL3_CMD);
+ netif_wake_queue(dev);
+}
+
+static void pop_tx_status(struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+ int i;
+
+ /* Clear the Tx status stack. */
+ for (i = 32; i > 0; i--) {
+ u_char tx_status = inb(ioaddr + TX_STATUS);
+ if (!(tx_status & 0x84))
+ break;
+ /* reset transmitter on jabber error or underrun */
+ if (tx_status & 0x30)
+ tc589_wait_for_completion(dev, TxReset);
+ if (tx_status & 0x38) {
+ netdev_dbg(dev, "transmit error: status 0x%02x\n", tx_status);
+ outw(TxEnable, ioaddr + EL3_CMD);
+ dev->stats.tx_aborted_errors++;
+ }
+ outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
+ }
+}
+
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+ struct el3_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ netdev_dbg(dev, "el3_start_xmit(length = %ld) called, status %4.4x.\n",
+ (long)skb->len, inw(ioaddr + EL3_STATUS));
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ dev->stats.tx_bytes += skb->len;
+
+ /* Put out the doubleword header... */
+ outw(skb->len, ioaddr + TX_FIFO);
+ outw(0x00, ioaddr + TX_FIFO);
+ /* ... and the packet rounded to a doubleword. */
+ outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+
+ if (inw(ioaddr + TX_FREE) <= 1536) {
+ netif_stop_queue(dev);
+ /* Interrupt us when the FIFO has room for max-sized packet. */
+ outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
+ }
+
+ pop_tx_status(dev);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dev_kfree_skb(skb);
+
+ return NETDEV_TX_OK;
+}
+
+/* The EL3 interrupt handler. */
+static irqreturn_t el3_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *) dev_id;
+ struct el3_private *lp = netdev_priv(dev);
+ unsigned int ioaddr;
+ __u16 status;
+ int i = 0, handled = 1;
+
+ if (!netif_device_present(dev))
+ return IRQ_NONE;
+
+ ioaddr = dev->base_addr;
+
+ netdev_dbg(dev, "interrupt, status %4.4x.\n", inw(ioaddr + EL3_STATUS));
+
+ spin_lock(&lp->lock);
+ while ((status = inw(ioaddr + EL3_STATUS)) &
+ (IntLatch | RxComplete | StatsFull)) {
+ if ((status & 0xe000) != 0x2000) {
+ netdev_dbg(dev, "interrupt from dead card\n");
+ handled = 0;
+ break;
+ }
+ if (status & RxComplete)
+ el3_rx(dev);
+ if (status & TxAvailable) {
+ netdev_dbg(dev, " TX room bit was handled.\n");
+ /* There's room in the FIFO for a full-sized packet. */
+ outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
+ netif_wake_queue(dev);
+ }
+ if (status & TxComplete)
+ pop_tx_status(dev);
+ if (status & (AdapterFailure | RxEarly | StatsFull)) {
+ /* Handle all uncommon interrupts. */
+ if (status & StatsFull) /* Empty statistics. */
+ update_stats(dev);
+ if (status & RxEarly) {
+ /* Rx early is unused. */
+ el3_rx(dev);
+ outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
+ }
+ if (status & AdapterFailure) {
+ u16 fifo_diag;
+ EL3WINDOW(4);
+ fifo_diag = inw(ioaddr + 4);
+ EL3WINDOW(1);
+ netdev_warn(dev, "adapter failure, FIFO diagnostic register %04x.\n",
+ fifo_diag);
+ if (fifo_diag & 0x0400) {
+ /* Tx overrun */
+ tc589_wait_for_completion(dev, TxReset);
+ outw(TxEnable, ioaddr + EL3_CMD);
+ }
+ if (fifo_diag & 0x2000) {
+ /* Rx underrun */
+ tc589_wait_for_completion(dev, RxReset);
+ set_rx_mode(dev);
+ outw(RxEnable, ioaddr + EL3_CMD);
+ }
+ outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
+ }
+ }
+ if (++i > 10) {
+ netdev_err(dev, "infinite loop in interrupt, status %4.4x.\n",
+ status);
+ /* Clear all interrupts */
+ outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
+ break;
+ }
+ /* Acknowledge the IRQ. */
+ outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+ }
+ lp->last_irq = jiffies;
+ spin_unlock(&lp->lock);
+ netdev_dbg(dev, "exiting interrupt, status %4.4x.\n",
+ inw(ioaddr + EL3_STATUS));
+ return IRQ_RETVAL(handled);
+}
+
+static void media_check(unsigned long arg)
+{
+ struct net_device *dev = (struct net_device *)(arg);
+ struct el3_private *lp = netdev_priv(dev);
+ unsigned int ioaddr = dev->base_addr;
+ u16 media, errs;
+ unsigned long flags;
+
+ if (!netif_device_present(dev))
+ goto reschedule;
+
+ /* Check for pending interrupt with expired latency timer: with
+ * this, we can limp along even if the interrupt is blocked
+ */
+ if ((inw(ioaddr + EL3_STATUS) & IntLatch) &&
+ (inb(ioaddr + EL3_TIMER) == 0xff)) {
+ if (!lp->fast_poll)
+ netdev_warn(dev, "interrupt(s) dropped!\n");
+
+ local_irq_save(flags);
+ el3_interrupt(dev->irq, dev);
+ local_irq_restore(flags);
+
+ lp->fast_poll = HZ;
+ }
+ if (lp->fast_poll) {
+ lp->fast_poll--;
+ lp->media.expires = jiffies + HZ/100;
+ add_timer(&lp->media);
+ return;
+ }
+
+ /* lp->lock guards the EL3 window. Window should always be 1 except
+ * when the lock is held
+ */
+
+ spin_lock_irqsave(&lp->lock, flags);
+ EL3WINDOW(4);
+ media = inw(ioaddr+WN4_MEDIA) & 0xc810;
+
+ /* Ignore collisions unless we've had no irq's recently */
+ if (time_before(jiffies, lp->last_irq + HZ)) {
+ media &= ~0x0010;
+ } else {
+ /* Try harder to detect carrier errors */
+ EL3WINDOW(6);
+ outw(StatsDisable, ioaddr + EL3_CMD);
+ errs = inb(ioaddr + 0);
+ outw(StatsEnable, ioaddr + EL3_CMD);
+ dev->stats.tx_carrier_errors += errs;
+ if (errs || (lp->media_status & 0x0010))
+ media |= 0x0010;
+ }
+
+ if (media != lp->media_status) {
+ if ((media & lp->media_status & 0x8000) &&
+ ((lp->media_status ^ media) & 0x0800))
+ netdev_info(dev, "%s link beat\n",
+ (lp->media_status & 0x0800 ? "lost" : "found"));
+ else if ((media & lp->media_status & 0x4000) &&
+ ((lp->media_status ^ media) & 0x0010))
+ netdev_info(dev, "coax cable %s\n",
+ (lp->media_status & 0x0010 ? "ok" : "problem"));
+ if (dev->if_port == 0) {
+ if (media & 0x8000) {
+ if (media & 0x0800)
+ netdev_info(dev, "flipped to 10baseT\n");
+ else
+ tc589_set_xcvr(dev, 2);
+ } else if (media & 0x4000) {
+ if (media & 0x0010)
+ tc589_set_xcvr(dev, 1);
+ else
+ netdev_info(dev, "flipped to 10base2\n");
+ }
+ }
+ lp->media_status = media;
+ }
+
+ EL3WINDOW(1);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+reschedule:
+ lp->media.expires = jiffies + HZ;
+ add_timer(&lp->media);
+}
+
+static struct net_device_stats *el3_get_stats(struct net_device *dev)
+{
+ struct el3_private *lp = netdev_priv(dev);
+ unsigned long flags;
+ struct pcmcia_device *link = lp->p_dev;
+
+ if (pcmcia_dev_present(link)) {
+ spin_lock_irqsave(&lp->lock, flags);
+ update_stats(dev);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ }
+ return &dev->stats;
+}
+
+/* Update statistics. We change to register window 6, so this should be run
+* single-threaded if the device is active. This is expected to be a rare
+* operation, and it's simpler for the rest of the driver to assume that
+* window 1 is always valid rather than use a special window-state variable.
+*
+* Caller must hold the lock for this
+*/
+
+static void update_stats(struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+
+ netdev_dbg(dev, "updating the statistics.\n");
+ /* Turn off statistics updates while reading. */
+ outw(StatsDisable, ioaddr + EL3_CMD);
+ /* Switch to the stats window, and read everything. */
+ EL3WINDOW(6);
+ dev->stats.tx_carrier_errors += inb(ioaddr + 0);
+ dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
+ /* Multiple collisions. */
+ inb(ioaddr + 2);
+ dev->stats.collisions += inb(ioaddr + 3);
+ dev->stats.tx_window_errors += inb(ioaddr + 4);
+ dev->stats.rx_fifo_errors += inb(ioaddr + 5);
+ dev->stats.tx_packets += inb(ioaddr + 6);
+ /* Rx packets */
+ inb(ioaddr + 7);
+ /* Tx deferrals */
+ inb(ioaddr + 8);
+ /* Rx octets */
+ inw(ioaddr + 10);
+ /* Tx octets */
+ inw(ioaddr + 12);
+
+ /* Back to window 1, and turn statistics back on. */
+ EL3WINDOW(1);
+ outw(StatsEnable, ioaddr + EL3_CMD);
+}
+
+static int el3_rx(struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+ int worklimit = 32;
+ short rx_status;
+
+ netdev_dbg(dev, "in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
+ while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
+ worklimit > 0) {
+ worklimit--;
+ if (rx_status & 0x4000) { /* Error, update stats. */
+ short error = rx_status & 0x3800;
+ dev->stats.rx_errors++;
+ switch (error) {
+ case 0x0000:
+ dev->stats.rx_over_errors++;
+ break;
+ case 0x0800:
+ dev->stats.rx_length_errors++;
+ break;
+ case 0x1000:
+ dev->stats.rx_frame_errors++;
+ break;
+ case 0x1800:
+ dev->stats.rx_length_errors++;
+ break;
+ case 0x2000:
+ dev->stats.rx_frame_errors++;
+ break;
+ case 0x2800:
+ dev->stats.rx_crc_errors++;
+ break;
+ }
+ } else {
+ short pkt_len = rx_status & 0x7ff;
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb(dev, pkt_len + 5);
+
+ netdev_dbg(dev, " Receiving packet size %d status %4.4x.\n",
+ pkt_len, rx_status);
+ if (skb != NULL) {
+ skb_reserve(skb, 2);
+ insl(ioaddr+RX_FIFO, skb_put(skb, pkt_len),
+ (pkt_len+3)>>2);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+ } else {
+ netdev_dbg(dev, "couldn't allocate a sk_buff of size %d.\n",
+ pkt_len);
+ dev->stats.rx_dropped++;
+ }
+ }
+ /* Pop the top of the Rx FIFO */
+ tc589_wait_for_completion(dev, RxDiscard);
+ }
+ if (worklimit == 0)
+ netdev_warn(dev, "too much work in el3_rx!\n");
+ return 0;
+}
+
+static void set_rx_mode(struct net_device *dev)
+{
+ unsigned int ioaddr = dev->base_addr;
+ u16 opts = SetRxFilter | RxStation | RxBroadcast;
+
+ if (dev->flags & IFF_PROMISC)
+ opts |= RxMulticast | RxProm;
+ else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI))
+ opts |= RxMulticast;
+ outw(opts, ioaddr + EL3_CMD);
+}
+
+static void set_multicast_list(struct net_device *dev)
+{
+ struct el3_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ set_rx_mode(dev);
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static int el3_close(struct net_device *dev)
+{
+ struct el3_private *lp = netdev_priv(dev);
+ struct pcmcia_device *link = lp->p_dev;
+ unsigned int ioaddr = dev->base_addr;
+
+ dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
+
+ if (pcmcia_dev_present(link)) {
+ /* Turn off statistics ASAP. We update dev->stats below. */
+ outw(StatsDisable, ioaddr + EL3_CMD);
+
+ /* Disable the receiver and transmitter. */
+ outw(RxDisable, ioaddr + EL3_CMD);
+ outw(TxDisable, ioaddr + EL3_CMD);
+
+ if (dev->if_port == 2)
+ /* Turn off thinnet power. Green! */
+ outw(StopCoax, ioaddr + EL3_CMD);
+ else if (dev->if_port == 1) {
+ /* Disable link beat and jabber */
+ EL3WINDOW(4);
+ outw(0, ioaddr + WN4_MEDIA);
+ }
+
+ /* Switching back to window 0 disables the IRQ. */
+ EL3WINDOW(0);
+ /* But we explicitly zero the IRQ line select anyway. */
+ outw(0x0f00, ioaddr + WN0_IRQ);
+
+ /* Check if the card still exists */
+ if ((inw(ioaddr+EL3_STATUS) & 0xe000) == 0x2000)
+ update_stats(dev);
+ }
+
+ link->open--;
+ netif_stop_queue(dev);
+ del_timer_sync(&lp->media);
+
+ return 0;
+}
+
+static const struct pcmcia_device_id tc589_ids[] = {
+ PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0101, 0x0562),
+ PCMCIA_MFC_DEVICE_PROD_ID1(0, "Motorola MARQUIS", 0xf03e4e77),
+ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0589),
+ PCMCIA_DEVICE_PROD_ID12("Farallon", "ENet", 0x58d93fc4, 0x992c2202),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "cis/3CXEM556.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "cis/3CXEM556.cis"),
+ PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, tc589_ids);
+
+static struct pcmcia_driver tc589_driver = {
+ .owner = THIS_MODULE,
+ .name = "3c589_cs",
+ .probe = tc589_probe,
+ .remove = tc589_detach,
+ .id_table = tc589_ids,
+ .suspend = tc589_suspend,
+ .resume = tc589_resume,
+};
+module_pcmcia_driver(tc589_driver);
diff --git a/drivers/net/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 491ee16da5c..61477b8e8d2 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -77,7 +77,6 @@ static int vortex_debug = 1;
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/mii.h>
@@ -90,7 +89,8 @@ static int vortex_debug = 1;
#include <linux/eisa.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
-#include <asm/irq.h> /* For NR_IRQS only. */
+#include <linux/gfp.h>
+#include <asm/irq.h> /* For nr_irqs only. */
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -102,8 +102,8 @@ static int vortex_debug = 1;
#include <linux/delay.h>
-static char version[] __devinitdata =
-DRV_NAME ": Donald Becker and others.\n";
+static const char version[] =
+ DRV_NAME ": Donald Becker and others.\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver ");
@@ -235,6 +235,7 @@ enum vortex_chips {
CH_3C900B_FL,
CH_3C905_1,
CH_3C905_2,
+ CH_3C905B_TX,
CH_3C905B_1,
CH_3C905B_2,
@@ -276,7 +277,7 @@ static struct vortex_chip_info {
int flags;
int drv_flags;
int io_size;
-} vortex_info_tbl[] __devinitdata = {
+} vortex_info_tbl[] = {
{"3c590 Vortex 10Mbps",
PCI_USES_MASTER, IS_VORTEX, 32, },
{"3c592 EISA 10Mbps Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */
@@ -307,6 +308,8 @@ static struct vortex_chip_info {
PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
{"3c905 Boomerang 100baseT4",
PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
+ {"3C905B-TX Fast Etherlink XL PCI",
+ PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
{"3c905B Cyclone 100baseTx",
PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
@@ -372,7 +375,7 @@ static struct vortex_chip_info {
};
-static struct pci_device_id vortex_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(vortex_pci_tbl) = {
{ 0x10B7, 0x5900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C590 },
{ 0x10B7, 0x5920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C592 },
{ 0x10B7, 0x5970, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C597 },
@@ -389,6 +392,7 @@ static struct pci_device_id vortex_pci_tbl[] = {
{ 0x10B7, 0x900A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900B_FL },
{ 0x10B7, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905_1 },
{ 0x10B7, 0x9051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905_2 },
+ { 0x10B7, 0x9054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_TX },
{ 0x10B7, 0x9055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_1 },
{ 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
@@ -431,7 +435,6 @@ MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);
First the windows. There are eight register windows, with the command
and status registers available in each.
*/
-#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)
#define EL3_CMD 0x0e
#define EL3_STATUS 0x0e
@@ -629,8 +632,11 @@ struct vortex_private {
pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */
open:1,
medialock:1,
- must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */
- large_frames:1; /* accept large frames */
+ large_frames:1, /* accept large frames */
+ handling_irq:1; /* private in_irq indicator */
+ /* {get|set}_wol operations are already serialized by rtnl.
+ * no additional locking is required for the enable_wol and acpi_set_WOL()
+ */
int drv_flags;
u16 status_enable;
u16 intr_enable;
@@ -641,17 +647,59 @@ struct vortex_private {
u16 deferred; /* Resend these interrupts when we
* bale from the ISR */
u16 io_size; /* Size of PCI region (for release_region) */
- spinlock_t lock; /* Serialise access to device & its vortex_private */
- struct mii_if_info mii; /* MII lib hooks/info */
+
+ /* Serialises access to hardware other than MII and variables below.
+ * The lock hierarchy is rtnl_lock > {lock, mii_lock} > window_lock. */
+ spinlock_t lock;
+
+ spinlock_t mii_lock; /* Serialises access to MII */
+ struct mii_if_info mii; /* MII lib hooks/info */
+ spinlock_t window_lock; /* Serialises access to windowed regs */
+ int window; /* Register window */
};
+static void window_set(struct vortex_private *vp, int window)
+{
+ if (window != vp->window) {
+ iowrite16(SelectWindow + window, vp->ioaddr + EL3_CMD);
+ vp->window = window;
+ }
+}
+
+#define DEFINE_WINDOW_IO(size) \
+static u ## size \
+window_read ## size(struct vortex_private *vp, int window, int addr) \
+{ \
+ unsigned long flags; \
+ u ## size ret; \
+ spin_lock_irqsave(&vp->window_lock, flags); \
+ window_set(vp, window); \
+ ret = ioread ## size(vp->ioaddr + addr); \
+ spin_unlock_irqrestore(&vp->window_lock, flags); \
+ return ret; \
+} \
+static void \
+window_write ## size(struct vortex_private *vp, u ## size value, \
+ int window, int addr) \
+{ \
+ unsigned long flags; \
+ spin_lock_irqsave(&vp->window_lock, flags); \
+ window_set(vp, window); \
+ iowrite ## size(value, vp->ioaddr + addr); \
+ spin_unlock_irqrestore(&vp->window_lock, flags); \
+}
+DEFINE_WINDOW_IO(8)
+DEFINE_WINDOW_IO(16)
+DEFINE_WINDOW_IO(32)
+
#ifdef CONFIG_PCI
-#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)
+#define DEVICE_PCI(dev) ((dev_is_pci(dev)) ? to_pci_dev((dev)) : NULL)
#else
#define DEVICE_PCI(dev) NULL
#endif
-#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
+#define VORTEX_PCI(vp) \
+ ((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL))
#ifdef CONFIG_EISA
#define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
@@ -659,7 +707,8 @@ struct vortex_private {
#define DEVICE_EISA(dev) NULL
#endif
-#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)
+#define VORTEX_EISA(vp) \
+ ((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL))
/* The action to take with a media selection timer tick.
Note that we deviate from the 3Com order by checking 10base2 before AUI.
@@ -707,13 +756,15 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
static int vortex_up(struct net_device *dev);
static void vortex_down(struct net_device *dev, int final);
static int vortex_open(struct net_device *dev);
-static void mdio_sync(void __iomem *ioaddr, int bits);
+static void mdio_sync(struct vortex_private *vp, int bits);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
static void vortex_timer(unsigned long arg);
static void rx_oom_timer(unsigned long arg);
-static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t vortex_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
static int vortex_rx(struct net_device *dev);
static int boomerang_rx(struct net_device *dev);
static irqreturn_t vortex_interrupt(int irq, void *dev_id);
@@ -799,58 +850,54 @@ static void poll_vortex(struct net_device *dev)
#ifdef CONFIG_PM
-static int vortex_suspend(struct pci_dev *pdev, pm_message_t state)
+static int vortex_suspend(struct device *dev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *ndev = pci_get_drvdata(pdev);
+
+ if (!ndev || !netif_running(ndev))
+ return 0;
+
+ netif_device_detach(ndev);
+ vortex_down(ndev, 1);
- if (dev && dev->priv) {
- if (netif_running(dev)) {
- netif_device_detach(dev);
- vortex_down(dev, 1);
- }
- pci_save_state(pdev);
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
- free_irq(dev->irq, dev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- }
return 0;
}
-static int vortex_resume(struct pci_dev *pdev)
+static int vortex_resume(struct device *dev)
{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct vortex_private *vp = netdev_priv(dev);
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *ndev = pci_get_drvdata(pdev);
int err;
- if (dev && vp) {
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_WARNING "%s: Could not enable device \n",
- dev->name);
- return err;
- }
- pci_set_master(pdev);
- if (request_irq(dev->irq, vp->full_bus_master_rx ?
- &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {
- printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
- pci_disable_device(pdev);
- return -EBUSY;
- }
- if (netif_running(dev)) {
- err = vortex_up(dev);
- if (err)
- return err;
- else
- netif_device_attach(dev);
- }
- }
+ if (!ndev || !netif_running(ndev))
+ return 0;
+
+ err = vortex_up(ndev);
+ if (err)
+ return err;
+
+ netif_device_attach(ndev);
+
return 0;
}
-#endif /* CONFIG_PM */
+static const struct dev_pm_ops vortex_pm_ops = {
+ .suspend = vortex_suspend,
+ .resume = vortex_resume,
+ .freeze = vortex_suspend,
+ .thaw = vortex_resume,
+ .poweroff = vortex_suspend,
+ .restore = vortex_resume,
+};
+
+#define VORTEX_PM_OPS (&vortex_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define VORTEX_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
#ifdef CONFIG_EISA
static struct eisa_device_id vortex_eisa_ids[] = {
@@ -883,7 +930,7 @@ static int __init vortex_eisa_probe(struct device *device)
return 0;
}
-static int __devexit vortex_eisa_remove(struct device *device)
+static int vortex_eisa_remove(struct device *device)
{
struct eisa_device *edev;
struct net_device *dev;
@@ -894,7 +941,7 @@ static int __devexit vortex_eisa_remove(struct device *device)
dev = eisa_get_drvdata(edev);
if (!dev) {
- printk("vortex_eisa_remove called for Compaq device!\n");
+ pr_err("vortex_eisa_remove called for Compaq device!\n");
BUG();
}
@@ -903,7 +950,7 @@ static int __devexit vortex_eisa_remove(struct device *device)
unregister_netdev(dev);
iowrite16(TotalReset|0x14, ioaddr + EL3_CMD);
- release_region(dev->base_addr, VORTEX_TOTAL_SIZE);
+ release_region(edev->base_addr, VORTEX_TOTAL_SIZE);
free_netdev(dev);
return 0;
@@ -914,7 +961,7 @@ static struct eisa_driver vortex_eisa_driver = {
.driver = {
.name = "3c59x",
.probe = vortex_eisa_probe,
- .remove = __devexit_p(vortex_eisa_remove)
+ .remove = vortex_eisa_remove
}
};
@@ -936,7 +983,7 @@ static int __init vortex_eisa_init(void)
* any device have been found when we exit from
* eisa_driver_register (the bus root driver may not be
* initialized yet). So we blindly assume something was
- * found, and let the sysfs magic happend...
+ * found, and let the sysfs magic happened...
*/
eisa_found = 1;
}
@@ -952,8 +999,8 @@ static int __init vortex_eisa_init(void)
}
/* returns count (>= 0), or negative on error */
-static int __devinit vortex_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int vortex_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
int rc, unit, pci_bar;
struct vortex_chip_info *vci;
@@ -964,6 +1011,10 @@ static int __devinit vortex_init_one(struct pci_dev *pdev,
if (rc < 0)
goto out;
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc < 0)
+ goto out_disable;
+
unit = vortex_cards_found;
if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
@@ -978,29 +1029,73 @@ static int __devinit vortex_init_one(struct pci_dev *pdev,
ioaddr = pci_iomap(pdev, pci_bar, 0);
if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
ioaddr = pci_iomap(pdev, 0, 0);
+ if (!ioaddr) {
+ rc = -ENOMEM;
+ goto out_release;
+ }
rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
ent->driver_data, unit);
- if (rc < 0) {
- pci_disable_device(pdev);
- goto out;
- }
+ if (rc < 0)
+ goto out_iounmap;
vortex_cards_found++;
-
+ goto out;
+
+out_iounmap:
+ pci_iounmap(pdev, ioaddr);
+out_release:
+ pci_release_regions(pdev);
+out_disable:
+ pci_disable_device(pdev);
out:
return rc;
}
+static const struct net_device_ops boomrang_netdev_ops = {
+ .ndo_open = vortex_open,
+ .ndo_stop = vortex_close,
+ .ndo_start_xmit = boomerang_start_xmit,
+ .ndo_tx_timeout = vortex_tx_timeout,
+ .ndo_get_stats = vortex_get_stats,
+#ifdef CONFIG_PCI
+ .ndo_do_ioctl = vortex_ioctl,
+#endif
+ .ndo_set_rx_mode = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = poll_vortex,
+#endif
+};
+
+static const struct net_device_ops vortex_netdev_ops = {
+ .ndo_open = vortex_open,
+ .ndo_stop = vortex_close,
+ .ndo_start_xmit = vortex_start_xmit,
+ .ndo_tx_timeout = vortex_tx_timeout,
+ .ndo_get_stats = vortex_get_stats,
+#ifdef CONFIG_PCI
+ .ndo_do_ioctl = vortex_ioctl,
+#endif
+ .ndo_set_rx_mode = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = poll_vortex,
+#endif
+};
+
/*
* Start up the PCI/EISA device which is described by *gendev.
* Return 0 on success.
*
* NOTE: pdev can be NULL, for the case of a Compaq device
*/
-static int __devinit vortex_probe1(struct device *gendev,
- void __iomem *ioaddr, int irq,
- int chip_idx, int card_idx)
+static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
+ int chip_idx, int card_idx)
{
struct vortex_private *vp;
int option;
@@ -1013,10 +1108,9 @@ static int __devinit vortex_probe1(struct device *gendev,
const char *print_name = "3c59x";
struct pci_dev *pdev = NULL;
struct eisa_device *edev = NULL;
- DECLARE_MAC_BUF(mac);
if (!printed_version) {
- printk (version);
+ pr_info("%s", version);
printed_version = 1;
}
@@ -1026,16 +1120,15 @@ static int __devinit vortex_probe1(struct device *gendev,
}
if ((edev = DEVICE_EISA(gendev))) {
- print_name = edev->dev.bus_id;
+ print_name = dev_name(&edev->dev);
}
}
dev = alloc_etherdev(sizeof(*vp));
retval = -ENOMEM;
- if (!dev) {
- printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n");
+ if (!dev)
goto out;
- }
+
SET_NETDEV_DEV(dev, gendev);
vp = netdev_priv(dev);
@@ -1065,9 +1158,9 @@ static int __devinit vortex_probe1(struct device *gendev,
print_info = (vortex_debug > 1);
if (print_info)
- printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
+ pr_info("See Documentation/networking/vortex.txt\n");
- printk(KERN_INFO "%s: 3Com %s %s at %p.\n",
+ pr_info("%s: 3Com %s %s at %p.\n",
print_name,
pdev ? "PCI" : "EISA",
vci->name,
@@ -1082,6 +1175,7 @@ static int __devinit vortex_probe1(struct device *gendev,
vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
vp->io_size = vci->io_size;
vp->card_idx = card_idx;
+ vp->window = -1;
/* module list only for Compaq device */
if (gendev == NULL) {
@@ -1090,11 +1184,6 @@ static int __devinit vortex_probe1(struct device *gendev,
/* PCI-only startup logic */
if (pdev) {
- /* EISA resources already marked, so only PCI needs to do this here */
- /* Ignore return value, because Cardbus drivers already allocate for us */
- if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
- vp->must_free_region = 1;
-
/* enable bus-mastering if necessary */
if (vci->flags & PCI_USES_MASTER)
pci_set_master(pdev);
@@ -1109,15 +1198,16 @@ static int __devinit vortex_probe1(struct device *gendev,
chip only. */
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < new_latency) {
- printk(KERN_INFO "%s: Overriding PCI latency"
- " timer (CFLT) setting of %d, new value is %d.\n",
+ pr_info("%s: Overriding PCI latency timer (CFLT) setting of %d, new value is %d.\n",
print_name, pci_latency, new_latency);
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
}
}
}
spin_lock_init(&vp->lock);
+ spin_lock_init(&vp->mii_lock);
+ spin_lock_init(&vp->window_lock);
vp->gendev = gendev;
vp->mii.dev = dev;
vp->mii.mdio_read = mdio_read;
@@ -1131,7 +1221,7 @@ static int __devinit vortex_probe1(struct device *gendev,
&vp->rx_ring_dma);
retval = -ENOMEM;
if (!vp->rx_ring)
- goto free_region;
+ goto free_device;
vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE);
vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE;
@@ -1169,7 +1259,6 @@ static int __devinit vortex_probe1(struct device *gendev,
vp->mii.force_media = vp->full_duplex;
vp->options = option;
/* Read the station address from the EEPROM. */
- EL3WINDOW(0);
{
int base;
@@ -1182,14 +1271,15 @@ static int __devinit vortex_probe1(struct device *gendev,
for (i = 0; i < 0x40; i++) {
int timer;
- iowrite16(base + i, ioaddr + Wn0EepromCmd);
+ window_write16(vp, base + i, 0, Wn0EepromCmd);
/* Pause for at least 162 us. for the read to take place. */
for (timer = 10; timer >= 0; timer--) {
udelay(162);
- if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
+ if ((window_read16(vp, 0, Wn0EepromCmd) &
+ 0x8000) == 0)
break;
}
- eeprom[i] = ioread16(ioaddr + Wn0EepromData);
+ eeprom[i] = window_read16(vp, 0, Wn0EepromData);
}
}
for (i = 0; i < 0x18; i++)
@@ -1201,35 +1291,32 @@ static int __devinit vortex_probe1(struct device *gendev,
checksum = (checksum ^ (checksum >> 8)) & 0xff;
}
if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
- printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
+ pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
for (i = 0; i < 3; i++)
((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
if (print_info)
- printk(" %s", print_mac(mac, dev->dev_addr));
+ pr_cont(" %pM", dev->dev_addr);
/* Unfortunately an all zero eeprom passes the checksum and this
gets found in the wild in failure cases. Crypto is hard 8) */
if (!is_valid_ether_addr(dev->dev_addr)) {
retval = -EINVAL;
- printk(KERN_ERR "*** EEPROM MAC address is invalid.\n");
+ pr_err("*** EEPROM MAC address is invalid.\n");
goto free_ring; /* With every pack */
}
- EL3WINDOW(2);
for (i = 0; i < 6; i++)
- iowrite8(dev->dev_addr[i], ioaddr + i);
+ window_write8(vp, dev->dev_addr[i], 2, i);
if (print_info)
- printk(", IRQ %d\n", dev->irq);
+ pr_cont(", IRQ %d\n", dev->irq);
/* Tell them about an invalid IRQ. */
- if (dev->irq <= 0 || dev->irq >= NR_IRQS)
- printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
+ if (dev->irq <= 0 || dev->irq >= nr_irqs)
+ pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
dev->irq);
- EL3WINDOW(4);
- step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
+ step = (window_read8(vp, 4, Wn4_NetDiag) & 0x1e) >> 1;
if (print_info) {
- printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
- "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
+ pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
+ eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
}
@@ -1244,23 +1331,20 @@ static int __devinit vortex_probe1(struct device *gendev,
}
if (print_info) {
- printk(KERN_INFO "%s: CardBus functions mapped "
- "%16.16llx->%p\n",
+ pr_info("%s: CardBus functions mapped %16.16llx->%p\n",
print_name,
(unsigned long long)pci_resource_start(pdev, 2),
vp->cb_fn_base);
}
- EL3WINDOW(2);
- n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
+ n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010;
if (vp->drv_flags & INVERT_LED_PWR)
n |= 0x10;
if (vp->drv_flags & INVERT_MII_PWR)
n |= 0x4000;
- iowrite16(n, ioaddr + Wn2_ResetOptions);
+ window_write16(vp, n, 2, Wn2_ResetOptions);
if (vp->drv_flags & WNO_XCVR_PWR) {
- EL3WINDOW(0);
- iowrite16(0x0800, ioaddr);
+ window_write16(vp, 0x0800, 0, 0);
}
}
@@ -1272,21 +1356,20 @@ static int __devinit vortex_probe1(struct device *gendev,
if (vp->info1 & 0x8000) {
vp->full_duplex = 1;
if (print_info)
- printk(KERN_INFO "Full duplex capable\n");
+ pr_info("Full duplex capable\n");
}
{
static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
unsigned int config;
- EL3WINDOW(3);
- vp->available_media = ioread16(ioaddr + Wn3_Options);
+ vp->available_media = window_read16(vp, 3, Wn3_Options);
if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */
vp->available_media = 0x40;
- config = ioread32(ioaddr + Wn3_Config);
+ config = window_read32(vp, 3, Wn3_Config);
if (print_info) {
- printk(KERN_DEBUG " Internal config register is %4.4x, "
- "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
- printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+ pr_debug(" Internal config register is %4.4x, transceivers %#x.\n",
+ config, window_read16(vp, 3, Wn3_Options));
+ pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
8 << RAM_SIZE(config),
RAM_WIDTH(config) ? "word" : "byte",
ram_split[RAM_SPLIT(config)],
@@ -1301,7 +1384,7 @@ static int __devinit vortex_probe1(struct device *gendev,
}
if (vp->media_override != 7) {
- printk(KERN_INFO "%s: Media override to transceiver type %d (%s).\n",
+ pr_info("%s: Media override to transceiver type %d (%s).\n",
print_name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
@@ -1311,11 +1394,10 @@ static int __devinit vortex_probe1(struct device *gendev,
if ((vp->available_media & 0x40) || (vci->drv_flags & HAS_NWAY) ||
dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
int phy, phy_idx = 0;
- EL3WINDOW(4);
mii_preamble_required++;
if (vp->drv_flags & EXTRA_PREAMBLE)
mii_preamble_required++;
- mdio_sync(ioaddr, 32);
+ mdio_sync(vp, 32);
mdio_read(dev, 24, MII_BMSR);
for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
int mii_status, phyx;
@@ -1334,8 +1416,8 @@ static int __devinit vortex_probe1(struct device *gendev,
if (mii_status && mii_status != 0xffff) {
vp->phys[phy_idx++] = phyx;
if (print_info) {
- printk(KERN_INFO " MII transceiver found at address %d,"
- " status %4x.\n", phyx, mii_status);
+ pr_info(" MII transceiver found at address %d, status %4x.\n",
+ phyx, mii_status);
}
if ((mii_status & 0x0040) == 0)
mii_preamble_required++;
@@ -1343,7 +1425,7 @@ static int __devinit vortex_probe1(struct device *gendev,
}
mii_preamble_required--;
if (phy_idx == 0) {
- printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n");
+ pr_warning(" ***WARNING*** No MII transceivers found!\n");
vp->phys[0] = 24;
} else {
vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
@@ -1359,7 +1441,7 @@ static int __devinit vortex_probe1(struct device *gendev,
if (vp->capabilities & CapBusMaster) {
vp->full_bus_master_tx = 1;
if (print_info) {
- printk(KERN_INFO " Enabling bus-master transmits and %s receives.\n",
+ pr_info(" Enabling bus-master transmits and %s receives.\n",
(vp->info2 & 1) ? "early" : "whole-frame" );
}
vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
@@ -1367,41 +1449,30 @@ static int __devinit vortex_probe1(struct device *gendev,
}
/* The 3c59x-specific entries in the device structure. */
- dev->open = vortex_open;
if (vp->full_bus_master_tx) {
- dev->hard_start_xmit = boomerang_start_xmit;
+ dev->netdev_ops = &boomrang_netdev_ops;
/* Actually, it still should work with iommu. */
if (card_idx < MAX_UNITS &&
((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
hw_checksums[card_idx] == 1)) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
}
- } else {
- dev->hard_start_xmit = vortex_start_xmit;
- }
+ } else
+ dev->netdev_ops = &vortex_netdev_ops;
if (print_info) {
- printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
+ pr_info("%s: scatter/gather %sabled. h/w checksums %sabled\n",
print_name,
(dev->features & NETIF_F_SG) ? "en":"dis",
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
}
- dev->stop = vortex_close;
- dev->get_stats = vortex_get_stats;
-#ifdef CONFIG_PCI
- dev->do_ioctl = vortex_ioctl;
-#endif
dev->ethtool_ops = &vortex_ethtool_ops;
- dev->set_multicast_list = set_rx_mode;
- dev->tx_timeout = vortex_tx_timeout;
dev->watchdog_timeo = (watchdog * HZ) / 1000;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = poll_vortex;
-#endif
+
if (pdev) {
vp->pm_state_valid = 1;
- pci_save_state(VORTEX_PCI(vp));
+ pci_save_state(pdev);
acpi_set_WOL(dev);
}
retval = register_netdev(dev);
@@ -1414,11 +1485,9 @@ free_ring:
+ sizeof(struct boom_tx_desc) * TX_RING_SIZE,
vp->rx_ring,
vp->rx_ring_dma);
-free_region:
- if (vp->must_free_region)
- release_region(dev->base_addr, vci->io_size);
+free_device:
free_netdev(dev);
- printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
+ pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval);
out:
return retval;
}
@@ -1440,13 +1509,13 @@ issue_and_wait(struct net_device *dev, int cmd)
for (i = 0; i < 100000; i++) {
if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
if (vortex_debug > 1)
- printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
+ pr_info("%s: command 0x%04x took %d usecs\n",
dev->name, cmd, i * 10);
return;
}
udelay(10);
}
- printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
+ pr_err("%s: command 0x%04x did not complete! Status=0x%x\n",
dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
}
@@ -1454,18 +1523,17 @@ static void
vortex_set_duplex(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
- printk(KERN_INFO "%s: setting %s-duplex.\n",
+ pr_info("%s: setting %s-duplex.\n",
dev->name, (vp->full_duplex) ? "full" : "half");
- EL3WINDOW(3);
/* Set the full-duplex bit. */
- iowrite16(((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
- (vp->large_frames ? 0x40 : 0) |
- ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ?
- 0x100 : 0),
- ioaddr + Wn3_MAC_Ctrl);
+ window_write16(vp,
+ ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
+ (vp->large_frames ? 0x40 : 0) |
+ ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ?
+ 0x100 : 0),
+ 3, Wn3_MAC_Ctrl);
}
static void vortex_check_media(struct net_device *dev, unsigned int init)
@@ -1498,25 +1566,24 @@ vortex_up(struct net_device *dev)
pci_restore_state(VORTEX_PCI(vp));
err = pci_enable_device(VORTEX_PCI(vp));
if (err) {
- printk(KERN_WARNING "%s: Could not enable device \n",
+ pr_warning("%s: Could not enable device\n",
dev->name);
goto err_out;
}
}
/* Before initializing select the active media port. */
- EL3WINDOW(3);
- config = ioread32(ioaddr + Wn3_Config);
+ config = window_read32(vp, 3, Wn3_Config);
if (vp->media_override != 7) {
- printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
+ pr_info("%s: Media override to transceiver %d (%s).\n",
dev->name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
} else if (vp->autoselect) {
if (vp->has_nway) {
if (vortex_debug > 1)
- printk(KERN_INFO "%s: using NWAY device table, not %d\n",
+ pr_info("%s: using NWAY device table, not %d\n",
dev->name, dev->if_port);
dev->if_port = XCVR_NWAY;
} else {
@@ -1525,13 +1592,13 @@ vortex_up(struct net_device *dev)
while (! (vp->available_media & media_tbl[dev->if_port].mask))
dev->if_port = media_tbl[dev->if_port].next;
if (vortex_debug > 1)
- printk(KERN_INFO "%s: first available media type: %s\n",
+ pr_info("%s: first available media type: %s\n",
dev->name, media_tbl[dev->if_port].name);
}
} else {
dev->if_port = vp->default_media;
if (vortex_debug > 1)
- printk(KERN_INFO "%s: using default media %s\n",
+ pr_info("%s: using default media %s\n",
dev->name, media_tbl[dev->if_port].name);
}
@@ -1546,17 +1613,16 @@ vortex_up(struct net_device *dev)
vp->rx_oom_timer.function = rx_oom_timer;
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Initial media type %s.\n",
+ pr_debug("%s: Initial media type %s.\n",
dev->name, media_tbl[dev->if_port].name);
vp->full_duplex = vp->mii.force_media;
config = BFINS(config, dev->if_port, 20, 4);
if (vortex_debug > 6)
- printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
- iowrite32(config, ioaddr + Wn3_Config);
+ pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config);
+ window_write32(vp, config, 3, Wn3_Config);
if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
- EL3WINDOW(4);
mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
@@ -1577,51 +1643,46 @@ vortex_up(struct net_device *dev)
iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
if (vortex_debug > 1) {
- EL3WINDOW(4);
- printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
- dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
+ pr_debug("%s: vortex_up() irq %d media status %4.4x.\n",
+ dev->name, dev->irq, window_read16(vp, 4, Wn4_Media));
}
/* Set the station address and mask in window 2 each time opened. */
- EL3WINDOW(2);
for (i = 0; i < 6; i++)
- iowrite8(dev->dev_addr[i], ioaddr + i);
+ window_write8(vp, dev->dev_addr[i], 2, i);
for (; i < 12; i+=2)
- iowrite16(0, ioaddr + i);
+ window_write16(vp, 0, 2, i);
if (vp->cb_fn_base) {
- unsigned short n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
+ unsigned short n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010;
if (vp->drv_flags & INVERT_LED_PWR)
n |= 0x10;
if (vp->drv_flags & INVERT_MII_PWR)
n |= 0x4000;
- iowrite16(n, ioaddr + Wn2_ResetOptions);
+ window_write16(vp, n, 2, Wn2_ResetOptions);
}
if (dev->if_port == XCVR_10base2)
/* Start the thinnet transceiver. We should really wait 50ms...*/
iowrite16(StartCoax, ioaddr + EL3_CMD);
if (dev->if_port != XCVR_NWAY) {
- EL3WINDOW(4);
- iowrite16((ioread16(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
- media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
+ window_write16(vp,
+ (window_read16(vp, 4, Wn4_Media) &
+ ~(Media_10TP|Media_SQE)) |
+ media_tbl[dev->if_port].media_bits,
+ 4, Wn4_Media);
}
/* Switch to the stats window, and clear all stats by reading. */
iowrite16(StatsDisable, ioaddr + EL3_CMD);
- EL3WINDOW(6);
for (i = 0; i < 10; i++)
- ioread8(ioaddr + i);
- ioread16(ioaddr + 10);
- ioread16(ioaddr + 12);
+ window_read8(vp, 6, i);
+ window_read16(vp, 6, 10);
+ window_read16(vp, 6, 12);
/* New: On the Vortex we must also clear the BadSSD counter. */
- EL3WINDOW(4);
- ioread8(ioaddr + 12);
+ window_read8(vp, 4, 12);
/* ..and on the Boomerang we enable the extra statistics bits. */
- iowrite16(0x0040, ioaddr + Wn4_NetDiag);
-
- /* Switch to register set 7 for normal use. */
- EL3WINDOW(7);
+ window_write16(vp, 0x0040, 4, Wn4_NetDiag);
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
vp->cur_rx = vp->dirty_rx = 0;
@@ -1679,14 +1740,14 @@ vortex_open(struct net_device *dev)
/* Use the now-standard shared IRQ implementation. */
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
- &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
- printk(KERN_ERR "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
+ boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
+ pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
goto err;
}
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
if (vortex_debug > 2)
- printk(KERN_DEBUG "%s: Filling in the Rx ring.\n", dev->name);
+ pr_debug("%s: Filling in the Rx ring.\n", dev->name);
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
@@ -1704,7 +1765,7 @@ vortex_open(struct net_device *dev)
}
if (i != RX_RING_SIZE) {
int j;
- printk(KERN_EMERG "%s: no memory for rx ring\n", dev->name);
+ pr_emerg("%s: no memory for rx ring\n", dev->name);
for (j = 0; j < i; j++) {
if (vp->rx_skbuff[j]) {
dev_kfree_skb(vp->rx_skbuff[j]);
@@ -1726,7 +1787,7 @@ err_free_irq:
free_irq(dev->irq, dev);
err:
if (vortex_debug > 1)
- printk(KERN_ERR "%s: vortex_open() fails: returning %d\n", dev->name, retval);
+ pr_err("%s: vortex_open() fails: returning %d\n", dev->name, retval);
out:
return retval;
}
@@ -1739,30 +1800,27 @@ vortex_timer(unsigned long data)
void __iomem *ioaddr = vp->ioaddr;
int next_tick = 60*HZ;
int ok = 0;
- int media_status, old_window;
+ int media_status;
if (vortex_debug > 2) {
- printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n",
+ pr_debug("%s: Media selection timer tick happened, %s.\n",
dev->name, media_tbl[dev->if_port].name);
- printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
+ pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
}
- disable_irq_lockdep(dev->irq);
- old_window = ioread16(ioaddr + EL3_CMD) >> 13;
- EL3WINDOW(4);
- media_status = ioread16(ioaddr + Wn4_Media);
+ media_status = window_read16(vp, 4, Wn4_Media);
switch (dev->if_port) {
case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx:
if (media_status & Media_LnkBeat) {
netif_carrier_on(dev);
ok = 1;
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
+ pr_debug("%s: Media %s has link beat, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
} else {
netif_carrier_off(dev);
if (vortex_debug > 1) {
- printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
+ pr_debug("%s: Media %s has no link beat, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
}
}
@@ -1770,20 +1828,17 @@ vortex_timer(unsigned long data)
case XCVR_MII: case XCVR_NWAY:
{
ok = 1;
- /* Interrupts are already disabled */
- spin_lock(&vp->lock);
vortex_check_media(dev, 0);
- spin_unlock(&vp->lock);
}
break;
default: /* Other media types handled by Tx timeouts. */
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media %s has no indication, %x.\n",
+ pr_debug("%s: Media %s has no indication, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
ok = 1;
}
- if (!netif_carrier_ok(dev))
+ if (dev->flags & IFF_SLAVE || !netif_carrier_ok(dev))
next_tick = 5*HZ;
if (vp->medialock)
@@ -1792,48 +1847,48 @@ vortex_timer(unsigned long data)
if (!ok) {
unsigned int config;
+ spin_lock_irq(&vp->lock);
+
do {
dev->if_port = media_tbl[dev->if_port].next;
} while ( ! (vp->available_media & media_tbl[dev->if_port].mask));
if (dev->if_port == XCVR_Default) { /* Go back to default. */
dev->if_port = vp->default_media;
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media selection failing, using default "
- "%s port.\n",
+ pr_debug("%s: Media selection failing, using default %s port.\n",
dev->name, media_tbl[dev->if_port].name);
} else {
if (vortex_debug > 1)
- printk(KERN_DEBUG "%s: Media selection failed, now trying "
- "%s port.\n",
+ pr_debug("%s: Media selection failed, now trying %s port.\n",
dev->name, media_tbl[dev->if_port].name);
next_tick = media_tbl[dev->if_port].wait;
}
- iowrite16((media_status & ~(Media_10TP|Media_SQE)) |
- media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
+ window_write16(vp,
+ (media_status & ~(Media_10TP|Media_SQE)) |
+ media_tbl[dev->if_port].media_bits,
+ 4, Wn4_Media);
- EL3WINDOW(3);
- config = ioread32(ioaddr + Wn3_Config);
+ config = window_read32(vp, 3, Wn3_Config);
config = BFINS(config, dev->if_port, 20, 4);
- iowrite32(config, ioaddr + Wn3_Config);
+ window_write32(vp, config, 3, Wn3_Config);
iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
ioaddr + EL3_CMD);
if (vortex_debug > 1)
- printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
+ pr_debug("wrote 0x%08x to Wn3_Config\n", config);
/* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */
+
+ spin_unlock_irq(&vp->lock);
}
leave_media_alone:
if (vortex_debug > 2)
- printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n",
+ pr_debug("%s: Media selection timer finished, %s.\n",
dev->name, media_tbl[dev->if_port].name);
- EL3WINDOW(old_window);
- enable_irq_lockdep(dev->irq);
mod_timer(&vp->timer, RUN_AT(next_tick));
if (vp->deferred)
iowrite16(FakeIntr, ioaddr + EL3_CMD);
- return;
}
static void vortex_tx_timeout(struct net_device *dev)
@@ -1841,21 +1896,20 @@ static void vortex_tx_timeout(struct net_device *dev)
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
- printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
+ pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
dev->name, ioread8(ioaddr + TxStatus),
ioread16(ioaddr + EL3_STATUS));
- EL3WINDOW(4);
- printk(KERN_ERR " diagnostics: net %04x media %04x dma %08x fifo %04x\n",
- ioread16(ioaddr + Wn4_NetDiag),
- ioread16(ioaddr + Wn4_Media),
+ pr_err(" diagnostics: net %04x media %04x dma %08x fifo %04x\n",
+ window_read16(vp, 4, Wn4_NetDiag),
+ window_read16(vp, 4, Wn4_Media),
ioread32(ioaddr + PktStatus),
- ioread16(ioaddr + Wn4_FIFODiag));
+ window_read16(vp, 4, Wn4_FIFODiag));
/* Slight code bloat to be user friendly. */
if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
- printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
+ pr_err("%s: Transmitter encountered 16 collisions --"
" network cable problem?\n", dev->name);
if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
- printk(KERN_ERR "%s: Interrupt posted but not delivered --"
+ pr_err("%s: Interrupt posted but not delivered --"
" IRQ blocked by another device?\n", dev->name);
/* Bad idea here.. but we might as well handle a few events. */
{
@@ -1879,7 +1933,7 @@ static void vortex_tx_timeout(struct net_device *dev)
dev->stats.tx_errors++;
if (vp->full_bus_master_tx) {
- printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
+ pr_debug("%s: Resetting the Tx ring pointer.\n", dev->name);
if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
ioaddr + DownListPtr);
@@ -1895,10 +1949,7 @@ static void vortex_tx_timeout(struct net_device *dev)
/* Issue Tx Enable */
iowrite16(TxEnable, ioaddr + EL3_CMD);
- dev->trans_start = jiffies;
-
- /* Switch to register set 7 for normal use. */
- EL3WINDOW(7);
+ dev->trans_start = jiffies; /* prevent tx timeout */
}
/*
@@ -1914,18 +1965,18 @@ vortex_error(struct net_device *dev, int status)
unsigned char tx_status = 0;
if (vortex_debug > 2) {
- printk(KERN_ERR "%s: vortex_error(), status=0x%x\n", dev->name, status);
+ pr_err("%s: vortex_error(), status=0x%x\n", dev->name, status);
}
if (status & TxComplete) { /* Really "TxError" for us. */
tx_status = ioread8(ioaddr + TxStatus);
/* Presumably a tx-timeout. We must merely re-enable. */
- if (vortex_debug > 2
- || (tx_status != 0x88 && vortex_debug > 0)) {
- printk(KERN_ERR "%s: Transmit error, Tx status register %2.2x.\n",
+ if (vortex_debug > 2 ||
+ (tx_status != 0x88 && vortex_debug > 0)) {
+ pr_err("%s: Transmit error, Tx status register %2.2x.\n",
dev->name, tx_status);
if (tx_status == 0x82) {
- printk(KERN_ERR "Probably a duplex mismatch. See "
+ pr_err("Probably a duplex mismatch. See "
"Documentation/networking/vortex.txt\n");
}
dump_tx_ring(dev);
@@ -1944,25 +1995,24 @@ vortex_error(struct net_device *dev, int status)
}
}
- if (status & RxEarly) { /* Rx early is unused. */
- vortex_rx(dev);
+ if (status & RxEarly) /* Rx early is unused. */
iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
- }
+
if (status & StatsFull) { /* Empty statistics. */
static int DoneDidThat;
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: Updating stats.\n", dev->name);
+ pr_debug("%s: Updating stats.\n", dev->name);
update_stats(ioaddr, dev);
/* HACK: Disable statistics as an interrupt source. */
/* This occurs when we have the wrong media type! */
if (DoneDidThat == 0 &&
ioread16(ioaddr + EL3_STATUS) & StatsFull) {
- printk(KERN_WARNING "%s: Updating statistics failed, disabling "
+ pr_warning("%s: Updating statistics failed, disabling "
"stats as an interrupt source.\n", dev->name);
- EL3WINDOW(5);
- iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
+ iowrite16(SetIntrEnb |
+ (window_read16(vp, 5, 10) & ~StatsFull),
+ ioaddr + EL3_CMD);
vp->intr_enable &= ~StatsFull;
- EL3WINDOW(7);
DoneDidThat++;
}
}
@@ -1972,9 +2022,8 @@ vortex_error(struct net_device *dev, int status)
}
if (status & HostError) {
u16 fifo_diag;
- EL3WINDOW(4);
- fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
- printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
+ fifo_diag = window_read16(vp, 4, Wn4_FIFODiag);
+ pr_err("%s: Host error, FIFO diagnostic register %4.4x.\n",
dev->name, fifo_diag);
/* Adapter failure requires Tx/Rx reset and reinit. */
if (vp->full_bus_master_tx) {
@@ -1982,7 +2031,7 @@ vortex_error(struct net_device *dev, int status)
/* 0x80000000 PCI master abort. */
/* 0x40000000 PCI target abort. */
if (vortex_debug)
- printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
+ pr_err("%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
/* In this case, blow the card away */
/* Must not enter D3 or we can't legally issue the reset! */
@@ -2011,7 +2060,7 @@ vortex_error(struct net_device *dev, int status)
}
}
-static int
+static netdev_tx_t
vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
@@ -2022,16 +2071,22 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (vp->bus_master) {
/* Set the bus-master controller to transfer the packet. */
int len = (skb->len + 3) & ~3;
- iowrite32(vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
- ioaddr + Wn7_MasterAddr);
+ vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len,
+ PCI_DMA_TODEVICE);
+ spin_lock_irq(&vp->window_lock);
+ window_set(vp, 7);
+ iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr);
iowrite16(len, ioaddr + Wn7_MasterLen);
+ spin_unlock_irq(&vp->window_lock);
vp->tx_skb = skb;
+ skb_tx_timestamp(skb);
iowrite16(StartDMADown, ioaddr + EL3_CMD);
/* netif_wake_queue() will be called at the DMADone interrupt. */
} else {
/* ... and the packet rounded to a doubleword. */
+ skb_tx_timestamp(skb);
iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
- dev_kfree_skb (skb);
+ dev_consume_skb_any (skb);
if (ioread16(ioaddr + TxFree) > 1536) {
netif_start_queue (dev); /* AKPM: redundant? */
} else {
@@ -2041,7 +2096,6 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- dev->trans_start = jiffies;
/* Clear the Tx status stack. */
{
@@ -2051,7 +2105,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
while (--i > 0 && (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
if (vortex_debug > 2)
- printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
+ pr_debug("%s: Tx error, status %2.2x.\n",
dev->name, tx_status);
if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
@@ -2063,10 +2117,10 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
}
}
- return 0;
+ return NETDEV_TX_OK;
}
-static int
+static netdev_tx_t
boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
@@ -2077,17 +2131,26 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
if (vortex_debug > 6) {
- printk(KERN_DEBUG "boomerang_start_xmit()\n");
- printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
+ pr_debug("boomerang_start_xmit()\n");
+ pr_debug("%s: Trying to send a packet, Tx index %d.\n",
dev->name, vp->cur_tx);
}
+ /*
+ * We can't allow a recursion from our interrupt handler back into the
+ * tx routine, as they take the same spin lock, and that causes
+ * deadlock. Just return NETDEV_TX_BUSY and let the stack try again in
+ * a bit
+ */
+ if (vp->handling_irq)
+ return NETDEV_TX_BUSY;
+
if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
if (vortex_debug > 0)
- printk(KERN_WARNING "%s: BUG! Tx Ring full, refusing to send buffer.\n",
+ pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
dev->name);
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
vp->tx_skbuff[entry] = skb;
@@ -2107,21 +2170,22 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
int i;
vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
- skb->len-skb->data_len, PCI_DMA_TODEVICE));
- vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len-skb->data_len);
+ skb_headlen(skb), PCI_DMA_TODEVICE));
+ vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
vp->tx_ring[entry].frag[i+1].addr =
- cpu_to_le32(pci_map_single(VORTEX_PCI(vp),
- (void*)page_address(frag->page) + frag->page_offset,
- frag->size, PCI_DMA_TODEVICE));
+ cpu_to_le32(pci_map_single(
+ VORTEX_PCI(vp),
+ (void *)skb_frag_address(frag),
+ skb_frag_size(frag), PCI_DMA_TODEVICE));
if (i == skb_shinfo(skb)->nr_frags-1)
- vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(frag->size|LAST_FRAG);
+ vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG);
else
- vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(frag->size);
+ vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag));
}
}
#else
@@ -2150,10 +2214,10 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
#endif
}
+ skb_tx_timestamp(skb);
iowrite16(DownUnstall, ioaddr + EL3_CMD);
spin_unlock_irqrestore(&vp->lock, flags);
- dev->trans_start = jiffies;
- return 0;
+ return NETDEV_TX_OK;
}
/* The interrupt handler does all of the Rx thread work and cleans up
@@ -2180,7 +2244,7 @@ vortex_interrupt(int irq, void *dev_id)
status = ioread16(ioaddr + EL3_STATUS);
if (vortex_debug > 6)
- printk("vortex_interrupt(). status=0x%4x\n", status);
+ pr_debug("vortex_interrupt(). status=0x%4x\n", status);
if ((status & IntLatch) == 0)
goto handler_exit; /* No interrupt: shared IRQs cause this */
@@ -2195,19 +2259,22 @@ vortex_interrupt(int irq, void *dev_id)
goto handler_exit;
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
+ pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
dev->name, status, ioread8(ioaddr + Timer));
+ spin_lock(&vp->window_lock);
+ window_set(vp, 7);
+
do {
if (vortex_debug > 5)
- printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
+ pr_debug("%s: In interrupt loop, status %4.4x.\n",
dev->name, status);
if (status & RxComplete)
vortex_rx(dev);
if (status & TxAvailable) {
if (vortex_debug > 5)
- printk(KERN_DEBUG " TX room bit was handled.\n");
+ pr_debug(" TX room bit was handled.\n");
/* There's room in the FIFO for a full-sized packet. */
iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
netif_wake_queue (dev);
@@ -2235,12 +2302,17 @@ vortex_interrupt(int irq, void *dev_id)
if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) {
if (status == 0xffff)
break;
+ if (status & RxEarly)
+ vortex_rx(dev);
+ spin_unlock(&vp->window_lock);
vortex_error(dev, status);
+ spin_lock(&vp->window_lock);
+ window_set(vp, 7);
}
if (--work_done < 0) {
- printk(KERN_WARNING "%s: Too much work in interrupt, status "
- "%4.4x.\n", dev->name, status);
+ pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
+ dev->name, status);
/* Disable all pending interrupts. */
do {
vp->deferred |= status;
@@ -2256,8 +2328,10 @@ vortex_interrupt(int irq, void *dev_id)
iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+ spin_unlock(&vp->window_lock);
+
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
+ pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, status);
handler_exit:
spin_unlock(&vp->lock);
@@ -2280,23 +2354,25 @@ boomerang_interrupt(int irq, void *dev_id)
ioaddr = vp->ioaddr;
+
/*
* It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
* and boomerang_start_xmit
*/
spin_lock(&vp->lock);
+ vp->handling_irq = 1;
status = ioread16(ioaddr + EL3_STATUS);
if (vortex_debug > 6)
- printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
+ pr_debug("boomerang_interrupt. status=0x%4x\n", status);
if ((status & IntLatch) == 0)
goto handler_exit; /* No interrupt: shared IRQs can cause this */
if (status == 0xffff) { /* h/w no longer present (hotplug)? */
if (vortex_debug > 1)
- printk(KERN_DEBUG "boomerang_interrupt(1): status = 0xffff\n");
+ pr_debug("boomerang_interrupt(1): status = 0xffff\n");
goto handler_exit;
}
@@ -2306,16 +2382,16 @@ boomerang_interrupt(int irq, void *dev_id)
}
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
+ pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
dev->name, status, ioread8(ioaddr + Timer));
do {
if (vortex_debug > 5)
- printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
+ pr_debug("%s: In interrupt loop, status %4.4x.\n",
dev->name, status);
if (status & UpComplete) {
iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
if (vortex_debug > 5)
- printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
+ pr_debug("boomerang_interrupt->boomerang_rx\n");
boomerang_rx(dev);
}
@@ -2350,7 +2426,7 @@ boomerang_interrupt(int irq, void *dev_id)
dev_kfree_skb_irq(skb);
vp->tx_skbuff[entry] = NULL;
} else {
- printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
+ pr_debug("boomerang_interrupt: no skb!\n");
}
/* dev->stats.tx_packets++; Counted below. */
dirty_tx++;
@@ -2358,7 +2434,7 @@ boomerang_interrupt(int irq, void *dev_id)
vp->dirty_tx = dirty_tx;
if (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1) {
if (vortex_debug > 6)
- printk(KERN_DEBUG "boomerang_interrupt: wake queue\n");
+ pr_debug("boomerang_interrupt: wake queue\n");
netif_wake_queue (dev);
}
}
@@ -2368,8 +2444,8 @@ boomerang_interrupt(int irq, void *dev_id)
vortex_error(dev, status);
if (--work_done < 0) {
- printk(KERN_WARNING "%s: Too much work in interrupt, status "
- "%4.4x.\n", dev->name, status);
+ pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
+ dev->name, status);
/* Disable all pending interrupts. */
do {
vp->deferred |= status;
@@ -2389,9 +2465,10 @@ boomerang_interrupt(int irq, void *dev_id)
} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
if (vortex_debug > 4)
- printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
+ pr_debug("%s: exiting interrupt, status %4.4x.\n",
dev->name, status);
handler_exit:
+ vp->handling_irq = 0;
spin_unlock(&vp->lock);
return IRQ_HANDLED;
}
@@ -2404,13 +2481,13 @@ static int vortex_rx(struct net_device *dev)
short rx_status;
if (vortex_debug > 5)
- printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
+ pr_debug("vortex_rx(): status %4.4x, rx_status %4.4x.\n",
ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
if (rx_status & 0x4000) { /* Error, update stats. */
unsigned char rx_error = ioread8(ioaddr + RxErrors);
if (vortex_debug > 2)
- printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
+ pr_debug(" Rx error: status %2.2x.\n", rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01) dev->stats.rx_over_errors++;
if (rx_error & 0x02) dev->stats.rx_length_errors++;
@@ -2422,9 +2499,9 @@ static int vortex_rx(struct net_device *dev)
int pkt_len = rx_status & 0x1fff;
struct sk_buff *skb;
- skb = dev_alloc_skb(pkt_len + 5);
+ skb = netdev_alloc_skb(dev, pkt_len + 5);
if (vortex_debug > 4)
- printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
if (skb != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
@@ -2447,7 +2524,6 @@ static int vortex_rx(struct net_device *dev)
iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
/* Wait a limited time to go to next packet. */
for (i = 200; i >= 0; i--)
@@ -2455,8 +2531,8 @@ static int vortex_rx(struct net_device *dev)
break;
continue;
} else if (vortex_debug > 0)
- printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
- "size %d.\n", dev->name, pkt_len);
+ pr_notice("%s: No memory to allocate a sk_buff of size %d.\n",
+ dev->name, pkt_len);
dev->stats.rx_dropped++;
}
issue_and_wait(dev, RxDiscard);
@@ -2475,7 +2551,7 @@ boomerang_rx(struct net_device *dev)
int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
if (vortex_debug > 5)
- printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
+ pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
if (--rx_work_limit < 0)
@@ -2483,7 +2559,7 @@ boomerang_rx(struct net_device *dev)
if (rx_status & RxDError) { /* Error, update stats. */
unsigned char rx_error = rx_status >> 16;
if (vortex_debug > 2)
- printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
+ pr_debug(" Rx error: status %2.2x.\n", rx_error);
dev->stats.rx_errors++;
if (rx_error & 0x01) dev->stats.rx_over_errors++;
if (rx_error & 0x02) dev->stats.rx_length_errors++;
@@ -2497,12 +2573,13 @@ boomerang_rx(struct net_device *dev)
dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
if (vortex_debug > 4)
- printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
+ pr_debug("Receiving packet size %d status %4.4x.\n",
pkt_len, rx_status);
/* Check if the packet is long enough to just accept without
copying to a properly sized skbuff. */
- if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+ if (pkt_len < rx_copybreak &&
+ (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
/* 'skb_put()' points to the start of sk_buff data area. */
@@ -2530,7 +2607,6 @@ boomerang_rx(struct net_device *dev)
}
}
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
}
entry = (++vp->cur_rx) % RX_RING_SIZE;
@@ -2540,11 +2616,11 @@ boomerang_rx(struct net_device *dev)
struct sk_buff *skb;
entry = vp->dirty_rx % RX_RING_SIZE;
if (vp->rx_skbuff[entry] == NULL) {
- skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
+ skb = netdev_alloc_skb_ip_align(dev, PKT_BUF_SZ);
if (skb == NULL) {
static unsigned long last_jif;
if (time_after(jiffies, last_jif + 10 * HZ)) {
- printk(KERN_WARNING "%s: memory shortage\n", dev->name);
+ pr_warning("%s: memory shortage\n", dev->name);
last_jif = jiffies;
}
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
@@ -2552,7 +2628,6 @@ boomerang_rx(struct net_device *dev)
break; /* Bad news! */
}
- skb_reserve(skb, NET_IP_ALIGN);
vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
vp->rx_skbuff[entry] = skb;
}
@@ -2576,7 +2651,7 @@ rx_oom_timer(unsigned long arg)
if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE) /* This test is redundant, but makes me feel good */
boomerang_rx(dev);
if (vortex_debug > 1) {
- printk(KERN_DEBUG "%s: rx_oom_timer %s\n", dev->name,
+ pr_debug("%s: rx_oom_timer %s\n", dev->name,
((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying");
}
spin_unlock_irq(&vp->lock);
@@ -2633,9 +2708,9 @@ vortex_close(struct net_device *dev)
vortex_down(dev, 1);
if (vortex_debug > 1) {
- printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
+ pr_debug("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
- printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
+ pr_debug("%s: vortex close stats: rx_nocopy %d rx_copy %d"
" tx_queued %d Rx pre-checksummed %d.\n",
dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
}
@@ -2644,8 +2719,7 @@ vortex_close(struct net_device *dev)
if (vp->rx_csumhits &&
(vp->drv_flags & HAS_HWCKSM) == 0 &&
(vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
- printk(KERN_WARNING "%s supports hardware checksums, and we're "
- "not using them!\n", dev->name);
+ pr_warning("%s supports hardware checksums, and we're not using them!\n", dev->name);
}
#endif
@@ -2695,22 +2769,24 @@ dump_tx_ring(struct net_device *dev)
int i;
int stalled = ioread32(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
- printk(KERN_ERR " Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
+ pr_err(" Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
vp->full_bus_master_tx,
vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
- printk(KERN_ERR " Transmit list %8.8x vs. %p.\n",
+ pr_err(" Transmit list %8.8x vs. %p.\n",
ioread32(ioaddr + DownListPtr),
&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
issue_and_wait(dev, DownStall);
for (i = 0; i < TX_RING_SIZE; i++) {
- printk(KERN_ERR " %d: @%p length %8.8x status %8.8x\n", i,
- &vp->tx_ring[i],
+ unsigned int length;
+
#if DO_ZEROCOPY
- le32_to_cpu(vp->tx_ring[i].frag[0].length),
+ length = le32_to_cpu(vp->tx_ring[i].frag[0].length);
#else
- le32_to_cpu(vp->tx_ring[i].length),
+ length = le32_to_cpu(vp->tx_ring[i].length);
#endif
+ pr_err(" %d: @%p length %8.8x status %8.8x\n",
+ i, &vp->tx_ring[i], length,
le32_to_cpu(vp->tx_ring[i].status));
}
if (!stalled)
@@ -2743,86 +2819,58 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev)
static void update_stats(void __iomem *ioaddr, struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- int old_window = ioread16(ioaddr + EL3_CMD);
- if (old_window == 0xffff) /* Chip suspended or ejected. */
- return;
/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
/* Switch to the stats window, and read everything. */
- EL3WINDOW(6);
- dev->stats.tx_carrier_errors += ioread8(ioaddr + 0);
- dev->stats.tx_heartbeat_errors += ioread8(ioaddr + 1);
- dev->stats.tx_window_errors += ioread8(ioaddr + 4);
- dev->stats.rx_fifo_errors += ioread8(ioaddr + 5);
- dev->stats.tx_packets += ioread8(ioaddr + 6);
- dev->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4;
- /* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */
+ dev->stats.tx_carrier_errors += window_read8(vp, 6, 0);
+ dev->stats.tx_heartbeat_errors += window_read8(vp, 6, 1);
+ dev->stats.tx_window_errors += window_read8(vp, 6, 4);
+ dev->stats.rx_fifo_errors += window_read8(vp, 6, 5);
+ dev->stats.tx_packets += window_read8(vp, 6, 6);
+ dev->stats.tx_packets += (window_read8(vp, 6, 9) &
+ 0x30) << 4;
+ /* Rx packets */ window_read8(vp, 6, 7); /* Must read to clear */
/* Don't bother with register 9, an extension of registers 6&7.
If we do use the 6&7 values the atomic update assumption above
is invalid. */
- dev->stats.rx_bytes += ioread16(ioaddr + 10);
- dev->stats.tx_bytes += ioread16(ioaddr + 12);
+ dev->stats.rx_bytes += window_read16(vp, 6, 10);
+ dev->stats.tx_bytes += window_read16(vp, 6, 12);
/* Extra stats for get_ethtool_stats() */
- vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2);
- vp->xstats.tx_single_collisions += ioread8(ioaddr + 3);
- vp->xstats.tx_deferred += ioread8(ioaddr + 8);
- EL3WINDOW(4);
- vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12);
+ vp->xstats.tx_multiple_collisions += window_read8(vp, 6, 2);
+ vp->xstats.tx_single_collisions += window_read8(vp, 6, 3);
+ vp->xstats.tx_deferred += window_read8(vp, 6, 8);
+ vp->xstats.rx_bad_ssd += window_read8(vp, 4, 12);
dev->stats.collisions = vp->xstats.tx_multiple_collisions
+ vp->xstats.tx_single_collisions
+ vp->xstats.tx_max_collisions;
{
- u8 up = ioread8(ioaddr + 13);
+ u8 up = window_read8(vp, 4, 13);
dev->stats.rx_bytes += (up & 0x0f) << 16;
dev->stats.tx_bytes += (up & 0xf0) << 12;
}
-
- EL3WINDOW(old_window >> 13);
- return;
}
static int vortex_nway_reset(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
- unsigned long flags;
- int rc;
- spin_lock_irqsave(&vp->lock, flags);
- EL3WINDOW(4);
- rc = mii_nway_restart(&vp->mii);
- spin_unlock_irqrestore(&vp->lock, flags);
- return rc;
+ return mii_nway_restart(&vp->mii);
}
static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
- unsigned long flags;
- int rc;
- spin_lock_irqsave(&vp->lock, flags);
- EL3WINDOW(4);
- rc = mii_ethtool_gset(&vp->mii, cmd);
- spin_unlock_irqrestore(&vp->lock, flags);
- return rc;
+ return mii_ethtool_gset(&vp->mii, cmd);
}
static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
- unsigned long flags;
- int rc;
- spin_lock_irqsave(&vp->lock, flags);
- EL3WINDOW(4);
- rc = mii_ethtool_sset(&vp->mii, cmd);
- spin_unlock_irqrestore(&vp->lock, flags);
- return rc;
+ return mii_ethtool_sset(&vp->mii, cmd);
}
static u32 vortex_get_msglevel(struct net_device *dev)
@@ -2881,18 +2929,53 @@ static void vortex_get_drvinfo(struct net_device *dev,
{
struct vortex_private *vp = netdev_priv(dev);
- strcpy(info->driver, DRV_NAME);
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
if (VORTEX_PCI(vp)) {
- strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
+ strlcpy(info->bus_info, pci_name(VORTEX_PCI(vp)),
+ sizeof(info->bus_info));
} else {
if (VORTEX_EISA(vp))
- sprintf(info->bus_info, vp->gendev->bus_id);
+ strlcpy(info->bus_info, dev_name(vp->gendev),
+ sizeof(info->bus_info));
else
- sprintf(info->bus_info, "EISA 0x%lx %d",
- dev->base_addr, dev->irq);
+ snprintf(info->bus_info, sizeof(info->bus_info),
+ "EISA 0x%lx %d", dev->base_addr, dev->irq);
}
}
+static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct vortex_private *vp = netdev_priv(dev);
+
+ if (!VORTEX_PCI(vp))
+ return;
+
+ wol->supported = WAKE_MAGIC;
+
+ wol->wolopts = 0;
+ if (vp->enable_wol)
+ wol->wolopts |= WAKE_MAGIC;
+}
+
+static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct vortex_private *vp = netdev_priv(dev);
+
+ if (!VORTEX_PCI(vp))
+ return -EOPNOTSUPP;
+
+ if (wol->wolopts & ~WAKE_MAGIC)
+ return -EINVAL;
+
+ if (wol->wolopts & WAKE_MAGIC)
+ vp->enable_wol = 1;
+ else
+ vp->enable_wol = 0;
+ acpi_set_WOL(dev);
+
+ return 0;
+}
+
static const struct ethtool_ops vortex_ethtool_ops = {
.get_drvinfo = vortex_get_drvinfo,
.get_strings = vortex_get_strings,
@@ -2904,6 +2987,9 @@ static const struct ethtool_ops vortex_ethtool_ops = {
.set_settings = vortex_set_settings,
.get_link = ethtool_op_get_link,
.nway_reset = vortex_nway_reset,
+ .get_wol = vortex_get_wol,
+ .set_wol = vortex_set_wol,
+ .get_ts_info = ethtool_op_get_ts_info,
};
#ifdef CONFIG_PCI
@@ -2914,8 +3000,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
int err;
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
- unsigned long flags;
pci_power_t state = 0;
if(VORTEX_PCI(vp))
@@ -2925,10 +3009,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if(state != 0)
pci_set_power_state(VORTEX_PCI(vp), PCI_D0);
- spin_lock_irqsave(&vp->lock, flags);
- EL3WINDOW(4);
err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL);
- spin_unlock_irqrestore(&vp->lock, flags);
if(state != 0)
pci_set_power_state(VORTEX_PCI(vp), state);
@@ -2948,9 +3029,9 @@ static void set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC) {
if (vortex_debug > 3)
- printk(KERN_NOTICE "%s: Setting promiscuous mode.\n", dev->name);
+ pr_notice("%s: Setting promiscuous mode.\n", dev->name);
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
- } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
+ } else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
} else
new_mode = SetRxFilter | RxStation | RxBroadcast;
@@ -2969,8 +3050,6 @@ static void set_rx_mode(struct net_device *dev)
static void set_8021q_mode(struct net_device *dev, int enable)
{
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
- int old_window = ioread16(ioaddr + EL3_CMD);
int mac_ctrl;
if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
@@ -2981,28 +3060,23 @@ static void set_8021q_mode(struct net_device *dev, int enable)
if (enable)
max_pkt_size += 4; /* 802.1Q VLAN tag */
- EL3WINDOW(3);
- iowrite16(max_pkt_size, ioaddr+Wn3_MaxPktSize);
+ window_write16(vp, max_pkt_size, 3, Wn3_MaxPktSize);
/* set VlanEtherType to let the hardware checksumming
treat tagged frames correctly */
- EL3WINDOW(7);
- iowrite16(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
+ window_write16(vp, VLAN_ETHER_TYPE, 7, Wn7_VlanEtherType);
} else {
/* on older cards we have to enable large frames */
vp->large_frames = dev->mtu > 1500 || enable;
- EL3WINDOW(3);
- mac_ctrl = ioread16(ioaddr+Wn3_MAC_Ctrl);
+ mac_ctrl = window_read16(vp, 3, Wn3_MAC_Ctrl);
if (vp->large_frames)
mac_ctrl |= 0x40;
else
mac_ctrl &= ~0x40;
- iowrite16(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
+ window_write16(vp, mac_ctrl, 3, Wn3_MAC_Ctrl);
}
-
- EL3WINDOW(old_window);
}
#else
@@ -3021,7 +3095,10 @@ static void set_8021q_mode(struct net_device *dev, int enable)
/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
met by back-to-back PCI I/O cycles, but we insert a delay to avoid
"overclocking" issues. */
-#define mdio_delay() ioread32(mdio_addr)
+static void mdio_delay(struct vortex_private *vp)
+{
+ window_read32(vp, 4, Wn4_PhysicalMgmt);
+}
#define MDIO_SHIFT_CLK 0x01
#define MDIO_DIR_WRITE 0x04
@@ -3032,16 +3109,15 @@ static void set_8021q_mode(struct net_device *dev, int enable)
/* Generate the preamble required for initial synchronization and
a few older transceivers. */
-static void mdio_sync(void __iomem *ioaddr, int bits)
+static void mdio_sync(struct vortex_private *vp, int bits)
{
- void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
-
/* Establish sync by sending at least 32 logic ones. */
while (-- bits >= 0) {
- iowrite16(MDIO_DATA_WRITE1, mdio_addr);
- mdio_delay();
- iowrite16(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
- mdio_delay();
+ window_write16(vp, MDIO_DATA_WRITE1, 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
+ window_write16(vp, MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK,
+ 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
}
}
@@ -3049,60 +3125,70 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
{
int i;
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
unsigned int retval = 0;
- void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+
+ spin_lock_bh(&vp->mii_lock);
if (mii_preamble_required)
- mdio_sync(ioaddr, 32);
+ mdio_sync(vp, 32);
/* Shift the read command bits out. */
for (i = 14; i >= 0; i--) {
int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
- iowrite16(dataval, mdio_addr);
- mdio_delay();
- iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
- mdio_delay();
+ window_write16(vp, dataval, 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
+ window_write16(vp, dataval | MDIO_SHIFT_CLK,
+ 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
}
/* Read the two transition, 16 data, and wire-idle bits. */
for (i = 19; i > 0; i--) {
- iowrite16(MDIO_ENB_IN, mdio_addr);
- mdio_delay();
- retval = (retval << 1) | ((ioread16(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
- iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
- mdio_delay();
+ window_write16(vp, MDIO_ENB_IN, 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
+ retval = (retval << 1) |
+ ((window_read16(vp, 4, Wn4_PhysicalMgmt) &
+ MDIO_DATA_READ) ? 1 : 0);
+ window_write16(vp, MDIO_ENB_IN | MDIO_SHIFT_CLK,
+ 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
}
+
+ spin_unlock_bh(&vp->mii_lock);
+
return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
}
static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
struct vortex_private *vp = netdev_priv(dev);
- void __iomem *ioaddr = vp->ioaddr;
int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
- void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
int i;
+ spin_lock_bh(&vp->mii_lock);
+
if (mii_preamble_required)
- mdio_sync(ioaddr, 32);
+ mdio_sync(vp, 32);
/* Shift the command bits out. */
for (i = 31; i >= 0; i--) {
int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
- iowrite16(dataval, mdio_addr);
- mdio_delay();
- iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
- mdio_delay();
+ window_write16(vp, dataval, 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
+ window_write16(vp, dataval | MDIO_SHIFT_CLK,
+ 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
}
/* Leave the interface idle. */
for (i = 1; i >= 0; i--) {
- iowrite16(MDIO_ENB_IN, mdio_addr);
- mdio_delay();
- iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
- mdio_delay();
+ window_write16(vp, MDIO_ENB_IN, 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
+ window_write16(vp, MDIO_ENB_IN | MDIO_SHIFT_CLK,
+ 4, Wn4_PhysicalMgmt);
+ mdio_delay(vp);
}
- return;
+
+ spin_unlock_bh(&vp->mii_lock);
}
/* ACPI: Advanced Configuration and Power Interface. */
@@ -3112,64 +3198,67 @@ static void acpi_set_WOL(struct net_device *dev)
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
+ device_set_wakeup_enable(vp->gendev, vp->enable_wol);
+
if (vp->enable_wol) {
/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
- EL3WINDOW(7);
- iowrite16(2, ioaddr + 0x0c);
+ window_write16(vp, 2, 7, 0x0c);
/* The RxFilter must accept the WOL frames. */
iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
iowrite16(RxEnable, ioaddr + EL3_CMD);
if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
- printk(KERN_INFO "%s: WOL not supported.\n",
- pci_name(VORTEX_PCI(vp)));
+ pr_info("%s: WOL not supported.\n", pci_name(VORTEX_PCI(vp)));
vp->enable_wol = 0;
return;
}
+ if (VORTEX_PCI(vp)->current_state < PCI_D3hot)
+ return;
+
/* Change the power state to D3; RxEnable doesn't take effect. */
pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
}
}
-static void __devexit vortex_remove_one(struct pci_dev *pdev)
+static void vortex_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct vortex_private *vp;
if (!dev) {
- printk("vortex_remove_one called for Compaq device!\n");
+ pr_err("vortex_remove_one called for Compaq device!\n");
BUG();
}
vp = netdev_priv(dev);
if (vp->cb_fn_base)
- pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
+ pci_iounmap(pdev, vp->cb_fn_base);
unregister_netdev(dev);
- if (VORTEX_PCI(vp)) {
- pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */
- if (vp->pm_state_valid)
- pci_restore_state(VORTEX_PCI(vp));
- pci_disable_device(VORTEX_PCI(vp));
- }
+ pci_set_power_state(pdev, PCI_D0); /* Go active */
+ if (vp->pm_state_valid)
+ pci_restore_state(pdev);
+ pci_disable_device(pdev);
+
/* Should really use issue_and_wait() here */
iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
vp->ioaddr + EL3_CMD);
- pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
+ pci_iounmap(pdev, vp->ioaddr);
pci_free_consistent(pdev,
sizeof(struct boom_rx_desc) * RX_RING_SIZE
+ sizeof(struct boom_tx_desc) * TX_RING_SIZE,
vp->rx_ring,
vp->rx_ring_dma);
- if (vp->must_free_region)
- release_region(dev->base_addr, vp->io_size);
+
+ pci_release_regions(pdev);
+
free_netdev(dev);
}
@@ -3177,12 +3266,9 @@ static void __devexit vortex_remove_one(struct pci_dev *pdev)
static struct pci_driver vortex_driver = {
.name = "3c59x",
.probe = vortex_init_one,
- .remove = __devexit_p(vortex_remove_one),
+ .remove = vortex_remove_one,
.id_table = vortex_pci_tbl,
-#ifdef CONFIG_PM
- .suspend = vortex_suspend,
- .resume = vortex_resume,
-#endif
+ .driver.pm = VORTEX_PM_OPS,
};
@@ -3208,7 +3294,6 @@ static int __init vortex_init(void)
static void __exit vortex_eisa_cleanup(void)
{
- struct vortex_private *vp;
void __iomem *ioaddr;
#ifdef CONFIG_EISA
@@ -3217,7 +3302,6 @@ static void __exit vortex_eisa_cleanup(void)
#endif
if (compaq_net_device) {
- vp = compaq_net_device->priv;
ioaddr = ioport_map(compaq_net_device->base_addr,
VORTEX_TOTAL_SIZE);
diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig
new file mode 100644
index 00000000000..afaab4b2333
--- /dev/null
+++ b/drivers/net/ethernet/3com/Kconfig
@@ -0,0 +1,107 @@
+#
+# 3Com Ethernet device configuration
+#
+
+config NET_VENDOR_3COM
+ bool "3Com devices"
+ default y
+ depends on ISA || EISA || PCI || PCMCIA
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about 3Com cards. If you say Y, you will be asked for
+ your specific card in the following questions.
+
+if NET_VENDOR_3COM
+
+config EL3
+ tristate "3c509/3c579 \"EtherLink III\" support"
+ depends on (ISA || EISA)
+ ---help---
+ If you have a network (Ethernet) card belonging to the 3Com
+ EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
+ from <http://www.tldp.org/docs.html#howto>.
+
+ If your card is not working you may need to use the DOS
+ setup disk to disable Plug & Play mode, and to select the default
+ media type.
+
+ To compile this driver as a module, choose M here. The module
+ will be called 3c509.
+
+config 3C515
+ tristate "3c515 ISA \"Fast EtherLink\""
+ depends on ISA && ISA_DMA_API
+ ---help---
+ If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
+ network card, say Y and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called 3c515.
+
+config PCMCIA_3C574
+ tristate "3Com 3c574 PCMCIA support"
+ depends on PCMCIA
+ ---help---
+ Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA
+ (PC-card) Fast Ethernet card to your computer.
+
+ To compile this driver as a module, choose M here: the module will be
+ called 3c574_cs. If unsure, say N.
+
+config PCMCIA_3C589
+ tristate "3Com 3c589 PCMCIA support"
+ depends on PCMCIA
+ ---help---
+ Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA
+ (PC-card) Ethernet card to your computer.
+
+ To compile this driver as a module, choose M here: the module will be
+ called 3c589_cs. If unsure, say N.
+
+config VORTEX
+ tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
+ depends on (PCI || EISA) && HAS_IOPORT_MAP
+ select MII
+ ---help---
+ This option enables driver support for a large number of 10Mbps and
+ 10/100Mbps EISA, PCI and Cardbus 3Com network cards:
+
+ "Vortex" (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
+ "Boomerang" (EtherLink XL 3c900 or 3c905) PCI
+ "Cyclone" (3c540/3c900/3c905/3c980/3c575/3c656) PCI and Cardbus
+ "Tornado" (3c905) PCI
+ "Hurricane" (3c555/3cSOHO) PCI
+
+ If you have such a card, say Y and read the Ethernet-HOWTO,
+ available from <http://www.tldp.org/docs.html#howto>. More
+ specific information is in
+ <file:Documentation/networking/vortex.txt> and in the comments at
+ the beginning of <file:drivers/net/ethernet/3com/3c59x.c>.
+
+ To compile this support as a module, choose M here.
+
+config TYPHOON
+ tristate "3cr990 series \"Typhoon\" support"
+ depends on PCI
+ select CRC32
+ ---help---
+ This option enables driver support for the 3cr990 series of cards:
+
+ 3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
+ 3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server,
+ 3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR
+
+ If you have a network (Ethernet) card of this type, say Y and read
+ the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called typhoon.
+
+endif # NET_VENDOR_3COM
diff --git a/drivers/net/ethernet/3com/Makefile b/drivers/net/ethernet/3com/Makefile
new file mode 100644
index 00000000000..74046afab99
--- /dev/null
+++ b/drivers/net/ethernet/3com/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the 3Com Ethernet device drivers
+#
+
+obj-$(CONFIG_EL3) += 3c509.o
+obj-$(CONFIG_3C515) += 3c515.o
+obj-$(CONFIG_PCMCIA_3C589) += 3c589_cs.o
+obj-$(CONFIG_PCMCIA_3C574) += 3c574_cs.o
+obj-$(CONFIG_VORTEX) += 3c59x.o
+obj-$(CONFIG_TYPHOON) += typhoon.o
diff --git a/drivers/net/typhoon.c b/drivers/net/ethernet/3com/typhoon.c
index 734ce0977f0..e13b04624de 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/ethernet/3com/typhoon.c
@@ -24,10 +24,6 @@
3XP Processor. It has been tested on x86 and sparc64.
KNOWN ISSUES:
- *) The current firmware always strips the VLAN tag off, even if
- we tell it not to. You should filter VLANs at the switch
- as a workaround (good practice in any event) until we can
- get this fixed.
*) Cannot DMA Rx packets to a 2 byte aligned address. Also firmware
issue. Hopefully 3Com will fix it.
*) Waiting for a command response takes 8ms due to non-preemptable
@@ -98,20 +94,17 @@ static const int multicast_filter_limit = 32;
#define TX_TIMEOUT (2*HZ)
#define PKT_BUF_SZ 1536
+#define FIRMWARE_NAME "3com/typhoon.bin"
-#define DRV_MODULE_NAME "typhoon"
-#define DRV_MODULE_VERSION "1.5.8"
-#define DRV_MODULE_RELDATE "06/11/09"
-#define PFX DRV_MODULE_NAME ": "
-#define ERR_PFX KERN_ERR PFX
+#define pr_fmt(fmt) KBUILD_MODNAME " " fmt
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@@ -129,16 +122,14 @@ static const int multicast_filter_limit = 32;
#include <asm/uaccess.h>
#include <linux/in6.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include "typhoon.h"
-#include "typhoon-firmware.h"
-
-static char version[] __devinitdata =
- "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
-MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE_NAME);
MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
MODULE_PARM_DESC(rx_copybreak, "Packets smaller than this are copied and "
"the buffer given back to the NIC. Default "
@@ -158,8 +149,8 @@ module_param(use_mmio, int, 0);
#endif
struct typhoon_card_info {
- char *name;
- int capabilities;
+ const char *name;
+ const int capabilities;
};
#define TYPHOON_CRYPTO_NONE 0x00
@@ -177,7 +168,7 @@ enum typhoon_cards {
};
/* directly indexed by enum typhoon_cards, above */
-static struct typhoon_card_info typhoon_card_info[] __devinitdata = {
+static struct typhoon_card_info typhoon_card_info[] = {
{ "3Com Typhoon (3C990-TX)",
TYPHOON_CRYPTO_NONE},
{ "3Com Typhoon (3CR990-TX-95)",
@@ -212,7 +203,7 @@ static struct typhoon_card_info typhoon_card_info[] __devinitdata = {
* bit 8 indicates if this is a (0) copper or (1) fiber card
* bits 12-16 indicate card type: (0) client and (1) server
*/
-static struct pci_device_id typhoon_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(typhoon_pci_tbl) = {
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,TYPHOON_TX },
{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_95,
@@ -259,7 +250,7 @@ struct typhoon_shared {
struct rx_free rxBuff[RXFREE_ENTRIES] __3xp_aligned;
u32 zeroWord;
struct tx_desc txHi[TXHI_ENTRIES];
-} __attribute__ ((packed));
+} __packed;
struct rxbuff_ent {
struct sk_buff *skb;
@@ -284,8 +275,6 @@ struct typhoon {
struct pci_dev * pdev;
struct net_device * dev;
struct napi_struct napi;
- spinlock_t state_lock;
- struct vlan_group * vlgrp;
struct basic_ring rxHiRing;
struct basic_ring rxBuffRing;
struct rxbuff_ent rxbuffers[RXENT_ENTRIES];
@@ -296,7 +285,6 @@ struct typhoon {
struct basic_ring respRing;
struct net_device_stats stats;
struct net_device_stats stats_saved;
- const char * name;
struct typhoon_shared * shared;
dma_addr_t shared_dma;
__le16 xcvr_select;
@@ -376,7 +364,7 @@ typhoon_inc_rxfree_index(u32 *index, const int count)
static inline void
typhoon_inc_tx_index(u32 *index, const int count)
{
- /* if we start using the Hi Tx ring, this needs updateing */
+ /* if we start using the Hi Tx ring, this needs updating */
typhoon_inc_index(index, count, TXLO_ENTRIES);
}
@@ -484,7 +472,7 @@ typhoon_hello(struct typhoon *tp)
typhoon_inc_cmd_index(&ring->lastWrite, 1);
INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
- smp_wmb();
+ wmb();
iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
spin_unlock(&tp->command_lock);
}
@@ -531,13 +519,13 @@ typhoon_process_response(struct typhoon *tp, int resp_size,
} else if(resp->cmd == TYPHOON_CMD_HELLO_RESP) {
typhoon_hello(tp);
} else {
- printk(KERN_ERR "%s: dumping unexpected response "
- "0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n",
- tp->name, le16_to_cpu(resp->cmd),
- resp->numDesc, resp->flags,
- le16_to_cpu(resp->parm1),
- le32_to_cpu(resp->parm2),
- le32_to_cpu(resp->parm3));
+ netdev_err(tp->dev,
+ "dumping unexpected response 0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n",
+ le16_to_cpu(resp->cmd),
+ resp->numDesc, resp->flags,
+ le16_to_cpu(resp->parm1),
+ le32_to_cpu(resp->parm2),
+ le32_to_cpu(resp->parm3));
}
cleanup:
@@ -546,7 +534,7 @@ cleanup:
indexes->respCleared = cpu_to_le32(cleared);
wmb();
- return (resp_save == NULL);
+ return resp_save == NULL;
}
static inline int
@@ -603,9 +591,8 @@ typhoon_issue_command(struct typhoon *tp, int num_cmd, struct cmd_desc *cmd,
freeResp = typhoon_num_free_resp(tp);
if(freeCmd < num_cmd || freeResp < num_resp) {
- printk("%s: no descs for cmd, had (needed) %d (%d) cmd, "
- "%d (%d) resp\n", tp->name, freeCmd, num_cmd,
- freeResp, num_resp);
+ netdev_err(tp->dev, "no descs for cmd, had (needed) %d (%d) cmd, %d (%d) resp\n",
+ freeCmd, num_cmd, freeResp, num_resp);
err = -ENOMEM;
goto out;
}
@@ -701,44 +688,6 @@ out:
return err;
}
-static void
-typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
- struct typhoon *tp = netdev_priv(dev);
- struct cmd_desc xp_cmd;
- int err;
-
- spin_lock_bh(&tp->state_lock);
- if(!tp->vlgrp != !grp) {
- /* We've either been turned on for the first time, or we've
- * been turned off. Update the 3XP.
- */
- if(grp)
- tp->offload |= TYPHOON_OFFLOAD_VLAN;
- else
- tp->offload &= ~TYPHOON_OFFLOAD_VLAN;
-
- /* If the interface is up, the runtime is running -- and we
- * must be up for the vlan core to call us.
- *
- * Do the command outside of the spin lock, as it is slow.
- */
- INIT_COMMAND_WITH_RESPONSE(&xp_cmd,
- TYPHOON_CMD_SET_OFFLOAD_TASKS);
- xp_cmd.parm2 = tp->offload;
- xp_cmd.parm3 = tp->offload;
- spin_unlock_bh(&tp->state_lock);
- err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
- if(err < 0)
- printk("%s: vlan offload error %d\n", tp->name, -err);
- spin_lock_bh(&tp->state_lock);
- }
-
- /* now make the change visible */
- tp->vlgrp = grp;
- spin_unlock_bh(&tp->state_lock);
-}
-
static inline void
typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
u32 ring_dma)
@@ -760,7 +709,7 @@ typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
tcpd->status = 0;
}
-static int
+static netdev_tx_t
typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
{
struct typhoon *tp = netdev_priv(dev);
@@ -824,7 +773,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
first_txd->processFlags |=
TYPHOON_TX_PF_INSERT_VLAN | TYPHOON_TX_PF_VLAN_PRIORITY;
first_txd->processFlags |=
- cpu_to_le32(ntohs(vlan_tx_tag_get(skb)) <<
+ cpu_to_le32(htons(vlan_tx_tag_get(skb)) <<
TYPHOON_TX_PF_VLAN_TAG_SHIFT);
}
@@ -861,17 +810,16 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
txd->frag.addrHi = 0;
first_txd->numDesc++;
- for(i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
void *frag_addr;
txd = (struct tx_desc *) (txRing->ringBase +
txRing->lastWrite);
typhoon_inc_tx_index(&txRing->lastWrite, 1);
- len = frag->size;
- frag_addr = (void *) page_address(frag->page) +
- frag->page_offset;
+ len = skb_frag_size(frag);
+ frag_addr = skb_frag_address(frag);
skb_dma = pci_map_single(tp->tx_pdev, frag_addr, len,
PCI_DMA_TODEVICE);
txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
@@ -887,8 +835,6 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
wmb();
iowrite32(txRing->lastWrite, tp->tx_ioaddr + txRing->writeRegister);
- dev->trans_start = jiffies;
-
/* If we don't have room to put the worst case packet on the
* queue, then we must stop the queue. We need 2 extra
* descriptors -- one to prevent ring wrap, and one for the
@@ -899,7 +845,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
if(typhoon_num_free_tx(txRing) < (numDesc + 2)) {
netif_stop_queue(dev);
- /* A Tx complete IRQ could have gotten inbetween, making
+ /* A Tx complete IRQ could have gotten between, making
* the ring free again. Only need to recheck here, since
* Tx is serialized.
*/
@@ -907,7 +853,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
netif_wake_queue(dev);
}
- return 0;
+ return NETDEV_TX_OK;
}
static void
@@ -921,18 +867,16 @@ typhoon_set_rx_mode(struct net_device *dev)
filter = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
if(dev->flags & IFF_PROMISC) {
filter |= TYPHOON_RX_FILTER_PROMISCOUS;
- } else if((dev->mc_count > multicast_filter_limit) ||
+ } else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
(dev->flags & IFF_ALLMULTI)) {
/* Too many to match, or accept all multicasts. */
filter |= TYPHOON_RX_FILTER_ALL_MCAST;
- } else if(dev->mc_count) {
- struct dev_mc_list *mclist;
- int i;
+ } else if (!netdev_mc_empty(dev)) {
+ struct netdev_hw_addr *ha;
memset(mc_filter, 0, sizeof(mc_filter));
- for(i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
- i++, mclist = mclist->next) {
- int bit = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
+ netdev_for_each_mc_addr(ha, dev) {
+ int bit = ether_crc(ETH_ALEN, ha->addr) & 0x3f;
mc_filter[bit >> 5] |= 1 << (bit & 0x1f);
}
@@ -946,7 +890,7 @@ typhoon_set_rx_mode(struct net_device *dev)
filter |= TYPHOON_RX_FILTER_MCAST_HASH;
}
- INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
+ INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
xp_cmd.parm1 = filter;
typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
}
@@ -972,36 +916,34 @@ typhoon_do_get_stats(struct typhoon *tp)
* The extra status reported would be a good candidate for
* ethtool_ops->get_{strings,stats}()
*/
- stats->tx_packets = le32_to_cpu(s->txPackets);
- stats->tx_bytes = le64_to_cpu(s->txBytes);
- stats->tx_errors = le32_to_cpu(s->txCarrierLost);
- stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost);
- stats->collisions = le32_to_cpu(s->txMultipleCollisions);
- stats->rx_packets = le32_to_cpu(s->rxPacketsGood);
- stats->rx_bytes = le64_to_cpu(s->rxBytesGood);
- stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns);
+ stats->tx_packets = le32_to_cpu(s->txPackets) +
+ saved->tx_packets;
+ stats->tx_bytes = le64_to_cpu(s->txBytes) +
+ saved->tx_bytes;
+ stats->tx_errors = le32_to_cpu(s->txCarrierLost) +
+ saved->tx_errors;
+ stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) +
+ saved->tx_carrier_errors;
+ stats->collisions = le32_to_cpu(s->txMultipleCollisions) +
+ saved->collisions;
+ stats->rx_packets = le32_to_cpu(s->rxPacketsGood) +
+ saved->rx_packets;
+ stats->rx_bytes = le64_to_cpu(s->rxBytesGood) +
+ saved->rx_bytes;
+ stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) +
+ saved->rx_fifo_errors;
stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) +
- le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors);
- stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors);
- stats->rx_length_errors = le32_to_cpu(s->rxOversized);
+ le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) +
+ saved->rx_errors;
+ stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) +
+ saved->rx_crc_errors;
+ stats->rx_length_errors = le32_to_cpu(s->rxOversized) +
+ saved->rx_length_errors;
tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ?
SPEED_100 : SPEED_10;
tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ?
DUPLEX_FULL : DUPLEX_HALF;
- /* add in the saved statistics
- */
- stats->tx_packets += saved->tx_packets;
- stats->tx_bytes += saved->tx_bytes;
- stats->tx_errors += saved->tx_errors;
- stats->collisions += saved->collisions;
- stats->rx_packets += saved->rx_packets;
- stats->rx_bytes += saved->rx_bytes;
- stats->rx_fifo_errors += saved->rx_fifo_errors;
- stats->rx_errors += saved->rx_errors;
- stats->rx_crc_errors += saved->rx_crc_errors;
- stats->rx_length_errors += saved->rx_length_errors;
-
return 0;
}
@@ -1017,25 +959,13 @@ typhoon_get_stats(struct net_device *dev)
return saved;
if(typhoon_do_get_stats(tp) < 0) {
- printk(KERN_ERR "%s: error getting stats\n", dev->name);
+ netdev_err(dev, "error getting stats\n");
return saved;
}
return stats;
}
-static int
-typhoon_set_mac_address(struct net_device *dev, void *addr)
-{
- struct sockaddr *saddr = (struct sockaddr *) addr;
-
- if(netif_running(dev))
- return -EBUSY;
-
- memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
- return 0;
-}
-
static void
typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
@@ -1046,22 +976,23 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
smp_rmb();
if(tp->card_state == Sleeping) {
- strcpy(info->fw_version, "Sleep image");
+ strlcpy(info->fw_version, "Sleep image",
+ sizeof(info->fw_version));
} else {
INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
- strcpy(info->fw_version, "Unknown runtime");
+ strlcpy(info->fw_version, "Unknown runtime",
+ sizeof(info->fw_version));
} else {
u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2);
- snprintf(info->fw_version, 32, "%02x.%03x.%03x",
- sleep_ver >> 24, (sleep_ver >> 12) & 0xfff,
- sleep_ver & 0xfff);
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%02x.%03x.%03x", sleep_ver >> 24,
+ (sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff);
}
}
- strcpy(info->driver, DRV_MODULE_NAME);
- strcpy(info->version, DRV_MODULE_VERSION);
- strcpy(info->bus_info, pci_name(pci_dev));
+ strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+ strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info));
}
static int
@@ -1108,7 +1039,7 @@ typhoon_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
/* need to get stats to make these link speed/duplex valid */
typhoon_do_get_stats(tp);
- cmd->speed = tp->speed;
+ ethtool_cmd_speed_set(cmd, tp->speed);
cmd->duplex = tp->duplex;
cmd->phy_address = 0;
cmd->transceiver = XCVR_INTERNAL;
@@ -1126,25 +1057,26 @@ static int
typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct typhoon *tp = netdev_priv(dev);
+ u32 speed = ethtool_cmd_speed(cmd);
struct cmd_desc xp_cmd;
__le16 xcvr;
int err;
err = -EINVAL;
- if(cmd->autoneg == AUTONEG_ENABLE) {
+ if (cmd->autoneg == AUTONEG_ENABLE) {
xcvr = TYPHOON_XCVR_AUTONEG;
} else {
- if(cmd->duplex == DUPLEX_HALF) {
- if(cmd->speed == SPEED_10)
+ if (cmd->duplex == DUPLEX_HALF) {
+ if (speed == SPEED_10)
xcvr = TYPHOON_XCVR_10HALF;
- else if(cmd->speed == SPEED_100)
+ else if (speed == SPEED_100)
xcvr = TYPHOON_XCVR_100HALF;
else
goto out;
- } else if(cmd->duplex == DUPLEX_FULL) {
- if(cmd->speed == SPEED_10)
+ } else if (cmd->duplex == DUPLEX_FULL) {
+ if (speed == SPEED_10)
xcvr = TYPHOON_XCVR_10FULL;
- else if(cmd->speed == SPEED_100)
+ else if (speed == SPEED_100)
xcvr = TYPHOON_XCVR_100FULL;
else
goto out;
@@ -1163,7 +1095,7 @@ typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
tp->speed = 0xff; /* invalid */
tp->duplex = 0xff; /* invalid */
} else {
- tp->speed = cmd->speed;
+ tp->speed = speed;
tp->duplex = cmd->duplex;
}
@@ -1202,25 +1134,13 @@ typhoon_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return 0;
}
-static u32
-typhoon_get_rx_csum(struct net_device *dev)
-{
- /* For now, we don't allow turning off RX checksums.
- */
- return 1;
-}
-
static void
typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
{
ering->rx_max_pending = RXENT_ENTRIES;
- ering->rx_mini_max_pending = 0;
- ering->rx_jumbo_max_pending = 0;
ering->tx_max_pending = TXLO_ENTRIES - 1;
ering->rx_pending = RXENT_ENTRIES;
- ering->rx_mini_pending = 0;
- ering->rx_jumbo_pending = 0;
ering->tx_pending = TXLO_ENTRIES - 1;
}
@@ -1231,10 +1151,6 @@ static const struct ethtool_ops typhoon_ethtool_ops = {
.get_wol = typhoon_get_wol,
.set_wol = typhoon_set_wol,
.get_link = ethtool_op_get_link,
- .get_rx_csum = typhoon_get_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = ethtool_op_set_tso,
.get_ringparam = typhoon_get_ringparam,
};
@@ -1318,13 +1234,15 @@ typhoon_init_interface(struct typhoon *tp)
tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr);
tp->card_state = Sleeping;
- smp_wmb();
tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
+ tp->offload |= TYPHOON_OFFLOAD_VLAN;
spin_lock_init(&tp->command_lock);
- spin_lock_init(&tp->state_lock);
+
+ /* Force the writes to the shared memory area out before continuing. */
+ wmb();
}
static void
@@ -1338,20 +1256,80 @@ typhoon_init_rings(struct typhoon *tp)
tp->rxHiRing.lastWrite = 0;
tp->rxBuffRing.lastWrite = 0;
tp->cmdRing.lastWrite = 0;
- tp->cmdRing.lastWrite = 0;
+ tp->respRing.lastWrite = 0;
tp->txLoRing.lastRead = 0;
tp->txHiRing.lastRead = 0;
}
+static const struct firmware *typhoon_fw;
+
+static int
+typhoon_request_firmware(struct typhoon *tp)
+{
+ const struct typhoon_file_header *fHdr;
+ const struct typhoon_section_header *sHdr;
+ const u8 *image_data;
+ u32 numSections;
+ u32 section_len;
+ u32 remaining;
+ int err;
+
+ if (typhoon_fw)
+ return 0;
+
+ err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev);
+ if (err) {
+ netdev_err(tp->dev, "Failed to load firmware \"%s\"\n",
+ FIRMWARE_NAME);
+ return err;
+ }
+
+ image_data = (u8 *) typhoon_fw->data;
+ remaining = typhoon_fw->size;
+ if (remaining < sizeof(struct typhoon_file_header))
+ goto invalid_fw;
+
+ fHdr = (struct typhoon_file_header *) image_data;
+ if (memcmp(fHdr->tag, "TYPHOON", 8))
+ goto invalid_fw;
+
+ numSections = le32_to_cpu(fHdr->numSections);
+ image_data += sizeof(struct typhoon_file_header);
+ remaining -= sizeof(struct typhoon_file_header);
+
+ while (numSections--) {
+ if (remaining < sizeof(struct typhoon_section_header))
+ goto invalid_fw;
+
+ sHdr = (struct typhoon_section_header *) image_data;
+ image_data += sizeof(struct typhoon_section_header);
+ section_len = le32_to_cpu(sHdr->len);
+
+ if (remaining < section_len)
+ goto invalid_fw;
+
+ image_data += section_len;
+ remaining -= section_len;
+ }
+
+ return 0;
+
+invalid_fw:
+ netdev_err(tp->dev, "Invalid firmware image\n");
+ release_firmware(typhoon_fw);
+ typhoon_fw = NULL;
+ return -EINVAL;
+}
+
static int
typhoon_download_firmware(struct typhoon *tp)
{
void __iomem *ioaddr = tp->ioaddr;
struct pci_dev *pdev = tp->pdev;
- struct typhoon_file_header *fHdr;
- struct typhoon_section_header *sHdr;
- u8 *image_data;
+ const struct typhoon_file_header *fHdr;
+ const struct typhoon_section_header *sHdr;
+ const u8 *image_data;
void *dpage;
dma_addr_t dpage_dma;
__sum16 csum;
@@ -1365,25 +1343,17 @@ typhoon_download_firmware(struct typhoon *tp)
int i;
int err;
- err = -EINVAL;
- fHdr = (struct typhoon_file_header *) typhoon_firmware_image;
- image_data = (u8 *) fHdr;
-
- if(memcmp(fHdr->tag, "TYPHOON", 8)) {
- printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name);
- goto err_out;
- }
+ image_data = (u8 *) typhoon_fw->data;
+ fHdr = (struct typhoon_file_header *) image_data;
/* Cannot just map the firmware image using pci_map_single() as
- * the firmware is part of the kernel/module image, so we allocate
- * some consistent memory to copy the sections into, as it is simpler,
- * and short-lived. If we ever split out and require a userland
- * firmware loader, then we can revisit this.
+ * the firmware is vmalloc()'d and may not be physically contiguous,
+ * so we allocate some consistent memory to copy the sections into.
*/
err = -ENOMEM;
dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
if(!dpage) {
- printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name);
+ netdev_err(tp->dev, "no DMA mem for firmware\n");
goto err_out;
}
@@ -1396,7 +1366,7 @@ typhoon_download_firmware(struct typhoon *tp)
err = -ETIMEDOUT;
if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
- printk(KERN_ERR "%s: card ready timeout\n", tp->name);
+ netdev_err(tp->dev, "card ready timeout\n");
goto err_out_irq;
}
@@ -1436,8 +1406,7 @@ typhoon_download_firmware(struct typhoon *tp)
if(typhoon_wait_interrupt(ioaddr) < 0 ||
ioread32(ioaddr + TYPHOON_REG_STATUS) !=
TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
- printk(KERN_ERR "%s: segment ready timeout\n",
- tp->name);
+ netdev_err(tp->dev, "segment ready timeout\n");
goto err_out_irq;
}
@@ -1447,8 +1416,8 @@ typhoon_download_firmware(struct typhoon *tp)
* the checksum, we can do this once, at the end.
*/
csum = csum_fold(csum_partial_copy_nocheck(image_data,
- dpage, len,
- 0));
+ dpage, len,
+ 0));
iowrite32(len, ioaddr + TYPHOON_REG_BOOT_LENGTH);
iowrite32(le16_to_cpu((__force __le16)csum),
@@ -1459,7 +1428,7 @@ typhoon_download_firmware(struct typhoon *tp)
iowrite32(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO);
typhoon_post_pci_writes(ioaddr);
iowrite32(TYPHOON_BOOTCMD_SEG_AVAILABLE,
- ioaddr + TYPHOON_REG_COMMAND);
+ ioaddr + TYPHOON_REG_COMMAND);
image_data += len;
load_addr += len;
@@ -1470,15 +1439,15 @@ typhoon_download_firmware(struct typhoon *tp)
if(typhoon_wait_interrupt(ioaddr) < 0 ||
ioread32(ioaddr + TYPHOON_REG_STATUS) !=
TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
- printk(KERN_ERR "%s: final segment ready timeout\n", tp->name);
+ netdev_err(tp->dev, "final segment ready timeout\n");
goto err_out_irq;
}
iowrite32(TYPHOON_BOOTCMD_DNLD_COMPLETE, ioaddr + TYPHOON_REG_COMMAND);
if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
- printk(KERN_ERR "%s: boot ready timeout, status 0x%0x\n",
- tp->name, ioread32(ioaddr + TYPHOON_REG_STATUS));
+ netdev_err(tp->dev, "boot ready timeout, status 0x%0x\n",
+ ioread32(ioaddr + TYPHOON_REG_STATUS));
goto err_out_irq;
}
@@ -1500,7 +1469,7 @@ typhoon_boot_3XP(struct typhoon *tp, u32 initial_status)
void __iomem *ioaddr = tp->ioaddr;
if(typhoon_wait_status(ioaddr, initial_status) < 0) {
- printk(KERN_ERR "%s: boot ready timeout\n", tp->name);
+ netdev_err(tp->dev, "boot ready timeout\n");
goto out_timeout;
}
@@ -1511,8 +1480,8 @@ typhoon_boot_3XP(struct typhoon *tp, u32 initial_status)
ioaddr + TYPHOON_REG_COMMAND);
if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_RUNNING) < 0) {
- printk(KERN_ERR "%s: boot finish timeout (status 0x%x)\n",
- tp->name, ioread32(ioaddr + TYPHOON_REG_STATUS));
+ netdev_err(tp->dev, "boot finish timeout (status 0x%x)\n",
+ ioread32(ioaddr + TYPHOON_REG_STATUS));
goto out_timeout;
}
@@ -1626,7 +1595,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
le32_to_cpu(indexes->rxBuffCleared))
return -ENOMEM;
- skb = dev_alloc_skb(PKT_BUF_SZ);
+ skb = netdev_alloc_skb(tp->dev, PKT_BUF_SZ);
if(!skb)
return -ENOMEM;
@@ -1637,7 +1606,6 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
skb_reserve(skb, 2);
#endif
- skb->dev = tp->dev;
dma_addr = pci_map_single(tp->pdev, skb->data,
PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
@@ -1692,7 +1660,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
pkt_len = le16_to_cpu(rx->frameLen);
if(pkt_len < rx_copybreak &&
- (new_skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+ (new_skb = netdev_alloc_skb(tp->dev, pkt_len + 2)) != NULL) {
skb_reserve(new_skb, 2);
pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
PKT_BUF_SZ,
@@ -1714,22 +1682,18 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD |
TYPHOON_RX_UDP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD);
if(csum_bits ==
- (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD)
- || csum_bits ==
+ (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD) ||
+ csum_bits ==
(TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) {
new_skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
- new_skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(new_skb);
- spin_lock(&tp->state_lock);
- if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN)
- vlan_hwaccel_receive_skb(new_skb, tp->vlgrp,
- ntohl(rx->vlanTag) & 0xffff);
- else
- netif_receive_skb(new_skb);
- spin_unlock(&tp->state_lock);
+ if (rx->rxStatus & TYPHOON_RX_VLAN)
+ __vlan_hwaccel_put_tag(new_skb, htons(ETH_P_8021Q),
+ ntohl(rx->vlanTag) & 0xffff);
+ netif_receive_skb(new_skb);
- tp->dev->last_rx = jiffies;
received++;
budget--;
}
@@ -1756,7 +1720,6 @@ static int
typhoon_poll(struct napi_struct *napi, int budget)
{
struct typhoon *tp = container_of(napi, struct typhoon, napi);
- struct net_device *dev = tp->dev;
struct typhoon_indexes *indexes = tp->indexes;
int work_done;
@@ -1785,7 +1748,7 @@ typhoon_poll(struct napi_struct *napi, int budget)
}
if (work_done < budget) {
- netif_rx_complete(dev, napi);
+ napi_complete(napi);
iowrite32(TYPHOON_INTR_NONE,
tp->ioaddr + TYPHOON_REG_INTR_MASK);
typhoon_post_pci_writes(tp->ioaddr);
@@ -1798,7 +1761,7 @@ static irqreturn_t
typhoon_interrupt(int irq, void *dev_instance)
{
struct net_device *dev = dev_instance;
- struct typhoon *tp = dev->priv;
+ struct typhoon *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->ioaddr;
u32 intr_status;
@@ -1808,13 +1771,12 @@ typhoon_interrupt(int irq, void *dev_instance)
iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
- if (netif_rx_schedule_prep(dev, &tp->napi)) {
+ if (napi_schedule_prep(&tp->napi)) {
iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
typhoon_post_pci_writes(ioaddr);
- __netif_rx_schedule(dev, &tp->napi);
+ __napi_schedule(&tp->napi);
} else {
- printk(KERN_ERR "%s: Error, poll already scheduled\n",
- dev->name);
+ netdev_err(dev, "Error, poll already scheduled\n");
}
return IRQ_HANDLED;
}
@@ -1847,16 +1809,15 @@ typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events)
xp_cmd.parm1 = events;
err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
if(err < 0) {
- printk(KERN_ERR "%s: typhoon_sleep(): wake events cmd err %d\n",
- tp->name, err);
+ netdev_err(tp->dev, "typhoon_sleep(): wake events cmd err %d\n",
+ err);
return err;
}
INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_GOTO_SLEEP);
err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
if(err < 0) {
- printk(KERN_ERR "%s: typhoon_sleep(): sleep cmd err %d\n",
- tp->name, err);
+ netdev_err(tp->dev, "typhoon_sleep(): sleep cmd err %d\n", err);
return err;
}
@@ -1907,12 +1868,12 @@ typhoon_start_runtime(struct typhoon *tp)
err = typhoon_download_firmware(tp);
if(err < 0) {
- printk("%s: cannot load runtime on 3XP\n", tp->name);
+ netdev_err(tp->dev, "cannot load runtime on 3XP\n");
goto error_out;
}
if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
- printk("%s: cannot boot 3XP\n", tp->name);
+ netdev_err(tp->dev, "cannot boot 3XP\n");
err = -EIO;
goto error_out;
}
@@ -1946,17 +1907,15 @@ typhoon_start_runtime(struct typhoon *tp)
goto error_out;
INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE);
- xp_cmd.parm1 = __constant_cpu_to_le16(ETH_P_8021Q);
+ xp_cmd.parm1 = cpu_to_le16(ETH_P_8021Q);
err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
if(err < 0)
goto error_out;
INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS);
- spin_lock_bh(&tp->state_lock);
xp_cmd.parm2 = tp->offload;
xp_cmd.parm3 = tp->offload;
err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
- spin_unlock_bh(&tp->state_lock);
if(err < 0)
goto error_out;
@@ -2016,9 +1975,7 @@ typhoon_stop_runtime(struct typhoon *tp, int wait_type)
}
if(i == TYPHOON_WAIT_TIMEOUT)
- printk(KERN_ERR
- "%s: halt timed out waiting for Tx to complete\n",
- tp->name);
+ netdev_err(tp->dev, "halt timed out waiting for Tx to complete\n");
INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_DISABLE);
typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
@@ -2035,11 +1992,10 @@ typhoon_stop_runtime(struct typhoon *tp, int wait_type)
typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_HALTED) < 0)
- printk(KERN_ERR "%s: timed out waiting for 3XP to halt\n",
- tp->name);
+ netdev_err(tp->dev, "timed out waiting for 3XP to halt\n");
if(typhoon_reset(ioaddr, wait_type) < 0) {
- printk(KERN_ERR "%s: unable to reset 3XP\n", tp->name);
+ netdev_err(tp->dev, "unable to reset 3XP\n");
return -ETIMEDOUT;
}
@@ -2058,9 +2014,8 @@ typhoon_tx_timeout(struct net_device *dev)
struct typhoon *tp = netdev_priv(dev);
if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) {
- printk(KERN_WARNING "%s: could not reset in tx timeout\n",
- dev->name);
- goto truely_dead;
+ netdev_warn(dev, "could not reset in tx timeout\n");
+ goto truly_dead;
}
/* If we ever start using the Hi ring, it will need cleaning too */
@@ -2068,15 +2023,14 @@ typhoon_tx_timeout(struct net_device *dev)
typhoon_free_rx_rings(tp);
if(typhoon_start_runtime(tp) < 0) {
- printk(KERN_ERR "%s: could not start runtime in tx timeout\n",
- dev->name);
- goto truely_dead;
+ netdev_err(dev, "could not start runtime in tx timeout\n");
+ goto truly_dead;
}
netif_wake_queue(dev);
return;
-truely_dead:
+truly_dead:
/* Reset the hardware, and turn off carrier to avoid more timeouts */
typhoon_reset(tp->ioaddr, NoWait);
netif_carrier_off(dev);
@@ -2088,13 +2042,17 @@ typhoon_open(struct net_device *dev)
struct typhoon *tp = netdev_priv(dev);
int err;
+ err = typhoon_request_firmware(tp);
+ if (err)
+ goto out;
+
err = typhoon_wakeup(tp, WaitSleep);
if(err < 0) {
- printk(KERN_ERR "%s: unable to wakeup device\n", dev->name);
+ netdev_err(dev, "unable to wakeup device\n");
goto out_sleep;
}
- err = request_irq(dev->irq, &typhoon_interrupt, IRQF_SHARED,
+ err = request_irq(dev->irq, typhoon_interrupt, IRQF_SHARED,
dev->name, dev);
if(err < 0)
goto out_sleep;
@@ -2115,14 +2073,13 @@ out_irq:
out_sleep:
if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
- printk(KERN_ERR "%s: unable to reboot into sleep img\n",
- dev->name);
+ netdev_err(dev, "unable to reboot into sleep img\n");
typhoon_reset(tp->ioaddr, NoWait);
goto out;
}
if(typhoon_sleep(tp, PCI_D3hot, 0) < 0)
- printk(KERN_ERR "%s: unable to go back to sleep\n", dev->name);
+ netdev_err(dev, "unable to go back to sleep\n");
out:
return err;
@@ -2137,7 +2094,7 @@ typhoon_close(struct net_device *dev)
napi_disable(&tp->napi);
if(typhoon_stop_runtime(tp, WaitSleep) < 0)
- printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
+ netdev_err(dev, "unable to stop runtime\n");
/* Make sure there is no irq handler running on a different CPU. */
free_irq(dev->irq, dev);
@@ -2146,10 +2103,10 @@ typhoon_close(struct net_device *dev)
typhoon_init_rings(tp);
if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
- printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name);
+ netdev_err(dev, "unable to boot sleep image\n");
if(typhoon_sleep(tp, PCI_D3hot, 0) < 0)
- printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
+ netdev_err(dev, "unable to put card to sleep\n");
return 0;
}
@@ -2167,14 +2124,12 @@ typhoon_resume(struct pci_dev *pdev)
return 0;
if(typhoon_wakeup(tp, WaitNoSleep) < 0) {
- printk(KERN_ERR "%s: critical: could not wake up in resume\n",
- dev->name);
+ netdev_err(dev, "critical: could not wake up in resume\n");
goto reset;
}
if(typhoon_start_runtime(tp) < 0) {
- printk(KERN_ERR "%s: critical: could not start runtime in "
- "resume\n", dev->name);
+ netdev_err(dev, "critical: could not start runtime in resume\n");
goto reset;
}
@@ -2198,19 +2153,14 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
if(!netif_running(dev))
return 0;
- spin_lock_bh(&tp->state_lock);
- if(tp->vlgrp && tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) {
- spin_unlock_bh(&tp->state_lock);
- printk(KERN_ERR "%s: cannot do WAKE_MAGIC with VLANS\n",
- dev->name);
- return -EBUSY;
- }
- spin_unlock_bh(&tp->state_lock);
+ /* TYPHOON_OFFLOAD_VLAN is always on now, so this doesn't work */
+ if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT)
+ netdev_warn(dev, "cannot do WAKE_MAGIC with VLAN offloading\n");
netif_device_detach(dev);
if(typhoon_stop_runtime(tp, WaitNoSleep) < 0) {
- printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
+ netdev_err(dev, "unable to stop runtime\n");
goto need_resume;
}
@@ -2218,7 +2168,7 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
typhoon_init_rings(tp);
if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
- printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name);
+ netdev_err(dev, "unable to boot sleep image\n");
goto need_resume;
}
@@ -2226,21 +2176,19 @@ typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0]));
xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2]));
if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
- printk(KERN_ERR "%s: unable to set mac address in suspend\n",
- dev->name);
+ netdev_err(dev, "unable to set mac address in suspend\n");
goto need_resume;
}
INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
xp_cmd.parm1 = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
- printk(KERN_ERR "%s: unable to set rx filter in suspend\n",
- dev->name);
+ netdev_err(dev, "unable to set rx filter in suspend\n");
goto need_resume;
}
if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) {
- printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
+ netdev_err(dev, "unable to put card to sleep\n");
goto need_resume;
}
@@ -2252,7 +2200,7 @@ need_resume:
}
#endif
-static int __devinit
+static int
typhoon_test_mmio(struct pci_dev *pdev)
{
void __iomem *ioaddr = pci_iomap(pdev, 1, 128);
@@ -2294,14 +2242,25 @@ out_unmap:
out:
if(!mode)
- printk(KERN_INFO PFX "falling back to port IO\n");
+ pr_info("%s: falling back to port IO\n", pci_name(pdev));
return mode;
}
-static int __devinit
+static const struct net_device_ops typhoon_netdev_ops = {
+ .ndo_open = typhoon_open,
+ .ndo_stop = typhoon_close,
+ .ndo_start_xmit = typhoon_start_tx,
+ .ndo_set_rx_mode = typhoon_set_rx_mode,
+ .ndo_tx_timeout = typhoon_tx_timeout,
+ .ndo_get_stats = typhoon_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
+
+static int
typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- static int did_version = 0;
struct net_device *dev;
struct typhoon *tp;
int card_id = (int) ent->driver_data;
@@ -2311,15 +2270,11 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct cmd_desc xp_cmd;
struct resp_desc xp_resp[3];
int err = 0;
- DECLARE_MAC_BUF(mac);
-
- if(!did_version++)
- printk(KERN_INFO "%s", version);
+ const char *err_msg;
dev = alloc_etherdev(sizeof(*tp));
if(dev == NULL) {
- printk(ERR_PFX "%s: unable to alloc new net device\n",
- pci_name(pdev));
+ err_msg = "unable to alloc new net device";
err = -ENOMEM;
goto error_out;
}
@@ -2327,57 +2282,48 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
err = pci_enable_device(pdev);
if(err < 0) {
- printk(ERR_PFX "%s: unable to enable device\n",
- pci_name(pdev));
+ err_msg = "unable to enable device";
goto error_out_dev;
}
err = pci_set_mwi(pdev);
if(err < 0) {
- printk(ERR_PFX "%s: unable to set MWI\n", pci_name(pdev));
+ err_msg = "unable to set MWI";
goto error_out_disable;
}
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if(err < 0) {
- printk(ERR_PFX "%s: No usable DMA configuration\n",
- pci_name(pdev));
+ err_msg = "No usable DMA configuration";
goto error_out_mwi;
}
/* sanity checks on IO and MMIO BARs
*/
if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
- printk(ERR_PFX
- "%s: region #1 not a PCI IO resource, aborting\n",
- pci_name(pdev));
+ err_msg = "region #1 not a PCI IO resource, aborting";
err = -ENODEV;
goto error_out_mwi;
}
if(pci_resource_len(pdev, 0) < 128) {
- printk(ERR_PFX "%s: Invalid PCI IO region size, aborting\n",
- pci_name(pdev));
+ err_msg = "Invalid PCI IO region size, aborting";
err = -ENODEV;
goto error_out_mwi;
}
if(!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
- printk(ERR_PFX
- "%s: region #1 not a PCI MMIO resource, aborting\n",
- pci_name(pdev));
+ err_msg = "region #1 not a PCI MMIO resource, aborting";
err = -ENODEV;
goto error_out_mwi;
}
if(pci_resource_len(pdev, 1) < 128) {
- printk(ERR_PFX "%s: Invalid PCI MMIO region size, aborting\n",
- pci_name(pdev));
+ err_msg = "Invalid PCI MMIO region size, aborting";
err = -ENODEV;
goto error_out_mwi;
}
- err = pci_request_regions(pdev, "typhoon");
+ err = pci_request_regions(pdev, KBUILD_MODNAME);
if(err < 0) {
- printk(ERR_PFX "%s: could not request regions\n",
- pci_name(pdev));
+ err_msg = "could not request regions";
goto error_out_mwi;
}
@@ -2388,8 +2334,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
ioaddr = pci_iomap(pdev, use_mmio, 128);
if (!ioaddr) {
- printk(ERR_PFX "%s: cannot remap registers, aborting\n",
- pci_name(pdev));
+ err_msg = "cannot remap registers, aborting";
err = -EIO;
goto error_out_regions;
}
@@ -2399,15 +2344,14 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
shared = pci_alloc_consistent(pdev, sizeof(struct typhoon_shared),
&shared_dma);
if(!shared) {
- printk(ERR_PFX "%s: could not allocate DMA memory\n",
- pci_name(pdev));
+ err_msg = "could not allocate DMA memory";
err = -ENOMEM;
goto error_out_remap;
}
dev->irq = pdev->irq;
tp = netdev_priv(dev);
- tp->shared = (struct typhoon_shared *) shared;
+ tp->shared = shared;
tp->shared_dma = shared_dma;
tp->pdev = pdev;
tp->tx_pdev = pdev;
@@ -2423,7 +2367,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
* 5) Put the card to sleep.
*/
if (typhoon_reset(ioaddr, WaitSleep) < 0) {
- printk(ERR_PFX "%s: could not reset 3XP\n", pci_name(pdev));
+ err_msg = "could not reset 3XP";
err = -EIO;
goto error_out_dma;
}
@@ -2435,26 +2379,18 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
pci_save_state(pdev);
- /* dev->name is not valid until we register, but we need to
- * use some common routines to initialize the card. So that those
- * routines print the right name, we keep our oun pointer to the name
- */
- tp->name = pci_name(pdev);
-
typhoon_init_interface(tp);
typhoon_init_rings(tp);
if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
- printk(ERR_PFX "%s: cannot boot 3XP sleep image\n",
- pci_name(pdev));
+ err_msg = "cannot boot 3XP sleep image";
err = -EIO;
goto error_out_reset;
}
INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS);
if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) {
- printk(ERR_PFX "%s: cannot read MAC address\n",
- pci_name(pdev));
+ err_msg = "cannot read MAC address";
err = -EIO;
goto error_out_reset;
}
@@ -2463,8 +2399,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2));
if(!is_valid_ether_addr(dev->dev_addr)) {
- printk(ERR_PFX "%s: Could not obtain valid ethernet address, "
- "aborting\n", pci_name(pdev));
+ err_msg = "Could not obtain valid ethernet address, aborting";
goto error_out_reset;
}
@@ -2473,8 +2408,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
- printk(ERR_PFX "%s: Could not get Sleep Image version\n",
- pci_name(pdev));
+ err_msg = "Could not get Sleep Image version";
goto error_out_reset;
}
@@ -2491,46 +2425,42 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET;
if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) {
- printk(ERR_PFX "%s: cannot put adapter to sleep\n",
- pci_name(pdev));
+ err_msg = "cannot put adapter to sleep";
err = -EIO;
goto error_out_reset;
}
/* The chip-specific entries in the device structure. */
- dev->open = typhoon_open;
- dev->hard_start_xmit = typhoon_start_tx;
- dev->stop = typhoon_close;
- dev->set_multicast_list = typhoon_set_rx_mode;
- dev->tx_timeout = typhoon_tx_timeout;
+ dev->netdev_ops = &typhoon_netdev_ops;
netif_napi_add(dev, &tp->napi, typhoon_poll, 16);
dev->watchdog_timeo = TX_TIMEOUT;
- dev->get_stats = typhoon_get_stats;
- dev->set_mac_address = typhoon_set_mac_address;
- dev->vlan_rx_register = typhoon_vlan_rx_register;
- SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops);
+ dev->ethtool_ops = &typhoon_ethtool_ops;
/* We can handle scatter gather, up to 16 entries, and
* we can do IP checksumming (only version 4, doh...)
+ *
+ * There's no way to turn off the RX VLAN offloading and stripping
+ * on the current 3XP firmware -- it does not respect the offload
+ * settings -- so we only allow the user to toggle the TX processing.
*/
- dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->features |= NETIF_F_TSO;
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+ NETIF_F_HW_VLAN_CTAG_TX;
+ dev->features = dev->hw_features |
+ NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM;
- if(register_netdev(dev) < 0)
+ if(register_netdev(dev) < 0) {
+ err_msg = "unable to register netdev";
goto error_out_reset;
-
- /* fixup our local name */
- tp->name = dev->name;
+ }
pci_set_drvdata(pdev, dev);
- printk(KERN_INFO "%s: %s at %s 0x%llx, %s\n",
- dev->name, typhoon_card_info[card_id].name,
- use_mmio ? "MMIO" : "IO",
- (unsigned long long)pci_resource_start(pdev, use_mmio),
- print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "%s at %s 0x%llx, %pM\n",
+ typhoon_card_info[card_id].name,
+ use_mmio ? "MMIO" : "IO",
+ (unsigned long long)pci_resource_start(pdev, use_mmio),
+ dev->dev_addr);
/* xp_resp still contains the response to the READ_VERSIONS command.
* For debugging, let the user know what version he has.
@@ -2540,23 +2470,20 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
* of version is Month/Day of build.
*/
u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff;
- printk(KERN_INFO "%s: Typhoon 1.0 Sleep Image built "
- "%02u/%02u/2000\n", dev->name, monthday >> 8,
- monthday & 0xff);
+ netdev_info(dev, "Typhoon 1.0 Sleep Image built %02u/%02u/2000\n",
+ monthday >> 8, monthday & 0xff);
} else if(xp_resp[0].numDesc == 2) {
/* This is the Typhoon 1.1+ type Sleep Image
*/
u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2);
u8 *ver_string = (u8 *) &xp_resp[1];
ver_string[25] = 0;
- printk(KERN_INFO "%s: Typhoon 1.1+ Sleep Image version "
- "%02x.%03x.%03x %s\n", dev->name, sleep_ver >> 24,
- (sleep_ver >> 12) & 0xfff, sleep_ver & 0xfff,
- ver_string);
+ netdev_info(dev, "Typhoon 1.1+ Sleep Image version %02x.%03x.%03x %s\n",
+ sleep_ver >> 24, (sleep_ver >> 12) & 0xfff,
+ sleep_ver & 0xfff, ver_string);
} else {
- printk(KERN_WARNING "%s: Unknown Sleep Image version "
- "(%u:%04x)\n", dev->name, xp_resp[0].numDesc,
- le32_to_cpu(xp_resp[0].parm2));
+ netdev_warn(dev, "Unknown Sleep Image version (%u:%04x)\n",
+ xp_resp[0].numDesc, le32_to_cpu(xp_resp[0].parm2));
}
return 0;
@@ -2578,10 +2505,11 @@ error_out_disable:
error_out_dev:
free_netdev(dev);
error_out:
+ pr_err("%s: %s\n", pci_name(pdev), err_msg);
return err;
}
-static void __devexit
+static void
typhoon_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -2597,15 +2525,14 @@ typhoon_remove_one(struct pci_dev *pdev)
pci_release_regions(pdev);
pci_clear_mwi(pdev);
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
free_netdev(dev);
}
static struct pci_driver typhoon_driver = {
- .name = DRV_MODULE_NAME,
+ .name = KBUILD_MODNAME,
.id_table = typhoon_pci_tbl,
.probe = typhoon_init_one,
- .remove = __devexit_p(typhoon_remove_one),
+ .remove = typhoon_remove_one,
#ifdef CONFIG_PM
.suspend = typhoon_suspend,
.resume = typhoon_resume,
@@ -2621,6 +2548,7 @@ typhoon_init(void)
static void __exit
typhoon_cleanup(void)
{
+ release_firmware(typhoon_fw);
pci_unregister_driver(&typhoon_driver);
}
diff --git a/drivers/net/typhoon.h b/drivers/net/ethernet/3com/typhoon.h
index dd7022ca735..88187fc84aa 100644
--- a/drivers/net/typhoon.h
+++ b/drivers/net/ethernet/3com/typhoon.h
@@ -77,7 +77,7 @@ struct typhoon_indexes {
volatile __le32 cmdCleared;
volatile __le32 respReady;
volatile __le32 rxHiReady;
-} __attribute__ ((packed));
+} __packed;
/* The host<->Typhoon interface
* Our means of communicating where things are
@@ -125,7 +125,7 @@ struct typhoon_interface {
__le32 rxHiAddr;
__le32 rxHiAddrHi;
__le32 rxHiSize;
-} __attribute__ ((packed));
+} __packed;
/* The Typhoon transmit/fragment descriptor
*
@@ -174,20 +174,20 @@ struct tx_desc {
u64 tx_addr; /* opaque for hardware, for TX_DESC */
};
__le32 processFlags;
-#define TYPHOON_TX_PF_NO_CRC __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_TX_PF_IP_CHKSUM __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_TX_PF_TCP_CHKSUM __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_TX_PF_TCP_SEGMENT __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_TX_PF_INSERT_VLAN __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_TX_PF_IPSEC __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_TX_PF_VLAN_PRIORITY __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_TX_PF_UDP_CHKSUM __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_TX_PF_PAD_FRAME __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_TX_PF_RESERVED __constant_cpu_to_le32(0x00000e00)
-#define TYPHOON_TX_PF_VLAN_MASK __constant_cpu_to_le32(0x0ffff000)
-#define TYPHOON_TX_PF_INTERNAL __constant_cpu_to_le32(0xf0000000)
+#define TYPHOON_TX_PF_NO_CRC cpu_to_le32(0x00000001)
+#define TYPHOON_TX_PF_IP_CHKSUM cpu_to_le32(0x00000002)
+#define TYPHOON_TX_PF_TCP_CHKSUM cpu_to_le32(0x00000004)
+#define TYPHOON_TX_PF_TCP_SEGMENT cpu_to_le32(0x00000008)
+#define TYPHOON_TX_PF_INSERT_VLAN cpu_to_le32(0x00000010)
+#define TYPHOON_TX_PF_IPSEC cpu_to_le32(0x00000020)
+#define TYPHOON_TX_PF_VLAN_PRIORITY cpu_to_le32(0x00000040)
+#define TYPHOON_TX_PF_UDP_CHKSUM cpu_to_le32(0x00000080)
+#define TYPHOON_TX_PF_PAD_FRAME cpu_to_le32(0x00000100)
+#define TYPHOON_TX_PF_RESERVED cpu_to_le32(0x00000e00)
+#define TYPHOON_TX_PF_VLAN_MASK cpu_to_le32(0x0ffff000)
+#define TYPHOON_TX_PF_INTERNAL cpu_to_le32(0xf0000000)
#define TYPHOON_TX_PF_VLAN_TAG_SHIFT 12
-} __attribute__ ((packed));
+} __packed;
/* The TCP Segmentation offload option descriptor
*
@@ -203,12 +203,12 @@ struct tcpopt_desc {
u8 flags;
u8 numDesc;
__le16 mss_flags;
-#define TYPHOON_TSO_FIRST __constant_cpu_to_le16(0x1000)
-#define TYPHOON_TSO_LAST __constant_cpu_to_le16(0x2000)
+#define TYPHOON_TSO_FIRST cpu_to_le16(0x1000)
+#define TYPHOON_TSO_LAST cpu_to_le16(0x2000)
__le32 respAddrLo;
__le32 bytesTx;
__le32 status;
-} __attribute__ ((packed));
+} __packed;
/* The IPSEC Offload descriptor
*
@@ -222,12 +222,12 @@ struct ipsec_desc {
u8 flags;
u8 numDesc;
__le16 ipsecFlags;
-#define TYPHOON_IPSEC_GEN_IV __constant_cpu_to_le16(0x0000)
-#define TYPHOON_IPSEC_USE_IV __constant_cpu_to_le16(0x0001)
+#define TYPHOON_IPSEC_GEN_IV cpu_to_le16(0x0000)
+#define TYPHOON_IPSEC_USE_IV cpu_to_le16(0x0001)
__le32 sa1;
__le32 sa2;
__le32 reserved;
-} __attribute__ ((packed));
+} __packed;
/* The Typhoon receive descriptor (Updated by NIC)
*
@@ -248,43 +248,43 @@ struct rx_desc {
u32 addr; /* opaque, comes from virtAddr */
u32 addrHi; /* opaque, comes from virtAddrHi */
__le32 rxStatus;
-#define TYPHOON_RX_ERR_INTERNAL __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_ERR_FIFO_UNDERRUN __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_ERR_BAD_SSD __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_ERR_RUNT __constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_ERR_CRC __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_ERR_OVERSIZE __constant_cpu_to_le32(0x00000005)
-#define TYPHOON_RX_ERR_ALIGN __constant_cpu_to_le32(0x00000006)
-#define TYPHOON_RX_ERR_DRIBBLE __constant_cpu_to_le32(0x00000007)
-#define TYPHOON_RX_PROTO_MASK __constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_PROTO_UNKNOWN __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_PROTO_IP __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_PROTO_IPX __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_VLAN __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_IP_FRAG __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_RX_IPSEC __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_RX_IP_CHK_FAIL __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_RX_TCP_CHK_FAIL __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_RX_UDP_CHK_FAIL __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_RX_IP_CHK_GOOD __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_RX_TCP_CHK_GOOD __constant_cpu_to_le32(0x00000200)
-#define TYPHOON_RX_UDP_CHK_GOOD __constant_cpu_to_le32(0x00000400)
+#define TYPHOON_RX_ERR_INTERNAL cpu_to_le32(0x00000000)
+#define TYPHOON_RX_ERR_FIFO_UNDERRUN cpu_to_le32(0x00000001)
+#define TYPHOON_RX_ERR_BAD_SSD cpu_to_le32(0x00000002)
+#define TYPHOON_RX_ERR_RUNT cpu_to_le32(0x00000003)
+#define TYPHOON_RX_ERR_CRC cpu_to_le32(0x00000004)
+#define TYPHOON_RX_ERR_OVERSIZE cpu_to_le32(0x00000005)
+#define TYPHOON_RX_ERR_ALIGN cpu_to_le32(0x00000006)
+#define TYPHOON_RX_ERR_DRIBBLE cpu_to_le32(0x00000007)
+#define TYPHOON_RX_PROTO_MASK cpu_to_le32(0x00000003)
+#define TYPHOON_RX_PROTO_UNKNOWN cpu_to_le32(0x00000000)
+#define TYPHOON_RX_PROTO_IP cpu_to_le32(0x00000001)
+#define TYPHOON_RX_PROTO_IPX cpu_to_le32(0x00000002)
+#define TYPHOON_RX_VLAN cpu_to_le32(0x00000004)
+#define TYPHOON_RX_IP_FRAG cpu_to_le32(0x00000008)
+#define TYPHOON_RX_IPSEC cpu_to_le32(0x00000010)
+#define TYPHOON_RX_IP_CHK_FAIL cpu_to_le32(0x00000020)
+#define TYPHOON_RX_TCP_CHK_FAIL cpu_to_le32(0x00000040)
+#define TYPHOON_RX_UDP_CHK_FAIL cpu_to_le32(0x00000080)
+#define TYPHOON_RX_IP_CHK_GOOD cpu_to_le32(0x00000100)
+#define TYPHOON_RX_TCP_CHK_GOOD cpu_to_le32(0x00000200)
+#define TYPHOON_RX_UDP_CHK_GOOD cpu_to_le32(0x00000400)
__le16 filterResults;
-#define TYPHOON_RX_FILTER_MASK __constant_cpu_to_le16(0x7fff)
-#define TYPHOON_RX_FILTERED __constant_cpu_to_le16(0x8000)
+#define TYPHOON_RX_FILTER_MASK cpu_to_le16(0x7fff)
+#define TYPHOON_RX_FILTERED cpu_to_le16(0x8000)
__le16 ipsecResults;
-#define TYPHOON_RX_OUTER_AH_GOOD __constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_OUTER_ESP_GOOD __constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_INNER_AH_GOOD __constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_INNER_ESP_GOOD __constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_OUTER_AH_FAIL __constant_cpu_to_le16(0x0010)
-#define TYPHOON_RX_OUTER_ESP_FAIL __constant_cpu_to_le16(0x0020)
-#define TYPHOON_RX_INNER_AH_FAIL __constant_cpu_to_le16(0x0040)
-#define TYPHOON_RX_INNER_ESP_FAIL __constant_cpu_to_le16(0x0080)
-#define TYPHOON_RX_UNKNOWN_SA __constant_cpu_to_le16(0x0100)
-#define TYPHOON_RX_ESP_FORMAT_ERR __constant_cpu_to_le16(0x0200)
+#define TYPHOON_RX_OUTER_AH_GOOD cpu_to_le16(0x0001)
+#define TYPHOON_RX_OUTER_ESP_GOOD cpu_to_le16(0x0002)
+#define TYPHOON_RX_INNER_AH_GOOD cpu_to_le16(0x0004)
+#define TYPHOON_RX_INNER_ESP_GOOD cpu_to_le16(0x0008)
+#define TYPHOON_RX_OUTER_AH_FAIL cpu_to_le16(0x0010)
+#define TYPHOON_RX_OUTER_ESP_FAIL cpu_to_le16(0x0020)
+#define TYPHOON_RX_INNER_AH_FAIL cpu_to_le16(0x0040)
+#define TYPHOON_RX_INNER_ESP_FAIL cpu_to_le16(0x0080)
+#define TYPHOON_RX_UNKNOWN_SA cpu_to_le16(0x0100)
+#define TYPHOON_RX_ESP_FORMAT_ERR cpu_to_le16(0x0200)
__be32 vlanTag;
-} __attribute__ ((packed));
+} __packed;
/* The Typhoon free buffer descriptor, used to give a buffer to the NIC
*
@@ -301,7 +301,7 @@ struct rx_free {
__le32 physAddrHi;
u32 virtAddr;
u32 virtAddrHi;
-} __attribute__ ((packed));
+} __packed;
/* The Typhoon command descriptor, used for commands and responses
*
@@ -318,36 +318,36 @@ struct cmd_desc {
u8 flags;
u8 numDesc;
__le16 cmd;
-#define TYPHOON_CMD_TX_ENABLE __constant_cpu_to_le16(0x0001)
-#define TYPHOON_CMD_TX_DISABLE __constant_cpu_to_le16(0x0002)
-#define TYPHOON_CMD_RX_ENABLE __constant_cpu_to_le16(0x0003)
-#define TYPHOON_CMD_RX_DISABLE __constant_cpu_to_le16(0x0004)
-#define TYPHOON_CMD_SET_RX_FILTER __constant_cpu_to_le16(0x0005)
-#define TYPHOON_CMD_READ_STATS __constant_cpu_to_le16(0x0007)
-#define TYPHOON_CMD_XCVR_SELECT __constant_cpu_to_le16(0x0013)
-#define TYPHOON_CMD_SET_MAX_PKT_SIZE __constant_cpu_to_le16(0x001a)
-#define TYPHOON_CMD_READ_MEDIA_STATUS __constant_cpu_to_le16(0x001b)
-#define TYPHOON_CMD_GOTO_SLEEP __constant_cpu_to_le16(0x0023)
-#define TYPHOON_CMD_SET_MULTICAST_HASH __constant_cpu_to_le16(0x0025)
-#define TYPHOON_CMD_SET_MAC_ADDRESS __constant_cpu_to_le16(0x0026)
-#define TYPHOON_CMD_READ_MAC_ADDRESS __constant_cpu_to_le16(0x0027)
-#define TYPHOON_CMD_VLAN_TYPE_WRITE __constant_cpu_to_le16(0x002b)
-#define TYPHOON_CMD_CREATE_SA __constant_cpu_to_le16(0x0034)
-#define TYPHOON_CMD_DELETE_SA __constant_cpu_to_le16(0x0035)
-#define TYPHOON_CMD_READ_VERSIONS __constant_cpu_to_le16(0x0043)
-#define TYPHOON_CMD_IRQ_COALESCE_CTRL __constant_cpu_to_le16(0x0045)
-#define TYPHOON_CMD_ENABLE_WAKE_EVENTS __constant_cpu_to_le16(0x0049)
-#define TYPHOON_CMD_SET_OFFLOAD_TASKS __constant_cpu_to_le16(0x004f)
-#define TYPHOON_CMD_HELLO_RESP __constant_cpu_to_le16(0x0057)
-#define TYPHOON_CMD_HALT __constant_cpu_to_le16(0x005d)
-#define TYPHOON_CMD_READ_IPSEC_INFO __constant_cpu_to_le16(0x005e)
-#define TYPHOON_CMD_GET_IPSEC_ENABLE __constant_cpu_to_le16(0x0067)
-#define TYPHOON_CMD_GET_CMD_LVL __constant_cpu_to_le16(0x0069)
+#define TYPHOON_CMD_TX_ENABLE cpu_to_le16(0x0001)
+#define TYPHOON_CMD_TX_DISABLE cpu_to_le16(0x0002)
+#define TYPHOON_CMD_RX_ENABLE cpu_to_le16(0x0003)
+#define TYPHOON_CMD_RX_DISABLE cpu_to_le16(0x0004)
+#define TYPHOON_CMD_SET_RX_FILTER cpu_to_le16(0x0005)
+#define TYPHOON_CMD_READ_STATS cpu_to_le16(0x0007)
+#define TYPHOON_CMD_XCVR_SELECT cpu_to_le16(0x0013)
+#define TYPHOON_CMD_SET_MAX_PKT_SIZE cpu_to_le16(0x001a)
+#define TYPHOON_CMD_READ_MEDIA_STATUS cpu_to_le16(0x001b)
+#define TYPHOON_CMD_GOTO_SLEEP cpu_to_le16(0x0023)
+#define TYPHOON_CMD_SET_MULTICAST_HASH cpu_to_le16(0x0025)
+#define TYPHOON_CMD_SET_MAC_ADDRESS cpu_to_le16(0x0026)
+#define TYPHOON_CMD_READ_MAC_ADDRESS cpu_to_le16(0x0027)
+#define TYPHOON_CMD_VLAN_TYPE_WRITE cpu_to_le16(0x002b)
+#define TYPHOON_CMD_CREATE_SA cpu_to_le16(0x0034)
+#define TYPHOON_CMD_DELETE_SA cpu_to_le16(0x0035)
+#define TYPHOON_CMD_READ_VERSIONS cpu_to_le16(0x0043)
+#define TYPHOON_CMD_IRQ_COALESCE_CTRL cpu_to_le16(0x0045)
+#define TYPHOON_CMD_ENABLE_WAKE_EVENTS cpu_to_le16(0x0049)
+#define TYPHOON_CMD_SET_OFFLOAD_TASKS cpu_to_le16(0x004f)
+#define TYPHOON_CMD_HELLO_RESP cpu_to_le16(0x0057)
+#define TYPHOON_CMD_HALT cpu_to_le16(0x005d)
+#define TYPHOON_CMD_READ_IPSEC_INFO cpu_to_le16(0x005e)
+#define TYPHOON_CMD_GET_IPSEC_ENABLE cpu_to_le16(0x0067)
+#define TYPHOON_CMD_GET_CMD_LVL cpu_to_le16(0x0069)
u16 seqNo;
__le16 parm1;
__le32 parm2;
__le32 parm3;
-} __attribute__ ((packed));
+} __packed;
/* The Typhoon response descriptor, see command descriptor for details
*/
@@ -359,7 +359,7 @@ struct resp_desc {
__le16 parm1;
__le32 parm2;
__le32 parm3;
-} __attribute__ ((packed));
+} __packed;
#define INIT_COMMAND_NO_RESPONSE(x, command) \
do { struct cmd_desc *_ptr = (x); \
@@ -380,11 +380,11 @@ struct resp_desc {
/* TYPHOON_CMD_SET_RX_FILTER filter bits (cmd.parm1)
*/
-#define TYPHOON_RX_FILTER_DIRECTED __constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_FILTER_ALL_MCAST __constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_FILTER_BROADCAST __constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_FILTER_PROMISCOUS __constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_FILTER_MCAST_HASH __constant_cpu_to_le16(0x0010)
+#define TYPHOON_RX_FILTER_DIRECTED cpu_to_le16(0x0001)
+#define TYPHOON_RX_FILTER_ALL_MCAST cpu_to_le16(0x0002)
+#define TYPHOON_RX_FILTER_BROADCAST cpu_to_le16(0x0004)
+#define TYPHOON_RX_FILTER_PROMISCOUS cpu_to_le16(0x0008)
+#define TYPHOON_RX_FILTER_MCAST_HASH cpu_to_le16(0x0010)
/* TYPHOON_CMD_READ_STATS response format
*/
@@ -416,40 +416,40 @@ struct stats_resp {
__le32 rxOverflow;
__le32 rxFiltered;
__le32 linkStatus;
-#define TYPHOON_LINK_STAT_MASK __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_GOOD __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_BAD __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_SPEED_MASK __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_100MBPS __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_10MBPS __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_DUPLEX_MASK __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_FULL_DUPLEX __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_HALF_DUPLEX __constant_cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_STAT_MASK cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_GOOD cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_BAD cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_SPEED_MASK cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_100MBPS cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_10MBPS cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_DUPLEX_MASK cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_FULL_DUPLEX cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_HALF_DUPLEX cpu_to_le32(0x00000000)
__le32 unused2;
__le32 unused3;
-} __attribute__ ((packed));
+} __packed;
/* TYPHOON_CMD_XCVR_SELECT xcvr values (resp.parm1)
*/
-#define TYPHOON_XCVR_10HALF __constant_cpu_to_le16(0x0000)
-#define TYPHOON_XCVR_10FULL __constant_cpu_to_le16(0x0001)
-#define TYPHOON_XCVR_100HALF __constant_cpu_to_le16(0x0002)
-#define TYPHOON_XCVR_100FULL __constant_cpu_to_le16(0x0003)
-#define TYPHOON_XCVR_AUTONEG __constant_cpu_to_le16(0x0004)
+#define TYPHOON_XCVR_10HALF cpu_to_le16(0x0000)
+#define TYPHOON_XCVR_10FULL cpu_to_le16(0x0001)
+#define TYPHOON_XCVR_100HALF cpu_to_le16(0x0002)
+#define TYPHOON_XCVR_100FULL cpu_to_le16(0x0003)
+#define TYPHOON_XCVR_AUTONEG cpu_to_le16(0x0004)
/* TYPHOON_CMD_READ_MEDIA_STATUS (resp.parm1)
*/
-#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE __constant_cpu_to_le16(0x0004)
-#define TYPHOON_MEDIA_STAT_COLLISION_DETECT __constant_cpu_to_le16(0x0010)
-#define TYPHOON_MEDIA_STAT_CARRIER_SENSE __constant_cpu_to_le16(0x0020)
-#define TYPHOON_MEDIA_STAT_POLARITY_REV __constant_cpu_to_le16(0x0400)
-#define TYPHOON_MEDIA_STAT_NO_LINK __constant_cpu_to_le16(0x0800)
+#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE cpu_to_le16(0x0004)
+#define TYPHOON_MEDIA_STAT_COLLISION_DETECT cpu_to_le16(0x0010)
+#define TYPHOON_MEDIA_STAT_CARRIER_SENSE cpu_to_le16(0x0020)
+#define TYPHOON_MEDIA_STAT_POLARITY_REV cpu_to_le16(0x0400)
+#define TYPHOON_MEDIA_STAT_NO_LINK cpu_to_le16(0x0800)
/* TYPHOON_CMD_SET_MULTICAST_HASH enable values (cmd.parm1)
*/
-#define TYPHOON_MCAST_HASH_DISABLE __constant_cpu_to_le16(0x0000)
-#define TYPHOON_MCAST_HASH_ENABLE __constant_cpu_to_le16(0x0001)
-#define TYPHOON_MCAST_HASH_SET __constant_cpu_to_le16(0x0002)
+#define TYPHOON_MCAST_HASH_DISABLE cpu_to_le16(0x0000)
+#define TYPHOON_MCAST_HASH_ENABLE cpu_to_le16(0x0001)
+#define TYPHOON_MCAST_HASH_SET cpu_to_le16(0x0002)
/* TYPHOON_CMD_CREATE_SA descriptor and settings
*/
@@ -459,9 +459,9 @@ struct sa_descriptor {
u16 cmd;
u16 seqNo;
u16 mode;
-#define TYPHOON_SA_MODE_NULL __constant_cpu_to_le16(0x0000)
-#define TYPHOON_SA_MODE_AH __constant_cpu_to_le16(0x0001)
-#define TYPHOON_SA_MODE_ESP __constant_cpu_to_le16(0x0002)
+#define TYPHOON_SA_MODE_NULL cpu_to_le16(0x0000)
+#define TYPHOON_SA_MODE_AH cpu_to_le16(0x0001)
+#define TYPHOON_SA_MODE_ESP cpu_to_le16(0x0002)
u8 hashFlags;
#define TYPHOON_SA_HASH_ENABLE 0x01
#define TYPHOON_SA_HASH_SHA1 0x02
@@ -488,27 +488,27 @@ struct sa_descriptor {
u32 index;
u32 unused;
u32 unused2;
-} __attribute__ ((packed));
+} __packed;
/* TYPHOON_CMD_SET_OFFLOAD_TASKS bits (cmd.parm2 (Tx) & cmd.parm3 (Rx))
* This is all for IPv4.
*/
-#define TYPHOON_OFFLOAD_TCP_CHKSUM __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_OFFLOAD_UDP_CHKSUM __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_OFFLOAD_IP_CHKSUM __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_OFFLOAD_IPSEC __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_OFFLOAD_BCAST_THROTTLE __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_OFFLOAD_DHCP_PREVENT __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_OFFLOAD_VLAN __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_OFFLOAD_FILTERING __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_OFFLOAD_TCP_SEGMENT __constant_cpu_to_le32(0x00000200)
+#define TYPHOON_OFFLOAD_TCP_CHKSUM cpu_to_le32(0x00000002)
+#define TYPHOON_OFFLOAD_UDP_CHKSUM cpu_to_le32(0x00000004)
+#define TYPHOON_OFFLOAD_IP_CHKSUM cpu_to_le32(0x00000008)
+#define TYPHOON_OFFLOAD_IPSEC cpu_to_le32(0x00000010)
+#define TYPHOON_OFFLOAD_BCAST_THROTTLE cpu_to_le32(0x00000020)
+#define TYPHOON_OFFLOAD_DHCP_PREVENT cpu_to_le32(0x00000040)
+#define TYPHOON_OFFLOAD_VLAN cpu_to_le32(0x00000080)
+#define TYPHOON_OFFLOAD_FILTERING cpu_to_le32(0x00000100)
+#define TYPHOON_OFFLOAD_TCP_SEGMENT cpu_to_le32(0x00000200)
/* TYPHOON_CMD_ENABLE_WAKE_EVENTS bits (cmd.parm1)
*/
-#define TYPHOON_WAKE_MAGIC_PKT __constant_cpu_to_le16(0x01)
-#define TYPHOON_WAKE_LINK_EVENT __constant_cpu_to_le16(0x02)
-#define TYPHOON_WAKE_ICMP_ECHO __constant_cpu_to_le16(0x04)
-#define TYPHOON_WAKE_ARP __constant_cpu_to_le16(0x08)
+#define TYPHOON_WAKE_MAGIC_PKT cpu_to_le16(0x01)
+#define TYPHOON_WAKE_LINK_EVENT cpu_to_le16(0x02)
+#define TYPHOON_WAKE_ICMP_ECHO cpu_to_le16(0x04)
+#define TYPHOON_WAKE_ARP cpu_to_le16(0x08)
/* These are used to load the firmware image on the NIC
*/
@@ -518,14 +518,14 @@ struct typhoon_file_header {
__le32 numSections;
__le32 startAddr;
__le32 hmacDigest[5];
-} __attribute__ ((packed));
+} __packed;
struct typhoon_section_header {
__le32 len;
u16 checksum;
u16 reserved;
__le32 startAddr;
-} __attribute__ ((packed));
+} __packed;
/* The Typhoon Register offsets
*/
diff --git a/drivers/net/ethernet/8390/8390.c b/drivers/net/ethernet/8390/8390.c
new file mode 100644
index 00000000000..5db1f55abef
--- /dev/null
+++ b/drivers/net/ethernet/8390/8390.c
@@ -0,0 +1,103 @@
+/* 8390 core for usual drivers */
+
+static const char version[] =
+ "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+
+#include "lib8390.c"
+
+int ei_open(struct net_device *dev)
+{
+ return __ei_open(dev);
+}
+EXPORT_SYMBOL(ei_open);
+
+int ei_close(struct net_device *dev)
+{
+ return __ei_close(dev);
+}
+EXPORT_SYMBOL(ei_close);
+
+netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ return __ei_start_xmit(skb, dev);
+}
+EXPORT_SYMBOL(ei_start_xmit);
+
+struct net_device_stats *ei_get_stats(struct net_device *dev)
+{
+ return __ei_get_stats(dev);
+}
+EXPORT_SYMBOL(ei_get_stats);
+
+void ei_set_multicast_list(struct net_device *dev)
+{
+ __ei_set_multicast_list(dev);
+}
+EXPORT_SYMBOL(ei_set_multicast_list);
+
+void ei_tx_timeout(struct net_device *dev)
+{
+ __ei_tx_timeout(dev);
+}
+EXPORT_SYMBOL(ei_tx_timeout);
+
+irqreturn_t ei_interrupt(int irq, void *dev_id)
+{
+ return __ei_interrupt(irq, dev_id);
+}
+EXPORT_SYMBOL(ei_interrupt);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void ei_poll(struct net_device *dev)
+{
+ __ei_poll(dev);
+}
+EXPORT_SYMBOL(ei_poll);
+#endif
+
+const struct net_device_ops ei_netdev_ops = {
+ .ndo_open = ei_open,
+ .ndo_stop = ei_close,
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_set_rx_mode = ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
+EXPORT_SYMBOL(ei_netdev_ops);
+
+struct net_device *__alloc_ei_netdev(int size)
+{
+ struct net_device *dev = ____alloc_ei_netdev(size);
+ if (dev)
+ dev->netdev_ops = &ei_netdev_ops;
+ return dev;
+}
+EXPORT_SYMBOL(__alloc_ei_netdev);
+
+void NS8390_init(struct net_device *dev, int startp)
+{
+ __NS8390_init(dev, startp);
+}
+EXPORT_SYMBOL(NS8390_init);
+
+#if defined(MODULE)
+
+static int __init ns8390_module_init(void)
+{
+ return 0;
+}
+
+static void __exit ns8390_module_exit(void)
+{
+}
+
+module_init(ns8390_module_init);
+module_exit(ns8390_module_exit);
+#endif /* MODULE */
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/8390.h b/drivers/net/ethernet/8390/8390.h
index 8e209f5e7c1..3e2f2c2e7b5 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/ethernet/8390/8390.h
@@ -9,12 +9,11 @@
#include <linux/if_ether.h>
#include <linux/ioport.h>
+#include <linux/irqreturn.h>
#include <linux/skbuff.h>
#define TX_PAGES 12 /* Two Tx slots */
-#define ETHER_ADDR_LEN 6
-
/* The 8390 specific per-packet-header format. */
struct e8390_pkt_hdr {
unsigned char status; /* status */
@@ -22,34 +21,43 @@ struct e8390_pkt_hdr {
unsigned short count; /* header + packet length in bytes */
};
-#ifdef notdef
-extern int ei_debug;
-#else
-#define ei_debug 1
-#endif
-
#ifdef CONFIG_NET_POLL_CONTROLLER
-extern void ei_poll(struct net_device *dev);
-extern void eip_poll(struct net_device *dev);
+void ei_poll(struct net_device *dev);
+void eip_poll(struct net_device *dev);
#endif
+
/* Without I/O delay - non ISA or later chips */
-extern void NS8390_init(struct net_device *dev, int startp);
-extern int ei_open(struct net_device *dev);
-extern int ei_close(struct net_device *dev);
-extern irqreturn_t ei_interrupt(int irq, void *dev_id);
-extern struct net_device *__alloc_ei_netdev(int size);
+void NS8390_init(struct net_device *dev, int startp);
+int ei_open(struct net_device *dev);
+int ei_close(struct net_device *dev);
+irqreturn_t ei_interrupt(int irq, void *dev_id);
+void ei_tx_timeout(struct net_device *dev);
+netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev);
+void ei_set_multicast_list(struct net_device *dev);
+struct net_device_stats *ei_get_stats(struct net_device *dev);
+
+extern const struct net_device_ops ei_netdev_ops;
+
+struct net_device *__alloc_ei_netdev(int size);
static inline struct net_device *alloc_ei_netdev(void)
{
return __alloc_ei_netdev(0);
}
/* With I/O delay form */
-extern void NS8390p_init(struct net_device *dev, int startp);
-extern int eip_open(struct net_device *dev);
-extern int eip_close(struct net_device *dev);
-extern irqreturn_t eip_interrupt(int irq, void *dev_id);
-extern struct net_device *__alloc_eip_netdev(int size);
+void NS8390p_init(struct net_device *dev, int startp);
+int eip_open(struct net_device *dev);
+int eip_close(struct net_device *dev);
+irqreturn_t eip_interrupt(int irq, void *dev_id);
+void eip_tx_timeout(struct net_device *dev);
+netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev);
+void eip_set_multicast_list(struct net_device *dev);
+struct net_device_stats *eip_get_stats(struct net_device *dev);
+
+extern const struct net_device_ops eip_netdev_ops;
+
+struct net_device *__alloc_eip_netdev(int size);
static inline struct net_device *alloc_eip_netdev(void)
{
return __alloc_eip_netdev(0);
@@ -85,6 +93,7 @@ struct ei_device {
u32 *reg_offset; /* Register mapping table */
spinlock_t page_lock; /* Page register locks */
unsigned long priv; /* Private field to store bus IDs etc. */
+ u32 msg_enable; /* debug message level */
#ifdef AX88796_PLATFORM
unsigned char rxcr_base; /* default value for RXCR */
#endif
diff --git a/drivers/net/ethernet/8390/8390p.c b/drivers/net/ethernet/8390/8390p.c
new file mode 100644
index 00000000000..e8fc2e87e84
--- /dev/null
+++ b/drivers/net/ethernet/8390/8390p.c
@@ -0,0 +1,105 @@
+/* 8390 core for ISA devices needing bus delays */
+
+static const char version[] =
+ "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+
+#define ei_inb(_p) inb(_p)
+#define ei_outb(_v, _p) outb(_v, _p)
+#define ei_inb_p(_p) inb_p(_p)
+#define ei_outb_p(_v, _p) outb_p(_v, _p)
+
+#include "lib8390.c"
+
+int eip_open(struct net_device *dev)
+{
+ return __ei_open(dev);
+}
+EXPORT_SYMBOL(eip_open);
+
+int eip_close(struct net_device *dev)
+{
+ return __ei_close(dev);
+}
+EXPORT_SYMBOL(eip_close);
+
+netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ return __ei_start_xmit(skb, dev);
+}
+EXPORT_SYMBOL(eip_start_xmit);
+
+struct net_device_stats *eip_get_stats(struct net_device *dev)
+{
+ return __ei_get_stats(dev);
+}
+EXPORT_SYMBOL(eip_get_stats);
+
+void eip_set_multicast_list(struct net_device *dev)
+{
+ __ei_set_multicast_list(dev);
+}
+EXPORT_SYMBOL(eip_set_multicast_list);
+
+void eip_tx_timeout(struct net_device *dev)
+{
+ __ei_tx_timeout(dev);
+}
+EXPORT_SYMBOL(eip_tx_timeout);
+
+irqreturn_t eip_interrupt(int irq, void *dev_id)
+{
+ return __ei_interrupt(irq, dev_id);
+}
+EXPORT_SYMBOL(eip_interrupt);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void eip_poll(struct net_device *dev)
+{
+ __ei_poll(dev);
+}
+EXPORT_SYMBOL(eip_poll);
+#endif
+
+const struct net_device_ops eip_netdev_ops = {
+ .ndo_open = eip_open,
+ .ndo_stop = eip_close,
+ .ndo_start_xmit = eip_start_xmit,
+ .ndo_tx_timeout = eip_tx_timeout,
+ .ndo_get_stats = eip_get_stats,
+ .ndo_set_rx_mode = eip_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = eip_poll,
+#endif
+};
+EXPORT_SYMBOL(eip_netdev_ops);
+
+struct net_device *__alloc_eip_netdev(int size)
+{
+ struct net_device *dev = ____alloc_ei_netdev(size);
+ if (dev)
+ dev->netdev_ops = &eip_netdev_ops;
+ return dev;
+}
+EXPORT_SYMBOL(__alloc_eip_netdev);
+
+void NS8390p_init(struct net_device *dev, int startp)
+{
+ __NS8390_init(dev, startp);
+}
+EXPORT_SYMBOL(NS8390p_init);
+
+static int __init NS8390p_init_module(void)
+{
+ return 0;
+}
+
+static void __exit NS8390p_cleanup_module(void)
+{
+}
+
+module_init(NS8390p_init_module);
+module_exit(NS8390p_cleanup_module);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
new file mode 100644
index 00000000000..0988811f4e4
--- /dev/null
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -0,0 +1,205 @@
+#
+# 8390 device configuration
+#
+
+config NET_VENDOR_8390
+ bool "National Semi-conductor 8390 devices"
+ default y
+ depends on NET_VENDOR_NATSEMI
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Western Digital cards. If you say Y, you will be
+ asked for your specific card in the following questions.
+
+if NET_VENDOR_8390
+
+config PCMCIA_AXNET
+ tristate "Asix AX88190 PCMCIA support"
+ depends on PCMCIA
+ ---help---
+ Say Y here if you intend to attach an Asix AX88190-based PCMCIA
+ (PC-card) Fast Ethernet card to your computer. These cards are
+ nearly NE2000 compatible but need a separate driver due to a few
+ misfeatures.
+
+ To compile this driver as a module, choose M here: the module will be
+ called axnet_cs. If unsure, say N.
+
+config AX88796
+ tristate "ASIX AX88796 NE2000 clone support"
+ depends on (ARM || MIPS || SUPERH)
+ select CRC32
+ select PHYLIB
+ select MDIO_BITBANG
+ ---help---
+ AX88796 driver, using platform bus to provide
+ chip detection and resources
+
+config AX88796_93CX6
+ bool "ASIX AX88796 external 93CX6 eeprom support"
+ depends on AX88796
+ select EEPROM_93CX6
+ ---help---
+ Select this if your platform comes with an external 93CX6 eeprom.
+
+config HYDRA
+ tristate "Hydra support"
+ depends on ZORRO
+ select CRC32
+ ---help---
+ If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called hydra.
+
+config ARM_ETHERH
+ tristate "I-cubed EtherH/ANT EtherM support"
+ depends on ARM && ARCH_ACORN
+ select CRC32
+ ---help---
+ If you have an Acorn system with one of these network cards, you
+ should say Y to this option if you wish to use it with Linux.
+
+config MAC8390
+ bool "Macintosh NS 8390 based ethernet cards"
+ depends on MAC
+ select CRC32
+ ---help---
+ If you want to include a driver to support Nubus or LC-PDS
+ Ethernet cards using an NS8390 chipset or its equivalent, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+config MCF8390
+ tristate "ColdFire NS8390 based Ethernet support"
+ depends on COLDFIRE
+ select CRC32
+ ---help---
+ This driver is for Ethernet devices using an NS8390-compatible
+ chipset on many common ColdFire CPU based boards. Many of the older
+ Freescale dev boards use this, and some other common boards like
+ some SnapGear routers do as well.
+
+ If you have one of these boards and want to use the network interface
+ on them then choose Y. To compile this driver as a module, choose M
+ here, the module will be called mcf8390.
+
+config NE2000
+ tristate "NE2000/NE1000 support"
+ depends on (ISA || (Q40 && m) || M32R || MACH_TX49XX)
+ select CRC32
+ ---help---
+ If you have a network (Ethernet) card of this type, say Y and read
+ the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>. Many Ethernet cards
+ without a specific driver are compatible with NE2000.
+
+ If you have a PCI NE2000 card however, say N here and Y to "PCI
+ NE2000 and clone support" below.
+
+ To compile this driver as a module, choose M here. The module
+ will be called ne.
+
+config NE2K_PCI
+ tristate "PCI NE2000 and clones support (see help)"
+ depends on PCI
+ select CRC32
+ ---help---
+ This driver is for NE2000 compatible PCI cards. It will not work
+ with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
+ support" below). If you have a PCI NE2000 network (Ethernet) card,
+ say Y and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ This driver also works for the following NE2000 clone cards:
+ RealTek RTL-8029 Winbond 89C940 Compex RL2000 KTI ET32P2
+ NetVin NV5000SC Via 86C926 SureCom NE34 Winbond
+ Holtek HT80232 Holtek HT80229
+
+ To compile this driver as a module, choose M here. The module
+ will be called ne2k-pci.
+
+config APNE
+ tristate "PCMCIA NE2000 support"
+ depends on AMIGA_PCMCIA
+ select CRC32
+ ---help---
+ If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise,
+ say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called apne.
+
+config PCMCIA_PCNET
+ tristate "NE2000 compatible PCMCIA support"
+ depends on PCMCIA
+ select CRC32
+ ---help---
+ Say Y here if you intend to attach an NE2000 compatible PCMCIA
+ (PC-card) Ethernet or Fast Ethernet card to your computer.
+
+ To compile this driver as a module, choose M here: the module will be
+ called pcnet_cs. If unsure, say N.
+
+config STNIC
+ tristate "National DP83902AV support"
+ depends on SUPERH
+ select CRC32
+ ---help---
+ Support for cards based on the National Semiconductor DP83902AV
+ ST-NIC Serial Network Interface Controller for Twisted Pair. This
+ is a 10Mbit/sec Ethernet controller. Product overview and specs at
+ <http://www.national.com/pf/DP/DP83902A.html>.
+
+ If unsure, say N.
+
+config ULTRA
+ tristate "SMC Ultra support"
+ depends on ISA
+ select CRC32
+ ---help---
+ If you have a network (Ethernet) card of this type, say Y and read
+ the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Important: There have been many reports that, with some motherboards
+ mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
+ such as some BusLogic models) causes corruption problems with many
+ operating systems. The Linux smc-ultra driver has a work-around for
+ this but keep it in mind if you have such a SCSI card and have
+ problems.
+
+ To compile this driver as a module, choose M here. The module
+ will be called smc-ultra.
+
+config WD80x3
+ tristate "WD80*3 support"
+ depends on ISA
+ select CRC32
+ ---help---
+ If you have a network (Ethernet) card of this type, say Y and read
+ the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called wd.
+
+config ZORRO8390
+ tristate "Zorro NS8390-based Ethernet support"
+ depends on ZORRO
+ select CRC32
+ ---help---
+ This driver is for Zorro Ethernet cards using an NS8390-compatible
+ chipset, like the Village Tronic Ariadne II and the Individual
+ Computers X-Surf Ethernet cards. If you have such a card, say Y.
+ Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called zorro8390.
+
+endif # NET_VENDOR_8390
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile
new file mode 100644
index 00000000000..ff3b3189418
--- /dev/null
+++ b/drivers/net/ethernet/8390/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the 8390 network device drivers.
+#
+
+obj-$(CONFIG_MAC8390) += mac8390.o
+obj-$(CONFIG_APNE) += apne.o 8390.o
+obj-$(CONFIG_ARM_ETHERH) += etherh.o
+obj-$(CONFIG_AX88796) += ax88796.o
+obj-$(CONFIG_HYDRA) += hydra.o 8390.o
+obj-$(CONFIG_MCF8390) += mcf8390.o 8390.o
+obj-$(CONFIG_NE2000) += ne.o 8390p.o
+obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
+obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o
+obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
+obj-$(CONFIG_STNIC) += stnic.o 8390.o
+obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
+obj-$(CONFIG_WD80x3) += wd.o 8390.o
+obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
diff --git a/drivers/net/apne.c b/drivers/net/ethernet/8390/apne.c
index 867f6fff543..c56ac9ebc08 100644
--- a/drivers/net/apne.c
+++ b/drivers/net/ethernet/8390/apne.c
@@ -36,9 +36,9 @@
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
#include <linux/jiffies.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/amigaints.h>
@@ -78,9 +78,6 @@
struct net_device * __init apne_probe(int unit);
static int apne_probe1(struct net_device *dev, int ioaddr);
-static int apne_open(struct net_device *dev);
-static int apne_close(struct net_device *dev);
-
static void apne_reset_8390(struct net_device *dev);
static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
@@ -119,9 +116,15 @@ static const char version[] =
static int apne_owned; /* signal if card already owned */
+static u32 apne_msg_enable;
+module_param_named(msg_enable, apne_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
+MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
+
struct net_device * __init apne_probe(int unit)
{
struct net_device *dev;
+ struct ei_device *ei_local;
+
#ifndef MANUAL_CONFIG
char tuple[8];
#endif
@@ -136,11 +139,11 @@ struct net_device * __init apne_probe(int unit)
if ( !(AMIGAHW_PRESENT(PCMCIA)) )
return ERR_PTR(-ENODEV);
- printk("Looking for PCMCIA ethernet card : ");
+ pr_info("Looking for PCMCIA ethernet card : ");
/* check if a card is inserted */
if (!(PCMCIA_INSERTED)) {
- printk("NO PCMCIA card inserted\n");
+ pr_cont("NO PCMCIA card inserted\n");
return ERR_PTR(-ENODEV);
}
@@ -151,6 +154,8 @@ struct net_device * __init apne_probe(int unit)
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
}
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = apne_msg_enable;
/* disable pcmcia irq for readtuple */
pcmcia_disable_irq();
@@ -158,14 +163,14 @@ struct net_device * __init apne_probe(int unit)
#ifndef MANUAL_CONFIG
if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) ||
(tuple[2] != CISTPL_FUNCID_NETWORK)) {
- printk("not an ethernet card\n");
+ pr_cont("not an ethernet card\n");
/* XXX: shouldn't we re-enable irq here? */
free_netdev(dev);
return ERR_PTR(-ENODEV);
}
#endif
- printk("ethernet PCMCIA card inserted\n");
+ pr_cont("ethernet PCMCIA card inserted\n");
if (!init_pcmcia()) {
/* XXX: shouldn't we re-enable irq here? */
@@ -207,12 +212,11 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
int neX000, ctron;
#endif
static unsigned version_printed;
- DECLARE_MAC_BUF(mac);
- if (ei_debug && version_printed++ == 0)
- printk(version);
+ if ((apne_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
+ netdev_info(dev, version);
- printk("PCMCIA NE*000 ethercard probe");
+ netdev_info(dev, "PCMCIA NE*000 ethercard probe");
/* Reset card. Who knows what dain-bramaged state it was left in. */
{ unsigned long reset_start_time = jiffies;
@@ -221,7 +225,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
- printk(" not found (no reset ack).\n");
+ pr_cont(" not found (no reset ack).\n");
return -ENODEV;
}
@@ -292,7 +296,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
start_page = 0x01;
stop_page = (wordlength == 2) ? 0x40 : 0x20;
} else {
- printk(" not found.\n");
+ pr_cont(" not found.\n");
return -ENXIO;
}
@@ -315,17 +319,18 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr;
dev->irq = IRQ_AMIGA_PORTS;
+ dev->netdev_ops = &ei_netdev_ops;
/* Install the Interrupt handler */
i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev);
if (i) return i;
- for(i = 0; i < ETHER_ADDR_LEN; i++)
+ for (i = 0; i < ETH_ALEN; i++)
dev->dev_addr[i] = SA_prom[i];
- printk(" %s\n", print_mac(mac, dev->dev_addr));
+ pr_cont(" %pM\n", dev->dev_addr);
- printk("%s: %s found.\n", dev->name, name);
+ netdev_info(dev, "%s found.\n", name);
ei_status.name = name;
ei_status.tx_start_page = start_page;
@@ -338,11 +343,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
ei_status.block_input = &apne_block_input;
ei_status.block_output = &apne_block_output;
ei_status.get_8390_hdr = &apne_get_8390_hdr;
- dev->open = &apne_open;
- dev->stop = &apne_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
+
NS8390_init(dev, 0);
pcmcia_ack_int(pcmcia_get_intreq()); /* ack PCMCIA int req */
@@ -353,32 +354,17 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
return 0;
}
-static int
-apne_open(struct net_device *dev)
-{
- ei_open(dev);
- return 0;
-}
-
-static int
-apne_close(struct net_device *dev)
-{
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
- ei_close(dev);
- return 0;
-}
-
/* Hard reset the card. This used to pause for the same period that a
8390 reset command required, but that shouldn't be necessary. */
static void
apne_reset_8390(struct net_device *dev)
{
unsigned long reset_start_time = jiffies;
+ struct ei_device *ei_local = netdev_priv(dev);
init_pcmcia();
- if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
+ netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
@@ -388,8 +374,8 @@ apne_reset_8390(struct net_device *dev)
/* This check _should_not_ be necessary, omit eventually. */
while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
- printk("%s: ne_reset_8390() did not complete.\n", dev->name);
- break;
+ netdev_err(dev, "ne_reset_8390() did not complete.\n");
+ break;
}
outb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */
}
@@ -409,9 +395,9 @@ apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pa
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_get_8390_hdr "
- "[DMAstat:%d][irqlock:%d][intr:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock, dev->irq);
+ netdev_err(dev, "DMAing conflict in ne_get_8390_hdr "
+ "[DMAstat:%d][irqlock:%d][intr:%d].\n",
+ ei_status.dmaing, ei_status.irqlock, dev->irq);
return;
}
@@ -456,9 +442,9 @@ apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int rin
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_block_input "
- "[DMAstat:%d][irqlock:%d][intr:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock, dev->irq);
+ netdev_err(dev, "DMAing conflict in ne_block_input "
+ "[DMAstat:%d][irqlock:%d][intr:%d].\n",
+ ei_status.dmaing, ei_status.irqlock, dev->irq);
return;
}
ei_status.dmaing |= 0x01;
@@ -477,7 +463,7 @@ apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int rin
buf[count-1] = inb(NE_BASE + NE_DATAPORT);
}
} else {
- ptrc = (char*)buf;
+ ptrc = buf;
for (cnt = 0; cnt < count; cnt++)
*ptrc++ = inb(NE_BASE + NE_DATAPORT);
}
@@ -504,9 +490,9 @@ apne_block_output(struct net_device *dev, int count,
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_block_output."
- "[DMAstat:%d][irqlock:%d][intr:%d]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock, dev->irq);
+ netdev_err(dev, "DMAing conflict in ne_block_output."
+ "[DMAstat:%d][irqlock:%d][intr:%d]\n",
+ ei_status.dmaing, ei_status.irqlock, dev->irq);
return;
}
ei_status.dmaing |= 0x01;
@@ -536,7 +522,7 @@ apne_block_output(struct net_device *dev, int count,
while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */
- printk("%s: timeout waiting for Tx RDC.\n", dev->name);
+ netdev_warn(dev, "timeout waiting for Tx RDC.\n");
apne_reset_8390(dev);
NS8390_init(dev,1);
break;
@@ -544,7 +530,6 @@ apne_block_output(struct net_device *dev, int count,
outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01;
- return;
}
static irqreturn_t apne_interrupt(int irq, void *dev_id)
@@ -560,8 +545,8 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id)
pcmcia_ack_int(pcmcia_intreq);
return IRQ_NONE;
}
- if (ei_debug > 3)
- printk("pcmcia intreq = %x\n", pcmcia_intreq);
+ if (apne_msg_enable & NETIF_MSG_INTR)
+ pr_debug("pcmcia intreq = %x\n", pcmcia_intreq);
pcmcia_disable_irq(); /* to get rid of the sti() within ei_interrupt */
ei_interrupt(irq, dev_id);
pcmcia_ack_int(pcmcia_get_intreq());
@@ -575,9 +560,7 @@ static struct net_device *apne_dev;
static int __init apne_module_init(void)
{
apne_dev = apne_probe(-1);
- if (IS_ERR(apne_dev))
- return PTR_ERR(apne_dev);
- return 0;
+ return PTR_ERR_OR_ZERO(apne_dev);
}
static void __exit apne_module_exit(void)
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
new file mode 100644
index 00000000000..1d162ccb473
--- /dev/null
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -0,0 +1,1016 @@
+/* drivers/net/ethernet/8390/ax88796.c
+ *
+ * Copyright 2005,2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Asix AX88796 10/100 Ethernet controller support
+ * Based on ne.c, by Donald Becker, et-al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/isapnp.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/phy.h>
+#include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
+
+#include <net/ax88796.h>
+
+
+/* Rename the lib8390.c functions to show that they are in this driver */
+#define __ei_open ax_ei_open
+#define __ei_close ax_ei_close
+#define __ei_poll ax_ei_poll
+#define __ei_start_xmit ax_ei_start_xmit
+#define __ei_tx_timeout ax_ei_tx_timeout
+#define __ei_get_stats ax_ei_get_stats
+#define __ei_set_multicast_list ax_ei_set_multicast_list
+#define __ei_interrupt ax_ei_interrupt
+#define ____alloc_ei_netdev ax__alloc_ei_netdev
+#define __NS8390_init ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a) readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a) ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x) (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+#define DRV_NAME "ax88796"
+#define DRV_VERSION "1.00"
+
+/* from ne.c */
+#define NE_CMD EI_SHIFT(0x00)
+#define NE_RESET EI_SHIFT(0x1f)
+#define NE_DATAPORT EI_SHIFT(0x10)
+
+#define NE1SM_START_PG 0x20 /* First page of TX buffer */
+#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
+#define NESM_START_PG 0x40 /* First page of TX buffer */
+#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
+
+#define AX_GPOC_PPDSET BIT(6)
+
+static u32 ax_msg_enable;
+
+/* device private data */
+
+struct ax_device {
+ struct mii_bus *mii_bus;
+ struct mdiobb_ctrl bb_ctrl;
+ struct phy_device *phy_dev;
+ void __iomem *addr_memr;
+ u8 reg_memr;
+ int link;
+ int speed;
+ int duplex;
+
+ void __iomem *map2;
+ const struct ax_plat_data *plat;
+
+ unsigned char running;
+ unsigned char resume_open;
+ unsigned int irqflags;
+
+ u32 reg_offsets[0x20];
+};
+
+static inline struct ax_device *to_ax_dev(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ return (struct ax_device *)(ei_local + 1);
+}
+
+/*
+ * ax_initial_check
+ *
+ * do an initial probe for the card to check whether it exists
+ * and is functional
+ */
+static int ax_initial_check(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *ioaddr = ei_local->mem;
+ int reg0;
+ int regd;
+
+ reg0 = ei_inb(ioaddr);
+ if (reg0 == 0xFF)
+ return -ENODEV;
+
+ ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD);
+ regd = ei_inb(ioaddr + 0x0d);
+ ei_outb(0xff, ioaddr + 0x0d);
+ ei_outb(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD);
+ ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
+ if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
+ ei_outb(reg0, ioaddr);
+ ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/*
+ * Hard reset the card. This used to pause for the same period that a
+ * 8390 reset command required, but that shouldn't be necessary.
+ */
+static void ax_reset_8390(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ unsigned long reset_start_time = jiffies;
+ void __iomem *addr = (void __iomem *)dev->base_addr;
+
+ netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
+
+ ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
+
+ ei_local->txing = 0;
+ ei_local->dmaing = 0;
+
+ /* This check _should_not_ be necessary, omit eventually. */
+ while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
+ if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
+ netdev_warn(dev, "%s: did not complete.\n", __func__);
+ break;
+ }
+ }
+
+ ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */
+}
+
+
+static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
+ int ring_page)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *nic_base = ei_local->mem;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_local->dmaing) {
+ netdev_err(dev, "DMAing conflict in %s "
+ "[DMAstat:%d][irqlock:%d].\n",
+ __func__,
+ ei_local->dmaing, ei_local->irqlock);
+ return;
+ }
+
+ ei_local->dmaing |= 0x01;
+ ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
+ ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+ ei_outb(0, nic_base + EN0_RCNTHI);
+ ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */
+ ei_outb(ring_page, nic_base + EN0_RSARHI);
+ ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ if (ei_local->word16)
+ ioread16_rep(nic_base + NE_DATAPORT, hdr,
+ sizeof(struct e8390_pkt_hdr) >> 1);
+ else
+ ioread8_rep(nic_base + NE_DATAPORT, hdr,
+ sizeof(struct e8390_pkt_hdr));
+
+ ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_local->dmaing &= ~0x01;
+
+ le16_to_cpus(&hdr->count);
+}
+
+
+/*
+ * Block input and output, similar to the Crynwr packet driver. If
+ * you are porting to a new ethercard, look at the packet driver
+ * source for hints. The NEx000 doesn't share the on-board packet
+ * memory -- you have to put the packet out through the "remote DMA"
+ * dataport using ei_outb.
+ */
+static void ax_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *nic_base = ei_local->mem;
+ char *buf = skb->data;
+
+ if (ei_local->dmaing) {
+ netdev_err(dev,
+ "DMAing conflict in %s "
+ "[DMAstat:%d][irqlock:%d].\n",
+ __func__,
+ ei_local->dmaing, ei_local->irqlock);
+ return;
+ }
+
+ ei_local->dmaing |= 0x01;
+
+ ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + NE_CMD);
+ ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+ ei_outb(count >> 8, nic_base + EN0_RCNTHI);
+ ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
+ ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
+ ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ if (ei_local->word16) {
+ ioread16_rep(nic_base + NE_DATAPORT, buf, count >> 1);
+ if (count & 0x01)
+ buf[count-1] = ei_inb(nic_base + NE_DATAPORT);
+
+ } else {
+ ioread8_rep(nic_base + NE_DATAPORT, buf, count);
+ }
+
+ ei_local->dmaing &= ~1;
+}
+
+static void ax_block_output(struct net_device *dev, int count,
+ const unsigned char *buf, const int start_page)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ void __iomem *nic_base = ei_local->mem;
+ unsigned long dma_start;
+
+ /*
+ * Round the count up for word writes. Do we need to do this?
+ * What effect will an odd byte count have on the 8390? I
+ * should check someday.
+ */
+ if (ei_local->word16 && (count & 0x01))
+ count++;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_local->dmaing) {
+ netdev_err(dev, "DMAing conflict in %s."
+ "[DMAstat:%d][irqlock:%d]\n",
+ __func__,
+ ei_local->dmaing, ei_local->irqlock);
+ return;
+ }
+
+ ei_local->dmaing |= 0x01;
+ /* We should already be in page 0, but to be safe... */
+ ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+ ei_outb(ENISR_RDC, nic_base + EN0_ISR);
+
+ /* Now the normal output. */
+ ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+ ei_outb(count >> 8, nic_base + EN0_RCNTHI);
+ ei_outb(0x00, nic_base + EN0_RSARLO);
+ ei_outb(start_page, nic_base + EN0_RSARHI);
+
+ ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+ if (ei_local->word16)
+ iowrite16_rep(nic_base + NE_DATAPORT, buf, count >> 1);
+ else
+ iowrite8_rep(nic_base + NE_DATAPORT, buf, count);
+
+ dma_start = jiffies;
+
+ while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
+ if (time_after(jiffies, dma_start + 2 * HZ / 100)) { /* 20ms */
+ netdev_warn(dev, "timeout waiting for Tx RDC.\n");
+ ax_reset_8390(dev);
+ ax_NS8390_init(dev, 1);
+ break;
+ }
+ }
+
+ ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_local->dmaing &= ~0x01;
+}
+
+/* definitions for accessing MII/EEPROM interface */
+
+#define AX_MEMR EI_SHIFT(0x14)
+#define AX_MEMR_MDC BIT(0)
+#define AX_MEMR_MDIR BIT(1)
+#define AX_MEMR_MDI BIT(2)
+#define AX_MEMR_MDO BIT(3)
+#define AX_MEMR_EECS BIT(4)
+#define AX_MEMR_EEI BIT(5)
+#define AX_MEMR_EEO BIT(6)
+#define AX_MEMR_EECLK BIT(7)
+
+static void ax_handle_link_change(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ struct phy_device *phy_dev = ax->phy_dev;
+ int status_change = 0;
+
+ if (phy_dev->link && ((ax->speed != phy_dev->speed) ||
+ (ax->duplex != phy_dev->duplex))) {
+
+ ax->speed = phy_dev->speed;
+ ax->duplex = phy_dev->duplex;
+ status_change = 1;
+ }
+
+ if (phy_dev->link != ax->link) {
+ if (!phy_dev->link) {
+ ax->speed = 0;
+ ax->duplex = -1;
+ }
+ ax->link = phy_dev->link;
+
+ status_change = 1;
+ }
+
+ if (status_change)
+ phy_print_status(phy_dev);
+}
+
+static int ax_mii_probe(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ struct phy_device *phy_dev = NULL;
+ int ret;
+
+ /* find the first phy */
+ phy_dev = phy_find_first(ax->mii_bus);
+ if (!phy_dev) {
+ netdev_err(dev, "no PHY found\n");
+ return -ENODEV;
+ }
+
+ ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change,
+ PHY_INTERFACE_MODE_MII);
+ if (ret) {
+ netdev_err(dev, "Could not attach to PHY\n");
+ return ret;
+ }
+
+ /* mask with MAC supported features */
+ phy_dev->supported &= PHY_BASIC_FEATURES;
+ phy_dev->advertising = phy_dev->supported;
+
+ ax->phy_dev = phy_dev;
+
+ netdev_info(dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+ phy_dev->drv->name, dev_name(&phy_dev->dev), phy_dev->irq);
+
+ return 0;
+}
+
+static void ax_phy_switch(struct net_device *dev, int on)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ struct ax_device *ax = to_ax_dev(dev);
+
+ u8 reg_gpoc = ax->plat->gpoc_val;
+
+ if (!!on)
+ reg_gpoc &= ~AX_GPOC_PPDSET;
+ else
+ reg_gpoc |= AX_GPOC_PPDSET;
+
+ ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17));
+}
+
+static int ax_open(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ int ret;
+
+ netdev_dbg(dev, "open\n");
+
+ ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+ dev->name, dev);
+ if (ret)
+ goto failed_request_irq;
+
+ /* turn the phy on (if turned off) */
+ ax_phy_switch(dev, 1);
+
+ ret = ax_mii_probe(dev);
+ if (ret)
+ goto failed_mii_probe;
+ phy_start(ax->phy_dev);
+
+ ret = ax_ei_open(dev);
+ if (ret)
+ goto failed_ax_ei_open;
+
+ ax->running = 1;
+
+ return 0;
+
+ failed_ax_ei_open:
+ phy_disconnect(ax->phy_dev);
+ failed_mii_probe:
+ ax_phy_switch(dev, 0);
+ free_irq(dev->irq, dev);
+ failed_request_irq:
+ return ret;
+}
+
+static int ax_close(struct net_device *dev)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+
+ netdev_dbg(dev, "close\n");
+
+ ax->running = 0;
+ wmb();
+
+ ax_ei_close(dev);
+
+ /* turn the phy off */
+ ax_phy_switch(dev, 0);
+ phy_disconnect(ax->phy_dev);
+
+ free_irq(dev->irq, dev);
+ return 0;
+}
+
+static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ struct phy_device *phy_dev = ax->phy_dev;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (!phy_dev)
+ return -ENODEV;
+
+ return phy_mii_ioctl(phy_dev, req, cmd);
+}
+
+/* ethtool ops */
+
+static void ax_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct platform_device *pdev = to_platform_device(dev->dev.parent);
+
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info));
+}
+
+static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ struct phy_device *phy_dev = ax->phy_dev;
+
+ if (!phy_dev)
+ return -ENODEV;
+
+ return phy_ethtool_gset(phy_dev, cmd);
+}
+
+static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct ax_device *ax = to_ax_dev(dev);
+ struct phy_device *phy_dev = ax->phy_dev;
+
+ if (!phy_dev)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phy_dev, cmd);
+}
+
+static u32 ax_get_msglevel(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ return ei_local->msg_enable;
+}
+
+static void ax_set_msglevel(struct net_device *dev, u32 v)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ ei_local->msg_enable = v;
+}
+
+static const struct ethtool_ops ax_ethtool_ops = {
+ .get_drvinfo = ax_get_drvinfo,
+ .get_settings = ax_get_settings,
+ .set_settings = ax_set_settings,
+ .get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
+ .get_msglevel = ax_get_msglevel,
+ .set_msglevel = ax_set_msglevel,
+};
+
+#ifdef CONFIG_AX88796_93CX6
+static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom)
+{
+ struct ei_device *ei_local = eeprom->data;
+ u8 reg = ei_inb(ei_local->mem + AX_MEMR);
+
+ eeprom->reg_data_in = reg & AX_MEMR_EEI;
+ eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */
+ eeprom->reg_data_clock = reg & AX_MEMR_EECLK;
+ eeprom->reg_chip_select = reg & AX_MEMR_EECS;
+}
+
+static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom)
+{
+ struct ei_device *ei_local = eeprom->data;
+ u8 reg = ei_inb(ei_local->mem + AX_MEMR);
+
+ reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS);
+
+ if (eeprom->reg_data_in)
+ reg |= AX_MEMR_EEI;
+ if (eeprom->reg_data_clock)
+ reg |= AX_MEMR_EECLK;
+ if (eeprom->reg_chip_select)
+ reg |= AX_MEMR_EECS;
+
+ ei_outb(reg, ei_local->mem + AX_MEMR);
+ udelay(10);
+}
+#endif
+
+static const struct net_device_ops ax_netdev_ops = {
+ .ndo_open = ax_open,
+ .ndo_stop = ax_close,
+ .ndo_do_ioctl = ax_ioctl,
+
+ .ndo_start_xmit = ax_ei_start_xmit,
+ .ndo_tx_timeout = ax_ei_tx_timeout,
+ .ndo_get_stats = ax_ei_get_stats,
+ .ndo_set_rx_mode = ax_ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ax_ei_poll,
+#endif
+};
+
+static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
+{
+ struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+ if (level)
+ ax->reg_memr |= AX_MEMR_MDC;
+ else
+ ax->reg_memr &= ~AX_MEMR_MDC;
+
+ ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
+{
+ struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+ if (output)
+ ax->reg_memr &= ~AX_MEMR_MDIR;
+ else
+ ax->reg_memr |= AX_MEMR_MDIR;
+
+ ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value)
+{
+ struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+
+ if (value)
+ ax->reg_memr |= AX_MEMR_MDO;
+ else
+ ax->reg_memr &= ~AX_MEMR_MDO;
+
+ ei_outb(ax->reg_memr, ax->addr_memr);
+}
+
+static int ax_bb_get_data(struct mdiobb_ctrl *ctrl)
+{
+ struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
+ int reg_memr = ei_inb(ax->addr_memr);
+
+ return reg_memr & AX_MEMR_MDI ? 1 : 0;
+}
+
+static struct mdiobb_ops bb_ops = {
+ .owner = THIS_MODULE,
+ .set_mdc = ax_bb_mdc,
+ .set_mdio_dir = ax_bb_dir,
+ .set_mdio_data = ax_bb_set_data,
+ .get_mdio_data = ax_bb_get_data,
+};
+
+/* setup code */
+
+static int ax_mii_init(struct net_device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev->dev.parent);
+ struct ei_device *ei_local = netdev_priv(dev);
+ struct ax_device *ax = to_ax_dev(dev);
+ int err, i;
+
+ ax->bb_ctrl.ops = &bb_ops;
+ ax->addr_memr = ei_local->mem + AX_MEMR;
+ ax->mii_bus = alloc_mdio_bitbang(&ax->bb_ctrl);
+ if (!ax->mii_bus) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ ax->mii_bus->name = "ax88796_mii_bus";
+ ax->mii_bus->parent = dev->dev.parent;
+ snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ pdev->name, pdev->id);
+
+ ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!ax->mii_bus->irq) {
+ err = -ENOMEM;
+ goto out_free_mdio_bitbang;
+ }
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ ax->mii_bus->irq[i] = PHY_POLL;
+
+ err = mdiobus_register(ax->mii_bus);
+ if (err)
+ goto out_free_irq;
+
+ return 0;
+
+ out_free_irq:
+ kfree(ax->mii_bus->irq);
+ out_free_mdio_bitbang:
+ free_mdio_bitbang(ax->mii_bus);
+ out:
+ return err;
+}
+
+static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
+{
+ void __iomem *ioaddr = ei_local->mem;
+ struct ax_device *ax = to_ax_dev(dev);
+
+ /* Select page 0 */
+ ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_STOP, ioaddr + E8390_CMD);
+
+ /* set to byte access */
+ ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
+ ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
+}
+
+/*
+ * ax_init_dev
+ *
+ * initialise the specified device, taking care to note the MAC
+ * address it may already have (if configured), ensure
+ * the device is ready to be used by lib8390.c and registerd with
+ * the network layer.
+ */
+static int ax_init_dev(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ struct ax_device *ax = to_ax_dev(dev);
+ void __iomem *ioaddr = ei_local->mem;
+ unsigned int start_page;
+ unsigned int stop_page;
+ int ret;
+ int i;
+
+ ret = ax_initial_check(dev);
+ if (ret)
+ goto err_out;
+
+ /* setup goes here */
+
+ ax_initial_setup(dev, ei_local);
+
+ /* read the mac from the card prom if we need it */
+
+ if (ax->plat->flags & AXFLG_HAS_EEPROM) {
+ unsigned char SA_prom[32];
+
+ for (i = 0; i < sizeof(SA_prom); i += 2) {
+ SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
+ SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT);
+ }
+
+ if (ax->plat->wordlength == 2)
+ for (i = 0; i < 16; i++)
+ SA_prom[i] = SA_prom[i+i];
+
+ memcpy(dev->dev_addr, SA_prom, ETH_ALEN);
+ }
+
+#ifdef CONFIG_AX88796_93CX6
+ if (ax->plat->flags & AXFLG_HAS_93CX6) {
+ unsigned char mac_addr[ETH_ALEN];
+ struct eeprom_93cx6 eeprom;
+
+ eeprom.data = ei_local;
+ eeprom.register_read = ax_eeprom_register_read;
+ eeprom.register_write = ax_eeprom_register_write;
+ eeprom.width = PCI_EEPROM_WIDTH_93C56;
+
+ eeprom_93cx6_multiread(&eeprom, 0,
+ (__le16 __force *)mac_addr,
+ sizeof(mac_addr) >> 1);
+
+ memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
+ }
+#endif
+ if (ax->plat->wordlength == 2) {
+ /* We must set the 8390 for word mode. */
+ ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
+ start_page = NESM_START_PG;
+ stop_page = NESM_STOP_PG;
+ } else {
+ start_page = NE1SM_START_PG;
+ stop_page = NE1SM_STOP_PG;
+ }
+
+ /* load the mac-address from the device */
+ if (ax->plat->flags & AXFLG_MAC_FROMDEV) {
+ ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+ ei_local->mem + E8390_CMD); /* 0x61 */
+ for (i = 0; i < ETH_ALEN; i++)
+ dev->dev_addr[i] =
+ ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+ }
+
+ if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) &&
+ ax->plat->mac_addr)
+ memcpy(dev->dev_addr, ax->plat->mac_addr, ETH_ALEN);
+
+ ax_reset_8390(dev);
+
+ ei_local->name = "AX88796";
+ ei_local->tx_start_page = start_page;
+ ei_local->stop_page = stop_page;
+ ei_local->word16 = (ax->plat->wordlength == 2);
+ ei_local->rx_start_page = start_page + TX_PAGES;
+
+#ifdef PACKETBUF_MEMSIZE
+ /* Allow the packet buffer size to be overridden by know-it-alls. */
+ ei_local->stop_page = ei_local->tx_start_page + PACKETBUF_MEMSIZE;
+#endif
+
+ ei_local->reset_8390 = &ax_reset_8390;
+ ei_local->block_input = &ax_block_input;
+ ei_local->block_output = &ax_block_output;
+ ei_local->get_8390_hdr = &ax_get_8390_hdr;
+ ei_local->priv = 0;
+ ei_local->msg_enable = ax_msg_enable;
+
+ dev->netdev_ops = &ax_netdev_ops;
+ dev->ethtool_ops = &ax_ethtool_ops;
+
+ ret = ax_mii_init(dev);
+ if (ret)
+ goto out_irq;
+
+ ax_NS8390_init(dev, 0);
+
+ ret = register_netdev(dev);
+ if (ret)
+ goto out_irq;
+
+ netdev_info(dev, "%dbit, irq %d, %lx, MAC: %pM\n",
+ ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr,
+ dev->dev_addr);
+
+ return 0;
+
+ out_irq:
+ /* cleanup irq */
+ free_irq(dev->irq, dev);
+ err_out:
+ return ret;
+}
+
+static int ax_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct ei_device *ei_local = netdev_priv(dev);
+ struct ax_device *ax = to_ax_dev(dev);
+ struct resource *mem;
+
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
+
+ iounmap(ei_local->mem);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+
+ if (ax->map2) {
+ iounmap(ax->map2);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ release_mem_region(mem->start, resource_size(mem));
+ }
+
+ free_netdev(dev);
+
+ return 0;
+}
+
+/*
+ * ax_probe
+ *
+ * This is the entry point when the platform device system uses to
+ * notify us of a new device to attach to. Allocate memory, find the
+ * resources and information passed, and map the necessary registers.
+ */
+static int ax_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct ei_device *ei_local;
+ struct ax_device *ax;
+ struct resource *irq, *mem, *mem2;
+ unsigned long mem_size, mem2_size = 0;
+ int ret = 0;
+
+ dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
+ if (dev == NULL)
+ return -ENOMEM;
+
+ /* ok, let's setup our device */
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ ei_local = netdev_priv(dev);
+ ax = to_ax_dev(dev);
+
+ ax->plat = dev_get_platdata(&pdev->dev);
+ platform_set_drvdata(pdev, dev);
+
+ ei_local->rxcr_base = ax->plat->rcr_val;
+
+ /* find the platform resources */
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq) {
+ dev_err(&pdev->dev, "no IRQ specified\n");
+ ret = -ENXIO;
+ goto exit_mem;
+ }
+
+ dev->irq = irq->start;
+ ax->irqflags = irq->flags & IRQF_TRIGGER_MASK;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "no MEM specified\n");
+ ret = -ENXIO;
+ goto exit_mem;
+ }
+
+ mem_size = resource_size(mem);
+
+ /*
+ * setup the register offsets from either the platform data or
+ * by using the size of the resource provided
+ */
+ if (ax->plat->reg_offsets)
+ ei_local->reg_offset = ax->plat->reg_offsets;
+ else {
+ ei_local->reg_offset = ax->reg_offsets;
+ for (ret = 0; ret < 0x18; ret++)
+ ax->reg_offsets[ret] = (mem_size / 0x18) * ret;
+ }
+
+ if (!request_mem_region(mem->start, mem_size, pdev->name)) {
+ dev_err(&pdev->dev, "cannot reserve registers\n");
+ ret = -ENXIO;
+ goto exit_mem;
+ }
+
+ ei_local->mem = ioremap(mem->start, mem_size);
+ dev->base_addr = (unsigned long)ei_local->mem;
+
+ if (ei_local->mem == NULL) {
+ dev_err(&pdev->dev, "Cannot ioremap area %pR\n", mem);
+
+ ret = -ENXIO;
+ goto exit_req;
+ }
+
+ /* look for reset area */
+ mem2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!mem2) {
+ if (!ax->plat->reg_offsets) {
+ for (ret = 0; ret < 0x20; ret++)
+ ax->reg_offsets[ret] = (mem_size / 0x20) * ret;
+ }
+ } else {
+ mem2_size = resource_size(mem2);
+
+ if (!request_mem_region(mem2->start, mem2_size, pdev->name)) {
+ dev_err(&pdev->dev, "cannot reserve registers\n");
+ ret = -ENXIO;
+ goto exit_mem1;
+ }
+
+ ax->map2 = ioremap(mem2->start, mem2_size);
+ if (!ax->map2) {
+ dev_err(&pdev->dev, "cannot map reset register\n");
+ ret = -ENXIO;
+ goto exit_mem2;
+ }
+
+ ei_local->reg_offset[0x1f] = ax->map2 - ei_local->mem;
+ }
+
+ /* got resources, now initialise and register device */
+ ret = ax_init_dev(dev);
+ if (!ret)
+ return 0;
+
+ if (!ax->map2)
+ goto exit_mem1;
+
+ iounmap(ax->map2);
+
+ exit_mem2:
+ release_mem_region(mem2->start, mem2_size);
+
+ exit_mem1:
+ iounmap(ei_local->mem);
+
+ exit_req:
+ release_mem_region(mem->start, mem_size);
+
+ exit_mem:
+ free_netdev(dev);
+
+ return ret;
+}
+
+/* suspend and resume */
+
+#ifdef CONFIG_PM
+static int ax_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+ struct ax_device *ax = to_ax_dev(ndev);
+
+ ax->resume_open = ax->running;
+
+ netif_device_detach(ndev);
+ ax_close(ndev);
+
+ return 0;
+}
+
+static int ax_resume(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct ax_device *ax = to_ax_dev(ndev);
+
+ ax_initial_setup(ndev, netdev_priv(ndev));
+ ax_NS8390_init(ndev, ax->resume_open);
+ netif_device_attach(ndev);
+
+ if (ax->resume_open)
+ ax_open(ndev);
+
+ return 0;
+}
+
+#else
+#define ax_suspend NULL
+#define ax_resume NULL
+#endif
+
+static struct platform_driver axdrv = {
+ .driver = {
+ .name = "ax88796",
+ .owner = THIS_MODULE,
+ },
+ .probe = ax_probe,
+ .remove = ax_remove,
+ .suspend = ax_suspend,
+ .resume = ax_resume,
+};
+
+module_platform_driver(axdrv);
+
+MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:ax88796");
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c
index 52bf11b73c6..73c57a4a7b9 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/ethernet/8390/axnet_cs.c
@@ -24,29 +24,27 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/crc32.h>
-#include "../8390.h"
+#include <linux/mii.h>
+#include "8390.h"
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
#include <asm/io.h>
-#include <asm/system.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
@@ -73,16 +71,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
MODULE_LICENSE("GPL");
-#ifdef PCMCIA_DEBUG
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"axnet_cs.c 1.28 2002/06/29 06:27:37 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
/*====================================================================*/
@@ -91,7 +79,11 @@ static void axnet_release(struct pcmcia_device *link);
static int axnet_open(struct net_device *dev);
static int axnet_close(struct net_device *dev);
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
+static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void axnet_tx_timeout(struct net_device *dev);
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
static void axnet_reset_8390(struct net_device *dev);
@@ -108,24 +100,24 @@ static void block_output(struct net_device *dev, int count,
static void axnet_detach(struct pcmcia_device *p_dev);
-static void axdev_setup(struct net_device *dev);
static void AX88190_init(struct net_device *dev, int startp);
static int ax_open(struct net_device *dev);
static int ax_close(struct net_device *dev);
static irqreturn_t ax_interrupt(int irq, void *dev_id);
+static u32 axnet_msg_enable;
/*====================================================================*/
typedef struct axnet_dev_t {
struct pcmcia_device *p_dev;
- dev_node_t node;
- caddr_t base;
- struct timer_list watchdog;
- int stale, fast_poll;
- u_short link_status;
- u_char duplex_flag;
- int phy_id;
- int flags;
+ caddr_t base;
+ struct timer_list watchdog;
+ int stale, fast_poll;
+ u_short link_status;
+ u_char duplex_flag;
+ int phy_id;
+ int flags;
+ int active_low;
} axnet_dev_t;
static inline axnet_dev_t *PRIV(struct net_device *dev)
@@ -134,60 +126,54 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
return p;
}
-/*======================================================================
-
- axnet_attach() creates an "instance" of the driver, allocating
- local data structures for one device. The device is registered
- with Card Services.
-
-======================================================================*/
+static const struct net_device_ops axnet_netdev_ops = {
+ .ndo_open = axnet_open,
+ .ndo_stop = axnet_close,
+ .ndo_do_ioctl = axnet_ioctl,
+ .ndo_start_xmit = axnet_start_xmit,
+ .ndo_tx_timeout = axnet_tx_timeout,
+ .ndo_get_stats = get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int axnet_probe(struct pcmcia_device *link)
{
axnet_dev_t *info;
struct net_device *dev;
+ struct ei_device *ei_local;
- DEBUG(0, "axnet_attach()\n");
-
- dev = alloc_netdev(sizeof(struct ei_device) + sizeof(axnet_dev_t),
- "eth%d", axdev_setup);
+ dev_dbg(&link->dev, "axnet_attach()\n");
+ dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
if (!dev)
return -ENOMEM;
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = axnet_msg_enable;
+ spin_lock_init(&ei_local->page_lock);
+
info = PRIV(dev);
info->p_dev = link;
link->priv = dev;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.IntType = INT_MEMORY_AND_IO;
+ link->config_flags |= CONF_ENABLE_IRQ;
+
+ dev->netdev_ops = &axnet_netdev_ops;
- dev->open = &axnet_open;
- dev->stop = &axnet_close;
- dev->do_ioctl = &axnet_ioctl;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ dev->watchdog_timeo = TX_TIMEOUT;
return axnet_config(link);
} /* axnet_attach */
-/*======================================================================
-
- This deletes a driver "instance". The device is de-registered
- with Card Services. If it has been released, all local data
- structures are freed. Otherwise, the structures will be freed
- when the device is released.
-
-======================================================================*/
-
static void axnet_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "axnet_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
- if (link->dev_node)
- unregister_netdev(dev);
+ unregister_netdev(dev);
axnet_release(link);
@@ -206,7 +192,7 @@ static int get_prom(struct pcmcia_device *link)
unsigned int ioaddr = dev->base_addr;
int i, j;
- /* This is based on drivers/net/ne.c */
+ /* This is based on drivers/net/ethernet/8390/ne.c */
struct {
u_char value, offset;
} program_seq[] = {
@@ -226,7 +212,7 @@ static int get_prom(struct pcmcia_device *link)
};
/* Not much of a test, but the alternatives are messy */
- if (link->conf.ConfigBase != 0x03c0)
+ if (link->config_base != 0x03c0)
return 0;
axnet_reset_8390(dev);
@@ -243,118 +229,79 @@ static int get_prom(struct pcmcia_device *link)
return 1;
} /* get_prom */
-/*======================================================================
-
- axnet_config() is scheduled to run after a CARD_INSERTION event
- is received, to configure the PCMCIA socket, and to make the
- ethernet device available to the system.
-
-======================================================================*/
-
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int try_io_port(struct pcmcia_device *link)
{
int j, ret;
- if (link->io.NumPorts1 == 32) {
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (link->io.NumPorts2 > 0) {
- /* for master/slave multifunction cards */
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->irq.Attributes =
- IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
- }
+ link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+ if (link->resource[0]->end == 32) {
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+ /* for master/slave multifunction cards */
+ if (link->resource[1]->end > 0)
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
} else {
/* This should be two 16-port windows */
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
}
- if (link->io.BasePort1 == 0) {
- link->io.IOAddrLines = 16;
+ if (link->resource[0]->start == 0) {
for (j = 0; j < 0x400; j += 0x20) {
- link->io.BasePort1 = j ^ 0x300;
- link->io.BasePort2 = (j ^ 0x300) + 0x10;
- ret = pcmcia_request_io(link, &link->io);
- if (ret == CS_SUCCESS) return ret;
+ link->resource[0]->start = j ^ 0x300;
+ link->resource[1]->start = (j ^ 0x300) + 0x10;
+ link->io_lines = 16;
+ ret = pcmcia_request_io(link);
+ if (ret == 0)
+ return ret;
}
return ret;
} else {
- return pcmcia_request_io(link, &link->io);
+ return pcmcia_request_io(link);
}
}
+static int axnet_configcheck(struct pcmcia_device *p_dev, void *priv_data)
+{
+ if (p_dev->config_index == 0)
+ return -EINVAL;
+
+ p_dev->config_index = 0x05;
+ if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32)
+ return -ENODEV;
+
+ return try_io_port(p_dev);
+}
+
static int axnet_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
axnet_dev_t *info = PRIV(dev);
- tuple_t tuple;
- cisparse_t parse;
- int i, j, last_ret, last_fn;
- u_short buf[64];
- DECLARE_MAC_BUF(mac);
+ int i, j, j2, ret;
- DEBUG(0, "axnet_config(0x%p)\n", link);
-
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
+ dev_dbg(&link->dev, "axnet_config(0x%p)\n", link);
/* don't trust the CIS on this; Linksys got it wrong */
- link->conf.Present = 0x63;
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- while (last_ret == CS_SUCCESS) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- cistpl_io_t *io = &(parse.cftable_entry.io);
-
- if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
- pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
- cfg->index == 0 || cfg->io.nwin == 0)
- goto next_entry;
-
- link->conf.ConfigIndex = 0x05;
- /* For multifunction cards, by convention, we configure the
- network function with window 0, and serial with window 1 */
- if (io->nwin > 1) {
- i = (io->win[1].len > io->win[0].len);
- link->io.BasePort2 = io->win[1-i].base;
- link->io.NumPorts2 = io->win[1-i].len;
- } else {
- i = link->io.NumPorts2 = 0;
- }
- link->io.BasePort1 = io->win[i].base;
- link->io.NumPorts1 = io->win[i].len;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
- last_ret = try_io_port(link);
- if (last_ret == CS_SUCCESS) break;
- }
- next_entry:
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- }
- if (last_ret != CS_SUCCESS) {
- cs_error(link, RequestIO, last_ret);
+ link->config_regs = 0x63;
+ link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+ ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
+ if (ret != 0)
goto failed;
- }
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-
- if (link->io.NumPorts2 == 8) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
+ if (!link->irq)
+ goto failed;
+
+ if (resource_size(link->resource[1]) == 8)
+ link->config_flags |= CONF_ENABLE_SPKR;
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
- dev->irq = link->irq.AssignedIRQ;
- dev->base_addr = link->io.BasePort1;
+ ret = pcmcia_enable_device(link);
+ if (ret)
+ goto failed;
+
+ dev->irq = link->irq;
+ dev->base_addr = link->resource[0]->start;
if (!get_prom(link)) {
- printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
- printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n");
+ pr_notice("this is not an AX88190 card!\n");
+ pr_notice("use pcnet_cs instead.\n");
goto failed;
}
@@ -363,10 +310,10 @@ static int axnet_config(struct pcmcia_device *link)
ei_status.tx_start_page = AXNET_START_PG;
ei_status.rx_start_page = AXNET_START_PG + TX_PAGES;
ei_status.stop_page = AXNET_STOP_PG;
- ei_status.reset_8390 = &axnet_reset_8390;
- ei_status.get_8390_hdr = &get_8390_hdr;
- ei_status.block_input = &block_input;
- ei_status.block_output = &block_output;
+ ei_status.reset_8390 = axnet_reset_8390;
+ ei_status.get_8390_hdr = get_8390_hdr;
+ ei_status.block_input = block_input;
+ ei_status.block_output = block_output;
if (inb(dev->base_addr + AXNET_TEST) != 0)
info->flags |= IS_AX88790;
@@ -376,61 +323,54 @@ static int axnet_config(struct pcmcia_device *link)
if (info->flags & IS_AX88790)
outb(0x10, dev->base_addr + AXNET_GPIO); /* select Internal PHY */
+ info->active_low = 0;
+
for (i = 0; i < 32; i++) {
j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
+ j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
+ if (j == j2) continue;
if ((j != 0) && (j != 0xffff)) break;
}
- /* Maybe PHY is in power down mode. (PPD_SET = 1)
- Bit 2 of CCSR is active low. */
if (i == 32) {
- conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 };
- pcmcia_access_configuration_register(link, &reg);
+ /* Maybe PHY is in power down mode. (PPD_SET = 1)
+ Bit 2 of CCSR is active low. */
+ pcmcia_write_config_byte(link, CISREG_CCSR, 0x04);
for (i = 0; i < 32; i++) {
j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
- if ((j != 0) && (j != 0xffff)) break;
+ j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
+ if (j == j2) continue;
+ if ((j != 0) && (j != 0xffff)) {
+ info->active_low = 1;
+ break;
+ }
}
}
info->phy_id = (i < 32) ? i : -1;
- link->dev_node = &info->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
- link->dev_node = NULL;
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- strcpy(info->node.dev_name, dev->name);
-
- printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, "
- "hw_addr %s\n",
- dev->name, ((info->flags & IS_AX88790) ? 7 : 1),
- dev->base_addr, dev->irq,
- print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "Asix AX88%d90: io %#3lx, irq %d, hw_addr %pM\n",
+ ((info->flags & IS_AX88790) ? 7 : 1),
+ dev->base_addr, dev->irq, dev->dev_addr);
if (info->phy_id != -1) {
- DEBUG(0, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
+ netdev_dbg(dev, " MII transceiver at index %d, status %x\n",
+ info->phy_id, j);
} else {
- printk(KERN_NOTICE " No MII transceivers found!\n");
+ netdev_notice(dev, " No MII transceivers found!\n");
}
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
axnet_release(link);
return -ENODEV;
} /* axnet_config */
-/*======================================================================
-
- After a card is removed, axnet_release() will unregister the net
- device, and release the PCMCIA configuration. If the device is
- still open, this will be postponed until it is closed.
-
-======================================================================*/
-
static void axnet_release(struct pcmcia_device *link)
{
pcmcia_disable_device(link);
@@ -449,8 +389,12 @@ static int axnet_suspend(struct pcmcia_device *link)
static int axnet_resume(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
+ axnet_dev_t *info = PRIV(dev);
if (link->open) {
+ if (info->active_low == 1)
+ pcmcia_write_config_byte(link, CISREG_CCSR, 0x04);
+
axnet_reset_8390(dev);
AX88190_init(dev, 1);
netif_device_attach(dev);
@@ -527,7 +471,7 @@ static int axnet_open(struct net_device *dev)
struct pcmcia_device *link = info->p_dev;
unsigned int nic_base = dev->base_addr;
- DEBUG(2, "axnet_open('%s')\n", dev->name);
+ dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name);
if (!pcmcia_dev_present(link))
return -ENODEV;
@@ -541,7 +485,7 @@ static int axnet_open(struct net_device *dev)
info->link_status = 0x00;
init_timer(&info->watchdog);
- info->watchdog.function = &ei_watchdog;
+ info->watchdog.function = ei_watchdog;
info->watchdog.data = (u_long)dev;
info->watchdog.expires = jiffies + HZ;
add_timer(&info->watchdog);
@@ -556,7 +500,7 @@ static int axnet_close(struct net_device *dev)
axnet_dev_t *info = PRIV(dev);
struct pcmcia_device *link = info->p_dev;
- DEBUG(2, "axnet_close('%s')\n", dev->name);
+ dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name);
ax_close(dev);
free_irq(dev->irq, dev);
@@ -594,8 +538,7 @@ static void axnet_reset_8390(struct net_device *dev)
outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
if (i == 100)
- printk(KERN_ERR "%s: axnet_reset_8390() did not complete.\n",
- dev->name);
+ netdev_err(dev, "axnet_reset_8390() did not complete\n");
} /* axnet_reset_8390 */
@@ -622,7 +565,7 @@ static void ei_watchdog(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
if (!info->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
ei_irq_wrapper(dev->irq, dev);
info->fast_poll = HZ;
}
@@ -637,7 +580,7 @@ static void ei_watchdog(u_long arg)
goto reschedule;
link = mdio_read(mii_addr, info->phy_id, 1);
if (!link || (link == 0xffff)) {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
info->phy_id = -1;
goto reschedule;
}
@@ -645,18 +588,14 @@ static void ei_watchdog(u_long arg)
link &= 0x0004;
if (link != info->link_status) {
u_short p = mdio_read(mii_addr, info->phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
if (link) {
info->duplex_flag = (p & 0x0140) ? 0x80 : 0x00;
if (p)
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((p & 0x0180) ? "100" : "10"),
- ((p & 0x0140) ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: %dbaseT-%cD selected\n",
+ (p & 0x0180) ? 100 : 10, (p & 0x0140) ? 'F' : 'H');
else
- printk(KERN_INFO "%s: link partner did not autonegotiate\n",
- dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
AX88190_init(dev, 1);
}
info->link_status = link;
@@ -667,33 +606,21 @@ reschedule:
add_timer(&info->watchdog);
}
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "axnet_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
/*====================================================================*/
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
axnet_dev_t *info = PRIV(dev);
- u16 *data = (u16 *)&rq->ifr_ifru;
+ struct mii_ioctl_data *data = if_mii(rq);
unsigned int mii_addr = dev->base_addr + AXNET_MII_EEP;
switch (cmd) {
case SIOCGMIIPHY:
- data[0] = info->phy_id;
+ data->phy_id = info->phy_id;
case SIOCGMIIREG: /* Read MII PHY register. */
- data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f);
+ data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- mdio_write(mii_addr, data[0], data[1] & 0x1f, data[2]);
+ mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in);
return 0;
}
return -EOPNOTSUPP;
@@ -724,13 +651,12 @@ static void block_input(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset)
{
unsigned int nic_base = dev->base_addr;
+ struct ei_device *ei_local = netdev_priv(dev);
int xfer_count = count;
char *buf = skb->data;
-#ifdef PCMCIA_DEBUG
- if ((ei_debug > 4) && (count != 4))
- printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+ if ((netif_msg_rx_status(ei_local)) && (count != 4))
+ netdev_dbg(dev, "[bi=%d]\n", count+4);
outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD);
@@ -748,10 +674,7 @@ static void block_output(struct net_device *dev, int count,
{
unsigned int nic_base = dev->base_addr;
-#ifdef PCMCIA_DEBUG
- if (ei_debug > 4)
- printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
-#endif
+ pr_debug("%s: [bo=%d]\n", dev->name, count);
/* Round the count up for word writes. Do we need to do this?
What effect will an odd byte count have on the 8390?
@@ -765,9 +688,10 @@ static void block_output(struct net_device *dev, int count,
outsw(nic_base + AXNET_DATAPORT, buf, count>>1);
}
-static struct pcmcia_device_id axnet_ids[] = {
+static const struct pcmcia_device_id axnet_ids[] = {
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081),
PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301),
+ PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309),
@@ -783,10 +707,12 @@ static struct pcmcia_device_id axnet_ids[] = {
PCMCIA_DEVICE_PROD_ID12("CNet", "CNF301", 0xbc477dde, 0x78c5f40b),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e),
+ PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXM", 0x5261440f, 0x3abbd061),
PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2),
PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8),
PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609),
+ PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058),
@@ -797,28 +723,14 @@ MODULE_DEVICE_TABLE(pcmcia, axnet_ids);
static struct pcmcia_driver axnet_cs_driver = {
.owner = THIS_MODULE,
- .drv = {
- .name = "axnet_cs",
- },
+ .name = "axnet_cs",
.probe = axnet_probe,
.remove = axnet_detach,
.id_table = axnet_ids,
.suspend = axnet_suspend,
.resume = axnet_resume,
};
-
-static int __init init_axnet_cs(void)
-{
- return pcmcia_register_driver(&axnet_cs_driver);
-}
-
-static void __exit exit_axnet_cs(void)
-{
- pcmcia_unregister_driver(&axnet_cs_driver);
-}
-
-module_init(init_axnet_cs);
-module_exit(exit_axnet_cs);
+module_pcmcia_driver(axnet_cs_driver);
/*====================================================================*/
@@ -857,7 +769,7 @@ module_exit(exit_axnet_cs);
Alexey Kuznetsov : use the 8390's six bit hash multicast filter.
Paul Gortmaker : tweak ANK's above multicast changes a bit.
Paul Gortmaker : update packet statistics for v2.1.x
- Alan Cox : support arbitary stupid port mappings on the
+ Alan Cox : support arbitrary stupid port mappings on the
68K Macintosh. Support >16bit I/O spaces
Paul Gortmaker : add kmod support for auto-loading of the 8390
module by all drivers that require it.
@@ -869,17 +781,12 @@ module_exit(exit_axnet_cs);
*/
-static const char *version_8390 =
- "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n";
-
#include <linux/bitops.h>
#include <asm/irq.h>
#include <linux/fcntl.h>
#include <linux/in.h>
#include <linux/interrupt.h>
-#include <linux/etherdevice.h>
-
#define BUG_83C690
/* These are the operational function interfaces to board-specific
@@ -905,28 +812,21 @@ static const char *version_8390 =
#define ei_block_input (ei_local->block_input)
#define ei_get_8390_hdr (ei_local->get_8390_hdr)
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef ei_debug
-int ei_debug = 1;
-#endif
-
/* Index to functions. */
static void ei_tx_intr(struct net_device *dev);
static void ei_tx_err(struct net_device *dev);
-static void ei_tx_timeout(struct net_device *dev);
static void ei_receive(struct net_device *dev);
static void ei_rx_overrun(struct net_device *dev);
/* Routines generic to NS8390-based boards. */
static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page);
-static void set_multicast_list(struct net_device *dev);
static void do_set_multicast_list(struct net_device *dev);
/*
* SMP and the 8390 setup.
*
- * The 8390 isnt exactly designed to be multithreaded on RX/TX. There is
+ * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is
* a page register that controls bank and packet buffer access. We guard
* this with ei_local->page_lock. Nobody should assume or set the page other
* than zero when the lock is not held. Lock holders must restore page 0
@@ -960,16 +860,7 @@ static void do_set_multicast_list(struct net_device *dev);
static int ax_open(struct net_device *dev)
{
unsigned long flags;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
-
-#ifdef HAVE_TX_TIMEOUT
- /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
- wrapper that does e.g. media check & then calls ei_tx_timeout. */
- if (dev->tx_timeout == NULL)
- dev->tx_timeout = ei_tx_timeout;
- if (dev->watchdog_timeo <= 0)
- dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+ struct ei_device *ei_local = netdev_priv(dev);
/*
* Grab the page lock so we own the register set, then call
@@ -1010,18 +901,18 @@ static int ax_close(struct net_device *dev)
}
/**
- * ei_tx_timeout - handle transmit time out condition
+ * axnet_tx_timeout - handle transmit time out condition
* @dev: network device which has apparently fallen asleep
*
* Called by kernel when device never acknowledges a transmit has
* completed (or failed) - i.e. never posted a Tx related interrupt.
*/
-static void ei_tx_timeout(struct net_device *dev)
+static void axnet_tx_timeout(struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
- int txsr, isr, tickssofar = jiffies - dev->trans_start;
+ struct ei_device *ei_local = netdev_priv(dev);
+ int txsr, isr, tickssofar = jiffies - dev_trans_start(dev);
unsigned long flags;
dev->stats.tx_errors++;
@@ -1031,9 +922,10 @@ static void ei_tx_timeout(struct net_device *dev)
isr = inb(e8390_base+EN0_ISR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
- printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
- dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
- (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
+ netdev_dbg(dev, "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
+ (txsr & ENTSR_ABT) ? "excess collisions." :
+ (isr) ? "lost interrupt?" : "cable problem?",
+ txsr, isr, tickssofar);
if (!isr && !dev->stats.tx_packets)
{
@@ -1054,17 +946,18 @@ static void ei_tx_timeout(struct net_device *dev)
}
/**
- * ei_start_xmit - begin packet transmission
+ * axnet_start_xmit - begin packet transmission
* @skb: packet to be sent
* @dev: network device to which packet is sent
*
* Sends a packet to an 8390 network device.
*/
-static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int length, send_length, output_page;
unsigned long flags;
u8 packet[ETH_ZLEN];
@@ -1080,14 +973,11 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&ei_local->page_lock, flags);
outb_p(0x00, e8390_base + EN0_IMR);
- spin_unlock_irqrestore(&ei_local->page_lock, flags);
/*
* Slow phase with lock held.
*/
- spin_lock_irqsave(&ei_local->page_lock, flags);
-
ei_local->irqlock = 1;
send_length = max(length, ETH_ZLEN);
@@ -1104,29 +994,36 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
output_page = ei_local->tx_start_page;
ei_local->tx1 = send_length;
- if (ei_debug && ei_local->tx2 > 0)
- printk(KERN_DEBUG "%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing);
+ if ((netif_msg_tx_queued(ei_local)) &&
+ ei_local->tx2 > 0)
+ netdev_dbg(dev,
+ "idle transmitter tx2=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx2, ei_local->lasttx,
+ ei_local->txing);
}
else if (ei_local->tx2 == 0)
{
output_page = ei_local->tx_start_page + TX_PAGES/2;
ei_local->tx2 = send_length;
- if (ei_debug && ei_local->tx1 > 0)
- printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing);
+ if ((netif_msg_tx_queued(ei_local)) &&
+ ei_local->tx1 > 0)
+ netdev_dbg(dev,
+ "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx1, ei_local->lasttx,
+ ei_local->txing);
}
else
{ /* We should never get here. */
- if (ei_debug)
- printk(KERN_DEBUG "%s: No Tx buffers free! tx1=%d tx2=%d last=%d\n",
- dev->name, ei_local->tx1, ei_local->tx2, ei_local->lasttx);
+ netif_dbg(ei_local, tx_err, dev,
+ "No Tx buffers free! tx1=%d tx2=%d last=%d\n",
+ ei_local->tx1, ei_local->tx2,
+ ei_local->lasttx);
ei_local->irqlock = 0;
netif_stop_queue(dev);
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
dev->stats.tx_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
/*
@@ -1175,14 +1072,13 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb (skb);
dev->stats.tx_bytes += send_length;
- return 0;
+ return NETDEV_TX_OK;
}
/**
* ax_interrupt - handle the interrupts from an 8390
* @irq: interrupt number
* @dev_id: a pointer to the net_device
- * @regs: unused
*
* Handle the ether interface interrupts. We pull packets from
* the 8390 via the card specific functions and fire them at the networking
@@ -1198,6 +1094,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
int interrupts, nr_serviced = 0, i;
struct ei_device *ei_local;
int handled = 0;
+ unsigned long flags;
e8390_base = dev->base_addr;
ei_local = netdev_priv(dev);
@@ -1206,36 +1103,38 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
* Protect the irq test too.
*/
- spin_lock(&ei_local->page_lock);
+ spin_lock_irqsave(&ei_local->page_lock, flags);
- if (ei_local->irqlock)
- {
+ if (ei_local->irqlock) {
#if 1 /* This might just be an interrupt for a PCI device sharing this line */
+ const char *msg;
/* The "irqlock" check is only for testing. */
- printk(ei_local->irqlock
- ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n"
- : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n",
- dev->name, inb_p(e8390_base + EN0_ISR),
- inb_p(e8390_base + EN0_IMR));
+ if (ei_local->irqlock)
+ msg = "Interrupted while interrupts are masked!";
+ else
+ msg = "Reentering the interrupt handler!";
+ netdev_info(dev, "%s, isr=%#2x imr=%#2x\n",
+ msg,
+ inb_p(e8390_base + EN0_ISR),
+ inb_p(e8390_base + EN0_IMR));
#endif
- spin_unlock(&ei_local->page_lock);
+ spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_NONE;
}
-
- if (ei_debug > 3)
- printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name,
- inb_p(e8390_base + EN0_ISR));
+
+ netif_dbg(ei_local, intr, dev, "interrupt(isr=%#2.2x)\n",
+ inb_p(e8390_base + EN0_ISR));
outb_p(0x00, e8390_base + EN0_ISR);
ei_local->irqlock = 1;
/* !!Assumption!! -- we stay in page 0. Don't break this. */
- while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0
- && ++nr_serviced < MAX_SERVICE)
+ while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0 &&
+ ++nr_serviced < MAX_SERVICE)
{
if (!netif_running(dev) || (interrupts == 0xff)) {
- if (ei_debug > 1)
- printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name);
+ netif_warn(ei_local, intr, dev,
+ "interrupt from stopped card\n");
outb_p(interrupts, e8390_base + EN0_ISR);
interrupts = 0;
break;
@@ -1271,18 +1170,20 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
}
}
- if (interrupts && ei_debug > 3)
+ if (interrupts && (netif_msg_intr(ei_local)))
{
handled = 1;
if (nr_serviced >= MAX_SERVICE)
{
/* 0xFF is valid for a card removal */
- if(interrupts!=0xFF)
- printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n",
- dev->name, interrupts);
+ if (interrupts != 0xFF)
+ netdev_warn(dev,
+ "Too much work at interrupt, status %#2.2x\n",
+ interrupts);
outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
} else {
- printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts);
+ netdev_warn(dev, "unknown interrupt %#2x\n",
+ interrupts);
outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */
}
}
@@ -1291,7 +1192,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
ei_local->irqlock = 0;
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
- spin_unlock(&ei_local->page_lock);
+ spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_RETVAL(handled);
}
@@ -1316,18 +1217,18 @@ static void ei_tx_err(struct net_device *dev)
unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
#ifdef VERBOSE_ERROR_DUMP
- printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr);
+ netdev_dbg(dev, "transmitter error (%#2x):", txsr);
if (txsr & ENTSR_ABT)
- printk("excess-collisions ");
+ pr_cont(" excess-collisions");
if (txsr & ENTSR_ND)
- printk("non-deferral ");
+ pr_cont(" non-deferral");
if (txsr & ENTSR_CRS)
- printk("lost-carrier ");
+ pr_cont(" lost-carrier");
if (txsr & ENTSR_FU)
- printk("FIFO-underrun ");
+ pr_cont(" FIFO-underrun");
if (txsr & ENTSR_CDH)
- printk("lost-heartbeat ");
- printk("\n");
+ pr_cont(" lost-heartbeat");
+ pr_cont("\n");
#endif
if (tx_was_aborted)
@@ -1352,7 +1253,7 @@ static void ei_tx_err(struct net_device *dev)
static void ei_tx_intr(struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int status = inb(e8390_base + EN0_TSR);
/*
@@ -1364,8 +1265,9 @@ static void ei_tx_intr(struct net_device *dev)
if (ei_local->tx1 < 0)
{
if (ei_local->lasttx != 1 && ei_local->lasttx != -1)
- printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx1);
+ netdev_err(dev, "%s: bogus last_tx_buffer %d, tx1=%d\n",
+ ei_local->name, ei_local->lasttx,
+ ei_local->tx1);
ei_local->tx1 = 0;
if (ei_local->tx2 > 0)
{
@@ -1380,8 +1282,9 @@ static void ei_tx_intr(struct net_device *dev)
else if (ei_local->tx2 < 0)
{
if (ei_local->lasttx != 2 && ei_local->lasttx != -2)
- printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx2);
+ netdev_err(dev, "%s: bogus last_tx_buffer %d, tx2=%d\n",
+ ei_local->name, ei_local->lasttx,
+ ei_local->tx2);
ei_local->tx2 = 0;
if (ei_local->tx1 > 0)
{
@@ -1394,8 +1297,9 @@ static void ei_tx_intr(struct net_device *dev)
else
ei_local->lasttx = 10, ei_local->txing = 0;
}
-// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",
-// dev->name, ei_local->lasttx);
+// else
+// netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n",
+// ei_local->lasttx);
/* Minimize Tx latency: update the statistics after we restart TXing. */
if (status & ENTSR_COL)
@@ -1433,7 +1337,7 @@ static void ei_tx_intr(struct net_device *dev)
static void ei_receive(struct net_device *dev)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned char rxing_page, this_frame, next_frame;
unsigned short current_offset;
int rx_pkt_count = 0;
@@ -1457,9 +1361,11 @@ static void ei_receive(struct net_device *dev)
Keep quiet if it looks like a card removal. One problem here
is that some clones crash in roughly the same way.
*/
- if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
- printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n",
- dev->name, this_frame, ei_local->current_page);
+ if ((netif_msg_rx_err(ei_local)) &&
+ this_frame != ei_local->current_page &&
+ (this_frame != 0x0 || rxing_page != 0xFF))
+ netdev_err(dev, "mismatched read page pointers %2x vs %2x\n",
+ this_frame, ei_local->current_page);
if (this_frame == rxing_page) /* Read all the frames? */
break; /* Done for now */
@@ -1474,10 +1380,10 @@ static void ei_receive(struct net_device *dev)
if (pkt_len < 60 || pkt_len > 1518)
{
- if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
- dev->name, rx_frame.count, rx_frame.status,
- rx_frame.next);
+ netif_err(ei_local, rx_err, dev,
+ "bogus packet size: %d, status=%#2x nxpg=%#2x\n",
+ rx_frame.count, rx_frame.status,
+ rx_frame.next);
dev->stats.rx_errors++;
dev->stats.rx_length_errors++;
}
@@ -1485,12 +1391,12 @@ static void ei_receive(struct net_device *dev)
{
struct sk_buff *skb;
- skb = dev_alloc_skb(pkt_len+2);
+ skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL)
{
- if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
+ netif_err(ei_local, rx_err, dev,
+ "Couldn't allocate a sk_buff of size %d\n",
+ pkt_len);
dev->stats.rx_dropped++;
break;
}
@@ -1501,7 +1407,6 @@ static void ei_receive(struct net_device *dev)
ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
if (pkt_stat & ENRSR_PHY)
@@ -1510,10 +1415,10 @@ static void ei_receive(struct net_device *dev)
}
else
{
- if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
- dev->name, rx_frame.status, rx_frame.next,
- rx_frame.count);
+ netif_err(ei_local, rx_err, dev,
+ "bogus packet: status=%#2x nxpg=%#2x size=%d\n",
+ rx_frame.status, rx_frame.next,
+ rx_frame.count);
dev->stats.rx_errors++;
/* NB: The NIC counts CRC, frame and missed errors. */
if (pkt_stat & ENRSR_FO)
@@ -1523,15 +1428,13 @@ static void ei_receive(struct net_device *dev)
/* This _should_ never happen: it's here for avoiding bad clones. */
if (next_frame >= ei_local->stop_page) {
- printk("%s: next frame inconsistency, %#2x\n", dev->name,
- next_frame);
+ netdev_info(dev, "next frame inconsistency, %#2x\n",
+ next_frame);
next_frame = ei_local->rx_start_page;
}
ei_local->current_page = next_frame;
outb_p(next_frame-1, e8390_base+EN0_BOUNDARY);
}
-
- return;
}
/**
@@ -1552,6 +1455,7 @@ static void ei_rx_overrun(struct net_device *dev)
axnet_dev_t *info = PRIV(dev);
long e8390_base = dev->base_addr;
unsigned char was_txing, must_resend = 0;
+ struct ei_device *ei_local = netdev_priv(dev);
/*
* Record whether a Tx was in progress and then issue the
@@ -1559,19 +1463,16 @@ static void ei_rx_overrun(struct net_device *dev)
*/
was_txing = inb_p(e8390_base+E8390_CMD) & E8390_TRANS;
outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
-
- if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name);
+
+ netif_dbg(ei_local, rx_err, dev, "Receiver overrun\n");
dev->stats.rx_over_errors++;
/*
* Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total.
- * Early datasheets said to poll the reset bit, but now they say that
- * it "is not a reliable indicator and subsequently should be ignored."
- * We wait at least 10ms.
+ * We wait at least 2ms.
*/
- mdelay(10);
+ mdelay(2);
/*
* Reset RBCR[01] back to zero as per magic incantation.
@@ -1618,7 +1519,7 @@ static void ei_rx_overrun(struct net_device *dev)
static struct net_device_stats *get_stats(struct net_device *dev)
{
long ioaddr = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
/* If the card is stopped, just return the present stats. */
@@ -1642,12 +1543,11 @@ static struct net_device_stats *get_stats(struct net_device *dev)
static inline void make_mc_bits(u8 *bits, struct net_device *dev)
{
- struct dev_mc_list *dmi;
+ struct netdev_hw_addr *ha;
u32 crc;
- for (dmi=dev->mc_list; dmi; dmi=dmi->next) {
-
- crc = ether_crc(ETH_ALEN, dmi->dmi_addr);
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc(ETH_ALEN, ha->addr);
/*
* The 8390 uses the 6 most significant bits of the
* CRC to index the multicast table.
@@ -1668,11 +1568,11 @@ static void do_set_multicast_list(struct net_device *dev)
{
long e8390_base = dev->base_addr;
int i;
- struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) {
memset(ei_local->mcfilter, 0, 8);
- if (dev->mc_list)
+ if (!netdev_mc_empty(dev))
make_mc_bits(ei_local->mcfilter, dev);
} else {
/* set to accept-all */
@@ -1688,7 +1588,7 @@ static void do_set_multicast_list(struct net_device *dev)
if(dev->flags&IFF_PROMISC)
outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR);
- else if(dev->flags&IFF_ALLMULTI || dev->mc_list)
+ else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev))
outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR);
else
outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR);
@@ -1711,30 +1611,6 @@ static void set_multicast_list(struct net_device *dev)
spin_unlock_irqrestore(&dev_lock(dev), flags);
}
-/**
- * axdev_setup - init rest of 8390 device struct
- * @dev: network device structure to init
- *
- * Initialize the rest of the 8390 device structure. Do NOT __init
- * this, as it is used by 8390 based modular drivers too.
- */
-
-static void axdev_setup(struct net_device *dev)
-{
- struct ei_device *ei_local;
- if (ei_debug > 1)
- printk(version_8390);
-
- ei_local = (struct ei_device *)netdev_priv(dev);
- spin_lock_init(&ei_local->page_lock);
-
- dev->hard_start_xmit = &ei_start_xmit;
- dev->get_stats = get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- ether_setup(dev);
-}
-
/* This page of functions should be 8390 generic */
/* Follow National Semi's recommendations for initializing the "NIC". */
@@ -1750,7 +1626,7 @@ static void AX88190_init(struct net_device *dev, int startp)
{
axnet_dev_t *info = PRIV(dev);
long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int i;
int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
@@ -1783,7 +1659,7 @@ static void AX88190_init(struct net_device *dev, int startp)
{
outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i));
if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i])
- printk(KERN_ERR "Hw. address read/write mismap %d\n",i);
+ netdev_err(dev, "Hw. address read/write mismap %d\n", i);
}
outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
@@ -1793,6 +1669,9 @@ static void AX88190_init(struct net_device *dev, int startp)
ei_local->tx1 = ei_local->tx2 = 0;
ei_local->txing = 0;
+ if (info->flags & IS_AX88790) /* select Internal PHY */
+ outb(0x10, e8390_base + AXNET_GPIO);
+
if (startp)
{
outb_p(0xff, e8390_base + EN0_ISR);
@@ -1813,12 +1692,11 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page)
{
long e8390_base = dev->base_addr;
- struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev);
if (inb_p(e8390_base) & E8390_TRANS)
{
- printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n",
- dev->name);
+ netdev_warn(dev, "trigger_send() called with the transmitter busy\n");
return;
}
outb_p(length & 0xff, e8390_base + EN0_TCNTLO);
diff --git a/drivers/net/arm/etherh.c b/drivers/net/ethernet/8390/etherh.c
index 5c5f1e470d3..b36ee9e0d22 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/ethernet/8390/etherh.c
@@ -33,7 +33,6 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
@@ -46,9 +45,9 @@
#include <linux/bitops.h>
#include <linux/jiffies.h>
-#include <asm/system.h>
#include <asm/ecard.h>
#include <asm/io.h>
+#include <asm/system_info.h>
#define EI_SHIFT(x) (ei_local->reg_offset[x])
@@ -57,18 +56,15 @@
#define ei_inb_p(_p) readb((void __iomem *)_p)
#define ei_outb_p(_v,_p) writeb(_v,(void __iomem *)_p)
-#define NET_DEBUG 0
-#define DEBUG_INIT 2
-
#define DRV_NAME "etherh"
#define DRV_VERSION "1.11"
-static char version[] __initdata =
+static char version[] =
"EtherH/EtherM Driver (c) 2002-2004 Russell King " DRV_VERSION "\n";
-#include "../lib8390.c"
+#include "lib8390.c"
-static unsigned int net_debug = NET_DEBUG;
+static u32 etherh_msg_enable;
struct etherh_priv {
void __iomem *ioc_fast;
@@ -318,9 +314,9 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf
void __iomem *dma_base, *addr;
if (ei_local->dmaing) {
- printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: "
- " DMAstat %d irqlock %d\n", dev->name,
- ei_local->dmaing, ei_local->irqlock);
+ netdev_err(dev, "DMAing conflict in etherh_block_input: "
+ " DMAstat %d irqlock %d\n",
+ ei_local->dmaing, ei_local->irqlock);
return;
}
@@ -362,8 +358,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf
while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0)
if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */
- printk(KERN_ERR "%s: timeout waiting for TX RDC\n",
- dev->name);
+ netdev_warn(dev, "timeout waiting for TX RDC\n");
etherh_reset (dev);
__NS8390_init (dev, 1);
break;
@@ -384,9 +379,9 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int
void __iomem *dma_base, *addr;
if (ei_local->dmaing) {
- printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: "
- " DMAstat %d irqlock %d\n", dev->name,
- ei_local->dmaing, ei_local->irqlock);
+ netdev_err(dev, "DMAing conflict in etherh_block_input: "
+ " DMAstat %d irqlock %d\n",
+ ei_local->dmaing, ei_local->irqlock);
return;
}
@@ -424,9 +419,9 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p
void __iomem *dma_base, *addr;
if (ei_local->dmaing) {
- printk(KERN_ERR "%s: DMAing conflict in etherh_get_header: "
- " DMAstat %d irqlock %d\n", dev->name,
- ei_local->dmaing, ei_local->irqlock);
+ netdev_err(dev, "DMAing conflict in etherh_get_header: "
+ " DMAstat %d irqlock %d\n",
+ ei_local->dmaing, ei_local->irqlock);
return;
}
@@ -464,12 +459,6 @@ etherh_open(struct net_device *dev)
{
struct ei_device *ei_local = netdev_priv(dev);
- if (!is_valid_ether_addr(dev->dev_addr)) {
- printk(KERN_WARNING "%s: invalid ethernet MAC address\n",
- dev->name);
- return -EINVAL;
- }
-
if (request_irq(dev->irq, __ei_interrupt, 0, dev->name, dev))
return -EAGAIN;
@@ -520,15 +509,15 @@ static void __init etherh_banner(void)
{
static int version_printed;
- if (net_debug && version_printed++ == 0)
- printk(KERN_INFO "%s", version);
+ if ((etherh_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
+ pr_info("%s", version);
}
/*
* Read the ethernet address string from the on board rom.
* This is an ascii string...
*/
-static int __init etherh_addr(char *addr, struct expansion_card *ec)
+static int etherh_addr(char *addr, struct expansion_card *ec)
{
struct in_chunk_dir cd;
char *s;
@@ -592,10 +581,11 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
cmd->supported = etherh_priv(dev)->supported;
- cmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(cmd, SPEED_10);
cmd->duplex = DUPLEX_HALF;
cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
- cmd->autoneg = dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+ cmd->autoneg = (dev->flags & IFF_AUTOMEDIA ?
+ AUTONEG_ENABLE : AUTONEG_DISABLE);
return 0;
}
@@ -631,16 +621,49 @@ static int etherh_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return 0;
}
+static u32 etherh_get_msglevel(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ return ei_local->msg_enable;
+}
+
+static void etherh_set_msglevel(struct net_device *dev, u32 v)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ ei_local->msg_enable = v;
+}
+
static const struct ethtool_ops etherh_ethtool_ops = {
.get_settings = etherh_get_settings,
.set_settings = etherh_set_settings,
.get_drvinfo = etherh_get_drvinfo,
+ .get_ts_info = ethtool_op_get_ts_info,
+ .get_msglevel = etherh_get_msglevel,
+ .set_msglevel = etherh_set_msglevel,
+};
+
+static const struct net_device_ops etherh_netdev_ops = {
+ .ndo_open = etherh_open,
+ .ndo_stop = etherh_close,
+ .ndo_set_config = etherh_set_config,
+ .ndo_start_xmit = __ei_start_xmit,
+ .ndo_tx_timeout = __ei_tx_timeout,
+ .ndo_get_stats = __ei_get_stats,
+ .ndo_set_rx_mode = __ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = __ei_poll,
+#endif
};
static u32 etherh_regoffsets[16];
static u32 etherm_regoffsets[16];
-static int __init
+static int
etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
{
const struct etherh_data *data = id->data;
@@ -648,7 +671,6 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
struct net_device *dev;
struct etherh_priv *eh;
int ret;
- DECLARE_MAC_BUF(mac);
etherh_banner();
@@ -664,9 +686,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
SET_NETDEV_DEV(dev, &ec->dev);
- dev->open = etherh_open;
- dev->stop = etherh_close;
- dev->set_config = etherh_set_config;
+ dev->netdev_ops = &etherh_netdev_ops;
dev->irq = ec->irq;
dev->ethtool_ops = &etherh_ethtool_ops;
@@ -738,6 +758,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
ei_local->block_output = etherh_block_output;
ei_local->get_8390_hdr = etherh_get_header;
ei_local->interface_num = 0;
+ ei_local->msg_enable = etherh_msg_enable;
etherh_reset(dev);
__NS8390_init(dev, 0);
@@ -746,8 +767,8 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
if (ret)
goto free;
- printk(KERN_INFO "%s: %s in slot %d, %s\n",
- dev->name, data->name, ec->slot_no, print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "%s in slot %d, %pM\n",
+ data->name, ec->slot_no, dev->dev_addr);
ecard_set_drvdata(ec, dev);
@@ -761,7 +782,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
return ret;
}
-static void __devexit etherh_remove(struct expansion_card *ec)
+static void etherh_remove(struct expansion_card *ec)
{
struct net_device *dev = ecard_get_drvdata(ec);
@@ -825,7 +846,7 @@ static const struct ecard_id etherh_ids[] = {
static struct ecard_driver etherh_driver = {
.probe = etherh_probe,
- .remove = __devexit_p(etherh_remove),
+ .remove = etherh_remove,
.id_table = etherh_ids,
.drv = {
.name = DRV_NAME,
diff --git a/drivers/net/hydra.c b/drivers/net/ethernet/8390/hydra.c
index b96cf2dcb10..0fe19d609c2 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/ethernet/8390/hydra.c
@@ -17,7 +17,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -54,9 +53,9 @@ static const char version[] =
#define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8))
-static int __devinit hydra_init_one(struct zorro_dev *z,
+static int hydra_init_one(struct zorro_dev *z,
const struct zorro_device_id *ent);
-static int __devinit hydra_init(struct zorro_dev *z);
+static int hydra_init(struct zorro_dev *z);
static int hydra_open(struct net_device *dev);
static int hydra_close(struct net_device *dev);
static void hydra_reset_8390(struct net_device *dev);
@@ -66,22 +65,24 @@ static void hydra_block_input(struct net_device *dev, int count,
struct sk_buff *skb, int ring_offset);
static void hydra_block_output(struct net_device *dev, int count,
const unsigned char *buf, int start_page);
-static void __devexit hydra_remove_one(struct zorro_dev *z);
+static void hydra_remove_one(struct zorro_dev *z);
+static u32 hydra_msg_enable;
-static struct zorro_device_id hydra_zorro_tbl[] __devinitdata = {
+static struct zorro_device_id hydra_zorro_tbl[] = {
{ ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET },
{ 0 }
};
+MODULE_DEVICE_TABLE(zorro, hydra_zorro_tbl);
static struct zorro_driver hydra_driver = {
.name = "hydra",
.id_table = hydra_zorro_tbl,
.probe = hydra_init_one,
- .remove = __devexit_p(hydra_remove_one),
+ .remove = hydra_remove_one,
};
-static int __devinit hydra_init_one(struct zorro_dev *z,
- const struct zorro_device_id *ent)
+static int hydra_init_one(struct zorro_dev *z,
+ const struct zorro_device_id *ent)
{
int err;
@@ -94,16 +95,32 @@ static int __devinit hydra_init_one(struct zorro_dev *z,
return 0;
}
-static int __devinit hydra_init(struct zorro_dev *z)
+static const struct net_device_ops hydra_netdev_ops = {
+ .ndo_open = hydra_open,
+ .ndo_stop = hydra_close,
+
+ .ndo_start_xmit = __ei_start_xmit,
+ .ndo_tx_timeout = __ei_tx_timeout,
+ .ndo_get_stats = __ei_get_stats,
+ .ndo_set_rx_mode = __ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = __ei_poll,
+#endif
+};
+
+static int hydra_init(struct zorro_dev *z)
{
struct net_device *dev;
- unsigned long board = ZTWO_VADDR(z->resource.start);
+ unsigned long board = (unsigned long)ZTWO_VADDR(z->resource.start);
unsigned long ioaddr = board+HYDRA_NIC_BASE;
const char name[] = "NE2000";
int start_page, stop_page;
int j;
int err;
- DECLARE_MAC_BUF(mac);
+ struct ei_device *ei_local;
static u32 hydra_offsets[16] = {
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
@@ -114,7 +131,7 @@ static int __devinit hydra_init(struct zorro_dev *z)
if (!dev)
return -ENOMEM;
- for(j = 0; j < ETHER_ADDR_LEN; j++)
+ for (j = 0; j < ETH_ALEN; j++)
dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j));
/* We must set the 8390 for word mode. */
@@ -122,6 +139,8 @@ static int __devinit hydra_init(struct zorro_dev *z)
start_page = NESM_START_PG;
stop_page = NESM_STOP_PG;
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = hydra_msg_enable;
dev->base_addr = ioaddr;
dev->irq = IRQ_AMIGA_PORTS;
@@ -140,17 +159,13 @@ static int __devinit hydra_init(struct zorro_dev *z)
ei_status.rx_start_page = start_page + TX_PAGES;
- ei_status.reset_8390 = &hydra_reset_8390;
- ei_status.block_input = &hydra_block_input;
- ei_status.block_output = &hydra_block_output;
- ei_status.get_8390_hdr = &hydra_get_8390_hdr;
+ ei_status.reset_8390 = hydra_reset_8390;
+ ei_status.block_input = hydra_block_input;
+ ei_status.block_output = hydra_block_output;
+ ei_status.get_8390_hdr = hydra_get_8390_hdr;
ei_status.reg_offset = hydra_offsets;
- dev->open = &hydra_open;
- dev->stop = &hydra_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = __ei_poll;
-#endif
+ dev->netdev_ops = &hydra_netdev_ops;
__NS8390_init(dev, 0);
err = register_netdev(dev);
@@ -162,9 +177,8 @@ static int __devinit hydra_init(struct zorro_dev *z)
zorro_set_drvdata(z, dev);
- printk(KERN_INFO "%s: Hydra at 0x%08lx, address "
- "%s (hydra.c " HYDRA_VERSION ")\n",
- dev->name, z->resource.start, print_mac(mac, dev->dev_addr));
+ pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n",
+ dev->name, &z->resource, dev->dev_addr);
return 0;
}
@@ -177,15 +191,16 @@ static int hydra_open(struct net_device *dev)
static int hydra_close(struct net_device *dev)
{
- if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n");
__ei_close(dev);
return 0;
}
static void hydra_reset_8390(struct net_device *dev)
{
- printk(KERN_INFO "Hydra hw reset not there\n");
+ netdev_info(dev, "Hydra hw reset not there\n");
}
static void hydra_get_8390_hdr(struct net_device *dev,
@@ -237,7 +252,7 @@ static void hydra_block_output(struct net_device *dev, int count,
z_memcpy_toio(mem_base+((start_page - NESM_START_PG)<<8), buf, count);
}
-static void __devexit hydra_remove_one(struct zorro_dev *z)
+static void hydra_remove_one(struct zorro_dev *z)
{
struct net_device *dev = zorro_get_drvdata(z);
diff --git a/drivers/net/lib8390.c b/drivers/net/ethernet/8390/lib8390.c
index 00d59ab2f8a..599311f0e05 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/ethernet/8390/lib8390.c
@@ -35,8 +35,8 @@
Alexey Kuznetsov : use the 8390's six bit hash multicast filter.
Paul Gortmaker : tweak ANK's above multicast changes a bit.
Paul Gortmaker : update packet statistics for v2.1.x
- Alan Cox : support arbitary stupid port mappings on the
- 68K Macintosh. Support >16bit I/O spaces
+ Alan Cox : support arbitrary stupid port mappings on the
+ 68K Macintosh. Support >16bit I/O spaces
Paul Gortmaker : add kmod support for auto-loading of the 8390
module by all drivers that require it.
Alan Cox : Spinlocking work, added 'BUG_83C690'
@@ -57,9 +57,8 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/bitops.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <asm/irq.h>
#include <linux/delay.h>
#include <linux/errno.h>
@@ -100,29 +99,27 @@
#define ei_block_input (ei_local->block_input)
#define ei_get_8390_hdr (ei_local->get_8390_hdr)
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef ei_debug
-int ei_debug = 1;
-#endif
-
/* Index to functions. */
static void ei_tx_intr(struct net_device *dev);
static void ei_tx_err(struct net_device *dev);
-static void ei_tx_timeout(struct net_device *dev);
static void ei_receive(struct net_device *dev);
static void ei_rx_overrun(struct net_device *dev);
/* Routines generic to NS8390-based boards. */
static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page);
-static void set_multicast_list(struct net_device *dev);
static void do_set_multicast_list(struct net_device *dev);
static void __NS8390_init(struct net_device *dev, int startp);
+static unsigned version_printed;
+static u32 msg_enable;
+module_param(msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
+MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
+
/*
* SMP and the 8390 setup.
*
- * The 8390 isnt exactly designed to be multithreaded on RX/TX. There is
+ * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is
* a page register that controls bank and packet buffer access. We guard
* this with ei_local->page_lock. Nobody should assume or set the page other
* than zero when the lock is not held. Lock holders must restore page 0
@@ -204,26 +201,22 @@ static void __NS8390_init(struct net_device *dev, int startp);
static int __ei_open(struct net_device *dev)
{
unsigned long flags;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
- /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
- wrapper that does e.g. media check & then calls ei_tx_timeout. */
- if (dev->tx_timeout == NULL)
- dev->tx_timeout = ei_tx_timeout;
if (dev->watchdog_timeo <= 0)
- dev->watchdog_timeo = TX_TIMEOUT;
+ dev->watchdog_timeo = TX_TIMEOUT;
/*
* Grab the page lock so we own the register set, then call
* the init function.
*/
- spin_lock_irqsave(&ei_local->page_lock, flags);
+ spin_lock_irqsave(&ei_local->page_lock, flags);
__NS8390_init(dev, 1);
/* Set the flag before we drop the lock, That way the IRQ arrives
after its set and we get no silly warnings */
netif_start_queue(dev);
- spin_unlock_irqrestore(&ei_local->page_lock, flags);
+ spin_unlock_irqrestore(&ei_local->page_lock, flags);
ei_local->irqlock = 0;
return 0;
}
@@ -236,16 +229,16 @@ static int __ei_open(struct net_device *dev)
*/
static int __ei_close(struct net_device *dev)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
/*
* Hold the page lock during close
*/
- spin_lock_irqsave(&ei_local->page_lock, flags);
+ spin_lock_irqsave(&ei_local->page_lock, flags);
__NS8390_init(dev, 0);
- spin_unlock_irqrestore(&ei_local->page_lock, flags);
+ spin_unlock_irqrestore(&ei_local->page_lock, flags);
netif_stop_queue(dev);
return 0;
}
@@ -258,11 +251,11 @@ static int __ei_close(struct net_device *dev)
* completed (or failed) - i.e. never posted a Tx related interrupt.
*/
-static void ei_tx_timeout(struct net_device *dev)
+static void __ei_tx_timeout(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
- int txsr, isr, tickssofar = jiffies - dev->trans_start;
+ struct ei_device *ei_local = netdev_priv(dev);
+ int txsr, isr, tickssofar = jiffies - dev_trans_start(dev);
unsigned long flags;
dev->stats.tx_errors++;
@@ -272,12 +265,12 @@ static void ei_tx_timeout(struct net_device *dev)
isr = ei_inb(e8390_base+EN0_ISR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
- printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
- dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
- (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
+ netdev_dbg(dev, "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d\n",
+ (txsr & ENTSR_ABT) ? "excess collisions." :
+ (isr) ? "lost interrupt?" : "cable problem?",
+ txsr, isr, tickssofar);
- if (!isr && !dev->stats.tx_packets)
- {
+ if (!isr && !dev->stats.tx_packets) {
/* The 8390 probably hasn't gotten on the cable yet. */
ei_local->interface_num ^= 1; /* Try a different xcvr. */
}
@@ -304,10 +297,11 @@ static void ei_tx_timeout(struct net_device *dev)
* Sends a packet to an 8390 network device.
*/
-static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t __ei_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int send_length = skb->len, output_page;
unsigned long flags;
char buf[ETH_ZLEN];
@@ -348,34 +342,33 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
* card, leaving a substantial gap between each transmitted packet.
*/
- if (ei_local->tx1 == 0)
- {
+ if (ei_local->tx1 == 0) {
output_page = ei_local->tx_start_page;
ei_local->tx1 = send_length;
- if (ei_debug && ei_local->tx2 > 0)
- printk(KERN_DEBUG "%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing);
- }
- else if (ei_local->tx2 == 0)
- {
+ if ((netif_msg_tx_queued(ei_local)) &&
+ ei_local->tx2 > 0)
+ netdev_dbg(dev,
+ "idle transmitter tx2=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx2, ei_local->lasttx, ei_local->txing);
+ } else if (ei_local->tx2 == 0) {
output_page = ei_local->tx_start_page + TX_PAGES/2;
ei_local->tx2 = send_length;
- if (ei_debug && ei_local->tx1 > 0)
- printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing);
- }
- else
- { /* We should never get here. */
- if (ei_debug)
- printk(KERN_DEBUG "%s: No Tx buffers free! tx1=%d tx2=%d last=%d\n",
- dev->name, ei_local->tx1, ei_local->tx2, ei_local->lasttx);
+ if ((netif_msg_tx_queued(ei_local)) &&
+ ei_local->tx1 > 0)
+ netdev_dbg(dev,
+ "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n",
+ ei_local->tx1, ei_local->lasttx, ei_local->txing);
+ } else { /* We should never get here. */
+ netif_dbg(ei_local, tx_err, dev,
+ "No Tx buffers free! tx1=%d tx2=%d last=%d\n",
+ ei_local->tx1, ei_local->tx2, ei_local->lasttx);
ei_local->irqlock = 0;
netif_stop_queue(dev);
ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock(&ei_local->page_lock);
enable_irq_lockdep_irqrestore(dev->irq, &flags);
dev->stats.tx_errors++;
- return 1;
+ return NETDEV_TX_BUSY;
}
/*
@@ -386,25 +379,20 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
ei_block_output(dev, send_length, data, output_page);
- if (! ei_local->txing)
- {
+ if (!ei_local->txing) {
ei_local->txing = 1;
NS8390_trigger_send(dev, send_length, output_page);
- dev->trans_start = jiffies;
- if (output_page == ei_local->tx_start_page)
- {
+ if (output_page == ei_local->tx_start_page) {
ei_local->tx1 = -1;
ei_local->lasttx = -1;
- }
- else
- {
+ } else {
ei_local->tx2 = -1;
ei_local->lasttx = -2;
}
- }
- else ei_local->txqueue++;
+ } else
+ ei_local->txqueue++;
- if (ei_local->tx1 && ei_local->tx2)
+ if (ei_local->tx1 && ei_local->tx2)
netif_stop_queue(dev);
else
netif_start_queue(dev);
@@ -415,11 +403,11 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock(&ei_local->page_lock);
enable_irq_lockdep_irqrestore(dev->irq, &flags);
-
- dev_kfree_skb (skb);
+ skb_tx_timestamp(skb);
+ dev_consume_skb_any(skb);
dev->stats.tx_bytes += send_length;
- return 0;
+ return NETDEV_TX_OK;
}
/**
@@ -447,32 +435,28 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id)
spin_lock(&ei_local->page_lock);
- if (ei_local->irqlock)
- {
-#if 1 /* This might just be an interrupt for a PCI device sharing this line */
- /* The "irqlock" check is only for testing. */
- printk(ei_local->irqlock
- ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n"
- : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n",
- dev->name, ei_inb_p(e8390_base + EN0_ISR),
+ if (ei_local->irqlock) {
+ /*
+ * This might just be an interrupt for a PCI device sharing
+ * this line
+ */
+ netdev_err(dev, "Interrupted while interrupts are masked! isr=%#2x imr=%#2x\n",
+ ei_inb_p(e8390_base + EN0_ISR),
ei_inb_p(e8390_base + EN0_IMR));
-#endif
spin_unlock(&ei_local->page_lock);
return IRQ_NONE;
}
/* Change to page 0 and read the intr status reg. */
ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);
- if (ei_debug > 3)
- printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name,
- ei_inb_p(e8390_base + EN0_ISR));
+ netif_dbg(ei_local, intr, dev, "interrupt(isr=%#2.2x)\n",
+ ei_inb_p(e8390_base + EN0_ISR));
/* !!Assumption!! -- we stay in page 0. Don't break this. */
- while ((interrupts = ei_inb_p(e8390_base + EN0_ISR)) != 0
- && ++nr_serviced < MAX_SERVICE)
- {
+ while ((interrupts = ei_inb_p(e8390_base + EN0_ISR)) != 0 &&
+ ++nr_serviced < MAX_SERVICE) {
if (!netif_running(dev)) {
- printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name);
+ netdev_warn(dev, "interrupt from stopped card\n");
/* rmk - acknowledge the interrupts */
ei_outb_p(interrupts, e8390_base + EN0_ISR);
interrupts = 0;
@@ -480,8 +464,7 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id)
}
if (interrupts & ENISR_OVER)
ei_rx_overrun(dev);
- else if (interrupts & (ENISR_RX+ENISR_RX_ERR))
- {
+ else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) {
/* Got a good (?) packet. */
ei_receive(dev);
}
@@ -491,35 +474,30 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id)
else if (interrupts & ENISR_TX_ERR)
ei_tx_err(dev);
- if (interrupts & ENISR_COUNTERS)
- {
+ if (interrupts & ENISR_COUNTERS) {
dev->stats.rx_frame_errors += ei_inb_p(e8390_base + EN0_COUNTER0);
dev->stats.rx_crc_errors += ei_inb_p(e8390_base + EN0_COUNTER1);
- dev->stats.rx_missed_errors+= ei_inb_p(e8390_base + EN0_COUNTER2);
+ dev->stats.rx_missed_errors += ei_inb_p(e8390_base + EN0_COUNTER2);
ei_outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */
}
/* Ignore any RDC interrupts that make it back to here. */
if (interrupts & ENISR_RDC)
- {
ei_outb_p(ENISR_RDC, e8390_base + EN0_ISR);
- }
ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
}
- if (interrupts && ei_debug)
- {
+ if (interrupts && (netif_msg_intr(ei_local))) {
ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
- if (nr_serviced >= MAX_SERVICE)
- {
+ if (nr_serviced >= MAX_SERVICE) {
/* 0xFF is valid for a card removal */
- if(interrupts!=0xFF)
- printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n",
- dev->name, interrupts);
+ if (interrupts != 0xFF)
+ netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n",
+ interrupts);
ei_outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
} else {
- printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts);
+ netdev_warn(dev, "unknown interrupt %#2x\n", interrupts);
ei_outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */
}
}
@@ -530,9 +508,9 @@ static irqreturn_t __ei_interrupt(int irq, void *dev_id)
#ifdef CONFIG_NET_POLL_CONTROLLER
static void __ei_poll(struct net_device *dev)
{
- disable_irq_lockdep(dev->irq);
+ disable_irq(dev->irq);
__ei_interrupt(dev->irq, dev);
- enable_irq_lockdep(dev->irq);
+ enable_irq(dev->irq);
}
#endif
@@ -559,30 +537,32 @@ static void ei_tx_err(struct net_device *dev)
unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
#ifdef VERBOSE_ERROR_DUMP
- printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr);
+ netdev_dbg(dev, "transmitter error (%#2x):", txsr);
if (txsr & ENTSR_ABT)
- printk("excess-collisions ");
+ pr_cont(" excess-collisions ");
if (txsr & ENTSR_ND)
- printk("non-deferral ");
+ pr_cont(" non-deferral ");
if (txsr & ENTSR_CRS)
- printk("lost-carrier ");
+ pr_cont(" lost-carrier ");
if (txsr & ENTSR_FU)
- printk("FIFO-underrun ");
+ pr_cont(" FIFO-underrun ");
if (txsr & ENTSR_CDH)
- printk("lost-heartbeat ");
- printk("\n");
+ pr_cont(" lost-heartbeat ");
+ pr_cont("\n");
#endif
ei_outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */
if (tx_was_aborted)
ei_tx_intr(dev);
- else
- {
+ else {
dev->stats.tx_errors++;
- if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++;
- if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++;
- if (txsr & ENTSR_OWC) dev->stats.tx_window_errors++;
+ if (txsr & ENTSR_CRS)
+ dev->stats.tx_carrier_errors++;
+ if (txsr & ENTSR_CDH)
+ dev->stats.tx_heartbeat_errors++;
+ if (txsr & ENTSR_OWC)
+ dev->stats.tx_window_errors++;
}
}
@@ -597,7 +577,7 @@ static void ei_tx_err(struct net_device *dev)
static void ei_tx_intr(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int status = ei_inb(e8390_base + EN0_TSR);
ei_outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */
@@ -608,52 +588,45 @@ static void ei_tx_intr(struct net_device *dev)
*/
ei_local->txqueue--;
- if (ei_local->tx1 < 0)
- {
+ if (ei_local->tx1 < 0) {
if (ei_local->lasttx != 1 && ei_local->lasttx != -1)
- printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx1);
+ pr_err("%s: bogus last_tx_buffer %d, tx1=%d\n",
+ ei_local->name, ei_local->lasttx, ei_local->tx1);
ei_local->tx1 = 0;
- if (ei_local->tx2 > 0)
- {
+ if (ei_local->tx2 > 0) {
ei_local->txing = 1;
NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6);
dev->trans_start = jiffies;
ei_local->tx2 = -1,
ei_local->lasttx = 2;
- }
- else ei_local->lasttx = 20, ei_local->txing = 0;
- }
- else if (ei_local->tx2 < 0)
- {
+ } else
+ ei_local->lasttx = 20, ei_local->txing = 0;
+ } else if (ei_local->tx2 < 0) {
if (ei_local->lasttx != 2 && ei_local->lasttx != -2)
- printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx2);
+ pr_err("%s: bogus last_tx_buffer %d, tx2=%d\n",
+ ei_local->name, ei_local->lasttx, ei_local->tx2);
ei_local->tx2 = 0;
- if (ei_local->tx1 > 0)
- {
+ if (ei_local->tx1 > 0) {
ei_local->txing = 1;
NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page);
dev->trans_start = jiffies;
ei_local->tx1 = -1;
ei_local->lasttx = 1;
- }
- else
+ } else
ei_local->lasttx = 10, ei_local->txing = 0;
- }
-// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",
-// dev->name, ei_local->lasttx);
+ } /* else
+ netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n",
+ ei_local->lasttx);
+*/
/* Minimize Tx latency: update the statistics after we restart TXing. */
if (status & ENTSR_COL)
dev->stats.collisions++;
if (status & ENTSR_PTX)
dev->stats.tx_packets++;
- else
- {
+ else {
dev->stats.tx_errors++;
- if (status & ENTSR_ABT)
- {
+ if (status & ENTSR_ABT) {
dev->stats.tx_aborted_errors++;
dev->stats.collisions += 16;
}
@@ -680,15 +653,14 @@ static void ei_tx_intr(struct net_device *dev)
static void ei_receive(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned char rxing_page, this_frame, next_frame;
unsigned short current_offset;
int rx_pkt_count = 0;
struct e8390_pkt_hdr rx_frame;
int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page;
- while (++rx_pkt_count < 10)
- {
+ while (++rx_pkt_count < 10) {
int pkt_len, pkt_stat;
/* Get the rx page (incoming packet pointer). */
@@ -707,9 +679,12 @@ static void ei_receive(struct net_device *dev)
Keep quiet if it looks like a card removal. One problem here
is that some clones crash in roughly the same way.
*/
- if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF))
- printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n",
- dev->name, this_frame, ei_local->current_page);
+ if ((netif_msg_rx_status(ei_local)) &&
+ this_frame != ei_local->current_page &&
+ (this_frame != 0x0 || rxing_page != 0xFF))
+ netdev_err(dev,
+ "mismatched read page pointers %2x vs %2x\n",
+ this_frame, ei_local->current_page);
if (this_frame == rxing_page) /* Read all the frames? */
break; /* Done for now */
@@ -725,58 +700,50 @@ static void ei_receive(struct net_device *dev)
/* Check for bogosity warned by 3c503 book: the status byte is never
written. This happened a lot during testing! This code should be
cleaned up someday. */
- if (rx_frame.next != next_frame
- && rx_frame.next != next_frame + 1
- && rx_frame.next != next_frame - num_rx_pages
- && rx_frame.next != next_frame + 1 - num_rx_pages) {
+ if (rx_frame.next != next_frame &&
+ rx_frame.next != next_frame + 1 &&
+ rx_frame.next != next_frame - num_rx_pages &&
+ rx_frame.next != next_frame + 1 - num_rx_pages) {
ei_local->current_page = rxing_page;
ei_outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY);
dev->stats.rx_errors++;
continue;
}
- if (pkt_len < 60 || pkt_len > 1518)
- {
- if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
- dev->name, rx_frame.count, rx_frame.status,
- rx_frame.next);
+ if (pkt_len < 60 || pkt_len > 1518) {
+ netif_dbg(ei_local, rx_status, dev,
+ "bogus packet size: %d, status=%#2x nxpg=%#2x\n",
+ rx_frame.count, rx_frame.status,
+ rx_frame.next);
dev->stats.rx_errors++;
dev->stats.rx_length_errors++;
- }
- else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
- {
+ } else if ((pkt_stat & 0x0F) == ENRSR_RXOK) {
struct sk_buff *skb;
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL)
- {
- if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
+ skb = netdev_alloc_skb(dev, pkt_len + 2);
+ if (skb == NULL) {
+ netif_err(ei_local, rx_err, dev,
+ "Couldn't allocate a sk_buff of size %d\n",
+ pkt_len);
dev->stats.rx_dropped++;
break;
- }
- else
- {
- skb_reserve(skb,2); /* IP headers on 16 byte boundaries */
+ } else {
+ skb_reserve(skb, 2); /* IP headers on 16 byte boundaries */
skb_put(skb, pkt_len); /* Make room */
ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
+ skb->protocol = eth_type_trans(skb, dev);
+ if (!skb_defer_rx_timestamp(skb))
+ netif_rx(skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
if (pkt_stat & ENRSR_PHY)
dev->stats.multicast++;
}
- }
- else
- {
- if (ei_debug)
- printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
- dev->name, rx_frame.status, rx_frame.next,
- rx_frame.count);
+ } else {
+ netif_err(ei_local, rx_err, dev,
+ "bogus packet: status=%#2x nxpg=%#2x size=%d\n",
+ rx_frame.status, rx_frame.next,
+ rx_frame.count);
dev->stats.rx_errors++;
/* NB: The NIC counts CRC, frame and missed errors. */
if (pkt_stat & ENRSR_FO)
@@ -786,8 +753,8 @@ static void ei_receive(struct net_device *dev)
/* This _should_ never happen: it's here for avoiding bad clones. */
if (next_frame >= ei_local->stop_page) {
- printk("%s: next frame inconsistency, %#2x\n", dev->name,
- next_frame);
+ netdev_notice(dev, "next frame inconsistency, %#2x\n",
+ next_frame);
next_frame = ei_local->rx_start_page;
}
ei_local->current_page = next_frame;
@@ -797,7 +764,6 @@ static void ei_receive(struct net_device *dev)
/* We used to also ack ENISR_OVER here, but that would sometimes mask
a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
ei_outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR);
- return;
}
/**
@@ -827,8 +793,7 @@ static void ei_rx_overrun(struct net_device *dev)
was_txing = ei_inb_p(e8390_base+E8390_CMD) & E8390_TRANS;
ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
- if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name);
+ netif_dbg(ei_local, rx_err, dev, "Receiver overrun\n");
dev->stats.rx_over_errors++;
/*
@@ -851,8 +816,7 @@ static void ei_rx_overrun(struct net_device *dev)
* step is vital, and skipping it will cause no end of havoc.
*/
- if (was_txing)
- {
+ if (was_txing) {
unsigned char tx_completed = ei_inb_p(e8390_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR);
if (!tx_completed)
must_resend = 1;
@@ -876,28 +840,28 @@ static void ei_rx_overrun(struct net_device *dev)
*/
ei_outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR);
if (must_resend)
- ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD);
+ ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD);
}
/*
* Collect the stats. This is called unlocked and from several contexts.
*/
-static struct net_device_stats *get_stats(struct net_device *dev)
+static struct net_device_stats *__ei_get_stats(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
/* If the card is stopped, just return the present stats. */
if (!netif_running(dev))
return &dev->stats;
- spin_lock_irqsave(&ei_local->page_lock,flags);
+ spin_lock_irqsave(&ei_local->page_lock, flags);
/* Read the counter registers, assuming we are in page 0. */
- dev->stats.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0);
- dev->stats.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1);
- dev->stats.rx_missed_errors+= ei_inb_p(ioaddr + EN0_COUNTER2);
+ dev->stats.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0);
+ dev->stats.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1);
+ dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
return &dev->stats;
@@ -910,17 +874,10 @@ static struct net_device_stats *get_stats(struct net_device *dev)
static inline void make_mc_bits(u8 *bits, struct net_device *dev)
{
- struct dev_mc_list *dmi;
-
- for (dmi=dev->mc_list; dmi; dmi=dmi->next)
- {
- u32 crc;
- if (dmi->dmi_addrlen != ETH_ALEN)
- {
- printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
- continue;
- }
- crc = ether_crc(ETH_ALEN, dmi->dmi_addr);
+ struct netdev_hw_addr *ha;
+
+ netdev_for_each_mc_addr(ha, dev) {
+ u32 crc = ether_crc(ETH_ALEN, ha->addr);
/*
* The 8390 uses the 6 most significant bits of the
* CRC to index the multicast table.
@@ -941,15 +898,13 @@ static void do_set_multicast_list(struct net_device *dev)
{
unsigned long e8390_base = dev->base_addr;
int i;
- struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
- if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
- {
+ if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) {
memset(ei_local->mcfilter, 0, 8);
- if (dev->mc_list)
+ if (!netdev_mc_empty(dev))
make_mc_bits(ei_local->mcfilter, dev);
- }
- else
+ } else
memset(ei_local->mcfilter, 0xFF, 8); /* mcast set to accept-all */
/*
@@ -968,23 +923,23 @@ static void do_set_multicast_list(struct net_device *dev)
if (netif_running(dev))
ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
ei_outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD);
- for(i = 0; i < 8; i++)
- {
+ for (i = 0; i < 8; i++) {
ei_outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i));
#ifndef BUG_83C690
- if(ei_inb_p(e8390_base + EN1_MULT_SHIFT(i))!=ei_local->mcfilter[i])
- printk(KERN_ERR "Multicast filter read/write mismap %d\n",i);
+ if (ei_inb_p(e8390_base + EN1_MULT_SHIFT(i)) != ei_local->mcfilter[i])
+ netdev_err(dev, "Multicast filter read/write mismap %d\n",
+ i);
#endif
}
ei_outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD);
- if(dev->flags&IFF_PROMISC)
- ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR);
- else if(dev->flags&IFF_ALLMULTI || dev->mc_list)
- ei_outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR);
- else
- ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
- }
+ if (dev->flags&IFF_PROMISC)
+ ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR);
+ else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev))
+ ei_outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR);
+ else
+ ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
+}
/*
* Called without lock held. This is invoked from user context and may
@@ -992,10 +947,10 @@ static void do_set_multicast_list(struct net_device *dev)
* not called too often. Must protect against both bh and irq users
*/
-static void set_multicast_list(struct net_device *dev)
+static void __ei_set_multicast_list(struct net_device *dev)
{
unsigned long flags;
- struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
spin_lock_irqsave(&ei_local->page_lock, flags);
do_set_multicast_list(dev);
@@ -1012,13 +967,10 @@ static void set_multicast_list(struct net_device *dev)
static void ethdev_setup(struct net_device *dev)
{
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
- if (ei_debug > 1)
- printk(version);
+ struct ei_device *ei_local = netdev_priv(dev);
- dev->hard_start_xmit = &ei_start_xmit;
- dev->get_stats = get_stats;
- dev->set_multicast_list = &set_multicast_list;
+ if ((msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
+ pr_info("%s", version);
ether_setup(dev);
@@ -1054,14 +1006,14 @@ static struct net_device *____alloc_ei_netdev(int size)
static void __NS8390_init(struct net_device *dev, int startp)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local = netdev_priv(dev);
int i;
int endcfg = ei_local->word16
? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0))
: 0x48;
- if(sizeof(struct e8390_pkt_hdr)!=4)
- panic("8390.c: header struct mispacked\n");
+ if (sizeof(struct e8390_pkt_hdr) != 4)
+ panic("8390.c: header struct mispacked\n");
/* Follow National Semi's recommendations for initing the DP83902. */
ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); /* 0x21 */
ei_outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */
@@ -1085,22 +1037,21 @@ static void __NS8390_init(struct net_device *dev, int startp)
/* Copy the station address into the DS8390 registers. */
ei_outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */
- for(i = 0; i < 6; i++)
- {
+ for (i = 0; i < 6; i++) {
ei_outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i));
- if (ei_debug > 1 && ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i])
- printk(KERN_ERR "Hw. address read/write mismap %d\n",i);
+ if ((netif_msg_probe(ei_local)) &&
+ ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i)) != dev->dev_addr[i])
+ netdev_err(dev,
+ "Hw. address read/write mismap %d\n", i);
}
ei_outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
- netif_start_queue(dev);
ei_local->tx1 = ei_local->tx2 = 0;
ei_local->txing = 0;
- if (startp)
- {
+ if (startp) {
ei_outb_p(0xff, e8390_base + EN0_ISR);
ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR);
ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD);
@@ -1118,14 +1069,12 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page)
{
unsigned long e8390_base = dev->base_addr;
- struct ei_device *ei_local __attribute((unused)) = (struct ei_device *) netdev_priv(dev);
+ struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev);
ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);
- if (ei_inb_p(e8390_base + E8390_CMD) & E8390_TRANS)
- {
- printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n",
- dev->name);
+ if (ei_inb_p(e8390_base + E8390_CMD) & E8390_TRANS) {
+ netdev_warn(dev, "trigger_send() called with the transmitter busy\n");
return;
}
ei_outb_p(length & 0xff, e8390_base + EN0_TCNTLO);
diff --git a/drivers/net/ethernet/8390/mac8390.c b/drivers/net/ethernet/8390/mac8390.c
new file mode 100644
index 00000000000..90e825e8abf
--- /dev/null
+++ b/drivers/net/ethernet/8390/mac8390.c
@@ -0,0 +1,882 @@
+/* mac8390.c: New driver for 8390-based Nubus (or Nubus-alike)
+ Ethernet cards on Linux */
+/* Based on the former daynaport.c driver, by Alan Cox. Some code
+ taken from or inspired by skeleton.c by Donald Becker, acenic.c by
+ Jes Sorensen, and ne2k-pci.c by Donald Becker and Paul Gortmaker.
+
+ This software may be used and distributed according to the terms of
+ the GNU Public License, incorporated herein by reference. */
+
+/* 2000-02-28: support added for Dayna and Kinetics cards by
+ A.G.deWijn@phys.uu.nl */
+/* 2000-04-04: support added for Dayna2 by bart@etpmod.phys.tue.nl */
+/* 2001-04-18: support for DaynaPort E/LC-M by rayk@knightsmanor.org */
+/* 2001-05-15: support for Cabletron ported from old daynaport driver
+ * and fixed access to Sonic Sys card which masquerades as a Farallon
+ * by rayk@knightsmanor.org */
+/* 2002-12-30: Try to support more cards, some clues from NetBSD driver */
+/* 2003-12-26: Make sure Asante cards always work. */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/nubus.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+
+#include <asm/dma.h>
+#include <asm/hwtest.h>
+#include <asm/macints.h>
+
+static char version[] =
+ "v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n";
+
+#define EI_SHIFT(x) (ei_local->reg_offset[x])
+#define ei_inb(port) in_8(port)
+#define ei_outb(val, port) out_8(port, val)
+#define ei_inb_p(port) in_8(port)
+#define ei_outb_p(val, port) out_8(port, val)
+
+#include "lib8390.c"
+
+#define WD_START_PG 0x00 /* First page of TX buffer */
+#define CABLETRON_RX_START_PG 0x00 /* First page of RX buffer */
+#define CABLETRON_RX_STOP_PG 0x30 /* Last page +1 of RX ring */
+#define CABLETRON_TX_START_PG CABLETRON_RX_STOP_PG
+ /* First page of TX buffer */
+
+/*
+ * Unfortunately it seems we have to hardcode these for the moment
+ * Shouldn't the card know about this?
+ * Does anyone know where to read it off the card?
+ * Do we trust the data provided by the card?
+ */
+
+#define DAYNA_8390_BASE 0x80000
+#define DAYNA_8390_MEM 0x00000
+
+#define CABLETRON_8390_BASE 0x90000
+#define CABLETRON_8390_MEM 0x00000
+
+#define INTERLAN_8390_BASE 0xE0000
+#define INTERLAN_8390_MEM 0xD0000
+
+enum mac8390_type {
+ MAC8390_NONE = -1,
+ MAC8390_APPLE,
+ MAC8390_ASANTE,
+ MAC8390_FARALLON,
+ MAC8390_CABLETRON,
+ MAC8390_DAYNA,
+ MAC8390_INTERLAN,
+ MAC8390_KINETICS,
+};
+
+static const char *cardname[] = {
+ "apple",
+ "asante",
+ "farallon",
+ "cabletron",
+ "dayna",
+ "interlan",
+ "kinetics",
+};
+
+static const int word16[] = {
+ 1, /* apple */
+ 1, /* asante */
+ 1, /* farallon */
+ 1, /* cabletron */
+ 0, /* dayna */
+ 1, /* interlan */
+ 0, /* kinetics */
+};
+
+/* on which cards do we use NuBus resources? */
+static const int useresources[] = {
+ 1, /* apple */
+ 1, /* asante */
+ 1, /* farallon */
+ 0, /* cabletron */
+ 0, /* dayna */
+ 0, /* interlan */
+ 0, /* kinetics */
+};
+
+enum mac8390_access {
+ ACCESS_UNKNOWN = 0,
+ ACCESS_32,
+ ACCESS_16,
+};
+
+extern int mac8390_memtest(struct net_device *dev);
+static int mac8390_initdev(struct net_device *dev, struct nubus_dev *ndev,
+ enum mac8390_type type);
+
+static int mac8390_open(struct net_device *dev);
+static int mac8390_close(struct net_device *dev);
+static void mac8390_no_reset(struct net_device *dev);
+static void interlan_reset(struct net_device *dev);
+
+/* Sane (32-bit chunk memory read/write) - Some Farallon and Apple do this*/
+static void sane_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page);
+static void sane_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
+static void sane_block_output(struct net_device *dev, int count,
+ const unsigned char *buf, const int start_page);
+
+/* dayna_memcpy to and from card */
+static void dayna_memcpy_fromcard(struct net_device *dev, void *to,
+ int from, int count);
+static void dayna_memcpy_tocard(struct net_device *dev, int to,
+ const void *from, int count);
+
+/* Dayna - Dayna/Kinetics use this */
+static void dayna_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page);
+static void dayna_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
+static void dayna_block_output(struct net_device *dev, int count,
+ const unsigned char *buf, int start_page);
+
+#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
+
+#define memcmp_withio(a, b, c) memcmp((a), (void *)(b), (c))
+
+/* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */
+static void slow_sane_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page);
+static void slow_sane_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
+static void slow_sane_block_output(struct net_device *dev, int count,
+ const unsigned char *buf, int start_page);
+static void word_memcpy_tocard(unsigned long tp, const void *fp, int count);
+static void word_memcpy_fromcard(void *tp, unsigned long fp, int count);
+static u32 mac8390_msg_enable;
+
+static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev)
+{
+ switch (dev->dr_sw) {
+ case NUBUS_DRSW_3COM:
+ switch (dev->dr_hw) {
+ case NUBUS_DRHW_APPLE_SONIC_NB:
+ case NUBUS_DRHW_APPLE_SONIC_LC:
+ case NUBUS_DRHW_SONNET:
+ return MAC8390_NONE;
+ break;
+ default:
+ return MAC8390_APPLE;
+ break;
+ }
+ break;
+
+ case NUBUS_DRSW_APPLE:
+ switch (dev->dr_hw) {
+ case NUBUS_DRHW_ASANTE_LC:
+ return MAC8390_NONE;
+ break;
+ case NUBUS_DRHW_CABLETRON:
+ return MAC8390_CABLETRON;
+ break;
+ default:
+ return MAC8390_APPLE;
+ break;
+ }
+ break;
+
+ case NUBUS_DRSW_ASANTE:
+ return MAC8390_ASANTE;
+ break;
+
+ case NUBUS_DRSW_TECHWORKS:
+ case NUBUS_DRSW_DAYNA2:
+ case NUBUS_DRSW_DAYNA_LC:
+ if (dev->dr_hw == NUBUS_DRHW_CABLETRON)
+ return MAC8390_CABLETRON;
+ else
+ return MAC8390_APPLE;
+ break;
+
+ case NUBUS_DRSW_FARALLON:
+ return MAC8390_FARALLON;
+ break;
+
+ case NUBUS_DRSW_KINETICS:
+ switch (dev->dr_hw) {
+ case NUBUS_DRHW_INTERLAN:
+ return MAC8390_INTERLAN;
+ break;
+ default:
+ return MAC8390_KINETICS;
+ break;
+ }
+ break;
+
+ case NUBUS_DRSW_DAYNA:
+ /*
+ * These correspond to Dayna Sonic cards
+ * which use the macsonic driver
+ */
+ if (dev->dr_hw == NUBUS_DRHW_SMC9194 ||
+ dev->dr_hw == NUBUS_DRHW_INTERLAN)
+ return MAC8390_NONE;
+ else
+ return MAC8390_DAYNA;
+ break;
+ }
+ return MAC8390_NONE;
+}
+
+static enum mac8390_access __init mac8390_testio(volatile unsigned long membase)
+{
+ unsigned long outdata = 0xA5A0B5B0;
+ unsigned long indata = 0x00000000;
+ /* Try writing 32 bits */
+ memcpy_toio(membase, &outdata, 4);
+ /* Now compare them */
+ if (memcmp_withio(&outdata, membase, 4) == 0)
+ return ACCESS_32;
+ /* Write 16 bit output */
+ word_memcpy_tocard(membase, &outdata, 4);
+ /* Now read it back */
+ word_memcpy_fromcard(&indata, membase, 4);
+ if (outdata == indata)
+ return ACCESS_16;
+ return ACCESS_UNKNOWN;
+}
+
+static int __init mac8390_memsize(unsigned long membase)
+{
+ unsigned long flags;
+ int i, j;
+
+ local_irq_save(flags);
+ /* Check up to 32K in 4K increments */
+ for (i = 0; i < 8; i++) {
+ volatile unsigned short *m = (unsigned short *)(membase + (i * 0x1000));
+
+ /* Unwriteable - we have a fully decoded card and the
+ RAM end located */
+ if (hwreg_present(m) == 0)
+ break;
+
+ /* write a distinctive byte */
+ *m = 0xA5A0 | i;
+ /* check that we read back what we wrote */
+ if (*m != (0xA5A0 | i))
+ break;
+
+ /* check for partial decode and wrap */
+ for (j = 0; j < i; j++) {
+ volatile unsigned short *p = (unsigned short *)(membase + (j * 0x1000));
+ if (*p != (0xA5A0 | j))
+ break;
+ }
+ }
+ local_irq_restore(flags);
+ /*
+ * in any case, we stopped once we tried one block too many,
+ * or once we reached 32K
+ */
+ return i * 0x1000;
+}
+
+static bool __init mac8390_init(struct net_device *dev, struct nubus_dev *ndev,
+ enum mac8390_type cardtype)
+{
+ struct nubus_dir dir;
+ struct nubus_dirent ent;
+ int offset;
+ volatile unsigned short *i;
+
+ printk_once(KERN_INFO pr_fmt("%s"), version);
+
+ dev->irq = SLOT2IRQ(ndev->board->slot);
+ /* This is getting to be a habit */
+ dev->base_addr = (ndev->board->slot_addr |
+ ((ndev->board->slot & 0xf) << 20));
+
+ /*
+ * Get some Nubus info - we will trust the card's idea
+ * of where its memory and registers are.
+ */
+
+ if (nubus_get_func_dir(ndev, &dir) == -1) {
+ pr_err("%s: Unable to get Nubus functional directory for slot %X!\n",
+ dev->name, ndev->board->slot);
+ return false;
+ }
+
+ /* Get the MAC address */
+ if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1) {
+ pr_info("%s: Couldn't get MAC address!\n", dev->name);
+ return false;
+ }
+
+ nubus_get_rsrc_mem(dev->dev_addr, &ent, 6);
+
+ if (useresources[cardtype] == 1) {
+ nubus_rewinddir(&dir);
+ if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS,
+ &ent) == -1) {
+ pr_err("%s: Memory offset resource for slot %X not found!\n",
+ dev->name, ndev->board->slot);
+ return false;
+ }
+ nubus_get_rsrc_mem(&offset, &ent, 4);
+ dev->mem_start = dev->base_addr + offset;
+ /* yes, this is how the Apple driver does it */
+ dev->base_addr = dev->mem_start + 0x10000;
+ nubus_rewinddir(&dir);
+ if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH,
+ &ent) == -1) {
+ pr_info("%s: Memory length resource for slot %X not found, probing\n",
+ dev->name, ndev->board->slot);
+ offset = mac8390_memsize(dev->mem_start);
+ } else {
+ nubus_get_rsrc_mem(&offset, &ent, 4);
+ }
+ dev->mem_end = dev->mem_start + offset;
+ } else {
+ switch (cardtype) {
+ case MAC8390_KINETICS:
+ case MAC8390_DAYNA: /* it's the same */
+ dev->base_addr = (int)(ndev->board->slot_addr +
+ DAYNA_8390_BASE);
+ dev->mem_start = (int)(ndev->board->slot_addr +
+ DAYNA_8390_MEM);
+ dev->mem_end = dev->mem_start +
+ mac8390_memsize(dev->mem_start);
+ break;
+ case MAC8390_INTERLAN:
+ dev->base_addr = (int)(ndev->board->slot_addr +
+ INTERLAN_8390_BASE);
+ dev->mem_start = (int)(ndev->board->slot_addr +
+ INTERLAN_8390_MEM);
+ dev->mem_end = dev->mem_start +
+ mac8390_memsize(dev->mem_start);
+ break;
+ case MAC8390_CABLETRON:
+ dev->base_addr = (int)(ndev->board->slot_addr +
+ CABLETRON_8390_BASE);
+ dev->mem_start = (int)(ndev->board->slot_addr +
+ CABLETRON_8390_MEM);
+ /* The base address is unreadable if 0x00
+ * has been written to the command register
+ * Reset the chip by writing E8390_NODMA +
+ * E8390_PAGE0 + E8390_STOP just to be
+ * sure
+ */
+ i = (void *)dev->base_addr;
+ *i = 0x21;
+ dev->mem_end = dev->mem_start +
+ mac8390_memsize(dev->mem_start);
+ break;
+
+ default:
+ pr_err("Card type %s is unsupported, sorry\n",
+ ndev->board->name);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+struct net_device * __init mac8390_probe(int unit)
+{
+ struct net_device *dev;
+ struct nubus_dev *ndev = NULL;
+ int err = -ENODEV;
+ struct ei_device *ei_local;
+
+ static unsigned int slots;
+
+ enum mac8390_type cardtype;
+
+ /* probably should check for Nubus instead */
+
+ if (!MACH_IS_MAC)
+ return ERR_PTR(-ENODEV);
+
+ dev = ____alloc_ei_netdev(0);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ if (unit >= 0)
+ sprintf(dev->name, "eth%d", unit);
+
+ while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET,
+ ndev))) {
+ /* Have we seen it already? */
+ if (slots & (1 << ndev->board->slot))
+ continue;
+ slots |= 1 << ndev->board->slot;
+
+ cardtype = mac8390_ident(ndev);
+ if (cardtype == MAC8390_NONE)
+ continue;
+
+ if (!mac8390_init(dev, ndev, cardtype))
+ continue;
+
+ /* Do the nasty 8390 stuff */
+ if (!mac8390_initdev(dev, ndev, cardtype))
+ break;
+ }
+
+ if (!ndev)
+ goto out;
+
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = mac8390_msg_enable;
+
+ err = register_netdev(dev);
+ if (err)
+ goto out;
+ return dev;
+
+out:
+ free_netdev(dev);
+ return ERR_PTR(err);
+}
+
+#ifdef MODULE
+MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others");
+MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver");
+MODULE_LICENSE("GPL");
+
+/* overkill, of course */
+static struct net_device *dev_mac8390[15];
+int init_module(void)
+{
+ int i;
+ for (i = 0; i < 15; i++) {
+ struct net_device *dev = mac8390_probe(-1);
+ if (IS_ERR(dev))
+ break;
+ dev_mac890[i] = dev;
+ }
+ if (!i) {
+ pr_notice("No useable cards found, driver NOT installed.\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ int i;
+ for (i = 0; i < 15; i++) {
+ struct net_device *dev = dev_mac890[i];
+ if (dev) {
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+ }
+}
+
+#endif /* MODULE */
+
+static const struct net_device_ops mac8390_netdev_ops = {
+ .ndo_open = mac8390_open,
+ .ndo_stop = mac8390_close,
+ .ndo_start_xmit = __ei_start_xmit,
+ .ndo_tx_timeout = __ei_tx_timeout,
+ .ndo_get_stats = __ei_get_stats,
+ .ndo_set_rx_mode = __ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = __ei_poll,
+#endif
+};
+
+static int __init mac8390_initdev(struct net_device *dev,
+ struct nubus_dev *ndev,
+ enum mac8390_type type)
+{
+ static u32 fwrd4_offsets[16] = {
+ 0, 4, 8, 12,
+ 16, 20, 24, 28,
+ 32, 36, 40, 44,
+ 48, 52, 56, 60
+ };
+ static u32 back4_offsets[16] = {
+ 60, 56, 52, 48,
+ 44, 40, 36, 32,
+ 28, 24, 20, 16,
+ 12, 8, 4, 0
+ };
+ static u32 fwrd2_offsets[16] = {
+ 0, 2, 4, 6,
+ 8, 10, 12, 14,
+ 16, 18, 20, 22,
+ 24, 26, 28, 30
+ };
+
+ int access_bitmode = 0;
+
+ /* Now fill in our stuff */
+ dev->netdev_ops = &mac8390_netdev_ops;
+
+ /* GAR, ei_status is actually a macro even though it looks global */
+ ei_status.name = cardname[type];
+ ei_status.word16 = word16[type];
+
+ /* Cabletron's TX/RX buffers are backwards */
+ if (type == MAC8390_CABLETRON) {
+ ei_status.tx_start_page = CABLETRON_TX_START_PG;
+ ei_status.rx_start_page = CABLETRON_RX_START_PG;
+ ei_status.stop_page = CABLETRON_RX_STOP_PG;
+ ei_status.rmem_start = dev->mem_start;
+ ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;
+ } else {
+ ei_status.tx_start_page = WD_START_PG;
+ ei_status.rx_start_page = WD_START_PG + TX_PAGES;
+ ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
+ ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
+ ei_status.rmem_end = dev->mem_end;
+ }
+
+ /* Fill in model-specific information and functions */
+ switch (type) {
+ case MAC8390_FARALLON:
+ case MAC8390_APPLE:
+ switch (mac8390_testio(dev->mem_start)) {
+ case ACCESS_UNKNOWN:
+ pr_err("Don't know how to access card memory!\n");
+ return -ENODEV;
+ break;
+
+ case ACCESS_16:
+ /* 16 bit card, register map is reversed */
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
+ ei_status.reg_offset = back4_offsets;
+ break;
+
+ case ACCESS_32:
+ /* 32 bit card, register map is reversed */
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = sane_block_input;
+ ei_status.block_output = sane_block_output;
+ ei_status.get_8390_hdr = sane_get_8390_hdr;
+ ei_status.reg_offset = back4_offsets;
+ access_bitmode = 1;
+ break;
+ }
+ break;
+
+ case MAC8390_ASANTE:
+ /* Some Asante cards pass the 32 bit test
+ * but overwrite system memory when run at 32 bit.
+ * so we run them all at 16 bit.
+ */
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
+ ei_status.reg_offset = back4_offsets;
+ break;
+
+ case MAC8390_CABLETRON:
+ /* 16 bit card, register map is short forward */
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
+ ei_status.reg_offset = fwrd2_offsets;
+ break;
+
+ case MAC8390_DAYNA:
+ case MAC8390_KINETICS:
+ /* 16 bit memory, register map is forward */
+ /* dayna and similar */
+ ei_status.reset_8390 = mac8390_no_reset;
+ ei_status.block_input = dayna_block_input;
+ ei_status.block_output = dayna_block_output;
+ ei_status.get_8390_hdr = dayna_get_8390_hdr;
+ ei_status.reg_offset = fwrd4_offsets;
+ break;
+
+ case MAC8390_INTERLAN:
+ /* 16 bit memory, register map is forward */
+ ei_status.reset_8390 = interlan_reset;
+ ei_status.block_input = slow_sane_block_input;
+ ei_status.block_output = slow_sane_block_output;
+ ei_status.get_8390_hdr = slow_sane_get_8390_hdr;
+ ei_status.reg_offset = fwrd4_offsets;
+ break;
+
+ default:
+ pr_err("Card type %s is unsupported, sorry\n",
+ ndev->board->name);
+ return -ENODEV;
+ }
+
+ __NS8390_init(dev, 0);
+
+ /* Good, done, now spit out some messages */
+ pr_info("%s: %s in slot %X (type %s)\n",
+ dev->name, ndev->board->name, ndev->board->slot,
+ cardname[type]);
+ pr_info("MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
+ dev->dev_addr, dev->irq,
+ (unsigned int)(dev->mem_end - dev->mem_start) >> 10,
+ dev->mem_start, access_bitmode ? 32 : 16);
+ return 0;
+}
+
+static int mac8390_open(struct net_device *dev)
+{
+ int err;
+
+ __ei_open(dev);
+ err = request_irq(dev->irq, __ei_interrupt, 0, "8390 Ethernet", dev);
+ if (err)
+ pr_err("%s: unable to get IRQ %d\n", dev->name, dev->irq);
+ return err;
+}
+
+static int mac8390_close(struct net_device *dev)
+{
+ free_irq(dev->irq, dev);
+ __ei_close(dev);
+ return 0;
+}
+
+static void mac8390_no_reset(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ ei_status.txing = 0;
+ netif_info(ei_local, hw, dev, "reset not supported\n");
+}
+
+static void interlan_reset(struct net_device *dev)
+{
+ unsigned char *target = nubus_slot_addr(IRQ2SLOT(dev->irq));
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ netif_info(ei_local, hw, dev, "Need to reset the NS8390 t=%lu...",
+ jiffies);
+ ei_status.txing = 0;
+ target[0xC0000] = 0;
+ if (netif_msg_hw(ei_local))
+ pr_cont("reset complete\n");
+}
+
+/* dayna_memcpy_fromio/dayna_memcpy_toio */
+/* directly from daynaport.c by Alan Cox */
+static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from,
+ int count)
+{
+ volatile unsigned char *ptr;
+ unsigned char *target = to;
+ from <<= 1; /* word, skip overhead */
+ ptr = (unsigned char *)(dev->mem_start+from);
+ /* Leading byte? */
+ if (from & 2) {
+ *target++ = ptr[-1];
+ ptr += 2;
+ count--;
+ }
+ while (count >= 2) {
+ *(unsigned short *)target = *(unsigned short volatile *)ptr;
+ ptr += 4; /* skip cruft */
+ target += 2;
+ count -= 2;
+ }
+ /* Trailing byte? */
+ if (count)
+ *target = *ptr;
+}
+
+static void dayna_memcpy_tocard(struct net_device *dev, int to,
+ const void *from, int count)
+{
+ volatile unsigned short *ptr;
+ const unsigned char *src = from;
+ to <<= 1; /* word, skip overhead */
+ ptr = (unsigned short *)(dev->mem_start+to);
+ /* Leading byte? */
+ if (to & 2) { /* avoid a byte write (stomps on other data) */
+ ptr[-1] = (ptr[-1]&0xFF00)|*src++;
+ ptr++;
+ count--;
+ }
+ while (count >= 2) {
+ *ptr++ = *(unsigned short *)src; /* Copy and */
+ ptr++; /* skip cruft */
+ src += 2;
+ count -= 2;
+ }
+ /* Trailing byte? */
+ if (count) {
+ /* card doesn't like byte writes */
+ *ptr = (*ptr & 0x00FF) | (*src << 8);
+ }
+}
+
+/* sane block input/output */
+static void sane_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page)
+{
+ unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
+ memcpy_fromio(hdr, dev->mem_start + hdr_start, 4);
+ /* Fix endianness */
+ hdr->count = swab16(hdr->count);
+}
+
+static void sane_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+ unsigned long xfer_start = xfer_base + dev->mem_start;
+
+ if (xfer_start + count > ei_status.rmem_end) {
+ /* We must wrap the input move. */
+ int semi_count = ei_status.rmem_end - xfer_start;
+ memcpy_fromio(skb->data, dev->mem_start + xfer_base,
+ semi_count);
+ count -= semi_count;
+ memcpy_fromio(skb->data + semi_count, ei_status.rmem_start,
+ count);
+ } else {
+ memcpy_fromio(skb->data, dev->mem_start + xfer_base, count);
+ }
+}
+
+static void sane_block_output(struct net_device *dev, int count,
+ const unsigned char *buf, int start_page)
+{
+ long shmem = (start_page - WD_START_PG)<<8;
+
+ memcpy_toio(dev->mem_start + shmem, buf, count);
+}
+
+/* dayna block input/output */
+static void dayna_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page)
+{
+ unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
+
+ dayna_memcpy_fromcard(dev, hdr, hdr_start, 4);
+ /* Fix endianness */
+ hdr->count = (hdr->count & 0xFF) << 8 | (hdr->count >> 8);
+}
+
+static void dayna_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+ unsigned long xfer_start = xfer_base+dev->mem_start;
+
+ /* Note the offset math is done in card memory space which is word
+ per long onto our space. */
+
+ if (xfer_start + count > ei_status.rmem_end) {
+ /* We must wrap the input move. */
+ int semi_count = ei_status.rmem_end - xfer_start;
+ dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);
+ count -= semi_count;
+ dayna_memcpy_fromcard(dev, skb->data + semi_count,
+ ei_status.rmem_start - dev->mem_start,
+ count);
+ } else {
+ dayna_memcpy_fromcard(dev, skb->data, xfer_base, count);
+ }
+}
+
+static void dayna_block_output(struct net_device *dev, int count,
+ const unsigned char *buf,
+ int start_page)
+{
+ long shmem = (start_page - WD_START_PG)<<8;
+
+ dayna_memcpy_tocard(dev, shmem, buf, count);
+}
+
+/* Cabletron block I/O */
+static void slow_sane_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr,
+ int ring_page)
+{
+ unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
+ word_memcpy_fromcard(hdr, dev->mem_start + hdr_start, 4);
+ /* Register endianism - fix here rather than 8390.c */
+ hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8);
+}
+
+static void slow_sane_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+ unsigned long xfer_start = xfer_base+dev->mem_start;
+
+ if (xfer_start + count > ei_status.rmem_end) {
+ /* We must wrap the input move. */
+ int semi_count = ei_status.rmem_end - xfer_start;
+ word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base,
+ semi_count);
+ count -= semi_count;
+ word_memcpy_fromcard(skb->data + semi_count,
+ ei_status.rmem_start, count);
+ } else {
+ word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base,
+ count);
+ }
+}
+
+static void slow_sane_block_output(struct net_device *dev, int count,
+ const unsigned char *buf, int start_page)
+{
+ long shmem = (start_page - WD_START_PG)<<8;
+
+ word_memcpy_tocard(dev->mem_start + shmem, buf, count);
+}
+
+static void word_memcpy_tocard(unsigned long tp, const void *fp, int count)
+{
+ volatile unsigned short *to = (void *)tp;
+ const unsigned short *from = fp;
+
+ count++;
+ count /= 2;
+
+ while (count--)
+ *to++ = *from++;
+}
+
+static void word_memcpy_fromcard(void *tp, unsigned long fp, int count)
+{
+ unsigned short *to = tp;
+ const volatile unsigned short *from = (const void *)fp;
+
+ count++;
+ count /= 2;
+
+ while (count--)
+ *to++ = *from++;
+}
+
+
diff --git a/drivers/net/ethernet/8390/mcf8390.c b/drivers/net/ethernet/8390/mcf8390.c
new file mode 100644
index 00000000000..38fcdcf7c4c
--- /dev/null
+++ b/drivers/net/ethernet/8390/mcf8390.c
@@ -0,0 +1,481 @@
+/*
+ * Support for ColdFire CPU based boards using a NS8390 Ethernet device.
+ *
+ * Derived from the many other 8390 drivers.
+ *
+ * (C) Copyright 2012, Greg Ungerer <gerg@uclinux.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <asm/mcf8390.h>
+
+static const char version[] =
+ "mcf8390.c: (15-06-2012) Greg Ungerer <gerg@uclinux.org>";
+
+#define NE_CMD 0x00
+#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset */
+#define NE_RESET 0x1f /* Issue a read to reset ,a write to clear */
+#define NE_EN0_ISR 0x07
+#define NE_EN0_DCFG 0x0e
+#define NE_EN0_RSARLO 0x08
+#define NE_EN0_RSARHI 0x09
+#define NE_EN0_RCNTLO 0x0a
+#define NE_EN0_RXCR 0x0c
+#define NE_EN0_TXCR 0x0d
+#define NE_EN0_RCNTHI 0x0b
+#define NE_EN0_IMR 0x0f
+
+#define NESM_START_PG 0x40 /* First page of TX buffer */
+#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
+static u32 mcf8390_msg_enable;
+
+#ifdef NE2000_ODDOFFSET
+/*
+ * A lot of the ColdFire boards use a separate address region for odd offset
+ * register addresses. The following functions convert and map as required.
+ * Note that the data port accesses are treated a little differently, and
+ * always accessed via the insX/outsX functions.
+ */
+static inline u32 NE_PTR(u32 addr)
+{
+ if (addr & 1)
+ return addr - 1 + NE2000_ODDOFFSET;
+ return addr;
+}
+
+static inline u32 NE_DATA_PTR(u32 addr)
+{
+ return addr;
+}
+
+void ei_outb(u32 val, u32 addr)
+{
+ NE2000_BYTE *rp;
+
+ rp = (NE2000_BYTE *) NE_PTR(addr);
+ *rp = RSWAP(val);
+}
+
+#define ei_inb ei_inb
+u8 ei_inb(u32 addr)
+{
+ NE2000_BYTE *rp, val;
+
+ rp = (NE2000_BYTE *) NE_PTR(addr);
+ val = *rp;
+ return (u8) (RSWAP(val) & 0xff);
+}
+
+void ei_insb(u32 addr, void *vbuf, int len)
+{
+ NE2000_BYTE *rp, val;
+ u8 *buf;
+
+ buf = (u8 *) vbuf;
+ rp = (NE2000_BYTE *) NE_DATA_PTR(addr);
+ for (; (len > 0); len--) {
+ val = *rp;
+ *buf++ = RSWAP(val);
+ }
+}
+
+void ei_insw(u32 addr, void *vbuf, int len)
+{
+ volatile u16 *rp;
+ u16 w, *buf;
+
+ buf = (u16 *) vbuf;
+ rp = (volatile u16 *) NE_DATA_PTR(addr);
+ for (; (len > 0); len--) {
+ w = *rp;
+ *buf++ = BSWAP(w);
+ }
+}
+
+void ei_outsb(u32 addr, const void *vbuf, int len)
+{
+ NE2000_BYTE *rp, val;
+ u8 *buf;
+
+ buf = (u8 *) vbuf;
+ rp = (NE2000_BYTE *) NE_DATA_PTR(addr);
+ for (; (len > 0); len--) {
+ val = *buf++;
+ *rp = RSWAP(val);
+ }
+}
+
+void ei_outsw(u32 addr, const void *vbuf, int len)
+{
+ volatile u16 *rp;
+ u16 w, *buf;
+
+ buf = (u16 *) vbuf;
+ rp = (volatile u16 *) NE_DATA_PTR(addr);
+ for (; (len > 0); len--) {
+ w = *buf++;
+ *rp = BSWAP(w);
+ }
+}
+
+#else /* !NE2000_ODDOFFSET */
+
+#define ei_inb inb
+#define ei_outb outb
+#define ei_insb insb
+#define ei_insw insw
+#define ei_outsb outsb
+#define ei_outsw outsw
+
+#endif /* !NE2000_ODDOFFSET */
+
+#define ei_inb_p ei_inb
+#define ei_outb_p ei_outb
+
+#include "lib8390.c"
+
+/*
+ * Hard reset the card. This used to pause for the same period that a
+ * 8390 reset command required, but that shouldn't be necessary.
+ */
+static void mcf8390_reset_8390(struct net_device *dev)
+{
+ unsigned long reset_start_time = jiffies;
+ u32 addr = dev->base_addr;
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
+
+ ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
+
+ ei_status.txing = 0;
+ ei_status.dmaing = 0;
+
+ /* This check _should_not_ be necessary, omit eventually. */
+ while ((ei_inb(addr + NE_EN0_ISR) & ENISR_RESET) == 0) {
+ if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
+ netdev_warn(dev, "%s: did not complete\n", __func__);
+ break;
+ }
+ }
+
+ ei_outb(ENISR_RESET, addr + NE_EN0_ISR);
+}
+
+/*
+ * This *shouldn't* happen.
+ * If it does, it's the last thing you'll see
+ */
+static void mcf8390_dmaing_err(const char *func, struct net_device *dev,
+ struct ei_device *ei_local)
+{
+ netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
+ func, ei_local->dmaing, ei_local->irqlock);
+}
+
+/*
+ * Grab the 8390 specific header. Similar to the block_input routine, but
+ * we don't need to be concerned with ring wrap as the header will be at
+ * the start of a page, so we optimize accordingly.
+ */
+static void mcf8390_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ u32 addr = dev->base_addr;
+
+ if (ei_local->dmaing) {
+ mcf8390_dmaing_err(__func__, dev, ei_local);
+ return;
+ }
+
+ ei_local->dmaing |= 0x01;
+ ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, addr + NE_CMD);
+ ei_outb(ENISR_RDC, addr + NE_EN0_ISR);
+ ei_outb(sizeof(struct e8390_pkt_hdr), addr + NE_EN0_RCNTLO);
+ ei_outb(0, addr + NE_EN0_RCNTHI);
+ ei_outb(0, addr + NE_EN0_RSARLO); /* On page boundary */
+ ei_outb(ring_page, addr + NE_EN0_RSARHI);
+ ei_outb(E8390_RREAD + E8390_START, addr + NE_CMD);
+
+ ei_insw(addr + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr) >> 1);
+
+ outb(ENISR_RDC, addr + NE_EN0_ISR); /* Ack intr */
+ ei_local->dmaing &= ~0x01;
+
+ hdr->count = cpu_to_le16(hdr->count);
+}
+
+/*
+ * Block input and output, similar to the Crynwr packet driver.
+ * If you are porting to a new ethercard, look at the packet driver source
+ * for hints. The NEx000 doesn't share the on-board packet memory --
+ * you have to put the packet out through the "remote DMA" dataport
+ * using z_writeb.
+ */
+static void mcf8390_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ u32 addr = dev->base_addr;
+ char *buf = skb->data;
+
+ if (ei_local->dmaing) {
+ mcf8390_dmaing_err(__func__, dev, ei_local);
+ return;
+ }
+
+ ei_local->dmaing |= 0x01;
+ ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, addr + NE_CMD);
+ ei_outb(ENISR_RDC, addr + NE_EN0_ISR);
+ ei_outb(count & 0xff, addr + NE_EN0_RCNTLO);
+ ei_outb(count >> 8, addr + NE_EN0_RCNTHI);
+ ei_outb(ring_offset & 0xff, addr + NE_EN0_RSARLO);
+ ei_outb(ring_offset >> 8, addr + NE_EN0_RSARHI);
+ ei_outb(E8390_RREAD + E8390_START, addr + NE_CMD);
+
+ ei_insw(addr + NE_DATAPORT, buf, count >> 1);
+ if (count & 1)
+ buf[count - 1] = ei_inb(addr + NE_DATAPORT);
+
+ ei_outb(ENISR_RDC, addr + NE_EN0_ISR); /* Ack intr */
+ ei_local->dmaing &= ~0x01;
+}
+
+static void mcf8390_block_output(struct net_device *dev, int count,
+ const unsigned char *buf,
+ const int start_page)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+ u32 addr = dev->base_addr;
+ unsigned long dma_start;
+
+ /* Make sure we transfer all bytes if 16bit IO writes */
+ if (count & 0x1)
+ count++;
+
+ if (ei_local->dmaing) {
+ mcf8390_dmaing_err(__func__, dev, ei_local);
+ return;
+ }
+
+ ei_local->dmaing |= 0x01;
+ /* We should already be in page 0, but to be safe... */
+ ei_outb(E8390_PAGE0 + E8390_START + E8390_NODMA, addr + NE_CMD);
+
+ ei_outb(ENISR_RDC, addr + NE_EN0_ISR);
+
+ /* Now the normal output. */
+ ei_outb(count & 0xff, addr + NE_EN0_RCNTLO);
+ ei_outb(count >> 8, addr + NE_EN0_RCNTHI);
+ ei_outb(0x00, addr + NE_EN0_RSARLO);
+ ei_outb(start_page, addr + NE_EN0_RSARHI);
+ ei_outb(E8390_RWRITE + E8390_START, addr + NE_CMD);
+
+ ei_outsw(addr + NE_DATAPORT, buf, count >> 1);
+
+ dma_start = jiffies;
+ while ((ei_inb(addr + NE_EN0_ISR) & ENISR_RDC) == 0) {
+ if (time_after(jiffies, dma_start + 2 * HZ / 100)) { /* 20ms */
+ netdev_warn(dev, "timeout waiting for Tx RDC\n");
+ mcf8390_reset_8390(dev);
+ __NS8390_init(dev, 1);
+ break;
+ }
+ }
+
+ ei_outb(ENISR_RDC, addr + NE_EN0_ISR); /* Ack intr */
+ ei_local->dmaing &= ~0x01;
+}
+
+static const struct net_device_ops mcf8390_netdev_ops = {
+ .ndo_open = __ei_open,
+ .ndo_stop = __ei_close,
+ .ndo_start_xmit = __ei_start_xmit,
+ .ndo_tx_timeout = __ei_tx_timeout,
+ .ndo_get_stats = __ei_get_stats,
+ .ndo_set_rx_mode = __ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = __ei_poll,
+#endif
+};
+
+static int mcf8390_init(struct net_device *dev)
+{
+ static u32 offsets[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ };
+ struct ei_device *ei_local = netdev_priv(dev);
+ unsigned char SA_prom[32];
+ u32 addr = dev->base_addr;
+ int start_page, stop_page;
+ int i, ret;
+
+ mcf8390_reset_8390(dev);
+
+ /*
+ * Read the 16 bytes of station address PROM.
+ * We must first initialize registers,
+ * similar to NS8390_init(eifdev, 0).
+ * We can't reliably read the SAPROM address without this.
+ * (I learned the hard way!).
+ */
+ {
+ static const struct {
+ u32 value;
+ u32 offset;
+ } program_seq[] = {
+ {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD},
+ /* Select page 0 */
+ {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */
+ {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */
+ {0x00, NE_EN0_RCNTHI},
+ {0x00, NE_EN0_IMR}, /* Mask completion irq */
+ {0xFF, NE_EN0_ISR},
+ {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */
+ {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */
+ {32, NE_EN0_RCNTLO},
+ {0x00, NE_EN0_RCNTHI},
+ {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */
+ {0x00, NE_EN0_RSARHI},
+ {E8390_RREAD + E8390_START, NE_CMD},
+ };
+ for (i = 0; i < ARRAY_SIZE(program_seq); i++) {
+ ei_outb(program_seq[i].value,
+ addr + program_seq[i].offset);
+ }
+ }
+
+ for (i = 0; i < 16; i++) {
+ SA_prom[i] = ei_inb(addr + NE_DATAPORT);
+ ei_inb(addr + NE_DATAPORT);
+ }
+
+ /* We must set the 8390 for word mode. */
+ ei_outb(0x49, addr + NE_EN0_DCFG);
+ start_page = NESM_START_PG;
+ stop_page = NESM_STOP_PG;
+
+ /* Install the Interrupt handler */
+ ret = request_irq(dev->irq, __ei_interrupt, 0, dev->name, dev);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ dev->dev_addr[i] = SA_prom[i];
+
+ netdev_dbg(dev, "Found ethernet address: %pM\n", dev->dev_addr);
+
+ ei_local->name = "mcf8390";
+ ei_local->tx_start_page = start_page;
+ ei_local->stop_page = stop_page;
+ ei_local->word16 = 1;
+ ei_local->rx_start_page = start_page + TX_PAGES;
+ ei_local->reset_8390 = mcf8390_reset_8390;
+ ei_local->block_input = mcf8390_block_input;
+ ei_local->block_output = mcf8390_block_output;
+ ei_local->get_8390_hdr = mcf8390_get_8390_hdr;
+ ei_local->reg_offset = offsets;
+
+ dev->netdev_ops = &mcf8390_netdev_ops;
+ __NS8390_init(dev, 0);
+ ret = register_netdev(dev);
+ if (ret) {
+ free_irq(dev->irq, dev);
+ return ret;
+ }
+
+ netdev_info(dev, "addr=0x%08x irq=%d, Ethernet Address %pM\n",
+ addr, dev->irq, dev->dev_addr);
+ return 0;
+}
+
+static int mcf8390_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct ei_device *ei_local;
+ struct resource *mem, *irq;
+ resource_size_t msize;
+ int ret;
+
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (irq == NULL) {
+ dev_err(&pdev->dev, "no IRQ specified?\n");
+ return -ENXIO;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "no memory address specified?\n");
+ return -ENXIO;
+ }
+ msize = resource_size(mem);
+ if (!request_mem_region(mem->start, msize, pdev->name))
+ return -EBUSY;
+
+ dev = ____alloc_ei_netdev(0);
+ if (dev == NULL) {
+ release_mem_region(mem->start, msize);
+ return -ENOMEM;
+ }
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ platform_set_drvdata(pdev, dev);
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = mcf8390_msg_enable;
+
+ dev->irq = irq->start;
+ dev->base_addr = mem->start;
+
+ ret = mcf8390_init(dev);
+ if (ret) {
+ release_mem_region(mem->start, msize);
+ free_netdev(dev);
+ return ret;
+ }
+ return 0;
+}
+
+static int mcf8390_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct resource *mem;
+
+ unregister_netdev(dev);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (mem)
+ release_mem_region(mem->start, resource_size(mem));
+ free_netdev(dev);
+ return 0;
+}
+
+static struct platform_driver mcf8390_drv = {
+ .driver = {
+ .name = "mcf8390",
+ .owner = THIS_MODULE,
+ },
+ .probe = mcf8390_probe,
+ .remove = mcf8390_remove,
+};
+
+module_platform_driver(mcf8390_drv);
+
+MODULE_DESCRIPTION("MCF8390 ColdFire NS8390 driver");
+MODULE_AUTHOR("Greg Ungerer <gerg@uclinux.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mcf8390");
diff --git a/drivers/net/ne.c b/drivers/net/ethernet/8390/ne.c
index fa3ceca4e15..58eaa8f3494 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -53,7 +53,6 @@ static const char version2[] =
#include <linux/jiffies.h>
#include <linux/platform_device.h>
-#include <asm/system.h>
#include <asm/io.h>
#include "8390.h"
@@ -64,6 +63,28 @@ static const char version2[] =
/* Do we support clones that don't adhere to 14,15 of the SAprom ? */
#define SUPPORT_NE_BAD_CLONES
+/* 0xbad = bad sig or no reset ack */
+#define BAD 0xbad
+
+#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
+static struct platform_device *pdev_ne[MAX_NE_CARDS];
+static int io[MAX_NE_CARDS];
+static int irq[MAX_NE_CARDS];
+static int bad[MAX_NE_CARDS];
+static u32 ne_msg_enable;
+
+#ifdef MODULE
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(bad, int, NULL, 0);
+module_param_named(msg_enable, ne_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
+MODULE_PARM_DESC(io, "I/O base address(es),required");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
+MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
+MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver");
+MODULE_LICENSE("GPL");
+#endif /* MODULE */
/* Do we perform extra sanity checks on stuff ? */
/* #define NE_SANITY_CHECK */
@@ -74,6 +95,10 @@ static const char version2[] =
/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
/* #define PACKETBUF_MEMSIZE 0x40 */
+/* This is set up so that no ISA autoprobe takes place. We can't guarantee
+that the ne2k probe is the last 8390 based probe to take place (as it
+is at boot) and so the probe will get confused by any other 8390 cards.
+ISA device autoprobes on a running machine are not recommended anyway. */
#if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R))
/* Do we need a portlist for the ISA auto-probe ? */
#define NEEDS_PORTLIST
@@ -119,7 +144,7 @@ bad_clone_list[] __initdata = {
{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
#ifdef CONFIG_MACH_TX49XX
- {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
+ {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
#endif
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
{NULL,}
@@ -151,9 +176,6 @@ bad_clone_list[] __initdata = {
static int ne_probe1(struct net_device *dev, unsigned long ioaddr);
static int ne_probe_isapnp(struct net_device *dev);
-static int ne_open(struct net_device *dev);
-static int ne_close(struct net_device *dev);
-
static void ne_reset_8390(struct net_device *dev);
static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
@@ -192,8 +214,13 @@ static int __init do_ne_probe(struct net_device *dev)
#endif
/* First check any supplied i/o locations. User knows best. <cough> */
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return ne_probe1(dev, base_addr);
+ if (base_addr > 0x1ff) { /* Check a single specified location. */
+ int ret = ne_probe1(dev, base_addr);
+ if (ret)
+ netdev_warn(dev, "ne.c: No NE*000 card found at "
+ "i/o = %#lx\n", base_addr);
+ return ret;
+ }
else if (base_addr != 0) /* Don't probe at all. */
return -ENXIO;
@@ -214,28 +241,6 @@ static int __init do_ne_probe(struct net_device *dev)
return -ENODEV;
}
-#ifndef MODULE
-struct net_device * __init ne_probe(int unit)
-{
- struct net_device *dev = alloc_eip_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_ne_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
static int __init ne_probe_isapnp(struct net_device *dev)
{
int i;
@@ -262,11 +267,14 @@ static int __init ne_probe_isapnp(struct net_device *dev)
/* found it */
dev->base_addr = pnp_port_start(idev, 0);
dev->irq = pnp_irq(idev, 0);
- printk(KERN_INFO "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n",
- (char *) isapnp_clone_list[i].driver_data,
- dev->base_addr, dev->irq);
+ netdev_info(dev,
+ "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n",
+ (char *) isapnp_clone_list[i].driver_data,
+ dev->base_addr, dev->irq);
if (ne_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */
- printk(KERN_ERR "ne.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr);
+ netdev_err(dev,
+ "ne.c: Probe of ISAPnP card at %#lx failed.\n",
+ dev->base_addr);
pnp_device_detach(idev);
return -ENXIO;
}
@@ -291,7 +299,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
int neX000, ctron, copam, bad_card;
int reg0, ret;
static unsigned version_printed;
- DECLARE_MAC_BUF(mac);
+ struct ei_device *ei_local = netdev_priv(dev);
if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
return -EBUSY;
@@ -318,10 +326,10 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
}
}
- if (ei_debug && version_printed++ == 0)
- printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
+ if ((ne_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
+ netdev_info(dev, "%s%s", version1, version2);
- printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr);
+ netdev_info(dev, "NE*000 ethercard probe at %#3lx:", ioaddr);
/* A user with a poor card that fails to ack the reset, or that
does not have a valid 0x57,0x57 signature can still use this
@@ -329,7 +337,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
with an otherwise unused dev->mem_end value of "0xBAD" will
cause the driver to skip these parts of the probe. */
- bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad));
+ bad_card = ((dev->base_addr != 0) && (dev->mem_end == BAD));
/* Reset card. Who knows what dain-bramaged state it was left in. */
@@ -342,10 +350,10 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
if (bad_card) {
- printk(" (warning: no reset ack)");
+ pr_cont(" (warning: no reset ack)");
break;
} else {
- printk(" not found (no reset ack).\n");
+ pr_cont(" not found (no reset ack).\n");
ret = -ENODEV;
goto err_out;
}
@@ -453,13 +461,13 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
}
if (bad_clone_list[i].name8 == NULL)
{
- printk(" not found (invalid signature %2.2x %2.2x).\n",
+ pr_cont(" not found (invalid signature %2.2x %2.2x).\n",
SA_prom[14], SA_prom[15]);
ret = -ENXIO;
goto err_out;
}
#else
- printk(" not found.\n");
+ pr_cont(" not found.\n");
ret = -ENXIO;
goto err_out;
#endif
@@ -475,15 +483,15 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
mdelay(10); /* wait 10ms for interrupt to propagate */
outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */
dev->irq = probe_irq_off(cookie);
- if (ei_debug > 2)
- printk(" autoirq is %d\n", dev->irq);
+ if (netif_msg_probe(ei_local))
+ pr_cont(" autoirq is %d", dev->irq);
} else if (dev->irq == 2)
/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
or don't know which one to set. */
dev->irq = 9;
if (! dev->irq) {
- printk(" failed to detect IRQ line.\n");
+ pr_cont(" failed to detect IRQ line.\n");
ret = -EAGAIN;
goto err_out;
}
@@ -492,7 +500,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
share and the board will usually be enabled. */
ret = request_irq(dev->irq, eip_interrupt, 0, name, dev);
if (ret) {
- printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
+ pr_cont(" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
goto err_out;
}
@@ -501,17 +509,17 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
#ifdef CONFIG_PLAT_MAPPI
outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
ioaddr + E8390_CMD); /* 0x61 */
- for (i = 0 ; i < ETHER_ADDR_LEN ; i++) {
+ for (i = 0; i < ETH_ALEN; i++) {
dev->dev_addr[i] = SA_prom[i]
= inb_p(ioaddr + EN1_PHYS_SHIFT(i));
}
#else
- for(i = 0; i < ETHER_ADDR_LEN; i++) {
+ for (i = 0; i < ETH_ALEN; i++) {
dev->dev_addr[i] = SA_prom[i];
}
#endif
- printk("%s\n", print_mac(mac, dev->dev_addr));
+ pr_cont("%pM\n", dev->dev_addr);
ei_status.name = name;
ei_status.tx_start_page = start_page;
@@ -531,18 +539,16 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
ei_status.block_output = &ne_block_output;
ei_status.get_8390_hdr = &ne_get_8390_hdr;
ei_status.priv = 0;
- dev->open = &ne_open;
- dev->stop = &ne_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = eip_poll;
-#endif
+
+ dev->netdev_ops = &eip_netdev_ops;
NS8390p_init(dev, 0);
+ ei_local->msg_enable = ne_msg_enable;
ret = register_netdev(dev);
if (ret)
goto out_irq;
- printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n",
- dev->name, name, ioaddr, dev->irq);
+ netdev_info(dev, "%s found at %#lx, using IRQ %d.\n",
+ name, ioaddr, dev->irq);
return 0;
out_irq:
@@ -552,29 +558,15 @@ err_out:
return ret;
}
-static int ne_open(struct net_device *dev)
-{
- eip_open(dev);
- return 0;
-}
-
-static int ne_close(struct net_device *dev)
-{
- if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
- eip_close(dev);
- return 0;
-}
-
/* Hard reset the card. This used to pause for the same period that a
8390 reset command required, but that shouldn't be necessary. */
static void ne_reset_8390(struct net_device *dev)
{
unsigned long reset_start_time = jiffies;
+ struct ei_device *ei_local = netdev_priv(dev);
- if (ei_debug > 1)
- printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
+ netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n", jiffies);
/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
@@ -585,7 +577,7 @@ static void ne_reset_8390(struct net_device *dev)
/* This check _should_not_ be necessary, omit eventually. */
while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
- printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name);
+ netdev_err(dev, "ne_reset_8390() did not complete.\n");
break;
}
outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */
@@ -603,9 +595,9 @@ static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, i
if (ei_status.dmaing)
{
- printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr "
- "[DMAstat:%d][irqlock:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ netdev_err(dev, "DMAing conflict in ne_get_8390_hdr "
+ "[DMAstat:%d][irqlock:%d].\n",
+ ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -637,6 +629,7 @@ static void ne_block_input(struct net_device *dev, int count, struct sk_buff *sk
{
#ifdef NE_SANITY_CHECK
int xfer_count = count;
+ struct ei_device *ei_local = netdev_priv(dev);
#endif
int nic_base = dev->base_addr;
char *buf = skb->data;
@@ -644,9 +637,9 @@ static void ne_block_input(struct net_device *dev, int count, struct sk_buff *sk
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing)
{
- printk(KERN_EMERG "%s: DMAing conflict in ne_block_input "
- "[DMAstat:%d][irqlock:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ netdev_err(dev, "DMAing conflict in ne_block_input "
+ "[DMAstat:%d][irqlock:%d].\n",
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -676,7 +669,7 @@ static void ne_block_input(struct net_device *dev, int count, struct sk_buff *sk
this message you either 1) have a slightly incompatible clone
or 2) have noise/speed problems with your bus. */
- if (ei_debug > 1)
+ if (netif_msg_rx_status(ei_local))
{
/* DMA termination address check... */
int addr, tries = 20;
@@ -690,9 +683,9 @@ static void ne_block_input(struct net_device *dev, int count, struct sk_buff *sk
break;
} while (--tries > 0);
if (tries <= 0)
- printk(KERN_WARNING "%s: RX transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
+ netdev_warn(dev, "RX transfer address mismatch,"
+ "%#4.4x (expected) vs. %#4.4x (actual).\n",
+ ring_offset + xfer_count, addr);
}
#endif
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
@@ -706,6 +699,7 @@ static void ne_block_output(struct net_device *dev, int count,
unsigned long dma_start;
#ifdef NE_SANITY_CHECK
int retries = 0;
+ struct ei_device *ei_local = netdev_priv(dev);
#endif
/* Round the count up for word writes. Do we need to do this?
@@ -718,9 +712,9 @@ static void ne_block_output(struct net_device *dev, int count,
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing)
{
- printk(KERN_EMERG "%s: DMAing conflict in ne_block_output."
- "[DMAstat:%d][irqlock:%d]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ netdev_err(dev, "DMAing conflict in ne_block_output."
+ "[DMAstat:%d][irqlock:%d]\n",
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -767,7 +761,7 @@ retry:
/* This was for the ALPHA version only, but enough people have
been encountering problems so it is still here. */
- if (ei_debug > 1)
+ if (netif_msg_tx_queued(ei_local))
{
/* DMA termination address check... */
int addr, tries = 20;
@@ -781,9 +775,9 @@ retry:
if (tries <= 0)
{
- printk(KERN_WARNING "%s: Tx packet transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, (start_page << 8) + count, addr);
+ netdev_warn(dev, "Tx packet transfer address mismatch,"
+ "%#4.4x (expected) vs. %#4.4x (actual).\n",
+ (start_page << 8) + count, addr);
if (retries++ == 0)
goto retry;
}
@@ -792,7 +786,7 @@ retry:
while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */
- printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
+ netdev_warn(dev, "timeout waiting for Tx RDC.\n");
ne_reset_8390(dev);
NS8390p_init(dev, 1);
break;
@@ -800,52 +794,102 @@ retry:
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01;
- return;
}
static int __init ne_drv_probe(struct platform_device *pdev)
{
struct net_device *dev;
+ int err, this_dev = pdev->id;
struct resource *res;
- int err, irq;
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- irq = platform_get_irq(pdev, 0);
- if (!res || irq < 0)
- return -ENODEV;
dev = alloc_eip_netdev();
if (!dev)
return -ENOMEM;
- dev->irq = irq;
- dev->base_addr = res->start;
+
+ /* ne.c doesn't populate resources in platform_device, but
+ * rbtx4927_ne_init and rbtx4938_ne_init do register devices
+ * with resources.
+ */
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (res) {
+ dev->base_addr = res->start;
+ dev->irq = platform_get_irq(pdev, 0);
+ } else {
+ if (this_dev < 0 || this_dev >= MAX_NE_CARDS) {
+ free_netdev(dev);
+ return -EINVAL;
+ }
+ dev->base_addr = io[this_dev];
+ dev->irq = irq[this_dev];
+ dev->mem_end = bad[this_dev];
+ }
+ SET_NETDEV_DEV(dev, &pdev->dev);
err = do_ne_probe(dev);
if (err) {
free_netdev(dev);
return err;
}
platform_set_drvdata(pdev, dev);
+
+ /* Update with any values found by probing, don't update if
+ * resources were specified.
+ */
+ if (!res) {
+ io[this_dev] = dev->base_addr;
+ irq[this_dev] = dev->irq;
+ }
return 0;
}
-static int __exit ne_drv_remove(struct platform_device *pdev)
+static int ne_drv_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
- unregister_netdev(dev);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, NE_IO_EXTENT);
- free_netdev(dev);
+ if (dev) {
+ struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+ netif_device_detach(dev);
+ unregister_netdev(dev);
+ if (idev)
+ pnp_device_detach(idev);
+ /* Careful ne_drv_remove can be called twice, once from
+ * the platform_driver.remove and again when the
+ * platform_device is being removed.
+ */
+ ei_status.priv = 0;
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, NE_IO_EXTENT);
+ free_netdev(dev);
+ }
return 0;
}
+/* Remove unused devices or all if true. */
+static void ne_loop_rm_unreg(int all)
+{
+ int this_dev;
+ struct platform_device *pdev;
+ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+ pdev = pdev_ne[this_dev];
+ /* No network device == unused */
+ if (pdev && (!platform_get_drvdata(pdev) || all)) {
+ ne_drv_remove(pdev);
+ platform_device_unregister(pdev);
+ pdev_ne[this_dev] = NULL;
+ }
+ }
+}
+
#ifdef CONFIG_PM
static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
struct net_device *dev = platform_get_drvdata(pdev);
- if (netif_running(dev))
+ if (netif_running(dev)) {
+ struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
netif_device_detach(dev);
+ if (idev)
+ pnp_stop_dev(idev);
+ }
return 0;
}
@@ -854,6 +898,9 @@ static int ne_drv_resume(struct platform_device *pdev)
struct net_device *dev = platform_get_drvdata(pdev);
if (netif_running(dev)) {
+ struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+ if (idev)
+ pnp_start_dev(idev);
ne_reset_8390(dev);
NS8390p_init(dev, 1);
netif_device_attach(dev);
@@ -866,7 +913,7 @@ static int ne_drv_resume(struct platform_device *pdev)
#endif
static struct platform_driver ne_driver = {
- .remove = __exit_p(ne_drv_remove),
+ .remove = ne_drv_remove,
.suspend = ne_drv_suspend,
.resume = ne_drv_resume,
.driver = {
@@ -875,91 +922,96 @@ static struct platform_driver ne_driver = {
},
};
-static int __init ne_init(void)
+static void __init ne_add_devices(void)
{
- return platform_driver_probe(&ne_driver, ne_drv_probe);
-}
+ int this_dev;
+ struct platform_device *pdev;
-static void __exit ne_exit(void)
-{
- platform_driver_unregister(&ne_driver);
+ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+ if (pdev_ne[this_dev])
+ continue;
+ pdev = platform_device_register_simple(
+ DRV_NAME, this_dev, NULL, 0);
+ if (IS_ERR(pdev))
+ continue;
+ pdev_ne[this_dev] = pdev;
+ }
}
#ifdef MODULE
-#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
-static struct net_device *dev_ne[MAX_NE_CARDS];
-static int io[MAX_NE_CARDS];
-static int irq[MAX_NE_CARDS];
-static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(bad, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es),required");
-MODULE_PARM_DESC(irq, "IRQ number(s)");
-MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
-MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that no ISA autoprobe takes place. We can't guarantee
-that the ne2k probe is the last 8390 based probe to take place (as it
-is at boot) and so the probe will get confused by any other 8390 cards.
-ISA device autoprobes on a running machine are not recommended anyway. */
-
int __init init_module(void)
{
- int this_dev, found = 0;
- int plat_found = !ne_init();
-
- for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- struct net_device *dev = alloc_eip_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->mem_end = bad[this_dev];
- dev->base_addr = io[this_dev];
- if (do_ne_probe(dev) == 0) {
- dev_ne[found++] = dev;
- continue;
- }
- free_netdev(dev);
- if (found || plat_found)
- break;
- if (io[this_dev] != 0)
- printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
- else
- printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
- return -ENXIO;
+ int retval;
+ ne_add_devices();
+ retval = platform_driver_probe(&ne_driver, ne_drv_probe);
+ if (retval) {
+ if (io[0] == 0)
+ pr_notice("ne.c: You must supply \"io=0xNNN\""
+ " value(s) for ISA cards.\n");
+ ne_loop_rm_unreg(1);
+ return retval;
}
- if (found || plat_found)
- return 0;
- return -ENODEV;
-}
-static void cleanup_card(struct net_device *dev)
+ /* Unregister unused platform_devices. */
+ ne_loop_rm_unreg(0);
+ return retval;
+}
+#else /* MODULE */
+static int __init ne_init(void)
{
- struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
- if (idev)
- pnp_device_detach(idev);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, NE_IO_EXTENT);
+ int retval = platform_driver_probe(&ne_driver, ne_drv_probe);
+
+ /* Unregister unused platform_devices. */
+ ne_loop_rm_unreg(0);
+ return retval;
}
+module_init(ne_init);
-void __exit cleanup_module(void)
+struct net_device * __init ne_probe(int unit)
{
int this_dev;
+ struct net_device *dev;
+
+ /* Find an empty slot, that is no net_device and zero io port. */
+ this_dev = 0;
+ while ((pdev_ne[this_dev] && platform_get_drvdata(pdev_ne[this_dev])) ||
+ io[this_dev]) {
+ if (++this_dev == MAX_NE_CARDS)
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Get irq, io from kernel command line */
+ dev = alloc_eip_netdev();
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
- ne_exit();
+ sprintf(dev->name, "eth%d", unit);
+ netdev_boot_setup_check(dev);
+
+ io[this_dev] = dev->base_addr;
+ irq[this_dev] = dev->irq;
+ bad[this_dev] = dev->mem_end;
+
+ free_netdev(dev);
+
+ ne_add_devices();
+
+ /* return the first device found */
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- struct net_device *dev = dev_ne[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
+ if (pdev_ne[this_dev]) {
+ dev = platform_get_drvdata(pdev_ne[this_dev]);
+ if (dev)
+ return dev;
}
}
+
+ return ERR_PTR(-ENODEV);
}
-#else /* MODULE */
-module_init(ne_init);
-module_exit(ne_exit);
#endif /* MODULE */
+
+static void __exit ne_exit(void)
+{
+ platform_driver_unregister(&ne_driver);
+ ne_loop_rm_unreg(1);
+}
+module_exit(ne_exit);
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c
index de0de744a8f..f395c967262 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ethernet/8390/ne2k-pci.c
@@ -33,8 +33,6 @@
/* The user-configurable values.
These may be modified when a driver module is loaded.*/
-static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
-
#define MAX_UNITS 8 /* More are supported, limit only on options */
/* Used to pass the full-duplex flag, etc. */
static int full_duplex[MAX_UNITS];
@@ -54,16 +52,18 @@ static int options[MAX_UNITS];
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include "8390.h"
+static u32 ne2k_msg_enable;
+
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " D. Becker/P. Gortmaker\n";
+static const char version[] =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+ " D. Becker/P. Gortmaker\n";
#if defined(__powerpc__)
#define inl_le(addr) le32_to_cpu(inl(addr))
@@ -76,10 +76,10 @@ MODULE_AUTHOR("Donald Becker / Paul Gortmaker");
MODULE_DESCRIPTION("PCI NE2000 clone driver");
MODULE_LICENSE("GPL");
-module_param(debug, int, 0);
+module_param_named(msg_enable, ne2k_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
module_param_array(options, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
-MODULE_PARM_DESC(debug, "debug level (1-2)");
+MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
MODULE_PARM_DESC(options, "Bit 5: full duplex");
MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
@@ -119,7 +119,7 @@ enum ne2k_pci_chipsets {
static struct {
char *name;
int flags;
-} pci_clone_list[] __devinitdata = {
+} pci_clone_list[] = {
{"RealTek RTL-8029", REALTEK_FDX},
{"Winbond 89C940", 0},
{"Compex RL2000", 0},
@@ -135,7 +135,7 @@ static struct {
};
-static struct pci_device_id ne2k_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(ne2k_pci_tbl) = {
{ 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 },
{ 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 },
{ 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 },
@@ -200,9 +200,23 @@ struct ne2k_pci_card {
in the 'dev' and 'ei_status' structures.
*/
+static const struct net_device_ops ne2k_netdev_ops = {
+ .ndo_open = ne2k_pci_open,
+ .ndo_stop = ne2k_pci_close,
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_set_rx_mode = ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
-static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int ne2k_pci_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct net_device *dev;
int i;
@@ -212,7 +226,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
static unsigned int fnd_cnt;
long ioaddr;
int flags = pci_clone_list[chip_idx].flags;
- DECLARE_MAC_BUF(mac);
+ struct ei_device *ei_local;
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
@@ -266,6 +280,10 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
dev_err(&pdev->dev, "cannot allocate ethernet device\n");
goto err_out_free_res;
}
+ dev->netdev_ops = &ne2k_netdev_ops;
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = ne2k_msg_enable;
+
SET_NETDEV_DEV(dev, &pdev->dev);
/* Reset card. Who knows what dain-bramaged state it was left in. */
@@ -354,25 +372,19 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
ei_status.block_output = &ne2k_pci_block_output;
ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr;
ei_status.priv = (unsigned long) pdev;
- dev->open = &ne2k_pci_open;
- dev->stop = &ne2k_pci_close;
+
dev->ethtool_ops = &ne2k_pci_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
NS8390_init(dev, 0);
+ memcpy(dev->dev_addr, SA_prom, dev->addr_len);
+
i = register_netdev(dev);
if (i)
goto err_out_free_netdev;
- for(i = 0; i < 6; i++)
- dev->dev_addr[i] = SA_prom[i];
- printk("%s: %s found at %#lx, IRQ %d, %s.\n",
- dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq,
- print_mac(mac, dev->dev_addr));
-
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ netdev_info(dev, "%s found at %#lx, IRQ %d, %pM.\n",
+ pci_clone_list[chip_idx].name, ioaddr, dev->irq,
+ dev->dev_addr);
return 0;
@@ -380,9 +392,7 @@ err_out_free_netdev:
free_netdev (dev);
err_out_free_res:
release_region (ioaddr, NE_IO_EXTENT);
- pci_set_drvdata (pdev, NULL);
return -ENODEV;
-
}
/*
@@ -443,9 +453,10 @@ static int ne2k_pci_close(struct net_device *dev)
static void ne2k_pci_reset_8390(struct net_device *dev)
{
unsigned long reset_start_time = jiffies;
+ struct ei_device *ei_local = netdev_priv(dev);
- if (debug > 1) printk("%s: Resetting the 8390 t=%ld...",
- dev->name, jiffies);
+ netif_dbg(ei_local, hw, dev, "resetting the 8390 t=%ld...\n",
+ jiffies);
outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
@@ -455,7 +466,7 @@ static void ne2k_pci_reset_8390(struct net_device *dev)
/* This check _should_not_ be necessary, omit eventually. */
while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
if (jiffies - reset_start_time > 2) {
- printk("%s: ne2k_pci_reset_8390() did not complete.\n", dev->name);
+ netdev_err(dev, "ne2k_pci_reset_8390() did not complete.\n");
break;
}
outb(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */
@@ -472,9 +483,9 @@ static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne2k_pci_get_8390_hdr "
+ netdev_err(dev, "DMAing conflict in ne2k_pci_get_8390_hdr "
"[DMAstat:%d][irqlock:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -510,9 +521,9 @@ static void ne2k_pci_block_input(struct net_device *dev, int count,
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne2k_pci_block_input "
+ netdev_err(dev, "DMAing conflict in ne2k_pci_block_input "
"[DMAstat:%d][irqlock:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -565,9 +576,9 @@ static void ne2k_pci_block_output(struct net_device *dev, int count,
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne2k_pci_block_output."
+ netdev_err(dev, "DMAing conflict in ne2k_pci_block_output."
"[DMAstat:%d][irqlock:%d]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -612,7 +623,7 @@ static void ne2k_pci_block_output(struct net_device *dev, int count,
while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0)
if (jiffies - dma_start > 2) { /* Avoid clock roll-over. */
- printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
+ netdev_warn(dev, "timeout waiting for Tx RDC.\n");
ne2k_pci_reset_8390(dev);
NS8390_init(dev,1);
break;
@@ -620,25 +631,40 @@ static void ne2k_pci_block_output(struct net_device *dev, int count,
outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01;
- return;
}
static void ne2k_pci_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- struct ei_device *ei = dev->priv;
+ struct ei_device *ei = netdev_priv(dev);
struct pci_dev *pci_dev = (struct pci_dev *) ei->priv;
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- strcpy(info->bus_info, pci_name(pci_dev));
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info));
+}
+
+static u32 ne2k_pci_get_msglevel(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ return ei_local->msg_enable;
+}
+
+static void ne2k_pci_set_msglevel(struct net_device *dev, u32 v)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ ei_local->msg_enable = v;
}
static const struct ethtool_ops ne2k_pci_ethtool_ops = {
.get_drvinfo = ne2k_pci_get_drvinfo,
+ .get_msglevel = ne2k_pci_get_msglevel,
+ .set_msglevel = ne2k_pci_set_msglevel,
};
-static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
+static void ne2k_pci_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -647,7 +673,6 @@ static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
release_region(dev->base_addr, NE_IO_EXTENT);
free_netdev(dev);
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
}
#ifdef CONFIG_PM
@@ -668,7 +693,7 @@ static int ne2k_pci_resume (struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata (pdev);
int rc;
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
rc = pci_enable_device(pdev);
@@ -687,7 +712,7 @@ static int ne2k_pci_resume (struct pci_dev *pdev)
static struct pci_driver ne2k_driver = {
.name = DRV_NAME,
.probe = ne2k_pci_init_one,
- .remove = __devexit_p(ne2k_pci_remove_one),
+ .remove = ne2k_pci_remove_one,
.id_table = ne2k_pci_tbl,
#ifdef CONFIG_PM
.suspend = ne2k_pci_suspend,
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c
index ebc1ae6bcbe..ca3c2b921cf 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/ethernet/8390/pcnet_cs.c
@@ -28,28 +28,26 @@
======================================================================*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/ptrace.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
-#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/log2.h>
-#include "../8390.h"
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include "8390.h"
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
#include <asm/io.h>
-#include <asm/system.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
@@ -68,16 +66,7 @@
#define PCNET_RDC_TIMEOUT (2*HZ/100) /* Max wait in jiffies for Tx RDC */
static const char *if_names[] = { "auto", "10baseT", "10base2"};
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
+static u32 pcnet_msg_enable;
/*====================================================================*/
@@ -109,7 +98,6 @@ static void pcnet_release(struct pcmcia_device *link);
static int pcnet_open(struct net_device *dev);
static int pcnet_close(struct net_device *dev);
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
static void pcnet_reset_8390(struct net_device *dev);
@@ -121,8 +109,6 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg,
static void pcnet_detach(struct pcmcia_device *p_dev);
-static dev_info_t dev_info = "pcnet_cs";
-
/*====================================================================*/
typedef struct hw_info_t {
@@ -216,7 +202,6 @@ static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII };
typedef struct pcnet_dev_t {
struct pcmcia_device *p_dev;
- dev_node_t node;
u_int flags;
void __iomem *base;
struct timer_list watchdog;
@@ -233,20 +218,29 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)
return (pcnet_dev_t *)(p + sizeof(struct ei_device));
}
-/*======================================================================
-
- pcnet_attach() creates an "instance" of the driver, allocating
- local data structures for one device. The device is registered
- with Card Services.
-
-======================================================================*/
+static const struct net_device_ops pcnet_netdev_ops = {
+ .ndo_open = pcnet_open,
+ .ndo_stop = pcnet_close,
+ .ndo_set_config = set_config,
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_do_ioctl = ei_ioctl,
+ .ndo_set_rx_mode = ei_set_multicast_list,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
static int pcnet_probe(struct pcmcia_device *link)
{
pcnet_dev_t *info;
struct net_device *dev;
- DEBUG(0, "pcnet_attach()\n");
+ dev_dbg(&link->dev, "pcnet_attach()\n");
/* Create new ethernet device */
dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
@@ -255,35 +249,20 @@ static int pcnet_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = dev;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.IntType = INT_MEMORY_AND_IO;
+ link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
- dev->open = &pcnet_open;
- dev->stop = &pcnet_close;
- dev->set_config = &set_config;
+ dev->netdev_ops = &pcnet_netdev_ops;
return pcnet_config(link);
} /* pcnet_attach */
-/*======================================================================
-
- This deletes a driver "instance". The device is de-registered
- with Card Services. If it has been released, all local data
- structures are freed. Otherwise, the structures will be freed
- when the device is released.
-
-======================================================================*/
-
static void pcnet_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "pcnet_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "pcnet_detach\n");
- if (link->dev_node)
- unregister_netdev(dev);
+ unregister_netdev(dev);
pcnet_release(link);
@@ -300,41 +279,33 @@ static void pcnet_detach(struct pcmcia_device *link)
static hw_info_t *get_hwinfo(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- win_req_t req;
- memreq_t mem;
u_char __iomem *base, *virt;
int i, j;
/* Allocate a small memory window */
- req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
- req.Base = 0; req.Size = 0;
- req.AccessSpeed = 0;
- i = pcmcia_request_window(&link, &req, &link->win);
- if (i != CS_SUCCESS) {
- cs_error(link, RequestWindow, i);
+ link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
+ link->resource[2]->start = 0; link->resource[2]->end = 0;
+ i = pcmcia_request_window(link, link->resource[2], 0);
+ if (i != 0)
return NULL;
- }
- virt = ioremap(req.Base, req.Size);
- mem.Page = 0;
+ virt = ioremap(link->resource[2]->start,
+ resource_size(link->resource[2]));
for (i = 0; i < NR_INFO; i++) {
- mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
- pcmcia_map_mem_page(link->win, &mem);
- base = &virt[hw_info[i].offset & (req.Size-1)];
+ pcmcia_map_mem_page(link, link->resource[2],
+ hw_info[i].offset & ~(resource_size(link->resource[2])-1));
+ base = &virt[hw_info[i].offset & (resource_size(link->resource[2])-1)];
if ((readb(base+0) == hw_info[i].a0) &&
(readb(base+2) == hw_info[i].a1) &&
- (readb(base+4) == hw_info[i].a2))
- break;
- }
- if (i < NR_INFO) {
- for (j = 0; j < 6; j++)
- dev->dev_addr[j] = readb(base + (j<<1));
+ (readb(base+4) == hw_info[i].a2)) {
+ for (j = 0; j < 6; j++)
+ dev->dev_addr[j] = readb(base + (j<<1));
+ break;
+ }
}
iounmap(virt);
- j = pcmcia_release_window(link->win);
- if (j != CS_SUCCESS)
- cs_error(link, ReleaseWindow, j);
+ j = pcmcia_release_window(link, link->resource[2]);
return (i < NR_INFO) ? hw_info+i : NULL;
} /* get_hwinfo */
@@ -353,7 +324,7 @@ static hw_info_t *get_prom(struct pcmcia_device *link)
u_char prom[32];
int i, j;
- /* This is lifted straight from drivers/net/ne.c */
+ /* This is lifted straight from drivers/net/ethernet/8390/ne.c */
struct {
u_char value, offset;
} program_seq[] = {
@@ -429,7 +400,7 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link)
int i, j;
/* Not much of a test, but the alternatives are messy */
- if (link->conf.ConfigBase != 0x03c0)
+ if (link->config_base != 0x03c0)
return NULL;
outb_p(0x01, ioaddr + EN0_DCFG); /* Set word-wide access. */
@@ -442,8 +413,6 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link)
dev->dev_addr[i] = j & 0xff;
dev->dev_addr[i+1] = j >> 8;
}
- printk(KERN_NOTICE "pcnet_cs: this is an AX88190 card!\n");
- printk(KERN_NOTICE "pcnet_cs: use axnet_cs instead.\n");
return NULL;
}
@@ -471,146 +440,137 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
return &default_info;
} /* get_hwired */
-/*======================================================================
-
- pcnet_config() is scheduled to run after a CARD_INSERTION event
- is received, to configure the PCMCIA socket, and to make the
- ethernet device available to the system.
-
-======================================================================*/
-
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int try_io_port(struct pcmcia_device *link)
{
int j, ret;
- if (link->io.NumPorts1 == 32) {
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (link->io.NumPorts2 > 0) {
+ link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+ if (link->resource[0]->end == 32) {
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+ if (link->resource[1]->end > 0) {
/* for master/slave multifunction cards */
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->irq.Attributes =
- IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
}
} else {
/* This should be two 16-port windows */
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
}
- if (link->io.BasePort1 == 0) {
- link->io.IOAddrLines = 16;
+ if (link->resource[0]->start == 0) {
for (j = 0; j < 0x400; j += 0x20) {
- link->io.BasePort1 = j ^ 0x300;
- link->io.BasePort2 = (j ^ 0x300) + 0x10;
- ret = pcmcia_request_io(link, &link->io);
- if (ret == CS_SUCCESS) return ret;
+ link->resource[0]->start = j ^ 0x300;
+ link->resource[1]->start = (j ^ 0x300) + 0x10;
+ link->io_lines = 16;
+ ret = pcmcia_request_io(link);
+ if (ret == 0)
+ return ret;
}
return ret;
} else {
- return pcmcia_request_io(link, &link->io);
+ return pcmcia_request_io(link);
}
}
-static int pcnet_config(struct pcmcia_device *link)
+static int pcnet_confcheck(struct pcmcia_device *p_dev, void *priv_data)
{
- struct net_device *dev = link->priv;
- pcnet_dev_t *info = PRIV(dev);
- tuple_t tuple;
- cisparse_t parse;
- int i, last_ret, last_fn, start_pg, stop_pg, cm_offset;
- int has_shmem = 0;
- u_short buf[64];
- hw_info_t *local_hw_info;
- DECLARE_MAC_BUF(mac);
-
- DEBUG(0, "pcnet_config(0x%p)\n", link);
-
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- while (last_ret == CS_SUCCESS) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
- cistpl_io_t *io = &(parse.cftable_entry.io);
-
- if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
- pcmcia_parse_tuple(link, &tuple, &parse) != 0 ||
- cfg->index == 0 || cfg->io.nwin == 0)
- goto next_entry;
-
- link->conf.ConfigIndex = cfg->index;
- /* For multifunction cards, by convention, we configure the
- network function with window 0, and serial with window 1 */
- if (io->nwin > 1) {
- i = (io->win[1].len > io->win[0].len);
- link->io.BasePort2 = io->win[1-i].base;
- link->io.NumPorts2 = io->win[1-i].len;
- } else {
- i = link->io.NumPorts2 = 0;
- }
- has_shmem = ((cfg->mem.nwin == 1) &&
- (cfg->mem.win[0].len >= 0x4000));
- link->io.BasePort1 = io->win[i].base;
- link->io.NumPorts1 = io->win[i].len;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) {
- last_ret = try_io_port(link);
- if (last_ret == CS_SUCCESS) break;
+ int *priv = priv_data;
+ int try = (*priv & 0x1);
+
+ *priv &= (p_dev->resource[2]->end >= 0x4000) ? 0x10 : ~0x10;
+
+ if (p_dev->config_index == 0)
+ return -EINVAL;
+
+ if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32)
+ return -EINVAL;
+
+ if (try)
+ p_dev->io_lines = 16;
+ return try_io_port(p_dev);
+}
+
+static hw_info_t *pcnet_try_config(struct pcmcia_device *link,
+ int *has_shmem, int try)
+{
+ struct net_device *dev = link->priv;
+ hw_info_t *local_hw_info;
+ pcnet_dev_t *info = PRIV(dev);
+ int priv = try;
+ int ret;
+
+ ret = pcmcia_loop_config(link, pcnet_confcheck, &priv);
+ if (ret) {
+ dev_warn(&link->dev, "no useable port range found\n");
+ return NULL;
}
- next_entry:
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- }
- if (last_ret != CS_SUCCESS) {
- cs_error(link, RequestIO, last_ret);
- goto failed;
- }
+ *has_shmem = (priv & 0x10);
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ if (!link->irq)
+ return NULL;
- if (link->io.NumPorts2 == 8) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
- if ((link->manf_id == MANFID_IBM) &&
- (link->card_id == PRODID_IBM_HOME_AND_AWAY))
- link->conf.ConfigIndex |= 0x10;
+ if (resource_size(link->resource[1]) == 8)
+ link->config_flags |= CONF_ENABLE_SPKR;
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
- dev->irq = link->irq.AssignedIRQ;
- dev->base_addr = link->io.BasePort1;
- if (info->flags & HAS_MISC_REG) {
- if ((if_port == 1) || (if_port == 2))
- dev->if_port = if_port;
- else
- printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n");
- } else {
- dev->if_port = 0;
- }
+ if ((link->manf_id == MANFID_IBM) &&
+ (link->card_id == PRODID_IBM_HOME_AND_AWAY))
+ link->config_index |= 0x10;
- if ((link->conf.ConfigBase == 0x03c0)
- && (link->manf_id == 0x149) && (link->card_id = 0xc1ab)) {
- printk(KERN_INFO "pcnet_cs: this is an AX88190 card!\n");
- printk(KERN_INFO "pcnet_cs: use axnet_cs instead.\n");
- goto failed;
- }
+ ret = pcmcia_enable_device(link);
+ if (ret)
+ return NULL;
- local_hw_info = get_hwinfo(link);
- if (local_hw_info == NULL)
- local_hw_info = get_prom(link);
- if (local_hw_info == NULL)
- local_hw_info = get_dl10019(link);
- if (local_hw_info == NULL)
- local_hw_info = get_ax88190(link);
- if (local_hw_info == NULL)
- local_hw_info = get_hwired(link);
-
- if (local_hw_info == NULL) {
- printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
- " address for io base %#3lx\n", dev->base_addr);
- goto failed;
+ dev->irq = link->irq;
+ dev->base_addr = link->resource[0]->start;
+
+ if (info->flags & HAS_MISC_REG) {
+ if ((if_port == 1) || (if_port == 2))
+ dev->if_port = if_port;
+ else
+ dev_notice(&link->dev, "invalid if_port requested\n");
+ } else
+ dev->if_port = 0;
+
+ if ((link->config_base == 0x03c0) &&
+ (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) {
+ dev_info(&link->dev,
+ "this is an AX88190 card - use axnet_cs instead.\n");
+ return NULL;
+ }
+
+ local_hw_info = get_hwinfo(link);
+ if (!local_hw_info)
+ local_hw_info = get_prom(link);
+ if (!local_hw_info)
+ local_hw_info = get_dl10019(link);
+ if (!local_hw_info)
+ local_hw_info = get_ax88190(link);
+ if (!local_hw_info)
+ local_hw_info = get_hwired(link);
+
+ return local_hw_info;
+}
+
+static int pcnet_config(struct pcmcia_device *link)
+{
+ struct net_device *dev = link->priv;
+ pcnet_dev_t *info = PRIV(dev);
+ int start_pg, stop_pg, cm_offset;
+ int has_shmem = 0;
+ hw_info_t *local_hw_info;
+ struct ei_device *ei_local;
+
+ dev_dbg(&link->dev, "pcnet_config\n");
+
+ local_hw_info = pcnet_try_config(link, &has_shmem, 0);
+ if (!local_hw_info) {
+ /* check whether forcing io_lines to 16 helps... */
+ pcmcia_disable_device(link);
+ local_hw_info = pcnet_try_config(link, &has_shmem, 1);
+ if (local_hw_info == NULL) {
+ dev_notice(&link->dev, "unable to read hardware net"
+ " address for io base %#3lx\n", dev->base_addr);
+ goto failed;
+ }
}
info->flags = local_hw_info->flags;
@@ -641,67 +601,47 @@ static int pcnet_config(struct pcmcia_device *link)
ei_status.name = "NE2000";
ei_status.word16 = 1;
- ei_status.reset_8390 = &pcnet_reset_8390;
+ ei_status.reset_8390 = pcnet_reset_8390;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-
- if (info->flags & (IS_DL10019|IS_DL10022)) {
- dev->do_ioctl = &ei_ioctl;
+ if (info->flags & (IS_DL10019|IS_DL10022))
mii_phy_probe(dev);
- }
- link->dev_node = &info->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
+ SET_NETDEV_DEV(dev, &link->dev);
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = pcnet_msg_enable;
if (register_netdev(dev) != 0) {
- printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
- link->dev_node = NULL;
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- strcpy(info->node.dev_name, dev->name);
-
if (info->flags & (IS_DL10019|IS_DL10022)) {
u_char id = inb(dev->base_addr + 0x1a);
- printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
- dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
+ netdev_info(dev, "NE2000 (DL100%d rev %02x): ",
+ (info->flags & IS_DL10022) ? 22 : 19, id);
if (info->pna_phy)
- printk("PNA, ");
+ pr_cont("PNA, ");
} else {
- printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name);
+ netdev_info(dev, "NE2000 Compatible: ");
}
- printk("io %#3lx, irq %d,", dev->base_addr, dev->irq);
+ pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq);
if (info->flags & USE_SHMEM)
- printk (" mem %#5lx,", dev->mem_start);
+ pr_cont(" mem %#5lx,", dev->mem_start);
if (info->flags & HAS_MISC_REG)
- printk(" %s xcvr,", if_names[dev->if_port]);
- printk(" hw_addr %s\n", print_mac(mac, dev->dev_addr));
+ pr_cont(" %s xcvr,", if_names[dev->if_port]);
+ pr_cont(" hw_addr %pM\n", dev->dev_addr);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
pcnet_release(link);
return -ENODEV;
} /* pcnet_config */
-/*======================================================================
-
- After a card is removed, pcnet_release() will unregister the net
- device, and release the PCMCIA configuration. If the device is
- still open, this will be postponed until it is closed.
-
-======================================================================*/
-
static void pcnet_release(struct pcmcia_device *link)
{
pcnet_dev_t *info = PRIV(link->priv);
- DEBUG(0, "pcnet_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "pcnet_release\n");
if (info->flags & USE_SHMEM)
iounmap(info->base);
@@ -709,15 +649,6 @@ static void pcnet_release(struct pcmcia_device *link)
pcmcia_disable_device(link);
}
-/*======================================================================
-
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the net drivers from trying
- to talk to the card any more.
-
-======================================================================*/
-
static int pcnet_suspend(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
@@ -955,7 +886,7 @@ static void mii_phy_probe(struct net_device *dev)
phyid = tmp << 16;
phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
phyid &= MII_PHYID_REV_MASK;
- DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
+ netdev_dbg(dev, "MII at %d is 0x%08x\n", i, phyid);
if (phyid == AM79C9XX_HOME_PHY) {
info->pna_phy = i;
} else if (phyid != AM79C9XX_ETH_PHY) {
@@ -971,7 +902,7 @@ static int pcnet_open(struct net_device *dev)
struct pcmcia_device *link = info->p_dev;
unsigned int nic_base = dev->base_addr;
- DEBUG(2, "pcnet_open('%s')\n", dev->name);
+ dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name);
if (!pcmcia_dev_present(link))
return -ENODEV;
@@ -979,7 +910,7 @@ static int pcnet_open(struct net_device *dev)
set_misc_reg(dev);
outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
- ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
+ ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev->name, dev);
if (ret)
return ret;
@@ -988,7 +919,7 @@ static int pcnet_open(struct net_device *dev)
info->phy_id = info->eth_phy;
info->link_status = 0x00;
init_timer(&info->watchdog);
- info->watchdog.function = &ei_watchdog;
+ info->watchdog.function = ei_watchdog;
info->watchdog.data = (u_long)dev;
info->watchdog.expires = jiffies + HZ;
add_timer(&info->watchdog);
@@ -1003,7 +934,7 @@ static int pcnet_close(struct net_device *dev)
pcnet_dev_t *info = PRIV(dev);
struct pcmcia_device *link = info->p_dev;
- DEBUG(2, "pcnet_close('%s')\n", dev->name);
+ dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name);
ei_close(dev);
free_irq(dev->irq, dev);
@@ -1041,8 +972,8 @@ static void pcnet_reset_8390(struct net_device *dev)
outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */
if (i == 100)
- printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n",
- dev->name);
+ netdev_err(dev, "pcnet_reset_8390() did not complete.\n");
+
set_misc_reg(dev);
} /* pcnet_reset_8390 */
@@ -1058,8 +989,7 @@ static int set_config(struct net_device *dev, struct ifmap *map)
else if ((map->port < 1) || (map->port > 2))
return -EINVAL;
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n",
- dev->name, if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
NS8390_init(dev, 1);
}
return 0;
@@ -1094,7 +1024,7 @@ static void ei_watchdog(u_long arg)
this, we can limp along even if the interrupt is blocked */
if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) {
if (!info->fast_poll)
- printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+ netdev_info(dev, "interrupt(s) dropped!\n");
ei_irq_wrapper(dev->irq, dev);
info->fast_poll = HZ;
}
@@ -1114,7 +1044,7 @@ static void ei_watchdog(u_long arg)
if (info->eth_phy) {
info->phy_id = info->eth_phy = 0;
} else {
- printk(KERN_INFO "%s: MII is missing!\n", dev->name);
+ netdev_info(dev, "MII is missing!\n");
info->flags &= ~HAS_MII;
}
goto reschedule;
@@ -1123,8 +1053,7 @@ static void ei_watchdog(u_long arg)
link &= 0x0004;
if (link != info->link_status) {
u_short p = mdio_read(mii_addr, info->phy_id, 5);
- printk(KERN_INFO "%s: %s link beat\n", dev->name,
- (link) ? "found" : "lost");
+ netdev_info(dev, "%s link beat\n", link ? "found" : "lost");
if (link && (info->flags & IS_DL10022)) {
/* Disable collision detection on full duplex links */
outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG);
@@ -1135,13 +1064,12 @@ static void ei_watchdog(u_long arg)
if (link) {
if (info->phy_id == info->eth_phy) {
if (p)
- printk(KERN_INFO "%s: autonegotiation complete: "
- "%sbaseT-%cD selected\n", dev->name,
- ((p & 0x0180) ? "100" : "10"),
- ((p & 0x0140) ? 'F' : 'H'));
+ netdev_info(dev, "autonegotiation complete: "
+ "%sbaseT-%cD selected\n",
+ ((p & 0x0180) ? "100" : "10"),
+ ((p & 0x0140) ? 'F' : 'H'));
else
- printk(KERN_INFO "%s: link partner did not "
- "autonegotiate\n", dev->name);
+ netdev_info(dev, "link partner did not autonegotiate\n");
}
NS8390_init(dev, 1);
}
@@ -1154,8 +1082,8 @@ static void ei_watchdog(u_long arg)
/* isolate this MII and try flipping to the other one */
mdio_write(mii_addr, info->phy_id, 0, 0x0400);
info->phy_id ^= info->pna_phy ^ info->eth_phy;
- printk(KERN_INFO "%s: switched to %s transceiver\n", dev->name,
- (info->phy_id == info->eth_phy) ? "ethernet" : "PNA");
+ netdev_info(dev, "switched to %s transceiver\n",
+ (info->phy_id == info->eth_phy) ? "ethernet" : "PNA");
mdio_write(mii_addr, info->phy_id, 0,
(info->phy_id == info->eth_phy) ? 0x1000 : 0);
info->link_status = 0;
@@ -1170,34 +1098,24 @@ reschedule:
/*====================================================================*/
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, "pcnet_cs");
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
-/*====================================================================*/
-
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
pcnet_dev_t *info = PRIV(dev);
- u16 *data = (u16 *)&rq->ifr_ifru;
+ struct mii_ioctl_data *data = if_mii(rq);
unsigned int mii_addr = dev->base_addr + DLINK_GPIO;
+
+ if (!(info->flags & (IS_DL10019|IS_DL10022)))
+ return -EINVAL;
+
switch (cmd) {
case SIOCGMIIPHY:
- data[0] = info->phy_id;
+ data->phy_id = info->phy_id;
case SIOCGMIIREG: /* Read MII PHY register. */
- data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f);
+ data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- mdio_write(mii_addr, data[0], data[1] & 0x1f, data[2]);
+ mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in);
return 0;
}
return -EOPNOTSUPP;
@@ -1212,9 +1130,9 @@ static void dma_get_8390_hdr(struct net_device *dev,
unsigned int nic_base = dev->base_addr;
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
- "[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ netdev_err(dev, "DMAing conflict in dma_block_input."
+ "[DMAstat:%1x][irqlock:%1x]\n",
+ ei_status.dmaing, ei_status.irqlock);
return;
}
@@ -1243,15 +1161,14 @@ static void dma_block_input(struct net_device *dev, int count,
unsigned int nic_base = dev->base_addr;
int xfer_count = count;
char *buf = skb->data;
+ struct ei_device *ei_local = netdev_priv(dev);
-#ifdef PCMCIA_DEBUG
- if ((ei_debug > 4) && (count != 4))
- printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+ if ((netif_msg_rx_status(ei_local)) && (count != 4))
+ netdev_dbg(dev, "[bi=%d]\n", count+4);
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
- "[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ netdev_err(dev, "DMAing conflict in dma_block_input."
+ "[DMAstat:%1x][irqlock:%1x]\n",
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -1269,7 +1186,8 @@ static void dma_block_input(struct net_device *dev, int count,
/* This was for the ALPHA version only, but enough people have been
encountering problems that it is still here. */
#ifdef PCMCIA_DEBUG
- if (ei_debug > 4) { /* DMA termination address check... */
+ /* DMA termination address check... */
+ if (netif_msg_rx_status(ei_local)) {
int addr, tries = 20;
do {
/* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
@@ -1281,9 +1199,9 @@ static void dma_block_input(struct net_device *dev, int count,
break;
} while (--tries > 0);
if (tries <= 0)
- printk(KERN_NOTICE "%s: RX transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
+ netdev_notice(dev, "RX transfer address mismatch,"
+ "%#4.4x (expected) vs. %#4.4x (actual).\n",
+ ring_offset + xfer_count, addr);
}
#endif
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
@@ -1299,12 +1217,12 @@ static void dma_block_output(struct net_device *dev, int count,
pcnet_dev_t *info = PRIV(dev);
#ifdef PCMCIA_DEBUG
int retries = 0;
+ struct ei_device *ei_local = netdev_priv(dev);
#endif
u_long dma_start;
#ifdef PCMCIA_DEBUG
- if (ei_debug > 4)
- printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
+ netif_dbg(ei_local, tx_queued, dev, "[bo=%d]\n", count);
#endif
/* Round the count up for word writes. Do we need to do this?
@@ -1313,9 +1231,9 @@ static void dma_block_output(struct net_device *dev, int count,
if (count & 0x01)
count++;
if (ei_status.dmaing) {
- printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output."
- "[DMAstat:%1x][irqlock:%1x]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
+ netdev_err(dev, "DMAing conflict in dma_block_output."
+ "[DMAstat:%1x][irqlock:%1x]\n",
+ ei_status.dmaing, ei_status.irqlock);
return;
}
ei_status.dmaing |= 0x01;
@@ -1342,7 +1260,8 @@ static void dma_block_output(struct net_device *dev, int count,
#ifdef PCMCIA_DEBUG
/* This was for the ALPHA version only, but enough people have been
encountering problems that it is still here. */
- if (ei_debug > 4) { /* DMA termination address check... */
+ /* DMA termination address check... */
+ if (netif_msg_tx_queued(ei_local)) {
int addr, tries = 20;
do {
int high = inb_p(nic_base + EN0_RSARHI);
@@ -1352,9 +1271,9 @@ static void dma_block_output(struct net_device *dev, int count,
break;
} while (--tries > 0);
if (tries <= 0) {
- printk(KERN_NOTICE "%s: Tx packet transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, (start_page << 8) + count, addr);
+ netdev_notice(dev, "Tx packet transfer address mismatch,"
+ "%#4.4x (expected) vs. %#4.4x (actual).\n",
+ (start_page << 8) + count, addr);
if (retries++ == 0)
goto retry;
}
@@ -1363,11 +1282,10 @@ static void dma_block_output(struct net_device *dev, int count,
while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) {
- printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n",
- dev->name);
- pcnet_reset_8390(dev);
- NS8390_init(dev, 1);
- break;
+ netdev_warn(dev, "timeout waiting for Tx RDC.\n");
+ pcnet_reset_8390(dev);
+ NS8390_init(dev, 1);
+ break;
}
outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
@@ -1388,9 +1306,9 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg,
ei_status.stop_page = stop_pg;
/* set up block i/o functions */
- ei_status.get_8390_hdr = &dma_get_8390_hdr;
- ei_status.block_input = &dma_block_input;
- ei_status.block_output = &dma_block_output;
+ ei_status.get_8390_hdr = dma_get_8390_hdr;
+ ei_status.block_input = dma_block_input;
+ ei_status.block_output = dma_block_output;
return 0;
}
@@ -1486,9 +1404,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
{
struct net_device *dev = link->priv;
pcnet_dev_t *info = PRIV(dev);
- win_req_t req;
- memreq_t mem;
- int i, window_size, offset, last_ret, last_fn;
+ int i, window_size, offset, ret;
window_size = (stop_pg - start_pg) << 8;
if (window_size > 32 * 1024)
@@ -1498,20 +1414,22 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
window_size = roundup_pow_of_two(window_size);
/* Allocate a memory window */
- req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
- req.Attributes |= WIN_USE_WAIT;
- req.Base = 0; req.Size = window_size;
- req.AccessSpeed = mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
-
- mem.CardOffset = (start_pg << 8) + cm_offset;
- offset = mem.CardOffset % window_size;
- mem.CardOffset -= offset;
- mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+ link->resource[3]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
+ link->resource[3]->flags |= WIN_USE_WAIT;
+ link->resource[3]->start = 0; link->resource[3]->end = window_size;
+ ret = pcmcia_request_window(link, link->resource[3], mem_speed);
+ if (ret)
+ goto failed;
+
+ offset = (start_pg << 8) + cm_offset;
+ offset -= offset % window_size;
+ ret = pcmcia_map_mem_page(link, link->resource[3], offset);
+ if (ret)
+ goto failed;
/* Try scribbling on the buffer */
- info->base = ioremap(req.Base, window_size);
+ info->base = ioremap(link->resource[3]->start,
+ resource_size(link->resource[3]));
for (i = 0; i < (TX_PAGES<<8); i += 2)
__raw_writew((i>>1), info->base+offset+i);
udelay(100);
@@ -1520,37 +1438,36 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
pcnet_reset_8390(dev);
if (i != (TX_PAGES<<8)) {
iounmap(info->base);
- pcmcia_release_window(link->win);
- info->base = NULL; link->win = NULL;
+ pcmcia_release_window(link, link->resource[3]);
+ info->base = NULL;
goto failed;
}
ei_status.mem = info->base + offset;
- ei_status.priv = req.Size;
+ ei_status.priv = resource_size(link->resource[3]);
dev->mem_start = (u_long)ei_status.mem;
- dev->mem_end = dev->mem_start + req.Size;
+ dev->mem_end = dev->mem_start + resource_size(link->resource[3]);
ei_status.tx_start_page = start_pg;
ei_status.rx_start_page = start_pg + TX_PAGES;
- ei_status.stop_page = start_pg + ((req.Size - offset) >> 8);
+ ei_status.stop_page = start_pg + (
+ (resource_size(link->resource[3]) - offset) >> 8);
/* set up block i/o functions */
- ei_status.get_8390_hdr = &shmem_get_8390_hdr;
- ei_status.block_input = &shmem_block_input;
- ei_status.block_output = &shmem_block_output;
+ ei_status.get_8390_hdr = shmem_get_8390_hdr;
+ ei_status.block_input = shmem_block_input;
+ ei_status.block_output = shmem_block_output;
info->flags |= USE_SHMEM;
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
return 1;
}
/*====================================================================*/
-static struct pcmcia_device_id pcnet_ids[] = {
+static const struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0057, 0x0021),
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0104, 0x000a),
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0xea15),
@@ -1559,6 +1476,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101),
PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+ PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
@@ -1579,7 +1497,6 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab),
PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
- PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
@@ -1622,6 +1539,8 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "FASTline PCMCIA 10/100 Fast-Ethernet", 0xfa2e424d, 0x3953d9b9),
PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722),
PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2),
+ PCMCIA_DEVICE_PROD_ID12("corega", "Ether CF-TD", 0x0a21501a, 0x6589340a),
+ PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether CF-TD LAN Card", 0x5261440f, 0x8797663b),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd),
PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d),
PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d),
@@ -1664,6 +1583,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b),
PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0),
PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956),
+ PCMCIA_DEVICE_PROD_ID12("KENTRONICS", "KEP-230", 0xaf8144c9, 0x868f6616),
PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64),
PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5),
PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3),
@@ -1697,7 +1617,6 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8),
PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76),
PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e),
- PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875),
PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f),
PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b),
@@ -1719,6 +1638,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50),
PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110),
PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941),
+ PCMCIA_DEVICE_PROD_ID12("RIOS Systems Co.", "PC CARD3 ETHERNET", 0x7dd33481, 0x10b41826),
PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df),
PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0),
PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd),
@@ -1742,30 +1662,36 @@ static struct pcmcia_device_id pcnet_ids[] = {
PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078),
/* too generic! */
/* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */
- PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
- PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
- PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
- PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
- PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
- PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
- PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
- PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
- PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "LA-PCM.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
- PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "tamarack.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
+ PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
+ PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
+ PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b),
PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0",
0xb4be14e3, 0x43ac239b, 0x0877b627),
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, pcnet_ids);
+MODULE_FIRMWARE("cis/PCMLM28.cis");
+MODULE_FIRMWARE("cis/DP83903.cis");
+MODULE_FIRMWARE("cis/LA-PCM.cis");
+MODULE_FIRMWARE("cis/PE520.cis");
+MODULE_FIRMWARE("cis/NE2K.cis");
+MODULE_FIRMWARE("cis/PE-200.cis");
+MODULE_FIRMWARE("cis/tamarack.cis");
static struct pcmcia_driver pcnet_driver = {
- .drv = {
- .name = "pcnet_cs",
- },
+ .name = "pcnet_cs",
.probe = pcnet_probe,
.remove = pcnet_detach,
.owner = THIS_MODULE,
@@ -1773,17 +1699,4 @@ static struct pcmcia_driver pcnet_driver = {
.suspend = pcnet_suspend,
.resume = pcnet_resume,
};
-
-static int __init init_pcnet_cs(void)
-{
- return pcmcia_register_driver(&pcnet_driver);
-}
-
-static void __exit exit_pcnet_cs(void)
-{
- DEBUG(0, "pcnet_cs: unloading\n");
- pcmcia_unregister_driver(&pcnet_driver);
-}
-
-module_init(init_pcnet_cs);
-module_exit(exit_pcnet_cs);
+module_pcmcia_driver(pcnet_driver);
diff --git a/drivers/net/smc-ultra.c b/drivers/net/ethernet/8390/smc-ultra.c
index 00d6cf1af48..139385dcdaa 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/ethernet/8390/smc-ultra.c
@@ -62,13 +62,13 @@ static const char version[] =
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/isapnp.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/system.h>
#include "8390.h"
@@ -111,6 +111,7 @@ static struct isapnp_device_id ultra_device_ids[] __initdata = {
MODULE_DEVICE_TABLE(isapnp, ultra_device_ids);
#endif
+static u32 ultra_msg_enable;
#define START_PG 0x00 /* First page of TX buffer */
@@ -142,9 +143,6 @@ static int __init do_ultra_probe(struct net_device *dev)
int base_addr = dev->base_addr;
int irq = dev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = &ultra_poll;
-#endif
if (base_addr > 0x1ff) /* Check a single specified location. */
return ultra_probe1(dev, base_addr);
else if (base_addr != 0) /* Don't probe at all. */
@@ -187,6 +185,22 @@ out:
}
#endif
+static const struct net_device_ops ultra_netdev_ops = {
+ .ndo_open = ultra_open,
+ .ndo_stop = ultra_close_card,
+
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_set_rx_mode = ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ultra_poll,
+#endif
+};
+
static int __init ultra_probe1(struct net_device *dev, int ioaddr)
{
int i, retval;
@@ -198,7 +212,7 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
unsigned char num_pages, irqreg, addr, piomode;
unsigned char idreg = inb(ioaddr + 7);
unsigned char reg4 = inb(ioaddr + 4) & 0x7f;
- DECLARE_MAC_BUF(mac);
+ struct ei_device *ei_local = netdev_priv(dev);
if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME))
return -EBUSY;
@@ -220,16 +234,16 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
goto out;
}
- if (ei_debug && version_printed++ == 0)
- printk(version);
+ if ((ultra_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
+ netdev_info(dev, version);
model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ";
for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(ioaddr + 8 + i);
- printk("%s: %s at %#3x, %s", dev->name, model_name,
- ioaddr, print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "%s at %#3x, %pM", model_name,
+ ioaddr, dev->dev_addr);
/* Switch from the station address to the alternate register set and
read the useful registers there. */
@@ -253,7 +267,7 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)];
if (irq == 0) {
- printk(", failed to detect IRQ line.\n");
+ pr_cont(", failed to detect IRQ line.\n");
retval = -EAGAIN;
goto out;
}
@@ -265,8 +279,12 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
{
- int addr_tbl[4] = {0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000};
- short num_pages_tbl[4] = {0x20, 0x40, 0x80, 0xff};
+ static const int addr_tbl[4] = {
+ 0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000
+ };
+ static const short num_pages_tbl[4] = {
+ 0x20, 0x40, 0x80, 0xff
+ };
dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ;
num_pages = num_pages_tbl[(addr >> 4) & 3];
@@ -280,7 +298,7 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG)*256);
if (!ei_status.mem) {
- printk(", failed to ioremap.\n");
+ pr_cont(", failed to ioremap.\n");
retval = -ENOMEM;
goto out;
}
@@ -288,25 +306,24 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG)*256;
if (piomode) {
- printk(",%s IRQ %d programmed-I/O mode.\n",
- eeprom_irq ? "EEPROM" : "assigned ", dev->irq);
+ pr_cont(", %s IRQ %d programmed-I/O mode.\n",
+ eeprom_irq ? "EEPROM" : "assigned ", dev->irq);
ei_status.block_input = &ultra_pio_input;
ei_status.block_output = &ultra_pio_output;
ei_status.get_8390_hdr = &ultra_pio_get_hdr;
} else {
- printk(",%s IRQ %d memory %#lx-%#lx.\n", eeprom_irq ? "" : "assigned ",
- dev->irq, dev->mem_start, dev->mem_end-1);
+ pr_cont(", %s IRQ %d memory %#lx-%#lx.\n",
+ eeprom_irq ? "" : "assigned ", dev->irq, dev->mem_start,
+ dev->mem_end-1);
ei_status.block_input = &ultra_block_input;
ei_status.block_output = &ultra_block_output;
ei_status.get_8390_hdr = &ultra_get_8390_hdr;
}
ei_status.reset_8390 = &ultra_reset_8390;
- dev->open = &ultra_open;
- dev->stop = &ultra_close_card;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
+
+ dev->netdev_ops = &ultra_netdev_ops;
NS8390_init(dev, 0);
+ ei_local->msg_enable = ultra_msg_enable;
retval = register_netdev(dev);
if (retval)
@@ -343,12 +360,15 @@ static int __init ultra_probe_isapnp(struct net_device *dev)
/* found it */
dev->base_addr = pnp_port_start(idev, 0);
dev->irq = pnp_irq(idev, 0);
- printk(KERN_INFO "smc-ultra.c: ISAPnP reports %s at i/o %#lx, irq %d.\n",
- (char *) ultra_device_ids[i].driver_data,
- dev->base_addr, dev->irq);
+ netdev_info(dev,
+ "smc-ultra.c: ISAPnP reports %s at i/o %#lx, irq %d.\n",
+ (char *) ultra_device_ids[i].driver_data,
+ dev->base_addr, dev->irq);
if (ultra_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */
- printk(KERN_ERR "smc-ultra.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr);
- pnp_device_detach(idev);
+ netdev_err(dev,
+ "smc-ultra.c: Probe of ISAPnP card at %#lx failed.\n",
+ dev->base_addr);
+ pnp_device_detach(idev);
return -ENXIO;
}
ei_status.priv = (unsigned long)idev;
@@ -399,9 +419,10 @@ static void
ultra_reset_8390(struct net_device *dev)
{
int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */
+ struct ei_device *ei_local = netdev_priv(dev);
outb(ULTRA_RESET, cmd_port);
- if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies);
+ netif_dbg(ei_local, hw, dev, "resetting Ultra, t=%ld...\n", jiffies);
ei_status.txing = 0;
outb(0x00, cmd_port); /* Disable shared memory for safety. */
@@ -411,8 +432,7 @@ ultra_reset_8390(struct net_device *dev)
else
outb(0x01, cmd_port + 6); /* Enable interrupts and memory. */
- if (ei_debug > 1) printk("reset done\n");
- return;
+ netif_dbg(ei_local, hw, dev, "reset done\n");
}
/* Grab the 8390 specific header. Similar to the block_input routine, but
@@ -518,11 +538,11 @@ static int
ultra_close_card(struct net_device *dev)
{
int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */
+ struct ei_device *ei_local = netdev_priv(dev);
netif_stop_queue(dev);
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
+ netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n");
outb(0x00, ioaddr + 6); /* Disable interrupts. */
free_irq(dev->irq, dev);
@@ -544,8 +564,10 @@ static int irq[MAX_ULTRA_CARDS];
module_param_array(io, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
+module_param_named(msg_enable, ultra_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
MODULE_PARM_DESC(io, "I/O base address(es)");
MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
+MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
MODULE_DESCRIPTION("SMC Ultra/EtherEZ ISA/PnP Ethernet driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/stnic.c b/drivers/net/ethernet/8390/stnic.c
index 2ed0bd59681..aca957d4e12 100644
--- a/drivers/net/stnic.c
+++ b/drivers/net/ethernet/8390/stnic.c
@@ -17,7 +17,6 @@
#include <linux/init.h>
#include <linux/delay.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <mach-se/mach/se.h>
#include <asm/machvec.h>
@@ -60,8 +59,6 @@ static byte stnic_eadr[6] =
static struct net_device *stnic_dev;
-static int stnic_open (struct net_device *dev);
-static int stnic_close (struct net_device *dev);
static void stnic_reset (struct net_device *dev);
static void stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
@@ -72,6 +69,11 @@ static void stnic_block_output (struct net_device *dev, int count,
static void stnic_init (struct net_device *dev);
+static u32 stnic_msg_enable;
+
+module_param_named(msg_enable, stnic_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
+MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
+
/* SH7750 specific read/write io. */
static inline void
STNIC_DELAY (void)
@@ -103,6 +105,7 @@ static int __init stnic_probe(void)
{
struct net_device *dev;
int i, err;
+ struct ei_device *ei_local;
/* If we are not running on a SolutionEngine, give up now */
if (! MACH_SE)
@@ -116,26 +119,22 @@ static int __init stnic_probe(void)
#ifdef CONFIG_SH_STANDARD_BIOS
sh_bios_get_node_addr (stnic_eadr);
#endif
- for (i = 0; i < ETHER_ADDR_LEN; i++)
+ for (i = 0; i < ETH_ALEN; i++)
dev->dev_addr[i] = stnic_eadr[i];
/* Set the base address to point to the NIC, not the "real" base! */
dev->base_addr = 0x1000;
dev->irq = IRQ_STNIC;
- dev->open = &stnic_open;
- dev->stop = &stnic_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
+ dev->netdev_ops = &ei_netdev_ops;
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev);
if (err) {
- printk (KERN_EMERG " unable to get IRQ %d.\n", dev->irq);
- free_netdev(dev);
- return err;
- }
+ netdev_emerg(dev, " unable to get IRQ %d.\n", dev->irq);
+ free_netdev(dev);
+ return err;
+ }
ei_status.name = dev->name;
ei_status.word16 = 1;
@@ -154,6 +153,8 @@ static int __init stnic_probe(void)
ei_status.block_output = &stnic_block_output;
stnic_init (dev);
+ ei_local = netdev_priv(dev);
+ ei_local->msg_enable = stnic_msg_enable;
err = register_netdev(dev);
if (err) {
@@ -163,35 +164,19 @@ static int __init stnic_probe(void)
}
stnic_dev = dev;
- printk (KERN_INFO "NS ST-NIC 83902A\n");
-
- return 0;
-}
-
-static int
-stnic_open (struct net_device *dev)
-{
-#if 0
- printk (KERN_DEBUG "stnic open\n");
-#endif
- ei_open (dev);
- return 0;
-}
+ netdev_info(dev, "NS ST-NIC 83902A\n");
-static int
-stnic_close (struct net_device *dev)
-{
- ei_close (dev);
return 0;
}
static void
stnic_reset (struct net_device *dev)
{
+ struct ei_device *ei_local = netdev_priv(dev);
+
*(vhalf *) PA_83902_RST = 0;
udelay (5);
- if (ei_debug > 1)
- printk (KERN_WARNING "8390 reset done (%ld).\n", jiffies);
+ netif_warn(ei_local, hw, dev, "8390 reset done (%ld).\n", jiffies);
*(vhalf *) PA_83902_RST = ~0;
udelay (5);
}
@@ -200,6 +185,8 @@ static void
stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page)
{
+ struct ei_device *ei_local = netdev_priv(dev);
+
half buf[2];
STNIC_WRITE (PG0_RSAR0, 0);
@@ -220,8 +207,7 @@ stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr,
hdr->count = ((buf[1] >> 8) & 0xff) | (buf[1] << 8);
#endif
- if (ei_debug > 1)
- printk (KERN_DEBUG "ring %x status %02x next %02x count %04x.\n",
+ netif_dbg(ei_local, probe, dev, "ring %x status %02x next %02x count %04x.\n",
ring_page, hdr->status, hdr->next, hdr->count);
STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA);
@@ -303,7 +289,6 @@ stnic_init (struct net_device *dev)
{
stnic_reset (dev);
NS8390_init (dev, 0);
- return;
}
static void __exit stnic_cleanup(void)
diff --git a/drivers/net/wd.c b/drivers/net/ethernet/8390/wd.c
index fa14255282a..dd7d816bde5 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/ethernet/8390/wd.c
@@ -39,7 +39,6 @@ static const char version[] =
#include <linux/etherdevice.h>
#include <asm/io.h>
-#include <asm/system.h>
#include "8390.h"
@@ -61,6 +60,7 @@ static void wd_block_output(struct net_device *dev, int count,
const unsigned char *buf, int start_page);
static int wd_close(struct net_device *dev);
+static u32 wd_msg_enable;
#define WD_START_PG 0x00 /* First page of TX buffer */
#define WD03_STOP_PG 0x20 /* Last page +1 of RX ring */
@@ -147,6 +147,21 @@ out:
}
#endif
+static const struct net_device_ops wd_netdev_ops = {
+ .ndo_open = wd_open,
+ .ndo_stop = wd_close,
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_set_rx_mode = ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
+
static int __init wd_probe1(struct net_device *dev, int ioaddr)
{
int i;
@@ -156,7 +171,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
int word16 = 0; /* 0 = 8 bit, 1 = 16 bit */
const char *model_name;
static unsigned version_printed;
- DECLARE_MAC_BUF(mac);
+ struct ei_device *ei_local = netdev_priv(dev);
for (i = 0; i < 8; i++)
checksum += inb(ioaddr + 8 + i);
@@ -167,19 +182,19 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
/* Check for semi-valid mem_start/end values if supplied. */
if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {
- printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
+ netdev_warn(dev,
+ "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
dev->mem_start = 0;
dev->mem_end = 0;
}
- if (ei_debug && version_printed++ == 0)
- printk(version);
+ if ((wd_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
+ netdev_info(dev, version);
for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(ioaddr + 8 + i);
- printk("%s: WD80x3 at %#3x, %s",
- dev->name, ioaddr, print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "WD80x3 at %#3x, %pM", ioaddr, dev->dev_addr);
/* The following PureData probe code was contributed by
Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
@@ -231,8 +246,9 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
}
#ifndef final_version
if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01))
- printk("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",
- word16 ? 16 : 8, (inb(ioaddr+1) & 0x01) ? 16 : 8);
+ pr_cont("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",
+ word16 ? 16 : 8,
+ (inb(ioaddr+1) & 0x01) ? 16 : 8);
#endif
}
@@ -246,7 +262,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
if (reg0 == 0xff || reg0 == 0) {
/* Future plan: this could check a few likely locations first. */
dev->mem_start = 0xd0000;
- printk(" assigning address %#lx", dev->mem_start);
+ pr_cont(" assigning address %#lx", dev->mem_start);
} else {
int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f;
/* Some boards don't have the register 5 -- it returns 0xff. */
@@ -261,7 +277,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
dev->base_addr = ioaddr+WD_NIC_OFFSET;
if (dev->irq < 2) {
- int irqmap[] = {9,3,5,7,10,11,15,4};
+ static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4};
int reg1 = inb(ioaddr+1);
int reg4 = inb(ioaddr+4);
if (ancient || reg1 == 0xff) { /* Ack!! No way to read the IRQ! */
@@ -284,8 +300,8 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */
- if (ei_debug > 2)
- printk(" autoirq is %d", dev->irq);
+ if (netif_msg_drv(ei_local))
+ pr_cont(" autoirq is %d", dev->irq);
if (dev->irq < 2)
dev->irq = word16 ? 10 : 5;
} else
@@ -297,7 +313,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
share and the board will usually be enabled. */
i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
if (i) {
- printk (" unable to get IRQ %d.\n", dev->irq);
+ pr_cont(" unable to get IRQ %d.\n", dev->irq);
return i;
}
@@ -325,19 +341,17 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
return -ENOMEM;
}
- printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
- model_name, dev->irq, dev->mem_start, dev->mem_end-1);
+ pr_cont(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
+ model_name, dev->irq, dev->mem_start, dev->mem_end-1);
- ei_status.reset_8390 = &wd_reset_8390;
- ei_status.block_input = &wd_block_input;
- ei_status.block_output = &wd_block_output;
- ei_status.get_8390_hdr = &wd_get_8390_hdr;
- dev->open = &wd_open;
- dev->stop = &wd_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
+ ei_status.reset_8390 = wd_reset_8390;
+ ei_status.block_input = wd_block_input;
+ ei_status.block_output = wd_block_output;
+ ei_status.get_8390_hdr = wd_get_8390_hdr;
+
+ dev->netdev_ops = &wd_netdev_ops;
NS8390_init(dev, 0);
+ ei_local->msg_enable = wd_msg_enable;
#if 1
/* Enable interrupt generation on softconfig cards -- M.U */
@@ -347,8 +361,10 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
#endif
err = register_netdev(dev);
- if (err)
+ if (err) {
free_irq(dev->irq, dev);
+ iounmap(ei_status.mem);
+ }
return err;
}
@@ -366,17 +382,18 @@ wd_open(struct net_device *dev)
outb(ei_status.reg5, ioaddr+WD_CMDREG5);
outb(ei_status.reg0, ioaddr); /* WD_CMDREG */
- ei_open(dev);
- return 0;
+ return ei_open(dev);
}
static void
wd_reset_8390(struct net_device *dev)
{
int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
+ struct ei_device *ei_local = netdev_priv(dev);
outb(WD_RESET, wd_cmd_port);
- if (ei_debug > 1) printk("resetting the WD80x3 t=%lu...", jiffies);
+ netif_dbg(ei_local, hw, dev, "resetting the WD80x3 t=%lu...\n",
+ jiffies);
ei_status.txing = 0;
/* Set up the ASIC registers, just in case something changed them. */
@@ -384,8 +401,7 @@ wd_reset_8390(struct net_device *dev)
if (ei_status.word16)
outb(NIC16 | ((dev->mem_start>>19) & 0x1f), wd_cmd_port+WD_CMDREG5);
- if (ei_debug > 1) printk("reset done\n");
- return;
+ netif_dbg(ei_local, hw, dev, "reset done\n");
}
/* Grab the 8390 specific header. Similar to the block_input routine, but
@@ -464,9 +480,9 @@ static int
wd_close(struct net_device *dev)
{
int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
+ struct ei_device *ei_local = netdev_priv(dev);
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
+ netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n");
ei_close(dev);
/* Change from 16-bit to 8-bit shared memory so reboot works. */
@@ -492,10 +508,12 @@ module_param_array(io, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
module_param_array(mem, int, NULL, 0);
module_param_array(mem_end, int, NULL, 0);
+module_param_named(msg_enable, wd_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
MODULE_PARM_DESC(io, "I/O base address(es)");
MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)");
MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)");
MODULE_PARM_DESC(mem_end, "memory end address(es)");
+MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/8390/zorro8390.c b/drivers/net/ethernet/8390/zorro8390.c
new file mode 100644
index 00000000000..8308728fad0
--- /dev/null
+++ b/drivers/net/ethernet/8390/zorro8390.c
@@ -0,0 +1,458 @@
+/*
+ * Amiga Linux/m68k and Linux/PPC Zorro NS8390 Ethernet Driver
+ *
+ * (C) Copyright 1998-2000 by some Elitist 680x0 Users(TM)
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This program is based on all the other NE2000 drivers for Linux
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * The Ariadne II and X-Surf are Zorro-II boards containing Realtek RTL8019AS
+ * Ethernet Controllers.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/zorro.h>
+#include <linux/jiffies.h>
+
+#include <asm/irq.h>
+#include <asm/amigaints.h>
+#include <asm/amigahw.h>
+
+#define EI_SHIFT(x) (ei_local->reg_offset[x])
+#define ei_inb(port) in_8(port)
+#define ei_outb(val, port) out_8(port, val)
+#define ei_inb_p(port) in_8(port)
+#define ei_outb_p(val, port) out_8(port, val)
+
+static const char version[] =
+ "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+
+static u32 zorro8390_msg_enable;
+
+#include "lib8390.c"
+
+#define DRV_NAME "zorro8390"
+
+#define NE_BASE (dev->base_addr)
+#define NE_CMD (0x00 * 2)
+#define NE_DATAPORT (0x10 * 2) /* NatSemi-defined port window offset */
+#define NE_RESET (0x1f * 2) /* Issue a read to reset,
+ * a write to clear. */
+#define NE_IO_EXTENT (0x20 * 2)
+
+#define NE_EN0_ISR (0x07 * 2)
+#define NE_EN0_DCFG (0x0e * 2)
+
+#define NE_EN0_RSARLO (0x08 * 2)
+#define NE_EN0_RSARHI (0x09 * 2)
+#define NE_EN0_RCNTLO (0x0a * 2)
+#define NE_EN0_RXCR (0x0c * 2)
+#define NE_EN0_TXCR (0x0d * 2)
+#define NE_EN0_RCNTHI (0x0b * 2)
+#define NE_EN0_IMR (0x0f * 2)
+
+#define NESM_START_PG 0x40 /* First page of TX buffer */
+#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
+
+#define WORDSWAP(a) ((((a) >> 8) & 0xff) | ((a) << 8))
+
+static struct card_info {
+ zorro_id id;
+ const char *name;
+ unsigned int offset;
+} cards[] = {
+ { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 },
+ { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 },
+};
+
+/* Hard reset the card. This used to pause for the same period that a
+ * 8390 reset command required, but that shouldn't be necessary.
+ */
+static void zorro8390_reset_8390(struct net_device *dev)
+{
+ unsigned long reset_start_time = jiffies;
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ netif_dbg(ei_local, hw, dev, "resetting - t=%ld...\n", jiffies);
+
+ z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+
+ ei_status.txing = 0;
+ ei_status.dmaing = 0;
+
+ /* This check _should_not_ be necessary, omit eventually. */
+ while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RESET) == 0)
+ if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
+ netdev_warn(dev, "%s: did not complete\n", __func__);
+ break;
+ }
+ z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr */
+}
+
+/* Grab the 8390 specific header. Similar to the block_input routine, but
+ * we don't need to be concerned with ring wrap as the header will be at
+ * the start of a page, so we optimize accordingly.
+ */
+static void zorro8390_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page)
+{
+ int nic_base = dev->base_addr;
+ int cnt;
+ short *ptrs;
+
+ /* This *shouldn't* happen.
+ * If it does, it's the last thing you'll see
+ */
+ if (ei_status.dmaing) {
+ netdev_warn(dev,
+ "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
+ __func__, ei_status.dmaing, ei_status.irqlock);
+ return;
+ }
+
+ ei_status.dmaing |= 0x01;
+ z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
+ z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+ z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
+ z_writeb(0, nic_base + NE_EN0_RCNTHI);
+ z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */
+ z_writeb(ring_page, nic_base + NE_EN0_RSARHI);
+ z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ ptrs = (short *)hdr;
+ for (cnt = 0; cnt < sizeof(struct e8390_pkt_hdr) >> 1; cnt++)
+ *ptrs++ = z_readw(NE_BASE + NE_DATAPORT);
+
+ z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */
+
+ hdr->count = WORDSWAP(hdr->count);
+
+ ei_status.dmaing &= ~0x01;
+}
+
+/* Block input and output, similar to the Crynwr packet driver.
+ * If you are porting to a new ethercard, look at the packet driver source
+ * for hints. The NEx000 doesn't share the on-board packet memory --
+ * you have to put the packet out through the "remote DMA" dataport
+ * using z_writeb.
+ */
+static void zorro8390_block_input(struct net_device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ int nic_base = dev->base_addr;
+ char *buf = skb->data;
+ short *ptrs;
+ int cnt;
+
+ /* This *shouldn't* happen.
+ * If it does, it's the last thing you'll see
+ */
+ if (ei_status.dmaing) {
+ netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
+ __func__, ei_status.dmaing, ei_status.irqlock);
+ return;
+ }
+ ei_status.dmaing |= 0x01;
+ z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
+ z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+ z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+ z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
+ z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
+ z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
+ z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+ ptrs = (short *)buf;
+ for (cnt = 0; cnt < count >> 1; cnt++)
+ *ptrs++ = z_readw(NE_BASE + NE_DATAPORT);
+ if (count & 0x01)
+ buf[count - 1] = z_readb(NE_BASE + NE_DATAPORT);
+
+ z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */
+ ei_status.dmaing &= ~0x01;
+}
+
+static void zorro8390_block_output(struct net_device *dev, int count,
+ const unsigned char *buf,
+ const int start_page)
+{
+ int nic_base = NE_BASE;
+ unsigned long dma_start;
+ short *ptrs;
+ int cnt;
+
+ /* Round the count up for word writes. Do we need to do this?
+ * What effect will an odd byte count have on the 8390?
+ * I should check someday.
+ */
+ if (count & 0x01)
+ count++;
+
+ /* This *shouldn't* happen.
+ * If it does, it's the last thing you'll see
+ */
+ if (ei_status.dmaing) {
+ netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
+ __func__, ei_status.dmaing, ei_status.irqlock);
+ return;
+ }
+ ei_status.dmaing |= 0x01;
+ /* We should already be in page 0, but to be safe... */
+ z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+ z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+
+ /* Now the normal output. */
+ z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+ z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
+ z_writeb(0x00, nic_base + NE_EN0_RSARLO);
+ z_writeb(start_page, nic_base + NE_EN0_RSARHI);
+
+ z_writeb(E8390_RWRITE + E8390_START, nic_base + NE_CMD);
+ ptrs = (short *)buf;
+ for (cnt = 0; cnt < count >> 1; cnt++)
+ z_writew(*ptrs++, NE_BASE + NE_DATAPORT);
+
+ dma_start = jiffies;
+
+ while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
+ if (time_after(jiffies, dma_start + 2 * HZ / 100)) {
+ /* 20ms */
+ netdev_warn(dev, "timeout waiting for Tx RDC\n");
+ zorro8390_reset_8390(dev);
+ __NS8390_init(dev, 1);
+ break;
+ }
+
+ z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */
+ ei_status.dmaing &= ~0x01;
+}
+
+static int zorro8390_open(struct net_device *dev)
+{
+ __ei_open(dev);
+ return 0;
+}
+
+static int zorro8390_close(struct net_device *dev)
+{
+ struct ei_device *ei_local = netdev_priv(dev);
+
+ netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard\n");
+ __ei_close(dev);
+ return 0;
+}
+
+static void zorro8390_remove_one(struct zorro_dev *z)
+{
+ struct net_device *dev = zorro_get_drvdata(z);
+
+ unregister_netdev(dev);
+ free_irq(IRQ_AMIGA_PORTS, dev);
+ release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT * 2);
+ free_netdev(dev);
+}
+
+static struct zorro_device_id zorro8390_zorro_tbl[] = {
+ { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, },
+ { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl);
+
+static const struct net_device_ops zorro8390_netdev_ops = {
+ .ndo_open = zorro8390_open,
+ .ndo_stop = zorro8390_close,
+ .ndo_start_xmit = __ei_start_xmit,
+ .ndo_tx_timeout = __ei_tx_timeout,
+ .ndo_get_stats = __ei_get_stats,
+ .ndo_set_rx_mode = __ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = __ei_poll,
+#endif
+};
+
+static int zorro8390_init(struct net_device *dev, unsigned long board,
+ const char *name, void __iomem *ioaddr)
+{
+ int i;
+ int err;
+ unsigned char SA_prom[32];
+ int start_page, stop_page;
+ struct ei_device *ei_local = netdev_priv(dev);
+ static u32 zorro8390_offsets[16] = {
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
+ 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+ };
+
+ /* Reset card. Who knows what dain-bramaged state it was left in. */
+ {
+ unsigned long reset_start_time = jiffies;
+
+ z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET);
+
+ while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
+ if (time_after(jiffies,
+ reset_start_time + 2 * HZ / 100)) {
+ netdev_warn(dev, "not found (no reset ack)\n");
+ return -ENODEV;
+ }
+
+ z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */
+ }
+
+ /* Read the 16 bytes of station address PROM.
+ * We must first initialize registers,
+ * similar to NS8390_init(eifdev, 0).
+ * We can't reliably read the SAPROM address without this.
+ * (I learned the hard way!).
+ */
+ {
+ static const struct {
+ u32 value;
+ u32 offset;
+ } program_seq[] = {
+ {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD},
+ /* Select page 0 */
+ {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */
+ {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */
+ {0x00, NE_EN0_RCNTHI},
+ {0x00, NE_EN0_IMR}, /* Mask completion irq */
+ {0xFF, NE_EN0_ISR},
+ {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */
+ {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */
+ {32, NE_EN0_RCNTLO},
+ {0x00, NE_EN0_RCNTHI},
+ {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */
+ {0x00, NE_EN0_RSARHI},
+ {E8390_RREAD + E8390_START, NE_CMD},
+ };
+ for (i = 0; i < ARRAY_SIZE(program_seq); i++)
+ z_writeb(program_seq[i].value,
+ ioaddr + program_seq[i].offset);
+ }
+ for (i = 0; i < 16; i++) {
+ SA_prom[i] = z_readb(ioaddr + NE_DATAPORT);
+ (void)z_readb(ioaddr + NE_DATAPORT);
+ }
+
+ /* We must set the 8390 for word mode. */
+ z_writeb(0x49, ioaddr + NE_EN0_DCFG);
+ start_page = NESM_START_PG;
+ stop_page = NESM_STOP_PG;
+
+ dev->base_addr = (unsigned long)ioaddr;
+ dev->irq = IRQ_AMIGA_PORTS;
+
+ /* Install the Interrupt handler */
+ i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt,
+ IRQF_SHARED, DRV_NAME, dev);
+ if (i)
+ return i;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ dev->dev_addr[i] = SA_prom[i];
+
+ pr_debug("Found ethernet address: %pM\n", dev->dev_addr);
+
+ ei_status.name = name;
+ ei_status.tx_start_page = start_page;
+ ei_status.stop_page = stop_page;
+ ei_status.word16 = 1;
+
+ ei_status.rx_start_page = start_page + TX_PAGES;
+
+ ei_status.reset_8390 = zorro8390_reset_8390;
+ ei_status.block_input = zorro8390_block_input;
+ ei_status.block_output = zorro8390_block_output;
+ ei_status.get_8390_hdr = zorro8390_get_8390_hdr;
+ ei_status.reg_offset = zorro8390_offsets;
+
+ dev->netdev_ops = &zorro8390_netdev_ops;
+ __NS8390_init(dev, 0);
+
+ ei_local->msg_enable = zorro8390_msg_enable;
+
+ err = register_netdev(dev);
+ if (err) {
+ free_irq(IRQ_AMIGA_PORTS, dev);
+ return err;
+ }
+
+ netdev_info(dev, "%s at 0x%08lx, Ethernet Address %pM\n",
+ name, board, dev->dev_addr);
+
+ return 0;
+}
+
+static int zorro8390_init_one(struct zorro_dev *z,
+ const struct zorro_device_id *ent)
+{
+ struct net_device *dev;
+ unsigned long board, ioaddr;
+ int err, i;
+
+ for (i = ARRAY_SIZE(cards) - 1; i >= 0; i--)
+ if (z->id == cards[i].id)
+ break;
+ if (i < 0)
+ return -ENODEV;
+
+ board = z->resource.start;
+ ioaddr = board + cards[i].offset;
+ dev = ____alloc_ei_netdev(0);
+ if (!dev)
+ return -ENOMEM;
+ if (!request_mem_region(ioaddr, NE_IO_EXTENT * 2, DRV_NAME)) {
+ free_netdev(dev);
+ return -EBUSY;
+ }
+ err = zorro8390_init(dev, board, cards[i].name, ZTWO_VADDR(ioaddr));
+ if (err) {
+ release_mem_region(ioaddr, NE_IO_EXTENT * 2);
+ free_netdev(dev);
+ return err;
+ }
+ zorro_set_drvdata(z, dev);
+ return 0;
+}
+
+static struct zorro_driver zorro8390_driver = {
+ .name = "zorro8390",
+ .id_table = zorro8390_zorro_tbl,
+ .probe = zorro8390_init_one,
+ .remove = zorro8390_remove_one,
+};
+
+static int __init zorro8390_init_module(void)
+{
+ return zorro_register_driver(&zorro8390_driver);
+}
+
+static void __exit zorro8390_cleanup_module(void)
+{
+ zorro_unregister_driver(&zorro8390_driver);
+}
+
+module_init(zorro8390_init_module);
+module_exit(zorro8390_cleanup_module);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
new file mode 100644
index 00000000000..edb71866185
--- /dev/null
+++ b/drivers/net/ethernet/Kconfig
@@ -0,0 +1,186 @@
+#
+# Ethernet LAN device configuration
+#
+
+menuconfig ETHERNET
+ bool "Ethernet driver support"
+ depends on NET
+ default y
+ ---help---
+ This section contains all the Ethernet device drivers.
+
+if ETHERNET
+
+config MDIO
+ tristate
+
+config SUNGEM_PHY
+ tristate
+
+source "drivers/net/ethernet/3com/Kconfig"
+source "drivers/net/ethernet/adaptec/Kconfig"
+source "drivers/net/ethernet/aeroflex/Kconfig"
+source "drivers/net/ethernet/allwinner/Kconfig"
+source "drivers/net/ethernet/alteon/Kconfig"
+source "drivers/net/ethernet/altera/Kconfig"
+source "drivers/net/ethernet/amd/Kconfig"
+source "drivers/net/ethernet/apple/Kconfig"
+source "drivers/net/ethernet/arc/Kconfig"
+source "drivers/net/ethernet/atheros/Kconfig"
+source "drivers/net/ethernet/cadence/Kconfig"
+source "drivers/net/ethernet/adi/Kconfig"
+source "drivers/net/ethernet/broadcom/Kconfig"
+source "drivers/net/ethernet/brocade/Kconfig"
+source "drivers/net/ethernet/calxeda/Kconfig"
+source "drivers/net/ethernet/chelsio/Kconfig"
+source "drivers/net/ethernet/cirrus/Kconfig"
+source "drivers/net/ethernet/cisco/Kconfig"
+
+config CX_ECAT
+ tristate "Beckhoff CX5020 EtherCAT master support"
+ depends on PCI
+ depends on X86 || COMPILE_TEST
+ ---help---
+ Driver for EtherCAT master module located on CCAT FPGA
+ that can be found on Beckhoff CX5020, and possibly other of CX
+ Beckhoff CX series industrial PCs.
+
+ To compile this driver as a module, choose M here. The module
+ will be called ec_bhf.
+
+source "drivers/net/ethernet/davicom/Kconfig"
+
+config DNET
+ tristate "Dave ethernet support (DNET)"
+ depends on HAS_IOMEM
+ select PHYLIB
+ ---help---
+ The Dave ethernet interface (DNET) is found on Qong Board FPGA.
+ Say Y to include support for the DNET chip.
+
+ To compile this driver as a module, choose M here: the module
+ will be called dnet.
+
+source "drivers/net/ethernet/dec/Kconfig"
+source "drivers/net/ethernet/dlink/Kconfig"
+source "drivers/net/ethernet/emulex/Kconfig"
+source "drivers/net/ethernet/neterion/Kconfig"
+source "drivers/net/ethernet/faraday/Kconfig"
+source "drivers/net/ethernet/freescale/Kconfig"
+source "drivers/net/ethernet/fujitsu/Kconfig"
+source "drivers/net/ethernet/hisilicon/Kconfig"
+source "drivers/net/ethernet/hp/Kconfig"
+source "drivers/net/ethernet/ibm/Kconfig"
+source "drivers/net/ethernet/intel/Kconfig"
+source "drivers/net/ethernet/i825xx/Kconfig"
+source "drivers/net/ethernet/xscale/Kconfig"
+source "drivers/net/ethernet/icplus/Kconfig"
+
+config JME
+ tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ This driver supports the PCI-Express gigabit ethernet adapters
+ based on JMicron JMC250 chipset.
+
+ To compile this driver as a module, choose M here. The module
+ will be called jme.
+
+config KORINA
+ tristate "Korina (IDT RC32434) Ethernet support"
+ depends on MIKROTIK_RB532
+ ---help---
+ If you have a Mikrotik RouterBoard 500 or IDT RC32434
+ based system say Y. Otherwise say N.
+
+config LANTIQ_ETOP
+ tristate "Lantiq SoC ETOP driver"
+ depends on SOC_TYPE_XWAY
+ ---help---
+ Support for the MII0 inside the Lantiq SoC
+
+source "drivers/net/ethernet/marvell/Kconfig"
+source "drivers/net/ethernet/mellanox/Kconfig"
+source "drivers/net/ethernet/micrel/Kconfig"
+source "drivers/net/ethernet/microchip/Kconfig"
+source "drivers/net/ethernet/moxa/Kconfig"
+source "drivers/net/ethernet/myricom/Kconfig"
+
+config FEALNX
+ tristate "Myson MTD-8xx PCI Ethernet support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ Say Y here to support the Myson MTD-800 family of PCI-based Ethernet
+ cards. <http://www.myson.com.tw/>
+
+source "drivers/net/ethernet/natsemi/Kconfig"
+source "drivers/net/ethernet/8390/Kconfig"
+
+config NET_NETX
+ tristate "NetX Ethernet support"
+ select MII
+ depends on ARCH_NETX
+ ---help---
+ This is support for the Hilscher netX builtin Ethernet ports
+
+ To compile this driver as a module, choose M here. The module
+ will be called netx-eth.
+
+source "drivers/net/ethernet/nuvoton/Kconfig"
+source "drivers/net/ethernet/nvidia/Kconfig"
+source "drivers/net/ethernet/nxp/Kconfig"
+source "drivers/net/ethernet/octeon/Kconfig"
+source "drivers/net/ethernet/oki-semi/Kconfig"
+
+config ETHOC
+ tristate "OpenCores 10/100 Mbps Ethernet MAC support"
+ depends on HAS_IOMEM && HAS_DMA
+ select MII
+ select PHYLIB
+ select CRC32
+ select BITREVERSE
+ ---help---
+ Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
+
+source "drivers/net/ethernet/packetengines/Kconfig"
+source "drivers/net/ethernet/pasemi/Kconfig"
+source "drivers/net/ethernet/qlogic/Kconfig"
+source "drivers/net/ethernet/realtek/Kconfig"
+source "drivers/net/ethernet/renesas/Kconfig"
+source "drivers/net/ethernet/rdc/Kconfig"
+
+config S6GMAC
+ tristate "S6105 GMAC ethernet support"
+ depends on XTENSA_VARIANT_S6000
+ select PHYLIB
+ ---help---
+ This driver supports the on chip ethernet device on the
+ S6105 xtensa processor.
+
+ To compile this driver as a module, choose M here. The module
+ will be called s6gmac.
+
+source "drivers/net/ethernet/samsung/Kconfig"
+source "drivers/net/ethernet/seeq/Kconfig"
+source "drivers/net/ethernet/silan/Kconfig"
+source "drivers/net/ethernet/sis/Kconfig"
+source "drivers/net/ethernet/sfc/Kconfig"
+source "drivers/net/ethernet/sgi/Kconfig"
+source "drivers/net/ethernet/smsc/Kconfig"
+source "drivers/net/ethernet/stmicro/Kconfig"
+source "drivers/net/ethernet/sun/Kconfig"
+source "drivers/net/ethernet/tehuti/Kconfig"
+source "drivers/net/ethernet/ti/Kconfig"
+source "drivers/net/ethernet/tile/Kconfig"
+source "drivers/net/ethernet/toshiba/Kconfig"
+source "drivers/net/ethernet/tundra/Kconfig"
+source "drivers/net/ethernet/via/Kconfig"
+source "drivers/net/ethernet/wiznet/Kconfig"
+source "drivers/net/ethernet/xilinx/Kconfig"
+source "drivers/net/ethernet/xircom/Kconfig"
+
+endif # ETHERNET
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
new file mode 100644
index 00000000000..58de3339ab3
--- /dev/null
+++ b/drivers/net/ethernet/Makefile
@@ -0,0 +1,83 @@
+#
+# Makefile for the Linux network Ethernet device drivers.
+#
+
+obj-$(CONFIG_NET_VENDOR_3COM) += 3com/
+obj-$(CONFIG_NET_VENDOR_8390) += 8390/
+obj-$(CONFIG_NET_VENDOR_ADAPTEC) += adaptec/
+obj-$(CONFIG_GRETH) += aeroflex/
+obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/
+obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/
+obj-$(CONFIG_ALTERA_TSE) += altera/
+obj-$(CONFIG_NET_VENDOR_AMD) += amd/
+obj-$(CONFIG_NET_VENDOR_APPLE) += apple/
+obj-$(CONFIG_NET_VENDOR_ARC) += arc/
+obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/
+obj-$(CONFIG_NET_CADENCE) += cadence/
+obj-$(CONFIG_NET_BFIN) += adi/
+obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/
+obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/
+obj-$(CONFIG_NET_CALXEDA_XGMAC) += calxeda/
+obj-$(CONFIG_NET_VENDOR_CHELSIO) += chelsio/
+obj-$(CONFIG_NET_VENDOR_CIRRUS) += cirrus/
+obj-$(CONFIG_NET_VENDOR_CISCO) += cisco/
+obj-$(CONFIG_CX_ECAT) += ec_bhf.o
+obj-$(CONFIG_DM9000) += davicom/
+obj-$(CONFIG_DNET) += dnet.o
+obj-$(CONFIG_NET_VENDOR_DEC) += dec/
+obj-$(CONFIG_NET_VENDOR_DLINK) += dlink/
+obj-$(CONFIG_NET_VENDOR_EMULEX) += emulex/
+obj-$(CONFIG_NET_VENDOR_EXAR) += neterion/
+obj-$(CONFIG_NET_VENDOR_FARADAY) += faraday/
+obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/
+obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/
+obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/
+obj-$(CONFIG_NET_VENDOR_HP) += hp/
+obj-$(CONFIG_NET_VENDOR_IBM) += ibm/
+obj-$(CONFIG_NET_VENDOR_INTEL) += intel/
+obj-$(CONFIG_NET_VENDOR_I825XX) += i825xx/
+obj-$(CONFIG_NET_VENDOR_XSCALE) += xscale/
+obj-$(CONFIG_IP1000) += icplus/
+obj-$(CONFIG_JME) += jme.o
+obj-$(CONFIG_KORINA) += korina.o
+obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
+obj-$(CONFIG_NET_VENDOR_MARVELL) += marvell/
+obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/
+obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/
+obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
+obj-$(CONFIG_NET_VENDOR_MOXART) += moxa/
+obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
+obj-$(CONFIG_FEALNX) += fealnx.o
+obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/
+obj-$(CONFIG_NET_NETX) += netx-eth.o
+obj-$(CONFIG_NET_VENDOR_NUVOTON) += nuvoton/
+obj-$(CONFIG_NET_VENDOR_NVIDIA) += nvidia/
+obj-$(CONFIG_LPC_ENET) += nxp/
+obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/
+obj-$(CONFIG_NET_VENDOR_OKI) += oki-semi/
+obj-$(CONFIG_ETHOC) += ethoc.o
+obj-$(CONFIG_NET_PACKET_ENGINE) += packetengines/
+obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
+obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
+obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
+obj-$(CONFIG_SH_ETH) += renesas/
+obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
+obj-$(CONFIG_S6GMAC) += s6gmac.o
+obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/
+obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
+obj-$(CONFIG_NET_VENDOR_SILAN) += silan/
+obj-$(CONFIG_NET_VENDOR_SIS) += sis/
+obj-$(CONFIG_SFC) += sfc/
+obj-$(CONFIG_NET_VENDOR_SGI) += sgi/
+obj-$(CONFIG_NET_VENDOR_SMSC) += smsc/
+obj-$(CONFIG_NET_VENDOR_STMICRO) += stmicro/
+obj-$(CONFIG_NET_VENDOR_SUN) += sun/
+obj-$(CONFIG_NET_VENDOR_TEHUTI) += tehuti/
+obj-$(CONFIG_NET_VENDOR_TI) += ti/
+obj-$(CONFIG_TILE_NET) += tile/
+obj-$(CONFIG_NET_VENDOR_TOSHIBA) += toshiba/
+obj-$(CONFIG_NET_VENDOR_TUNDRA) += tundra/
+obj-$(CONFIG_NET_VENDOR_VIA) += via/
+obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/
+obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
+obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
diff --git a/drivers/net/ethernet/adaptec/Kconfig b/drivers/net/ethernet/adaptec/Kconfig
new file mode 100644
index 00000000000..5c804bbe3da
--- /dev/null
+++ b/drivers/net/ethernet/adaptec/Kconfig
@@ -0,0 +1,35 @@
+#
+# Adaptec network device configuration
+#
+
+config NET_VENDOR_ADAPTEC
+ bool "Adaptec devices"
+ default y
+ depends on PCI
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Adaptec cards. If you say Y, you will be asked for
+ your specific card in the following questions.
+
+if NET_VENDOR_ADAPTEC
+
+config ADAPTEC_STARFIRE
+ tristate "Adaptec Starfire/DuraLAN support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
+ adapter. The DuraLAN chip is used on the 64 bit PCI boards from
+ Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip
+ driver.
+
+ To compile this driver as a module, choose M here: the module
+ will be called starfire. This is recommended.
+
+endif # NET_VENDOR_ADAPTEC
diff --git a/drivers/net/ethernet/adaptec/Makefile b/drivers/net/ethernet/adaptec/Makefile
new file mode 100644
index 00000000000..6c07b758ac0
--- /dev/null
+++ b/drivers/net/ethernet/adaptec/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Adaptec network device drivers.
+#
+
+obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
diff --git a/drivers/net/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index 1d2ef8f4778..40dbbf74033 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -30,6 +30,7 @@
#define DRV_VERSION "2.1"
#define DRV_RELDATE "July 6, 2008"
+#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -42,11 +43,11 @@
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/mm.h>
+#include <linux/firmware.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/uaccess.h>
#include <asm/io.h>
-#include "starfire_firmware.h"
/*
* The current frame processor firmware fails to checksum a fragment
* of length 1. If and when this is fixed, the #define below can be removed.
@@ -113,15 +114,6 @@ static int rx_copybreak /* = 0 */;
#define DMA_BURST_SIZE 128
#endif
-/* Used to pass the media type, etc.
- Both 'options[]' and 'full_duplex[]' exist for driver interoperability.
- The media type is usually passed in 'options[]'.
- These variables are deprecated, use ethtool instead. -Ion
-*/
-#define MAX_UNITS 8 /* More are supported, limit only on options */
-static int options[MAX_UNITS] = {0, };
-static int full_duplex[MAX_UNITS] = {0, };
-
/* Operational parameters that are set at compile time. */
/* The "native" ring sizes are either 256 or 2048.
@@ -144,11 +136,7 @@ static int full_duplex[MAX_UNITS] = {0, };
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (2 * HZ)
-/*
- * This SUCKS.
- * We need a much better method to determine if dma_addr_t is 64-bit.
- */
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
/* 64-bit dma_addr_t */
#define ADDR_64BITS /* This chip uses 64 bit addresses. */
#define netdrv_addr_t __le64
@@ -173,15 +161,21 @@ static int full_duplex[MAX_UNITS] = {0, };
#define skb_first_frag_len(skb) skb_headlen(skb)
#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
+/* Firmware names */
+#define FIRMWARE_RX "adaptec/starfire_rx.bin"
+#define FIRMWARE_TX "adaptec/starfire_tx.bin"
+
/* These identify the driver base version and may not be removed. */
-static char version[] =
+static const char version[] =
KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
+" (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+MODULE_FIRMWARE(FIRMWARE_RX);
+MODULE_FIRMWARE(FIRMWARE_TX);
module_param(max_interrupt_work, int, 0);
module_param(mtu, int, 0);
@@ -189,8 +183,6 @@ module_param(debug, int, 0);
module_param(rx_copybreak, int, 0);
module_param(intr_latency, int, 0);
module_param(small_frames, int, 0);
-module_param_array(options, int, NULL, 0);
-module_param_array(full_duplex, int, NULL, 0);
module_param(enable_hw_cksum, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt");
MODULE_PARM_DESC(mtu, "MTU (all boards)");
@@ -198,8 +190,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-6)");
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
MODULE_PARM_DESC(intr_latency, "Maximum interrupt latency, in microseconds");
MODULE_PARM_DESC(small_frames, "Maximum size of receive frames that bypass interrupt latency (0,64,128,256,512)");
-MODULE_PARM_DESC(options, "Deprecated: Bits 0-3: media type, bit 17: full duplex");
-MODULE_PARM_DESC(full_duplex, "Deprecated: Forced full-duplex setting (0/1)");
MODULE_PARM_DESC(enable_hw_cksum, "Enable/disable hardware cksum support (0/1)");
/*
@@ -295,8 +285,8 @@ enum chipset {
CH_6915 = 0,
};
-static struct pci_device_id starfire_pci_tbl[] = {
- { 0x9004, 0x6915, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_6915 },
+static DEFINE_PCI_DEVICE_TABLE(starfire_pci_tbl) = {
+ { PCI_VDEVICE(ADAPTEC, 0x6915), CH_6915 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, starfire_pci_tbl);
@@ -305,7 +295,7 @@ MODULE_DEVICE_TABLE(pci, starfire_pci_tbl);
static const struct chip_info {
const char *name;
int drv_flags;
-} netdrv_tbl[] __devinitdata = {
+} netdrv_tbl[] = {
{ "Adaptec Starfire 6915", CanHaveMII },
};
@@ -556,10 +546,9 @@ struct netdev_private {
unsigned int tx_done;
struct napi_struct napi;
struct net_device *dev;
- struct net_device_stats stats;
struct pci_dev *pci_dev;
#ifdef VLAN_SUPPORT
- struct vlan_group *vlgrp;
+ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
#endif
void *queue_mem;
dma_addr_t queue_mem_dma;
@@ -589,7 +578,7 @@ static int netdev_open(struct net_device *dev);
static void check_duplex(struct net_device *dev);
static void tx_timeout(struct net_device *dev);
static void init_ring(struct net_device *dev);
-static int start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t intr_handler(int irq, void *dev_instance);
static void netdev_error(struct net_device *dev, int intr_status);
static int __netdev_rx(struct net_device *dev, int *quota);
@@ -605,55 +594,66 @@ static const struct ethtool_ops ethtool_ops;
#ifdef VLAN_SUPPORT
-static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
- struct netdev_private *np = netdev_priv(dev);
-
- spin_lock(&np->lock);
- if (debug > 2)
- printk("%s: Setting vlgrp to %p\n", dev->name, grp);
- np->vlgrp = grp;
- set_rx_mode(dev);
- spin_unlock(&np->lock);
-}
-
-static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+static int netdev_vlan_rx_add_vid(struct net_device *dev,
+ __be16 proto, u16 vid)
{
struct netdev_private *np = netdev_priv(dev);
spin_lock(&np->lock);
if (debug > 1)
printk("%s: Adding vlanid %d to vlan filter\n", dev->name, vid);
+ set_bit(vid, np->active_vlans);
set_rx_mode(dev);
spin_unlock(&np->lock);
+
+ return 0;
}
-static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+static int netdev_vlan_rx_kill_vid(struct net_device *dev,
+ __be16 proto, u16 vid)
{
struct netdev_private *np = netdev_priv(dev);
spin_lock(&np->lock);
if (debug > 1)
printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid);
- vlan_group_set_device(np->vlgrp, vid, NULL);
+ clear_bit(vid, np->active_vlans);
set_rx_mode(dev);
spin_unlock(&np->lock);
+
+ return 0;
}
#endif /* VLAN_SUPPORT */
-static int __devinit starfire_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = netdev_open,
+ .ndo_stop = netdev_close,
+ .ndo_start_xmit = start_tx,
+ .ndo_tx_timeout = tx_timeout,
+ .ndo_get_stats = get_stats,
+ .ndo_set_rx_mode = set_rx_mode,
+ .ndo_do_ioctl = netdev_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef VLAN_SUPPORT
+ .ndo_vlan_rx_add_vid = netdev_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = netdev_vlan_rx_kill_vid,
+#endif
+};
+
+static int starfire_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
+ struct device *d = &pdev->dev;
struct netdev_private *np;
- int i, irq, option, chip_idx = ent->driver_data;
+ int i, irq, chip_idx = ent->driver_data;
struct net_device *dev;
- static int card_idx = -1;
long ioaddr;
void __iomem *base;
int drv_flags, io_size;
int boguscnt;
- DECLARE_MAC_BUF(mac);
/* when built into the kernel, we only print version if device is found */
#ifndef MODULE
@@ -662,36 +662,33 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
printk(version);
#endif
- card_idx++;
-
if (pci_enable_device (pdev))
return -EIO;
ioaddr = pci_resource_start(pdev, 0);
io_size = pci_resource_len(pdev, 0);
if (!ioaddr || ((pci_resource_flags(pdev, 0) & IORESOURCE_MEM) == 0)) {
- printk(KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx);
+ dev_err(d, "no PCI MEM resources, aborting\n");
return -ENODEV;
}
dev = alloc_etherdev(sizeof(*np));
- if (!dev) {
- printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx);
+ if (!dev)
return -ENOMEM;
- }
+
SET_NETDEV_DEV(dev, &pdev->dev);
irq = pdev->irq;
if (pci_request_regions (pdev, DRV_NAME)) {
- printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);
+ dev_err(d, "cannot reserve PCI resources, aborting\n");
goto err_out_free_netdev;
}
base = ioremap(ioaddr, io_size);
if (!base) {
- printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n",
- card_idx, io_size, ioaddr);
+ dev_err(d, "cannot remap %#x @ %#lx, aborting\n",
+ io_size, ioaddr);
goto err_out_free_res;
}
@@ -705,11 +702,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
if (enable_hw_cksum)
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
#endif /* ZEROCOPY */
+
#ifdef VLAN_SUPPORT
- dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
- dev->vlan_rx_register = netdev_vlan_rx_register;
- dev->vlan_rx_add_vid = netdev_vlan_rx_add_vid;
- dev->vlan_rx_kill_vid = netdev_vlan_rx_kill_vid;
+ dev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER;
#endif /* VLAN_RX_KILL_VID */
#ifdef ADDR_64BITS
dev->features |= NETIF_F_HIGHDMA;
@@ -745,9 +740,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
/* wait a little longer */
udelay(1000);
- dev->base_addr = (unsigned long)base;
- dev->irq = irq;
-
np = netdev_priv(dev);
np->dev = dev;
np->base = base;
@@ -764,21 +756,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
drv_flags = netdrv_tbl[chip_idx].drv_flags;
- option = card_idx < MAX_UNITS ? options[card_idx] : 0;
- if (dev->mem_start)
- option = dev->mem_start;
-
- /* The lower four bits are the media type. */
- if (option & 0x200)
- np->mii_if.full_duplex = 1;
-
- if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
- np->mii_if.full_duplex = 1;
-
- if (np->mii_if.full_duplex)
- np->mii_if.force_media = 1;
- else
- np->mii_if.force_media = 0;
np->speed100 = 1;
/* timer resolution is 128 * 0.8us */
@@ -805,17 +782,11 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
}
}
- /* The chip-specific entries in the device structure. */
- dev->open = &netdev_open;
- dev->hard_start_xmit = &start_tx;
- dev->tx_timeout = tx_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
+ dev->ethtool_ops = &ethtool_ops;
+
netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work);
- dev->stop = &netdev_close;
- dev->get_stats = &get_stats;
- dev->set_multicast_list = &set_rx_mode;
- dev->do_ioctl = &netdev_ioctl;
- SET_ETHTOOL_OPS(dev, &ethtool_ops);
if (mtu)
dev->mtu = mtu;
@@ -823,9 +794,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
if (register_netdev(dev))
goto err_out_cleardev;
- printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n",
+ printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
dev->name, netdrv_tbl[chip_idx].name, base,
- print_mac(mac, dev->dev_addr), irq);
+ dev->dev_addr, irq);
if (drv_flags & CanHaveMII) {
int phy, phy_idx = 0;
@@ -864,7 +835,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
return 0;
err_out_cleardev:
- pci_set_drvdata(pdev, NULL);
iounmap(base);
err_out_free_res:
pci_release_regions (pdev);
@@ -881,9 +851,9 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
void __iomem *mdio_addr = np->base + MIICtrl + (phy_id<<7) + (location<<2);
int result, boguscnt=1000;
/* ??? Should we add a busy-wait here? */
- do
+ do {
result = readl(mdio_addr);
- while ((result & 0xC0000000) != 0x80000000 && --boguscnt > 0);
+ } while ((result & 0xC0000000) != 0x80000000 && --boguscnt > 0);
if (boguscnt == 0)
return 0;
if ((result & 0xffff) == 0xffff)
@@ -903,14 +873,18 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
static int netdev_open(struct net_device *dev)
{
+ const struct firmware *fw_rx, *fw_tx;
+ const __be32 *fw_rx_data, *fw_tx_data;
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
+ const int irq = np->pci_dev->irq;
int i, retval;
+ size_t tx_size, rx_size;
size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
/* Do we ever need to reset the chip??? */
- retval = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev);
+ retval = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
@@ -919,7 +893,7 @@ static int netdev_open(struct net_device *dev)
writel(1, ioaddr + PCIDeviceConfig);
if (debug > 1)
printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
- dev->name, dev->irq);
+ dev->name, irq);
/* Allocate the various queues. */
if (!np->queue_mem) {
@@ -930,7 +904,7 @@ static int netdev_open(struct net_device *dev)
np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
if (np->queue_mem == NULL) {
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
return -ENOMEM;
}
@@ -1041,11 +1015,40 @@ static int netdev_open(struct net_device *dev)
writel(ETH_P_8021Q, ioaddr + VlanType);
#endif /* VLAN_SUPPORT */
+ retval = request_firmware(&fw_rx, FIRMWARE_RX, &np->pci_dev->dev);
+ if (retval) {
+ printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
+ FIRMWARE_RX);
+ goto out_init;
+ }
+ if (fw_rx->size % 4) {
+ printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
+ fw_rx->size, FIRMWARE_RX);
+ retval = -EINVAL;
+ goto out_rx;
+ }
+ retval = request_firmware(&fw_tx, FIRMWARE_TX, &np->pci_dev->dev);
+ if (retval) {
+ printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
+ FIRMWARE_TX);
+ goto out_rx;
+ }
+ if (fw_tx->size % 4) {
+ printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
+ fw_tx->size, FIRMWARE_TX);
+ retval = -EINVAL;
+ goto out_tx;
+ }
+ fw_rx_data = (const __be32 *)&fw_rx->data[0];
+ fw_tx_data = (const __be32 *)&fw_tx->data[0];
+ rx_size = fw_rx->size / 4;
+ tx_size = fw_tx->size / 4;
+
/* Load Rx/Tx firmware into the frame processors */
- for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
- writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
- for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
- writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
+ for (i = 0; i < rx_size; i++)
+ writel(be32_to_cpup(&fw_rx_data[i]), ioaddr + RxGfpMem + i * 4);
+ for (i = 0; i < tx_size; i++)
+ writel(be32_to_cpup(&fw_tx_data[i]), ioaddr + TxGfpMem + i * 4);
if (enable_hw_cksum)
/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl);
@@ -1057,7 +1060,14 @@ static int netdev_open(struct net_device *dev)
printk(KERN_DEBUG "%s: Done netdev_open().\n",
dev->name);
- return 0;
+out_tx:
+ release_firmware(fw_tx);
+out_rx:
+ release_firmware(fw_rx);
+out_init:
+ if (retval)
+ netdev_close(dev);
+ return retval;
}
@@ -1119,8 +1129,8 @@ static void tx_timeout(struct net_device *dev)
/* Trigger an immediate transmit demand. */
- dev->trans_start = jiffies;
- np->stats.tx_errors++;
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ dev->stats.tx_errors++;
netif_wake_queue(dev);
}
@@ -1138,12 +1148,11 @@ static void init_ring(struct net_device *dev)
/* Fill in the Rx buffers. Handle allocation failure gracefully. */
for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+ struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz);
np->rx_info[i].skb = skb;
if (skb == NULL)
break;
np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
- skb->dev = dev; /* Mark as being used by this device. */
/* Grrr, we cannot offset to correctly align the IP header. */
np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
}
@@ -1167,12 +1176,10 @@ static void init_ring(struct net_device *dev)
for (i = 0; i < TX_RING_SIZE; i++)
memset(&np->tx_info[i], 0, sizeof(np->tx_info[i]));
-
- return;
}
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
unsigned int entry;
@@ -1185,7 +1192,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
*/
if ((np->cur_tx - np->dirty_tx) + skb_num_frags(skb) * 2 > TX_RING_SIZE) {
netif_stop_queue(dev);
- return 1;
+ return NETDEV_TX_BUSY;
}
#if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
@@ -1213,17 +1220,20 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
}
if (skb->ip_summed == CHECKSUM_PARTIAL) {
status |= TxCalTCP;
- np->stats.tx_compressed++;
+ dev->stats.tx_compressed++;
}
status |= skb_first_frag_len(skb) | (skb_num_frags(skb) << 16);
np->tx_info[entry].mapping =
pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
} else {
- skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1];
- status |= this_frag->size;
+ const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1];
+ status |= skb_frag_size(this_frag);
np->tx_info[entry].mapping =
- pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE);
+ pci_map_single(np->pci_dev,
+ skb_frag_address(this_frag),
+ skb_frag_size(this_frag),
+ PCI_DMA_TODEVICE);
}
np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping);
@@ -1258,9 +1268,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
if ((np->cur_tx - np->dirty_tx) + 4 > TX_RING_SIZE)
netif_stop_queue(dev);
- dev->trans_start = jiffies;
-
- return 0;
+ return NETDEV_TX_OK;
}
@@ -1291,8 +1299,8 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
if (intr_status & (IntrRxDone | IntrRxEmpty)) {
u32 enable;
- if (likely(netif_rx_schedule_prep(dev, &np->napi))) {
- __netif_rx_schedule(dev, &np->napi);
+ if (likely(napi_schedule_prep(&np->napi))) {
+ __napi_schedule(&np->napi);
enable = readl(ioaddr + IntrEnable);
enable &= ~(IntrRxDone | IntrRxEmpty);
writel(enable, ioaddr + IntrEnable);
@@ -1324,7 +1332,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
printk(KERN_DEBUG "%s: Tx completion #%d entry %d is %#8.8x.\n",
dev->name, np->dirty_tx, np->tx_done, tx_status);
if ((tx_status & 0xe0000000) == 0xa0000000) {
- np->stats.tx_packets++;
+ dev->stats.tx_packets++;
} else if ((tx_status & 0xe0000000) == 0x80000000) {
u16 entry = (tx_status & 0x7fff) / sizeof(starfire_tx_desc);
struct sk_buff *skb = np->tx_info[entry].skb;
@@ -1341,7 +1349,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
pci_unmap_single(np->pci_dev,
np->tx_info[entry].mapping,
- skb_shinfo(skb)->frags[i].size,
+ skb_frag_size(&skb_shinfo(skb)->frags[i]),
PCI_DMA_TODEVICE);
np->dirty_tx++;
entry++;
@@ -1412,9 +1420,9 @@ static int __netdev_rx(struct net_device *dev, int *quota)
/* There was an error. */
if (debug > 2)
printk(KERN_DEBUG " netdev_rx() Rx error was %#8.8x.\n", desc_status);
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
if (desc_status & RxFIFOErr)
- np->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
goto next_rx;
}
@@ -1431,8 +1439,8 @@ static int __netdev_rx(struct net_device *dev, int *quota)
printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d, quota %d.\n", pkt_len, *quota);
/* Check if the packet is long enough to accept without copying
to a minimally-sized skbuff. */
- if (pkt_len < rx_copybreak
- && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+ if (pkt_len < rx_copybreak &&
+ (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
skb_reserve(skb, 2); /* 16 byte align the IP header */
pci_dma_sync_single_for_cpu(np->pci_dev,
np->rx_info[entry].mapping,
@@ -1452,12 +1460,8 @@ static int __netdev_rx(struct net_device *dev, int *quota)
#ifndef final_version /* Remove after testing. */
/* You will want this info for the initial debug. */
if (debug > 5) {
- printk(KERN_DEBUG " Rx data " MAC_FMT " " MAC_FMT
- " %2.2x%2.2x.\n",
- skb->data[0], skb->data[1], skb->data[2],
- skb->data[3], skb->data[4], skb->data[5],
- skb->data[6], skb->data[7], skb->data[8],
- skb->data[9], skb->data[10], skb->data[11],
+ printk(KERN_DEBUG " Rx data %pM %pM %2.2x%2.2x.\n",
+ skb->data, skb->data + 6,
skb->data[12], skb->data[13]);
}
#endif
@@ -1469,7 +1473,7 @@ static int __netdev_rx(struct net_device *dev, int *quota)
#endif
if (le16_to_cpu(desc->status2) & 0x0100) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
- np->stats.rx_compressed++;
+ dev->stats.rx_compressed++;
}
/*
* This feature doesn't seem to be working, at least
@@ -1486,29 +1490,29 @@ static int __netdev_rx(struct net_device *dev, int *quota)
printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2));
}
#ifdef VLAN_SUPPORT
- if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
+ if (le16_to_cpu(desc->status2) & 0x0200) {
u16 vlid = le16_to_cpu(desc->vlanid);
if (debug > 4) {
printk(KERN_DEBUG " netdev_rx() vlanid = %d\n",
vlid);
}
- /*
- * vlan_hwaccel_rx expects a packet with the VLAN tag
- * stripped out.
- */
- vlan_hwaccel_rx(skb, np->vlgrp, vlid);
- } else
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlid);
+ }
#endif /* VLAN_SUPPORT */
- netif_receive_skb(skb);
- dev->last_rx = jiffies;
- np->stats.rx_packets++;
+ netif_receive_skb(skb);
+ dev->stats.rx_packets++;
next_rx:
np->cur_rx++;
desc->status = 0;
np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE;
}
+
+ if (*quota == 0) { /* out of rx quota */
+ retcode = 1;
+ goto out;
+ }
writew(np->rx_done, np->base + CompletionQConsumerIdx);
out:
@@ -1536,7 +1540,7 @@ static int netdev_poll(struct napi_struct *napi, int budget)
intr_status = readl(ioaddr + IntrStatus);
} while (intr_status & (IntrRxDone | IntrRxEmpty));
- netif_rx_complete(dev, napi);
+ napi_complete(napi);
intr_status = readl(ioaddr + IntrEnable);
intr_status |= IntrRxDone | IntrRxEmpty;
writel(intr_status, ioaddr + IntrEnable);
@@ -1560,13 +1564,12 @@ static void refill_rx_ring(struct net_device *dev)
for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
entry = np->dirty_rx % RX_RING_SIZE;
if (np->rx_info[entry].skb == NULL) {
- skb = dev_alloc_skb(np->rx_buf_sz);
+ skb = netdev_alloc_skb(dev, np->rx_buf_sz);
np->rx_info[entry].skb = skb;
if (skb == NULL)
break; /* Better luck next round. */
np->rx_info[entry].mapping =
pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
- skb->dev = dev; /* Mark as being used by this device. */
np->rx_ring[entry].rxaddr =
cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
}
@@ -1667,12 +1670,12 @@ static void netdev_error(struct net_device *dev, int intr_status)
printk(KERN_WARNING "%s: PCI Tx underflow -- adapter is probably malfunctioning\n", dev->name);
}
if (intr_status & IntrRxGFPDead) {
- np->stats.rx_fifo_errors++;
- np->stats.rx_errors++;
+ dev->stats.rx_fifo_errors++;
+ dev->stats.rx_errors++;
}
if (intr_status & (IntrNoTxCsum | IntrDMAErr)) {
- np->stats.tx_fifo_errors++;
- np->stats.tx_errors++;
+ dev->stats.tx_fifo_errors++;
+ dev->stats.tx_errors++;
}
if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrRxGFPDead | IntrNoTxCsum | IntrPCIPad)) && debug)
printk(KERN_ERR "%s: Something Wicked happened! %#8.8x.\n",
@@ -1686,78 +1689,83 @@ static struct net_device_stats *get_stats(struct net_device *dev)
void __iomem *ioaddr = np->base;
/* This adapter architecture needs no SMP locks. */
- np->stats.tx_bytes = readl(ioaddr + 0x57010);
- np->stats.rx_bytes = readl(ioaddr + 0x57044);
- np->stats.tx_packets = readl(ioaddr + 0x57000);
- np->stats.tx_aborted_errors =
+ dev->stats.tx_bytes = readl(ioaddr + 0x57010);
+ dev->stats.rx_bytes = readl(ioaddr + 0x57044);
+ dev->stats.tx_packets = readl(ioaddr + 0x57000);
+ dev->stats.tx_aborted_errors =
readl(ioaddr + 0x57024) + readl(ioaddr + 0x57028);
- np->stats.tx_window_errors = readl(ioaddr + 0x57018);
- np->stats.collisions =
+ dev->stats.tx_window_errors = readl(ioaddr + 0x57018);
+ dev->stats.collisions =
readl(ioaddr + 0x57004) + readl(ioaddr + 0x57008);
/* The chip only need report frame silently dropped. */
- np->stats.rx_dropped += readw(ioaddr + RxDMAStatus);
+ dev->stats.rx_dropped += readw(ioaddr + RxDMAStatus);
writew(0, ioaddr + RxDMAStatus);
- np->stats.rx_crc_errors = readl(ioaddr + 0x5703C);
- np->stats.rx_frame_errors = readl(ioaddr + 0x57040);
- np->stats.rx_length_errors = readl(ioaddr + 0x57058);
- np->stats.rx_missed_errors = readl(ioaddr + 0x5707C);
+ dev->stats.rx_crc_errors = readl(ioaddr + 0x5703C);
+ dev->stats.rx_frame_errors = readl(ioaddr + 0x57040);
+ dev->stats.rx_length_errors = readl(ioaddr + 0x57058);
+ dev->stats.rx_missed_errors = readl(ioaddr + 0x5707C);
- return &np->stats;
+ return &dev->stats;
}
+#ifdef VLAN_SUPPORT
+static u32 set_vlan_mode(struct netdev_private *np)
+{
+ u32 ret = VlanMode;
+ u16 vid;
+ void __iomem *filter_addr = np->base + HashTable + 8;
+ int vlan_count = 0;
+
+ for_each_set_bit(vid, np->active_vlans, VLAN_N_VID) {
+ if (vlan_count == 32)
+ break;
+ writew(vid, filter_addr);
+ filter_addr += 16;
+ vlan_count++;
+ }
+ if (vlan_count == 32) {
+ ret |= PerfectFilterVlan;
+ while (vlan_count < 32) {
+ writew(0, filter_addr);
+ filter_addr += 16;
+ vlan_count++;
+ }
+ }
+ return ret;
+}
+#endif /* VLAN_SUPPORT */
static void set_rx_mode(struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
u32 rx_mode = MinVLANPrio;
- struct dev_mc_list *mclist;
+ struct netdev_hw_addr *ha;
int i;
-#ifdef VLAN_SUPPORT
- rx_mode |= VlanMode;
- if (np->vlgrp) {
- int vlan_count = 0;
- void __iomem *filter_addr = ioaddr + HashTable + 8;
- for (i = 0; i < VLAN_VID_MASK; i++) {
- if (vlan_group_get_device(np->vlgrp, i)) {
- if (vlan_count >= 32)
- break;
- writew(i, filter_addr);
- filter_addr += 16;
- vlan_count++;
- }
- }
- if (i == VLAN_VID_MASK) {
- rx_mode |= PerfectFilterVlan;
- while (vlan_count < 32) {
- writew(0, filter_addr);
- filter_addr += 16;
- vlan_count++;
- }
- }
- }
+#ifdef VLAN_SUPPORT
+ rx_mode |= set_vlan_mode(np);
#endif /* VLAN_SUPPORT */
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
rx_mode |= AcceptAll;
- } else if ((dev->mc_count > multicast_filter_limit)
- || (dev->flags & IFF_ALLMULTI)) {
+ } else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
+ (dev->flags & IFF_ALLMULTI)) {
/* Too many to match, or accept all multicasts. */
rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter;
- } else if (dev->mc_count <= 14) {
+ } else if (netdev_mc_count(dev) <= 14) {
/* Use the 16 element perfect filter, skip first two entries. */
void __iomem *filter_addr = ioaddr + PerfFilterTable + 2 * 16;
__be16 *eaddrs;
- for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2;
- i++, mclist = mclist->next) {
- eaddrs = (__be16 *)mclist->dmi_addr;
+ netdev_for_each_mc_addr(ha, dev) {
+ eaddrs = (__be16 *) ha->addr;
writew(be16_to_cpu(eaddrs[2]), filter_addr); filter_addr += 4;
writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4;
writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 8;
}
eaddrs = (__be16 *)dev->dev_addr;
+ i = netdev_mc_count(dev) + 2;
while (i++ < 16) {
writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 4;
writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4;
@@ -1771,11 +1779,10 @@ static void set_rx_mode(struct net_device *dev)
__le16 mc_filter[32] __attribute__ ((aligned(sizeof(long)))); /* Multicast hash filter */
memset(mc_filter, 0, sizeof(mc_filter));
- for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
- i++, mclist = mclist->next) {
+ netdev_for_each_mc_addr(ha, dev) {
/* The chip uses the upper 9 CRC bits
as index into the hash table */
- int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23;
+ int bit_nr = ether_crc_le(ETH_ALEN, ha->addr) >> 23;
__le32 *fptr = (__le32 *) &mc_filter[(bit_nr >> 4) & ~1];
*fptr |= cpu_to_le32(1 << (bit_nr & 31));
@@ -1805,9 +1812,9 @@ static int check_if_running(struct net_device *dev)
static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct netdev_private *np = netdev_priv(dev);
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- strcpy(info->bus_info, pci_name(np->pci_dev));
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info));
}
static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -1924,7 +1931,7 @@ static int netdev_close(struct net_device *dev)
}
}
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
@@ -1984,7 +1991,7 @@ static int starfire_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-static void __devexit starfire_remove_one (struct pci_dev *pdev)
+static void starfire_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct netdev_private *np = netdev_priv(dev);
@@ -2004,7 +2011,6 @@ static void __devexit starfire_remove_one (struct pci_dev *pdev)
iounmap(np->base);
pci_release_regions(pdev);
- pci_set_drvdata(pdev, NULL);
free_netdev(dev); /* Will also free np!! */
}
@@ -2012,7 +2018,7 @@ static void __devexit starfire_remove_one (struct pci_dev *pdev)
static struct pci_driver starfire_driver = {
.name = DRV_NAME,
.probe = starfire_init_one,
- .remove = __devexit_p(starfire_remove_one),
+ .remove = starfire_remove_one,
#ifdef CONFIG_PM
.suspend = starfire_suspend,
.resume = starfire_resume,
@@ -2030,11 +2036,7 @@ static int __init starfire_init (void)
printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n");
#endif
- /* we can do this test only at run-time... sigh */
- if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) {
- printk("This driver has dma_addr_t issues, please send email to maintainer\n");
- return -ENODEV;
- }
+ BUILD_BUG_ON(sizeof(dma_addr_t) != sizeof(netdrv_addr_t));
return pci_register_driver(&starfire_driver);
}
diff --git a/drivers/net/ethernet/adi/Kconfig b/drivers/net/ethernet/adi/Kconfig
new file mode 100644
index 00000000000..f952fff6a9a
--- /dev/null
+++ b/drivers/net/ethernet/adi/Kconfig
@@ -0,0 +1,69 @@
+#
+# Blackfin device configuration
+#
+
+config NET_BFIN
+ bool "Blackfin devices"
+ depends on BF516 || BF518 || BF526 || BF527 || BF536 || BF537
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y.
+ Make sure you know the name of your card. Read the Ethernet-HOWTO,
+ available from <http://www.tldp.org/docs.html#howto>.
+
+ If unsure, say Y.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the remaining Blackfin card questions. If you say Y, you will be
+ asked for your specific card in the following questions.
+
+if NET_BFIN
+
+config BFIN_MAC
+ tristate "Blackfin on-chip MAC support"
+ depends on (BF516 || BF518 || BF526 || BF527 || BF536 || BF537)
+ select CRC32
+ select MII
+ select PHYLIB
+ select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
+ ---help---
+ This is the driver for Blackfin on-chip mac device. Say Y if you want
+ it compiled into the kernel. This driver is also available as a
+ module ( = code which can be inserted in and removed from the running
+ kernel whenever you want). The module will be called bfin_mac.
+
+config BFIN_MAC_USE_L1
+ bool "Use L1 memory for rx/tx packets"
+ depends on BFIN_MAC && (BF527 || BF537)
+ default y
+ ---help---
+ To get maximum network performance, you should use L1 memory as rx/tx
+ buffers. Say N here if you want to reserve L1 memory for other uses.
+
+config BFIN_TX_DESC_NUM
+ int "Number of transmit buffer packets"
+ depends on BFIN_MAC
+ range 6 10 if BFIN_MAC_USE_L1
+ range 10 100
+ default "10"
+ ---help---
+ Set the number of buffer packets used in driver.
+
+config BFIN_RX_DESC_NUM
+ int "Number of receive buffer packets"
+ depends on BFIN_MAC
+ range 20 100 if BFIN_MAC_USE_L1
+ range 20 800
+ default "20"
+ ---help---
+ Set the number of buffer packets used in driver.
+
+config BFIN_MAC_USE_HWSTAMP
+ bool "Use IEEE 1588 hwstamp"
+ depends on BFIN_MAC && BF518
+ select PTP_1588_CLOCK
+ default y
+ ---help---
+ To support the IEEE 1588 Precision Time Protocol (PTP), select y here
+
+endif # NET_BFIN
diff --git a/drivers/net/ethernet/adi/Makefile b/drivers/net/ethernet/adi/Makefile
new file mode 100644
index 00000000000..b1fbe195d0e
--- /dev/null
+++ b/drivers/net/ethernet/adi/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Blackfin device drivers.
+#
+
+obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
new file mode 100644
index 00000000000..7ae74d450e8
--- /dev/null
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -0,0 +1,1921 @@
+/*
+ * Blackfin On-Chip MAC Driver
+ *
+ * Copyright 2004-2010 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#define DRV_VERSION "1.1"
+#define DRV_DESC "Blackfin on-chip Ethernet MAC driver"
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/crc32.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+
+#include <asm/dma.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/div64.h>
+#include <asm/dpmc.h>
+#include <asm/blackfin.h>
+#include <asm/cacheflush.h>
+#include <asm/portmux.h>
+#include <mach/pll.h>
+
+#include "bfin_mac.h"
+
+MODULE_AUTHOR("Bryan Wu, Luke Yang");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_ALIAS("platform:bfin_mac");
+
+#if defined(CONFIG_BFIN_MAC_USE_L1)
+# define bfin_mac_alloc(dma_handle, size, num) l1_data_sram_zalloc(size*num)
+# define bfin_mac_free(dma_handle, ptr, num) l1_data_sram_free(ptr)
+#else
+# define bfin_mac_alloc(dma_handle, size, num) \
+ dma_alloc_coherent(NULL, size*num, dma_handle, GFP_KERNEL)
+# define bfin_mac_free(dma_handle, ptr, num) \
+ dma_free_coherent(NULL, sizeof(*ptr)*num, ptr, dma_handle)
+#endif
+
+#define PKT_BUF_SZ 1580
+
+#define MAX_TIMEOUT_CNT 500
+
+/* pointers to maintain transmit list */
+static struct net_dma_desc_tx *tx_list_head;
+static struct net_dma_desc_tx *tx_list_tail;
+static struct net_dma_desc_rx *rx_list_head;
+static struct net_dma_desc_rx *rx_list_tail;
+static struct net_dma_desc_rx *current_rx_ptr;
+static struct net_dma_desc_tx *current_tx_ptr;
+static struct net_dma_desc_tx *tx_desc;
+static struct net_dma_desc_rx *rx_desc;
+
+static void desc_list_free(void)
+{
+ struct net_dma_desc_rx *r;
+ struct net_dma_desc_tx *t;
+ int i;
+#if !defined(CONFIG_BFIN_MAC_USE_L1)
+ dma_addr_t dma_handle = 0;
+#endif
+
+ if (tx_desc) {
+ t = tx_list_head;
+ for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
+ if (t) {
+ if (t->skb) {
+ dev_kfree_skb(t->skb);
+ t->skb = NULL;
+ }
+ t = t->next;
+ }
+ }
+ bfin_mac_free(dma_handle, tx_desc, CONFIG_BFIN_TX_DESC_NUM);
+ }
+
+ if (rx_desc) {
+ r = rx_list_head;
+ for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
+ if (r) {
+ if (r->skb) {
+ dev_kfree_skb(r->skb);
+ r->skb = NULL;
+ }
+ r = r->next;
+ }
+ }
+ bfin_mac_free(dma_handle, rx_desc, CONFIG_BFIN_RX_DESC_NUM);
+ }
+}
+
+static int desc_list_init(struct net_device *dev)
+{
+ int i;
+ struct sk_buff *new_skb;
+#if !defined(CONFIG_BFIN_MAC_USE_L1)
+ /*
+ * This dma_handle is useless in Blackfin dma_alloc_coherent().
+ * The real dma handler is the return value of dma_alloc_coherent().
+ */
+ dma_addr_t dma_handle;
+#endif
+
+ tx_desc = bfin_mac_alloc(&dma_handle,
+ sizeof(struct net_dma_desc_tx),
+ CONFIG_BFIN_TX_DESC_NUM);
+ if (tx_desc == NULL)
+ goto init_error;
+
+ rx_desc = bfin_mac_alloc(&dma_handle,
+ sizeof(struct net_dma_desc_rx),
+ CONFIG_BFIN_RX_DESC_NUM);
+ if (rx_desc == NULL)
+ goto init_error;
+
+ /* init tx_list */
+ tx_list_head = tx_list_tail = tx_desc;
+
+ for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
+ struct net_dma_desc_tx *t = tx_desc + i;
+ struct dma_descriptor *a = &(t->desc_a);
+ struct dma_descriptor *b = &(t->desc_b);
+
+ /*
+ * disable DMA
+ * read from memory WNR = 0
+ * wordsize is 32 bits
+ * 6 half words is desc size
+ * large desc flow
+ */
+ a->config = WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
+ a->start_addr = (unsigned long)t->packet;
+ a->x_count = 0;
+ a->next_dma_desc = b;
+
+ /*
+ * enabled DMA
+ * write to memory WNR = 1
+ * wordsize is 32 bits
+ * disable interrupt
+ * 6 half words is desc size
+ * large desc flow
+ */
+ b->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
+ b->start_addr = (unsigned long)(&(t->status));
+ b->x_count = 0;
+
+ t->skb = NULL;
+ tx_list_tail->desc_b.next_dma_desc = a;
+ tx_list_tail->next = t;
+ tx_list_tail = t;
+ }
+ tx_list_tail->next = tx_list_head; /* tx_list is a circle */
+ tx_list_tail->desc_b.next_dma_desc = &(tx_list_head->desc_a);
+ current_tx_ptr = tx_list_head;
+
+ /* init rx_list */
+ rx_list_head = rx_list_tail = rx_desc;
+
+ for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
+ struct net_dma_desc_rx *r = rx_desc + i;
+ struct dma_descriptor *a = &(r->desc_a);
+ struct dma_descriptor *b = &(r->desc_b);
+
+ /* allocate a new skb for next time receive */
+ new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
+ if (!new_skb)
+ goto init_error;
+
+ skb_reserve(new_skb, NET_IP_ALIGN);
+ /* Invidate the data cache of skb->data range when it is write back
+ * cache. It will prevent overwritting the new data from DMA
+ */
+ blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
+ (unsigned long)new_skb->end);
+ r->skb = new_skb;
+
+ /*
+ * enabled DMA
+ * write to memory WNR = 1
+ * wordsize is 32 bits
+ * disable interrupt
+ * 6 half words is desc size
+ * large desc flow
+ */
+ a->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
+ /* since RXDWA is enabled */
+ a->start_addr = (unsigned long)new_skb->data - 2;
+ a->x_count = 0;
+ a->next_dma_desc = b;
+
+ /*
+ * enabled DMA
+ * write to memory WNR = 1
+ * wordsize is 32 bits
+ * enable interrupt
+ * 6 half words is desc size
+ * large desc flow
+ */
+ b->config = DMAEN | WNR | WDSIZE_32 | DI_EN |
+ NDSIZE_6 | DMAFLOW_LARGE;
+ b->start_addr = (unsigned long)(&(r->status));
+ b->x_count = 0;
+
+ rx_list_tail->desc_b.next_dma_desc = a;
+ rx_list_tail->next = r;
+ rx_list_tail = r;
+ }
+ rx_list_tail->next = rx_list_head; /* rx_list is a circle */
+ rx_list_tail->desc_b.next_dma_desc = &(rx_list_head->desc_a);
+ current_rx_ptr = rx_list_head;
+
+ return 0;
+
+init_error:
+ desc_list_free();
+ pr_err("kmalloc failed\n");
+ return -ENOMEM;
+}
+
+
+/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
+
+/*
+ * MII operations
+ */
+/* Wait until the previous MDC/MDIO transaction has completed */
+static int bfin_mdio_poll(void)
+{
+ int timeout_cnt = MAX_TIMEOUT_CNT;
+
+ /* poll the STABUSY bit */
+ while ((bfin_read_EMAC_STAADD()) & STABUSY) {
+ udelay(1);
+ if (timeout_cnt-- < 0) {
+ pr_err("wait MDC/MDIO transaction to complete timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+/* Read an off-chip register in a PHY through the MDC/MDIO port */
+static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
+{
+ int ret;
+
+ ret = bfin_mdio_poll();
+ if (ret)
+ return ret;
+
+ /* read mode */
+ bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
+ SET_REGAD((u16) regnum) |
+ STABUSY);
+
+ ret = bfin_mdio_poll();
+ if (ret)
+ return ret;
+
+ return (int) bfin_read_EMAC_STADAT();
+}
+
+/* Write an off-chip register in a PHY through the MDC/MDIO port */
+static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
+ u16 value)
+{
+ int ret;
+
+ ret = bfin_mdio_poll();
+ if (ret)
+ return ret;
+
+ bfin_write_EMAC_STADAT((u32) value);
+
+ /* write mode */
+ bfin_write_EMAC_STAADD(SET_PHYAD((u16) phy_addr) |
+ SET_REGAD((u16) regnum) |
+ STAOP |
+ STABUSY);
+
+ return bfin_mdio_poll();
+}
+
+static void bfin_mac_adjust_link(struct net_device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+ struct phy_device *phydev = lp->phydev;
+ unsigned long flags;
+ int new_state = 0;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ if (phydev->link) {
+ /* Now we make sure that we can be in full duplex mode.
+ * If not, we operate in half-duplex mode. */
+ if (phydev->duplex != lp->old_duplex) {
+ u32 opmode = bfin_read_EMAC_OPMODE();
+ new_state = 1;
+
+ if (phydev->duplex)
+ opmode |= FDMODE;
+ else
+ opmode &= ~(FDMODE);
+
+ bfin_write_EMAC_OPMODE(opmode);
+ lp->old_duplex = phydev->duplex;
+ }
+
+ if (phydev->speed != lp->old_speed) {
+ if (phydev->interface == PHY_INTERFACE_MODE_RMII) {
+ u32 opmode = bfin_read_EMAC_OPMODE();
+ switch (phydev->speed) {
+ case 10:
+ opmode |= RMII_10;
+ break;
+ case 100:
+ opmode &= ~RMII_10;
+ break;
+ default:
+ netdev_warn(dev,
+ "Ack! Speed (%d) is not 10/100!\n",
+ phydev->speed);
+ break;
+ }
+ bfin_write_EMAC_OPMODE(opmode);
+ }
+
+ new_state = 1;
+ lp->old_speed = phydev->speed;
+ }
+
+ if (!lp->old_link) {
+ new_state = 1;
+ lp->old_link = 1;
+ }
+ } else if (lp->old_link) {
+ new_state = 1;
+ lp->old_link = 0;
+ lp->old_speed = 0;
+ lp->old_duplex = -1;
+ }
+
+ if (new_state) {
+ u32 opmode = bfin_read_EMAC_OPMODE();
+ phy_print_status(phydev);
+ pr_debug("EMAC_OPMODE = 0x%08x\n", opmode);
+ }
+
+ spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+/* MDC = 2.5 MHz */
+#define MDC_CLK 2500000
+
+static int mii_probe(struct net_device *dev, int phy_mode)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+ struct phy_device *phydev = NULL;
+ unsigned short sysctl;
+ int i;
+ u32 sclk, mdc_div;
+
+ /* Enable PHY output early */
+ if (!(bfin_read_VR_CTL() & CLKBUFOE))
+ bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);
+
+ sclk = get_sclk();
+ mdc_div = ((sclk / MDC_CLK) / 2) - 1;
+
+ sysctl = bfin_read_EMAC_SYSCTL();
+ sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div);
+ bfin_write_EMAC_SYSCTL(sysctl);
+
+ /* search for connected PHY device */
+ for (i = 0; i < PHY_MAX_ADDR; ++i) {
+ struct phy_device *const tmp_phydev = lp->mii_bus->phy_map[i];
+
+ if (!tmp_phydev)
+ continue; /* no PHY here... */
+
+ phydev = tmp_phydev;
+ break; /* found it */
+ }
+
+ /* now we are supposed to have a proper phydev, to attach to... */
+ if (!phydev) {
+ netdev_err(dev, "no phy device found\n");
+ return -ENODEV;
+ }
+
+ if (phy_mode != PHY_INTERFACE_MODE_RMII &&
+ phy_mode != PHY_INTERFACE_MODE_MII) {
+ netdev_err(dev, "invalid phy interface mode\n");
+ return -EINVAL;
+ }
+
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
+ &bfin_mac_adjust_link, phy_mode);
+
+ if (IS_ERR(phydev)) {
+ netdev_err(dev, "could not attach PHY\n");
+ return PTR_ERR(phydev);
+ }
+
+ /* mask with MAC supported features */
+ phydev->supported &= (SUPPORTED_10baseT_Half
+ | SUPPORTED_10baseT_Full
+ | SUPPORTED_100baseT_Half
+ | SUPPORTED_100baseT_Full
+ | SUPPORTED_Autoneg
+ | SUPPORTED_Pause | SUPPORTED_Asym_Pause
+ | SUPPORTED_MII
+ | SUPPORTED_TP);
+
+ phydev->advertising = phydev->supported;
+
+ lp->old_link = 0;
+ lp->old_speed = 0;
+ lp->old_duplex = -1;
+ lp->phydev = phydev;
+
+ pr_info("attached PHY driver [%s] "
+ "(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)@sclk=%dMHz)\n",
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
+ MDC_CLK, mdc_div, sclk/1000000);
+
+ return 0;
+}
+
+/*
+ * Ethtool support
+ */
+
+/*
+ * interrupt routine for magic packet wakeup
+ */
+static irqreturn_t bfin_mac_wake_interrupt(int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+static int
+bfin_mac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+
+ if (lp->phydev)
+ return phy_ethtool_gset(lp->phydev, cmd);
+
+ return -EINVAL;
+}
+
+static int
+bfin_mac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (lp->phydev)
+ return phy_ethtool_sset(lp->phydev, cmd);
+
+ return -EINVAL;
+}
+
+static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
+ strlcpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info));
+}
+
+static void bfin_mac_ethtool_getwol(struct net_device *dev,
+ struct ethtool_wolinfo *wolinfo)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+
+ wolinfo->supported = WAKE_MAGIC;
+ wolinfo->wolopts = lp->wol;
+}
+
+static int bfin_mac_ethtool_setwol(struct net_device *dev,
+ struct ethtool_wolinfo *wolinfo)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+ int rc;
+
+ if (wolinfo->wolopts & (WAKE_MAGICSECURE |
+ WAKE_UCAST |
+ WAKE_MCAST |
+ WAKE_BCAST |
+ WAKE_ARP))
+ return -EOPNOTSUPP;
+
+ lp->wol = wolinfo->wolopts;
+
+ if (lp->wol && !lp->irq_wake_requested) {
+ /* register wake irq handler */
+ rc = request_irq(IRQ_MAC_WAKEDET, bfin_mac_wake_interrupt,
+ 0, "EMAC_WAKE", dev);
+ if (rc)
+ return rc;
+ lp->irq_wake_requested = true;
+ }
+
+ if (!lp->wol && lp->irq_wake_requested) {
+ free_irq(IRQ_MAC_WAKEDET, dev);
+ lp->irq_wake_requested = false;
+ }
+
+ /* Make sure the PHY driver doesn't suspend */
+ device_init_wakeup(&dev->dev, lp->wol);
+
+ return 0;
+}
+
+#ifdef CONFIG_BFIN_MAC_USE_HWSTAMP
+static int bfin_mac_ethtool_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->phc_index = lp->phc_index;
+ info->tx_types =
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
+ return 0;
+}
+#endif
+
+static const struct ethtool_ops bfin_mac_ethtool_ops = {
+ .get_settings = bfin_mac_ethtool_getsettings,
+ .set_settings = bfin_mac_ethtool_setsettings,
+ .get_link = ethtool_op_get_link,
+ .get_drvinfo = bfin_mac_ethtool_getdrvinfo,
+ .get_wol = bfin_mac_ethtool_getwol,
+ .set_wol = bfin_mac_ethtool_setwol,
+#ifdef CONFIG_BFIN_MAC_USE_HWSTAMP
+ .get_ts_info = bfin_mac_ethtool_get_ts_info,
+#endif
+};
+
+/**************************************************************************/
+static void setup_system_regs(struct net_device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+ int i;
+ unsigned short sysctl;
+
+ /*
+ * Odd word alignment for Receive Frame DMA word
+ * Configure checksum support and rcve frame word alignment
+ */
+ sysctl = bfin_read_EMAC_SYSCTL();
+ /*
+ * check if interrupt is requested for any PHY,
+ * enable PHY interrupt only if needed
+ */
+ for (i = 0; i < PHY_MAX_ADDR; ++i)
+ if (lp->mii_bus->irq[i] != PHY_POLL)
+ break;
+ if (i < PHY_MAX_ADDR)
+ sysctl |= PHYIE;
+ sysctl |= RXDWA;
+#if defined(BFIN_MAC_CSUM_OFFLOAD)
+ sysctl |= RXCKS;
+#else
+ sysctl &= ~RXCKS;
+#endif
+ bfin_write_EMAC_SYSCTL(sysctl);
+
+ bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
+
+ /* Set vlan regs to let 1522 bytes long packets pass through */
+ bfin_write_EMAC_VLAN1(lp->vlan1_mask);
+ bfin_write_EMAC_VLAN2(lp->vlan2_mask);
+
+ /* Initialize the TX DMA channel registers */
+ bfin_write_DMA2_X_COUNT(0);
+ bfin_write_DMA2_X_MODIFY(4);
+ bfin_write_DMA2_Y_COUNT(0);
+ bfin_write_DMA2_Y_MODIFY(0);
+
+ /* Initialize the RX DMA channel registers */
+ bfin_write_DMA1_X_COUNT(0);
+ bfin_write_DMA1_X_MODIFY(4);
+ bfin_write_DMA1_Y_COUNT(0);
+ bfin_write_DMA1_Y_MODIFY(0);
+}
+
+static void setup_mac_addr(u8 *mac_addr)
+{
+ u32 addr_low = le32_to_cpu(*(__le32 *) & mac_addr[0]);
+ u16 addr_hi = le16_to_cpu(*(__le16 *) & mac_addr[4]);
+
+ /* this depends on a little-endian machine */
+ bfin_write_EMAC_ADDRLO(addr_low);
+ bfin_write_EMAC_ADDRHI(addr_hi);
+}
+
+static int bfin_mac_set_mac_address(struct net_device *dev, void *p)
+{
+ struct sockaddr *addr = p;
+ if (netif_running(dev))
+ return -EBUSY;
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ setup_mac_addr(dev->dev_addr);
+ return 0;
+}
+
+#ifdef CONFIG_BFIN_MAC_USE_HWSTAMP
+#define bfin_mac_hwtstamp_is_none(cfg) ((cfg) == HWTSTAMP_FILTER_NONE)
+
+static u32 bfin_select_phc_clock(u32 input_clk, unsigned int *shift_result)
+{
+ u32 ipn = 1000000000UL / input_clk;
+ u32 ppn = 1;
+ unsigned int shift = 0;
+
+ while (ppn <= ipn) {
+ ppn <<= 1;
+ shift++;
+ }
+ *shift_result = shift;
+ return 1000000000UL / ppn;
+}
+
+static int bfin_mac_hwtstamp_set(struct net_device *netdev,
+ struct ifreq *ifr)
+{
+ struct hwtstamp_config config;
+ struct bfin_mac_local *lp = netdev_priv(netdev);
+ u16 ptpctl;
+ u32 ptpfv1, ptpfv2, ptpfv3, ptpfoff;
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ pr_debug("%s config flag:0x%x, tx_type:0x%x, rx_filter:0x%x\n",
+ __func__, config.flags, config.tx_type, config.rx_filter);
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ if ((config.tx_type != HWTSTAMP_TX_OFF) &&
+ (config.tx_type != HWTSTAMP_TX_ON))
+ return -ERANGE;
+
+ ptpctl = bfin_read_EMAC_PTP_CTL();
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ /*
+ * Dont allow any timestamping
+ */
+ ptpfv3 = 0xFFFFFFFF;
+ bfin_write_EMAC_PTP_FV3(ptpfv3);
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ /*
+ * Clear the five comparison mask bits (bits[12:8]) in EMAC_PTP_CTL)
+ * to enable all the field matches.
+ */
+ ptpctl &= ~0x1F00;
+ bfin_write_EMAC_PTP_CTL(ptpctl);
+ /*
+ * Keep the default values of the EMAC_PTP_FOFF register.
+ */
+ ptpfoff = 0x4A24170C;
+ bfin_write_EMAC_PTP_FOFF(ptpfoff);
+ /*
+ * Keep the default values of the EMAC_PTP_FV1 and EMAC_PTP_FV2
+ * registers.
+ */
+ ptpfv1 = 0x11040800;
+ bfin_write_EMAC_PTP_FV1(ptpfv1);
+ ptpfv2 = 0x0140013F;
+ bfin_write_EMAC_PTP_FV2(ptpfv2);
+ /*
+ * The default value (0xFFFC) allows the timestamping of both
+ * received Sync messages and Delay_Req messages.
+ */
+ ptpfv3 = 0xFFFFFFFC;
+ bfin_write_EMAC_PTP_FV3(ptpfv3);
+
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ /* Clear all five comparison mask bits (bits[12:8]) in the
+ * EMAC_PTP_CTL register to enable all the field matches.
+ */
+ ptpctl &= ~0x1F00;
+ bfin_write_EMAC_PTP_CTL(ptpctl);
+ /*
+ * Keep the default values of the EMAC_PTP_FOFF register, except set
+ * the PTPCOF field to 0x2A.
+ */
+ ptpfoff = 0x2A24170C;
+ bfin_write_EMAC_PTP_FOFF(ptpfoff);
+ /*
+ * Keep the default values of the EMAC_PTP_FV1 and EMAC_PTP_FV2
+ * registers.
+ */
+ ptpfv1 = 0x11040800;
+ bfin_write_EMAC_PTP_FV1(ptpfv1);
+ ptpfv2 = 0x0140013F;
+ bfin_write_EMAC_PTP_FV2(ptpfv2);
+ /*
+ * To allow the timestamping of Pdelay_Req and Pdelay_Resp, set
+ * the value to 0xFFF0.
+ */
+ ptpfv3 = 0xFFFFFFF0;
+ bfin_write_EMAC_PTP_FV3(ptpfv3);
+
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ /*
+ * Clear bits 8 and 12 of the EMAC_PTP_CTL register to enable only the
+ * EFTM and PTPCM field comparison.
+ */
+ ptpctl &= ~0x1100;
+ bfin_write_EMAC_PTP_CTL(ptpctl);
+ /*
+ * Keep the default values of all the fields of the EMAC_PTP_FOFF
+ * register, except set the PTPCOF field to 0x0E.
+ */
+ ptpfoff = 0x0E24170C;
+ bfin_write_EMAC_PTP_FOFF(ptpfoff);
+ /*
+ * Program bits [15:0] of the EMAC_PTP_FV1 register to 0x88F7, which
+ * corresponds to PTP messages on the MAC layer.
+ */
+ ptpfv1 = 0x110488F7;
+ bfin_write_EMAC_PTP_FV1(ptpfv1);
+ ptpfv2 = 0x0140013F;
+ bfin_write_EMAC_PTP_FV2(ptpfv2);
+ /*
+ * To allow the timestamping of Pdelay_Req and Pdelay_Resp
+ * messages, set the value to 0xFFF0.
+ */
+ ptpfv3 = 0xFFFFFFF0;
+ bfin_write_EMAC_PTP_FV3(ptpfv3);
+
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ if (config.tx_type == HWTSTAMP_TX_OFF &&
+ bfin_mac_hwtstamp_is_none(config.rx_filter)) {
+ ptpctl &= ~PTP_EN;
+ bfin_write_EMAC_PTP_CTL(ptpctl);
+
+ SSYNC();
+ } else {
+ ptpctl |= PTP_EN;
+ bfin_write_EMAC_PTP_CTL(ptpctl);
+
+ /*
+ * clear any existing timestamp
+ */
+ bfin_read_EMAC_PTP_RXSNAPLO();
+ bfin_read_EMAC_PTP_RXSNAPHI();
+
+ bfin_read_EMAC_PTP_TXSNAPLO();
+ bfin_read_EMAC_PTP_TXSNAPHI();
+
+ SSYNC();
+ }
+
+ lp->stamp_cfg = config;
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+static int bfin_mac_hwtstamp_get(struct net_device *netdev,
+ struct ifreq *ifr)
+{
+ struct bfin_mac_local *lp = netdev_priv(netdev);
+
+ return copy_to_user(ifr->ifr_data, &lp->stamp_cfg,
+ sizeof(lp->stamp_cfg)) ?
+ -EFAULT : 0;
+}
+
+static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
+{
+ struct bfin_mac_local *lp = netdev_priv(netdev);
+
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+ int timeout_cnt = MAX_TIMEOUT_CNT;
+
+ /* When doing time stamping, keep the connection to the socket
+ * a while longer
+ */
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
+ /*
+ * The timestamping is done at the EMAC module's MII/RMII interface
+ * when the module sees the Start of Frame of an event message packet. This
+ * interface is the closest possible place to the physical Ethernet transmission
+ * medium, providing the best timing accuracy.
+ */
+ while ((!(bfin_read_EMAC_PTP_ISTAT() & TXTL)) && (--timeout_cnt))
+ udelay(1);
+ if (timeout_cnt == 0)
+ netdev_err(netdev, "timestamp the TX packet failed\n");
+ else {
+ struct skb_shared_hwtstamps shhwtstamps;
+ u64 ns;
+ u64 regval;
+
+ regval = bfin_read_EMAC_PTP_TXSNAPLO();
+ regval |= (u64)bfin_read_EMAC_PTP_TXSNAPHI() << 32;
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ ns = regval << lp->shift;
+ shhwtstamps.hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, &shhwtstamps);
+ }
+ }
+}
+
+static void bfin_rx_hwtstamp(struct net_device *netdev, struct sk_buff *skb)
+{
+ struct bfin_mac_local *lp = netdev_priv(netdev);
+ u32 valid;
+ u64 regval, ns;
+ struct skb_shared_hwtstamps *shhwtstamps;
+
+ if (bfin_mac_hwtstamp_is_none(lp->stamp_cfg.rx_filter))
+ return;
+
+ valid = bfin_read_EMAC_PTP_ISTAT() & RXEL;
+ if (!valid)
+ return;
+
+ shhwtstamps = skb_hwtstamps(skb);
+
+ regval = bfin_read_EMAC_PTP_RXSNAPLO();
+ regval |= (u64)bfin_read_EMAC_PTP_RXSNAPHI() << 32;
+ ns = regval << lp->shift;
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+}
+
+static void bfin_mac_hwtstamp_init(struct net_device *netdev)
+{
+ struct bfin_mac_local *lp = netdev_priv(netdev);
+ u64 addend, ppb;
+ u32 input_clk, phc_clk;
+
+ /* Initialize hardware timer */
+ input_clk = get_sclk();
+ phc_clk = bfin_select_phc_clock(input_clk, &lp->shift);
+ addend = phc_clk * (1ULL << 32);
+ do_div(addend, input_clk);
+ bfin_write_EMAC_PTP_ADDEND((u32)addend);
+
+ lp->addend = addend;
+ ppb = 1000000000ULL * input_clk;
+ do_div(ppb, phc_clk);
+ lp->max_ppb = ppb - 1000000000ULL - 1ULL;
+
+ /* Initialize hwstamp config */
+ lp->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE;
+ lp->stamp_cfg.tx_type = HWTSTAMP_TX_OFF;
+}
+
+static u64 bfin_ptp_time_read(struct bfin_mac_local *lp)
+{
+ u64 ns;
+ u32 lo, hi;
+
+ lo = bfin_read_EMAC_PTP_TIMELO();
+ hi = bfin_read_EMAC_PTP_TIMEHI();
+
+ ns = ((u64) hi) << 32;
+ ns |= lo;
+ ns <<= lp->shift;
+
+ return ns;
+}
+
+static void bfin_ptp_time_write(struct bfin_mac_local *lp, u64 ns)
+{
+ u32 hi, lo;
+
+ ns >>= lp->shift;
+ hi = ns >> 32;
+ lo = ns & 0xffffffff;
+
+ bfin_write_EMAC_PTP_TIMELO(lo);
+ bfin_write_EMAC_PTP_TIMEHI(hi);
+}
+
+/* PTP Hardware Clock operations */
+
+static int bfin_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+ u64 adj;
+ u32 diff, addend;
+ int neg_adj = 0;
+ struct bfin_mac_local *lp =
+ container_of(ptp, struct bfin_mac_local, caps);
+
+ if (ppb < 0) {
+ neg_adj = 1;
+ ppb = -ppb;
+ }
+ addend = lp->addend;
+ adj = addend;
+ adj *= ppb;
+ diff = div_u64(adj, 1000000000ULL);
+
+ addend = neg_adj ? addend - diff : addend + diff;
+
+ bfin_write_EMAC_PTP_ADDEND(addend);
+
+ return 0;
+}
+
+static int bfin_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ s64 now;
+ unsigned long flags;
+ struct bfin_mac_local *lp =
+ container_of(ptp, struct bfin_mac_local, caps);
+
+ spin_lock_irqsave(&lp->phc_lock, flags);
+
+ now = bfin_ptp_time_read(lp);
+ now += delta;
+ bfin_ptp_time_write(lp, now);
+
+ spin_unlock_irqrestore(&lp->phc_lock, flags);
+
+ return 0;
+}
+
+static int bfin_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+ u64 ns;
+ u32 remainder;
+ unsigned long flags;
+ struct bfin_mac_local *lp =
+ container_of(ptp, struct bfin_mac_local, caps);
+
+ spin_lock_irqsave(&lp->phc_lock, flags);
+
+ ns = bfin_ptp_time_read(lp);
+
+ spin_unlock_irqrestore(&lp->phc_lock, flags);
+
+ ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
+ ts->tv_nsec = remainder;
+ return 0;
+}
+
+static int bfin_ptp_settime(struct ptp_clock_info *ptp,
+ const struct timespec *ts)
+{
+ u64 ns;
+ unsigned long flags;
+ struct bfin_mac_local *lp =
+ container_of(ptp, struct bfin_mac_local, caps);
+
+ ns = ts->tv_sec * 1000000000ULL;
+ ns += ts->tv_nsec;
+
+ spin_lock_irqsave(&lp->phc_lock, flags);
+
+ bfin_ptp_time_write(lp, ns);
+
+ spin_unlock_irqrestore(&lp->phc_lock, flags);
+
+ return 0;
+}
+
+static int bfin_ptp_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
+{
+ return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info bfin_ptp_caps = {
+ .owner = THIS_MODULE,
+ .name = "BF518 clock",
+ .max_adj = 0,
+ .n_alarm = 0,
+ .n_ext_ts = 0,
+ .n_per_out = 0,
+ .n_pins = 0,
+ .pps = 0,
+ .adjfreq = bfin_ptp_adjfreq,
+ .adjtime = bfin_ptp_adjtime,
+ .gettime = bfin_ptp_gettime,
+ .settime = bfin_ptp_settime,
+ .enable = bfin_ptp_enable,
+};
+
+static int bfin_phc_init(struct net_device *netdev, struct device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(netdev);
+
+ lp->caps = bfin_ptp_caps;
+ lp->caps.max_adj = lp->max_ppb;
+ lp->clock = ptp_clock_register(&lp->caps, dev);
+ if (IS_ERR(lp->clock))
+ return PTR_ERR(lp->clock);
+
+ lp->phc_index = ptp_clock_index(lp->clock);
+ spin_lock_init(&lp->phc_lock);
+
+ return 0;
+}
+
+static void bfin_phc_release(struct bfin_mac_local *lp)
+{
+ ptp_clock_unregister(lp->clock);
+}
+
+#else
+# define bfin_mac_hwtstamp_is_none(cfg) 0
+# define bfin_mac_hwtstamp_init(dev)
+# define bfin_mac_hwtstamp_set(dev, ifr) (-EOPNOTSUPP)
+# define bfin_mac_hwtstamp_get(dev, ifr) (-EOPNOTSUPP)
+# define bfin_rx_hwtstamp(dev, skb)
+# define bfin_tx_hwtstamp(dev, skb)
+# define bfin_phc_init(netdev, dev) 0
+# define bfin_phc_release(lp)
+#endif
+
+static inline void _tx_reclaim_skb(void)
+{
+ do {
+ tx_list_head->desc_a.config &= ~DMAEN;
+ tx_list_head->status.status_word = 0;
+ if (tx_list_head->skb) {
+ dev_consume_skb_any(tx_list_head->skb);
+ tx_list_head->skb = NULL;
+ }
+ tx_list_head = tx_list_head->next;
+
+ } while (tx_list_head->status.status_word != 0);
+}
+
+static void tx_reclaim_skb(struct bfin_mac_local *lp)
+{
+ int timeout_cnt = MAX_TIMEOUT_CNT;
+
+ if (tx_list_head->status.status_word != 0)
+ _tx_reclaim_skb();
+
+ if (current_tx_ptr->next == tx_list_head) {
+ while (tx_list_head->status.status_word == 0) {
+ /* slow down polling to avoid too many queue stop. */
+ udelay(10);
+ /* reclaim skb if DMA is not running. */
+ if (!(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN))
+ break;
+ if (timeout_cnt-- < 0)
+ break;
+ }
+
+ if (timeout_cnt >= 0)
+ _tx_reclaim_skb();
+ else
+ netif_stop_queue(lp->ndev);
+ }
+
+ if (current_tx_ptr->next != tx_list_head &&
+ netif_queue_stopped(lp->ndev))
+ netif_wake_queue(lp->ndev);
+
+ if (tx_list_head != current_tx_ptr) {
+ /* shorten the timer interval if tx queue is stopped */
+ if (netif_queue_stopped(lp->ndev))
+ lp->tx_reclaim_timer.expires =
+ jiffies + (TX_RECLAIM_JIFFIES >> 4);
+ else
+ lp->tx_reclaim_timer.expires =
+ jiffies + TX_RECLAIM_JIFFIES;
+
+ mod_timer(&lp->tx_reclaim_timer,
+ lp->tx_reclaim_timer.expires);
+ }
+
+ return;
+}
+
+static void tx_reclaim_skb_timeout(unsigned long lp)
+{
+ tx_reclaim_skb((struct bfin_mac_local *)lp);
+}
+
+static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+ u16 *data;
+ u32 data_align = (unsigned long)(skb->data) & 0x3;
+
+ current_tx_ptr->skb = skb;
+
+ if (data_align == 0x2) {
+ /* move skb->data to current_tx_ptr payload */
+ data = (u16 *)(skb->data) - 1;
+ *data = (u16)(skb->len);
+ /*
+ * When transmitting an Ethernet packet, the PTP_TSYNC module requires
+ * a DMA_Length_Word field associated with the packet. The lower 12 bits
+ * of this field are the length of the packet payload in bytes and the higher
+ * 4 bits are the timestamping enable field.
+ */
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+ *data |= 0x1000;
+
+ current_tx_ptr->desc_a.start_addr = (u32)data;
+ /* this is important! */
+ blackfin_dcache_flush_range((u32)data,
+ (u32)((u8 *)data + skb->len + 4));
+ } else {
+ *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
+ /* enable timestamping for the sent packet */
+ if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)
+ *((u16 *)(current_tx_ptr->packet)) |= 0x1000;
+ memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
+ skb->len);
+ current_tx_ptr->desc_a.start_addr =
+ (u32)current_tx_ptr->packet;
+ blackfin_dcache_flush_range(
+ (u32)current_tx_ptr->packet,
+ (u32)(current_tx_ptr->packet + skb->len + 2));
+ }
+
+ /* make sure the internal data buffers in the core are drained
+ * so that the DMA descriptors are completely written when the
+ * DMA engine goes to fetch them below
+ */
+ SSYNC();
+
+ /* always clear status buffer before start tx dma */
+ current_tx_ptr->status.status_word = 0;
+
+ /* enable this packet's dma */
+ current_tx_ptr->desc_a.config |= DMAEN;
+
+ /* tx dma is running, just return */
+ if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
+ goto out;
+
+ /* tx dma is not running */
+ bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
+ /* dma enabled, read from memory, size is 6 */
+ bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
+ /* Turn on the EMAC tx */
+ bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
+
+out:
+ bfin_tx_hwtstamp(dev, skb);
+
+ current_tx_ptr = current_tx_ptr->next;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += (skb->len);
+
+ tx_reclaim_skb(lp);
+
+ return NETDEV_TX_OK;
+}
+
+#define IP_HEADER_OFF 0
+#define RX_ERROR_MASK (RX_LONG | RX_ALIGN | RX_CRC | RX_LEN | \
+ RX_FRAG | RX_ADDR | RX_DMAO | RX_PHY | RX_LATE | RX_RANGE)
+
+static void bfin_mac_rx(struct net_device *dev)
+{
+ struct sk_buff *skb, *new_skb;
+ unsigned short len;
+ struct bfin_mac_local *lp __maybe_unused = netdev_priv(dev);
+#if defined(BFIN_MAC_CSUM_OFFLOAD)
+ unsigned int i;
+ unsigned char fcs[ETH_FCS_LEN + 1];
+#endif
+
+ /* check if frame status word reports an error condition
+ * we which case we simply drop the packet
+ */
+ if (current_rx_ptr->status.status_word & RX_ERROR_MASK) {
+ netdev_notice(dev, "rx: receive error - packet dropped\n");
+ dev->stats.rx_dropped++;
+ goto out;
+ }
+
+ /* allocate a new skb for next time receive */
+ skb = current_rx_ptr->skb;
+
+ new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
+ if (!new_skb) {
+ dev->stats.rx_dropped++;
+ goto out;
+ }
+ /* reserve 2 bytes for RXDWA padding */
+ skb_reserve(new_skb, NET_IP_ALIGN);
+ /* Invidate the data cache of skb->data range when it is write back
+ * cache. It will prevent overwritting the new data from DMA
+ */
+ blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
+ (unsigned long)new_skb->end);
+
+ current_rx_ptr->skb = new_skb;
+ current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
+
+ len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
+ /* Deduce Ethernet FCS length from Ethernet payload length */
+ len -= ETH_FCS_LEN;
+ skb_put(skb, len);
+
+ skb->protocol = eth_type_trans(skb, dev);
+
+ bfin_rx_hwtstamp(dev, skb);
+
+#if defined(BFIN_MAC_CSUM_OFFLOAD)
+ /* Checksum offloading only works for IPv4 packets with the standard IP header
+ * length of 20 bytes, because the blackfin MAC checksum calculation is
+ * based on that assumption. We must NOT use the calculated checksum if our
+ * IP version or header break that assumption.
+ */
+ if (skb->data[IP_HEADER_OFF] == 0x45) {
+ skb->csum = current_rx_ptr->status.ip_payload_csum;
+ /*
+ * Deduce Ethernet FCS from hardware generated IP payload checksum.
+ * IP checksum is based on 16-bit one's complement algorithm.
+ * To deduce a value from checksum is equal to add its inversion.
+ * If the IP payload len is odd, the inversed FCS should also
+ * begin from odd address and leave first byte zero.
+ */
+ if (skb->len % 2) {
+ fcs[0] = 0;
+ for (i = 0; i < ETH_FCS_LEN; i++)
+ fcs[i + 1] = ~skb->data[skb->len + i];
+ skb->csum = csum_partial(fcs, ETH_FCS_LEN + 1, skb->csum);
+ } else {
+ for (i = 0; i < ETH_FCS_LEN; i++)
+ fcs[i] = ~skb->data[skb->len + i];
+ skb->csum = csum_partial(fcs, ETH_FCS_LEN, skb->csum);
+ }
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ }
+#endif
+
+ netif_rx(skb);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
+out:
+ current_rx_ptr->status.status_word = 0x00000000;
+ current_rx_ptr = current_rx_ptr->next;
+}
+
+/* interrupt routine to handle rx and error signal */
+static irqreturn_t bfin_mac_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ int number = 0;
+
+get_one_packet:
+ if (current_rx_ptr->status.status_word == 0) {
+ /* no more new packet received */
+ if (number == 0) {
+ if (current_rx_ptr->next->status.status_word != 0) {
+ current_rx_ptr = current_rx_ptr->next;
+ goto real_rx;
+ }
+ }
+ bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() |
+ DMA_DONE | DMA_ERR);
+ return IRQ_HANDLED;
+ }
+
+real_rx:
+ bfin_mac_rx(dev);
+ number++;
+ goto get_one_packet;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void bfin_mac_poll(struct net_device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+
+ disable_irq(IRQ_MAC_RX);
+ bfin_mac_interrupt(IRQ_MAC_RX, dev);
+ tx_reclaim_skb(lp);
+ enable_irq(IRQ_MAC_RX);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+static void bfin_mac_disable(void)
+{
+ unsigned int opmode;
+
+ opmode = bfin_read_EMAC_OPMODE();
+ opmode &= (~RE);
+ opmode &= (~TE);
+ /* Turn off the EMAC */
+ bfin_write_EMAC_OPMODE(opmode);
+}
+
+/*
+ * Enable Interrupts, Receive, and Transmit
+ */
+static int bfin_mac_enable(struct phy_device *phydev)
+{
+ int ret;
+ u32 opmode;
+
+ pr_debug("%s\n", __func__);
+
+ /* Set RX DMA */
+ bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
+ bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config);
+
+ /* Wait MII done */
+ ret = bfin_mdio_poll();
+ if (ret)
+ return ret;
+
+ /* We enable only RX here */
+ /* ASTP : Enable Automatic Pad Stripping
+ PR : Promiscuous Mode for test
+ PSF : Receive frames with total length less than 64 bytes.
+ FDMODE : Full Duplex Mode
+ LB : Internal Loopback for test
+ RE : Receiver Enable */
+ opmode = bfin_read_EMAC_OPMODE();
+ if (opmode & FDMODE)
+ opmode |= PSF;
+ else
+ opmode |= DRO | DC | PSF;
+ opmode |= RE;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RMII) {
+ opmode |= RMII; /* For Now only 100MBit are supported */
+#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
+ if (__SILICON_REVISION__ < 3) {
+ /*
+ * This isn't publicly documented (fun times!), but in
+ * silicon <=0.2, the RX and TX pins are clocked together.
+ * So in order to recv, we must enable the transmit side
+ * as well. This will cause a spurious TX interrupt too,
+ * but we can easily consume that.
+ */
+ opmode |= TE;
+ }
+#endif
+ }
+
+ /* Turn on the EMAC rx */
+ bfin_write_EMAC_OPMODE(opmode);
+
+ return 0;
+}
+
+/* Our watchdog timed out. Called by the networking layer */
+static void bfin_mac_timeout(struct net_device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+
+ pr_debug("%s: %s\n", dev->name, __func__);
+
+ bfin_mac_disable();
+
+ del_timer(&lp->tx_reclaim_timer);
+
+ /* reset tx queue and free skb */
+ while (tx_list_head != current_tx_ptr) {
+ tx_list_head->desc_a.config &= ~DMAEN;
+ tx_list_head->status.status_word = 0;
+ if (tx_list_head->skb) {
+ dev_kfree_skb(tx_list_head->skb);
+ tx_list_head->skb = NULL;
+ }
+ tx_list_head = tx_list_head->next;
+ }
+
+ if (netif_queue_stopped(lp->ndev))
+ netif_wake_queue(lp->ndev);
+
+ bfin_mac_enable(lp->phydev);
+
+ /* We can accept TX packets again */
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ netif_wake_queue(dev);
+}
+
+static void bfin_mac_multicast_hash(struct net_device *dev)
+{
+ u32 emac_hashhi, emac_hashlo;
+ struct netdev_hw_addr *ha;
+ u32 crc;
+
+ emac_hashhi = emac_hashlo = 0;
+
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc(ETH_ALEN, ha->addr);
+ crc >>= 26;
+
+ if (crc & 0x20)
+ emac_hashhi |= 1 << (crc & 0x1f);
+ else
+ emac_hashlo |= 1 << (crc & 0x1f);
+ }
+
+ bfin_write_EMAC_HASHHI(emac_hashhi);
+ bfin_write_EMAC_HASHLO(emac_hashlo);
+}
+
+/*
+ * This routine will, depending on the values passed to it,
+ * either make it accept multicast packets, go into
+ * promiscuous mode (for TCPDUMP and cousins) or accept
+ * a select set of multicast packets
+ */
+static void bfin_mac_set_multicast_list(struct net_device *dev)
+{
+ u32 sysctl;
+
+ if (dev->flags & IFF_PROMISC) {
+ netdev_info(dev, "set promisc mode\n");
+ sysctl = bfin_read_EMAC_OPMODE();
+ sysctl |= PR;
+ bfin_write_EMAC_OPMODE(sysctl);
+ } else if (dev->flags & IFF_ALLMULTI) {
+ /* accept all multicast */
+ sysctl = bfin_read_EMAC_OPMODE();
+ sysctl |= PAM;
+ bfin_write_EMAC_OPMODE(sysctl);
+ } else if (!netdev_mc_empty(dev)) {
+ /* set up multicast hash table */
+ sysctl = bfin_read_EMAC_OPMODE();
+ sysctl |= HM;
+ bfin_write_EMAC_OPMODE(sysctl);
+ bfin_mac_multicast_hash(dev);
+ } else {
+ /* clear promisc or multicast mode */
+ sysctl = bfin_read_EMAC_OPMODE();
+ sysctl &= ~(RAF | PAM);
+ bfin_write_EMAC_OPMODE(sysctl);
+ }
+}
+
+static int bfin_mac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ struct bfin_mac_local *lp = netdev_priv(netdev);
+
+ if (!netif_running(netdev))
+ return -EINVAL;
+
+ switch (cmd) {
+ case SIOCSHWTSTAMP:
+ return bfin_mac_hwtstamp_set(netdev, ifr);
+ case SIOCGHWTSTAMP:
+ return bfin_mac_hwtstamp_get(netdev, ifr);
+ default:
+ if (lp->phydev)
+ return phy_mii_ioctl(lp->phydev, ifr, cmd);
+ else
+ return -EOPNOTSUPP;
+ }
+}
+
+/*
+ * this puts the device in an inactive state
+ */
+static void bfin_mac_shutdown(struct net_device *dev)
+{
+ /* Turn off the EMAC */
+ bfin_write_EMAC_OPMODE(0x00000000);
+ /* Turn off the EMAC RX DMA */
+ bfin_write_DMA1_CONFIG(0x0000);
+ bfin_write_DMA2_CONFIG(0x0000);
+}
+
+/*
+ * Open and Initialize the interface
+ *
+ * Set up everything, reset the card, etc..
+ */
+static int bfin_mac_open(struct net_device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+ int ret;
+ pr_debug("%s: %s\n", dev->name, __func__);
+
+ /*
+ * Check that the address is valid. If its not, refuse
+ * to bring the device up. The user must specify an
+ * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
+ */
+ if (!is_valid_ether_addr(dev->dev_addr)) {
+ netdev_warn(dev, "no valid ethernet hw addr\n");
+ return -EINVAL;
+ }
+
+ /* initial rx and tx list */
+ ret = desc_list_init(dev);
+ if (ret)
+ return ret;
+
+ phy_start(lp->phydev);
+ setup_system_regs(dev);
+ setup_mac_addr(dev->dev_addr);
+
+ bfin_mac_disable();
+ ret = bfin_mac_enable(lp->phydev);
+ if (ret)
+ return ret;
+ pr_debug("hardware init finished\n");
+
+ netif_start_queue(dev);
+ netif_carrier_on(dev);
+
+ return 0;
+}
+
+/*
+ * this makes the board clean up everything that it can
+ * and not talk to the outside world. Caused by
+ * an 'ifconfig ethX down'
+ */
+static int bfin_mac_close(struct net_device *dev)
+{
+ struct bfin_mac_local *lp = netdev_priv(dev);
+ pr_debug("%s: %s\n", dev->name, __func__);
+
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+
+ phy_stop(lp->phydev);
+ phy_write(lp->phydev, MII_BMCR, BMCR_PDOWN);
+
+ /* clear everything */
+ bfin_mac_shutdown(dev);
+
+ /* free the rx/tx buffers */
+ desc_list_free();
+
+ return 0;
+}
+
+static const struct net_device_ops bfin_mac_netdev_ops = {
+ .ndo_open = bfin_mac_open,
+ .ndo_stop = bfin_mac_close,
+ .ndo_start_xmit = bfin_mac_hard_start_xmit,
+ .ndo_set_mac_address = bfin_mac_set_mac_address,
+ .ndo_tx_timeout = bfin_mac_timeout,
+ .ndo_set_rx_mode = bfin_mac_set_multicast_list,
+ .ndo_do_ioctl = bfin_mac_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = bfin_mac_poll,
+#endif
+};
+
+static int bfin_mac_probe(struct platform_device *pdev)
+{
+ struct net_device *ndev;
+ struct bfin_mac_local *lp;
+ struct platform_device *pd;
+ struct bfin_mii_bus_platform_data *mii_bus_data;
+ int rc;
+
+ ndev = alloc_etherdev(sizeof(struct bfin_mac_local));
+ if (!ndev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ platform_set_drvdata(pdev, ndev);
+ lp = netdev_priv(ndev);
+ lp->ndev = ndev;
+
+ /* Grab the MAC address in the MAC */
+ *(__le32 *) (&(ndev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
+ *(__le16 *) (&(ndev->dev_addr[4])) = cpu_to_le16((u16) bfin_read_EMAC_ADDRHI());
+
+ /* probe mac */
+ /*todo: how to proble? which is revision_register */
+ bfin_write_EMAC_ADDRLO(0x12345678);
+ if (bfin_read_EMAC_ADDRLO() != 0x12345678) {
+ dev_err(&pdev->dev, "Cannot detect Blackfin on-chip ethernet MAC controller!\n");
+ rc = -ENODEV;
+ goto out_err_probe_mac;
+ }
+
+
+ /*
+ * Is it valid? (Did bootloader initialize it?)
+ * Grab the MAC from the board somehow
+ * this is done in the arch/blackfin/mach-bfxxx/boards/eth_mac.c
+ */
+ if (!is_valid_ether_addr(ndev->dev_addr)) {
+ if (bfin_get_ether_addr(ndev->dev_addr) ||
+ !is_valid_ether_addr(ndev->dev_addr)) {
+ /* Still not valid, get a random one */
+ netdev_warn(ndev, "Setting Ethernet MAC to a random one\n");
+ eth_hw_addr_random(ndev);
+ }
+ }
+
+ setup_mac_addr(ndev->dev_addr);
+
+ if (!dev_get_platdata(&pdev->dev)) {
+ dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n");
+ rc = -ENODEV;
+ goto out_err_probe_mac;
+ }
+ pd = dev_get_platdata(&pdev->dev);
+ lp->mii_bus = platform_get_drvdata(pd);
+ if (!lp->mii_bus) {
+ dev_err(&pdev->dev, "Cannot get mii_bus!\n");
+ rc = -ENODEV;
+ goto out_err_probe_mac;
+ }
+ lp->mii_bus->priv = ndev;
+ mii_bus_data = dev_get_platdata(&pd->dev);
+
+ rc = mii_probe(ndev, mii_bus_data->phy_mode);
+ if (rc) {
+ dev_err(&pdev->dev, "MII Probe failed!\n");
+ goto out_err_mii_probe;
+ }
+
+ lp->vlan1_mask = ETH_P_8021Q | mii_bus_data->vlan1_mask;
+ lp->vlan2_mask = ETH_P_8021Q | mii_bus_data->vlan2_mask;
+
+ /* Fill in the fields of the device structure with ethernet values. */
+ ether_setup(ndev);
+
+ ndev->netdev_ops = &bfin_mac_netdev_ops;
+ ndev->ethtool_ops = &bfin_mac_ethtool_ops;
+
+ init_timer(&lp->tx_reclaim_timer);
+ lp->tx_reclaim_timer.data = (unsigned long)lp;
+ lp->tx_reclaim_timer.function = tx_reclaim_skb_timeout;
+
+ spin_lock_init(&lp->lock);
+
+ /* now, enable interrupts */
+ /* register irq handler */
+ rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt,
+ 0, "EMAC_RX", ndev);
+ if (rc) {
+ dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n");
+ rc = -EBUSY;
+ goto out_err_request_irq;
+ }
+
+ rc = register_netdev(ndev);
+ if (rc) {
+ dev_err(&pdev->dev, "Cannot register net device!\n");
+ goto out_err_reg_ndev;
+ }
+
+ bfin_mac_hwtstamp_init(ndev);
+ rc = bfin_phc_init(ndev, &pdev->dev);
+ if (rc) {
+ dev_err(&pdev->dev, "Cannot register PHC device!\n");
+ goto out_err_phc;
+ }
+
+ /* now, print out the card info, in a short format.. */
+ netdev_info(ndev, "%s, Version %s\n", DRV_DESC, DRV_VERSION);
+
+ return 0;
+
+out_err_phc:
+out_err_reg_ndev:
+ free_irq(IRQ_MAC_RX, ndev);
+out_err_request_irq:
+out_err_mii_probe:
+ mdiobus_unregister(lp->mii_bus);
+ mdiobus_free(lp->mii_bus);
+out_err_probe_mac:
+ free_netdev(ndev);
+
+ return rc;
+}
+
+static int bfin_mac_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct bfin_mac_local *lp = netdev_priv(ndev);
+
+ bfin_phc_release(lp);
+
+ lp->mii_bus->priv = NULL;
+
+ unregister_netdev(ndev);
+
+ free_irq(IRQ_MAC_RX, ndev);
+
+ free_netdev(ndev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+ struct net_device *net_dev = platform_get_drvdata(pdev);
+ struct bfin_mac_local *lp = netdev_priv(net_dev);
+
+ if (lp->wol) {
+ bfin_write_EMAC_OPMODE((bfin_read_EMAC_OPMODE() & ~TE) | RE);
+ bfin_write_EMAC_WKUP_CTL(MPKE);
+ enable_irq_wake(IRQ_MAC_WAKEDET);
+ } else {
+ if (netif_running(net_dev))
+ bfin_mac_close(net_dev);
+ }
+
+ return 0;
+}
+
+static int bfin_mac_resume(struct platform_device *pdev)
+{
+ struct net_device *net_dev = platform_get_drvdata(pdev);
+ struct bfin_mac_local *lp = netdev_priv(net_dev);
+
+ if (lp->wol) {
+ bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
+ bfin_write_EMAC_WKUP_CTL(0);
+ disable_irq_wake(IRQ_MAC_WAKEDET);
+ } else {
+ if (netif_running(net_dev))
+ bfin_mac_open(net_dev);
+ }
+
+ return 0;
+}
+#else
+#define bfin_mac_suspend NULL
+#define bfin_mac_resume NULL
+#endif /* CONFIG_PM */
+
+static int bfin_mii_bus_probe(struct platform_device *pdev)
+{
+ struct mii_bus *miibus;
+ struct bfin_mii_bus_platform_data *mii_bus_pd;
+ const unsigned short *pin_req;
+ int rc, i;
+
+ mii_bus_pd = dev_get_platdata(&pdev->dev);
+ if (!mii_bus_pd) {
+ dev_err(&pdev->dev, "No peripherals in platform data!\n");
+ return -EINVAL;
+ }
+
+ /*
+ * We are setting up a network card,
+ * so set the GPIO pins to Ethernet mode
+ */
+ pin_req = mii_bus_pd->mac_peripherals;
+ rc = peripheral_request_list(pin_req, KBUILD_MODNAME);
+ if (rc) {
+ dev_err(&pdev->dev, "Requesting peripherals failed!\n");
+ return rc;
+ }
+
+ rc = -ENOMEM;
+ miibus = mdiobus_alloc();
+ if (miibus == NULL)
+ goto out_err_alloc;
+ miibus->read = bfin_mdiobus_read;
+ miibus->write = bfin_mdiobus_write;
+
+ miibus->parent = &pdev->dev;
+ miibus->name = "bfin_mii_bus";
+ miibus->phy_mask = mii_bus_pd->phy_mask;
+
+ snprintf(miibus->id, MII_BUS_ID_SIZE, "%s-%x",
+ pdev->name, pdev->id);
+ miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+ if (!miibus->irq)
+ goto out_err_irq_alloc;
+
+ for (i = rc; i < PHY_MAX_ADDR; ++i)
+ miibus->irq[i] = PHY_POLL;
+
+ rc = clamp(mii_bus_pd->phydev_number, 0, PHY_MAX_ADDR);
+ if (rc != mii_bus_pd->phydev_number)
+ dev_err(&pdev->dev, "Invalid number (%i) of phydevs\n",
+ mii_bus_pd->phydev_number);
+ for (i = 0; i < rc; ++i) {
+ unsigned short phyaddr = mii_bus_pd->phydev_data[i].addr;
+ if (phyaddr < PHY_MAX_ADDR)
+ miibus->irq[phyaddr] = mii_bus_pd->phydev_data[i].irq;
+ else
+ dev_err(&pdev->dev,
+ "Invalid PHY address %i for phydev %i\n",
+ phyaddr, i);
+ }
+
+ rc = mdiobus_register(miibus);
+ if (rc) {
+ dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
+ goto out_err_mdiobus_register;
+ }
+
+ platform_set_drvdata(pdev, miibus);
+ return 0;
+
+out_err_mdiobus_register:
+ kfree(miibus->irq);
+out_err_irq_alloc:
+ mdiobus_free(miibus);
+out_err_alloc:
+ peripheral_free_list(pin_req);
+
+ return rc;
+}
+
+static int bfin_mii_bus_remove(struct platform_device *pdev)
+{
+ struct mii_bus *miibus = platform_get_drvdata(pdev);
+ struct bfin_mii_bus_platform_data *mii_bus_pd =
+ dev_get_platdata(&pdev->dev);
+
+ mdiobus_unregister(miibus);
+ kfree(miibus->irq);
+ mdiobus_free(miibus);
+ peripheral_free_list(mii_bus_pd->mac_peripherals);
+
+ return 0;
+}
+
+static struct platform_driver bfin_mii_bus_driver = {
+ .probe = bfin_mii_bus_probe,
+ .remove = bfin_mii_bus_remove,
+ .driver = {
+ .name = "bfin_mii_bus",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver bfin_mac_driver = {
+ .probe = bfin_mac_probe,
+ .remove = bfin_mac_remove,
+ .resume = bfin_mac_resume,
+ .suspend = bfin_mac_suspend,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init bfin_mac_init(void)
+{
+ int ret;
+ ret = platform_driver_register(&bfin_mii_bus_driver);
+ if (!ret)
+ return platform_driver_register(&bfin_mac_driver);
+ return -ENODEV;
+}
+
+module_init(bfin_mac_init);
+
+static void __exit bfin_mac_cleanup(void)
+{
+ platform_driver_unregister(&bfin_mac_driver);
+ platform_driver_unregister(&bfin_mii_bus_driver);
+}
+
+module_exit(bfin_mac_cleanup);
+
diff --git a/drivers/net/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h
index beff51064ff..6dec86ac97c 100644
--- a/drivers/net/bfin_mac.h
+++ b/drivers/net/ethernet/adi/bfin_mac.h
@@ -7,8 +7,25 @@
*
* Licensed under the GPL-2 or later.
*/
+#ifndef _BFIN_MAC_H_
+#define _BFIN_MAC_H_
+#include <linux/net_tstamp.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/timer.h>
+#include <linux/etherdevice.h>
+#include <linux/bfin_mac.h>
+
+/*
+ * Disable hardware checksum for bug #5600 if writeback cache is
+ * enabled. Otherwize, corrupted RX packet will be sent up stack
+ * without error mark.
+ */
+#ifndef CONFIG_BFIN_EXTMEM_WRITEBACK
#define BFIN_MAC_CSUM_OFFLOAD
+#endif
+
+#define TX_RECLAIM_JIFFIES (HZ / 5)
struct dma_descriptor {
struct dma_descriptor *next_dma_desc;
@@ -57,16 +74,36 @@ struct bfin_mac_local {
*/
struct net_device_stats stats;
- unsigned char Mac[6]; /* MAC address of the board */
spinlock_t lock;
+ int wol; /* Wake On Lan */
+ int irq_wake_requested;
+ struct timer_list tx_reclaim_timer;
+ struct net_device *ndev;
+
+ /* Data for EMAC_VLAN1 regs */
+ u16 vlan1_mask, vlan2_mask;
+
/* MII and PHY stuffs */
int old_link; /* used by bf537_adjust_link */
int old_speed;
int old_duplex;
struct phy_device *phydev;
- struct mii_bus mii_bus;
+ struct mii_bus *mii_bus;
+
+#if defined(CONFIG_BFIN_MAC_USE_HWSTAMP)
+ u32 addend;
+ unsigned int shift;
+ s32 max_ppb;
+ struct hwtstamp_config stamp_cfg;
+ struct ptp_clock_info caps;
+ struct ptp_clock *clock;
+ int phc_index;
+ spinlock_t phc_lock; /* protects time lo/hi registers */
+#endif
};
-extern void bfin_get_ether_addr(char *addr);
+int bfin_get_ether_addr(char *addr);
+
+#endif
diff --git a/drivers/net/ethernet/aeroflex/Kconfig b/drivers/net/ethernet/aeroflex/Kconfig
new file mode 100644
index 00000000000..4f4a8d78fd5
--- /dev/null
+++ b/drivers/net/ethernet/aeroflex/Kconfig
@@ -0,0 +1,11 @@
+#
+# Aeroflex Gaisler network device configuration
+#
+
+config GRETH
+ tristate "Aeroflex Gaisler GRETH Ethernet MAC support"
+ depends on SPARC
+ select PHYLIB
+ select CRC32
+ ---help---
+ Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
diff --git a/drivers/net/ethernet/aeroflex/Makefile b/drivers/net/ethernet/aeroflex/Makefile
new file mode 100644
index 00000000000..6e62a679282
--- /dev/null
+++ b/drivers/net/ethernet/aeroflex/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Aeroflex Gaisler network device drivers.
+#
+
+obj-$(CONFIG_GRETH) += greth.o
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
new file mode 100644
index 00000000000..23578dfee24
--- /dev/null
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -0,0 +1,1607 @@
+/*
+ * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC.
+ *
+ * 2005-2010 (c) Aeroflex Gaisler AB
+ *
+ * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs
+ * available in the GRLIB VHDL IP core library.
+ *
+ * Full documentation of both cores can be found here:
+ * http://www.gaisler.com/products/grlib/grip.pdf
+ *
+ * The Gigabit version supports scatter/gather DMA, any alignment of
+ * buffers and checksum offloading.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Contributors: Kristoffer Glembo
+ * Daniel Hellstrom
+ * Marko Isomaki
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/io.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+#include <asm/byteorder.h>
+
+#ifdef CONFIG_SPARC
+#include <asm/idprom.h>
+#endif
+
+#include "greth.h"
+
+#define GRETH_DEF_MSG_ENABLE \
+ (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_IFDOWN | \
+ NETIF_MSG_IFUP | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR)
+
+static int greth_debug = -1; /* -1 == use GRETH_DEF_MSG_ENABLE as value */
+module_param(greth_debug, int, 0);
+MODULE_PARM_DESC(greth_debug, "GRETH bitmapped debugging message enable value");
+
+/* Accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
+static int macaddr[6];
+module_param_array(macaddr, int, NULL, 0);
+MODULE_PARM_DESC(macaddr, "GRETH Ethernet MAC address");
+
+static int greth_edcl = 1;
+module_param(greth_edcl, int, 0);
+MODULE_PARM_DESC(greth_edcl, "GRETH EDCL usage indicator. Set to 1 if EDCL is used.");
+
+static int greth_open(struct net_device *dev);
+static netdev_tx_t greth_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+static netdev_tx_t greth_start_xmit_gbit(struct sk_buff *skb,
+ struct net_device *dev);
+static int greth_rx(struct net_device *dev, int limit);
+static int greth_rx_gbit(struct net_device *dev, int limit);
+static void greth_clean_tx(struct net_device *dev);
+static void greth_clean_tx_gbit(struct net_device *dev);
+static irqreturn_t greth_interrupt(int irq, void *dev_id);
+static int greth_close(struct net_device *dev);
+static int greth_set_mac_add(struct net_device *dev, void *p);
+static void greth_set_multicast_list(struct net_device *dev);
+
+#define GRETH_REGLOAD(a) (be32_to_cpu(__raw_readl(&(a))))
+#define GRETH_REGSAVE(a, v) (__raw_writel(cpu_to_be32(v), &(a)))
+#define GRETH_REGORIN(a, v) (GRETH_REGSAVE(a, (GRETH_REGLOAD(a) | (v))))
+#define GRETH_REGANDIN(a, v) (GRETH_REGSAVE(a, (GRETH_REGLOAD(a) & (v))))
+
+#define NEXT_TX(N) (((N) + 1) & GRETH_TXBD_NUM_MASK)
+#define SKIP_TX(N, C) (((N) + C) & GRETH_TXBD_NUM_MASK)
+#define NEXT_RX(N) (((N) + 1) & GRETH_RXBD_NUM_MASK)
+
+static void greth_print_rx_packet(void *addr, int len)
+{
+ print_hex_dump(KERN_DEBUG, "RX: ", DUMP_PREFIX_OFFSET, 16, 1,
+ addr, len, true);
+}
+
+static void greth_print_tx_packet(struct sk_buff *skb)
+{
+ int i;
+ int length;
+
+ if (skb_shinfo(skb)->nr_frags == 0)
+ length = skb->len;
+ else
+ length = skb_headlen(skb);
+
+ print_hex_dump(KERN_DEBUG, "TX: ", DUMP_PREFIX_OFFSET, 16, 1,
+ skb->data, length, true);
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+
+ print_hex_dump(KERN_DEBUG, "TX: ", DUMP_PREFIX_OFFSET, 16, 1,
+ skb_frag_address(&skb_shinfo(skb)->frags[i]),
+ skb_shinfo(skb)->frags[i].size, true);
+ }
+}
+
+static inline void greth_enable_tx(struct greth_private *greth)
+{
+ wmb();
+ GRETH_REGORIN(greth->regs->control, GRETH_TXEN);
+}
+
+static inline void greth_disable_tx(struct greth_private *greth)
+{
+ GRETH_REGANDIN(greth->regs->control, ~GRETH_TXEN);
+}
+
+static inline void greth_enable_rx(struct greth_private *greth)
+{
+ wmb();
+ GRETH_REGORIN(greth->regs->control, GRETH_RXEN);
+}
+
+static inline void greth_disable_rx(struct greth_private *greth)
+{
+ GRETH_REGANDIN(greth->regs->control, ~GRETH_RXEN);
+}
+
+static inline void greth_enable_irqs(struct greth_private *greth)
+{
+ GRETH_REGORIN(greth->regs->control, GRETH_RXI | GRETH_TXI);
+}
+
+static inline void greth_disable_irqs(struct greth_private *greth)
+{
+ GRETH_REGANDIN(greth->regs->control, ~(GRETH_RXI|GRETH_TXI));
+}
+
+static inline void greth_write_bd(u32 *bd, u32 val)
+{
+ __raw_writel(cpu_to_be32(val), bd);
+}
+
+static inline u32 greth_read_bd(u32 *bd)
+{
+ return be32_to_cpu(__raw_readl(bd));
+}
+
+static void greth_clean_rings(struct greth_private *greth)
+{
+ int i;
+ struct greth_bd *rx_bdp = greth->rx_bd_base;
+ struct greth_bd *tx_bdp = greth->tx_bd_base;
+
+ if (greth->gbit_mac) {
+
+ /* Free and unmap RX buffers */
+ for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) {
+ if (greth->rx_skbuff[i] != NULL) {
+ dev_kfree_skb(greth->rx_skbuff[i]);
+ dma_unmap_single(greth->dev,
+ greth_read_bd(&rx_bdp->addr),
+ MAX_FRAME_SIZE+NET_IP_ALIGN,
+ DMA_FROM_DEVICE);
+ }
+ }
+
+ /* TX buffers */
+ while (greth->tx_free < GRETH_TXBD_NUM) {
+
+ struct sk_buff *skb = greth->tx_skbuff[greth->tx_last];
+ int nr_frags = skb_shinfo(skb)->nr_frags;
+ tx_bdp = greth->tx_bd_base + greth->tx_last;
+ greth->tx_last = NEXT_TX(greth->tx_last);
+
+ dma_unmap_single(greth->dev,
+ greth_read_bd(&tx_bdp->addr),
+ skb_headlen(skb),
+ DMA_TO_DEVICE);
+
+ for (i = 0; i < nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ tx_bdp = greth->tx_bd_base + greth->tx_last;
+
+ dma_unmap_page(greth->dev,
+ greth_read_bd(&tx_bdp->addr),
+ skb_frag_size(frag),
+ DMA_TO_DEVICE);
+
+ greth->tx_last = NEXT_TX(greth->tx_last);
+ }
+ greth->tx_free += nr_frags+1;
+ dev_kfree_skb(skb);
+ }
+
+
+ } else { /* 10/100 Mbps MAC */
+
+ for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) {
+ kfree(greth->rx_bufs[i]);
+ dma_unmap_single(greth->dev,
+ greth_read_bd(&rx_bdp->addr),
+ MAX_FRAME_SIZE,
+ DMA_FROM_DEVICE);
+ }
+ for (i = 0; i < GRETH_TXBD_NUM; i++, tx_bdp++) {
+ kfree(greth->tx_bufs[i]);
+ dma_unmap_single(greth->dev,
+ greth_read_bd(&tx_bdp->addr),
+ MAX_FRAME_SIZE,
+ DMA_TO_DEVICE);
+ }
+ }
+}
+
+static int greth_init_rings(struct greth_private *greth)
+{
+ struct sk_buff *skb;
+ struct greth_bd *rx_bd, *tx_bd;
+ u32 dma_addr;
+ int i;
+
+ rx_bd = greth->rx_bd_base;
+ tx_bd = greth->tx_bd_base;
+
+ /* Initialize descriptor rings and buffers */
+ if (greth->gbit_mac) {
+
+ for (i = 0; i < GRETH_RXBD_NUM; i++) {
+ skb = netdev_alloc_skb(greth->netdev, MAX_FRAME_SIZE+NET_IP_ALIGN);
+ if (skb == NULL) {
+ if (netif_msg_ifup(greth))
+ dev_err(greth->dev, "Error allocating DMA ring.\n");
+ goto cleanup;
+ }
+ skb_reserve(skb, NET_IP_ALIGN);
+ dma_addr = dma_map_single(greth->dev,
+ skb->data,
+ MAX_FRAME_SIZE+NET_IP_ALIGN,
+ DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(greth->dev, dma_addr)) {
+ if (netif_msg_ifup(greth))
+ dev_err(greth->dev, "Could not create initial DMA mapping\n");
+ goto cleanup;
+ }
+ greth->rx_skbuff[i] = skb;
+ greth_write_bd(&rx_bd[i].addr, dma_addr);
+ greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE);
+ }
+
+ } else {
+
+ /* 10/100 MAC uses a fixed set of buffers and copy to/from SKBs */
+ for (i = 0; i < GRETH_RXBD_NUM; i++) {
+
+ greth->rx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL);
+
+ if (greth->rx_bufs[i] == NULL) {
+ if (netif_msg_ifup(greth))
+ dev_err(greth->dev, "Error allocating DMA ring.\n");
+ goto cleanup;
+ }
+
+ dma_addr = dma_map_single(greth->dev,
+ greth->rx_bufs[i],
+ MAX_FRAME_SIZE,
+ DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(greth->dev, dma_addr)) {
+ if (netif_msg_ifup(greth))
+ dev_err(greth->dev, "Could not create initial DMA mapping\n");
+ goto cleanup;
+ }
+ greth_write_bd(&rx_bd[i].addr, dma_addr);
+ greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE);
+ }
+ for (i = 0; i < GRETH_TXBD_NUM; i++) {
+
+ greth->tx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL);
+
+ if (greth->tx_bufs[i] == NULL) {
+ if (netif_msg_ifup(greth))
+ dev_err(greth->dev, "Error allocating DMA ring.\n");
+ goto cleanup;
+ }
+
+ dma_addr = dma_map_single(greth->dev,
+ greth->tx_bufs[i],
+ MAX_FRAME_SIZE,
+ DMA_TO_DEVICE);
+
+ if (dma_mapping_error(greth->dev, dma_addr)) {
+ if (netif_msg_ifup(greth))
+ dev_err(greth->dev, "Could not create initial DMA mapping\n");
+ goto cleanup;
+ }
+ greth_write_bd(&tx_bd[i].addr, dma_addr);
+ greth_write_bd(&tx_bd[i].stat, 0);
+ }
+ }
+ greth_write_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat,
+ greth_read_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat) | GRETH_BD_WR);
+
+ /* Initialize pointers. */
+ greth->rx_cur = 0;
+ greth->tx_next = 0;
+ greth->tx_last = 0;
+ greth->tx_free = GRETH_TXBD_NUM;
+
+ /* Initialize descriptor base address */
+ GRETH_REGSAVE(greth->regs->tx_desc_p, greth->tx_bd_base_phys);
+ GRETH_REGSAVE(greth->regs->rx_desc_p, greth->rx_bd_base_phys);
+
+ return 0;
+
+cleanup:
+ greth_clean_rings(greth);
+ return -ENOMEM;
+}
+
+static int greth_open(struct net_device *dev)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ int err;
+
+ err = greth_init_rings(greth);
+ if (err) {
+ if (netif_msg_ifup(greth))
+ dev_err(&dev->dev, "Could not allocate memory for DMA rings\n");
+ return err;
+ }
+
+ err = request_irq(greth->irq, greth_interrupt, 0, "eth", (void *) dev);
+ if (err) {
+ if (netif_msg_ifup(greth))
+ dev_err(&dev->dev, "Could not allocate interrupt %d\n", dev->irq);
+ greth_clean_rings(greth);
+ return err;
+ }
+
+ if (netif_msg_ifup(greth))
+ dev_dbg(&dev->dev, " starting queue\n");
+ netif_start_queue(dev);
+
+ GRETH_REGSAVE(greth->regs->status, 0xFF);
+
+ napi_enable(&greth->napi);
+
+ greth_enable_irqs(greth);
+ greth_enable_tx(greth);
+ greth_enable_rx(greth);
+ return 0;
+
+}
+
+static int greth_close(struct net_device *dev)
+{
+ struct greth_private *greth = netdev_priv(dev);
+
+ napi_disable(&greth->napi);
+
+ greth_disable_irqs(greth);
+ greth_disable_tx(greth);
+ greth_disable_rx(greth);
+
+ netif_stop_queue(dev);
+
+ free_irq(greth->irq, (void *) dev);
+
+ greth_clean_rings(greth);
+
+ return 0;
+}
+
+static netdev_tx_t
+greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ struct greth_bd *bdp;
+ int err = NETDEV_TX_OK;
+ u32 status, dma_addr, ctrl;
+ unsigned long flags;
+
+ /* Clean TX Ring */
+ greth_clean_tx(greth->netdev);
+
+ if (unlikely(greth->tx_free <= 0)) {
+ spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/
+ ctrl = GRETH_REGLOAD(greth->regs->control);
+ /* Enable TX IRQ only if not already in poll() routine */
+ if (ctrl & GRETH_RXI)
+ GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
+ netif_stop_queue(dev);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (netif_msg_pktdata(greth))
+ greth_print_tx_packet(skb);
+
+
+ if (unlikely(skb->len > MAX_FRAME_SIZE)) {
+ dev->stats.tx_errors++;
+ goto out;
+ }
+
+ bdp = greth->tx_bd_base + greth->tx_next;
+ dma_addr = greth_read_bd(&bdp->addr);
+
+ memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len);
+
+ dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE);
+
+ status = GRETH_BD_EN | GRETH_BD_IE | (skb->len & GRETH_BD_LEN);
+ greth->tx_bufs_length[greth->tx_next] = skb->len & GRETH_BD_LEN;
+
+ /* Wrap around descriptor ring */
+ if (greth->tx_next == GRETH_TXBD_NUM_MASK) {
+ status |= GRETH_BD_WR;
+ }
+
+ greth->tx_next = NEXT_TX(greth->tx_next);
+ greth->tx_free--;
+
+ /* Write descriptor control word and enable transmission */
+ greth_write_bd(&bdp->stat, status);
+ spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
+ greth_enable_tx(greth);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+
+out:
+ dev_kfree_skb(skb);
+ return err;
+}
+
+
+static netdev_tx_t
+greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ struct greth_bd *bdp;
+ u32 status = 0, dma_addr, ctrl;
+ int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
+ unsigned long flags;
+
+ nr_frags = skb_shinfo(skb)->nr_frags;
+
+ /* Clean TX Ring */
+ greth_clean_tx_gbit(dev);
+
+ if (greth->tx_free < nr_frags + 1) {
+ spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/
+ ctrl = GRETH_REGLOAD(greth->regs->control);
+ /* Enable TX IRQ only if not already in poll() routine */
+ if (ctrl & GRETH_RXI)
+ GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
+ netif_stop_queue(dev);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+ err = NETDEV_TX_BUSY;
+ goto out;
+ }
+
+ if (netif_msg_pktdata(greth))
+ greth_print_tx_packet(skb);
+
+ if (unlikely(skb->len > MAX_FRAME_SIZE)) {
+ dev->stats.tx_errors++;
+ goto out;
+ }
+
+ /* Save skb pointer. */
+ greth->tx_skbuff[greth->tx_next] = skb;
+
+ /* Linear buf */
+ if (nr_frags != 0)
+ status = GRETH_TXBD_MORE;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ status |= GRETH_TXBD_CSALL;
+ status |= skb_headlen(skb) & GRETH_BD_LEN;
+ if (greth->tx_next == GRETH_TXBD_NUM_MASK)
+ status |= GRETH_BD_WR;
+
+
+ bdp = greth->tx_bd_base + greth->tx_next;
+ greth_write_bd(&bdp->stat, status);
+ dma_addr = dma_map_single(greth->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
+
+ if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
+ goto map_error;
+
+ greth_write_bd(&bdp->addr, dma_addr);
+
+ curr_tx = NEXT_TX(greth->tx_next);
+
+ /* Frags */
+ for (i = 0; i < nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ greth->tx_skbuff[curr_tx] = NULL;
+ bdp = greth->tx_bd_base + curr_tx;
+
+ status = GRETH_BD_EN;
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ status |= GRETH_TXBD_CSALL;
+ status |= skb_frag_size(frag) & GRETH_BD_LEN;
+
+ /* Wrap around descriptor ring */
+ if (curr_tx == GRETH_TXBD_NUM_MASK)
+ status |= GRETH_BD_WR;
+
+ /* More fragments left */
+ if (i < nr_frags - 1)
+ status |= GRETH_TXBD_MORE;
+ else
+ status |= GRETH_BD_IE; /* enable IRQ on last fragment */
+
+ greth_write_bd(&bdp->stat, status);
+
+ dma_addr = skb_frag_dma_map(greth->dev, frag, 0, skb_frag_size(frag),
+ DMA_TO_DEVICE);
+
+ if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
+ goto frag_map_error;
+
+ greth_write_bd(&bdp->addr, dma_addr);
+
+ curr_tx = NEXT_TX(curr_tx);
+ }
+
+ wmb();
+
+ /* Enable the descriptor chain by enabling the first descriptor */
+ bdp = greth->tx_bd_base + greth->tx_next;
+ greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
+ greth->tx_next = curr_tx;
+ greth->tx_free -= nr_frags + 1;
+
+ wmb();
+
+ spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
+ greth_enable_tx(greth);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+
+ return NETDEV_TX_OK;
+
+frag_map_error:
+ /* Unmap SKB mappings that succeeded and disable descriptor */
+ for (i = 0; greth->tx_next + i != curr_tx; i++) {
+ bdp = greth->tx_bd_base + greth->tx_next + i;
+ dma_unmap_single(greth->dev,
+ greth_read_bd(&bdp->addr),
+ greth_read_bd(&bdp->stat) & GRETH_BD_LEN,
+ DMA_TO_DEVICE);
+ greth_write_bd(&bdp->stat, 0);
+ }
+map_error:
+ if (net_ratelimit())
+ dev_warn(greth->dev, "Could not create TX DMA mapping\n");
+ dev_kfree_skb(skb);
+out:
+ return err;
+}
+
+static irqreturn_t greth_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct greth_private *greth;
+ u32 status, ctrl;
+ irqreturn_t retval = IRQ_NONE;
+
+ greth = netdev_priv(dev);
+
+ spin_lock(&greth->devlock);
+
+ /* Get the interrupt events that caused us to be here. */
+ status = GRETH_REGLOAD(greth->regs->status);
+
+ /* Must see if interrupts are enabled also, INT_TX|INT_RX flags may be
+ * set regardless of whether IRQ is enabled or not. Especially
+ * important when shared IRQ.
+ */
+ ctrl = GRETH_REGLOAD(greth->regs->control);
+
+ /* Handle rx and tx interrupts through poll */
+ if (((status & (GRETH_INT_RE | GRETH_INT_RX)) && (ctrl & GRETH_RXI)) ||
+ ((status & (GRETH_INT_TE | GRETH_INT_TX)) && (ctrl & GRETH_TXI))) {
+ retval = IRQ_HANDLED;
+
+ /* Disable interrupts and schedule poll() */
+ greth_disable_irqs(greth);
+ napi_schedule(&greth->napi);
+ }
+
+ mmiowb();
+ spin_unlock(&greth->devlock);
+
+ return retval;
+}
+
+static void greth_clean_tx(struct net_device *dev)
+{
+ struct greth_private *greth;
+ struct greth_bd *bdp;
+ u32 stat;
+
+ greth = netdev_priv(dev);
+
+ while (1) {
+ bdp = greth->tx_bd_base + greth->tx_last;
+ GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
+ mb();
+ stat = greth_read_bd(&bdp->stat);
+
+ if (unlikely(stat & GRETH_BD_EN))
+ break;
+
+ if (greth->tx_free == GRETH_TXBD_NUM)
+ break;
+
+ /* Check status for errors */
+ if (unlikely(stat & GRETH_TXBD_STATUS)) {
+ dev->stats.tx_errors++;
+ if (stat & GRETH_TXBD_ERR_AL)
+ dev->stats.tx_aborted_errors++;
+ if (stat & GRETH_TXBD_ERR_UE)
+ dev->stats.tx_fifo_errors++;
+ }
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += greth->tx_bufs_length[greth->tx_last];
+ greth->tx_last = NEXT_TX(greth->tx_last);
+ greth->tx_free++;
+ }
+
+ if (greth->tx_free > 0) {
+ netif_wake_queue(dev);
+ }
+
+}
+
+static inline void greth_update_tx_stats(struct net_device *dev, u32 stat)
+{
+ /* Check status for errors */
+ if (unlikely(stat & GRETH_TXBD_STATUS)) {
+ dev->stats.tx_errors++;
+ if (stat & GRETH_TXBD_ERR_AL)
+ dev->stats.tx_aborted_errors++;
+ if (stat & GRETH_TXBD_ERR_UE)
+ dev->stats.tx_fifo_errors++;
+ if (stat & GRETH_TXBD_ERR_LC)
+ dev->stats.tx_aborted_errors++;
+ }
+ dev->stats.tx_packets++;
+}
+
+static void greth_clean_tx_gbit(struct net_device *dev)
+{
+ struct greth_private *greth;
+ struct greth_bd *bdp, *bdp_last_frag;
+ struct sk_buff *skb;
+ u32 stat;
+ int nr_frags, i;
+
+ greth = netdev_priv(dev);
+
+ while (greth->tx_free < GRETH_TXBD_NUM) {
+
+ skb = greth->tx_skbuff[greth->tx_last];
+
+ nr_frags = skb_shinfo(skb)->nr_frags;
+
+ /* We only clean fully completed SKBs */
+ bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags);
+
+ GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
+ mb();
+ stat = greth_read_bd(&bdp_last_frag->stat);
+
+ if (stat & GRETH_BD_EN)
+ break;
+
+ greth->tx_skbuff[greth->tx_last] = NULL;
+
+ greth_update_tx_stats(dev, stat);
+ dev->stats.tx_bytes += skb->len;
+
+ bdp = greth->tx_bd_base + greth->tx_last;
+
+ greth->tx_last = NEXT_TX(greth->tx_last);
+
+ dma_unmap_single(greth->dev,
+ greth_read_bd(&bdp->addr),
+ skb_headlen(skb),
+ DMA_TO_DEVICE);
+
+ for (i = 0; i < nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ bdp = greth->tx_bd_base + greth->tx_last;
+
+ dma_unmap_page(greth->dev,
+ greth_read_bd(&bdp->addr),
+ skb_frag_size(frag),
+ DMA_TO_DEVICE);
+
+ greth->tx_last = NEXT_TX(greth->tx_last);
+ }
+ greth->tx_free += nr_frags+1;
+ dev_kfree_skb(skb);
+ }
+
+ if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS+1)))
+ netif_wake_queue(dev);
+}
+
+static int greth_rx(struct net_device *dev, int limit)
+{
+ struct greth_private *greth;
+ struct greth_bd *bdp;
+ struct sk_buff *skb;
+ int pkt_len;
+ int bad, count;
+ u32 status, dma_addr;
+ unsigned long flags;
+
+ greth = netdev_priv(dev);
+
+ for (count = 0; count < limit; ++count) {
+
+ bdp = greth->rx_bd_base + greth->rx_cur;
+ GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
+ mb();
+ status = greth_read_bd(&bdp->stat);
+
+ if (unlikely(status & GRETH_BD_EN)) {
+ break;
+ }
+
+ dma_addr = greth_read_bd(&bdp->addr);
+ bad = 0;
+
+ /* Check status for errors. */
+ if (unlikely(status & GRETH_RXBD_STATUS)) {
+ if (status & GRETH_RXBD_ERR_FT) {
+ dev->stats.rx_length_errors++;
+ bad = 1;
+ }
+ if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) {
+ dev->stats.rx_frame_errors++;
+ bad = 1;
+ }
+ if (status & GRETH_RXBD_ERR_CRC) {
+ dev->stats.rx_crc_errors++;
+ bad = 1;
+ }
+ }
+ if (unlikely(bad)) {
+ dev->stats.rx_errors++;
+
+ } else {
+
+ pkt_len = status & GRETH_BD_LEN;
+
+ skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN);
+
+ if (unlikely(skb == NULL)) {
+
+ if (net_ratelimit())
+ dev_warn(&dev->dev, "low on memory - " "packet dropped\n");
+
+ dev->stats.rx_dropped++;
+
+ } else {
+ skb_reserve(skb, NET_IP_ALIGN);
+
+ dma_sync_single_for_cpu(greth->dev,
+ dma_addr,
+ pkt_len,
+ DMA_FROM_DEVICE);
+
+ if (netif_msg_pktdata(greth))
+ greth_print_rx_packet(phys_to_virt(dma_addr), pkt_len);
+
+ memcpy(skb_put(skb, pkt_len), phys_to_virt(dma_addr), pkt_len);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ dev->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ netif_receive_skb(skb);
+ }
+ }
+
+ status = GRETH_BD_EN | GRETH_BD_IE;
+ if (greth->rx_cur == GRETH_RXBD_NUM_MASK) {
+ status |= GRETH_BD_WR;
+ }
+
+ wmb();
+ greth_write_bd(&bdp->stat, status);
+
+ dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE);
+
+ spin_lock_irqsave(&greth->devlock, flags); /* save from XMIT */
+ greth_enable_rx(greth);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+
+ greth->rx_cur = NEXT_RX(greth->rx_cur);
+ }
+
+ return count;
+}
+
+static inline int hw_checksummed(u32 status)
+{
+
+ if (status & GRETH_RXBD_IP_FRAG)
+ return 0;
+
+ if (status & GRETH_RXBD_IP && status & GRETH_RXBD_IP_CSERR)
+ return 0;
+
+ if (status & GRETH_RXBD_UDP && status & GRETH_RXBD_UDP_CSERR)
+ return 0;
+
+ if (status & GRETH_RXBD_TCP && status & GRETH_RXBD_TCP_CSERR)
+ return 0;
+
+ return 1;
+}
+
+static int greth_rx_gbit(struct net_device *dev, int limit)
+{
+ struct greth_private *greth;
+ struct greth_bd *bdp;
+ struct sk_buff *skb, *newskb;
+ int pkt_len;
+ int bad, count = 0;
+ u32 status, dma_addr;
+ unsigned long flags;
+
+ greth = netdev_priv(dev);
+
+ for (count = 0; count < limit; ++count) {
+
+ bdp = greth->rx_bd_base + greth->rx_cur;
+ skb = greth->rx_skbuff[greth->rx_cur];
+ GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
+ mb();
+ status = greth_read_bd(&bdp->stat);
+ bad = 0;
+
+ if (status & GRETH_BD_EN)
+ break;
+
+ /* Check status for errors. */
+ if (unlikely(status & GRETH_RXBD_STATUS)) {
+
+ if (status & GRETH_RXBD_ERR_FT) {
+ dev->stats.rx_length_errors++;
+ bad = 1;
+ } else if (status &
+ (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE | GRETH_RXBD_ERR_LE)) {
+ dev->stats.rx_frame_errors++;
+ bad = 1;
+ } else if (status & GRETH_RXBD_ERR_CRC) {
+ dev->stats.rx_crc_errors++;
+ bad = 1;
+ }
+ }
+
+ /* Allocate new skb to replace current, not needed if the
+ * current skb can be reused */
+ if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) {
+ skb_reserve(newskb, NET_IP_ALIGN);
+
+ dma_addr = dma_map_single(greth->dev,
+ newskb->data,
+ MAX_FRAME_SIZE + NET_IP_ALIGN,
+ DMA_FROM_DEVICE);
+
+ if (!dma_mapping_error(greth->dev, dma_addr)) {
+ /* Process the incoming frame. */
+ pkt_len = status & GRETH_BD_LEN;
+
+ dma_unmap_single(greth->dev,
+ greth_read_bd(&bdp->addr),
+ MAX_FRAME_SIZE + NET_IP_ALIGN,
+ DMA_FROM_DEVICE);
+
+ if (netif_msg_pktdata(greth))
+ greth_print_rx_packet(phys_to_virt(greth_read_bd(&bdp->addr)), pkt_len);
+
+ skb_put(skb, pkt_len);
+
+ if (dev->features & NETIF_F_RXCSUM && hw_checksummed(status))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb_checksum_none_assert(skb);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+ netif_receive_skb(skb);
+
+ greth->rx_skbuff[greth->rx_cur] = newskb;
+ greth_write_bd(&bdp->addr, dma_addr);
+ } else {
+ if (net_ratelimit())
+ dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n");
+ dev_kfree_skb(newskb);
+ /* reusing current skb, so it is a drop */
+ dev->stats.rx_dropped++;
+ }
+ } else if (bad) {
+ /* Bad Frame transfer, the skb is reused */
+ dev->stats.rx_dropped++;
+ } else {
+ /* Failed Allocating a new skb. This is rather stupid
+ * but the current "filled" skb is reused, as if
+ * transfer failure. One could argue that RX descriptor
+ * table handling should be divided into cleaning and
+ * filling as the TX part of the driver
+ */
+ if (net_ratelimit())
+ dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n");
+ /* reusing current skb, so it is a drop */
+ dev->stats.rx_dropped++;
+ }
+
+ status = GRETH_BD_EN | GRETH_BD_IE;
+ if (greth->rx_cur == GRETH_RXBD_NUM_MASK) {
+ status |= GRETH_BD_WR;
+ }
+
+ wmb();
+ greth_write_bd(&bdp->stat, status);
+ spin_lock_irqsave(&greth->devlock, flags);
+ greth_enable_rx(greth);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+ greth->rx_cur = NEXT_RX(greth->rx_cur);
+ }
+
+ return count;
+
+}
+
+static int greth_poll(struct napi_struct *napi, int budget)
+{
+ struct greth_private *greth;
+ int work_done = 0;
+ unsigned long flags;
+ u32 mask, ctrl;
+ greth = container_of(napi, struct greth_private, napi);
+
+restart_txrx_poll:
+ if (netif_queue_stopped(greth->netdev)) {
+ if (greth->gbit_mac)
+ greth_clean_tx_gbit(greth->netdev);
+ else
+ greth_clean_tx(greth->netdev);
+ }
+
+ if (greth->gbit_mac) {
+ work_done += greth_rx_gbit(greth->netdev, budget - work_done);
+ } else {
+ work_done += greth_rx(greth->netdev, budget - work_done);
+ }
+
+ if (work_done < budget) {
+
+ spin_lock_irqsave(&greth->devlock, flags);
+
+ ctrl = GRETH_REGLOAD(greth->regs->control);
+ if (netif_queue_stopped(greth->netdev)) {
+ GRETH_REGSAVE(greth->regs->control,
+ ctrl | GRETH_TXI | GRETH_RXI);
+ mask = GRETH_INT_RX | GRETH_INT_RE |
+ GRETH_INT_TX | GRETH_INT_TE;
+ } else {
+ GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI);
+ mask = GRETH_INT_RX | GRETH_INT_RE;
+ }
+
+ if (GRETH_REGLOAD(greth->regs->status) & mask) {
+ GRETH_REGSAVE(greth->regs->control, ctrl);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+ goto restart_txrx_poll;
+ } else {
+ __napi_complete(napi);
+ spin_unlock_irqrestore(&greth->devlock, flags);
+ }
+ }
+
+ return work_done;
+}
+
+static int greth_set_mac_add(struct net_device *dev, void *p)
+{
+ struct sockaddr *addr = p;
+ struct greth_private *greth;
+ struct greth_regs *regs;
+
+ greth = netdev_priv(dev);
+ regs = greth->regs;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+ GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 |
+ dev->dev_addr[4] << 8 | dev->dev_addr[5]);
+
+ return 0;
+}
+
+static u32 greth_hash_get_index(__u8 *addr)
+{
+ return (ether_crc(6, addr)) & 0x3F;
+}
+
+static void greth_set_hash_filter(struct net_device *dev)
+{
+ struct netdev_hw_addr *ha;
+ struct greth_private *greth = netdev_priv(dev);
+ struct greth_regs *regs = greth->regs;
+ u32 mc_filter[2];
+ unsigned int bitnr;
+
+ mc_filter[0] = mc_filter[1] = 0;
+
+ netdev_for_each_mc_addr(ha, dev) {
+ bitnr = greth_hash_get_index(ha->addr);
+ mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
+ }
+
+ GRETH_REGSAVE(regs->hash_msb, mc_filter[1]);
+ GRETH_REGSAVE(regs->hash_lsb, mc_filter[0]);
+}
+
+static void greth_set_multicast_list(struct net_device *dev)
+{
+ int cfg;
+ struct greth_private *greth = netdev_priv(dev);
+ struct greth_regs *regs = greth->regs;
+
+ cfg = GRETH_REGLOAD(regs->control);
+ if (dev->flags & IFF_PROMISC)
+ cfg |= GRETH_CTRL_PR;
+ else
+ cfg &= ~GRETH_CTRL_PR;
+
+ if (greth->multicast) {
+ if (dev->flags & IFF_ALLMULTI) {
+ GRETH_REGSAVE(regs->hash_msb, -1);
+ GRETH_REGSAVE(regs->hash_lsb, -1);
+ cfg |= GRETH_CTRL_MCEN;
+ GRETH_REGSAVE(regs->control, cfg);
+ return;
+ }
+
+ if (netdev_mc_empty(dev)) {
+ cfg &= ~GRETH_CTRL_MCEN;
+ GRETH_REGSAVE(regs->control, cfg);
+ return;
+ }
+
+ /* Setup multicast filter */
+ greth_set_hash_filter(dev);
+ cfg |= GRETH_CTRL_MCEN;
+ }
+ GRETH_REGSAVE(regs->control, cfg);
+}
+
+static u32 greth_get_msglevel(struct net_device *dev)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ return greth->msg_enable;
+}
+
+static void greth_set_msglevel(struct net_device *dev, u32 value)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ greth->msg_enable = value;
+}
+static int greth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ struct phy_device *phy = greth->phy;
+
+ if (!phy)
+ return -ENODEV;
+
+ return phy_ethtool_gset(phy, cmd);
+}
+
+static int greth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ struct phy_device *phy = greth->phy;
+
+ if (!phy)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phy, cmd);
+}
+
+static int greth_get_regs_len(struct net_device *dev)
+{
+ return sizeof(struct greth_regs);
+}
+
+static void greth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+ struct greth_private *greth = netdev_priv(dev);
+
+ strlcpy(info->driver, dev_driver_string(greth->dev),
+ sizeof(info->driver));
+ strlcpy(info->version, "revision: 1.0", sizeof(info->version));
+ strlcpy(info->bus_info, greth->dev->bus->name, sizeof(info->bus_info));
+ strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
+ info->eedump_len = 0;
+ info->regdump_len = sizeof(struct greth_regs);
+}
+
+static void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
+{
+ int i;
+ struct greth_private *greth = netdev_priv(dev);
+ u32 __iomem *greth_regs = (u32 __iomem *) greth->regs;
+ u32 *buff = p;
+
+ for (i = 0; i < sizeof(struct greth_regs) / sizeof(u32); i++)
+ buff[i] = greth_read_bd(&greth_regs[i]);
+}
+
+static const struct ethtool_ops greth_ethtool_ops = {
+ .get_msglevel = greth_get_msglevel,
+ .set_msglevel = greth_set_msglevel,
+ .get_settings = greth_get_settings,
+ .set_settings = greth_set_settings,
+ .get_drvinfo = greth_get_drvinfo,
+ .get_regs_len = greth_get_regs_len,
+ .get_regs = greth_get_regs,
+ .get_link = ethtool_op_get_link,
+};
+
+static struct net_device_ops greth_netdev_ops = {
+ .ndo_open = greth_open,
+ .ndo_stop = greth_close,
+ .ndo_start_xmit = greth_start_xmit,
+ .ndo_set_mac_address = greth_set_mac_add,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static inline int wait_for_mdio(struct greth_private *greth)
+{
+ unsigned long timeout = jiffies + 4*HZ/100;
+ while (GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_BUSY) {
+ if (time_after(jiffies, timeout))
+ return 0;
+ }
+ return 1;
+}
+
+static int greth_mdio_read(struct mii_bus *bus, int phy, int reg)
+{
+ struct greth_private *greth = bus->priv;
+ int data;
+
+ if (!wait_for_mdio(greth))
+ return -EBUSY;
+
+ GRETH_REGSAVE(greth->regs->mdio, ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 2);
+
+ if (!wait_for_mdio(greth))
+ return -EBUSY;
+
+ if (!(GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_NVALID)) {
+ data = (GRETH_REGLOAD(greth->regs->mdio) >> 16) & 0xFFFF;
+ return data;
+
+ } else {
+ return -1;
+ }
+}
+
+static int greth_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+ struct greth_private *greth = bus->priv;
+
+ if (!wait_for_mdio(greth))
+ return -EBUSY;
+
+ GRETH_REGSAVE(greth->regs->mdio,
+ ((val & 0xFFFF) << 16) | ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 1);
+
+ if (!wait_for_mdio(greth))
+ return -EBUSY;
+
+ return 0;
+}
+
+static void greth_link_change(struct net_device *dev)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ struct phy_device *phydev = greth->phy;
+ unsigned long flags;
+ int status_change = 0;
+ u32 ctrl;
+
+ spin_lock_irqsave(&greth->devlock, flags);
+
+ if (phydev->link) {
+
+ if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) {
+ ctrl = GRETH_REGLOAD(greth->regs->control) &
+ ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB);
+
+ if (phydev->duplex)
+ ctrl |= GRETH_CTRL_FD;
+
+ if (phydev->speed == SPEED_100)
+ ctrl |= GRETH_CTRL_SP;
+ else if (phydev->speed == SPEED_1000)
+ ctrl |= GRETH_CTRL_GB;
+
+ GRETH_REGSAVE(greth->regs->control, ctrl);
+ greth->speed = phydev->speed;
+ greth->duplex = phydev->duplex;
+ status_change = 1;
+ }
+ }
+
+ if (phydev->link != greth->link) {
+ if (!phydev->link) {
+ greth->speed = 0;
+ greth->duplex = -1;
+ }
+ greth->link = phydev->link;
+
+ status_change = 1;
+ }
+
+ spin_unlock_irqrestore(&greth->devlock, flags);
+
+ if (status_change) {
+ if (phydev->link)
+ pr_debug("%s: link up (%d/%s)\n",
+ dev->name, phydev->speed,
+ DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
+ else
+ pr_debug("%s: link down\n", dev->name);
+ }
+}
+
+static int greth_mdio_probe(struct net_device *dev)
+{
+ struct greth_private *greth = netdev_priv(dev);
+ struct phy_device *phy = NULL;
+ int ret;
+
+ /* Find the first PHY */
+ phy = phy_find_first(greth->mdio);
+
+ if (!phy) {
+ if (netif_msg_probe(greth))
+ dev_err(&dev->dev, "no PHY found\n");
+ return -ENXIO;
+ }
+
+ ret = phy_connect_direct(dev, phy, &greth_link_change,
+ greth->gbit_mac ? PHY_INTERFACE_MODE_GMII : PHY_INTERFACE_MODE_MII);
+ if (ret) {
+ if (netif_msg_ifup(greth))
+ dev_err(&dev->dev, "could not attach to PHY\n");
+ return ret;
+ }
+
+ if (greth->gbit_mac)
+ phy->supported &= PHY_GBIT_FEATURES;
+ else
+ phy->supported &= PHY_BASIC_FEATURES;
+
+ phy->advertising = phy->supported;
+
+ greth->link = 0;
+ greth->speed = 0;
+ greth->duplex = -1;
+ greth->phy = phy;
+
+ return 0;
+}
+
+static inline int phy_aneg_done(struct phy_device *phydev)
+{
+ int retval;
+
+ retval = phy_read(phydev, MII_BMSR);
+
+ return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
+}
+
+static int greth_mdio_init(struct greth_private *greth)
+{
+ int ret, phy;
+ unsigned long timeout;
+
+ greth->mdio = mdiobus_alloc();
+ if (!greth->mdio) {
+ return -ENOMEM;
+ }
+
+ greth->mdio->name = "greth-mdio";
+ snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq);
+ greth->mdio->read = greth_mdio_read;
+ greth->mdio->write = greth_mdio_write;
+ greth->mdio->priv = greth;
+
+ greth->mdio->irq = greth->mdio_irqs;
+
+ for (phy = 0; phy < PHY_MAX_ADDR; phy++)
+ greth->mdio->irq[phy] = PHY_POLL;
+
+ ret = mdiobus_register(greth->mdio);
+ if (ret) {
+ goto error;
+ }
+
+ ret = greth_mdio_probe(greth->netdev);
+ if (ret) {
+ if (netif_msg_probe(greth))
+ dev_err(&greth->netdev->dev, "failed to probe MDIO bus\n");
+ goto unreg_mdio;
+ }
+
+ phy_start(greth->phy);
+
+ /* If Ethernet debug link is used make autoneg happen right away */
+ if (greth->edcl && greth_edcl == 1) {
+ phy_start_aneg(greth->phy);
+ timeout = jiffies + 6*HZ;
+ while (!phy_aneg_done(greth->phy) && time_before(jiffies, timeout)) {
+ }
+ phy_read_status(greth->phy);
+ greth_link_change(greth->netdev);
+ }
+
+ return 0;
+
+unreg_mdio:
+ mdiobus_unregister(greth->mdio);
+error:
+ mdiobus_free(greth->mdio);
+ return ret;
+}
+
+/* Initialize the GRETH MAC */
+static int greth_of_probe(struct platform_device *ofdev)
+{
+ struct net_device *dev;
+ struct greth_private *greth;
+ struct greth_regs *regs;
+
+ int i;
+ int err;
+ int tmp;
+ unsigned long timeout;
+
+ dev = alloc_etherdev(sizeof(struct greth_private));
+
+ if (dev == NULL)
+ return -ENOMEM;
+
+ greth = netdev_priv(dev);
+ greth->netdev = dev;
+ greth->dev = &ofdev->dev;
+
+ if (greth_debug > 0)
+ greth->msg_enable = greth_debug;
+ else
+ greth->msg_enable = GRETH_DEF_MSG_ENABLE;
+
+ spin_lock_init(&greth->devlock);
+
+ greth->regs = of_ioremap(&ofdev->resource[0], 0,
+ resource_size(&ofdev->resource[0]),
+ "grlib-greth regs");
+
+ if (greth->regs == NULL) {
+ if (netif_msg_probe(greth))
+ dev_err(greth->dev, "ioremap failure.\n");
+ err = -EIO;
+ goto error1;
+ }
+
+ regs = greth->regs;
+ greth->irq = ofdev->archdata.irqs[0];
+
+ dev_set_drvdata(greth->dev, dev);
+ SET_NETDEV_DEV(dev, greth->dev);
+
+ if (netif_msg_probe(greth))
+ dev_dbg(greth->dev, "resetting controller.\n");
+
+ /* Reset the controller. */
+ GRETH_REGSAVE(regs->control, GRETH_RESET);
+
+ /* Wait for MAC to reset itself */
+ timeout = jiffies + HZ/100;
+ while (GRETH_REGLOAD(regs->control) & GRETH_RESET) {
+ if (time_after(jiffies, timeout)) {
+ err = -EIO;
+ if (netif_msg_probe(greth))
+ dev_err(greth->dev, "timeout when waiting for reset.\n");
+ goto error2;
+ }
+ }
+
+ /* Get default PHY address */
+ greth->phyaddr = (GRETH_REGLOAD(regs->mdio) >> 11) & 0x1F;
+
+ /* Check if we have GBIT capable MAC */
+ tmp = GRETH_REGLOAD(regs->control);
+ greth->gbit_mac = (tmp >> 27) & 1;
+
+ /* Check for multicast capability */
+ greth->multicast = (tmp >> 25) & 1;
+
+ greth->edcl = (tmp >> 31) & 1;
+
+ /* If we have EDCL we disable the EDCL speed-duplex FSM so
+ * it doesn't interfere with the software */
+ if (greth->edcl != 0)
+ GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX);
+
+ /* Check if MAC can handle MDIO interrupts */
+ greth->mdio_int_en = (tmp >> 26) & 1;
+
+ err = greth_mdio_init(greth);
+ if (err) {
+ if (netif_msg_probe(greth))
+ dev_err(greth->dev, "failed to register MDIO bus\n");
+ goto error2;
+ }
+
+ /* Allocate TX descriptor ring in coherent memory */
+ greth->tx_bd_base = dma_zalloc_coherent(greth->dev, 1024,
+ &greth->tx_bd_base_phys,
+ GFP_KERNEL);
+ if (!greth->tx_bd_base) {
+ err = -ENOMEM;
+ goto error3;
+ }
+
+ /* Allocate RX descriptor ring in coherent memory */
+ greth->rx_bd_base = dma_zalloc_coherent(greth->dev, 1024,
+ &greth->rx_bd_base_phys,
+ GFP_KERNEL);
+ if (!greth->rx_bd_base) {
+ err = -ENOMEM;
+ goto error4;
+ }
+
+ /* Get MAC address from: module param, OF property or ID prom */
+ for (i = 0; i < 6; i++) {
+ if (macaddr[i] != 0)
+ break;
+ }
+ if (i == 6) {
+ const unsigned char *addr;
+ int len;
+ addr = of_get_property(ofdev->dev.of_node, "local-mac-address",
+ &len);
+ if (addr != NULL && len == 6) {
+ for (i = 0; i < 6; i++)
+ macaddr[i] = (unsigned int) addr[i];
+ } else {
+#ifdef CONFIG_SPARC
+ for (i = 0; i < 6; i++)
+ macaddr[i] = (unsigned int) idprom->id_ethaddr[i];
+#endif
+ }
+ }
+
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = macaddr[i];
+
+ macaddr[5]++;
+
+ if (!is_valid_ether_addr(&dev->dev_addr[0])) {
+ if (netif_msg_probe(greth))
+ dev_err(greth->dev, "no valid ethernet address, aborting.\n");
+ err = -EINVAL;
+ goto error5;
+ }
+
+ GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+ GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 |
+ dev->dev_addr[4] << 8 | dev->dev_addr[5]);
+
+ /* Clear all pending interrupts except PHY irq */
+ GRETH_REGSAVE(regs->status, 0xFF);
+
+ if (greth->gbit_mac) {
+ dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+ NETIF_F_RXCSUM;
+ dev->features = dev->hw_features | NETIF_F_HIGHDMA;
+ greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit;
+ }
+
+ if (greth->multicast) {
+ greth_netdev_ops.ndo_set_rx_mode = greth_set_multicast_list;
+ dev->flags |= IFF_MULTICAST;
+ } else {
+ dev->flags &= ~IFF_MULTICAST;
+ }
+
+ dev->netdev_ops = &greth_netdev_ops;
+ dev->ethtool_ops = &greth_ethtool_ops;
+
+ err = register_netdev(dev);
+ if (err) {
+ if (netif_msg_probe(greth))
+ dev_err(greth->dev, "netdevice registration failed.\n");
+ goto error5;
+ }
+
+ /* setup NAPI */
+ netif_napi_add(dev, &greth->napi, greth_poll, 64);
+
+ return 0;
+
+error5:
+ dma_free_coherent(greth->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys);
+error4:
+ dma_free_coherent(greth->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys);
+error3:
+ mdiobus_unregister(greth->mdio);
+error2:
+ of_iounmap(&ofdev->resource[0], greth->regs, resource_size(&ofdev->resource[0]));
+error1:
+ free_netdev(dev);
+ return err;
+}
+
+static int greth_of_remove(struct platform_device *of_dev)
+{
+ struct net_device *ndev = platform_get_drvdata(of_dev);
+ struct greth_private *greth = netdev_priv(ndev);
+
+ /* Free descriptor areas */
+ dma_free_coherent(&of_dev->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys);
+
+ dma_free_coherent(&of_dev->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys);
+
+ if (greth->phy)
+ phy_stop(greth->phy);
+ mdiobus_unregister(greth->mdio);
+
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+
+ of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0]));
+
+ return 0;
+}
+
+static struct of_device_id greth_of_match[] = {
+ {
+ .name = "GAISLER_ETHMAC",
+ },
+ {
+ .name = "01_01d",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, greth_of_match);
+
+static struct platform_driver greth_of_driver = {
+ .driver = {
+ .name = "grlib-greth",
+ .owner = THIS_MODULE,
+ .of_match_table = greth_of_match,
+ },
+ .probe = greth_of_probe,
+ .remove = greth_of_remove,
+};
+
+module_platform_driver(greth_of_driver);
+
+MODULE_AUTHOR("Aeroflex Gaisler AB.");
+MODULE_DESCRIPTION("Aeroflex Gaisler Ethernet MAC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/aeroflex/greth.h b/drivers/net/ethernet/aeroflex/greth.h
new file mode 100644
index 00000000000..232a622a85b
--- /dev/null
+++ b/drivers/net/ethernet/aeroflex/greth.h
@@ -0,0 +1,142 @@
+#ifndef GRETH_H
+#define GRETH_H
+
+#include <linux/phy.h>
+
+/* Register bits and masks */
+#define GRETH_RESET 0x40
+#define GRETH_MII_BUSY 0x8
+#define GRETH_MII_NVALID 0x10
+
+#define GRETH_CTRL_FD 0x10
+#define GRETH_CTRL_PR 0x20
+#define GRETH_CTRL_SP 0x80
+#define GRETH_CTRL_GB 0x100
+#define GRETH_CTRL_PSTATIEN 0x400
+#define GRETH_CTRL_MCEN 0x800
+#define GRETH_CTRL_DISDUPLEX 0x1000
+#define GRETH_STATUS_PHYSTAT 0x100
+
+#define GRETH_BD_EN 0x800
+#define GRETH_BD_WR 0x1000
+#define GRETH_BD_IE 0x2000
+#define GRETH_BD_LEN 0x7FF
+
+#define GRETH_TXEN 0x1
+#define GRETH_INT_TE 0x2
+#define GRETH_INT_TX 0x8
+#define GRETH_TXI 0x4
+#define GRETH_TXBD_STATUS 0x0001C000
+#define GRETH_TXBD_MORE 0x20000
+#define GRETH_TXBD_IPCS 0x40000
+#define GRETH_TXBD_TCPCS 0x80000
+#define GRETH_TXBD_UDPCS 0x100000
+#define GRETH_TXBD_CSALL (GRETH_TXBD_IPCS | GRETH_TXBD_TCPCS | GRETH_TXBD_UDPCS)
+#define GRETH_TXBD_ERR_LC 0x10000
+#define GRETH_TXBD_ERR_UE 0x4000
+#define GRETH_TXBD_ERR_AL 0x8000
+
+#define GRETH_INT_RE 0x1
+#define GRETH_INT_RX 0x4
+#define GRETH_RXEN 0x2
+#define GRETH_RXI 0x8
+#define GRETH_RXBD_STATUS 0xFFFFC000
+#define GRETH_RXBD_ERR_AE 0x4000
+#define GRETH_RXBD_ERR_FT 0x8000
+#define GRETH_RXBD_ERR_CRC 0x10000
+#define GRETH_RXBD_ERR_OE 0x20000
+#define GRETH_RXBD_ERR_LE 0x40000
+#define GRETH_RXBD_IP 0x80000
+#define GRETH_RXBD_IP_CSERR 0x100000
+#define GRETH_RXBD_UDP 0x200000
+#define GRETH_RXBD_UDP_CSERR 0x400000
+#define GRETH_RXBD_TCP 0x800000
+#define GRETH_RXBD_TCP_CSERR 0x1000000
+#define GRETH_RXBD_IP_FRAG 0x2000000
+#define GRETH_RXBD_MCAST 0x4000000
+
+/* Descriptor parameters */
+#define GRETH_TXBD_NUM 128
+#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1)
+#define GRETH_TX_BUF_SIZE 2048
+#define GRETH_RXBD_NUM 128
+#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1)
+#define GRETH_RX_BUF_SIZE 2048
+
+/* Buffers per page */
+#define GRETH_RX_BUF_PPGAE (PAGE_SIZE/GRETH_RX_BUF_SIZE)
+#define GRETH_TX_BUF_PPGAE (PAGE_SIZE/GRETH_TX_BUF_SIZE)
+
+/* How many pages are needed for buffers */
+#define GRETH_RX_BUF_PAGE_NUM (GRETH_RXBD_NUM/GRETH_RX_BUF_PPGAE)
+#define GRETH_TX_BUF_PAGE_NUM (GRETH_TXBD_NUM/GRETH_TX_BUF_PPGAE)
+
+/* Buffer size.
+ * Gbit MAC uses tagged maximum frame size which is 1518 excluding CRC.
+ * Set to 1520 to make all buffers word aligned for non-gbit MAC.
+ */
+#define MAX_FRAME_SIZE 1520
+
+/* GRETH APB registers */
+struct greth_regs {
+ u32 control;
+ u32 status;
+ u32 esa_msb;
+ u32 esa_lsb;
+ u32 mdio;
+ u32 tx_desc_p;
+ u32 rx_desc_p;
+ u32 edclip;
+ u32 hash_msb;
+ u32 hash_lsb;
+};
+
+/* GRETH buffer descriptor */
+struct greth_bd {
+ u32 stat;
+ u32 addr;
+};
+
+struct greth_private {
+ struct sk_buff *rx_skbuff[GRETH_RXBD_NUM];
+ struct sk_buff *tx_skbuff[GRETH_TXBD_NUM];
+
+ unsigned char *tx_bufs[GRETH_TXBD_NUM];
+ unsigned char *rx_bufs[GRETH_RXBD_NUM];
+ u16 tx_bufs_length[GRETH_TXBD_NUM];
+
+ u16 tx_next;
+ u16 tx_last;
+ u16 tx_free;
+ u16 rx_cur;
+
+ struct greth_regs *regs; /* Address of controller registers. */
+ struct greth_bd *rx_bd_base; /* Address of Rx BDs. */
+ struct greth_bd *tx_bd_base; /* Address of Tx BDs. */
+ dma_addr_t rx_bd_base_phys;
+ dma_addr_t tx_bd_base_phys;
+
+ int irq;
+
+ struct device *dev; /* Pointer to platform_device->dev */
+ struct net_device *netdev;
+ struct napi_struct napi;
+ spinlock_t devlock;
+
+ struct phy_device *phy;
+ struct mii_bus *mdio;
+ int mdio_irqs[PHY_MAX_ADDR];
+ unsigned int link;
+ unsigned int speed;
+ unsigned int duplex;
+
+ u32 msg_enable;
+
+ u8 phyaddr;
+ u8 multicast;
+ u8 gbit_mac;
+ u8 mdio_int_en;
+ u8 edcl;
+};
+
+#endif
diff --git a/drivers/net/ethernet/allwinner/Kconfig b/drivers/net/ethernet/allwinner/Kconfig
new file mode 100644
index 00000000000..d8d95d4cd45
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/Kconfig
@@ -0,0 +1,37 @@
+#
+# Allwinner device configuration
+#
+
+config NET_VENDOR_ALLWINNER
+ bool "Allwinner devices"
+ default y
+
+ depends on ARCH_SUNXI
+ ---help---
+ If you have a network (Ethernet) card belonging to this
+ class, say Y and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly
+ affect the kernel: saying N will just cause the configurator
+ to skip all the questions about Allwinner cards. If you say Y,
+ you will be asked for your specific card in the following
+ questions.
+
+if NET_VENDOR_ALLWINNER
+
+config SUN4I_EMAC
+ tristate "Allwinner A10 EMAC support"
+ depends on ARCH_SUNXI
+ depends on OF
+ select CRC32
+ select MII
+ select PHYLIB
+ select MDIO_SUN4I
+ ---help---
+ Support for Allwinner A10 EMAC ethernet driver.
+
+ To compile this driver as a module, choose M here. The module
+ will be called sun4i-emac.
+
+endif # NET_VENDOR_ALLWINNER
diff --git a/drivers/net/ethernet/allwinner/Makefile b/drivers/net/ethernet/allwinner/Makefile
new file mode 100644
index 00000000000..03129f79651
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Allwinner device drivers.
+#
+
+obj-$(CONFIG_SUN4I_EMAC) += sun4i-emac.o
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
new file mode 100644
index 00000000000..d81e7167a8b
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -0,0 +1,970 @@
+/*
+ * Allwinner EMAC Fast Ethernet driver for Linux.
+ *
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
+ * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on the Linux driver provided by Allwinner:
+ * Copyright (C) 1997 Sten Wang
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+
+#include "sun4i-emac.h"
+
+#define DRV_NAME "sun4i-emac"
+#define DRV_VERSION "1.02"
+
+#define EMAC_MAX_FRAME_LEN 0x0600
+
+/* Transmit timeout, default 5 seconds. */
+static int watchdog = 5000;
+module_param(watchdog, int, 0400);
+MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
+
+/* EMAC register address locking.
+ *
+ * The EMAC uses an address register to control where data written
+ * to the data register goes. This means that the address register
+ * must be preserved over interrupts or similar calls.
+ *
+ * During interrupt and other critical calls, a spinlock is used to
+ * protect the system, but the calls themselves save the address
+ * in the address register in case they are interrupting another
+ * access to the device.
+ *
+ * For general accesses a lock is provided so that calls which are
+ * allowed to sleep are serialised so that the address register does
+ * not need to be saved. This lock also serves to serialise access
+ * to the EEPROM and PHY access registers which are shared between
+ * these two devices.
+ */
+
+/* The driver supports the original EMACE, and now the two newer
+ * devices, EMACA and EMACB.
+ */
+
+struct emac_board_info {
+ struct clk *clk;
+ struct device *dev;
+ struct platform_device *pdev;
+ spinlock_t lock;
+ void __iomem *membase;
+ u32 msg_enable;
+ struct net_device *ndev;
+ struct sk_buff *skb_last;
+ u16 tx_fifo_stat;
+
+ int emacrx_completed_flag;
+
+ struct phy_device *phy_dev;
+ struct device_node *phy_node;
+ unsigned int link;
+ unsigned int speed;
+ unsigned int duplex;
+
+ phy_interface_t phy_interface;
+};
+
+static void emac_update_speed(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ unsigned int reg_val;
+
+ /* set EMAC SPEED, depend on PHY */
+ reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
+ reg_val &= ~(0x1 << 8);
+ if (db->speed == SPEED_100)
+ reg_val |= 1 << 8;
+ writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
+}
+
+static void emac_update_duplex(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ unsigned int reg_val;
+
+ /* set duplex depend on phy */
+ reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
+ reg_val &= ~EMAC_MAC_CTL1_DUPLEX_EN;
+ if (db->duplex)
+ reg_val |= EMAC_MAC_CTL1_DUPLEX_EN;
+ writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
+}
+
+static void emac_handle_link_change(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ struct phy_device *phydev = db->phy_dev;
+ unsigned long flags;
+ int status_change = 0;
+
+ if (phydev->link) {
+ if (db->speed != phydev->speed) {
+ spin_lock_irqsave(&db->lock, flags);
+ db->speed = phydev->speed;
+ emac_update_speed(dev);
+ spin_unlock_irqrestore(&db->lock, flags);
+ status_change = 1;
+ }
+
+ if (db->duplex != phydev->duplex) {
+ spin_lock_irqsave(&db->lock, flags);
+ db->duplex = phydev->duplex;
+ emac_update_duplex(dev);
+ spin_unlock_irqrestore(&db->lock, flags);
+ status_change = 1;
+ }
+ }
+
+ if (phydev->link != db->link) {
+ if (!phydev->link) {
+ db->speed = 0;
+ db->duplex = -1;
+ }
+ db->link = phydev->link;
+
+ status_change = 1;
+ }
+
+ if (status_change)
+ phy_print_status(phydev);
+}
+
+static int emac_mdio_probe(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+
+ /* to-do: PHY interrupts are currently not supported */
+
+ /* attach the mac to the phy */
+ db->phy_dev = of_phy_connect(db->ndev, db->phy_node,
+ &emac_handle_link_change, 0,
+ db->phy_interface);
+ if (!db->phy_dev) {
+ netdev_err(db->ndev, "could not find the PHY\n");
+ return -ENODEV;
+ }
+
+ /* mask with MAC supported features */
+ db->phy_dev->supported &= PHY_BASIC_FEATURES;
+ db->phy_dev->advertising = db->phy_dev->supported;
+
+ db->link = 0;
+ db->speed = 0;
+ db->duplex = -1;
+
+ return 0;
+}
+
+static void emac_mdio_remove(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+
+ phy_disconnect(db->phy_dev);
+ db->phy_dev = NULL;
+}
+
+static void emac_reset(struct emac_board_info *db)
+{
+ dev_dbg(db->dev, "resetting device\n");
+
+ /* RESET device */
+ writel(0, db->membase + EMAC_CTL_REG);
+ udelay(200);
+ writel(EMAC_CTL_RESET, db->membase + EMAC_CTL_REG);
+ udelay(200);
+}
+
+static void emac_outblk_32bit(void __iomem *reg, void *data, int count)
+{
+ writesl(reg, data, round_up(count, 4) / 4);
+}
+
+static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
+{
+ readsl(reg, data, round_up(count, 4) / 4);
+}
+
+static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct emac_board_info *dm = netdev_priv(dev);
+ struct phy_device *phydev = dm->phy_dev;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_mii_ioctl(phydev, rq, cmd);
+}
+
+/* ethtool ops */
+static void emac_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, DRV_NAME, sizeof(DRV_NAME));
+ strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
+ strlcpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info));
+}
+
+static int emac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct emac_board_info *dm = netdev_priv(dev);
+ struct phy_device *phydev = dm->phy_dev;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_ethtool_gset(phydev, cmd);
+}
+
+static int emac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct emac_board_info *dm = netdev_priv(dev);
+ struct phy_device *phydev = dm->phy_dev;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phydev, cmd);
+}
+
+static const struct ethtool_ops emac_ethtool_ops = {
+ .get_drvinfo = emac_get_drvinfo,
+ .get_settings = emac_get_settings,
+ .set_settings = emac_set_settings,
+ .get_link = ethtool_op_get_link,
+};
+
+static unsigned int emac_setup(struct net_device *ndev)
+{
+ struct emac_board_info *db = netdev_priv(ndev);
+ unsigned int reg_val;
+
+ /* set up TX */
+ reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+
+ writel(reg_val | EMAC_TX_MODE_ABORTED_FRAME_EN,
+ db->membase + EMAC_TX_MODE_REG);
+
+ /* set MAC */
+ /* set MAC CTL0 */
+ reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
+ writel(reg_val | EMAC_MAC_CTL0_RX_FLOW_CTL_EN |
+ EMAC_MAC_CTL0_TX_FLOW_CTL_EN,
+ db->membase + EMAC_MAC_CTL0_REG);
+
+ /* set MAC CTL1 */
+ reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
+ reg_val |= EMAC_MAC_CTL1_LEN_CHECK_EN;
+ reg_val |= EMAC_MAC_CTL1_CRC_EN;
+ reg_val |= EMAC_MAC_CTL1_PAD_EN;
+ writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
+
+ /* set up IPGT */
+ writel(EMAC_MAC_IPGT_FULL_DUPLEX, db->membase + EMAC_MAC_IPGT_REG);
+
+ /* set up IPGR */
+ writel((EMAC_MAC_IPGR_IPG1 << 8) | EMAC_MAC_IPGR_IPG2,
+ db->membase + EMAC_MAC_IPGR_REG);
+
+ /* set up Collison window */
+ writel((EMAC_MAC_CLRT_COLLISION_WINDOW << 8) | EMAC_MAC_CLRT_RM,
+ db->membase + EMAC_MAC_CLRT_REG);
+
+ /* set up Max Frame Length */
+ writel(EMAC_MAX_FRAME_LEN,
+ db->membase + EMAC_MAC_MAXF_REG);
+
+ return 0;
+}
+
+static void emac_set_rx_mode(struct net_device *ndev)
+{
+ struct emac_board_info *db = netdev_priv(ndev);
+ unsigned int reg_val;
+
+ /* set up RX */
+ reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+
+ if (ndev->flags & IFF_PROMISC)
+ reg_val |= EMAC_RX_CTL_PASS_ALL_EN;
+ else
+ reg_val &= ~EMAC_RX_CTL_PASS_ALL_EN;
+
+ writel(reg_val | EMAC_RX_CTL_PASS_LEN_OOR_EN |
+ EMAC_RX_CTL_ACCEPT_UNICAST_EN | EMAC_RX_CTL_DA_FILTER_EN |
+ EMAC_RX_CTL_ACCEPT_MULTICAST_EN |
+ EMAC_RX_CTL_ACCEPT_BROADCAST_EN,
+ db->membase + EMAC_RX_CTL_REG);
+}
+
+static unsigned int emac_powerup(struct net_device *ndev)
+{
+ struct emac_board_info *db = netdev_priv(ndev);
+ unsigned int reg_val;
+
+ /* initial EMAC */
+ /* flush RX FIFO */
+ reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+ reg_val |= 0x8;
+ writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+ udelay(1);
+
+ /* initial MAC */
+ /* soft reset MAC */
+ reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
+ reg_val &= ~EMAC_MAC_CTL0_SOFT_RESET;
+ writel(reg_val, db->membase + EMAC_MAC_CTL0_REG);
+
+ /* set MII clock */
+ reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
+ reg_val &= (~(0xf << 2));
+ reg_val |= (0xD << 2);
+ writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
+
+ /* clear RX counter */
+ writel(0x0, db->membase + EMAC_RX_FBC_REG);
+
+ /* disable all interrupt and clear interrupt status */
+ writel(0, db->membase + EMAC_INT_CTL_REG);
+ reg_val = readl(db->membase + EMAC_INT_STA_REG);
+ writel(reg_val, db->membase + EMAC_INT_STA_REG);
+
+ udelay(1);
+
+ /* set up EMAC */
+ emac_setup(ndev);
+
+ /* set mac_address to chip */
+ writel(ndev->dev_addr[0] << 16 | ndev->dev_addr[1] << 8 | ndev->
+ dev_addr[2], db->membase + EMAC_MAC_A1_REG);
+ writel(ndev->dev_addr[3] << 16 | ndev->dev_addr[4] << 8 | ndev->
+ dev_addr[5], db->membase + EMAC_MAC_A0_REG);
+
+ mdelay(1);
+
+ return 0;
+}
+
+static int emac_set_mac_address(struct net_device *dev, void *p)
+{
+ struct sockaddr *addr = p;
+ struct emac_board_info *db = netdev_priv(dev);
+
+ if (netif_running(dev))
+ return -EBUSY;
+
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+ writel(dev->dev_addr[0] << 16 | dev->dev_addr[1] << 8 | dev->
+ dev_addr[2], db->membase + EMAC_MAC_A1_REG);
+ writel(dev->dev_addr[3] << 16 | dev->dev_addr[4] << 8 | dev->
+ dev_addr[5], db->membase + EMAC_MAC_A0_REG);
+
+ return 0;
+}
+
+/* Initialize emac board */
+static void emac_init_device(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ unsigned long flags;
+ unsigned int reg_val;
+
+ spin_lock_irqsave(&db->lock, flags);
+
+ emac_update_speed(dev);
+ emac_update_duplex(dev);
+
+ /* enable RX/TX */
+ reg_val = readl(db->membase + EMAC_CTL_REG);
+ writel(reg_val | EMAC_CTL_RESET | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN,
+ db->membase + EMAC_CTL_REG);
+
+ /* enable RX/TX0/RX Hlevel interrup */
+ reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+ reg_val |= (0xf << 0) | (0x01 << 8);
+ writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+ spin_unlock_irqrestore(&db->lock, flags);
+}
+
+/* Our watchdog timed out. Called by the networking layer */
+static void emac_timeout(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ unsigned long flags;
+
+ if (netif_msg_timer(db))
+ dev_err(db->dev, "tx time out.\n");
+
+ /* Save previous register address */
+ spin_lock_irqsave(&db->lock, flags);
+
+ netif_stop_queue(dev);
+ emac_reset(db);
+ emac_init_device(dev);
+ /* We can accept TX packets again */
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev);
+
+ /* Restore previous register address */
+ spin_unlock_irqrestore(&db->lock, flags);
+}
+
+/* Hardware start transmission.
+ * Send a packet to media from the upper layer.
+ */
+static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ unsigned long channel;
+ unsigned long flags;
+
+ channel = db->tx_fifo_stat & 3;
+ if (channel == 3)
+ return 1;
+
+ channel = (channel == 1 ? 1 : 0);
+
+ spin_lock_irqsave(&db->lock, flags);
+
+ writel(channel, db->membase + EMAC_TX_INS_REG);
+
+ emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG,
+ skb->data, skb->len);
+ dev->stats.tx_bytes += skb->len;
+
+ db->tx_fifo_stat |= 1 << channel;
+ /* TX control: First packet immediately send, second packet queue */
+ if (channel == 0) {
+ /* set TX len */
+ writel(skb->len, db->membase + EMAC_TX_PL0_REG);
+ /* start translate from fifo to phy */
+ writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1,
+ db->membase + EMAC_TX_CTL0_REG);
+
+ /* save the time stamp */
+ dev->trans_start = jiffies;
+ } else if (channel == 1) {
+ /* set TX len */
+ writel(skb->len, db->membase + EMAC_TX_PL1_REG);
+ /* start translate from fifo to phy */
+ writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1,
+ db->membase + EMAC_TX_CTL1_REG);
+
+ /* save the time stamp */
+ dev->trans_start = jiffies;
+ }
+
+ if ((db->tx_fifo_stat & 3) == 3) {
+ /* Second packet */
+ netif_stop_queue(dev);
+ }
+
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ /* free this SKB */
+ dev_consume_skb_any(skb);
+
+ return NETDEV_TX_OK;
+}
+
+/* EMAC interrupt handler
+ * receive the packet to upper layer, free the transmitted packet
+ */
+static void emac_tx_done(struct net_device *dev, struct emac_board_info *db,
+ unsigned int tx_status)
+{
+ /* One packet sent complete */
+ db->tx_fifo_stat &= ~(tx_status & 3);
+ if (3 == (tx_status & 3))
+ dev->stats.tx_packets += 2;
+ else
+ dev->stats.tx_packets++;
+
+ if (netif_msg_tx_done(db))
+ dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
+
+ netif_wake_queue(dev);
+}
+
+/* Received a packet and pass to upper layer
+ */
+static void emac_rx(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ struct sk_buff *skb;
+ u8 *rdptr;
+ bool good_packet;
+ static int rxlen_last;
+ unsigned int reg_val;
+ u32 rxhdr, rxstatus, rxcount, rxlen;
+
+ /* Check packet ready or not */
+ while (1) {
+ /* race warning: the first packet might arrive with
+ * the interrupts disabled, but the second will fix
+ * it
+ */
+ rxcount = readl(db->membase + EMAC_RX_FBC_REG);
+
+ if (netif_msg_rx_status(db))
+ dev_dbg(db->dev, "RXCount: %x\n", rxcount);
+
+ if ((db->skb_last != NULL) && (rxlen_last > 0)) {
+ dev->stats.rx_bytes += rxlen_last;
+
+ /* Pass to upper layer */
+ db->skb_last->protocol = eth_type_trans(db->skb_last,
+ dev);
+ netif_rx(db->skb_last);
+ dev->stats.rx_packets++;
+ db->skb_last = NULL;
+ rxlen_last = 0;
+
+ reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+ reg_val &= ~EMAC_RX_CTL_DMA_EN;
+ writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+ }
+
+ if (!rxcount) {
+ db->emacrx_completed_flag = 1;
+ reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+ reg_val |= (0xf << 0) | (0x01 << 8);
+ writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+ /* had one stuck? */
+ rxcount = readl(db->membase + EMAC_RX_FBC_REG);
+ if (!rxcount)
+ return;
+ }
+
+ reg_val = readl(db->membase + EMAC_RX_IO_DATA_REG);
+ if (netif_msg_rx_status(db))
+ dev_dbg(db->dev, "receive header: %x\n", reg_val);
+ if (reg_val != EMAC_UNDOCUMENTED_MAGIC) {
+ /* disable RX */
+ reg_val = readl(db->membase + EMAC_CTL_REG);
+ writel(reg_val & ~EMAC_CTL_RX_EN,
+ db->membase + EMAC_CTL_REG);
+
+ /* Flush RX FIFO */
+ reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+ writel(reg_val | (1 << 3),
+ db->membase + EMAC_RX_CTL_REG);
+
+ do {
+ reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+ } while (reg_val & (1 << 3));
+
+ /* enable RX */
+ reg_val = readl(db->membase + EMAC_CTL_REG);
+ writel(reg_val | EMAC_CTL_RX_EN,
+ db->membase + EMAC_CTL_REG);
+ reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+ reg_val |= (0xf << 0) | (0x01 << 8);
+ writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+ db->emacrx_completed_flag = 1;
+
+ return;
+ }
+
+ /* A packet ready now & Get status/length */
+ good_packet = true;
+
+ emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
+ &rxhdr, sizeof(rxhdr));
+
+ if (netif_msg_rx_status(db))
+ dev_dbg(db->dev, "rxhdr: %x\n", *((int *)(&rxhdr)));
+
+ rxlen = EMAC_RX_IO_DATA_LEN(rxhdr);
+ rxstatus = EMAC_RX_IO_DATA_STATUS(rxhdr);
+
+ if (netif_msg_rx_status(db))
+ dev_dbg(db->dev, "RX: status %02x, length %04x\n",
+ rxstatus, rxlen);
+
+ /* Packet Status check */
+ if (rxlen < 0x40) {
+ good_packet = false;
+ if (netif_msg_rx_err(db))
+ dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
+ }
+
+ if (unlikely(!(rxstatus & EMAC_RX_IO_DATA_STATUS_OK))) {
+ good_packet = false;
+
+ if (rxstatus & EMAC_RX_IO_DATA_STATUS_CRC_ERR) {
+ if (netif_msg_rx_err(db))
+ dev_dbg(db->dev, "crc error\n");
+ dev->stats.rx_crc_errors++;
+ }
+
+ if (rxstatus & EMAC_RX_IO_DATA_STATUS_LEN_ERR) {
+ if (netif_msg_rx_err(db))
+ dev_dbg(db->dev, "length error\n");
+ dev->stats.rx_length_errors++;
+ }
+ }
+
+ /* Move data from EMAC */
+ skb = dev_alloc_skb(rxlen + 4);
+ if (good_packet && skb) {
+ skb_reserve(skb, 2);
+ rdptr = (u8 *) skb_put(skb, rxlen - 4);
+
+ /* Read received packet from RX SRAM */
+ if (netif_msg_rx_status(db))
+ dev_dbg(db->dev, "RxLen %x\n", rxlen);
+
+ emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
+ rdptr, rxlen);
+ dev->stats.rx_bytes += rxlen;
+
+ /* Pass to upper layer */
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->stats.rx_packets++;
+ }
+ }
+}
+
+static irqreturn_t emac_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct emac_board_info *db = netdev_priv(dev);
+ int int_status;
+ unsigned long flags;
+ unsigned int reg_val;
+
+ /* A real interrupt coming */
+
+ /* holders of db->lock must always block IRQs */
+ spin_lock_irqsave(&db->lock, flags);
+
+ /* Disable all interrupts */
+ writel(0, db->membase + EMAC_INT_CTL_REG);
+
+ /* Got EMAC interrupt status */
+ /* Got ISR */
+ int_status = readl(db->membase + EMAC_INT_STA_REG);
+ /* Clear ISR status */
+ writel(int_status, db->membase + EMAC_INT_STA_REG);
+
+ if (netif_msg_intr(db))
+ dev_dbg(db->dev, "emac interrupt %02x\n", int_status);
+
+ /* Received the coming packet */
+ if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) {
+ /* carrier lost */
+ db->emacrx_completed_flag = 0;
+ emac_rx(dev);
+ }
+
+ /* Transmit Interrupt check */
+ if (int_status & (0x01 | 0x02))
+ emac_tx_done(dev, db, int_status);
+
+ if (int_status & (0x04 | 0x08))
+ netdev_info(dev, " ab : %x\n", int_status);
+
+ /* Re-enable interrupt mask */
+ if (db->emacrx_completed_flag == 1) {
+ reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+ reg_val |= (0xf << 0) | (0x01 << 8);
+ writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+ }
+ spin_unlock_irqrestore(&db->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Used by netconsole
+ */
+static void emac_poll_controller(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ emac_interrupt(dev->irq, dev);
+ enable_irq(dev->irq);
+}
+#endif
+
+/* Open the interface.
+ * The interface is opened whenever "ifconfig" actives it.
+ */
+static int emac_open(struct net_device *dev)
+{
+ struct emac_board_info *db = netdev_priv(dev);
+ int ret;
+
+ if (netif_msg_ifup(db))
+ dev_dbg(db->dev, "enabling %s\n", dev->name);
+
+ if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev))
+ return -EAGAIN;
+
+ /* Initialize EMAC board */
+ emac_reset(db);
+ emac_init_device(dev);
+
+ ret = emac_mdio_probe(dev);
+ if (ret < 0) {
+ free_irq(dev->irq, dev);
+ netdev_err(dev, "cannot probe MDIO bus\n");
+ return ret;
+ }
+
+ phy_start(db->phy_dev);
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static void emac_shutdown(struct net_device *dev)
+{
+ unsigned int reg_val;
+ struct emac_board_info *db = netdev_priv(dev);
+
+ /* Disable all interrupt */
+ writel(0, db->membase + EMAC_INT_CTL_REG);
+
+ /* clear interupt status */
+ reg_val = readl(db->membase + EMAC_INT_STA_REG);
+ writel(reg_val, db->membase + EMAC_INT_STA_REG);
+
+ /* Disable RX/TX */
+ reg_val = readl(db->membase + EMAC_CTL_REG);
+ reg_val &= ~(EMAC_CTL_TX_EN | EMAC_CTL_RX_EN | EMAC_CTL_RESET);
+ writel(reg_val, db->membase + EMAC_CTL_REG);
+}
+
+/* Stop the interface.
+ * The interface is stopped when it is brought.
+ */
+static int emac_stop(struct net_device *ndev)
+{
+ struct emac_board_info *db = netdev_priv(ndev);
+
+ if (netif_msg_ifdown(db))
+ dev_dbg(db->dev, "shutting down %s\n", ndev->name);
+
+ netif_stop_queue(ndev);
+ netif_carrier_off(ndev);
+
+ phy_stop(db->phy_dev);
+
+ emac_mdio_remove(ndev);
+
+ emac_shutdown(ndev);
+
+ free_irq(ndev->irq, ndev);
+
+ return 0;
+}
+
+static const struct net_device_ops emac_netdev_ops = {
+ .ndo_open = emac_open,
+ .ndo_stop = emac_stop,
+ .ndo_start_xmit = emac_start_xmit,
+ .ndo_tx_timeout = emac_timeout,
+ .ndo_set_rx_mode = emac_set_rx_mode,
+ .ndo_do_ioctl = emac_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = emac_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = emac_poll_controller,
+#endif
+};
+
+/* Search EMAC board, allocate space and register it
+ */
+static int emac_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct emac_board_info *db;
+ struct net_device *ndev;
+ int ret = 0;
+ const char *mac_addr;
+
+ ndev = alloc_etherdev(sizeof(struct emac_board_info));
+ if (!ndev) {
+ dev_err(&pdev->dev, "could not allocate device.\n");
+ return -ENOMEM;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ db = netdev_priv(ndev);
+ memset(db, 0, sizeof(*db));
+
+ db->dev = &pdev->dev;
+ db->ndev = ndev;
+ db->pdev = pdev;
+
+ spin_lock_init(&db->lock);
+
+ db->membase = of_iomap(np, 0);
+ if (!db->membase) {
+ dev_err(&pdev->dev, "failed to remap registers\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* fill in parameters for net-dev structure */
+ ndev->base_addr = (unsigned long)db->membase;
+ ndev->irq = irq_of_parse_and_map(np, 0);
+ if (ndev->irq == -ENXIO) {
+ netdev_err(ndev, "No irq resource\n");
+ ret = ndev->irq;
+ goto out;
+ }
+
+ db->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(db->clk))
+ goto out;
+
+ clk_prepare_enable(db->clk);
+
+ db->phy_node = of_parse_phandle(np, "phy", 0);
+ if (!db->phy_node) {
+ dev_err(&pdev->dev, "no associated PHY\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Read MAC-address from DT */
+ mac_addr = of_get_mac_address(np);
+ if (mac_addr)
+ memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+
+ /* Check if the MAC address is valid, if not get a random one */
+ if (!is_valid_ether_addr(ndev->dev_addr)) {
+ eth_hw_addr_random(ndev);
+ dev_warn(&pdev->dev, "using random MAC address %pM\n",
+ ndev->dev_addr);
+ }
+
+ db->emacrx_completed_flag = 1;
+ emac_powerup(ndev);
+ emac_reset(db);
+
+ ether_setup(ndev);
+
+ ndev->netdev_ops = &emac_netdev_ops;
+ ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+ ndev->ethtool_ops = &emac_ethtool_ops;
+
+ platform_set_drvdata(pdev, ndev);
+
+ /* Carrier starts down, phylib will bring it up */
+ netif_carrier_off(ndev);
+
+ ret = register_netdev(ndev);
+ if (ret) {
+ dev_err(&pdev->dev, "Registering netdev failed!\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n",
+ ndev->name, db->membase, ndev->irq, ndev->dev_addr);
+
+ return 0;
+
+out:
+ dev_err(db->dev, "not found (%d).\n", ret);
+
+ free_netdev(ndev);
+
+ return ret;
+}
+
+static int emac_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+
+ dev_dbg(&pdev->dev, "released and freed device\n");
+ return 0;
+}
+
+static int emac_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+
+ netif_carrier_off(ndev);
+ netif_device_detach(ndev);
+ emac_shutdown(ndev);
+
+ return 0;
+}
+
+static int emac_resume(struct platform_device *dev)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+ struct emac_board_info *db = netdev_priv(ndev);
+
+ emac_reset(db);
+ emac_init_device(ndev);
+ netif_device_attach(ndev);
+
+ return 0;
+}
+
+static const struct of_device_id emac_of_match[] = {
+ {.compatible = "allwinner,sun4i-a10-emac",},
+
+ /* Deprecated */
+ {.compatible = "allwinner,sun4i-emac",},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, emac_of_match);
+
+static struct platform_driver emac_driver = {
+ .driver = {
+ .name = "sun4i-emac",
+ .of_match_table = emac_of_match,
+ },
+ .probe = emac_probe,
+ .remove = emac_remove,
+ .suspend = emac_suspend,
+ .resume = emac_resume,
+};
+
+module_platform_driver(emac_driver);
+
+MODULE_AUTHOR("Stefan Roese <sr@denx.de>");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_DESCRIPTION("Allwinner A10 emac network driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
new file mode 100644
index 00000000000..38c72d9ec60
--- /dev/null
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -0,0 +1,108 @@
+/*
+ * Allwinner EMAC Fast Ethernet driver for Linux.
+ *
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * Based on the Linux driver provided by Allwinner:
+ * Copyright (C) 1997 Sten Wang
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _SUN4I_EMAC_H_
+#define _SUN4I_EMAC_H_
+
+#define EMAC_CTL_REG (0x00)
+#define EMAC_CTL_RESET (1 << 0)
+#define EMAC_CTL_TX_EN (1 << 1)
+#define EMAC_CTL_RX_EN (1 << 2)
+#define EMAC_TX_MODE_REG (0x04)
+#define EMAC_TX_MODE_ABORTED_FRAME_EN (1 << 0)
+#define EMAC_TX_MODE_DMA_EN (1 << 1)
+#define EMAC_TX_FLOW_REG (0x08)
+#define EMAC_TX_CTL0_REG (0x0c)
+#define EMAC_TX_CTL1_REG (0x10)
+#define EMAC_TX_INS_REG (0x14)
+#define EMAC_TX_PL0_REG (0x18)
+#define EMAC_TX_PL1_REG (0x1c)
+#define EMAC_TX_STA_REG (0x20)
+#define EMAC_TX_IO_DATA_REG (0x24)
+#define EMAC_TX_IO_DATA1_REG (0x28)
+#define EMAC_TX_TSVL0_REG (0x2c)
+#define EMAC_TX_TSVH0_REG (0x30)
+#define EMAC_TX_TSVL1_REG (0x34)
+#define EMAC_TX_TSVH1_REG (0x38)
+#define EMAC_RX_CTL_REG (0x3c)
+#define EMAC_RX_CTL_AUTO_DRQ_EN (1 << 1)
+#define EMAC_RX_CTL_DMA_EN (1 << 2)
+#define EMAC_RX_CTL_PASS_ALL_EN (1 << 4)
+#define EMAC_RX_CTL_PASS_CTL_EN (1 << 5)
+#define EMAC_RX_CTL_PASS_CRC_ERR_EN (1 << 6)
+#define EMAC_RX_CTL_PASS_LEN_ERR_EN (1 << 7)
+#define EMAC_RX_CTL_PASS_LEN_OOR_EN (1 << 8)
+#define EMAC_RX_CTL_ACCEPT_UNICAST_EN (1 << 16)
+#define EMAC_RX_CTL_DA_FILTER_EN (1 << 17)
+#define EMAC_RX_CTL_ACCEPT_MULTICAST_EN (1 << 20)
+#define EMAC_RX_CTL_HASH_FILTER_EN (1 << 21)
+#define EMAC_RX_CTL_ACCEPT_BROADCAST_EN (1 << 22)
+#define EMAC_RX_CTL_SA_FILTER_EN (1 << 24)
+#define EMAC_RX_CTL_SA_FILTER_INVERT_EN (1 << 25)
+#define EMAC_RX_HASH0_REG (0x40)
+#define EMAC_RX_HASH1_REG (0x44)
+#define EMAC_RX_STA_REG (0x48)
+#define EMAC_RX_IO_DATA_REG (0x4c)
+#define EMAC_RX_IO_DATA_LEN(x) (x & 0xffff)
+#define EMAC_RX_IO_DATA_STATUS(x) ((x >> 16) & 0xffff)
+#define EMAC_RX_IO_DATA_STATUS_CRC_ERR (1 << 4)
+#define EMAC_RX_IO_DATA_STATUS_LEN_ERR (3 << 5)
+#define EMAC_RX_IO_DATA_STATUS_OK (1 << 7)
+#define EMAC_RX_FBC_REG (0x50)
+#define EMAC_INT_CTL_REG (0x54)
+#define EMAC_INT_STA_REG (0x58)
+#define EMAC_MAC_CTL0_REG (0x5c)
+#define EMAC_MAC_CTL0_RX_FLOW_CTL_EN (1 << 2)
+#define EMAC_MAC_CTL0_TX_FLOW_CTL_EN (1 << 3)
+#define EMAC_MAC_CTL0_SOFT_RESET (1 << 15)
+#define EMAC_MAC_CTL1_REG (0x60)
+#define EMAC_MAC_CTL1_DUPLEX_EN (1 << 0)
+#define EMAC_MAC_CTL1_LEN_CHECK_EN (1 << 1)
+#define EMAC_MAC_CTL1_HUGE_FRAME_EN (1 << 2)
+#define EMAC_MAC_CTL1_DELAYED_CRC_EN (1 << 3)
+#define EMAC_MAC_CTL1_CRC_EN (1 << 4)
+#define EMAC_MAC_CTL1_PAD_EN (1 << 5)
+#define EMAC_MAC_CTL1_PAD_CRC_EN (1 << 6)
+#define EMAC_MAC_CTL1_AD_SHORT_FRAME_EN (1 << 7)
+#define EMAC_MAC_CTL1_BACKOFF_DIS (1 << 12)
+#define EMAC_MAC_IPGT_REG (0x64)
+#define EMAC_MAC_IPGT_HALF_DUPLEX (0x12)
+#define EMAC_MAC_IPGT_FULL_DUPLEX (0x15)
+#define EMAC_MAC_IPGR_REG (0x68)
+#define EMAC_MAC_IPGR_IPG1 (0x0c)
+#define EMAC_MAC_IPGR_IPG2 (0x12)
+#define EMAC_MAC_CLRT_REG (0x6c)
+#define EMAC_MAC_CLRT_COLLISION_WINDOW (0x37)
+#define EMAC_MAC_CLRT_RM (0x0f)
+#define EMAC_MAC_MAXF_REG (0x70)
+#define EMAC_MAC_SUPP_REG (0x74)
+#define EMAC_MAC_TEST_REG (0x78)
+#define EMAC_MAC_MCFG_REG (0x7c)
+#define EMAC_MAC_A0_REG (0x98)
+#define EMAC_MAC_A1_REG (0x9c)
+#define EMAC_MAC_A2_REG (0xa0)
+#define EMAC_SAFX_L_REG0 (0xa4)
+#define EMAC_SAFX_H_REG0 (0xa8)
+#define EMAC_SAFX_L_REG1 (0xac)
+#define EMAC_SAFX_H_REG1 (0xb0)
+#define EMAC_SAFX_L_REG2 (0xb4)
+#define EMAC_SAFX_H_REG2 (0xb8)
+#define EMAC_SAFX_L_REG3 (0xbc)
+#define EMAC_SAFX_H_REG3 (0xc0)
+
+#define EMAC_PHY_DUPLEX (1 << 8)
+
+#define EMAC_EEPROM_MAGIC (0x444d394b)
+#define EMAC_UNDOCUMENTED_MAGIC (0x0143414d)
+#endif /* _SUN4I_EMAC_H_ */
diff --git a/drivers/net/ethernet/alteon/Kconfig b/drivers/net/ethernet/alteon/Kconfig
new file mode 100644
index 00000000000..799a8528207
--- /dev/null
+++ b/drivers/net/ethernet/alteon/Kconfig
@@ -0,0 +1,48 @@
+#
+# Alteon network device configuration
+#
+
+config NET_VENDOR_ALTEON
+ bool "Alteon devices"
+ default y
+ depends on PCI
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Alteon cards. If you say Y, you will be asked for
+ your specific card in the following questions.
+
+if NET_VENDOR_ALTEON
+
+config ACENIC
+ tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
+ depends on PCI
+ ---help---
+ Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
+ GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
+ adapter. The driver allows for using the Jumbo Frame option (9000
+ bytes/frame) however it requires that your switches can handle this
+ as well. To enable Jumbo Frames, add `mtu 9000' to your ifconfig
+ line.
+
+ To compile this driver as a module, choose M here: the
+ module will be called acenic.
+
+config ACENIC_OMIT_TIGON_I
+ bool "Omit support for old Tigon I based AceNICs"
+ depends on ACENIC
+ ---help---
+ Say Y here if you only have Tigon II based AceNICs and want to leave
+ out support for the older Tigon I based cards which are no longer
+ being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B
+ version)). This will reduce the size of the driver object by
+ app. 100KB. If you are not sure whether your card is a Tigon I or a
+ Tigon II, say N here.
+
+ The safe and default value for this is N.
+
+endif # NET_VENDOR_ALTEON
diff --git a/drivers/net/ethernet/alteon/Makefile b/drivers/net/ethernet/alteon/Makefile
new file mode 100644
index 00000000000..a2ca173f2a5
--- /dev/null
+++ b/drivers/net/ethernet/alteon/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Alteon network device drivers.
+#
+
+obj-$(CONFIG_ACENIC) += acenic.o
diff --git a/drivers/net/acenic.c b/drivers/net/ethernet/alteon/acenic.c
index 66de80b64b9..9a6991be974 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/ethernet/alteon/acenic.c
@@ -61,15 +61,14 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/sockios.h>
-
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/prefetch.h>
#include <linux/if_vlan.h>
-#endif
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
@@ -78,7 +77,6 @@
#include <net/sock.h>
#include <net/ip.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
@@ -133,7 +131,7 @@
#define PCI_DEVICE_ID_SGI_ACENIC 0x0009
#endif
-static struct pci_device_id acenic_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(acenic_pci_tbl) = {
{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE,
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_ALTEON_ACENIC_COPPER,
@@ -168,15 +166,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#define BOARD_IDX_STATIC 0
#define BOARD_IDX_OVERFLOW -1
-#if (defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)) && \
- defined(NETIF_F_HW_VLAN_RX)
-#define ACENIC_DO_VLAN 1
-#define ACE_RCB_VLAN_FLAG RCB_FLG_VLAN_ASSIST
-#else
-#define ACENIC_DO_VLAN 0
-#define ACE_RCB_VLAN_FLAG 0
-#endif
-
#include "acenic.h"
/*
@@ -186,8 +175,6 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
#define MAX_RODATA_LEN 8*1024
#define MAX_DATA_LEN 2*1024
-#include "acenic_firmware.h"
-
#ifndef tigon2FwReleaseLocal
#define tigon2FwReleaseLocal 0
#endif
@@ -417,6 +404,10 @@ static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
+#ifndef CONFIG_ACENIC_OMIT_TIGON_I
+MODULE_FIRMWARE("acenic/tg1.bin");
+#endif
+MODULE_FIRMWARE("acenic/tg2.bin");
module_param_array_named(link, link_state, int, NULL, 0);
module_param_array(trace, int, NULL, 0);
@@ -434,7 +425,7 @@ MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descript
MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)");
-static char version[] __devinitdata =
+static const char version[] =
"acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
@@ -450,43 +441,42 @@ static const struct ethtool_ops ace_ethtool_ops = {
static void ace_watchdog(struct net_device *dev);
-static int __devinit acenic_probe_one(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static const struct net_device_ops ace_netdev_ops = {
+ .ndo_open = ace_open,
+ .ndo_stop = ace_close,
+ .ndo_tx_timeout = ace_watchdog,
+ .ndo_get_stats = ace_get_stats,
+ .ndo_start_xmit = ace_start_xmit,
+ .ndo_set_rx_mode = ace_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = ace_set_mac_addr,
+ .ndo_change_mtu = ace_change_mtu,
+};
+
+static int acenic_probe_one(struct pci_dev *pdev,
+ const struct pci_device_id *id)
{
struct net_device *dev;
struct ace_private *ap;
static int boards_found;
dev = alloc_etherdev(sizeof(struct ace_private));
- if (dev == NULL) {
- printk(KERN_ERR "acenic: Unable to allocate "
- "net_device structure!\n");
+ if (dev == NULL)
return -ENOMEM;
- }
SET_NETDEV_DEV(dev, &pdev->dev);
- ap = dev->priv;
+ ap = netdev_priv(dev);
ap->pdev = pdev;
ap->name = pci_name(pdev);
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-#if ACENIC_DO_VLAN
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->vlan_rx_register = ace_vlan_rx_register;
-#endif
+ dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
- dev->tx_timeout = &ace_watchdog;
dev->watchdog_timeo = 5*HZ;
- dev->open = &ace_open;
- dev->stop = &ace_close;
- dev->hard_start_xmit = &ace_start_xmit;
- dev->get_stats = &ace_get_stats;
- dev->set_multicast_list = &ace_set_multicast_list;
- SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
- dev->set_mac_address = &ace_set_mac_addr;
- dev->change_mtu = &ace_change_mtu;
+ dev->netdev_ops = &ace_netdev_ops;
+ dev->ethtool_ops = &ace_ethtool_ops;
/* we only display this string ONCE */
if (!boards_found)
@@ -612,7 +602,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev,
return -ENODEV;
}
-static void __devexit acenic_remove_one(struct pci_dev *pdev)
+static void acenic_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct ace_private *ap = netdev_priv(dev);
@@ -650,7 +640,7 @@ static void __devexit acenic_remove_one(struct pci_dev *pdev)
dma_addr_t mapping;
ringp = &ap->skb->rx_std_skbuff[i];
- mapping = pci_unmap_addr(ringp, mapping);
+ mapping = dma_unmap_addr(ringp, mapping);
pci_unmap_page(ap->pdev, mapping,
ACE_STD_BUFSIZE,
PCI_DMA_FROMDEVICE);
@@ -670,7 +660,7 @@ static void __devexit acenic_remove_one(struct pci_dev *pdev)
dma_addr_t mapping;
ringp = &ap->skb->rx_mini_skbuff[i];
- mapping = pci_unmap_addr(ringp,mapping);
+ mapping = dma_unmap_addr(ringp,mapping);
pci_unmap_page(ap->pdev, mapping,
ACE_MINI_BUFSIZE,
PCI_DMA_FROMDEVICE);
@@ -689,7 +679,7 @@ static void __devexit acenic_remove_one(struct pci_dev *pdev)
dma_addr_t mapping;
ringp = &ap->skb->rx_jumbo_skbuff[i];
- mapping = pci_unmap_addr(ringp, mapping);
+ mapping = dma_unmap_addr(ringp, mapping);
pci_unmap_page(ap->pdev, mapping,
ACE_JUMBO_BUFSIZE,
PCI_DMA_FROMDEVICE);
@@ -708,22 +698,9 @@ static struct pci_driver acenic_pci_driver = {
.name = "acenic",
.id_table = acenic_pci_tbl,
.probe = acenic_probe_one,
- .remove = __devexit_p(acenic_remove_one),
+ .remove = acenic_remove_one,
};
-static int __init acenic_init(void)
-{
- return pci_register_driver(&acenic_pci_driver);
-}
-
-static void __exit acenic_exit(void)
-{
- pci_unregister_driver(&acenic_pci_driver);
-}
-
-module_init(acenic_init);
-module_exit(acenic_exit);
-
static void ace_free_descriptors(struct net_device *dev)
{
struct ace_private *ap = netdev_priv(dev);
@@ -880,7 +857,7 @@ static inline void ace_issue_cmd(struct ace_regs __iomem *regs, struct cmd *cmd)
}
-static int __devinit ace_init(struct net_device *dev)
+static int ace_init(struct net_device *dev)
{
struct ace_private *ap;
struct ace_regs __iomem *regs;
@@ -892,7 +869,6 @@ static int __devinit ace_init(struct net_device *dev)
int board_idx, ecode = 0;
short i;
unsigned char cache_size;
- DECLARE_MAC_BUF(mac);
ap = netdev_priv(dev);
regs = ap->regs;
@@ -938,8 +914,8 @@ static int __devinit ace_init(struct net_device *dev)
case 4:
case 5:
printk(KERN_INFO " Tigon I (Rev. %i), Firmware: %i.%i.%i, ",
- tig_ver, tigonFwReleaseMajor, tigonFwReleaseMinor,
- tigonFwReleaseFix);
+ tig_ver, ap->firmware_major, ap->firmware_minor,
+ ap->firmware_fix);
writel(0, &regs->LocalCtrl);
ap->version = 1;
ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES;
@@ -947,8 +923,8 @@ static int __devinit ace_init(struct net_device *dev)
#endif
case 6:
printk(KERN_INFO " Tigon II (Rev. %i), Firmware: %i.%i.%i, ",
- tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor,
- tigon2FwReleaseFix);
+ tig_ver, ap->firmware_major, ap->firmware_minor,
+ ap->firmware_fix);
writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl);
readl(&regs->CpuBCtrl); /* PCI write posting */
/*
@@ -1019,7 +995,7 @@ static int __devinit ace_init(struct net_device *dev)
dev->dev_addr[4] = (mac2 >> 8) & 0xff;
dev->dev_addr[5] = mac2 & 0xff;
- printk("MAC: %s\n", print_mac(mac, dev->dev_addr));
+ printk("MAC: %pM\n", dev->dev_addr);
/*
* Looks like this is necessary to deal with on all architectures,
@@ -1152,9 +1128,9 @@ static int __devinit ace_init(struct net_device *dev)
/*
* Configure DMA attributes.
*/
- if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+ if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
ap->pci_using_dac = 1;
- } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
ap->pci_using_dac = 0;
} else {
ecode = -ENODEV;
@@ -1200,7 +1176,10 @@ static int __devinit ace_init(struct net_device *dev)
memset(ap->info, 0, sizeof(struct ace_info));
memset(ap->skb, 0, sizeof(struct ace_skb));
- ace_load_firmware(dev);
+ ecode = ace_load_firmware(dev);
+ if (ecode)
+ goto init_error;
+
ap->fw_running = 0;
tmp_ptr = ap->info_dma;
@@ -1234,7 +1213,7 @@ static int __devinit ace_init(struct net_device *dev)
set_aceaddr(&info->rx_std_ctrl.rngptr, ap->rx_ring_base_dma);
info->rx_std_ctrl.max_len = ACE_STD_BUFSIZE;
info->rx_std_ctrl.flags =
- RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
+ RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST;
memset(ap->rx_std_ring, 0,
RX_STD_RING_ENTRIES * sizeof(struct rx_desc));
@@ -1250,7 +1229,7 @@ static int __devinit ace_init(struct net_device *dev)
(sizeof(struct rx_desc) * RX_STD_RING_ENTRIES)));
info->rx_jumbo_ctrl.max_len = 0;
info->rx_jumbo_ctrl.flags =
- RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
+ RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST;
memset(ap->rx_jumbo_ring, 0,
RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc));
@@ -1272,7 +1251,7 @@ static int __devinit ace_init(struct net_device *dev)
RX_JUMBO_RING_ENTRIES))));
info->rx_mini_ctrl.max_len = ACE_MINI_SIZE;
info->rx_mini_ctrl.flags =
- RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|ACE_RCB_VLAN_FLAG;
+ RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|RCB_FLG_VLAN_ASSIST;
for (i = 0; i < RX_MINI_RING_ENTRIES; i++)
ap->rx_mini_ring[i].flags =
@@ -1318,7 +1297,7 @@ static int __devinit ace_init(struct net_device *dev)
}
info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap);
- tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
+ tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | RCB_FLG_VLAN_ASSIST;
/*
* The Tigon I does not like having the TX ring in host memory ;-(
@@ -1436,10 +1415,7 @@ static int __devinit ace_init(struct net_device *dev)
if (ap->version >= 2)
writel(tmp, &regs->TuneFastLink);
- if (ACE_IS_TIGON_I(ap))
- writel(tigonFwStartAddr, &regs->Pc);
- if (ap->version == 2)
- writel(tigon2FwStartAddr, &regs->Pc);
+ writel(ap->firmware_start, &regs->Pc);
writel(0, &regs->Mb0Lo);
@@ -1508,13 +1484,13 @@ static int __devinit ace_init(struct net_device *dev)
* firmware to wipe the ring without re-initializing it.
*/
if (!test_and_set_bit(0, &ap->std_refill_busy))
- ace_load_std_rx_ring(ap, RX_RING_SIZE);
+ ace_load_std_rx_ring(dev, RX_RING_SIZE);
else
printk(KERN_ERR "%s: Someone is busy refilling the RX ring\n",
ap->name);
if (ap->version >= 2) {
if (!test_and_set_bit(0, &ap->mini_refill_busy))
- ace_load_mini_rx_ring(ap, RX_MINI_SIZE);
+ ace_load_mini_rx_ring(dev, RX_MINI_SIZE);
else
printk(KERN_ERR "%s: Someone is busy refilling "
"the RX mini ring\n", ap->name);
@@ -1574,7 +1550,7 @@ static void ace_watchdog(struct net_device *data)
/*
* We haven't received a stats update event for more than 2.5
* seconds and there is data in the transmit queue, thus we
- * asume the card is stuck.
+ * assume the card is stuck.
*/
if (*ap->tx_csm != ap->tx_ret_csm) {
printk(KERN_WARNING "%s: Transmitter is stuck, %08x\n",
@@ -1590,9 +1566,10 @@ static void ace_watchdog(struct net_device *data)
}
-static void ace_tasklet(unsigned long dev)
+static void ace_tasklet(unsigned long arg)
{
- struct ace_private *ap = netdev_priv((struct net_device *)dev);
+ struct net_device *dev = (struct net_device *) arg;
+ struct ace_private *ap = netdev_priv(dev);
int cur_size;
cur_size = atomic_read(&ap->cur_rx_bufs);
@@ -1601,7 +1578,7 @@ static void ace_tasklet(unsigned long dev)
#ifdef DEBUG
printk("refilling buffers (current %i)\n", cur_size);
#endif
- ace_load_std_rx_ring(ap, RX_RING_SIZE - cur_size);
+ ace_load_std_rx_ring(dev, RX_RING_SIZE - cur_size);
}
if (ap->version >= 2) {
@@ -1612,7 +1589,7 @@ static void ace_tasklet(unsigned long dev)
printk("refilling mini buffers (current %i)\n",
cur_size);
#endif
- ace_load_mini_rx_ring(ap, RX_MINI_SIZE - cur_size);
+ ace_load_mini_rx_ring(dev, RX_MINI_SIZE - cur_size);
}
}
@@ -1622,7 +1599,7 @@ static void ace_tasklet(unsigned long dev)
#ifdef DEBUG
printk("refilling jumbo buffers (current %i)\n", cur_size);
#endif
- ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size);
+ ace_load_jumbo_rx_ring(dev, RX_JUMBO_SIZE - cur_size);
}
ap->tasklet_pending = 0;
}
@@ -1648,8 +1625,9 @@ static void ace_dump_trace(struct ace_private *ap)
* done only before the device is enabled, thus no interrupts are
* generated and by the interrupt handler/tasklet handler.
*/
-static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)
+static void ace_load_std_rx_ring(struct net_device *dev, int nr_bufs)
{
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs __iomem *regs = ap->regs;
short i, idx;
@@ -1663,17 +1641,16 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)
struct rx_desc *rd;
dma_addr_t mapping;
- skb = alloc_skb(ACE_STD_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC);
+ skb = netdev_alloc_skb_ip_align(dev, ACE_STD_BUFSIZE);
if (!skb)
break;
- skb_reserve(skb, NET_IP_ALIGN);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
offset_in_page(skb->data),
ACE_STD_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->skb->rx_std_skbuff[idx].skb = skb;
- pci_unmap_addr_set(&ap->skb->rx_std_skbuff[idx],
+ dma_unmap_addr_set(&ap->skb->rx_std_skbuff[idx],
mapping, mapping);
rd = &ap->rx_std_ring[idx];
@@ -1711,8 +1688,9 @@ static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)
}
-static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)
+static void ace_load_mini_rx_ring(struct net_device *dev, int nr_bufs)
{
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs __iomem *regs = ap->regs;
short i, idx;
@@ -1724,17 +1702,16 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)
struct rx_desc *rd;
dma_addr_t mapping;
- skb = alloc_skb(ACE_MINI_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC);
+ skb = netdev_alloc_skb_ip_align(dev, ACE_MINI_BUFSIZE);
if (!skb)
break;
- skb_reserve(skb, NET_IP_ALIGN);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
offset_in_page(skb->data),
ACE_MINI_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->skb->rx_mini_skbuff[idx].skb = skb;
- pci_unmap_addr_set(&ap->skb->rx_mini_skbuff[idx],
+ dma_unmap_addr_set(&ap->skb->rx_mini_skbuff[idx],
mapping, mapping);
rd = &ap->rx_mini_ring[idx];
@@ -1768,8 +1745,9 @@ static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)
* Load the jumbo rx ring, this may happen at any time if the MTU
* is changed to a value > 1500.
*/
-static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs)
+static void ace_load_jumbo_rx_ring(struct net_device *dev, int nr_bufs)
{
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs __iomem *regs = ap->regs;
short i, idx;
@@ -1780,17 +1758,16 @@ static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs)
struct rx_desc *rd;
dma_addr_t mapping;
- skb = alloc_skb(ACE_JUMBO_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC);
+ skb = netdev_alloc_skb_ip_align(dev, ACE_JUMBO_BUFSIZE);
if (!skb)
break;
- skb_reserve(skb, NET_IP_ALIGN);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
offset_in_page(skb->data),
ACE_JUMBO_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->skb->rx_jumbo_skbuff[idx].skb = skb;
- pci_unmap_addr_set(&ap->skb->rx_jumbo_skbuff[idx],
+ dma_unmap_addr_set(&ap->skb->rx_jumbo_skbuff[idx],
mapping, mapping);
rd = &ap->rx_jumbo_ring[idx];
@@ -2003,7 +1980,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
skb = rip->skb;
rip->skb = NULL;
pci_unmap_page(ap->pdev,
- pci_unmap_addr(rip, mapping),
+ dma_unmap_addr(rip, mapping),
mapsize,
PCI_DMA_FROMDEVICE);
skb_put(skb, retdesc->size);
@@ -2023,18 +2000,14 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
skb->csum = htons(csum);
skb->ip_summed = CHECKSUM_COMPLETE;
} else {
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
}
/* send it up */
-#if ACENIC_DO_VLAN
- if (ap->vlgrp && (bd_flags & BD_FLG_VLAN_TAG)) {
- vlan_hwaccel_rx(skb, ap->vlgrp, retdesc->vlan);
- } else
-#endif
- netif_rx(skb);
+ if ((bd_flags & BD_FLG_VLAN_TAG))
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), retdesc->vlan);
+ netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += retdesc->size;
@@ -2069,18 +2042,16 @@ static inline void ace_tx_int(struct net_device *dev,
do {
struct sk_buff *skb;
- dma_addr_t mapping;
struct tx_ring_info *info;
info = ap->skb->tx_skbuff + idx;
skb = info->skb;
- mapping = pci_unmap_addr(info, mapping);
- if (mapping) {
- pci_unmap_page(ap->pdev, mapping,
- pci_unmap_len(info, maplen),
+ if (dma_unmap_len(info, maplen)) {
+ pci_unmap_page(ap->pdev, dma_unmap_addr(info, mapping),
+ dma_unmap_len(info, maplen),
PCI_DMA_TODEVICE);
- pci_unmap_addr_set(info, mapping, 0);
+ dma_unmap_len_set(info, maplen, 0);
}
if (skb) {
@@ -2208,7 +2179,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
#ifdef DEBUG
printk("low on std buffers %i\n", cur_size);
#endif
- ace_load_std_rx_ring(ap,
+ ace_load_std_rx_ring(dev,
RX_RING_SIZE - cur_size);
} else
run_tasklet = 1;
@@ -2224,7 +2195,8 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
printk("low on mini buffers %i\n",
cur_size);
#endif
- ace_load_mini_rx_ring(ap, RX_MINI_SIZE - cur_size);
+ ace_load_mini_rx_ring(dev,
+ RX_MINI_SIZE - cur_size);
} else
run_tasklet = 1;
}
@@ -2240,7 +2212,8 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
printk("low on jumbo buffers %i\n",
cur_size);
#endif
- ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size);
+ ace_load_jumbo_rx_ring(dev,
+ RX_JUMBO_SIZE - cur_size);
} else
run_tasklet = 1;
}
@@ -2254,24 +2227,6 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-
-#if ACENIC_DO_VLAN
-static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
- struct ace_private *ap = netdev_priv(dev);
- unsigned long flags;
-
- local_irq_save(flags);
- ace_mask_irq(dev);
-
- ap->vlgrp = grp;
-
- ace_unmask_irq(dev);
- local_irq_restore(flags);
-}
-#endif /* ACENIC_DO_VLAN */
-
-
static int ace_open(struct net_device *dev)
{
struct ace_private *ap = netdev_priv(dev);
@@ -2297,7 +2252,7 @@ static int ace_open(struct net_device *dev)
if (ap->jumbo &&
!test_and_set_bit(0, &ap->jumbo_refill_busy))
- ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE);
+ ace_load_jumbo_rx_ring(dev, RX_JUMBO_SIZE);
if (dev->flags & IFF_PROMISC) {
cmd.evt = C_SET_PROMISC_MODE;
@@ -2368,14 +2323,12 @@ static int ace_close(struct net_device *dev)
for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) {
struct sk_buff *skb;
- dma_addr_t mapping;
struct tx_ring_info *info;
info = ap->skb->tx_skbuff + i;
skb = info->skb;
- mapping = pci_unmap_addr(info, mapping);
- if (mapping) {
+ if (dma_unmap_len(info, maplen)) {
if (ACE_IS_TIGON_I(ap)) {
/* NB: TIGON_1 is special, tx_ring is in io space */
struct tx_desc __iomem *tx;
@@ -2386,10 +2339,10 @@ static int ace_close(struct net_device *dev)
} else
memset(ap->tx_ring + i, 0,
sizeof(struct tx_desc));
- pci_unmap_page(ap->pdev, mapping,
- pci_unmap_len(info, maplen),
+ pci_unmap_page(ap->pdev, dma_unmap_addr(info, mapping),
+ dma_unmap_len(info, maplen),
PCI_DMA_TODEVICE);
- pci_unmap_addr_set(info, mapping, 0);
+ dma_unmap_len_set(info, maplen, 0);
}
if (skb) {
dev_kfree_skb(skb);
@@ -2424,8 +2377,8 @@ ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
info = ap->skb->tx_skbuff + idx;
info->skb = tail;
- pci_unmap_addr_set(info, mapping, mapping);
- pci_unmap_len_set(info, maplen, skb->len);
+ dma_unmap_addr_set(info, mapping, mapping);
+ dma_unmap_len_set(info, maplen, skb->len);
return mapping;
}
@@ -2443,21 +2396,18 @@ ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr,
writel(addr >> 32, &io->addr.addrhi);
writel(addr & 0xffffffff, &io->addr.addrlo);
writel(flagsize, &io->flagsize);
-#if ACENIC_DO_VLAN
writel(vlan_tag, &io->vlanres);
-#endif
} else {
desc->addr.addrhi = addr >> 32;
desc->addr.addrlo = addr;
desc->flagsize = flagsize;
-#if ACENIC_DO_VLAN
desc->vlanres = vlan_tag;
-#endif
}
}
-static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ace_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
struct ace_private *ap = netdev_priv(dev);
struct ace_regs __iomem *regs = ap->regs;
@@ -2479,12 +2429,10 @@ restart:
flagsize = (skb->len << 16) | (BD_FLG_END);
if (skb->ip_summed == CHECKSUM_PARTIAL)
flagsize |= BD_FLG_TCP_UDP_SUM;
-#if ACENIC_DO_VLAN
if (vlan_tx_tag_present(skb)) {
flagsize |= BD_FLG_VLAN_TAG;
vlan_tag = vlan_tx_tag_get(skb);
}
-#endif
desc = ap->tx_ring + idx;
idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
@@ -2502,30 +2450,28 @@ restart:
flagsize = (skb_headlen(skb) << 16);
if (skb->ip_summed == CHECKSUM_PARTIAL)
flagsize |= BD_FLG_TCP_UDP_SUM;
-#if ACENIC_DO_VLAN
if (vlan_tx_tag_present(skb)) {
flagsize |= BD_FLG_VLAN_TAG;
vlan_tag = vlan_tx_tag_get(skb);
}
-#endif
ace_load_tx_bd(ap, ap->tx_ring + idx, mapping, flagsize, vlan_tag);
idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
struct tx_ring_info *info;
- len += frag->size;
+ len += skb_frag_size(frag);
info = ap->skb->tx_skbuff + idx;
desc = ap->tx_ring + idx;
- mapping = pci_map_page(ap->pdev, frag->page,
- frag->page_offset, frag->size,
- PCI_DMA_TODEVICE);
+ mapping = skb_frag_dma_map(&ap->pdev->dev, frag, 0,
+ skb_frag_size(frag),
+ DMA_TO_DEVICE);
- flagsize = (frag->size << 16);
+ flagsize = skb_frag_size(frag) << 16;
if (skb->ip_summed == CHECKSUM_PARTIAL)
flagsize |= BD_FLG_TCP_UDP_SUM;
idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
@@ -2543,8 +2489,8 @@ restart:
} else {
info->skb = NULL;
}
- pci_unmap_addr_set(info, mapping, mapping);
- pci_unmap_len_set(info, maplen, frag->size);
+ dma_unmap_addr_set(info, mapping, mapping);
+ dma_unmap_len_set(info, maplen, skb_frag_size(frag));
ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
}
}
@@ -2558,7 +2504,7 @@ restart:
/*
* A TX-descriptor producer (an IRQ) might have gotten
- * inbetween, making the ring free again. Since xmit is
+ * between, making the ring free again. Since xmit is
* serialized, this is the only situation we have to
* re-test.
*/
@@ -2566,7 +2512,6 @@ restart:
netif_wake_queue(dev);
}
- dev->trans_start = jiffies;
return NETDEV_TX_OK;
overflow:
@@ -2615,7 +2560,7 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu)
"support\n", dev->name);
ap->jumbo = 1;
if (!test_and_set_bit(0, &ap->jumbo_refill_busy))
- ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE);
+ ace_load_jumbo_rx_ring(dev, RX_JUMBO_SIZE);
ace_set_rxtx_parms(dev, 1);
}
} else {
@@ -2653,15 +2598,15 @@ static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
link = readl(&regs->GigLnkState);
if (link & LNK_1000MB)
- ecmd->speed = SPEED_1000;
+ ethtool_cmd_speed_set(ecmd, SPEED_1000);
else {
link = readl(&regs->FastLnkState);
if (link & LNK_100MB)
- ecmd->speed = SPEED_100;
+ ethtool_cmd_speed_set(ecmd, SPEED_100);
else if (link & LNK_10MB)
- ecmd->speed = SPEED_10;
+ ethtool_cmd_speed_set(ecmd, SPEED_10);
else
- ecmd->speed = 0;
+ ethtool_cmd_speed_set(ecmd, 0);
}
if (link & LNK_FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
@@ -2713,9 +2658,9 @@ static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
link |= LNK_TX_FLOW_CTL_Y;
if (ecmd->autoneg == AUTONEG_ENABLE)
link |= LNK_NEGOTIATE;
- if (ecmd->speed != speed) {
+ if (ethtool_cmd_speed(ecmd) != speed) {
link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
- switch (speed) {
+ switch (ethtool_cmd_speed(ecmd)) {
case SPEED_1000:
link |= LNK_1000MB;
break;
@@ -2757,8 +2702,8 @@ static void ace_get_drvinfo(struct net_device *dev,
strlcpy(info->driver, "acenic", sizeof(info->driver));
snprintf(info->version, sizeof(info->version), "%i.%i.%i",
- tigonFwReleaseMajor, tigonFwReleaseMinor,
- tigonFwReleaseFix);
+ ap->firmware_major, ap->firmware_minor,
+ ap->firmware_fix);
if (ap->pdev)
strlcpy(info->bus_info, pci_name(ap->pdev),
@@ -2837,7 +2782,7 @@ static void ace_set_multicast_list(struct net_device *dev)
* set the entire multicast list at a time and keeping track of
* it here is going to be messy.
*/
- if ((dev->mc_count) && !(ap->mcast_all)) {
+ if (!netdev_mc_empty(dev) && !ap->mcast_all) {
cmd.evt = C_SET_MULTICAST_MODE;
cmd.code = C_C_MCAST_ENABLE;
cmd.idx = 0;
@@ -2865,11 +2810,10 @@ static struct net_device_stats *ace_get_stats(struct net_device *dev)
}
-static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src,
- u32 dest, int size)
+static void ace_copy(struct ace_regs __iomem *regs, const __be32 *src,
+ u32 dest, int size)
{
void __iomem *tdest;
- u32 *wsrc;
short tsize, i;
if (size <= 0)
@@ -2881,24 +2825,19 @@ static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src,
tdest = (void __iomem *) &regs->Window +
(dest & (ACE_WINDOW_SIZE - 1));
writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
- /*
- * This requires byte swapping on big endian, however
- * writel does that for us
- */
- wsrc = src;
for (i = 0; i < (tsize / 4); i++) {
- writel(wsrc[i], tdest + i*4);
+ /* Firmware is big-endian */
+ writel(be32_to_cpup(src), tdest);
+ src++;
+ tdest += 4;
+ dest += 4;
+ size -= 4;
}
- dest += tsize;
- src += tsize;
- size -= tsize;
}
-
- return;
}
-static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int size)
+static void ace_clear(struct ace_regs __iomem *regs, u32 dest, int size)
{
void __iomem *tdest;
short tsize = 0, i;
@@ -2920,8 +2859,6 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz
dest += tsize;
size -= tsize;
}
-
- return;
}
@@ -2931,10 +2868,15 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz
* This operation requires the NIC to be halted and is performed with
* interrupts disabled and with the spinlock hold.
*/
-static int __devinit ace_load_firmware(struct net_device *dev)
+static int ace_load_firmware(struct net_device *dev)
{
+ const struct firmware *fw;
+ const char *fw_name = "acenic/tg2.bin";
struct ace_private *ap = netdev_priv(dev);
struct ace_regs __iomem *regs = ap->regs;
+ const __be32 *fw_data;
+ u32 load_addr;
+ int ret;
if (!(readl(&regs->CpuCtrl) & CPU_HALTED)) {
printk(KERN_ERR "%s: trying to download firmware while the "
@@ -2942,28 +2884,52 @@ static int __devinit ace_load_firmware(struct net_device *dev)
return -EFAULT;
}
+ if (ACE_IS_TIGON_I(ap))
+ fw_name = "acenic/tg1.bin";
+
+ ret = request_firmware(&fw, fw_name, &ap->pdev->dev);
+ if (ret) {
+ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+ ap->name, fw_name);
+ return ret;
+ }
+
+ fw_data = (void *)fw->data;
+
+ /* Firmware blob starts with version numbers, followed by
+ load and start address. Remainder is the blob to be loaded
+ contiguously from load address. We don't bother to represent
+ the BSS/SBSS sections any more, since we were clearing the
+ whole thing anyway. */
+ ap->firmware_major = fw->data[0];
+ ap->firmware_minor = fw->data[1];
+ ap->firmware_fix = fw->data[2];
+
+ ap->firmware_start = be32_to_cpu(fw_data[1]);
+ if (ap->firmware_start < 0x4000 || ap->firmware_start >= 0x80000) {
+ printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n",
+ ap->name, ap->firmware_start, fw_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ load_addr = be32_to_cpu(fw_data[2]);
+ if (load_addr < 0x4000 || load_addr >= 0x80000) {
+ printk(KERN_ERR "%s: bogus load address %08x in \"%s\"\n",
+ ap->name, load_addr, fw_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
/*
- * Do not try to clear more than 512KB or we end up seeing
- * funny things on NICs with only 512KB SRAM
+ * Do not try to clear more than 512KiB or we end up seeing
+ * funny things on NICs with only 512KiB SRAM
*/
ace_clear(regs, 0x2000, 0x80000-0x2000);
- if (ACE_IS_TIGON_I(ap)) {
- ace_copy(regs, tigonFwText, tigonFwTextAddr, tigonFwTextLen);
- ace_copy(regs, tigonFwData, tigonFwDataAddr, tigonFwDataLen);
- ace_copy(regs, tigonFwRodata, tigonFwRodataAddr,
- tigonFwRodataLen);
- ace_clear(regs, tigonFwBssAddr, tigonFwBssLen);
- ace_clear(regs, tigonFwSbssAddr, tigonFwSbssLen);
- }else if (ap->version == 2) {
- ace_clear(regs, tigon2FwBssAddr, tigon2FwBssLen);
- ace_clear(regs, tigon2FwSbssAddr, tigon2FwSbssLen);
- ace_copy(regs, tigon2FwText, tigon2FwTextAddr,tigon2FwTextLen);
- ace_copy(regs, tigon2FwRodata, tigon2FwRodataAddr,
- tigon2FwRodataLen);
- ace_copy(regs, tigon2FwData, tigon2FwDataAddr,tigon2FwDataLen);
- }
-
- return 0;
+ ace_copy(regs, &fw_data[3], load_addr, fw->size-12);
+ out:
+ release_firmware(fw);
+ return ret;
}
@@ -2982,7 +2948,7 @@ static int __devinit ace_load_firmware(struct net_device *dev)
* Thanks to Stevarino Webinski for helping tracking down the bugs in the
* code i2c readout code by beta testing all my hacks.
*/
-static void __devinit eeprom_start(struct ace_regs __iomem *regs)
+static void eeprom_start(struct ace_regs __iomem *regs)
{
u32 local;
@@ -3011,7 +2977,7 @@ static void __devinit eeprom_start(struct ace_regs __iomem *regs)
}
-static void __devinit eeprom_prep(struct ace_regs __iomem *regs, u8 magic)
+static void eeprom_prep(struct ace_regs __iomem *regs, u8 magic)
{
short i;
u32 local;
@@ -3048,7 +3014,7 @@ static void __devinit eeprom_prep(struct ace_regs __iomem *regs, u8 magic)
}
-static int __devinit eeprom_check_ack(struct ace_regs __iomem *regs)
+static int eeprom_check_ack(struct ace_regs __iomem *regs)
{
int state;
u32 local;
@@ -3076,7 +3042,7 @@ static int __devinit eeprom_check_ack(struct ace_regs __iomem *regs)
}
-static void __devinit eeprom_stop(struct ace_regs __iomem *regs)
+static void eeprom_stop(struct ace_regs __iomem *regs)
{
u32 local;
@@ -3111,8 +3077,7 @@ static void __devinit eeprom_stop(struct ace_regs __iomem *regs)
/*
* Read a whole byte from the EEPROM.
*/
-static int __devinit read_eeprom_byte(struct net_device *dev,
- unsigned long offset)
+static int read_eeprom_byte(struct net_device *dev, unsigned long offset)
{
struct ace_private *ap = netdev_priv(dev);
struct ace_regs __iomem *regs = ap->regs;
@@ -3221,9 +3186,4 @@ static int __devinit read_eeprom_byte(struct net_device *dev,
goto out;
}
-
-/*
- * Local variables:
- * compile-command: "gcc -D__SMP__ -D__KERNEL__ -DMODULE -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include ../../include/linux/modversions.h -c -o acenic.o acenic.c"
- * End:
- */
+module_pci_driver(acenic_pci_driver);
diff --git a/drivers/net/acenic.h b/drivers/net/ethernet/alteon/acenic.h
index 4487f32759a..51c486cfbb8 100644
--- a/drivers/net/acenic.h
+++ b/drivers/net/ethernet/alteon/acenic.h
@@ -1,5 +1,6 @@
#ifndef _ACENIC_H_
#define _ACENIC_H_
+#include <linux/interrupt.h>
/*
@@ -589,7 +590,7 @@ struct ace_info {
struct ring_info {
struct sk_buff *skb;
- DECLARE_PCI_UNMAP_ADDR(mapping)
+ DEFINE_DMA_UNMAP_ADDR(mapping);
};
@@ -600,8 +601,8 @@ struct ring_info {
*/
struct tx_ring_info {
struct sk_buff *skb;
- DECLARE_PCI_UNMAP_ADDR(mapping)
- DECLARE_PCI_UNMAP_LEN(maplen)
+ DEFINE_DMA_UNMAP_ADDR(mapping);
+ DEFINE_DMA_UNMAP_LEN(maplen);
};
@@ -664,10 +665,6 @@ struct ace_private
struct rx_desc *rx_mini_ring;
struct rx_desc *rx_return_ring;
-#if ACENIC_DO_VLAN
- struct vlan_group *vlgrp;
-#endif
-
int tasklet_pending, jumbo;
struct tasklet_struct ace_tasklet;
@@ -694,6 +691,10 @@ struct ace_private
u32 last_tx, last_std_rx, last_mini_rx;
#endif
int pci_using_dac;
+ u8 firmware_major;
+ u8 firmware_minor;
+ u8 firmware_fix;
+ u32 firmware_start;
};
@@ -765,13 +766,14 @@ static inline void ace_unmask_irq(struct net_device *dev)
* Prototypes
*/
static int ace_init(struct net_device *dev);
-static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs);
-static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs);
-static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs);
+static void ace_load_std_rx_ring(struct net_device *dev, int nr_bufs);
+static void ace_load_mini_rx_ring(struct net_device *dev, int nr_bufs);
+static void ace_load_jumbo_rx_ring(struct net_device *dev, int nr_bufs);
static irqreturn_t ace_interrupt(int irq, void *dev_id);
static int ace_load_firmware(struct net_device *dev);
static int ace_open(struct net_device *dev);
-static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ace_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
static int ace_close(struct net_device *dev);
static void ace_tasklet(unsigned long dev);
static void ace_dump_trace(struct ace_private *ap);
@@ -784,8 +786,5 @@ static void ace_free_descriptors(struct net_device *dev);
static void ace_init_cleanup(struct net_device *dev);
static struct net_device_stats *ace_get_stats(struct net_device *dev);
static int read_eeprom_byte(struct net_device *dev, unsigned long offset);
-#if ACENIC_DO_VLAN
-static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
-#endif
#endif /* _ACENIC_H_ */
diff --git a/drivers/net/ethernet/altera/Kconfig b/drivers/net/ethernet/altera/Kconfig
new file mode 100644
index 00000000000..fdddba51473
--- /dev/null
+++ b/drivers/net/ethernet/altera/Kconfig
@@ -0,0 +1,9 @@
+config ALTERA_TSE
+ tristate "Altera Triple-Speed Ethernet MAC support"
+ depends on HAS_DMA
+ select PHYLIB
+ ---help---
+ This driver supports the Altera Triple-Speed (TSE) Ethernet MAC.
+
+ To compile this driver as a module, choose M here. The module
+ will be called alteratse.
diff --git a/drivers/net/ethernet/altera/Makefile b/drivers/net/ethernet/altera/Makefile
new file mode 100644
index 00000000000..3eff2fd3997
--- /dev/null
+++ b/drivers/net/ethernet/altera/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the Altera device drivers.
+#
+
+obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
+altera_tse-objs := altera_tse_main.o altera_tse_ethtool.o \
+altera_msgdma.o altera_sgdma.o altera_utils.o
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c
new file mode 100644
index 00000000000..0fb986ba329
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_msgdma.c
@@ -0,0 +1,206 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/netdevice.h>
+#include "altera_utils.h"
+#include "altera_tse.h"
+#include "altera_msgdmahw.h"
+#include "altera_msgdma.h"
+
+/* No initialization work to do for MSGDMA */
+int msgdma_initialize(struct altera_tse_private *priv)
+{
+ return 0;
+}
+
+void msgdma_uninitialize(struct altera_tse_private *priv)
+{
+}
+
+void msgdma_start_rxdma(struct altera_tse_private *priv)
+{
+}
+
+void msgdma_reset(struct altera_tse_private *priv)
+{
+ int counter;
+
+ /* Reset Rx mSGDMA */
+ csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr,
+ msgdma_csroffs(status));
+ csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr,
+ msgdma_csroffs(control));
+
+ counter = 0;
+ while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
+ if (tse_bit_is_clear(priv->rx_dma_csr, msgdma_csroffs(status),
+ MSGDMA_CSR_STAT_RESETTING))
+ break;
+ udelay(1);
+ }
+
+ if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
+ netif_warn(priv, drv, priv->dev,
+ "TSE Rx mSGDMA resetting bit never cleared!\n");
+
+ /* clear all status bits */
+ csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, msgdma_csroffs(status));
+
+ /* Reset Tx mSGDMA */
+ csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr,
+ msgdma_csroffs(status));
+
+ csrwr32(MSGDMA_CSR_CTL_RESET, priv->tx_dma_csr,
+ msgdma_csroffs(control));
+
+ counter = 0;
+ while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
+ if (tse_bit_is_clear(priv->tx_dma_csr, msgdma_csroffs(status),
+ MSGDMA_CSR_STAT_RESETTING))
+ break;
+ udelay(1);
+ }
+
+ if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
+ netif_warn(priv, drv, priv->dev,
+ "TSE Tx mSGDMA resetting bit never cleared!\n");
+
+ /* clear all status bits */
+ csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, msgdma_csroffs(status));
+}
+
+void msgdma_disable_rxirq(struct altera_tse_private *priv)
+{
+ tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control),
+ MSGDMA_CSR_CTL_GLOBAL_INTR);
+}
+
+void msgdma_enable_rxirq(struct altera_tse_private *priv)
+{
+ tse_set_bit(priv->rx_dma_csr, msgdma_csroffs(control),
+ MSGDMA_CSR_CTL_GLOBAL_INTR);
+}
+
+void msgdma_disable_txirq(struct altera_tse_private *priv)
+{
+ tse_clear_bit(priv->tx_dma_csr, msgdma_csroffs(control),
+ MSGDMA_CSR_CTL_GLOBAL_INTR);
+}
+
+void msgdma_enable_txirq(struct altera_tse_private *priv)
+{
+ tse_set_bit(priv->tx_dma_csr, msgdma_csroffs(control),
+ MSGDMA_CSR_CTL_GLOBAL_INTR);
+}
+
+void msgdma_clear_rxirq(struct altera_tse_private *priv)
+{
+ csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status));
+}
+
+void msgdma_clear_txirq(struct altera_tse_private *priv)
+{
+ csrwr32(MSGDMA_CSR_STAT_IRQ, priv->tx_dma_csr, msgdma_csroffs(status));
+}
+
+/* return 0 to indicate transmit is pending */
+int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
+{
+ csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc,
+ msgdma_descroffs(read_addr_lo));
+ csrwr32(upper_32_bits(buffer->dma_addr), priv->tx_dma_desc,
+ msgdma_descroffs(read_addr_hi));
+ csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_lo));
+ csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_hi));
+ csrwr32(buffer->len, priv->tx_dma_desc, msgdma_descroffs(len));
+ csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(burst_seq_num));
+ csrwr32(MSGDMA_DESC_TX_STRIDE, priv->tx_dma_desc,
+ msgdma_descroffs(stride));
+ csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc,
+ msgdma_descroffs(control));
+ return 0;
+}
+
+u32 msgdma_tx_completions(struct altera_tse_private *priv)
+{
+ u32 ready = 0;
+ u32 inuse;
+ u32 status;
+
+ /* Get number of sent descriptors */
+ inuse = csrrd32(priv->tx_dma_csr, msgdma_csroffs(rw_fill_level))
+ & 0xffff;
+
+ if (inuse) { /* Tx FIFO is not empty */
+ ready = priv->tx_prod - priv->tx_cons - inuse - 1;
+ } else {
+ /* Check for buffered last packet */
+ status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status));
+ if (status & MSGDMA_CSR_STAT_BUSY)
+ ready = priv->tx_prod - priv->tx_cons - 1;
+ else
+ ready = priv->tx_prod - priv->tx_cons;
+ }
+ return ready;
+}
+
+/* Put buffer to the mSGDMA RX FIFO
+ */
+void msgdma_add_rx_desc(struct altera_tse_private *priv,
+ struct tse_buffer *rxbuffer)
+{
+ u32 len = priv->rx_dma_buf_sz;
+ dma_addr_t dma_addr = rxbuffer->dma_addr;
+ u32 control = (MSGDMA_DESC_CTL_END_ON_EOP
+ | MSGDMA_DESC_CTL_END_ON_LEN
+ | MSGDMA_DESC_CTL_TR_COMP_IRQ
+ | MSGDMA_DESC_CTL_EARLY_IRQ
+ | MSGDMA_DESC_CTL_TR_ERR_IRQ
+ | MSGDMA_DESC_CTL_GO);
+
+ csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo));
+ csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi));
+ csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc,
+ msgdma_descroffs(write_addr_lo));
+ csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc,
+ msgdma_descroffs(write_addr_hi));
+ csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len));
+ csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(burst_seq_num));
+ csrwr32(0x00010001, priv->rx_dma_desc, msgdma_descroffs(stride));
+ csrwr32(control, priv->rx_dma_desc, msgdma_descroffs(control));
+}
+
+/* status is returned on upper 16 bits,
+ * length is returned in lower 16 bits
+ */
+u32 msgdma_rx_status(struct altera_tse_private *priv)
+{
+ u32 rxstatus = 0;
+ u32 pktlength;
+ u32 pktstatus;
+
+ if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level))
+ & 0xffff) {
+ pktlength = csrrd32(priv->rx_dma_resp,
+ msgdma_respoffs(bytes_transferred));
+ pktstatus = csrrd32(priv->rx_dma_resp,
+ msgdma_respoffs(status));
+ rxstatus = pktstatus;
+ rxstatus = rxstatus << 16;
+ rxstatus |= (pktlength & 0xffff);
+ }
+ return rxstatus;
+}
diff --git a/drivers/net/ethernet/altera/altera_msgdma.h b/drivers/net/ethernet/altera/altera_msgdma.h
new file mode 100644
index 00000000000..42cf61c8105
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_msgdma.h
@@ -0,0 +1,35 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ALTERA_MSGDMA_H__
+#define __ALTERA_MSGDMA_H__
+
+void msgdma_reset(struct altera_tse_private *);
+void msgdma_enable_txirq(struct altera_tse_private *);
+void msgdma_enable_rxirq(struct altera_tse_private *);
+void msgdma_disable_rxirq(struct altera_tse_private *);
+void msgdma_disable_txirq(struct altera_tse_private *);
+void msgdma_clear_rxirq(struct altera_tse_private *);
+void msgdma_clear_txirq(struct altera_tse_private *);
+u32 msgdma_tx_completions(struct altera_tse_private *);
+void msgdma_add_rx_desc(struct altera_tse_private *, struct tse_buffer *);
+int msgdma_tx_buffer(struct altera_tse_private *, struct tse_buffer *);
+u32 msgdma_rx_status(struct altera_tse_private *);
+int msgdma_initialize(struct altera_tse_private *);
+void msgdma_uninitialize(struct altera_tse_private *);
+void msgdma_start_rxdma(struct altera_tse_private *);
+
+#endif /* __ALTERA_MSGDMA_H__ */
diff --git a/drivers/net/ethernet/altera/altera_msgdmahw.h b/drivers/net/ethernet/altera/altera_msgdmahw.h
new file mode 100644
index 00000000000..e335626e1b6
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_msgdmahw.h
@@ -0,0 +1,162 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ALTERA_MSGDMAHW_H__
+#define __ALTERA_MSGDMAHW_H__
+
+/* mSGDMA extended descriptor format
+ */
+struct msgdma_extended_desc {
+ u32 read_addr_lo; /* data buffer source address low bits */
+ u32 write_addr_lo; /* data buffer destination address low bits */
+ u32 len; /* the number of bytes to transfer
+ * per descriptor
+ */
+ u32 burst_seq_num; /* bit 31:24 write burst
+ * bit 23:16 read burst
+ * bit 15:0 sequence number
+ */
+ u32 stride; /* bit 31:16 write stride
+ * bit 15:0 read stride
+ */
+ u32 read_addr_hi; /* data buffer source address high bits */
+ u32 write_addr_hi; /* data buffer destination address high bits */
+ u32 control; /* characteristics of the transfer */
+};
+
+/* mSGDMA descriptor control field bit definitions
+ */
+#define MSGDMA_DESC_CTL_SET_CH(x) ((x) & 0xff)
+#define MSGDMA_DESC_CTL_GEN_SOP BIT(8)
+#define MSGDMA_DESC_CTL_GEN_EOP BIT(9)
+#define MSGDMA_DESC_CTL_PARK_READS BIT(10)
+#define MSGDMA_DESC_CTL_PARK_WRITES BIT(11)
+#define MSGDMA_DESC_CTL_END_ON_EOP BIT(12)
+#define MSGDMA_DESC_CTL_END_ON_LEN BIT(13)
+#define MSGDMA_DESC_CTL_TR_COMP_IRQ BIT(14)
+#define MSGDMA_DESC_CTL_EARLY_IRQ BIT(15)
+#define MSGDMA_DESC_CTL_TR_ERR_IRQ (0xff << 16)
+#define MSGDMA_DESC_CTL_EARLY_DONE BIT(24)
+/* Writing ‘1’ to the ‘go’ bit commits the entire descriptor into the
+ * descriptor FIFO(s)
+ */
+#define MSGDMA_DESC_CTL_GO BIT(31)
+
+/* Tx buffer control flags
+ */
+#define MSGDMA_DESC_CTL_TX_FIRST (MSGDMA_DESC_CTL_GEN_SOP | \
+ MSGDMA_DESC_CTL_TR_ERR_IRQ | \
+ MSGDMA_DESC_CTL_GO)
+
+#define MSGDMA_DESC_CTL_TX_MIDDLE (MSGDMA_DESC_CTL_TR_ERR_IRQ | \
+ MSGDMA_DESC_CTL_GO)
+
+#define MSGDMA_DESC_CTL_TX_LAST (MSGDMA_DESC_CTL_GEN_EOP | \
+ MSGDMA_DESC_CTL_TR_COMP_IRQ | \
+ MSGDMA_DESC_CTL_TR_ERR_IRQ | \
+ MSGDMA_DESC_CTL_GO)
+
+#define MSGDMA_DESC_CTL_TX_SINGLE (MSGDMA_DESC_CTL_GEN_SOP | \
+ MSGDMA_DESC_CTL_GEN_EOP | \
+ MSGDMA_DESC_CTL_TR_COMP_IRQ | \
+ MSGDMA_DESC_CTL_TR_ERR_IRQ | \
+ MSGDMA_DESC_CTL_GO)
+
+#define MSGDMA_DESC_CTL_RX_SINGLE (MSGDMA_DESC_CTL_END_ON_EOP | \
+ MSGDMA_DESC_CTL_END_ON_LEN | \
+ MSGDMA_DESC_CTL_TR_COMP_IRQ | \
+ MSGDMA_DESC_CTL_EARLY_IRQ | \
+ MSGDMA_DESC_CTL_TR_ERR_IRQ | \
+ MSGDMA_DESC_CTL_GO)
+
+/* mSGDMA extended descriptor stride definitions
+ */
+#define MSGDMA_DESC_TX_STRIDE (0x00010001)
+#define MSGDMA_DESC_RX_STRIDE (0x00010001)
+
+/* mSGDMA dispatcher control and status register map
+ */
+struct msgdma_csr {
+ u32 status; /* Read/Clear */
+ u32 control; /* Read/Write */
+ u32 rw_fill_level; /* bit 31:16 - write fill level
+ * bit 15:0 - read fill level
+ */
+ u32 resp_fill_level; /* bit 15:0 */
+ u32 rw_seq_num; /* bit 31:16 - write sequence number
+ * bit 15:0 - read sequence number
+ */
+ u32 pad[3]; /* reserved */
+};
+
+/* mSGDMA CSR status register bit definitions
+ */
+#define MSGDMA_CSR_STAT_BUSY BIT(0)
+#define MSGDMA_CSR_STAT_DESC_BUF_EMPTY BIT(1)
+#define MSGDMA_CSR_STAT_DESC_BUF_FULL BIT(2)
+#define MSGDMA_CSR_STAT_RESP_BUF_EMPTY BIT(3)
+#define MSGDMA_CSR_STAT_RESP_BUF_FULL BIT(4)
+#define MSGDMA_CSR_STAT_STOPPED BIT(5)
+#define MSGDMA_CSR_STAT_RESETTING BIT(6)
+#define MSGDMA_CSR_STAT_STOPPED_ON_ERR BIT(7)
+#define MSGDMA_CSR_STAT_STOPPED_ON_EARLY BIT(8)
+#define MSGDMA_CSR_STAT_IRQ BIT(9)
+#define MSGDMA_CSR_STAT_MASK 0x3FF
+#define MSGDMA_CSR_STAT_MASK_WITHOUT_IRQ 0x1FF
+
+#define MSGDMA_CSR_STAT_BUSY_GET(v) GET_BIT_VALUE(v, 0)
+#define MSGDMA_CSR_STAT_DESC_BUF_EMPTY_GET(v) GET_BIT_VALUE(v, 1)
+#define MSGDMA_CSR_STAT_DESC_BUF_FULL_GET(v) GET_BIT_VALUE(v, 2)
+#define MSGDMA_CSR_STAT_RESP_BUF_EMPTY_GET(v) GET_BIT_VALUE(v, 3)
+#define MSGDMA_CSR_STAT_RESP_BUF_FULL_GET(v) GET_BIT_VALUE(v, 4)
+#define MSGDMA_CSR_STAT_STOPPED_GET(v) GET_BIT_VALUE(v, 5)
+#define MSGDMA_CSR_STAT_RESETTING_GET(v) GET_BIT_VALUE(v, 6)
+#define MSGDMA_CSR_STAT_STOPPED_ON_ERR_GET(v) GET_BIT_VALUE(v, 7)
+#define MSGDMA_CSR_STAT_STOPPED_ON_EARLY_GET(v) GET_BIT_VALUE(v, 8)
+#define MSGDMA_CSR_STAT_IRQ_GET(v) GET_BIT_VALUE(v, 9)
+
+/* mSGDMA CSR control register bit definitions
+ */
+#define MSGDMA_CSR_CTL_STOP BIT(0)
+#define MSGDMA_CSR_CTL_RESET BIT(1)
+#define MSGDMA_CSR_CTL_STOP_ON_ERR BIT(2)
+#define MSGDMA_CSR_CTL_STOP_ON_EARLY BIT(3)
+#define MSGDMA_CSR_CTL_GLOBAL_INTR BIT(4)
+#define MSGDMA_CSR_CTL_STOP_DESCS BIT(5)
+
+/* mSGDMA CSR fill level bits
+ */
+#define MSGDMA_CSR_WR_FILL_LEVEL_GET(v) (((v) & 0xffff0000) >> 16)
+#define MSGDMA_CSR_RD_FILL_LEVEL_GET(v) ((v) & 0x0000ffff)
+#define MSGDMA_CSR_RESP_FILL_LEVEL_GET(v) ((v) & 0x0000ffff)
+
+/* mSGDMA response register map
+ */
+struct msgdma_response {
+ u32 bytes_transferred;
+ u32 status;
+};
+
+#define msgdma_respoffs(a) (offsetof(struct msgdma_response, a))
+#define msgdma_csroffs(a) (offsetof(struct msgdma_csr, a))
+#define msgdma_descroffs(a) (offsetof(struct msgdma_extended_desc, a))
+
+/* mSGDMA response register bit definitions
+ */
+#define MSGDMA_RESP_EARLY_TERM BIT(8)
+#define MSGDMA_RESP_ERR_MASK 0xFF
+
+#endif /* __ALTERA_MSGDMA_H__*/
diff --git a/drivers/net/ethernet/altera/altera_sgdma.c b/drivers/net/ethernet/altera/altera_sgdma.c
new file mode 100644
index 00000000000..580553d42d3
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_sgdma.c
@@ -0,0 +1,540 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/list.h>
+#include "altera_utils.h"
+#include "altera_tse.h"
+#include "altera_sgdmahw.h"
+#include "altera_sgdma.h"
+
+static void sgdma_setup_descrip(struct sgdma_descrip __iomem *desc,
+ struct sgdma_descrip __iomem *ndesc,
+ dma_addr_t ndesc_phys,
+ dma_addr_t raddr,
+ dma_addr_t waddr,
+ u16 length,
+ int generate_eop,
+ int rfixed,
+ int wfixed);
+
+static int sgdma_async_write(struct altera_tse_private *priv,
+ struct sgdma_descrip __iomem *desc);
+
+static int sgdma_async_read(struct altera_tse_private *priv);
+
+static dma_addr_t
+sgdma_txphysaddr(struct altera_tse_private *priv,
+ struct sgdma_descrip __iomem *desc);
+
+static dma_addr_t
+sgdma_rxphysaddr(struct altera_tse_private *priv,
+ struct sgdma_descrip __iomem *desc);
+
+static int sgdma_txbusy(struct altera_tse_private *priv);
+
+static int sgdma_rxbusy(struct altera_tse_private *priv);
+
+static void
+queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer);
+
+static void
+queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer);
+
+static struct tse_buffer *
+dequeue_tx(struct altera_tse_private *priv);
+
+static struct tse_buffer *
+dequeue_rx(struct altera_tse_private *priv);
+
+static struct tse_buffer *
+queue_rx_peekhead(struct altera_tse_private *priv);
+
+int sgdma_initialize(struct altera_tse_private *priv)
+{
+ priv->txctrlreg = SGDMA_CTRLREG_ILASTD |
+ SGDMA_CTRLREG_INTEN;
+
+ priv->rxctrlreg = SGDMA_CTRLREG_IDESCRIP |
+ SGDMA_CTRLREG_INTEN |
+ SGDMA_CTRLREG_ILASTD;
+
+ priv->sgdmadesclen = sizeof(struct sgdma_descrip);
+
+ INIT_LIST_HEAD(&priv->txlisthd);
+ INIT_LIST_HEAD(&priv->rxlisthd);
+
+ priv->rxdescphys = (dma_addr_t) 0;
+ priv->txdescphys = (dma_addr_t) 0;
+
+ priv->rxdescphys = dma_map_single(priv->device,
+ (void __force *)priv->rx_dma_desc,
+ priv->rxdescmem, DMA_BIDIRECTIONAL);
+
+ if (dma_mapping_error(priv->device, priv->rxdescphys)) {
+ sgdma_uninitialize(priv);
+ netdev_err(priv->dev, "error mapping rx descriptor memory\n");
+ return -EINVAL;
+ }
+
+ priv->txdescphys = dma_map_single(priv->device,
+ (void __force *)priv->tx_dma_desc,
+ priv->txdescmem, DMA_TO_DEVICE);
+
+ if (dma_mapping_error(priv->device, priv->txdescphys)) {
+ sgdma_uninitialize(priv);
+ netdev_err(priv->dev, "error mapping tx descriptor memory\n");
+ return -EINVAL;
+ }
+
+ /* Initialize descriptor memory to all 0's, sync memory to cache */
+ memset_io(priv->tx_dma_desc, 0, priv->txdescmem);
+ memset_io(priv->rx_dma_desc, 0, priv->rxdescmem);
+
+ dma_sync_single_for_device(priv->device, priv->txdescphys,
+ priv->txdescmem, DMA_TO_DEVICE);
+
+ dma_sync_single_for_device(priv->device, priv->rxdescphys,
+ priv->rxdescmem, DMA_TO_DEVICE);
+
+ return 0;
+}
+
+void sgdma_uninitialize(struct altera_tse_private *priv)
+{
+ if (priv->rxdescphys)
+ dma_unmap_single(priv->device, priv->rxdescphys,
+ priv->rxdescmem, DMA_BIDIRECTIONAL);
+
+ if (priv->txdescphys)
+ dma_unmap_single(priv->device, priv->txdescphys,
+ priv->txdescmem, DMA_TO_DEVICE);
+}
+
+/* This function resets the SGDMA controller and clears the
+ * descriptor memory used for transmits and receives.
+ */
+void sgdma_reset(struct altera_tse_private *priv)
+{
+ /* Initialize descriptor memory to 0 */
+ memset_io(priv->tx_dma_desc, 0, priv->txdescmem);
+ memset_io(priv->rx_dma_desc, 0, priv->rxdescmem);
+
+ csrwr32(SGDMA_CTRLREG_RESET, priv->tx_dma_csr, sgdma_csroffs(control));
+ csrwr32(0, priv->tx_dma_csr, sgdma_csroffs(control));
+
+ csrwr32(SGDMA_CTRLREG_RESET, priv->rx_dma_csr, sgdma_csroffs(control));
+ csrwr32(0, priv->rx_dma_csr, sgdma_csroffs(control));
+}
+
+/* For SGDMA, interrupts remain enabled after initially enabling,
+ * so no need to provide implementations for abstract enable
+ * and disable
+ */
+
+void sgdma_enable_rxirq(struct altera_tse_private *priv)
+{
+}
+
+void sgdma_enable_txirq(struct altera_tse_private *priv)
+{
+}
+
+void sgdma_disable_rxirq(struct altera_tse_private *priv)
+{
+}
+
+void sgdma_disable_txirq(struct altera_tse_private *priv)
+{
+}
+
+void sgdma_clear_rxirq(struct altera_tse_private *priv)
+{
+ tse_set_bit(priv->rx_dma_csr, sgdma_csroffs(control),
+ SGDMA_CTRLREG_CLRINT);
+}
+
+void sgdma_clear_txirq(struct altera_tse_private *priv)
+{
+ tse_set_bit(priv->tx_dma_csr, sgdma_csroffs(control),
+ SGDMA_CTRLREG_CLRINT);
+}
+
+/* transmits buffer through SGDMA. Returns number of buffers
+ * transmitted, 0 if not possible.
+ *
+ * tx_lock is held by the caller
+ */
+int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
+{
+ struct sgdma_descrip __iomem *descbase =
+ (struct sgdma_descrip __iomem *)priv->tx_dma_desc;
+
+ struct sgdma_descrip __iomem *cdesc = &descbase[0];
+ struct sgdma_descrip __iomem *ndesc = &descbase[1];
+
+ /* wait 'til the tx sgdma is ready for the next transmit request */
+ if (sgdma_txbusy(priv))
+ return 0;
+
+ sgdma_setup_descrip(cdesc, /* current descriptor */
+ ndesc, /* next descriptor */
+ sgdma_txphysaddr(priv, ndesc),
+ buffer->dma_addr, /* address of packet to xmit */
+ 0, /* write addr 0 for tx dma */
+ buffer->len, /* length of packet */
+ SGDMA_CONTROL_EOP, /* Generate EOP */
+ 0, /* read fixed */
+ SGDMA_CONTROL_WR_FIXED); /* Generate SOP */
+
+ sgdma_async_write(priv, cdesc);
+
+ /* enqueue the request to the pending transmit queue */
+ queue_tx(priv, buffer);
+
+ return 1;
+}
+
+
+/* tx_lock held to protect access to queued tx list
+ */
+u32 sgdma_tx_completions(struct altera_tse_private *priv)
+{
+ u32 ready = 0;
+
+ if (!sgdma_txbusy(priv) &&
+ ((csrrd8(priv->tx_dma_desc, sgdma_descroffs(control))
+ & SGDMA_CONTROL_HW_OWNED) == 0) &&
+ (dequeue_tx(priv))) {
+ ready = 1;
+ }
+
+ return ready;
+}
+
+void sgdma_start_rxdma(struct altera_tse_private *priv)
+{
+ sgdma_async_read(priv);
+}
+
+void sgdma_add_rx_desc(struct altera_tse_private *priv,
+ struct tse_buffer *rxbuffer)
+{
+ queue_rx(priv, rxbuffer);
+}
+
+/* status is returned on upper 16 bits,
+ * length is returned in lower 16 bits
+ */
+u32 sgdma_rx_status(struct altera_tse_private *priv)
+{
+ struct sgdma_descrip __iomem *base =
+ (struct sgdma_descrip __iomem *)priv->rx_dma_desc;
+ struct sgdma_descrip __iomem *desc = NULL;
+ struct tse_buffer *rxbuffer = NULL;
+ unsigned int rxstatus = 0;
+
+ u32 sts = csrrd32(priv->rx_dma_csr, sgdma_csroffs(status));
+
+ desc = &base[0];
+ if (sts & SGDMA_STSREG_EOP) {
+ unsigned int pktlength = 0;
+ unsigned int pktstatus = 0;
+ dma_sync_single_for_cpu(priv->device,
+ priv->rxdescphys,
+ priv->sgdmadesclen,
+ DMA_FROM_DEVICE);
+
+ pktlength = csrrd16(desc, sgdma_descroffs(bytes_xferred));
+ pktstatus = csrrd8(desc, sgdma_descroffs(status));
+ rxstatus = pktstatus & ~SGDMA_STATUS_EOP;
+ rxstatus = rxstatus << 16;
+ rxstatus |= (pktlength & 0xffff);
+
+ if (rxstatus) {
+ csrwr8(0, desc, sgdma_descroffs(status));
+
+ rxbuffer = dequeue_rx(priv);
+ if (rxbuffer == NULL)
+ netdev_info(priv->dev,
+ "sgdma rx and rx queue empty!\n");
+
+ /* Clear control */
+ csrwr32(0, priv->rx_dma_csr, sgdma_csroffs(control));
+ /* clear status */
+ csrwr32(0xf, priv->rx_dma_csr, sgdma_csroffs(status));
+
+ /* kick the rx sgdma after reaping this descriptor */
+ sgdma_async_read(priv);
+
+ } else {
+ /* If the SGDMA indicated an end of packet on recv,
+ * then it's expected that the rxstatus from the
+ * descriptor is non-zero - meaning a valid packet
+ * with a nonzero length, or an error has been
+ * indicated. if not, then all we can do is signal
+ * an error and return no packet received. Most likely
+ * there is a system design error, or an error in the
+ * underlying kernel (cache or cache management problem)
+ */
+ netdev_err(priv->dev,
+ "SGDMA RX Error Info: %x, %x, %x\n",
+ sts, csrrd8(desc, sgdma_descroffs(status)),
+ rxstatus);
+ }
+ } else if (sts == 0) {
+ sgdma_async_read(priv);
+ }
+
+ return rxstatus;
+}
+
+
+/* Private functions */
+static void sgdma_setup_descrip(struct sgdma_descrip __iomem *desc,
+ struct sgdma_descrip __iomem *ndesc,
+ dma_addr_t ndesc_phys,
+ dma_addr_t raddr,
+ dma_addr_t waddr,
+ u16 length,
+ int generate_eop,
+ int rfixed,
+ int wfixed)
+{
+ /* Clear the next descriptor as not owned by hardware */
+
+ u32 ctrl = csrrd8(ndesc, sgdma_descroffs(control));
+ ctrl &= ~SGDMA_CONTROL_HW_OWNED;
+ csrwr8(ctrl, ndesc, sgdma_descroffs(control));
+
+ ctrl = SGDMA_CONTROL_HW_OWNED;
+ ctrl |= generate_eop;
+ ctrl |= rfixed;
+ ctrl |= wfixed;
+
+ /* Channel is implicitly zero, initialized to 0 by default */
+ csrwr32(lower_32_bits(raddr), desc, sgdma_descroffs(raddr));
+ csrwr32(lower_32_bits(waddr), desc, sgdma_descroffs(waddr));
+
+ csrwr32(0, desc, sgdma_descroffs(pad1));
+ csrwr32(0, desc, sgdma_descroffs(pad2));
+ csrwr32(lower_32_bits(ndesc_phys), desc, sgdma_descroffs(next));
+
+ csrwr8(ctrl, desc, sgdma_descroffs(control));
+ csrwr8(0, desc, sgdma_descroffs(status));
+ csrwr8(0, desc, sgdma_descroffs(wburst));
+ csrwr8(0, desc, sgdma_descroffs(rburst));
+ csrwr16(length, desc, sgdma_descroffs(bytes));
+ csrwr16(0, desc, sgdma_descroffs(bytes_xferred));
+}
+
+/* If hardware is busy, don't restart async read.
+ * if status register is 0 - meaning initial state, restart async read,
+ * probably for the first time when populating a receive buffer.
+ * If read status indicate not busy and a status, restart the async
+ * DMA read.
+ */
+static int sgdma_async_read(struct altera_tse_private *priv)
+{
+ struct sgdma_descrip __iomem *descbase =
+ (struct sgdma_descrip __iomem *)priv->rx_dma_desc;
+
+ struct sgdma_descrip __iomem *cdesc = &descbase[0];
+ struct sgdma_descrip __iomem *ndesc = &descbase[1];
+ struct tse_buffer *rxbuffer = NULL;
+
+ if (!sgdma_rxbusy(priv)) {
+ rxbuffer = queue_rx_peekhead(priv);
+ if (rxbuffer == NULL) {
+ netdev_err(priv->dev, "no rx buffers available\n");
+ return 0;
+ }
+
+ sgdma_setup_descrip(cdesc, /* current descriptor */
+ ndesc, /* next descriptor */
+ sgdma_rxphysaddr(priv, ndesc),
+ 0, /* read addr 0 for rx dma */
+ rxbuffer->dma_addr, /* write addr for rx dma */
+ 0, /* read 'til EOP */
+ 0, /* EOP: NA for rx dma */
+ 0, /* read fixed: NA for rx dma */
+ 0); /* SOP: NA for rx DMA */
+
+ dma_sync_single_for_device(priv->device,
+ priv->rxdescphys,
+ priv->sgdmadesclen,
+ DMA_TO_DEVICE);
+
+ csrwr32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)),
+ priv->rx_dma_csr,
+ sgdma_csroffs(next_descrip));
+
+ csrwr32((priv->rxctrlreg | SGDMA_CTRLREG_START),
+ priv->rx_dma_csr,
+ sgdma_csroffs(control));
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int sgdma_async_write(struct altera_tse_private *priv,
+ struct sgdma_descrip __iomem *desc)
+{
+ if (sgdma_txbusy(priv))
+ return 0;
+
+ /* clear control and status */
+ csrwr32(0, priv->tx_dma_csr, sgdma_csroffs(control));
+ csrwr32(0x1f, priv->tx_dma_csr, sgdma_csroffs(status));
+
+ dma_sync_single_for_device(priv->device, priv->txdescphys,
+ priv->sgdmadesclen, DMA_TO_DEVICE);
+
+ csrwr32(lower_32_bits(sgdma_txphysaddr(priv, desc)),
+ priv->tx_dma_csr,
+ sgdma_csroffs(next_descrip));
+
+ csrwr32((priv->txctrlreg | SGDMA_CTRLREG_START),
+ priv->tx_dma_csr,
+ sgdma_csroffs(control));
+
+ return 1;
+}
+
+static dma_addr_t
+sgdma_txphysaddr(struct altera_tse_private *priv,
+ struct sgdma_descrip __iomem *desc)
+{
+ dma_addr_t paddr = priv->txdescmem_busaddr;
+ uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->tx_dma_desc;
+ return (dma_addr_t)((uintptr_t)paddr + offs);
+}
+
+static dma_addr_t
+sgdma_rxphysaddr(struct altera_tse_private *priv,
+ struct sgdma_descrip __iomem *desc)
+{
+ dma_addr_t paddr = priv->rxdescmem_busaddr;
+ uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->rx_dma_desc;
+ return (dma_addr_t)((uintptr_t)paddr + offs);
+}
+
+#define list_remove_head(list, entry, type, member) \
+ do { \
+ entry = NULL; \
+ if (!list_empty(list)) { \
+ entry = list_entry((list)->next, type, member); \
+ list_del_init(&entry->member); \
+ } \
+ } while (0)
+
+#define list_peek_head(list, entry, type, member) \
+ do { \
+ entry = NULL; \
+ if (!list_empty(list)) { \
+ entry = list_entry((list)->next, type, member); \
+ } \
+ } while (0)
+
+/* adds a tse_buffer to the tail of a tx buffer list.
+ * assumes the caller is managing and holding a mutual exclusion
+ * primitive to avoid simultaneous pushes/pops to the list.
+ */
+static void
+queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer)
+{
+ list_add_tail(&buffer->lh, &priv->txlisthd);
+}
+
+
+/* adds a tse_buffer to the tail of a rx buffer list
+ * assumes the caller is managing and holding a mutual exclusion
+ * primitive to avoid simultaneous pushes/pops to the list.
+ */
+static void
+queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer)
+{
+ list_add_tail(&buffer->lh, &priv->rxlisthd);
+}
+
+/* dequeues a tse_buffer from the transmit buffer list, otherwise
+ * returns NULL if empty.
+ * assumes the caller is managing and holding a mutual exclusion
+ * primitive to avoid simultaneous pushes/pops to the list.
+ */
+static struct tse_buffer *
+dequeue_tx(struct altera_tse_private *priv)
+{
+ struct tse_buffer *buffer = NULL;
+ list_remove_head(&priv->txlisthd, buffer, struct tse_buffer, lh);
+ return buffer;
+}
+
+/* dequeues a tse_buffer from the receive buffer list, otherwise
+ * returns NULL if empty
+ * assumes the caller is managing and holding a mutual exclusion
+ * primitive to avoid simultaneous pushes/pops to the list.
+ */
+static struct tse_buffer *
+dequeue_rx(struct altera_tse_private *priv)
+{
+ struct tse_buffer *buffer = NULL;
+ list_remove_head(&priv->rxlisthd, buffer, struct tse_buffer, lh);
+ return buffer;
+}
+
+/* dequeues a tse_buffer from the receive buffer list, otherwise
+ * returns NULL if empty
+ * assumes the caller is managing and holding a mutual exclusion
+ * primitive to avoid simultaneous pushes/pops to the list while the
+ * head is being examined.
+ */
+static struct tse_buffer *
+queue_rx_peekhead(struct altera_tse_private *priv)
+{
+ struct tse_buffer *buffer = NULL;
+ list_peek_head(&priv->rxlisthd, buffer, struct tse_buffer, lh);
+ return buffer;
+}
+
+/* check and return rx sgdma status without polling
+ */
+static int sgdma_rxbusy(struct altera_tse_private *priv)
+{
+ return csrrd32(priv->rx_dma_csr, sgdma_csroffs(status))
+ & SGDMA_STSREG_BUSY;
+}
+
+/* waits for the tx sgdma to finish it's current operation, returns 0
+ * when it transitions to nonbusy, returns 1 if the operation times out
+ */
+static int sgdma_txbusy(struct altera_tse_private *priv)
+{
+ int delay = 0;
+
+ /* if DMA is busy, wait for current transactino to finish */
+ while ((csrrd32(priv->tx_dma_csr, sgdma_csroffs(status))
+ & SGDMA_STSREG_BUSY) && (delay++ < 100))
+ udelay(1);
+
+ if (csrrd32(priv->tx_dma_csr, sgdma_csroffs(status))
+ & SGDMA_STSREG_BUSY) {
+ netdev_err(priv->dev, "timeout waiting for tx dma\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/drivers/net/ethernet/altera/altera_sgdma.h b/drivers/net/ethernet/altera/altera_sgdma.h
new file mode 100644
index 00000000000..584977e29ef
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_sgdma.h
@@ -0,0 +1,36 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ALTERA_SGDMA_H__
+#define __ALTERA_SGDMA_H__
+
+void sgdma_reset(struct altera_tse_private *);
+void sgdma_enable_txirq(struct altera_tse_private *);
+void sgdma_enable_rxirq(struct altera_tse_private *);
+void sgdma_disable_rxirq(struct altera_tse_private *);
+void sgdma_disable_txirq(struct altera_tse_private *);
+void sgdma_clear_rxirq(struct altera_tse_private *);
+void sgdma_clear_txirq(struct altera_tse_private *);
+int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *);
+u32 sgdma_tx_completions(struct altera_tse_private *);
+void sgdma_add_rx_desc(struct altera_tse_private *priv, struct tse_buffer *);
+void sgdma_status(struct altera_tse_private *);
+u32 sgdma_rx_status(struct altera_tse_private *);
+int sgdma_initialize(struct altera_tse_private *);
+void sgdma_uninitialize(struct altera_tse_private *);
+void sgdma_start_rxdma(struct altera_tse_private *);
+
+#endif /* __ALTERA_SGDMA_H__ */
diff --git a/drivers/net/ethernet/altera/altera_sgdmahw.h b/drivers/net/ethernet/altera/altera_sgdmahw.h
new file mode 100644
index 00000000000..85bc33b218d
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_sgdmahw.h
@@ -0,0 +1,126 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ALTERA_SGDMAHW_H__
+#define __ALTERA_SGDMAHW_H__
+
+/* SGDMA descriptor structure */
+struct sgdma_descrip {
+ u32 raddr; /* address of data to be read */
+ u32 pad1;
+ u32 waddr;
+ u32 pad2;
+ u32 next;
+ u32 pad3;
+ u16 bytes;
+ u8 rburst;
+ u8 wburst;
+ u16 bytes_xferred; /* 16 bits, bytes xferred */
+
+ /* bit 0: error
+ * bit 1: length error
+ * bit 2: crc error
+ * bit 3: truncated error
+ * bit 4: phy error
+ * bit 5: collision error
+ * bit 6: reserved
+ * bit 7: status eop for recv case
+ */
+ u8 status;
+
+ /* bit 0: eop
+ * bit 1: read_fixed
+ * bit 2: write fixed
+ * bits 3,4,5,6: Channel (always 0)
+ * bit 7: hardware owned
+ */
+ u8 control;
+} __packed;
+
+
+#define SGDMA_STATUS_ERR BIT(0)
+#define SGDMA_STATUS_LENGTH_ERR BIT(1)
+#define SGDMA_STATUS_CRC_ERR BIT(2)
+#define SGDMA_STATUS_TRUNC_ERR BIT(3)
+#define SGDMA_STATUS_PHY_ERR BIT(4)
+#define SGDMA_STATUS_COLL_ERR BIT(5)
+#define SGDMA_STATUS_EOP BIT(7)
+
+#define SGDMA_CONTROL_EOP BIT(0)
+#define SGDMA_CONTROL_RD_FIXED BIT(1)
+#define SGDMA_CONTROL_WR_FIXED BIT(2)
+
+/* Channel is always 0, so just zero initialize it */
+
+#define SGDMA_CONTROL_HW_OWNED BIT(7)
+
+/* SGDMA register space */
+struct sgdma_csr {
+ /* bit 0: error
+ * bit 1: eop
+ * bit 2: descriptor completed
+ * bit 3: chain completed
+ * bit 4: busy
+ * remainder reserved
+ */
+ u32 status;
+ u32 pad1[3];
+
+ /* bit 0: interrupt on error
+ * bit 1: interrupt on eop
+ * bit 2: interrupt after every descriptor
+ * bit 3: interrupt after last descrip in a chain
+ * bit 4: global interrupt enable
+ * bit 5: starts descriptor processing
+ * bit 6: stop core on dma error
+ * bit 7: interrupt on max descriptors
+ * bits 8-15: max descriptors to generate interrupt
+ * bit 16: Software reset
+ * bit 17: clears owned by hardware if 0, does not clear otherwise
+ * bit 18: enables descriptor polling mode
+ * bit 19-26: clocks before polling again
+ * bit 27-30: reserved
+ * bit 31: clear interrupt
+ */
+ u32 control;
+ u32 pad2[3];
+ u32 next_descrip;
+ u32 pad3[3];
+};
+
+#define sgdma_csroffs(a) (offsetof(struct sgdma_csr, a))
+#define sgdma_descroffs(a) (offsetof(struct sgdma_descrip, a))
+
+#define SGDMA_STSREG_ERR BIT(0) /* Error */
+#define SGDMA_STSREG_EOP BIT(1) /* EOP */
+#define SGDMA_STSREG_DESCRIP BIT(2) /* Descriptor completed */
+#define SGDMA_STSREG_CHAIN BIT(3) /* Chain completed */
+#define SGDMA_STSREG_BUSY BIT(4) /* Controller busy */
+
+#define SGDMA_CTRLREG_IOE BIT(0) /* Interrupt on error */
+#define SGDMA_CTRLREG_IOEOP BIT(1) /* Interrupt on EOP */
+#define SGDMA_CTRLREG_IDESCRIP BIT(2) /* Interrupt after every descriptor */
+#define SGDMA_CTRLREG_ILASTD BIT(3) /* Interrupt after last descriptor */
+#define SGDMA_CTRLREG_INTEN BIT(4) /* Global Interrupt enable */
+#define SGDMA_CTRLREG_START BIT(5) /* starts descriptor processing */
+#define SGDMA_CTRLREG_STOPERR BIT(6) /* stop on dma error */
+#define SGDMA_CTRLREG_INTMAX BIT(7) /* Interrupt on max descriptors */
+#define SGDMA_CTRLREG_RESET BIT(16)/* Software reset */
+#define SGDMA_CTRLREG_COBHW BIT(17)/* Clears owned by hardware */
+#define SGDMA_CTRLREG_POLL BIT(18)/* enables descriptor polling mode */
+#define SGDMA_CTRLREG_CLRINT BIT(31)/* Clears interrupt */
+
+#endif /* __ALTERA_SGDMAHW_H__ */
diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h
new file mode 100644
index 00000000000..2adb24d4523
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -0,0 +1,537 @@
+/* Altera Triple-Speed Ethernet MAC driver
+ * Copyright (C) 2008-2014 Altera Corporation. All rights reserved
+ *
+ * Contributors:
+ * Dalon Westergreen
+ * Thomas Chou
+ * Ian Abbott
+ * Yuriy Kozlov
+ * Tobias Klauser
+ * Andriy Smolskyy
+ * Roman Bulgakov
+ * Dmytro Mytarchuk
+ * Matthew Gerlach
+ *
+ * Original driver contributed by SLS.
+ * Major updates contributed by GlobalLogic
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ALTERA_TSE_H__
+#define __ALTERA_TSE_H__
+
+#define ALTERA_TSE_RESOURCE_NAME "altera_tse"
+
+#include <linux/bitops.h>
+#include <linux/if_vlan.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+
+#define ALTERA_TSE_SW_RESET_WATCHDOG_CNTR 10000
+#define ALTERA_TSE_MAC_FIFO_WIDTH 4 /* TX/RX FIFO width in
+ * bytes
+ */
+/* Rx FIFO default settings */
+#define ALTERA_TSE_RX_SECTION_EMPTY 16
+#define ALTERA_TSE_RX_SECTION_FULL 0
+#define ALTERA_TSE_RX_ALMOST_EMPTY 8
+#define ALTERA_TSE_RX_ALMOST_FULL 8
+
+/* Tx FIFO default settings */
+#define ALTERA_TSE_TX_SECTION_EMPTY 16
+#define ALTERA_TSE_TX_SECTION_FULL 0
+#define ALTERA_TSE_TX_ALMOST_EMPTY 8
+#define ALTERA_TSE_TX_ALMOST_FULL 3
+
+/* MAC function configuration default settings */
+#define ALTERA_TSE_TX_IPG_LENGTH 12
+
+#define ALTERA_TSE_PAUSE_QUANTA 0xffff
+
+#define GET_BIT_VALUE(v, bit) (((v) >> (bit)) & 0x1)
+
+/* MAC Command_Config Register Bit Definitions
+ */
+#define MAC_CMDCFG_TX_ENA BIT(0)
+#define MAC_CMDCFG_RX_ENA BIT(1)
+#define MAC_CMDCFG_XON_GEN BIT(2)
+#define MAC_CMDCFG_ETH_SPEED BIT(3)
+#define MAC_CMDCFG_PROMIS_EN BIT(4)
+#define MAC_CMDCFG_PAD_EN BIT(5)
+#define MAC_CMDCFG_CRC_FWD BIT(6)
+#define MAC_CMDCFG_PAUSE_FWD BIT(7)
+#define MAC_CMDCFG_PAUSE_IGNORE BIT(8)
+#define MAC_CMDCFG_TX_ADDR_INS BIT(9)
+#define MAC_CMDCFG_HD_ENA BIT(10)
+#define MAC_CMDCFG_EXCESS_COL BIT(11)
+#define MAC_CMDCFG_LATE_COL BIT(12)
+#define MAC_CMDCFG_SW_RESET BIT(13)
+#define MAC_CMDCFG_MHASH_SEL BIT(14)
+#define MAC_CMDCFG_LOOP_ENA BIT(15)
+#define MAC_CMDCFG_TX_ADDR_SEL(v) (((v) & 0x7) << 16)
+#define MAC_CMDCFG_MAGIC_ENA BIT(19)
+#define MAC_CMDCFG_SLEEP BIT(20)
+#define MAC_CMDCFG_WAKEUP BIT(21)
+#define MAC_CMDCFG_XOFF_GEN BIT(22)
+#define MAC_CMDCFG_CNTL_FRM_ENA BIT(23)
+#define MAC_CMDCFG_NO_LGTH_CHECK BIT(24)
+#define MAC_CMDCFG_ENA_10 BIT(25)
+#define MAC_CMDCFG_RX_ERR_DISC BIT(26)
+#define MAC_CMDCFG_DISABLE_READ_TIMEOUT BIT(27)
+#define MAC_CMDCFG_CNT_RESET BIT(31)
+
+#define MAC_CMDCFG_TX_ENA_GET(v) GET_BIT_VALUE(v, 0)
+#define MAC_CMDCFG_RX_ENA_GET(v) GET_BIT_VALUE(v, 1)
+#define MAC_CMDCFG_XON_GEN_GET(v) GET_BIT_VALUE(v, 2)
+#define MAC_CMDCFG_ETH_SPEED_GET(v) GET_BIT_VALUE(v, 3)
+#define MAC_CMDCFG_PROMIS_EN_GET(v) GET_BIT_VALUE(v, 4)
+#define MAC_CMDCFG_PAD_EN_GET(v) GET_BIT_VALUE(v, 5)
+#define MAC_CMDCFG_CRC_FWD_GET(v) GET_BIT_VALUE(v, 6)
+#define MAC_CMDCFG_PAUSE_FWD_GET(v) GET_BIT_VALUE(v, 7)
+#define MAC_CMDCFG_PAUSE_IGNORE_GET(v) GET_BIT_VALUE(v, 8)
+#define MAC_CMDCFG_TX_ADDR_INS_GET(v) GET_BIT_VALUE(v, 9)
+#define MAC_CMDCFG_HD_ENA_GET(v) GET_BIT_VALUE(v, 10)
+#define MAC_CMDCFG_EXCESS_COL_GET(v) GET_BIT_VALUE(v, 11)
+#define MAC_CMDCFG_LATE_COL_GET(v) GET_BIT_VALUE(v, 12)
+#define MAC_CMDCFG_SW_RESET_GET(v) GET_BIT_VALUE(v, 13)
+#define MAC_CMDCFG_MHASH_SEL_GET(v) GET_BIT_VALUE(v, 14)
+#define MAC_CMDCFG_LOOP_ENA_GET(v) GET_BIT_VALUE(v, 15)
+#define MAC_CMDCFG_TX_ADDR_SEL_GET(v) (((v) >> 16) & 0x7)
+#define MAC_CMDCFG_MAGIC_ENA_GET(v) GET_BIT_VALUE(v, 19)
+#define MAC_CMDCFG_SLEEP_GET(v) GET_BIT_VALUE(v, 20)
+#define MAC_CMDCFG_WAKEUP_GET(v) GET_BIT_VALUE(v, 21)
+#define MAC_CMDCFG_XOFF_GEN_GET(v) GET_BIT_VALUE(v, 22)
+#define MAC_CMDCFG_CNTL_FRM_ENA_GET(v) GET_BIT_VALUE(v, 23)
+#define MAC_CMDCFG_NO_LGTH_CHECK_GET(v) GET_BIT_VALUE(v, 24)
+#define MAC_CMDCFG_ENA_10_GET(v) GET_BIT_VALUE(v, 25)
+#define MAC_CMDCFG_RX_ERR_DISC_GET(v) GET_BIT_VALUE(v, 26)
+#define MAC_CMDCFG_DISABLE_READ_TIMEOUT_GET(v) GET_BIT_VALUE(v, 27)
+#define MAC_CMDCFG_CNT_RESET_GET(v) GET_BIT_VALUE(v, 31)
+
+/* MDIO registers within MAC register Space
+ */
+struct altera_tse_mdio {
+ u32 control; /* PHY device operation control register */
+ u32 status; /* PHY device operation status register */
+ u32 phy_id1; /* Bits 31:16 of PHY identifier */
+ u32 phy_id2; /* Bits 15:0 of PHY identifier */
+ u32 auto_negotiation_advertisement; /* Auto-negotiation
+ * advertisement
+ * register
+ */
+ u32 remote_partner_base_page_ability;
+
+ u32 reg6;
+ u32 reg7;
+ u32 reg8;
+ u32 reg9;
+ u32 rega;
+ u32 regb;
+ u32 regc;
+ u32 regd;
+ u32 rege;
+ u32 regf;
+ u32 reg10;
+ u32 reg11;
+ u32 reg12;
+ u32 reg13;
+ u32 reg14;
+ u32 reg15;
+ u32 reg16;
+ u32 reg17;
+ u32 reg18;
+ u32 reg19;
+ u32 reg1a;
+ u32 reg1b;
+ u32 reg1c;
+ u32 reg1d;
+ u32 reg1e;
+ u32 reg1f;
+};
+
+/* MAC register Space. Note that some of these registers may or may not be
+ * present depending upon options chosen by the user when the core was
+ * configured and built. Please consult the Altera Triple Speed Ethernet User
+ * Guide for details.
+ */
+struct altera_tse_mac {
+ /* Bits 15:0: MegaCore function revision (0x0800). Bit 31:16: Customer
+ * specific revision
+ */
+ u32 megacore_revision;
+ /* Provides a memory location for user applications to test the device
+ * memory operation.
+ */
+ u32 scratch_pad;
+ /* The host processor uses this register to control and configure the
+ * MAC block
+ */
+ u32 command_config;
+ /* 32-bit primary MAC address word 0 bits 0 to 31 of the primary
+ * MAC address
+ */
+ u32 mac_addr_0;
+ /* 32-bit primary MAC address word 1 bits 32 to 47 of the primary
+ * MAC address
+ */
+ u32 mac_addr_1;
+ /* 14-bit maximum frame length. The MAC receive logic */
+ u32 frm_length;
+ /* The pause quanta is used in each pause frame sent to a remote
+ * Ethernet device, in increments of 512 Ethernet bit times
+ */
+ u32 pause_quanta;
+ /* 12-bit receive FIFO section-empty threshold */
+ u32 rx_section_empty;
+ /* 12-bit receive FIFO section-full threshold */
+ u32 rx_section_full;
+ /* 12-bit transmit FIFO section-empty threshold */
+ u32 tx_section_empty;
+ /* 12-bit transmit FIFO section-full threshold */
+ u32 tx_section_full;
+ /* 12-bit receive FIFO almost-empty threshold */
+ u32 rx_almost_empty;
+ /* 12-bit receive FIFO almost-full threshold */
+ u32 rx_almost_full;
+ /* 12-bit transmit FIFO almost-empty threshold */
+ u32 tx_almost_empty;
+ /* 12-bit transmit FIFO almost-full threshold */
+ u32 tx_almost_full;
+ /* MDIO address of PHY Device 0. Bits 0 to 4 hold a 5-bit PHY address */
+ u32 mdio_phy0_addr;
+ /* MDIO address of PHY Device 1. Bits 0 to 4 hold a 5-bit PHY address */
+ u32 mdio_phy1_addr;
+
+ /* Bit[15:0]—16-bit holdoff quanta */
+ u32 holdoff_quant;
+
+ /* only if 100/1000 BaseX PCS, reserved otherwise */
+ u32 reserved1[5];
+
+ /* Minimum IPG between consecutive transmit frame in terms of bytes */
+ u32 tx_ipg_length;
+
+ /* IEEE 802.3 oEntity Managed Object Support */
+
+ /* The MAC addresses */
+ u32 mac_id_1;
+ u32 mac_id_2;
+
+ /* Number of frames transmitted without error including pause frames */
+ u32 frames_transmitted_ok;
+ /* Number of frames received without error including pause frames */
+ u32 frames_received_ok;
+ /* Number of frames received with a CRC error */
+ u32 frames_check_sequence_errors;
+ /* Frame received with an alignment error */
+ u32 alignment_errors;
+ /* Sum of payload and padding octets of frames transmitted without
+ * error
+ */
+ u32 octets_transmitted_ok;
+ /* Sum of payload and padding octets of frames received without error */
+ u32 octets_received_ok;
+
+ /* IEEE 802.3 oPausedEntity Managed Object Support */
+
+ /* Number of transmitted pause frames */
+ u32 tx_pause_mac_ctrl_frames;
+ /* Number of Received pause frames */
+ u32 rx_pause_mac_ctrl_frames;
+
+ /* IETF MIB (MIB-II) Object Support */
+
+ /* Number of frames received with error */
+ u32 if_in_errors;
+ /* Number of frames transmitted with error */
+ u32 if_out_errors;
+ /* Number of valid received unicast frames */
+ u32 if_in_ucast_pkts;
+ /* Number of valid received multicasts frames (without pause) */
+ u32 if_in_multicast_pkts;
+ /* Number of valid received broadcast frames */
+ u32 if_in_broadcast_pkts;
+ u32 if_out_discards;
+ /* The number of valid unicast frames transmitted */
+ u32 if_out_ucast_pkts;
+ /* The number of valid multicast frames transmitted,
+ * excluding pause frames
+ */
+ u32 if_out_multicast_pkts;
+ u32 if_out_broadcast_pkts;
+
+ /* IETF RMON MIB Object Support */
+
+ /* Counts the number of dropped packets due to internal errors
+ * of the MAC client.
+ */
+ u32 ether_stats_drop_events;
+ /* Total number of bytes received. Good and bad frames. */
+ u32 ether_stats_octets;
+ /* Total number of packets received. Counts good and bad packets. */
+ u32 ether_stats_pkts;
+ /* Number of packets received with less than 64 bytes. */
+ u32 ether_stats_undersize_pkts;
+ /* The number of frames received that are longer than the
+ * value configured in the frm_length register
+ */
+ u32 ether_stats_oversize_pkts;
+ /* Number of received packet with 64 bytes */
+ u32 ether_stats_pkts_64_octets;
+ /* Frames (good and bad) with 65 to 127 bytes */
+ u32 ether_stats_pkts_65to127_octets;
+ /* Frames (good and bad) with 128 to 255 bytes */
+ u32 ether_stats_pkts_128to255_octets;
+ /* Frames (good and bad) with 256 to 511 bytes */
+ u32 ether_stats_pkts_256to511_octets;
+ /* Frames (good and bad) with 512 to 1023 bytes */
+ u32 ether_stats_pkts_512to1023_octets;
+ /* Frames (good and bad) with 1024 to 1518 bytes */
+ u32 ether_stats_pkts_1024to1518_octets;
+
+ /* Any frame length from 1519 to the maximum length configured in the
+ * frm_length register, if it is greater than 1518
+ */
+ u32 ether_stats_pkts_1519tox_octets;
+ /* Too long frames with CRC error */
+ u32 ether_stats_jabbers;
+ /* Too short frames with CRC error */
+ u32 ether_stats_fragments;
+
+ u32 reserved2;
+
+ /* FIFO control register */
+ u32 tx_cmd_stat;
+ u32 rx_cmd_stat;
+
+ /* Extended Statistics Counters */
+ u32 msb_octets_transmitted_ok;
+ u32 msb_octets_received_ok;
+ u32 msb_ether_stats_octets;
+
+ u32 reserved3;
+
+ /* Multicast address resolution table, mapped in the controller address
+ * space
+ */
+ u32 hash_table[64];
+
+ /* Registers 0 to 31 within PHY device 0/1 connected to the MDIO PHY
+ * management interface
+ */
+ struct altera_tse_mdio mdio_phy0;
+ struct altera_tse_mdio mdio_phy1;
+
+ /* 4 Supplemental MAC Addresses */
+ u32 supp_mac_addr_0_0;
+ u32 supp_mac_addr_0_1;
+ u32 supp_mac_addr_1_0;
+ u32 supp_mac_addr_1_1;
+ u32 supp_mac_addr_2_0;
+ u32 supp_mac_addr_2_1;
+ u32 supp_mac_addr_3_0;
+ u32 supp_mac_addr_3_1;
+
+ u32 reserved4[8];
+
+ /* IEEE 1588v2 Feature */
+ u32 tx_period;
+ u32 tx_adjust_fns;
+ u32 tx_adjust_ns;
+ u32 rx_period;
+ u32 rx_adjust_fns;
+ u32 rx_adjust_ns;
+
+ u32 reserved5[42];
+};
+
+#define tse_csroffs(a) (offsetof(struct altera_tse_mac, a))
+
+/* Transmit and Receive Command Registers Bit Definitions
+ */
+#define ALTERA_TSE_TX_CMD_STAT_OMIT_CRC BIT(17)
+#define ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 BIT(18)
+#define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16 BIT(25)
+
+/* Wrapper around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer
+ */
+struct tse_buffer {
+ struct list_head lh;
+ struct sk_buff *skb;
+ dma_addr_t dma_addr;
+ u32 len;
+ int mapped_as_page;
+};
+
+struct altera_tse_private;
+
+#define ALTERA_DTYPE_SGDMA 1
+#define ALTERA_DTYPE_MSGDMA 2
+
+/* standard DMA interface for SGDMA and MSGDMA */
+struct altera_dmaops {
+ int altera_dtype;
+ int dmamask;
+ void (*reset_dma)(struct altera_tse_private *);
+ void (*enable_txirq)(struct altera_tse_private *);
+ void (*enable_rxirq)(struct altera_tse_private *);
+ void (*disable_txirq)(struct altera_tse_private *);
+ void (*disable_rxirq)(struct altera_tse_private *);
+ void (*clear_txirq)(struct altera_tse_private *);
+ void (*clear_rxirq)(struct altera_tse_private *);
+ int (*tx_buffer)(struct altera_tse_private *, struct tse_buffer *);
+ u32 (*tx_completions)(struct altera_tse_private *);
+ void (*add_rx_desc)(struct altera_tse_private *, struct tse_buffer *);
+ u32 (*get_rx_status)(struct altera_tse_private *);
+ int (*init_dma)(struct altera_tse_private *);
+ void (*uninit_dma)(struct altera_tse_private *);
+ void (*start_rxdma)(struct altera_tse_private *);
+};
+
+/* This structure is private to each device.
+ */
+struct altera_tse_private {
+ struct net_device *dev;
+ struct device *device;
+ struct napi_struct napi;
+
+ /* MAC address space */
+ struct altera_tse_mac __iomem *mac_dev;
+
+ /* TSE Revision */
+ u32 revision;
+
+ /* mSGDMA Rx Dispatcher address space */
+ void __iomem *rx_dma_csr;
+ void __iomem *rx_dma_desc;
+ void __iomem *rx_dma_resp;
+
+ /* mSGDMA Tx Dispatcher address space */
+ void __iomem *tx_dma_csr;
+ void __iomem *tx_dma_desc;
+
+ /* Rx buffers queue */
+ struct tse_buffer *rx_ring;
+ u32 rx_cons;
+ u32 rx_prod;
+ u32 rx_ring_size;
+ u32 rx_dma_buf_sz;
+
+ /* Tx ring buffer */
+ struct tse_buffer *tx_ring;
+ u32 tx_prod;
+ u32 tx_cons;
+ u32 tx_ring_size;
+
+ /* Interrupts */
+ u32 tx_irq;
+ u32 rx_irq;
+
+ /* RX/TX MAC FIFO configs */
+ u32 tx_fifo_depth;
+ u32 rx_fifo_depth;
+ u32 max_mtu;
+
+ /* Hash filter settings */
+ u32 hash_filter;
+ u32 added_unicast;
+
+ /* Descriptor memory info for managing SGDMA */
+ u32 txdescmem;
+ u32 rxdescmem;
+ dma_addr_t rxdescmem_busaddr;
+ dma_addr_t txdescmem_busaddr;
+ u32 txctrlreg;
+ u32 rxctrlreg;
+ dma_addr_t rxdescphys;
+ dma_addr_t txdescphys;
+ size_t sgdmadesclen;
+
+ struct list_head txlisthd;
+ struct list_head rxlisthd;
+
+ /* MAC command_config register protection */
+ spinlock_t mac_cfg_lock;
+ /* Tx path protection */
+ spinlock_t tx_lock;
+ /* Rx DMA & interrupt control protection */
+ spinlock_t rxdma_irq_lock;
+
+ /* PHY */
+ int phy_addr; /* PHY's MDIO address, -1 for autodetection */
+ phy_interface_t phy_iface;
+ struct mii_bus *mdio;
+ struct phy_device *phydev;
+ int oldspeed;
+ int oldduplex;
+ int oldlink;
+
+ /* ethtool msglvl option */
+ u32 msg_enable;
+
+ struct altera_dmaops *dmaops;
+};
+
+/* Function prototypes
+ */
+void altera_tse_set_ethtool_ops(struct net_device *);
+
+static inline
+u32 csrrd32(void __iomem *mac, size_t offs)
+{
+ void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+ return readl(paddr);
+}
+
+static inline
+u16 csrrd16(void __iomem *mac, size_t offs)
+{
+ void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+ return readw(paddr);
+}
+
+static inline
+u8 csrrd8(void __iomem *mac, size_t offs)
+{
+ void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+ return readb(paddr);
+}
+
+static inline
+void csrwr32(u32 val, void __iomem *mac, size_t offs)
+{
+ void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+ writel(val, paddr);
+}
+
+static inline
+void csrwr16(u16 val, void __iomem *mac, size_t offs)
+{
+ void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+ writew(val, paddr);
+}
+
+static inline
+void csrwr8(u8 val, void __iomem *mac, size_t offs)
+{
+ void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+ writeb(val, paddr);
+}
+
+#endif /* __ALTERA_TSE_H__ */
diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c b/drivers/net/ethernet/altera/altera_tse_ethtool.c
new file mode 100644
index 00000000000..be72e1e6452
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c
@@ -0,0 +1,275 @@
+/* Ethtool support for Altera Triple-Speed Ethernet MAC driver
+ * Copyright (C) 2008-2014 Altera Corporation. All rights reserved
+ *
+ * Contributors:
+ * Dalon Westergreen
+ * Thomas Chou
+ * Ian Abbott
+ * Yuriy Kozlov
+ * Tobias Klauser
+ * Andriy Smolskyy
+ * Roman Bulgakov
+ * Dmytro Mytarchuk
+ *
+ * Original driver contributed by SLS.
+ * Major updates contributed by GlobalLogic
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/ethtool.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+
+#include "altera_tse.h"
+
+#define TSE_STATS_LEN 31
+#define TSE_NUM_REGS 128
+
+static char const stat_gstrings[][ETH_GSTRING_LEN] = {
+ "tx_packets",
+ "rx_packets",
+ "rx_crc_errors",
+ "rx_align_errors",
+ "tx_bytes",
+ "rx_bytes",
+ "tx_pause",
+ "rx_pause",
+ "rx_errors",
+ "tx_errors",
+ "rx_unicast",
+ "rx_multicast",
+ "rx_broadcast",
+ "tx_discards",
+ "tx_unicast",
+ "tx_multicast",
+ "tx_broadcast",
+ "ether_drops",
+ "rx_total_bytes",
+ "rx_total_packets",
+ "rx_undersize",
+ "rx_oversize",
+ "rx_64_bytes",
+ "rx_65_127_bytes",
+ "rx_128_255_bytes",
+ "rx_256_511_bytes",
+ "rx_512_1023_bytes",
+ "rx_1024_1518_bytes",
+ "rx_gte_1519_bytes",
+ "rx_jabbers",
+ "rx_runts",
+};
+
+static void tse_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ u32 rev = ioread32(&priv->mac_dev->megacore_revision);
+
+ strcpy(info->driver, "altera_tse");
+ strcpy(info->version, "v8.0");
+ snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d",
+ rev & 0xFFFF, (rev & 0xFFFF0000) >> 16);
+ sprintf(info->bus_info, "platform");
+}
+
+/* Fill in a buffer with the strings which correspond to the
+ * stats
+ */
+static void tse_gstrings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+ memcpy(buf, stat_gstrings, TSE_STATS_LEN * ETH_GSTRING_LEN);
+}
+
+static void tse_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
+ u64 *buf)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ u64 ext;
+
+ buf[0] = csrrd32(priv->mac_dev,
+ tse_csroffs(frames_transmitted_ok));
+ buf[1] = csrrd32(priv->mac_dev,
+ tse_csroffs(frames_received_ok));
+ buf[2] = csrrd32(priv->mac_dev,
+ tse_csroffs(frames_check_sequence_errors));
+ buf[3] = csrrd32(priv->mac_dev,
+ tse_csroffs(alignment_errors));
+
+ /* Extended aOctetsTransmittedOK counter */
+ ext = (u64) csrrd32(priv->mac_dev,
+ tse_csroffs(msb_octets_transmitted_ok)) << 32;
+
+ ext |= csrrd32(priv->mac_dev,
+ tse_csroffs(octets_transmitted_ok));
+ buf[4] = ext;
+
+ /* Extended aOctetsReceivedOK counter */
+ ext = (u64) csrrd32(priv->mac_dev,
+ tse_csroffs(msb_octets_received_ok)) << 32;
+
+ ext |= csrrd32(priv->mac_dev,
+ tse_csroffs(octets_received_ok));
+ buf[5] = ext;
+
+ buf[6] = csrrd32(priv->mac_dev,
+ tse_csroffs(tx_pause_mac_ctrl_frames));
+ buf[7] = csrrd32(priv->mac_dev,
+ tse_csroffs(rx_pause_mac_ctrl_frames));
+ buf[8] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_in_errors));
+ buf[9] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_out_errors));
+ buf[10] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_in_ucast_pkts));
+ buf[11] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_in_multicast_pkts));
+ buf[12] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_in_broadcast_pkts));
+ buf[13] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_out_discards));
+ buf[14] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_out_ucast_pkts));
+ buf[15] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_out_multicast_pkts));
+ buf[16] = csrrd32(priv->mac_dev,
+ tse_csroffs(if_out_broadcast_pkts));
+ buf[17] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_drop_events));
+
+ /* Extended etherStatsOctets counter */
+ ext = (u64) csrrd32(priv->mac_dev,
+ tse_csroffs(msb_ether_stats_octets)) << 32;
+ ext |= csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_octets));
+ buf[18] = ext;
+
+ buf[19] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts));
+ buf[20] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_undersize_pkts));
+ buf[21] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_oversize_pkts));
+ buf[22] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts_64_octets));
+ buf[23] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts_65to127_octets));
+ buf[24] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts_128to255_octets));
+ buf[25] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts_256to511_octets));
+ buf[26] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts_512to1023_octets));
+ buf[27] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts_1024to1518_octets));
+ buf[28] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_pkts_1519tox_octets));
+ buf[29] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_jabbers));
+ buf[30] = csrrd32(priv->mac_dev,
+ tse_csroffs(ether_stats_fragments));
+}
+
+static int tse_sset_count(struct net_device *dev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return TSE_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static u32 tse_get_msglevel(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ return priv->msg_enable;
+}
+
+static void tse_set_msglevel(struct net_device *dev, uint32_t data)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ priv->msg_enable = data;
+}
+
+static int tse_reglen(struct net_device *dev)
+{
+ return TSE_NUM_REGS * sizeof(u32);
+}
+
+static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *regbuf)
+{
+ int i;
+ struct altera_tse_private *priv = netdev_priv(dev);
+ u32 *buf = regbuf;
+
+ /* Set version to a known value, so ethtool knows
+ * how to do any special formatting of this data.
+ * This version number will need to change if and
+ * when this register table is changed.
+ *
+ * version[31:0] = 1: Dump the first 128 TSE Registers
+ * Upper bits are all 0 by default
+ *
+ * Upper 16-bits will indicate feature presence for
+ * Ethtool register decoding in future version.
+ */
+
+ regs->version = 1;
+
+ for (i = 0; i < TSE_NUM_REGS; i++)
+ buf[i] = csrrd32(priv->mac_dev, i * 4);
+}
+
+static int tse_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+
+ if (phydev == NULL)
+ return -ENODEV;
+
+ return phy_ethtool_gset(phydev, cmd);
+}
+
+static int tse_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+
+ if (phydev == NULL)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phydev, cmd);
+}
+
+static const struct ethtool_ops tse_ethtool_ops = {
+ .get_drvinfo = tse_get_drvinfo,
+ .get_regs_len = tse_reglen,
+ .get_regs = tse_get_regs,
+ .get_link = ethtool_op_get_link,
+ .get_settings = tse_get_settings,
+ .set_settings = tse_set_settings,
+ .get_strings = tse_gstrings,
+ .get_sset_count = tse_sset_count,
+ .get_ethtool_stats = tse_fill_stats,
+ .get_msglevel = tse_get_msglevel,
+ .set_msglevel = tse_set_msglevel,
+};
+
+void altera_tse_set_ethtool_ops(struct net_device *netdev)
+{
+ netdev->ethtool_ops = &tse_ethtool_ops;
+}
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
new file mode 100644
index 00000000000..7330681574d
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -0,0 +1,1577 @@
+/* Altera Triple-Speed Ethernet MAC driver
+ * Copyright (C) 2008-2014 Altera Corporation. All rights reserved
+ *
+ * Contributors:
+ * Dalon Westergreen
+ * Thomas Chou
+ * Ian Abbott
+ * Yuriy Kozlov
+ * Tobias Klauser
+ * Andriy Smolskyy
+ * Roman Bulgakov
+ * Dmytro Mytarchuk
+ * Matthew Gerlach
+ *
+ * Original driver contributed by SLS.
+ * Major updates contributed by GlobalLogic
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/atomic.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <asm/cacheflush.h>
+
+#include "altera_utils.h"
+#include "altera_tse.h"
+#include "altera_sgdma.h"
+#include "altera_msgdma.h"
+
+static atomic_t instance_count = ATOMIC_INIT(~0);
+/* Module parameters */
+static int debug = -1;
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)");
+
+static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
+ NETIF_MSG_LINK | NETIF_MSG_IFUP |
+ NETIF_MSG_IFDOWN);
+
+#define RX_DESCRIPTORS 64
+static int dma_rx_num = RX_DESCRIPTORS;
+module_param(dma_rx_num, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_rx_num, "Number of descriptors in the RX list");
+
+#define TX_DESCRIPTORS 64
+static int dma_tx_num = TX_DESCRIPTORS;
+module_param(dma_tx_num, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_tx_num, "Number of descriptors in the TX list");
+
+
+#define POLL_PHY (-1)
+
+/* Make sure DMA buffer size is larger than the max frame size
+ * plus some alignment offset and a VLAN header. If the max frame size is
+ * 1518, a VLAN header would be additional 4 bytes and additional
+ * headroom for alignment is 2 bytes, 2048 is just fine.
+ */
+#define ALTERA_RXDMABUFFER_SIZE 2048
+
+/* Allow network stack to resume queueing packets after we've
+ * finished transmitting at least 1/4 of the packets in the queue.
+ */
+#define TSE_TX_THRESH(x) (x->tx_ring_size / 4)
+
+#define TXQUEUESTOP_THRESHHOLD 2
+
+static struct of_device_id altera_tse_ids[];
+
+static inline u32 tse_tx_avail(struct altera_tse_private *priv)
+{
+ return priv->tx_cons + priv->tx_ring_size - priv->tx_prod - 1;
+}
+
+/* MDIO specific functions
+ */
+static int altera_tse_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+ struct net_device *ndev = bus->priv;
+ struct altera_tse_private *priv = netdev_priv(ndev);
+
+ /* set MDIO address */
+ csrwr32((mii_id & 0x1f), priv->mac_dev,
+ tse_csroffs(mdio_phy0_addr));
+
+ /* get the data */
+ return csrrd32(priv->mac_dev,
+ tse_csroffs(mdio_phy0) + regnum * 4) & 0xffff;
+}
+
+static int altera_tse_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+ u16 value)
+{
+ struct net_device *ndev = bus->priv;
+ struct altera_tse_private *priv = netdev_priv(ndev);
+
+ /* set MDIO address */
+ csrwr32((mii_id & 0x1f), priv->mac_dev,
+ tse_csroffs(mdio_phy0_addr));
+
+ /* write the data */
+ csrwr32(value, priv->mac_dev, tse_csroffs(mdio_phy0) + regnum * 4);
+ return 0;
+}
+
+static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ int ret;
+ int i;
+ struct device_node *mdio_node = NULL;
+ struct mii_bus *mdio = NULL;
+ struct device_node *child_node = NULL;
+
+ for_each_child_of_node(priv->device->of_node, child_node) {
+ if (of_device_is_compatible(child_node, "altr,tse-mdio")) {
+ mdio_node = child_node;
+ break;
+ }
+ }
+
+ if (mdio_node) {
+ netdev_dbg(dev, "FOUND MDIO subnode\n");
+ } else {
+ netdev_dbg(dev, "NO MDIO subnode\n");
+ return 0;
+ }
+
+ mdio = mdiobus_alloc();
+ if (mdio == NULL) {
+ netdev_err(dev, "Error allocating MDIO bus\n");
+ return -ENOMEM;
+ }
+
+ mdio->name = ALTERA_TSE_RESOURCE_NAME;
+ mdio->read = &altera_tse_mdio_read;
+ mdio->write = &altera_tse_mdio_write;
+ snprintf(mdio->id, MII_BUS_ID_SIZE, "%s-%u", mdio->name, id);
+
+ mdio->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
+ if (mdio->irq == NULL) {
+ ret = -ENOMEM;
+ goto out_free_mdio;
+ }
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ mdio->irq[i] = PHY_POLL;
+
+ mdio->priv = dev;
+ mdio->parent = priv->device;
+
+ ret = of_mdiobus_register(mdio, mdio_node);
+ if (ret != 0) {
+ netdev_err(dev, "Cannot register MDIO bus %s\n",
+ mdio->id);
+ goto out_free_mdio_irq;
+ }
+
+ if (netif_msg_drv(priv))
+ netdev_info(dev, "MDIO bus %s: created\n", mdio->id);
+
+ priv->mdio = mdio;
+ return 0;
+out_free_mdio_irq:
+ kfree(mdio->irq);
+out_free_mdio:
+ mdiobus_free(mdio);
+ mdio = NULL;
+ return ret;
+}
+
+static void altera_tse_mdio_destroy(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+
+ if (priv->mdio == NULL)
+ return;
+
+ if (netif_msg_drv(priv))
+ netdev_info(dev, "MDIO bus %s: removed\n",
+ priv->mdio->id);
+
+ mdiobus_unregister(priv->mdio);
+ kfree(priv->mdio->irq);
+ mdiobus_free(priv->mdio);
+ priv->mdio = NULL;
+}
+
+static int tse_init_rx_buffer(struct altera_tse_private *priv,
+ struct tse_buffer *rxbuffer, int len)
+{
+ rxbuffer->skb = netdev_alloc_skb_ip_align(priv->dev, len);
+ if (!rxbuffer->skb)
+ return -ENOMEM;
+
+ rxbuffer->dma_addr = dma_map_single(priv->device, rxbuffer->skb->data,
+ len,
+ DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(priv->device, rxbuffer->dma_addr)) {
+ netdev_err(priv->dev, "%s: DMA mapping error\n", __func__);
+ dev_kfree_skb_any(rxbuffer->skb);
+ return -EINVAL;
+ }
+ rxbuffer->dma_addr &= (dma_addr_t)~3;
+ rxbuffer->len = len;
+ return 0;
+}
+
+static void tse_free_rx_buffer(struct altera_tse_private *priv,
+ struct tse_buffer *rxbuffer)
+{
+ struct sk_buff *skb = rxbuffer->skb;
+ dma_addr_t dma_addr = rxbuffer->dma_addr;
+
+ if (skb != NULL) {
+ if (dma_addr)
+ dma_unmap_single(priv->device, dma_addr,
+ rxbuffer->len,
+ DMA_FROM_DEVICE);
+ dev_kfree_skb_any(skb);
+ rxbuffer->skb = NULL;
+ rxbuffer->dma_addr = 0;
+ }
+}
+
+/* Unmap and free Tx buffer resources
+ */
+static void tse_free_tx_buffer(struct altera_tse_private *priv,
+ struct tse_buffer *buffer)
+{
+ if (buffer->dma_addr) {
+ if (buffer->mapped_as_page)
+ dma_unmap_page(priv->device, buffer->dma_addr,
+ buffer->len, DMA_TO_DEVICE);
+ else
+ dma_unmap_single(priv->device, buffer->dma_addr,
+ buffer->len, DMA_TO_DEVICE);
+ buffer->dma_addr = 0;
+ }
+ if (buffer->skb) {
+ dev_kfree_skb_any(buffer->skb);
+ buffer->skb = NULL;
+ }
+}
+
+static int alloc_init_skbufs(struct altera_tse_private *priv)
+{
+ unsigned int rx_descs = priv->rx_ring_size;
+ unsigned int tx_descs = priv->tx_ring_size;
+ int ret = -ENOMEM;
+ int i;
+
+ /* Create Rx ring buffer */
+ priv->rx_ring = kcalloc(rx_descs, sizeof(struct tse_buffer),
+ GFP_KERNEL);
+ if (!priv->rx_ring)
+ goto err_rx_ring;
+
+ /* Create Tx ring buffer */
+ priv->tx_ring = kcalloc(tx_descs, sizeof(struct tse_buffer),
+ GFP_KERNEL);
+ if (!priv->tx_ring)
+ goto err_tx_ring;
+
+ priv->tx_cons = 0;
+ priv->tx_prod = 0;
+
+ /* Init Rx ring */
+ for (i = 0; i < rx_descs; i++) {
+ ret = tse_init_rx_buffer(priv, &priv->rx_ring[i],
+ priv->rx_dma_buf_sz);
+ if (ret)
+ goto err_init_rx_buffers;
+ }
+
+ priv->rx_cons = 0;
+ priv->rx_prod = 0;
+
+ return 0;
+err_init_rx_buffers:
+ while (--i >= 0)
+ tse_free_rx_buffer(priv, &priv->rx_ring[i]);
+ kfree(priv->tx_ring);
+err_tx_ring:
+ kfree(priv->rx_ring);
+err_rx_ring:
+ return ret;
+}
+
+static void free_skbufs(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ unsigned int rx_descs = priv->rx_ring_size;
+ unsigned int tx_descs = priv->tx_ring_size;
+ int i;
+
+ /* Release the DMA TX/RX socket buffers */
+ for (i = 0; i < rx_descs; i++)
+ tse_free_rx_buffer(priv, &priv->rx_ring[i]);
+ for (i = 0; i < tx_descs; i++)
+ tse_free_tx_buffer(priv, &priv->tx_ring[i]);
+
+
+ kfree(priv->tx_ring);
+}
+
+/* Reallocate the skb for the reception process
+ */
+static inline void tse_rx_refill(struct altera_tse_private *priv)
+{
+ unsigned int rxsize = priv->rx_ring_size;
+ unsigned int entry;
+ int ret;
+
+ for (; priv->rx_cons - priv->rx_prod > 0;
+ priv->rx_prod++) {
+ entry = priv->rx_prod % rxsize;
+ if (likely(priv->rx_ring[entry].skb == NULL)) {
+ ret = tse_init_rx_buffer(priv, &priv->rx_ring[entry],
+ priv->rx_dma_buf_sz);
+ if (unlikely(ret != 0))
+ break;
+ priv->dmaops->add_rx_desc(priv, &priv->rx_ring[entry]);
+ }
+ }
+}
+
+/* Pull out the VLAN tag and fix up the packet
+ */
+static inline void tse_rx_vlan(struct net_device *dev, struct sk_buff *skb)
+{
+ struct ethhdr *eth_hdr;
+ u16 vid;
+ if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+ !__vlan_get_tag(skb, &vid)) {
+ eth_hdr = (struct ethhdr *)skb->data;
+ memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2);
+ skb_pull(skb, VLAN_HLEN);
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
+ }
+}
+
+/* Receive a packet: retrieve and pass over to upper levels
+ */
+static int tse_rx(struct altera_tse_private *priv, int limit)
+{
+ unsigned int count = 0;
+ unsigned int next_entry;
+ struct sk_buff *skb;
+ unsigned int entry = priv->rx_cons % priv->rx_ring_size;
+ u32 rxstatus;
+ u16 pktlength;
+ u16 pktstatus;
+
+ while ((rxstatus = priv->dmaops->get_rx_status(priv)) != 0) {
+ pktstatus = rxstatus >> 16;
+ pktlength = rxstatus & 0xffff;
+
+ if ((pktstatus & 0xFF) || (pktlength == 0))
+ netdev_err(priv->dev,
+ "RCV pktstatus %08X pktlength %08X\n",
+ pktstatus, pktlength);
+
+ count++;
+ next_entry = (++priv->rx_cons) % priv->rx_ring_size;
+
+ skb = priv->rx_ring[entry].skb;
+ if (unlikely(!skb)) {
+ netdev_err(priv->dev,
+ "%s: Inconsistent Rx descriptor chain\n",
+ __func__);
+ priv->dev->stats.rx_dropped++;
+ break;
+ }
+ priv->rx_ring[entry].skb = NULL;
+
+ skb_put(skb, pktlength);
+
+ /* make cache consistent with receive packet buffer */
+ dma_sync_single_for_cpu(priv->device,
+ priv->rx_ring[entry].dma_addr,
+ priv->rx_ring[entry].len,
+ DMA_FROM_DEVICE);
+
+ dma_unmap_single(priv->device, priv->rx_ring[entry].dma_addr,
+ priv->rx_ring[entry].len, DMA_FROM_DEVICE);
+
+ if (netif_msg_pktdata(priv)) {
+ netdev_info(priv->dev, "frame received %d bytes\n",
+ pktlength);
+ print_hex_dump(KERN_ERR, "data: ", DUMP_PREFIX_OFFSET,
+ 16, 1, skb->data, pktlength, true);
+ }
+
+ tse_rx_vlan(priv->dev, skb);
+
+ skb->protocol = eth_type_trans(skb, priv->dev);
+ skb_checksum_none_assert(skb);
+
+ napi_gro_receive(&priv->napi, skb);
+
+ priv->dev->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += pktlength;
+
+ entry = next_entry;
+
+ tse_rx_refill(priv);
+ }
+
+ return count;
+}
+
+/* Reclaim resources after transmission completes
+ */
+static int tse_tx_complete(struct altera_tse_private *priv)
+{
+ unsigned int txsize = priv->tx_ring_size;
+ u32 ready;
+ unsigned int entry;
+ struct tse_buffer *tx_buff;
+ int txcomplete = 0;
+
+ spin_lock(&priv->tx_lock);
+
+ ready = priv->dmaops->tx_completions(priv);
+
+ /* Free sent buffers */
+ while (ready && (priv->tx_cons != priv->tx_prod)) {
+ entry = priv->tx_cons % txsize;
+ tx_buff = &priv->tx_ring[entry];
+
+ if (netif_msg_tx_done(priv))
+ netdev_dbg(priv->dev, "%s: curr %d, dirty %d\n",
+ __func__, priv->tx_prod, priv->tx_cons);
+
+ if (likely(tx_buff->skb))
+ priv->dev->stats.tx_packets++;
+
+ tse_free_tx_buffer(priv, tx_buff);
+ priv->tx_cons++;
+
+ txcomplete++;
+ ready--;
+ }
+
+ if (unlikely(netif_queue_stopped(priv->dev) &&
+ tse_tx_avail(priv) > TSE_TX_THRESH(priv))) {
+ netif_tx_lock(priv->dev);
+ if (netif_queue_stopped(priv->dev) &&
+ tse_tx_avail(priv) > TSE_TX_THRESH(priv)) {
+ if (netif_msg_tx_done(priv))
+ netdev_dbg(priv->dev, "%s: restart transmit\n",
+ __func__);
+ netif_wake_queue(priv->dev);
+ }
+ netif_tx_unlock(priv->dev);
+ }
+
+ spin_unlock(&priv->tx_lock);
+ return txcomplete;
+}
+
+/* NAPI polling function
+ */
+static int tse_poll(struct napi_struct *napi, int budget)
+{
+ struct altera_tse_private *priv =
+ container_of(napi, struct altera_tse_private, napi);
+ int rxcomplete = 0;
+ int txcomplete = 0;
+ unsigned long int flags;
+
+ txcomplete = tse_tx_complete(priv);
+
+ rxcomplete = tse_rx(priv, budget);
+
+ if (rxcomplete >= budget || txcomplete > 0)
+ return rxcomplete;
+
+ napi_gro_flush(napi, false);
+ __napi_complete(napi);
+
+ netdev_dbg(priv->dev,
+ "NAPI Complete, did %d packets with budget %d\n",
+ txcomplete+rxcomplete, budget);
+
+ spin_lock_irqsave(&priv->rxdma_irq_lock, flags);
+ priv->dmaops->enable_rxirq(priv);
+ priv->dmaops->enable_txirq(priv);
+ spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
+ return rxcomplete + txcomplete;
+}
+
+/* DMA TX & RX FIFO interrupt routing
+ */
+static irqreturn_t altera_isr(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct altera_tse_private *priv;
+ unsigned long int flags;
+
+ if (unlikely(!dev)) {
+ pr_err("%s: invalid dev pointer\n", __func__);
+ return IRQ_NONE;
+ }
+ priv = netdev_priv(dev);
+
+ /* turn off desc irqs and enable napi rx */
+ spin_lock_irqsave(&priv->rxdma_irq_lock, flags);
+
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ priv->dmaops->disable_rxirq(priv);
+ priv->dmaops->disable_txirq(priv);
+ __napi_schedule(&priv->napi);
+ }
+
+ /* reset IRQs */
+ priv->dmaops->clear_rxirq(priv);
+ priv->dmaops->clear_txirq(priv);
+
+ spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/* Transmit a packet (called by the kernel). Dispatches
+ * either the SGDMA method for transmitting or the
+ * MSGDMA method, assumes no scatter/gather support,
+ * implying an assumption that there's only one
+ * physically contiguous fragment starting at
+ * skb->data, for length of skb_headlen(skb).
+ */
+static int tse_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ unsigned int txsize = priv->tx_ring_size;
+ unsigned int entry;
+ struct tse_buffer *buffer = NULL;
+ int nfrags = skb_shinfo(skb)->nr_frags;
+ unsigned int nopaged_len = skb_headlen(skb);
+ enum netdev_tx ret = NETDEV_TX_OK;
+ dma_addr_t dma_addr;
+
+ spin_lock_bh(&priv->tx_lock);
+
+ if (unlikely(tse_tx_avail(priv) < nfrags + 1)) {
+ if (!netif_queue_stopped(dev)) {
+ netif_stop_queue(dev);
+ /* This is a hard error, log it. */
+ netdev_err(priv->dev,
+ "%s: Tx list full when queue awake\n",
+ __func__);
+ }
+ ret = NETDEV_TX_BUSY;
+ goto out;
+ }
+
+ /* Map the first skb fragment */
+ entry = priv->tx_prod % txsize;
+ buffer = &priv->tx_ring[entry];
+
+ dma_addr = dma_map_single(priv->device, skb->data, nopaged_len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(priv->device, dma_addr)) {
+ netdev_err(priv->dev, "%s: DMA mapping error\n", __func__);
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+
+ buffer->skb = skb;
+ buffer->dma_addr = dma_addr;
+ buffer->len = nopaged_len;
+
+ /* Push data out of the cache hierarchy into main memory */
+ dma_sync_single_for_device(priv->device, buffer->dma_addr,
+ buffer->len, DMA_TO_DEVICE);
+
+ priv->dmaops->tx_buffer(priv, buffer);
+
+ skb_tx_timestamp(skb);
+
+ priv->tx_prod++;
+ dev->stats.tx_bytes += skb->len;
+
+ if (unlikely(tse_tx_avail(priv) <= TXQUEUESTOP_THRESHHOLD)) {
+ if (netif_msg_hw(priv))
+ netdev_dbg(priv->dev, "%s: stop transmitted packets\n",
+ __func__);
+ netif_stop_queue(dev);
+ }
+
+out:
+ spin_unlock_bh(&priv->tx_lock);
+
+ return ret;
+}
+
+/* Called every time the controller might need to be made
+ * aware of new link state. The PHY code conveys this
+ * information through variables in the phydev structure, and this
+ * function converts those variables into the appropriate
+ * register values, and can bring down the device if needed.
+ */
+static void altera_tse_adjust_link(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+ int new_state = 0;
+
+ /* only change config if there is a link */
+ spin_lock(&priv->mac_cfg_lock);
+ if (phydev->link) {
+ /* Read old config */
+ u32 cfg_reg = ioread32(&priv->mac_dev->command_config);
+
+ /* Check duplex */
+ if (phydev->duplex != priv->oldduplex) {
+ new_state = 1;
+ if (!(phydev->duplex))
+ cfg_reg |= MAC_CMDCFG_HD_ENA;
+ else
+ cfg_reg &= ~MAC_CMDCFG_HD_ENA;
+
+ netdev_dbg(priv->dev, "%s: Link duplex = 0x%x\n",
+ dev->name, phydev->duplex);
+
+ priv->oldduplex = phydev->duplex;
+ }
+
+ /* Check speed */
+ if (phydev->speed != priv->oldspeed) {
+ new_state = 1;
+ switch (phydev->speed) {
+ case 1000:
+ cfg_reg |= MAC_CMDCFG_ETH_SPEED;
+ cfg_reg &= ~MAC_CMDCFG_ENA_10;
+ break;
+ case 100:
+ cfg_reg &= ~MAC_CMDCFG_ETH_SPEED;
+ cfg_reg &= ~MAC_CMDCFG_ENA_10;
+ break;
+ case 10:
+ cfg_reg &= ~MAC_CMDCFG_ETH_SPEED;
+ cfg_reg |= MAC_CMDCFG_ENA_10;
+ break;
+ default:
+ if (netif_msg_link(priv))
+ netdev_warn(dev, "Speed (%d) is not 10/100/1000!\n",
+ phydev->speed);
+ break;
+ }
+ priv->oldspeed = phydev->speed;
+ }
+ iowrite32(cfg_reg, &priv->mac_dev->command_config);
+
+ if (!priv->oldlink) {
+ new_state = 1;
+ priv->oldlink = 1;
+ }
+ } else if (priv->oldlink) {
+ new_state = 1;
+ priv->oldlink = 0;
+ priv->oldspeed = 0;
+ priv->oldduplex = -1;
+ }
+
+ if (new_state && netif_msg_link(priv))
+ phy_print_status(phydev);
+
+ spin_unlock(&priv->mac_cfg_lock);
+}
+static struct phy_device *connect_local_phy(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ struct phy_device *phydev = NULL;
+ char phy_id_fmt[MII_BUS_ID_SIZE + 3];
+
+ if (priv->phy_addr != POLL_PHY) {
+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT,
+ priv->mdio->id, priv->phy_addr);
+
+ netdev_dbg(dev, "trying to attach to %s\n", phy_id_fmt);
+
+ phydev = phy_connect(dev, phy_id_fmt, &altera_tse_adjust_link,
+ priv->phy_iface);
+ if (IS_ERR(phydev))
+ netdev_err(dev, "Could not attach to PHY\n");
+
+ } else {
+ int ret;
+ phydev = phy_find_first(priv->mdio);
+ if (phydev == NULL) {
+ netdev_err(dev, "No PHY found\n");
+ return phydev;
+ }
+
+ ret = phy_connect_direct(dev, phydev, &altera_tse_adjust_link,
+ priv->phy_iface);
+ if (ret != 0) {
+ netdev_err(dev, "Could not attach to PHY\n");
+ phydev = NULL;
+ }
+ }
+ return phydev;
+}
+
+/* Initialize driver's PHY state, and attach to the PHY
+ */
+static int init_phy(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ struct phy_device *phydev;
+ struct device_node *phynode;
+
+ priv->oldlink = 0;
+ priv->oldspeed = 0;
+ priv->oldduplex = -1;
+
+ phynode = of_parse_phandle(priv->device->of_node, "phy-handle", 0);
+
+ if (!phynode) {
+ netdev_dbg(dev, "no phy-handle found\n");
+ if (!priv->mdio) {
+ netdev_err(dev,
+ "No phy-handle nor local mdio specified\n");
+ return -ENODEV;
+ }
+ phydev = connect_local_phy(dev);
+ } else {
+ netdev_dbg(dev, "phy-handle found\n");
+ phydev = of_phy_connect(dev, phynode,
+ &altera_tse_adjust_link, 0, priv->phy_iface);
+ }
+
+ if (!phydev) {
+ netdev_err(dev, "Could not find the PHY\n");
+ return -ENODEV;
+ }
+
+ /* Stop Advertising 1000BASE Capability if interface is not GMII
+ * Note: Checkpatch throws CHECKs for the camel case defines below,
+ * it's ok to ignore.
+ */
+ if ((priv->phy_iface == PHY_INTERFACE_MODE_MII) ||
+ (priv->phy_iface == PHY_INTERFACE_MODE_RMII))
+ phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full);
+
+ /* Broken HW is sometimes missing the pull-up resistor on the
+ * MDIO line, which results in reads to non-existent devices returning
+ * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
+ * device as well.
+ * Note: phydev->phy_id is the result of reading the UID PHY registers.
+ */
+ if (phydev->phy_id == 0) {
+ netdev_err(dev, "Bad PHY UID 0x%08x\n", phydev->phy_id);
+ phy_disconnect(phydev);
+ return -ENODEV;
+ }
+
+ netdev_dbg(dev, "attached to PHY %d UID 0x%08x Link = %d\n",
+ phydev->addr, phydev->phy_id, phydev->link);
+
+ priv->phydev = phydev;
+ return 0;
+}
+
+static void tse_update_mac_addr(struct altera_tse_private *priv, u8 *addr)
+{
+ u32 msb;
+ u32 lsb;
+
+ msb = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
+ lsb = ((addr[5] << 8) | addr[4]) & 0xffff;
+
+ /* Set primary MAC address */
+ csrwr32(msb, priv->mac_dev, tse_csroffs(mac_addr_0));
+ csrwr32(lsb, priv->mac_dev, tse_csroffs(mac_addr_1));
+}
+
+/* MAC software reset.
+ * When reset is triggered, the MAC function completes the current
+ * transmission or reception, and subsequently disables the transmit and
+ * receive logic, flushes the receive FIFO buffer, and resets the statistics
+ * counters.
+ */
+static int reset_mac(struct altera_tse_private *priv)
+{
+ int counter;
+ u32 dat;
+
+ dat = csrrd32(priv->mac_dev, tse_csroffs(command_config));
+ dat &= ~(MAC_CMDCFG_TX_ENA | MAC_CMDCFG_RX_ENA);
+ dat |= MAC_CMDCFG_SW_RESET | MAC_CMDCFG_CNT_RESET;
+ csrwr32(dat, priv->mac_dev, tse_csroffs(command_config));
+
+ counter = 0;
+ while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
+ if (tse_bit_is_clear(priv->mac_dev, tse_csroffs(command_config),
+ MAC_CMDCFG_SW_RESET))
+ break;
+ udelay(1);
+ }
+
+ if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
+ dat = csrrd32(priv->mac_dev, tse_csroffs(command_config));
+ dat &= ~MAC_CMDCFG_SW_RESET;
+ csrwr32(dat, priv->mac_dev, tse_csroffs(command_config));
+ return -1;
+ }
+ return 0;
+}
+
+/* Initialize MAC core registers
+*/
+static int init_mac(struct altera_tse_private *priv)
+{
+ unsigned int cmd = 0;
+ u32 frm_length;
+
+ /* Setup Rx FIFO */
+ csrwr32(priv->rx_fifo_depth - ALTERA_TSE_RX_SECTION_EMPTY,
+ priv->mac_dev, tse_csroffs(rx_section_empty));
+
+ csrwr32(ALTERA_TSE_RX_SECTION_FULL, priv->mac_dev,
+ tse_csroffs(rx_section_full));
+
+ csrwr32(ALTERA_TSE_RX_ALMOST_EMPTY, priv->mac_dev,
+ tse_csroffs(rx_almost_empty));
+
+ csrwr32(ALTERA_TSE_RX_ALMOST_FULL, priv->mac_dev,
+ tse_csroffs(rx_almost_full));
+
+ /* Setup Tx FIFO */
+ csrwr32(priv->tx_fifo_depth - ALTERA_TSE_TX_SECTION_EMPTY,
+ priv->mac_dev, tse_csroffs(tx_section_empty));
+
+ csrwr32(ALTERA_TSE_TX_SECTION_FULL, priv->mac_dev,
+ tse_csroffs(tx_section_full));
+
+ csrwr32(ALTERA_TSE_TX_ALMOST_EMPTY, priv->mac_dev,
+ tse_csroffs(tx_almost_empty));
+
+ csrwr32(ALTERA_TSE_TX_ALMOST_FULL, priv->mac_dev,
+ tse_csroffs(tx_almost_full));
+
+ /* MAC Address Configuration */
+ tse_update_mac_addr(priv, priv->dev->dev_addr);
+
+ /* MAC Function Configuration */
+ frm_length = ETH_HLEN + priv->dev->mtu + ETH_FCS_LEN;
+ csrwr32(frm_length, priv->mac_dev, tse_csroffs(frm_length));
+
+ csrwr32(ALTERA_TSE_TX_IPG_LENGTH, priv->mac_dev,
+ tse_csroffs(tx_ipg_length));
+
+ /* Disable RX/TX shift 16 for alignment of all received frames on 16-bit
+ * start address
+ */
+ tse_set_bit(priv->mac_dev, tse_csroffs(rx_cmd_stat),
+ ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16);
+
+ tse_clear_bit(priv->mac_dev, tse_csroffs(tx_cmd_stat),
+ ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 |
+ ALTERA_TSE_TX_CMD_STAT_OMIT_CRC);
+
+ /* Set the MAC options */
+ cmd = csrrd32(priv->mac_dev, tse_csroffs(command_config));
+ cmd &= ~MAC_CMDCFG_PAD_EN; /* No padding Removal on Receive */
+ cmd &= ~MAC_CMDCFG_CRC_FWD; /* CRC Removal */
+ cmd |= MAC_CMDCFG_RX_ERR_DISC; /* Automatically discard frames
+ * with CRC errors
+ */
+ cmd |= MAC_CMDCFG_CNTL_FRM_ENA;
+ cmd &= ~MAC_CMDCFG_TX_ENA;
+ cmd &= ~MAC_CMDCFG_RX_ENA;
+
+ /* Default speed and duplex setting, full/100 */
+ cmd &= ~MAC_CMDCFG_HD_ENA;
+ cmd &= ~MAC_CMDCFG_ETH_SPEED;
+ cmd &= ~MAC_CMDCFG_ENA_10;
+
+ csrwr32(cmd, priv->mac_dev, tse_csroffs(command_config));
+
+ csrwr32(ALTERA_TSE_PAUSE_QUANTA, priv->mac_dev,
+ tse_csroffs(pause_quanta));
+
+ if (netif_msg_hw(priv))
+ dev_dbg(priv->device,
+ "MAC post-initialization: CMD_CONFIG = 0x%08x\n", cmd);
+
+ return 0;
+}
+
+/* Start/stop MAC transmission logic
+ */
+static void tse_set_mac(struct altera_tse_private *priv, bool enable)
+{
+ u32 value = csrrd32(priv->mac_dev, tse_csroffs(command_config));
+
+ if (enable)
+ value |= MAC_CMDCFG_TX_ENA | MAC_CMDCFG_RX_ENA;
+ else
+ value &= ~(MAC_CMDCFG_TX_ENA | MAC_CMDCFG_RX_ENA);
+
+ csrwr32(value, priv->mac_dev, tse_csroffs(command_config));
+}
+
+/* Change the MTU
+ */
+static int tse_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ unsigned int max_mtu = priv->max_mtu;
+ unsigned int min_mtu = ETH_ZLEN + ETH_FCS_LEN;
+
+ if (netif_running(dev)) {
+ netdev_err(dev, "must be stopped to change its MTU\n");
+ return -EBUSY;
+ }
+
+ if ((new_mtu < min_mtu) || (new_mtu > max_mtu)) {
+ netdev_err(dev, "invalid MTU, max MTU is: %u\n", max_mtu);
+ return -EINVAL;
+ }
+
+ dev->mtu = new_mtu;
+ netdev_update_features(dev);
+
+ return 0;
+}
+
+static void altera_tse_set_mcfilter(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ int i;
+ struct netdev_hw_addr *ha;
+
+ /* clear the hash filter */
+ for (i = 0; i < 64; i++)
+ csrwr32(0, priv->mac_dev, tse_csroffs(hash_table) + i * 4);
+
+ netdev_for_each_mc_addr(ha, dev) {
+ unsigned int hash = 0;
+ int mac_octet;
+
+ for (mac_octet = 5; mac_octet >= 0; mac_octet--) {
+ unsigned char xor_bit = 0;
+ unsigned char octet = ha->addr[mac_octet];
+ unsigned int bitshift;
+
+ for (bitshift = 0; bitshift < 8; bitshift++)
+ xor_bit ^= ((octet >> bitshift) & 0x01);
+
+ hash = (hash << 1) | xor_bit;
+ }
+ csrwr32(1, priv->mac_dev, tse_csroffs(hash_table) + hash * 4);
+ }
+}
+
+
+static void altera_tse_set_mcfilterall(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ int i;
+
+ /* set the hash filter */
+ for (i = 0; i < 64; i++)
+ csrwr32(1, priv->mac_dev, tse_csroffs(hash_table) + i * 4);
+}
+
+/* Set or clear the multicast filter for this adaptor
+ */
+static void tse_set_rx_mode_hashfilter(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+
+ spin_lock(&priv->mac_cfg_lock);
+
+ if (dev->flags & IFF_PROMISC)
+ tse_set_bit(priv->mac_dev, tse_csroffs(command_config),
+ MAC_CMDCFG_PROMIS_EN);
+
+ if (dev->flags & IFF_ALLMULTI)
+ altera_tse_set_mcfilterall(dev);
+ else
+ altera_tse_set_mcfilter(dev);
+
+ spin_unlock(&priv->mac_cfg_lock);
+}
+
+/* Set or clear the multicast filter for this adaptor
+ */
+static void tse_set_rx_mode(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+
+ spin_lock(&priv->mac_cfg_lock);
+
+ if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
+ !netdev_mc_empty(dev) || !netdev_uc_empty(dev))
+ tse_set_bit(priv->mac_dev, tse_csroffs(command_config),
+ MAC_CMDCFG_PROMIS_EN);
+ else
+ tse_clear_bit(priv->mac_dev, tse_csroffs(command_config),
+ MAC_CMDCFG_PROMIS_EN);
+
+ spin_unlock(&priv->mac_cfg_lock);
+}
+
+/* Open and initialize the interface
+ */
+static int tse_open(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ int ret = 0;
+ int i;
+ unsigned long int flags;
+
+ /* Reset and configure TSE MAC and probe associated PHY */
+ ret = priv->dmaops->init_dma(priv);
+ if (ret != 0) {
+ netdev_err(dev, "Cannot initialize DMA\n");
+ goto phy_error;
+ }
+
+ if (netif_msg_ifup(priv))
+ netdev_warn(dev, "device MAC address %pM\n",
+ dev->dev_addr);
+
+ if ((priv->revision < 0xd00) || (priv->revision > 0xe00))
+ netdev_warn(dev, "TSE revision %x\n", priv->revision);
+
+ spin_lock(&priv->mac_cfg_lock);
+ ret = reset_mac(priv);
+ if (ret)
+ netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret);
+
+ ret = init_mac(priv);
+ spin_unlock(&priv->mac_cfg_lock);
+ if (ret) {
+ netdev_err(dev, "Cannot init MAC core (error: %d)\n", ret);
+ goto alloc_skbuf_error;
+ }
+
+ priv->dmaops->reset_dma(priv);
+
+ /* Create and initialize the TX/RX descriptors chains. */
+ priv->rx_ring_size = dma_rx_num;
+ priv->tx_ring_size = dma_tx_num;
+ ret = alloc_init_skbufs(priv);
+ if (ret) {
+ netdev_err(dev, "DMA descriptors initialization failed\n");
+ goto alloc_skbuf_error;
+ }
+
+
+ /* Register RX interrupt */
+ ret = request_irq(priv->rx_irq, altera_isr, IRQF_SHARED,
+ dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "Unable to register RX interrupt %d\n",
+ priv->rx_irq);
+ goto init_error;
+ }
+
+ /* Register TX interrupt */
+ ret = request_irq(priv->tx_irq, altera_isr, IRQF_SHARED,
+ dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "Unable to register TX interrupt %d\n",
+ priv->tx_irq);
+ goto tx_request_irq_error;
+ }
+
+ /* Enable DMA interrupts */
+ spin_lock_irqsave(&priv->rxdma_irq_lock, flags);
+ priv->dmaops->enable_rxirq(priv);
+ priv->dmaops->enable_txirq(priv);
+
+ /* Setup RX descriptor chain */
+ for (i = 0; i < priv->rx_ring_size; i++)
+ priv->dmaops->add_rx_desc(priv, &priv->rx_ring[i]);
+
+ spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
+
+ if (priv->phydev)
+ phy_start(priv->phydev);
+
+ napi_enable(&priv->napi);
+ netif_start_queue(dev);
+
+ priv->dmaops->start_rxdma(priv);
+
+ /* Start MAC Rx/Tx */
+ spin_lock(&priv->mac_cfg_lock);
+ tse_set_mac(priv, true);
+ spin_unlock(&priv->mac_cfg_lock);
+
+ return 0;
+
+tx_request_irq_error:
+ free_irq(priv->rx_irq, dev);
+init_error:
+ free_skbufs(dev);
+alloc_skbuf_error:
+ if (priv->phydev) {
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
+phy_error:
+ return ret;
+}
+
+/* Stop TSE MAC interface and put the device in an inactive state
+ */
+static int tse_shutdown(struct net_device *dev)
+{
+ struct altera_tse_private *priv = netdev_priv(dev);
+ int ret;
+ unsigned long int flags;
+
+ /* Stop and disconnect the PHY */
+ if (priv->phydev) {
+ phy_stop(priv->phydev);
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
+
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+
+ /* Disable DMA interrupts */
+ spin_lock_irqsave(&priv->rxdma_irq_lock, flags);
+ priv->dmaops->disable_rxirq(priv);
+ priv->dmaops->disable_txirq(priv);
+ spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags);
+
+ /* Free the IRQ lines */
+ free_irq(priv->rx_irq, dev);
+ free_irq(priv->tx_irq, dev);
+
+ /* disable and reset the MAC, empties fifo */
+ spin_lock(&priv->mac_cfg_lock);
+ spin_lock(&priv->tx_lock);
+
+ ret = reset_mac(priv);
+ if (ret)
+ netdev_err(dev, "Cannot reset MAC core (error: %d)\n", ret);
+ priv->dmaops->reset_dma(priv);
+ free_skbufs(dev);
+
+ spin_unlock(&priv->tx_lock);
+ spin_unlock(&priv->mac_cfg_lock);
+
+ priv->dmaops->uninit_dma(priv);
+
+ return 0;
+}
+
+static struct net_device_ops altera_tse_netdev_ops = {
+ .ndo_open = tse_open,
+ .ndo_stop = tse_shutdown,
+ .ndo_start_xmit = tse_start_xmit,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_rx_mode = tse_set_rx_mode,
+ .ndo_change_mtu = tse_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static int request_and_map(struct platform_device *pdev, const char *name,
+ struct resource **res, void __iomem **ptr)
+{
+ struct resource *region;
+ struct device *device = &pdev->dev;
+
+ *res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+ if (*res == NULL) {
+ dev_err(device, "resource %s not defined\n", name);
+ return -ENODEV;
+ }
+
+ region = devm_request_mem_region(device, (*res)->start,
+ resource_size(*res), dev_name(device));
+ if (region == NULL) {
+ dev_err(device, "unable to request %s\n", name);
+ return -EBUSY;
+ }
+
+ *ptr = devm_ioremap_nocache(device, region->start,
+ resource_size(region));
+ if (*ptr == NULL) {
+ dev_err(device, "ioremap_nocache of %s failed!", name);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/* Probe Altera TSE MAC device
+ */
+static int altera_tse_probe(struct platform_device *pdev)
+{
+ struct net_device *ndev;
+ int ret = -ENODEV;
+ struct resource *control_port;
+ struct resource *dma_res;
+ struct altera_tse_private *priv;
+ const unsigned char *macaddr;
+ struct device_node *np = pdev->dev.of_node;
+ void __iomem *descmap;
+ const struct of_device_id *of_id = NULL;
+
+ ndev = alloc_etherdev(sizeof(struct altera_tse_private));
+ if (!ndev) {
+ dev_err(&pdev->dev, "Could not allocate network device\n");
+ return -ENODEV;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ priv = netdev_priv(ndev);
+ priv->device = &pdev->dev;
+ priv->dev = ndev;
+ priv->msg_enable = netif_msg_init(debug, default_msg_level);
+
+ of_id = of_match_device(altera_tse_ids, &pdev->dev);
+
+ if (of_id)
+ priv->dmaops = (struct altera_dmaops *)of_id->data;
+
+
+ if (priv->dmaops &&
+ priv->dmaops->altera_dtype == ALTERA_DTYPE_SGDMA) {
+ /* Get the mapped address to the SGDMA descriptor memory */
+ ret = request_and_map(pdev, "s1", &dma_res, &descmap);
+ if (ret)
+ goto err_free_netdev;
+
+ /* Start of that memory is for transmit descriptors */
+ priv->tx_dma_desc = descmap;
+
+ /* First half is for tx descriptors, other half for tx */
+ priv->txdescmem = resource_size(dma_res)/2;
+
+ priv->txdescmem_busaddr = (dma_addr_t)dma_res->start;
+
+ priv->rx_dma_desc = (void __iomem *)((uintptr_t)(descmap +
+ priv->txdescmem));
+ priv->rxdescmem = resource_size(dma_res)/2;
+ priv->rxdescmem_busaddr = dma_res->start;
+ priv->rxdescmem_busaddr += priv->txdescmem;
+
+ if (upper_32_bits(priv->rxdescmem_busaddr)) {
+ dev_dbg(priv->device,
+ "SGDMA bus addresses greater than 32-bits\n");
+ goto err_free_netdev;
+ }
+ if (upper_32_bits(priv->txdescmem_busaddr)) {
+ dev_dbg(priv->device,
+ "SGDMA bus addresses greater than 32-bits\n");
+ goto err_free_netdev;
+ }
+ } else if (priv->dmaops &&
+ priv->dmaops->altera_dtype == ALTERA_DTYPE_MSGDMA) {
+ ret = request_and_map(pdev, "rx_resp", &dma_res,
+ &priv->rx_dma_resp);
+ if (ret)
+ goto err_free_netdev;
+
+ ret = request_and_map(pdev, "tx_desc", &dma_res,
+ &priv->tx_dma_desc);
+ if (ret)
+ goto err_free_netdev;
+
+ priv->txdescmem = resource_size(dma_res);
+ priv->txdescmem_busaddr = dma_res->start;
+
+ ret = request_and_map(pdev, "rx_desc", &dma_res,
+ &priv->rx_dma_desc);
+ if (ret)
+ goto err_free_netdev;
+
+ priv->rxdescmem = resource_size(dma_res);
+ priv->rxdescmem_busaddr = dma_res->start;
+
+ } else {
+ goto err_free_netdev;
+ }
+
+ if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask)))
+ dma_set_coherent_mask(priv->device,
+ DMA_BIT_MASK(priv->dmaops->dmamask));
+ else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32)))
+ dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32));
+ else
+ goto err_free_netdev;
+
+ /* MAC address space */
+ ret = request_and_map(pdev, "control_port", &control_port,
+ (void __iomem **)&priv->mac_dev);
+ if (ret)
+ goto err_free_netdev;
+
+ /* xSGDMA Rx Dispatcher address space */
+ ret = request_and_map(pdev, "rx_csr", &dma_res,
+ &priv->rx_dma_csr);
+ if (ret)
+ goto err_free_netdev;
+
+
+ /* xSGDMA Tx Dispatcher address space */
+ ret = request_and_map(pdev, "tx_csr", &dma_res,
+ &priv->tx_dma_csr);
+ if (ret)
+ goto err_free_netdev;
+
+
+ /* Rx IRQ */
+ priv->rx_irq = platform_get_irq_byname(pdev, "rx_irq");
+ if (priv->rx_irq == -ENXIO) {
+ dev_err(&pdev->dev, "cannot obtain Rx IRQ\n");
+ ret = -ENXIO;
+ goto err_free_netdev;
+ }
+
+ /* Tx IRQ */
+ priv->tx_irq = platform_get_irq_byname(pdev, "tx_irq");
+ if (priv->tx_irq == -ENXIO) {
+ dev_err(&pdev->dev, "cannot obtain Tx IRQ\n");
+ ret = -ENXIO;
+ goto err_free_netdev;
+ }
+
+ /* get FIFO depths from device tree */
+ if (of_property_read_u32(pdev->dev.of_node, "rx-fifo-depth",
+ &priv->rx_fifo_depth)) {
+ dev_err(&pdev->dev, "cannot obtain rx-fifo-depth\n");
+ ret = -ENXIO;
+ goto err_free_netdev;
+ }
+
+ if (of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth",
+ &priv->rx_fifo_depth)) {
+ dev_err(&pdev->dev, "cannot obtain tx-fifo-depth\n");
+ ret = -ENXIO;
+ goto err_free_netdev;
+ }
+
+ /* get hash filter settings for this instance */
+ priv->hash_filter =
+ of_property_read_bool(pdev->dev.of_node,
+ "altr,has-hash-multicast-filter");
+
+ /* Set hash filter to not set for now until the
+ * multicast filter receive issue is debugged
+ */
+ priv->hash_filter = 0;
+
+ /* get supplemental address settings for this instance */
+ priv->added_unicast =
+ of_property_read_bool(pdev->dev.of_node,
+ "altr,has-supplementary-unicast");
+
+ /* Max MTU is 1500, ETH_DATA_LEN */
+ priv->max_mtu = ETH_DATA_LEN;
+
+ /* Get the max mtu from the device tree. Note that the
+ * "max-frame-size" parameter is actually max mtu. Definition
+ * in the ePAPR v1.1 spec and usage differ, so go with usage.
+ */
+ of_property_read_u32(pdev->dev.of_node, "max-frame-size",
+ &priv->max_mtu);
+
+ /* The DMA buffer size already accounts for an alignment bias
+ * to avoid unaligned access exceptions for the NIOS processor,
+ */
+ priv->rx_dma_buf_sz = ALTERA_RXDMABUFFER_SIZE;
+
+ /* get default MAC address from device tree */
+ macaddr = of_get_mac_address(pdev->dev.of_node);
+ if (macaddr)
+ ether_addr_copy(ndev->dev_addr, macaddr);
+ else
+ eth_hw_addr_random(ndev);
+
+ priv->phy_iface = of_get_phy_mode(np);
+
+ /* try to get PHY address from device tree, use PHY autodetection if
+ * no valid address is given
+ */
+ if (of_property_read_u32(pdev->dev.of_node, "phy-addr",
+ &priv->phy_addr)) {
+ priv->phy_addr = POLL_PHY;
+ }
+
+ if (!((priv->phy_addr == POLL_PHY) ||
+ ((priv->phy_addr >= 0) && (priv->phy_addr < PHY_MAX_ADDR)))) {
+ dev_err(&pdev->dev, "invalid phy-addr specified %d\n",
+ priv->phy_addr);
+ goto err_free_netdev;
+ }
+
+ /* Create/attach to MDIO bus */
+ ret = altera_tse_mdio_create(ndev,
+ atomic_add_return(1, &instance_count));
+
+ if (ret)
+ goto err_free_netdev;
+
+ /* initialize netdev */
+ ether_setup(ndev);
+ ndev->mem_start = control_port->start;
+ ndev->mem_end = control_port->end;
+ ndev->netdev_ops = &altera_tse_netdev_ops;
+ altera_tse_set_ethtool_ops(ndev);
+
+ altera_tse_netdev_ops.ndo_set_rx_mode = tse_set_rx_mode;
+
+ if (priv->hash_filter)
+ altera_tse_netdev_ops.ndo_set_rx_mode =
+ tse_set_rx_mode_hashfilter;
+
+ /* Scatter/gather IO is not supported,
+ * so it is turned off
+ */
+ ndev->hw_features &= ~NETIF_F_SG;
+ ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
+
+ /* VLAN offloading of tagging, stripping and filtering is not
+ * supported by hardware, but driver will accommodate the
+ * extra 4-byte VLAN tag for processing by upper layers
+ */
+ ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+
+ /* setup NAPI interface */
+ netif_napi_add(ndev, &priv->napi, tse_poll, NAPI_POLL_WEIGHT);
+
+ spin_lock_init(&priv->mac_cfg_lock);
+ spin_lock_init(&priv->tx_lock);
+ spin_lock_init(&priv->rxdma_irq_lock);
+
+ ret = register_netdev(ndev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register TSE net device\n");
+ goto err_register_netdev;
+ }
+
+ platform_set_drvdata(pdev, ndev);
+
+ priv->revision = ioread32(&priv->mac_dev->megacore_revision);
+
+ if (netif_msg_probe(priv))
+ dev_info(&pdev->dev, "Altera TSE MAC version %d.%d at 0x%08lx irq %d/%d\n",
+ (priv->revision >> 8) & 0xff,
+ priv->revision & 0xff,
+ (unsigned long) control_port->start, priv->rx_irq,
+ priv->tx_irq);
+
+ ret = init_phy(ndev);
+ if (ret != 0) {
+ netdev_err(ndev, "Cannot attach to PHY (error: %d)\n", ret);
+ goto err_init_phy;
+ }
+ return 0;
+
+err_init_phy:
+ unregister_netdev(ndev);
+err_register_netdev:
+ netif_napi_del(&priv->napi);
+ altera_tse_mdio_destroy(ndev);
+err_free_netdev:
+ free_netdev(ndev);
+ return ret;
+}
+
+/* Remove Altera TSE MAC device
+ */
+static int altera_tse_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ altera_tse_mdio_destroy(ndev);
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+
+ return 0;
+}
+
+static const struct altera_dmaops altera_dtype_sgdma = {
+ .altera_dtype = ALTERA_DTYPE_SGDMA,
+ .dmamask = 32,
+ .reset_dma = sgdma_reset,
+ .enable_txirq = sgdma_enable_txirq,
+ .enable_rxirq = sgdma_enable_rxirq,
+ .disable_txirq = sgdma_disable_txirq,
+ .disable_rxirq = sgdma_disable_rxirq,
+ .clear_txirq = sgdma_clear_txirq,
+ .clear_rxirq = sgdma_clear_rxirq,
+ .tx_buffer = sgdma_tx_buffer,
+ .tx_completions = sgdma_tx_completions,
+ .add_rx_desc = sgdma_add_rx_desc,
+ .get_rx_status = sgdma_rx_status,
+ .init_dma = sgdma_initialize,
+ .uninit_dma = sgdma_uninitialize,
+ .start_rxdma = sgdma_start_rxdma,
+};
+
+static const struct altera_dmaops altera_dtype_msgdma = {
+ .altera_dtype = ALTERA_DTYPE_MSGDMA,
+ .dmamask = 64,
+ .reset_dma = msgdma_reset,
+ .enable_txirq = msgdma_enable_txirq,
+ .enable_rxirq = msgdma_enable_rxirq,
+ .disable_txirq = msgdma_disable_txirq,
+ .disable_rxirq = msgdma_disable_rxirq,
+ .clear_txirq = msgdma_clear_txirq,
+ .clear_rxirq = msgdma_clear_rxirq,
+ .tx_buffer = msgdma_tx_buffer,
+ .tx_completions = msgdma_tx_completions,
+ .add_rx_desc = msgdma_add_rx_desc,
+ .get_rx_status = msgdma_rx_status,
+ .init_dma = msgdma_initialize,
+ .uninit_dma = msgdma_uninitialize,
+ .start_rxdma = msgdma_start_rxdma,
+};
+
+static struct of_device_id altera_tse_ids[] = {
+ { .compatible = "altr,tse-msgdma-1.0", .data = &altera_dtype_msgdma, },
+ { .compatible = "altr,tse-1.0", .data = &altera_dtype_sgdma, },
+ { .compatible = "ALTR,tse-1.0", .data = &altera_dtype_sgdma, },
+ {},
+};
+MODULE_DEVICE_TABLE(of, altera_tse_ids);
+
+static struct platform_driver altera_tse_driver = {
+ .probe = altera_tse_probe,
+ .remove = altera_tse_remove,
+ .suspend = NULL,
+ .resume = NULL,
+ .driver = {
+ .name = ALTERA_TSE_RESOURCE_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = altera_tse_ids,
+ },
+};
+
+module_platform_driver(altera_tse_driver);
+
+MODULE_AUTHOR("Altera Corporation");
+MODULE_DESCRIPTION("Altera Triple Speed Ethernet MAC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/ethernet/altera/altera_utils.c b/drivers/net/ethernet/altera/altera_utils.c
new file mode 100644
index 00000000000..d7eeb1713ad
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_utils.c
@@ -0,0 +1,44 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "altera_tse.h"
+#include "altera_utils.h"
+
+void tse_set_bit(void __iomem *ioaddr, size_t offs, u32 bit_mask)
+{
+ u32 value = csrrd32(ioaddr, offs);
+ value |= bit_mask;
+ csrwr32(value, ioaddr, offs);
+}
+
+void tse_clear_bit(void __iomem *ioaddr, size_t offs, u32 bit_mask)
+{
+ u32 value = csrrd32(ioaddr, offs);
+ value &= ~bit_mask;
+ csrwr32(value, ioaddr, offs);
+}
+
+int tse_bit_is_set(void __iomem *ioaddr, size_t offs, u32 bit_mask)
+{
+ u32 value = csrrd32(ioaddr, offs);
+ return (value & bit_mask) ? 1 : 0;
+}
+
+int tse_bit_is_clear(void __iomem *ioaddr, size_t offs, u32 bit_mask)
+{
+ u32 value = csrrd32(ioaddr, offs);
+ return (value & bit_mask) ? 0 : 1;
+}
diff --git a/drivers/net/ethernet/altera/altera_utils.h b/drivers/net/ethernet/altera/altera_utils.h
new file mode 100644
index 00000000000..baf100ccf58
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_utils.h
@@ -0,0 +1,27 @@
+/* Altera TSE SGDMA and MSGDMA Linux driver
+ * Copyright (C) 2014 Altera Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+
+#ifndef __ALTERA_UTILS_H__
+#define __ALTERA_UTILS_H__
+
+void tse_set_bit(void __iomem *ioaddr, size_t offs, u32 bit_mask);
+void tse_clear_bit(void __iomem *ioaddr, size_t offs, u32 bit_mask);
+int tse_bit_is_set(void __iomem *ioaddr, size_t offs, u32 bit_mask);
+int tse_bit_is_clear(void __iomem *ioaddr, size_t offs, u32 bit_mask);
+
+#endif /* __ALTERA_UTILS_H__*/
diff --git a/drivers/net/ethernet/amd/7990.c b/drivers/net/ethernet/amd/7990.c
new file mode 100644
index 00000000000..98a10d555b7
--- /dev/null
+++ b/drivers/net/ethernet/amd/7990.c
@@ -0,0 +1,666 @@
+/*
+ * 7990.c -- LANCE ethernet IC generic routines.
+ * This is an attempt to separate out the bits of various ethernet
+ * drivers that are common because they all use the AMD 7990 LANCE
+ * (Local Area Network Controller for Ethernet) chip.
+ *
+ * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
+ *
+ * Most of this stuff was obtained by looking at other LANCE drivers,
+ * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
+ * NB: this was made easy by the fact that Jes Sorensen had cleaned up
+ * most of a2025 and sunlance with the aim of merging them, so the
+ * common code was pretty obvious.
+ */
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/route.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <asm/irq.h>
+/* Used for the temporal inet entries and routing */
+#include <linux/socket.h>
+#include <linux/bitops.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/pgtable.h>
+#ifdef CONFIG_HP300
+#include <asm/blinken.h>
+#endif
+
+#include "7990.h"
+
+#define WRITERAP(lp, x) out_be16(lp->base + LANCE_RAP, (x))
+#define WRITERDP(lp, x) out_be16(lp->base + LANCE_RDP, (x))
+#define READRDP(lp) in_be16(lp->base + LANCE_RDP)
+
+#if defined(CONFIG_HPLANCE) || defined(CONFIG_HPLANCE_MODULE)
+#include "hplance.h"
+
+#undef WRITERAP
+#undef WRITERDP
+#undef READRDP
+
+#if defined(CONFIG_MVME147_NET) || defined(CONFIG_MVME147_NET_MODULE)
+
+/* Lossage Factor Nine, Mr Sulu. */
+#define WRITERAP(lp, x) (lp->writerap(lp, x))
+#define WRITERDP(lp, x) (lp->writerdp(lp, x))
+#define READRDP(lp) (lp->readrdp(lp))
+
+#else
+
+/* These inlines can be used if only CONFIG_HPLANCE is defined */
+static inline void WRITERAP(struct lance_private *lp, __u16 value)
+{
+ do {
+ out_be16(lp->base + HPLANCE_REGOFF + LANCE_RAP, value);
+ } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
+}
+
+static inline void WRITERDP(struct lance_private *lp, __u16 value)
+{
+ do {
+ out_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP, value);
+ } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
+}
+
+static inline __u16 READRDP(struct lance_private *lp)
+{
+ __u16 value;
+ do {
+ value = in_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP);
+ } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
+ return value;
+}
+
+#endif
+#endif /* CONFIG_HPLANCE || CONFIG_HPLANCE_MODULE */
+
+/* debugging output macros, various flavours */
+/* #define TEST_HITS */
+#ifdef UNDEF
+#define PRINT_RINGS() \
+do { \
+ int t; \
+ for (t = 0; t < RX_RING_SIZE; t++) { \
+ printk("R%d: @(%02X %04X) len %04X, mblen %04X, bits %02X\n", \
+ t, ib->brx_ring[t].rmd1_hadr, ib->brx_ring[t].rmd0, \
+ ib->brx_ring[t].length, \
+ ib->brx_ring[t].mblength, ib->brx_ring[t].rmd1_bits); \
+ } \
+ for (t = 0; t < TX_RING_SIZE; t++) { \
+ printk("T%d: @(%02X %04X) len %04X, misc %04X, bits %02X\n", \
+ t, ib->btx_ring[t].tmd1_hadr, ib->btx_ring[t].tmd0, \
+ ib->btx_ring[t].length, \
+ ib->btx_ring[t].misc, ib->btx_ring[t].tmd1_bits); \
+ } \
+} while (0)
+#else
+#define PRINT_RINGS()
+#endif
+
+/* Load the CSR registers. The LANCE has to be STOPped when we do this! */
+static void load_csrs(struct lance_private *lp)
+{
+ volatile struct lance_init_block *aib = lp->lance_init_block;
+ int leptr;
+
+ leptr = LANCE_ADDR(aib);
+
+ WRITERAP(lp, LE_CSR1); /* load address of init block */
+ WRITERDP(lp, leptr & 0xFFFF);
+ WRITERAP(lp, LE_CSR2);
+ WRITERDP(lp, leptr >> 16);
+ WRITERAP(lp, LE_CSR3);
+ WRITERDP(lp, lp->busmaster_regval); /* set byteswap/ALEctrl/byte ctrl */
+
+ /* Point back to csr0 */
+ WRITERAP(lp, LE_CSR0);
+}
+
+/* #define to 0 or 1 appropriately */
+#define DEBUG_IRING 0
+/* Set up the Lance Rx and Tx rings and the init block */
+static void lance_init_ring(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ volatile struct lance_init_block *ib = lp->init_block;
+ volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */
+ int leptr;
+ int i;
+
+ aib = lp->lance_init_block;
+
+ lp->rx_new = lp->tx_new = 0;
+ lp->rx_old = lp->tx_old = 0;
+
+ ib->mode = LE_MO_PROM; /* normal, enable Tx & Rx */
+
+ /* Copy the ethernet address to the lance init block
+ * Notice that we do a byteswap if we're big endian.
+ * [I think this is the right criterion; at least, sunlance,
+ * a2065 and atarilance do the byteswap and lance.c (PC) doesn't.
+ * However, the datasheet says that the BSWAP bit doesn't affect
+ * the init block, so surely it should be low byte first for
+ * everybody? Um.]
+ * We could define the ib->physaddr as three 16bit values and
+ * use (addr[1] << 8) | addr[0] & co, but this is more efficient.
+ */
+#ifdef __BIG_ENDIAN
+ ib->phys_addr[0] = dev->dev_addr[1];
+ ib->phys_addr[1] = dev->dev_addr[0];
+ ib->phys_addr[2] = dev->dev_addr[3];
+ ib->phys_addr[3] = dev->dev_addr[2];
+ ib->phys_addr[4] = dev->dev_addr[5];
+ ib->phys_addr[5] = dev->dev_addr[4];
+#else
+ for (i = 0; i < 6; i++)
+ ib->phys_addr[i] = dev->dev_addr[i];
+#endif
+
+ if (DEBUG_IRING)
+ printk("TX rings:\n");
+
+ lp->tx_full = 0;
+ /* Setup the Tx ring entries */
+ for (i = 0; i < (1 << lp->lance_log_tx_bufs); i++) {
+ leptr = LANCE_ADDR(&aib->tx_buf[i][0]);
+ ib->btx_ring[i].tmd0 = leptr;
+ ib->btx_ring[i].tmd1_hadr = leptr >> 16;
+ ib->btx_ring[i].tmd1_bits = 0;
+ ib->btx_ring[i].length = 0xf000; /* The ones required by tmd2 */
+ ib->btx_ring[i].misc = 0;
+ if (DEBUG_IRING)
+ printk("%d: 0x%8.8x\n", i, leptr);
+ }
+
+ /* Setup the Rx ring entries */
+ if (DEBUG_IRING)
+ printk("RX rings:\n");
+ for (i = 0; i < (1 << lp->lance_log_rx_bufs); i++) {
+ leptr = LANCE_ADDR(&aib->rx_buf[i][0]);
+
+ ib->brx_ring[i].rmd0 = leptr;
+ ib->brx_ring[i].rmd1_hadr = leptr >> 16;
+ ib->brx_ring[i].rmd1_bits = LE_R1_OWN;
+ /* 0xf000 == bits that must be one (reserved, presumably) */
+ ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000;
+ ib->brx_ring[i].mblength = 0;
+ if (DEBUG_IRING)
+ printk("%d: 0x%8.8x\n", i, leptr);
+ }
+
+ /* Setup the initialization block */
+
+ /* Setup rx descriptor pointer */
+ leptr = LANCE_ADDR(&aib->brx_ring);
+ ib->rx_len = (lp->lance_log_rx_bufs << 13) | (leptr >> 16);
+ ib->rx_ptr = leptr;
+ if (DEBUG_IRING)
+ printk("RX ptr: %8.8x\n", leptr);
+
+ /* Setup tx descriptor pointer */
+ leptr = LANCE_ADDR(&aib->btx_ring);
+ ib->tx_len = (lp->lance_log_tx_bufs << 13) | (leptr >> 16);
+ ib->tx_ptr = leptr;
+ if (DEBUG_IRING)
+ printk("TX ptr: %8.8x\n", leptr);
+
+ /* Clear the multicast filter */
+ ib->filter[0] = 0;
+ ib->filter[1] = 0;
+ PRINT_RINGS();
+}
+
+/* LANCE must be STOPped before we do this, too... */
+static int init_restart_lance(struct lance_private *lp)
+{
+ int i;
+
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_INIT);
+
+ /* Need a hook here for sunlance ledma stuff */
+
+ /* Wait for the lance to complete initialization */
+ for (i = 0; (i < 100) && !(READRDP(lp) & (LE_C0_ERR | LE_C0_IDON)); i++)
+ barrier();
+ if ((i == 100) || (READRDP(lp) & LE_C0_ERR)) {
+ printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, READRDP(lp));
+ return -1;
+ }
+
+ /* Clear IDON by writing a "1", enable interrupts and start lance */
+ WRITERDP(lp, LE_C0_IDON);
+ WRITERDP(lp, LE_C0_INEA | LE_C0_STRT);
+
+ return 0;
+}
+
+static int lance_reset(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ int status;
+
+ /* Stop the lance */
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_STOP);
+
+ load_csrs(lp);
+ lance_init_ring(dev);
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ status = init_restart_lance(lp);
+#ifdef DEBUG_DRIVER
+ printk("Lance restart=%d\n", status);
+#endif
+ return status;
+}
+
+static int lance_rx(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ volatile struct lance_init_block *ib = lp->init_block;
+ volatile struct lance_rx_desc *rd;
+ unsigned char bits;
+#ifdef TEST_HITS
+ int i;
+#endif
+
+#ifdef TEST_HITS
+ printk("[");
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ if (i == lp->rx_new)
+ printk("%s",
+ ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "_" : "X");
+ else
+ printk("%s",
+ ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "." : "1");
+ }
+ printk("]");
+#endif
+#ifdef CONFIG_HP300
+ blinken_leds(0x40, 0);
+#endif
+ WRITERDP(lp, LE_C0_RINT | LE_C0_INEA); /* ack Rx int, reenable ints */
+ for (rd = &ib->brx_ring[lp->rx_new]; /* For each Rx ring we own... */
+ !((bits = rd->rmd1_bits) & LE_R1_OWN);
+ rd = &ib->brx_ring[lp->rx_new]) {
+
+ /* We got an incomplete frame? */
+ if ((bits & LE_R1_POK) != LE_R1_POK) {
+ dev->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
+ continue;
+ } else if (bits & LE_R1_ERR) {
+ /* Count only the end frame as a rx error,
+ * not the beginning
+ */
+ if (bits & LE_R1_BUF)
+ dev->stats.rx_fifo_errors++;
+ if (bits & LE_R1_CRC)
+ dev->stats.rx_crc_errors++;
+ if (bits & LE_R1_OFL)
+ dev->stats.rx_over_errors++;
+ if (bits & LE_R1_FRA)
+ dev->stats.rx_frame_errors++;
+ if (bits & LE_R1_EOP)
+ dev->stats.rx_errors++;
+ } else {
+ int len = (rd->mblength & 0xfff) - 4;
+ struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
+
+ if (!skb) {
+ dev->stats.rx_dropped++;
+ rd->mblength = 0;
+ rd->rmd1_bits = LE_R1_OWN;
+ lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
+ return 0;
+ }
+
+ skb_reserve(skb, 2); /* 16 byte align */
+ skb_put(skb, len); /* make room */
+ skb_copy_to_linear_data(skb,
+ (unsigned char *)&(ib->rx_buf[lp->rx_new][0]),
+ len);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
+ }
+
+ /* Return the packet to the pool */
+ rd->mblength = 0;
+ rd->rmd1_bits = LE_R1_OWN;
+ lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
+ }
+ return 0;
+}
+
+static int lance_tx(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ volatile struct lance_init_block *ib = lp->init_block;
+ volatile struct lance_tx_desc *td;
+ int i, j;
+ int status;
+
+#ifdef CONFIG_HP300
+ blinken_leds(0x80, 0);
+#endif
+ /* csr0 is 2f3 */
+ WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
+ /* csr0 is 73 */
+
+ j = lp->tx_old;
+ for (i = j; i != lp->tx_new; i = j) {
+ td = &ib->btx_ring[i];
+
+ /* If we hit a packet not owned by us, stop */
+ if (td->tmd1_bits & LE_T1_OWN)
+ break;
+
+ if (td->tmd1_bits & LE_T1_ERR) {
+ status = td->misc;
+
+ dev->stats.tx_errors++;
+ if (status & LE_T3_RTY)
+ dev->stats.tx_aborted_errors++;
+ if (status & LE_T3_LCOL)
+ dev->stats.tx_window_errors++;
+
+ if (status & LE_T3_CLOS) {
+ dev->stats.tx_carrier_errors++;
+ if (lp->auto_select) {
+ lp->tpe = 1 - lp->tpe;
+ printk("%s: Carrier Lost, trying %s\n",
+ dev->name,
+ lp->tpe ? "TPE" : "AUI");
+ /* Stop the lance */
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_STOP);
+ lance_init_ring(dev);
+ load_csrs(lp);
+ init_restart_lance(lp);
+ return 0;
+ }
+ }
+
+ /* buffer errors and underflows turn off the transmitter */
+ /* Restart the adapter */
+ if (status & (LE_T3_BUF|LE_T3_UFL)) {
+ dev->stats.tx_fifo_errors++;
+
+ printk("%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
+ dev->name);
+ /* Stop the lance */
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_STOP);
+ lance_init_ring(dev);
+ load_csrs(lp);
+ init_restart_lance(lp);
+ return 0;
+ }
+ } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
+ /*
+ * So we don't count the packet more than once.
+ */
+ td->tmd1_bits &= ~(LE_T1_POK);
+
+ /* One collision before packet was sent. */
+ if (td->tmd1_bits & LE_T1_EONE)
+ dev->stats.collisions++;
+
+ /* More than one collision, be optimistic. */
+ if (td->tmd1_bits & LE_T1_EMORE)
+ dev->stats.collisions += 2;
+
+ dev->stats.tx_packets++;
+ }
+
+ j = (j + 1) & lp->tx_ring_mod_mask;
+ }
+ lp->tx_old = j;
+ WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
+ return 0;
+}
+
+static irqreturn_t
+lance_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct lance_private *lp = netdev_priv(dev);
+ int csr0;
+
+ spin_lock(&lp->devlock);
+
+ WRITERAP(lp, LE_CSR0); /* LANCE Controller Status */
+ csr0 = READRDP(lp);
+
+ PRINT_RINGS();
+
+ if (!(csr0 & LE_C0_INTR)) { /* Check if any interrupt has */
+ spin_unlock(&lp->devlock);
+ return IRQ_NONE; /* been generated by the Lance. */
+ }
+
+ /* Acknowledge all the interrupt sources ASAP */
+ WRITERDP(lp, csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT|LE_C0_INIT));
+
+ if ((csr0 & LE_C0_ERR)) {
+ /* Clear the error condition */
+ WRITERDP(lp, LE_C0_BABL|LE_C0_ERR|LE_C0_MISS|LE_C0_INEA);
+ }
+
+ if (csr0 & LE_C0_RINT)
+ lance_rx(dev);
+
+ if (csr0 & LE_C0_TINT)
+ lance_tx(dev);
+
+ /* Log misc errors. */
+ if (csr0 & LE_C0_BABL)
+ dev->stats.tx_errors++; /* Tx babble. */
+ if (csr0 & LE_C0_MISS)
+ dev->stats.rx_errors++; /* Missed a Rx frame. */
+ if (csr0 & LE_C0_MERR) {
+ printk("%s: Bus master arbitration failure, status %4.4x.\n",
+ dev->name, csr0);
+ /* Restart the chip. */
+ WRITERDP(lp, LE_C0_STRT);
+ }
+
+ if (lp->tx_full && netif_queue_stopped(dev) && (TX_BUFFS_AVAIL >= 0)) {
+ lp->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR|LE_C0_IDON|LE_C0_INEA);
+
+ spin_unlock(&lp->devlock);
+ return IRQ_HANDLED;
+}
+
+int lance_open(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ int res;
+
+ /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
+ if (request_irq(lp->irq, lance_interrupt, IRQF_SHARED, lp->name, dev))
+ return -EAGAIN;
+
+ res = lance_reset(dev);
+ spin_lock_init(&lp->devlock);
+ netif_start_queue(dev);
+
+ return res;
+}
+EXPORT_SYMBOL_GPL(lance_open);
+
+int lance_close(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+
+ /* Stop the LANCE */
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_STOP);
+
+ free_irq(lp->irq, dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(lance_close);
+
+void lance_tx_timeout(struct net_device *dev)
+{
+ printk("lance_tx_timeout\n");
+ lance_reset(dev);
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ netif_wake_queue(dev);
+}
+EXPORT_SYMBOL_GPL(lance_tx_timeout);
+
+int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ volatile struct lance_init_block *ib = lp->init_block;
+ int entry, skblen, len;
+ static int outs;
+ unsigned long flags;
+
+ if (!TX_BUFFS_AVAIL)
+ return NETDEV_TX_LOCKED;
+
+ netif_stop_queue(dev);
+
+ skblen = skb->len;
+
+#ifdef DEBUG_DRIVER
+ /* dump the packet */
+ {
+ int i;
+
+ for (i = 0; i < 64; i++) {
+ if ((i % 16) == 0)
+ printk("\n");
+ printk("%2.2x ", skb->data[i]);
+ }
+ }
+#endif
+ len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
+ entry = lp->tx_new & lp->tx_ring_mod_mask;
+ ib->btx_ring[entry].length = (-len) | 0xf000;
+ ib->btx_ring[entry].misc = 0;
+
+ if (skb->len < ETH_ZLEN)
+ memset((void *)&ib->tx_buf[entry][0], 0, ETH_ZLEN);
+ skb_copy_from_linear_data(skb, (void *)&ib->tx_buf[entry][0], skblen);
+
+ /* Now, give the packet to the lance */
+ ib->btx_ring[entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
+ lp->tx_new = (lp->tx_new + 1) & lp->tx_ring_mod_mask;
+
+ outs++;
+ /* Kick the lance: transmit now */
+ WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD);
+ dev_consume_skb_any(skb);
+
+ spin_lock_irqsave(&lp->devlock, flags);
+ if (TX_BUFFS_AVAIL)
+ netif_start_queue(dev);
+ else
+ lp->tx_full = 1;
+ spin_unlock_irqrestore(&lp->devlock, flags);
+
+ return NETDEV_TX_OK;
+}
+EXPORT_SYMBOL_GPL(lance_start_xmit);
+
+/* taken from the depca driver via a2065.c */
+static void lance_load_multicast(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ volatile struct lance_init_block *ib = lp->init_block;
+ volatile u16 *mcast_table = (u16 *)&ib->filter;
+ struct netdev_hw_addr *ha;
+ u32 crc;
+
+ /* set all multicast bits */
+ if (dev->flags & IFF_ALLMULTI) {
+ ib->filter[0] = 0xffffffff;
+ ib->filter[1] = 0xffffffff;
+ return;
+ }
+ /* clear the multicast filter */
+ ib->filter[0] = 0;
+ ib->filter[1] = 0;
+
+ /* Add addresses */
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(6, ha->addr);
+ crc = crc >> 26;
+ mcast_table[crc >> 4] |= 1 << (crc & 0xf);
+ }
+}
+
+
+void lance_set_multicast(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+ volatile struct lance_init_block *ib = lp->init_block;
+ int stopped;
+
+ stopped = netif_queue_stopped(dev);
+ if (!stopped)
+ netif_stop_queue(dev);
+
+ while (lp->tx_old != lp->tx_new)
+ schedule();
+
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_STOP);
+ lance_init_ring(dev);
+
+ if (dev->flags & IFF_PROMISC) {
+ ib->mode |= LE_MO_PROM;
+ } else {
+ ib->mode &= ~LE_MO_PROM;
+ lance_load_multicast(dev);
+ }
+ load_csrs(lp);
+ init_restart_lance(lp);
+
+ if (!stopped)
+ netif_start_queue(dev);
+}
+EXPORT_SYMBOL_GPL(lance_set_multicast);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void lance_poll(struct net_device *dev)
+{
+ struct lance_private *lp = netdev_priv(dev);
+
+ spin_lock(&lp->devlock);
+ WRITERAP(lp, LE_CSR0);
+ WRITERDP(lp, LE_C0_STRT);
+ spin_unlock(&lp->devlock);
+ lance_interrupt(dev->irq, dev);
+}
+#endif
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/amd/7990.h b/drivers/net/ethernet/amd/7990.h
new file mode 100644
index 00000000000..e9e0be31380
--- /dev/null
+++ b/drivers/net/ethernet/amd/7990.h
@@ -0,0 +1,250 @@
+/*
+ * 7990.h -- LANCE ethernet IC generic routines.
+ * This is an attempt to separate out the bits of various ethernet
+ * drivers that are common because they all use the AMD 7990 LANCE
+ * (Local Area Network Controller for Ethernet) chip.
+ *
+ * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
+ *
+ * Most of this stuff was obtained by looking at other LANCE drivers,
+ * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
+ */
+
+#ifndef _7990_H
+#define _7990_H
+
+/* The lance only has two register locations. We communicate mostly via memory. */
+#define LANCE_RDP 0 /* Register Data Port */
+#define LANCE_RAP 2 /* Register Address Port */
+
+/* Transmit/receive ring definitions.
+ * We allow the specific drivers to override these defaults if they want to.
+ * NB: according to lance.c, increasing the number of buffers is a waste
+ * of space and reduces the chance that an upper layer will be able to
+ * reorder queued Tx packets based on priority. [Clearly there is a minimum
+ * limit too: too small and we drop rx packets and can't tx at full speed.]
+ * 4+4 seems to be the usual setting; the atarilance driver uses 3 and 5.
+ */
+
+/* Blast! This won't work. The problem is that we can't specify a default
+ * setting because that would cause the lance_init_block struct to be
+ * too long (and overflow the RAM on shared-memory cards like the HP LANCE.
+ */
+#ifndef LANCE_LOG_TX_BUFFERS
+#define LANCE_LOG_TX_BUFFERS 1
+#define LANCE_LOG_RX_BUFFERS 3
+#endif
+
+#define TX_RING_SIZE (1 << LANCE_LOG_TX_BUFFERS)
+#define RX_RING_SIZE (1 << LANCE_LOG_RX_BUFFERS)
+#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
+#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
+#define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
+#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
+#define PKT_BUFF_SIZE (1544)
+#define RX_BUFF_SIZE PKT_BUFF_SIZE
+#define TX_BUFF_SIZE PKT_BUFF_SIZE
+
+/* Each receive buffer is described by a receive message descriptor (RMD) */
+struct lance_rx_desc {
+ volatile unsigned short rmd0; /* low address of packet */
+ volatile unsigned char rmd1_bits; /* descriptor bits */
+ volatile unsigned char rmd1_hadr; /* high address of packet */
+ volatile short length; /* This length is 2s complement (negative)!
+ * Buffer length */
+ volatile unsigned short mblength; /* Actual number of bytes received */
+};
+
+/* Ditto for TMD: */
+struct lance_tx_desc {
+ volatile unsigned short tmd0; /* low address of packet */
+ volatile unsigned char tmd1_bits; /* descriptor bits */
+ volatile unsigned char tmd1_hadr; /* high address of packet */
+ volatile short length; /* Length is 2s complement (negative)! */
+ volatile unsigned short misc;
+};
+
+/* There are three memory structures accessed by the LANCE:
+ * the initialization block, the receive and transmit descriptor rings,
+ * and the data buffers themselves. In fact we might as well put the
+ * init block,the Tx and Rx rings and the buffers together in memory:
+ */
+struct lance_init_block {
+ volatile unsigned short mode; /* Pre-set mode (reg. 15) */
+ volatile unsigned char phys_addr[6]; /* Physical ethernet address */
+ volatile unsigned filter[2]; /* Multicast filter (64 bits) */
+
+ /* Receive and transmit ring base, along with extra bits. */
+ volatile unsigned short rx_ptr; /* receive descriptor addr */
+ volatile unsigned short rx_len; /* receive len and high addr */
+ volatile unsigned short tx_ptr; /* transmit descriptor addr */
+ volatile unsigned short tx_len; /* transmit len and high addr */
+
+ /* The Tx and Rx ring entries must be aligned on 8-byte boundaries.
+ * This will be true if this whole struct is 8-byte aligned.
+ */
+ volatile struct lance_tx_desc btx_ring[TX_RING_SIZE];
+ volatile struct lance_rx_desc brx_ring[RX_RING_SIZE];
+
+ volatile char tx_buf[TX_RING_SIZE][TX_BUFF_SIZE];
+ volatile char rx_buf[RX_RING_SIZE][RX_BUFF_SIZE];
+ /* we use this just to make the struct big enough that we can move its startaddr
+ * in order to force alignment to an eight byte boundary.
+ */
+};
+
+/* This is where we keep all the stuff the driver needs to know about.
+ * I'm definitely unhappy about the mechanism for allowing specific
+ * drivers to add things...
+ */
+struct lance_private {
+ const char *name;
+ unsigned long base;
+ volatile struct lance_init_block *init_block; /* CPU address of RAM */
+ volatile struct lance_init_block *lance_init_block; /* LANCE address of RAM */
+
+ int rx_new, tx_new;
+ int rx_old, tx_old;
+
+ int lance_log_rx_bufs, lance_log_tx_bufs;
+ int rx_ring_mod_mask, tx_ring_mod_mask;
+
+ int tpe; /* TPE is selected */
+ int auto_select; /* cable-selection is by carrier */
+ unsigned short busmaster_regval;
+
+ unsigned int irq; /* IRQ to register */
+
+ /* This is because the HP LANCE is disgusting and you have to check
+ * a DIO-specific register every time you read/write the LANCE regs :-<
+ * [could we get away with making these some sort of macro?]
+ */
+ void (*writerap)(void *, unsigned short);
+ void (*writerdp)(void *, unsigned short);
+ unsigned short (*readrdp)(void *);
+ spinlock_t devlock;
+ char tx_full;
+};
+
+/*
+ * Am7990 Control and Status Registers
+ */
+#define LE_CSR0 0x0000 /* LANCE Controller Status */
+#define LE_CSR1 0x0001 /* IADR[15:0] (bit0==0 ie word aligned) */
+#define LE_CSR2 0x0002 /* IADR[23:16] (high bits reserved) */
+#define LE_CSR3 0x0003 /* Misc */
+
+/*
+ * Bit definitions for CSR0 (LANCE Controller Status)
+ */
+#define LE_C0_ERR 0x8000 /* Error = BABL | CERR | MISS | MERR */
+#define LE_C0_BABL 0x4000 /* Babble: Transmitted too many bits */
+#define LE_C0_CERR 0x2000 /* No Heartbeat (10BASE-T) */
+#define LE_C0_MISS 0x1000 /* Missed Frame (no rx buffer to put it in) */
+#define LE_C0_MERR 0x0800 /* Memory Error */
+#define LE_C0_RINT 0x0400 /* Receive Interrupt */
+#define LE_C0_TINT 0x0200 /* Transmit Interrupt */
+#define LE_C0_IDON 0x0100 /* Initialization Done */
+#define LE_C0_INTR 0x0080 /* Interrupt Flag
+ = BABL | MISS | MERR | RINT | TINT | IDON */
+#define LE_C0_INEA 0x0040 /* Interrupt Enable */
+#define LE_C0_RXON 0x0020 /* Receive On */
+#define LE_C0_TXON 0x0010 /* Transmit On */
+#define LE_C0_TDMD 0x0008 /* Transmit Demand */
+#define LE_C0_STOP 0x0004 /* Stop */
+#define LE_C0_STRT 0x0002 /* Start */
+#define LE_C0_INIT 0x0001 /* Initialize */
+
+
+/*
+ * Bit definitions for CSR3
+ */
+#define LE_C3_BSWP 0x0004 /* Byte Swap (on for big endian byte order) */
+#define LE_C3_ACON 0x0002 /* ALE Control (on for active low ALE) */
+#define LE_C3_BCON 0x0001 /* Byte Control */
+
+
+/*
+ * Mode Flags
+ */
+#define LE_MO_PROM 0x8000 /* Promiscuous Mode */
+/* these next ones 0x4000 -- 0x0080 are not available on the LANCE 7990,
+ * but they are in NetBSD's am7990.h, presumably for backwards-compatible chips
+ */
+#define LE_MO_DRCVBC 0x4000 /* disable receive broadcast */
+#define LE_MO_DRCVPA 0x2000 /* disable physical address detection */
+#define LE_MO_DLNKTST 0x1000 /* disable link status */
+#define LE_MO_DAPC 0x0800 /* disable automatic polarity correction */
+#define LE_MO_MENDECL 0x0400 /* MENDEC loopback mode */
+#define LE_MO_LRTTSEL 0x0200 /* lower RX threshold / TX mode selection */
+#define LE_MO_PSEL1 0x0100 /* port selection bit1 */
+#define LE_MO_PSEL0 0x0080 /* port selection bit0 */
+/* and this one is from the C-LANCE data sheet... */
+#define LE_MO_EMBA 0x0080 /* Enable Modified Backoff Algorithm
+ (C-LANCE, not original LANCE) */
+#define LE_MO_INTL 0x0040 /* Internal Loopback */
+#define LE_MO_DRTY 0x0020 /* Disable Retry */
+#define LE_MO_FCOLL 0x0010 /* Force Collision */
+#define LE_MO_DXMTFCS 0x0008 /* Disable Transmit CRC */
+#define LE_MO_LOOP 0x0004 /* Loopback Enable */
+#define LE_MO_DTX 0x0002 /* Disable Transmitter */
+#define LE_MO_DRX 0x0001 /* Disable Receiver */
+
+
+/*
+ * Receive Flags
+ */
+#define LE_R1_OWN 0x80 /* LANCE owns the descriptor */
+#define LE_R1_ERR 0x40 /* Error */
+#define LE_R1_FRA 0x20 /* Framing Error */
+#define LE_R1_OFL 0x10 /* Overflow Error */
+#define LE_R1_CRC 0x08 /* CRC Error */
+#define LE_R1_BUF 0x04 /* Buffer Error */
+#define LE_R1_SOP 0x02 /* Start of Packet */
+#define LE_R1_EOP 0x01 /* End of Packet */
+#define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */
+
+
+/*
+ * Transmit Flags
+ */
+#define LE_T1_OWN 0x80 /* LANCE owns the descriptor */
+#define LE_T1_ERR 0x40 /* Error */
+#define LE_T1_RES 0x20 /* Reserved, LANCE writes this with a zero */
+#define LE_T1_EMORE 0x10 /* More than one retry needed */
+#define LE_T1_EONE 0x08 /* One retry needed */
+#define LE_T1_EDEF 0x04 /* Deferred */
+#define LE_T1_SOP 0x02 /* Start of Packet */
+#define LE_T1_EOP 0x01 /* End of Packet */
+#define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */
+
+/*
+ * Error Flags
+ */
+#define LE_T3_BUF 0x8000 /* Buffer Error */
+#define LE_T3_UFL 0x4000 /* Underflow Error */
+#define LE_T3_LCOL 0x1000 /* Late Collision */
+#define LE_T3_CLOS 0x0800 /* Loss of Carrier */
+#define LE_T3_RTY 0x0400 /* Retry Error */
+#define LE_T3_TDR 0x03ff /* Time Domain Reflectometry */
+
+/* Miscellaneous useful macros */
+
+#define TX_BUFFS_AVAIL ((lp->tx_old <= lp->tx_new) ? \
+ lp->tx_old + lp->tx_ring_mod_mask - lp->tx_new : \
+ lp->tx_old - lp->tx_new - 1)
+
+/* The LANCE only uses 24 bit addresses. This does the obvious thing. */
+#define LANCE_ADDR(x) ((int)(x) & ~0xff000000)
+
+/* Now the prototypes we export */
+int lance_open(struct net_device *dev);
+int lance_close(struct net_device *dev);
+int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
+void lance_set_multicast(struct net_device *dev);
+void lance_tx_timeout(struct net_device *dev);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void lance_poll(struct net_device *dev);
+#endif
+
+#endif /* ndef _7990_H */
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
new file mode 100644
index 00000000000..bbaf36d9f5e
--- /dev/null
+++ b/drivers/net/ethernet/amd/Kconfig
@@ -0,0 +1,192 @@
+#
+# AMD network device configuration
+#
+
+config NET_VENDOR_AMD
+ bool "AMD devices"
+ default y
+ depends on DIO || MACH_DECSTATION || MVME147 || ATARI || SUN3 || \
+ SUN3X || SBUS || PCI || ZORRO || (ISA && ISA_DMA_API) || \
+ (ARM && ARCH_EBSA110) || ISA || EISA || PCMCIA || ARM64
+ ---help---
+ If you have a network (Ethernet) chipset belonging to this class,
+ say Y.
+
+ Note that the answer to this question does not directly affect
+ the kernel: saying N will just case the configurator to skip all
+ the questions regarding AMD chipsets. If you say Y, you will be asked
+ for your specific chipset/driver in the following questions.
+
+if NET_VENDOR_AMD
+
+config A2065
+ tristate "A2065 support"
+ depends on ZORRO
+ select CRC32
+ ---help---
+ If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
+ say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called a2065.
+
+config AMD8111_ETH
+ tristate "AMD 8111 (new PCI LANCE) support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ If you have an AMD 8111-based PCI LANCE ethernet card,
+ answer Y here and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called amd8111e.
+
+config LANCE
+ tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
+ depends on ISA && ISA_DMA_API
+ ---help---
+ If you have a network (Ethernet) card of this type, say Y and read
+ the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are
+ of this type.
+
+ To compile this driver as a module, choose M here: the module
+ will be called lance. This is recommended.
+
+config PCNET32
+ tristate "AMD PCnet32 PCI support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
+ answer Y here and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called pcnet32.
+
+config ARIADNE
+ tristate "Ariadne support"
+ depends on ZORRO
+ ---help---
+ If you have a Village Tronic Ariadne Ethernet adapter, say Y.
+ Otherwise, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ariadne.
+
+config ARM_AM79C961A
+ bool "ARM EBSA110 AM79C961A support"
+ depends on ARM && ARCH_EBSA110
+ select CRC32
+ ---help---
+ If you wish to compile a kernel for the EBSA-110, then you should
+ always answer Y to this.
+
+config ATARILANCE
+ tristate "Atari LANCE support"
+ depends on ATARI
+ ---help---
+ Say Y to include support for several Atari Ethernet adapters based
+ on the AMD LANCE chipset: RieblCard (with or without battery), or
+ PAMCard VME (also the version by Rhotron, with different addresses).
+
+config DECLANCE
+ tristate "DEC LANCE ethernet controller support"
+ depends on MACH_DECSTATION
+ select CRC32
+ ---help---
+ This driver is for the series of Ethernet controllers produced by
+ DEC (now Compaq) based on the AMD LANCE chipset, including the
+ DEPCA series. (This chipset is better known via the NE2100 cards.)
+
+config HPLANCE
+ bool "HP on-board LANCE support"
+ depends on DIO
+ select CRC32
+ ---help---
+ If you want to use the builtin "LANCE" Ethernet controller on an
+ HP300 machine, say Y here.
+
+config MIPS_AU1X00_ENET
+ tristate "MIPS AU1000 Ethernet support"
+ depends on MIPS_ALCHEMY
+ select PHYLIB
+ select CRC32
+ ---help---
+ If you have an Alchemy Semi AU1X00 based system
+ say Y. Otherwise, say N.
+
+config MVME147_NET
+ tristate "MVME147 (LANCE) Ethernet support"
+ depends on MVME147
+ select CRC32
+ ---help---
+ Support for the on-board Ethernet interface on the Motorola MVME147
+ single-board computer. Say Y here to include the
+ driver for this chip in your kernel.
+ To compile this driver as a module, choose M here.
+
+config PCMCIA_NMCLAN
+ tristate "New Media PCMCIA support"
+ depends on PCMCIA
+ help
+ Say Y here if you intend to attach a New Media Ethernet or LiveWire
+ PCMCIA (PC-card) Ethernet card to your computer.
+
+ To compile this driver as a module, choose M here: the module will be
+ called nmclan_cs. If unsure, say N.
+
+config NI65
+ tristate "NI6510 support"
+ depends on ISA && ISA_DMA_API
+ ---help---
+ If you have a network (Ethernet) card of this type, say Y and read
+ the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called ni65.
+
+config SUN3LANCE
+ tristate "Sun3/Sun3x on-board LANCE support"
+ depends on (SUN3 || SUN3X)
+ ---help---
+ Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
+ featured an AMD LANCE 10Mbit Ethernet controller on board; say Y
+ here to compile in the Linux driver for this and enable Ethernet.
+ General Linux information on the Sun 3 and 3x series (now
+ discontinued) is at
+ <http://www.angelfire.com/ca2/tech68k/sun3.html>.
+
+ If you're not building a kernel for a Sun 3, say N.
+
+config SUNLANCE
+ tristate "Sun LANCE support"
+ depends on SBUS
+ select CRC32
+ ---help---
+ This driver supports the "le" interface present on all 32-bit Sparc
+ systems, on some older Ultra systems and as an Sbus option. These
+ cards are based on the AMD LANCE chipset, which is better known
+ via the NE2100 cards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called sunlance.
+
+config AMD_XGBE
+ tristate "AMD 10GbE Ethernet driver"
+ depends on OF_NET
+ select PHYLIB
+ select AMD_XGBE_PHY
+ ---help---
+ This driver supports the AMD 10GbE Ethernet device found on an
+ AMD SoC.
+
+ To compile this driver as a module, choose M here: the module
+ will be called amd-xgbe.
+
+endif # NET_VENDOR_AMD
diff --git a/drivers/net/ethernet/amd/Makefile b/drivers/net/ethernet/amd/Makefile
new file mode 100644
index 00000000000..a38a2dce3eb
--- /dev/null
+++ b/drivers/net/ethernet/amd/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for the AMD network device drivers.
+#
+
+obj-$(CONFIG_A2065) += a2065.o
+obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
+obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
+obj-$(CONFIG_ARIADNE) += ariadne.o
+obj-$(CONFIG_ATARILANCE) += atarilance.o
+obj-$(CONFIG_DECLANCE) += declance.o
+obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
+obj-$(CONFIG_LANCE) += lance.o
+obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
+obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
+obj-$(CONFIG_PCMCIA_NMCLAN) += nmclan_cs.o
+obj-$(CONFIG_NI65) += ni65.o
+obj-$(CONFIG_PCNET32) += pcnet32.o
+obj-$(CONFIG_SUN3LANCE) += sun3lance.o
+obj-$(CONFIG_SUNLANCE) += sunlance.o
+obj-$(CONFIG_AMD_XGBE) += xgbe/
diff --git a/drivers/net/a2065.c b/drivers/net/ethernet/amd/a2065.c
index 9c0837435b6..56139184b80 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/ethernet/amd/a2065.c
@@ -37,6 +37,11 @@
* both 10BASE-2 (thin coax) and AUI (DB-15) connectors
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+/*#define DEBUG*/
+/*#define TEST_HITS*/
+
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -46,42 +51,35 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/crc32.h>
#include <linux/zorro.h>
#include <linux/bitops.h>
+#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
#include "a2065.h"
-
- /*
- * Transmit/Receive Ring Definitions
- */
+/* Transmit/Receive Ring Definitions */
#define LANCE_LOG_TX_BUFFERS (2)
#define LANCE_LOG_RX_BUFFERS (4)
-#define TX_RING_SIZE (1<<LANCE_LOG_TX_BUFFERS)
-#define RX_RING_SIZE (1<<LANCE_LOG_RX_BUFFERS)
+#define TX_RING_SIZE (1 << LANCE_LOG_TX_BUFFERS)
+#define RX_RING_SIZE (1 << LANCE_LOG_RX_BUFFERS)
-#define TX_RING_MOD_MASK (TX_RING_SIZE-1)
-#define RX_RING_MOD_MASK (RX_RING_SIZE-1)
+#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
+#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
#define PKT_BUF_SIZE (1544)
#define RX_BUFF_SIZE PKT_BUF_SIZE
#define TX_BUFF_SIZE PKT_BUF_SIZE
-
- /*
- * Layout of the Lance's RAM Buffer
- */
-
+/* Layout of the Lance's RAM Buffer */
struct lance_init_block {
unsigned short mode; /* Pre-set mode (reg. 15) */
@@ -98,14 +96,11 @@ struct lance_init_block {
struct lance_rx_desc brx_ring[RX_RING_SIZE];
struct lance_tx_desc btx_ring[TX_RING_SIZE];
- char rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
- char tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
+ char rx_buf[RX_RING_SIZE][RX_BUFF_SIZE];
+ char tx_buf[TX_RING_SIZE][TX_BUFF_SIZE];
};
-
- /*
- * Private Device Data
- */
+/* Private Device Data */
struct lance_private {
char *name;
@@ -130,21 +125,14 @@ struct lance_private {
struct timer_list multicast_timer;
};
-#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
- lp->tx_old+lp->tx_ring_mod_mask-lp->tx_new:\
- lp->tx_old - lp->tx_new-1)
-
-
#define LANCE_ADDR(x) ((int)(x) & ~0xff000000)
/* Load the CSR registers */
-static void load_csrs (struct lance_private *lp)
+static void load_csrs(struct lance_private *lp)
{
volatile struct lance_regs *ll = lp->ll;
volatile struct lance_init_block *aib = lp->lance_init_block;
- int leptr;
-
- leptr = LANCE_ADDR (aib);
+ int leptr = LANCE_ADDR(aib);
ll->rap = LE_CSR1;
ll->rdp = (leptr & 0xFFFF);
@@ -157,19 +145,16 @@ static void load_csrs (struct lance_private *lp)
ll->rap = LE_CSR0;
}
-#define ZERO 0
-
/* Setup the Lance Rx and Tx rings */
-static void lance_init_ring (struct net_device *dev)
+static void lance_init_ring(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_init_block *ib = lp->init_block;
- volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */
+ volatile struct lance_init_block *aib = lp->lance_init_block;
+ /* for LANCE_ADDR computations */
int leptr;
int i;
- aib = lp->lance_init_block;
-
/* Lock out other processes while setting up hardware */
netif_stop_queue(dev);
lp->rx_new = lp->tx_new = 0;
@@ -180,41 +165,38 @@ static void lance_init_ring (struct net_device *dev)
/* Copy the ethernet address to the lance init block
* Note that on the sparc you need to swap the ethernet address.
*/
- ib->phys_addr [0] = dev->dev_addr [1];
- ib->phys_addr [1] = dev->dev_addr [0];
- ib->phys_addr [2] = dev->dev_addr [3];
- ib->phys_addr [3] = dev->dev_addr [2];
- ib->phys_addr [4] = dev->dev_addr [5];
- ib->phys_addr [5] = dev->dev_addr [4];
-
- if (ZERO)
- printk(KERN_DEBUG "TX rings:\n");
+ ib->phys_addr[0] = dev->dev_addr[1];
+ ib->phys_addr[1] = dev->dev_addr[0];
+ ib->phys_addr[2] = dev->dev_addr[3];
+ ib->phys_addr[3] = dev->dev_addr[2];
+ ib->phys_addr[4] = dev->dev_addr[5];
+ ib->phys_addr[5] = dev->dev_addr[4];
/* Setup the Tx ring entries */
- for (i = 0; i <= (1<<lp->lance_log_tx_bufs); i++) {
+ netdev_dbg(dev, "TX rings:\n");
+ for (i = 0; i <= 1 << lp->lance_log_tx_bufs; i++) {
leptr = LANCE_ADDR(&aib->tx_buf[i][0]);
- ib->btx_ring [i].tmd0 = leptr;
- ib->btx_ring [i].tmd1_hadr = leptr >> 16;
- ib->btx_ring [i].tmd1_bits = 0;
- ib->btx_ring [i].length = 0xf000; /* The ones required by tmd2 */
- ib->btx_ring [i].misc = 0;
- if (i < 3 && ZERO)
- printk(KERN_DEBUG "%d: 0x%8.8x\n", i, leptr);
+ ib->btx_ring[i].tmd0 = leptr;
+ ib->btx_ring[i].tmd1_hadr = leptr >> 16;
+ ib->btx_ring[i].tmd1_bits = 0;
+ ib->btx_ring[i].length = 0xf000; /* The ones required by tmd2 */
+ ib->btx_ring[i].misc = 0;
+ if (i < 3)
+ netdev_dbg(dev, "%d: 0x%08x\n", i, leptr);
}
/* Setup the Rx ring entries */
- if (ZERO)
- printk(KERN_DEBUG "RX rings:\n");
- for (i = 0; i < (1<<lp->lance_log_rx_bufs); i++) {
+ netdev_dbg(dev, "RX rings:\n");
+ for (i = 0; i < 1 << lp->lance_log_rx_bufs; i++) {
leptr = LANCE_ADDR(&aib->rx_buf[i][0]);
- ib->brx_ring [i].rmd0 = leptr;
- ib->brx_ring [i].rmd1_hadr = leptr >> 16;
- ib->brx_ring [i].rmd1_bits = LE_R1_OWN;
- ib->brx_ring [i].length = -RX_BUFF_SIZE | 0xf000;
- ib->brx_ring [i].mblength = 0;
- if (i < 3 && ZERO)
- printk(KERN_DEBUG "%d: 0x%8.8x\n", i, leptr);
+ ib->brx_ring[i].rmd0 = leptr;
+ ib->brx_ring[i].rmd1_hadr = leptr >> 16;
+ ib->brx_ring[i].rmd1_bits = LE_R1_OWN;
+ ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000;
+ ib->brx_ring[i].mblength = 0;
+ if (i < 3)
+ netdev_dbg(dev, "%d: 0x%08x\n", i, leptr);
}
/* Setup the initialization block */
@@ -223,22 +205,20 @@ static void lance_init_ring (struct net_device *dev)
leptr = LANCE_ADDR(&aib->brx_ring);
ib->rx_len = (lp->lance_log_rx_bufs << 13) | (leptr >> 16);
ib->rx_ptr = leptr;
- if (ZERO)
- printk(KERN_DEBUG "RX ptr: %8.8x\n", leptr);
+ netdev_dbg(dev, "RX ptr: %08x\n", leptr);
/* Setup tx descriptor pointer */
leptr = LANCE_ADDR(&aib->btx_ring);
ib->tx_len = (lp->lance_log_tx_bufs << 13) | (leptr >> 16);
ib->tx_ptr = leptr;
- if (ZERO)
- printk(KERN_DEBUG "TX ptr: %8.8x\n", leptr);
+ netdev_dbg(dev, "TX ptr: %08x\n", leptr);
/* Clear the multicast filter */
- ib->filter [0] = 0;
- ib->filter [1] = 0;
+ ib->filter[0] = 0;
+ ib->filter[1] = 0;
}
-static int init_restart_lance (struct lance_private *lp)
+static int init_restart_lance(struct lance_private *lp)
{
volatile struct lance_regs *ll = lp->ll;
int i;
@@ -250,8 +230,7 @@ static int init_restart_lance (struct lance_private *lp)
for (i = 0; (i < 100) && !(ll->rdp & (LE_C0_ERR | LE_C0_IDON)); i++)
barrier();
if ((i == 100) || (ll->rdp & LE_C0_ERR)) {
- printk(KERN_ERR "LANCE unopened after %d ticks, csr0=%4.4x.\n",
- i, ll->rdp);
+ pr_err("unopened after %d ticks, csr0=%04x\n", i, ll->rdp);
return -EIO;
}
@@ -262,7 +241,7 @@ static int init_restart_lance (struct lance_private *lp)
return 0;
}
-static int lance_rx (struct net_device *dev)
+static int lance_rx(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_init_block *ib = lp->init_block;
@@ -272,22 +251,24 @@ static int lance_rx (struct net_device *dev)
#ifdef TEST_HITS
int i;
- printk(KERN_DEBUG "[");
+ char buf[RX_RING_SIZE + 1];
+
for (i = 0; i < RX_RING_SIZE; i++) {
+ char r1_own = ib->brx_ring[i].rmd1_bits & LE_R1_OWN;
if (i == lp->rx_new)
- printk ("%s",
- ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "_" : "X");
+ buf[i] = r1_own ? '_' : 'X';
else
- printk ("%s",
- ib->brx_ring [i].rmd1_bits & LE_R1_OWN ? "." : "1");
+ buf[i] = r1_own ? '.' : '1';
}
- printk ("]\n");
+ buf[RX_RING_SIZE] = 0;
+
+ pr_debug("RxRing TestHits: [%s]\n", buf);
#endif
- ll->rdp = LE_C0_RINT|LE_C0_INEA;
- for (rd = &ib->brx_ring [lp->rx_new];
+ ll->rdp = LE_C0_RINT | LE_C0_INEA;
+ for (rd = &ib->brx_ring[lp->rx_new];
!((bits = rd->rmd1_bits) & LE_R1_OWN);
- rd = &ib->brx_ring [lp->rx_new]) {
+ rd = &ib->brx_ring[lp->rx_new]) {
/* We got an incomplete frame? */
if ((bits & LE_R1_POK) != LE_R1_POK) {
@@ -298,18 +279,21 @@ static int lance_rx (struct net_device *dev)
/* Count only the end frame as a rx error,
* not the beginning
*/
- if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++;
- if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++;
- if (bits & LE_R1_OFL) dev->stats.rx_over_errors++;
- if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
- if (bits & LE_R1_EOP) dev->stats.rx_errors++;
+ if (bits & LE_R1_BUF)
+ dev->stats.rx_fifo_errors++;
+ if (bits & LE_R1_CRC)
+ dev->stats.rx_crc_errors++;
+ if (bits & LE_R1_OFL)
+ dev->stats.rx_over_errors++;
+ if (bits & LE_R1_FRA)
+ dev->stats.rx_frame_errors++;
+ if (bits & LE_R1_EOP)
+ dev->stats.rx_errors++;
} else {
int len = (rd->mblength & 0xfff) - 4;
- struct sk_buff *skb = dev_alloc_skb (len+2);
+ struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
if (!skb) {
- printk(KERN_WARNING "%s: Memory squeeze, "
- "deferring packet.\n", dev->name);
dev->stats.rx_dropped++;
rd->mblength = 0;
rd->rmd1_bits = LE_R1_OWN;
@@ -317,14 +301,13 @@ static int lance_rx (struct net_device *dev)
return 0;
}
- skb_reserve (skb, 2); /* 16 byte align */
- skb_put (skb, len); /* make room */
+ skb_reserve(skb, 2); /* 16 byte align */
+ skb_put(skb, len); /* make room */
skb_copy_to_linear_data(skb,
- (unsigned char *)&(ib->rx_buf [lp->rx_new][0]),
- len);
- skb->protocol = eth_type_trans (skb, dev);
- netif_rx (skb);
- dev->last_rx = jiffies;
+ (unsigned char *)&ib->rx_buf[lp->rx_new][0],
+ len);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += len;
}
@@ -337,7 +320,7 @@ static int lance_rx (struct net_device *dev)
return 0;
}
-static int lance_tx (struct net_device *dev)
+static int lance_tx(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_init_block *ib = lp->init_block;
@@ -352,7 +335,7 @@ static int lance_tx (struct net_device *dev)
j = lp->tx_old;
for (i = j; i != lp->tx_new; i = j) {
- td = &ib->btx_ring [i];
+ td = &ib->btx_ring[i];
/* If we hit a packet not owned by us, stop */
if (td->tmd1_bits & LE_T1_OWN)
@@ -362,45 +345,44 @@ static int lance_tx (struct net_device *dev)
status = td->misc;
dev->stats.tx_errors++;
- if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++;
- if (status & LE_T3_LCOL) dev->stats.tx_window_errors++;
+ if (status & LE_T3_RTY)
+ dev->stats.tx_aborted_errors++;
+ if (status & LE_T3_LCOL)
+ dev->stats.tx_window_errors++;
if (status & LE_T3_CLOS) {
dev->stats.tx_carrier_errors++;
if (lp->auto_select) {
lp->tpe = 1 - lp->tpe;
- printk(KERN_ERR "%s: Carrier Lost, "
- "trying %s\n", dev->name,
- lp->tpe?"TPE":"AUI");
+ netdev_err(dev, "Carrier Lost, trying %s\n",
+ lp->tpe ? "TPE" : "AUI");
/* Stop the lance */
ll->rap = LE_CSR0;
ll->rdp = LE_C0_STOP;
- lance_init_ring (dev);
- load_csrs (lp);
- init_restart_lance (lp);
+ lance_init_ring(dev);
+ load_csrs(lp);
+ init_restart_lance(lp);
return 0;
}
}
- /* buffer errors and underflows turn off the transmitter */
- /* Restart the adapter */
- if (status & (LE_T3_BUF|LE_T3_UFL)) {
+ /* buffer errors and underflows turn off
+ * the transmitter, so restart the adapter
+ */
+ if (status & (LE_T3_BUF | LE_T3_UFL)) {
dev->stats.tx_fifo_errors++;
- printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, "
- "restarting\n", dev->name);
+ netdev_err(dev, "Tx: ERR_BUF|ERR_UFL, restarting\n");
/* Stop the lance */
ll->rap = LE_CSR0;
ll->rdp = LE_C0_STOP;
- lance_init_ring (dev);
- load_csrs (lp);
- init_restart_lance (lp);
+ lance_init_ring(dev);
+ load_csrs(lp);
+ init_restart_lance(lp);
return 0;
}
} else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
- /*
- * So we don't count the packet more than once.
- */
+ /* So we don't count the packet more than once. */
td->tmd1_bits &= ~(LE_T1_POK);
/* One collision before packet was sent. */
@@ -421,17 +403,19 @@ static int lance_tx (struct net_device *dev)
return 0;
}
-static irqreturn_t lance_interrupt (int irq, void *dev_id)
+static int lance_tx_buffs_avail(struct lance_private *lp)
{
- struct net_device *dev;
- struct lance_private *lp;
- volatile struct lance_regs *ll;
- int csr0;
-
- dev = (struct net_device *) dev_id;
+ if (lp->tx_old <= lp->tx_new)
+ return lp->tx_old + lp->tx_ring_mod_mask - lp->tx_new;
+ return lp->tx_old - lp->tx_new - 1;
+}
- lp = netdev_priv(dev);
- ll = lp->ll;
+static irqreturn_t lance_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct lance_private *lp = netdev_priv(dev);
+ volatile struct lance_regs *ll = lp->ll;
+ int csr0;
ll->rap = LE_CSR0; /* LANCE Controller Status */
csr0 = ll->rdp;
@@ -440,19 +424,19 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id)
return IRQ_NONE; /* been generated by the Lance. */
/* Acknowledge all the interrupt sources ASAP */
- ll->rdp = csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT|
+ ll->rdp = csr0 & ~(LE_C0_INEA | LE_C0_TDMD | LE_C0_STOP | LE_C0_STRT |
LE_C0_INIT);
- if ((csr0 & LE_C0_ERR)) {
+ if (csr0 & LE_C0_ERR) {
/* Clear the error condition */
- ll->rdp = LE_C0_BABL|LE_C0_ERR|LE_C0_MISS|LE_C0_INEA;
+ ll->rdp = LE_C0_BABL | LE_C0_ERR | LE_C0_MISS | LE_C0_INEA;
}
if (csr0 & LE_C0_RINT)
- lance_rx (dev);
+ lance_rx(dev);
if (csr0 & LE_C0_TINT)
- lance_tx (dev);
+ lance_tx(dev);
/* Log misc errors. */
if (csr0 & LE_C0_BABL)
@@ -460,22 +444,22 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id)
if (csr0 & LE_C0_MISS)
dev->stats.rx_errors++; /* Missed a Rx frame. */
if (csr0 & LE_C0_MERR) {
- printk(KERN_ERR "%s: Bus master arbitration failure, status "
- "%4.4x.\n", dev->name, csr0);
+ netdev_err(dev, "Bus master arbitration failure, status %04x\n",
+ csr0);
/* Restart the chip. */
ll->rdp = LE_C0_STRT;
}
- if (netif_queue_stopped(dev) && TX_BUFFS_AVAIL > 0)
+ if (netif_queue_stopped(dev) && lance_tx_buffs_avail(lp) > 0)
netif_wake_queue(dev);
ll->rap = LE_CSR0;
- ll->rdp = LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR|
- LE_C0_IDON|LE_C0_INEA;
+ ll->rdp = (LE_C0_BABL | LE_C0_CERR | LE_C0_MISS | LE_C0_MERR |
+ LE_C0_IDON | LE_C0_INEA);
return IRQ_HANDLED;
}
-static int lance_open (struct net_device *dev)
+static int lance_open(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
@@ -488,17 +472,18 @@ static int lance_open (struct net_device *dev)
/* Install the Interrupt handler */
ret = request_irq(IRQ_AMIGA_PORTS, lance_interrupt, IRQF_SHARED,
dev->name, dev);
- if (ret) return ret;
+ if (ret)
+ return ret;
- load_csrs (lp);
- lance_init_ring (dev);
+ load_csrs(lp);
+ lance_init_ring(dev);
netif_start_queue(dev);
- return init_restart_lance (lp);
+ return init_restart_lance(lp);
}
-static int lance_close (struct net_device *dev)
+static int lance_close(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
@@ -514,7 +499,7 @@ static int lance_close (struct net_device *dev)
return 0;
}
-static inline int lance_reset (struct net_device *dev)
+static inline int lance_reset(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
@@ -524,16 +509,15 @@ static inline int lance_reset (struct net_device *dev)
ll->rap = LE_CSR0;
ll->rdp = LE_C0_STOP;
- load_csrs (lp);
+ load_csrs(lp);
- lance_init_ring (dev);
- dev->trans_start = jiffies;
+ lance_init_ring(dev);
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_start_queue(dev);
- status = init_restart_lance (lp);
-#ifdef DEBUG_DRIVER
- printk(KERN_DEBUG "Lance restart=%d\n", status);
-#endif
+ status = init_restart_lance(lp);
+ netdev_dbg(dev, "Lance restart=%d\n", status);
+
return status;
}
@@ -542,72 +526,54 @@ static void lance_tx_timeout(struct net_device *dev)
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
- printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n",
- dev->name, ll->rdp);
+ netdev_err(dev, "transmit timed out, status %04x, reset\n", ll->rdp);
lance_reset(dev);
netif_wake_queue(dev);
}
-static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
volatile struct lance_init_block *ib = lp->init_block;
- int entry, skblen, len;
- int status = 0;
+ int entry, skblen;
+ int status = NETDEV_TX_OK;
unsigned long flags;
- skblen = skb->len;
- len = skblen;
-
- if (len < ETH_ZLEN) {
- len = ETH_ZLEN;
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- }
+ if (skb_padto(skb, ETH_ZLEN))
+ return NETDEV_TX_OK;
+ skblen = max_t(unsigned, skb->len, ETH_ZLEN);
local_irq_save(flags);
- if (!TX_BUFFS_AVAIL){
+ if (!lance_tx_buffs_avail(lp)) {
local_irq_restore(flags);
- return -1;
+ return NETDEV_TX_LOCKED;
}
-#ifdef DEBUG_DRIVER
+#ifdef DEBUG
/* dump the packet */
- {
- int i;
-
- for (i = 0; i < 64; i++) {
- if ((i % 16) == 0)
- printk("\n" KERN_DEBUG);
- printk ("%2.2x ", skb->data [i]);
- }
- printk("\n");
- }
+ print_hex_dump(KERN_DEBUG, "skb->data: ", DUMP_PREFIX_NONE,
+ 16, 1, skb->data, 64, true);
#endif
entry = lp->tx_new & lp->tx_ring_mod_mask;
- ib->btx_ring [entry].length = (-len) | 0xf000;
- ib->btx_ring [entry].misc = 0;
+ ib->btx_ring[entry].length = (-skblen) | 0xf000;
+ ib->btx_ring[entry].misc = 0;
- skb_copy_from_linear_data(skb, (void *)&ib->tx_buf [entry][0], skblen);
-
- /* Clear the slack of the packet, do I need this? */
- if (len != skblen)
- memset ((void *) &ib->tx_buf [entry][skblen], 0, len - skblen);
+ skb_copy_from_linear_data(skb, (void *)&ib->tx_buf[entry][0], skblen);
/* Now, give the packet to the lance */
- ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
+ ib->btx_ring[entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN);
lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;
dev->stats.tx_bytes += skblen;
- if (TX_BUFFS_AVAIL <= 0)
+ if (lance_tx_buffs_avail(lp) <= 0)
netif_stop_queue(dev);
/* Kick the lance: transmit now */
ll->rdp = LE_C0_INEA | LE_C0_TDMD;
- dev->trans_start = jiffies;
- dev_kfree_skb (skb);
+ dev_kfree_skb(skb);
local_irq_restore(flags);
@@ -615,43 +581,33 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
}
/* taken from the depca driver */
-static void lance_load_multicast (struct net_device *dev)
+static void lance_load_multicast(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_init_block *ib = lp->init_block;
volatile u16 *mcast_table = (u16 *)&ib->filter;
- struct dev_mc_list *dmi=dev->mc_list;
- char *addrs;
- int i;
+ struct netdev_hw_addr *ha;
u32 crc;
/* set all multicast bits */
- if (dev->flags & IFF_ALLMULTI){
- ib->filter [0] = 0xffffffff;
- ib->filter [1] = 0xffffffff;
+ if (dev->flags & IFF_ALLMULTI) {
+ ib->filter[0] = 0xffffffff;
+ ib->filter[1] = 0xffffffff;
return;
}
/* clear the multicast filter */
- ib->filter [0] = 0;
- ib->filter [1] = 0;
+ ib->filter[0] = 0;
+ ib->filter[1] = 0;
/* Add addresses */
- for (i = 0; i < dev->mc_count; i++){
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
-
- /* multicast address? */
- if (!(*addrs & 1))
- continue;
-
- crc = ether_crc_le(6, addrs);
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(6, ha->addr);
crc = crc >> 26;
- mcast_table [crc >> 4] |= 1 << (crc & 0xf);
+ mcast_table[crc >> 4] |= 1 << (crc & 0xf);
}
- return;
}
-static void lance_set_multicast (struct net_device *dev)
+static void lance_set_multicast(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_init_block *ib = lp->init_block;
@@ -670,51 +626,61 @@ static void lance_set_multicast (struct net_device *dev)
ll->rap = LE_CSR0;
ll->rdp = LE_C0_STOP;
- lance_init_ring (dev);
+ lance_init_ring(dev);
if (dev->flags & IFF_PROMISC) {
ib->mode |= LE_MO_PROM;
} else {
ib->mode &= ~LE_MO_PROM;
- lance_load_multicast (dev);
+ lance_load_multicast(dev);
}
- load_csrs (lp);
- init_restart_lance (lp);
+ load_csrs(lp);
+ init_restart_lance(lp);
netif_wake_queue(dev);
}
-static int __devinit a2065_init_one(struct zorro_dev *z,
- const struct zorro_device_id *ent);
-static void __devexit a2065_remove_one(struct zorro_dev *z);
+static int a2065_init_one(struct zorro_dev *z,
+ const struct zorro_device_id *ent);
+static void a2065_remove_one(struct zorro_dev *z);
-static struct zorro_device_id a2065_zorro_tbl[] __devinitdata = {
+static struct zorro_device_id a2065_zorro_tbl[] = {
{ ZORRO_PROD_CBM_A2065_1 },
{ ZORRO_PROD_CBM_A2065_2 },
{ ZORRO_PROD_AMERISTAR_A2065 },
{ 0 }
};
+MODULE_DEVICE_TABLE(zorro, a2065_zorro_tbl);
static struct zorro_driver a2065_driver = {
.name = "a2065",
.id_table = a2065_zorro_tbl,
.probe = a2065_init_one,
- .remove = __devexit_p(a2065_remove_one),
+ .remove = a2065_remove_one,
};
-static int __devinit a2065_init_one(struct zorro_dev *z,
- const struct zorro_device_id *ent)
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_set_rx_mode = lance_set_multicast,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
+static int a2065_init_one(struct zorro_dev *z,
+ const struct zorro_device_id *ent)
{
struct net_device *dev;
struct lance_private *priv;
- unsigned long board, base_addr, mem_start;
+ unsigned long board = z->resource.start;
+ unsigned long base_addr = board + A2065_LANCE;
+ unsigned long mem_start = board + A2065_RAM;
struct resource *r1, *r2;
+ u32 serial;
int err;
- DECLARE_MAC_BUF(mac);
-
- board = z->resource.start;
- base_addr = board+A2065_LANCE;
- mem_start = board+A2065_RAM;
r1 = request_mem_region(base_addr, sizeof(struct lance_regs),
"Am7990");
@@ -722,14 +688,14 @@ static int __devinit a2065_init_one(struct zorro_dev *z,
return -EBUSY;
r2 = request_mem_region(mem_start, A2065_RAM_SIZE, "RAM");
if (!r2) {
- release_resource(r1);
+ release_mem_region(base_addr, sizeof(struct lance_regs));
return -EBUSY;
}
dev = alloc_etherdev(sizeof(struct lance_private));
if (dev == NULL) {
- release_resource(r1);
- release_resource(r2);
+ release_mem_region(base_addr, sizeof(struct lance_regs));
+ release_mem_region(mem_start, A2065_RAM_SIZE);
return -ENOMEM;
}
@@ -738,6 +704,7 @@ static int __devinit a2065_init_one(struct zorro_dev *z,
r1->name = dev->name;
r2->name = dev->name;
+ serial = be32_to_cpu(z->rom.er_SerialNumber);
dev->dev_addr[0] = 0x00;
if (z->id != ZORRO_PROD_AMERISTAR_A2065) { /* Commodore */
dev->dev_addr[1] = 0x80;
@@ -746,12 +713,12 @@ static int __devinit a2065_init_one(struct zorro_dev *z,
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0x9f;
}
- dev->dev_addr[3] = (z->rom.er_SerialNumber>>16) & 0xff;
- dev->dev_addr[4] = (z->rom.er_SerialNumber>>8) & 0xff;
- dev->dev_addr[5] = z->rom.er_SerialNumber & 0xff;
- dev->base_addr = ZTWO_VADDR(base_addr);
- dev->mem_start = ZTWO_VADDR(mem_start);
- dev->mem_end = dev->mem_start+A2065_RAM_SIZE;
+ dev->dev_addr[3] = (serial >> 16) & 0xff;
+ dev->dev_addr[4] = (serial >> 8) & 0xff;
+ dev->dev_addr[5] = serial & 0xff;
+ dev->base_addr = (unsigned long)ZTWO_VADDR(base_addr);
+ dev->mem_start = (unsigned long)ZTWO_VADDR(mem_start);
+ dev->mem_end = dev->mem_start + A2065_RAM_SIZE;
priv->ll = (volatile struct lance_regs *)dev->base_addr;
priv->init_block = (struct lance_init_block *)dev->mem_start;
@@ -764,37 +731,32 @@ static int __devinit a2065_init_one(struct zorro_dev *z,
priv->rx_ring_mod_mask = RX_RING_MOD_MASK;
priv->tx_ring_mod_mask = TX_RING_MOD_MASK;
- dev->open = &lance_open;
- dev->stop = &lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->tx_timeout = &lance_tx_timeout;
+ dev->netdev_ops = &lance_netdev_ops;
dev->watchdog_timeo = 5*HZ;
- dev->set_multicast_list = &lance_set_multicast;
dev->dma = 0;
init_timer(&priv->multicast_timer);
priv->multicast_timer.data = (unsigned long) dev;
priv->multicast_timer.function =
- (void (*)(unsigned long)) &lance_set_multicast;
+ (void (*)(unsigned long))lance_set_multicast;
err = register_netdev(dev);
if (err) {
- release_resource(r1);
- release_resource(r2);
+ release_mem_region(base_addr, sizeof(struct lance_regs));
+ release_mem_region(mem_start, A2065_RAM_SIZE);
free_netdev(dev);
return err;
}
zorro_set_drvdata(z, dev);
- printk(KERN_INFO "%s: A2065 at 0x%08lx, Ethernet Address "
- "%s\n", dev->name, board,
- print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "A2065 at 0x%08lx, Ethernet Address %pM\n",
+ board, dev->dev_addr);
return 0;
}
-static void __devexit a2065_remove_one(struct zorro_dev *z)
+static void a2065_remove_one(struct zorro_dev *z)
{
struct net_device *dev = zorro_get_drvdata(z);
diff --git a/drivers/net/a2065.h b/drivers/net/ethernet/amd/a2065.h
index 5117759d4e9..5117759d4e9 100644
--- a/drivers/net/a2065.h
+++ b/drivers/net/ethernet/amd/a2065.h
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c
index aa4a5246be5..87e727b921d 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/ethernet/amd/am79c961a.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/net/am79c961.c
+ * linux/drivers/net/ethernet/amd/am79c961a.c
*
* by Russell King <rmk@arm.linux.org.uk> 1995-2001.
*
@@ -27,10 +27,9 @@
#include <linux/crc32.h>
#include <linux/bitops.h>
#include <linux/platform_device.h>
+#include <linux/io.h>
#include <mach/hardware.h>
-#include <asm/io.h>
-#include <asm/system.h>
#define TX_BUFFERS 15
#define RX_BUFFERS 25
@@ -50,7 +49,7 @@ static const char version[] =
#ifdef __arm__
static void write_rreg(u_long base, u_int reg, u_int val)
{
- __asm__(
+ asm volatile(
"str%?h %1, [%2] @ NET_RAP\n\t"
"str%?h %0, [%2, #-4] @ NET_RDP"
:
@@ -60,7 +59,7 @@ static void write_rreg(u_long base, u_int reg, u_int val)
static inline unsigned short read_rreg(u_long base_addr, u_int reg)
{
unsigned short v;
- __asm__(
+ asm volatile(
"str%?h %1, [%2] @ NET_RAP\n\t"
"ldr%?h %0, [%2, #-4] @ NET_RDP"
: "=r" (v)
@@ -70,7 +69,7 @@ static inline unsigned short read_rreg(u_long base_addr, u_int reg)
static inline void write_ireg(u_long base, u_int reg, u_int val)
{
- __asm__(
+ asm volatile(
"str%?h %1, [%2] @ NET_RAP\n\t"
"str%?h %0, [%2, #8] @ NET_IDP"
:
@@ -80,7 +79,7 @@ static inline void write_ireg(u_long base, u_int reg, u_int val)
static inline unsigned short read_ireg(u_long base_addr, u_int reg)
{
u_short v;
- __asm__(
+ asm volatile(
"str%?h %1, [%2] @ NAT_RAP\n\t"
"ldr%?h %0, [%2, #8] @ NET_IDP\n\t"
: "=r" (v)
@@ -91,47 +90,48 @@ static inline unsigned short read_ireg(u_long base_addr, u_int reg)
#define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
#define am_readword(dev,off) __raw_readw(ISAMEM_BASE + ((off) << 1))
-static inline void
+static void
am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
{
offset = ISAMEM_BASE + (offset << 1);
length = (length + 1) & ~1;
if ((int)buf & 2) {
- __asm__ __volatile__("str%?h %2, [%0], #4"
+ asm volatile("str%?h %2, [%0], #4"
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
buf += 2;
length -= 2;
}
while (length > 8) {
- unsigned int tmp, tmp2;
- __asm__ __volatile__(
- "ldm%?ia %1!, {%2, %3}\n\t"
+ register unsigned int tmp asm("r2"), tmp2 asm("r3");
+ asm volatile(
+ "ldm%?ia %0!, {%1, %2}"
+ : "+r" (buf), "=&r" (tmp), "=&r" (tmp2));
+ length -= 8;
+ asm volatile(
+ "str%?h %1, [%0], #4\n\t"
+ "mov%? %1, %1, lsr #16\n\t"
+ "str%?h %1, [%0], #4\n\t"
"str%?h %2, [%0], #4\n\t"
"mov%? %2, %2, lsr #16\n\t"
- "str%?h %2, [%0], #4\n\t"
- "str%?h %3, [%0], #4\n\t"
- "mov%? %3, %3, lsr #16\n\t"
- "str%?h %3, [%0], #4"
- : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
- : "0" (offset), "1" (buf));
- length -= 8;
+ "str%?h %2, [%0], #4"
+ : "+r" (offset), "=&r" (tmp), "=&r" (tmp2));
}
while (length > 0) {
- __asm__ __volatile__("str%?h %2, [%0], #4"
+ asm volatile("str%?h %2, [%0], #4"
: "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
buf += 2;
length -= 2;
}
}
-static inline void
+static void
am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
{
offset = ISAMEM_BASE + (offset << 1);
length = (length + 1) & ~1;
if ((int)buf & 2) {
unsigned int tmp;
- __asm__ __volatile__(
+ asm volatile(
"ldr%?h %2, [%0], #4\n\t"
"str%?b %2, [%1], #1\n\t"
"mov%? %2, %2, lsr #8\n\t"
@@ -140,12 +140,12 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned
length -= 2;
}
while (length > 8) {
- unsigned int tmp, tmp2, tmp3;
- __asm__ __volatile__(
+ register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3;
+ asm volatile(
"ldr%?h %2, [%0], #4\n\t"
+ "ldr%?h %4, [%0], #4\n\t"
"ldr%?h %3, [%0], #4\n\t"
- "orr%? %2, %2, %3, lsl #16\n\t"
- "ldr%?h %3, [%0], #4\n\t"
+ "orr%? %2, %2, %4, lsl #16\n\t"
"ldr%?h %4, [%0], #4\n\t"
"orr%? %3, %3, %4, lsl #16\n\t"
"stm%?ia %1!, {%2, %3}"
@@ -155,7 +155,7 @@ am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned
}
while (length > 0) {
unsigned int tmp;
- __asm__ __volatile__(
+ asm volatile(
"ldr%?h %2, [%0], #4\n\t"
"str%?b %2, [%1], #1\n\t"
"mov%? %2, %2, lsr #8\n\t"
@@ -196,6 +196,40 @@ am79c961_ramtest(struct net_device *dev, unsigned int val)
return errorcount;
}
+static void am79c961_mc_hash(char *addr, u16 *hash)
+{
+ int idx, bit;
+ u32 crc;
+
+ crc = ether_crc_le(ETH_ALEN, addr);
+
+ idx = crc >> 30;
+ bit = (crc >> 26) & 15;
+
+ hash[idx] |= 1 << bit;
+}
+
+static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash)
+{
+ unsigned int mode = MODE_PORT_10BT;
+
+ if (dev->flags & IFF_PROMISC) {
+ mode |= MODE_PROMISC;
+ memset(hash, 0xff, 4 * sizeof(*hash));
+ } else if (dev->flags & IFF_ALLMULTI) {
+ memset(hash, 0xff, 4 * sizeof(*hash));
+ } else {
+ struct netdev_hw_addr *ha;
+
+ memset(hash, 0, 4 * sizeof(*hash));
+
+ netdev_for_each_mc_addr(ha, dev)
+ am79c961_mc_hash(ha->addr, hash);
+ }
+
+ return mode;
+}
+
static void
am79c961_init_for_open(struct net_device *dev)
{
@@ -203,14 +237,15 @@ am79c961_init_for_open(struct net_device *dev)
unsigned long flags;
unsigned char *p;
u_int hdr_addr, first_free_addr;
+ u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
int i;
/*
* Stop the chip.
*/
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */
write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */
@@ -218,16 +253,12 @@ am79c961_init_for_open(struct net_device *dev)
write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */
for (i = LADRL; i <= LADRH; i++)
- write_rreg (dev->base_addr, i, 0);
+ write_rreg (dev->base_addr, i, multi_hash[i - LADRL]);
for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
- i = MODE_PORT_10BT;
- if (dev->flags & IFF_PROMISC)
- i |= MODE_PROMISC;
-
- write_rreg (dev->base_addr, MODE, i);
+ write_rreg (dev->base_addr, MODE, mode);
write_rreg (dev->base_addr, POLLINT, 0);
write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
@@ -276,8 +307,11 @@ static void am79c961_timer(unsigned long data)
struct net_device *dev = (struct net_device *)data;
struct dev_priv *priv = netdev_priv(dev);
unsigned int lnkstat, carrier;
+ unsigned long flags;
+ spin_lock_irqsave(&priv->chip_lock, flags);
lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
carrier = netif_carrier_ok(dev);
if (lnkstat && !carrier) {
@@ -300,8 +334,6 @@ am79c961_open(struct net_device *dev)
struct dev_priv *priv = netdev_priv(dev);
int ret;
- memset (&priv->stats, 0, sizeof (priv->stats));
-
ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev);
if (ret)
return ret;
@@ -332,10 +364,10 @@ am79c961_close(struct net_device *dev)
netif_stop_queue(dev);
netif_carrier_off(dev);
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_STOP);
write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
free_irq (dev->irq, dev);
@@ -343,55 +375,16 @@ am79c961_close(struct net_device *dev)
}
/*
- * Get the current statistics.
- */
-static struct net_device_stats *am79c961_getstats (struct net_device *dev)
-{
- struct dev_priv *priv = netdev_priv(dev);
- return &priv->stats;
-}
-
-static void am79c961_mc_hash(struct dev_mc_list *dmi, unsigned short *hash)
-{
- if (dmi->dmi_addrlen == ETH_ALEN && dmi->dmi_addr[0] & 0x01) {
- int idx, bit;
- u32 crc;
-
- crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
-
- idx = crc >> 30;
- bit = (crc >> 26) & 15;
-
- hash[idx] |= 1 << bit;
- }
-}
-
-/*
* Set or clear promiscuous/multicast mode filter for this adapter.
*/
static void am79c961_setmulticastlist (struct net_device *dev)
{
struct dev_priv *priv = netdev_priv(dev);
unsigned long flags;
- unsigned short multi_hash[4], mode;
+ u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
int i, stopped;
- mode = MODE_PORT_10BT;
-
- if (dev->flags & IFF_PROMISC) {
- mode |= MODE_PROMISC;
- } else if (dev->flags & IFF_ALLMULTI) {
- memset(multi_hash, 0xff, sizeof(multi_hash));
- } else {
- struct dev_mc_list *dmi;
-
- memset(multi_hash, 0x00, sizeof(multi_hash));
-
- for (dmi = dev->mc_list; dmi; dmi = dmi->next)
- am79c961_mc_hash(dmi, multi_hash);
- }
-
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
@@ -405,9 +398,9 @@ static void am79c961_setmulticastlist (struct net_device *dev)
* Spin waiting for chip to report suspend mode
*/
while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
nop();
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
}
}
@@ -429,7 +422,7 @@ static void am79c961_setmulticastlist (struct net_device *dev)
write_rreg(dev->base_addr, CTRL1, 0);
}
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
}
static void am79c961_timeout(struct net_device *dev)
@@ -467,10 +460,9 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
priv->txhead = head;
- spin_lock_irqsave(priv->chip_lock, flags);
+ spin_lock_irqsave(&priv->chip_lock, flags);
write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
- dev->trans_start = jiffies;
- spin_unlock_irqrestore(priv->chip_lock, flags);
+ spin_unlock_irqrestore(&priv->chip_lock, flags);
/*
* If the next packet is owned by the ethernet device,
@@ -480,9 +472,9 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)
netif_stop_queue(dev);
- dev_kfree_skb(skb);
+ dev_consume_skb_any(skb);
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -511,19 +503,19 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) {
am_writeword (dev, hdraddr + 2, RMD_OWN);
- priv->stats.rx_errors ++;
+ dev->stats.rx_errors++;
if (status & RMD_ERR) {
if (status & RMD_FRAM)
- priv->stats.rx_frame_errors ++;
+ dev->stats.rx_frame_errors++;
if (status & RMD_CRC)
- priv->stats.rx_crc_errors ++;
+ dev->stats.rx_crc_errors++;
} else if (status & RMD_STP)
- priv->stats.rx_length_errors ++;
+ dev->stats.rx_length_errors++;
continue;
}
len = am_readword(dev, hdraddr + 6);
- skb = dev_alloc_skb(len + 2);
+ skb = netdev_alloc_skb(dev, len + 2);
if (skb) {
skb_reserve(skb, 2);
@@ -532,13 +524,11 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
am_writeword(dev, hdraddr + 2, RMD_OWN);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
- priv->stats.rx_bytes += len;
- priv->stats.rx_packets ++;
+ dev->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
} else {
am_writeword (dev, hdraddr + 2, RMD_OWN);
- printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
- priv->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
break;
}
} while (1);
@@ -567,7 +557,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv)
if (status & TMD_ERR) {
u_int status2;
- priv->stats.tx_errors ++;
+ dev->stats.tx_errors++;
status2 = am_readword (dev, hdraddr + 6);
@@ -577,18 +567,18 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv)
am_writeword (dev, hdraddr + 6, 0);
if (status2 & TST_RTRY)
- priv->stats.collisions += 16;
+ dev->stats.collisions += 16;
if (status2 & TST_LCOL)
- priv->stats.tx_window_errors ++;
+ dev->stats.tx_window_errors++;
if (status2 & TST_LCAR)
- priv->stats.tx_carrier_errors ++;
+ dev->stats.tx_carrier_errors++;
if (status2 & TST_UFLO)
- priv->stats.tx_fifo_errors ++;
+ dev->stats.tx_fifo_errors++;
continue;
}
- priv->stats.tx_packets ++;
+ dev->stats.tx_packets++;
len = am_readword (dev, hdraddr + 4);
- priv->stats.tx_bytes += -len;
+ dev->stats.tx_bytes += -len;
} while (priv->txtail != priv->txhead);
netif_wake_queue(dev);
@@ -618,7 +608,7 @@ am79c961_interrupt(int irq, void *dev_id)
}
if (status & CSR0_MISS) {
handled = 1;
- priv->stats.rx_dropped ++;
+ dev->stats.rx_dropped++;
}
if (status & CSR0_CERR) {
handled = 1;
@@ -666,8 +656,21 @@ static void __init am79c961_banner(void)
if (net_debug && version_printed++ == 0)
printk(KERN_INFO "%s", version);
}
+static const struct net_device_ops am79c961_netdev_ops = {
+ .ndo_open = am79c961_open,
+ .ndo_stop = am79c961_close,
+ .ndo_start_xmit = am79c961_sendpacket,
+ .ndo_set_rx_mode = am79c961_setmulticastlist,
+ .ndo_tx_timeout = am79c961_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = am79c961_poll_controller,
+#endif
+};
-static int __init am79c961_probe(struct platform_device *pdev)
+static int am79c961_probe(struct platform_device *pdev)
{
struct resource *res;
struct net_device *dev;
@@ -733,22 +736,12 @@ static int __init am79c961_probe(struct platform_device *pdev)
if (am79c961_hw_init(dev))
goto release;
- dev->open = am79c961_open;
- dev->stop = am79c961_close;
- dev->hard_start_xmit = am79c961_sendpacket;
- dev->get_stats = am79c961_getstats;
- dev->set_multicast_list = am79c961_setmulticastlist;
- dev->tx_timeout = am79c961_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = am79c961_poll_controller;
-#endif
+ dev->netdev_ops = &am79c961_netdev_ops;
ret = register_netdev(dev);
if (ret == 0) {
- DECLARE_MAC_BUF(mac);
-
- printk(KERN_INFO "%s: ether address %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
+ printk(KERN_INFO "%s: ether address %pM\n",
+ dev->name, dev->dev_addr);
return 0;
}
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/ethernet/amd/am79c961a.h
index 483009fe6ec..9f384b79507 100644
--- a/drivers/net/arm/am79c961a.h
+++ b/drivers/net/ethernet/amd/am79c961a.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/net/arm/am79c961a.h
+ * linux/drivers/net/ethernet/amd/am79c961a.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -130,7 +130,6 @@
#define ISALED0_LNKST 0x8000
struct dev_priv {
- struct net_device_stats stats;
unsigned long rxbuffer[RX_BUFFERS];
unsigned long txbuffer[TX_BUFFERS];
unsigned char txhead;
diff --git a/drivers/net/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index c54967f7942..068dc7cad5f 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -24,9 +24,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
Module Name:
@@ -73,9 +71,8 @@ Revision History:
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/compiler.h>
-#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
@@ -88,7 +85,6 @@ Revision History:
#include <linux/crc32.h>
#include <linux/dma-mapping.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
@@ -107,13 +103,13 @@ MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "M
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
module_param_array(speed_duplex, int, NULL, 0);
-MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
+MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotiate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
module_param_array(coalesce, bool, NULL, 0);
MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0: Disable");
module_param_array(dynamic_ipg, bool, NULL, 0);
MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable");
-static struct pci_device_id amd8111e_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(amd8111e_pci_tbl) = {
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD8111E_7462,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -336,7 +332,8 @@ static int amd8111e_init_ring(struct net_device *dev)
/* Allocating receive skbs */
for (i = 0; i < NUM_RX_BUFFERS; i++) {
- if (!(lp->rx_skbuff[i] = dev_alloc_skb(lp->rx_buff_len))) {
+ lp->rx_skbuff[i] = netdev_alloc_skb(dev, lp->rx_buff_len);
+ if (!lp->rx_skbuff[i]) {
/* Release previos allocated skbs */
for(--i; i >= 0 ;i--)
dev_kfree_skb(lp->rx_skbuff[i]);
@@ -397,7 +394,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
event_count = coal_conf->rx_event_count;
if( timeout > MAX_TIMEOUT ||
event_count > MAX_EVENT_COUNT )
- return -EINVAL;
+ return -EINVAL;
timeout = timeout * DELAY_TIMER_CONV;
writel(VAL0|STINTEN, mmio+INTEN0);
@@ -410,7 +407,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod)
event_count = coal_conf->tx_event_count;
if( timeout > MAX_TIMEOUT ||
event_count > MAX_EVENT_COUNT )
- return -EINVAL;
+ return -EINVAL;
timeout = timeout * DELAY_TIMER_CONV;
@@ -499,7 +496,7 @@ static int amd8111e_restart(struct net_device *dev)
writel( VAL0 | APAD_XMT | REX_RTRY, mmio + CMD2 );
/* Setting the MAC address to the device */
- for(i = 0; i < ETH_ADDR_LEN; i++)
+ for (i = 0; i < ETH_ALEN; i++)
writeb( dev->dev_addr[i], mmio + PADR + i );
/* Enable interrupt coalesce */
@@ -644,10 +641,6 @@ This function frees the transmiter and receiver descriptor rings.
*/
static void amd8111e_free_ring(struct amd8111e_priv* lp)
{
-
- /* Free transmit and receive skbs */
- amd8111e_free_skbs(lp->amd8111e_net_dev);
-
/* Free transmit and receive descriptor rings */
if(lp->rx_ring){
pci_free_consistent(lp->pci_dev,
@@ -665,15 +658,6 @@ static void amd8111e_free_ring(struct amd8111e_priv* lp)
}
}
-#if AMD8111E_VLAN_TAG_USED
-/*
-This is the receive indication function for packets with vlan tag.
-*/
-static int amd8111e_vlan_rx(struct amd8111e_priv *lp, struct sk_buff *skb, u16 vlan_tag)
-{
- return vlan_hwaccel_receive_skb(skb, lp->vlgrp,vlan_tag);
-}
-#endif
/*
This function will free all the transmit skbs that are actually transmitted by the device. It will check the ownership of the skb before freeing the skb.
@@ -736,6 +720,9 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
int rx_pkt_limit = budget;
unsigned long flags;
+ if (rx_pkt_limit <= 0)
+ goto rx_not_empty;
+
do{
/* process receive packets until we use the quota*/
/* If we own the next entry, it's a new packet. Send it up. */
@@ -768,7 +755,7 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
#if AMD8111E_VLAN_TAG_USED
vtag = status & TT_MASK;
/*MAC will strip vlan tag*/
- if(lp->vlgrp != NULL && vtag !=0)
+ if (vtag != 0)
min_pkt_len =MIN_PKT_LEN - 4;
else
#endif
@@ -781,7 +768,8 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
}
if(--rx_pkt_limit < 0)
goto rx_not_empty;
- if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){
+ new_skb = netdev_alloc_skb(dev, lp->rx_buff_len);
+ if (!new_skb) {
/* if allocation fail,
ignore that pkt and go to next one */
lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
@@ -803,17 +791,16 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
skb->protocol = eth_type_trans(skb, dev);
#if AMD8111E_VLAN_TAG_USED
- if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){
- amd8111e_vlan_rx(lp, skb,
- le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info));
- } else
+ if (vtag == TT_VLAN_TAGGED){
+ u16 vlan_tag = le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info);
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
+ }
#endif
- netif_receive_skb(skb);
+ netif_receive_skb(skb);
/*COAL update rx coalescing parameters*/
lp->coal_conf.rx_packets++;
lp->coal_conf.rx_bytes += pkt_len;
num_rx_pkt++;
- dev->last_rx = jiffies;
err_next_pkt:
lp->rx_ring[rx_index].buff_phy_addr
@@ -833,12 +820,14 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
} while(intr0 & RINT0);
- /* Receive descriptor is empty now */
- spin_lock_irqsave(&lp->lock, flags);
- __netif_rx_complete(dev, napi);
- writel(VAL0|RINTEN0, mmio + INTEN0);
- writel(VAL2 | RDMD0, mmio + CMD0);
- spin_unlock_irqrestore(&lp->lock, flags);
+ if (rx_pkt_limit > 0) {
+ /* Receive descriptor is empty now */
+ spin_lock_irqsave(&lp->lock, flags);
+ __napi_complete(napi);
+ writel(VAL0|RINTEN0, mmio + INTEN0);
+ writel(VAL2 | RDMD0, mmio + CMD0);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ }
rx_not_empty:
return num_rx_pkt;
@@ -907,18 +896,18 @@ static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER)
}
/*
-This function reads the mib registers and returns the hardware statistics. It updates previous internal driver statistics with new values.
-*/
-static struct net_device_stats *amd8111e_get_stats(struct net_device * dev)
+ * This function reads the mib registers and returns the hardware statistics.
+ * It updates previous internal driver statistics with new values.
+ */
+static struct net_device_stats *amd8111e_get_stats(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
void __iomem *mmio = lp->mmio;
unsigned long flags;
- /* struct net_device_stats *prev_stats = &lp->prev_stats; */
- struct net_device_stats* new_stats = &lp->stats;
+ struct net_device_stats *new_stats = &dev->stats;
- if(!lp->opened)
- return &lp->stats;
+ if (!lp->opened)
+ return new_stats;
spin_lock_irqsave (&lp->lock, flags);
/* stats.rx_packets */
@@ -1173,14 +1162,13 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
/* Check if Receive Interrupt has occurred. */
if (intr0 & RINT0) {
- if (netif_rx_schedule_prep(dev, &lp->napi)) {
+ if (napi_schedule_prep(&lp->napi)) {
/* Disable receive interupts */
writel(RINTEN0, mmio + INTEN0);
/* Schedule a polling routine */
- __netif_rx_schedule(dev, &lp->napi);
+ __napi_schedule(&lp->napi);
} else if (intren0 & RINTEN0) {
- printk("************Driver bug! \
- interrupt while in poll\n");
+ printk("************Driver bug! interrupt while in poll\n");
/* Fix by disable receive interrupts */
writel(RINTEN0, mmio + INTEN0);
}
@@ -1231,7 +1219,9 @@ static int amd8111e_close(struct net_device * dev)
amd8111e_disable_interrupt(lp);
amd8111e_stop_chip(lp);
- amd8111e_free_ring(lp);
+
+ /* Free transmit and receive skbs */
+ amd8111e_free_skbs(lp->amd8111e_net_dev);
netif_carrier_off(lp->amd8111e_net_dev);
@@ -1241,6 +1231,7 @@ static int amd8111e_close(struct net_device * dev)
spin_unlock_irq(&lp->lock);
free_irq(dev->irq, dev);
+ amd8111e_free_ring(lp);
/* Update the statistics before closing */
amd8111e_get_stats(dev);
@@ -1300,7 +1291,8 @@ static int amd8111e_tx_queue_avail(struct amd8111e_priv* lp )
This function will queue the transmit packets to the descriptors and will trigger the send operation. It also initializes the transmit descriptors with buffer physical address, byte count, ownership to hardware etc.
*/
-static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev)
+static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
+ struct net_device * dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
int tx_index;
@@ -1316,7 +1308,7 @@ static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev)
lp->tx_ring[tx_index].tx_flags = 0;
#if AMD8111E_VLAN_TAG_USED
- if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){
+ if (vlan_tx_tag_present(skb)) {
lp->tx_ring[tx_index].tag_ctrl_cmd |=
cpu_to_le16(TCC_VLAN_INSERT);
lp->tx_ring[tx_index].tag_ctrl_info =
@@ -1340,13 +1332,11 @@ static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev)
writel( VAL1 | TDMD0, lp->mmio + CMD0);
writel( VAL2 | RDMD0,lp->mmio + CMD0);
- dev->trans_start = jiffies;
-
if(amd8111e_tx_queue_avail(lp) < 0){
netif_stop_queue(dev);
}
spin_unlock_irqrestore(&lp->lock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/*
This function returns all the memory mapped registers of the device.
@@ -1377,41 +1367,39 @@ list to the device.
*/
static void amd8111e_set_multicast_list(struct net_device *dev)
{
- struct dev_mc_list* mc_ptr;
+ struct netdev_hw_addr *ha;
struct amd8111e_priv *lp = netdev_priv(dev);
u32 mc_filter[2] ;
- int i,bit_num;
+ int bit_num;
+
if(dev->flags & IFF_PROMISC){
writel( VAL2 | PROM, lp->mmio + CMD2);
return;
}
else
writel( PROM, lp->mmio + CMD2);
- if(dev->flags & IFF_ALLMULTI || dev->mc_count > MAX_FILTER_SIZE){
+ if (dev->flags & IFF_ALLMULTI ||
+ netdev_mc_count(dev) > MAX_FILTER_SIZE) {
/* get all multicast packet */
mc_filter[1] = mc_filter[0] = 0xffffffff;
- lp->mc_list = dev->mc_list;
lp->options |= OPTION_MULTICAST_ENABLE;
amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF);
return;
}
- if( dev->mc_count == 0 ){
+ if (netdev_mc_empty(dev)) {
/* get only own packets */
mc_filter[1] = mc_filter[0] = 0;
- lp->mc_list = NULL;
lp->options &= ~OPTION_MULTICAST_ENABLE;
amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF);
- /* disable promiscous mode */
+ /* disable promiscuous mode */
writel(PROM, lp->mmio + CMD2);
return;
}
/* load all the multicast addresses in the logic filter */
lp->options |= OPTION_MULTICAST_ENABLE;
- lp->mc_list = dev->mc_list;
mc_filter[1] = mc_filter[0] = 0;
- for (i = 0, mc_ptr = dev->mc_list; mc_ptr && i < dev->mc_count;
- i++, mc_ptr = mc_ptr->next) {
- bit_num = (ether_crc_le(ETH_ALEN, mc_ptr->dmi_addr) >> 26) & 0x3f;
+ netdev_for_each_mc_addr(ha, dev) {
+ bit_num = (ether_crc_le(ETH_ALEN, ha->addr) >> 26) & 0x3f;
mc_filter[bit_num >> 5] |= 1 << (bit_num & 31);
}
amd8111e_writeq(*(u64*)mc_filter,lp->mmio+ LADRF);
@@ -1425,10 +1413,11 @@ static void amd8111e_get_drvinfo(struct net_device* dev, struct ethtool_drvinfo
{
struct amd8111e_priv *lp = netdev_priv(dev);
struct pci_dev *pci_dev = lp->pci_dev;
- strcpy (info->driver, MODULE_NAME);
- strcpy (info->version, MODULE_VERS);
- sprintf(info->fw_version,"%u",chip_version);
- strcpy (info->bus_info, pci_name(pci_dev));
+ strlcpy(info->driver, MODULE_NAME, sizeof(info->driver));
+ strlcpy(info->version, MODULE_VERS, sizeof(info->version));
+ snprintf(info->fw_version, sizeof(info->fw_version),
+ "%u", chip_version);
+ strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info));
}
static int amd8111e_get_regs_len(struct net_device *dev)
@@ -1523,9 +1512,6 @@ static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd)
int err;
u32 mii_regval;
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
switch(cmd) {
case SIOCGMIIPHY:
data->phy_id = lp->ext_phy_addr;
@@ -1565,7 +1551,7 @@ static int amd8111e_set_mac_address(struct net_device *dev, void *p)
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
spin_lock_irq(&lp->lock);
/* Setting the MAC address to the device */
- for(i = 0; i < ETH_ADDR_LEN; i++)
+ for (i = 0; i < ETH_ALEN; i++)
writeb( dev->dev_addr[i], lp->mmio + PADR + i );
spin_unlock_irq(&lp->lock);
@@ -1605,16 +1591,6 @@ static int amd8111e_change_mtu(struct net_device *dev, int new_mtu)
return err;
}
-#if AMD8111E_VLAN_TAG_USED
-static void amd8111e_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
- struct amd8111e_priv *lp = netdev_priv(dev);
- spin_lock_irq(&lp->lock);
- lp->vlgrp = grp;
- spin_unlock_irq(&lp->lock);
-}
-#endif
-
static int amd8111e_enable_magicpkt(struct amd8111e_priv* lp)
{
writel( VAL1|MPPLBA, lp->mmio + CMD3);
@@ -1635,8 +1611,13 @@ static int amd8111e_enable_link_change(struct amd8111e_priv* lp)
readl(lp->mmio + CMD7);
return 0;
}
-/* This function is called when a packet transmission fails to complete within a resonable period, on the assumption that an interrupts have been failed or the interface is locked up. This function will reinitialize the hardware */
+/*
+ * This function is called when a packet transmission fails to complete
+ * within a reasonable period, on the assumption that an interrupt have
+ * failed or the interface is locked up. This function will reinitialize
+ * the hardware.
+ */
static void amd8111e_tx_timeout(struct net_device *dev)
{
struct amd8111e_priv* lp = netdev_priv(dev);
@@ -1721,7 +1702,7 @@ static int amd8111e_resume(struct pci_dev *pci_dev)
}
-static void __devexit amd8111e_remove_one(struct pci_dev *pdev)
+static void amd8111e_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
if (dev) {
@@ -1730,7 +1711,6 @@ static void __devexit amd8111e_remove_one(struct pci_dev *pdev)
free_netdev(dev);
pci_release_regions(pdev);
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
}
}
static void amd8111e_config_ipg(struct net_device* dev)
@@ -1793,7 +1773,7 @@ static void amd8111e_config_ipg(struct net_device* dev)
}
-static void __devinit amd8111e_probe_ext_phy(struct net_device* dev)
+static void amd8111e_probe_ext_phy(struct net_device *dev)
{
struct amd8111e_priv *lp = netdev_priv(dev);
int i;
@@ -1813,14 +1793,29 @@ static void __devinit amd8111e_probe_ext_phy(struct net_device* dev)
lp->ext_phy_addr = 1;
}
-static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
+static const struct net_device_ops amd8111e_netdev_ops = {
+ .ndo_open = amd8111e_open,
+ .ndo_stop = amd8111e_close,
+ .ndo_start_xmit = amd8111e_start_xmit,
+ .ndo_tx_timeout = amd8111e_tx_timeout,
+ .ndo_get_stats = amd8111e_get_stats,
+ .ndo_set_rx_mode = amd8111e_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = amd8111e_set_mac_address,
+ .ndo_do_ioctl = amd8111e_ioctl,
+ .ndo_change_mtu = amd8111e_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = amd8111e_poll,
+#endif
+};
+
+static int amd8111e_probe_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- int err,i,pm_cap;
+ int err, i;
unsigned long reg_addr,reg_len;
struct amd8111e_priv* lp;
struct net_device* dev;
- DECLARE_MAC_BUF(mac);
err = pci_enable_device(pdev);
if(err){
@@ -1846,16 +1841,18 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
pci_set_master(pdev);
/* Find power-management capability. */
- if((pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM))==0){
+ if (!pdev->pm_cap) {
printk(KERN_ERR "amd8111e: No Power Management capability, "
"exiting.\n");
+ err = -ENODEV;
goto err_free_reg;
}
/* Initialize DMA */
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
printk(KERN_ERR "amd8111e: DMA not supported,"
"exiting.\n");
+ err = -ENODEV;
goto err_free_reg;
}
@@ -1864,7 +1861,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
dev = alloc_etherdev(sizeof(struct amd8111e_priv));
if (!dev) {
- printk(KERN_ERR "amd8111e: Etherdev alloc failed, exiting.\n");
err = -ENOMEM;
goto err_free_reg;
}
@@ -1872,14 +1868,13 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
SET_NETDEV_DEV(dev, &pdev->dev);
#if AMD8111E_VLAN_TAG_USED
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX ;
- dev->vlan_rx_register =amd8111e_vlan_rx_register;
+ dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX ;
#endif
lp = netdev_priv(dev);
lp->pci_dev = pdev;
lp->amd8111e_net_dev = dev;
- lp->pm_cap = pm_cap;
+ lp->pm_cap = pdev->pm_cap;
spin_lock_init(&lp->lock);
@@ -1892,7 +1887,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
}
/* Initializing MAC address */
- for(i = 0; i < ETH_ADDR_LEN; i++)
+ for (i = 0; i < ETH_ALEN; i++)
dev->dev_addr[i] = readb(lp->mmio + PADR + i);
/* Setting user defined parametrs */
@@ -1902,27 +1897,16 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
if(dynamic_ipg[card_idx++])
lp->options |= OPTION_DYN_IPG_ENABLE;
+
/* Initialize driver entry points */
- dev->open = amd8111e_open;
- dev->hard_start_xmit = amd8111e_start_xmit;
- dev->stop = amd8111e_close;
- dev->get_stats = amd8111e_get_stats;
- dev->set_multicast_list = amd8111e_set_multicast_list;
- dev->set_mac_address = amd8111e_set_mac_address;
- dev->do_ioctl = amd8111e_ioctl;
- dev->change_mtu = amd8111e_change_mtu;
- SET_ETHTOOL_OPS(dev, &ops);
+ dev->netdev_ops = &amd8111e_netdev_ops;
+ dev->ethtool_ops = &ops;
dev->irq =pdev->irq;
- dev->tx_timeout = amd8111e_tx_timeout;
dev->watchdog_timeo = AMD8111E_TX_TIMEOUT;
netif_napi_add(dev, &lp->napi, amd8111e_rx_poll, 32);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = amd8111e_poll;
-#endif
#if AMD8111E_VLAN_TAG_USED
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->vlan_rx_register =amd8111e_vlan_rx_register;
+ dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
#endif
/* Probe the external PHY */
amd8111e_probe_ext_phy(dev);
@@ -1955,15 +1939,15 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
IPG_CONVERGE_JIFFIES;
lp->ipg_data.ipg = DEFAULT_IPG;
lp->ipg_data.ipg_state = CSTATE;
- };
+ }
/* display driver and device information */
chip_version = (readl(lp->mmio + CHIPID) & 0xf0000000)>>28;
printk(KERN_INFO "%s: AMD-8111e Driver Version: %s\n",
dev->name,MODULE_VERS);
- printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %s\n",
- dev->name, chip_version, print_mac(mac, dev->dev_addr));
+ printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %pM\n",
+ dev->name, chip_version, dev->dev_addr);
if (lp->ext_phy_id)
printk(KERN_INFO "%s: Found MII PHY ID 0x%08x at address 0x%02x\n",
dev->name, lp->ext_phy_id, lp->ext_phy_addr);
@@ -1982,7 +1966,6 @@ err_free_reg:
err_disable_pdev:
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
return err;
}
@@ -1991,20 +1974,9 @@ static struct pci_driver amd8111e_driver = {
.name = MODULE_NAME,
.id_table = amd8111e_pci_tbl,
.probe = amd8111e_probe_one,
- .remove = __devexit_p(amd8111e_remove_one),
+ .remove = amd8111e_remove_one,
.suspend = amd8111e_suspend,
.resume = amd8111e_resume
};
-static int __init amd8111e_init(void)
-{
- return pci_register_driver(&amd8111e_driver);
-}
-
-static void __exit amd8111e_cleanup(void)
-{
- pci_unregister_driver(&amd8111e_driver);
-}
-
-module_init(amd8111e_init);
-module_exit(amd8111e_cleanup);
+module_pci_driver(amd8111e_driver);
diff --git a/drivers/net/amd8111e.h b/drivers/net/ethernet/amd/amd8111e.h
index 28c60a71ed5..a75092d584c 100644
--- a/drivers/net/amd8111e.h
+++ b/drivers/net/ethernet/amd/amd8111e.h
@@ -13,9 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
Module Name:
@@ -586,7 +584,6 @@ typedef enum {
#define PKT_BUFF_SZ 1536
#define MIN_PKT_LEN 60
-#define ETH_ADDR_LEN 6
#define AMD8111E_TX_TIMEOUT (3 * HZ)/* 3 sec */
#define SOFT_TIMER_FREQ 0xBEBC /* 0.5 sec */
@@ -754,7 +751,7 @@ struct amd8111e_priv{
const char *name;
struct pci_dev *pci_dev; /* Ptr to the associated pci_dev */
struct net_device* amd8111e_net_dev; /* ptr to associated net_device */
- /* Transmit and recive skbs */
+ /* Transmit and receive skbs */
struct sk_buff *tx_skbuff[NUM_TX_BUFFERS];
struct sk_buff *rx_skbuff[NUM_RX_BUFFERS];
/* Transmit and receive dma mapped addr */
@@ -783,13 +780,8 @@ struct amd8111e_priv{
struct net_device *next;
int mii;
struct mii_if_info mii_if;
-#if AMD8111E_VLAN_TAG_USED
- struct vlan_group *vlgrp;
-#endif
char opened;
- struct net_device_stats stats;
unsigned int drv_rx_errors;
- struct dev_mc_list* mc_list;
struct amd8111e_coalesce_conf coal_conf;
struct ipg_info ipg_data;
@@ -813,8 +805,8 @@ typedef enum {
static int card_idx;
static int speed_duplex[MAX_UNITS] = { 0, };
-static int coalesce[MAX_UNITS] = {1,1,1,1,1,1,1,1};
-static int dynamic_ipg[MAX_UNITS] = {0,0,0,0,0,0,0,0};
+static bool coalesce[MAX_UNITS] = { [ 0 ... MAX_UNITS-1] = true };
+static bool dynamic_ipg[MAX_UNITS] = { [ 0 ... MAX_UNITS-1] = false };
static unsigned int chip_version;
#endif /* _AMD8111E_H */
diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c
new file mode 100644
index 00000000000..968b7bfac8f
--- /dev/null
+++ b/drivers/net/ethernet/amd/ariadne.c
@@ -0,0 +1,792 @@
+/*
+ * Amiga Linux/m68k Ariadne Ethernet Driver
+ *
+ * © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
+ * Peter De Schrijver (p2@mind.be)
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This program is based on
+ *
+ * lance.c: An AMD LANCE ethernet driver for linux.
+ * Written 1993-94 by Donald Becker.
+ *
+ * Am79C960: PCnet(tm)-ISA Single-Chip Ethernet Controller
+ * Advanced Micro Devices
+ * Publication #16907, Rev. B, Amendment/0, May 1994
+ *
+ * MC68230: Parallel Interface/Timer (PI/T)
+ * Motorola Semiconductors, December, 1983
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * The Ariadne is a Zorro-II board made by Village Tronic. It contains:
+ *
+ * - an Am79C960 PCnet-ISA Single-Chip Ethernet Controller with both
+ * 10BASE-2 (thin coax) and 10BASE-T (UTP) connectors
+ *
+ * - an MC68230 Parallel Interface/Timer configured as 2 parallel ports
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+/*#define DEBUG*/
+
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/zorro.h>
+#include <linux/bitops.h>
+
+#include <asm/byteorder.h>
+#include <asm/amigaints.h>
+#include <asm/amigahw.h>
+#include <asm/irq.h>
+
+#include "ariadne.h"
+
+#ifdef ARIADNE_DEBUG
+int ariadne_debug = ARIADNE_DEBUG;
+#else
+int ariadne_debug = 1;
+#endif
+
+/* Macros to Fix Endianness problems */
+
+/* Swap the Bytes in a WORD */
+#define swapw(x) (((x >> 8) & 0x00ff) | ((x << 8) & 0xff00))
+/* Get the Low BYTE in a WORD */
+#define lowb(x) (x & 0xff)
+/* Get the Swapped High WORD in a LONG */
+#define swhighw(x) ((((x) >> 8) & 0xff00) | (((x) >> 24) & 0x00ff))
+/* Get the Swapped Low WORD in a LONG */
+#define swloww(x) ((((x) << 8) & 0xff00) | (((x) >> 8) & 0x00ff))
+
+/* Transmit/Receive Ring Definitions */
+
+#define TX_RING_SIZE 5
+#define RX_RING_SIZE 16
+
+#define PKT_BUF_SIZE 1520
+
+/* Private Device Data */
+
+struct ariadne_private {
+ volatile struct TDRE *tx_ring[TX_RING_SIZE];
+ volatile struct RDRE *rx_ring[RX_RING_SIZE];
+ volatile u_short *tx_buff[TX_RING_SIZE];
+ volatile u_short *rx_buff[RX_RING_SIZE];
+ int cur_tx, cur_rx; /* The next free ring entry */
+ int dirty_tx; /* The ring entries to be free()ed */
+ char tx_full;
+};
+
+/* Structure Created in the Ariadne's RAM Buffer */
+
+struct lancedata {
+ struct TDRE tx_ring[TX_RING_SIZE];
+ struct RDRE rx_ring[RX_RING_SIZE];
+ u_short tx_buff[TX_RING_SIZE][PKT_BUF_SIZE / sizeof(u_short)];
+ u_short rx_buff[RX_RING_SIZE][PKT_BUF_SIZE / sizeof(u_short)];
+};
+
+static void memcpyw(volatile u_short *dest, u_short *src, int len)
+{
+ while (len >= 2) {
+ *(dest++) = *(src++);
+ len -= 2;
+ }
+ if (len == 1)
+ *dest = (*(u_char *)src) << 8;
+}
+
+static void ariadne_init_ring(struct net_device *dev)
+{
+ struct ariadne_private *priv = netdev_priv(dev);
+ volatile struct lancedata *lancedata = (struct lancedata *)dev->mem_start;
+ int i;
+
+ netif_stop_queue(dev);
+
+ priv->tx_full = 0;
+ priv->cur_rx = priv->cur_tx = 0;
+ priv->dirty_tx = 0;
+
+ /* Set up TX Ring */
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ volatile struct TDRE *t = &lancedata->tx_ring[i];
+ t->TMD0 = swloww(ARIADNE_RAM +
+ offsetof(struct lancedata, tx_buff[i]));
+ t->TMD1 = swhighw(ARIADNE_RAM +
+ offsetof(struct lancedata, tx_buff[i])) |
+ TF_STP | TF_ENP;
+ t->TMD2 = swapw((u_short)-PKT_BUF_SIZE);
+ t->TMD3 = 0;
+ priv->tx_ring[i] = &lancedata->tx_ring[i];
+ priv->tx_buff[i] = lancedata->tx_buff[i];
+ netdev_dbg(dev, "TX Entry %2d at %p, Buf at %p\n",
+ i, &lancedata->tx_ring[i], lancedata->tx_buff[i]);
+ }
+
+ /* Set up RX Ring */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ volatile struct RDRE *r = &lancedata->rx_ring[i];
+ r->RMD0 = swloww(ARIADNE_RAM +
+ offsetof(struct lancedata, rx_buff[i]));
+ r->RMD1 = swhighw(ARIADNE_RAM +
+ offsetof(struct lancedata, rx_buff[i])) |
+ RF_OWN;
+ r->RMD2 = swapw((u_short)-PKT_BUF_SIZE);
+ r->RMD3 = 0x0000;
+ priv->rx_ring[i] = &lancedata->rx_ring[i];
+ priv->rx_buff[i] = lancedata->rx_buff[i];
+ netdev_dbg(dev, "RX Entry %2d at %p, Buf at %p\n",
+ i, &lancedata->rx_ring[i], lancedata->rx_buff[i]);
+ }
+}
+
+static int ariadne_rx(struct net_device *dev)
+{
+ struct ariadne_private *priv = netdev_priv(dev);
+ int entry = priv->cur_rx % RX_RING_SIZE;
+ int i;
+
+ /* If we own the next entry, it's a new packet. Send it up */
+ while (!(lowb(priv->rx_ring[entry]->RMD1) & RF_OWN)) {
+ int status = lowb(priv->rx_ring[entry]->RMD1);
+
+ if (status != (RF_STP | RF_ENP)) { /* There was an error */
+ /* There is a tricky error noted by
+ * John Murphy <murf@perftech.com> to Russ Nelson:
+ * Even with full-sized buffers it's possible for a
+ * jabber packet to use two buffers, with only the
+ * last correctly noting the error
+ */
+ /* Only count a general error at the end of a packet */
+ if (status & RF_ENP)
+ dev->stats.rx_errors++;
+ if (status & RF_FRAM)
+ dev->stats.rx_frame_errors++;
+ if (status & RF_OFLO)
+ dev->stats.rx_over_errors++;
+ if (status & RF_CRC)
+ dev->stats.rx_crc_errors++;
+ if (status & RF_BUFF)
+ dev->stats.rx_fifo_errors++;
+ priv->rx_ring[entry]->RMD1 &= 0xff00 | RF_STP | RF_ENP;
+ } else {
+ /* Malloc up new buffer, compatible with net-3 */
+ short pkt_len = swapw(priv->rx_ring[entry]->RMD3);
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb(dev, pkt_len + 2);
+ if (skb == NULL) {
+ for (i = 0; i < RX_RING_SIZE; i++)
+ if (lowb(priv->rx_ring[(entry + i) % RX_RING_SIZE]->RMD1) & RF_OWN)
+ break;
+
+ if (i > RX_RING_SIZE - 2) {
+ dev->stats.rx_dropped++;
+ priv->rx_ring[entry]->RMD1 |= RF_OWN;
+ priv->cur_rx++;
+ }
+ break;
+ }
+
+
+ skb_reserve(skb, 2); /* 16 byte align */
+ skb_put(skb, pkt_len); /* Make room */
+ skb_copy_to_linear_data(skb,
+ (const void *)priv->rx_buff[entry],
+ pkt_len);
+ skb->protocol = eth_type_trans(skb, dev);
+ netdev_dbg(dev, "RX pkt type 0x%04x from %pM to %pM data %p len %u\n",
+ ((u_short *)skb->data)[6],
+ skb->data + 6, skb->data,
+ skb->data, skb->len);
+
+ netif_rx(skb);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+ }
+
+ priv->rx_ring[entry]->RMD1 |= RF_OWN;
+ entry = (++priv->cur_rx) % RX_RING_SIZE;
+ }
+
+ priv->cur_rx = priv->cur_rx % RX_RING_SIZE;
+
+ /* We should check that at least two ring entries are free.
+ * If not, we should free one and mark stats->rx_dropped++
+ */
+
+ return 0;
+}
+
+static irqreturn_t ariadne_interrupt(int irq, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+ struct ariadne_private *priv;
+ int csr0, boguscnt;
+ int handled = 0;
+
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+
+ if (!(lance->RDP & INTR)) /* Check if any interrupt has been */
+ return IRQ_NONE; /* generated by the board */
+
+ priv = netdev_priv(dev);
+
+ boguscnt = 10;
+ while ((csr0 = lance->RDP) & (ERR | RINT | TINT) && --boguscnt >= 0) {
+ /* Acknowledge all of the current interrupt sources ASAP */
+ lance->RDP = csr0 & ~(INEA | TDMD | STOP | STRT | INIT);
+
+#ifdef DEBUG
+ if (ariadne_debug > 5) {
+ netdev_dbg(dev, "interrupt csr0=%#02x new csr=%#02x [",
+ csr0, lance->RDP);
+ if (csr0 & INTR)
+ pr_cont(" INTR");
+ if (csr0 & INEA)
+ pr_cont(" INEA");
+ if (csr0 & RXON)
+ pr_cont(" RXON");
+ if (csr0 & TXON)
+ pr_cont(" TXON");
+ if (csr0 & TDMD)
+ pr_cont(" TDMD");
+ if (csr0 & STOP)
+ pr_cont(" STOP");
+ if (csr0 & STRT)
+ pr_cont(" STRT");
+ if (csr0 & INIT)
+ pr_cont(" INIT");
+ if (csr0 & ERR)
+ pr_cont(" ERR");
+ if (csr0 & BABL)
+ pr_cont(" BABL");
+ if (csr0 & CERR)
+ pr_cont(" CERR");
+ if (csr0 & MISS)
+ pr_cont(" MISS");
+ if (csr0 & MERR)
+ pr_cont(" MERR");
+ if (csr0 & RINT)
+ pr_cont(" RINT");
+ if (csr0 & TINT)
+ pr_cont(" TINT");
+ if (csr0 & IDON)
+ pr_cont(" IDON");
+ pr_cont(" ]\n");
+ }
+#endif
+
+ if (csr0 & RINT) { /* Rx interrupt */
+ handled = 1;
+ ariadne_rx(dev);
+ }
+
+ if (csr0 & TINT) { /* Tx-done interrupt */
+ int dirty_tx = priv->dirty_tx;
+
+ handled = 1;
+ while (dirty_tx < priv->cur_tx) {
+ int entry = dirty_tx % TX_RING_SIZE;
+ int status = lowb(priv->tx_ring[entry]->TMD1);
+
+ if (status & TF_OWN)
+ break; /* It still hasn't been Txed */
+
+ priv->tx_ring[entry]->TMD1 &= 0xff00;
+
+ if (status & TF_ERR) {
+ /* There was an major error, log it */
+ int err_status = priv->tx_ring[entry]->TMD3;
+ dev->stats.tx_errors++;
+ if (err_status & EF_RTRY)
+ dev->stats.tx_aborted_errors++;
+ if (err_status & EF_LCAR)
+ dev->stats.tx_carrier_errors++;
+ if (err_status & EF_LCOL)
+ dev->stats.tx_window_errors++;
+ if (err_status & EF_UFLO) {
+ /* Ackk! On FIFO errors the Tx unit is turned off! */
+ dev->stats.tx_fifo_errors++;
+ /* Remove this verbosity later! */
+ netdev_err(dev, "Tx FIFO error! Status %04x\n",
+ csr0);
+ /* Restart the chip */
+ lance->RDP = STRT;
+ }
+ } else {
+ if (status & (TF_MORE | TF_ONE))
+ dev->stats.collisions++;
+ dev->stats.tx_packets++;
+ }
+ dirty_tx++;
+ }
+
+#ifndef final_version
+ if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) {
+ netdev_err(dev, "out-of-sync dirty pointer, %d vs. %d, full=%d\n",
+ dirty_tx, priv->cur_tx,
+ priv->tx_full);
+ dirty_tx += TX_RING_SIZE;
+ }
+#endif
+
+ if (priv->tx_full && netif_queue_stopped(dev) &&
+ dirty_tx > priv->cur_tx - TX_RING_SIZE + 2) {
+ /* The ring is no longer full */
+ priv->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+
+ priv->dirty_tx = dirty_tx;
+ }
+
+ /* Log misc errors */
+ if (csr0 & BABL) {
+ handled = 1;
+ dev->stats.tx_errors++; /* Tx babble */
+ }
+ if (csr0 & MISS) {
+ handled = 1;
+ dev->stats.rx_errors++; /* Missed a Rx frame */
+ }
+ if (csr0 & MERR) {
+ handled = 1;
+ netdev_err(dev, "Bus master arbitration failure, status %04x\n",
+ csr0);
+ /* Restart the chip */
+ lance->RDP = STRT;
+ }
+ }
+
+ /* Clear any other interrupt, and set interrupt enable */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA | BABL | CERR | MISS | MERR | IDON;
+
+ if (ariadne_debug > 4)
+ netdev_dbg(dev, "exiting interrupt, csr%d=%#04x\n",
+ lance->RAP, lance->RDP);
+
+ return IRQ_RETVAL(handled);
+}
+
+static int ariadne_open(struct net_device *dev)
+{
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+ u_short in;
+ u_long version;
+ int i;
+
+ /* Reset the LANCE */
+ in = lance->Reset;
+
+ /* Stop the LANCE */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = STOP;
+
+ /* Check the LANCE version */
+ lance->RAP = CSR88; /* Chip ID */
+ version = swapw(lance->RDP);
+ lance->RAP = CSR89; /* Chip ID */
+ version |= swapw(lance->RDP) << 16;
+ if ((version & 0x00000fff) != 0x00000003) {
+ pr_warn("Couldn't find AMD Ethernet Chip\n");
+ return -EAGAIN;
+ }
+ if ((version & 0x0ffff000) != 0x00003000) {
+ pr_warn("Couldn't find Am79C960 (Wrong part number = %ld)\n",
+ (version & 0x0ffff000) >> 12);
+ return -EAGAIN;
+ }
+
+ netdev_dbg(dev, "Am79C960 (PCnet-ISA) Revision %ld\n",
+ (version & 0xf0000000) >> 28);
+
+ ariadne_init_ring(dev);
+
+ /* Miscellaneous Stuff */
+ lance->RAP = CSR3; /* Interrupt Masks and Deferral Control */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR4; /* Test and Features Control */
+ lance->RDP = DPOLL | APAD_XMT | MFCOM | RCVCCOM | TXSTRTM | JABM;
+
+ /* Set the Multicast Table */
+ lance->RAP = CSR8; /* Logical Address Filter, LADRF[15:0] */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR9; /* Logical Address Filter, LADRF[31:16] */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR10; /* Logical Address Filter, LADRF[47:32] */
+ lance->RDP = 0x0000;
+ lance->RAP = CSR11; /* Logical Address Filter, LADRF[63:48] */
+ lance->RDP = 0x0000;
+
+ /* Set the Ethernet Hardware Address */
+ lance->RAP = CSR12; /* Physical Address Register, PADR[15:0] */
+ lance->RDP = ((u_short *)&dev->dev_addr[0])[0];
+ lance->RAP = CSR13; /* Physical Address Register, PADR[31:16] */
+ lance->RDP = ((u_short *)&dev->dev_addr[0])[1];
+ lance->RAP = CSR14; /* Physical Address Register, PADR[47:32] */
+ lance->RDP = ((u_short *)&dev->dev_addr[0])[2];
+
+ /* Set the Init Block Mode */
+ lance->RAP = CSR15; /* Mode Register */
+ lance->RDP = 0x0000;
+
+ /* Set the Transmit Descriptor Ring Pointer */
+ lance->RAP = CSR30; /* Base Address of Transmit Ring */
+ lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, tx_ring));
+ lance->RAP = CSR31; /* Base Address of transmit Ring */
+ lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, tx_ring));
+
+ /* Set the Receive Descriptor Ring Pointer */
+ lance->RAP = CSR24; /* Base Address of Receive Ring */
+ lance->RDP = swloww(ARIADNE_RAM + offsetof(struct lancedata, rx_ring));
+ lance->RAP = CSR25; /* Base Address of Receive Ring */
+ lance->RDP = swhighw(ARIADNE_RAM + offsetof(struct lancedata, rx_ring));
+
+ /* Set the Number of RX and TX Ring Entries */
+ lance->RAP = CSR76; /* Receive Ring Length */
+ lance->RDP = swapw(((u_short)-RX_RING_SIZE));
+ lance->RAP = CSR78; /* Transmit Ring Length */
+ lance->RDP = swapw(((u_short)-TX_RING_SIZE));
+
+ /* Enable Media Interface Port Auto Select (10BASE-2/10BASE-T) */
+ lance->RAP = ISACSR2; /* Miscellaneous Configuration */
+ lance->IDP = ASEL;
+
+ /* LED Control */
+ lance->RAP = ISACSR5; /* LED1 Status */
+ lance->IDP = PSE|XMTE;
+ lance->RAP = ISACSR6; /* LED2 Status */
+ lance->IDP = PSE|COLE;
+ lance->RAP = ISACSR7; /* LED3 Status */
+ lance->IDP = PSE|RCVE;
+
+ netif_start_queue(dev);
+
+ i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (i)
+ return i;
+
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA | STRT;
+
+ return 0;
+}
+
+static int ariadne_close(struct net_device *dev)
+{
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+
+ netif_stop_queue(dev);
+
+ lance->RAP = CSR112; /* Missed Frame Count */
+ dev->stats.rx_missed_errors = swapw(lance->RDP);
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+
+ if (ariadne_debug > 1) {
+ netdev_dbg(dev, "Shutting down ethercard, status was %02x\n",
+ lance->RDP);
+ netdev_dbg(dev, "%lu packets missed\n",
+ dev->stats.rx_missed_errors);
+ }
+
+ /* We stop the LANCE here -- it occasionally polls memory if we don't */
+ lance->RDP = STOP;
+
+ free_irq(IRQ_AMIGA_PORTS, dev);
+
+ return 0;
+}
+
+static inline void ariadne_reset(struct net_device *dev)
+{
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = STOP;
+ ariadne_init_ring(dev);
+ lance->RDP = INEA | STRT;
+ netif_start_queue(dev);
+}
+
+static void ariadne_tx_timeout(struct net_device *dev)
+{
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+
+ netdev_err(dev, "transmit timed out, status %04x, resetting\n",
+ lance->RDP);
+ ariadne_reset(dev);
+ netif_wake_queue(dev);
+}
+
+static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct ariadne_private *priv = netdev_priv(dev);
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+ int entry;
+ unsigned long flags;
+ int len = skb->len;
+
+#if 0
+ if (ariadne_debug > 3) {
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ netdev_dbg(dev, "%s: csr0 %04x\n", __func__, lance->RDP);
+ lance->RDP = 0x0000;
+ }
+#endif
+
+ /* FIXME: is the 79C960 new enough to do its own padding right ? */
+ if (skb->len < ETH_ZLEN) {
+ if (skb_padto(skb, ETH_ZLEN))
+ return NETDEV_TX_OK;
+ len = ETH_ZLEN;
+ }
+
+ /* Fill in a Tx ring entry */
+
+ netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data %p len %u\n",
+ ((u_short *)skb->data)[6],
+ skb->data + 6, skb->data,
+ skb->data, skb->len);
+
+ local_irq_save(flags);
+
+ entry = priv->cur_tx % TX_RING_SIZE;
+
+ /* Caution: the write order is important here, set the base address with
+ the "ownership" bits last */
+
+ priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len);
+ priv->tx_ring[entry]->TMD3 = 0x0000;
+ memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len);
+
+#ifdef DEBUG
+ print_hex_dump(KERN_DEBUG, "tx_buff: ", DUMP_PREFIX_OFFSET, 16, 1,
+ (void *)priv->tx_buff[entry],
+ skb->len > 64 ? 64 : skb->len, true);
+#endif
+
+ priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1 & 0xff00)
+ | TF_OWN | TF_STP | TF_ENP;
+
+ dev_kfree_skb(skb);
+
+ priv->cur_tx++;
+ if ((priv->cur_tx >= TX_RING_SIZE) &&
+ (priv->dirty_tx >= TX_RING_SIZE)) {
+
+ netdev_dbg(dev, "*** Subtracting TX_RING_SIZE from cur_tx (%d) and dirty_tx (%d)\n",
+ priv->cur_tx, priv->dirty_tx);
+
+ priv->cur_tx -= TX_RING_SIZE;
+ priv->dirty_tx -= TX_RING_SIZE;
+ }
+ dev->stats.tx_bytes += len;
+
+ /* Trigger an immediate send poll */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA | TDMD;
+
+ if (lowb(priv->tx_ring[(entry + 1) % TX_RING_SIZE]->TMD1) != 0) {
+ netif_stop_queue(dev);
+ priv->tx_full = 1;
+ }
+ local_irq_restore(flags);
+
+ return NETDEV_TX_OK;
+}
+
+static struct net_device_stats *ariadne_get_stats(struct net_device *dev)
+{
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+ short saved_addr;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ saved_addr = lance->RAP;
+ lance->RAP = CSR112; /* Missed Frame Count */
+ dev->stats.rx_missed_errors = swapw(lance->RDP);
+ lance->RAP = saved_addr;
+ local_irq_restore(flags);
+
+ return &dev->stats;
+}
+
+/* Set or clear the multicast filter for this adaptor.
+ * num_addrs == -1 Promiscuous mode, receive all packets
+ * num_addrs == 0 Normal mode, clear multicast list
+ * num_addrs > 0 Multicast mode, receive normal and MC packets,
+ * and do best-effort filtering.
+ */
+static void set_multicast_list(struct net_device *dev)
+{
+ volatile struct Am79C960 *lance = (struct Am79C960 *)dev->base_addr;
+
+ if (!netif_running(dev))
+ return;
+
+ netif_stop_queue(dev);
+
+ /* We take the simple way out and always enable promiscuous mode */
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = STOP; /* Temporarily stop the lance */
+ ariadne_init_ring(dev);
+
+ if (dev->flags & IFF_PROMISC) {
+ lance->RAP = CSR15; /* Mode Register */
+ lance->RDP = PROM; /* Set promiscuous mode */
+ } else {
+ short multicast_table[4];
+ int num_addrs = netdev_mc_count(dev);
+ int i;
+ /* We don't use the multicast table,
+ * but rely on upper-layer filtering
+ */
+ memset(multicast_table, (num_addrs == 0) ? 0 : -1,
+ sizeof(multicast_table));
+ for (i = 0; i < 4; i++) {
+ lance->RAP = CSR8 + (i << 8);
+ /* Logical Address Filter */
+ lance->RDP = swapw(multicast_table[i]);
+ }
+ lance->RAP = CSR15; /* Mode Register */
+ lance->RDP = 0x0000; /* Unset promiscuous mode */
+ }
+
+ lance->RAP = CSR0; /* PCnet-ISA Controller Status */
+ lance->RDP = INEA | STRT | IDON;/* Resume normal operation */
+
+ netif_wake_queue(dev);
+}
+
+
+static void ariadne_remove_one(struct zorro_dev *z)
+{
+ struct net_device *dev = zorro_get_drvdata(z);
+
+ unregister_netdev(dev);
+ release_mem_region(ZTWO_PADDR(dev->base_addr), sizeof(struct Am79C960));
+ release_mem_region(ZTWO_PADDR(dev->mem_start), ARIADNE_RAM_SIZE);
+ free_netdev(dev);
+}
+
+static struct zorro_device_id ariadne_zorro_tbl[] = {
+ { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl);
+
+static const struct net_device_ops ariadne_netdev_ops = {
+ .ndo_open = ariadne_open,
+ .ndo_stop = ariadne_close,
+ .ndo_start_xmit = ariadne_start_xmit,
+ .ndo_tx_timeout = ariadne_tx_timeout,
+ .ndo_get_stats = ariadne_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
+static int ariadne_init_one(struct zorro_dev *z,
+ const struct zorro_device_id *ent)
+{
+ unsigned long board = z->resource.start;
+ unsigned long base_addr = board + ARIADNE_LANCE;
+ unsigned long mem_start = board + ARIADNE_RAM;
+ struct resource *r1, *r2;
+ struct net_device *dev;
+ u32 serial;
+ int err;
+
+ r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960");
+ if (!r1)
+ return -EBUSY;
+ r2 = request_mem_region(mem_start, ARIADNE_RAM_SIZE, "RAM");
+ if (!r2) {
+ release_mem_region(base_addr, sizeof(struct Am79C960));
+ return -EBUSY;
+ }
+
+ dev = alloc_etherdev(sizeof(struct ariadne_private));
+ if (dev == NULL) {
+ release_mem_region(base_addr, sizeof(struct Am79C960));
+ release_mem_region(mem_start, ARIADNE_RAM_SIZE);
+ return -ENOMEM;
+ }
+
+ r1->name = dev->name;
+ r2->name = dev->name;
+
+ serial = be32_to_cpu(z->rom.er_SerialNumber);
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0x60;
+ dev->dev_addr[2] = 0x30;
+ dev->dev_addr[3] = (serial >> 16) & 0xff;
+ dev->dev_addr[4] = (serial >> 8) & 0xff;
+ dev->dev_addr[5] = serial & 0xff;
+ dev->base_addr = (unsigned long)ZTWO_VADDR(base_addr);
+ dev->mem_start = (unsigned long)ZTWO_VADDR(mem_start);
+ dev->mem_end = dev->mem_start + ARIADNE_RAM_SIZE;
+
+ dev->netdev_ops = &ariadne_netdev_ops;
+ dev->watchdog_timeo = 5 * HZ;
+
+ err = register_netdev(dev);
+ if (err) {
+ release_mem_region(base_addr, sizeof(struct Am79C960));
+ release_mem_region(mem_start, ARIADNE_RAM_SIZE);
+ free_netdev(dev);
+ return err;
+ }
+ zorro_set_drvdata(z, dev);
+
+ netdev_info(dev, "Ariadne at 0x%08lx, Ethernet Address %pM\n",
+ board, dev->dev_addr);
+
+ return 0;
+}
+
+static struct zorro_driver ariadne_driver = {
+ .name = "ariadne",
+ .id_table = ariadne_zorro_tbl,
+ .probe = ariadne_init_one,
+ .remove = ariadne_remove_one,
+};
+
+static int __init ariadne_init_module(void)
+{
+ return zorro_register_driver(&ariadne_driver);
+}
+
+static void __exit ariadne_cleanup_module(void)
+{
+ zorro_unregister_driver(&ariadne_driver);
+}
+
+module_init(ariadne_init_module);
+module_exit(ariadne_cleanup_module);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ariadne.h b/drivers/net/ethernet/amd/ariadne.h
index bb613f292e0..727be5cdd1e 100644
--- a/drivers/net/ariadne.h
+++ b/drivers/net/ethernet/amd/ariadne.h
@@ -244,7 +244,7 @@ struct Am79C960 {
#define DLNKTST 0x0010 /* Disable Link Status */
#define DAPC 0x0008 /* Disable Automatic Polarity Correction */
#define MENDECL 0x0004 /* MENDEC Loopback Mode */
-#define LRTTSEL 0x0002 /* Low Receive Treshold/Transmit Mode Select */
+#define LRTTSEL 0x0002 /* Low Receive Threshold/Transmit Mode Select */
#define PORTSEL1 0x0001 /* Port Select Bits */
#define PORTSEL2 0x8000 /* Port Select Bits */
#define INTL 0x4000 /* Internal Loopback */
diff --git a/drivers/net/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
index 0860cc280b0..e07ce5ff2d4 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/ethernet/amd/atarilance.c
@@ -53,7 +53,6 @@ static char version[] = "atarilance.c: v1.3 04/04/96 "
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/bitops.h>
@@ -117,7 +116,7 @@ MODULE_LICENSE("GPL");
#define RX_RING_LEN_BITS (RX_LOG_RING_SIZE << 5)
#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
-#define TX_TIMEOUT 20
+#define TX_TIMEOUT (HZ/5)
/* The LANCE Rx and Tx ring descriptors. */
struct lance_rx_head {
@@ -363,7 +362,7 @@ static void *slow_memcpy( void *dst, const void *src, size_t len )
*cto++ = *cfrom++;
MFPDELAY();
}
- return( dst );
+ return dst;
}
@@ -408,7 +407,7 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag,
int writeflag)
{
int ret;
- long flags;
+ unsigned long flags;
long *vbr, save_berr;
local_irq_save(flags);
@@ -450,9 +449,19 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag,
vbr[2] = save_berr;
local_irq_restore(flags);
- return( ret );
+ return ret;
}
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_set_mac_address = lance_set_mac_address,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
static unsigned long __init lance_probe1( struct net_device *dev,
struct lance_addr *init_rec )
@@ -466,7 +475,6 @@ static unsigned long __init lance_probe1( struct net_device *dev,
int i;
static int did_version;
unsigned short save1, save2;
- DECLARE_MAC_BUF(mac);
PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
(long)memaddr, (long)ioaddr ));
@@ -518,10 +526,10 @@ static unsigned long __init lance_probe1( struct net_device *dev,
goto probe_ok;
probe_fail:
- return( 0 );
+ return 0;
probe_ok:
- lp = (struct lance_private *)dev->priv;
+ lp = netdev_priv(dev);
MEM = (struct lance_memory *)memaddr;
IO = lp->iobase = (struct lance_ioreg *)ioaddr;
dev->base_addr = (unsigned long)ioaddr; /* informational only */
@@ -546,26 +554,23 @@ static unsigned long __init lance_probe1( struct net_device *dev,
memaddr == (unsigned short *)0xffe00000) {
/* PAMs card and Riebl on ST use level 5 autovector */
if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
- "PAM/Riebl-ST Ethernet", dev)) {
+ "PAM,Riebl-ST Ethernet", dev)) {
printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
- return( 0 );
+ return 0;
}
- dev->irq = (unsigned short)IRQ_AUTO_5;
+ dev->irq = IRQ_AUTO_5;
}
else {
- /* For VME-RieblCards, request a free VME int;
- * (This must be unsigned long, since dev->irq is short and the
- * IRQ_MACHSPEC bit would be cut off...)
- */
- unsigned long irq = atari_register_vme_int();
+ /* For VME-RieblCards, request a free VME int */
+ unsigned int irq = atari_register_vme_int();
if (!irq) {
printk( "Lance: request for VME interrupt failed\n" );
- return( 0 );
+ return 0;
}
if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
"Riebl-VME Ethernet", dev)) {
- printk( "Lance: request for irq %ld failed\n", irq );
- return( 0 );
+ printk( "Lance: request for irq %u failed\n", irq );
+ return 0;
}
dev->irq = irq;
}
@@ -581,10 +586,10 @@ static unsigned long __init lance_probe1( struct net_device *dev,
switch( lp->cardtype ) {
case OLD_RIEBL:
/* No ethernet address! (Set some default address) */
- memcpy( dev->dev_addr, OldRieblDefHwaddr, 6 );
+ memcpy(dev->dev_addr, OldRieblDefHwaddr, ETH_ALEN);
break;
case NEW_RIEBL:
- lp->memcpy_f( dev->dev_addr, RIEBL_HWADDR_ADDR, 6 );
+ lp->memcpy_f(dev->dev_addr, RIEBL_HWADDR_ADDR, ETH_ALEN);
break;
case PAM_CARD:
i = IO->eeprom;
@@ -595,7 +600,7 @@ static unsigned long __init lance_probe1( struct net_device *dev,
i = IO->mem;
break;
}
- printk("%s\n", print_mac(mac, dev->dev_addr));
+ printk("%pM\n", dev->dev_addr);
if (lp->cardtype == OLD_RIEBL) {
printk( "%s: Warning: This is a default ethernet address!\n",
dev->name );
@@ -624,24 +629,18 @@ static unsigned long __init lance_probe1( struct net_device *dev,
if (did_version++ == 0)
DPRINTK( 1, ( version ));
- /* The LANCE-specific entries in the device structure. */
- dev->open = &lance_open;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->stop = &lance_close;
- dev->set_multicast_list = &set_multicast_list;
- dev->set_mac_address = &lance_set_mac_address;
+ dev->netdev_ops = &lance_netdev_ops;
/* XXX MSch */
- dev->tx_timeout = lance_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- return( 1 );
+ return 1;
}
static int lance_open( struct net_device *dev )
-
-{ struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+ struct lance_private *lp = netdev_priv(dev);
struct lance_ioreg *IO = lp->iobase;
int i;
@@ -660,11 +659,11 @@ static int lance_open( struct net_device *dev )
while (--i > 0)
if (DREG & CSR0_IDON)
break;
- if (i < 0 || (DREG & CSR0_ERR)) {
+ if (i <= 0 || (DREG & CSR0_ERR)) {
DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
dev->name, i, DREG ));
DREG = CSR0_STOP;
- return( -EIO );
+ return -EIO;
}
DREG = CSR0_IDON;
DREG = CSR0_STRT;
@@ -674,15 +673,15 @@ static int lance_open( struct net_device *dev )
DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
- return( 0 );
+ return 0;
}
/* Initialize the LANCE Rx and Tx rings. */
static void lance_init_ring( struct net_device *dev )
-
-{ struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+ struct lance_private *lp = netdev_priv(dev);
int i;
unsigned offset;
@@ -730,7 +729,7 @@ static void lance_init_ring( struct net_device *dev )
static void lance_tx_timeout (struct net_device *dev)
{
- struct lance_private *lp = (struct lance_private *) dev->priv;
+ struct lance_private *lp = netdev_priv(dev);
struct lance_ioreg *IO = lp->iobase;
AREG = CSR0;
@@ -765,21 +764,19 @@ static void lance_tx_timeout (struct net_device *dev)
/* lance_restart, essentially */
lance_init_ring(dev);
REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
- dev->trans_start = jiffies;
- netif_wake_queue (dev);
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ netif_wake_queue(dev);
}
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
-
-{ struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+ struct lance_private *lp = netdev_priv(dev);
struct lance_ioreg *IO = lp->iobase;
int entry, len;
struct lance_tx_head *head;
unsigned long flags;
- DECLARE_MAC_BUF(mac);
- DECLARE_MAC_BUF(mac2);
DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
dev->name, DREG ));
@@ -795,19 +792,17 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
if (len > skb->len) {
if (skb_padto(skb, len))
- return 0;
+ return NETDEV_TX_OK;
}
netif_stop_queue (dev);
/* Fill in a Tx ring entry */
if (lance_debug >= 3) {
- printk( "%s: TX pkt type 0x%04x from "
- "%s to %s"
+ printk( "%s: TX pkt type 0x%04x from %pM to %pM"
" data at 0x%08x len %d\n",
dev->name, ((u_short *)skb->data)[6],
- print_mac(mac, &skb->data[6]),
- print_mac(mac2, skb->data),
+ &skb->data[6], skb->data,
(int)skb->data, (int)skb->len );
}
@@ -838,7 +833,6 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
/* Trigger an immediate send poll. */
DREG = CSR0_INEA | CSR0_TDMD;
- dev->trans_start = jiffies;
if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
TMD1_OWN_HOST)
@@ -847,7 +841,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
lp->tx_full = 1;
spin_unlock_irqrestore (&lp->devlock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/* The LANCE interrupt handler. */
@@ -865,7 +859,7 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id )
return IRQ_NONE;
}
- lp = (struct lance_private *)dev->priv;
+ lp = netdev_priv(dev);
IO = lp->iobase;
spin_lock (&lp->devlock);
@@ -931,8 +925,8 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id )
}
#endif
- if (lp->tx_full && (netif_queue_stopped(dev))
- && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
+ if (lp->tx_full && (netif_queue_stopped(dev)) &&
+ dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
/* The ring is no longer full, clear tbusy. */
lp->tx_full = 0;
netif_wake_queue (dev);
@@ -965,8 +959,8 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id )
static int lance_rx( struct net_device *dev )
-
-{ struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+ struct lance_private *lp = netdev_priv(dev);
int entry = lp->cur_rx & RX_RING_MOD_MASK;
int i;
@@ -1000,10 +994,8 @@ static int lance_rx( struct net_device *dev )
dev->stats.rx_errors++;
}
else {
- skb = dev_alloc_skb( pkt_len+2 );
+ skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL) {
- DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
- dev->name ));
for( i = 0; i < RX_RING_SIZE; i++ )
if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
RMD1_OWN_CHIP)
@@ -1019,14 +1011,12 @@ static int lance_rx( struct net_device *dev )
if (lance_debug >= 3) {
u_char *data = PKTBUF_ADDR(head);
- DECLARE_MAC_BUF(mac);
- DECLARE_MAC_BUF(mac2);
- printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %s to %s "
+ printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %pM to %pM "
"data %02x %02x %02x %02x %02x %02x %02x %02x "
"len %d\n",
dev->name, ((u_short *)data)[6],
- print_mac(mac, &data[6]), print_mac(mac2, data),
+ &data[6], data,
data[15], data[16], data[17], data[18],
data[19], data[20], data[21], data[22],
pkt_len);
@@ -1037,7 +1027,6 @@ static int lance_rx( struct net_device *dev )
lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len );
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
}
@@ -1057,8 +1046,8 @@ static int lance_rx( struct net_device *dev )
static int lance_close( struct net_device *dev )
-
-{ struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+ struct lance_private *lp = netdev_priv(dev);
struct lance_ioreg *IO = lp->iobase;
netif_stop_queue (dev);
@@ -1084,8 +1073,8 @@ static int lance_close( struct net_device *dev )
*/
static void set_multicast_list( struct net_device *dev )
-
-{ struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+ struct lance_private *lp = netdev_priv(dev);
struct lance_ioreg *IO = lp->iobase;
if (netif_running(dev))
@@ -1101,7 +1090,7 @@ static void set_multicast_list( struct net_device *dev )
REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
} else {
short multicast_table[4];
- int num_addrs = dev->mc_count;
+ int num_addrs = netdev_mc_count(dev);
int i;
/* We don't use the multicast table, but rely on upper-layer
* filtering. */
@@ -1126,19 +1115,19 @@ static void set_multicast_list( struct net_device *dev )
/* This is needed for old RieblCards and possible for new RieblCards */
static int lance_set_mac_address( struct net_device *dev, void *addr )
-
-{ struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+ struct lance_private *lp = netdev_priv(dev);
struct sockaddr *saddr = addr;
int i;
if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
- return( -EOPNOTSUPP );
+ return -EOPNOTSUPP;
if (netif_running(dev)) {
/* Only possible while card isn't started */
DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n",
dev->name ));
- return( -EIO );
+ return -EIO;
}
memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len );
@@ -1148,7 +1137,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr )
/* set also the magic for future sessions */
*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
- return( 0 );
+ return 0;
}
@@ -1158,9 +1147,7 @@ static struct net_device *atarilance_dev;
static int __init atarilance_module_init(void)
{
atarilance_dev = atarilance_probe(-1);
- if (IS_ERR(atarilance_dev))
- return PTR_ERR(atarilance_dev);
- return 0;
+ return PTR_ERR_OR_ZERO(atarilance_dev);
}
static void __exit atarilance_module_exit(void)
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
new file mode 100644
index 00000000000..a78e4c13695
--- /dev/null
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -0,0 +1,1347 @@
+/*
+ *
+ * Alchemy Au1x00 ethernet driver
+ *
+ * Copyright 2001-2003, 2006 MontaVista Software Inc.
+ * Copyright 2002 TimeSys Corp.
+ * Added ethtool/mii-tool support,
+ * Copyright 2004 Matt Porter <mporter@kernel.crashing.org>
+ * Update: 2004 Bjoern Riemer, riemer@fokus.fraunhofer.de
+ * or riemer@riemer-nt.de: fixed the link beat detection with
+ * ioctls (SIOCGMIIPHY)
+ * Copyright 2006 Herbert Valerio Riedel <hvr@gnu.org>
+ * converted to use linux-2.6.x's PHY framework
+ *
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/capability.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/in.h>
+#include <linux/ioport.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/crc32.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/io.h>
+
+#include <asm/mipsregs.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+
+#include <au1000.h>
+#include <au1xxx_eth.h>
+#include <prom.h>
+
+#include "au1000_eth.h"
+
+#ifdef AU1000_ETH_DEBUG
+static int au1000_debug = 5;
+#else
+static int au1000_debug = 3;
+#endif
+
+#define AU1000_DEF_MSG_ENABLE (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK)
+
+#define DRV_NAME "au1000_eth"
+#define DRV_VERSION "1.7"
+#define DRV_AUTHOR "Pete Popov <ppopov@embeddedalley.com>"
+#define DRV_DESC "Au1xxx on-chip Ethernet driver"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+/*
+ * Theory of operation
+ *
+ * The Au1000 MACs use a simple rx and tx descriptor ring scheme.
+ * There are four receive and four transmit descriptors. These
+ * descriptors are not in memory; rather, they are just a set of
+ * hardware registers.
+ *
+ * Since the Au1000 has a coherent data cache, the receive and
+ * transmit buffers are allocated from the KSEG0 segment. The
+ * hardware registers, however, are still mapped at KSEG1 to
+ * make sure there's no out-of-order writes, and that all writes
+ * complete immediately.
+ */
+
+/*
+ * board-specific configurations
+ *
+ * PHY detection algorithm
+ *
+ * If phy_static_config is undefined, the PHY setup is
+ * autodetected:
+ *
+ * mii_probe() first searches the current MAC's MII bus for a PHY,
+ * selecting the first (or last, if phy_search_highest_addr is
+ * defined) PHY address not already claimed by another netdev.
+ *
+ * If nothing was found that way when searching for the 2nd ethernet
+ * controller's PHY and phy1_search_mac0 is defined, then
+ * the first MII bus is searched as well for an unclaimed PHY; this is
+ * needed in case of a dual-PHY accessible only through the MAC0's MII
+ * bus.
+ *
+ * Finally, if no PHY is found, then the corresponding ethernet
+ * controller is not registered to the network subsystem.
+ */
+
+/* autodetection defaults: phy1_search_mac0 */
+
+/* static PHY setup
+ *
+ * most boards PHY setup should be detectable properly with the
+ * autodetection algorithm in mii_probe(), but in some cases (e.g. if
+ * you have a switch attached, or want to use the PHY's interrupt
+ * notification capabilities) you can provide a static PHY
+ * configuration here
+ *
+ * IRQs may only be set, if a PHY address was configured
+ * If a PHY address is given, also a bus id is required to be set
+ *
+ * ps: make sure the used irqs are configured properly in the board
+ * specific irq-map
+ */
+
+static void au1000_enable_mac(struct net_device *dev, int force_reset)
+{
+ unsigned long flags;
+ struct au1000_private *aup = netdev_priv(dev);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ if (force_reset || (!aup->mac_enabled)) {
+ writel(MAC_EN_CLOCK_ENABLE, aup->enable);
+ au_sync_delay(2);
+ writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
+ | MAC_EN_CLOCK_ENABLE), aup->enable);
+ au_sync_delay(2);
+
+ aup->mac_enabled = 1;
+ }
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+}
+
+/*
+ * MII operations
+ */
+static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ u32 *const mii_control_reg = &aup->mac->mii_control;
+ u32 *const mii_data_reg = &aup->mac->mii_data;
+ u32 timedout = 20;
+ u32 mii_control;
+
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
+ mdelay(1);
+ if (--timedout == 0) {
+ netdev_err(dev, "read_MII busy timeout!!\n");
+ return -1;
+ }
+ }
+
+ mii_control = MAC_SET_MII_SELECT_REG(reg) |
+ MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ;
+
+ writel(mii_control, mii_control_reg);
+
+ timedout = 20;
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
+ mdelay(1);
+ if (--timedout == 0) {
+ netdev_err(dev, "mdio_read busy timeout!!\n");
+ return -1;
+ }
+ }
+ return readl(mii_data_reg);
+}
+
+static void au1000_mdio_write(struct net_device *dev, int phy_addr,
+ int reg, u16 value)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ u32 *const mii_control_reg = &aup->mac->mii_control;
+ u32 *const mii_data_reg = &aup->mac->mii_data;
+ u32 timedout = 20;
+ u32 mii_control;
+
+ while (readl(mii_control_reg) & MAC_MII_BUSY) {
+ mdelay(1);
+ if (--timedout == 0) {
+ netdev_err(dev, "mdio_write busy timeout!!\n");
+ return;
+ }
+ }
+
+ mii_control = MAC_SET_MII_SELECT_REG(reg) |
+ MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE;
+
+ writel(value, mii_data_reg);
+ writel(mii_control, mii_control_reg);
+}
+
+static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
+{
+ /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does
+ * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus)
+ */
+ struct net_device *const dev = bus->priv;
+
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
+ return au1000_mdio_read(dev, phy_addr, regnum);
+}
+
+static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
+ u16 value)
+{
+ struct net_device *const dev = bus->priv;
+
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
+ au1000_mdio_write(dev, phy_addr, regnum, value);
+ return 0;
+}
+
+static int au1000_mdiobus_reset(struct mii_bus *bus)
+{
+ struct net_device *const dev = bus->priv;
+
+ /* make sure the MAC associated with this
+ * mii_bus is enabled
+ */
+ au1000_enable_mac(dev, 0);
+
+ return 0;
+}
+
+static void au1000_hard_stop(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
+
+ netif_dbg(aup, drv, dev, "hard stop\n");
+
+ reg = readl(&aup->mac->control);
+ reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+ writel(reg, &aup->mac->control);
+ au_sync_delay(10);
+}
+
+static void au1000_enable_rx_tx(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
+
+ netif_dbg(aup, hw, dev, "enable_rx_tx\n");
+
+ reg = readl(&aup->mac->control);
+ reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ writel(reg, &aup->mac->control);
+ au_sync_delay(10);
+}
+
+static void
+au1000_adjust_link(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct phy_device *phydev = aup->phy_dev;
+ unsigned long flags;
+ u32 reg;
+
+ int status_change = 0;
+
+ BUG_ON(!aup->phy_dev);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ if (phydev->link && (aup->old_speed != phydev->speed)) {
+ /* speed changed */
+
+ switch (phydev->speed) {
+ case SPEED_10:
+ case SPEED_100:
+ break;
+ default:
+ netdev_warn(dev, "Speed (%d) is not 10/100 ???\n",
+ phydev->speed);
+ break;
+ }
+
+ aup->old_speed = phydev->speed;
+
+ status_change = 1;
+ }
+
+ if (phydev->link && (aup->old_duplex != phydev->duplex)) {
+ /* duplex mode changed */
+
+ /* switching duplex mode requires to disable rx and tx! */
+ au1000_hard_stop(dev);
+
+ reg = readl(&aup->mac->control);
+ if (DUPLEX_FULL == phydev->duplex) {
+ reg |= MAC_FULL_DUPLEX;
+ reg &= ~MAC_DISABLE_RX_OWN;
+ } else {
+ reg &= ~MAC_FULL_DUPLEX;
+ reg |= MAC_DISABLE_RX_OWN;
+ }
+ writel(reg, &aup->mac->control);
+ au_sync_delay(1);
+
+ au1000_enable_rx_tx(dev);
+ aup->old_duplex = phydev->duplex;
+
+ status_change = 1;
+ }
+
+ if (phydev->link != aup->old_link) {
+ /* link state changed */
+
+ if (!phydev->link) {
+ /* link went down */
+ aup->old_speed = 0;
+ aup->old_duplex = -1;
+ }
+
+ aup->old_link = phydev->link;
+ status_change = 1;
+ }
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+
+ if (status_change) {
+ if (phydev->link)
+ netdev_info(dev, "link up (%d/%s)\n",
+ phydev->speed,
+ DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
+ else
+ netdev_info(dev, "link down\n");
+ }
+}
+
+static int au1000_mii_probe(struct net_device *dev)
+{
+ struct au1000_private *const aup = netdev_priv(dev);
+ struct phy_device *phydev = NULL;
+ int phy_addr;
+
+ if (aup->phy_static_config) {
+ BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
+
+ if (aup->phy_addr)
+ phydev = aup->mii_bus->phy_map[aup->phy_addr];
+ else
+ netdev_info(dev, "using PHY-less setup\n");
+ return 0;
+ }
+
+ /* find the first (lowest address) PHY
+ * on the current MAC's MII bus
+ */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
+ if (aup->mii_bus->phy_map[phy_addr]) {
+ phydev = aup->mii_bus->phy_map[phy_addr];
+ if (!aup->phy_search_highest_addr)
+ /* break out with first one found */
+ break;
+ }
+
+ if (aup->phy1_search_mac0) {
+ /* try harder to find a PHY */
+ if (!phydev && (aup->mac_id == 1)) {
+ /* no PHY found, maybe we have a dual PHY? */
+ dev_info(&dev->dev, ": no PHY found on MAC1, "
+ "let's see if it's attached to MAC0...\n");
+
+ /* find the first (lowest address) non-attached
+ * PHY on the MAC0 MII bus
+ */
+ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+ struct phy_device *const tmp_phydev =
+ aup->mii_bus->phy_map[phy_addr];
+
+ if (aup->mac_id == 1)
+ break;
+
+ /* no PHY here... */
+ if (!tmp_phydev)
+ continue;
+
+ /* already claimed by MAC0 */
+ if (tmp_phydev->attached_dev)
+ continue;
+
+ phydev = tmp_phydev;
+ break; /* found it */
+ }
+ }
+ }
+
+ if (!phydev) {
+ netdev_err(dev, "no PHY found\n");
+ return -1;
+ }
+
+ /* now we are supposed to have a proper phydev, to attach to... */
+ BUG_ON(phydev->attached_dev);
+
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
+ &au1000_adjust_link, PHY_INTERFACE_MODE_MII);
+
+ if (IS_ERR(phydev)) {
+ netdev_err(dev, "Could not attach to PHY\n");
+ return PTR_ERR(phydev);
+ }
+
+ /* mask with MAC supported features */
+ phydev->supported &= (SUPPORTED_10baseT_Half
+ | SUPPORTED_10baseT_Full
+ | SUPPORTED_100baseT_Half
+ | SUPPORTED_100baseT_Full
+ | SUPPORTED_Autoneg
+ /* | SUPPORTED_Pause | SUPPORTED_Asym_Pause */
+ | SUPPORTED_MII
+ | SUPPORTED_TP);
+
+ phydev->advertising = phydev->supported;
+
+ aup->old_link = 0;
+ aup->old_speed = 0;
+ aup->old_duplex = -1;
+ aup->phy_dev = phydev;
+
+ netdev_info(dev, "attached PHY driver [%s] "
+ "(mii_bus:phy_addr=%s, irq=%d)\n",
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
+
+ return 0;
+}
+
+
+/*
+ * Buffer allocation/deallocation routines. The buffer descriptor returned
+ * has the virtual and dma address of a buffer suitable for
+ * both, receive and transmit operations.
+ */
+static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup)
+{
+ struct db_dest *pDB;
+ pDB = aup->pDBfree;
+
+ if (pDB)
+ aup->pDBfree = pDB->pnext;
+
+ return pDB;
+}
+
+void au1000_ReleaseDB(struct au1000_private *aup, struct db_dest *pDB)
+{
+ struct db_dest *pDBfree = aup->pDBfree;
+ if (pDBfree)
+ pDBfree->pnext = pDB;
+ aup->pDBfree = pDB;
+}
+
+static void au1000_reset_mac_unlocked(struct net_device *dev)
+{
+ struct au1000_private *const aup = netdev_priv(dev);
+ int i;
+
+ au1000_hard_stop(dev);
+
+ writel(MAC_EN_CLOCK_ENABLE, aup->enable);
+ au_sync_delay(2);
+ writel(0, aup->enable);
+ au_sync_delay(2);
+
+ aup->tx_full = 0;
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ /* reset control bits */
+ aup->rx_dma_ring[i]->buff_stat &= ~0xf;
+ }
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ /* reset control bits */
+ aup->tx_dma_ring[i]->buff_stat &= ~0xf;
+ }
+
+ aup->mac_enabled = 0;
+
+}
+
+static void au1000_reset_mac(struct net_device *dev)
+{
+ struct au1000_private *const aup = netdev_priv(dev);
+ unsigned long flags;
+
+ netif_dbg(aup, hw, dev, "reset mac, aup %x\n",
+ (unsigned)aup);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ au1000_reset_mac_unlocked(dev);
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+}
+
+/*
+ * Setup the receive and transmit "rings". These pointers are the addresses
+ * of the rx and tx MAC DMA registers so they are fixed by the hardware --
+ * these are not descriptors sitting in memory.
+ */
+static void
+au1000_setup_hw_rings(struct au1000_private *aup, void __iomem *tx_base)
+{
+ int i;
+
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ aup->rx_dma_ring[i] = (struct rx_dma *)
+ (tx_base + 0x100 + sizeof(struct rx_dma) * i);
+ }
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ aup->tx_dma_ring[i] = (struct tx_dma *)
+ (tx_base + sizeof(struct tx_dma) * i);
+ }
+}
+
+/*
+ * ethtool operations
+ */
+
+static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ if (aup->phy_dev)
+ return phy_ethtool_gset(aup->phy_dev, cmd);
+
+ return -EINVAL;
+}
+
+static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (aup->phy_dev)
+ return phy_ethtool_sset(aup->phy_dev, cmd);
+
+ return -EINVAL;
+}
+
+static void
+au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ snprintf(info->bus_info, sizeof(info->bus_info), "%s %d", DRV_NAME,
+ aup->mac_id);
+ info->regdump_len = 0;
+}
+
+static void au1000_set_msglevel(struct net_device *dev, u32 value)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ aup->msg_enable = value;
+}
+
+static u32 au1000_get_msglevel(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ return aup->msg_enable;
+}
+
+static const struct ethtool_ops au1000_ethtool_ops = {
+ .get_settings = au1000_get_settings,
+ .set_settings = au1000_set_settings,
+ .get_drvinfo = au1000_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_msglevel = au1000_get_msglevel,
+ .set_msglevel = au1000_set_msglevel,
+};
+
+
+/*
+ * Initialize the interface.
+ *
+ * When the device powers up, the clocks are disabled and the
+ * mac is in reset state. When the interface is closed, we
+ * do the same -- reset the device and disable the clocks to
+ * conserve power. Thus, whenever au1000_init() is called,
+ * the device should already be in reset state.
+ */
+static int au1000_init(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ unsigned long flags;
+ int i;
+ u32 control;
+
+ netif_dbg(aup, hw, dev, "au1000_init\n");
+
+ /* bring the device out of reset */
+ au1000_enable_mac(dev, 1);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ writel(0, &aup->mac->control);
+ aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
+ aup->tx_tail = aup->tx_head;
+ aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;
+
+ writel(dev->dev_addr[5]<<8 | dev->dev_addr[4],
+ &aup->mac->mac_addr_high);
+ writel(dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
+ dev->dev_addr[1]<<8 | dev->dev_addr[0],
+ &aup->mac->mac_addr_low);
+
+
+ for (i = 0; i < NUM_RX_DMA; i++)
+ aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
+
+ au_sync();
+
+ control = MAC_RX_ENABLE | MAC_TX_ENABLE;
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+ control |= MAC_BIG_ENDIAN;
+#endif
+ if (aup->phy_dev) {
+ if (aup->phy_dev->link && (DUPLEX_FULL == aup->phy_dev->duplex))
+ control |= MAC_FULL_DUPLEX;
+ else
+ control |= MAC_DISABLE_RX_OWN;
+ } else { /* PHY-less op, assume full-duplex */
+ control |= MAC_FULL_DUPLEX;
+ }
+
+ writel(control, &aup->mac->control);
+ writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */
+ au_sync();
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+ return 0;
+}
+
+static inline void au1000_update_rx_stats(struct net_device *dev, u32 status)
+{
+ struct net_device_stats *ps = &dev->stats;
+
+ ps->rx_packets++;
+ if (status & RX_MCAST_FRAME)
+ ps->multicast++;
+
+ if (status & RX_ERROR) {
+ ps->rx_errors++;
+ if (status & RX_MISSED_FRAME)
+ ps->rx_missed_errors++;
+ if (status & (RX_OVERLEN | RX_RUNT | RX_LEN_ERROR))
+ ps->rx_length_errors++;
+ if (status & RX_CRC_ERROR)
+ ps->rx_crc_errors++;
+ if (status & RX_COLL)
+ ps->collisions++;
+ } else
+ ps->rx_bytes += status & RX_FRAME_LEN_MASK;
+
+}
+
+/*
+ * Au1000 receive routine.
+ */
+static int au1000_rx(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct sk_buff *skb;
+ struct rx_dma *prxd;
+ u32 buff_stat, status;
+ struct db_dest *pDB;
+ u32 frmlen;
+
+ netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head);
+
+ prxd = aup->rx_dma_ring[aup->rx_head];
+ buff_stat = prxd->buff_stat;
+ while (buff_stat & RX_T_DONE) {
+ status = prxd->status;
+ pDB = aup->rx_db_inuse[aup->rx_head];
+ au1000_update_rx_stats(dev, status);
+ if (!(status & RX_ERROR)) {
+
+ /* good frame */
+ frmlen = (status & RX_FRAME_LEN_MASK);
+ frmlen -= 4; /* Remove FCS */
+ skb = netdev_alloc_skb(dev, frmlen + 2);
+ if (skb == NULL) {
+ dev->stats.rx_dropped++;
+ continue;
+ }
+ skb_reserve(skb, 2); /* 16 byte IP header align */
+ skb_copy_to_linear_data(skb,
+ (unsigned char *)pDB->vaddr, frmlen);
+ skb_put(skb, frmlen);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb); /* pass the packet to upper layers */
+ } else {
+ if (au1000_debug > 4) {
+ pr_err("rx_error(s):");
+ if (status & RX_MISSED_FRAME)
+ pr_cont(" miss");
+ if (status & RX_WDOG_TIMER)
+ pr_cont(" wdog");
+ if (status & RX_RUNT)
+ pr_cont(" runt");
+ if (status & RX_OVERLEN)
+ pr_cont(" overlen");
+ if (status & RX_COLL)
+ pr_cont(" coll");
+ if (status & RX_MII_ERROR)
+ pr_cont(" mii error");
+ if (status & RX_CRC_ERROR)
+ pr_cont(" crc error");
+ if (status & RX_LEN_ERROR)
+ pr_cont(" len error");
+ if (status & RX_U_CNTRL_FRAME)
+ pr_cont(" u control frame");
+ pr_cont("\n");
+ }
+ }
+ prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
+ aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
+ au_sync();
+
+ /* next descriptor */
+ prxd = aup->rx_dma_ring[aup->rx_head];
+ buff_stat = prxd->buff_stat;
+ }
+ return 0;
+}
+
+static void au1000_update_tx_stats(struct net_device *dev, u32 status)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct net_device_stats *ps = &dev->stats;
+
+ if (status & TX_FRAME_ABORTED) {
+ if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
+ if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
+ /* any other tx errors are only valid
+ * in half duplex mode
+ */
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
+ }
+ } else {
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
+ if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
+ ps->tx_carrier_errors++;
+ }
+ }
+}
+
+/*
+ * Called from the interrupt service routine to acknowledge
+ * the TX DONE bits. This is a must if the irq is setup as
+ * edge triggered.
+ */
+static void au1000_tx_ack(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct tx_dma *ptxd;
+
+ ptxd = aup->tx_dma_ring[aup->tx_tail];
+
+ while (ptxd->buff_stat & TX_T_DONE) {
+ au1000_update_tx_stats(dev, ptxd->status);
+ ptxd->buff_stat &= ~TX_T_DONE;
+ ptxd->len = 0;
+ au_sync();
+
+ aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
+ ptxd = aup->tx_dma_ring[aup->tx_tail];
+
+ if (aup->tx_full) {
+ aup->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+ }
+}
+
+/*
+ * Au1000 interrupt service routine.
+ */
+static irqreturn_t au1000_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+
+ /* Handle RX interrupts first to minimize chance of overrun */
+
+ au1000_rx(dev);
+ au1000_tx_ack(dev);
+ return IRQ_RETVAL(1);
+}
+
+static int au1000_open(struct net_device *dev)
+{
+ int retval;
+ struct au1000_private *aup = netdev_priv(dev);
+
+ netif_dbg(aup, drv, dev, "open: dev=%p\n", dev);
+
+ retval = request_irq(dev->irq, au1000_interrupt, 0,
+ dev->name, dev);
+ if (retval) {
+ netdev_err(dev, "unable to get IRQ %d\n", dev->irq);
+ return retval;
+ }
+
+ retval = au1000_init(dev);
+ if (retval) {
+ netdev_err(dev, "error in au1000_init\n");
+ free_irq(dev->irq, dev);
+ return retval;
+ }
+
+ if (aup->phy_dev) {
+ /* cause the PHY state machine to schedule a link state check */
+ aup->phy_dev->state = PHY_CHANGELINK;
+ phy_start(aup->phy_dev);
+ }
+
+ netif_start_queue(dev);
+
+ netif_dbg(aup, drv, dev, "open: Initialization done.\n");
+
+ return 0;
+}
+
+static int au1000_close(struct net_device *dev)
+{
+ unsigned long flags;
+ struct au1000_private *const aup = netdev_priv(dev);
+
+ netif_dbg(aup, drv, dev, "close: dev=%p\n", dev);
+
+ if (aup->phy_dev)
+ phy_stop(aup->phy_dev);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ au1000_reset_mac_unlocked(dev);
+
+ /* stop the device */
+ netif_stop_queue(dev);
+
+ /* disable the interrupt */
+ free_irq(dev->irq, dev);
+ spin_unlock_irqrestore(&aup->lock, flags);
+
+ return 0;
+}
+
+/*
+ * Au1000 transmit routine.
+ */
+static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct net_device_stats *ps = &dev->stats;
+ struct tx_dma *ptxd;
+ u32 buff_stat;
+ struct db_dest *pDB;
+ int i;
+
+ netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n",
+ (unsigned)aup, skb->len,
+ skb->data, aup->tx_head);
+
+ ptxd = aup->tx_dma_ring[aup->tx_head];
+ buff_stat = ptxd->buff_stat;
+ if (buff_stat & TX_DMA_ENABLE) {
+ /* We've wrapped around and the transmitter is still busy */
+ netif_stop_queue(dev);
+ aup->tx_full = 1;
+ return NETDEV_TX_BUSY;
+ } else if (buff_stat & TX_T_DONE) {
+ au1000_update_tx_stats(dev, ptxd->status);
+ ptxd->len = 0;
+ }
+
+ if (aup->tx_full) {
+ aup->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+
+ pDB = aup->tx_db_inuse[aup->tx_head];
+ skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
+ if (skb->len < ETH_ZLEN) {
+ for (i = skb->len; i < ETH_ZLEN; i++)
+ ((char *)pDB->vaddr)[i] = 0;
+
+ ptxd->len = ETH_ZLEN;
+ } else
+ ptxd->len = skb->len;
+
+ ps->tx_packets++;
+ ps->tx_bytes += ptxd->len;
+
+ ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
+ au_sync();
+ dev_kfree_skb(skb);
+ aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
+ return NETDEV_TX_OK;
+}
+
+/*
+ * The Tx ring has been full longer than the watchdog timeout
+ * value. The transmitter must be hung?
+ */
+static void au1000_tx_timeout(struct net_device *dev)
+{
+ netdev_err(dev, "au1000_tx_timeout: dev=%p\n", dev);
+ au1000_reset_mac(dev);
+ au1000_init(dev);
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ netif_wake_queue(dev);
+}
+
+static void au1000_multicast_list(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ u32 reg;
+
+ netif_dbg(aup, drv, dev, "%s: flags=%x\n", __func__, dev->flags);
+ reg = readl(&aup->mac->control);
+ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+ reg |= MAC_PROMISCUOUS;
+ } else if ((dev->flags & IFF_ALLMULTI) ||
+ netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) {
+ reg |= MAC_PASS_ALL_MULTI;
+ reg &= ~MAC_PROMISCUOUS;
+ netdev_info(dev, "Pass all multicast\n");
+ } else {
+ struct netdev_hw_addr *ha;
+ u32 mc_filter[2]; /* Multicast hash filter */
+
+ mc_filter[1] = mc_filter[0] = 0;
+ netdev_for_each_mc_addr(ha, dev)
+ set_bit(ether_crc(ETH_ALEN, ha->addr)>>26,
+ (long *)mc_filter);
+ writel(mc_filter[1], &aup->mac->multi_hash_high);
+ writel(mc_filter[0], &aup->mac->multi_hash_low);
+ reg &= ~MAC_PROMISCUOUS;
+ reg |= MAC_HASH_MODE;
+ }
+ writel(reg, &aup->mac->control);
+}
+
+static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (!aup->phy_dev)
+ return -EINVAL; /* PHY not controllable */
+
+ return phy_mii_ioctl(aup->phy_dev, rq, cmd);
+}
+
+static const struct net_device_ops au1000_netdev_ops = {
+ .ndo_open = au1000_open,
+ .ndo_stop = au1000_close,
+ .ndo_start_xmit = au1000_tx,
+ .ndo_set_rx_mode = au1000_multicast_list,
+ .ndo_do_ioctl = au1000_ioctl,
+ .ndo_tx_timeout = au1000_tx_timeout,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
+
+static int au1000_probe(struct platform_device *pdev)
+{
+ static unsigned version_printed;
+ struct au1000_private *aup = NULL;
+ struct au1000_eth_platform_data *pd;
+ struct net_device *dev = NULL;
+ struct db_dest *pDB, *pDBfree;
+ int irq, i, err = 0;
+ struct resource *base, *macen, *macdma;
+
+ base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!base) {
+ dev_err(&pdev->dev, "failed to retrieve base register\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!macen) {
+ dev_err(&pdev->dev, "failed to retrieve MAC Enable register\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to retrieve IRQ\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ macdma = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (!macdma) {
+ dev_err(&pdev->dev, "failed to retrieve MACDMA registers\n");
+ err = -ENODEV;
+ goto out;
+ }
+
+ if (!request_mem_region(base->start, resource_size(base),
+ pdev->name)) {
+ dev_err(&pdev->dev, "failed to request memory region for base registers\n");
+ err = -ENXIO;
+ goto out;
+ }
+
+ if (!request_mem_region(macen->start, resource_size(macen),
+ pdev->name)) {
+ dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n");
+ err = -ENXIO;
+ goto err_request;
+ }
+
+ if (!request_mem_region(macdma->start, resource_size(macdma),
+ pdev->name)) {
+ dev_err(&pdev->dev, "failed to request MACDMA memory region\n");
+ err = -ENXIO;
+ goto err_macdma;
+ }
+
+ dev = alloc_etherdev(sizeof(struct au1000_private));
+ if (!dev) {
+ err = -ENOMEM;
+ goto err_alloc;
+ }
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ platform_set_drvdata(pdev, dev);
+ aup = netdev_priv(dev);
+
+ spin_lock_init(&aup->lock);
+ aup->msg_enable = (au1000_debug < 4 ?
+ AU1000_DEF_MSG_ENABLE : au1000_debug);
+
+ /* Allocate the data buffers
+ * Snooping works fine with eth on all au1xxx
+ */
+ aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ &aup->dma_addr, 0);
+ if (!aup->vaddr) {
+ dev_err(&pdev->dev, "failed to allocate data buffers\n");
+ err = -ENOMEM;
+ goto err_vaddr;
+ }
+
+ /* aup->mac is the base address of the MAC's registers */
+ aup->mac = (struct mac_reg *)
+ ioremap_nocache(base->start, resource_size(base));
+ if (!aup->mac) {
+ dev_err(&pdev->dev, "failed to ioremap MAC registers\n");
+ err = -ENXIO;
+ goto err_remap1;
+ }
+
+ /* Setup some variables for quick register address access */
+ aup->enable = (u32 *)ioremap_nocache(macen->start,
+ resource_size(macen));
+ if (!aup->enable) {
+ dev_err(&pdev->dev, "failed to ioremap MAC enable register\n");
+ err = -ENXIO;
+ goto err_remap2;
+ }
+ aup->mac_id = pdev->id;
+
+ aup->macdma = ioremap_nocache(macdma->start, resource_size(macdma));
+ if (!aup->macdma) {
+ dev_err(&pdev->dev, "failed to ioremap MACDMA registers\n");
+ err = -ENXIO;
+ goto err_remap3;
+ }
+
+ au1000_setup_hw_rings(aup, aup->macdma);
+
+ writel(0, aup->enable);
+ aup->mac_enabled = 0;
+
+ pd = dev_get_platdata(&pdev->dev);
+ if (!pd) {
+ dev_info(&pdev->dev, "no platform_data passed,"
+ " PHY search on MAC0\n");
+ aup->phy1_search_mac0 = 1;
+ } else {
+ if (is_valid_ether_addr(pd->mac)) {
+ memcpy(dev->dev_addr, pd->mac, ETH_ALEN);
+ } else {
+ /* Set a random MAC since no valid provided by platform_data. */
+ eth_hw_addr_random(dev);
+ }
+
+ aup->phy_static_config = pd->phy_static_config;
+ aup->phy_search_highest_addr = pd->phy_search_highest_addr;
+ aup->phy1_search_mac0 = pd->phy1_search_mac0;
+ aup->phy_addr = pd->phy_addr;
+ aup->phy_busid = pd->phy_busid;
+ aup->phy_irq = pd->phy_irq;
+ }
+
+ if (aup->phy_busid && aup->phy_busid > 0) {
+ dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII bus not supported yet\n");
+ err = -ENODEV;
+ goto err_mdiobus_alloc;
+ }
+
+ aup->mii_bus = mdiobus_alloc();
+ if (aup->mii_bus == NULL) {
+ dev_err(&pdev->dev, "failed to allocate mdiobus structure\n");
+ err = -ENOMEM;
+ goto err_mdiobus_alloc;
+ }
+
+ aup->mii_bus->priv = dev;
+ aup->mii_bus->read = au1000_mdiobus_read;
+ aup->mii_bus->write = au1000_mdiobus_write;
+ aup->mii_bus->reset = au1000_mdiobus_reset;
+ aup->mii_bus->name = "au1000_eth_mii";
+ snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ pdev->name, aup->mac_id);
+ aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+ if (aup->mii_bus->irq == NULL) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ for (i = 0; i < PHY_MAX_ADDR; ++i)
+ aup->mii_bus->irq[i] = PHY_POLL;
+ /* if known, set corresponding PHY IRQs */
+ if (aup->phy_static_config)
+ if (aup->phy_irq && aup->phy_busid == aup->mac_id)
+ aup->mii_bus->irq[aup->phy_addr] = aup->phy_irq;
+
+ err = mdiobus_register(aup->mii_bus);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register MDIO bus\n");
+ goto err_mdiobus_reg;
+ }
+
+ err = au1000_mii_probe(dev);
+ if (err != 0)
+ goto err_out;
+
+ pDBfree = NULL;
+ /* setup the data buffer descriptors and attach a buffer to each one */
+ pDB = aup->db;
+ for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
+ pDB->pnext = pDBfree;
+ pDBfree = pDB;
+ pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
+ pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+ pDB++;
+ }
+ aup->pDBfree = pDBfree;
+
+ err = -ENODEV;
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ pDB = au1000_GetFreeDB(aup);
+ if (!pDB)
+ goto err_out;
+
+ aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ aup->rx_db_inuse[i] = pDB;
+ }
+
+ err = -ENODEV;
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ pDB = au1000_GetFreeDB(aup);
+ if (!pDB)
+ goto err_out;
+
+ aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ aup->tx_dma_ring[i]->len = 0;
+ aup->tx_db_inuse[i] = pDB;
+ }
+
+ dev->base_addr = base->start;
+ dev->irq = irq;
+ dev->netdev_ops = &au1000_netdev_ops;
+ dev->ethtool_ops = &au1000_ethtool_ops;
+ dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+ /*
+ * The boot code uses the ethernet controller, so reset it to start
+ * fresh. au1000_init() expects that the device is in reset state.
+ */
+ au1000_reset_mac(dev);
+
+ err = register_netdev(dev);
+ if (err) {
+ netdev_err(dev, "Cannot register net device, aborting.\n");
+ goto err_out;
+ }
+
+ netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n",
+ (unsigned long)base->start, irq);
+ if (version_printed++ == 0)
+ pr_info("%s version %s %s\n",
+ DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+
+ return 0;
+
+err_out:
+ if (aup->mii_bus != NULL)
+ mdiobus_unregister(aup->mii_bus);
+
+ /* here we should have a valid dev plus aup-> register addresses
+ * so we can reset the mac properly.
+ */
+ au1000_reset_mac(dev);
+
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ if (aup->rx_db_inuse[i])
+ au1000_ReleaseDB(aup, aup->rx_db_inuse[i]);
+ }
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ if (aup->tx_db_inuse[i])
+ au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
+ }
+err_mdiobus_reg:
+ mdiobus_free(aup->mii_bus);
+err_mdiobus_alloc:
+ iounmap(aup->macdma);
+err_remap3:
+ iounmap(aup->enable);
+err_remap2:
+ iounmap(aup->mac);
+err_remap1:
+ dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr);
+err_vaddr:
+ free_netdev(dev);
+err_alloc:
+ release_mem_region(macdma->start, resource_size(macdma));
+err_macdma:
+ release_mem_region(macen->start, resource_size(macen));
+err_request:
+ release_mem_region(base->start, resource_size(base));
+out:
+ return err;
+}
+
+static int au1000_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct au1000_private *aup = netdev_priv(dev);
+ int i;
+ struct resource *base, *macen;
+
+ unregister_netdev(dev);
+ mdiobus_unregister(aup->mii_bus);
+ mdiobus_free(aup->mii_bus);
+
+ for (i = 0; i < NUM_RX_DMA; i++)
+ if (aup->rx_db_inuse[i])
+ au1000_ReleaseDB(aup, aup->rx_db_inuse[i]);
+
+ for (i = 0; i < NUM_TX_DMA; i++)
+ if (aup->tx_db_inuse[i])
+ au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
+
+ dma_free_noncoherent(NULL, MAX_BUF_SIZE *
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr);
+
+ iounmap(aup->macdma);
+ iounmap(aup->mac);
+ iounmap(aup->enable);
+
+ base = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ release_mem_region(base->start, resource_size(base));
+
+ base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(base->start, resource_size(base));
+
+ macen = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ release_mem_region(macen->start, resource_size(macen));
+
+ free_netdev(dev);
+
+ return 0;
+}
+
+static struct platform_driver au1000_eth_driver = {
+ .probe = au1000_probe,
+ .remove = au1000_remove,
+ .driver = {
+ .name = "au1000-eth",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(au1000_eth_driver);
+
+MODULE_ALIAS("platform:au1000-eth");
diff --git a/drivers/net/au1000_eth.h b/drivers/net/ethernet/amd/au1000_eth.h
index f3baeaa1285..ca53024f017 100644
--- a/drivers/net/au1000_eth.h
+++ b/drivers/net/ethernet/amd/au1000_eth.h
@@ -18,8 +18,7 @@
* for more details.
*
* You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
*
* ########################################################################
*
@@ -35,7 +34,7 @@
#define NUM_TX_BUFFS 4
#define MAX_BUF_SIZE 2048
-#define ETH_TX_TIMEOUT HZ/4
+#define ETH_TX_TIMEOUT (HZ/4)
#define MAC_MIN_PKT_SIZE 64
#define MULTICAST_FILTER_LIMIT 64
@@ -44,34 +43,34 @@
* Data Buffer Descriptor. Data buffers must be aligned on 32 byte
* boundary for both, receive and transmit.
*/
-typedef struct db_dest {
+struct db_dest {
struct db_dest *pnext;
- volatile u32 *vaddr;
+ u32 *vaddr;
dma_addr_t dma_addr;
-} db_dest_t;
+};
/*
* The transmit and receive descriptors are memory
* mapped registers.
*/
-typedef struct tx_dma {
+struct tx_dma {
u32 status;
u32 buff_stat;
u32 len;
u32 pad;
-} tx_dma_t;
+};
-typedef struct rx_dma {
+struct rx_dma {
u32 status;
u32 buff_stat;
u32 pad[2];
-} rx_dma_t;
+};
/*
* MAC control registers, memory mapped.
*/
-typedef struct mac_reg {
+struct mac_reg {
u32 control;
u32 mac_addr_high;
u32 mac_addr_low;
@@ -82,16 +81,16 @@ typedef struct mac_reg {
u32 flow_control;
u32 vlan1_tag;
u32 vlan2_tag;
-} mac_reg_t;
+};
struct au1000_private {
- db_dest_t *pDBfree;
- db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS];
- volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA];
- volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA];
- db_dest_t *rx_db_inuse[NUM_RX_DMA];
- db_dest_t *tx_db_inuse[NUM_TX_DMA];
+ struct db_dest *pDBfree;
+ struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS];
+ struct rx_dma *rx_dma_ring[NUM_RX_DMA];
+ struct tx_dma *tx_dma_ring[NUM_TX_DMA];
+ struct db_dest *rx_db_inuse[NUM_RX_DMA];
+ struct db_dest *tx_db_inuse[NUM_TX_DMA];
u32 rx_head;
u32 tx_head;
u32 tx_tail;
@@ -99,21 +98,36 @@ struct au1000_private {
int mac_id;
- int mac_enabled; /* whether MAC is currently enabled and running (req. for mdio) */
+ int mac_enabled; /* whether MAC is currently enabled and running
+ * (req. for mdio)
+ */
int old_link; /* used by au1000_adjust_link */
int old_speed;
int old_duplex;
struct phy_device *phy_dev;
- struct mii_bus mii_bus;
-
- /* These variables are just for quick access to certain regs addresses. */
- volatile mac_reg_t *mac; /* mac registers */
- volatile u32 *enable; /* address of MAC Enable Register */
-
+ struct mii_bus *mii_bus;
+
+ /* PHY configuration */
+ int phy_static_config;
+ int phy_search_highest_addr;
+ int phy1_search_mac0;
+
+ int phy_addr;
+ int phy_busid;
+ int phy_irq;
+
+ /* These variables are just for quick access
+ * to certain regs addresses.
+ */
+ struct mac_reg *mac; /* mac registers */
+ u32 *enable; /* address of MAC Enable Register */
+ void __iomem *macdma; /* base of MAC DMA port */
u32 vaddr; /* virtual address of rx/tx buffers */
dma_addr_t dma_addr; /* dma address of rx/tx buffers */
spinlock_t lock; /* Serialise access to device */
+
+ u32 msg_enable;
};
diff --git a/drivers/net/declance.c b/drivers/net/ethernet/amd/declance.c
index 3e3506411ac..57397295887 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/ethernet/amd/declance.c
@@ -64,7 +64,6 @@
#include <linux/types.h>
#include <asm/addrspace.h>
-#include <asm/system.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic.h>
@@ -73,7 +72,7 @@
#include <asm/dec/machtype.h>
#include <asm/dec/system.h>
-static char version[] __devinitdata =
+static char version[] =
"declance.c: v0.011 by Linux MIPS DECstation task force\n";
MODULE_AUTHOR("Linux MIPS DECstation task force");
@@ -326,15 +325,18 @@ static void load_csrs(struct lance_private *lp)
*/
static void cp_to_buf(const int type, void *to, const void *from, int len)
{
- unsigned short *tp, *fp, clen;
- unsigned char *rtp, *rfp;
+ unsigned short *tp;
+ const unsigned short *fp;
+ unsigned short clen;
+ unsigned char *rtp;
+ const unsigned char *rfp;
if (type == PMAD_LANCE) {
memcpy(to, from, len);
} else if (type == PMAX_LANCE) {
clen = len >> 1;
- tp = (unsigned short *) to;
- fp = (unsigned short *) from;
+ tp = to;
+ fp = from;
while (clen--) {
*tp++ = *fp++;
@@ -342,8 +344,8 @@ static void cp_to_buf(const int type, void *to, const void *from, int len)
}
clen = len & 1;
- rtp = (unsigned char *) tp;
- rfp = (unsigned char *) fp;
+ rtp = (unsigned char *)tp;
+ rfp = (const unsigned char *)fp;
while (clen--) {
*rtp++ = *rfp++;
}
@@ -352,8 +354,8 @@ static void cp_to_buf(const int type, void *to, const void *from, int len)
* copy 16 Byte chunks
*/
clen = len >> 4;
- tp = (unsigned short *) to;
- fp = (unsigned short *) from;
+ tp = to;
+ fp = from;
while (clen--) {
*tp++ = *fp++;
*tp++ = *fp++;
@@ -370,8 +372,8 @@ static void cp_to_buf(const int type, void *to, const void *from, int len)
* do the rest, if any.
*/
clen = len & 15;
- rtp = (unsigned char *) tp;
- rfp = (unsigned char *) fp;
+ rtp = (unsigned char *)tp;
+ rfp = (const unsigned char *)fp;
while (clen--) {
*rtp++ = *rfp++;
}
@@ -382,15 +384,18 @@ static void cp_to_buf(const int type, void *to, const void *from, int len)
static void cp_from_buf(const int type, void *to, const void *from, int len)
{
- unsigned short *tp, *fp, clen;
- unsigned char *rtp, *rfp;
+ unsigned short *tp;
+ const unsigned short *fp;
+ unsigned short clen;
+ unsigned char *rtp;
+ const unsigned char *rfp;
if (type == PMAD_LANCE) {
memcpy(to, from, len);
} else if (type == PMAX_LANCE) {
clen = len >> 1;
- tp = (unsigned short *) to;
- fp = (unsigned short *) from;
+ tp = to;
+ fp = from;
while (clen--) {
*tp++ = *fp++;
fp++;
@@ -398,8 +403,8 @@ static void cp_from_buf(const int type, void *to, const void *from, int len)
clen = len & 1;
- rtp = (unsigned char *) tp;
- rfp = (unsigned char *) fp;
+ rtp = (unsigned char *)tp;
+ rfp = (const unsigned char *)fp;
while (clen--) {
*rtp++ = *rfp++;
@@ -410,8 +415,8 @@ static void cp_from_buf(const int type, void *to, const void *from, int len)
* copy 16 Byte chunks
*/
clen = len >> 4;
- tp = (unsigned short *) to;
- fp = (unsigned short *) from;
+ tp = to;
+ fp = from;
while (clen--) {
*tp++ = *fp++;
*tp++ = *fp++;
@@ -428,8 +433,8 @@ static void cp_from_buf(const int type, void *to, const void *from, int len)
* do the rest, if any.
*/
clen = len & 15;
- rtp = (unsigned char *) tp;
- rfp = (unsigned char *) fp;
+ rtp = (unsigned char *)tp;
+ rfp = (const unsigned char *)fp;
while (clen--) {
*rtp++ = *rfp++;
}
@@ -599,11 +604,9 @@ static int lance_rx(struct net_device *dev)
dev->stats.rx_errors++;
} else {
len = (*rds_ptr(rd, mblength, lp->type) & 0xfff) - 4;
- skb = dev_alloc_skb(len + 2);
+ skb = netdev_alloc_skb(dev, len + 2);
if (skb == 0) {
- printk("%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
*rds_ptr(rd, mblength, lp->type) = 0;
*rds_ptr(rd, rmd1, lp->type) =
@@ -618,11 +621,10 @@ static int lance_rx(struct net_device *dev)
skb_put(skb, len); /* make room */
cp_from_buf(lp->type, skb->data,
- (char *)lp->rx_buf_ptr_cpu[entry], len);
+ lp->rx_buf_ptr_cpu[entry], len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
}
@@ -802,14 +804,14 @@ static int lance_open(struct net_device *dev)
netif_start_queue(dev);
/* Associate IRQ with lance_interrupt */
- if (request_irq(dev->irq, &lance_interrupt, 0, "lance", dev)) {
+ if (request_irq(dev->irq, lance_interrupt, 0, "lance", dev)) {
printk("%s: Can't get IRQ %d\n", dev->name, dev->irq);
return -EAGAIN;
}
if (lp->dma_irq >= 0) {
unsigned long flags;
- if (request_irq(lp->dma_irq, &lance_dma_merr_int, 0,
+ if (request_irq(lp->dma_irq, lance_dma_merr_int, IRQF_ONESHOT,
"lance error", dev)) {
free_irq(dev->irq, dev);
printk("%s: Can't get DMA IRQ %d\n", dev->name,
@@ -875,7 +877,7 @@ static inline int lance_reset(struct net_device *dev)
lance_init_ring(dev);
load_csrs(lp);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
status = init_restart_lance(lp);
return status;
}
@@ -896,23 +898,26 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
volatile u16 *ib = (volatile u16 *)dev->mem_start;
+ unsigned long flags;
int entry, len;
len = skb->len;
if (len < ETH_ZLEN) {
if (skb_padto(skb, ETH_ZLEN))
- return 0;
+ return NETDEV_TX_OK;
len = ETH_ZLEN;
}
dev->stats.tx_bytes += len;
+ spin_lock_irqsave(&lp->lock, flags);
+
entry = lp->tx_new;
*lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len);
*lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0;
- cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, len);
+ cp_to_buf(lp->type, lp->tx_buf_ptr_cpu[entry], skb->data, len);
/* Now, give the packet to the lance */
*lib_ptr(ib, btx_ring[entry].tmd1, lp->type) =
@@ -926,19 +931,18 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Kick the lance: transmit now */
writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD);
- dev->trans_start = jiffies;
+ spin_unlock_irqrestore(&lp->lock, flags);
+
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
static void lance_load_multicast(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
volatile u16 *ib = (volatile u16 *)dev->mem_start;
- struct dev_mc_list *dmi = dev->mc_list;
- char *addrs;
- int i;
+ struct netdev_hw_addr *ha;
u32 crc;
/* set all multicast bits */
@@ -956,19 +960,11 @@ static void lance_load_multicast(struct net_device *dev)
*lib_ptr(ib, filter[3], lp->type) = 0;
/* Add addresses */
- for (i = 0; i < dev->mc_count; i++) {
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
-
- /* multicast address? */
- if (!(*addrs & 1))
- continue;
-
- crc = ether_crc_le(ETH_ALEN, addrs);
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(ETH_ALEN, ha->addr);
crc = crc >> 26;
*lib_ptr(ib, filter[crc >> 4], lp->type) |= 1 << (crc & 0xf);
}
- return;
}
static void lance_set_multicast(struct net_device *dev)
@@ -1011,7 +1007,18 @@ static void lance_set_multicast_retry(unsigned long _opaque)
lance_set_multicast(dev);
}
-static int __init dec_lance_probe(struct device *bdev, const int type)
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_set_rx_mode = lance_set_multicast,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
+static int dec_lance_probe(struct device *bdev, const int type)
{
static unsigned version_printed;
static const char fmt[] = "declance%d";
@@ -1023,19 +1030,18 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
int i, ret;
unsigned long esar_base;
unsigned char *esar;
- DECLARE_MAC_BUF(mac);
if (dec_lance_debug && version_printed++ == 0)
printk(version);
if (bdev)
- snprintf(name, sizeof(name), "%s", bdev->bus_id);
+ snprintf(name, sizeof(name), "%s", dev_name(bdev));
else {
i = 0;
dev = root_lance_dev;
while (dev) {
i++;
- lp = (struct lance_private *)dev->priv;
+ lp = netdev_priv(dev);
dev = lp->next;
}
snprintf(name, sizeof(name), fmt, i);
@@ -1043,8 +1049,6 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
dev = alloc_etherdev(sizeof(struct lance_private));
if (!dev) {
- printk(KERN_ERR "%s: Unable to allocate etherdev, aborting.\n",
- name);
ret = -ENOMEM;
goto err_out;
}
@@ -1107,10 +1111,10 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
start = to_tc_dev(bdev)->resource.start;
len = to_tc_dev(bdev)->resource.end - start + 1;
- if (!request_mem_region(start, len, bdev->bus_id)) {
+ if (!request_mem_region(start, len, dev_name(bdev))) {
printk(KERN_ERR
"%s: Unable to reserve MMIO resource\n",
- bdev->bus_id);
+ dev_name(bdev));
ret = -EBUSY;
goto err_out_dev;
}
@@ -1223,15 +1227,10 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
for (i = 0; i < 6; i++)
dev->dev_addr[i] = esar[i * 4];
- printk(", addr = %s, irq = %d\n",
- print_mac(mac, dev->dev_addr), dev->irq);
+ printk(", addr = %pM, irq = %d\n", dev->dev_addr, dev->irq);
- dev->open = &lance_open;
- dev->stop = &lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->tx_timeout = &lance_tx_timeout;
+ dev->netdev_ops = &lance_netdev_ops;
dev->watchdog_timeo = 5*HZ;
- dev->set_multicast_list = &lance_set_multicast;
/* lp->ll is the location of the registers for lance card */
lp->ll = ll;
@@ -1250,7 +1249,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
*/
init_timer(&lp->multicast_timer);
lp->multicast_timer.data = (unsigned long) dev;
- lp->multicast_timer.function = &lance_set_multicast_retry;
+ lp->multicast_timer.function = lance_set_multicast_retry;
ret = register_netdev(dev);
if (ret) {
@@ -1321,7 +1320,7 @@ static void __exit dec_lance_platform_remove(void)
}
#ifdef CONFIG_TC
-static int __init dec_lance_tc_probe(struct device *dev);
+static int dec_lance_tc_probe(struct device *dev);
static int __exit dec_lance_tc_remove(struct device *dev);
static const struct tc_device_id dec_lance_tc_table[] = {
@@ -1340,7 +1339,7 @@ static struct tc_driver dec_lance_tc_driver = {
},
};
-static int __init dec_lance_tc_probe(struct device *dev)
+static int dec_lance_tc_probe(struct device *dev)
{
int status = dec_lance_probe(dev, PMAD_LANCE);
if (!status)
diff --git a/drivers/net/hplance.c b/drivers/net/ethernet/amd/hplance.c
index 2e802634d36..6c9de117ffc 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/ethernet/amd/hplance.c
@@ -10,7 +10,6 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -23,15 +22,14 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include "hplance.h"
-/* We have 16834 bytes of RAM for the init block and buffers. This places
+/* We have 16392 bytes of RAM for the init block and buffers. This places
* an upper limit on the number of buffers we can use. NetBSD uses 8 Rx
- * buffers and 2 Tx buffers.
+ * buffers and 2 Tx buffers, it takes (8 + 2) * 1544 bytes.
*/
#define LANCE_LOG_TX_BUFFERS 1
#define LANCE_LOG_RX_BUFFERS 3
@@ -48,11 +46,9 @@ struct hplance_private {
* plus board-specific init, open and close actions.
* Oh, and we need to tell the generic code how to read and write LANCE registers...
*/
-static int __devinit hplance_init_one(struct dio_dev *d,
- const struct dio_device_id *ent);
-static void __devinit hplance_init(struct net_device *dev,
- struct dio_dev *d);
-static void __devexit hplance_remove_one(struct dio_dev *d);
+static int hplance_init_one(struct dio_dev *d, const struct dio_device_id *ent);
+static void hplance_init(struct net_device *dev, struct dio_dev *d);
+static void hplance_remove_one(struct dio_dev *d);
static void hplance_writerap(void *priv, unsigned short value);
static void hplance_writerdp(void *priv, unsigned short value);
static unsigned short hplance_readrdp(void *priv);
@@ -68,16 +64,27 @@ static struct dio_driver hplance_driver = {
.name = "hplance",
.id_table = hplance_dio_tbl,
.probe = hplance_init_one,
- .remove = __devexit_p(hplance_remove_one),
+ .remove = hplance_remove_one,
+};
+
+static const struct net_device_ops hplance_netdev_ops = {
+ .ndo_open = hplance_open,
+ .ndo_stop = hplance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_rx_mode = lance_set_multicast,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = lance_poll,
+#endif
};
/* Find all the HP Lance boards and initialise them... */
-static int __devinit hplance_init_one(struct dio_dev *d,
- const struct dio_device_id *ent)
+static int hplance_init_one(struct dio_dev *d, const struct dio_device_id *ent)
{
struct net_device *dev;
int err = -ENOMEM;
- int i;
dev = alloc_etherdev(sizeof(struct hplance_private));
if (!dev)
@@ -95,13 +102,8 @@ static int __devinit hplance_init_one(struct dio_dev *d,
dio_set_drvdata(d, dev);
- printk(KERN_INFO "%s: %s; select code %d, addr %2.2x", dev->name, d->name, d->scode, dev->dev_addr[0]);
-
- for (i=1; i<6; i++) {
- printk(":%2.2x", dev->dev_addr[i]);
- }
-
- printk(", irq %d\n", d->ipl);
+ printk(KERN_INFO "%s: %s; select code %d, addr %pM, irq %d\n",
+ dev->name, d->name, d->scode, dev->dev_addr, d->ipl);
return 0;
@@ -113,7 +115,7 @@ static int __devinit hplance_init_one(struct dio_dev *d,
return err;
}
-static void __devexit hplance_remove_one(struct dio_dev *d)
+static void hplance_remove_one(struct dio_dev *d)
{
struct net_device *dev = dio_get_drvdata(d);
@@ -123,49 +125,43 @@ static void __devexit hplance_remove_one(struct dio_dev *d)
}
/* Initialise a single lance board at the given DIO device */
-static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
+static void hplance_init(struct net_device *dev, struct dio_dev *d)
{
- unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
- struct hplance_private *lp;
- int i;
-
- /* reset the board */
- out_8(va+DIO_IDOFF, 0xff);
- udelay(100); /* ariba! ariba! udelay! udelay! */
-
- /* Fill the dev fields */
- dev->base_addr = va;
- dev->open = &hplance_open;
- dev->stop = &hplance_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = lance_poll;
-#endif
- dev->hard_start_xmit = &lance_start_xmit;
- dev->set_multicast_list = &lance_set_multicast;
- dev->dma = 0;
-
- for (i=0; i<6; i++) {
- /* The NVRAM holds our ethernet address, one nibble per byte,
- * at bytes NVRAMOFF+1,3,5,7,9...
- */
- dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
- | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
- }
-
- lp = netdev_priv(dev);
- lp->lance.name = (char*)d->name; /* discards const, shut up gcc */
- lp->lance.base = va;
- lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */
- lp->lance.lance_init_block = NULL; /* LANCE addr of same RAM */
- lp->lance.busmaster_regval = LE_C3_BSWP; /* we're bigendian */
- lp->lance.irq = d->ipl;
- lp->lance.writerap = hplance_writerap;
- lp->lance.writerdp = hplance_writerdp;
- lp->lance.readrdp = hplance_readrdp;
- lp->lance.lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
- lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
- lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
- lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
+ unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
+ struct hplance_private *lp;
+ int i;
+
+ /* reset the board */
+ out_8(va + DIO_IDOFF, 0xff);
+ udelay(100); /* ariba! ariba! udelay! udelay! */
+
+ /* Fill the dev fields */
+ dev->base_addr = va;
+ dev->netdev_ops = &hplance_netdev_ops;
+ dev->dma = 0;
+
+ for (i = 0; i < 6; i++) {
+ /* The NVRAM holds our ethernet address, one nibble per byte,
+ * at bytes NVRAMOFF+1,3,5,7,9...
+ */
+ dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
+ | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
+ }
+
+ lp = netdev_priv(dev);
+ lp->lance.name = d->name;
+ lp->lance.base = va;
+ lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */
+ lp->lance.lance_init_block = NULL; /* LANCE addr of same RAM */
+ lp->lance.busmaster_regval = LE_C3_BSWP; /* we're bigendian */
+ lp->lance.irq = d->ipl;
+ lp->lance.writerap = hplance_writerap;
+ lp->lance.writerdp = hplance_writerdp;
+ lp->lance.readrdp = hplance_readrdp;
+ lp->lance.lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
+ lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
+ lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
+ lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
}
/* This is disgusting. We have to check the DIO status register for ack every
@@ -199,25 +195,25 @@ static unsigned short hplance_readrdp(void *priv)
static int hplance_open(struct net_device *dev)
{
- int status;
- struct lance_private *lp = netdev_priv(dev);
+ int status;
+ struct lance_private *lp = netdev_priv(dev);
- status = lance_open(dev); /* call generic lance open code */
- if (status)
- return status;
- /* enable interrupts at board level. */
- out_8(lp->base + HPLANCE_STATUS, LE_IE);
+ status = lance_open(dev); /* call generic lance open code */
+ if (status)
+ return status;
+ /* enable interrupts at board level. */
+ out_8(lp->base + HPLANCE_STATUS, LE_IE);
- return 0;
+ return 0;
}
static int hplance_close(struct net_device *dev)
{
- struct lance_private *lp = netdev_priv(dev);
+ struct lance_private *lp = netdev_priv(dev);
- out_8(lp->base + HPLANCE_STATUS, 0); /* disable interrupts at boardlevel */
- lance_close(dev);
- return 0;
+ out_8(lp->base + HPLANCE_STATUS, 0); /* disable interrupts at boardlevel */
+ lance_close(dev);
+ return 0;
}
static int __init hplance_init_module(void)
@@ -227,7 +223,7 @@ static int __init hplance_init_module(void)
static void __exit hplance_cleanup_module(void)
{
- dio_unregister_driver(&hplance_driver);
+ dio_unregister_driver(&hplance_driver);
}
module_init(hplance_init_module);
diff --git a/drivers/net/hplance.h b/drivers/net/ethernet/amd/hplance.h
index 04aee9e0376..04aee9e0376 100644
--- a/drivers/net/hplance.h
+++ b/drivers/net/ethernet/amd/hplance.h
diff --git a/drivers/net/lance.c b/drivers/net/ethernet/amd/lance.c
index 977ed3401bb..256f590f6bb 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/ethernet/amd/lance.c
@@ -207,7 +207,7 @@ tx_full and tbusy flags.
#define LANCE_BUS_IF 0x16
#define LANCE_TOTAL_SIZE 0x18
-#define TX_TIMEOUT 20
+#define TX_TIMEOUT (HZ/5)
/* The LANCE Rx and Tx ring descriptors. */
struct lance_rx_head {
@@ -248,7 +248,6 @@ struct lance_private {
int cur_rx, cur_tx; /* The next free ring entry */
int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
int dma;
- struct net_device_stats stats;
unsigned char chip_version; /* See lance_chip_type. */
spinlock_t devlock;
};
@@ -300,7 +299,8 @@ static unsigned char lance_need_isa_bounce_buffers = 1;
static int lance_open(struct net_device *dev);
static void lance_init_ring(struct net_device *dev, gfp_t mode);
-static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
static int lance_rx(struct net_device *dev);
static irqreturn_t lance_interrupt(int irq, void *dev_id);
static int lance_close(struct net_device *dev);
@@ -359,7 +359,7 @@ int __init init_module(void)
static void cleanup_card(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
if (dev->dma != 4)
free_dma(dev->dma);
release_region(dev->base_addr, LANCE_TOTAL_SIZE);
@@ -391,7 +391,8 @@ MODULE_LICENSE("GPL");
*/
static int __init do_lance_probe(struct net_device *dev)
{
- int *port, result;
+ unsigned int *port;
+ int result;
if (high_memory <= phys_to_virt(16*1024*1024))
lance_need_isa_bounce_buffers = 0;
@@ -418,7 +419,7 @@ static int __init do_lance_probe(struct net_device *dev)
if (card < NUM_CARDS) { /*Signature OK*/
result = lance_probe1(dev, ioaddr, 0, 0);
if (!result) {
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int ver = lp->chip_version;
r->name = chip_table[ver].name;
@@ -453,20 +454,31 @@ out:
}
#endif
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_stop = lance_close,
+ .ndo_get_stats = lance_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
{
struct lance_private *lp;
- long dma_channels; /* Mark spuriously-busy DMA channels */
+ unsigned long dma_channels; /* Mark spuriously-busy DMA channels */
int i, reset_val, lance_version;
const char *chipname;
/* Flags for specific chips or boards. */
- unsigned char hpJ2405A = 0; /* HP ISA adaptor */
- int hp_builtin = 0; /* HP on-board ethernet. */
- static int did_version; /* Already printed version info. */
+ unsigned char hpJ2405A = 0; /* HP ISA adaptor */
+ int hp_builtin = 0; /* HP on-board ethernet. */
+ static int did_version; /* Already printed version info. */
unsigned long flags;
int err = -ENOMEM;
void __iomem *bios;
- DECLARE_MAC_BUF(mac);
/* First we look for special cases.
Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
@@ -480,14 +492,14 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
static const short ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360};
int hp_port = (readl(bios + 1) & 1) ? 0x499 : 0x99;
/* We can have boards other than the built-in! Verify this is on-board. */
- if ((inb(hp_port) & 0xc0) == 0x80
- && ioaddr_table[inb(hp_port) & 3] == ioaddr)
+ if ((inb(hp_port) & 0xc0) == 0x80 &&
+ ioaddr_table[inb(hp_port) & 3] == ioaddr)
hp_builtin = hp_port;
}
iounmap(bios);
/* We also recognize the HP Vectra on-board here, but check below. */
- hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
- && inb(ioaddr+2) == 0x09);
+ hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00 &&
+ inb(ioaddr+2) == 0x09);
/* Reset the LANCE. */
reset_val = inw(ioaddr+LANCE_RESET); /* Reset the LANCE */
@@ -520,7 +532,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
}
}
- /* We can't allocate dev->priv from alloc_etherdev() because it must
+ /* We can't allocate private data from alloc_etherdev() because it must
a ISA DMA-able region. */
chipname = chip_table[lance_version].name;
printk("%s: %s at %#3x, ", dev->name, chipname, ioaddr);
@@ -529,7 +541,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
The first six bytes are the station address. */
for (i = 0; i < 6; i++)
dev->dev_addr[i] = inb(ioaddr + i);
- printk("%s", print_mac(mac, dev->dev_addr));
+ printk("%pM", dev->dev_addr);
dev->base_addr = ioaddr;
/* Make certain the data structures used by the LANCE are aligned and DMAble. */
@@ -538,7 +550,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
if(lp==NULL)
return -ENODEV;
if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
- dev->priv = lp;
+ dev->ml_priv = lp;
lp->name = chipname;
lp->rx_buffs = (unsigned long)kmalloc(PKT_BUF_SZ*RX_RING_SIZE,
GFP_DMA | GFP_KERNEL);
@@ -714,12 +726,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
printk(version);
/* The LANCE-specific entries in the device structure. */
- dev->open = lance_open;
- dev->hard_start_xmit = lance_start_xmit;
- dev->stop = lance_close;
- dev->get_stats = lance_get_stats;
- dev->set_multicast_list = set_multicast_list;
- dev->tx_timeout = lance_tx_timeout;
+ dev->netdev_ops = &lance_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
err = register_netdev(dev);
@@ -742,12 +749,12 @@ out_lp:
static int
lance_open(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int ioaddr = dev->base_addr;
int i;
if (dev->irq == 0 ||
- request_irq(dev->irq, &lance_interrupt, 0, lp->name, dev)) {
+ request_irq(dev->irq, lance_interrupt, 0, dev->name, dev)) {
return -EAGAIN;
}
@@ -830,7 +837,7 @@ lance_open(struct net_device *dev)
static void
lance_purge_ring(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int i;
/* Free all the skbuffs in the Rx and Tx queues. */
@@ -854,7 +861,7 @@ lance_purge_ring(struct net_device *dev)
static void
lance_init_ring(struct net_device *dev, gfp_t gfp)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int i;
lp->cur_rx = lp->cur_tx = 0;
@@ -866,10 +873,9 @@ lance_init_ring(struct net_device *dev, gfp_t gfp)
skb = alloc_skb(PKT_BUF_SZ, GFP_DMA | gfp);
lp->rx_skbuff[i] = skb;
- if (skb) {
- skb->dev = dev;
+ if (skb)
rx_buff = skb->data;
- } else
+ else
rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
if (rx_buff == NULL)
lp->rx_ring[i].base = 0;
@@ -896,7 +902,7 @@ lance_init_ring(struct net_device *dev, gfp_t gfp)
static void
lance_restart(struct net_device *dev, unsigned int csr0_bits, int must_reinit)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
if (must_reinit ||
(chip_table[lp->chip_version].flags & LANCE_MUST_REINIT_RING)) {
@@ -910,14 +916,14 @@ lance_restart(struct net_device *dev, unsigned int csr0_bits, int must_reinit)
static void lance_tx_timeout (struct net_device *dev)
{
- struct lance_private *lp = (struct lance_private *) dev->priv;
+ struct lance_private *lp = (struct lance_private *) dev->ml_priv;
int ioaddr = dev->base_addr;
outw (0, ioaddr + LANCE_ADDR);
printk ("%s: transmit timed out, status %4.4x, resetting.\n",
dev->name, inw (ioaddr + LANCE_DATA));
outw (0x0004, ioaddr + LANCE_DATA);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
#ifndef final_version
if (lance_debug > 3) {
int i;
@@ -937,14 +943,15 @@ static void lance_tx_timeout (struct net_device *dev)
#endif
lance_restart (dev, 0x0043, 1);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue (dev);
}
-static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int ioaddr = dev->base_addr;
int entry;
unsigned long flags;
@@ -980,7 +987,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->tx_ring[entry].misc = 0x0000;
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* If any part of this buffer is >16M we must copy it to a low-memory
buffer. */
@@ -1002,14 +1009,12 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
outw(0x0000, ioaddr+LANCE_ADDR);
outw(0x0048, ioaddr+LANCE_DATA);
- dev->trans_start = jiffies;
-
if ((lp->cur_tx - lp->dirty_tx) >= TX_RING_SIZE)
netif_stop_queue(dev);
out:
spin_unlock_irqrestore(&lp->devlock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/* The LANCE interrupt handler. */
@@ -1021,13 +1026,13 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
int must_restart;
ioaddr = dev->base_addr;
- lp = dev->priv;
+ lp = dev->ml_priv;
spin_lock (&lp->devlock);
outw(0x00, dev->base_addr + LANCE_ADDR);
- while ((csr0 = inw(dev->base_addr + LANCE_DATA)) & 0x8600
- && --boguscnt >= 0) {
+ while ((csr0 = inw(dev->base_addr + LANCE_DATA)) & 0x8600 &&
+ --boguscnt >= 0) {
/* Acknowledge all of the current interrupt sources ASAP. */
outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
@@ -1055,13 +1060,16 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
if (status & 0x40000000) {
/* There was an major error, log it. */
int err_status = lp->tx_ring[entry].misc;
- lp->stats.tx_errors++;
- if (err_status & 0x0400) lp->stats.tx_aborted_errors++;
- if (err_status & 0x0800) lp->stats.tx_carrier_errors++;
- if (err_status & 0x1000) lp->stats.tx_window_errors++;
+ dev->stats.tx_errors++;
+ if (err_status & 0x0400)
+ dev->stats.tx_aborted_errors++;
+ if (err_status & 0x0800)
+ dev->stats.tx_carrier_errors++;
+ if (err_status & 0x1000)
+ dev->stats.tx_window_errors++;
if (err_status & 0x4000) {
/* Ackk! On FIFO errors the Tx unit is turned off! */
- lp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
/* Remove this verbosity later! */
printk("%s: Tx FIFO error! Status %4.4x.\n",
dev->name, csr0);
@@ -1070,8 +1078,8 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
}
} else {
if (status & 0x18000000)
- lp->stats.collisions++;
- lp->stats.tx_packets++;
+ dev->stats.collisions++;
+ dev->stats.tx_packets++;
}
/* We must free the original skb if it's not a data-only copy
@@ -1101,8 +1109,10 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
}
/* Log misc errors. */
- if (csr0 & 0x4000) lp->stats.tx_errors++; /* Tx babble. */
- if (csr0 & 0x1000) lp->stats.rx_errors++; /* Missed a Rx frame. */
+ if (csr0 & 0x4000)
+ dev->stats.tx_errors++; /* Tx babble. */
+ if (csr0 & 0x1000)
+ dev->stats.rx_errors++; /* Missed a Rx frame. */
if (csr0 & 0x0800) {
printk("%s: Bus master arbitration failure, status %4.4x.\n",
dev->name, csr0);
@@ -1134,7 +1144,7 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
static int
lance_rx(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int entry = lp->cur_rx & RX_RING_MOD_MASK;
int i;
@@ -1148,11 +1158,15 @@ lance_rx(struct net_device *dev)
buffers it's possible for a jabber packet to use two
buffers, with only the last correctly noting the error. */
if (status & 0x01) /* Only count a general error at the */
- lp->stats.rx_errors++; /* end of a packet.*/
- if (status & 0x20) lp->stats.rx_frame_errors++;
- if (status & 0x10) lp->stats.rx_over_errors++;
- if (status & 0x08) lp->stats.rx_crc_errors++;
- if (status & 0x04) lp->stats.rx_fifo_errors++;
+ dev->stats.rx_errors++; /* end of a packet.*/
+ if (status & 0x20)
+ dev->stats.rx_frame_errors++;
+ if (status & 0x10)
+ dev->stats.rx_over_errors++;
+ if (status & 0x08)
+ dev->stats.rx_crc_errors++;
+ if (status & 0x04)
+ dev->stats.rx_fifo_errors++;
lp->rx_ring[entry].base &= 0x03ffffff;
}
else
@@ -1164,7 +1178,7 @@ lance_rx(struct net_device *dev)
if(pkt_len<60)
{
printk("%s: Runt packet!\n",dev->name);
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
else
{
@@ -1178,7 +1192,7 @@ lance_rx(struct net_device *dev)
if (i > RX_RING_SIZE -2)
{
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
lp->rx_ring[entry].base |= 0x80000000;
lp->cur_rx++;
}
@@ -1191,9 +1205,8 @@ lance_rx(struct net_device *dev)
pkt_len);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
- dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes+=pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
}
/* The docs say that the buffer length isn't touched, but Andrew Boyd
@@ -1213,13 +1226,13 @@ static int
lance_close(struct net_device *dev)
{
int ioaddr = dev->base_addr;
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
netif_stop_queue (dev);
if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
outw(112, ioaddr+LANCE_ADDR);
- lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
+ dev->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
}
outw(0, ioaddr+LANCE_ADDR);
@@ -1246,7 +1259,7 @@ lance_close(struct net_device *dev)
static struct net_device_stats *lance_get_stats(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
short ioaddr = dev->base_addr;
@@ -1256,12 +1269,12 @@ static struct net_device_stats *lance_get_stats(struct net_device *dev)
spin_lock_irqsave(&lp->devlock, flags);
saved_addr = inw(ioaddr+LANCE_ADDR);
outw(112, ioaddr+LANCE_ADDR);
- lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
+ dev->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
outw(saved_addr, ioaddr+LANCE_ADDR);
spin_unlock_irqrestore(&lp->devlock, flags);
}
- return &lp->stats;
+ return &dev->stats;
}
/* Set or clear the multicast filter for this adaptor.
@@ -1280,7 +1293,7 @@ static void set_multicast_list(struct net_device *dev)
} else {
short multicast_table[4];
int i;
- int num_addrs=dev->mc_count;
+ int num_addrs=netdev_mc_count(dev);
if(dev->flags&IFF_ALLMULTI)
num_addrs=1;
/* FIXIT: We don't use the multicast table, but rely on upper-layer filtering. */
diff --git a/drivers/net/mvme147.c b/drivers/net/ethernet/amd/mvme147.c
index 06ca4252155..0660ac5846b 100644
--- a/drivers/net/mvme147.c
+++ b/drivers/net/ethernet/amd/mvme147.c
@@ -10,11 +10,11 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
/* Used for the temporal inet entries and routing */
#include <linux/socket.h>
#include <linux/route.h>
@@ -22,14 +22,13 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/mvme147hw.h>
-/* We have 16834 bytes of RAM for the init block and buffers. This places
+/* We have 32K of RAM for the init block and buffers. This places
* an upper limit on the number of buffers we can use. NetBSD uses 8 Rx
- * buffers and 2 Tx buffers.
+ * buffers and 2 Tx buffers, it takes (8 + 2) * 1544 bytes.
*/
#define LANCE_LOG_TX_BUFFERS 1
#define LANCE_LOG_RX_BUFFERS 3
@@ -57,6 +56,17 @@ typedef void (*writerap_t)(void *, unsigned short);
typedef void (*writerdp_t)(void *, unsigned short);
typedef unsigned short (*readrdp_t)(void *);
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = m147lance_open,
+ .ndo_stop = m147lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_rx_mode = lance_set_multicast,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
/* Initialise the one and only on-board 7990 */
struct net_device * __init mvme147lance_probe(int unit)
{
@@ -67,7 +77,6 @@ struct net_device * __init mvme147lance_probe(int unit)
u_long *addr;
u_long address;
int err;
- DECLARE_MAC_BUF(mac);
if (!MACH_IS_MVME147 || called)
return ERR_PTR(-ENODEV);
@@ -82,40 +91,34 @@ struct net_device * __init mvme147lance_probe(int unit)
/* Fill the dev fields */
dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
- dev->open = &m147lance_open;
- dev->stop = &m147lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->set_multicast_list = &lance_set_multicast;
- dev->tx_timeout = &lance_tx_timeout;
+ dev->netdev_ops = &lance_netdev_ops;
dev->dma = 0;
- addr=(u_long *)ETHERNET_ADDRESS;
+ addr = (u_long *)ETHERNET_ADDRESS;
address = *addr;
- dev->dev_addr[0]=0x08;
- dev->dev_addr[1]=0x00;
- dev->dev_addr[2]=0x3e;
- address=address>>8;
- dev->dev_addr[5]=address&0xff;
- address=address>>8;
- dev->dev_addr[4]=address&0xff;
- address=address>>8;
- dev->dev_addr[3]=address&0xff;
-
- printk("%s: MVME147 at 0x%08lx, irq %d, "
- "Hardware Address %s\n",
+ dev->dev_addr[0] = 0x08;
+ dev->dev_addr[1] = 0x00;
+ dev->dev_addr[2] = 0x3e;
+ address = address >> 8;
+ dev->dev_addr[5] = address&0xff;
+ address = address >> 8;
+ dev->dev_addr[4] = address&0xff;
+ address = address >> 8;
+ dev->dev_addr[3] = address&0xff;
+
+ printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n",
dev->name, dev->base_addr, MVME147_LANCE_IRQ,
- print_mac(mac, dev->dev_addr));
+ dev->dev_addr);
- lp = (struct m147lance_private *)dev->priv;
- lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 16K */
- if (!lp->ram)
- {
+ lp = netdev_priv(dev);
+ lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */
+ if (!lp->ram) {
printk("%s: No memory for LANCE buffers\n", dev->name);
free_netdev(dev);
return ERR_PTR(-ENOMEM);
}
- lp->lance.name = (char*)name; /* discards const, shut up gcc */
+ lp->lance.name = name;
lp->lance.base = dev->base_addr;
lp->lance.init_block = (struct lance_init_block *)(lp->ram); /* CPU addr */
lp->lance.lance_init_block = (struct lance_init_block *)(lp->ram); /* LANCE addr of same RAM */
@@ -162,8 +165,8 @@ static int m147lance_open(struct net_device *dev)
if (status)
return status;
/* enable interrupts at board level. */
- m147_pcc->lan_cntrl=0; /* clear the interrupts (if any) */
- m147_pcc->lan_cntrl=0x08 | 0x04; /* Enable irq 4 */
+ m147_pcc->lan_cntrl = 0; /* clear the interrupts (if any) */
+ m147_pcc->lan_cntrl = 0x08 | 0x04; /* Enable irq 4 */
return 0;
}
@@ -171,7 +174,7 @@ static int m147lance_open(struct net_device *dev)
static int m147lance_close(struct net_device *dev)
{
/* disable interrupts at boardlevel */
- m147_pcc->lan_cntrl=0x0; /* disable interrupts */
+ m147_pcc->lan_cntrl = 0x0; /* disable interrupts */
lance_close(dev);
return 0;
}
@@ -183,14 +186,12 @@ static struct net_device *dev_mvme147_lance;
int __init init_module(void)
{
dev_mvme147_lance = mvme147lance_probe(-1);
- if (IS_ERR(dev_mvme147_lance))
- return PTR_ERR(dev_mvme147_lance);
- return 0;
+ return PTR_ERR_OR_ZERO(dev_mvme147_lance);
}
void __exit cleanup_module(void)
{
- struct m147lance_private *lp = dev_mvme147_lance->priv;
+ struct m147lance_private *lp = netdev_priv(dev_mvme147_lance);
unregister_netdev(dev_mvme147_lance);
free_pages(lp->ram, 3);
free_netdev(dev_mvme147_lance);
diff --git a/drivers/net/ni65.c b/drivers/net/ethernet/amd/ni65.c
index 3edc971d0ec..1cf33addd15 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ethernet/amd/ni65.c
@@ -7,8 +7,6 @@
* EtherBlaster. (probably it also works with every full NE2100
* compatible card)
*
- * To compile as module, type:
- * gcc -O2 -fomit-frame-pointer -m486 -D__KERNEL__ -DMODULE -c ni65.c
* driver probes: io: 0x360,0x300,0x320,0x340 / dma: 3,5,6,7
*
* This is an extension to the Linux operating system, and is covered by the
@@ -239,7 +237,7 @@ struct priv
void *tmdbounce[TMDNUM];
int tmdbouncenum;
int lock,xmit_queued;
- struct net_device_stats stats;
+
void *self;
int cmdr_addr;
int cardno;
@@ -254,12 +252,12 @@ static void ni65_xmit_intr(struct net_device *dev,int);
static int ni65_open(struct net_device *dev);
static int ni65_lance_reinit(struct net_device *dev);
static void ni65_init_lance(struct priv *p,unsigned char*,int,int);
-static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ni65_send_packet(struct sk_buff *skb,
+ struct net_device *dev);
static void ni65_timeout(struct net_device *dev);
static int ni65_close(struct net_device *dev);
static int ni65_alloc_buffer(struct net_device *dev);
static void ni65_free_buffer(struct priv *p);
-static struct net_device_stats *ni65_get_stats(struct net_device *);
static void set_multicast_list(struct net_device *dev);
static int irqtab[] __initdata = { 9,12,15,5 }; /* irq config-translate */
@@ -295,8 +293,8 @@ static void ni65_set_performance(struct priv *p)
*/
static int ni65_open(struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
- int irqval = request_irq(dev->irq, &ni65_interrupt,0,
+ struct priv *p = dev->ml_priv;
+ int irqval = request_irq(dev->irq, ni65_interrupt,0,
cards[p->cardno].cardname,dev);
if (irqval) {
printk(KERN_ERR "%s: unable to get IRQ %d (irqval=%d).\n",
@@ -321,7 +319,7 @@ static int ni65_open(struct net_device *dev)
*/
static int ni65_close(struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
netif_stop_queue(dev);
@@ -345,7 +343,7 @@ static int ni65_close(struct net_device *dev)
static void cleanup_card(struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
disable_dma(dev->dma);
free_dma(dev->dma);
release_region(dev->base_addr, cards[p->cardno].total_size);
@@ -363,8 +361,8 @@ static int dma;
struct net_device * __init ni65_probe(int unit)
{
struct net_device *dev = alloc_etherdev(0);
- static int ports[] = {0x360,0x300,0x320,0x340, 0};
- int *port;
+ static const int ports[] = { 0x360, 0x300, 0x320, 0x340, 0 };
+ const int *port;
int err = 0;
if (!dev)
@@ -403,6 +401,17 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops ni65_netdev_ops = {
+ .ndo_open = ni65_open,
+ .ndo_stop = ni65_close,
+ .ndo_start_xmit = ni65_send_packet,
+ .ndo_tx_timeout = ni65_timeout,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* this is the real card probe ..
*/
@@ -444,7 +453,7 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
release_region(ioaddr, cards[i].total_size);
return j;
}
- p = (struct priv *) dev->priv;
+ p = dev->ml_priv;
p->cmdr_addr = ioaddr + cards[i].cmd_offset;
p->cardno = i;
spin_lock_init(&p->ring_lock);
@@ -483,8 +492,9 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
else {
if(dev->dma == 0) {
/* 'stuck test' from lance.c */
- long dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
- (inb(DMA2_STAT_REG) & 0xf0);
+ unsigned long dma_channels =
+ ((inb(DMA1_STAT_REG) >> 4) & 0x0f)
+ | (inb(DMA2_STAT_REG) & 0xf0);
for(i=1;i<5;i++) {
int dma = dmatab[i];
if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
@@ -550,13 +560,9 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
}
dev->base_addr = ioaddr;
- dev->open = ni65_open;
- dev->stop = ni65_close;
- dev->hard_start_xmit = ni65_send_packet;
- dev->tx_timeout = ni65_timeout;
+ dev->netdev_ops = &ni65_netdev_ops;
dev->watchdog_timeo = HZ/2;
- dev->get_stats = ni65_get_stats;
- dev->set_multicast_list = set_multicast_list;
+
return 0; /* everything is OK */
}
@@ -615,10 +621,8 @@ static void *ni65_alloc_mem(struct net_device *dev,char *what,int size,int type)
}
else {
ret = ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA);
- if(!ret) {
- printk(KERN_WARNING "%s: unable to allocate %s memory.\n",dev->name,what);
+ if(!ret)
return NULL;
- }
}
if( (u32) virt_to_phys(ptr+size) > 0x1000000) {
printk(KERN_WARNING "%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what);
@@ -647,8 +651,8 @@ static int ni65_alloc_buffer(struct net_device *dev)
if(!ptr)
return -ENOMEM;
- p = dev->priv = (struct priv *) (((unsigned long) ptr + 7) & ~0x7);
- memset((char *) dev->priv,0,sizeof(struct priv));
+ p = dev->ml_priv = (struct priv *) (((unsigned long) ptr + 7) & ~0x7);
+ memset((char *)p, 0, sizeof(struct priv));
p->self = ptr;
for(i=0;i<TMDNUM;i++)
@@ -778,7 +782,7 @@ static void ni65_stop_start(struct net_device *dev,struct priv *p)
if(!p->lock)
if (p->tmdnum || !p->xmit_queued)
netif_wake_queue(dev);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
}
else
writedatareg(CSR0_STRT | csr0);
@@ -790,7 +794,7 @@ static void ni65_stop_start(struct net_device *dev,struct priv *p)
static int ni65_lance_reinit(struct net_device *dev)
{
int i;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
unsigned long flags;
p->lock = 0;
@@ -843,7 +847,7 @@ static int ni65_lance_reinit(struct net_device *dev)
if(dev->flags & IFF_PROMISC)
ni65_init_lance(p,dev->dev_addr,0x00,M_PROM);
- else if(dev->mc_count || dev->flags & IFF_ALLMULTI)
+ else if (netdev_mc_count(dev) || dev->flags & IFF_ALLMULTI)
ni65_init_lance(p,dev->dev_addr,0xff,0x0);
else
ni65_init_lance(p,dev->dev_addr,0x00,0x00);
@@ -876,7 +880,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
struct priv *p;
int bcnt = 32;
- p = (struct priv *) dev->priv;
+ p = dev->ml_priv;
spin_lock(&p->ring_lock);
@@ -899,17 +903,16 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
if(csr0 & CSR0_ERR)
{
- struct priv *p = (struct priv *) dev->priv;
if(debuglevel > 1)
printk(KERN_ERR "%s: general error: %04x.\n",dev->name,csr0);
if(csr0 & CSR0_BABL)
- p->stats.tx_errors++;
+ dev->stats.tx_errors++;
if(csr0 & CSR0_MISS) {
int i;
for(i=0;i<RMDNUM;i++)
printk("%02x ",p->rmdhead[i].u.s.status);
printk("\n");
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
if(csr0 & CSR0_MERR) {
if(debuglevel > 1)
@@ -924,8 +927,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
int j;
for(j=0;j<RMDNUM;j++)
{
- struct priv *p = (struct priv *) dev->priv;
- int i,k,num1,num2;
+ int i, num2;
for(i=RMDNUM-1;i>0;i--) {
num2 = (p->rmdnum + i) & (RMDNUM-1);
if(!(p->rmdhead[num2].u.s.status & RCV_OWN))
@@ -933,6 +935,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
}
if(i) {
+ int k, num1;
for(k=0;k<RMDNUM;k++) {
num1 = (p->rmdnum + k) & (RMDNUM-1);
if(!(p->rmdhead[num1].u.s.status & RCV_OWN))
@@ -944,7 +947,6 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
if(debuglevel > 0)
{
char buf[256],*buf1;
- int k;
buf1 = buf;
for(k=0;k<RMDNUM;k++) {
sprintf(buf1,"%02x ",(p->rmdhead[k].u.s.status)); /* & RCV_OWN) ); */
@@ -982,7 +984,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
*/
static void ni65_xmit_intr(struct net_device *dev,int csr0)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
while(p->xmit_queued)
{
@@ -1000,12 +1002,12 @@ static void ni65_xmit_intr(struct net_device *dev,int csr0)
#endif
/* checking some errors */
if(tmdp->status2 & XMIT_RTRY)
- p->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
if(tmdp->status2 & XMIT_LCAR)
- p->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if(tmdp->status2 & (XMIT_BUFF | XMIT_UFLO )) {
/* this stops the xmitter */
- p->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if(debuglevel > 0)
printk(KERN_ERR "%s: Xmit FIFO/BUFF error\n",dev->name);
if(p->features & INIT_RING_BEFORE_START) {
@@ -1019,12 +1021,12 @@ static void ni65_xmit_intr(struct net_device *dev,int csr0)
if(debuglevel > 2)
printk(KERN_ERR "%s: xmit-error: %04x %02x-%04x\n",dev->name,csr0,(int) tmdstat,(int) tmdp->status2);
if(!(csr0 & CSR0_BABL)) /* don't count errors twice */
- p->stats.tx_errors++;
+ dev->stats.tx_errors++;
tmdp->status2 = 0;
}
else {
- p->stats.tx_bytes -= (short)(tmdp->blen);
- p->stats.tx_packets++;
+ dev->stats.tx_bytes -= (short)(tmdp->blen);
+ dev->stats.tx_packets++;
}
#ifdef XMT_VIA_SKB
@@ -1049,7 +1051,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
struct rmd *rmdp;
int rmdstat,len;
int cnt=0;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
rmdp = p->rmdhead + p->rmdnum;
while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN))
@@ -1060,7 +1062,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
if(!(rmdstat & RCV_ERR)) {
if(rmdstat & RCV_START)
{
- p->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
printk(KERN_ERR "%s: recv, packet too long: %d\n",dev->name,rmdp->mlen & 0x0fff);
}
}
@@ -1069,16 +1071,16 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
printk(KERN_ERR "%s: receive-error: %04x, lance-status: %04x/%04x\n",
dev->name,(int) rmdstat,csr0,(int) inw(PORT+L_DATAREG) );
if(rmdstat & RCV_FRAM)
- p->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if(rmdstat & RCV_OFLO)
- p->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
if(rmdstat & RCV_CRC)
- p->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if(rmdstat & RCV_BUF_ERR)
- p->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
}
if(!(csr0 & CSR0_MISS)) /* don't count errors twice */
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
else if( (len = (rmdp->mlen & 0x0fff) - 4) >= 60)
{
@@ -1087,7 +1089,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
if (skb)
skb_reserve(skb,16);
#else
- struct sk_buff *skb = dev_alloc_skb(len+2);
+ struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
#endif
if(skb)
{
@@ -1109,21 +1111,20 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
skb_put(skb,len);
skb_copy_to_linear_data(skb, (unsigned char *) p->recvbounce[p->rmdnum],len);
#endif
- p->stats.rx_packets++;
- p->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
- dev->last_rx = jiffies;
}
else
{
printk(KERN_ERR "%s: can't alloc new sk_buff\n",dev->name);
- p->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
}
else {
printk(KERN_INFO "%s: received runt packet\n",dev->name);
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
rmdp->blen = -(R_BUF_SIZE-8);
rmdp->mlen = 0;
@@ -1140,14 +1141,14 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
static void ni65_timeout(struct net_device *dev)
{
int i;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
printk(KERN_ERR "%s: xmitter timed out, try to restart!\n",dev->name);
for(i=0;i<TMDNUM;i++)
printk("%02x ",p->tmdhead[i].u.s.status);
printk("\n");
ni65_lance_reinit(dev);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue(dev);
}
@@ -1155,15 +1156,16 @@ static void ni65_timeout(struct net_device *dev)
* Send a packet
*/
-static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ni65_send_packet(struct sk_buff *skb,
+ struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
netif_stop_queue(dev);
if (test_and_set_bit(0, (void*)&p->lock)) {
printk(KERN_ERR "%s: Queue was locked.\n", dev->name);
- return 1;
+ return NETDEV_TX_BUSY;
}
{
@@ -1209,29 +1211,11 @@ static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
netif_wake_queue(dev);
p->lock = 0;
- dev->trans_start = jiffies;
spin_unlock_irqrestore(&p->ring_lock, flags);
}
- return 0;
-}
-
-static struct net_device_stats *ni65_get_stats(struct net_device *dev)
-{
-
-#if 0
- int i;
- struct priv *p = (struct priv *) dev->priv;
- for(i=0;i<RMDNUM;i++)
- {
- struct rmd *rmdp = p->rmdhead + ((p->rmdnum + i) & (RMDNUM-1));
- printk("%02x ",rmdp->u.s.status);
- }
- printk("\n");
-#endif
-
- return &((struct priv *) dev->priv)->stats;
+ return NETDEV_TX_OK;
}
static void set_multicast_list(struct net_device *dev)
@@ -1254,7 +1238,7 @@ MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)");
int __init init_module(void)
{
dev_ni65 = ni65_probe(-1);
- return IS_ERR(dev_ni65) ? PTR_ERR(dev_ni65) : 0;
+ return PTR_ERR_OR_ZERO(dev_ni65);
}
void __exit cleanup_module(void)
@@ -1266,7 +1250,3 @@ void __exit cleanup_module(void)
#endif /* MODULE */
MODULE_LICENSE("GPL");
-
-/*
- * END of ni65.c
- */
diff --git a/drivers/net/ni65.h b/drivers/net/ethernet/amd/ni65.h
index e6217e35edf..e6217e35edf 100644
--- a/drivers/net/ni65.h
+++ b/drivers/net/ethernet/amd/ni65.h
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c
index cfcbea9b7e2..abf3b1581c8 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/ethernet/amd/nmclan_cs.c
@@ -69,7 +69,7 @@ Driver Notes and Issues
History
-------------------------------------------------------------------------------
Log: nmclan_cs.c,v
- * 2.5.75-ac1 2003/07/11 Alan Cox <alan@redhat.com>
+ * 2.5.75-ac1 2003/07/11 Alan Cox <alan@lxorguk.ukuu.org.uk>
* Fixed hang on card eject as we probe it
* Cleaned up to use new style locking.
*
@@ -111,6 +111,8 @@ Log: nmclan_cs.c,v
---------------------------------------------------------------------------- */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "nmclan_cs"
#define DRV_VERSION "0.16"
@@ -130,7 +132,6 @@ Include Files
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -146,22 +147,17 @@ Include Files
#include <linux/ioport.h>
#include <linux/bitops.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <asm/system.h>
/* ----------------------------------------------------------------------------
Defines
---------------------------------------------------------------------------- */
-#define ETHER_ADDR_LEN ETH_ALEN
- /* 6 bytes in an Ethernet Address */
#define MACE_LADRF_LEN 8
/* 8 bytes in Logical Address Filter */
@@ -363,7 +359,6 @@ typedef struct _mace_statistics {
typedef struct _mace_private {
struct pcmcia_device *p_dev;
- dev_node_t node;
struct net_device_stats linux_stats; /* Linux statistics counters */
mace_statistics mace_stats; /* MACE chip statistics counters */
@@ -381,13 +376,6 @@ typedef struct _mace_private {
Private Global Variables
---------------------------------------------------------------------------- */
-#ifdef PCMCIA_DEBUG
-static char rcsid[] =
-"nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao";
-static char *version =
-DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
-#endif
-
static const char *if_names[]={
"Auto", "10baseT", "BNC",
};
@@ -406,12 +394,6 @@ MODULE_LICENSE("GPL");
/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
INT_MODULE_PARM(if_port, 0);
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
/* ----------------------------------------------------------------------------
Function Prototypes
@@ -424,7 +406,8 @@ static void nmclan_reset(struct net_device *dev);
static int mace_config(struct net_device *dev, struct ifmap *map);
static int mace_open(struct net_device *dev);
static int mace_close(struct net_device *dev);
-static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
static void mace_tx_timeout(struct net_device *dev);
static irqreturn_t mace_interrupt(int irq, void *dev_id);
static struct net_device_stats *mace_get_stats(struct net_device *dev);
@@ -436,20 +419,25 @@ static const struct ethtool_ops netdev_ethtool_ops;
static void nmclan_detach(struct pcmcia_device *p_dev);
-/* ----------------------------------------------------------------------------
-nmclan_attach
- Creates an "instance" of the driver, allocating local data
- structures for one device. The device is registered with Card
- Services.
----------------------------------------------------------------------------- */
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_start_xmit,
+ .ndo_tx_timeout = mace_tx_timeout,
+ .ndo_set_config = mace_config,
+ .ndo_get_stats = mace_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int nmclan_probe(struct pcmcia_device *link)
{
mace_private *lp;
struct net_device *dev;
- DEBUG(0, "nmclan_attach()\n");
- DEBUG(1, "%s\n", rcsid);
+ dev_dbg(&link->dev, "nmclan_attach()\n");
/* Create new ethernet device */
dev = alloc_etherdev(sizeof(mace_private));
@@ -460,51 +448,28 @@ static int nmclan_probe(struct pcmcia_device *link)
link->priv = dev;
spin_lock_init(&lp->bank_lock);
- link->io.NumPorts1 = 32;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.IOAddrLines = 5;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->irq.Handler = &mace_interrupt;
- link->irq.Instance = dev;
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.IntType = INT_MEMORY_AND_IO;
- link->conf.ConfigIndex = 1;
- link->conf.Present = PRESENT_OPTION;
+ link->resource[0]->end = 32;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+ link->config_flags |= CONF_ENABLE_IRQ;
+ link->config_index = 1;
+ link->config_regs = PRESENT_OPTION;
lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
- dev->hard_start_xmit = &mace_start_xmit;
- dev->set_config = &mace_config;
- dev->get_stats = &mace_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->open = &mace_open;
- dev->stop = &mace_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = mace_tx_timeout;
+ dev->netdev_ops = &mace_netdev_ops;
+ dev->ethtool_ops = &netdev_ethtool_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
return nmclan_config(link);
} /* nmclan_attach */
-/* ----------------------------------------------------------------------------
-nmclan_detach
- This deletes a driver "instance". The device is de-registered
- with Card Services. If it has been released, all local data
- structures are freed. Otherwise, the structures will be freed
- when the device is released.
----------------------------------------------------------------------------- */
-
static void nmclan_detach(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- DEBUG(0, "nmclan_detach(0x%p)\n", link);
+ dev_dbg(&link->dev, "nmclan_detach\n");
- if (link->dev_node)
- unregister_netdev(dev);
+ unregister_netdev(dev);
nmclan_release(link);
@@ -535,7 +500,7 @@ static int mace_read(mace_private *lp, unsigned int ioaddr, int reg)
spin_unlock_irqrestore(&lp->bank_lock, flags);
break;
}
- return (data & 0xFF);
+ return data & 0xFF;
} /* mace_read */
/* ----------------------------------------------------------------------------
@@ -579,7 +544,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
/* Wait for reset bit to be cleared automatically after <= 200ns */;
if(++ct > 500)
{
- printk(KERN_ERR "mace: reset failed, card removed ?\n");
+ pr_err("reset failed, card removed?\n");
return -1;
}
udelay(1);
@@ -626,12 +591,12 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
{
if(++ ct > 500)
{
- printk(KERN_ERR "mace: ADDRCHG timeout, card removed ?\n");
+ pr_err("ADDRCHG timeout, card removed?\n");
return -1;
}
}
/* Set PADR register */
- for (i = 0; i < ETHER_ADDR_LEN; i++)
+ for (i = 0; i < ETH_ALEN; i++)
mace_write(lp, ioaddr, MACE_PADR, enet_addr[i]);
/* MAC Configuration Control Register should be written last */
@@ -641,45 +606,41 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr)
return 0;
} /* mace_init */
-/* ----------------------------------------------------------------------------
-nmclan_config
- This routine is scheduled to run after a CARD_INSERTION event
- is received, to configure the PCMCIA socket, and to make the
- ethernet device available to the system.
----------------------------------------------------------------------------- */
-
-#define CS_CHECK(fn, ret) \
- do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
static int nmclan_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
mace_private *lp = netdev_priv(dev);
- tuple_t tuple;
- u_char buf[64];
- int i, last_ret, last_fn;
+ u8 *buf;
+ size_t len;
+ int i, ret;
unsigned int ioaddr;
- DECLARE_MAC_BUF(mac);
- DEBUG(0, "nmclan_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "nmclan_config\n");
+
+ link->io_lines = 5;
+ ret = pcmcia_request_io(link);
+ if (ret)
+ goto failed;
+ ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
+ if (ret)
+ goto failed;
+ ret = pcmcia_enable_device(link);
+ if (ret)
+ goto failed;
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
- dev->irq = link->irq.AssignedIRQ;
- dev->base_addr = link->io.BasePort1;
+ dev->irq = link->irq;
+ dev->base_addr = link->resource[0]->start;
ioaddr = dev->base_addr;
/* Read the ethernet address from the CIS. */
- tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
+ len = pcmcia_get_tuple(link, 0x80, &buf);
+ if (!buf || len < ETH_ALEN) {
+ kfree(buf);
+ goto failed;
+ }
+ memcpy(dev->dev_addr, buf, ETH_ALEN);
+ kfree(buf);
/* Verify configuration by reading the MACE ID. */
{
@@ -688,11 +649,11 @@ static int nmclan_config(struct pcmcia_device *link)
sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
- DEBUG(0, "nmclan_cs configured: mace id=%x %x\n",
+ dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
sig[0], sig[1]);
} else {
- printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
- " be 0x40 0x?9\n", sig[0], sig[1]);
+ pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
+ sig[0], sig[1]);
return -ENODEV;
}
}
@@ -704,42 +665,28 @@ static int nmclan_config(struct pcmcia_device *link)
if (if_port <= 2)
dev->if_port = if_port;
else
- printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
+ pr_notice("invalid if_port requested\n");
- link->dev_node = &lp->node;
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ SET_NETDEV_DEV(dev, &link->dev);
i = register_netdev(dev);
if (i != 0) {
- printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
- link->dev_node = NULL;
+ pr_notice("register_netdev() failed\n");
goto failed;
}
- strcpy(lp->node.dev_name, dev->name);
-
- printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
- " hw_addr %s\n",
- dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],
- print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n",
+ dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr);
return 0;
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
nmclan_release(link);
return -ENODEV;
} /* nmclan_config */
-/* ----------------------------------------------------------------------------
-nmclan_release
- After a card is removed, nmclan_release() will unregister the
- net device, and release the PCMCIA configuration. If the device
- is still open, this will be postponed until it is closed.
----------------------------------------------------------------------------- */
static void nmclan_release(struct pcmcia_device *link)
{
- DEBUG(0, "nmclan_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "nmclan_release\n");
pcmcia_disable_device(link);
}
@@ -776,29 +723,20 @@ static void nmclan_reset(struct net_device *dev)
#if RESET_XILINX
struct pcmcia_device *link = &lp->link;
- conf_reg_t reg;
- u_long OrigCorValue;
+ u8 OrigCorValue;
/* Save original COR value */
- reg.Function = 0;
- reg.Action = CS_READ;
- reg.Offset = CISREG_COR;
- reg.Value = 0;
- pcmcia_access_configuration_register(link, &reg);
- OrigCorValue = reg.Value;
+ pcmcia_read_config_byte(link, CISREG_COR, &OrigCorValue);
/* Reset Xilinx */
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
- DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
+ dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%x, resetting...\n",
OrigCorValue);
- reg.Value = COR_SOFT_RESET;
- pcmcia_access_configuration_register(link, &reg);
+ pcmcia_write_config_byte(link, CISREG_COR, COR_SOFT_RESET);
/* Need to wait for 20 ms for PCMCIA to finish reset. */
/* Restore original COR configuration index */
- reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK);
- pcmcia_access_configuration_register(link, &reg);
+ pcmcia_write_config_byte(link, CISREG_COR,
+ (COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK)));
/* Xilinx is now completely reset along with the MACE chip. */
lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
@@ -826,8 +764,7 @@ static int mace_config(struct net_device *dev, struct ifmap *map)
if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
if (map->port <= 2) {
dev->if_port = map->port;
- printk(KERN_INFO "%s: switched to %s port\n", dev->name,
- if_names[dev->if_port]);
+ netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]);
} else
return -EINVAL;
}
@@ -867,7 +804,7 @@ static int mace_close(struct net_device *dev)
mace_private *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+ dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
/* Mask off all interrupts from the MACE chip. */
outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
@@ -881,29 +818,14 @@ static int mace_close(struct net_device *dev)
static void netdev_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
-}
-
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- pc_debug = level;
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ snprintf(info->bus_info, sizeof(info->bus_info),
+ "PCMCIA 0x%lx", dev->base_addr);
}
-#endif /* PCMCIA_DEBUG */
static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
};
/* ----------------------------------------------------------------------------
@@ -922,25 +844,26 @@ static void mace_tx_timeout(struct net_device *dev)
mace_private *lp = netdev_priv(dev);
struct pcmcia_device *link = lp->p_dev;
- printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
+ netdev_notice(dev, "transmit timed out -- ");
#if RESET_ON_TIMEOUT
- printk("resetting card\n");
- pcmcia_reset_card(link, NULL);
+ pr_cont("resetting card\n");
+ pcmcia_reset_card(link->socket);
#else /* #if RESET_ON_TIMEOUT */
- printk("NOT resetting card\n");
+ pr_cont("NOT resetting card\n");
#endif /* #if RESET_ON_TIMEOUT */
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue(dev);
}
-static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
mace_private *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
netif_stop_queue(dev);
- DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
+ pr_debug("%s: mace_start_xmit(length = %ld) called.\n",
dev->name, (long)skb->len);
#if (!TX_INTERRUPTABLE)
@@ -970,8 +893,6 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
outb(skb->data[skb->len-1], ioaddr + AM2150_XMT);
}
- dev->trans_start = jiffies;
-
#if MULTI_TX
if (lp->tx_free_frames > 0)
netif_start_queue(dev);
@@ -986,7 +907,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
} /* mace_start_xmit */
/* ----------------------------------------------------------------------------
@@ -1002,7 +923,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
int IntrCnt = MACE_MAX_IR_ITERATIONS;
if (dev == NULL) {
- DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
+ pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
irq);
return IRQ_NONE;
}
@@ -1010,22 +931,21 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
ioaddr = dev->base_addr;
if (lp->tx_irq_disabled) {
- printk(
- (lp->tx_irq_disabled?
- KERN_NOTICE "%s: Interrupt with tx_irq_disabled "
- "[isr=%02X, imr=%02X]\n":
- KERN_NOTICE "%s: Re-entering the interrupt handler "
- "[isr=%02X, imr=%02X]\n"),
- dev->name,
- inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
- inb(ioaddr + AM2150_MACE_BASE + MACE_IMR)
- );
+ const char *msg;
+ if (lp->tx_irq_disabled)
+ msg = "Interrupt with tx_irq_disabled";
+ else
+ msg = "Re-entering the interrupt handler";
+ netdev_notice(dev, "%s [isr=%02X, imr=%02X]\n",
+ msg,
+ inb(ioaddr + AM2150_MACE_BASE + MACE_IR),
+ inb(ioaddr + AM2150_MACE_BASE + MACE_IMR));
/* WARNING: MACE_IR has been read! */
return IRQ_NONE;
}
if (!netif_device_present(dev)) {
- DEBUG(2, "%s: interrupt from dead card\n", dev->name);
+ netdev_dbg(dev, "interrupt from dead card\n");
return IRQ_NONE;
}
@@ -1033,7 +953,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
/* WARNING: MACE_IR is a READ/CLEAR port! */
status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
- DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
+ pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
if (status & MACE_IR_RCVINT) {
mace_rx(dev, MACE_MAX_RX_ITERATIONS);
@@ -1152,7 +1072,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
) {
rx_status = inw(ioaddr + AM2150_RCV);
- DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status"
+ pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
" 0x%X.\n", dev->name, rx_framecnt, rx_status);
if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
@@ -1179,10 +1099,10 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
/* rcv collision count */
- DEBUG(3, " receiving packet size 0x%X rx_status"
+ pr_debug(" receiving packet size 0x%X rx_status"
" 0x%X.\n", pkt_len, rx_status);
- skb = dev_alloc_skb(pkt_len+2);
+ skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb != NULL) {
skb_reserve(skb, 2);
@@ -1193,13 +1113,12 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
netif_rx(skb); /* Send the packet to the upper (protocol) layers. */
- dev->last_rx = jiffies;
lp->linux_stats.rx_packets++;
lp->linux_stats.rx_bytes += pkt_len;
outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
continue;
} else {
- DEBUG(1, "%s: couldn't allocate a sk_buff of size"
+ pr_debug("%s: couldn't allocate a sk_buff of size"
" %d.\n", dev->name, pkt_len);
lp->linux_stats.rx_dropped++;
}
@@ -1215,28 +1134,28 @@ pr_linux_stats
---------------------------------------------------------------------------- */
static void pr_linux_stats(struct net_device_stats *pstats)
{
- DEBUG(2, "pr_linux_stats\n");
- DEBUG(2, " rx_packets=%-7ld tx_packets=%ld\n",
+ pr_debug("pr_linux_stats\n");
+ pr_debug(" rx_packets=%-7ld tx_packets=%ld\n",
(long)pstats->rx_packets, (long)pstats->tx_packets);
- DEBUG(2, " rx_errors=%-7ld tx_errors=%ld\n",
+ pr_debug(" rx_errors=%-7ld tx_errors=%ld\n",
(long)pstats->rx_errors, (long)pstats->tx_errors);
- DEBUG(2, " rx_dropped=%-7ld tx_dropped=%ld\n",
+ pr_debug(" rx_dropped=%-7ld tx_dropped=%ld\n",
(long)pstats->rx_dropped, (long)pstats->tx_dropped);
- DEBUG(2, " multicast=%-7ld collisions=%ld\n",
+ pr_debug(" multicast=%-7ld collisions=%ld\n",
(long)pstats->multicast, (long)pstats->collisions);
- DEBUG(2, " rx_length_errors=%-7ld rx_over_errors=%ld\n",
+ pr_debug(" rx_length_errors=%-7ld rx_over_errors=%ld\n",
(long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
- DEBUG(2, " rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
+ pr_debug(" rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
(long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
- DEBUG(2, " rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
+ pr_debug(" rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
(long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
- DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
+ pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
(long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
- DEBUG(2, " tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
+ pr_debug(" tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
(long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
- DEBUG(2, " tx_window_errors=%ld\n",
+ pr_debug(" tx_window_errors=%ld\n",
(long)pstats->tx_window_errors);
} /* pr_linux_stats */
@@ -1245,48 +1164,48 @@ pr_mace_stats
---------------------------------------------------------------------------- */
static void pr_mace_stats(mace_statistics *pstats)
{
- DEBUG(2, "pr_mace_stats\n");
+ pr_debug("pr_mace_stats\n");
- DEBUG(2, " xmtsv=%-7d uflo=%d\n",
+ pr_debug(" xmtsv=%-7d uflo=%d\n",
pstats->xmtsv, pstats->uflo);
- DEBUG(2, " lcol=%-7d more=%d\n",
+ pr_debug(" lcol=%-7d more=%d\n",
pstats->lcol, pstats->more);
- DEBUG(2, " one=%-7d defer=%d\n",
+ pr_debug(" one=%-7d defer=%d\n",
pstats->one, pstats->defer);
- DEBUG(2, " lcar=%-7d rtry=%d\n",
+ pr_debug(" lcar=%-7d rtry=%d\n",
pstats->lcar, pstats->rtry);
/* MACE_XMTRC */
- DEBUG(2, " exdef=%-7d xmtrc=%d\n",
+ pr_debug(" exdef=%-7d xmtrc=%d\n",
pstats->exdef, pstats->xmtrc);
/* RFS1--Receive Status (RCVSTS) */
- DEBUG(2, " oflo=%-7d clsn=%d\n",
+ pr_debug(" oflo=%-7d clsn=%d\n",
pstats->oflo, pstats->clsn);
- DEBUG(2, " fram=%-7d fcs=%d\n",
+ pr_debug(" fram=%-7d fcs=%d\n",
pstats->fram, pstats->fcs);
/* RFS2--Runt Packet Count (RNTPC) */
/* RFS3--Receive Collision Count (RCVCC) */
- DEBUG(2, " rfs_rntpc=%-7d rfs_rcvcc=%d\n",
+ pr_debug(" rfs_rntpc=%-7d rfs_rcvcc=%d\n",
pstats->rfs_rntpc, pstats->rfs_rcvcc);
/* MACE_IR */
- DEBUG(2, " jab=%-7d babl=%d\n",
+ pr_debug(" jab=%-7d babl=%d\n",
pstats->jab, pstats->babl);
- DEBUG(2, " cerr=%-7d rcvcco=%d\n",
+ pr_debug(" cerr=%-7d rcvcco=%d\n",
pstats->cerr, pstats->rcvcco);
- DEBUG(2, " rntpco=%-7d mpco=%d\n",
+ pr_debug(" rntpco=%-7d mpco=%d\n",
pstats->rntpco, pstats->mpco);
/* MACE_MPC */
- DEBUG(2, " mpc=%d\n", pstats->mpc);
+ pr_debug(" mpc=%d\n", pstats->mpc);
/* MACE_RNTPC */
- DEBUG(2, " rntpc=%d\n", pstats->rntpc);
+ pr_debug(" rntpc=%d\n", pstats->rntpc);
/* MACE_RCVCC */
- DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);
+ pr_debug(" rcvcc=%d\n", pstats->rcvcc);
} /* pr_mace_stats */
@@ -1341,8 +1260,6 @@ static void update_stats(unsigned int ioaddr, struct net_device *dev)
lp->linux_stats.tx_fifo_errors = lp->mace_stats.uflo;
lp->linux_stats.tx_heartbeat_errors = lp->mace_stats.cerr;
/* lp->linux_stats.tx_window_errors; */
-
- return;
} /* update_stats */
/* ----------------------------------------------------------------------------
@@ -1355,7 +1272,7 @@ static struct net_device_stats *mace_get_stats(struct net_device *dev)
update_stats(dev->base_addr, dev);
- DEBUG(1, "%s: updating the statistics.\n", dev->name);
+ pr_debug("%s: updating the statistics.\n", dev->name);
pr_linux_stats(&lp->linux_stats);
pr_mace_stats(&lp->mace_stats);
@@ -1371,7 +1288,7 @@ updateCRC
static void updateCRC(int *CRC, int bit)
{
- int poly[]={
+ static const int poly[]={
1,1,1,0, 1,1,0,1,
1,0,1,1, 1,0,0,0,
1,0,0,0, 0,0,1,1,
@@ -1422,16 +1339,12 @@ static void BuildLAF(int *ladrf, int *adr)
ladrf[byte] |= (1 << (hashcode & 7));
#ifdef PCMCIA_DEBUG
- if (pc_debug > 2) {
- printk(KERN_DEBUG " adr =");
- for (i = 0; i < 6; i++)
- printk(" %02X", adr[i]);
- printk("\n" KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63]"
- " =", hashcode);
- for (i = 0; i < 8; i++)
- printk(" %02X", ladrf[i]);
- printk("\n");
- }
+ if (0)
+ printk(KERN_DEBUG " adr =%pM\n", adr);
+ printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
+ for (i = 0; i < 8; i++)
+ pr_cont(" %02X", ladrf[i]);
+ pr_cont("\n");
#endif
} /* BuildLAF */
@@ -1452,12 +1365,12 @@ static void restore_multicast_list(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
int i;
- DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
+ pr_debug("%s: restoring Rx mode to %d addresses.\n",
dev->name, num_addrs);
if (num_addrs > 0) {
- DEBUG(1, "Attempt to restore multicast list detected.\n");
+ pr_debug("Attempt to restore multicast list detected.\n");
mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
/* Poll ADDRCHG bit */
@@ -1504,31 +1417,29 @@ Output
static void set_multicast_list(struct net_device *dev)
{
mace_private *lp = netdev_priv(dev);
- int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */
- int i;
- struct dev_mc_list *dmi = dev->mc_list;
+ int adr[ETH_ALEN] = {0}; /* Ethernet address */
+ struct netdev_hw_addr *ha;
#ifdef PCMCIA_DEBUG
- if (pc_debug > 1) {
+ {
static int old;
- if (dev->mc_count != old) {
- old = dev->mc_count;
- DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+ if (netdev_mc_count(dev) != old) {
+ old = netdev_mc_count(dev);
+ pr_debug("%s: setting Rx mode to %d addresses.\n",
dev->name, old);
}
}
#endif
/* Set multicast_num_addrs. */
- lp->multicast_num_addrs = dev->mc_count;
+ lp->multicast_num_addrs = netdev_mc_count(dev);
/* Set multicast_ladrf. */
if (num_addrs > 0) {
/* Calculate multicast logical address filter */
memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN);
- for (i = 0; i < dev->mc_count; i++) {
- memcpy(adr, dmi->dmi_addr, ETHER_ADDR_LEN);
- dmi = dmi->next;
+ netdev_for_each_mc_addr(ha, dev) {
+ memcpy(adr, ha->addr, ETH_ALEN);
BuildLAF(lp->multicast_ladrf, adr);
}
}
@@ -1544,7 +1455,7 @@ static void restore_multicast_list(struct net_device *dev)
unsigned int ioaddr = dev->base_addr;
mace_private *lp = netdev_priv(dev);
- DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
+ pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
lp->multicast_num_addrs);
if (dev->flags & IFF_PROMISC) {
@@ -1565,22 +1476,22 @@ static void set_multicast_list(struct net_device *dev)
mace_private *lp = netdev_priv(dev);
#ifdef PCMCIA_DEBUG
- if (pc_debug > 1) {
+ {
static int old;
- if (dev->mc_count != old) {
- old = dev->mc_count;
- DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+ if (netdev_mc_count(dev) != old) {
+ old = netdev_mc_count(dev);
+ pr_debug("%s: setting Rx mode to %d addresses.\n",
dev->name, old);
}
}
#endif
- lp->multicast_num_addrs = dev->mc_count;
+ lp->multicast_num_addrs = netdev_mc_count(dev);
restore_multicast_list(dev);
} /* set_multicast_list */
-static struct pcmcia_device_id nmclan_ids[] = {
+static const struct pcmcia_device_id nmclan_ids[] = {
PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941),
PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf),
PCMCIA_DEVICE_NULL,
@@ -1589,25 +1500,11 @@ MODULE_DEVICE_TABLE(pcmcia, nmclan_ids);
static struct pcmcia_driver nmclan_cs_driver = {
.owner = THIS_MODULE,
- .drv = {
- .name = "nmclan_cs",
- },
+ .name = "nmclan_cs",
.probe = nmclan_probe,
.remove = nmclan_detach,
.id_table = nmclan_ids,
.suspend = nmclan_suspend,
.resume = nmclan_resume,
};
-
-static int __init init_nmclan_cs(void)
-{
- return pcmcia_register_driver(&nmclan_cs_driver);
-}
-
-static void __exit exit_nmclan_cs(void)
-{
- pcmcia_unregister_driver(&nmclan_cs_driver);
-}
-
-module_init(init_nmclan_cs);
-module_exit(exit_nmclan_cs);
+module_pcmcia_driver(nmclan_cs_driver);
diff --git a/drivers/net/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c
index ca8c0e03740..e7cc9174e36 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/ethernet/amd/pcnet32.c
@@ -21,6 +21,8 @@
*
*************************************************************************/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define DRV_NAME "pcnet32"
#define DRV_VERSION "1.35"
#define DRV_RELDATE "21.Apr.2008"
@@ -31,6 +33,7 @@ static const char *const version =
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
@@ -44,20 +47,21 @@ static const char *const version =
#include <linux/crc32.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <asm/irq.h>
/*
* PCI device identifiers for "new style" Linux PCI Device Drivers
*/
-static struct pci_device_id pcnet32_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(pcnet32_pci_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME), },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE), },
@@ -78,10 +82,10 @@ static int cards_found;
/*
* VLB I/O addresses
*/
-static unsigned int pcnet32_portlist[] __initdata =
+static unsigned int pcnet32_portlist[] =
{ 0x300, 0x320, 0x340, 0x360, 0 };
-static int pcnet32_debug = 0;
+static int pcnet32_debug;
static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */
static int pcnet32vlb; /* check for VLB cards ? */
@@ -266,7 +270,7 @@ struct pcnet32_private {
struct sk_buff **rx_skbuff;
dma_addr_t *tx_dma_addr;
dma_addr_t *rx_dma_addr;
- struct pcnet32_access a;
+ const struct pcnet32_access *a;
spinlock_t lock; /* Guard lock */
unsigned int cur_rx, cur_tx; /* The next free ring entry */
unsigned int rx_ring_size; /* current rx ring size */
@@ -291,19 +295,22 @@ struct pcnet32_private {
struct net_device *next;
struct mii_if_info mii_if;
struct timer_list watchdog_timer;
- struct timer_list blink_timer;
u32 msg_enable; /* debug message level */
/* each bit indicates an available PHY */
u32 phymask;
unsigned short chip_version; /* which variant this is */
+
+ /* saved registers during ethtool blink */
+ u16 save_regs[4];
};
static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
static int pcnet32_probe1(unsigned long, int, struct pci_dev *);
static int pcnet32_open(struct net_device *);
static int pcnet32_init_ring(struct net_device *);
-static int pcnet32_start_xmit(struct sk_buff *, struct net_device *);
+static netdev_tx_t pcnet32_start_xmit(struct sk_buff *,
+ struct net_device *);
static void pcnet32_tx_timeout(struct net_device *dev);
static irqreturn_t pcnet32_interrupt(int, void *);
static int pcnet32_close(struct net_device *);
@@ -319,8 +326,6 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits);
static void pcnet32_ethtool_test(struct net_device *dev,
struct ethtool_test *eth_test, u64 * data);
static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1);
-static int pcnet32_phys_id(struct net_device *dev, u32 data);
-static void pcnet32_led_blink_callback(struct net_device *dev);
static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr);
@@ -371,10 +376,10 @@ static void pcnet32_wio_reset(unsigned long addr)
static int pcnet32_wio_check(unsigned long addr)
{
outw(88, addr + PCNET32_WIO_RAP);
- return (inw(addr + PCNET32_WIO_RAP) == 88);
+ return inw(addr + PCNET32_WIO_RAP) == 88;
}
-static struct pcnet32_access pcnet32_wio = {
+static const struct pcnet32_access pcnet32_wio = {
.read_csr = pcnet32_wio_read_csr,
.write_csr = pcnet32_wio_write_csr,
.read_bcr = pcnet32_wio_read_bcr,
@@ -387,7 +392,7 @@ static struct pcnet32_access pcnet32_wio = {
static u16 pcnet32_dwio_read_csr(unsigned long addr, int index)
{
outl(index, addr + PCNET32_DWIO_RAP);
- return (inl(addr + PCNET32_DWIO_RDP) & 0xffff);
+ return inl(addr + PCNET32_DWIO_RDP) & 0xffff;
}
static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val)
@@ -399,7 +404,7 @@ static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val)
static u16 pcnet32_dwio_read_bcr(unsigned long addr, int index)
{
outl(index, addr + PCNET32_DWIO_RAP);
- return (inl(addr + PCNET32_DWIO_BDP) & 0xffff);
+ return inl(addr + PCNET32_DWIO_BDP) & 0xffff;
}
static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val)
@@ -410,7 +415,7 @@ static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val)
static u16 pcnet32_dwio_read_rap(unsigned long addr)
{
- return (inl(addr + PCNET32_DWIO_RAP) & 0xffff);
+ return inl(addr + PCNET32_DWIO_RAP) & 0xffff;
}
static void pcnet32_dwio_write_rap(unsigned long addr, u16 val)
@@ -426,10 +431,10 @@ static void pcnet32_dwio_reset(unsigned long addr)
static int pcnet32_dwio_check(unsigned long addr)
{
outl(88, addr + PCNET32_DWIO_RAP);
- return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88);
+ return (inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88;
}
-static struct pcnet32_access pcnet32_dwio = {
+static const struct pcnet32_access pcnet32_dwio = {
.read_csr = pcnet32_dwio_read_csr,
.write_csr = pcnet32_dwio_write_csr,
.read_bcr = pcnet32_dwio_read_bcr,
@@ -443,7 +448,7 @@ static void pcnet32_netif_stop(struct net_device *dev)
{
struct pcnet32_private *lp = netdev_priv(dev);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
napi_disable(&lp->napi);
netif_tx_disable(dev);
}
@@ -455,9 +460,9 @@ static void pcnet32_netif_start(struct net_device *dev)
u16 val;
netif_wake_queue(dev);
- val = lp->a.read_csr(ioaddr, CSR3);
+ val = lp->a->read_csr(ioaddr, CSR3);
val &= 0x00ff;
- lp->a.write_csr(ioaddr, CSR3, val);
+ lp->a->write_csr(ioaddr, CSR3, val);
napi_enable(&lp->napi);
}
@@ -484,31 +489,20 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev,
(1 << size),
&new_ring_dma_addr);
if (new_tx_ring == NULL) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
- "%s: Consistent memory allocation failed.\n",
- dev->name);
+ netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
return;
}
memset(new_tx_ring, 0, sizeof(struct pcnet32_tx_head) * (1 << size));
- new_dma_addr_list = kcalloc((1 << size), sizeof(dma_addr_t),
- GFP_ATOMIC);
- if (!new_dma_addr_list) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
- "%s: Memory allocation failed.\n", dev->name);
+ new_dma_addr_list = kcalloc(1 << size, sizeof(dma_addr_t),
+ GFP_ATOMIC);
+ if (!new_dma_addr_list)
goto free_new_tx_ring;
- }
- new_skb_list = kcalloc((1 << size), sizeof(struct sk_buff *),
- GFP_ATOMIC);
- if (!new_skb_list) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
- "%s: Memory allocation failed.\n", dev->name);
+ new_skb_list = kcalloc(1 << size, sizeof(struct sk_buff *),
+ GFP_ATOMIC);
+ if (!new_skb_list)
goto free_new_lists;
- }
kfree(lp->tx_skbuff);
kfree(lp->tx_dma_addr);
@@ -526,15 +520,14 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev,
lp->tx_skbuff = new_skb_list;
return;
- free_new_lists:
+free_new_lists:
kfree(new_dma_addr_list);
- free_new_tx_ring:
+free_new_tx_ring:
pci_free_consistent(lp->pci_dev,
sizeof(struct pcnet32_tx_head) *
(1 << size),
new_tx_ring,
new_ring_dma_addr);
- return;
}
/*
@@ -556,55 +549,42 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
struct pcnet32_rx_head *new_rx_ring;
struct sk_buff **new_skb_list;
int new, overlap;
+ unsigned int entries = 1 << size;
new_rx_ring = pci_alloc_consistent(lp->pci_dev,
sizeof(struct pcnet32_rx_head) *
- (1 << size),
+ entries,
&new_ring_dma_addr);
if (new_rx_ring == NULL) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
- "%s: Consistent memory allocation failed.\n",
- dev->name);
+ netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
return;
}
- memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * (1 << size));
+ memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * entries);
- new_dma_addr_list = kcalloc((1 << size), sizeof(dma_addr_t),
- GFP_ATOMIC);
- if (!new_dma_addr_list) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
- "%s: Memory allocation failed.\n", dev->name);
+ new_dma_addr_list = kcalloc(entries, sizeof(dma_addr_t), GFP_ATOMIC);
+ if (!new_dma_addr_list)
goto free_new_rx_ring;
- }
- new_skb_list = kcalloc((1 << size), sizeof(struct sk_buff *),
- GFP_ATOMIC);
- if (!new_skb_list) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR
- "%s: Memory allocation failed.\n", dev->name);
+ new_skb_list = kcalloc(entries, sizeof(struct sk_buff *), GFP_ATOMIC);
+ if (!new_skb_list)
goto free_new_lists;
- }
/* first copy the current receive buffers */
- overlap = min(size, lp->rx_ring_size);
+ overlap = min(entries, lp->rx_ring_size);
for (new = 0; new < overlap; new++) {
new_rx_ring[new] = lp->rx_ring[new];
new_dma_addr_list[new] = lp->rx_dma_addr[new];
new_skb_list[new] = lp->rx_skbuff[new];
}
/* now allocate any new buffers needed */
- for (; new < size; new++ ) {
+ for (; new < entries; new++) {
struct sk_buff *rx_skbuff;
- new_skb_list[new] = dev_alloc_skb(PKT_BUF_SKB);
- if (!(rx_skbuff = new_skb_list[new])) {
+ new_skb_list[new] = netdev_alloc_skb(dev, PKT_BUF_SKB);
+ rx_skbuff = new_skb_list[new];
+ if (!rx_skbuff) {
/* keep the original lists and buffers */
- if (netif_msg_drv(lp))
- printk(KERN_ERR
- "%s: pcnet32_realloc_rx_ring dev_alloc_skb failed.\n",
- dev->name);
+ netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n",
+ __func__);
goto free_all_new;
}
skb_reserve(rx_skbuff, NET_IP_ALIGN);
@@ -612,6 +592,13 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
new_dma_addr_list[new] =
pci_map_single(lp->pci_dev, rx_skbuff->data,
PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(lp->pci_dev,
+ new_dma_addr_list[new])) {
+ netif_err(lp, drv, dev, "%s dma mapping failed\n",
+ __func__);
+ dev_kfree_skb(new_skb_list[new]);
+ goto free_all_new;
+ }
new_rx_ring[new].base = cpu_to_le32(new_dma_addr_list[new]);
new_rx_ring[new].buf_length = cpu_to_le16(NEG_BUF_SIZE);
new_rx_ring[new].status = cpu_to_le16(0x8000);
@@ -619,8 +606,12 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
/* and free any unneeded buffers */
for (; new < lp->rx_ring_size; new++) {
if (lp->rx_skbuff[new]) {
- pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[new],
- PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ if (!pci_dma_mapping_error(lp->pci_dev,
+ lp->rx_dma_addr[new]))
+ pci_unmap_single(lp->pci_dev,
+ lp->rx_dma_addr[new],
+ PKT_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
dev_kfree_skb(lp->rx_skbuff[new]);
}
}
@@ -632,7 +623,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
lp->rx_ring_size, lp->rx_ring,
lp->rx_ring_dma_addr);
- lp->rx_ring_size = (1 << size);
+ lp->rx_ring_size = entries;
lp->rx_mod_mask = lp->rx_ring_size - 1;
lp->rx_len_bits = (size << 4);
lp->rx_ring = new_rx_ring;
@@ -641,24 +632,26 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
lp->rx_skbuff = new_skb_list;
return;
- free_all_new:
- for (; --new >= lp->rx_ring_size; ) {
+free_all_new:
+ while (--new >= lp->rx_ring_size) {
if (new_skb_list[new]) {
- pci_unmap_single(lp->pci_dev, new_dma_addr_list[new],
- PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ if (!pci_dma_mapping_error(lp->pci_dev,
+ new_dma_addr_list[new]))
+ pci_unmap_single(lp->pci_dev,
+ new_dma_addr_list[new],
+ PKT_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
dev_kfree_skb(new_skb_list[new]);
}
}
kfree(new_skb_list);
- free_new_lists:
+free_new_lists:
kfree(new_dma_addr_list);
- free_new_rx_ring:
+free_new_rx_ring:
pci_free_consistent(lp->pci_dev,
- sizeof(struct pcnet32_rx_head) *
- (1 << size),
+ sizeof(struct pcnet32_rx_head) * entries,
new_rx_ring,
new_ring_dma_addr);
- return;
}
static void pcnet32_purge_rx_ring(struct net_device *dev)
@@ -671,8 +664,12 @@ static void pcnet32_purge_rx_ring(struct net_device *dev)
lp->rx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->rx_skbuff[i]) {
- pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i],
- PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ if (!pci_dma_mapping_error(lp->pci_dev,
+ lp->rx_dma_addr[i]))
+ pci_unmap_single(lp->pci_dev,
+ lp->rx_dma_addr[i],
+ PKT_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(lp->rx_skbuff[i]);
}
lp->rx_skbuff[i] = NULL;
@@ -723,12 +720,14 @@ static void pcnet32_get_drvinfo(struct net_device *dev,
{
struct pcnet32_private *lp = netdev_priv(dev);
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
if (lp->pci_dev)
- strcpy(info->bus_info, pci_name(lp->pci_dev));
+ strlcpy(info->bus_info, pci_name(lp->pci_dev),
+ sizeof(info->bus_info));
else
- sprintf(info->bus_info, "VLB 0x%lx", dev->base_addr);
+ snprintf(info->bus_info, sizeof(info->bus_info),
+ "VLB 0x%lx", dev->base_addr);
}
static u32 pcnet32_get_link(struct net_device *dev)
@@ -742,7 +741,7 @@ static u32 pcnet32_get_link(struct net_device *dev)
r = mii_link_ok(&lp->mii_if);
} else if (lp->chip_version >= PCNET32_79C970A) {
ulong ioaddr = dev->base_addr; /* card base I/O address */
- r = (lp->a.read_bcr(ioaddr, 4) != 0xc0);
+ r = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
} else { /* can not detect link on really old chips */
r = 1;
}
@@ -804,7 +803,7 @@ static int pcnet32_set_ringparam(struct net_device *dev,
pcnet32_netif_stop(dev);
spin_lock_irqsave(&lp->lock, flags);
- lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */
+ lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */
size = min(ering->tx_pending, (unsigned int)TX_MAX_RING_SIZE);
@@ -835,16 +834,14 @@ static int pcnet32_set_ringparam(struct net_device *dev,
spin_unlock_irqrestore(&lp->lock, flags);
- if (netif_msg_drv(lp))
- printk(KERN_INFO
- "%s: Ring Param Settings: RX: %d, TX: %d\n", dev->name,
- lp->rx_ring_size, lp->tx_ring_size);
+ netif_info(lp, drv, dev, "Ring Param Settings: RX: %d, TX: %d\n",
+ lp->rx_ring_size, lp->tx_ring_size);
return 0;
}
static void pcnet32_get_strings(struct net_device *dev, u32 stringset,
- u8 * data)
+ u8 *data)
{
memcpy(data, pcnet32_gstrings_test, sizeof(pcnet32_gstrings_test));
}
@@ -868,23 +865,21 @@ static void pcnet32_ethtool_test(struct net_device *dev,
if (test->flags == ETH_TEST_FL_OFFLINE) {
rc = pcnet32_loopback_test(dev, data);
if (rc) {
- if (netif_msg_hw(lp))
- printk(KERN_DEBUG "%s: Loopback test failed.\n",
- dev->name);
+ netif_printk(lp, hw, KERN_DEBUG, dev,
+ "Loopback test failed\n");
test->flags |= ETH_TEST_FL_FAILED;
- } else if (netif_msg_hw(lp))
- printk(KERN_DEBUG "%s: Loopback test passed.\n",
- dev->name);
- } else if (netif_msg_hw(lp))
- printk(KERN_DEBUG
- "%s: No tests to run (specify 'Offline' on ethtool).",
- dev->name);
+ } else
+ netif_printk(lp, hw, KERN_DEBUG, dev,
+ "Loopback test passed\n");
+ } else
+ netif_printk(lp, hw, KERN_DEBUG, dev,
+ "No tests to run (specify 'Offline' on ethtool)\n");
} /* end pcnet32_ethtool_test */
static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
{
struct pcnet32_private *lp = netdev_priv(dev);
- struct pcnet32_access *a = &lp->a; /* access to registers */
+ const struct pcnet32_access *a = lp->a; /* access to registers */
ulong ioaddr = dev->base_addr; /* card base I/O address */
struct sk_buff *skb; /* sk buff */
int x, i; /* counters */
@@ -904,59 +899,64 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
pcnet32_netif_stop(dev);
spin_lock_irqsave(&lp->lock, flags);
- lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */
+ lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */
numbuffs = min(numbuffs, (int)min(lp->rx_ring_size, lp->tx_ring_size));
/* Reset the PCNET32 */
- lp->a.reset(ioaddr);
- lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
+ lp->a->reset(ioaddr);
+ lp->a->write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
/* switch pcnet32 to 32bit mode */
- lp->a.write_bcr(ioaddr, 20, 2);
+ lp->a->write_bcr(ioaddr, 20, 2);
/* purge & init rings but don't actually restart */
pcnet32_restart(dev, 0x0000);
- lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */
+ lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */
/* Initialize Transmit buffers. */
size = data_len + 15;
for (x = 0; x < numbuffs; x++) {
- if (!(skb = dev_alloc_skb(size))) {
- if (netif_msg_hw(lp))
- printk(KERN_DEBUG
- "%s: Cannot allocate skb at line: %d!\n",
- dev->name, __LINE__);
+ skb = netdev_alloc_skb(dev, size);
+ if (!skb) {
+ netif_printk(lp, hw, KERN_DEBUG, dev,
+ "Cannot allocate skb at line: %d!\n",
+ __LINE__);
goto clean_up;
- } else {
- packet = skb->data;
- skb_put(skb, size); /* create space for data */
- lp->tx_skbuff[x] = skb;
- lp->tx_ring[x].length = cpu_to_le16(-skb->len);
- lp->tx_ring[x].misc = 0;
-
- /* put DA and SA into the skb */
- for (i = 0; i < 6; i++)
- *packet++ = dev->dev_addr[i];
- for (i = 0; i < 6; i++)
- *packet++ = dev->dev_addr[i];
- /* type */
- *packet++ = 0x08;
- *packet++ = 0x06;
- /* packet number */
- *packet++ = x;
- /* fill packet with data */
- for (i = 0; i < data_len; i++)
- *packet++ = i;
-
- lp->tx_dma_addr[x] =
- pci_map_single(lp->pci_dev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
- lp->tx_ring[x].base = cpu_to_le32(lp->tx_dma_addr[x]);
- wmb(); /* Make sure owner changes after all others are visible */
- lp->tx_ring[x].status = cpu_to_le16(status);
}
+ packet = skb->data;
+ skb_put(skb, size); /* create space for data */
+ lp->tx_skbuff[x] = skb;
+ lp->tx_ring[x].length = cpu_to_le16(-skb->len);
+ lp->tx_ring[x].misc = 0;
+
+ /* put DA and SA into the skb */
+ for (i = 0; i < 6; i++)
+ *packet++ = dev->dev_addr[i];
+ for (i = 0; i < 6; i++)
+ *packet++ = dev->dev_addr[i];
+ /* type */
+ *packet++ = 0x08;
+ *packet++ = 0x06;
+ /* packet number */
+ *packet++ = x;
+ /* fill packet with data */
+ for (i = 0; i < data_len; i++)
+ *packet++ = i;
+
+ lp->tx_dma_addr[x] =
+ pci_map_single(lp->pci_dev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[x])) {
+ netif_printk(lp, hw, KERN_DEBUG, dev,
+ "DMA mapping error at line: %d!\n",
+ __LINE__);
+ goto clean_up;
+ }
+ lp->tx_ring[x].base = cpu_to_le32(lp->tx_dma_addr[x]);
+ wmb(); /* Make sure owner changes after all others are visible */
+ lp->tx_ring[x].status = cpu_to_le16(status);
}
x = a->read_bcr(ioaddr, 32); /* set internal loopback in BCR32 */
@@ -964,10 +964,10 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
/* set int loopback in CSR15 */
x = a->read_csr(ioaddr, CSR15) & 0xfffc;
- lp->a.write_csr(ioaddr, CSR15, x | 0x0044);
+ lp->a->write_csr(ioaddr, CSR15, x | 0x0044);
teststatus = cpu_to_le16(0x8000);
- lp->a.write_csr(ioaddr, CSR0, CSR0_START); /* Set STRT bit */
+ lp->a->write_csr(ioaddr, CSR0, CSR0_START); /* Set STRT bit */
/* Check status of descriptors */
for (x = 0; x < numbuffs; x++) {
@@ -981,25 +981,22 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
ticks++;
}
if (ticks == 200) {
- if (netif_msg_hw(lp))
- printk("%s: Desc %d failed to reset!\n",
- dev->name, x);
+ netif_err(lp, hw, dev, "Desc %d failed to reset!\n", x);
break;
}
}
- lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */
+ lp->a->write_csr(ioaddr, CSR0, CSR0_STOP); /* Set STOP bit */
wmb();
if (netif_msg_hw(lp) && netif_msg_pktdata(lp)) {
- printk(KERN_DEBUG "%s: RX loopback packets:\n", dev->name);
+ netdev_printk(KERN_DEBUG, dev, "RX loopback packets:\n");
for (x = 0; x < numbuffs; x++) {
- printk(KERN_DEBUG "%s: Packet %d:\n", dev->name, x);
+ netdev_printk(KERN_DEBUG, dev, "Packet %d: ", x);
skb = lp->rx_skbuff[x];
- for (i = 0; i < size; i++) {
- printk("%02x ", *(skb->data + i));
- }
- printk("\n");
+ for (i = 0; i < size; i++)
+ pr_cont(" %02x", *(skb->data + i));
+ pr_cont("\n");
}
}
@@ -1010,11 +1007,9 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
packet = lp->tx_skbuff[x]->data;
for (i = 0; i < size; i++) {
if (*(skb->data + i) != packet[i]) {
- if (netif_msg_hw(lp))
- printk(KERN_DEBUG
- "%s: Error in compare! %2x - %02x %02x\n",
- dev->name, i, *(skb->data + i),
- packet[i]);
+ netif_printk(lp, hw, KERN_DEBUG, dev,
+ "Error in compare! %2x - %02x %02x\n",
+ i, *(skb->data + i), packet[i]);
rc = 1;
break;
}
@@ -1022,7 +1017,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
x++;
}
- clean_up:
+clean_up:
*data1 = rc;
pcnet32_purge_tx_ring(dev);
@@ -1037,68 +1032,47 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
pcnet32_restart(dev, CSR0_NORMAL);
} else {
pcnet32_purge_rx_ring(dev);
- lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */
+ lp->a->write_bcr(ioaddr, 20, 4); /* return to 16bit mode */
}
spin_unlock_irqrestore(&lp->lock, flags);
- return (rc);
+ return rc;
} /* end pcnet32_loopback_test */
-static void pcnet32_led_blink_callback(struct net_device *dev)
+static int pcnet32_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct pcnet32_private *lp = netdev_priv(dev);
- struct pcnet32_access *a = &lp->a;
+ const struct pcnet32_access *a = lp->a;
ulong ioaddr = dev->base_addr;
unsigned long flags;
int i;
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++) {
- a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
- }
- spin_unlock_irqrestore(&lp->lock, flags);
-
- mod_timer(&lp->blink_timer, PCNET32_BLINK_TIMEOUT);
-}
-
-static int pcnet32_phys_id(struct net_device *dev, u32 data)
-{
- struct pcnet32_private *lp = netdev_priv(dev);
- struct pcnet32_access *a = &lp->a;
- ulong ioaddr = dev->base_addr;
- unsigned long flags;
- int i, regs[4];
-
- if (!lp->blink_timer.function) {
- init_timer(&lp->blink_timer);
- lp->blink_timer.function = (void *)pcnet32_led_blink_callback;
- lp->blink_timer.data = (unsigned long)dev;
- }
-
- /* Save the current value of the bcrs */
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++) {
- regs[i - 4] = a->read_bcr(ioaddr, i);
- }
- spin_unlock_irqrestore(&lp->lock, flags);
-
- mod_timer(&lp->blink_timer, jiffies);
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* AV: the limit here makes no sense whatsoever */
- if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)))
- data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ);
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ /* Save the current value of the bcrs */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ lp->save_regs[i - 4] = a->read_bcr(ioaddr, i);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ return 2; /* cycle on/off twice per second */
- msleep_interruptible(data * 1000);
- del_timer_sync(&lp->blink_timer);
+ case ETHTOOL_ID_ON:
+ case ETHTOOL_ID_OFF:
+ /* Blink the led */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
+ spin_unlock_irqrestore(&lp->lock, flags);
+ break;
- /* Restore the original value of the bcrs */
- spin_lock_irqsave(&lp->lock, flags);
- for (i = 4; i < 8; i++) {
- a->write_bcr(ioaddr, i, regs[i - 4]);
+ case ETHTOOL_ID_INACTIVE:
+ /* Restore the original value of the bcrs */
+ spin_lock_irqsave(&lp->lock, flags);
+ for (i = 4; i < 8; i++)
+ a->write_bcr(ioaddr, i, lp->save_regs[i - 4]);
+ spin_unlock_irqrestore(&lp->lock, flags);
}
- spin_unlock_irqrestore(&lp->lock, flags);
-
return 0;
}
@@ -1110,7 +1084,7 @@ static int pcnet32_suspend(struct net_device *dev, unsigned long *flags,
{
int csr5;
struct pcnet32_private *lp = netdev_priv(dev);
- struct pcnet32_access *a = &lp->a;
+ const struct pcnet32_access *a = lp->a;
ulong ioaddr = dev->base_addr;
int ticks;
@@ -1133,10 +1107,8 @@ static int pcnet32_suspend(struct net_device *dev, unsigned long *flags,
spin_lock_irqsave(&lp->lock, *flags);
ticks++;
if (ticks > 200) {
- if (netif_msg_hw(lp))
- printk(KERN_DEBUG
- "%s: Error getting into suspend!\n",
- dev->name);
+ netif_printk(lp, hw, KERN_DEBUG, dev,
+ "Error getting into suspend!\n");
return 0;
}
}
@@ -1181,53 +1153,58 @@ static void pcnet32_rx_entry(struct net_device *dev,
/* Discard oversize frames. */
if (unlikely(pkt_len > PKT_BUF_SIZE)) {
- if (netif_msg_drv(lp))
- printk(KERN_ERR "%s: Impossible packet size %d!\n",
- dev->name, pkt_len);
+ netif_err(lp, drv, dev, "Impossible packet size %d!\n",
+ pkt_len);
dev->stats.rx_errors++;
return;
}
if (pkt_len < 60) {
- if (netif_msg_rx_err(lp))
- printk(KERN_ERR "%s: Runt packet!\n", dev->name);
+ netif_err(lp, rx_err, dev, "Runt packet!\n");
dev->stats.rx_errors++;
return;
}
if (pkt_len > rx_copybreak) {
struct sk_buff *newskb;
+ dma_addr_t new_dma_addr;
- if ((newskb = dev_alloc_skb(PKT_BUF_SKB))) {
+ newskb = netdev_alloc_skb(dev, PKT_BUF_SKB);
+ /*
+ * map the new buffer, if mapping fails, drop the packet and
+ * reuse the old buffer
+ */
+ if (newskb) {
skb_reserve(newskb, NET_IP_ALIGN);
- skb = lp->rx_skbuff[entry];
- pci_unmap_single(lp->pci_dev,
- lp->rx_dma_addr[entry],
- PKT_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
- skb_put(skb, pkt_len);
- lp->rx_skbuff[entry] = newskb;
- lp->rx_dma_addr[entry] =
- pci_map_single(lp->pci_dev,
- newskb->data,
- PKT_BUF_SIZE,
- PCI_DMA_FROMDEVICE);
- rxp->base = cpu_to_le32(lp->rx_dma_addr[entry]);
- rx_in_place = 1;
+ new_dma_addr = pci_map_single(lp->pci_dev,
+ newskb->data,
+ PKT_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(lp->pci_dev, new_dma_addr)) {
+ netif_err(lp, rx_err, dev,
+ "DMA mapping error.\n");
+ dev_kfree_skb(newskb);
+ skb = NULL;
+ } else {
+ skb = lp->rx_skbuff[entry];
+ pci_unmap_single(lp->pci_dev,
+ lp->rx_dma_addr[entry],
+ PKT_BUF_SIZE,
+ PCI_DMA_FROMDEVICE);
+ skb_put(skb, pkt_len);
+ lp->rx_skbuff[entry] = newskb;
+ lp->rx_dma_addr[entry] = new_dma_addr;
+ rxp->base = cpu_to_le32(new_dma_addr);
+ rx_in_place = 1;
+ }
} else
skb = NULL;
- } else {
- skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN);
- }
+ } else
+ skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN);
if (skb == NULL) {
- if (netif_msg_drv(lp))
- printk(KERN_ERR
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
dev->stats.rx_dropped++;
return;
}
- skb->dev = dev;
if (!rx_in_place) {
skb_reserve(skb, NET_IP_ALIGN);
skb_put(skb, pkt_len); /* Make room */
@@ -1246,9 +1223,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
dev->stats.rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, dev);
netif_receive_skb(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
- return;
}
static int pcnet32_rx(struct net_device *dev, int budget)
@@ -1296,11 +1271,9 @@ static int pcnet32_tx(struct net_device *dev)
/* There was a major error, log it. */
int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
dev->stats.tx_errors++;
- if (netif_msg_tx_err(lp))
- printk(KERN_ERR
- "%s: Tx error status=%04x err_status=%08x\n",
- dev->name, status,
- err_status);
+ netif_err(lp, tx_err, dev,
+ "Tx error status=%04x err_status=%08x\n",
+ status, err_status);
if (err_status & 0x04000000)
dev->stats.tx_aborted_errors++;
if (err_status & 0x08000000)
@@ -1312,10 +1285,7 @@ static int pcnet32_tx(struct net_device *dev)
dev->stats.tx_fifo_errors++;
/* Ackk! On FIFO errors the Tx unit is turned off! */
/* Remove this verbosity later! */
- if (netif_msg_tx_err(lp))
- printk(KERN_ERR
- "%s: Tx FIFO error!\n",
- dev->name);
+ netif_err(lp, tx_err, dev, "Tx FIFO error!\n");
must_restart = 1;
}
#else
@@ -1324,10 +1294,7 @@ static int pcnet32_tx(struct net_device *dev)
if (!lp->dxsuflo) { /* If controller doesn't recover ... */
/* Ackk! On FIFO errors the Tx unit is turned off! */
/* Remove this verbosity later! */
- if (netif_msg_tx_err(lp))
- printk(KERN_ERR
- "%s: Tx FIFO error!\n",
- dev->name);
+ netif_err(lp, tx_err, dev, "Tx FIFO error!\n");
must_restart = 1;
}
}
@@ -1353,11 +1320,8 @@ static int pcnet32_tx(struct net_device *dev)
delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
if (delta > lp->tx_ring_size) {
- if (netif_msg_drv(lp))
- printk(KERN_ERR
- "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
- dev->name, dirty_tx, lp->cur_tx,
- lp->tx_full);
+ netif_err(lp, drv, dev, "out-of-sync dirty pointer, %d vs. %d, full=%d\n",
+ dirty_tx, lp->cur_tx, lp->tx_full);
dirty_tx += lp->tx_ring_size;
delta -= lp->tx_ring_size;
}
@@ -1388,8 +1352,8 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
spin_lock_irqsave(&lp->lock, flags);
if (pcnet32_tx(dev)) {
/* reset the chip to clear the error condition, then restart */
- lp->a.reset(ioaddr);
- lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
+ lp->a->reset(ioaddr);
+ lp->a->write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
pcnet32_restart(dev, CSR0_START);
netif_wake_queue(dev);
}
@@ -1398,16 +1362,16 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
if (work_done < budget) {
spin_lock_irqsave(&lp->lock, flags);
- __netif_rx_complete(dev, napi);
+ __napi_complete(napi);
/* clear interrupt masks */
- val = lp->a.read_csr(ioaddr, CSR3);
+ val = lp->a->read_csr(ioaddr, CSR3);
val &= 0x00ff;
- lp->a.write_csr(ioaddr, CSR3, val);
+ lp->a->write_csr(ioaddr, CSR3, val);
/* Set interrupt enable. */
- lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
- mmiowb();
+ lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN);
+
spin_unlock_irqrestore(&lp->lock, flags);
}
return work_done;
@@ -1420,7 +1384,7 @@ static int pcnet32_get_regs_len(struct net_device *dev)
struct pcnet32_private *lp = netdev_priv(dev);
int j = lp->phycount * PCNET32_REGS_PER_PHY;
- return ((PCNET32_NUM_REGS + j) * sizeof(u16));
+ return (PCNET32_NUM_REGS + j) * sizeof(u16);
}
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
@@ -1429,7 +1393,7 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
int i, csr0;
u16 *buff = ptr;
struct pcnet32_private *lp = netdev_priv(dev);
- struct pcnet32_access *a = &lp->a;
+ const struct pcnet32_access *a = lp->a;
ulong ioaddr = dev->base_addr;
unsigned long flags;
@@ -1444,21 +1408,20 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
*buff++ = inw(ioaddr + i);
/* read control and status registers */
- for (i = 0; i < 90; i++) {
+ for (i = 0; i < 90; i++)
*buff++ = a->read_csr(ioaddr, i);
- }
*buff++ = a->read_csr(ioaddr, 112);
*buff++ = a->read_csr(ioaddr, 114);
/* read bus configuration registers */
- for (i = 0; i < 30; i++) {
+ for (i = 0; i < 30; i++)
*buff++ = a->read_bcr(ioaddr, i);
- }
+
*buff++ = 0; /* skip bcr30 so as not to hang 79C976 */
- for (i = 31; i < 36; i++) {
+
+ for (i = 31; i < 36; i++)
*buff++ = a->read_bcr(ioaddr, i);
- }
/* read mii phy registers */
if (lp->mii) {
@@ -1466,9 +1429,9 @@ static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
for (j = 0; j < PCNET32_MAX_PHYS; j++) {
if (lp->phymask & (1 << j)) {
for (i = 0; i < PCNET32_REGS_PER_PHY; i++) {
- lp->a.write_bcr(ioaddr, 33,
+ lp->a->write_bcr(ioaddr, 33,
(j << 5) | i);
- *buff++ = lp->a.read_bcr(ioaddr, 34);
+ *buff++ = lp->a->read_bcr(ioaddr, 34);
}
}
}
@@ -1497,7 +1460,7 @@ static const struct ethtool_ops pcnet32_ethtool_ops = {
.set_ringparam = pcnet32_set_ringparam,
.get_strings = pcnet32_get_strings,
.self_test = pcnet32_ethtool_test,
- .phys_id = pcnet32_phys_id,
+ .set_phys_id = pcnet32_set_phys_id,
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
.get_sset_count = pcnet32_get_sset_count,
@@ -1506,7 +1469,7 @@ static const struct ethtool_ops pcnet32_ethtool_ops = {
/* only probes for non-PCI devices, the rest are handled by
* pci_register_driver via pcnet32_probe_pci */
-static void __devinit pcnet32_probe_vlbus(unsigned int *pcnet32_portlist)
+static void pcnet32_probe_vlbus(unsigned int *pcnet32_portlist)
{
unsigned int *port, ioaddr;
@@ -1515,8 +1478,8 @@ static void __devinit pcnet32_probe_vlbus(unsigned int *pcnet32_portlist)
if (request_region
(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_vlbus")) {
/* check if there is really a pcnet chip on that ioaddr */
- if ((inb(ioaddr + 14) == 0x57)
- && (inb(ioaddr + 15) == 0x57)) {
+ if ((inb(ioaddr + 14) == 0x57) &&
+ (inb(ioaddr + 15) == 0x57)) {
pcnet32_probe1(ioaddr, 0, NULL);
} else {
release_region(ioaddr, PCNET32_TOTAL_SIZE);
@@ -1525,7 +1488,7 @@ static void __devinit pcnet32_probe_vlbus(unsigned int *pcnet32_portlist)
}
}
-static int __devinit
+static int
pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned long ioaddr;
@@ -1534,8 +1497,7 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
err = pci_enable_device(pdev);
if (err < 0) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_ERR PFX
- "failed to enable device -- err=%d\n", err);
+ pr_err("failed to enable device -- err=%d\n", err);
return err;
}
pci_set_master(pdev);
@@ -1543,37 +1505,49 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
ioaddr = pci_resource_start(pdev, 0);
if (!ioaddr) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_ERR PFX
- "card has no PCI IO resources, aborting\n");
+ pr_err("card has no PCI IO resources, aborting\n");
return -ENODEV;
}
if (!pci_dma_supported(pdev, PCNET32_DMA_MASK)) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_ERR PFX
- "architecture does not support 32bit PCI busmaster DMA\n");
+ pr_err("architecture does not support 32bit PCI busmaster DMA\n");
return -ENODEV;
}
- if (request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci") ==
- NULL) {
+ if (!request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci")) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_ERR PFX
- "io address range already allocated\n");
+ pr_err("io address range already allocated\n");
return -EBUSY;
}
err = pcnet32_probe1(ioaddr, 1, pdev);
- if (err < 0) {
+ if (err < 0)
pci_disable_device(pdev);
- }
+
return err;
}
+static const struct net_device_ops pcnet32_netdev_ops = {
+ .ndo_open = pcnet32_open,
+ .ndo_stop = pcnet32_close,
+ .ndo_start_xmit = pcnet32_start_xmit,
+ .ndo_tx_timeout = pcnet32_tx_timeout,
+ .ndo_get_stats = pcnet32_get_stats,
+ .ndo_set_rx_mode = pcnet32_set_multicast_list,
+ .ndo_do_ioctl = pcnet32_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = pcnet32_poll_controller,
+#endif
+};
+
/* pcnet32_probe1
* Called from both pcnet32_probe_vlbus and pcnet_probe_pci.
* pdev will be NULL when called from pcnet32_probe_vlbus.
*/
-static int __devinit
+static int
pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
{
struct pcnet32_private *lp;
@@ -1582,8 +1556,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
int chip_version;
char *chipname;
struct net_device *dev;
- struct pcnet32_access *a = NULL;
- u8 promaddr[6];
+ const struct pcnet32_access *a = NULL;
+ u8 promaddr[ETH_ALEN];
int ret = -ENODEV;
/* reset the chip */
@@ -1594,21 +1568,23 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
a = &pcnet32_wio;
} else {
pcnet32_dwio_reset(ioaddr);
- if (pcnet32_dwio_read_csr(ioaddr, 0) == 4
- && pcnet32_dwio_check(ioaddr)) {
+ if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 &&
+ pcnet32_dwio_check(ioaddr)) {
a = &pcnet32_dwio;
- } else
+ } else {
+ if (pcnet32_debug & NETIF_MSG_PROBE)
+ pr_err("No access methods\n");
goto err_release_region;
+ }
}
chip_version =
a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16);
if ((pcnet32_debug & NETIF_MSG_PROBE) && (pcnet32_debug & NETIF_MSG_HW))
- printk(KERN_INFO " PCnet chip version is %#x.\n",
- chip_version);
+ pr_info(" PCnet chip version is %#x\n", chip_version);
if ((chip_version & 0xfff) != 0x003) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_INFO PFX "Unsupported chip version.\n");
+ pr_info("Unsupported chip version\n");
goto err_release_region;
}
@@ -1661,7 +1637,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
if (cards_found < MAX_UNITS && homepna[cards_found])
media |= 1; /* switch to home wiring mode */
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_DEBUG PFX "media set to %sMbit mode.\n",
+ printk(KERN_DEBUG PFX "media set to %sMbit mode\n",
(media & 1) ? "1" : "10");
a->write_bcr(ioaddr, 49, media);
break;
@@ -1677,16 +1653,15 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
break;
default:
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_INFO PFX
- "PCnet version %#x, no PCnet32 chip.\n",
- chip_version);
+ pr_info("PCnet version %#x, no PCnet32 chip\n",
+ chip_version);
goto err_release_region;
}
/*
* On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
* starting until the packet is loaded. Strike one for reliability, lose
- * one for latency - although on PCI this isnt a big loss. Older chips
+ * one for latency - although on PCI this isn't a big loss. Older chips
* have FIFO's smaller than a packet, so you can't do this.
* Turn on BCR18:BurstRdEn and BCR18:BurstWrEn.
*/
@@ -1700,15 +1675,15 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
dev = alloc_etherdev(sizeof(*lp));
if (!dev) {
- if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_ERR PFX "Memory allocation failed.\n");
ret = -ENOMEM;
goto err_release_region;
}
- SET_NETDEV_DEV(dev, &pdev->dev);
+
+ if (pdev)
+ SET_NETDEV_DEV(dev, &pdev->dev);
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_INFO PFX "%s at %#3lx,", chipname, ioaddr);
+ pr_info("%s at %#3lx,", chipname, ioaddr);
/* In most chips, after a chip reset, the ethernet address is read from the
* station address PROM at the base address and programmed into the
@@ -1726,76 +1701,73 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
}
/* read PROM address and compare with CSR address */
- for (i = 0; i < 6; i++)
+ for (i = 0; i < ETH_ALEN; i++)
promaddr[i] = inb(ioaddr + i);
- if (memcmp(promaddr, dev->dev_addr, 6)
- || !is_valid_ether_addr(dev->dev_addr)) {
+ if (!ether_addr_equal(promaddr, dev->dev_addr) ||
+ !is_valid_ether_addr(dev->dev_addr)) {
if (is_valid_ether_addr(promaddr)) {
if (pcnet32_debug & NETIF_MSG_PROBE) {
- printk(" warning: CSR address invalid,\n");
- printk(KERN_INFO
- " using instead PROM address of");
+ pr_cont(" warning: CSR address invalid,\n");
+ pr_info(" using instead PROM address of");
}
- memcpy(dev->dev_addr, promaddr, 6);
+ memcpy(dev->dev_addr, promaddr, ETH_ALEN);
}
}
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
- if (!is_valid_ether_addr(dev->perm_addr))
- memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
+ if (!is_valid_ether_addr(dev->dev_addr))
+ memset(dev->dev_addr, 0, ETH_ALEN);
if (pcnet32_debug & NETIF_MSG_PROBE) {
- DECLARE_MAC_BUF(mac);
- printk(" %s", print_mac(mac, dev->dev_addr));
+ pr_cont(" %pM", dev->dev_addr);
/* Version 0x2623 and 0x2624 */
if (((chip_version + 1) & 0xfffe) == 0x2624) {
i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */
- printk("\n" KERN_INFO " tx_start_pt(0x%04x):", i);
+ pr_info(" tx_start_pt(0x%04x):", i);
switch (i >> 10) {
case 0:
- printk(" 20 bytes,");
+ pr_cont(" 20 bytes,");
break;
case 1:
- printk(" 64 bytes,");
+ pr_cont(" 64 bytes,");
break;
case 2:
- printk(" 128 bytes,");
+ pr_cont(" 128 bytes,");
break;
case 3:
- printk("~220 bytes,");
+ pr_cont("~220 bytes,");
break;
}
i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */
- printk(" BCR18(%x):", i & 0xffff);
+ pr_cont(" BCR18(%x):", i & 0xffff);
if (i & (1 << 5))
- printk("BurstWrEn ");
+ pr_cont("BurstWrEn ");
if (i & (1 << 6))
- printk("BurstRdEn ");
+ pr_cont("BurstRdEn ");
if (i & (1 << 7))
- printk("DWordIO ");
+ pr_cont("DWordIO ");
if (i & (1 << 11))
- printk("NoUFlow ");
+ pr_cont("NoUFlow ");
i = a->read_bcr(ioaddr, 25);
- printk("\n" KERN_INFO " SRAMSIZE=0x%04x,", i << 8);
+ pr_info(" SRAMSIZE=0x%04x,", i << 8);
i = a->read_bcr(ioaddr, 26);
- printk(" SRAM_BND=0x%04x,", i << 8);
+ pr_cont(" SRAM_BND=0x%04x,", i << 8);
i = a->read_bcr(ioaddr, 27);
if (i & (1 << 14))
- printk("LowLatRx");
+ pr_cont("LowLatRx");
}
}
dev->base_addr = ioaddr;
lp = netdev_priv(dev);
/* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
- if ((lp->init_block =
- pci_alloc_consistent(pdev, sizeof(*lp->init_block), &lp->init_dma_addr)) == NULL) {
+ lp->init_block = pci_alloc_consistent(pdev, sizeof(*lp->init_block),
+ &lp->init_dma_addr);
+ if (!lp->init_block) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_ERR PFX
- "Consistent memory allocation failed.\n");
+ pr_err("Consistent memory allocation failed\n");
ret = -ENOMEM;
goto err_free_netdev;
}
@@ -1805,7 +1777,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
spin_lock_init(&lp->lock);
- SET_NETDEV_DEV(dev, &pdev->dev);
lp->name = chipname;
lp->shared_irq = shared;
lp->tx_ring_size = TX_RING_SIZE; /* default tx ring size */
@@ -1821,8 +1792,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
lp->mii = mii;
lp->chip_version = chip_version;
lp->msg_enable = pcnet32_debug;
- if ((cards_found >= MAX_UNITS)
- || (options[cards_found] > sizeof(options_mapping)))
+ if ((cards_found >= MAX_UNITS) ||
+ (options[cards_found] >= sizeof(options_mapping)))
lp->options = PCNET32_PORT_ASEL;
else
lp->options = options_mapping[options[cards_found]];
@@ -1839,13 +1810,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
lp->options |= PCNET32_PORT_FD;
- if (!a) {
- if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_ERR PFX "No access methods\n");
- ret = -ENODEV;
- goto err_free_consistent;
- }
- lp->a = *a;
+ lp->a = a;
/* prior to register_netdev, dev->name is not yet correct */
if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) {
@@ -1853,8 +1818,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
goto err_free_ring;
}
/* detect special T1/E1 WAN card by checking for MAC address */
- if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
- && dev->dev_addr[2] == 0x75)
+ if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 &&
+ dev->dev_addr[2] == 0x75)
lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
lp->init_block->mode = cpu_to_le16(0x0003); /* Disable Rx and Tx. */
@@ -1876,7 +1841,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
if (pdev) { /* use the IRQ provided by PCI */
dev->irq = pdev->irq;
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(" assigned IRQ %d.\n", dev->irq);
+ pr_cont(" assigned IRQ %d\n", dev->irq);
} else {
unsigned long irq_mask = probe_irq_on();
@@ -1892,19 +1857,19 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
dev->irq = probe_irq_off(irq_mask);
if (!dev->irq) {
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(", failed to detect IRQ line.\n");
+ pr_cont(", failed to detect IRQ line\n");
ret = -ENODEV;
goto err_free_ring;
}
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(", probed IRQ %d.\n", dev->irq);
+ pr_cont(", probed IRQ %d\n", dev->irq);
}
/* Set the mii phy_id so that we can query the link state */
if (lp->mii) {
/* lp->phycount and lp->phymask are set to 0 by memset above */
- lp->mii_if.phy_id = ((lp->a.read_bcr(ioaddr, 33)) >> 5) & 0x1f;
+ lp->mii_if.phy_id = ((lp->a->read_bcr(ioaddr, 33)) >> 5) & 0x1f;
/* scan for PHYs */
for (i = 0; i < PCNET32_MAX_PHYS; i++) {
unsigned short id1, id2;
@@ -1921,14 +1886,12 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
lp->phymask |= (1 << i);
lp->mii_if.phy_id = i;
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_INFO PFX
- "Found PHY %04x:%04x at address %d.\n",
- id1, id2, i);
+ pr_info("Found PHY %04x:%04x at address %d\n",
+ id1, id2, i);
}
- lp->a.write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
- if (lp->phycount > 1) {
+ lp->a->write_bcr(ioaddr, 33, (lp->mii_if.phy_id) << 5);
+ if (lp->phycount > 1)
lp->options |= PCNET32_PORT_MII;
- }
}
init_timer(&lp->watchdog_timer);
@@ -1936,20 +1899,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
lp->watchdog_timer.function = (void *)&pcnet32_watchdog;
/* The PCNET32-specific entries in the device structure. */
- dev->open = &pcnet32_open;
- dev->hard_start_xmit = &pcnet32_start_xmit;
- dev->stop = &pcnet32_close;
- dev->get_stats = &pcnet32_get_stats;
- dev->set_multicast_list = &pcnet32_set_multicast_list;
- dev->do_ioctl = &pcnet32_ioctl;
+ dev->netdev_ops = &pcnet32_netdev_ops;
dev->ethtool_ops = &pcnet32_ethtool_ops;
- dev->tx_timeout = pcnet32_tx_timeout;
dev->watchdog_timeo = (5 * HZ);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = pcnet32_poll_controller;
-#endif
-
/* Fill in the generic fields of the device structure. */
if (register_netdev(dev))
goto err_free_ring;
@@ -1962,7 +1915,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
}
if (pcnet32_debug & NETIF_MSG_PROBE)
- printk(KERN_INFO "%s: registered as %s\n", dev->name, lp->name);
+ pr_info("%s: registered as %s\n", dev->name, lp->name);
cards_found++;
/* enable LED writes */
@@ -1970,14 +1923,13 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
return 0;
- err_free_ring:
+err_free_ring:
pcnet32_free_ring(dev);
- err_free_consistent:
pci_free_consistent(lp->pci_dev, sizeof(*lp->init_block),
lp->init_block, lp->init_dma_addr);
- err_free_netdev:
+err_free_netdev:
free_netdev(dev);
- err_release_region:
+err_release_region:
release_region(ioaddr, PCNET32_TOTAL_SIZE);
return ret;
}
@@ -1992,10 +1944,7 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name)
lp->tx_ring_size,
&lp->tx_ring_dma_addr);
if (lp->tx_ring == NULL) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
- "%s: Consistent memory allocation failed.\n",
- name);
+ netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
return -ENOMEM;
}
@@ -2004,48 +1953,29 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name)
lp->rx_ring_size,
&lp->rx_ring_dma_addr);
if (lp->rx_ring == NULL) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
- "%s: Consistent memory allocation failed.\n",
- name);
+ netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
return -ENOMEM;
}
lp->tx_dma_addr = kcalloc(lp->tx_ring_size, sizeof(dma_addr_t),
GFP_ATOMIC);
- if (!lp->tx_dma_addr) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
- "%s: Memory allocation failed.\n", name);
+ if (!lp->tx_dma_addr)
return -ENOMEM;
- }
lp->rx_dma_addr = kcalloc(lp->rx_ring_size, sizeof(dma_addr_t),
GFP_ATOMIC);
- if (!lp->rx_dma_addr) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
- "%s: Memory allocation failed.\n", name);
+ if (!lp->rx_dma_addr)
return -ENOMEM;
- }
lp->tx_skbuff = kcalloc(lp->tx_ring_size, sizeof(struct sk_buff *),
GFP_ATOMIC);
- if (!lp->tx_skbuff) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
- "%s: Memory allocation failed.\n", name);
+ if (!lp->tx_skbuff)
return -ENOMEM;
- }
lp->rx_skbuff = kcalloc(lp->rx_ring_size, sizeof(struct sk_buff *),
GFP_ATOMIC);
- if (!lp->rx_skbuff) {
- if (netif_msg_drv(lp))
- printk("\n" KERN_ERR PFX
- "%s: Memory allocation failed.\n", name);
+ if (!lp->rx_skbuff)
return -ENOMEM;
- }
return 0;
}
@@ -2086,13 +2016,14 @@ static void pcnet32_free_ring(struct net_device *dev)
static int pcnet32_open(struct net_device *dev)
{
struct pcnet32_private *lp = netdev_priv(dev);
+ struct pci_dev *pdev = lp->pci_dev;
unsigned long ioaddr = dev->base_addr;
u16 val;
int i;
int rc;
unsigned long flags;
- if (request_irq(dev->irq, &pcnet32_interrupt,
+ if (request_irq(dev->irq, pcnet32_interrupt,
lp->shared_irq ? IRQF_SHARED : 0, dev->name,
(void *)dev)) {
return -EAGAIN;
@@ -2106,27 +2037,26 @@ static int pcnet32_open(struct net_device *dev)
}
/* Reset the PCNET32 */
- lp->a.reset(ioaddr);
+ lp->a->reset(ioaddr);
/* switch pcnet32 to 32bit mode */
- lp->a.write_bcr(ioaddr, 20, 2);
+ lp->a->write_bcr(ioaddr, 20, 2);
- if (netif_msg_ifup(lp))
- printk(KERN_DEBUG
- "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
- dev->name, dev->irq, (u32) (lp->tx_ring_dma_addr),
- (u32) (lp->rx_ring_dma_addr),
- (u32) (lp->init_dma_addr));
+ netif_printk(lp, ifup, KERN_DEBUG, dev,
+ "%s() irq %d tx/rx rings %#x/%#x init %#x\n",
+ __func__, dev->irq, (u32) (lp->tx_ring_dma_addr),
+ (u32) (lp->rx_ring_dma_addr),
+ (u32) (lp->init_dma_addr));
/* set/reset autoselect bit */
- val = lp->a.read_bcr(ioaddr, 2) & ~2;
+ val = lp->a->read_bcr(ioaddr, 2) & ~2;
if (lp->options & PCNET32_PORT_ASEL)
val |= 2;
- lp->a.write_bcr(ioaddr, 2, val);
+ lp->a->write_bcr(ioaddr, 2, val);
/* handle full duplex setting */
if (lp->mii_if.full_duplex) {
- val = lp->a.read_bcr(ioaddr, 9) & ~3;
+ val = lp->a->read_bcr(ioaddr, 9) & ~3;
if (lp->options & PCNET32_PORT_FD) {
val |= 1;
if (lp->options == (PCNET32_PORT_FD | PCNET32_PORT_AUI))
@@ -2136,25 +2066,23 @@ static int pcnet32_open(struct net_device *dev)
if (lp->chip_version == 0x2627)
val |= 3;
}
- lp->a.write_bcr(ioaddr, 9, val);
+ lp->a->write_bcr(ioaddr, 9, val);
}
/* set/reset GPSI bit in test register */
- val = lp->a.read_csr(ioaddr, 124) & ~0x10;
+ val = lp->a->read_csr(ioaddr, 124) & ~0x10;
if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI)
val |= 0x10;
- lp->a.write_csr(ioaddr, 124, val);
+ lp->a->write_csr(ioaddr, 124, val);
/* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */
- if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
- (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
- lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
+ if (pdev && pdev->subsystem_vendor == PCI_VENDOR_ID_AT &&
+ (pdev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
+ pdev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
if (lp->options & PCNET32_PORT_ASEL) {
lp->options = PCNET32_PORT_FD | PCNET32_PORT_100;
- if (netif_msg_link(lp))
- printk(KERN_DEBUG
- "%s: Setting 100Mb-Full Duplex.\n",
- dev->name);
+ netif_printk(lp, link, KERN_DEBUG, dev,
+ "Setting 100Mb-Full Duplex\n");
}
}
if (lp->phycount < 2) {
@@ -2164,50 +2092,50 @@ static int pcnet32_open(struct net_device *dev)
* duplex, and/or enable auto negotiation, and clear DANAS
*/
if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
- lp->a.write_bcr(ioaddr, 32,
- lp->a.read_bcr(ioaddr, 32) | 0x0080);
+ lp->a->write_bcr(ioaddr, 32,
+ lp->a->read_bcr(ioaddr, 32) | 0x0080);
/* disable Auto Negotiation, set 10Mpbs, HD */
- val = lp->a.read_bcr(ioaddr, 32) & ~0xb8;
+ val = lp->a->read_bcr(ioaddr, 32) & ~0xb8;
if (lp->options & PCNET32_PORT_FD)
val |= 0x10;
if (lp->options & PCNET32_PORT_100)
val |= 0x08;
- lp->a.write_bcr(ioaddr, 32, val);
+ lp->a->write_bcr(ioaddr, 32, val);
} else {
if (lp->options & PCNET32_PORT_ASEL) {
- lp->a.write_bcr(ioaddr, 32,
- lp->a.read_bcr(ioaddr,
+ lp->a->write_bcr(ioaddr, 32,
+ lp->a->read_bcr(ioaddr,
32) | 0x0080);
/* enable auto negotiate, setup, disable fd */
- val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
+ val = lp->a->read_bcr(ioaddr, 32) & ~0x98;
val |= 0x20;
- lp->a.write_bcr(ioaddr, 32, val);
+ lp->a->write_bcr(ioaddr, 32, val);
}
}
} else {
int first_phy = -1;
u16 bmcr;
u32 bcr9;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
/*
* There is really no good other way to handle multiple PHYs
* other than turning off all automatics
*/
- val = lp->a.read_bcr(ioaddr, 2);
- lp->a.write_bcr(ioaddr, 2, val & ~2);
- val = lp->a.read_bcr(ioaddr, 32);
- lp->a.write_bcr(ioaddr, 32, val & ~(1 << 7)); /* stop MII manager */
+ val = lp->a->read_bcr(ioaddr, 2);
+ lp->a->write_bcr(ioaddr, 2, val & ~2);
+ val = lp->a->read_bcr(ioaddr, 32);
+ lp->a->write_bcr(ioaddr, 32, val & ~(1 << 7)); /* stop MII manager */
if (!(lp->options & PCNET32_PORT_ASEL)) {
/* setup ecmd */
ecmd.port = PORT_MII;
ecmd.transceiver = XCVR_INTERNAL;
ecmd.autoneg = AUTONEG_DISABLE;
- ecmd.speed =
- lp->
- options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
- bcr9 = lp->a.read_bcr(ioaddr, 9);
+ ethtool_cmd_speed_set(&ecmd,
+ (lp->options & PCNET32_PORT_100) ?
+ SPEED_100 : SPEED_10);
+ bcr9 = lp->a->read_bcr(ioaddr, 9);
if (lp->options & PCNET32_PORT_FD) {
ecmd.duplex = DUPLEX_FULL;
@@ -2216,7 +2144,7 @@ static int pcnet32_open(struct net_device *dev)
ecmd.duplex = DUPLEX_HALF;
bcr9 |= ~(1 << 0);
}
- lp->a.write_bcr(ioaddr, 9, bcr9);
+ lp->a->write_bcr(ioaddr, 9, bcr9);
}
for (i = 0; i < PCNET32_MAX_PHYS; i++) {
@@ -2242,16 +2170,14 @@ static int pcnet32_open(struct net_device *dev)
}
}
lp->mii_if.phy_id = first_phy;
- if (netif_msg_link(lp))
- printk(KERN_INFO "%s: Using PHY number %d.\n",
- dev->name, first_phy);
+ netif_info(lp, link, dev, "Using PHY number %d\n", first_phy);
}
#ifdef DO_DXSUFLO
if (lp->dxsuflo) { /* Disable transmit stop on underflow */
- val = lp->a.read_csr(ioaddr, CSR3);
+ val = lp->a->read_csr(ioaddr, CSR3);
val |= 0x40;
- lp->a.write_csr(ioaddr, CSR3, val);
+ lp->a->write_csr(ioaddr, CSR3, val);
}
#endif
@@ -2267,42 +2193,41 @@ static int pcnet32_open(struct net_device *dev)
napi_enable(&lp->napi);
/* Re-initialize the PCNET32, and start it when done. */
- lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
- lp->a.write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
+ lp->a->write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
+ lp->a->write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
- lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
- lp->a.write_csr(ioaddr, CSR0, CSR0_INIT);
+ lp->a->write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
+ lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
netif_start_queue(dev);
if (lp->chip_version >= PCNET32_79C970A) {
/* Print the link status and start the watchdog */
pcnet32_check_media(dev, 1);
- mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT);
+ mod_timer(&lp->watchdog_timer, PCNET32_WATCHDOG_TIMEOUT);
}
i = 0;
while (i++ < 100)
- if (lp->a.read_csr(ioaddr, CSR0) & CSR0_IDON)
+ if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
break;
/*
* We used to clear the InitDone bit, 0x0100, here but Mark Stockton
* reports that doing so triggers a bug in the '974.
*/
- lp->a.write_csr(ioaddr, CSR0, CSR0_NORMAL);
+ lp->a->write_csr(ioaddr, CSR0, CSR0_NORMAL);
- if (netif_msg_ifup(lp))
- printk(KERN_DEBUG
- "%s: pcnet32 open after %d ticks, init block %#x csr0 %4.4x.\n",
- dev->name, i,
- (u32) (lp->init_dma_addr),
- lp->a.read_csr(ioaddr, CSR0));
+ netif_printk(lp, ifup, KERN_DEBUG, dev,
+ "pcnet32 open after %d ticks, init block %#x csr0 %4.4x\n",
+ i,
+ (u32) (lp->init_dma_addr),
+ lp->a->read_csr(ioaddr, CSR0));
spin_unlock_irqrestore(&lp->lock, flags);
return 0; /* Always succeed */
- err_free_ring:
+err_free_ring:
/* free any allocated skbuffs */
pcnet32_purge_rx_ring(dev);
@@ -2310,9 +2235,9 @@ static int pcnet32_open(struct net_device *dev)
* Switch back to 16bit mode to avoid problems with dumb
* DOS packet driver after a warm reboot
*/
- lp->a.write_bcr(ioaddr, 20, 4);
+ lp->a->write_bcr(ioaddr, 20, 4);
- err_free_irq:
+err_free_irq:
spin_unlock_irqrestore(&lp->lock, flags);
free_irq(dev->irq, dev);
return rc;
@@ -2340,9 +2265,12 @@ static void pcnet32_purge_tx_ring(struct net_device *dev)
lp->tx_ring[i].status = 0; /* CPU owns buffer */
wmb(); /* Make sure adapter sees owner change */
if (lp->tx_skbuff[i]) {
- pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i],
- lp->tx_skbuff[i]->len,
- PCI_DMA_TODEVICE);
+ if (!pci_dma_mapping_error(lp->pci_dev,
+ lp->tx_dma_addr[i]))
+ pci_unmap_single(lp->pci_dev,
+ lp->tx_dma_addr[i],
+ lp->tx_skbuff[i]->len,
+ PCI_DMA_TODEVICE);
dev_kfree_skb_any(lp->tx_skbuff[i]);
}
lp->tx_skbuff[i] = NULL;
@@ -2363,24 +2291,31 @@ static int pcnet32_init_ring(struct net_device *dev)
for (i = 0; i < lp->rx_ring_size; i++) {
struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
if (rx_skbuff == NULL) {
- if (!
- (rx_skbuff = lp->rx_skbuff[i] =
- dev_alloc_skb(PKT_BUF_SKB))) {
- /* there is not much, we can do at this point */
- if (netif_msg_drv(lp))
- printk(KERN_ERR
- "%s: pcnet32_init_ring dev_alloc_skb failed.\n",
- dev->name);
+ lp->rx_skbuff[i] = netdev_alloc_skb(dev, PKT_BUF_SKB);
+ rx_skbuff = lp->rx_skbuff[i];
+ if (!rx_skbuff) {
+ /* there is not much we can do at this point */
+ netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n",
+ __func__);
return -1;
}
skb_reserve(rx_skbuff, NET_IP_ALIGN);
}
rmb();
- if (lp->rx_dma_addr[i] == 0)
+ if (lp->rx_dma_addr[i] == 0) {
lp->rx_dma_addr[i] =
pci_map_single(lp->pci_dev, rx_skbuff->data,
PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(lp->pci_dev,
+ lp->rx_dma_addr[i])) {
+ /* there is not much we can do at this point */
+ netif_err(lp, drv, dev,
+ "%s pci dma mapping error\n",
+ __func__);
+ return -1;
+ }
+ }
lp->rx_ring[i].base = cpu_to_le32(lp->rx_dma_addr[i]);
lp->rx_ring[i].buf_length = cpu_to_le16(NEG_BUF_SIZE);
wmb(); /* Make sure owner changes after all others are visible */
@@ -2417,26 +2352,25 @@ static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
/* wait for stop */
for (i = 0; i < 100; i++)
- if (lp->a.read_csr(ioaddr, CSR0) & CSR0_STOP)
+ if (lp->a->read_csr(ioaddr, CSR0) & CSR0_STOP)
break;
- if (i >= 100 && netif_msg_drv(lp))
- printk(KERN_ERR
- "%s: pcnet32_restart timed out waiting for stop.\n",
- dev->name);
+ if (i >= 100)
+ netif_err(lp, drv, dev, "%s timed out waiting for stop\n",
+ __func__);
pcnet32_purge_tx_ring(dev);
if (pcnet32_init_ring(dev))
return;
/* ReInit Ring */
- lp->a.write_csr(ioaddr, CSR0, CSR0_INIT);
+ lp->a->write_csr(ioaddr, CSR0, CSR0_INIT);
i = 0;
while (i++ < 1000)
- if (lp->a.read_csr(ioaddr, CSR0) & CSR0_IDON)
+ if (lp->a->read_csr(ioaddr, CSR0) & CSR0_IDON)
break;
- lp->a.write_csr(ioaddr, CSR0, csr0_bits);
+ lp->a->write_csr(ioaddr, CSR0, csr0_bits);
}
static void pcnet32_tx_timeout(struct net_device *dev)
@@ -2447,10 +2381,9 @@ static void pcnet32_tx_timeout(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
/* Transmitter timeout, serious problems. */
if (pcnet32_debug & NETIF_MSG_DRV)
- printk(KERN_ERR
- "%s: transmit timed out, status %4.4x, resetting.\n",
- dev->name, lp->a.read_csr(ioaddr, CSR0));
- lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
+ pr_err("%s: transmit timed out, status %4.4x, resetting\n",
+ dev->name, lp->a->read_csr(ioaddr, CSR0));
+ lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
dev->stats.tx_errors++;
if (netif_msg_tx_err(lp)) {
int i;
@@ -2474,13 +2407,14 @@ static void pcnet32_tx_timeout(struct net_device *dev)
}
pcnet32_restart(dev, CSR0_NORMAL);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_wake_queue(dev);
spin_unlock_irqrestore(&lp->lock, flags);
}
-static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
struct pcnet32_private *lp = netdev_priv(dev);
unsigned long ioaddr = dev->base_addr;
@@ -2490,11 +2424,9 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- if (netif_msg_tx_queued(lp)) {
- printk(KERN_DEBUG
- "%s: pcnet32_start_xmit() called, csr0 %4.4x.\n",
- dev->name, lp->a.read_csr(ioaddr, CSR0));
- }
+ netif_printk(lp, tx_queued, KERN_DEBUG, dev,
+ "%s() called, csr0 %4.4x\n",
+ __func__, lp->a->read_csr(ioaddr, CSR0));
/* Default status -- will not enable Successful-TxDone
* interrupt when that option is available to us.
@@ -2513,9 +2445,14 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->tx_ring[entry].misc = 0x00000000;
- lp->tx_skbuff[entry] = skb;
lp->tx_dma_addr[entry] =
pci_map_single(lp->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(lp->pci_dev, lp->tx_dma_addr[entry])) {
+ dev_kfree_skb_any(skb);
+ dev->stats.tx_dropped++;
+ goto drop_packet;
+ }
+ lp->tx_skbuff[entry] = skb;
lp->tx_ring[entry].base = cpu_to_le32(lp->tx_dma_addr[entry]);
wmb(); /* Make sure owner changes after all others are visible */
lp->tx_ring[entry].status = cpu_to_le16(status);
@@ -2524,16 +2461,15 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->stats.tx_bytes += skb->len;
/* Trigger an immediate send poll. */
- lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
-
- dev->trans_start = jiffies;
+ lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL);
if (lp->tx_ring[(entry + 1) & lp->tx_mod_mask].base != 0) {
lp->tx_full = 1;
netif_stop_queue(dev);
}
+drop_packet:
spin_unlock_irqrestore(&lp->lock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/* The PCNET32 interrupt handler. */
@@ -2551,18 +2487,16 @@ pcnet32_interrupt(int irq, void *dev_id)
spin_lock(&lp->lock);
- csr0 = lp->a.read_csr(ioaddr, CSR0);
+ csr0 = lp->a->read_csr(ioaddr, CSR0);
while ((csr0 & 0x8f00) && --boguscnt >= 0) {
- if (csr0 == 0xffff) {
+ if (csr0 == 0xffff)
break; /* PCMCIA remove happened */
- }
/* Acknowledge all of the current interrupt sources ASAP. */
- lp->a.write_csr(ioaddr, CSR0, csr0 & ~0x004f);
+ lp->a->write_csr(ioaddr, CSR0, csr0 & ~0x004f);
- if (netif_msg_intr(lp))
- printk(KERN_DEBUG
- "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n",
- dev->name, csr0, lp->a.read_csr(ioaddr, CSR0));
+ netif_printk(lp, intr, KERN_DEBUG, dev,
+ "interrupt csr0=%#2.2x new csr=%#2.2x\n",
+ csr0, lp->a->read_csr(ioaddr, CSR0));
/* Log misc errors. */
if (csr0 & 0x4000)
@@ -2582,28 +2516,26 @@ pcnet32_interrupt(int irq, void *dev_id)
dev->stats.rx_errors++; /* Missed a Rx frame. */
}
if (csr0 & 0x0800) {
- if (netif_msg_drv(lp))
- printk(KERN_ERR
- "%s: Bus master arbitration failure, status %4.4x.\n",
- dev->name, csr0);
+ netif_err(lp, drv, dev, "Bus master arbitration failure, status %4.4x\n",
+ csr0);
/* unlike for the lance, there is no restart needed */
}
- if (netif_rx_schedule_prep(dev, &lp->napi)) {
+ if (napi_schedule_prep(&lp->napi)) {
u16 val;
/* set interrupt masks */
- val = lp->a.read_csr(ioaddr, CSR3);
+ val = lp->a->read_csr(ioaddr, CSR3);
val |= 0x5f00;
- lp->a.write_csr(ioaddr, CSR3, val);
- mmiowb();
- __netif_rx_schedule(dev, &lp->napi);
+ lp->a->write_csr(ioaddr, CSR3, val);
+
+ __napi_schedule(&lp->napi);
break;
}
- csr0 = lp->a.read_csr(ioaddr, CSR0);
+ csr0 = lp->a->read_csr(ioaddr, CSR0);
}
- if (netif_msg_intr(lp))
- printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
- dev->name, lp->a.read_csr(ioaddr, CSR0));
+ netif_printk(lp, intr, KERN_DEBUG, dev,
+ "exiting interrupt, csr0=%#4.4x\n",
+ lp->a->read_csr(ioaddr, CSR0));
spin_unlock(&lp->lock);
@@ -2623,21 +2555,20 @@ static int pcnet32_close(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+ dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
- if (netif_msg_ifdown(lp))
- printk(KERN_DEBUG
- "%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, lp->a.read_csr(ioaddr, CSR0));
+ netif_printk(lp, ifdown, KERN_DEBUG, dev,
+ "Shutting down ethercard, status was %2.2x\n",
+ lp->a->read_csr(ioaddr, CSR0));
/* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
- lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
+ lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
/*
* Switch back to 16bit mode to avoid problems with dumb
* DOS packet driver after a warm reboot
*/
- lp->a.write_bcr(ioaddr, 20, 4);
+ lp->a->write_bcr(ioaddr, 20, 4);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -2660,7 +2591,7 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev)
unsigned long flags;
spin_lock_irqsave(&lp->lock, flags);
- dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
+ dev->stats.rx_missed_errors = lp->a->read_csr(ioaddr, 112);
spin_unlock_irqrestore(&lp->lock, flags);
return &dev->stats;
@@ -2672,9 +2603,8 @@ static void pcnet32_load_multicast(struct net_device *dev)
struct pcnet32_private *lp = netdev_priv(dev);
volatile struct pcnet32_init_block *ib = lp->init_block;
volatile __le16 *mcast_table = (__le16 *)ib->filter;
- struct dev_mc_list *dmi = dev->mc_list;
+ struct netdev_hw_addr *ha;
unsigned long ioaddr = dev->base_addr;
- char *addrs;
int i;
u32 crc;
@@ -2682,10 +2612,10 @@ static void pcnet32_load_multicast(struct net_device *dev)
if (dev->flags & IFF_ALLMULTI) {
ib->filter[0] = cpu_to_le32(~0U);
ib->filter[1] = cpu_to_le32(~0U);
- lp->a.write_csr(ioaddr, PCNET32_MC_FILTER, 0xffff);
- lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+1, 0xffff);
- lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+2, 0xffff);
- lp->a.write_csr(ioaddr, PCNET32_MC_FILTER+3, 0xffff);
+ lp->a->write_csr(ioaddr, PCNET32_MC_FILTER, 0xffff);
+ lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+1, 0xffff);
+ lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+2, 0xffff);
+ lp->a->write_csr(ioaddr, PCNET32_MC_FILTER+3, 0xffff);
return;
}
/* clear the multicast filter */
@@ -2693,22 +2623,14 @@ static void pcnet32_load_multicast(struct net_device *dev)
ib->filter[1] = 0;
/* Add addresses */
- for (i = 0; i < dev->mc_count; i++) {
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
-
- /* multicast address? */
- if (!(*addrs & 1))
- continue;
-
- crc = ether_crc_le(6, addrs);
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(6, ha->addr);
crc = crc >> 26;
mcast_table[crc >> 4] |= cpu_to_le16(1 << (crc & 0xf));
}
for (i = 0; i < 4; i++)
- lp->a.write_csr(ioaddr, PCNET32_MC_FILTER + i,
+ lp->a->write_csr(ioaddr, PCNET32_MC_FILTER + i,
le16_to_cpu(mcast_table[i]));
- return;
}
/*
@@ -2722,30 +2644,28 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
suspended = pcnet32_suspend(dev, &flags, 0);
- csr15 = lp->a.read_csr(ioaddr, CSR15);
+ csr15 = lp->a->read_csr(ioaddr, CSR15);
if (dev->flags & IFF_PROMISC) {
/* Log any net taps. */
- if (netif_msg_hw(lp))
- printk(KERN_INFO "%s: Promiscuous mode enabled.\n",
- dev->name);
+ netif_info(lp, hw, dev, "Promiscuous mode enabled\n");
lp->init_block->mode =
cpu_to_le16(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) <<
7);
- lp->a.write_csr(ioaddr, CSR15, csr15 | 0x8000);
+ lp->a->write_csr(ioaddr, CSR15, csr15 | 0x8000);
} else {
lp->init_block->mode =
cpu_to_le16((lp->options & PCNET32_PORT_PORTSEL) << 7);
- lp->a.write_csr(ioaddr, CSR15, csr15 & 0x7fff);
+ lp->a->write_csr(ioaddr, CSR15, csr15 & 0x7fff);
pcnet32_load_multicast(dev);
}
if (suspended) {
int csr5;
/* clear SUSPEND (SPND) - CSR5 bit 0 */
- csr5 = lp->a.read_csr(ioaddr, CSR5);
- lp->a.write_csr(ioaddr, CSR5, csr5 & (~CSR5_SUSPEND));
+ csr5 = lp->a->read_csr(ioaddr, CSR5);
+ lp->a->write_csr(ioaddr, CSR5, csr5 & (~CSR5_SUSPEND));
} else {
- lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);
+ lp->a->write_csr(ioaddr, CSR0, CSR0_STOP);
pcnet32_restart(dev, CSR0_NORMAL);
netif_wake_queue(dev);
}
@@ -2763,8 +2683,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
if (!lp->mii)
return 0;
- lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
- val_out = lp->a.read_bcr(ioaddr, 34);
+ lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
+ val_out = lp->a->read_bcr(ioaddr, 34);
return val_out;
}
@@ -2778,8 +2698,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
if (!lp->mii)
return;
- lp->a.write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
- lp->a.write_bcr(ioaddr, 34, val);
+ lp->a->write_bcr(ioaddr, 33, ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
+ lp->a->write_bcr(ioaddr, 34, val);
}
static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -2814,10 +2734,8 @@ static int pcnet32_check_otherphy(struct net_device *dev)
mii.phy_id = i;
if (mii_link_ok(&mii)) {
/* found PHY with active link */
- if (netif_msg_link(lp))
- printk(KERN_INFO
- "%s: Using PHY number %d.\n",
- dev->name, i);
+ netif_info(lp, link, dev, "Using PHY number %d\n",
+ i);
/* isolate inactive phy */
bmcr =
@@ -2858,13 +2776,12 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
curr_link = mii_link_ok(&lp->mii_if);
} else {
ulong ioaddr = dev->base_addr; /* card base I/O address */
- curr_link = (lp->a.read_bcr(ioaddr, 4) != 0xc0);
+ curr_link = (lp->a->read_bcr(ioaddr, 4) != 0xc0);
}
if (!curr_link) {
if (prev_link || verbose) {
netif_carrier_off(dev);
- if (netif_msg_link(lp))
- printk(KERN_INFO "%s: link down\n", dev->name);
+ netif_info(lp, link, dev, "link down\n");
}
if (lp->phycount > 1) {
curr_link = pcnet32_check_otherphy(dev);
@@ -2874,26 +2791,24 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
netif_carrier_on(dev);
if (lp->mii) {
if (netif_msg_link(lp)) {
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = {
+ .cmd = ETHTOOL_GSET };
mii_ethtool_gset(&lp->mii_if, &ecmd);
- printk(KERN_INFO
- "%s: link up, %sMbps, %s-duplex\n",
- dev->name,
- (ecmd.speed == SPEED_100) ? "100" : "10",
- (ecmd.duplex ==
- DUPLEX_FULL) ? "full" : "half");
+ netdev_info(dev, "link up, %uMbps, %s-duplex\n",
+ ethtool_cmd_speed(&ecmd),
+ (ecmd.duplex == DUPLEX_FULL)
+ ? "full" : "half");
}
- bcr9 = lp->a.read_bcr(dev->base_addr, 9);
+ bcr9 = lp->a->read_bcr(dev->base_addr, 9);
if ((bcr9 & (1 << 0)) != lp->mii_if.full_duplex) {
if (lp->mii_if.full_duplex)
bcr9 |= (1 << 0);
else
bcr9 &= ~(1 << 0);
- lp->a.write_bcr(dev->base_addr, 9, bcr9);
+ lp->a->write_bcr(dev->base_addr, 9, bcr9);
}
} else {
- if (netif_msg_link(lp))
- printk(KERN_INFO "%s: link up\n", dev->name);
+ netif_info(lp, link, dev, "link up\n");
}
}
}
@@ -2913,7 +2828,7 @@ static void pcnet32_watchdog(struct net_device *dev)
pcnet32_check_media(dev, 0);
spin_unlock_irqrestore(&lp->lock, flags);
- mod_timer(&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT);
+ mod_timer(&lp->watchdog_timer, round_jiffies(PCNET32_WATCHDOG_TIMEOUT));
}
static int pcnet32_pm_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -2943,7 +2858,7 @@ static int pcnet32_pm_resume(struct pci_dev *pdev)
return 0;
}
-static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
+static void pcnet32_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
@@ -2957,14 +2872,13 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
lp->init_block, lp->init_dma_addr);
free_netdev(dev);
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
}
}
static struct pci_driver pcnet32_driver = {
.name = DRV_NAME,
.probe = pcnet32_probe_pci,
- .remove = __devexit_p(pcnet32_remove_one),
+ .remove = pcnet32_remove_one,
.id_table = pcnet32_pci_tbl,
.suspend = pcnet32_pm_suspend,
.resume = pcnet32_pm_resume,
@@ -3005,7 +2919,7 @@ MODULE_LICENSE("GPL");
static int __init pcnet32_init_module(void)
{
- printk(KERN_INFO "%s", version);
+ pr_info("%s", version);
pcnet32_debug = netif_msg_init(debug, PCNET32_MSG_DEFAULT);
@@ -3021,7 +2935,7 @@ static int __init pcnet32_init_module(void)
pcnet32_probe_vlbus(pcnet32_portlist);
if (cards_found && (pcnet32_debug & NETIF_MSG_PROBE))
- printk(KERN_INFO PFX "%d cards_found.\n", cards_found);
+ pr_info("%d cards_found\n", cards_found);
return (pcnet32_have_pci + cards_found) ? 0 : -ENODEV;
}
diff --git a/drivers/net/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c
index 359452a06c6..3d8c6b2cdea 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/ethernet/amd/sun3lance.c
@@ -28,7 +28,6 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/ioport.h>
@@ -294,6 +293,16 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_set_mac_address = NULL,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init lance_probe( struct net_device *dev)
{
unsigned long ioaddr;
@@ -303,7 +312,6 @@ static int __init lance_probe( struct net_device *dev)
static int did_version;
volatile unsigned short *ioaddr_probe;
unsigned short tmp1, tmp2;
- DECLARE_MAC_BUF(mac);
#ifdef CONFIG_SUN3
ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
@@ -350,7 +358,7 @@ static int __init lance_probe( struct net_device *dev)
REGA(CSR0) = CSR0_STOP;
- if (request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev) < 0) {
+ if (request_irq(LANCE_IRQ, lance_interrupt, 0, "SUN3 Lance", dev) < 0) {
#ifdef CONFIG_SUN3
iounmap((void __iomem *)ioaddr);
#endif
@@ -379,7 +387,7 @@ static int __init lance_probe( struct net_device *dev)
MEM->init.hwaddr[4] = dev->dev_addr[5];
MEM->init.hwaddr[5] = dev->dev_addr[4];
- printk("%s\n", print_mac(mac, dev->dev_addr));
+ printk("%pM\n", dev->dev_addr);
MEM->init.mode = 0x0000;
MEM->init.filter[0] = 0x00000000;
@@ -398,12 +406,7 @@ static int __init lance_probe( struct net_device *dev)
if (did_version++ == 0)
printk( version );
- /* The LANCE-specific entries in the device structure. */
- dev->open = &lance_open;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->stop = &lance_close;
- dev->set_multicast_list = &set_multicast_list;
- dev->set_mac_address = NULL;
+ dev->netdev_ops = &lance_netdev_ops;
// KLUDGE -- REMOVE ME
set_bit(__LINK_STATE_PRESENT, &dev->state);
@@ -429,11 +432,11 @@ static int lance_open( struct net_device *dev )
while (--i > 0)
if (DREG & CSR0_IDON)
break;
- if (i < 0 || (DREG & CSR0_ERR)) {
+ if (i <= 0 || (DREG & CSR0_ERR)) {
DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
dev->name, i, DREG ));
DREG = CSR0_STOP;
- return( -EIO );
+ return -EIO;
}
DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA;
@@ -442,7 +445,7 @@ static int lance_open( struct net_device *dev )
DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
- return( 0 );
+ return 0;
}
@@ -520,9 +523,9 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
/* Transmitter timeout, serious problems. */
if (netif_queue_stopped(dev)) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 20)
- return( 1 );
+ int tickssofar = jiffies - dev_trans_start(dev);
+ if (tickssofar < HZ/5)
+ return NETDEV_TX_BUSY;
DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
dev->name, DREG ));
@@ -556,9 +559,8 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
netif_start_queue(dev);
- dev->trans_start = jiffies;
- return 0;
+ return NETDEV_TX_OK;
}
@@ -573,7 +575,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
printk( "%s: tx queue lock!.\n", dev->name);
/* don't clear dev->tbusy flag. */
- return 1;
+ return NETDEV_TX_BUSY;
}
AREG = CSR0;
@@ -634,8 +636,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
AREG = CSR0;
DPRINTK( 2, ( "%s: lance_start_xmit() exiting, csr0 %4.4x.\n",
dev->name, DREG ));
- dev->trans_start = jiffies;
- dev_kfree_skb( skb );
+ dev_kfree_skb(skb);
lp->lock = 0;
if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
@@ -644,7 +645,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
local_irq_restore(flags);
- return 0;
+ return NETDEV_TX_OK;
}
/* The LANCE interrupt handler. */
@@ -809,11 +810,8 @@ static int lance_rx( struct net_device *dev )
dev->stats.rx_errors++;
}
else {
- skb = dev_alloc_skb( pkt_len+2 );
+ skb = netdev_alloc_skb(dev, pkt_len + 2);
if (skb == NULL) {
- DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
- dev->name ));
-
dev->stats.rx_dropped++;
head->msg_length = 0;
head->flag |= RMD1_OWN_CHIP;
@@ -824,12 +822,10 @@ static int lance_rx( struct net_device *dev )
#if 0
if (lance_debug >= 3) {
u_char *data = PKTBUF_ADDR(head);
- DECLARE_MAC_BUF(mac);
- DECLARE_MAC_BUF(mac2)
printk("%s: RX pkt %d type 0x%04x"
- " from %s to %s",
+ " from %pM to %pM",
dev->name, lp->new_tx, ((u_short *)data)[6],
- print_mac(mac, &data[6]), print_mac(mac2, data));
+ &data[6], data);
printk(" data %02x %02x %02x %02x %02x %02x %02x %02x "
"len %d at %08x\n",
@@ -852,7 +848,6 @@ static int lance_rx( struct net_device *dev )
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
}
@@ -916,7 +911,7 @@ static void set_multicast_list( struct net_device *dev )
REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
} else {
short multicast_table[4];
- int num_addrs = dev->mc_count;
+ int num_addrs = netdev_mc_count(dev);
int i;
/* We don't use the multicast table, but rely on upper-layer
* filtering. */
@@ -945,9 +940,7 @@ static struct net_device *sun3lance_dev;
int __init init_module(void)
{
sun3lance_dev = sun3lance_probe(-1);
- if (IS_ERR(sun3lance_dev))
- return PTR_ERR(sun3lance_dev);
- return 0;
+ return PTR_ERR_OR_ZERO(sun3lance_dev);
}
void __exit cleanup_module(void)
diff --git a/drivers/net/sunlance.c b/drivers/net/ethernet/amd/sunlance.c
index 4e994f87469..5e4273b7aa2 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/ethernet/amd/sunlance.c
@@ -78,10 +78,8 @@ static char lancestr[] = "LANCE";
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
-#include <linux/init.h>
#include <linux/crc32.h>
#include <linux/errno.h>
#include <linux/socket.h> /* Used for the temporal inet entries and routing */
@@ -91,14 +89,16 @@ static char lancestr[] = "LANCE";
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/gfp.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
#include <asm/byteorder.h> /* Used by the checksum routines */
#include <asm/idprom.h>
-#include <asm/sbus.h>
#include <asm/prom.h>
#include <asm/auxio.h> /* For tpe-link-test? setting */
#include <asm/irq.h>
@@ -248,7 +248,7 @@ struct lance_private {
int rx_new, tx_new;
int rx_old, tx_old;
- struct sbus_dma *ledma; /* If set this points to ledma */
+ struct platform_device *ledma; /* If set this points to ledma */
char tpe; /* cable-selection is TPE */
char auto_select; /* cable-selection by carrier */
char burst_sizes; /* ledma SBus burst sizes */
@@ -263,7 +263,8 @@ struct lance_private {
char *name;
dma_addr_t init_block_dvma;
struct net_device *dev; /* Backpointer */
- struct sbus_dev *sdev;
+ struct platform_device *op;
+ struct platform_device *lebuffer;
struct timer_list multicast_timer;
};
@@ -340,7 +341,7 @@ static void lance_init_ring_dvma(struct net_device *dev)
ib->phys_addr [5] = dev->dev_addr [4];
/* Setup the Tx ring entries */
- for (i = 0; i <= TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i));
ib->btx_ring [i].tmd0 = leptr;
ib->btx_ring [i].tmd1_hadr = leptr >> 16;
@@ -396,7 +397,7 @@ static void lance_init_ring_pio(struct net_device *dev)
sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]);
/* Setup the Tx ring entries */
- for (i = 0; i <= TX_RING_SIZE; i++) {
+ for (i = 0; i < TX_RING_SIZE; i++) {
leptr = libbuff_offset(tx_buf, i);
sbus_writew(leptr, &ib->btx_ring [i].tmd0);
sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr);
@@ -531,11 +532,9 @@ static void lance_rx_dvma(struct net_device *dev)
if (bits & LE_R1_EOP) dev->stats.rx_errors++;
} else {
len = (rd->mblength & 0xfff) - 4;
- skb = dev_alloc_skb(len + 2);
+ skb = netdev_alloc_skb(dev, len + 2);
if (skb == NULL) {
- printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
rd->mblength = 0;
rd->rmd1_bits = LE_R1_OWN;
@@ -552,7 +551,6 @@ static void lance_rx_dvma(struct net_device *dev)
len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
}
@@ -704,11 +702,9 @@ static void lance_rx_pio(struct net_device *dev)
if (bits & LE_R1_EOP) dev->stats.rx_errors++;
} else {
len = (sbus_readw(&rd->mblength) & 0xfff) - 4;
- skb = dev_alloc_skb(len + 2);
+ skb = netdev_alloc_skb(dev, len + 2);
if (skb == NULL) {
- printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
- dev->name);
dev->stats.rx_dropped++;
sbus_writew(0, &rd->mblength);
sbus_writeb(LE_R1_OWN, &rd->rmd1_bits);
@@ -723,7 +719,6 @@ static void lance_rx_pio(struct net_device *dev)
lance_piocopy_to_skb(skb, &(ib->rx_buf[entry][0]), len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
}
@@ -922,7 +917,7 @@ static int lance_open(struct net_device *dev)
STOP_LANCE(lp);
- if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED,
+ if (request_irq(dev->irq, lance_interrupt, IRQF_SHARED,
lancestr, (void *) dev)) {
printk(KERN_ERR "Lance: Can't get irq %d\n", dev->irq);
return -EAGAIN;
@@ -1002,7 +997,7 @@ static int lance_reset(struct net_device *dev)
}
lp->init_ring(dev);
load_csrs(lp);
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
status = init_restart_lance(lp);
return status;
}
@@ -1053,7 +1048,7 @@ static void lance_piocopy_from_skb(void __iomem *dest, unsigned char *src, int l
}
src = (char *) p16;
break;
- };
+ }
if (len >= 2) {
u16 val = src[0] << 8 | src[1];
sbus_writew(val, piobuf);
@@ -1159,19 +1154,16 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irq(&lp->lock);
- dev->trans_start = jiffies;
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
/* taken from the depca driver */
static void lance_load_multicast(struct net_device *dev)
{
struct lance_private *lp = netdev_priv(dev);
- struct dev_mc_list *dmi = dev->mc_list;
- char *addrs;
- int i;
+ struct netdev_hw_addr *ha;
u32 crc;
u32 val;
@@ -1195,14 +1187,8 @@ static void lance_load_multicast(struct net_device *dev)
return;
/* Add addresses */
- for (i = 0; i < dev->mc_count; i++) {
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
-
- /* multicast address? */
- if (!(*addrs & 1))
- continue;
- crc = ether_crc_le(6, addrs);
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(6, ha->addr);
crc = crc >> 26;
if (lp->pio_buffer) {
struct lance_init_block __iomem *ib = lp->init_block_iomem;
@@ -1272,52 +1258,56 @@ static void lance_set_multicast_retry(unsigned long _opaque)
static void lance_free_hwresources(struct lance_private *lp)
{
if (lp->lregs)
- sbus_iounmap(lp->lregs, LANCE_REG_SIZE);
+ of_iounmap(&lp->op->resource[0], lp->lregs, LANCE_REG_SIZE);
+ if (lp->dregs) {
+ struct platform_device *ledma = lp->ledma;
+
+ of_iounmap(&ledma->resource[0], lp->dregs,
+ resource_size(&ledma->resource[0]));
+ }
if (lp->init_block_iomem) {
- sbus_iounmap(lp->init_block_iomem,
- sizeof(struct lance_init_block));
+ of_iounmap(&lp->lebuffer->resource[0], lp->init_block_iomem,
+ sizeof(struct lance_init_block));
} else if (lp->init_block_mem) {
- sbus_free_consistent(lp->sdev,
- sizeof(struct lance_init_block),
- lp->init_block_mem,
- lp->init_block_dvma);
+ dma_free_coherent(&lp->op->dev,
+ sizeof(struct lance_init_block),
+ lp->init_block_mem,
+ lp->init_block_dvma);
}
}
/* Ethtool support... */
static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct lance_private *lp = netdev_priv(dev);
-
- strcpy(info->driver, "sunlance");
- strcpy(info->version, "2.02");
- sprintf(info->bus_info, "SBUS:%d",
- lp->sdev->slot);
-}
-
-static u32 sparc_lance_get_link(struct net_device *dev)
-{
- /* We really do not keep track of this, but this
- * is better than not reporting anything at all.
- */
- return 1;
+ strlcpy(info->driver, "sunlance", sizeof(info->driver));
+ strlcpy(info->version, "2.02", sizeof(info->version));
}
static const struct ethtool_ops sparc_lance_ethtool_ops = {
.get_drvinfo = sparc_lance_get_drvinfo,
- .get_link = sparc_lance_get_link,
+ .get_link = ethtool_op_get_link,
};
-static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
- struct sbus_dma *ledma,
- struct sbus_dev *lebuffer)
+static const struct net_device_ops sparc_lance_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_rx_mode = lance_set_multicast,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static int sparc_lance_probe_one(struct platform_device *op,
+ struct platform_device *ledma,
+ struct platform_device *lebuffer)
{
+ struct device_node *dp = op->dev.of_node;
static unsigned version_printed;
- struct device_node *dp = sdev->ofdev.node;
- struct net_device *dev;
struct lance_private *lp;
+ struct net_device *dev;
int i;
- DECLARE_MAC_BUF(mac);
dev = alloc_etherdev(sizeof(struct lance_private) + 8);
if (!dev)
@@ -1338,14 +1328,27 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
dev->dev_addr[i] = idprom->id_ethaddr[i];
/* Get the IO region */
- lp->lregs = sbus_ioremap(&sdev->resource[0], 0,
- LANCE_REG_SIZE, lancestr);
+ lp->lregs = of_ioremap(&op->resource[0], 0,
+ LANCE_REG_SIZE, lancestr);
if (!lp->lregs) {
printk(KERN_ERR "SunLance: Cannot map registers.\n");
goto fail;
}
- lp->sdev = sdev;
+ lp->ledma = ledma;
+ if (lp->ledma) {
+ lp->dregs = of_ioremap(&ledma->resource[0], 0,
+ resource_size(&ledma->resource[0]),
+ "ledma");
+ if (!lp->dregs) {
+ printk(KERN_ERR "SunLance: Cannot map "
+ "ledma registers.\n");
+ goto fail;
+ }
+ }
+
+ lp->op = op;
+ lp->lebuffer = lebuffer;
if (lebuffer) {
/* sanity check */
if (lebuffer->resource[0].start & 7) {
@@ -1353,8 +1356,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
goto fail;
}
lp->init_block_iomem =
- sbus_ioremap(&lebuffer->resource[0], 0,
- sizeof(struct lance_init_block), "lebuffer");
+ of_ioremap(&lebuffer->resource[0], 0,
+ sizeof(struct lance_init_block), "lebuffer");
if (!lp->init_block_iomem) {
printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n");
goto fail;
@@ -1366,12 +1369,12 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
lp->tx = lance_tx_pio;
} else {
lp->init_block_mem =
- sbus_alloc_consistent(sdev, sizeof(struct lance_init_block),
- &lp->init_block_dvma);
- if (!lp->init_block_mem || lp->init_block_dvma == 0) {
- printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n");
+ dma_alloc_coherent(&op->dev,
+ sizeof(struct lance_init_block),
+ &lp->init_block_dvma, GFP_ATOMIC);
+ if (!lp->init_block_mem)
goto fail;
- }
+
lp->pio_buffer = 0;
lp->init_ring = lance_init_ring_dvma;
lp->rx = lance_rx_dvma;
@@ -1383,13 +1386,13 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
LE_C3_BCON));
lp->name = lancestr;
- lp->ledma = ledma;
lp->burst_sizes = 0;
if (lp->ledma) {
- struct device_node *ledma_dp = ledma->sdev->ofdev.node;
- const char *prop;
+ struct device_node *ledma_dp = ledma->dev.of_node;
+ struct device_node *sbus_dp;
unsigned int sbmask;
+ const char *prop;
u32 csr;
/* Find burst-size property for ledma */
@@ -1397,7 +1400,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
"burst-sizes", 0);
/* ledma may be capable of fast bursts, but sbus may not. */
- sbmask = of_getintprop_default(ledma_dp, "burst-sizes",
+ sbus_dp = ledma_dp->parent;
+ sbmask = of_getintprop_default(sbus_dp, "burst-sizes",
DMA_BURSTBITS);
lp->burst_sizes &= sbmask;
@@ -1435,8 +1439,6 @@ no_link_test:
lp->tpe = 1;
}
- lp->dregs = ledma->regs;
-
/* Reset ledma */
csr = sbus_readl(lp->dregs + DMA_CSR);
sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR);
@@ -1446,18 +1448,12 @@ no_link_test:
lp->dregs = NULL;
lp->dev = dev;
- SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
- dev->open = &lance_open;
- dev->stop = &lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->tx_timeout = &lance_tx_timeout;
+ SET_NETDEV_DEV(dev, &op->dev);
dev->watchdog_timeo = 5*HZ;
- dev->set_multicast_list = &lance_set_multicast;
dev->ethtool_ops = &sparc_lance_ethtool_ops;
+ dev->netdev_ops = &sparc_lance_ops;
- dev->irq = sdev->irqs[0];
-
- dev->dma = 0;
+ dev->irq = op->archdata.irqs[0];
/* We cannot sleep if the chip is busy during a
* multicast list update event, because such events
@@ -1466,17 +1462,17 @@ no_link_test:
*/
init_timer(&lp->multicast_timer);
lp->multicast_timer.data = (unsigned long) dev;
- lp->multicast_timer.function = &lance_set_multicast_retry;
+ lp->multicast_timer.function = lance_set_multicast_retry;
if (register_netdev(dev)) {
printk(KERN_ERR "SunLance: Cannot register device.\n");
goto fail;
}
- dev_set_drvdata(&sdev->ofdev.dev, lp);
+ platform_set_drvdata(op, lp);
- printk(KERN_INFO "%s: LANCE %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
+ printk(KERN_INFO "%s: LANCE %pM\n",
+ dev->name, dev->dev_addr);
return 0;
@@ -1486,80 +1482,25 @@ fail:
return -ENODEV;
}
-/* On 4m, find the associated dma for the lance chip */
-static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev)
+static int sunlance_sbus_probe(struct platform_device *op)
{
- struct sbus_dma *p;
-
- for_each_dvma(p) {
- if (p->sdev == sdev)
- return p;
- }
- return NULL;
-}
-
-#ifdef CONFIG_SUN4
-
-#include <asm/sun4paddr.h>
-#include <asm/machines.h>
-
-/* Find all the lance cards on the system and initialize them */
-static struct sbus_dev sun4_sdev;
-static int __devinit sparc_lance_init(void)
-{
- if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
- (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
- memset(&sun4_sdev, 0, sizeof(struct sbus_dev));
- sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
- sun4_sdev.irqs[0] = 6;
- return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
- }
- return -ENODEV;
-}
-
-static int __exit sunlance_sun4_remove(void)
-{
- struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev);
- struct net_device *net_dev = lp->dev;
-
- unregister_netdev(net_dev);
-
- lance_free_hwresources(lp);
-
- free_netdev(net_dev);
-
- dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL);
-
- return 0;
-}
-
-#else /* !CONFIG_SUN4 */
-
-static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
-{
- struct sbus_dev *sdev = to_sbus_device(&dev->dev);
+ struct platform_device *parent = to_platform_device(op->dev.parent);
+ struct device_node *parent_dp = parent->dev.of_node;
int err;
- if (sdev->parent) {
- struct of_device *parent = &sdev->parent->ofdev;
-
- if (!strcmp(parent->node->name, "ledma")) {
- struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev));
-
- err = sparc_lance_probe_one(sdev, ledma, NULL);
- } else if (!strcmp(parent->node->name, "lebuffer")) {
- err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev));
- } else
- err = sparc_lance_probe_one(sdev, NULL, NULL);
+ if (!strcmp(parent_dp->name, "ledma")) {
+ err = sparc_lance_probe_one(op, parent, NULL);
+ } else if (!strcmp(parent_dp->name, "lebuffer")) {
+ err = sparc_lance_probe_one(op, NULL, parent);
} else
- err = sparc_lance_probe_one(sdev, NULL, NULL);
+ err = sparc_lance_probe_one(op, NULL, NULL);
return err;
}
-static int __devexit sunlance_sbus_remove(struct of_device *dev)
+static int sunlance_sbus_remove(struct platform_device *op)
{
- struct lance_private *lp = dev_get_drvdata(&dev->dev);
+ struct lance_private *lp = platform_get_drvdata(op);
struct net_device *net_dev = lp->dev;
unregister_netdev(net_dev);
@@ -1568,12 +1509,10 @@ static int __devexit sunlance_sbus_remove(struct of_device *dev)
free_netdev(net_dev);
- dev_set_drvdata(&dev->dev, NULL);
-
return 0;
}
-static struct of_device_id sunlance_sbus_match[] = {
+static const struct of_device_id sunlance_sbus_match[] = {
{
.name = "le",
},
@@ -1582,29 +1521,14 @@ static struct of_device_id sunlance_sbus_match[] = {
MODULE_DEVICE_TABLE(of, sunlance_sbus_match);
-static struct of_platform_driver sunlance_sbus_driver = {
- .name = "sunlance",
- .match_table = sunlance_sbus_match,
+static struct platform_driver sunlance_sbus_driver = {
+ .driver = {
+ .name = "sunlance",
+ .owner = THIS_MODULE,
+ .of_match_table = sunlance_sbus_match,
+ },
.probe = sunlance_sbus_probe,
- .remove = __devexit_p(sunlance_sbus_remove),
+ .remove = sunlance_sbus_remove,
};
-
-/* Find all the lance cards on the system and initialize them */
-static int __init sparc_lance_init(void)
-{
- return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type);
-}
-#endif /* !CONFIG_SUN4 */
-
-static void __exit sparc_lance_exit(void)
-{
-#ifdef CONFIG_SUN4
- sunlance_sun4_remove();
-#else
- of_unregister_driver(&sunlance_sbus_driver);
-#endif
-}
-
-module_init(sparc_lance_init);
-module_exit(sparc_lance_exit);
+module_platform_driver(sunlance_sbus_driver);
diff --git a/drivers/net/ethernet/amd/xgbe/Makefile b/drivers/net/ethernet/amd/xgbe/Makefile
new file mode 100644
index 00000000000..26cf9af1642
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_AMD_XGBE) += amd-xgbe.o
+
+amd-xgbe-objs := xgbe-main.o xgbe-drv.o xgbe-dev.o \
+ xgbe-desc.o xgbe-ethtool.o xgbe-mdio.o
+
+amd-xgbe-$(CONFIG_DEBUG_FS) += xgbe-debugfs.o
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
new file mode 100644
index 00000000000..bf462ee86f5
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -0,0 +1,1007 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __XGBE_COMMON_H__
+#define __XGBE_COMMON_H__
+
+/* DMA register offsets */
+#define DMA_MR 0x3000
+#define DMA_SBMR 0x3004
+#define DMA_ISR 0x3008
+#define DMA_AXIARCR 0x3010
+#define DMA_AXIAWCR 0x3018
+#define DMA_DSR0 0x3020
+#define DMA_DSR1 0x3024
+#define DMA_DSR2 0x3028
+#define DMA_DSR3 0x302c
+#define DMA_DSR4 0x3030
+
+/* DMA register entry bit positions and sizes */
+#define DMA_AXIARCR_DRC_INDEX 0
+#define DMA_AXIARCR_DRC_WIDTH 4
+#define DMA_AXIARCR_DRD_INDEX 4
+#define DMA_AXIARCR_DRD_WIDTH 2
+#define DMA_AXIARCR_TEC_INDEX 8
+#define DMA_AXIARCR_TEC_WIDTH 4
+#define DMA_AXIARCR_TED_INDEX 12
+#define DMA_AXIARCR_TED_WIDTH 2
+#define DMA_AXIARCR_THC_INDEX 16
+#define DMA_AXIARCR_THC_WIDTH 4
+#define DMA_AXIARCR_THD_INDEX 20
+#define DMA_AXIARCR_THD_WIDTH 2
+#define DMA_AXIAWCR_DWC_INDEX 0
+#define DMA_AXIAWCR_DWC_WIDTH 4
+#define DMA_AXIAWCR_DWD_INDEX 4
+#define DMA_AXIAWCR_DWD_WIDTH 2
+#define DMA_AXIAWCR_RPC_INDEX 8
+#define DMA_AXIAWCR_RPC_WIDTH 4
+#define DMA_AXIAWCR_RPD_INDEX 12
+#define DMA_AXIAWCR_RPD_WIDTH 2
+#define DMA_AXIAWCR_RHC_INDEX 16
+#define DMA_AXIAWCR_RHC_WIDTH 4
+#define DMA_AXIAWCR_RHD_INDEX 20
+#define DMA_AXIAWCR_RHD_WIDTH 2
+#define DMA_AXIAWCR_TDC_INDEX 24
+#define DMA_AXIAWCR_TDC_WIDTH 4
+#define DMA_AXIAWCR_TDD_INDEX 28
+#define DMA_AXIAWCR_TDD_WIDTH 2
+#define DMA_DSR0_RPS_INDEX 8
+#define DMA_DSR0_RPS_WIDTH 4
+#define DMA_DSR0_TPS_INDEX 12
+#define DMA_DSR0_TPS_WIDTH 4
+#define DMA_ISR_MACIS_INDEX 17
+#define DMA_ISR_MACIS_WIDTH 1
+#define DMA_ISR_MTLIS_INDEX 16
+#define DMA_ISR_MTLIS_WIDTH 1
+#define DMA_MR_SWR_INDEX 0
+#define DMA_MR_SWR_WIDTH 1
+#define DMA_SBMR_EAME_INDEX 11
+#define DMA_SBMR_EAME_WIDTH 1
+#define DMA_SBMR_UNDEF_INDEX 0
+#define DMA_SBMR_UNDEF_WIDTH 1
+
+/* DMA channel register offsets
+ * Multiple channels can be active. The first channel has registers
+ * that begin at 0x3100. Each subsequent channel has registers that
+ * are accessed using an offset of 0x80 from the previous channel.
+ */
+#define DMA_CH_BASE 0x3100
+#define DMA_CH_INC 0x80
+
+#define DMA_CH_CR 0x00
+#define DMA_CH_TCR 0x04
+#define DMA_CH_RCR 0x08
+#define DMA_CH_TDLR_HI 0x10
+#define DMA_CH_TDLR_LO 0x14
+#define DMA_CH_RDLR_HI 0x18
+#define DMA_CH_RDLR_LO 0x1c
+#define DMA_CH_TDTR_LO 0x24
+#define DMA_CH_RDTR_LO 0x2c
+#define DMA_CH_TDRLR 0x30
+#define DMA_CH_RDRLR 0x34
+#define DMA_CH_IER 0x38
+#define DMA_CH_RIWT 0x3c
+#define DMA_CH_CATDR_LO 0x44
+#define DMA_CH_CARDR_LO 0x4c
+#define DMA_CH_CATBR_HI 0x50
+#define DMA_CH_CATBR_LO 0x54
+#define DMA_CH_CARBR_HI 0x58
+#define DMA_CH_CARBR_LO 0x5c
+#define DMA_CH_SR 0x60
+
+/* DMA channel register entry bit positions and sizes */
+#define DMA_CH_CR_PBLX8_INDEX 16
+#define DMA_CH_CR_PBLX8_WIDTH 1
+#define DMA_CH_IER_AIE_INDEX 15
+#define DMA_CH_IER_AIE_WIDTH 1
+#define DMA_CH_IER_FBEE_INDEX 12
+#define DMA_CH_IER_FBEE_WIDTH 1
+#define DMA_CH_IER_NIE_INDEX 16
+#define DMA_CH_IER_NIE_WIDTH 1
+#define DMA_CH_IER_RBUE_INDEX 7
+#define DMA_CH_IER_RBUE_WIDTH 1
+#define DMA_CH_IER_RIE_INDEX 6
+#define DMA_CH_IER_RIE_WIDTH 1
+#define DMA_CH_IER_RSE_INDEX 8
+#define DMA_CH_IER_RSE_WIDTH 1
+#define DMA_CH_IER_TBUE_INDEX 2
+#define DMA_CH_IER_TBUE_WIDTH 1
+#define DMA_CH_IER_TIE_INDEX 0
+#define DMA_CH_IER_TIE_WIDTH 1
+#define DMA_CH_IER_TXSE_INDEX 1
+#define DMA_CH_IER_TXSE_WIDTH 1
+#define DMA_CH_RCR_PBL_INDEX 16
+#define DMA_CH_RCR_PBL_WIDTH 6
+#define DMA_CH_RCR_RBSZ_INDEX 1
+#define DMA_CH_RCR_RBSZ_WIDTH 14
+#define DMA_CH_RCR_SR_INDEX 0
+#define DMA_CH_RCR_SR_WIDTH 1
+#define DMA_CH_RIWT_RWT_INDEX 0
+#define DMA_CH_RIWT_RWT_WIDTH 8
+#define DMA_CH_SR_FBE_INDEX 12
+#define DMA_CH_SR_FBE_WIDTH 1
+#define DMA_CH_SR_RBU_INDEX 7
+#define DMA_CH_SR_RBU_WIDTH 1
+#define DMA_CH_SR_RI_INDEX 6
+#define DMA_CH_SR_RI_WIDTH 1
+#define DMA_CH_SR_RPS_INDEX 8
+#define DMA_CH_SR_RPS_WIDTH 1
+#define DMA_CH_SR_TBU_INDEX 2
+#define DMA_CH_SR_TBU_WIDTH 1
+#define DMA_CH_SR_TI_INDEX 0
+#define DMA_CH_SR_TI_WIDTH 1
+#define DMA_CH_SR_TPS_INDEX 1
+#define DMA_CH_SR_TPS_WIDTH 1
+#define DMA_CH_TCR_OSP_INDEX 4
+#define DMA_CH_TCR_OSP_WIDTH 1
+#define DMA_CH_TCR_PBL_INDEX 16
+#define DMA_CH_TCR_PBL_WIDTH 6
+#define DMA_CH_TCR_ST_INDEX 0
+#define DMA_CH_TCR_ST_WIDTH 1
+#define DMA_CH_TCR_TSE_INDEX 12
+#define DMA_CH_TCR_TSE_WIDTH 1
+
+/* DMA channel register values */
+#define DMA_OSP_DISABLE 0x00
+#define DMA_OSP_ENABLE 0x01
+#define DMA_PBL_1 1
+#define DMA_PBL_2 2
+#define DMA_PBL_4 4
+#define DMA_PBL_8 8
+#define DMA_PBL_16 16
+#define DMA_PBL_32 32
+#define DMA_PBL_64 64 /* 8 x 8 */
+#define DMA_PBL_128 128 /* 8 x 16 */
+#define DMA_PBL_256 256 /* 8 x 32 */
+#define DMA_PBL_X8_DISABLE 0x00
+#define DMA_PBL_X8_ENABLE 0x01
+
+
+/* MAC register offsets */
+#define MAC_TCR 0x0000
+#define MAC_RCR 0x0004
+#define MAC_PFR 0x0008
+#define MAC_WTR 0x000c
+#define MAC_HTR0 0x0010
+#define MAC_HTR1 0x0014
+#define MAC_HTR2 0x0018
+#define MAC_HTR3 0x001c
+#define MAC_HTR4 0x0020
+#define MAC_HTR5 0x0024
+#define MAC_HTR6 0x0028
+#define MAC_HTR7 0x002c
+#define MAC_VLANTR 0x0050
+#define MAC_VLANHTR 0x0058
+#define MAC_VLANIR 0x0060
+#define MAC_IVLANIR 0x0064
+#define MAC_RETMR 0x006c
+#define MAC_Q0TFCR 0x0070
+#define MAC_RFCR 0x0090
+#define MAC_RQC0R 0x00a0
+#define MAC_RQC1R 0x00a4
+#define MAC_RQC2R 0x00a8
+#define MAC_RQC3R 0x00ac
+#define MAC_ISR 0x00b0
+#define MAC_IER 0x00b4
+#define MAC_RTSR 0x00b8
+#define MAC_PMTCSR 0x00c0
+#define MAC_RWKPFR 0x00c4
+#define MAC_LPICSR 0x00d0
+#define MAC_LPITCR 0x00d4
+#define MAC_VR 0x0110
+#define MAC_DR 0x0114
+#define MAC_HWF0R 0x011c
+#define MAC_HWF1R 0x0120
+#define MAC_HWF2R 0x0124
+#define MAC_GPIOCR 0x0278
+#define MAC_GPIOSR 0x027c
+#define MAC_MACA0HR 0x0300
+#define MAC_MACA0LR 0x0304
+#define MAC_MACA1HR 0x0308
+#define MAC_MACA1LR 0x030c
+
+#define MAC_QTFCR_INC 4
+#define MAC_MACA_INC 4
+
+/* MAC register entry bit positions and sizes */
+#define MAC_HWF0R_ADDMACADRSEL_INDEX 18
+#define MAC_HWF0R_ADDMACADRSEL_WIDTH 5
+#define MAC_HWF0R_ARPOFFSEL_INDEX 9
+#define MAC_HWF0R_ARPOFFSEL_WIDTH 1
+#define MAC_HWF0R_EEESEL_INDEX 13
+#define MAC_HWF0R_EEESEL_WIDTH 1
+#define MAC_HWF0R_GMIISEL_INDEX 1
+#define MAC_HWF0R_GMIISEL_WIDTH 1
+#define MAC_HWF0R_MGKSEL_INDEX 7
+#define MAC_HWF0R_MGKSEL_WIDTH 1
+#define MAC_HWF0R_MMCSEL_INDEX 8
+#define MAC_HWF0R_MMCSEL_WIDTH 1
+#define MAC_HWF0R_RWKSEL_INDEX 6
+#define MAC_HWF0R_RWKSEL_WIDTH 1
+#define MAC_HWF0R_RXCOESEL_INDEX 16
+#define MAC_HWF0R_RXCOESEL_WIDTH 1
+#define MAC_HWF0R_SAVLANINS_INDEX 27
+#define MAC_HWF0R_SAVLANINS_WIDTH 1
+#define MAC_HWF0R_SMASEL_INDEX 5
+#define MAC_HWF0R_SMASEL_WIDTH 1
+#define MAC_HWF0R_TSSEL_INDEX 12
+#define MAC_HWF0R_TSSEL_WIDTH 1
+#define MAC_HWF0R_TSSTSSEL_INDEX 25
+#define MAC_HWF0R_TSSTSSEL_WIDTH 2
+#define MAC_HWF0R_TXCOESEL_INDEX 14
+#define MAC_HWF0R_TXCOESEL_WIDTH 1
+#define MAC_HWF0R_VLHASH_INDEX 4
+#define MAC_HWF0R_VLHASH_WIDTH 1
+#define MAC_HWF1R_ADVTHWORD_INDEX 13
+#define MAC_HWF1R_ADVTHWORD_WIDTH 1
+#define MAC_HWF1R_DBGMEMA_INDEX 19
+#define MAC_HWF1R_DBGMEMA_WIDTH 1
+#define MAC_HWF1R_DCBEN_INDEX 16
+#define MAC_HWF1R_DCBEN_WIDTH 1
+#define MAC_HWF1R_HASHTBLSZ_INDEX 24
+#define MAC_HWF1R_HASHTBLSZ_WIDTH 3
+#define MAC_HWF1R_L3L4FNUM_INDEX 27
+#define MAC_HWF1R_L3L4FNUM_WIDTH 4
+#define MAC_HWF1R_RSSEN_INDEX 20
+#define MAC_HWF1R_RSSEN_WIDTH 1
+#define MAC_HWF1R_RXFIFOSIZE_INDEX 0
+#define MAC_HWF1R_RXFIFOSIZE_WIDTH 5
+#define MAC_HWF1R_SPHEN_INDEX 17
+#define MAC_HWF1R_SPHEN_WIDTH 1
+#define MAC_HWF1R_TSOEN_INDEX 18
+#define MAC_HWF1R_TSOEN_WIDTH 1
+#define MAC_HWF1R_TXFIFOSIZE_INDEX 6
+#define MAC_HWF1R_TXFIFOSIZE_WIDTH 5
+#define MAC_HWF2R_AUXSNAPNUM_INDEX 28
+#define MAC_HWF2R_AUXSNAPNUM_WIDTH 3
+#define MAC_HWF2R_PPSOUTNUM_INDEX 24
+#define MAC_HWF2R_PPSOUTNUM_WIDTH 3
+#define MAC_HWF2R_RXCHCNT_INDEX 12
+#define MAC_HWF2R_RXCHCNT_WIDTH 4
+#define MAC_HWF2R_RXQCNT_INDEX 0
+#define MAC_HWF2R_RXQCNT_WIDTH 4
+#define MAC_HWF2R_TXCHCNT_INDEX 18
+#define MAC_HWF2R_TXCHCNT_WIDTH 4
+#define MAC_HWF2R_TXQCNT_INDEX 6
+#define MAC_HWF2R_TXQCNT_WIDTH 4
+#define MAC_ISR_MMCRXIS_INDEX 9
+#define MAC_ISR_MMCRXIS_WIDTH 1
+#define MAC_ISR_MMCTXIS_INDEX 10
+#define MAC_ISR_MMCTXIS_WIDTH 1
+#define MAC_ISR_PMTIS_INDEX 4
+#define MAC_ISR_PMTIS_WIDTH 1
+#define MAC_MACA1HR_AE_INDEX 31
+#define MAC_MACA1HR_AE_WIDTH 1
+#define MAC_PFR_HMC_INDEX 2
+#define MAC_PFR_HMC_WIDTH 1
+#define MAC_PFR_HUC_INDEX 1
+#define MAC_PFR_HUC_WIDTH 1
+#define MAC_PFR_PM_INDEX 4
+#define MAC_PFR_PM_WIDTH 1
+#define MAC_PFR_PR_INDEX 0
+#define MAC_PFR_PR_WIDTH 1
+#define MAC_PMTCSR_MGKPKTEN_INDEX 1
+#define MAC_PMTCSR_MGKPKTEN_WIDTH 1
+#define MAC_PMTCSR_PWRDWN_INDEX 0
+#define MAC_PMTCSR_PWRDWN_WIDTH 1
+#define MAC_PMTCSR_RWKFILTRST_INDEX 31
+#define MAC_PMTCSR_RWKFILTRST_WIDTH 1
+#define MAC_PMTCSR_RWKPKTEN_INDEX 2
+#define MAC_PMTCSR_RWKPKTEN_WIDTH 1
+#define MAC_Q0TFCR_PT_INDEX 16
+#define MAC_Q0TFCR_PT_WIDTH 16
+#define MAC_Q0TFCR_TFE_INDEX 1
+#define MAC_Q0TFCR_TFE_WIDTH 1
+#define MAC_RCR_ACS_INDEX 1
+#define MAC_RCR_ACS_WIDTH 1
+#define MAC_RCR_CST_INDEX 2
+#define MAC_RCR_CST_WIDTH 1
+#define MAC_RCR_DCRCC_INDEX 3
+#define MAC_RCR_DCRCC_WIDTH 1
+#define MAC_RCR_IPC_INDEX 9
+#define MAC_RCR_IPC_WIDTH 1
+#define MAC_RCR_JE_INDEX 8
+#define MAC_RCR_JE_WIDTH 1
+#define MAC_RCR_LM_INDEX 10
+#define MAC_RCR_LM_WIDTH 1
+#define MAC_RCR_RE_INDEX 0
+#define MAC_RCR_RE_WIDTH 1
+#define MAC_RFCR_RFE_INDEX 0
+#define MAC_RFCR_RFE_WIDTH 1
+#define MAC_RQC0R_RXQ0EN_INDEX 0
+#define MAC_RQC0R_RXQ0EN_WIDTH 2
+#define MAC_TCR_SS_INDEX 29
+#define MAC_TCR_SS_WIDTH 2
+#define MAC_TCR_TE_INDEX 0
+#define MAC_TCR_TE_WIDTH 1
+#define MAC_VLANTR_DOVLTC_INDEX 20
+#define MAC_VLANTR_DOVLTC_WIDTH 1
+#define MAC_VLANTR_ERSVLM_INDEX 19
+#define MAC_VLANTR_ERSVLM_WIDTH 1
+#define MAC_VLANTR_ESVL_INDEX 18
+#define MAC_VLANTR_ESVL_WIDTH 1
+#define MAC_VLANTR_EVLS_INDEX 21
+#define MAC_VLANTR_EVLS_WIDTH 2
+#define MAC_VLANTR_EVLRXS_INDEX 24
+#define MAC_VLANTR_EVLRXS_WIDTH 1
+#define MAC_VR_DEVID_INDEX 8
+#define MAC_VR_DEVID_WIDTH 8
+#define MAC_VR_SNPSVER_INDEX 0
+#define MAC_VR_SNPSVER_WIDTH 8
+#define MAC_VR_USERVER_INDEX 16
+#define MAC_VR_USERVER_WIDTH 8
+
+/* MMC register offsets */
+#define MMC_CR 0x0800
+#define MMC_RISR 0x0804
+#define MMC_TISR 0x0808
+#define MMC_RIER 0x080c
+#define MMC_TIER 0x0810
+#define MMC_TXOCTETCOUNT_GB_LO 0x0814
+#define MMC_TXOCTETCOUNT_GB_HI 0x0818
+#define MMC_TXFRAMECOUNT_GB_LO 0x081c
+#define MMC_TXFRAMECOUNT_GB_HI 0x0820
+#define MMC_TXBROADCASTFRAMES_G_LO 0x0824
+#define MMC_TXBROADCASTFRAMES_G_HI 0x0828
+#define MMC_TXMULTICASTFRAMES_G_LO 0x082c
+#define MMC_TXMULTICASTFRAMES_G_HI 0x0830
+#define MMC_TX64OCTETS_GB_LO 0x0834
+#define MMC_TX64OCTETS_GB_HI 0x0838
+#define MMC_TX65TO127OCTETS_GB_LO 0x083c
+#define MMC_TX65TO127OCTETS_GB_HI 0x0840
+#define MMC_TX128TO255OCTETS_GB_LO 0x0844
+#define MMC_TX128TO255OCTETS_GB_HI 0x0848
+#define MMC_TX256TO511OCTETS_GB_LO 0x084c
+#define MMC_TX256TO511OCTETS_GB_HI 0x0850
+#define MMC_TX512TO1023OCTETS_GB_LO 0x0854
+#define MMC_TX512TO1023OCTETS_GB_HI 0x0858
+#define MMC_TX1024TOMAXOCTETS_GB_LO 0x085c
+#define MMC_TX1024TOMAXOCTETS_GB_HI 0x0860
+#define MMC_TXUNICASTFRAMES_GB_LO 0x0864
+#define MMC_TXUNICASTFRAMES_GB_HI 0x0868
+#define MMC_TXMULTICASTFRAMES_GB_LO 0x086c
+#define MMC_TXMULTICASTFRAMES_GB_HI 0x0870
+#define MMC_TXBROADCASTFRAMES_GB_LO 0x0874
+#define MMC_TXBROADCASTFRAMES_GB_HI 0x0878
+#define MMC_TXUNDERFLOWERROR_LO 0x087c
+#define MMC_TXUNDERFLOWERROR_HI 0x0880
+#define MMC_TXOCTETCOUNT_G_LO 0x0884
+#define MMC_TXOCTETCOUNT_G_HI 0x0888
+#define MMC_TXFRAMECOUNT_G_LO 0x088c
+#define MMC_TXFRAMECOUNT_G_HI 0x0890
+#define MMC_TXPAUSEFRAMES_LO 0x0894
+#define MMC_TXPAUSEFRAMES_HI 0x0898
+#define MMC_TXVLANFRAMES_G_LO 0x089c
+#define MMC_TXVLANFRAMES_G_HI 0x08a0
+#define MMC_RXFRAMECOUNT_GB_LO 0x0900
+#define MMC_RXFRAMECOUNT_GB_HI 0x0904
+#define MMC_RXOCTETCOUNT_GB_LO 0x0908
+#define MMC_RXOCTETCOUNT_GB_HI 0x090c
+#define MMC_RXOCTETCOUNT_G_LO 0x0910
+#define MMC_RXOCTETCOUNT_G_HI 0x0914
+#define MMC_RXBROADCASTFRAMES_G_LO 0x0918
+#define MMC_RXBROADCASTFRAMES_G_HI 0x091c
+#define MMC_RXMULTICASTFRAMES_G_LO 0x0920
+#define MMC_RXMULTICASTFRAMES_G_HI 0x0924
+#define MMC_RXCRCERROR_LO 0x0928
+#define MMC_RXCRCERROR_HI 0x092c
+#define MMC_RXRUNTERROR 0x0930
+#define MMC_RXJABBERERROR 0x0934
+#define MMC_RXUNDERSIZE_G 0x0938
+#define MMC_RXOVERSIZE_G 0x093c
+#define MMC_RX64OCTETS_GB_LO 0x0940
+#define MMC_RX64OCTETS_GB_HI 0x0944
+#define MMC_RX65TO127OCTETS_GB_LO 0x0948
+#define MMC_RX65TO127OCTETS_GB_HI 0x094c
+#define MMC_RX128TO255OCTETS_GB_LO 0x0950
+#define MMC_RX128TO255OCTETS_GB_HI 0x0954
+#define MMC_RX256TO511OCTETS_GB_LO 0x0958
+#define MMC_RX256TO511OCTETS_GB_HI 0x095c
+#define MMC_RX512TO1023OCTETS_GB_LO 0x0960
+#define MMC_RX512TO1023OCTETS_GB_HI 0x0964
+#define MMC_RX1024TOMAXOCTETS_GB_LO 0x0968
+#define MMC_RX1024TOMAXOCTETS_GB_HI 0x096c
+#define MMC_RXUNICASTFRAMES_G_LO 0x0970
+#define MMC_RXUNICASTFRAMES_G_HI 0x0974
+#define MMC_RXLENGTHERROR_LO 0x0978
+#define MMC_RXLENGTHERROR_HI 0x097c
+#define MMC_RXOUTOFRANGETYPE_LO 0x0980
+#define MMC_RXOUTOFRANGETYPE_HI 0x0984
+#define MMC_RXPAUSEFRAMES_LO 0x0988
+#define MMC_RXPAUSEFRAMES_HI 0x098c
+#define MMC_RXFIFOOVERFLOW_LO 0x0990
+#define MMC_RXFIFOOVERFLOW_HI 0x0994
+#define MMC_RXVLANFRAMES_GB_LO 0x0998
+#define MMC_RXVLANFRAMES_GB_HI 0x099c
+#define MMC_RXWATCHDOGERROR 0x09a0
+
+/* MMC register entry bit positions and sizes */
+#define MMC_CR_CR_INDEX 0
+#define MMC_CR_CR_WIDTH 1
+#define MMC_CR_CSR_INDEX 1
+#define MMC_CR_CSR_WIDTH 1
+#define MMC_CR_ROR_INDEX 2
+#define MMC_CR_ROR_WIDTH 1
+#define MMC_CR_MCF_INDEX 3
+#define MMC_CR_MCF_WIDTH 1
+#define MMC_CR_MCT_INDEX 4
+#define MMC_CR_MCT_WIDTH 2
+#define MMC_RIER_ALL_INTERRUPTS_INDEX 0
+#define MMC_RIER_ALL_INTERRUPTS_WIDTH 23
+#define MMC_RISR_RXFRAMECOUNT_GB_INDEX 0
+#define MMC_RISR_RXFRAMECOUNT_GB_WIDTH 1
+#define MMC_RISR_RXOCTETCOUNT_GB_INDEX 1
+#define MMC_RISR_RXOCTETCOUNT_GB_WIDTH 1
+#define MMC_RISR_RXOCTETCOUNT_G_INDEX 2
+#define MMC_RISR_RXOCTETCOUNT_G_WIDTH 1
+#define MMC_RISR_RXBROADCASTFRAMES_G_INDEX 3
+#define MMC_RISR_RXBROADCASTFRAMES_G_WIDTH 1
+#define MMC_RISR_RXMULTICASTFRAMES_G_INDEX 4
+#define MMC_RISR_RXMULTICASTFRAMES_G_WIDTH 1
+#define MMC_RISR_RXCRCERROR_INDEX 5
+#define MMC_RISR_RXCRCERROR_WIDTH 1
+#define MMC_RISR_RXRUNTERROR_INDEX 6
+#define MMC_RISR_RXRUNTERROR_WIDTH 1
+#define MMC_RISR_RXJABBERERROR_INDEX 7
+#define MMC_RISR_RXJABBERERROR_WIDTH 1
+#define MMC_RISR_RXUNDERSIZE_G_INDEX 8
+#define MMC_RISR_RXUNDERSIZE_G_WIDTH 1
+#define MMC_RISR_RXOVERSIZE_G_INDEX 9
+#define MMC_RISR_RXOVERSIZE_G_WIDTH 1
+#define MMC_RISR_RX64OCTETS_GB_INDEX 10
+#define MMC_RISR_RX64OCTETS_GB_WIDTH 1
+#define MMC_RISR_RX65TO127OCTETS_GB_INDEX 11
+#define MMC_RISR_RX65TO127OCTETS_GB_WIDTH 1
+#define MMC_RISR_RX128TO255OCTETS_GB_INDEX 12
+#define MMC_RISR_RX128TO255OCTETS_GB_WIDTH 1
+#define MMC_RISR_RX256TO511OCTETS_GB_INDEX 13
+#define MMC_RISR_RX256TO511OCTETS_GB_WIDTH 1
+#define MMC_RISR_RX512TO1023OCTETS_GB_INDEX 14
+#define MMC_RISR_RX512TO1023OCTETS_GB_WIDTH 1
+#define MMC_RISR_RX1024TOMAXOCTETS_GB_INDEX 15
+#define MMC_RISR_RX1024TOMAXOCTETS_GB_WIDTH 1
+#define MMC_RISR_RXUNICASTFRAMES_G_INDEX 16
+#define MMC_RISR_RXUNICASTFRAMES_G_WIDTH 1
+#define MMC_RISR_RXLENGTHERROR_INDEX 17
+#define MMC_RISR_RXLENGTHERROR_WIDTH 1
+#define MMC_RISR_RXOUTOFRANGETYPE_INDEX 18
+#define MMC_RISR_RXOUTOFRANGETYPE_WIDTH 1
+#define MMC_RISR_RXPAUSEFRAMES_INDEX 19
+#define MMC_RISR_RXPAUSEFRAMES_WIDTH 1
+#define MMC_RISR_RXFIFOOVERFLOW_INDEX 20
+#define MMC_RISR_RXFIFOOVERFLOW_WIDTH 1
+#define MMC_RISR_RXVLANFRAMES_GB_INDEX 21
+#define MMC_RISR_RXVLANFRAMES_GB_WIDTH 1
+#define MMC_RISR_RXWATCHDOGERROR_INDEX 22
+#define MMC_RISR_RXWATCHDOGERROR_WIDTH 1
+#define MMC_TIER_ALL_INTERRUPTS_INDEX 0
+#define MMC_TIER_ALL_INTERRUPTS_WIDTH 18
+#define MMC_TISR_TXOCTETCOUNT_GB_INDEX 0
+#define MMC_TISR_TXOCTETCOUNT_GB_WIDTH 1
+#define MMC_TISR_TXFRAMECOUNT_GB_INDEX 1
+#define MMC_TISR_TXFRAMECOUNT_GB_WIDTH 1
+#define MMC_TISR_TXBROADCASTFRAMES_G_INDEX 2
+#define MMC_TISR_TXBROADCASTFRAMES_G_WIDTH 1
+#define MMC_TISR_TXMULTICASTFRAMES_G_INDEX 3
+#define MMC_TISR_TXMULTICASTFRAMES_G_WIDTH 1
+#define MMC_TISR_TX64OCTETS_GB_INDEX 4
+#define MMC_TISR_TX64OCTETS_GB_WIDTH 1
+#define MMC_TISR_TX65TO127OCTETS_GB_INDEX 5
+#define MMC_TISR_TX65TO127OCTETS_GB_WIDTH 1
+#define MMC_TISR_TX128TO255OCTETS_GB_INDEX 6
+#define MMC_TISR_TX128TO255OCTETS_GB_WIDTH 1
+#define MMC_TISR_TX256TO511OCTETS_GB_INDEX 7
+#define MMC_TISR_TX256TO511OCTETS_GB_WIDTH 1
+#define MMC_TISR_TX512TO1023OCTETS_GB_INDEX 8
+#define MMC_TISR_TX512TO1023OCTETS_GB_WIDTH 1
+#define MMC_TISR_TX1024TOMAXOCTETS_GB_INDEX 9
+#define MMC_TISR_TX1024TOMAXOCTETS_GB_WIDTH 1
+#define MMC_TISR_TXUNICASTFRAMES_GB_INDEX 10
+#define MMC_TISR_TXUNICASTFRAMES_GB_WIDTH 1
+#define MMC_TISR_TXMULTICASTFRAMES_GB_INDEX 11
+#define MMC_TISR_TXMULTICASTFRAMES_GB_WIDTH 1
+#define MMC_TISR_TXBROADCASTFRAMES_GB_INDEX 12
+#define MMC_TISR_TXBROADCASTFRAMES_GB_WIDTH 1
+#define MMC_TISR_TXUNDERFLOWERROR_INDEX 13
+#define MMC_TISR_TXUNDERFLOWERROR_WIDTH 1
+#define MMC_TISR_TXOCTETCOUNT_G_INDEX 14
+#define MMC_TISR_TXOCTETCOUNT_G_WIDTH 1
+#define MMC_TISR_TXFRAMECOUNT_G_INDEX 15
+#define MMC_TISR_TXFRAMECOUNT_G_WIDTH 1
+#define MMC_TISR_TXPAUSEFRAMES_INDEX 16
+#define MMC_TISR_TXPAUSEFRAMES_WIDTH 1
+#define MMC_TISR_TXVLANFRAMES_G_INDEX 17
+#define MMC_TISR_TXVLANFRAMES_G_WIDTH 1
+
+/* MTL register offsets */
+#define MTL_OMR 0x1000
+#define MTL_FDCR 0x1008
+#define MTL_FDSR 0x100c
+#define MTL_FDDR 0x1010
+#define MTL_ISR 0x1020
+#define MTL_RQDCM0R 0x1030
+#define MTL_TCPM0R 0x1040
+#define MTL_TCPM1R 0x1044
+
+#define MTL_RQDCM_INC 4
+#define MTL_RQDCM_Q_PER_REG 4
+
+/* MTL register entry bit positions and sizes */
+#define MTL_OMR_ETSALG_INDEX 5
+#define MTL_OMR_ETSALG_WIDTH 2
+#define MTL_OMR_RAA_INDEX 2
+#define MTL_OMR_RAA_WIDTH 1
+
+/* MTL queue register offsets
+ * Multiple queues can be active. The first queue has registers
+ * that begin at 0x1100. Each subsequent queue has registers that
+ * are accessed using an offset of 0x80 from the previous queue.
+ */
+#define MTL_Q_BASE 0x1100
+#define MTL_Q_INC 0x80
+
+#define MTL_Q_TQOMR 0x00
+#define MTL_Q_TQUR 0x04
+#define MTL_Q_TQDR 0x08
+#define MTL_Q_TCECR 0x10
+#define MTL_Q_TCESR 0x14
+#define MTL_Q_TCQWR 0x18
+#define MTL_Q_RQOMR 0x40
+#define MTL_Q_RQMPOCR 0x44
+#define MTL_Q_RQDR 0x4c
+#define MTL_Q_IER 0x70
+#define MTL_Q_ISR 0x74
+
+/* MTL queue register entry bit positions and sizes */
+#define MTL_Q_TCQWR_QW_INDEX 0
+#define MTL_Q_TCQWR_QW_WIDTH 21
+#define MTL_Q_RQOMR_EHFC_INDEX 7
+#define MTL_Q_RQOMR_EHFC_WIDTH 1
+#define MTL_Q_RQOMR_RFA_INDEX 8
+#define MTL_Q_RQOMR_RFA_WIDTH 3
+#define MTL_Q_RQOMR_RFD_INDEX 13
+#define MTL_Q_RQOMR_RFD_WIDTH 3
+#define MTL_Q_RQOMR_RQS_INDEX 16
+#define MTL_Q_RQOMR_RQS_WIDTH 9
+#define MTL_Q_RQOMR_RSF_INDEX 5
+#define MTL_Q_RQOMR_RSF_WIDTH 1
+#define MTL_Q_RQOMR_RTC_INDEX 0
+#define MTL_Q_RQOMR_RTC_WIDTH 2
+#define MTL_Q_TQOMR_FTQ_INDEX 0
+#define MTL_Q_TQOMR_FTQ_WIDTH 1
+#define MTL_Q_TQOMR_TQS_INDEX 16
+#define MTL_Q_TQOMR_TQS_WIDTH 10
+#define MTL_Q_TQOMR_TSF_INDEX 1
+#define MTL_Q_TQOMR_TSF_WIDTH 1
+#define MTL_Q_TQOMR_TTC_INDEX 4
+#define MTL_Q_TQOMR_TTC_WIDTH 3
+#define MTL_Q_TQOMR_TXQEN_INDEX 2
+#define MTL_Q_TQOMR_TXQEN_WIDTH 2
+
+/* MTL queue register value */
+#define MTL_RSF_DISABLE 0x00
+#define MTL_RSF_ENABLE 0x01
+#define MTL_TSF_DISABLE 0x00
+#define MTL_TSF_ENABLE 0x01
+
+#define MTL_RX_THRESHOLD_64 0x00
+#define MTL_RX_THRESHOLD_96 0x02
+#define MTL_RX_THRESHOLD_128 0x03
+#define MTL_TX_THRESHOLD_32 0x01
+#define MTL_TX_THRESHOLD_64 0x00
+#define MTL_TX_THRESHOLD_96 0x02
+#define MTL_TX_THRESHOLD_128 0x03
+#define MTL_TX_THRESHOLD_192 0x04
+#define MTL_TX_THRESHOLD_256 0x05
+#define MTL_TX_THRESHOLD_384 0x06
+#define MTL_TX_THRESHOLD_512 0x07
+
+#define MTL_ETSALG_WRR 0x00
+#define MTL_ETSALG_WFQ 0x01
+#define MTL_ETSALG_DWRR 0x02
+#define MTL_RAA_SP 0x00
+#define MTL_RAA_WSP 0x01
+
+#define MTL_Q_DISABLED 0x00
+#define MTL_Q_ENABLED 0x02
+
+
+/* MTL traffic class register offsets
+ * Multiple traffic classes can be active. The first class has registers
+ * that begin at 0x1100. Each subsequent queue has registers that
+ * are accessed using an offset of 0x80 from the previous queue.
+ */
+#define MTL_TC_BASE MTL_Q_BASE
+#define MTL_TC_INC MTL_Q_INC
+
+#define MTL_TC_ETSCR 0x10
+
+/* MTL traffic class register entry bit positions and sizes */
+#define MTL_TC_ETSCR_TSA_INDEX 0
+#define MTL_TC_ETSCR_TSA_WIDTH 2
+
+/* MTL traffic class register value */
+#define MTL_TSA_SP 0x00
+#define MTL_TSA_ETS 0x02
+
+
+/* PCS MMD select register offset
+ * The MMD select register is used for accessing PCS registers
+ * when the underlying APB3 interface is using indirect addressing.
+ * Indirect addressing requires accessing registers in two phases,
+ * an address phase and a data phase. The address phases requires
+ * writing an address selection value to the MMD select regiesters.
+ */
+#define PCS_MMD_SELECT 0xff
+
+
+/* Descriptor/Packet entry bit positions and sizes */
+#define RX_PACKET_ERRORS_CRC_INDEX 2
+#define RX_PACKET_ERRORS_CRC_WIDTH 1
+#define RX_PACKET_ERRORS_FRAME_INDEX 3
+#define RX_PACKET_ERRORS_FRAME_WIDTH 1
+#define RX_PACKET_ERRORS_LENGTH_INDEX 0
+#define RX_PACKET_ERRORS_LENGTH_WIDTH 1
+#define RX_PACKET_ERRORS_OVERRUN_INDEX 1
+#define RX_PACKET_ERRORS_OVERRUN_WIDTH 1
+
+#define RX_PACKET_ATTRIBUTES_CSUM_DONE_INDEX 0
+#define RX_PACKET_ATTRIBUTES_CSUM_DONE_WIDTH 1
+#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 1
+#define RX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1
+#define RX_PACKET_ATTRIBUTES_INCOMPLETE_INDEX 2
+#define RX_PACKET_ATTRIBUTES_INCOMPLETE_WIDTH 1
+
+#define RX_NORMAL_DESC0_OVT_INDEX 0
+#define RX_NORMAL_DESC0_OVT_WIDTH 16
+#define RX_NORMAL_DESC3_ES_INDEX 15
+#define RX_NORMAL_DESC3_ES_WIDTH 1
+#define RX_NORMAL_DESC3_ETLT_INDEX 16
+#define RX_NORMAL_DESC3_ETLT_WIDTH 4
+#define RX_NORMAL_DESC3_INTE_INDEX 30
+#define RX_NORMAL_DESC3_INTE_WIDTH 1
+#define RX_NORMAL_DESC3_LD_INDEX 28
+#define RX_NORMAL_DESC3_LD_WIDTH 1
+#define RX_NORMAL_DESC3_OWN_INDEX 31
+#define RX_NORMAL_DESC3_OWN_WIDTH 1
+#define RX_NORMAL_DESC3_PL_INDEX 0
+#define RX_NORMAL_DESC3_PL_WIDTH 14
+
+#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_INDEX 0
+#define TX_PACKET_ATTRIBUTES_CSUM_ENABLE_WIDTH 1
+#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_INDEX 1
+#define TX_PACKET_ATTRIBUTES_TSO_ENABLE_WIDTH 1
+#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_INDEX 2
+#define TX_PACKET_ATTRIBUTES_VLAN_CTAG_WIDTH 1
+
+#define TX_CONTEXT_DESC2_MSS_INDEX 0
+#define TX_CONTEXT_DESC2_MSS_WIDTH 15
+#define TX_CONTEXT_DESC3_CTXT_INDEX 30
+#define TX_CONTEXT_DESC3_CTXT_WIDTH 1
+#define TX_CONTEXT_DESC3_TCMSSV_INDEX 26
+#define TX_CONTEXT_DESC3_TCMSSV_WIDTH 1
+#define TX_CONTEXT_DESC3_VLTV_INDEX 16
+#define TX_CONTEXT_DESC3_VLTV_WIDTH 1
+#define TX_CONTEXT_DESC3_VT_INDEX 0
+#define TX_CONTEXT_DESC3_VT_WIDTH 16
+
+#define TX_NORMAL_DESC2_HL_B1L_INDEX 0
+#define TX_NORMAL_DESC2_HL_B1L_WIDTH 14
+#define TX_NORMAL_DESC2_IC_INDEX 31
+#define TX_NORMAL_DESC2_IC_WIDTH 1
+#define TX_NORMAL_DESC2_VTIR_INDEX 14
+#define TX_NORMAL_DESC2_VTIR_WIDTH 2
+#define TX_NORMAL_DESC3_CIC_INDEX 16
+#define TX_NORMAL_DESC3_CIC_WIDTH 2
+#define TX_NORMAL_DESC3_CPC_INDEX 26
+#define TX_NORMAL_DESC3_CPC_WIDTH 2
+#define TX_NORMAL_DESC3_CTXT_INDEX 30
+#define TX_NORMAL_DESC3_CTXT_WIDTH 1
+#define TX_NORMAL_DESC3_FD_INDEX 29
+#define TX_NORMAL_DESC3_FD_WIDTH 1
+#define TX_NORMAL_DESC3_FL_INDEX 0
+#define TX_NORMAL_DESC3_FL_WIDTH 15
+#define TX_NORMAL_DESC3_LD_INDEX 28
+#define TX_NORMAL_DESC3_LD_WIDTH 1
+#define TX_NORMAL_DESC3_OWN_INDEX 31
+#define TX_NORMAL_DESC3_OWN_WIDTH 1
+#define TX_NORMAL_DESC3_TCPHDRLEN_INDEX 19
+#define TX_NORMAL_DESC3_TCPHDRLEN_WIDTH 4
+#define TX_NORMAL_DESC3_TCPPL_INDEX 0
+#define TX_NORMAL_DESC3_TCPPL_WIDTH 18
+#define TX_NORMAL_DESC3_TSE_INDEX 18
+#define TX_NORMAL_DESC3_TSE_WIDTH 1
+
+#define TX_NORMAL_DESC2_VLAN_INSERT 0x2
+
+/* MDIO undefined or vendor specific registers */
+#ifndef MDIO_AN_COMP_STAT
+#define MDIO_AN_COMP_STAT 0x0030
+#endif
+
+
+/* Bit setting and getting macros
+ * The get macro will extract the current bit field value from within
+ * the variable
+ *
+ * The set macro will clear the current bit field value within the
+ * variable and then set the bit field of the variable to the
+ * specified value
+ */
+#define GET_BITS(_var, _index, _width) \
+ (((_var) >> (_index)) & ((0x1 << (_width)) - 1))
+
+#define SET_BITS(_var, _index, _width, _val) \
+do { \
+ (_var) &= ~(((0x1 << (_width)) - 1) << (_index)); \
+ (_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index)); \
+} while (0)
+
+#define GET_BITS_LE(_var, _index, _width) \
+ ((le32_to_cpu((_var)) >> (_index)) & ((0x1 << (_width)) - 1))
+
+#define SET_BITS_LE(_var, _index, _width, _val) \
+do { \
+ (_var) &= cpu_to_le32(~(((0x1 << (_width)) - 1) << (_index))); \
+ (_var) |= cpu_to_le32((((_val) & \
+ ((0x1 << (_width)) - 1)) << (_index))); \
+} while (0)
+
+
+/* Bit setting and getting macros based on register fields
+ * The get macro uses the bit field definitions formed using the input
+ * names to extract the current bit field value from within the
+ * variable
+ *
+ * The set macro uses the bit field definitions formed using the input
+ * names to set the bit field of the variable to the specified value
+ */
+#define XGMAC_GET_BITS(_var, _prefix, _field) \
+ GET_BITS((_var), \
+ _prefix##_##_field##_INDEX, \
+ _prefix##_##_field##_WIDTH)
+
+#define XGMAC_SET_BITS(_var, _prefix, _field, _val) \
+ SET_BITS((_var), \
+ _prefix##_##_field##_INDEX, \
+ _prefix##_##_field##_WIDTH, (_val))
+
+#define XGMAC_GET_BITS_LE(_var, _prefix, _field) \
+ GET_BITS_LE((_var), \
+ _prefix##_##_field##_INDEX, \
+ _prefix##_##_field##_WIDTH)
+
+#define XGMAC_SET_BITS_LE(_var, _prefix, _field, _val) \
+ SET_BITS_LE((_var), \
+ _prefix##_##_field##_INDEX, \
+ _prefix##_##_field##_WIDTH, (_val))
+
+
+/* Macros for reading or writing registers
+ * The ioread macros will get bit fields or full values using the
+ * register definitions formed using the input names
+ *
+ * The iowrite macros will set bit fields or full values using the
+ * register definitions formed using the input names
+ */
+#define XGMAC_IOREAD(_pdata, _reg) \
+ ioread32((_pdata)->xgmac_regs + _reg)
+
+#define XGMAC_IOREAD_BITS(_pdata, _reg, _field) \
+ GET_BITS(XGMAC_IOREAD((_pdata), _reg), \
+ _reg##_##_field##_INDEX, \
+ _reg##_##_field##_WIDTH)
+
+#define XGMAC_IOWRITE(_pdata, _reg, _val) \
+ iowrite32((_val), (_pdata)->xgmac_regs + _reg)
+
+#define XGMAC_IOWRITE_BITS(_pdata, _reg, _field, _val) \
+do { \
+ u32 reg_val = XGMAC_IOREAD((_pdata), _reg); \
+ SET_BITS(reg_val, \
+ _reg##_##_field##_INDEX, \
+ _reg##_##_field##_WIDTH, (_val)); \
+ XGMAC_IOWRITE((_pdata), _reg, reg_val); \
+} while (0)
+
+
+/* Macros for reading or writing MTL queue or traffic class registers
+ * Similar to the standard read and write macros except that the
+ * base register value is calculated by the queue or traffic class number
+ */
+#define XGMAC_MTL_IOREAD(_pdata, _n, _reg) \
+ ioread32((_pdata)->xgmac_regs + \
+ MTL_Q_BASE + ((_n) * MTL_Q_INC) + _reg)
+
+#define XGMAC_MTL_IOREAD_BITS(_pdata, _n, _reg, _field) \
+ GET_BITS(XGMAC_MTL_IOREAD((_pdata), (_n), _reg), \
+ _reg##_##_field##_INDEX, \
+ _reg##_##_field##_WIDTH)
+
+#define XGMAC_MTL_IOWRITE(_pdata, _n, _reg, _val) \
+ iowrite32((_val), (_pdata)->xgmac_regs + \
+ MTL_Q_BASE + ((_n) * MTL_Q_INC) + _reg)
+
+#define XGMAC_MTL_IOWRITE_BITS(_pdata, _n, _reg, _field, _val) \
+do { \
+ u32 reg_val = XGMAC_MTL_IOREAD((_pdata), (_n), _reg); \
+ SET_BITS(reg_val, \
+ _reg##_##_field##_INDEX, \
+ _reg##_##_field##_WIDTH, (_val)); \
+ XGMAC_MTL_IOWRITE((_pdata), (_n), _reg, reg_val); \
+} while (0)
+
+
+/* Macros for reading or writing DMA channel registers
+ * Similar to the standard read and write macros except that the
+ * base register value is obtained from the ring
+ */
+#define XGMAC_DMA_IOREAD(_channel, _reg) \
+ ioread32((_channel)->dma_regs + _reg)
+
+#define XGMAC_DMA_IOREAD_BITS(_channel, _reg, _field) \
+ GET_BITS(XGMAC_DMA_IOREAD((_channel), _reg), \
+ _reg##_##_field##_INDEX, \
+ _reg##_##_field##_WIDTH)
+
+#define XGMAC_DMA_IOWRITE(_channel, _reg, _val) \
+ iowrite32((_val), (_channel)->dma_regs + _reg)
+
+#define XGMAC_DMA_IOWRITE_BITS(_channel, _reg, _field, _val) \
+do { \
+ u32 reg_val = XGMAC_DMA_IOREAD((_channel), _reg); \
+ SET_BITS(reg_val, \
+ _reg##_##_field##_INDEX, \
+ _reg##_##_field##_WIDTH, (_val)); \
+ XGMAC_DMA_IOWRITE((_channel), _reg, reg_val); \
+} while (0)
+
+
+/* Macros for building, reading or writing register values or bits
+ * within the register values of XPCS registers.
+ */
+#define XPCS_IOWRITE(_pdata, _off, _val) \
+ iowrite32(_val, (_pdata)->xpcs_regs + (_off))
+
+#define XPCS_IOREAD(_pdata, _off) \
+ ioread32((_pdata)->xpcs_regs + (_off))
+
+
+/* Macros for building, reading or writing register values or bits
+ * using MDIO. Different from above because of the use of standardized
+ * Linux include values. No shifting is performed with the bit
+ * operations, everything works on mask values.
+ */
+#define XMDIO_READ(_pdata, _mmd, _reg) \
+ ((_pdata)->hw_if.read_mmd_regs((_pdata), 0, \
+ MII_ADDR_C45 | (_mmd << 16) | ((_reg) & 0xffff)))
+
+#define XMDIO_READ_BITS(_pdata, _mmd, _reg, _mask) \
+ (XMDIO_READ((_pdata), _mmd, _reg) & _mask)
+
+#define XMDIO_WRITE(_pdata, _mmd, _reg, _val) \
+ ((_pdata)->hw_if.write_mmd_regs((_pdata), 0, \
+ MII_ADDR_C45 | (_mmd << 16) | ((_reg) & 0xffff), (_val)))
+
+#define XMDIO_WRITE_BITS(_pdata, _mmd, _reg, _mask, _val) \
+do { \
+ u32 mmd_val = XMDIO_READ((_pdata), _mmd, _reg); \
+ mmd_val &= ~_mask; \
+ mmd_val |= (_val); \
+ XMDIO_WRITE((_pdata), _mmd, _reg, mmd_val); \
+} while (0)
+
+#endif
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
new file mode 100644
index 00000000000..6bb76d5c817
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
@@ -0,0 +1,375 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+static ssize_t xgbe_common_read(char __user *buffer, size_t count,
+ loff_t *ppos, unsigned int value)
+{
+ char *buf;
+ ssize_t len;
+
+ if (*ppos != 0)
+ return 0;
+
+ buf = kasprintf(GFP_KERNEL, "0x%08x\n", value);
+ if (!buf)
+ return -ENOMEM;
+
+ if (count < strlen(buf)) {
+ kfree(buf);
+ return -ENOSPC;
+ }
+
+ len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
+ kfree(buf);
+
+ return len;
+}
+
+static ssize_t xgbe_common_write(const char __user *buffer, size_t count,
+ loff_t *ppos, unsigned int *value)
+{
+ char workarea[32];
+ ssize_t len;
+ unsigned int scan_value;
+
+ if (*ppos != 0)
+ return 0;
+
+ if (count >= sizeof(workarea))
+ return -ENOSPC;
+
+ len = simple_write_to_buffer(workarea, sizeof(workarea) - 1, ppos,
+ buffer, count);
+ if (len < 0)
+ return len;
+
+ workarea[len] = '\0';
+ if (sscanf(workarea, "%x", &scan_value) == 1)
+ *value = scan_value;
+ else
+ return -EIO;
+
+ return len;
+}
+
+static ssize_t xgmac_reg_addr_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+
+ return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xgmac_reg);
+}
+
+static ssize_t xgmac_reg_addr_write(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+
+ return xgbe_common_write(buffer, count, ppos,
+ &pdata->debugfs_xgmac_reg);
+}
+
+static ssize_t xgmac_reg_value_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+ unsigned int value;
+
+ value = XGMAC_IOREAD(pdata, pdata->debugfs_xgmac_reg);
+
+ return xgbe_common_read(buffer, count, ppos, value);
+}
+
+static ssize_t xgmac_reg_value_write(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+ unsigned int value;
+ ssize_t len;
+
+ len = xgbe_common_write(buffer, count, ppos, &value);
+ if (len < 0)
+ return len;
+
+ XGMAC_IOWRITE(pdata, pdata->debugfs_xgmac_reg, value);
+
+ return len;
+}
+
+static const struct file_operations xgmac_reg_addr_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = xgmac_reg_addr_read,
+ .write = xgmac_reg_addr_write,
+};
+
+static const struct file_operations xgmac_reg_value_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = xgmac_reg_value_read,
+ .write = xgmac_reg_value_write,
+};
+
+static ssize_t xpcs_mmd_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+
+ return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_mmd);
+}
+
+static ssize_t xpcs_mmd_write(struct file *filp, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+
+ return xgbe_common_write(buffer, count, ppos,
+ &pdata->debugfs_xpcs_mmd);
+}
+
+static ssize_t xpcs_reg_addr_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+
+ return xgbe_common_read(buffer, count, ppos, pdata->debugfs_xpcs_reg);
+}
+
+static ssize_t xpcs_reg_addr_write(struct file *filp, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+
+ return xgbe_common_write(buffer, count, ppos,
+ &pdata->debugfs_xpcs_reg);
+}
+
+static ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+ unsigned int value;
+
+ value = pdata->hw_if.read_mmd_regs(pdata, pdata->debugfs_xpcs_mmd,
+ pdata->debugfs_xpcs_reg);
+
+ return xgbe_common_read(buffer, count, ppos, value);
+}
+
+static ssize_t xpcs_reg_value_write(struct file *filp,
+ const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct xgbe_prv_data *pdata = filp->private_data;
+ unsigned int value;
+ ssize_t len;
+
+ len = xgbe_common_write(buffer, count, ppos, &value);
+ if (len < 0)
+ return len;
+
+ pdata->hw_if.write_mmd_regs(pdata, pdata->debugfs_xpcs_mmd,
+ pdata->debugfs_xpcs_reg, value);
+
+ return len;
+}
+
+static const struct file_operations xpcs_mmd_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = xpcs_mmd_read,
+ .write = xpcs_mmd_write,
+};
+
+static const struct file_operations xpcs_reg_addr_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = xpcs_reg_addr_read,
+ .write = xpcs_reg_addr_write,
+};
+
+static const struct file_operations xpcs_reg_value_fops = {
+ .owner = THIS_MODULE,
+ .open = simple_open,
+ .read = xpcs_reg_value_read,
+ .write = xpcs_reg_value_write,
+};
+
+void xgbe_debugfs_init(struct xgbe_prv_data *pdata)
+{
+ struct dentry *pfile;
+ char *buf;
+
+ /* Set defaults */
+ pdata->debugfs_xgmac_reg = 0;
+ pdata->debugfs_xpcs_mmd = 1;
+ pdata->debugfs_xpcs_reg = 0;
+
+ buf = kasprintf(GFP_KERNEL, "amd-xgbe-%s", pdata->netdev->name);
+ pdata->xgbe_debugfs = debugfs_create_dir(buf, NULL);
+ if (pdata->xgbe_debugfs == NULL) {
+ netdev_err(pdata->netdev, "debugfs_create_dir failed\n");
+ return;
+ }
+
+ pfile = debugfs_create_file("xgmac_register", 0600,
+ pdata->xgbe_debugfs, pdata,
+ &xgmac_reg_addr_fops);
+ if (!pfile)
+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
+
+ pfile = debugfs_create_file("xgmac_register_value", 0600,
+ pdata->xgbe_debugfs, pdata,
+ &xgmac_reg_value_fops);
+ if (!pfile)
+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
+
+ pfile = debugfs_create_file("xpcs_mmd", 0600,
+ pdata->xgbe_debugfs, pdata,
+ &xpcs_mmd_fops);
+ if (!pfile)
+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
+
+ pfile = debugfs_create_file("xpcs_register", 0600,
+ pdata->xgbe_debugfs, pdata,
+ &xpcs_reg_addr_fops);
+ if (!pfile)
+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
+
+ pfile = debugfs_create_file("xpcs_register_value", 0600,
+ pdata->xgbe_debugfs, pdata,
+ &xpcs_reg_value_fops);
+ if (!pfile)
+ netdev_err(pdata->netdev, "debugfs_create_file failed\n");
+
+ kfree(buf);
+}
+
+void xgbe_debugfs_exit(struct xgbe_prv_data *pdata)
+{
+ debugfs_remove_recursive(pdata->xgbe_debugfs);
+ pdata->xgbe_debugfs = NULL;
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-desc.c b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
new file mode 100644
index 00000000000..6f1c85956d5
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-desc.c
@@ -0,0 +1,556 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+static void xgbe_unmap_skb(struct xgbe_prv_data *, struct xgbe_ring_data *);
+
+static void xgbe_free_ring(struct xgbe_prv_data *pdata,
+ struct xgbe_ring *ring)
+{
+ struct xgbe_ring_data *rdata;
+ unsigned int i;
+
+ if (!ring)
+ return;
+
+ if (ring->rdata) {
+ for (i = 0; i < ring->rdesc_count; i++) {
+ rdata = GET_DESC_DATA(ring, i);
+ xgbe_unmap_skb(pdata, rdata);
+ }
+
+ kfree(ring->rdata);
+ ring->rdata = NULL;
+ }
+
+ if (ring->rdesc) {
+ dma_free_coherent(pdata->dev,
+ (sizeof(struct xgbe_ring_desc) *
+ ring->rdesc_count),
+ ring->rdesc, ring->rdesc_dma);
+ ring->rdesc = NULL;
+ }
+}
+
+static void xgbe_free_ring_resources(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ DBGPR("-->xgbe_free_ring_resources\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ xgbe_free_ring(pdata, channel->tx_ring);
+ xgbe_free_ring(pdata, channel->rx_ring);
+ }
+
+ DBGPR("<--xgbe_free_ring_resources\n");
+}
+
+static int xgbe_init_ring(struct xgbe_prv_data *pdata,
+ struct xgbe_ring *ring, unsigned int rdesc_count)
+{
+ DBGPR("-->xgbe_init_ring\n");
+
+ if (!ring)
+ return 0;
+
+ /* Descriptors */
+ ring->rdesc_count = rdesc_count;
+ ring->rdesc = dma_alloc_coherent(pdata->dev,
+ (sizeof(struct xgbe_ring_desc) *
+ rdesc_count), &ring->rdesc_dma,
+ GFP_KERNEL);
+ if (!ring->rdesc)
+ return -ENOMEM;
+
+ /* Descriptor information */
+ ring->rdata = kcalloc(rdesc_count, sizeof(struct xgbe_ring_data),
+ GFP_KERNEL);
+ if (!ring->rdata)
+ return -ENOMEM;
+
+ DBGPR(" rdesc=0x%p, rdesc_dma=0x%llx, rdata=0x%p\n",
+ ring->rdesc, ring->rdesc_dma, ring->rdata);
+
+ DBGPR("<--xgbe_init_ring\n");
+
+ return 0;
+}
+
+static int xgbe_alloc_ring_resources(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+ int ret;
+
+ DBGPR("-->xgbe_alloc_ring_resources\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ DBGPR(" %s - tx_ring:\n", channel->name);
+ ret = xgbe_init_ring(pdata, channel->tx_ring,
+ pdata->tx_desc_count);
+ if (ret) {
+ netdev_alert(pdata->netdev,
+ "error initializing Tx ring\n");
+ goto err_ring;
+ }
+
+ DBGPR(" %s - rx_ring:\n", channel->name);
+ ret = xgbe_init_ring(pdata, channel->rx_ring,
+ pdata->rx_desc_count);
+ if (ret) {
+ netdev_alert(pdata->netdev,
+ "error initializing Tx ring\n");
+ goto err_ring;
+ }
+ }
+
+ DBGPR("<--xgbe_alloc_ring_resources\n");
+
+ return 0;
+
+err_ring:
+ xgbe_free_ring_resources(pdata);
+
+ return ret;
+}
+
+static void xgbe_wrapper_tx_descriptor_init(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_channel *channel;
+ struct xgbe_ring *ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_ring_desc *rdesc;
+ dma_addr_t rdesc_dma;
+ unsigned int i, j;
+
+ DBGPR("-->xgbe_wrapper_tx_descriptor_init\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ ring = channel->tx_ring;
+ if (!ring)
+ break;
+
+ rdesc = ring->rdesc;
+ rdesc_dma = ring->rdesc_dma;
+
+ for (j = 0; j < ring->rdesc_count; j++) {
+ rdata = GET_DESC_DATA(ring, j);
+
+ rdata->rdesc = rdesc;
+ rdata->rdesc_dma = rdesc_dma;
+
+ rdesc++;
+ rdesc_dma += sizeof(struct xgbe_ring_desc);
+ }
+
+ ring->cur = 0;
+ ring->dirty = 0;
+ ring->tx.queue_stopped = 0;
+
+ hw_if->tx_desc_init(channel);
+ }
+
+ DBGPR("<--xgbe_wrapper_tx_descriptor_init\n");
+}
+
+static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_channel *channel;
+ struct xgbe_ring *ring;
+ struct xgbe_ring_desc *rdesc;
+ struct xgbe_ring_data *rdata;
+ dma_addr_t rdesc_dma, skb_dma;
+ struct sk_buff *skb = NULL;
+ unsigned int i, j;
+
+ DBGPR("-->xgbe_wrapper_rx_descriptor_init\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ ring = channel->rx_ring;
+ if (!ring)
+ break;
+
+ rdesc = ring->rdesc;
+ rdesc_dma = ring->rdesc_dma;
+
+ for (j = 0; j < ring->rdesc_count; j++) {
+ rdata = GET_DESC_DATA(ring, j);
+
+ rdata->rdesc = rdesc;
+ rdata->rdesc_dma = rdesc_dma;
+
+ /* Allocate skb & assign to each rdesc */
+ skb = dev_alloc_skb(pdata->rx_buf_size);
+ if (skb == NULL)
+ break;
+ skb_dma = dma_map_single(pdata->dev, skb->data,
+ pdata->rx_buf_size,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(pdata->dev, skb_dma)) {
+ netdev_alert(pdata->netdev,
+ "failed to do the dma map\n");
+ dev_kfree_skb_any(skb);
+ break;
+ }
+ rdata->skb = skb;
+ rdata->skb_dma = skb_dma;
+ rdata->skb_dma_len = pdata->rx_buf_size;
+
+ rdesc++;
+ rdesc_dma += sizeof(struct xgbe_ring_desc);
+ }
+
+ ring->cur = 0;
+ ring->dirty = 0;
+ ring->rx.realloc_index = 0;
+ ring->rx.realloc_threshold = 0;
+
+ hw_if->rx_desc_init(channel);
+ }
+
+ DBGPR("<--xgbe_wrapper_rx_descriptor_init\n");
+}
+
+static void xgbe_unmap_skb(struct xgbe_prv_data *pdata,
+ struct xgbe_ring_data *rdata)
+{
+ if (rdata->skb_dma) {
+ if (rdata->mapped_as_page) {
+ dma_unmap_page(pdata->dev, rdata->skb_dma,
+ rdata->skb_dma_len, DMA_TO_DEVICE);
+ } else {
+ dma_unmap_single(pdata->dev, rdata->skb_dma,
+ rdata->skb_dma_len, DMA_TO_DEVICE);
+ }
+ rdata->skb_dma = 0;
+ rdata->skb_dma_len = 0;
+ }
+
+ if (rdata->skb) {
+ dev_kfree_skb_any(rdata->skb);
+ rdata->skb = NULL;
+ }
+
+ rdata->tso_header = 0;
+ rdata->len = 0;
+ rdata->interrupt = 0;
+ rdata->mapped_as_page = 0;
+}
+
+static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_ring *ring = channel->tx_ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_packet_data *packet;
+ struct skb_frag_struct *frag;
+ dma_addr_t skb_dma;
+ unsigned int start_index, cur_index;
+ unsigned int offset, tso, vlan, datalen, len;
+ unsigned int i;
+
+ DBGPR("-->xgbe_map_tx_skb: cur = %d\n", ring->cur);
+
+ offset = 0;
+ start_index = ring->cur;
+ cur_index = ring->cur;
+
+ packet = &ring->packet_data;
+ packet->rdesc_count = 0;
+ packet->length = 0;
+
+ tso = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ TSO_ENABLE);
+ vlan = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ VLAN_CTAG);
+
+ /* Save space for a context descriptor if needed */
+ if ((tso && (packet->mss != ring->tx.cur_mss)) ||
+ (vlan && (packet->vlan_ctag != ring->tx.cur_vlan_ctag)))
+ cur_index++;
+ rdata = GET_DESC_DATA(ring, cur_index);
+
+ if (tso) {
+ DBGPR(" TSO packet\n");
+
+ /* Map the TSO header */
+ skb_dma = dma_map_single(pdata->dev, skb->data,
+ packet->header_len, DMA_TO_DEVICE);
+ if (dma_mapping_error(pdata->dev, skb_dma)) {
+ netdev_alert(pdata->netdev, "dma_map_single failed\n");
+ goto err_out;
+ }
+ rdata->skb_dma = skb_dma;
+ rdata->skb_dma_len = packet->header_len;
+ rdata->tso_header = 1;
+
+ offset = packet->header_len;
+
+ packet->length += packet->header_len;
+
+ cur_index++;
+ rdata = GET_DESC_DATA(ring, cur_index);
+ }
+
+ /* Map the (remainder of the) packet */
+ for (datalen = skb_headlen(skb) - offset; datalen; ) {
+ len = min_t(unsigned int, datalen, TX_MAX_BUF_SIZE);
+
+ skb_dma = dma_map_single(pdata->dev, skb->data + offset, len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(pdata->dev, skb_dma)) {
+ netdev_alert(pdata->netdev, "dma_map_single failed\n");
+ goto err_out;
+ }
+ rdata->skb_dma = skb_dma;
+ rdata->skb_dma_len = len;
+ DBGPR(" skb data: index=%u, dma=0x%llx, len=%u\n",
+ cur_index, skb_dma, len);
+
+ datalen -= len;
+ offset += len;
+
+ packet->length += len;
+
+ cur_index++;
+ rdata = GET_DESC_DATA(ring, cur_index);
+ }
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ DBGPR(" mapping frag %u\n", i);
+
+ frag = &skb_shinfo(skb)->frags[i];
+ offset = 0;
+
+ for (datalen = skb_frag_size(frag); datalen; ) {
+ len = min_t(unsigned int, datalen, TX_MAX_BUF_SIZE);
+
+ skb_dma = skb_frag_dma_map(pdata->dev, frag, offset,
+ len, DMA_TO_DEVICE);
+ if (dma_mapping_error(pdata->dev, skb_dma)) {
+ netdev_alert(pdata->netdev,
+ "skb_frag_dma_map failed\n");
+ goto err_out;
+ }
+ rdata->skb_dma = skb_dma;
+ rdata->skb_dma_len = len;
+ rdata->mapped_as_page = 1;
+ DBGPR(" skb data: index=%u, dma=0x%llx, len=%u\n",
+ cur_index, skb_dma, len);
+
+ datalen -= len;
+ offset += len;
+
+ packet->length += len;
+
+ cur_index++;
+ rdata = GET_DESC_DATA(ring, cur_index);
+ }
+ }
+
+ /* Save the skb address in the last entry */
+ rdata->skb = skb;
+
+ /* Save the number of descriptor entries used */
+ packet->rdesc_count = cur_index - start_index;
+
+ DBGPR("<--xgbe_map_tx_skb: count=%u\n", packet->rdesc_count);
+
+ return packet->rdesc_count;
+
+err_out:
+ while (start_index < cur_index) {
+ rdata = GET_DESC_DATA(ring, start_index++);
+ xgbe_unmap_skb(pdata, rdata);
+ }
+
+ DBGPR("<--xgbe_map_tx_skb: count=0\n");
+
+ return 0;
+}
+
+static void xgbe_realloc_skb(struct xgbe_channel *channel)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_ring *ring = channel->rx_ring;
+ struct xgbe_ring_data *rdata;
+ struct sk_buff *skb = NULL;
+ dma_addr_t skb_dma;
+ int i;
+
+ DBGPR("-->xgbe_realloc_skb: rx_ring->rx.realloc_index = %u\n",
+ ring->rx.realloc_index);
+
+ for (i = 0; i < ring->dirty; i++) {
+ rdata = GET_DESC_DATA(ring, ring->rx.realloc_index);
+
+ /* Reset rdata values */
+ xgbe_unmap_skb(pdata, rdata);
+
+ /* Allocate skb & assign to each rdesc */
+ skb = dev_alloc_skb(pdata->rx_buf_size);
+ if (skb == NULL) {
+ netdev_alert(pdata->netdev,
+ "failed to allocate skb\n");
+ break;
+ }
+ skb_dma = dma_map_single(pdata->dev, skb->data,
+ pdata->rx_buf_size, DMA_FROM_DEVICE);
+ if (dma_mapping_error(pdata->dev, skb_dma)) {
+ netdev_alert(pdata->netdev,
+ "failed to do the dma map\n");
+ dev_kfree_skb_any(skb);
+ break;
+ }
+ rdata->skb = skb;
+ rdata->skb_dma = skb_dma;
+ rdata->skb_dma_len = pdata->rx_buf_size;
+
+ hw_if->rx_desc_reset(rdata);
+
+ ring->rx.realloc_index++;
+ }
+ ring->dirty = 0;
+
+ DBGPR("<--xgbe_realloc_skb\n");
+}
+
+void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *desc_if)
+{
+ DBGPR("-->xgbe_init_function_ptrs_desc\n");
+
+ desc_if->alloc_ring_resources = xgbe_alloc_ring_resources;
+ desc_if->free_ring_resources = xgbe_free_ring_resources;
+ desc_if->map_tx_skb = xgbe_map_tx_skb;
+ desc_if->realloc_skb = xgbe_realloc_skb;
+ desc_if->unmap_skb = xgbe_unmap_skb;
+ desc_if->wrapper_tx_desc_init = xgbe_wrapper_tx_descriptor_init;
+ desc_if->wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init;
+
+ DBGPR("<--xgbe_init_function_ptrs_desc\n");
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
new file mode 100644
index 00000000000..002293b0819
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -0,0 +1,2182 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/phy.h>
+#include <linux/clk.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+static unsigned int xgbe_usec_to_riwt(struct xgbe_prv_data *pdata,
+ unsigned int usec)
+{
+ unsigned long rate;
+ unsigned int ret;
+
+ DBGPR("-->xgbe_usec_to_riwt\n");
+
+ rate = clk_get_rate(pdata->sysclock);
+
+ /*
+ * Convert the input usec value to the watchdog timer value. Each
+ * watchdog timer value is equivalent to 256 clock cycles.
+ * Calculate the required value as:
+ * ( usec * ( system_clock_mhz / 10^6 ) / 256
+ */
+ ret = (usec * (rate / 1000000)) / 256;
+
+ DBGPR("<--xgbe_usec_to_riwt\n");
+
+ return ret;
+}
+
+static unsigned int xgbe_riwt_to_usec(struct xgbe_prv_data *pdata,
+ unsigned int riwt)
+{
+ unsigned long rate;
+ unsigned int ret;
+
+ DBGPR("-->xgbe_riwt_to_usec\n");
+
+ rate = clk_get_rate(pdata->sysclock);
+
+ /*
+ * Convert the input watchdog timer value to the usec value. Each
+ * watchdog timer value is equivalent to 256 clock cycles.
+ * Calculate the required value as:
+ * ( riwt * 256 ) / ( system_clock_mhz / 10^6 )
+ */
+ ret = (riwt * 256) / (rate / 1000000);
+
+ DBGPR("<--xgbe_riwt_to_usec\n");
+
+ return ret;
+}
+
+static int xgbe_config_pblx8(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++)
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_CR, PBLX8,
+ pdata->pblx8);
+
+ return 0;
+}
+
+static int xgbe_get_tx_pbl_val(struct xgbe_prv_data *pdata)
+{
+ return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_TCR, PBL);
+}
+
+static int xgbe_config_tx_pbl_val(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, PBL,
+ pdata->tx_pbl);
+ }
+
+ return 0;
+}
+
+static int xgbe_get_rx_pbl_val(struct xgbe_prv_data *pdata)
+{
+ return XGMAC_DMA_IOREAD_BITS(pdata->channel, DMA_CH_RCR, PBL);
+}
+
+static int xgbe_config_rx_pbl_val(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, PBL,
+ pdata->rx_pbl);
+ }
+
+ return 0;
+}
+
+static int xgbe_config_osp_mode(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, OSP,
+ pdata->tx_osp_mode);
+ }
+
+ return 0;
+}
+
+static int xgbe_config_rsf_mode(struct xgbe_prv_data *pdata, unsigned int val)
+{
+ unsigned int i;
+
+ for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RSF, val);
+
+ return 0;
+}
+
+static int xgbe_config_tsf_mode(struct xgbe_prv_data *pdata, unsigned int val)
+{
+ unsigned int i;
+
+ for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TSF, val);
+
+ return 0;
+}
+
+static int xgbe_config_rx_threshold(struct xgbe_prv_data *pdata,
+ unsigned int val)
+{
+ unsigned int i;
+
+ for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RTC, val);
+
+ return 0;
+}
+
+static int xgbe_config_tx_threshold(struct xgbe_prv_data *pdata,
+ unsigned int val)
+{
+ unsigned int i;
+
+ for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TTC, val);
+
+ return 0;
+}
+
+static int xgbe_config_rx_coalesce(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RIWT, RWT,
+ pdata->rx_riwt);
+ }
+
+ return 0;
+}
+
+static int xgbe_config_tx_coalesce(struct xgbe_prv_data *pdata)
+{
+ return 0;
+}
+
+static void xgbe_config_rx_buffer_size(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, RBSZ,
+ pdata->rx_buf_size);
+ }
+}
+
+static void xgbe_config_tso_mode(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, TSE, 1);
+ }
+}
+
+static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
+{
+ unsigned int max_q_count, q_count;
+ unsigned int reg, reg_val;
+ unsigned int i;
+
+ /* Clear MTL flow control */
+ for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
+
+ /* Clear MAC flow control */
+ max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
+ q_count = min_t(unsigned int, pdata->hw_feat.rx_q_cnt, max_q_count);
+ reg = MAC_Q0TFCR;
+ for (i = 0; i < q_count; i++) {
+ reg_val = XGMAC_IOREAD(pdata, reg);
+ XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 0);
+ XGMAC_IOWRITE(pdata, reg, reg_val);
+
+ reg += MAC_QTFCR_INC;
+ }
+
+ return 0;
+}
+
+static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
+{
+ unsigned int max_q_count, q_count;
+ unsigned int reg, reg_val;
+ unsigned int i;
+
+ /* Set MTL flow control */
+ for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 1);
+
+ /* Set MAC flow control */
+ max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
+ q_count = min_t(unsigned int, pdata->hw_feat.rx_q_cnt, max_q_count);
+ reg = MAC_Q0TFCR;
+ for (i = 0; i < q_count; i++) {
+ reg_val = XGMAC_IOREAD(pdata, reg);
+
+ /* Enable transmit flow control */
+ XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, TFE, 1);
+ /* Set pause time */
+ XGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, 0xffff);
+
+ XGMAC_IOWRITE(pdata, reg, reg_val);
+
+ reg += MAC_QTFCR_INC;
+ }
+
+ return 0;
+}
+
+static int xgbe_disable_rx_flow_control(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 0);
+
+ return 0;
+}
+
+static int xgbe_enable_rx_flow_control(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_RFCR, RFE, 1);
+
+ return 0;
+}
+
+static int xgbe_config_tx_flow_control(struct xgbe_prv_data *pdata)
+{
+ if (pdata->tx_pause)
+ xgbe_enable_tx_flow_control(pdata);
+ else
+ xgbe_disable_tx_flow_control(pdata);
+
+ return 0;
+}
+
+static int xgbe_config_rx_flow_control(struct xgbe_prv_data *pdata)
+{
+ if (pdata->rx_pause)
+ xgbe_enable_rx_flow_control(pdata);
+ else
+ xgbe_disable_rx_flow_control(pdata);
+
+ return 0;
+}
+
+static void xgbe_config_flow_control(struct xgbe_prv_data *pdata)
+{
+ xgbe_config_tx_flow_control(pdata);
+ xgbe_config_rx_flow_control(pdata);
+}
+
+static void xgbe_enable_dma_interrupts(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int dma_ch_isr, dma_ch_ier;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ /* Clear all the interrupts which are set */
+ dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr);
+
+ /* Clear all interrupt enable bits */
+ dma_ch_ier = 0;
+
+ /* Enable following interrupts
+ * NIE - Normal Interrupt Summary Enable
+ * AIE - Abnormal Interrupt Summary Enable
+ * FBEE - Fatal Bus Error Enable
+ */
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, NIE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, AIE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, FBEE, 1);
+
+ if (channel->tx_ring) {
+ /* Enable the following Tx interrupts
+ * TIE - Transmit Interrupt Enable (unless polling)
+ */
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, TIE, 1);
+ }
+ if (channel->rx_ring) {
+ /* Enable following Rx interrupts
+ * RBUE - Receive Buffer Unavailable Enable
+ * RIE - Receive Interrupt Enable
+ */
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RBUE, 1);
+ XGMAC_SET_BITS(dma_ch_ier, DMA_CH_IER, RIE, 1);
+ }
+
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
+ }
+}
+
+static void xgbe_enable_mtl_interrupts(struct xgbe_prv_data *pdata)
+{
+ unsigned int mtl_q_isr;
+ unsigned int q_count, i;
+
+ q_count = max(pdata->hw_feat.tx_q_cnt, pdata->hw_feat.rx_q_cnt);
+ for (i = 0; i < q_count; i++) {
+ /* Clear all the interrupts which are set */
+ mtl_q_isr = XGMAC_MTL_IOREAD(pdata, i, MTL_Q_ISR);
+ XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_ISR, mtl_q_isr);
+
+ /* No MTL interrupts to be enabled */
+ XGMAC_MTL_IOWRITE(pdata, i, MTL_Q_ISR, 0);
+ }
+}
+
+static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata)
+{
+ /* No MAC interrupts to be enabled */
+ XGMAC_IOWRITE(pdata, MAC_IER, 0);
+
+ /* Enable all counter interrupts */
+ XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xff);
+ XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xff);
+}
+
+static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x3);
+
+ return 0;
+}
+
+static int xgbe_set_gmii_2500_speed(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0x2);
+
+ return 0;
+}
+
+static int xgbe_set_xgmii_speed(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, SS, 0);
+
+ return 0;
+}
+
+static int xgbe_set_promiscuous_mode(struct xgbe_prv_data *pdata,
+ unsigned int enable)
+{
+ unsigned int val = enable ? 1 : 0;
+
+ if (XGMAC_IOREAD_BITS(pdata, MAC_PFR, PR) == val)
+ return 0;
+
+ DBGPR(" %s promiscuous mode\n", enable ? "entering" : "leaving");
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, val);
+
+ return 0;
+}
+
+static int xgbe_set_all_multicast_mode(struct xgbe_prv_data *pdata,
+ unsigned int enable)
+{
+ unsigned int val = enable ? 1 : 0;
+
+ if (XGMAC_IOREAD_BITS(pdata, MAC_PFR, PM) == val)
+ return 0;
+
+ DBGPR(" %s allmulti mode\n", enable ? "entering" : "leaving");
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, val);
+
+ return 0;
+}
+
+static int xgbe_set_addn_mac_addrs(struct xgbe_prv_data *pdata,
+ unsigned int am_mode)
+{
+ struct netdev_hw_addr *ha;
+ unsigned int mac_reg;
+ unsigned int mac_addr_hi, mac_addr_lo;
+ u8 *mac_addr;
+ unsigned int i;
+
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
+ XGMAC_IOWRITE_BITS(pdata, MAC_PFR, HMC, 0);
+
+ i = 0;
+ mac_reg = MAC_MACA1HR;
+
+ netdev_for_each_uc_addr(ha, pdata->netdev) {
+ mac_addr_lo = 0;
+ mac_addr_hi = 0;
+ mac_addr = (u8 *)&mac_addr_lo;
+ mac_addr[0] = ha->addr[0];
+ mac_addr[1] = ha->addr[1];
+ mac_addr[2] = ha->addr[2];
+ mac_addr[3] = ha->addr[3];
+ mac_addr = (u8 *)&mac_addr_hi;
+ mac_addr[0] = ha->addr[4];
+ mac_addr[1] = ha->addr[5];
+
+ DBGPR(" adding unicast address %pM at 0x%04x\n",
+ ha->addr, mac_reg);
+
+ XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
+
+ XGMAC_IOWRITE(pdata, mac_reg, mac_addr_hi);
+ mac_reg += MAC_MACA_INC;
+ XGMAC_IOWRITE(pdata, mac_reg, mac_addr_lo);
+ mac_reg += MAC_MACA_INC;
+
+ i++;
+ }
+
+ if (!am_mode) {
+ netdev_for_each_mc_addr(ha, pdata->netdev) {
+ mac_addr_lo = 0;
+ mac_addr_hi = 0;
+ mac_addr = (u8 *)&mac_addr_lo;
+ mac_addr[0] = ha->addr[0];
+ mac_addr[1] = ha->addr[1];
+ mac_addr[2] = ha->addr[2];
+ mac_addr[3] = ha->addr[3];
+ mac_addr = (u8 *)&mac_addr_hi;
+ mac_addr[0] = ha->addr[4];
+ mac_addr[1] = ha->addr[5];
+
+ DBGPR(" adding multicast address %pM at 0x%04x\n",
+ ha->addr, mac_reg);
+
+ XGMAC_SET_BITS(mac_addr_hi, MAC_MACA1HR, AE, 1);
+
+ XGMAC_IOWRITE(pdata, mac_reg, mac_addr_hi);
+ mac_reg += MAC_MACA_INC;
+ XGMAC_IOWRITE(pdata, mac_reg, mac_addr_lo);
+ mac_reg += MAC_MACA_INC;
+
+ i++;
+ }
+ }
+
+ /* Clear remaining additional MAC address entries */
+ for (; i < pdata->hw_feat.addn_mac; i++) {
+ XGMAC_IOWRITE(pdata, mac_reg, 0);
+ mac_reg += MAC_MACA_INC;
+ XGMAC_IOWRITE(pdata, mac_reg, 0);
+ mac_reg += MAC_MACA_INC;
+ }
+
+ return 0;
+}
+
+static int xgbe_set_mac_address(struct xgbe_prv_data *pdata, u8 *addr)
+{
+ unsigned int mac_addr_hi, mac_addr_lo;
+
+ mac_addr_hi = (addr[5] << 8) | (addr[4] << 0);
+ mac_addr_lo = (addr[3] << 24) | (addr[2] << 16) |
+ (addr[1] << 8) | (addr[0] << 0);
+
+ XGMAC_IOWRITE(pdata, MAC_MACA0HR, mac_addr_hi);
+ XGMAC_IOWRITE(pdata, MAC_MACA0LR, mac_addr_lo);
+
+ return 0;
+}
+
+static int xgbe_read_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
+ int mmd_reg)
+{
+ unsigned int mmd_address;
+ int mmd_data;
+
+ if (mmd_reg & MII_ADDR_C45)
+ mmd_address = mmd_reg & ~MII_ADDR_C45;
+ else
+ mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
+
+ /* The PCS registers are accessed using mmio. The underlying APB3
+ * management interface uses indirect addressing to access the MMD
+ * register sets. This requires accessing of the PCS register in two
+ * phases, an address phase and a data phase.
+ *
+ * The mmio interface is based on 32-bit offsets and values. All
+ * register offsets must therefore be adjusted by left shifting the
+ * offset 2 bits and reading 32 bits of data.
+ */
+ mutex_lock(&pdata->xpcs_mutex);
+ XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8);
+ mmd_data = XPCS_IOREAD(pdata, (mmd_address & 0xff) << 2);
+ mutex_unlock(&pdata->xpcs_mutex);
+
+ return mmd_data;
+}
+
+static void xgbe_write_mmd_regs(struct xgbe_prv_data *pdata, int prtad,
+ int mmd_reg, int mmd_data)
+{
+ unsigned int mmd_address;
+
+ if (mmd_reg & MII_ADDR_C45)
+ mmd_address = mmd_reg & ~MII_ADDR_C45;
+ else
+ mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
+
+ /* The PCS registers are accessed using mmio. The underlying APB3
+ * management interface uses indirect addressing to access the MMD
+ * register sets. This requires accessing of the PCS register in two
+ * phases, an address phase and a data phase.
+ *
+ * The mmio interface is based on 32-bit offsets and values. All
+ * register offsets must therefore be adjusted by left shifting the
+ * offset 2 bits and reading 32 bits of data.
+ */
+ mutex_lock(&pdata->xpcs_mutex);
+ XPCS_IOWRITE(pdata, PCS_MMD_SELECT << 2, mmd_address >> 8);
+ XPCS_IOWRITE(pdata, (mmd_address & 0xff) << 2, mmd_data);
+ mutex_unlock(&pdata->xpcs_mutex);
+}
+
+static int xgbe_tx_complete(struct xgbe_ring_desc *rdesc)
+{
+ return !XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN);
+}
+
+static int xgbe_disable_rx_csum(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 0);
+
+ return 0;
+}
+
+static int xgbe_enable_rx_csum(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, IPC, 1);
+
+ return 0;
+}
+
+static int xgbe_enable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
+{
+ /* Put the VLAN tag in the Rx descriptor */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLRXS, 1);
+
+ /* Don't check the VLAN type */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, DOVLTC, 1);
+
+ /* Check only C-TAG (0x8100) packets */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERSVLM, 0);
+
+ /* Don't consider an S-TAG (0x88A8) packet as a VLAN packet */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ESVL, 0);
+
+ /* Enable VLAN tag stripping */
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0x3);
+
+ return 0;
+}
+
+static int xgbe_disable_rx_vlan_stripping(struct xgbe_prv_data *pdata)
+{
+ XGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EVLS, 0);
+
+ return 0;
+}
+
+static void xgbe_tx_desc_reset(struct xgbe_ring_data *rdata)
+{
+ struct xgbe_ring_desc *rdesc = rdata->rdesc;
+
+ /* Reset the Tx descriptor
+ * Set buffer 1 (lo) address to zero
+ * Set buffer 1 (hi) address to zero
+ * Reset all other control bits (IC, TTSE, B2L & B1L)
+ * Reset all other control bits (OWN, CTXT, FD, LD, CPC, CIC, etc)
+ */
+ rdesc->desc0 = 0;
+ rdesc->desc1 = 0;
+ rdesc->desc2 = 0;
+ rdesc->desc3 = 0;
+}
+
+static void xgbe_tx_desc_init(struct xgbe_channel *channel)
+{
+ struct xgbe_ring *ring = channel->tx_ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_ring_desc *rdesc;
+ int i;
+ int start_index = ring->cur;
+
+ DBGPR("-->tx_desc_init\n");
+
+ /* Initialze all descriptors */
+ for (i = 0; i < ring->rdesc_count; i++) {
+ rdata = GET_DESC_DATA(ring, i);
+ rdesc = rdata->rdesc;
+
+ /* Initialize Tx descriptor
+ * Set buffer 1 (lo) address to zero
+ * Set buffer 1 (hi) address to zero
+ * Reset all other control bits (IC, TTSE, B2L & B1L)
+ * Reset all other control bits (OWN, CTXT, FD, LD, CPC, CIC,
+ * etc)
+ */
+ rdesc->desc0 = 0;
+ rdesc->desc1 = 0;
+ rdesc->desc2 = 0;
+ rdesc->desc3 = 0;
+ }
+
+ /* Make sure everything is written to the descriptor(s) before
+ * telling the device about them
+ */
+ wmb();
+
+ /* Update the total number of Tx descriptors */
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDRLR, ring->rdesc_count - 1);
+
+ /* Update the starting address of descriptor ring */
+ rdata = GET_DESC_DATA(ring, start_index);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_HI,
+ upper_32_bits(rdata->rdesc_dma));
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDLR_LO,
+ lower_32_bits(rdata->rdesc_dma));
+
+ DBGPR("<--tx_desc_init\n");
+}
+
+static void xgbe_rx_desc_reset(struct xgbe_ring_data *rdata)
+{
+ struct xgbe_ring_desc *rdesc = rdata->rdesc;
+
+ /* Reset the Rx descriptor
+ * Set buffer 1 (lo) address to dma address (lo)
+ * Set buffer 1 (hi) address to dma address (hi)
+ * Set buffer 2 (lo) address to zero
+ * Set buffer 2 (hi) address to zero and set control bits
+ * OWN and INTE
+ */
+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->skb_dma));
+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->skb_dma));
+ rdesc->desc2 = 0;
+
+ rdesc->desc3 = 0;
+ if (rdata->interrupt)
+ XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE, 1);
+
+ /* Since the Rx DMA engine is likely running, make sure everything
+ * is written to the descriptor(s) before setting the OWN bit
+ * for the descriptor
+ */
+ wmb();
+
+ XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN, 1);
+
+ /* Make sure ownership is written to the descriptor */
+ wmb();
+}
+
+static void xgbe_rx_desc_init(struct xgbe_channel *channel)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_ring *ring = channel->rx_ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_ring_desc *rdesc;
+ unsigned int start_index = ring->cur;
+ unsigned int rx_coalesce, rx_frames;
+ unsigned int i;
+
+ DBGPR("-->rx_desc_init\n");
+
+ rx_coalesce = (pdata->rx_riwt || pdata->rx_frames) ? 1 : 0;
+ rx_frames = pdata->rx_frames;
+
+ /* Initialize all descriptors */
+ for (i = 0; i < ring->rdesc_count; i++) {
+ rdata = GET_DESC_DATA(ring, i);
+ rdesc = rdata->rdesc;
+
+ /* Initialize Rx descriptor
+ * Set buffer 1 (lo) address to dma address (lo)
+ * Set buffer 1 (hi) address to dma address (hi)
+ * Set buffer 2 (lo) address to zero
+ * Set buffer 2 (hi) address to zero and set control
+ * bits OWN and INTE appropriateley
+ */
+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->skb_dma));
+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->skb_dma));
+ rdesc->desc2 = 0;
+ rdesc->desc3 = 0;
+ XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN, 1);
+ XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE, 1);
+ rdata->interrupt = 1;
+ if (rx_coalesce && (!rx_frames || ((i + 1) % rx_frames))) {
+ /* Clear interrupt on completion bit */
+ XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE,
+ 0);
+ rdata->interrupt = 0;
+ }
+ }
+
+ /* Make sure everything is written to the descriptors before
+ * telling the device about them
+ */
+ wmb();
+
+ /* Update the total number of Rx descriptors */
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDRLR, ring->rdesc_count - 1);
+
+ /* Update the starting address of descriptor ring */
+ rdata = GET_DESC_DATA(ring, start_index);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_HI,
+ upper_32_bits(rdata->rdesc_dma));
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDLR_LO,
+ lower_32_bits(rdata->rdesc_dma));
+
+ /* Update the Rx Descriptor Tail Pointer */
+ rdata = GET_DESC_DATA(ring, start_index + ring->rdesc_count - 1);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
+ lower_32_bits(rdata->rdesc_dma));
+
+ DBGPR("<--rx_desc_init\n");
+}
+
+static void xgbe_pre_xmit(struct xgbe_channel *channel)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_ring *ring = channel->tx_ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_ring_desc *rdesc;
+ struct xgbe_packet_data *packet = &ring->packet_data;
+ unsigned int csum, tso, vlan;
+ unsigned int tso_context, vlan_context;
+ unsigned int tx_coalesce, tx_frames;
+ int start_index = ring->cur;
+ int i;
+
+ DBGPR("-->xgbe_pre_xmit\n");
+
+ csum = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ CSUM_ENABLE);
+ tso = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ TSO_ENABLE);
+ vlan = XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ VLAN_CTAG);
+
+ if (tso && (packet->mss != ring->tx.cur_mss))
+ tso_context = 1;
+ else
+ tso_context = 0;
+
+ if (vlan && (packet->vlan_ctag != ring->tx.cur_vlan_ctag))
+ vlan_context = 1;
+ else
+ vlan_context = 0;
+
+ tx_coalesce = (pdata->tx_usecs || pdata->tx_frames) ? 1 : 0;
+ tx_frames = pdata->tx_frames;
+ if (tx_coalesce && !channel->tx_timer_active)
+ ring->coalesce_count = 0;
+
+ rdata = GET_DESC_DATA(ring, ring->cur);
+ rdesc = rdata->rdesc;
+
+ /* Create a context descriptor if this is a TSO packet */
+ if (tso_context || vlan_context) {
+ if (tso_context) {
+ DBGPR(" TSO context descriptor, mss=%u\n",
+ packet->mss);
+
+ /* Set the MSS size */
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_CONTEXT_DESC2,
+ MSS, packet->mss);
+
+ /* Mark it as a CONTEXT descriptor */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
+ CTXT, 1);
+
+ /* Indicate this descriptor contains the MSS */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
+ TCMSSV, 1);
+
+ ring->tx.cur_mss = packet->mss;
+ }
+
+ if (vlan_context) {
+ DBGPR(" VLAN context descriptor, ctag=%u\n",
+ packet->vlan_ctag);
+
+ /* Mark it as a CONTEXT descriptor */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
+ CTXT, 1);
+
+ /* Set the VLAN tag */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
+ VT, packet->vlan_ctag);
+
+ /* Indicate this descriptor contains the VLAN tag */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_CONTEXT_DESC3,
+ VLTV, 1);
+
+ ring->tx.cur_vlan_ctag = packet->vlan_ctag;
+ }
+
+ ring->cur++;
+ rdata = GET_DESC_DATA(ring, ring->cur);
+ rdesc = rdata->rdesc;
+ }
+
+ /* Update buffer address (for TSO this is the header) */
+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->skb_dma));
+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->skb_dma));
+
+ /* Update the buffer length */
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L,
+ rdata->skb_dma_len);
+
+ /* VLAN tag insertion check */
+ if (vlan)
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, VTIR,
+ TX_NORMAL_DESC2_VLAN_INSERT);
+
+ /* Set IC bit based on Tx coalescing settings */
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
+ if (tx_coalesce && (!tx_frames ||
+ (++ring->coalesce_count % tx_frames)))
+ /* Clear IC bit */
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0);
+
+ /* Mark it as First Descriptor */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FD, 1);
+
+ /* Mark it as a NORMAL descriptor */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0);
+
+ /* Set OWN bit if not the first descriptor */
+ if (ring->cur != start_index)
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
+
+ if (tso) {
+ /* Enable TSO */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, TSE, 1);
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, TCPPL,
+ packet->tcp_payload_len);
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, TCPHDRLEN,
+ packet->tcp_header_len / 4);
+ } else {
+ /* Enable CRC and Pad Insertion */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CPC, 0);
+
+ /* Enable HW CSUM */
+ if (csum)
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3,
+ CIC, 0x3);
+
+ /* Set the total length to be transmitted */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, FL,
+ packet->length);
+ }
+
+ for (i = ring->cur - start_index + 1; i < packet->rdesc_count; i++) {
+ ring->cur++;
+ rdata = GET_DESC_DATA(ring, ring->cur);
+ rdesc = rdata->rdesc;
+
+ /* Update buffer address */
+ rdesc->desc0 = cpu_to_le32(lower_32_bits(rdata->skb_dma));
+ rdesc->desc1 = cpu_to_le32(upper_32_bits(rdata->skb_dma));
+
+ /* Update the buffer length */
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, HL_B1L,
+ rdata->skb_dma_len);
+
+ /* Set IC bit based on Tx coalescing settings */
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 1);
+ if (tx_coalesce && (!tx_frames ||
+ (++ring->coalesce_count % tx_frames)))
+ /* Clear IC bit */
+ XGMAC_SET_BITS_LE(rdesc->desc2, TX_NORMAL_DESC2, IC, 0);
+
+ /* Set OWN bit */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
+
+ /* Mark it as NORMAL descriptor */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT, 0);
+
+ /* Enable HW CSUM */
+ if (csum)
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3,
+ CIC, 0x3);
+ }
+
+ /* Set LAST bit for the last descriptor */
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD, 1);
+
+ /* In case the Tx DMA engine is running, make sure everything
+ * is written to the descriptor(s) before setting the OWN bit
+ * for the first descriptor
+ */
+ wmb();
+
+ /* Set OWN bit for the first descriptor */
+ rdata = GET_DESC_DATA(ring, start_index);
+ rdesc = rdata->rdesc;
+ XGMAC_SET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, OWN, 1);
+
+#ifdef XGMAC_ENABLE_TX_DESC_DUMP
+ xgbe_dump_tx_desc(ring, start_index, packet->rdesc_count, 1);
+#endif
+
+ /* Make sure ownership is written to the descriptor */
+ wmb();
+
+ /* Issue a poll command to Tx DMA by writing address
+ * of next immediate free descriptor */
+ ring->cur++;
+ rdata = GET_DESC_DATA(ring, ring->cur);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO,
+ lower_32_bits(rdata->rdesc_dma));
+
+ /* Start the Tx coalescing timer */
+ if (tx_coalesce && !channel->tx_timer_active) {
+ channel->tx_timer_active = 1;
+ hrtimer_start(&channel->tx_timer,
+ ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC),
+ HRTIMER_MODE_REL);
+ }
+
+ DBGPR(" %s: descriptors %u to %u written\n",
+ channel->name, start_index & (ring->rdesc_count - 1),
+ (ring->cur - 1) & (ring->rdesc_count - 1));
+
+ DBGPR("<--xgbe_pre_xmit\n");
+}
+
+static int xgbe_dev_read(struct xgbe_channel *channel)
+{
+ struct xgbe_ring *ring = channel->rx_ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_ring_desc *rdesc;
+ struct xgbe_packet_data *packet = &ring->packet_data;
+ unsigned int err, etlt;
+
+ DBGPR("-->xgbe_dev_read: cur = %d\n", ring->cur);
+
+ rdata = GET_DESC_DATA(ring, ring->cur);
+ rdesc = rdata->rdesc;
+
+ /* Check for data availability */
+ if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, OWN))
+ return 1;
+
+#ifdef XGMAC_ENABLE_RX_DESC_DUMP
+ xgbe_dump_rx_desc(ring, rdesc, ring->cur);
+#endif
+
+ /* Get the packet length */
+ rdata->len = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, PL);
+
+ if (!XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, LD)) {
+ /* Not all the data has been transferred for this packet */
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ INCOMPLETE, 1);
+ return 0;
+ }
+
+ /* This is the last of the data for this packet */
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ INCOMPLETE, 0);
+
+ /* Set checksum done indicator as appropriate */
+ if (channel->pdata->netdev->features & NETIF_F_RXCSUM)
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ CSUM_DONE, 1);
+
+ /* Check for errors (only valid in last descriptor) */
+ err = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ES);
+ etlt = XGMAC_GET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, ETLT);
+ DBGPR(" err=%u, etlt=%#x\n", err, etlt);
+
+ if (!err || (err && !etlt)) {
+ if (etlt == 0x09) {
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ VLAN_CTAG, 1);
+ packet->vlan_ctag = XGMAC_GET_BITS_LE(rdesc->desc0,
+ RX_NORMAL_DESC0,
+ OVT);
+ DBGPR(" vlan-ctag=0x%04x\n", packet->vlan_ctag);
+ }
+ } else {
+ if ((etlt == 0x05) || (etlt == 0x06))
+ XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
+ CSUM_DONE, 0);
+ else
+ XGMAC_SET_BITS(packet->errors, RX_PACKET_ERRORS,
+ FRAME, 1);
+ }
+
+ DBGPR("<--xgbe_dev_read: %s - descriptor=%u (cur=%d)\n", channel->name,
+ ring->cur & (ring->rdesc_count - 1), ring->cur);
+
+ return 0;
+}
+
+static int xgbe_is_context_desc(struct xgbe_ring_desc *rdesc)
+{
+ /* Rx and Tx share CTXT bit, so check TDES3.CTXT bit */
+ return XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, CTXT);
+}
+
+static int xgbe_is_last_desc(struct xgbe_ring_desc *rdesc)
+{
+ /* Rx and Tx share LD bit, so check TDES3.LD bit */
+ return XGMAC_GET_BITS_LE(rdesc->desc3, TX_NORMAL_DESC3, LD);
+}
+
+static void xgbe_save_interrupt_status(struct xgbe_channel *channel,
+ enum xgbe_int_state int_state)
+{
+ unsigned int dma_ch_ier;
+
+ if (int_state == XGMAC_INT_STATE_SAVE) {
+ channel->saved_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
+ channel->saved_ier &= DMA_INTERRUPT_MASK;
+ } else {
+ dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
+ dma_ch_ier |= channel->saved_ier;
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
+ }
+}
+
+static int xgbe_enable_int(struct xgbe_channel *channel,
+ enum xgbe_int int_id)
+{
+ switch (int_id) {
+ case XGMAC_INT_DMA_ISR_DC0IS:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TI:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TPS:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TXSE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TBU:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TBUE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_RI:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RIE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_RBU:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RBUE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_RPS:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RSE, 1);
+ break;
+ case XGMAC_INT_DMA_CH_SR_FBE:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, FBEE, 1);
+ break;
+ case XGMAC_INT_DMA_ALL:
+ xgbe_save_interrupt_status(channel, XGMAC_INT_STATE_RESTORE);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int xgbe_disable_int(struct xgbe_channel *channel,
+ enum xgbe_int int_id)
+{
+ unsigned int dma_ch_ier;
+
+ switch (int_id) {
+ case XGMAC_INT_DMA_ISR_DC0IS:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TI:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TIE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TPS:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TXSE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_TBU:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, TBUE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_RI:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RIE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_RBU:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RBUE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_RPS:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, RSE, 0);
+ break;
+ case XGMAC_INT_DMA_CH_SR_FBE:
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_IER, FBEE, 0);
+ break;
+ case XGMAC_INT_DMA_ALL:
+ xgbe_save_interrupt_status(channel, XGMAC_INT_STATE_SAVE);
+
+ dma_ch_ier = XGMAC_DMA_IOREAD(channel, DMA_CH_IER);
+ dma_ch_ier &= ~DMA_INTERRUPT_MASK;
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_IER, dma_ch_ier);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int xgbe_exit(struct xgbe_prv_data *pdata)
+{
+ unsigned int count = 2000;
+
+ DBGPR("-->xgbe_exit\n");
+
+ /* Issue a software reset */
+ XGMAC_IOWRITE_BITS(pdata, DMA_MR, SWR, 1);
+ usleep_range(10, 15);
+
+ /* Poll Until Poll Condition */
+ while (count-- && XGMAC_IOREAD_BITS(pdata, DMA_MR, SWR))
+ usleep_range(500, 600);
+
+ if (!count)
+ return -EBUSY;
+
+ DBGPR("<--xgbe_exit\n");
+
+ return 0;
+}
+
+static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata)
+{
+ unsigned int i, count;
+
+ for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1);
+
+ /* Poll Until Poll Condition */
+ for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++) {
+ count = 2000;
+ while (count-- && XGMAC_MTL_IOREAD_BITS(pdata, i,
+ MTL_Q_TQOMR, FTQ))
+ usleep_range(500, 600);
+
+ if (!count)
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static void xgbe_config_dma_bus(struct xgbe_prv_data *pdata)
+{
+ /* Set enhanced addressing mode */
+ XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, EAME, 1);
+
+ /* Set the System Bus mode */
+ XGMAC_IOWRITE_BITS(pdata, DMA_SBMR, UNDEF, 1);
+}
+
+static void xgbe_config_dma_cache(struct xgbe_prv_data *pdata)
+{
+ unsigned int arcache, awcache;
+
+ arcache = 0;
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, DMA_ARCACHE_SETTING);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, DRD, DMA_ARDOMAIN_SETTING);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, TEC, DMA_ARCACHE_SETTING);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, TED, DMA_ARDOMAIN_SETTING);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, THC, DMA_ARCACHE_SETTING);
+ XGMAC_SET_BITS(arcache, DMA_AXIARCR, THD, DMA_ARDOMAIN_SETTING);
+ XGMAC_IOWRITE(pdata, DMA_AXIARCR, arcache);
+
+ awcache = 0;
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, DMA_AWCACHE_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWD, DMA_AWDOMAIN_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, DMA_AWCACHE_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPD, DMA_AWDOMAIN_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, DMA_AWCACHE_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHD, DMA_AWDOMAIN_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDC, DMA_AWCACHE_SETTING);
+ XGMAC_SET_BITS(awcache, DMA_AXIAWCR, TDD, DMA_AWDOMAIN_SETTING);
+ XGMAC_IOWRITE(pdata, DMA_AXIAWCR, awcache);
+}
+
+static void xgbe_config_mtl_mode(struct xgbe_prv_data *pdata)
+{
+ unsigned int i;
+
+ /* Set Tx to weighted round robin scheduling algorithm (when
+ * traffic class is using ETS algorithm)
+ */
+ XGMAC_IOWRITE_BITS(pdata, MTL_OMR, ETSALG, MTL_ETSALG_WRR);
+
+ /* Set Tx traffic classes to strict priority algorithm */
+ for (i = 0; i < XGBE_TC_CNT; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_TC_ETSCR, TSA, MTL_TSA_SP);
+
+ /* Set Rx to strict priority algorithm */
+ XGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP);
+}
+
+static unsigned int xgbe_calculate_per_queue_fifo(unsigned long fifo_size,
+ unsigned char queue_count)
+{
+ unsigned int q_fifo_size = 0;
+ enum xgbe_mtl_fifo_size p_fifo = XGMAC_MTL_FIFO_SIZE_256;
+
+ /* Calculate Tx/Rx fifo share per queue */
+ switch (fifo_size) {
+ case 0:
+ q_fifo_size = FIFO_SIZE_B(128);
+ break;
+ case 1:
+ q_fifo_size = FIFO_SIZE_B(256);
+ break;
+ case 2:
+ q_fifo_size = FIFO_SIZE_B(512);
+ break;
+ case 3:
+ q_fifo_size = FIFO_SIZE_KB(1);
+ break;
+ case 4:
+ q_fifo_size = FIFO_SIZE_KB(2);
+ break;
+ case 5:
+ q_fifo_size = FIFO_SIZE_KB(4);
+ break;
+ case 6:
+ q_fifo_size = FIFO_SIZE_KB(8);
+ break;
+ case 7:
+ q_fifo_size = FIFO_SIZE_KB(16);
+ break;
+ case 8:
+ q_fifo_size = FIFO_SIZE_KB(32);
+ break;
+ case 9:
+ q_fifo_size = FIFO_SIZE_KB(64);
+ break;
+ case 10:
+ q_fifo_size = FIFO_SIZE_KB(128);
+ break;
+ case 11:
+ q_fifo_size = FIFO_SIZE_KB(256);
+ break;
+ }
+ q_fifo_size = q_fifo_size / queue_count;
+
+ /* Set the queue fifo size programmable value */
+ if (q_fifo_size >= FIFO_SIZE_KB(256))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_256K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(128))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_128K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(64))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_64K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(32))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_32K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(16))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_16K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(8))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_8K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(4))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_4K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(2))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_2K;
+ else if (q_fifo_size >= FIFO_SIZE_KB(1))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_1K;
+ else if (q_fifo_size >= FIFO_SIZE_B(512))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_512;
+ else if (q_fifo_size >= FIFO_SIZE_B(256))
+ p_fifo = XGMAC_MTL_FIFO_SIZE_256;
+
+ return p_fifo;
+}
+
+static void xgbe_config_tx_fifo_size(struct xgbe_prv_data *pdata)
+{
+ enum xgbe_mtl_fifo_size fifo_size;
+ unsigned int i;
+
+ fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.tx_fifo_size,
+ pdata->hw_feat.tx_q_cnt);
+
+ for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TQS, fifo_size);
+
+ netdev_notice(pdata->netdev, "%d Tx queues, %d byte fifo per queue\n",
+ pdata->hw_feat.tx_q_cnt, ((fifo_size + 1) * 256));
+}
+
+static void xgbe_config_rx_fifo_size(struct xgbe_prv_data *pdata)
+{
+ enum xgbe_mtl_fifo_size fifo_size;
+ unsigned int i;
+
+ fifo_size = xgbe_calculate_per_queue_fifo(pdata->hw_feat.rx_fifo_size,
+ pdata->hw_feat.rx_q_cnt);
+
+ for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RQS, fifo_size);
+
+ netdev_notice(pdata->netdev, "%d Rx queues, %d byte fifo per queue\n",
+ pdata->hw_feat.rx_q_cnt, ((fifo_size + 1) * 256));
+}
+
+static void xgbe_config_rx_queue_mapping(struct xgbe_prv_data *pdata)
+{
+ unsigned int i, reg, reg_val;
+ unsigned int q_count = pdata->hw_feat.rx_q_cnt;
+
+ /* Select dynamic mapping of MTL Rx queue to DMA Rx channel */
+ reg = MTL_RQDCM0R;
+ reg_val = 0;
+ for (i = 0; i < q_count;) {
+ reg_val |= (0x80 << ((i++ % MTL_RQDCM_Q_PER_REG) << 3));
+
+ if ((i % MTL_RQDCM_Q_PER_REG) && (i != q_count))
+ continue;
+
+ XGMAC_IOWRITE(pdata, reg, reg_val);
+
+ reg += MTL_RQDCM_INC;
+ reg_val = 0;
+ }
+}
+
+static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata)
+{
+ unsigned int i;
+
+ for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++) {
+ /* Activate flow control when less than 4k left in fifo */
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFA, 2);
+
+ /* De-activate flow control when more than 6k left in fifo */
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFD, 4);
+ }
+}
+
+static void xgbe_config_mac_address(struct xgbe_prv_data *pdata)
+{
+ xgbe_set_mac_address(pdata, pdata->netdev->dev_addr);
+}
+
+static void xgbe_config_jumbo_enable(struct xgbe_prv_data *pdata)
+{
+ unsigned int val;
+
+ val = (pdata->netdev->mtu > XGMAC_STD_PACKET_MTU) ? 1 : 0;
+
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val);
+}
+
+static void xgbe_config_checksum_offload(struct xgbe_prv_data *pdata)
+{
+ if (pdata->netdev->features & NETIF_F_RXCSUM)
+ xgbe_enable_rx_csum(pdata);
+ else
+ xgbe_disable_rx_csum(pdata);
+}
+
+static void xgbe_config_vlan_support(struct xgbe_prv_data *pdata)
+{
+ if (pdata->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
+ xgbe_enable_rx_vlan_stripping(pdata);
+ else
+ xgbe_disable_rx_vlan_stripping(pdata);
+}
+
+static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_mmc_stats *stats = &pdata->mmc_stats;
+ unsigned int mmc_isr = XGMAC_IOREAD(pdata, MMC_TISR);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_GB))
+ stats->txoctetcount_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_GB))
+ stats->txframecount_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_G))
+ stats->txbroadcastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_G))
+ stats->txmulticastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX64OCTETS_GB))
+ stats->tx64octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX65TO127OCTETS_GB))
+ stats->tx65to127octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX128TO255OCTETS_GB))
+ stats->tx128to255octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX256TO511OCTETS_GB))
+ stats->tx256to511octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX512TO1023OCTETS_GB))
+ stats->tx512to1023octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX1024TOMAXOCTETS_GB))
+ stats->tx1024tomaxoctets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNICASTFRAMES_GB))
+ stats->txunicastframes_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_GB))
+ stats->txmulticastframes_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_GB))
+ stats->txbroadcastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNDERFLOWERROR))
+ stats->txunderflowerror +=
+ XGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_G))
+ stats->txoctetcount_g +=
+ XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_G))
+ stats->txframecount_g +=
+ XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXPAUSEFRAMES))
+ stats->txpauseframes +=
+ XGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXVLANFRAMES_G))
+ stats->txvlanframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO);
+}
+
+static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_mmc_stats *stats = &pdata->mmc_stats;
+ unsigned int mmc_isr = XGMAC_IOREAD(pdata, MMC_RISR);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFRAMECOUNT_GB))
+ stats->rxframecount_gb +=
+ XGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_GB))
+ stats->rxoctetcount_gb +=
+ XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_G))
+ stats->rxoctetcount_g +=
+ XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXBROADCASTFRAMES_G))
+ stats->rxbroadcastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXMULTICASTFRAMES_G))
+ stats->rxmulticastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXCRCERROR))
+ stats->rxcrcerror +=
+ XGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXRUNTERROR))
+ stats->rxrunterror +=
+ XGMAC_IOREAD(pdata, MMC_RXRUNTERROR);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXJABBERERROR))
+ stats->rxjabbererror +=
+ XGMAC_IOREAD(pdata, MMC_RXJABBERERROR);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNDERSIZE_G))
+ stats->rxundersize_g +=
+ XGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOVERSIZE_G))
+ stats->rxoversize_g +=
+ XGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX64OCTETS_GB))
+ stats->rx64octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX65TO127OCTETS_GB))
+ stats->rx65to127octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX128TO255OCTETS_GB))
+ stats->rx128to255octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX256TO511OCTETS_GB))
+ stats->rx256to511octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX512TO1023OCTETS_GB))
+ stats->rx512to1023octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX1024TOMAXOCTETS_GB))
+ stats->rx1024tomaxoctets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNICASTFRAMES_G))
+ stats->rxunicastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXLENGTHERROR))
+ stats->rxlengtherror +=
+ XGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOUTOFRANGETYPE))
+ stats->rxoutofrangetype +=
+ XGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXPAUSEFRAMES))
+ stats->rxpauseframes +=
+ XGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFIFOOVERFLOW))
+ stats->rxfifooverflow +=
+ XGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXVLANFRAMES_GB))
+ stats->rxvlanframes_gb +=
+ XGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO);
+
+ if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXWATCHDOGERROR))
+ stats->rxwatchdogerror +=
+ XGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR);
+}
+
+static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_mmc_stats *stats = &pdata->mmc_stats;
+
+ /* Freeze counters */
+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1);
+
+ stats->txoctetcount_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO);
+
+ stats->txframecount_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO);
+
+ stats->txbroadcastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO);
+
+ stats->txmulticastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO);
+
+ stats->tx64octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO);
+
+ stats->tx65to127octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO);
+
+ stats->tx128to255octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO);
+
+ stats->tx256to511octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO);
+
+ stats->tx512to1023octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO);
+
+ stats->tx1024tomaxoctets_gb +=
+ XGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
+
+ stats->txunicastframes_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO);
+
+ stats->txmulticastframes_gb +=
+ XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
+
+ stats->txbroadcastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
+
+ stats->txunderflowerror +=
+ XGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO);
+
+ stats->txoctetcount_g +=
+ XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO);
+
+ stats->txframecount_g +=
+ XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO);
+
+ stats->txpauseframes +=
+ XGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO);
+
+ stats->txvlanframes_g +=
+ XGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO);
+
+ stats->rxframecount_gb +=
+ XGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO);
+
+ stats->rxoctetcount_gb +=
+ XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO);
+
+ stats->rxoctetcount_g +=
+ XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO);
+
+ stats->rxbroadcastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO);
+
+ stats->rxmulticastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO);
+
+ stats->rxcrcerror +=
+ XGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO);
+
+ stats->rxrunterror +=
+ XGMAC_IOREAD(pdata, MMC_RXRUNTERROR);
+
+ stats->rxjabbererror +=
+ XGMAC_IOREAD(pdata, MMC_RXJABBERERROR);
+
+ stats->rxundersize_g +=
+ XGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G);
+
+ stats->rxoversize_g +=
+ XGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G);
+
+ stats->rx64octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO);
+
+ stats->rx65to127octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO);
+
+ stats->rx128to255octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO);
+
+ stats->rx256to511octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO);
+
+ stats->rx512to1023octets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO);
+
+ stats->rx1024tomaxoctets_gb +=
+ XGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
+
+ stats->rxunicastframes_g +=
+ XGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO);
+
+ stats->rxlengtherror +=
+ XGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO);
+
+ stats->rxoutofrangetype +=
+ XGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO);
+
+ stats->rxpauseframes +=
+ XGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO);
+
+ stats->rxfifooverflow +=
+ XGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO);
+
+ stats->rxvlanframes_gb +=
+ XGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO);
+
+ stats->rxwatchdogerror +=
+ XGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR);
+
+ /* Un-freeze counters */
+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0);
+}
+
+static void xgbe_config_mmc(struct xgbe_prv_data *pdata)
+{
+ /* Set counters to reset on read */
+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, ROR, 1);
+
+ /* Reset the counters */
+ XGMAC_IOWRITE_BITS(pdata, MMC_CR, CR, 1);
+}
+
+static void xgbe_enable_tx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ /* Enable each Tx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1);
+ }
+
+ /* Enable each Tx queue */
+ for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN,
+ MTL_Q_ENABLED);
+
+ /* Enable MAC Tx */
+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 1);
+}
+
+static void xgbe_disable_tx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ /* Disable MAC Tx */
+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
+
+ /* Disable each Tx queue */
+ for (i = 0; i < pdata->hw_feat.tx_q_cnt; i++)
+ XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, TXQEN, 0);
+
+ /* Disable each Tx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0);
+ }
+}
+
+static void xgbe_enable_rx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int reg_val, i;
+
+ /* Enable each Rx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1);
+ }
+
+ /* Enable each Rx queue */
+ reg_val = 0;
+ for (i = 0; i < pdata->hw_feat.rx_q_cnt; i++)
+ reg_val |= (0x02 << (i << 1));
+ XGMAC_IOWRITE(pdata, MAC_RQC0R, reg_val);
+
+ /* Enable MAC Rx */
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 1);
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 1);
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 1);
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 1);
+}
+
+static void xgbe_disable_rx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ /* Disable MAC Rx */
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 0);
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 0);
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0);
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0);
+
+ /* Disable each Rx queue */
+ XGMAC_IOWRITE(pdata, MAC_RQC0R, 0);
+
+ /* Disable each Rx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0);
+ }
+}
+
+static void xgbe_powerup_tx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ /* Enable each Tx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 1);
+ }
+
+ /* Enable MAC Tx */
+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 1);
+}
+
+static void xgbe_powerdown_tx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ /* Disable MAC Tx */
+ XGMAC_IOWRITE_BITS(pdata, MAC_TCR, TE, 0);
+
+ /* Disable each Tx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_TCR, ST, 0);
+ }
+}
+
+static void xgbe_powerup_rx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ /* Enable each Rx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 1);
+ }
+}
+
+static void xgbe_powerdown_rx(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ /* Disable each Rx DMA channel */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->rx_ring)
+ break;
+
+ XGMAC_DMA_IOWRITE_BITS(channel, DMA_CH_RCR, SR, 0);
+ }
+}
+
+static int xgbe_init(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ int ret;
+
+ DBGPR("-->xgbe_init\n");
+
+ /* Flush Tx queues */
+ ret = xgbe_flush_tx_queues(pdata);
+ if (ret)
+ return ret;
+
+ /*
+ * Initialize DMA related features
+ */
+ xgbe_config_dma_bus(pdata);
+ xgbe_config_dma_cache(pdata);
+ xgbe_config_osp_mode(pdata);
+ xgbe_config_pblx8(pdata);
+ xgbe_config_tx_pbl_val(pdata);
+ xgbe_config_rx_pbl_val(pdata);
+ xgbe_config_rx_coalesce(pdata);
+ xgbe_config_tx_coalesce(pdata);
+ xgbe_config_rx_buffer_size(pdata);
+ xgbe_config_tso_mode(pdata);
+ desc_if->wrapper_tx_desc_init(pdata);
+ desc_if->wrapper_rx_desc_init(pdata);
+ xgbe_enable_dma_interrupts(pdata);
+
+ /*
+ * Initialize MTL related features
+ */
+ xgbe_config_mtl_mode(pdata);
+ xgbe_config_rx_queue_mapping(pdata);
+ /*TODO: Program the priorities mapped to the Selected Traffic Classes
+ in MTL_TC_Prty_Map0-3 registers */
+ xgbe_config_tsf_mode(pdata, pdata->tx_sf_mode);
+ xgbe_config_rsf_mode(pdata, pdata->rx_sf_mode);
+ xgbe_config_tx_threshold(pdata, pdata->tx_threshold);
+ xgbe_config_rx_threshold(pdata, pdata->rx_threshold);
+ xgbe_config_tx_fifo_size(pdata);
+ xgbe_config_rx_fifo_size(pdata);
+ xgbe_config_flow_control_threshold(pdata);
+ /*TODO: Queue to Traffic Class Mapping (Q2TCMAP) */
+ /*TODO: Error Packet and undersized good Packet forwarding enable
+ (FEP and FUP)
+ */
+ xgbe_enable_mtl_interrupts(pdata);
+
+ /* Transmit Class Weight */
+ XGMAC_IOWRITE_BITS(pdata, MTL_Q_TCQWR, QW, 0x10);
+
+ /*
+ * Initialize MAC related features
+ */
+ xgbe_config_mac_address(pdata);
+ xgbe_config_jumbo_enable(pdata);
+ xgbe_config_flow_control(pdata);
+ xgbe_config_checksum_offload(pdata);
+ xgbe_config_vlan_support(pdata);
+ xgbe_config_mmc(pdata);
+ xgbe_enable_mac_interrupts(pdata);
+
+ DBGPR("<--xgbe_init\n");
+
+ return 0;
+}
+
+void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *hw_if)
+{
+ DBGPR("-->xgbe_init_function_ptrs\n");
+
+ hw_if->tx_complete = xgbe_tx_complete;
+
+ hw_if->set_promiscuous_mode = xgbe_set_promiscuous_mode;
+ hw_if->set_all_multicast_mode = xgbe_set_all_multicast_mode;
+ hw_if->set_addn_mac_addrs = xgbe_set_addn_mac_addrs;
+ hw_if->set_mac_address = xgbe_set_mac_address;
+
+ hw_if->enable_rx_csum = xgbe_enable_rx_csum;
+ hw_if->disable_rx_csum = xgbe_disable_rx_csum;
+
+ hw_if->enable_rx_vlan_stripping = xgbe_enable_rx_vlan_stripping;
+ hw_if->disable_rx_vlan_stripping = xgbe_disable_rx_vlan_stripping;
+
+ hw_if->read_mmd_regs = xgbe_read_mmd_regs;
+ hw_if->write_mmd_regs = xgbe_write_mmd_regs;
+
+ hw_if->set_gmii_speed = xgbe_set_gmii_speed;
+ hw_if->set_gmii_2500_speed = xgbe_set_gmii_2500_speed;
+ hw_if->set_xgmii_speed = xgbe_set_xgmii_speed;
+
+ hw_if->enable_tx = xgbe_enable_tx;
+ hw_if->disable_tx = xgbe_disable_tx;
+ hw_if->enable_rx = xgbe_enable_rx;
+ hw_if->disable_rx = xgbe_disable_rx;
+
+ hw_if->powerup_tx = xgbe_powerup_tx;
+ hw_if->powerdown_tx = xgbe_powerdown_tx;
+ hw_if->powerup_rx = xgbe_powerup_rx;
+ hw_if->powerdown_rx = xgbe_powerdown_rx;
+
+ hw_if->pre_xmit = xgbe_pre_xmit;
+ hw_if->dev_read = xgbe_dev_read;
+ hw_if->enable_int = xgbe_enable_int;
+ hw_if->disable_int = xgbe_disable_int;
+ hw_if->init = xgbe_init;
+ hw_if->exit = xgbe_exit;
+
+ /* Descriptor related Sequences have to be initialized here */
+ hw_if->tx_desc_init = xgbe_tx_desc_init;
+ hw_if->rx_desc_init = xgbe_rx_desc_init;
+ hw_if->tx_desc_reset = xgbe_tx_desc_reset;
+ hw_if->rx_desc_reset = xgbe_rx_desc_reset;
+ hw_if->is_last_desc = xgbe_is_last_desc;
+ hw_if->is_context_desc = xgbe_is_context_desc;
+
+ /* For FLOW ctrl */
+ hw_if->config_tx_flow_control = xgbe_config_tx_flow_control;
+ hw_if->config_rx_flow_control = xgbe_config_rx_flow_control;
+
+ /* For RX coalescing */
+ hw_if->config_rx_coalesce = xgbe_config_rx_coalesce;
+ hw_if->config_tx_coalesce = xgbe_config_tx_coalesce;
+ hw_if->usec_to_riwt = xgbe_usec_to_riwt;
+ hw_if->riwt_to_usec = xgbe_riwt_to_usec;
+
+ /* For RX and TX threshold config */
+ hw_if->config_rx_threshold = xgbe_config_rx_threshold;
+ hw_if->config_tx_threshold = xgbe_config_tx_threshold;
+
+ /* For RX and TX Store and Forward Mode config */
+ hw_if->config_rsf_mode = xgbe_config_rsf_mode;
+ hw_if->config_tsf_mode = xgbe_config_tsf_mode;
+
+ /* For TX DMA Operating on Second Frame config */
+ hw_if->config_osp_mode = xgbe_config_osp_mode;
+
+ /* For RX and TX PBL config */
+ hw_if->config_rx_pbl_val = xgbe_config_rx_pbl_val;
+ hw_if->get_rx_pbl_val = xgbe_get_rx_pbl_val;
+ hw_if->config_tx_pbl_val = xgbe_config_tx_pbl_val;
+ hw_if->get_tx_pbl_val = xgbe_get_tx_pbl_val;
+ hw_if->config_pblx8 = xgbe_config_pblx8;
+
+ /* For MMC statistics support */
+ hw_if->tx_mmc_int = xgbe_tx_mmc_int;
+ hw_if->rx_mmc_int = xgbe_rx_mmc_int;
+ hw_if->read_mmc_stats = xgbe_read_mmc_stats;
+
+ DBGPR("<--xgbe_init_function_ptrs\n");
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
new file mode 100644
index 00000000000..cfe3d93b5f5
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -0,0 +1,1351 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/tcp.h>
+#include <linux/if_vlan.h>
+#include <linux/phy.h>
+#include <net/busy_poll.h>
+#include <linux/clk.h>
+#include <linux/if_ether.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+static int xgbe_poll(struct napi_struct *, int);
+static void xgbe_set_rx_mode(struct net_device *);
+
+static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring)
+{
+ return (ring->rdesc_count - (ring->cur - ring->dirty));
+}
+
+static int xgbe_calc_rx_buf_size(struct net_device *netdev, unsigned int mtu)
+{
+ unsigned int rx_buf_size;
+
+ if (mtu > XGMAC_JUMBO_PACKET_MTU) {
+ netdev_alert(netdev, "MTU exceeds maximum supported value\n");
+ return -EINVAL;
+ }
+
+ rx_buf_size = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+ if (rx_buf_size < RX_MIN_BUF_SIZE)
+ rx_buf_size = RX_MIN_BUF_SIZE;
+ rx_buf_size = (rx_buf_size + RX_BUF_ALIGN - 1) & ~(RX_BUF_ALIGN - 1);
+
+ return rx_buf_size;
+}
+
+static void xgbe_enable_rx_tx_ints(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (channel->tx_ring)
+ hw_if->enable_int(channel,
+ XGMAC_INT_DMA_CH_SR_TI);
+ if (channel->rx_ring)
+ hw_if->enable_int(channel,
+ XGMAC_INT_DMA_CH_SR_RI);
+ }
+}
+
+static void xgbe_disable_rx_tx_ints(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (channel->tx_ring)
+ hw_if->disable_int(channel,
+ XGMAC_INT_DMA_CH_SR_TI);
+ if (channel->rx_ring)
+ hw_if->disable_int(channel,
+ XGMAC_INT_DMA_CH_SR_RI);
+ }
+}
+
+static irqreturn_t xgbe_isr(int irq, void *data)
+{
+ struct xgbe_prv_data *pdata = data;
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_channel *channel;
+ unsigned int dma_isr, dma_ch_isr;
+ unsigned int mac_isr;
+ unsigned int i;
+
+ /* The DMA interrupt status register also reports MAC and MTL
+ * interrupts. So for polling mode, we just need to check for
+ * this register to be non-zero
+ */
+ dma_isr = XGMAC_IOREAD(pdata, DMA_ISR);
+ if (!dma_isr)
+ goto isr_done;
+
+ DBGPR("-->xgbe_isr\n");
+
+ DBGPR(" DMA_ISR = %08x\n", dma_isr);
+ DBGPR(" DMA_DS0 = %08x\n", XGMAC_IOREAD(pdata, DMA_DSR0));
+ DBGPR(" DMA_DS1 = %08x\n", XGMAC_IOREAD(pdata, DMA_DSR1));
+
+ for (i = 0; i < pdata->channel_count; i++) {
+ if (!(dma_isr & (1 << i)))
+ continue;
+
+ channel = pdata->channel + i;
+
+ dma_ch_isr = XGMAC_DMA_IOREAD(channel, DMA_CH_SR);
+ DBGPR(" DMA_CH%u_ISR = %08x\n", i, dma_ch_isr);
+
+ if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, TI) ||
+ XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, RI)) {
+ if (napi_schedule_prep(&pdata->napi)) {
+ /* Disable Tx and Rx interrupts */
+ xgbe_disable_rx_tx_ints(pdata);
+
+ /* Turn on polling */
+ __napi_schedule(&pdata->napi);
+ }
+ }
+
+ /* Restart the device on a Fatal Bus Error */
+ if (XGMAC_GET_BITS(dma_ch_isr, DMA_CH_SR, FBE))
+ schedule_work(&pdata->restart_work);
+
+ /* Clear all interrupt signals */
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_SR, dma_ch_isr);
+ }
+
+ if (XGMAC_GET_BITS(dma_isr, DMA_ISR, MACIS)) {
+ mac_isr = XGMAC_IOREAD(pdata, MAC_ISR);
+
+ if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCTXIS))
+ hw_if->tx_mmc_int(pdata);
+
+ if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCRXIS))
+ hw_if->rx_mmc_int(pdata);
+ }
+
+ DBGPR(" DMA_ISR = %08x\n", XGMAC_IOREAD(pdata, DMA_ISR));
+
+ DBGPR("<--xgbe_isr\n");
+
+isr_done:
+ return IRQ_HANDLED;
+}
+
+static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
+{
+ struct xgbe_channel *channel = container_of(timer,
+ struct xgbe_channel,
+ tx_timer);
+ struct xgbe_ring *ring = channel->tx_ring;
+ struct xgbe_prv_data *pdata = channel->pdata;
+ unsigned long flags;
+
+ DBGPR("-->xgbe_tx_timer\n");
+
+ spin_lock_irqsave(&ring->lock, flags);
+
+ if (napi_schedule_prep(&pdata->napi)) {
+ /* Disable Tx and Rx interrupts */
+ xgbe_disable_rx_tx_ints(pdata);
+
+ /* Turn on polling */
+ __napi_schedule(&pdata->napi);
+ }
+
+ channel->tx_timer_active = 0;
+
+ spin_unlock_irqrestore(&ring->lock, flags);
+
+ DBGPR("<--xgbe_tx_timer\n");
+
+ return HRTIMER_NORESTART;
+}
+
+static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ DBGPR("-->xgbe_init_tx_timers\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ DBGPR(" %s adding tx timer\n", channel->name);
+ hrtimer_init(&channel->tx_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ channel->tx_timer.function = xgbe_tx_timer;
+ }
+
+ DBGPR("<--xgbe_init_tx_timers\n");
+}
+
+static void xgbe_stop_tx_timers(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel;
+ unsigned int i;
+
+ DBGPR("-->xgbe_stop_tx_timers\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ if (!channel->tx_ring)
+ break;
+
+ DBGPR(" %s deleting tx timer\n", channel->name);
+ channel->tx_timer_active = 0;
+ hrtimer_cancel(&channel->tx_timer);
+ }
+
+ DBGPR("<--xgbe_stop_tx_timers\n");
+}
+
+void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
+{
+ unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
+ struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
+
+ DBGPR("-->xgbe_get_all_hw_features\n");
+
+ mac_hfr0 = XGMAC_IOREAD(pdata, MAC_HWF0R);
+ mac_hfr1 = XGMAC_IOREAD(pdata, MAC_HWF1R);
+ mac_hfr2 = XGMAC_IOREAD(pdata, MAC_HWF2R);
+
+ memset(hw_feat, 0, sizeof(*hw_feat));
+
+ /* Hardware feature register 0 */
+ hw_feat->gmii = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL);
+ hw_feat->vlhash = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH);
+ hw_feat->sma = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL);
+ hw_feat->rwk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL);
+ hw_feat->mgk = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL);
+ hw_feat->mmc = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL);
+ hw_feat->aoe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL);
+ hw_feat->ts = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL);
+ hw_feat->eee = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL);
+ hw_feat->tx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL);
+ hw_feat->rx_coe = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL);
+ hw_feat->addn_mac = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R,
+ ADDMACADRSEL);
+ hw_feat->ts_src = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL);
+ hw_feat->sa_vlan_ins = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS);
+
+ /* Hardware feature register 1 */
+ hw_feat->rx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
+ RXFIFOSIZE);
+ hw_feat->tx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
+ TXFIFOSIZE);
+ hw_feat->dcb = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
+ hw_feat->sph = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
+ hw_feat->tso = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
+ hw_feat->dma_debug = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA);
+ hw_feat->hash_table_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
+ HASHTBLSZ);
+ hw_feat->l3l4_filter_num = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
+ L3L4FNUM);
+
+ /* Hardware feature register 2 */
+ hw_feat->rx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT);
+ hw_feat->tx_q_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT);
+ hw_feat->rx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT);
+ hw_feat->tx_ch_cnt = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT);
+ hw_feat->pps_out_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
+ hw_feat->aux_snap_num = XGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, AUXSNAPNUM);
+
+ /* The Queue and Channel counts are zero based so increment them
+ * to get the actual number
+ */
+ hw_feat->rx_q_cnt++;
+ hw_feat->tx_q_cnt++;
+ hw_feat->rx_ch_cnt++;
+ hw_feat->tx_ch_cnt++;
+
+ DBGPR("<--xgbe_get_all_hw_features\n");
+}
+
+static void xgbe_napi_enable(struct xgbe_prv_data *pdata, unsigned int add)
+{
+ if (add)
+ netif_napi_add(pdata->netdev, &pdata->napi, xgbe_poll,
+ NAPI_POLL_WEIGHT);
+ napi_enable(&pdata->napi);
+}
+
+static void xgbe_napi_disable(struct xgbe_prv_data *pdata)
+{
+ napi_disable(&pdata->napi);
+}
+
+void xgbe_init_tx_coalesce(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+
+ DBGPR("-->xgbe_init_tx_coalesce\n");
+
+ pdata->tx_usecs = XGMAC_INIT_DMA_TX_USECS;
+ pdata->tx_frames = XGMAC_INIT_DMA_TX_FRAMES;
+
+ hw_if->config_tx_coalesce(pdata);
+
+ DBGPR("<--xgbe_init_tx_coalesce\n");
+}
+
+void xgbe_init_rx_coalesce(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+
+ DBGPR("-->xgbe_init_rx_coalesce\n");
+
+ pdata->rx_riwt = hw_if->usec_to_riwt(pdata, XGMAC_INIT_DMA_RX_USECS);
+ pdata->rx_frames = XGMAC_INIT_DMA_RX_FRAMES;
+
+ hw_if->config_rx_coalesce(pdata);
+
+ DBGPR("<--xgbe_init_rx_coalesce\n");
+}
+
+static void xgbe_free_tx_skbuff(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ struct xgbe_channel *channel;
+ struct xgbe_ring *ring;
+ struct xgbe_ring_data *rdata;
+ unsigned int i, j;
+
+ DBGPR("-->xgbe_free_tx_skbuff\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ ring = channel->tx_ring;
+ if (!ring)
+ break;
+
+ for (j = 0; j < ring->rdesc_count; j++) {
+ rdata = GET_DESC_DATA(ring, j);
+ desc_if->unmap_skb(pdata, rdata);
+ }
+ }
+
+ DBGPR("<--xgbe_free_tx_skbuff\n");
+}
+
+static void xgbe_free_rx_skbuff(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ struct xgbe_channel *channel;
+ struct xgbe_ring *ring;
+ struct xgbe_ring_data *rdata;
+ unsigned int i, j;
+
+ DBGPR("-->xgbe_free_rx_skbuff\n");
+
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++) {
+ ring = channel->rx_ring;
+ if (!ring)
+ break;
+
+ for (j = 0; j < ring->rdesc_count; j++) {
+ rdata = GET_DESC_DATA(ring, j);
+ desc_if->unmap_skb(pdata, rdata);
+ }
+ }
+
+ DBGPR("<--xgbe_free_rx_skbuff\n");
+}
+
+int xgbe_powerdown(struct net_device *netdev, unsigned int caller)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ unsigned long flags;
+
+ DBGPR("-->xgbe_powerdown\n");
+
+ if (!netif_running(netdev) ||
+ (caller == XGMAC_IOCTL_CONTEXT && pdata->power_down)) {
+ netdev_alert(netdev, "Device is already powered down\n");
+ DBGPR("<--xgbe_powerdown\n");
+ return -EINVAL;
+ }
+
+ phy_stop(pdata->phydev);
+
+ spin_lock_irqsave(&pdata->lock, flags);
+
+ if (caller == XGMAC_DRIVER_CONTEXT)
+ netif_device_detach(netdev);
+
+ netif_tx_stop_all_queues(netdev);
+ xgbe_napi_disable(pdata);
+
+ /* Powerdown Tx/Rx */
+ hw_if->powerdown_tx(pdata);
+ hw_if->powerdown_rx(pdata);
+
+ pdata->power_down = 1;
+
+ spin_unlock_irqrestore(&pdata->lock, flags);
+
+ DBGPR("<--xgbe_powerdown\n");
+
+ return 0;
+}
+
+int xgbe_powerup(struct net_device *netdev, unsigned int caller)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ unsigned long flags;
+
+ DBGPR("-->xgbe_powerup\n");
+
+ if (!netif_running(netdev) ||
+ (caller == XGMAC_IOCTL_CONTEXT && !pdata->power_down)) {
+ netdev_alert(netdev, "Device is already powered up\n");
+ DBGPR("<--xgbe_powerup\n");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pdata->lock, flags);
+
+ pdata->power_down = 0;
+
+ phy_start(pdata->phydev);
+
+ /* Enable Tx/Rx */
+ hw_if->powerup_tx(pdata);
+ hw_if->powerup_rx(pdata);
+
+ if (caller == XGMAC_DRIVER_CONTEXT)
+ netif_device_attach(netdev);
+
+ xgbe_napi_enable(pdata, 0);
+ netif_tx_start_all_queues(netdev);
+
+ spin_unlock_irqrestore(&pdata->lock, flags);
+
+ DBGPR("<--xgbe_powerup\n");
+
+ return 0;
+}
+
+static int xgbe_start(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct net_device *netdev = pdata->netdev;
+
+ DBGPR("-->xgbe_start\n");
+
+ xgbe_set_rx_mode(netdev);
+
+ hw_if->init(pdata);
+
+ phy_start(pdata->phydev);
+
+ hw_if->enable_tx(pdata);
+ hw_if->enable_rx(pdata);
+
+ xgbe_init_tx_timers(pdata);
+
+ xgbe_napi_enable(pdata, 1);
+ netif_tx_start_all_queues(netdev);
+
+ DBGPR("<--xgbe_start\n");
+
+ return 0;
+}
+
+static void xgbe_stop(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct net_device *netdev = pdata->netdev;
+
+ DBGPR("-->xgbe_stop\n");
+
+ phy_stop(pdata->phydev);
+
+ netif_tx_stop_all_queues(netdev);
+ xgbe_napi_disable(pdata);
+
+ xgbe_stop_tx_timers(pdata);
+
+ hw_if->disable_tx(pdata);
+ hw_if->disable_rx(pdata);
+
+ DBGPR("<--xgbe_stop\n");
+}
+
+static void xgbe_restart_dev(struct xgbe_prv_data *pdata, unsigned int reset)
+{
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+
+ DBGPR("-->xgbe_restart_dev\n");
+
+ /* If not running, "restart" will happen on open */
+ if (!netif_running(pdata->netdev))
+ return;
+
+ xgbe_stop(pdata);
+ synchronize_irq(pdata->irq_number);
+
+ xgbe_free_tx_skbuff(pdata);
+ xgbe_free_rx_skbuff(pdata);
+
+ /* Issue software reset to device if requested */
+ if (reset)
+ hw_if->exit(pdata);
+
+ xgbe_start(pdata);
+
+ DBGPR("<--xgbe_restart_dev\n");
+}
+
+static void xgbe_restart(struct work_struct *work)
+{
+ struct xgbe_prv_data *pdata = container_of(work,
+ struct xgbe_prv_data,
+ restart_work);
+
+ rtnl_lock();
+
+ xgbe_restart_dev(pdata, 1);
+
+ rtnl_unlock();
+}
+
+static void xgbe_prep_vlan(struct sk_buff *skb, struct xgbe_packet_data *packet)
+{
+ if (vlan_tx_tag_present(skb))
+ packet->vlan_ctag = vlan_tx_tag_get(skb);
+}
+
+static int xgbe_prep_tso(struct sk_buff *skb, struct xgbe_packet_data *packet)
+{
+ int ret;
+
+ if (!XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ TSO_ENABLE))
+ return 0;
+
+ ret = skb_cow_head(skb, 0);
+ if (ret)
+ return ret;
+
+ packet->header_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ packet->tcp_header_len = tcp_hdrlen(skb);
+ packet->tcp_payload_len = skb->len - packet->header_len;
+ packet->mss = skb_shinfo(skb)->gso_size;
+ DBGPR(" packet->header_len=%u\n", packet->header_len);
+ DBGPR(" packet->tcp_header_len=%u, packet->tcp_payload_len=%u\n",
+ packet->tcp_header_len, packet->tcp_payload_len);
+ DBGPR(" packet->mss=%u\n", packet->mss);
+
+ return 0;
+}
+
+static int xgbe_is_tso(struct sk_buff *skb)
+{
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return 0;
+
+ if (!skb_is_gso(skb))
+ return 0;
+
+ DBGPR(" TSO packet to be processed\n");
+
+ return 1;
+}
+
+static void xgbe_packet_info(struct xgbe_ring *ring, struct sk_buff *skb,
+ struct xgbe_packet_data *packet)
+{
+ struct skb_frag_struct *frag;
+ unsigned int context_desc;
+ unsigned int len;
+ unsigned int i;
+
+ context_desc = 0;
+ packet->rdesc_count = 0;
+
+ if (xgbe_is_tso(skb)) {
+ /* TSO requires an extra desriptor if mss is different */
+ if (skb_shinfo(skb)->gso_size != ring->tx.cur_mss) {
+ context_desc = 1;
+ packet->rdesc_count++;
+ }
+
+ /* TSO requires an extra desriptor for TSO header */
+ packet->rdesc_count++;
+
+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ TSO_ENABLE, 1);
+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ CSUM_ENABLE, 1);
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL)
+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ CSUM_ENABLE, 1);
+
+ if (vlan_tx_tag_present(skb)) {
+ /* VLAN requires an extra descriptor if tag is different */
+ if (vlan_tx_tag_get(skb) != ring->tx.cur_vlan_ctag)
+ /* We can share with the TSO context descriptor */
+ if (!context_desc) {
+ context_desc = 1;
+ packet->rdesc_count++;
+ }
+
+ XGMAC_SET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES,
+ VLAN_CTAG, 1);
+ }
+
+ for (len = skb_headlen(skb); len;) {
+ packet->rdesc_count++;
+ len -= min_t(unsigned int, len, TX_MAX_BUF_SIZE);
+ }
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ frag = &skb_shinfo(skb)->frags[i];
+ for (len = skb_frag_size(frag); len; ) {
+ packet->rdesc_count++;
+ len -= min_t(unsigned int, len, TX_MAX_BUF_SIZE);
+ }
+ }
+}
+
+static int xgbe_open(struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ int ret;
+
+ DBGPR("-->xgbe_open\n");
+
+ /* Enable the clock */
+ ret = clk_prepare_enable(pdata->sysclock);
+ if (ret) {
+ netdev_alert(netdev, "clk_prepare_enable failed\n");
+ return ret;
+ }
+
+ /* Calculate the Rx buffer size before allocating rings */
+ ret = xgbe_calc_rx_buf_size(netdev, netdev->mtu);
+ if (ret < 0)
+ goto err_clk;
+ pdata->rx_buf_size = ret;
+
+ /* Allocate the ring descriptors and buffers */
+ ret = desc_if->alloc_ring_resources(pdata);
+ if (ret)
+ goto err_clk;
+
+ /* Initialize the device restart work struct */
+ INIT_WORK(&pdata->restart_work, xgbe_restart);
+
+ /* Request interrupts */
+ ret = devm_request_irq(pdata->dev, netdev->irq, xgbe_isr, 0,
+ netdev->name, pdata);
+ if (ret) {
+ netdev_alert(netdev, "error requesting irq %d\n",
+ pdata->irq_number);
+ goto err_irq;
+ }
+ pdata->irq_number = netdev->irq;
+
+ ret = xgbe_start(pdata);
+ if (ret)
+ goto err_start;
+
+ DBGPR("<--xgbe_open\n");
+
+ return 0;
+
+err_start:
+ hw_if->exit(pdata);
+
+ devm_free_irq(pdata->dev, pdata->irq_number, pdata);
+ pdata->irq_number = 0;
+
+err_irq:
+ desc_if->free_ring_resources(pdata);
+
+err_clk:
+ clk_disable_unprepare(pdata->sysclock);
+
+ return ret;
+}
+
+static int xgbe_close(struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+
+ DBGPR("-->xgbe_close\n");
+
+ /* Stop the device */
+ xgbe_stop(pdata);
+
+ /* Issue software reset to device */
+ hw_if->exit(pdata);
+
+ /* Free all the ring data */
+ desc_if->free_ring_resources(pdata);
+
+ /* Release the interrupt */
+ if (pdata->irq_number != 0) {
+ devm_free_irq(pdata->dev, pdata->irq_number, pdata);
+ pdata->irq_number = 0;
+ }
+
+ /* Disable the clock */
+ clk_disable_unprepare(pdata->sysclock);
+
+ DBGPR("<--xgbe_close\n");
+
+ return 0;
+}
+
+static int xgbe_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ struct xgbe_channel *channel;
+ struct xgbe_ring *ring;
+ struct xgbe_packet_data *packet;
+ unsigned long flags;
+ int ret;
+
+ DBGPR("-->xgbe_xmit: skb->len = %d\n", skb->len);
+
+ channel = pdata->channel + skb->queue_mapping;
+ ring = channel->tx_ring;
+ packet = &ring->packet_data;
+
+ ret = NETDEV_TX_OK;
+
+ spin_lock_irqsave(&ring->lock, flags);
+
+ if (skb->len == 0) {
+ netdev_err(netdev, "empty skb received from stack\n");
+ dev_kfree_skb_any(skb);
+ goto tx_netdev_return;
+ }
+
+ /* Calculate preliminary packet info */
+ memset(packet, 0, sizeof(*packet));
+ xgbe_packet_info(ring, skb, packet);
+
+ /* Check that there are enough descriptors available */
+ if (packet->rdesc_count > xgbe_tx_avail_desc(ring)) {
+ DBGPR(" Tx queue stopped, not enough descriptors available\n");
+ netif_stop_subqueue(netdev, channel->queue_index);
+ ring->tx.queue_stopped = 1;
+ ret = NETDEV_TX_BUSY;
+ goto tx_netdev_return;
+ }
+
+ ret = xgbe_prep_tso(skb, packet);
+ if (ret) {
+ netdev_err(netdev, "error processing TSO packet\n");
+ dev_kfree_skb_any(skb);
+ goto tx_netdev_return;
+ }
+ xgbe_prep_vlan(skb, packet);
+
+ if (!desc_if->map_tx_skb(channel, skb)) {
+ dev_kfree_skb_any(skb);
+ goto tx_netdev_return;
+ }
+
+ /* Configure required descriptor fields for transmission */
+ hw_if->pre_xmit(channel);
+
+#ifdef XGMAC_ENABLE_TX_PKT_DUMP
+ xgbe_print_pkt(netdev, skb, true);
+#endif
+
+tx_netdev_return:
+ spin_unlock_irqrestore(&ring->lock, flags);
+
+ DBGPR("<--xgbe_xmit\n");
+
+ return ret;
+}
+
+static void xgbe_set_rx_mode(struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ unsigned int pr_mode, am_mode;
+
+ DBGPR("-->xgbe_set_rx_mode\n");
+
+ pr_mode = ((netdev->flags & IFF_PROMISC) != 0);
+ am_mode = ((netdev->flags & IFF_ALLMULTI) != 0);
+
+ if (netdev_uc_count(netdev) > pdata->hw_feat.addn_mac)
+ pr_mode = 1;
+ if (netdev_mc_count(netdev) > pdata->hw_feat.addn_mac)
+ am_mode = 1;
+ if ((netdev_uc_count(netdev) + netdev_mc_count(netdev)) >
+ pdata->hw_feat.addn_mac)
+ pr_mode = 1;
+
+ hw_if->set_promiscuous_mode(pdata, pr_mode);
+ hw_if->set_all_multicast_mode(pdata, am_mode);
+ if (!pr_mode)
+ hw_if->set_addn_mac_addrs(pdata, am_mode);
+
+ DBGPR("<--xgbe_set_rx_mode\n");
+}
+
+static int xgbe_set_mac_address(struct net_device *netdev, void *addr)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct sockaddr *saddr = addr;
+
+ DBGPR("-->xgbe_set_mac_address\n");
+
+ if (!is_valid_ether_addr(saddr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(netdev->dev_addr, saddr->sa_data, netdev->addr_len);
+
+ hw_if->set_mac_address(pdata, netdev->dev_addr);
+
+ DBGPR("<--xgbe_set_mac_address\n");
+
+ return 0;
+}
+
+static int xgbe_change_mtu(struct net_device *netdev, int mtu)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ int ret;
+
+ DBGPR("-->xgbe_change_mtu\n");
+
+ ret = xgbe_calc_rx_buf_size(netdev, mtu);
+ if (ret < 0)
+ return ret;
+
+ pdata->rx_buf_size = ret;
+ netdev->mtu = mtu;
+
+ xgbe_restart_dev(pdata, 0);
+
+ DBGPR("<--xgbe_change_mtu\n");
+
+ return 0;
+}
+
+static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev,
+ struct rtnl_link_stats64 *s)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_mmc_stats *pstats = &pdata->mmc_stats;
+
+ DBGPR("-->%s\n", __func__);
+
+ pdata->hw_if.read_mmc_stats(pdata);
+
+ s->rx_packets = pstats->rxframecount_gb;
+ s->rx_bytes = pstats->rxoctetcount_gb;
+ s->rx_errors = pstats->rxframecount_gb -
+ pstats->rxbroadcastframes_g -
+ pstats->rxmulticastframes_g -
+ pstats->rxunicastframes_g;
+ s->multicast = pstats->rxmulticastframes_g;
+ s->rx_length_errors = pstats->rxlengtherror;
+ s->rx_crc_errors = pstats->rxcrcerror;
+ s->rx_fifo_errors = pstats->rxfifooverflow;
+
+ s->tx_packets = pstats->txframecount_gb;
+ s->tx_bytes = pstats->txoctetcount_gb;
+ s->tx_errors = pstats->txframecount_gb - pstats->txframecount_g;
+ s->tx_dropped = netdev->stats.tx_dropped;
+
+ DBGPR("<--%s\n", __func__);
+
+ return s;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void xgbe_poll_controller(struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ DBGPR("-->xgbe_poll_controller\n");
+
+ disable_irq(pdata->irq_number);
+
+ xgbe_isr(pdata->irq_number, pdata);
+
+ enable_irq(pdata->irq_number);
+
+ DBGPR("<--xgbe_poll_controller\n");
+}
+#endif /* End CONFIG_NET_POLL_CONTROLLER */
+
+static int xgbe_set_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ unsigned int rxcsum_enabled, rxvlan_enabled;
+
+ rxcsum_enabled = !!(pdata->netdev_features & NETIF_F_RXCSUM);
+ rxvlan_enabled = !!(pdata->netdev_features & NETIF_F_HW_VLAN_CTAG_RX);
+
+ if ((features & NETIF_F_RXCSUM) && !rxcsum_enabled) {
+ hw_if->enable_rx_csum(pdata);
+ netdev_alert(netdev, "state change - rxcsum enabled\n");
+ } else if (!(features & NETIF_F_RXCSUM) && rxcsum_enabled) {
+ hw_if->disable_rx_csum(pdata);
+ netdev_alert(netdev, "state change - rxcsum disabled\n");
+ }
+
+ if ((features & NETIF_F_HW_VLAN_CTAG_RX) && !rxvlan_enabled) {
+ hw_if->enable_rx_vlan_stripping(pdata);
+ netdev_alert(netdev, "state change - rxvlan enabled\n");
+ } else if (!(features & NETIF_F_HW_VLAN_CTAG_RX) && rxvlan_enabled) {
+ hw_if->disable_rx_vlan_stripping(pdata);
+ netdev_alert(netdev, "state change - rxvlan disabled\n");
+ }
+
+ pdata->netdev_features = features;
+
+ DBGPR("<--xgbe_set_features\n");
+
+ return 0;
+}
+
+static const struct net_device_ops xgbe_netdev_ops = {
+ .ndo_open = xgbe_open,
+ .ndo_stop = xgbe_close,
+ .ndo_start_xmit = xgbe_xmit,
+ .ndo_set_rx_mode = xgbe_set_rx_mode,
+ .ndo_set_mac_address = xgbe_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = xgbe_change_mtu,
+ .ndo_get_stats64 = xgbe_get_stats64,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = xgbe_poll_controller,
+#endif
+ .ndo_set_features = xgbe_set_features,
+};
+
+struct net_device_ops *xgbe_get_netdev_ops(void)
+{
+ return (struct net_device_ops *)&xgbe_netdev_ops;
+}
+
+static int xgbe_tx_poll(struct xgbe_channel *channel)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ struct xgbe_ring *ring = channel->tx_ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_ring_desc *rdesc;
+ struct net_device *netdev = pdata->netdev;
+ unsigned long flags;
+ int processed = 0;
+
+ DBGPR("-->xgbe_tx_poll\n");
+
+ /* Nothing to do if there isn't a Tx ring for this channel */
+ if (!ring)
+ return 0;
+
+ spin_lock_irqsave(&ring->lock, flags);
+
+ while ((processed < TX_DESC_MAX_PROC) && (ring->dirty < ring->cur)) {
+ rdata = GET_DESC_DATA(ring, ring->dirty);
+ rdesc = rdata->rdesc;
+
+ if (!hw_if->tx_complete(rdesc))
+ break;
+
+#ifdef XGMAC_ENABLE_TX_DESC_DUMP
+ xgbe_dump_tx_desc(ring, ring->dirty, 1, 0);
+#endif
+
+ /* Free the SKB and reset the descriptor for re-use */
+ desc_if->unmap_skb(pdata, rdata);
+ hw_if->tx_desc_reset(rdata);
+
+ processed++;
+ ring->dirty++;
+ }
+
+ if ((ring->tx.queue_stopped == 1) &&
+ (xgbe_tx_avail_desc(ring) > TX_DESC_MIN_FREE)) {
+ ring->tx.queue_stopped = 0;
+ netif_wake_subqueue(netdev, channel->queue_index);
+ }
+
+ DBGPR("<--xgbe_tx_poll: processed=%d\n", processed);
+
+ spin_unlock_irqrestore(&ring->lock, flags);
+
+ return processed;
+}
+
+static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
+{
+ struct xgbe_prv_data *pdata = channel->pdata;
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct xgbe_desc_if *desc_if = &pdata->desc_if;
+ struct xgbe_ring *ring = channel->rx_ring;
+ struct xgbe_ring_data *rdata;
+ struct xgbe_packet_data *packet;
+ struct net_device *netdev = pdata->netdev;
+ struct sk_buff *skb;
+ unsigned int incomplete, error;
+ unsigned int cur_len, put_len, max_len;
+ int received = 0;
+
+ DBGPR("-->xgbe_rx_poll: budget=%d\n", budget);
+
+ /* Nothing to do if there isn't a Rx ring for this channel */
+ if (!ring)
+ return 0;
+
+ packet = &ring->packet_data;
+ while (received < budget) {
+ DBGPR(" cur = %d\n", ring->cur);
+
+ /* Clear the packet data information */
+ memset(packet, 0, sizeof(*packet));
+ skb = NULL;
+ error = 0;
+ cur_len = 0;
+
+read_again:
+ rdata = GET_DESC_DATA(ring, ring->cur);
+
+ if (hw_if->dev_read(channel))
+ break;
+
+ received++;
+ ring->cur++;
+ ring->dirty++;
+
+ dma_unmap_single(pdata->dev, rdata->skb_dma,
+ rdata->skb_dma_len, DMA_FROM_DEVICE);
+ rdata->skb_dma = 0;
+
+ incomplete = XGMAC_GET_BITS(packet->attributes,
+ RX_PACKET_ATTRIBUTES,
+ INCOMPLETE);
+
+ /* Earlier error, just drain the remaining data */
+ if (incomplete && error)
+ goto read_again;
+
+ if (error || packet->errors) {
+ if (packet->errors)
+ DBGPR("Error in received packet\n");
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+ put_len = rdata->len - cur_len;
+ if (skb) {
+ if (pskb_expand_head(skb, 0, put_len, GFP_ATOMIC)) {
+ DBGPR("pskb_expand_head error\n");
+ if (incomplete) {
+ error = 1;
+ goto read_again;
+ }
+
+ dev_kfree_skb(skb);
+ continue;
+ }
+ memcpy(skb_tail_pointer(skb), rdata->skb->data,
+ put_len);
+ } else {
+ skb = rdata->skb;
+ rdata->skb = NULL;
+ }
+ skb_put(skb, put_len);
+ cur_len += put_len;
+
+ if (incomplete)
+ goto read_again;
+
+ /* Be sure we don't exceed the configured MTU */
+ max_len = netdev->mtu + ETH_HLEN;
+ if (!(netdev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+ (skb->protocol == htons(ETH_P_8021Q)))
+ max_len += VLAN_HLEN;
+
+ if (skb->len > max_len) {
+ DBGPR("packet length exceeds configured MTU\n");
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+#ifdef XGMAC_ENABLE_RX_PKT_DUMP
+ xgbe_print_pkt(netdev, skb, false);
+#endif
+
+ skb_checksum_none_assert(skb);
+ if (XGMAC_GET_BITS(packet->attributes,
+ RX_PACKET_ATTRIBUTES, CSUM_DONE))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ if (XGMAC_GET_BITS(packet->attributes,
+ RX_PACKET_ATTRIBUTES, VLAN_CTAG))
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ packet->vlan_ctag);
+
+ skb->dev = netdev;
+ skb->protocol = eth_type_trans(skb, netdev);
+ skb_record_rx_queue(skb, channel->queue_index);
+ skb_mark_napi_id(skb, &pdata->napi);
+
+ netdev->last_rx = jiffies;
+ napi_gro_receive(&pdata->napi, skb);
+ }
+
+ if (received) {
+ desc_if->realloc_skb(channel);
+
+ /* Update the Rx Tail Pointer Register with address of
+ * the last cleaned entry */
+ rdata = GET_DESC_DATA(ring, ring->rx.realloc_index - 1);
+ XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
+ lower_32_bits(rdata->rdesc_dma));
+ }
+
+ DBGPR("<--xgbe_rx_poll: received = %d\n", received);
+
+ return received;
+}
+
+static int xgbe_poll(struct napi_struct *napi, int budget)
+{
+ struct xgbe_prv_data *pdata = container_of(napi, struct xgbe_prv_data,
+ napi);
+ struct xgbe_channel *channel;
+ int processed;
+ unsigned int i;
+
+ DBGPR("-->xgbe_poll: budget=%d\n", budget);
+
+ /* Cleanup Tx ring first */
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++)
+ xgbe_tx_poll(channel);
+
+ /* Process Rx ring next */
+ processed = 0;
+ channel = pdata->channel;
+ for (i = 0; i < pdata->channel_count; i++, channel++)
+ processed += xgbe_rx_poll(channel, budget - processed);
+
+ /* If we processed everything, we are done */
+ if (processed < budget) {
+ /* Turn off polling */
+ napi_complete(napi);
+
+ /* Enable Tx and Rx interrupts */
+ xgbe_enable_rx_tx_ints(pdata);
+ }
+
+ DBGPR("<--xgbe_poll: received = %d\n", processed);
+
+ return processed;
+}
+
+void xgbe_dump_tx_desc(struct xgbe_ring *ring, unsigned int idx,
+ unsigned int count, unsigned int flag)
+{
+ struct xgbe_ring_data *rdata;
+ struct xgbe_ring_desc *rdesc;
+
+ while (count--) {
+ rdata = GET_DESC_DATA(ring, idx);
+ rdesc = rdata->rdesc;
+ DBGPR("TX_NORMAL_DESC[%d %s] = %08x:%08x:%08x:%08x\n", idx,
+ (flag == 1) ? "QUEUED FOR TX" : "TX BY DEVICE",
+ le32_to_cpu(rdesc->desc0), le32_to_cpu(rdesc->desc1),
+ le32_to_cpu(rdesc->desc2), le32_to_cpu(rdesc->desc3));
+ idx++;
+ }
+}
+
+void xgbe_dump_rx_desc(struct xgbe_ring *ring, struct xgbe_ring_desc *desc,
+ unsigned int idx)
+{
+ DBGPR("RX_NORMAL_DESC[%d RX BY DEVICE] = %08x:%08x:%08x:%08x\n", idx,
+ le32_to_cpu(desc->desc0), le32_to_cpu(desc->desc1),
+ le32_to_cpu(desc->desc2), le32_to_cpu(desc->desc3));
+}
+
+void xgbe_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx)
+{
+ struct ethhdr *eth = (struct ethhdr *)skb->data;
+ unsigned char *buf = skb->data;
+ unsigned char buffer[128];
+ unsigned int i, j;
+
+ netdev_alert(netdev, "\n************** SKB dump ****************\n");
+
+ netdev_alert(netdev, "%s packet of %d bytes\n",
+ (tx_rx ? "TX" : "RX"), skb->len);
+
+ netdev_alert(netdev, "Dst MAC addr: %pM\n", eth->h_dest);
+ netdev_alert(netdev, "Src MAC addr: %pM\n", eth->h_source);
+ netdev_alert(netdev, "Protocol: 0x%04hx\n", ntohs(eth->h_proto));
+
+ for (i = 0, j = 0; i < skb->len;) {
+ j += snprintf(buffer + j, sizeof(buffer) - j, "%02hhx",
+ buf[i++]);
+
+ if ((i % 32) == 0) {
+ netdev_alert(netdev, " 0x%04x: %s\n", i - 32, buffer);
+ j = 0;
+ } else if ((i % 16) == 0) {
+ buffer[j++] = ' ';
+ buffer[j++] = ' ';
+ } else if ((i % 4) == 0) {
+ buffer[j++] = ' ';
+ }
+ }
+ if (i % 32)
+ netdev_alert(netdev, " 0x%04x: %s\n", i - (i % 32), buffer);
+
+ netdev_alert(netdev, "\n************** SKB dump ****************\n");
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
new file mode 100644
index 00000000000..8909f2b51af
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
@@ -0,0 +1,510 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/phy.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+struct xgbe_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int stat_size;
+ int stat_offset;
+};
+
+#define XGMAC_MMC_STAT(_string, _var) \
+ { _string, \
+ FIELD_SIZEOF(struct xgbe_mmc_stats, _var), \
+ offsetof(struct xgbe_prv_data, mmc_stats._var), \
+ }
+
+static const struct xgbe_stats xgbe_gstring_stats[] = {
+ XGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
+ XGMAC_MMC_STAT("tx_packets", txframecount_gb),
+ XGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
+ XGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
+ XGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
+ XGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
+ XGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
+ XGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
+ XGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
+ XGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
+ XGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
+ XGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
+ XGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
+ XGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
+
+ XGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
+ XGMAC_MMC_STAT("rx_packets", rxframecount_gb),
+ XGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
+ XGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
+ XGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
+ XGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
+ XGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
+ XGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
+ XGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
+ XGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
+ XGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
+ XGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
+ XGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
+ XGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
+ XGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
+ XGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
+ XGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
+ XGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
+ XGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
+ XGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
+ XGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
+ XGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
+};
+#define XGBE_STATS_COUNT ARRAY_SIZE(xgbe_gstring_stats)
+
+static void xgbe_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
+{
+ int i;
+
+ DBGPR("-->%s\n", __func__);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < XGBE_STATS_COUNT; i++) {
+ memcpy(data, xgbe_gstring_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ data += ETH_GSTRING_LEN;
+ }
+ break;
+ }
+
+ DBGPR("<--%s\n", __func__);
+}
+
+static void xgbe_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ u8 *stat;
+ int i;
+
+ DBGPR("-->%s\n", __func__);
+
+ pdata->hw_if.read_mmc_stats(pdata);
+ for (i = 0; i < XGBE_STATS_COUNT; i++) {
+ stat = (u8 *)pdata + xgbe_gstring_stats[i].stat_offset;
+ *data++ = *(u64 *)stat;
+ }
+
+ DBGPR("<--%s\n", __func__);
+}
+
+static int xgbe_get_sset_count(struct net_device *netdev, int stringset)
+{
+ int ret;
+
+ DBGPR("-->%s\n", __func__);
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ ret = XGBE_STATS_COUNT;
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ DBGPR("<--%s\n", __func__);
+
+ return ret;
+}
+
+static void xgbe_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ DBGPR("-->xgbe_get_pauseparam\n");
+
+ pause->autoneg = pdata->pause_autoneg;
+ pause->tx_pause = pdata->tx_pause;
+ pause->rx_pause = pdata->rx_pause;
+
+ DBGPR("<--xgbe_get_pauseparam\n");
+}
+
+static int xgbe_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct phy_device *phydev = pdata->phydev;
+ int ret = 0;
+
+ DBGPR("-->xgbe_set_pauseparam\n");
+
+ DBGPR(" autoneg = %d, tx_pause = %d, rx_pause = %d\n",
+ pause->autoneg, pause->tx_pause, pause->rx_pause);
+
+ pdata->pause_autoneg = pause->autoneg;
+ if (pause->autoneg) {
+ phydev->advertising |= ADVERTISED_Pause;
+ phydev->advertising |= ADVERTISED_Asym_Pause;
+
+ } else {
+ phydev->advertising &= ~ADVERTISED_Pause;
+ phydev->advertising &= ~ADVERTISED_Asym_Pause;
+
+ pdata->tx_pause = pause->tx_pause;
+ pdata->rx_pause = pause->rx_pause;
+ }
+
+ if (netif_running(netdev))
+ ret = phy_start_aneg(phydev);
+
+ DBGPR("<--xgbe_set_pauseparam\n");
+
+ return ret;
+}
+
+static int xgbe_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *cmd)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ int ret;
+
+ DBGPR("-->xgbe_get_settings\n");
+
+ if (!pdata->phydev)
+ return -ENODEV;
+
+ spin_lock_irq(&pdata->lock);
+
+ ret = phy_ethtool_gset(pdata->phydev, cmd);
+ cmd->transceiver = XCVR_EXTERNAL;
+
+ spin_unlock_irq(&pdata->lock);
+
+ DBGPR("<--xgbe_get_settings\n");
+
+ return ret;
+}
+
+static int xgbe_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *cmd)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct phy_device *phydev = pdata->phydev;
+ u32 speed;
+ int ret;
+
+ DBGPR("-->xgbe_set_settings\n");
+
+ if (!pdata->phydev)
+ return -ENODEV;
+
+ spin_lock_irq(&pdata->lock);
+
+ speed = ethtool_cmd_speed(cmd);
+
+ ret = -EINVAL;
+ if (cmd->phy_address != phydev->addr)
+ goto unlock;
+
+ if ((cmd->autoneg != AUTONEG_ENABLE) &&
+ (cmd->autoneg != AUTONEG_DISABLE))
+ goto unlock;
+
+ if ((cmd->autoneg == AUTONEG_DISABLE) &&
+ (((speed != SPEED_10000) && (speed != SPEED_1000)) ||
+ (cmd->duplex != DUPLEX_FULL)))
+ goto unlock;
+
+ if (cmd->autoneg == AUTONEG_ENABLE) {
+ /* Clear settings needed to force speeds */
+ phydev->supported &= ~SUPPORTED_1000baseT_Full;
+ phydev->supported &= ~SUPPORTED_10000baseT_Full;
+ } else {
+ /* Add settings needed to force speed */
+ phydev->supported |= SUPPORTED_1000baseT_Full;
+ phydev->supported |= SUPPORTED_10000baseT_Full;
+ }
+
+ cmd->advertising &= phydev->supported;
+ if ((cmd->autoneg == AUTONEG_ENABLE) && !cmd->advertising)
+ goto unlock;
+
+ ret = 0;
+ phydev->autoneg = cmd->autoneg;
+ phydev->speed = speed;
+ phydev->duplex = cmd->duplex;
+ phydev->advertising = cmd->advertising;
+
+ if (cmd->autoneg == AUTONEG_ENABLE)
+ phydev->advertising |= ADVERTISED_Autoneg;
+ else
+ phydev->advertising &= ~ADVERTISED_Autoneg;
+
+ if (netif_running(netdev))
+ ret = phy_start_aneg(phydev);
+
+unlock:
+ spin_unlock_irq(&pdata->lock);
+
+ DBGPR("<--xgbe_set_settings\n");
+
+ return ret;
+}
+
+static void xgbe_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ strlcpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, XGBE_DRV_VERSION, sizeof(drvinfo->version));
+ strlcpy(drvinfo->bus_info, dev_name(pdata->dev),
+ sizeof(drvinfo->bus_info));
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%d",
+ XGMAC_IOREAD_BITS(pdata, MAC_VR, USERVER),
+ XGMAC_IOREAD_BITS(pdata, MAC_VR, DEVID),
+ XGMAC_IOREAD_BITS(pdata, MAC_VR, SNPSVER));
+ drvinfo->n_stats = XGBE_STATS_COUNT;
+}
+
+static int xgbe_get_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ unsigned int riwt;
+
+ DBGPR("-->xgbe_get_coalesce\n");
+
+ memset(ec, 0, sizeof(struct ethtool_coalesce));
+
+ riwt = pdata->rx_riwt;
+ ec->rx_coalesce_usecs = hw_if->riwt_to_usec(pdata, riwt);
+ ec->rx_max_coalesced_frames = pdata->rx_frames;
+
+ ec->tx_coalesce_usecs = pdata->tx_usecs;
+ ec->tx_max_coalesced_frames = pdata->tx_frames;
+
+ DBGPR("<--xgbe_get_coalesce\n");
+
+ return 0;
+}
+
+static int xgbe_set_coalesce(struct net_device *netdev,
+ struct ethtool_coalesce *ec)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ unsigned int rx_frames, rx_riwt, rx_usecs;
+ unsigned int tx_frames, tx_usecs;
+
+ DBGPR("-->xgbe_set_coalesce\n");
+
+ /* Check for not supported parameters */
+ if ((ec->rx_coalesce_usecs_irq) ||
+ (ec->rx_max_coalesced_frames_irq) ||
+ (ec->tx_coalesce_usecs_irq) ||
+ (ec->tx_max_coalesced_frames_irq) ||
+ (ec->stats_block_coalesce_usecs) ||
+ (ec->use_adaptive_rx_coalesce) ||
+ (ec->use_adaptive_tx_coalesce) ||
+ (ec->pkt_rate_low) ||
+ (ec->rx_coalesce_usecs_low) ||
+ (ec->rx_max_coalesced_frames_low) ||
+ (ec->tx_coalesce_usecs_low) ||
+ (ec->tx_max_coalesced_frames_low) ||
+ (ec->pkt_rate_high) ||
+ (ec->rx_coalesce_usecs_high) ||
+ (ec->rx_max_coalesced_frames_high) ||
+ (ec->tx_coalesce_usecs_high) ||
+ (ec->tx_max_coalesced_frames_high) ||
+ (ec->rate_sample_interval))
+ return -EOPNOTSUPP;
+
+ /* Can only change rx-frames when interface is down (see
+ * rx_descriptor_init in xgbe-dev.c)
+ */
+ rx_frames = pdata->rx_frames;
+ if (rx_frames != ec->rx_max_coalesced_frames && netif_running(netdev)) {
+ netdev_alert(netdev,
+ "interface must be down to change rx-frames\n");
+ return -EINVAL;
+ }
+
+ rx_riwt = hw_if->usec_to_riwt(pdata, ec->rx_coalesce_usecs);
+ rx_frames = ec->rx_max_coalesced_frames;
+
+ /* Use smallest possible value if conversion resulted in zero */
+ if (ec->rx_coalesce_usecs && !rx_riwt)
+ rx_riwt = 1;
+
+ /* Check the bounds of values for Rx */
+ if (rx_riwt > XGMAC_MAX_DMA_RIWT) {
+ rx_usecs = hw_if->riwt_to_usec(pdata, XGMAC_MAX_DMA_RIWT);
+ netdev_alert(netdev, "rx-usec is limited to %d usecs\n",
+ rx_usecs);
+ return -EINVAL;
+ }
+ if (rx_frames > pdata->channel->rx_ring->rdesc_count) {
+ netdev_alert(netdev, "rx-frames is limited to %d frames\n",
+ pdata->channel->rx_ring->rdesc_count);
+ return -EINVAL;
+ }
+
+ tx_usecs = ec->tx_coalesce_usecs;
+ tx_frames = ec->tx_max_coalesced_frames;
+
+ /* Check the bounds of values for Tx */
+ if (tx_frames > pdata->channel->tx_ring->rdesc_count) {
+ netdev_alert(netdev, "tx-frames is limited to %d frames\n",
+ pdata->channel->tx_ring->rdesc_count);
+ return -EINVAL;
+ }
+
+ pdata->rx_riwt = rx_riwt;
+ pdata->rx_frames = rx_frames;
+ hw_if->config_rx_coalesce(pdata);
+
+ pdata->tx_usecs = tx_usecs;
+ pdata->tx_frames = tx_frames;
+ hw_if->config_tx_coalesce(pdata);
+
+ DBGPR("<--xgbe_set_coalesce\n");
+
+ return 0;
+}
+
+static const struct ethtool_ops xgbe_ethtool_ops = {
+ .get_settings = xgbe_get_settings,
+ .set_settings = xgbe_set_settings,
+ .get_drvinfo = xgbe_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_coalesce = xgbe_get_coalesce,
+ .set_coalesce = xgbe_set_coalesce,
+ .get_pauseparam = xgbe_get_pauseparam,
+ .set_pauseparam = xgbe_set_pauseparam,
+ .get_strings = xgbe_get_strings,
+ .get_ethtool_stats = xgbe_get_ethtool_stats,
+ .get_sset_count = xgbe_get_sset_count,
+};
+
+struct ethtool_ops *xgbe_get_ethtool_ops(void)
+{
+ return (struct ethtool_ops *)&xgbe_ethtool_ops;
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
new file mode 100644
index 00000000000..5a1891faba8
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c
@@ -0,0 +1,513 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/clk.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(XGBE_DRV_VERSION);
+MODULE_DESCRIPTION(XGBE_DRV_DESC);
+
+static struct xgbe_channel *xgbe_alloc_rings(struct xgbe_prv_data *pdata)
+{
+ struct xgbe_channel *channel_mem, *channel;
+ struct xgbe_ring *tx_ring, *rx_ring;
+ unsigned int count, i;
+
+ DBGPR("-->xgbe_alloc_rings\n");
+
+ count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
+
+ channel_mem = devm_kcalloc(pdata->dev, count,
+ sizeof(struct xgbe_channel), GFP_KERNEL);
+ if (!channel_mem)
+ return NULL;
+
+ tx_ring = devm_kcalloc(pdata->dev, pdata->tx_ring_count,
+ sizeof(struct xgbe_ring), GFP_KERNEL);
+ if (!tx_ring)
+ return NULL;
+
+ rx_ring = devm_kcalloc(pdata->dev, pdata->rx_ring_count,
+ sizeof(struct xgbe_ring), GFP_KERNEL);
+ if (!rx_ring)
+ return NULL;
+
+ for (i = 0, channel = channel_mem; i < count; i++, channel++) {
+ snprintf(channel->name, sizeof(channel->name), "channel-%d", i);
+ channel->pdata = pdata;
+ channel->queue_index = i;
+ channel->dma_regs = pdata->xgmac_regs + DMA_CH_BASE +
+ (DMA_CH_INC * i);
+
+ if (i < pdata->tx_ring_count) {
+ spin_lock_init(&tx_ring->lock);
+ channel->tx_ring = tx_ring++;
+ }
+
+ if (i < pdata->rx_ring_count) {
+ spin_lock_init(&tx_ring->lock);
+ channel->rx_ring = rx_ring++;
+ }
+
+ DBGPR(" %s - queue_index=%u, dma_regs=%p, tx=%p, rx=%p\n",
+ channel->name, channel->queue_index, channel->dma_regs,
+ channel->tx_ring, channel->rx_ring);
+ }
+
+ pdata->channel_count = count;
+
+ DBGPR("<--xgbe_alloc_rings\n");
+
+ return channel_mem;
+}
+
+static void xgbe_default_config(struct xgbe_prv_data *pdata)
+{
+ DBGPR("-->xgbe_default_config\n");
+
+ pdata->pblx8 = DMA_PBL_X8_ENABLE;
+ pdata->tx_sf_mode = MTL_TSF_ENABLE;
+ pdata->tx_threshold = MTL_TX_THRESHOLD_64;
+ pdata->tx_pbl = DMA_PBL_16;
+ pdata->tx_osp_mode = DMA_OSP_ENABLE;
+ pdata->rx_sf_mode = MTL_RSF_DISABLE;
+ pdata->rx_threshold = MTL_RX_THRESHOLD_64;
+ pdata->rx_pbl = DMA_PBL_16;
+ pdata->pause_autoneg = 1;
+ pdata->tx_pause = 1;
+ pdata->rx_pause = 1;
+ pdata->power_down = 0;
+ pdata->default_autoneg = AUTONEG_ENABLE;
+ pdata->default_speed = SPEED_10000;
+
+ DBGPR("<--xgbe_default_config\n");
+}
+
+static void xgbe_init_all_fptrs(struct xgbe_prv_data *pdata)
+{
+ xgbe_init_function_ptrs_dev(&pdata->hw_if);
+ xgbe_init_function_ptrs_desc(&pdata->desc_if);
+}
+
+static int xgbe_probe(struct platform_device *pdev)
+{
+ struct xgbe_prv_data *pdata;
+ struct xgbe_hw_if *hw_if;
+ struct xgbe_desc_if *desc_if;
+ struct net_device *netdev;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ const u8 *mac_addr;
+ int ret;
+
+ DBGPR("--> xgbe_probe\n");
+
+ netdev = alloc_etherdev_mq(sizeof(struct xgbe_prv_data),
+ XGBE_MAX_DMA_CHANNELS);
+ if (!netdev) {
+ dev_err(dev, "alloc_etherdev failed\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+ SET_NETDEV_DEV(netdev, dev);
+ pdata = netdev_priv(netdev);
+ pdata->netdev = netdev;
+ pdata->pdev = pdev;
+ pdata->dev = dev;
+ platform_set_drvdata(pdev, netdev);
+
+ spin_lock_init(&pdata->lock);
+ mutex_init(&pdata->xpcs_mutex);
+
+ /* Set and validate the number of descriptors for a ring */
+ BUILD_BUG_ON_NOT_POWER_OF_2(TX_DESC_CNT);
+ pdata->tx_desc_count = TX_DESC_CNT;
+ if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) {
+ dev_err(dev, "tx descriptor count (%d) is not valid\n",
+ pdata->tx_desc_count);
+ ret = -EINVAL;
+ goto err_io;
+ }
+ BUILD_BUG_ON_NOT_POWER_OF_2(RX_DESC_CNT);
+ pdata->rx_desc_count = RX_DESC_CNT;
+ if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) {
+ dev_err(dev, "rx descriptor count (%d) is not valid\n",
+ pdata->rx_desc_count);
+ ret = -EINVAL;
+ goto err_io;
+ }
+
+ /* Obtain the system clock setting */
+ pdata->sysclock = devm_clk_get(dev, NULL);
+ if (IS_ERR(pdata->sysclock)) {
+ dev_err(dev, "devm_clk_get failed\n");
+ ret = PTR_ERR(pdata->sysclock);
+ goto err_io;
+ }
+
+ /* Obtain the mmio areas for the device */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pdata->xgmac_regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(pdata->xgmac_regs)) {
+ dev_err(dev, "xgmac ioremap failed\n");
+ ret = PTR_ERR(pdata->xgmac_regs);
+ goto err_io;
+ }
+ DBGPR(" xgmac_regs = %p\n", pdata->xgmac_regs);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ pdata->xpcs_regs = devm_ioremap_resource(dev, res);
+ if (IS_ERR(pdata->xpcs_regs)) {
+ dev_err(dev, "xpcs ioremap failed\n");
+ ret = PTR_ERR(pdata->xpcs_regs);
+ goto err_io;
+ }
+ DBGPR(" xpcs_regs = %p\n", pdata->xpcs_regs);
+
+ /* Set the DMA mask */
+ if (!dev->dma_mask)
+ dev->dma_mask = &dev->coherent_dma_mask;
+ *(dev->dma_mask) = DMA_BIT_MASK(40);
+ dev->coherent_dma_mask = DMA_BIT_MASK(40);
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0) {
+ dev_err(dev, "platform_get_irq failed\n");
+ goto err_io;
+ }
+ netdev->irq = ret;
+ netdev->base_addr = (unsigned long)pdata->xgmac_regs;
+
+ /* Set all the function pointers */
+ xgbe_init_all_fptrs(pdata);
+ hw_if = &pdata->hw_if;
+ desc_if = &pdata->desc_if;
+
+ /* Issue software reset to device */
+ hw_if->exit(pdata);
+
+ /* Populate the hardware features */
+ xgbe_get_all_hw_features(pdata);
+
+ /* Retrieve the MAC address */
+ mac_addr = of_get_mac_address(dev->of_node);
+ if (!mac_addr) {
+ dev_err(dev, "invalid mac address for this device\n");
+ ret = -EINVAL;
+ goto err_io;
+ }
+ memcpy(netdev->dev_addr, mac_addr, netdev->addr_len);
+
+ /* Retrieve the PHY mode - it must be "xgmii" */
+ pdata->phy_mode = of_get_phy_mode(dev->of_node);
+ if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) {
+ dev_err(dev, "invalid phy-mode specified for this device\n");
+ ret = -EINVAL;
+ goto err_io;
+ }
+
+ /* Set default configuration data */
+ xgbe_default_config(pdata);
+
+ /* Calculate the number of Tx and Rx rings to be created */
+ pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(),
+ pdata->hw_feat.tx_ch_cnt);
+ ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count);
+ if (ret) {
+ dev_err(dev, "error setting real tx queue count\n");
+ goto err_io;
+ }
+
+ pdata->rx_ring_count = min_t(unsigned int,
+ netif_get_num_default_rss_queues(),
+ pdata->hw_feat.rx_ch_cnt);
+ ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count);
+ if (ret) {
+ dev_err(dev, "error setting real rx queue count\n");
+ goto err_io;
+ }
+
+ /* Allocate the rings for the DMA channels */
+ pdata->channel = xgbe_alloc_rings(pdata);
+ if (!pdata->channel) {
+ dev_err(dev, "ring allocation failed\n");
+ ret = -ENOMEM;
+ goto err_io;
+ }
+
+ /* Prepare to regsiter with MDIO */
+ pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name);
+ if (!pdata->mii_bus_id) {
+ dev_err(dev, "failed to allocate mii bus id\n");
+ ret = -ENOMEM;
+ goto err_io;
+ }
+ ret = xgbe_mdio_register(pdata);
+ if (ret)
+ goto err_bus_id;
+
+ /* Set network and ethtool operations */
+ netdev->netdev_ops = xgbe_get_netdev_ops();
+ netdev->ethtool_ops = xgbe_get_ethtool_ops();
+
+ /* Set device features */
+ netdev->hw_features = NETIF_F_SG |
+ NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM |
+ NETIF_F_RXCSUM |
+ NETIF_F_TSO |
+ NETIF_F_TSO6 |
+ NETIF_F_GRO |
+ NETIF_F_HW_VLAN_CTAG_RX |
+ NETIF_F_HW_VLAN_CTAG_TX;
+
+ netdev->vlan_features |= NETIF_F_SG |
+ NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM |
+ NETIF_F_TSO |
+ NETIF_F_TSO6;
+
+ netdev->features |= netdev->hw_features;
+ pdata->netdev_features = netdev->features;
+
+ xgbe_init_rx_coalesce(pdata);
+ xgbe_init_tx_coalesce(pdata);
+
+ netif_carrier_off(netdev);
+ ret = register_netdev(netdev);
+ if (ret) {
+ dev_err(dev, "net device registration failed\n");
+ goto err_reg_netdev;
+ }
+
+ xgbe_debugfs_init(pdata);
+
+ netdev_notice(netdev, "net device enabled\n");
+
+ DBGPR("<-- xgbe_probe\n");
+
+ return 0;
+
+err_reg_netdev:
+ xgbe_mdio_unregister(pdata);
+
+err_bus_id:
+ kfree(pdata->mii_bus_id);
+
+err_io:
+ free_netdev(netdev);
+
+err_alloc:
+ dev_notice(dev, "net device not enabled\n");
+
+ return ret;
+}
+
+static int xgbe_remove(struct platform_device *pdev)
+{
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ DBGPR("-->xgbe_remove\n");
+
+ xgbe_debugfs_exit(pdata);
+
+ unregister_netdev(netdev);
+
+ xgbe_mdio_unregister(pdata);
+
+ kfree(pdata->mii_bus_id);
+
+ free_netdev(netdev);
+
+ DBGPR("<--xgbe_remove\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int xgbe_suspend(struct device *dev)
+{
+ struct net_device *netdev = dev_get_drvdata(dev);
+ int ret;
+
+ DBGPR("-->xgbe_suspend\n");
+
+ if (!netif_running(netdev)) {
+ DBGPR("<--xgbe_dev_suspend\n");
+ return -EINVAL;
+ }
+
+ ret = xgbe_powerdown(netdev, XGMAC_DRIVER_CONTEXT);
+
+ DBGPR("<--xgbe_suspend\n");
+
+ return ret;
+}
+
+static int xgbe_resume(struct device *dev)
+{
+ struct net_device *netdev = dev_get_drvdata(dev);
+ int ret;
+
+ DBGPR("-->xgbe_resume\n");
+
+ if (!netif_running(netdev)) {
+ DBGPR("<--xgbe_dev_resume\n");
+ return -EINVAL;
+ }
+
+ ret = xgbe_powerup(netdev, XGMAC_DRIVER_CONTEXT);
+
+ DBGPR("<--xgbe_resume\n");
+
+ return ret;
+}
+#endif /* CONFIG_PM */
+
+static const struct of_device_id xgbe_of_match[] = {
+ { .compatible = "amd,xgbe-seattle-v1a", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, xgbe_of_match);
+static SIMPLE_DEV_PM_OPS(xgbe_pm_ops, xgbe_suspend, xgbe_resume);
+
+static struct platform_driver xgbe_driver = {
+ .driver = {
+ .name = "amd-xgbe",
+ .of_match_table = xgbe_of_match,
+ .pm = &xgbe_pm_ops,
+ },
+ .probe = xgbe_probe,
+ .remove = xgbe_remove,
+};
+
+module_platform_driver(xgbe_driver);
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
new file mode 100644
index 00000000000..ea7a5d6750e
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
@@ -0,0 +1,433 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/spinlock.h>
+#include <linux/mdio.h>
+#include <linux/phy.h>
+#include <linux/of.h>
+
+#include "xgbe.h"
+#include "xgbe-common.h"
+
+
+static int xgbe_mdio_read(struct mii_bus *mii, int prtad, int mmd_reg)
+{
+ struct xgbe_prv_data *pdata = mii->priv;
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ int mmd_data;
+
+ DBGPR_MDIO("-->xgbe_mdio_read: prtad=%#x mmd_reg=%#x\n",
+ prtad, mmd_reg);
+
+ mmd_data = hw_if->read_mmd_regs(pdata, prtad, mmd_reg);
+
+ DBGPR_MDIO("<--xgbe_mdio_read: mmd_data=%#x\n", mmd_data);
+
+ return mmd_data;
+}
+
+static int xgbe_mdio_write(struct mii_bus *mii, int prtad, int mmd_reg,
+ u16 mmd_val)
+{
+ struct xgbe_prv_data *pdata = mii->priv;
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ int mmd_data = mmd_val;
+
+ DBGPR_MDIO("-->xgbe_mdio_write: prtad=%#x mmd_reg=%#x mmd_data=%#x\n",
+ prtad, mmd_reg, mmd_data);
+
+ hw_if->write_mmd_regs(pdata, prtad, mmd_reg, mmd_data);
+
+ DBGPR_MDIO("<--xgbe_mdio_write\n");
+
+ return 0;
+}
+
+static void xgbe_adjust_link(struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+ struct xgbe_hw_if *hw_if = &pdata->hw_if;
+ struct phy_device *phydev = pdata->phydev;
+ unsigned long flags;
+ int new_state = 0;
+
+ if (phydev == NULL)
+ return;
+
+ DBGPR_MDIO("-->xgbe_adjust_link: address=%d, newlink=%d, curlink=%d\n",
+ phydev->addr, phydev->link, pdata->phy_link);
+
+ spin_lock_irqsave(&pdata->lock, flags);
+
+ if (phydev->link) {
+ /* Flow control support */
+ if (pdata->pause_autoneg) {
+ if (phydev->pause || phydev->asym_pause) {
+ pdata->tx_pause = 1;
+ pdata->rx_pause = 1;
+ } else {
+ pdata->tx_pause = 0;
+ pdata->rx_pause = 0;
+ }
+ }
+
+ if (pdata->tx_pause != pdata->phy_tx_pause) {
+ hw_if->config_tx_flow_control(pdata);
+ pdata->phy_tx_pause = pdata->tx_pause;
+ }
+
+ if (pdata->rx_pause != pdata->phy_rx_pause) {
+ hw_if->config_rx_flow_control(pdata);
+ pdata->phy_rx_pause = pdata->rx_pause;
+ }
+
+ /* Speed support */
+ if (phydev->speed != pdata->phy_speed) {
+ new_state = 1;
+
+ switch (phydev->speed) {
+ case SPEED_10000:
+ hw_if->set_xgmii_speed(pdata);
+ break;
+
+ case SPEED_2500:
+ hw_if->set_gmii_2500_speed(pdata);
+ break;
+
+ case SPEED_1000:
+ hw_if->set_gmii_speed(pdata);
+ break;
+ }
+ pdata->phy_speed = phydev->speed;
+ }
+
+ if (phydev->link != pdata->phy_link) {
+ new_state = 1;
+ pdata->phy_link = 1;
+ }
+ } else if (pdata->phy_link) {
+ new_state = 1;
+ pdata->phy_link = 0;
+ pdata->phy_speed = SPEED_UNKNOWN;
+ }
+
+ if (new_state)
+ phy_print_status(phydev);
+
+ spin_unlock_irqrestore(&pdata->lock, flags);
+
+ DBGPR_MDIO("<--xgbe_adjust_link\n");
+}
+
+void xgbe_dump_phy_registers(struct xgbe_prv_data *pdata)
+{
+ struct device *dev = pdata->dev;
+ struct phy_device *phydev = pdata->mii->phy_map[XGBE_PRTAD];
+ int i;
+
+ dev_alert(dev, "\n************* PHY Reg dump **********************\n");
+
+ dev_alert(dev, "PCS Control Reg (%#04x) = %#04x\n", MDIO_CTRL1,
+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1));
+ dev_alert(dev, "PCS Status Reg (%#04x) = %#04x\n", MDIO_STAT1,
+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1));
+ dev_alert(dev, "Phy Id (PHYS ID 1 %#04x)= %#04x\n", MDIO_DEVID1,
+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID1));
+ dev_alert(dev, "Phy Id (PHYS ID 2 %#04x)= %#04x\n", MDIO_DEVID2,
+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVID2));
+ dev_alert(dev, "Devices in Package (%#04x)= %#04x\n", MDIO_DEVS1,
+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS1));
+ dev_alert(dev, "Devices in Package (%#04x)= %#04x\n", MDIO_DEVS2,
+ XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_DEVS2));
+
+ dev_alert(dev, "Auto-Neg Control Reg (%#04x) = %#04x\n", MDIO_CTRL1,
+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1));
+ dev_alert(dev, "Auto-Neg Status Reg (%#04x) = %#04x\n", MDIO_STAT1,
+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_STAT1));
+ dev_alert(dev, "Auto-Neg Ad Reg 1 (%#04x) = %#04x\n",
+ MDIO_AN_ADVERTISE,
+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE));
+ dev_alert(dev, "Auto-Neg Ad Reg 2 (%#04x) = %#04x\n",
+ MDIO_AN_ADVERTISE + 1,
+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1));
+ dev_alert(dev, "Auto-Neg Ad Reg 3 (%#04x) = %#04x\n",
+ MDIO_AN_ADVERTISE + 2,
+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2));
+ dev_alert(dev, "Auto-Neg Completion Reg (%#04x) = %#04x\n",
+ MDIO_AN_COMP_STAT,
+ XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_COMP_STAT));
+
+ dev_alert(dev, "MMD Device Mask = %#x\n",
+ phydev->c45_ids.devices_in_package);
+ for (i = 0; i < ARRAY_SIZE(phydev->c45_ids.device_ids); i++)
+ dev_alert(dev, " MMD %d: ID = %#08x\n", i,
+ phydev->c45_ids.device_ids[i]);
+
+ dev_alert(dev, "\n*************************************************\n");
+}
+
+int xgbe_mdio_register(struct xgbe_prv_data *pdata)
+{
+ struct net_device *netdev = pdata->netdev;
+ struct device_node *phy_node;
+ struct mii_bus *mii;
+ struct phy_device *phydev;
+ int ret = 0;
+
+ DBGPR("-->xgbe_mdio_register\n");
+
+ /* Retrieve the phy-handle */
+ phy_node = of_parse_phandle(pdata->dev->of_node, "phy-handle", 0);
+ if (!phy_node) {
+ dev_err(pdata->dev, "unable to parse phy-handle\n");
+ return -EINVAL;
+ }
+
+ /* Register with the MDIO bus */
+ mii = mdiobus_alloc();
+ if (mii == NULL) {
+ dev_err(pdata->dev, "mdiobus_alloc failed\n");
+ ret = -ENOMEM;
+ goto err_node_get;
+ }
+
+ /* Register on the MDIO bus (don't probe any PHYs) */
+ mii->name = XGBE_PHY_NAME;
+ mii->read = xgbe_mdio_read;
+ mii->write = xgbe_mdio_write;
+ snprintf(mii->id, sizeof(mii->id), "%s", pdata->mii_bus_id);
+ mii->priv = pdata;
+ mii->phy_mask = ~0;
+ mii->parent = pdata->dev;
+ ret = mdiobus_register(mii);
+ if (ret) {
+ dev_err(pdata->dev, "mdiobus_register failed\n");
+ goto err_mdiobus_alloc;
+ }
+ DBGPR(" mdiobus_register succeeded for %s\n", pdata->mii_bus_id);
+
+ /* Probe the PCS using Clause 45 */
+ phydev = get_phy_device(mii, XGBE_PRTAD, true);
+ if (IS_ERR(phydev) || !phydev ||
+ !phydev->c45_ids.device_ids[MDIO_MMD_PCS]) {
+ dev_err(pdata->dev, "get_phy_device failed\n");
+ ret = phydev ? PTR_ERR(phydev) : -ENOLINK;
+ goto err_mdiobus_register;
+ }
+ request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
+ MDIO_ID_ARGS(phydev->c45_ids.device_ids[MDIO_MMD_PCS]));
+
+ of_node_get(phy_node);
+ phydev->dev.of_node = phy_node;
+ ret = phy_device_register(phydev);
+ if (ret) {
+ dev_err(pdata->dev, "phy_device_register failed\n");
+ of_node_put(phy_node);
+ goto err_phy_device;
+ }
+
+ /* Add a reference to the PHY driver so it can't be unloaded */
+ pdata->phy_module = phydev->dev.driver ?
+ phydev->dev.driver->owner : NULL;
+ if (!try_module_get(pdata->phy_module)) {
+ dev_err(pdata->dev, "try_module_get failed\n");
+ ret = -EIO;
+ goto err_phy_device;
+ }
+
+ pdata->mii = mii;
+ pdata->mdio_mmd = MDIO_MMD_PCS;
+
+ pdata->phy_link = -1;
+ pdata->phy_speed = SPEED_UNKNOWN;
+ pdata->phy_tx_pause = pdata->tx_pause;
+ pdata->phy_rx_pause = pdata->rx_pause;
+
+ ret = phy_connect_direct(netdev, phydev, &xgbe_adjust_link,
+ pdata->phy_mode);
+ if (ret) {
+ netdev_err(netdev, "phy_connect_direct failed\n");
+ goto err_phy_device;
+ }
+
+ if (!phydev->drv || (phydev->drv->phy_id == 0)) {
+ netdev_err(netdev, "phy_id not valid\n");
+ ret = -ENODEV;
+ goto err_phy_connect;
+ }
+ DBGPR(" phy_connect_direct succeeded for PHY %s, link=%d\n",
+ dev_name(&phydev->dev), phydev->link);
+
+ phydev->autoneg = pdata->default_autoneg;
+ if (phydev->autoneg == AUTONEG_DISABLE) {
+ /* Add settings needed to force speed */
+ phydev->supported |= SUPPORTED_1000baseT_Full;
+ phydev->supported |= SUPPORTED_10000baseT_Full;
+
+ phydev->speed = pdata->default_speed;
+ phydev->duplex = DUPLEX_FULL;
+
+ phydev->advertising &= ~ADVERTISED_Autoneg;
+ }
+
+ pdata->phydev = phydev;
+
+ of_node_put(phy_node);
+
+ DBGPHY_REGS(pdata);
+
+ DBGPR("<--xgbe_mdio_register\n");
+
+ return 0;
+
+err_phy_connect:
+ phy_disconnect(phydev);
+
+err_phy_device:
+ phy_device_free(phydev);
+
+err_mdiobus_register:
+ mdiobus_unregister(mii);
+
+err_mdiobus_alloc:
+ mdiobus_free(mii);
+
+err_node_get:
+ of_node_put(phy_node);
+
+ return ret;
+}
+
+void xgbe_mdio_unregister(struct xgbe_prv_data *pdata)
+{
+ DBGPR("-->xgbe_mdio_unregister\n");
+
+ phy_disconnect(pdata->phydev);
+ pdata->phydev = NULL;
+
+ module_put(pdata->phy_module);
+ pdata->phy_module = NULL;
+
+ mdiobus_unregister(pdata->mii);
+ pdata->mii->priv = NULL;
+
+ mdiobus_free(pdata->mii);
+ pdata->mii = NULL;
+
+ DBGPR("<--xgbe_mdio_unregister\n");
+}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
new file mode 100644
index 00000000000..ab0627162c0
--- /dev/null
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -0,0 +1,676 @@
+/*
+ * AMD 10Gb Ethernet driver
+ *
+ * This file is available to you under your choice of the following two
+ * licenses:
+ *
+ * License 1: GPLv2
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ *
+ * This file is free software; you may copy, redistribute and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * License 2: Modified BSD
+ *
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Advanced Micro Devices, Inc. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * The Synopsys DWC ETHER XGMAC Software Driver and documentation
+ * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
+ * Inc. unless otherwise expressly agreed to in writing between Synopsys
+ * and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product
+ * under any End User Software License Agreement or Agreement for Licensed
+ * Product with Synopsys or any supplement thereto. Permission is hereby
+ * granted, free of charge, to any person obtaining a copy of this software
+ * annotated with this license and the Software, to deal in the Software
+ * without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __XGBE_H__
+#define __XGBE_H__
+
+#include <linux/dma-mapping.h>
+#include <linux/netdevice.h>
+#include <linux/workqueue.h>
+#include <linux/phy.h>
+
+
+#define XGBE_DRV_NAME "amd-xgbe"
+#define XGBE_DRV_VERSION "1.0.0-a"
+#define XGBE_DRV_DESC "AMD 10 Gigabit Ethernet Driver"
+
+/* Descriptor related defines */
+#define TX_DESC_CNT 512
+#define TX_DESC_MIN_FREE (TX_DESC_CNT >> 3)
+#define TX_DESC_MAX_PROC (TX_DESC_CNT >> 1)
+#define RX_DESC_CNT 512
+
+#define TX_MAX_BUF_SIZE (0x3fff & ~(64 - 1))
+
+#define RX_MIN_BUF_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
+#define RX_BUF_ALIGN 64
+
+#define XGBE_MAX_DMA_CHANNELS 16
+#define DMA_ARDOMAIN_SETTING 0x2
+#define DMA_ARCACHE_SETTING 0xb
+#define DMA_AWDOMAIN_SETTING 0x2
+#define DMA_AWCACHE_SETTING 0x7
+#define DMA_INTERRUPT_MASK 0x31c7
+
+#define XGMAC_MIN_PACKET 60
+#define XGMAC_STD_PACKET_MTU 1500
+#define XGMAC_MAX_STD_PACKET 1518
+#define XGMAC_JUMBO_PACKET_MTU 9000
+#define XGMAC_MAX_JUMBO_PACKET 9018
+
+#define MAX_MULTICAST_LIST 14
+#define TX_FLAGS_IP_PKT 0x00000001
+#define TX_FLAGS_TCP_PKT 0x00000002
+
+/* MDIO bus phy name */
+#define XGBE_PHY_NAME "amd_xgbe_phy"
+#define XGBE_PRTAD 0
+
+/* Driver PMT macros */
+#define XGMAC_DRIVER_CONTEXT 1
+#define XGMAC_IOCTL_CONTEXT 2
+
+#define FIFO_SIZE_B(x) (x)
+#define FIFO_SIZE_KB(x) (x * 1024)
+
+#define XGBE_TC_CNT 2
+
+/* Helper macro for descriptor handling
+ * Always use GET_DESC_DATA to access the descriptor data
+ * since the index is free-running and needs to be and-ed
+ * with the descriptor count value of the ring to index to
+ * the proper descriptor data.
+ */
+#define GET_DESC_DATA(_ring, _idx) \
+ ((_ring)->rdata + \
+ ((_idx) & ((_ring)->rdesc_count - 1)))
+
+
+/* Default coalescing parameters */
+#define XGMAC_INIT_DMA_TX_USECS 100
+#define XGMAC_INIT_DMA_TX_FRAMES 16
+
+#define XGMAC_MAX_DMA_RIWT 0xff
+#define XGMAC_INIT_DMA_RX_USECS 100
+#define XGMAC_INIT_DMA_RX_FRAMES 16
+
+/* Flow control queue count */
+#define XGMAC_MAX_FLOW_CONTROL_QUEUES 8
+
+
+struct xgbe_prv_data;
+
+struct xgbe_packet_data {
+ unsigned int attributes;
+
+ unsigned int errors;
+
+ unsigned int rdesc_count;
+ unsigned int length;
+
+ unsigned int header_len;
+ unsigned int tcp_header_len;
+ unsigned int tcp_payload_len;
+ unsigned short mss;
+
+ unsigned short vlan_ctag;
+};
+
+/* Common Rx and Tx descriptor mapping */
+struct xgbe_ring_desc {
+ unsigned int desc0;
+ unsigned int desc1;
+ unsigned int desc2;
+ unsigned int desc3;
+};
+
+/* Structure used to hold information related to the descriptor
+ * and the packet associated with the descriptor (always use
+ * use the GET_DESC_DATA macro to access this data from the ring)
+ */
+struct xgbe_ring_data {
+ struct xgbe_ring_desc *rdesc; /* Virtual address of descriptor */
+ dma_addr_t rdesc_dma; /* DMA address of descriptor */
+
+ struct sk_buff *skb; /* Virtual address of SKB */
+ dma_addr_t skb_dma; /* DMA address of SKB data */
+ unsigned int skb_dma_len; /* Length of SKB DMA area */
+ unsigned int tso_header; /* TSO header indicator */
+
+ unsigned short len; /* Length of received Rx packet */
+
+ unsigned int interrupt; /* Interrupt indicator */
+
+ unsigned int mapped_as_page;
+};
+
+struct xgbe_ring {
+ /* Ring lock - used just for TX rings at the moment */
+ spinlock_t lock;
+
+ /* Per packet related information */
+ struct xgbe_packet_data packet_data;
+
+ /* Virtual/DMA addresses and count of allocated descriptor memory */
+ struct xgbe_ring_desc *rdesc;
+ dma_addr_t rdesc_dma;
+ unsigned int rdesc_count;
+
+ /* Array of descriptor data corresponding the descriptor memory
+ * (always use the GET_DESC_DATA macro to access this data)
+ */
+ struct xgbe_ring_data *rdata;
+
+ /* Ring index values
+ * cur - Tx: index of descriptor to be used for current transfer
+ * Rx: index of descriptor to check for packet availability
+ * dirty - Tx: index of descriptor to check for transfer complete
+ * Rx: count of descriptors in which a packet has been received
+ * (used with skb_realloc_index to refresh the ring)
+ */
+ unsigned int cur;
+ unsigned int dirty;
+
+ /* Coalesce frame count used for interrupt bit setting */
+ unsigned int coalesce_count;
+
+ union {
+ struct {
+ unsigned int queue_stopped;
+ unsigned short cur_mss;
+ unsigned short cur_vlan_ctag;
+ } tx;
+
+ struct {
+ unsigned int realloc_index;
+ unsigned int realloc_threshold;
+ } rx;
+ };
+} ____cacheline_aligned;
+
+/* Structure used to describe the descriptor rings associated with
+ * a DMA channel.
+ */
+struct xgbe_channel {
+ char name[16];
+
+ /* Address of private data area for device */
+ struct xgbe_prv_data *pdata;
+
+ /* Queue index and base address of queue's DMA registers */
+ unsigned int queue_index;
+ void __iomem *dma_regs;
+
+ unsigned int saved_ier;
+
+ unsigned int tx_timer_active;
+ struct hrtimer tx_timer;
+
+ struct xgbe_ring *tx_ring;
+ struct xgbe_ring *rx_ring;
+} ____cacheline_aligned;
+
+enum xgbe_int {
+ XGMAC_INT_DMA_ISR_DC0IS,
+ XGMAC_INT_DMA_CH_SR_TI,
+ XGMAC_INT_DMA_CH_SR_TPS,
+ XGMAC_INT_DMA_CH_SR_TBU,
+ XGMAC_INT_DMA_CH_SR_RI,
+ XGMAC_INT_DMA_CH_SR_RBU,
+ XGMAC_INT_DMA_CH_SR_RPS,
+ XGMAC_INT_DMA_CH_SR_FBE,
+ XGMAC_INT_DMA_ALL,
+};
+
+enum xgbe_int_state {
+ XGMAC_INT_STATE_SAVE,
+ XGMAC_INT_STATE_RESTORE,
+};
+
+enum xgbe_mtl_fifo_size {
+ XGMAC_MTL_FIFO_SIZE_256 = 0x00,
+ XGMAC_MTL_FIFO_SIZE_512 = 0x01,
+ XGMAC_MTL_FIFO_SIZE_1K = 0x03,
+ XGMAC_MTL_FIFO_SIZE_2K = 0x07,
+ XGMAC_MTL_FIFO_SIZE_4K = 0x0f,
+ XGMAC_MTL_FIFO_SIZE_8K = 0x1f,
+ XGMAC_MTL_FIFO_SIZE_16K = 0x3f,
+ XGMAC_MTL_FIFO_SIZE_32K = 0x7f,
+ XGMAC_MTL_FIFO_SIZE_64K = 0xff,
+ XGMAC_MTL_FIFO_SIZE_128K = 0x1ff,
+ XGMAC_MTL_FIFO_SIZE_256K = 0x3ff,
+};
+
+struct xgbe_mmc_stats {
+ /* Tx Stats */
+ u64 txoctetcount_gb;
+ u64 txframecount_gb;
+ u64 txbroadcastframes_g;
+ u64 txmulticastframes_g;
+ u64 tx64octets_gb;
+ u64 tx65to127octets_gb;
+ u64 tx128to255octets_gb;
+ u64 tx256to511octets_gb;
+ u64 tx512to1023octets_gb;
+ u64 tx1024tomaxoctets_gb;
+ u64 txunicastframes_gb;
+ u64 txmulticastframes_gb;
+ u64 txbroadcastframes_gb;
+ u64 txunderflowerror;
+ u64 txoctetcount_g;
+ u64 txframecount_g;
+ u64 txpauseframes;
+ u64 txvlanframes_g;
+
+ /* Rx Stats */
+ u64 rxframecount_gb;
+ u64 rxoctetcount_gb;
+ u64 rxoctetcount_g;
+ u64 rxbroadcastframes_g;
+ u64 rxmulticastframes_g;
+ u64 rxcrcerror;
+ u64 rxrunterror;
+ u64 rxjabbererror;
+ u64 rxundersize_g;
+ u64 rxoversize_g;
+ u64 rx64octets_gb;
+ u64 rx65to127octets_gb;
+ u64 rx128to255octets_gb;
+ u64 rx256to511octets_gb;
+ u64 rx512to1023octets_gb;
+ u64 rx1024tomaxoctets_gb;
+ u64 rxunicastframes_g;
+ u64 rxlengtherror;
+ u64 rxoutofrangetype;
+ u64 rxpauseframes;
+ u64 rxfifooverflow;
+ u64 rxvlanframes_gb;
+ u64 rxwatchdogerror;
+};
+
+struct xgbe_hw_if {
+ int (*tx_complete)(struct xgbe_ring_desc *);
+
+ int (*set_promiscuous_mode)(struct xgbe_prv_data *, unsigned int);
+ int (*set_all_multicast_mode)(struct xgbe_prv_data *, unsigned int);
+ int (*set_addn_mac_addrs)(struct xgbe_prv_data *, unsigned int);
+ int (*set_mac_address)(struct xgbe_prv_data *, u8 *addr);
+
+ int (*enable_rx_csum)(struct xgbe_prv_data *);
+ int (*disable_rx_csum)(struct xgbe_prv_data *);
+
+ int (*enable_rx_vlan_stripping)(struct xgbe_prv_data *);
+ int (*disable_rx_vlan_stripping)(struct xgbe_prv_data *);
+
+ int (*read_mmd_regs)(struct xgbe_prv_data *, int, int);
+ void (*write_mmd_regs)(struct xgbe_prv_data *, int, int, int);
+ int (*set_gmii_speed)(struct xgbe_prv_data *);
+ int (*set_gmii_2500_speed)(struct xgbe_prv_data *);
+ int (*set_xgmii_speed)(struct xgbe_prv_data *);
+
+ void (*enable_tx)(struct xgbe_prv_data *);
+ void (*disable_tx)(struct xgbe_prv_data *);
+ void (*enable_rx)(struct xgbe_prv_data *);
+ void (*disable_rx)(struct xgbe_prv_data *);
+
+ void (*powerup_tx)(struct xgbe_prv_data *);
+ void (*powerdown_tx)(struct xgbe_prv_data *);
+ void (*powerup_rx)(struct xgbe_prv_data *);
+ void (*powerdown_rx)(struct xgbe_prv_data *);
+
+ int (*init)(struct xgbe_prv_data *);
+ int (*exit)(struct xgbe_prv_data *);
+
+ int (*enable_int)(struct xgbe_channel *, enum xgbe_int);
+ int (*disable_int)(struct xgbe_channel *, enum xgbe_int);
+ void (*pre_xmit)(struct xgbe_channel *);
+ int (*dev_read)(struct xgbe_channel *);
+ void (*tx_desc_init)(struct xgbe_channel *);
+ void (*rx_desc_init)(struct xgbe_channel *);
+ void (*rx_desc_reset)(struct xgbe_ring_data *);
+ void (*tx_desc_reset)(struct xgbe_ring_data *);
+ int (*is_last_desc)(struct xgbe_ring_desc *);
+ int (*is_context_desc)(struct xgbe_ring_desc *);
+
+ /* For FLOW ctrl */
+ int (*config_tx_flow_control)(struct xgbe_prv_data *);
+ int (*config_rx_flow_control)(struct xgbe_prv_data *);
+
+ /* For RX coalescing */
+ int (*config_rx_coalesce)(struct xgbe_prv_data *);
+ int (*config_tx_coalesce)(struct xgbe_prv_data *);
+ unsigned int (*usec_to_riwt)(struct xgbe_prv_data *, unsigned int);
+ unsigned int (*riwt_to_usec)(struct xgbe_prv_data *, unsigned int);
+
+ /* For RX and TX threshold config */
+ int (*config_rx_threshold)(struct xgbe_prv_data *, unsigned int);
+ int (*config_tx_threshold)(struct xgbe_prv_data *, unsigned int);
+
+ /* For RX and TX Store and Forward Mode config */
+ int (*config_rsf_mode)(struct xgbe_prv_data *, unsigned int);
+ int (*config_tsf_mode)(struct xgbe_prv_data *, unsigned int);
+
+ /* For TX DMA Operate on Second Frame config */
+ int (*config_osp_mode)(struct xgbe_prv_data *);
+
+ /* For RX and TX PBL config */
+ int (*config_rx_pbl_val)(struct xgbe_prv_data *);
+ int (*get_rx_pbl_val)(struct xgbe_prv_data *);
+ int (*config_tx_pbl_val)(struct xgbe_prv_data *);
+ int (*get_tx_pbl_val)(struct xgbe_prv_data *);
+ int (*config_pblx8)(struct xgbe_prv_data *);
+
+ /* For MMC statistics */
+ void (*rx_mmc_int)(struct xgbe_prv_data *);
+ void (*tx_mmc_int)(struct xgbe_prv_data *);
+ void (*read_mmc_stats)(struct xgbe_prv_data *);
+};
+
+struct xgbe_desc_if {
+ int (*alloc_ring_resources)(struct xgbe_prv_data *);
+ void (*free_ring_resources)(struct xgbe_prv_data *);
+ int (*map_tx_skb)(struct xgbe_channel *, struct sk_buff *);
+ void (*realloc_skb)(struct xgbe_channel *);
+ void (*unmap_skb)(struct xgbe_prv_data *, struct xgbe_ring_data *);
+ void (*wrapper_tx_desc_init)(struct xgbe_prv_data *);
+ void (*wrapper_rx_desc_init)(struct xgbe_prv_data *);
+};
+
+/* This structure contains flags that indicate what hardware features
+ * or configurations are present in the device.
+ */
+struct xgbe_hw_features {
+ /* HW Feature Register0 */
+ unsigned int gmii; /* 1000 Mbps support */
+ unsigned int vlhash; /* VLAN Hash Filter */
+ unsigned int sma; /* SMA(MDIO) Interface */
+ unsigned int rwk; /* PMT remote wake-up packet */
+ unsigned int mgk; /* PMT magic packet */
+ unsigned int mmc; /* RMON module */
+ unsigned int aoe; /* ARP Offload */
+ unsigned int ts; /* IEEE 1588-2008 Adavanced Timestamp */
+ unsigned int eee; /* Energy Efficient Ethernet */
+ unsigned int tx_coe; /* Tx Checksum Offload */
+ unsigned int rx_coe; /* Rx Checksum Offload */
+ unsigned int addn_mac; /* Additional MAC Addresses */
+ unsigned int ts_src; /* Timestamp Source */
+ unsigned int sa_vlan_ins; /* Source Address or VLAN Insertion */
+
+ /* HW Feature Register1 */
+ unsigned int rx_fifo_size; /* MTL Receive FIFO Size */
+ unsigned int tx_fifo_size; /* MTL Transmit FIFO Size */
+ unsigned int adv_ts_hi; /* Advance Timestamping High Word */
+ unsigned int dcb; /* DCB Feature */
+ unsigned int sph; /* Split Header Feature */
+ unsigned int tso; /* TCP Segmentation Offload */
+ unsigned int dma_debug; /* DMA Debug Registers */
+ unsigned int rss; /* Receive Side Scaling */
+ unsigned int hash_table_size; /* Hash Table Size */
+ unsigned int l3l4_filter_num; /* Number of L3-L4 Filters */
+
+ /* HW Feature Register2 */
+ unsigned int rx_q_cnt; /* Number of MTL Receive Queues */
+ unsigned int tx_q_cnt; /* Number of MTL Transmit Queues */
+ unsigned int rx_ch_cnt; /* Number of DMA Receive Channels */
+ unsigned int tx_ch_cnt; /* Number of DMA Transmit Channels */
+ unsigned int pps_out_num; /* Number of PPS outputs */
+ unsigned int aux_snap_num; /* Number of Aux snapshot inputs */
+};
+
+struct xgbe_prv_data {
+ struct net_device *netdev;
+ struct platform_device *pdev;
+ struct device *dev;
+
+ /* XGMAC/XPCS related mmio registers */
+ void __iomem *xgmac_regs; /* XGMAC CSRs */
+ void __iomem *xpcs_regs; /* XPCS MMD registers */
+
+ /* Overall device lock */
+ spinlock_t lock;
+
+ /* XPCS indirect addressing mutex */
+ struct mutex xpcs_mutex;
+
+ int irq_number;
+
+ struct xgbe_hw_if hw_if;
+ struct xgbe_desc_if desc_if;
+
+ /* Rings for Tx/Rx on a DMA channel */
+ struct xgbe_channel *channel;
+ unsigned int channel_count;
+ unsigned int tx_ring_count;
+ unsigned int tx_desc_count;
+ unsigned int rx_ring_count;
+ unsigned int rx_desc_count;
+
+ /* Tx/Rx common settings */
+ unsigned int pblx8;
+
+ /* Tx settings */
+ unsigned int tx_sf_mode;
+ unsigned int tx_threshold;
+ unsigned int tx_pbl;
+ unsigned int tx_osp_mode;
+
+ /* Rx settings */
+ unsigned int rx_sf_mode;
+ unsigned int rx_threshold;
+ unsigned int rx_pbl;
+
+ /* Tx coalescing settings */
+ unsigned int tx_usecs;
+ unsigned int tx_frames;
+
+ /* Rx coalescing settings */
+ unsigned int rx_riwt;
+ unsigned int rx_frames;
+
+ /* Current MTU */
+ unsigned int rx_buf_size;
+
+ /* Flow control settings */
+ unsigned int pause_autoneg;
+ unsigned int tx_pause;
+ unsigned int rx_pause;
+
+ /* MDIO settings */
+ struct module *phy_module;
+ char *mii_bus_id;
+ struct mii_bus *mii;
+ int mdio_mmd;
+ struct phy_device *phydev;
+ int default_autoneg;
+ int default_speed;
+
+ /* Current PHY settings */
+ phy_interface_t phy_mode;
+ int phy_link;
+ int phy_speed;
+ unsigned int phy_tx_pause;
+ unsigned int phy_rx_pause;
+
+ /* Netdev related settings */
+ netdev_features_t netdev_features;
+ struct napi_struct napi;
+ struct xgbe_mmc_stats mmc_stats;
+
+ /* System clock value used for Rx watchdog */
+ struct clk *sysclock;
+
+ /* Hardware features of the device */
+ struct xgbe_hw_features hw_feat;
+
+ /* Device restart work structure */
+ struct work_struct restart_work;
+
+ /* Keeps track of power mode */
+ unsigned int power_down;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *xgbe_debugfs;
+
+ unsigned int debugfs_xgmac_reg;
+
+ unsigned int debugfs_xpcs_mmd;
+ unsigned int debugfs_xpcs_reg;
+#endif
+};
+
+/* Function prototypes*/
+
+void xgbe_init_function_ptrs_dev(struct xgbe_hw_if *);
+void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *);
+struct net_device_ops *xgbe_get_netdev_ops(void);
+struct ethtool_ops *xgbe_get_ethtool_ops(void);
+
+int xgbe_mdio_register(struct xgbe_prv_data *);
+void xgbe_mdio_unregister(struct xgbe_prv_data *);
+void xgbe_dump_phy_registers(struct xgbe_prv_data *);
+void xgbe_dump_tx_desc(struct xgbe_ring *, unsigned int, unsigned int,
+ unsigned int);
+void xgbe_dump_rx_desc(struct xgbe_ring *, struct xgbe_ring_desc *,
+ unsigned int);
+void xgbe_print_pkt(struct net_device *, struct sk_buff *, bool);
+void xgbe_get_all_hw_features(struct xgbe_prv_data *);
+int xgbe_powerup(struct net_device *, unsigned int);
+int xgbe_powerdown(struct net_device *, unsigned int);
+void xgbe_init_rx_coalesce(struct xgbe_prv_data *);
+void xgbe_init_tx_coalesce(struct xgbe_prv_data *);
+
+#ifdef CONFIG_DEBUG_FS
+void xgbe_debugfs_init(struct xgbe_prv_data *);
+void xgbe_debugfs_exit(struct xgbe_prv_data *);
+#else
+static inline void xgbe_debugfs_init(struct xgbe_prv_data *pdata) {}
+static inline void xgbe_debugfs_exit(struct xgbe_prv_data *pdata) {}
+#endif /* CONFIG_DEBUG_FS */
+
+/* NOTE: Uncomment for TX and RX DESCRIPTOR DUMP in KERNEL LOG */
+#if 0
+#define XGMAC_ENABLE_TX_DESC_DUMP
+#define XGMAC_ENABLE_RX_DESC_DUMP
+#endif
+
+/* NOTE: Uncomment for TX and RX PACKET DUMP in KERNEL LOG */
+#if 0
+#define XGMAC_ENABLE_TX_PKT_DUMP
+#define XGMAC_ENABLE_RX_PKT_DUMP
+#endif
+
+/* NOTE: Uncomment for function trace log messages in KERNEL LOG */
+#if 0
+#define YDEBUG
+#define YDEBUG_MDIO
+#endif
+
+/* For debug prints */
+#ifdef YDEBUG
+#define DBGPR(x...) pr_alert(x)
+#define DBGPHY_REGS(x...) xgbe_dump_phy_registers(x)
+#else
+#define DBGPR(x...) do { } while (0)
+#define DBGPHY_REGS(x...) do { } while (0)
+#endif
+
+#ifdef YDEBUG_MDIO
+#define DBGPR_MDIO(x...) pr_alert(x)
+#else
+#define DBGPR_MDIO(x...) do { } while (0)
+#endif
+
+#endif
diff --git a/drivers/net/ethernet/apple/Kconfig b/drivers/net/ethernet/apple/Kconfig
new file mode 100644
index 00000000000..1375e2dc946
--- /dev/null
+++ b/drivers/net/ethernet/apple/Kconfig
@@ -0,0 +1,65 @@
+#
+# Apple device configuration
+#
+
+config NET_VENDOR_APPLE
+ bool "Apple devices"
+ default y
+ depends on (PPC_PMAC && PPC32) || MAC
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about IBM devices. If you say Y, you will be asked for
+ your specific card in the following questions.
+
+if NET_VENDOR_APPLE
+
+config MACE
+ tristate "MACE (Power Mac ethernet) support"
+ depends on PPC_PMAC && PPC32
+ select CRC32
+ ---help---
+ Power Macintoshes and clones with Ethernet built-in on the
+ motherboard will usually use a MACE (Medium Access Control for
+ Ethernet) interface. Say Y to include support for the MACE chip.
+
+ To compile this driver as a module, choose M here: the module
+ will be called mace.
+
+config MACE_AAUI_PORT
+ bool "Use AAUI port instead of TP by default"
+ depends on MACE
+ ---help---
+ Some Apple machines (notably the Apple Network Server) which use the
+ MACE ethernet chip have an Apple AUI port (small 15-pin connector),
+ instead of an 8-pin RJ45 connector for twisted-pair ethernet. Say
+ Y here if you have such a machine. If unsure, say N.
+ The driver will default to AAUI on ANS anyway, and if you use it as
+ a module, you can provide the port_aaui=0|1 to force the driver.
+
+config BMAC
+ tristate "BMAC (G3 ethernet) support"
+ depends on PPC_PMAC && PPC32
+ select CRC32
+ ---help---
+ Say Y for support of BMAC Ethernet interfaces. These are used on G3
+ computers.
+
+ To compile this driver as a module, choose M here: the module
+ will be called bmac.
+
+config MACMACE
+ bool "Macintosh (AV) onboard MACE ethernet"
+ depends on MAC
+ select CRC32
+ ---help---
+ Support for the onboard AMD 79C940 MACE Ethernet controller used in
+ the 660AV and 840AV Macintosh. If you have one of these Macintoshes
+ say Y and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+endif # NET_VENDOR_APPLE
diff --git a/drivers/net/ethernet/apple/Makefile b/drivers/net/ethernet/apple/Makefile
new file mode 100644
index 00000000000..86eaa17af0f
--- /dev/null
+++ b/drivers/net/ethernet/apple/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the Apple network device drivers.
+#
+
+obj-$(CONFIG_MACE) += mace.o
+obj-$(CONFIG_BMAC) += bmac.o
+obj-$(CONFIG_MACMACE) += macmace.o
diff --git a/drivers/net/bmac.c b/drivers/net/ethernet/apple/bmac.c
index a42bd19646d..daae0e01625 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/ethernet/apple/bmac.c
@@ -7,6 +7,7 @@
* May 1999, Al Viro: proper release of /proc/net/bmac entry, switched to
* dynamic procfs inode.
*/
+#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
@@ -20,6 +21,7 @@
#include <linux/crc32.h>
#include <linux/bitrev.h>
#include <linux/ethtool.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
@@ -166,7 +168,6 @@ static inline void
dbdma_st32(volatile __u32 __iomem *a, unsigned long x)
{
__asm__ volatile( "stwbrx %0,0,%1" : : "r" (x), "r" (a) : "memory");
- return;
}
static inline unsigned long
@@ -381,8 +382,6 @@ bmac_init_registers(struct net_device *dev)
bmwrite(dev, RXCFG, RxCRCNoStrip | RxHashFilterEnable | RxRejectOwnPackets);
bmwrite(dev, INTDISABLE, EnableNormal);
-
- return;
}
#if 0
@@ -428,17 +427,18 @@ bmac_init_phy(struct net_device *dev)
printk(KERN_DEBUG "phy registers:");
for (addr = 0; addr < 32; ++addr) {
if ((addr & 7) == 0)
- printk("\n" KERN_DEBUG);
- printk(" %.4x", bmac_mif_read(dev, addr));
+ printk(KERN_DEBUG);
+ printk(KERN_CONT " %.4x", bmac_mif_read(dev, addr));
}
- printk("\n");
+ printk(KERN_CONT "\n");
+
if (bp->is_bmac_plus) {
unsigned int capable, ctrl;
ctrl = bmac_mif_read(dev, 0);
capable = ((bmac_mif_read(dev, 1) & 0xf800) >> 6) | 1;
- if (bmac_mif_read(dev, 4) != capable
- || (ctrl & 0x1000) == 0) {
+ if (bmac_mif_read(dev, 4) != capable ||
+ (ctrl & 0x1000) == 0) {
bmac_mif_write(dev, 4, capable);
bmac_mif_write(dev, 0, 0x1200);
} else
@@ -607,8 +607,9 @@ bmac_init_tx_ring(struct bmac_data *bp)
}
static int
-bmac_init_rx_ring(struct bmac_data *bp)
+bmac_init_rx_ring(struct net_device *dev)
{
+ struct bmac_data *bp = netdev_priv(dev);
volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
int i;
struct sk_buff *skb;
@@ -618,7 +619,7 @@ bmac_init_rx_ring(struct bmac_data *bp)
(N_RX_RING + 1) * sizeof(struct dbdma_cmd));
for (i = 0; i < N_RX_RING; i++) {
if ((skb = bp->rx_bufs[i]) == NULL) {
- bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2);
+ bp->rx_bufs[i] = skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
if (skb != NULL)
skb_reserve(skb, 2);
}
@@ -716,15 +717,13 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id)
skb_put(skb, nb);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
++dev->stats.rx_packets;
dev->stats.rx_bytes += nb;
} else {
++dev->stats.rx_dropped;
}
- dev->last_rx = jiffies;
if ((skb = bp->rx_bufs[i]) == NULL) {
- bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2);
+ bp->rx_bufs[i] = skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
if (skb != NULL)
skb_reserve(bp->rx_bufs[i], 2);
}
@@ -972,9 +971,9 @@ bmac_remove_multi(struct net_device *dev,
*/
static void bmac_set_multicast(struct net_device *dev)
{
- struct dev_mc_list *dmi;
+ struct netdev_hw_addr *ha;
struct bmac_data *bp = netdev_priv(dev);
- int num_addrs = dev->mc_count;
+ int num_addrs = netdev_mc_count(dev);
unsigned short rx_cfg;
int i;
@@ -983,7 +982,7 @@ static void bmac_set_multicast(struct net_device *dev)
XXDEBUG(("bmac: enter bmac_set_multicast, n_addrs=%d\n", num_addrs));
- if((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+ if((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
for (i=0; i<4; i++) bp->hash_table_mask[i] = 0xffff;
bmac_update_hash_table_mask(dev, bp);
rx_cfg = bmac_rx_on(dev, 1, 0);
@@ -1001,8 +1000,8 @@ static void bmac_set_multicast(struct net_device *dev)
rx_cfg = bmac_rx_on(dev, 0, 0);
XXDEBUG(("bmac: multi disabled, rx_cfg=%#08x\n", rx_cfg));
} else {
- for (dmi=dev->mc_list; dmi!=NULL; dmi=dmi->next)
- bmac_addhash(bp, dmi->dmi_addr);
+ netdev_for_each_mc_addr(ha, dev)
+ bmac_addhash(bp, ha->addr);
bmac_update_hash_table_mask(dev, bp);
rx_cfg = bmac_rx_on(dev, 1, 0);
XXDEBUG(("bmac: multi enabled, rx_cfg=%#08x\n", rx_cfg));
@@ -1016,13 +1015,11 @@ static void bmac_set_multicast(struct net_device *dev)
static void bmac_set_multicast(struct net_device *dev)
{
- struct dev_mc_list *dmi = dev->mc_list;
- char *addrs;
- int i;
+ struct netdev_hw_addr *ha;
unsigned short rx_cfg;
u32 crc;
- if((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 64)) {
+ if((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
bmwrite(dev, BHASH0, 0xffff);
bmwrite(dev, BHASH1, 0xffff);
bmwrite(dev, BHASH2, 0xffff);
@@ -1032,22 +1029,14 @@ static void bmac_set_multicast(struct net_device *dev)
rx_cfg |= RxPromiscEnable;
bmwrite(dev, RXCFG, rx_cfg);
} else {
- u16 hash_table[4];
+ u16 hash_table[4] = { 0 };
rx_cfg = bmread(dev, RXCFG);
rx_cfg &= ~RxPromiscEnable;
bmwrite(dev, RXCFG, rx_cfg);
- for(i = 0; i < 4; i++) hash_table[i] = 0;
-
- for(i = 0; i < dev->mc_count; i++) {
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
-
- if(!(*addrs & 1))
- continue;
-
- crc = ether_crc_le(6, addrs);
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(6, ha->addr);
crc >>= 26;
hash_table[crc >> 4] |= 1 << (crc & 0xf);
}
@@ -1064,7 +1053,6 @@ static int miscintcount;
static irqreturn_t bmac_misc_intr(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct bmac_data *bp = netdev_priv(dev);
unsigned int status = bmread(dev, STATUS);
if (miscintcount++ < 10) {
XXDEBUG(("bmac_misc_intr\n"));
@@ -1218,7 +1206,7 @@ static void bmac_reset_and_enable(struct net_device *dev)
spin_lock_irqsave(&bp->lock, flags);
bmac_enable_and_reset_chip(dev);
bmac_init_tx_ring(bp);
- bmac_init_rx_ring(bp);
+ bmac_init_rx_ring(dev);
bmac_init_chip(dev);
bmac_start_chip(dev);
bmwrite(dev, INTDISABLE, EnableNormal);
@@ -1228,29 +1216,32 @@ static void bmac_reset_and_enable(struct net_device *dev)
* It seems that the bmac can't receive until it's transmitted
* a packet. So we give it a dummy packet to transmit.
*/
- skb = dev_alloc_skb(ETHERMINPACKET);
+ skb = netdev_alloc_skb(dev, ETHERMINPACKET);
if (skb != NULL) {
data = skb_put(skb, ETHERMINPACKET);
memset(data, 0, ETHERMINPACKET);
- memcpy(data, dev->dev_addr, 6);
- memcpy(data+6, dev->dev_addr, 6);
+ memcpy(data, dev->dev_addr, ETH_ALEN);
+ memcpy(data + ETH_ALEN, dev->dev_addr, ETH_ALEN);
bmac_transmit_packet(skb, dev);
}
spin_unlock_irqrestore(&bp->lock, flags);
}
-static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
- struct bmac_data *bp = netdev_priv(dev);
- strcpy(info->driver, "bmac");
- strcpy(info->bus_info, bp->mdev->ofdev.dev.bus_id);
-}
static const struct ethtool_ops bmac_ethtool_ops = {
- .get_drvinfo = bmac_get_drvinfo,
.get_link = ethtool_op_get_link,
};
-static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
+static const struct net_device_ops bmac_netdev_ops = {
+ .ndo_open = bmac_open,
+ .ndo_stop = bmac_close,
+ .ndo_start_xmit = bmac_output,
+ .ndo_set_rx_mode = bmac_set_multicast,
+ .ndo_set_mac_address = bmac_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static int bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
int j, rev, ret;
struct bmac_data *bp;
@@ -1258,7 +1249,6 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
unsigned char addr[6];
struct net_device *dev;
int is_bmac_plus = ((int)match->data) != 0;
- DECLARE_MAC_BUF(mac);
if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) {
printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n");
@@ -1277,10 +1267,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
memcpy(addr, prop_addr, sizeof(addr));
dev = alloc_etherdev(PRIV_BYTES);
- if (!dev) {
- printk(KERN_ERR "BMAC: alloc_etherdev failed, out of memory\n");
+ if (!dev)
return -ENOMEM;
- }
bp = netdev_priv(dev);
SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
@@ -1312,12 +1300,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
bmac_enable_and_reset_chip(dev);
bmwrite(dev, INTDISABLE, DisableAll);
- dev->open = bmac_open;
- dev->stop = bmac_close;
+ dev->netdev_ops = &bmac_netdev_ops;
dev->ethtool_ops = &bmac_ethtool_ops;
- dev->hard_start_xmit = bmac_output;
- dev->set_multicast_list = bmac_set_multicast;
- dev->set_mac_address = bmac_set_address;
bmac_get_station_address(dev, addr);
if (bmac_verify_checksum(dev) != 0)
@@ -1368,8 +1352,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
goto err_out_irq2;
}
- printk(KERN_INFO "%s: BMAC%s at %s",
- dev->name, (is_bmac_plus ? "+" : ""), print_mac(mac, dev->dev_addr));
+ printk(KERN_INFO "%s: BMAC%s at %pM",
+ dev->name, (is_bmac_plus ? "+" : ""), dev->dev_addr);
XXDEBUG((", base_addr=%#0lx", dev->base_addr));
printk("\n");
@@ -1486,7 +1470,7 @@ bmac_output(struct sk_buff *skb, struct net_device *dev)
struct bmac_data *bp = netdev_priv(dev);
skb_queue_tail(bp->queue, skb);
bmac_start(dev);
- return 0;
+ return NETDEV_TX_OK;
}
static void bmac_tx_timeout(unsigned long data)
@@ -1588,7 +1572,7 @@ bmac_proc_info(char *buffer, char **start, off_t offset, int length)
int i;
if (bmac_devs == NULL)
- return (-ENOSYS);
+ return -ENOSYS;
len += sprintf(buffer, "BMAC counters & registers\n");
@@ -1615,7 +1599,7 @@ bmac_proc_info(char *buffer, char **start, off_t offset, int length)
}
#endif
-static int __devexit bmac_remove(struct macio_dev *mdev)
+static int bmac_remove(struct macio_dev *mdev)
{
struct net_device *dev = macio_get_drvdata(mdev);
struct bmac_data *bp = netdev_priv(dev);
@@ -1654,8 +1638,11 @@ MODULE_DEVICE_TABLE (of, bmac_match);
static struct macio_driver bmac_driver =
{
- .name = "bmac",
- .match_table = bmac_match,
+ .driver = {
+ .name = "bmac",
+ .owner = THIS_MODULE,
+ .of_match_table = bmac_match,
+ },
.probe = bmac_probe,
.remove = bmac_remove,
#ifdef CONFIG_PM
@@ -1669,10 +1656,8 @@ static int __init bmac_init(void)
{
if (bmac_emergency_rxbuf == NULL) {
bmac_emergency_rxbuf = kmalloc(RX_BUFLEN, GFP_KERNEL);
- if (bmac_emergency_rxbuf == NULL) {
- printk(KERN_ERR "BMAC: can't allocate emergency RX buffer\n");
+ if (bmac_emergency_rxbuf == NULL)
return -ENOMEM;
- }
}
return macio_register_driver(&bmac_driver);
diff --git a/drivers/net/bmac.h b/drivers/net/ethernet/apple/bmac.h
index a1d19d867ba..a1d19d867ba 100644
--- a/drivers/net/bmac.h
+++ b/drivers/net/ethernet/apple/bmac.h
diff --git a/drivers/net/mace.c b/drivers/net/ethernet/apple/mace.c
index 451acdca2a2..842fe768490 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/ethernet/apple/mace.c
@@ -13,9 +13,11 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/crc32.h>
#include <linux/spinlock.h>
#include <linux/bitrev.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/dbdma.h>
#include <asm/io.h>
@@ -94,14 +96,23 @@ static void __mace_set_address(struct net_device *dev, void *addr);
*/
static unsigned char *dummy_buf;
-static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_xmit_start,
+ .ndo_set_rx_mode = mace_set_multicast,
+ .ndo_set_mac_address = mace_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static int mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
{
struct device_node *mace = macio_get_of_node(mdev);
struct net_device *dev;
struct mace_data *mp;
const unsigned char *addr;
int j, rev, rc = -EBUSY;
- DECLARE_MAC_BUF(mac);
if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) {
printk(KERN_ERR "can't use MACE %s: need 3 addrs and 3 irqs\n",
@@ -125,10 +136,8 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
*/
if (dummy_buf == NULL) {
dummy_buf = kmalloc(RX_BUFLEN+2, GFP_KERNEL);
- if (dummy_buf == NULL) {
- printk(KERN_ERR "MACE: couldn't allocate dummy buffer\n");
+ if (dummy_buf == NULL)
return -ENOMEM;
- }
}
if (macio_request_resources(mdev, "mace")) {
@@ -138,13 +147,12 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
dev = alloc_etherdev(PRIV_BYTES);
if (!dev) {
- printk(KERN_ERR "MACE: can't allocate ethernet device !\n");
rc = -ENOMEM;
goto err_release;
}
SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
- mp = dev->priv;
+ mp = netdev_priv(dev);
mp->mdev = mdev;
macio_set_drvdata(mdev, dev);
@@ -165,7 +173,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
in_8(&mp->mace->chipid_lo);
- mp = (struct mace_data *) dev->priv;
+ mp = netdev_priv(dev);
mp->maccc = ENXMT | ENRCV;
mp->tx_dma = ioremap(macio_resource_start(mdev, 1), 0x1000);
@@ -197,7 +205,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
mp->port_aaui = port_aaui;
else {
/* Apple Network Server uses the AAUI port */
- if (machine_is_compatible("AAPL,ShinerESB"))
+ if (of_machine_is_compatible("AAPL,ShinerESB"))
mp->port_aaui = 1;
else {
#ifdef CONFIG_MACE_AAUI_PORT
@@ -208,11 +216,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
}
}
- dev->open = mace_open;
- dev->stop = mace_close;
- dev->hard_start_xmit = mace_xmit_start;
- dev->set_multicast_list = mace_set_multicast;
- dev->set_mac_address = mace_set_address;
+ dev->netdev_ops = &mace_netdev_ops;
/*
* Most of what is below could be moved to mace_open()
@@ -241,8 +245,8 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
goto err_free_rx_irq;
}
- printk(KERN_INFO "%s: MACE at %s, chip revision %d.%d\n",
- dev->name, print_mac(mac, dev->dev_addr),
+ printk(KERN_INFO "%s: MACE at %pM, chip revision %d.%d\n",
+ dev->name, dev->dev_addr,
mp->chipid >> 8, mp->chipid & 0xff);
return 0;
@@ -267,7 +271,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
return rc;
}
-static int __devexit mace_remove(struct macio_dev *mdev)
+static int mace_remove(struct macio_dev *mdev)
{
struct net_device *dev = macio_get_drvdata(mdev);
struct mace_data *mp;
@@ -276,7 +280,7 @@ static int __devexit mace_remove(struct macio_dev *mdev)
macio_set_drvdata(mdev, NULL);
- mp = dev->priv;
+ mp = netdev_priv(dev);
unregister_netdev(dev);
@@ -312,7 +316,7 @@ static void dbdma_reset(volatile struct dbdma_regs __iomem *dma)
static void mace_reset(struct net_device *dev)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
int i;
@@ -367,7 +371,7 @@ static void mace_reset(struct net_device *dev)
static void __mace_set_address(struct net_device *dev, void *addr)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
unsigned char *p = addr;
int i;
@@ -388,7 +392,7 @@ static void __mace_set_address(struct net_device *dev, void *addr)
static int mace_set_address(struct net_device *dev, void *addr)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
unsigned long flags;
@@ -423,7 +427,7 @@ static inline void mace_clean_rings(struct mace_data *mp)
static int mace_open(struct net_device *dev)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
volatile struct dbdma_regs __iomem *td = mp->tx_dma;
@@ -440,7 +444,7 @@ static int mace_open(struct net_device *dev)
memset((char *)mp->rx_cmds, 0, N_RX_RING * sizeof(struct dbdma_cmd));
cp = mp->rx_cmds;
for (i = 0; i < N_RX_RING - 1; ++i) {
- skb = dev_alloc_skb(RX_BUFLEN + 2);
+ skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
if (!skb) {
data = dummy_buf;
} else {
@@ -493,7 +497,7 @@ static int mace_open(struct net_device *dev)
static int mace_close(struct net_device *dev)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
volatile struct dbdma_regs __iomem *td = mp->tx_dma;
@@ -513,7 +517,7 @@ static int mace_close(struct net_device *dev)
static inline void mace_set_timeout(struct net_device *dev)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
if (mp->timeout_active)
del_timer(&mp->tx_timeout);
@@ -526,7 +530,7 @@ static inline void mace_set_timeout(struct net_device *dev)
static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct dbdma_regs __iomem *td = mp->tx_dma;
volatile struct dbdma_cmd *cp, *np;
unsigned long flags;
@@ -542,7 +546,7 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
mp->tx_fullup = 1;
spin_unlock_irqrestore(&mp->lock, flags);
- return 1; /* can't take it at the moment */
+ return NETDEV_TX_BUSY; /* can't take it at the moment */
}
spin_unlock_irqrestore(&mp->lock, flags);
@@ -576,14 +580,14 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
spin_unlock_irqrestore(&mp->lock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
static void mace_set_multicast(struct net_device *dev)
{
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
- int i, j;
+ int i;
u32 crc;
unsigned long flags;
@@ -593,7 +597,7 @@ static void mace_set_multicast(struct net_device *dev)
mp->maccc |= PROM;
} else {
unsigned char multicast_filter[8];
- struct dev_mc_list *dmi = dev->mc_list;
+ struct netdev_hw_addr *ha;
if (dev->flags & IFF_ALLMULTI) {
for (i = 0; i < 8; i++)
@@ -601,11 +605,10 @@ static void mace_set_multicast(struct net_device *dev)
} else {
for (i = 0; i < 8; i++)
multicast_filter[i] = 0;
- for (i = 0; i < dev->mc_count; i++) {
- crc = ether_crc_le(6, dmi->dmi_addr);
- j = crc >> 26; /* bit number in multicast_filter */
- multicast_filter[j >> 3] |= 1 << (j & 7);
- dmi = dmi->next;
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(6, ha->addr);
+ i = crc >> 26; /* bit number in multicast_filter */
+ multicast_filter[i >> 3] |= 1 << (i & 7);
}
}
#if 0
@@ -656,7 +659,7 @@ static void mace_handle_misc_intrs(struct mace_data *mp, int intr, struct net_de
static irqreturn_t mace_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
volatile struct dbdma_regs __iomem *td = mp->tx_dma;
volatile struct dbdma_cmd *cp;
@@ -802,7 +805,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
static void mace_tx_timeout(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct mace __iomem *mb = mp->mace;
volatile struct dbdma_regs __iomem *td = mp->tx_dma;
volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
@@ -873,7 +876,7 @@ static irqreturn_t mace_txdma_intr(int irq, void *dev_id)
static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct mace_data *mp = (struct mace_data *) dev->priv;
+ struct mace_data *mp = netdev_priv(dev);
volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
volatile struct dbdma_cmd *cp, *np;
int i, nb, stat, next;
@@ -892,8 +895,8 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
if (next >= N_RX_RING)
next = 0;
np = mp->rx_cmds + next;
- if (next != mp->rx_fill
- && (ld_le16(&np->xfer_status) & ACTIVE) != 0) {
+ if (next != mp->rx_fill &&
+ (ld_le16(&np->xfer_status) & ACTIVE) != 0) {
printk(KERN_DEBUG "mace: lost a status word\n");
++mace_lost_status;
} else
@@ -929,7 +932,6 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
skb->protocol = eth_type_trans(skb, dev);
dev->stats.rx_bytes += skb->len;
netif_rx(skb);
- dev->last_rx = jiffies;
mp->rx_bufs[i] = NULL;
++dev->stats.rx_packets;
}
@@ -954,7 +956,7 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
cp = mp->rx_cmds + i;
skb = mp->rx_bufs[i];
if (!skb) {
- skb = dev_alloc_skb(RX_BUFLEN + 2);
+ skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
if (skb) {
skb_reserve(skb, 2);
mp->rx_bufs[i] = skb;
@@ -993,8 +995,11 @@ MODULE_DEVICE_TABLE (of, mace_match);
static struct macio_driver mace_driver =
{
- .name = "mace",
- .match_table = mace_match,
+ .driver = {
+ .name = "mace",
+ .owner = THIS_MODULE,
+ .of_match_table = mace_match,
+ },
.probe = mace_probe,
.remove = mace_remove,
};
diff --git a/drivers/net/mace.h b/drivers/net/ethernet/apple/mace.h
index 30b7ec0cedb..30b7ec0cedb 100644
--- a/drivers/net/mace.h
+++ b/drivers/net/ethernet/apple/mace.h
diff --git a/drivers/net/macmace.c b/drivers/net/ethernet/apple/macmace.c
index 51ad3765e07..58a200df4c3 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/ethernet/apple/macmace.c
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*
* Copyright (C) 1996 Paul Mackerras.
- * Copyright (C) 1998 Alan Cox <alan@redhat.com>
+ * Copyright (C) 1998 Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* Modified heavily by Joshua M. Thompson based on Dave Huang's NetBSD driver
*
@@ -30,16 +30,15 @@
#include <linux/bitrev.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/gfp.h>
+#include <linux/interrupt.h>
#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_psc.h>
#include <asm/page.h>
#include "mace.h"
static char mac_mace_string[] = "macmace";
-static struct platform_device *mac_mace_device;
#define N_TX_BUFF_ORDER 0
#define N_TX_RING (1 << N_TX_BUFF_ORDER)
@@ -180,26 +179,30 @@ static void mace_dma_off(struct net_device *dev)
psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
}
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_xmit_start,
+ .ndo_tx_timeout = mace_tx_timeout,
+ .ndo_set_rx_mode = mace_set_multicast,
+ .ndo_set_mac_address = mace_set_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* Not really much of a probe. The hardware table tells us if this
* model of Macintrash has a MACE (AV macintoshes)
*/
-static int __devinit mace_probe(struct platform_device *pdev)
+static int mace_probe(struct platform_device *pdev)
{
int j;
struct mace_data *mp;
unsigned char *addr;
struct net_device *dev;
unsigned char checksum = 0;
- static int found = 0;
int err;
- DECLARE_MAC_BUF(mac);
-
- if (found || macintosh_config->ether_type != MAC_ETHER_MACE)
- return -ENODEV;
-
- found = 1; /* prevent 'finding' one on every device probe */
dev = alloc_etherdev(PRIV_BYTES);
if (!dev)
@@ -208,10 +211,11 @@ static int __devinit mace_probe(struct platform_device *pdev)
mp = netdev_priv(dev);
mp->device = &pdev->dev;
+ platform_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
dev->base_addr = (u32)MACE_BASE;
- mp->mace = (volatile struct mace *) MACE_BASE;
+ mp->mace = MACE_BASE;
dev->irq = IRQ_MAC_MACE;
mp->dma_intr = IRQ_MAC_MACE_DMA;
@@ -225,7 +229,7 @@ static int __devinit mace_probe(struct platform_device *pdev)
* bits are reversed.
*/
- addr = (void *)MACE_PROM;
+ addr = MACE_PROM;
for (j = 0; j < 6; ++j) {
u8 v = bitrev8(addr[j<<4]);
@@ -241,16 +245,11 @@ static int __devinit mace_probe(struct platform_device *pdev)
return -ENODEV;
}
- dev->open = mace_open;
- dev->stop = mace_close;
- dev->hard_start_xmit = mace_xmit_start;
- dev->tx_timeout = mace_tx_timeout;
+ dev->netdev_ops = &mace_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->set_multicast_list = mace_set_multicast;
- dev->set_mac_address = mace_set_address;
- printk(KERN_INFO "%s: 68K MACE, hardware address %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
+ printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n",
+ dev->name, dev->dev_addr);
err = register_netdev(dev);
if (!err)
@@ -388,20 +387,16 @@ static int mace_open(struct net_device *dev)
/* Allocate the DMA ring buffers */
mp->tx_ring = dma_alloc_coherent(mp->device,
- N_TX_RING * MACE_BUFF_SIZE,
- &mp->tx_ring_phys, GFP_KERNEL);
- if (mp->tx_ring == NULL) {
- printk(KERN_ERR "%s: unable to allocate DMA tx buffers\n", dev->name);
+ N_TX_RING * MACE_BUFF_SIZE,
+ &mp->tx_ring_phys, GFP_KERNEL);
+ if (mp->tx_ring == NULL)
goto out1;
- }
mp->rx_ring = dma_alloc_coherent(mp->device,
- N_RX_RING * MACE_BUFF_SIZE,
- &mp->rx_ring_phys, GFP_KERNEL);
- if (mp->rx_ring == NULL) {
- printk(KERN_ERR "%s: unable to allocate DMA rx buffers\n", dev->name);
+ N_RX_RING * MACE_BUFF_SIZE,
+ &mp->rx_ring_phys, GFP_KERNEL);
+ if (mp->rx_ring == NULL)
goto out2;
- }
mace_dma_off(dev);
@@ -483,7 +478,6 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb(skb);
- dev->trans_start = jiffies;
return NETDEV_TX_OK;
}
@@ -491,7 +485,7 @@ static void mace_set_multicast(struct net_device *dev)
{
struct mace_data *mp = netdev_priv(dev);
volatile struct mace *mb = mp->mace;
- int i, j;
+ int i;
u32 crc;
u8 maccc;
unsigned long flags;
@@ -504,7 +498,7 @@ static void mace_set_multicast(struct net_device *dev)
mb->maccc |= PROM;
} else {
unsigned char multicast_filter[8];
- struct dev_mc_list *dmi = dev->mc_list;
+ struct netdev_hw_addr *ha;
if (dev->flags & IFF_ALLMULTI) {
for (i = 0; i < 8; i++) {
@@ -513,11 +507,11 @@ static void mace_set_multicast(struct net_device *dev)
} else {
for (i = 0; i < 8; i++)
multicast_filter[i] = 0;
- for (i = 0; i < dev->mc_count; i++) {
- crc = ether_crc_le(6, dmi->dmi_addr);
- j = crc >> 26; /* bit number in multicast_filter */
- multicast_filter[j >> 3] |= 1 << (j & 7);
- dmi = dmi->next;
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(6, ha->addr);
+ /* bit number in multicast_filter */
+ i = crc >> 26;
+ multicast_filter[i >> 3] |= 1 << (i & 7);
}
}
@@ -664,7 +658,7 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
} else {
unsigned int frame_length = mf->rcvcnt + ((frame_status & 0x0F) << 8 );
- skb = dev_alloc_skb(frame_length + 2);
+ skb = netdev_alloc_skb(dev, frame_length + 2);
if (!skb) {
dev->stats.rx_dropped++;
return;
@@ -674,7 +668,6 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes += frame_length;
}
@@ -748,8 +741,9 @@ static irqreturn_t mace_dma_intr(int irq, void *dev_id)
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Macintosh MACE ethernet driver");
+MODULE_ALIAS("platform:macmace");
-static int __devexit mac_mace_device_remove (struct platform_device *pdev)
+static int mac_mace_device_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct mace_data *mp = netdev_priv(dev);
@@ -771,49 +765,24 @@ static int __devexit mac_mace_device_remove (struct platform_device *pdev)
static struct platform_driver mac_mace_driver = {
.probe = mace_probe,
- .remove = __devexit_p(mac_mace_device_remove),
+ .remove = mac_mace_device_remove,
.driver = {
- .name = mac_mace_string,
+ .name = mac_mace_string,
+ .owner = THIS_MODULE,
},
};
static int __init mac_mace_init_module(void)
{
- int err;
-
if (!MACH_IS_MAC)
return -ENODEV;
- if ((err = platform_driver_register(&mac_mace_driver))) {
- printk(KERN_ERR "Driver registration failed\n");
- return err;
- }
-
- mac_mace_device = platform_device_alloc(mac_mace_string, 0);
- if (!mac_mace_device)
- goto out_unregister;
-
- if (platform_device_add(mac_mace_device)) {
- platform_device_put(mac_mace_device);
- mac_mace_device = NULL;
- }
-
- return 0;
-
-out_unregister:
- platform_driver_unregister(&mac_mace_driver);
-
- return -ENOMEM;
+ return platform_driver_register(&mac_mace_driver);
}
static void __exit mac_mace_cleanup_module(void)
{
platform_driver_unregister(&mac_mace_driver);
-
- if (mac_mace_device) {
- platform_device_unregister(mac_mace_device);
- mac_mace_device = NULL;
- }
}
module_init(mac_mace_init_module);
diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig
new file mode 100644
index 00000000000..514c57fd26f
--- /dev/null
+++ b/drivers/net/ethernet/arc/Kconfig
@@ -0,0 +1,31 @@
+#
+# ARC EMAC network device configuration
+#
+
+config NET_VENDOR_ARC
+ bool "ARC devices"
+ default y
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about ARC cards. If you say Y, you will be asked for
+ your specific card in the following questions.
+
+if NET_VENDOR_ARC
+
+config ARC_EMAC
+ tristate "ARC EMAC support"
+ select MII
+ select PHYLIB
+ depends on OF_IRQ
+ depends on OF_NET
+ ---help---
+ On some legacy ARC (Synopsys) FPGA boards such as ARCAngel4/ML50x
+ non-standard on-chip ethernet device ARC EMAC 10/100 is used.
+ Say Y here if you have such a board. If unsure, say N.
+
+endif # NET_VENDOR_ARC
diff --git a/drivers/net/ethernet/arc/Makefile b/drivers/net/ethernet/arc/Makefile
new file mode 100644
index 00000000000..00c8657637d
--- /dev/null
+++ b/drivers/net/ethernet/arc/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the ARC network device drivers.
+#
+
+arc_emac-objs := emac_main.o emac_mdio.o
+obj-$(CONFIG_ARC_EMAC) += arc_emac.o
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
new file mode 100644
index 00000000000..53f85bf7152
--- /dev/null
+++ b/drivers/net/ethernet/arc/emac.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
+ *
+ * Registers and bits definitions of ARC EMAC
+ */
+
+#ifndef ARC_EMAC_H
+#define ARC_EMAC_H
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/clk.h>
+
+/* STATUS and ENABLE Register bit masks */
+#define TXINT_MASK (1<<0) /* Transmit interrupt */
+#define RXINT_MASK (1<<1) /* Receive interrupt */
+#define ERR_MASK (1<<2) /* Error interrupt */
+#define TXCH_MASK (1<<3) /* Transmit chaining error interrupt */
+#define MSER_MASK (1<<4) /* Missed packet counter error */
+#define RXCR_MASK (1<<8) /* RXCRCERR counter rolled over */
+#define RXFR_MASK (1<<9) /* RXFRAMEERR counter rolled over */
+#define RXFL_MASK (1<<10) /* RXOFLOWERR counter rolled over */
+#define MDIO_MASK (1<<12) /* MDIO complete interrupt */
+#define TXPL_MASK (1<<31) /* Force polling of BD by EMAC */
+
+/* CONTROL Register bit masks */
+#define EN_MASK (1<<0) /* VMAC enable */
+#define TXRN_MASK (1<<3) /* TX enable */
+#define RXRN_MASK (1<<4) /* RX enable */
+#define DSBC_MASK (1<<8) /* Disable receive broadcast */
+#define ENFL_MASK (1<<10) /* Enable Full-duplex */
+#define PROM_MASK (1<<11) /* Promiscuous mode */
+
+/* Buffer descriptor INFO bit masks */
+#define OWN_MASK (1<<31) /* 0-CPU owns buffer, 1-EMAC owns buffer */
+#define FIRST_MASK (1<<16) /* First buffer in chain */
+#define LAST_MASK (1<<17) /* Last buffer in chain */
+#define LEN_MASK 0x000007FF /* last 11 bits */
+#define CRLS (1<<21)
+#define DEFR (1<<22)
+#define DROP (1<<23)
+#define RTRY (1<<24)
+#define LTCL (1<<28)
+#define UFLO (1<<29)
+
+#define FOR_EMAC OWN_MASK
+#define FOR_CPU 0
+
+/* ARC EMAC register set combines entries for MAC and MDIO */
+enum {
+ R_ID = 0,
+ R_STATUS,
+ R_ENABLE,
+ R_CTRL,
+ R_POLLRATE,
+ R_RXERR,
+ R_MISS,
+ R_TX_RING,
+ R_RX_RING,
+ R_ADDRL,
+ R_ADDRH,
+ R_LAFL,
+ R_LAFH,
+ R_MDIO,
+};
+
+#define TX_TIMEOUT (400*HZ/1000) /* Transmission timeout */
+
+#define ARC_EMAC_NAPI_WEIGHT 40 /* Workload for NAPI */
+
+#define EMAC_BUFFER_SIZE 1536 /* EMAC buffer size */
+
+/**
+ * struct arc_emac_bd - EMAC buffer descriptor (BD).
+ *
+ * @info: Contains status information on the buffer itself.
+ * @data: 32-bit byte addressable pointer to the packet data.
+ */
+struct arc_emac_bd {
+ __le32 info;
+ dma_addr_t data;
+};
+
+/* Number of Rx/Tx BD's */
+#define RX_BD_NUM 128
+#define TX_BD_NUM 128
+
+#define RX_RING_SZ (RX_BD_NUM * sizeof(struct arc_emac_bd))
+#define TX_RING_SZ (TX_BD_NUM * sizeof(struct arc_emac_bd))
+
+/**
+ * struct buffer_state - Stores Rx/Tx buffer state.
+ * @sk_buff: Pointer to socket buffer.
+ * @addr: Start address of DMA-mapped memory region.
+ * @len: Length of DMA-mapped memory region.
+ */
+struct buffer_state {
+ struct sk_buff *skb;
+ DEFINE_DMA_UNMAP_ADDR(addr);
+ DEFINE_DMA_UNMAP_LEN(len);
+};
+
+/**
+ * struct arc_emac_priv - Storage of EMAC's private information.
+ * @dev: Pointer to the current device.
+ * @ndev: Pointer to the current network device.
+ * @phy_dev: Pointer to attached PHY device.
+ * @bus: Pointer to the current MII bus.
+ * @regs: Base address of EMAC memory-mapped control registers.
+ * @napi: Structure for NAPI.
+ * @stats: Network device statistics.
+ * @rxbd: Pointer to Rx BD ring.
+ * @txbd: Pointer to Tx BD ring.
+ * @rxbd_dma: DMA handle for Rx BD ring.
+ * @txbd_dma: DMA handle for Tx BD ring.
+ * @rx_buff: Storage for Rx buffers states.
+ * @tx_buff: Storage for Tx buffers states.
+ * @txbd_curr: Index of Tx BD to use on the next "ndo_start_xmit".
+ * @txbd_dirty: Index of Tx BD to free on the next Tx interrupt.
+ * @last_rx_bd: Index of the last Rx BD we've got from EMAC.
+ * @link: PHY's last seen link state.
+ * @duplex: PHY's last set duplex mode.
+ * @speed: PHY's last set speed.
+ */
+struct arc_emac_priv {
+ /* Devices */
+ struct device *dev;
+ struct net_device *ndev;
+ struct phy_device *phy_dev;
+ struct mii_bus *bus;
+
+ void __iomem *regs;
+ struct clk *clk;
+
+ struct napi_struct napi;
+ struct net_device_stats stats;
+
+ struct arc_emac_bd *rxbd;
+ struct arc_emac_bd *txbd;
+
+ dma_addr_t rxbd_dma;
+ dma_addr_t txbd_dma;
+
+ struct buffer_state rx_buff[RX_BD_NUM];
+ struct buffer_state tx_buff[TX_BD_NUM];
+ unsigned int txbd_curr;
+ unsigned int txbd_dirty;
+
+ unsigned int last_rx_bd;
+
+ unsigned int link;
+ unsigned int duplex;
+ unsigned int speed;
+};
+
+/**
+ * arc_reg_set - Sets EMAC register with provided value.
+ * @priv: Pointer to ARC EMAC private data structure.
+ * @reg: Register offset from base address.
+ * @value: Value to set in register.
+ */
+static inline void arc_reg_set(struct arc_emac_priv *priv, int reg, int value)
+{
+ iowrite32(value, priv->regs + reg * sizeof(int));
+}
+
+/**
+ * arc_reg_get - Gets value of specified EMAC register.
+ * @priv: Pointer to ARC EMAC private data structure.
+ * @reg: Register offset from base address.
+ *
+ * returns: Value of requested register.
+ */
+static inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg)
+{
+ return ioread32(priv->regs + reg * sizeof(int));
+}
+
+/**
+ * arc_reg_or - Applies mask to specified EMAC register - ("reg" | "mask").
+ * @priv: Pointer to ARC EMAC private data structure.
+ * @reg: Register offset from base address.
+ * @mask: Mask to apply to specified register.
+ *
+ * This function reads initial register value, then applies provided mask
+ * to it and then writes register back.
+ */
+static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask)
+{
+ unsigned int value = arc_reg_get(priv, reg);
+ arc_reg_set(priv, reg, value | mask);
+}
+
+/**
+ * arc_reg_clr - Applies mask to specified EMAC register - ("reg" & ~"mask").
+ * @priv: Pointer to ARC EMAC private data structure.
+ * @reg: Register offset from base address.
+ * @mask: Mask to apply to specified register.
+ *
+ * This function reads initial register value, then applies provided mask
+ * to it and then writes register back.
+ */
+static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
+{
+ unsigned int value = arc_reg_get(priv, reg);
+ arc_reg_set(priv, reg, value & ~mask);
+}
+
+int arc_mdio_probe(struct platform_device *pdev, struct arc_emac_priv *priv);
+int arc_mdio_remove(struct arc_emac_priv *priv);
+
+#endif /* ARC_EMAC_H */
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
new file mode 100644
index 00000000000..18e2faccebb
--- /dev/null
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -0,0 +1,887 @@
+/*
+ * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for the ARC EMAC 10100 (hardware revision 5)
+ *
+ * Contributors:
+ * Amit Bhor
+ * Sameer Dhavale
+ * Vineet Gupta
+ */
+
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/of_platform.h>
+
+#include "emac.h"
+
+#define DRV_NAME "arc_emac"
+#define DRV_VERSION "1.0"
+
+/**
+ * arc_emac_adjust_link - Adjust the PHY link duplex.
+ * @ndev: Pointer to the net_device structure.
+ *
+ * This function is called to change the duplex setting after auto negotiation
+ * is done by the PHY.
+ */
+static void arc_emac_adjust_link(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ struct phy_device *phy_dev = priv->phy_dev;
+ unsigned int reg, state_changed = 0;
+
+ if (priv->link != phy_dev->link) {
+ priv->link = phy_dev->link;
+ state_changed = 1;
+ }
+
+ if (priv->speed != phy_dev->speed) {
+ priv->speed = phy_dev->speed;
+ state_changed = 1;
+ }
+
+ if (priv->duplex != phy_dev->duplex) {
+ reg = arc_reg_get(priv, R_CTRL);
+
+ if (DUPLEX_FULL == phy_dev->duplex)
+ reg |= ENFL_MASK;
+ else
+ reg &= ~ENFL_MASK;
+
+ arc_reg_set(priv, R_CTRL, reg);
+ priv->duplex = phy_dev->duplex;
+ state_changed = 1;
+ }
+
+ if (state_changed)
+ phy_print_status(phy_dev);
+}
+
+/**
+ * arc_emac_get_settings - Get PHY settings.
+ * @ndev: Pointer to net_device structure.
+ * @cmd: Pointer to ethtool_cmd structure.
+ *
+ * This implements ethtool command for getting PHY settings. If PHY could
+ * not be found, the function returns -ENODEV. This function calls the
+ * relevant PHY ethtool API to get the PHY settings.
+ * Issue "ethtool ethX" under linux prompt to execute this function.
+ */
+static int arc_emac_get_settings(struct net_device *ndev,
+ struct ethtool_cmd *cmd)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+
+ return phy_ethtool_gset(priv->phy_dev, cmd);
+}
+
+/**
+ * arc_emac_set_settings - Set PHY settings as passed in the argument.
+ * @ndev: Pointer to net_device structure.
+ * @cmd: Pointer to ethtool_cmd structure.
+ *
+ * This implements ethtool command for setting various PHY settings. If PHY
+ * could not be found, the function returns -ENODEV. This function calls the
+ * relevant PHY ethtool API to set the PHY.
+ * Issue e.g. "ethtool -s ethX speed 1000" under linux prompt to execute this
+ * function.
+ */
+static int arc_emac_set_settings(struct net_device *ndev,
+ struct ethtool_cmd *cmd)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ return phy_ethtool_sset(priv->phy_dev, cmd);
+}
+
+/**
+ * arc_emac_get_drvinfo - Get EMAC driver information.
+ * @ndev: Pointer to net_device structure.
+ * @info: Pointer to ethtool_drvinfo structure.
+ *
+ * This implements ethtool command for getting the driver information.
+ * Issue "ethtool -i ethX" under linux prompt to execute this function.
+ */
+static void arc_emac_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+}
+
+static const struct ethtool_ops arc_emac_ethtool_ops = {
+ .get_settings = arc_emac_get_settings,
+ .set_settings = arc_emac_set_settings,
+ .get_drvinfo = arc_emac_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
+#define FIRST_OR_LAST_MASK (FIRST_MASK | LAST_MASK)
+
+/**
+ * arc_emac_tx_clean - clears processed by EMAC Tx BDs.
+ * @ndev: Pointer to the network device.
+ */
+static void arc_emac_tx_clean(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &priv->stats;
+ unsigned int i;
+
+ for (i = 0; i < TX_BD_NUM; i++) {
+ unsigned int *txbd_dirty = &priv->txbd_dirty;
+ struct arc_emac_bd *txbd = &priv->txbd[*txbd_dirty];
+ struct buffer_state *tx_buff = &priv->tx_buff[*txbd_dirty];
+ struct sk_buff *skb = tx_buff->skb;
+ unsigned int info = le32_to_cpu(txbd->info);
+
+ if ((info & FOR_EMAC) || !txbd->data)
+ break;
+
+ if (unlikely(info & (DROP | DEFR | LTCL | UFLO))) {
+ stats->tx_errors++;
+ stats->tx_dropped++;
+
+ if (info & DEFR)
+ stats->tx_carrier_errors++;
+
+ if (info & LTCL)
+ stats->collisions++;
+
+ if (info & UFLO)
+ stats->tx_fifo_errors++;
+ } else if (likely(info & FIRST_OR_LAST_MASK)) {
+ stats->tx_packets++;
+ stats->tx_bytes += skb->len;
+ }
+
+ dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr),
+ dma_unmap_len(tx_buff, len), DMA_TO_DEVICE);
+
+ /* return the sk_buff to system */
+ dev_kfree_skb_irq(skb);
+
+ txbd->data = 0;
+ txbd->info = 0;
+
+ *txbd_dirty = (*txbd_dirty + 1) % TX_BD_NUM;
+
+ if (netif_queue_stopped(ndev))
+ netif_wake_queue(ndev);
+ }
+}
+
+/**
+ * arc_emac_rx - processing of Rx packets.
+ * @ndev: Pointer to the network device.
+ * @budget: How many BDs to process on 1 call.
+ *
+ * returns: Number of processed BDs
+ *
+ * Iterate through Rx BDs and deliver received packages to upper layer.
+ */
+static int arc_emac_rx(struct net_device *ndev, int budget)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ unsigned int work_done;
+
+ for (work_done = 0; work_done < budget; work_done++) {
+ unsigned int *last_rx_bd = &priv->last_rx_bd;
+ struct net_device_stats *stats = &priv->stats;
+ struct buffer_state *rx_buff = &priv->rx_buff[*last_rx_bd];
+ struct arc_emac_bd *rxbd = &priv->rxbd[*last_rx_bd];
+ unsigned int pktlen, info = le32_to_cpu(rxbd->info);
+ struct sk_buff *skb;
+ dma_addr_t addr;
+
+ if (unlikely((info & OWN_MASK) == FOR_EMAC))
+ break;
+
+ /* Make a note that we saw a packet at this BD.
+ * So next time, driver starts from this + 1
+ */
+ *last_rx_bd = (*last_rx_bd + 1) % RX_BD_NUM;
+
+ if (unlikely((info & FIRST_OR_LAST_MASK) !=
+ FIRST_OR_LAST_MASK)) {
+ /* We pre-allocate buffers of MTU size so incoming
+ * packets won't be split/chained.
+ */
+ if (net_ratelimit())
+ netdev_err(ndev, "incomplete packet received\n");
+
+ /* Return ownership to EMAC */
+ rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
+ stats->rx_errors++;
+ stats->rx_length_errors++;
+ continue;
+ }
+
+ pktlen = info & LEN_MASK;
+ stats->rx_packets++;
+ stats->rx_bytes += pktlen;
+ skb = rx_buff->skb;
+ skb_put(skb, pktlen);
+ skb->dev = ndev;
+ skb->protocol = eth_type_trans(skb, ndev);
+
+ dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
+ dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
+
+ /* Prepare the BD for next cycle */
+ rx_buff->skb = netdev_alloc_skb_ip_align(ndev,
+ EMAC_BUFFER_SIZE);
+ if (unlikely(!rx_buff->skb)) {
+ stats->rx_errors++;
+ /* Because receive_skb is below, increment rx_dropped */
+ stats->rx_dropped++;
+ continue;
+ }
+
+ /* receive_skb only if new skb was allocated to avoid holes */
+ netif_receive_skb(skb);
+
+ addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
+ EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&ndev->dev, addr)) {
+ if (net_ratelimit())
+ netdev_err(ndev, "cannot dma map\n");
+ dev_kfree_skb(rx_buff->skb);
+ stats->rx_errors++;
+ continue;
+ }
+ dma_unmap_addr_set(rx_buff, addr, addr);
+ dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
+
+ rxbd->data = cpu_to_le32(addr);
+
+ /* Make sure pointer to data buffer is set */
+ wmb();
+
+ /* Return ownership to EMAC */
+ rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
+ }
+
+ return work_done;
+}
+
+/**
+ * arc_emac_poll - NAPI poll handler.
+ * @napi: Pointer to napi_struct structure.
+ * @budget: How many BDs to process on 1 call.
+ *
+ * returns: Number of processed BDs
+ */
+static int arc_emac_poll(struct napi_struct *napi, int budget)
+{
+ struct net_device *ndev = napi->dev;
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ unsigned int work_done;
+
+ arc_emac_tx_clean(ndev);
+
+ work_done = arc_emac_rx(ndev, budget);
+ if (work_done < budget) {
+ napi_complete(napi);
+ arc_reg_or(priv, R_ENABLE, RXINT_MASK);
+ }
+
+ return work_done;
+}
+
+/**
+ * arc_emac_intr - Global interrupt handler for EMAC.
+ * @irq: irq number.
+ * @dev_instance: device instance.
+ *
+ * returns: IRQ_HANDLED for all cases.
+ *
+ * ARC EMAC has only 1 interrupt line, and depending on bits raised in
+ * STATUS register we may tell what is a reason for interrupt to fire.
+ */
+static irqreturn_t arc_emac_intr(int irq, void *dev_instance)
+{
+ struct net_device *ndev = dev_instance;
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &priv->stats;
+ unsigned int status;
+
+ status = arc_reg_get(priv, R_STATUS);
+ status &= ~MDIO_MASK;
+
+ /* Reset all flags except "MDIO complete" */
+ arc_reg_set(priv, R_STATUS, status);
+
+ if (status & RXINT_MASK) {
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ arc_reg_clr(priv, R_ENABLE, RXINT_MASK);
+ __napi_schedule(&priv->napi);
+ }
+ }
+
+ if (status & ERR_MASK) {
+ /* MSER/RXCR/RXFR/RXFL interrupt fires on corresponding
+ * 8-bit error counter overrun.
+ */
+
+ if (status & MSER_MASK) {
+ stats->rx_missed_errors += 0x100;
+ stats->rx_errors += 0x100;
+ }
+
+ if (status & RXCR_MASK) {
+ stats->rx_crc_errors += 0x100;
+ stats->rx_errors += 0x100;
+ }
+
+ if (status & RXFR_MASK) {
+ stats->rx_frame_errors += 0x100;
+ stats->rx_errors += 0x100;
+ }
+
+ if (status & RXFL_MASK) {
+ stats->rx_over_errors += 0x100;
+ stats->rx_errors += 0x100;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void arc_emac_poll_controller(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ arc_emac_intr(dev->irq, dev);
+ enable_irq(dev->irq);
+}
+#endif
+
+/**
+ * arc_emac_open - Open the network device.
+ * @ndev: Pointer to the network device.
+ *
+ * returns: 0, on success or non-zero error value on failure.
+ *
+ * This function sets the MAC address, requests and enables an IRQ
+ * for the EMAC device and starts the Tx queue.
+ * It also connects to the phy device.
+ */
+static int arc_emac_open(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ struct phy_device *phy_dev = priv->phy_dev;
+ int i;
+
+ phy_dev->autoneg = AUTONEG_ENABLE;
+ phy_dev->speed = 0;
+ phy_dev->duplex = 0;
+ phy_dev->advertising &= phy_dev->supported;
+
+ priv->last_rx_bd = 0;
+
+ /* Allocate and set buffers for Rx BD's */
+ for (i = 0; i < RX_BD_NUM; i++) {
+ dma_addr_t addr;
+ unsigned int *last_rx_bd = &priv->last_rx_bd;
+ struct arc_emac_bd *rxbd = &priv->rxbd[*last_rx_bd];
+ struct buffer_state *rx_buff = &priv->rx_buff[*last_rx_bd];
+
+ rx_buff->skb = netdev_alloc_skb_ip_align(ndev,
+ EMAC_BUFFER_SIZE);
+ if (unlikely(!rx_buff->skb))
+ return -ENOMEM;
+
+ addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
+ EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&ndev->dev, addr)) {
+ netdev_err(ndev, "cannot dma map\n");
+ dev_kfree_skb(rx_buff->skb);
+ return -ENOMEM;
+ }
+ dma_unmap_addr_set(rx_buff, addr, addr);
+ dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
+
+ rxbd->data = cpu_to_le32(addr);
+
+ /* Make sure pointer to data buffer is set */
+ wmb();
+
+ /* Return ownership to EMAC */
+ rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
+
+ *last_rx_bd = (*last_rx_bd + 1) % RX_BD_NUM;
+ }
+
+ /* Clean Tx BD's */
+ memset(priv->txbd, 0, TX_RING_SZ);
+
+ /* Initialize logical address filter */
+ arc_reg_set(priv, R_LAFL, 0);
+ arc_reg_set(priv, R_LAFH, 0);
+
+ /* Set BD ring pointers for device side */
+ arc_reg_set(priv, R_RX_RING, (unsigned int)priv->rxbd_dma);
+ arc_reg_set(priv, R_TX_RING, (unsigned int)priv->txbd_dma);
+
+ /* Enable interrupts */
+ arc_reg_set(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
+
+ /* Set CONTROL */
+ arc_reg_set(priv, R_CTRL,
+ (RX_BD_NUM << 24) | /* RX BD table length */
+ (TX_BD_NUM << 16) | /* TX BD table length */
+ TXRN_MASK | RXRN_MASK);
+
+ napi_enable(&priv->napi);
+
+ /* Enable EMAC */
+ arc_reg_or(priv, R_CTRL, EN_MASK);
+
+ phy_start_aneg(priv->phy_dev);
+
+ netif_start_queue(ndev);
+
+ return 0;
+}
+
+/**
+ * arc_emac_set_rx_mode - Change the receive filtering mode.
+ * @ndev: Pointer to the network device.
+ *
+ * This function enables/disables promiscuous or all-multicast mode
+ * and updates the multicast filtering list of the network device.
+ */
+static void arc_emac_set_rx_mode(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+
+ if (ndev->flags & IFF_PROMISC) {
+ arc_reg_or(priv, R_CTRL, PROM_MASK);
+ } else {
+ arc_reg_clr(priv, R_CTRL, PROM_MASK);
+
+ if (ndev->flags & IFF_ALLMULTI) {
+ arc_reg_set(priv, R_LAFL, ~0);
+ arc_reg_set(priv, R_LAFH, ~0);
+ } else {
+ struct netdev_hw_addr *ha;
+ unsigned int filter[2] = { 0, 0 };
+ int bit;
+
+ netdev_for_each_mc_addr(ha, ndev) {
+ bit = ether_crc_le(ETH_ALEN, ha->addr) >> 26;
+ filter[bit >> 5] |= 1 << (bit & 31);
+ }
+
+ arc_reg_set(priv, R_LAFL, filter[0]);
+ arc_reg_set(priv, R_LAFH, filter[1]);
+ }
+ }
+}
+
+/**
+ * arc_emac_stop - Close the network device.
+ * @ndev: Pointer to the network device.
+ *
+ * This function stops the Tx queue, disables interrupts and frees the IRQ for
+ * the EMAC device.
+ * It also disconnects the PHY device associated with the EMAC device.
+ */
+static int arc_emac_stop(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+
+ napi_disable(&priv->napi);
+ netif_stop_queue(ndev);
+
+ /* Disable interrupts */
+ arc_reg_clr(priv, R_ENABLE, RXINT_MASK | ERR_MASK);
+
+ /* Disable EMAC */
+ arc_reg_clr(priv, R_CTRL, EN_MASK);
+
+ return 0;
+}
+
+/**
+ * arc_emac_stats - Get system network statistics.
+ * @ndev: Pointer to net_device structure.
+ *
+ * Returns the address of the device statistics structure.
+ * Statistics are updated in interrupt handler.
+ */
+static struct net_device_stats *arc_emac_stats(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &priv->stats;
+ unsigned long miss, rxerr;
+ u8 rxcrc, rxfram, rxoflow;
+
+ rxerr = arc_reg_get(priv, R_RXERR);
+ miss = arc_reg_get(priv, R_MISS);
+
+ rxcrc = rxerr;
+ rxfram = rxerr >> 8;
+ rxoflow = rxerr >> 16;
+
+ stats->rx_errors += miss;
+ stats->rx_errors += rxcrc + rxfram + rxoflow;
+
+ stats->rx_over_errors += rxoflow;
+ stats->rx_frame_errors += rxfram;
+ stats->rx_crc_errors += rxcrc;
+ stats->rx_missed_errors += miss;
+
+ return stats;
+}
+
+/**
+ * arc_emac_tx - Starts the data transmission.
+ * @skb: sk_buff pointer that contains data to be Transmitted.
+ * @ndev: Pointer to net_device structure.
+ *
+ * returns: NETDEV_TX_OK, on success
+ * NETDEV_TX_BUSY, if any of the descriptors are not free.
+ *
+ * This function is invoked from upper layers to initiate transmission.
+ */
+static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ unsigned int len, *txbd_curr = &priv->txbd_curr;
+ struct net_device_stats *stats = &priv->stats;
+ __le32 *info = &priv->txbd[*txbd_curr].info;
+ dma_addr_t addr;
+
+ if (skb_padto(skb, ETH_ZLEN))
+ return NETDEV_TX_OK;
+
+ len = max_t(unsigned int, ETH_ZLEN, skb->len);
+
+ /* EMAC still holds this buffer in its possession.
+ * CPU must not modify this buffer descriptor
+ */
+ if (unlikely((le32_to_cpu(*info) & OWN_MASK) == FOR_EMAC)) {
+ netif_stop_queue(ndev);
+ return NETDEV_TX_BUSY;
+ }
+
+ addr = dma_map_single(&ndev->dev, (void *)skb->data, len,
+ DMA_TO_DEVICE);
+
+ if (unlikely(dma_mapping_error(&ndev->dev, addr))) {
+ stats->tx_dropped++;
+ stats->tx_errors++;
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ dma_unmap_addr_set(&priv->tx_buff[*txbd_curr], addr, addr);
+ dma_unmap_len_set(&priv->tx_buff[*txbd_curr], len, len);
+
+ priv->tx_buff[*txbd_curr].skb = skb;
+ priv->txbd[*txbd_curr].data = cpu_to_le32(addr);
+
+ /* Make sure pointer to data buffer is set */
+ wmb();
+
+ skb_tx_timestamp(skb);
+
+ *info = cpu_to_le32(FOR_EMAC | FIRST_OR_LAST_MASK | len);
+
+ /* Increment index to point to the next BD */
+ *txbd_curr = (*txbd_curr + 1) % TX_BD_NUM;
+
+ /* Get "info" of the next BD */
+ info = &priv->txbd[*txbd_curr].info;
+
+ /* Check if if Tx BD ring is full - next BD is still owned by EMAC */
+ if (unlikely((le32_to_cpu(*info) & OWN_MASK) == FOR_EMAC))
+ netif_stop_queue(ndev);
+
+ arc_reg_set(priv, R_STATUS, TXPL_MASK);
+
+ return NETDEV_TX_OK;
+}
+
+static void arc_emac_set_address_internal(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ unsigned int addr_low, addr_hi;
+
+ addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]);
+ addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]);
+
+ arc_reg_set(priv, R_ADDRL, addr_low);
+ arc_reg_set(priv, R_ADDRH, addr_hi);
+}
+
+/**
+ * arc_emac_set_address - Set the MAC address for this device.
+ * @ndev: Pointer to net_device structure.
+ * @p: 6 byte Address to be written as MAC address.
+ *
+ * This function copies the HW address from the sockaddr structure to the
+ * net_device structure and updates the address in HW.
+ *
+ * returns: -EBUSY if the net device is busy or 0 if the address is set
+ * successfully.
+ */
+static int arc_emac_set_address(struct net_device *ndev, void *p)
+{
+ struct sockaddr *addr = p;
+
+ if (netif_running(ndev))
+ return -EBUSY;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+
+ arc_emac_set_address_internal(ndev);
+
+ return 0;
+}
+
+static const struct net_device_ops arc_emac_netdev_ops = {
+ .ndo_open = arc_emac_open,
+ .ndo_stop = arc_emac_stop,
+ .ndo_start_xmit = arc_emac_tx,
+ .ndo_set_mac_address = arc_emac_set_address,
+ .ndo_get_stats = arc_emac_stats,
+ .ndo_set_rx_mode = arc_emac_set_rx_mode,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = arc_emac_poll_controller,
+#endif
+};
+
+static int arc_emac_probe(struct platform_device *pdev)
+{
+ struct resource res_regs;
+ struct device_node *phy_node;
+ struct arc_emac_priv *priv;
+ struct net_device *ndev;
+ const char *mac_addr;
+ unsigned int id, clock_frequency, irq;
+ int err;
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ /* Get PHY from device tree */
+ phy_node = of_parse_phandle(pdev->dev.of_node, "phy", 0);
+ if (!phy_node) {
+ dev_err(&pdev->dev, "failed to retrieve phy description from device tree\n");
+ return -ENODEV;
+ }
+
+ /* Get EMAC registers base address from device tree */
+ err = of_address_to_resource(pdev->dev.of_node, 0, &res_regs);
+ if (err) {
+ dev_err(&pdev->dev, "failed to retrieve registers base from device tree\n");
+ return -ENODEV;
+ }
+
+ /* Get IRQ from device tree */
+ irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (!irq) {
+ dev_err(&pdev->dev, "failed to retrieve <irq> value from device tree\n");
+ return -ENODEV;
+ }
+
+ ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
+ if (!ndev)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ndev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ ndev->netdev_ops = &arc_emac_netdev_ops;
+ ndev->ethtool_ops = &arc_emac_ethtool_ops;
+ ndev->watchdog_timeo = TX_TIMEOUT;
+ /* FIXME :: no multicast support yet */
+ ndev->flags &= ~IFF_MULTICAST;
+
+ priv = netdev_priv(ndev);
+ priv->dev = &pdev->dev;
+ priv->ndev = ndev;
+
+ priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs);
+ if (IS_ERR(priv->regs)) {
+ err = PTR_ERR(priv->regs);
+ goto out_netdev;
+ }
+ dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs);
+
+ priv->clk = of_clk_get(pdev->dev.of_node, 0);
+ if (IS_ERR(priv->clk)) {
+ /* Get CPU clock frequency from device tree */
+ if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+ &clock_frequency)) {
+ dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n");
+ err = -EINVAL;
+ goto out_netdev;
+ }
+ } else {
+ err = clk_prepare_enable(priv->clk);
+ if (err) {
+ dev_err(&pdev->dev, "failed to enable clock\n");
+ goto out_clkget;
+ }
+
+ clock_frequency = clk_get_rate(priv->clk);
+ }
+
+ id = arc_reg_get(priv, R_ID);
+
+ /* Check for EMAC revision 5 or 7, magic number */
+ if (!(id == 0x0005fd02 || id == 0x0007fd02)) {
+ dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id);
+ err = -ENODEV;
+ goto out_clken;
+ }
+ dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id);
+
+ /* Set poll rate so that it polls every 1 ms */
+ arc_reg_set(priv, R_POLLRATE, clock_frequency / 1000000);
+
+ ndev->irq = irq;
+ dev_info(&pdev->dev, "IRQ is %d\n", ndev->irq);
+
+ /* Register interrupt handler for device */
+ err = devm_request_irq(&pdev->dev, ndev->irq, arc_emac_intr, 0,
+ ndev->name, ndev);
+ if (err) {
+ dev_err(&pdev->dev, "could not allocate IRQ\n");
+ goto out_clken;
+ }
+
+ /* Get MAC address from device tree */
+ mac_addr = of_get_mac_address(pdev->dev.of_node);
+
+ if (mac_addr)
+ memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
+ else
+ eth_hw_addr_random(ndev);
+
+ arc_emac_set_address_internal(ndev);
+ dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr);
+
+ /* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */
+ priv->rxbd = dmam_alloc_coherent(&pdev->dev, RX_RING_SZ + TX_RING_SZ,
+ &priv->rxbd_dma, GFP_KERNEL);
+
+ if (!priv->rxbd) {
+ dev_err(&pdev->dev, "failed to allocate data buffers\n");
+ err = -ENOMEM;
+ goto out_clken;
+ }
+
+ priv->txbd = priv->rxbd + RX_BD_NUM;
+
+ priv->txbd_dma = priv->rxbd_dma + RX_RING_SZ;
+ dev_dbg(&pdev->dev, "EMAC Device addr: Rx Ring [0x%x], Tx Ring[%x]\n",
+ (unsigned int)priv->rxbd_dma, (unsigned int)priv->txbd_dma);
+
+ err = arc_mdio_probe(pdev, priv);
+ if (err) {
+ dev_err(&pdev->dev, "failed to probe MII bus\n");
+ goto out_clken;
+ }
+
+ priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
+ PHY_INTERFACE_MODE_MII);
+ if (!priv->phy_dev) {
+ dev_err(&pdev->dev, "of_phy_connect() failed\n");
+ err = -ENODEV;
+ goto out_mdio;
+ }
+
+ dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n",
+ priv->phy_dev->drv->name, priv->phy_dev->phy_id);
+
+ netif_napi_add(ndev, &priv->napi, arc_emac_poll, ARC_EMAC_NAPI_WEIGHT);
+
+ err = register_netdev(ndev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to register network device\n");
+ goto out_netif_api;
+ }
+
+ return 0;
+
+out_netif_api:
+ netif_napi_del(&priv->napi);
+ phy_disconnect(priv->phy_dev);
+ priv->phy_dev = NULL;
+out_mdio:
+ arc_mdio_remove(priv);
+out_clken:
+ if (!IS_ERR(priv->clk))
+ clk_disable_unprepare(priv->clk);
+out_clkget:
+ if (!IS_ERR(priv->clk))
+ clk_put(priv->clk);
+out_netdev:
+ free_netdev(ndev);
+ return err;
+}
+
+static int arc_emac_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+
+ phy_disconnect(priv->phy_dev);
+ priv->phy_dev = NULL;
+ arc_mdio_remove(priv);
+ unregister_netdev(ndev);
+ netif_napi_del(&priv->napi);
+
+ if (!IS_ERR(priv->clk)) {
+ clk_disable_unprepare(priv->clk);
+ clk_put(priv->clk);
+ }
+
+ free_netdev(ndev);
+
+ return 0;
+}
+
+static const struct of_device_id arc_emac_dt_ids[] = {
+ { .compatible = "snps,arc-emac" },
+ { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, arc_emac_dt_ids);
+
+static struct platform_driver arc_emac_driver = {
+ .probe = arc_emac_probe,
+ .remove = arc_emac_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = arc_emac_dt_ids,
+ },
+};
+
+module_platform_driver(arc_emac_driver);
+
+MODULE_AUTHOR("Alexey Brodkin <abrodkin@synopsys.com>");
+MODULE_DESCRIPTION("ARC EMAC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/arc/emac_mdio.c b/drivers/net/ethernet/arc/emac_mdio.c
new file mode 100644
index 00000000000..26ba2423f33
--- /dev/null
+++ b/drivers/net/ethernet/arc/emac_mdio.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com)
+ *
+ * MDIO implementation for ARC EMAC
+ */
+
+#include <linux/delay.h>
+#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+
+#include "emac.h"
+
+/* Number of seconds we wait for "MDIO complete" flag to appear */
+#define ARC_MDIO_COMPLETE_POLL_COUNT 1
+
+/**
+ * arc_mdio_complete_wait - Waits until MDIO transaction is completed.
+ * @priv: Pointer to ARC EMAC private data structure.
+ *
+ * returns: 0 on success, -ETIMEDOUT on a timeout.
+ */
+static int arc_mdio_complete_wait(struct arc_emac_priv *priv)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARC_MDIO_COMPLETE_POLL_COUNT * 40; i++) {
+ unsigned int status = arc_reg_get(priv, R_STATUS);
+
+ status &= MDIO_MASK;
+
+ if (status) {
+ /* Reset "MDIO complete" flag */
+ arc_reg_set(priv, R_STATUS, status);
+ return 0;
+ }
+
+ msleep(25);
+ }
+
+ return -ETIMEDOUT;
+}
+
+/**
+ * arc_mdio_read - MDIO interface read function.
+ * @bus: Pointer to MII bus structure.
+ * @phy_addr: Address of the PHY device.
+ * @reg_num: PHY register to read.
+ *
+ * returns: The register contents on success, -ETIMEDOUT on a timeout.
+ *
+ * Reads the contents of the requested register from the requested PHY
+ * address.
+ */
+static int arc_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
+{
+ struct arc_emac_priv *priv = bus->priv;
+ unsigned int value;
+ int error;
+
+ arc_reg_set(priv, R_MDIO,
+ 0x60020000 | (phy_addr << 23) | (reg_num << 18));
+
+ error = arc_mdio_complete_wait(priv);
+ if (error < 0)
+ return error;
+
+ value = arc_reg_get(priv, R_MDIO) & 0xffff;
+
+ dev_dbg(priv->dev, "arc_mdio_read(phy_addr=%i, reg_num=%x) = %x\n",
+ phy_addr, reg_num, value);
+
+ return value;
+}
+
+/**
+ * arc_mdio_write - MDIO interface write function.
+ * @bus: Pointer to MII bus structure.
+ * @phy_addr: Address of the PHY device.
+ * @reg_num: PHY register to write to.
+ * @value: Value to be written into the register.
+ *
+ * returns: 0 on success, -ETIMEDOUT on a timeout.
+ *
+ * Writes the value to the requested register.
+ */
+static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
+ int reg_num, u16 value)
+{
+ struct arc_emac_priv *priv = bus->priv;
+
+ dev_dbg(priv->dev,
+ "arc_mdio_write(phy_addr=%i, reg_num=%x, value=%x)\n",
+ phy_addr, reg_num, value);
+
+ arc_reg_set(priv, R_MDIO,
+ 0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
+
+ return arc_mdio_complete_wait(priv);
+}
+
+/**
+ * arc_mdio_probe - MDIO probe function.
+ * @pdev: Pointer to platform device.
+ * @priv: Pointer to ARC EMAC private data structure.
+ *
+ * returns: 0 on success, -ENOMEM when mdiobus_alloc
+ * (to allocate memory for MII bus structure) fails.
+ *
+ * Sets up and registers the MDIO interface.
+ */
+int arc_mdio_probe(struct platform_device *pdev, struct arc_emac_priv *priv)
+{
+ struct mii_bus *bus;
+ int error;
+
+ bus = mdiobus_alloc();
+ if (!bus)
+ return -ENOMEM;
+
+ priv->bus = bus;
+ bus->priv = priv;
+ bus->parent = priv->dev;
+ bus->name = "Synopsys MII Bus",
+ bus->read = &arc_mdio_read;
+ bus->write = &arc_mdio_write;
+
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
+
+ error = of_mdiobus_register(bus, pdev->dev.of_node);
+ if (error) {
+ dev_err(priv->dev, "cannot register MDIO bus %s\n", bus->name);
+ mdiobus_free(bus);
+ return error;
+ }
+
+ return 0;
+}
+
+/**
+ * arc_mdio_remove - MDIO remove function.
+ * @priv: Pointer to ARC EMAC private data structure.
+ *
+ * Unregisters the MDIO and frees any associate memory for MII bus.
+ */
+int arc_mdio_remove(struct arc_emac_priv *priv)
+{
+ mdiobus_unregister(priv->bus);
+ mdiobus_free(priv->bus);
+ priv->bus = NULL;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/atheros/Kconfig b/drivers/net/ethernet/atheros/Kconfig
new file mode 100644
index 00000000000..58ad37c733b
--- /dev/null
+++ b/drivers/net/ethernet/atheros/Kconfig
@@ -0,0 +1,83 @@
+#
+# Atheros device configuration
+#
+
+config NET_VENDOR_ATHEROS
+ bool "Atheros devices"
+ default y
+ depends on PCI
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Atheros devices. If you say Y, you will be asked
+ for your specific card in the following questions.
+
+if NET_VENDOR_ATHEROS
+
+config ATL2
+ tristate "Atheros L2 Fast Ethernet support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ This driver supports the Atheros L2 fast ethernet adapter.
+
+ To compile this driver as a module, choose M here. The module
+ will be called atl2.
+
+config ATL1
+ tristate "Atheros/Attansic L1 Gigabit Ethernet support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ This driver supports the Atheros/Attansic L1 gigabit ethernet
+ adapter.
+
+ To compile this driver as a module, choose M here. The module
+ will be called atl1.
+
+config ATL1E
+ tristate "Atheros L1E Gigabit Ethernet support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ This driver supports the Atheros L1E gigabit ethernet adapter.
+
+ To compile this driver as a module, choose M here. The module
+ will be called atl1e.
+
+config ATL1C
+ tristate "Atheros L1C Gigabit Ethernet support"
+ depends on PCI
+ select CRC32
+ select MII
+ ---help---
+ This driver supports the Atheros L1C gigabit ethernet adapter.
+
+ To compile this driver as a module, choose M here. The module
+ will be called atl1c.
+
+config ALX
+ tristate "Qualcomm Atheros AR816x/AR817x support"
+ depends on PCI
+ select CRC32
+ select MDIO
+ help
+ This driver supports the Qualcomm Atheros L1F ethernet adapter,
+ i.e. the following chipsets:
+
+ 1969:1091 - AR8161 Gigabit Ethernet
+ 1969:1090 - AR8162 Fast Ethernet
+ 1969:10A1 - AR8171 Gigabit Ethernet
+ 1969:10A0 - AR8172 Fast Ethernet
+
+ To compile this driver as a module, choose M here. The module
+ will be called alx.
+
+endif # NET_VENDOR_ATHEROS
diff --git a/drivers/net/ethernet/atheros/Makefile b/drivers/net/ethernet/atheros/Makefile
new file mode 100644
index 00000000000..5cf1c65bbce
--- /dev/null
+++ b/drivers/net/ethernet/atheros/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the Atheros network device drivers.
+#
+
+obj-$(CONFIG_ATL1) += atlx/
+obj-$(CONFIG_ATL2) += atlx/
+obj-$(CONFIG_ATL1E) += atl1e/
+obj-$(CONFIG_ATL1C) += atl1c/
+obj-$(CONFIG_ALX) += alx/
diff --git a/drivers/net/ethernet/atheros/alx/Makefile b/drivers/net/ethernet/atheros/alx/Makefile
new file mode 100644
index 00000000000..5901fa407d5
--- /dev/null
+++ b/drivers/net/ethernet/atheros/alx/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ALX) += alx.o
+alx-objs := main.o ethtool.o hw.o
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/ethernet/atheros/alx/alx.h b/drivers/net/ethernet/atheros/alx/alx.h
new file mode 100644
index 00000000000..8fc93c5f6ab
--- /dev/null
+++ b/drivers/net/ethernet/atheros/alx/alx.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is free software: you may copy, redistribute and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _ALX_H_
+#define _ALX_H_
+
+#include <linux/types.h>
+#include <linux/etherdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include "hw.h"
+
+#define ALX_WATCHDOG_TIME (5 * HZ)
+
+struct alx_buffer {
+ struct sk_buff *skb;
+ DEFINE_DMA_UNMAP_ADDR(dma);
+ DEFINE_DMA_UNMAP_LEN(size);
+};
+
+struct alx_rx_queue {
+ struct alx_rrd *rrd;
+ dma_addr_t rrd_dma;
+
+ struct alx_rfd *rfd;
+ dma_addr_t rfd_dma;
+
+ struct alx_buffer *bufs;
+
+ u16 write_idx, read_idx;
+ u16 rrd_read_idx;
+};
+#define ALX_RX_ALLOC_THRESH 32
+
+struct alx_tx_queue {
+ struct alx_txd *tpd;
+ dma_addr_t tpd_dma;
+ struct alx_buffer *bufs;
+ u16 write_idx, read_idx;
+};
+
+#define ALX_DEFAULT_TX_WORK 128
+
+enum alx_device_quirks {
+ ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG = BIT(0),
+};
+
+struct alx_priv {
+ struct net_device *dev;
+
+ struct alx_hw hw;
+
+ /* all descriptor memory */
+ struct {
+ dma_addr_t dma;
+ void *virt;
+ unsigned int size;
+ } descmem;
+
+ /* protect int_mask updates */
+ spinlock_t irq_lock;
+ u32 int_mask;
+
+ unsigned int tx_ringsz;
+ unsigned int rx_ringsz;
+ unsigned int rxbuf_size;
+
+ struct napi_struct napi;
+ struct alx_tx_queue txq;
+ struct alx_rx_queue rxq;
+
+ struct work_struct link_check_wk;
+ struct work_struct reset_wk;
+
+ u16 msg_enable;
+
+ bool msi;
+
+ /* protects hw.stats */
+ spinlock_t stats_lock;
+};
+
+extern const struct ethtool_ops alx_ethtool_ops;
+extern const char alx_drv_name[];
+
+#endif
diff --git a/drivers/net/ethernet/atheros/alx/ethtool.c b/drivers/net/ethernet/atheros/alx/ethtool.c
new file mode 100644
index 00000000000..08e22df2a30
--- /dev/null
+++ b/drivers/net/ethernet/atheros/alx/ethtool.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is free software: you may copy, redistribute and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/pci.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mdio.h>
+#include <linux/interrupt.h>
+#include <asm/byteorder.h>
+
+#include "alx.h"
+#include "reg.h"
+#include "hw.h"
+
+/* The order of these strings must match the order of the fields in
+ * struct alx_hw_stats
+ * See hw.h
+ */
+static const char alx_gstrings_stats[][ETH_GSTRING_LEN] = {
+ "rx_packets",
+ "rx_bcast_packets",
+ "rx_mcast_packets",
+ "rx_pause_packets",
+ "rx_ctrl_packets",
+ "rx_fcs_errors",
+ "rx_length_errors",
+ "rx_bytes",
+ "rx_runt_packets",
+ "rx_fragments",
+ "rx_64B_or_less_packets",
+ "rx_65B_to_127B_packets",
+ "rx_128B_to_255B_packets",
+ "rx_256B_to_511B_packets",
+ "rx_512B_to_1023B_packets",
+ "rx_1024B_to_1518B_packets",
+ "rx_1519B_to_mtu_packets",
+ "rx_oversize_packets",
+ "rx_rxf_ov_drop_packets",
+ "rx_rrd_ov_drop_packets",
+ "rx_align_errors",
+ "rx_bcast_bytes",
+ "rx_mcast_bytes",
+ "rx_address_errors",
+ "tx_packets",
+ "tx_bcast_packets",
+ "tx_mcast_packets",
+ "tx_pause_packets",
+ "tx_exc_defer_packets",
+ "tx_ctrl_packets",
+ "tx_defer_packets",
+ "tx_bytes",
+ "tx_64B_or_less_packets",
+ "tx_65B_to_127B_packets",
+ "tx_128B_to_255B_packets",
+ "tx_256B_to_511B_packets",
+ "tx_512B_to_1023B_packets",
+ "tx_1024B_to_1518B_packets",
+ "tx_1519B_to_mtu_packets",
+ "tx_single_collision",
+ "tx_multiple_collisions",
+ "tx_late_collision",
+ "tx_abort_collision",
+ "tx_underrun",
+ "tx_trd_eop",
+ "tx_length_errors",
+ "tx_trunc_packets",
+ "tx_bcast_bytes",
+ "tx_mcast_bytes",
+ "tx_update",
+};
+
+#define ALX_NUM_STATS ARRAY_SIZE(alx_gstrings_stats)
+
+
+static u32 alx_get_supported_speeds(struct alx_hw *hw)
+{
+ u32 supported = SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full;
+
+ if (alx_hw_giga(hw))
+ supported |= SUPPORTED_1000baseT_Full;
+
+ BUILD_BUG_ON(SUPPORTED_10baseT_Half != ADVERTISED_10baseT_Half);
+ BUILD_BUG_ON(SUPPORTED_10baseT_Full != ADVERTISED_10baseT_Full);
+ BUILD_BUG_ON(SUPPORTED_100baseT_Half != ADVERTISED_100baseT_Half);
+ BUILD_BUG_ON(SUPPORTED_100baseT_Full != ADVERTISED_100baseT_Full);
+ BUILD_BUG_ON(SUPPORTED_1000baseT_Full != ADVERTISED_1000baseT_Full);
+
+ return supported;
+}
+
+static int alx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+
+ ecmd->supported = SUPPORTED_Autoneg |
+ SUPPORTED_TP |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause;
+ if (alx_hw_giga(hw))
+ ecmd->supported |= SUPPORTED_1000baseT_Full;
+ ecmd->supported |= alx_get_supported_speeds(hw);
+
+ ecmd->advertising = ADVERTISED_TP;
+ if (hw->adv_cfg & ADVERTISED_Autoneg)
+ ecmd->advertising |= hw->adv_cfg;
+
+ ecmd->port = PORT_TP;
+ ecmd->phy_address = 0;
+
+ if (hw->adv_cfg & ADVERTISED_Autoneg)
+ ecmd->autoneg = AUTONEG_ENABLE;
+ else
+ ecmd->autoneg = AUTONEG_DISABLE;
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (hw->flowctrl & ALX_FC_ANEG && hw->adv_cfg & ADVERTISED_Autoneg) {
+ if (hw->flowctrl & ALX_FC_RX) {
+ ecmd->advertising |= ADVERTISED_Pause;
+
+ if (!(hw->flowctrl & ALX_FC_TX))
+ ecmd->advertising |= ADVERTISED_Asym_Pause;
+ } else if (hw->flowctrl & ALX_FC_TX) {
+ ecmd->advertising |= ADVERTISED_Asym_Pause;
+ }
+ }
+
+ ethtool_cmd_speed_set(ecmd, hw->link_speed);
+ ecmd->duplex = hw->duplex;
+
+ return 0;
+}
+
+static int alx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+ u32 adv_cfg;
+
+ ASSERT_RTNL();
+
+ if (ecmd->autoneg == AUTONEG_ENABLE) {
+ if (ecmd->advertising & ~alx_get_supported_speeds(hw))
+ return -EINVAL;
+ adv_cfg = ecmd->advertising | ADVERTISED_Autoneg;
+ } else {
+ adv_cfg = alx_speed_to_ethadv(ethtool_cmd_speed(ecmd),
+ ecmd->duplex);
+
+ if (!adv_cfg || adv_cfg == ADVERTISED_1000baseT_Full)
+ return -EINVAL;
+ }
+
+ hw->adv_cfg = adv_cfg;
+ return alx_setup_speed_duplex(hw, adv_cfg, hw->flowctrl);
+}
+
+static void alx_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+
+ pause->autoneg = !!(hw->flowctrl & ALX_FC_ANEG &&
+ hw->adv_cfg & ADVERTISED_Autoneg);
+ pause->tx_pause = !!(hw->flowctrl & ALX_FC_TX);
+ pause->rx_pause = !!(hw->flowctrl & ALX_FC_RX);
+}
+
+
+static int alx_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+ int err = 0;
+ bool reconfig_phy = false;
+ u8 fc = 0;
+
+ if (pause->tx_pause)
+ fc |= ALX_FC_TX;
+ if (pause->rx_pause)
+ fc |= ALX_FC_RX;
+ if (pause->autoneg)
+ fc |= ALX_FC_ANEG;
+
+ ASSERT_RTNL();
+
+ /* restart auto-neg for auto-mode */
+ if (hw->adv_cfg & ADVERTISED_Autoneg) {
+ if (!((fc ^ hw->flowctrl) & ALX_FC_ANEG))
+ reconfig_phy = true;
+ if (fc & hw->flowctrl & ALX_FC_ANEG &&
+ (fc ^ hw->flowctrl) & (ALX_FC_RX | ALX_FC_TX))
+ reconfig_phy = true;
+ }
+
+ if (reconfig_phy) {
+ err = alx_setup_speed_duplex(hw, hw->adv_cfg, fc);
+ if (err)
+ return err;
+ }
+
+ /* flow control on mac */
+ if ((fc ^ hw->flowctrl) & (ALX_FC_RX | ALX_FC_TX))
+ alx_cfg_mac_flowcontrol(hw, fc);
+
+ hw->flowctrl = fc;
+
+ return 0;
+}
+
+static u32 alx_get_msglevel(struct net_device *netdev)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+
+ return alx->msg_enable;
+}
+
+static void alx_set_msglevel(struct net_device *netdev, u32 data)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+
+ alx->msg_enable = data;
+}
+
+static void alx_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *estats, u64 *data)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+
+ spin_lock(&alx->stats_lock);
+
+ alx_update_hw_stats(hw);
+ BUILD_BUG_ON(sizeof(hw->stats) - offsetof(struct alx_hw_stats, rx_ok) <
+ ALX_NUM_STATS * sizeof(u64));
+ memcpy(data, &hw->stats.rx_ok, ALX_NUM_STATS * sizeof(u64));
+
+ spin_unlock(&alx->stats_lock);
+}
+
+static void alx_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
+{
+ switch (stringset) {
+ case ETH_SS_STATS:
+ memcpy(buf, &alx_gstrings_stats, sizeof(alx_gstrings_stats));
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+}
+
+static int alx_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ALX_NUM_STATS;
+ default:
+ return -EINVAL;
+ }
+}
+
+const struct ethtool_ops alx_ethtool_ops = {
+ .get_settings = alx_get_settings,
+ .set_settings = alx_set_settings,
+ .get_pauseparam = alx_get_pauseparam,
+ .set_pauseparam = alx_set_pauseparam,
+ .get_msglevel = alx_get_msglevel,
+ .set_msglevel = alx_set_msglevel,
+ .get_link = ethtool_op_get_link,
+ .get_strings = alx_get_strings,
+ .get_sset_count = alx_get_sset_count,
+ .get_ethtool_stats = alx_get_ethtool_stats,
+};
diff --git a/drivers/net/ethernet/atheros/alx/hw.c b/drivers/net/ethernet/atheros/alx/hw.c
new file mode 100644
index 00000000000..7712f068f6d
--- /dev/null
+++ b/drivers/net/ethernet/atheros/alx/hw.c
@@ -0,0 +1,1110 @@
+/*
+ * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is free software: you may copy, redistribute and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/mdio.h>
+#include "reg.h"
+#include "hw.h"
+
+static inline bool alx_is_rev_a(u8 rev)
+{
+ return rev == ALX_REV_A0 || rev == ALX_REV_A1;
+}
+
+static int alx_wait_mdio_idle(struct alx_hw *hw)
+{
+ u32 val;
+ int i;
+
+ for (i = 0; i < ALX_MDIO_MAX_AC_TO; i++) {
+ val = alx_read_mem32(hw, ALX_MDIO);
+ if (!(val & ALX_MDIO_BUSY))
+ return 0;
+ udelay(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int alx_read_phy_core(struct alx_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 *phy_data)
+{
+ u32 val, clk_sel;
+ int err;
+
+ *phy_data = 0;
+
+ /* use slow clock when it's in hibernation status */
+ clk_sel = hw->link_speed != SPEED_UNKNOWN ?
+ ALX_MDIO_CLK_SEL_25MD4 :
+ ALX_MDIO_CLK_SEL_25MD128;
+
+ if (ext) {
+ val = dev << ALX_MDIO_EXTN_DEVAD_SHIFT |
+ reg << ALX_MDIO_EXTN_REG_SHIFT;
+ alx_write_mem32(hw, ALX_MDIO_EXTN, val);
+
+ val = ALX_MDIO_SPRES_PRMBL | ALX_MDIO_START |
+ ALX_MDIO_MODE_EXT | ALX_MDIO_OP_READ |
+ clk_sel << ALX_MDIO_CLK_SEL_SHIFT;
+ } else {
+ val = ALX_MDIO_SPRES_PRMBL |
+ clk_sel << ALX_MDIO_CLK_SEL_SHIFT |
+ reg << ALX_MDIO_REG_SHIFT |
+ ALX_MDIO_START | ALX_MDIO_OP_READ;
+ }
+ alx_write_mem32(hw, ALX_MDIO, val);
+
+ err = alx_wait_mdio_idle(hw);
+ if (err)
+ return err;
+ val = alx_read_mem32(hw, ALX_MDIO);
+ *phy_data = ALX_GET_FIELD(val, ALX_MDIO_DATA);
+ return 0;
+}
+
+static int alx_write_phy_core(struct alx_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 phy_data)
+{
+ u32 val, clk_sel;
+
+ /* use slow clock when it's in hibernation status */
+ clk_sel = hw->link_speed != SPEED_UNKNOWN ?
+ ALX_MDIO_CLK_SEL_25MD4 :
+ ALX_MDIO_CLK_SEL_25MD128;
+
+ if (ext) {
+ val = dev << ALX_MDIO_EXTN_DEVAD_SHIFT |
+ reg << ALX_MDIO_EXTN_REG_SHIFT;
+ alx_write_mem32(hw, ALX_MDIO_EXTN, val);
+
+ val = ALX_MDIO_SPRES_PRMBL |
+ clk_sel << ALX_MDIO_CLK_SEL_SHIFT |
+ phy_data << ALX_MDIO_DATA_SHIFT |
+ ALX_MDIO_START | ALX_MDIO_MODE_EXT;
+ } else {
+ val = ALX_MDIO_SPRES_PRMBL |
+ clk_sel << ALX_MDIO_CLK_SEL_SHIFT |
+ reg << ALX_MDIO_REG_SHIFT |
+ phy_data << ALX_MDIO_DATA_SHIFT |
+ ALX_MDIO_START;
+ }
+ alx_write_mem32(hw, ALX_MDIO, val);
+
+ return alx_wait_mdio_idle(hw);
+}
+
+static int __alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data)
+{
+ return alx_read_phy_core(hw, false, 0, reg, phy_data);
+}
+
+static int __alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data)
+{
+ return alx_write_phy_core(hw, false, 0, reg, phy_data);
+}
+
+static int __alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata)
+{
+ return alx_read_phy_core(hw, true, dev, reg, pdata);
+}
+
+static int __alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data)
+{
+ return alx_write_phy_core(hw, true, dev, reg, data);
+}
+
+static int __alx_read_phy_dbg(struct alx_hw *hw, u16 reg, u16 *pdata)
+{
+ int err;
+
+ err = __alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, reg);
+ if (err)
+ return err;
+
+ return __alx_read_phy_reg(hw, ALX_MII_DBG_DATA, pdata);
+}
+
+static int __alx_write_phy_dbg(struct alx_hw *hw, u16 reg, u16 data)
+{
+ int err;
+
+ err = __alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, reg);
+ if (err)
+ return err;
+
+ return __alx_write_phy_reg(hw, ALX_MII_DBG_DATA, data);
+}
+
+int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data)
+{
+ int err;
+
+ spin_lock(&hw->mdio_lock);
+ err = __alx_read_phy_reg(hw, reg, phy_data);
+ spin_unlock(&hw->mdio_lock);
+
+ return err;
+}
+
+int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data)
+{
+ int err;
+
+ spin_lock(&hw->mdio_lock);
+ err = __alx_write_phy_reg(hw, reg, phy_data);
+ spin_unlock(&hw->mdio_lock);
+
+ return err;
+}
+
+int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata)
+{
+ int err;
+
+ spin_lock(&hw->mdio_lock);
+ err = __alx_read_phy_ext(hw, dev, reg, pdata);
+ spin_unlock(&hw->mdio_lock);
+
+ return err;
+}
+
+int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data)
+{
+ int err;
+
+ spin_lock(&hw->mdio_lock);
+ err = __alx_write_phy_ext(hw, dev, reg, data);
+ spin_unlock(&hw->mdio_lock);
+
+ return err;
+}
+
+static int alx_read_phy_dbg(struct alx_hw *hw, u16 reg, u16 *pdata)
+{
+ int err;
+
+ spin_lock(&hw->mdio_lock);
+ err = __alx_read_phy_dbg(hw, reg, pdata);
+ spin_unlock(&hw->mdio_lock);
+
+ return err;
+}
+
+static int alx_write_phy_dbg(struct alx_hw *hw, u16 reg, u16 data)
+{
+ int err;
+
+ spin_lock(&hw->mdio_lock);
+ err = __alx_write_phy_dbg(hw, reg, data);
+ spin_unlock(&hw->mdio_lock);
+
+ return err;
+}
+
+static u16 alx_get_phy_config(struct alx_hw *hw)
+{
+ u32 val;
+ u16 phy_val;
+
+ val = alx_read_mem32(hw, ALX_PHY_CTRL);
+ /* phy in reset */
+ if ((val & ALX_PHY_CTRL_DSPRST_OUT) == 0)
+ return ALX_DRV_PHY_UNKNOWN;
+
+ val = alx_read_mem32(hw, ALX_DRV);
+ val = ALX_GET_FIELD(val, ALX_DRV_PHY);
+ if (ALX_DRV_PHY_UNKNOWN == val)
+ return ALX_DRV_PHY_UNKNOWN;
+
+ alx_read_phy_reg(hw, ALX_MII_DBG_ADDR, &phy_val);
+ if (ALX_PHY_INITED == phy_val)
+ return val;
+
+ return ALX_DRV_PHY_UNKNOWN;
+}
+
+static bool alx_wait_reg(struct alx_hw *hw, u32 reg, u32 wait, u32 *val)
+{
+ u32 read;
+ int i;
+
+ for (i = 0; i < ALX_SLD_MAX_TO; i++) {
+ read = alx_read_mem32(hw, reg);
+ if ((read & wait) == 0) {
+ if (val)
+ *val = read;
+ return true;
+ }
+ mdelay(1);
+ }
+
+ return false;
+}
+
+static bool alx_read_macaddr(struct alx_hw *hw, u8 *addr)
+{
+ u32 mac0, mac1;
+
+ mac0 = alx_read_mem32(hw, ALX_STAD0);
+ mac1 = alx_read_mem32(hw, ALX_STAD1);
+
+ /* addr should be big-endian */
+ put_unaligned(cpu_to_be32(mac0), (__be32 *)(addr + 2));
+ put_unaligned(cpu_to_be16(mac1), (__be16 *)addr);
+
+ return is_valid_ether_addr(addr);
+}
+
+int alx_get_perm_macaddr(struct alx_hw *hw, u8 *addr)
+{
+ u32 val;
+
+ /* try to get it from register first */
+ if (alx_read_macaddr(hw, addr))
+ return 0;
+
+ /* try to load from efuse */
+ if (!alx_wait_reg(hw, ALX_SLD, ALX_SLD_STAT | ALX_SLD_START, &val))
+ return -EIO;
+ alx_write_mem32(hw, ALX_SLD, val | ALX_SLD_START);
+ if (!alx_wait_reg(hw, ALX_SLD, ALX_SLD_START, NULL))
+ return -EIO;
+ if (alx_read_macaddr(hw, addr))
+ return 0;
+
+ /* try to load from flash/eeprom (if present) */
+ val = alx_read_mem32(hw, ALX_EFLD);
+ if (val & (ALX_EFLD_F_EXIST | ALX_EFLD_E_EXIST)) {
+ if (!alx_wait_reg(hw, ALX_EFLD,
+ ALX_EFLD_STAT | ALX_EFLD_START, &val))
+ return -EIO;
+ alx_write_mem32(hw, ALX_EFLD, val | ALX_EFLD_START);
+ if (!alx_wait_reg(hw, ALX_EFLD, ALX_EFLD_START, NULL))
+ return -EIO;
+ if (alx_read_macaddr(hw, addr))
+ return 0;
+ }
+
+ return -EIO;
+}
+
+void alx_set_macaddr(struct alx_hw *hw, const u8 *addr)
+{
+ u32 val;
+
+ /* for example: 00-0B-6A-F6-00-DC * STAD0=6AF600DC, STAD1=000B */
+ val = be32_to_cpu(get_unaligned((__be32 *)(addr + 2)));
+ alx_write_mem32(hw, ALX_STAD0, val);
+ val = be16_to_cpu(get_unaligned((__be16 *)addr));
+ alx_write_mem32(hw, ALX_STAD1, val);
+}
+
+static void alx_reset_osc(struct alx_hw *hw, u8 rev)
+{
+ u32 val, val2;
+
+ /* clear Internal OSC settings, switching OSC by hw itself */
+ val = alx_read_mem32(hw, ALX_MISC3);
+ alx_write_mem32(hw, ALX_MISC3,
+ (val & ~ALX_MISC3_25M_BY_SW) |
+ ALX_MISC3_25M_NOTO_INTNL);
+
+ /* 25M clk from chipset may be unstable 1s after de-assert of
+ * PERST, driver need re-calibrate before enter Sleep for WoL
+ */
+ val = alx_read_mem32(hw, ALX_MISC);
+ if (rev >= ALX_REV_B0) {
+ /* restore over current protection def-val,
+ * this val could be reset by MAC-RST
+ */
+ ALX_SET_FIELD(val, ALX_MISC_PSW_OCP, ALX_MISC_PSW_OCP_DEF);
+ /* a 0->1 change will update the internal val of osc */
+ val &= ~ALX_MISC_INTNLOSC_OPEN;
+ alx_write_mem32(hw, ALX_MISC, val);
+ alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN);
+ /* hw will automatically dis OSC after cab. */
+ val2 = alx_read_mem32(hw, ALX_MSIC2);
+ val2 &= ~ALX_MSIC2_CALB_START;
+ alx_write_mem32(hw, ALX_MSIC2, val2);
+ alx_write_mem32(hw, ALX_MSIC2, val2 | ALX_MSIC2_CALB_START);
+ } else {
+ val &= ~ALX_MISC_INTNLOSC_OPEN;
+ /* disable isolate for rev A devices */
+ if (alx_is_rev_a(rev))
+ val &= ~ALX_MISC_ISO_EN;
+
+ alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN);
+ alx_write_mem32(hw, ALX_MISC, val);
+ }
+
+ udelay(20);
+}
+
+static int alx_stop_mac(struct alx_hw *hw)
+{
+ u32 rxq, txq, val;
+ u16 i;
+
+ rxq = alx_read_mem32(hw, ALX_RXQ0);
+ alx_write_mem32(hw, ALX_RXQ0, rxq & ~ALX_RXQ0_EN);
+ txq = alx_read_mem32(hw, ALX_TXQ0);
+ alx_write_mem32(hw, ALX_TXQ0, txq & ~ALX_TXQ0_EN);
+
+ udelay(40);
+
+ hw->rx_ctrl &= ~(ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_TX_EN);
+ alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl);
+
+ for (i = 0; i < ALX_DMA_MAC_RST_TO; i++) {
+ val = alx_read_mem32(hw, ALX_MAC_STS);
+ if (!(val & ALX_MAC_STS_IDLE))
+ return 0;
+ udelay(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+int alx_reset_mac(struct alx_hw *hw)
+{
+ u32 val, pmctrl;
+ int i, ret;
+ u8 rev;
+ bool a_cr;
+
+ pmctrl = 0;
+ rev = alx_hw_revision(hw);
+ a_cr = alx_is_rev_a(rev) && alx_hw_with_cr(hw);
+
+ /* disable all interrupts, RXQ/TXQ */
+ alx_write_mem32(hw, ALX_MSIX_MASK, 0xFFFFFFFF);
+ alx_write_mem32(hw, ALX_IMR, 0);
+ alx_write_mem32(hw, ALX_ISR, ALX_ISR_DIS);
+
+ ret = alx_stop_mac(hw);
+ if (ret)
+ return ret;
+
+ /* mac reset workaroud */
+ alx_write_mem32(hw, ALX_RFD_PIDX, 1);
+
+ /* dis l0s/l1 before mac reset */
+ if (a_cr) {
+ pmctrl = alx_read_mem32(hw, ALX_PMCTRL);
+ if (pmctrl & (ALX_PMCTRL_L1_EN | ALX_PMCTRL_L0S_EN))
+ alx_write_mem32(hw, ALX_PMCTRL,
+ pmctrl & ~(ALX_PMCTRL_L1_EN |
+ ALX_PMCTRL_L0S_EN));
+ }
+
+ /* reset whole mac safely */
+ val = alx_read_mem32(hw, ALX_MASTER);
+ alx_write_mem32(hw, ALX_MASTER,
+ val | ALX_MASTER_DMA_MAC_RST | ALX_MASTER_OOB_DIS);
+
+ /* make sure it's real idle */
+ udelay(10);
+ for (i = 0; i < ALX_DMA_MAC_RST_TO; i++) {
+ val = alx_read_mem32(hw, ALX_RFD_PIDX);
+ if (val == 0)
+ break;
+ udelay(10);
+ }
+ for (; i < ALX_DMA_MAC_RST_TO; i++) {
+ val = alx_read_mem32(hw, ALX_MASTER);
+ if ((val & ALX_MASTER_DMA_MAC_RST) == 0)
+ break;
+ udelay(10);
+ }
+ if (i == ALX_DMA_MAC_RST_TO)
+ return -EIO;
+ udelay(10);
+
+ if (a_cr) {
+ alx_write_mem32(hw, ALX_MASTER, val | ALX_MASTER_PCLKSEL_SRDS);
+ /* restore l0s / l1 */
+ if (pmctrl & (ALX_PMCTRL_L1_EN | ALX_PMCTRL_L0S_EN))
+ alx_write_mem32(hw, ALX_PMCTRL, pmctrl);
+ }
+
+ alx_reset_osc(hw, rev);
+
+ /* clear Internal OSC settings, switching OSC by hw itself,
+ * disable isolate for rev A devices
+ */
+ val = alx_read_mem32(hw, ALX_MISC3);
+ alx_write_mem32(hw, ALX_MISC3,
+ (val & ~ALX_MISC3_25M_BY_SW) |
+ ALX_MISC3_25M_NOTO_INTNL);
+ val = alx_read_mem32(hw, ALX_MISC);
+ val &= ~ALX_MISC_INTNLOSC_OPEN;
+ if (alx_is_rev_a(rev))
+ val &= ~ALX_MISC_ISO_EN;
+ alx_write_mem32(hw, ALX_MISC, val);
+ udelay(20);
+
+ /* driver control speed/duplex, hash-alg */
+ alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl);
+
+ val = alx_read_mem32(hw, ALX_SERDES);
+ alx_write_mem32(hw, ALX_SERDES,
+ val | ALX_SERDES_MACCLK_SLWDWN |
+ ALX_SERDES_PHYCLK_SLWDWN);
+
+ return 0;
+}
+
+void alx_reset_phy(struct alx_hw *hw)
+{
+ int i;
+ u32 val;
+ u16 phy_val;
+
+ /* (DSP)reset PHY core */
+ val = alx_read_mem32(hw, ALX_PHY_CTRL);
+ val &= ~(ALX_PHY_CTRL_DSPRST_OUT | ALX_PHY_CTRL_IDDQ |
+ ALX_PHY_CTRL_GATE_25M | ALX_PHY_CTRL_POWER_DOWN |
+ ALX_PHY_CTRL_CLS);
+ val |= ALX_PHY_CTRL_RST_ANALOG;
+
+ val |= (ALX_PHY_CTRL_HIB_PULSE | ALX_PHY_CTRL_HIB_EN);
+ alx_write_mem32(hw, ALX_PHY_CTRL, val);
+ udelay(10);
+ alx_write_mem32(hw, ALX_PHY_CTRL, val | ALX_PHY_CTRL_DSPRST_OUT);
+
+ for (i = 0; i < ALX_PHY_CTRL_DSPRST_TO; i++)
+ udelay(10);
+
+ /* phy power saving & hib */
+ alx_write_phy_dbg(hw, ALX_MIIDBG_LEGCYPS, ALX_LEGCYPS_DEF);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_SYSMODCTRL,
+ ALX_SYSMODCTRL_IECHOADJ_DEF);
+ alx_write_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_VDRVBIAS,
+ ALX_VDRVBIAS_DEF);
+
+ /* EEE advertisement */
+ val = alx_read_mem32(hw, ALX_LPI_CTRL);
+ alx_write_mem32(hw, ALX_LPI_CTRL, val & ~ALX_LPI_CTRL_EN);
+ alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_LOCAL_EEEADV, 0);
+
+ /* phy power saving */
+ alx_write_phy_dbg(hw, ALX_MIIDBG_TST10BTCFG, ALX_TST10BTCFG_DEF);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_SRDSYSMOD, ALX_SRDSYSMOD_DEF);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_TST100BTCFG, ALX_TST100BTCFG_DEF);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_ANACTRL, ALX_ANACTRL_DEF);
+ alx_read_phy_dbg(hw, ALX_MIIDBG_GREENCFG2, &phy_val);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_GREENCFG2,
+ phy_val & ~ALX_GREENCFG2_GATE_DFSE_EN);
+ /* rtl8139c, 120m issue */
+ alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_NLP78,
+ ALX_MIIEXT_NLP78_120M_DEF);
+ alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_S3DIG10,
+ ALX_MIIEXT_S3DIG10_DEF);
+
+ if (hw->lnk_patch) {
+ /* Turn off half amplitude */
+ alx_read_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL3,
+ &phy_val);
+ alx_write_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL3,
+ phy_val | ALX_CLDCTRL3_BP_CABLE1TH_DET_GT);
+ /* Turn off Green feature */
+ alx_read_phy_dbg(hw, ALX_MIIDBG_GREENCFG2, &phy_val);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_GREENCFG2,
+ phy_val | ALX_GREENCFG2_BP_GREEN);
+ /* Turn off half Bias */
+ alx_read_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL5,
+ &phy_val);
+ alx_write_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL5,
+ phy_val | ALX_CLDCTRL5_BP_VD_HLFBIAS);
+ }
+
+ /* set phy interrupt mask */
+ alx_write_phy_reg(hw, ALX_MII_IER, ALX_IER_LINK_UP | ALX_IER_LINK_DOWN);
+}
+
+#define ALX_PCI_CMD (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO)
+
+void alx_reset_pcie(struct alx_hw *hw)
+{
+ u8 rev = alx_hw_revision(hw);
+ u32 val;
+ u16 val16;
+
+ /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
+ pci_read_config_word(hw->pdev, PCI_COMMAND, &val16);
+ if (!(val16 & ALX_PCI_CMD) || (val16 & PCI_COMMAND_INTX_DISABLE)) {
+ val16 = (val16 | ALX_PCI_CMD) & ~PCI_COMMAND_INTX_DISABLE;
+ pci_write_config_word(hw->pdev, PCI_COMMAND, val16);
+ }
+
+ /* clear WoL setting/status */
+ val = alx_read_mem32(hw, ALX_WOL0);
+ alx_write_mem32(hw, ALX_WOL0, 0);
+
+ val = alx_read_mem32(hw, ALX_PDLL_TRNS1);
+ alx_write_mem32(hw, ALX_PDLL_TRNS1, val & ~ALX_PDLL_TRNS1_D3PLLOFF_EN);
+
+ /* mask some pcie error bits */
+ val = alx_read_mem32(hw, ALX_UE_SVRT);
+ val &= ~(ALX_UE_SVRT_DLPROTERR | ALX_UE_SVRT_FCPROTERR);
+ alx_write_mem32(hw, ALX_UE_SVRT, val);
+
+ /* wol 25M & pclk */
+ val = alx_read_mem32(hw, ALX_MASTER);
+ if (alx_is_rev_a(rev) && alx_hw_with_cr(hw)) {
+ if ((val & ALX_MASTER_WAKEN_25M) == 0 ||
+ (val & ALX_MASTER_PCLKSEL_SRDS) == 0)
+ alx_write_mem32(hw, ALX_MASTER,
+ val | ALX_MASTER_PCLKSEL_SRDS |
+ ALX_MASTER_WAKEN_25M);
+ } else {
+ if ((val & ALX_MASTER_WAKEN_25M) == 0 ||
+ (val & ALX_MASTER_PCLKSEL_SRDS) != 0)
+ alx_write_mem32(hw, ALX_MASTER,
+ (val & ~ALX_MASTER_PCLKSEL_SRDS) |
+ ALX_MASTER_WAKEN_25M);
+ }
+
+ /* ASPM setting */
+ alx_enable_aspm(hw, true, true);
+
+ udelay(10);
+}
+
+void alx_start_mac(struct alx_hw *hw)
+{
+ u32 mac, txq, rxq;
+
+ rxq = alx_read_mem32(hw, ALX_RXQ0);
+ alx_write_mem32(hw, ALX_RXQ0, rxq | ALX_RXQ0_EN);
+ txq = alx_read_mem32(hw, ALX_TXQ0);
+ alx_write_mem32(hw, ALX_TXQ0, txq | ALX_TXQ0_EN);
+
+ mac = hw->rx_ctrl;
+ if (hw->duplex == DUPLEX_FULL)
+ mac |= ALX_MAC_CTRL_FULLD;
+ else
+ mac &= ~ALX_MAC_CTRL_FULLD;
+ ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED,
+ hw->link_speed == SPEED_1000 ? ALX_MAC_CTRL_SPEED_1000 :
+ ALX_MAC_CTRL_SPEED_10_100);
+ mac |= ALX_MAC_CTRL_TX_EN | ALX_MAC_CTRL_RX_EN;
+ hw->rx_ctrl = mac;
+ alx_write_mem32(hw, ALX_MAC_CTRL, mac);
+}
+
+void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc)
+{
+ if (fc & ALX_FC_RX)
+ hw->rx_ctrl |= ALX_MAC_CTRL_RXFC_EN;
+ else
+ hw->rx_ctrl &= ~ALX_MAC_CTRL_RXFC_EN;
+
+ if (fc & ALX_FC_TX)
+ hw->rx_ctrl |= ALX_MAC_CTRL_TXFC_EN;
+ else
+ hw->rx_ctrl &= ~ALX_MAC_CTRL_TXFC_EN;
+
+ alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl);
+}
+
+void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en)
+{
+ u32 pmctrl;
+ u8 rev = alx_hw_revision(hw);
+
+ pmctrl = alx_read_mem32(hw, ALX_PMCTRL);
+
+ ALX_SET_FIELD(pmctrl, ALX_PMCTRL_LCKDET_TIMER,
+ ALX_PMCTRL_LCKDET_TIMER_DEF);
+ pmctrl |= ALX_PMCTRL_RCVR_WT_1US |
+ ALX_PMCTRL_L1_CLKSW_EN |
+ ALX_PMCTRL_L1_SRDSRX_PWD;
+ ALX_SET_FIELD(pmctrl, ALX_PMCTRL_L1REQ_TO, ALX_PMCTRL_L1REG_TO_DEF);
+ ALX_SET_FIELD(pmctrl, ALX_PMCTRL_L1_TIMER, ALX_PMCTRL_L1_TIMER_16US);
+ pmctrl &= ~(ALX_PMCTRL_L1_SRDS_EN |
+ ALX_PMCTRL_L1_SRDSPLL_EN |
+ ALX_PMCTRL_L1_BUFSRX_EN |
+ ALX_PMCTRL_SADLY_EN |
+ ALX_PMCTRL_HOTRST_WTEN|
+ ALX_PMCTRL_L0S_EN |
+ ALX_PMCTRL_L1_EN |
+ ALX_PMCTRL_ASPM_FCEN |
+ ALX_PMCTRL_TXL1_AFTER_L0S |
+ ALX_PMCTRL_RXL1_AFTER_L0S);
+ if (alx_is_rev_a(rev) && alx_hw_with_cr(hw))
+ pmctrl |= ALX_PMCTRL_L1_SRDS_EN | ALX_PMCTRL_L1_SRDSPLL_EN;
+
+ if (l0s_en)
+ pmctrl |= (ALX_PMCTRL_L0S_EN | ALX_PMCTRL_ASPM_FCEN);
+ if (l1_en)
+ pmctrl |= (ALX_PMCTRL_L1_EN | ALX_PMCTRL_ASPM_FCEN);
+
+ alx_write_mem32(hw, ALX_PMCTRL, pmctrl);
+}
+
+
+static u32 ethadv_to_hw_cfg(struct alx_hw *hw, u32 ethadv_cfg)
+{
+ u32 cfg = 0;
+
+ if (ethadv_cfg & ADVERTISED_Autoneg) {
+ cfg |= ALX_DRV_PHY_AUTO;
+ if (ethadv_cfg & ADVERTISED_10baseT_Half)
+ cfg |= ALX_DRV_PHY_10;
+ if (ethadv_cfg & ADVERTISED_10baseT_Full)
+ cfg |= ALX_DRV_PHY_10 | ALX_DRV_PHY_DUPLEX;
+ if (ethadv_cfg & ADVERTISED_100baseT_Half)
+ cfg |= ALX_DRV_PHY_100;
+ if (ethadv_cfg & ADVERTISED_100baseT_Full)
+ cfg |= ALX_DRV_PHY_100 | ALX_DRV_PHY_DUPLEX;
+ if (ethadv_cfg & ADVERTISED_1000baseT_Half)
+ cfg |= ALX_DRV_PHY_1000;
+ if (ethadv_cfg & ADVERTISED_1000baseT_Full)
+ cfg |= ALX_DRV_PHY_100 | ALX_DRV_PHY_DUPLEX;
+ if (ethadv_cfg & ADVERTISED_Pause)
+ cfg |= ADVERTISE_PAUSE_CAP;
+ if (ethadv_cfg & ADVERTISED_Asym_Pause)
+ cfg |= ADVERTISE_PAUSE_ASYM;
+ } else {
+ switch (ethadv_cfg) {
+ case ADVERTISED_10baseT_Half:
+ cfg |= ALX_DRV_PHY_10;
+ break;
+ case ADVERTISED_100baseT_Half:
+ cfg |= ALX_DRV_PHY_100;
+ break;
+ case ADVERTISED_10baseT_Full:
+ cfg |= ALX_DRV_PHY_10 | ALX_DRV_PHY_DUPLEX;
+ break;
+ case ADVERTISED_100baseT_Full:
+ cfg |= ALX_DRV_PHY_100 | ALX_DRV_PHY_DUPLEX;
+ break;
+ }
+ }
+
+ return cfg;
+}
+
+int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl)
+{
+ u16 adv, giga, cr;
+ u32 val;
+ int err = 0;
+
+ alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, 0);
+ val = alx_read_mem32(hw, ALX_DRV);
+ ALX_SET_FIELD(val, ALX_DRV_PHY, 0);
+
+ if (ethadv & ADVERTISED_Autoneg) {
+ adv = ADVERTISE_CSMA;
+ adv |= ethtool_adv_to_mii_adv_t(ethadv);
+
+ if (flowctrl & ALX_FC_ANEG) {
+ if (flowctrl & ALX_FC_RX) {
+ adv |= ADVERTISED_Pause;
+ if (!(flowctrl & ALX_FC_TX))
+ adv |= ADVERTISED_Asym_Pause;
+ } else if (flowctrl & ALX_FC_TX) {
+ adv |= ADVERTISED_Asym_Pause;
+ }
+ }
+ giga = 0;
+ if (alx_hw_giga(hw))
+ giga = ethtool_adv_to_mii_ctrl1000_t(ethadv);
+
+ cr = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART;
+
+ if (alx_write_phy_reg(hw, MII_ADVERTISE, adv) ||
+ alx_write_phy_reg(hw, MII_CTRL1000, giga) ||
+ alx_write_phy_reg(hw, MII_BMCR, cr))
+ err = -EBUSY;
+ } else {
+ cr = BMCR_RESET;
+ if (ethadv == ADVERTISED_100baseT_Half ||
+ ethadv == ADVERTISED_100baseT_Full)
+ cr |= BMCR_SPEED100;
+ if (ethadv == ADVERTISED_10baseT_Full ||
+ ethadv == ADVERTISED_100baseT_Full)
+ cr |= BMCR_FULLDPLX;
+
+ err = alx_write_phy_reg(hw, MII_BMCR, cr);
+ }
+
+ if (!err) {
+ alx_write_phy_reg(hw, ALX_MII_DBG_ADDR, ALX_PHY_INITED);
+ val |= ethadv_to_hw_cfg(hw, ethadv);
+ }
+
+ alx_write_mem32(hw, ALX_DRV, val);
+
+ return err;
+}
+
+
+void alx_post_phy_link(struct alx_hw *hw)
+{
+ u16 phy_val, len, agc;
+ u8 revid = alx_hw_revision(hw);
+ bool adj_th = revid == ALX_REV_B0;
+
+ if (revid != ALX_REV_B0 && !alx_is_rev_a(revid))
+ return;
+
+ /* 1000BT/AZ, wrong cable length */
+ if (hw->link_speed != SPEED_UNKNOWN) {
+ alx_read_phy_ext(hw, ALX_MIIEXT_PCS, ALX_MIIEXT_CLDCTRL6,
+ &phy_val);
+ len = ALX_GET_FIELD(phy_val, ALX_CLDCTRL6_CAB_LEN);
+ alx_read_phy_dbg(hw, ALX_MIIDBG_AGC, &phy_val);
+ agc = ALX_GET_FIELD(phy_val, ALX_AGC_2_VGA);
+
+ if ((hw->link_speed == SPEED_1000 &&
+ (len > ALX_CLDCTRL6_CAB_LEN_SHORT1G ||
+ (len == 0 && agc > ALX_AGC_LONG1G_LIMT))) ||
+ (hw->link_speed == SPEED_100 &&
+ (len > ALX_CLDCTRL6_CAB_LEN_SHORT100M ||
+ (len == 0 && agc > ALX_AGC_LONG100M_LIMT)))) {
+ alx_write_phy_dbg(hw, ALX_MIIDBG_AZ_ANADECT,
+ ALX_AZ_ANADECT_LONG);
+ alx_read_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE,
+ &phy_val);
+ alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE,
+ phy_val | ALX_AFE_10BT_100M_TH);
+ } else {
+ alx_write_phy_dbg(hw, ALX_MIIDBG_AZ_ANADECT,
+ ALX_AZ_ANADECT_DEF);
+ alx_read_phy_ext(hw, ALX_MIIEXT_ANEG,
+ ALX_MIIEXT_AFE, &phy_val);
+ alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE,
+ phy_val & ~ALX_AFE_10BT_100M_TH);
+ }
+
+ /* threshold adjust */
+ if (adj_th && hw->lnk_patch) {
+ if (hw->link_speed == SPEED_100) {
+ alx_write_phy_dbg(hw, ALX_MIIDBG_MSE16DB,
+ ALX_MSE16DB_UP);
+ } else if (hw->link_speed == SPEED_1000) {
+ /*
+ * Giga link threshold, raise the tolerance of
+ * noise 50%
+ */
+ alx_read_phy_dbg(hw, ALX_MIIDBG_MSE20DB,
+ &phy_val);
+ ALX_SET_FIELD(phy_val, ALX_MSE20DB_TH,
+ ALX_MSE20DB_TH_HI);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_MSE20DB,
+ phy_val);
+ }
+ }
+ } else {
+ alx_read_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE,
+ &phy_val);
+ alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, ALX_MIIEXT_AFE,
+ phy_val & ~ALX_AFE_10BT_100M_TH);
+
+ if (adj_th && hw->lnk_patch) {
+ alx_write_phy_dbg(hw, ALX_MIIDBG_MSE16DB,
+ ALX_MSE16DB_DOWN);
+ alx_read_phy_dbg(hw, ALX_MIIDBG_MSE20DB, &phy_val);
+ ALX_SET_FIELD(phy_val, ALX_MSE20DB_TH,
+ ALX_MSE20DB_TH_DEF);
+ alx_write_phy_dbg(hw, ALX_MIIDBG_MSE20DB, phy_val);
+ }
+ }
+}
+
+bool alx_phy_configured(struct alx_hw *hw)
+{
+ u32 cfg, hw_cfg;
+
+ cfg = ethadv_to_hw_cfg(hw, hw->adv_cfg);
+ cfg = ALX_GET_FIELD(cfg, ALX_DRV_PHY);
+ hw_cfg = alx_get_phy_config(hw);
+
+ if (hw_cfg == ALX_DRV_PHY_UNKNOWN)
+ return false;
+
+ return cfg == hw_cfg;
+}
+
+int alx_read_phy_link(struct alx_hw *hw)
+{
+ struct pci_dev *pdev = hw->pdev;
+ u16 bmsr, giga;
+ int err;
+
+ err = alx_read_phy_reg(hw, MII_BMSR, &bmsr);
+ if (err)
+ return err;
+
+ err = alx_read_phy_reg(hw, MII_BMSR, &bmsr);
+ if (err)
+ return err;
+
+ if (!(bmsr & BMSR_LSTATUS)) {
+ hw->link_speed = SPEED_UNKNOWN;
+ hw->duplex = DUPLEX_UNKNOWN;
+ return 0;
+ }
+
+ /* speed/duplex result is saved in PHY Specific Status Register */
+ err = alx_read_phy_reg(hw, ALX_MII_GIGA_PSSR, &giga);
+ if (err)
+ return err;
+
+ if (!(giga & ALX_GIGA_PSSR_SPD_DPLX_RESOLVED))
+ goto wrong_speed;
+
+ switch (giga & ALX_GIGA_PSSR_SPEED) {
+ case ALX_GIGA_PSSR_1000MBS:
+ hw->link_speed = SPEED_1000;
+ break;
+ case ALX_GIGA_PSSR_100MBS:
+ hw->link_speed = SPEED_100;
+ break;
+ case ALX_GIGA_PSSR_10MBS:
+ hw->link_speed = SPEED_10;
+ break;
+ default:
+ goto wrong_speed;
+ }
+
+ hw->duplex = (giga & ALX_GIGA_PSSR_DPLX) ? DUPLEX_FULL : DUPLEX_HALF;
+ return 0;
+
+wrong_speed:
+ dev_err(&pdev->dev, "invalid PHY speed/duplex: 0x%x\n", giga);
+ return -EINVAL;
+}
+
+int alx_clear_phy_intr(struct alx_hw *hw)
+{
+ u16 isr;
+
+ /* clear interrupt status by reading it */
+ return alx_read_phy_reg(hw, ALX_MII_ISR, &isr);
+}
+
+void alx_disable_rss(struct alx_hw *hw)
+{
+ u32 ctrl = alx_read_mem32(hw, ALX_RXQ0);
+
+ ctrl &= ~ALX_RXQ0_RSS_HASH_EN;
+ alx_write_mem32(hw, ALX_RXQ0, ctrl);
+}
+
+void alx_configure_basic(struct alx_hw *hw)
+{
+ u32 val, raw_mtu, max_payload;
+ u16 val16;
+ u8 chip_rev = alx_hw_revision(hw);
+
+ alx_set_macaddr(hw, hw->mac_addr);
+
+ alx_write_mem32(hw, ALX_CLK_GATE, ALX_CLK_GATE_ALL);
+
+ /* idle timeout to switch clk_125M */
+ if (chip_rev >= ALX_REV_B0)
+ alx_write_mem32(hw, ALX_IDLE_DECISN_TIMER,
+ ALX_IDLE_DECISN_TIMER_DEF);
+
+ alx_write_mem32(hw, ALX_SMB_TIMER, hw->smb_timer * 500UL);
+
+ val = alx_read_mem32(hw, ALX_MASTER);
+ val |= ALX_MASTER_IRQMOD2_EN |
+ ALX_MASTER_IRQMOD1_EN |
+ ALX_MASTER_SYSALVTIMER_EN;
+ alx_write_mem32(hw, ALX_MASTER, val);
+ alx_write_mem32(hw, ALX_IRQ_MODU_TIMER,
+ (hw->imt >> 1) << ALX_IRQ_MODU_TIMER1_SHIFT);
+ /* intr re-trig timeout */
+ alx_write_mem32(hw, ALX_INT_RETRIG, ALX_INT_RETRIG_TO);
+ /* tpd threshold to trig int */
+ alx_write_mem32(hw, ALX_TINT_TPD_THRSHLD, hw->ith_tpd);
+ alx_write_mem32(hw, ALX_TINT_TIMER, hw->imt);
+
+ raw_mtu = hw->mtu + ETH_HLEN;
+ alx_write_mem32(hw, ALX_MTU, raw_mtu + 8);
+ if (raw_mtu > ALX_MTU_JUMBO_TH)
+ hw->rx_ctrl &= ~ALX_MAC_CTRL_FAST_PAUSE;
+
+ if ((raw_mtu + 8) < ALX_TXQ1_JUMBO_TSO_TH)
+ val = (raw_mtu + 8 + 7) >> 3;
+ else
+ val = ALX_TXQ1_JUMBO_TSO_TH >> 3;
+ alx_write_mem32(hw, ALX_TXQ1, val | ALX_TXQ1_ERRLGPKT_DROP_EN);
+
+ max_payload = pcie_get_readrq(hw->pdev) >> 8;
+ /*
+ * if BIOS had changed the default dma read max length,
+ * restore it to default value
+ */
+ if (max_payload < ALX_DEV_CTRL_MAXRRS_MIN)
+ pcie_set_readrq(hw->pdev, 128 << ALX_DEV_CTRL_MAXRRS_MIN);
+
+ val = ALX_TXQ_TPD_BURSTPREF_DEF << ALX_TXQ0_TPD_BURSTPREF_SHIFT |
+ ALX_TXQ0_MODE_ENHANCE | ALX_TXQ0_LSO_8023_EN |
+ ALX_TXQ0_SUPT_IPOPT |
+ ALX_TXQ_TXF_BURST_PREF_DEF << ALX_TXQ0_TXF_BURST_PREF_SHIFT;
+ alx_write_mem32(hw, ALX_TXQ0, val);
+ val = ALX_TXQ_TPD_BURSTPREF_DEF << ALX_HQTPD_Q1_NUMPREF_SHIFT |
+ ALX_TXQ_TPD_BURSTPREF_DEF << ALX_HQTPD_Q2_NUMPREF_SHIFT |
+ ALX_TXQ_TPD_BURSTPREF_DEF << ALX_HQTPD_Q3_NUMPREF_SHIFT |
+ ALX_HQTPD_BURST_EN;
+ alx_write_mem32(hw, ALX_HQTPD, val);
+
+ /* rxq, flow control */
+ val = alx_read_mem32(hw, ALX_SRAM5);
+ val = ALX_GET_FIELD(val, ALX_SRAM_RXF_LEN) << 3;
+ if (val > ALX_SRAM_RXF_LEN_8K) {
+ val16 = ALX_MTU_STD_ALGN >> 3;
+ val = (val - ALX_RXQ2_RXF_FLOW_CTRL_RSVD) >> 3;
+ } else {
+ val16 = ALX_MTU_STD_ALGN >> 3;
+ val = (val - ALX_MTU_STD_ALGN) >> 3;
+ }
+ alx_write_mem32(hw, ALX_RXQ2,
+ val16 << ALX_RXQ2_RXF_XOFF_THRESH_SHIFT |
+ val << ALX_RXQ2_RXF_XON_THRESH_SHIFT);
+ val = ALX_RXQ0_NUM_RFD_PREF_DEF << ALX_RXQ0_NUM_RFD_PREF_SHIFT |
+ ALX_RXQ0_RSS_MODE_DIS << ALX_RXQ0_RSS_MODE_SHIFT |
+ ALX_RXQ0_IDT_TBL_SIZE_DEF << ALX_RXQ0_IDT_TBL_SIZE_SHIFT |
+ ALX_RXQ0_RSS_HSTYP_ALL | ALX_RXQ0_RSS_HASH_EN |
+ ALX_RXQ0_IPV6_PARSE_EN;
+
+ if (alx_hw_giga(hw))
+ ALX_SET_FIELD(val, ALX_RXQ0_ASPM_THRESH,
+ ALX_RXQ0_ASPM_THRESH_100M);
+
+ alx_write_mem32(hw, ALX_RXQ0, val);
+
+ val = alx_read_mem32(hw, ALX_DMA);
+ val = ALX_DMA_RORDER_MODE_OUT << ALX_DMA_RORDER_MODE_SHIFT |
+ ALX_DMA_RREQ_PRI_DATA |
+ max_payload << ALX_DMA_RREQ_BLEN_SHIFT |
+ ALX_DMA_WDLY_CNT_DEF << ALX_DMA_WDLY_CNT_SHIFT |
+ ALX_DMA_RDLY_CNT_DEF << ALX_DMA_RDLY_CNT_SHIFT |
+ (hw->dma_chnl - 1) << ALX_DMA_RCHNL_SEL_SHIFT;
+ alx_write_mem32(hw, ALX_DMA, val);
+
+ /* default multi-tx-q weights */
+ val = ALX_WRR_PRI_RESTRICT_NONE << ALX_WRR_PRI_SHIFT |
+ 4 << ALX_WRR_PRI0_SHIFT |
+ 4 << ALX_WRR_PRI1_SHIFT |
+ 4 << ALX_WRR_PRI2_SHIFT |
+ 4 << ALX_WRR_PRI3_SHIFT;
+ alx_write_mem32(hw, ALX_WRR, val);
+}
+
+bool alx_get_phy_info(struct alx_hw *hw)
+{
+ u16 devs1, devs2;
+
+ if (alx_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id[0]) ||
+ alx_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id[1]))
+ return false;
+
+ /* since we haven't PMA/PMD status2 register, we can't
+ * use mdio45_probe function for prtad and mmds.
+ * use fixed MMD3 to get mmds.
+ */
+ if (alx_read_phy_ext(hw, 3, MDIO_DEVS1, &devs1) ||
+ alx_read_phy_ext(hw, 3, MDIO_DEVS2, &devs2))
+ return false;
+ hw->mdio.mmds = devs1 | devs2 << 16;
+
+ return true;
+}
+
+void alx_update_hw_stats(struct alx_hw *hw)
+{
+ /* RX stats */
+ hw->stats.rx_ok += alx_read_mem32(hw, ALX_MIB_RX_OK);
+ hw->stats.rx_bcast += alx_read_mem32(hw, ALX_MIB_RX_BCAST);
+ hw->stats.rx_mcast += alx_read_mem32(hw, ALX_MIB_RX_MCAST);
+ hw->stats.rx_pause += alx_read_mem32(hw, ALX_MIB_RX_PAUSE);
+ hw->stats.rx_ctrl += alx_read_mem32(hw, ALX_MIB_RX_CTRL);
+ hw->stats.rx_fcs_err += alx_read_mem32(hw, ALX_MIB_RX_FCS_ERR);
+ hw->stats.rx_len_err += alx_read_mem32(hw, ALX_MIB_RX_LEN_ERR);
+ hw->stats.rx_byte_cnt += alx_read_mem32(hw, ALX_MIB_RX_BYTE_CNT);
+ hw->stats.rx_runt += alx_read_mem32(hw, ALX_MIB_RX_RUNT);
+ hw->stats.rx_frag += alx_read_mem32(hw, ALX_MIB_RX_FRAG);
+ hw->stats.rx_sz_64B += alx_read_mem32(hw, ALX_MIB_RX_SZ_64B);
+ hw->stats.rx_sz_127B += alx_read_mem32(hw, ALX_MIB_RX_SZ_127B);
+ hw->stats.rx_sz_255B += alx_read_mem32(hw, ALX_MIB_RX_SZ_255B);
+ hw->stats.rx_sz_511B += alx_read_mem32(hw, ALX_MIB_RX_SZ_511B);
+ hw->stats.rx_sz_1023B += alx_read_mem32(hw, ALX_MIB_RX_SZ_1023B);
+ hw->stats.rx_sz_1518B += alx_read_mem32(hw, ALX_MIB_RX_SZ_1518B);
+ hw->stats.rx_sz_max += alx_read_mem32(hw, ALX_MIB_RX_SZ_MAX);
+ hw->stats.rx_ov_sz += alx_read_mem32(hw, ALX_MIB_RX_OV_SZ);
+ hw->stats.rx_ov_rxf += alx_read_mem32(hw, ALX_MIB_RX_OV_RXF);
+ hw->stats.rx_ov_rrd += alx_read_mem32(hw, ALX_MIB_RX_OV_RRD);
+ hw->stats.rx_align_err += alx_read_mem32(hw, ALX_MIB_RX_ALIGN_ERR);
+ hw->stats.rx_bc_byte_cnt += alx_read_mem32(hw, ALX_MIB_RX_BCCNT);
+ hw->stats.rx_mc_byte_cnt += alx_read_mem32(hw, ALX_MIB_RX_MCCNT);
+ hw->stats.rx_err_addr += alx_read_mem32(hw, ALX_MIB_RX_ERRADDR);
+
+ /* TX stats */
+ hw->stats.tx_ok += alx_read_mem32(hw, ALX_MIB_TX_OK);
+ hw->stats.tx_bcast += alx_read_mem32(hw, ALX_MIB_TX_BCAST);
+ hw->stats.tx_mcast += alx_read_mem32(hw, ALX_MIB_TX_MCAST);
+ hw->stats.tx_pause += alx_read_mem32(hw, ALX_MIB_TX_PAUSE);
+ hw->stats.tx_exc_defer += alx_read_mem32(hw, ALX_MIB_TX_EXC_DEFER);
+ hw->stats.tx_ctrl += alx_read_mem32(hw, ALX_MIB_TX_CTRL);
+ hw->stats.tx_defer += alx_read_mem32(hw, ALX_MIB_TX_DEFER);
+ hw->stats.tx_byte_cnt += alx_read_mem32(hw, ALX_MIB_TX_BYTE_CNT);
+ hw->stats.tx_sz_64B += alx_read_mem32(hw, ALX_MIB_TX_SZ_64B);
+ hw->stats.tx_sz_127B += alx_read_mem32(hw, ALX_MIB_TX_SZ_127B);
+ hw->stats.tx_sz_255B += alx_read_mem32(hw, ALX_MIB_TX_SZ_255B);
+ hw->stats.tx_sz_511B += alx_read_mem32(hw, ALX_MIB_TX_SZ_511B);
+ hw->stats.tx_sz_1023B += alx_read_mem32(hw, ALX_MIB_TX_SZ_1023B);
+ hw->stats.tx_sz_1518B += alx_read_mem32(hw, ALX_MIB_TX_SZ_1518B);
+ hw->stats.tx_sz_max += alx_read_mem32(hw, ALX_MIB_TX_SZ_MAX);
+ hw->stats.tx_single_col += alx_read_mem32(hw, ALX_MIB_TX_SINGLE_COL);
+ hw->stats.tx_multi_col += alx_read_mem32(hw, ALX_MIB_TX_MULTI_COL);
+ hw->stats.tx_late_col += alx_read_mem32(hw, ALX_MIB_TX_LATE_COL);
+ hw->stats.tx_abort_col += alx_read_mem32(hw, ALX_MIB_TX_ABORT_COL);
+ hw->stats.tx_underrun += alx_read_mem32(hw, ALX_MIB_TX_UNDERRUN);
+ hw->stats.tx_trd_eop += alx_read_mem32(hw, ALX_MIB_TX_TRD_EOP);
+ hw->stats.tx_len_err += alx_read_mem32(hw, ALX_MIB_TX_LEN_ERR);
+ hw->stats.tx_trunc += alx_read_mem32(hw, ALX_MIB_TX_TRUNC);
+ hw->stats.tx_bc_byte_cnt += alx_read_mem32(hw, ALX_MIB_TX_BCCNT);
+ hw->stats.tx_mc_byte_cnt += alx_read_mem32(hw, ALX_MIB_TX_MCCNT);
+
+ hw->stats.update += alx_read_mem32(hw, ALX_MIB_UPDATE);
+}
diff --git a/drivers/net/ethernet/atheros/alx/hw.h b/drivers/net/ethernet/atheros/alx/hw.h
new file mode 100644
index 00000000000..15548802d6f
--- /dev/null
+++ b/drivers/net/ethernet/atheros/alx/hw.h
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is free software: you may copy, redistribute and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ALX_HW_H_
+#define ALX_HW_H_
+#include <linux/types.h>
+#include <linux/mdio.h>
+#include <linux/pci.h>
+#include "reg.h"
+
+/* Transmit Packet Descriptor, contains 4 32-bit words.
+ *
+ * 31 16 0
+ * +----------------+----------------+
+ * | vlan-tag | buf length |
+ * +----------------+----------------+
+ * | Word 1 |
+ * +----------------+----------------+
+ * | Word 2: buf addr lo |
+ * +----------------+----------------+
+ * | Word 3: buf addr hi |
+ * +----------------+----------------+
+ *
+ * Word 2 and 3 combine to form a 64-bit buffer address
+ *
+ * Word 1 has three forms, depending on the state of bit 8/12/13:
+ * if bit8 =='1', the definition is just for custom checksum offload.
+ * if bit8 == '0' && bit12 == '1' && bit13 == '1', the *FIRST* descriptor
+ * for the skb is special for LSO V2, Word 2 become total skb length ,
+ * Word 3 is meaningless.
+ * other condition, the definition is for general skb or ip/tcp/udp
+ * checksum or LSO(TSO) offload.
+ *
+ * Here is the depiction:
+ *
+ * 0-+ 0-+
+ * 1 | 1 |
+ * 2 | 2 |
+ * 3 | Payload offset 3 | L4 header offset
+ * 4 | (7:0) 4 | (7:0)
+ * 5 | 5 |
+ * 6 | 6 |
+ * 7-+ 7-+
+ * 8 Custom csum enable = 1 8 Custom csum enable = 0
+ * 9 General IPv4 checksum 9 General IPv4 checksum
+ * 10 General TCP checksum 10 General TCP checksum
+ * 11 General UDP checksum 11 General UDP checksum
+ * 12 Large Send Segment enable 12 Large Send Segment enable
+ * 13 Large Send Segment type 13 Large Send Segment type
+ * 14 VLAN tagged 14 VLAN tagged
+ * 15 Insert VLAN tag 15 Insert VLAN tag
+ * 16 IPv4 packet 16 IPv4 packet
+ * 17 Ethernet frame type 17 Ethernet frame type
+ * 18-+ 18-+
+ * 19 | 19 |
+ * 20 | 20 |
+ * 21 | Custom csum offset 21 |
+ * 22 | (25:18) 22 |
+ * 23 | 23 | MSS (30:18)
+ * 24 | 24 |
+ * 25-+ 25 |
+ * 26-+ 26 |
+ * 27 | 27 |
+ * 28 | Reserved 28 |
+ * 29 | 29 |
+ * 30-+ 30-+
+ * 31 End of packet 31 End of packet
+ */
+struct alx_txd {
+ __le16 len;
+ __le16 vlan_tag;
+ __le32 word1;
+ union {
+ __le64 addr;
+ struct {
+ __le32 pkt_len;
+ __le32 resvd;
+ } l;
+ } adrl;
+} __packed;
+
+/* tpd word 1 */
+#define TPD_CXSUMSTART_MASK 0x00FF
+#define TPD_CXSUMSTART_SHIFT 0
+#define TPD_L4HDROFFSET_MASK 0x00FF
+#define TPD_L4HDROFFSET_SHIFT 0
+#define TPD_CXSUM_EN_MASK 0x0001
+#define TPD_CXSUM_EN_SHIFT 8
+#define TPD_IP_XSUM_MASK 0x0001
+#define TPD_IP_XSUM_SHIFT 9
+#define TPD_TCP_XSUM_MASK 0x0001
+#define TPD_TCP_XSUM_SHIFT 10
+#define TPD_UDP_XSUM_MASK 0x0001
+#define TPD_UDP_XSUM_SHIFT 11
+#define TPD_LSO_EN_MASK 0x0001
+#define TPD_LSO_EN_SHIFT 12
+#define TPD_LSO_V2_MASK 0x0001
+#define TPD_LSO_V2_SHIFT 13
+#define TPD_VLTAGGED_MASK 0x0001
+#define TPD_VLTAGGED_SHIFT 14
+#define TPD_INS_VLTAG_MASK 0x0001
+#define TPD_INS_VLTAG_SHIFT 15
+#define TPD_IPV4_MASK 0x0001
+#define TPD_IPV4_SHIFT 16
+#define TPD_ETHTYPE_MASK 0x0001
+#define TPD_ETHTYPE_SHIFT 17
+#define TPD_CXSUMOFFSET_MASK 0x00FF
+#define TPD_CXSUMOFFSET_SHIFT 18
+#define TPD_MSS_MASK 0x1FFF
+#define TPD_MSS_SHIFT 18
+#define TPD_EOP_MASK 0x0001
+#define TPD_EOP_SHIFT 31
+
+#define DESC_GET(_x, _name) ((_x) >> _name##SHIFT & _name##MASK)
+
+/* Receive Free Descriptor */
+struct alx_rfd {
+ __le64 addr; /* data buffer address, length is
+ * declared in register --- every
+ * buffer has the same size
+ */
+} __packed;
+
+/* Receive Return Descriptor, contains 4 32-bit words.
+ *
+ * 31 16 0
+ * +----------------+----------------+
+ * | Word 0 |
+ * +----------------+----------------+
+ * | Word 1: RSS Hash value |
+ * +----------------+----------------+
+ * | Word 2 |
+ * +----------------+----------------+
+ * | Word 3 |
+ * +----------------+----------------+
+ *
+ * Word 0 depiction & Word 2 depiction:
+ *
+ * 0--+ 0--+
+ * 1 | 1 |
+ * 2 | 2 |
+ * 3 | 3 |
+ * 4 | 4 |
+ * 5 | 5 |
+ * 6 | 6 |
+ * 7 | IP payload checksum 7 | VLAN tag
+ * 8 | (15:0) 8 | (15:0)
+ * 9 | 9 |
+ * 10 | 10 |
+ * 11 | 11 |
+ * 12 | 12 |
+ * 13 | 13 |
+ * 14 | 14 |
+ * 15-+ 15-+
+ * 16-+ 16-+
+ * 17 | Number of RFDs 17 |
+ * 18 | (19:16) 18 |
+ * 19-+ 19 | Protocol ID
+ * 20-+ 20 | (23:16)
+ * 21 | 21 |
+ * 22 | 22 |
+ * 23 | 23-+
+ * 24 | 24 | Reserved
+ * 25 | Start index of RFD-ring 25-+
+ * 26 | (31:20) 26 | RSS Q-num (27:25)
+ * 27 | 27-+
+ * 28 | 28-+
+ * 29 | 29 | RSS Hash algorithm
+ * 30 | 30 | (31:28)
+ * 31-+ 31-+
+ *
+ * Word 3 depiction:
+ *
+ * 0--+
+ * 1 |
+ * 2 |
+ * 3 |
+ * 4 |
+ * 5 |
+ * 6 |
+ * 7 | Packet length (include FCS)
+ * 8 | (13:0)
+ * 9 |
+ * 10 |
+ * 11 |
+ * 12 |
+ * 13-+
+ * 14 L4 Header checksum error
+ * 15 IPv4 checksum error
+ * 16 VLAN tagged
+ * 17-+
+ * 18 | Protocol ID (19:17)
+ * 19-+
+ * 20 Receive error summary
+ * 21 FCS(CRC) error
+ * 22 Frame alignment error
+ * 23 Truncated packet
+ * 24 Runt packet
+ * 25 Incomplete packet due to insufficient rx-desc
+ * 26 Broadcast packet
+ * 27 Multicast packet
+ * 28 Ethernet type (EII or 802.3)
+ * 29 FIFO overflow
+ * 30 Length error (for 802.3, length field mismatch with actual len)
+ * 31 Updated, indicate to driver that this RRD is refreshed.
+ */
+struct alx_rrd {
+ __le32 word0;
+ __le32 rss_hash;
+ __le32 word2;
+ __le32 word3;
+} __packed;
+
+/* rrd word 0 */
+#define RRD_XSUM_MASK 0xFFFF
+#define RRD_XSUM_SHIFT 0
+#define RRD_NOR_MASK 0x000F
+#define RRD_NOR_SHIFT 16
+#define RRD_SI_MASK 0x0FFF
+#define RRD_SI_SHIFT 20
+
+/* rrd word 2 */
+#define RRD_VLTAG_MASK 0xFFFF
+#define RRD_VLTAG_SHIFT 0
+#define RRD_PID_MASK 0x00FF
+#define RRD_PID_SHIFT 16
+/* non-ip packet */
+#define RRD_PID_NONIP 0
+/* ipv4(only) */
+#define RRD_PID_IPV4 1
+/* tcp/ipv6 */
+#define RRD_PID_IPV6TCP 2
+/* tcp/ipv4 */
+#define RRD_PID_IPV4TCP 3
+/* udp/ipv6 */
+#define RRD_PID_IPV6UDP 4
+/* udp/ipv4 */
+#define RRD_PID_IPV4UDP 5
+/* ipv6(only) */
+#define RRD_PID_IPV6 6
+/* LLDP packet */
+#define RRD_PID_LLDP 7
+/* 1588 packet */
+#define RRD_PID_1588 8
+#define RRD_RSSQ_MASK 0x0007
+#define RRD_RSSQ_SHIFT 25
+#define RRD_RSSALG_MASK 0x000F
+#define RRD_RSSALG_SHIFT 28
+#define RRD_RSSALG_TCPV6 0x1
+#define RRD_RSSALG_IPV6 0x2
+#define RRD_RSSALG_TCPV4 0x4
+#define RRD_RSSALG_IPV4 0x8
+
+/* rrd word 3 */
+#define RRD_PKTLEN_MASK 0x3FFF
+#define RRD_PKTLEN_SHIFT 0
+#define RRD_ERR_L4_MASK 0x0001
+#define RRD_ERR_L4_SHIFT 14
+#define RRD_ERR_IPV4_MASK 0x0001
+#define RRD_ERR_IPV4_SHIFT 15
+#define RRD_VLTAGGED_MASK 0x0001
+#define RRD_VLTAGGED_SHIFT 16
+#define RRD_OLD_PID_MASK 0x0007
+#define RRD_OLD_PID_SHIFT 17
+#define RRD_ERR_RES_MASK 0x0001
+#define RRD_ERR_RES_SHIFT 20
+#define RRD_ERR_FCS_MASK 0x0001
+#define RRD_ERR_FCS_SHIFT 21
+#define RRD_ERR_FAE_MASK 0x0001
+#define RRD_ERR_FAE_SHIFT 22
+#define RRD_ERR_TRUNC_MASK 0x0001
+#define RRD_ERR_TRUNC_SHIFT 23
+#define RRD_ERR_RUNT_MASK 0x0001
+#define RRD_ERR_RUNT_SHIFT 24
+#define RRD_ERR_ICMP_MASK 0x0001
+#define RRD_ERR_ICMP_SHIFT 25
+#define RRD_BCAST_MASK 0x0001
+#define RRD_BCAST_SHIFT 26
+#define RRD_MCAST_MASK 0x0001
+#define RRD_MCAST_SHIFT 27
+#define RRD_ETHTYPE_MASK 0x0001
+#define RRD_ETHTYPE_SHIFT 28
+#define RRD_ERR_FIFOV_MASK 0x0001
+#define RRD_ERR_FIFOV_SHIFT 29
+#define RRD_ERR_LEN_MASK 0x0001
+#define RRD_ERR_LEN_SHIFT 30
+#define RRD_UPDATED_MASK 0x0001
+#define RRD_UPDATED_SHIFT 31
+
+
+#define ALX_MAX_SETUP_LNK_CYCLE 50
+
+/* for FlowControl */
+#define ALX_FC_RX 0x01
+#define ALX_FC_TX 0x02
+#define ALX_FC_ANEG 0x04
+
+/* for sleep control */
+#define ALX_SLEEP_WOL_PHY 0x00000001
+#define ALX_SLEEP_WOL_MAGIC 0x00000002
+#define ALX_SLEEP_CIFS 0x00000004
+#define ALX_SLEEP_ACTIVE (ALX_SLEEP_WOL_PHY | \
+ ALX_SLEEP_WOL_MAGIC | \
+ ALX_SLEEP_CIFS)
+
+/* for RSS hash type */
+#define ALX_RSS_HASH_TYPE_IPV4 0x1
+#define ALX_RSS_HASH_TYPE_IPV4_TCP 0x2
+#define ALX_RSS_HASH_TYPE_IPV6 0x4
+#define ALX_RSS_HASH_TYPE_IPV6_TCP 0x8
+#define ALX_RSS_HASH_TYPE_ALL (ALX_RSS_HASH_TYPE_IPV4 | \
+ ALX_RSS_HASH_TYPE_IPV4_TCP | \
+ ALX_RSS_HASH_TYPE_IPV6 | \
+ ALX_RSS_HASH_TYPE_IPV6_TCP)
+#define ALX_DEF_RXBUF_SIZE 1536
+#define ALX_MAX_JUMBO_PKT_SIZE (9*1024)
+#define ALX_MAX_TSO_PKT_SIZE (7*1024)
+#define ALX_MAX_FRAME_SIZE ALX_MAX_JUMBO_PKT_SIZE
+#define ALX_MIN_FRAME_SIZE 68
+#define ALX_RAW_MTU(_mtu) (_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN)
+
+#define ALX_MAX_RX_QUEUES 8
+#define ALX_MAX_TX_QUEUES 4
+#define ALX_MAX_HANDLED_INTRS 5
+
+#define ALX_ISR_MISC (ALX_ISR_PCIE_LNKDOWN | \
+ ALX_ISR_DMAW | \
+ ALX_ISR_DMAR | \
+ ALX_ISR_SMB | \
+ ALX_ISR_MANU | \
+ ALX_ISR_TIMER)
+
+#define ALX_ISR_FATAL (ALX_ISR_PCIE_LNKDOWN | \
+ ALX_ISR_DMAW | ALX_ISR_DMAR)
+
+#define ALX_ISR_ALERT (ALX_ISR_RXF_OV | \
+ ALX_ISR_TXF_UR | \
+ ALX_ISR_RFD_UR)
+
+#define ALX_ISR_ALL_QUEUES (ALX_ISR_TX_Q0 | \
+ ALX_ISR_TX_Q1 | \
+ ALX_ISR_TX_Q2 | \
+ ALX_ISR_TX_Q3 | \
+ ALX_ISR_RX_Q0 | \
+ ALX_ISR_RX_Q1 | \
+ ALX_ISR_RX_Q2 | \
+ ALX_ISR_RX_Q3 | \
+ ALX_ISR_RX_Q4 | \
+ ALX_ISR_RX_Q5 | \
+ ALX_ISR_RX_Q6 | \
+ ALX_ISR_RX_Q7)
+
+/* Statistics counters collected by the MAC
+ *
+ * The order of the fields must match the strings in alx_gstrings_stats
+ * All stats fields should be u64
+ * See ethtool.c
+ */
+struct alx_hw_stats {
+ /* rx */
+ u64 rx_ok; /* good RX packets */
+ u64 rx_bcast; /* good RX broadcast packets */
+ u64 rx_mcast; /* good RX multicast packets */
+ u64 rx_pause; /* RX pause frames */
+ u64 rx_ctrl; /* RX control packets other than pause frames */
+ u64 rx_fcs_err; /* RX packets with bad FCS */
+ u64 rx_len_err; /* RX packets with length != actual size */
+ u64 rx_byte_cnt; /* good bytes received. FCS is NOT included */
+ u64 rx_runt; /* RX packets < 64 bytes with good FCS */
+ u64 rx_frag; /* RX packets < 64 bytes with bad FCS */
+ u64 rx_sz_64B; /* 64 byte RX packets */
+ u64 rx_sz_127B; /* 65-127 byte RX packets */
+ u64 rx_sz_255B; /* 128-255 byte RX packets */
+ u64 rx_sz_511B; /* 256-511 byte RX packets */
+ u64 rx_sz_1023B; /* 512-1023 byte RX packets */
+ u64 rx_sz_1518B; /* 1024-1518 byte RX packets */
+ u64 rx_sz_max; /* 1519 byte to MTU RX packets */
+ u64 rx_ov_sz; /* truncated RX packets, size > MTU */
+ u64 rx_ov_rxf; /* frames dropped due to RX FIFO overflow */
+ u64 rx_ov_rrd; /* frames dropped due to RRD overflow */
+ u64 rx_align_err; /* alignment errors */
+ u64 rx_bc_byte_cnt; /* RX broadcast bytes, excluding FCS */
+ u64 rx_mc_byte_cnt; /* RX multicast bytes, excluding FCS */
+ u64 rx_err_addr; /* packets dropped due to address filtering */
+
+ /* tx */
+ u64 tx_ok; /* good TX packets */
+ u64 tx_bcast; /* good TX broadcast packets */
+ u64 tx_mcast; /* good TX multicast packets */
+ u64 tx_pause; /* TX pause frames */
+ u64 tx_exc_defer; /* TX packets deferred excessively */
+ u64 tx_ctrl; /* TX control frames, excluding pause frames */
+ u64 tx_defer; /* TX packets deferred */
+ u64 tx_byte_cnt; /* bytes transmitted, FCS is NOT included */
+ u64 tx_sz_64B; /* 64 byte TX packets */
+ u64 tx_sz_127B; /* 65-127 byte TX packets */
+ u64 tx_sz_255B; /* 128-255 byte TX packets */
+ u64 tx_sz_511B; /* 256-511 byte TX packets */
+ u64 tx_sz_1023B; /* 512-1023 byte TX packets */
+ u64 tx_sz_1518B; /* 1024-1518 byte TX packets */
+ u64 tx_sz_max; /* 1519 byte to MTU TX packets */
+ u64 tx_single_col; /* packets TX after a single collision */
+ u64 tx_multi_col; /* packets TX after multiple collisions */
+ u64 tx_late_col; /* TX packets with late collisions */
+ u64 tx_abort_col; /* TX packets aborted w/excessive collisions */
+ u64 tx_underrun; /* TX packets aborted due to TX FIFO underrun
+ * or TRD FIFO underrun
+ */
+ u64 tx_trd_eop; /* reads beyond the EOP into the next frame
+ * when TRD was not written timely
+ */
+ u64 tx_len_err; /* TX packets where length != actual size */
+ u64 tx_trunc; /* TX packets truncated due to size > MTU */
+ u64 tx_bc_byte_cnt; /* broadcast bytes transmitted, excluding FCS */
+ u64 tx_mc_byte_cnt; /* multicast bytes transmitted, excluding FCS */
+ u64 update;
+};
+
+
+/* maximum interrupt vectors for msix */
+#define ALX_MAX_MSIX_INTRS 16
+
+#define ALX_GET_FIELD(_data, _field) \
+ (((_data) >> _field ## _SHIFT) & _field ## _MASK)
+
+#define ALX_SET_FIELD(_data, _field, _value) do { \
+ (_data) &= ~(_field ## _MASK << _field ## _SHIFT); \
+ (_data) |= ((_value) & _field ## _MASK) << _field ## _SHIFT;\
+ } while (0)
+
+struct alx_hw {
+ struct pci_dev *pdev;
+ u8 __iomem *hw_addr;
+
+ /* current & permanent mac addr */
+ u8 mac_addr[ETH_ALEN];
+ u8 perm_addr[ETH_ALEN];
+
+ u16 mtu;
+ u16 imt;
+ u8 dma_chnl;
+ u8 max_dma_chnl;
+ /* tpd threshold to trig INT */
+ u32 ith_tpd;
+ u32 rx_ctrl;
+ u32 mc_hash[2];
+
+ u32 smb_timer;
+ /* SPEED_* + DUPLEX_*, SPEED_UNKNOWN if link is down */
+ int link_speed;
+ u8 duplex;
+
+ /* auto-neg advertisement or force mode config */
+ u8 flowctrl;
+ u32 adv_cfg;
+
+ spinlock_t mdio_lock;
+ struct mdio_if_info mdio;
+ u16 phy_id[2];
+
+ /* PHY link patch flag */
+ bool lnk_patch;
+
+ /* cumulated stats from the hardware (registers are cleared on read) */
+ struct alx_hw_stats stats;
+};
+
+static inline int alx_hw_revision(struct alx_hw *hw)
+{
+ return hw->pdev->revision >> ALX_PCI_REVID_SHIFT;
+}
+
+static inline bool alx_hw_with_cr(struct alx_hw *hw)
+{
+ return hw->pdev->revision & 1;
+}
+
+static inline bool alx_hw_giga(struct alx_hw *hw)
+{
+ return hw->pdev->device & 1;
+}
+
+static inline void alx_write_mem8(struct alx_hw *hw, u32 reg, u8 val)
+{
+ writeb(val, hw->hw_addr + reg);
+}
+
+static inline void alx_write_mem16(struct alx_hw *hw, u32 reg, u16 val)
+{
+ writew(val, hw->hw_addr + reg);
+}
+
+static inline u16 alx_read_mem16(struct alx_hw *hw, u32 reg)
+{
+ return readw(hw->hw_addr + reg);
+}
+
+static inline void alx_write_mem32(struct alx_hw *hw, u32 reg, u32 val)
+{
+ writel(val, hw->hw_addr + reg);
+}
+
+static inline u32 alx_read_mem32(struct alx_hw *hw, u32 reg)
+{
+ return readl(hw->hw_addr + reg);
+}
+
+static inline void alx_post_write(struct alx_hw *hw)
+{
+ readl(hw->hw_addr);
+}
+
+int alx_get_perm_macaddr(struct alx_hw *hw, u8 *addr);
+void alx_reset_phy(struct alx_hw *hw);
+void alx_reset_pcie(struct alx_hw *hw);
+void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en);
+int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl);
+void alx_post_phy_link(struct alx_hw *hw);
+int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data);
+int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data);
+int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata);
+int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data);
+int alx_read_phy_link(struct alx_hw *hw);
+int alx_clear_phy_intr(struct alx_hw *hw);
+void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc);
+void alx_start_mac(struct alx_hw *hw);
+int alx_reset_mac(struct alx_hw *hw);
+void alx_set_macaddr(struct alx_hw *hw, const u8 *addr);
+bool alx_phy_configured(struct alx_hw *hw);
+void alx_configure_basic(struct alx_hw *hw);
+void alx_disable_rss(struct alx_hw *hw);
+bool alx_get_phy_info(struct alx_hw *hw);
+void alx_update_hw_stats(struct alx_hw *hw);
+
+static inline u32 alx_speed_to_ethadv(int speed, u8 duplex)
+{
+ if (speed == SPEED_1000 && duplex == DUPLEX_FULL)
+ return ADVERTISED_1000baseT_Full;
+ if (speed == SPEED_100 && duplex == DUPLEX_FULL)
+ return ADVERTISED_100baseT_Full;
+ if (speed == SPEED_100 && duplex== DUPLEX_HALF)
+ return ADVERTISED_100baseT_Half;
+ if (speed == SPEED_10 && duplex == DUPLEX_FULL)
+ return ADVERTISED_10baseT_Full;
+ if (speed == SPEED_10 && duplex == DUPLEX_HALF)
+ return ADVERTISED_10baseT_Half;
+ return 0;
+}
+
+#endif
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
new file mode 100644
index 00000000000..49faa97a30c
--- /dev/null
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -0,0 +1,1557 @@
+/*
+ * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is free software: you may copy, redistribute and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_vlan.h>
+#include <linux/mdio.h>
+#include <linux/aer.h>
+#include <linux/bitops.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/ip6_checksum.h>
+#include <linux/crc32.h>
+#include "alx.h"
+#include "hw.h"
+#include "reg.h"
+
+const char alx_drv_name[] = "alx";
+
+
+static void alx_free_txbuf(struct alx_priv *alx, int entry)
+{
+ struct alx_buffer *txb = &alx->txq.bufs[entry];
+
+ if (dma_unmap_len(txb, size)) {
+ dma_unmap_single(&alx->hw.pdev->dev,
+ dma_unmap_addr(txb, dma),
+ dma_unmap_len(txb, size),
+ DMA_TO_DEVICE);
+ dma_unmap_len_set(txb, size, 0);
+ }
+
+ if (txb->skb) {
+ dev_kfree_skb_any(txb->skb);
+ txb->skb = NULL;
+ }
+}
+
+static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
+{
+ struct alx_rx_queue *rxq = &alx->rxq;
+ struct sk_buff *skb;
+ struct alx_buffer *cur_buf;
+ dma_addr_t dma;
+ u16 cur, next, count = 0;
+
+ next = cur = rxq->write_idx;
+ if (++next == alx->rx_ringsz)
+ next = 0;
+ cur_buf = &rxq->bufs[cur];
+
+ while (!cur_buf->skb && next != rxq->read_idx) {
+ struct alx_rfd *rfd = &rxq->rfd[cur];
+
+ skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
+ if (!skb)
+ break;
+ dma = dma_map_single(&alx->hw.pdev->dev,
+ skb->data, alx->rxbuf_size,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&alx->hw.pdev->dev, dma)) {
+ dev_kfree_skb(skb);
+ break;
+ }
+
+ /* Unfortunately, RX descriptor buffers must be 4-byte
+ * aligned, so we can't use IP alignment.
+ */
+ if (WARN_ON(dma & 3)) {
+ dev_kfree_skb(skb);
+ break;
+ }
+
+ cur_buf->skb = skb;
+ dma_unmap_len_set(cur_buf, size, alx->rxbuf_size);
+ dma_unmap_addr_set(cur_buf, dma, dma);
+ rfd->addr = cpu_to_le64(dma);
+
+ cur = next;
+ if (++next == alx->rx_ringsz)
+ next = 0;
+ cur_buf = &rxq->bufs[cur];
+ count++;
+ }
+
+ if (count) {
+ /* flush all updates before updating hardware */
+ wmb();
+ rxq->write_idx = cur;
+ alx_write_mem16(&alx->hw, ALX_RFD_PIDX, cur);
+ }
+
+ return count;
+}
+
+static inline int alx_tpd_avail(struct alx_priv *alx)
+{
+ struct alx_tx_queue *txq = &alx->txq;
+
+ if (txq->write_idx >= txq->read_idx)
+ return alx->tx_ringsz + txq->read_idx - txq->write_idx - 1;
+ return txq->read_idx - txq->write_idx - 1;
+}
+
+static bool alx_clean_tx_irq(struct alx_priv *alx)
+{
+ struct alx_tx_queue *txq = &alx->txq;
+ u16 hw_read_idx, sw_read_idx;
+ unsigned int total_bytes = 0, total_packets = 0;
+ int budget = ALX_DEFAULT_TX_WORK;
+
+ sw_read_idx = txq->read_idx;
+ hw_read_idx = alx_read_mem16(&alx->hw, ALX_TPD_PRI0_CIDX);
+
+ if (sw_read_idx != hw_read_idx) {
+ while (sw_read_idx != hw_read_idx && budget > 0) {
+ struct sk_buff *skb;
+
+ skb = txq->bufs[sw_read_idx].skb;
+ if (skb) {
+ total_bytes += skb->len;
+ total_packets++;
+ budget--;
+ }
+
+ alx_free_txbuf(alx, sw_read_idx);
+
+ if (++sw_read_idx == alx->tx_ringsz)
+ sw_read_idx = 0;
+ }
+ txq->read_idx = sw_read_idx;
+
+ netdev_completed_queue(alx->dev, total_packets, total_bytes);
+ }
+
+ if (netif_queue_stopped(alx->dev) && netif_carrier_ok(alx->dev) &&
+ alx_tpd_avail(alx) > alx->tx_ringsz/4)
+ netif_wake_queue(alx->dev);
+
+ return sw_read_idx == hw_read_idx;
+}
+
+static void alx_schedule_link_check(struct alx_priv *alx)
+{
+ schedule_work(&alx->link_check_wk);
+}
+
+static void alx_schedule_reset(struct alx_priv *alx)
+{
+ schedule_work(&alx->reset_wk);
+}
+
+static bool alx_clean_rx_irq(struct alx_priv *alx, int budget)
+{
+ struct alx_rx_queue *rxq = &alx->rxq;
+ struct alx_rrd *rrd;
+ struct alx_buffer *rxb;
+ struct sk_buff *skb;
+ u16 length, rfd_cleaned = 0;
+
+ while (budget > 0) {
+ rrd = &rxq->rrd[rxq->rrd_read_idx];
+ if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT)))
+ break;
+ rrd->word3 &= ~cpu_to_le32(1 << RRD_UPDATED_SHIFT);
+
+ if (ALX_GET_FIELD(le32_to_cpu(rrd->word0),
+ RRD_SI) != rxq->read_idx ||
+ ALX_GET_FIELD(le32_to_cpu(rrd->word0),
+ RRD_NOR) != 1) {
+ alx_schedule_reset(alx);
+ return 0;
+ }
+
+ rxb = &rxq->bufs[rxq->read_idx];
+ dma_unmap_single(&alx->hw.pdev->dev,
+ dma_unmap_addr(rxb, dma),
+ dma_unmap_len(rxb, size),
+ DMA_FROM_DEVICE);
+ dma_unmap_len_set(rxb, size, 0);
+ skb = rxb->skb;
+ rxb->skb = NULL;
+
+ if (rrd->word3 & cpu_to_le32(1 << RRD_ERR_RES_SHIFT) ||
+ rrd->word3 & cpu_to_le32(1 << RRD_ERR_LEN_SHIFT)) {
+ rrd->word3 = 0;
+ dev_kfree_skb_any(skb);
+ goto next_pkt;
+ }
+
+ length = ALX_GET_FIELD(le32_to_cpu(rrd->word3),
+ RRD_PKTLEN) - ETH_FCS_LEN;
+ skb_put(skb, length);
+ skb->protocol = eth_type_trans(skb, alx->dev);
+
+ skb_checksum_none_assert(skb);
+ if (alx->dev->features & NETIF_F_RXCSUM &&
+ !(rrd->word3 & (cpu_to_le32(1 << RRD_ERR_L4_SHIFT) |
+ cpu_to_le32(1 << RRD_ERR_IPV4_SHIFT)))) {
+ switch (ALX_GET_FIELD(le32_to_cpu(rrd->word2),
+ RRD_PID)) {
+ case RRD_PID_IPV6UDP:
+ case RRD_PID_IPV4UDP:
+ case RRD_PID_IPV4TCP:
+ case RRD_PID_IPV6TCP:
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ break;
+ }
+ }
+
+ napi_gro_receive(&alx->napi, skb);
+ budget--;
+
+next_pkt:
+ if (++rxq->read_idx == alx->rx_ringsz)
+ rxq->read_idx = 0;
+ if (++rxq->rrd_read_idx == alx->rx_ringsz)
+ rxq->rrd_read_idx = 0;
+
+ if (++rfd_cleaned > ALX_RX_ALLOC_THRESH)
+ rfd_cleaned -= alx_refill_rx_ring(alx, GFP_ATOMIC);
+ }
+
+ if (rfd_cleaned)
+ alx_refill_rx_ring(alx, GFP_ATOMIC);
+
+ return budget > 0;
+}
+
+static int alx_poll(struct napi_struct *napi, int budget)
+{
+ struct alx_priv *alx = container_of(napi, struct alx_priv, napi);
+ struct alx_hw *hw = &alx->hw;
+ bool complete = true;
+ unsigned long flags;
+
+ complete = alx_clean_tx_irq(alx) &&
+ alx_clean_rx_irq(alx, budget);
+
+ if (!complete)
+ return 1;
+
+ napi_complete(&alx->napi);
+
+ /* enable interrupt */
+ spin_lock_irqsave(&alx->irq_lock, flags);
+ alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0;
+ alx_write_mem32(hw, ALX_IMR, alx->int_mask);
+ spin_unlock_irqrestore(&alx->irq_lock, flags);
+
+ alx_post_write(hw);
+
+ return 0;
+}
+
+static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr)
+{
+ struct alx_hw *hw = &alx->hw;
+ bool write_int_mask = false;
+
+ spin_lock(&alx->irq_lock);
+
+ /* ACK interrupt */
+ alx_write_mem32(hw, ALX_ISR, intr | ALX_ISR_DIS);
+ intr &= alx->int_mask;
+
+ if (intr & ALX_ISR_FATAL) {
+ netif_warn(alx, hw, alx->dev,
+ "fatal interrupt 0x%x, resetting\n", intr);
+ alx_schedule_reset(alx);
+ goto out;
+ }
+
+ if (intr & ALX_ISR_ALERT)
+ netdev_warn(alx->dev, "alert interrupt: 0x%x\n", intr);
+
+ if (intr & ALX_ISR_PHY) {
+ /* suppress PHY interrupt, because the source
+ * is from PHY internal. only the internal status
+ * is cleared, the interrupt status could be cleared.
+ */
+ alx->int_mask &= ~ALX_ISR_PHY;
+ write_int_mask = true;
+ alx_schedule_link_check(alx);
+ }
+
+ if (intr & (ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0)) {
+ napi_schedule(&alx->napi);
+ /* mask rx/tx interrupt, enable them when napi complete */
+ alx->int_mask &= ~ALX_ISR_ALL_QUEUES;
+ write_int_mask = true;
+ }
+
+ if (write_int_mask)
+ alx_write_mem32(hw, ALX_IMR, alx->int_mask);
+
+ alx_write_mem32(hw, ALX_ISR, 0);
+
+ out:
+ spin_unlock(&alx->irq_lock);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t alx_intr_msi(int irq, void *data)
+{
+ struct alx_priv *alx = data;
+
+ return alx_intr_handle(alx, alx_read_mem32(&alx->hw, ALX_ISR));
+}
+
+static irqreturn_t alx_intr_legacy(int irq, void *data)
+{
+ struct alx_priv *alx = data;
+ struct alx_hw *hw = &alx->hw;
+ u32 intr;
+
+ intr = alx_read_mem32(hw, ALX_ISR);
+
+ if (intr & ALX_ISR_DIS || !(intr & alx->int_mask))
+ return IRQ_NONE;
+
+ return alx_intr_handle(alx, intr);
+}
+
+static void alx_init_ring_ptrs(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+ u32 addr_hi = ((u64)alx->descmem.dma) >> 32;
+
+ alx->rxq.read_idx = 0;
+ alx->rxq.write_idx = 0;
+ alx->rxq.rrd_read_idx = 0;
+ alx_write_mem32(hw, ALX_RX_BASE_ADDR_HI, addr_hi);
+ alx_write_mem32(hw, ALX_RRD_ADDR_LO, alx->rxq.rrd_dma);
+ alx_write_mem32(hw, ALX_RRD_RING_SZ, alx->rx_ringsz);
+ alx_write_mem32(hw, ALX_RFD_ADDR_LO, alx->rxq.rfd_dma);
+ alx_write_mem32(hw, ALX_RFD_RING_SZ, alx->rx_ringsz);
+ alx_write_mem32(hw, ALX_RFD_BUF_SZ, alx->rxbuf_size);
+
+ alx->txq.read_idx = 0;
+ alx->txq.write_idx = 0;
+ alx_write_mem32(hw, ALX_TX_BASE_ADDR_HI, addr_hi);
+ alx_write_mem32(hw, ALX_TPD_PRI0_ADDR_LO, alx->txq.tpd_dma);
+ alx_write_mem32(hw, ALX_TPD_RING_SZ, alx->tx_ringsz);
+
+ /* load these pointers into the chip */
+ alx_write_mem32(hw, ALX_SRAM9, ALX_SRAM_LOAD_PTR);
+}
+
+static void alx_free_txring_buf(struct alx_priv *alx)
+{
+ struct alx_tx_queue *txq = &alx->txq;
+ int i;
+
+ if (!txq->bufs)
+ return;
+
+ for (i = 0; i < alx->tx_ringsz; i++)
+ alx_free_txbuf(alx, i);
+
+ memset(txq->bufs, 0, alx->tx_ringsz * sizeof(struct alx_buffer));
+ memset(txq->tpd, 0, alx->tx_ringsz * sizeof(struct alx_txd));
+ txq->write_idx = 0;
+ txq->read_idx = 0;
+
+ netdev_reset_queue(alx->dev);
+}
+
+static void alx_free_rxring_buf(struct alx_priv *alx)
+{
+ struct alx_rx_queue *rxq = &alx->rxq;
+ struct alx_buffer *cur_buf;
+ u16 i;
+
+ if (rxq == NULL)
+ return;
+
+ for (i = 0; i < alx->rx_ringsz; i++) {
+ cur_buf = rxq->bufs + i;
+ if (cur_buf->skb) {
+ dma_unmap_single(&alx->hw.pdev->dev,
+ dma_unmap_addr(cur_buf, dma),
+ dma_unmap_len(cur_buf, size),
+ DMA_FROM_DEVICE);
+ dev_kfree_skb(cur_buf->skb);
+ cur_buf->skb = NULL;
+ dma_unmap_len_set(cur_buf, size, 0);
+ dma_unmap_addr_set(cur_buf, dma, 0);
+ }
+ }
+
+ rxq->write_idx = 0;
+ rxq->read_idx = 0;
+ rxq->rrd_read_idx = 0;
+}
+
+static void alx_free_buffers(struct alx_priv *alx)
+{
+ alx_free_txring_buf(alx);
+ alx_free_rxring_buf(alx);
+}
+
+static int alx_reinit_rings(struct alx_priv *alx)
+{
+ alx_free_buffers(alx);
+
+ alx_init_ring_ptrs(alx);
+
+ if (!alx_refill_rx_ring(alx, GFP_KERNEL))
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void alx_add_mc_addr(struct alx_hw *hw, const u8 *addr, u32 *mc_hash)
+{
+ u32 crc32, bit, reg;
+
+ crc32 = ether_crc(ETH_ALEN, addr);
+ reg = (crc32 >> 31) & 0x1;
+ bit = (crc32 >> 26) & 0x1F;
+
+ mc_hash[reg] |= BIT(bit);
+}
+
+static void __alx_set_rx_mode(struct net_device *netdev)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+ struct netdev_hw_addr *ha;
+ u32 mc_hash[2] = {};
+
+ if (!(netdev->flags & IFF_ALLMULTI)) {
+ netdev_for_each_mc_addr(ha, netdev)
+ alx_add_mc_addr(hw, ha->addr, mc_hash);
+
+ alx_write_mem32(hw, ALX_HASH_TBL0, mc_hash[0]);
+ alx_write_mem32(hw, ALX_HASH_TBL1, mc_hash[1]);
+ }
+
+ hw->rx_ctrl &= ~(ALX_MAC_CTRL_MULTIALL_EN | ALX_MAC_CTRL_PROMISC_EN);
+ if (netdev->flags & IFF_PROMISC)
+ hw->rx_ctrl |= ALX_MAC_CTRL_PROMISC_EN;
+ if (netdev->flags & IFF_ALLMULTI)
+ hw->rx_ctrl |= ALX_MAC_CTRL_MULTIALL_EN;
+
+ alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl);
+}
+
+static void alx_set_rx_mode(struct net_device *netdev)
+{
+ __alx_set_rx_mode(netdev);
+}
+
+static int alx_set_mac_address(struct net_device *netdev, void *data)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+ struct sockaddr *addr = data;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (netdev->addr_assign_type & NET_ADDR_RANDOM)
+ netdev->addr_assign_type ^= NET_ADDR_RANDOM;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
+ alx_set_macaddr(hw, hw->mac_addr);
+
+ return 0;
+}
+
+static int alx_alloc_descriptors(struct alx_priv *alx)
+{
+ alx->txq.bufs = kcalloc(alx->tx_ringsz,
+ sizeof(struct alx_buffer),
+ GFP_KERNEL);
+ if (!alx->txq.bufs)
+ return -ENOMEM;
+
+ alx->rxq.bufs = kcalloc(alx->rx_ringsz,
+ sizeof(struct alx_buffer),
+ GFP_KERNEL);
+ if (!alx->rxq.bufs)
+ goto out_free;
+
+ /* physical tx/rx ring descriptors
+ *
+ * Allocate them as a single chunk because they must not cross a
+ * 4G boundary (hardware has a single register for high 32 bits
+ * of addresses only)
+ */
+ alx->descmem.size = sizeof(struct alx_txd) * alx->tx_ringsz +
+ sizeof(struct alx_rrd) * alx->rx_ringsz +
+ sizeof(struct alx_rfd) * alx->rx_ringsz;
+ alx->descmem.virt = dma_zalloc_coherent(&alx->hw.pdev->dev,
+ alx->descmem.size,
+ &alx->descmem.dma,
+ GFP_KERNEL);
+ if (!alx->descmem.virt)
+ goto out_free;
+
+ alx->txq.tpd = alx->descmem.virt;
+ alx->txq.tpd_dma = alx->descmem.dma;
+
+ /* alignment requirement for next block */
+ BUILD_BUG_ON(sizeof(struct alx_txd) % 8);
+
+ alx->rxq.rrd =
+ (void *)((u8 *)alx->descmem.virt +
+ sizeof(struct alx_txd) * alx->tx_ringsz);
+ alx->rxq.rrd_dma = alx->descmem.dma +
+ sizeof(struct alx_txd) * alx->tx_ringsz;
+
+ /* alignment requirement for next block */
+ BUILD_BUG_ON(sizeof(struct alx_rrd) % 8);
+
+ alx->rxq.rfd =
+ (void *)((u8 *)alx->descmem.virt +
+ sizeof(struct alx_txd) * alx->tx_ringsz +
+ sizeof(struct alx_rrd) * alx->rx_ringsz);
+ alx->rxq.rfd_dma = alx->descmem.dma +
+ sizeof(struct alx_txd) * alx->tx_ringsz +
+ sizeof(struct alx_rrd) * alx->rx_ringsz;
+
+ return 0;
+out_free:
+ kfree(alx->txq.bufs);
+ kfree(alx->rxq.bufs);
+ return -ENOMEM;
+}
+
+static int alx_alloc_rings(struct alx_priv *alx)
+{
+ int err;
+
+ err = alx_alloc_descriptors(alx);
+ if (err)
+ return err;
+
+ alx->int_mask &= ~ALX_ISR_ALL_QUEUES;
+ alx->int_mask |= ALX_ISR_TX_Q0 | ALX_ISR_RX_Q0;
+ alx->tx_ringsz = alx->tx_ringsz;
+
+ netif_napi_add(alx->dev, &alx->napi, alx_poll, 64);
+
+ alx_reinit_rings(alx);
+ return 0;
+}
+
+static void alx_free_rings(struct alx_priv *alx)
+{
+ netif_napi_del(&alx->napi);
+ alx_free_buffers(alx);
+
+ kfree(alx->txq.bufs);
+ kfree(alx->rxq.bufs);
+
+ dma_free_coherent(&alx->hw.pdev->dev,
+ alx->descmem.size,
+ alx->descmem.virt,
+ alx->descmem.dma);
+}
+
+static void alx_config_vector_mapping(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+
+ alx_write_mem32(hw, ALX_MSI_MAP_TBL1, 0);
+ alx_write_mem32(hw, ALX_MSI_MAP_TBL2, 0);
+ alx_write_mem32(hw, ALX_MSI_ID_MAP, 0);
+}
+
+static void alx_irq_enable(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+
+ /* level-1 interrupt switch */
+ alx_write_mem32(hw, ALX_ISR, 0);
+ alx_write_mem32(hw, ALX_IMR, alx->int_mask);
+ alx_post_write(hw);
+}
+
+static void alx_irq_disable(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+
+ alx_write_mem32(hw, ALX_ISR, ALX_ISR_DIS);
+ alx_write_mem32(hw, ALX_IMR, 0);
+ alx_post_write(hw);
+
+ synchronize_irq(alx->hw.pdev->irq);
+}
+
+static int alx_request_irq(struct alx_priv *alx)
+{
+ struct pci_dev *pdev = alx->hw.pdev;
+ struct alx_hw *hw = &alx->hw;
+ int err;
+ u32 msi_ctrl;
+
+ msi_ctrl = (hw->imt >> 1) << ALX_MSI_RETRANS_TM_SHIFT;
+
+ if (!pci_enable_msi(alx->hw.pdev)) {
+ alx->msi = true;
+
+ alx_write_mem32(hw, ALX_MSI_RETRANS_TIMER,
+ msi_ctrl | ALX_MSI_MASK_SEL_LINE);
+ err = request_irq(pdev->irq, alx_intr_msi, 0,
+ alx->dev->name, alx);
+ if (!err)
+ goto out;
+ /* fall back to legacy interrupt */
+ pci_disable_msi(alx->hw.pdev);
+ }
+
+ alx_write_mem32(hw, ALX_MSI_RETRANS_TIMER, 0);
+ err = request_irq(pdev->irq, alx_intr_legacy, IRQF_SHARED,
+ alx->dev->name, alx);
+out:
+ if (!err)
+ alx_config_vector_mapping(alx);
+ return err;
+}
+
+static void alx_free_irq(struct alx_priv *alx)
+{
+ struct pci_dev *pdev = alx->hw.pdev;
+
+ free_irq(pdev->irq, alx);
+
+ if (alx->msi) {
+ pci_disable_msi(alx->hw.pdev);
+ alx->msi = false;
+ }
+}
+
+static int alx_identify_hw(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+ int rev = alx_hw_revision(hw);
+
+ if (rev > ALX_REV_C0)
+ return -EINVAL;
+
+ hw->max_dma_chnl = rev >= ALX_REV_B0 ? 4 : 2;
+
+ return 0;
+}
+
+static int alx_init_sw(struct alx_priv *alx)
+{
+ struct pci_dev *pdev = alx->hw.pdev;
+ struct alx_hw *hw = &alx->hw;
+ int err;
+
+ err = alx_identify_hw(alx);
+ if (err) {
+ dev_err(&pdev->dev, "unrecognized chip, aborting\n");
+ return err;
+ }
+
+ alx->hw.lnk_patch =
+ pdev->device == ALX_DEV_ID_AR8161 &&
+ pdev->subsystem_vendor == PCI_VENDOR_ID_ATTANSIC &&
+ pdev->subsystem_device == 0x0091 &&
+ pdev->revision == 0;
+
+ hw->smb_timer = 400;
+ hw->mtu = alx->dev->mtu;
+ alx->rxbuf_size = ALIGN(ALX_RAW_MTU(hw->mtu), 8);
+ alx->tx_ringsz = 256;
+ alx->rx_ringsz = 512;
+ hw->imt = 200;
+ alx->int_mask = ALX_ISR_MISC;
+ hw->dma_chnl = hw->max_dma_chnl;
+ hw->ith_tpd = alx->tx_ringsz / 3;
+ hw->link_speed = SPEED_UNKNOWN;
+ hw->duplex = DUPLEX_UNKNOWN;
+ hw->adv_cfg = ADVERTISED_Autoneg |
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_1000baseT_Full;
+ hw->flowctrl = ALX_FC_ANEG | ALX_FC_RX | ALX_FC_TX;
+
+ hw->rx_ctrl = ALX_MAC_CTRL_WOLSPED_SWEN |
+ ALX_MAC_CTRL_MHASH_ALG_HI5B |
+ ALX_MAC_CTRL_BRD_EN |
+ ALX_MAC_CTRL_PCRCE |
+ ALX_MAC_CTRL_CRCE |
+ ALX_MAC_CTRL_RXFC_EN |
+ ALX_MAC_CTRL_TXFC_EN |
+ 7 << ALX_MAC_CTRL_PRMBLEN_SHIFT;
+
+ return err;
+}
+
+
+static netdev_features_t alx_fix_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ if (netdev->mtu > ALX_MAX_TSO_PKT_SIZE)
+ features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+ return features;
+}
+
+static void alx_netif_stop(struct alx_priv *alx)
+{
+ alx->dev->trans_start = jiffies;
+ if (netif_carrier_ok(alx->dev)) {
+ netif_carrier_off(alx->dev);
+ netif_tx_disable(alx->dev);
+ napi_disable(&alx->napi);
+ }
+}
+
+static void alx_halt(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+
+ alx_netif_stop(alx);
+ hw->link_speed = SPEED_UNKNOWN;
+ hw->duplex = DUPLEX_UNKNOWN;
+
+ alx_reset_mac(hw);
+
+ /* disable l0s/l1 */
+ alx_enable_aspm(hw, false, false);
+ alx_irq_disable(alx);
+ alx_free_buffers(alx);
+}
+
+static void alx_configure(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+
+ alx_configure_basic(hw);
+ alx_disable_rss(hw);
+ __alx_set_rx_mode(alx->dev);
+
+ alx_write_mem32(hw, ALX_MAC_CTRL, hw->rx_ctrl);
+}
+
+static void alx_activate(struct alx_priv *alx)
+{
+ /* hardware setting lost, restore it */
+ alx_reinit_rings(alx);
+ alx_configure(alx);
+
+ /* clear old interrupts */
+ alx_write_mem32(&alx->hw, ALX_ISR, ~(u32)ALX_ISR_DIS);
+
+ alx_irq_enable(alx);
+
+ alx_schedule_link_check(alx);
+}
+
+static void alx_reinit(struct alx_priv *alx)
+{
+ ASSERT_RTNL();
+
+ alx_halt(alx);
+ alx_activate(alx);
+}
+
+static int alx_change_mtu(struct net_device *netdev, int mtu)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ int max_frame = mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+ if ((max_frame < ALX_MIN_FRAME_SIZE) ||
+ (max_frame > ALX_MAX_FRAME_SIZE))
+ return -EINVAL;
+
+ if (netdev->mtu == mtu)
+ return 0;
+
+ netdev->mtu = mtu;
+ alx->hw.mtu = mtu;
+ alx->rxbuf_size = mtu > ALX_DEF_RXBUF_SIZE ?
+ ALIGN(max_frame, 8) : ALX_DEF_RXBUF_SIZE;
+ netdev_update_features(netdev);
+ if (netif_running(netdev))
+ alx_reinit(alx);
+ return 0;
+}
+
+static void alx_netif_start(struct alx_priv *alx)
+{
+ netif_tx_wake_all_queues(alx->dev);
+ napi_enable(&alx->napi);
+ netif_carrier_on(alx->dev);
+}
+
+static int __alx_open(struct alx_priv *alx, bool resume)
+{
+ int err;
+
+ if (!resume)
+ netif_carrier_off(alx->dev);
+
+ err = alx_alloc_rings(alx);
+ if (err)
+ return err;
+
+ alx_configure(alx);
+
+ err = alx_request_irq(alx);
+ if (err)
+ goto out_free_rings;
+
+ /* clear old interrupts */
+ alx_write_mem32(&alx->hw, ALX_ISR, ~(u32)ALX_ISR_DIS);
+
+ alx_irq_enable(alx);
+
+ if (!resume)
+ netif_tx_start_all_queues(alx->dev);
+
+ alx_schedule_link_check(alx);
+ return 0;
+
+out_free_rings:
+ alx_free_rings(alx);
+ return err;
+}
+
+static void __alx_stop(struct alx_priv *alx)
+{
+ alx_halt(alx);
+ alx_free_irq(alx);
+ alx_free_rings(alx);
+}
+
+static const char *alx_speed_desc(struct alx_hw *hw)
+{
+ switch (alx_speed_to_ethadv(hw->link_speed, hw->duplex)) {
+ case ADVERTISED_1000baseT_Full:
+ return "1 Gbps Full";
+ case ADVERTISED_100baseT_Full:
+ return "100 Mbps Full";
+ case ADVERTISED_100baseT_Half:
+ return "100 Mbps Half";
+ case ADVERTISED_10baseT_Full:
+ return "10 Mbps Full";
+ case ADVERTISED_10baseT_Half:
+ return "10 Mbps Half";
+ default:
+ return "Unknown speed";
+ }
+}
+
+static void alx_check_link(struct alx_priv *alx)
+{
+ struct alx_hw *hw = &alx->hw;
+ unsigned long flags;
+ int old_speed;
+ u8 old_duplex;
+ int err;
+
+ /* clear PHY internal interrupt status, otherwise the main
+ * interrupt status will be asserted forever
+ */
+ alx_clear_phy_intr(hw);
+
+ old_speed = hw->link_speed;
+ old_duplex = hw->duplex;
+ err = alx_read_phy_link(hw);
+ if (err < 0)
+ goto reset;
+
+ spin_lock_irqsave(&alx->irq_lock, flags);
+ alx->int_mask |= ALX_ISR_PHY;
+ alx_write_mem32(hw, ALX_IMR, alx->int_mask);
+ spin_unlock_irqrestore(&alx->irq_lock, flags);
+
+ if (old_speed == hw->link_speed)
+ return;
+
+ if (hw->link_speed != SPEED_UNKNOWN) {
+ netif_info(alx, link, alx->dev,
+ "NIC Up: %s\n", alx_speed_desc(hw));
+ alx_post_phy_link(hw);
+ alx_enable_aspm(hw, true, true);
+ alx_start_mac(hw);
+
+ if (old_speed == SPEED_UNKNOWN)
+ alx_netif_start(alx);
+ } else {
+ /* link is now down */
+ alx_netif_stop(alx);
+ netif_info(alx, link, alx->dev, "Link Down\n");
+ err = alx_reset_mac(hw);
+ if (err)
+ goto reset;
+ alx_irq_disable(alx);
+
+ /* MAC reset causes all HW settings to be lost, restore all */
+ err = alx_reinit_rings(alx);
+ if (err)
+ goto reset;
+ alx_configure(alx);
+ alx_enable_aspm(hw, false, true);
+ alx_post_phy_link(hw);
+ alx_irq_enable(alx);
+ }
+
+ return;
+
+reset:
+ alx_schedule_reset(alx);
+}
+
+static int alx_open(struct net_device *netdev)
+{
+ return __alx_open(netdev_priv(netdev), false);
+}
+
+static int alx_stop(struct net_device *netdev)
+{
+ __alx_stop(netdev_priv(netdev));
+ return 0;
+}
+
+static void alx_link_check(struct work_struct *work)
+{
+ struct alx_priv *alx;
+
+ alx = container_of(work, struct alx_priv, link_check_wk);
+
+ rtnl_lock();
+ alx_check_link(alx);
+ rtnl_unlock();
+}
+
+static void alx_reset(struct work_struct *work)
+{
+ struct alx_priv *alx = container_of(work, struct alx_priv, reset_wk);
+
+ rtnl_lock();
+ alx_reinit(alx);
+ rtnl_unlock();
+}
+
+static int alx_tx_csum(struct sk_buff *skb, struct alx_txd *first)
+{
+ u8 cso, css;
+
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return 0;
+
+ cso = skb_checksum_start_offset(skb);
+ if (cso & 1)
+ return -EINVAL;
+
+ css = cso + skb->csum_offset;
+ first->word1 |= cpu_to_le32((cso >> 1) << TPD_CXSUMSTART_SHIFT);
+ first->word1 |= cpu_to_le32((css >> 1) << TPD_CXSUMOFFSET_SHIFT);
+ first->word1 |= cpu_to_le32(1 << TPD_CXSUM_EN_SHIFT);
+
+ return 0;
+}
+
+static int alx_map_tx_skb(struct alx_priv *alx, struct sk_buff *skb)
+{
+ struct alx_tx_queue *txq = &alx->txq;
+ struct alx_txd *tpd, *first_tpd;
+ dma_addr_t dma;
+ int maplen, f, first_idx = txq->write_idx;
+
+ first_tpd = &txq->tpd[txq->write_idx];
+ tpd = first_tpd;
+
+ maplen = skb_headlen(skb);
+ dma = dma_map_single(&alx->hw.pdev->dev, skb->data, maplen,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&alx->hw.pdev->dev, dma))
+ goto err_dma;
+
+ dma_unmap_len_set(&txq->bufs[txq->write_idx], size, maplen);
+ dma_unmap_addr_set(&txq->bufs[txq->write_idx], dma, dma);
+
+ tpd->adrl.addr = cpu_to_le64(dma);
+ tpd->len = cpu_to_le16(maplen);
+
+ for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+ struct skb_frag_struct *frag;
+
+ frag = &skb_shinfo(skb)->frags[f];
+
+ if (++txq->write_idx == alx->tx_ringsz)
+ txq->write_idx = 0;
+ tpd = &txq->tpd[txq->write_idx];
+
+ tpd->word1 = first_tpd->word1;
+
+ maplen = skb_frag_size(frag);
+ dma = skb_frag_dma_map(&alx->hw.pdev->dev, frag, 0,
+ maplen, DMA_TO_DEVICE);
+ if (dma_mapping_error(&alx->hw.pdev->dev, dma))
+ goto err_dma;
+ dma_unmap_len_set(&txq->bufs[txq->write_idx], size, maplen);
+ dma_unmap_addr_set(&txq->bufs[txq->write_idx], dma, dma);
+
+ tpd->adrl.addr = cpu_to_le64(dma);
+ tpd->len = cpu_to_le16(maplen);
+ }
+
+ /* last TPD, set EOP flag and store skb */
+ tpd->word1 |= cpu_to_le32(1 << TPD_EOP_SHIFT);
+ txq->bufs[txq->write_idx].skb = skb;
+
+ if (++txq->write_idx == alx->tx_ringsz)
+ txq->write_idx = 0;
+
+ return 0;
+
+err_dma:
+ f = first_idx;
+ while (f != txq->write_idx) {
+ alx_free_txbuf(alx, f);
+ if (++f == alx->tx_ringsz)
+ f = 0;
+ }
+ return -ENOMEM;
+}
+
+static netdev_tx_t alx_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_tx_queue *txq = &alx->txq;
+ struct alx_txd *first;
+ int tpdreq = skb_shinfo(skb)->nr_frags + 1;
+
+ if (alx_tpd_avail(alx) < tpdreq) {
+ netif_stop_queue(alx->dev);
+ goto drop;
+ }
+
+ first = &txq->tpd[txq->write_idx];
+ memset(first, 0, sizeof(*first));
+
+ if (alx_tx_csum(skb, first))
+ goto drop;
+
+ if (alx_map_tx_skb(alx, skb) < 0)
+ goto drop;
+
+ netdev_sent_queue(alx->dev, skb->len);
+
+ /* flush updates before updating hardware */
+ wmb();
+ alx_write_mem16(&alx->hw, ALX_TPD_PRI0_PIDX, txq->write_idx);
+
+ if (alx_tpd_avail(alx) < alx->tx_ringsz/8)
+ netif_stop_queue(alx->dev);
+
+ return NETDEV_TX_OK;
+
+drop:
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+static void alx_tx_timeout(struct net_device *dev)
+{
+ struct alx_priv *alx = netdev_priv(dev);
+
+ alx_schedule_reset(alx);
+}
+
+static int alx_mdio_read(struct net_device *netdev,
+ int prtad, int devad, u16 addr)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+ u16 val;
+ int err;
+
+ if (prtad != hw->mdio.prtad)
+ return -EINVAL;
+
+ if (devad == MDIO_DEVAD_NONE)
+ err = alx_read_phy_reg(hw, addr, &val);
+ else
+ err = alx_read_phy_ext(hw, devad, addr, &val);
+
+ if (err)
+ return err;
+ return val;
+}
+
+static int alx_mdio_write(struct net_device *netdev,
+ int prtad, int devad, u16 addr, u16 val)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+ struct alx_hw *hw = &alx->hw;
+
+ if (prtad != hw->mdio.prtad)
+ return -EINVAL;
+
+ if (devad == MDIO_DEVAD_NONE)
+ return alx_write_phy_reg(hw, addr, val);
+
+ return alx_write_phy_ext(hw, devad, addr, val);
+}
+
+static int alx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+
+ if (!netif_running(netdev))
+ return -EAGAIN;
+
+ return mdio_mii_ioctl(&alx->hw.mdio, if_mii(ifr), cmd);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void alx_poll_controller(struct net_device *netdev)
+{
+ struct alx_priv *alx = netdev_priv(netdev);
+
+ if (alx->msi)
+ alx_intr_msi(0, alx);
+ else
+ alx_intr_legacy(0, alx);
+}
+#endif
+
+static struct rtnl_link_stats64 *alx_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *net_stats)
+{
+ struct alx_priv *alx = netdev_priv(dev);
+ struct alx_hw_stats *hw_stats = &alx->hw.stats;
+
+ spin_lock(&alx->stats_lock);
+
+ alx_update_hw_stats(&alx->hw);
+
+ net_stats->tx_bytes = hw_stats->tx_byte_cnt;
+ net_stats->rx_bytes = hw_stats->rx_byte_cnt;
+ net_stats->multicast = hw_stats->rx_mcast;
+ net_stats->collisions = hw_stats->tx_single_col +
+ hw_stats->tx_multi_col +
+ hw_stats->tx_late_col +
+ hw_stats->tx_abort_col;
+
+ net_stats->rx_errors = hw_stats->rx_frag +
+ hw_stats->rx_fcs_err +
+ hw_stats->rx_len_err +
+ hw_stats->rx_ov_sz +
+ hw_stats->rx_ov_rrd +
+ hw_stats->rx_align_err +
+ hw_stats->rx_ov_rxf;
+
+ net_stats->rx_fifo_errors = hw_stats->rx_ov_rxf;
+ net_stats->rx_length_errors = hw_stats->rx_len_err;
+ net_stats->rx_crc_errors = hw_stats->rx_fcs_err;
+ net_stats->rx_frame_errors = hw_stats->rx_align_err;
+ net_stats->rx_dropped = hw_stats->rx_ov_rrd;
+
+ net_stats->tx_errors = hw_stats->tx_late_col +
+ hw_stats->tx_abort_col +
+ hw_stats->tx_underrun +
+ hw_stats->tx_trunc;
+
+ net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+ net_stats->tx_fifo_errors = hw_stats->tx_underrun;
+ net_stats->tx_window_errors = hw_stats->tx_late_col;
+
+ net_stats->tx_packets = hw_stats->tx_ok + net_stats->tx_errors;
+ net_stats->rx_packets = hw_stats->rx_ok + net_stats->rx_errors;
+
+ spin_unlock(&alx->stats_lock);
+
+ return net_stats;
+}
+
+static const struct net_device_ops alx_netdev_ops = {
+ .ndo_open = alx_open,
+ .ndo_stop = alx_stop,
+ .ndo_start_xmit = alx_start_xmit,
+ .ndo_get_stats64 = alx_get_stats64,
+ .ndo_set_rx_mode = alx_set_rx_mode,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = alx_set_mac_address,
+ .ndo_change_mtu = alx_change_mtu,
+ .ndo_do_ioctl = alx_ioctl,
+ .ndo_tx_timeout = alx_tx_timeout,
+ .ndo_fix_features = alx_fix_features,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = alx_poll_controller,
+#endif
+};
+
+static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct net_device *netdev;
+ struct alx_priv *alx;
+ struct alx_hw *hw;
+ bool phy_configured;
+ int bars, err;
+
+ err = pci_enable_device_mem(pdev);
+ if (err)
+ return err;
+
+ /* The alx chip can DMA to 64-bit addresses, but it uses a single
+ * shared register for the high 32 bits, so only a single, aligned,
+ * 4 GB physical address range can be used for descriptors.
+ */
+ if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
+ dev_dbg(&pdev->dev, "DMA to 64-BIT addresses\n");
+ } else {
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (err) {
+ dev_err(&pdev->dev, "No usable DMA config, aborting\n");
+ goto out_pci_disable;
+ }
+ }
+
+ bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ err = pci_request_selected_regions(pdev, bars, alx_drv_name);
+ if (err) {
+ dev_err(&pdev->dev,
+ "pci_request_selected_regions failed(bars:%d)\n", bars);
+ goto out_pci_disable;
+ }
+
+ pci_enable_pcie_error_reporting(pdev);
+ pci_set_master(pdev);
+
+ if (!pdev->pm_cap) {
+ dev_err(&pdev->dev,
+ "Can't find power management capability, aborting\n");
+ err = -EIO;
+ goto out_pci_release;
+ }
+
+ netdev = alloc_etherdev(sizeof(*alx));
+ if (!netdev) {
+ err = -ENOMEM;
+ goto out_pci_release;
+ }
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ alx = netdev_priv(netdev);
+ spin_lock_init(&alx->hw.mdio_lock);
+ spin_lock_init(&alx->irq_lock);
+ spin_lock_init(&alx->stats_lock);
+ alx->dev = netdev;
+ alx->hw.pdev = pdev;
+ alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP |
+ NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR | NETIF_MSG_WOL;
+ hw = &alx->hw;
+ pci_set_drvdata(pdev, alx);
+
+ hw->hw_addr = pci_ioremap_bar(pdev, 0);
+ if (!hw->hw_addr) {
+ dev_err(&pdev->dev, "cannot map device registers\n");
+ err = -EIO;
+ goto out_free_netdev;
+ }
+
+ netdev->netdev_ops = &alx_netdev_ops;
+ netdev->ethtool_ops = &alx_ethtool_ops;
+ netdev->irq = pdev->irq;
+ netdev->watchdog_timeo = ALX_WATCHDOG_TIME;
+
+ if (ent->driver_data & ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG)
+ pdev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
+
+ err = alx_init_sw(alx);
+ if (err) {
+ dev_err(&pdev->dev, "net device private data init failed\n");
+ goto out_unmap;
+ }
+
+ alx_reset_pcie(hw);
+
+ phy_configured = alx_phy_configured(hw);
+
+ if (!phy_configured)
+ alx_reset_phy(hw);
+
+ err = alx_reset_mac(hw);
+ if (err) {
+ dev_err(&pdev->dev, "MAC Reset failed, error = %d\n", err);
+ goto out_unmap;
+ }
+
+ /* setup link to put it in a known good starting state */
+ if (!phy_configured) {
+ err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl);
+ if (err) {
+ dev_err(&pdev->dev,
+ "failed to configure PHY speed/duplex (err=%d)\n",
+ err);
+ goto out_unmap;
+ }
+ }
+
+ netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+
+ if (alx_get_perm_macaddr(hw, hw->perm_addr)) {
+ dev_warn(&pdev->dev,
+ "Invalid permanent address programmed, using random one\n");
+ eth_hw_addr_random(netdev);
+ memcpy(hw->perm_addr, netdev->dev_addr, netdev->addr_len);
+ }
+
+ memcpy(hw->mac_addr, hw->perm_addr, ETH_ALEN);
+ memcpy(netdev->dev_addr, hw->mac_addr, ETH_ALEN);
+ memcpy(netdev->perm_addr, hw->perm_addr, ETH_ALEN);
+
+ hw->mdio.prtad = 0;
+ hw->mdio.mmds = 0;
+ hw->mdio.dev = netdev;
+ hw->mdio.mode_support = MDIO_SUPPORTS_C45 |
+ MDIO_SUPPORTS_C22 |
+ MDIO_EMULATE_C22;
+ hw->mdio.mdio_read = alx_mdio_read;
+ hw->mdio.mdio_write = alx_mdio_write;
+
+ if (!alx_get_phy_info(hw)) {
+ dev_err(&pdev->dev, "failed to identify PHY\n");
+ err = -EIO;
+ goto out_unmap;
+ }
+
+ INIT_WORK(&alx->link_check_wk, alx_link_check);
+ INIT_WORK(&alx->reset_wk, alx_reset);
+ netif_carrier_off(netdev);
+
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&pdev->dev, "register netdevice failed\n");
+ goto out_unmap;
+ }
+
+ netdev_info(netdev,
+ "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n",
+ netdev->dev_addr);
+
+ return 0;
+
+out_unmap:
+ iounmap(hw->hw_addr);
+out_free_netdev:
+ free_netdev(netdev);
+out_pci_release:
+ pci_release_selected_regions(pdev, bars);
+out_pci_disable:
+ pci_disable_device(pdev);
+ return err;
+}
+
+static void alx_remove(struct pci_dev *pdev)
+{
+ struct alx_priv *alx = pci_get_drvdata(pdev);
+ struct alx_hw *hw = &alx->hw;
+
+ cancel_work_sync(&alx->link_check_wk);
+ cancel_work_sync(&alx->reset_wk);
+
+ /* restore permanent mac address */
+ alx_set_macaddr(hw, hw->perm_addr);
+
+ unregister_netdev(alx->dev);
+ iounmap(hw->hw_addr);
+ pci_release_selected_regions(pdev,
+ pci_select_bars(pdev, IORESOURCE_MEM));
+
+ pci_disable_pcie_error_reporting(pdev);
+ pci_disable_device(pdev);
+
+ free_netdev(alx->dev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int alx_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct alx_priv *alx = pci_get_drvdata(pdev);
+
+ if (!netif_running(alx->dev))
+ return 0;
+ netif_device_detach(alx->dev);
+ __alx_stop(alx);
+ return 0;
+}
+
+static int alx_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct alx_priv *alx = pci_get_drvdata(pdev);
+ struct alx_hw *hw = &alx->hw;
+
+ alx_reset_phy(hw);
+
+ if (!netif_running(alx->dev))
+ return 0;
+ netif_device_attach(alx->dev);
+ return __alx_open(alx, true);
+}
+
+static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
+#define ALX_PM_OPS (&alx_pm_ops)
+#else
+#define ALX_PM_OPS NULL
+#endif
+
+
+static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct alx_priv *alx = pci_get_drvdata(pdev);
+ struct net_device *netdev = alx->dev;
+ pci_ers_result_t rc = PCI_ERS_RESULT_NEED_RESET;
+
+ dev_info(&pdev->dev, "pci error detected\n");
+
+ rtnl_lock();
+
+ if (netif_running(netdev)) {
+ netif_device_detach(netdev);
+ alx_halt(alx);
+ }
+
+ if (state == pci_channel_io_perm_failure)
+ rc = PCI_ERS_RESULT_DISCONNECT;
+ else
+ pci_disable_device(pdev);
+
+ rtnl_unlock();
+
+ return rc;
+}
+
+static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev)
+{
+ struct alx_priv *alx = pci_get_drvdata(pdev);
+ struct alx_hw *hw = &alx->hw;
+ pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT;
+
+ dev_info(&pdev->dev, "pci error slot reset\n");
+
+ rtnl_lock();
+
+ if (pci_enable_device(pdev)) {
+ dev_err(&pdev->dev, "Failed to re-enable PCI device after reset\n");
+ goto out;
+ }
+
+ pci_set_master(pdev);
+
+ alx_reset_pcie(hw);
+ if (!alx_reset_mac(hw))
+ rc = PCI_ERS_RESULT_RECOVERED;
+out:
+ pci_cleanup_aer_uncorrect_error_status(pdev);
+
+ rtnl_unlock();
+
+ return rc;
+}
+
+static void alx_pci_error_resume(struct pci_dev *pdev)
+{
+ struct alx_priv *alx = pci_get_drvdata(pdev);
+ struct net_device *netdev = alx->dev;
+
+ dev_info(&pdev->dev, "pci error resume\n");
+
+ rtnl_lock();
+
+ if (netif_running(netdev)) {
+ alx_activate(alx);
+ netif_device_attach(netdev);
+ }
+
+ rtnl_unlock();
+}
+
+static const struct pci_error_handlers alx_err_handlers = {
+ .error_detected = alx_pci_error_detected,
+ .slot_reset = alx_pci_error_slot_reset,
+ .resume = alx_pci_error_resume,
+};
+
+static DEFINE_PCI_DEVICE_TABLE(alx_pci_tbl) = {
+ { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8161),
+ .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
+ { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_E2200),
+ .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
+ { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8162),
+ .driver_data = ALX_DEV_QUIRK_MSI_INTX_DISABLE_BUG },
+ { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8171) },
+ { PCI_VDEVICE(ATTANSIC, ALX_DEV_ID_AR8172) },
+ {}
+};
+
+static struct pci_driver alx_driver = {
+ .name = alx_drv_name,
+ .id_table = alx_pci_tbl,
+ .probe = alx_probe,
+ .remove = alx_remove,
+ .err_handler = &alx_err_handlers,
+ .driver.pm = ALX_PM_OPS,
+};
+
+module_pci_driver(alx_driver);
+MODULE_DEVICE_TABLE(pci, alx_pci_tbl);
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_AUTHOR("Qualcomm Corporation, <nic-devel@qualcomm.com>");
+MODULE_DESCRIPTION(
+ "Qualcomm Atheros(R) AR816x/AR817x PCI-E Ethernet Network Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/atheros/alx/reg.h b/drivers/net/ethernet/atheros/alx/reg.h
new file mode 100644
index 00000000000..af006b44b2a
--- /dev/null
+++ b/drivers/net/ethernet/atheros/alx/reg.h
@@ -0,0 +1,854 @@
+/*
+ * Copyright (c) 2013 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This file is free software: you may copy, redistribute and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ALX_REG_H
+#define ALX_REG_H
+
+#define ALX_DEV_ID_AR8161 0x1091
+#define ALX_DEV_ID_E2200 0xe091
+#define ALX_DEV_ID_AR8162 0x1090
+#define ALX_DEV_ID_AR8171 0x10A1
+#define ALX_DEV_ID_AR8172 0x10A0
+
+/* rev definition,
+ * bit(0): with xD support
+ * bit(1): with Card Reader function
+ * bit(7:2): real revision
+ */
+#define ALX_PCI_REVID_SHIFT 3
+#define ALX_REV_A0 0
+#define ALX_REV_A1 1
+#define ALX_REV_B0 2
+#define ALX_REV_C0 3
+
+#define ALX_DEV_CTRL 0x0060
+#define ALX_DEV_CTRL_MAXRRS_MIN 2
+
+#define ALX_MSIX_MASK 0x0090
+
+#define ALX_UE_SVRT 0x010C
+#define ALX_UE_SVRT_FCPROTERR BIT(13)
+#define ALX_UE_SVRT_DLPROTERR BIT(4)
+
+/* eeprom & flash load register */
+#define ALX_EFLD 0x0204
+#define ALX_EFLD_F_EXIST BIT(10)
+#define ALX_EFLD_E_EXIST BIT(9)
+#define ALX_EFLD_STAT BIT(5)
+#define ALX_EFLD_START BIT(0)
+
+/* eFuse load register */
+#define ALX_SLD 0x0218
+#define ALX_SLD_STAT BIT(12)
+#define ALX_SLD_START BIT(11)
+#define ALX_SLD_MAX_TO 100
+
+#define ALX_PDLL_TRNS1 0x1104
+#define ALX_PDLL_TRNS1_D3PLLOFF_EN BIT(11)
+
+#define ALX_PMCTRL 0x12F8
+#define ALX_PMCTRL_HOTRST_WTEN BIT(31)
+/* bit30: L0s/L1 controlled by MAC based on throughput(setting in 15A0) */
+#define ALX_PMCTRL_ASPM_FCEN BIT(30)
+#define ALX_PMCTRL_SADLY_EN BIT(29)
+#define ALX_PMCTRL_LCKDET_TIMER_MASK 0xF
+#define ALX_PMCTRL_LCKDET_TIMER_SHIFT 24
+#define ALX_PMCTRL_LCKDET_TIMER_DEF 0xC
+/* bit[23:20] if pm_request_l1 time > @, then enter L0s not L1 */
+#define ALX_PMCTRL_L1REQ_TO_MASK 0xF
+#define ALX_PMCTRL_L1REQ_TO_SHIFT 20
+#define ALX_PMCTRL_L1REG_TO_DEF 0xF
+#define ALX_PMCTRL_TXL1_AFTER_L0S BIT(19)
+#define ALX_PMCTRL_L1_TIMER_MASK 0x7
+#define ALX_PMCTRL_L1_TIMER_SHIFT 16
+#define ALX_PMCTRL_L1_TIMER_16US 4
+#define ALX_PMCTRL_RCVR_WT_1US BIT(15)
+/* bit13: enable pcie clk switch in L1 state */
+#define ALX_PMCTRL_L1_CLKSW_EN BIT(13)
+#define ALX_PMCTRL_L0S_EN BIT(12)
+#define ALX_PMCTRL_RXL1_AFTER_L0S BIT(11)
+#define ALX_PMCTRL_L1_BUFSRX_EN BIT(7)
+/* bit6: power down serdes RX */
+#define ALX_PMCTRL_L1_SRDSRX_PWD BIT(6)
+#define ALX_PMCTRL_L1_SRDSPLL_EN BIT(5)
+#define ALX_PMCTRL_L1_SRDS_EN BIT(4)
+#define ALX_PMCTRL_L1_EN BIT(3)
+
+/*******************************************************/
+/* following registers are mapped only to memory space */
+/*******************************************************/
+
+#define ALX_MASTER 0x1400
+/* bit12: 1:alwys select pclk from serdes, not sw to 25M */
+#define ALX_MASTER_PCLKSEL_SRDS BIT(12)
+/* bit11: irq moduration for rx */
+#define ALX_MASTER_IRQMOD2_EN BIT(11)
+/* bit10: irq moduration for tx/rx */
+#define ALX_MASTER_IRQMOD1_EN BIT(10)
+#define ALX_MASTER_SYSALVTIMER_EN BIT(7)
+#define ALX_MASTER_OOB_DIS BIT(6)
+/* bit5: wakeup without pcie clk */
+#define ALX_MASTER_WAKEN_25M BIT(5)
+/* bit0: MAC & DMA reset */
+#define ALX_MASTER_DMA_MAC_RST BIT(0)
+#define ALX_DMA_MAC_RST_TO 50
+
+#define ALX_IRQ_MODU_TIMER 0x1408
+#define ALX_IRQ_MODU_TIMER1_MASK 0xFFFF
+#define ALX_IRQ_MODU_TIMER1_SHIFT 0
+
+#define ALX_PHY_CTRL 0x140C
+#define ALX_PHY_CTRL_100AB_EN BIT(17)
+/* bit14: affect MAC & PHY, go to low power sts */
+#define ALX_PHY_CTRL_POWER_DOWN BIT(14)
+/* bit13: 1:pll always ON, 0:can switch in lpw */
+#define ALX_PHY_CTRL_PLL_ON BIT(13)
+#define ALX_PHY_CTRL_RST_ANALOG BIT(12)
+#define ALX_PHY_CTRL_HIB_PULSE BIT(11)
+#define ALX_PHY_CTRL_HIB_EN BIT(10)
+#define ALX_PHY_CTRL_IDDQ BIT(7)
+#define ALX_PHY_CTRL_GATE_25M BIT(5)
+#define ALX_PHY_CTRL_LED_MODE BIT(2)
+/* bit0: out of dsp RST state */
+#define ALX_PHY_CTRL_DSPRST_OUT BIT(0)
+#define ALX_PHY_CTRL_DSPRST_TO 80
+#define ALX_PHY_CTRL_CLS (ALX_PHY_CTRL_LED_MODE | \
+ ALX_PHY_CTRL_100AB_EN | \
+ ALX_PHY_CTRL_PLL_ON)
+
+#define ALX_MAC_STS 0x1410
+#define ALX_MAC_STS_TXQ_BUSY BIT(3)
+#define ALX_MAC_STS_RXQ_BUSY BIT(2)
+#define ALX_MAC_STS_TXMAC_BUSY BIT(1)
+#define ALX_MAC_STS_RXMAC_BUSY BIT(0)
+#define ALX_MAC_STS_IDLE (ALX_MAC_STS_TXQ_BUSY | \
+ ALX_MAC_STS_RXQ_BUSY | \
+ ALX_MAC_STS_TXMAC_BUSY | \
+ ALX_MAC_STS_RXMAC_BUSY)
+
+#define ALX_MDIO 0x1414
+#define ALX_MDIO_MODE_EXT BIT(30)
+#define ALX_MDIO_BUSY BIT(27)
+#define ALX_MDIO_CLK_SEL_MASK 0x7
+#define ALX_MDIO_CLK_SEL_SHIFT 24
+#define ALX_MDIO_CLK_SEL_25MD4 0
+#define ALX_MDIO_CLK_SEL_25MD128 7
+#define ALX_MDIO_START BIT(23)
+#define ALX_MDIO_SPRES_PRMBL BIT(22)
+/* bit21: 1:read,0:write */
+#define ALX_MDIO_OP_READ BIT(21)
+#define ALX_MDIO_REG_MASK 0x1F
+#define ALX_MDIO_REG_SHIFT 16
+#define ALX_MDIO_DATA_MASK 0xFFFF
+#define ALX_MDIO_DATA_SHIFT 0
+#define ALX_MDIO_MAX_AC_TO 120
+
+#define ALX_MDIO_EXTN 0x1448
+#define ALX_MDIO_EXTN_DEVAD_MASK 0x1F
+#define ALX_MDIO_EXTN_DEVAD_SHIFT 16
+#define ALX_MDIO_EXTN_REG_MASK 0xFFFF
+#define ALX_MDIO_EXTN_REG_SHIFT 0
+
+#define ALX_SERDES 0x1424
+#define ALX_SERDES_PHYCLK_SLWDWN BIT(18)
+#define ALX_SERDES_MACCLK_SLWDWN BIT(17)
+
+#define ALX_LPI_CTRL 0x1440
+#define ALX_LPI_CTRL_EN BIT(0)
+
+/* for B0+, bit[13..] for C0+ */
+#define ALX_HRTBT_EXT_CTRL 0x1AD0
+#define L1F_HRTBT_EXT_CTRL_PERIOD_HIGH_MASK 0x3F
+#define L1F_HRTBT_EXT_CTRL_PERIOD_HIGH_SHIFT 24
+#define L1F_HRTBT_EXT_CTRL_SWOI_STARTUP_PKT_EN BIT(23)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_FRAGMENTED BIT(22)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_FRAGMENTED BIT(21)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_KEEPALIVE_EN BIT(20)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_HAS_VLAN BIT(19)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_IS_8023 BIT(18)
+#define L1F_HRTBT_EXT_CTRL_IOAC_1_IS_IPV6 BIT(17)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_KEEPALIVE_EN BIT(16)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_HAS_VLAN BIT(15)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_IS_8023 BIT(14)
+#define L1F_HRTBT_EXT_CTRL_IOAC_2_IS_IPV6 BIT(13)
+#define ALX_HRTBT_EXT_CTRL_NS_EN BIT(12)
+#define ALX_HRTBT_EXT_CTRL_FRAG_LEN_MASK 0xFF
+#define ALX_HRTBT_EXT_CTRL_FRAG_LEN_SHIFT 4
+#define ALX_HRTBT_EXT_CTRL_IS_8023 BIT(3)
+#define ALX_HRTBT_EXT_CTRL_IS_IPV6 BIT(2)
+#define ALX_HRTBT_EXT_CTRL_WAKEUP_EN BIT(1)
+#define ALX_HRTBT_EXT_CTRL_ARP_EN BIT(0)
+
+#define ALX_HRTBT_REM_IPV4_ADDR 0x1AD4
+#define ALX_HRTBT_HOST_IPV4_ADDR 0x1478
+#define ALX_HRTBT_REM_IPV6_ADDR3 0x1AD8
+#define ALX_HRTBT_REM_IPV6_ADDR2 0x1ADC
+#define ALX_HRTBT_REM_IPV6_ADDR1 0x1AE0
+#define ALX_HRTBT_REM_IPV6_ADDR0 0x1AE4
+
+/* 1B8C ~ 1B94 for C0+ */
+#define ALX_SWOI_ACER_CTRL 0x1B8C
+#define ALX_SWOI_ORIG_ACK_NAK_EN BIT(20)
+#define ALX_SWOI_ORIG_ACK_NAK_PKT_LEN_MASK 0XFF
+#define ALX_SWOI_ORIG_ACK_NAK_PKT_LEN_SHIFT 12
+#define ALX_SWOI_ORIG_ACK_ADDR_MASK 0XFFF
+#define ALX_SWOI_ORIG_ACK_ADDR_SHIFT 0
+
+#define ALX_SWOI_IOAC_CTRL_2 0x1B90
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_FRAG_LEN_MASK 0xFF
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_FRAG_LEN_SHIFT 24
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_PKT_LEN_MASK 0xFFF
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_PKT_LEN_SHIFT 12
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_HDR_ADDR_MASK 0xFFF
+#define ALX_SWOI_IOAC_CTRL_2_SWOI_1_HDR_ADDR_SHIFT 0
+
+#define ALX_SWOI_IOAC_CTRL_3 0x1B94
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_FRAG_LEN_MASK 0xFF
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_FRAG_LEN_SHIFT 24
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_PKT_LEN_MASK 0xFFF
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_PKT_LEN_SHIFT 12
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_HDR_ADDR_MASK 0xFFF
+#define ALX_SWOI_IOAC_CTRL_3_SWOI_2_HDR_ADDR_SHIFT 0
+
+/* for B0 */
+#define ALX_IDLE_DECISN_TIMER 0x1474
+/* 1ms */
+#define ALX_IDLE_DECISN_TIMER_DEF 0x400
+
+#define ALX_MAC_CTRL 0x1480
+#define ALX_MAC_CTRL_FAST_PAUSE BIT(31)
+#define ALX_MAC_CTRL_WOLSPED_SWEN BIT(30)
+/* bit29: 1:legacy(hi5b), 0:marvl(lo5b)*/
+#define ALX_MAC_CTRL_MHASH_ALG_HI5B BIT(29)
+#define ALX_MAC_CTRL_BRD_EN BIT(26)
+#define ALX_MAC_CTRL_MULTIALL_EN BIT(25)
+#define ALX_MAC_CTRL_SPEED_MASK 0x3
+#define ALX_MAC_CTRL_SPEED_SHIFT 20
+#define ALX_MAC_CTRL_SPEED_10_100 1
+#define ALX_MAC_CTRL_SPEED_1000 2
+#define ALX_MAC_CTRL_PROMISC_EN BIT(15)
+#define ALX_MAC_CTRL_VLANSTRIP BIT(14)
+#define ALX_MAC_CTRL_PRMBLEN_MASK 0xF
+#define ALX_MAC_CTRL_PRMBLEN_SHIFT 10
+#define ALX_MAC_CTRL_PCRCE BIT(7)
+#define ALX_MAC_CTRL_CRCE BIT(6)
+#define ALX_MAC_CTRL_FULLD BIT(5)
+#define ALX_MAC_CTRL_RXFC_EN BIT(3)
+#define ALX_MAC_CTRL_TXFC_EN BIT(2)
+#define ALX_MAC_CTRL_RX_EN BIT(1)
+#define ALX_MAC_CTRL_TX_EN BIT(0)
+
+#define ALX_STAD0 0x1488
+#define ALX_STAD1 0x148C
+
+#define ALX_HASH_TBL0 0x1490
+#define ALX_HASH_TBL1 0x1494
+
+#define ALX_MTU 0x149C
+#define ALX_MTU_JUMBO_TH 1514
+#define ALX_MTU_STD_ALGN 1536
+
+#define ALX_SRAM5 0x1524
+#define ALX_SRAM_RXF_LEN_MASK 0xFFF
+#define ALX_SRAM_RXF_LEN_SHIFT 0
+#define ALX_SRAM_RXF_LEN_8K (8*1024)
+
+#define ALX_SRAM9 0x1534
+#define ALX_SRAM_LOAD_PTR BIT(0)
+
+#define ALX_RX_BASE_ADDR_HI 0x1540
+
+#define ALX_TX_BASE_ADDR_HI 0x1544
+
+#define ALX_RFD_ADDR_LO 0x1550
+#define ALX_RFD_RING_SZ 0x1560
+#define ALX_RFD_BUF_SZ 0x1564
+
+#define ALX_RRD_ADDR_LO 0x1568
+#define ALX_RRD_RING_SZ 0x1578
+
+/* pri3: highest, pri0: lowest */
+#define ALX_TPD_PRI3_ADDR_LO 0x14E4
+#define ALX_TPD_PRI2_ADDR_LO 0x14E0
+#define ALX_TPD_PRI1_ADDR_LO 0x157C
+#define ALX_TPD_PRI0_ADDR_LO 0x1580
+
+/* producer index is 16bit */
+#define ALX_TPD_PRI3_PIDX 0x1618
+#define ALX_TPD_PRI2_PIDX 0x161A
+#define ALX_TPD_PRI1_PIDX 0x15F0
+#define ALX_TPD_PRI0_PIDX 0x15F2
+
+/* consumer index is 16bit */
+#define ALX_TPD_PRI3_CIDX 0x161C
+#define ALX_TPD_PRI2_CIDX 0x161E
+#define ALX_TPD_PRI1_CIDX 0x15F4
+#define ALX_TPD_PRI0_CIDX 0x15F6
+
+#define ALX_TPD_RING_SZ 0x1584
+
+#define ALX_TXQ0 0x1590
+#define ALX_TXQ0_TXF_BURST_PREF_MASK 0xFFFF
+#define ALX_TXQ0_TXF_BURST_PREF_SHIFT 16
+#define ALX_TXQ_TXF_BURST_PREF_DEF 0x200
+#define ALX_TXQ0_LSO_8023_EN BIT(7)
+#define ALX_TXQ0_MODE_ENHANCE BIT(6)
+#define ALX_TXQ0_EN BIT(5)
+#define ALX_TXQ0_SUPT_IPOPT BIT(4)
+#define ALX_TXQ0_TPD_BURSTPREF_MASK 0xF
+#define ALX_TXQ0_TPD_BURSTPREF_SHIFT 0
+#define ALX_TXQ_TPD_BURSTPREF_DEF 5
+
+#define ALX_TXQ1 0x1594
+/* bit11: drop large packet, len > (rfd buf) */
+#define ALX_TXQ1_ERRLGPKT_DROP_EN BIT(11)
+#define ALX_TXQ1_JUMBO_TSO_TH (7*1024)
+
+#define ALX_RXQ0 0x15A0
+#define ALX_RXQ0_EN BIT(31)
+#define ALX_RXQ0_RSS_HASH_EN BIT(29)
+#define ALX_RXQ0_RSS_MODE_MASK 0x3
+#define ALX_RXQ0_RSS_MODE_SHIFT 26
+#define ALX_RXQ0_RSS_MODE_DIS 0
+#define ALX_RXQ0_RSS_MODE_MQMI 3
+#define ALX_RXQ0_NUM_RFD_PREF_MASK 0x3F
+#define ALX_RXQ0_NUM_RFD_PREF_SHIFT 20
+#define ALX_RXQ0_NUM_RFD_PREF_DEF 8
+#define ALX_RXQ0_IDT_TBL_SIZE_MASK 0x1FF
+#define ALX_RXQ0_IDT_TBL_SIZE_SHIFT 8
+#define ALX_RXQ0_IDT_TBL_SIZE_DEF 0x100
+#define ALX_RXQ0_IDT_TBL_SIZE_NORMAL 128
+#define ALX_RXQ0_IPV6_PARSE_EN BIT(7)
+#define ALX_RXQ0_RSS_HSTYP_MASK 0xF
+#define ALX_RXQ0_RSS_HSTYP_SHIFT 2
+#define ALX_RXQ0_RSS_HSTYP_IPV6_TCP_EN BIT(5)
+#define ALX_RXQ0_RSS_HSTYP_IPV6_EN BIT(4)
+#define ALX_RXQ0_RSS_HSTYP_IPV4_TCP_EN BIT(3)
+#define ALX_RXQ0_RSS_HSTYP_IPV4_EN BIT(2)
+#define ALX_RXQ0_RSS_HSTYP_ALL (ALX_RXQ0_RSS_HSTYP_IPV6_TCP_EN | \
+ ALX_RXQ0_RSS_HSTYP_IPV4_TCP_EN | \
+ ALX_RXQ0_RSS_HSTYP_IPV6_EN | \
+ ALX_RXQ0_RSS_HSTYP_IPV4_EN)
+#define ALX_RXQ0_ASPM_THRESH_MASK 0x3
+#define ALX_RXQ0_ASPM_THRESH_SHIFT 0
+#define ALX_RXQ0_ASPM_THRESH_100M 3
+
+#define ALX_RXQ2 0x15A8
+#define ALX_RXQ2_RXF_XOFF_THRESH_MASK 0xFFF
+#define ALX_RXQ2_RXF_XOFF_THRESH_SHIFT 16
+#define ALX_RXQ2_RXF_XON_THRESH_MASK 0xFFF
+#define ALX_RXQ2_RXF_XON_THRESH_SHIFT 0
+/* Size = tx-packet(1522) + IPG(12) + SOF(8) + 64(Pause) + IPG(12) + SOF(8) +
+ * rx-packet(1522) + delay-of-link(64)
+ * = 3212.
+ */
+#define ALX_RXQ2_RXF_FLOW_CTRL_RSVD 3212
+
+#define ALX_DMA 0x15C0
+#define ALX_DMA_RCHNL_SEL_MASK 0x3
+#define ALX_DMA_RCHNL_SEL_SHIFT 26
+#define ALX_DMA_WDLY_CNT_MASK 0xF
+#define ALX_DMA_WDLY_CNT_SHIFT 16
+#define ALX_DMA_WDLY_CNT_DEF 4
+#define ALX_DMA_RDLY_CNT_MASK 0x1F
+#define ALX_DMA_RDLY_CNT_SHIFT 11
+#define ALX_DMA_RDLY_CNT_DEF 15
+/* bit10: 0:tpd with pri, 1: data */
+#define ALX_DMA_RREQ_PRI_DATA BIT(10)
+#define ALX_DMA_RREQ_BLEN_MASK 0x7
+#define ALX_DMA_RREQ_BLEN_SHIFT 4
+#define ALX_DMA_RORDER_MODE_MASK 0x7
+#define ALX_DMA_RORDER_MODE_SHIFT 0
+#define ALX_DMA_RORDER_MODE_OUT 4
+
+#define ALX_WOL0 0x14A0
+#define ALX_WOL0_PME_LINK BIT(5)
+#define ALX_WOL0_LINK_EN BIT(4)
+#define ALX_WOL0_PME_MAGIC_EN BIT(3)
+#define ALX_WOL0_MAGIC_EN BIT(2)
+
+#define ALX_RFD_PIDX 0x15E0
+
+#define ALX_RFD_CIDX 0x15F8
+
+/* MIB */
+#define ALX_MIB_BASE 0x1700
+
+#define ALX_MIB_RX_OK (ALX_MIB_BASE + 0)
+#define ALX_MIB_RX_BCAST (ALX_MIB_BASE + 4)
+#define ALX_MIB_RX_MCAST (ALX_MIB_BASE + 8)
+#define ALX_MIB_RX_PAUSE (ALX_MIB_BASE + 12)
+#define ALX_MIB_RX_CTRL (ALX_MIB_BASE + 16)
+#define ALX_MIB_RX_FCS_ERR (ALX_MIB_BASE + 20)
+#define ALX_MIB_RX_LEN_ERR (ALX_MIB_BASE + 24)
+#define ALX_MIB_RX_BYTE_CNT (ALX_MIB_BASE + 28)
+#define ALX_MIB_RX_RUNT (ALX_MIB_BASE + 32)
+#define ALX_MIB_RX_FRAG (ALX_MIB_BASE + 36)
+#define ALX_MIB_RX_SZ_64B (ALX_MIB_BASE + 40)
+#define ALX_MIB_RX_SZ_127B (ALX_MIB_BASE + 44)
+#define ALX_MIB_RX_SZ_255B (ALX_MIB_BASE + 48)
+#define ALX_MIB_RX_SZ_511B (ALX_MIB_BASE + 52)
+#define ALX_MIB_RX_SZ_1023B (ALX_MIB_BASE + 56)
+#define ALX_MIB_RX_SZ_1518B (ALX_MIB_BASE + 60)
+#define ALX_MIB_RX_SZ_MAX (ALX_MIB_BASE + 64)
+#define ALX_MIB_RX_OV_SZ (ALX_MIB_BASE + 68)
+#define ALX_MIB_RX_OV_RXF (ALX_MIB_BASE + 72)
+#define ALX_MIB_RX_OV_RRD (ALX_MIB_BASE + 76)
+#define ALX_MIB_RX_ALIGN_ERR (ALX_MIB_BASE + 80)
+#define ALX_MIB_RX_BCCNT (ALX_MIB_BASE + 84)
+#define ALX_MIB_RX_MCCNT (ALX_MIB_BASE + 88)
+#define ALX_MIB_RX_ERRADDR (ALX_MIB_BASE + 92)
+
+#define ALX_MIB_TX_OK (ALX_MIB_BASE + 96)
+#define ALX_MIB_TX_BCAST (ALX_MIB_BASE + 100)
+#define ALX_MIB_TX_MCAST (ALX_MIB_BASE + 104)
+#define ALX_MIB_TX_PAUSE (ALX_MIB_BASE + 108)
+#define ALX_MIB_TX_EXC_DEFER (ALX_MIB_BASE + 112)
+#define ALX_MIB_TX_CTRL (ALX_MIB_BASE + 116)
+#define ALX_MIB_TX_DEFER (ALX_MIB_BASE + 120)
+#define ALX_MIB_TX_BYTE_CNT (ALX_MIB_BASE + 124)
+#define ALX_MIB_TX_SZ_64B (ALX_MIB_BASE + 128)
+#define ALX_MIB_TX_SZ_127B (ALX_MIB_BASE + 132)
+#define ALX_MIB_TX_SZ_255B (ALX_MIB_BASE + 136)
+#define ALX_MIB_TX_SZ_511B (ALX_MIB_BASE + 140)
+#define ALX_MIB_TX_SZ_1023B (ALX_MIB_BASE + 144)
+#define ALX_MIB_TX_SZ_1518B (ALX_MIB_BASE + 148)
+#define ALX_MIB_TX_SZ_MAX (ALX_MIB_BASE + 152)
+#define ALX_MIB_TX_SINGLE_COL (ALX_MIB_BASE + 156)
+#define ALX_MIB_TX_MULTI_COL (ALX_MIB_BASE + 160)
+#define ALX_MIB_TX_LATE_COL (ALX_MIB_BASE + 164)
+#define ALX_MIB_TX_ABORT_COL (ALX_MIB_BASE + 168)
+#define ALX_MIB_TX_UNDERRUN (ALX_MIB_BASE + 172)
+#define ALX_MIB_TX_TRD_EOP (ALX_MIB_BASE + 176)
+#define ALX_MIB_TX_LEN_ERR (ALX_MIB_BASE + 180)
+#define ALX_MIB_TX_TRUNC (ALX_MIB_BASE + 184)
+#define ALX_MIB_TX_BCCNT (ALX_MIB_BASE + 188)
+#define ALX_MIB_TX_MCCNT (ALX_MIB_BASE + 192)
+#define ALX_MIB_UPDATE (ALX_MIB_BASE + 196)
+
+
+#define ALX_ISR 0x1600
+#define ALX_ISR_DIS BIT(31)
+#define ALX_ISR_RX_Q7 BIT(30)
+#define ALX_ISR_RX_Q6 BIT(29)
+#define ALX_ISR_RX_Q5 BIT(28)
+#define ALX_ISR_RX_Q4 BIT(27)
+#define ALX_ISR_PCIE_LNKDOWN BIT(26)
+#define ALX_ISR_RX_Q3 BIT(19)
+#define ALX_ISR_RX_Q2 BIT(18)
+#define ALX_ISR_RX_Q1 BIT(17)
+#define ALX_ISR_RX_Q0 BIT(16)
+#define ALX_ISR_TX_Q0 BIT(15)
+#define ALX_ISR_PHY BIT(12)
+#define ALX_ISR_DMAW BIT(10)
+#define ALX_ISR_DMAR BIT(9)
+#define ALX_ISR_TXF_UR BIT(8)
+#define ALX_ISR_TX_Q3 BIT(7)
+#define ALX_ISR_TX_Q2 BIT(6)
+#define ALX_ISR_TX_Q1 BIT(5)
+#define ALX_ISR_RFD_UR BIT(4)
+#define ALX_ISR_RXF_OV BIT(3)
+#define ALX_ISR_MANU BIT(2)
+#define ALX_ISR_TIMER BIT(1)
+#define ALX_ISR_SMB BIT(0)
+
+#define ALX_IMR 0x1604
+
+/* re-send assert msg if SW no response */
+#define ALX_INT_RETRIG 0x1608
+/* 40ms */
+#define ALX_INT_RETRIG_TO 20000
+
+#define ALX_SMB_TIMER 0x15C4
+
+#define ALX_TINT_TPD_THRSHLD 0x15C8
+
+#define ALX_TINT_TIMER 0x15CC
+
+#define ALX_CLK_GATE 0x1814
+#define ALX_CLK_GATE_RXMAC BIT(5)
+#define ALX_CLK_GATE_TXMAC BIT(4)
+#define ALX_CLK_GATE_RXQ BIT(3)
+#define ALX_CLK_GATE_TXQ BIT(2)
+#define ALX_CLK_GATE_DMAR BIT(1)
+#define ALX_CLK_GATE_DMAW BIT(0)
+#define ALX_CLK_GATE_ALL (ALX_CLK_GATE_RXMAC | \
+ ALX_CLK_GATE_TXMAC | \
+ ALX_CLK_GATE_RXQ | \
+ ALX_CLK_GATE_TXQ | \
+ ALX_CLK_GATE_DMAR | \
+ ALX_CLK_GATE_DMAW)
+
+/* interop between drivers */
+#define ALX_DRV 0x1804
+#define ALX_DRV_PHY_AUTO BIT(28)
+#define ALX_DRV_PHY_1000 BIT(27)
+#define ALX_DRV_PHY_100 BIT(26)
+#define ALX_DRV_PHY_10 BIT(25)
+#define ALX_DRV_PHY_DUPLEX BIT(24)
+/* bit23: adv Pause */
+#define ALX_DRV_PHY_PAUSE BIT(23)
+/* bit22: adv Asym Pause */
+#define ALX_DRV_PHY_MASK 0xFF
+#define ALX_DRV_PHY_SHIFT 21
+#define ALX_DRV_PHY_UNKNOWN 0
+
+/* flag of phy inited */
+#define ALX_PHY_INITED 0x003F
+
+/* reg 1830 ~ 186C for C0+, 16 bit map patterns and wake packet detection */
+#define ALX_WOL_CTRL2 0x1830
+#define ALX_WOL_CTRL2_DATA_STORE BIT(3)
+#define ALX_WOL_CTRL2_PTRN_EVT BIT(2)
+#define ALX_WOL_CTRL2_PME_PTRN_EN BIT(1)
+#define ALX_WOL_CTRL2_PTRN_EN BIT(0)
+
+#define ALX_WOL_CTRL3 0x1834
+#define ALX_WOL_CTRL3_PTRN_ADDR_MASK 0xFFFFF
+#define ALX_WOL_CTRL3_PTRN_ADDR_SHIFT 0
+
+#define ALX_WOL_CTRL4 0x1838
+#define ALX_WOL_CTRL4_PT15_MATCH BIT(31)
+#define ALX_WOL_CTRL4_PT14_MATCH BIT(30)
+#define ALX_WOL_CTRL4_PT13_MATCH BIT(29)
+#define ALX_WOL_CTRL4_PT12_MATCH BIT(28)
+#define ALX_WOL_CTRL4_PT11_MATCH BIT(27)
+#define ALX_WOL_CTRL4_PT10_MATCH BIT(26)
+#define ALX_WOL_CTRL4_PT9_MATCH BIT(25)
+#define ALX_WOL_CTRL4_PT8_MATCH BIT(24)
+#define ALX_WOL_CTRL4_PT7_MATCH BIT(23)
+#define ALX_WOL_CTRL4_PT6_MATCH BIT(22)
+#define ALX_WOL_CTRL4_PT5_MATCH BIT(21)
+#define ALX_WOL_CTRL4_PT4_MATCH BIT(20)
+#define ALX_WOL_CTRL4_PT3_MATCH BIT(19)
+#define ALX_WOL_CTRL4_PT2_MATCH BIT(18)
+#define ALX_WOL_CTRL4_PT1_MATCH BIT(17)
+#define ALX_WOL_CTRL4_PT0_MATCH BIT(16)
+#define ALX_WOL_CTRL4_PT15_EN BIT(15)
+#define ALX_WOL_CTRL4_PT14_EN BIT(14)
+#define ALX_WOL_CTRL4_PT13_EN BIT(13)
+#define ALX_WOL_CTRL4_PT12_EN BIT(12)
+#define ALX_WOL_CTRL4_PT11_EN BIT(11)
+#define ALX_WOL_CTRL4_PT10_EN BIT(10)
+#define ALX_WOL_CTRL4_PT9_EN BIT(9)
+#define ALX_WOL_CTRL4_PT8_EN BIT(8)
+#define ALX_WOL_CTRL4_PT7_EN BIT(7)
+#define ALX_WOL_CTRL4_PT6_EN BIT(6)
+#define ALX_WOL_CTRL4_PT5_EN BIT(5)
+#define ALX_WOL_CTRL4_PT4_EN BIT(4)
+#define ALX_WOL_CTRL4_PT3_EN BIT(3)
+#define ALX_WOL_CTRL4_PT2_EN BIT(2)
+#define ALX_WOL_CTRL4_PT1_EN BIT(1)
+#define ALX_WOL_CTRL4_PT0_EN BIT(0)
+
+#define ALX_WOL_CTRL5 0x183C
+#define ALX_WOL_CTRL5_PT3_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT3_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT2_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT2_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT1_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT1_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT0_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT0_LEN_SHIFT 0
+
+#define ALX_WOL_CTRL6 0x1840
+#define ALX_WOL_CTRL5_PT7_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT7_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT6_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT6_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT5_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT5_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT4_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT4_LEN_SHIFT 0
+
+#define ALX_WOL_CTRL7 0x1844
+#define ALX_WOL_CTRL5_PT11_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT11_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT10_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT10_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT9_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT9_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT8_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT8_LEN_SHIFT 0
+
+#define ALX_WOL_CTRL8 0x1848
+#define ALX_WOL_CTRL5_PT15_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT15_LEN_SHIFT 24
+#define ALX_WOL_CTRL5_PT14_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT14_LEN_SHIFT 16
+#define ALX_WOL_CTRL5_PT13_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT13_LEN_SHIFT 8
+#define ALX_WOL_CTRL5_PT12_LEN_MASK 0xFF
+#define ALX_WOL_CTRL5_PT12_LEN_SHIFT 0
+
+#define ALX_ACER_FIXED_PTN0 0x1850
+#define ALX_ACER_FIXED_PTN0_MASK 0xFFFFFFFF
+#define ALX_ACER_FIXED_PTN0_SHIFT 0
+
+#define ALX_ACER_FIXED_PTN1 0x1854
+#define ALX_ACER_FIXED_PTN1_MASK 0xFFFF
+#define ALX_ACER_FIXED_PTN1_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM0 0x1858
+#define ALX_ACER_RANDOM_NUM0_MASK 0xFFFFFFFF
+#define ALX_ACER_RANDOM_NUM0_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM1 0x185C
+#define ALX_ACER_RANDOM_NUM1_MASK 0xFFFFFFFF
+#define ALX_ACER_RANDOM_NUM1_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM2 0x1860
+#define ALX_ACER_RANDOM_NUM2_MASK 0xFFFFFFFF
+#define ALX_ACER_RANDOM_NUM2_SHIFT 0
+
+#define ALX_ACER_RANDOM_NUM3 0x1864
+#define ALX_ACER_RANDOM_NUM3_MASK 0xFFFFFFFF
+#define ALX_ACER_RANDOM_NUM3_SHIFT 0
+
+#define ALX_ACER_MAGIC 0x1868
+#define ALX_ACER_MAGIC_EN BIT(31)
+#define ALX_ACER_MAGIC_PME_EN BIT(30)
+#define ALX_ACER_MAGIC_MATCH BIT(29)
+#define ALX_ACER_MAGIC_FF_CHECK BIT(10)
+#define ALX_ACER_MAGIC_RAN_LEN_MASK 0x1F
+#define ALX_ACER_MAGIC_RAN_LEN_SHIFT 5
+#define ALX_ACER_MAGIC_FIX_LEN_MASK 0x1F
+#define ALX_ACER_MAGIC_FIX_LEN_SHIFT 0
+
+#define ALX_ACER_TIMER 0x186C
+#define ALX_ACER_TIMER_EN BIT(31)
+#define ALX_ACER_TIMER_PME_EN BIT(30)
+#define ALX_ACER_TIMER_MATCH BIT(29)
+#define ALX_ACER_TIMER_THRES_MASK 0x1FFFF
+#define ALX_ACER_TIMER_THRES_SHIFT 0
+#define ALX_ACER_TIMER_THRES_DEF 1
+
+/* RSS definitions */
+#define ALX_RSS_KEY0 0x14B0
+#define ALX_RSS_KEY1 0x14B4
+#define ALX_RSS_KEY2 0x14B8
+#define ALX_RSS_KEY3 0x14BC
+#define ALX_RSS_KEY4 0x14C0
+#define ALX_RSS_KEY5 0x14C4
+#define ALX_RSS_KEY6 0x14C8
+#define ALX_RSS_KEY7 0x14CC
+#define ALX_RSS_KEY8 0x14D0
+#define ALX_RSS_KEY9 0x14D4
+
+#define ALX_RSS_IDT_TBL0 0x1B00
+
+#define ALX_MSI_MAP_TBL1 0x15D0
+#define ALX_MSI_MAP_TBL1_TXQ1_SHIFT 20
+#define ALX_MSI_MAP_TBL1_TXQ0_SHIFT 16
+#define ALX_MSI_MAP_TBL1_RXQ3_SHIFT 12
+#define ALX_MSI_MAP_TBL1_RXQ2_SHIFT 8
+#define ALX_MSI_MAP_TBL1_RXQ1_SHIFT 4
+#define ALX_MSI_MAP_TBL1_RXQ0_SHIFT 0
+
+#define ALX_MSI_MAP_TBL2 0x15D8
+#define ALX_MSI_MAP_TBL2_TXQ3_SHIFT 20
+#define ALX_MSI_MAP_TBL2_TXQ2_SHIFT 16
+#define ALX_MSI_MAP_TBL2_RXQ7_SHIFT 12
+#define ALX_MSI_MAP_TBL2_RXQ6_SHIFT 8
+#define ALX_MSI_MAP_TBL2_RXQ5_SHIFT 4
+#define ALX_MSI_MAP_TBL2_RXQ4_SHIFT 0
+
+#define ALX_MSI_ID_MAP 0x15D4
+
+#define ALX_MSI_RETRANS_TIMER 0x1920
+/* bit16: 1:line,0:standard */
+#define ALX_MSI_MASK_SEL_LINE BIT(16)
+#define ALX_MSI_RETRANS_TM_MASK 0xFFFF
+#define ALX_MSI_RETRANS_TM_SHIFT 0
+
+/* CR DMA ctrl */
+
+/* TX QoS */
+#define ALX_WRR 0x1938
+#define ALX_WRR_PRI_MASK 0x3
+#define ALX_WRR_PRI_SHIFT 29
+#define ALX_WRR_PRI_RESTRICT_NONE 3
+#define ALX_WRR_PRI3_MASK 0x1F
+#define ALX_WRR_PRI3_SHIFT 24
+#define ALX_WRR_PRI2_MASK 0x1F
+#define ALX_WRR_PRI2_SHIFT 16
+#define ALX_WRR_PRI1_MASK 0x1F
+#define ALX_WRR_PRI1_SHIFT 8
+#define ALX_WRR_PRI0_MASK 0x1F
+#define ALX_WRR_PRI0_SHIFT 0
+
+#define ALX_HQTPD 0x193C
+#define ALX_HQTPD_BURST_EN BIT(31)
+#define ALX_HQTPD_Q3_NUMPREF_MASK 0xF
+#define ALX_HQTPD_Q3_NUMPREF_SHIFT 8
+#define ALX_HQTPD_Q2_NUMPREF_MASK 0xF
+#define ALX_HQTPD_Q2_NUMPREF_SHIFT 4
+#define ALX_HQTPD_Q1_NUMPREF_MASK 0xF
+#define ALX_HQTPD_Q1_NUMPREF_SHIFT 0
+
+#define ALX_MISC 0x19C0
+#define ALX_MISC_PSW_OCP_MASK 0x7
+#define ALX_MISC_PSW_OCP_SHIFT 21
+#define ALX_MISC_PSW_OCP_DEF 0x7
+#define ALX_MISC_ISO_EN BIT(12)
+#define ALX_MISC_INTNLOSC_OPEN BIT(3)
+
+#define ALX_MSIC2 0x19C8
+#define ALX_MSIC2_CALB_START BIT(0)
+
+#define ALX_MISC3 0x19CC
+/* bit1: 1:Software control 25M */
+#define ALX_MISC3_25M_BY_SW BIT(1)
+/* bit0: 25M switch to intnl OSC */
+#define ALX_MISC3_25M_NOTO_INTNL BIT(0)
+
+/* MSIX tbl in memory space */
+#define ALX_MSIX_ENTRY_BASE 0x2000
+
+/********************* PHY regs definition ***************************/
+
+/* PHY Specific Status Register */
+#define ALX_MII_GIGA_PSSR 0x11
+#define ALX_GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800
+#define ALX_GIGA_PSSR_DPLX 0x2000
+#define ALX_GIGA_PSSR_SPEED 0xC000
+#define ALX_GIGA_PSSR_10MBS 0x0000
+#define ALX_GIGA_PSSR_100MBS 0x4000
+#define ALX_GIGA_PSSR_1000MBS 0x8000
+
+/* PHY Interrupt Enable Register */
+#define ALX_MII_IER 0x12
+#define ALX_IER_LINK_UP 0x0400
+#define ALX_IER_LINK_DOWN 0x0800
+
+/* PHY Interrupt Status Register */
+#define ALX_MII_ISR 0x13
+
+#define ALX_MII_DBG_ADDR 0x1D
+#define ALX_MII_DBG_DATA 0x1E
+
+/***************************** debug port *************************************/
+
+#define ALX_MIIDBG_ANACTRL 0x00
+#define ALX_ANACTRL_DEF 0x02EF
+
+#define ALX_MIIDBG_SYSMODCTRL 0x04
+/* en half bias */
+#define ALX_SYSMODCTRL_IECHOADJ_DEF 0xBB8B
+
+#define ALX_MIIDBG_SRDSYSMOD 0x05
+#define ALX_SRDSYSMOD_DEEMP_EN 0x0040
+#define ALX_SRDSYSMOD_DEF 0x2C46
+
+#define ALX_MIIDBG_HIBNEG 0x0B
+#define ALX_HIBNEG_PSHIB_EN 0x8000
+#define ALX_HIBNEG_HIB_PSE 0x1000
+#define ALX_HIBNEG_DEF 0xBC40
+#define ALX_HIBNEG_NOHIB (ALX_HIBNEG_DEF & \
+ ~(ALX_HIBNEG_PSHIB_EN | ALX_HIBNEG_HIB_PSE))
+
+#define ALX_MIIDBG_TST10BTCFG 0x12
+#define ALX_TST10BTCFG_DEF 0x4C04
+
+#define ALX_MIIDBG_AZ_ANADECT 0x15
+#define ALX_AZ_ANADECT_DEF 0x3220
+#define ALX_AZ_ANADECT_LONG 0x3210
+
+#define ALX_MIIDBG_MSE16DB 0x18
+#define ALX_MSE16DB_UP 0x05EA
+#define ALX_MSE16DB_DOWN 0x02EA
+
+#define ALX_MIIDBG_MSE20DB 0x1C
+#define ALX_MSE20DB_TH_MASK 0x7F
+#define ALX_MSE20DB_TH_SHIFT 2
+#define ALX_MSE20DB_TH_DEF 0x2E
+#define ALX_MSE20DB_TH_HI 0x54
+
+#define ALX_MIIDBG_AGC 0x23
+#define ALX_AGC_2_VGA_MASK 0x3FU
+#define ALX_AGC_2_VGA_SHIFT 8
+#define ALX_AGC_LONG1G_LIMT 40
+#define ALX_AGC_LONG100M_LIMT 44
+
+#define ALX_MIIDBG_LEGCYPS 0x29
+#define ALX_LEGCYPS_EN 0x8000
+#define ALX_LEGCYPS_DEF 0x129D
+
+#define ALX_MIIDBG_TST100BTCFG 0x36
+#define ALX_TST100BTCFG_DEF 0xE12C
+
+#define ALX_MIIDBG_GREENCFG 0x3B
+#define ALX_GREENCFG_DEF 0x7078
+
+#define ALX_MIIDBG_GREENCFG2 0x3D
+#define ALX_GREENCFG2_BP_GREEN 0x8000
+#define ALX_GREENCFG2_GATE_DFSE_EN 0x0080
+
+/******* dev 3 *********/
+#define ALX_MIIEXT_PCS 3
+
+#define ALX_MIIEXT_CLDCTRL3 0x8003
+#define ALX_CLDCTRL3_BP_CABLE1TH_DET_GT 0x8000
+
+#define ALX_MIIEXT_CLDCTRL5 0x8005
+#define ALX_CLDCTRL5_BP_VD_HLFBIAS 0x4000
+
+#define ALX_MIIEXT_CLDCTRL6 0x8006
+#define ALX_CLDCTRL6_CAB_LEN_MASK 0xFF
+#define ALX_CLDCTRL6_CAB_LEN_SHIFT 0
+#define ALX_CLDCTRL6_CAB_LEN_SHORT1G 116
+#define ALX_CLDCTRL6_CAB_LEN_SHORT100M 152
+
+#define ALX_MIIEXT_VDRVBIAS 0x8062
+#define ALX_VDRVBIAS_DEF 0x3
+
+/********* dev 7 **********/
+#define ALX_MIIEXT_ANEG 7
+
+#define ALX_MIIEXT_LOCAL_EEEADV 0x3C
+#define ALX_LOCAL_EEEADV_1000BT 0x0004
+#define ALX_LOCAL_EEEADV_100BT 0x0002
+
+#define ALX_MIIEXT_AFE 0x801A
+#define ALX_AFE_10BT_100M_TH 0x0040
+
+#define ALX_MIIEXT_S3DIG10 0x8023
+/* bit0: 1:bypass 10BT rx fifo, 0:original 10BT rx */
+#define ALX_MIIEXT_S3DIG10_SL 0x0001
+#define ALX_MIIEXT_S3DIG10_DEF 0
+
+#define ALX_MIIEXT_NLP78 0x8027
+#define ALX_MIIEXT_NLP78_120M_DEF 0x8A05
+
+#endif
diff --git a/drivers/net/ethernet/atheros/atl1c/Makefile b/drivers/net/ethernet/atheros/atl1c/Makefile
new file mode 100644
index 00000000000..c37d966952e
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atl1c/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ATL1C) += atl1c.o
+atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h
new file mode 100644
index 00000000000..b9203d92893
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h
@@ -0,0 +1,605 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ATL1C_H_
+#define _ATL1C_H_
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/mii.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/tcp.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/workqueue.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+
+#include "atl1c_hw.h"
+
+/* Wake Up Filter Control */
+#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
+#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
+#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
+#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
+
+#define AT_VLAN_TO_TAG(_vlan, _tag) \
+ _tag = ((((_vlan) >> 8) & 0xFF) |\
+ (((_vlan) & 0xFF) << 8))
+
+#define AT_TAG_TO_VLAN(_tag, _vlan) \
+ _vlan = ((((_tag) >> 8) & 0xFF) |\
+ (((_tag) & 0xFF) << 8))
+
+#define SPEED_0 0xffff
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+#define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)
+#define MAX_JUMBO_FRAME_SIZE (6*1024)
+
+#define AT_MAX_RECEIVE_QUEUE 4
+#define AT_DEF_RECEIVE_QUEUE 1
+#define AT_MAX_TRANSMIT_QUEUE 2
+
+#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL
+#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL
+
+#define AT_TX_WATCHDOG (5 * HZ)
+#define AT_MAX_INT_WORK 5
+#define AT_TWSI_EEPROM_TIMEOUT 100
+#define AT_HW_MAX_IDLE_DELAY 10
+#define AT_SUSPEND_LINK_TIMEOUT 100
+
+#define AT_ASPM_L0S_TIMER 6
+#define AT_ASPM_L1_TIMER 12
+#define AT_LCKDET_TIMER 12
+
+#define ATL1C_PCIE_L0S_L1_DISABLE 0x01
+#define ATL1C_PCIE_PHY_RESET 0x02
+
+#define ATL1C_ASPM_L0s_ENABLE 0x0001
+#define ATL1C_ASPM_L1_ENABLE 0x0002
+
+#define AT_REGS_LEN (74 * sizeof(u32))
+#define AT_EEPROM_LEN 512
+
+#define ATL1C_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
+#define ATL1C_RFD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc)
+#define ATL1C_TPD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc)
+#define ATL1C_RRD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status)
+
+/* tpd word 1 bit 0:7 General Checksum task offload */
+#define TPD_L4HDR_OFFSET_MASK 0x00FF
+#define TPD_L4HDR_OFFSET_SHIFT 0
+
+/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */
+#define TPD_TCPHDR_OFFSET_MASK 0x00FF
+#define TPD_TCPHDR_OFFSET_SHIFT 0
+
+/* tpd word 1 bit 0:7 Custom Checksum task offload */
+#define TPD_PLOADOFFSET_MASK 0x00FF
+#define TPD_PLOADOFFSET_SHIFT 0
+
+/* tpd word 1 bit 8:17 */
+#define TPD_CCSUM_EN_MASK 0x0001
+#define TPD_CCSUM_EN_SHIFT 8
+#define TPD_IP_CSUM_MASK 0x0001
+#define TPD_IP_CSUM_SHIFT 9
+#define TPD_TCP_CSUM_MASK 0x0001
+#define TPD_TCP_CSUM_SHIFT 10
+#define TPD_UDP_CSUM_MASK 0x0001
+#define TPD_UDP_CSUM_SHIFT 11
+#define TPD_LSO_EN_MASK 0x0001 /* TCP Large Send Offload */
+#define TPD_LSO_EN_SHIFT 12
+#define TPD_LSO_VER_MASK 0x0001
+#define TPD_LSO_VER_SHIFT 13 /* 0 : ipv4; 1 : ipv4/ipv6 */
+#define TPD_CON_VTAG_MASK 0x0001
+#define TPD_CON_VTAG_SHIFT 14
+#define TPD_INS_VTAG_MASK 0x0001
+#define TPD_INS_VTAG_SHIFT 15
+#define TPD_IPV4_PACKET_MASK 0x0001 /* valid when LSO VER is 1 */
+#define TPD_IPV4_PACKET_SHIFT 16
+#define TPD_ETH_TYPE_MASK 0x0001
+#define TPD_ETH_TYPE_SHIFT 17 /* 0 : 802.3 frame; 1 : Ethernet */
+
+/* tpd word 18:25 Custom Checksum task offload */
+#define TPD_CCSUM_OFFSET_MASK 0x00FF
+#define TPD_CCSUM_OFFSET_SHIFT 18
+#define TPD_CCSUM_EPAD_MASK 0x0001
+#define TPD_CCSUM_EPAD_SHIFT 30
+
+/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */
+#define TPD_MSS_MASK 0x1FFF
+#define TPD_MSS_SHIFT 18
+
+#define TPD_EOP_MASK 0x0001
+#define TPD_EOP_SHIFT 31
+
+struct atl1c_tpd_desc {
+ __le16 buffer_len; /* include 4-byte CRC */
+ __le16 vlan_tag;
+ __le32 word1;
+ __le64 buffer_addr;
+};
+
+struct atl1c_tpd_ext_desc {
+ u32 reservd_0;
+ __le32 word1;
+ __le32 pkt_len;
+ u32 reservd_1;
+};
+/* rrs word 0 bit 0:31 */
+#define RRS_RX_CSUM_MASK 0xFFFF
+#define RRS_RX_CSUM_SHIFT 0
+#define RRS_RX_RFD_CNT_MASK 0x000F
+#define RRS_RX_RFD_CNT_SHIFT 16
+#define RRS_RX_RFD_INDEX_MASK 0x0FFF
+#define RRS_RX_RFD_INDEX_SHIFT 20
+
+/* rrs flag bit 0:16 */
+#define RRS_HEAD_LEN_MASK 0x00FF
+#define RRS_HEAD_LEN_SHIFT 0
+#define RRS_HDS_TYPE_MASK 0x0003
+#define RRS_HDS_TYPE_SHIFT 8
+#define RRS_CPU_NUM_MASK 0x0003
+#define RRS_CPU_NUM_SHIFT 10
+#define RRS_HASH_FLG_MASK 0x000F
+#define RRS_HASH_FLG_SHIFT 12
+
+#define RRS_HDS_TYPE_HEAD 1
+#define RRS_HDS_TYPE_DATA 2
+
+#define RRS_IS_NO_HDS_TYPE(flag) \
+ ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0)
+
+#define RRS_IS_HDS_HEAD(flag) \
+ ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
+ RRS_HDS_TYPE_HEAD)
+
+#define RRS_IS_HDS_DATA(flag) \
+ ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
+ RRS_HDS_TYPE_DATA)
+
+/* rrs word 3 bit 0:31 */
+#define RRS_PKT_SIZE_MASK 0x3FFF
+#define RRS_PKT_SIZE_SHIFT 0
+#define RRS_ERR_L4_CSUM_MASK 0x0001
+#define RRS_ERR_L4_CSUM_SHIFT 14
+#define RRS_ERR_IP_CSUM_MASK 0x0001
+#define RRS_ERR_IP_CSUM_SHIFT 15
+#define RRS_VLAN_INS_MASK 0x0001
+#define RRS_VLAN_INS_SHIFT 16
+#define RRS_PROT_ID_MASK 0x0007
+#define RRS_PROT_ID_SHIFT 17
+#define RRS_RX_ERR_SUM_MASK 0x0001
+#define RRS_RX_ERR_SUM_SHIFT 20
+#define RRS_RX_ERR_CRC_MASK 0x0001
+#define RRS_RX_ERR_CRC_SHIFT 21
+#define RRS_RX_ERR_FAE_MASK 0x0001
+#define RRS_RX_ERR_FAE_SHIFT 22
+#define RRS_RX_ERR_TRUNC_MASK 0x0001
+#define RRS_RX_ERR_TRUNC_SHIFT 23
+#define RRS_RX_ERR_RUNC_MASK 0x0001
+#define RRS_RX_ERR_RUNC_SHIFT 24
+#define RRS_RX_ERR_ICMP_MASK 0x0001
+#define RRS_RX_ERR_ICMP_SHIFT 25
+#define RRS_PACKET_BCAST_MASK 0x0001
+#define RRS_PACKET_BCAST_SHIFT 26
+#define RRS_PACKET_MCAST_MASK 0x0001
+#define RRS_PACKET_MCAST_SHIFT 27
+#define RRS_PACKET_TYPE_MASK 0x0001
+#define RRS_PACKET_TYPE_SHIFT 28
+#define RRS_FIFO_FULL_MASK 0x0001
+#define RRS_FIFO_FULL_SHIFT 29
+#define RRS_802_3_LEN_ERR_MASK 0x0001
+#define RRS_802_3_LEN_ERR_SHIFT 30
+#define RRS_RXD_UPDATED_MASK 0x0001
+#define RRS_RXD_UPDATED_SHIFT 31
+
+#define RRS_ERR_L4_CSUM 0x00004000
+#define RRS_ERR_IP_CSUM 0x00008000
+#define RRS_VLAN_INS 0x00010000
+#define RRS_RX_ERR_SUM 0x00100000
+#define RRS_RX_ERR_CRC 0x00200000
+#define RRS_802_3_LEN_ERR 0x40000000
+#define RRS_RXD_UPDATED 0x80000000
+
+#define RRS_PACKET_TYPE_802_3 1
+#define RRS_PACKET_TYPE_ETH 0
+#define RRS_PACKET_IS_ETH(word) \
+ ((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \
+ RRS_PACKET_TYPE_ETH)
+#define RRS_RXD_IS_VALID(word) \
+ ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
+
+#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \
+ ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1)
+#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \
+ ((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6)
+
+struct atl1c_recv_ret_status {
+ __le32 word0;
+ __le32 rss_hash;
+ __le16 vlan_tag;
+ __le16 flag;
+ __le32 word3;
+};
+
+/* RFD descriptor */
+struct atl1c_rx_free_desc {
+ __le64 buffer_addr;
+};
+
+/* DMA Order Settings */
+enum atl1c_dma_order {
+ atl1c_dma_ord_in = 1,
+ atl1c_dma_ord_enh = 2,
+ atl1c_dma_ord_out = 4
+};
+
+enum atl1c_dma_rcb {
+ atl1c_rcb_64 = 0,
+ atl1c_rcb_128 = 1
+};
+
+enum atl1c_mac_speed {
+ atl1c_mac_speed_0 = 0,
+ atl1c_mac_speed_10_100 = 1,
+ atl1c_mac_speed_1000 = 2
+};
+
+enum atl1c_dma_req_block {
+ atl1c_dma_req_128 = 0,
+ atl1c_dma_req_256 = 1,
+ atl1c_dma_req_512 = 2,
+ atl1c_dma_req_1024 = 3,
+ atl1c_dma_req_2048 = 4,
+ atl1c_dma_req_4096 = 5
+};
+
+
+enum atl1c_nic_type {
+ athr_l1c = 0,
+ athr_l2c = 1,
+ athr_l2c_b,
+ athr_l2c_b2,
+ athr_l1d,
+ athr_l1d_2,
+};
+
+enum atl1c_trans_queue {
+ atl1c_trans_normal = 0,
+ atl1c_trans_high = 1
+};
+
+struct atl1c_hw_stats {
+ /* rx */
+ unsigned long rx_ok; /* The number of good packet received. */
+ unsigned long rx_bcast; /* The number of good broadcast packet received. */
+ unsigned long rx_mcast; /* The number of good multicast packet received. */
+ unsigned long rx_pause; /* The number of Pause packet received. */
+ unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */
+ unsigned long rx_fcs_err; /* The number of packets with bad FCS. */
+ unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */
+ unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */
+ unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */
+ unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */
+ unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */
+ unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */
+ unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */
+ unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */
+ unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
+ unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
+ unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
+ unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
+ unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */
+ unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */
+ unsigned long rx_align_err; /* Alignment Error */
+ unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
+ unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
+ unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */
+
+ /* tx */
+ unsigned long tx_ok; /* The number of good packet transmitted. */
+ unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */
+ unsigned long tx_mcast; /* The number of good multicast packet transmitted. */
+ unsigned long tx_pause; /* The number of Pause packet transmitted. */
+ unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */
+ unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */
+ unsigned long tx_defer; /* The number of packets transmitted that is deferred. */
+ unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */
+ unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */
+ unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
+ unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
+ unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
+ unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
+ unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
+ unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
+ unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */
+ unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
+ unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */
+ unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */
+ unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
+ unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
+ unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */
+ unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */
+ unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */
+ unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */
+};
+
+struct atl1c_hw {
+ u8 __iomem *hw_addr; /* inner register address */
+ struct atl1c_adapter *adapter;
+ enum atl1c_nic_type nic_type;
+ enum atl1c_dma_order dma_order;
+ enum atl1c_dma_rcb rcb_value;
+ enum atl1c_dma_req_block dmar_block;
+
+ u16 device_id;
+ u16 vendor_id;
+ u16 subsystem_id;
+ u16 subsystem_vendor_id;
+ u8 revision_id;
+ u16 phy_id1;
+ u16 phy_id2;
+
+ u32 intr_mask;
+
+ u8 preamble_len;
+ u16 max_frame_size;
+ u16 min_frame_size;
+
+ enum atl1c_mac_speed mac_speed;
+ bool mac_duplex;
+ bool hibernate;
+ u16 media_type;
+#define MEDIA_TYPE_AUTO_SENSOR 0
+#define MEDIA_TYPE_100M_FULL 1
+#define MEDIA_TYPE_100M_HALF 2
+#define MEDIA_TYPE_10M_FULL 3
+#define MEDIA_TYPE_10M_HALF 4
+
+ u16 autoneg_advertised;
+ u16 mii_autoneg_adv_reg;
+ u16 mii_1000t_ctrl_reg;
+
+ u16 tx_imt; /* TX Interrupt Moderator timer ( 2us resolution) */
+ u16 rx_imt; /* RX Interrupt Moderator timer ( 2us resolution) */
+ u16 ict; /* Interrupt Clear timer (2us resolution) */
+ u16 ctrl_flags;
+#define ATL1C_INTR_CLEAR_ON_READ 0x0001
+#define ATL1C_INTR_MODRT_ENABLE 0x0002
+#define ATL1C_CMB_ENABLE 0x0004
+#define ATL1C_SMB_ENABLE 0x0010
+#define ATL1C_TXQ_MODE_ENHANCE 0x0020
+#define ATL1C_RX_IPV6_CHKSUM 0x0040
+#define ATL1C_ASPM_L0S_SUPPORT 0x0080
+#define ATL1C_ASPM_L1_SUPPORT 0x0100
+#define ATL1C_ASPM_CTRL_MON 0x0200
+#define ATL1C_HIB_DISABLE 0x0400
+#define ATL1C_APS_MODE_ENABLE 0x0800
+#define ATL1C_LINK_EXT_SYNC 0x1000
+#define ATL1C_CLK_GATING_EN 0x2000
+#define ATL1C_FPGA_VERSION 0x8000
+ u16 link_cap_flags;
+#define ATL1C_LINK_CAP_1000M 0x0001
+ u32 smb_timer;
+
+ u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
+ interrupt request */
+ u16 tpd_thresh;
+ u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */
+ u8 rfd_burst;
+ u32 base_cpu;
+ u32 indirect_tab;
+ u8 mac_addr[ETH_ALEN];
+ u8 perm_mac_addr[ETH_ALEN];
+
+ bool phy_configured;
+ bool re_autoneg;
+ bool emi_ca;
+ bool msi_lnkpatch; /* link patch for specific platforms */
+};
+
+/*
+ * atl1c_ring_header represents a single, contiguous block of DMA space
+ * mapped for the three descriptor rings (tpd, rfd, rrd) described below
+ */
+struct atl1c_ring_header {
+ void *desc; /* virtual address */
+ dma_addr_t dma; /* physical address*/
+ unsigned int size; /* length in bytes */
+};
+
+/*
+ * atl1c_buffer is wrapper around a pointer to a socket buffer
+ * so a DMA handle can be stored along with the skb
+ */
+struct atl1c_buffer {
+ struct sk_buff *skb; /* socket buffer */
+ u16 length; /* rx buffer length */
+ u16 flags; /* information of buffer */
+#define ATL1C_BUFFER_FREE 0x0001
+#define ATL1C_BUFFER_BUSY 0x0002
+#define ATL1C_BUFFER_STATE_MASK 0x0003
+
+#define ATL1C_PCIMAP_SINGLE 0x0004
+#define ATL1C_PCIMAP_PAGE 0x0008
+#define ATL1C_PCIMAP_TYPE_MASK 0x000C
+
+#define ATL1C_PCIMAP_TODEVICE 0x0010
+#define ATL1C_PCIMAP_FROMDEVICE 0x0020
+#define ATL1C_PCIMAP_DIRECTION_MASK 0x0030
+ dma_addr_t dma;
+};
+
+#define ATL1C_SET_BUFFER_STATE(buff, state) do { \
+ ((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK; \
+ ((buff)->flags) |= (state); \
+ } while (0)
+
+#define ATL1C_SET_PCIMAP_TYPE(buff, type, direction) do { \
+ ((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK; \
+ ((buff)->flags) |= (type); \
+ ((buff)->flags) &= ~ATL1C_PCIMAP_DIRECTION_MASK; \
+ ((buff)->flags) |= (direction); \
+ } while (0)
+
+/* transimit packet descriptor (tpd) ring */
+struct atl1c_tpd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use; /* this is protectd by adapter->tx_lock */
+ atomic_t next_to_clean;
+ struct atl1c_buffer *buffer_info;
+};
+
+/* receive free descriptor (rfd) ring */
+struct atl1c_rfd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use;
+ u16 next_to_clean;
+ struct atl1c_buffer *buffer_info;
+};
+
+/* receive return descriptor (rrd) ring */
+struct atl1c_rrd_ring {
+ void *desc; /* descriptor ring virtual address */
+ dma_addr_t dma; /* descriptor ring physical address */
+ u16 size; /* descriptor ring length in bytes */
+ u16 count; /* number of descriptors in the ring */
+ u16 next_to_use;
+ u16 next_to_clean;
+};
+
+/* board specific private data structure */
+struct atl1c_adapter {
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+ struct napi_struct napi;
+ struct page *rx_page;
+ unsigned int rx_page_offset;
+ unsigned int rx_frag_size;
+ struct atl1c_hw hw;
+ struct atl1c_hw_stats hw_stats;
+ struct mii_if_info mii; /* MII interface info */
+ u16 rx_buffer_len;
+
+ unsigned long flags;
+#define __AT_TESTING 0x0001
+#define __AT_RESETTING 0x0002
+#define __AT_DOWN 0x0003
+ unsigned long work_event;
+#define ATL1C_WORK_EVENT_RESET 0
+#define ATL1C_WORK_EVENT_LINK_CHANGE 1
+ u32 msg_enable;
+
+ bool have_msi;
+ u32 wol;
+ u16 link_speed;
+ u16 link_duplex;
+
+ spinlock_t mdio_lock;
+ spinlock_t tx_lock;
+ atomic_t irq_sem;
+
+ struct work_struct common_task;
+ struct timer_list watchdog_timer;
+ struct timer_list phy_config_timer;
+
+ /* All Descriptor memory */
+ struct atl1c_ring_header ring_header;
+ struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE];
+ struct atl1c_rfd_ring rfd_ring;
+ struct atl1c_rrd_ring rrd_ring;
+ u32 bd_number; /* board number;*/
+};
+
+#define AT_WRITE_REG(a, reg, value) ( \
+ writel((value), ((a)->hw_addr + reg)))
+
+#define AT_WRITE_FLUSH(a) (\
+ readl((a)->hw_addr))
+
+#define AT_READ_REG(a, reg, pdata) do { \
+ if (unlikely((a)->hibernate)) { \
+ readl((a)->hw_addr + reg); \
+ *(u32 *)pdata = readl((a)->hw_addr + reg); \
+ } else { \
+ *(u32 *)pdata = readl((a)->hw_addr + reg); \
+ } \
+ } while (0)
+
+#define AT_WRITE_REGB(a, reg, value) (\
+ writeb((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGB(a, reg) (\
+ readb((a)->hw_addr + reg))
+
+#define AT_WRITE_REGW(a, reg, value) (\
+ writew((value), ((a)->hw_addr + reg)))
+
+#define AT_READ_REGW(a, reg, pdata) do { \
+ if (unlikely((a)->hibernate)) { \
+ readw((a)->hw_addr + reg); \
+ *(u16 *)pdata = readw((a)->hw_addr + reg); \
+ } else { \
+ *(u16 *)pdata = readw((a)->hw_addr + reg); \
+ } \
+ } while (0)
+
+#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+ writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
+
+#define AT_READ_REG_ARRAY(a, reg, offset) ( \
+ readl(((a)->hw_addr + reg) + ((offset) << 2)))
+
+extern char atl1c_driver_name[];
+extern char atl1c_driver_version[];
+
+void atl1c_reinit_locked(struct atl1c_adapter *adapter);
+s32 atl1c_reset_hw(struct atl1c_hw *hw);
+void atl1c_set_ethtool_ops(struct net_device *netdev);
+#endif /* _ATL1C_H_ */
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
new file mode 100644
index 00000000000..48694c239d5
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_ethtool.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/slab.h>
+
+#include "atl1c.h"
+
+static int atl1c_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+
+ ecmd->supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_TP);
+ if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M)
+ ecmd->supported |= SUPPORTED_1000baseT_Full;
+
+ ecmd->advertising = ADVERTISED_TP;
+
+ ecmd->advertising |= hw->autoneg_advertised;
+
+ ecmd->port = PORT_TP;
+ ecmd->phy_address = 0;
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (adapter->link_speed != SPEED_0) {
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
+ if (adapter->link_duplex == FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+ } else {
+ ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+ ecmd->duplex = DUPLEX_UNKNOWN;
+ }
+
+ ecmd->autoneg = AUTONEG_ENABLE;
+ return 0;
+}
+
+static int atl1c_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u16 autoneg_advertised;
+
+ while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+ msleep(1);
+
+ if (ecmd->autoneg == AUTONEG_ENABLE) {
+ autoneg_advertised = ADVERTISED_Autoneg;
+ } else {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (speed == SPEED_1000) {
+ if (ecmd->duplex != DUPLEX_FULL) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev,
+ "1000M half is invalid\n");
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+ autoneg_advertised = ADVERTISED_1000baseT_Full;
+ } else if (speed == SPEED_100) {
+ if (ecmd->duplex == DUPLEX_FULL)
+ autoneg_advertised = ADVERTISED_100baseT_Full;
+ else
+ autoneg_advertised = ADVERTISED_100baseT_Half;
+ } else {
+ if (ecmd->duplex == DUPLEX_FULL)
+ autoneg_advertised = ADVERTISED_10baseT_Full;
+ else
+ autoneg_advertised = ADVERTISED_10baseT_Half;
+ }
+ }
+
+ if (hw->autoneg_advertised != autoneg_advertised) {
+ hw->autoneg_advertised = autoneg_advertised;
+ if (atl1c_restart_autoneg(hw) != 0) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev,
+ "ethtool speed/duplex setting failed\n");
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+ }
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ return 0;
+}
+
+static u32 atl1c_get_msglevel(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ return adapter->msg_enable;
+}
+
+static void atl1c_set_msglevel(struct net_device *netdev, u32 data)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ adapter->msg_enable = data;
+}
+
+static int atl1c_get_regs_len(struct net_device *netdev)
+{
+ return AT_REGS_LEN;
+}
+
+static void atl1c_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 *regs_buff = p;
+ u16 phy_data;
+
+ memset(p, 0, AT_REGS_LEN);
+
+ regs->version = 1;
+ AT_READ_REG(hw, REG_PM_CTRL, p++);
+ AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++);
+ AT_READ_REG(hw, REG_TWSI_CTRL, p++);
+ AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++);
+ AT_READ_REG(hw, REG_MASTER_CTRL, p++);
+ AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++);
+ AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++);
+ AT_READ_REG(hw, REG_GPHY_CTRL, p++);
+ AT_READ_REG(hw, REG_LINK_CTRL, p++);
+ AT_READ_REG(hw, REG_IDLE_STATUS, p++);
+ AT_READ_REG(hw, REG_MDIO_CTRL, p++);
+ AT_READ_REG(hw, REG_SERDES, p++);
+ AT_READ_REG(hw, REG_MAC_CTRL, p++);
+ AT_READ_REG(hw, REG_MAC_IPG_IFG, p++);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR, p++);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++);
+ AT_READ_REG(hw, REG_RX_HASH_TABLE, p++);
+ AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++);
+ AT_READ_REG(hw, REG_RXQ_CTRL, p++);
+ AT_READ_REG(hw, REG_TXQ_CTRL, p++);
+ AT_READ_REG(hw, REG_MTU, p++);
+ AT_READ_REG(hw, REG_WOL_CTRL, p++);
+
+ atl1c_read_phy_reg(hw, MII_BMCR, &phy_data);
+ regs_buff[AT_REGS_LEN/sizeof(u32) - 2] = (u32) phy_data;
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ regs_buff[AT_REGS_LEN/sizeof(u32) - 1] = (u32) phy_data;
+}
+
+static int atl1c_get_eeprom_len(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (atl1c_check_eeprom_exist(&adapter->hw))
+ return AT_EEPROM_LEN;
+ else
+ return 0;
+}
+
+static int atl1c_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 *eeprom_buff;
+ int first_dword, last_dword;
+ int ret_val = 0;
+ int i;
+
+ if (eeprom->len == 0)
+ return -EINVAL;
+
+ if (!atl1c_check_eeprom_exist(hw)) /* not exist */
+ return -EINVAL;
+
+ eeprom->magic = adapter->pdev->vendor |
+ (adapter->pdev->device << 16);
+
+ first_dword = eeprom->offset >> 2;
+ last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+ eeprom_buff = kmalloc(sizeof(u32) *
+ (last_dword - first_dword + 1), GFP_KERNEL);
+ if (eeprom_buff == NULL)
+ return -ENOMEM;
+
+ for (i = first_dword; i < last_dword; i++) {
+ if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
+ kfree(eeprom_buff);
+ return -EIO;
+ }
+ }
+
+ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+ eeprom->len);
+ kfree(eeprom_buff);
+
+ return ret_val;
+ return 0;
+}
+
+static void atl1c_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ strlcpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, atl1c_driver_version,
+ sizeof(drvinfo->version));
+ strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
+ drvinfo->n_stats = 0;
+ drvinfo->testinfo_len = 0;
+ drvinfo->regdump_len = atl1c_get_regs_len(netdev);
+ drvinfo->eedump_len = atl1c_get_eeprom_len(netdev);
+}
+
+static void atl1c_get_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_MAGIC | WAKE_PHY;
+ wol->wolopts = 0;
+
+ if (adapter->wol & AT_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if (adapter->wol & AT_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if (adapter->wol & AT_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if (adapter->wol & AT_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+ if (adapter->wol & AT_WUFC_LNKC)
+ wol->wolopts |= WAKE_PHY;
+}
+
+static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
+ WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
+ return -EOPNOTSUPP;
+ /* these settings will always override what we currently have */
+ adapter->wol = 0;
+
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= AT_WUFC_MAG;
+ if (wol->wolopts & WAKE_PHY)
+ adapter->wol |= AT_WUFC_LNKC;
+
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ return 0;
+}
+
+static int atl1c_nway_reset(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ if (netif_running(netdev))
+ atl1c_reinit_locked(adapter);
+ return 0;
+}
+
+static const struct ethtool_ops atl1c_ethtool_ops = {
+ .get_settings = atl1c_get_settings,
+ .set_settings = atl1c_set_settings,
+ .get_drvinfo = atl1c_get_drvinfo,
+ .get_regs_len = atl1c_get_regs_len,
+ .get_regs = atl1c_get_regs,
+ .get_wol = atl1c_get_wol,
+ .set_wol = atl1c_set_wol,
+ .get_msglevel = atl1c_get_msglevel,
+ .set_msglevel = atl1c_set_msglevel,
+ .nway_reset = atl1c_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = atl1c_get_eeprom_len,
+ .get_eeprom = atl1c_get_eeprom,
+};
+
+void atl1c_set_ethtool_ops(struct net_device *netdev)
+{
+ netdev->ethtool_ops = &atl1c_ethtool_ops;
+}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
new file mode 100644
index 00000000000..1cda49a28f7
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
@@ -0,0 +1,865 @@
+/*
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+
+#include "atl1c.h"
+
+/*
+ * check_eeprom_exist
+ * return 1 if eeprom exist
+ */
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
+ if (data & TWSI_DEBUG_DEV_EXIST)
+ return 1;
+
+ AT_READ_REG(hw, REG_MASTER_CTRL, &data);
+ if (data & MASTER_CTRL_OTP_SEL)
+ return 1;
+ return 0;
+}
+
+void atl1c_hw_set_mac_addr(struct atl1c_hw *hw, u8 *mac_addr)
+{
+ u32 value;
+ /*
+ * 00-0B-6A-F6-00-DC
+ * 0: 6AF600DC 1: 000B
+ * low dword
+ */
+ value = mac_addr[2] << 24 |
+ mac_addr[3] << 16 |
+ mac_addr[4] << 8 |
+ mac_addr[5];
+ AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+ /* hight dword */
+ value = mac_addr[0] << 8 |
+ mac_addr[1];
+ AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/* read mac address from hardware register */
+static bool atl1c_read_current_addr(struct atl1c_hw *hw, u8 *eth_addr)
+{
+ u32 addr[2];
+
+ AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
+ AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
+
+ *(u32 *) &eth_addr[2] = htonl(addr[0]);
+ *(u16 *) &eth_addr[0] = htons((u16)addr[1]);
+
+ return is_valid_ether_addr(eth_addr);
+}
+
+/*
+ * atl1c_get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int atl1c_get_permanent_address(struct atl1c_hw *hw)
+{
+ u32 i;
+ u32 otp_ctrl_data;
+ u32 twsi_ctrl_data;
+ u16 phy_data;
+ bool raise_vol = false;
+
+ /* MAC-address from BIOS is the 1st priority */
+ if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
+ return 0;
+
+ /* init */
+ AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+ if (atl1c_check_eeprom_exist(hw)) {
+ if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
+ /* Enable OTP CLK */
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
+ otp_ctrl_data |= OTP_CTRL_CLK_EN;
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ msleep(1);
+ }
+ }
+ /* raise voltage temporally for l2cb */
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
+ atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
+ phy_data &= ~ANACTRL_HB_EN;
+ atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
+ atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
+ phy_data |= VOLT_CTRL_SWLOWEST;
+ atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
+ udelay(20);
+ raise_vol = true;
+ }
+
+ AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+ twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
+ AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
+ for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
+ msleep(10);
+ AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
+ if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
+ break;
+ }
+ if (i >= AT_TWSI_EEPROM_TIMEOUT)
+ return -1;
+ }
+ /* Disable OTP_CLK */
+ if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
+ otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+ msleep(1);
+ }
+ if (raise_vol) {
+ atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
+ phy_data |= ANACTRL_HB_EN;
+ atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
+ atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
+ phy_data &= ~VOLT_CTRL_SWLOWEST;
+ atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
+ udelay(20);
+ }
+
+ if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
+ return 0;
+
+ return -1;
+}
+
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
+{
+ int i;
+ bool ret = false;
+ u32 otp_ctrl_data;
+ u32 control;
+ u32 data;
+
+ if (offset & 3)
+ return ret; /* address do not align */
+
+ AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+ AT_WRITE_REG(hw, REG_OTP_CTRL,
+ (otp_ctrl_data | OTP_CTRL_CLK_EN));
+
+ AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
+ control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
+ AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
+
+ for (i = 0; i < 10; i++) {
+ udelay(100);
+ AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
+ if (control & EEPROM_CTRL_RW)
+ break;
+ }
+ if (control & EEPROM_CTRL_RW) {
+ AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
+ AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
+ data = data & 0xFFFF;
+ *p_value = swab32((data << 16) | (*p_value >> 16));
+ ret = true;
+ }
+ if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
+ AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
+
+ return ret;
+}
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+int atl1c_read_mac_addr(struct atl1c_hw *hw)
+{
+ int err = 0;
+
+ err = atl1c_get_permanent_address(hw);
+ if (err)
+ eth_random_addr(hw->perm_mac_addr);
+
+ memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
+ return err;
+}
+
+/*
+ * atl1c_hash_mc_addr
+ * purpose
+ * set hash value for a multicast address
+ * hash calcu processing :
+ * 1. calcu 32bit CRC for multicast address
+ * 2. reverse crc with MSB to LSB
+ */
+u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
+{
+ u32 crc32;
+ u32 value = 0;
+ int i;
+
+ crc32 = ether_crc_le(6, mc_addr);
+ for (i = 0; i < 32; i++)
+ value |= (((crc32 >> i) & 1) << (31 - i));
+
+ return value;
+}
+
+/*
+ * Sets the bit in the multicast table corresponding to the hash value.
+ * hw - Struct containing variables accessed by shared code
+ * hash_value - Multicast address hash value
+ */
+void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
+{
+ u32 hash_bit, hash_reg;
+ u32 mta;
+
+ /*
+ * The HASH Table is a register array of 2 32-bit registers.
+ * It is treated like an array of 64 bits. We want to set
+ * bit BitArray[hash_value]. So we figure out what register
+ * the bit is in, read it, OR in the new bit, then write
+ * back the new value. The register is determined by the
+ * upper bit of the hash value and the bit within that
+ * register are determined by the lower 5 bits of the value.
+ */
+ hash_reg = (hash_value >> 31) & 0x1;
+ hash_bit = (hash_value >> 26) & 0x1F;
+
+ mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+ mta |= (1 << hash_bit);
+
+ AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+
+/*
+ * wait mdio module be idle
+ * return true: idle
+ * false: still busy
+ */
+bool atl1c_wait_mdio_idle(struct atl1c_hw *hw)
+{
+ u32 val;
+ int i;
+
+ for (i = 0; i < MDIO_MAX_AC_TO; i++) {
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ if (!(val & (MDIO_CTRL_BUSY | MDIO_CTRL_START)))
+ break;
+ udelay(10);
+ }
+
+ return i != MDIO_MAX_AC_TO;
+}
+
+void atl1c_stop_phy_polling(struct atl1c_hw *hw)
+{
+ if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+ return;
+
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, 0);
+ atl1c_wait_mdio_idle(hw);
+}
+
+void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel)
+{
+ u32 val;
+
+ if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
+ return;
+
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_REG, 1) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_OP_READ;
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+ atl1c_wait_mdio_idle(hw);
+ val |= MDIO_CTRL_AP_EN;
+ val &= ~MDIO_CTRL_START;
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+ udelay(30);
+}
+
+
+/*
+ * atl1c_read_phy_core
+ * core funtion to read register in PHY via MDIO control regsiter.
+ * ext: extension register (see IEEE 802.3)
+ * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
+ * reg: reg to read
+ */
+int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 *phy_data)
+{
+ u32 val;
+ u16 clk_sel = MDIO_CTRL_CLK_25_4;
+
+ atl1c_stop_phy_polling(hw);
+
+ *phy_data = 0;
+
+ /* only l2c_b2 & l1d_2 could use slow clock */
+ if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
+ hw->hibernate)
+ clk_sel = MDIO_CTRL_CLK_25_128;
+ if (ext) {
+ val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
+ AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_MODE_EXT |
+ MDIO_CTRL_OP_READ;
+ } else {
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_REG, reg) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_OP_READ;
+ }
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ if (!atl1c_wait_mdio_idle(hw))
+ return -1;
+
+ AT_READ_REG(hw, REG_MDIO_CTRL, &val);
+ *phy_data = (u16)FIELD_GETX(val, MDIO_CTRL_DATA);
+
+ atl1c_start_phy_polling(hw, clk_sel);
+
+ return 0;
+}
+
+/*
+ * atl1c_write_phy_core
+ * core funtion to write to register in PHY via MDIO control regsiter.
+ * ext: extension register (see IEEE 802.3)
+ * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
+ * reg: reg to write
+ */
+int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 phy_data)
+{
+ u32 val;
+ u16 clk_sel = MDIO_CTRL_CLK_25_4;
+
+ atl1c_stop_phy_polling(hw);
+
+
+ /* only l2c_b2 & l1d_2 could use slow clock */
+ if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
+ hw->hibernate)
+ clk_sel = MDIO_CTRL_CLK_25_128;
+
+ if (ext) {
+ val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
+ AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_DATA, phy_data) |
+ MDIO_CTRL_START |
+ MDIO_CTRL_MODE_EXT;
+ } else {
+ val = MDIO_CTRL_SPRES_PRMBL |
+ FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
+ FIELDX(MDIO_CTRL_DATA, phy_data) |
+ FIELDX(MDIO_CTRL_REG, reg) |
+ MDIO_CTRL_START;
+ }
+ AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ if (!atl1c_wait_mdio_idle(hw))
+ return -1;
+
+ atl1c_start_phy_polling(hw, clk_sel);
+
+ return 0;
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+ return atl1c_read_phy_core(hw, false, 0, reg_addr, phy_data);
+}
+
+/*
+ * Writes a value to a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to write
+ * data - data to write to the PHY
+ */
+int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
+{
+ return atl1c_write_phy_core(hw, false, 0, reg_addr, phy_data);
+}
+
+/* read from PHY extension register */
+int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
+ u16 reg_addr, u16 *phy_data)
+{
+ return atl1c_read_phy_core(hw, true, dev_addr, reg_addr, phy_data);
+}
+
+/* write to PHY extension register */
+int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
+ u16 reg_addr, u16 phy_data)
+{
+ return atl1c_write_phy_core(hw, true, dev_addr, reg_addr, phy_data);
+}
+
+int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+ int err;
+
+ err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
+ if (unlikely(err))
+ return err;
+ else
+ err = atl1c_read_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+ return err;
+}
+
+int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data)
+{
+ int err;
+
+ err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
+ if (unlikely(err))
+ return err;
+ else
+ err = atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
+
+ return err;
+}
+
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
+{
+ u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_ALL;
+ u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
+ ~GIGA_CR_1000T_SPEED_MASK;
+
+ if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
+ mii_adv_data |= ADVERTISE_10HALF;
+ if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
+ mii_adv_data |= ADVERTISE_10FULL;
+ if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
+ mii_adv_data |= ADVERTISE_100HALF;
+ if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
+ mii_adv_data |= ADVERTISE_100FULL;
+
+ if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+ mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
+ ADVERTISE_100HALF | ADVERTISE_100FULL;
+
+ if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
+ if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
+ mii_giga_ctrl_data |= ADVERTISE_1000HALF;
+ if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
+ mii_giga_ctrl_data |= ADVERTISE_1000FULL;
+ if (hw->autoneg_advertised & ADVERTISED_Autoneg)
+ mii_giga_ctrl_data |= ADVERTISE_1000HALF |
+ ADVERTISE_1000FULL;
+ }
+
+ if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
+ atl1c_write_phy_reg(hw, MII_CTRL1000, mii_giga_ctrl_data) != 0)
+ return -1;
+ return 0;
+}
+
+void atl1c_phy_disable(struct atl1c_hw *hw)
+{
+ atl1c_power_saving(hw, 0);
+}
+
+
+int atl1c_phy_reset(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 phy_data;
+ u32 phy_ctrl_data, lpi_ctrl;
+ int err;
+
+ /* reset PHY core */
+ AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl_data);
+ phy_ctrl_data &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_PHY_IDDQ |
+ GPHY_CTRL_GATE_25M_EN | GPHY_CTRL_PWDOWN_HW | GPHY_CTRL_CLS);
+ phy_ctrl_data |= GPHY_CTRL_SEL_ANA_RST;
+ if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE))
+ phy_ctrl_data |= (GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
+ else
+ phy_ctrl_data &= ~(GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
+ AT_WRITE_FLUSH(hw);
+ udelay(10);
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data | GPHY_CTRL_EXT_RESET);
+ AT_WRITE_FLUSH(hw);
+ udelay(10 * GPHY_CTRL_EXT_RST_TO); /* delay 800us */
+
+ /* switch clock */
+ if (hw->nic_type == athr_l2c_b) {
+ atl1c_read_phy_dbg(hw, MIIDBG_CFGLPSPD, &phy_data);
+ atl1c_write_phy_dbg(hw, MIIDBG_CFGLPSPD,
+ phy_data & ~CFGLPSPD_RSTCNT_CLK125SW);
+ }
+
+ /* tx-half amplitude issue fix */
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
+ atl1c_read_phy_dbg(hw, MIIDBG_CABLE1TH_DET, &phy_data);
+ phy_data |= CABLE1TH_DET_EN;
+ atl1c_write_phy_dbg(hw, MIIDBG_CABLE1TH_DET, phy_data);
+ }
+
+ /* clear bit3 of dbgport 3B to lower voltage */
+ if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE)) {
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
+ atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
+ phy_data &= ~VOLT_CTRL_SWLOWEST;
+ atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
+ }
+ /* power saving config */
+ phy_data =
+ hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ?
+ L1D_LEGCYPS_DEF : L1C_LEGCYPS_DEF;
+ atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS, phy_data);
+ /* hib */
+ atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
+ SYSMODCTRL_IECHOADJ_DEF);
+ } else {
+ /* disable pws */
+ atl1c_read_phy_dbg(hw, MIIDBG_LEGCYPS, &phy_data);
+ atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS,
+ phy_data & ~LEGCYPS_EN);
+ /* disable hibernate */
+ atl1c_read_phy_dbg(hw, MIIDBG_HIBNEG, &phy_data);
+ atl1c_write_phy_dbg(hw, MIIDBG_HIBNEG,
+ phy_data & HIBNEG_PSHIB_EN);
+ }
+ /* disable AZ(EEE) by default */
+ if (hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ||
+ hw->nic_type == athr_l2c_b2) {
+ AT_READ_REG(hw, REG_LPI_CTRL, &lpi_ctrl);
+ AT_WRITE_REG(hw, REG_LPI_CTRL, lpi_ctrl & ~LPI_CTRL_EN);
+ atl1c_write_phy_ext(hw, MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, 0);
+ atl1c_write_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL3,
+ L2CB_CLDCTRL3);
+ }
+
+ /* other debug port to set */
+ atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, ANACTRL_DEF);
+ atl1c_write_phy_dbg(hw, MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF);
+ atl1c_write_phy_dbg(hw, MIIDBG_TST10BTCFG, TST10BTCFG_DEF);
+ /* UNH-IOL test issue, set bit7 */
+ atl1c_write_phy_dbg(hw, MIIDBG_TST100BTCFG,
+ TST100BTCFG_DEF | TST100BTCFG_LITCH_EN);
+
+ /* set phy interrupt mask */
+ phy_data = IER_LINK_UP | IER_LINK_DOWN;
+ err = atl1c_write_phy_reg(hw, MII_IER, phy_data);
+ if (err) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Error enable PHY linkChange Interrupt\n");
+ return err;
+ }
+ return 0;
+}
+
+int atl1c_phy_init(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ int ret_val;
+ u16 mii_bmcr_data = BMCR_RESET;
+
+ if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) ||
+ (atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) {
+ dev_err(&pdev->dev, "Error get phy ID\n");
+ return -1;
+ }
+ switch (hw->media_type) {
+ case MEDIA_TYPE_AUTO_SENSOR:
+ ret_val = atl1c_phy_setup_adv(hw);
+ if (ret_val) {
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev,
+ "Error Setting up Auto-Negotiation\n");
+ return ret_val;
+ }
+ mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
+ break;
+ case MEDIA_TYPE_100M_FULL:
+ mii_bmcr_data |= BMCR_SPEED100 | BMCR_FULLDPLX;
+ break;
+ case MEDIA_TYPE_100M_HALF:
+ mii_bmcr_data |= BMCR_SPEED100;
+ break;
+ case MEDIA_TYPE_10M_FULL:
+ mii_bmcr_data |= BMCR_FULLDPLX;
+ break;
+ case MEDIA_TYPE_10M_HALF:
+ break;
+ default:
+ if (netif_msg_link(adapter))
+ dev_err(&pdev->dev, "Wrong Media type %d\n",
+ hw->media_type);
+ return -1;
+ break;
+ }
+
+ ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+ if (ret_val)
+ return ret_val;
+ hw->phy_configured = true;
+
+ return 0;
+}
+
+/*
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ */
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
+{
+ int err;
+ u16 phy_data;
+
+ /* Read PHY Specific Status Register (17) */
+ err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
+ if (err)
+ return err;
+
+ if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
+ return -1;
+
+ switch (phy_data & GIGA_PSSR_SPEED) {
+ case GIGA_PSSR_1000MBS:
+ *speed = SPEED_1000;
+ break;
+ case GIGA_PSSR_100MBS:
+ *speed = SPEED_100;
+ break;
+ case GIGA_PSSR_10MBS:
+ *speed = SPEED_10;
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ if (phy_data & GIGA_PSSR_DPLX)
+ *duplex = FULL_DUPLEX;
+ else
+ *duplex = HALF_DUPLEX;
+
+ return 0;
+}
+
+/* select one link mode to get lower power consumption */
+int atl1c_phy_to_ps_link(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ int ret = 0;
+ u16 autoneg_advertised = ADVERTISED_10baseT_Half;
+ u16 save_autoneg_advertised;
+ u16 phy_data;
+ u16 mii_lpa_data;
+ u16 speed = SPEED_0;
+ u16 duplex = FULL_DUPLEX;
+ int i;
+
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ if (phy_data & BMSR_LSTATUS) {
+ atl1c_read_phy_reg(hw, MII_LPA, &mii_lpa_data);
+ if (mii_lpa_data & LPA_10FULL)
+ autoneg_advertised = ADVERTISED_10baseT_Full;
+ else if (mii_lpa_data & LPA_10HALF)
+ autoneg_advertised = ADVERTISED_10baseT_Half;
+ else if (mii_lpa_data & LPA_100HALF)
+ autoneg_advertised = ADVERTISED_100baseT_Half;
+ else if (mii_lpa_data & LPA_100FULL)
+ autoneg_advertised = ADVERTISED_100baseT_Full;
+
+ save_autoneg_advertised = hw->autoneg_advertised;
+ hw->phy_configured = false;
+ hw->autoneg_advertised = autoneg_advertised;
+ if (atl1c_restart_autoneg(hw) != 0) {
+ dev_dbg(&pdev->dev, "phy autoneg failed\n");
+ ret = -1;
+ }
+ hw->autoneg_advertised = save_autoneg_advertised;
+
+ if (mii_lpa_data) {
+ for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
+ mdelay(100);
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ if (phy_data & BMSR_LSTATUS) {
+ if (atl1c_get_speed_and_duplex(hw, &speed,
+ &duplex) != 0)
+ dev_dbg(&pdev->dev,
+ "get speed and duplex failed\n");
+ break;
+ }
+ }
+ }
+ } else {
+ speed = SPEED_10;
+ duplex = HALF_DUPLEX;
+ }
+ adapter->link_speed = speed;
+ adapter->link_duplex = duplex;
+
+ return ret;
+}
+
+int atl1c_restart_autoneg(struct atl1c_hw *hw)
+{
+ int err = 0;
+ u16 mii_bmcr_data = BMCR_RESET;
+
+ err = atl1c_phy_setup_adv(hw);
+ if (err)
+ return err;
+ mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
+
+ return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
+}
+
+int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc)
+{
+ struct atl1c_adapter *adapter = hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 master_ctrl, mac_ctrl, phy_ctrl;
+ u32 wol_ctrl, speed;
+ u16 phy_data;
+
+ wol_ctrl = 0;
+ speed = adapter->link_speed == SPEED_1000 ?
+ MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100;
+
+ AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl);
+ AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl);
+ AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl);
+
+ master_ctrl &= ~MASTER_CTRL_CLK_SEL_DIS;
+ mac_ctrl = FIELD_SETX(mac_ctrl, MAC_CTRL_SPEED, speed);
+ mac_ctrl &= ~(MAC_CTRL_DUPLX | MAC_CTRL_RX_EN | MAC_CTRL_TX_EN);
+ if (adapter->link_duplex == FULL_DUPLEX)
+ mac_ctrl |= MAC_CTRL_DUPLX;
+ phy_ctrl &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_CLS);
+ phy_ctrl |= GPHY_CTRL_SEL_ANA_RST | GPHY_CTRL_HIB_PULSE |
+ GPHY_CTRL_HIB_EN;
+ if (!wufc) { /* without WoL */
+ master_ctrl |= MASTER_CTRL_CLK_SEL_DIS;
+ phy_ctrl |= GPHY_CTRL_PHY_IDDQ | GPHY_CTRL_PWDOWN_HW;
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+ hw->phy_configured = false; /* re-init PHY when resume */
+ return 0;
+ }
+ phy_ctrl |= GPHY_CTRL_EXT_RESET;
+ if (wufc & AT_WUFC_MAG) {
+ mac_ctrl |= MAC_CTRL_RX_EN | MAC_CTRL_BC_EN;
+ wol_ctrl |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+ if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V11)
+ wol_ctrl |= WOL_PATTERN_EN | WOL_PATTERN_PME_EN;
+ }
+ if (wufc & AT_WUFC_LNKC) {
+ wol_ctrl |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
+ if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
+ dev_dbg(&pdev->dev, "%s: write phy MII_IER failed.\n",
+ atl1c_driver_name);
+ }
+ }
+ /* clear PHY interrupt */
+ atl1c_read_phy_reg(hw, MII_ISR, &phy_data);
+
+ dev_dbg(&pdev->dev, "%s: suspend MAC=%x,MASTER=%x,PHY=0x%x,WOL=%x\n",
+ atl1c_driver_name, mac_ctrl, master_ctrl, phy_ctrl, wol_ctrl);
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
+ AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
+ AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl);
+
+ return 0;
+}
+
+
+/* configure phy after Link change Event */
+void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed)
+{
+ u16 phy_val;
+ bool adj_thresh = false;
+
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2 ||
+ hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2)
+ adj_thresh = true;
+
+ if (link_speed != SPEED_0) { /* link up */
+ /* az with brcm, half-amp */
+ if (hw->nic_type == athr_l1d_2) {
+ atl1c_read_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL6,
+ &phy_val);
+ phy_val = FIELD_GETX(phy_val, CLDCTRL6_CAB_LEN);
+ phy_val = phy_val > CLDCTRL6_CAB_LEN_SHORT ?
+ AZ_ANADECT_LONG : AZ_ANADECT_DEF;
+ atl1c_write_phy_dbg(hw, MIIDBG_AZ_ANADECT, phy_val);
+ }
+ /* threshold adjust */
+ if (adj_thresh && link_speed == SPEED_100 && hw->msi_lnkpatch) {
+ atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB, L1D_MSE16DB_UP);
+ atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
+ L1D_SYSMODCTRL_IECHOADJ_DEF);
+ }
+ } else { /* link down */
+ if (adj_thresh && hw->msi_lnkpatch) {
+ atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
+ SYSMODCTRL_IECHOADJ_DEF);
+ atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB,
+ L1D_MSE16DB_DOWN);
+ }
+ }
+}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
new file mode 100644
index 00000000000..21d8c4dbdbe
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h
@@ -0,0 +1,1024 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ATL1C_HW_H_
+#define _ATL1C_HW_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+
+#define FIELD_GETX(_x, _name) ((_x) >> (_name##_SHIFT) & (_name##_MASK))
+#define FIELD_SETX(_x, _name, _v) \
+(((_x) & ~((_name##_MASK) << (_name##_SHIFT))) |\
+(((_v) & (_name##_MASK)) << (_name##_SHIFT)))
+#define FIELDX(_name, _v) (((_v) & (_name##_MASK)) << (_name##_SHIFT))
+
+struct atl1c_adapter;
+struct atl1c_hw;
+
+/* function prototype */
+void atl1c_phy_disable(struct atl1c_hw *hw);
+void atl1c_hw_set_mac_addr(struct atl1c_hw *hw, u8 *mac_addr);
+int atl1c_phy_reset(struct atl1c_hw *hw);
+int atl1c_read_mac_addr(struct atl1c_hw *hw);
+int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex);
+u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr);
+void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value);
+int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data);
+int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data);
+bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value);
+int atl1c_phy_init(struct atl1c_hw *hw);
+int atl1c_check_eeprom_exist(struct atl1c_hw *hw);
+int atl1c_restart_autoneg(struct atl1c_hw *hw);
+int atl1c_phy_to_ps_link(struct atl1c_hw *hw);
+int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc);
+bool atl1c_wait_mdio_idle(struct atl1c_hw *hw);
+void atl1c_stop_phy_polling(struct atl1c_hw *hw);
+void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel);
+int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 *phy_data);
+int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
+ u16 reg, u16 phy_data);
+int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
+ u16 reg_addr, u16 *phy_data);
+int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
+ u16 reg_addr, u16 phy_data);
+int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data);
+int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data);
+void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed);
+
+/* hw-ids */
+#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062
+#define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063
+#define PCI_DEVICE_ID_ATHEROS_L2C_B 0x2060 /* AR8152 v1.1 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L2C_B2 0x2062 /* AR8152 v2.0 Fast 10/100 */
+#define PCI_DEVICE_ID_ATHEROS_L1D 0x1073 /* AR8151 v1.0 Gigabit 1000 */
+#define PCI_DEVICE_ID_ATHEROS_L1D_2_0 0x1083 /* AR8151 v2.0 Gigabit 1000 */
+#define L2CB_V10 0xc0
+#define L2CB_V11 0xc1
+#define L2CB_V20 0xc0
+#define L2CB_V21 0xc1
+
+/* register definition */
+#define REG_DEVICE_CAP 0x5C
+#define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7
+#define DEVICE_CAP_MAX_PAYLOAD_SHIFT 0
+
+#define DEVICE_CTRL_MAXRRS_MIN 2
+
+#define REG_LINK_CTRL 0x68
+#define LINK_CTRL_L0S_EN 0x01
+#define LINK_CTRL_L1_EN 0x02
+#define LINK_CTRL_EXT_SYNC 0x80
+
+#define REG_PCIE_IND_ACC_ADDR 0x80
+#define REG_PCIE_IND_ACC_DATA 0x84
+
+#define REG_DEV_SERIALNUM_CTRL 0x200
+#define REG_DEV_MAC_SEL_MASK 0x0 /* 0:EUI; 1:MAC */
+#define REG_DEV_MAC_SEL_SHIFT 0
+#define REG_DEV_SERIAL_NUM_EN_MASK 0x1
+#define REG_DEV_SERIAL_NUM_EN_SHIFT 1
+
+#define REG_TWSI_CTRL 0x218
+#define TWSI_CTLR_FREQ_MASK 0x3UL
+#define TWSI_CTRL_FREQ_SHIFT 24
+#define TWSI_CTRL_FREQ_100K 0
+#define TWSI_CTRL_FREQ_200K 1
+#define TWSI_CTRL_FREQ_300K 2
+#define TWSI_CTRL_FREQ_400K 3
+#define TWSI_CTRL_LD_EXIST BIT(23)
+#define TWSI_CTRL_HW_LDSTAT BIT(12) /* 0:finish,1:in progress */
+#define TWSI_CTRL_SW_LDSTART BIT(11)
+#define TWSI_CTRL_LD_OFFSET_MASK 0xFF
+#define TWSI_CTRL_LD_OFFSET_SHIFT 0
+
+#define REG_PCIE_DEV_MISC_CTRL 0x21C
+#define PCIE_DEV_MISC_EXT_PIPE 0x2
+#define PCIE_DEV_MISC_RETRY_BUFDIS 0x1
+#define PCIE_DEV_MISC_SPIROM_EXIST 0x4
+#define PCIE_DEV_MISC_SERDES_ENDIAN 0x8
+#define PCIE_DEV_MISC_SERDES_SEL_DIN 0x10
+
+#define REG_PCIE_PHYMISC 0x1000
+#define PCIE_PHYMISC_FORCE_RCV_DET BIT(2)
+#define PCIE_PHYMISC_NFTS_MASK 0xFFUL
+#define PCIE_PHYMISC_NFTS_SHIFT 16
+
+#define REG_PCIE_PHYMISC2 0x1004
+#define PCIE_PHYMISC2_L0S_TH_MASK 0x3UL
+#define PCIE_PHYMISC2_L0S_TH_SHIFT 18
+#define L2CB1_PCIE_PHYMISC2_L0S_TH 3
+#define PCIE_PHYMISC2_CDR_BW_MASK 0x3UL
+#define PCIE_PHYMISC2_CDR_BW_SHIFT 16
+#define L2CB1_PCIE_PHYMISC2_CDR_BW 3
+
+#define REG_TWSI_DEBUG 0x1108
+#define TWSI_DEBUG_DEV_EXIST BIT(29)
+
+#define REG_DMA_DBG 0x1114
+#define DMA_DBG_VENDOR_MSG BIT(0)
+
+#define REG_EEPROM_CTRL 0x12C0
+#define EEPROM_CTRL_DATA_HI_MASK 0xFFFF
+#define EEPROM_CTRL_DATA_HI_SHIFT 0
+#define EEPROM_CTRL_ADDR_MASK 0x3FF
+#define EEPROM_CTRL_ADDR_SHIFT 16
+#define EEPROM_CTRL_ACK 0x40000000
+#define EEPROM_CTRL_RW 0x80000000
+
+#define REG_EEPROM_DATA_LO 0x12C4
+
+#define REG_OTP_CTRL 0x12F0
+#define OTP_CTRL_CLK_EN BIT(1)
+
+#define REG_PM_CTRL 0x12F8
+#define PM_CTRL_HOTRST BIT(31)
+#define PM_CTRL_MAC_ASPM_CHK BIT(30) /* L0s/L1 dis by MAC based on
+ * thrghput(setting in 15A0) */
+#define PM_CTRL_SA_DLY_EN BIT(29)
+#define PM_CTRL_L0S_BUFSRX_EN BIT(28)
+#define PM_CTRL_LCKDET_TIMER_MASK 0xFUL
+#define PM_CTRL_LCKDET_TIMER_SHIFT 24
+#define PM_CTRL_LCKDET_TIMER_DEF 0xC
+#define PM_CTRL_PM_REQ_TIMER_MASK 0xFUL
+#define PM_CTRL_PM_REQ_TIMER_SHIFT 20 /* pm_request_l1 time > @
+ * ->L0s not L1 */
+#define PM_CTRL_PM_REQ_TO_DEF 0xF
+#define PMCTRL_TXL1_AFTER_L0S BIT(19) /* l1dv2.0+ */
+#define L1D_PMCTRL_L1_ENTRY_TM_MASK 7UL /* l1dv2.0+, 3bits */
+#define L1D_PMCTRL_L1_ENTRY_TM_SHIFT 16
+#define L1D_PMCTRL_L1_ENTRY_TM_DIS 0
+#define L1D_PMCTRL_L1_ENTRY_TM_2US 1
+#define L1D_PMCTRL_L1_ENTRY_TM_4US 2
+#define L1D_PMCTRL_L1_ENTRY_TM_8US 3
+#define L1D_PMCTRL_L1_ENTRY_TM_16US 4
+#define L1D_PMCTRL_L1_ENTRY_TM_24US 5
+#define L1D_PMCTRL_L1_ENTRY_TM_32US 6
+#define L1D_PMCTRL_L1_ENTRY_TM_63US 7
+#define PM_CTRL_L1_ENTRY_TIMER_MASK 0xFUL /* l1C 4bits */
+#define PM_CTRL_L1_ENTRY_TIMER_SHIFT 16
+#define L2CB1_PM_CTRL_L1_ENTRY_TM 7
+#define L1C_PM_CTRL_L1_ENTRY_TM 0xF
+#define PM_CTRL_RCVR_WT_TIMER BIT(15) /* 1:1us, 0:2ms */
+#define PM_CTRL_CLK_PWM_VER1_1 BIT(14) /* 0:1.0a,1:1.1 */
+#define PM_CTRL_CLK_SWH_L1 BIT(13) /* en pcie clk sw in L1 */
+#define PM_CTRL_ASPM_L0S_EN BIT(12)
+#define PM_CTRL_RXL1_AFTER_L0S BIT(11) /* l1dv2.0+ */
+#define L1D_PMCTRL_L0S_TIMER_MASK 7UL /* l1d2.0+, 3bits*/
+#define L1D_PMCTRL_L0S_TIMER_SHIFT 8
+#define PM_CTRL_L0S_ENTRY_TIMER_MASK 0xFUL /* l1c, 4bits */
+#define PM_CTRL_L0S_ENTRY_TIMER_SHIFT 8
+#define PM_CTRL_SERDES_BUFS_RX_L1_EN BIT(7)
+#define PM_CTRL_SERDES_PD_EX_L1 BIT(6) /* power down serdes rx */
+#define PM_CTRL_SERDES_PLL_L1_EN BIT(5)
+#define PM_CTRL_SERDES_L1_EN BIT(4)
+#define PM_CTRL_ASPM_L1_EN BIT(3)
+#define PM_CTRL_CLK_REQ_EN BIT(2)
+#define PM_CTRL_RBER_EN BIT(1)
+#define PM_CTRL_SPRSDWER_EN BIT(0)
+
+#define REG_LTSSM_ID_CTRL 0x12FC
+#define LTSSM_ID_EN_WRO 0x1000
+
+
+/* Selene Master Control Register */
+#define REG_MASTER_CTRL 0x1400
+#define MASTER_CTRL_OTP_SEL BIT(31)
+#define MASTER_DEV_NUM_MASK 0x7FUL
+#define MASTER_DEV_NUM_SHIFT 24
+#define MASTER_REV_NUM_MASK 0xFFUL
+#define MASTER_REV_NUM_SHIFT 16
+#define MASTER_CTRL_INT_RDCLR BIT(14)
+#define MASTER_CTRL_CLK_SEL_DIS BIT(12) /* 1:alwys sel pclk from
+ * serdes, not sw to 25M */
+#define MASTER_CTRL_RX_ITIMER_EN BIT(11) /* IRQ MODURATION FOR RX */
+#define MASTER_CTRL_TX_ITIMER_EN BIT(10) /* MODURATION FOR TX/RX */
+#define MASTER_CTRL_MANU_INT BIT(9) /* SOFT MANUAL INT */
+#define MASTER_CTRL_MANUTIMER_EN BIT(8)
+#define MASTER_CTRL_SA_TIMER_EN BIT(7) /* SYS ALIVE TIMER EN */
+#define MASTER_CTRL_OOB_DIS BIT(6) /* OUT OF BOX DIS */
+#define MASTER_CTRL_WAKEN_25M BIT(5) /* WAKE WO. PCIE CLK */
+#define MASTER_CTRL_BERT_START BIT(4)
+#define MASTER_PCIE_TSTMOD_MASK 3UL
+#define MASTER_PCIE_TSTMOD_SHIFT 2
+#define MASTER_PCIE_RST BIT(1)
+#define MASTER_CTRL_SOFT_RST BIT(0) /* RST MAC & DMA */
+#define DMA_MAC_RST_TO 50
+
+/* Timer Initial Value Register */
+#define REG_MANUAL_TIMER_INIT 0x1404
+
+/* IRQ ModeratorTimer Initial Value Register */
+#define REG_IRQ_MODRT_TIMER_INIT 0x1408
+#define IRQ_MODRT_TIMER_MASK 0xffff
+#define IRQ_MODRT_TX_TIMER_SHIFT 0
+#define IRQ_MODRT_RX_TIMER_SHIFT 16
+
+#define REG_GPHY_CTRL 0x140C
+#define GPHY_CTRL_ADDR_MASK 0x1FUL
+#define GPHY_CTRL_ADDR_SHIFT 19
+#define GPHY_CTRL_BP_VLTGSW BIT(18)
+#define GPHY_CTRL_100AB_EN BIT(17)
+#define GPHY_CTRL_10AB_EN BIT(16)
+#define GPHY_CTRL_PHY_PLL_BYPASS BIT(15)
+#define GPHY_CTRL_PWDOWN_HW BIT(14) /* affect MAC&PHY, to low pw */
+#define GPHY_CTRL_PHY_PLL_ON BIT(13) /* 1:pll always on, 0:can sw */
+#define GPHY_CTRL_SEL_ANA_RST BIT(12)
+#define GPHY_CTRL_HIB_PULSE BIT(11)
+#define GPHY_CTRL_HIB_EN BIT(10)
+#define GPHY_CTRL_GIGA_DIS BIT(9)
+#define GPHY_CTRL_PHY_IDDQ_DIS BIT(8) /* pw on RST */
+#define GPHY_CTRL_PHY_IDDQ BIT(7) /* bit8 affect bit7 while rb */
+#define GPHY_CTRL_LPW_EXIT BIT(6)
+#define GPHY_CTRL_GATE_25M_EN BIT(5)
+#define GPHY_CTRL_REV_ANEG BIT(4)
+#define GPHY_CTRL_ANEG_NOW BIT(3)
+#define GPHY_CTRL_LED_MODE BIT(2)
+#define GPHY_CTRL_RTL_MODE BIT(1)
+#define GPHY_CTRL_EXT_RESET BIT(0) /* 1:out of DSP RST status */
+#define GPHY_CTRL_EXT_RST_TO 80 /* 800us atmost */
+#define GPHY_CTRL_CLS (\
+ GPHY_CTRL_LED_MODE |\
+ GPHY_CTRL_100AB_EN |\
+ GPHY_CTRL_PHY_PLL_ON)
+
+/* Block IDLE Status Register */
+#define REG_IDLE_STATUS 0x1410
+#define IDLE_STATUS_SFORCE_MASK 0xFUL
+#define IDLE_STATUS_SFORCE_SHIFT 14
+#define IDLE_STATUS_CALIB_DONE BIT(13)
+#define IDLE_STATUS_CALIB_RES_MASK 0x1FUL
+#define IDLE_STATUS_CALIB_RES_SHIFT 8
+#define IDLE_STATUS_CALIBERR_MASK 0xFUL
+#define IDLE_STATUS_CALIBERR_SHIFT 4
+#define IDLE_STATUS_TXQ_BUSY BIT(3)
+#define IDLE_STATUS_RXQ_BUSY BIT(2)
+#define IDLE_STATUS_TXMAC_BUSY BIT(1)
+#define IDLE_STATUS_RXMAC_BUSY BIT(0)
+#define IDLE_STATUS_MASK (\
+ IDLE_STATUS_TXQ_BUSY |\
+ IDLE_STATUS_RXQ_BUSY |\
+ IDLE_STATUS_TXMAC_BUSY |\
+ IDLE_STATUS_RXMAC_BUSY)
+
+/* MDIO Control Register */
+#define REG_MDIO_CTRL 0x1414
+#define MDIO_CTRL_MODE_EXT BIT(30)
+#define MDIO_CTRL_POST_READ BIT(29)
+#define MDIO_CTRL_AP_EN BIT(28)
+#define MDIO_CTRL_BUSY BIT(27)
+#define MDIO_CTRL_CLK_SEL_MASK 0x7UL
+#define MDIO_CTRL_CLK_SEL_SHIFT 24
+#define MDIO_CTRL_CLK_25_4 0 /* 25MHz divide 4 */
+#define MDIO_CTRL_CLK_25_6 2
+#define MDIO_CTRL_CLK_25_8 3
+#define MDIO_CTRL_CLK_25_10 4
+#define MDIO_CTRL_CLK_25_32 5
+#define MDIO_CTRL_CLK_25_64 6
+#define MDIO_CTRL_CLK_25_128 7
+#define MDIO_CTRL_START BIT(23)
+#define MDIO_CTRL_SPRES_PRMBL BIT(22)
+#define MDIO_CTRL_OP_READ BIT(21) /* 1:read, 0:write */
+#define MDIO_CTRL_REG_MASK 0x1FUL
+#define MDIO_CTRL_REG_SHIFT 16
+#define MDIO_CTRL_DATA_MASK 0xFFFFUL
+#define MDIO_CTRL_DATA_SHIFT 0
+#define MDIO_MAX_AC_TO 120 /* 1.2ms timeout for slow clk */
+
+/* for extension reg access */
+#define REG_MDIO_EXTN 0x1448
+#define MDIO_EXTN_PORTAD_MASK 0x1FUL
+#define MDIO_EXTN_PORTAD_SHIFT 21
+#define MDIO_EXTN_DEVAD_MASK 0x1FUL
+#define MDIO_EXTN_DEVAD_SHIFT 16
+#define MDIO_EXTN_REG_MASK 0xFFFFUL
+#define MDIO_EXTN_REG_SHIFT 0
+
+/* BIST Control and Status Register0 (for the Packet Memory) */
+#define REG_BIST0_CTRL 0x141c
+#define BIST0_NOW 0x1
+#define BIST0_SRAM_FAIL 0x2 /* 1: The SRAM failure is
+ * un-repairable because
+ * it has address decoder
+ * failure or more than 1 cell
+ * stuck-to-x failure */
+#define BIST0_FUSE_FLAG 0x4
+
+/* BIST Control and Status Register1(for the retry buffer of PCI Express) */
+#define REG_BIST1_CTRL 0x1420
+#define BIST1_NOW 0x1
+#define BIST1_SRAM_FAIL 0x2
+#define BIST1_FUSE_FLAG 0x4
+
+/* SerDes Lock Detect Control and Status Register */
+#define REG_SERDES 0x1424
+#define SERDES_PHY_CLK_SLOWDOWN BIT(18)
+#define SERDES_MAC_CLK_SLOWDOWN BIT(17)
+#define SERDES_SELFB_PLL_MASK 0x3UL
+#define SERDES_SELFB_PLL_SHIFT 14
+#define SERDES_PHYCLK_SEL_GTX BIT(13) /* 1:gtx_clk, 0:25M */
+#define SERDES_PCIECLK_SEL_SRDS BIT(12) /* 1:serdes,0:25M */
+#define SERDES_BUFS_RX_EN BIT(11)
+#define SERDES_PD_RX BIT(10)
+#define SERDES_PLL_EN BIT(9)
+#define SERDES_EN BIT(8)
+#define SERDES_SELFB_PLL_SEL_CSR BIT(6) /* 0:state-machine,1:csr */
+#define SERDES_SELFB_PLL_CSR_MASK 0x3UL
+#define SERDES_SELFB_PLL_CSR_SHIFT 4
+#define SERDES_SELFB_PLL_CSR_4 3 /* 4-12% OV-CLK */
+#define SERDES_SELFB_PLL_CSR_0 2 /* 0-4% OV-CLK */
+#define SERDES_SELFB_PLL_CSR_12 1 /* 12-18% OV-CLK */
+#define SERDES_SELFB_PLL_CSR_18 0 /* 18-25% OV-CLK */
+#define SERDES_VCO_SLOW BIT(3)
+#define SERDES_VCO_FAST BIT(2)
+#define SERDES_LOCK_DETECT_EN BIT(1)
+#define SERDES_LOCK_DETECT BIT(0)
+
+#define REG_LPI_DECISN_TIMER 0x143C
+#define L2CB_LPI_DESISN_TIMER 0x7D00
+
+#define REG_LPI_CTRL 0x1440
+#define LPI_CTRL_CHK_DA BIT(31)
+#define LPI_CTRL_ENH_TO_MASK 0x1FFFUL
+#define LPI_CTRL_ENH_TO_SHIFT 12
+#define LPI_CTRL_ENH_TH_MASK 0x1FUL
+#define LPI_CTRL_ENH_TH_SHIFT 6
+#define LPI_CTRL_ENH_EN BIT(5)
+#define LPI_CTRL_CHK_RX BIT(4)
+#define LPI_CTRL_CHK_STATE BIT(3)
+#define LPI_CTRL_GMII BIT(2)
+#define LPI_CTRL_TO_PHY BIT(1)
+#define LPI_CTRL_EN BIT(0)
+
+#define REG_LPI_WAIT 0x1444
+#define LPI_WAIT_TIMER_MASK 0xFFFFUL
+#define LPI_WAIT_TIMER_SHIFT 0
+
+/* MAC Control Register */
+#define REG_MAC_CTRL 0x1480
+#define MAC_CTRL_SPEED_MODE_SW BIT(30) /* 0:phy,1:sw */
+#define MAC_CTRL_HASH_ALG_CRC32 BIT(29) /* 1:legacy,0:lw_5b */
+#define MAC_CTRL_SINGLE_PAUSE_EN BIT(28)
+#define MAC_CTRL_DBG BIT(27)
+#define MAC_CTRL_BC_EN BIT(26)
+#define MAC_CTRL_MC_ALL_EN BIT(25)
+#define MAC_CTRL_RX_CHKSUM_EN BIT(24)
+#define MAC_CTRL_TX_HUGE BIT(23)
+#define MAC_CTRL_DBG_TX_BKPRESURE BIT(22)
+#define MAC_CTRL_SPEED_MASK 3UL
+#define MAC_CTRL_SPEED_SHIFT 20
+#define MAC_CTRL_SPEED_10_100 1
+#define MAC_CTRL_SPEED_1000 2
+#define MAC_CTRL_TX_SIMURST BIT(19)
+#define MAC_CTRL_SCNT BIT(17)
+#define MAC_CTRL_TX_PAUSE BIT(16)
+#define MAC_CTRL_PROMIS_EN BIT(15)
+#define MAC_CTRL_RMV_VLAN BIT(14)
+#define MAC_CTRL_PRMLEN_MASK 0xFUL
+#define MAC_CTRL_PRMLEN_SHIFT 10
+#define MAC_CTRL_HUGE_EN BIT(9)
+#define MAC_CTRL_LENCHK BIT(8)
+#define MAC_CTRL_PAD BIT(7)
+#define MAC_CTRL_ADD_CRC BIT(6)
+#define MAC_CTRL_DUPLX BIT(5)
+#define MAC_CTRL_LOOPBACK BIT(4)
+#define MAC_CTRL_RX_FLOW BIT(3)
+#define MAC_CTRL_TX_FLOW BIT(2)
+#define MAC_CTRL_RX_EN BIT(1)
+#define MAC_CTRL_TX_EN BIT(0)
+
+/* MAC IPG/IFG Control Register */
+#define REG_MAC_IPG_IFG 0x1484
+#define MAC_IPG_IFG_IPGT_SHIFT 0 /* Desired back to back
+ * inter-packet gap. The
+ * default is 96-bit time */
+#define MAC_IPG_IFG_IPGT_MASK 0x7f
+#define MAC_IPG_IFG_MIFG_SHIFT 8 /* Minimum number of IFG to
+ * enforce in between RX frames */
+#define MAC_IPG_IFG_MIFG_MASK 0xff /* Frame gap below such IFP is dropped */
+#define MAC_IPG_IFG_IPGR1_SHIFT 16 /* 64bit Carrier-Sense window */
+#define MAC_IPG_IFG_IPGR1_MASK 0x7f
+#define MAC_IPG_IFG_IPGR2_SHIFT 24 /* 96-bit IPG window */
+#define MAC_IPG_IFG_IPGR2_MASK 0x7f
+
+/* MAC STATION ADDRESS */
+#define REG_MAC_STA_ADDR 0x1488
+
+/* Hash table for multicast address */
+#define REG_RX_HASH_TABLE 0x1490
+
+/* MAC Half-Duplex Control Register */
+#define REG_MAC_HALF_DUPLX_CTRL 0x1498
+#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 /* Collision Window */
+#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff
+#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12
+#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf
+#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000
+#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 /* No back-off on backpressure,
+ * immediately start the
+ * transmission after back pressure */
+#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 /* Maximum binary exponential number */
+#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 /* IPG to start JAM for collision based flow control in half-duplex */
+#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf /* mode. In unit of 8-bit time */
+
+/* Maximum Frame Length Control Register */
+#define REG_MTU 0x149c
+
+/* Wake-On-Lan control register */
+#define REG_WOL_CTRL 0x14a0
+#define WOL_PT7_MATCH BIT(31)
+#define WOL_PT6_MATCH BIT(30)
+#define WOL_PT5_MATCH BIT(29)
+#define WOL_PT4_MATCH BIT(28)
+#define WOL_PT3_MATCH BIT(27)
+#define WOL_PT2_MATCH BIT(26)
+#define WOL_PT1_MATCH BIT(25)
+#define WOL_PT0_MATCH BIT(24)
+#define WOL_PT7_EN BIT(23)
+#define WOL_PT6_EN BIT(22)
+#define WOL_PT5_EN BIT(21)
+#define WOL_PT4_EN BIT(20)
+#define WOL_PT3_EN BIT(19)
+#define WOL_PT2_EN BIT(18)
+#define WOL_PT1_EN BIT(17)
+#define WOL_PT0_EN BIT(16)
+#define WOL_LNKCHG_ST BIT(10)
+#define WOL_MAGIC_ST BIT(9)
+#define WOL_PATTERN_ST BIT(8)
+#define WOL_OOB_EN BIT(6)
+#define WOL_LINK_CHG_PME_EN BIT(5)
+#define WOL_LINK_CHG_EN BIT(4)
+#define WOL_MAGIC_PME_EN BIT(3)
+#define WOL_MAGIC_EN BIT(2)
+#define WOL_PATTERN_PME_EN BIT(1)
+#define WOL_PATTERN_EN BIT(0)
+
+/* WOL Length ( 2 DWORD ) */
+#define REG_WOL_PTLEN1 0x14A4
+#define WOL_PTLEN1_3_MASK 0xFFUL
+#define WOL_PTLEN1_3_SHIFT 24
+#define WOL_PTLEN1_2_MASK 0xFFUL
+#define WOL_PTLEN1_2_SHIFT 16
+#define WOL_PTLEN1_1_MASK 0xFFUL
+#define WOL_PTLEN1_1_SHIFT 8
+#define WOL_PTLEN1_0_MASK 0xFFUL
+#define WOL_PTLEN1_0_SHIFT 0
+
+#define REG_WOL_PTLEN2 0x14A8
+#define WOL_PTLEN2_7_MASK 0xFFUL
+#define WOL_PTLEN2_7_SHIFT 24
+#define WOL_PTLEN2_6_MASK 0xFFUL
+#define WOL_PTLEN2_6_SHIFT 16
+#define WOL_PTLEN2_5_MASK 0xFFUL
+#define WOL_PTLEN2_5_SHIFT 8
+#define WOL_PTLEN2_4_MASK 0xFFUL
+#define WOL_PTLEN2_4_SHIFT 0
+
+/* Internal SRAM Partition Register */
+#define RFDX_HEAD_ADDR_MASK 0x03FF
+#define RFDX_HARD_ADDR_SHIFT 0
+#define RFDX_TAIL_ADDR_MASK 0x03FF
+#define RFDX_TAIL_ADDR_SHIFT 16
+
+#define REG_SRAM_RFD0_INFO 0x1500
+#define REG_SRAM_RFD1_INFO 0x1504
+#define REG_SRAM_RFD2_INFO 0x1508
+#define REG_SRAM_RFD3_INFO 0x150C
+
+#define REG_RFD_NIC_LEN 0x1510 /* In 8-bytes */
+#define RFD_NIC_LEN_MASK 0x03FF
+
+#define REG_SRAM_TRD_ADDR 0x1518
+#define TPD_HEAD_ADDR_MASK 0x03FF
+#define TPD_HEAD_ADDR_SHIFT 0
+#define TPD_TAIL_ADDR_MASK 0x03FF
+#define TPD_TAIL_ADDR_SHIFT 16
+
+#define REG_SRAM_TRD_LEN 0x151C /* In 8-bytes */
+#define TPD_NIC_LEN_MASK 0x03FF
+
+#define REG_SRAM_RXF_ADDR 0x1520
+#define REG_SRAM_RXF_LEN 0x1524
+#define REG_SRAM_TXF_ADDR 0x1528
+#define REG_SRAM_TXF_LEN 0x152C
+#define REG_SRAM_TCPH_ADDR 0x1530
+#define REG_SRAM_PKTH_ADDR 0x1532
+
+/*
+ * Load Ptr Register
+ * Software sets this bit after the initialization of the head and tail */
+#define REG_LOAD_PTR 0x1534
+
+/*
+ * addresses of all descriptors, as well as the following descriptor
+ * control register, which triggers each function block to load the head
+ * pointer to prepare for the operation. This bit is then self-cleared
+ * after one cycle.
+ */
+#define REG_RX_BASE_ADDR_HI 0x1540
+#define REG_TX_BASE_ADDR_HI 0x1544
+#define REG_RFD0_HEAD_ADDR_LO 0x1550
+#define REG_RFD_RING_SIZE 0x1560
+#define RFD_RING_SIZE_MASK 0x0FFF
+#define REG_RX_BUF_SIZE 0x1564
+#define RX_BUF_SIZE_MASK 0xFFFF
+#define REG_RRD0_HEAD_ADDR_LO 0x1568
+#define REG_RRD_RING_SIZE 0x1578
+#define RRD_RING_SIZE_MASK 0x0FFF
+#define REG_TPD_PRI1_ADDR_LO 0x157C
+#define REG_TPD_PRI0_ADDR_LO 0x1580
+#define REG_TPD_RING_SIZE 0x1584
+#define TPD_RING_SIZE_MASK 0xFFFF
+
+/* TXQ Control Register */
+#define REG_TXQ_CTRL 0x1590
+#define TXQ_TXF_BURST_NUM_MASK 0xFFFFUL
+#define TXQ_TXF_BURST_NUM_SHIFT 16
+#define L1C_TXQ_TXF_BURST_PREF 0x200
+#define L2CB_TXQ_TXF_BURST_PREF 0x40
+#define TXQ_CTRL_PEDING_CLR BIT(8)
+#define TXQ_CTRL_LS_8023_EN BIT(7)
+#define TXQ_CTRL_ENH_MODE BIT(6)
+#define TXQ_CTRL_EN BIT(5)
+#define TXQ_CTRL_IP_OPTION_EN BIT(4)
+#define TXQ_NUM_TPD_BURST_MASK 0xFUL
+#define TXQ_NUM_TPD_BURST_SHIFT 0
+#define TXQ_NUM_TPD_BURST_DEF 5
+#define TXQ_CFGV (\
+ FIELDX(TXQ_NUM_TPD_BURST, TXQ_NUM_TPD_BURST_DEF) |\
+ TXQ_CTRL_ENH_MODE |\
+ TXQ_CTRL_LS_8023_EN |\
+ TXQ_CTRL_IP_OPTION_EN)
+#define L1C_TXQ_CFGV (\
+ TXQ_CFGV |\
+ FIELDX(TXQ_TXF_BURST_NUM, L1C_TXQ_TXF_BURST_PREF))
+#define L2CB_TXQ_CFGV (\
+ TXQ_CFGV |\
+ FIELDX(TXQ_TXF_BURST_NUM, L2CB_TXQ_TXF_BURST_PREF))
+
+
+/* Jumbo packet Threshold for task offload */
+#define REG_TX_TSO_OFFLOAD_THRESH 0x1594 /* In 8-bytes */
+#define TX_TSO_OFFLOAD_THRESH_MASK 0x07FF
+#define MAX_TSO_FRAME_SIZE (7*1024)
+
+#define REG_TXF_WATER_MARK 0x1598 /* In 8-bytes */
+#define TXF_WATER_MARK_MASK 0x0FFF
+#define TXF_LOW_WATER_MARK_SHIFT 0
+#define TXF_HIGH_WATER_MARK_SHIFT 16
+#define TXQ_CTRL_BURST_MODE_EN 0x80000000
+
+#define REG_THRUPUT_MON_CTRL 0x159C
+#define THRUPUT_MON_RATE_MASK 0x3
+#define THRUPUT_MON_RATE_SHIFT 0
+#define THRUPUT_MON_EN 0x80
+
+/* RXQ Control Register */
+#define REG_RXQ_CTRL 0x15A0
+#define ASPM_THRUPUT_LIMIT_MASK 0x3
+#define ASPM_THRUPUT_LIMIT_SHIFT 0
+#define ASPM_THRUPUT_LIMIT_NO 0x00
+#define ASPM_THRUPUT_LIMIT_1M 0x01
+#define ASPM_THRUPUT_LIMIT_10M 0x02
+#define ASPM_THRUPUT_LIMIT_100M 0x03
+#define IPV6_CHKSUM_CTRL_EN BIT(7)
+#define RXQ_RFD_BURST_NUM_MASK 0x003F
+#define RXQ_RFD_BURST_NUM_SHIFT 20
+#define RXQ_NUM_RFD_PREF_DEF 8
+#define RSS_MODE_MASK 3UL
+#define RSS_MODE_SHIFT 26
+#define RSS_MODE_DIS 0
+#define RSS_MODE_SQSI 1
+#define RSS_MODE_MQSI 2
+#define RSS_MODE_MQMI 3
+#define RSS_NIP_QUEUE_SEL BIT(28) /* 0:q0, 1:table */
+#define RRS_HASH_CTRL_EN BIT(29)
+#define RX_CUT_THRU_EN BIT(30)
+#define RXQ_CTRL_EN BIT(31)
+
+#define REG_RFD_FREE_THRESH 0x15A4
+#define RFD_FREE_THRESH_MASK 0x003F
+#define RFD_FREE_HI_THRESH_SHIFT 0
+#define RFD_FREE_LO_THRESH_SHIFT 6
+
+/* RXF flow control register */
+#define REG_RXQ_RXF_PAUSE_THRESH 0x15A8
+#define RXQ_RXF_PAUSE_TH_HI_SHIFT 0
+#define RXQ_RXF_PAUSE_TH_HI_MASK 0x0FFF
+#define RXQ_RXF_PAUSE_TH_LO_SHIFT 16
+#define RXQ_RXF_PAUSE_TH_LO_MASK 0x0FFF
+
+#define REG_RXD_DMA_CTRL 0x15AC
+#define RXD_DMA_THRESH_MASK 0x0FFF /* In 8-bytes */
+#define RXD_DMA_THRESH_SHIFT 0
+#define RXD_DMA_DOWN_TIMER_MASK 0xFFFF
+#define RXD_DMA_DOWN_TIMER_SHIFT 16
+
+/* DMA Engine Control Register */
+#define REG_DMA_CTRL 0x15C0
+#define DMA_CTRL_SMB_NOW BIT(31)
+#define DMA_CTRL_WPEND_CLR BIT(30)
+#define DMA_CTRL_RPEND_CLR BIT(29)
+#define DMA_CTRL_WDLY_CNT_MASK 0xFUL
+#define DMA_CTRL_WDLY_CNT_SHIFT 16
+#define DMA_CTRL_WDLY_CNT_DEF 4
+#define DMA_CTRL_RDLY_CNT_MASK 0x1FUL
+#define DMA_CTRL_RDLY_CNT_SHIFT 11
+#define DMA_CTRL_RDLY_CNT_DEF 15
+#define DMA_CTRL_RREQ_PRI_DATA BIT(10) /* 0:tpd, 1:data */
+#define DMA_CTRL_WREQ_BLEN_MASK 7UL
+#define DMA_CTRL_WREQ_BLEN_SHIFT 7
+#define DMA_CTRL_RREQ_BLEN_MASK 7UL
+#define DMA_CTRL_RREQ_BLEN_SHIFT 4
+#define L1C_CTRL_DMA_RCB_LEN128 BIT(3) /* 0:64bytes,1:128bytes */
+#define DMA_CTRL_RORDER_MODE_MASK 7UL
+#define DMA_CTRL_RORDER_MODE_SHIFT 0
+#define DMA_CTRL_RORDER_MODE_OUT 4
+#define DMA_CTRL_RORDER_MODE_ENHANCE 2
+#define DMA_CTRL_RORDER_MODE_IN 1
+
+/* INT-triggle/SMB Control Register */
+#define REG_SMB_STAT_TIMER 0x15C4 /* 2us resolution */
+#define SMB_STAT_TIMER_MASK 0xFFFFFF
+#define REG_TINT_TPD_THRESH 0x15C8 /* tpd th to trig intrrupt */
+
+/* Mail box */
+#define MB_RFDX_PROD_IDX_MASK 0xFFFF
+#define REG_MB_RFD0_PROD_IDX 0x15E0
+
+#define REG_TPD_PRI1_PIDX 0x15F0 /* 16bit,hi-tpd producer idx */
+#define REG_TPD_PRI0_PIDX 0x15F2 /* 16bit,lo-tpd producer idx */
+#define REG_TPD_PRI1_CIDX 0x15F4 /* 16bit,hi-tpd consumer idx */
+#define REG_TPD_PRI0_CIDX 0x15F6 /* 16bit,lo-tpd consumer idx */
+
+#define REG_MB_RFD01_CONS_IDX 0x15F8
+#define MB_RFD0_CONS_IDX_MASK 0x0000FFFF
+#define MB_RFD1_CONS_IDX_MASK 0xFFFF0000
+
+/* Interrupt Status Register */
+#define REG_ISR 0x1600
+#define ISR_SMB 0x00000001
+#define ISR_TIMER 0x00000002
+/*
+ * Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set
+ * in Table 51 Selene Master Control Register (Offset 0x1400).
+ */
+#define ISR_MANUAL 0x00000004
+#define ISR_HW_RXF_OV 0x00000008 /* RXF overflow interrupt */
+#define ISR_RFD0_UR 0x00000010 /* RFD0 under run */
+#define ISR_RFD1_UR 0x00000020
+#define ISR_RFD2_UR 0x00000040
+#define ISR_RFD3_UR 0x00000080
+#define ISR_TXF_UR 0x00000100
+#define ISR_DMAR_TO_RST 0x00000200
+#define ISR_DMAW_TO_RST 0x00000400
+#define ISR_TX_CREDIT 0x00000800
+#define ISR_GPHY 0x00001000
+/* GPHY low power state interrupt */
+#define ISR_GPHY_LPW 0x00002000
+#define ISR_TXQ_TO_RST 0x00004000
+#define ISR_TX_PKT 0x00008000
+#define ISR_RX_PKT_0 0x00010000
+#define ISR_RX_PKT_1 0x00020000
+#define ISR_RX_PKT_2 0x00040000
+#define ISR_RX_PKT_3 0x00080000
+#define ISR_MAC_RX 0x00100000
+#define ISR_MAC_TX 0x00200000
+#define ISR_UR_DETECTED 0x00400000
+#define ISR_FERR_DETECTED 0x00800000
+#define ISR_NFERR_DETECTED 0x01000000
+#define ISR_CERR_DETECTED 0x02000000
+#define ISR_PHY_LINKDOWN 0x04000000
+#define ISR_DIS_INT 0x80000000
+
+/* Interrupt Mask Register */
+#define REG_IMR 0x1604
+
+#define IMR_NORMAL_MASK (\
+ ISR_MANUAL |\
+ ISR_HW_RXF_OV |\
+ ISR_RFD0_UR |\
+ ISR_TXF_UR |\
+ ISR_DMAR_TO_RST |\
+ ISR_TXQ_TO_RST |\
+ ISR_DMAW_TO_RST |\
+ ISR_GPHY |\
+ ISR_TX_PKT |\
+ ISR_RX_PKT_0 |\
+ ISR_GPHY_LPW |\
+ ISR_PHY_LINKDOWN)
+
+#define ISR_RX_PKT (\
+ ISR_RX_PKT_0 |\
+ ISR_RX_PKT_1 |\
+ ISR_RX_PKT_2 |\
+ ISR_RX_PKT_3)
+
+#define ISR_OVER (\
+ ISR_RFD0_UR |\
+ ISR_RFD1_UR |\
+ ISR_RFD2_UR |\
+ ISR_RFD3_UR |\
+ ISR_HW_RXF_OV |\
+ ISR_TXF_UR)
+
+#define ISR_ERROR (\
+ ISR_DMAR_TO_RST |\
+ ISR_TXQ_TO_RST |\
+ ISR_DMAW_TO_RST |\
+ ISR_PHY_LINKDOWN)
+
+#define REG_INT_RETRIG_TIMER 0x1608
+#define INT_RETRIG_TIMER_MASK 0xFFFF
+
+#define REG_MAC_RX_STATUS_BIN 0x1700
+#define REG_MAC_RX_STATUS_END 0x175c
+#define REG_MAC_TX_STATUS_BIN 0x1760
+#define REG_MAC_TX_STATUS_END 0x17c0
+
+#define REG_CLK_GATING_CTRL 0x1814
+#define CLK_GATING_DMAW_EN 0x0001
+#define CLK_GATING_DMAR_EN 0x0002
+#define CLK_GATING_TXQ_EN 0x0004
+#define CLK_GATING_RXQ_EN 0x0008
+#define CLK_GATING_TXMAC_EN 0x0010
+#define CLK_GATING_RXMAC_EN 0x0020
+
+#define CLK_GATING_EN_ALL (CLK_GATING_DMAW_EN |\
+ CLK_GATING_DMAR_EN |\
+ CLK_GATING_TXQ_EN |\
+ CLK_GATING_RXQ_EN |\
+ CLK_GATING_TXMAC_EN|\
+ CLK_GATING_RXMAC_EN)
+
+/* DEBUG ADDR */
+#define REG_DEBUG_DATA0 0x1900
+#define REG_DEBUG_DATA1 0x1904
+
+#define L1D_MPW_PHYID1 0xD01C /* V7 */
+#define L1D_MPW_PHYID2 0xD01D /* V1-V6 */
+#define L1D_MPW_PHYID3 0xD01E /* V8 */
+
+
+/* Autoneg Advertisement Register */
+#define ADVERTISE_DEFAULT_CAP \
+ (ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)
+
+/* 1000BASE-T Control Register */
+#define GIGA_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port 0=DTE device */
+
+#define GIGA_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master 0=Configure PHY as Slave */
+#define GIGA_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value 0=Automatic Master/Slave config */
+#define GIGA_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
+#define GIGA_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
+#define GIGA_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
+#define GIGA_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
+#define GIGA_CR_1000T_SPEED_MASK 0x0300
+#define GIGA_CR_1000T_DEFAULT_CAP 0x0300
+
+/* PHY Specific Status Register */
+#define MII_GIGA_PSSR 0x11
+#define GIGA_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
+#define GIGA_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
+#define GIGA_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
+#define GIGA_PSSR_10MBS 0x0000 /* 00=10Mbs */
+#define GIGA_PSSR_100MBS 0x4000 /* 01=100Mbs */
+#define GIGA_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
+
+/* PHY Interrupt Enable Register */
+#define MII_IER 0x12
+#define IER_LINK_UP 0x0400
+#define IER_LINK_DOWN 0x0800
+
+/* PHY Interrupt Status Register */
+#define MII_ISR 0x13
+#define ISR_LINK_UP 0x0400
+#define ISR_LINK_DOWN 0x0800
+
+/* Cable-Detect-Test Control Register */
+#define MII_CDTC 0x16
+#define CDTC_EN_OFF 0 /* sc */
+#define CDTC_EN_BITS 1
+#define CDTC_PAIR_OFF 8
+#define CDTC_PAIR_BIT 2
+
+/* Cable-Detect-Test Status Register */
+#define MII_CDTS 0x1C
+#define CDTS_STATUS_OFF 8
+#define CDTS_STATUS_BITS 2
+#define CDTS_STATUS_NORMAL 0
+#define CDTS_STATUS_SHORT 1
+#define CDTS_STATUS_OPEN 2
+#define CDTS_STATUS_INVALID 3
+
+#define MII_DBG_ADDR 0x1D
+#define MII_DBG_DATA 0x1E
+
+/***************************** debug port *************************************/
+
+#define MIIDBG_ANACTRL 0x00
+#define ANACTRL_CLK125M_DELAY_EN 0x8000
+#define ANACTRL_VCO_FAST 0x4000
+#define ANACTRL_VCO_SLOW 0x2000
+#define ANACTRL_AFE_MODE_EN 0x1000
+#define ANACTRL_LCKDET_PHY 0x800
+#define ANACTRL_LCKDET_EN 0x400
+#define ANACTRL_OEN_125M 0x200
+#define ANACTRL_HBIAS_EN 0x100
+#define ANACTRL_HB_EN 0x80
+#define ANACTRL_SEL_HSP 0x40
+#define ANACTRL_CLASSA_EN 0x20
+#define ANACTRL_MANUSWON_SWR_MASK 3U
+#define ANACTRL_MANUSWON_SWR_SHIFT 2
+#define ANACTRL_MANUSWON_SWR_2V 0
+#define ANACTRL_MANUSWON_SWR_1P9V 1
+#define ANACTRL_MANUSWON_SWR_1P8V 2
+#define ANACTRL_MANUSWON_SWR_1P7V 3
+#define ANACTRL_MANUSWON_BW3_4M 0x2
+#define ANACTRL_RESTART_CAL 0x1
+#define ANACTRL_DEF 0x02EF
+
+#define MIIDBG_SYSMODCTRL 0x04
+#define SYSMODCTRL_IECHOADJ_PFMH_PHY 0x8000
+#define SYSMODCTRL_IECHOADJ_BIASGEN 0x4000
+#define SYSMODCTRL_IECHOADJ_PFML_PHY 0x2000
+#define SYSMODCTRL_IECHOADJ_PS_MASK 3U
+#define SYSMODCTRL_IECHOADJ_PS_SHIFT 10
+#define SYSMODCTRL_IECHOADJ_PS_40 3
+#define SYSMODCTRL_IECHOADJ_PS_20 2
+#define SYSMODCTRL_IECHOADJ_PS_0 1
+#define SYSMODCTRL_IECHOADJ_10BT_100MV 0x40 /* 1:100mv, 0:200mv */
+#define SYSMODCTRL_IECHOADJ_HLFAP_MASK 3U
+#define SYSMODCTRL_IECHOADJ_HLFAP_SHIFT 4
+#define SYSMODCTRL_IECHOADJ_VDFULBW 0x8
+#define SYSMODCTRL_IECHOADJ_VDBIASHLF 0x4
+#define SYSMODCTRL_IECHOADJ_VDAMPHLF 0x2
+#define SYSMODCTRL_IECHOADJ_VDLANSW 0x1
+#define SYSMODCTRL_IECHOADJ_DEF 0x88BB /* ???? */
+
+/* for l1d & l2cb */
+#define SYSMODCTRL_IECHOADJ_CUR_ADD 0x8000
+#define SYSMODCTRL_IECHOADJ_CUR_MASK 7U
+#define SYSMODCTRL_IECHOADJ_CUR_SHIFT 12
+#define SYSMODCTRL_IECHOADJ_VOL_MASK 0xFU
+#define SYSMODCTRL_IECHOADJ_VOL_SHIFT 8
+#define SYSMODCTRL_IECHOADJ_VOL_17ALL 3
+#define SYSMODCTRL_IECHOADJ_VOL_100M15 1
+#define SYSMODCTRL_IECHOADJ_VOL_10M17 0
+#define SYSMODCTRL_IECHOADJ_BIAS1_MASK 0xFU
+#define SYSMODCTRL_IECHOADJ_BIAS1_SHIFT 4
+#define SYSMODCTRL_IECHOADJ_BIAS2_MASK 0xFU
+#define SYSMODCTRL_IECHOADJ_BIAS2_SHIFT 0
+#define L1D_SYSMODCTRL_IECHOADJ_DEF 0x4FBB
+
+#define MIIDBG_SRDSYSMOD 0x05
+#define SRDSYSMOD_LCKDET_EN 0x2000
+#define SRDSYSMOD_PLL_EN 0x800
+#define SRDSYSMOD_SEL_HSP 0x400
+#define SRDSYSMOD_HLFTXDR 0x200
+#define SRDSYSMOD_TXCLK_DELAY_EN 0x100
+#define SRDSYSMOD_TXELECIDLE 0x80
+#define SRDSYSMOD_DEEMP_EN 0x40
+#define SRDSYSMOD_MS_PAD 0x4
+#define SRDSYSMOD_CDR_ADC_VLTG 0x2
+#define SRDSYSMOD_CDR_DAC_1MA 0x1
+#define SRDSYSMOD_DEF 0x2C46
+
+#define MIIDBG_CFGLPSPD 0x0A
+#define CFGLPSPD_RSTCNT_MASK 3U
+#define CFGLPSPD_RSTCNT_SHIFT 14
+#define CFGLPSPD_RSTCNT_CLK125SW 0x2000
+
+#define MIIDBG_HIBNEG 0x0B
+#define HIBNEG_PSHIB_EN 0x8000
+#define HIBNEG_WAKE_BOTH 0x4000
+#define HIBNEG_ONOFF_ANACHG_SUDEN 0x2000
+#define HIBNEG_HIB_PULSE 0x1000
+#define HIBNEG_GATE_25M_EN 0x800
+#define HIBNEG_RST_80U 0x400
+#define HIBNEG_RST_TIMER_MASK 3U
+#define HIBNEG_RST_TIMER_SHIFT 8
+#define HIBNEG_GTX_CLK_DELAY_MASK 3U
+#define HIBNEG_GTX_CLK_DELAY_SHIFT 5
+#define HIBNEG_BYPSS_BRKTIMER 0x10
+#define HIBNEG_DEF 0xBC40
+
+#define MIIDBG_TST10BTCFG 0x12
+#define TST10BTCFG_INTV_TIMER_MASK 3U
+#define TST10BTCFG_INTV_TIMER_SHIFT 14
+#define TST10BTCFG_TRIGER_TIMER_MASK 3U
+#define TST10BTCFG_TRIGER_TIMER_SHIFT 12
+#define TST10BTCFG_DIV_MAN_MLT3_EN 0x800
+#define TST10BTCFG_OFF_DAC_IDLE 0x400
+#define TST10BTCFG_LPBK_DEEP 0x4 /* 1:deep,0:shallow */
+#define TST10BTCFG_DEF 0x4C04
+
+#define MIIDBG_AZ_ANADECT 0x15
+#define AZ_ANADECT_10BTRX_TH 0x8000
+#define AZ_ANADECT_BOTH_01CHNL 0x4000
+#define AZ_ANADECT_INTV_MASK 0x3FU
+#define AZ_ANADECT_INTV_SHIFT 8
+#define AZ_ANADECT_THRESH_MASK 0xFU
+#define AZ_ANADECT_THRESH_SHIFT 4
+#define AZ_ANADECT_CHNL_MASK 0xFU
+#define AZ_ANADECT_CHNL_SHIFT 0
+#define AZ_ANADECT_DEF 0x3220
+#define AZ_ANADECT_LONG 0xb210
+
+#define MIIDBG_MSE16DB 0x18 /* l1d */
+#define L1D_MSE16DB_UP 0x05EA
+#define L1D_MSE16DB_DOWN 0x02EA
+
+#define MIIDBG_LEGCYPS 0x29
+#define LEGCYPS_EN 0x8000
+#define LEGCYPS_DAC_AMP1000_MASK 7U
+#define LEGCYPS_DAC_AMP1000_SHIFT 12
+#define LEGCYPS_DAC_AMP100_MASK 7U
+#define LEGCYPS_DAC_AMP100_SHIFT 9
+#define LEGCYPS_DAC_AMP10_MASK 7U
+#define LEGCYPS_DAC_AMP10_SHIFT 6
+#define LEGCYPS_UNPLUG_TIMER_MASK 7U
+#define LEGCYPS_UNPLUG_TIMER_SHIFT 3
+#define LEGCYPS_UNPLUG_DECT_EN 0x4
+#define LEGCYPS_ECNC_PS_EN 0x1
+#define L1D_LEGCYPS_DEF 0x129D
+#define L1C_LEGCYPS_DEF 0x36DD
+
+#define MIIDBG_TST100BTCFG 0x36
+#define TST100BTCFG_NORMAL_BW_EN 0x8000
+#define TST100BTCFG_BADLNK_BYPASS 0x4000
+#define TST100BTCFG_SHORTCABL_TH_MASK 0x3FU
+#define TST100BTCFG_SHORTCABL_TH_SHIFT 8
+#define TST100BTCFG_LITCH_EN 0x80
+#define TST100BTCFG_VLT_SW 0x40
+#define TST100BTCFG_LONGCABL_TH_MASK 0x3FU
+#define TST100BTCFG_LONGCABL_TH_SHIFT 0
+#define TST100BTCFG_DEF 0xE12C
+
+#define MIIDBG_VOLT_CTRL 0x3B /* only for l2cb 1 & 2 */
+#define VOLT_CTRL_CABLE1TH_MASK 0x1FFU
+#define VOLT_CTRL_CABLE1TH_SHIFT 7
+#define VOLT_CTRL_AMPCTRL_MASK 3U
+#define VOLT_CTRL_AMPCTRL_SHIFT 5
+#define VOLT_CTRL_SW_BYPASS 0x10
+#define VOLT_CTRL_SWLOWEST 0x8
+#define VOLT_CTRL_DACAMP10_MASK 7U
+#define VOLT_CTRL_DACAMP10_SHIFT 0
+
+#define MIIDBG_CABLE1TH_DET 0x3E
+#define CABLE1TH_DET_EN 0x8000
+
+
+/******* dev 3 *********/
+#define MIIEXT_PCS 3
+
+#define MIIEXT_CLDCTRL3 0x8003
+#define CLDCTRL3_BP_CABLE1TH_DET_GT 0x8000
+#define CLDCTRL3_AZ_DISAMP 0x1000
+#define L2CB_CLDCTRL3 0x4D19
+#define L1D_CLDCTRL3 0xDD19
+
+#define MIIEXT_CLDCTRL6 0x8006
+#define CLDCTRL6_CAB_LEN_MASK 0x1FFU
+#define CLDCTRL6_CAB_LEN_SHIFT 0
+#define CLDCTRL6_CAB_LEN_SHORT 0x50
+
+/********* dev 7 **********/
+#define MIIEXT_ANEG 7
+
+#define MIIEXT_LOCAL_EEEADV 0x3C
+#define LOCAL_EEEADV_1000BT 0x4
+#define LOCAL_EEEADV_100BT 0x2
+
+#define MIIEXT_REMOTE_EEEADV 0x3D
+#define REMOTE_EEEADV_1000BT 0x4
+#define REMOTE_EEEADV_100BT 0x2
+
+#define MIIEXT_EEE_ANEG 0x8000
+#define EEE_ANEG_1000M 0x4
+#define EEE_ANEG_100M 0x2
+
+#endif /*_ATL1C_HW_H_*/
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
new file mode 100644
index 00000000000..e11bf18fbbd
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -0,0 +1,2803 @@
+/*
+ * Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "atl1c.h"
+
+#define ATL1C_DRV_VERSION "1.0.1.1-NAPI"
+char atl1c_driver_name[] = "atl1c";
+char atl1c_driver_version[] = ATL1C_DRV_VERSION;
+
+/*
+ * atl1c_pci_tbl - PCI Device ID Table
+ *
+ * Wildcard entries (PCI_ANY_ID) should come last
+ * Last entry must be all 0s
+ *
+ * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
+ * Class, Class Mask, private data (not used) }
+ */
+static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = {
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D_2_0)},
+ /* required last entry */
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, atl1c_pci_tbl);
+
+MODULE_AUTHOR("Jie Yang");
+MODULE_AUTHOR("Qualcomm Atheros Inc., <nic-devel@qualcomm.com>");
+MODULE_DESCRIPTION("Qualcom Atheros 100/1000M Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATL1C_DRV_VERSION);
+
+static int atl1c_stop_mac(struct atl1c_hw *hw);
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw);
+static void atl1c_set_aspm(struct atl1c_hw *hw, u16 link_speed);
+static void atl1c_start_mac(struct atl1c_adapter *adapter);
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter,
+ int *work_done, int work_to_do);
+static int atl1c_up(struct atl1c_adapter *adapter);
+static void atl1c_down(struct atl1c_adapter *adapter);
+static int atl1c_reset_mac(struct atl1c_hw *hw);
+static void atl1c_reset_dma_ring(struct atl1c_adapter *adapter);
+static int atl1c_configure(struct atl1c_adapter *adapter);
+static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter);
+
+static const u16 atl1c_pay_load_size[] = {
+ 128, 256, 512, 1024, 2048, 4096,
+};
+
+
+static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE |
+ NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP;
+static void atl1c_pcie_patch(struct atl1c_hw *hw)
+{
+ u32 mst_data, data;
+
+ /* pclk sel could switch to 25M */
+ AT_READ_REG(hw, REG_MASTER_CTRL, &mst_data);
+ mst_data &= ~MASTER_CTRL_CLK_SEL_DIS;
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, mst_data);
+
+ /* WoL/PCIE related settings */
+ if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
+ AT_READ_REG(hw, REG_PCIE_PHYMISC, &data);
+ data |= PCIE_PHYMISC_FORCE_RCV_DET;
+ AT_WRITE_REG(hw, REG_PCIE_PHYMISC, data);
+ } else { /* new dev set bit5 of MASTER */
+ if (!(mst_data & MASTER_CTRL_WAKEN_25M))
+ AT_WRITE_REG(hw, REG_MASTER_CTRL,
+ mst_data | MASTER_CTRL_WAKEN_25M);
+ }
+ /* aspm/PCIE setting only for l2cb 1.0 */
+ if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V10) {
+ AT_READ_REG(hw, REG_PCIE_PHYMISC2, &data);
+ data = FIELD_SETX(data, PCIE_PHYMISC2_CDR_BW,
+ L2CB1_PCIE_PHYMISC2_CDR_BW);
+ data = FIELD_SETX(data, PCIE_PHYMISC2_L0S_TH,
+ L2CB1_PCIE_PHYMISC2_L0S_TH);
+ AT_WRITE_REG(hw, REG_PCIE_PHYMISC2, data);
+ /* extend L1 sync timer */
+ AT_READ_REG(hw, REG_LINK_CTRL, &data);
+ data |= LINK_CTRL_EXT_SYNC;
+ AT_WRITE_REG(hw, REG_LINK_CTRL, data);
+ }
+ /* l2cb 1.x & l1d 1.x */
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d) {
+ AT_READ_REG(hw, REG_PM_CTRL, &data);
+ data |= PM_CTRL_L0S_BUFSRX_EN;
+ AT_WRITE_REG(hw, REG_PM_CTRL, data);
+ /* clear vendor msg */
+ AT_READ_REG(hw, REG_DMA_DBG, &data);
+ AT_WRITE_REG(hw, REG_DMA_DBG, data & ~DMA_DBG_VENDOR_MSG);
+ }
+}
+
+/* FIXME: no need any more ? */
+/*
+ * atl1c_init_pcie - init PCIE module
+ */
+static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag)
+{
+ u32 data;
+ u32 pci_cmd;
+ struct pci_dev *pdev = hw->adapter->pdev;
+ int pos;
+
+ AT_READ_REG(hw, PCI_COMMAND, &pci_cmd);
+ pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ pci_cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_IO);
+ AT_WRITE_REG(hw, PCI_COMMAND, pci_cmd);
+
+ /*
+ * Clear any PowerSaveing Settings
+ */
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+ /* wol sts read-clear */
+ AT_READ_REG(hw, REG_WOL_CTRL, &data);
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+ /*
+ * Mask some pcie error bits
+ */
+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
+ if (pos) {
+ pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, &data);
+ data &= ~(PCI_ERR_UNC_DLP | PCI_ERR_UNC_FCP);
+ pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, data);
+ }
+ /* clear error status */
+ pcie_capability_write_word(pdev, PCI_EXP_DEVSTA,
+ PCI_EXP_DEVSTA_NFED |
+ PCI_EXP_DEVSTA_FED |
+ PCI_EXP_DEVSTA_CED |
+ PCI_EXP_DEVSTA_URD);
+
+ AT_READ_REG(hw, REG_LTSSM_ID_CTRL, &data);
+ data &= ~LTSSM_ID_EN_WRO;
+ AT_WRITE_REG(hw, REG_LTSSM_ID_CTRL, data);
+
+ atl1c_pcie_patch(hw);
+ if (flag & ATL1C_PCIE_L0S_L1_DISABLE)
+ atl1c_disable_l0s_l1(hw);
+
+ msleep(5);
+}
+
+/**
+ * atl1c_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_enable(struct atl1c_adapter *adapter)
+{
+ if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
+ AT_WRITE_REG(&adapter->hw, REG_ISR, 0x7FFFFFFF);
+ AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+ AT_WRITE_FLUSH(&adapter->hw);
+ }
+}
+
+/**
+ * atl1c_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_disable(struct atl1c_adapter *adapter)
+{
+ atomic_inc(&adapter->irq_sem);
+ AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
+ AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT);
+ AT_WRITE_FLUSH(&adapter->hw);
+ synchronize_irq(adapter->pdev->irq);
+}
+
+/**
+ * atl1c_irq_reset - reset interrupt confiure on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
+{
+ atomic_set(&adapter->irq_sem, 1);
+ atl1c_irq_enable(adapter);
+}
+
+/*
+ * atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
+ * of the idle status register until the device is actually idle
+ */
+static u32 atl1c_wait_until_idle(struct atl1c_hw *hw, u32 modu_ctrl)
+{
+ int timeout;
+ u32 data;
+
+ for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+ AT_READ_REG(hw, REG_IDLE_STATUS, &data);
+ if ((data & modu_ctrl) == 0)
+ return 0;
+ msleep(1);
+ }
+ return data;
+}
+
+/**
+ * atl1c_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1c_phy_config(unsigned long data)
+{
+ struct atl1c_adapter *adapter = (struct atl1c_adapter *) data;
+ struct atl1c_hw *hw = &adapter->hw;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ atl1c_restart_autoneg(hw);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+}
+
+void atl1c_reinit_locked(struct atl1c_adapter *adapter)
+{
+ WARN_ON(in_interrupt());
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ clear_bit(__AT_RESETTING, &adapter->flags);
+}
+
+static void atl1c_check_link_status(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ int err;
+ unsigned long flags;
+ u16 speed, duplex, phy_data;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ /* MII_BMSR must read twise */
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+
+ if ((phy_data & BMSR_LSTATUS) == 0) {
+ /* link down */
+ netif_carrier_off(netdev);
+ hw->hibernate = true;
+ if (atl1c_reset_mac(hw) != 0)
+ if (netif_msg_hw(adapter))
+ dev_warn(&pdev->dev, "reset mac failed\n");
+ atl1c_set_aspm(hw, SPEED_0);
+ atl1c_post_phy_linkchg(hw, SPEED_0);
+ atl1c_reset_dma_ring(adapter);
+ atl1c_configure(adapter);
+ } else {
+ /* Link Up */
+ hw->hibernate = false;
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ err = atl1c_get_speed_and_duplex(hw, &speed, &duplex);
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+ if (unlikely(err))
+ return;
+ /* link result is our setting */
+ if (adapter->link_speed != speed ||
+ adapter->link_duplex != duplex) {
+ adapter->link_speed = speed;
+ adapter->link_duplex = duplex;
+ atl1c_set_aspm(hw, speed);
+ atl1c_post_phy_linkchg(hw, speed);
+ atl1c_start_mac(adapter);
+ if (netif_msg_link(adapter))
+ dev_info(&pdev->dev,
+ "%s: %s NIC Link is Up<%d Mbps %s>\n",
+ atl1c_driver_name, netdev->name,
+ adapter->link_speed,
+ adapter->link_duplex == FULL_DUPLEX ?
+ "Full Duplex" : "Half Duplex");
+ }
+ if (!netif_carrier_ok(netdev))
+ netif_carrier_on(netdev);
+ }
+}
+
+static void atl1c_link_chg_event(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 phy_data;
+ u16 link_up;
+
+ spin_lock(&adapter->mdio_lock);
+ atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ atl1c_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ spin_unlock(&adapter->mdio_lock);
+ link_up = phy_data & BMSR_LSTATUS;
+ /* notify upper layer link down ASAP */
+ if (!link_up) {
+ if (netif_carrier_ok(netdev)) {
+ /* old link state: Up */
+ netif_carrier_off(netdev);
+ if (netif_msg_link(adapter))
+ dev_info(&pdev->dev,
+ "%s: %s NIC Link is Down\n",
+ atl1c_driver_name, netdev->name);
+ adapter->link_speed = SPEED_0;
+ }
+ }
+
+ set_bit(ATL1C_WORK_EVENT_LINK_CHANGE, &adapter->work_event);
+ schedule_work(&adapter->common_task);
+}
+
+static void atl1c_common_task(struct work_struct *work)
+{
+ struct atl1c_adapter *adapter;
+ struct net_device *netdev;
+
+ adapter = container_of(work, struct atl1c_adapter, common_task);
+ netdev = adapter->netdev;
+
+ if (test_bit(__AT_DOWN, &adapter->flags))
+ return;
+
+ if (test_and_clear_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event)) {
+ netif_device_detach(netdev);
+ atl1c_down(adapter);
+ atl1c_up(adapter);
+ netif_device_attach(netdev);
+ }
+
+ if (test_and_clear_bit(ATL1C_WORK_EVENT_LINK_CHANGE,
+ &adapter->work_event)) {
+ atl1c_irq_disable(adapter);
+ atl1c_check_link_status(adapter);
+ atl1c_irq_enable(adapter);
+ }
+}
+
+
+static void atl1c_del_timer(struct atl1c_adapter *adapter)
+{
+ del_timer_sync(&adapter->phy_config_timer);
+}
+
+
+/**
+ * atl1c_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl1c_tx_timeout(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ /* Do the reset outside of interrupt context */
+ set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event);
+ schedule_work(&adapter->common_task);
+}
+
+/**
+ * atl1c_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ */
+static void atl1c_set_multi(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ struct netdev_hw_addr *ha;
+ u32 mac_ctrl_data;
+ u32 hash_value;
+
+ /* Check for Promiscuous and All Multicast modes */
+ AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data);
+
+ if (netdev->flags & IFF_PROMISC) {
+ mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
+ } else if (netdev->flags & IFF_ALLMULTI) {
+ mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
+ mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
+ } else {
+ mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+ }
+
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
+
+ /* clear the old settings from the multicast hash table */
+ AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+ AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+ /* comoute mc addresses' hash value ,and put it into hash table */
+ netdev_for_each_mc_addr(ha, netdev) {
+ hash_value = atl1c_hash_mc_addr(hw, ha->addr);
+ atl1c_hash_set(hw, hash_value);
+ }
+}
+
+static void __atl1c_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data)
+{
+ if (features & NETIF_F_HW_VLAN_CTAG_RX) {
+ /* enable VLAN tag insert/strip */
+ *mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+ } else {
+ /* disable VLAN tag insert/strip */
+ *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
+ }
+}
+
+static void atl1c_vlan_mode(struct net_device *netdev,
+ netdev_features_t features)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ u32 mac_ctrl_data = 0;
+
+ if (netif_msg_pktdata(adapter))
+ dev_dbg(&pdev->dev, "atl1c_vlan_mode\n");
+
+ atl1c_irq_disable(adapter);
+ AT_READ_REG(&adapter->hw, REG_MAC_CTRL, &mac_ctrl_data);
+ __atl1c_vlan_mode(features, &mac_ctrl_data);
+ AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
+ atl1c_irq_enable(adapter);
+}
+
+static void atl1c_restore_vlan(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ if (netif_msg_pktdata(adapter))
+ dev_dbg(&pdev->dev, "atl1c_restore_vlan\n");
+ atl1c_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+/**
+ * atl1c_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1c_set_mac_addr(struct net_device *netdev, void *p)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (netif_running(netdev))
+ return -EBUSY;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+ atl1c_hw_set_mac_addr(&adapter->hw, adapter->hw.mac_addr);
+
+ return 0;
+}
+
+static void atl1c_set_rxbufsize(struct atl1c_adapter *adapter,
+ struct net_device *dev)
+{
+ unsigned int head_size;
+ int mtu = dev->mtu;
+
+ adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
+ roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
+
+ head_size = SKB_DATA_ALIGN(adapter->rx_buffer_len + NET_SKB_PAD) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ adapter->rx_frag_size = roundup_pow_of_two(head_size);
+}
+
+static netdev_features_t atl1c_fix_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ /*
+ * Since there is no support for separate rx/tx vlan accel
+ * enable/disable make sure tx flag is always in same state as rx.
+ */
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ features |= NETIF_F_HW_VLAN_CTAG_TX;
+ else
+ features &= ~NETIF_F_HW_VLAN_CTAG_TX;
+
+ if (netdev->mtu > MAX_TSO_FRAME_SIZE)
+ features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+ return features;
+}
+
+static int atl1c_set_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = netdev->features ^ features;
+
+ if (changed & NETIF_F_HW_VLAN_CTAG_RX)
+ atl1c_vlan_mode(netdev, features);
+
+ return 0;
+}
+
+/**
+ * atl1c_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1c_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ int old_mtu = netdev->mtu;
+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+ /* Fast Ethernet controller doesn't support jumbo packet */
+ if (((hw->nic_type == athr_l2c ||
+ hw->nic_type == athr_l2c_b ||
+ hw->nic_type == athr_l2c_b2) && new_mtu > ETH_DATA_LEN) ||
+ max_frame < ETH_ZLEN + ETH_FCS_LEN ||
+ max_frame > MAX_JUMBO_FRAME_SIZE) {
+ if (netif_msg_link(adapter))
+ dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+ return -EINVAL;
+ }
+ /* set MTU */
+ if (old_mtu != new_mtu && netif_running(netdev)) {
+ while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
+ msleep(1);
+ netdev->mtu = new_mtu;
+ adapter->hw.max_frame_size = new_mtu;
+ atl1c_set_rxbufsize(adapter, netdev);
+ atl1c_down(adapter);
+ netdev_update_features(netdev);
+ atl1c_up(adapter);
+ clear_bit(__AT_RESETTING, &adapter->flags);
+ }
+ return 0;
+}
+
+/*
+ * caller should hold mdio_lock
+ */
+static int atl1c_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ u16 result;
+
+ atl1c_read_phy_reg(&adapter->hw, reg_num, &result);
+ return result;
+}
+
+static void atl1c_mdio_write(struct net_device *netdev, int phy_id,
+ int reg_num, int val)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ atl1c_write_phy_reg(&adapter->hw, reg_num, val);
+}
+
+static int atl1c_mii_ioctl(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ struct mii_ioctl_data *data = if_mii(ifr);
+ unsigned long flags;
+ int retval = 0;
+
+ if (!netif_running(netdev))
+ return -EINVAL;
+
+ spin_lock_irqsave(&adapter->mdio_lock, flags);
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ data->phy_id = 0;
+ break;
+
+ case SIOCGMIIREG:
+ if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+ &data->val_out)) {
+ retval = -EIO;
+ goto out;
+ }
+ break;
+
+ case SIOCSMIIREG:
+ if (data->reg_num & ~(0x1F)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ dev_dbg(&pdev->dev, "<atl1c_mii_ioctl> write %x %x",
+ data->reg_num, data->val_in);
+ if (atl1c_write_phy_reg(&adapter->hw,
+ data->reg_num, data->val_in)) {
+ retval = -EIO;
+ goto out;
+ }
+ break;
+
+ default:
+ retval = -EOPNOTSUPP;
+ break;
+ }
+out:
+ spin_unlock_irqrestore(&adapter->mdio_lock, flags);
+ return retval;
+}
+
+static int atl1c_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ return atl1c_mii_ioctl(netdev, ifr, cmd);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+/**
+ * atl1c_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ */
+static int atl1c_alloc_queues(struct atl1c_adapter *adapter)
+{
+ return 0;
+}
+
+static void atl1c_set_mac_type(struct atl1c_hw *hw)
+{
+ switch (hw->device_id) {
+ case PCI_DEVICE_ID_ATTANSIC_L2C:
+ hw->nic_type = athr_l2c;
+ break;
+ case PCI_DEVICE_ID_ATTANSIC_L1C:
+ hw->nic_type = athr_l1c;
+ break;
+ case PCI_DEVICE_ID_ATHEROS_L2C_B:
+ hw->nic_type = athr_l2c_b;
+ break;
+ case PCI_DEVICE_ID_ATHEROS_L2C_B2:
+ hw->nic_type = athr_l2c_b2;
+ break;
+ case PCI_DEVICE_ID_ATHEROS_L1D:
+ hw->nic_type = athr_l1d;
+ break;
+ case PCI_DEVICE_ID_ATHEROS_L1D_2_0:
+ hw->nic_type = athr_l1d_2;
+ break;
+ default:
+ break;
+ }
+}
+
+static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
+{
+ u32 link_ctrl_data;
+
+ atl1c_set_mac_type(hw);
+ AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data);
+
+ hw->ctrl_flags = ATL1C_INTR_MODRT_ENABLE |
+ ATL1C_TXQ_MODE_ENHANCE;
+ hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT |
+ ATL1C_ASPM_L1_SUPPORT;
+ hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON;
+
+ if (hw->nic_type == athr_l1c ||
+ hw->nic_type == athr_l1d ||
+ hw->nic_type == athr_l1d_2)
+ hw->link_cap_flags |= ATL1C_LINK_CAP_1000M;
+ return 0;
+}
+
+struct atl1c_platform_patch {
+ u16 pci_did;
+ u8 pci_revid;
+ u16 subsystem_vid;
+ u16 subsystem_did;
+ u32 patch_flag;
+#define ATL1C_LINK_PATCH 0x1
+};
+static const struct atl1c_platform_patch plats[] = {
+{0x2060, 0xC1, 0x1019, 0x8152, 0x1},
+{0x2060, 0xC1, 0x1019, 0x2060, 0x1},
+{0x2060, 0xC1, 0x1019, 0xE000, 0x1},
+{0x2062, 0xC0, 0x1019, 0x8152, 0x1},
+{0x2062, 0xC0, 0x1019, 0x2062, 0x1},
+{0x2062, 0xC0, 0x1458, 0xE000, 0x1},
+{0x2062, 0xC1, 0x1019, 0x8152, 0x1},
+{0x2062, 0xC1, 0x1019, 0x2062, 0x1},
+{0x2062, 0xC1, 0x1458, 0xE000, 0x1},
+{0x2062, 0xC1, 0x1565, 0x2802, 0x1},
+{0x2062, 0xC1, 0x1565, 0x2801, 0x1},
+{0x1073, 0xC0, 0x1019, 0x8151, 0x1},
+{0x1073, 0xC0, 0x1019, 0x1073, 0x1},
+{0x1073, 0xC0, 0x1458, 0xE000, 0x1},
+{0x1083, 0xC0, 0x1458, 0xE000, 0x1},
+{0x1083, 0xC0, 0x1019, 0x8151, 0x1},
+{0x1083, 0xC0, 0x1019, 0x1083, 0x1},
+{0x1083, 0xC0, 0x1462, 0x7680, 0x1},
+{0x1083, 0xC0, 0x1565, 0x2803, 0x1},
+{0},
+};
+
+static void atl1c_patch_assign(struct atl1c_hw *hw)
+{
+ struct pci_dev *pdev = hw->adapter->pdev;
+ u32 misc_ctrl;
+ int i = 0;
+
+ hw->msi_lnkpatch = false;
+
+ while (plats[i].pci_did != 0) {
+ if (plats[i].pci_did == hw->device_id &&
+ plats[i].pci_revid == hw->revision_id &&
+ plats[i].subsystem_vid == hw->subsystem_vendor_id &&
+ plats[i].subsystem_did == hw->subsystem_id) {
+ if (plats[i].patch_flag & ATL1C_LINK_PATCH)
+ hw->msi_lnkpatch = true;
+ }
+ i++;
+ }
+
+ if (hw->device_id == PCI_DEVICE_ID_ATHEROS_L2C_B2 &&
+ hw->revision_id == L2CB_V21) {
+ /* config acess mode */
+ pci_write_config_dword(pdev, REG_PCIE_IND_ACC_ADDR,
+ REG_PCIE_DEV_MISC_CTRL);
+ pci_read_config_dword(pdev, REG_PCIE_IND_ACC_DATA, &misc_ctrl);
+ misc_ctrl &= ~0x100;
+ pci_write_config_dword(pdev, REG_PCIE_IND_ACC_ADDR,
+ REG_PCIE_DEV_MISC_CTRL);
+ pci_write_config_dword(pdev, REG_PCIE_IND_ACC_DATA, misc_ctrl);
+ }
+}
+/**
+ * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl1c_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ */
+static int atl1c_sw_init(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 revision;
+
+
+ adapter->wol = 0;
+ device_set_wakeup_enable(&pdev->dev, false);
+ adapter->link_speed = SPEED_0;
+ adapter->link_duplex = FULL_DUPLEX;
+ adapter->tpd_ring[0].count = 1024;
+ adapter->rfd_ring.count = 512;
+
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_id = pdev->subsystem_device;
+ pci_read_config_dword(pdev, PCI_CLASS_REVISION, &revision);
+ hw->revision_id = revision & 0xFF;
+ /* before link up, we assume hibernate is true */
+ hw->hibernate = true;
+ hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
+ if (atl1c_setup_mac_funcs(hw) != 0) {
+ dev_err(&pdev->dev, "set mac function pointers failed\n");
+ return -1;
+ }
+ atl1c_patch_assign(hw);
+
+ hw->intr_mask = IMR_NORMAL_MASK;
+ hw->phy_configured = false;
+ hw->preamble_len = 7;
+ hw->max_frame_size = adapter->netdev->mtu;
+ hw->autoneg_advertised = ADVERTISED_Autoneg;
+ hw->indirect_tab = 0xE4E4E4E4;
+ hw->base_cpu = 0;
+
+ hw->ict = 50000; /* 100ms */
+ hw->smb_timer = 200000; /* 400ms */
+ hw->rx_imt = 200;
+ hw->tx_imt = 1000;
+
+ hw->tpd_burst = 5;
+ hw->rfd_burst = 8;
+ hw->dma_order = atl1c_dma_ord_out;
+ hw->dmar_block = atl1c_dma_req_1024;
+
+ if (atl1c_alloc_queues(adapter)) {
+ dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
+ }
+ /* TODO */
+ atl1c_set_rxbufsize(adapter, adapter->netdev);
+ atomic_set(&adapter->irq_sem, 1);
+ spin_lock_init(&adapter->mdio_lock);
+ spin_lock_init(&adapter->tx_lock);
+ set_bit(__AT_DOWN, &adapter->flags);
+
+ return 0;
+}
+
+static inline void atl1c_clean_buffer(struct pci_dev *pdev,
+ struct atl1c_buffer *buffer_info)
+{
+ u16 pci_driection;
+ if (buffer_info->flags & ATL1C_BUFFER_FREE)
+ return;
+ if (buffer_info->dma) {
+ if (buffer_info->flags & ATL1C_PCIMAP_FROMDEVICE)
+ pci_driection = PCI_DMA_FROMDEVICE;
+ else
+ pci_driection = PCI_DMA_TODEVICE;
+
+ if (buffer_info->flags & ATL1C_PCIMAP_SINGLE)
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length, pci_driection);
+ else if (buffer_info->flags & ATL1C_PCIMAP_PAGE)
+ pci_unmap_page(pdev, buffer_info->dma,
+ buffer_info->length, pci_driection);
+ }
+ if (buffer_info->skb)
+ dev_consume_skb_any(buffer_info->skb);
+ buffer_info->dma = 0;
+ buffer_info->skb = NULL;
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
+}
+/**
+ * atl1c_clean_tx_ring - Free Tx-skb
+ * @adapter: board private structure
+ */
+static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 index, ring_count;
+
+ ring_count = tpd_ring->count;
+ for (index = 0; index < ring_count; index++) {
+ buffer_info = &tpd_ring->buffer_info[index];
+ atl1c_clean_buffer(pdev, buffer_info);
+ }
+
+ /* Zero out Tx-buffers */
+ memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
+ ring_count);
+ atomic_set(&tpd_ring->next_to_clean, 0);
+ tpd_ring->next_to_use = 0;
+}
+
+/**
+ * atl1c_clean_rx_ring - Free rx-reservation skbs
+ * @adapter: board private structure
+ */
+static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter)
+{
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring;
+ struct atl1c_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ int j;
+
+ for (j = 0; j < rfd_ring->count; j++) {
+ buffer_info = &rfd_ring->buffer_info[j];
+ atl1c_clean_buffer(pdev, buffer_info);
+ }
+ /* zero out the descriptor ring */
+ memset(rfd_ring->desc, 0, rfd_ring->size);
+ rfd_ring->next_to_clean = 0;
+ rfd_ring->next_to_use = 0;
+ rrd_ring->next_to_use = 0;
+ rrd_ring->next_to_clean = 0;
+}
+
+/*
+ * Read / Write Ptr Initialize:
+ */
+static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter)
+{
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring;
+ struct atl1c_buffer *buffer_info;
+ int i, j;
+
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].next_to_use = 0;
+ atomic_set(&tpd_ring[i].next_to_clean, 0);
+ buffer_info = tpd_ring[i].buffer_info;
+ for (j = 0; j < tpd_ring->count; j++)
+ ATL1C_SET_BUFFER_STATE(&buffer_info[i],
+ ATL1C_BUFFER_FREE);
+ }
+ rfd_ring->next_to_use = 0;
+ rfd_ring->next_to_clean = 0;
+ rrd_ring->next_to_use = 0;
+ rrd_ring->next_to_clean = 0;
+ for (j = 0; j < rfd_ring->count; j++) {
+ buffer_info = &rfd_ring->buffer_info[j];
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
+ }
+}
+
+/**
+ * atl1c_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl1c_free_ring_resources(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+
+ pci_free_consistent(pdev, adapter->ring_header.size,
+ adapter->ring_header.desc,
+ adapter->ring_header.dma);
+ adapter->ring_header.desc = NULL;
+
+ /* Note: just free tdp_ring.buffer_info,
+ * it contain rfd_ring.buffer_info, do not double free */
+ if (adapter->tpd_ring[0].buffer_info) {
+ kfree(adapter->tpd_ring[0].buffer_info);
+ adapter->tpd_ring[0].buffer_info = NULL;
+ }
+ if (adapter->rx_page) {
+ put_page(adapter->rx_page);
+ adapter->rx_page = NULL;
+ }
+}
+
+/**
+ * atl1c_setup_mem_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring;
+ struct atl1c_ring_header *ring_header = &adapter->ring_header;
+ int size;
+ int i;
+ int count = 0;
+ int rx_desc_count = 0;
+ u32 offset = 0;
+
+ rrd_ring->count = rfd_ring->count;
+ for (i = 1; i < AT_MAX_TRANSMIT_QUEUE; i++)
+ tpd_ring[i].count = tpd_ring[0].count;
+
+ /* 2 tpd queue, one high priority queue,
+ * another normal priority queue */
+ size = sizeof(struct atl1c_buffer) * (tpd_ring->count * 2 +
+ rfd_ring->count);
+ tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
+ if (unlikely(!tpd_ring->buffer_info))
+ goto err_nomem;
+
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].buffer_info =
+ (tpd_ring->buffer_info + count);
+ count += tpd_ring[i].count;
+ }
+
+ rfd_ring->buffer_info =
+ (tpd_ring->buffer_info + count);
+ count += rfd_ring->count;
+ rx_desc_count += rfd_ring->count;
+
+ /*
+ * real ring DMA buffer
+ * each ring/block may need up to 8 bytes for alignment, hence the
+ * additional bytes tacked onto the end.
+ */
+ ring_header->size = size =
+ sizeof(struct atl1c_tpd_desc) * tpd_ring->count * 2 +
+ sizeof(struct atl1c_rx_free_desc) * rx_desc_count +
+ sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
+ 8 * 4;
+
+ ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
+ &ring_header->dma);
+ if (unlikely(!ring_header->desc)) {
+ dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+ goto err_nomem;
+ }
+ memset(ring_header->desc, 0, ring_header->size);
+ /* init TPD ring */
+
+ tpd_ring[0].dma = roundup(ring_header->dma, 8);
+ offset = tpd_ring[0].dma - ring_header->dma;
+ for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) {
+ tpd_ring[i].dma = ring_header->dma + offset;
+ tpd_ring[i].desc = (u8 *) ring_header->desc + offset;
+ tpd_ring[i].size =
+ sizeof(struct atl1c_tpd_desc) * tpd_ring[i].count;
+ offset += roundup(tpd_ring[i].size, 8);
+ }
+ /* init RFD ring */
+ rfd_ring->dma = ring_header->dma + offset;
+ rfd_ring->desc = (u8 *) ring_header->desc + offset;
+ rfd_ring->size = sizeof(struct atl1c_rx_free_desc) * rfd_ring->count;
+ offset += roundup(rfd_ring->size, 8);
+
+ /* init RRD ring */
+ rrd_ring->dma = ring_header->dma + offset;
+ rrd_ring->desc = (u8 *) ring_header->desc + offset;
+ rrd_ring->size = sizeof(struct atl1c_recv_ret_status) *
+ rrd_ring->count;
+ offset += roundup(rrd_ring->size, 8);
+
+ return 0;
+
+err_nomem:
+ kfree(tpd_ring->buffer_info);
+ return -ENOMEM;
+}
+
+static void atl1c_configure_des_ring(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring;
+ struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *)
+ adapter->tpd_ring;
+
+ /* TPD */
+ AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI,
+ (u32)((tpd_ring[atl1c_trans_normal].dma &
+ AT_DMA_HI_ADDR_MASK) >> 32));
+ /* just enable normal priority TX queue */
+ AT_WRITE_REG(hw, REG_TPD_PRI0_ADDR_LO,
+ (u32)(tpd_ring[atl1c_trans_normal].dma &
+ AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_TPD_PRI1_ADDR_LO,
+ (u32)(tpd_ring[atl1c_trans_high].dma &
+ AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_TPD_RING_SIZE,
+ (u32)(tpd_ring[0].count & TPD_RING_SIZE_MASK));
+
+
+ /* RFD */
+ AT_WRITE_REG(hw, REG_RX_BASE_ADDR_HI,
+ (u32)((rfd_ring->dma & AT_DMA_HI_ADDR_MASK) >> 32));
+ AT_WRITE_REG(hw, REG_RFD0_HEAD_ADDR_LO,
+ (u32)(rfd_ring->dma & AT_DMA_LO_ADDR_MASK));
+
+ AT_WRITE_REG(hw, REG_RFD_RING_SIZE,
+ rfd_ring->count & RFD_RING_SIZE_MASK);
+ AT_WRITE_REG(hw, REG_RX_BUF_SIZE,
+ adapter->rx_buffer_len & RX_BUF_SIZE_MASK);
+
+ /* RRD */
+ AT_WRITE_REG(hw, REG_RRD0_HEAD_ADDR_LO,
+ (u32)(rrd_ring->dma & AT_DMA_LO_ADDR_MASK));
+ AT_WRITE_REG(hw, REG_RRD_RING_SIZE,
+ (rrd_ring->count & RRD_RING_SIZE_MASK));
+
+ if (hw->nic_type == athr_l2c_b) {
+ AT_WRITE_REG(hw, REG_SRAM_RXF_LEN, 0x02a0L);
+ AT_WRITE_REG(hw, REG_SRAM_TXF_LEN, 0x0100L);
+ AT_WRITE_REG(hw, REG_SRAM_RXF_ADDR, 0x029f0000L);
+ AT_WRITE_REG(hw, REG_SRAM_RFD0_INFO, 0x02bf02a0L);
+ AT_WRITE_REG(hw, REG_SRAM_TXF_ADDR, 0x03bf02c0L);
+ AT_WRITE_REG(hw, REG_SRAM_TRD_ADDR, 0x03df03c0L);
+ AT_WRITE_REG(hw, REG_TXF_WATER_MARK, 0); /* TX watermark, to enter l1 state.*/
+ AT_WRITE_REG(hw, REG_RXD_DMA_CTRL, 0); /* RXD threshold.*/
+ }
+ /* Load all of base address above */
+ AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
+}
+
+static void atl1c_configure_tx(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ int max_pay_load;
+ u16 tx_offload_thresh;
+ u32 txq_ctrl_data;
+
+ tx_offload_thresh = MAX_TSO_FRAME_SIZE;
+ AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
+ (tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
+ max_pay_load = pcie_get_readrq(adapter->pdev) >> 8;
+ hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
+ /*
+ * if BIOS had changed the dam-read-max-length to an invalid value,
+ * restore it to default value
+ */
+ if (hw->dmar_block < DEVICE_CTRL_MAXRRS_MIN) {
+ pcie_set_readrq(adapter->pdev, 128 << DEVICE_CTRL_MAXRRS_MIN);
+ hw->dmar_block = DEVICE_CTRL_MAXRRS_MIN;
+ }
+ txq_ctrl_data =
+ hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2 ?
+ L2CB_TXQ_CFGV : L1C_TXQ_CFGV;
+
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data);
+}
+
+static void atl1c_configure_rx(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 rxq_ctrl_data;
+
+ rxq_ctrl_data = (hw->rfd_burst & RXQ_RFD_BURST_NUM_MASK) <<
+ RXQ_RFD_BURST_NUM_SHIFT;
+
+ if (hw->ctrl_flags & ATL1C_RX_IPV6_CHKSUM)
+ rxq_ctrl_data |= IPV6_CHKSUM_CTRL_EN;
+
+ /* aspm for gigabit */
+ if (hw->nic_type != athr_l1d_2 && (hw->device_id & 1) != 0)
+ rxq_ctrl_data = FIELD_SETX(rxq_ctrl_data, ASPM_THRUPUT_LIMIT,
+ ASPM_THRUPUT_LIMIT_100M);
+
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
+}
+
+static void atl1c_configure_dma(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 dma_ctrl_data;
+
+ dma_ctrl_data = FIELDX(DMA_CTRL_RORDER_MODE, DMA_CTRL_RORDER_MODE_OUT) |
+ DMA_CTRL_RREQ_PRI_DATA |
+ FIELDX(DMA_CTRL_RREQ_BLEN, hw->dmar_block) |
+ FIELDX(DMA_CTRL_WDLY_CNT, DMA_CTRL_WDLY_CNT_DEF) |
+ FIELDX(DMA_CTRL_RDLY_CNT, DMA_CTRL_RDLY_CNT_DEF);
+
+ AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
+}
+
+/*
+ * Stop the mac, transmit and receive units
+ * hw - Struct containing variables accessed by shared code
+ * return : 0 or idle status (if error)
+ */
+static int atl1c_stop_mac(struct atl1c_hw *hw)
+{
+ u32 data;
+
+ AT_READ_REG(hw, REG_RXQ_CTRL, &data);
+ data &= ~RXQ_CTRL_EN;
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, data);
+
+ AT_READ_REG(hw, REG_TXQ_CTRL, &data);
+ data &= ~TXQ_CTRL_EN;
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, data);
+
+ atl1c_wait_until_idle(hw, IDLE_STATUS_RXQ_BUSY | IDLE_STATUS_TXQ_BUSY);
+
+ AT_READ_REG(hw, REG_MAC_CTRL, &data);
+ data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, data);
+
+ return (int)atl1c_wait_until_idle(hw,
+ IDLE_STATUS_TXMAC_BUSY | IDLE_STATUS_RXMAC_BUSY);
+}
+
+static void atl1c_start_mac(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 mac, txq, rxq;
+
+ hw->mac_duplex = adapter->link_duplex == FULL_DUPLEX ? true : false;
+ hw->mac_speed = adapter->link_speed == SPEED_1000 ?
+ atl1c_mac_speed_1000 : atl1c_mac_speed_10_100;
+
+ AT_READ_REG(hw, REG_TXQ_CTRL, &txq);
+ AT_READ_REG(hw, REG_RXQ_CTRL, &rxq);
+ AT_READ_REG(hw, REG_MAC_CTRL, &mac);
+
+ txq |= TXQ_CTRL_EN;
+ rxq |= RXQ_CTRL_EN;
+ mac |= MAC_CTRL_TX_EN | MAC_CTRL_TX_FLOW |
+ MAC_CTRL_RX_EN | MAC_CTRL_RX_FLOW |
+ MAC_CTRL_ADD_CRC | MAC_CTRL_PAD |
+ MAC_CTRL_BC_EN | MAC_CTRL_SINGLE_PAUSE_EN |
+ MAC_CTRL_HASH_ALG_CRC32;
+ if (hw->mac_duplex)
+ mac |= MAC_CTRL_DUPLX;
+ else
+ mac &= ~MAC_CTRL_DUPLX;
+ mac = FIELD_SETX(mac, MAC_CTRL_SPEED, hw->mac_speed);
+ mac = FIELD_SETX(mac, MAC_CTRL_PRMLEN, hw->preamble_len);
+
+ AT_WRITE_REG(hw, REG_TXQ_CTRL, txq);
+ AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, mac);
+}
+
+/*
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ * hw - Struct containing variables accessed by shared code
+ * return : 0 or idle status (if error)
+ */
+static int atl1c_reset_mac(struct atl1c_hw *hw)
+{
+ struct atl1c_adapter *adapter = hw->adapter;
+ struct pci_dev *pdev = adapter->pdev;
+ u32 ctrl_data = 0;
+
+ atl1c_stop_mac(hw);
+ /*
+ * Issue Soft Reset to the MAC. This will reset the chip's
+ * transmit, receive, DMA. It will not effect
+ * the current PCI configuration. The global reset bit is self-
+ * clearing, and should clear within a microsecond.
+ */
+ AT_READ_REG(hw, REG_MASTER_CTRL, &ctrl_data);
+ ctrl_data |= MASTER_CTRL_OOB_DIS;
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, ctrl_data | MASTER_CTRL_SOFT_RST);
+
+ AT_WRITE_FLUSH(hw);
+ msleep(10);
+ /* Wait at least 10ms for All module to be Idle */
+
+ if (atl1c_wait_until_idle(hw, IDLE_STATUS_MASK)) {
+ dev_err(&pdev->dev,
+ "MAC state machine can't be idle since"
+ " disabled for 10ms second\n");
+ return -1;
+ }
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, ctrl_data);
+
+ /* driver control speed/duplex */
+ AT_READ_REG(hw, REG_MAC_CTRL, &ctrl_data);
+ AT_WRITE_REG(hw, REG_MAC_CTRL, ctrl_data | MAC_CTRL_SPEED_MODE_SW);
+
+ /* clk switch setting */
+ AT_READ_REG(hw, REG_SERDES, &ctrl_data);
+ switch (hw->nic_type) {
+ case athr_l2c_b:
+ ctrl_data &= ~(SERDES_PHY_CLK_SLOWDOWN |
+ SERDES_MAC_CLK_SLOWDOWN);
+ AT_WRITE_REG(hw, REG_SERDES, ctrl_data);
+ break;
+ case athr_l2c_b2:
+ case athr_l1d_2:
+ ctrl_data |= SERDES_PHY_CLK_SLOWDOWN | SERDES_MAC_CLK_SLOWDOWN;
+ AT_WRITE_REG(hw, REG_SERDES, ctrl_data);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void atl1c_disable_l0s_l1(struct atl1c_hw *hw)
+{
+ u16 ctrl_flags = hw->ctrl_flags;
+
+ hw->ctrl_flags &= ~(ATL1C_ASPM_L0S_SUPPORT | ATL1C_ASPM_L1_SUPPORT);
+ atl1c_set_aspm(hw, SPEED_0);
+ hw->ctrl_flags = ctrl_flags;
+}
+
+/*
+ * Set ASPM state.
+ * Enable/disable L0s/L1 depend on link state.
+ */
+static void atl1c_set_aspm(struct atl1c_hw *hw, u16 link_speed)
+{
+ u32 pm_ctrl_data;
+ u32 link_l1_timer;
+
+ AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
+ pm_ctrl_data &= ~(PM_CTRL_ASPM_L1_EN |
+ PM_CTRL_ASPM_L0S_EN |
+ PM_CTRL_MAC_ASPM_CHK);
+ /* L1 timer */
+ if (hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) {
+ pm_ctrl_data &= ~PMCTRL_TXL1_AFTER_L0S;
+ link_l1_timer =
+ link_speed == SPEED_1000 || link_speed == SPEED_100 ?
+ L1D_PMCTRL_L1_ENTRY_TM_16US : 1;
+ pm_ctrl_data = FIELD_SETX(pm_ctrl_data,
+ L1D_PMCTRL_L1_ENTRY_TM, link_l1_timer);
+ } else {
+ link_l1_timer = hw->nic_type == athr_l2c_b ?
+ L2CB1_PM_CTRL_L1_ENTRY_TM : L1C_PM_CTRL_L1_ENTRY_TM;
+ if (link_speed != SPEED_1000 && link_speed != SPEED_100)
+ link_l1_timer = 1;
+ pm_ctrl_data = FIELD_SETX(pm_ctrl_data,
+ PM_CTRL_L1_ENTRY_TIMER, link_l1_timer);
+ }
+
+ /* L0S/L1 enable */
+ if ((hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT) && link_speed != SPEED_0)
+ pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN | PM_CTRL_MAC_ASPM_CHK;
+ if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT)
+ pm_ctrl_data |= PM_CTRL_ASPM_L1_EN | PM_CTRL_MAC_ASPM_CHK;
+
+ /* l2cb & l1d & l2cb2 & l1d2 */
+ if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d ||
+ hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) {
+ pm_ctrl_data = FIELD_SETX(pm_ctrl_data,
+ PM_CTRL_PM_REQ_TIMER, PM_CTRL_PM_REQ_TO_DEF);
+ pm_ctrl_data |= PM_CTRL_RCVR_WT_TIMER |
+ PM_CTRL_SERDES_PD_EX_L1 |
+ PM_CTRL_CLK_SWH_L1;
+ pm_ctrl_data &= ~(PM_CTRL_SERDES_L1_EN |
+ PM_CTRL_SERDES_PLL_L1_EN |
+ PM_CTRL_SERDES_BUFS_RX_L1_EN |
+ PM_CTRL_SA_DLY_EN |
+ PM_CTRL_HOTRST);
+ /* disable l0s if link down or l2cb */
+ if (link_speed == SPEED_0 || hw->nic_type == athr_l2c_b)
+ pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
+ } else { /* l1c */
+ pm_ctrl_data =
+ FIELD_SETX(pm_ctrl_data, PM_CTRL_L1_ENTRY_TIMER, 0);
+ if (link_speed != SPEED_0) {
+ pm_ctrl_data |= PM_CTRL_SERDES_L1_EN |
+ PM_CTRL_SERDES_PLL_L1_EN |
+ PM_CTRL_SERDES_BUFS_RX_L1_EN;
+ pm_ctrl_data &= ~(PM_CTRL_SERDES_PD_EX_L1 |
+ PM_CTRL_CLK_SWH_L1 |
+ PM_CTRL_ASPM_L0S_EN |
+ PM_CTRL_ASPM_L1_EN);
+ } else { /* link down */
+ pm_ctrl_data |= PM_CTRL_CLK_SWH_L1;
+ pm_ctrl_data &= ~(PM_CTRL_SERDES_L1_EN |
+ PM_CTRL_SERDES_PLL_L1_EN |
+ PM_CTRL_SERDES_BUFS_RX_L1_EN |
+ PM_CTRL_ASPM_L0S_EN);
+ }
+ }
+ AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data);
+
+ return;
+}
+
+/**
+ * atl1c_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl1c_configure_mac(struct atl1c_adapter *adapter)
+{
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 master_ctrl_data = 0;
+ u32 intr_modrt_data;
+ u32 data;
+
+ AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data);
+ master_ctrl_data &= ~(MASTER_CTRL_TX_ITIMER_EN |
+ MASTER_CTRL_RX_ITIMER_EN |
+ MASTER_CTRL_INT_RDCLR);
+ /* clear interrupt status */
+ AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF);
+ /* Clear any WOL status */
+ AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
+ /* set Interrupt Clear Timer
+ * HW will enable self to assert interrupt event to system after
+ * waiting x-time for software to notify it accept interrupt.
+ */
+
+ data = CLK_GATING_EN_ALL;
+ if (hw->ctrl_flags & ATL1C_CLK_GATING_EN) {
+ if (hw->nic_type == athr_l2c_b)
+ data &= ~CLK_GATING_RXMAC_EN;
+ } else
+ data = 0;
+ AT_WRITE_REG(hw, REG_CLK_GATING_CTRL, data);
+
+ AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER,
+ hw->ict & INT_RETRIG_TIMER_MASK);
+
+ atl1c_configure_des_ring(adapter);
+
+ if (hw->ctrl_flags & ATL1C_INTR_MODRT_ENABLE) {
+ intr_modrt_data = (hw->tx_imt & IRQ_MODRT_TIMER_MASK) <<
+ IRQ_MODRT_TX_TIMER_SHIFT;
+ intr_modrt_data |= (hw->rx_imt & IRQ_MODRT_TIMER_MASK) <<
+ IRQ_MODRT_RX_TIMER_SHIFT;
+ AT_WRITE_REG(hw, REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data);
+ master_ctrl_data |=
+ MASTER_CTRL_TX_ITIMER_EN | MASTER_CTRL_RX_ITIMER_EN;
+ }
+
+ if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ)
+ master_ctrl_data |= MASTER_CTRL_INT_RDCLR;
+
+ master_ctrl_data |= MASTER_CTRL_SA_TIMER_EN;
+ AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data);
+
+ AT_WRITE_REG(hw, REG_SMB_STAT_TIMER,
+ hw->smb_timer & SMB_STAT_TIMER_MASK);
+
+ /* set MTU */
+ AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
+ VLAN_HLEN + ETH_FCS_LEN);
+
+ atl1c_configure_tx(adapter);
+ atl1c_configure_rx(adapter);
+ atl1c_configure_dma(adapter);
+
+ return 0;
+}
+
+static int atl1c_configure(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int num;
+
+ atl1c_init_ring_ptrs(adapter);
+ atl1c_set_multi(netdev);
+ atl1c_restore_vlan(adapter);
+
+ num = atl1c_alloc_rx_buffer(adapter);
+ if (unlikely(num == 0))
+ return -ENOMEM;
+
+ if (atl1c_configure_mac(adapter))
+ return -EIO;
+
+ return 0;
+}
+
+static void atl1c_update_hw_stats(struct atl1c_adapter *adapter)
+{
+ u16 hw_reg_addr = 0;
+ unsigned long *stats_item = NULL;
+ u32 data;
+
+ /* update rx status */
+ hw_reg_addr = REG_MAC_RX_STATUS_BIN;
+ stats_item = &adapter->hw_stats.rx_ok;
+ while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
+ AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+ *stats_item += data;
+ stats_item++;
+ hw_reg_addr += 4;
+ }
+/* update tx status */
+ hw_reg_addr = REG_MAC_TX_STATUS_BIN;
+ stats_item = &adapter->hw_stats.tx_ok;
+ while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
+ AT_READ_REG(&adapter->hw, hw_reg_addr, &data);
+ *stats_item += data;
+ stats_item++;
+ hw_reg_addr += 4;
+ }
+}
+
+/**
+ * atl1c_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ */
+static struct net_device_stats *atl1c_get_stats(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw_stats *hw_stats = &adapter->hw_stats;
+ struct net_device_stats *net_stats = &netdev->stats;
+
+ atl1c_update_hw_stats(adapter);
+ net_stats->rx_bytes = hw_stats->rx_byte_cnt;
+ net_stats->tx_bytes = hw_stats->tx_byte_cnt;
+ net_stats->multicast = hw_stats->rx_mcast;
+ net_stats->collisions = hw_stats->tx_1_col +
+ hw_stats->tx_2_col +
+ hw_stats->tx_late_col +
+ hw_stats->tx_abort_col;
+
+ net_stats->rx_errors = hw_stats->rx_frag +
+ hw_stats->rx_fcs_err +
+ hw_stats->rx_len_err +
+ hw_stats->rx_sz_ov +
+ hw_stats->rx_rrd_ov +
+ hw_stats->rx_align_err +
+ hw_stats->rx_rxf_ov;
+
+ net_stats->rx_fifo_errors = hw_stats->rx_rxf_ov;
+ net_stats->rx_length_errors = hw_stats->rx_len_err;
+ net_stats->rx_crc_errors = hw_stats->rx_fcs_err;
+ net_stats->rx_frame_errors = hw_stats->rx_align_err;
+ net_stats->rx_dropped = hw_stats->rx_rrd_ov;
+
+ net_stats->tx_errors = hw_stats->tx_late_col +
+ hw_stats->tx_abort_col +
+ hw_stats->tx_underrun +
+ hw_stats->tx_trunc;
+
+ net_stats->tx_fifo_errors = hw_stats->tx_underrun;
+ net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
+ net_stats->tx_window_errors = hw_stats->tx_late_col;
+
+ net_stats->rx_packets = hw_stats->rx_ok + net_stats->rx_errors;
+ net_stats->tx_packets = hw_stats->tx_ok + net_stats->tx_errors;
+
+ return net_stats;
+}
+
+static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter)
+{
+ u16 phy_data;
+
+ spin_lock(&adapter->mdio_lock);
+ atl1c_read_phy_reg(&adapter->hw, MII_ISR, &phy_data);
+ spin_unlock(&adapter->mdio_lock);
+}
+
+static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ struct pci_dev *pdev = adapter->pdev;
+ u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+ u16 hw_next_to_clean;
+ u16 reg;
+
+ reg = type == atl1c_trans_high ? REG_TPD_PRI1_CIDX : REG_TPD_PRI0_CIDX;
+
+ AT_READ_REGW(&adapter->hw, reg, &hw_next_to_clean);
+
+ while (next_to_clean != hw_next_to_clean) {
+ buffer_info = &tpd_ring->buffer_info[next_to_clean];
+ atl1c_clean_buffer(pdev, buffer_info);
+ if (++next_to_clean == tpd_ring->count)
+ next_to_clean = 0;
+ atomic_set(&tpd_ring->next_to_clean, next_to_clean);
+ }
+
+ if (netif_queue_stopped(adapter->netdev) &&
+ netif_carrier_ok(adapter->netdev)) {
+ netif_wake_queue(adapter->netdev);
+ }
+
+ return true;
+}
+
+/**
+ * atl1c_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ */
+static irqreturn_t atl1c_intr(int irq, void *data)
+{
+ struct net_device *netdev = data;
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_hw *hw = &adapter->hw;
+ int max_ints = AT_MAX_INT_WORK;
+ int handled = IRQ_NONE;
+ u32 status;
+ u32 reg_data;
+
+ do {
+ AT_READ_REG(hw, REG_ISR, &reg_data);
+ status = reg_data & hw->intr_mask;
+
+ if (status == 0 || (status & ISR_DIS_INT) != 0) {
+ if (max_ints != AT_MAX_INT_WORK)
+ handled = IRQ_HANDLED;
+ break;
+ }
+ /* link event */
+ if (status & ISR_GPHY)
+ atl1c_clear_phy_int(adapter);
+ /* Ack ISR */
+ AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+ if (status & ISR_RX_PKT) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
+ hw->intr_mask &= ~ISR_RX_PKT;
+ AT_WRITE_REG(hw, REG_IMR, hw->intr_mask);
+ __napi_schedule(&adapter->napi);
+ }
+ }
+ if (status & ISR_TX_PKT)
+ atl1c_clean_tx_irq(adapter, atl1c_trans_normal);
+
+ handled = IRQ_HANDLED;
+ /* check if PCIE PHY Link down */
+ if (status & ISR_ERROR) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "atl1c hardware error (status = 0x%x)\n",
+ status & ISR_ERROR);
+ /* reset MAC */
+ set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event);
+ schedule_work(&adapter->common_task);
+ return IRQ_HANDLED;
+ }
+
+ if (status & ISR_OVER)
+ if (netif_msg_intr(adapter))
+ dev_warn(&pdev->dev,
+ "TX/RX overflow (status = 0x%x)\n",
+ status & ISR_OVER);
+
+ /* link event */
+ if (status & (ISR_GPHY | ISR_MANUAL)) {
+ netdev->stats.tx_carrier_errors++;
+ atl1c_link_chg_event(adapter);
+ break;
+ }
+
+ } while (--max_ints > 0);
+ /* re-enable Interrupt*/
+ AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
+ return handled;
+}
+
+static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter,
+ struct sk_buff *skb, struct atl1c_recv_ret_status *prrs)
+{
+ /*
+ * The pid field in RRS in not correct sometimes, so we
+ * cannot figure out if the packet is fragmented or not,
+ * so we tell the KERNEL CHECKSUM_NONE
+ */
+ skb_checksum_none_assert(skb);
+}
+
+static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter)
+{
+ struct sk_buff *skb;
+ struct page *page;
+
+ if (adapter->rx_frag_size > PAGE_SIZE)
+ return netdev_alloc_skb(adapter->netdev,
+ adapter->rx_buffer_len);
+
+ page = adapter->rx_page;
+ if (!page) {
+ adapter->rx_page = page = alloc_page(GFP_ATOMIC);
+ if (unlikely(!page))
+ return NULL;
+ adapter->rx_page_offset = 0;
+ }
+
+ skb = build_skb(page_address(page) + adapter->rx_page_offset,
+ adapter->rx_frag_size);
+ if (likely(skb)) {
+ adapter->rx_page_offset += adapter->rx_frag_size;
+ if (adapter->rx_page_offset >= PAGE_SIZE)
+ adapter->rx_page = NULL;
+ else
+ get_page(page);
+ }
+ return skb;
+}
+
+static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter)
+{
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring;
+ struct pci_dev *pdev = adapter->pdev;
+ struct atl1c_buffer *buffer_info, *next_info;
+ struct sk_buff *skb;
+ void *vir_addr = NULL;
+ u16 num_alloc = 0;
+ u16 rfd_next_to_use, next_next;
+ struct atl1c_rx_free_desc *rfd_desc;
+ dma_addr_t mapping;
+
+ next_next = rfd_next_to_use = rfd_ring->next_to_use;
+ if (++next_next == rfd_ring->count)
+ next_next = 0;
+ buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+ next_info = &rfd_ring->buffer_info[next_next];
+
+ while (next_info->flags & ATL1C_BUFFER_FREE) {
+ rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
+
+ skb = atl1c_alloc_skb(adapter);
+ if (unlikely(!skb)) {
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev, "alloc rx buffer failed\n");
+ break;
+ }
+
+ /*
+ * Make buffer alignment 2 beyond a 16 byte boundary
+ * this will result in a 16 byte aligned IP header after
+ * the 14 byte MAC header is removed
+ */
+ vir_addr = skb->data;
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+ buffer_info->skb = skb;
+ buffer_info->length = adapter->rx_buffer_len;
+ mapping = pci_map_single(pdev, vir_addr,
+ buffer_info->length,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(pdev, mapping))) {
+ dev_kfree_skb(skb);
+ buffer_info->skb = NULL;
+ buffer_info->length = 0;
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE);
+ netif_warn(adapter, rx_err, adapter->netdev, "RX pci_map_single failed");
+ break;
+ }
+ buffer_info->dma = mapping;
+ ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+ ATL1C_PCIMAP_FROMDEVICE);
+ rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+ rfd_next_to_use = next_next;
+ if (++next_next == rfd_ring->count)
+ next_next = 0;
+ buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+ next_info = &rfd_ring->buffer_info[next_next];
+ num_alloc++;
+ }
+
+ if (num_alloc) {
+ /* TODO: update mailbox here */
+ wmb();
+ rfd_ring->next_to_use = rfd_next_to_use;
+ AT_WRITE_REG(&adapter->hw, REG_MB_RFD0_PROD_IDX,
+ rfd_ring->next_to_use & MB_RFDX_PROD_IDX_MASK);
+ }
+
+ return num_alloc;
+}
+
+static void atl1c_clean_rrd(struct atl1c_rrd_ring *rrd_ring,
+ struct atl1c_recv_ret_status *rrs, u16 num)
+{
+ u16 i;
+ /* the relationship between rrd and rfd is one map one */
+ for (i = 0; i < num; i++, rrs = ATL1C_RRD_DESC(rrd_ring,
+ rrd_ring->next_to_clean)) {
+ rrs->word3 &= ~RRS_RXD_UPDATED;
+ if (++rrd_ring->next_to_clean == rrd_ring->count)
+ rrd_ring->next_to_clean = 0;
+ }
+}
+
+static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring,
+ struct atl1c_recv_ret_status *rrs, u16 num)
+{
+ u16 i;
+ u16 rfd_index;
+ struct atl1c_buffer *buffer_info = rfd_ring->buffer_info;
+
+ rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+ RRS_RX_RFD_INDEX_MASK;
+ for (i = 0; i < num; i++) {
+ buffer_info[rfd_index].skb = NULL;
+ ATL1C_SET_BUFFER_STATE(&buffer_info[rfd_index],
+ ATL1C_BUFFER_FREE);
+ if (++rfd_index == rfd_ring->count)
+ rfd_index = 0;
+ }
+ rfd_ring->next_to_clean = rfd_index;
+}
+
+static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter,
+ int *work_done, int work_to_do)
+{
+ u16 rfd_num, rfd_index;
+ u16 count = 0;
+ u16 length;
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ struct atl1c_rfd_ring *rfd_ring = &adapter->rfd_ring;
+ struct atl1c_rrd_ring *rrd_ring = &adapter->rrd_ring;
+ struct sk_buff *skb;
+ struct atl1c_recv_ret_status *rrs;
+ struct atl1c_buffer *buffer_info;
+
+ while (1) {
+ if (*work_done >= work_to_do)
+ break;
+ rrs = ATL1C_RRD_DESC(rrd_ring, rrd_ring->next_to_clean);
+ if (likely(RRS_RXD_IS_VALID(rrs->word3))) {
+ rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) &
+ RRS_RX_RFD_CNT_MASK;
+ if (unlikely(rfd_num != 1))
+ /* TODO support mul rfd*/
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "Multi rfd not support yet!\n");
+ goto rrs_checked;
+ } else {
+ break;
+ }
+rrs_checked:
+ atl1c_clean_rrd(rrd_ring, rrs, rfd_num);
+ if (rrs->word3 & (RRS_RX_ERR_SUM | RRS_802_3_LEN_ERR)) {
+ atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "wrong packet! rrs word3 is %x\n",
+ rrs->word3);
+ continue;
+ }
+
+ length = le16_to_cpu((rrs->word3 >> RRS_PKT_SIZE_SHIFT) &
+ RRS_PKT_SIZE_MASK);
+ /* Good Receive */
+ if (likely(rfd_num == 1)) {
+ rfd_index = (rrs->word0 >> RRS_RX_RFD_INDEX_SHIFT) &
+ RRS_RX_RFD_INDEX_MASK;
+ buffer_info = &rfd_ring->buffer_info[rfd_index];
+ pci_unmap_single(pdev, buffer_info->dma,
+ buffer_info->length, PCI_DMA_FROMDEVICE);
+ skb = buffer_info->skb;
+ } else {
+ /* TODO */
+ if (netif_msg_rx_err(adapter))
+ dev_warn(&pdev->dev,
+ "Multi rfd not support yet!\n");
+ break;
+ }
+ atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+ skb_put(skb, length - ETH_FCS_LEN);
+ skb->protocol = eth_type_trans(skb, netdev);
+ atl1c_rx_checksum(adapter, skb, rrs);
+ if (rrs->word3 & RRS_VLAN_INS) {
+ u16 vlan;
+
+ AT_TAG_TO_VLAN(rrs->vlan_tag, vlan);
+ vlan = le16_to_cpu(vlan);
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan);
+ }
+ netif_receive_skb(skb);
+
+ (*work_done)++;
+ count++;
+ }
+ if (count)
+ atl1c_alloc_rx_buffer(adapter);
+}
+
+/**
+ * atl1c_clean - NAPI Rx polling callback
+ */
+static int atl1c_clean(struct napi_struct *napi, int budget)
+{
+ struct atl1c_adapter *adapter =
+ container_of(napi, struct atl1c_adapter, napi);
+ int work_done = 0;
+
+ /* Keep link state information with original netdev */
+ if (!netif_carrier_ok(adapter->netdev))
+ goto quit_polling;
+ /* just enable one RXQ */
+ atl1c_clean_rx_irq(adapter, &work_done, budget);
+
+ if (work_done < budget) {
+quit_polling:
+ napi_complete(napi);
+ adapter->hw.intr_mask |= ISR_RX_PKT;
+ AT_WRITE_REG(&adapter->hw, REG_IMR, adapter->hw.intr_mask);
+ }
+ return work_done;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void atl1c_netpoll(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ disable_irq(adapter->pdev->irq);
+ atl1c_intr(adapter->pdev->irq, netdev);
+ enable_irq(adapter->pdev->irq);
+}
+#endif
+
+static inline u16 atl1c_tpd_avail(struct atl1c_adapter *adapter, enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ u16 next_to_use = 0;
+ u16 next_to_clean = 0;
+
+ next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+ next_to_use = tpd_ring->next_to_use;
+
+ return (u16)(next_to_clean > next_to_use) ?
+ (next_to_clean - next_to_use - 1) :
+ (tpd_ring->count + next_to_clean - next_to_use - 1);
+}
+
+/*
+ * get next usable tpd
+ * Note: should call atl1c_tdp_avail to make sure
+ * there is enough tpd to use
+ */
+static struct atl1c_tpd_desc *atl1c_get_tpd(struct atl1c_adapter *adapter,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ struct atl1c_tpd_desc *tpd_desc;
+ u16 next_to_use = 0;
+
+ next_to_use = tpd_ring->next_to_use;
+ if (++tpd_ring->next_to_use == tpd_ring->count)
+ tpd_ring->next_to_use = 0;
+ tpd_desc = ATL1C_TPD_DESC(tpd_ring, next_to_use);
+ memset(tpd_desc, 0, sizeof(struct atl1c_tpd_desc));
+ return tpd_desc;
+}
+
+static struct atl1c_buffer *
+atl1c_get_tx_buffer(struct atl1c_adapter *adapter, struct atl1c_tpd_desc *tpd)
+{
+ struct atl1c_tpd_ring *tpd_ring = adapter->tpd_ring;
+
+ return &tpd_ring->buffer_info[tpd -
+ (struct atl1c_tpd_desc *)tpd_ring->desc];
+}
+
+/* Calculate the transmit packet descript needed*/
+static u16 atl1c_cal_tpd_req(const struct sk_buff *skb)
+{
+ u16 tpd_req;
+ u16 proto_hdr_len = 0;
+
+ tpd_req = skb_shinfo(skb)->nr_frags + 1;
+
+ if (skb_is_gso(skb)) {
+ proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ if (proto_hdr_len < skb_headlen(skb))
+ tpd_req++;
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+ tpd_req++;
+ }
+ return tpd_req;
+}
+
+static int atl1c_tso_csum(struct atl1c_adapter *adapter,
+ struct sk_buff *skb,
+ struct atl1c_tpd_desc **tpd,
+ enum atl1c_trans_queue type)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ unsigned short offload_type;
+ u8 hdr_len;
+ u32 real_len;
+
+ if (skb_is_gso(skb)) {
+ int err;
+
+ err = skb_cow_head(skb, 0);
+ if (err < 0)
+ return err;
+
+ offload_type = skb_shinfo(skb)->gso_type;
+
+ if (offload_type & SKB_GSO_TCPV4) {
+ real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
+ + ntohs(ip_hdr(skb)->tot_len));
+
+ if (real_len < skb->len)
+ pskb_trim(skb, real_len);
+
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (unlikely(skb->len == hdr_len)) {
+ /* only xsum need */
+ if (netif_msg_tx_queued(adapter))
+ dev_warn(&pdev->dev,
+ "IPV4 tso with zero data??\n");
+ goto check_sum;
+ } else {
+ ip_hdr(skb)->check = 0;
+ tcp_hdr(skb)->check = ~csum_tcpudp_magic(
+ ip_hdr(skb)->saddr,
+ ip_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ (*tpd)->word1 |= 1 << TPD_IPV4_PACKET_SHIFT;
+ }
+ }
+
+ if (offload_type & SKB_GSO_TCPV6) {
+ struct atl1c_tpd_ext_desc *etpd =
+ *(struct atl1c_tpd_ext_desc **)(tpd);
+
+ memset(etpd, 0, sizeof(struct atl1c_tpd_ext_desc));
+ *tpd = atl1c_get_tpd(adapter, type);
+ ipv6_hdr(skb)->payload_len = 0;
+ /* check payload == 0 byte ? */
+ hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+ if (unlikely(skb->len == hdr_len)) {
+ /* only xsum need */
+ if (netif_msg_tx_queued(adapter))
+ dev_warn(&pdev->dev,
+ "IPV6 tso with zero data??\n");
+ goto check_sum;
+ } else
+ tcp_hdr(skb)->check = ~csum_ipv6_magic(
+ &ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0);
+ etpd->word1 |= 1 << TPD_LSO_EN_SHIFT;
+ etpd->word1 |= 1 << TPD_LSO_VER_SHIFT;
+ etpd->pkt_len = cpu_to_le32(skb->len);
+ (*tpd)->word1 |= 1 << TPD_LSO_VER_SHIFT;
+ }
+
+ (*tpd)->word1 |= 1 << TPD_LSO_EN_SHIFT;
+ (*tpd)->word1 |= (skb_transport_offset(skb) & TPD_TCPHDR_OFFSET_MASK) <<
+ TPD_TCPHDR_OFFSET_SHIFT;
+ (*tpd)->word1 |= (skb_shinfo(skb)->gso_size & TPD_MSS_MASK) <<
+ TPD_MSS_SHIFT;
+ return 0;
+ }
+
+check_sum:
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+ u8 css, cso;
+ cso = skb_checksum_start_offset(skb);
+
+ if (unlikely(cso & 0x1)) {
+ if (netif_msg_tx_err(adapter))
+ dev_err(&adapter->pdev->dev,
+ "payload offset should not an event number\n");
+ return -1;
+ } else {
+ css = cso + skb->csum_offset;
+
+ (*tpd)->word1 |= ((cso >> 1) & TPD_PLOADOFFSET_MASK) <<
+ TPD_PLOADOFFSET_SHIFT;
+ (*tpd)->word1 |= ((css >> 1) & TPD_CCSUM_OFFSET_MASK) <<
+ TPD_CCSUM_OFFSET_SHIFT;
+ (*tpd)->word1 |= 1 << TPD_CCSUM_EN_SHIFT;
+ }
+ }
+ return 0;
+}
+
+static void atl1c_tx_rollback(struct atl1c_adapter *adpt,
+ struct atl1c_tpd_desc *first_tpd,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adpt->tpd_ring[type];
+ struct atl1c_buffer *buffer_info;
+ struct atl1c_tpd_desc *tpd;
+ u16 first_index, index;
+
+ first_index = first_tpd - (struct atl1c_tpd_desc *)tpd_ring->desc;
+ index = first_index;
+ while (index != tpd_ring->next_to_use) {
+ tpd = ATL1C_TPD_DESC(tpd_ring, index);
+ buffer_info = &tpd_ring->buffer_info[index];
+ atl1c_clean_buffer(adpt->pdev, buffer_info);
+ memset(tpd, 0, sizeof(struct atl1c_tpd_desc));
+ if (++index == tpd_ring->count)
+ index = 0;
+ }
+ tpd_ring->next_to_use = first_index;
+}
+
+static int atl1c_tx_map(struct atl1c_adapter *adapter,
+ struct sk_buff *skb, struct atl1c_tpd_desc *tpd,
+ enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_desc *use_tpd = NULL;
+ struct atl1c_buffer *buffer_info = NULL;
+ u16 buf_len = skb_headlen(skb);
+ u16 map_len = 0;
+ u16 mapped_len = 0;
+ u16 hdr_len = 0;
+ u16 nr_frags;
+ u16 f;
+ int tso;
+
+ nr_frags = skb_shinfo(skb)->nr_frags;
+ tso = (tpd->word1 >> TPD_LSO_EN_SHIFT) & TPD_LSO_EN_MASK;
+ if (tso) {
+ /* TSO */
+ map_len = hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ use_tpd = tpd;
+
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = map_len;
+ buffer_info->dma = pci_map_single(adapter->pdev,
+ skb->data, hdr_len, PCI_DMA_TODEVICE);
+ if (unlikely(pci_dma_mapping_error(adapter->pdev,
+ buffer_info->dma)))
+ goto err_dma;
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+ ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+ ATL1C_PCIMAP_TODEVICE);
+ mapped_len += map_len;
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ if (mapped_len < buf_len) {
+ /* mapped_len == 0, means we should use the first tpd,
+ which is given by caller */
+ if (mapped_len == 0)
+ use_tpd = tpd;
+ else {
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+ }
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = buf_len - mapped_len;
+ buffer_info->dma =
+ pci_map_single(adapter->pdev, skb->data + mapped_len,
+ buffer_info->length, PCI_DMA_TODEVICE);
+ if (unlikely(pci_dma_mapping_error(adapter->pdev,
+ buffer_info->dma)))
+ goto err_dma;
+
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+ ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE,
+ ATL1C_PCIMAP_TODEVICE);
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ for (f = 0; f < nr_frags; f++) {
+ struct skb_frag_struct *frag;
+
+ frag = &skb_shinfo(skb)->frags[f];
+
+ use_tpd = atl1c_get_tpd(adapter, type);
+ memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc));
+
+ buffer_info = atl1c_get_tx_buffer(adapter, use_tpd);
+ buffer_info->length = skb_frag_size(frag);
+ buffer_info->dma = skb_frag_dma_map(&adapter->pdev->dev,
+ frag, 0,
+ buffer_info->length,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma))
+ goto err_dma;
+
+ ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY);
+ ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE,
+ ATL1C_PCIMAP_TODEVICE);
+ use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
+ use_tpd->buffer_len = cpu_to_le16(buffer_info->length);
+ }
+
+ /* The last tpd */
+ use_tpd->word1 |= 1 << TPD_EOP_SHIFT;
+ /* The last buffer info contain the skb address,
+ so it will be free after unmap */
+ buffer_info->skb = skb;
+
+ return 0;
+
+err_dma:
+ buffer_info->dma = 0;
+ buffer_info->length = 0;
+ return -1;
+}
+
+static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
+ struct atl1c_tpd_desc *tpd, enum atl1c_trans_queue type)
+{
+ struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type];
+ u16 reg;
+
+ reg = type == atl1c_trans_high ? REG_TPD_PRI1_PIDX : REG_TPD_PRI0_PIDX;
+ AT_WRITE_REGW(&adapter->hw, reg, tpd_ring->next_to_use);
+}
+
+static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ unsigned long flags;
+ u16 tpd_req = 1;
+ struct atl1c_tpd_desc *tpd;
+ enum atl1c_trans_queue type = atl1c_trans_normal;
+
+ if (test_bit(__AT_DOWN, &adapter->flags)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ tpd_req = atl1c_cal_tpd_req(skb);
+ if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
+ if (netif_msg_pktdata(adapter))
+ dev_info(&adapter->pdev->dev, "tx locked\n");
+ return NETDEV_TX_LOCKED;
+ }
+
+ if (atl1c_tpd_avail(adapter, type) < tpd_req) {
+ /* no enough descriptor, just stop queue */
+ netif_stop_queue(netdev);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+
+ tpd = atl1c_get_tpd(adapter, type);
+
+ /* do TSO and check sum */
+ if (atl1c_tso_csum(adapter, skb, &tpd, type) != 0) {
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (unlikely(vlan_tx_tag_present(skb))) {
+ u16 vlan = vlan_tx_tag_get(skb);
+ __le16 tag;
+
+ vlan = cpu_to_le16(vlan);
+ AT_VLAN_TO_TAG(vlan, tag);
+ tpd->word1 |= 1 << TPD_INS_VTAG_SHIFT;
+ tpd->vlan_tag = tag;
+ }
+
+ if (skb_network_offset(skb) != ETH_HLEN)
+ tpd->word1 |= 1 << TPD_ETH_TYPE_SHIFT; /* Ethernet frame */
+
+ if (atl1c_tx_map(adapter, skb, tpd, type) < 0) {
+ netif_info(adapter, tx_done, adapter->netdev,
+ "tx-skb droppted due to dma error\n");
+ /* roll back tpd/buffer */
+ atl1c_tx_rollback(adapter, tpd, type);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ dev_kfree_skb_any(skb);
+ } else {
+ atl1c_tx_queue(adapter, skb, tpd, type);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
+ }
+
+ return NETDEV_TX_OK;
+}
+
+static void atl1c_free_irq(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ free_irq(adapter->pdev->irq, netdev);
+
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
+}
+
+static int atl1c_request_irq(struct atl1c_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
+ int flags = 0;
+ int err = 0;
+
+ adapter->have_msi = true;
+ err = pci_enable_msi(adapter->pdev);
+ if (err) {
+ if (netif_msg_ifup(adapter))
+ dev_err(&pdev->dev,
+ "Unable to allocate MSI interrupt Error: %d\n",
+ err);
+ adapter->have_msi = false;
+ }
+
+ if (!adapter->have_msi)
+ flags |= IRQF_SHARED;
+ err = request_irq(adapter->pdev->irq, atl1c_intr, flags,
+ netdev->name, netdev);
+ if (err) {
+ if (netif_msg_ifup(adapter))
+ dev_err(&pdev->dev,
+ "Unable to allocate interrupt Error: %d\n",
+ err);
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
+ return err;
+ }
+ if (netif_msg_ifup(adapter))
+ dev_dbg(&pdev->dev, "atl1c_request_irq OK\n");
+ return err;
+}
+
+
+static void atl1c_reset_dma_ring(struct atl1c_adapter *adapter)
+{
+ /* release tx-pending skbs and reset tx/rx ring index */
+ atl1c_clean_tx_ring(adapter, atl1c_trans_normal);
+ atl1c_clean_tx_ring(adapter, atl1c_trans_high);
+ atl1c_clean_rx_ring(adapter);
+}
+
+static int atl1c_up(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int err;
+
+ netif_carrier_off(netdev);
+
+ err = atl1c_configure(adapter);
+ if (unlikely(err))
+ goto err_up;
+
+ err = atl1c_request_irq(adapter);
+ if (unlikely(err))
+ goto err_up;
+
+ atl1c_check_link_status(adapter);
+ clear_bit(__AT_DOWN, &adapter->flags);
+ napi_enable(&adapter->napi);
+ atl1c_irq_enable(adapter);
+ netif_start_queue(netdev);
+ return err;
+
+err_up:
+ atl1c_clean_rx_ring(adapter);
+ return err;
+}
+
+static void atl1c_down(struct atl1c_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ atl1c_del_timer(adapter);
+ adapter->work_event = 0; /* clear all event */
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ set_bit(__AT_DOWN, &adapter->flags);
+ netif_carrier_off(netdev);
+ napi_disable(&adapter->napi);
+ atl1c_irq_disable(adapter);
+ atl1c_free_irq(adapter);
+ /* disable ASPM if device inactive */
+ atl1c_disable_l0s_l1(&adapter->hw);
+ /* reset MAC to disable all RX/TX */
+ atl1c_reset_mac(&adapter->hw);
+ msleep(1);
+
+ adapter->link_speed = SPEED_0;
+ adapter->link_duplex = -1;
+ atl1c_reset_dma_ring(adapter);
+}
+
+/**
+ * atl1c_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP). At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ */
+static int atl1c_open(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ int err;
+
+ /* disallow open during test */
+ if (test_bit(__AT_TESTING, &adapter->flags))
+ return -EBUSY;
+
+ /* allocate rx/tx dma buffer & descriptors */
+ err = atl1c_setup_ring_resources(adapter);
+ if (unlikely(err))
+ return err;
+
+ err = atl1c_up(adapter);
+ if (unlikely(err))
+ goto err_up;
+
+ return 0;
+
+err_up:
+ atl1c_free_irq(adapter);
+ atl1c_free_ring_resources(adapter);
+ atl1c_reset_mac(&adapter->hw);
+ return err;
+}
+
+/**
+ * atl1c_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS. The hardware is still under the drivers control, but
+ * needs to be disabled. A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ */
+static int atl1c_close(struct net_device *netdev)
+{
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+ set_bit(__AT_DOWN, &adapter->flags);
+ cancel_work_sync(&adapter->common_task);
+ atl1c_down(adapter);
+ atl1c_free_ring_resources(adapter);
+ return 0;
+}
+
+static int atl1c_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+ struct atl1c_hw *hw = &adapter->hw;
+ u32 wufc = adapter->wol;
+
+ atl1c_disable_l0s_l1(hw);
+ if (netif_running(netdev)) {
+ WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+ atl1c_down(adapter);
+ }
+ netif_device_detach(netdev);
+
+ if (wufc)
+ if (atl1c_phy_to_ps_link(hw) != 0)
+ dev_dbg(&pdev->dev, "phy power saving failed");
+
+ atl1c_power_saving(hw, wufc);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int atl1c_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+ atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE);
+
+ atl1c_phy_reset(&adapter->hw);
+ atl1c_reset_mac(&adapter->hw);
+ atl1c_phy_init(&adapter->hw);
+
+#if 0
+ AT_READ_REG(&adapter->hw, REG_PM_CTRLSTAT, &pm_data);
+ pm_data &= ~PM_CTRLSTAT_PME_EN;
+ AT_WRITE_REG(&adapter->hw, REG_PM_CTRLSTAT, pm_data);
+#endif
+
+ netif_device_attach(netdev);
+ if (netif_running(netdev))
+ atl1c_up(adapter);
+
+ return 0;
+}
+#endif
+
+static void atl1c_shutdown(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ atl1c_suspend(&pdev->dev);
+ pci_wake_from_d3(pdev, adapter->wol);
+ pci_set_power_state(pdev, PCI_D3hot);
+}
+
+static const struct net_device_ops atl1c_netdev_ops = {
+ .ndo_open = atl1c_open,
+ .ndo_stop = atl1c_close,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_start_xmit = atl1c_xmit_frame,
+ .ndo_set_mac_address = atl1c_set_mac_addr,
+ .ndo_set_rx_mode = atl1c_set_multi,
+ .ndo_change_mtu = atl1c_change_mtu,
+ .ndo_fix_features = atl1c_fix_features,
+ .ndo_set_features = atl1c_set_features,
+ .ndo_do_ioctl = atl1c_ioctl,
+ .ndo_tx_timeout = atl1c_tx_timeout,
+ .ndo_get_stats = atl1c_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl1c_netpoll,
+#endif
+};
+
+static int atl1c_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
+{
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ pci_set_drvdata(pdev, netdev);
+
+ netdev->netdev_ops = &atl1c_netdev_ops;
+ netdev->watchdog_timeo = AT_TX_WATCHDOG;
+ atl1c_set_ethtool_ops(netdev);
+
+ /* TODO: add when ready */
+ netdev->hw_features = NETIF_F_SG |
+ NETIF_F_HW_CSUM |
+ NETIF_F_HW_VLAN_CTAG_RX |
+ NETIF_F_TSO |
+ NETIF_F_TSO6;
+ netdev->features = netdev->hw_features |
+ NETIF_F_HW_VLAN_CTAG_TX;
+ return 0;
+}
+
+/**
+ * atl1c_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl1c_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl1c_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ */
+static int atl1c_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct net_device *netdev;
+ struct atl1c_adapter *adapter;
+ static int cards_found;
+
+ int err = 0;
+
+ /* enable device (incl. PCI PM wakeup and hotplug setup) */
+ err = pci_enable_device_mem(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ return err;
+ }
+
+ /*
+ * The atl1c chip can DMA to 64-bit addresses, but it uses a single
+ * shared register for the high 32 bits, so only a single, aligned,
+ * 4 GB physical address range can be used at a time.
+ *
+ * Supporting 64-bit DMA on this hardware is more trouble than it's
+ * worth. It is far easier to limit to 32-bit DMA than update
+ * various kernel subsystems to support the mechanics required by a
+ * fixed-high-32-bit system.
+ */
+ if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+ (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
+ dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
+ goto err_dma;
+ }
+
+ err = pci_request_regions(pdev, atl1c_driver_name);
+ if (err) {
+ dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+ goto err_pci_reg;
+ }
+
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev(sizeof(struct atl1c_adapter));
+ if (netdev == NULL) {
+ err = -ENOMEM;
+ goto err_alloc_etherdev;
+ }
+
+ err = atl1c_init_netdev(netdev, pdev);
+ if (err) {
+ dev_err(&pdev->dev, "init netdevice failed\n");
+ goto err_init_netdev;
+ }
+ adapter = netdev_priv(netdev);
+ adapter->bd_number = cards_found;
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->hw.adapter = adapter;
+ adapter->msg_enable = netif_msg_init(-1, atl1c_default_msg);
+ adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+ if (!adapter->hw.hw_addr) {
+ err = -EIO;
+ dev_err(&pdev->dev, "cannot map device registers\n");
+ goto err_ioremap;
+ }
+
+ /* init mii data */
+ adapter->mii.dev = netdev;
+ adapter->mii.mdio_read = atl1c_mdio_read;
+ adapter->mii.mdio_write = atl1c_mdio_write;
+ adapter->mii.phy_id_mask = 0x1f;
+ adapter->mii.reg_num_mask = MDIO_CTRL_REG_MASK;
+ netif_napi_add(netdev, &adapter->napi, atl1c_clean, 64);
+ setup_timer(&adapter->phy_config_timer, atl1c_phy_config,
+ (unsigned long)adapter);
+ /* setup the private structure */
+ err = atl1c_sw_init(adapter);
+ if (err) {
+ dev_err(&pdev->dev, "net device private data init failed\n");
+ goto err_sw_init;
+ }
+ atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE);
+
+ /* Init GPHY as early as possible due to power saving issue */
+ atl1c_phy_reset(&adapter->hw);
+
+ err = atl1c_reset_mac(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ goto err_reset;
+ }
+
+ /* reset the controller to
+ * put the device in a known good starting state */
+ err = atl1c_phy_init(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ goto err_reset;
+ }
+ if (atl1c_read_mac_addr(&adapter->hw)) {
+ /* got a random MAC address, set NET_ADDR_RANDOM to netdev */
+ netdev->addr_assign_type = NET_ADDR_RANDOM;
+ }
+ memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+ if (netif_msg_probe(adapter))
+ dev_dbg(&pdev->dev, "mac address : %pM\n",
+ adapter->hw.mac_addr);
+
+ atl1c_hw_set_mac_addr(&adapter->hw, adapter->hw.mac_addr);
+ INIT_WORK(&adapter->common_task, atl1c_common_task);
+ adapter->work_event = 0;
+ err = register_netdev(netdev);
+ if (err) {
+ dev_err(&pdev->dev, "register netdevice failed\n");
+ goto err_register;
+ }
+
+ if (netif_msg_probe(adapter))
+ dev_info(&pdev->dev, "version %s\n", ATL1C_DRV_VERSION);
+ cards_found++;
+ return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+ iounmap(adapter->hw.hw_addr);
+err_init_netdev:
+err_ioremap:
+ free_netdev(netdev);
+err_alloc_etherdev:
+ pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+ pci_disable_device(pdev);
+ return err;
+}
+
+/**
+ * atl1c_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl1c_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device. The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ */
+static void atl1c_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ unregister_netdev(netdev);
+ /* restore permanent address */
+ atl1c_hw_set_mac_addr(&adapter->hw, adapter->hw.perm_mac_addr);
+ atl1c_phy_disable(&adapter->hw);
+
+ iounmap(adapter->hw.hw_addr);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ free_netdev(netdev);
+}
+
+/**
+ * atl1c_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ netif_device_detach(netdev);
+
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
+ if (netif_running(netdev))
+ atl1c_down(adapter);
+
+ pci_disable_device(pdev);
+
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * atl1c_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t atl1c_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (pci_enable_device(pdev)) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Cannot re-enable PCI device after reset\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ atl1c_reset_mac(&adapter->hw);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * atl1c_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the atl1c_resume routine.
+ */
+static void atl1c_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1c_adapter *adapter = netdev_priv(netdev);
+
+ if (netif_running(netdev)) {
+ if (atl1c_up(adapter)) {
+ if (netif_msg_hw(adapter))
+ dev_err(&pdev->dev,
+ "Cannot bring device back up after reset\n");
+ return;
+ }
+ }
+
+ netif_device_attach(netdev);
+}
+
+static const struct pci_error_handlers atl1c_err_handler = {
+ .error_detected = atl1c_io_error_detected,
+ .slot_reset = atl1c_io_slot_reset,
+ .resume = atl1c_io_resume,
+};
+
+static SIMPLE_DEV_PM_OPS(atl1c_pm_ops, atl1c_suspend, atl1c_resume);
+
+static struct pci_driver atl1c_driver = {
+ .name = atl1c_driver_name,
+ .id_table = atl1c_pci_tbl,
+ .probe = atl1c_probe,
+ .remove = atl1c_remove,
+ .shutdown = atl1c_shutdown,
+ .err_handler = &atl1c_err_handler,
+ .driver.pm = &atl1c_pm_ops,
+};
+
+module_pci_driver(atl1c_driver);
diff --git a/drivers/net/atl1e/Makefile b/drivers/net/ethernet/atheros/atl1e/Makefile
index bc11be824e7..bc11be824e7 100644
--- a/drivers/net/atl1e/Makefile
+++ b/drivers/net/ethernet/atheros/atl1e/Makefile
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h
index b645fa0f3f6..0212dac7e23 100644
--- a/drivers/net/atl1e/atl1e.h
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h
@@ -23,8 +23,7 @@
#ifndef _ATL1E_H_
#define _ATL1E_H_
-#include <linux/version.h>
-#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -46,7 +45,6 @@
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/tcp.h>
-#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/workqueue.h>
@@ -187,7 +185,7 @@ struct atl1e_tpd_desc {
/* how about 0x2000 */
#define MAX_TX_BUF_LEN 0x2000
#define MAX_TX_BUF_SHIFT 13
-/*#define MAX_TX_BUF_LEN 0x3000 */
+#define MAX_TSO_SEG_SIZE 0x3c00
/* rrs word 1 bit 0:31 */
#define RRS_RX_CSUM_MASK 0xFFFF
@@ -378,10 +376,19 @@ struct atl1e_hw {
*/
struct atl1e_tx_buffer {
struct sk_buff *skb;
+ u16 flags;
+#define ATL1E_TX_PCIMAP_SINGLE 0x0001
+#define ATL1E_TX_PCIMAP_PAGE 0x0002
+#define ATL1E_TX_PCIMAP_TYPE_MASK 0x0003
u16 length;
dma_addr_t dma;
};
+#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do { \
+ ((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK; \
+ ((tx_buff)->flags) |= (type); \
+ } while (0)
+
struct atl1e_rx_page {
dma_addr_t dma; /* receive rage DMA address */
u8 *addr; /* receive rage virtual address */
@@ -425,14 +432,11 @@ struct atl1e_rx_ring {
struct atl1e_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
- struct vlan_group *vlgrp;
struct napi_struct napi;
struct mii_if_info mii; /* MII interface info */
struct atl1e_hw hw;
struct atl1e_hw_stats hw_stats;
- struct net_device_stats net_stats;
- bool have_msi;
u32 wol;
u16 link_speed;
u16 link_duplex;
@@ -449,7 +453,7 @@ struct atl1e_adapter {
/* All Descriptor memory */
dma_addr_t ring_dma;
void *ring_vir_addr;
- int ring_size;
+ u32 ring_size;
struct atl1e_tx_ring tx_ring;
struct atl1e_rx_ring rx_ring;
@@ -494,10 +498,10 @@ struct atl1e_adapter {
extern char atl1e_driver_name[];
extern char atl1e_driver_version[];
-extern void atl1e_check_options(struct atl1e_adapter *adapter);
-extern int atl1e_up(struct atl1e_adapter *adapter);
-extern void atl1e_down(struct atl1e_adapter *adapter);
-extern void atl1e_reinit_locked(struct atl1e_adapter *adapter);
-extern s32 atl1e_reset_hw(struct atl1e_hw *hw);
-extern void atl1e_set_ethtool_ops(struct net_device *netdev);
+void atl1e_check_options(struct atl1e_adapter *adapter);
+int atl1e_up(struct atl1e_adapter *adapter);
+void atl1e_down(struct atl1e_adapter *adapter);
+void atl1e_reinit_locked(struct atl1e_adapter *adapter);
+s32 atl1e_reset_hw(struct atl1e_hw *hw);
+void atl1e_set_ethtool_ops(struct net_device *netdev);
#endif /* _ATL1_E_H_ */
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
index 619c6583e1a..1be072f4afc 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c
@@ -22,6 +22,7 @@
#include <linux/netdevice.h>
#include <linux/ethtool.h>
+#include <linux/slab.h>
#include "atl1e.h"
@@ -50,14 +51,14 @@ static int atl1e_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
- ecmd->speed = adapter->link_speed;
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
- ecmd->duplex = -1;
+ ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+ ecmd->duplex = DUPLEX_UNKNOWN;
}
ecmd->autoneg = AUTONEG_ENABLE;
@@ -94,18 +95,18 @@ static int atl1e_set_settings(struct net_device *netdev,
ecmd->advertising = hw->autoneg_advertised |
ADVERTISED_TP | ADVERTISED_Autoneg;
- adv4 = hw->mii_autoneg_adv_reg & ~MII_AR_SPEED_MASK;
+ adv4 = hw->mii_autoneg_adv_reg & ~ADVERTISE_ALL;
adv9 = hw->mii_1000t_ctrl_reg & ~MII_AT001_CR_1000T_SPEED_MASK;
if (hw->autoneg_advertised & ADVERTISE_10_HALF)
- adv4 |= MII_AR_10T_HD_CAPS;
+ adv4 |= ADVERTISE_10HALF;
if (hw->autoneg_advertised & ADVERTISE_10_FULL)
- adv4 |= MII_AR_10T_FD_CAPS;
+ adv4 |= ADVERTISE_10FULL;
if (hw->autoneg_advertised & ADVERTISE_100_HALF)
- adv4 |= MII_AR_100TX_HD_CAPS;
+ adv4 |= ADVERTISE_100HALF;
if (hw->autoneg_advertised & ADVERTISE_100_FULL)
- adv4 |= MII_AR_100TX_FD_CAPS;
+ adv4 |= ADVERTISE_100FULL;
if (hw->autoneg_advertised & ADVERTISE_1000_FULL)
- adv9 |= MII_AT001_CR_1000T_FD_CAPS;
+ adv9 |= ADVERTISE_1000FULL;
if (adv4 != hw->mii_autoneg_adv_reg ||
adv9 != hw->mii_1000t_ctrl_reg) {
@@ -131,11 +132,6 @@ static int atl1e_set_settings(struct net_device *netdev,
return 0;
}
-static u32 atl1e_get_tx_csum(struct net_device *netdev)
-{
- return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
static u32 atl1e_get_msglevel(struct net_device *netdev)
{
#ifdef DBG
@@ -145,10 +141,6 @@ static u32 atl1e_get_msglevel(struct net_device *netdev)
#endif
}
-static void atl1e_set_msglevel(struct net_device *netdev, u32 data)
-{
-}
-
static int atl1e_get_regs_len(struct net_device *netdev)
{
return AT_REGS_LEN * sizeof(u32);
@@ -276,7 +268,7 @@ static int atl1e_set_eeprom(struct net_device *netdev,
if (eeprom_buff == NULL)
return -ENOMEM;
- ptr = (u32 *)eeprom_buff;
+ ptr = eeprom_buff;
if (eeprom->offset & 3) {
/* need read/modify/write of first changed EEPROM word */
@@ -318,10 +310,12 @@ static void atl1e_get_drvinfo(struct net_device *netdev,
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
- strncpy(drvinfo->driver, atl1e_driver_name, 32);
- strncpy(drvinfo->version, atl1e_driver_version, 32);
- strncpy(drvinfo->fw_version, "L1e", 32);
- strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+ strlcpy(drvinfo->driver, atl1e_driver_name, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, atl1e_driver_version,
+ sizeof(drvinfo->version));
+ strlcpy(drvinfo->fw_version, "L1e", sizeof(drvinfo->fw_version));
+ strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = atl1e_get_regs_len(netdev);
@@ -346,8 +340,6 @@ static void atl1e_get_wol(struct net_device *netdev,
wol->wolopts |= WAKE_MAGIC;
if (adapter->wol & AT_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
-
- return;
}
static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
@@ -365,6 +357,8 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
if (wol->wolopts & WAKE_PHY)
adapter->wol |= AT_WUFC_LNKC;
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
return 0;
}
@@ -376,7 +370,7 @@ static int atl1e_nway_reset(struct net_device *netdev)
return 0;
}
-static struct ethtool_ops atl1e_ethtool_ops = {
+static const struct ethtool_ops atl1e_ethtool_ops = {
.get_settings = atl1e_get_settings,
.set_settings = atl1e_set_settings,
.get_drvinfo = atl1e_get_drvinfo,
@@ -385,21 +379,14 @@ static struct ethtool_ops atl1e_ethtool_ops = {
.get_wol = atl1e_get_wol,
.set_wol = atl1e_set_wol,
.get_msglevel = atl1e_get_msglevel,
- .set_msglevel = atl1e_set_msglevel,
.nway_reset = atl1e_nway_reset,
.get_link = ethtool_op_get_link,
.get_eeprom_len = atl1e_get_eeprom_len,
.get_eeprom = atl1e_get_eeprom,
.set_eeprom = atl1e_set_eeprom,
- .get_tx_csum = atl1e_get_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
- .get_tso = ethtool_op_get_tso,
-#endif
};
void atl1e_set_ethtool_ops(struct net_device *netdev)
{
- SET_ETHTOOL_OPS(netdev, &atl1e_ethtool_ops);
+ netdev->ethtool_ops = &atl1e_ethtool_ops;
}
diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c
index 949e75358bf..923063d2e5b 100644
--- a/drivers/net/atl1e/atl1e_hw.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.c
@@ -163,9 +163,6 @@ int atl1e_read_mac_addr(struct atl1e_hw *hw)
* atl1e_hash_mc_addr
* purpose
* set hash value for a multicast address
- * hash calcu processing :
- * 1. calcu 32bit CRC for multicast address
- * 2. reverse crc with MSB to LSB
*/
u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
{
@@ -174,7 +171,6 @@ u32 atl1e_hash_mc_addr(struct atl1e_hw *hw, u8 *mc_addr)
int i;
crc32 = ether_crc_le(6, mc_addr);
- crc32 = ~crc32;
for (i = 0; i < 32; i++)
value |= (((crc32 >> i) & 1) << (31 - i));
@@ -322,7 +318,7 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
* Advertisement Register (Address 4) and the 1000 mb speed bits in
* the 1000Base-T control Register (Address 9).
*/
- mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
+ mii_autoneg_adv_reg &= ~ADVERTISE_ALL;
mii_1000t_ctrl_reg &= ~MII_AT001_CR_1000T_SPEED_MASK;
/*
@@ -331,44 +327,37 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
*/
switch (hw->media_type) {
case MEDIA_TYPE_AUTO_SENSOR:
- mii_autoneg_adv_reg |= (MII_AR_10T_HD_CAPS |
- MII_AR_10T_FD_CAPS |
- MII_AR_100TX_HD_CAPS |
- MII_AR_100TX_FD_CAPS);
- hw->autoneg_advertised = ADVERTISE_10_HALF |
- ADVERTISE_10_FULL |
- ADVERTISE_100_HALF |
- ADVERTISE_100_FULL;
+ mii_autoneg_adv_reg |= ADVERTISE_ALL;
+ hw->autoneg_advertised = ADVERTISE_ALL;
if (hw->nic_type == athr_l1e) {
- mii_1000t_ctrl_reg |=
- MII_AT001_CR_1000T_FD_CAPS;
+ mii_1000t_ctrl_reg |= ADVERTISE_1000FULL;
hw->autoneg_advertised |= ADVERTISE_1000_FULL;
}
break;
case MEDIA_TYPE_100M_FULL:
- mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
+ mii_autoneg_adv_reg |= ADVERTISE_100FULL;
hw->autoneg_advertised = ADVERTISE_100_FULL;
break;
case MEDIA_TYPE_100M_HALF:
- mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
+ mii_autoneg_adv_reg |= ADVERTISE_100_HALF;
hw->autoneg_advertised = ADVERTISE_100_HALF;
break;
case MEDIA_TYPE_10M_FULL:
- mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
+ mii_autoneg_adv_reg |= ADVERTISE_10_FULL;
hw->autoneg_advertised = ADVERTISE_10_FULL;
break;
default:
- mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
+ mii_autoneg_adv_reg |= ADVERTISE_10_HALF;
hw->autoneg_advertised = ADVERTISE_10_HALF;
break;
}
/* flow control fixed to enable all */
- mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
+ mii_autoneg_adv_reg |= (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP);
hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
hw->mii_1000t_ctrl_reg = mii_1000t_ctrl_reg;
@@ -378,7 +367,7 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
return ret_val;
if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
- ret_val = atl1e_write_phy_reg(hw, MII_AT001_CR,
+ ret_val = atl1e_write_phy_reg(hw, MII_CTRL1000,
mii_1000t_ctrl_reg);
if (ret_val)
return ret_val;
@@ -397,12 +386,11 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
*/
int atl1e_phy_commit(struct atl1e_hw *hw)
{
- struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
- struct pci_dev *pdev = adapter->pdev;
+ struct atl1e_adapter *adapter = hw->adapter;
int ret_val;
u16 phy_data;
- phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG;
+ phy_data = BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART;
ret_val = atl1e_write_phy_reg(hw, MII_BMCR, phy_data);
if (ret_val) {
@@ -419,20 +407,19 @@ int atl1e_phy_commit(struct atl1e_hw *hw)
}
if (0 != (val & (MDIO_START | MDIO_BUSY))) {
- dev_err(&pdev->dev,
- "pcie linkdown at least for 25ms\n");
+ netdev_err(adapter->netdev,
+ "pcie linkdown at least for 25ms\n");
return ret_val;
}
- dev_err(&pdev->dev, "pcie linkup after %d ms\n", i);
+ netdev_err(adapter->netdev, "pcie linkup after %d ms\n", i);
}
return 0;
}
int atl1e_phy_init(struct atl1e_hw *hw)
{
- struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
- struct pci_dev *pdev = adapter->pdev;
+ struct atl1e_adapter *adapter = hw->adapter;
s32 ret_val;
u16 phy_val;
@@ -496,20 +483,22 @@ int atl1e_phy_init(struct atl1e_hw *hw)
/*Enable PHY LinkChange Interrupt */
ret_val = atl1e_write_phy_reg(hw, MII_INT_CTRL, 0xC00);
if (ret_val) {
- dev_err(&pdev->dev, "Error enable PHY linkChange Interrupt\n");
+ netdev_err(adapter->netdev,
+ "Error enable PHY linkChange Interrupt\n");
return ret_val;
}
/* setup AutoNeg parameters */
ret_val = atl1e_phy_setup_autoneg_adv(hw);
if (ret_val) {
- dev_err(&pdev->dev, "Error Setting up Auto-Negotiation\n");
+ netdev_err(adapter->netdev,
+ "Error Setting up Auto-Negotiation\n");
return ret_val;
}
/* SW.Reset & En-Auto-Neg to restart Auto-Neg*/
- dev_dbg(&pdev->dev, "Restarting Auto-Neg");
+ netdev_dbg(adapter->netdev, "Restarting Auto-Negotiation\n");
ret_val = atl1e_phy_commit(hw);
if (ret_val) {
- dev_err(&pdev->dev, "Error Resetting the phy");
+ netdev_err(adapter->netdev, "Error resetting the phy\n");
return ret_val;
}
@@ -525,7 +514,7 @@ int atl1e_phy_init(struct atl1e_hw *hw)
*/
int atl1e_reset_hw(struct atl1e_hw *hw)
{
- struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
+ struct atl1e_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
u32 idle_status_data = 0;
@@ -563,9 +552,8 @@ int atl1e_reset_hw(struct atl1e_hw *hw)
}
if (timeout >= AT_HW_MAX_IDLE_DELAY) {
- dev_err(&pdev->dev,
- "MAC state machine cann't be idle since"
- " disabled for 10ms second\n");
+ netdev_err(adapter->netdev,
+ "MAC state machine can't be idle since disabled for 10ms second\n");
return AT_ERR_TIMEOUT;
}
@@ -650,15 +638,14 @@ int atl1e_restart_autoneg(struct atl1e_hw *hw)
return err;
if (hw->nic_type == athr_l1e || hw->nic_type == athr_l2e_revA) {
- err = atl1e_write_phy_reg(hw, MII_AT001_CR,
+ err = atl1e_write_phy_reg(hw, MII_CTRL1000,
hw->mii_1000t_ctrl_reg);
if (err)
return err;
}
err = atl1e_write_phy_reg(hw, MII_BMCR,
- MII_CR_RESET | MII_CR_AUTO_NEG_EN |
- MII_CR_RESTART_AUTO_NEG);
+ BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
return err;
}
diff --git a/drivers/net/atl1e/atl1e_hw.h b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.h
index 5ea2f4d86cf..74df16aef79 100644
--- a/drivers/net/atl1e/atl1e_hw.h
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_hw.h
@@ -629,127 +629,24 @@ s32 atl1e_restart_autoneg(struct atl1e_hw *hw);
/***************************** MII definition ***************************************/
/* PHY Common Register */
-#define MII_BMCR 0x00
-#define MII_BMSR 0x01
-#define MII_PHYSID1 0x02
-#define MII_PHYSID2 0x03
-#define MII_ADVERTISE 0x04
-#define MII_LPA 0x05
-#define MII_EXPANSION 0x06
-#define MII_AT001_CR 0x09
-#define MII_AT001_SR 0x0A
-#define MII_AT001_ESR 0x0F
#define MII_AT001_PSCR 0x10
#define MII_AT001_PSSR 0x11
#define MII_INT_CTRL 0x12
#define MII_INT_STATUS 0x13
#define MII_SMARTSPEED 0x14
-#define MII_RERRCOUNTER 0x15
-#define MII_SREVISION 0x16
-#define MII_RESV1 0x17
#define MII_LBRERROR 0x18
-#define MII_PHYADDR 0x19
#define MII_RESV2 0x1a
-#define MII_TPISTATUS 0x1b
-#define MII_NCONFIG 0x1c
#define MII_DBG_ADDR 0x1D
#define MII_DBG_DATA 0x1E
-
-/* PHY Control Register */
-#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
-#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
-#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
-#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
-#define MII_CR_POWER_DOWN 0x0800 /* Power down */
-#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
-#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
-#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
-#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
-#define MII_CR_SPEED_MASK 0x2040
-#define MII_CR_SPEED_1000 0x0040
-#define MII_CR_SPEED_100 0x2000
-#define MII_CR_SPEED_10 0x0000
-
-
-/* PHY Status Register */
-#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
-#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
-#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
-#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
-#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
-#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
-#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
-#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
-#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
-#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
-#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
-#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
-#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
-#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
-#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
-
-/* Link partner ability register. */
-#define MII_LPA_SLCT 0x001f /* Same as advertise selector */
-#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
-#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
-#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
-#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
-#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */
-#define MII_LPA_PAUSE 0x0400 /* PAUSE */
-#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */
-#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */
-#define MII_LPA_LPACK 0x4000 /* Link partner acked us */
-#define MII_LPA_NPAGE 0x8000 /* Next page bit */
-
/* Autoneg Advertisement Register */
-#define MII_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */
-#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
-#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
-#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
-#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
-#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
-#define MII_AR_PAUSE 0x0400 /* Pause operation desired */
-#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
-#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
-#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */
-#define MII_AR_SPEED_MASK 0x01E0
-#define MII_AR_DEFAULT_CAP_MASK 0x0DE0
+#define MII_AR_DEFAULT_CAP_MASK 0
/* 1000BASE-T Control Register */
-#define MII_AT001_CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
-#define MII_AT001_CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
-#define MII_AT001_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */
-/* 0=DTE device */
-#define MII_AT001_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
-/* 0=Configure PHY as Slave */
-#define MII_AT001_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
-/* 0=Automatic Master/Slave config */
-#define MII_AT001_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
-#define MII_AT001_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
-#define MII_AT001_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
-#define MII_AT001_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
-#define MII_AT001_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
-#define MII_AT001_CR_1000T_SPEED_MASK 0x0300
-#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK 0x0300
-
-/* 1000BASE-T Status Register */
-#define MII_AT001_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
-#define MII_AT001_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
-#define MII_AT001_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
-#define MII_AT001_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
-#define MII_AT001_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */
-#define MII_AT001_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
-#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT 12
-#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT 13
-
-/* Extended Status Register */
-#define MII_AT001_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
-#define MII_AT001_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
-#define MII_AT001_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
-#define MII_AT001_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
+#define MII_AT001_CR_1000T_SPEED_MASK \
+ (ADVERTISE_1000FULL | ADVERTISE_1000HALF)
+#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK MII_AT001_CR_1000T_SPEED_MASK
/* AT001 PHY Specific Control Register */
#define MII_AT001_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index 7685b995ff9..4345332533a 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -35,8 +35,9 @@ char atl1e_driver_version[] = DRV_VERSION;
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
* Class, Class Mask, private data (not used) }
*/
-static struct pci_device_id atl1e_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(atl1e_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
/* required last entry */
{ 0 }
};
@@ -88,7 +89,7 @@ static const u16 atl1e_pay_load_size[] = {
128, 256, 512, 1024, 2048, 4096,
};
-/*
+/**
* atl1e_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
*/
@@ -101,7 +102,7 @@ static inline void atl1e_irq_enable(struct atl1e_adapter *adapter)
}
}
-/*
+/**
* atl1e_irq_disable - Mask off interrupt generation on the NIC
* @adapter: board private structure
*/
@@ -113,7 +114,7 @@ static inline void atl1e_irq_disable(struct atl1e_adapter *adapter)
synchronize_irq(adapter->pdev->irq);
}
-/*
+/**
* atl1e_irq_reset - reset interrupt confiure on the NIC
* @adapter: board private structure
*/
@@ -125,7 +126,7 @@ static inline void atl1e_irq_reset(struct atl1e_adapter *adapter)
AT_WRITE_FLUSH(&adapter->hw);
}
-/*
+/**
* atl1e_phy_config - Timer Call-back
* @data: pointer to netdev cast into an unsigned long
*/
@@ -163,11 +164,10 @@ static int atl1e_check_link(struct atl1e_adapter *adapter)
{
struct atl1e_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
int err = 0;
u16 speed, duplex, phy_data;
- /* MII_BMSR must read twise */
+ /* MII_BMSR must read twice */
atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
if ((phy_data & BMSR_LSTATUS) == 0) {
@@ -194,12 +194,11 @@ static int atl1e_check_link(struct atl1e_adapter *adapter)
adapter->link_speed = speed;
adapter->link_duplex = duplex;
atl1e_setup_mac_ctrl(adapter);
- dev_info(&pdev->dev,
- "%s: %s NIC Link is Up<%d Mbps %s>\n",
- atl1e_driver_name, netdev->name,
- adapter->link_speed,
- adapter->link_duplex == FULL_DUPLEX ?
- "Full Duplex" : "Half Duplex");
+ netdev_info(netdev,
+ "NIC Link is Up <%d Mbps %s Duplex>\n",
+ adapter->link_speed,
+ adapter->link_duplex == FULL_DUPLEX ?
+ "Full" : "Half");
}
if (!netif_carrier_ok(netdev)) {
@@ -211,7 +210,7 @@ static int atl1e_check_link(struct atl1e_adapter *adapter)
return 0;
}
-/*
+/**
* atl1e_link_chg_task - deal with link change event Out of interrupt context
* @netdev: network interface device structure
*/
@@ -229,7 +228,6 @@ static void atl1e_link_chg_task(struct work_struct *work)
static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
u16 phy_data = 0;
u16 link_up = 0;
@@ -242,8 +240,7 @@ static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
if (!link_up) {
if (netif_carrier_ok(netdev)) {
/* old link state: Up */
- dev_info(&pdev->dev, "%s: %s NIC Link is Down\n",
- atl1e_driver_name, netdev->name);
+ netdev_info(netdev, "NIC Link is Down\n");
adapter->link_speed = SPEED_0;
netif_stop_queue(netdev);
}
@@ -262,7 +259,7 @@ static void atl1e_cancel_work(struct atl1e_adapter *adapter)
cancel_work_sync(&adapter->link_chg_task);
}
-/*
+/**
* atl1e_tx_timeout - Respond to a Tx Hang
* @netdev: network interface device structure
*/
@@ -274,7 +271,7 @@ static void atl1e_tx_timeout(struct net_device *netdev)
schedule_work(&adapter->reset_task);
}
-/*
+/**
* atl1e_set_multi - Multicast and Promiscuous mode set
* @netdev: network interface device structure
*
@@ -287,7 +284,7 @@ static void atl1e_set_multi(struct net_device *netdev)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw *hw = &adapter->hw;
- struct dev_mc_list *mc_ptr;
+ struct netdev_hw_addr *ha;
u32 mac_ctrl_data = 0;
u32 hash_value;
@@ -310,46 +307,73 @@ static void atl1e_set_multi(struct net_device *netdev)
AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
/* comoute mc addresses' hash value ,and put it into hash table */
- for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
- hash_value = atl1e_hash_mc_addr(hw, mc_ptr->dmi_addr);
+ netdev_for_each_mc_addr(ha, netdev) {
+ hash_value = atl1e_hash_mc_addr(hw, ha->addr);
atl1e_hash_set(hw, hash_value);
}
}
-static void atl1e_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
+static void __atl1e_rx_mode(netdev_features_t features, u32 *mac_ctrl_data)
+{
+
+ if (features & NETIF_F_RXALL) {
+ /* enable RX of ALL frames */
+ *mac_ctrl_data |= MAC_CTRL_DBG;
+ } else {
+ /* disable RX of ALL frames */
+ *mac_ctrl_data &= ~MAC_CTRL_DBG;
+ }
+}
+
+static void atl1e_rx_mode(struct net_device *netdev,
+ netdev_features_t features)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
- struct pci_dev *pdev = adapter->pdev;
u32 mac_ctrl_data = 0;
- dev_dbg(&pdev->dev, "atl1e_vlan_rx_register\n");
+ netdev_dbg(adapter->netdev, "%s\n", __func__);
atl1e_irq_disable(adapter);
-
- adapter->vlgrp = grp;
mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
+ __atl1e_rx_mode(features, &mac_ctrl_data);
+ AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
+ atl1e_irq_enable(adapter);
+}
- if (grp) {
+
+static void __atl1e_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data)
+{
+ if (features & NETIF_F_HW_VLAN_CTAG_RX) {
/* enable VLAN tag insert/strip */
- mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+ *mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
} else {
/* disable VLAN tag insert/strip */
- mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
+ *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
}
+}
+
+static void atl1e_vlan_mode(struct net_device *netdev,
+ netdev_features_t features)
+{
+ struct atl1e_adapter *adapter = netdev_priv(netdev);
+ u32 mac_ctrl_data = 0;
+
+ netdev_dbg(adapter->netdev, "%s\n", __func__);
+ atl1e_irq_disable(adapter);
+ mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
+ __atl1e_vlan_mode(features, &mac_ctrl_data);
AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
atl1e_irq_enable(adapter);
}
static void atl1e_restore_vlan(struct atl1e_adapter *adapter)
{
- struct pci_dev *pdev = adapter->pdev;
-
- dev_dbg(&pdev->dev, "atl1e_restore_vlan !");
- atl1e_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+ netdev_dbg(adapter->netdev, "%s\n", __func__);
+ atl1e_vlan_mode(adapter->netdev, adapter->netdev->features);
}
-/*
+
+/**
* atl1e_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
@@ -375,7 +399,37 @@ static int atl1e_set_mac_addr(struct net_device *netdev, void *p)
return 0;
}
-/*
+static netdev_features_t atl1e_fix_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ /*
+ * Since there is no support for separate rx/tx vlan accel
+ * enable/disable make sure tx flag is always in same state as rx.
+ */
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ features |= NETIF_F_HW_VLAN_CTAG_TX;
+ else
+ features &= ~NETIF_F_HW_VLAN_CTAG_TX;
+
+ return features;
+}
+
+static int atl1e_set_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = netdev->features ^ features;
+
+ if (changed & NETIF_F_HW_VLAN_CTAG_RX)
+ atl1e_vlan_mode(netdev, features);
+
+ if (changed & NETIF_F_RXALL)
+ atl1e_rx_mode(netdev, features);
+
+
+ return 0;
+}
+
+/**
* atl1e_change_mtu - Change the Maximum Transfer Unit
* @netdev: network interface device structure
* @new_mtu: new value for maximum frame size
@@ -390,7 +444,7 @@ static int atl1e_change_mtu(struct net_device *netdev, int new_mtu)
if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
- dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+ netdev_warn(adapter->netdev, "invalid MTU setting\n");
return -EINVAL;
}
/* set MTU */
@@ -427,17 +481,10 @@ static void atl1e_mdio_write(struct net_device *netdev, int phy_id,
atl1e_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val);
}
-/*
- * atl1e_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
static int atl1e_mii_ioctl(struct net_device *netdev,
struct ifreq *ifr, int cmd)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
- struct pci_dev *pdev = adapter->pdev;
struct mii_ioctl_data *data = if_mii(ifr);
unsigned long flags;
int retval = 0;
@@ -452,10 +499,6 @@ static int atl1e_mii_ioctl(struct net_device *netdev,
break;
case SIOCGMIIREG:
- if (!capable(CAP_NET_ADMIN)) {
- retval = -EPERM;
- goto out;
- }
if (atl1e_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
&data->val_out)) {
retval = -EIO;
@@ -464,17 +507,13 @@ static int atl1e_mii_ioctl(struct net_device *netdev,
break;
case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN)) {
- retval = -EPERM;
- goto out;
- }
if (data->reg_num & ~(0x1F)) {
retval = -EFAULT;
goto out;
}
- dev_dbg(&pdev->dev, "<atl1e_mii_ioctl> write %x %x",
- data->reg_num, data->val_in);
+ netdev_dbg(adapter->netdev, "<atl1e_mii_ioctl> write %x %x\n",
+ data->reg_num, data->val_in);
if (atl1e_write_phy_reg(&adapter->hw,
data->reg_num, data->val_in)) {
retval = -EIO;
@@ -492,12 +531,6 @@ out:
}
-/*
- * atl1e_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
static int atl1e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
@@ -528,17 +561,17 @@ static void atl1e_setup_pcicmd(struct pci_dev *pdev)
msleep(1);
}
-/*
+/**
* atl1e_alloc_queues - Allocate memory for all rings
* @adapter: board private structure to initialize
*
*/
-static int __devinit atl1e_alloc_queues(struct atl1e_adapter *adapter)
+static int atl1e_alloc_queues(struct atl1e_adapter *adapter)
{
return 0;
}
-/*
+/**
* atl1e_sw_init - Initialize general software structures (struct atl1e_adapter)
* @adapter: board private structure to initialize
*
@@ -546,7 +579,7 @@ static int __devinit atl1e_alloc_queues(struct atl1e_adapter *adapter)
* Fields are initialized based on PCI device information and
* OS network device settings (MTU size).
*/
-static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter)
+static int atl1e_sw_init(struct atl1e_adapter *adapter)
{
struct atl1e_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
@@ -562,8 +595,8 @@ static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter)
hw->device_id = pdev->device;
hw->subsystem_vendor_id = pdev->subsystem_vendor;
hw->subsystem_id = pdev->subsystem_device;
+ hw->revision_id = pdev->revision;
- pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
@@ -609,7 +642,7 @@ static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter)
hw->dmaw_dly_cnt = 4;
if (atl1e_alloc_queues(adapter)) {
- dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+ netdev_err(adapter->netdev, "Unable to allocate memory for queues\n");
return -ENOMEM;
}
@@ -622,14 +655,13 @@ static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter)
return 0;
}
-/*
+/**
* atl1e_clean_tx_ring - Free Tx-skb
* @adapter: board private structure
*/
static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
{
- struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
- &adapter->tx_ring;
+ struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
struct atl1e_tx_buffer *tx_buffer = NULL;
struct pci_dev *pdev = adapter->pdev;
u16 index, ring_count;
@@ -642,7 +674,11 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
for (index = 0; index < ring_count; index++) {
tx_buffer = &tx_ring->tx_buffer[index];
if (tx_buffer->dma) {
- pci_unmap_page(pdev, tx_buffer->dma,
+ if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+ pci_unmap_single(pdev, tx_buffer->dma,
+ tx_buffer->length, PCI_DMA_TODEVICE);
+ else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+ pci_unmap_page(pdev, tx_buffer->dma,
tx_buffer->length, PCI_DMA_TODEVICE);
tx_buffer->dma = 0;
}
@@ -662,14 +698,14 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
ring_count);
}
-/*
+/**
* atl1e_clean_rx_ring - Free rx-reservation skbs
* @adapter: board private structure
*/
static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter)
{
struct atl1e_rx_ring *rx_ring =
- (struct atl1e_rx_ring *)&adapter->rx_ring;
+ &adapter->rx_ring;
struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc;
u16 i, j;
@@ -702,10 +738,8 @@ static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size)
static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
{
- struct atl1e_tx_ring *tx_ring = NULL;
struct atl1e_rx_ring *rx_ring = NULL;
- tx_ring = &adapter->tx_ring;
rx_ring = &adapter->rx_ring;
rx_ring->real_page_size = adapter->rx_ring.page_size
@@ -718,8 +752,6 @@ static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
adapter->ring_vir_addr = NULL;
adapter->rx_ring.desc = NULL;
rwlock_init(&adapter->tx_ring.tx_lock);
-
- return;
}
/*
@@ -749,7 +781,7 @@ static void atl1e_init_ring_ptrs(struct atl1e_adapter *adapter)
}
}
-/*
+/**
* atl1e_free_ring_resources - Free Tx / RX descriptor Resources
* @adapter: board private structure
*
@@ -774,7 +806,7 @@ static void atl1e_free_ring_resources(struct atl1e_adapter *adapter)
}
}
-/*
+/**
* atl1e_setup_mem_resources - allocate Tx / RX descriptor resources
* @adapter: board private structure
*
@@ -803,8 +835,8 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
adapter->ring_size, &adapter->ring_dma);
if (adapter->ring_vir_addr == NULL) {
- dev_err(&pdev->dev, "pci_alloc_consistent failed, "
- "size = D%d", size);
+ netdev_err(adapter->netdev,
+ "pci_alloc_consistent failed, size = D%d\n", size);
return -ENOMEM;
}
@@ -815,12 +847,10 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
/* Init TPD Ring */
tx_ring->dma = roundup(adapter->ring_dma, 8);
offset = tx_ring->dma - adapter->ring_dma;
- tx_ring->desc = (struct atl1e_tpd_desc *)
- (adapter->ring_vir_addr + offset);
+ tx_ring->desc = adapter->ring_vir_addr + offset;
size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count);
tx_ring->tx_buffer = kzalloc(size, GFP_KERNEL);
if (tx_ring->tx_buffer == NULL) {
- dev_err(&pdev->dev, "kzalloc failed , size = D%d", size);
err = -ENOMEM;
goto failed;
}
@@ -841,7 +871,7 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
/* Init CMB dma address */
tx_ring->cmb_dma = adapter->ring_dma + offset;
- tx_ring->cmb = (u32 *)(adapter->ring_vir_addr + offset);
+ tx_ring->cmb = adapter->ring_vir_addr + offset;
offset += sizeof(u32);
for (i = 0; i < adapter->num_rx_queues; i++) {
@@ -855,8 +885,8 @@ static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
}
if (unlikely(offset > adapter->ring_size)) {
- dev_err(&pdev->dev, "offset(%d) > ring size(%d) !!\n",
- offset, adapter->ring_size);
+ netdev_err(adapter->netdev, "offset(%d) > ring size(%d) !!\n",
+ offset, adapter->ring_size);
err = -1;
goto failed;
}
@@ -871,14 +901,12 @@ failed:
return err;
}
-static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter)
+static inline void atl1e_configure_des_ring(struct atl1e_adapter *adapter)
{
- struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
- struct atl1e_rx_ring *rx_ring =
- (struct atl1e_rx_ring *)&adapter->rx_ring;
- struct atl1e_tx_ring *tx_ring =
- (struct atl1e_tx_ring *)&adapter->tx_ring;
+ struct atl1e_hw *hw = &adapter->hw;
+ struct atl1e_rx_ring *rx_ring = &adapter->rx_ring;
+ struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
struct atl1e_rx_page_desc *rx_page_desc = NULL;
int i, j;
@@ -915,13 +943,11 @@ static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter)
AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size);
/* Load all of base address above */
AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
-
- return;
}
static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
{
- struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+ struct atl1e_hw *hw = &adapter->hw;
u32 dev_ctrl_data = 0;
u32 max_pay_load = 0;
u32 jumbo_thresh = 0;
@@ -946,11 +972,11 @@ static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) &
DEVICE_CTRL_MAX_PAYLOAD_MASK;
- hw->dmaw_block = min(max_pay_load, hw->dmaw_block);
+ hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) &
DEVICE_CTRL_MAX_RREQ_SZ_MASK;
- hw->dmar_block = min(max_pay_load, hw->dmar_block);
+ hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
if (hw->nic_type != athr_l2e_revB)
AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2,
@@ -960,12 +986,11 @@ static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
(((u16)hw->tpd_burst & TXQ_CTRL_NUM_TPD_BURST_MASK)
<< TXQ_CTRL_NUM_TPD_BURST_SHIFT)
| TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN);
- return;
}
static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
{
- struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw;
+ struct atl1e_hw *hw = &adapter->hw;
u32 rxf_len = 0;
u32 rxf_low = 0;
u32 rxf_high = 0;
@@ -1014,7 +1039,6 @@ static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
- return;
}
static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
@@ -1034,7 +1058,6 @@ static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
<< DMA_CTRL_DMAW_DLY_CNT_SHIFT;
AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
- return;
}
static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
@@ -1059,19 +1082,19 @@ static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
value |= (((u32)adapter->hw.preamble_len &
MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
- if (adapter->vlgrp)
- value |= MAC_CTRL_RMV_VLAN;
+ __atl1e_vlan_mode(netdev->features, &value);
value |= MAC_CTRL_BC_EN;
if (netdev->flags & IFF_PROMISC)
value |= MAC_CTRL_PROMIS_EN;
if (netdev->flags & IFF_ALLMULTI)
value |= MAC_CTRL_MC_ALL_EN;
-
+ if (netdev->features & NETIF_F_RXALL)
+ value |= MAC_CTRL_DBG;
AT_WRITE_REG(hw, REG_MAC_CTRL, value);
}
-/*
+/**
* atl1e_configure - Configure Transmit&Receive Unit after Reset
* @adapter: board private structure
*
@@ -1080,7 +1103,6 @@ static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
static int atl1e_configure(struct atl1e_adapter *adapter)
{
struct atl1e_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
u32 intr_status_data = 0;
@@ -1133,8 +1155,8 @@ static int atl1e_configure(struct atl1e_adapter *adapter)
intr_status_data = AT_READ_REG(hw, REG_ISR);
if (unlikely((intr_status_data & ISR_PHY_LINKDOWN) != 0)) {
- dev_err(&pdev->dev, "atl1e_configure failed,"
- "PCIE phy link down\n");
+ netdev_err(adapter->netdev,
+ "atl1e_configure failed, PCIE phy link down\n");
return -1;
}
@@ -1142,7 +1164,7 @@ static int atl1e_configure(struct atl1e_adapter *adapter)
return 0;
}
-/*
+/**
* atl1e_get_stats - Get System Network Statistics
* @netdev: network interface device structure
*
@@ -1153,35 +1175,43 @@ static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
struct atl1e_hw_stats *hw_stats = &adapter->hw_stats;
- struct net_device_stats *net_stats = &adapter->net_stats;
+ struct net_device_stats *net_stats = &netdev->stats;
- net_stats->rx_packets = hw_stats->rx_ok;
- net_stats->tx_packets = hw_stats->tx_ok;
net_stats->rx_bytes = hw_stats->rx_byte_cnt;
net_stats->tx_bytes = hw_stats->tx_byte_cnt;
net_stats->multicast = hw_stats->rx_mcast;
net_stats->collisions = hw_stats->tx_1_col +
- hw_stats->tx_2_col * 2 +
- hw_stats->tx_late_col + hw_stats->tx_abort_col;
+ hw_stats->tx_2_col +
+ hw_stats->tx_late_col +
+ hw_stats->tx_abort_col;
+
+ net_stats->rx_errors = hw_stats->rx_frag +
+ hw_stats->rx_fcs_err +
+ hw_stats->rx_len_err +
+ hw_stats->rx_sz_ov +
+ hw_stats->rx_rrd_ov +
+ hw_stats->rx_align_err +
+ hw_stats->rx_rxf_ov;
- net_stats->rx_errors = hw_stats->rx_frag + hw_stats->rx_fcs_err +
- hw_stats->rx_len_err + hw_stats->rx_sz_ov +
- hw_stats->rx_rrd_ov + hw_stats->rx_align_err;
net_stats->rx_fifo_errors = hw_stats->rx_rxf_ov;
net_stats->rx_length_errors = hw_stats->rx_len_err;
net_stats->rx_crc_errors = hw_stats->rx_fcs_err;
net_stats->rx_frame_errors = hw_stats->rx_align_err;
- net_stats->rx_over_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+ net_stats->rx_dropped = hw_stats->rx_rrd_ov;
- net_stats->rx_missed_errors = hw_stats->rx_rrd_ov + hw_stats->rx_rxf_ov;
+ net_stats->tx_errors = hw_stats->tx_late_col +
+ hw_stats->tx_abort_col +
+ hw_stats->tx_underrun +
+ hw_stats->tx_trunc;
- net_stats->tx_errors = hw_stats->tx_late_col + hw_stats->tx_abort_col +
- hw_stats->tx_underrun + hw_stats->tx_trunc;
net_stats->tx_fifo_errors = hw_stats->tx_underrun;
net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
net_stats->tx_window_errors = hw_stats->tx_late_col;
- return &adapter->net_stats;
+ net_stats->rx_packets = hw_stats->rx_ok + net_stats->rx_errors;
+ net_stats->tx_packets = hw_stats->tx_ok + net_stats->tx_errors;
+
+ return net_stats;
}
static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
@@ -1218,8 +1248,7 @@ static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter)
static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
{
- struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *)
- &adapter->tx_ring;
+ struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
struct atl1e_tx_buffer *tx_buffer = NULL;
u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX);
u16 next_to_clean = atomic_read(&tx_ring->next_to_clean);
@@ -1227,7 +1256,11 @@ static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
while (next_to_clean != hw_next_to_clean) {
tx_buffer = &tx_ring->tx_buffer[next_to_clean];
if (tx_buffer->dma) {
- pci_unmap_page(adapter->pdev, tx_buffer->dma,
+ if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+ pci_unmap_single(adapter->pdev, tx_buffer->dma,
+ tx_buffer->length, PCI_DMA_TODEVICE);
+ else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+ pci_unmap_page(adapter->pdev, tx_buffer->dma,
tx_buffer->length, PCI_DMA_TODEVICE);
tx_buffer->dma = 0;
}
@@ -1251,17 +1284,15 @@ static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
return true;
}
-/*
+/**
* atl1e_intr - Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
*/
static irqreturn_t atl1e_intr(int irq, void *data)
{
struct net_device *netdev = data;
struct atl1e_adapter *adapter = netdev_priv(netdev);
- struct pci_dev *pdev = adapter->pdev;
struct atl1e_hw *hw = &adapter->hw;
int max_ints = AT_MAX_INT_WORK;
int handled = IRQ_NONE;
@@ -1284,8 +1315,8 @@ static irqreturn_t atl1e_intr(int irq, void *data)
handled = IRQ_HANDLED;
/* check if PCIE PHY Link down */
if (status & ISR_PHY_LINKDOWN) {
- dev_err(&pdev->dev,
- "pcie phy linkdown %x\n", status);
+ netdev_err(adapter->netdev,
+ "pcie phy linkdown %x\n", status);
if (netif_running(adapter->netdev)) {
/* reset MAC */
atl1e_irq_reset(adapter);
@@ -1296,9 +1327,9 @@ static irqreturn_t atl1e_intr(int irq, void *data)
/* check if DMA read/write error */
if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
- dev_err(&pdev->dev,
- "PCIE DMA RW error (status = 0x%x)\n",
- status);
+ netdev_err(adapter->netdev,
+ "PCIE DMA RW error (status = 0x%x)\n",
+ status);
atl1e_irq_reset(adapter);
schedule_work(&adapter->reset_task);
break;
@@ -1309,7 +1340,7 @@ static irqreturn_t atl1e_intr(int irq, void *data)
/* link event */
if (status & (ISR_GPHY | ISR_MANUAL)) {
- adapter->net_stats.tx_carrier_errors++;
+ netdev->stats.tx_carrier_errors++;
atl1e_link_chg_event(adapter);
break;
}
@@ -1326,9 +1357,9 @@ static irqreturn_t atl1e_intr(int irq, void *data)
AT_WRITE_REG(hw, REG_IMR,
IMR_NORMAL_MASK & ~ISR_RX_EVENT);
AT_WRITE_FLUSH(hw);
- if (likely(netif_rx_schedule_prep(netdev,
+ if (likely(napi_schedule_prep(
&adapter->napi)))
- __netif_rx_schedule(netdev, &adapter->napi);
+ __napi_schedule(&adapter->napi);
}
} while (--max_ints > 0);
/* re-enable Interrupt*/
@@ -1346,7 +1377,7 @@ static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
u16 pkt_flags;
u16 err_flags;
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
pkt_flags = prrs->pkt_flag;
err_flags = prrs->err_flag;
if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
@@ -1375,16 +1406,14 @@ static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter,
(struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc;
u8 rx_using = rx_page_desc[que].rx_using;
- return (struct atl1e_rx_page *)&(rx_page_desc[que].rx_page[rx_using]);
+ return &(rx_page_desc[que].rx_page[rx_using]);
}
static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
int *work_done, int work_to_do)
{
- struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
- struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *)
- &adapter->rx_ring;
+ struct atl1e_rx_ring *rx_ring = &adapter->rx_ring;
struct atl1e_rx_page_desc *rx_page_desc =
(struct atl1e_rx_page_desc *) rx_ring->rx_page_desc;
struct sk_buff *skb = NULL;
@@ -1403,11 +1432,10 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
rx_page->read_offset);
/* check sequence number */
if (prrs->seq_num != rx_page_desc[que].rx_nxseq) {
- dev_err(&pdev->dev,
- "rx sequence number"
- " error (rx=%d) (expect=%d)\n",
- prrs->seq_num,
- rx_page_desc[que].rx_nxseq);
+ netdev_err(netdev,
+ "rx sequence number error (rx=%d) (expect=%d)\n",
+ prrs->seq_num,
+ rx_page_desc[que].rx_nxseq);
rx_page_desc[que].rx_nxseq++;
/* just for debug use */
AT_WRITE_REG(&adapter->hw, REG_DEBUG_DATA0,
@@ -1418,49 +1446,44 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
rx_page_desc[que].rx_nxseq++;
/* error packet */
- if (prrs->pkt_flag & RRS_IS_ERR_FRAME) {
+ if ((prrs->pkt_flag & RRS_IS_ERR_FRAME) &&
+ !(netdev->features & NETIF_F_RXALL)) {
if (prrs->err_flag & (RRS_ERR_BAD_CRC |
RRS_ERR_DRIBBLE | RRS_ERR_CODE |
RRS_ERR_TRUNC)) {
/* hardware error, discard this packet*/
- dev_err(&pdev->dev,
- "rx packet desc error %x\n",
- *((u32 *)prrs + 1));
+ netdev_err(netdev,
+ "rx packet desc error %x\n",
+ *((u32 *)prrs + 1));
goto skip_pkt;
}
}
packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
- RRS_PKT_SIZE_MASK) - 4; /* CRC */
- skb = netdev_alloc_skb(netdev,
- packet_size + NET_IP_ALIGN);
- if (skb == NULL) {
- dev_warn(&pdev->dev, "%s: Memory squeeze,"
- "deferring packet.\n", netdev->name);
+ RRS_PKT_SIZE_MASK);
+ if (likely(!(netdev->features & NETIF_F_RXFCS)))
+ packet_size -= 4; /* CRC */
+
+ skb = netdev_alloc_skb_ip_align(netdev, packet_size);
+ if (skb == NULL)
goto skip_pkt;
- }
- skb_reserve(skb, NET_IP_ALIGN);
- skb->dev = netdev;
+
memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
skb_put(skb, packet_size);
skb->protocol = eth_type_trans(skb, netdev);
atl1e_rx_checksum(adapter, skb, prrs);
- if (unlikely(adapter->vlgrp &&
- (prrs->pkt_flag & RRS_IS_VLAN_TAG))) {
+ if (prrs->pkt_flag & RRS_IS_VLAN_TAG) {
u16 vlan_tag = (prrs->vtag >> 4) |
((prrs->vtag & 7) << 13) |
((prrs->vtag & 8) << 9);
- dev_dbg(&pdev->dev,
- "RXD VLAN TAG<RRD>=0x%04x\n",
- prrs->vtag);
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- vlan_tag);
- } else {
- netif_receive_skb(skb);
+ netdev_dbg(netdev,
+ "RXD VLAN TAG<RRD>=0x%04x\n",
+ prrs->vtag);
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
}
+ netif_receive_skb(skb);
- netdev->last_rx = jiffies;
skip_pkt:
/* skip current packet whether it's ok or not. */
rx_page->read_offset +=
@@ -1494,16 +1517,13 @@ fatal_err:
schedule_work(&adapter->reset_task);
}
-/*
+/**
* atl1e_clean - NAPI Rx polling callback
- * @adapter: board private structure
*/
static int atl1e_clean(struct napi_struct *napi, int budget)
{
struct atl1e_adapter *adapter =
container_of(napi, struct atl1e_adapter, napi);
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
u32 imr_data;
int work_done = 0;
@@ -1516,14 +1536,14 @@ static int atl1e_clean(struct napi_struct *napi, int budget)
/* If no Tx and not enough Rx work done, exit the polling mode */
if (work_done < budget) {
quit_polling:
- netif_rx_complete(netdev, napi);
+ napi_complete(napi);
imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
/* test debug */
if (test_bit(__AT_DOWN, &adapter->flags)) {
atomic_dec(&adapter->irq_sem);
- dev_err(&pdev->dev,
- "atl1e_clean is called when AT_DOWN\n");
+ netdev_err(adapter->netdev,
+ "atl1e_clean is called when AT_DOWN\n");
}
/* reenable RX intr */
/*atl1e_irq_enable(adapter); */
@@ -1578,7 +1598,7 @@ static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter)
tx_ring->next_to_use = 0;
memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc));
- return (struct atl1e_tpd_desc *)&tx_ring->desc[next_to_use];
+ return &tx_ring->desc[next_to_use];
}
static struct atl1e_tx_buffer *
@@ -1598,12 +1618,12 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
u16 proto_hdr_len = 0;
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- fg_size = skb_shinfo(skb)->frags[i].size;
+ fg_size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
tpd_req += ((fg_size + MAX_TX_BUF_LEN - 1) >> MAX_TX_BUF_SHIFT);
}
if (skb_is_gso(skb)) {
- if (skb->protocol == ntohs(ETH_P_IP) ||
+ if (skb->protocol == htons(ETH_P_IP) ||
(skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
proto_hdr_len = skb_transport_offset(skb) +
tcp_hdrlen(skb);
@@ -1621,18 +1641,17 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
static int atl1e_tso_csum(struct atl1e_adapter *adapter,
struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
{
- struct pci_dev *pdev = adapter->pdev;
+ unsigned short offload_type;
u8 hdr_len;
u32 real_len;
- unsigned short offload_type;
- int err;
if (skb_is_gso(skb)) {
- if (skb_header_cloned(skb)) {
- err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
- if (unlikely(err))
- return -1;
- }
+ int err;
+
+ err = skb_cow_head(skb, 0);
+ if (err < 0)
+ return err;
+
offload_type = skb_shinfo(skb)->gso_type;
if (offload_type & SKB_GSO_TCPV4) {
@@ -1645,8 +1664,8 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter,
hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
if (unlikely(skb->len == hdr_len)) {
/* only xsum need */
- dev_warn(&pdev->dev,
- "IPV4 tso with zero data??\n");
+ netdev_warn(adapter->netdev,
+ "IPV4 tso with zero data??\n");
goto check_sum;
} else {
ip_hdr(skb)->check = 0;
@@ -1667,51 +1686,16 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter,
}
return 0;
}
-
- if (offload_type & SKB_GSO_TCPV6) {
- real_len = (((unsigned char *)ipv6_hdr(skb) - skb->data)
- + ntohs(ipv6_hdr(skb)->payload_len));
- if (real_len < skb->len)
- pskb_trim(skb, real_len);
-
- /* check payload == 0 byte ? */
- hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
- if (unlikely(skb->len == hdr_len)) {
- /* only xsum need */
- dev_warn(&pdev->dev,
- "IPV6 tso with zero data??\n");
- goto check_sum;
- } else {
- tcp_hdr(skb)->check = ~csum_ipv6_magic(
- &ipv6_hdr(skb)->saddr,
- &ipv6_hdr(skb)->daddr,
- 0, IPPROTO_TCP, 0);
- tpd->word3 |= 1 << TPD_IP_VERSION_SHIFT;
- hdr_len >>= 1;
- tpd->word3 |= (hdr_len & TPD_V6_IPHLLO_MASK) <<
- TPD_V6_IPHLLO_SHIFT;
- tpd->word3 |= ((hdr_len >> 3) &
- TPD_V6_IPHLHI_MASK) <<
- TPD_V6_IPHLHI_SHIFT;
- tpd->word3 |= (tcp_hdrlen(skb) >> 2 &
- TPD_TCPHDRLEN_MASK) <<
- TPD_TCPHDRLEN_SHIFT;
- tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
- TPD_MSS_MASK) << TPD_MSS_SHIFT;
- tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
- }
- }
- return 0;
}
check_sum:
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
u8 css, cso;
- cso = skb_transport_offset(skb);
+ cso = skb_checksum_start_offset(skb);
if (unlikely(cso & 0x1)) {
- dev_err(&adapter->pdev->dev,
- "pay load offset should not ant event number\n");
+ netdev_err(adapter->netdev,
+ "payload offset should not ant event number\n");
return -1;
} else {
css = cso + skb->csum_offset;
@@ -1726,18 +1710,20 @@ check_sum:
return 0;
}
-static void atl1e_tx_map(struct atl1e_adapter *adapter,
- struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
+static int atl1e_tx_map(struct atl1e_adapter *adapter,
+ struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
{
struct atl1e_tpd_desc *use_tpd = NULL;
struct atl1e_tx_buffer *tx_buffer = NULL;
- u16 buf_len = skb->len - skb->data_len;
+ u16 buf_len = skb_headlen(skb);
u16 map_len = 0;
u16 mapped_len = 0;
u16 hdr_len = 0;
u16 nr_frags;
u16 f;
int segment;
+ int ring_start = adapter->tx_ring.next_to_use;
+ int ring_end;
nr_frags = skb_shinfo(skb)->nr_frags;
segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
@@ -1750,6 +1736,10 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
tx_buffer->length = map_len;
tx_buffer->dma = pci_map_single(adapter->pdev,
skb->data, hdr_len, PCI_DMA_TODEVICE);
+ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma))
+ return -ENOSPC;
+
+ ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
mapped_len += map_len;
use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1775,6 +1765,23 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
tx_buffer->dma =
pci_map_single(adapter->pdev, skb->data + mapped_len,
map_len, PCI_DMA_TODEVICE);
+
+ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) {
+ /* We need to unwind the mappings we've done */
+ ring_end = adapter->tx_ring.next_to_use;
+ adapter->tx_ring.next_to_use = ring_start;
+ while (adapter->tx_ring.next_to_use != ring_end) {
+ tpd = atl1e_get_tpd(adapter);
+ tx_buffer = atl1e_get_tx_buffer(adapter, tpd);
+ pci_unmap_single(adapter->pdev, tx_buffer->dma,
+ tx_buffer->length, PCI_DMA_TODEVICE);
+ }
+ /* Reset the tx rings next pointer */
+ adapter->tx_ring.next_to_use = ring_start;
+ return -ENOSPC;
+ }
+
+ ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
mapped_len += map_len;
use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1783,12 +1790,12 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
}
for (f = 0; f < nr_frags; f++) {
- struct skb_frag_struct *frag;
+ const struct skb_frag_struct *frag;
u16 i;
u16 seg_num;
frag = &skb_shinfo(skb)->frags[f];
- buf_len = frag->size;
+ buf_len = skb_frag_size(frag);
seg_num = (buf_len + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
for (i = 0; i < seg_num; i++) {
@@ -1796,8 +1803,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
- if (tx_buffer->skb)
- BUG();
+ BUG_ON(tx_buffer->skb);
tx_buffer->skb = NULL;
tx_buffer->length =
@@ -1805,12 +1811,29 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
MAX_TX_BUF_LEN : buf_len;
buf_len -= tx_buffer->length;
- tx_buffer->dma =
- pci_map_page(adapter->pdev, frag->page,
- frag->page_offset +
- (i * MAX_TX_BUF_LEN),
- tx_buffer->length,
- PCI_DMA_TODEVICE);
+ tx_buffer->dma = skb_frag_dma_map(&adapter->pdev->dev,
+ frag,
+ (i * MAX_TX_BUF_LEN),
+ tx_buffer->length,
+ DMA_TO_DEVICE);
+
+ if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) {
+ /* We need to unwind the mappings we've done */
+ ring_end = adapter->tx_ring.next_to_use;
+ adapter->tx_ring.next_to_use = ring_start;
+ while (adapter->tx_ring.next_to_use != ring_end) {
+ tpd = atl1e_get_tpd(adapter);
+ tx_buffer = atl1e_get_tx_buffer(adapter, tpd);
+ dma_unmap_page(&adapter->pdev->dev, tx_buffer->dma,
+ tx_buffer->length, DMA_TO_DEVICE);
+ }
+
+ /* Reset the ring next to use pointer */
+ adapter->tx_ring.next_to_use = ring_start;
+ return -ENOSPC;
+ }
+
+ ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
((cpu_to_le32(tx_buffer->length) &
@@ -1827,6 +1850,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
/* The last buffer info contain the skb address,
so it will be free after unmap */
tx_buffer->skb = skb;
+ return 0;
}
static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
@@ -1841,7 +1865,8 @@ static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
AT_WRITE_REG(&adapter->hw, REG_MB_TPD_PROD_IDX, tx_ring->next_to_use);
}
-static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
+ struct net_device *netdev)
{
struct atl1e_adapter *adapter = netdev_priv(netdev);
unsigned long flags;
@@ -1870,7 +1895,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tpd = atl1e_get_tpd(adapter);
- if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
+ if (vlan_tx_tag_present(skb)) {
u16 vlan_tag = vlan_tx_tag_get(skb);
u16 atl1e_vlan_tag;
@@ -1880,7 +1905,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
TPD_VLAN_SHIFT;
}
- if (skb->protocol == ntohs(ETH_P_8021Q))
+ if (skb->protocol == htons(ETH_P_8021Q))
tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
if (skb_network_offset(skb) != ETH_HLEN)
@@ -1893,10 +1918,15 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
- atl1e_tx_map(adapter, skb, tpd);
+ if (atl1e_tx_map(adapter, skb, tpd)) {
+ dev_kfree_skb_any(skb);
+ goto out;
+ }
+
atl1e_tx_queue(adapter, tpd_req, tpd);
- netdev->trans_start = jiffies;
+ netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+out:
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -1906,40 +1936,22 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter)
struct net_device *netdev = adapter->netdev;
free_irq(adapter->pdev->irq, netdev);
-
- if (adapter->have_msi)
- pci_disable_msi(adapter->pdev);
}
static int atl1e_request_irq(struct atl1e_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
- int flags = 0;
int err = 0;
- adapter->have_msi = true;
- err = pci_enable_msi(adapter->pdev);
+ err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name,
+ netdev);
if (err) {
- dev_dbg(&pdev->dev,
- "Unable to allocate MSI interrupt Error: %d\n", err);
- adapter->have_msi = false;
- } else
- netdev->irq = pdev->irq;
-
-
- if (!adapter->have_msi)
- flags |= IRQF_SHARED;
- err = request_irq(adapter->pdev->irq, &atl1e_intr, flags,
- netdev->name, netdev);
- if (err) {
- dev_dbg(&pdev->dev,
- "Unable to allocate interrupt Error: %d\n", err);
- if (adapter->have_msi)
- pci_disable_msi(adapter->pdev);
+ netdev_dbg(adapter->netdev,
+ "Unable to allocate interrupt Error: %d\n", err);
return err;
}
- dev_dbg(&pdev->dev, "atl1e_request_irq OK\n");
+ netdev_dbg(netdev, "atl1e_request_irq OK\n");
return err;
}
@@ -1983,11 +1995,7 @@ void atl1e_down(struct atl1e_adapter *adapter)
* reschedule our watchdog timer */
set_bit(__AT_DOWN, &adapter->flags);
-#ifdef NETIF_F_LLTX
netif_stop_queue(netdev);
-#else
- netif_tx_disable(netdev);
-#endif
/* reset MAC to disable all RX/TX */
atl1e_reset_hw(&adapter->hw);
@@ -2004,7 +2012,7 @@ void atl1e_down(struct atl1e_adapter *adapter)
atl1e_clean_rx_ring(adapter);
}
-/*
+/**
* atl1e_open - Called when a network interface is made active
* @netdev: network interface device structure
*
@@ -2050,7 +2058,7 @@ err_req_irq:
return err;
}
-/*
+/**
* atl1e_close - Disables a network interface
* @netdev: network interface device structure
*
@@ -2104,16 +2112,16 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state)
if (wufc) {
/* get link status */
- atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
- atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data);
+ atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data);
+ atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data);
- mii_advertise_data = MII_AR_10T_HD_CAPS;
+ mii_advertise_data = ADVERTISE_10HALF;
- if ((atl1e_write_phy_reg(hw, MII_AT001_CR, 0) != 0) ||
+ if ((atl1e_write_phy_reg(hw, MII_CTRL1000, 0) != 0) ||
(atl1e_write_phy_reg(hw,
MII_ADVERTISE, mii_advertise_data) != 0) ||
(atl1e_phy_commit(hw)) != 0) {
- dev_dbg(&pdev->dev, "set phy register failed\n");
+ netdev_dbg(adapter->netdev, "set phy register failed\n");
goto wol_dis;
}
@@ -2129,23 +2137,20 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state)
for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
msleep(100);
atl1e_read_phy_reg(hw, MII_BMSR,
- (u16 *)&mii_bmsr_data);
+ &mii_bmsr_data);
if (mii_bmsr_data & BMSR_LSTATUS)
break;
}
if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
- dev_dbg(&pdev->dev,
- "%s: Link may change"
- "when suspend\n",
- atl1e_driver_name);
+ netdev_dbg(adapter->netdev,
+ "Link may change when suspend\n");
}
wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
/* only link up can wake up */
if (atl1e_write_phy_reg(hw, MII_INT_CTRL, 0x400) != 0) {
- dev_dbg(&pdev->dev, "%s: read write phy "
- "register failed.\n",
- atl1e_driver_name);
+ netdev_dbg(adapter->netdev,
+ "read write phy register failed\n");
goto wol_dis;
}
}
@@ -2159,16 +2164,14 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state)
MAC_CTRL_PRMLEN_MASK) <<
MAC_CTRL_PRMLEN_SHIFT);
- if (adapter->vlgrp)
- mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
+ __atl1e_vlan_mode(netdev->features, &mac_ctrl_data);
/* magic packet maybe Broadcast&multicast&Unicast frame */
if (wufc & AT_WUFC_MAG)
mac_ctrl_data |= MAC_CTRL_BC_EN;
- dev_dbg(&pdev->dev,
- "%s: suspend MAC=0x%x\n",
- atl1e_driver_name, mac_ctrl_data);
+ netdev_dbg(adapter->netdev, "suspend MAC=0x%x\n",
+ mac_ctrl_data);
AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
@@ -2218,8 +2221,8 @@ static int atl1e_resume(struct pci_dev *pdev)
err = pci_enable_device(pdev);
if (err) {
- dev_err(&pdev->dev, "ATL1e: Cannot enable PCI"
- " device from suspend\n");
+ netdev_err(adapter->netdev,
+ "Cannot enable PCI device from suspend\n");
return err;
}
@@ -2254,38 +2257,45 @@ static void atl1e_shutdown(struct pci_dev *pdev)
atl1e_suspend(pdev, PMSG_SUSPEND);
}
+static const struct net_device_ops atl1e_netdev_ops = {
+ .ndo_open = atl1e_open,
+ .ndo_stop = atl1e_close,
+ .ndo_start_xmit = atl1e_xmit_frame,
+ .ndo_get_stats = atl1e_get_stats,
+ .ndo_set_rx_mode = atl1e_set_multi,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = atl1e_set_mac_addr,
+ .ndo_fix_features = atl1e_fix_features,
+ .ndo_set_features = atl1e_set_features,
+ .ndo_change_mtu = atl1e_change_mtu,
+ .ndo_do_ioctl = atl1e_ioctl,
+ .ndo_tx_timeout = atl1e_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl1e_netpoll,
+#endif
+
+};
+
static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
{
SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);
- netdev->irq = pdev->irq;
- netdev->open = &atl1e_open;
- netdev->stop = &atl1e_close;
- netdev->hard_start_xmit = &atl1e_xmit_frame;
- netdev->get_stats = &atl1e_get_stats;
- netdev->set_multicast_list = &atl1e_set_multi;
- netdev->set_mac_address = &atl1e_set_mac_addr;
- netdev->change_mtu = &atl1e_change_mtu;
- netdev->do_ioctl = &atl1e_ioctl;
- netdev->tx_timeout = &atl1e_tx_timeout;
+ netdev->netdev_ops = &atl1e_netdev_ops;
+
netdev->watchdog_timeo = AT_TX_WATCHDOG;
- netdev->vlan_rx_register = atl1e_vlan_rx_register;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = atl1e_netpoll;
-#endif
atl1e_set_ethtool_ops(netdev);
- netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- netdev->features |= NETIF_F_LLTX;
- netdev->features |= NETIF_F_TSO;
- netdev->features |= NETIF_F_TSO6;
-
+ netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
+ NETIF_F_HW_VLAN_CTAG_RX;
+ netdev->features = netdev->hw_features | NETIF_F_LLTX |
+ NETIF_F_HW_VLAN_CTAG_TX;
+ /* not enabled by default */
+ netdev->hw_features |= NETIF_F_RXALL | NETIF_F_RXFCS;
return 0;
}
-/*
+/**
* atl1e_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in atl1e_pci_tbl
@@ -2296,8 +2306,7 @@ static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
* The OS initialization, configuring of the adapter private structure,
* and a hardware reset occur.
*/
-static int __devinit atl1e_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *netdev;
struct atl1e_adapter *adapter = NULL;
@@ -2321,8 +2330,8 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
* various kernel subsystems to support the mechanics required by a
* fixed-high-32-bit system.
*/
- if ((pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) ||
- (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) != 0)) {
+ if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+ (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
goto err_dma;
}
@@ -2338,13 +2347,12 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
netdev = alloc_etherdev(sizeof(struct atl1e_adapter));
if (netdev == NULL) {
err = -ENOMEM;
- dev_err(&pdev->dev, "etherdev alloc failed\n");
goto err_alloc_etherdev;
}
err = atl1e_init_netdev(netdev, pdev);
if (err) {
- dev_err(&pdev->dev, "init netdevice failed\n");
+ netdev_err(netdev, "init netdevice failed\n");
goto err_init_netdev;
}
adapter = netdev_priv(netdev);
@@ -2355,10 +2363,9 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
adapter->hw.hw_addr = pci_iomap(pdev, BAR_0, 0);
if (!adapter->hw.hw_addr) {
err = -EIO;
- dev_err(&pdev->dev, "cannot map device registers\n");
+ netdev_err(netdev, "cannot map device registers\n");
goto err_ioremap;
}
- netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
/* init mii data */
adapter->mii.dev = netdev;
@@ -2370,7 +2377,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64);
init_timer(&adapter->phy_config_timer);
- adapter->phy_config_timer.function = &atl1e_phy_config;
+ adapter->phy_config_timer.function = atl1e_phy_config;
adapter->phy_config_timer.data = (unsigned long) adapter;
/* get user settings */
@@ -2385,14 +2392,12 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
/* setup the private structure */
err = atl1e_sw_init(adapter);
if (err) {
- dev_err(&pdev->dev, "net device private data init failed\n");
+ netdev_err(netdev, "net device private data init failed\n");
goto err_sw_init;
}
/* Init GPHY as early as possible due to power saving issue */
- spin_lock(&adapter->mdio_lock);
atl1e_phy_init(&adapter->hw);
- spin_unlock(&adapter->mdio_lock);
/* reset the controller to
* put the device in a known good starting state */
err = atl1e_reset_hw(&adapter->hw);
@@ -2403,22 +2408,19 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
if (atl1e_read_mac_addr(&adapter->hw) != 0) {
err = -EIO;
- dev_err(&pdev->dev, "get mac address failed\n");
+ netdev_err(netdev, "get mac address failed\n");
goto err_eeprom;
}
memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
- memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
- dev_dbg(&pdev->dev, "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n",
- adapter->hw.mac_addr[0], adapter->hw.mac_addr[1],
- adapter->hw.mac_addr[2], adapter->hw.mac_addr[3],
- adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]);
+ netdev_dbg(netdev, "mac address : %pM\n", adapter->hw.mac_addr);
INIT_WORK(&adapter->reset_task, atl1e_reset_task);
INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
+ netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE);
err = register_netdev(netdev);
if (err) {
- dev_err(&pdev->dev, "register netdevice failed\n");
+ netdev_err(netdev, "register netdevice failed\n");
goto err_register;
}
@@ -2434,7 +2436,7 @@ err_reset:
err_register:
err_sw_init:
err_eeprom:
- iounmap(adapter->hw.hw_addr);
+ pci_iounmap(pdev, adapter->hw.hw_addr);
err_init_netdev:
err_ioremap:
free_netdev(netdev);
@@ -2446,7 +2448,7 @@ err_dma:
return err;
}
-/*
+/**
* atl1e_remove - Device Removal Routine
* @pdev: PCI device information struct
*
@@ -2455,7 +2457,7 @@ err_dma:
* Hot-Plug event, or because the driver is going to be removed from
* memory.
*/
-static void __devexit atl1e_remove(struct pci_dev *pdev)
+static void atl1e_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1e_adapter *adapter = netdev_priv(netdev);
@@ -2472,13 +2474,13 @@ static void __devexit atl1e_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
atl1e_free_ring_resources(adapter);
atl1e_force_ps(&adapter->hw);
- iounmap(adapter->hw.hw_addr);
+ pci_iounmap(pdev, adapter->hw.hw_addr);
pci_release_regions(pdev);
free_netdev(netdev);
pci_disable_device(pdev);
}
-/*
+/**
* atl1e_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
* @state: The current pci connection state
@@ -2490,10 +2492,13 @@ static pci_ers_result_t
atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct atl1e_adapter *adapter = netdev->priv;
+ struct atl1e_adapter *adapter = netdev_priv(netdev);
netif_device_detach(netdev);
+ if (state == pci_channel_io_perm_failure)
+ return PCI_ERS_RESULT_DISCONNECT;
+
if (netif_running(netdev))
atl1e_down(adapter);
@@ -2503,7 +2508,7 @@ atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
return PCI_ERS_RESULT_NEED_RESET;
}
-/*
+/**
* atl1e_io_slot_reset - called after the pci bus has been reset.
* @pdev: Pointer to PCI device
*
@@ -2513,11 +2518,11 @@ atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct atl1e_adapter *adapter = netdev->priv;
+ struct atl1e_adapter *adapter = netdev_priv(netdev);
if (pci_enable_device(pdev)) {
- dev_err(&pdev->dev,
- "ATL1e: Cannot re-enable PCI device after reset.\n");
+ netdev_err(adapter->netdev,
+ "Cannot re-enable PCI device after reset\n");
return PCI_ERS_RESULT_DISCONNECT;
}
pci_set_master(pdev);
@@ -2530,7 +2535,7 @@ static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
return PCI_ERS_RESULT_RECOVERED;
}
-/*
+/**
* atl1e_io_resume - called when traffic can start flowing again.
* @pdev: Pointer to PCI device
*
@@ -2541,12 +2546,12 @@ static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
static void atl1e_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct atl1e_adapter *adapter = netdev->priv;
+ struct atl1e_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev)) {
if (atl1e_up(adapter)) {
- dev_err(&pdev->dev,
- "ATL1e: can't bring device back up after reset\n");
+ netdev_err(adapter->netdev,
+ "can't bring device back up after reset\n");
return;
}
}
@@ -2554,7 +2559,7 @@ static void atl1e_io_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
}
-static struct pci_error_handlers atl1e_err_handler = {
+static const struct pci_error_handlers atl1e_err_handler = {
.error_detected = atl1e_io_error_detected,
.slot_reset = atl1e_io_slot_reset,
.resume = atl1e_io_resume,
@@ -2564,8 +2569,8 @@ static struct pci_driver atl1e_driver = {
.name = atl1e_driver_name,
.id_table = atl1e_pci_tbl,
.probe = atl1e_probe,
- .remove = __devexit_p(atl1e_remove),
- /* Power Managment Hooks */
+ .remove = atl1e_remove,
+ /* Power Management Hooks */
#ifdef CONFIG_PM
.suspend = atl1e_suspend,
.resume = atl1e_resume,
@@ -2574,27 +2579,4 @@ static struct pci_driver atl1e_driver = {
.err_handler = &atl1e_err_handler
};
-/*
- * atl1e_init_module - Driver Registration Routine
- *
- * atl1e_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1e_init_module(void)
-{
- return pci_register_driver(&atl1e_driver);
-}
-
-/*
- * atl1e_exit_module - Driver Exit Cleanup Routine
- *
- * atl1e_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1e_exit_module(void)
-{
- pci_unregister_driver(&atl1e_driver);
-}
-
-module_init(atl1e_init_module);
-module_exit(atl1e_exit_module);
+module_pci_driver(atl1e_driver);
diff --git a/drivers/net/atl1e/atl1e_param.c b/drivers/net/ethernet/atheros/atl1e/atl1e_param.c
index f72abb34b0c..fa314282c9a 100644
--- a/drivers/net/atl1e/atl1e_param.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_param.c
@@ -40,8 +40,8 @@
#define ATL1E_PARAM_INIT { [0 ... ATL1E_MAX_NIC] = OPTION_UNSET }
#define ATL1E_PARAM(x, desc) \
- static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
- static int num_##x; \
+ static int x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
+ static unsigned int num_##x; \
module_param_array_named(x, x, int, &num_##x, 0); \
MODULE_PARM_DESC(x, desc);
@@ -116,7 +116,8 @@ struct atl1e_option {
} arg;
};
-static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt, struct pci_dev *pdev)
+static int atl1e_validate_option(int *value, struct atl1e_option *opt,
+ struct atl1e_adapter *adapter)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
@@ -127,16 +128,19 @@ static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt,
case enable_option:
switch (*value) {
case OPTION_ENABLED:
- dev_info(&pdev->dev, "%s Enabled\n", opt->name);
+ netdev_info(adapter->netdev,
+ "%s Enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
- dev_info(&pdev->dev, "%s Disabled\n", opt->name);
+ netdev_info(adapter->netdev,
+ "%s Disabled\n", opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
- dev_info(&pdev->dev, "%s set to %i\n", opt->name, *value);
+ netdev_info(adapter->netdev, "%s set to %i\n",
+ opt->name, *value);
return 0;
}
break;
@@ -148,8 +152,8 @@ static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt,
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
- dev_info(&pdev->dev, "%s\n",
- ent->str);
+ netdev_info(adapter->netdev,
+ "%s\n", ent->str);
return 0;
}
}
@@ -159,13 +163,13 @@ static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt,
BUG();
}
- dev_info(&pdev->dev, "Invalid %s specified (%i) %s\n",
- opt->name, *value, opt->err);
+ netdev_info(adapter->netdev, "Invalid %s specified (%i) %s\n",
+ opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
-/*
+/**
* atl1e_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
@@ -174,13 +178,15 @@ static int __devinit atl1e_validate_option(int *value, struct atl1e_option *opt,
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
*/
-void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
+void atl1e_check_options(struct atl1e_adapter *adapter)
{
- struct pci_dev *pdev = adapter->pdev;
int bd = adapter->bd_number;
+
if (bd >= ATL1E_MAX_NIC) {
- dev_notice(&pdev->dev, "no configuration for board #%i\n", bd);
- dev_notice(&pdev->dev, "Using defaults for all values\n");
+ netdev_notice(adapter->netdev,
+ "no configuration for board #%i\n", bd);
+ netdev_notice(adapter->netdev,
+ "Using defaults for all values\n");
}
{ /* Transmit Ring Size */
@@ -196,7 +202,7 @@ void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
int val;
if (num_tx_desc_cnt > bd) {
val = tx_desc_cnt[bd];
- atl1e_validate_option(&val, &opt, pdev);
+ atl1e_validate_option(&val, &opt, adapter);
adapter->tx_ring.count = (u16) val & 0xFFFC;
} else
adapter->tx_ring.count = (u16)opt.def;
@@ -215,7 +221,7 @@ void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
int val;
if (num_rx_mem_size > bd) {
val = rx_mem_size[bd];
- atl1e_validate_option(&val, &opt, pdev);
+ atl1e_validate_option(&val, &opt, adapter);
adapter->rx_ring.page_size = (u32)val * 1024;
} else {
adapter->rx_ring.page_size = (u32)opt.def * 1024;
@@ -235,7 +241,7 @@ void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
int val;
if (num_int_mod_timer > bd) {
val = int_mod_timer[bd];
- atl1e_validate_option(&val, &opt, pdev);
+ atl1e_validate_option(&val, &opt, adapter);
adapter->hw.imt = (u16) val;
} else
adapter->hw.imt = (u16)(opt.def);
@@ -254,7 +260,7 @@ void __devinit atl1e_check_options(struct atl1e_adapter *adapter)
int val;
if (num_media_type > bd) {
val = media_type[bd];
- atl1e_validate_option(&val, &opt, pdev);
+ atl1e_validate_option(&val, &opt, adapter);
adapter->hw.media_type = (u16) val;
} else
adapter->hw.media_type = (u16)(opt.def);
diff --git a/drivers/net/ethernet/atheros/atlx/Makefile b/drivers/net/ethernet/atheros/atlx/Makefile
new file mode 100644
index 00000000000..e4f6022ca55
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atlx/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ATL1) += atl1.o
+obj-$(CONFIG_ATL2) += atl2.o
+
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index e23ce77712f..b460db7919a 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -24,16 +24,12 @@
* file called COPYING.
*
* Contact Information:
- * Xiong Huang <xiong_huang@attansic.com>
- * Attansic Technology Corp. 3F 147, Xianzheng 9th Road, Zhubei,
- * Xinzhu 302, TAIWAN, REPUBLIC OF CHINA
- *
+ * Xiong Huang <xiong.huang@atheros.com>
+ * Jie Yang <jie.yang@atheros.com>
* Chris Snook <csnook@redhat.com>
* Jay Cliburn <jcliburn@gmail.com>
*
- * This version is adapted from the Attansic reference driver for
- * inclusion in the Linux kernel. It is currently under heavy development.
- * A very incomplete list of things that need to be dealt with:
+ * This version is adapted from the Attansic reference driver.
*
* TODO:
* Add more ethtool functions.
@@ -48,7 +44,7 @@
* SMP torture testing
*/
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <asm/byteorder.h>
#include <linux/compiler.h>
@@ -86,9 +82,18 @@
#include "atl1.h"
+#define ATLX_DRIVER_VERSION "2.1.3"
+MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, "
+ "Chris Snook <csnook@redhat.com>, "
+ "Jay Cliburn <jcliburn@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATLX_DRIVER_VERSION);
+
/* Temporary hack for merging atl1 and atl2 */
#include "atlx.c"
+static const struct ethtool_ops atl1_ethtool_ops;
+
/*
* This is the only thing that needs to be changed to adjust the
* maximum number of ports that the driver can manage.
@@ -108,8 +113,8 @@
*
* Default Value: 100 (200us)
*/
-static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
-static int num_int_mod_timer;
+static int int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
+static unsigned int num_int_mod_timer;
module_param_array_named(int_mod_timer, int_mod_timer, int,
&num_int_mod_timer, 0);
MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
@@ -138,8 +143,8 @@ struct atl1_option {
} arg;
};
-static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
- struct pci_dev *pdev)
+static int atl1_validate_option(int *value, struct atl1_option *opt,
+ struct pci_dev *pdev)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
@@ -190,7 +195,7 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
return -1;
}
-/*
+/**
* atl1_check_options - Range Checking for Command Line Parameters
* @adapter: board private structure
*
@@ -199,7 +204,7 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
* value exists, a default value is used. The final value is stored
* in a variable in the adapter structure.
*/
-void __devinit atl1_check_options(struct atl1_adapter *adapter)
+static void atl1_check_options(struct atl1_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
int bd = adapter->bd_number;
@@ -230,7 +235,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
/*
* atl1_pci_tbl - PCI Device ID Table
*/
-static const struct pci_device_id atl1_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(atl1_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1)},
/* required last entry */
{0,}
@@ -261,7 +266,7 @@ static s32 atl1_reset_hw(struct atl1_hw *hw)
* interrupts & Clear any pending interrupt events
*/
/*
- * iowrite32(0, hw->hw_addr + REG_IMR);
+ * atlx_irq_disable(adapter);
* iowrite32(0xffffffff, hw->hw_addr + REG_ISR);
*/
@@ -351,7 +356,7 @@ static bool atl1_read_eeprom(struct atl1_hw *hw, u32 offset, u32 *p_value)
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to read
*/
-s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
+static s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
{
u32 val;
int i;
@@ -527,16 +532,19 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
* Reads the adapter's MAC address from the EEPROM
* hw - Struct containing variables accessed by shared code
*/
-s32 atl1_read_mac_addr(struct atl1_hw *hw)
+static s32 atl1_read_mac_addr(struct atl1_hw *hw)
{
+ s32 ret = 0;
u16 i;
- if (atl1_get_permanent_address(hw))
- random_ether_addr(hw->perm_mac_addr);
+ if (atl1_get_permanent_address(hw)) {
+ eth_random_addr(hw->perm_mac_addr);
+ ret = 1;
+ }
for (i = 0; i < ETH_ALEN; i++)
hw->mac_addr[i] = hw->perm_mac_addr[i];
- return 0;
+ return ret;
}
/*
@@ -551,7 +559,7 @@ s32 atl1_read_mac_addr(struct atl1_hw *hw)
* 1. calcu 32bit CRC for multicast address
* 2. reverse crc with MSB to LSB
*/
-u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
+static u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
{
u32 crc32, value = 0;
int i;
@@ -568,7 +576,7 @@ u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr)
* hw - Struct containing variables accessed by shared code
* hash_value - Multicast address hash value
*/
-void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
+static void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
{
u32 hash_bit, hash_reg;
u32 mta;
@@ -853,7 +861,7 @@ static s32 atl1_init_hw(struct atl1_hw *hw)
atl1_init_flash_opcode(hw);
if (!hw->phy_configured) {
- /* enable GPHY LinkChange Interrrupt */
+ /* enable GPHY LinkChange Interrupt */
ret_val = atl1_write_phy_reg(hw, 18, 0xC00);
if (ret_val)
return ret_val;
@@ -912,7 +920,7 @@ static s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex
return 0;
}
-void atl1_set_mac_addr(struct atl1_hw *hw)
+static void atl1_set_mac_addr(struct atl1_hw *hw)
{
u32 value;
/*
@@ -929,7 +937,7 @@ void atl1_set_mac_addr(struct atl1_hw *hw)
iowrite32(value, (hw->hw_addr + REG_MAC_STA_ADDR) + (1 << 2));
}
-/*
+/**
* atl1_sw_init - Initialize general software structures (struct atl1_adapter)
* @adapter: board private structure to initialize
*
@@ -937,7 +945,7 @@ void atl1_set_mac_addr(struct atl1_hw *hw)
* Fields are initialized based on PCI device information and
* OS network device settings (MTU size).
*/
-static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
+static int atl1_sw_init(struct atl1_adapter *adapter)
{
struct atl1_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
@@ -946,6 +954,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
adapter->wol = 0;
+ device_set_wakeup_enable(&adapter->pdev->dev, false);
adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
adapter->ict = 50000; /* 100ms */
adapter->link_speed = SPEED_0; /* hardware init */
@@ -1005,12 +1014,6 @@ static void mdio_write(struct net_device *netdev, int phy_id, int reg_num,
atl1_write_phy_reg(&adapter->hw, reg_num, val);
}
-/*
- * atl1_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
@@ -1027,7 +1030,7 @@ static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
return retval;
}
-/*
+/**
* atl1_setup_mem_resources - allocate Tx / RX descriptor resources
* @adapter: board private structure
*
@@ -1052,7 +1055,7 @@ static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
goto err_nomem;
}
rfd_ring->buffer_info =
- (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
+ (tpd_ring->buffer_info + tpd_ring->count);
/*
* real ring DMA buffer
@@ -1138,7 +1141,7 @@ static void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
atomic_set(&rrd_ring->next_to_clean, 0);
}
-/*
+/**
* atl1_clean_rx_ring - Free RFD Buffers
* @adapter: board private structure
*/
@@ -1178,7 +1181,7 @@ static void atl1_clean_rx_ring(struct atl1_adapter *adapter)
atomic_set(&rrd_ring->next_to_clean, 0);
}
-/*
+/**
* atl1_clean_tx_ring - Free Tx Buffers
* @adapter: board private structure
*/
@@ -1218,7 +1221,7 @@ static void atl1_clean_tx_ring(struct atl1_adapter *adapter)
atomic_set(&tpd_ring->next_to_clean, 0);
}
-/*
+/**
* atl1_free_ring_resources - Free Tx / RX descriptor Resources
* @adapter: board private structure
*
@@ -1249,6 +1252,12 @@ static void atl1_free_ring_resources(struct atl1_adapter *adapter)
rrd_ring->desc = NULL;
rrd_ring->dma = 0;
+
+ adapter->cmb.dma = 0;
+ adapter->cmb.cmb = NULL;
+
+ adapter->smb.dma = 0;
+ adapter->smb.smb = NULL;
}
static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
@@ -1273,8 +1282,7 @@ static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
value |= (((u32) adapter->hw.preamble_len
& MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
/* vlan */
- if (adapter->vlgrp)
- value |= MAC_CTRL_RMV_VLAN;
+ __atlx_vlan_mode(netdev->features, &value);
/* rx checksum
if (adapter->rx_csum)
value |= MAC_CTRL_RX_CHKSUM_EN;
@@ -1342,8 +1350,8 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
/* link result is our setting */
if (!reconfig) {
- if (adapter->link_speed != speed
- || adapter->link_duplex != duplex) {
+ if (adapter->link_speed != speed ||
+ adapter->link_duplex != duplex) {
adapter->link_speed = speed;
adapter->link_duplex = duplex;
atl1_setup_mac_ctrl(adapter);
@@ -1394,7 +1402,8 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
/* auto-neg, insert timer to re-config phy */
if (!adapter->phy_timer_pending) {
adapter->phy_timer_pending = true;
- mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ);
+ mod_timer(&adapter->phy_config_timer,
+ round_jiffies(jiffies + 3 * HZ));
}
return 0;
@@ -1455,7 +1464,7 @@ static void set_flow_ctrl_new(struct atl1_hw *hw)
iowrite32(value, hw->hw_addr + REG_RXQ_RRD_PAUSE_THRESH);
}
-/*
+/**
* atl1_configure - Configure Transmit&Receive Unit after Reset
* @adapter: board private structure
*
@@ -1666,35 +1675,45 @@ static void atl1_via_workaround(struct atl1_adapter *adapter)
static void atl1_inc_smb(struct atl1_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
struct stats_msg_block *smb = adapter->smb.smb;
+ u64 new_rx_errors = smb->rx_frag +
+ smb->rx_fcs_err +
+ smb->rx_len_err +
+ smb->rx_sz_ov +
+ smb->rx_rxf_ov +
+ smb->rx_rrd_ov +
+ smb->rx_align_err;
+ u64 new_tx_errors = smb->tx_late_col +
+ smb->tx_abort_col +
+ smb->tx_underrun +
+ smb->tx_trunc;
+
/* Fill out the OS statistics structure */
- adapter->soft_stats.rx_packets += smb->rx_ok;
- adapter->soft_stats.tx_packets += smb->tx_ok;
+ adapter->soft_stats.rx_packets += smb->rx_ok + new_rx_errors;
+ adapter->soft_stats.tx_packets += smb->tx_ok + new_tx_errors;
adapter->soft_stats.rx_bytes += smb->rx_byte_cnt;
adapter->soft_stats.tx_bytes += smb->tx_byte_cnt;
adapter->soft_stats.multicast += smb->rx_mcast;
- adapter->soft_stats.collisions += (smb->tx_1_col + smb->tx_2_col * 2 +
- smb->tx_late_col + smb->tx_abort_col * adapter->hw.max_retry);
+ adapter->soft_stats.collisions += smb->tx_1_col +
+ smb->tx_2_col +
+ smb->tx_late_col +
+ smb->tx_abort_col;
/* Rx Errors */
- adapter->soft_stats.rx_errors += (smb->rx_frag + smb->rx_fcs_err +
- smb->rx_len_err + smb->rx_sz_ov + smb->rx_rxf_ov +
- smb->rx_rrd_ov + smb->rx_align_err);
+ adapter->soft_stats.rx_errors += new_rx_errors;
adapter->soft_stats.rx_fifo_errors += smb->rx_rxf_ov;
adapter->soft_stats.rx_length_errors += smb->rx_len_err;
adapter->soft_stats.rx_crc_errors += smb->rx_fcs_err;
adapter->soft_stats.rx_frame_errors += smb->rx_align_err;
- adapter->soft_stats.rx_missed_errors += (smb->rx_rrd_ov +
- smb->rx_rxf_ov);
adapter->soft_stats.rx_pause += smb->rx_pause;
adapter->soft_stats.rx_rrd_ov += smb->rx_rrd_ov;
adapter->soft_stats.rx_trunc += smb->rx_sz_ov;
/* Tx Errors */
- adapter->soft_stats.tx_errors += (smb->tx_late_col +
- smb->tx_abort_col + smb->tx_underrun + smb->tx_trunc);
+ adapter->soft_stats.tx_errors += new_tx_errors;
adapter->soft_stats.tx_fifo_errors += smb->tx_underrun;
adapter->soft_stats.tx_aborted_errors += smb->tx_abort_col;
adapter->soft_stats.tx_window_errors += smb->tx_late_col;
@@ -1708,31 +1727,29 @@ static void atl1_inc_smb(struct atl1_adapter *adapter)
adapter->soft_stats.tx_trunc += smb->tx_trunc;
adapter->soft_stats.tx_pause += smb->tx_pause;
- adapter->net_stats.rx_packets = adapter->soft_stats.rx_packets;
- adapter->net_stats.tx_packets = adapter->soft_stats.tx_packets;
- adapter->net_stats.rx_bytes = adapter->soft_stats.rx_bytes;
- adapter->net_stats.tx_bytes = adapter->soft_stats.tx_bytes;
- adapter->net_stats.multicast = adapter->soft_stats.multicast;
- adapter->net_stats.collisions = adapter->soft_stats.collisions;
- adapter->net_stats.rx_errors = adapter->soft_stats.rx_errors;
- adapter->net_stats.rx_over_errors =
- adapter->soft_stats.rx_missed_errors;
- adapter->net_stats.rx_length_errors =
+ netdev->stats.rx_bytes = adapter->soft_stats.rx_bytes;
+ netdev->stats.tx_bytes = adapter->soft_stats.tx_bytes;
+ netdev->stats.multicast = adapter->soft_stats.multicast;
+ netdev->stats.collisions = adapter->soft_stats.collisions;
+ netdev->stats.rx_errors = adapter->soft_stats.rx_errors;
+ netdev->stats.rx_length_errors =
adapter->soft_stats.rx_length_errors;
- adapter->net_stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
- adapter->net_stats.rx_frame_errors =
+ netdev->stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
+ netdev->stats.rx_frame_errors =
adapter->soft_stats.rx_frame_errors;
- adapter->net_stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
- adapter->net_stats.rx_missed_errors =
- adapter->soft_stats.rx_missed_errors;
- adapter->net_stats.tx_errors = adapter->soft_stats.tx_errors;
- adapter->net_stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
- adapter->net_stats.tx_aborted_errors =
+ netdev->stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
+ netdev->stats.rx_dropped = adapter->soft_stats.rx_rrd_ov;
+ netdev->stats.tx_errors = adapter->soft_stats.tx_errors;
+ netdev->stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
+ netdev->stats.tx_aborted_errors =
adapter->soft_stats.tx_aborted_errors;
- adapter->net_stats.tx_window_errors =
+ netdev->stats.tx_window_errors =
adapter->soft_stats.tx_window_errors;
- adapter->net_stats.tx_carrier_errors =
+ netdev->stats.tx_carrier_errors =
adapter->soft_stats.tx_carrier_errors;
+
+ netdev->stats.rx_packets = adapter->soft_stats.rx_packets;
+ netdev->stats.tx_packets = adapter->soft_stats.tx_packets;
}
static void atl1_update_mailbox(struct atl1_adapter *adapter)
@@ -1801,7 +1818,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
* the higher layers and let it be sorted out there.
*/
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
@@ -1826,11 +1843,9 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
adapter->hw_csum_good++;
return;
}
-
- return;
}
-/*
+/**
* atl1_alloc_rx_buffers - Replace used receive buffers
* @adapter: address of board private structure
*/
@@ -1860,21 +1875,14 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
- skb = netdev_alloc_skb(adapter->netdev,
- adapter->rx_buffer_len + NET_IP_ALIGN);
+ skb = netdev_alloc_skb_ip_align(adapter->netdev,
+ adapter->rx_buffer_len);
if (unlikely(!skb)) {
/* Better luck next round */
- adapter->net_stats.rx_dropped++;
+ adapter->soft_stats.rx_dropped++;
break;
}
- /*
- * Make buffer alignment 2 beyond a 16 byte boundary
- * this will result in a 16 byte aligned IP header after
- * the 14 byte MAC header is removed
- */
- skb_reserve(skb, NET_IP_ALIGN);
-
buffer_info->alloced = 1;
buffer_info->skb = skb;
buffer_info->length = (u16) adapter->rx_buffer_len;
@@ -1910,7 +1918,7 @@ next:
return num_alloc;
}
-static void atl1_intr_rx(struct atl1_adapter *adapter)
+static int atl1_intr_rx(struct atl1_adapter *adapter, int budget)
{
int i, count;
u16 length;
@@ -1926,7 +1934,7 @@ static void atl1_intr_rx(struct atl1_adapter *adapter)
rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
- while (1) {
+ while (count < budget) {
rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
i = 1;
if (likely(rrd->xsz.valid)) { /* packet valid */
@@ -2018,20 +2026,19 @@ rrd_ok:
atl1_rx_checksum(adapter, rrd, skb);
skb->protocol = eth_type_trans(skb, adapter->netdev);
- if (adapter->vlgrp && (rrd->pkt_flg & PACKET_FLAG_VLAN_INS)) {
+ if (rrd->pkt_flg & PACKET_FLAG_VLAN_INS) {
u16 vlan_tag = (rrd->vlan_tag >> 4) |
((rrd->vlan_tag & 7) << 13) |
((rrd->vlan_tag & 8) << 9);
- vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag);
- } else
- netif_rx(skb);
+
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
+ }
+ netif_receive_skb(skb);
/* let protocol layer free skb */
buffer_info->skb = NULL;
buffer_info->alloced = 0;
rrd->xsz.valid = 0;
-
- adapter->netdev->last_rx = jiffies;
}
atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean);
@@ -2059,22 +2066,22 @@ rrd_ok:
iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
spin_unlock(&adapter->mb_lock);
}
+
+ return count;
}
-static void atl1_intr_tx(struct atl1_adapter *adapter)
+static int atl1_intr_tx(struct atl1_adapter *adapter)
{
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
struct atl1_buffer *buffer_info;
u16 sw_tpd_next_to_clean;
u16 cmb_tpd_next_to_clean;
+ int count = 0;
sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
- struct tx_packet_desc *tpd;
-
- tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
if (buffer_info->dma) {
pci_unmap_page(adapter->pdev, buffer_info->dma,
@@ -2089,37 +2096,39 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
if (++sw_tpd_next_to_clean == tpd_ring->count)
sw_tpd_next_to_clean = 0;
+
+ count++;
}
atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean);
- if (netif_queue_stopped(adapter->netdev)
- && netif_carrier_ok(adapter->netdev))
+ if (netif_queue_stopped(adapter->netdev) &&
+ netif_carrier_ok(adapter->netdev))
netif_wake_queue(adapter->netdev);
+
+ return count;
}
static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
{
u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
u16 next_to_use = atomic_read(&tpd_ring->next_to_use);
- return ((next_to_clean > next_to_use) ?
+ return (next_to_clean > next_to_use) ?
next_to_clean - next_to_use - 1 :
- tpd_ring->count + next_to_clean - next_to_use - 1);
+ tpd_ring->count + next_to_clean - next_to_use - 1;
}
static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
- struct tx_packet_desc *ptpd)
+ struct tx_packet_desc *ptpd)
{
- /* spinlock held */
u8 hdr_len, ip_off;
u32 real_len;
- int err;
if (skb_shinfo(skb)->gso_size) {
- if (skb_header_cloned(skb)) {
- err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
- if (unlikely(err))
- return -1;
- }
+ int err;
+
+ err = skb_cow_head(skb, 0);
+ if (err < 0)
+ return err;
if (skb->protocol == htons(ETH_P_IP)) {
struct iphdr *iph = ip_hdr(skb);
@@ -2165,7 +2174,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
return 3;
}
}
- return false;
+ return 0;
}
static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
@@ -2174,7 +2183,7 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
u8 css, cso;
if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
- css = (u8) (skb->csum_start - skb_headroom(skb));
+ css = skb_checksum_start_offset(skb);
cso = css + (u8) skb->csum_offset;
if (unlikely(css & 0x1)) {
/* L1 hardware requires an even number here */
@@ -2196,7 +2205,6 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
struct tx_packet_desc *ptpd)
{
- /* spinlock held */
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
struct atl1_buffer *buffer_info;
u16 buf_len = skb->len;
@@ -2213,8 +2221,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
nr_frags = skb_shinfo(skb)->nr_frags;
next_to_use = atomic_read(&tpd_ring->next_to_use);
buffer_info = &tpd_ring->buffer_info[next_to_use];
- if (unlikely(buffer_info->skb))
- BUG();
+ BUG_ON(buffer_info->skb);
/* put skb in last TPD */
buffer_info->skb = NULL;
@@ -2270,26 +2277,25 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
}
for (f = 0; f < nr_frags; f++) {
- struct skb_frag_struct *frag;
+ const struct skb_frag_struct *frag;
u16 i, nseg;
frag = &skb_shinfo(skb)->frags[f];
- buf_len = frag->size;
+ buf_len = skb_frag_size(frag);
nseg = (buf_len + ATL1_MAX_TX_BUF_LEN - 1) /
ATL1_MAX_TX_BUF_LEN;
for (i = 0; i < nseg; i++) {
buffer_info = &tpd_ring->buffer_info[next_to_use];
- if (unlikely(buffer_info->skb))
- BUG();
+ BUG_ON(buffer_info->skb);
+
buffer_info->skb = NULL;
buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
ATL1_MAX_TX_BUF_LEN : buf_len;
buf_len -= buffer_info->length;
- buffer_info->dma = pci_map_page(adapter->pdev,
- frag->page,
- frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN),
- buffer_info->length, PCI_DMA_TODEVICE);
+ buffer_info->dma = skb_frag_dma_map(&adapter->pdev->dev,
+ frag, i * ATL1_MAX_TX_BUF_LEN,
+ buffer_info->length, DMA_TO_DEVICE);
if (++next_to_use == tpd_ring->count)
next_to_use = 0;
@@ -2303,7 +2309,6 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
struct tx_packet_desc *ptpd)
{
- /* spinlock held */
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
struct atl1_buffer *buffer_info;
struct tx_packet_desc *tpd;
@@ -2317,7 +2322,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
if (tpd != ptpd)
memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
- tpd->word2 = (cpu_to_le16(buffer_info->length) &
+ tpd->word2 &= ~(TPD_BUFLEN_MASK << TPD_BUFLEN_SHIFT);
+ tpd->word2 |= (cpu_to_le16(buffer_info->length) &
TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
/*
@@ -2350,24 +2356,23 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
atomic_set(&tpd_ring->next_to_use, next_to_use);
}
-static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
+ struct net_device *netdev)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
- int len = skb->len;
+ int len;
int tso;
int count = 1;
int ret_val;
struct tx_packet_desc *ptpd;
- u16 frag_size;
u16 vlan_tag;
- unsigned long flags;
unsigned int nr_frags = 0;
unsigned int mss = 0;
unsigned int f;
unsigned int proto_hdr_len;
- len -= skb->data_len;
+ len = skb_headlen(skb);
if (unlikely(skb->len <= 0)) {
dev_kfree_skb_any(skb);
@@ -2376,15 +2381,14 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
nr_frags = skb_shinfo(skb)->nr_frags;
for (f = 0; f < nr_frags; f++) {
- frag_size = skb_shinfo(skb)->frags[f].size;
- if (frag_size)
- count += (frag_size + ATL1_MAX_TX_BUF_LEN - 1) /
- ATL1_MAX_TX_BUF_LEN;
+ unsigned int f_size = skb_frag_size(&skb_shinfo(skb)->frags[f]);
+ count += (f_size + ATL1_MAX_TX_BUF_LEN - 1) /
+ ATL1_MAX_TX_BUF_LEN;
}
mss = skb_shinfo(skb)->gso_size;
if (mss) {
- if (skb->protocol == ntohs(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
proto_hdr_len = (skb_transport_offset(skb) +
tcp_hdrlen(skb));
if (unlikely(proto_hdr_len > len)) {
@@ -2399,18 +2403,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}
- if (!spin_trylock_irqsave(&adapter->lock, flags)) {
- /* Can't get lock - tell upper layer to requeue */
- if (netif_msg_tx_queued(adapter))
- dev_printk(KERN_DEBUG, &adapter->pdev->dev,
- "tx locked\n");
- return NETDEV_TX_LOCKED;
- }
-
if (atl1_tpd_avail(&adapter->tpd_ring) < count) {
/* not enough descriptors */
netif_stop_queue(netdev);
- spin_unlock_irqrestore(&adapter->lock, flags);
if (netif_msg_tx_queued(adapter))
dev_printk(KERN_DEBUG, &adapter->pdev->dev,
"tx busy\n");
@@ -2421,18 +2416,17 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
(u16) atomic_read(&tpd_ring->next_to_use));
memset(ptpd, 0, sizeof(struct tx_packet_desc));
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
vlan_tag = vlan_tx_tag_get(skb);
vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
((vlan_tag >> 9) & 0x8);
ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
- ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) <<
- TPD_VL_TAGGED_SHIFT;
+ ptpd->word2 |= (vlan_tag & TPD_VLANTAG_MASK) <<
+ TPD_VLANTAG_SHIFT;
}
tso = atl1_tso(adapter, skb, ptpd);
if (tso < 0) {
- spin_unlock_irqrestore(&adapter->lock, flags);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -2440,7 +2434,6 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (!tso) {
ret_val = atl1_tx_csum(adapter, skb, ptpd);
if (ret_val < 0) {
- spin_unlock_irqrestore(&adapter->lock, flags);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -2449,112 +2442,138 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
atl1_tx_map(adapter, skb, ptpd);
atl1_tx_queue(adapter, count, ptpd);
atl1_update_mailbox(adapter);
- spin_unlock_irqrestore(&adapter->lock, flags);
- netdev->trans_start = jiffies;
+ mmiowb();
return NETDEV_TX_OK;
}
-/*
+static int atl1_rings_clean(struct napi_struct *napi, int budget)
+{
+ struct atl1_adapter *adapter = container_of(napi, struct atl1_adapter, napi);
+ int work_done = atl1_intr_rx(adapter, budget);
+
+ if (atl1_intr_tx(adapter))
+ work_done = budget;
+
+ /* Let's come again to process some more packets */
+ if (work_done >= budget)
+ return work_done;
+
+ napi_complete(napi);
+ /* re-enable Interrupt */
+ if (likely(adapter->int_enabled))
+ atlx_imr_set(adapter, IMR_NORMAL_MASK);
+ return work_done;
+}
+
+static inline int atl1_sched_rings_clean(struct atl1_adapter* adapter)
+{
+ if (!napi_schedule_prep(&adapter->napi))
+ /* It is possible in case even the RX/TX ints are disabled via IMR
+ * register the ISR bits are set anyway (but do not produce IRQ).
+ * To handle such situation the napi functions used to check is
+ * something scheduled or not.
+ */
+ return 0;
+
+ __napi_schedule(&adapter->napi);
+
+ /*
+ * Disable RX/TX ints via IMR register if it is
+ * allowed. NAPI handler must reenable them in same
+ * way.
+ */
+ if (!adapter->int_enabled)
+ return 1;
+
+ atlx_imr_set(adapter, IMR_NORXTX_MASK);
+ return 1;
+}
+
+/**
* atl1_intr - Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
*/
static irqreturn_t atl1_intr(int irq, void *data)
{
struct atl1_adapter *adapter = netdev_priv(data);
u32 status;
- int max_ints = 10;
status = adapter->cmb.cmb->int_stats;
if (!status)
return IRQ_NONE;
- do {
- /* clear CMB interrupt status at once */
- adapter->cmb.cmb->int_stats = 0;
-
- if (status & ISR_GPHY) /* clear phy status */
- atlx_clear_phy_int(adapter);
+ /* clear CMB interrupt status at once,
+ * but leave rx/tx interrupt status in case it should be dropped
+ * only if rx/tx processing queued. In other case interrupt
+ * can be lost.
+ */
+ adapter->cmb.cmb->int_stats = status & (ISR_CMB_TX | ISR_CMB_RX);
- /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
- iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
+ if (status & ISR_GPHY) /* clear phy status */
+ atlx_clear_phy_int(adapter);
- /* check if SMB intr */
- if (status & ISR_SMB)
- atl1_inc_smb(adapter);
+ /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
+ iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
- /* check if PCIE PHY Link down */
- if (status & ISR_PHY_LINKDOWN) {
- if (netif_msg_intr(adapter))
- dev_printk(KERN_DEBUG, &adapter->pdev->dev,
- "pcie phy link down %x\n", status);
- if (netif_running(adapter->netdev)) { /* reset MAC */
- iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
- return IRQ_HANDLED;
- }
- }
+ /* check if SMB intr */
+ if (status & ISR_SMB)
+ atl1_inc_smb(adapter);
- /* check if DMA read/write error ? */
- if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
- if (netif_msg_intr(adapter))
- dev_printk(KERN_DEBUG, &adapter->pdev->dev,
- "pcie DMA r/w error (status = 0x%x)\n",
- status);
- iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
+ /* check if PCIE PHY Link down */
+ if (status & ISR_PHY_LINKDOWN) {
+ if (netif_msg_intr(adapter))
+ dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+ "pcie phy link down %x\n", status);
+ if (netif_running(adapter->netdev)) { /* reset MAC */
+ atlx_irq_disable(adapter);
+ schedule_work(&adapter->reset_dev_task);
return IRQ_HANDLED;
}
+ }
- /* link event */
- if (status & ISR_GPHY) {
- adapter->soft_stats.tx_carrier_errors++;
- atl1_check_for_link(adapter);
- }
+ /* check if DMA read/write error ? */
+ if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+ if (netif_msg_intr(adapter))
+ dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+ "pcie DMA r/w error (status = 0x%x)\n",
+ status);
+ atlx_irq_disable(adapter);
+ schedule_work(&adapter->reset_dev_task);
+ return IRQ_HANDLED;
+ }
- /* transmit event */
- if (status & ISR_CMB_TX)
- atl1_intr_tx(adapter);
-
- /* rx exception */
- if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
- ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
- ISR_HOST_RRD_OV | ISR_CMB_RX))) {
- if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
- ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
- ISR_HOST_RRD_OV))
- if (netif_msg_intr(adapter))
- dev_printk(KERN_DEBUG,
- &adapter->pdev->dev,
- "rx exception, ISR = 0x%x\n",
- status);
- atl1_intr_rx(adapter);
- }
+ /* link event */
+ if (status & ISR_GPHY) {
+ adapter->soft_stats.tx_carrier_errors++;
+ atl1_check_for_link(adapter);
+ }
- if (--max_ints < 0)
- break;
+ /* transmit or receive event */
+ if (status & (ISR_CMB_TX | ISR_CMB_RX) &&
+ atl1_sched_rings_clean(adapter))
+ adapter->cmb.cmb->int_stats = adapter->cmb.cmb->int_stats &
+ ~(ISR_CMB_TX | ISR_CMB_RX);
- } while ((status = adapter->cmb.cmb->int_stats));
+ /* rx exception */
+ if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
+ ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
+ ISR_HOST_RRD_OV))) {
+ if (netif_msg_intr(adapter))
+ dev_printk(KERN_DEBUG,
+ &adapter->pdev->dev,
+ "rx exception, ISR = 0x%x\n",
+ status);
+ atl1_sched_rings_clean(adapter);
+ }
/* re-enable Interrupt */
iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
return IRQ_HANDLED;
}
-/*
- * atl1_watchdog - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl1_watchdog(unsigned long data)
-{
- struct atl1_adapter *adapter = (struct atl1_adapter *)data;
-
- /* Reset the timer */
- mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-}
-/*
+/**
* atl1_phy_config - Timer Call-back
* @data: pointer to netdev cast into an unsigned long
*/
@@ -2596,7 +2615,7 @@ static s32 atl1_up(struct atl1_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
int err;
- int irq_flags = IRQF_SAMPLE_RANDOM;
+ int irq_flags = 0;
/* hardware has been reset, we need to reload some things */
atlx_set_multi(netdev);
@@ -2620,12 +2639,12 @@ static s32 atl1_up(struct atl1_adapter *adapter)
irq_flags |= IRQF_SHARED;
}
- err = request_irq(adapter->pdev->irq, &atl1_intr, irq_flags,
+ err = request_irq(adapter->pdev->irq, atl1_intr, irq_flags,
netdev->name, netdev);
if (unlikely(err))
goto err_up;
- mod_timer(&adapter->watchdog_timer, jiffies);
+ napi_enable(&adapter->napi);
atlx_irq_enable(adapter);
atl1_check_link(adapter);
netif_start_queue(netdev);
@@ -2642,7 +2661,8 @@ static void atl1_down(struct atl1_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- del_timer_sync(&adapter->watchdog_timer);
+ napi_disable(&adapter->napi);
+ netif_stop_queue(netdev);
del_timer_sync(&adapter->phy_config_timer);
adapter->phy_timer_pending = false;
@@ -2655,16 +2675,15 @@ static void atl1_down(struct atl1_adapter *adapter)
adapter->link_speed = SPEED_0;
adapter->link_duplex = -1;
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
atl1_clean_tx_ring(adapter);
atl1_clean_rx_ring(adapter);
}
-static void atl1_tx_timeout_task(struct work_struct *work)
+static void atl1_reset_dev_task(struct work_struct *work)
{
struct atl1_adapter *adapter =
- container_of(work, struct atl1_adapter, tx_timeout_task);
+ container_of(work, struct atl1_adapter, reset_dev_task);
struct net_device *netdev = adapter->netdev;
netif_device_detach(netdev);
@@ -2673,7 +2692,7 @@ static void atl1_tx_timeout_task(struct work_struct *work)
netif_device_attach(netdev);
}
-/*
+/**
* atl1_change_mtu - Change the Maximum Transfer Unit
* @netdev: network interface device structure
* @new_mtu: new value for maximum frame size
@@ -2707,7 +2726,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
return 0;
}
-/*
+/**
* atl1_open - Called when a network interface is made active
* @netdev: network interface device structure
*
@@ -2724,6 +2743,8 @@ static int atl1_open(struct net_device *netdev)
struct atl1_adapter *adapter = netdev_priv(netdev);
int err;
+ netif_carrier_off(netdev);
+
/* allocate transmit descriptors */
err = atl1_setup_ring_resources(adapter);
if (err)
@@ -2740,7 +2761,7 @@ err_up:
return err;
}
-/*
+/**
* atl1_close - Disables a network interface
* @netdev: network interface device structure
*
@@ -2759,16 +2780,16 @@ static int atl1_close(struct net_device *netdev)
return 0;
}
-#ifdef CONFIG_PM
-static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int atl1_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1_adapter *adapter = netdev_priv(netdev);
struct atl1_hw *hw = &adapter->hw;
u32 ctrl = 0;
u32 wufc = adapter->wol;
u32 val;
- int retval;
u16 speed;
u16 duplex;
@@ -2776,17 +2797,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
if (netif_running(netdev))
atl1_down(adapter);
- retval = pci_save_state(pdev);
- if (retval)
- return retval;
-
atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
val = ctrl & BMSR_LSTATUS;
if (val)
wufc &= ~ATLX_WUFC_LNKC;
+ if (!wufc)
+ goto disable_wol;
- if (val && wufc) {
+ if (val) {
val = atl1_get_speed_and_duplex(hw, &speed, &duplex);
if (val) {
if (netif_msg_ifdown(adapter))
@@ -2811,8 +2830,7 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
ctrl |= MAC_CTRL_DUPLX;
ctrl |= (((u32)adapter->hw.preamble_len &
MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
- if (adapter->vlgrp)
- ctrl |= MAC_CTRL_RMV_VLAN;
+ __atlx_vlan_mode(netdev->features, &ctrl);
if (wufc & ATLX_WUFC_MAG)
ctrl |= MAC_CTRL_BC_EN;
iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
@@ -2823,23 +2841,18 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
-
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
- goto exit;
- }
-
- if (!val && wufc) {
+ } else {
ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
ioread32(hw->hw_addr + REG_WOL_CTRL);
iowrite32(0, hw->hw_addr + REG_MAC_CTRL);
ioread32(hw->hw_addr + REG_MAC_CTRL);
hw->phy_configured = false;
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
- goto exit;
}
-disable_wol:
+ return 0;
+
+ disable_wol:
iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
ioread32(hw->hw_addr + REG_WOL_CTRL);
ctrl = ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
@@ -2847,57 +2860,42 @@ disable_wol:
iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC);
ioread32(hw->hw_addr + REG_PCIE_PHYMISC);
hw->phy_configured = false;
- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
-exit:
- if (netif_running(netdev))
- pci_disable_msi(adapter->pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
-static int atl1_resume(struct pci_dev *pdev)
+static int atl1_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1_adapter *adapter = netdev_priv(netdev);
- u32 err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
-
- err = pci_enable_device(pdev);
- if (err) {
- if (netif_msg_ifup(adapter))
- dev_printk(KERN_DEBUG, &pdev->dev,
- "error enabling pci device\n");
- return err;
- }
- pci_set_master(pdev);
iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
atl1_reset_hw(&adapter->hw);
- adapter->cmb.cmb->int_stats = 0;
- if (netif_running(netdev))
+ if (netif_running(netdev)) {
+ adapter->cmb.cmb->int_stats = 0;
atl1_up(adapter);
+ }
netif_device_attach(netdev);
return 0;
}
-#else
-#define atl1_suspend NULL
-#define atl1_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(atl1_pm_ops, atl1_suspend, atl1_resume);
+
static void atl1_shutdown(struct pci_dev *pdev)
{
-#ifdef CONFIG_PM
- atl1_suspend(pdev, PMSG_SUSPEND);
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+
+#ifdef CONFIG_PM_SLEEP
+ atl1_suspend(&pdev->dev);
#endif
+ pci_wake_from_d3(pdev, adapter->wol);
+ pci_set_power_state(pdev, PCI_D3hot);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2909,7 +2907,24 @@ static void atl1_poll_controller(struct net_device *netdev)
}
#endif
-/*
+static const struct net_device_ops atl1_netdev_ops = {
+ .ndo_open = atl1_open,
+ .ndo_stop = atl1_close,
+ .ndo_start_xmit = atl1_xmit_frame,
+ .ndo_set_rx_mode = atlx_set_multi,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = atl1_set_mac,
+ .ndo_change_mtu = atl1_change_mtu,
+ .ndo_fix_features = atlx_fix_features,
+ .ndo_set_features = atlx_set_features,
+ .ndo_do_ioctl = atlx_ioctl,
+ .ndo_tx_timeout = atlx_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl1_poll_controller,
+#endif
+};
+
+/**
* atl1_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in atl1_pci_tbl
@@ -2920,8 +2935,7 @@ static void atl1_poll_controller(struct net_device *netdev)
* The OS initialization, configuring of the adapter private structure,
* and a hardware reset occur.
*/
-static int __devinit atl1_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int atl1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *netdev;
struct atl1_adapter *adapter;
@@ -2942,7 +2956,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
* various kernel subsystems to support the mechanics required by a
* fixed-high-32-bit system.
*/
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev, "no usable DMA configuration\n");
goto err_dma;
@@ -2996,20 +3010,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
adapter->mii.phy_id_mask = 0x1f;
adapter->mii.reg_num_mask = 0x1f;
- netdev->open = &atl1_open;
- netdev->stop = &atl1_close;
- netdev->hard_start_xmit = &atl1_xmit_frame;
- netdev->get_stats = &atlx_get_stats;
- netdev->set_multicast_list = &atlx_set_multi;
- netdev->set_mac_address = &atl1_set_mac;
- netdev->change_mtu = &atl1_change_mtu;
- netdev->do_ioctl = &atlx_ioctl;
- netdev->tx_timeout = &atlx_tx_timeout;
+ netdev->netdev_ops = &atl1_netdev_ops;
netdev->watchdog_timeo = 5 * HZ;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = atl1_poll_controller;
-#endif
- netdev->vlan_rx_register = atlx_vlan_rx_register;
+ netif_napi_add(netdev, &adapter->napi, atl1_rings_clean, 64);
netdev->ethtool_ops = &atl1_ethtool_ops;
adapter->bd_number = cards_found;
@@ -3021,8 +3024,13 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netdev->features = NETIF_F_HW_CSUM;
netdev->features |= NETIF_F_SG;
- netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
- netdev->features |= NETIF_F_LLTX;
+ netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
+
+ netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO |
+ NETIF_F_HW_VLAN_CTAG_RX;
+
+ /* is this valid? see atl1_setup_mac_ctrl() */
+ netdev->features |= NETIF_F_RXCSUM;
/*
* patch for some L1 of old version,
@@ -3044,7 +3052,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
}
/* copy the MAC address out of the EEPROM */
- atl1_read_mac_addr(&adapter->hw);
+ if (atl1_read_mac_addr(&adapter->hw)) {
+ /* mark random mac */
+ netdev->addr_assign_type = NET_ADDR_RANDOM;
+ }
memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
if (!is_valid_ether_addr(netdev->dev_addr)) {
@@ -3064,23 +3075,15 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
atl1_pcie_patch(adapter);
/* assume we have no link for now */
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &atl1_watchdog;
- adapter->watchdog_timer.data = (unsigned long)adapter;
-
- init_timer(&adapter->phy_config_timer);
- adapter->phy_config_timer.function = &atl1_phy_config;
- adapter->phy_config_timer.data = (unsigned long)adapter;
+ setup_timer(&adapter->phy_config_timer, atl1_phy_config,
+ (unsigned long)adapter);
adapter->phy_timer_pending = false;
- INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
+ INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);
INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
- INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
-
err = register_netdev(netdev);
if (err)
goto err_common;
@@ -3101,7 +3104,7 @@ err_request_regions:
return err;
}
-/*
+/**
* atl1_remove - Device Removal Routine
* @pdev: PCI device information struct
*
@@ -3110,7 +3113,7 @@ err_request_regions:
* Hot-Plug event, or because the driver is going to be removed from
* memory.
*/
-static void __devexit atl1_remove(struct pci_dev *pdev)
+static void atl1_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1_adapter *adapter;
@@ -3125,7 +3128,8 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
* from the BIOS during POST. If we've been messing with the MAC
* address, we need to save the permanent one.
*/
- if (memcmp(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN)) {
+ if (!ether_addr_equal_unaligned(adapter->hw.mac_addr,
+ adapter->hw.perm_mac_addr)) {
memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr,
ETH_ALEN);
atl1_set_mac_addr(&adapter->hw);
@@ -3143,37 +3147,11 @@ static struct pci_driver atl1_driver = {
.name = ATLX_DRIVER_NAME,
.id_table = atl1_pci_tbl,
.probe = atl1_probe,
- .remove = __devexit_p(atl1_remove),
- .suspend = atl1_suspend,
- .resume = atl1_resume,
- .shutdown = atl1_shutdown
+ .remove = atl1_remove,
+ .shutdown = atl1_shutdown,
+ .driver.pm = &atl1_pm_ops,
};
-/*
- * atl1_exit_module - Driver Exit Cleanup Routine
- *
- * atl1_exit_module is called just before the driver is removed
- * from memory.
- */
-static void __exit atl1_exit_module(void)
-{
- pci_unregister_driver(&atl1_driver);
-}
-
-/*
- * atl1_init_module - Driver Registration Routine
- *
- * atl1_init_module is the first routine called when the driver is
- * loaded. All it does is register with the PCI subsystem.
- */
-static int __init atl1_init_module(void)
-{
- return pci_register_driver(&atl1_driver);
-}
-
-module_init(atl1_init_module);
-module_exit(atl1_exit_module);
-
struct atl1_stats {
char stat_string[ETH_GSTRING_LEN];
int sizeof_stat;
@@ -3190,8 +3168,6 @@ static struct atl1_stats atl1_gstrings_stats[] = {
{"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)},
{"rx_errors", ATL1_STAT(soft_stats.rx_errors)},
{"tx_errors", ATL1_STAT(soft_stats.tx_errors)},
- {"rx_dropped", ATL1_STAT(net_stats.rx_dropped)},
- {"tx_dropped", ATL1_STAT(net_stats.tx_dropped)},
{"multicast", ATL1_STAT(soft_stats.multicast)},
{"collisions", ATL1_STAT(soft_stats.collisions)},
{"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)},
@@ -3276,14 +3252,14 @@ static int atl1_get_settings(struct net_device *netdev,
if (netif_carrier_ok(adapter->netdev)) {
u16 link_speed, link_duplex;
atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
- ecmd->speed = link_speed;
+ ethtool_cmd_speed_set(ecmd, link_speed);
if (link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
- ecmd->speed = -1;
- ecmd->duplex = -1;
+ ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+ ecmd->duplex = DUPLEX_UNKNOWN;
}
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
hw->media_type == MEDIA_TYPE_1000M_FULL)
@@ -3313,7 +3289,8 @@ static int atl1_set_settings(struct net_device *netdev,
if (ecmd->autoneg == AUTONEG_ENABLE)
hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
else {
- if (ecmd->speed == SPEED_1000) {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
@@ -3322,7 +3299,7 @@ static int atl1_set_settings(struct net_device *netdev,
goto exit_sset;
}
hw->media_type = MEDIA_TYPE_1000M_FULL;
- } else if (ecmd->speed == SPEED_100) {
+ } else if (speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL)
hw->media_type = MEDIA_TYPE_100M_FULL;
else
@@ -3407,11 +3384,10 @@ static void atl1_get_drvinfo(struct net_device *netdev,
{
struct atl1_adapter *adapter = netdev_priv(netdev);
- strncpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
- strncpy(drvinfo->version, ATLX_DRIVER_VERSION,
+ strlcpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, ATLX_DRIVER_VERSION,
sizeof(drvinfo->version));
- strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
- strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->eedump_len = ATL1_EEDUMP_LEN;
}
@@ -3421,17 +3397,10 @@ static void atl1_get_wol(struct net_device *netdev,
{
struct atl1_adapter *adapter = netdev_priv(netdev);
- wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+ wol->supported = WAKE_MAGIC;
wol->wolopts = 0;
- if (adapter->wol & ATLX_WUFC_EX)
- wol->wolopts |= WAKE_UCAST;
- if (adapter->wol & ATLX_WUFC_MC)
- wol->wolopts |= WAKE_MCAST;
- if (adapter->wol & ATLX_WUFC_BC)
- wol->wolopts |= WAKE_BCAST;
if (adapter->wol & ATLX_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
- return;
}
static int atl1_set_wol(struct net_device *netdev,
@@ -3439,17 +3408,15 @@ static int atl1_set_wol(struct net_device *netdev,
{
struct atl1_adapter *adapter = netdev_priv(netdev);
- if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+ if (wol->wolopts & (WAKE_PHY | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
+ WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP;
adapter->wol = 0;
- if (wol->wolopts & WAKE_UCAST)
- adapter->wol |= ATLX_WUFC_EX;
- if (wol->wolopts & WAKE_MCAST)
- adapter->wol |= ATLX_WUFC_MC;
- if (wol->wolopts & WAKE_BCAST)
- adapter->wol |= ATLX_WUFC_BC;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= ATLX_WUFC_MAG;
+
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
return 0;
}
@@ -3525,12 +3492,8 @@ static void atl1_get_ringparam(struct net_device *netdev,
ring->rx_max_pending = ATL1_MAX_RFD;
ring->tx_max_pending = ATL1_MAX_TPD;
- ring->rx_mini_max_pending = 0;
- ring->rx_jumbo_max_pending = 0;
ring->rx_pending = rxdr->count;
ring->tx_pending = txdr->count;
- ring->rx_mini_pending = 0;
- ring->rx_jumbo_pending = 0;
}
static int atl1_set_ringparam(struct net_device *netdev,
@@ -3545,6 +3508,8 @@ static int atl1_set_ringparam(struct net_device *netdev,
struct atl1_rfd_ring rfd_old, rfd_new;
struct atl1_rrd_ring rrd_old, rrd_new;
struct atl1_ring_header rhdr_old, rhdr_new;
+ struct atl1_smb smb;
+ struct atl1_cmb cmb;
int err;
tpd_old = adapter->tpd_ring;
@@ -3585,11 +3550,19 @@ static int atl1_set_ringparam(struct net_device *netdev,
adapter->rrd_ring = rrd_old;
adapter->tpd_ring = tpd_old;
adapter->ring_header = rhdr_old;
+ /*
+ * Save SMB and CMB, since atl1_free_ring_resources
+ * will clear them.
+ */
+ smb = adapter->smb;
+ cmb = adapter->cmb;
atl1_free_ring_resources(adapter);
adapter->rfd_ring = rfd_new;
adapter->rrd_ring = rrd_new;
adapter->tpd_ring = tpd_new;
adapter->ring_header = rhdr_new;
+ adapter->smb = smb;
+ adapter->cmb = cmb;
err = atl1_up(adapter);
if (err)
@@ -3641,12 +3614,6 @@ static int atl1_set_pauseparam(struct net_device *netdev,
return 0;
}
-/* FIXME: is this right? -- CHS */
-static u32 atl1_get_rx_csum(struct net_device *netdev)
-{
- return 1;
-}
-
static void atl1_get_strings(struct net_device *netdev, u32 stringset,
u8 *data)
{
@@ -3700,7 +3667,7 @@ static int atl1_nway_reset(struct net_device *netdev)
return 0;
}
-const struct ethtool_ops atl1_ethtool_ops = {
+static const struct ethtool_ops atl1_ethtool_ops = {
.get_settings = atl1_get_settings,
.set_settings = atl1_set_settings,
.get_drvinfo = atl1_get_drvinfo,
@@ -3714,13 +3681,11 @@ const struct ethtool_ops atl1_ethtool_ops = {
.set_ringparam = atl1_set_ringparam,
.get_pauseparam = atl1_get_pauseparam,
.set_pauseparam = atl1_set_pauseparam,
- .get_rx_csum = atl1_get_rx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
.get_link = ethtool_op_get_link,
- .set_sg = ethtool_op_set_sg,
.get_strings = atl1_get_strings,
.nway_reset = atl1_nway_reset,
.get_ethtool_stats = atl1_get_ethtool_stats,
.get_sset_count = atl1_get_sset_count,
- .set_tso = ethtool_op_set_tso,
};
+
+module_pci_driver(atl1_driver);
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/ethernet/atheros/atlx/atl1.h
index a5015b14a42..34a58cd846a 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/ethernet/atheros/atlx/atl1.h
@@ -56,16 +56,13 @@ struct atl1_adapter;
struct atl1_hw;
/* function prototypes needed by multiple files */
-u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
-void atl1_hash_set(struct atl1_hw *hw, u32 hash_value);
-s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data);
-void atl1_set_mac_addr(struct atl1_hw *hw);
+static u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
+static void atl1_hash_set(struct atl1_hw *hw, u32 hash_value);
+static void atl1_set_mac_addr(struct atl1_hw *hw);
static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
int cmd);
static u32 atl1_check_link(struct atl1_adapter *adapter);
-extern const struct ethtool_ops atl1_ethtool_ops;
-
/* hardware definitions specific to L1 */
/* Block IDLE Status Register */
@@ -278,13 +275,17 @@ extern const struct ethtool_ops atl1_ethtool_ops;
#define ISR_DIS_SMB 0x20000000
#define ISR_DIS_DMA 0x40000000
-/* Normal Interrupt mask */
-#define IMR_NORMAL_MASK (\
+/* Normal Interrupt mask without RX/TX enabled */
+#define IMR_NORXTX_MASK (\
ISR_SMB |\
ISR_GPHY |\
ISR_PHY_LINKDOWN|\
ISR_DMAR_TO_RST |\
- ISR_DMAW_TO_RST |\
+ ISR_DMAW_TO_RST)
+
+/* Normal Interrupt mask */
+#define IMR_NORMAL_MASK (\
+ IMR_NORXTX_MASK |\
ISR_CMB_TX |\
ISR_CMB_RX)
@@ -436,8 +437,8 @@ struct rx_free_desc {
__le16 buf_len; /* Size of the receive buffer in host memory */
u16 coalese; /* Update consumer index to host after the
* reception of this frame */
- /* __attribute__ ((packed)) is required */
-} __attribute__ ((packed));
+ /* __packed is required */
+} __packed;
/*
* The L1 transmit packet descriptor is comprised of four 32-bit words.
@@ -504,7 +505,7 @@ struct rx_free_desc {
#define TPD_PKTNT_MASK 0x0001
#define TPD_PKTINT_SHIFT 15
#define TPD_VLANTAG_MASK 0xFFFF
-#define TPD_VLAN_SHIFT 16
+#define TPD_VLANTAG_SHIFT 16
/* tpd word 3 bits 0:13 */
#define TPD_EOP_MASK 0x0001
@@ -665,6 +666,7 @@ struct atl1_sft_stats {
u64 rx_errors;
u64 rx_length_errors;
u64 rx_crc_errors;
+ u64 rx_dropped;
u64 rx_frame_errors;
u64 rx_fifo_errors;
u64 rx_missed_errors;
@@ -754,18 +756,17 @@ struct atl1_hw {
struct atl1_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
- struct net_device_stats net_stats;
+
struct atl1_sft_stats soft_stats;
- struct vlan_group *vlgrp;
u32 rx_buffer_len;
u32 wol;
u16 link_speed;
u16 link_duplex;
spinlock_t lock;
- struct work_struct tx_timeout_task;
+ struct napi_struct napi;
+ struct work_struct reset_dev_task;
struct work_struct link_chg_task;
- struct work_struct pcie_dma_to_rst_task;
- struct timer_list watchdog_timer;
+
struct timer_list phy_config_timer;
bool phy_timer_pending;
@@ -786,6 +787,12 @@ struct atl1_adapter {
u16 ict; /* interrupt clear timer (2us resolution */
struct mii_if_info mii; /* MII interface info */
+ /*
+ * Use this value to check is napi handler allowed to
+ * enable ints or not
+ */
+ bool int_enabled;
+
u32 bd_number; /* board number */
bool pci_using_64;
struct atl1_hw hw;
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
new file mode 100644
index 00000000000..6746bd71714
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -0,0 +1,3090 @@
+/*
+ * Copyright(c) 2006 - 2007 Atheros Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2008 Chris Snook <csnook@redhat.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/atomic.h>
+#include <linux/crc32.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/hardirq.h>
+#include <linux/if_vlan.h>
+#include <linux/in.h>
+#include <linux/interrupt.h>
+#include <linux/ip.h>
+#include <linux/irqflags.h>
+#include <linux/irqreturn.h>
+#include <linux/mii.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/pm.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/tcp.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+#include "atl2.h"
+
+#define ATL2_DRV_VERSION "2.2.3"
+
+static const char atl2_driver_name[] = "atl2";
+static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver";
+static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation.";
+static const char atl2_driver_version[] = ATL2_DRV_VERSION;
+static const struct ethtool_ops atl2_ethtool_ops;
+
+MODULE_AUTHOR("Atheros Corporation <xiong.huang@atheros.com>, Chris Snook <csnook@redhat.com>");
+MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATL2_DRV_VERSION);
+
+/*
+ * atl2_pci_tbl - PCI Device ID Table
+ */
+static DEFINE_PCI_DEVICE_TABLE(atl2_pci_tbl) = {
+ {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2)},
+ /* required last entry */
+ {0,}
+};
+MODULE_DEVICE_TABLE(pci, atl2_pci_tbl);
+
+static void atl2_check_options(struct atl2_adapter *adapter);
+
+/**
+ * atl2_sw_init - Initialize general software structures (struct atl2_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * atl2_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ */
+static int atl2_sw_init(struct atl2_adapter *adapter)
+{
+ struct atl2_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+
+ /* PCI config space info */
+ hw->vendor_id = pdev->vendor;
+ hw->device_id = pdev->device;
+ hw->subsystem_vendor_id = pdev->subsystem_vendor;
+ hw->subsystem_id = pdev->subsystem_device;
+ hw->revision_id = pdev->revision;
+
+ pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+ adapter->wol = 0;
+ adapter->ict = 50000; /* ~100ms */
+ adapter->link_speed = SPEED_0; /* hardware init */
+ adapter->link_duplex = FULL_DUPLEX;
+
+ hw->phy_configured = false;
+ hw->preamble_len = 7;
+ hw->ipgt = 0x60;
+ hw->min_ifg = 0x50;
+ hw->ipgr1 = 0x40;
+ hw->ipgr2 = 0x60;
+ hw->retry_buf = 2;
+ hw->max_retry = 0xf;
+ hw->lcol = 0x37;
+ hw->jam_ipg = 7;
+ hw->fc_rxd_hi = 0;
+ hw->fc_rxd_lo = 0;
+ hw->max_frame_size = adapter->netdev->mtu;
+
+ spin_lock_init(&adapter->stats_lock);
+
+ set_bit(__ATL2_DOWN, &adapter->flags);
+
+ return 0;
+}
+
+/**
+ * atl2_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ */
+static void atl2_set_multi(struct net_device *netdev)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+ struct netdev_hw_addr *ha;
+ u32 rctl;
+ u32 hash_value;
+
+ /* Check for Promiscuous and All Multicast modes */
+ rctl = ATL2_READ_REG(hw, REG_MAC_CTRL);
+
+ if (netdev->flags & IFF_PROMISC) {
+ rctl |= MAC_CTRL_PROMIS_EN;
+ } else if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= MAC_CTRL_MC_ALL_EN;
+ rctl &= ~MAC_CTRL_PROMIS_EN;
+ } else
+ rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+
+ ATL2_WRITE_REG(hw, REG_MAC_CTRL, rctl);
+
+ /* clear the old settings from the multicast hash table */
+ ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+ ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+ /* comoute mc addresses' hash value ,and put it into hash table */
+ netdev_for_each_mc_addr(ha, netdev) {
+ hash_value = atl2_hash_mc_addr(hw, ha->addr);
+ atl2_hash_set(hw, hash_value);
+ }
+}
+
+static void init_ring_ptrs(struct atl2_adapter *adapter)
+{
+ /* Read / Write Ptr Initialize: */
+ adapter->txd_write_ptr = 0;
+ atomic_set(&adapter->txd_read_ptr, 0);
+
+ adapter->rxd_read_ptr = 0;
+ adapter->rxd_write_ptr = 0;
+
+ atomic_set(&adapter->txs_write_ptr, 0);
+ adapter->txs_next_clear = 0;
+}
+
+/**
+ * atl2_configure - Configure Transmit&Receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx /Rx unit of the MAC after a reset.
+ */
+static int atl2_configure(struct atl2_adapter *adapter)
+{
+ struct atl2_hw *hw = &adapter->hw;
+ u32 value;
+
+ /* clear interrupt status */
+ ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0xffffffff);
+
+ /* set MAC Address */
+ value = (((u32)hw->mac_addr[2]) << 24) |
+ (((u32)hw->mac_addr[3]) << 16) |
+ (((u32)hw->mac_addr[4]) << 8) |
+ (((u32)hw->mac_addr[5]));
+ ATL2_WRITE_REG(hw, REG_MAC_STA_ADDR, value);
+ value = (((u32)hw->mac_addr[0]) << 8) |
+ (((u32)hw->mac_addr[1]));
+ ATL2_WRITE_REG(hw, (REG_MAC_STA_ADDR+4), value);
+
+ /* HI base address */
+ ATL2_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI,
+ (u32)((adapter->ring_dma & 0xffffffff00000000ULL) >> 32));
+
+ /* LO base address */
+ ATL2_WRITE_REG(hw, REG_TXD_BASE_ADDR_LO,
+ (u32)(adapter->txd_dma & 0x00000000ffffffffULL));
+ ATL2_WRITE_REG(hw, REG_TXS_BASE_ADDR_LO,
+ (u32)(adapter->txs_dma & 0x00000000ffffffffULL));
+ ATL2_WRITE_REG(hw, REG_RXD_BASE_ADDR_LO,
+ (u32)(adapter->rxd_dma & 0x00000000ffffffffULL));
+
+ /* element count */
+ ATL2_WRITE_REGW(hw, REG_TXD_MEM_SIZE, (u16)(adapter->txd_ring_size/4));
+ ATL2_WRITE_REGW(hw, REG_TXS_MEM_SIZE, (u16)adapter->txs_ring_size);
+ ATL2_WRITE_REGW(hw, REG_RXD_BUF_NUM, (u16)adapter->rxd_ring_size);
+
+ /* config Internal SRAM */
+/*
+ ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_tx_end);
+ ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_rx_end);
+*/
+
+ /* config IPG/IFG */
+ value = (((u32)hw->ipgt & MAC_IPG_IFG_IPGT_MASK) <<
+ MAC_IPG_IFG_IPGT_SHIFT) |
+ (((u32)hw->min_ifg & MAC_IPG_IFG_MIFG_MASK) <<
+ MAC_IPG_IFG_MIFG_SHIFT) |
+ (((u32)hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK) <<
+ MAC_IPG_IFG_IPGR1_SHIFT)|
+ (((u32)hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK) <<
+ MAC_IPG_IFG_IPGR2_SHIFT);
+ ATL2_WRITE_REG(hw, REG_MAC_IPG_IFG, value);
+
+ /* config Half-Duplex Control */
+ value = ((u32)hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) |
+ (((u32)hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK) <<
+ MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) |
+ MAC_HALF_DUPLX_CTRL_EXC_DEF_EN |
+ (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) |
+ (((u32)hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) <<
+ MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT);
+ ATL2_WRITE_REG(hw, REG_MAC_HALF_DUPLX_CTRL, value);
+
+ /* set Interrupt Moderator Timer */
+ ATL2_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, adapter->imt);
+ ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_ITIMER_EN);
+
+ /* set Interrupt Clear Timer */
+ ATL2_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, adapter->ict);
+
+ /* set MTU */
+ ATL2_WRITE_REG(hw, REG_MTU, adapter->netdev->mtu +
+ ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE);
+
+ /* 1590 */
+ ATL2_WRITE_REG(hw, REG_TX_CUT_THRESH, 0x177);
+
+ /* flow control */
+ ATL2_WRITE_REGW(hw, REG_PAUSE_ON_TH, hw->fc_rxd_hi);
+ ATL2_WRITE_REGW(hw, REG_PAUSE_OFF_TH, hw->fc_rxd_lo);
+
+ /* Init mailbox */
+ ATL2_WRITE_REGW(hw, REG_MB_TXD_WR_IDX, (u16)adapter->txd_write_ptr);
+ ATL2_WRITE_REGW(hw, REG_MB_RXD_RD_IDX, (u16)adapter->rxd_read_ptr);
+
+ /* enable DMA read/write */
+ ATL2_WRITE_REGB(hw, REG_DMAR, DMAR_EN);
+ ATL2_WRITE_REGB(hw, REG_DMAW, DMAW_EN);
+
+ value = ATL2_READ_REG(&adapter->hw, REG_ISR);
+ if ((value & ISR_PHY_LINKDOWN) != 0)
+ value = 1; /* config failed */
+ else
+ value = 0;
+
+ /* clear all interrupt status */
+ ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0x3fffffff);
+ ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0);
+ return value;
+}
+
+/**
+ * atl2_setup_ring_resources - allocate Tx / RX descriptor resources
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ */
+static s32 atl2_setup_ring_resources(struct atl2_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ int size;
+ u8 offset = 0;
+
+ /* real ring DMA buffer */
+ adapter->ring_size = size =
+ adapter->txd_ring_size * 1 + 7 + /* dword align */
+ adapter->txs_ring_size * 4 + 7 + /* dword align */
+ adapter->rxd_ring_size * 1536 + 127; /* 128bytes align */
+
+ adapter->ring_vir_addr = pci_alloc_consistent(pdev, size,
+ &adapter->ring_dma);
+ if (!adapter->ring_vir_addr)
+ return -ENOMEM;
+ memset(adapter->ring_vir_addr, 0, adapter->ring_size);
+
+ /* Init TXD Ring */
+ adapter->txd_dma = adapter->ring_dma ;
+ offset = (adapter->txd_dma & 0x7) ? (8 - (adapter->txd_dma & 0x7)) : 0;
+ adapter->txd_dma += offset;
+ adapter->txd_ring = adapter->ring_vir_addr + offset;
+
+ /* Init TXS Ring */
+ adapter->txs_dma = adapter->txd_dma + adapter->txd_ring_size;
+ offset = (adapter->txs_dma & 0x7) ? (8 - (adapter->txs_dma & 0x7)) : 0;
+ adapter->txs_dma += offset;
+ adapter->txs_ring = (struct tx_pkt_status *)
+ (((u8 *)adapter->txd_ring) + (adapter->txd_ring_size + offset));
+
+ /* Init RXD Ring */
+ adapter->rxd_dma = adapter->txs_dma + adapter->txs_ring_size * 4;
+ offset = (adapter->rxd_dma & 127) ?
+ (128 - (adapter->rxd_dma & 127)) : 0;
+ if (offset > 7)
+ offset -= 8;
+ else
+ offset += (128 - 8);
+
+ adapter->rxd_dma += offset;
+ adapter->rxd_ring = (struct rx_desc *) (((u8 *)adapter->txs_ring) +
+ (adapter->txs_ring_size * 4 + offset));
+
+/*
+ * Read / Write Ptr Initialize:
+ * init_ring_ptrs(adapter);
+ */
+ return 0;
+}
+
+/**
+ * atl2_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static inline void atl2_irq_enable(struct atl2_adapter *adapter)
+{
+ ATL2_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK);
+ ATL2_WRITE_FLUSH(&adapter->hw);
+}
+
+/**
+ * atl2_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ */
+static inline void atl2_irq_disable(struct atl2_adapter *adapter)
+{
+ ATL2_WRITE_REG(&adapter->hw, REG_IMR, 0);
+ ATL2_WRITE_FLUSH(&adapter->hw);
+ synchronize_irq(adapter->pdev->irq);
+}
+
+static void __atl2_vlan_mode(netdev_features_t features, u32 *ctrl)
+{
+ if (features & NETIF_F_HW_VLAN_CTAG_RX) {
+ /* enable VLAN tag insert/strip */
+ *ctrl |= MAC_CTRL_RMV_VLAN;
+ } else {
+ /* disable VLAN tag insert/strip */
+ *ctrl &= ~MAC_CTRL_RMV_VLAN;
+ }
+}
+
+static void atl2_vlan_mode(struct net_device *netdev,
+ netdev_features_t features)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ u32 ctrl;
+
+ atl2_irq_disable(adapter);
+
+ ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL);
+ __atl2_vlan_mode(features, &ctrl);
+ ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl);
+
+ atl2_irq_enable(adapter);
+}
+
+static void atl2_restore_vlan(struct atl2_adapter *adapter)
+{
+ atl2_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+static netdev_features_t atl2_fix_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ /*
+ * Since there is no support for separate rx/tx vlan accel
+ * enable/disable make sure tx flag is always in same state as rx.
+ */
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ features |= NETIF_F_HW_VLAN_CTAG_TX;
+ else
+ features &= ~NETIF_F_HW_VLAN_CTAG_TX;
+
+ return features;
+}
+
+static int atl2_set_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = netdev->features ^ features;
+
+ if (changed & NETIF_F_HW_VLAN_CTAG_RX)
+ atl2_vlan_mode(netdev, features);
+
+ return 0;
+}
+
+static void atl2_intr_rx(struct atl2_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct rx_desc *rxd;
+ struct sk_buff *skb;
+
+ do {
+ rxd = adapter->rxd_ring+adapter->rxd_write_ptr;
+ if (!rxd->status.update)
+ break; /* end of tx */
+
+ /* clear this flag at once */
+ rxd->status.update = 0;
+
+ if (rxd->status.ok && rxd->status.pkt_size >= 60) {
+ int rx_size = (int)(rxd->status.pkt_size - 4);
+ /* alloc new buffer */
+ skb = netdev_alloc_skb_ip_align(netdev, rx_size);
+ if (NULL == skb) {
+ /*
+ * Check that some rx space is free. If not,
+ * free one and mark stats->rx_dropped++.
+ */
+ netdev->stats.rx_dropped++;
+ break;
+ }
+ memcpy(skb->data, rxd->packet, rx_size);
+ skb_put(skb, rx_size);
+ skb->protocol = eth_type_trans(skb, netdev);
+ if (rxd->status.vlan) {
+ u16 vlan_tag = (rxd->status.vtag>>4) |
+ ((rxd->status.vtag&7) << 13) |
+ ((rxd->status.vtag&8) << 9);
+
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
+ }
+ netif_rx(skb);
+ netdev->stats.rx_bytes += rx_size;
+ netdev->stats.rx_packets++;
+ } else {
+ netdev->stats.rx_errors++;
+
+ if (rxd->status.ok && rxd->status.pkt_size <= 60)
+ netdev->stats.rx_length_errors++;
+ if (rxd->status.mcast)
+ netdev->stats.multicast++;
+ if (rxd->status.crc)
+ netdev->stats.rx_crc_errors++;
+ if (rxd->status.align)
+ netdev->stats.rx_frame_errors++;
+ }
+
+ /* advance write ptr */
+ if (++adapter->rxd_write_ptr == adapter->rxd_ring_size)
+ adapter->rxd_write_ptr = 0;
+ } while (1);
+
+ /* update mailbox? */
+ adapter->rxd_read_ptr = adapter->rxd_write_ptr;
+ ATL2_WRITE_REGW(&adapter->hw, REG_MB_RXD_RD_IDX, adapter->rxd_read_ptr);
+}
+
+static void atl2_intr_tx(struct atl2_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ u32 txd_read_ptr;
+ u32 txs_write_ptr;
+ struct tx_pkt_status *txs;
+ struct tx_pkt_header *txph;
+ int free_hole = 0;
+
+ do {
+ txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr);
+ txs = adapter->txs_ring + txs_write_ptr;
+ if (!txs->update)
+ break; /* tx stop here */
+
+ free_hole = 1;
+ txs->update = 0;
+
+ if (++txs_write_ptr == adapter->txs_ring_size)
+ txs_write_ptr = 0;
+ atomic_set(&adapter->txs_write_ptr, (int)txs_write_ptr);
+
+ txd_read_ptr = (u32) atomic_read(&adapter->txd_read_ptr);
+ txph = (struct tx_pkt_header *)
+ (((u8 *)adapter->txd_ring) + txd_read_ptr);
+
+ if (txph->pkt_size != txs->pkt_size) {
+ struct tx_pkt_status *old_txs = txs;
+ printk(KERN_WARNING
+ "%s: txs packet size not consistent with txd"
+ " txd_:0x%08x, txs_:0x%08x!\n",
+ adapter->netdev->name,
+ *(u32 *)txph, *(u32 *)txs);
+ printk(KERN_WARNING
+ "txd read ptr: 0x%x\n",
+ txd_read_ptr);
+ txs = adapter->txs_ring + txs_write_ptr;
+ printk(KERN_WARNING
+ "txs-behind:0x%08x\n",
+ *(u32 *)txs);
+ if (txs_write_ptr < 2) {
+ txs = adapter->txs_ring +
+ (adapter->txs_ring_size +
+ txs_write_ptr - 2);
+ } else {
+ txs = adapter->txs_ring + (txs_write_ptr - 2);
+ }
+ printk(KERN_WARNING
+ "txs-before:0x%08x\n",
+ *(u32 *)txs);
+ txs = old_txs;
+ }
+
+ /* 4for TPH */
+ txd_read_ptr += (((u32)(txph->pkt_size) + 7) & ~3);
+ if (txd_read_ptr >= adapter->txd_ring_size)
+ txd_read_ptr -= adapter->txd_ring_size;
+
+ atomic_set(&adapter->txd_read_ptr, (int)txd_read_ptr);
+
+ /* tx statistics: */
+ if (txs->ok) {
+ netdev->stats.tx_bytes += txs->pkt_size;
+ netdev->stats.tx_packets++;
+ }
+ else
+ netdev->stats.tx_errors++;
+
+ if (txs->defer)
+ netdev->stats.collisions++;
+ if (txs->abort_col)
+ netdev->stats.tx_aborted_errors++;
+ if (txs->late_col)
+ netdev->stats.tx_window_errors++;
+ if (txs->underun)
+ netdev->stats.tx_fifo_errors++;
+ } while (1);
+
+ if (free_hole) {
+ if (netif_queue_stopped(adapter->netdev) &&
+ netif_carrier_ok(adapter->netdev))
+ netif_wake_queue(adapter->netdev);
+ }
+}
+
+static void atl2_check_for_link(struct atl2_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ u16 phy_data = 0;
+
+ spin_lock(&adapter->stats_lock);
+ atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+ spin_unlock(&adapter->stats_lock);
+
+ /* notify upper layer link down ASAP */
+ if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */
+ if (netif_carrier_ok(netdev)) { /* old link state: Up */
+ printk(KERN_INFO "%s: %s NIC Link is Down\n",
+ atl2_driver_name, netdev->name);
+ adapter->link_speed = SPEED_0;
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
+ }
+ schedule_work(&adapter->link_chg_task);
+}
+
+static inline void atl2_clear_phy_int(struct atl2_adapter *adapter)
+{
+ u16 phy_data;
+ spin_lock(&adapter->stats_lock);
+ atl2_read_phy_reg(&adapter->hw, 19, &phy_data);
+ spin_unlock(&adapter->stats_lock);
+}
+
+/**
+ * atl2_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ */
+static irqreturn_t atl2_intr(int irq, void *data)
+{
+ struct atl2_adapter *adapter = netdev_priv(data);
+ struct atl2_hw *hw = &adapter->hw;
+ u32 status;
+
+ status = ATL2_READ_REG(hw, REG_ISR);
+ if (0 == status)
+ return IRQ_NONE;
+
+ /* link event */
+ if (status & ISR_PHY)
+ atl2_clear_phy_int(adapter);
+
+ /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
+ ATL2_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
+
+ /* check if PCIE PHY Link down */
+ if (status & ISR_PHY_LINKDOWN) {
+ if (netif_running(adapter->netdev)) { /* reset MAC */
+ ATL2_WRITE_REG(hw, REG_ISR, 0);
+ ATL2_WRITE_REG(hw, REG_IMR, 0);
+ ATL2_WRITE_FLUSH(hw);
+ schedule_work(&adapter->reset_task);
+ return IRQ_HANDLED;
+ }
+ }
+
+ /* check if DMA read/write error? */
+ if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+ ATL2_WRITE_REG(hw, REG_ISR, 0);
+ ATL2_WRITE_REG(hw, REG_IMR, 0);
+ ATL2_WRITE_FLUSH(hw);
+ schedule_work(&adapter->reset_task);
+ return IRQ_HANDLED;
+ }
+
+ /* link event */
+ if (status & (ISR_PHY | ISR_MANUAL)) {
+ adapter->netdev->stats.tx_carrier_errors++;
+ atl2_check_for_link(adapter);
+ }
+
+ /* transmit event */
+ if (status & ISR_TX_EVENT)
+ atl2_intr_tx(adapter);
+
+ /* rx exception */
+ if (status & ISR_RX_EVENT)
+ atl2_intr_rx(adapter);
+
+ /* re-enable Interrupt */
+ ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0);
+ return IRQ_HANDLED;
+}
+
+static int atl2_request_irq(struct atl2_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int flags, err = 0;
+
+ flags = IRQF_SHARED;
+ adapter->have_msi = true;
+ err = pci_enable_msi(adapter->pdev);
+ if (err)
+ adapter->have_msi = false;
+
+ if (adapter->have_msi)
+ flags &= ~IRQF_SHARED;
+
+ return request_irq(adapter->pdev->irq, atl2_intr, flags, netdev->name,
+ netdev);
+}
+
+/**
+ * atl2_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ */
+static void atl2_free_ring_resources(struct atl2_adapter *adapter)
+{
+ struct pci_dev *pdev = adapter->pdev;
+ pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr,
+ adapter->ring_dma);
+}
+
+/**
+ * atl2_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP). At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ */
+static int atl2_open(struct net_device *netdev)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ int err;
+ u32 val;
+
+ /* disallow open during test */
+ if (test_bit(__ATL2_TESTING, &adapter->flags))
+ return -EBUSY;
+
+ /* allocate transmit descriptors */
+ err = atl2_setup_ring_resources(adapter);
+ if (err)
+ return err;
+
+ err = atl2_init_hw(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ goto err_init_hw;
+ }
+
+ /* hardware has been reset, we need to reload some things */
+ atl2_set_multi(netdev);
+ init_ring_ptrs(adapter);
+
+ atl2_restore_vlan(adapter);
+
+ if (atl2_configure(adapter)) {
+ err = -EIO;
+ goto err_config;
+ }
+
+ err = atl2_request_irq(adapter);
+ if (err)
+ goto err_req_irq;
+
+ clear_bit(__ATL2_DOWN, &adapter->flags);
+
+ mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 4*HZ));
+
+ val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL);
+ ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
+ val | MASTER_CTRL_MANUAL_INT);
+
+ atl2_irq_enable(adapter);
+
+ return 0;
+
+err_init_hw:
+err_req_irq:
+err_config:
+ atl2_free_ring_resources(adapter);
+ atl2_reset_hw(&adapter->hw);
+
+ return err;
+}
+
+static void atl2_down(struct atl2_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ /* signal that we're down so the interrupt handler does not
+ * reschedule our watchdog timer */
+ set_bit(__ATL2_DOWN, &adapter->flags);
+
+ netif_tx_disable(netdev);
+
+ /* reset MAC to disable all RX/TX */
+ atl2_reset_hw(&adapter->hw);
+ msleep(1);
+
+ atl2_irq_disable(adapter);
+
+ del_timer_sync(&adapter->watchdog_timer);
+ del_timer_sync(&adapter->phy_config_timer);
+ clear_bit(0, &adapter->cfg_phy);
+
+ netif_carrier_off(netdev);
+ adapter->link_speed = SPEED_0;
+ adapter->link_duplex = -1;
+}
+
+static void atl2_free_irq(struct atl2_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ free_irq(adapter->pdev->irq, netdev);
+
+#ifdef CONFIG_PCI_MSI
+ if (adapter->have_msi)
+ pci_disable_msi(adapter->pdev);
+#endif
+}
+
+/**
+ * atl2_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS. The hardware is still under the drivers control, but
+ * needs to be disabled. A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ */
+static int atl2_close(struct net_device *netdev)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+
+ WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags));
+
+ atl2_down(adapter);
+ atl2_free_irq(adapter);
+ atl2_free_ring_resources(adapter);
+
+ return 0;
+}
+
+static inline int TxsFreeUnit(struct atl2_adapter *adapter)
+{
+ u32 txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr);
+
+ return (adapter->txs_next_clear >= txs_write_ptr) ?
+ (int) (adapter->txs_ring_size - adapter->txs_next_clear +
+ txs_write_ptr - 1) :
+ (int) (txs_write_ptr - adapter->txs_next_clear - 1);
+}
+
+static inline int TxdFreeBytes(struct atl2_adapter *adapter)
+{
+ u32 txd_read_ptr = (u32)atomic_read(&adapter->txd_read_ptr);
+
+ return (adapter->txd_write_ptr >= txd_read_ptr) ?
+ (int) (adapter->txd_ring_size - adapter->txd_write_ptr +
+ txd_read_ptr - 1) :
+ (int) (txd_read_ptr - adapter->txd_write_ptr - 1);
+}
+
+static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct tx_pkt_header *txph;
+ u32 offset, copy_len;
+ int txs_unused;
+ int txbuf_unused;
+
+ if (test_bit(__ATL2_DOWN, &adapter->flags)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (unlikely(skb->len <= 0)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ txs_unused = TxsFreeUnit(adapter);
+ txbuf_unused = TxdFreeBytes(adapter);
+
+ if (skb->len + sizeof(struct tx_pkt_header) + 4 > txbuf_unused ||
+ txs_unused < 1) {
+ /* not enough resources */
+ netif_stop_queue(netdev);
+ return NETDEV_TX_BUSY;
+ }
+
+ offset = adapter->txd_write_ptr;
+
+ txph = (struct tx_pkt_header *) (((u8 *)adapter->txd_ring) + offset);
+
+ *(u32 *)txph = 0;
+ txph->pkt_size = skb->len;
+
+ offset += 4;
+ if (offset >= adapter->txd_ring_size)
+ offset -= adapter->txd_ring_size;
+ copy_len = adapter->txd_ring_size - offset;
+ if (copy_len >= skb->len) {
+ memcpy(((u8 *)adapter->txd_ring) + offset, skb->data, skb->len);
+ offset += ((u32)(skb->len + 3) & ~3);
+ } else {
+ memcpy(((u8 *)adapter->txd_ring)+offset, skb->data, copy_len);
+ memcpy((u8 *)adapter->txd_ring, skb->data+copy_len,
+ skb->len-copy_len);
+ offset = ((u32)(skb->len-copy_len + 3) & ~3);
+ }
+#ifdef NETIF_F_HW_VLAN_CTAG_TX
+ if (vlan_tx_tag_present(skb)) {
+ u16 vlan_tag = vlan_tx_tag_get(skb);
+ vlan_tag = (vlan_tag << 4) |
+ (vlan_tag >> 13) |
+ ((vlan_tag >> 9) & 0x8);
+ txph->ins_vlan = 1;
+ txph->vlan = vlan_tag;
+ }
+#endif
+ if (offset >= adapter->txd_ring_size)
+ offset -= adapter->txd_ring_size;
+ adapter->txd_write_ptr = offset;
+
+ /* clear txs before send */
+ adapter->txs_ring[adapter->txs_next_clear].update = 0;
+ if (++adapter->txs_next_clear == adapter->txs_ring_size)
+ adapter->txs_next_clear = 0;
+
+ ATL2_WRITE_REGW(&adapter->hw, REG_MB_TXD_WR_IDX,
+ (adapter->txd_write_ptr >> 2));
+
+ mmiowb();
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+}
+
+/**
+ * atl2_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl2_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+
+ if ((new_mtu < 40) || (new_mtu > (ETH_DATA_LEN + VLAN_SIZE)))
+ return -EINVAL;
+
+ /* set MTU */
+ if (hw->max_frame_size != new_mtu) {
+ netdev->mtu = new_mtu;
+ ATL2_WRITE_REG(hw, REG_MTU, new_mtu + ENET_HEADER_SIZE +
+ VLAN_SIZE + ETHERNET_FCS_SIZE);
+ }
+
+ return 0;
+}
+
+/**
+ * atl2_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl2_set_mac(struct net_device *netdev, void *p)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (netif_running(netdev))
+ return -EBUSY;
+
+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+ memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+ atl2_set_mac_addr(&adapter->hw);
+
+ return 0;
+}
+
+static int atl2_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct mii_ioctl_data *data = if_mii(ifr);
+ unsigned long flags;
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ data->phy_id = 0;
+ break;
+ case SIOCGMIIREG:
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+ if (atl2_read_phy_reg(&adapter->hw,
+ data->reg_num & 0x1F, &data->val_out)) {
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ return -EIO;
+ }
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ break;
+ case SIOCSMIIREG:
+ if (data->reg_num & ~(0x1F))
+ return -EFAULT;
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+ if (atl2_write_phy_reg(&adapter->hw, data->reg_num,
+ data->val_in)) {
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ return -EIO;
+ }
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static int atl2_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ return atl2_mii_ioctl(netdev, ifr, cmd);
+#ifdef ETHTOOL_OPS_COMPAT
+ case SIOCETHTOOL:
+ return ethtool_ioctl(ifr);
+#endif
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+/**
+ * atl2_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl2_tx_timeout(struct net_device *netdev)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+
+ /* Do the reset outside of interrupt context */
+ schedule_work(&adapter->reset_task);
+}
+
+/**
+ * atl2_watchdog - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl2_watchdog(unsigned long data)
+{
+ struct atl2_adapter *adapter = (struct atl2_adapter *) data;
+
+ if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
+ u32 drop_rxd, drop_rxs;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+ drop_rxd = ATL2_READ_REG(&adapter->hw, REG_STS_RXD_OV);
+ drop_rxs = ATL2_READ_REG(&adapter->hw, REG_STS_RXS_OV);
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+
+ adapter->netdev->stats.rx_over_errors += drop_rxd + drop_rxs;
+
+ /* Reset the timer */
+ mod_timer(&adapter->watchdog_timer,
+ round_jiffies(jiffies + 4 * HZ));
+ }
+}
+
+/**
+ * atl2_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl2_phy_config(unsigned long data)
+{
+ struct atl2_adapter *adapter = (struct atl2_adapter *) data;
+ struct atl2_hw *hw = &adapter->hw;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+ atl2_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
+ atl2_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN |
+ MII_CR_RESTART_AUTO_NEG);
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+ clear_bit(0, &adapter->cfg_phy);
+}
+
+static int atl2_up(struct atl2_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ int err = 0;
+ u32 val;
+
+ /* hardware has been reset, we need to reload some things */
+
+ err = atl2_init_hw(&adapter->hw);
+ if (err) {
+ err = -EIO;
+ return err;
+ }
+
+ atl2_set_multi(netdev);
+ init_ring_ptrs(adapter);
+
+ atl2_restore_vlan(adapter);
+
+ if (atl2_configure(adapter)) {
+ err = -EIO;
+ goto err_up;
+ }
+
+ clear_bit(__ATL2_DOWN, &adapter->flags);
+
+ val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL);
+ ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val |
+ MASTER_CTRL_MANUAL_INT);
+
+ atl2_irq_enable(adapter);
+
+err_up:
+ return err;
+}
+
+static void atl2_reinit_locked(struct atl2_adapter *adapter)
+{
+ WARN_ON(in_interrupt());
+ while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags))
+ msleep(1);
+ atl2_down(adapter);
+ atl2_up(adapter);
+ clear_bit(__ATL2_RESETTING, &adapter->flags);
+}
+
+static void atl2_reset_task(struct work_struct *work)
+{
+ struct atl2_adapter *adapter;
+ adapter = container_of(work, struct atl2_adapter, reset_task);
+
+ atl2_reinit_locked(adapter);
+}
+
+static void atl2_setup_mac_ctrl(struct atl2_adapter *adapter)
+{
+ u32 value;
+ struct atl2_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+
+ /* Config MAC CTRL Register */
+ value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY;
+
+ /* duplex */
+ if (FULL_DUPLEX == adapter->link_duplex)
+ value |= MAC_CTRL_DUPLX;
+
+ /* flow control */
+ value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
+
+ /* PAD & CRC */
+ value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+
+ /* preamble length */
+ value |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) <<
+ MAC_CTRL_PRMLEN_SHIFT);
+
+ /* vlan */
+ __atl2_vlan_mode(netdev->features, &value);
+
+ /* filter mode */
+ value |= MAC_CTRL_BC_EN;
+ if (netdev->flags & IFF_PROMISC)
+ value |= MAC_CTRL_PROMIS_EN;
+ else if (netdev->flags & IFF_ALLMULTI)
+ value |= MAC_CTRL_MC_ALL_EN;
+
+ /* half retry buffer */
+ value |= (((u32)(adapter->hw.retry_buf &
+ MAC_CTRL_HALF_LEFT_BUF_MASK)) << MAC_CTRL_HALF_LEFT_BUF_SHIFT);
+
+ ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
+}
+
+static int atl2_check_link(struct atl2_adapter *adapter)
+{
+ struct atl2_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
+ int ret_val;
+ u16 speed, duplex, phy_data;
+ int reconfig = 0;
+
+ /* MII_BMSR must read twise */
+ atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
+ atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
+ if (!(phy_data&BMSR_LSTATUS)) { /* link down */
+ if (netif_carrier_ok(netdev)) { /* old link state: Up */
+ u32 value;
+ /* disable rx */
+ value = ATL2_READ_REG(hw, REG_MAC_CTRL);
+ value &= ~MAC_CTRL_RX_EN;
+ ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
+ adapter->link_speed = SPEED_0;
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
+ return 0;
+ }
+
+ /* Link Up */
+ ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex);
+ if (ret_val)
+ return ret_val;
+ switch (hw->MediaType) {
+ case MEDIA_TYPE_100M_FULL:
+ if (speed != SPEED_100 || duplex != FULL_DUPLEX)
+ reconfig = 1;
+ break;
+ case MEDIA_TYPE_100M_HALF:
+ if (speed != SPEED_100 || duplex != HALF_DUPLEX)
+ reconfig = 1;
+ break;
+ case MEDIA_TYPE_10M_FULL:
+ if (speed != SPEED_10 || duplex != FULL_DUPLEX)
+ reconfig = 1;
+ break;
+ case MEDIA_TYPE_10M_HALF:
+ if (speed != SPEED_10 || duplex != HALF_DUPLEX)
+ reconfig = 1;
+ break;
+ }
+ /* link result is our setting */
+ if (reconfig == 0) {
+ if (adapter->link_speed != speed ||
+ adapter->link_duplex != duplex) {
+ adapter->link_speed = speed;
+ adapter->link_duplex = duplex;
+ atl2_setup_mac_ctrl(adapter);
+ printk(KERN_INFO "%s: %s NIC Link is Up<%d Mbps %s>\n",
+ atl2_driver_name, netdev->name,
+ adapter->link_speed,
+ adapter->link_duplex == FULL_DUPLEX ?
+ "Full Duplex" : "Half Duplex");
+ }
+
+ if (!netif_carrier_ok(netdev)) { /* Link down -> Up */
+ netif_carrier_on(netdev);
+ netif_wake_queue(netdev);
+ }
+ return 0;
+ }
+
+ /* change original link status */
+ if (netif_carrier_ok(netdev)) {
+ u32 value;
+ /* disable rx */
+ value = ATL2_READ_REG(hw, REG_MAC_CTRL);
+ value &= ~MAC_CTRL_RX_EN;
+ ATL2_WRITE_REG(hw, REG_MAC_CTRL, value);
+
+ adapter->link_speed = SPEED_0;
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ }
+
+ /* auto-neg, insert timer to re-config phy
+ * (if interval smaller than 5 seconds, something strange) */
+ if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
+ if (!test_and_set_bit(0, &adapter->cfg_phy))
+ mod_timer(&adapter->phy_config_timer,
+ round_jiffies(jiffies + 5 * HZ));
+ }
+
+ return 0;
+}
+
+/**
+ * atl2_link_chg_task - deal with link change event Out of interrupt context
+ */
+static void atl2_link_chg_task(struct work_struct *work)
+{
+ struct atl2_adapter *adapter;
+ unsigned long flags;
+
+ adapter = container_of(work, struct atl2_adapter, link_chg_task);
+
+ spin_lock_irqsave(&adapter->stats_lock, flags);
+ atl2_check_link(adapter);
+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
+}
+
+static void atl2_setup_pcicmd(struct pci_dev *pdev)
+{
+ u16 cmd;
+
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+
+ if (cmd & PCI_COMMAND_INTX_DISABLE)
+ cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ if (cmd & PCI_COMMAND_IO)
+ cmd &= ~PCI_COMMAND_IO;
+ if (0 == (cmd & PCI_COMMAND_MEMORY))
+ cmd |= PCI_COMMAND_MEMORY;
+ if (0 == (cmd & PCI_COMMAND_MASTER))
+ cmd |= PCI_COMMAND_MASTER;
+ pci_write_config_word(pdev, PCI_COMMAND, cmd);
+
+ /*
+ * some motherboards BIOS(PXE/EFI) driver may set PME
+ * while they transfer control to OS (Windows/Linux)
+ * so we should clear this bit before NIC work normally
+ */
+ pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void atl2_poll_controller(struct net_device *netdev)
+{
+ disable_irq(netdev->irq);
+ atl2_intr(netdev->irq, netdev);
+ enable_irq(netdev->irq);
+}
+#endif
+
+
+static const struct net_device_ops atl2_netdev_ops = {
+ .ndo_open = atl2_open,
+ .ndo_stop = atl2_close,
+ .ndo_start_xmit = atl2_xmit_frame,
+ .ndo_set_rx_mode = atl2_set_multi,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = atl2_set_mac,
+ .ndo_change_mtu = atl2_change_mtu,
+ .ndo_fix_features = atl2_fix_features,
+ .ndo_set_features = atl2_set_features,
+ .ndo_do_ioctl = atl2_ioctl,
+ .ndo_tx_timeout = atl2_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl2_poll_controller,
+#endif
+};
+
+/**
+ * atl2_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in atl2_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * atl2_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ */
+static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct net_device *netdev;
+ struct atl2_adapter *adapter;
+ static int cards_found;
+ unsigned long mmio_start;
+ int mmio_len;
+ int err;
+
+ cards_found = 0;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+
+ /*
+ * atl2 is a shared-high-32-bit device, so we're stuck with 32-bit DMA
+ * until the kernel has the proper infrastructure to support 64-bit DMA
+ * on these devices.
+ */
+ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) &&
+ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n");
+ goto err_dma;
+ }
+
+ /* Mark all PCI regions associated with PCI device
+ * pdev as being reserved by owner atl2_driver_name */
+ err = pci_request_regions(pdev, atl2_driver_name);
+ if (err)
+ goto err_pci_reg;
+
+ /* Enables bus-mastering on the device and calls
+ * pcibios_set_master to do the needed arch specific settings */
+ pci_set_master(pdev);
+
+ err = -ENOMEM;
+ netdev = alloc_etherdev(sizeof(struct atl2_adapter));
+ if (!netdev)
+ goto err_alloc_etherdev;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ pci_set_drvdata(pdev, netdev);
+ adapter = netdev_priv(netdev);
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->hw.back = adapter;
+
+ mmio_start = pci_resource_start(pdev, 0x0);
+ mmio_len = pci_resource_len(pdev, 0x0);
+
+ adapter->hw.mem_rang = (u32)mmio_len;
+ adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
+ if (!adapter->hw.hw_addr) {
+ err = -EIO;
+ goto err_ioremap;
+ }
+
+ atl2_setup_pcicmd(pdev);
+
+ netdev->netdev_ops = &atl2_netdev_ops;
+ netdev->ethtool_ops = &atl2_ethtool_ops;
+ netdev->watchdog_timeo = 5 * HZ;
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+ netdev->mem_start = mmio_start;
+ netdev->mem_end = mmio_start + mmio_len;
+ adapter->bd_number = cards_found;
+ adapter->pci_using_64 = false;
+
+ /* setup the private structure */
+ err = atl2_sw_init(adapter);
+ if (err)
+ goto err_sw_init;
+
+ err = -EIO;
+
+ netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_RX;
+ netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
+
+ /* Init PHY as early as possible due to power saving issue */
+ atl2_phy_init(&adapter->hw);
+
+ /* reset the controller to
+ * put the device in a known good starting state */
+
+ if (atl2_reset_hw(&adapter->hw)) {
+ err = -EIO;
+ goto err_reset;
+ }
+
+ /* copy the MAC address out of the EEPROM */
+ atl2_read_mac_addr(&adapter->hw);
+ memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+ if (!is_valid_ether_addr(netdev->dev_addr)) {
+ err = -EIO;
+ goto err_eeprom;
+ }
+
+ atl2_check_options(adapter);
+
+ init_timer(&adapter->watchdog_timer);
+ adapter->watchdog_timer.function = atl2_watchdog;
+ adapter->watchdog_timer.data = (unsigned long) adapter;
+
+ init_timer(&adapter->phy_config_timer);
+ adapter->phy_config_timer.function = atl2_phy_config;
+ adapter->phy_config_timer.data = (unsigned long) adapter;
+
+ INIT_WORK(&adapter->reset_task, atl2_reset_task);
+ INIT_WORK(&adapter->link_chg_task, atl2_link_chg_task);
+
+ strcpy(netdev->name, "eth%d"); /* ?? */
+ err = register_netdev(netdev);
+ if (err)
+ goto err_register;
+
+ /* assume we have no link for now */
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+
+ cards_found++;
+
+ return 0;
+
+err_reset:
+err_register:
+err_sw_init:
+err_eeprom:
+ iounmap(adapter->hw.hw_addr);
+err_ioremap:
+ free_netdev(netdev);
+err_alloc_etherdev:
+ pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+ pci_disable_device(pdev);
+ return err;
+}
+
+/**
+ * atl2_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * atl2_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device. The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ */
+/* FIXME: write the original MAC address back in case it was changed from a
+ * BIOS-set value, as in atl1 -- CHS */
+static void atl2_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+
+ /* flush_scheduled work may reschedule our watchdog task, so
+ * explicitly disable watchdog tasks from being rescheduled */
+ set_bit(__ATL2_DOWN, &adapter->flags);
+
+ del_timer_sync(&adapter->watchdog_timer);
+ del_timer_sync(&adapter->phy_config_timer);
+ cancel_work_sync(&adapter->reset_task);
+ cancel_work_sync(&adapter->link_chg_task);
+
+ unregister_netdev(netdev);
+
+ atl2_force_ps(&adapter->hw);
+
+ iounmap(adapter->hw.hw_addr);
+ pci_release_regions(pdev);
+
+ free_netdev(netdev);
+
+ pci_disable_device(pdev);
+}
+
+static int atl2_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+ u16 speed, duplex;
+ u32 ctrl = 0;
+ u32 wufc = adapter->wol;
+
+#ifdef CONFIG_PM
+ int retval = 0;
+#endif
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev)) {
+ WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags));
+ atl2_down(adapter);
+ }
+
+#ifdef CONFIG_PM
+ retval = pci_save_state(pdev);
+ if (retval)
+ return retval;
+#endif
+
+ atl2_read_phy_reg(hw, MII_BMSR, (u16 *)&ctrl);
+ atl2_read_phy_reg(hw, MII_BMSR, (u16 *)&ctrl);
+ if (ctrl & BMSR_LSTATUS)
+ wufc &= ~ATLX_WUFC_LNKC;
+
+ if (0 != (ctrl & BMSR_LSTATUS) && 0 != wufc) {
+ u32 ret_val;
+ /* get current link speed & duplex */
+ ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex);
+ if (ret_val) {
+ printk(KERN_DEBUG
+ "%s: get speed&duplex error while suspend\n",
+ atl2_driver_name);
+ goto wol_dis;
+ }
+
+ ctrl = 0;
+
+ /* turn on magic packet wol */
+ if (wufc & ATLX_WUFC_MAG)
+ ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN);
+
+ /* ignore Link Chg event when Link is up */
+ ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl);
+
+ /* Config MAC CTRL Register */
+ ctrl = MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY;
+ if (FULL_DUPLEX == adapter->link_duplex)
+ ctrl |= MAC_CTRL_DUPLX;
+ ctrl |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
+ ctrl |= (((u32)adapter->hw.preamble_len &
+ MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
+ ctrl |= (((u32)(adapter->hw.retry_buf &
+ MAC_CTRL_HALF_LEFT_BUF_MASK)) <<
+ MAC_CTRL_HALF_LEFT_BUF_SHIFT);
+ if (wufc & ATLX_WUFC_MAG) {
+ /* magic packet maybe Broadcast&multicast&Unicast */
+ ctrl |= MAC_CTRL_BC_EN;
+ }
+
+ ATL2_WRITE_REG(hw, REG_MAC_CTRL, ctrl);
+
+ /* pcie patch */
+ ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
+ ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+ ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+ ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
+ ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
+ ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+ goto suspend_exit;
+ }
+
+ if (0 == (ctrl&BMSR_LSTATUS) && 0 != (wufc&ATLX_WUFC_LNKC)) {
+ /* link is down, so only LINK CHG WOL event enable */
+ ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
+ ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl);
+ ATL2_WRITE_REG(hw, REG_MAC_CTRL, 0);
+
+ /* pcie patch */
+ ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
+ ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+ ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+ ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
+ ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
+ ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
+
+ hw->phy_configured = false; /* re-init PHY when resume */
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
+
+ goto suspend_exit;
+ }
+
+wol_dis:
+ /* WOL disabled */
+ ATL2_WRITE_REG(hw, REG_WOL_CTRL, 0);
+
+ /* pcie patch */
+ ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC);
+ ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
+ ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
+ ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1);
+ ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK;
+ ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl);
+
+ atl2_force_ps(hw);
+ hw->phy_configured = false; /* re-init PHY when resume */
+
+ pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+
+suspend_exit:
+ if (netif_running(netdev))
+ atl2_free_irq(adapter);
+
+ pci_disable_device(pdev);
+
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int atl2_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ u32 err;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR
+ "atl2: Cannot enable PCI device from suspend\n");
+ return err;
+ }
+
+ pci_set_master(pdev);
+
+ ATL2_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */
+
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+
+ ATL2_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
+
+ if (netif_running(netdev)) {
+ err = atl2_request_irq(adapter);
+ if (err)
+ return err;
+ }
+
+ atl2_reset_hw(&adapter->hw);
+
+ if (netif_running(netdev))
+ atl2_up(adapter);
+
+ netif_device_attach(netdev);
+
+ return 0;
+}
+#endif
+
+static void atl2_shutdown(struct pci_dev *pdev)
+{
+ atl2_suspend(pdev, PMSG_SUSPEND);
+}
+
+static struct pci_driver atl2_driver = {
+ .name = atl2_driver_name,
+ .id_table = atl2_pci_tbl,
+ .probe = atl2_probe,
+ .remove = atl2_remove,
+ /* Power Management Hooks */
+ .suspend = atl2_suspend,
+#ifdef CONFIG_PM
+ .resume = atl2_resume,
+#endif
+ .shutdown = atl2_shutdown,
+};
+
+/**
+ * atl2_init_module - Driver Registration Routine
+ *
+ * atl2_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ */
+static int __init atl2_init_module(void)
+{
+ printk(KERN_INFO "%s - version %s\n", atl2_driver_string,
+ atl2_driver_version);
+ printk(KERN_INFO "%s\n", atl2_copyright);
+ return pci_register_driver(&atl2_driver);
+}
+module_init(atl2_init_module);
+
+/**
+ * atl2_exit_module - Driver Exit Cleanup Routine
+ *
+ * atl2_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit atl2_exit_module(void)
+{
+ pci_unregister_driver(&atl2_driver);
+}
+module_exit(atl2_exit_module);
+
+static void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value)
+{
+ struct atl2_adapter *adapter = hw->back;
+ pci_read_config_word(adapter->pdev, reg, value);
+}
+
+static void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value)
+{
+ struct atl2_adapter *adapter = hw->back;
+ pci_write_config_word(adapter->pdev, reg, *value);
+}
+
+static int atl2_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+
+ ecmd->supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_TP);
+ ecmd->advertising = ADVERTISED_TP;
+
+ ecmd->advertising |= ADVERTISED_Autoneg;
+ ecmd->advertising |= hw->autoneg_advertised;
+
+ ecmd->port = PORT_TP;
+ ecmd->phy_address = 0;
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (adapter->link_speed != SPEED_0) {
+ ethtool_cmd_speed_set(ecmd, adapter->link_speed);
+ if (adapter->link_duplex == FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+ } else {
+ ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+ ecmd->duplex = DUPLEX_UNKNOWN;
+ }
+
+ ecmd->autoneg = AUTONEG_ENABLE;
+ return 0;
+}
+
+static int atl2_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+
+ while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags))
+ msleep(1);
+
+ if (ecmd->autoneg == AUTONEG_ENABLE) {
+#define MY_ADV_MASK (ADVERTISE_10_HALF | \
+ ADVERTISE_10_FULL | \
+ ADVERTISE_100_HALF| \
+ ADVERTISE_100_FULL)
+
+ if ((ecmd->advertising & MY_ADV_MASK) == MY_ADV_MASK) {
+ hw->MediaType = MEDIA_TYPE_AUTO_SENSOR;
+ hw->autoneg_advertised = MY_ADV_MASK;
+ } else if ((ecmd->advertising & MY_ADV_MASK) ==
+ ADVERTISE_100_FULL) {
+ hw->MediaType = MEDIA_TYPE_100M_FULL;
+ hw->autoneg_advertised = ADVERTISE_100_FULL;
+ } else if ((ecmd->advertising & MY_ADV_MASK) ==
+ ADVERTISE_100_HALF) {
+ hw->MediaType = MEDIA_TYPE_100M_HALF;
+ hw->autoneg_advertised = ADVERTISE_100_HALF;
+ } else if ((ecmd->advertising & MY_ADV_MASK) ==
+ ADVERTISE_10_FULL) {
+ hw->MediaType = MEDIA_TYPE_10M_FULL;
+ hw->autoneg_advertised = ADVERTISE_10_FULL;
+ } else if ((ecmd->advertising & MY_ADV_MASK) ==
+ ADVERTISE_10_HALF) {
+ hw->MediaType = MEDIA_TYPE_10M_HALF;
+ hw->autoneg_advertised = ADVERTISE_10_HALF;
+ } else {
+ clear_bit(__ATL2_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+ ecmd->advertising = hw->autoneg_advertised |
+ ADVERTISED_TP | ADVERTISED_Autoneg;
+ } else {
+ clear_bit(__ATL2_RESETTING, &adapter->flags);
+ return -EINVAL;
+ }
+
+ /* reset the link */
+ if (netif_running(adapter->netdev)) {
+ atl2_down(adapter);
+ atl2_up(adapter);
+ } else
+ atl2_reset_hw(&adapter->hw);
+
+ clear_bit(__ATL2_RESETTING, &adapter->flags);
+ return 0;
+}
+
+static u32 atl2_get_msglevel(struct net_device *netdev)
+{
+ return 0;
+}
+
+/*
+ * It's sane for this to be empty, but we might want to take advantage of this.
+ */
+static void atl2_set_msglevel(struct net_device *netdev, u32 data)
+{
+}
+
+static int atl2_get_regs_len(struct net_device *netdev)
+{
+#define ATL2_REGS_LEN 42
+ return sizeof(u32) * ATL2_REGS_LEN;
+}
+
+static void atl2_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+ u32 *regs_buff = p;
+ u16 phy_data;
+
+ memset(p, 0, sizeof(u32) * ATL2_REGS_LEN);
+
+ regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
+
+ regs_buff[0] = ATL2_READ_REG(hw, REG_VPD_CAP);
+ regs_buff[1] = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
+ regs_buff[2] = ATL2_READ_REG(hw, REG_SPI_FLASH_CONFIG);
+ regs_buff[3] = ATL2_READ_REG(hw, REG_TWSI_CTRL);
+ regs_buff[4] = ATL2_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL);
+ regs_buff[5] = ATL2_READ_REG(hw, REG_MASTER_CTRL);
+ regs_buff[6] = ATL2_READ_REG(hw, REG_MANUAL_TIMER_INIT);
+ regs_buff[7] = ATL2_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT);
+ regs_buff[8] = ATL2_READ_REG(hw, REG_PHY_ENABLE);
+ regs_buff[9] = ATL2_READ_REG(hw, REG_CMBDISDMA_TIMER);
+ regs_buff[10] = ATL2_READ_REG(hw, REG_IDLE_STATUS);
+ regs_buff[11] = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+ regs_buff[12] = ATL2_READ_REG(hw, REG_SERDES_LOCK);
+ regs_buff[13] = ATL2_READ_REG(hw, REG_MAC_CTRL);
+ regs_buff[14] = ATL2_READ_REG(hw, REG_MAC_IPG_IFG);
+ regs_buff[15] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR);
+ regs_buff[16] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR+4);
+ regs_buff[17] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE);
+ regs_buff[18] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE+4);
+ regs_buff[19] = ATL2_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL);
+ regs_buff[20] = ATL2_READ_REG(hw, REG_MTU);
+ regs_buff[21] = ATL2_READ_REG(hw, REG_WOL_CTRL);
+ regs_buff[22] = ATL2_READ_REG(hw, REG_SRAM_TXRAM_END);
+ regs_buff[23] = ATL2_READ_REG(hw, REG_DESC_BASE_ADDR_HI);
+ regs_buff[24] = ATL2_READ_REG(hw, REG_TXD_BASE_ADDR_LO);
+ regs_buff[25] = ATL2_READ_REG(hw, REG_TXD_MEM_SIZE);
+ regs_buff[26] = ATL2_READ_REG(hw, REG_TXS_BASE_ADDR_LO);
+ regs_buff[27] = ATL2_READ_REG(hw, REG_TXS_MEM_SIZE);
+ regs_buff[28] = ATL2_READ_REG(hw, REG_RXD_BASE_ADDR_LO);
+ regs_buff[29] = ATL2_READ_REG(hw, REG_RXD_BUF_NUM);
+ regs_buff[30] = ATL2_READ_REG(hw, REG_DMAR);
+ regs_buff[31] = ATL2_READ_REG(hw, REG_TX_CUT_THRESH);
+ regs_buff[32] = ATL2_READ_REG(hw, REG_DMAW);
+ regs_buff[33] = ATL2_READ_REG(hw, REG_PAUSE_ON_TH);
+ regs_buff[34] = ATL2_READ_REG(hw, REG_PAUSE_OFF_TH);
+ regs_buff[35] = ATL2_READ_REG(hw, REG_MB_TXD_WR_IDX);
+ regs_buff[36] = ATL2_READ_REG(hw, REG_MB_RXD_RD_IDX);
+ regs_buff[38] = ATL2_READ_REG(hw, REG_ISR);
+ regs_buff[39] = ATL2_READ_REG(hw, REG_IMR);
+
+ atl2_read_phy_reg(hw, MII_BMCR, &phy_data);
+ regs_buff[40] = (u32)phy_data;
+ atl2_read_phy_reg(hw, MII_BMSR, &phy_data);
+ regs_buff[41] = (u32)phy_data;
+}
+
+static int atl2_get_eeprom_len(struct net_device *netdev)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+
+ if (!atl2_check_eeprom_exist(&adapter->hw))
+ return 512;
+ else
+ return 0;
+}
+
+static int atl2_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+ u32 *eeprom_buff;
+ int first_dword, last_dword;
+ int ret_val = 0;
+ int i;
+
+ if (eeprom->len == 0)
+ return -EINVAL;
+
+ if (atl2_check_eeprom_exist(hw))
+ return -EINVAL;
+
+ eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+
+ first_dword = eeprom->offset >> 2;
+ last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+
+ eeprom_buff = kmalloc(sizeof(u32) * (last_dword - first_dword + 1),
+ GFP_KERNEL);
+ if (!eeprom_buff)
+ return -ENOMEM;
+
+ for (i = first_dword; i < last_dword; i++) {
+ if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) {
+ ret_val = -EIO;
+ goto free;
+ }
+ }
+
+ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
+ eeprom->len);
+free:
+ kfree(eeprom_buff);
+
+ return ret_val;
+}
+
+static int atl2_set_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ struct atl2_hw *hw = &adapter->hw;
+ u32 *eeprom_buff;
+ u32 *ptr;
+ int max_len, first_dword, last_dword, ret_val = 0;
+ int i;
+
+ if (eeprom->len == 0)
+ return -EOPNOTSUPP;
+
+ if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+ return -EFAULT;
+
+ max_len = 512;
+
+ first_dword = eeprom->offset >> 2;
+ last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
+ eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+ if (!eeprom_buff)
+ return -ENOMEM;
+
+ ptr = eeprom_buff;
+
+ if (eeprom->offset & 3) {
+ /* need read/modify/write of first changed EEPROM word */
+ /* only the second byte of the word is being modified */
+ if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) {
+ ret_val = -EIO;
+ goto out;
+ }
+ ptr++;
+ }
+ if (((eeprom->offset + eeprom->len) & 3)) {
+ /*
+ * need read/modify/write of last changed EEPROM word
+ * only the first byte of the word is being modified
+ */
+ if (!atl2_read_eeprom(hw, last_dword * 4,
+ &(eeprom_buff[last_dword - first_dword]))) {
+ ret_val = -EIO;
+ goto out;
+ }
+ }
+
+ /* Device's eeprom is always little-endian, word addressable */
+ memcpy(ptr, bytes, eeprom->len);
+
+ for (i = 0; i < last_dword - first_dword + 1; i++) {
+ if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) {
+ ret_val = -EIO;
+ goto out;
+ }
+ }
+ out:
+ kfree(eeprom_buff);
+ return ret_val;
+}
+
+static void atl2_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+
+ strlcpy(drvinfo->driver, atl2_driver_name, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, atl2_driver_version,
+ sizeof(drvinfo->version));
+ strlcpy(drvinfo->fw_version, "L2", sizeof(drvinfo->fw_version));
+ strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
+ drvinfo->n_stats = 0;
+ drvinfo->testinfo_len = 0;
+ drvinfo->regdump_len = atl2_get_regs_len(netdev);
+ drvinfo->eedump_len = atl2_get_eeprom_len(netdev);
+}
+
+static void atl2_get_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_MAGIC;
+ wol->wolopts = 0;
+
+ if (adapter->wol & ATLX_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if (adapter->wol & ATLX_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if (adapter->wol & ATLX_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if (adapter->wol & ATLX_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+ if (adapter->wol & ATLX_WUFC_LNKC)
+ wol->wolopts |= WAKE_PHY;
+}
+
+static int atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
+ return -EOPNOTSUPP;
+
+ if (wol->wolopts & (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
+ return -EOPNOTSUPP;
+
+ /* these settings will always override what we currently have */
+ adapter->wol = 0;
+
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= ATLX_WUFC_MAG;
+ if (wol->wolopts & WAKE_PHY)
+ adapter->wol |= ATLX_WUFC_LNKC;
+
+ return 0;
+}
+
+static int atl2_nway_reset(struct net_device *netdev)
+{
+ struct atl2_adapter *adapter = netdev_priv(netdev);
+ if (netif_running(netdev))
+ atl2_reinit_locked(adapter);
+ return 0;
+}
+
+static const struct ethtool_ops atl2_ethtool_ops = {
+ .get_settings = atl2_get_settings,
+ .set_settings = atl2_set_settings,
+ .get_drvinfo = atl2_get_drvinfo,
+ .get_regs_len = atl2_get_regs_len,
+ .get_regs = atl2_get_regs,
+ .get_wol = atl2_get_wol,
+ .set_wol = atl2_set_wol,
+ .get_msglevel = atl2_get_msglevel,
+ .set_msglevel = atl2_set_msglevel,
+ .nway_reset = atl2_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_eeprom_len = atl2_get_eeprom_len,
+ .get_eeprom = atl2_get_eeprom,
+ .set_eeprom = atl2_set_eeprom,
+};
+
+#define LBYTESWAP(a) ((((a) & 0x00ff00ff) << 8) | \
+ (((a) & 0xff00ff00) >> 8))
+#define LONGSWAP(a) ((LBYTESWAP(a) << 16) | (LBYTESWAP(a) >> 16))
+#define SHORTSWAP(a) (((a) << 8) | ((a) >> 8))
+
+/*
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * return : 0 or idle status (if error)
+ */
+static s32 atl2_reset_hw(struct atl2_hw *hw)
+{
+ u32 icr;
+ u16 pci_cfg_cmd_word;
+ int i;
+
+ /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */
+ atl2_read_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word);
+ if ((pci_cfg_cmd_word &
+ (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) !=
+ (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) {
+ pci_cfg_cmd_word |=
+ (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER);
+ atl2_write_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word);
+ }
+
+ /* Clear Interrupt mask to stop board from generating
+ * interrupts & Clear any pending interrupt events
+ */
+ /* FIXME */
+ /* ATL2_WRITE_REG(hw, REG_IMR, 0); */
+ /* ATL2_WRITE_REG(hw, REG_ISR, 0xffffffff); */
+
+ /* Issue Soft Reset to the MAC. This will reset the chip's
+ * transmit, receive, DMA. It will not effect
+ * the current PCI configuration. The global reset bit is self-
+ * clearing, and should clear within a microsecond.
+ */
+ ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST);
+ wmb();
+ msleep(1); /* delay about 1ms */
+
+ /* Wait at least 10ms for All module to be Idle */
+ for (i = 0; i < 10; i++) {
+ icr = ATL2_READ_REG(hw, REG_IDLE_STATUS);
+ if (!icr)
+ break;
+ msleep(1); /* delay 1 ms */
+ cpu_relax();
+ }
+
+ if (icr)
+ return icr;
+
+ return 0;
+}
+
+#define CUSTOM_SPI_CS_SETUP 2
+#define CUSTOM_SPI_CLK_HI 2
+#define CUSTOM_SPI_CLK_LO 2
+#define CUSTOM_SPI_CS_HOLD 2
+#define CUSTOM_SPI_CS_HI 3
+
+static struct atl2_spi_flash_dev flash_table[] =
+{
+/* MFR WRSR READ PROGRAM WREN WRDI RDSR RDID SECTOR_ERASE CHIP_ERASE */
+{"Atmel", 0x0, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62 },
+{"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60 },
+{"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7 },
+};
+
+static bool atl2_spi_read(struct atl2_hw *hw, u32 addr, u32 *buf)
+{
+ int i;
+ u32 value;
+
+ ATL2_WRITE_REG(hw, REG_SPI_DATA, 0);
+ ATL2_WRITE_REG(hw, REG_SPI_ADDR, addr);
+
+ value = SPI_FLASH_CTRL_WAIT_READY |
+ (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) <<
+ SPI_FLASH_CTRL_CS_SETUP_SHIFT |
+ (CUSTOM_SPI_CLK_HI & SPI_FLASH_CTRL_CLK_HI_MASK) <<
+ SPI_FLASH_CTRL_CLK_HI_SHIFT |
+ (CUSTOM_SPI_CLK_LO & SPI_FLASH_CTRL_CLK_LO_MASK) <<
+ SPI_FLASH_CTRL_CLK_LO_SHIFT |
+ (CUSTOM_SPI_CS_HOLD & SPI_FLASH_CTRL_CS_HOLD_MASK) <<
+ SPI_FLASH_CTRL_CS_HOLD_SHIFT |
+ (CUSTOM_SPI_CS_HI & SPI_FLASH_CTRL_CS_HI_MASK) <<
+ SPI_FLASH_CTRL_CS_HI_SHIFT |
+ (0x1 & SPI_FLASH_CTRL_INS_MASK) << SPI_FLASH_CTRL_INS_SHIFT;
+
+ ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+
+ value |= SPI_FLASH_CTRL_START;
+
+ ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+
+ for (i = 0; i < 10; i++) {
+ msleep(1);
+ value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
+ if (!(value & SPI_FLASH_CTRL_START))
+ break;
+ }
+
+ if (value & SPI_FLASH_CTRL_START)
+ return false;
+
+ *buf = ATL2_READ_REG(hw, REG_SPI_DATA);
+
+ return true;
+}
+
+/*
+ * get_permanent_address
+ * return 0 if get valid mac address,
+ */
+static int get_permanent_address(struct atl2_hw *hw)
+{
+ u32 Addr[2];
+ u32 i, Control;
+ u16 Register;
+ u8 EthAddr[ETH_ALEN];
+ bool KeyValid;
+
+ if (is_valid_ether_addr(hw->perm_mac_addr))
+ return 0;
+
+ Addr[0] = 0;
+ Addr[1] = 0;
+
+ if (!atl2_check_eeprom_exist(hw)) { /* eeprom exists */
+ Register = 0;
+ KeyValid = false;
+
+ /* Read out all EEPROM content */
+ i = 0;
+ while (1) {
+ if (atl2_read_eeprom(hw, i + 0x100, &Control)) {
+ if (KeyValid) {
+ if (Register == REG_MAC_STA_ADDR)
+ Addr[0] = Control;
+ else if (Register ==
+ (REG_MAC_STA_ADDR + 4))
+ Addr[1] = Control;
+ KeyValid = false;
+ } else if ((Control & 0xff) == 0x5A) {
+ KeyValid = true;
+ Register = (u16) (Control >> 16);
+ } else {
+ /* assume data end while encount an invalid KEYWORD */
+ break;
+ }
+ } else {
+ break; /* read error */
+ }
+ i += 4;
+ }
+
+ *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
+ *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *) &Addr[1]);
+
+ if (is_valid_ether_addr(EthAddr)) {
+ memcpy(hw->perm_mac_addr, EthAddr, ETH_ALEN);
+ return 0;
+ }
+ return 1;
+ }
+
+ /* see if SPI flash exists? */
+ Addr[0] = 0;
+ Addr[1] = 0;
+ Register = 0;
+ KeyValid = false;
+ i = 0;
+ while (1) {
+ if (atl2_spi_read(hw, i + 0x1f000, &Control)) {
+ if (KeyValid) {
+ if (Register == REG_MAC_STA_ADDR)
+ Addr[0] = Control;
+ else if (Register == (REG_MAC_STA_ADDR + 4))
+ Addr[1] = Control;
+ KeyValid = false;
+ } else if ((Control & 0xff) == 0x5A) {
+ KeyValid = true;
+ Register = (u16) (Control >> 16);
+ } else {
+ break; /* data end */
+ }
+ } else {
+ break; /* read error */
+ }
+ i += 4;
+ }
+
+ *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
+ *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *)&Addr[1]);
+ if (is_valid_ether_addr(EthAddr)) {
+ memcpy(hw->perm_mac_addr, EthAddr, ETH_ALEN);
+ return 0;
+ }
+ /* maybe MAC-address is from BIOS */
+ Addr[0] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR);
+ Addr[1] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR + 4);
+ *(u32 *) &EthAddr[2] = LONGSWAP(Addr[0]);
+ *(u16 *) &EthAddr[0] = SHORTSWAP(*(u16 *) &Addr[1]);
+
+ if (is_valid_ether_addr(EthAddr)) {
+ memcpy(hw->perm_mac_addr, EthAddr, ETH_ALEN);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Reads the adapter's MAC address from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static s32 atl2_read_mac_addr(struct atl2_hw *hw)
+{
+ if (get_permanent_address(hw)) {
+ /* for test */
+ /* FIXME: shouldn't we use eth_random_addr() here? */
+ hw->perm_mac_addr[0] = 0x00;
+ hw->perm_mac_addr[1] = 0x13;
+ hw->perm_mac_addr[2] = 0x74;
+ hw->perm_mac_addr[3] = 0x00;
+ hw->perm_mac_addr[4] = 0x5c;
+ hw->perm_mac_addr[5] = 0x38;
+ }
+
+ memcpy(hw->mac_addr, hw->perm_mac_addr, ETH_ALEN);
+
+ return 0;
+}
+
+/*
+ * Hashes an address to determine its location in the multicast table
+ *
+ * hw - Struct containing variables accessed by shared code
+ * mc_addr - the multicast address to hash
+ *
+ * atl2_hash_mc_addr
+ * purpose
+ * set hash value for a multicast address
+ * hash calcu processing :
+ * 1. calcu 32bit CRC for multicast address
+ * 2. reverse crc with MSB to LSB
+ */
+static u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr)
+{
+ u32 crc32, value;
+ int i;
+
+ value = 0;
+ crc32 = ether_crc_le(6, mc_addr);
+
+ for (i = 0; i < 32; i++)
+ value |= (((crc32 >> i) & 1) << (31 - i));
+
+ return value;
+}
+
+/*
+ * Sets the bit in the multicast table corresponding to the hash value.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * hash_value - Multicast address hash value
+ */
+static void atl2_hash_set(struct atl2_hw *hw, u32 hash_value)
+{
+ u32 hash_bit, hash_reg;
+ u32 mta;
+
+ /* The HASH Table is a register array of 2 32-bit registers.
+ * It is treated like an array of 64 bits. We want to set
+ * bit BitArray[hash_value]. So we figure out what register
+ * the bit is in, read it, OR in the new bit, then write
+ * back the new value. The register is determined by the
+ * upper 7 bits of the hash value and the bit within that
+ * register are determined by the lower 5 bits of the value.
+ */
+ hash_reg = (hash_value >> 31) & 0x1;
+ hash_bit = (hash_value >> 26) & 0x1F;
+
+ mta = ATL2_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
+
+ mta |= (1 << hash_bit);
+
+ ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
+}
+
+/*
+ * atl2_init_pcie - init PCIE module
+ */
+static void atl2_init_pcie(struct atl2_hw *hw)
+{
+ u32 value;
+ value = LTSSM_TEST_MODE_DEF;
+ ATL2_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value);
+
+ value = PCIE_DLL_TX_CTRL1_DEF;
+ ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, value);
+}
+
+static void atl2_init_flash_opcode(struct atl2_hw *hw)
+{
+ if (hw->flash_vendor >= ARRAY_SIZE(flash_table))
+ hw->flash_vendor = 0; /* ATMEL */
+
+ /* Init OP table */
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_PROGRAM,
+ flash_table[hw->flash_vendor].cmdPROGRAM);
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_SC_ERASE,
+ flash_table[hw->flash_vendor].cmdSECTOR_ERASE);
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_CHIP_ERASE,
+ flash_table[hw->flash_vendor].cmdCHIP_ERASE);
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDID,
+ flash_table[hw->flash_vendor].cmdRDID);
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WREN,
+ flash_table[hw->flash_vendor].cmdWREN);
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDSR,
+ flash_table[hw->flash_vendor].cmdRDSR);
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WRSR,
+ flash_table[hw->flash_vendor].cmdWRSR);
+ ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_READ,
+ flash_table[hw->flash_vendor].cmdREAD);
+}
+
+/********************************************************************
+* Performs basic configuration of the adapter.
+*
+* hw - Struct containing variables accessed by shared code
+* Assumes that the controller has previously been reset and is in a
+* post-reset uninitialized state. Initializes multicast table,
+* and Calls routines to setup link
+* Leaves the transmit and receive units disabled and uninitialized.
+********************************************************************/
+static s32 atl2_init_hw(struct atl2_hw *hw)
+{
+ u32 ret_val = 0;
+
+ atl2_init_pcie(hw);
+
+ /* Zero out the Multicast HASH table */
+ /* clear the old settings from the multicast hash table */
+ ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
+ ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
+
+ atl2_init_flash_opcode(hw);
+
+ ret_val = atl2_phy_init(hw);
+
+ return ret_val;
+}
+
+/*
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ */
+static s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed,
+ u16 *duplex)
+{
+ s32 ret_val;
+ u16 phy_data;
+
+ /* Read PHY Specific Status Register (17) */
+ ret_val = atl2_read_phy_reg(hw, MII_ATLX_PSSR, &phy_data);
+ if (ret_val)
+ return ret_val;
+
+ if (!(phy_data & MII_ATLX_PSSR_SPD_DPLX_RESOLVED))
+ return ATLX_ERR_PHY_RES;
+
+ switch (phy_data & MII_ATLX_PSSR_SPEED) {
+ case MII_ATLX_PSSR_100MBS:
+ *speed = SPEED_100;
+ break;
+ case MII_ATLX_PSSR_10MBS:
+ *speed = SPEED_10;
+ break;
+ default:
+ return ATLX_ERR_PHY_SPEED;
+ break;
+ }
+
+ if (phy_data & MII_ATLX_PSSR_DPLX)
+ *duplex = FULL_DUPLEX;
+ else
+ *duplex = HALF_DUPLEX;
+
+ return 0;
+}
+
+/*
+ * Reads the value from a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to read
+ */
+static s32 atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data)
+{
+ u32 val;
+ int i;
+
+ val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
+ MDIO_START |
+ MDIO_SUP_PREAMBLE |
+ MDIO_RW |
+ MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+ ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ wmb();
+
+ for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+ udelay(2);
+ val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ break;
+ wmb();
+ }
+ if (!(val & (MDIO_START | MDIO_BUSY))) {
+ *phy_data = (u16)val;
+ return 0;
+ }
+
+ return ATLX_ERR_PHY;
+}
+
+/*
+ * Writes a value to a PHY register
+ * hw - Struct containing variables accessed by shared code
+ * reg_addr - address of the PHY register to write
+ * data - data to write to the PHY
+ */
+static s32 atl2_write_phy_reg(struct atl2_hw *hw, u32 reg_addr, u16 phy_data)
+{
+ int i;
+ u32 val;
+
+ val = ((u32)(phy_data & MDIO_DATA_MASK)) << MDIO_DATA_SHIFT |
+ (reg_addr & MDIO_REG_ADDR_MASK) << MDIO_REG_ADDR_SHIFT |
+ MDIO_SUP_PREAMBLE |
+ MDIO_START |
+ MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT;
+ ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val);
+
+ wmb();
+
+ for (i = 0; i < MDIO_WAIT_TIMES; i++) {
+ udelay(2);
+ val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ break;
+
+ wmb();
+ }
+
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ return 0;
+
+ return ATLX_ERR_PHY;
+}
+
+/*
+ * Configures PHY autoneg and flow control advertisement settings
+ *
+ * hw - Struct containing variables accessed by shared code
+ */
+static s32 atl2_phy_setup_autoneg_adv(struct atl2_hw *hw)
+{
+ s32 ret_val;
+ s16 mii_autoneg_adv_reg;
+
+ /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+ mii_autoneg_adv_reg = MII_AR_DEFAULT_CAP_MASK;
+
+ /* Need to parse autoneg_advertised and set up
+ * the appropriate PHY registers. First we will parse for
+ * autoneg_advertised software override. Since we can advertise
+ * a plethora of combinations, we need to check each bit
+ * individually.
+ */
+
+ /* First we clear all the 10/100 mb speed bits in the Auto-Neg
+ * Advertisement Register (Address 4) and the 1000 mb speed bits in
+ * the 1000Base-T Control Register (Address 9). */
+ mii_autoneg_adv_reg &= ~MII_AR_SPEED_MASK;
+
+ /* Need to parse MediaType and setup the
+ * appropriate PHY registers. */
+ switch (hw->MediaType) {
+ case MEDIA_TYPE_AUTO_SENSOR:
+ mii_autoneg_adv_reg |=
+ (MII_AR_10T_HD_CAPS |
+ MII_AR_10T_FD_CAPS |
+ MII_AR_100TX_HD_CAPS|
+ MII_AR_100TX_FD_CAPS);
+ hw->autoneg_advertised =
+ ADVERTISE_10_HALF |
+ ADVERTISE_10_FULL |
+ ADVERTISE_100_HALF|
+ ADVERTISE_100_FULL;
+ break;
+ case MEDIA_TYPE_100M_FULL:
+ mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS;
+ hw->autoneg_advertised = ADVERTISE_100_FULL;
+ break;
+ case MEDIA_TYPE_100M_HALF:
+ mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS;
+ hw->autoneg_advertised = ADVERTISE_100_HALF;
+ break;
+ case MEDIA_TYPE_10M_FULL:
+ mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS;
+ hw->autoneg_advertised = ADVERTISE_10_FULL;
+ break;
+ default:
+ mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS;
+ hw->autoneg_advertised = ADVERTISE_10_HALF;
+ break;
+ }
+
+ /* flow control fixed to enable all */
+ mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE);
+
+ hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg;
+
+ ret_val = atl2_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg);
+
+ if (ret_val)
+ return ret_val;
+
+ return 0;
+}
+
+/*
+ * Resets the PHY and make all config validate
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sets bit 15 and 12 of the MII Control regiser (for F001 bug)
+ */
+static s32 atl2_phy_commit(struct atl2_hw *hw)
+{
+ s32 ret_val;
+ u16 phy_data;
+
+ phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG;
+ ret_val = atl2_write_phy_reg(hw, MII_BMCR, phy_data);
+ if (ret_val) {
+ u32 val;
+ int i;
+ /* pcie serdes link may be down ! */
+ for (i = 0; i < 25; i++) {
+ msleep(1);
+ val = ATL2_READ_REG(hw, REG_MDIO_CTRL);
+ if (!(val & (MDIO_START | MDIO_BUSY)))
+ break;
+ }
+
+ if (0 != (val & (MDIO_START | MDIO_BUSY))) {
+ printk(KERN_ERR "atl2: PCIe link down for at least 25ms !\n");
+ return ret_val;
+ }
+ }
+ return 0;
+}
+
+static s32 atl2_phy_init(struct atl2_hw *hw)
+{
+ s32 ret_val;
+ u16 phy_val;
+
+ if (hw->phy_configured)
+ return 0;
+
+ /* Enable PHY */
+ ATL2_WRITE_REGW(hw, REG_PHY_ENABLE, 1);
+ ATL2_WRITE_FLUSH(hw);
+ msleep(1);
+
+ /* check if the PHY is in powersaving mode */
+ atl2_write_phy_reg(hw, MII_DBG_ADDR, 0);
+ atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val);
+
+ /* 024E / 124E 0r 0274 / 1274 ? */
+ if (phy_val & 0x1000) {
+ phy_val &= ~0x1000;
+ atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val);
+ }
+
+ msleep(1);
+
+ /*Enable PHY LinkChange Interrupt */
+ ret_val = atl2_write_phy_reg(hw, 18, 0xC00);
+ if (ret_val)
+ return ret_val;
+
+ /* setup AutoNeg parameters */
+ ret_val = atl2_phy_setup_autoneg_adv(hw);
+ if (ret_val)
+ return ret_val;
+
+ /* SW.Reset & En-Auto-Neg to restart Auto-Neg */
+ ret_val = atl2_phy_commit(hw);
+ if (ret_val)
+ return ret_val;
+
+ hw->phy_configured = true;
+
+ return ret_val;
+}
+
+static void atl2_set_mac_addr(struct atl2_hw *hw)
+{
+ u32 value;
+ /* 00-0B-6A-F6-00-DC
+ * 0: 6AF600DC 1: 000B
+ * low dword */
+ value = (((u32)hw->mac_addr[2]) << 24) |
+ (((u32)hw->mac_addr[3]) << 16) |
+ (((u32)hw->mac_addr[4]) << 8) |
+ (((u32)hw->mac_addr[5]));
+ ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
+ /* hight dword */
+ value = (((u32)hw->mac_addr[0]) << 8) |
+ (((u32)hw->mac_addr[1]));
+ ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
+}
+
+/*
+ * check_eeprom_exist
+ * return 0 if eeprom exist
+ */
+static int atl2_check_eeprom_exist(struct atl2_hw *hw)
+{
+ u32 value;
+
+ value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL);
+ if (value & SPI_FLASH_CTRL_EN_VPD) {
+ value &= ~SPI_FLASH_CTRL_EN_VPD;
+ ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value);
+ }
+ value = ATL2_READ_REGW(hw, REG_PCIE_CAP_LIST);
+ return ((value & 0xFF00) == 0x6C00) ? 0 : 1;
+}
+
+/* FIXME: This doesn't look right. -- CHS */
+static bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value)
+{
+ return true;
+}
+
+static bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue)
+{
+ int i;
+ u32 Control;
+
+ if (Offset & 0x3)
+ return false; /* address do not align */
+
+ ATL2_WRITE_REG(hw, REG_VPD_DATA, 0);
+ Control = (Offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT;
+ ATL2_WRITE_REG(hw, REG_VPD_CAP, Control);
+
+ for (i = 0; i < 10; i++) {
+ msleep(2);
+ Control = ATL2_READ_REG(hw, REG_VPD_CAP);
+ if (Control & VPD_CAP_VPD_FLAG)
+ break;
+ }
+
+ if (Control & VPD_CAP_VPD_FLAG) {
+ *pValue = ATL2_READ_REG(hw, REG_VPD_DATA);
+ return true;
+ }
+ return false; /* timeout */
+}
+
+static void atl2_force_ps(struct atl2_hw *hw)
+{
+ u16 phy_val;
+
+ atl2_write_phy_reg(hw, MII_DBG_ADDR, 0);
+ atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val);
+ atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val | 0x1000);
+
+ atl2_write_phy_reg(hw, MII_DBG_ADDR, 2);
+ atl2_write_phy_reg(hw, MII_DBG_DATA, 0x3000);
+ atl2_write_phy_reg(hw, MII_DBG_ADDR, 3);
+ atl2_write_phy_reg(hw, MII_DBG_DATA, 0);
+}
+
+/* This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+#define ATL2_MAX_NIC 4
+
+#define OPTION_UNSET -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED 1
+
+/* All parameters are treated the same, as an integer array of values.
+ * This macro just reduces the need to repeat the same declaration code
+ * over and over (plus this helps to avoid typo bugs).
+ */
+#define ATL2_PARAM_INIT {[0 ... ATL2_MAX_NIC] = OPTION_UNSET}
+#ifndef module_param_array
+/* Module Parameters are always initialized to -1, so that the driver
+ * can tell the difference between no user specified value or the
+ * user asking for the default value.
+ * The true default values are loaded in when atl2_check_options is called.
+ *
+ * This is a GCC extension to ANSI C.
+ * See the item "Labeled Elements in Initializers" in the section
+ * "Extensions to the C Language Family" of the GCC documentation.
+ */
+
+#define ATL2_PARAM(X, desc) \
+ static const int X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \
+ MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \
+ MODULE_PARM_DESC(X, desc);
+#else
+#define ATL2_PARAM(X, desc) \
+ static int X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \
+ static unsigned int num_##X; \
+ module_param_array_named(X, X, int, &num_##X, 0); \
+ MODULE_PARM_DESC(X, desc);
+#endif
+
+/*
+ * Transmit Memory Size
+ * Valid Range: 64-2048
+ * Default Value: 128
+ */
+#define ATL2_MIN_TX_MEMSIZE 4 /* 4KB */
+#define ATL2_MAX_TX_MEMSIZE 64 /* 64KB */
+#define ATL2_DEFAULT_TX_MEMSIZE 8 /* 8KB */
+ATL2_PARAM(TxMemSize, "Bytes of Transmit Memory");
+
+/*
+ * Receive Memory Block Count
+ * Valid Range: 16-512
+ * Default Value: 128
+ */
+#define ATL2_MIN_RXD_COUNT 16
+#define ATL2_MAX_RXD_COUNT 512
+#define ATL2_DEFAULT_RXD_COUNT 64
+ATL2_PARAM(RxMemBlock, "Number of receive memory block");
+
+/*
+ * User Specified MediaType Override
+ *
+ * Valid Range: 0-5
+ * - 0 - auto-negotiate at all supported speeds
+ * - 1 - only link at 1000Mbps Full Duplex
+ * - 2 - only link at 100Mbps Full Duplex
+ * - 3 - only link at 100Mbps Half Duplex
+ * - 4 - only link at 10Mbps Full Duplex
+ * - 5 - only link at 10Mbps Half Duplex
+ * Default Value: 0
+ */
+ATL2_PARAM(MediaType, "MediaType Select");
+
+/*
+ * Interrupt Moderate Timer in units of 2048 ns (~2 us)
+ * Valid Range: 10-65535
+ * Default Value: 45000(90ms)
+ */
+#define INT_MOD_DEFAULT_CNT 100 /* 200us */
+#define INT_MOD_MAX_CNT 65000
+#define INT_MOD_MIN_CNT 50
+ATL2_PARAM(IntModTimer, "Interrupt Moderator Timer");
+
+/*
+ * FlashVendor
+ * Valid Range: 0-2
+ * 0 - Atmel
+ * 1 - SST
+ * 2 - ST
+ */
+ATL2_PARAM(FlashVendor, "SPI Flash Vendor");
+
+#define AUTONEG_ADV_DEFAULT 0x2F
+#define AUTONEG_ADV_MASK 0x2F
+#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
+
+#define FLASH_VENDOR_DEFAULT 0
+#define FLASH_VENDOR_MIN 0
+#define FLASH_VENDOR_MAX 2
+
+struct atl2_option {
+ enum { enable_option, range_option, list_option } type;
+ char *name;
+ char *err;
+ int def;
+ union {
+ struct { /* range_option info */
+ int min;
+ int max;
+ } r;
+ struct { /* list_option info */
+ int nr;
+ struct atl2_opt_list { int i; char *str; } *p;
+ } l;
+ } arg;
+};
+
+static int atl2_validate_option(int *value, struct atl2_option *opt)
+{
+ int i;
+ struct atl2_opt_list *ent;
+
+ if (*value == OPTION_UNSET) {
+ *value = opt->def;
+ return 0;
+ }
+
+ switch (opt->type) {
+ case enable_option:
+ switch (*value) {
+ case OPTION_ENABLED:
+ printk(KERN_INFO "%s Enabled\n", opt->name);
+ return 0;
+ break;
+ case OPTION_DISABLED:
+ printk(KERN_INFO "%s Disabled\n", opt->name);
+ return 0;
+ break;
+ }
+ break;
+ case range_option:
+ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+ printk(KERN_INFO "%s set to %i\n", opt->name, *value);
+ return 0;
+ }
+ break;
+ case list_option:
+ for (i = 0; i < opt->arg.l.nr; i++) {
+ ent = &opt->arg.l.p[i];
+ if (*value == ent->i) {
+ if (ent->str[0] != '\0')
+ printk(KERN_INFO "%s\n", ent->str);
+ return 0;
+ }
+ }
+ break;
+ default:
+ BUG();
+ }
+
+ printk(KERN_INFO "Invalid %s specified (%i) %s\n",
+ opt->name, *value, opt->err);
+ *value = opt->def;
+ return -1;
+}
+
+/**
+ * atl2_check_options - Range Checking for Command Line Parameters
+ * @adapter: board private structure
+ *
+ * This routine checks all command line parameters for valid user
+ * input. If an invalid value is given, or if no user specified
+ * value exists, a default value is used. The final value is stored
+ * in a variable in the adapter structure.
+ */
+static void atl2_check_options(struct atl2_adapter *adapter)
+{
+ int val;
+ struct atl2_option opt;
+ int bd = adapter->bd_number;
+ if (bd >= ATL2_MAX_NIC) {
+ printk(KERN_NOTICE "Warning: no configuration for board #%i\n",
+ bd);
+ printk(KERN_NOTICE "Using defaults for all values\n");
+#ifndef module_param_array
+ bd = ATL2_MAX_NIC;
+#endif
+ }
+
+ /* Bytes of Transmit Memory */
+ opt.type = range_option;
+ opt.name = "Bytes of Transmit Memory";
+ opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_TX_MEMSIZE);
+ opt.def = ATL2_DEFAULT_TX_MEMSIZE;
+ opt.arg.r.min = ATL2_MIN_TX_MEMSIZE;
+ opt.arg.r.max = ATL2_MAX_TX_MEMSIZE;
+#ifdef module_param_array
+ if (num_TxMemSize > bd) {
+#endif
+ val = TxMemSize[bd];
+ atl2_validate_option(&val, &opt);
+ adapter->txd_ring_size = ((u32) val) * 1024;
+#ifdef module_param_array
+ } else
+ adapter->txd_ring_size = ((u32)opt.def) * 1024;
+#endif
+ /* txs ring size: */
+ adapter->txs_ring_size = adapter->txd_ring_size / 128;
+ if (adapter->txs_ring_size > 160)
+ adapter->txs_ring_size = 160;
+
+ /* Receive Memory Block Count */
+ opt.type = range_option;
+ opt.name = "Number of receive memory block";
+ opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_RXD_COUNT);
+ opt.def = ATL2_DEFAULT_RXD_COUNT;
+ opt.arg.r.min = ATL2_MIN_RXD_COUNT;
+ opt.arg.r.max = ATL2_MAX_RXD_COUNT;
+#ifdef module_param_array
+ if (num_RxMemBlock > bd) {
+#endif
+ val = RxMemBlock[bd];
+ atl2_validate_option(&val, &opt);
+ adapter->rxd_ring_size = (u32)val;
+ /* FIXME */
+ /* ((u16)val)&~1; */ /* even number */
+#ifdef module_param_array
+ } else
+ adapter->rxd_ring_size = (u32)opt.def;
+#endif
+ /* init RXD Flow control value */
+ adapter->hw.fc_rxd_hi = (adapter->rxd_ring_size / 8) * 7;
+ adapter->hw.fc_rxd_lo = (ATL2_MIN_RXD_COUNT / 8) >
+ (adapter->rxd_ring_size / 12) ? (ATL2_MIN_RXD_COUNT / 8) :
+ (adapter->rxd_ring_size / 12);
+
+ /* Interrupt Moderate Timer */
+ opt.type = range_option;
+ opt.name = "Interrupt Moderate Timer";
+ opt.err = "using default of " __MODULE_STRING(INT_MOD_DEFAULT_CNT);
+ opt.def = INT_MOD_DEFAULT_CNT;
+ opt.arg.r.min = INT_MOD_MIN_CNT;
+ opt.arg.r.max = INT_MOD_MAX_CNT;
+#ifdef module_param_array
+ if (num_IntModTimer > bd) {
+#endif
+ val = IntModTimer[bd];
+ atl2_validate_option(&val, &opt);
+ adapter->imt = (u16) val;
+#ifdef module_param_array
+ } else
+ adapter->imt = (u16)(opt.def);
+#endif
+ /* Flash Vendor */
+ opt.type = range_option;
+ opt.name = "SPI Flash Vendor";
+ opt.err = "using default of " __MODULE_STRING(FLASH_VENDOR_DEFAULT);
+ opt.def = FLASH_VENDOR_DEFAULT;
+ opt.arg.r.min = FLASH_VENDOR_MIN;
+ opt.arg.r.max = FLASH_VENDOR_MAX;
+#ifdef module_param_array
+ if (num_FlashVendor > bd) {
+#endif
+ val = FlashVendor[bd];
+ atl2_validate_option(&val, &opt);
+ adapter->hw.flash_vendor = (u8) val;
+#ifdef module_param_array
+ } else
+ adapter->hw.flash_vendor = (u8)(opt.def);
+#endif
+ /* MediaType */
+ opt.type = range_option;
+ opt.name = "Speed/Duplex Selection";
+ opt.err = "using default of " __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR);
+ opt.def = MEDIA_TYPE_AUTO_SENSOR;
+ opt.arg.r.min = MEDIA_TYPE_AUTO_SENSOR;
+ opt.arg.r.max = MEDIA_TYPE_10M_HALF;
+#ifdef module_param_array
+ if (num_MediaType > bd) {
+#endif
+ val = MediaType[bd];
+ atl2_validate_option(&val, &opt);
+ adapter->hw.MediaType = (u16) val;
+#ifdef module_param_array
+ } else
+ adapter->hw.MediaType = (u16)(opt.def);
+#endif
+}
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.h b/drivers/net/ethernet/atheros/atlx/atl2.h
new file mode 100644
index 00000000000..2f27d4c4c3a
--- /dev/null
+++ b/drivers/net/ethernet/atheros/atlx/atl2.h
@@ -0,0 +1,524 @@
+/* atl2.h -- atl2 driver definitions
+ *
+ * Copyright(c) 2007 Atheros Corporation. All rights reserved.
+ * Copyright(c) 2006 xiong huang <xiong.huang@atheros.com>
+ * Copyright(c) 2007 Chris Snook <csnook@redhat.com>
+ *
+ * Derived from Intel e1000 driver
+ * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ATL2_H_
+#define _ATL2_H_
+
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+
+#ifndef _ATL2_HW_H_
+#define _ATL2_HW_H_
+
+#ifndef _ATL2_OSDEP_H_
+#define _ATL2_OSDEP_H_
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+
+#include "atlx.h"
+
+#ifdef ETHTOOL_OPS_COMPAT
+int ethtool_ioctl(struct ifreq *ifr);
+#endif
+
+#define PCI_COMMAND_REGISTER PCI_COMMAND
+#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
+
+#define ATL2_WRITE_REG(a, reg, value) (iowrite32((value), \
+ ((a)->hw_addr + (reg))))
+
+#define ATL2_WRITE_FLUSH(a) (ioread32((a)->hw_addr))
+
+#define ATL2_READ_REG(a, reg) (ioread32((a)->hw_addr + (reg)))
+
+#define ATL2_WRITE_REGB(a, reg, value) (iowrite8((value), \
+ ((a)->hw_addr + (reg))))
+
+#define ATL2_READ_REGB(a, reg) (ioread8((a)->hw_addr + (reg)))
+
+#define ATL2_WRITE_REGW(a, reg, value) (iowrite16((value), \
+ ((a)->hw_addr + (reg))))
+
+#define ATL2_READ_REGW(a, reg) (ioread16((a)->hw_addr + (reg)))
+
+#define ATL2_WRITE_REG_ARRAY(a, reg, offset, value) \
+ (iowrite32((value), (((a)->hw_addr + (reg)) + ((offset) << 2))))
+
+#define ATL2_READ_REG_ARRAY(a, reg, offset) \
+ (ioread32(((a)->hw_addr + (reg)) + ((offset) << 2)))
+
+#endif /* _ATL2_OSDEP_H_ */
+
+struct atl2_adapter;
+struct atl2_hw;
+
+/* function prototype */
+static s32 atl2_reset_hw(struct atl2_hw *hw);
+static s32 atl2_read_mac_addr(struct atl2_hw *hw);
+static s32 atl2_init_hw(struct atl2_hw *hw);
+static s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed,
+ u16 *duplex);
+static u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr);
+static void atl2_hash_set(struct atl2_hw *hw, u32 hash_value);
+static s32 atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data);
+static s32 atl2_write_phy_reg(struct atl2_hw *hw, u32 reg_addr, u16 phy_data);
+static void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value);
+static void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value);
+static void atl2_set_mac_addr(struct atl2_hw *hw);
+static bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue);
+static bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value);
+static s32 atl2_phy_init(struct atl2_hw *hw);
+static int atl2_check_eeprom_exist(struct atl2_hw *hw);
+static void atl2_force_ps(struct atl2_hw *hw);
+
+/* register definition */
+
+/* Block IDLE Status Register */
+#define IDLE_STATUS_RXMAC 1 /* 1: RXMAC is non-IDLE */
+#define IDLE_STATUS_TXMAC 2 /* 1: TXMAC is non-IDLE */
+#define IDLE_STATUS_DMAR 8 /* 1: DMAR is non-IDLE */
+#define IDLE_STATUS_DMAW 4 /* 1: DMAW is non-IDLE */
+
+/* MDIO Control Register */
+#define MDIO_WAIT_TIMES 10
+
+/* MAC Control Register */
+#define MAC_CTRL_DBG_TX_BKPRESURE 0x100000 /* 1: TX max backoff */
+#define MAC_CTRL_MACLP_CLK_PHY 0x8000000 /* 1: 25MHz from phy */
+#define MAC_CTRL_HALF_LEFT_BUF_SHIFT 28
+#define MAC_CTRL_HALF_LEFT_BUF_MASK 0xF /* MAC retry buf x32B */
+
+/* Internal SRAM Partition Register */
+#define REG_SRAM_TXRAM_END 0x1500 /* Internal tail address of TXRAM
+ * default: 2byte*1024 */
+#define REG_SRAM_RXRAM_END 0x1502 /* Internal tail address of RXRAM
+ * default: 2byte*1024 */
+
+/* Descriptor Control register */
+#define REG_TXD_BASE_ADDR_LO 0x1544 /* The base address of the Transmit
+ * Data Mem low 32-bit(dword align) */
+#define REG_TXD_MEM_SIZE 0x1548 /* Transmit Data Memory size(by
+ * double word , max 256KB) */
+#define REG_TXS_BASE_ADDR_LO 0x154C /* The base address of the Transmit
+ * Status Memory low 32-bit(dword word
+ * align) */
+#define REG_TXS_MEM_SIZE 0x1550 /* double word unit, max 4*2047
+ * bytes. */
+#define REG_RXD_BASE_ADDR_LO 0x1554 /* The base address of the Transmit
+ * Status Memory low 32-bit(unit 8
+ * bytes) */
+#define REG_RXD_BUF_NUM 0x1558 /* Receive Data & Status Memory buffer
+ * number (unit 1536bytes, max
+ * 1536*2047) */
+
+/* DMAR Control Register */
+#define REG_DMAR 0x1580
+#define DMAR_EN 0x1 /* 1: Enable DMAR */
+
+/* TX Cur-Through (early tx threshold) Control Register */
+#define REG_TX_CUT_THRESH 0x1590 /* TxMac begin transmit packet
+ * threshold(unit word) */
+
+/* DMAW Control Register */
+#define REG_DMAW 0x15A0
+#define DMAW_EN 0x1
+
+/* Flow control register */
+#define REG_PAUSE_ON_TH 0x15A8 /* RXD high watermark of overflow
+ * threshold configuration register */
+#define REG_PAUSE_OFF_TH 0x15AA /* RXD lower watermark of overflow
+ * threshold configuration register */
+
+/* Mailbox Register */
+#define REG_MB_TXD_WR_IDX 0x15f0 /* double word align */
+#define REG_MB_RXD_RD_IDX 0x15F4 /* RXD Read index (unit: 1536byets) */
+
+/* Interrupt Status Register */
+#define ISR_TIMER 1 /* Interrupt when Timer counts down to zero */
+#define ISR_MANUAL 2 /* Software manual interrupt, for debug. Set
+ * when SW_MAN_INT_EN is set in Table 51
+ * Selene Master Control Register
+ * (Offset 0x1400). */
+#define ISR_RXF_OV 4 /* RXF overflow interrupt */
+#define ISR_TXF_UR 8 /* TXF underrun interrupt */
+#define ISR_TXS_OV 0x10 /* Internal transmit status buffer full
+ * interrupt */
+#define ISR_RXS_OV 0x20 /* Internal receive status buffer full
+ * interrupt */
+#define ISR_LINK_CHG 0x40 /* Link Status Change Interrupt */
+#define ISR_HOST_TXD_UR 0x80
+#define ISR_HOST_RXD_OV 0x100 /* Host rx data memory full , one pulse */
+#define ISR_DMAR_TO_RST 0x200 /* DMAR op timeout interrupt. SW should
+ * do Reset */
+#define ISR_DMAW_TO_RST 0x400
+#define ISR_PHY 0x800 /* phy interrupt */
+#define ISR_TS_UPDATE 0x10000 /* interrupt after new tx pkt status written
+ * to host */
+#define ISR_RS_UPDATE 0x20000 /* interrupt ater new rx pkt status written
+ * to host. */
+#define ISR_TX_EARLY 0x40000 /* interrupt when txmac begin transmit one
+ * packet */
+
+#define ISR_TX_EVENT (ISR_TXF_UR | ISR_TXS_OV | ISR_HOST_TXD_UR |\
+ ISR_TS_UPDATE | ISR_TX_EARLY)
+#define ISR_RX_EVENT (ISR_RXF_OV | ISR_RXS_OV | ISR_HOST_RXD_OV |\
+ ISR_RS_UPDATE)
+
+#define IMR_NORMAL_MASK (\
+ /*ISR_LINK_CHG |*/\
+ ISR_MANUAL |\
+ ISR_DMAR_TO_RST |\
+ ISR_DMAW_TO_RST |\
+ ISR_PHY |\
+ ISR_PHY_LINKDOWN |\
+ ISR_TS_UPDATE |\
+ ISR_RS_UPDATE)
+
+/* Receive MAC Statistics Registers */
+#define REG_STS_RX_PAUSE 0x1700 /* Num pause packets received */
+#define REG_STS_RXD_OV 0x1704 /* Num frames dropped due to RX
+ * FIFO overflow */
+#define REG_STS_RXS_OV 0x1708 /* Num frames dropped due to RX
+ * Status Buffer Overflow */
+#define REG_STS_RX_FILTER 0x170C /* Num packets dropped due to
+ * address filtering */
+
+/* MII definitions */
+
+/* PHY Common Register */
+#define MII_SMARTSPEED 0x14
+#define MII_DBG_ADDR 0x1D
+#define MII_DBG_DATA 0x1E
+
+/* PCI Command Register Bit Definitions */
+#define PCI_REG_COMMAND 0x04
+#define CMD_IO_SPACE 0x0001
+#define CMD_MEMORY_SPACE 0x0002
+#define CMD_BUS_MASTER 0x0004
+
+#define MEDIA_TYPE_100M_FULL 1
+#define MEDIA_TYPE_100M_HALF 2
+#define MEDIA_TYPE_10M_FULL 3
+#define MEDIA_TYPE_10M_HALF 4
+
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x000F /* Everything */
+
+/* The size (in bytes) of a ethernet packet */
+#define ENET_HEADER_SIZE 14
+#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* with FCS */
+#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* with FCS */
+#define ETHERNET_FCS_SIZE 4
+#define MAX_JUMBO_FRAME_SIZE 0x2000
+#define VLAN_SIZE 4
+
+struct tx_pkt_header {
+ unsigned pkt_size:11;
+ unsigned:4; /* reserved */
+ unsigned ins_vlan:1; /* txmac should insert vlan */
+ unsigned short vlan; /* vlan tag */
+};
+/* FIXME: replace above bitfields with MASK/SHIFT defines below */
+#define TX_PKT_HEADER_SIZE_MASK 0x7FF
+#define TX_PKT_HEADER_SIZE_SHIFT 0
+#define TX_PKT_HEADER_INS_VLAN_MASK 0x1
+#define TX_PKT_HEADER_INS_VLAN_SHIFT 15
+#define TX_PKT_HEADER_VLAN_TAG_MASK 0xFFFF
+#define TX_PKT_HEADER_VLAN_TAG_SHIFT 16
+
+struct tx_pkt_status {
+ unsigned pkt_size:11;
+ unsigned:5; /* reserved */
+ unsigned ok:1; /* current packet transmitted without error */
+ unsigned bcast:1; /* broadcast packet */
+ unsigned mcast:1; /* multicast packet */
+ unsigned pause:1; /* transmiited a pause frame */
+ unsigned ctrl:1;
+ unsigned defer:1; /* current packet is xmitted with defer */
+ unsigned exc_defer:1;
+ unsigned single_col:1;
+ unsigned multi_col:1;
+ unsigned late_col:1;
+ unsigned abort_col:1;
+ unsigned underun:1; /* current packet is aborted
+ * due to txram underrun */
+ unsigned:3; /* reserved */
+ unsigned update:1; /* always 1'b1 in tx_status_buf */
+};
+/* FIXME: replace above bitfields with MASK/SHIFT defines below */
+#define TX_PKT_STATUS_SIZE_MASK 0x7FF
+#define TX_PKT_STATUS_SIZE_SHIFT 0
+#define TX_PKT_STATUS_OK_MASK 0x1
+#define TX_PKT_STATUS_OK_SHIFT 16
+#define TX_PKT_STATUS_BCAST_MASK 0x1
+#define TX_PKT_STATUS_BCAST_SHIFT 17
+#define TX_PKT_STATUS_MCAST_MASK 0x1
+#define TX_PKT_STATUS_MCAST_SHIFT 18
+#define TX_PKT_STATUS_PAUSE_MASK 0x1
+#define TX_PKT_STATUS_PAUSE_SHIFT 19
+#define TX_PKT_STATUS_CTRL_MASK 0x1
+#define TX_PKT_STATUS_CTRL_SHIFT 20
+#define TX_PKT_STATUS_DEFER_MASK 0x1
+#define TX_PKT_STATUS_DEFER_SHIFT 21
+#define TX_PKT_STATUS_EXC_DEFER_MASK 0x1
+#define TX_PKT_STATUS_EXC_DEFER_SHIFT 22
+#define TX_PKT_STATUS_SINGLE_COL_MASK 0x1
+#define TX_PKT_STATUS_SINGLE_COL_SHIFT 23
+#define TX_PKT_STATUS_MULTI_COL_MASK 0x1
+#define TX_PKT_STATUS_MULTI_COL_SHIFT 24
+#define TX_PKT_STATUS_LATE_COL_MASK 0x1
+#define TX_PKT_STATUS_LATE_COL_SHIFT 25
+#define TX_PKT_STATUS_ABORT_COL_MASK 0x1
+#define TX_PKT_STATUS_ABORT_COL_SHIFT 26
+#define TX_PKT_STATUS_UNDERRUN_MASK 0x1
+#define TX_PKT_STATUS_UNDERRUN_SHIFT 27
+#define TX_PKT_STATUS_UPDATE_MASK 0x1
+#define TX_PKT_STATUS_UPDATE_SHIFT 31
+
+struct rx_pkt_status {
+ unsigned pkt_size:11; /* packet size, max 2047 bytes */
+ unsigned:5; /* reserved */
+ unsigned ok:1; /* current packet received ok without error */
+ unsigned bcast:1; /* current packet is broadcast */
+ unsigned mcast:1; /* current packet is multicast */
+ unsigned pause:1;
+ unsigned ctrl:1;
+ unsigned crc:1; /* received a packet with crc error */
+ unsigned code:1; /* received a packet with code error */
+ unsigned runt:1; /* received a packet less than 64 bytes
+ * with good crc */
+ unsigned frag:1; /* received a packet less than 64 bytes
+ * with bad crc */
+ unsigned trunc:1; /* current frame truncated due to rxram full */
+ unsigned align:1; /* this packet is alignment error */
+ unsigned vlan:1; /* this packet has vlan */
+ unsigned:3; /* reserved */
+ unsigned update:1;
+ unsigned short vtag; /* vlan tag */
+ unsigned:16;
+};
+/* FIXME: replace above bitfields with MASK/SHIFT defines below */
+#define RX_PKT_STATUS_SIZE_MASK 0x7FF
+#define RX_PKT_STATUS_SIZE_SHIFT 0
+#define RX_PKT_STATUS_OK_MASK 0x1
+#define RX_PKT_STATUS_OK_SHIFT 16
+#define RX_PKT_STATUS_BCAST_MASK 0x1
+#define RX_PKT_STATUS_BCAST_SHIFT 17
+#define RX_PKT_STATUS_MCAST_MASK 0x1
+#define RX_PKT_STATUS_MCAST_SHIFT 18
+#define RX_PKT_STATUS_PAUSE_MASK 0x1
+#define RX_PKT_STATUS_PAUSE_SHIFT 19
+#define RX_PKT_STATUS_CTRL_MASK 0x1
+#define RX_PKT_STATUS_CTRL_SHIFT 20
+#define RX_PKT_STATUS_CRC_MASK 0x1
+#define RX_PKT_STATUS_CRC_SHIFT 21
+#define RX_PKT_STATUS_CODE_MASK 0x1
+#define RX_PKT_STATUS_CODE_SHIFT 22
+#define RX_PKT_STATUS_RUNT_MASK 0x1
+#define RX_PKT_STATUS_RUNT_SHIFT 23
+#define RX_PKT_STATUS_FRAG_MASK 0x1
+#define RX_PKT_STATUS_FRAG_SHIFT 24
+#define RX_PKT_STATUS_TRUNK_MASK 0x1
+#define RX_PKT_STATUS_TRUNK_SHIFT 25
+#define RX_PKT_STATUS_ALIGN_MASK 0x1
+#define RX_PKT_STATUS_ALIGN_SHIFT 26
+#define RX_PKT_STATUS_VLAN_MASK 0x1
+#define RX_PKT_STATUS_VLAN_SHIFT 27
+#define RX_PKT_STATUS_UPDATE_MASK 0x1
+#define RX_PKT_STATUS_UPDATE_SHIFT 31
+#define RX_PKT_STATUS_VLAN_TAG_MASK 0xFFFF
+#define RX_PKT_STATUS_VLAN_TAG_SHIFT 32
+
+struct rx_desc {
+ struct rx_pkt_status status;
+ unsigned char packet[1536-sizeof(struct rx_pkt_status)];
+};
+
+enum atl2_speed_duplex {
+ atl2_10_half = 0,
+ atl2_10_full = 1,
+ atl2_100_half = 2,
+ atl2_100_full = 3
+};
+
+struct atl2_spi_flash_dev {
+ const char *manu_name; /* manufacturer id */
+ /* op-code */
+ u8 cmdWRSR;
+ u8 cmdREAD;
+ u8 cmdPROGRAM;
+ u8 cmdWREN;
+ u8 cmdWRDI;
+ u8 cmdRDSR;
+ u8 cmdRDID;
+ u8 cmdSECTOR_ERASE;
+ u8 cmdCHIP_ERASE;
+};
+
+/* Structure containing variables used by the shared code (atl2_hw.c) */
+struct atl2_hw {
+ u8 __iomem *hw_addr;
+ void *back;
+
+ u8 preamble_len;
+ u8 max_retry; /* Retransmission maximum, afterwards the
+ * packet will be discarded. */
+ u8 jam_ipg; /* IPG to start JAM for collision based flow
+ * control in half-duplex mode. In unit of
+ * 8-bit time. */
+ u8 ipgt; /* Desired back to back inter-packet gap. The
+ * default is 96-bit time. */
+ u8 min_ifg; /* Minimum number of IFG to enforce in between
+ * RX frames. Frame gap below such IFP is
+ * dropped. */
+ u8 ipgr1; /* 64bit Carrier-Sense window */
+ u8 ipgr2; /* 96-bit IPG window */
+ u8 retry_buf; /* When half-duplex mode, should hold some
+ * bytes for mac retry . (8*4bytes unit) */
+
+ u16 fc_rxd_hi;
+ u16 fc_rxd_lo;
+ u16 lcol; /* Collision Window */
+ u16 max_frame_size;
+
+ u16 MediaType;
+ u16 autoneg_advertised;
+ u16 pci_cmd_word;
+
+ u16 mii_autoneg_adv_reg;
+
+ u32 mem_rang;
+ u32 txcw;
+ u32 mc_filter_type;
+ u32 num_mc_addrs;
+ u32 collision_delta;
+ u32 tx_packet_delta;
+ u16 phy_spd_default;
+
+ u16 device_id;
+ u16 vendor_id;
+ u16 subsystem_id;
+ u16 subsystem_vendor_id;
+ u8 revision_id;
+
+ /* spi flash */
+ u8 flash_vendor;
+
+ u8 dma_fairness;
+ u8 mac_addr[ETH_ALEN];
+ u8 perm_mac_addr[ETH_ALEN];
+
+ /* FIXME */
+ /* bool phy_preamble_sup; */
+ bool phy_configured;
+};
+
+#endif /* _ATL2_HW_H_ */
+
+struct atl2_ring_header {
+ /* pointer to the descriptor ring memory */
+ void *desc;
+ /* physical address of the descriptor ring */
+ dma_addr_t dma;
+ /* length of descriptor ring in bytes */
+ unsigned int size;
+};
+
+/* board specific private data structure */
+struct atl2_adapter {
+ /* OS defined structs */
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+ u32 wol;
+ u16 link_speed;
+ u16 link_duplex;
+
+ spinlock_t stats_lock;
+
+ struct work_struct reset_task;
+ struct work_struct link_chg_task;
+ struct timer_list watchdog_timer;
+ struct timer_list phy_config_timer;
+
+ unsigned long cfg_phy;
+ bool mac_disabled;
+
+ /* All Descriptor memory */
+ dma_addr_t ring_dma;
+ void *ring_vir_addr;
+ int ring_size;
+
+ struct tx_pkt_header *txd_ring;
+ dma_addr_t txd_dma;
+
+ struct tx_pkt_status *txs_ring;
+ dma_addr_t txs_dma;
+
+ struct rx_desc *rxd_ring;
+ dma_addr_t rxd_dma;
+
+ u32 txd_ring_size; /* bytes per unit */
+ u32 txs_ring_size; /* dwords per unit */
+ u32 rxd_ring_size; /* 1536 bytes per unit */
+
+ /* read /write ptr: */
+ /* host */
+ u32 txd_write_ptr;
+ u32 txs_next_clear;
+ u32 rxd_read_ptr;
+
+ /* nic */
+ atomic_t txd_read_ptr;
+ atomic_t txs_write_ptr;
+ u32 rxd_write_ptr;
+
+ /* Interrupt Moderator timer ( 2us resolution) */
+ u16 imt;
+ /* Interrupt Clear timer (2us resolution) */
+ u16 ict;
+
+ unsigned long flags;
+ /* structs defined in atl2_hw.h */
+ u32 bd_number; /* board number */
+ bool pci_using_64;
+ bool have_msi;
+ struct atl2_hw hw;
+
+ u32 usr_cmd;
+ /* FIXME */
+ /* u32 regs_buff[ATL2_REGS_LEN]; */
+ u32 pci_state[16];
+
+ u32 *config_space;
+};
+
+enum atl2_state_t {
+ __ATL2_TESTING,
+ __ATL2_RESETTING,
+ __ATL2_DOWN
+};
+
+#endif /* _ATL2_H_ */
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c
index b3e7fcf0f6e..46a622cceee 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/ethernet/atheros/atlx/atlx.c
@@ -41,6 +41,10 @@
#include "atlx.h"
+static s32 atlx_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data);
+static u32 atlx_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr);
+static void atlx_set_mac_addr(struct atl1_hw *hw);
+
static struct atlx_spi_flash_dev flash_table[] = {
/* MFR_NAME WRSR READ PRGM WREN WRDI RDSR RDID SEC_ERS CHIP_ERS */
{"Atmel", 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62},
@@ -60,7 +64,7 @@ static int atlx_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
}
-/*
+/**
* atlx_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure
* @p: pointer to an address structure
@@ -105,13 +109,12 @@ static void atlx_check_for_link(struct atlx_adapter *adapter)
netdev->name);
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
}
}
schedule_work(&adapter->link_chg_task);
}
-/*
+/**
* atlx_set_multi - Multicast and Promiscuous mode set
* @netdev: network interface device structure
*
@@ -124,7 +127,7 @@ static void atlx_set_multi(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
struct atlx_hw *hw = &adapter->hw;
- struct dev_mc_list *mc_ptr;
+ struct netdev_hw_addr *ha;
u32 rctl;
u32 hash_value;
@@ -145,30 +148,37 @@ static void atlx_set_multi(struct net_device *netdev)
iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
/* compute mc addresses' hash value ,and put it into hash table */
- for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
- hash_value = atlx_hash_mc_addr(hw, mc_ptr->dmi_addr);
+ netdev_for_each_mc_addr(ha, netdev) {
+ hash_value = atlx_hash_mc_addr(hw, ha->addr);
atlx_hash_set(hw, hash_value);
}
}
-/*
+static inline void atlx_imr_set(struct atlx_adapter *adapter,
+ unsigned int imr)
+{
+ iowrite32(imr, adapter->hw.hw_addr + REG_IMR);
+ ioread32(adapter->hw.hw_addr + REG_IMR);
+}
+
+/**
* atlx_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
*/
static void atlx_irq_enable(struct atlx_adapter *adapter)
{
- iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
- ioread32(adapter->hw.hw_addr + REG_IMR);
+ atlx_imr_set(adapter, IMR_NORMAL_MASK);
+ adapter->int_enabled = true;
}
-/*
+/**
* atlx_irq_disable - Mask off interrupt generation on the NIC
* @adapter: board private structure
*/
static void atlx_irq_disable(struct atlx_adapter *adapter)
{
- iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- ioread32(adapter->hw.hw_addr + REG_IMR);
+ adapter->int_enabled = false;
+ atlx_imr_set(adapter, 0);
synchronize_irq(adapter->pdev->irq);
}
@@ -182,20 +192,7 @@ static void atlx_clear_phy_int(struct atlx_adapter *adapter)
spin_unlock_irqrestore(&adapter->lock, flags);
}
-/*
- * atlx_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- */
-static struct net_device_stats *atlx_get_stats(struct net_device *netdev)
-{
- struct atlx_adapter *adapter = netdev_priv(netdev);
- return &adapter->net_stats;
-}
-
-/*
+/**
* atlx_tx_timeout - Respond to a Tx Hang
* @netdev: network interface device structure
*/
@@ -203,7 +200,7 @@ static void atlx_tx_timeout(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
/* Do the reset outside of interrupt context */
- schedule_work(&adapter->tx_timeout_task);
+ schedule_work(&adapter->reset_dev_task);
}
/*
@@ -221,8 +218,19 @@ static void atlx_link_chg_task(struct work_struct *work)
spin_unlock_irqrestore(&adapter->lock, flags);
}
-static void atlx_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
+static void __atlx_vlan_mode(netdev_features_t features, u32 *ctrl)
+{
+ if (features & NETIF_F_HW_VLAN_CTAG_RX) {
+ /* enable VLAN tag insert/strip */
+ *ctrl |= MAC_CTRL_RMV_VLAN;
+ } else {
+ /* disable VLAN tag insert/strip */
+ *ctrl &= ~MAC_CTRL_RMV_VLAN;
+ }
+}
+
+static void atlx_vlan_mode(struct net_device *netdev,
+ netdev_features_t features)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
unsigned long flags;
@@ -230,27 +238,42 @@ static void atlx_vlan_rx_register(struct net_device *netdev,
spin_lock_irqsave(&adapter->lock, flags);
/* atlx_irq_disable(adapter); FIXME: confirm/remove */
- adapter->vlgrp = grp;
-
- if (grp) {
- /* enable VLAN tag insert/strip */
- ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
- ctrl |= MAC_CTRL_RMV_VLAN;
- iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
- } else {
- /* disable VLAN tag insert/strip */
- ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
- ctrl &= ~MAC_CTRL_RMV_VLAN;
- iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
- }
-
+ ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
+ __atlx_vlan_mode(features, &ctrl);
+ iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
/* atlx_irq_enable(adapter); FIXME */
spin_unlock_irqrestore(&adapter->lock, flags);
}
static void atlx_restore_vlan(struct atlx_adapter *adapter)
{
- atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+ atlx_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+static netdev_features_t atlx_fix_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ /*
+ * Since there is no support for separate rx/tx vlan accel
+ * enable/disable make sure tx flag is always in same state as rx.
+ */
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ features |= NETIF_F_HW_VLAN_CTAG_TX;
+ else
+ features &= ~NETIF_F_HW_VLAN_CTAG_TX;
+
+ return features;
+}
+
+static int atlx_set_features(struct net_device *netdev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = netdev->features ^ features;
+
+ if (changed & NETIF_F_HW_VLAN_CTAG_RX)
+ atlx_vlan_mode(netdev, features);
+
+ return 0;
}
#endif /* ATLX_C */
diff --git a/drivers/net/atlx/atlx.h b/drivers/net/ethernet/atheros/atlx/atlx.h
index 297a03da6b7..448f5dcc02e 100644
--- a/drivers/net/atlx/atlx.h
+++ b/drivers/net/ethernet/atheros/atlx/atlx.h
@@ -29,12 +29,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#define ATLX_DRIVER_VERSION "2.1.3"
-MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
- Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ATLX_DRIVER_VERSION);
-
#define ATLX_ERR_PHY 2
#define ATLX_ERR_PHY_SPEED 7
#define ATLX_ERR_PHY_RES 8
@@ -490,7 +484,6 @@ MODULE_VERSION(ATLX_DRIVER_VERSION);
/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA */
#define EEPROM_SUM 0xBABA
-#define NODE_ADDRESS_SIZE 6
struct atlx_spi_flash_dev {
const char *manu_name; /* manufacturer id */
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
new file mode 100644
index 00000000000..3e488094b07
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -0,0 +1,164 @@
+#
+# Broadcom device configuration
+#
+
+config NET_VENDOR_BROADCOM
+ bool "Broadcom devices"
+ default y
+ depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \
+ SIBYTE_SB1xxx_SOC
+ ---help---
+ If you have a network (Ethernet) chipset belonging to this class,
+ say Y.
+
+ Note that the answer to this question does not directly affect
+ the kernel: saying N will just case the configurator to skip all
+ the questions regarding AMD chipsets. If you say Y, you will be asked
+ for your specific chipset/driver in the following questions.
+
+if NET_VENDOR_BROADCOM
+
+config B44
+ tristate "Broadcom 440x/47xx ethernet support"
+ depends on SSB_POSSIBLE && HAS_DMA
+ select SSB
+ select MII
+ select PHYLIB
+ ---help---
+ If you have a network (Ethernet) controller of this type, say Y
+ or M and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called b44.
+
+# Auto-select SSB PCI-HOST support, if possible
+config B44_PCI_AUTOSELECT
+ bool
+ depends on B44 && SSB_PCIHOST_POSSIBLE
+ select SSB_PCIHOST
+ default y
+
+# Auto-select SSB PCICORE driver, if possible
+config B44_PCICORE_AUTOSELECT
+ bool
+ depends on B44 && SSB_DRIVER_PCICORE_POSSIBLE
+ select SSB_DRIVER_PCICORE
+ default y
+
+config B44_PCI
+ bool
+ depends on B44_PCI_AUTOSELECT && B44_PCICORE_AUTOSELECT
+ default y
+
+config BCM63XX_ENET
+ tristate "Broadcom 63xx internal mac support"
+ depends on BCM63XX
+ select MII
+ select PHYLIB
+ help
+ This driver supports the ethernet MACs in the Broadcom 63xx
+ MIPS chipset family (BCM63XX).
+
+config BCMGENET
+ tristate "Broadcom GENET internal MAC support"
+ depends on OF
+ select MII
+ select PHYLIB
+ select FIXED_PHY if BCMGENET=y
+ select BCM7XXX_PHY
+ help
+ This driver supports the built-in Ethernet MACs found in the
+ Broadcom BCM7xxx Set Top Box family chipset.
+
+config BNX2
+ tristate "Broadcom NetXtremeII support"
+ depends on PCI
+ select CRC32
+ select FW_LOADER
+ ---help---
+ This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called bnx2. This is recommended.
+
+config CNIC
+ tristate "Broadcom CNIC support"
+ depends on PCI
+ select BNX2
+ select UIO
+ ---help---
+ This driver supports offload features of Broadcom NetXtremeII
+ gigabit Ethernet cards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called cnic. This is recommended.
+
+config SB1250_MAC
+ tristate "SB1250 Gigabit Ethernet support"
+ depends on SIBYTE_SB1xxx_SOC
+ select PHYLIB
+ ---help---
+ This driver supports Gigabit Ethernet interfaces based on the
+ Broadcom SiByte family of System-On-a-Chip parts. They include
+ the BCM1120, BCM1125, BCM1125H, BCM1250, BCM1255, BCM1280, BCM1455
+ and BCM1480 chips.
+
+ To compile this driver as a module, choose M here: the module
+ will be called sb1250-mac.
+
+config TIGON3
+ tristate "Broadcom Tigon3 support"
+ depends on PCI
+ select PHYLIB
+ select HWMON
+ select PTP_1588_CLOCK
+ ---help---
+ This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called tg3. This is recommended.
+
+config BNX2X
+ tristate "Broadcom NetXtremeII 10Gb support"
+ depends on PCI
+ select FW_LOADER
+ select ZLIB_INFLATE
+ select LIBCRC32C
+ select MDIO
+ ---help---
+ This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
+ To compile this driver as a module, choose M here: the module
+ will be called bnx2x. This is recommended.
+
+config BNX2X_SRIOV
+ bool "Broadcom 578xx and 57712 SR-IOV support"
+ depends on BNX2X && PCI_IOV
+ default y
+ ---help---
+ This configuration parameter enables Single Root Input Output
+ Virtualization support in the 578xx and 57712 products. This
+ allows for virtual function acceleration in virtual environments.
+
+config BGMAC
+ tristate "BCMA bus GBit core support"
+ depends on BCMA_HOST_SOC && HAS_DMA && BCM47XX
+ select PHYLIB
+ ---help---
+ This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
+ They can be found on BCM47xx SoCs and provide gigabit ethernet.
+ In case of using this driver on BCM4706 it's also requires to enable
+ BCMA_DRIVER_GMAC_CMN to make it work.
+
+config SYSTEMPORT
+ tristate "Broadcom SYSTEMPORT internal MAC support"
+ depends on OF
+ select MII
+ select PHYLIB
+ select FIXED_PHY if SYSTEMPORT=y
+ help
+ This driver supports the built-in Ethernet MACs found in the
+ Broadcom BCM7xxx Set Top Box family chipset using an internal
+ Ethernet switch.
+
+endif # NET_VENDOR_BROADCOM
diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile
new file mode 100644
index 00000000000..e2a958a657e
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the Broadcom network device drivers.
+#
+
+obj-$(CONFIG_B44) += b44.o
+obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
+obj-$(CONFIG_BCMGENET) += genet/
+obj-$(CONFIG_BNX2) += bnx2.o
+obj-$(CONFIG_CNIC) += cnic.o
+obj-$(CONFIG_BNX2X) += bnx2x/
+obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
+obj-$(CONFIG_TIGON3) += tg3.o
+obj-$(CONFIG_BGMAC) += bgmac.o
+obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o
diff --git a/drivers/net/b44.c b/drivers/net/ethernet/broadcom/b44.c
index c3bda5ce67c..ca5a20a48b1 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -5,11 +5,14 @@
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
* Copyright (C) 2006 Felix Fietkau (nbd@openwrt.org)
* Copyright (C) 2006 Broadcom Corporation.
- * Copyright (C) 2007 Michael Buesch <mb@bu3sch.de>
+ * Copyright (C) 2007 Michael Buesch <m@bues.ch>
+ * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
*
* Distribute under GPL.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -23,8 +26,11 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/ssb/ssb.h>
+#include <linux/slab.h>
+#include <linux/phy.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -34,8 +40,8 @@
#include "b44.h"
#define DRV_MODULE_NAME "b44"
-#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "2.0"
+#define DRV_DESCRIPTION "Broadcom 44xx/47xx 10/100 PCI ethernet driver"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
@@ -73,8 +79,8 @@
(BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
-#define RX_PKT_OFFSET 30
-#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET + 64)
+#define RX_PKT_OFFSET (RX_HEADER_LEN + 2)
+#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET)
/* minimum number of free TX descriptors required to wake up TX process */
#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
@@ -88,11 +94,8 @@
#define B44_ETHIPV6UDP_HLEN 62
#define B44_ETHIPV4UDP_HLEN 42
-static char version[] __devinitdata =
- DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION "\n";
-
MODULE_AUTHOR("Felix Fietkau, Florian Schirmer, Pekka Pietikainen, David S. Miller");
-MODULE_DESCRIPTION("Broadcom 44xx/47xx 10/100 PCI ethernet driver");
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
@@ -102,7 +105,7 @@ MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
#ifdef CONFIG_B44_PCI
-static const struct pci_device_id b44_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(b44_pci_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B0) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1) },
@@ -133,7 +136,6 @@ static void b44_init_rings(struct b44 *);
static void b44_init_hw(struct b44 *, int);
-static int dma_desc_align_mask;
static int dma_desc_sync_size;
static int instance;
@@ -148,9 +150,8 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
unsigned long offset,
enum dma_data_direction dir)
{
- ssb_dma_sync_single_range_for_device(sdev, dma_base,
- offset & dma_desc_align_mask,
- dma_desc_sync_size, dir);
+ dma_sync_single_for_device(sdev->dma_dev, dma_base + offset,
+ dma_desc_sync_size, dir);
}
static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
@@ -158,9 +159,8 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
unsigned long offset,
enum dma_data_direction dir)
{
- ssb_dma_sync_single_range_for_cpu(sdev, dma_base,
- offset & dma_desc_align_mask,
- dma_desc_sync_size, dir);
+ dma_sync_single_for_cpu(sdev->dma_dev, dma_base + offset,
+ dma_desc_sync_size, dir);
}
static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
@@ -189,11 +189,10 @@ static int b44_wait_bit(struct b44 *bp, unsigned long reg,
udelay(10);
}
if (i == timeout) {
- printk(KERN_ERR PFX "%s: BUG! Timeout waiting for bit %08x of register "
- "%lx to %s.\n",
- bp->dev->name,
- bit, reg,
- (clear ? "clear" : "set"));
+ if (net_ratelimit())
+ netdev_err(bp->dev, "BUG! Timeout waiting for bit %08x of register %lx to %s\n",
+ bit, reg, clear ? "clear" : "set");
+
return -ENODEV;
}
return 0;
@@ -287,7 +286,7 @@ static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
static inline int b44_readphy(struct b44 *bp, int reg, u32 *val)
{
- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
return 0;
return __b44_readphy(bp, bp->phy_addr, reg, val);
@@ -295,14 +294,14 @@ static inline int b44_readphy(struct b44 *bp, int reg, u32 *val)
static inline int b44_writephy(struct b44 *bp, int reg, u32 val)
{
- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
return 0;
return __b44_writephy(bp, bp->phy_addr, reg, val);
}
/* miilib interface */
-static int b44_mii_read(struct net_device *dev, int phy_id, int location)
+static int b44_mdio_read_mii(struct net_device *dev, int phy_id, int location)
{
u32 val;
struct b44 *bp = netdev_priv(dev);
@@ -312,19 +311,36 @@ static int b44_mii_read(struct net_device *dev, int phy_id, int location)
return val;
}
-static void b44_mii_write(struct net_device *dev, int phy_id, int location,
- int val)
+static void b44_mdio_write_mii(struct net_device *dev, int phy_id, int location,
+ int val)
{
struct b44 *bp = netdev_priv(dev);
__b44_writephy(bp, phy_id, location, val);
}
+static int b44_mdio_read_phylib(struct mii_bus *bus, int phy_id, int location)
+{
+ u32 val;
+ struct b44 *bp = bus->priv;
+ int rc = __b44_readphy(bp, phy_id, location, &val);
+ if (rc)
+ return 0xffffffff;
+ return val;
+}
+
+static int b44_mdio_write_phylib(struct mii_bus *bus, int phy_id, int location,
+ u16 val)
+{
+ struct b44 *bp = bus->priv;
+ return __b44_writephy(bp, phy_id, location, val);
+}
+
static int b44_phy_reset(struct b44 *bp)
{
u32 val;
int err;
- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
return 0;
err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
if (err)
@@ -333,13 +349,12 @@ static int b44_phy_reset(struct b44 *bp)
err = b44_readphy(bp, MII_BMCR, &val);
if (!err) {
if (val & BMCR_RESET) {
- printk(KERN_ERR PFX "%s: PHY Reset would not complete.\n",
- bp->dev->name);
+ netdev_err(bp->dev, "PHY Reset would not complete\n");
err = -ENODEV;
}
}
- return 0;
+ return err;
}
static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags)
@@ -384,11 +399,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
__b44_set_flow_ctrl(bp, pause_enab);
}
-#ifdef SSB_DRIVER_MIPS
-extern char *nvram_get(char *name);
+#ifdef CONFIG_BCM47XX
+#include <bcm47xx_nvram.h>
static void b44_wap54g10_workaround(struct b44 *bp)
{
- const char *str;
+ char buf[20];
u32 val;
int err;
@@ -397,10 +412,9 @@ static void b44_wap54g10_workaround(struct b44 *bp)
* see https://dev.openwrt.org/ticket/146
* check and reset bit "isolate"
*/
- str = nvram_get("boardnum");
- if (!str)
+ if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
return;
- if (simple_strtoul(str, NULL, 0) == 2) {
+ if (simple_strtoul(buf, NULL, 0) == 2) {
err = __b44_readphy(bp, 0, MII_BMCR, &val);
if (err)
goto error;
@@ -413,7 +427,7 @@ static void b44_wap54g10_workaround(struct b44 *bp)
}
return;
error:
- printk(KERN_WARNING PFX "PHY: cannot reset MII transceiver isolate bit.\n");
+ pr_warning("PHY: cannot reset MII transceiver isolate bit\n");
}
#else
static inline void b44_wap54g10_workaround(struct b44 *bp)
@@ -428,7 +442,7 @@ static int b44_setup_phy(struct b44 *bp)
b44_wap54g10_workaround(bp);
- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
return 0;
if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
goto out;
@@ -488,9 +502,11 @@ out:
static void b44_stats_update(struct b44 *bp)
{
unsigned long reg;
- u32 *val;
+ u64 *val;
val = &bp->hw_stats.tx_good_octets;
+ u64_stats_update_begin(&bp->hw_stats.syncp);
+
for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
*val++ += br32(bp, reg);
}
@@ -501,23 +517,22 @@ static void b44_stats_update(struct b44 *bp)
for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
*val++ += br32(bp, reg);
}
+
+ u64_stats_update_end(&bp->hw_stats.syncp);
}
static void b44_link_report(struct b44 *bp)
{
if (!netif_carrier_ok(bp->dev)) {
- printk(KERN_INFO PFX "%s: Link is down.\n", bp->dev->name);
+ netdev_info(bp->dev, "Link is down\n");
} else {
- printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
- bp->dev->name,
- (bp->flags & B44_FLAG_100_BASE_T) ? 100 : 10,
- (bp->flags & B44_FLAG_FULL_DUPLEX) ? "full" : "half");
+ netdev_info(bp->dev, "Link is up at %d Mbps, %s duplex\n",
+ (bp->flags & B44_FLAG_100_BASE_T) ? 100 : 10,
+ (bp->flags & B44_FLAG_FULL_DUPLEX) ? "full" : "half");
- printk(KERN_INFO PFX "%s: Flow control is %s for TX and "
- "%s for RX.\n",
- bp->dev->name,
- (bp->flags & B44_FLAG_TX_PAUSE) ? "on" : "off",
- (bp->flags & B44_FLAG_RX_PAUSE) ? "on" : "off");
+ netdev_info(bp->dev, "Flow control is %s for TX and %s for RX\n",
+ (bp->flags & B44_FLAG_TX_PAUSE) ? "on" : "off",
+ (bp->flags & B44_FLAG_RX_PAUSE) ? "on" : "off");
}
}
@@ -525,12 +540,14 @@ static void b44_check_phy(struct b44 *bp)
{
u32 bmsr, aux;
- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY) {
bp->flags |= B44_FLAG_100_BASE_T;
- bp->flags |= B44_FLAG_FULL_DUPLEX;
if (!netif_carrier_ok(bp->dev)) {
u32 val = br32(bp, B44_TX_CTRL);
- val |= TX_CTRL_DUPLEX;
+ if (bp->flags & B44_FLAG_FULL_DUPLEX)
+ val |= TX_CTRL_DUPLEX;
+ else
+ val &= ~TX_CTRL_DUPLEX;
bw32(bp, B44_TX_CTRL, val);
netif_carrier_on(bp->dev);
b44_link_report(bp);
@@ -576,11 +593,9 @@ static void b44_check_phy(struct b44 *bp)
}
if (bmsr & BMSR_RFAULT)
- printk(KERN_WARNING PFX "%s: Remote fault detected in PHY\n",
- bp->dev->name);
+ netdev_warn(bp->dev, "Remote fault detected in PHY\n");
if (bmsr & BMSR_JCD)
- printk(KERN_WARNING PFX "%s: Jabber detected in PHY\n",
- bp->dev->name);
+ netdev_warn(bp->dev, "Jabber detected in PHY\n");
}
}
@@ -602,6 +617,7 @@ static void b44_timer(unsigned long __opaque)
static void b44_tx(struct b44 *bp)
{
u32 cur, cons;
+ unsigned bytes_compl = 0, pkts_compl = 0;
cur = br32(bp, B44_DMATX_STAT) & DMATX_STAT_CDMASK;
cur /= sizeof(struct dma_desc);
@@ -613,14 +629,19 @@ static void b44_tx(struct b44 *bp)
BUG_ON(skb == NULL);
- ssb_dma_unmap_single(bp->sdev,
- rp->mapping,
- skb->len,
- DMA_TO_DEVICE);
+ dma_unmap_single(bp->sdev->dma_dev,
+ rp->mapping,
+ skb->len,
+ DMA_TO_DEVICE);
rp->skb = NULL;
+
+ bytes_compl += skb->len;
+ pkts_compl++;
+
dev_kfree_skb_irq(skb);
}
+ netdev_completed_queue(bp->dev, pkts_compl, bytes_compl);
bp->tx_cons = cons;
if (netif_queue_stopped(bp->dev) &&
TX_BUFFS_AVAIL(bp) > B44_TX_WAKEUP_THRESH)
@@ -653,36 +674,36 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (skb == NULL)
return -ENOMEM;
- mapping = ssb_dma_map_single(bp->sdev, skb->data,
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
+ mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
+ RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
/* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */
- if (ssb_dma_mapping_error(bp->sdev, mapping) ||
- mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
+ if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
+ mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
/* Sigh... */
- if (!ssb_dma_mapping_error(bp->sdev, mapping))
- ssb_dma_unmap_single(bp->sdev, mapping,
+ if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+ dma_unmap_single(bp->sdev->dma_dev, mapping,
RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
- skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
+ skb = alloc_skb(RX_PKT_BUF_SZ, GFP_ATOMIC | GFP_DMA);
if (skb == NULL)
return -ENOMEM;
- mapping = ssb_dma_map_single(bp->sdev, skb->data,
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
- if (ssb_dma_mapping_error(bp->sdev, mapping) ||
- mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
- if (!ssb_dma_mapping_error(bp->sdev, mapping))
- ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
+ mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
+ RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
+ mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
+ if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+ dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
return -ENOMEM;
}
+ bp->force_copybreak = 1;
}
rh = (struct rx_header *) skb->data;
- skb_reserve(skb, RX_PKT_OFFSET);
rh->len = 0;
rh->flags = 0;
@@ -693,17 +714,17 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (src_map != NULL)
src_map->skb = NULL;
- ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET));
+ ctrl = (DESC_CTRL_LEN & RX_PKT_BUF_SZ);
if (dest_idx == (B44_RX_RING_SIZE - 1))
ctrl |= DESC_CTRL_EOT;
dp = &bp->rx_ring[dest_idx];
dp->ctrl = cpu_to_le32(ctrl);
- dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset);
+ dp->addr = cpu_to_le32((u32) mapping + bp->dma_offset);
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
- dest_idx * sizeof(dp),
+ dest_idx * sizeof(*dp),
DMA_BIDIRECTIONAL);
return RX_PKT_BUF_SZ;
@@ -731,7 +752,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_cpu(bp->sdev, bp->rx_ring_dma,
- src_idx * sizeof(src_desc),
+ src_idx * sizeof(*src_desc),
DMA_BIDIRECTIONAL);
ctrl = src_desc->ctrl;
@@ -747,12 +768,12 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
- dest_idx * sizeof(dest_desc),
+ dest_idx * sizeof(*dest_desc),
DMA_BIDIRECTIONAL);
- ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr),
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_device(bp->sdev->dma_dev, dest_map->mapping,
+ RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
}
static int b44_rx(struct b44 *bp, int budget)
@@ -772,9 +793,9 @@ static int b44_rx(struct b44 *bp, int budget)
struct rx_header *rh;
u16 len;
- ssb_dma_sync_single_for_cpu(bp->sdev, map,
- RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
+ dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
+ RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
rh = (struct rx_header *) skb->data;
len = le16_to_cpu(rh->len);
if ((len > (RX_PKT_BUF_SZ - RX_PKT_OFFSET)) ||
@@ -782,7 +803,7 @@ static int b44_rx(struct b44 *bp, int budget)
drop_it:
b44_recycle_rx(bp, cons, bp->rx_prod);
drop_it_no_recycle:
- bp->stats.rx_dropped++;
+ bp->dev->stats.rx_dropped++;
goto next_pkt;
}
@@ -801,35 +822,33 @@ static int b44_rx(struct b44 *bp, int budget)
/* Omit CRC. */
len -= 4;
- if (len > RX_COPY_THRESHOLD) {
+ if (!bp->force_copybreak && len > RX_COPY_THRESHOLD) {
int skb_size;
skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
if (skb_size < 0)
goto drop_it;
- ssb_dma_unmap_single(bp->sdev, map,
- skb_size, DMA_FROM_DEVICE);
+ dma_unmap_single(bp->sdev->dma_dev, map,
+ skb_size, DMA_FROM_DEVICE);
/* Leave out rx_header */
- skb_put(skb, len + RX_PKT_OFFSET);
- skb_pull(skb, RX_PKT_OFFSET);
+ skb_put(skb, len + RX_PKT_OFFSET);
+ skb_pull(skb, RX_PKT_OFFSET);
} else {
struct sk_buff *copy_skb;
b44_recycle_rx(bp, cons, bp->rx_prod);
- copy_skb = dev_alloc_skb(len + 2);
+ copy_skb = netdev_alloc_skb_ip_align(bp->dev, len);
if (copy_skb == NULL)
goto drop_it_no_recycle;
- skb_reserve(copy_skb, 2);
skb_put(copy_skb, len);
/* DMA sync done above, copy just the actual packet */
skb_copy_from_linear_data_offset(skb, RX_PKT_OFFSET,
copy_skb->data, len);
skb = copy_skb;
}
- skb->ip_summed = CHECKSUM_NONE;
+ skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, bp->dev);
netif_receive_skb(skb);
- bp->dev->last_rx = jiffies;
received++;
budget--;
next_pkt:
@@ -847,25 +866,32 @@ static int b44_rx(struct b44 *bp, int budget)
static int b44_poll(struct napi_struct *napi, int budget)
{
struct b44 *bp = container_of(napi, struct b44, napi);
- struct net_device *netdev = bp->dev;
int work_done;
+ unsigned long flags;
- spin_lock_irq(&bp->lock);
+ spin_lock_irqsave(&bp->lock, flags);
if (bp->istat & (ISTAT_TX | ISTAT_TO)) {
/* spin_lock(&bp->tx_lock); */
b44_tx(bp);
/* spin_unlock(&bp->tx_lock); */
}
- spin_unlock_irq(&bp->lock);
+ if (bp->istat & ISTAT_RFO) { /* fast recovery, in ~20msec */
+ bp->istat &= ~ISTAT_RFO;
+ b44_disable_ints(bp);
+ ssb_device_enable(bp->sdev, 0); /* resets ISTAT_RFO */
+ b44_init_rings(bp);
+ b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY);
+ netif_wake_queue(bp->dev);
+ }
+
+ spin_unlock_irqrestore(&bp->lock, flags);
work_done = 0;
if (bp->istat & ISTAT_RX)
work_done += b44_rx(bp, budget);
if (bp->istat & ISTAT_ERRORS) {
- unsigned long flags;
-
spin_lock_irqsave(&bp->lock, flags);
b44_halt(bp);
b44_init_rings(bp);
@@ -876,7 +902,7 @@ static int b44_poll(struct napi_struct *napi, int budget)
}
if (work_done < budget) {
- netif_rx_complete(netdev, napi);
+ napi_complete(napi);
b44_enable_ints(bp);
}
@@ -904,20 +930,17 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
handled = 1;
if (unlikely(!netif_running(dev))) {
- printk(KERN_INFO "%s: late interrupt.\n", dev->name);
+ netdev_info(dev, "late interrupt\n");
goto irq_ack;
}
- if (netif_rx_schedule_prep(dev, &bp->napi)) {
+ if (napi_schedule_prep(&bp->napi)) {
/* NOTE: These writes are posted by the readback of
* the ISTAT register below.
*/
bp->istat = istat;
__b44_disable_ints(bp);
- __netif_rx_schedule(dev, &bp->napi);
- } else {
- printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
- dev->name);
+ __napi_schedule(&bp->napi);
}
irq_ack:
@@ -932,8 +955,7 @@ static void b44_tx_timeout(struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
- printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
- dev->name);
+ netdev_err(dev, "transmit timed out, resetting\n");
spin_lock_irq(&bp->lock);
@@ -948,42 +970,42 @@ static void b44_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
int rc = NETDEV_TX_OK;
dma_addr_t mapping;
u32 len, entry, ctrl;
+ unsigned long flags;
len = skb->len;
- spin_lock_irq(&bp->lock);
+ spin_lock_irqsave(&bp->lock, flags);
/* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
netif_stop_queue(dev);
- printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
- dev->name);
+ netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
goto err_out;
}
- mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
- if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
+ mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
+ if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
struct sk_buff *bounce_skb;
/* Chip can't handle DMA to/from >1GB, use bounce buffer */
- if (!ssb_dma_mapping_error(bp->sdev, mapping))
- ssb_dma_unmap_single(bp->sdev, mapping, len,
+ if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+ dma_unmap_single(bp->sdev->dma_dev, mapping, len,
DMA_TO_DEVICE);
- bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
+ bounce_skb = alloc_skb(len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb)
goto err_out;
- mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
- len, DMA_TO_DEVICE);
- if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) {
- if (!ssb_dma_mapping_error(bp->sdev, mapping))
- ssb_dma_unmap_single(bp->sdev, mapping,
+ mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
+ len, DMA_TO_DEVICE);
+ if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
+ if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
+ dma_unmap_single(bp->sdev->dma_dev, mapping,
len, DMA_TO_DEVICE);
dev_kfree_skb_any(bounce_skb);
goto err_out;
@@ -1023,13 +1045,13 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (bp->flags & B44_FLAG_REORDER_BUG)
br32(bp, B44_DMATX_PTR);
+ netdev_sent_queue(dev, skb->len);
+
if (TX_BUFFS_AVAIL(bp) < 1)
netif_stop_queue(dev);
- dev->trans_start = jiffies;
-
out_unlock:
- spin_unlock_irq(&bp->lock);
+ spin_unlock_irqrestore(&bp->lock, flags);
return rc;
@@ -1082,8 +1104,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL)
continue;
- ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ,
- DMA_FROM_DEVICE);
+ dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
+ DMA_FROM_DEVICE);
dev_kfree_skb_any(rp->skb);
rp->skb = NULL;
}
@@ -1094,8 +1116,8 @@ static void b44_free_rings(struct b44 *bp)
if (rp->skb == NULL)
continue;
- ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len,
- DMA_TO_DEVICE);
+ dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(rp->skb);
rp->skb = NULL;
}
@@ -1117,14 +1139,12 @@ static void b44_init_rings(struct b44 *bp)
memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
if (bp->flags & B44_FLAG_RX_RING_HACK)
- ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_BIDIRECTIONAL);
+ dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
if (bp->flags & B44_FLAG_TX_RING_HACK)
- ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_TO_DEVICE);
+ dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES, DMA_TO_DEVICE);
for (i = 0; i < bp->rx_pending; i++) {
if (b44_alloc_rx_skb(bp, -1, i) < 0)
@@ -1144,27 +1164,23 @@ static void b44_free_consistent(struct b44 *bp)
bp->tx_buffers = NULL;
if (bp->rx_ring) {
if (bp->flags & B44_FLAG_RX_RING_HACK) {
- ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_BIDIRECTIONAL);
+ dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
+ DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
kfree(bp->rx_ring);
} else
- ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
- bp->rx_ring, bp->rx_ring_dma,
- GFP_KERNEL);
+ dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
+ bp->rx_ring, bp->rx_ring_dma);
bp->rx_ring = NULL;
bp->flags &= ~B44_FLAG_RX_RING_HACK;
}
if (bp->tx_ring) {
if (bp->flags & B44_FLAG_TX_RING_HACK) {
- ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma,
- DMA_TABLE_BYTES,
- DMA_TO_DEVICE);
+ dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
+ DMA_TABLE_BYTES, DMA_TO_DEVICE);
kfree(bp->tx_ring);
} else
- ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
- bp->tx_ring, bp->tx_ring_dma,
- GFP_KERNEL);
+ dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
+ bp->tx_ring, bp->tx_ring_dma);
bp->tx_ring = NULL;
bp->flags &= ~B44_FLAG_TX_RING_HACK;
}
@@ -1189,7 +1205,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
goto out_err;
size = DMA_TABLE_BYTES;
- bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->rx_ring_dma, gfp);
+ bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
+ &bp->rx_ring_dma, gfp);
if (!bp->rx_ring) {
/* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
@@ -1201,12 +1218,12 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
if (!rx_ring)
goto out_err;
- rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring,
- DMA_TABLE_BYTES,
- DMA_BIDIRECTIONAL);
+ rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
+ DMA_TABLE_BYTES,
+ DMA_BIDIRECTIONAL);
- if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) ||
- rx_ring_dma + size > DMA_30BIT_MASK) {
+ if (dma_mapping_error(bp->sdev->dma_dev, rx_ring_dma) ||
+ rx_ring_dma + size > DMA_BIT_MASK(30)) {
kfree(rx_ring);
goto out_err;
}
@@ -1216,7 +1233,8 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
bp->flags |= B44_FLAG_RX_RING_HACK;
}
- bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->tx_ring_dma, gfp);
+ bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
+ &bp->tx_ring_dma, gfp);
if (!bp->tx_ring) {
/* Allocation may have failed due to ssb_dma_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
@@ -1228,12 +1246,12 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
if (!tx_ring)
goto out_err;
- tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring,
- DMA_TABLE_BYTES,
- DMA_TO_DEVICE);
+ tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
+ DMA_TABLE_BYTES,
+ DMA_TO_DEVICE);
- if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) ||
- tx_ring_dma + size > DMA_30BIT_MASK) {
+ if (dma_mapping_error(bp->sdev->dma_dev, tx_ring_dma) ||
+ tx_ring_dma + size > DMA_BIT_MASK(30)) {
kfree(tx_ring);
goto out_err;
}
@@ -1266,8 +1284,14 @@ static void b44_clear_stats(struct b44 *bp)
static void b44_chip_reset(struct b44 *bp, int reset_kind)
{
struct ssb_device *sdev = bp->sdev;
+ bool was_enabled;
+
+ was_enabled = ssb_device_is_enabled(bp->sdev);
+
+ ssb_device_enable(bp->sdev, 0);
+ ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
- if (ssb_device_is_enabled(bp->sdev)) {
+ if (was_enabled) {
bw32(bp, B44_RCV_LAZY, 0);
bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1);
@@ -1279,10 +1303,8 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
}
bw32(bp, B44_DMARX_CTRL, 0);
bp->rx_prod = bp->rx_cons = 0;
- } else
- ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
+ }
- ssb_device_enable(bp->sdev, 0);
b44_clear_stats(bp);
/*
@@ -1295,14 +1317,18 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
switch (sdev->bus->bustype) {
case SSB_BUSTYPE_SSB:
bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
- (((ssb_clockspeed(sdev->bus) + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
+ (DIV_ROUND_CLOSEST(ssb_clockspeed(sdev->bus),
+ B44_MDC_RATIO)
& MDIO_CTRL_MAXF_MASK)));
break;
case SSB_BUSTYPE_PCI:
- case SSB_BUSTYPE_PCMCIA:
bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
(0x0d & MDIO_CTRL_MAXF_MASK)));
break;
+ case SSB_BUSTYPE_PCMCIA:
+ case SSB_BUSTYPE_SDIO:
+ WARN_ON(1); /* A device with this bus does not exist. */
+ break;
}
br32(bp, B44_MDIO_CTRL);
@@ -1310,7 +1336,7 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) {
bw32(bp, B44_ENET_CTRL, ENET_CTRL_EPSEL);
br32(bp, B44_ENET_CTRL);
- bp->flags &= ~B44_FLAG_INTERNAL_PHY;
+ bp->flags |= B44_FLAG_EXTERNAL_PHY;
} else {
u32 val = br32(bp, B44_DEVCTRL);
@@ -1319,7 +1345,7 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
br32(bp, B44_DEVCTRL);
udelay(100);
}
- bp->flags |= B44_FLAG_INTERNAL_PHY;
+ bp->flags &= ~B44_FLAG_EXTERNAL_PHY;
}
}
@@ -1330,11 +1356,14 @@ static void b44_halt(struct b44 *bp)
/* reset PHY */
b44_phy_reset(bp);
/* power down PHY */
- printk(KERN_INFO PFX "%s: powering down PHY\n", bp->dev->name);
+ netdev_info(bp->dev, "powering down PHY\n");
bw32(bp, B44_MAC_CTRL, MAC_CTRL_PHY_PDOWN);
/* now reset the chip, but without enabling the MAC&PHY
* part of it. This has to be done _after_ we shut down the PHY */
- b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL);
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
+ b44_chip_reset(bp, B44_CHIP_RESET_FULL);
+ else
+ b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL);
}
/* bp->lock is held. */
@@ -1419,6 +1448,8 @@ static void b44_init_hw(struct b44 *bp, int reset_kind)
val = br32(bp, B44_ENET_CTRL);
bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE));
+
+ netdev_reset_queue(bp->dev);
}
static int b44_open(struct net_device *dev)
@@ -1453,6 +1484,10 @@ static int b44_open(struct net_device *dev)
add_timer(&bp->timer);
b44_enable_ints(bp);
+
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
+ phy_start(bp->phydev);
+
netif_start_queue(dev);
out:
return err;
@@ -1502,8 +1537,7 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
for (k = 0; k< ethaddr_bytes; k++) {
ppattern[offset + magicsync +
(j * ETH_ALEN) + k] = macaddr[k];
- len++;
- set_bit(len, (unsigned long *) pmask);
+ set_bit(len++, (unsigned long *) pmask);
}
}
return len - 1;
@@ -1521,10 +1555,8 @@ static void b44_setup_pseudo_magicp(struct b44 *bp)
u8 pwol_mask[B44_PMASK_SIZE];
pwol_pattern = kzalloc(B44_PATTERN_SIZE, GFP_KERNEL);
- if (!pwol_pattern) {
- printk(KERN_ERR PFX "Memory not available for WOL\n");
+ if (!pwol_pattern)
return;
- }
/* Ipv4 magic packet pattern - pattern 0.*/
memset(pwol_mask, 0, B44_PMASK_SIZE);
@@ -1618,6 +1650,9 @@ static int b44_close(struct net_device *dev)
netif_stop_queue(dev);
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
+ phy_stop(bp->phydev);
+
napi_disable(&bp->napi);
del_timer_sync(&bp->timer);
@@ -1642,57 +1677,64 @@ static int b44_close(struct net_device *dev)
return 0;
}
-static struct net_device_stats *b44_get_stats(struct net_device *dev)
+static struct rtnl_link_stats64 *b44_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *nstat)
{
struct b44 *bp = netdev_priv(dev);
- struct net_device_stats *nstat = &bp->stats;
struct b44_hw_stats *hwstat = &bp->hw_stats;
-
- /* Convert HW stats into netdevice stats. */
- nstat->rx_packets = hwstat->rx_pkts;
- nstat->tx_packets = hwstat->tx_pkts;
- nstat->rx_bytes = hwstat->rx_octets;
- nstat->tx_bytes = hwstat->tx_octets;
- nstat->tx_errors = (hwstat->tx_jabber_pkts +
- hwstat->tx_oversize_pkts +
- hwstat->tx_underruns +
- hwstat->tx_excessive_cols +
- hwstat->tx_late_cols);
- nstat->multicast = hwstat->tx_multicast_pkts;
- nstat->collisions = hwstat->tx_total_cols;
-
- nstat->rx_length_errors = (hwstat->rx_oversize_pkts +
- hwstat->rx_undersize);
- nstat->rx_over_errors = hwstat->rx_missed_pkts;
- nstat->rx_frame_errors = hwstat->rx_align_errs;
- nstat->rx_crc_errors = hwstat->rx_crc_errs;
- nstat->rx_errors = (hwstat->rx_jabber_pkts +
- hwstat->rx_oversize_pkts +
- hwstat->rx_missed_pkts +
- hwstat->rx_crc_align_errs +
- hwstat->rx_undersize +
- hwstat->rx_crc_errs +
- hwstat->rx_align_errs +
- hwstat->rx_symbol_errs);
-
- nstat->tx_aborted_errors = hwstat->tx_underruns;
+ unsigned int start;
+
+ do {
+ start = u64_stats_fetch_begin_irq(&hwstat->syncp);
+
+ /* Convert HW stats into rtnl_link_stats64 stats. */
+ nstat->rx_packets = hwstat->rx_pkts;
+ nstat->tx_packets = hwstat->tx_pkts;
+ nstat->rx_bytes = hwstat->rx_octets;
+ nstat->tx_bytes = hwstat->tx_octets;
+ nstat->tx_errors = (hwstat->tx_jabber_pkts +
+ hwstat->tx_oversize_pkts +
+ hwstat->tx_underruns +
+ hwstat->tx_excessive_cols +
+ hwstat->tx_late_cols);
+ nstat->multicast = hwstat->tx_multicast_pkts;
+ nstat->collisions = hwstat->tx_total_cols;
+
+ nstat->rx_length_errors = (hwstat->rx_oversize_pkts +
+ hwstat->rx_undersize);
+ nstat->rx_over_errors = hwstat->rx_missed_pkts;
+ nstat->rx_frame_errors = hwstat->rx_align_errs;
+ nstat->rx_crc_errors = hwstat->rx_crc_errs;
+ nstat->rx_errors = (hwstat->rx_jabber_pkts +
+ hwstat->rx_oversize_pkts +
+ hwstat->rx_missed_pkts +
+ hwstat->rx_crc_align_errs +
+ hwstat->rx_undersize +
+ hwstat->rx_crc_errs +
+ hwstat->rx_align_errs +
+ hwstat->rx_symbol_errs);
+
+ nstat->tx_aborted_errors = hwstat->tx_underruns;
#if 0
- /* Carrier lost counter seems to be broken for some devices */
- nstat->tx_carrier_errors = hwstat->tx_carrier_lost;
+ /* Carrier lost counter seems to be broken for some devices */
+ nstat->tx_carrier_errors = hwstat->tx_carrier_lost;
#endif
+ } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start));
return nstat;
}
static int __b44_load_mcast(struct b44 *bp, struct net_device *dev)
{
- struct dev_mc_list *mclist;
+ struct netdev_hw_addr *ha;
int i, num_ents;
- num_ents = min_t(int, dev->mc_count, B44_MCAST_TABLE_SIZE);
- mclist = dev->mc_list;
- for (i = 0; mclist && i < num_ents; i++, mclist = mclist->next) {
- __b44_cam_write(bp, mclist->dmi_addr, i + 1);
+ num_ents = min_t(int, netdev_mc_count(dev), B44_MCAST_TABLE_SIZE);
+ i = 0;
+ netdev_for_each_mc_addr(ha, dev) {
+ if (i == num_ents)
+ break;
+ __b44_cam_write(bp, ha->addr, i++ + 1);
}
return i+1;
}
@@ -1714,7 +1756,7 @@ static void __b44_set_rx_mode(struct net_device *dev)
__b44_set_mac_addr(bp);
if ((dev->flags & IFF_ALLMULTI) ||
- (dev->mc_count > B44_MCAST_TABLE_SIZE))
+ (netdev_mc_count(dev) > B44_MCAST_TABLE_SIZE))
val |= RXCONFIG_ALLMULTI;
else
i = __b44_load_mcast(bp, dev);
@@ -1754,15 +1796,18 @@ static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *inf
struct b44 *bp = netdev_priv(dev);
struct ssb_bus *bus = bp->sdev->bus;
- strncpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
- strncpy(info->version, DRV_MODULE_VERSION, sizeof(info->driver));
+ strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
switch (bus->bustype) {
case SSB_BUSTYPE_PCI:
- strncpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info));
+ strlcpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info));
break;
- case SSB_BUSTYPE_PCMCIA:
case SSB_BUSTYPE_SSB:
- strncpy(info->bus_info, "SSB", sizeof(info->bus_info));
+ strlcpy(info->bus_info, "SSB", sizeof(info->bus_info));
+ break;
+ case SSB_BUSTYPE_PCMCIA:
+ case SSB_BUSTYPE_SDIO:
+ WARN_ON(1); /* A device with this bus does not exist. */
break;
}
}
@@ -1791,6 +1836,11 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct b44 *bp = netdev_priv(dev);
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY) {
+ BUG_ON(!bp->phydev);
+ return phy_ethtool_gset(bp->phydev, cmd);
+ }
+
cmd->supported = (SUPPORTED_Autoneg);
cmd->supported |= (SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
@@ -1808,20 +1858,20 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (bp->flags & B44_FLAG_ADV_100FULL)
cmd->advertising |= ADVERTISED_100baseT_Full;
cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
- cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
- SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(cmd, ((bp->flags & B44_FLAG_100_BASE_T) ?
+ SPEED_100 : SPEED_10));
cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
DUPLEX_FULL : DUPLEX_HALF;
cmd->port = 0;
cmd->phy_address = bp->phy_addr;
- cmd->transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
- XCVR_INTERNAL : XCVR_EXTERNAL;
+ cmd->transceiver = (bp->flags & B44_FLAG_EXTERNAL_PHY) ?
+ XCVR_EXTERNAL : XCVR_INTERNAL;
cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
AUTONEG_DISABLE : AUTONEG_ENABLE;
if (cmd->autoneg == AUTONEG_ENABLE)
cmd->advertising |= ADVERTISED_Autoneg;
if (!netif_running(dev)){
- cmd->speed = 0;
+ ethtool_cmd_speed_set(cmd, 0);
cmd->duplex = 0xff;
}
cmd->maxtxpkt = 0;
@@ -1832,6 +1882,23 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct b44 *bp = netdev_priv(dev);
+ u32 speed;
+ int ret;
+
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY) {
+ BUG_ON(!bp->phydev);
+ spin_lock_irq(&bp->lock);
+ if (netif_running(dev))
+ b44_setup_phy(bp);
+
+ ret = phy_ethtool_sset(bp->phydev, cmd);
+
+ spin_unlock_irq(&bp->lock);
+
+ return ret;
+ }
+
+ speed = ethtool_cmd_speed(cmd);
/* We do not support gigabit. */
if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -1839,8 +1906,8 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
(ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full))
return -EINVAL;
- } else if ((cmd->speed != SPEED_100 &&
- cmd->speed != SPEED_10) ||
+ } else if ((speed != SPEED_100 &&
+ speed != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)) {
return -EINVAL;
@@ -1874,7 +1941,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
} else {
bp->flags |= B44_FLAG_FORCE_LINK;
bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
- if (cmd->speed == SPEED_100)
+ if (speed == SPEED_100)
bp->flags |= B44_FLAG_100_BASE_T;
if (cmd->duplex == DUPLEX_FULL)
bp->flags |= B44_FLAG_FULL_DUPLEX;
@@ -1994,17 +2061,24 @@ static void b44_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct b44 *bp = netdev_priv(dev);
- u32 *val = &bp->hw_stats.tx_good_octets;
+ struct b44_hw_stats *hwstat = &bp->hw_stats;
+ u64 *data_src, *data_dst;
+ unsigned int start;
u32 i;
spin_lock_irq(&bp->lock);
-
b44_stats_update(bp);
+ spin_unlock_irq(&bp->lock);
- for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
- *data++ = *val++;
+ do {
+ data_src = &hwstat->tx_good_octets;
+ data_dst = data;
+ start = u64_stats_fetch_begin_irq(&hwstat->syncp);
- spin_unlock_irq(&bp->lock);
+ for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
+ *data_dst++ = *data_src++;
+
+ } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start));
}
static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -2054,7 +2128,6 @@ static const struct ethtool_ops b44_ethtool_ops = {
static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct mii_ioctl_data *data = if_mii(ifr);
struct b44 *bp = netdev_priv(dev);
int err = -EINVAL;
@@ -2062,13 +2135,18 @@ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
goto out;
spin_lock_irq(&bp->lock);
- err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY) {
+ BUG_ON(!bp->phydev);
+ err = phy_mii_ioctl(bp->phydev, ifr, cmd);
+ } else {
+ err = generic_mii_ioctl(&bp->mii_if, if_mii(ifr), cmd, NULL);
+ }
spin_unlock_irq(&bp->lock);
out:
return err;
}
-static int __devinit b44_get_invariants(struct b44 *bp)
+static int b44_get_invariants(struct b44 *bp)
{
struct ssb_device *sdev = bp->sdev;
int err = 0;
@@ -2089,15 +2167,13 @@ static int __devinit b44_get_invariants(struct b44 *bp)
* valid PHY address. */
bp->phy_addr &= 0x1F;
- memcpy(bp->dev->dev_addr, addr, 6);
+ memcpy(bp->dev->dev_addr, addr, ETH_ALEN);
if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
- printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
+ pr_err("Invalid MAC address found in EEPROM\n");
return -EINVAL;
}
- memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
-
bp->imask = IMASK_DEF;
/* XXX - really required?
@@ -2110,24 +2186,175 @@ static int __devinit b44_get_invariants(struct b44 *bp)
return err;
}
-static int __devinit b44_init_one(struct ssb_device *sdev,
- const struct ssb_device_id *ent)
+static const struct net_device_ops b44_netdev_ops = {
+ .ndo_open = b44_open,
+ .ndo_stop = b44_close,
+ .ndo_start_xmit = b44_start_xmit,
+ .ndo_get_stats64 = b44_get_stats64,
+ .ndo_set_rx_mode = b44_set_rx_mode,
+ .ndo_set_mac_address = b44_set_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = b44_ioctl,
+ .ndo_tx_timeout = b44_tx_timeout,
+ .ndo_change_mtu = b44_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = b44_poll_controller,
+#endif
+};
+
+static void b44_adjust_link(struct net_device *dev)
+{
+ struct b44 *bp = netdev_priv(dev);
+ struct phy_device *phydev = bp->phydev;
+ bool status_changed = 0;
+
+ BUG_ON(!phydev);
+
+ if (bp->old_link != phydev->link) {
+ status_changed = 1;
+ bp->old_link = phydev->link;
+ }
+
+ /* reflect duplex change */
+ if (phydev->link) {
+ if ((phydev->duplex == DUPLEX_HALF) &&
+ (bp->flags & B44_FLAG_FULL_DUPLEX)) {
+ status_changed = 1;
+ bp->flags &= ~B44_FLAG_FULL_DUPLEX;
+ } else if ((phydev->duplex == DUPLEX_FULL) &&
+ !(bp->flags & B44_FLAG_FULL_DUPLEX)) {
+ status_changed = 1;
+ bp->flags |= B44_FLAG_FULL_DUPLEX;
+ }
+ }
+
+ if (status_changed) {
+ u32 val = br32(bp, B44_TX_CTRL);
+ if (bp->flags & B44_FLAG_FULL_DUPLEX)
+ val |= TX_CTRL_DUPLEX;
+ else
+ val &= ~TX_CTRL_DUPLEX;
+ bw32(bp, B44_TX_CTRL, val);
+ phy_print_status(phydev);
+ }
+}
+
+static int b44_register_phy_one(struct b44 *bp)
+{
+ struct mii_bus *mii_bus;
+ struct ssb_device *sdev = bp->sdev;
+ struct phy_device *phydev;
+ char bus_id[MII_BUS_ID_SIZE + 3];
+ struct ssb_sprom *sprom = &sdev->bus->sprom;
+ int err;
+
+ mii_bus = mdiobus_alloc();
+ if (!mii_bus) {
+ dev_err(sdev->dev, "mdiobus_alloc() failed\n");
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ mii_bus->priv = bp;
+ mii_bus->read = b44_mdio_read_phylib;
+ mii_bus->write = b44_mdio_write_phylib;
+ mii_bus->name = "b44_eth_mii";
+ mii_bus->parent = sdev->dev;
+ mii_bus->phy_mask = ~(1 << bp->phy_addr);
+ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%x", instance);
+ mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!mii_bus->irq) {
+ dev_err(sdev->dev, "mii_bus irq allocation failed\n");
+ err = -ENOMEM;
+ goto err_out_mdiobus;
+ }
+
+ memset(mii_bus->irq, PHY_POLL, sizeof(int) * PHY_MAX_ADDR);
+
+ bp->mii_bus = mii_bus;
+
+ err = mdiobus_register(mii_bus);
+ if (err) {
+ dev_err(sdev->dev, "failed to register MII bus\n");
+ goto err_out_mdiobus_irq;
+ }
+
+ if (!bp->mii_bus->phy_map[bp->phy_addr] &&
+ (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
+
+ dev_info(sdev->dev,
+ "could not find PHY at %i, use fixed one\n",
+ bp->phy_addr);
+
+ bp->phy_addr = 0;
+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, "fixed-0",
+ bp->phy_addr);
+ } else {
+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id,
+ bp->phy_addr);
+ }
+
+ phydev = phy_connect(bp->dev, bus_id, &b44_adjust_link,
+ PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(phydev)) {
+ dev_err(sdev->dev, "could not attach PHY at %i\n",
+ bp->phy_addr);
+ err = PTR_ERR(phydev);
+ goto err_out_mdiobus_unregister;
+ }
+
+ /* mask with MAC supported features */
+ phydev->supported &= (SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_MII);
+ phydev->advertising = phydev->supported;
+
+ bp->phydev = phydev;
+ bp->old_link = 0;
+ bp->phy_addr = phydev->addr;
+
+ dev_info(sdev->dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
+ phydev->drv->name, dev_name(&phydev->dev));
+
+ return 0;
+
+err_out_mdiobus_unregister:
+ mdiobus_unregister(mii_bus);
+
+err_out_mdiobus_irq:
+ kfree(mii_bus->irq);
+
+err_out_mdiobus:
+ mdiobus_free(mii_bus);
+
+err_out:
+ return err;
+}
+
+static void b44_unregister_phy_one(struct b44 *bp)
+{
+ struct mii_bus *mii_bus = bp->mii_bus;
+
+ phy_disconnect(bp->phydev);
+ mdiobus_unregister(mii_bus);
+ kfree(mii_bus->irq);
+ mdiobus_free(mii_bus);
+}
+
+static int b44_init_one(struct ssb_device *sdev,
+ const struct ssb_device_id *ent)
{
- static int b44_version_printed = 0;
struct net_device *dev;
struct b44 *bp;
int err;
- DECLARE_MAC_BUF(mac);
instance++;
- if (b44_version_printed++ == 0)
- printk(KERN_INFO "%s", version);
-
+ pr_info_once("%s version %s\n", DRV_DESCRIPTION, DRV_MODULE_VERSION);
dev = alloc_etherdev(sizeof(*bp));
if (!dev) {
- dev_err(sdev->dev, "Etherdev alloc failed, aborting.\n");
err = -ENOMEM;
goto out;
}
@@ -2140,6 +2367,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
bp = netdev_priv(dev);
bp->sdev = sdev;
bp->dev = dev;
+ bp->force_copybreak = 0;
bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
@@ -2148,24 +2376,11 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
bp->rx_pending = B44_DEF_RX_RING_PENDING;
bp->tx_pending = B44_DEF_TX_RING_PENDING;
- dev->open = b44_open;
- dev->stop = b44_close;
- dev->hard_start_xmit = b44_start_xmit;
- dev->get_stats = b44_get_stats;
- dev->set_multicast_list = b44_set_rx_mode;
- dev->set_mac_address = b44_set_mac_addr;
- dev->do_ioctl = b44_ioctl;
- dev->tx_timeout = b44_tx_timeout;
+ dev->netdev_ops = &b44_netdev_ops;
netif_napi_add(dev, &bp->napi, b44_poll, 64);
dev->watchdog_timeo = B44_TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = b44_poll_controller;
-#endif
- dev->change_mtu = b44_change_mtu;
dev->irq = sdev->irq;
- SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
-
- netif_carrier_off(dev);
+ dev->ethtool_ops = &b44_ethtool_ops;
err = ssb_bus_powerup(sdev->bus, 0);
if (err) {
@@ -2173,22 +2388,29 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
"Failed to powerup the bus\n");
goto err_out_free_dev;
}
- err = ssb_dma_set_mask(sdev, DMA_30BIT_MASK);
- if (err) {
+
+ if (dma_set_mask_and_coherent(sdev->dma_dev, DMA_BIT_MASK(30))) {
dev_err(sdev->dev,
- "Required 30BIT DMA mask unsupported by the system.\n");
+ "Required 30BIT DMA mask unsupported by the system\n");
goto err_out_powerdown;
}
+
err = b44_get_invariants(bp);
if (err) {
dev_err(sdev->dev,
- "Problem fetching invariants of chip, aborting.\n");
+ "Problem fetching invariants of chip, aborting\n");
+ goto err_out_powerdown;
+ }
+
+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
+ dev_err(sdev->dev, "No PHY present on this MAC, aborting\n");
+ err = -ENODEV;
goto err_out_powerdown;
}
bp->mii_if.dev = dev;
- bp->mii_if.mdio_read = b44_mii_read;
- bp->mii_if.mdio_write = b44_mii_write;
+ bp->mii_if.mdio_read = b44_mdio_read_mii;
+ bp->mii_if.mdio_write = b44_mdio_write_mii;
bp->mii_if.phy_id = bp->phy_addr;
bp->mii_if.phy_id_mask = 0x1f;
bp->mii_if.reg_num_mask = 0x1f;
@@ -2202,10 +2424,12 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
err = register_netdev(dev);
if (err) {
- dev_err(sdev->dev, "Cannot register net device, aborting.\n");
+ dev_err(sdev->dev, "Cannot register net device, aborting\n");
goto err_out_powerdown;
}
+ netif_carrier_off(dev);
+
ssb_set_drvdata(sdev, dev);
/* Chip reset provides power to the b44 MAC & PCI cores, which
@@ -2213,11 +2437,27 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
*/
b44_chip_reset(bp, B44_CHIP_RESET_FULL);
- printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
+ /* do a phy reset to test if there is an active phy */
+ err = b44_phy_reset(bp);
+ if (err < 0) {
+ dev_err(sdev->dev, "phy reset failed\n");
+ goto err_out_unregister_netdev;
+ }
+
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY) {
+ err = b44_register_phy_one(bp);
+ if (err) {
+ dev_err(sdev->dev, "Cannot register PHY, aborting\n");
+ goto err_out_unregister_netdev;
+ }
+ }
+
+ netdev_info(dev, "%s %pM\n", DRV_DESCRIPTION, dev->dev_addr);
return 0;
+err_out_unregister_netdev:
+ unregister_netdev(dev);
err_out_powerdown:
ssb_bus_may_powerdown(sdev->bus);
@@ -2228,11 +2468,15 @@ out:
return err;
}
-static void __devexit b44_remove_one(struct ssb_device *sdev)
+static void b44_remove_one(struct ssb_device *sdev)
{
struct net_device *dev = ssb_get_drvdata(sdev);
+ struct b44 *bp = netdev_priv(dev);
unregister_netdev(dev);
+ if (bp->flags & B44_FLAG_EXTERNAL_PHY)
+ b44_unregister_phy_one(bp);
+ ssb_device_disable(sdev, 0);
ssb_bus_may_powerdown(sdev->bus);
free_netdev(dev);
ssb_pcihost_set_power_state(sdev, PCI_D3hot);
@@ -2284,18 +2528,27 @@ static int b44_resume(struct ssb_device *sdev)
if (!netif_running(dev))
return 0;
+ spin_lock_irq(&bp->lock);
+ b44_init_rings(bp);
+ b44_init_hw(bp, B44_FULL_RESET);
+ spin_unlock_irq(&bp->lock);
+
+ /*
+ * As a shared interrupt, the handler can be called immediately. To be
+ * able to check the interrupt status the hardware must already be
+ * powered back on (b44_init_hw).
+ */
rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev);
if (rc) {
- printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+ netdev_err(dev, "request_irq failed\n");
+ spin_lock_irq(&bp->lock);
+ b44_halt(bp);
+ b44_free_rings(bp);
+ spin_unlock_irq(&bp->lock);
return rc;
}
- spin_lock_irq(&bp->lock);
-
- b44_init_rings(bp);
- b44_init_hw(bp, B44_FULL_RESET);
netif_device_attach(bp->dev);
- spin_unlock_irq(&bp->lock);
b44_enable_ints(bp);
netif_wake_queue(dev);
@@ -2309,12 +2562,12 @@ static struct ssb_driver b44_ssb_driver = {
.name = DRV_MODULE_NAME,
.id_table = b44_ssb_tbl,
.probe = b44_init_one,
- .remove = __devexit_p(b44_remove_one),
+ .remove = b44_remove_one,
.suspend = b44_suspend,
.resume = b44_resume,
};
-static inline int b44_pci_init(void)
+static inline int __init b44_pci_init(void)
{
int err = 0;
#ifdef CONFIG_B44_PCI
@@ -2336,7 +2589,6 @@ static int __init b44_init(void)
int err;
/* Setup paramaters for syncing RX/TX DMA descriptors */
- dma_desc_align_mask = ~(dma_desc_align_size - 1);
dma_desc_sync_size = max_t(unsigned int, dma_desc_align_size, sizeof(struct dma_desc));
err = b44_pci_init();
diff --git a/drivers/net/b44.h b/drivers/net/ethernet/broadcom/b44.h
index 7db0c84a795..3e9c3fc7591 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/ethernet/broadcom/b44.h
@@ -97,7 +97,7 @@
#define B44_DMARX_STAT 0x021CUL /* DMA RX Current Active Desc. + Status */
#define DMARX_STAT_CDMASK 0x00000fff /* Current Descriptor Mask */
#define DMARX_STAT_SMASK 0x0000f000 /* State Mask */
-#define DMARX_STAT_SDISABLED 0x00000000 /* State Disbaled */
+#define DMARX_STAT_SDISABLED 0x00000000 /* State Disabled */
#define DMARX_STAT_SACTIVE 0x00001000 /* State Active */
#define DMARX_STAT_SIDLE 0x00002000 /* State Idle Wait */
#define DMARX_STAT_SSTOPPED 0x00003000 /* State Stopped */
@@ -280,9 +280,10 @@ struct ring_info {
dma_addr_t mapping;
};
-#define B44_MCAST_TABLE_SIZE 32
-#define B44_PHY_ADDR_NO_PHY 30
-#define B44_MDC_RATIO 5000000
+#define B44_MCAST_TABLE_SIZE 32
+#define B44_PHY_ADDR_NO_LOCAL_PHY 30 /* no local phy regs */
+#define B44_PHY_ADDR_NO_PHY 31 /* no phy present at all */
+#define B44_MDC_RATIO 5000000
#define B44_STAT_REG_DECLARE \
_B44(tx_good_octets) \
@@ -338,11 +339,15 @@ struct ring_info {
* the layout
*/
struct b44_hw_stats {
-#define _B44(x) u32 x;
+#define _B44(x) u64 x;
B44_STAT_REG_DECLARE
#undef _B44
+ struct u64_stats_sync syncp;
};
+#define B44_BOARDFLAG_ROBO 0x0010 /* Board has robo switch */
+#define B44_BOARDFLAG_ADM 0x0080 /* Board has ADMtek switch */
+
struct ssb_device;
struct b44 {
@@ -375,7 +380,7 @@ struct b44 {
#define B44_FLAG_ADV_10FULL 0x02000000
#define B44_FLAG_ADV_100HALF 0x04000000
#define B44_FLAG_ADV_100FULL 0x08000000
-#define B44_FLAG_INTERNAL_PHY 0x10000000
+#define B44_FLAG_EXTERNAL_PHY 0x10000000
#define B44_FLAG_RX_RING_HACK 0x20000000
#define B44_FLAG_TX_RING_HACK 0x40000000
#define B44_FLAG_WOL_ENABLE 0x80000000
@@ -384,7 +389,6 @@ struct b44 {
struct timer_list timer;
- struct net_device_stats stats;
struct b44_hw_stats hw_stats;
struct ssb_device *sdev;
@@ -395,7 +399,10 @@ struct b44 {
u32 rx_pending;
u32 tx_pending;
u8 phy_addr;
-
+ u8 force_copybreak;
+ struct phy_device *phydev;
+ struct mii_bus *mii_bus;
+ int old_link;
struct mii_if_info mii_if;
};
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
new file mode 100644
index 00000000000..3e8d1a88ed3
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -0,0 +1,2919 @@
+/*
+ * Driver for BCM963xx builtin Ethernet mac
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/if_vlan.h>
+
+#include <bcm63xx_dev_enet.h>
+#include "bcm63xx_enet.h"
+
+static char bcm_enet_driver_name[] = "bcm63xx_enet";
+static char bcm_enet_driver_version[] = "1.0";
+
+static int copybreak __read_mostly = 128;
+module_param(copybreak, int, 0);
+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+
+/* io registers memory shared between all devices */
+static void __iomem *bcm_enet_shared_base[3];
+
+/*
+ * io helpers to access mac registers
+ */
+static inline u32 enet_readl(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readl(priv->base + off);
+}
+
+static inline void enet_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off)
+{
+ bcm_writel(val, priv->base + off);
+}
+
+/*
+ * io helpers to access switch registers
+ */
+static inline u32 enetsw_readl(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readl(priv->base + off);
+}
+
+static inline void enetsw_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off)
+{
+ bcm_writel(val, priv->base + off);
+}
+
+static inline u16 enetsw_readw(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readw(priv->base + off);
+}
+
+static inline void enetsw_writew(struct bcm_enet_priv *priv,
+ u16 val, u32 off)
+{
+ bcm_writew(val, priv->base + off);
+}
+
+static inline u8 enetsw_readb(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readb(priv->base + off);
+}
+
+static inline void enetsw_writeb(struct bcm_enet_priv *priv,
+ u8 val, u32 off)
+{
+ bcm_writeb(val, priv->base + off);
+}
+
+
+/* io helpers to access shared registers */
+static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readl(bcm_enet_shared_base[0] + off);
+}
+
+static inline void enet_dma_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off)
+{
+ bcm_writel(val, bcm_enet_shared_base[0] + off);
+}
+
+static inline u32 enet_dmac_readl(struct bcm_enet_priv *priv, u32 off, int chan)
+{
+ return bcm_readl(bcm_enet_shared_base[1] +
+ bcm63xx_enetdmacreg(off) + chan * priv->dma_chan_width);
+}
+
+static inline void enet_dmac_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off, int chan)
+{
+ bcm_writel(val, bcm_enet_shared_base[1] +
+ bcm63xx_enetdmacreg(off) + chan * priv->dma_chan_width);
+}
+
+static inline u32 enet_dmas_readl(struct bcm_enet_priv *priv, u32 off, int chan)
+{
+ return bcm_readl(bcm_enet_shared_base[2] + off + chan * priv->dma_chan_width);
+}
+
+static inline void enet_dmas_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off, int chan)
+{
+ bcm_writel(val, bcm_enet_shared_base[2] + off + chan * priv->dma_chan_width);
+}
+
+/*
+ * write given data into mii register and wait for transfer to end
+ * with timeout (average measured transfer time is 25us)
+ */
+static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data)
+{
+ int limit;
+
+ /* make sure mii interrupt status is cleared */
+ enet_writel(priv, ENET_IR_MII, ENET_IR_REG);
+
+ enet_writel(priv, data, ENET_MIIDATA_REG);
+ wmb();
+
+ /* busy wait on mii interrupt bit, with timeout */
+ limit = 1000;
+ do {
+ if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
+ break;
+ udelay(1);
+ } while (limit-- > 0);
+
+ return (limit < 0) ? 1 : 0;
+}
+
+/*
+ * MII internal read callback
+ */
+static int bcm_enet_mdio_read(struct bcm_enet_priv *priv, int mii_id,
+ int regnum)
+{
+ u32 tmp, val;
+
+ tmp = regnum << ENET_MIIDATA_REG_SHIFT;
+ tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+ tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+ tmp |= ENET_MIIDATA_OP_READ_MASK;
+
+ if (do_mdio_op(priv, tmp))
+ return -1;
+
+ val = enet_readl(priv, ENET_MIIDATA_REG);
+ val &= 0xffff;
+ return val;
+}
+
+/*
+ * MII internal write callback
+ */
+static int bcm_enet_mdio_write(struct bcm_enet_priv *priv, int mii_id,
+ int regnum, u16 value)
+{
+ u32 tmp;
+
+ tmp = (value & 0xffff) << ENET_MIIDATA_DATA_SHIFT;
+ tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+ tmp |= regnum << ENET_MIIDATA_REG_SHIFT;
+ tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+ tmp |= ENET_MIIDATA_OP_WRITE_MASK;
+
+ (void)do_mdio_op(priv, tmp);
+ return 0;
+}
+
+/*
+ * MII read callback from phylib
+ */
+static int bcm_enet_mdio_read_phylib(struct mii_bus *bus, int mii_id,
+ int regnum)
+{
+ return bcm_enet_mdio_read(bus->priv, mii_id, regnum);
+}
+
+/*
+ * MII write callback from phylib
+ */
+static int bcm_enet_mdio_write_phylib(struct mii_bus *bus, int mii_id,
+ int regnum, u16 value)
+{
+ return bcm_enet_mdio_write(bus->priv, mii_id, regnum, value);
+}
+
+/*
+ * MII read callback from mii core
+ */
+static int bcm_enet_mdio_read_mii(struct net_device *dev, int mii_id,
+ int regnum)
+{
+ return bcm_enet_mdio_read(netdev_priv(dev), mii_id, regnum);
+}
+
+/*
+ * MII write callback from mii core
+ */
+static void bcm_enet_mdio_write_mii(struct net_device *dev, int mii_id,
+ int regnum, int value)
+{
+ bcm_enet_mdio_write(netdev_priv(dev), mii_id, regnum, value);
+}
+
+/*
+ * refill rx queue
+ */
+static int bcm_enet_refill_rx(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ while (priv->rx_desc_count < priv->rx_ring_size) {
+ struct bcm_enet_desc *desc;
+ struct sk_buff *skb;
+ dma_addr_t p;
+ int desc_idx;
+ u32 len_stat;
+
+ desc_idx = priv->rx_dirty_desc;
+ desc = &priv->rx_desc_cpu[desc_idx];
+
+ if (!priv->rx_skb[desc_idx]) {
+ skb = netdev_alloc_skb(dev, priv->rx_skb_size);
+ if (!skb)
+ break;
+ priv->rx_skb[desc_idx] = skb;
+ p = dma_map_single(&priv->pdev->dev, skb->data,
+ priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ desc->address = p;
+ }
+
+ len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
+ len_stat |= DMADESC_OWNER_MASK;
+ if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
+ len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
+ priv->rx_dirty_desc = 0;
+ } else {
+ priv->rx_dirty_desc++;
+ }
+ wmb();
+ desc->len_stat = len_stat;
+
+ priv->rx_desc_count++;
+
+ /* tell dma engine we allocated one buffer */
+ if (priv->dma_has_sram)
+ enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+ else
+ enet_dmac_writel(priv, 1, ENETDMAC_BUFALLOC, priv->rx_chan);
+ }
+
+ /* If rx ring is still empty, set a timer to try allocating
+ * again at a later time. */
+ if (priv->rx_desc_count == 0 && netif_running(dev)) {
+ dev_warn(&priv->pdev->dev, "unable to refill rx ring\n");
+ priv->rx_timeout.expires = jiffies + HZ;
+ add_timer(&priv->rx_timeout);
+ }
+
+ return 0;
+}
+
+/*
+ * timer callback to defer refill rx queue in case we're OOM
+ */
+static void bcm_enet_refill_rx_timer(unsigned long data)
+{
+ struct net_device *dev;
+ struct bcm_enet_priv *priv;
+
+ dev = (struct net_device *)data;
+ priv = netdev_priv(dev);
+
+ spin_lock(&priv->rx_lock);
+ bcm_enet_refill_rx((struct net_device *)data);
+ spin_unlock(&priv->rx_lock);
+}
+
+/*
+ * extract packet from rx queue
+ */
+static int bcm_enet_receive_queue(struct net_device *dev, int budget)
+{
+ struct bcm_enet_priv *priv;
+ struct device *kdev;
+ int processed;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+ processed = 0;
+
+ /* don't scan ring further than number of refilled
+ * descriptor */
+ if (budget > priv->rx_desc_count)
+ budget = priv->rx_desc_count;
+
+ do {
+ struct bcm_enet_desc *desc;
+ struct sk_buff *skb;
+ int desc_idx;
+ u32 len_stat;
+ unsigned int len;
+
+ desc_idx = priv->rx_curr_desc;
+ desc = &priv->rx_desc_cpu[desc_idx];
+
+ /* make sure we actually read the descriptor status at
+ * each loop */
+ rmb();
+
+ len_stat = desc->len_stat;
+
+ /* break if dma ownership belongs to hw */
+ if (len_stat & DMADESC_OWNER_MASK)
+ break;
+
+ processed++;
+ priv->rx_curr_desc++;
+ if (priv->rx_curr_desc == priv->rx_ring_size)
+ priv->rx_curr_desc = 0;
+ priv->rx_desc_count--;
+
+ /* if the packet does not have start of packet _and_
+ * end of packet flag set, then just recycle it */
+ if ((len_stat & (DMADESC_ESOP_MASK >> priv->dma_desc_shift)) !=
+ (DMADESC_ESOP_MASK >> priv->dma_desc_shift)) {
+ dev->stats.rx_dropped++;
+ continue;
+ }
+
+ /* recycle packet if it's marked as bad */
+ if (!priv->enet_is_sw &&
+ unlikely(len_stat & DMADESC_ERR_MASK)) {
+ dev->stats.rx_errors++;
+
+ if (len_stat & DMADESC_OVSIZE_MASK)
+ dev->stats.rx_length_errors++;
+ if (len_stat & DMADESC_CRC_MASK)
+ dev->stats.rx_crc_errors++;
+ if (len_stat & DMADESC_UNDER_MASK)
+ dev->stats.rx_frame_errors++;
+ if (len_stat & DMADESC_OV_MASK)
+ dev->stats.rx_fifo_errors++;
+ continue;
+ }
+
+ /* valid packet */
+ skb = priv->rx_skb[desc_idx];
+ len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT;
+ /* don't include FCS */
+ len -= 4;
+
+ if (len < copybreak) {
+ struct sk_buff *nskb;
+
+ nskb = netdev_alloc_skb_ip_align(dev, len);
+ if (!nskb) {
+ /* forget packet, just rearm desc */
+ dev->stats.rx_dropped++;
+ continue;
+ }
+
+ dma_sync_single_for_cpu(kdev, desc->address,
+ len, DMA_FROM_DEVICE);
+ memcpy(nskb->data, skb->data, len);
+ dma_sync_single_for_device(kdev, desc->address,
+ len, DMA_FROM_DEVICE);
+ skb = nskb;
+ } else {
+ dma_unmap_single(&priv->pdev->dev, desc->address,
+ priv->rx_skb_size, DMA_FROM_DEVICE);
+ priv->rx_skb[desc_idx] = NULL;
+ }
+
+ skb_put(skb, len);
+ skb->protocol = eth_type_trans(skb, dev);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
+ netif_receive_skb(skb);
+
+ } while (--budget > 0);
+
+ if (processed || !priv->rx_desc_count) {
+ bcm_enet_refill_rx(dev);
+
+ /* kick rx dma */
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ ENETDMAC_CHANCFG, priv->rx_chan);
+ }
+
+ return processed;
+}
+
+
+/*
+ * try to or force reclaim of transmitted buffers
+ */
+static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
+{
+ struct bcm_enet_priv *priv;
+ int released;
+
+ priv = netdev_priv(dev);
+ released = 0;
+
+ while (priv->tx_desc_count < priv->tx_ring_size) {
+ struct bcm_enet_desc *desc;
+ struct sk_buff *skb;
+
+ /* We run in a bh and fight against start_xmit, which
+ * is called with bh disabled */
+ spin_lock(&priv->tx_lock);
+
+ desc = &priv->tx_desc_cpu[priv->tx_dirty_desc];
+
+ if (!force && (desc->len_stat & DMADESC_OWNER_MASK)) {
+ spin_unlock(&priv->tx_lock);
+ break;
+ }
+
+ /* ensure other field of the descriptor were not read
+ * before we checked ownership */
+ rmb();
+
+ skb = priv->tx_skb[priv->tx_dirty_desc];
+ priv->tx_skb[priv->tx_dirty_desc] = NULL;
+ dma_unmap_single(&priv->pdev->dev, desc->address, skb->len,
+ DMA_TO_DEVICE);
+
+ priv->tx_dirty_desc++;
+ if (priv->tx_dirty_desc == priv->tx_ring_size)
+ priv->tx_dirty_desc = 0;
+ priv->tx_desc_count++;
+
+ spin_unlock(&priv->tx_lock);
+
+ if (desc->len_stat & DMADESC_UNDER_MASK)
+ dev->stats.tx_errors++;
+
+ dev_kfree_skb(skb);
+ released++;
+ }
+
+ if (netif_queue_stopped(dev) && released)
+ netif_wake_queue(dev);
+
+ return released;
+}
+
+/*
+ * poll func, called by network core
+ */
+static int bcm_enet_poll(struct napi_struct *napi, int budget)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+ int tx_work_done, rx_work_done;
+
+ priv = container_of(napi, struct bcm_enet_priv, napi);
+ dev = priv->net_dev;
+
+ /* ack interrupts */
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, priv->tx_chan);
+
+ /* reclaim sent skb */
+ tx_work_done = bcm_enet_tx_reclaim(dev, 0);
+
+ spin_lock(&priv->rx_lock);
+ rx_work_done = bcm_enet_receive_queue(dev, budget);
+ spin_unlock(&priv->rx_lock);
+
+ if (rx_work_done >= budget || tx_work_done > 0) {
+ /* rx/tx queue is not yet empty/clean */
+ return rx_work_done;
+ }
+
+ /* no more packet in rx/tx queue, remove device from poll
+ * queue */
+ napi_complete(napi);
+
+ /* restore rx/tx interrupt */
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->tx_chan);
+
+ return rx_work_done;
+}
+
+/*
+ * mac interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_mac(int irq, void *dev_id)
+{
+ struct net_device *dev;
+ struct bcm_enet_priv *priv;
+ u32 stat;
+
+ dev = dev_id;
+ priv = netdev_priv(dev);
+
+ stat = enet_readl(priv, ENET_IR_REG);
+ if (!(stat & ENET_IR_MIB))
+ return IRQ_NONE;
+
+ /* clear & mask interrupt */
+ enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+ enet_writel(priv, 0, ENET_IRMASK_REG);
+
+ /* read mib registers in workqueue */
+ schedule_work(&priv->mib_update_task);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * rx/tx dma interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_dma(int irq, void *dev_id)
+{
+ struct net_device *dev;
+ struct bcm_enet_priv *priv;
+
+ dev = dev_id;
+ priv = netdev_priv(dev);
+
+ /* mask rx/tx interrupts */
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
+
+ napi_schedule(&priv->napi);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * tx request callback
+ */
+static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct bcm_enet_desc *desc;
+ u32 len_stat;
+ int ret;
+
+ priv = netdev_priv(dev);
+
+ /* lock against tx reclaim */
+ spin_lock(&priv->tx_lock);
+
+ /* make sure the tx hw queue is not full, should not happen
+ * since we stop queue before it's the case */
+ if (unlikely(!priv->tx_desc_count)) {
+ netif_stop_queue(dev);
+ dev_err(&priv->pdev->dev, "xmit called with no tx desc "
+ "available?\n");
+ ret = NETDEV_TX_BUSY;
+ goto out_unlock;
+ }
+
+ /* pad small packets sent on a switch device */
+ if (priv->enet_is_sw && skb->len < 64) {
+ int needed = 64 - skb->len;
+ char *data;
+
+ if (unlikely(skb_tailroom(skb) < needed)) {
+ struct sk_buff *nskb;
+
+ nskb = skb_copy_expand(skb, 0, needed, GFP_ATOMIC);
+ if (!nskb) {
+ ret = NETDEV_TX_BUSY;
+ goto out_unlock;
+ }
+ dev_kfree_skb(skb);
+ skb = nskb;
+ }
+ data = skb_put(skb, needed);
+ memset(data, 0, needed);
+ }
+
+ /* point to the next available desc */
+ desc = &priv->tx_desc_cpu[priv->tx_curr_desc];
+ priv->tx_skb[priv->tx_curr_desc] = skb;
+
+ /* fill descriptor */
+ desc->address = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+
+ len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK;
+ len_stat |= (DMADESC_ESOP_MASK >> priv->dma_desc_shift) |
+ DMADESC_APPEND_CRC |
+ DMADESC_OWNER_MASK;
+
+ priv->tx_curr_desc++;
+ if (priv->tx_curr_desc == priv->tx_ring_size) {
+ priv->tx_curr_desc = 0;
+ len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
+ }
+ priv->tx_desc_count--;
+
+ /* dma might be already polling, make sure we update desc
+ * fields in correct order */
+ wmb();
+ desc->len_stat = len_stat;
+ wmb();
+
+ /* kick tx dma */
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ ENETDMAC_CHANCFG, priv->tx_chan);
+
+ /* stop queue if no more desc available */
+ if (!priv->tx_desc_count)
+ netif_stop_queue(dev);
+
+ dev->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ ret = NETDEV_TX_OK;
+
+out_unlock:
+ spin_unlock(&priv->tx_lock);
+ return ret;
+}
+
+/*
+ * Change the interface's mac address.
+ */
+static int bcm_enet_set_mac_address(struct net_device *dev, void *p)
+{
+ struct bcm_enet_priv *priv;
+ struct sockaddr *addr = p;
+ u32 val;
+
+ priv = netdev_priv(dev);
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+ /* use perfect match register 0 to store my mac address */
+ val = (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) |
+ (dev->dev_addr[4] << 8) | dev->dev_addr[5];
+ enet_writel(priv, val, ENET_PML_REG(0));
+
+ val = (dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+ val |= ENET_PMH_DATAVALID_MASK;
+ enet_writel(priv, val, ENET_PMH_REG(0));
+
+ return 0;
+}
+
+/*
+ * Change rx mode (promiscuous/allmulti) and update multicast list
+ */
+static void bcm_enet_set_multicast_list(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct netdev_hw_addr *ha;
+ u32 val;
+ int i;
+
+ priv = netdev_priv(dev);
+
+ val = enet_readl(priv, ENET_RXCFG_REG);
+
+ if (dev->flags & IFF_PROMISC)
+ val |= ENET_RXCFG_PROMISC_MASK;
+ else
+ val &= ~ENET_RXCFG_PROMISC_MASK;
+
+ /* only 3 perfect match registers left, first one is used for
+ * own mac address */
+ if ((dev->flags & IFF_ALLMULTI) || netdev_mc_count(dev) > 3)
+ val |= ENET_RXCFG_ALLMCAST_MASK;
+ else
+ val &= ~ENET_RXCFG_ALLMCAST_MASK;
+
+ /* no need to set perfect match registers if we catch all
+ * multicast */
+ if (val & ENET_RXCFG_ALLMCAST_MASK) {
+ enet_writel(priv, val, ENET_RXCFG_REG);
+ return;
+ }
+
+ i = 0;
+ netdev_for_each_mc_addr(ha, dev) {
+ u8 *dmi_addr;
+ u32 tmp;
+
+ if (i == 3)
+ break;
+ /* update perfect match registers */
+ dmi_addr = ha->addr;
+ tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) |
+ (dmi_addr[4] << 8) | dmi_addr[5];
+ enet_writel(priv, tmp, ENET_PML_REG(i + 1));
+
+ tmp = (dmi_addr[0] << 8 | dmi_addr[1]);
+ tmp |= ENET_PMH_DATAVALID_MASK;
+ enet_writel(priv, tmp, ENET_PMH_REG(i++ + 1));
+ }
+
+ for (; i < 3; i++) {
+ enet_writel(priv, 0, ENET_PML_REG(i + 1));
+ enet_writel(priv, 0, ENET_PMH_REG(i + 1));
+ }
+
+ enet_writel(priv, val, ENET_RXCFG_REG);
+}
+
+/*
+ * set mac duplex parameters
+ */
+static void bcm_enet_set_duplex(struct bcm_enet_priv *priv, int fullduplex)
+{
+ u32 val;
+
+ val = enet_readl(priv, ENET_TXCTL_REG);
+ if (fullduplex)
+ val |= ENET_TXCTL_FD_MASK;
+ else
+ val &= ~ENET_TXCTL_FD_MASK;
+ enet_writel(priv, val, ENET_TXCTL_REG);
+}
+
+/*
+ * set mac flow control parameters
+ */
+static void bcm_enet_set_flow(struct bcm_enet_priv *priv, int rx_en, int tx_en)
+{
+ u32 val;
+
+ /* rx flow control (pause frame handling) */
+ val = enet_readl(priv, ENET_RXCFG_REG);
+ if (rx_en)
+ val |= ENET_RXCFG_ENFLOW_MASK;
+ else
+ val &= ~ENET_RXCFG_ENFLOW_MASK;
+ enet_writel(priv, val, ENET_RXCFG_REG);
+
+ if (!priv->dma_has_sram)
+ return;
+
+ /* tx flow control (pause frame generation) */
+ val = enet_dma_readl(priv, ENETDMA_CFG_REG);
+ if (tx_en)
+ val |= ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+ else
+ val &= ~ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+ enet_dma_writel(priv, val, ENETDMA_CFG_REG);
+}
+
+/*
+ * link changed callback (from phylib)
+ */
+static void bcm_enet_adjust_phy_link(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct phy_device *phydev;
+ int status_changed;
+
+ priv = netdev_priv(dev);
+ phydev = priv->phydev;
+ status_changed = 0;
+
+ if (priv->old_link != phydev->link) {
+ status_changed = 1;
+ priv->old_link = phydev->link;
+ }
+
+ /* reflect duplex change in mac configuration */
+ if (phydev->link && phydev->duplex != priv->old_duplex) {
+ bcm_enet_set_duplex(priv,
+ (phydev->duplex == DUPLEX_FULL) ? 1 : 0);
+ status_changed = 1;
+ priv->old_duplex = phydev->duplex;
+ }
+
+ /* enable flow control if remote advertise it (trust phylib to
+ * check that duplex is full */
+ if (phydev->link && phydev->pause != priv->old_pause) {
+ int rx_pause_en, tx_pause_en;
+
+ if (phydev->pause) {
+ /* pause was advertised by lpa and us */
+ rx_pause_en = 1;
+ tx_pause_en = 1;
+ } else if (!priv->pause_auto) {
+ /* pause setting overrided by user */
+ rx_pause_en = priv->pause_rx;
+ tx_pause_en = priv->pause_tx;
+ } else {
+ rx_pause_en = 0;
+ tx_pause_en = 0;
+ }
+
+ bcm_enet_set_flow(priv, rx_pause_en, tx_pause_en);
+ status_changed = 1;
+ priv->old_pause = phydev->pause;
+ }
+
+ if (status_changed) {
+ pr_info("%s: link %s", dev->name, phydev->link ?
+ "UP" : "DOWN");
+ if (phydev->link)
+ pr_cont(" - %d/%s - flow control %s", phydev->speed,
+ DUPLEX_FULL == phydev->duplex ? "full" : "half",
+ phydev->pause == 1 ? "rx&tx" : "off");
+
+ pr_cont("\n");
+ }
+}
+
+/*
+ * link changed callback (if phylib is not used)
+ */
+static void bcm_enet_adjust_link(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ bcm_enet_set_duplex(priv, priv->force_duplex_full);
+ bcm_enet_set_flow(priv, priv->pause_rx, priv->pause_tx);
+ netif_carrier_on(dev);
+
+ pr_info("%s: link forced UP - %d/%s - flow control %s/%s\n",
+ dev->name,
+ priv->force_speed_100 ? 100 : 10,
+ priv->force_duplex_full ? "full" : "half",
+ priv->pause_rx ? "rx" : "off",
+ priv->pause_tx ? "tx" : "off");
+}
+
+/*
+ * open callback, allocate dma rings & buffers and start rx operation
+ */
+static int bcm_enet_open(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct sockaddr addr;
+ struct device *kdev;
+ struct phy_device *phydev;
+ int i, ret;
+ unsigned int size;
+ char phy_id[MII_BUS_ID_SIZE + 3];
+ void *p;
+ u32 val;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+
+ if (priv->has_phy) {
+ /* connect to PHY */
+ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ priv->mii_bus->id, priv->phy_id);
+
+ phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link,
+ PHY_INTERFACE_MODE_MII);
+
+ if (IS_ERR(phydev)) {
+ dev_err(kdev, "could not attach to PHY\n");
+ return PTR_ERR(phydev);
+ }
+
+ /* mask with MAC supported features */
+ phydev->supported &= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_MII);
+ phydev->advertising = phydev->supported;
+
+ if (priv->pause_auto && priv->pause_rx && priv->pause_tx)
+ phydev->advertising |= SUPPORTED_Pause;
+ else
+ phydev->advertising &= ~SUPPORTED_Pause;
+
+ dev_info(kdev, "attached PHY at address %d [%s]\n",
+ phydev->addr, phydev->drv->name);
+
+ priv->old_link = 0;
+ priv->old_duplex = -1;
+ priv->old_pause = -1;
+ priv->phydev = phydev;
+ }
+
+ /* mask all interrupts and request them */
+ enet_writel(priv, 0, ENET_IRMASK_REG);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
+
+ ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
+ if (ret)
+ goto out_phy_disconnect;
+
+ ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, 0,
+ dev->name, dev);
+ if (ret)
+ goto out_freeirq;
+
+ ret = request_irq(priv->irq_tx, bcm_enet_isr_dma,
+ 0, dev->name, dev);
+ if (ret)
+ goto out_freeirq_rx;
+
+ /* initialize perfect match registers */
+ for (i = 0; i < 4; i++) {
+ enet_writel(priv, 0, ENET_PML_REG(i));
+ enet_writel(priv, 0, ENET_PMH_REG(i));
+ }
+
+ /* write device mac address */
+ memcpy(addr.sa_data, dev->dev_addr, ETH_ALEN);
+ bcm_enet_set_mac_address(dev, &addr);
+
+ /* allocate rx dma ring */
+ size = priv->rx_ring_size * sizeof(struct bcm_enet_desc);
+ p = dma_zalloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL);
+ if (!p) {
+ ret = -ENOMEM;
+ goto out_freeirq_tx;
+ }
+
+ priv->rx_desc_alloc_size = size;
+ priv->rx_desc_cpu = p;
+
+ /* allocate tx dma ring */
+ size = priv->tx_ring_size * sizeof(struct bcm_enet_desc);
+ p = dma_zalloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL);
+ if (!p) {
+ ret = -ENOMEM;
+ goto out_free_rx_ring;
+ }
+
+ priv->tx_desc_alloc_size = size;
+ priv->tx_desc_cpu = p;
+
+ priv->tx_skb = kcalloc(priv->tx_ring_size, sizeof(struct sk_buff *),
+ GFP_KERNEL);
+ if (!priv->tx_skb) {
+ ret = -ENOMEM;
+ goto out_free_tx_ring;
+ }
+
+ priv->tx_desc_count = priv->tx_ring_size;
+ priv->tx_dirty_desc = 0;
+ priv->tx_curr_desc = 0;
+ spin_lock_init(&priv->tx_lock);
+
+ /* init & fill rx ring with skbs */
+ priv->rx_skb = kcalloc(priv->rx_ring_size, sizeof(struct sk_buff *),
+ GFP_KERNEL);
+ if (!priv->rx_skb) {
+ ret = -ENOMEM;
+ goto out_free_tx_skb;
+ }
+
+ priv->rx_desc_count = 0;
+ priv->rx_dirty_desc = 0;
+ priv->rx_curr_desc = 0;
+
+ /* initialize flow control buffer allocation */
+ if (priv->dma_has_sram)
+ enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+ ENETDMA_BUFALLOC_REG(priv->rx_chan));
+ else
+ enet_dmac_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+ ENETDMAC_BUFALLOC, priv->rx_chan);
+
+ if (bcm_enet_refill_rx(dev)) {
+ dev_err(kdev, "cannot allocate rx skb queue\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* write rx & tx ring addresses */
+ if (priv->dma_has_sram) {
+ enet_dmas_writel(priv, priv->rx_desc_dma,
+ ENETDMAS_RSTART_REG, priv->rx_chan);
+ enet_dmas_writel(priv, priv->tx_desc_dma,
+ ENETDMAS_RSTART_REG, priv->tx_chan);
+ } else {
+ enet_dmac_writel(priv, priv->rx_desc_dma,
+ ENETDMAC_RSTART, priv->rx_chan);
+ enet_dmac_writel(priv, priv->tx_desc_dma,
+ ENETDMAC_RSTART, priv->tx_chan);
+ }
+
+ /* clear remaining state ram for rx & tx channel */
+ if (priv->dma_has_sram) {
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->rx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->tx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->rx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->tx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->rx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->tx_chan);
+ } else {
+ enet_dmac_writel(priv, 0, ENETDMAC_FC, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_FC, priv->tx_chan);
+ }
+
+ /* set max rx/tx length */
+ enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG);
+ enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG);
+
+ /* set dma maximum burst len */
+ enet_dmac_writel(priv, priv->dma_maxburst,
+ ENETDMAC_MAXBURST, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_maxburst,
+ ENETDMAC_MAXBURST, priv->tx_chan);
+
+ /* set correct transmit fifo watermark */
+ enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG);
+
+ /* set flow control low/high threshold to 1/3 / 2/3 */
+ if (priv->dma_has_sram) {
+ val = priv->rx_ring_size / 3;
+ enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
+ val = (priv->rx_ring_size * 2) / 3;
+ enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+ } else {
+ enet_dmac_writel(priv, 5, ENETDMAC_FC, priv->rx_chan);
+ enet_dmac_writel(priv, priv->rx_ring_size, ENETDMAC_LEN, priv->rx_chan);
+ enet_dmac_writel(priv, priv->tx_ring_size, ENETDMAC_LEN, priv->tx_chan);
+ }
+
+ /* all set, enable mac and interrupts, start dma engine and
+ * kick rx dma channel */
+ wmb();
+ val = enet_readl(priv, ENET_CTL_REG);
+ val |= ENET_CTL_ENABLE_MASK;
+ enet_writel(priv, val, ENET_CTL_REG);
+ enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ ENETDMAC_CHANCFG, priv->rx_chan);
+
+ /* watch "mib counters about to overflow" interrupt */
+ enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+ enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+
+ /* watch "packet transferred" interrupt in rx and tx */
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, priv->tx_chan);
+
+ /* make sure we enable napi before rx interrupt */
+ napi_enable(&priv->napi);
+
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->tx_chan);
+
+ if (priv->has_phy)
+ phy_start(priv->phydev);
+ else
+ bcm_enet_adjust_link(dev);
+
+ netif_start_queue(dev);
+ return 0;
+
+out:
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct bcm_enet_desc *desc;
+
+ if (!priv->rx_skb[i])
+ continue;
+
+ desc = &priv->rx_desc_cpu[i];
+ dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_skb[i]);
+ }
+ kfree(priv->rx_skb);
+
+out_free_tx_skb:
+ kfree(priv->tx_skb);
+
+out_free_tx_ring:
+ dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+ priv->tx_desc_cpu, priv->tx_desc_dma);
+
+out_free_rx_ring:
+ dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+ priv->rx_desc_cpu, priv->rx_desc_dma);
+
+out_freeirq_tx:
+ free_irq(priv->irq_tx, dev);
+
+out_freeirq_rx:
+ free_irq(priv->irq_rx, dev);
+
+out_freeirq:
+ free_irq(dev->irq, dev);
+
+out_phy_disconnect:
+ phy_disconnect(priv->phydev);
+
+ return ret;
+}
+
+/*
+ * disable mac
+ */
+static void bcm_enet_disable_mac(struct bcm_enet_priv *priv)
+{
+ int limit;
+ u32 val;
+
+ val = enet_readl(priv, ENET_CTL_REG);
+ val |= ENET_CTL_DISABLE_MASK;
+ enet_writel(priv, val, ENET_CTL_REG);
+
+ limit = 1000;
+ do {
+ u32 val;
+
+ val = enet_readl(priv, ENET_CTL_REG);
+ if (!(val & ENET_CTL_DISABLE_MASK))
+ break;
+ udelay(1);
+ } while (limit--);
+}
+
+/*
+ * disable dma in given channel
+ */
+static void bcm_enet_disable_dma(struct bcm_enet_priv *priv, int chan)
+{
+ int limit;
+
+ enet_dmac_writel(priv, 0, ENETDMAC_CHANCFG, chan);
+
+ limit = 1000;
+ do {
+ u32 val;
+
+ val = enet_dmac_readl(priv, ENETDMAC_CHANCFG, chan);
+ if (!(val & ENETDMAC_CHANCFG_EN_MASK))
+ break;
+ udelay(1);
+ } while (limit--);
+}
+
+/*
+ * stop callback
+ */
+static int bcm_enet_stop(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct device *kdev;
+ int i;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+ if (priv->has_phy)
+ phy_stop(priv->phydev);
+ del_timer_sync(&priv->rx_timeout);
+
+ /* mask all interrupts */
+ enet_writel(priv, 0, ENET_IRMASK_REG);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
+
+ /* make sure no mib update is scheduled */
+ cancel_work_sync(&priv->mib_update_task);
+
+ /* disable dma & mac */
+ bcm_enet_disable_dma(priv, priv->tx_chan);
+ bcm_enet_disable_dma(priv, priv->rx_chan);
+ bcm_enet_disable_mac(priv);
+
+ /* force reclaim of all tx buffers */
+ bcm_enet_tx_reclaim(dev, 1);
+
+ /* free the rx skb ring */
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct bcm_enet_desc *desc;
+
+ if (!priv->rx_skb[i])
+ continue;
+
+ desc = &priv->rx_desc_cpu[i];
+ dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_skb[i]);
+ }
+
+ /* free remaining allocated memory */
+ kfree(priv->rx_skb);
+ kfree(priv->tx_skb);
+ dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+ priv->rx_desc_cpu, priv->rx_desc_dma);
+ dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+ priv->tx_desc_cpu, priv->tx_desc_dma);
+ free_irq(priv->irq_tx, dev);
+ free_irq(priv->irq_rx, dev);
+ free_irq(dev->irq, dev);
+
+ /* release phy */
+ if (priv->has_phy) {
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
+
+ return 0;
+}
+
+/*
+ * ethtool callbacks
+ */
+struct bcm_enet_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int stat_offset;
+ int mib_reg;
+};
+
+#define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m), \
+ offsetof(struct bcm_enet_priv, m)
+#define DEV_STAT(m) sizeof(((struct net_device_stats *)0)->m), \
+ offsetof(struct net_device_stats, m)
+
+static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = {
+ { "rx_packets", DEV_STAT(rx_packets), -1 },
+ { "tx_packets", DEV_STAT(tx_packets), -1 },
+ { "rx_bytes", DEV_STAT(rx_bytes), -1 },
+ { "tx_bytes", DEV_STAT(tx_bytes), -1 },
+ { "rx_errors", DEV_STAT(rx_errors), -1 },
+ { "tx_errors", DEV_STAT(tx_errors), -1 },
+ { "rx_dropped", DEV_STAT(rx_dropped), -1 },
+ { "tx_dropped", DEV_STAT(tx_dropped), -1 },
+
+ { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS},
+ { "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS },
+ { "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETH_MIB_RX_BRDCAST },
+ { "rx_multicast", GEN_STAT(mib.rx_mult), ETH_MIB_RX_MULT },
+ { "rx_64_octets", GEN_STAT(mib.rx_64), ETH_MIB_RX_64 },
+ { "rx_65_127_oct", GEN_STAT(mib.rx_65_127), ETH_MIB_RX_65_127 },
+ { "rx_128_255_oct", GEN_STAT(mib.rx_128_255), ETH_MIB_RX_128_255 },
+ { "rx_256_511_oct", GEN_STAT(mib.rx_256_511), ETH_MIB_RX_256_511 },
+ { "rx_512_1023_oct", GEN_STAT(mib.rx_512_1023), ETH_MIB_RX_512_1023 },
+ { "rx_1024_max_oct", GEN_STAT(mib.rx_1024_max), ETH_MIB_RX_1024_MAX },
+ { "rx_jabber", GEN_STAT(mib.rx_jab), ETH_MIB_RX_JAB },
+ { "rx_oversize", GEN_STAT(mib.rx_ovr), ETH_MIB_RX_OVR },
+ { "rx_fragment", GEN_STAT(mib.rx_frag), ETH_MIB_RX_FRAG },
+ { "rx_dropped", GEN_STAT(mib.rx_drop), ETH_MIB_RX_DROP },
+ { "rx_crc_align", GEN_STAT(mib.rx_crc_align), ETH_MIB_RX_CRC_ALIGN },
+ { "rx_undersize", GEN_STAT(mib.rx_und), ETH_MIB_RX_UND },
+ { "rx_crc", GEN_STAT(mib.rx_crc), ETH_MIB_RX_CRC },
+ { "rx_align", GEN_STAT(mib.rx_align), ETH_MIB_RX_ALIGN },
+ { "rx_symbol_error", GEN_STAT(mib.rx_sym), ETH_MIB_RX_SYM },
+ { "rx_pause", GEN_STAT(mib.rx_pause), ETH_MIB_RX_PAUSE },
+ { "rx_control", GEN_STAT(mib.rx_cntrl), ETH_MIB_RX_CNTRL },
+
+ { "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETH_MIB_TX_GD_OCTETS },
+ { "tx_good_pkts", GEN_STAT(mib.tx_gd_pkts), ETH_MIB_TX_GD_PKTS },
+ { "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETH_MIB_TX_BRDCAST },
+ { "tx_multicast", GEN_STAT(mib.tx_mult), ETH_MIB_TX_MULT },
+ { "tx_64_oct", GEN_STAT(mib.tx_64), ETH_MIB_TX_64 },
+ { "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETH_MIB_TX_65_127 },
+ { "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETH_MIB_TX_128_255 },
+ { "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETH_MIB_TX_256_511 },
+ { "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETH_MIB_TX_512_1023},
+ { "tx_1024_max_oct", GEN_STAT(mib.tx_1024_max), ETH_MIB_TX_1024_MAX },
+ { "tx_jabber", GEN_STAT(mib.tx_jab), ETH_MIB_TX_JAB },
+ { "tx_oversize", GEN_STAT(mib.tx_ovr), ETH_MIB_TX_OVR },
+ { "tx_fragment", GEN_STAT(mib.tx_frag), ETH_MIB_TX_FRAG },
+ { "tx_underrun", GEN_STAT(mib.tx_underrun), ETH_MIB_TX_UNDERRUN },
+ { "tx_collisions", GEN_STAT(mib.tx_col), ETH_MIB_TX_COL },
+ { "tx_single_collision", GEN_STAT(mib.tx_1_col), ETH_MIB_TX_1_COL },
+ { "tx_multiple_collision", GEN_STAT(mib.tx_m_col), ETH_MIB_TX_M_COL },
+ { "tx_excess_collision", GEN_STAT(mib.tx_ex_col), ETH_MIB_TX_EX_COL },
+ { "tx_late_collision", GEN_STAT(mib.tx_late), ETH_MIB_TX_LATE },
+ { "tx_deferred", GEN_STAT(mib.tx_def), ETH_MIB_TX_DEF },
+ { "tx_carrier_sense", GEN_STAT(mib.tx_crs), ETH_MIB_TX_CRS },
+ { "tx_pause", GEN_STAT(mib.tx_pause), ETH_MIB_TX_PAUSE },
+
+};
+
+#define BCM_ENET_STATS_LEN ARRAY_SIZE(bcm_enet_gstrings_stats)
+
+static const u32 unused_mib_regs[] = {
+ ETH_MIB_TX_ALL_OCTETS,
+ ETH_MIB_TX_ALL_PKTS,
+ ETH_MIB_RX_ALL_OCTETS,
+ ETH_MIB_RX_ALL_PKTS,
+};
+
+
+static void bcm_enet_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strlcpy(drvinfo->driver, bcm_enet_driver_name, sizeof(drvinfo->driver));
+ strlcpy(drvinfo->version, bcm_enet_driver_version,
+ sizeof(drvinfo->version));
+ strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+ strlcpy(drvinfo->bus_info, "bcm63xx", sizeof(drvinfo->bus_info));
+ drvinfo->n_stats = BCM_ENET_STATS_LEN;
+}
+
+static int bcm_enet_get_sset_count(struct net_device *netdev,
+ int string_set)
+{
+ switch (string_set) {
+ case ETH_SS_STATS:
+ return BCM_ENET_STATS_LEN;
+ default:
+ return -EINVAL;
+ }
+}
+
+static void bcm_enet_get_strings(struct net_device *netdev,
+ u32 stringset, u8 *data)
+{
+ int i;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+ memcpy(data + i * ETH_GSTRING_LEN,
+ bcm_enet_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ }
+ break;
+ }
+}
+
+static void update_mib_counters(struct bcm_enet_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+ const struct bcm_enet_stats *s;
+ u32 val;
+ char *p;
+
+ s = &bcm_enet_gstrings_stats[i];
+ if (s->mib_reg == -1)
+ continue;
+
+ val = enet_readl(priv, ENET_MIB_REG(s->mib_reg));
+ p = (char *)priv + s->stat_offset;
+
+ if (s->sizeof_stat == sizeof(u64))
+ *(u64 *)p += val;
+ else
+ *(u32 *)p += val;
+ }
+
+ /* also empty unused mib counters to make sure mib counter
+ * overflow interrupt is cleared */
+ for (i = 0; i < ARRAY_SIZE(unused_mib_regs); i++)
+ (void)enet_readl(priv, ENET_MIB_REG(unused_mib_regs[i]));
+}
+
+static void bcm_enet_update_mib_counters_defer(struct work_struct *t)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = container_of(t, struct bcm_enet_priv, mib_update_task);
+ mutex_lock(&priv->mib_update_lock);
+ update_mib_counters(priv);
+ mutex_unlock(&priv->mib_update_lock);
+
+ /* reenable mib interrupt */
+ if (netif_running(priv->net_dev))
+ enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+}
+
+static void bcm_enet_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct bcm_enet_priv *priv;
+ int i;
+
+ priv = netdev_priv(netdev);
+
+ mutex_lock(&priv->mib_update_lock);
+ update_mib_counters(priv);
+
+ for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+ const struct bcm_enet_stats *s;
+ char *p;
+
+ s = &bcm_enet_gstrings_stats[i];
+ if (s->mib_reg == -1)
+ p = (char *)&netdev->stats;
+ else
+ p = (char *)priv;
+ p += s->stat_offset;
+ data[i] = (s->sizeof_stat == sizeof(u64)) ?
+ *(u64 *)p : *(u32 *)p;
+ }
+ mutex_unlock(&priv->mib_update_lock);
+}
+
+static int bcm_enet_nway_reset(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return genphy_restart_aneg(priv->phydev);
+ }
+
+ return -EOPNOTSUPP;
+}
+
+static int bcm_enet_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ cmd->maxrxpkt = 0;
+ cmd->maxtxpkt = 0;
+
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return phy_ethtool_gset(priv->phydev, cmd);
+ } else {
+ cmd->autoneg = 0;
+ ethtool_cmd_speed_set(cmd, ((priv->force_speed_100)
+ ? SPEED_100 : SPEED_10));
+ cmd->duplex = (priv->force_duplex_full) ?
+ DUPLEX_FULL : DUPLEX_HALF;
+ cmd->supported = ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full;
+ cmd->advertising = 0;
+ cmd->port = PORT_MII;
+ cmd->transceiver = XCVR_EXTERNAL;
+ }
+ return 0;
+}
+
+static int bcm_enet_set_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return phy_ethtool_sset(priv->phydev, cmd);
+ } else {
+
+ if (cmd->autoneg ||
+ (cmd->speed != SPEED_100 && cmd->speed != SPEED_10) ||
+ cmd->port != PORT_MII)
+ return -EINVAL;
+
+ priv->force_speed_100 = (cmd->speed == SPEED_100) ? 1 : 0;
+ priv->force_duplex_full = (cmd->duplex == DUPLEX_FULL) ? 1 : 0;
+
+ if (netif_running(dev))
+ bcm_enet_adjust_link(dev);
+ return 0;
+ }
+}
+
+static void bcm_enet_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ /* rx/tx ring is actually only limited by memory */
+ ering->rx_max_pending = 8192;
+ ering->tx_max_pending = 8192;
+ ering->rx_pending = priv->rx_ring_size;
+ ering->tx_pending = priv->tx_ring_size;
+}
+
+static int bcm_enet_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bcm_enet_priv *priv;
+ int was_running;
+
+ priv = netdev_priv(dev);
+
+ was_running = 0;
+ if (netif_running(dev)) {
+ bcm_enet_stop(dev);
+ was_running = 1;
+ }
+
+ priv->rx_ring_size = ering->rx_pending;
+ priv->tx_ring_size = ering->tx_pending;
+
+ if (was_running) {
+ int err;
+
+ err = bcm_enet_open(dev);
+ if (err)
+ dev_close(dev);
+ else
+ bcm_enet_set_multicast_list(dev);
+ }
+ return 0;
+}
+
+static void bcm_enet_get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *ecmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ ecmd->autoneg = priv->pause_auto;
+ ecmd->rx_pause = priv->pause_rx;
+ ecmd->tx_pause = priv->pause_tx;
+}
+
+static int bcm_enet_set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *ecmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ if (priv->has_phy) {
+ if (ecmd->autoneg && (ecmd->rx_pause != ecmd->tx_pause)) {
+ /* asymetric pause mode not supported,
+ * actually possible but integrated PHY has RO
+ * asym_pause bit */
+ return -EINVAL;
+ }
+ } else {
+ /* no pause autoneg on direct mii connection */
+ if (ecmd->autoneg)
+ return -EINVAL;
+ }
+
+ priv->pause_auto = ecmd->autoneg;
+ priv->pause_rx = ecmd->rx_pause;
+ priv->pause_tx = ecmd->tx_pause;
+
+ return 0;
+}
+
+static const struct ethtool_ops bcm_enet_ethtool_ops = {
+ .get_strings = bcm_enet_get_strings,
+ .get_sset_count = bcm_enet_get_sset_count,
+ .get_ethtool_stats = bcm_enet_get_ethtool_stats,
+ .nway_reset = bcm_enet_nway_reset,
+ .get_settings = bcm_enet_get_settings,
+ .set_settings = bcm_enet_set_settings,
+ .get_drvinfo = bcm_enet_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_ringparam = bcm_enet_get_ringparam,
+ .set_ringparam = bcm_enet_set_ringparam,
+ .get_pauseparam = bcm_enet_get_pauseparam,
+ .set_pauseparam = bcm_enet_set_pauseparam,
+};
+
+static int bcm_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return phy_mii_ioctl(priv->phydev, rq, cmd);
+ } else {
+ struct mii_if_info mii;
+
+ mii.dev = dev;
+ mii.mdio_read = bcm_enet_mdio_read_mii;
+ mii.mdio_write = bcm_enet_mdio_write_mii;
+ mii.phy_id = 0;
+ mii.phy_id_mask = 0x3f;
+ mii.reg_num_mask = 0x1f;
+ return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL);
+ }
+}
+
+/*
+ * calculate actual hardware mtu
+ */
+static int compute_hw_mtu(struct bcm_enet_priv *priv, int mtu)
+{
+ int actual_mtu;
+
+ actual_mtu = mtu;
+
+ /* add ethernet header + vlan tag size */
+ actual_mtu += VLAN_ETH_HLEN;
+
+ if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU)
+ return -EINVAL;
+
+ /*
+ * setup maximum size before we get overflow mark in
+ * descriptor, note that this will not prevent reception of
+ * big frames, they will be split into multiple buffers
+ * anyway
+ */
+ priv->hw_mtu = actual_mtu;
+
+ /*
+ * align rx buffer size to dma burst len, account FCS since
+ * it's appended
+ */
+ priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN,
+ priv->dma_maxburst * 4);
+ return 0;
+}
+
+/*
+ * adjust mtu, can't be called while device is running
+ */
+static int bcm_enet_change_mtu(struct net_device *dev, int new_mtu)
+{
+ int ret;
+
+ if (netif_running(dev))
+ return -EBUSY;
+
+ ret = compute_hw_mtu(netdev_priv(dev), new_mtu);
+ if (ret)
+ return ret;
+ dev->mtu = new_mtu;
+ return 0;
+}
+
+/*
+ * preinit hardware to allow mii operation while device is down
+ */
+static void bcm_enet_hw_preinit(struct bcm_enet_priv *priv)
+{
+ u32 val;
+ int limit;
+
+ /* make sure mac is disabled */
+ bcm_enet_disable_mac(priv);
+
+ /* soft reset mac */
+ val = ENET_CTL_SRESET_MASK;
+ enet_writel(priv, val, ENET_CTL_REG);
+ wmb();
+
+ limit = 1000;
+ do {
+ val = enet_readl(priv, ENET_CTL_REG);
+ if (!(val & ENET_CTL_SRESET_MASK))
+ break;
+ udelay(1);
+ } while (limit--);
+
+ /* select correct mii interface */
+ val = enet_readl(priv, ENET_CTL_REG);
+ if (priv->use_external_mii)
+ val |= ENET_CTL_EPHYSEL_MASK;
+ else
+ val &= ~ENET_CTL_EPHYSEL_MASK;
+ enet_writel(priv, val, ENET_CTL_REG);
+
+ /* turn on mdc clock */
+ enet_writel(priv, (0x1f << ENET_MIISC_MDCFREQDIV_SHIFT) |
+ ENET_MIISC_PREAMBLEEN_MASK, ENET_MIISC_REG);
+
+ /* set mib counters to self-clear when read */
+ val = enet_readl(priv, ENET_MIBCTL_REG);
+ val |= ENET_MIBCTL_RDCLEAR_MASK;
+ enet_writel(priv, val, ENET_MIBCTL_REG);
+}
+
+static const struct net_device_ops bcm_enet_ops = {
+ .ndo_open = bcm_enet_open,
+ .ndo_stop = bcm_enet_stop,
+ .ndo_start_xmit = bcm_enet_start_xmit,
+ .ndo_set_mac_address = bcm_enet_set_mac_address,
+ .ndo_set_rx_mode = bcm_enet_set_multicast_list,
+ .ndo_do_ioctl = bcm_enet_ioctl,
+ .ndo_change_mtu = bcm_enet_change_mtu,
+};
+
+/*
+ * allocate netdevice, request register memory and register device.
+ */
+static int bcm_enet_probe(struct platform_device *pdev)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+ struct bcm63xx_enet_platform_data *pd;
+ struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx;
+ struct mii_bus *bus;
+ const char *clk_name;
+ int i, ret;
+
+ /* stop if shared driver failed, assume driver->probe will be
+ * called in the same order we register devices (correct ?) */
+ if (!bcm_enet_shared_base[0])
+ return -ENODEV;
+
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
+ if (!res_irq || !res_irq_rx || !res_irq_tx)
+ return -ENODEV;
+
+ ret = 0;
+ dev = alloc_etherdev(sizeof(*priv));
+ if (!dev)
+ return -ENOMEM;
+ priv = netdev_priv(dev);
+
+ priv->enet_is_sw = false;
+ priv->dma_maxburst = BCMENET_DMA_MAXBURST;
+
+ ret = compute_hw_mtu(priv, dev->mtu);
+ if (ret)
+ goto out;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->base = devm_ioremap_resource(&pdev->dev, res_mem);
+ if (IS_ERR(priv->base)) {
+ ret = PTR_ERR(priv->base);
+ goto out;
+ }
+
+ dev->irq = priv->irq = res_irq->start;
+ priv->irq_rx = res_irq_rx->start;
+ priv->irq_tx = res_irq_tx->start;
+ priv->mac_id = pdev->id;
+
+ /* get rx & tx dma channel id for this mac */
+ if (priv->mac_id == 0) {
+ priv->rx_chan = 0;
+ priv->tx_chan = 1;
+ clk_name = "enet0";
+ } else {
+ priv->rx_chan = 2;
+ priv->tx_chan = 3;
+ clk_name = "enet1";
+ }
+
+ priv->mac_clk = clk_get(&pdev->dev, clk_name);
+ if (IS_ERR(priv->mac_clk)) {
+ ret = PTR_ERR(priv->mac_clk);
+ goto out;
+ }
+ clk_prepare_enable(priv->mac_clk);
+
+ /* initialize default and fetch platform data */
+ priv->rx_ring_size = BCMENET_DEF_RX_DESC;
+ priv->tx_ring_size = BCMENET_DEF_TX_DESC;
+
+ pd = dev_get_platdata(&pdev->dev);
+ if (pd) {
+ memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN);
+ priv->has_phy = pd->has_phy;
+ priv->phy_id = pd->phy_id;
+ priv->has_phy_interrupt = pd->has_phy_interrupt;
+ priv->phy_interrupt = pd->phy_interrupt;
+ priv->use_external_mii = !pd->use_internal_phy;
+ priv->pause_auto = pd->pause_auto;
+ priv->pause_rx = pd->pause_rx;
+ priv->pause_tx = pd->pause_tx;
+ priv->force_duplex_full = pd->force_duplex_full;
+ priv->force_speed_100 = pd->force_speed_100;
+ priv->dma_chan_en_mask = pd->dma_chan_en_mask;
+ priv->dma_chan_int_mask = pd->dma_chan_int_mask;
+ priv->dma_chan_width = pd->dma_chan_width;
+ priv->dma_has_sram = pd->dma_has_sram;
+ priv->dma_desc_shift = pd->dma_desc_shift;
+ }
+
+ if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) {
+ /* using internal PHY, enable clock */
+ priv->phy_clk = clk_get(&pdev->dev, "ephy");
+ if (IS_ERR(priv->phy_clk)) {
+ ret = PTR_ERR(priv->phy_clk);
+ priv->phy_clk = NULL;
+ goto out_put_clk_mac;
+ }
+ clk_prepare_enable(priv->phy_clk);
+ }
+
+ /* do minimal hardware init to be able to probe mii bus */
+ bcm_enet_hw_preinit(priv);
+
+ /* MII bus registration */
+ if (priv->has_phy) {
+
+ priv->mii_bus = mdiobus_alloc();
+ if (!priv->mii_bus) {
+ ret = -ENOMEM;
+ goto out_uninit_hw;
+ }
+
+ bus = priv->mii_bus;
+ bus->name = "bcm63xx_enet MII bus";
+ bus->parent = &pdev->dev;
+ bus->priv = priv;
+ bus->read = bcm_enet_mdio_read_phylib;
+ bus->write = bcm_enet_mdio_write_phylib;
+ sprintf(bus->id, "%s-%d", pdev->name, priv->mac_id);
+
+ /* only probe bus where we think the PHY is, because
+ * the mdio read operation return 0 instead of 0xffff
+ * if a slave is not present on hw */
+ bus->phy_mask = ~(1 << priv->phy_id);
+
+ bus->irq = devm_kzalloc(&pdev->dev, sizeof(int) * PHY_MAX_ADDR,
+ GFP_KERNEL);
+ if (!bus->irq) {
+ ret = -ENOMEM;
+ goto out_free_mdio;
+ }
+
+ if (priv->has_phy_interrupt)
+ bus->irq[priv->phy_id] = priv->phy_interrupt;
+ else
+ bus->irq[priv->phy_id] = PHY_POLL;
+
+ ret = mdiobus_register(bus);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to register mdio bus\n");
+ goto out_free_mdio;
+ }
+ } else {
+
+ /* run platform code to initialize PHY device */
+ if (pd->mii_config &&
+ pd->mii_config(dev, 1, bcm_enet_mdio_read_mii,
+ bcm_enet_mdio_write_mii)) {
+ dev_err(&pdev->dev, "unable to configure mdio bus\n");
+ goto out_uninit_hw;
+ }
+ }
+
+ spin_lock_init(&priv->rx_lock);
+
+ /* init rx timeout (used for oom) */
+ init_timer(&priv->rx_timeout);
+ priv->rx_timeout.function = bcm_enet_refill_rx_timer;
+ priv->rx_timeout.data = (unsigned long)dev;
+
+ /* init the mib update lock&work */
+ mutex_init(&priv->mib_update_lock);
+ INIT_WORK(&priv->mib_update_task, bcm_enet_update_mib_counters_defer);
+
+ /* zero mib counters */
+ for (i = 0; i < ENET_MIB_REG_COUNT; i++)
+ enet_writel(priv, 0, ENET_MIB_REG(i));
+
+ /* register netdevice */
+ dev->netdev_ops = &bcm_enet_ops;
+ netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
+
+ dev->ethtool_ops = &bcm_enet_ethtool_ops;
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ ret = register_netdev(dev);
+ if (ret)
+ goto out_unregister_mdio;
+
+ netif_carrier_off(dev);
+ platform_set_drvdata(pdev, dev);
+ priv->pdev = pdev;
+ priv->net_dev = dev;
+
+ return 0;
+
+out_unregister_mdio:
+ if (priv->mii_bus)
+ mdiobus_unregister(priv->mii_bus);
+
+out_free_mdio:
+ if (priv->mii_bus)
+ mdiobus_free(priv->mii_bus);
+
+out_uninit_hw:
+ /* turn off mdc clock */
+ enet_writel(priv, 0, ENET_MIISC_REG);
+ if (priv->phy_clk) {
+ clk_disable_unprepare(priv->phy_clk);
+ clk_put(priv->phy_clk);
+ }
+
+out_put_clk_mac:
+ clk_disable_unprepare(priv->mac_clk);
+ clk_put(priv->mac_clk);
+out:
+ free_netdev(dev);
+ return ret;
+}
+
+
+/*
+ * exit func, stops hardware and unregisters netdevice
+ */
+static int bcm_enet_remove(struct platform_device *pdev)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+
+ /* stop netdevice */
+ dev = platform_get_drvdata(pdev);
+ priv = netdev_priv(dev);
+ unregister_netdev(dev);
+
+ /* turn off mdc clock */
+ enet_writel(priv, 0, ENET_MIISC_REG);
+
+ if (priv->has_phy) {
+ mdiobus_unregister(priv->mii_bus);
+ mdiobus_free(priv->mii_bus);
+ } else {
+ struct bcm63xx_enet_platform_data *pd;
+
+ pd = dev_get_platdata(&pdev->dev);
+ if (pd && pd->mii_config)
+ pd->mii_config(dev, 0, bcm_enet_mdio_read_mii,
+ bcm_enet_mdio_write_mii);
+ }
+
+ /* disable hw block clocks */
+ if (priv->phy_clk) {
+ clk_disable_unprepare(priv->phy_clk);
+ clk_put(priv->phy_clk);
+ }
+ clk_disable_unprepare(priv->mac_clk);
+ clk_put(priv->mac_clk);
+
+ free_netdev(dev);
+ return 0;
+}
+
+struct platform_driver bcm63xx_enet_driver = {
+ .probe = bcm_enet_probe,
+ .remove = bcm_enet_remove,
+ .driver = {
+ .name = "bcm63xx_enet",
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * switch mii access callbacks
+ */
+static int bcmenet_sw_mdio_read(struct bcm_enet_priv *priv,
+ int ext, int phy_id, int location)
+{
+ u32 reg;
+ int ret;
+
+ spin_lock_bh(&priv->enetsw_mdio_lock);
+ enetsw_writel(priv, 0, ENETSW_MDIOC_REG);
+
+ reg = ENETSW_MDIOC_RD_MASK |
+ (phy_id << ENETSW_MDIOC_PHYID_SHIFT) |
+ (location << ENETSW_MDIOC_REG_SHIFT);
+
+ if (ext)
+ reg |= ENETSW_MDIOC_EXT_MASK;
+
+ enetsw_writel(priv, reg, ENETSW_MDIOC_REG);
+ udelay(50);
+ ret = enetsw_readw(priv, ENETSW_MDIOD_REG);
+ spin_unlock_bh(&priv->enetsw_mdio_lock);
+ return ret;
+}
+
+static void bcmenet_sw_mdio_write(struct bcm_enet_priv *priv,
+ int ext, int phy_id, int location,
+ uint16_t data)
+{
+ u32 reg;
+
+ spin_lock_bh(&priv->enetsw_mdio_lock);
+ enetsw_writel(priv, 0, ENETSW_MDIOC_REG);
+
+ reg = ENETSW_MDIOC_WR_MASK |
+ (phy_id << ENETSW_MDIOC_PHYID_SHIFT) |
+ (location << ENETSW_MDIOC_REG_SHIFT);
+
+ if (ext)
+ reg |= ENETSW_MDIOC_EXT_MASK;
+
+ reg |= data;
+
+ enetsw_writel(priv, reg, ENETSW_MDIOC_REG);
+ udelay(50);
+ spin_unlock_bh(&priv->enetsw_mdio_lock);
+}
+
+static inline int bcm_enet_port_is_rgmii(int portid)
+{
+ return portid >= ENETSW_RGMII_PORT0;
+}
+
+/*
+ * enet sw PHY polling
+ */
+static void swphy_poll_timer(unsigned long data)
+{
+ struct bcm_enet_priv *priv = (struct bcm_enet_priv *)data;
+ unsigned int i;
+
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm63xx_enetsw_port *port;
+ int val, j, up, advertise, lpa, lpa2, speed, duplex, media;
+ int external_phy = bcm_enet_port_is_rgmii(i);
+ u8 override;
+
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (port->bypass_link)
+ continue;
+
+ /* dummy read to clear */
+ for (j = 0; j < 2; j++)
+ val = bcmenet_sw_mdio_read(priv, external_phy,
+ port->phy_id, MII_BMSR);
+
+ if (val == 0xffff)
+ continue;
+
+ up = (val & BMSR_LSTATUS) ? 1 : 0;
+ if (!(up ^ priv->sw_port_link[i]))
+ continue;
+
+ priv->sw_port_link[i] = up;
+
+ /* link changed */
+ if (!up) {
+ dev_info(&priv->pdev->dev, "link DOWN on %s\n",
+ port->name);
+ enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK,
+ ENETSW_PORTOV_REG(i));
+ enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK |
+ ENETSW_PTCTRL_TXDIS_MASK,
+ ENETSW_PTCTRL_REG(i));
+ continue;
+ }
+
+ advertise = bcmenet_sw_mdio_read(priv, external_phy,
+ port->phy_id, MII_ADVERTISE);
+
+ lpa = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id,
+ MII_LPA);
+
+ lpa2 = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id,
+ MII_STAT1000);
+
+ /* figure out media and duplex from advertise and LPA values */
+ media = mii_nway_result(lpa & advertise);
+ duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+ if (lpa2 & LPA_1000FULL)
+ duplex = 1;
+
+ if (lpa2 & (LPA_1000FULL | LPA_1000HALF))
+ speed = 1000;
+ else {
+ if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF))
+ speed = 100;
+ else
+ speed = 10;
+ }
+
+ dev_info(&priv->pdev->dev,
+ "link UP on %s, %dMbps, %s-duplex\n",
+ port->name, speed, duplex ? "full" : "half");
+
+ override = ENETSW_PORTOV_ENABLE_MASK |
+ ENETSW_PORTOV_LINKUP_MASK;
+
+ if (speed == 1000)
+ override |= ENETSW_IMPOV_1000_MASK;
+ else if (speed == 100)
+ override |= ENETSW_IMPOV_100_MASK;
+ if (duplex)
+ override |= ENETSW_IMPOV_FDX_MASK;
+
+ enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i));
+ enetsw_writeb(priv, 0, ENETSW_PTCTRL_REG(i));
+ }
+
+ priv->swphy_poll.expires = jiffies + HZ;
+ add_timer(&priv->swphy_poll);
+}
+
+/*
+ * open callback, allocate dma rings & buffers and start rx operation
+ */
+static int bcm_enetsw_open(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct device *kdev;
+ int i, ret;
+ unsigned int size;
+ void *p;
+ u32 val;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+
+ /* mask all interrupts and request them */
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
+
+ ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
+ 0, dev->name, dev);
+ if (ret)
+ goto out_freeirq;
+
+ if (priv->irq_tx != -1) {
+ ret = request_irq(priv->irq_tx, bcm_enet_isr_dma,
+ 0, dev->name, dev);
+ if (ret)
+ goto out_freeirq_rx;
+ }
+
+ /* allocate rx dma ring */
+ size = priv->rx_ring_size * sizeof(struct bcm_enet_desc);
+ p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL);
+ if (!p) {
+ dev_err(kdev, "cannot allocate rx ring %u\n", size);
+ ret = -ENOMEM;
+ goto out_freeirq_tx;
+ }
+
+ memset(p, 0, size);
+ priv->rx_desc_alloc_size = size;
+ priv->rx_desc_cpu = p;
+
+ /* allocate tx dma ring */
+ size = priv->tx_ring_size * sizeof(struct bcm_enet_desc);
+ p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL);
+ if (!p) {
+ dev_err(kdev, "cannot allocate tx ring\n");
+ ret = -ENOMEM;
+ goto out_free_rx_ring;
+ }
+
+ memset(p, 0, size);
+ priv->tx_desc_alloc_size = size;
+ priv->tx_desc_cpu = p;
+
+ priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size,
+ GFP_KERNEL);
+ if (!priv->tx_skb) {
+ dev_err(kdev, "cannot allocate rx skb queue\n");
+ ret = -ENOMEM;
+ goto out_free_tx_ring;
+ }
+
+ priv->tx_desc_count = priv->tx_ring_size;
+ priv->tx_dirty_desc = 0;
+ priv->tx_curr_desc = 0;
+ spin_lock_init(&priv->tx_lock);
+
+ /* init & fill rx ring with skbs */
+ priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size,
+ GFP_KERNEL);
+ if (!priv->rx_skb) {
+ dev_err(kdev, "cannot allocate rx skb queue\n");
+ ret = -ENOMEM;
+ goto out_free_tx_skb;
+ }
+
+ priv->rx_desc_count = 0;
+ priv->rx_dirty_desc = 0;
+ priv->rx_curr_desc = 0;
+
+ /* disable all ports */
+ for (i = 0; i < priv->num_ports; i++) {
+ enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK,
+ ENETSW_PORTOV_REG(i));
+ enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK |
+ ENETSW_PTCTRL_TXDIS_MASK,
+ ENETSW_PTCTRL_REG(i));
+
+ priv->sw_port_link[i] = 0;
+ }
+
+ /* reset mib */
+ val = enetsw_readb(priv, ENETSW_GMCR_REG);
+ val |= ENETSW_GMCR_RST_MIB_MASK;
+ enetsw_writeb(priv, val, ENETSW_GMCR_REG);
+ mdelay(1);
+ val &= ~ENETSW_GMCR_RST_MIB_MASK;
+ enetsw_writeb(priv, val, ENETSW_GMCR_REG);
+ mdelay(1);
+
+ /* force CPU port state */
+ val = enetsw_readb(priv, ENETSW_IMPOV_REG);
+ val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
+ enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
+
+ /* enable switch forward engine */
+ val = enetsw_readb(priv, ENETSW_SWMODE_REG);
+ val |= ENETSW_SWMODE_FWD_EN_MASK;
+ enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
+
+ /* enable jumbo on all ports */
+ enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
+ enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
+
+ /* initialize flow control buffer allocation */
+ enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+ ENETDMA_BUFALLOC_REG(priv->rx_chan));
+
+ if (bcm_enet_refill_rx(dev)) {
+ dev_err(kdev, "cannot allocate rx skb queue\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* write rx & tx ring addresses */
+ enet_dmas_writel(priv, priv->rx_desc_dma,
+ ENETDMAS_RSTART_REG, priv->rx_chan);
+ enet_dmas_writel(priv, priv->tx_desc_dma,
+ ENETDMAS_RSTART_REG, priv->tx_chan);
+
+ /* clear remaining state ram for rx & tx channel */
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->rx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG, priv->tx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->rx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG, priv->tx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->rx_chan);
+ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG, priv->tx_chan);
+
+ /* set dma maximum burst len */
+ enet_dmac_writel(priv, priv->dma_maxburst,
+ ENETDMAC_MAXBURST, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_maxburst,
+ ENETDMAC_MAXBURST, priv->tx_chan);
+
+ /* set flow control low/high threshold to 1/3 / 2/3 */
+ val = priv->rx_ring_size / 3;
+ enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
+ val = (priv->rx_ring_size * 2) / 3;
+ enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+
+ /* all set, enable mac and interrupts, start dma engine and
+ * kick rx dma channel
+ */
+ wmb();
+ enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
+ ENETDMAC_CHANCFG, priv->rx_chan);
+
+ /* watch "packet transferred" interrupt in rx and tx */
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IR, priv->rx_chan);
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IR, priv->tx_chan);
+
+ /* make sure we enable napi before rx interrupt */
+ napi_enable(&priv->napi);
+
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
+ ENETDMAC_IRMASK, priv->tx_chan);
+
+ netif_carrier_on(dev);
+ netif_start_queue(dev);
+
+ /* apply override config for bypass_link ports here. */
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm63xx_enetsw_port *port;
+ u8 override;
+ port = &priv->used_ports[i];
+ if (!port->used)
+ continue;
+
+ if (!port->bypass_link)
+ continue;
+
+ override = ENETSW_PORTOV_ENABLE_MASK |
+ ENETSW_PORTOV_LINKUP_MASK;
+
+ switch (port->force_speed) {
+ case 1000:
+ override |= ENETSW_IMPOV_1000_MASK;
+ break;
+ case 100:
+ override |= ENETSW_IMPOV_100_MASK;
+ break;
+ case 10:
+ break;
+ default:
+ pr_warn("invalid forced speed on port %s: assume 10\n",
+ port->name);
+ break;
+ }
+
+ if (port->force_duplex_full)
+ override |= ENETSW_IMPOV_FDX_MASK;
+
+
+ enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i));
+ enetsw_writeb(priv, 0, ENETSW_PTCTRL_REG(i));
+ }
+
+ /* start phy polling timer */
+ init_timer(&priv->swphy_poll);
+ priv->swphy_poll.function = swphy_poll_timer;
+ priv->swphy_poll.data = (unsigned long)priv;
+ priv->swphy_poll.expires = jiffies;
+ add_timer(&priv->swphy_poll);
+ return 0;
+
+out:
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct bcm_enet_desc *desc;
+
+ if (!priv->rx_skb[i])
+ continue;
+
+ desc = &priv->rx_desc_cpu[i];
+ dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_skb[i]);
+ }
+ kfree(priv->rx_skb);
+
+out_free_tx_skb:
+ kfree(priv->tx_skb);
+
+out_free_tx_ring:
+ dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+ priv->tx_desc_cpu, priv->tx_desc_dma);
+
+out_free_rx_ring:
+ dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+ priv->rx_desc_cpu, priv->rx_desc_dma);
+
+out_freeirq_tx:
+ if (priv->irq_tx != -1)
+ free_irq(priv->irq_tx, dev);
+
+out_freeirq_rx:
+ free_irq(priv->irq_rx, dev);
+
+out_freeirq:
+ return ret;
+}
+
+/* stop callback */
+static int bcm_enetsw_stop(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct device *kdev;
+ int i;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+
+ del_timer_sync(&priv->swphy_poll);
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+ del_timer_sync(&priv->rx_timeout);
+
+ /* mask all interrupts */
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
+
+ /* disable dma & mac */
+ bcm_enet_disable_dma(priv, priv->tx_chan);
+ bcm_enet_disable_dma(priv, priv->rx_chan);
+
+ /* force reclaim of all tx buffers */
+ bcm_enet_tx_reclaim(dev, 1);
+
+ /* free the rx skb ring */
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct bcm_enet_desc *desc;
+
+ if (!priv->rx_skb[i])
+ continue;
+
+ desc = &priv->rx_desc_cpu[i];
+ dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_skb[i]);
+ }
+
+ /* free remaining allocated memory */
+ kfree(priv->rx_skb);
+ kfree(priv->tx_skb);
+ dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+ priv->rx_desc_cpu, priv->rx_desc_dma);
+ dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+ priv->tx_desc_cpu, priv->tx_desc_dma);
+ if (priv->irq_tx != -1)
+ free_irq(priv->irq_tx, dev);
+ free_irq(priv->irq_rx, dev);
+
+ return 0;
+}
+
+/* try to sort out phy external status by walking the used_port field
+ * in the bcm_enet_priv structure. in case the phy address is not
+ * assigned to any physical port on the switch, assume it is external
+ * (and yell at the user).
+ */
+static int bcm_enetsw_phy_is_external(struct bcm_enet_priv *priv, int phy_id)
+{
+ int i;
+
+ for (i = 0; i < priv->num_ports; ++i) {
+ if (!priv->used_ports[i].used)
+ continue;
+ if (priv->used_ports[i].phy_id == phy_id)
+ return bcm_enet_port_is_rgmii(i);
+ }
+
+ printk_once(KERN_WARNING "bcm63xx_enet: could not find a used port with phy_id %i, assuming phy is external\n",
+ phy_id);
+ return 1;
+}
+
+/* can't use bcmenet_sw_mdio_read directly as we need to sort out
+ * external/internal status of the given phy_id first.
+ */
+static int bcm_enetsw_mii_mdio_read(struct net_device *dev, int phy_id,
+ int location)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ return bcmenet_sw_mdio_read(priv,
+ bcm_enetsw_phy_is_external(priv, phy_id),
+ phy_id, location);
+}
+
+/* can't use bcmenet_sw_mdio_write directly as we need to sort out
+ * external/internal status of the given phy_id first.
+ */
+static void bcm_enetsw_mii_mdio_write(struct net_device *dev, int phy_id,
+ int location,
+ int val)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ bcmenet_sw_mdio_write(priv, bcm_enetsw_phy_is_external(priv, phy_id),
+ phy_id, location, val);
+}
+
+static int bcm_enetsw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct mii_if_info mii;
+
+ mii.dev = dev;
+ mii.mdio_read = bcm_enetsw_mii_mdio_read;
+ mii.mdio_write = bcm_enetsw_mii_mdio_write;
+ mii.phy_id = 0;
+ mii.phy_id_mask = 0x3f;
+ mii.reg_num_mask = 0x1f;
+ return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL);
+
+}
+
+static const struct net_device_ops bcm_enetsw_ops = {
+ .ndo_open = bcm_enetsw_open,
+ .ndo_stop = bcm_enetsw_stop,
+ .ndo_start_xmit = bcm_enet_start_xmit,
+ .ndo_change_mtu = bcm_enet_change_mtu,
+ .ndo_do_ioctl = bcm_enetsw_ioctl,
+};
+
+
+static const struct bcm_enet_stats bcm_enetsw_gstrings_stats[] = {
+ { "rx_packets", DEV_STAT(rx_packets), -1 },
+ { "tx_packets", DEV_STAT(tx_packets), -1 },
+ { "rx_bytes", DEV_STAT(rx_bytes), -1 },
+ { "tx_bytes", DEV_STAT(tx_bytes), -1 },
+ { "rx_errors", DEV_STAT(rx_errors), -1 },
+ { "tx_errors", DEV_STAT(tx_errors), -1 },
+ { "rx_dropped", DEV_STAT(rx_dropped), -1 },
+ { "tx_dropped", DEV_STAT(tx_dropped), -1 },
+
+ { "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETHSW_MIB_RX_GD_OCT },
+ { "tx_unicast", GEN_STAT(mib.tx_unicast), ETHSW_MIB_RX_BRDCAST },
+ { "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETHSW_MIB_RX_BRDCAST },
+ { "tx_multicast", GEN_STAT(mib.tx_mult), ETHSW_MIB_RX_MULT },
+ { "tx_64_octets", GEN_STAT(mib.tx_64), ETHSW_MIB_RX_64 },
+ { "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETHSW_MIB_RX_65_127 },
+ { "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETHSW_MIB_RX_128_255 },
+ { "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETHSW_MIB_RX_256_511 },
+ { "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETHSW_MIB_RX_512_1023},
+ { "tx_1024_1522_oct", GEN_STAT(mib.tx_1024_max),
+ ETHSW_MIB_RX_1024_1522 },
+ { "tx_1523_2047_oct", GEN_STAT(mib.tx_1523_2047),
+ ETHSW_MIB_RX_1523_2047 },
+ { "tx_2048_4095_oct", GEN_STAT(mib.tx_2048_4095),
+ ETHSW_MIB_RX_2048_4095 },
+ { "tx_4096_8191_oct", GEN_STAT(mib.tx_4096_8191),
+ ETHSW_MIB_RX_4096_8191 },
+ { "tx_8192_9728_oct", GEN_STAT(mib.tx_8192_9728),
+ ETHSW_MIB_RX_8192_9728 },
+ { "tx_oversize", GEN_STAT(mib.tx_ovr), ETHSW_MIB_RX_OVR },
+ { "tx_oversize_drop", GEN_STAT(mib.tx_ovr), ETHSW_MIB_RX_OVR_DISC },
+ { "tx_dropped", GEN_STAT(mib.tx_drop), ETHSW_MIB_RX_DROP },
+ { "tx_undersize", GEN_STAT(mib.tx_underrun), ETHSW_MIB_RX_UND },
+ { "tx_pause", GEN_STAT(mib.tx_pause), ETHSW_MIB_RX_PAUSE },
+
+ { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETHSW_MIB_TX_ALL_OCT },
+ { "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETHSW_MIB_TX_BRDCAST },
+ { "rx_multicast", GEN_STAT(mib.rx_mult), ETHSW_MIB_TX_MULT },
+ { "rx_unicast", GEN_STAT(mib.rx_unicast), ETHSW_MIB_TX_MULT },
+ { "rx_pause", GEN_STAT(mib.rx_pause), ETHSW_MIB_TX_PAUSE },
+ { "rx_dropped", GEN_STAT(mib.rx_drop), ETHSW_MIB_TX_DROP_PKTS },
+
+};
+
+#define BCM_ENETSW_STATS_LEN \
+ (sizeof(bcm_enetsw_gstrings_stats) / sizeof(struct bcm_enet_stats))
+
+static void bcm_enetsw_get_strings(struct net_device *netdev,
+ u32 stringset, u8 *data)
+{
+ int i;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) {
+ memcpy(data + i * ETH_GSTRING_LEN,
+ bcm_enetsw_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ }
+ break;
+ }
+}
+
+static int bcm_enetsw_get_sset_count(struct net_device *netdev,
+ int string_set)
+{
+ switch (string_set) {
+ case ETH_SS_STATS:
+ return BCM_ENETSW_STATS_LEN;
+ default:
+ return -EINVAL;
+ }
+}
+
+static void bcm_enetsw_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strncpy(drvinfo->driver, bcm_enet_driver_name, 32);
+ strncpy(drvinfo->version, bcm_enet_driver_version, 32);
+ strncpy(drvinfo->fw_version, "N/A", 32);
+ strncpy(drvinfo->bus_info, "bcm63xx", 32);
+ drvinfo->n_stats = BCM_ENETSW_STATS_LEN;
+}
+
+static void bcm_enetsw_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct bcm_enet_priv *priv;
+ int i;
+
+ priv = netdev_priv(netdev);
+
+ for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) {
+ const struct bcm_enet_stats *s;
+ u32 lo, hi;
+ char *p;
+ int reg;
+
+ s = &bcm_enetsw_gstrings_stats[i];
+
+ reg = s->mib_reg;
+ if (reg == -1)
+ continue;
+
+ lo = enetsw_readl(priv, ENETSW_MIB_REG(reg));
+ p = (char *)priv + s->stat_offset;
+
+ if (s->sizeof_stat == sizeof(u64)) {
+ hi = enetsw_readl(priv, ENETSW_MIB_REG(reg + 1));
+ *(u64 *)p = ((u64)hi << 32 | lo);
+ } else {
+ *(u32 *)p = lo;
+ }
+ }
+
+ for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) {
+ const struct bcm_enet_stats *s;
+ char *p;
+
+ s = &bcm_enetsw_gstrings_stats[i];
+
+ if (s->mib_reg == -1)
+ p = (char *)&netdev->stats + s->stat_offset;
+ else
+ p = (char *)priv + s->stat_offset;
+
+ data[i] = (s->sizeof_stat == sizeof(u64)) ?
+ *(u64 *)p : *(u32 *)p;
+ }
+}
+
+static void bcm_enetsw_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ /* rx/tx ring is actually only limited by memory */
+ ering->rx_max_pending = 8192;
+ ering->tx_max_pending = 8192;
+ ering->rx_mini_max_pending = 0;
+ ering->rx_jumbo_max_pending = 0;
+ ering->rx_pending = priv->rx_ring_size;
+ ering->tx_pending = priv->tx_ring_size;
+}
+
+static int bcm_enetsw_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bcm_enet_priv *priv;
+ int was_running;
+
+ priv = netdev_priv(dev);
+
+ was_running = 0;
+ if (netif_running(dev)) {
+ bcm_enetsw_stop(dev);
+ was_running = 1;
+ }
+
+ priv->rx_ring_size = ering->rx_pending;
+ priv->tx_ring_size = ering->tx_pending;
+
+ if (was_running) {
+ int err;
+
+ err = bcm_enetsw_open(dev);
+ if (err)
+ dev_close(dev);
+ }
+ return 0;
+}
+
+static struct ethtool_ops bcm_enetsw_ethtool_ops = {
+ .get_strings = bcm_enetsw_get_strings,
+ .get_sset_count = bcm_enetsw_get_sset_count,
+ .get_ethtool_stats = bcm_enetsw_get_ethtool_stats,
+ .get_drvinfo = bcm_enetsw_get_drvinfo,
+ .get_ringparam = bcm_enetsw_get_ringparam,
+ .set_ringparam = bcm_enetsw_set_ringparam,
+};
+
+/* allocate netdevice, request register memory and register device. */
+static int bcm_enetsw_probe(struct platform_device *pdev)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+ struct bcm63xx_enetsw_platform_data *pd;
+ struct resource *res_mem;
+ int ret, irq_rx, irq_tx;
+
+ /* stop if shared driver failed, assume driver->probe will be
+ * called in the same order we register devices (correct ?)
+ */
+ if (!bcm_enet_shared_base[0])
+ return -ENODEV;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq_rx = platform_get_irq(pdev, 0);
+ irq_tx = platform_get_irq(pdev, 1);
+ if (!res_mem || irq_rx < 0)
+ return -ENODEV;
+
+ ret = 0;
+ dev = alloc_etherdev(sizeof(*priv));
+ if (!dev)
+ return -ENOMEM;
+ priv = netdev_priv(dev);
+ memset(priv, 0, sizeof(*priv));
+
+ /* initialize default and fetch platform data */
+ priv->enet_is_sw = true;
+ priv->irq_rx = irq_rx;
+ priv->irq_tx = irq_tx;
+ priv->rx_ring_size = BCMENET_DEF_RX_DESC;
+ priv->tx_ring_size = BCMENET_DEF_TX_DESC;
+ priv->dma_maxburst = BCMENETSW_DMA_MAXBURST;
+
+ pd = dev_get_platdata(&pdev->dev);
+ if (pd) {
+ memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN);
+ memcpy(priv->used_ports, pd->used_ports,
+ sizeof(pd->used_ports));
+ priv->num_ports = pd->num_ports;
+ priv->dma_has_sram = pd->dma_has_sram;
+ priv->dma_chan_en_mask = pd->dma_chan_en_mask;
+ priv->dma_chan_int_mask = pd->dma_chan_int_mask;
+ priv->dma_chan_width = pd->dma_chan_width;
+ }
+
+ ret = compute_hw_mtu(priv, dev->mtu);
+ if (ret)
+ goto out;
+
+ if (!request_mem_region(res_mem->start, resource_size(res_mem),
+ "bcm63xx_enetsw")) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ priv->base = ioremap(res_mem->start, resource_size(res_mem));
+ if (priv->base == NULL) {
+ ret = -ENOMEM;
+ goto out_release_mem;
+ }
+
+ priv->mac_clk = clk_get(&pdev->dev, "enetsw");
+ if (IS_ERR(priv->mac_clk)) {
+ ret = PTR_ERR(priv->mac_clk);
+ goto out_unmap;
+ }
+ clk_enable(priv->mac_clk);
+
+ priv->rx_chan = 0;
+ priv->tx_chan = 1;
+ spin_lock_init(&priv->rx_lock);
+
+ /* init rx timeout (used for oom) */
+ init_timer(&priv->rx_timeout);
+ priv->rx_timeout.function = bcm_enet_refill_rx_timer;
+ priv->rx_timeout.data = (unsigned long)dev;
+
+ /* register netdevice */
+ dev->netdev_ops = &bcm_enetsw_ops;
+ netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
+ dev->ethtool_ops = &bcm_enetsw_ethtool_ops;
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ spin_lock_init(&priv->enetsw_mdio_lock);
+
+ ret = register_netdev(dev);
+ if (ret)
+ goto out_put_clk;
+
+ netif_carrier_off(dev);
+ platform_set_drvdata(pdev, dev);
+ priv->pdev = pdev;
+ priv->net_dev = dev;
+
+ return 0;
+
+out_put_clk:
+ clk_put(priv->mac_clk);
+
+out_unmap:
+ iounmap(priv->base);
+
+out_release_mem:
+ release_mem_region(res_mem->start, resource_size(res_mem));
+out:
+ free_netdev(dev);
+ return ret;
+}
+
+
+/* exit func, stops hardware and unregisters netdevice */
+static int bcm_enetsw_remove(struct platform_device *pdev)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+ struct resource *res;
+
+ /* stop netdevice */
+ dev = platform_get_drvdata(pdev);
+ priv = netdev_priv(dev);
+ unregister_netdev(dev);
+
+ /* release device resources */
+ iounmap(priv->base);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ free_netdev(dev);
+ return 0;
+}
+
+struct platform_driver bcm63xx_enetsw_driver = {
+ .probe = bcm_enetsw_probe,
+ .remove = bcm_enetsw_remove,
+ .driver = {
+ .name = "bcm63xx_enetsw",
+ .owner = THIS_MODULE,
+ },
+};
+
+/* reserve & remap memory space shared between all macs */
+static int bcm_enet_shared_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ void __iomem *p[3];
+ unsigned int i;
+
+ memset(bcm_enet_shared_base, 0, sizeof(bcm_enet_shared_base));
+
+ for (i = 0; i < 3; i++) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ p[i] = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(p[i]))
+ return PTR_ERR(p[i]);
+ }
+
+ memcpy(bcm_enet_shared_base, p, sizeof(bcm_enet_shared_base));
+
+ return 0;
+}
+
+static int bcm_enet_shared_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+/* this "shared" driver is needed because both macs share a single
+ * address space
+ */
+struct platform_driver bcm63xx_enet_shared_driver = {
+ .probe = bcm_enet_shared_probe,
+ .remove = bcm_enet_shared_remove,
+ .driver = {
+ .name = "bcm63xx_enet_shared",
+ .owner = THIS_MODULE,
+ },
+};
+
+/* entry point */
+static int __init bcm_enet_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&bcm63xx_enet_shared_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&bcm63xx_enet_driver);
+ if (ret)
+ platform_driver_unregister(&bcm63xx_enet_shared_driver);
+
+ ret = platform_driver_register(&bcm63xx_enetsw_driver);
+ if (ret) {
+ platform_driver_unregister(&bcm63xx_enet_driver);
+ platform_driver_unregister(&bcm63xx_enet_shared_driver);
+ }
+
+ return ret;
+}
+
+static void __exit bcm_enet_exit(void)
+{
+ platform_driver_unregister(&bcm63xx_enet_driver);
+ platform_driver_unregister(&bcm63xx_enetsw_driver);
+ platform_driver_unregister(&bcm63xx_enet_shared_driver);
+}
+
+
+module_init(bcm_enet_init);
+module_exit(bcm_enet_exit);
+
+MODULE_DESCRIPTION("BCM63xx internal ethernet mac driver");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.h b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
new file mode 100644
index 00000000000..f55af431008
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -0,0 +1,360 @@
+#ifndef BCM63XX_ENET_H_
+#define BCM63XX_ENET_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_regs.h>
+#include <bcm63xx_irq.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_iudma.h>
+
+/* default number of descriptor */
+#define BCMENET_DEF_RX_DESC 64
+#define BCMENET_DEF_TX_DESC 32
+
+/* maximum burst len for dma (4 bytes unit) */
+#define BCMENET_DMA_MAXBURST 16
+#define BCMENETSW_DMA_MAXBURST 8
+
+/* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value
+ * must be low enough so that a DMA transfer of above burst length can
+ * not overflow the fifo */
+#define BCMENET_TX_FIFO_TRESH 32
+
+/*
+ * hardware maximum rx/tx packet size including FCS, max mtu is
+ * actually 2047, but if we set max rx size register to 2047 we won't
+ * get overflow information if packet size is 2048 or above
+ */
+#define BCMENET_MAX_MTU 2046
+
+/*
+ * MIB Counters register definitions
+*/
+#define ETH_MIB_TX_GD_OCTETS 0
+#define ETH_MIB_TX_GD_PKTS 1
+#define ETH_MIB_TX_ALL_OCTETS 2
+#define ETH_MIB_TX_ALL_PKTS 3
+#define ETH_MIB_TX_BRDCAST 4
+#define ETH_MIB_TX_MULT 5
+#define ETH_MIB_TX_64 6
+#define ETH_MIB_TX_65_127 7
+#define ETH_MIB_TX_128_255 8
+#define ETH_MIB_TX_256_511 9
+#define ETH_MIB_TX_512_1023 10
+#define ETH_MIB_TX_1024_MAX 11
+#define ETH_MIB_TX_JAB 12
+#define ETH_MIB_TX_OVR 13
+#define ETH_MIB_TX_FRAG 14
+#define ETH_MIB_TX_UNDERRUN 15
+#define ETH_MIB_TX_COL 16
+#define ETH_MIB_TX_1_COL 17
+#define ETH_MIB_TX_M_COL 18
+#define ETH_MIB_TX_EX_COL 19
+#define ETH_MIB_TX_LATE 20
+#define ETH_MIB_TX_DEF 21
+#define ETH_MIB_TX_CRS 22
+#define ETH_MIB_TX_PAUSE 23
+
+#define ETH_MIB_RX_GD_OCTETS 32
+#define ETH_MIB_RX_GD_PKTS 33
+#define ETH_MIB_RX_ALL_OCTETS 34
+#define ETH_MIB_RX_ALL_PKTS 35
+#define ETH_MIB_RX_BRDCAST 36
+#define ETH_MIB_RX_MULT 37
+#define ETH_MIB_RX_64 38
+#define ETH_MIB_RX_65_127 39
+#define ETH_MIB_RX_128_255 40
+#define ETH_MIB_RX_256_511 41
+#define ETH_MIB_RX_512_1023 42
+#define ETH_MIB_RX_1024_MAX 43
+#define ETH_MIB_RX_JAB 44
+#define ETH_MIB_RX_OVR 45
+#define ETH_MIB_RX_FRAG 46
+#define ETH_MIB_RX_DROP 47
+#define ETH_MIB_RX_CRC_ALIGN 48
+#define ETH_MIB_RX_UND 49
+#define ETH_MIB_RX_CRC 50
+#define ETH_MIB_RX_ALIGN 51
+#define ETH_MIB_RX_SYM 52
+#define ETH_MIB_RX_PAUSE 53
+#define ETH_MIB_RX_CNTRL 54
+
+
+/*
+ * SW MIB Counters register definitions
+*/
+#define ETHSW_MIB_TX_ALL_OCT 0
+#define ETHSW_MIB_TX_DROP_PKTS 2
+#define ETHSW_MIB_TX_QOS_PKTS 3
+#define ETHSW_MIB_TX_BRDCAST 4
+#define ETHSW_MIB_TX_MULT 5
+#define ETHSW_MIB_TX_UNI 6
+#define ETHSW_MIB_TX_COL 7
+#define ETHSW_MIB_TX_1_COL 8
+#define ETHSW_MIB_TX_M_COL 9
+#define ETHSW_MIB_TX_DEF 10
+#define ETHSW_MIB_TX_LATE 11
+#define ETHSW_MIB_TX_EX_COL 12
+#define ETHSW_MIB_TX_PAUSE 14
+#define ETHSW_MIB_TX_QOS_OCT 15
+
+#define ETHSW_MIB_RX_ALL_OCT 17
+#define ETHSW_MIB_RX_UND 19
+#define ETHSW_MIB_RX_PAUSE 20
+#define ETHSW_MIB_RX_64 21
+#define ETHSW_MIB_RX_65_127 22
+#define ETHSW_MIB_RX_128_255 23
+#define ETHSW_MIB_RX_256_511 24
+#define ETHSW_MIB_RX_512_1023 25
+#define ETHSW_MIB_RX_1024_1522 26
+#define ETHSW_MIB_RX_OVR 27
+#define ETHSW_MIB_RX_JAB 28
+#define ETHSW_MIB_RX_ALIGN 29
+#define ETHSW_MIB_RX_CRC 30
+#define ETHSW_MIB_RX_GD_OCT 31
+#define ETHSW_MIB_RX_DROP 33
+#define ETHSW_MIB_RX_UNI 34
+#define ETHSW_MIB_RX_MULT 35
+#define ETHSW_MIB_RX_BRDCAST 36
+#define ETHSW_MIB_RX_SA_CHANGE 37
+#define ETHSW_MIB_RX_FRAG 38
+#define ETHSW_MIB_RX_OVR_DISC 39
+#define ETHSW_MIB_RX_SYM 40
+#define ETHSW_MIB_RX_QOS_PKTS 41
+#define ETHSW_MIB_RX_QOS_OCT 42
+#define ETHSW_MIB_RX_1523_2047 44
+#define ETHSW_MIB_RX_2048_4095 45
+#define ETHSW_MIB_RX_4096_8191 46
+#define ETHSW_MIB_RX_8192_9728 47
+
+
+struct bcm_enet_mib_counters {
+ u64 tx_gd_octets;
+ u32 tx_gd_pkts;
+ u32 tx_all_octets;
+ u32 tx_all_pkts;
+ u32 tx_unicast;
+ u32 tx_brdcast;
+ u32 tx_mult;
+ u32 tx_64;
+ u32 tx_65_127;
+ u32 tx_128_255;
+ u32 tx_256_511;
+ u32 tx_512_1023;
+ u32 tx_1024_max;
+ u32 tx_1523_2047;
+ u32 tx_2048_4095;
+ u32 tx_4096_8191;
+ u32 tx_8192_9728;
+ u32 tx_jab;
+ u32 tx_drop;
+ u32 tx_ovr;
+ u32 tx_frag;
+ u32 tx_underrun;
+ u32 tx_col;
+ u32 tx_1_col;
+ u32 tx_m_col;
+ u32 tx_ex_col;
+ u32 tx_late;
+ u32 tx_def;
+ u32 tx_crs;
+ u32 tx_pause;
+ u64 rx_gd_octets;
+ u32 rx_gd_pkts;
+ u32 rx_all_octets;
+ u32 rx_all_pkts;
+ u32 rx_brdcast;
+ u32 rx_unicast;
+ u32 rx_mult;
+ u32 rx_64;
+ u32 rx_65_127;
+ u32 rx_128_255;
+ u32 rx_256_511;
+ u32 rx_512_1023;
+ u32 rx_1024_max;
+ u32 rx_jab;
+ u32 rx_ovr;
+ u32 rx_frag;
+ u32 rx_drop;
+ u32 rx_crc_align;
+ u32 rx_und;
+ u32 rx_crc;
+ u32 rx_align;
+ u32 rx_sym;
+ u32 rx_pause;
+ u32 rx_cntrl;
+};
+
+
+struct bcm_enet_priv {
+
+ /* mac id (from platform device id) */
+ int mac_id;
+
+ /* base remapped address of device */
+ void __iomem *base;
+
+ /* mac irq, rx_dma irq, tx_dma irq */
+ int irq;
+ int irq_rx;
+ int irq_tx;
+
+ /* hw view of rx & tx dma ring */
+ dma_addr_t rx_desc_dma;
+ dma_addr_t tx_desc_dma;
+
+ /* allocated size (in bytes) for rx & tx dma ring */
+ unsigned int rx_desc_alloc_size;
+ unsigned int tx_desc_alloc_size;
+
+
+ struct napi_struct napi;
+
+ /* dma channel id for rx */
+ int rx_chan;
+
+ /* number of dma desc in rx ring */
+ int rx_ring_size;
+
+ /* cpu view of rx dma ring */
+ struct bcm_enet_desc *rx_desc_cpu;
+
+ /* current number of armed descriptor given to hardware for rx */
+ int rx_desc_count;
+
+ /* next rx descriptor to fetch from hardware */
+ int rx_curr_desc;
+
+ /* next dirty rx descriptor to refill */
+ int rx_dirty_desc;
+
+ /* size of allocated rx skbs */
+ unsigned int rx_skb_size;
+
+ /* list of skb given to hw for rx */
+ struct sk_buff **rx_skb;
+
+ /* used when rx skb allocation failed, so we defer rx queue
+ * refill */
+ struct timer_list rx_timeout;
+
+ /* lock rx_timeout against rx normal operation */
+ spinlock_t rx_lock;
+
+
+ /* dma channel id for tx */
+ int tx_chan;
+
+ /* number of dma desc in tx ring */
+ int tx_ring_size;
+
+ /* maximum dma burst size */
+ int dma_maxburst;
+
+ /* cpu view of rx dma ring */
+ struct bcm_enet_desc *tx_desc_cpu;
+
+ /* number of available descriptor for tx */
+ int tx_desc_count;
+
+ /* next tx descriptor avaiable */
+ int tx_curr_desc;
+
+ /* next dirty tx descriptor to reclaim */
+ int tx_dirty_desc;
+
+ /* list of skb given to hw for tx */
+ struct sk_buff **tx_skb;
+
+ /* lock used by tx reclaim and xmit */
+ spinlock_t tx_lock;
+
+
+ /* set if internal phy is ignored and external mii interface
+ * is selected */
+ int use_external_mii;
+
+ /* set if a phy is connected, phy address must be known,
+ * probing is not possible */
+ int has_phy;
+ int phy_id;
+
+ /* set if connected phy has an associated irq */
+ int has_phy_interrupt;
+ int phy_interrupt;
+
+ /* used when a phy is connected (phylib used) */
+ struct mii_bus *mii_bus;
+ struct phy_device *phydev;
+ int old_link;
+ int old_duplex;
+ int old_pause;
+
+ /* used when no phy is connected */
+ int force_speed_100;
+ int force_duplex_full;
+
+ /* pause parameters */
+ int pause_auto;
+ int pause_rx;
+ int pause_tx;
+
+ /* stats */
+ struct bcm_enet_mib_counters mib;
+
+ /* after mib interrupt, mib registers update is done in this
+ * work queue */
+ struct work_struct mib_update_task;
+
+ /* lock mib update between userspace request and workqueue */
+ struct mutex mib_update_lock;
+
+ /* mac clock */
+ struct clk *mac_clk;
+
+ /* phy clock if internal phy is used */
+ struct clk *phy_clk;
+
+ /* network device reference */
+ struct net_device *net_dev;
+
+ /* platform device reference */
+ struct platform_device *pdev;
+
+ /* maximum hardware transmit/receive size */
+ unsigned int hw_mtu;
+
+ bool enet_is_sw;
+
+ /* port mapping for switch devices */
+ int num_ports;
+ struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
+ int sw_port_link[ENETSW_MAX_PORT];
+
+ /* used to poll switch port state */
+ struct timer_list swphy_poll;
+ spinlock_t enetsw_mdio_lock;
+
+ /* dma channel enable mask */
+ u32 dma_chan_en_mask;
+
+ /* dma channel interrupt mask */
+ u32 dma_chan_int_mask;
+
+ /* DMA engine has internal SRAM */
+ bool dma_has_sram;
+
+ /* dma channel width */
+ unsigned int dma_chan_width;
+
+ /* dma descriptor shift value */
+ unsigned int dma_desc_shift;
+};
+
+
+#endif /* ! BCM63XX_ENET_H_ */
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
new file mode 100644
index 00000000000..5776e503e4c
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -0,0 +1,1633 @@
+/*
+ * Broadcom BCM7xxx System Port Ethernet MAC driver
+ *
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+
+#include "bcmsysport.h"
+
+/* I/O accessors register helpers */
+#define BCM_SYSPORT_IO_MACRO(name, offset) \
+static inline u32 name##_readl(struct bcm_sysport_priv *priv, u32 off) \
+{ \
+ u32 reg = __raw_readl(priv->base + offset + off); \
+ return reg; \
+} \
+static inline void name##_writel(struct bcm_sysport_priv *priv, \
+ u32 val, u32 off) \
+{ \
+ __raw_writel(val, priv->base + offset + off); \
+} \
+
+BCM_SYSPORT_IO_MACRO(intrl2_0, SYS_PORT_INTRL2_0_OFFSET);
+BCM_SYSPORT_IO_MACRO(intrl2_1, SYS_PORT_INTRL2_1_OFFSET);
+BCM_SYSPORT_IO_MACRO(umac, SYS_PORT_UMAC_OFFSET);
+BCM_SYSPORT_IO_MACRO(tdma, SYS_PORT_TDMA_OFFSET);
+BCM_SYSPORT_IO_MACRO(rdma, SYS_PORT_RDMA_OFFSET);
+BCM_SYSPORT_IO_MACRO(rxchk, SYS_PORT_RXCHK_OFFSET);
+BCM_SYSPORT_IO_MACRO(txchk, SYS_PORT_TXCHK_OFFSET);
+BCM_SYSPORT_IO_MACRO(rbuf, SYS_PORT_RBUF_OFFSET);
+BCM_SYSPORT_IO_MACRO(tbuf, SYS_PORT_TBUF_OFFSET);
+BCM_SYSPORT_IO_MACRO(topctrl, SYS_PORT_TOPCTRL_OFFSET);
+
+/* L2-interrupt masking/unmasking helpers, does automatic saving of the applied
+ * mask in a software copy to avoid CPU_MASK_STATUS reads in hot-paths.
+ */
+#define BCM_SYSPORT_INTR_L2(which) \
+static inline void intrl2_##which##_mask_clear(struct bcm_sysport_priv *priv, \
+ u32 mask) \
+{ \
+ intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR); \
+ priv->irq##which##_mask &= ~(mask); \
+} \
+static inline void intrl2_##which##_mask_set(struct bcm_sysport_priv *priv, \
+ u32 mask) \
+{ \
+ intrl2_## which##_writel(priv, mask, INTRL2_CPU_MASK_SET); \
+ priv->irq##which##_mask |= (mask); \
+} \
+
+BCM_SYSPORT_INTR_L2(0)
+BCM_SYSPORT_INTR_L2(1)
+
+/* Register accesses to GISB/RBUS registers are expensive (few hundred
+ * nanoseconds), so keep the check for 64-bits explicit here to save
+ * one register write per-packet on 32-bits platforms.
+ */
+static inline void dma_desc_set_addr(struct bcm_sysport_priv *priv,
+ void __iomem *d,
+ dma_addr_t addr)
+{
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+ __raw_writel(upper_32_bits(addr) & DESC_ADDR_HI_MASK,
+ d + DESC_ADDR_HI_STATUS_LEN);
+#endif
+ __raw_writel(lower_32_bits(addr), d + DESC_ADDR_LO);
+}
+
+static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
+ struct dma_desc *desc,
+ unsigned int port)
+{
+ /* Ports are latched, so write upper address first */
+ tdma_writel(priv, desc->addr_status_len, TDMA_WRITE_PORT_HI(port));
+ tdma_writel(priv, desc->addr_lo, TDMA_WRITE_PORT_LO(port));
+}
+
+/* Ethtool operations */
+static int bcm_sysport_set_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static int bcm_sysport_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int bcm_sysport_set_rx_csum(struct net_device *dev,
+ netdev_features_t wanted)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ priv->rx_csum_en = !!(wanted & NETIF_F_RXCSUM);
+ reg = rxchk_readl(priv, RXCHK_CONTROL);
+ if (priv->rx_csum_en)
+ reg |= RXCHK_EN;
+ else
+ reg &= ~RXCHK_EN;
+
+ /* If UniMAC forwards CRC, we need to skip over it to get
+ * a valid CHK bit to be set in the per-packet status word
+ */
+ if (priv->rx_csum_en && priv->crc_fwd)
+ reg |= RXCHK_SKIP_FCS;
+ else
+ reg &= ~RXCHK_SKIP_FCS;
+
+ rxchk_writel(priv, reg, RXCHK_CONTROL);
+
+ return 0;
+}
+
+static int bcm_sysport_set_tx_csum(struct net_device *dev,
+ netdev_features_t wanted)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ /* Hardware transmit checksum requires us to enable the Transmit status
+ * block prepended to the packet contents
+ */
+ priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM));
+ reg = tdma_readl(priv, TDMA_CONTROL);
+ if (priv->tsb_en)
+ reg |= TSB_EN;
+ else
+ reg &= ~TSB_EN;
+ tdma_writel(priv, reg, TDMA_CONTROL);
+
+ return 0;
+}
+
+static int bcm_sysport_set_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = features ^ dev->features;
+ netdev_features_t wanted = dev->wanted_features;
+ int ret = 0;
+
+ if (changed & NETIF_F_RXCSUM)
+ ret = bcm_sysport_set_rx_csum(dev, wanted);
+ if (changed & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))
+ ret = bcm_sysport_set_tx_csum(dev, wanted);
+
+ return ret;
+}
+
+/* Hardware counters must be kept in sync because the order/offset
+ * is important here (order in structure declaration = order in hardware)
+ */
+static const struct bcm_sysport_stats bcm_sysport_gstrings_stats[] = {
+ /* general stats */
+ STAT_NETDEV(rx_packets),
+ STAT_NETDEV(tx_packets),
+ STAT_NETDEV(rx_bytes),
+ STAT_NETDEV(tx_bytes),
+ STAT_NETDEV(rx_errors),
+ STAT_NETDEV(tx_errors),
+ STAT_NETDEV(rx_dropped),
+ STAT_NETDEV(tx_dropped),
+ STAT_NETDEV(multicast),
+ /* UniMAC RSV counters */
+ STAT_MIB_RX("rx_64_octets", mib.rx.pkt_cnt.cnt_64),
+ STAT_MIB_RX("rx_65_127_oct", mib.rx.pkt_cnt.cnt_127),
+ STAT_MIB_RX("rx_128_255_oct", mib.rx.pkt_cnt.cnt_255),
+ STAT_MIB_RX("rx_256_511_oct", mib.rx.pkt_cnt.cnt_511),
+ STAT_MIB_RX("rx_512_1023_oct", mib.rx.pkt_cnt.cnt_1023),
+ STAT_MIB_RX("rx_1024_1518_oct", mib.rx.pkt_cnt.cnt_1518),
+ STAT_MIB_RX("rx_vlan_1519_1522_oct", mib.rx.pkt_cnt.cnt_mgv),
+ STAT_MIB_RX("rx_1522_2047_oct", mib.rx.pkt_cnt.cnt_2047),
+ STAT_MIB_RX("rx_2048_4095_oct", mib.rx.pkt_cnt.cnt_4095),
+ STAT_MIB_RX("rx_4096_9216_oct", mib.rx.pkt_cnt.cnt_9216),
+ STAT_MIB_RX("rx_pkts", mib.rx.pkt),
+ STAT_MIB_RX("rx_bytes", mib.rx.bytes),
+ STAT_MIB_RX("rx_multicast", mib.rx.mca),
+ STAT_MIB_RX("rx_broadcast", mib.rx.bca),
+ STAT_MIB_RX("rx_fcs", mib.rx.fcs),
+ STAT_MIB_RX("rx_control", mib.rx.cf),
+ STAT_MIB_RX("rx_pause", mib.rx.pf),
+ STAT_MIB_RX("rx_unknown", mib.rx.uo),
+ STAT_MIB_RX("rx_align", mib.rx.aln),
+ STAT_MIB_RX("rx_outrange", mib.rx.flr),
+ STAT_MIB_RX("rx_code", mib.rx.cde),
+ STAT_MIB_RX("rx_carrier", mib.rx.fcr),
+ STAT_MIB_RX("rx_oversize", mib.rx.ovr),
+ STAT_MIB_RX("rx_jabber", mib.rx.jbr),
+ STAT_MIB_RX("rx_mtu_err", mib.rx.mtue),
+ STAT_MIB_RX("rx_good_pkts", mib.rx.pok),
+ STAT_MIB_RX("rx_unicast", mib.rx.uc),
+ STAT_MIB_RX("rx_ppp", mib.rx.ppp),
+ STAT_MIB_RX("rx_crc", mib.rx.rcrc),
+ /* UniMAC TSV counters */
+ STAT_MIB_TX("tx_64_octets", mib.tx.pkt_cnt.cnt_64),
+ STAT_MIB_TX("tx_65_127_oct", mib.tx.pkt_cnt.cnt_127),
+ STAT_MIB_TX("tx_128_255_oct", mib.tx.pkt_cnt.cnt_255),
+ STAT_MIB_TX("tx_256_511_oct", mib.tx.pkt_cnt.cnt_511),
+ STAT_MIB_TX("tx_512_1023_oct", mib.tx.pkt_cnt.cnt_1023),
+ STAT_MIB_TX("tx_1024_1518_oct", mib.tx.pkt_cnt.cnt_1518),
+ STAT_MIB_TX("tx_vlan_1519_1522_oct", mib.tx.pkt_cnt.cnt_mgv),
+ STAT_MIB_TX("tx_1522_2047_oct", mib.tx.pkt_cnt.cnt_2047),
+ STAT_MIB_TX("tx_2048_4095_oct", mib.tx.pkt_cnt.cnt_4095),
+ STAT_MIB_TX("tx_4096_9216_oct", mib.tx.pkt_cnt.cnt_9216),
+ STAT_MIB_TX("tx_pkts", mib.tx.pkts),
+ STAT_MIB_TX("tx_multicast", mib.tx.mca),
+ STAT_MIB_TX("tx_broadcast", mib.tx.bca),
+ STAT_MIB_TX("tx_pause", mib.tx.pf),
+ STAT_MIB_TX("tx_control", mib.tx.cf),
+ STAT_MIB_TX("tx_fcs_err", mib.tx.fcs),
+ STAT_MIB_TX("tx_oversize", mib.tx.ovr),
+ STAT_MIB_TX("tx_defer", mib.tx.drf),
+ STAT_MIB_TX("tx_excess_defer", mib.tx.edf),
+ STAT_MIB_TX("tx_single_col", mib.tx.scl),
+ STAT_MIB_TX("tx_multi_col", mib.tx.mcl),
+ STAT_MIB_TX("tx_late_col", mib.tx.lcl),
+ STAT_MIB_TX("tx_excess_col", mib.tx.ecl),
+ STAT_MIB_TX("tx_frags", mib.tx.frg),
+ STAT_MIB_TX("tx_total_col", mib.tx.ncl),
+ STAT_MIB_TX("tx_jabber", mib.tx.jbr),
+ STAT_MIB_TX("tx_bytes", mib.tx.bytes),
+ STAT_MIB_TX("tx_good_pkts", mib.tx.pok),
+ STAT_MIB_TX("tx_unicast", mib.tx.uc),
+ /* UniMAC RUNT counters */
+ STAT_RUNT("rx_runt_pkts", mib.rx_runt_cnt),
+ STAT_RUNT("rx_runt_valid_fcs", mib.rx_runt_fcs),
+ STAT_RUNT("rx_runt_inval_fcs_align", mib.rx_runt_fcs_align),
+ STAT_RUNT("rx_runt_bytes", mib.rx_runt_bytes),
+ /* RXCHK misc statistics */
+ STAT_RXCHK("rxchk_bad_csum", mib.rxchk_bad_csum, RXCHK_BAD_CSUM_CNTR),
+ STAT_RXCHK("rxchk_other_pkt_disc", mib.rxchk_other_pkt_disc,
+ RXCHK_OTHER_DISC_CNTR),
+ /* RBUF misc statistics */
+ STAT_RBUF("rbuf_ovflow_cnt", mib.rbuf_ovflow_cnt, RBUF_OVFL_DISC_CNTR),
+ STAT_RBUF("rbuf_err_cnt", mib.rbuf_err_cnt, RBUF_ERR_PKT_CNTR),
+};
+
+#define BCM_SYSPORT_STATS_LEN ARRAY_SIZE(bcm_sysport_gstrings_stats)
+
+static void bcm_sysport_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+ strlcpy(info->version, "0.1", sizeof(info->version));
+ strlcpy(info->bus_info, "platform", sizeof(info->bus_info));
+ info->n_stats = BCM_SYSPORT_STATS_LEN;
+}
+
+static u32 bcm_sysport_get_msglvl(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ return priv->msg_enable;
+}
+
+static void bcm_sysport_set_msglvl(struct net_device *dev, u32 enable)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ priv->msg_enable = enable;
+}
+
+static int bcm_sysport_get_sset_count(struct net_device *dev, int string_set)
+{
+ switch (string_set) {
+ case ETH_SS_STATS:
+ return BCM_SYSPORT_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void bcm_sysport_get_strings(struct net_device *dev,
+ u32 stringset, u8 *data)
+{
+ int i;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ memcpy(data + i * ETH_GSTRING_LEN,
+ bcm_sysport_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv)
+{
+ int i, j = 0;
+
+ for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ const struct bcm_sysport_stats *s;
+ u8 offset = 0;
+ u32 val = 0;
+ char *p;
+
+ s = &bcm_sysport_gstrings_stats[i];
+ switch (s->type) {
+ case BCM_SYSPORT_STAT_NETDEV:
+ continue;
+ case BCM_SYSPORT_STAT_MIB_RX:
+ case BCM_SYSPORT_STAT_MIB_TX:
+ case BCM_SYSPORT_STAT_RUNT:
+ if (s->type != BCM_SYSPORT_STAT_MIB_RX)
+ offset = UMAC_MIB_STAT_OFFSET;
+ val = umac_readl(priv, UMAC_MIB_START + j + offset);
+ break;
+ case BCM_SYSPORT_STAT_RXCHK:
+ val = rxchk_readl(priv, s->reg_offset);
+ if (val == ~0)
+ rxchk_writel(priv, 0, s->reg_offset);
+ break;
+ case BCM_SYSPORT_STAT_RBUF:
+ val = rbuf_readl(priv, s->reg_offset);
+ if (val == ~0)
+ rbuf_writel(priv, 0, s->reg_offset);
+ break;
+ }
+
+ j += s->stat_sizeof;
+ p = (char *)priv + s->stat_offset;
+ *(u32 *)p = val;
+ }
+
+ netif_dbg(priv, hw, priv->netdev, "updated MIB counters\n");
+}
+
+static void bcm_sysport_get_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ int i;
+
+ if (netif_running(dev))
+ bcm_sysport_update_mib_counters(priv);
+
+ for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ const struct bcm_sysport_stats *s;
+ char *p;
+
+ s = &bcm_sysport_gstrings_stats[i];
+ if (s->type == BCM_SYSPORT_STAT_NETDEV)
+ p = (char *)&dev->stats;
+ else
+ p = (char *)priv;
+ p += s->stat_offset;
+ data[i] = *(u32 *)p;
+ }
+}
+
+static void bcm_sysport_free_cb(struct bcm_sysport_cb *cb)
+{
+ dev_kfree_skb_any(cb->skb);
+ cb->skb = NULL;
+ dma_unmap_addr_set(cb, dma_addr, 0);
+}
+
+static int bcm_sysport_rx_refill(struct bcm_sysport_priv *priv,
+ struct bcm_sysport_cb *cb)
+{
+ struct device *kdev = &priv->pdev->dev;
+ struct net_device *ndev = priv->netdev;
+ dma_addr_t mapping;
+ int ret;
+
+ cb->skb = netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH);
+ if (!cb->skb) {
+ netif_err(priv, rx_err, ndev, "SKB alloc failed\n");
+ return -ENOMEM;
+ }
+
+ mapping = dma_map_single(kdev, cb->skb->data,
+ RX_BUF_LENGTH, DMA_FROM_DEVICE);
+ ret = dma_mapping_error(kdev, mapping);
+ if (ret) {
+ bcm_sysport_free_cb(cb);
+ netif_err(priv, rx_err, ndev, "DMA mapping failure\n");
+ return ret;
+ }
+
+ dma_unmap_addr_set(cb, dma_addr, mapping);
+ dma_desc_set_addr(priv, priv->rx_bd_assign_ptr, mapping);
+
+ priv->rx_bd_assign_index++;
+ priv->rx_bd_assign_index &= (priv->num_rx_bds - 1);
+ priv->rx_bd_assign_ptr = priv->rx_bds +
+ (priv->rx_bd_assign_index * DESC_SIZE);
+
+ netif_dbg(priv, rx_status, ndev, "RX refill\n");
+
+ return 0;
+}
+
+static int bcm_sysport_alloc_rx_bufs(struct bcm_sysport_priv *priv)
+{
+ struct bcm_sysport_cb *cb;
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < priv->num_rx_bds; i++) {
+ cb = &priv->rx_cbs[priv->rx_bd_assign_index];
+ if (cb->skb)
+ continue;
+
+ ret = bcm_sysport_rx_refill(priv, cb);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/* Poll the hardware for up to budget packets to process */
+static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
+ unsigned int budget)
+{
+ struct device *kdev = &priv->pdev->dev;
+ struct net_device *ndev = priv->netdev;
+ unsigned int processed = 0, to_process;
+ struct bcm_sysport_cb *cb;
+ struct sk_buff *skb;
+ unsigned int p_index;
+ u16 len, status;
+ struct bcm_rsb *rsb;
+
+ /* Determine how much we should process since last call */
+ p_index = rdma_readl(priv, RDMA_PROD_INDEX);
+ p_index &= RDMA_PROD_INDEX_MASK;
+
+ if (p_index < priv->rx_c_index)
+ to_process = (RDMA_CONS_INDEX_MASK + 1) -
+ priv->rx_c_index + p_index;
+ else
+ to_process = p_index - priv->rx_c_index;
+
+ netif_dbg(priv, rx_status, ndev,
+ "p_index=%d rx_c_index=%d to_process=%d\n",
+ p_index, priv->rx_c_index, to_process);
+
+ while ((processed < to_process) &&
+ (processed < budget)) {
+
+ cb = &priv->rx_cbs[priv->rx_read_ptr];
+ skb = cb->skb;
+ dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
+ RX_BUF_LENGTH, DMA_FROM_DEVICE);
+
+ /* Extract the Receive Status Block prepended */
+ rsb = (struct bcm_rsb *)skb->data;
+ len = (rsb->rx_status_len >> DESC_LEN_SHIFT) & DESC_LEN_MASK;
+ status = (rsb->rx_status_len >> DESC_STATUS_SHIFT) &
+ DESC_STATUS_MASK;
+
+ processed++;
+ priv->rx_read_ptr++;
+ if (priv->rx_read_ptr == priv->num_rx_bds)
+ priv->rx_read_ptr = 0;
+
+ netif_dbg(priv, rx_status, ndev,
+ "p=%d, c=%d, rd_ptr=%d, len=%d, flag=0x%04x\n",
+ p_index, priv->rx_c_index, priv->rx_read_ptr,
+ len, status);
+
+ if (unlikely(!skb)) {
+ netif_err(priv, rx_err, ndev, "out of memory!\n");
+ ndev->stats.rx_dropped++;
+ ndev->stats.rx_errors++;
+ goto refill;
+ }
+
+ if (unlikely(!(status & DESC_EOP) || !(status & DESC_SOP))) {
+ netif_err(priv, rx_status, ndev, "fragmented packet!\n");
+ ndev->stats.rx_dropped++;
+ ndev->stats.rx_errors++;
+ bcm_sysport_free_cb(cb);
+ goto refill;
+ }
+
+ if (unlikely(status & (RX_STATUS_ERR | RX_STATUS_OVFLOW))) {
+ netif_err(priv, rx_err, ndev, "error packet\n");
+ if (status & RX_STATUS_OVFLOW)
+ ndev->stats.rx_over_errors++;
+ ndev->stats.rx_dropped++;
+ ndev->stats.rx_errors++;
+ bcm_sysport_free_cb(cb);
+ goto refill;
+ }
+
+ skb_put(skb, len);
+
+ /* Hardware validated our checksum */
+ if (likely(status & DESC_L4_CSUM))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ /* Hardware pre-pends packets with 2bytes before Ethernet
+ * header plus we have the Receive Status Block, strip off all
+ * of this from the SKB.
+ */
+ skb_pull(skb, sizeof(*rsb) + 2);
+ len -= (sizeof(*rsb) + 2);
+
+ /* UniMAC may forward CRC */
+ if (priv->crc_fwd) {
+ skb_trim(skb, len - ETH_FCS_LEN);
+ len -= ETH_FCS_LEN;
+ }
+
+ skb->protocol = eth_type_trans(skb, ndev);
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += len;
+
+ napi_gro_receive(&priv->napi, skb);
+refill:
+ bcm_sysport_rx_refill(priv, cb);
+ }
+
+ return processed;
+}
+
+static void bcm_sysport_tx_reclaim_one(struct bcm_sysport_priv *priv,
+ struct bcm_sysport_cb *cb,
+ unsigned int *bytes_compl,
+ unsigned int *pkts_compl)
+{
+ struct device *kdev = &priv->pdev->dev;
+ struct net_device *ndev = priv->netdev;
+
+ if (cb->skb) {
+ ndev->stats.tx_bytes += cb->skb->len;
+ *bytes_compl += cb->skb->len;
+ dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
+ ndev->stats.tx_packets++;
+ (*pkts_compl)++;
+ bcm_sysport_free_cb(cb);
+ /* SKB fragment */
+ } else if (dma_unmap_addr(cb, dma_addr)) {
+ ndev->stats.tx_bytes += dma_unmap_len(cb, dma_len);
+ dma_unmap_page(kdev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len), DMA_TO_DEVICE);
+ dma_unmap_addr_set(cb, dma_addr, 0);
+ }
+}
+
+/* Reclaim queued SKBs for transmission completion, lockless version */
+static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
+ struct bcm_sysport_tx_ring *ring)
+{
+ struct net_device *ndev = priv->netdev;
+ unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
+ unsigned int pkts_compl = 0, bytes_compl = 0;
+ struct bcm_sysport_cb *cb;
+ struct netdev_queue *txq;
+ u32 hw_ind;
+
+ txq = netdev_get_tx_queue(ndev, ring->index);
+
+ /* Compute how many descriptors have been processed since last call */
+ hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
+ c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
+ ring->p_index = (hw_ind & RING_PROD_INDEX_MASK);
+
+ last_c_index = ring->c_index;
+ num_tx_cbs = ring->size;
+
+ c_index &= (num_tx_cbs - 1);
+
+ if (c_index >= last_c_index)
+ last_tx_cn = c_index - last_c_index;
+ else
+ last_tx_cn = num_tx_cbs - last_c_index + c_index;
+
+ netif_dbg(priv, tx_done, ndev,
+ "ring=%d c_index=%d last_tx_cn=%d last_c_index=%d\n",
+ ring->index, c_index, last_tx_cn, last_c_index);
+
+ while (last_tx_cn-- > 0) {
+ cb = ring->cbs + last_c_index;
+ bcm_sysport_tx_reclaim_one(priv, cb, &bytes_compl, &pkts_compl);
+
+ ring->desc_count++;
+ last_c_index++;
+ last_c_index &= (num_tx_cbs - 1);
+ }
+
+ ring->c_index = c_index;
+
+ if (netif_tx_queue_stopped(txq) && pkts_compl)
+ netif_tx_wake_queue(txq);
+
+ netif_dbg(priv, tx_done, ndev,
+ "ring=%d c_index=%d pkts_compl=%d, bytes_compl=%d\n",
+ ring->index, ring->c_index, pkts_compl, bytes_compl);
+
+ return pkts_compl;
+}
+
+/* Locked version of the per-ring TX reclaim routine */
+static unsigned int bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
+ struct bcm_sysport_tx_ring *ring)
+{
+ unsigned int released;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ring->lock, flags);
+ released = __bcm_sysport_tx_reclaim(priv, ring);
+ spin_unlock_irqrestore(&ring->lock, flags);
+
+ return released;
+}
+
+static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
+{
+ struct bcm_sysport_tx_ring *ring =
+ container_of(napi, struct bcm_sysport_tx_ring, napi);
+ unsigned int work_done = 0;
+
+ work_done = bcm_sysport_tx_reclaim(ring->priv, ring);
+
+ if (work_done == 0) {
+ napi_complete(napi);
+ /* re-enable TX interrupt */
+ intrl2_1_mask_clear(ring->priv, BIT(ring->index));
+ }
+
+ return 0;
+}
+
+static void bcm_sysport_tx_reclaim_all(struct bcm_sysport_priv *priv)
+{
+ unsigned int q;
+
+ for (q = 0; q < priv->netdev->num_tx_queues; q++)
+ bcm_sysport_tx_reclaim(priv, &priv->tx_rings[q]);
+}
+
+static int bcm_sysport_poll(struct napi_struct *napi, int budget)
+{
+ struct bcm_sysport_priv *priv =
+ container_of(napi, struct bcm_sysport_priv, napi);
+ unsigned int work_done = 0;
+
+ work_done = bcm_sysport_desc_rx(priv, budget);
+
+ priv->rx_c_index += work_done;
+ priv->rx_c_index &= RDMA_CONS_INDEX_MASK;
+ rdma_writel(priv, priv->rx_c_index, RDMA_CONS_INDEX);
+
+ if (work_done < budget) {
+ napi_complete(napi);
+ /* re-enable RX interrupts */
+ intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE);
+ }
+
+ return work_done;
+}
+
+
+/* RX and misc interrupt routine */
+static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) &
+ ~intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
+ intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR);
+
+ if (unlikely(priv->irq0_stat == 0)) {
+ netdev_warn(priv->netdev, "spurious RX interrupt\n");
+ return IRQ_NONE;
+ }
+
+ if (priv->irq0_stat & INTRL2_0_RDMA_MBDONE) {
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ /* disable RX interrupts */
+ intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE);
+ __napi_schedule(&priv->napi);
+ }
+ }
+
+ /* TX ring is full, perform a full reclaim since we do not know
+ * which one would trigger this interrupt
+ */
+ if (priv->irq0_stat & INTRL2_0_TX_RING_FULL)
+ bcm_sysport_tx_reclaim_all(priv);
+
+ return IRQ_HANDLED;
+}
+
+/* TX interrupt service routine */
+static irqreturn_t bcm_sysport_tx_isr(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct bcm_sysport_tx_ring *txr;
+ unsigned int ring;
+
+ priv->irq1_stat = intrl2_1_readl(priv, INTRL2_CPU_STATUS) &
+ ~intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+
+ if (unlikely(priv->irq1_stat == 0)) {
+ netdev_warn(priv->netdev, "spurious TX interrupt\n");
+ return IRQ_NONE;
+ }
+
+ for (ring = 0; ring < dev->num_tx_queues; ring++) {
+ if (!(priv->irq1_stat & BIT(ring)))
+ continue;
+
+ txr = &priv->tx_rings[ring];
+
+ if (likely(napi_schedule_prep(&txr->napi))) {
+ intrl2_1_mask_set(priv, BIT(ring));
+ __napi_schedule(&txr->napi);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int bcm_sysport_insert_tsb(struct sk_buff *skb, struct net_device *dev)
+{
+ struct sk_buff *nskb;
+ struct bcm_tsb *tsb;
+ u32 csum_info;
+ u8 ip_proto;
+ u16 csum_start;
+ u16 ip_ver;
+
+ /* Re-allocate SKB if needed */
+ if (unlikely(skb_headroom(skb) < sizeof(*tsb))) {
+ nskb = skb_realloc_headroom(skb, sizeof(*tsb));
+ dev_kfree_skb(skb);
+ if (!nskb) {
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
+ return -ENOMEM;
+ }
+ skb = nskb;
+ }
+
+ tsb = (struct bcm_tsb *)skb_push(skb, sizeof(*tsb));
+ /* Zero-out TSB by default */
+ memset(tsb, 0, sizeof(*tsb));
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ ip_ver = htons(skb->protocol);
+ switch (ip_ver) {
+ case ETH_P_IP:
+ ip_proto = ip_hdr(skb)->protocol;
+ break;
+ case ETH_P_IPV6:
+ ip_proto = ipv6_hdr(skb)->nexthdr;
+ break;
+ default:
+ return 0;
+ }
+
+ /* Get the checksum offset and the L4 (transport) offset */
+ csum_start = skb_checksum_start_offset(skb) - sizeof(*tsb);
+ csum_info = (csum_start + skb->csum_offset) & L4_CSUM_PTR_MASK;
+ csum_info |= (csum_start << L4_PTR_SHIFT);
+
+ if (ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP) {
+ csum_info |= L4_LENGTH_VALID;
+ if (ip_proto == IPPROTO_UDP && ip_ver == ETH_P_IP)
+ csum_info |= L4_UDP;
+ } else
+ csum_info = 0;
+
+ tsb->l4_ptr_dest_map = csum_info;
+ }
+
+ return 0;
+}
+
+static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct device *kdev = &priv->pdev->dev;
+ struct bcm_sysport_tx_ring *ring;
+ struct bcm_sysport_cb *cb;
+ struct netdev_queue *txq;
+ struct dma_desc *desc;
+ unsigned int skb_len;
+ unsigned long flags;
+ dma_addr_t mapping;
+ u32 len_status;
+ u16 queue;
+ int ret;
+
+ queue = skb_get_queue_mapping(skb);
+ txq = netdev_get_tx_queue(dev, queue);
+ ring = &priv->tx_rings[queue];
+
+ /* lock against tx reclaim in BH context and TX ring full interrupt */
+ spin_lock_irqsave(&ring->lock, flags);
+ if (unlikely(ring->desc_count == 0)) {
+ netif_tx_stop_queue(txq);
+ netdev_err(dev, "queue %d awake and ring full!\n", queue);
+ ret = NETDEV_TX_BUSY;
+ goto out;
+ }
+
+ /* Insert TSB and checksum infos */
+ if (priv->tsb_en) {
+ ret = bcm_sysport_insert_tsb(skb, dev);
+ if (ret) {
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+ }
+
+ /* The Ethernet switch we are interfaced with needs packets to be at
+ * least 64 bytes (including FCS) otherwise they will be discarded when
+ * they enter the switch port logic. When Broadcom tags are enabled, we
+ * need to make sure that packets are at least 68 bytes
+ * (including FCS and tag) because the length verification is done after
+ * the Broadcom tag is stripped off the ingress packet.
+ */
+ if (skb_padto(skb, ETH_ZLEN + ENET_BRCM_TAG_LEN)) {
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+
+ skb_len = skb->len < ETH_ZLEN + ENET_BRCM_TAG_LEN ?
+ ETH_ZLEN + ENET_BRCM_TAG_LEN : skb->len;
+
+ mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE);
+ if (dma_mapping_error(kdev, mapping)) {
+ netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n",
+ skb->data, skb_len);
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+
+ /* Remember the SKB for future freeing */
+ cb = &ring->cbs[ring->curr_desc];
+ cb->skb = skb;
+ dma_unmap_addr_set(cb, dma_addr, mapping);
+ dma_unmap_len_set(cb, dma_len, skb_len);
+
+ /* Fetch a descriptor entry from our pool */
+ desc = ring->desc_cpu;
+
+ desc->addr_lo = lower_32_bits(mapping);
+ len_status = upper_32_bits(mapping) & DESC_ADDR_HI_MASK;
+ len_status |= (skb_len << DESC_LEN_SHIFT);
+ len_status |= (DESC_SOP | DESC_EOP | TX_STATUS_APP_CRC) <<
+ DESC_STATUS_SHIFT;
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ len_status |= (DESC_L4_CSUM << DESC_STATUS_SHIFT);
+
+ ring->curr_desc++;
+ if (ring->curr_desc == ring->size)
+ ring->curr_desc = 0;
+ ring->desc_count--;
+
+ /* Ensure write completion of the descriptor status/length
+ * in DRAM before the System Port WRITE_PORT register latches
+ * the value
+ */
+ wmb();
+ desc->addr_status_len = len_status;
+ wmb();
+
+ /* Write this descriptor address to the RING write port */
+ tdma_port_write_desc_addr(priv, desc, ring->index);
+
+ /* Check ring space and update SW control flow */
+ if (ring->desc_count == 0)
+ netif_tx_stop_queue(txq);
+
+ netif_dbg(priv, tx_queued, dev, "ring=%d desc_count=%d, curr_desc=%d\n",
+ ring->index, ring->desc_count, ring->curr_desc);
+
+ ret = NETDEV_TX_OK;
+out:
+ spin_unlock_irqrestore(&ring->lock, flags);
+ return ret;
+}
+
+static void bcm_sysport_tx_timeout(struct net_device *dev)
+{
+ netdev_warn(dev, "transmit timeout!\n");
+
+ dev->trans_start = jiffies;
+ dev->stats.tx_errors++;
+
+ netif_tx_wake_all_queues(dev);
+}
+
+/* phylib adjust link callback */
+static void bcm_sysport_adj_link(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+ unsigned int changed = 0;
+ u32 cmd_bits = 0, reg;
+
+ if (priv->old_link != phydev->link) {
+ changed = 1;
+ priv->old_link = phydev->link;
+ }
+
+ if (priv->old_duplex != phydev->duplex) {
+ changed = 1;
+ priv->old_duplex = phydev->duplex;
+ }
+
+ switch (phydev->speed) {
+ case SPEED_2500:
+ cmd_bits = CMD_SPEED_2500;
+ break;
+ case SPEED_1000:
+ cmd_bits = CMD_SPEED_1000;
+ break;
+ case SPEED_100:
+ cmd_bits = CMD_SPEED_100;
+ break;
+ case SPEED_10:
+ cmd_bits = CMD_SPEED_10;
+ break;
+ default:
+ break;
+ }
+ cmd_bits <<= CMD_SPEED_SHIFT;
+
+ if (phydev->duplex == DUPLEX_HALF)
+ cmd_bits |= CMD_HD_EN;
+
+ if (priv->old_pause != phydev->pause) {
+ changed = 1;
+ priv->old_pause = phydev->pause;
+ }
+
+ if (!phydev->pause)
+ cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
+
+ if (changed) {
+ reg = umac_readl(priv, UMAC_CMD);
+ reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
+ CMD_HD_EN | CMD_RX_PAUSE_IGNORE |
+ CMD_TX_PAUSE_IGNORE);
+ reg |= cmd_bits;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ phy_print_status(priv->phydev);
+ }
+}
+
+static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
+ unsigned int index)
+{
+ struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
+ struct device *kdev = &priv->pdev->dev;
+ size_t size;
+ void *p;
+ u32 reg;
+
+ /* Simple descriptors partitioning for now */
+ size = 256;
+
+ /* We just need one DMA descriptor which is DMA-able, since writing to
+ * the port will allocate a new descriptor in its internal linked-list
+ */
+ p = dma_zalloc_coherent(kdev, 1, &ring->desc_dma, GFP_KERNEL);
+ if (!p) {
+ netif_err(priv, hw, priv->netdev, "DMA alloc failed\n");
+ return -ENOMEM;
+ }
+
+ ring->cbs = kzalloc(sizeof(struct bcm_sysport_cb) * size, GFP_KERNEL);
+ if (!ring->cbs) {
+ netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
+ return -ENOMEM;
+ }
+
+ /* Initialize SW view of the ring */
+ spin_lock_init(&ring->lock);
+ ring->priv = priv;
+ netif_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64);
+ ring->index = index;
+ ring->size = size;
+ ring->alloc_size = ring->size;
+ ring->desc_cpu = p;
+ ring->desc_count = ring->size;
+ ring->curr_desc = 0;
+
+ /* Initialize HW ring */
+ tdma_writel(priv, RING_EN, TDMA_DESC_RING_HEAD_TAIL_PTR(index));
+ tdma_writel(priv, 0, TDMA_DESC_RING_COUNT(index));
+ tdma_writel(priv, 1, TDMA_DESC_RING_INTR_CONTROL(index));
+ tdma_writel(priv, 0, TDMA_DESC_RING_PROD_CONS_INDEX(index));
+ tdma_writel(priv, RING_IGNORE_STATUS, TDMA_DESC_RING_MAPPING(index));
+ tdma_writel(priv, 0, TDMA_DESC_RING_PCP_DEI_VID(index));
+
+ /* Program the number of descriptors as MAX_THRESHOLD and half of
+ * its size for the hysteresis trigger
+ */
+ tdma_writel(priv, ring->size |
+ 1 << RING_HYST_THRESH_SHIFT,
+ TDMA_DESC_RING_MAX_HYST(index));
+
+ /* Enable the ring queue in the arbiter */
+ reg = tdma_readl(priv, TDMA_TIER1_ARB_0_QUEUE_EN);
+ reg |= (1 << index);
+ tdma_writel(priv, reg, TDMA_TIER1_ARB_0_QUEUE_EN);
+
+ napi_enable(&ring->napi);
+
+ netif_dbg(priv, hw, priv->netdev,
+ "TDMA cfg, size=%d, desc_cpu=%p\n",
+ ring->size, ring->desc_cpu);
+
+ return 0;
+}
+
+static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
+ unsigned int index)
+{
+ struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
+ struct device *kdev = &priv->pdev->dev;
+ u32 reg;
+
+ /* Caller should stop the TDMA engine */
+ reg = tdma_readl(priv, TDMA_STATUS);
+ if (!(reg & TDMA_DISABLED))
+ netdev_warn(priv->netdev, "TDMA not stopped!\n");
+
+ napi_disable(&ring->napi);
+ netif_napi_del(&ring->napi);
+
+ bcm_sysport_tx_reclaim(priv, ring);
+
+ kfree(ring->cbs);
+ ring->cbs = NULL;
+
+ if (ring->desc_dma) {
+ dma_free_coherent(kdev, 1, ring->desc_cpu, ring->desc_dma);
+ ring->desc_dma = 0;
+ }
+ ring->size = 0;
+ ring->alloc_size = 0;
+
+ netif_dbg(priv, hw, priv->netdev, "TDMA fini done\n");
+}
+
+/* RDMA helper */
+static inline int rdma_enable_set(struct bcm_sysport_priv *priv,
+ unsigned int enable)
+{
+ unsigned int timeout = 1000;
+ u32 reg;
+
+ reg = rdma_readl(priv, RDMA_CONTROL);
+ if (enable)
+ reg |= RDMA_EN;
+ else
+ reg &= ~RDMA_EN;
+ rdma_writel(priv, reg, RDMA_CONTROL);
+
+ /* Poll for RMDA disabling completion */
+ do {
+ reg = rdma_readl(priv, RDMA_STATUS);
+ if (!!(reg & RDMA_DISABLED) == !enable)
+ return 0;
+ usleep_range(1000, 2000);
+ } while (timeout-- > 0);
+
+ netdev_err(priv->netdev, "timeout waiting for RDMA to finish\n");
+
+ return -ETIMEDOUT;
+}
+
+/* TDMA helper */
+static inline int tdma_enable_set(struct bcm_sysport_priv *priv,
+ unsigned int enable)
+{
+ unsigned int timeout = 1000;
+ u32 reg;
+
+ reg = tdma_readl(priv, TDMA_CONTROL);
+ if (enable)
+ reg |= TDMA_EN;
+ else
+ reg &= ~TDMA_EN;
+ tdma_writel(priv, reg, TDMA_CONTROL);
+
+ /* Poll for TMDA disabling completion */
+ do {
+ reg = tdma_readl(priv, TDMA_STATUS);
+ if (!!(reg & TDMA_DISABLED) == !enable)
+ return 0;
+
+ usleep_range(1000, 2000);
+ } while (timeout-- > 0);
+
+ netdev_err(priv->netdev, "timeout waiting for TDMA to finish\n");
+
+ return -ETIMEDOUT;
+}
+
+static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
+{
+ u32 reg;
+ int ret;
+
+ /* Initialize SW view of the RX ring */
+ priv->num_rx_bds = NUM_RX_DESC;
+ priv->rx_bds = priv->base + SYS_PORT_RDMA_OFFSET;
+ priv->rx_bd_assign_ptr = priv->rx_bds;
+ priv->rx_bd_assign_index = 0;
+ priv->rx_c_index = 0;
+ priv->rx_read_ptr = 0;
+ priv->rx_cbs = kzalloc(priv->num_rx_bds *
+ sizeof(struct bcm_sysport_cb), GFP_KERNEL);
+ if (!priv->rx_cbs) {
+ netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
+ return -ENOMEM;
+ }
+
+ ret = bcm_sysport_alloc_rx_bufs(priv);
+ if (ret) {
+ netif_err(priv, hw, priv->netdev, "SKB allocation failed\n");
+ return ret;
+ }
+
+ /* Initialize HW, ensure RDMA is disabled */
+ reg = rdma_readl(priv, RDMA_STATUS);
+ if (!(reg & RDMA_DISABLED))
+ rdma_enable_set(priv, 0);
+
+ rdma_writel(priv, 0, RDMA_WRITE_PTR_LO);
+ rdma_writel(priv, 0, RDMA_WRITE_PTR_HI);
+ rdma_writel(priv, 0, RDMA_PROD_INDEX);
+ rdma_writel(priv, 0, RDMA_CONS_INDEX);
+ rdma_writel(priv, priv->num_rx_bds << RDMA_RING_SIZE_SHIFT |
+ RX_BUF_LENGTH, RDMA_RING_BUF_SIZE);
+ /* Operate the queue in ring mode */
+ rdma_writel(priv, 0, RDMA_START_ADDR_HI);
+ rdma_writel(priv, 0, RDMA_START_ADDR_LO);
+ rdma_writel(priv, 0, RDMA_END_ADDR_HI);
+ rdma_writel(priv, NUM_HW_RX_DESC_WORDS - 1, RDMA_END_ADDR_LO);
+
+ rdma_writel(priv, 1, RDMA_MBDONE_INTR);
+
+ netif_dbg(priv, hw, priv->netdev,
+ "RDMA cfg, num_rx_bds=%d, rx_bds=%p\n",
+ priv->num_rx_bds, priv->rx_bds);
+
+ return 0;
+}
+
+static void bcm_sysport_fini_rx_ring(struct bcm_sysport_priv *priv)
+{
+ struct bcm_sysport_cb *cb;
+ unsigned int i;
+ u32 reg;
+
+ /* Caller should ensure RDMA is disabled */
+ reg = rdma_readl(priv, RDMA_STATUS);
+ if (!(reg & RDMA_DISABLED))
+ netdev_warn(priv->netdev, "RDMA not stopped!\n");
+
+ for (i = 0; i < priv->num_rx_bds; i++) {
+ cb = &priv->rx_cbs[i];
+ if (dma_unmap_addr(cb, dma_addr))
+ dma_unmap_single(&priv->pdev->dev,
+ dma_unmap_addr(cb, dma_addr),
+ RX_BUF_LENGTH, DMA_FROM_DEVICE);
+ bcm_sysport_free_cb(cb);
+ }
+
+ kfree(priv->rx_cbs);
+ priv->rx_cbs = NULL;
+
+ netif_dbg(priv, hw, priv->netdev, "RDMA fini done\n");
+}
+
+static void bcm_sysport_set_rx_mode(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ reg = umac_readl(priv, UMAC_CMD);
+ if (dev->flags & IFF_PROMISC)
+ reg |= CMD_PROMISC;
+ else
+ reg &= ~CMD_PROMISC;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ /* No support for ALLMULTI */
+ if (dev->flags & IFF_ALLMULTI)
+ return;
+}
+
+static inline void umac_enable_set(struct bcm_sysport_priv *priv,
+ unsigned int enable)
+{
+ u32 reg;
+
+ reg = umac_readl(priv, UMAC_CMD);
+ if (enable)
+ reg |= CMD_RX_EN | CMD_TX_EN;
+ else
+ reg &= ~(CMD_RX_EN | CMD_TX_EN);
+ umac_writel(priv, reg, UMAC_CMD);
+
+ /* UniMAC stops on a packet boundary, wait for a full-sized packet
+ * to be processed (1 msec).
+ */
+ if (enable == 0)
+ usleep_range(1000, 2000);
+}
+
+static inline void umac_reset(struct bcm_sysport_priv *priv)
+{
+ u32 reg;
+
+ reg = umac_readl(priv, UMAC_CMD);
+ reg |= CMD_SW_RESET;
+ umac_writel(priv, reg, UMAC_CMD);
+ udelay(10);
+ reg = umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_SW_RESET;
+ umac_writel(priv, reg, UMAC_CMD);
+}
+
+static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
+ unsigned char *addr)
+{
+ umac_writel(priv, (addr[0] << 24) | (addr[1] << 16) |
+ (addr[2] << 8) | addr[3], UMAC_MAC0);
+ umac_writel(priv, (addr[4] << 8) | addr[5], UMAC_MAC1);
+}
+
+static void topctrl_flush(struct bcm_sysport_priv *priv)
+{
+ topctrl_writel(priv, RX_FLUSH, RX_FLUSH_CNTL);
+ topctrl_writel(priv, TX_FLUSH, TX_FLUSH_CNTL);
+ mdelay(1);
+ topctrl_writel(priv, 0, RX_FLUSH_CNTL);
+ topctrl_writel(priv, 0, TX_FLUSH_CNTL);
+}
+
+static int bcm_sysport_open(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ unsigned int i;
+ u32 reg;
+ int ret;
+
+ /* Reset UniMAC */
+ umac_reset(priv);
+
+ /* Flush TX and RX FIFOs at TOPCTRL level */
+ topctrl_flush(priv);
+
+ /* Disable the UniMAC RX/TX */
+ umac_enable_set(priv, 0);
+
+ /* Enable RBUF 2bytes alignment and Receive Status Block */
+ reg = rbuf_readl(priv, RBUF_CONTROL);
+ reg |= RBUF_4B_ALGN | RBUF_RSB_EN;
+ rbuf_writel(priv, reg, RBUF_CONTROL);
+
+ /* Set maximum frame length */
+ umac_writel(priv, UMAC_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+
+ /* Set MAC address */
+ umac_set_hw_addr(priv, dev->dev_addr);
+
+ /* Read CRC forward */
+ priv->crc_fwd = !!(umac_readl(priv, UMAC_CMD) & CMD_CRC_FWD);
+
+ priv->phydev = of_phy_connect(dev, priv->phy_dn, bcm_sysport_adj_link,
+ 0, priv->phy_interface);
+ if (!priv->phydev) {
+ netdev_err(dev, "could not attach to PHY\n");
+ return -ENODEV;
+ }
+
+ /* Reset house keeping link status */
+ priv->old_duplex = -1;
+ priv->old_link = -1;
+ priv->old_pause = -1;
+
+ /* mask all interrupts and request them */
+ intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
+ intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+
+ ret = request_irq(priv->irq0, bcm_sysport_rx_isr, 0, dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "failed to request RX interrupt\n");
+ goto out_phy_disconnect;
+ }
+
+ ret = request_irq(priv->irq1, bcm_sysport_tx_isr, 0, dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "failed to request TX interrupt\n");
+ goto out_free_irq0;
+ }
+
+ /* Initialize both hardware and software ring */
+ for (i = 0; i < dev->num_tx_queues; i++) {
+ ret = bcm_sysport_init_tx_ring(priv, i);
+ if (ret) {
+ netdev_err(dev, "failed to initialize TX ring %d\n",
+ i);
+ goto out_free_tx_ring;
+ }
+ }
+
+ /* Initialize linked-list */
+ tdma_writel(priv, TDMA_LL_RAM_INIT_BUSY, TDMA_STATUS);
+
+ /* Initialize RX ring */
+ ret = bcm_sysport_init_rx_ring(priv);
+ if (ret) {
+ netdev_err(dev, "failed to initialize RX ring\n");
+ goto out_free_rx_ring;
+ }
+
+ /* Turn on RDMA */
+ ret = rdma_enable_set(priv, 1);
+ if (ret)
+ goto out_free_rx_ring;
+
+ /* Enable RX interrupt and TX ring full interrupt */
+ intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+
+ /* Turn on TDMA */
+ ret = tdma_enable_set(priv, 1);
+ if (ret)
+ goto out_clear_rx_int;
+
+ /* Enable NAPI */
+ napi_enable(&priv->napi);
+
+ /* Turn on UniMAC TX/RX */
+ umac_enable_set(priv, 1);
+
+ phy_start(priv->phydev);
+
+ /* Enable TX interrupts for the 32 TXQs */
+ intrl2_1_mask_clear(priv, 0xffffffff);
+
+ /* Last call before we start the real business */
+ netif_tx_start_all_queues(dev);
+
+ return 0;
+
+out_clear_rx_int:
+ intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+out_free_rx_ring:
+ bcm_sysport_fini_rx_ring(priv);
+out_free_tx_ring:
+ for (i = 0; i < dev->num_tx_queues; i++)
+ bcm_sysport_fini_tx_ring(priv, i);
+ free_irq(priv->irq1, dev);
+out_free_irq0:
+ free_irq(priv->irq0, dev);
+out_phy_disconnect:
+ phy_disconnect(priv->phydev);
+ return ret;
+}
+
+static int bcm_sysport_stop(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ unsigned int i;
+ u32 reg;
+ int ret;
+
+ /* stop all software from updating hardware */
+ netif_tx_stop_all_queues(dev);
+ napi_disable(&priv->napi);
+ phy_stop(priv->phydev);
+
+ /* mask all interrupts */
+ intrl2_0_mask_set(priv, 0xffffffff);
+ intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ intrl2_1_mask_set(priv, 0xffffffff);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+
+ /* Disable UniMAC RX */
+ reg = umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_RX_EN;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ ret = tdma_enable_set(priv, 0);
+ if (ret) {
+ netdev_err(dev, "timeout disabling RDMA\n");
+ return ret;
+ }
+
+ /* Wait for a maximum packet size to be drained */
+ usleep_range(2000, 3000);
+
+ ret = rdma_enable_set(priv, 0);
+ if (ret) {
+ netdev_err(dev, "timeout disabling TDMA\n");
+ return ret;
+ }
+
+ /* Disable UniMAC TX */
+ reg = umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_TX_EN;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ /* Free RX/TX rings SW structures */
+ for (i = 0; i < dev->num_tx_queues; i++)
+ bcm_sysport_fini_tx_ring(priv, i);
+ bcm_sysport_fini_rx_ring(priv);
+
+ free_irq(priv->irq0, dev);
+ free_irq(priv->irq1, dev);
+
+ /* Disconnect from PHY */
+ phy_disconnect(priv->phydev);
+
+ return 0;
+}
+
+static struct ethtool_ops bcm_sysport_ethtool_ops = {
+ .get_settings = bcm_sysport_get_settings,
+ .set_settings = bcm_sysport_set_settings,
+ .get_drvinfo = bcm_sysport_get_drvinfo,
+ .get_msglevel = bcm_sysport_get_msglvl,
+ .set_msglevel = bcm_sysport_set_msglvl,
+ .get_link = ethtool_op_get_link,
+ .get_strings = bcm_sysport_get_strings,
+ .get_ethtool_stats = bcm_sysport_get_stats,
+ .get_sset_count = bcm_sysport_get_sset_count,
+};
+
+static const struct net_device_ops bcm_sysport_netdev_ops = {
+ .ndo_start_xmit = bcm_sysport_xmit,
+ .ndo_tx_timeout = bcm_sysport_tx_timeout,
+ .ndo_open = bcm_sysport_open,
+ .ndo_stop = bcm_sysport_stop,
+ .ndo_set_features = bcm_sysport_set_features,
+ .ndo_set_rx_mode = bcm_sysport_set_rx_mode,
+};
+
+#define REV_FMT "v%2x.%02x"
+
+static int bcm_sysport_probe(struct platform_device *pdev)
+{
+ struct bcm_sysport_priv *priv;
+ struct device_node *dn;
+ struct net_device *dev;
+ const void *macaddr;
+ struct resource *r;
+ u32 txq, rxq;
+ int ret;
+
+ dn = pdev->dev.of_node;
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ /* Read the Transmit/Receive Queue properties */
+ if (of_property_read_u32(dn, "systemport,num-txq", &txq))
+ txq = TDMA_NUM_RINGS;
+ if (of_property_read_u32(dn, "systemport,num-rxq", &rxq))
+ rxq = 1;
+
+ dev = alloc_etherdev_mqs(sizeof(*priv), txq, rxq);
+ if (!dev)
+ return -ENOMEM;
+
+ /* Initialize private members */
+ priv = netdev_priv(dev);
+
+ priv->irq0 = platform_get_irq(pdev, 0);
+ priv->irq1 = platform_get_irq(pdev, 1);
+ if (priv->irq0 <= 0 || priv->irq1 <= 0) {
+ dev_err(&pdev->dev, "invalid interrupts\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ priv->base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(priv->base)) {
+ ret = PTR_ERR(priv->base);
+ goto err;
+ }
+
+ priv->netdev = dev;
+ priv->pdev = pdev;
+
+ priv->phy_interface = of_get_phy_mode(dn);
+ /* Default to GMII interface mode */
+ if (priv->phy_interface < 0)
+ priv->phy_interface = PHY_INTERFACE_MODE_GMII;
+
+ /* In the case of a fixed PHY, the DT node associated
+ * to the PHY is the Ethernet MAC DT node.
+ */
+ if (of_phy_is_fixed_link(dn)) {
+ ret = of_phy_register_fixed_link(dn);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register fixed PHY\n");
+ goto err;
+ }
+
+ priv->phy_dn = dn;
+ }
+
+ /* Initialize netdevice members */
+ macaddr = of_get_mac_address(dn);
+ if (!macaddr || !is_valid_ether_addr(macaddr)) {
+ dev_warn(&pdev->dev, "using random Ethernet MAC\n");
+ random_ether_addr(dev->dev_addr);
+ } else {
+ ether_addr_copy(dev->dev_addr, macaddr);
+ }
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev_set_drvdata(&pdev->dev, dev);
+ dev->ethtool_ops = &bcm_sysport_ethtool_ops;
+ dev->netdev_ops = &bcm_sysport_netdev_ops;
+ netif_napi_add(dev, &priv->napi, bcm_sysport_poll, 64);
+
+ /* HW supported features, none enabled by default */
+ dev->hw_features |= NETIF_F_RXCSUM | NETIF_F_HIGHDMA |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+ /* Set the needed headroom once and for all */
+ BUILD_BUG_ON(sizeof(struct bcm_tsb) != 8);
+ dev->needed_headroom += sizeof(struct bcm_tsb);
+
+ /* libphy will adjust the link state accordingly */
+ netif_carrier_off(dev);
+
+ ret = register_netdev(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register net_device\n");
+ goto err;
+ }
+
+ priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
+ dev_info(&pdev->dev,
+ "Broadcom SYSTEMPORT" REV_FMT
+ " at 0x%p (irqs: %d, %d, TXQs: %d, RXQs: %d)\n",
+ (priv->rev >> 8) & 0xff, priv->rev & 0xff,
+ priv->base, priv->irq0, priv->irq1, txq, rxq);
+
+ return 0;
+err:
+ free_netdev(dev);
+ return ret;
+}
+
+static int bcm_sysport_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = dev_get_drvdata(&pdev->dev);
+
+ /* Not much to do, ndo_close has been called
+ * and we use managed allocations
+ */
+ unregister_netdev(dev);
+ free_netdev(dev);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id bcm_sysport_of_match[] = {
+ { .compatible = "brcm,systemport-v1.00" },
+ { .compatible = "brcm,systemport" },
+ { /* sentinel */ }
+};
+
+static struct platform_driver bcm_sysport_driver = {
+ .probe = bcm_sysport_probe,
+ .remove = bcm_sysport_remove,
+ .driver = {
+ .name = "brcm-systemport",
+ .owner = THIS_MODULE,
+ .of_match_table = bcm_sysport_of_match,
+ },
+};
+module_platform_driver(bcm_sysport_driver);
+
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_DESCRIPTION("Broadcom System Port Ethernet MAC driver");
+MODULE_ALIAS("platform:brcm-systemport");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
new file mode 100644
index 00000000000..281c0824603
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -0,0 +1,678 @@
+/*
+ * Broadcom BCM7xxx System Port Ethernet MAC driver
+ *
+ * Copyright (C) 2014 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __BCM_SYSPORT_H
+#define __BCM_SYSPORT_H
+
+#include <linux/if_vlan.h>
+
+/* Receive/transmit descriptor format */
+#define DESC_ADDR_HI_STATUS_LEN 0x00
+#define DESC_ADDR_HI_SHIFT 0
+#define DESC_ADDR_HI_MASK 0xff
+#define DESC_STATUS_SHIFT 8
+#define DESC_STATUS_MASK 0x3ff
+#define DESC_LEN_SHIFT 18
+#define DESC_LEN_MASK 0x7fff
+#define DESC_ADDR_LO 0x04
+
+/* HW supports 40-bit addressing hence the */
+#define DESC_SIZE (WORDS_PER_DESC * sizeof(u32))
+
+/* Default RX buffer allocation size */
+#define RX_BUF_LENGTH 2048
+
+/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(4) + FCS(4) = 1526.
+ * 1536 is multiple of 256 bytes
+ */
+#define ENET_BRCM_TAG_LEN 4
+#define ENET_PAD 10
+#define UMAC_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \
+ ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
+
+/* Transmit status block */
+struct bcm_tsb {
+ u32 pcp_dei_vid;
+#define PCP_DEI_MASK 0xf
+#define VID_SHIFT 4
+#define VID_MASK 0xfff
+ u32 l4_ptr_dest_map;
+#define L4_CSUM_PTR_MASK 0x1ff
+#define L4_PTR_SHIFT 9
+#define L4_PTR_MASK 0x1ff
+#define L4_UDP (1 << 18)
+#define L4_LENGTH_VALID (1 << 19)
+#define DEST_MAP_SHIFT 20
+#define DEST_MAP_MASK 0x1ff
+};
+
+/* Receive status block uses the same
+ * definitions as the DMA descriptor
+ */
+struct bcm_rsb {
+ u32 rx_status_len;
+ u32 brcm_egress_tag;
+};
+
+/* Common Receive/Transmit status bits */
+#define DESC_L4_CSUM (1 << 7)
+#define DESC_SOP (1 << 8)
+#define DESC_EOP (1 << 9)
+
+/* Receive Status bits */
+#define RX_STATUS_UCAST 0
+#define RX_STATUS_BCAST 0x04
+#define RX_STATUS_MCAST 0x08
+#define RX_STATUS_L2_MCAST 0x0c
+#define RX_STATUS_ERR (1 << 4)
+#define RX_STATUS_OVFLOW (1 << 5)
+#define RX_STATUS_PARSE_FAIL (1 << 6)
+
+/* Transmit Status bits */
+#define TX_STATUS_VLAN_NO_ACT 0x00
+#define TX_STATUS_VLAN_PCP_TSB 0x01
+#define TX_STATUS_VLAN_QUEUE 0x02
+#define TX_STATUS_VLAN_VID_TSB 0x03
+#define TX_STATUS_OWR_CRC (1 << 2)
+#define TX_STATUS_APP_CRC (1 << 3)
+#define TX_STATUS_BRCM_TAG_NO_ACT 0
+#define TX_STATUS_BRCM_TAG_ZERO 0x10
+#define TX_STATUS_BRCM_TAG_ONE_QUEUE 0x20
+#define TX_STATUS_BRCM_TAG_ONE_TSB 0x30
+#define TX_STATUS_SKIP_BYTES (1 << 6)
+
+/* Specific register definitions */
+#define SYS_PORT_TOPCTRL_OFFSET 0
+#define REV_CNTL 0x00
+#define REV_MASK 0xffff
+
+#define RX_FLUSH_CNTL 0x04
+#define RX_FLUSH (1 << 0)
+
+#define TX_FLUSH_CNTL 0x08
+#define TX_FLUSH (1 << 0)
+
+#define MISC_CNTL 0x0c
+#define SYS_CLK_SEL (1 << 0)
+#define TDMA_EOP_SEL (1 << 1)
+
+/* Level-2 Interrupt controller offsets and defines */
+#define SYS_PORT_INTRL2_0_OFFSET 0x200
+#define SYS_PORT_INTRL2_1_OFFSET 0x240
+#define INTRL2_CPU_STATUS 0x00
+#define INTRL2_CPU_SET 0x04
+#define INTRL2_CPU_CLEAR 0x08
+#define INTRL2_CPU_MASK_STATUS 0x0c
+#define INTRL2_CPU_MASK_SET 0x10
+#define INTRL2_CPU_MASK_CLEAR 0x14
+
+/* Level-2 instance 0 interrupt bits */
+#define INTRL2_0_GISB_ERR (1 << 0)
+#define INTRL2_0_RBUF_OVFLOW (1 << 1)
+#define INTRL2_0_TBUF_UNDFLOW (1 << 2)
+#define INTRL2_0_MPD (1 << 3)
+#define INTRL2_0_BRCM_MATCH_TAG (1 << 4)
+#define INTRL2_0_RDMA_MBDONE (1 << 5)
+#define INTRL2_0_OVER_MAX_THRESH (1 << 6)
+#define INTRL2_0_BELOW_HYST_THRESH (1 << 7)
+#define INTRL2_0_FREE_LIST_EMPTY (1 << 8)
+#define INTRL2_0_TX_RING_FULL (1 << 9)
+#define INTRL2_0_DESC_ALLOC_ERR (1 << 10)
+#define INTRL2_0_UNEXP_PKTSIZE_ACK (1 << 11)
+
+/* RXCHK offset and defines */
+#define SYS_PORT_RXCHK_OFFSET 0x300
+
+#define RXCHK_CONTROL 0x00
+#define RXCHK_EN (1 << 0)
+#define RXCHK_SKIP_FCS (1 << 1)
+#define RXCHK_BAD_CSUM_DIS (1 << 2)
+#define RXCHK_BRCM_TAG_EN (1 << 3)
+#define RXCHK_BRCM_TAG_MATCH_SHIFT 4
+#define RXCHK_BRCM_TAG_MATCH_MASK 0xff
+#define RXCHK_PARSE_TNL (1 << 12)
+#define RXCHK_VIOL_EN (1 << 13)
+#define RXCHK_VIOL_DIS (1 << 14)
+#define RXCHK_INCOM_PKT (1 << 15)
+#define RXCHK_V6_DUPEXT_EN (1 << 16)
+#define RXCHK_V6_DUPEXT_DIS (1 << 17)
+#define RXCHK_ETHERTYPE_DIS (1 << 18)
+#define RXCHK_L2_HDR_DIS (1 << 19)
+#define RXCHK_L3_HDR_DIS (1 << 20)
+#define RXCHK_MAC_RX_ERR_DIS (1 << 21)
+#define RXCHK_PARSE_AUTH (1 << 22)
+
+#define RXCHK_BRCM_TAG0 0x04
+#define RXCHK_BRCM_TAG(i) ((i) * RXCHK_BRCM_TAG0)
+#define RXCHK_BRCM_TAG0_MASK 0x24
+#define RXCHK_BRCM_TAG_MASK(i) ((i) * RXCHK_BRCM_TAG0_MASK)
+#define RXCHK_BRCM_TAG_MATCH_STATUS 0x44
+#define RXCHK_ETHERTYPE 0x48
+#define RXCHK_BAD_CSUM_CNTR 0x4C
+#define RXCHK_OTHER_DISC_CNTR 0x50
+
+/* TXCHCK offsets and defines */
+#define SYS_PORT_TXCHK_OFFSET 0x380
+#define TXCHK_PKT_RDY_THRESH 0x00
+
+/* Receive buffer offset and defines */
+#define SYS_PORT_RBUF_OFFSET 0x400
+
+#define RBUF_CONTROL 0x00
+#define RBUF_RSB_EN (1 << 0)
+#define RBUF_4B_ALGN (1 << 1)
+#define RBUF_BRCM_TAG_STRIP (1 << 2)
+#define RBUF_BAD_PKT_DISC (1 << 3)
+#define RBUF_RESUME_THRESH_SHIFT 4
+#define RBUF_RESUME_THRESH_MASK 0xff
+#define RBUF_OK_TO_SEND_SHIFT 12
+#define RBUF_OK_TO_SEND_MASK 0xff
+#define RBUF_CRC_REPLACE (1 << 20)
+#define RBUF_OK_TO_SEND_MODE (1 << 21)
+#define RBUF_RSB_SWAP (1 << 22)
+#define RBUF_ACPI_EN (1 << 23)
+
+#define RBUF_PKT_RDY_THRESH 0x04
+
+#define RBUF_STATUS 0x08
+#define RBUF_WOL_MODE (1 << 0)
+#define RBUF_MPD (1 << 1)
+#define RBUF_ACPI (1 << 2)
+
+#define RBUF_OVFL_DISC_CNTR 0x0c
+#define RBUF_ERR_PKT_CNTR 0x10
+
+/* Transmit buffer offset and defines */
+#define SYS_PORT_TBUF_OFFSET 0x600
+
+#define TBUF_CONTROL 0x00
+#define TBUF_BP_EN (1 << 0)
+#define TBUF_MAX_PKT_THRESH_SHIFT 1
+#define TBUF_MAX_PKT_THRESH_MASK 0x1f
+#define TBUF_FULL_THRESH_SHIFT 8
+#define TBUF_FULL_THRESH_MASK 0x1f
+
+/* UniMAC offset and defines */
+#define SYS_PORT_UMAC_OFFSET 0x800
+
+#define UMAC_CMD 0x008
+#define CMD_TX_EN (1 << 0)
+#define CMD_RX_EN (1 << 1)
+#define CMD_SPEED_SHIFT 2
+#define CMD_SPEED_10 0
+#define CMD_SPEED_100 1
+#define CMD_SPEED_1000 2
+#define CMD_SPEED_2500 3
+#define CMD_SPEED_MASK 3
+#define CMD_PROMISC (1 << 4)
+#define CMD_PAD_EN (1 << 5)
+#define CMD_CRC_FWD (1 << 6)
+#define CMD_PAUSE_FWD (1 << 7)
+#define CMD_RX_PAUSE_IGNORE (1 << 8)
+#define CMD_TX_ADDR_INS (1 << 9)
+#define CMD_HD_EN (1 << 10)
+#define CMD_SW_RESET (1 << 13)
+#define CMD_LCL_LOOP_EN (1 << 15)
+#define CMD_AUTO_CONFIG (1 << 22)
+#define CMD_CNTL_FRM_EN (1 << 23)
+#define CMD_NO_LEN_CHK (1 << 24)
+#define CMD_RMT_LOOP_EN (1 << 25)
+#define CMD_PRBL_EN (1 << 27)
+#define CMD_TX_PAUSE_IGNORE (1 << 28)
+#define CMD_TX_RX_EN (1 << 29)
+#define CMD_RUNT_FILTER_DIS (1 << 30)
+
+#define UMAC_MAC0 0x00c
+#define UMAC_MAC1 0x010
+#define UMAC_MAX_FRAME_LEN 0x014
+
+#define UMAC_TX_FLUSH 0x334
+
+#define UMAC_MIB_START 0x400
+
+/* There is a 0xC gap between the end of RX and beginning of TX stats and then
+ * between the end of TX stats and the beginning of the RX RUNT
+ */
+#define UMAC_MIB_STAT_OFFSET 0xc
+
+#define UMAC_MIB_CTRL 0x580
+#define MIB_RX_CNT_RST (1 << 0)
+#define MIB_RUNT_CNT_RST (1 << 1)
+#define MIB_TX_CNT_RST (1 << 2)
+#define UMAC_MDF_CTRL 0x650
+#define UMAC_MDF_ADDR 0x654
+
+/* Receive DMA offset and defines */
+#define SYS_PORT_RDMA_OFFSET 0x2000
+
+#define RDMA_CONTROL 0x1000
+#define RDMA_EN (1 << 0)
+#define RDMA_RING_CFG (1 << 1)
+#define RDMA_DISC_EN (1 << 2)
+#define RDMA_BUF_DATA_OFFSET_SHIFT 4
+#define RDMA_BUF_DATA_OFFSET_MASK 0x3ff
+
+#define RDMA_STATUS 0x1004
+#define RDMA_DISABLED (1 << 0)
+#define RDMA_DESC_RAM_INIT_BUSY (1 << 1)
+#define RDMA_BP_STATUS (1 << 2)
+
+#define RDMA_SCB_BURST_SIZE 0x1008
+
+#define RDMA_RING_BUF_SIZE 0x100c
+#define RDMA_RING_SIZE_SHIFT 16
+
+#define RDMA_WRITE_PTR_HI 0x1010
+#define RDMA_WRITE_PTR_LO 0x1014
+#define RDMA_PROD_INDEX 0x1018
+#define RDMA_PROD_INDEX_MASK 0xffff
+
+#define RDMA_CONS_INDEX 0x101c
+#define RDMA_CONS_INDEX_MASK 0xffff
+
+#define RDMA_START_ADDR_HI 0x1020
+#define RDMA_START_ADDR_LO 0x1024
+#define RDMA_END_ADDR_HI 0x1028
+#define RDMA_END_ADDR_LO 0x102c
+
+#define RDMA_MBDONE_INTR 0x1030
+#define RDMA_INTR_THRESH_MASK 0xff
+#define RDMA_TIMEOUT_SHIFT 16
+#define RDMA_TIMEOUT_MASK 0xffff
+
+#define RDMA_XON_XOFF_THRESH 0x1034
+#define RDMA_XON_XOFF_THRESH_MASK 0xffff
+#define RDMA_XOFF_THRESH_SHIFT 16
+
+#define RDMA_READ_PTR_HI 0x1038
+#define RDMA_READ_PTR_LO 0x103c
+
+#define RDMA_OVERRIDE 0x1040
+#define RDMA_LE_MODE (1 << 0)
+#define RDMA_REG_MODE (1 << 1)
+
+#define RDMA_TEST 0x1044
+#define RDMA_TP_OUT_SEL (1 << 0)
+#define RDMA_MEM_SEL (1 << 1)
+
+#define RDMA_DEBUG 0x1048
+
+/* Transmit DMA offset and defines */
+#define TDMA_NUM_RINGS 32 /* rings = queues */
+#define TDMA_PORT_SIZE DESC_SIZE /* two 32-bits words */
+
+#define SYS_PORT_TDMA_OFFSET 0x4000
+#define TDMA_WRITE_PORT_OFFSET 0x0000
+#define TDMA_WRITE_PORT_HI(i) (TDMA_WRITE_PORT_OFFSET + \
+ (i) * TDMA_PORT_SIZE)
+#define TDMA_WRITE_PORT_LO(i) (TDMA_WRITE_PORT_OFFSET + \
+ sizeof(u32) + (i) * TDMA_PORT_SIZE)
+
+#define TDMA_READ_PORT_OFFSET (TDMA_WRITE_PORT_OFFSET + \
+ (TDMA_NUM_RINGS * TDMA_PORT_SIZE))
+#define TDMA_READ_PORT_HI(i) (TDMA_READ_PORT_OFFSET + \
+ (i) * TDMA_PORT_SIZE)
+#define TDMA_READ_PORT_LO(i) (TDMA_READ_PORT_OFFSET + \
+ sizeof(u32) + (i) * TDMA_PORT_SIZE)
+
+#define TDMA_READ_PORT_CMD_OFFSET (TDMA_READ_PORT_OFFSET + \
+ (TDMA_NUM_RINGS * TDMA_PORT_SIZE))
+#define TDMA_READ_PORT_CMD(i) (TDMA_READ_PORT_CMD_OFFSET + \
+ (i) * sizeof(u32))
+
+#define TDMA_DESC_RING_00_BASE (TDMA_READ_PORT_CMD_OFFSET + \
+ (TDMA_NUM_RINGS * sizeof(u32)))
+
+/* Register offsets and defines relatives to a specific ring number */
+#define RING_HEAD_TAIL_PTR 0x00
+#define RING_HEAD_MASK 0x7ff
+#define RING_TAIL_SHIFT 11
+#define RING_TAIL_MASK 0x7ff
+#define RING_FLUSH (1 << 24)
+#define RING_EN (1 << 25)
+
+#define RING_COUNT 0x04
+#define RING_COUNT_MASK 0x7ff
+#define RING_BUFF_DONE_SHIFT 11
+#define RING_BUFF_DONE_MASK 0x7ff
+
+#define RING_MAX_HYST 0x08
+#define RING_MAX_THRESH_MASK 0x7ff
+#define RING_HYST_THRESH_SHIFT 11
+#define RING_HYST_THRESH_MASK 0x7ff
+
+#define RING_INTR_CONTROL 0x0c
+#define RING_INTR_THRESH_MASK 0x7ff
+#define RING_EMPTY_INTR_EN (1 << 15)
+#define RING_TIMEOUT_SHIFT 16
+#define RING_TIMEOUT_MASK 0xffff
+
+#define RING_PROD_CONS_INDEX 0x10
+#define RING_PROD_INDEX_MASK 0xffff
+#define RING_CONS_INDEX_SHIFT 16
+#define RING_CONS_INDEX_MASK 0xffff
+
+#define RING_MAPPING 0x14
+#define RING_QID_MASK 0x3
+#define RING_PORT_ID_SHIFT 3
+#define RING_PORT_ID_MASK 0x7
+#define RING_IGNORE_STATUS (1 << 6)
+#define RING_FAILOVER_EN (1 << 7)
+#define RING_CREDIT_SHIFT 8
+#define RING_CREDIT_MASK 0xffff
+
+#define RING_PCP_DEI_VID 0x18
+#define RING_VID_MASK 0x7ff
+#define RING_DEI (1 << 12)
+#define RING_PCP_SHIFT 13
+#define RING_PCP_MASK 0x7
+#define RING_PKT_SIZE_ADJ_SHIFT 16
+#define RING_PKT_SIZE_ADJ_MASK 0xf
+
+#define TDMA_DESC_RING_SIZE 28
+
+/* Defininition for a given TX ring base address */
+#define TDMA_DESC_RING_BASE(i) (TDMA_DESC_RING_00_BASE + \
+ ((i) * TDMA_DESC_RING_SIZE))
+
+/* Ring indexed register addreses */
+#define TDMA_DESC_RING_HEAD_TAIL_PTR(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_HEAD_TAIL_PTR)
+#define TDMA_DESC_RING_COUNT(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_COUNT)
+#define TDMA_DESC_RING_MAX_HYST(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_MAX_HYST)
+#define TDMA_DESC_RING_INTR_CONTROL(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_INTR_CONTROL)
+#define TDMA_DESC_RING_PROD_CONS_INDEX(i) \
+ (TDMA_DESC_RING_BASE(i) + \
+ RING_PROD_CONS_INDEX)
+#define TDMA_DESC_RING_MAPPING(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_MAPPING)
+#define TDMA_DESC_RING_PCP_DEI_VID(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_PCP_DEI_VID)
+
+#define TDMA_CONTROL 0x600
+#define TDMA_EN (1 << 0)
+#define TSB_EN (1 << 1)
+#define TSB_SWAP (1 << 2)
+#define ACB_ALGO (1 << 3)
+#define BUF_DATA_OFFSET_SHIFT 4
+#define BUF_DATA_OFFSET_MASK 0x3ff
+#define VLAN_EN (1 << 14)
+#define SW_BRCM_TAG (1 << 15)
+#define WNC_KPT_SIZE_UPDATE (1 << 16)
+#define SYNC_PKT_SIZE (1 << 17)
+#define ACH_TXDONE_DELAY_SHIFT 18
+#define ACH_TXDONE_DELAY_MASK 0xff
+
+#define TDMA_STATUS 0x604
+#define TDMA_DISABLED (1 << 0)
+#define TDMA_LL_RAM_INIT_BUSY (1 << 1)
+
+#define TDMA_SCB_BURST_SIZE 0x608
+#define TDMA_OVER_MAX_THRESH_STATUS 0x60c
+#define TDMA_OVER_HYST_THRESH_STATUS 0x610
+#define TDMA_TPID 0x614
+
+#define TDMA_FREE_LIST_HEAD_TAIL_PTR 0x618
+#define TDMA_FREE_HEAD_MASK 0x7ff
+#define TDMA_FREE_TAIL_SHIFT 11
+#define TDMA_FREE_TAIL_MASK 0x7ff
+
+#define TDMA_FREE_LIST_COUNT 0x61c
+#define TDMA_FREE_LIST_COUNT_MASK 0x7ff
+
+#define TDMA_TIER2_ARB_CTRL 0x620
+#define TDMA_ARB_MODE_RR 0
+#define TDMA_ARB_MODE_WEIGHT_RR 0x1
+#define TDMA_ARB_MODE_STRICT 0x2
+#define TDMA_ARB_MODE_DEFICIT_RR 0x3
+#define TDMA_CREDIT_SHIFT 4
+#define TDMA_CREDIT_MASK 0xffff
+
+#define TDMA_TIER1_ARB_0_CTRL 0x624
+#define TDMA_ARB_EN (1 << 0)
+
+#define TDMA_TIER1_ARB_0_QUEUE_EN 0x628
+#define TDMA_TIER1_ARB_1_CTRL 0x62c
+#define TDMA_TIER1_ARB_1_QUEUE_EN 0x630
+#define TDMA_TIER1_ARB_2_CTRL 0x634
+#define TDMA_TIER1_ARB_2_QUEUE_EN 0x638
+#define TDMA_TIER1_ARB_3_CTRL 0x63c
+#define TDMA_TIER1_ARB_3_QUEUE_EN 0x640
+
+#define TDMA_SCB_ENDIAN_OVERRIDE 0x644
+#define TDMA_LE_MODE (1 << 0)
+#define TDMA_REG_MODE (1 << 1)
+
+#define TDMA_TEST 0x648
+#define TDMA_TP_OUT_SEL (1 << 0)
+#define TDMA_MEM_TM (1 << 1)
+
+#define TDMA_DEBUG 0x64c
+
+/* Transmit/Receive descriptor */
+struct dma_desc {
+ u32 addr_status_len;
+ u32 addr_lo;
+};
+
+/* Number of Receive hardware descriptor words */
+#define NUM_HW_RX_DESC_WORDS 1024
+/* Real number of usable descriptors */
+#define NUM_RX_DESC (NUM_HW_RX_DESC_WORDS / WORDS_PER_DESC)
+
+/* Internal linked-list RAM has up to 1536 entries */
+#define NUM_TX_DESC 1536
+
+#define WORDS_PER_DESC (sizeof(struct dma_desc) / sizeof(u32))
+
+/* Rx/Tx common counter group.*/
+struct bcm_sysport_pkt_counters {
+ u32 cnt_64; /* RO Received/Transmited 64 bytes packet */
+ u32 cnt_127; /* RO Rx/Tx 127 bytes packet */
+ u32 cnt_255; /* RO Rx/Tx 65-255 bytes packet */
+ u32 cnt_511; /* RO Rx/Tx 256-511 bytes packet */
+ u32 cnt_1023; /* RO Rx/Tx 512-1023 bytes packet */
+ u32 cnt_1518; /* RO Rx/Tx 1024-1518 bytes packet */
+ u32 cnt_mgv; /* RO Rx/Tx 1519-1522 good VLAN packet */
+ u32 cnt_2047; /* RO Rx/Tx 1522-2047 bytes packet*/
+ u32 cnt_4095; /* RO Rx/Tx 2048-4095 bytes packet*/
+ u32 cnt_9216; /* RO Rx/Tx 4096-9216 bytes packet*/
+};
+
+/* RSV, Receive Status Vector */
+struct bcm_sysport_rx_counters {
+ struct bcm_sysport_pkt_counters pkt_cnt;
+ u32 pkt; /* RO (0x428) Received pkt count*/
+ u32 bytes; /* RO Received byte count */
+ u32 mca; /* RO # of Received multicast pkt */
+ u32 bca; /* RO # of Receive broadcast pkt */
+ u32 fcs; /* RO # of Received FCS error */
+ u32 cf; /* RO # of Received control frame pkt*/
+ u32 pf; /* RO # of Received pause frame pkt */
+ u32 uo; /* RO # of unknown op code pkt */
+ u32 aln; /* RO # of alignment error count */
+ u32 flr; /* RO # of frame length out of range count */
+ u32 cde; /* RO # of code error pkt */
+ u32 fcr; /* RO # of carrier sense error pkt */
+ u32 ovr; /* RO # of oversize pkt*/
+ u32 jbr; /* RO # of jabber count */
+ u32 mtue; /* RO # of MTU error pkt*/
+ u32 pok; /* RO # of Received good pkt */
+ u32 uc; /* RO # of unicast pkt */
+ u32 ppp; /* RO # of PPP pkt */
+ u32 rcrc; /* RO (0x470),# of CRC match pkt */
+};
+
+/* TSV, Transmit Status Vector */
+struct bcm_sysport_tx_counters {
+ struct bcm_sysport_pkt_counters pkt_cnt;
+ u32 pkts; /* RO (0x4a8) Transmited pkt */
+ u32 mca; /* RO # of xmited multicast pkt */
+ u32 bca; /* RO # of xmited broadcast pkt */
+ u32 pf; /* RO # of xmited pause frame count */
+ u32 cf; /* RO # of xmited control frame count */
+ u32 fcs; /* RO # of xmited FCS error count */
+ u32 ovr; /* RO # of xmited oversize pkt */
+ u32 drf; /* RO # of xmited deferral pkt */
+ u32 edf; /* RO # of xmited Excessive deferral pkt*/
+ u32 scl; /* RO # of xmited single collision pkt */
+ u32 mcl; /* RO # of xmited multiple collision pkt*/
+ u32 lcl; /* RO # of xmited late collision pkt */
+ u32 ecl; /* RO # of xmited excessive collision pkt*/
+ u32 frg; /* RO # of xmited fragments pkt*/
+ u32 ncl; /* RO # of xmited total collision count */
+ u32 jbr; /* RO # of xmited jabber count*/
+ u32 bytes; /* RO # of xmited byte count */
+ u32 pok; /* RO # of xmited good pkt */
+ u32 uc; /* RO (0x0x4f0)# of xmited unitcast pkt */
+};
+
+struct bcm_sysport_mib {
+ struct bcm_sysport_rx_counters rx;
+ struct bcm_sysport_tx_counters tx;
+ u32 rx_runt_cnt;
+ u32 rx_runt_fcs;
+ u32 rx_runt_fcs_align;
+ u32 rx_runt_bytes;
+ u32 rxchk_bad_csum;
+ u32 rxchk_other_pkt_disc;
+ u32 rbuf_ovflow_cnt;
+ u32 rbuf_err_cnt;
+};
+
+/* HW maintains a large list of counters */
+enum bcm_sysport_stat_type {
+ BCM_SYSPORT_STAT_NETDEV = -1,
+ BCM_SYSPORT_STAT_MIB_RX,
+ BCM_SYSPORT_STAT_MIB_TX,
+ BCM_SYSPORT_STAT_RUNT,
+ BCM_SYSPORT_STAT_RXCHK,
+ BCM_SYSPORT_STAT_RBUF,
+};
+
+/* Macros to help define ethtool statistics */
+#define STAT_NETDEV(m) { \
+ .stat_string = __stringify(m), \
+ .stat_sizeof = sizeof(((struct net_device_stats *)0)->m), \
+ .stat_offset = offsetof(struct net_device_stats, m), \
+ .type = BCM_SYSPORT_STAT_NETDEV, \
+}
+
+#define STAT_MIB(str, m, _type) { \
+ .stat_string = str, \
+ .stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+ .stat_offset = offsetof(struct bcm_sysport_priv, m), \
+ .type = _type, \
+}
+
+#define STAT_MIB_RX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_RX)
+#define STAT_MIB_TX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_TX)
+#define STAT_RUNT(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_RUNT)
+
+#define STAT_RXCHK(str, m, ofs) { \
+ .stat_string = str, \
+ .stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+ .stat_offset = offsetof(struct bcm_sysport_priv, m), \
+ .type = BCM_SYSPORT_STAT_RXCHK, \
+ .reg_offset = ofs, \
+}
+
+#define STAT_RBUF(str, m, ofs) { \
+ .stat_string = str, \
+ .stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+ .stat_offset = offsetof(struct bcm_sysport_priv, m), \
+ .type = BCM_SYSPORT_STAT_RBUF, \
+ .reg_offset = ofs, \
+}
+
+struct bcm_sysport_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int stat_sizeof;
+ int stat_offset;
+ enum bcm_sysport_stat_type type;
+ /* reg offset from UMAC base for misc counters */
+ u16 reg_offset;
+};
+
+/* Software house keeping helper structure */
+struct bcm_sysport_cb {
+ struct sk_buff *skb; /* SKB for RX packets */
+ void __iomem *bd_addr; /* Buffer descriptor PHYS addr */
+
+ DEFINE_DMA_UNMAP_ADDR(dma_addr);
+ DEFINE_DMA_UNMAP_LEN(dma_len);
+};
+
+/* Software view of the TX ring */
+struct bcm_sysport_tx_ring {
+ spinlock_t lock; /* Ring lock for tx reclaim/xmit */
+ struct napi_struct napi; /* NAPI per tx queue */
+ dma_addr_t desc_dma; /* DMA cookie */
+ unsigned int index; /* Ring index */
+ unsigned int size; /* Ring current size */
+ unsigned int alloc_size; /* Ring one-time allocated size */
+ unsigned int desc_count; /* Number of descriptors */
+ unsigned int curr_desc; /* Current descriptor */
+ unsigned int c_index; /* Last consumer index */
+ unsigned int p_index; /* Current producer index */
+ struct bcm_sysport_cb *cbs; /* Transmit control blocks */
+ struct dma_desc *desc_cpu; /* CPU view of the descriptor */
+ struct bcm_sysport_priv *priv; /* private context backpointer */
+};
+
+/* Driver private structure */
+struct bcm_sysport_priv {
+ void __iomem *base;
+ u32 irq0_stat;
+ u32 irq0_mask;
+ u32 irq1_stat;
+ u32 irq1_mask;
+ struct napi_struct napi ____cacheline_aligned;
+ struct net_device *netdev;
+ struct platform_device *pdev;
+ int irq0;
+ int irq1;
+
+ /* Transmit rings */
+ struct bcm_sysport_tx_ring tx_rings[TDMA_NUM_RINGS];
+
+ /* Receive queue */
+ void __iomem *rx_bds;
+ void __iomem *rx_bd_assign_ptr;
+ unsigned int rx_bd_assign_index;
+ struct bcm_sysport_cb *rx_cbs;
+ unsigned int num_rx_bds;
+ unsigned int rx_read_ptr;
+ unsigned int rx_c_index;
+
+ /* PHY device */
+ struct device_node *phy_dn;
+ struct phy_device *phydev;
+ phy_interface_t phy_interface;
+ int old_pause;
+ int old_link;
+ int old_duplex;
+
+ /* Misc fields */
+ unsigned int rx_csum_en:1;
+ unsigned int tsb_en:1;
+ unsigned int crc_fwd:1;
+ u16 rev;
+
+ /* MIB related fields */
+ struct bcm_sysport_mib mib;
+
+ /* Ethtool */
+ u32 msg_enable;
+};
+#endif /* __BCM_SYSPORT_H */
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
new file mode 100644
index 00000000000..05c6af6c418
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -0,0 +1,1588 @@
+/*
+ * Driver for (BCM4706)? GBit MAC core on BCMA bus.
+ *
+ * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bgmac.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <bcm47xx_nvram.h>
+
+static const struct bcma_device_id bgmac_bcma_tbl[] = {
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
+ BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
+ BCMA_CORETABLE_END
+};
+MODULE_DEVICE_TABLE(bcma, bgmac_bcma_tbl);
+
+static bool bgmac_wait_value(struct bcma_device *core, u16 reg, u32 mask,
+ u32 value, int timeout)
+{
+ u32 val;
+ int i;
+
+ for (i = 0; i < timeout / 10; i++) {
+ val = bcma_read32(core, reg);
+ if ((val & mask) == value)
+ return true;
+ udelay(10);
+ }
+ pr_err("Timeout waiting for reg 0x%X\n", reg);
+ return false;
+}
+
+/**************************************************
+ * DMA
+ **************************************************/
+
+static void bgmac_dma_tx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
+{
+ u32 val;
+ int i;
+
+ if (!ring->mmio_base)
+ return;
+
+ /* Suspend DMA TX ring first.
+ * bgmac_wait_value doesn't support waiting for any of few values, so
+ * implement whole loop here.
+ */
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL,
+ BGMAC_DMA_TX_SUSPEND);
+ for (i = 0; i < 10000 / 10; i++) {
+ val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
+ val &= BGMAC_DMA_TX_STAT;
+ if (val == BGMAC_DMA_TX_STAT_DISABLED ||
+ val == BGMAC_DMA_TX_STAT_IDLEWAIT ||
+ val == BGMAC_DMA_TX_STAT_STOPPED) {
+ i = 0;
+ break;
+ }
+ udelay(10);
+ }
+ if (i)
+ bgmac_err(bgmac, "Timeout suspending DMA TX ring 0x%X (BGMAC_DMA_TX_STAT: 0x%08X)\n",
+ ring->mmio_base, val);
+
+ /* Remove SUSPEND bit */
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, 0);
+ if (!bgmac_wait_value(bgmac->core,
+ ring->mmio_base + BGMAC_DMA_TX_STATUS,
+ BGMAC_DMA_TX_STAT, BGMAC_DMA_TX_STAT_DISABLED,
+ 10000)) {
+ bgmac_warn(bgmac, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n",
+ ring->mmio_base);
+ udelay(300);
+ val = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
+ if ((val & BGMAC_DMA_TX_STAT) != BGMAC_DMA_TX_STAT_DISABLED)
+ bgmac_err(bgmac, "Reset of DMA TX ring 0x%X failed\n",
+ ring->mmio_base);
+ }
+}
+
+static void bgmac_dma_tx_enable(struct bgmac *bgmac,
+ struct bgmac_dma_ring *ring)
+{
+ u32 ctl;
+
+ ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL);
+ if (bgmac->core->id.rev >= 4) {
+ ctl &= ~BGMAC_DMA_TX_BL_MASK;
+ ctl |= BGMAC_DMA_TX_BL_128 << BGMAC_DMA_TX_BL_SHIFT;
+
+ ctl &= ~BGMAC_DMA_TX_MR_MASK;
+ ctl |= BGMAC_DMA_TX_MR_2 << BGMAC_DMA_TX_MR_SHIFT;
+
+ ctl &= ~BGMAC_DMA_TX_PC_MASK;
+ ctl |= BGMAC_DMA_TX_PC_16 << BGMAC_DMA_TX_PC_SHIFT;
+
+ ctl &= ~BGMAC_DMA_TX_PT_MASK;
+ ctl |= BGMAC_DMA_TX_PT_8 << BGMAC_DMA_TX_PT_SHIFT;
+ }
+ ctl |= BGMAC_DMA_TX_ENABLE;
+ ctl |= BGMAC_DMA_TX_PARITY_DISABLE;
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl);
+}
+
+static netdev_tx_t bgmac_dma_tx_add(struct bgmac *bgmac,
+ struct bgmac_dma_ring *ring,
+ struct sk_buff *skb)
+{
+ struct device *dma_dev = bgmac->core->dma_dev;
+ struct net_device *net_dev = bgmac->net_dev;
+ struct bgmac_dma_desc *dma_desc;
+ struct bgmac_slot_info *slot;
+ u32 ctl0, ctl1;
+ int free_slots;
+
+ if (skb->len > BGMAC_DESC_CTL1_LEN) {
+ bgmac_err(bgmac, "Too long skb (%d)\n", skb->len);
+ goto err_stop_drop;
+ }
+
+ if (ring->start <= ring->end)
+ free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS;
+ else
+ free_slots = ring->start - ring->end;
+ if (free_slots == 1) {
+ bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n");
+ netif_stop_queue(net_dev);
+ return NETDEV_TX_BUSY;
+ }
+
+ slot = &ring->slots[ring->end];
+ slot->skb = skb;
+ slot->dma_addr = dma_map_single(dma_dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dma_dev, slot->dma_addr)) {
+ bgmac_err(bgmac, "Mapping error of skb on ring 0x%X\n",
+ ring->mmio_base);
+ goto err_stop_drop;
+ }
+
+ ctl0 = BGMAC_DESC_CTL0_IOC | BGMAC_DESC_CTL0_SOF | BGMAC_DESC_CTL0_EOF;
+ if (ring->end == ring->num_slots - 1)
+ ctl0 |= BGMAC_DESC_CTL0_EOT;
+ ctl1 = skb->len & BGMAC_DESC_CTL1_LEN;
+
+ dma_desc = ring->cpu_base;
+ dma_desc += ring->end;
+ dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr));
+ dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr));
+ dma_desc->ctl0 = cpu_to_le32(ctl0);
+ dma_desc->ctl1 = cpu_to_le32(ctl1);
+
+ netdev_sent_queue(net_dev, skb->len);
+
+ wmb();
+
+ /* Increase ring->end to point empty slot. We tell hardware the first
+ * slot it should *not* read.
+ */
+ if (++ring->end >= BGMAC_TX_RING_SLOTS)
+ ring->end = 0;
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
+ ring->index_base +
+ ring->end * sizeof(struct bgmac_dma_desc));
+
+ /* Always keep one slot free to allow detecting bugged calls. */
+ if (--free_slots == 1)
+ netif_stop_queue(net_dev);
+
+ return NETDEV_TX_OK;
+
+err_stop_drop:
+ netif_stop_queue(net_dev);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+/* Free transmitted packets */
+static void bgmac_dma_tx_free(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
+{
+ struct device *dma_dev = bgmac->core->dma_dev;
+ int empty_slot;
+ bool freed = false;
+ unsigned bytes_compl = 0, pkts_compl = 0;
+
+ /* The last slot that hardware didn't consume yet */
+ empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
+ empty_slot &= BGMAC_DMA_TX_STATDPTR;
+ empty_slot -= ring->index_base;
+ empty_slot &= BGMAC_DMA_TX_STATDPTR;
+ empty_slot /= sizeof(struct bgmac_dma_desc);
+
+ while (ring->start != empty_slot) {
+ struct bgmac_slot_info *slot = &ring->slots[ring->start];
+
+ if (slot->skb) {
+ /* Unmap no longer used buffer */
+ dma_unmap_single(dma_dev, slot->dma_addr,
+ slot->skb->len, DMA_TO_DEVICE);
+ slot->dma_addr = 0;
+
+ bytes_compl += slot->skb->len;
+ pkts_compl++;
+
+ /* Free memory! :) */
+ dev_kfree_skb(slot->skb);
+ slot->skb = NULL;
+ } else {
+ bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n",
+ ring->start, ring->end);
+ }
+
+ if (++ring->start >= BGMAC_TX_RING_SLOTS)
+ ring->start = 0;
+ freed = true;
+ }
+
+ netdev_completed_queue(bgmac->net_dev, pkts_compl, bytes_compl);
+
+ if (freed && netif_queue_stopped(bgmac->net_dev))
+ netif_wake_queue(bgmac->net_dev);
+}
+
+static void bgmac_dma_rx_reset(struct bgmac *bgmac, struct bgmac_dma_ring *ring)
+{
+ if (!ring->mmio_base)
+ return;
+
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, 0);
+ if (!bgmac_wait_value(bgmac->core,
+ ring->mmio_base + BGMAC_DMA_RX_STATUS,
+ BGMAC_DMA_RX_STAT, BGMAC_DMA_RX_STAT_DISABLED,
+ 10000))
+ bgmac_err(bgmac, "Reset of ring 0x%X RX failed\n",
+ ring->mmio_base);
+}
+
+static void bgmac_dma_rx_enable(struct bgmac *bgmac,
+ struct bgmac_dma_ring *ring)
+{
+ u32 ctl;
+
+ ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL);
+ if (bgmac->core->id.rev >= 4) {
+ ctl &= ~BGMAC_DMA_RX_BL_MASK;
+ ctl |= BGMAC_DMA_RX_BL_128 << BGMAC_DMA_RX_BL_SHIFT;
+
+ ctl &= ~BGMAC_DMA_RX_PC_MASK;
+ ctl |= BGMAC_DMA_RX_PC_8 << BGMAC_DMA_RX_PC_SHIFT;
+
+ ctl &= ~BGMAC_DMA_RX_PT_MASK;
+ ctl |= BGMAC_DMA_RX_PT_1 << BGMAC_DMA_RX_PT_SHIFT;
+ }
+ ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
+ ctl |= BGMAC_DMA_RX_ENABLE;
+ ctl |= BGMAC_DMA_RX_PARITY_DISABLE;
+ ctl |= BGMAC_DMA_RX_OVERFLOW_CONT;
+ ctl |= BGMAC_RX_FRAME_OFFSET << BGMAC_DMA_RX_FRAME_OFFSET_SHIFT;
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, ctl);
+}
+
+static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
+ struct bgmac_slot_info *slot)
+{
+ struct device *dma_dev = bgmac->core->dma_dev;
+ struct sk_buff *skb;
+ dma_addr_t dma_addr;
+ struct bgmac_rx_header *rx;
+
+ /* Alloc skb */
+ skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE);
+ if (!skb)
+ return -ENOMEM;
+
+ /* Poison - if everything goes fine, hardware will overwrite it */
+ rx = (struct bgmac_rx_header *)skb->data;
+ rx->len = cpu_to_le16(0xdead);
+ rx->flags = cpu_to_le16(0xbeef);
+
+ /* Map skb for the DMA */
+ dma_addr = dma_map_single(dma_dev, skb->data,
+ BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dma_dev, dma_addr)) {
+ bgmac_err(bgmac, "DMA mapping error\n");
+ dev_kfree_skb(skb);
+ return -ENOMEM;
+ }
+
+ /* Update the slot */
+ slot->skb = skb;
+ slot->dma_addr = dma_addr;
+
+ if (slot->dma_addr & 0xC0000000)
+ bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
+
+ return 0;
+}
+
+static void bgmac_dma_rx_setup_desc(struct bgmac *bgmac,
+ struct bgmac_dma_ring *ring, int desc_idx)
+{
+ struct bgmac_dma_desc *dma_desc = ring->cpu_base + desc_idx;
+ u32 ctl0 = 0, ctl1 = 0;
+
+ if (desc_idx == ring->num_slots - 1)
+ ctl0 |= BGMAC_DESC_CTL0_EOT;
+ ctl1 |= BGMAC_RX_BUF_SIZE & BGMAC_DESC_CTL1_LEN;
+ /* Is there any BGMAC device that requires extension? */
+ /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) &
+ * B43_DMA64_DCTL1_ADDREXT_MASK;
+ */
+
+ dma_desc->addr_low = cpu_to_le32(lower_32_bits(ring->slots[desc_idx].dma_addr));
+ dma_desc->addr_high = cpu_to_le32(upper_32_bits(ring->slots[desc_idx].dma_addr));
+ dma_desc->ctl0 = cpu_to_le32(ctl0);
+ dma_desc->ctl1 = cpu_to_le32(ctl1);
+}
+
+static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
+ int weight)
+{
+ u32 end_slot;
+ int handled = 0;
+
+ end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
+ end_slot &= BGMAC_DMA_RX_STATDPTR;
+ end_slot -= ring->index_base;
+ end_slot &= BGMAC_DMA_RX_STATDPTR;
+ end_slot /= sizeof(struct bgmac_dma_desc);
+
+ ring->end = end_slot;
+
+ while (ring->start != ring->end) {
+ struct device *dma_dev = bgmac->core->dma_dev;
+ struct bgmac_slot_info *slot = &ring->slots[ring->start];
+ struct sk_buff *skb = slot->skb;
+ struct bgmac_rx_header *rx;
+ u16 len, flags;
+
+ /* Unmap buffer to make it accessible to the CPU */
+ dma_sync_single_for_cpu(dma_dev, slot->dma_addr,
+ BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
+
+ /* Get info from the header */
+ rx = (struct bgmac_rx_header *)skb->data;
+ len = le16_to_cpu(rx->len);
+ flags = le16_to_cpu(rx->flags);
+
+ do {
+ dma_addr_t old_dma_addr = slot->dma_addr;
+ int err;
+
+ /* Check for poison and drop or pass the packet */
+ if (len == 0xdead && flags == 0xbeef) {
+ bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
+ ring->start);
+ dma_sync_single_for_device(dma_dev,
+ slot->dma_addr,
+ BGMAC_RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
+ break;
+ }
+
+ /* Omit CRC. */
+ len -= ETH_FCS_LEN;
+
+ /* Prepare new skb as replacement */
+ err = bgmac_dma_rx_skb_for_slot(bgmac, slot);
+ if (err) {
+ /* Poison the old skb */
+ rx->len = cpu_to_le16(0xdead);
+ rx->flags = cpu_to_le16(0xbeef);
+
+ dma_sync_single_for_device(dma_dev,
+ slot->dma_addr,
+ BGMAC_RX_BUF_SIZE,
+ DMA_FROM_DEVICE);
+ break;
+ }
+ bgmac_dma_rx_setup_desc(bgmac, ring, ring->start);
+
+ /* Unmap old skb, we'll pass it to the netfif */
+ dma_unmap_single(dma_dev, old_dma_addr,
+ BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);
+
+ skb_put(skb, BGMAC_RX_FRAME_OFFSET + len);
+ skb_pull(skb, BGMAC_RX_FRAME_OFFSET);
+
+ skb_checksum_none_assert(skb);
+ skb->protocol = eth_type_trans(skb, bgmac->net_dev);
+ netif_receive_skb(skb);
+ handled++;
+ } while (0);
+
+ if (++ring->start >= BGMAC_RX_RING_SLOTS)
+ ring->start = 0;
+
+ if (handled >= weight) /* Should never be greater */
+ break;
+ }
+
+ return handled;
+}
+
+/* Does ring support unaligned addressing? */
+static bool bgmac_dma_unaligned(struct bgmac *bgmac,
+ struct bgmac_dma_ring *ring,
+ enum bgmac_dma_ring_type ring_type)
+{
+ switch (ring_type) {
+ case BGMAC_DMA_RING_TX:
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
+ 0xff0);
+ if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO))
+ return true;
+ break;
+ case BGMAC_DMA_RING_RX:
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
+ 0xff0);
+ if (bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO))
+ return true;
+ break;
+ }
+ return false;
+}
+
+static void bgmac_dma_ring_free(struct bgmac *bgmac,
+ struct bgmac_dma_ring *ring)
+{
+ struct device *dma_dev = bgmac->core->dma_dev;
+ struct bgmac_slot_info *slot;
+ int size;
+ int i;
+
+ for (i = 0; i < ring->num_slots; i++) {
+ slot = &ring->slots[i];
+ if (slot->skb) {
+ if (slot->dma_addr)
+ dma_unmap_single(dma_dev, slot->dma_addr,
+ slot->skb->len, DMA_TO_DEVICE);
+ dev_kfree_skb(slot->skb);
+ }
+ }
+
+ if (ring->cpu_base) {
+ /* Free ring of descriptors */
+ size = ring->num_slots * sizeof(struct bgmac_dma_desc);
+ dma_free_coherent(dma_dev, size, ring->cpu_base,
+ ring->dma_base);
+ }
+}
+
+static void bgmac_dma_free(struct bgmac *bgmac)
+{
+ int i;
+
+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
+ bgmac_dma_ring_free(bgmac, &bgmac->tx_ring[i]);
+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
+ bgmac_dma_ring_free(bgmac, &bgmac->rx_ring[i]);
+}
+
+static int bgmac_dma_alloc(struct bgmac *bgmac)
+{
+ struct device *dma_dev = bgmac->core->dma_dev;
+ struct bgmac_dma_ring *ring;
+ static const u16 ring_base[] = { BGMAC_DMA_BASE0, BGMAC_DMA_BASE1,
+ BGMAC_DMA_BASE2, BGMAC_DMA_BASE3, };
+ int size; /* ring size: different for Tx and Rx */
+ int err;
+ int i;
+
+ BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
+ BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));
+
+ if (!(bcma_aread32(bgmac->core, BCMA_IOST) & BCMA_IOST_DMA64)) {
+ bgmac_err(bgmac, "Core does not report 64-bit DMA\n");
+ return -ENOTSUPP;
+ }
+
+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
+ ring = &bgmac->tx_ring[i];
+ ring->num_slots = BGMAC_TX_RING_SLOTS;
+ ring->mmio_base = ring_base[i];
+
+ /* Alloc ring of descriptors */
+ size = ring->num_slots * sizeof(struct bgmac_dma_desc);
+ ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
+ &ring->dma_base,
+ GFP_KERNEL);
+ if (!ring->cpu_base) {
+ bgmac_err(bgmac, "Allocation of TX ring 0x%X failed\n",
+ ring->mmio_base);
+ goto err_dma_free;
+ }
+ if (ring->dma_base & 0xC0000000)
+ bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
+
+ ring->unaligned = bgmac_dma_unaligned(bgmac, ring,
+ BGMAC_DMA_RING_TX);
+ if (ring->unaligned)
+ ring->index_base = lower_32_bits(ring->dma_base);
+ else
+ ring->index_base = 0;
+
+ /* No need to alloc TX slots yet */
+ }
+
+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
+ int j;
+
+ ring = &bgmac->rx_ring[i];
+ ring->num_slots = BGMAC_RX_RING_SLOTS;
+ ring->mmio_base = ring_base[i];
+
+ /* Alloc ring of descriptors */
+ size = ring->num_slots * sizeof(struct bgmac_dma_desc);
+ ring->cpu_base = dma_zalloc_coherent(dma_dev, size,
+ &ring->dma_base,
+ GFP_KERNEL);
+ if (!ring->cpu_base) {
+ bgmac_err(bgmac, "Allocation of RX ring 0x%X failed\n",
+ ring->mmio_base);
+ err = -ENOMEM;
+ goto err_dma_free;
+ }
+ if (ring->dma_base & 0xC0000000)
+ bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
+
+ ring->unaligned = bgmac_dma_unaligned(bgmac, ring,
+ BGMAC_DMA_RING_RX);
+ if (ring->unaligned)
+ ring->index_base = lower_32_bits(ring->dma_base);
+ else
+ ring->index_base = 0;
+
+ /* Alloc RX slots */
+ for (j = 0; j < ring->num_slots; j++) {
+ err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
+ if (err) {
+ bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n");
+ goto err_dma_free;
+ }
+ }
+ }
+
+ return 0;
+
+err_dma_free:
+ bgmac_dma_free(bgmac);
+ return -ENOMEM;
+}
+
+static void bgmac_dma_init(struct bgmac *bgmac)
+{
+ struct bgmac_dma_ring *ring;
+ int i;
+
+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
+ ring = &bgmac->tx_ring[i];
+
+ if (!ring->unaligned)
+ bgmac_dma_tx_enable(bgmac, ring);
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
+ lower_32_bits(ring->dma_base));
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGHI,
+ upper_32_bits(ring->dma_base));
+ if (ring->unaligned)
+ bgmac_dma_tx_enable(bgmac, ring);
+
+ ring->start = 0;
+ ring->end = 0; /* Points the slot that should *not* be read */
+ }
+
+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
+ int j;
+
+ ring = &bgmac->rx_ring[i];
+
+ if (!ring->unaligned)
+ bgmac_dma_rx_enable(bgmac, ring);
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
+ lower_32_bits(ring->dma_base));
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGHI,
+ upper_32_bits(ring->dma_base));
+ if (ring->unaligned)
+ bgmac_dma_rx_enable(bgmac, ring);
+
+ for (j = 0; j < ring->num_slots; j++)
+ bgmac_dma_rx_setup_desc(bgmac, ring, j);
+
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
+ ring->index_base +
+ ring->num_slots * sizeof(struct bgmac_dma_desc));
+
+ ring->start = 0;
+ ring->end = 0;
+ }
+}
+
+/**************************************************
+ * PHY ops
+ **************************************************/
+
+static u16 bgmac_phy_read(struct bgmac *bgmac, u8 phyaddr, u8 reg)
+{
+ struct bcma_device *core;
+ u16 phy_access_addr;
+ u16 phy_ctl_addr;
+ u32 tmp;
+
+ BUILD_BUG_ON(BGMAC_PA_DATA_MASK != BCMA_GMAC_CMN_PA_DATA_MASK);
+ BUILD_BUG_ON(BGMAC_PA_ADDR_MASK != BCMA_GMAC_CMN_PA_ADDR_MASK);
+ BUILD_BUG_ON(BGMAC_PA_ADDR_SHIFT != BCMA_GMAC_CMN_PA_ADDR_SHIFT);
+ BUILD_BUG_ON(BGMAC_PA_REG_MASK != BCMA_GMAC_CMN_PA_REG_MASK);
+ BUILD_BUG_ON(BGMAC_PA_REG_SHIFT != BCMA_GMAC_CMN_PA_REG_SHIFT);
+ BUILD_BUG_ON(BGMAC_PA_WRITE != BCMA_GMAC_CMN_PA_WRITE);
+ BUILD_BUG_ON(BGMAC_PA_START != BCMA_GMAC_CMN_PA_START);
+ BUILD_BUG_ON(BGMAC_PC_EPA_MASK != BCMA_GMAC_CMN_PC_EPA_MASK);
+ BUILD_BUG_ON(BGMAC_PC_MCT_MASK != BCMA_GMAC_CMN_PC_MCT_MASK);
+ BUILD_BUG_ON(BGMAC_PC_MCT_SHIFT != BCMA_GMAC_CMN_PC_MCT_SHIFT);
+ BUILD_BUG_ON(BGMAC_PC_MTE != BCMA_GMAC_CMN_PC_MTE);
+
+ if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
+ core = bgmac->core->bus->drv_gmac_cmn.core;
+ phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
+ phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
+ } else {
+ core = bgmac->core;
+ phy_access_addr = BGMAC_PHY_ACCESS;
+ phy_ctl_addr = BGMAC_PHY_CNTL;
+ }
+
+ tmp = bcma_read32(core, phy_ctl_addr);
+ tmp &= ~BGMAC_PC_EPA_MASK;
+ tmp |= phyaddr;
+ bcma_write32(core, phy_ctl_addr, tmp);
+
+ tmp = BGMAC_PA_START;
+ tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
+ tmp |= reg << BGMAC_PA_REG_SHIFT;
+ bcma_write32(core, phy_access_addr, tmp);
+
+ if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
+ bgmac_err(bgmac, "Reading PHY %d register 0x%X failed\n",
+ phyaddr, reg);
+ return 0xffff;
+ }
+
+ return bcma_read32(core, phy_access_addr) & BGMAC_PA_DATA_MASK;
+}
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphywr */
+static int bgmac_phy_write(struct bgmac *bgmac, u8 phyaddr, u8 reg, u16 value)
+{
+ struct bcma_device *core;
+ u16 phy_access_addr;
+ u16 phy_ctl_addr;
+ u32 tmp;
+
+ if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT) {
+ core = bgmac->core->bus->drv_gmac_cmn.core;
+ phy_access_addr = BCMA_GMAC_CMN_PHY_ACCESS;
+ phy_ctl_addr = BCMA_GMAC_CMN_PHY_CTL;
+ } else {
+ core = bgmac->core;
+ phy_access_addr = BGMAC_PHY_ACCESS;
+ phy_ctl_addr = BGMAC_PHY_CNTL;
+ }
+
+ tmp = bcma_read32(core, phy_ctl_addr);
+ tmp &= ~BGMAC_PC_EPA_MASK;
+ tmp |= phyaddr;
+ bcma_write32(core, phy_ctl_addr, tmp);
+
+ bgmac_write(bgmac, BGMAC_INT_STATUS, BGMAC_IS_MDIO);
+ if (bgmac_read(bgmac, BGMAC_INT_STATUS) & BGMAC_IS_MDIO)
+ bgmac_warn(bgmac, "Error setting MDIO int\n");
+
+ tmp = BGMAC_PA_START;
+ tmp |= BGMAC_PA_WRITE;
+ tmp |= phyaddr << BGMAC_PA_ADDR_SHIFT;
+ tmp |= reg << BGMAC_PA_REG_SHIFT;
+ tmp |= value;
+ bcma_write32(core, phy_access_addr, tmp);
+
+ if (!bgmac_wait_value(core, phy_access_addr, BGMAC_PA_START, 0, 1000)) {
+ bgmac_err(bgmac, "Writing to PHY %d register 0x%X failed\n",
+ phyaddr, reg);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyinit */
+static void bgmac_phy_init(struct bgmac *bgmac)
+{
+ struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
+ struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
+ u8 i;
+
+ if (ci->id == BCMA_CHIP_ID_BCM5356) {
+ for (i = 0; i < 5; i++) {
+ bgmac_phy_write(bgmac, i, 0x1f, 0x008b);
+ bgmac_phy_write(bgmac, i, 0x15, 0x0100);
+ bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
+ bgmac_phy_write(bgmac, i, 0x12, 0x2aaa);
+ bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
+ }
+ }
+ if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg != 10) ||
+ (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg != 10) ||
+ (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg != 9)) {
+ bcma_chipco_chipctl_maskset(cc, 2, ~0xc0000000, 0);
+ bcma_chipco_chipctl_maskset(cc, 4, ~0x80000000, 0);
+ for (i = 0; i < 5; i++) {
+ bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
+ bgmac_phy_write(bgmac, i, 0x16, 0x5284);
+ bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
+ bgmac_phy_write(bgmac, i, 0x17, 0x0010);
+ bgmac_phy_write(bgmac, i, 0x1f, 0x000f);
+ bgmac_phy_write(bgmac, i, 0x16, 0x5296);
+ bgmac_phy_write(bgmac, i, 0x17, 0x1073);
+ bgmac_phy_write(bgmac, i, 0x17, 0x9073);
+ bgmac_phy_write(bgmac, i, 0x16, 0x52b6);
+ bgmac_phy_write(bgmac, i, 0x17, 0x9273);
+ bgmac_phy_write(bgmac, i, 0x1f, 0x000b);
+ }
+ }
+}
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipphyreset */
+static void bgmac_phy_reset(struct bgmac *bgmac)
+{
+ if (bgmac->phyaddr == BGMAC_PHY_NOREGS)
+ return;
+
+ bgmac_phy_write(bgmac, bgmac->phyaddr, MII_BMCR, BMCR_RESET);
+ udelay(100);
+ if (bgmac_phy_read(bgmac, bgmac->phyaddr, MII_BMCR) & BMCR_RESET)
+ bgmac_err(bgmac, "PHY reset failed\n");
+ bgmac_phy_init(bgmac);
+}
+
+/**************************************************
+ * Chip ops
+ **************************************************/
+
+/* TODO: can we just drop @force? Can we don't reset MAC at all if there is
+ * nothing to change? Try if after stabilizng driver.
+ */
+static void bgmac_cmdcfg_maskset(struct bgmac *bgmac, u32 mask, u32 set,
+ bool force)
+{
+ u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
+ u32 new_val = (cmdcfg & mask) | set;
+
+ bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR(bgmac->core->id.rev));
+ udelay(2);
+
+ if (new_val != cmdcfg || force)
+ bgmac_write(bgmac, BGMAC_CMDCFG, new_val);
+
+ bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR(bgmac->core->id.rev));
+ udelay(2);
+}
+
+static void bgmac_write_mac_address(struct bgmac *bgmac, u8 *addr)
+{
+ u32 tmp;
+
+ tmp = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
+ bgmac_write(bgmac, BGMAC_MACADDR_HIGH, tmp);
+ tmp = (addr[4] << 8) | addr[5];
+ bgmac_write(bgmac, BGMAC_MACADDR_LOW, tmp);
+}
+
+static void bgmac_set_rx_mode(struct net_device *net_dev)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+
+ if (net_dev->flags & IFF_PROMISC)
+ bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_PROM, true);
+ else
+ bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_PROM, 0, true);
+}
+
+#if 0 /* We don't use that regs yet */
+static void bgmac_chip_stats_update(struct bgmac *bgmac)
+{
+ int i;
+
+ if (bgmac->core->id.id != BCMA_CORE_4706_MAC_GBIT) {
+ for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
+ bgmac->mib_tx_regs[i] =
+ bgmac_read(bgmac,
+ BGMAC_TX_GOOD_OCTETS + (i * 4));
+ for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
+ bgmac->mib_rx_regs[i] =
+ bgmac_read(bgmac,
+ BGMAC_RX_GOOD_OCTETS + (i * 4));
+ }
+
+ /* TODO: what else? how to handle BCM4706? Specs are needed */
+}
+#endif
+
+static void bgmac_clear_mib(struct bgmac *bgmac)
+{
+ int i;
+
+ if (bgmac->core->id.id == BCMA_CORE_4706_MAC_GBIT)
+ return;
+
+ bgmac_set(bgmac, BGMAC_DEV_CTL, BGMAC_DC_MROR);
+ for (i = 0; i < BGMAC_NUM_MIB_TX_REGS; i++)
+ bgmac_read(bgmac, BGMAC_TX_GOOD_OCTETS + (i * 4));
+ for (i = 0; i < BGMAC_NUM_MIB_RX_REGS; i++)
+ bgmac_read(bgmac, BGMAC_RX_GOOD_OCTETS + (i * 4));
+}
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_speed */
+static void bgmac_mac_speed(struct bgmac *bgmac)
+{
+ u32 mask = ~(BGMAC_CMDCFG_ES_MASK | BGMAC_CMDCFG_HD);
+ u32 set = 0;
+
+ switch (bgmac->mac_speed) {
+ case SPEED_10:
+ set |= BGMAC_CMDCFG_ES_10;
+ break;
+ case SPEED_100:
+ set |= BGMAC_CMDCFG_ES_100;
+ break;
+ case SPEED_1000:
+ set |= BGMAC_CMDCFG_ES_1000;
+ break;
+ case SPEED_2500:
+ set |= BGMAC_CMDCFG_ES_2500;
+ break;
+ default:
+ bgmac_err(bgmac, "Unsupported speed: %d\n", bgmac->mac_speed);
+ }
+
+ if (bgmac->mac_duplex == DUPLEX_HALF)
+ set |= BGMAC_CMDCFG_HD;
+
+ bgmac_cmdcfg_maskset(bgmac, mask, set, true);
+}
+
+static void bgmac_miiconfig(struct bgmac *bgmac)
+{
+ struct bcma_device *core = bgmac->core;
+ struct bcma_chipinfo *ci = &core->bus->chipinfo;
+ u8 imode;
+
+ if (ci->id == BCMA_CHIP_ID_BCM4707 ||
+ ci->id == BCMA_CHIP_ID_BCM53018) {
+ bcma_awrite32(core, BCMA_IOCTL,
+ bcma_aread32(core, BCMA_IOCTL) | 0x40 |
+ BGMAC_BCMA_IOCTL_SW_CLKEN);
+ bgmac->mac_speed = SPEED_2500;
+ bgmac->mac_duplex = DUPLEX_FULL;
+ bgmac_mac_speed(bgmac);
+ } else {
+ imode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) &
+ BGMAC_DS_MM_MASK) >> BGMAC_DS_MM_SHIFT;
+ if (imode == 0 || imode == 1) {
+ bgmac->mac_speed = SPEED_100;
+ bgmac->mac_duplex = DUPLEX_FULL;
+ bgmac_mac_speed(bgmac);
+ }
+ }
+}
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
+static void bgmac_chip_reset(struct bgmac *bgmac)
+{
+ struct bcma_device *core = bgmac->core;
+ struct bcma_bus *bus = core->bus;
+ struct bcma_chipinfo *ci = &bus->chipinfo;
+ u32 flags;
+ u32 iost;
+ int i;
+
+ if (bcma_core_is_enabled(core)) {
+ if (!bgmac->stats_grabbed) {
+ /* bgmac_chip_stats_update(bgmac); */
+ bgmac->stats_grabbed = true;
+ }
+
+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
+ bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);
+
+ bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
+ udelay(1);
+
+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
+ bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);
+
+ /* TODO: Clear software multicast filter list */
+ }
+
+ iost = bcma_aread32(core, BCMA_IOST);
+ if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM47186) ||
+ (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) ||
+ (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188))
+ iost &= ~BGMAC_BCMA_IOST_ATTACHED;
+
+ /* 3GMAC: for BCM4707, only do core reset at bgmac_probe() */
+ if (ci->id != BCMA_CHIP_ID_BCM4707) {
+ flags = 0;
+ if (iost & BGMAC_BCMA_IOST_ATTACHED) {
+ flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
+ if (!bgmac->has_robosw)
+ flags |= BGMAC_BCMA_IOCTL_SW_RESET;
+ }
+ bcma_core_enable(core, flags);
+ }
+
+ /* Request Misc PLL for corerev > 2 */
+ if (core->id.rev > 2 &&
+ ci->id != BCMA_CHIP_ID_BCM4707 &&
+ ci->id != BCMA_CHIP_ID_BCM53018) {
+ bgmac_set(bgmac, BCMA_CLKCTLST,
+ BGMAC_BCMA_CLKCTLST_MISC_PLL_REQ);
+ bgmac_wait_value(bgmac->core, BCMA_CLKCTLST,
+ BGMAC_BCMA_CLKCTLST_MISC_PLL_ST,
+ BGMAC_BCMA_CLKCTLST_MISC_PLL_ST,
+ 1000);
+ }
+
+ if (ci->id == BCMA_CHIP_ID_BCM5357 ||
+ ci->id == BCMA_CHIP_ID_BCM4749 ||
+ ci->id == BCMA_CHIP_ID_BCM53572) {
+ struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
+ u8 et_swtype = 0;
+ u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
+ BGMAC_CHIPCTL_1_IF_TYPE_MII;
+ char buf[4];
+
+ if (bcm47xx_nvram_getenv("et_swtype", buf, sizeof(buf)) > 0) {
+ if (kstrtou8(buf, 0, &et_swtype))
+ bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n",
+ buf);
+ et_swtype &= 0x0f;
+ et_swtype <<= 4;
+ sw_type = et_swtype;
+ } else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM5358) {
+ sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII;
+ } else if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM47186) ||
+ (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) ||
+ (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188)) {
+ sw_type = BGMAC_CHIPCTL_1_IF_TYPE_RGMII |
+ BGMAC_CHIPCTL_1_SW_TYPE_RGMII;
+ }
+ bcma_chipco_chipctl_maskset(cc, 1,
+ ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
+ BGMAC_CHIPCTL_1_SW_TYPE_MASK),
+ sw_type);
+ }
+
+ if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
+ bcma_awrite32(core, BCMA_IOCTL,
+ bcma_aread32(core, BCMA_IOCTL) &
+ ~BGMAC_BCMA_IOCTL_SW_RESET);
+
+ /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
+ * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
+ * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
+ * be keps until taking MAC out of the reset.
+ */
+ bgmac_cmdcfg_maskset(bgmac,
+ ~(BGMAC_CMDCFG_TE |
+ BGMAC_CMDCFG_RE |
+ BGMAC_CMDCFG_RPI |
+ BGMAC_CMDCFG_TAI |
+ BGMAC_CMDCFG_HD |
+ BGMAC_CMDCFG_ML |
+ BGMAC_CMDCFG_CFE |
+ BGMAC_CMDCFG_RL |
+ BGMAC_CMDCFG_RED |
+ BGMAC_CMDCFG_PE |
+ BGMAC_CMDCFG_TPI |
+ BGMAC_CMDCFG_PAD_EN |
+ BGMAC_CMDCFG_PF),
+ BGMAC_CMDCFG_PROM |
+ BGMAC_CMDCFG_NLC |
+ BGMAC_CMDCFG_CFE |
+ BGMAC_CMDCFG_SR(core->id.rev),
+ false);
+ bgmac->mac_speed = SPEED_UNKNOWN;
+ bgmac->mac_duplex = DUPLEX_UNKNOWN;
+
+ bgmac_clear_mib(bgmac);
+ if (core->id.id == BCMA_CORE_4706_MAC_GBIT)
+ bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
+ BCMA_GMAC_CMN_PC_MTE);
+ else
+ bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
+ bgmac_miiconfig(bgmac);
+ bgmac_phy_init(bgmac);
+
+ netdev_reset_queue(bgmac->net_dev);
+
+ bgmac->int_status = 0;
+}
+
+static void bgmac_chip_intrs_on(struct bgmac *bgmac)
+{
+ bgmac_write(bgmac, BGMAC_INT_MASK, bgmac->int_mask);
+}
+
+static void bgmac_chip_intrs_off(struct bgmac *bgmac)
+{
+ bgmac_write(bgmac, BGMAC_INT_MASK, 0);
+ bgmac_read(bgmac, BGMAC_INT_MASK);
+}
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_enable */
+static void bgmac_enable(struct bgmac *bgmac)
+{
+ struct bcma_chipinfo *ci = &bgmac->core->bus->chipinfo;
+ u32 cmdcfg;
+ u32 mode;
+ u32 rxq_ctl;
+ u32 fl_ctl;
+ u16 bp_clk;
+ u8 mdp;
+
+ cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG);
+ bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE),
+ BGMAC_CMDCFG_SR(bgmac->core->id.rev), true);
+ udelay(2);
+ cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE;
+ bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg);
+
+ mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
+ BGMAC_DS_MM_SHIFT;
+ if (ci->id != BCMA_CHIP_ID_BCM47162 || mode != 0)
+ bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
+ if (ci->id == BCMA_CHIP_ID_BCM47162 && mode == 2)
+ bcma_chipco_chipctl_maskset(&bgmac->core->bus->drv_cc, 1, ~0,
+ BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
+
+ switch (ci->id) {
+ case BCMA_CHIP_ID_BCM5357:
+ case BCMA_CHIP_ID_BCM4749:
+ case BCMA_CHIP_ID_BCM53572:
+ case BCMA_CHIP_ID_BCM4716:
+ case BCMA_CHIP_ID_BCM47162:
+ fl_ctl = 0x03cb04cb;
+ if (ci->id == BCMA_CHIP_ID_BCM5357 ||
+ ci->id == BCMA_CHIP_ID_BCM4749 ||
+ ci->id == BCMA_CHIP_ID_BCM53572)
+ fl_ctl = 0x2300e1;
+ bgmac_write(bgmac, BGMAC_FLOW_CTL_THRESH, fl_ctl);
+ bgmac_write(bgmac, BGMAC_PAUSE_CTL, 0x27fff);
+ break;
+ }
+
+ if (ci->id != BCMA_CHIP_ID_BCM4707 &&
+ ci->id != BCMA_CHIP_ID_BCM53018) {
+ rxq_ctl = bgmac_read(bgmac, BGMAC_RXQ_CTL);
+ rxq_ctl &= ~BGMAC_RXQ_CTL_MDP_MASK;
+ bp_clk = bcma_pmu_get_bus_clock(&bgmac->core->bus->drv_cc) /
+ 1000000;
+ mdp = (bp_clk * 128 / 1000) - 3;
+ rxq_ctl |= (mdp << BGMAC_RXQ_CTL_MDP_SHIFT);
+ bgmac_write(bgmac, BGMAC_RXQ_CTL, rxq_ctl);
+ }
+}
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
+static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
+{
+ struct bgmac_dma_ring *ring;
+ int i;
+
+ /* 1 interrupt per received frame */
+ bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
+
+ /* Enable 802.3x tx flow control (honor received PAUSE frames) */
+ bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_RPI, 0, true);
+
+ bgmac_set_rx_mode(bgmac->net_dev);
+
+ bgmac_write_mac_address(bgmac, bgmac->net_dev->dev_addr);
+
+ if (bgmac->loopback)
+ bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
+ else
+ bgmac_cmdcfg_maskset(bgmac, ~BGMAC_CMDCFG_ML, 0, false);
+
+ bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
+
+ if (full_init) {
+ bgmac_dma_init(bgmac);
+ if (1) /* FIXME: is there any case we don't want IRQs? */
+ bgmac_chip_intrs_on(bgmac);
+ } else {
+ for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
+ ring = &bgmac->rx_ring[i];
+ bgmac_dma_rx_enable(bgmac, ring);
+ }
+ }
+
+ bgmac_enable(bgmac);
+}
+
+static irqreturn_t bgmac_interrupt(int irq, void *dev_id)
+{
+ struct bgmac *bgmac = netdev_priv(dev_id);
+
+ u32 int_status = bgmac_read(bgmac, BGMAC_INT_STATUS);
+ int_status &= bgmac->int_mask;
+
+ if (!int_status)
+ return IRQ_NONE;
+
+ /* Ack */
+ bgmac_write(bgmac, BGMAC_INT_STATUS, int_status);
+
+ /* Disable new interrupts until handling existing ones */
+ bgmac_chip_intrs_off(bgmac);
+
+ bgmac->int_status = int_status;
+
+ napi_schedule(&bgmac->napi);
+
+ return IRQ_HANDLED;
+}
+
+static int bgmac_poll(struct napi_struct *napi, int weight)
+{
+ struct bgmac *bgmac = container_of(napi, struct bgmac, napi);
+ struct bgmac_dma_ring *ring;
+ int handled = 0;
+
+ if (bgmac->int_status & BGMAC_IS_TX0) {
+ ring = &bgmac->tx_ring[0];
+ bgmac_dma_tx_free(bgmac, ring);
+ bgmac->int_status &= ~BGMAC_IS_TX0;
+ }
+
+ if (bgmac->int_status & BGMAC_IS_RX) {
+ ring = &bgmac->rx_ring[0];
+ handled += bgmac_dma_rx_read(bgmac, ring, weight);
+ bgmac->int_status &= ~BGMAC_IS_RX;
+ }
+
+ if (bgmac->int_status) {
+ bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status);
+ bgmac->int_status = 0;
+ }
+
+ if (handled < weight)
+ napi_complete(napi);
+
+ bgmac_chip_intrs_on(bgmac);
+
+ return handled;
+}
+
+/**************************************************
+ * net_device_ops
+ **************************************************/
+
+static int bgmac_open(struct net_device *net_dev)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+ int err = 0;
+
+ bgmac_chip_reset(bgmac);
+ /* Specs say about reclaiming rings here, but we do that in DMA init */
+ bgmac_chip_init(bgmac, true);
+
+ err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
+ KBUILD_MODNAME, net_dev);
+ if (err < 0) {
+ bgmac_err(bgmac, "IRQ request error: %d!\n", err);
+ goto err_out;
+ }
+ napi_enable(&bgmac->napi);
+
+ phy_start(bgmac->phy_dev);
+
+ netif_carrier_on(net_dev);
+
+err_out:
+ return err;
+}
+
+static int bgmac_stop(struct net_device *net_dev)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+
+ netif_carrier_off(net_dev);
+
+ phy_stop(bgmac->phy_dev);
+
+ napi_disable(&bgmac->napi);
+ bgmac_chip_intrs_off(bgmac);
+ free_irq(bgmac->core->irq, net_dev);
+
+ bgmac_chip_reset(bgmac);
+
+ return 0;
+}
+
+static netdev_tx_t bgmac_start_xmit(struct sk_buff *skb,
+ struct net_device *net_dev)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+ struct bgmac_dma_ring *ring;
+
+ /* No QOS support yet */
+ ring = &bgmac->tx_ring[0];
+ return bgmac_dma_tx_add(bgmac, ring, skb);
+}
+
+static int bgmac_set_mac_address(struct net_device *net_dev, void *addr)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+ int ret;
+
+ ret = eth_prepare_mac_addr_change(net_dev, addr);
+ if (ret < 0)
+ return ret;
+ bgmac_write_mac_address(bgmac, (u8 *)addr);
+ eth_commit_mac_addr_change(net_dev, addr);
+ return 0;
+}
+
+static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+
+ if (!netif_running(net_dev))
+ return -EINVAL;
+
+ return phy_mii_ioctl(bgmac->phy_dev, ifr, cmd);
+}
+
+static const struct net_device_ops bgmac_netdev_ops = {
+ .ndo_open = bgmac_open,
+ .ndo_stop = bgmac_stop,
+ .ndo_start_xmit = bgmac_start_xmit,
+ .ndo_set_rx_mode = bgmac_set_rx_mode,
+ .ndo_set_mac_address = bgmac_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = bgmac_ioctl,
+};
+
+/**************************************************
+ * ethtool_ops
+ **************************************************/
+
+static int bgmac_get_settings(struct net_device *net_dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+
+ return phy_ethtool_gset(bgmac->phy_dev, cmd);
+}
+
+static int bgmac_set_settings(struct net_device *net_dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+
+ return phy_ethtool_sset(bgmac->phy_dev, cmd);
+}
+
+static void bgmac_get_drvinfo(struct net_device *net_dev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+ strlcpy(info->bus_info, "BCMA", sizeof(info->bus_info));
+}
+
+static const struct ethtool_ops bgmac_ethtool_ops = {
+ .get_settings = bgmac_get_settings,
+ .set_settings = bgmac_set_settings,
+ .get_drvinfo = bgmac_get_drvinfo,
+};
+
+/**************************************************
+ * MII
+ **************************************************/
+
+static int bgmac_mii_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+ return bgmac_phy_read(bus->priv, mii_id, regnum);
+}
+
+static int bgmac_mii_write(struct mii_bus *bus, int mii_id, int regnum,
+ u16 value)
+{
+ return bgmac_phy_write(bus->priv, mii_id, regnum, value);
+}
+
+static void bgmac_adjust_link(struct net_device *net_dev)
+{
+ struct bgmac *bgmac = netdev_priv(net_dev);
+ struct phy_device *phy_dev = bgmac->phy_dev;
+ bool update = false;
+
+ if (phy_dev->link) {
+ if (phy_dev->speed != bgmac->mac_speed) {
+ bgmac->mac_speed = phy_dev->speed;
+ update = true;
+ }
+
+ if (phy_dev->duplex != bgmac->mac_duplex) {
+ bgmac->mac_duplex = phy_dev->duplex;
+ update = true;
+ }
+ }
+
+ if (update) {
+ bgmac_mac_speed(bgmac);
+ phy_print_status(phy_dev);
+ }
+}
+
+static int bgmac_mii_register(struct bgmac *bgmac)
+{
+ struct mii_bus *mii_bus;
+ struct phy_device *phy_dev;
+ char bus_id[MII_BUS_ID_SIZE + 3];
+ int i, err = 0;
+
+ mii_bus = mdiobus_alloc();
+ if (!mii_bus)
+ return -ENOMEM;
+
+ mii_bus->name = "bgmac mii bus";
+ sprintf(mii_bus->id, "%s-%d-%d", "bgmac", bgmac->core->bus->num,
+ bgmac->core->core_unit);
+ mii_bus->priv = bgmac;
+ mii_bus->read = bgmac_mii_read;
+ mii_bus->write = bgmac_mii_write;
+ mii_bus->parent = &bgmac->core->dev;
+ mii_bus->phy_mask = ~(1 << bgmac->phyaddr);
+
+ mii_bus->irq = kmalloc_array(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
+ if (!mii_bus->irq) {
+ err = -ENOMEM;
+ goto err_free_bus;
+ }
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+ mii_bus->irq[i] = PHY_POLL;
+
+ err = mdiobus_register(mii_bus);
+ if (err) {
+ bgmac_err(bgmac, "Registration of mii bus failed\n");
+ goto err_free_irq;
+ }
+
+ bgmac->mii_bus = mii_bus;
+
+ /* Connect to the PHY */
+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id,
+ bgmac->phyaddr);
+ phy_dev = phy_connect(bgmac->net_dev, bus_id, &bgmac_adjust_link,
+ PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(phy_dev)) {
+ bgmac_err(bgmac, "PHY connecton failed\n");
+ err = PTR_ERR(phy_dev);
+ goto err_unregister_bus;
+ }
+ bgmac->phy_dev = phy_dev;
+
+ return err;
+
+err_unregister_bus:
+ mdiobus_unregister(mii_bus);
+err_free_irq:
+ kfree(mii_bus->irq);
+err_free_bus:
+ mdiobus_free(mii_bus);
+ return err;
+}
+
+static void bgmac_mii_unregister(struct bgmac *bgmac)
+{
+ struct mii_bus *mii_bus = bgmac->mii_bus;
+
+ mdiobus_unregister(mii_bus);
+ kfree(mii_bus->irq);
+ mdiobus_free(mii_bus);
+}
+
+/**************************************************
+ * BCMA bus ops
+ **************************************************/
+
+/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipattach */
+static int bgmac_probe(struct bcma_device *core)
+{
+ struct net_device *net_dev;
+ struct bgmac *bgmac;
+ struct ssb_sprom *sprom = &core->bus->sprom;
+ u8 *mac = core->core_unit ? sprom->et1mac : sprom->et0mac;
+ int err;
+
+ /* We don't support 2nd, 3rd, ... units, SPROM has to be adjusted */
+ if (core->core_unit > 1) {
+ pr_err("Unsupported core_unit %d\n", core->core_unit);
+ return -ENOTSUPP;
+ }
+
+ if (!is_valid_ether_addr(mac)) {
+ dev_err(&core->dev, "Invalid MAC addr: %pM\n", mac);
+ eth_random_addr(mac);
+ dev_warn(&core->dev, "Using random MAC: %pM\n", mac);
+ }
+
+ /* Allocation and references */
+ net_dev = alloc_etherdev(sizeof(*bgmac));
+ if (!net_dev)
+ return -ENOMEM;
+ net_dev->netdev_ops = &bgmac_netdev_ops;
+ net_dev->irq = core->irq;
+ net_dev->ethtool_ops = &bgmac_ethtool_ops;
+ bgmac = netdev_priv(net_dev);
+ bgmac->net_dev = net_dev;
+ bgmac->core = core;
+ bcma_set_drvdata(core, bgmac);
+
+ /* Defaults */
+ memcpy(bgmac->net_dev->dev_addr, mac, ETH_ALEN);
+
+ /* On BCM4706 we need common core to access PHY */
+ if (core->id.id == BCMA_CORE_4706_MAC_GBIT &&
+ !core->bus->drv_gmac_cmn.core) {
+ bgmac_err(bgmac, "GMAC CMN core not found (required for BCM4706)\n");
+ err = -ENODEV;
+ goto err_netdev_free;
+ }
+ bgmac->cmn = core->bus->drv_gmac_cmn.core;
+
+ bgmac->phyaddr = core->core_unit ? sprom->et1phyaddr :
+ sprom->et0phyaddr;
+ bgmac->phyaddr &= BGMAC_PHY_MASK;
+ if (bgmac->phyaddr == BGMAC_PHY_MASK) {
+ bgmac_err(bgmac, "No PHY found\n");
+ err = -ENODEV;
+ goto err_netdev_free;
+ }
+ bgmac_info(bgmac, "Found PHY addr: %d%s\n", bgmac->phyaddr,
+ bgmac->phyaddr == BGMAC_PHY_NOREGS ? " (NOREGS)" : "");
+
+ if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) {
+ bgmac_err(bgmac, "PCI setup not implemented\n");
+ err = -ENOTSUPP;
+ goto err_netdev_free;
+ }
+
+ bgmac_chip_reset(bgmac);
+
+ /* For Northstar, we have to take all GMAC core out of reset */
+ if (core->id.id == BCMA_CHIP_ID_BCM4707 ||
+ core->id.id == BCMA_CHIP_ID_BCM53018) {
+ struct bcma_device *ns_core;
+ int ns_gmac;
+
+ /* Northstar has 4 GMAC cores */
+ for (ns_gmac = 0; ns_gmac < 4; ns_gmac++) {
+ /* As Northstar requirement, we have to reset all GMACs
+ * before accessing one. bgmac_chip_reset() call
+ * bcma_core_enable() for this core. Then the other
+ * three GMACs didn't reset. We do it here.
+ */
+ ns_core = bcma_find_core_unit(core->bus,
+ BCMA_CORE_MAC_GBIT,
+ ns_gmac);
+ if (ns_core && !bcma_core_is_enabled(ns_core))
+ bcma_core_enable(ns_core, 0);
+ }
+ }
+
+ err = bgmac_dma_alloc(bgmac);
+ if (err) {
+ bgmac_err(bgmac, "Unable to alloc memory for DMA\n");
+ goto err_netdev_free;
+ }
+
+ bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK;
+ if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0)
+ bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
+
+ /* TODO: reset the external phy. Specs are needed */
+ bgmac_phy_reset(bgmac);
+
+ bgmac->has_robosw = !!(core->bus->sprom.boardflags_lo &
+ BGMAC_BFL_ENETROBO);
+ if (bgmac->has_robosw)
+ bgmac_warn(bgmac, "Support for Roboswitch not implemented\n");
+
+ if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM)
+ bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n");
+
+ err = bgmac_mii_register(bgmac);
+ if (err) {
+ bgmac_err(bgmac, "Cannot register MDIO\n");
+ goto err_dma_free;
+ }
+
+ err = register_netdev(bgmac->net_dev);
+ if (err) {
+ bgmac_err(bgmac, "Cannot register net device\n");
+ goto err_mii_unregister;
+ }
+
+ netif_carrier_off(net_dev);
+
+ netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT);
+
+ return 0;
+
+err_mii_unregister:
+ bgmac_mii_unregister(bgmac);
+err_dma_free:
+ bgmac_dma_free(bgmac);
+
+err_netdev_free:
+ bcma_set_drvdata(core, NULL);
+ free_netdev(net_dev);
+
+ return err;
+}
+
+static void bgmac_remove(struct bcma_device *core)
+{
+ struct bgmac *bgmac = bcma_get_drvdata(core);
+
+ netif_napi_del(&bgmac->napi);
+ unregister_netdev(bgmac->net_dev);
+ bgmac_mii_unregister(bgmac);
+ bgmac_dma_free(bgmac);
+ bcma_set_drvdata(core, NULL);
+ free_netdev(bgmac->net_dev);
+}
+
+static struct bcma_driver bgmac_bcma_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = bgmac_bcma_tbl,
+ .probe = bgmac_probe,
+ .remove = bgmac_remove,
+};
+
+static int __init bgmac_init(void)
+{
+ int err;
+
+ err = bcma_driver_register(&bgmac_bcma_driver);
+ if (err)
+ return err;
+ pr_info("Broadcom 47xx GBit MAC driver loaded\n");
+
+ return 0;
+}
+
+static void __exit bgmac_exit(void)
+{
+ bcma_driver_unregister(&bgmac_bcma_driver);
+}
+
+module_init(bgmac_init)
+module_exit(bgmac_exit)
+
+MODULE_AUTHOR("Rafał Miłecki");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h
new file mode 100644
index 00000000000..89fa5bc69c5
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bgmac.h
@@ -0,0 +1,488 @@
+#ifndef _BGMAC_H
+#define _BGMAC_H
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#define bgmac_err(bgmac, fmt, ...) \
+ dev_err(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
+#define bgmac_warn(bgmac, fmt, ...) \
+ dev_warn(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
+#define bgmac_info(bgmac, fmt, ...) \
+ dev_info(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
+#define bgmac_dbg(bgmac, fmt, ...) \
+ dev_dbg(&(bgmac)->core->dev, fmt, ##__VA_ARGS__)
+
+#include <linux/bcma/bcma.h>
+#include <linux/netdevice.h>
+
+#define BGMAC_DEV_CTL 0x000
+#define BGMAC_DC_TSM 0x00000002
+#define BGMAC_DC_CFCO 0x00000004
+#define BGMAC_DC_RLSS 0x00000008
+#define BGMAC_DC_MROR 0x00000010
+#define BGMAC_DC_FCM_MASK 0x00000060
+#define BGMAC_DC_FCM_SHIFT 5
+#define BGMAC_DC_NAE 0x00000080
+#define BGMAC_DC_TF 0x00000100
+#define BGMAC_DC_RDS_MASK 0x00030000
+#define BGMAC_DC_RDS_SHIFT 16
+#define BGMAC_DC_TDS_MASK 0x000c0000
+#define BGMAC_DC_TDS_SHIFT 18
+#define BGMAC_DEV_STATUS 0x004 /* Configuration of the interface */
+#define BGMAC_DS_RBF 0x00000001
+#define BGMAC_DS_RDF 0x00000002
+#define BGMAC_DS_RIF 0x00000004
+#define BGMAC_DS_TBF 0x00000008
+#define BGMAC_DS_TDF 0x00000010
+#define BGMAC_DS_TIF 0x00000020
+#define BGMAC_DS_PO 0x00000040
+#define BGMAC_DS_MM_MASK 0x00000300 /* Mode of the interface */
+#define BGMAC_DS_MM_SHIFT 8
+#define BGMAC_BIST_STATUS 0x00c
+#define BGMAC_INT_STATUS 0x020 /* Interrupt status */
+#define BGMAC_IS_MRO 0x00000001
+#define BGMAC_IS_MTO 0x00000002
+#define BGMAC_IS_TFD 0x00000004
+#define BGMAC_IS_LS 0x00000008
+#define BGMAC_IS_MDIO 0x00000010
+#define BGMAC_IS_MR 0x00000020
+#define BGMAC_IS_MT 0x00000040
+#define BGMAC_IS_TO 0x00000080
+#define BGMAC_IS_DESC_ERR 0x00000400 /* Descriptor error */
+#define BGMAC_IS_DATA_ERR 0x00000800 /* Data error */
+#define BGMAC_IS_DESC_PROT_ERR 0x00001000 /* Descriptor protocol error */
+#define BGMAC_IS_RX_DESC_UNDERF 0x00002000 /* Receive descriptor underflow */
+#define BGMAC_IS_RX_F_OVERF 0x00004000 /* Receive FIFO overflow */
+#define BGMAC_IS_TX_F_UNDERF 0x00008000 /* Transmit FIFO underflow */
+#define BGMAC_IS_RX 0x00010000 /* Interrupt for RX queue 0 */
+#define BGMAC_IS_TX0 0x01000000 /* Interrupt for TX queue 0 */
+#define BGMAC_IS_TX1 0x02000000 /* Interrupt for TX queue 1 */
+#define BGMAC_IS_TX2 0x04000000 /* Interrupt for TX queue 2 */
+#define BGMAC_IS_TX3 0x08000000 /* Interrupt for TX queue 3 */
+#define BGMAC_IS_TX_MASK 0x0f000000
+#define BGMAC_IS_INTMASK 0x0f01fcff
+#define BGMAC_IS_ERRMASK 0x0000fc00
+#define BGMAC_INT_MASK 0x024 /* Interrupt mask */
+#define BGMAC_GP_TIMER 0x028
+#define BGMAC_INT_RECV_LAZY 0x100
+#define BGMAC_IRL_TO_MASK 0x00ffffff
+#define BGMAC_IRL_FC_MASK 0xff000000
+#define BGMAC_IRL_FC_SHIFT 24 /* Shift the number of interrupts triggered per received frame */
+#define BGMAC_FLOW_CTL_THRESH 0x104 /* Flow control thresholds */
+#define BGMAC_WRRTHRESH 0x108
+#define BGMAC_GMAC_IDLE_CNT_THRESH 0x10c
+#define BGMAC_PHY_ACCESS 0x180 /* PHY access address */
+#define BGMAC_PA_DATA_MASK 0x0000ffff
+#define BGMAC_PA_ADDR_MASK 0x001f0000
+#define BGMAC_PA_ADDR_SHIFT 16
+#define BGMAC_PA_REG_MASK 0x1f000000
+#define BGMAC_PA_REG_SHIFT 24
+#define BGMAC_PA_WRITE 0x20000000
+#define BGMAC_PA_START 0x40000000
+#define BGMAC_PHY_CNTL 0x188 /* PHY control address */
+#define BGMAC_PC_EPA_MASK 0x0000001f
+#define BGMAC_PC_MCT_MASK 0x007f0000
+#define BGMAC_PC_MCT_SHIFT 16
+#define BGMAC_PC_MTE 0x00800000
+#define BGMAC_TXQ_CTL 0x18c
+#define BGMAC_TXQ_CTL_DBT_MASK 0x00000fff
+#define BGMAC_TXQ_CTL_DBT_SHIFT 0
+#define BGMAC_RXQ_CTL 0x190
+#define BGMAC_RXQ_CTL_DBT_MASK 0x00000fff
+#define BGMAC_RXQ_CTL_DBT_SHIFT 0
+#define BGMAC_RXQ_CTL_PTE 0x00001000
+#define BGMAC_RXQ_CTL_MDP_MASK 0x3f000000
+#define BGMAC_RXQ_CTL_MDP_SHIFT 24
+#define BGMAC_GPIO_SELECT 0x194
+#define BGMAC_GPIO_OUTPUT_EN 0x198
+
+/* For 0x1e0 see BCMA_CLKCTLST. Below are BGMAC specific bits */
+#define BGMAC_BCMA_CLKCTLST_MISC_PLL_REQ 0x00000100
+#define BGMAC_BCMA_CLKCTLST_MISC_PLL_ST 0x01000000
+
+#define BGMAC_HW_WAR 0x1e4
+#define BGMAC_PWR_CTL 0x1e8
+#define BGMAC_DMA_BASE0 0x200 /* Tx and Rx controller */
+#define BGMAC_DMA_BASE1 0x240 /* Tx controller only */
+#define BGMAC_DMA_BASE2 0x280 /* Tx controller only */
+#define BGMAC_DMA_BASE3 0x2C0 /* Tx controller only */
+#define BGMAC_TX_GOOD_OCTETS 0x300
+#define BGMAC_TX_GOOD_OCTETS_HIGH 0x304
+#define BGMAC_TX_GOOD_PKTS 0x308
+#define BGMAC_TX_OCTETS 0x30c
+#define BGMAC_TX_OCTETS_HIGH 0x310
+#define BGMAC_TX_PKTS 0x314
+#define BGMAC_TX_BROADCAST_PKTS 0x318
+#define BGMAC_TX_MULTICAST_PKTS 0x31c
+#define BGMAC_TX_LEN_64 0x320
+#define BGMAC_TX_LEN_65_TO_127 0x324
+#define BGMAC_TX_LEN_128_TO_255 0x328
+#define BGMAC_TX_LEN_256_TO_511 0x32c
+#define BGMAC_TX_LEN_512_TO_1023 0x330
+#define BGMAC_TX_LEN_1024_TO_1522 0x334
+#define BGMAC_TX_LEN_1523_TO_2047 0x338
+#define BGMAC_TX_LEN_2048_TO_4095 0x33c
+#define BGMAC_TX_LEN_4095_TO_8191 0x340
+#define BGMAC_TX_LEN_8192_TO_MAX 0x344
+#define BGMAC_TX_JABBER_PKTS 0x348 /* Error */
+#define BGMAC_TX_OVERSIZE_PKTS 0x34c /* Error */
+#define BGMAC_TX_FRAGMENT_PKTS 0x350
+#define BGMAC_TX_UNDERRUNS 0x354 /* Error */
+#define BGMAC_TX_TOTAL_COLS 0x358
+#define BGMAC_TX_SINGLE_COLS 0x35c
+#define BGMAC_TX_MULTIPLE_COLS 0x360
+#define BGMAC_TX_EXCESSIVE_COLS 0x364 /* Error */
+#define BGMAC_TX_LATE_COLS 0x368 /* Error */
+#define BGMAC_TX_DEFERED 0x36c
+#define BGMAC_TX_CARRIER_LOST 0x370
+#define BGMAC_TX_PAUSE_PKTS 0x374
+#define BGMAC_TX_UNI_PKTS 0x378
+#define BGMAC_TX_Q0_PKTS 0x37c
+#define BGMAC_TX_Q0_OCTETS 0x380
+#define BGMAC_TX_Q0_OCTETS_HIGH 0x384
+#define BGMAC_TX_Q1_PKTS 0x388
+#define BGMAC_TX_Q1_OCTETS 0x38c
+#define BGMAC_TX_Q1_OCTETS_HIGH 0x390
+#define BGMAC_TX_Q2_PKTS 0x394
+#define BGMAC_TX_Q2_OCTETS 0x398
+#define BGMAC_TX_Q2_OCTETS_HIGH 0x39c
+#define BGMAC_TX_Q3_PKTS 0x3a0
+#define BGMAC_TX_Q3_OCTETS 0x3a4
+#define BGMAC_TX_Q3_OCTETS_HIGH 0x3a8
+#define BGMAC_RX_GOOD_OCTETS 0x3b0
+#define BGMAC_RX_GOOD_OCTETS_HIGH 0x3b4
+#define BGMAC_RX_GOOD_PKTS 0x3b8
+#define BGMAC_RX_OCTETS 0x3bc
+#define BGMAC_RX_OCTETS_HIGH 0x3c0
+#define BGMAC_RX_PKTS 0x3c4
+#define BGMAC_RX_BROADCAST_PKTS 0x3c8
+#define BGMAC_RX_MULTICAST_PKTS 0x3cc
+#define BGMAC_RX_LEN_64 0x3d0
+#define BGMAC_RX_LEN_65_TO_127 0x3d4
+#define BGMAC_RX_LEN_128_TO_255 0x3d8
+#define BGMAC_RX_LEN_256_TO_511 0x3dc
+#define BGMAC_RX_LEN_512_TO_1023 0x3e0
+#define BGMAC_RX_LEN_1024_TO_1522 0x3e4
+#define BGMAC_RX_LEN_1523_TO_2047 0x3e8
+#define BGMAC_RX_LEN_2048_TO_4095 0x3ec
+#define BGMAC_RX_LEN_4095_TO_8191 0x3f0
+#define BGMAC_RX_LEN_8192_TO_MAX 0x3f4
+#define BGMAC_RX_JABBER_PKTS 0x3f8 /* Error */
+#define BGMAC_RX_OVERSIZE_PKTS 0x3fc /* Error */
+#define BGMAC_RX_FRAGMENT_PKTS 0x400
+#define BGMAC_RX_MISSED_PKTS 0x404 /* Error */
+#define BGMAC_RX_CRC_ALIGN_ERRS 0x408 /* Error */
+#define BGMAC_RX_UNDERSIZE 0x40c /* Error */
+#define BGMAC_RX_CRC_ERRS 0x410 /* Error */
+#define BGMAC_RX_ALIGN_ERRS 0x414 /* Error */
+#define BGMAC_RX_SYMBOL_ERRS 0x418 /* Error */
+#define BGMAC_RX_PAUSE_PKTS 0x41c
+#define BGMAC_RX_NONPAUSE_PKTS 0x420
+#define BGMAC_RX_SACHANGES 0x424
+#define BGMAC_RX_UNI_PKTS 0x428
+#define BGMAC_UNIMAC_VERSION 0x800
+#define BGMAC_HDBKP_CTL 0x804
+#define BGMAC_CMDCFG 0x808 /* Configuration */
+#define BGMAC_CMDCFG_TE 0x00000001 /* Set to activate TX */
+#define BGMAC_CMDCFG_RE 0x00000002 /* Set to activate RX */
+#define BGMAC_CMDCFG_ES_MASK 0x0000000c /* Ethernet speed see gmac_speed */
+#define BGMAC_CMDCFG_ES_10 0x00000000
+#define BGMAC_CMDCFG_ES_100 0x00000004
+#define BGMAC_CMDCFG_ES_1000 0x00000008
+#define BGMAC_CMDCFG_ES_2500 0x0000000C
+#define BGMAC_CMDCFG_PROM 0x00000010 /* Set to activate promiscuous mode */
+#define BGMAC_CMDCFG_PAD_EN 0x00000020
+#define BGMAC_CMDCFG_CF 0x00000040
+#define BGMAC_CMDCFG_PF 0x00000080
+#define BGMAC_CMDCFG_RPI 0x00000100 /* Unset to enable 802.3x tx flow control */
+#define BGMAC_CMDCFG_TAI 0x00000200
+#define BGMAC_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */
+#define BGMAC_CMDCFG_HD_SHIFT 10
+#define BGMAC_CMDCFG_SR_REV0 0x00000800 /* Set to reset mode, for other revs */
+#define BGMAC_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, only for core rev 4 */
+#define BGMAC_CMDCFG_SR(rev) ((rev == 4) ? BGMAC_CMDCFG_SR_REV4 : BGMAC_CMDCFG_SR_REV0)
+#define BGMAC_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */
+#define BGMAC_CMDCFG_AE 0x00400000
+#define BGMAC_CMDCFG_CFE 0x00800000
+#define BGMAC_CMDCFG_NLC 0x01000000
+#define BGMAC_CMDCFG_RL 0x02000000
+#define BGMAC_CMDCFG_RED 0x04000000
+#define BGMAC_CMDCFG_PE 0x08000000
+#define BGMAC_CMDCFG_TPI 0x10000000
+#define BGMAC_CMDCFG_AT 0x20000000
+#define BGMAC_MACADDR_HIGH 0x80c /* High 4 octets of own mac address */
+#define BGMAC_MACADDR_LOW 0x810 /* Low 2 octets of own mac address */
+#define BGMAC_RXMAX_LENGTH 0x814 /* Max receive frame length with vlan tag */
+#define BGMAC_PAUSEQUANTA 0x818
+#define BGMAC_MAC_MODE 0x844
+#define BGMAC_OUTERTAG 0x848
+#define BGMAC_INNERTAG 0x84c
+#define BGMAC_TXIPG 0x85c
+#define BGMAC_PAUSE_CTL 0xb30
+#define BGMAC_TX_FLUSH 0xb34
+#define BGMAC_RX_STATUS 0xb38
+#define BGMAC_TX_STATUS 0xb3c
+
+/* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */
+#define BGMAC_BCMA_IOCTL_SW_CLKEN 0x00000004 /* PHY Clock Enable */
+#define BGMAC_BCMA_IOCTL_SW_RESET 0x00000008 /* PHY Reset */
+
+/* BCMA GMAC core specific IO status (BCMA_IOST) flags */
+#define BGMAC_BCMA_IOST_ATTACHED 0x00000800
+
+#define BGMAC_NUM_MIB_TX_REGS \
+ (((BGMAC_TX_Q3_OCTETS_HIGH - BGMAC_TX_GOOD_OCTETS) / 4) + 1)
+#define BGMAC_NUM_MIB_RX_REGS \
+ (((BGMAC_RX_UNI_PKTS - BGMAC_RX_GOOD_OCTETS) / 4) + 1)
+
+#define BGMAC_DMA_TX_CTL 0x00
+#define BGMAC_DMA_TX_ENABLE 0x00000001
+#define BGMAC_DMA_TX_SUSPEND 0x00000002
+#define BGMAC_DMA_TX_LOOPBACK 0x00000004
+#define BGMAC_DMA_TX_FLUSH 0x00000010
+#define BGMAC_DMA_TX_MR_MASK 0x000000C0 /* Multiple outstanding reads */
+#define BGMAC_DMA_TX_MR_SHIFT 6
+#define BGMAC_DMA_TX_MR_1 0
+#define BGMAC_DMA_TX_MR_2 1
+#define BGMAC_DMA_TX_PARITY_DISABLE 0x00000800
+#define BGMAC_DMA_TX_ADDREXT_MASK 0x00030000
+#define BGMAC_DMA_TX_ADDREXT_SHIFT 16
+#define BGMAC_DMA_TX_BL_MASK 0x001C0000 /* BurstLen bits */
+#define BGMAC_DMA_TX_BL_SHIFT 18
+#define BGMAC_DMA_TX_BL_16 0
+#define BGMAC_DMA_TX_BL_32 1
+#define BGMAC_DMA_TX_BL_64 2
+#define BGMAC_DMA_TX_BL_128 3
+#define BGMAC_DMA_TX_BL_256 4
+#define BGMAC_DMA_TX_BL_512 5
+#define BGMAC_DMA_TX_BL_1024 6
+#define BGMAC_DMA_TX_PC_MASK 0x00E00000 /* Prefetch control */
+#define BGMAC_DMA_TX_PC_SHIFT 21
+#define BGMAC_DMA_TX_PC_0 0
+#define BGMAC_DMA_TX_PC_4 1
+#define BGMAC_DMA_TX_PC_8 2
+#define BGMAC_DMA_TX_PC_16 3
+#define BGMAC_DMA_TX_PT_MASK 0x03000000 /* Prefetch threshold */
+#define BGMAC_DMA_TX_PT_SHIFT 24
+#define BGMAC_DMA_TX_PT_1 0
+#define BGMAC_DMA_TX_PT_2 1
+#define BGMAC_DMA_TX_PT_4 2
+#define BGMAC_DMA_TX_PT_8 3
+#define BGMAC_DMA_TX_INDEX 0x04
+#define BGMAC_DMA_TX_RINGLO 0x08
+#define BGMAC_DMA_TX_RINGHI 0x0C
+#define BGMAC_DMA_TX_STATUS 0x10
+#define BGMAC_DMA_TX_STATDPTR 0x00001FFF
+#define BGMAC_DMA_TX_STAT 0xF0000000
+#define BGMAC_DMA_TX_STAT_DISABLED 0x00000000
+#define BGMAC_DMA_TX_STAT_ACTIVE 0x10000000
+#define BGMAC_DMA_TX_STAT_IDLEWAIT 0x20000000
+#define BGMAC_DMA_TX_STAT_STOPPED 0x30000000
+#define BGMAC_DMA_TX_STAT_SUSP 0x40000000
+#define BGMAC_DMA_TX_ERROR 0x14
+#define BGMAC_DMA_TX_ERRDPTR 0x0001FFFF
+#define BGMAC_DMA_TX_ERR 0xF0000000
+#define BGMAC_DMA_TX_ERR_NOERR 0x00000000
+#define BGMAC_DMA_TX_ERR_PROT 0x10000000
+#define BGMAC_DMA_TX_ERR_UNDERRUN 0x20000000
+#define BGMAC_DMA_TX_ERR_TRANSFER 0x30000000
+#define BGMAC_DMA_TX_ERR_DESCREAD 0x40000000
+#define BGMAC_DMA_TX_ERR_CORE 0x50000000
+#define BGMAC_DMA_RX_CTL 0x20
+#define BGMAC_DMA_RX_ENABLE 0x00000001
+#define BGMAC_DMA_RX_FRAME_OFFSET_MASK 0x000000FE
+#define BGMAC_DMA_RX_FRAME_OFFSET_SHIFT 1
+#define BGMAC_DMA_RX_DIRECT_FIFO 0x00000100
+#define BGMAC_DMA_RX_OVERFLOW_CONT 0x00000400
+#define BGMAC_DMA_RX_PARITY_DISABLE 0x00000800
+#define BGMAC_DMA_RX_MR_MASK 0x000000C0 /* Multiple outstanding reads */
+#define BGMAC_DMA_RX_MR_SHIFT 6
+#define BGMAC_DMA_TX_MR_1 0
+#define BGMAC_DMA_TX_MR_2 1
+#define BGMAC_DMA_RX_ADDREXT_MASK 0x00030000
+#define BGMAC_DMA_RX_ADDREXT_SHIFT 16
+#define BGMAC_DMA_RX_BL_MASK 0x001C0000 /* BurstLen bits */
+#define BGMAC_DMA_RX_BL_SHIFT 18
+#define BGMAC_DMA_RX_BL_16 0
+#define BGMAC_DMA_RX_BL_32 1
+#define BGMAC_DMA_RX_BL_64 2
+#define BGMAC_DMA_RX_BL_128 3
+#define BGMAC_DMA_RX_BL_256 4
+#define BGMAC_DMA_RX_BL_512 5
+#define BGMAC_DMA_RX_BL_1024 6
+#define BGMAC_DMA_RX_PC_MASK 0x00E00000 /* Prefetch control */
+#define BGMAC_DMA_RX_PC_SHIFT 21
+#define BGMAC_DMA_RX_PC_0 0
+#define BGMAC_DMA_RX_PC_4 1
+#define BGMAC_DMA_RX_PC_8 2
+#define BGMAC_DMA_RX_PC_16 3
+#define BGMAC_DMA_RX_PT_MASK 0x03000000 /* Prefetch threshold */
+#define BGMAC_DMA_RX_PT_SHIFT 24
+#define BGMAC_DMA_RX_PT_1 0
+#define BGMAC_DMA_RX_PT_2 1
+#define BGMAC_DMA_RX_PT_4 2
+#define BGMAC_DMA_RX_PT_8 3
+#define BGMAC_DMA_RX_INDEX 0x24
+#define BGMAC_DMA_RX_RINGLO 0x28
+#define BGMAC_DMA_RX_RINGHI 0x2C
+#define BGMAC_DMA_RX_STATUS 0x30
+#define BGMAC_DMA_RX_STATDPTR 0x00001FFF
+#define BGMAC_DMA_RX_STAT 0xF0000000
+#define BGMAC_DMA_RX_STAT_DISABLED 0x00000000
+#define BGMAC_DMA_RX_STAT_ACTIVE 0x10000000
+#define BGMAC_DMA_RX_STAT_IDLEWAIT 0x20000000
+#define BGMAC_DMA_RX_STAT_STOPPED 0x30000000
+#define BGMAC_DMA_RX_STAT_SUSP 0x40000000
+#define BGMAC_DMA_RX_ERROR 0x34
+#define BGMAC_DMA_RX_ERRDPTR 0x0001FFFF
+#define BGMAC_DMA_RX_ERR 0xF0000000
+#define BGMAC_DMA_RX_ERR_NOERR 0x00000000
+#define BGMAC_DMA_RX_ERR_PROT 0x10000000
+#define BGMAC_DMA_RX_ERR_UNDERRUN 0x20000000
+#define BGMAC_DMA_RX_ERR_TRANSFER 0x30000000
+#define BGMAC_DMA_RX_ERR_DESCREAD 0x40000000
+#define BGMAC_DMA_RX_ERR_CORE 0x50000000
+
+#define BGMAC_DESC_CTL0_EOT 0x10000000 /* End of ring */
+#define BGMAC_DESC_CTL0_IOC 0x20000000 /* IRQ on complete */
+#define BGMAC_DESC_CTL0_SOF 0x40000000 /* Start of frame */
+#define BGMAC_DESC_CTL0_EOF 0x80000000 /* End of frame */
+#define BGMAC_DESC_CTL1_LEN 0x00001FFF
+
+#define BGMAC_PHY_NOREGS 0x1E
+#define BGMAC_PHY_MASK 0x1F
+
+#define BGMAC_MAX_TX_RINGS 4
+#define BGMAC_MAX_RX_RINGS 1
+
+#define BGMAC_TX_RING_SLOTS 128
+#define BGMAC_RX_RING_SLOTS 512 - 1 /* Why -1? Well, Broadcom does that... */
+
+#define BGMAC_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */
+#define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
+#define BGMAC_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */
+#define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
+
+#define BGMAC_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */
+#define BGMAC_BFL_ENETADM 0x0080 /* has ADMtek switch */
+#define BGMAC_BFL_ENETVLAN 0x0100 /* can do vlan */
+
+#define BGMAC_CHIPCTL_1_IF_TYPE_MASK 0x00000030
+#define BGMAC_CHIPCTL_1_IF_TYPE_RMII 0x00000000
+#define BGMAC_CHIPCTL_1_IF_TYPE_MII 0x00000010
+#define BGMAC_CHIPCTL_1_IF_TYPE_RGMII 0x00000020
+#define BGMAC_CHIPCTL_1_SW_TYPE_MASK 0x000000C0
+#define BGMAC_CHIPCTL_1_SW_TYPE_EPHY 0x00000000
+#define BGMAC_CHIPCTL_1_SW_TYPE_EPHYMII 0x00000040
+#define BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII 0x00000080
+#define BGMAC_CHIPCTL_1_SW_TYPE_RGMII 0x000000C0
+#define BGMAC_CHIPCTL_1_RXC_DLL_BYPASS 0x00010000
+
+#define BGMAC_WEIGHT 64
+
+#define ETHER_MAX_LEN 1518
+
+struct bgmac_slot_info {
+ struct sk_buff *skb;
+ dma_addr_t dma_addr;
+};
+
+struct bgmac_dma_desc {
+ __le32 ctl0;
+ __le32 ctl1;
+ __le32 addr_low;
+ __le32 addr_high;
+} __packed;
+
+enum bgmac_dma_ring_type {
+ BGMAC_DMA_RING_TX,
+ BGMAC_DMA_RING_RX,
+};
+
+/**
+ * bgmac_dma_ring - contains info about DMA ring (either TX or RX one)
+ * @start: index of the first slot containing data
+ * @end: index of a slot that can *not* be read (yet)
+ *
+ * Be really aware of the specific @end meaning. It's an index of a slot *after*
+ * the one containing data that can be read. If @start equals @end the ring is
+ * empty.
+ */
+struct bgmac_dma_ring {
+ u16 num_slots;
+ u16 start;
+ u16 end;
+
+ u16 mmio_base;
+ struct bgmac_dma_desc *cpu_base;
+ dma_addr_t dma_base;
+ u32 index_base; /* Used for unaligned rings only, otherwise 0 */
+ bool unaligned;
+
+ struct bgmac_slot_info slots[BGMAC_RX_RING_SLOTS];
+};
+
+struct bgmac_rx_header {
+ __le16 len;
+ __le16 flags;
+ __le16 pad[12];
+};
+
+struct bgmac {
+ struct bcma_device *core;
+ struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */
+ struct net_device *net_dev;
+ struct napi_struct napi;
+ struct mii_bus *mii_bus;
+ struct phy_device *phy_dev;
+
+ /* DMA */
+ struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS];
+ struct bgmac_dma_ring rx_ring[BGMAC_MAX_RX_RINGS];
+
+ /* Stats */
+ bool stats_grabbed;
+ u32 mib_tx_regs[BGMAC_NUM_MIB_TX_REGS];
+ u32 mib_rx_regs[BGMAC_NUM_MIB_RX_REGS];
+
+ /* Int */
+ u32 int_mask;
+ u32 int_status;
+
+ /* Current MAC state */
+ int mac_speed;
+ int mac_duplex;
+
+ u8 phyaddr;
+ bool has_robosw;
+
+ bool loopback;
+};
+
+static inline u32 bgmac_read(struct bgmac *bgmac, u16 offset)
+{
+ return bcma_read32(bgmac->core, offset);
+}
+
+static inline void bgmac_write(struct bgmac *bgmac, u16 offset, u32 value)
+{
+ bcma_write32(bgmac->core, offset, value);
+}
+
+static inline void bgmac_maskset(struct bgmac *bgmac, u16 offset, u32 mask,
+ u32 set)
+{
+ bgmac_write(bgmac, offset, (bgmac_read(bgmac, offset) & mask) | set);
+}
+
+static inline void bgmac_mask(struct bgmac *bgmac, u16 offset, u32 mask)
+{
+ bgmac_maskset(bgmac, offset, mask, 0);
+}
+
+static inline void bgmac_set(struct bgmac *bgmac, u16 offset, u32 set)
+{
+ bgmac_maskset(bgmac, offset, ~0, set);
+}
+
+#endif /* _BGMAC_H */
diff --git a/drivers/net/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 2486a656f12..67d2b004737 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -1,6 +1,6 @@
/* bnx2.c: Broadcom NX2 network driver.
*
- * Copyright (c) 2004-2008 Broadcom Corporation
+ * Copyright (c) 2004-2013 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -9,10 +9,12 @@
* Written by: Michael Chan (mchan@broadcom.com)
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/stringify.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/errno.h>
@@ -21,7 +23,6 @@
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -35,10 +36,8 @@
#include <linux/time.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
+#include <linux/if.h>
#include <linux/if_vlan.h>
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define BCM_VLAN 1
-#endif
#include <net/ip.h>
#include <net/tcp.h>
#include <net/checksum.h>
@@ -46,36 +45,47 @@
#include <linux/crc32.h>
#include <linux/prefetch.h>
#include <linux/cache.h>
-#include <linux/zlib.h>
+#include <linux/firmware.h>
#include <linux/log2.h>
+#include <linux/aer.h>
+#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
+#define BCM_CNIC 1
+#include "cnic_if.h"
+#endif
#include "bnx2.h"
#include "bnx2_fw.h"
-#include "bnx2_fw2.h"
-
-#define FW_BUF_SIZE 0x10000
#define DRV_MODULE_NAME "bnx2"
-#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.8.0"
-#define DRV_MODULE_RELDATE "Aug 14, 2008"
+#define DRV_MODULE_VERSION "2.2.5"
+#define DRV_MODULE_RELDATE "December 20, 2013"
+#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw"
+#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw"
+#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw"
+#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw"
+#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw"
#define RUN_AT(x) (jiffies + (x))
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (5*HZ)
-static char version[] __devinitdata =
+static char version[] =
"Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709/5716 Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_FIRMWARE(FW_MIPS_FILE_06);
+MODULE_FIRMWARE(FW_RV2P_FILE_06);
+MODULE_FIRMWARE(FW_MIPS_FILE_09);
+MODULE_FIRMWARE(FW_RV2P_FILE_09);
+MODULE_FIRMWARE(FW_RV2P_FILE_09_Ax);
static int disable_msi = 0;
-module_param(disable_msi, int, 0);
+module_param(disable_msi, int, S_IRUGO);
MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
typedef enum {
@@ -89,12 +99,13 @@ typedef enum {
BCM5709,
BCM5709S,
BCM5716,
+ BCM5716S,
} board_t;
/* indexed by board_t, above */
static struct {
char *name;
-} board_info[] __devinitdata = {
+} board_info[] = {
{ "Broadcom NetXtreme II BCM5706 1000Base-T" },
{ "HP NC370T Multifunction Gigabit Server Adapter" },
{ "HP NC370i Multifunction Gigabit Server Adapter" },
@@ -105,6 +116,7 @@ static struct {
{ "Broadcom NetXtreme II BCM5709 1000Base-T" },
{ "Broadcom NetXtreme II BCM5709 1000Base-SX" },
{ "Broadcom NetXtreme II BCM5716 1000Base-T" },
+ { "Broadcom NetXtreme II BCM5716 1000Base-SX" },
};
static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
@@ -128,10 +140,12 @@ static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709S },
{ PCI_VENDOR_ID_BROADCOM, 0x163b,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
+ { PCI_VENDOR_ID_BROADCOM, 0x163c,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716S },
{ 0, }
};
-static struct flash_spec flash_table[] =
+static const struct flash_spec flash_table[] =
{
#define BUFFERED_FLAGS (BNX2_NV_BUFFERED | BNX2_NV_TRANSLATE)
#define NONBUFFERED_FLAGS (BNX2_NV_WREN)
@@ -220,7 +234,7 @@ static struct flash_spec flash_table[] =
"Buffered flash (256kB)"},
};
-static struct flash_spec flash_5709 = {
+static const struct flash_spec flash_5709 = {
.flags = BNX2_NV_BUFFERED,
.page_bits = BCM5709_FLASH_PAGE_BITS,
.page_size = BCM5709_FLASH_PAGE_SIZE,
@@ -231,22 +245,26 @@ static struct flash_spec flash_5709 = {
MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
+static void bnx2_init_napi(struct bnx2 *bp);
+static void bnx2_del_napi(struct bnx2 *bp);
+
static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
{
u32 diff;
- smp_mb();
+ /* Tell compiler to fetch tx_prod and tx_cons from memory. */
+ barrier();
/* The ring uses 256 indices for 255 entries, one of them
* needs to be skipped.
*/
diff = txr->tx_prod - txr->tx_cons;
- if (unlikely(diff >= TX_DESC_CNT)) {
+ if (unlikely(diff >= BNX2_TX_DESC_CNT)) {
diff &= 0xffff;
- if (diff == TX_DESC_CNT)
- diff = MAX_TX_DESC_CNT;
+ if (diff == BNX2_TX_DESC_CNT)
+ diff = BNX2_MAX_TX_DESC_CNT;
}
- return (bp->tx_ring_size - diff);
+ return bp->tx_ring_size - diff;
}
static u32
@@ -255,8 +273,8 @@ bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
u32 val;
spin_lock_bh(&bp->indirect_lock);
- REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
- val = REG_RD(bp, BNX2_PCICFG_REG_WINDOW);
+ BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
+ val = BNX2_RD(bp, BNX2_PCICFG_REG_WINDOW);
spin_unlock_bh(&bp->indirect_lock);
return val;
}
@@ -265,8 +283,8 @@ static void
bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
{
spin_lock_bh(&bp->indirect_lock);
- REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
- REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
+ BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
+ BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
spin_unlock_bh(&bp->indirect_lock);
}
@@ -279,7 +297,7 @@ bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val)
static u32
bnx2_shmem_rd(struct bnx2 *bp, u32 offset)
{
- return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset));
+ return bnx2_reg_rd_ind(bp, bp->shmem_base + offset);
}
static void
@@ -287,25 +305,186 @@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
{
offset += cid_addr;
spin_lock_bh(&bp->indirect_lock);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
int i;
- REG_WR(bp, BNX2_CTX_CTX_DATA, val);
- REG_WR(bp, BNX2_CTX_CTX_CTRL,
- offset | BNX2_CTX_CTX_CTRL_WRITE_REQ);
+ BNX2_WR(bp, BNX2_CTX_CTX_DATA, val);
+ BNX2_WR(bp, BNX2_CTX_CTX_CTRL,
+ offset | BNX2_CTX_CTX_CTRL_WRITE_REQ);
for (i = 0; i < 5; i++) {
- val = REG_RD(bp, BNX2_CTX_CTX_CTRL);
+ val = BNX2_RD(bp, BNX2_CTX_CTX_CTRL);
if ((val & BNX2_CTX_CTX_CTRL_WRITE_REQ) == 0)
break;
udelay(5);
}
} else {
- REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
- REG_WR(bp, BNX2_CTX_DATA, val);
+ BNX2_WR(bp, BNX2_CTX_DATA_ADR, offset);
+ BNX2_WR(bp, BNX2_CTX_DATA, val);
}
spin_unlock_bh(&bp->indirect_lock);
}
+#ifdef BCM_CNIC
+static int
+bnx2_drv_ctl(struct net_device *dev, struct drv_ctl_info *info)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+ struct drv_ctl_io *io = &info->data.io;
+
+ switch (info->cmd) {
+ case DRV_CTL_IO_WR_CMD:
+ bnx2_reg_wr_ind(bp, io->offset, io->data);
+ break;
+ case DRV_CTL_IO_RD_CMD:
+ io->data = bnx2_reg_rd_ind(bp, io->offset);
+ break;
+ case DRV_CTL_CTX_WR_CMD:
+ bnx2_ctx_wr(bp, io->cid_addr, io->offset, io->data);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void bnx2_setup_cnic_irq_info(struct bnx2 *bp)
+{
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+ int sb_id;
+
+ if (bp->flags & BNX2_FLAG_USING_MSIX) {
+ cp->drv_state |= CNIC_DRV_STATE_USING_MSIX;
+ bnapi->cnic_present = 0;
+ sb_id = bp->irq_nvecs;
+ cp->irq_arr[0].irq_flags |= CNIC_IRQ_FL_MSIX;
+ } else {
+ cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX;
+ bnapi->cnic_tag = bnapi->last_status_idx;
+ bnapi->cnic_present = 1;
+ sb_id = 0;
+ cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX;
+ }
+
+ cp->irq_arr[0].vector = bp->irq_tbl[sb_id].vector;
+ cp->irq_arr[0].status_blk = (void *)
+ ((unsigned long) bnapi->status_blk.msi +
+ (BNX2_SBLK_MSIX_ALIGN_SIZE * sb_id));
+ cp->irq_arr[0].status_blk_num = sb_id;
+ cp->num_irq = 1;
+}
+
+static int bnx2_register_cnic(struct net_device *dev, struct cnic_ops *ops,
+ void *data)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ if (ops == NULL)
+ return -EINVAL;
+
+ if (cp->drv_state & CNIC_DRV_STATE_REGD)
+ return -EBUSY;
+
+ if (!bnx2_reg_rd_ind(bp, BNX2_FW_MAX_ISCSI_CONN))
+ return -ENODEV;
+
+ bp->cnic_data = data;
+ rcu_assign_pointer(bp->cnic_ops, ops);
+
+ cp->num_irq = 0;
+ cp->drv_state = CNIC_DRV_STATE_REGD;
+
+ bnx2_setup_cnic_irq_info(bp);
+
+ return 0;
+}
+
+static int bnx2_unregister_cnic(struct net_device *dev)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ mutex_lock(&bp->cnic_lock);
+ cp->drv_state = 0;
+ bnapi->cnic_present = 0;
+ RCU_INIT_POINTER(bp->cnic_ops, NULL);
+ mutex_unlock(&bp->cnic_lock);
+ synchronize_rcu();
+ return 0;
+}
+
+static struct cnic_eth_dev *bnx2_cnic_probe(struct net_device *dev)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ if (!cp->max_iscsi_conn)
+ return NULL;
+
+ cp->drv_owner = THIS_MODULE;
+ cp->chip_id = bp->chip_id;
+ cp->pdev = bp->pdev;
+ cp->io_base = bp->regview;
+ cp->drv_ctl = bnx2_drv_ctl;
+ cp->drv_register_cnic = bnx2_register_cnic;
+ cp->drv_unregister_cnic = bnx2_unregister_cnic;
+
+ return cp;
+}
+
+static void
+bnx2_cnic_stop(struct bnx2 *bp)
+{
+ struct cnic_ops *c_ops;
+ struct cnic_ctl_info info;
+
+ mutex_lock(&bp->cnic_lock);
+ c_ops = rcu_dereference_protected(bp->cnic_ops,
+ lockdep_is_held(&bp->cnic_lock));
+ if (c_ops) {
+ info.cmd = CNIC_CTL_STOP_CMD;
+ c_ops->cnic_ctl(bp->cnic_data, &info);
+ }
+ mutex_unlock(&bp->cnic_lock);
+}
+
+static void
+bnx2_cnic_start(struct bnx2 *bp)
+{
+ struct cnic_ops *c_ops;
+ struct cnic_ctl_info info;
+
+ mutex_lock(&bp->cnic_lock);
+ c_ops = rcu_dereference_protected(bp->cnic_ops,
+ lockdep_is_held(&bp->cnic_lock));
+ if (c_ops) {
+ if (!(bp->flags & BNX2_FLAG_USING_MSIX)) {
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+
+ bnapi->cnic_tag = bnapi->last_status_idx;
+ }
+ info.cmd = CNIC_CTL_START_CMD;
+ c_ops->cnic_ctl(bp->cnic_data, &info);
+ }
+ mutex_unlock(&bp->cnic_lock);
+}
+
+#else
+
+static void
+bnx2_cnic_stop(struct bnx2 *bp)
+{
+}
+
+static void
+bnx2_cnic_start(struct bnx2 *bp)
+{
+}
+
+#endif
+
static int
bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
{
@@ -313,11 +492,11 @@ bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
int i, ret;
if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
- val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ val1 = BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
- REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ BNX2_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+ BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
udelay(40);
}
@@ -325,16 +504,16 @@ bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
val1 = (bp->phy_addr << 21) | (reg << 16) |
BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT |
BNX2_EMAC_MDIO_COMM_START_BUSY;
- REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
+ BNX2_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
for (i = 0; i < 50; i++) {
udelay(10);
- val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+ val1 = BNX2_RD(bp, BNX2_EMAC_MDIO_COMM);
if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
- val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+ val1 = BNX2_RD(bp, BNX2_EMAC_MDIO_COMM);
val1 &= BNX2_EMAC_MDIO_COMM_DATA;
break;
@@ -351,11 +530,11 @@ bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
}
if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
- val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ val1 = BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
- REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ BNX2_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+ BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
udelay(40);
}
@@ -370,11 +549,11 @@ bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
int i, ret;
if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
- val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ val1 = BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
- REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ BNX2_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+ BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
udelay(40);
}
@@ -382,12 +561,12 @@ bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
val1 = (bp->phy_addr << 21) | (reg << 16) | val |
BNX2_EMAC_MDIO_COMM_COMMAND_WRITE |
BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT;
- REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
+ BNX2_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
for (i = 0; i < 50; i++) {
udelay(10);
- val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+ val1 = BNX2_RD(bp, BNX2_EMAC_MDIO_COMM);
if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
udelay(5);
break;
@@ -400,11 +579,11 @@ bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
ret = 0;
if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
- val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ val1 = BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
- REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
- REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+ BNX2_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+ BNX2_RD(bp, BNX2_EMAC_MDIO_MODE);
udelay(40);
}
@@ -420,10 +599,10 @@ bnx2_disable_int(struct bnx2 *bp)
for (i = 0; i < bp->irq_nvecs; i++) {
bnapi = &bp->bnx2_napi[i];
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
}
- REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
+ BNX2_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
}
static void
@@ -435,16 +614,16 @@ bnx2_enable_int(struct bnx2 *bp)
for (i = 0; i < bp->irq_nvecs; i++) {
bnapi = &bp->bnx2_napi[i];
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
- BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
- BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
- bnapi->last_status_idx);
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+ BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
+ bnapi->last_status_idx);
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
- BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
- bnapi->last_status_idx);
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+ BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ bnapi->last_status_idx);
}
- REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
+ BNX2_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
}
static void
@@ -453,6 +632,9 @@ bnx2_disable_int_sync(struct bnx2 *bp)
int i;
atomic_inc(&bp->intr_sem);
+ if (!netif_running(bp->dev))
+ return;
+
bnx2_disable_int(bp);
for (i = 0; i < bp->irq_nvecs; i++)
synchronize_irq(bp->irq_tbl[i].vector);
@@ -477,24 +659,32 @@ bnx2_napi_enable(struct bnx2 *bp)
}
static void
-bnx2_netif_stop(struct bnx2 *bp)
+bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
{
- bnx2_disable_int_sync(bp);
+ if (stop_cnic)
+ bnx2_cnic_stop(bp);
if (netif_running(bp->dev)) {
bnx2_napi_disable(bp);
netif_tx_disable(bp->dev);
- bp->dev->trans_start = jiffies; /* prevent tx timeout */
}
+ bnx2_disable_int_sync(bp);
+ netif_carrier_off(bp->dev); /* prevent tx timeout */
}
static void
-bnx2_netif_start(struct bnx2 *bp)
+bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
{
if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
netif_tx_wake_all_queues(bp->dev);
+ spin_lock_bh(&bp->phy_lock);
+ if (bp->link_up)
+ netif_carrier_on(bp->dev);
+ spin_unlock_bh(&bp->phy_lock);
bnx2_napi_enable(bp);
bnx2_enable_int(bp);
+ if (start_cnic)
+ bnx2_cnic_start(bp);
}
}
}
@@ -509,9 +699,9 @@ bnx2_free_tx_mem(struct bnx2 *bp)
struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
if (txr->tx_desc_ring) {
- pci_free_consistent(bp->pdev, TXBD_RING_SIZE,
- txr->tx_desc_ring,
- txr->tx_desc_mapping);
+ dma_free_coherent(&bp->pdev->dev, TXBD_RING_SIZE,
+ txr->tx_desc_ring,
+ txr->tx_desc_mapping);
txr->tx_desc_ring = NULL;
}
kfree(txr->tx_buf_ring);
@@ -531,24 +721,22 @@ bnx2_free_rx_mem(struct bnx2 *bp)
for (j = 0; j < bp->rx_max_ring; j++) {
if (rxr->rx_desc_ring[j])
- pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
- rxr->rx_desc_ring[j],
- rxr->rx_desc_mapping[j]);
+ dma_free_coherent(&bp->pdev->dev, RXBD_RING_SIZE,
+ rxr->rx_desc_ring[j],
+ rxr->rx_desc_mapping[j]);
rxr->rx_desc_ring[j] = NULL;
}
- if (rxr->rx_buf_ring)
- vfree(rxr->rx_buf_ring);
+ vfree(rxr->rx_buf_ring);
rxr->rx_buf_ring = NULL;
for (j = 0; j < bp->rx_max_pg_ring; j++) {
if (rxr->rx_pg_desc_ring[j])
- pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
- rxr->rx_pg_desc_ring[i],
- rxr->rx_pg_desc_mapping[i]);
- rxr->rx_pg_desc_ring[i] = NULL;
+ dma_free_coherent(&bp->pdev->dev, RXBD_RING_SIZE,
+ rxr->rx_pg_desc_ring[j],
+ rxr->rx_pg_desc_mapping[j]);
+ rxr->rx_pg_desc_ring[j] = NULL;
}
- if (rxr->rx_pg_ring)
- vfree(rxr->rx_pg_ring);
+ vfree(rxr->rx_pg_ring);
rxr->rx_pg_ring = NULL;
}
}
@@ -567,8 +755,8 @@ bnx2_alloc_tx_mem(struct bnx2 *bp)
return -ENOMEM;
txr->tx_desc_ring =
- pci_alloc_consistent(bp->pdev, TXBD_RING_SIZE,
- &txr->tx_desc_mapping);
+ dma_alloc_coherent(&bp->pdev->dev, TXBD_RING_SIZE,
+ &txr->tx_desc_mapping, GFP_KERNEL);
if (txr->tx_desc_ring == NULL)
return -ENOMEM;
}
@@ -586,36 +774,35 @@ bnx2_alloc_rx_mem(struct bnx2 *bp)
int j;
rxr->rx_buf_ring =
- vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
+ vzalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
if (rxr->rx_buf_ring == NULL)
return -ENOMEM;
- memset(rxr->rx_buf_ring, 0,
- SW_RXBD_RING_SIZE * bp->rx_max_ring);
-
for (j = 0; j < bp->rx_max_ring; j++) {
rxr->rx_desc_ring[j] =
- pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
- &rxr->rx_desc_mapping[j]);
+ dma_alloc_coherent(&bp->pdev->dev,
+ RXBD_RING_SIZE,
+ &rxr->rx_desc_mapping[j],
+ GFP_KERNEL);
if (rxr->rx_desc_ring[j] == NULL)
return -ENOMEM;
}
if (bp->rx_pg_ring_size) {
- rxr->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
+ rxr->rx_pg_ring = vzalloc(SW_RXPG_RING_SIZE *
bp->rx_max_pg_ring);
if (rxr->rx_pg_ring == NULL)
return -ENOMEM;
- memset(rxr->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
- bp->rx_max_pg_ring);
}
for (j = 0; j < bp->rx_max_pg_ring; j++) {
rxr->rx_pg_desc_ring[j] =
- pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
- &rxr->rx_pg_desc_mapping[j]);
+ dma_alloc_coherent(&bp->pdev->dev,
+ RXBD_RING_SIZE,
+ &rxr->rx_pg_desc_mapping[j],
+ GFP_KERNEL);
if (rxr->rx_pg_desc_ring[j] == NULL)
return -ENOMEM;
@@ -635,16 +822,16 @@ bnx2_free_mem(struct bnx2 *bp)
for (i = 0; i < bp->ctx_pages; i++) {
if (bp->ctx_blk[i]) {
- pci_free_consistent(bp->pdev, BCM_PAGE_SIZE,
- bp->ctx_blk[i],
- bp->ctx_blk_mapping[i]);
+ dma_free_coherent(&bp->pdev->dev, BNX2_PAGE_SIZE,
+ bp->ctx_blk[i],
+ bp->ctx_blk_mapping[i]);
bp->ctx_blk[i] = NULL;
}
}
if (bnapi->status_blk.msi) {
- pci_free_consistent(bp->pdev, bp->status_stats_size,
- bnapi->status_blk.msi,
- bp->status_blk_mapping);
+ dma_free_coherent(&bp->pdev->dev, bp->status_stats_size,
+ bnapi->status_blk.msi,
+ bp->status_blk_mapping);
bnapi->status_blk.msi = NULL;
bp->stats_blk = NULL;
}
@@ -665,13 +852,11 @@ bnx2_alloc_mem(struct bnx2 *bp)
bp->status_stats_size = status_blk_size +
sizeof(struct statistics_block);
- status_blk = pci_alloc_consistent(bp->pdev, bp->status_stats_size,
- &bp->status_blk_mapping);
+ status_blk = dma_zalloc_coherent(&bp->pdev->dev, bp->status_stats_size,
+ &bp->status_blk_mapping, GFP_KERNEL);
if (status_blk == NULL)
goto alloc_mem_err;
- memset(status_blk, 0, bp->status_stats_size);
-
bnapi = &bp->bnx2_napi[0];
bnapi->status_blk.msi = status_blk;
bnapi->hw_tx_cons_ptr =
@@ -679,13 +864,12 @@ bnx2_alloc_mem(struct bnx2 *bp)
bnapi->hw_rx_cons_ptr =
&bnapi->status_blk.msi->status_rx_quick_consumer_index0;
if (bp->flags & BNX2_FLAG_MSIX_CAP) {
- for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) {
+ for (i = 1; i < bp->irq_nvecs; i++) {
struct status_block_msix *sblk;
bnapi = &bp->bnx2_napi[i];
- sblk = (void *) (status_blk +
- BNX2_SBLK_MSIX_ALIGN_SIZE * i);
+ sblk = (status_blk + BNX2_SBLK_MSIX_ALIGN_SIZE * i);
bnapi->status_blk.msix = sblk;
bnapi->hw_tx_cons_ptr =
&sblk->status_tx_quick_consumer_index;
@@ -699,14 +883,15 @@ bnx2_alloc_mem(struct bnx2 *bp)
bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- bp->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ bp->ctx_pages = 0x2000 / BNX2_PAGE_SIZE;
if (bp->ctx_pages == 0)
bp->ctx_pages = 1;
for (i = 0; i < bp->ctx_pages; i++) {
- bp->ctx_blk[i] = pci_alloc_consistent(bp->pdev,
- BCM_PAGE_SIZE,
- &bp->ctx_blk_mapping[i]);
+ bp->ctx_blk[i] = dma_alloc_coherent(&bp->pdev->dev,
+ BNX2_PAGE_SIZE,
+ &bp->ctx_blk_mapping[i],
+ GFP_KERNEL);
if (bp->ctx_blk[i] == NULL)
goto alloc_mem_err;
}
@@ -789,9 +974,9 @@ bnx2_report_fw_link(struct bnx2 *bp)
static char *
bnx2_xceiver_str(struct bnx2 *bp)
{
- return ((bp->phy_port == PORT_FIBRE) ? "SerDes" :
+ return (bp->phy_port == PORT_FIBRE) ? "SerDes" :
((bp->phy_flags & BNX2_PHY_FLAG_SERDES) ? "Remote Copper" :
- "Copper"));
+ "Copper");
}
static void
@@ -799,33 +984,27 @@ bnx2_report_link(struct bnx2 *bp)
{
if (bp->link_up) {
netif_carrier_on(bp->dev);
- printk(KERN_INFO PFX "%s NIC %s Link is Up, ", bp->dev->name,
- bnx2_xceiver_str(bp));
-
- printk("%d Mbps ", bp->line_speed);
-
- if (bp->duplex == DUPLEX_FULL)
- printk("full duplex");
- else
- printk("half duplex");
+ netdev_info(bp->dev, "NIC %s Link is Up, %d Mbps %s duplex",
+ bnx2_xceiver_str(bp),
+ bp->line_speed,
+ bp->duplex == DUPLEX_FULL ? "full" : "half");
if (bp->flow_ctrl) {
if (bp->flow_ctrl & FLOW_CTRL_RX) {
- printk(", receive ");
+ pr_cont(", receive ");
if (bp->flow_ctrl & FLOW_CTRL_TX)
- printk("& transmit ");
+ pr_cont("& transmit ");
}
else {
- printk(", transmit ");
+ pr_cont(", transmit ");
}
- printk("flow control ON");
+ pr_cont("flow control ON");
}
- printk("\n");
- }
- else {
+ pr_cont("\n");
+ } else {
netif_carrier_off(bp->dev);
- printk(KERN_ERR PFX "%s NIC %s Link is Down\n", bp->dev->name,
- bnx2_xceiver_str(bp));
+ netdev_err(bp->dev, "NIC %s Link is Down\n",
+ bnx2_xceiver_str(bp));
}
bnx2_report_fw_link(bp);
@@ -851,7 +1030,7 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
}
if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
- (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+ (BNX2_CHIP(bp) == BNX2_CHIP_5708)) {
u32 val;
bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
@@ -1017,6 +1196,8 @@ bnx2_copper_linkup(struct bnx2 *bp)
{
u32 bmcr;
+ bp->phy_flags &= ~BNX2_PHY_FLAG_MDIX;
+
bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
if (bmcr & BMCR_ANENABLE) {
u32 local_adv, remote_adv, common;
@@ -1075,6 +1256,14 @@ bnx2_copper_linkup(struct bnx2 *bp)
}
}
+ if (bp->link_up) {
+ u32 ext_status;
+
+ bnx2_read_phy(bp, MII_BNX2_EXT_STATUS, &ext_status);
+ if (ext_status & EXT_STATUS_MDIX)
+ bp->phy_flags |= BNX2_PHY_FLAG_MDIX;
+ }
+
return 0;
}
@@ -1087,30 +1276,9 @@ bnx2_init_rx_context(struct bnx2 *bp, u32 cid)
val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
val |= 0x02 << 8;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- u32 lo_water, hi_water;
-
- if (bp->flow_ctrl & FLOW_CTRL_TX)
- lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT;
- else
- lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS;
- if (lo_water >= bp->rx_ring_size)
- lo_water = 0;
-
- hi_water = bp->rx_ring_size / 4;
-
- if (hi_water <= lo_water)
- lo_water = 0;
-
- hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE;
- lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE;
+ if (bp->flow_ctrl & FLOW_CTRL_TX)
+ val |= BNX2_L2CTX_FLOW_CTRL_ENABLE;
- if (hi_water > 0xf)
- hi_water = 0xf;
- else if (hi_water == 0)
- lo_water = 0;
- val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT);
- }
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
}
@@ -1127,19 +1295,19 @@ bnx2_init_all_rx_contexts(struct bnx2 *bp)
}
}
-static int
+static void
bnx2_set_mac_link(struct bnx2 *bp)
{
u32 val;
- REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620);
+ BNX2_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620);
if (bp->link_up && (bp->line_speed == SPEED_1000) &&
(bp->duplex == DUPLEX_HALF)) {
- REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff);
+ BNX2_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff);
}
/* Configure the EMAC mode register. */
- val = REG_RD(bp, BNX2_EMAC_MODE);
+ val = BNX2_RD(bp, BNX2_EMAC_MODE);
val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
@@ -1148,7 +1316,7 @@ bnx2_set_mac_link(struct bnx2 *bp)
if (bp->link_up) {
switch (bp->line_speed) {
case SPEED_10:
- if (CHIP_NUM(bp) != CHIP_NUM_5706) {
+ if (BNX2_CHIP(bp) != BNX2_CHIP_5706) {
val |= BNX2_EMAC_MODE_PORT_MII_10M;
break;
}
@@ -1171,37 +1339,34 @@ bnx2_set_mac_link(struct bnx2 *bp)
/* Set the MAC to operate in the appropriate duplex mode. */
if (bp->duplex == DUPLEX_HALF)
val |= BNX2_EMAC_MODE_HALF_DUPLEX;
- REG_WR(bp, BNX2_EMAC_MODE, val);
+ BNX2_WR(bp, BNX2_EMAC_MODE, val);
/* Enable/disable rx PAUSE. */
bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN;
if (bp->flow_ctrl & FLOW_CTRL_RX)
bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN;
- REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode);
+ BNX2_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode);
/* Enable/disable tx PAUSE. */
- val = REG_RD(bp, BNX2_EMAC_TX_MODE);
+ val = BNX2_RD(bp, BNX2_EMAC_TX_MODE);
val &= ~BNX2_EMAC_TX_MODE_FLOW_EN;
if (bp->flow_ctrl & FLOW_CTRL_TX)
val |= BNX2_EMAC_TX_MODE_FLOW_EN;
- REG_WR(bp, BNX2_EMAC_TX_MODE, val);
+ BNX2_WR(bp, BNX2_EMAC_TX_MODE, val);
/* Acknowledge the interrupt. */
- REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
+ BNX2_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- bnx2_init_all_rx_contexts(bp);
-
- return 0;
+ bnx2_init_all_rx_contexts(bp);
}
static void
bnx2_enable_bmsr1(struct bnx2 *bp)
{
if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
- (CHIP_NUM(bp) == CHIP_NUM_5709))
+ (BNX2_CHIP(bp) == BNX2_CHIP_5709))
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_GP_STATUS);
}
@@ -1210,7 +1375,7 @@ static void
bnx2_disable_bmsr1(struct bnx2 *bp)
{
if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
- (CHIP_NUM(bp) == CHIP_NUM_5709))
+ (BNX2_CHIP(bp) == BNX2_CHIP_5709))
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
}
@@ -1227,7 +1392,7 @@ bnx2_test_and_enable_2g5(struct bnx2 *bp)
if (bp->autoneg & AUTONEG_SPEED)
bp->advertising |= ADVERTISED_2500baseX_Full;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_OVER1G);
bnx2_read_phy(bp, bp->mii_up1, &up1);
@@ -1237,7 +1402,7 @@ bnx2_test_and_enable_2g5(struct bnx2 *bp)
ret = 0;
}
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
@@ -1253,7 +1418,7 @@ bnx2_test_and_disable_2g5(struct bnx2 *bp)
if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
return 0;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_OVER1G);
bnx2_read_phy(bp, bp->mii_up1, &up1);
@@ -1263,7 +1428,7 @@ bnx2_test_and_disable_2g5(struct bnx2 *bp)
ret = 1;
}
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
@@ -1273,30 +1438,39 @@ bnx2_test_and_disable_2g5(struct bnx2 *bp)
static void
bnx2_enable_forced_2g5(struct bnx2 *bp)
{
- u32 bmcr;
+ u32 uninitialized_var(bmcr);
+ int err;
if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
return;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
u32 val;
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_SERDES_DIG);
- bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_MISC1, &val);
- val &= ~MII_BNX2_SD_MISC1_FORCE_MSK;
- val |= MII_BNX2_SD_MISC1_FORCE | MII_BNX2_SD_MISC1_FORCE_2_5G;
- bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_MISC1, val);
+ if (!bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_MISC1, &val)) {
+ val &= ~MII_BNX2_SD_MISC1_FORCE_MSK;
+ val |= MII_BNX2_SD_MISC1_FORCE |
+ MII_BNX2_SD_MISC1_FORCE_2_5G;
+ bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_MISC1, val);
+ }
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
- bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
+ err = bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
- } else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
- bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
- bmcr |= BCM5708S_BMCR_FORCE_2500;
+ } else if (BNX2_CHIP(bp) == BNX2_CHIP_5708) {
+ err = bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
+ if (!err)
+ bmcr |= BCM5708S_BMCR_FORCE_2500;
+ } else {
+ return;
}
+ if (err)
+ return;
+
if (bp->autoneg & AUTONEG_SPEED) {
bmcr &= ~BMCR_ANENABLE;
if (bp->req_duplex == DUPLEX_FULL)
@@ -1308,29 +1482,37 @@ bnx2_enable_forced_2g5(struct bnx2 *bp)
static void
bnx2_disable_forced_2g5(struct bnx2 *bp)
{
- u32 bmcr;
+ u32 uninitialized_var(bmcr);
+ int err;
if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
return;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
u32 val;
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_SERDES_DIG);
- bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_MISC1, &val);
- val &= ~MII_BNX2_SD_MISC1_FORCE;
- bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_MISC1, val);
+ if (!bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_MISC1, &val)) {
+ val &= ~MII_BNX2_SD_MISC1_FORCE;
+ bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_MISC1, val);
+ }
bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
- bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
+ err = bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
- } else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
- bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
- bmcr &= ~BCM5708S_BMCR_FORCE_2500;
+ } else if (BNX2_CHIP(bp) == BNX2_CHIP_5708) {
+ err = bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
+ if (!err)
+ bmcr &= ~BCM5708S_BMCR_FORCE_2500;
+ } else {
+ return;
}
+ if (err)
+ return;
+
if (bp->autoneg & AUTONEG_SPEED)
bmcr |= BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_ANRESTART;
bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
@@ -1371,14 +1553,14 @@ bnx2_set_link(struct bnx2 *bp)
bnx2_disable_bmsr1(bp);
if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
- (CHIP_NUM(bp) == CHIP_NUM_5706)) {
+ (BNX2_CHIP(bp) == BNX2_CHIP_5706)) {
u32 val, an_dbg;
if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
bnx2_5706s_force_link_dn(bp, 0);
bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
}
- val = REG_RD(bp, BNX2_EMAC_STATUS);
+ val = BNX2_RD(bp, BNX2_EMAC_STATUS);
bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
@@ -1395,11 +1577,11 @@ bnx2_set_link(struct bnx2 *bp)
bp->link_up = 1;
if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
- if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5706)
bnx2_5706s_linkup(bp);
- else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+ else if (BNX2_CHIP(bp) == BNX2_CHIP_5708)
bnx2_5708s_linkup(bp);
- else if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ else if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
bnx2_5709s_linkup(bp);
}
else {
@@ -1495,6 +1677,8 @@ static int bnx2_fw_sync(struct bnx2 *, u32, int, int);
static int
bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 speed_arg = 0, pause_adv;
@@ -1552,12 +1736,14 @@ bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
static int
bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 adv, bmcr;
u32 new_adv = 0;
if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
- return (bnx2_setup_remote_phy(bp, port));
+ return bnx2_setup_remote_phy(bp, port);
if (!(bp->autoneg & AUTONEG_SPEED)) {
u32 new_bmcr;
@@ -1577,7 +1763,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
new_bmcr = bmcr & ~BMCR_ANENABLE;
new_bmcr |= BMCR_SPEED1000;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
if (bp->req_line_speed == SPEED_2500)
bnx2_enable_forced_2g5(bp);
else if (bp->req_line_speed == SPEED_1000) {
@@ -1585,7 +1771,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
new_bmcr &= ~0x2000;
}
- } else if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ } else if (BNX2_CHIP(bp) == BNX2_CHIP_5708) {
if (bp->req_line_speed == SPEED_2500)
new_bmcr |= BCM5708S_BMCR_FORCE_2500;
else
@@ -1654,7 +1840,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
* exchanging base pages plus 3 next pages and
* normally completes in about 120 msec.
*/
- bp->current_interval = SERDES_AN_TIMEOUT;
+ bp->current_interval = BNX2_SERDES_AN_TIMEOUT;
bp->serdes_an_pending = 1;
mod_timer(&bp->timer, jiffies + bp->current_interval);
} else {
@@ -1762,8 +1948,8 @@ bnx2_send_heart_beat(struct bnx2 *bp)
spin_lock(&bp->indirect_lock);
msg = (u32) (++bp->fw_drv_pulse_wr_seq & BNX2_DRV_PULSE_SEQ_MASK);
addr = bp->shmem_base + BNX2_DRV_PULSE_MB;
- REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, addr);
- REG_WR(bp, BNX2_PCICFG_REG_WINDOW, msg);
+ BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, addr);
+ BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW, msg);
spin_unlock(&bp->indirect_lock);
}
@@ -1792,22 +1978,26 @@ bnx2_remote_phy_event(struct bnx2 *bp)
switch (speed) {
case BNX2_LINK_STATUS_10HALF:
bp->duplex = DUPLEX_HALF;
+ /* fall through */
case BNX2_LINK_STATUS_10FULL:
bp->line_speed = SPEED_10;
break;
case BNX2_LINK_STATUS_100HALF:
bp->duplex = DUPLEX_HALF;
+ /* fall through */
case BNX2_LINK_STATUS_100BASE_T4:
case BNX2_LINK_STATUS_100FULL:
bp->line_speed = SPEED_100;
break;
case BNX2_LINK_STATUS_1000HALF:
bp->duplex = DUPLEX_HALF;
+ /* fall through */
case BNX2_LINK_STATUS_1000FULL:
bp->line_speed = SPEED_1000;
break;
case BNX2_LINK_STATUS_2500HALF:
bp->duplex = DUPLEX_HALF;
+ /* fall through */
case BNX2_LINK_STATUS_2500FULL:
bp->line_speed = SPEED_2500;
break;
@@ -1864,45 +2054,36 @@ bnx2_set_remote_link(struct bnx2 *bp)
static int
bnx2_setup_copper_phy(struct bnx2 *bp)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
- u32 bmcr;
+ u32 bmcr, adv_reg, new_adv = 0;
u32 new_bmcr;
bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
+ bnx2_read_phy(bp, bp->mii_adv, &adv_reg);
+ adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
+ ADVERTISE_PAUSE_ASYM);
+
+ new_adv = ADVERTISE_CSMA | ethtool_adv_to_mii_adv_t(bp->advertising);
+
if (bp->autoneg & AUTONEG_SPEED) {
- u32 adv_reg, adv1000_reg;
- u32 new_adv_reg = 0;
- u32 new_adv1000_reg = 0;
+ u32 adv1000_reg;
+ u32 new_adv1000 = 0;
- bnx2_read_phy(bp, bp->mii_adv, &adv_reg);
- adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
- ADVERTISE_PAUSE_ASYM);
+ new_adv |= bnx2_phy_get_pause_adv(bp);
bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg);
adv1000_reg &= PHY_ALL_1000_SPEED;
- if (bp->advertising & ADVERTISED_10baseT_Half)
- new_adv_reg |= ADVERTISE_10HALF;
- if (bp->advertising & ADVERTISED_10baseT_Full)
- new_adv_reg |= ADVERTISE_10FULL;
- if (bp->advertising & ADVERTISED_100baseT_Half)
- new_adv_reg |= ADVERTISE_100HALF;
- if (bp->advertising & ADVERTISED_100baseT_Full)
- new_adv_reg |= ADVERTISE_100FULL;
- if (bp->advertising & ADVERTISED_1000baseT_Full)
- new_adv1000_reg |= ADVERTISE_1000FULL;
-
- new_adv_reg |= ADVERTISE_CSMA;
-
- new_adv_reg |= bnx2_phy_get_pause_adv(bp);
-
- if ((adv1000_reg != new_adv1000_reg) ||
- (adv_reg != new_adv_reg) ||
+ new_adv1000 |= ethtool_adv_to_mii_ctrl1000_t(bp->advertising);
+ if ((adv1000_reg != new_adv1000) ||
+ (adv_reg != new_adv) ||
((bmcr & BMCR_ANENABLE) == 0)) {
- bnx2_write_phy(bp, bp->mii_adv, new_adv_reg);
- bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg);
+ bnx2_write_phy(bp, bp->mii_adv, new_adv);
+ bnx2_write_phy(bp, MII_CTRL1000, new_adv1000);
bnx2_write_phy(bp, bp->mii_bmcr, BMCR_ANRESTART |
BMCR_ANENABLE);
}
@@ -1916,6 +2097,10 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
return 0;
}
+ /* advertise nothing when forcing speed */
+ if (adv_reg != new_adv)
+ bnx2_write_phy(bp, bp->mii_adv, new_adv);
+
new_bmcr = 0;
if (bp->req_line_speed == SPEED_100) {
new_bmcr |= BMCR_SPEED100;
@@ -1961,15 +2146,17 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
static int
bnx2_setup_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
if (bp->loopback == MAC_LOOPBACK)
return 0;
if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
- return (bnx2_setup_serdes_phy(bp, port));
+ return bnx2_setup_serdes_phy(bp, port);
}
else {
- return (bnx2_setup_copper_phy(bp));
+ return bnx2_setup_copper_phy(bp);
}
}
@@ -2051,9 +2238,9 @@ bnx2_init_5708s_phy(struct bnx2 *bp, int reset_phy)
bnx2_write_phy(bp, BCM5708S_UP1, val);
}
- if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
- (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
- (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
+ if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_A0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_B0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_B1)) {
/* increase tx signal amplitude */
bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
BCM5708S_BLK_ADDR_TX_MISC);
@@ -2089,8 +2276,8 @@ bnx2_init_5706s_phy(struct bnx2 *bp, int reset_phy)
bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
- if (CHIP_NUM(bp) == CHIP_NUM_5706)
- REG_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300);
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5706)
+ BNX2_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300);
if (bp->dev->mtu > 1500) {
u32 val;
@@ -2165,15 +2352,23 @@ bnx2_init_copper_phy(struct bnx2 *bp, int reset_phy)
}
/* ethernet@wirespeed */
- bnx2_write_phy(bp, 0x18, 0x7007);
- bnx2_read_phy(bp, 0x18, &val);
- bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
+ bnx2_write_phy(bp, MII_BNX2_AUX_CTL, AUX_CTL_MISC_CTL);
+ bnx2_read_phy(bp, MII_BNX2_AUX_CTL, &val);
+ val |= AUX_CTL_MISC_CTL_WR | AUX_CTL_MISC_CTL_WIRESPEED;
+
+ /* auto-mdix */
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
+ val |= AUX_CTL_MISC_CTL_AUTOMDIX;
+
+ bnx2_write_phy(bp, MII_BNX2_AUX_CTL, val);
return 0;
}
static int
bnx2_init_phy(struct bnx2 *bp, int reset_phy)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 val;
int rc = 0;
@@ -2187,7 +2382,7 @@ bnx2_init_phy(struct bnx2 *bp, int reset_phy)
bp->mii_adv = MII_ADVERTISE;
bp->mii_lpa = MII_LPA;
- REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
+ BNX2_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
goto setup_phy;
@@ -2198,11 +2393,11 @@ bnx2_init_phy(struct bnx2 *bp, int reset_phy)
bp->phy_id |= val & 0xffff;
if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
- if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5706)
rc = bnx2_init_5706s_phy(bp, reset_phy);
- else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+ else if (BNX2_CHIP(bp) == BNX2_CHIP_5708)
rc = bnx2_init_5708s_phy(bp, reset_phy);
- else if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ else if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
rc = bnx2_init_5709s_phy(bp, reset_phy);
}
else {
@@ -2221,10 +2416,10 @@ bnx2_set_mac_loopback(struct bnx2 *bp)
{
u32 mac_mode;
- mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
+ mac_mode = BNX2_RD(bp, BNX2_EMAC_MODE);
mac_mode &= ~BNX2_EMAC_MODE_PORT;
mac_mode |= BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK;
- REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
+ BNX2_WR(bp, BNX2_EMAC_MODE, mac_mode);
bp->link_up = 1;
return 0;
}
@@ -2250,17 +2445,60 @@ bnx2_set_phy_loopback(struct bnx2 *bp)
msleep(100);
}
- mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
+ mac_mode = BNX2_RD(bp, BNX2_EMAC_MODE);
mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
BNX2_EMAC_MODE_25G_MODE);
mac_mode |= BNX2_EMAC_MODE_PORT_GMII;
- REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
+ BNX2_WR(bp, BNX2_EMAC_MODE, mac_mode);
bp->link_up = 1;
return 0;
}
+static void
+bnx2_dump_mcp_state(struct bnx2 *bp)
+{
+ struct net_device *dev = bp->dev;
+ u32 mcp_p0, mcp_p1;
+
+ netdev_err(dev, "<--- start MCP states dump --->\n");
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ mcp_p0 = BNX2_MCP_STATE_P0;
+ mcp_p1 = BNX2_MCP_STATE_P1;
+ } else {
+ mcp_p0 = BNX2_MCP_STATE_P0_5708;
+ mcp_p1 = BNX2_MCP_STATE_P1_5708;
+ }
+ netdev_err(dev, "DEBUG: MCP_STATE_P0[%08x] MCP_STATE_P1[%08x]\n",
+ bnx2_reg_rd_ind(bp, mcp_p0), bnx2_reg_rd_ind(bp, mcp_p1));
+ netdev_err(dev, "DEBUG: MCP mode[%08x] state[%08x] evt_mask[%08x]\n",
+ bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_MODE),
+ bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_STATE),
+ bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_EVENT_MASK));
+ netdev_err(dev, "DEBUG: pc[%08x] pc[%08x] instr[%08x]\n",
+ bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_PROGRAM_COUNTER),
+ bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_PROGRAM_COUNTER),
+ bnx2_reg_rd_ind(bp, BNX2_MCP_CPU_INSTRUCTION));
+ netdev_err(dev, "DEBUG: shmem states:\n");
+ netdev_err(dev, "DEBUG: drv_mb[%08x] fw_mb[%08x] link_status[%08x]",
+ bnx2_shmem_rd(bp, BNX2_DRV_MB),
+ bnx2_shmem_rd(bp, BNX2_FW_MB),
+ bnx2_shmem_rd(bp, BNX2_LINK_STATUS));
+ pr_cont(" drv_pulse_mb[%08x]\n", bnx2_shmem_rd(bp, BNX2_DRV_PULSE_MB));
+ netdev_err(dev, "DEBUG: dev_info_signature[%08x] reset_type[%08x]",
+ bnx2_shmem_rd(bp, BNX2_DEV_INFO_SIGNATURE),
+ bnx2_shmem_rd(bp, BNX2_BC_STATE_RESET_TYPE));
+ pr_cont(" condition[%08x]\n",
+ bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION));
+ DP_SHMEM_LINE(bp, BNX2_BC_RESET_TYPE);
+ DP_SHMEM_LINE(bp, 0x3cc);
+ DP_SHMEM_LINE(bp, 0x3dc);
+ DP_SHMEM_LINE(bp, 0x3ec);
+ netdev_err(dev, "DEBUG: 0x3fc[%08x]\n", bnx2_shmem_rd(bp, 0x3fc));
+ netdev_err(dev, "<--- end MCP states dump --->\n");
+}
+
static int
bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
{
@@ -2269,6 +2507,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
bp->fw_wr_seq++;
msg_data |= bp->fw_wr_seq;
+ bp->fw_last_msg = msg_data;
bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
@@ -2276,7 +2515,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
return 0;
/* wait for an acknowledgement. */
- for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) {
+ for (i = 0; i < (BNX2_FW_ACK_TIME_OUT_MS / 10); i++) {
msleep(10);
val = bnx2_shmem_rd(bp, BNX2_FW_MB);
@@ -2289,14 +2528,14 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
/* If we timed out, inform the firmware that this is the case. */
if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) {
- if (!silent)
- printk(KERN_ERR PFX "fw sync timeout, reset code = "
- "%x\n", msg_data);
-
msg_data &= ~BNX2_DRV_MSG_CODE;
msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data);
+ if (!silent) {
+ pr_err("fw sync timeout, reset code = %x\n", msg_data);
+ bnx2_dump_mcp_state(bp);
+ }
return -EBUSY;
}
@@ -2314,10 +2553,10 @@ bnx2_init_5709_context(struct bnx2 *bp)
u32 val;
val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12);
- val |= (BCM_PAGE_BITS - 8) << 16;
- REG_WR(bp, BNX2_CTX_COMMAND, val);
+ val |= (BNX2_PAGE_BITS - 8) << 16;
+ BNX2_WR(bp, BNX2_CTX_COMMAND, val);
for (i = 0; i < 10; i++) {
- val = REG_RD(bp, BNX2_CTX_COMMAND);
+ val = BNX2_RD(bp, BNX2_CTX_COMMAND);
if (!(val & BNX2_CTX_COMMAND_MEM_INIT))
break;
udelay(2);
@@ -2329,20 +2568,20 @@ bnx2_init_5709_context(struct bnx2 *bp)
int j;
if (bp->ctx_blk[i])
- memset(bp->ctx_blk[i], 0, BCM_PAGE_SIZE);
+ memset(bp->ctx_blk[i], 0, BNX2_PAGE_SIZE);
else
return -ENOMEM;
- REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0,
- (bp->ctx_blk_mapping[i] & 0xffffffff) |
- BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID);
- REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA1,
- (u64) bp->ctx_blk_mapping[i] >> 32);
- REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL, i |
- BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
+ BNX2_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0,
+ (bp->ctx_blk_mapping[i] & 0xffffffff) |
+ BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID);
+ BNX2_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA1,
+ (u64) bp->ctx_blk_mapping[i] >> 32);
+ BNX2_WR(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL, i |
+ BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
for (j = 0; j < 10; j++) {
- val = REG_RD(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL);
+ val = BNX2_RD(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL);
if (!(val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ))
break;
udelay(5);
@@ -2367,7 +2606,7 @@ bnx2_init_context(struct bnx2 *bp)
vcid--;
- if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+ if (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) {
u32 new_vcid;
vcid_addr = GET_PCID_ADDR(vcid);
@@ -2388,8 +2627,8 @@ bnx2_init_context(struct bnx2 *bp)
vcid_addr += (i << PHY_CTX_SHIFT);
pcid_addr += (i << PHY_CTX_SHIFT);
- REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
- REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+ BNX2_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
+ BNX2_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
/* Zero out the context. */
for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
@@ -2406,13 +2645,10 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
u32 val;
good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL);
- if (good_mbuf == NULL) {
- printk(KERN_ERR PFX "Failed to allocate memory in "
- "bnx2_alloc_bad_rbuf\n");
+ if (good_mbuf == NULL)
return -ENOMEM;
- }
- REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+ BNX2_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
good_mbuf_cnt = 0;
@@ -2457,29 +2693,34 @@ bnx2_set_mac_addr(struct bnx2 *bp, u8 *mac_addr, u32 pos)
val = (mac_addr[0] << 8) | mac_addr[1];
- REG_WR(bp, BNX2_EMAC_MAC_MATCH0 + (pos * 8), val);
+ BNX2_WR(bp, BNX2_EMAC_MAC_MATCH0 + (pos * 8), val);
val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
(mac_addr[4] << 8) | mac_addr[5];
- REG_WR(bp, BNX2_EMAC_MAC_MATCH1 + (pos * 8), val);
+ BNX2_WR(bp, BNX2_EMAC_MAC_MATCH1 + (pos * 8), val);
}
static inline int
-bnx2_alloc_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
+bnx2_alloc_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index, gfp_t gfp)
{
dma_addr_t mapping;
- struct sw_pg *rx_pg = &rxr->rx_pg_ring[index];
- struct rx_bd *rxbd =
- &rxr->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
- struct page *page = alloc_page(GFP_ATOMIC);
+ struct bnx2_sw_pg *rx_pg = &rxr->rx_pg_ring[index];
+ struct bnx2_rx_bd *rxbd =
+ &rxr->rx_pg_desc_ring[BNX2_RX_RING(index)][BNX2_RX_IDX(index)];
+ struct page *page = alloc_page(gfp);
if (!page)
return -ENOMEM;
- mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
+ mapping = dma_map_page(&bp->pdev->dev, page, 0, PAGE_SIZE,
PCI_DMA_FROMDEVICE);
+ if (dma_mapping_error(&bp->pdev->dev, mapping)) {
+ __free_page(page);
+ return -EIO;
+ }
+
rx_pg->page = page;
- pci_unmap_addr_set(rx_pg, mapping, mapping);
+ dma_unmap_addr_set(rx_pg, mapping, mapping);
rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
return 0;
@@ -2488,41 +2729,43 @@ bnx2_alloc_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
static void
bnx2_free_rx_page(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
{
- struct sw_pg *rx_pg = &rxr->rx_pg_ring[index];
+ struct bnx2_sw_pg *rx_pg = &rxr->rx_pg_ring[index];
struct page *page = rx_pg->page;
if (!page)
return;
- pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping), PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(rx_pg, mapping),
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
__free_page(page);
rx_pg->page = NULL;
}
static inline int
-bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index)
+bnx2_alloc_rx_data(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u16 index, gfp_t gfp)
{
- struct sk_buff *skb;
- struct sw_bd *rx_buf = &rxr->rx_buf_ring[index];
+ u8 *data;
+ struct bnx2_sw_bd *rx_buf = &rxr->rx_buf_ring[index];
dma_addr_t mapping;
- struct rx_bd *rxbd = &rxr->rx_desc_ring[RX_RING(index)][RX_IDX(index)];
- unsigned long align;
+ struct bnx2_rx_bd *rxbd =
+ &rxr->rx_desc_ring[BNX2_RX_RING(index)][BNX2_RX_IDX(index)];
- skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
- if (skb == NULL) {
+ data = kmalloc(bp->rx_buf_size, gfp);
+ if (!data)
return -ENOMEM;
- }
-
- if (unlikely((align = (unsigned long) skb->data & (BNX2_RX_ALIGN - 1))))
- skb_reserve(skb, BNX2_RX_ALIGN - align);
- mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
- PCI_DMA_FROMDEVICE);
+ mapping = dma_map_single(&bp->pdev->dev,
+ get_l2_fhdr(data),
+ bp->rx_buf_use_size,
+ PCI_DMA_FROMDEVICE);
+ if (dma_mapping_error(&bp->pdev->dev, mapping)) {
+ kfree(data);
+ return -EIO;
+ }
- rx_buf->skb = skb;
- pci_unmap_addr_set(rx_buf, mapping, mapping);
+ rx_buf->data = data;
+ dma_unmap_addr_set(rx_buf, mapping, mapping);
rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
@@ -2543,9 +2786,9 @@ bnx2_phy_event_is_set(struct bnx2 *bp, struct bnx2_napi *bnapi, u32 event)
old_link_state = sblk->status_attn_bits_ack & event;
if (new_link_state != old_link_state) {
if (new_link_state)
- REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, event);
+ BNX2_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, event);
else
- REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, event);
+ BNX2_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, event);
} else
is_set = 0;
@@ -2574,7 +2817,8 @@ bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
/* Tell compiler that status block fields can change. */
barrier();
cons = *bnapi->hw_tx_cons_ptr;
- if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT))
+ barrier();
+ if (unlikely((cons & BNX2_MAX_TX_DESC_CNT) == BNX2_MAX_TX_DESC_CNT))
cons++;
return cons;
}
@@ -2585,6 +2829,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
u16 hw_cons, sw_cons, sw_ring_cons;
int tx_pkt = 0, index;
+ unsigned int tx_bytes = 0;
struct netdev_queue *txq;
index = (bnapi - bp->bnx2_napi);
@@ -2594,24 +2839,25 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
sw_cons = txr->tx_cons;
while (sw_cons != hw_cons) {
- struct sw_bd *tx_buf;
+ struct bnx2_sw_tx_bd *tx_buf;
struct sk_buff *skb;
int i, last;
- sw_ring_cons = TX_RING_IDX(sw_cons);
+ sw_ring_cons = BNX2_TX_RING_IDX(sw_cons);
tx_buf = &txr->tx_buf_ring[sw_ring_cons];
skb = tx_buf->skb;
+ /* prefetch skb_end_pointer() to speedup skb_shinfo(skb) */
+ prefetch(&skb->end);
+
/* partial BD completions possible with TSO packets */
- if (skb_is_gso(skb)) {
+ if (tx_buf->is_gso) {
u16 last_idx, last_ring_idx;
- last_idx = sw_cons +
- skb_shinfo(skb)->nr_frags + 1;
- last_ring_idx = sw_ring_cons +
- skb_shinfo(skb)->nr_frags + 1;
- if (unlikely(last_ring_idx >= MAX_TX_DESC_CNT)) {
+ last_idx = sw_cons + tx_buf->nr_frags + 1;
+ last_ring_idx = sw_ring_cons + tx_buf->nr_frags + 1;
+ if (unlikely(last_ring_idx >= BNX2_MAX_TX_DESC_CNT)) {
last_idx++;
}
if (((s16) ((s16) last_idx - (s16) hw_cons)) > 0) {
@@ -2619,33 +2865,37 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
}
}
- pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping),
+ dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping),
skb_headlen(skb), PCI_DMA_TODEVICE);
tx_buf->skb = NULL;
- last = skb_shinfo(skb)->nr_frags;
+ last = tx_buf->nr_frags;
for (i = 0; i < last; i++) {
- sw_cons = NEXT_TX_BD(sw_cons);
+ struct bnx2_sw_tx_bd *tx_buf;
+
+ sw_cons = BNX2_NEXT_TX_BD(sw_cons);
- pci_unmap_page(bp->pdev,
- pci_unmap_addr(
- &txr->tx_buf_ring[TX_RING_IDX(sw_cons)],
- mapping),
- skb_shinfo(skb)->frags[i].size,
+ tx_buf = &txr->tx_buf_ring[BNX2_TX_RING_IDX(sw_cons)];
+ dma_unmap_page(&bp->pdev->dev,
+ dma_unmap_addr(tx_buf, mapping),
+ skb_frag_size(&skb_shinfo(skb)->frags[i]),
PCI_DMA_TODEVICE);
}
- sw_cons = NEXT_TX_BD(sw_cons);
+ sw_cons = BNX2_NEXT_TX_BD(sw_cons);
- dev_kfree_skb(skb);
+ tx_bytes += skb->len;
+ dev_kfree_skb_any(skb);
tx_pkt++;
if (tx_pkt == budget)
break;
- hw_cons = bnx2_get_hw_tx_cons(bnapi);
+ if (hw_cons == sw_cons)
+ hw_cons = bnx2_get_hw_tx_cons(bnapi);
}
+ netdev_tx_completed_queue(txq, tx_pkt, tx_bytes);
txr->hw_tx_cons = hw_cons;
txr->tx_cons = sw_cons;
@@ -2672,112 +2922,126 @@ static void
bnx2_reuse_rx_skb_pages(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
struct sk_buff *skb, int count)
{
- struct sw_pg *cons_rx_pg, *prod_rx_pg;
- struct rx_bd *cons_bd, *prod_bd;
- dma_addr_t mapping;
+ struct bnx2_sw_pg *cons_rx_pg, *prod_rx_pg;
+ struct bnx2_rx_bd *cons_bd, *prod_bd;
int i;
- u16 hw_prod = rxr->rx_pg_prod, prod;
+ u16 hw_prod, prod;
u16 cons = rxr->rx_pg_cons;
+ cons_rx_pg = &rxr->rx_pg_ring[cons];
+
+ /* The caller was unable to allocate a new page to replace the
+ * last one in the frags array, so we need to recycle that page
+ * and then free the skb.
+ */
+ if (skb) {
+ struct page *page;
+ struct skb_shared_info *shinfo;
+
+ shinfo = skb_shinfo(skb);
+ shinfo->nr_frags--;
+ page = skb_frag_page(&shinfo->frags[shinfo->nr_frags]);
+ __skb_frag_set_page(&shinfo->frags[shinfo->nr_frags], NULL);
+
+ cons_rx_pg->page = page;
+ dev_kfree_skb(skb);
+ }
+
+ hw_prod = rxr->rx_pg_prod;
+
for (i = 0; i < count; i++) {
- prod = RX_PG_RING_IDX(hw_prod);
+ prod = BNX2_RX_PG_RING_IDX(hw_prod);
prod_rx_pg = &rxr->rx_pg_ring[prod];
cons_rx_pg = &rxr->rx_pg_ring[cons];
- cons_bd = &rxr->rx_pg_desc_ring[RX_RING(cons)][RX_IDX(cons)];
- prod_bd = &rxr->rx_pg_desc_ring[RX_RING(prod)][RX_IDX(prod)];
-
- if (i == 0 && skb) {
- struct page *page;
- struct skb_shared_info *shinfo;
-
- shinfo = skb_shinfo(skb);
- shinfo->nr_frags--;
- page = shinfo->frags[shinfo->nr_frags].page;
- shinfo->frags[shinfo->nr_frags].page = NULL;
- mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
- PCI_DMA_FROMDEVICE);
- cons_rx_pg->page = page;
- pci_unmap_addr_set(cons_rx_pg, mapping, mapping);
- dev_kfree_skb(skb);
- }
+ cons_bd = &rxr->rx_pg_desc_ring[BNX2_RX_RING(cons)]
+ [BNX2_RX_IDX(cons)];
+ prod_bd = &rxr->rx_pg_desc_ring[BNX2_RX_RING(prod)]
+ [BNX2_RX_IDX(prod)];
+
if (prod != cons) {
prod_rx_pg->page = cons_rx_pg->page;
cons_rx_pg->page = NULL;
- pci_unmap_addr_set(prod_rx_pg, mapping,
- pci_unmap_addr(cons_rx_pg, mapping));
+ dma_unmap_addr_set(prod_rx_pg, mapping,
+ dma_unmap_addr(cons_rx_pg, mapping));
prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi;
prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
}
- cons = RX_PG_RING_IDX(NEXT_RX_BD(cons));
- hw_prod = NEXT_RX_BD(hw_prod);
+ cons = BNX2_RX_PG_RING_IDX(BNX2_NEXT_RX_BD(cons));
+ hw_prod = BNX2_NEXT_RX_BD(hw_prod);
}
rxr->rx_pg_prod = hw_prod;
rxr->rx_pg_cons = cons;
}
static inline void
-bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
- struct sk_buff *skb, u16 cons, u16 prod)
+bnx2_reuse_rx_data(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr,
+ u8 *data, u16 cons, u16 prod)
{
- struct sw_bd *cons_rx_buf, *prod_rx_buf;
- struct rx_bd *cons_bd, *prod_bd;
+ struct bnx2_sw_bd *cons_rx_buf, *prod_rx_buf;
+ struct bnx2_rx_bd *cons_bd, *prod_bd;
cons_rx_buf = &rxr->rx_buf_ring[cons];
prod_rx_buf = &rxr->rx_buf_ring[prod];
- pci_dma_sync_single_for_device(bp->pdev,
- pci_unmap_addr(cons_rx_buf, mapping),
+ dma_sync_single_for_device(&bp->pdev->dev,
+ dma_unmap_addr(cons_rx_buf, mapping),
BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
rxr->rx_prod_bseq += bp->rx_buf_use_size;
- prod_rx_buf->skb = skb;
+ prod_rx_buf->data = data;
if (cons == prod)
return;
- pci_unmap_addr_set(prod_rx_buf, mapping,
- pci_unmap_addr(cons_rx_buf, mapping));
+ dma_unmap_addr_set(prod_rx_buf, mapping,
+ dma_unmap_addr(cons_rx_buf, mapping));
- cons_bd = &rxr->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)];
- prod_bd = &rxr->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)];
+ cons_bd = &rxr->rx_desc_ring[BNX2_RX_RING(cons)][BNX2_RX_IDX(cons)];
+ prod_bd = &rxr->rx_desc_ring[BNX2_RX_RING(prod)][BNX2_RX_IDX(prod)];
prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi;
prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
}
-static int
-bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb,
+static struct sk_buff *
+bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, u8 *data,
unsigned int len, unsigned int hdr_len, dma_addr_t dma_addr,
u32 ring_idx)
{
int err;
u16 prod = ring_idx & 0xffff;
+ struct sk_buff *skb;
- err = bnx2_alloc_rx_skb(bp, rxr, prod);
+ err = bnx2_alloc_rx_data(bp, rxr, prod, GFP_ATOMIC);
if (unlikely(err)) {
- bnx2_reuse_rx_skb(bp, rxr, skb, (u16) (ring_idx >> 16), prod);
+ bnx2_reuse_rx_data(bp, rxr, data, (u16) (ring_idx >> 16), prod);
+error:
if (hdr_len) {
unsigned int raw_len = len + 4;
int pages = PAGE_ALIGN(raw_len - hdr_len) >> PAGE_SHIFT;
bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages);
}
- return err;
+ return NULL;
}
- skb_reserve(skb, BNX2_RX_OFFSET);
- pci_unmap_single(bp->pdev, dma_addr, bp->rx_buf_use_size,
+ dma_unmap_single(&bp->pdev->dev, dma_addr, bp->rx_buf_use_size,
PCI_DMA_FROMDEVICE);
-
+ skb = build_skb(data, 0);
+ if (!skb) {
+ kfree(data);
+ goto error;
+ }
+ skb_reserve(skb, ((u8 *)get_l2_fhdr(data) - data) + BNX2_RX_OFFSET);
if (hdr_len == 0) {
skb_put(skb, len);
- return 0;
+ return skb;
} else {
unsigned int i, frag_len, frag_size, pages;
- struct sw_pg *rx_pg;
+ struct bnx2_sw_pg *rx_pg;
u16 pg_cons = rxr->rx_pg_cons;
u16 pg_prod = rxr->rx_pg_prod;
@@ -2786,6 +3050,8 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb,
skb_put(skb, hdr_len);
for (i = 0; i < pages; i++) {
+ dma_addr_t mapping_old;
+
frag_len = min(frag_size, (unsigned int) PAGE_SIZE);
if (unlikely(frag_len <= 4)) {
unsigned int tail = 4 - frag_len;
@@ -2800,17 +3066,17 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb,
} else {
skb_frag_t *frag =
&skb_shinfo(skb)->frags[i - 1];
- frag->size -= tail;
+ skb_frag_size_sub(frag, tail);
skb->data_len -= tail;
- skb->truesize -= tail;
}
- return 0;
+ return skb;
}
rx_pg = &rxr->rx_pg_ring[pg_cons];
- pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping),
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
-
+ /* Don't unmap yet. If we're unable to allocate a new
+ * page, we need to recycle the page and the DMA addr.
+ */
+ mapping_old = dma_unmap_addr(rx_pg, mapping);
if (i == pages - 1)
frag_len -= 4;
@@ -2818,27 +3084,31 @@ bnx2_rx_skb(struct bnx2 *bp, struct bnx2_rx_ring_info *rxr, struct sk_buff *skb,
rx_pg->page = NULL;
err = bnx2_alloc_rx_page(bp, rxr,
- RX_PG_RING_IDX(pg_prod));
+ BNX2_RX_PG_RING_IDX(pg_prod),
+ GFP_ATOMIC);
if (unlikely(err)) {
rxr->rx_pg_cons = pg_cons;
rxr->rx_pg_prod = pg_prod;
bnx2_reuse_rx_skb_pages(bp, rxr, skb,
pages - i);
- return err;
+ return NULL;
}
+ dma_unmap_page(&bp->pdev->dev, mapping_old,
+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
+
frag_size -= frag_len;
skb->data_len += frag_len;
- skb->truesize += frag_len;
+ skb->truesize += PAGE_SIZE;
skb->len += frag_len;
- pg_prod = NEXT_RX_BD(pg_prod);
- pg_cons = RX_PG_RING_IDX(NEXT_RX_BD(pg_cons));
+ pg_prod = BNX2_NEXT_RX_BD(pg_prod);
+ pg_cons = BNX2_RX_PG_RING_IDX(BNX2_NEXT_RX_BD(pg_cons));
}
rxr->rx_pg_prod = pg_prod;
rxr->rx_pg_cons = pg_cons;
}
- return 0;
+ return skb;
}
static inline u16
@@ -2849,7 +3119,8 @@ bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi)
/* Tell compiler that status block fields can change. */
barrier();
cons = *bnapi->hw_rx_cons_ptr;
- if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT))
+ barrier();
+ if (unlikely((cons & BNX2_MAX_RX_DESC_CNT) == BNX2_MAX_RX_DESC_CNT))
cons++;
return cons;
}
@@ -2862,6 +3133,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
struct l2_fhdr *rx_hdr;
int rx_pkt = 0, pg_ring_used = 0;
+ if (budget <= 0)
+ return rx_pkt;
+
hw_cons = bnx2_get_hw_rx_cons(bnapi);
sw_cons = rxr->rx_cons;
sw_prod = rxr->rx_prod;
@@ -2873,40 +3147,35 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
while (sw_cons != hw_cons) {
unsigned int len, hdr_len;
u32 status;
- struct sw_bd *rx_buf;
+ struct bnx2_sw_bd *rx_buf, *next_rx_buf;
struct sk_buff *skb;
dma_addr_t dma_addr;
- u16 vtag = 0;
- int hw_vlan __maybe_unused = 0;
+ u8 *data;
+ u16 next_ring_idx;
- sw_ring_cons = RX_RING_IDX(sw_cons);
- sw_ring_prod = RX_RING_IDX(sw_prod);
+ sw_ring_cons = BNX2_RX_RING_IDX(sw_cons);
+ sw_ring_prod = BNX2_RX_RING_IDX(sw_prod);
rx_buf = &rxr->rx_buf_ring[sw_ring_cons];
- skb = rx_buf->skb;
+ data = rx_buf->data;
+ rx_buf->data = NULL;
- rx_buf->skb = NULL;
+ rx_hdr = get_l2_fhdr(data);
+ prefetch(rx_hdr);
- dma_addr = pci_unmap_addr(rx_buf, mapping);
+ dma_addr = dma_unmap_addr(rx_buf, mapping);
- pci_dma_sync_single_for_cpu(bp->pdev, dma_addr,
+ dma_sync_single_for_cpu(&bp->pdev->dev, dma_addr,
BNX2_RX_OFFSET + BNX2_RX_COPY_THRESH,
PCI_DMA_FROMDEVICE);
- rx_hdr = (struct l2_fhdr *) skb->data;
- len = rx_hdr->l2_fhdr_pkt_len;
+ next_ring_idx = BNX2_RX_RING_IDX(BNX2_NEXT_RX_BD(sw_cons));
+ next_rx_buf = &rxr->rx_buf_ring[next_ring_idx];
+ prefetch(get_l2_fhdr(next_rx_buf->data));
- if ((status = rx_hdr->l2_fhdr_status) &
- (L2_FHDR_ERRORS_BAD_CRC |
- L2_FHDR_ERRORS_PHY_DECODE |
- L2_FHDR_ERRORS_ALIGNMENT |
- L2_FHDR_ERRORS_TOO_SHORT |
- L2_FHDR_ERRORS_GIANT_FRAME)) {
+ len = rx_hdr->l2_fhdr_pkt_len;
+ status = rx_hdr->l2_fhdr_status;
- bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
- sw_ring_prod);
- goto next_rx;
- }
hdr_len = 0;
if (status & L2_FHDR_STATUS_SPLIT) {
hdr_len = rx_hdr->l2_fhdr_ip_xsum;
@@ -2916,51 +3185,53 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
pg_ring_used = 1;
}
+ if (unlikely(status & (L2_FHDR_ERRORS_BAD_CRC |
+ L2_FHDR_ERRORS_PHY_DECODE |
+ L2_FHDR_ERRORS_ALIGNMENT |
+ L2_FHDR_ERRORS_TOO_SHORT |
+ L2_FHDR_ERRORS_GIANT_FRAME))) {
+
+ bnx2_reuse_rx_data(bp, rxr, data, sw_ring_cons,
+ sw_ring_prod);
+ if (pg_ring_used) {
+ int pages;
+
+ pages = PAGE_ALIGN(len - hdr_len) >> PAGE_SHIFT;
+
+ bnx2_reuse_rx_skb_pages(bp, rxr, NULL, pages);
+ }
+ goto next_rx;
+ }
+
len -= 4;
if (len <= bp->rx_copy_thresh) {
- struct sk_buff *new_skb;
-
- new_skb = netdev_alloc_skb(bp->dev, len + 6);
- if (new_skb == NULL) {
- bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
+ skb = netdev_alloc_skb(bp->dev, len + 6);
+ if (skb == NULL) {
+ bnx2_reuse_rx_data(bp, rxr, data, sw_ring_cons,
sw_ring_prod);
goto next_rx;
}
/* aligned copy */
- skb_copy_from_linear_data_offset(skb,
- BNX2_RX_OFFSET - 6,
- new_skb->data, len + 6);
- skb_reserve(new_skb, 6);
- skb_put(new_skb, len);
+ memcpy(skb->data,
+ (u8 *)rx_hdr + BNX2_RX_OFFSET - 6,
+ len + 6);
+ skb_reserve(skb, 6);
+ skb_put(skb, len);
- bnx2_reuse_rx_skb(bp, rxr, skb,
+ bnx2_reuse_rx_data(bp, rxr, data,
sw_ring_cons, sw_ring_prod);
- skb = new_skb;
- } else if (unlikely(bnx2_rx_skb(bp, rxr, skb, len, hdr_len,
- dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
- goto next_rx;
-
- if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
- !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
- vtag = rx_hdr->l2_fhdr_vlan_tag;
-#ifdef BCM_VLAN
- if (bp->vlgrp)
- hw_vlan = 1;
- else
-#endif
- {
- struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
- __skb_push(skb, 4);
-
- memmove(ve, skb->data + 4, ETH_ALEN * 2);
- ve->h_vlan_proto = htons(ETH_P_8021Q);
- ve->h_vlan_TCI = htons(vtag);
- len += 4;
- }
+ } else {
+ skb = bnx2_rx_skb(bp, rxr, data, len, hdr_len, dma_addr,
+ (sw_ring_cons << 16) | sw_ring_prod);
+ if (!skb)
+ goto next_rx;
}
+ if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
+ !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG))
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), rx_hdr->l2_fhdr_vlan_tag);
skb->protocol = eth_type_trans(skb, bp->dev);
@@ -2972,8 +3243,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
}
- skb->ip_summed = CHECKSUM_NONE;
- if (bp->rx_csum &&
+ skb_checksum_none_assert(skb);
+ if ((bp->dev->features & NETIF_F_RXCSUM) &&
(status & (L2_FHDR_STATUS_TCP_SEGMENT |
L2_FHDR_STATUS_UDP_DATAGRAM))) {
@@ -2981,20 +3252,19 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
L2_FHDR_ERRORS_UDP_XSUM)) == 0))
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
+ if ((bp->dev->features & NETIF_F_RXHASH) &&
+ ((status & L2_FHDR_STATUS_USE_RXHASH) ==
+ L2_FHDR_STATUS_USE_RXHASH))
+ skb_set_hash(skb, rx_hdr->l2_fhdr_hash,
+ PKT_HASH_TYPE_L3);
-#ifdef BCM_VLAN
- if (hw_vlan)
- vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
- else
-#endif
- netif_receive_skb(skb);
-
- bp->dev->last_rx = jiffies;
+ skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]);
+ napi_gro_receive(&bnapi->napi, skb);
rx_pkt++;
next_rx:
- sw_cons = NEXT_RX_BD(sw_cons);
- sw_prod = NEXT_RX_BD(sw_prod);
+ sw_cons = BNX2_NEXT_RX_BD(sw_cons);
+ sw_prod = BNX2_NEXT_RX_BD(sw_prod);
if ((rx_pkt == budget))
break;
@@ -3009,11 +3279,11 @@ next_rx:
rxr->rx_prod = sw_prod;
if (pg_ring_used)
- REG_WR16(bp, rxr->rx_pg_bidx_addr, rxr->rx_pg_prod);
+ BNX2_WR16(bp, rxr->rx_pg_bidx_addr, rxr->rx_pg_prod);
- REG_WR16(bp, rxr->rx_bidx_addr, sw_prod);
+ BNX2_WR16(bp, rxr->rx_bidx_addr, sw_prod);
- REG_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
+ BNX2_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
mmiowb();
@@ -3029,10 +3299,9 @@ bnx2_msi(int irq, void *dev_instance)
{
struct bnx2_napi *bnapi = dev_instance;
struct bnx2 *bp = bnapi->bp;
- struct net_device *dev = bp->dev;
prefetch(bnapi->status_blk.msi);
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -3040,7 +3309,7 @@ bnx2_msi(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- netif_rx_schedule(dev, &bnapi->napi);
+ napi_schedule(&bnapi->napi);
return IRQ_HANDLED;
}
@@ -3050,7 +3319,6 @@ bnx2_msi_1shot(int irq, void *dev_instance)
{
struct bnx2_napi *bnapi = dev_instance;
struct bnx2 *bp = bnapi->bp;
- struct net_device *dev = bp->dev;
prefetch(bnapi->status_blk.msi);
@@ -3058,7 +3326,7 @@ bnx2_msi_1shot(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- netif_rx_schedule(dev, &bnapi->napi);
+ napi_schedule(&bnapi->napi);
return IRQ_HANDLED;
}
@@ -3068,7 +3336,6 @@ bnx2_interrupt(int irq, void *dev_instance)
{
struct bnx2_napi *bnapi = dev_instance;
struct bnx2 *bp = bnapi->bp;
- struct net_device *dev = bp->dev;
struct status_block *sblk = bnapi->status_blk.msi;
/* When using INTx, it is possible for the interrupt to arrive
@@ -3078,26 +3345,26 @@ bnx2_interrupt(int irq, void *dev_instance)
* the status block write.
*/
if ((sblk->status_idx == bnapi->last_status_idx) &&
- (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
+ (BNX2_RD(bp, BNX2_PCICFG_MISC_STATUS) &
BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
return IRQ_NONE;
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
/* Read back to deassert IRQ immediately to avoid too many
* spurious interrupts.
*/
- REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
+ BNX2_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
/* Return here if interrupt is shared and is disabled. */
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- if (netif_rx_schedule_prep(dev, &bnapi->napi)) {
+ if (napi_schedule_prep(&bnapi->napi)) {
bnapi->last_status_idx = sblk->status_idx;
- __netif_rx_schedule(dev, &bnapi->napi);
+ __napi_schedule(&bnapi->napi);
}
return IRQ_HANDLED;
@@ -3126,6 +3393,11 @@ bnx2_has_work(struct bnx2_napi *bnapi)
if (bnx2_has_fast_work(bnapi))
return 1;
+#ifdef BCM_CNIC
+ if (bnapi->cnic_present && (bnapi->cnic_tag != sblk->status_idx))
+ return 1;
+#endif
+
if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) !=
(sblk->status_attn_bits_ack & STATUS_ATTN_EVENTS))
return 1;
@@ -3133,6 +3405,45 @@ bnx2_has_work(struct bnx2_napi *bnapi)
return 0;
}
+static void
+bnx2_chk_missed_msi(struct bnx2 *bp)
+{
+ struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+ u32 msi_ctrl;
+
+ if (bnx2_has_work(bnapi)) {
+ msi_ctrl = BNX2_RD(bp, BNX2_PCICFG_MSI_CONTROL);
+ if (!(msi_ctrl & BNX2_PCICFG_MSI_CONTROL_ENABLE))
+ return;
+
+ if (bnapi->last_status_idx == bp->idle_chk_status_idx) {
+ BNX2_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl &
+ ~BNX2_PCICFG_MSI_CONTROL_ENABLE);
+ BNX2_WR(bp, BNX2_PCICFG_MSI_CONTROL, msi_ctrl);
+ bnx2_msi(bp->irq_tbl[0].vector, bnapi);
+ }
+ }
+
+ bp->idle_chk_status_idx = bnapi->last_status_idx;
+}
+
+#ifdef BCM_CNIC
+static void bnx2_poll_cnic(struct bnx2 *bp, struct bnx2_napi *bnapi)
+{
+ struct cnic_ops *c_ops;
+
+ if (!bnapi->cnic_present)
+ return;
+
+ rcu_read_lock();
+ c_ops = rcu_dereference(bp->cnic_ops);
+ if (c_ops)
+ bnapi->cnic_tag = c_ops->cnic_handler(bp->cnic_data,
+ bnapi->status_blk.msi);
+ rcu_read_unlock();
+}
+#endif
+
static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi)
{
struct status_block *sblk = bnapi->status_blk.msi;
@@ -3147,9 +3458,9 @@ static void bnx2_poll_link(struct bnx2 *bp, struct bnx2_napi *bnapi)
/* This is needed to take care of transient status
* during link changes.
*/
- REG_WR(bp, BNX2_HC_COMMAND,
- bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
- REG_RD(bp, BNX2_HC_COMMAND);
+ BNX2_WR(bp, BNX2_HC_COMMAND,
+ bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
+ BNX2_RD(bp, BNX2_HC_COMMAND);
}
}
@@ -3185,10 +3496,10 @@ static int bnx2_poll_msix(struct napi_struct *napi, int budget)
rmb();
if (likely(!bnx2_has_fast_work(bnapi))) {
- netif_rx_complete(bp->dev, napi);
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
- BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
- bnapi->last_status_idx);
+ napi_complete(napi);
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+ BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ bnapi->last_status_idx);
break;
}
}
@@ -3207,31 +3518,36 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
- if (unlikely(work_done >= budget))
- break;
+#ifdef BCM_CNIC
+ bnx2_poll_cnic(bp, bnapi);
+#endif
/* bnapi->last_status_idx is used below to tell the hw how
* much work has been processed, so we must read it before
* checking for more work.
*/
bnapi->last_status_idx = sblk->status_idx;
+
+ if (unlikely(work_done >= budget))
+ break;
+
rmb();
if (likely(!bnx2_has_work(bnapi))) {
- netif_rx_complete(bp->dev, napi);
+ napi_complete(napi);
if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) {
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
- BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
- bnapi->last_status_idx);
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+ BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ bnapi->last_status_idx);
break;
}
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
- BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
- BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
- bnapi->last_status_idx);
-
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
- BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
- bnapi->last_status_idx);
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+ BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
+ bnapi->last_status_idx);
+
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+ BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+ bnapi->last_status_idx);
break;
}
}
@@ -3247,21 +3563,20 @@ bnx2_set_rx_mode(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
u32 rx_mode, sort_mode;
- struct dev_addr_list *uc_ptr;
+ struct netdev_hw_addr *ha;
int i;
+ if (!netif_running(dev))
+ return;
+
spin_lock_bh(&bp->phy_lock);
rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
-#ifdef BCM_VLAN
- if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
- rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
-#else
- if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
+ if (!(dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+ (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
-#endif
if (dev->flags & IFF_PROMISC) {
/* Promiscuous mode. */
rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
@@ -3270,14 +3585,13 @@ bnx2_set_rx_mode(struct net_device *dev)
}
else if (dev->flags & IFF_ALLMULTI) {
for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
- REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
- 0xffffffff);
+ BNX2_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
+ 0xffffffff);
}
sort_mode |= BNX2_RPM_SORT_USER0_MC_EN;
}
else {
/* Accept one or more multicast(s). */
- struct dev_mc_list *mclist;
u32 mc_filter[NUM_MC_HASH_REGISTERS];
u32 regidx;
u32 bit;
@@ -3285,10 +3599,8 @@ bnx2_set_rx_mode(struct net_device *dev)
memset(mc_filter, 0, 4 * NUM_MC_HASH_REGISTERS);
- for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
- i++, mclist = mclist->next) {
-
- crc = ether_crc_le(ETH_ALEN, mclist->dmi_addr);
+ netdev_for_each_mc_addr(ha, dev) {
+ crc = ether_crc_le(ETH_ALEN, ha->addr);
bit = crc & 0xff;
regidx = (bit & 0xe0) >> 5;
bit &= 0x1f;
@@ -3296,89 +3608,223 @@ bnx2_set_rx_mode(struct net_device *dev)
}
for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
- REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
- mc_filter[i]);
+ BNX2_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
+ mc_filter[i]);
}
sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
}
- uc_ptr = NULL;
- if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) {
+ if (netdev_uc_count(dev) > BNX2_MAX_UNICAST_ADDRESSES) {
rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
BNX2_RPM_SORT_USER0_PROM_VLAN;
} else if (!(dev->flags & IFF_PROMISC)) {
- uc_ptr = dev->uc_list;
-
/* Add all entries into to the match filter list */
- for (i = 0; i < dev->uc_count; i++) {
- bnx2_set_mac_addr(bp, uc_ptr->da_addr,
+ i = 0;
+ netdev_for_each_uc_addr(ha, dev) {
+ bnx2_set_mac_addr(bp, ha->addr,
i + BNX2_START_UNICAST_ADDRESS_INDEX);
sort_mode |= (1 <<
(i + BNX2_START_UNICAST_ADDRESS_INDEX));
- uc_ptr = uc_ptr->next;
+ i++;
}
}
if (rx_mode != bp->rx_mode) {
bp->rx_mode = rx_mode;
- REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode);
+ BNX2_WR(bp, BNX2_EMAC_RX_MODE, rx_mode);
}
- REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
- REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
- REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
+ BNX2_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
+ BNX2_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
+ BNX2_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
spin_unlock_bh(&bp->phy_lock);
}
-static void
-load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len,
- u32 rv2p_proc)
+static int
+check_fw_section(const struct firmware *fw,
+ const struct bnx2_fw_file_section *section,
+ u32 alignment, bool non_empty)
{
+ u32 offset = be32_to_cpu(section->offset);
+ u32 len = be32_to_cpu(section->len);
+
+ if ((offset == 0 && len != 0) || offset >= fw->size || offset & 3)
+ return -EINVAL;
+ if ((non_empty && len == 0) || len > fw->size - offset ||
+ len & (alignment - 1))
+ return -EINVAL;
+ return 0;
+}
+
+static int
+check_mips_fw_entry(const struct firmware *fw,
+ const struct bnx2_mips_fw_file_entry *entry)
+{
+ if (check_fw_section(fw, &entry->text, 4, true) ||
+ check_fw_section(fw, &entry->data, 4, false) ||
+ check_fw_section(fw, &entry->rodata, 4, false))
+ return -EINVAL;
+ return 0;
+}
+
+static void bnx2_release_firmware(struct bnx2 *bp)
+{
+ if (bp->rv2p_firmware) {
+ release_firmware(bp->mips_firmware);
+ release_firmware(bp->rv2p_firmware);
+ bp->rv2p_firmware = NULL;
+ }
+}
+
+static int bnx2_request_uncached_firmware(struct bnx2 *bp)
+{
+ const char *mips_fw_file, *rv2p_fw_file;
+ const struct bnx2_mips_fw_file *mips_fw;
+ const struct bnx2_rv2p_fw_file *rv2p_fw;
+ int rc;
+
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ mips_fw_file = FW_MIPS_FILE_09;
+ if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5709_A0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5709_A1))
+ rv2p_fw_file = FW_RV2P_FILE_09_Ax;
+ else
+ rv2p_fw_file = FW_RV2P_FILE_09;
+ } else {
+ mips_fw_file = FW_MIPS_FILE_06;
+ rv2p_fw_file = FW_RV2P_FILE_06;
+ }
+
+ rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev);
+ if (rc) {
+ pr_err("Can't load firmware file \"%s\"\n", mips_fw_file);
+ goto out;
+ }
+
+ rc = request_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev);
+ if (rc) {
+ pr_err("Can't load firmware file \"%s\"\n", rv2p_fw_file);
+ goto err_release_mips_firmware;
+ }
+ mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+ rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+ if (bp->mips_firmware->size < sizeof(*mips_fw) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->com) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->cp) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->rxp) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->tpat) ||
+ check_mips_fw_entry(bp->mips_firmware, &mips_fw->txp)) {
+ pr_err("Firmware file \"%s\" is invalid\n", mips_fw_file);
+ rc = -EINVAL;
+ goto err_release_firmware;
+ }
+ if (bp->rv2p_firmware->size < sizeof(*rv2p_fw) ||
+ check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc1.rv2p, 8, true) ||
+ check_fw_section(bp->rv2p_firmware, &rv2p_fw->proc2.rv2p, 8, true)) {
+ pr_err("Firmware file \"%s\" is invalid\n", rv2p_fw_file);
+ rc = -EINVAL;
+ goto err_release_firmware;
+ }
+out:
+ return rc;
+
+err_release_firmware:
+ release_firmware(bp->rv2p_firmware);
+ bp->rv2p_firmware = NULL;
+err_release_mips_firmware:
+ release_firmware(bp->mips_firmware);
+ goto out;
+}
+
+static int bnx2_request_firmware(struct bnx2 *bp)
+{
+ return bp->rv2p_firmware ? 0 : bnx2_request_uncached_firmware(bp);
+}
+
+static u32
+rv2p_fw_fixup(u32 rv2p_proc, int idx, u32 loc, u32 rv2p_code)
+{
+ switch (idx) {
+ case RV2P_P1_FIXUP_PAGE_SIZE_IDX:
+ rv2p_code &= ~RV2P_BD_PAGE_SIZE_MSK;
+ rv2p_code |= RV2P_BD_PAGE_SIZE;
+ break;
+ }
+ return rv2p_code;
+}
+
+static int
+load_rv2p_fw(struct bnx2 *bp, u32 rv2p_proc,
+ const struct bnx2_rv2p_fw_file_entry *fw_entry)
+{
+ u32 rv2p_code_len, file_offset;
+ __be32 *rv2p_code;
int i;
- u32 val;
+ u32 val, cmd, addr;
+
+ rv2p_code_len = be32_to_cpu(fw_entry->rv2p.len);
+ file_offset = be32_to_cpu(fw_entry->rv2p.offset);
- if (rv2p_proc == RV2P_PROC2 && CHIP_NUM(bp) == CHIP_NUM_5709) {
- val = le32_to_cpu(rv2p_code[XI_RV2P_PROC2_MAX_BD_PAGE_LOC]);
- val &= ~XI_RV2P_PROC2_BD_PAGE_SIZE_MSK;
- val |= XI_RV2P_PROC2_BD_PAGE_SIZE;
- rv2p_code[XI_RV2P_PROC2_MAX_BD_PAGE_LOC] = cpu_to_le32(val);
+ rv2p_code = (__be32 *)(bp->rv2p_firmware->data + file_offset);
+
+ if (rv2p_proc == RV2P_PROC1) {
+ cmd = BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
+ addr = BNX2_RV2P_PROC1_ADDR_CMD;
+ } else {
+ cmd = BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
+ addr = BNX2_RV2P_PROC2_ADDR_CMD;
}
for (i = 0; i < rv2p_code_len; i += 8) {
- REG_WR(bp, BNX2_RV2P_INSTR_HIGH, le32_to_cpu(*rv2p_code));
+ BNX2_WR(bp, BNX2_RV2P_INSTR_HIGH, be32_to_cpu(*rv2p_code));
rv2p_code++;
- REG_WR(bp, BNX2_RV2P_INSTR_LOW, le32_to_cpu(*rv2p_code));
+ BNX2_WR(bp, BNX2_RV2P_INSTR_LOW, be32_to_cpu(*rv2p_code));
rv2p_code++;
- if (rv2p_proc == RV2P_PROC1) {
- val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
- REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val);
- }
- else {
- val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
- REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val);
+ val = (i / 8) | cmd;
+ BNX2_WR(bp, addr, val);
+ }
+
+ rv2p_code = (__be32 *)(bp->rv2p_firmware->data + file_offset);
+ for (i = 0; i < 8; i++) {
+ u32 loc, code;
+
+ loc = be32_to_cpu(fw_entry->fixup[i]);
+ if (loc && ((loc * 4) < rv2p_code_len)) {
+ code = be32_to_cpu(*(rv2p_code + loc - 1));
+ BNX2_WR(bp, BNX2_RV2P_INSTR_HIGH, code);
+ code = be32_to_cpu(*(rv2p_code + loc));
+ code = rv2p_fw_fixup(rv2p_proc, i, loc, code);
+ BNX2_WR(bp, BNX2_RV2P_INSTR_LOW, code);
+
+ val = (loc / 2) | cmd;
+ BNX2_WR(bp, addr, val);
}
}
/* Reset the processor, un-stall is done later. */
if (rv2p_proc == RV2P_PROC1) {
- REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET);
+ BNX2_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET);
}
else {
- REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
+ BNX2_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
}
+
+ return 0;
}
static int
-load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
+load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg,
+ const struct bnx2_mips_fw_file_entry *fw_entry)
{
+ u32 addr, len, file_offset;
+ __be32 *data;
u32 offset;
u32 val;
- int rc;
/* Halt the CPU. */
val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
@@ -3387,64 +3833,52 @@ load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear);
/* Load the Text area. */
- offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
- if (fw->gz_text) {
- int j;
+ addr = be32_to_cpu(fw_entry->text.addr);
+ len = be32_to_cpu(fw_entry->text.len);
+ file_offset = be32_to_cpu(fw_entry->text.offset);
+ data = (__be32 *)(bp->mips_firmware->data + file_offset);
- rc = zlib_inflate_blob(fw->text, FW_BUF_SIZE, fw->gz_text,
- fw->gz_text_len);
- if (rc < 0)
- return rc;
-
- for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, le32_to_cpu(fw->text[j]));
- }
- }
-
- /* Load the Data area. */
- offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
- if (fw->data) {
+ offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+ if (len) {
int j;
- for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, fw->data[j]);
- }
+ for (j = 0; j < (len / 4); j++, offset += 4)
+ bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
}
- /* Load the SBSS area. */
- offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
- if (fw->sbss_len) {
- int j;
-
- for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, 0);
- }
- }
+ /* Load the Data area. */
+ addr = be32_to_cpu(fw_entry->data.addr);
+ len = be32_to_cpu(fw_entry->data.len);
+ file_offset = be32_to_cpu(fw_entry->data.offset);
+ data = (__be32 *)(bp->mips_firmware->data + file_offset);
- /* Load the BSS area. */
- offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
- if (fw->bss_len) {
+ offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+ if (len) {
int j;
- for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, 0);
- }
+ for (j = 0; j < (len / 4); j++, offset += 4)
+ bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
}
/* Load the Read-Only area. */
- offset = cpu_reg->spad_base +
- (fw->rodata_addr - cpu_reg->mips_view_base);
- if (fw->rodata) {
+ addr = be32_to_cpu(fw_entry->rodata.addr);
+ len = be32_to_cpu(fw_entry->rodata.len);
+ file_offset = be32_to_cpu(fw_entry->rodata.offset);
+ data = (__be32 *)(bp->mips_firmware->data + file_offset);
+
+ offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base);
+ if (len) {
int j;
- for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
- bnx2_reg_wr_ind(bp, offset, fw->rodata[j]);
- }
+ for (j = 0; j < (len / 4); j++, offset += 4)
+ bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j]));
}
/* Clear the pre-fetch instruction. */
bnx2_reg_wr_ind(bp, cpu_reg->inst, 0);
- bnx2_reg_wr_ind(bp, cpu_reg->pc, fw->start_addr);
+
+ val = be32_to_cpu(fw_entry->start_addr);
+ bnx2_reg_wr_ind(bp, cpu_reg->pc, val);
/* Start the CPU. */
val = bnx2_reg_rd_ind(bp, cpu_reg->mode);
@@ -3458,228 +3892,186 @@ load_cpu_fw(struct bnx2 *bp, const struct cpu_reg *cpu_reg, struct fw_info *fw)
static int
bnx2_init_cpus(struct bnx2 *bp)
{
- struct fw_info *fw;
- int rc, rv2p_len;
- void *text, *rv2p;
+ const struct bnx2_mips_fw_file *mips_fw =
+ (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+ const struct bnx2_rv2p_fw_file *rv2p_fw =
+ (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+ int rc;
/* Initialize the RV2P processor. */
- text = vmalloc(FW_BUF_SIZE);
- if (!text)
- return -ENOMEM;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- rv2p = bnx2_xi_rv2p_proc1;
- rv2p_len = sizeof(bnx2_xi_rv2p_proc1);
- } else {
- rv2p = bnx2_rv2p_proc1;
- rv2p_len = sizeof(bnx2_rv2p_proc1);
- }
- rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len);
- if (rc < 0)
- goto init_cpu_err;
-
- load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC1);
-
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- rv2p = bnx2_xi_rv2p_proc2;
- rv2p_len = sizeof(bnx2_xi_rv2p_proc2);
- } else {
- rv2p = bnx2_rv2p_proc2;
- rv2p_len = sizeof(bnx2_rv2p_proc2);
- }
- rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len);
- if (rc < 0)
- goto init_cpu_err;
-
- load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC2);
+ load_rv2p_fw(bp, RV2P_PROC1, &rv2p_fw->proc1);
+ load_rv2p_fw(bp, RV2P_PROC2, &rv2p_fw->proc2);
/* Initialize the RX Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_rxp_fw_09;
- else
- fw = &bnx2_rxp_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_rxp, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_rxp, &mips_fw->rxp);
if (rc)
goto init_cpu_err;
/* Initialize the TX Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_txp_fw_09;
- else
- fw = &bnx2_txp_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_txp, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_txp, &mips_fw->txp);
if (rc)
goto init_cpu_err;
/* Initialize the TX Patch-up Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_tpat_fw_09;
- else
- fw = &bnx2_tpat_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_tpat, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_tpat, &mips_fw->tpat);
if (rc)
goto init_cpu_err;
/* Initialize the Completion Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_com_fw_09;
- else
- fw = &bnx2_com_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_com, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_com, &mips_fw->com);
if (rc)
goto init_cpu_err;
/* Initialize the Command Processor. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- fw = &bnx2_cp_fw_09;
- else
- fw = &bnx2_cp_fw_06;
-
- fw->text = text;
- rc = load_cpu_fw(bp, &cpu_reg_cp, fw);
+ rc = load_cpu_fw(bp, &cpu_reg_cp, &mips_fw->cp);
init_cpu_err:
- vfree(text);
return rc;
}
-static int
-bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
+static void
+bnx2_setup_wol(struct bnx2 *bp)
{
- u16 pmcsr;
+ int i;
+ u32 val, wol_msg;
- pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
+ if (bp->wol) {
+ u32 advertising;
+ u8 autoneg;
- switch (state) {
- case PCI_D0: {
- u32 val;
+ autoneg = bp->autoneg;
+ advertising = bp->advertising;
- pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
- (pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
- PCI_PM_CTRL_PME_STATUS);
-
- if (pmcsr & PCI_PM_CTRL_STATE_MASK)
- /* delay required during transition out of D3hot */
- msleep(20);
+ if (bp->phy_port == PORT_TP) {
+ bp->autoneg = AUTONEG_SPEED;
+ bp->advertising = ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_Autoneg;
+ }
- val = REG_RD(bp, BNX2_EMAC_MODE);
- val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD;
- val &= ~BNX2_EMAC_MODE_MPKT;
- REG_WR(bp, BNX2_EMAC_MODE, val);
+ spin_lock_bh(&bp->phy_lock);
+ bnx2_setup_phy(bp, bp->phy_port);
+ spin_unlock_bh(&bp->phy_lock);
- val = REG_RD(bp, BNX2_RPM_CONFIG);
- val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
- REG_WR(bp, BNX2_RPM_CONFIG, val);
- break;
- }
- case PCI_D3hot: {
- int i;
- u32 val, wol_msg;
-
- if (bp->wol) {
- u32 advertising;
- u8 autoneg;
-
- autoneg = bp->autoneg;
- advertising = bp->advertising;
-
- if (bp->phy_port == PORT_TP) {
- bp->autoneg = AUTONEG_SPEED;
- bp->advertising = ADVERTISED_10baseT_Half |
- ADVERTISED_10baseT_Full |
- ADVERTISED_100baseT_Half |
- ADVERTISED_100baseT_Full |
- ADVERTISED_Autoneg;
- }
+ bp->autoneg = autoneg;
+ bp->advertising = advertising;
- spin_lock_bh(&bp->phy_lock);
- bnx2_setup_phy(bp, bp->phy_port);
- spin_unlock_bh(&bp->phy_lock);
+ bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0);
- bp->autoneg = autoneg;
- bp->advertising = advertising;
+ val = BNX2_RD(bp, BNX2_EMAC_MODE);
- bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0);
+ /* Enable port mode. */
+ val &= ~BNX2_EMAC_MODE_PORT;
+ val |= BNX2_EMAC_MODE_MPKT_RCVD |
+ BNX2_EMAC_MODE_ACPI_RCVD |
+ BNX2_EMAC_MODE_MPKT;
+ if (bp->phy_port == PORT_TP) {
+ val |= BNX2_EMAC_MODE_PORT_MII;
+ } else {
+ val |= BNX2_EMAC_MODE_PORT_GMII;
+ if (bp->line_speed == SPEED_2500)
+ val |= BNX2_EMAC_MODE_25G_MODE;
+ }
- val = REG_RD(bp, BNX2_EMAC_MODE);
+ BNX2_WR(bp, BNX2_EMAC_MODE, val);
- /* Enable port mode. */
- val &= ~BNX2_EMAC_MODE_PORT;
- val |= BNX2_EMAC_MODE_MPKT_RCVD |
- BNX2_EMAC_MODE_ACPI_RCVD |
- BNX2_EMAC_MODE_MPKT;
- if (bp->phy_port == PORT_TP)
- val |= BNX2_EMAC_MODE_PORT_MII;
- else {
- val |= BNX2_EMAC_MODE_PORT_GMII;
- if (bp->line_speed == SPEED_2500)
- val |= BNX2_EMAC_MODE_25G_MODE;
- }
+ /* receive all multicast */
+ for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
+ BNX2_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
+ 0xffffffff);
+ }
+ BNX2_WR(bp, BNX2_EMAC_RX_MODE, BNX2_EMAC_RX_MODE_SORT_MODE);
- REG_WR(bp, BNX2_EMAC_MODE, val);
+ val = 1 | BNX2_RPM_SORT_USER0_BC_EN | BNX2_RPM_SORT_USER0_MC_EN;
+ BNX2_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
+ BNX2_WR(bp, BNX2_RPM_SORT_USER0, val);
+ BNX2_WR(bp, BNX2_RPM_SORT_USER0, val | BNX2_RPM_SORT_USER0_ENA);
- /* receive all multicast */
- for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
- REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
- 0xffffffff);
- }
- REG_WR(bp, BNX2_EMAC_RX_MODE,
- BNX2_EMAC_RX_MODE_SORT_MODE);
+ /* Need to enable EMAC and RPM for WOL. */
+ BNX2_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+ BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE |
+ BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE |
+ BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE);
- val = 1 | BNX2_RPM_SORT_USER0_BC_EN |
- BNX2_RPM_SORT_USER0_MC_EN;
- REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
- REG_WR(bp, BNX2_RPM_SORT_USER0, val);
- REG_WR(bp, BNX2_RPM_SORT_USER0, val |
- BNX2_RPM_SORT_USER0_ENA);
+ val = BNX2_RD(bp, BNX2_RPM_CONFIG);
+ val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
+ BNX2_WR(bp, BNX2_RPM_CONFIG, val);
- /* Need to enable EMAC and RPM for WOL. */
- REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
- BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE |
- BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE |
- BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE);
+ wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
+ } else {
+ wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+ }
- val = REG_RD(bp, BNX2_RPM_CONFIG);
- val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
- REG_WR(bp, BNX2_RPM_CONFIG, val);
+ if (!(bp->flags & BNX2_FLAG_NO_WOL)) {
+ u32 val;
- wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
- }
- else {
- wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+ wol_msg |= BNX2_DRV_MSG_DATA_WAIT3;
+ if (bp->fw_last_msg || BNX2_CHIP(bp) != BNX2_CHIP_5709) {
+ bnx2_fw_sync(bp, wol_msg, 1, 0);
+ return;
}
+ /* Tell firmware not to power down the PHY yet, otherwise
+ * the chip will take a long time to respond to MMIO reads.
+ */
+ val = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE);
+ bnx2_shmem_wr(bp, BNX2_PORT_FEATURE,
+ val | BNX2_PORT_FEATURE_ASF_ENABLED);
+ bnx2_fw_sync(bp, wol_msg, 1, 0);
+ bnx2_shmem_wr(bp, BNX2_PORT_FEATURE, val);
+ }
+
+}
+
+static int
+bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
+{
+ switch (state) {
+ case PCI_D0: {
+ u32 val;
- if (!(bp->flags & BNX2_FLAG_NO_WOL))
- bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg,
- 1, 0);
+ pci_enable_wake(bp->pdev, PCI_D0, false);
+ pci_set_power_state(bp->pdev, PCI_D0);
- pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
- if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
- (CHIP_ID(bp) == CHIP_ID_5706_A1)) {
+ val = BNX2_RD(bp, BNX2_EMAC_MODE);
+ val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD;
+ val &= ~BNX2_EMAC_MODE_MPKT;
+ BNX2_WR(bp, BNX2_EMAC_MODE, val);
+
+ val = BNX2_RD(bp, BNX2_RPM_CONFIG);
+ val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
+ BNX2_WR(bp, BNX2_RPM_CONFIG, val);
+ break;
+ }
+ case PCI_D3hot: {
+ bnx2_setup_wol(bp);
+ pci_wake_from_d3(bp->pdev, bp->wol);
+ if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1)) {
if (bp->wol)
- pmcsr |= 3;
- }
- else {
- pmcsr |= 3;
+ pci_set_power_state(bp->pdev, PCI_D3hot);
+ break;
+
}
- if (bp->wol) {
- pmcsr |= PCI_PM_CTRL_PME_ENABLE;
+ if (!bp->fw_last_msg && BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ u32 val;
+
+ /* Tell firmware not to power down the PHY yet,
+ * otherwise the other port may not respond to
+ * MMIO reads.
+ */
+ val = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION);
+ val &= ~BNX2_CONDITION_PM_STATE_MASK;
+ val |= BNX2_CONDITION_PM_STATE_UNPREP;
+ bnx2_shmem_wr(bp, BNX2_BC_STATE_CONDITION, val);
}
- pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
- pmcsr);
+ pci_set_power_state(bp->pdev, PCI_D3hot);
/* No more memory access after this point until
* device is brought back to D0.
*/
- udelay(50);
break;
}
default:
@@ -3695,9 +4087,9 @@ bnx2_acquire_nvram_lock(struct bnx2 *bp)
int j;
/* Request access to the flash interface. */
- REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_SET2);
+ BNX2_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_SET2);
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
- val = REG_RD(bp, BNX2_NVM_SW_ARB);
+ val = BNX2_RD(bp, BNX2_NVM_SW_ARB);
if (val & BNX2_NVM_SW_ARB_ARB_ARB2)
break;
@@ -3717,10 +4109,10 @@ bnx2_release_nvram_lock(struct bnx2 *bp)
u32 val;
/* Relinquish nvram interface. */
- REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_CLR2);
+ BNX2_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_CLR2);
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
- val = REG_RD(bp, BNX2_NVM_SW_ARB);
+ val = BNX2_RD(bp, BNX2_NVM_SW_ARB);
if (!(val & BNX2_NVM_SW_ARB_ARB_ARB2))
break;
@@ -3739,20 +4131,20 @@ bnx2_enable_nvram_write(struct bnx2 *bp)
{
u32 val;
- val = REG_RD(bp, BNX2_MISC_CFG);
- REG_WR(bp, BNX2_MISC_CFG, val | BNX2_MISC_CFG_NVM_WR_EN_PCI);
+ val = BNX2_RD(bp, BNX2_MISC_CFG);
+ BNX2_WR(bp, BNX2_MISC_CFG, val | BNX2_MISC_CFG_NVM_WR_EN_PCI);
if (bp->flash_info->flags & BNX2_NV_WREN) {
int j;
- REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
- REG_WR(bp, BNX2_NVM_COMMAND,
- BNX2_NVM_COMMAND_WREN | BNX2_NVM_COMMAND_DOIT);
+ BNX2_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+ BNX2_WR(bp, BNX2_NVM_COMMAND,
+ BNX2_NVM_COMMAND_WREN | BNX2_NVM_COMMAND_DOIT);
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
udelay(5);
- val = REG_RD(bp, BNX2_NVM_COMMAND);
+ val = BNX2_RD(bp, BNX2_NVM_COMMAND);
if (val & BNX2_NVM_COMMAND_DONE)
break;
}
@@ -3768,8 +4160,8 @@ bnx2_disable_nvram_write(struct bnx2 *bp)
{
u32 val;
- val = REG_RD(bp, BNX2_MISC_CFG);
- REG_WR(bp, BNX2_MISC_CFG, val & ~BNX2_MISC_CFG_NVM_WR_EN);
+ val = BNX2_RD(bp, BNX2_MISC_CFG);
+ BNX2_WR(bp, BNX2_MISC_CFG, val & ~BNX2_MISC_CFG_NVM_WR_EN);
}
@@ -3778,10 +4170,10 @@ bnx2_enable_nvram_access(struct bnx2 *bp)
{
u32 val;
- val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
+ val = BNX2_RD(bp, BNX2_NVM_ACCESS_ENABLE);
/* Enable both bits, even on read. */
- REG_WR(bp, BNX2_NVM_ACCESS_ENABLE,
- val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN);
+ BNX2_WR(bp, BNX2_NVM_ACCESS_ENABLE,
+ val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN);
}
static void
@@ -3789,9 +4181,9 @@ bnx2_disable_nvram_access(struct bnx2 *bp)
{
u32 val;
- val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
+ val = BNX2_RD(bp, BNX2_NVM_ACCESS_ENABLE);
/* Disable both bits, even after read. */
- REG_WR(bp, BNX2_NVM_ACCESS_ENABLE,
+ BNX2_WR(bp, BNX2_NVM_ACCESS_ENABLE,
val & ~(BNX2_NVM_ACCESS_ENABLE_EN |
BNX2_NVM_ACCESS_ENABLE_WR_EN));
}
@@ -3811,13 +4203,13 @@ bnx2_nvram_erase_page(struct bnx2 *bp, u32 offset)
BNX2_NVM_COMMAND_DOIT;
/* Need to clear DONE bit separately. */
- REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+ BNX2_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
/* Address of the NVRAM to read from. */
- REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
+ BNX2_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
/* Issue an erase command. */
- REG_WR(bp, BNX2_NVM_COMMAND, cmd);
+ BNX2_WR(bp, BNX2_NVM_COMMAND, cmd);
/* Wait for completion. */
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
@@ -3825,7 +4217,7 @@ bnx2_nvram_erase_page(struct bnx2 *bp, u32 offset)
udelay(5);
- val = REG_RD(bp, BNX2_NVM_COMMAND);
+ val = BNX2_RD(bp, BNX2_NVM_COMMAND);
if (val & BNX2_NVM_COMMAND_DONE)
break;
}
@@ -3853,13 +4245,13 @@ bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags)
}
/* Need to clear DONE bit separately. */
- REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+ BNX2_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
/* Address of the NVRAM to read from. */
- REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
+ BNX2_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
/* Issue a read command. */
- REG_WR(bp, BNX2_NVM_COMMAND, cmd);
+ BNX2_WR(bp, BNX2_NVM_COMMAND, cmd);
/* Wait for completion. */
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
@@ -3867,9 +4259,9 @@ bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags)
udelay(5);
- val = REG_RD(bp, BNX2_NVM_COMMAND);
+ val = BNX2_RD(bp, BNX2_NVM_COMMAND);
if (val & BNX2_NVM_COMMAND_DONE) {
- __be32 v = cpu_to_be32(REG_RD(bp, BNX2_NVM_READ));
+ __be32 v = cpu_to_be32(BNX2_RD(bp, BNX2_NVM_READ));
memcpy(ret_val, &v, 4);
break;
}
@@ -3899,24 +4291,24 @@ bnx2_nvram_write_dword(struct bnx2 *bp, u32 offset, u8 *val, u32 cmd_flags)
}
/* Need to clear DONE bit separately. */
- REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
+ BNX2_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
memcpy(&val32, val, 4);
/* Write the data. */
- REG_WR(bp, BNX2_NVM_WRITE, be32_to_cpu(val32));
+ BNX2_WR(bp, BNX2_NVM_WRITE, be32_to_cpu(val32));
/* Address of the NVRAM to write to. */
- REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
+ BNX2_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
/* Issue the write command. */
- REG_WR(bp, BNX2_NVM_COMMAND, cmd);
+ BNX2_WR(bp, BNX2_NVM_COMMAND, cmd);
/* Wait for completion. */
for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
udelay(5);
- if (REG_RD(bp, BNX2_NVM_COMMAND) & BNX2_NVM_COMMAND_DONE)
+ if (BNX2_RD(bp, BNX2_NVM_COMMAND) & BNX2_NVM_COMMAND_DONE)
break;
}
if (j >= NVRAM_TIMEOUT_COUNT)
@@ -3930,15 +4322,15 @@ bnx2_init_nvram(struct bnx2 *bp)
{
u32 val;
int j, entry_count, rc = 0;
- struct flash_spec *flash;
+ const struct flash_spec *flash;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
bp->flash_info = &flash_5709;
goto get_flash_size;
}
/* Determine the selected interface. */
- val = REG_RD(bp, BNX2_NVM_CFG1);
+ val = BNX2_RD(bp, BNX2_NVM_CFG1);
entry_count = ARRAY_SIZE(flash_table);
@@ -3977,10 +4369,10 @@ bnx2_init_nvram(struct bnx2 *bp)
bnx2_enable_nvram_access(bp);
/* Reconfigure the flash interface */
- REG_WR(bp, BNX2_NVM_CFG1, flash->config1);
- REG_WR(bp, BNX2_NVM_CFG2, flash->config2);
- REG_WR(bp, BNX2_NVM_CFG3, flash->config3);
- REG_WR(bp, BNX2_NVM_WRITE1, flash->write1);
+ BNX2_WR(bp, BNX2_NVM_CFG1, flash->config1);
+ BNX2_WR(bp, BNX2_NVM_CFG2, flash->config2);
+ BNX2_WR(bp, BNX2_NVM_CFG3, flash->config3);
+ BNX2_WR(bp, BNX2_NVM_WRITE1, flash->write1);
/* Disable access to flash interface */
bnx2_disable_nvram_access(bp);
@@ -3993,7 +4385,7 @@ bnx2_init_nvram(struct bnx2 *bp)
if (j == entry_count) {
bp->flash_info = NULL;
- printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
+ pr_alert("Unknown flash/EEPROM type\n");
return -ENODEV;
}
@@ -4341,10 +4733,10 @@ bnx2_init_fw_cap(struct bnx2 *bp)
static void
bnx2_setup_msix_tbl(struct bnx2 *bp)
{
- REG_WR(bp, BNX2_PCI_GRC_WINDOW_ADDR, BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN);
+ BNX2_WR(bp, BNX2_PCI_GRC_WINDOW_ADDR, BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN);
- REG_WR(bp, BNX2_PCI_GRC_WINDOW2_ADDR, BNX2_MSIX_TABLE_ADDR);
- REG_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);
+ BNX2_WR(bp, BNX2_PCI_GRC_WINDOW2_ADDR, BNX2_MSIX_TABLE_ADDR);
+ BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);
}
static int
@@ -4356,13 +4748,28 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
/* Wait for the current PCI transaction to complete before
* issuing a reset. */
- REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
- BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
- BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
- val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
- udelay(5);
+ if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) ||
+ (BNX2_CHIP(bp) == BNX2_CHIP_5708)) {
+ BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
+ BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
+ BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
+ val = BNX2_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
+ udelay(5);
+ } else { /* 5709 */
+ val = BNX2_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+ val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
+ BNX2_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
+ val = BNX2_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+
+ for (i = 0; i < 100; i++) {
+ msleep(1);
+ val = BNX2_RD(bp, BNX2_PCICFG_DEVICE_CONTROL);
+ if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND))
+ break;
+ }
+ }
/* Wait for the firmware to tell us it is ok to issue a reset. */
bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
@@ -4374,17 +4781,17 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
/* Do a dummy read to force the chip to complete all current transaction
* before we issue a reset. */
- val = REG_RD(bp, BNX2_MISC_ID);
+ val = BNX2_RD(bp, BNX2_MISC_ID);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- REG_WR(bp, BNX2_MISC_COMMAND, BNX2_MISC_COMMAND_SW_RESET);
- REG_RD(bp, BNX2_MISC_COMMAND);
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ BNX2_WR(bp, BNX2_MISC_COMMAND, BNX2_MISC_COMMAND_SW_RESET);
+ BNX2_RD(bp, BNX2_MISC_COMMAND);
udelay(5);
val = BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
- pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, val);
+ BNX2_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
} else {
val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
@@ -4392,19 +4799,19 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
/* Chip reset. */
- REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
+ BNX2_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
/* Reading back any register after chip reset will hang the
* bus on 5706 A0 and A1. The msleep below provides plenty
* of margin for write posting.
*/
- if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
- (CHIP_ID(bp) == CHIP_ID_5706_A1))
+ if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1))
msleep(20);
/* Reset takes approximate 30 usec */
for (i = 0; i < 10; i++) {
- val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
+ val = BNX2_RD(bp, BNX2_PCICFG_MISC_CONFIG);
if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0)
break;
@@ -4413,15 +4820,15 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
- printk(KERN_ERR PFX "Chip reset did not complete\n");
+ pr_err("Chip reset did not complete\n");
return -EBUSY;
}
}
/* Make sure byte swapping is properly configured. */
- val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0);
+ val = BNX2_RD(bp, BNX2_PCI_SWAP_DIAG0);
if (val != 0x01020304) {
- printk(KERN_ERR PFX "Chip not in correct endian mode\n");
+ pr_err("Chip not in correct endian mode\n");
return -ENODEV;
}
@@ -4438,17 +4845,21 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
bnx2_set_default_remote_link(bp);
spin_unlock_bh(&bp->phy_lock);
- if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+ if (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) {
/* Adjust the voltage regular to two steps lower. The default
* of this register is 0x0000000e. */
- REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
+ BNX2_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
/* Remove bad rbuf memory from the free pool. */
rc = bnx2_alloc_bad_rbuf(bp);
}
- if (bp->flags & BNX2_FLAG_USING_MSIX)
+ if (bp->flags & BNX2_FLAG_USING_MSIX) {
bnx2_setup_msix_tbl(bp);
+ /* Prevent MSIX table reads and write from timing out */
+ BNX2_WR(bp, BNX2_MISC_ECO_HW_CTL,
+ BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN);
+ }
return rc;
}
@@ -4456,11 +4867,11 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
static int
bnx2_init_chip(struct bnx2 *bp)
{
- u32 val;
+ u32 val, mtu;
int rc, i;
/* Make sure the interrupt is not active. */
- REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+ BNX2_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP |
BNX2_DMA_CONFIG_DATA_WORD_SWAP |
@@ -4476,16 +4887,17 @@ bnx2_init_chip(struct bnx2 *bp)
if ((bp->flags & BNX2_FLAG_PCIX) && (bp->bus_speed_mhz == 133))
val |= (1 << 23);
- if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
- (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & BNX2_FLAG_PCIX))
+ if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) &&
+ (BNX2_CHIP_ID(bp) != BNX2_CHIP_ID_5706_A0) &&
+ !(bp->flags & BNX2_FLAG_PCIX))
val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
- REG_WR(bp, BNX2_DMA_CONFIG, val);
+ BNX2_WR(bp, BNX2_DMA_CONFIG, val);
- if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
- val = REG_RD(bp, BNX2_TDMA_CONFIG);
+ if (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) {
+ val = BNX2_RD(bp, BNX2_TDMA_CONFIG);
val |= BNX2_TDMA_CONFIG_ONE_DMA;
- REG_WR(bp, BNX2_TDMA_CONFIG, val);
+ BNX2_WR(bp, BNX2_TDMA_CONFIG, val);
}
if (bp->flags & BNX2_FLAG_PCIX) {
@@ -4497,14 +4909,14 @@ bnx2_init_chip(struct bnx2 *bp)
val16 & ~PCI_X_CMD_ERO);
}
- REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
- BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
- BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
- BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
+ BNX2_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+ BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
+ BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
+ BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
/* Initialize context mapping and zero out the quick contexts. The
* context block must have already been enabled. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
rc = bnx2_init_5709_context(bp);
if (rc)
return rc;
@@ -4518,26 +4930,29 @@ bnx2_init_chip(struct bnx2 *bp)
bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0);
- val = REG_RD(bp, BNX2_MQ_CONFIG);
+ val = BNX2_RD(bp, BNX2_MQ_CONFIG);
val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
- if (CHIP_ID(bp) == CHIP_ID_5709_A0 || CHIP_ID(bp) == CHIP_ID_5709_A1)
- val |= BNX2_MQ_CONFIG_HALT_DIS;
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ val |= BNX2_MQ_CONFIG_BIN_MQ_MODE;
+ if (BNX2_CHIP_REV(bp) == BNX2_CHIP_REV_Ax)
+ val |= BNX2_MQ_CONFIG_HALT_DIS;
+ }
- REG_WR(bp, BNX2_MQ_CONFIG, val);
+ BNX2_WR(bp, BNX2_MQ_CONFIG, val);
val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
- REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val);
- REG_WR(bp, BNX2_MQ_KNL_WIND_END, val);
+ BNX2_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val);
+ BNX2_WR(bp, BNX2_MQ_KNL_WIND_END, val);
- val = (BCM_PAGE_BITS - 8) << 24;
- REG_WR(bp, BNX2_RV2P_CONFIG, val);
+ val = (BNX2_PAGE_BITS - 8) << 24;
+ BNX2_WR(bp, BNX2_RV2P_CONFIG, val);
/* Configure page size. */
- val = REG_RD(bp, BNX2_TBDR_CONFIG);
+ val = BNX2_RD(bp, BNX2_TBDR_CONFIG);
val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE;
- val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
- REG_WR(bp, BNX2_TBDR_CONFIG, val);
+ val |= (BNX2_PAGE_BITS - 8) << 24 | 0x40;
+ BNX2_WR(bp, BNX2_TBDR_CONFIG, val);
val = bp->mac_addr[0] +
(bp->mac_addr[1] << 8) +
@@ -4545,121 +4960,137 @@ bnx2_init_chip(struct bnx2 *bp)
bp->mac_addr[3] +
(bp->mac_addr[4] << 8) +
(bp->mac_addr[5] << 16);
- REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
+ BNX2_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
/* Program the MTU. Also include 4 bytes for CRC32. */
- val = bp->dev->mtu + ETH_HLEN + 4;
+ mtu = bp->dev->mtu;
+ val = mtu + ETH_HLEN + ETH_FCS_LEN;
if (val > (MAX_ETHERNET_PACKET_SIZE + 4))
val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
- REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
+ BNX2_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
+
+ if (mtu < 1500)
+ mtu = 1500;
+
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG, BNX2_RBUF_CONFIG_VAL(mtu));
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG2, BNX2_RBUF_CONFIG2_VAL(mtu));
+ bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG3, BNX2_RBUF_CONFIG3_VAL(mtu));
+ memset(bp->bnx2_napi[0].status_blk.msi, 0, bp->status_stats_size);
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
bp->bnx2_napi[i].last_status_idx = 0;
+ bp->idle_chk_status_idx = 0xffff;
+
bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
/* Set up how to generate a link change interrupt. */
- REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
+ BNX2_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
- REG_WR(bp, BNX2_HC_STATUS_ADDR_L,
- (u64) bp->status_blk_mapping & 0xffffffff);
- REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32);
+ BNX2_WR(bp, BNX2_HC_STATUS_ADDR_L,
+ (u64) bp->status_blk_mapping & 0xffffffff);
+ BNX2_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32);
- REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L,
- (u64) bp->stats_blk_mapping & 0xffffffff);
- REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H,
- (u64) bp->stats_blk_mapping >> 32);
+ BNX2_WR(bp, BNX2_HC_STATISTICS_ADDR_L,
+ (u64) bp->stats_blk_mapping & 0xffffffff);
+ BNX2_WR(bp, BNX2_HC_STATISTICS_ADDR_H,
+ (u64) bp->stats_blk_mapping >> 32);
- REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP,
- (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip);
+ BNX2_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP,
+ (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip);
- REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP,
- (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip);
+ BNX2_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP,
+ (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip);
- REG_WR(bp, BNX2_HC_COMP_PROD_TRIP,
- (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip);
+ BNX2_WR(bp, BNX2_HC_COMP_PROD_TRIP,
+ (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip);
- REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks);
+ BNX2_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks);
- REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks);
+ BNX2_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks);
- REG_WR(bp, BNX2_HC_COM_TICKS,
- (bp->com_ticks_int << 16) | bp->com_ticks);
+ BNX2_WR(bp, BNX2_HC_COM_TICKS,
+ (bp->com_ticks_int << 16) | bp->com_ticks);
- REG_WR(bp, BNX2_HC_CMD_TICKS,
- (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
+ BNX2_WR(bp, BNX2_HC_CMD_TICKS,
+ (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
- if (CHIP_NUM(bp) == CHIP_NUM_5708)
- REG_WR(bp, BNX2_HC_STATS_TICKS, 0);
+ if (bp->flags & BNX2_FLAG_BROKEN_STATS)
+ BNX2_WR(bp, BNX2_HC_STATS_TICKS, 0);
else
- REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks);
- REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */
+ BNX2_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks);
+ BNX2_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */
- if (CHIP_ID(bp) == CHIP_ID_5706_A1)
+ if (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1)
val = BNX2_HC_CONFIG_COLLECT_STATS;
else {
val = BNX2_HC_CONFIG_RX_TMR_MODE | BNX2_HC_CONFIG_TX_TMR_MODE |
BNX2_HC_CONFIG_COLLECT_STATS;
}
- if (bp->irq_nvecs > 1) {
- REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
- BNX2_HC_MSIX_BIT_VECTOR_VAL);
+ if (bp->flags & BNX2_FLAG_USING_MSIX) {
+ BNX2_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
+ BNX2_HC_MSIX_BIT_VECTOR_VAL);
val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
}
if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
- val |= BNX2_HC_CONFIG_ONE_SHOT;
+ val |= BNX2_HC_CONFIG_ONE_SHOT | BNX2_HC_CONFIG_USE_INT_PARAM;
+
+ BNX2_WR(bp, BNX2_HC_CONFIG, val);
- REG_WR(bp, BNX2_HC_CONFIG, val);
+ if (bp->rx_ticks < 25)
+ bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 1);
+ else
+ bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 0);
for (i = 1; i < bp->irq_nvecs; i++) {
u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) +
BNX2_HC_SB_CONFIG_1;
- REG_WR(bp, base,
+ BNX2_WR(bp, base,
BNX2_HC_SB_CONFIG_1_TX_TMR_MODE |
BNX2_HC_SB_CONFIG_1_RX_TMR_MODE |
BNX2_HC_SB_CONFIG_1_ONE_SHOT);
- REG_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF,
+ BNX2_WR(bp, base + BNX2_HC_TX_QUICK_CONS_TRIP_OFF,
(bp->tx_quick_cons_trip_int << 16) |
bp->tx_quick_cons_trip);
- REG_WR(bp, base + BNX2_HC_TX_TICKS_OFF,
+ BNX2_WR(bp, base + BNX2_HC_TX_TICKS_OFF,
(bp->tx_ticks_int << 16) | bp->tx_ticks);
- REG_WR(bp, base + BNX2_HC_RX_QUICK_CONS_TRIP_OFF,
- (bp->rx_quick_cons_trip_int << 16) |
+ BNX2_WR(bp, base + BNX2_HC_RX_QUICK_CONS_TRIP_OFF,
+ (bp->rx_quick_cons_trip_int << 16) |
bp->rx_quick_cons_trip);
- REG_WR(bp, base + BNX2_HC_RX_TICKS_OFF,
+ BNX2_WR(bp, base + BNX2_HC_RX_TICKS_OFF,
(bp->rx_ticks_int << 16) | bp->rx_ticks);
}
/* Clear internal stats counters. */
- REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
+ BNX2_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
- REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_EVENTS);
+ BNX2_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_EVENTS);
/* Initialize the receive filter. */
bnx2_set_rx_mode(bp->dev);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL);
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ val = BNX2_RD(bp, BNX2_MISC_NEW_CORE_CTL);
val |= BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE;
- REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
+ BNX2_WR(bp, BNX2_MISC_NEW_CORE_CTL, val);
}
rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
1, 0);
- REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_DEFAULT);
- REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
+ BNX2_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_DEFAULT);
+ BNX2_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
udelay(20);
- bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND);
+ bp->hc_cmd = BNX2_RD(bp, BNX2_HC_COMMAND);
return rc;
}
@@ -4693,7 +5124,7 @@ bnx2_init_tx_context(struct bnx2 *bp, u32 cid, struct bnx2_tx_ring_info *txr)
u32 val, offset0, offset1, offset2, offset3;
u32 cid_addr = GET_CID_ADDR(cid);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
offset0 = BNX2_L2CTX_TYPE_XI;
offset1 = BNX2_L2CTX_CMD_TYPE_XI;
offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI;
@@ -4720,7 +5151,7 @@ bnx2_init_tx_context(struct bnx2 *bp, u32 cid, struct bnx2_tx_ring_info *txr)
static void
bnx2_init_tx_ring(struct bnx2 *bp, int ring_num)
{
- struct tx_bd *txbd;
+ struct bnx2_tx_bd *txbd;
u32 cid = TX_CID;
struct bnx2_napi *bnapi;
struct bnx2_tx_ring_info *txr;
@@ -4735,7 +5166,7 @@ bnx2_init_tx_ring(struct bnx2 *bp, int ring_num)
bp->tx_wake_thresh = bp->tx_ring_size / 2;
- txbd = &txr->tx_desc_ring[MAX_TX_DESC_CNT];
+ txbd = &txr->tx_desc_ring[BNX2_MAX_TX_DESC_CNT];
txbd->tx_bd_haddr_hi = (u64) txr->tx_desc_mapping >> 32;
txbd->tx_bd_haddr_lo = (u64) txr->tx_desc_mapping & 0xffffffff;
@@ -4750,17 +5181,17 @@ bnx2_init_tx_ring(struct bnx2 *bp, int ring_num)
}
static void
-bnx2_init_rxbd_rings(struct rx_bd *rx_ring[], dma_addr_t dma[], u32 buf_size,
- int num_rings)
+bnx2_init_rxbd_rings(struct bnx2_rx_bd *rx_ring[], dma_addr_t dma[],
+ u32 buf_size, int num_rings)
{
int i;
- struct rx_bd *rxbd;
+ struct bnx2_rx_bd *rxbd;
for (i = 0; i < num_rings; i++) {
int j;
rxbd = &rx_ring[i][0];
- for (j = 0; j < MAX_RX_DESC_CNT; j++, rxbd++) {
+ for (j = 0; j < BNX2_MAX_RX_DESC_CNT; j++, rxbd++) {
rxbd->rx_bd_len = buf_size;
rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
}
@@ -4794,9 +5225,9 @@ bnx2_init_rx_ring(struct bnx2 *bp, int ring_num)
bnx2_init_rx_context(bp, cid);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- val = REG_RD(bp, BNX2_MQ_MAP_L2_5);
- REG_WR(bp, BNX2_MQ_MAP_L2_5, val | BNX2_MQ_MAP_L2_5_ARM);
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ val = BNX2_RD(bp, BNX2_MQ_MAP_L2_5);
+ BNX2_WR(bp, BNX2_MQ_MAP_L2_5, val | BNX2_MQ_MAP_L2_5_ARM);
}
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
@@ -4815,8 +5246,8 @@ bnx2_init_rx_ring(struct bnx2 *bp, int ring_num)
val = (u64) rxr->rx_pg_desc_mapping[0] & 0xffffffff;
bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
+ BNX2_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
}
val = (u64) rxr->rx_desc_mapping[0] >> 32;
@@ -4827,19 +5258,25 @@ bnx2_init_rx_ring(struct bnx2 *bp, int ring_num)
ring_prod = prod = rxr->rx_pg_prod;
for (i = 0; i < bp->rx_pg_ring_size; i++) {
- if (bnx2_alloc_rx_page(bp, rxr, ring_prod) < 0)
+ if (bnx2_alloc_rx_page(bp, rxr, ring_prod, GFP_KERNEL) < 0) {
+ netdev_warn(bp->dev, "init'ed rx page ring %d with %d/%d pages only\n",
+ ring_num, i, bp->rx_pg_ring_size);
break;
- prod = NEXT_RX_BD(prod);
- ring_prod = RX_PG_RING_IDX(prod);
+ }
+ prod = BNX2_NEXT_RX_BD(prod);
+ ring_prod = BNX2_RX_PG_RING_IDX(prod);
}
rxr->rx_pg_prod = prod;
ring_prod = prod = rxr->rx_prod;
for (i = 0; i < bp->rx_ring_size; i++) {
- if (bnx2_alloc_rx_skb(bp, rxr, ring_prod) < 0)
+ if (bnx2_alloc_rx_data(bp, rxr, ring_prod, GFP_KERNEL) < 0) {
+ netdev_warn(bp->dev, "init'ed rx ring %d with %d/%d skbs only\n",
+ ring_num, i, bp->rx_ring_size);
break;
- prod = NEXT_RX_BD(prod);
- ring_prod = RX_RING_IDX(prod);
+ }
+ prod = BNX2_NEXT_RX_BD(prod);
+ ring_prod = BNX2_RX_RING_IDX(prod);
}
rxr->rx_prod = prod;
@@ -4847,10 +5284,10 @@ bnx2_init_rx_ring(struct bnx2 *bp, int ring_num)
rxr->rx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_BSEQ;
rxr->rx_pg_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_HOST_PG_BDIDX;
- REG_WR16(bp, rxr->rx_pg_bidx_addr, rxr->rx_pg_prod);
- REG_WR16(bp, rxr->rx_bidx_addr, prod);
+ BNX2_WR16(bp, rxr->rx_pg_bidx_addr, rxr->rx_pg_prod);
+ BNX2_WR16(bp, rxr->rx_bidx_addr, prod);
- REG_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
+ BNX2_WR(bp, rxr->rx_bseq_addr, rxr->rx_prod_bseq);
}
static void
@@ -4861,39 +5298,41 @@ bnx2_init_all_rings(struct bnx2 *bp)
bnx2_clear_ring_states(bp);
- REG_WR(bp, BNX2_TSCH_TSS_CFG, 0);
+ BNX2_WR(bp, BNX2_TSCH_TSS_CFG, 0);
for (i = 0; i < bp->num_tx_rings; i++)
bnx2_init_tx_ring(bp, i);
if (bp->num_tx_rings > 1)
- REG_WR(bp, BNX2_TSCH_TSS_CFG, ((bp->num_tx_rings - 1) << 24) |
- (TX_TSS_CID << 7));
+ BNX2_WR(bp, BNX2_TSCH_TSS_CFG, ((bp->num_tx_rings - 1) << 24) |
+ (TX_TSS_CID << 7));
- REG_WR(bp, BNX2_RLUP_RSS_CONFIG, 0);
+ BNX2_WR(bp, BNX2_RLUP_RSS_CONFIG, 0);
bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ, 0);
for (i = 0; i < bp->num_rx_rings; i++)
bnx2_init_rx_ring(bp, i);
if (bp->num_rx_rings > 1) {
- u32 tbl_32;
- u8 *tbl = (u8 *) &tbl_32;
-
- bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ,
- BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES);
+ u32 tbl_32 = 0;
for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) {
- tbl[i % 4] = i % (bp->num_rx_rings - 1);
- if ((i % 4) == 3)
- bnx2_reg_wr_ind(bp,
- BNX2_RXP_SCRATCH_RSS_TBL + i,
- cpu_to_be32(tbl_32));
+ int shift = (i % 8) << 2;
+
+ tbl_32 |= (i % (bp->num_rx_rings - 1)) << shift;
+ if ((i % 8) == 7) {
+ BNX2_WR(bp, BNX2_RLUP_RSS_DATA, tbl_32);
+ BNX2_WR(bp, BNX2_RLUP_RSS_COMMAND, (i >> 3) |
+ BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK |
+ BNX2_RLUP_RSS_COMMAND_WRITE |
+ BNX2_RLUP_RSS_COMMAND_HASH_MASK);
+ tbl_32 = 0;
+ }
}
val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI |
BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_ALL_XI;
- REG_WR(bp, BNX2_RLUP_RSS_CONFIG, val);
+ BNX2_WR(bp, BNX2_RLUP_RSS_CONFIG, val);
}
}
@@ -4902,8 +5341,8 @@ static u32 bnx2_find_max_ring(u32 ring_size, u32 max_size)
{
u32 max, num_rings = 1;
- while (ring_size > MAX_RX_DESC_CNT) {
- ring_size -= MAX_RX_DESC_CNT;
+ while (ring_size > BNX2_MAX_RX_DESC_CNT) {
+ ring_size -= BNX2_MAX_RX_DESC_CNT;
num_rings++;
}
/* round to next power of 2 */
@@ -4926,7 +5365,7 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
rx_size = bp->dev->mtu + ETH_HLEN + BNX2_RX_OFFSET + 8;
rx_space = SKB_DATA_ALIGN(rx_size + BNX2_RX_ALIGN) + NET_SKB_PAD +
- sizeof(struct skb_shared_info);
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
bp->rx_copy_thresh = BNX2_RX_COPY_THRESH;
bp->rx_pg_ring_size = 0;
@@ -4936,24 +5375,26 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
int pages = PAGE_ALIGN(bp->dev->mtu - 40) >> PAGE_SHIFT;
jumbo_size = size * pages;
- if (jumbo_size > MAX_TOTAL_RX_PG_DESC_CNT)
- jumbo_size = MAX_TOTAL_RX_PG_DESC_CNT;
+ if (jumbo_size > BNX2_MAX_TOTAL_RX_PG_DESC_CNT)
+ jumbo_size = BNX2_MAX_TOTAL_RX_PG_DESC_CNT;
bp->rx_pg_ring_size = jumbo_size;
bp->rx_max_pg_ring = bnx2_find_max_ring(jumbo_size,
- MAX_RX_PG_RINGS);
- bp->rx_max_pg_ring_idx = (bp->rx_max_pg_ring * RX_DESC_CNT) - 1;
+ BNX2_MAX_RX_PG_RINGS);
+ bp->rx_max_pg_ring_idx =
+ (bp->rx_max_pg_ring * BNX2_RX_DESC_CNT) - 1;
rx_size = BNX2_RX_COPY_THRESH + BNX2_RX_OFFSET;
bp->rx_copy_thresh = 0;
}
bp->rx_buf_use_size = rx_size;
- /* hw alignment */
- bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;
+ /* hw alignment + build_skb() overhead*/
+ bp->rx_buf_size = SKB_DATA_ALIGN(bp->rx_buf_use_size + BNX2_RX_ALIGN) +
+ NET_SKB_PAD + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
bp->rx_jumbo_thresh = rx_size - BNX2_RX_OFFSET;
bp->rx_ring_size = size;
- bp->rx_max_ring = bnx2_find_max_ring(size, MAX_RX_RINGS);
- bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1;
+ bp->rx_max_ring = bnx2_find_max_ring(size, BNX2_MAX_RX_RINGS);
+ bp->rx_max_ring_idx = (bp->rx_max_ring * BNX2_RX_DESC_CNT) - 1;
}
static void
@@ -4969,33 +5410,35 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
if (txr->tx_buf_ring == NULL)
continue;
- for (j = 0; j < TX_DESC_CNT; ) {
- struct sw_bd *tx_buf = &txr->tx_buf_ring[j];
+ for (j = 0; j < BNX2_TX_DESC_CNT; ) {
+ struct bnx2_sw_tx_bd *tx_buf = &txr->tx_buf_ring[j];
struct sk_buff *skb = tx_buf->skb;
int k, last;
if (skb == NULL) {
- j++;
+ j = BNX2_NEXT_TX_BD(j);
continue;
}
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(tx_buf, mapping),
- skb_headlen(skb), PCI_DMA_TODEVICE);
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(tx_buf, mapping),
+ skb_headlen(skb),
+ PCI_DMA_TODEVICE);
tx_buf->skb = NULL;
- last = skb_shinfo(skb)->nr_frags;
- for (k = 0; k < last; k++) {
- tx_buf = &txr->tx_buf_ring[j + k + 1];
- pci_unmap_page(bp->pdev,
- pci_unmap_addr(tx_buf, mapping),
- skb_shinfo(skb)->frags[j].size,
+ last = tx_buf->nr_frags;
+ j = BNX2_NEXT_TX_BD(j);
+ for (k = 0; k < last; k++, j = BNX2_NEXT_TX_BD(j)) {
+ tx_buf = &txr->tx_buf_ring[BNX2_TX_RING_IDX(j)];
+ dma_unmap_page(&bp->pdev->dev,
+ dma_unmap_addr(tx_buf, mapping),
+ skb_frag_size(&skb_shinfo(skb)->frags[k]),
PCI_DMA_TODEVICE);
}
dev_kfree_skb(skb);
- j += k + 1;
}
+ netdev_tx_reset_queue(netdev_get_tx_queue(bp->dev, i));
}
}
@@ -5013,20 +5456,20 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
return;
for (j = 0; j < bp->rx_max_ring_idx; j++) {
- struct sw_bd *rx_buf = &rxr->rx_buf_ring[j];
- struct sk_buff *skb = rx_buf->skb;
+ struct bnx2_sw_bd *rx_buf = &rxr->rx_buf_ring[j];
+ u8 *data = rx_buf->data;
- if (skb == NULL)
+ if (data == NULL)
continue;
- pci_unmap_single(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
bp->rx_buf_use_size,
PCI_DMA_FROMDEVICE);
- rx_buf->skb = NULL;
+ rx_buf->data = NULL;
- dev_kfree_skb(skb);
+ kfree(data);
}
for (j = 0; j < bp->rx_max_pg_ring_idx; j++)
bnx2_free_rx_page(bp, rxr, j);
@@ -5075,6 +5518,21 @@ bnx2_init_nic(struct bnx2 *bp, int reset_phy)
}
static int
+bnx2_shutdown_chip(struct bnx2 *bp)
+{
+ u32 reset_code;
+
+ if (bp->flags & BNX2_FLAG_NO_WOL)
+ reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
+ else if (bp->wol)
+ reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
+ else
+ reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
+
+ return bnx2_reset_chip(bp, reset_code);
+}
+
+static int
bnx2_test_registers(struct bnx2 *bp)
{
int ret;
@@ -5196,7 +5654,7 @@ bnx2_test_registers(struct bnx2 *bp)
ret = 0;
is_5709 = 0;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
is_5709 = 1;
for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
@@ -5295,7 +5753,7 @@ bnx2_test_memory(struct bnx2 *bp)
};
struct mem_entry *mem_tbl;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
mem_tbl = mem_tbl_5709;
else
mem_tbl = mem_tbl_5706;
@@ -5317,12 +5775,13 @@ static int
bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
{
unsigned int pkt_size, num_pkts, i;
- struct sk_buff *skb, *rx_skb;
+ struct sk_buff *skb;
+ u8 *data;
unsigned char *packet;
u16 rx_start_idx, rx_idx;
dma_addr_t map;
- struct tx_bd *txbd;
- struct sw_bd *rx_buf;
+ struct bnx2_tx_bd *txbd;
+ struct bnx2_sw_bd *rx_buf;
struct l2_fhdr *rx_hdr;
int ret = -ENODEV;
struct bnx2_napi *bnapi = &bp->bnx2_napi[0], *tx_napi;
@@ -5352,25 +5811,29 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
if (!skb)
return -ENOMEM;
packet = skb_put(skb, pkt_size);
- memcpy(packet, bp->dev->dev_addr, 6);
- memset(packet + 6, 0x0, 8);
+ memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
+ memset(packet + ETH_ALEN, 0x0, 8);
for (i = 14; i < pkt_size; i++)
packet[i] = (unsigned char) (i & 0xff);
- map = pci_map_single(bp->pdev, skb->data, pkt_size,
- PCI_DMA_TODEVICE);
+ map = dma_map_single(&bp->pdev->dev, skb->data, pkt_size,
+ PCI_DMA_TODEVICE);
+ if (dma_mapping_error(&bp->pdev->dev, map)) {
+ dev_kfree_skb(skb);
+ return -EIO;
+ }
- REG_WR(bp, BNX2_HC_COMMAND,
- bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
+ BNX2_WR(bp, BNX2_HC_COMMAND,
+ bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
- REG_RD(bp, BNX2_HC_COMMAND);
+ BNX2_RD(bp, BNX2_HC_COMMAND);
udelay(5);
rx_start_idx = bnx2_get_hw_rx_cons(bnapi);
num_pkts = 0;
- txbd = &txr->tx_desc_ring[TX_RING_IDX(txr->tx_prod)];
+ txbd = &txr->tx_desc_ring[BNX2_TX_RING_IDX(txr->tx_prod)];
txbd->tx_bd_haddr_hi = (u64) map >> 32;
txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff;
@@ -5378,22 +5841,22 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END;
num_pkts++;
- txr->tx_prod = NEXT_TX_BD(txr->tx_prod);
+ txr->tx_prod = BNX2_NEXT_TX_BD(txr->tx_prod);
txr->tx_prod_bseq += pkt_size;
- REG_WR16(bp, txr->tx_bidx_addr, txr->tx_prod);
- REG_WR(bp, txr->tx_bseq_addr, txr->tx_prod_bseq);
+ BNX2_WR16(bp, txr->tx_bidx_addr, txr->tx_prod);
+ BNX2_WR(bp, txr->tx_bseq_addr, txr->tx_prod_bseq);
udelay(100);
- REG_WR(bp, BNX2_HC_COMMAND,
- bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
+ BNX2_WR(bp, BNX2_HC_COMMAND,
+ bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
- REG_RD(bp, BNX2_HC_COMMAND);
+ BNX2_RD(bp, BNX2_HC_COMMAND);
udelay(5);
- pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
+ dma_unmap_single(&bp->pdev->dev, map, pkt_size, PCI_DMA_TODEVICE);
dev_kfree_skb(skb);
if (bnx2_get_hw_tx_cons(tx_napi) != txr->tx_prod)
@@ -5405,14 +5868,14 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
}
rx_buf = &rxr->rx_buf_ring[rx_start_idx];
- rx_skb = rx_buf->skb;
+ data = rx_buf->data;
- rx_hdr = (struct l2_fhdr *) rx_skb->data;
- skb_reserve(rx_skb, BNX2_RX_OFFSET);
+ rx_hdr = get_l2_fhdr(data);
+ data = (u8 *)rx_hdr + BNX2_RX_OFFSET;
- pci_dma_sync_single_for_cpu(bp->pdev,
- pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size, PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
if (rx_hdr->l2_fhdr_status &
(L2_FHDR_ERRORS_BAD_CRC |
@@ -5429,7 +5892,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
}
for (i = 14; i < pkt_size; i++) {
- if (*(rx_skb->data + i) != (unsigned char) (i & 0xff)) {
+ if (*(data + i) != (unsigned char) (i & 0xff)) {
goto loopback_test_done;
}
}
@@ -5508,6 +5971,9 @@ bnx2_test_link(struct bnx2 *bp)
{
u32 bmsr;
+ if (!netif_running(bp->dev))
+ return -ENODEV;
+
if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) {
if (bp->link_up)
return 0;
@@ -5535,14 +6001,14 @@ bnx2_test_intr(struct bnx2 *bp)
if (!netif_running(bp->dev))
return -ENODEV;
- status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff;
+ status_idx = BNX2_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff;
/* This register is not touched during run-time. */
- REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
- REG_RD(bp, BNX2_HC_COMMAND);
+ BNX2_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
+ BNX2_RD(bp, BNX2_HC_COMMAND);
for (i = 0; i < 10; i++) {
- if ((REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff) !=
+ if ((BNX2_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff) !=
status_idx) {
break;
@@ -5600,7 +6066,7 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
} else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
u32 bmcr;
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
@@ -5629,7 +6095,7 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
}
} else
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
if (check_link) {
u32 val;
@@ -5670,15 +6136,15 @@ bnx2_5708_serdes_timer(struct bnx2 *bp)
bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
if (bmcr & BMCR_ANENABLE) {
bnx2_enable_forced_2g5(bp);
- bp->current_interval = SERDES_FORCED_TIMEOUT;
+ bp->current_interval = BNX2_SERDES_FORCED_TIMEOUT;
} else {
bnx2_disable_forced_2g5(bp);
bp->serdes_an_pending = 2;
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
}
} else
- bp->current_interval = bp->timer_interval;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
spin_unlock(&bp->phy_lock);
}
@@ -5694,18 +6160,22 @@ bnx2_timer(unsigned long data)
if (atomic_read(&bp->intr_sem) != 0)
goto bnx2_restart_timer;
+ if ((bp->flags & (BNX2_FLAG_USING_MSI | BNX2_FLAG_ONE_SHOT_MSI)) ==
+ BNX2_FLAG_USING_MSI)
+ bnx2_chk_missed_msi(bp);
+
bnx2_send_heart_beat(bp);
bp->stats_blk->stat_FwRxDrop =
bnx2_reg_rd_ind(bp, BNX2_FW_RX_DROP_COUNT);
/* workaround occasional corrupted counters */
- if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
- REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
- BNX2_HC_COMMAND_STATS_NOW);
+ if ((bp->flags & BNX2_FLAG_BROKEN_STATS) && bp->stats_ticks)
+ BNX2_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
+ BNX2_HC_COMMAND_STATS_NOW);
if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
- if (CHIP_NUM(bp) == CHIP_NUM_5706)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5706)
bnx2_5706_serdes_timer(bp);
else
bnx2_5708_serdes_timer(bp);
@@ -5739,7 +6209,7 @@ bnx2_request_irq(struct bnx2 *bp)
}
static void
-bnx2_free_irq(struct bnx2 *bp)
+__bnx2_free_irq(struct bnx2 *bp)
{
struct bnx2_irq *irq;
int i;
@@ -5750,6 +6220,13 @@ bnx2_free_irq(struct bnx2 *bp)
free_irq(irq->vector, &bp->bnx2_napi[i]);
irq->requested = 0;
}
+}
+
+static void
+bnx2_free_irq(struct bnx2 *bp)
+{
+
+ __bnx2_free_irq(bp);
if (bp->flags & BNX2_FLAG_USING_MSI)
pci_disable_msi(bp->pdev);
else if (bp->flags & BNX2_FLAG_USING_MSIX)
@@ -5761,51 +6238,75 @@ bnx2_free_irq(struct bnx2 *bp)
static void
bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
{
- int i, rc;
+ int i, total_vecs;
struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
+ struct net_device *dev = bp->dev;
+ const int len = sizeof(bp->irq_tbl[0].name);
bnx2_setup_msix_tbl(bp);
- REG_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1);
- REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE);
- REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE);
+ BNX2_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1);
+ BNX2_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE);
+ BNX2_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE);
+
+ /* Need to flush the previous three writes to ensure MSI-X
+ * is setup properly */
+ BNX2_RD(bp, BNX2_PCI_MSIX_CONTROL);
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
msix_ent[i].entry = i;
msix_ent[i].vector = 0;
-
- strcpy(bp->irq_tbl[i].name, bp->dev->name);
- bp->irq_tbl[i].handler = bnx2_msi_1shot;
}
- rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
- if (rc != 0)
+ total_vecs = msix_vecs;
+#ifdef BCM_CNIC
+ total_vecs++;
+#endif
+ total_vecs = pci_enable_msix_range(bp->pdev, msix_ent,
+ BNX2_MIN_MSIX_VEC, total_vecs);
+ if (total_vecs < 0)
return;
+ msix_vecs = total_vecs;
+#ifdef BCM_CNIC
+ msix_vecs--;
+#endif
bp->irq_nvecs = msix_vecs;
bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
- for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
+ for (i = 0; i < total_vecs; i++) {
bp->irq_tbl[i].vector = msix_ent[i].vector;
+ snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
+ bp->irq_tbl[i].handler = bnx2_msi_1shot;
+ }
}
-static void
+static int
bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
{
- int cpus = num_online_cpus();
- int msix_vecs = min(cpus + 1, RX_MAX_RINGS);
+ int cpus = netif_get_num_default_rss_queues();
+ int msix_vecs;
+
+ if (!bp->num_req_rx_rings)
+ msix_vecs = max(cpus + 1, bp->num_req_tx_rings);
+ else if (!bp->num_req_tx_rings)
+ msix_vecs = max(cpus, bp->num_req_rx_rings);
+ else
+ msix_vecs = max(bp->num_req_rx_rings, bp->num_req_tx_rings);
+
+ msix_vecs = min(msix_vecs, RX_MAX_RINGS);
bp->irq_tbl[0].handler = bnx2_interrupt;
strcpy(bp->irq_tbl[0].name, bp->dev->name);
bp->irq_nvecs = 1;
bp->irq_tbl[0].vector = bp->pdev->irq;
- if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi && cpus > 1)
+ if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi)
bnx2_enable_msix(bp, msix_vecs);
if ((bp->flags & BNX2_FLAG_MSI_CAP) && !dis_msi &&
!(bp->flags & BNX2_FLAG_USING_MSIX)) {
if (pci_enable_msi(bp->pdev) == 0) {
bp->flags |= BNX2_FLAG_USING_MSI;
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
bp->flags |= BNX2_FLAG_ONE_SHOT_MSI;
bp->irq_tbl[0].handler = bnx2_msi_1shot;
} else
@@ -5815,10 +6316,19 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
}
}
- bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
- bp->dev->real_num_tx_queues = bp->num_tx_rings;
+ if (!bp->num_req_tx_rings)
+ bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
+ else
+ bp->num_tx_rings = min(bp->irq_nvecs, bp->num_req_tx_rings);
+
+ if (!bp->num_req_rx_rings)
+ bp->num_rx_rings = bp->irq_nvecs;
+ else
+ bp->num_rx_rings = min(bp->irq_nvecs, bp->num_req_rx_rings);
+
+ netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings);
- bp->num_rx_rings = bp->irq_nvecs;
+ return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings);
}
/* Called with rtnl_lock */
@@ -5828,12 +6338,18 @@ bnx2_open(struct net_device *dev)
struct bnx2 *bp = netdev_priv(dev);
int rc;
+ rc = bnx2_request_firmware(bp);
+ if (rc < 0)
+ goto out;
+
netif_carrier_off(dev);
- bnx2_set_power_state(bp, PCI_D0);
bnx2_disable_int(bp);
- bnx2_setup_int_mode(bp, disable_msi);
+ rc = bnx2_setup_int_mode(bp, disable_msi);
+ if (rc)
+ goto open_err;
+ bnx2_init_napi(bp);
bnx2_napi_enable(bp);
rc = bnx2_alloc_mem(bp);
if (rc)
@@ -5851,6 +6367,8 @@ bnx2_open(struct net_device *dev)
atomic_set(&bp->intr_sem, 0);
+ memset(bp->temp_stats_blk, 0, sizeof(struct statistics_block));
+
bnx2_enable_int(bp);
if (bp->flags & BNX2_FLAG_USING_MSI) {
@@ -5858,11 +6376,7 @@ bnx2_open(struct net_device *dev)
* If MSI test fails, go back to INTx mode
*/
if (bnx2_test_intr(bp) != 0) {
- printk(KERN_WARNING PFX "%s: No interrupt was generated"
- " using MSI, switching to INTx mode. Please"
- " report this failure to the PCI maintainer"
- " and include system chipset information.\n",
- bp->dev->name);
+ netdev_warn(bp->dev, "No interrupt was generated using MSI, switching to INTx mode. Please report this failure to the PCI maintainer and include system chipset information.\n");
bnx2_disable_int(bp);
bnx2_free_irq(bp);
@@ -5882,76 +6396,176 @@ bnx2_open(struct net_device *dev)
}
}
if (bp->flags & BNX2_FLAG_USING_MSI)
- printk(KERN_INFO PFX "%s: using MSI\n", dev->name);
+ netdev_info(dev, "using MSI\n");
else if (bp->flags & BNX2_FLAG_USING_MSIX)
- printk(KERN_INFO PFX "%s: using MSIX\n", dev->name);
+ netdev_info(dev, "using MSIX\n");
netif_tx_start_all_queues(dev);
-
- return 0;
+out:
+ return rc;
open_err:
bnx2_napi_disable(bp);
bnx2_free_skbs(bp);
bnx2_free_irq(bp);
bnx2_free_mem(bp);
- return rc;
+ bnx2_del_napi(bp);
+ bnx2_release_firmware(bp);
+ goto out;
}
static void
bnx2_reset_task(struct work_struct *work)
{
struct bnx2 *bp = container_of(work, struct bnx2, reset_task);
+ int rc;
+ u16 pcicmd;
- if (!netif_running(bp->dev))
+ rtnl_lock();
+ if (!netif_running(bp->dev)) {
+ rtnl_unlock();
return;
+ }
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
- bnx2_init_nic(bp, 1);
+ pci_read_config_word(bp->pdev, PCI_COMMAND, &pcicmd);
+ if (!(pcicmd & PCI_COMMAND_MEMORY)) {
+ /* in case PCI block has reset */
+ pci_restore_state(bp->pdev);
+ pci_save_state(bp->pdev);
+ }
+ rc = bnx2_init_nic(bp, 1);
+ if (rc) {
+ netdev_err(bp->dev, "failed to reset NIC, closing\n");
+ bnx2_napi_enable(bp);
+ dev_close(bp->dev);
+ rtnl_unlock();
+ return;
+ }
atomic_set(&bp->intr_sem, 1);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
+ rtnl_unlock();
}
+#define BNX2_FTQ_ENTRY(ftq) { __stringify(ftq##FTQ_CTL), BNX2_##ftq##FTQ_CTL }
+
static void
-bnx2_tx_timeout(struct net_device *dev)
+bnx2_dump_ftq(struct bnx2 *bp)
{
- struct bnx2 *bp = netdev_priv(dev);
+ int i;
+ u32 reg, bdidx, cid, valid;
+ struct net_device *dev = bp->dev;
+ static const struct ftq_reg {
+ char *name;
+ u32 off;
+ } ftq_arr[] = {
+ BNX2_FTQ_ENTRY(RV2P_P),
+ BNX2_FTQ_ENTRY(RV2P_T),
+ BNX2_FTQ_ENTRY(RV2P_M),
+ BNX2_FTQ_ENTRY(TBDR_),
+ BNX2_FTQ_ENTRY(TDMA_),
+ BNX2_FTQ_ENTRY(TXP_),
+ BNX2_FTQ_ENTRY(TXP_),
+ BNX2_FTQ_ENTRY(TPAT_),
+ BNX2_FTQ_ENTRY(RXP_C),
+ BNX2_FTQ_ENTRY(RXP_),
+ BNX2_FTQ_ENTRY(COM_COMXQ_),
+ BNX2_FTQ_ENTRY(COM_COMTQ_),
+ BNX2_FTQ_ENTRY(COM_COMQ_),
+ BNX2_FTQ_ENTRY(CP_CPQ_),
+ };
- /* This allows the netif to be shutdown gracefully before resetting */
- schedule_work(&bp->reset_task);
+ netdev_err(dev, "<--- start FTQ dump --->\n");
+ for (i = 0; i < ARRAY_SIZE(ftq_arr); i++)
+ netdev_err(dev, "%s %08x\n", ftq_arr[i].name,
+ bnx2_reg_rd_ind(bp, ftq_arr[i].off));
+
+ netdev_err(dev, "CPU states:\n");
+ for (reg = BNX2_TXP_CPU_MODE; reg <= BNX2_CP_CPU_MODE; reg += 0x40000)
+ netdev_err(dev, "%06x mode %x state %x evt_mask %x pc %x pc %x instr %x\n",
+ reg, bnx2_reg_rd_ind(bp, reg),
+ bnx2_reg_rd_ind(bp, reg + 4),
+ bnx2_reg_rd_ind(bp, reg + 8),
+ bnx2_reg_rd_ind(bp, reg + 0x1c),
+ bnx2_reg_rd_ind(bp, reg + 0x1c),
+ bnx2_reg_rd_ind(bp, reg + 0x20));
+
+ netdev_err(dev, "<--- end FTQ dump --->\n");
+ netdev_err(dev, "<--- start TBDC dump --->\n");
+ netdev_err(dev, "TBDC free cnt: %ld\n",
+ BNX2_RD(bp, BNX2_TBDC_STATUS) & BNX2_TBDC_STATUS_FREE_CNT);
+ netdev_err(dev, "LINE CID BIDX CMD VALIDS\n");
+ for (i = 0; i < 0x20; i++) {
+ int j = 0;
+
+ BNX2_WR(bp, BNX2_TBDC_BD_ADDR, i);
+ BNX2_WR(bp, BNX2_TBDC_CAM_OPCODE,
+ BNX2_TBDC_CAM_OPCODE_OPCODE_CAM_READ);
+ BNX2_WR(bp, BNX2_TBDC_COMMAND, BNX2_TBDC_COMMAND_CMD_REG_ARB);
+ while ((BNX2_RD(bp, BNX2_TBDC_COMMAND) &
+ BNX2_TBDC_COMMAND_CMD_REG_ARB) && j < 100)
+ j++;
+
+ cid = BNX2_RD(bp, BNX2_TBDC_CID);
+ bdidx = BNX2_RD(bp, BNX2_TBDC_BIDX);
+ valid = BNX2_RD(bp, BNX2_TBDC_CAM_OPCODE);
+ netdev_err(dev, "%02x %06x %04lx %02x [%x]\n",
+ i, cid, bdidx & BNX2_TBDC_BDIDX_BDIDX,
+ bdidx >> 24, (valid >> 8) & 0x0ff);
+ }
+ netdev_err(dev, "<--- end TBDC dump --->\n");
}
-#ifdef BCM_VLAN
-/* Called with rtnl_lock */
static void
-bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
+bnx2_dump_state(struct bnx2 *bp)
{
- struct bnx2 *bp = netdev_priv(dev);
+ struct net_device *dev = bp->dev;
+ u32 val1, val2;
+
+ pci_read_config_dword(bp->pdev, PCI_COMMAND, &val1);
+ netdev_err(dev, "DEBUG: intr_sem[%x] PCI_CMD[%08x]\n",
+ atomic_read(&bp->intr_sem), val1);
+ pci_read_config_dword(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &val1);
+ pci_read_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, &val2);
+ netdev_err(dev, "DEBUG: PCI_PM[%08x] PCI_MISC_CFG[%08x]\n", val1, val2);
+ netdev_err(dev, "DEBUG: EMAC_TX_STATUS[%08x] EMAC_RX_STATUS[%08x]\n",
+ BNX2_RD(bp, BNX2_EMAC_TX_STATUS),
+ BNX2_RD(bp, BNX2_EMAC_RX_STATUS));
+ netdev_err(dev, "DEBUG: RPM_MGMT_PKT_CTRL[%08x]\n",
+ BNX2_RD(bp, BNX2_RPM_MGMT_PKT_CTRL));
+ netdev_err(dev, "DEBUG: HC_STATS_INTERRUPT_STATUS[%08x]\n",
+ BNX2_RD(bp, BNX2_HC_STATS_INTERRUPT_STATUS));
+ if (bp->flags & BNX2_FLAG_USING_MSIX)
+ netdev_err(dev, "DEBUG: PBA[%08x]\n",
+ BNX2_RD(bp, BNX2_PCI_GRC_WINDOW3_BASE));
+}
- bnx2_netif_stop(bp);
+static void
+bnx2_tx_timeout(struct net_device *dev)
+{
+ struct bnx2 *bp = netdev_priv(dev);
- bp->vlgrp = vlgrp;
- bnx2_set_rx_mode(dev);
- if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
- bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
+ bnx2_dump_ftq(bp);
+ bnx2_dump_state(bp);
+ bnx2_dump_mcp_state(bp);
- bnx2_netif_start(bp);
+ /* This allows the netif to be shutdown gracefully before resetting */
+ schedule_work(&bp->reset_task);
}
-#endif
/* Called with netif_tx_lock.
* bnx2_tx_int() runs without netif_tx_lock unless it needs to call
* netif_wake_queue().
*/
-static int
+static netdev_tx_t
bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
dma_addr_t mapping;
- struct tx_bd *txbd;
- struct sw_bd *tx_buf;
+ struct bnx2_tx_bd *txbd;
+ struct bnx2_sw_tx_bd *tx_buf;
u32 len, vlan_tag_flags, last_frag, mss;
u16 prod, ring_prod;
int i;
@@ -5968,28 +6582,26 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(bnx2_tx_avail(bp, txr) <
(skb_shinfo(skb)->nr_frags + 1))) {
netif_tx_stop_queue(txq);
- printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
- dev->name);
+ netdev_err(dev, "BUG! Tx ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
len = skb_headlen(skb);
prod = txr->tx_prod;
- ring_prod = TX_RING_IDX(prod);
+ ring_prod = BNX2_TX_RING_IDX(prod);
vlan_tag_flags = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
}
-#ifdef BCM_VLAN
- if (bp->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
vlan_tag_flags |=
(TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
}
-#endif
+
if ((mss = skb_shinfo(skb)->gso_size)) {
- u32 tcp_opt_len, ip_tcp_len;
+ u32 tcp_opt_len;
struct iphdr *iph;
vlan_tag_flags |= TX_BD_FLAGS_SW_LSO;
@@ -6013,21 +6625,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
mss |= (tcp_off & 0xc) << TX_BD_TCP6_OFF2_SHL;
}
} else {
- if (skb_header_cloned(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
-
- ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
-
iph = ip_hdr(skb);
- iph->check = 0;
- iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
- tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
- iph->daddr, 0,
- IPPROTO_TCP,
- 0);
if (tcp_opt_len || (iph->ihl > 5)) {
vlan_tag_flags |= ((iph->ihl - 5) +
(tcp_opt_len >> 2)) << 8;
@@ -6036,11 +6634,15 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
} else
mss = 0;
- mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ mapping = dma_map_single(&bp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE);
+ if (dma_mapping_error(&bp->pdev->dev, mapping)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
tx_buf = &txr->tx_buf_ring[ring_prod];
tx_buf->skb = skb;
- pci_unmap_addr_set(tx_buf, mapping, mapping);
+ dma_unmap_addr_set(tx_buf, mapping, mapping);
txbd = &txr->tx_desc_ring[ring_prod];
@@ -6050,19 +6652,23 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbd->tx_bd_vlan_tag_flags = vlan_tag_flags | TX_BD_FLAGS_START;
last_frag = skb_shinfo(skb)->nr_frags;
+ tx_buf->nr_frags = last_frag;
+ tx_buf->is_gso = skb_is_gso(skb);
for (i = 0; i < last_frag; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- prod = NEXT_TX_BD(prod);
- ring_prod = TX_RING_IDX(prod);
+ prod = BNX2_NEXT_TX_BD(prod);
+ ring_prod = BNX2_TX_RING_IDX(prod);
txbd = &txr->tx_desc_ring[ring_prod];
- len = frag->size;
- mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
- len, PCI_DMA_TODEVICE);
- pci_unmap_addr_set(&txr->tx_buf_ring[ring_prod],
- mapping, mapping);
+ len = skb_frag_size(frag);
+ mapping = skb_frag_dma_map(&bp->pdev->dev, frag, 0, len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(&bp->pdev->dev, mapping))
+ goto dma_error;
+ dma_unmap_addr_set(&txr->tx_buf_ring[ring_prod], mapping,
+ mapping);
txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
@@ -6072,24 +6678,59 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END;
- prod = NEXT_TX_BD(prod);
+ /* Sync BD data before updating TX mailbox */
+ wmb();
+
+ netdev_tx_sent_queue(txq, skb->len);
+
+ prod = BNX2_NEXT_TX_BD(prod);
txr->tx_prod_bseq += skb->len;
- REG_WR16(bp, txr->tx_bidx_addr, prod);
- REG_WR(bp, txr->tx_bseq_addr, txr->tx_prod_bseq);
+ BNX2_WR16(bp, txr->tx_bidx_addr, prod);
+ BNX2_WR(bp, txr->tx_bseq_addr, txr->tx_prod_bseq);
mmiowb();
txr->tx_prod = prod;
- dev->trans_start = jiffies;
if (unlikely(bnx2_tx_avail(bp, txr) <= MAX_SKB_FRAGS)) {
netif_tx_stop_queue(txq);
+
+ /* netif_tx_stop_queue() must be done before checking
+ * tx index in bnx2_tx_avail() below, because in
+ * bnx2_tx_int(), we update tx index before checking for
+ * netif_tx_queue_stopped().
+ */
+ smp_mb();
if (bnx2_tx_avail(bp, txr) > bp->tx_wake_thresh)
netif_tx_wake_queue(txq);
}
return NETDEV_TX_OK;
+dma_error:
+ /* save value of frag that failed */
+ last_frag = i;
+
+ /* start back at beginning and unmap skb */
+ prod = txr->tx_prod;
+ ring_prod = BNX2_TX_RING_IDX(prod);
+ tx_buf = &txr->tx_buf_ring[ring_prod];
+ tx_buf->skb = NULL;
+ dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping),
+ skb_headlen(skb), PCI_DMA_TODEVICE);
+
+ /* unmap remaining mapped pages */
+ for (i = 0; i < last_frag; i++) {
+ prod = BNX2_NEXT_TX_BD(prod);
+ ring_prod = BNX2_TX_RING_IDX(prod);
+ tx_buf = &txr->tx_buf_ring[ring_prod];
+ dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(tx_buf, mapping),
+ skb_frag_size(&skb_shinfo(skb)->frags[i]),
+ PCI_DMA_TODEVICE);
+ }
+
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
}
/* Called with rtnl_lock */
@@ -6097,114 +6738,125 @@ static int
bnx2_close(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
- u32 reset_code;
-
- cancel_work_sync(&bp->reset_task);
bnx2_disable_int_sync(bp);
bnx2_napi_disable(bp);
+ netif_tx_disable(dev);
del_timer_sync(&bp->timer);
- if (bp->flags & BNX2_FLAG_NO_WOL)
- reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
- else if (bp->wol)
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
- else
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
- bnx2_reset_chip(bp, reset_code);
+ bnx2_shutdown_chip(bp);
bnx2_free_irq(bp);
bnx2_free_skbs(bp);
bnx2_free_mem(bp);
+ bnx2_del_napi(bp);
bp->link_up = 0;
netif_carrier_off(bp->dev);
- bnx2_set_power_state(bp, PCI_D3hot);
return 0;
}
-#define GET_NET_STATS64(ctr) \
- (unsigned long) ((unsigned long) (ctr##_hi) << 32) + \
- (unsigned long) (ctr##_lo)
+static void
+bnx2_save_stats(struct bnx2 *bp)
+{
+ u32 *hw_stats = (u32 *) bp->stats_blk;
+ u32 *temp_stats = (u32 *) bp->temp_stats_blk;
+ int i;
-#define GET_NET_STATS32(ctr) \
- (ctr##_lo)
+ /* The 1st 10 counters are 64-bit counters */
+ for (i = 0; i < 20; i += 2) {
+ u32 hi;
+ u64 lo;
-#if (BITS_PER_LONG == 64)
-#define GET_NET_STATS GET_NET_STATS64
-#else
-#define GET_NET_STATS GET_NET_STATS32
-#endif
+ hi = temp_stats[i] + hw_stats[i];
+ lo = (u64) temp_stats[i + 1] + (u64) hw_stats[i + 1];
+ if (lo > 0xffffffff)
+ hi++;
+ temp_stats[i] = hi;
+ temp_stats[i + 1] = lo & 0xffffffff;
+ }
+
+ for ( ; i < sizeof(struct statistics_block) / 4; i++)
+ temp_stats[i] += hw_stats[i];
+}
-static struct net_device_stats *
-bnx2_get_stats(struct net_device *dev)
+#define GET_64BIT_NET_STATS64(ctr) \
+ (((u64) (ctr##_hi) << 32) + (u64) (ctr##_lo))
+
+#define GET_64BIT_NET_STATS(ctr) \
+ GET_64BIT_NET_STATS64(bp->stats_blk->ctr) + \
+ GET_64BIT_NET_STATS64(bp->temp_stats_blk->ctr)
+
+#define GET_32BIT_NET_STATS(ctr) \
+ (unsigned long) (bp->stats_blk->ctr + \
+ bp->temp_stats_blk->ctr)
+
+static struct rtnl_link_stats64 *
+bnx2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats)
{
struct bnx2 *bp = netdev_priv(dev);
- struct statistics_block *stats_blk = bp->stats_blk;
- struct net_device_stats *net_stats = &bp->net_stats;
- if (bp->stats_blk == NULL) {
+ if (bp->stats_blk == NULL)
return net_stats;
- }
+
net_stats->rx_packets =
- GET_NET_STATS(stats_blk->stat_IfHCInUcastPkts) +
- GET_NET_STATS(stats_blk->stat_IfHCInMulticastPkts) +
- GET_NET_STATS(stats_blk->stat_IfHCInBroadcastPkts);
+ GET_64BIT_NET_STATS(stat_IfHCInUcastPkts) +
+ GET_64BIT_NET_STATS(stat_IfHCInMulticastPkts) +
+ GET_64BIT_NET_STATS(stat_IfHCInBroadcastPkts);
net_stats->tx_packets =
- GET_NET_STATS(stats_blk->stat_IfHCOutUcastPkts) +
- GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts) +
- GET_NET_STATS(stats_blk->stat_IfHCOutBroadcastPkts);
+ GET_64BIT_NET_STATS(stat_IfHCOutUcastPkts) +
+ GET_64BIT_NET_STATS(stat_IfHCOutMulticastPkts) +
+ GET_64BIT_NET_STATS(stat_IfHCOutBroadcastPkts);
net_stats->rx_bytes =
- GET_NET_STATS(stats_blk->stat_IfHCInOctets);
+ GET_64BIT_NET_STATS(stat_IfHCInOctets);
net_stats->tx_bytes =
- GET_NET_STATS(stats_blk->stat_IfHCOutOctets);
+ GET_64BIT_NET_STATS(stat_IfHCOutOctets);
net_stats->multicast =
- GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts);
+ GET_64BIT_NET_STATS(stat_IfHCInMulticastPkts);
net_stats->collisions =
- (unsigned long) stats_blk->stat_EtherStatsCollisions;
+ GET_32BIT_NET_STATS(stat_EtherStatsCollisions);
net_stats->rx_length_errors =
- (unsigned long) (stats_blk->stat_EtherStatsUndersizePkts +
- stats_blk->stat_EtherStatsOverrsizePkts);
+ GET_32BIT_NET_STATS(stat_EtherStatsUndersizePkts) +
+ GET_32BIT_NET_STATS(stat_EtherStatsOverrsizePkts);
net_stats->rx_over_errors =
- (unsigned long) stats_blk->stat_IfInMBUFDiscards;
+ GET_32BIT_NET_STATS(stat_IfInFTQDiscards) +
+ GET_32BIT_NET_STATS(stat_IfInMBUFDiscards);
net_stats->rx_frame_errors =
- (unsigned long) stats_blk->stat_Dot3StatsAlignmentErrors;
+ GET_32BIT_NET_STATS(stat_Dot3StatsAlignmentErrors);
net_stats->rx_crc_errors =
- (unsigned long) stats_blk->stat_Dot3StatsFCSErrors;
+ GET_32BIT_NET_STATS(stat_Dot3StatsFCSErrors);
net_stats->rx_errors = net_stats->rx_length_errors +
net_stats->rx_over_errors + net_stats->rx_frame_errors +
net_stats->rx_crc_errors;
net_stats->tx_aborted_errors =
- (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions +
- stats_blk->stat_Dot3StatsLateCollisions);
+ GET_32BIT_NET_STATS(stat_Dot3StatsExcessiveCollisions) +
+ GET_32BIT_NET_STATS(stat_Dot3StatsLateCollisions);
- if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
- (CHIP_ID(bp) == CHIP_ID_5708_A0))
+ if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_A0))
net_stats->tx_carrier_errors = 0;
else {
net_stats->tx_carrier_errors =
- (unsigned long)
- stats_blk->stat_Dot3StatsCarrierSenseErrors;
+ GET_32BIT_NET_STATS(stat_Dot3StatsCarrierSenseErrors);
}
net_stats->tx_errors =
- (unsigned long)
- stats_blk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
- +
+ GET_32BIT_NET_STATS(stat_emac_tx_stat_dot3statsinternalmactransmiterrors) +
net_stats->tx_aborted_errors +
net_stats->tx_carrier_errors;
net_stats->rx_missed_errors =
- (unsigned long) (stats_blk->stat_IfInMBUFDiscards +
- stats_blk->stat_FwRxDrop);
+ GET_32BIT_NET_STATS(stat_IfInFTQDiscards) +
+ GET_32BIT_NET_STATS(stat_IfInMBUFDiscards) +
+ GET_32BIT_NET_STATS(stat_FwRxDrop);
return net_stats;
}
@@ -6249,18 +6901,23 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (bp->autoneg & AUTONEG_SPEED) {
cmd->autoneg = AUTONEG_ENABLE;
- }
- else {
+ } else {
cmd->autoneg = AUTONEG_DISABLE;
}
if (netif_carrier_ok(dev)) {
- cmd->speed = bp->line_speed;
+ ethtool_cmd_speed_set(cmd, bp->line_speed);
cmd->duplex = bp->duplex;
+ if (!(bp->phy_flags & BNX2_PHY_FLAG_SERDES)) {
+ if (bp->phy_flags & BNX2_PHY_FLAG_MDIX)
+ cmd->eth_tp_mdix = ETH_TP_MDI_X;
+ else
+ cmd->eth_tp_mdix = ETH_TP_MDI;
+ }
}
else {
- cmd->speed = -1;
- cmd->duplex = -1;
+ ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
+ cmd->duplex = DUPLEX_UNKNOWN;
}
spin_unlock_bh(&bp->phy_lock);
@@ -6298,51 +6955,34 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (cmd->autoneg == AUTONEG_ENABLE) {
autoneg |= AUTONEG_SPEED;
- cmd->advertising &= ETHTOOL_ALL_COPPER_SPEED;
-
- /* allow advertising 1 speed */
- if ((cmd->advertising == ADVERTISED_10baseT_Half) ||
- (cmd->advertising == ADVERTISED_10baseT_Full) ||
- (cmd->advertising == ADVERTISED_100baseT_Half) ||
- (cmd->advertising == ADVERTISED_100baseT_Full)) {
-
- if (cmd->port == PORT_FIBRE)
- goto err_out_unlock;
-
- advertising = cmd->advertising;
-
- } else if (cmd->advertising == ADVERTISED_2500baseX_Full) {
- if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) ||
- (cmd->port == PORT_TP))
- goto err_out_unlock;
- } else if (cmd->advertising == ADVERTISED_1000baseT_Full)
- advertising = cmd->advertising;
- else if (cmd->advertising == ADVERTISED_1000baseT_Half)
- goto err_out_unlock;
- else {
- if (cmd->port == PORT_FIBRE)
- advertising = ETHTOOL_ALL_FIBRE_SPEED;
- else
+ advertising = cmd->advertising;
+ if (cmd->port == PORT_TP) {
+ advertising &= ETHTOOL_ALL_COPPER_SPEED;
+ if (!advertising)
advertising = ETHTOOL_ALL_COPPER_SPEED;
+ } else {
+ advertising &= ETHTOOL_ALL_FIBRE_SPEED;
+ if (!advertising)
+ advertising = ETHTOOL_ALL_FIBRE_SPEED;
}
advertising |= ADVERTISED_Autoneg;
}
else {
+ u32 speed = ethtool_cmd_speed(cmd);
if (cmd->port == PORT_FIBRE) {
- if ((cmd->speed != SPEED_1000 &&
- cmd->speed != SPEED_2500) ||
+ if ((speed != SPEED_1000 &&
+ speed != SPEED_2500) ||
(cmd->duplex != DUPLEX_FULL))
goto err_out_unlock;
- if (cmd->speed == SPEED_2500 &&
+ if (speed == SPEED_2500 &&
!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
goto err_out_unlock;
- }
- else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500)
+ } else if (speed == SPEED_1000 || speed == SPEED_2500)
goto err_out_unlock;
autoneg &= ~AUTONEG_SPEED;
- req_line_speed = cmd->speed;
+ req_line_speed = speed;
req_duplex = cmd->duplex;
advertising = 0;
}
@@ -6370,10 +7010,10 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct bnx2 *bp = netdev_priv(dev);
- strcpy(info->driver, DRV_MODULE_NAME);
- strcpy(info->version, DRV_MODULE_VERSION);
- strcpy(info->bus_info, pci_name(bp->pdev));
- strcpy(info->fw_version, bp->fw_version);
+ strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
+ strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
+ strlcpy(info->fw_version, bp->fw_version, sizeof(info->fw_version));
}
#define BNX2_REGDUMP_LEN (32 * 1024)
@@ -6390,28 +7030,30 @@ bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
u32 *p = _p, i, offset;
u8 *orig_p = _p;
struct bnx2 *bp = netdev_priv(dev);
- u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c,
- 0x0800, 0x0880, 0x0c00, 0x0c10,
- 0x0c30, 0x0d08, 0x1000, 0x101c,
- 0x1040, 0x1048, 0x1080, 0x10a4,
- 0x1400, 0x1490, 0x1498, 0x14f0,
- 0x1500, 0x155c, 0x1580, 0x15dc,
- 0x1600, 0x1658, 0x1680, 0x16d8,
- 0x1800, 0x1820, 0x1840, 0x1854,
- 0x1880, 0x1894, 0x1900, 0x1984,
- 0x1c00, 0x1c0c, 0x1c40, 0x1c54,
- 0x1c80, 0x1c94, 0x1d00, 0x1d84,
- 0x2000, 0x2030, 0x23c0, 0x2400,
- 0x2800, 0x2820, 0x2830, 0x2850,
- 0x2b40, 0x2c10, 0x2fc0, 0x3058,
- 0x3c00, 0x3c94, 0x4000, 0x4010,
- 0x4080, 0x4090, 0x43c0, 0x4458,
- 0x4c00, 0x4c18, 0x4c40, 0x4c54,
- 0x4fc0, 0x5010, 0x53c0, 0x5444,
- 0x5c00, 0x5c18, 0x5c80, 0x5c90,
- 0x5fc0, 0x6000, 0x6400, 0x6428,
- 0x6800, 0x6848, 0x684c, 0x6860,
- 0x6888, 0x6910, 0x8000 };
+ static const u32 reg_boundaries[] = {
+ 0x0000, 0x0098, 0x0400, 0x045c,
+ 0x0800, 0x0880, 0x0c00, 0x0c10,
+ 0x0c30, 0x0d08, 0x1000, 0x101c,
+ 0x1040, 0x1048, 0x1080, 0x10a4,
+ 0x1400, 0x1490, 0x1498, 0x14f0,
+ 0x1500, 0x155c, 0x1580, 0x15dc,
+ 0x1600, 0x1658, 0x1680, 0x16d8,
+ 0x1800, 0x1820, 0x1840, 0x1854,
+ 0x1880, 0x1894, 0x1900, 0x1984,
+ 0x1c00, 0x1c0c, 0x1c40, 0x1c54,
+ 0x1c80, 0x1c94, 0x1d00, 0x1d84,
+ 0x2000, 0x2030, 0x23c0, 0x2400,
+ 0x2800, 0x2820, 0x2830, 0x2850,
+ 0x2b40, 0x2c10, 0x2fc0, 0x3058,
+ 0x3c00, 0x3c94, 0x4000, 0x4010,
+ 0x4080, 0x4090, 0x43c0, 0x4458,
+ 0x4c00, 0x4c18, 0x4c40, 0x4c54,
+ 0x4fc0, 0x5010, 0x53c0, 0x5444,
+ 0x5c00, 0x5c18, 0x5c80, 0x5c90,
+ 0x5fc0, 0x6000, 0x6400, 0x6428,
+ 0x6800, 0x6848, 0x684c, 0x6860,
+ 0x6888, 0x6910, 0x8000
+ };
regs->version = 0;
@@ -6424,7 +7066,7 @@ bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
offset = reg_boundaries[0];
p += offset;
while (offset < BNX2_REGDUMP_LEN) {
- *p++ = REG_RD(bp, offset);
+ *p++ = BNX2_RD(bp, offset);
offset += 4;
if (offset == reg_boundaries[i + 1]) {
offset = reg_boundaries[i + 2];
@@ -6470,6 +7112,9 @@ bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
else {
bp->wol = 0;
}
+
+ device_set_wakeup_enable(&bp->pdev->dev, bp->wol);
+
return 0;
}
@@ -6479,6 +7124,9 @@ bnx2_nway_reset(struct net_device *dev)
struct bnx2 *bp = netdev_priv(dev);
u32 bmcr;
+ if (!netif_running(dev))
+ return -EAGAIN;
+
if (!(bp->autoneg & AUTONEG_SPEED)) {
return -EINVAL;
}
@@ -6502,7 +7150,7 @@ bnx2_nway_reset(struct net_device *dev)
spin_lock_bh(&bp->phy_lock);
- bp->current_interval = SERDES_AN_TIMEOUT;
+ bp->current_interval = BNX2_SERDES_AN_TIMEOUT;
bp->serdes_an_pending = 1;
mod_timer(&bp->timer, jiffies + bp->current_interval);
}
@@ -6516,6 +7164,14 @@ bnx2_nway_reset(struct net_device *dev)
return 0;
}
+static u32
+bnx2_get_link(struct net_device *dev)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+
+ return bp->link_up;
+}
+
static int
bnx2_get_eeprom_len(struct net_device *dev)
{
@@ -6609,7 +7265,7 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
0xff;
bp->stats_ticks = coal->stats_block_coalesce_usecs;
- if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+ if (bp->flags & BNX2_FLAG_BROKEN_STATS) {
if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC)
bp->stats_ticks = USEC_PER_SEC;
}
@@ -6618,9 +7274,9 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
if (netif_running(bp->dev)) {
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
bnx2_init_nic(bp, 0);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
}
return 0;
@@ -6631,24 +7287,31 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
{
struct bnx2 *bp = netdev_priv(dev);
- ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT;
- ering->rx_mini_max_pending = 0;
- ering->rx_jumbo_max_pending = MAX_TOTAL_RX_PG_DESC_CNT;
+ ering->rx_max_pending = BNX2_MAX_TOTAL_RX_DESC_CNT;
+ ering->rx_jumbo_max_pending = BNX2_MAX_TOTAL_RX_PG_DESC_CNT;
ering->rx_pending = bp->rx_ring_size;
- ering->rx_mini_pending = 0;
ering->rx_jumbo_pending = bp->rx_pg_ring_size;
- ering->tx_max_pending = MAX_TX_DESC_CNT;
+ ering->tx_max_pending = BNX2_MAX_TX_DESC_CNT;
ering->tx_pending = bp->tx_ring_size;
}
static int
-bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
+bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx, bool reset_irq)
{
if (netif_running(bp->dev)) {
- bnx2_netif_stop(bp);
+ /* Reset will erase chipset stats; save them */
+ bnx2_save_stats(bp);
+
+ bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
+ if (reset_irq) {
+ bnx2_free_irq(bp);
+ bnx2_del_napi(bp);
+ } else {
+ __bnx2_free_irq(bp);
+ }
bnx2_free_skbs(bp);
bnx2_free_mem(bp);
}
@@ -6657,13 +7320,35 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
bp->tx_ring_size = tx;
if (netif_running(bp->dev)) {
- int rc;
+ int rc = 0;
- rc = bnx2_alloc_mem(bp);
- if (rc)
+ if (reset_irq) {
+ rc = bnx2_setup_int_mode(bp, disable_msi);
+ bnx2_init_napi(bp);
+ }
+
+ if (!rc)
+ rc = bnx2_alloc_mem(bp);
+
+ if (!rc)
+ rc = bnx2_request_irq(bp);
+
+ if (!rc)
+ rc = bnx2_init_nic(bp, 0);
+
+ if (rc) {
+ bnx2_napi_enable(bp);
+ dev_close(bp->dev);
return rc;
- bnx2_init_nic(bp, 0);
- bnx2_netif_start(bp);
+ }
+#ifdef BCM_CNIC
+ mutex_lock(&bp->cnic_lock);
+ /* Let cnic know about the new status block. */
+ if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD)
+ bnx2_setup_cnic_irq_info(bp);
+ mutex_unlock(&bp->cnic_lock);
+#endif
+ bnx2_netif_start(bp, true);
}
return 0;
}
@@ -6674,13 +7359,14 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
struct bnx2 *bp = netdev_priv(dev);
int rc;
- if ((ering->rx_pending > MAX_TOTAL_RX_DESC_CNT) ||
- (ering->tx_pending > MAX_TX_DESC_CNT) ||
+ if ((ering->rx_pending > BNX2_MAX_TOTAL_RX_DESC_CNT) ||
+ (ering->tx_pending > BNX2_MAX_TX_DESC_CNT) ||
(ering->tx_pending <= MAX_SKB_FRAGS)) {
return -EINVAL;
}
- rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending);
+ rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending,
+ false);
return rc;
}
@@ -6712,52 +7398,18 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
bp->autoneg &= ~AUTONEG_FLOW_CTRL;
}
- spin_lock_bh(&bp->phy_lock);
-
- bnx2_setup_phy(bp, bp->phy_port);
-
- spin_unlock_bh(&bp->phy_lock);
-
- return 0;
-}
-
-static u32
-bnx2_get_rx_csum(struct net_device *dev)
-{
- struct bnx2 *bp = netdev_priv(dev);
-
- return bp->rx_csum;
-}
-
-static int
-bnx2_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct bnx2 *bp = netdev_priv(dev);
-
- bp->rx_csum = data;
- return 0;
-}
-
-static int
-bnx2_set_tso(struct net_device *dev, u32 data)
-{
- struct bnx2 *bp = netdev_priv(dev);
+ if (netif_running(dev)) {
+ spin_lock_bh(&bp->phy_lock);
+ bnx2_setup_phy(bp, bp->phy_port);
+ spin_unlock_bh(&bp->phy_lock);
+ }
- if (data) {
- dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- dev->features |= NETIF_F_TSO6;
- } else
- dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
- NETIF_F_TSO_ECN);
return 0;
}
-#define BNX2_NUM_STATS 46
-
static struct {
char string[ETH_GSTRING_LEN];
-} bnx2_stats_str_arr[BNX2_NUM_STATS] = {
+} bnx2_stats_str_arr[] = {
{ "rx_bytes" },
{ "rx_error_bytes" },
{ "tx_bytes" },
@@ -6802,10 +7454,13 @@ static struct {
{ "tx_xoff_frames" },
{ "rx_mac_ctrl_frames" },
{ "rx_filtered_packets" },
+ { "rx_ftq_discards" },
{ "rx_discards" },
{ "rx_fw_discards" },
};
+#define BNX2_NUM_STATS ARRAY_SIZE(bnx2_stats_str_arr)
+
#define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4)
static const unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
@@ -6853,6 +7508,7 @@ static const unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
STATS_OFFSET32(stat_OutXoffSent),
STATS_OFFSET32(stat_MacControlFramesReceived),
STATS_OFFSET32(stat_IfInFramesL2FilterDiscards),
+ STATS_OFFSET32(stat_IfInFTQDiscards),
STATS_OFFSET32(stat_IfInMBUFDiscards),
STATS_OFFSET32(stat_FwRxDrop),
};
@@ -6865,7 +7521,7 @@ static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
4,0,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,
- 4,4,4,4,4,4,
+ 4,4,4,4,4,4,4,
};
static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
@@ -6873,7 +7529,7 @@ static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,
- 4,4,4,4,4,4,
+ 4,4,4,4,4,4,4,
};
#define BNX2_NUM_TESTS 6
@@ -6911,7 +7567,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
if (etest->flags & ETH_TEST_FL_OFFLINE) {
int i;
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
bnx2_free_skbs(bp);
@@ -6926,12 +7582,11 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
if ((buf[2] = bnx2_test_loopback(bp)) != 0)
etest->flags |= ETH_TEST_FL_FAILED;
- if (!netif_running(bp->dev)) {
- bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
- }
+ if (!netif_running(bp->dev))
+ bnx2_shutdown_chip(bp);
else {
bnx2_init_nic(bp, 1);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
}
/* wait for link up */
@@ -6980,6 +7635,7 @@ bnx2_get_ethtool_stats(struct net_device *dev,
struct bnx2 *bp = netdev_priv(dev);
int i;
u32 *hw_stats = (u32 *) bp->stats_blk;
+ u32 *temp_stats = (u32 *) bp->temp_stats_blk;
u8 *stats_len_arr = NULL;
if (hw_stats == NULL) {
@@ -6987,76 +7643,153 @@ bnx2_get_ethtool_stats(struct net_device *dev,
return;
}
- if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
- (CHIP_ID(bp) == CHIP_ID_5706_A1) ||
- (CHIP_ID(bp) == CHIP_ID_5706_A2) ||
- (CHIP_ID(bp) == CHIP_ID_5708_A0))
+ if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A2) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_A0))
stats_len_arr = bnx2_5706_stats_len_arr;
else
stats_len_arr = bnx2_5708_stats_len_arr;
for (i = 0; i < BNX2_NUM_STATS; i++) {
+ unsigned long offset;
+
if (stats_len_arr[i] == 0) {
/* skip this counter */
buf[i] = 0;
continue;
}
+
+ offset = bnx2_stats_offset_arr[i];
if (stats_len_arr[i] == 4) {
/* 4-byte counter */
- buf[i] = (u64)
- *(hw_stats + bnx2_stats_offset_arr[i]);
+ buf[i] = (u64) *(hw_stats + offset) +
+ *(temp_stats + offset);
continue;
}
/* 8-byte counter */
- buf[i] = (((u64) *(hw_stats +
- bnx2_stats_offset_arr[i])) << 32) +
- *(hw_stats + bnx2_stats_offset_arr[i] + 1);
+ buf[i] = (((u64) *(hw_stats + offset)) << 32) +
+ *(hw_stats + offset + 1) +
+ (((u64) *(temp_stats + offset)) << 32) +
+ *(temp_stats + offset + 1);
}
}
static int
-bnx2_phys_id(struct net_device *dev, u32 data)
+bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state)
{
struct bnx2 *bp = netdev_priv(dev);
- int i;
- u32 save;
- if (data == 0)
- data = 2;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ bp->leds_save = BNX2_RD(bp, BNX2_MISC_CFG);
+ BNX2_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
+ return 1; /* cycle on/off once per second */
+
+ case ETHTOOL_ID_ON:
+ BNX2_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
+ BNX2_EMAC_LED_1000MB_OVERRIDE |
+ BNX2_EMAC_LED_100MB_OVERRIDE |
+ BNX2_EMAC_LED_10MB_OVERRIDE |
+ BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
+ BNX2_EMAC_LED_TRAFFIC);
+ break;
- save = REG_RD(bp, BNX2_MISC_CFG);
- REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
+ case ETHTOOL_ID_OFF:
+ BNX2_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE);
+ break;
- for (i = 0; i < (data * 2); i++) {
- if ((i % 2) == 0) {
- REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE);
- }
- else {
- REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
- BNX2_EMAC_LED_1000MB_OVERRIDE |
- BNX2_EMAC_LED_100MB_OVERRIDE |
- BNX2_EMAC_LED_10MB_OVERRIDE |
- BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
- BNX2_EMAC_LED_TRAFFIC);
- }
- msleep_interruptible(500);
- if (signal_pending(current))
- break;
+ case ETHTOOL_ID_INACTIVE:
+ BNX2_WR(bp, BNX2_EMAC_LED, 0);
+ BNX2_WR(bp, BNX2_MISC_CFG, bp->leds_save);
+ break;
}
- REG_WR(bp, BNX2_EMAC_LED, 0);
- REG_WR(bp, BNX2_MISC_CFG, save);
+
return 0;
}
+static netdev_features_t
+bnx2_fix_features(struct net_device *dev, netdev_features_t features)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+
+ if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
+ features |= NETIF_F_HW_VLAN_CTAG_RX;
+
+ return features;
+}
+
static int
-bnx2_set_tx_csum(struct net_device *dev, u32 data)
+bnx2_set_features(struct net_device *dev, netdev_features_t features)
{
struct bnx2 *bp = netdev_priv(dev);
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- return (ethtool_op_set_tx_ipv6_csum(dev, data));
+ /* TSO with VLAN tag won't work with current firmware */
+ if (features & NETIF_F_HW_VLAN_CTAG_TX)
+ dev->vlan_features |= (dev->hw_features & NETIF_F_ALL_TSO);
else
- return (ethtool_op_set_tx_csum(dev, data));
+ dev->vlan_features &= ~NETIF_F_ALL_TSO;
+
+ if ((!!(features & NETIF_F_HW_VLAN_CTAG_RX) !=
+ !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) &&
+ netif_running(dev)) {
+ bnx2_netif_stop(bp, false);
+ dev->features = features;
+ bnx2_set_rx_mode(dev);
+ bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
+ bnx2_netif_start(bp, false);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void bnx2_get_channels(struct net_device *dev,
+ struct ethtool_channels *channels)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+ u32 max_rx_rings = 1;
+ u32 max_tx_rings = 1;
+
+ if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) {
+ max_rx_rings = RX_MAX_RINGS;
+ max_tx_rings = TX_MAX_RINGS;
+ }
+
+ channels->max_rx = max_rx_rings;
+ channels->max_tx = max_tx_rings;
+ channels->max_other = 0;
+ channels->max_combined = 0;
+ channels->rx_count = bp->num_rx_rings;
+ channels->tx_count = bp->num_tx_rings;
+ channels->other_count = 0;
+ channels->combined_count = 0;
+}
+
+static int bnx2_set_channels(struct net_device *dev,
+ struct ethtool_channels *channels)
+{
+ struct bnx2 *bp = netdev_priv(dev);
+ u32 max_rx_rings = 1;
+ u32 max_tx_rings = 1;
+ int rc = 0;
+
+ if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) {
+ max_rx_rings = RX_MAX_RINGS;
+ max_tx_rings = TX_MAX_RINGS;
+ }
+ if (channels->rx_count > max_rx_rings ||
+ channels->tx_count > max_tx_rings)
+ return -EINVAL;
+
+ bp->num_req_rx_rings = channels->rx_count;
+ bp->num_req_tx_rings = channels->tx_count;
+
+ if (netif_running(dev))
+ rc = bnx2_change_ring_size(bp, bp->rx_ring_size,
+ bp->tx_ring_size, true);
+
+ return rc;
}
static const struct ethtool_ops bnx2_ethtool_ops = {
@@ -7068,7 +7801,7 @@ static const struct ethtool_ops bnx2_ethtool_ops = {
.get_wol = bnx2_get_wol,
.set_wol = bnx2_set_wol,
.nway_reset = bnx2_nway_reset,
- .get_link = ethtool_op_get_link,
+ .get_link = bnx2_get_link,
.get_eeprom_len = bnx2_get_eeprom_len,
.get_eeprom = bnx2_get_eeprom,
.set_eeprom = bnx2_set_eeprom,
@@ -7078,16 +7811,13 @@ static const struct ethtool_ops bnx2_ethtool_ops = {
.set_ringparam = bnx2_set_ringparam,
.get_pauseparam = bnx2_get_pauseparam,
.set_pauseparam = bnx2_set_pauseparam,
- .get_rx_csum = bnx2_get_rx_csum,
- .set_rx_csum = bnx2_set_rx_csum,
- .set_tx_csum = bnx2_set_tx_csum,
- .set_sg = ethtool_op_set_sg,
- .set_tso = bnx2_set_tso,
.self_test = bnx2_self_test,
.get_strings = bnx2_get_strings,
- .phys_id = bnx2_phys_id,
+ .set_phys_id = bnx2_set_phys_id,
.get_ethtool_stats = bnx2_get_ethtool_stats,
.get_sset_count = bnx2_get_sset_count,
+ .get_channels = bnx2_get_channels,
+ .set_channels = bnx2_set_channels,
};
/* Called with rtnl_lock */
@@ -7122,9 +7852,6 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
}
case SIOCSMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
return -EOPNOTSUPP;
@@ -7152,7 +7879,7 @@ bnx2_change_mac_addr(struct net_device *dev, void *p)
struct bnx2 *bp = netdev_priv(dev);
if (!is_valid_ether_addr(addr->sa_data))
- return -EINVAL;
+ return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
if (netif_running(dev))
@@ -7172,25 +7899,31 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
dev->mtu = new_mtu;
- return (bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size));
+ return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size,
+ false);
}
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+#ifdef CONFIG_NET_POLL_CONTROLLER
static void
poll_bnx2(struct net_device *dev)
{
struct bnx2 *bp = netdev_priv(dev);
+ int i;
- disable_irq(bp->pdev->irq);
- bnx2_interrupt(bp->pdev->irq, dev);
- enable_irq(bp->pdev->irq);
+ for (i = 0; i < bp->irq_nvecs; i++) {
+ struct bnx2_irq *irq = &bp->irq_tbl[i];
+
+ disable_irq(irq->vector);
+ irq->handler(irq->vector, &bp->bnx2_napi[i]);
+ enable_irq(irq->vector);
+ }
}
#endif
-static void __devinit
+static void
bnx2_get_5709_media(struct bnx2 *bp)
{
- u32 val = REG_RD(bp, BNX2_MISC_DUAL_MEDIA_CTRL);
+ u32 val = BNX2_RD(bp, BNX2_MISC_DUAL_MEDIA_CTRL);
u32 bond_id = val & BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID;
u32 strap;
@@ -7206,7 +7939,7 @@ bnx2_get_5709_media(struct bnx2 *bp)
else
strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
- if (PCI_FUNC(bp->pdev->devfn) == 0) {
+ if (bp->func == 0) {
switch (strap) {
case 0x4:
case 0x5:
@@ -7225,18 +7958,18 @@ bnx2_get_5709_media(struct bnx2 *bp)
}
}
-static void __devinit
+static void
bnx2_get_pci_speed(struct bnx2 *bp)
{
u32 reg;
- reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
+ reg = BNX2_RD(bp, BNX2_PCICFG_MISC_STATUS);
if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
u32 clkreg;
bp->flags |= BNX2_FLAG_PCIX;
- clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS);
+ clkreg = BNX2_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS);
clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
switch (clkreg) {
@@ -7277,14 +8010,82 @@ bnx2_get_pci_speed(struct bnx2 *bp)
}
-static int __devinit
+static void
+bnx2_read_vpd_fw_ver(struct bnx2 *bp)
+{
+ int rc, i, j;
+ u8 *data;
+ unsigned int block_end, rosize, len;
+
+#define BNX2_VPD_NVRAM_OFFSET 0x300
+#define BNX2_VPD_LEN 128
+#define BNX2_MAX_VER_SLEN 30
+
+ data = kmalloc(256, GFP_KERNEL);
+ if (!data)
+ return;
+
+ rc = bnx2_nvram_read(bp, BNX2_VPD_NVRAM_OFFSET, data + BNX2_VPD_LEN,
+ BNX2_VPD_LEN);
+ if (rc)
+ goto vpd_done;
+
+ for (i = 0; i < BNX2_VPD_LEN; i += 4) {
+ data[i] = data[i + BNX2_VPD_LEN + 3];
+ data[i + 1] = data[i + BNX2_VPD_LEN + 2];
+ data[i + 2] = data[i + BNX2_VPD_LEN + 1];
+ data[i + 3] = data[i + BNX2_VPD_LEN];
+ }
+
+ i = pci_vpd_find_tag(data, 0, BNX2_VPD_LEN, PCI_VPD_LRDT_RO_DATA);
+ if (i < 0)
+ goto vpd_done;
+
+ rosize = pci_vpd_lrdt_size(&data[i]);
+ i += PCI_VPD_LRDT_TAG_SIZE;
+ block_end = i + rosize;
+
+ if (block_end > BNX2_VPD_LEN)
+ goto vpd_done;
+
+ j = pci_vpd_find_info_keyword(data, i, rosize,
+ PCI_VPD_RO_KEYWORD_MFR_ID);
+ if (j < 0)
+ goto vpd_done;
+
+ len = pci_vpd_info_field_size(&data[j]);
+
+ j += PCI_VPD_INFO_FLD_HDR_SIZE;
+ if (j + len > block_end || len != 4 ||
+ memcmp(&data[j], "1028", 4))
+ goto vpd_done;
+
+ j = pci_vpd_find_info_keyword(data, i, rosize,
+ PCI_VPD_RO_KEYWORD_VENDOR0);
+ if (j < 0)
+ goto vpd_done;
+
+ len = pci_vpd_info_field_size(&data[j]);
+
+ j += PCI_VPD_INFO_FLD_HDR_SIZE;
+ if (j + len > block_end || len > BNX2_MAX_VER_SLEN)
+ goto vpd_done;
+
+ memcpy(bp->fw_version, &data[j], len);
+ bp->fw_version[len] = ' ';
+
+vpd_done:
+ kfree(data);
+}
+
+static int
bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
{
struct bnx2 *bp;
- unsigned long mem_len;
int rc, i, j;
u32 reg;
u64 dma_mask, persist_dma_mask;
+ int err;
SET_NETDEV_DEV(dev, &pdev->dev);
bp = netdev_priv(dev);
@@ -7292,33 +8093,40 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->flags = 0;
bp->phy_flags = 0;
+ bp->temp_stats_blk =
+ kzalloc(sizeof(struct statistics_block), GFP_KERNEL);
+
+ if (bp->temp_stats_blk == NULL) {
+ rc = -ENOMEM;
+ goto err_out;
+ }
+
/* enable device (incl. PCI PM wakeup), and bus-mastering */
rc = pci_enable_device(pdev);
if (rc) {
- dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n");
+ dev_err(&pdev->dev, "Cannot enable PCI device, aborting\n");
goto err_out;
}
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
dev_err(&pdev->dev,
- "Cannot find PCI device base address, aborting.\n");
+ "Cannot find PCI device base address, aborting\n");
rc = -ENODEV;
goto err_out_disable;
}
rc = pci_request_regions(pdev, DRV_MODULE_NAME);
if (rc) {
- dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting.\n");
+ dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
goto err_out_disable;
}
pci_set_master(pdev);
- pci_save_state(pdev);
- bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ bp->pm_cap = pdev->pm_cap;
if (bp->pm_cap == 0) {
dev_err(&pdev->dev,
- "Cannot find power management capability, aborting.\n");
+ "Cannot find power management capability, aborting\n");
rc = -EIO;
goto err_out_release;
}
@@ -7328,17 +8136,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
spin_lock_init(&bp->phy_lock);
spin_lock_init(&bp->indirect_lock);
+#ifdef BCM_CNIC
+ mutex_init(&bp->cnic_lock);
+#endif
INIT_WORK(&bp->reset_task, bnx2_reset_task);
- dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
- mem_len = MB_GET_CID_ADDR(TX_TSS_CID + TX_MAX_TSS_RINGS);
- dev->mem_end = dev->mem_start + mem_len;
- dev->irq = pdev->irq;
-
- bp->regview = ioremap_nocache(dev->base_addr, mem_len);
-
+ bp->regview = pci_iomap(pdev, 0, MB_GET_CID_ADDR(TX_TSS_CID +
+ TX_MAX_TSS_RINGS + 1));
if (!bp->regview) {
- dev_err(&pdev->dev, "Cannot map register space, aborting.\n");
+ dev_err(&pdev->dev, "Cannot map register space, aborting\n");
rc = -ENOMEM;
goto err_out_release;
}
@@ -7347,49 +8153,55 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
* Rely on CPU to do target byte swapping on big endian systems
* The chip's target access swapping will not swap all accesses
*/
- pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
- BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
- BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
+ BNX2_WR(bp, BNX2_PCICFG_MISC_CONFIG,
+ BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+ BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
- bnx2_set_power_state(bp, PCI_D0);
-
- bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
+ bp->chip_id = BNX2_RD(bp, BNX2_MISC_ID);
- if (CHIP_NUM(bp) == CHIP_NUM_5709) {
- if (pci_find_capability(pdev, PCI_CAP_ID_EXP) == 0) {
- dev_err(&pdev->dev,
- "Cannot find PCIE capability, aborting.\n");
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {
+ if (!pci_is_pcie(pdev)) {
+ dev_err(&pdev->dev, "Not PCIE, aborting\n");
rc = -EIO;
goto err_out_unmap;
}
bp->flags |= BNX2_FLAG_PCIE;
- if (CHIP_REV(bp) == CHIP_REV_Ax)
+ if (BNX2_CHIP_REV(bp) == BNX2_CHIP_REV_Ax)
bp->flags |= BNX2_FLAG_JUMBO_BROKEN;
+
+ /* AER (Advanced Error Reporting) hooks */
+ err = pci_enable_pcie_error_reporting(pdev);
+ if (!err)
+ bp->flags |= BNX2_FLAG_AER_ENABLED;
+
} else {
bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
if (bp->pcix_cap == 0) {
dev_err(&pdev->dev,
- "Cannot find PCIX capability, aborting.\n");
+ "Cannot find PCIX capability, aborting\n");
rc = -EIO;
goto err_out_unmap;
}
+ bp->flags |= BNX2_FLAG_BROKEN_STATS;
}
- if (CHIP_NUM(bp) == CHIP_NUM_5709 && CHIP_REV(bp) != CHIP_REV_Ax) {
- if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709 &&
+ BNX2_CHIP_REV(bp) != BNX2_CHIP_REV_Ax) {
+ if (pdev->msix_cap)
bp->flags |= BNX2_FLAG_MSIX_CAP;
}
- if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) {
- if (pci_find_capability(pdev, PCI_CAP_ID_MSI))
+ if (BNX2_CHIP_ID(bp) != BNX2_CHIP_ID_5706_A0 &&
+ BNX2_CHIP_ID(bp) != BNX2_CHIP_ID_5706_A1) {
+ if (pdev->msi_cap)
bp->flags |= BNX2_FLAG_MSI_CAP;
}
/* 5708 cannot support DMA addresses > 40-bit. */
- if (CHIP_NUM(bp) == CHIP_NUM_5708)
- persist_dma_mask = dma_mask = DMA_40BIT_MASK;
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5708)
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
else
- persist_dma_mask = dma_mask = DMA_64BIT_MASK;
+ persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
/* Configure DMA attributes. */
if (pci_set_dma_mask(pdev, dma_mask) == 0) {
@@ -7397,11 +8209,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
rc = pci_set_consistent_dma_mask(pdev, persist_dma_mask);
if (rc) {
dev_err(&pdev->dev,
- "pci_set_consistent_dma_mask failed, aborting.\n");
+ "pci_set_consistent_dma_mask failed, aborting\n");
goto err_out_unmap;
}
- } else if ((rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
- dev_err(&pdev->dev, "System does not support DMA, aborting.\n");
+ } else if ((rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
+ dev_err(&pdev->dev, "System does not support DMA, aborting\n");
goto err_out_unmap;
}
@@ -7409,16 +8221,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bnx2_get_pci_speed(bp);
/* 5706A0 may falsely detect SERR and PERR. */
- if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
- reg = REG_RD(bp, PCI_COMMAND);
+ if (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) {
+ reg = BNX2_RD(bp, PCI_COMMAND);
reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
- REG_WR(bp, PCI_COMMAND, reg);
- }
- else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) &&
+ BNX2_WR(bp, PCI_COMMAND, reg);
+ } else if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1) &&
!(bp->flags & BNX2_FLAG_PCIX)) {
dev_err(&pdev->dev,
- "5706 A1 can only be used in a PCIX bus, aborting.\n");
+ "5706 A1 can only be used in a PCIX bus, aborting\n");
goto err_out_unmap;
}
@@ -7426,9 +8237,12 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
reg = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_SIGNATURE);
+ if (bnx2_reg_rd_ind(bp, BNX2_MCP_TOE_ID) & BNX2_MCP_TOE_ID_FUNCTION_ID)
+ bp->func = 1;
+
if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
BNX2_SHM_HDR_SIGNATURE_SIG) {
- u32 off = PCI_FUNC(pdev->devfn) << 2;
+ u32 off = bp->func << 2;
bp->shmem_base = bnx2_reg_rd_ind(bp, BNX2_SHM_HDR_ADDR_0 + off);
} else
@@ -7441,15 +8255,23 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
BNX2_DEV_INFO_SIGNATURE_MAGIC) {
- dev_err(&pdev->dev, "Firmware not running, aborting.\n");
+ dev_err(&pdev->dev, "Firmware not running, aborting\n");
rc = -ENODEV;
goto err_out_unmap;
}
+ bnx2_read_vpd_fw_ver(bp);
+
+ j = strlen(bp->fw_version);
reg = bnx2_shmem_rd(bp, BNX2_DEV_INFO_BC_REV);
- for (i = 0, j = 0; i < 3; i++) {
+ for (i = 0; i < 3 && j < 24; i++) {
u8 num, k, skip0;
+ if (i == 0) {
+ bp->fw_version[j++] = 'b';
+ bp->fw_version[j++] = 'c';
+ bp->fw_version[j++] = ' ';
+ }
num = (u8) (reg >> (24 - (i * 8)));
for (k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
if (num >= k || !skip0 || k == 1) {
@@ -7480,10 +8302,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
reg != BNX2_CONDITION_MFW_RUN_NONE) {
u32 addr = bnx2_shmem_rd(bp, BNX2_MFW_VER_PTR);
- bp->fw_version[j++] = ' ';
- for (i = 0; i < 3; i++) {
+ if (j < 32)
+ bp->fw_version[j++] = ' ';
+ for (i = 0; i < 3 && j < 28; i++) {
reg = bnx2_reg_rd_ind(bp, addr + i * 4);
- reg = swab32(reg);
+ reg = be32_to_cpu(reg);
memcpy(&bp->fw_version[j], &reg, 4);
j += 4;
}
@@ -7499,32 +8322,29 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->mac_addr[4] = (u8) (reg >> 8);
bp->mac_addr[5] = (u8) reg;
- bp->tx_ring_size = MAX_TX_DESC_CNT;
+ bp->tx_ring_size = BNX2_MAX_TX_DESC_CNT;
bnx2_set_rx_ring_size(bp, 255);
- bp->rx_csum = 1;
-
- bp->tx_quick_cons_trip_int = 20;
+ bp->tx_quick_cons_trip_int = 2;
bp->tx_quick_cons_trip = 20;
- bp->tx_ticks_int = 80;
+ bp->tx_ticks_int = 18;
bp->tx_ticks = 80;
- bp->rx_quick_cons_trip_int = 6;
- bp->rx_quick_cons_trip = 6;
+ bp->rx_quick_cons_trip_int = 2;
+ bp->rx_quick_cons_trip = 12;
bp->rx_ticks_int = 18;
bp->rx_ticks = 18;
bp->stats_ticks = USEC_PER_SEC & BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
- bp->timer_interval = HZ;
- bp->current_interval = HZ;
+ bp->current_interval = BNX2_TIMER_INTERVAL;
bp->phy_addr = 1;
/* Disable WOL support if we are running on a SERDES chip. */
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
bnx2_get_5709_media(bp);
- else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
+ else if (BNX2_CHIP_BOND(bp) & BNX2_CHIP_BOND_SERDES_BIT)
bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
bp->phy_port = PORT_TP;
@@ -7535,7 +8355,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->flags |= BNX2_FLAG_NO_WOL;
bp->wol = 0;
}
- if (CHIP_NUM(bp) == CHIP_NUM_5706) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5706) {
/* Don't do parallel detect on this board because of
* some board problems. The link will not go down
* if we do parallel detect.
@@ -7548,24 +8368,30 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
bp->phy_flags |= BNX2_PHY_FLAG_2_5G_CAPABLE;
}
- } else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
- CHIP_NUM(bp) == CHIP_NUM_5708)
+ } else if (BNX2_CHIP(bp) == BNX2_CHIP_5706 ||
+ BNX2_CHIP(bp) == BNX2_CHIP_5708)
bp->phy_flags |= BNX2_PHY_FLAG_CRC_FIX;
- else if (CHIP_NUM(bp) == CHIP_NUM_5709 &&
- (CHIP_REV(bp) == CHIP_REV_Ax ||
- CHIP_REV(bp) == CHIP_REV_Bx))
+ else if (BNX2_CHIP(bp) == BNX2_CHIP_5709 &&
+ (BNX2_CHIP_REV(bp) == BNX2_CHIP_REV_Ax ||
+ BNX2_CHIP_REV(bp) == BNX2_CHIP_REV_Bx))
bp->phy_flags |= BNX2_PHY_FLAG_DIS_EARLY_DAC;
bnx2_init_fw_cap(bp);
- if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
- (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
- (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
+ if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_A0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_B0) ||
+ (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5708_B1) ||
+ !(BNX2_RD(bp, BNX2_PCI_CONFIG_3) & BNX2_PCI_CONFIG_3_VAUX_PRESET)) {
bp->flags |= BNX2_FLAG_NO_WOL;
bp->wol = 0;
}
- if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+ if (bp->flags & BNX2_FLAG_NO_WOL)
+ device_set_wakeup_capable(&bp->pdev->dev, false);
+ else
+ device_set_wakeup_enable(&bp->pdev->dev, bp->wol);
+
+ if (BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A0) {
bp->tx_quick_cons_trip_int =
bp->tx_quick_cons_trip;
bp->tx_ticks_int = bp->tx_ticks;
@@ -7587,7 +8413,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
* AMD believes this incompatibility is unique to the 5706, and
* prefers to locally disable MSI rather than globally disabling it.
*/
- if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) {
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5706 && disable_msi == 0) {
struct pci_dev *amd_8132 = NULL;
while ((amd_8132 = pci_get_device(PCI_VENDOR_ID_AMD,
@@ -7607,30 +8433,41 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
init_timer(&bp->timer);
- bp->timer.expires = RUN_AT(bp->timer_interval);
+ bp->timer.expires = RUN_AT(BNX2_TIMER_INTERVAL);
bp->timer.data = (unsigned long) bp;
bp->timer.function = bnx2_timer;
+#ifdef BCM_CNIC
+ if (bnx2_shmem_rd(bp, BNX2_ISCSI_INITIATOR) & BNX2_ISCSI_INITIATOR_EN)
+ bp->cnic_eth_dev.max_iscsi_conn =
+ (bnx2_shmem_rd(bp, BNX2_ISCSI_MAX_CONN) &
+ BNX2_ISCSI_MAX_CONN_MASK) >> BNX2_ISCSI_MAX_CONN_SHIFT;
+ bp->cnic_probe = bnx2_cnic_probe;
+#endif
+ pci_save_state(pdev);
+
return 0;
err_out_unmap:
- if (bp->regview) {
- iounmap(bp->regview);
- bp->regview = NULL;
+ if (bp->flags & BNX2_FLAG_AER_ENABLED) {
+ pci_disable_pcie_error_reporting(pdev);
+ bp->flags &= ~BNX2_FLAG_AER_ENABLED;
}
+ pci_iounmap(pdev, bp->regview);
+ bp->regview = NULL;
+
err_out_release:
pci_release_regions(pdev);
err_out_disable:
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
err_out:
return rc;
}
-static char * __devinit
+static char *
bnx2_bus_string(struct bnx2 *bp, char *str)
{
char *s = str;
@@ -7650,12 +8487,21 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
return str;
}
-static void __devinit
+static void
+bnx2_del_napi(struct bnx2 *bp)
+{
+ int i;
+
+ for (i = 0; i < bp->irq_nvecs; i++)
+ netif_napi_del(&bp->bnx2_napi[i].napi);
+}
+
+static void
bnx2_init_napi(struct bnx2 *bp)
{
int i;
- for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+ for (i = 0; i < bp->irq_nvecs; i++) {
struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
int (*poll)(struct napi_struct *, int);
@@ -7669,161 +8515,165 @@ bnx2_init_napi(struct bnx2 *bp)
}
}
-static int __devinit
+static const struct net_device_ops bnx2_netdev_ops = {
+ .ndo_open = bnx2_open,
+ .ndo_start_xmit = bnx2_start_xmit,
+ .ndo_stop = bnx2_close,
+ .ndo_get_stats64 = bnx2_get_stats64,
+ .ndo_set_rx_mode = bnx2_set_rx_mode,
+ .ndo_do_ioctl = bnx2_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = bnx2_change_mac_addr,
+ .ndo_change_mtu = bnx2_change_mtu,
+ .ndo_fix_features = bnx2_fix_features,
+ .ndo_set_features = bnx2_set_features,
+ .ndo_tx_timeout = bnx2_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = poll_bnx2,
+#endif
+};
+
+static int
bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int version_printed = 0;
- struct net_device *dev = NULL;
+ struct net_device *dev;
struct bnx2 *bp;
int rc;
char str[40];
- DECLARE_MAC_BUF(mac);
if (version_printed++ == 0)
- printk(KERN_INFO "%s", version);
+ pr_info("%s", version);
/* dev zeroed in init_etherdev */
dev = alloc_etherdev_mq(sizeof(*bp), TX_MAX_RINGS);
-
if (!dev)
return -ENOMEM;
rc = bnx2_init_board(pdev, dev);
- if (rc < 0) {
- free_netdev(dev);
- return rc;
- }
+ if (rc < 0)
+ goto err_free;
- dev->open = bnx2_open;
- dev->hard_start_xmit = bnx2_start_xmit;
- dev->stop = bnx2_close;
- dev->get_stats = bnx2_get_stats;
- dev->set_rx_mode = bnx2_set_rx_mode;
- dev->do_ioctl = bnx2_ioctl;
- dev->set_mac_address = bnx2_change_mac_addr;
- dev->change_mtu = bnx2_change_mtu;
- dev->tx_timeout = bnx2_tx_timeout;
+ dev->netdev_ops = &bnx2_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef BCM_VLAN
- dev->vlan_rx_register = bnx2_vlan_rx_register;
-#endif
dev->ethtool_ops = &bnx2_ethtool_ops;
bp = netdev_priv(dev);
- bnx2_init_napi(bp);
-
-#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
- dev->poll_controller = poll_bnx2;
-#endif
pci_set_drvdata(pdev, dev);
- memcpy(dev->dev_addr, bp->mac_addr, 6);
- memcpy(dev->perm_addr, bp->mac_addr, 6);
- bp->name = board_info[ent->driver_data].name;
+ memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- dev->features |= NETIF_F_IPV6_CSUM;
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_TSO | NETIF_F_TSO_ECN |
+ NETIF_F_RXHASH | NETIF_F_RXCSUM;
-#ifdef BCM_VLAN
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-#endif
- dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
- if (CHIP_NUM(bp) == CHIP_NUM_5709)
- dev->features |= NETIF_F_TSO6;
+ if (BNX2_CHIP(bp) == BNX2_CHIP_5709)
+ dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+
+ dev->vlan_features = dev->hw_features;
+ dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
+ dev->features |= dev->hw_features;
+ dev->priv_flags |= IFF_UNICAST_FLT;
if ((rc = register_netdev(dev))) {
dev_err(&pdev->dev, "Cannot register net device\n");
- if (bp->regview)
- iounmap(bp->regview);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
- free_netdev(dev);
- return rc;
+ goto error;
}
- printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, "
- "IRQ %d, node addr %s\n",
- dev->name,
- bp->name,
- ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
- ((CHIP_ID(bp) & 0x0ff0) >> 4),
- bnx2_bus_string(bp, str),
- dev->base_addr,
- bp->pdev->irq, print_mac(mac, dev->dev_addr));
+ netdev_info(dev, "%s (%c%d) %s found at mem %lx, IRQ %d, "
+ "node addr %pM\n", board_info[ent->driver_data].name,
+ ((BNX2_CHIP_ID(bp) & 0xf000) >> 12) + 'A',
+ ((BNX2_CHIP_ID(bp) & 0x0ff0) >> 4),
+ bnx2_bus_string(bp, str), (long)pci_resource_start(pdev, 0),
+ pdev->irq, dev->dev_addr);
return 0;
+
+error:
+ pci_iounmap(pdev, bp->regview);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+err_free:
+ free_netdev(dev);
+ return rc;
}
-static void __devexit
+static void
bnx2_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
- flush_scheduled_work();
-
unregister_netdev(dev);
- if (bp->regview)
- iounmap(bp->regview);
+ del_timer_sync(&bp->timer);
+ cancel_work_sync(&bp->reset_task);
+
+ pci_iounmap(bp->pdev, bp->regview);
+
+ kfree(bp->temp_stats_blk);
+
+ if (bp->flags & BNX2_FLAG_AER_ENABLED) {
+ pci_disable_pcie_error_reporting(pdev);
+ bp->flags &= ~BNX2_FLAG_AER_ENABLED;
+ }
+
+ bnx2_release_firmware(bp);
free_netdev(dev);
+
pci_release_regions(pdev);
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
}
+#ifdef CONFIG_PM_SLEEP
static int
-bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
+bnx2_suspend(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
- u32 reset_code;
-
- /* PCI register 4 needs to be saved whether netif_running() or not.
- * MSI address and data need to be saved if using MSI and
- * netif_running().
- */
- pci_save_state(pdev);
- if (!netif_running(dev))
- return 0;
- flush_scheduled_work();
- bnx2_netif_stop(bp);
- netif_device_detach(dev);
- del_timer_sync(&bp->timer);
- if (bp->flags & BNX2_FLAG_NO_WOL)
- reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
- else if (bp->wol)
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
- else
- reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
- bnx2_reset_chip(bp, reset_code);
- bnx2_free_skbs(bp);
- bnx2_set_power_state(bp, pci_choose_state(pdev, state));
+ if (netif_running(dev)) {
+ cancel_work_sync(&bp->reset_task);
+ bnx2_netif_stop(bp, true);
+ netif_device_detach(dev);
+ del_timer_sync(&bp->timer);
+ bnx2_shutdown_chip(bp);
+ __bnx2_free_irq(bp);
+ bnx2_free_skbs(bp);
+ }
+ bnx2_setup_wol(bp);
return 0;
}
static int
-bnx2_resume(struct pci_dev *pdev)
+bnx2_resume(struct device *device)
{
+ struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
- pci_restore_state(pdev);
if (!netif_running(dev))
return 0;
bnx2_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
+ bnx2_request_irq(bp);
bnx2_init_nic(bp, 1);
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
return 0;
}
+static SIMPLE_DEV_PM_OPS(bnx2_pm_ops, bnx2_suspend, bnx2_resume);
+#define BNX2_PM_OPS (&bnx2_pm_ops)
+
+#else
+
+#define BNX2_PM_OPS NULL
+
+#endif /* CONFIG_PM_SLEEP */
/**
* bnx2_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
@@ -7841,8 +8691,13 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
rtnl_lock();
netif_device_detach(dev);
+ if (state == pci_channel_io_perm_failure) {
+ rtnl_unlock();
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
if (netif_running(dev)) {
- bnx2_netif_stop(bp);
+ bnx2_netif_stop(bp, true);
del_timer_sync(&bp->timer);
bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
}
@@ -7864,24 +8719,42 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
+ pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;
+ int err = 0;
rtnl_lock();
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
- "Cannot re-enable PCI device after reset.\n");
- rtnl_unlock();
- return PCI_ERS_RESULT_DISCONNECT;
- }
- pci_set_master(pdev);
- pci_restore_state(pdev);
+ "Cannot re-enable PCI device after reset\n");
+ } else {
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
+ pci_save_state(pdev);
- if (netif_running(dev)) {
- bnx2_set_power_state(bp, PCI_D0);
- bnx2_init_nic(bp, 1);
+ if (netif_running(dev))
+ err = bnx2_init_nic(bp, 1);
+
+ if (!err)
+ result = PCI_ERS_RESULT_RECOVERED;
}
+ if (result != PCI_ERS_RESULT_RECOVERED && netif_running(dev)) {
+ bnx2_napi_enable(bp);
+ dev_close(dev);
+ }
rtnl_unlock();
- return PCI_ERS_RESULT_RECOVERED;
+
+ if (!(bp->flags & BNX2_FLAG_AER_ENABLED))
+ return result;
+
+ err = pci_cleanup_aer_uncorrect_error_status(pdev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n",
+ err); /* non-fatal, continue */
+ }
+
+ return result;
}
/**
@@ -7898,13 +8771,35 @@ static void bnx2_io_resume(struct pci_dev *pdev)
rtnl_lock();
if (netif_running(dev))
- bnx2_netif_start(bp);
+ bnx2_netif_start(bp, true);
netif_device_attach(dev);
rtnl_unlock();
}
-static struct pci_error_handlers bnx2_err_handler = {
+static void bnx2_shutdown(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2 *bp;
+
+ if (!dev)
+ return;
+
+ bp = netdev_priv(dev);
+ if (!bp)
+ return;
+
+ rtnl_lock();
+ if (netif_running(dev))
+ dev_close(bp->dev);
+
+ if (system_state == SYSTEM_POWER_OFF)
+ bnx2_set_power_state(bp, PCI_D3hot);
+
+ rtnl_unlock();
+}
+
+static const struct pci_error_handlers bnx2_err_handler = {
.error_detected = bnx2_io_error_detected,
.slot_reset = bnx2_io_slot_reset,
.resume = bnx2_io_resume,
@@ -7914,24 +8809,10 @@ static struct pci_driver bnx2_pci_driver = {
.name = DRV_MODULE_NAME,
.id_table = bnx2_pci_tbl,
.probe = bnx2_init_one,
- .remove = __devexit_p(bnx2_remove_one),
- .suspend = bnx2_suspend,
- .resume = bnx2_resume,
+ .remove = bnx2_remove_one,
+ .driver.pm = BNX2_PM_OPS,
.err_handler = &bnx2_err_handler,
+ .shutdown = bnx2_shutdown,
};
-static int __init bnx2_init(void)
-{
- return pci_register_driver(&bnx2_pci_driver);
-}
-
-static void __exit bnx2_cleanup(void)
-{
- pci_unregister_driver(&bnx2_pci_driver);
-}
-
-module_init(bnx2_init);
-module_exit(bnx2_cleanup);
-
-
-
+module_pci_driver(bnx2_pci_driver);
diff --git a/drivers/net/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h
index dfacd31f7ed..e341bc366fa 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/ethernet/broadcom/bnx2.h
@@ -1,6 +1,6 @@
/* bnx2.h: Broadcom NX2 network driver.
*
- * Copyright (c) 2004-2007 Broadcom Corporation
+ * Copyright (c) 2004-2013 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
/*
* tx_bd definition
*/
-struct tx_bd {
+struct bnx2_tx_bd {
u32 tx_bd_haddr_hi;
u32 tx_bd_haddr_lo;
u32 tx_bd_mss_nbytes;
@@ -48,7 +48,7 @@ struct tx_bd {
/*
* rx_bd definition
*/
-struct rx_bd {
+struct bnx2_rx_bd {
u32 rx_bd_haddr_hi;
u32 rx_bd_haddr_lo;
u32 rx_bd_len;
@@ -295,6 +295,9 @@ struct l2_fhdr {
#define L2_FHDR_ERRORS_TCP_XSUM (1<<28)
#define L2_FHDR_ERRORS_UDP_XSUM (1<<31)
+ #define L2_FHDR_STATUS_USE_RXHASH \
+ (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_RSS_HASH)
+
u32 l2_fhdr_hash;
#if defined(__BIG_ENDIAN)
u16 l2_fhdr_pkt_len;
@@ -349,18 +352,19 @@ struct l2_fhdr {
#define BNX2_L2CTX_BD_PRE_READ 0x00000000
#define BNX2_L2CTX_CTX_SIZE 0x00000000
#define BNX2_L2CTX_CTX_TYPE 0x00000000
-#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT 32
-#define BNX2_L2CTX_LO_WATER_MARK_SCALE 4
-#define BNX2_L2CTX_LO_WATER_MARK_DIS 0
-#define BNX2_L2CTX_HI_WATER_MARK_SHIFT 4
-#define BNX2_L2CTX_HI_WATER_MARK_SCALE 16
-#define BNX2_L2CTX_WATER_MARKS_MSK 0x000000ff
+#define BNX2_L2CTX_FLOW_CTRL_ENABLE 0x000000ff
#define BNX2_L2CTX_CTX_TYPE_SIZE_L2 ((0x20/20)<<16)
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28)
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28)
#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE (1<<28)
#define BNX2_L2CTX_HOST_BDIDX 0x00000004
+#define BNX2_L2CTX_L5_STATUSB_NUM_SHIFT 16
+#define BNX2_L2CTX_L2_STATUSB_NUM_SHIFT 24
+#define BNX2_L2CTX_L5_STATUSB_NUM(sb_id) \
+ (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L5_STATUSB_NUM_SHIFT) : 0)
+#define BNX2_L2CTX_L2_STATUSB_NUM(sb_id) \
+ (((sb_id) > 0) ? (((sb_id) + 7) << BNX2_L2CTX_L2_STATUSB_NUM_SHIFT) : 0)
#define BNX2_L2CTX_HOST_BSEQ 0x00000008
#define BNX2_L2CTX_NX_BSEQ 0x0000000c
#define BNX2_L2CTX_NX_BDHADDR_HI 0x00000010
@@ -378,6 +382,9 @@ struct l2_fhdr {
* pci_config_l definition
* offset: 0000
*/
+#define BNX2_PCICFG_MSI_CONTROL 0x00000058
+#define BNX2_PCICFG_MSI_CONTROL_ENABLE (1L<<16)
+
#define BNX2_PCICFG_MISC_CONFIG 0x00000068
#define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP (1L<<2)
#define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP (1L<<3)
@@ -454,6 +461,8 @@ struct l2_fhdr {
#define BNX2_PCICFG_MAILBOX_QUEUE_ADDR 0x00000090
#define BNX2_PCICFG_MAILBOX_QUEUE_DATA 0x00000094
+#define BNX2_PCICFG_DEVICE_CONTROL 0x000000b4
+#define BNX2_PCICFG_DEVICE_STATUS_NO_PEND ((1L<<5)<<16)
/*
* pci_reg definition
@@ -4173,6 +4182,15 @@ struct l2_fhdr {
#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_IP_ONLY_XI (2L<<2)
#define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_RES_XI (3L<<2)
+#define BNX2_RLUP_RSS_COMMAND 0x00002048
+#define BNX2_RLUP_RSS_COMMAND_RSS_IND_TABLE_ADDR (0xfUL<<0)
+#define BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK (0xffUL<<4)
+#define BNX2_RLUP_RSS_COMMAND_WRITE (1UL<<12)
+#define BNX2_RLUP_RSS_COMMAND_READ (1UL<<13)
+#define BNX2_RLUP_RSS_COMMAND_HASH_MASK (0x7UL<<14)
+
+#define BNX2_RLUP_RSS_DATA 0x0000204c
+
/*
* rbuf_reg definition
@@ -4199,7 +4217,14 @@ struct l2_fhdr {
#define BNX2_RBUF_CONFIG 0x0020000c
#define BNX2_RBUF_CONFIG_XOFF_TRIP (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG_XOFF_TRIP_VAL(mtu) \
+ ((((mtu) - 1500) * 31 / 1000) + 54)
#define BNX2_RBUF_CONFIG_XON_TRIP (0x3ffL<<16)
+#define BNX2_RBUF_CONFIG_XON_TRIP_VAL(mtu) \
+ ((((mtu) - 1500) * 39 / 1000) + 66)
+#define BNX2_RBUF_CONFIG_VAL(mtu) \
+ (BNX2_RBUF_CONFIG_XOFF_TRIP_VAL(mtu) | \
+ (BNX2_RBUF_CONFIG_XON_TRIP_VAL(mtu) << 16))
#define BNX2_RBUF_FW_BUF_ALLOC 0x00200010
#define BNX2_RBUF_FW_BUF_ALLOC_VALUE (0x1ffL<<7)
@@ -4221,11 +4246,25 @@ struct l2_fhdr {
#define BNX2_RBUF_CONFIG2 0x0020001c
#define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP_VAL(mtu) \
+ ((((mtu) - 1500) * 4 / 1000) + 5)
#define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP (0x3ffL<<16)
+#define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP_VAL(mtu) \
+ ((((mtu) - 1500) * 2 / 100) + 30)
+#define BNX2_RBUF_CONFIG2_VAL(mtu) \
+ (BNX2_RBUF_CONFIG2_MAC_DROP_TRIP_VAL(mtu) | \
+ (BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP_VAL(mtu) << 16))
#define BNX2_RBUF_CONFIG3 0x00200020
#define BNX2_RBUF_CONFIG3_CU_DROP_TRIP (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG3_CU_DROP_TRIP_VAL(mtu) \
+ ((((mtu) - 1500) * 12 / 1000) + 18)
#define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP (0x3ffL<<16)
+#define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP_VAL(mtu) \
+ ((((mtu) - 1500) * 2 / 100) + 30)
+#define BNX2_RBUF_CONFIG3_VAL(mtu) \
+ (BNX2_RBUF_CONFIG3_CU_DROP_TRIP_VAL(mtu) | \
+ (BNX2_RBUF_CONFIG3_CU_KEEP_TRIP_VAL(mtu) << 16))
#define BNX2_RBUF_PKT_DATA 0x00208000
#define BNX2_RBUF_CLIST_DATA 0x00210000
@@ -4603,6 +4642,47 @@ struct l2_fhdr {
#define BNX2_TBDR_FTQ_CTL_CUR_DEPTH (0x3ffL<<22)
+/*
+ * tbdc definition
+ * offset: 0x5400
+ */
+#define BNX2_TBDC_COMMAND 0x5400
+#define BNX2_TBDC_COMMAND_CMD_ENABLED (1UL<<0)
+#define BNX2_TBDC_COMMAND_CMD_FLUSH (1UL<<1)
+#define BNX2_TBDC_COMMAND_CMD_SOFT_RST (1UL<<2)
+#define BNX2_TBDC_COMMAND_CMD_REG_ARB (1UL<<3)
+#define BNX2_TBDC_COMMAND_WRCHK_RANGE_ERROR (1UL<<4)
+#define BNX2_TBDC_COMMAND_WRCHK_ALL_ONES_ERROR (1UL<<5)
+#define BNX2_TBDC_COMMAND_WRCHK_ALL_ZEROS_ERROR (1UL<<6)
+#define BNX2_TBDC_COMMAND_WRCHK_ANY_ONES_ERROR (1UL<<7)
+#define BNX2_TBDC_COMMAND_WRCHK_ANY_ZEROS_ERROR (1UL<<8)
+
+#define BNX2_TBDC_STATUS 0x5404
+#define BNX2_TBDC_STATUS_FREE_CNT (0x3fUL<<0)
+
+#define BNX2_TBDC_BD_ADDR 0x5424
+
+#define BNX2_TBDC_BIDX 0x542c
+#define BNX2_TBDC_BDIDX_BDIDX (0xffffUL<<0)
+#define BNX2_TBDC_BDIDX_CMD (0xffUL<<24)
+
+#define BNX2_TBDC_CID 0x5430
+
+#define BNX2_TBDC_CAM_OPCODE 0x5434
+#define BNX2_TBDC_CAM_OPCODE_OPCODE (0x7UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_OPCODE_SEARCH (0UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_OPCODE_CACHE_WRITE (1UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_OPCODE_INVALIDATE (2UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_OPCODE_CAM_WRITE (4UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_OPCODE_CAM_READ (5UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_OPCODE_RAM_WRITE (6UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_OPCODE_RAM_READ (7UL<<0)
+#define BNX2_TBDC_CAM_OPCODE_SMASK_BDIDX (1UL<<4)
+#define BNX2_TBDC_CAM_OPCODE_SMASK_CID (1UL<<5)
+#define BNX2_TBDC_CAM_OPCODE_SMASK_CMD (1UL<<6)
+#define BNX2_TBDC_CAM_OPCODE_WMT_FAILED (1UL<<7)
+#define BNX2_TBDC_CAM_OPCODE_CAM_VALIDS (0xffUL<<8)
+
/*
* tdma_reg definition
@@ -5578,7 +5658,7 @@ struct l2_fhdr {
#define BNX2_TXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_TXP_CPU_STATE_SOFT_HALTED (1L<<10)
#define BNX2_TXP_CPU_STATE_SPAD_UNDERFLOW (1L<<11)
-#define BNX2_TXP_CPU_STATE_INTERRRUPT (1L<<12)
+#define BNX2_TXP_CPU_STATE_INTERRUPT (1L<<12)
#define BNX2_TXP_CPU_STATE_DATA_ACCESS_STALL (1L<<14)
#define BNX2_TXP_CPU_STATE_INST_FETCH_STALL (1L<<15)
#define BNX2_TXP_CPU_STATE_BLOCKED_READ (1L<<31)
@@ -5673,7 +5753,7 @@ struct l2_fhdr {
#define BNX2_TPAT_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_TPAT_CPU_STATE_SOFT_HALTED (1L<<10)
#define BNX2_TPAT_CPU_STATE_SPAD_UNDERFLOW (1L<<11)
-#define BNX2_TPAT_CPU_STATE_INTERRRUPT (1L<<12)
+#define BNX2_TPAT_CPU_STATE_INTERRUPT (1L<<12)
#define BNX2_TPAT_CPU_STATE_DATA_ACCESS_STALL (1L<<14)
#define BNX2_TPAT_CPU_STATE_INST_FETCH_STALL (1L<<15)
#define BNX2_TPAT_CPU_STATE_BLOCKED_READ (1L<<31)
@@ -5768,7 +5848,7 @@ struct l2_fhdr {
#define BNX2_RXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_RXP_CPU_STATE_SOFT_HALTED (1L<<10)
#define BNX2_RXP_CPU_STATE_SPAD_UNDERFLOW (1L<<11)
-#define BNX2_RXP_CPU_STATE_INTERRRUPT (1L<<12)
+#define BNX2_RXP_CPU_STATE_INTERRUPT (1L<<12)
#define BNX2_RXP_CPU_STATE_DATA_ACCESS_STALL (1L<<14)
#define BNX2_RXP_CPU_STATE_INST_FETCH_STALL (1L<<15)
#define BNX2_RXP_CPU_STATE_BLOCKED_READ (1L<<31)
@@ -5876,6 +5956,7 @@ struct l2_fhdr {
#define BNX2_RXP_FTQ_CTL_CUR_DEPTH (0x3ffL<<22)
#define BNX2_RXP_SCRATCH 0x000e0000
+#define BNX2_RXP_SCRATCH_RXP_FLOOD 0x000e0024
#define BNX2_RXP_SCRATCH_RSS_TBL_SZ 0x000e0038
#define BNX2_RXP_SCRATCH_RSS_TBL 0x000e003c
#define BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES 128
@@ -5913,7 +5994,7 @@ struct l2_fhdr {
#define BNX2_COM_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_COM_CPU_STATE_SOFT_HALTED (1L<<10)
#define BNX2_COM_CPU_STATE_SPAD_UNDERFLOW (1L<<11)
-#define BNX2_COM_CPU_STATE_INTERRRUPT (1L<<12)
+#define BNX2_COM_CPU_STATE_INTERRUPT (1L<<12)
#define BNX2_COM_CPU_STATE_DATA_ACCESS_STALL (1L<<14)
#define BNX2_COM_CPU_STATE_INST_FETCH_STALL (1L<<15)
#define BNX2_COM_CPU_STATE_BLOCKED_READ (1L<<31)
@@ -6043,6 +6124,7 @@ struct l2_fhdr {
#define BNX2_COM_SCRATCH 0x00120000
+#define BNX2_FW_RX_LOW_LATENCY 0x00120058
#define BNX2_FW_RX_DROP_COUNT 0x00120084
@@ -6078,7 +6160,7 @@ struct l2_fhdr {
#define BNX2_CP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_CP_CPU_STATE_SOFT_HALTED (1L<<10)
#define BNX2_CP_CPU_STATE_SPAD_UNDERFLOW (1L<<11)
-#define BNX2_CP_CPU_STATE_INTERRRUPT (1L<<12)
+#define BNX2_CP_CPU_STATE_INTERRUPT (1L<<12)
#define BNX2_CP_CPU_STATE_DATA_ACCESS_STALL (1L<<14)
#define BNX2_CP_CPU_STATE_INST_FETCH_STALL (1L<<15)
#define BNX2_CP_CPU_STATE_BLOCKED_READ (1L<<31)
@@ -6166,6 +6248,8 @@ struct l2_fhdr {
#define BNX2_CP_SCRATCH 0x001a0000
+#define BNX2_FW_MAX_ISCSI_CONN 0x001a0080
+
/*
* mcp_reg definition
@@ -6248,7 +6332,7 @@ struct l2_fhdr {
#define BNX2_MCP_CPU_STATE_FIO_ABORT_HALTED (1L<<8)
#define BNX2_MCP_CPU_STATE_SOFT_HALTED (1L<<10)
#define BNX2_MCP_CPU_STATE_SPAD_UNDERFLOW (1L<<11)
-#define BNX2_MCP_CPU_STATE_INTERRRUPT (1L<<12)
+#define BNX2_MCP_CPU_STATE_INTERRUPT (1L<<12)
#define BNX2_MCP_CPU_STATE_DATA_ACCESS_STALL (1L<<14)
#define BNX2_MCP_CPU_STATE_INST_FETCH_STALL (1L<<15)
#define BNX2_MCP_CPU_STATE_BLOCKED_READ (1L<<31)
@@ -6314,6 +6398,10 @@ struct l2_fhdr {
#define BNX2_MCP_ROM 0x00150000
#define BNX2_MCP_SCRATCH 0x00160000
+#define BNX2_MCP_STATE_P1 0x0016f9c8
+#define BNX2_MCP_STATE_P0 0x0016fdc8
+#define BNX2_MCP_STATE_P1_5708 0x001699c8
+#define BNX2_MCP_STATE_P0_5708 0x00169dc8
#define BNX2_SHM_HDR_SIGNATURE BNX2_MCP_SCRATCH
#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK 0xffff0000
@@ -6383,6 +6471,15 @@ struct l2_fhdr {
#define BCM5708S_TX_ACTL3 0x17
+#define MII_BNX2_EXT_STATUS 0x11
+#define EXT_STATUS_MDIX (1 << 13)
+
+#define MII_BNX2_AUX_CTL 0x18
+#define AUX_CTL_MISC_CTL 0x7007
+#define AUX_CTL_MISC_CTL_WIRESPEED (1 << 4)
+#define AUX_CTL_MISC_CTL_AUTOMDIX (1 << 9)
+#define AUX_CTL_MISC_CTL_WR (1 << 15)
+
#define MII_BNX2_DSP_RW_PORT 0x15
#define MII_BNX2_DSP_ADDRESS 0x17
#define MII_BNX2_DSP_EXPAND_REG 0x0f00
@@ -6450,37 +6547,38 @@ struct l2_fhdr {
/* Use CPU native page size up to 16K for the ring sizes. */
#if (PAGE_SHIFT > 14)
-#define BCM_PAGE_BITS 14
+#define BNX2_PAGE_BITS 14
#else
-#define BCM_PAGE_BITS PAGE_SHIFT
+#define BNX2_PAGE_BITS PAGE_SHIFT
#endif
-#define BCM_PAGE_SIZE (1 << BCM_PAGE_BITS)
+#define BNX2_PAGE_SIZE (1 << BNX2_PAGE_BITS)
-#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd))
-#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
+#define BNX2_TX_DESC_CNT (BNX2_PAGE_SIZE / sizeof(struct bnx2_tx_bd))
+#define BNX2_MAX_TX_DESC_CNT (BNX2_TX_DESC_CNT - 1)
-#define MAX_RX_RINGS 4
-#define MAX_RX_PG_RINGS 16
-#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd))
-#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
-#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
-#define MAX_TOTAL_RX_PG_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_PG_RINGS)
+#define BNX2_MAX_RX_RINGS 8
+#define BNX2_MAX_RX_PG_RINGS 32
+#define BNX2_RX_DESC_CNT (BNX2_PAGE_SIZE / sizeof(struct bnx2_rx_bd))
+#define BNX2_MAX_RX_DESC_CNT (BNX2_RX_DESC_CNT - 1)
+#define BNX2_MAX_TOTAL_RX_DESC_CNT (BNX2_MAX_RX_DESC_CNT * BNX2_MAX_RX_RINGS)
+#define BNX2_MAX_TOTAL_RX_PG_DESC_CNT \
+ (BNX2_MAX_RX_DESC_CNT * BNX2_MAX_RX_PG_RINGS)
-#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \
- (MAX_TX_DESC_CNT - 1)) ? \
+#define BNX2_NEXT_TX_BD(x) (((x) & (BNX2_MAX_TX_DESC_CNT - 1)) == \
+ (BNX2_MAX_TX_DESC_CNT - 1)) ? \
(x) + 2 : (x) + 1
-#define TX_RING_IDX(x) ((x) & MAX_TX_DESC_CNT)
+#define BNX2_TX_RING_IDX(x) ((x) & BNX2_MAX_TX_DESC_CNT)
-#define NEXT_RX_BD(x) (((x) & (MAX_RX_DESC_CNT - 1)) == \
- (MAX_RX_DESC_CNT - 1)) ? \
+#define BNX2_NEXT_RX_BD(x) (((x) & (BNX2_MAX_RX_DESC_CNT - 1)) == \
+ (BNX2_MAX_RX_DESC_CNT - 1)) ? \
(x) + 2 : (x) + 1
-#define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
-#define RX_PG_RING_IDX(x) ((x) & bp->rx_max_pg_ring_idx)
+#define BNX2_RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
+#define BNX2_RX_PG_RING_IDX(x) ((x) & bp->rx_max_pg_ring_idx)
-#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4))
-#define RX_IDX(x) ((x) & MAX_RX_DESC_CNT)
+#define BNX2_RX_RING(x) (((x) & ~BNX2_MAX_RX_DESC_CNT) >> (BNX2_PAGE_BITS - 4))
+#define BNX2_RX_IDX(x) ((x) & BNX2_MAX_RX_DESC_CNT)
/* Context size. */
#define CTX_SHIFT 7
@@ -6516,21 +6614,42 @@ struct l2_fhdr {
#define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID)
#define MB_RX_CID_ADDR MB_GET_CID_ADDR(RX_CID)
-struct sw_bd {
- struct sk_buff *skb;
- DECLARE_PCI_UNMAP_ADDR(mapping)
+/*
+ * This driver uses new build_skb() API :
+ * RX ring buffer contains pointer to kmalloc() data only,
+ * skb are built only after Hardware filled the frame.
+ */
+struct bnx2_sw_bd {
+ u8 *data;
+ DEFINE_DMA_UNMAP_ADDR(mapping);
};
-struct sw_pg {
+/* Its faster to compute this from data than storing it in sw_bd
+ * (less cache misses)
+ */
+static inline struct l2_fhdr *get_l2_fhdr(u8 *data)
+{
+ return (struct l2_fhdr *)(PTR_ALIGN(data, BNX2_RX_ALIGN) + NET_SKB_PAD);
+}
+
+
+struct bnx2_sw_pg {
struct page *page;
- DECLARE_PCI_UNMAP_ADDR(mapping)
+ DEFINE_DMA_UNMAP_ADDR(mapping);
+};
+
+struct bnx2_sw_tx_bd {
+ struct sk_buff *skb;
+ DEFINE_DMA_UNMAP_ADDR(mapping);
+ unsigned short is_gso;
+ unsigned short nr_frags;
};
-#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
-#define SW_RXPG_RING_SIZE (sizeof(struct sw_pg) * RX_DESC_CNT)
-#define RXBD_RING_SIZE (sizeof(struct rx_bd) * RX_DESC_CNT)
-#define SW_TXBD_RING_SIZE (sizeof(struct sw_bd) * TX_DESC_CNT)
-#define TXBD_RING_SIZE (sizeof(struct tx_bd) * TX_DESC_CNT)
+#define SW_RXBD_RING_SIZE (sizeof(struct bnx2_sw_bd) * BNX2_RX_DESC_CNT)
+#define SW_RXPG_RING_SIZE (sizeof(struct bnx2_sw_pg) * BNX2_RX_DESC_CNT)
+#define RXBD_RING_SIZE (sizeof(struct bnx2_rx_bd) * BNX2_RX_DESC_CNT)
+#define SW_TXBD_RING_SIZE (sizeof(struct bnx2_sw_tx_bd) * BNX2_TX_DESC_CNT)
+#define TXBD_RING_SIZE (sizeof(struct bnx2_tx_bd) * BNX2_TX_DESC_CNT)
/* Buffered flash (Atmel: AT45DB011B) specific information */
#define SEEPROM_PAGE_BITS 2
@@ -6591,15 +6710,18 @@ struct flash_spec {
#define BNX2_MAX_MSIX_HW_VEC 9
#define BNX2_MAX_MSIX_VEC 9
-#define BNX2_BASE_VEC 0
-#define BNX2_TX_VEC 1
-#define BNX2_TX_INT_NUM (BNX2_TX_VEC << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT)
+#ifdef BCM_CNIC
+#define BNX2_MIN_MSIX_VEC 2
+#else
+#define BNX2_MIN_MSIX_VEC 1
+#endif
+
struct bnx2_irq {
irq_handler_t handler;
unsigned int vector;
u8 requested;
- char name[16];
+ char name[IFNAMSIZ + 2];
};
struct bnx2_tx_ring_info {
@@ -6608,8 +6730,8 @@ struct bnx2_tx_ring_info {
u32 tx_bidx_addr;
u32 tx_bseq_addr;
- struct tx_bd *tx_desc_ring;
- struct sw_bd *tx_buf_ring;
+ struct bnx2_tx_bd *tx_desc_ring;
+ struct bnx2_sw_tx_bd *tx_buf_ring;
u16 tx_cons;
u16 hw_tx_cons;
@@ -6629,13 +6751,13 @@ struct bnx2_rx_ring_info {
u16 rx_pg_prod;
u16 rx_pg_cons;
- struct sw_bd *rx_buf_ring;
- struct rx_bd *rx_desc_ring[MAX_RX_RINGS];
- struct sw_pg *rx_pg_ring;
- struct rx_bd *rx_pg_desc_ring[MAX_RX_PG_RINGS];
+ struct bnx2_sw_bd *rx_buf_ring;
+ struct bnx2_rx_bd *rx_desc_ring[BNX2_MAX_RX_RINGS];
+ struct bnx2_sw_pg *rx_pg_ring;
+ struct bnx2_rx_bd *rx_pg_desc_ring[BNX2_MAX_RX_PG_RINGS];
- dma_addr_t rx_desc_mapping[MAX_RX_RINGS];
- dma_addr_t rx_pg_desc_mapping[MAX_RX_PG_RINGS];
+ dma_addr_t rx_desc_mapping[BNX2_MAX_RX_RINGS];
+ dma_addr_t rx_pg_desc_mapping[BNX2_MAX_RX_PG_RINGS];
};
struct bnx2_napi {
@@ -6650,6 +6772,11 @@ struct bnx2_napi {
u32 last_status_idx;
u32 int_num;
+#ifdef BCM_CNIC
+ u32 cnic_tag;
+ int cnic_present;
+#endif
+
struct bnx2_rx_ring_info rx_ring;
struct bnx2_tx_ring_info tx_ring;
};
@@ -6679,13 +6806,11 @@ struct bnx2 {
BNX2_FLAG_USING_MSIX)
#define BNX2_FLAG_JUMBO_BROKEN 0x00000800
#define BNX2_FLAG_CAN_KEEP_VLAN 0x00001000
+#define BNX2_FLAG_BROKEN_STATS 0x00002000
+#define BNX2_FLAG_AER_ENABLED 0x00004000
struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC];
-#ifdef BCM_VLAN
- struct vlan_group *vlgrp;
-#endif
-
u32 rx_buf_use_size; /* useable size */
u32 rx_buf_size; /* with alignment */
u32 rx_copy_thresh;
@@ -6693,18 +6818,22 @@ struct bnx2 {
u32 rx_max_ring_idx;
u32 rx_max_pg_ring_idx;
- u32 rx_csum;
-
/* TX constants */
int tx_ring_size;
u32 tx_wake_thresh;
+#ifdef BCM_CNIC
+ struct cnic_ops __rcu *cnic_ops;
+ void *cnic_data;
+#endif
+
/* End of fields used in the performance code paths. */
- char *name;
+ unsigned int current_interval;
+#define BNX2_TIMER_INTERVAL HZ
+#define BNX2_SERDES_AN_TIMEOUT (HZ / 3)
+#define BNX2_SERDES_FORCED_TIMEOUT (HZ / 10)
- int timer_interval;
- int current_interval;
struct timer_list timer;
struct work_struct reset_task;
@@ -6724,6 +6853,7 @@ struct bnx2 {
#define BNX2_PHY_FLAG_REMOTE_PHY_CAP 0x00000800
#define BNX2_PHY_FLAG_FORCED_DOWN 0x00001000
#define BNX2_PHY_FLAG_NO_PARALLEL 0x00002000
+#define BNX2_PHY_FLAG_MDIX 0x00004000
u32 mii_bmcr;
u32 mii_bmsr;
@@ -6734,33 +6864,31 @@ struct bnx2 {
u32 chip_id;
/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
-#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
-#define CHIP_NUM_5706 0x57060000
-#define CHIP_NUM_5708 0x57080000
-#define CHIP_NUM_5709 0x57090000
-
-#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
-#define CHIP_REV_Ax 0x00000000
-#define CHIP_REV_Bx 0x00001000
-#define CHIP_REV_Cx 0x00002000
-
-#define CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0)
-#define CHIP_BONDING(bp) (((bp)->chip_id) & 0x0000000f)
-
-#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
-#define CHIP_ID_5706_A0 0x57060000
-#define CHIP_ID_5706_A1 0x57060010
-#define CHIP_ID_5706_A2 0x57060020
-#define CHIP_ID_5708_A0 0x57080000
-#define CHIP_ID_5708_B0 0x57081000
-#define CHIP_ID_5708_B1 0x57081010
-#define CHIP_ID_5709_A0 0x57090000
-#define CHIP_ID_5709_A1 0x57090010
-
-#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf)
+#define BNX2_CHIP(bp) (((bp)->chip_id) & 0xffff0000)
+#define BNX2_CHIP_5706 0x57060000
+#define BNX2_CHIP_5708 0x57080000
+#define BNX2_CHIP_5709 0x57090000
+
+#define BNX2_CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
+#define BNX2_CHIP_REV_Ax 0x00000000
+#define BNX2_CHIP_REV_Bx 0x00001000
+#define BNX2_CHIP_REV_Cx 0x00002000
+
+#define BNX2_CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0)
+#define BNX2_CHIP_BOND(bp) (((bp)->chip_id) & 0x0000000f)
+
+#define BNX2_CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
+#define BNX2_CHIP_ID_5706_A0 0x57060000
+#define BNX2_CHIP_ID_5706_A1 0x57060010
+#define BNX2_CHIP_ID_5706_A2 0x57060020
+#define BNX2_CHIP_ID_5708_A0 0x57080000
+#define BNX2_CHIP_ID_5708_B0 0x57081000
+#define BNX2_CHIP_ID_5708_B1 0x57081010
+#define BNX2_CHIP_ID_5709_A0 0x57090000
+#define BNX2_CHIP_ID_5709_A1 0x57090010
/* A serdes chip will have the first bit of the bond id set. */
-#define CHIP_BOND_ID_SERDES_BIT 0x01
+#define BNX2_CHIP_BOND_SERDES_BIT 0x01
u32 phy_addr;
u32 phy_id;
@@ -6772,6 +6900,7 @@ struct bnx2 {
u16 fw_wr_seq;
u16 fw_drv_pulse_wr_seq;
+ u32 fw_last_msg;
int rx_max_ring;
int rx_ring_size;
@@ -6799,6 +6928,7 @@ struct bnx2 {
dma_addr_t status_blk_mapping;
struct statistics_block *stats_blk;
+ struct statistics_block *temp_stats_blk;
dma_addr_t stats_blk_mapping;
int ctx_pages;
@@ -6819,9 +6949,6 @@ struct bnx2 {
u8 flow_ctrl; /* actual flow ctrl settings */
/* may be different from */
/* req_flow_ctrl if autoneg */
-#define FLOW_CTRL_TX 1
-#define FLOW_CTRL_RX 2
-
u32 advertising;
u8 req_flow_ctrl; /* flow ctrl advertisement */
@@ -6836,8 +6963,6 @@ struct bnx2 {
#define PHY_LOOPBACK 2
u8 serdes_an_pending;
-#define SERDES_AN_TIMEOUT (HZ / 3)
-#define SERDES_FORCED_TIMEOUT (HZ / 10)
u8 mac_addr[8];
@@ -6848,9 +6973,7 @@ struct bnx2 {
int pm_cap;
int pcix_cap;
- struct net_device_stats net_stats;
-
- struct flash_spec *flash_info;
+ const struct flash_spec *flash_info;
u32 flash_size;
int status_stats_size;
@@ -6858,17 +6981,34 @@ struct bnx2 {
struct bnx2_irq irq_tbl[BNX2_MAX_MSIX_VEC];
int irq_nvecs;
+ u8 func;
+
u8 num_tx_rings;
u8 num_rx_rings;
+
+ int num_req_tx_rings;
+ int num_req_rx_rings;
+
+ u32 leds_save;
+ u32 idle_chk_status_idx;
+
+#ifdef BCM_CNIC
+ struct mutex cnic_lock;
+ struct cnic_eth_dev cnic_eth_dev;
+ struct cnic_eth_dev *(*cnic_probe)(struct net_device *);
+#endif
+
+ const struct firmware *mips_firmware;
+ const struct firmware *rv2p_firmware;
};
-#define REG_RD(bp, offset) \
+#define BNX2_RD(bp, offset) \
readl(bp->regview + offset)
-#define REG_WR(bp, offset, val) \
+#define BNX2_WR(bp, offset, val) \
writel(val, bp->regview + offset)
-#define REG_WR16(bp, offset, val) \
+#define BNX2_WR16(bp, offset, val) \
writew(val, bp->regview + offset)
struct cpu_reg {
@@ -6890,44 +7030,41 @@ struct cpu_reg {
u32 mips_view_base;
};
-struct fw_info {
- const u32 ver_major;
- const u32 ver_minor;
- const u32 ver_fix;
-
- const u32 start_addr;
-
- /* Text section. */
- const u32 text_addr;
- const u32 text_len;
- const u32 text_index;
- __le32 *text;
- u8 *gz_text;
- const u32 gz_text_len;
-
- /* Data section. */
- const u32 data_addr;
- const u32 data_len;
- const u32 data_index;
- const u32 *data;
-
- /* SBSS section. */
- const u32 sbss_addr;
- const u32 sbss_len;
- const u32 sbss_index;
-
- /* BSS section. */
- const u32 bss_addr;
- const u32 bss_len;
- const u32 bss_index;
-
- /* Read-only section. */
- const u32 rodata_addr;
- const u32 rodata_len;
- const u32 rodata_index;
- const u32 *rodata;
+struct bnx2_fw_file_section {
+ __be32 addr;
+ __be32 len;
+ __be32 offset;
};
+struct bnx2_mips_fw_file_entry {
+ __be32 start_addr;
+ struct bnx2_fw_file_section text;
+ struct bnx2_fw_file_section data;
+ struct bnx2_fw_file_section rodata;
+};
+
+struct bnx2_rv2p_fw_file_entry {
+ struct bnx2_fw_file_section rv2p;
+ __be32 fixup[8];
+};
+
+struct bnx2_mips_fw_file {
+ struct bnx2_mips_fw_file_entry com;
+ struct bnx2_mips_fw_file_entry cp;
+ struct bnx2_mips_fw_file_entry rxp;
+ struct bnx2_mips_fw_file_entry tpat;
+ struct bnx2_mips_fw_file_entry txp;
+};
+
+struct bnx2_rv2p_fw_file {
+ struct bnx2_rv2p_fw_file_entry proc1;
+ struct bnx2_rv2p_fw_file_entry proc2;
+};
+
+#define RV2P_P1_FIXUP_PAGE_SIZE_IDX 0
+#define RV2P_BD_PAGE_SIZE_MSK 0xffff
+#define RV2P_BD_PAGE_SIZE ((BNX2_PAGE_SIZE / 16) - 1)
+
#define RV2P_PROC1 0
#define RV2P_PROC2 1
@@ -6935,14 +7072,14 @@ struct fw_info {
/* This value (in milliseconds) determines the frequency of the driver
* issuing the PULSE message code. The firmware monitors this periodic
* pulse to determine when to switch to an OS-absent mode. */
-#define DRV_PULSE_PERIOD_MS 250
+#define BNX2_DRV_PULSE_PERIOD_MS 250
/* This value (in milliseconds) determines how long the driver should
* wait for an acknowledgement from the firmware before timing out. Once
* the firmware has timed out, the driver will assume there is no firmware
* running and there won't be any firmware-driver synchronization during a
* driver reset. */
-#define FW_ACK_TIME_OUT_MS 1000
+#define BNX2_FW_ACK_TIME_OUT_MS 1000
#define BNX2_DRV_RESET_SIGNATURE 0x00000000
@@ -7231,6 +7368,8 @@ struct fw_info {
#define BNX2_BC_STATE_RESET_TYPE_VALUE(msg) (BNX2_BC_STATE_RESET_TYPE_SIG | \
(msg))
+#define BNX2_BC_RESET_TYPE 0x000001c0
+
#define BNX2_BC_STATE 0x000001c4
#define BNX2_BC_STATE_ERR_MASK 0x0000ff00
#define BNX2_BC_STATE_SIGN 0x42530000
@@ -7268,6 +7407,10 @@ struct fw_info {
#define BNX2_CONDITION_MFW_RUN_NCSI 0x00006000
#define BNX2_CONDITION_MFW_RUN_NONE 0x0000e000
#define BNX2_CONDITION_MFW_RUN_MASK 0x0000e000
+#define BNX2_CONDITION_PM_STATE_MASK 0x00030000
+#define BNX2_CONDITION_PM_STATE_FULL 0x00030000
+#define BNX2_CONDITION_PM_STATE_PREP 0x00020000
+#define BNX2_CONDITION_PM_STATE_UNPREP 0x00010000
#define BNX2_BC_STATE_DEBUG_CMD 0x1dc
#define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000
@@ -7301,6 +7444,21 @@ struct fw_info {
#define BNX2_RPHY_SERDES_LINK 0x374
#define BNX2_RPHY_COPPER_LINK 0x378
+#define BNX2_ISCSI_INITIATOR 0x3dc
+#define BNX2_ISCSI_INITIATOR_EN 0x00080000
+
+#define BNX2_ISCSI_MAX_CONN 0x3e4
+#define BNX2_ISCSI_MAX_CONN_MASK 0xffff0000
+#define BNX2_ISCSI_MAX_CONN_SHIFT 16
+
#define HOST_VIEW_SHMEM_BASE 0x167c00
+#define DP_SHMEM_LINE(bp, offset) \
+ netdev_err(bp->dev, "DEBUG: %08x: %08x %08x %08x %08x\n", \
+ offset, \
+ bnx2_shmem_rd(bp, offset), \
+ bnx2_shmem_rd(bp, offset + 4), \
+ bnx2_shmem_rd(bp, offset + 8), \
+ bnx2_shmem_rd(bp, offset + 12))
+
#endif
diff --git a/drivers/net/ethernet/broadcom/bnx2_fw.h b/drivers/net/ethernet/broadcom/bnx2_fw.h
new file mode 100644
index 00000000000..940eb91f209
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2_fw.h
@@ -0,0 +1,88 @@
+/* bnx2_fw.h: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+/* Initialized Values for the Completion Processor. */
+static const struct cpu_reg cpu_reg_com = {
+ .mode = BNX2_COM_CPU_MODE,
+ .mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA,
+ .state = BNX2_COM_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_COM_CPU_REG_FILE,
+ .evmask = BNX2_COM_CPU_EVENT_MASK,
+ .pc = BNX2_COM_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_COM_CPU_INSTRUCTION,
+ .bp = BNX2_COM_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_COM_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
+/* Initialized Values the Command Processor. */
+static const struct cpu_reg cpu_reg_cp = {
+ .mode = BNX2_CP_CPU_MODE,
+ .mode_value_halt = BNX2_CP_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_CP_CPU_MODE_STEP_ENA,
+ .state = BNX2_CP_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_CP_CPU_REG_FILE,
+ .evmask = BNX2_CP_CPU_EVENT_MASK,
+ .pc = BNX2_CP_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_CP_CPU_INSTRUCTION,
+ .bp = BNX2_CP_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_CP_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
+/* Initialized Values for the RX Processor. */
+static const struct cpu_reg cpu_reg_rxp = {
+ .mode = BNX2_RXP_CPU_MODE,
+ .mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA,
+ .state = BNX2_RXP_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_RXP_CPU_REG_FILE,
+ .evmask = BNX2_RXP_CPU_EVENT_MASK,
+ .pc = BNX2_RXP_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_RXP_CPU_INSTRUCTION,
+ .bp = BNX2_RXP_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_RXP_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
+/* Initialized Values for the TX Patch-up Processor. */
+static const struct cpu_reg cpu_reg_tpat = {
+ .mode = BNX2_TPAT_CPU_MODE,
+ .mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA,
+ .state = BNX2_TPAT_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_TPAT_CPU_REG_FILE,
+ .evmask = BNX2_TPAT_CPU_EVENT_MASK,
+ .pc = BNX2_TPAT_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_TPAT_CPU_INSTRUCTION,
+ .bp = BNX2_TPAT_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_TPAT_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
+
+/* Initialized Values for the TX Processor. */
+static const struct cpu_reg cpu_reg_txp = {
+ .mode = BNX2_TXP_CPU_MODE,
+ .mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT,
+ .mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA,
+ .state = BNX2_TXP_CPU_STATE,
+ .state_value_clear = 0xffffff,
+ .gpr0 = BNX2_TXP_CPU_REG_FILE,
+ .evmask = BNX2_TXP_CPU_EVENT_MASK,
+ .pc = BNX2_TXP_CPU_PROGRAM_COUNTER,
+ .inst = BNX2_TXP_CPU_INSTRUCTION,
+ .bp = BNX2_TXP_CPU_HW_BREAKPOINT,
+ .spad_base = BNX2_TXP_SCRATCH,
+ .mips_view_base = 0x8000000,
+};
diff --git a/drivers/net/ethernet/broadcom/bnx2x/Makefile b/drivers/net/ethernet/broadcom/bnx2x/Makefile
new file mode 100644
index 00000000000..116762daae0
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for Broadcom 10-Gigabit ethernet driver
+#
+
+obj-$(CONFIG_BNX2X) += bnx2x.o
+
+bnx2x-y := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o bnx2x_sp.o
+bnx2x-$(CONFIG_BNX2X_SRIOV) += bnx2x_vfpf.o bnx2x_sriov.o
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
new file mode 100644
index 00000000000..8206a293e6b
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -0,0 +1,2557 @@
+/* bnx2x.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007-2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
+ * Written by: Eliezer Tamir
+ * Based on code from Michael Chan's bnx2 driver
+ */
+
+#ifndef BNX2X_H
+#define BNX2X_H
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/types.h>
+#include <linux/pci_regs.h>
+
+/* compilation time flags */
+
+/* define this to make the driver freeze on error to allow getting debug info
+ * (you will need to reboot afterwards) */
+/* #define BNX2X_STOP_ON_ERROR */
+
+#define DRV_MODULE_VERSION "1.78.19-0"
+#define DRV_MODULE_RELDATE "2014/02/10"
+#define BNX2X_BC_VER 0x040200
+
+#if defined(CONFIG_DCB)
+#define BCM_DCBNL
+#endif
+
+#include "bnx2x_hsi.h"
+
+#include "../cnic_if.h"
+
+#define BNX2X_MIN_MSIX_VEC_CNT(bp) ((bp)->min_msix_vec_cnt)
+
+#include <linux/mdio.h>
+
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_mfw_req.h"
+#include "bnx2x_link.h"
+#include "bnx2x_sp.h"
+#include "bnx2x_dcb.h"
+#include "bnx2x_stats.h"
+#include "bnx2x_vfpf.h"
+
+enum bnx2x_int_mode {
+ BNX2X_INT_MODE_MSIX,
+ BNX2X_INT_MODE_INTX,
+ BNX2X_INT_MODE_MSI
+};
+
+/* error/debug prints */
+
+#define DRV_MODULE_NAME "bnx2x"
+
+/* for messages that are currently off */
+#define BNX2X_MSG_OFF 0x0
+#define BNX2X_MSG_MCP 0x0010000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_STATS 0x0020000 /* was: NETIF_MSG_TIMER */
+#define BNX2X_MSG_NVM 0x0040000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_DMAE 0x0080000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_SP 0x0100000 /* was: NETIF_MSG_INTR */
+#define BNX2X_MSG_FP 0x0200000 /* was: NETIF_MSG_INTR */
+#define BNX2X_MSG_IOV 0x0800000
+#define BNX2X_MSG_IDLE 0x2000000 /* used for idle check*/
+#define BNX2X_MSG_ETHTOOL 0x4000000
+#define BNX2X_MSG_DCB 0x8000000
+
+/* regular debug print */
+#define DP_INNER(fmt, ...) \
+ pr_notice("[%s:%d(%s)]" fmt, \
+ __func__, __LINE__, \
+ bp->dev ? (bp->dev->name) : "?", \
+ ##__VA_ARGS__);
+
+#define DP(__mask, fmt, ...) \
+do { \
+ if (unlikely(bp->msg_enable & (__mask))) \
+ DP_INNER(fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define DP_AND(__mask, fmt, ...) \
+do { \
+ if (unlikely((bp->msg_enable & (__mask)) == __mask)) \
+ DP_INNER(fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define DP_CONT(__mask, fmt, ...) \
+do { \
+ if (unlikely(bp->msg_enable & (__mask))) \
+ pr_cont(fmt, ##__VA_ARGS__); \
+} while (0)
+
+/* errors debug print */
+#define BNX2X_DBG_ERR(fmt, ...) \
+do { \
+ if (unlikely(netif_msg_probe(bp))) \
+ pr_err("[%s:%d(%s)]" fmt, \
+ __func__, __LINE__, \
+ bp->dev ? (bp->dev->name) : "?", \
+ ##__VA_ARGS__); \
+} while (0)
+
+/* for errors (never masked) */
+#define BNX2X_ERR(fmt, ...) \
+do { \
+ pr_err("[%s:%d(%s)]" fmt, \
+ __func__, __LINE__, \
+ bp->dev ? (bp->dev->name) : "?", \
+ ##__VA_ARGS__); \
+} while (0)
+
+#define BNX2X_ERROR(fmt, ...) \
+ pr_err("[%s:%d]" fmt, __func__, __LINE__, ##__VA_ARGS__)
+
+/* before we have a dev->name use dev_info() */
+#define BNX2X_DEV_INFO(fmt, ...) \
+do { \
+ if (unlikely(netif_msg_probe(bp))) \
+ dev_info(&bp->pdev->dev, fmt, ##__VA_ARGS__); \
+} while (0)
+
+/* Error handling */
+void bnx2x_panic_dump(struct bnx2x *bp, bool disable_int);
+#ifdef BNX2X_STOP_ON_ERROR
+#define bnx2x_panic() \
+do { \
+ bp->panic = 1; \
+ BNX2X_ERR("driver assert\n"); \
+ bnx2x_panic_dump(bp, true); \
+} while (0)
+#else
+#define bnx2x_panic() \
+do { \
+ bp->panic = 1; \
+ BNX2X_ERR("driver assert\n"); \
+ bnx2x_panic_dump(bp, false); \
+} while (0)
+#endif
+
+#define bnx2x_mc_addr(ha) ((ha)->addr)
+#define bnx2x_uc_addr(ha) ((ha)->addr)
+
+#define U64_LO(x) ((u32)(((u64)(x)) & 0xffffffff))
+#define U64_HI(x) ((u32)(((u64)(x)) >> 32))
+#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo))
+
+#define REG_ADDR(bp, offset) ((bp->regview) + (offset))
+
+#define REG_RD(bp, offset) readl(REG_ADDR(bp, offset))
+#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
+#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset))
+
+#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
+#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
+#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
+
+#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset)
+#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val)
+
+#define REG_RD_DMAE(bp, offset, valp, len32) \
+ do { \
+ bnx2x_read_dmae(bp, offset, len32);\
+ memcpy(valp, bnx2x_sp(bp, wb_data[0]), (len32) * 4); \
+ } while (0)
+
+#define REG_WR_DMAE(bp, offset, valp, len32) \
+ do { \
+ memcpy(bnx2x_sp(bp, wb_data[0]), valp, (len32) * 4); \
+ bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \
+ offset, len32); \
+ } while (0)
+
+#define REG_WR_DMAE_LEN(bp, offset, valp, len32) \
+ REG_WR_DMAE(bp, offset, valp, len32)
+
+#define VIRT_WR_DMAE_LEN(bp, data, addr, len32, le32_swap) \
+ do { \
+ memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \
+ bnx2x_write_big_buf_wb(bp, addr, len32); \
+ } while (0)
+
+#define SHMEM_ADDR(bp, field) (bp->common.shmem_base + \
+ offsetof(struct shmem_region, field))
+#define SHMEM_RD(bp, field) REG_RD(bp, SHMEM_ADDR(bp, field))
+#define SHMEM_WR(bp, field, val) REG_WR(bp, SHMEM_ADDR(bp, field), val)
+
+#define SHMEM2_ADDR(bp, field) (bp->common.shmem2_base + \
+ offsetof(struct shmem2_region, field))
+#define SHMEM2_RD(bp, field) REG_RD(bp, SHMEM2_ADDR(bp, field))
+#define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val)
+#define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \
+ offsetof(struct mf_cfg, field))
+#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \
+ offsetof(struct mf2_cfg, field))
+
+#define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field))
+#define MF_CFG_WR(bp, field, val) REG_WR(bp,\
+ MF_CFG_ADDR(bp, field), (val))
+#define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field))
+
+#define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \
+ (SHMEM2_RD((bp), size) > \
+ offsetof(struct shmem2_region, field)))
+
+#define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg)
+#define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val)
+
+/* SP SB indices */
+
+/* General SP events - stats query, cfc delete, etc */
+#define HC_SP_INDEX_ETH_DEF_CONS 3
+
+/* EQ completions */
+#define HC_SP_INDEX_EQ_CONS 7
+
+/* FCoE L2 connection completions */
+#define HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS 6
+#define HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS 4
+/* iSCSI L2 */
+#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5
+#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1
+
+/* Special clients parameters */
+
+/* SB indices */
+/* FCoE L2 */
+#define BNX2X_FCOE_L2_RX_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS])
+
+#define BNX2X_FCOE_L2_TX_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS])
+
+/**
+ * CIDs and CLIDs:
+ * CLIDs below is a CLID for func 0, then the CLID for other
+ * functions will be calculated by the formula:
+ *
+ * FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X
+ *
+ */
+enum {
+ BNX2X_ISCSI_ETH_CL_ID_IDX,
+ BNX2X_FCOE_ETH_CL_ID_IDX,
+ BNX2X_MAX_CNIC_ETH_CL_ID_IDX,
+};
+
+/* use a value high enough to be above all the PFs, which has least significant
+ * nibble as 8, so when cnic needs to come up with a CID for UIO to use to
+ * calculate doorbell address according to old doorbell configuration scheme
+ * (db_msg_sz 1 << 7 * cid + 0x40 DPM offset) it can come up with a valid number
+ * We must avoid coming up with cid 8 for iscsi since according to this method
+ * the designated UIO cid will come out 0 and it has a special handling for that
+ * case which doesn't suit us. Therefore will will cieling to closes cid which
+ * has least signigifcant nibble 8 and if it is 8 we will move forward to 0x18.
+ */
+
+#define BNX2X_1st_NON_L2_ETH_CID(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) * \
+ (bp)->max_cos)
+/* amount of cids traversed by UIO's DPM addition to doorbell */
+#define UIO_DPM 8
+/* roundup to DPM offset */
+#define UIO_ROUNDUP(bp) (roundup(BNX2X_1st_NON_L2_ETH_CID(bp), \
+ UIO_DPM))
+/* offset to nearest value which has lsb nibble matching DPM */
+#define UIO_CID_OFFSET(bp) ((UIO_ROUNDUP(bp) + UIO_DPM) % \
+ (UIO_DPM * 2))
+/* add offset to rounded-up cid to get a value which could be used with UIO */
+#define UIO_DPM_ALIGN(bp) (UIO_ROUNDUP(bp) + UIO_CID_OFFSET(bp))
+/* but wait - avoid UIO special case for cid 0 */
+#define UIO_DPM_CID0_OFFSET(bp) ((UIO_DPM * 2) * \
+ (UIO_DPM_ALIGN(bp) == UIO_DPM))
+/* Properly DPM aligned CID dajusted to cid 0 secal case */
+#define BNX2X_CNIC_START_ETH_CID(bp) (UIO_DPM_ALIGN(bp) + \
+ (UIO_DPM_CID0_OFFSET(bp)))
+/* how many cids were wasted - need this value for cid allocation */
+#define UIO_CID_PAD(bp) (BNX2X_CNIC_START_ETH_CID(bp) - \
+ BNX2X_1st_NON_L2_ETH_CID(bp))
+ /* iSCSI L2 */
+#define BNX2X_ISCSI_ETH_CID(bp) (BNX2X_CNIC_START_ETH_CID(bp))
+ /* FCoE L2 */
+#define BNX2X_FCOE_ETH_CID(bp) (BNX2X_CNIC_START_ETH_CID(bp) + 1)
+
+#define CNIC_SUPPORT(bp) ((bp)->cnic_support)
+#define CNIC_ENABLED(bp) ((bp)->cnic_enabled)
+#define CNIC_LOADED(bp) ((bp)->cnic_loaded)
+#define FCOE_INIT(bp) ((bp)->fcoe_init)
+
+#define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \
+ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR
+
+#define SM_RX_ID 0
+#define SM_TX_ID 1
+
+/* defines for multiple tx priority indices */
+#define FIRST_TX_ONLY_COS_INDEX 1
+#define FIRST_TX_COS_INDEX 0
+
+/* rules for calculating the cids of tx-only connections */
+#define CID_TO_FP(cid, bp) ((cid) % BNX2X_NUM_NON_CNIC_QUEUES(bp))
+#define CID_COS_TO_TX_ONLY_CID(cid, cos, bp) \
+ (cid + cos * BNX2X_NUM_NON_CNIC_QUEUES(bp))
+
+/* fp index inside class of service range */
+#define FP_COS_TO_TXQ(fp, cos, bp) \
+ ((fp)->index + cos * BNX2X_NUM_NON_CNIC_QUEUES(bp))
+
+/* Indexes for transmission queues array:
+ * txdata for RSS i CoS j is at location i + (j * num of RSS)
+ * txdata for FCoE (if exist) is at location max cos * num of RSS
+ * txdata for FWD (if exist) is one location after FCoE
+ * txdata for OOO (if exist) is one location after FWD
+ */
+enum {
+ FCOE_TXQ_IDX_OFFSET,
+ FWD_TXQ_IDX_OFFSET,
+ OOO_TXQ_IDX_OFFSET,
+};
+#define MAX_ETH_TXQ_IDX(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) * (bp)->max_cos)
+#define FCOE_TXQ_IDX(bp) (MAX_ETH_TXQ_IDX(bp) + FCOE_TXQ_IDX_OFFSET)
+
+/* fast path */
+/*
+ * This driver uses new build_skb() API :
+ * RX ring buffer contains pointer to kmalloc() data only,
+ * skb are built only after Hardware filled the frame.
+ */
+struct sw_rx_bd {
+ u8 *data;
+ DEFINE_DMA_UNMAP_ADDR(mapping);
+};
+
+struct sw_tx_bd {
+ struct sk_buff *skb;
+ u16 first_bd;
+ u8 flags;
+/* Set on the first BD descriptor when there is a split BD */
+#define BNX2X_TSO_SPLIT_BD (1<<0)
+#define BNX2X_HAS_SECOND_PBD (1<<1)
+};
+
+struct sw_rx_page {
+ struct page *page;
+ DEFINE_DMA_UNMAP_ADDR(mapping);
+};
+
+union db_prod {
+ struct doorbell_set_prod data;
+ u32 raw;
+};
+
+/* dropless fc FW/HW related params */
+#define BRB_SIZE(bp) (CHIP_IS_E3(bp) ? 1024 : 512)
+#define MAX_AGG_QS(bp) (CHIP_IS_E1(bp) ? \
+ ETH_MAX_AGGREGATION_QUEUES_E1 :\
+ ETH_MAX_AGGREGATION_QUEUES_E1H_E2)
+#define FW_DROP_LEVEL(bp) (3 + MAX_SPQ_PENDING + MAX_AGG_QS(bp))
+#define FW_PREFETCH_CNT 16
+#define DROPLESS_FC_HEADROOM 100
+
+/* MC hsi */
+#define BCM_PAGE_SHIFT 12
+#define BCM_PAGE_SIZE (1 << BCM_PAGE_SHIFT)
+#define BCM_PAGE_MASK (~(BCM_PAGE_SIZE - 1))
+#define BCM_PAGE_ALIGN(addr) (((addr) + BCM_PAGE_SIZE - 1) & BCM_PAGE_MASK)
+
+#define PAGES_PER_SGE_SHIFT 0
+#define PAGES_PER_SGE (1 << PAGES_PER_SGE_SHIFT)
+#define SGE_PAGE_SIZE PAGE_SIZE
+#define SGE_PAGE_SHIFT PAGE_SHIFT
+#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))(addr))
+#define SGE_PAGES (SGE_PAGE_SIZE * PAGES_PER_SGE)
+#define TPA_AGG_SIZE min_t(u32, (min_t(u32, 8, MAX_SKB_FRAGS) * \
+ SGE_PAGES), 0xffff)
+
+/* SGE ring related macros */
+#define NUM_RX_SGE_PAGES 2
+#define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
+#define NEXT_PAGE_SGE_DESC_CNT 2
+#define MAX_RX_SGE_CNT (RX_SGE_CNT - NEXT_PAGE_SGE_DESC_CNT)
+/* RX_SGE_CNT is promised to be a power of 2 */
+#define RX_SGE_MASK (RX_SGE_CNT - 1)
+#define NUM_RX_SGE (RX_SGE_CNT * NUM_RX_SGE_PAGES)
+#define MAX_RX_SGE (NUM_RX_SGE - 1)
+#define NEXT_SGE_IDX(x) ((((x) & RX_SGE_MASK) == \
+ (MAX_RX_SGE_CNT - 1)) ? \
+ (x) + 1 + NEXT_PAGE_SGE_DESC_CNT : \
+ (x) + 1)
+#define RX_SGE(x) ((x) & MAX_RX_SGE)
+
+/*
+ * Number of required SGEs is the sum of two:
+ * 1. Number of possible opened aggregations (next packet for
+ * these aggregations will probably consume SGE immediately)
+ * 2. Rest of BRB blocks divided by 2 (block will consume new SGE only
+ * after placement on BD for new TPA aggregation)
+ *
+ * Takes into account NEXT_PAGE_SGE_DESC_CNT "next" elements on each page
+ */
+#define NUM_SGE_REQ (MAX_AGG_QS(bp) + \
+ (BRB_SIZE(bp) - MAX_AGG_QS(bp)) / 2)
+#define NUM_SGE_PG_REQ ((NUM_SGE_REQ + MAX_RX_SGE_CNT - 1) / \
+ MAX_RX_SGE_CNT)
+#define SGE_TH_LO(bp) (NUM_SGE_REQ + \
+ NUM_SGE_PG_REQ * NEXT_PAGE_SGE_DESC_CNT)
+#define SGE_TH_HI(bp) (SGE_TH_LO(bp) + DROPLESS_FC_HEADROOM)
+
+/* Manipulate a bit vector defined as an array of u64 */
+
+/* Number of bits in one sge_mask array element */
+#define BIT_VEC64_ELEM_SZ 64
+#define BIT_VEC64_ELEM_SHIFT 6
+#define BIT_VEC64_ELEM_MASK ((u64)BIT_VEC64_ELEM_SZ - 1)
+
+#define __BIT_VEC64_SET_BIT(el, bit) \
+ do { \
+ el = ((el) | ((u64)0x1 << (bit))); \
+ } while (0)
+
+#define __BIT_VEC64_CLEAR_BIT(el, bit) \
+ do { \
+ el = ((el) & (~((u64)0x1 << (bit)))); \
+ } while (0)
+
+#define BIT_VEC64_SET_BIT(vec64, idx) \
+ __BIT_VEC64_SET_BIT((vec64)[(idx) >> BIT_VEC64_ELEM_SHIFT], \
+ (idx) & BIT_VEC64_ELEM_MASK)
+
+#define BIT_VEC64_CLEAR_BIT(vec64, idx) \
+ __BIT_VEC64_CLEAR_BIT((vec64)[(idx) >> BIT_VEC64_ELEM_SHIFT], \
+ (idx) & BIT_VEC64_ELEM_MASK)
+
+#define BIT_VEC64_TEST_BIT(vec64, idx) \
+ (((vec64)[(idx) >> BIT_VEC64_ELEM_SHIFT] >> \
+ ((idx) & BIT_VEC64_ELEM_MASK)) & 0x1)
+
+/* Creates a bitmask of all ones in less significant bits.
+ idx - index of the most significant bit in the created mask */
+#define BIT_VEC64_ONES_MASK(idx) \
+ (((u64)0x1 << (((idx) & BIT_VEC64_ELEM_MASK) + 1)) - 1)
+#define BIT_VEC64_ELEM_ONE_MASK ((u64)(~0))
+
+/*******************************************************/
+
+/* Number of u64 elements in SGE mask array */
+#define RX_SGE_MASK_LEN (NUM_RX_SGE / BIT_VEC64_ELEM_SZ)
+#define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1)
+#define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK)
+
+union host_hc_status_block {
+ /* pointer to fp status block e1x */
+ struct host_hc_status_block_e1x *e1x_sb;
+ /* pointer to fp status block e2 */
+ struct host_hc_status_block_e2 *e2_sb;
+};
+
+struct bnx2x_agg_info {
+ /*
+ * First aggregation buffer is a data buffer, the following - are pages.
+ * We will preallocate the data buffer for each aggregation when
+ * we open the interface and will replace the BD at the consumer
+ * with this one when we receive the TPA_START CQE in order to
+ * keep the Rx BD ring consistent.
+ */
+ struct sw_rx_bd first_buf;
+ u8 tpa_state;
+#define BNX2X_TPA_START 1
+#define BNX2X_TPA_STOP 2
+#define BNX2X_TPA_ERROR 3
+ u8 placement_offset;
+ u16 parsing_flags;
+ u16 vlan_tag;
+ u16 len_on_bd;
+ u32 rxhash;
+ enum pkt_hash_types rxhash_type;
+ u16 gro_size;
+ u16 full_page;
+};
+
+#define Q_STATS_OFFSET32(stat_name) \
+ (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4)
+
+struct bnx2x_fp_txdata {
+
+ struct sw_tx_bd *tx_buf_ring;
+
+ union eth_tx_bd_types *tx_desc_ring;
+ dma_addr_t tx_desc_mapping;
+
+ u32 cid;
+
+ union db_prod tx_db;
+
+ u16 tx_pkt_prod;
+ u16 tx_pkt_cons;
+ u16 tx_bd_prod;
+ u16 tx_bd_cons;
+
+ unsigned long tx_pkt;
+
+ __le16 *tx_cons_sb;
+
+ int txq_index;
+ struct bnx2x_fastpath *parent_fp;
+ int tx_ring_size;
+};
+
+enum bnx2x_tpa_mode_t {
+ TPA_MODE_LRO,
+ TPA_MODE_GRO
+};
+
+struct bnx2x_fastpath {
+ struct bnx2x *bp; /* parent */
+
+ struct napi_struct napi;
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ unsigned int state;
+#define BNX2X_FP_STATE_IDLE 0
+#define BNX2X_FP_STATE_NAPI (1 << 0) /* NAPI owns this FP */
+#define BNX2X_FP_STATE_POLL (1 << 1) /* poll owns this FP */
+#define BNX2X_FP_STATE_DISABLED (1 << 2)
+#define BNX2X_FP_STATE_NAPI_YIELD (1 << 3) /* NAPI yielded this FP */
+#define BNX2X_FP_STATE_POLL_YIELD (1 << 4) /* poll yielded this FP */
+#define BNX2X_FP_OWNED (BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
+#define BNX2X_FP_YIELD (BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)
+#define BNX2X_FP_LOCKED (BNX2X_FP_OWNED | BNX2X_FP_STATE_DISABLED)
+#define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
+ /* protect state */
+ spinlock_t lock;
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
+ union host_hc_status_block status_blk;
+ /* chip independent shortcuts into sb structure */
+ __le16 *sb_index_values;
+ __le16 *sb_running_index;
+ /* chip independent shortcut into rx_prods_offset memory */
+ u32 ustorm_rx_prods_offset;
+
+ u32 rx_buf_size;
+ u32 rx_frag_size; /* 0 if kmalloced(), or rx_buf_size + NET_SKB_PAD */
+ dma_addr_t status_blk_mapping;
+
+ enum bnx2x_tpa_mode_t mode;
+
+ u8 max_cos; /* actual number of active tx coses */
+ struct bnx2x_fp_txdata *txdata_ptr[BNX2X_MULTI_TX_COS];
+
+ struct sw_rx_bd *rx_buf_ring; /* BDs mappings ring */
+ struct sw_rx_page *rx_page_ring; /* SGE pages mappings ring */
+
+ struct eth_rx_bd *rx_desc_ring;
+ dma_addr_t rx_desc_mapping;
+
+ union eth_rx_cqe *rx_comp_ring;
+ dma_addr_t rx_comp_mapping;
+
+ /* SGE ring */
+ struct eth_rx_sge *rx_sge_ring;
+ dma_addr_t rx_sge_mapping;
+
+ u64 sge_mask[RX_SGE_MASK_LEN];
+
+ u32 cid;
+
+ __le16 fp_hc_idx;
+
+ u8 index; /* number in fp array */
+ u8 rx_queue; /* index for skb_record */
+ u8 cl_id; /* eth client id */
+ u8 cl_qzone_id;
+ u8 fw_sb_id; /* status block number in FW */
+ u8 igu_sb_id; /* status block number in HW */
+
+ u16 rx_bd_prod;
+ u16 rx_bd_cons;
+ u16 rx_comp_prod;
+ u16 rx_comp_cons;
+ u16 rx_sge_prod;
+ /* The last maximal completed SGE */
+ u16 last_max_sge;
+ __le16 *rx_cons_sb;
+ unsigned long rx_pkt,
+ rx_calls;
+
+ /* TPA related */
+ struct bnx2x_agg_info *tpa_info;
+ u8 disable_tpa;
+#ifdef BNX2X_STOP_ON_ERROR
+ u64 tpa_queue_used;
+#endif
+ /* The size is calculated using the following:
+ sizeof name field from netdev structure +
+ 4 ('-Xx-' string) +
+ 4 (for the digits and to make it DWORD aligned) */
+#define FP_NAME_SIZE (sizeof(((struct net_device *)0)->name) + 8)
+ char name[FP_NAME_SIZE];
+};
+
+#define bnx2x_fp(bp, nr, var) ((bp)->fp[(nr)].var)
+#define bnx2x_sp_obj(bp, fp) ((bp)->sp_objs[(fp)->index])
+#define bnx2x_fp_stats(bp, fp) (&((bp)->fp_stats[(fp)->index]))
+#define bnx2x_fp_qstats(bp, fp) (&((bp)->fp_stats[(fp)->index].eth_q_stats))
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
+{
+ spin_lock_init(&fp->lock);
+ fp->state = BNX2X_FP_STATE_IDLE;
+}
+
+/* called from the device poll routine to get ownership of a FP */
+static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
+{
+ bool rc = true;
+
+ spin_lock_bh(&fp->lock);
+ if (fp->state & BNX2X_FP_LOCKED) {
+ WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
+ fp->state |= BNX2X_FP_STATE_NAPI_YIELD;
+ rc = false;
+ } else {
+ /* we don't care if someone yielded */
+ fp->state = BNX2X_FP_STATE_NAPI;
+ }
+ spin_unlock_bh(&fp->lock);
+ return rc;
+}
+
+/* returns true is someone tried to get the FP while napi had it */
+static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
+{
+ bool rc = false;
+
+ spin_lock_bh(&fp->lock);
+ WARN_ON(fp->state &
+ (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));
+
+ if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
+ rc = true;
+
+ /* state ==> idle, unless currently disabled */
+ fp->state &= BNX2X_FP_STATE_DISABLED;
+ spin_unlock_bh(&fp->lock);
+ return rc;
+}
+
+/* called from bnx2x_low_latency_poll() */
+static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
+{
+ bool rc = true;
+
+ spin_lock_bh(&fp->lock);
+ if ((fp->state & BNX2X_FP_LOCKED)) {
+ fp->state |= BNX2X_FP_STATE_POLL_YIELD;
+ rc = false;
+ } else {
+ /* preserve yield marks */
+ fp->state |= BNX2X_FP_STATE_POLL;
+ }
+ spin_unlock_bh(&fp->lock);
+ return rc;
+}
+
+/* returns true if someone tried to get the FP while it was locked */
+static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
+{
+ bool rc = false;
+
+ spin_lock_bh(&fp->lock);
+ WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
+
+ if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
+ rc = true;
+
+ /* state ==> idle, unless currently disabled */
+ fp->state &= BNX2X_FP_STATE_DISABLED;
+ spin_unlock_bh(&fp->lock);
+ return rc;
+}
+
+/* true if a socket is polling, even if it did not get the lock */
+static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
+{
+ WARN_ON(!(fp->state & BNX2X_FP_OWNED));
+ return fp->state & BNX2X_FP_USER_PEND;
+}
+
+/* false if fp is currently owned */
+static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
+{
+ int rc = true;
+
+ spin_lock_bh(&fp->lock);
+ if (fp->state & BNX2X_FP_OWNED)
+ rc = false;
+ fp->state |= BNX2X_FP_STATE_DISABLED;
+ spin_unlock_bh(&fp->lock);
+
+ return rc;
+}
+#else
+static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
+{
+}
+
+static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
+{
+ return true;
+}
+
+static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
+{
+ return false;
+}
+
+static inline bool bnx2x_fp_lock_poll(struct bnx2x_fastpath *fp)
+{
+ return false;
+}
+
+static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
+{
+ return false;
+}
+
+static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
+{
+ return false;
+}
+static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
+{
+ return true;
+}
+#endif /* CONFIG_NET_RX_BUSY_POLL */
+
+/* Use 2500 as a mini-jumbo MTU for FCoE */
+#define BNX2X_FCOE_MINI_JUMBO_MTU 2500
+
+#define FCOE_IDX_OFFSET 0
+
+#define FCOE_IDX(bp) (BNX2X_NUM_NON_CNIC_QUEUES(bp) + \
+ FCOE_IDX_OFFSET)
+#define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX(bp)])
+#define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var)
+#define bnx2x_fcoe_inner_sp_obj(bp) (&bp->sp_objs[FCOE_IDX(bp)])
+#define bnx2x_fcoe_sp_obj(bp, var) (bnx2x_fcoe_inner_sp_obj(bp)->var)
+#define bnx2x_fcoe_tx(bp, var) (bnx2x_fcoe_fp(bp)-> \
+ txdata_ptr[FIRST_TX_COS_INDEX] \
+ ->var)
+
+#define IS_ETH_FP(fp) ((fp)->index < BNX2X_NUM_ETH_QUEUES((fp)->bp))
+#define IS_FCOE_FP(fp) ((fp)->index == FCOE_IDX((fp)->bp))
+#define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX(bp))
+
+/* MC hsi */
+#define MAX_FETCH_BD 13 /* HW max BDs per packet */
+#define RX_COPY_THRESH 92
+
+#define NUM_TX_RINGS 16
+#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_tx_bd_types))
+#define NEXT_PAGE_TX_DESC_CNT 1
+#define MAX_TX_DESC_CNT (TX_DESC_CNT - NEXT_PAGE_TX_DESC_CNT)
+#define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS)
+#define MAX_TX_BD (NUM_TX_BD - 1)
+#define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2)
+#define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \
+ (MAX_TX_DESC_CNT - 1)) ? \
+ (x) + 1 + NEXT_PAGE_TX_DESC_CNT : \
+ (x) + 1)
+#define TX_BD(x) ((x) & MAX_TX_BD)
+#define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT)
+
+/* number of NEXT_PAGE descriptors may be required during placement */
+#define NEXT_CNT_PER_TX_PKT(bds) \
+ (((bds) + MAX_TX_DESC_CNT - 1) / \
+ MAX_TX_DESC_CNT * NEXT_PAGE_TX_DESC_CNT)
+/* max BDs per tx packet w/o next_pages:
+ * START_BD - describes packed
+ * START_BD(splitted) - includes unpaged data segment for GSO
+ * PARSING_BD - for TSO and CSUM data
+ * PARSING_BD2 - for encapsulation data
+ * Frag BDs - describes pages for frags
+ */
+#define BDS_PER_TX_PKT 4
+#define MAX_BDS_PER_TX_PKT (MAX_SKB_FRAGS + BDS_PER_TX_PKT)
+/* max BDs per tx packet including next pages */
+#define MAX_DESC_PER_TX_PKT (MAX_BDS_PER_TX_PKT + \
+ NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT))
+
+/* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */
+#define NUM_RX_RINGS 8
+#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
+#define NEXT_PAGE_RX_DESC_CNT 2
+#define MAX_RX_DESC_CNT (RX_DESC_CNT - NEXT_PAGE_RX_DESC_CNT)
+#define RX_DESC_MASK (RX_DESC_CNT - 1)
+#define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS)
+#define MAX_RX_BD (NUM_RX_BD - 1)
+#define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
+
+/* dropless fc calculations for BDs
+ *
+ * Number of BDs should as number of buffers in BRB:
+ * Low threshold takes into account NEXT_PAGE_RX_DESC_CNT
+ * "next" elements on each page
+ */
+#define NUM_BD_REQ BRB_SIZE(bp)
+#define NUM_BD_PG_REQ ((NUM_BD_REQ + MAX_RX_DESC_CNT - 1) / \
+ MAX_RX_DESC_CNT)
+#define BD_TH_LO(bp) (NUM_BD_REQ + \
+ NUM_BD_PG_REQ * NEXT_PAGE_RX_DESC_CNT + \
+ FW_DROP_LEVEL(bp))
+#define BD_TH_HI(bp) (BD_TH_LO(bp) + DROPLESS_FC_HEADROOM)
+
+#define MIN_RX_AVAIL ((bp)->dropless_fc ? BD_TH_HI(bp) + 128 : 128)
+
+#define MIN_RX_SIZE_TPA_HW (CHIP_IS_E1(bp) ? \
+ ETH_MIN_RX_CQES_WITH_TPA_E1 : \
+ ETH_MIN_RX_CQES_WITH_TPA_E1H_E2)
+#define MIN_RX_SIZE_NONTPA_HW ETH_MIN_RX_CQES_WITHOUT_TPA
+#define MIN_RX_SIZE_TPA (max_t(u32, MIN_RX_SIZE_TPA_HW, MIN_RX_AVAIL))
+#define MIN_RX_SIZE_NONTPA (max_t(u32, MIN_RX_SIZE_NONTPA_HW,\
+ MIN_RX_AVAIL))
+
+#define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \
+ (MAX_RX_DESC_CNT - 1)) ? \
+ (x) + 1 + NEXT_PAGE_RX_DESC_CNT : \
+ (x) + 1)
+#define RX_BD(x) ((x) & MAX_RX_BD)
+
+/*
+ * As long as CQE is X times bigger than BD entry we have to allocate X times
+ * more pages for CQ ring in order to keep it balanced with BD ring
+ */
+#define CQE_BD_REL (sizeof(union eth_rx_cqe) / sizeof(struct eth_rx_bd))
+#define NUM_RCQ_RINGS (NUM_RX_RINGS * CQE_BD_REL)
+#define RCQ_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe))
+#define NEXT_PAGE_RCQ_DESC_CNT 1
+#define MAX_RCQ_DESC_CNT (RCQ_DESC_CNT - NEXT_PAGE_RCQ_DESC_CNT)
+#define NUM_RCQ_BD (RCQ_DESC_CNT * NUM_RCQ_RINGS)
+#define MAX_RCQ_BD (NUM_RCQ_BD - 1)
+#define MAX_RCQ_AVAIL (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2)
+#define NEXT_RCQ_IDX(x) ((((x) & MAX_RCQ_DESC_CNT) == \
+ (MAX_RCQ_DESC_CNT - 1)) ? \
+ (x) + 1 + NEXT_PAGE_RCQ_DESC_CNT : \
+ (x) + 1)
+#define RCQ_BD(x) ((x) & MAX_RCQ_BD)
+
+/* dropless fc calculations for RCQs
+ *
+ * Number of RCQs should be as number of buffers in BRB:
+ * Low threshold takes into account NEXT_PAGE_RCQ_DESC_CNT
+ * "next" elements on each page
+ */
+#define NUM_RCQ_REQ BRB_SIZE(bp)
+#define NUM_RCQ_PG_REQ ((NUM_BD_REQ + MAX_RCQ_DESC_CNT - 1) / \
+ MAX_RCQ_DESC_CNT)
+#define RCQ_TH_LO(bp) (NUM_RCQ_REQ + \
+ NUM_RCQ_PG_REQ * NEXT_PAGE_RCQ_DESC_CNT + \
+ FW_DROP_LEVEL(bp))
+#define RCQ_TH_HI(bp) (RCQ_TH_LO(bp) + DROPLESS_FC_HEADROOM)
+
+/* This is needed for determining of last_max */
+#define SUB_S16(a, b) (s16)((s16)(a) - (s16)(b))
+#define SUB_S32(a, b) (s32)((s32)(a) - (s32)(b))
+
+#define BNX2X_SWCID_SHIFT 17
+#define BNX2X_SWCID_MASK ((0x1 << BNX2X_SWCID_SHIFT) - 1)
+
+/* used on a CID received from the HW */
+#define SW_CID(x) (le32_to_cpu(x) & BNX2X_SWCID_MASK)
+#define CQE_CMD(x) (le32_to_cpu(x) >> \
+ COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT)
+
+#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr_hi), \
+ le32_to_cpu((bd)->addr_lo))
+#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes))
+
+#define BNX2X_DB_MIN_SHIFT 3 /* 8 bytes */
+#define BNX2X_DB_SHIFT 3 /* 8 bytes*/
+#if (BNX2X_DB_SHIFT < BNX2X_DB_MIN_SHIFT)
+#error "Min DB doorbell stride is 8"
+#endif
+#define DOORBELL(bp, cid, val) \
+ do { \
+ writel((u32)(val), bp->doorbells + (bp->db_size * (cid))); \
+ } while (0)
+
+/* TX CSUM helpers */
+#define SKB_CS_OFF(skb) (offsetof(struct tcphdr, check) - \
+ skb->csum_offset)
+#define SKB_CS(skb) (*(u16 *)(skb_transport_header(skb) + \
+ skb->csum_offset))
+
+#define pbd_tcp_flags(tcp_hdr) (ntohl(tcp_flag_word(tcp_hdr))>>16 & 0xff)
+
+#define XMIT_PLAIN 0
+#define XMIT_CSUM_V4 (1 << 0)
+#define XMIT_CSUM_V6 (1 << 1)
+#define XMIT_CSUM_TCP (1 << 2)
+#define XMIT_GSO_V4 (1 << 3)
+#define XMIT_GSO_V6 (1 << 4)
+#define XMIT_CSUM_ENC_V4 (1 << 5)
+#define XMIT_CSUM_ENC_V6 (1 << 6)
+#define XMIT_GSO_ENC_V4 (1 << 7)
+#define XMIT_GSO_ENC_V6 (1 << 8)
+
+#define XMIT_CSUM_ENC (XMIT_CSUM_ENC_V4 | XMIT_CSUM_ENC_V6)
+#define XMIT_GSO_ENC (XMIT_GSO_ENC_V4 | XMIT_GSO_ENC_V6)
+
+#define XMIT_CSUM (XMIT_CSUM_V4 | XMIT_CSUM_V6 | XMIT_CSUM_ENC)
+#define XMIT_GSO (XMIT_GSO_V4 | XMIT_GSO_V6 | XMIT_GSO_ENC)
+
+/* stuff added to make the code fit 80Col */
+#define CQE_TYPE(cqe_fp_flags) ((cqe_fp_flags) & ETH_FAST_PATH_RX_CQE_TYPE)
+#define CQE_TYPE_START(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_START_AGG)
+#define CQE_TYPE_STOP(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_STOP_AGG)
+#define CQE_TYPE_SLOW(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_RAMROD)
+#define CQE_TYPE_FAST(cqe_type) ((cqe_type) == RX_ETH_CQE_TYPE_ETH_FASTPATH)
+
+#define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG
+
+#define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \
+ (((le16_to_cpu(flags) & \
+ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \
+ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT) \
+ == PRS_FLAG_OVERETH_IPV4)
+#define BNX2X_RX_SUM_FIX(cqe) \
+ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags)
+
+#define FP_USB_FUNC_OFF \
+ offsetof(struct cstorm_status_block_u, func)
+#define FP_CSB_FUNC_OFF \
+ offsetof(struct cstorm_status_block_c, func)
+
+#define HC_INDEX_ETH_RX_CQ_CONS 1
+
+#define HC_INDEX_OOO_TX_CQ_CONS 4
+
+#define HC_INDEX_ETH_TX_CQ_CONS_COS0 5
+
+#define HC_INDEX_ETH_TX_CQ_CONS_COS1 6
+
+#define HC_INDEX_ETH_TX_CQ_CONS_COS2 7
+
+#define HC_INDEX_ETH_FIRST_TX_CQ_CONS HC_INDEX_ETH_TX_CQ_CONS_COS0
+
+#define BNX2X_RX_SB_INDEX \
+ (&fp->sb_index_values[HC_INDEX_ETH_RX_CQ_CONS])
+
+#define BNX2X_TX_SB_INDEX_BASE BNX2X_TX_SB_INDEX_COS0
+
+#define BNX2X_TX_SB_INDEX_COS0 \
+ (&fp->sb_index_values[HC_INDEX_ETH_TX_CQ_CONS_COS0])
+
+/* end of fast path */
+
+/* common */
+
+struct bnx2x_common {
+
+ u32 chip_id;
+/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
+#define CHIP_ID(bp) (bp->common.chip_id & 0xfffffff0)
+
+#define CHIP_NUM(bp) (bp->common.chip_id >> 16)
+#define CHIP_NUM_57710 0x164e
+#define CHIP_NUM_57711 0x164f
+#define CHIP_NUM_57711E 0x1650
+#define CHIP_NUM_57712 0x1662
+#define CHIP_NUM_57712_MF 0x1663
+#define CHIP_NUM_57712_VF 0x166f
+#define CHIP_NUM_57713 0x1651
+#define CHIP_NUM_57713E 0x1652
+#define CHIP_NUM_57800 0x168a
+#define CHIP_NUM_57800_MF 0x16a5
+#define CHIP_NUM_57800_VF 0x16a9
+#define CHIP_NUM_57810 0x168e
+#define CHIP_NUM_57810_MF 0x16ae
+#define CHIP_NUM_57810_VF 0x16af
+#define CHIP_NUM_57811 0x163d
+#define CHIP_NUM_57811_MF 0x163e
+#define CHIP_NUM_57811_VF 0x163f
+#define CHIP_NUM_57840_OBSOLETE 0x168d
+#define CHIP_NUM_57840_MF_OBSOLETE 0x16ab
+#define CHIP_NUM_57840_4_10 0x16a1
+#define CHIP_NUM_57840_2_20 0x16a2
+#define CHIP_NUM_57840_MF 0x16a4
+#define CHIP_NUM_57840_VF 0x16ad
+#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710)
+#define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711)
+#define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E)
+#define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712)
+#define CHIP_IS_57712_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57712_VF)
+#define CHIP_IS_57712_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57712_MF)
+#define CHIP_IS_57800(bp) (CHIP_NUM(bp) == CHIP_NUM_57800)
+#define CHIP_IS_57800_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57800_MF)
+#define CHIP_IS_57800_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57800_VF)
+#define CHIP_IS_57810(bp) (CHIP_NUM(bp) == CHIP_NUM_57810)
+#define CHIP_IS_57810_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57810_MF)
+#define CHIP_IS_57810_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57810_VF)
+#define CHIP_IS_57811(bp) (CHIP_NUM(bp) == CHIP_NUM_57811)
+#define CHIP_IS_57811_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57811_MF)
+#define CHIP_IS_57811_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57811_VF)
+#define CHIP_IS_57840(bp) \
+ ((CHIP_NUM(bp) == CHIP_NUM_57840_4_10) || \
+ (CHIP_NUM(bp) == CHIP_NUM_57840_2_20) || \
+ (CHIP_NUM(bp) == CHIP_NUM_57840_OBSOLETE))
+#define CHIP_IS_57840_MF(bp) ((CHIP_NUM(bp) == CHIP_NUM_57840_MF) || \
+ (CHIP_NUM(bp) == CHIP_NUM_57840_MF_OBSOLETE))
+#define CHIP_IS_57840_VF(bp) (CHIP_NUM(bp) == CHIP_NUM_57840_VF)
+#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \
+ CHIP_IS_57711E(bp))
+#define CHIP_IS_57811xx(bp) (CHIP_IS_57811(bp) || \
+ CHIP_IS_57811_MF(bp) || \
+ CHIP_IS_57811_VF(bp))
+#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \
+ CHIP_IS_57712_MF(bp) || \
+ CHIP_IS_57712_VF(bp))
+#define CHIP_IS_E3(bp) (CHIP_IS_57800(bp) || \
+ CHIP_IS_57800_MF(bp) || \
+ CHIP_IS_57800_VF(bp) || \
+ CHIP_IS_57810(bp) || \
+ CHIP_IS_57810_MF(bp) || \
+ CHIP_IS_57810_VF(bp) || \
+ CHIP_IS_57811xx(bp) || \
+ CHIP_IS_57840(bp) || \
+ CHIP_IS_57840_MF(bp) || \
+ CHIP_IS_57840_VF(bp))
+#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp)))
+#define USES_WARPCORE(bp) (CHIP_IS_E3(bp))
+#define IS_E1H_OFFSET (!CHIP_IS_E1(bp))
+
+#define CHIP_REV_SHIFT 12
+#define CHIP_REV_MASK (0xF << CHIP_REV_SHIFT)
+#define CHIP_REV_VAL(bp) (bp->common.chip_id & CHIP_REV_MASK)
+#define CHIP_REV_Ax (0x0 << CHIP_REV_SHIFT)
+#define CHIP_REV_Bx (0x1 << CHIP_REV_SHIFT)
+/* assume maximum 5 revisions */
+#define CHIP_REV_IS_SLOW(bp) (CHIP_REV_VAL(bp) > 0x00005000)
+/* Emul versions are A=>0xe, B=>0xc, C=>0xa, D=>8, E=>6 */
+#define CHIP_REV_IS_EMUL(bp) ((CHIP_REV_IS_SLOW(bp)) && \
+ !(CHIP_REV_VAL(bp) & 0x00001000))
+/* FPGA versions are A=>0xf, B=>0xd, C=>0xb, D=>9, E=>7 */
+#define CHIP_REV_IS_FPGA(bp) ((CHIP_REV_IS_SLOW(bp)) && \
+ (CHIP_REV_VAL(bp) & 0x00001000))
+
+#define CHIP_TIME(bp) ((CHIP_REV_IS_EMUL(bp)) ? 2000 : \
+ ((CHIP_REV_IS_FPGA(bp)) ? 200 : 1))
+
+#define CHIP_METAL(bp) (bp->common.chip_id & 0x00000ff0)
+#define CHIP_BOND_ID(bp) (bp->common.chip_id & 0x0000000f)
+#define CHIP_REV_SIM(bp) (((CHIP_REV_MASK - CHIP_REV_VAL(bp)) >>\
+ (CHIP_REV_SHIFT + 1)) \
+ << CHIP_REV_SHIFT)
+#define CHIP_REV(bp) (CHIP_REV_IS_SLOW(bp) ? \
+ CHIP_REV_SIM(bp) :\
+ CHIP_REV_VAL(bp))
+#define CHIP_IS_E3B0(bp) (CHIP_IS_E3(bp) && \
+ (CHIP_REV(bp) == CHIP_REV_Bx))
+#define CHIP_IS_E3A0(bp) (CHIP_IS_E3(bp) && \
+ (CHIP_REV(bp) == CHIP_REV_Ax))
+/* This define is used in two main places:
+ * 1. In the early stages of nic_load, to know if to configure Parser / Searcher
+ * to nic-only mode or to offload mode. Offload mode is configured if either the
+ * chip is E1x (where MIC_MODE register is not applicable), or if cnic already
+ * registered for this port (which means that the user wants storage services).
+ * 2. During cnic-related load, to know if offload mode is already configured in
+ * the HW or needs to be configured.
+ * Since the transition from nic-mode to offload-mode in HW causes traffic
+ * corruption, nic-mode is configured only in ports on which storage services
+ * where never requested.
+ */
+#define CONFIGURE_NIC_MODE(bp) (!CHIP_IS_E1x(bp) && !CNIC_ENABLED(bp))
+
+ int flash_size;
+#define BNX2X_NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */
+#define BNX2X_NVRAM_TIMEOUT_COUNT 30000
+#define BNX2X_NVRAM_PAGE_SIZE 256
+
+ u32 shmem_base;
+ u32 shmem2_base;
+ u32 mf_cfg_base;
+ u32 mf2_cfg_base;
+
+ u32 hw_config;
+
+ u32 bc_ver;
+
+ u8 int_block;
+#define INT_BLOCK_HC 0
+#define INT_BLOCK_IGU 1
+#define INT_BLOCK_MODE_NORMAL 0
+#define INT_BLOCK_MODE_BW_COMP 2
+#define CHIP_INT_MODE_IS_NBC(bp) \
+ (!CHIP_IS_E1x(bp) && \
+ !((bp)->common.int_block & INT_BLOCK_MODE_BW_COMP))
+#define CHIP_INT_MODE_IS_BC(bp) (!CHIP_INT_MODE_IS_NBC(bp))
+
+ u8 chip_port_mode;
+#define CHIP_4_PORT_MODE 0x0
+#define CHIP_2_PORT_MODE 0x1
+#define CHIP_PORT_MODE_NONE 0x2
+#define CHIP_MODE(bp) (bp->common.chip_port_mode)
+#define CHIP_MODE_IS_4_PORT(bp) (CHIP_MODE(bp) == CHIP_4_PORT_MODE)
+
+ u32 boot_mode;
+};
+
+/* IGU MSIX STATISTICS on 57712: 64 for VFs; 4 for PFs; 4 for Attentions */
+#define BNX2X_IGU_STAS_MSG_VF_CNT 64
+#define BNX2X_IGU_STAS_MSG_PF_CNT 4
+
+#define MAX_IGU_ATTN_ACK_TO 100
+/* end of common */
+
+/* port */
+
+struct bnx2x_port {
+ u32 pmf;
+
+ u32 link_config[LINK_CONFIG_SIZE];
+
+ u32 supported[LINK_CONFIG_SIZE];
+/* link settings - missing defines */
+#define SUPPORTED_2500baseX_Full (1 << 15)
+
+ u32 advertising[LINK_CONFIG_SIZE];
+/* link settings - missing defines */
+#define ADVERTISED_2500baseX_Full (1 << 15)
+
+ u32 phy_addr;
+
+ /* used to synchronize phy accesses */
+ struct mutex phy_mutex;
+
+ u32 port_stx;
+
+ struct nig_stats old_nig_stats;
+};
+
+/* end of port */
+
+#define STATS_OFFSET32(stat_name) \
+ (offsetof(struct bnx2x_eth_stats, stat_name) / 4)
+
+/* slow path */
+#define BNX2X_MAX_NUM_OF_VFS 64
+#define BNX2X_VF_CID_WND 4 /* log num of queues per VF. HW config. */
+#define BNX2X_CIDS_PER_VF (1 << BNX2X_VF_CID_WND)
+
+/* We need to reserve doorbell addresses for all VF and queue combinations */
+#define BNX2X_VF_CIDS (BNX2X_MAX_NUM_OF_VFS * BNX2X_CIDS_PER_VF)
+
+/* The doorbell is configured to have the same number of CIDs for PFs and for
+ * VFs. For this reason the PF CID zone is as large as the VF zone.
+ */
+#define BNX2X_FIRST_VF_CID BNX2X_VF_CIDS
+#define BNX2X_MAX_NUM_VF_QUEUES 64
+#define BNX2X_VF_ID_INVALID 0xFF
+
+/* the number of VF CIDS multiplied by the amount of bytes reserved for each
+ * cid must not exceed the size of the VF doorbell
+ */
+#define BNX2X_VF_BAR_SIZE 512
+#if (BNX2X_VF_BAR_SIZE < BNX2X_CIDS_PER_VF * (1 << BNX2X_DB_SHIFT))
+#error "VF doorbell bar size is 512"
+#endif
+
+/*
+ * The total number of L2 queues, MSIX vectors and HW contexts (CIDs) is
+ * control by the number of fast-path status blocks supported by the
+ * device (HW/FW). Each fast-path status block (FP-SB) aka non-default
+ * status block represents an independent interrupts context that can
+ * serve a regular L2 networking queue. However special L2 queues such
+ * as the FCoE queue do not require a FP-SB and other components like
+ * the CNIC may consume FP-SB reducing the number of possible L2 queues
+ *
+ * If the maximum number of FP-SB available is X then:
+ * a. If CNIC is supported it consumes 1 FP-SB thus the max number of
+ * regular L2 queues is Y=X-1
+ * b. In MF mode the actual number of L2 queues is Y= (X-1/MF_factor)
+ * c. If the FCoE L2 queue is supported the actual number of L2 queues
+ * is Y+1
+ * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for
+ * slow-path interrupts) or Y+2 if CNIC is supported (one additional
+ * FP interrupt context for the CNIC).
+ * e. The number of HW context (CID count) is always X or X+1 if FCoE
+ * L2 queue is supported. The cid for the FCoE L2 queue is always X.
+ */
+
+/* fast-path interrupt contexts E1x */
+#define FP_SB_MAX_E1x 16
+/* fast-path interrupt contexts E2 */
+#define FP_SB_MAX_E2 HC_SB_MAX_SB_E2
+
+union cdu_context {
+ struct eth_context eth;
+ char pad[1024];
+};
+
+/* CDU host DB constants */
+#define CDU_ILT_PAGE_SZ_HW 2
+#define CDU_ILT_PAGE_SZ (8192 << CDU_ILT_PAGE_SZ_HW) /* 32K */
+#define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context))
+
+#define CNIC_ISCSI_CID_MAX 256
+#define CNIC_FCOE_CID_MAX 2048
+#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX + CNIC_FCOE_CID_MAX)
+#define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS)
+
+#define QM_ILT_PAGE_SZ_HW 0
+#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 4K */
+#define QM_CID_ROUND 1024
+
+/* TM (timers) host DB constants */
+#define TM_ILT_PAGE_SZ_HW 0
+#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 4K */
+#define TM_CONN_NUM (BNX2X_FIRST_VF_CID + \
+ BNX2X_VF_CIDS + \
+ CNIC_ISCSI_CID_MAX)
+#define TM_ILT_SZ (8 * TM_CONN_NUM)
+#define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ)
+
+/* SRC (Searcher) host DB constants */
+#define SRC_ILT_PAGE_SZ_HW 0
+#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 4K */
+#define SRC_HASH_BITS 10
+#define SRC_CONN_NUM (1 << SRC_HASH_BITS) /* 1024 */
+#define SRC_ILT_SZ (sizeof(struct src_ent) * SRC_CONN_NUM)
+#define SRC_T2_SZ SRC_ILT_SZ
+#define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ)
+
+#define MAX_DMAE_C 8
+
+/* DMA memory not used in fastpath */
+struct bnx2x_slowpath {
+ union {
+ struct mac_configuration_cmd e1x;
+ struct eth_classify_rules_ramrod_data e2;
+ } mac_rdata;
+
+ union {
+ struct tstorm_eth_mac_filter_config e1x;
+ struct eth_filter_rules_ramrod_data e2;
+ } rx_mode_rdata;
+
+ union {
+ struct mac_configuration_cmd e1;
+ struct eth_multicast_rules_ramrod_data e2;
+ } mcast_rdata;
+
+ struct eth_rss_update_ramrod_data rss_rdata;
+
+ /* Queue State related ramrods are always sent under rtnl_lock */
+ union {
+ struct client_init_ramrod_data init_data;
+ struct client_update_ramrod_data update_data;
+ struct tpa_update_ramrod_data tpa_data;
+ } q_rdata;
+
+ union {
+ struct function_start_data func_start;
+ /* pfc configuration for DCBX ramrod */
+ struct flow_control_configuration pfc_config;
+ } func_rdata;
+
+ /* afex ramrod can not be a part of func_rdata union because these
+ * events might arrive in parallel to other events from func_rdata.
+ * Therefore, if they would have been defined in the same union,
+ * data can get corrupted.
+ */
+ union {
+ struct afex_vif_list_ramrod_data viflist_data;
+ struct function_update_data func_update;
+ } func_afex_rdata;
+
+ /* used by dmae command executer */
+ struct dmae_command dmae[MAX_DMAE_C];
+
+ u32 stats_comp;
+ union mac_stats mac_stats;
+ struct nig_stats nig_stats;
+ struct host_port_stats port_stats;
+ struct host_func_stats func_stats;
+
+ u32 wb_comp;
+ u32 wb_data[4];
+
+ union drv_info_to_mcp drv_info_to_mcp;
+};
+
+#define bnx2x_sp(bp, var) (&bp->slowpath->var)
+#define bnx2x_sp_mapping(bp, var) \
+ (bp->slowpath_mapping + offsetof(struct bnx2x_slowpath, var))
+
+/* attn group wiring */
+#define MAX_DYNAMIC_ATTN_GRPS 8
+
+struct attn_route {
+ u32 sig[5];
+};
+
+struct iro {
+ u32 base;
+ u16 m1;
+ u16 m2;
+ u16 m3;
+ u16 size;
+};
+
+struct hw_context {
+ union cdu_context *vcxt;
+ dma_addr_t cxt_mapping;
+ size_t size;
+};
+
+/* forward */
+struct bnx2x_ilt;
+
+struct bnx2x_vfdb;
+
+enum bnx2x_recovery_state {
+ BNX2X_RECOVERY_DONE,
+ BNX2X_RECOVERY_INIT,
+ BNX2X_RECOVERY_WAIT,
+ BNX2X_RECOVERY_FAILED,
+ BNX2X_RECOVERY_NIC_LOADING
+};
+
+/*
+ * Event queue (EQ or event ring) MC hsi
+ * NUM_EQ_PAGES and EQ_DESC_CNT_PAGE must be power of 2
+ */
+#define NUM_EQ_PAGES 1
+#define EQ_DESC_CNT_PAGE (BCM_PAGE_SIZE / sizeof(union event_ring_elem))
+#define EQ_DESC_MAX_PAGE (EQ_DESC_CNT_PAGE - 1)
+#define NUM_EQ_DESC (EQ_DESC_CNT_PAGE * NUM_EQ_PAGES)
+#define EQ_DESC_MASK (NUM_EQ_DESC - 1)
+#define MAX_EQ_AVAIL (EQ_DESC_MAX_PAGE * NUM_EQ_PAGES - 2)
+
+/* depends on EQ_DESC_CNT_PAGE being a power of 2 */
+#define NEXT_EQ_IDX(x) ((((x) & EQ_DESC_MAX_PAGE) == \
+ (EQ_DESC_MAX_PAGE - 1)) ? (x) + 2 : (x) + 1)
+
+/* depends on the above and on NUM_EQ_PAGES being a power of 2 */
+#define EQ_DESC(x) ((x) & EQ_DESC_MASK)
+
+#define BNX2X_EQ_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_EQ_CONS])
+
+/* This is a data that will be used to create a link report message.
+ * We will keep the data used for the last link report in order
+ * to prevent reporting the same link parameters twice.
+ */
+struct bnx2x_link_report_data {
+ u16 line_speed; /* Effective line speed */
+ unsigned long link_report_flags;/* BNX2X_LINK_REPORT_XXX flags */
+};
+
+enum {
+ BNX2X_LINK_REPORT_FD, /* Full DUPLEX */
+ BNX2X_LINK_REPORT_LINK_DOWN,
+ BNX2X_LINK_REPORT_RX_FC_ON,
+ BNX2X_LINK_REPORT_TX_FC_ON,
+};
+
+enum {
+ BNX2X_PORT_QUERY_IDX,
+ BNX2X_PF_QUERY_IDX,
+ BNX2X_FCOE_QUERY_IDX,
+ BNX2X_FIRST_QUEUE_QUERY_IDX,
+};
+
+struct bnx2x_fw_stats_req {
+ struct stats_query_header hdr;
+ struct stats_query_entry query[FP_SB_MAX_E1x+
+ BNX2X_FIRST_QUEUE_QUERY_IDX];
+};
+
+struct bnx2x_fw_stats_data {
+ struct stats_counter storm_counters;
+ struct per_port_stats port;
+ struct per_pf_stats pf;
+ struct fcoe_statistics_params fcoe;
+ struct per_queue_stats queue_stats[1];
+};
+
+/* Public slow path states */
+enum sp_rtnl_flag {
+ BNX2X_SP_RTNL_SETUP_TC,
+ BNX2X_SP_RTNL_TX_TIMEOUT,
+ BNX2X_SP_RTNL_FAN_FAILURE,
+ BNX2X_SP_RTNL_AFEX_F_UPDATE,
+ BNX2X_SP_RTNL_ENABLE_SRIOV,
+ BNX2X_SP_RTNL_VFPF_MCAST,
+ BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
+ BNX2X_SP_RTNL_RX_MODE,
+ BNX2X_SP_RTNL_HYPERVISOR_VLAN,
+ BNX2X_SP_RTNL_TX_STOP,
+ BNX2X_SP_RTNL_GET_DRV_VERSION,
+};
+
+enum bnx2x_iov_flag {
+ BNX2X_IOV_HANDLE_VF_MSG,
+ BNX2X_IOV_HANDLE_FLR,
+};
+
+struct bnx2x_prev_path_list {
+ struct list_head list;
+ u8 bus;
+ u8 slot;
+ u8 path;
+ u8 aer;
+ u8 undi;
+};
+
+struct bnx2x_sp_objs {
+ /* MACs object */
+ struct bnx2x_vlan_mac_obj mac_obj;
+
+ /* Queue State object */
+ struct bnx2x_queue_sp_obj q_obj;
+};
+
+struct bnx2x_fp_stats {
+ struct tstorm_per_queue_stats old_tclient;
+ struct ustorm_per_queue_stats old_uclient;
+ struct xstorm_per_queue_stats old_xclient;
+ struct bnx2x_eth_q_stats eth_q_stats;
+ struct bnx2x_eth_q_stats_old eth_q_stats_old;
+};
+
+struct bnx2x {
+ /* Fields used in the tx and intr/napi performance paths
+ * are grouped together in the beginning of the structure
+ */
+ struct bnx2x_fastpath *fp;
+ struct bnx2x_sp_objs *sp_objs;
+ struct bnx2x_fp_stats *fp_stats;
+ struct bnx2x_fp_txdata *bnx2x_txq;
+ void __iomem *regview;
+ void __iomem *doorbells;
+ u16 db_size;
+
+ u8 pf_num; /* absolute PF number */
+ u8 pfid; /* per-path PF number */
+ int base_fw_ndsb; /**/
+#define BP_PATH(bp) (CHIP_IS_E1x(bp) ? 0 : (bp->pf_num & 1))
+#define BP_PORT(bp) (bp->pfid & 1)
+#define BP_FUNC(bp) (bp->pfid)
+#define BP_ABS_FUNC(bp) (bp->pf_num)
+#define BP_VN(bp) ((bp)->pfid >> 1)
+#define BP_MAX_VN_NUM(bp) (CHIP_MODE_IS_4_PORT(bp) ? 2 : 4)
+#define BP_L_ID(bp) (BP_VN(bp) << 2)
+#define BP_FW_MB_IDX_VN(bp, vn) (BP_PORT(bp) +\
+ (vn) * ((CHIP_IS_E1x(bp) || (CHIP_MODE_IS_4_PORT(bp))) ? 2 : 1))
+#define BP_FW_MB_IDX(bp) BP_FW_MB_IDX_VN(bp, BP_VN(bp))
+
+#ifdef CONFIG_BNX2X_SRIOV
+ /* protects vf2pf mailbox from simultaneous access */
+ struct mutex vf2pf_mutex;
+ /* vf pf channel mailbox contains request and response buffers */
+ struct bnx2x_vf_mbx_msg *vf2pf_mbox;
+ dma_addr_t vf2pf_mbox_mapping;
+
+ /* we set aside a copy of the acquire response */
+ struct pfvf_acquire_resp_tlv acquire_resp;
+
+ /* bulletin board for messages from pf to vf */
+ union pf_vf_bulletin *pf2vf_bulletin;
+ dma_addr_t pf2vf_bulletin_mapping;
+
+ struct pf_vf_bulletin_content old_bulletin;
+
+ u16 requested_nr_virtfn;
+#endif /* CONFIG_BNX2X_SRIOV */
+
+ struct net_device *dev;
+ struct pci_dev *pdev;
+
+ const struct iro *iro_arr;
+#define IRO (bp->iro_arr)
+
+ enum bnx2x_recovery_state recovery_state;
+ int is_leader;
+ struct msix_entry *msix_table;
+
+ int tx_ring_size;
+
+/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
+#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
+#define ETH_MIN_PACKET_SIZE 60
+#define ETH_MAX_PACKET_SIZE 1500
+#define ETH_MAX_JUMBO_PACKET_SIZE 9600
+/* TCP with Timestamp Option (32) + IPv6 (40) */
+#define ETH_MAX_TPA_HEADER_SIZE 72
+
+ /* Max supported alignment is 256 (8 shift) */
+#define BNX2X_RX_ALIGN_SHIFT min(8, L1_CACHE_SHIFT)
+
+ /* FW uses 2 Cache lines Alignment for start packet and size
+ *
+ * We assume skb_build() uses sizeof(struct skb_shared_info) bytes
+ * at the end of skb->data, to avoid wasting a full cache line.
+ * This reduces memory use (skb->truesize).
+ */
+#define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT)
+
+#define BNX2X_FW_RX_ALIGN_END \
+ max_t(u64, 1UL << BNX2X_RX_ALIGN_SHIFT, \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+
+#define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5)
+
+ struct host_sp_status_block *def_status_blk;
+#define DEF_SB_IGU_ID 16
+#define DEF_SB_ID HC_SP_SB_ID
+ __le16 def_idx;
+ __le16 def_att_idx;
+ u32 attn_state;
+ struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
+
+ /* slow path ring */
+ struct eth_spe *spq;
+ dma_addr_t spq_mapping;
+ u16 spq_prod_idx;
+ struct eth_spe *spq_prod_bd;
+ struct eth_spe *spq_last_bd;
+ __le16 *dsb_sp_prod;
+ atomic_t cq_spq_left; /* ETH_XXX ramrods credit */
+ /* used to synchronize spq accesses */
+ spinlock_t spq_lock;
+
+ /* event queue */
+ union event_ring_elem *eq_ring;
+ dma_addr_t eq_mapping;
+ u16 eq_prod;
+ u16 eq_cons;
+ __le16 *eq_cons_sb;
+ atomic_t eq_spq_left; /* COMMON_XXX ramrods credit */
+
+ /* Counter for marking that there is a STAT_QUERY ramrod pending */
+ u16 stats_pending;
+ /* Counter for completed statistics ramrods */
+ u16 stats_comp;
+
+ /* End of fields used in the performance code paths */
+
+ int panic;
+ int msg_enable;
+
+ u32 flags;
+#define PCIX_FLAG (1 << 0)
+#define PCI_32BIT_FLAG (1 << 1)
+#define ONE_PORT_FLAG (1 << 2)
+#define NO_WOL_FLAG (1 << 3)
+#define USING_MSIX_FLAG (1 << 5)
+#define USING_MSI_FLAG (1 << 6)
+#define DISABLE_MSI_FLAG (1 << 7)
+#define TPA_ENABLE_FLAG (1 << 8)
+#define NO_MCP_FLAG (1 << 9)
+#define GRO_ENABLE_FLAG (1 << 10)
+#define MF_FUNC_DIS (1 << 11)
+#define OWN_CNIC_IRQ (1 << 12)
+#define NO_ISCSI_OOO_FLAG (1 << 13)
+#define NO_ISCSI_FLAG (1 << 14)
+#define NO_FCOE_FLAG (1 << 15)
+#define BC_SUPPORTS_PFC_STATS (1 << 17)
+#define TX_SWITCHING (1 << 18)
+#define BC_SUPPORTS_FCOE_FEATURES (1 << 19)
+#define USING_SINGLE_MSIX_FLAG (1 << 20)
+#define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21)
+#define IS_VF_FLAG (1 << 22)
+#define INTERRUPTS_ENABLED_FLAG (1 << 23)
+#define BC_SUPPORTS_RMMOD_CMD (1 << 24)
+#define HAS_PHYS_PORT_ID (1 << 25)
+#define AER_ENABLED (1 << 26)
+
+#define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG)
+
+#ifdef CONFIG_BNX2X_SRIOV
+#define IS_VF(bp) ((bp)->flags & IS_VF_FLAG)
+#define IS_PF(bp) (!((bp)->flags & IS_VF_FLAG))
+#else
+#define IS_VF(bp) false
+#define IS_PF(bp) true
+#endif
+
+#define NO_ISCSI(bp) ((bp)->flags & NO_ISCSI_FLAG)
+#define NO_ISCSI_OOO(bp) ((bp)->flags & NO_ISCSI_OOO_FLAG)
+#define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG)
+
+ u8 cnic_support;
+ bool cnic_enabled;
+ bool cnic_loaded;
+ struct cnic_eth_dev *(*cnic_probe)(struct net_device *);
+
+ /* Flag that indicates that we can start looking for FCoE L2 queue
+ * completions in the default status block.
+ */
+ bool fcoe_init;
+
+ int mrrs;
+
+ struct delayed_work sp_task;
+ struct delayed_work iov_task;
+
+ atomic_t interrupt_occurred;
+ struct delayed_work sp_rtnl_task;
+
+ struct delayed_work period_task;
+ struct timer_list timer;
+ int current_interval;
+
+ u16 fw_seq;
+ u16 fw_drv_pulse_wr_seq;
+ u32 func_stx;
+
+ struct link_params link_params;
+ struct link_vars link_vars;
+ u32 link_cnt;
+ struct bnx2x_link_report_data last_reported_link;
+
+ struct mdio_if_info mdio;
+
+ struct bnx2x_common common;
+ struct bnx2x_port port;
+
+ struct cmng_init cmng;
+
+ u32 mf_config[E1HVN_MAX];
+ u32 mf_ext_config;
+ u32 path_has_ovlan; /* E3 */
+ u16 mf_ov;
+ u8 mf_mode;
+#define IS_MF(bp) (bp->mf_mode != 0)
+#define IS_MF_SI(bp) (bp->mf_mode == MULTI_FUNCTION_SI)
+#define IS_MF_SD(bp) (bp->mf_mode == MULTI_FUNCTION_SD)
+#define IS_MF_AFEX(bp) (bp->mf_mode == MULTI_FUNCTION_AFEX)
+
+ u8 wol;
+
+ int rx_ring_size;
+
+ u16 tx_quick_cons_trip_int;
+ u16 tx_quick_cons_trip;
+ u16 tx_ticks_int;
+ u16 tx_ticks;
+
+ u16 rx_quick_cons_trip_int;
+ u16 rx_quick_cons_trip;
+ u16 rx_ticks_int;
+ u16 rx_ticks;
+/* Maximal coalescing timeout in us */
+#define BNX2X_MAX_COALESCE_TOUT (0xff*BNX2X_BTR)
+
+ u32 lin_cnt;
+
+ u16 state;
+#define BNX2X_STATE_CLOSED 0
+#define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000
+#define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000
+#define BNX2X_STATE_OPEN 0x3000
+#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000
+#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
+
+#define BNX2X_STATE_DIAG 0xe000
+#define BNX2X_STATE_ERROR 0xf000
+
+#define BNX2X_MAX_PRIORITY 8
+#define BNX2X_MAX_ENTRIES_PER_PRI 16
+#define BNX2X_MAX_COS 3
+#define BNX2X_MAX_TX_COS 2
+ int num_queues;
+ uint num_ethernet_queues;
+ uint num_cnic_queues;
+ int num_napi_queues;
+ int disable_tpa;
+
+ u32 rx_mode;
+#define BNX2X_RX_MODE_NONE 0
+#define BNX2X_RX_MODE_NORMAL 1
+#define BNX2X_RX_MODE_ALLMULTI 2
+#define BNX2X_RX_MODE_PROMISC 3
+#define BNX2X_MAX_MULTICAST 64
+
+ u8 igu_dsb_id;
+ u8 igu_base_sb;
+ u8 igu_sb_cnt;
+ u8 min_msix_vec_cnt;
+
+ u32 igu_base_addr;
+ dma_addr_t def_status_blk_mapping;
+
+ struct bnx2x_slowpath *slowpath;
+ dma_addr_t slowpath_mapping;
+
+ /* Mechanism protecting the drv_info_to_mcp */
+ struct mutex drv_info_mutex;
+ bool drv_info_mng_owner;
+
+ /* Total number of FW statistics requests */
+ u8 fw_stats_num;
+
+ /*
+ * This is a memory buffer that will contain both statistics
+ * ramrod request and data.
+ */
+ void *fw_stats;
+ dma_addr_t fw_stats_mapping;
+
+ /*
+ * FW statistics request shortcut (points at the
+ * beginning of fw_stats buffer).
+ */
+ struct bnx2x_fw_stats_req *fw_stats_req;
+ dma_addr_t fw_stats_req_mapping;
+ int fw_stats_req_sz;
+
+ /*
+ * FW statistics data shortcut (points at the beginning of
+ * fw_stats buffer + fw_stats_req_sz).
+ */
+ struct bnx2x_fw_stats_data *fw_stats_data;
+ dma_addr_t fw_stats_data_mapping;
+ int fw_stats_data_sz;
+
+ /* For max 1024 cids (VF RSS), 32KB ILT page size and 1KB
+ * context size we need 8 ILT entries.
+ */
+#define ILT_MAX_L2_LINES 32
+ struct hw_context context[ILT_MAX_L2_LINES];
+
+ struct bnx2x_ilt *ilt;
+#define BP_ILT(bp) ((bp)->ilt)
+#define ILT_MAX_LINES 256
+/*
+ * Maximum supported number of RSS queues: number of IGU SBs minus one that goes
+ * to CNIC.
+ */
+#define BNX2X_MAX_RSS_COUNT(bp) ((bp)->igu_sb_cnt - CNIC_SUPPORT(bp))
+
+/*
+ * Maximum CID count that might be required by the bnx2x:
+ * Max RSS * Max_Tx_Multi_Cos + FCoE + iSCSI
+ */
+
+#define BNX2X_L2_CID_COUNT(bp) (BNX2X_NUM_ETH_QUEUES(bp) * BNX2X_MULTI_TX_COS \
+ + CNIC_SUPPORT(bp) * (2 + UIO_CID_PAD(bp)))
+#define BNX2X_L2_MAX_CID(bp) (BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS \
+ + CNIC_SUPPORT(bp) * (2 + UIO_CID_PAD(bp)))
+#define L2_ILT_LINES(bp) (DIV_ROUND_UP(BNX2X_L2_CID_COUNT(bp),\
+ ILT_PAGE_CIDS))
+
+ int qm_cid_count;
+
+ bool dropless_fc;
+
+ void *t2;
+ dma_addr_t t2_mapping;
+ struct cnic_ops __rcu *cnic_ops;
+ void *cnic_data;
+ u32 cnic_tag;
+ struct cnic_eth_dev cnic_eth_dev;
+ union host_hc_status_block cnic_sb;
+ dma_addr_t cnic_sb_mapping;
+ struct eth_spe *cnic_kwq;
+ struct eth_spe *cnic_kwq_prod;
+ struct eth_spe *cnic_kwq_cons;
+ struct eth_spe *cnic_kwq_last;
+ u16 cnic_kwq_pending;
+ u16 cnic_spq_pending;
+ u8 fip_mac[ETH_ALEN];
+ struct mutex cnic_mutex;
+ struct bnx2x_vlan_mac_obj iscsi_l2_mac_obj;
+
+ /* Start index of the "special" (CNIC related) L2 clients */
+ u8 cnic_base_cl_id;
+
+ int dmae_ready;
+ /* used to synchronize dmae accesses */
+ spinlock_t dmae_lock;
+
+ /* used to protect the FW mail box */
+ struct mutex fw_mb_mutex;
+
+ /* used to synchronize stats collecting */
+ int stats_state;
+
+ /* used for synchronization of concurrent threads statistics handling */
+ spinlock_t stats_lock;
+
+ /* used by dmae command loader */
+ struct dmae_command stats_dmae;
+ int executer_idx;
+
+ u16 stats_counter;
+ struct bnx2x_eth_stats eth_stats;
+ struct host_func_stats func_stats;
+ struct bnx2x_eth_stats_old eth_stats_old;
+ struct bnx2x_net_stats_old net_stats_old;
+ struct bnx2x_fw_port_stats_old fw_stats_old;
+ bool stats_init;
+
+ struct z_stream_s *strm;
+ void *gunzip_buf;
+ dma_addr_t gunzip_mapping;
+ int gunzip_outlen;
+#define FW_BUF_SIZE 0x8000
+#define GUNZIP_BUF(bp) (bp->gunzip_buf)
+#define GUNZIP_PHYS(bp) (bp->gunzip_mapping)
+#define GUNZIP_OUTLEN(bp) (bp->gunzip_outlen)
+
+ struct raw_op *init_ops;
+ /* Init blocks offsets inside init_ops */
+ u16 *init_ops_offsets;
+ /* Data blob - has 32 bit granularity */
+ u32 *init_data;
+ u32 init_mode_flags;
+#define INIT_MODE_FLAGS(bp) (bp->init_mode_flags)
+ /* Zipped PRAM blobs - raw data */
+ const u8 *tsem_int_table_data;
+ const u8 *tsem_pram_data;
+ const u8 *usem_int_table_data;
+ const u8 *usem_pram_data;
+ const u8 *xsem_int_table_data;
+ const u8 *xsem_pram_data;
+ const u8 *csem_int_table_data;
+ const u8 *csem_pram_data;
+#define INIT_OPS(bp) (bp->init_ops)
+#define INIT_OPS_OFFSETS(bp) (bp->init_ops_offsets)
+#define INIT_DATA(bp) (bp->init_data)
+#define INIT_TSEM_INT_TABLE_DATA(bp) (bp->tsem_int_table_data)
+#define INIT_TSEM_PRAM_DATA(bp) (bp->tsem_pram_data)
+#define INIT_USEM_INT_TABLE_DATA(bp) (bp->usem_int_table_data)
+#define INIT_USEM_PRAM_DATA(bp) (bp->usem_pram_data)
+#define INIT_XSEM_INT_TABLE_DATA(bp) (bp->xsem_int_table_data)
+#define INIT_XSEM_PRAM_DATA(bp) (bp->xsem_pram_data)
+#define INIT_CSEM_INT_TABLE_DATA(bp) (bp->csem_int_table_data)
+#define INIT_CSEM_PRAM_DATA(bp) (bp->csem_pram_data)
+
+#define PHY_FW_VER_LEN 20
+ char fw_ver[32];
+ const struct firmware *firmware;
+
+ struct bnx2x_vfdb *vfdb;
+#define IS_SRIOV(bp) ((bp)->vfdb)
+
+ /* DCB support on/off */
+ u16 dcb_state;
+#define BNX2X_DCB_STATE_OFF 0
+#define BNX2X_DCB_STATE_ON 1
+
+ /* DCBX engine mode */
+ int dcbx_enabled;
+#define BNX2X_DCBX_ENABLED_OFF 0
+#define BNX2X_DCBX_ENABLED_ON_NEG_OFF 1
+#define BNX2X_DCBX_ENABLED_ON_NEG_ON 2
+#define BNX2X_DCBX_ENABLED_INVALID (-1)
+
+ bool dcbx_mode_uset;
+
+ struct bnx2x_config_dcbx_params dcbx_config_params;
+ struct bnx2x_dcbx_port_params dcbx_port_params;
+ int dcb_version;
+
+ /* CAM credit pools */
+
+ /* used only in sriov */
+ struct bnx2x_credit_pool_obj vlans_pool;
+
+ struct bnx2x_credit_pool_obj macs_pool;
+
+ /* RX_MODE object */
+ struct bnx2x_rx_mode_obj rx_mode_obj;
+
+ /* MCAST object */
+ struct bnx2x_mcast_obj mcast_obj;
+
+ /* RSS configuration object */
+ struct bnx2x_rss_config_obj rss_conf_obj;
+
+ /* Function State controlling object */
+ struct bnx2x_func_sp_obj func_obj;
+
+ unsigned long sp_state;
+
+ /* operation indication for the sp_rtnl task */
+ unsigned long sp_rtnl_state;
+
+ /* Indication of the IOV tasks */
+ unsigned long iov_task_state;
+
+ /* DCBX Negotiation results */
+ struct dcbx_features dcbx_local_feat;
+ u32 dcbx_error;
+
+#ifdef BCM_DCBNL
+ struct dcbx_features dcbx_remote_feat;
+ u32 dcbx_remote_flags;
+#endif
+ /* AFEX: store default vlan used */
+ int afex_def_vlan_tag;
+ enum mf_cfg_afex_vlan_mode afex_vlan_mode;
+ u32 pending_max;
+
+ /* multiple tx classes of service */
+ u8 max_cos;
+
+ /* priority to cos mapping */
+ u8 prio_to_cos[8];
+
+ int fp_array_size;
+ u32 dump_preset_idx;
+ bool stats_started;
+ struct semaphore stats_sema;
+
+ u8 phys_port_id[ETH_ALEN];
+};
+
+/* Tx queues may be less or equal to Rx queues */
+extern int num_queues;
+#define BNX2X_NUM_QUEUES(bp) (bp->num_queues)
+#define BNX2X_NUM_ETH_QUEUES(bp) ((bp)->num_ethernet_queues)
+#define BNX2X_NUM_NON_CNIC_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - \
+ (bp)->num_cnic_queues)
+#define BNX2X_NUM_RX_QUEUES(bp) BNX2X_NUM_QUEUES(bp)
+
+#define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1)
+
+#define BNX2X_MAX_QUEUES(bp) BNX2X_MAX_RSS_COUNT(bp)
+/* #define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1) */
+
+#define RSS_IPV4_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY
+
+#define RSS_IPV4_TCP_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY
+
+#define RSS_IPV6_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY
+
+#define RSS_IPV6_TCP_CAP_MASK \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY
+
+/* func init flags */
+#define FUNC_FLG_RSS 0x0001
+#define FUNC_FLG_STATS 0x0002
+/* removed FUNC_FLG_UNMATCHED 0x0004 */
+#define FUNC_FLG_TPA 0x0008
+#define FUNC_FLG_SPQ 0x0010
+#define FUNC_FLG_LEADING 0x0020 /* PF only */
+#define FUNC_FLG_LEADING_STATS 0x0040
+struct bnx2x_func_init_params {
+ /* dma */
+ dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */
+ dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */
+
+ u16 func_flgs;
+ u16 func_id; /* abs fid */
+ u16 pf_id;
+ u16 spq_prod; /* valid iff FUNC_FLG_SPQ */
+};
+
+#define for_each_cnic_queue(bp, var) \
+ for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \
+ (var)++) \
+ if (skip_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_eth_queue(bp, var) \
+ for ((var) = 0; (var) < BNX2X_NUM_ETH_QUEUES(bp); (var)++)
+
+#define for_each_nondefault_eth_queue(bp, var) \
+ for ((var) = 1; (var) < BNX2X_NUM_ETH_QUEUES(bp); (var)++)
+
+#define for_each_queue(bp, var) \
+ for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \
+ if (skip_queue(bp, var)) \
+ continue; \
+ else
+
+/* Skip forwarding FP */
+#define for_each_valid_rx_queue(bp, var) \
+ for ((var) = 0; \
+ (var) < (CNIC_LOADED(bp) ? BNX2X_NUM_QUEUES(bp) : \
+ BNX2X_NUM_ETH_QUEUES(bp)); \
+ (var)++) \
+ if (skip_rx_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_rx_queue_cnic(bp, var) \
+ for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \
+ (var)++) \
+ if (skip_rx_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_rx_queue(bp, var) \
+ for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \
+ if (skip_rx_queue(bp, var)) \
+ continue; \
+ else
+
+/* Skip OOO FP */
+#define for_each_valid_tx_queue(bp, var) \
+ for ((var) = 0; \
+ (var) < (CNIC_LOADED(bp) ? BNX2X_NUM_QUEUES(bp) : \
+ BNX2X_NUM_ETH_QUEUES(bp)); \
+ (var)++) \
+ if (skip_tx_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_tx_queue_cnic(bp, var) \
+ for ((var) = BNX2X_NUM_ETH_QUEUES(bp); (var) < BNX2X_NUM_QUEUES(bp); \
+ (var)++) \
+ if (skip_tx_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_tx_queue(bp, var) \
+ for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \
+ if (skip_tx_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_nondefault_queue(bp, var) \
+ for ((var) = 1; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \
+ if (skip_queue(bp, var)) \
+ continue; \
+ else
+
+#define for_each_cos_in_tx_queue(fp, var) \
+ for ((var) = 0; (var) < (fp)->max_cos; (var)++)
+
+/* skip rx queue
+ * if FCOE l2 support is disabled and this is the fcoe L2 queue
+ */
+#define skip_rx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx))
+
+/* skip tx queue
+ * if FCOE l2 support is disabled and this is the fcoe L2 queue
+ */
+#define skip_tx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx))
+
+#define skip_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx))
+
+/**
+ * bnx2x_set_mac_one - configure a single MAC address
+ *
+ * @bp: driver handle
+ * @mac: MAC to configure
+ * @obj: MAC object handle
+ * @set: if 'true' add a new MAC, otherwise - delete
+ * @mac_type: the type of the MAC to configure (e.g. ETH, UC list)
+ * @ramrod_flags: RAMROD_XXX flags (e.g. RAMROD_CONT, RAMROD_COMP_WAIT)
+ *
+ * Configures one MAC according to provided parameters or continues the
+ * execution of previously scheduled commands if RAMROD_CONT is set in
+ * ramrod_flags.
+ *
+ * Returns zero if operation has successfully completed, a positive value if the
+ * operation has been successfully scheduled and a negative - if a requested
+ * operations has failed.
+ */
+int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac,
+ struct bnx2x_vlan_mac_obj *obj, bool set,
+ int mac_type, unsigned long *ramrod_flags);
+/**
+ * bnx2x_del_all_macs - delete all MACs configured for the specific MAC object
+ *
+ * @bp: driver handle
+ * @mac_obj: MAC object handle
+ * @mac_type: type of the MACs to clear (BNX2X_XXX_MAC)
+ * @wait_for_comp: if 'true' block until completion
+ *
+ * Deletes all MACs of the specific type (e.g. ETH, UC list).
+ *
+ * Returns zero if operation has successfully completed, a positive value if the
+ * operation has been successfully scheduled and a negative - if a requested
+ * operations has failed.
+ */
+int bnx2x_del_all_macs(struct bnx2x *bp,
+ struct bnx2x_vlan_mac_obj *mac_obj,
+ int mac_type, bool wait_for_comp);
+
+/* Init Function API */
+void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p);
+void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid,
+ u8 vf_valid, int fw_sb_id, int igu_sb_id);
+int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
+int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
+int bnx2x_set_mult_gpio(struct bnx2x *bp, u8 pins, u32 mode);
+int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
+void bnx2x_read_mf_cfg(struct bnx2x *bp);
+
+int bnx2x_pretend_func(struct bnx2x *bp, u16 pretend_func_val);
+
+/* dmae */
+void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
+void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
+ u32 len32);
+void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx);
+u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type);
+u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode);
+u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type,
+ bool with_comp, u8 comp_type);
+
+void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
+ u8 src_type, u8 dst_type);
+int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae,
+ u32 *comp);
+
+/* FLR related routines */
+u32 bnx2x_flr_clnup_poll_count(struct bnx2x *bp);
+void bnx2x_tx_hw_flushed(struct bnx2x *bp, u32 poll_count);
+int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, u32 poll_cnt);
+u8 bnx2x_is_pcie_pending(struct pci_dev *dev);
+int bnx2x_flr_clnup_poll_hw_counter(struct bnx2x *bp, u32 reg,
+ char *msg, u32 poll_cnt);
+
+void bnx2x_calc_fc_adv(struct bnx2x *bp);
+int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
+ u32 data_hi, u32 data_lo, int cmd_type);
+void bnx2x_update_coalesce(struct bnx2x *bp);
+int bnx2x_get_cur_phy_idx(struct bnx2x *bp);
+
+bool bnx2x_port_after_undi(struct bnx2x *bp);
+
+static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
+ int wait)
+{
+ u32 val;
+
+ do {
+ val = REG_RD(bp, reg);
+ if (val == expected)
+ break;
+ ms -= wait;
+ msleep(wait);
+
+ } while (ms > 0);
+
+ return val;
+}
+
+void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
+ bool is_pf);
+
+#define BNX2X_ILT_ZALLOC(x, y, size) \
+ x = dma_zalloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL)
+
+#define BNX2X_ILT_FREE(x, y, size) \
+ do { \
+ if (x) { \
+ dma_free_coherent(&bp->pdev->dev, size, x, y); \
+ x = NULL; \
+ y = 0; \
+ } \
+ } while (0)
+
+#define ILOG2(x) (ilog2((x)))
+
+#define ILT_NUM_PAGE_ENTRIES (3072)
+/* In 57710/11 we use whole table since we have 8 func
+ * In 57712 we have only 4 func, but use same size per func, then only half of
+ * the table in use
+ */
+#define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8)
+
+#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC)
+/*
+ * the phys address is shifted right 12 bits and has an added
+ * 1=valid bit added to the 53rd bit
+ * then since this is a wide register(TM)
+ * we split it into two 32 bit writes
+ */
+#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
+#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44)))
+
+/* load/unload mode */
+#define LOAD_NORMAL 0
+#define LOAD_OPEN 1
+#define LOAD_DIAG 2
+#define LOAD_LOOPBACK_EXT 3
+#define UNLOAD_NORMAL 0
+#define UNLOAD_CLOSE 1
+#define UNLOAD_RECOVERY 2
+
+/* DMAE command defines */
+#define DMAE_TIMEOUT -1
+#define DMAE_PCI_ERROR -2 /* E2 and onward */
+#define DMAE_NOT_RDY -3
+#define DMAE_PCI_ERR_FLAG 0x80000000
+
+#define DMAE_SRC_PCI 0
+#define DMAE_SRC_GRC 1
+
+#define DMAE_DST_NONE 0
+#define DMAE_DST_PCI 1
+#define DMAE_DST_GRC 2
+
+#define DMAE_COMP_PCI 0
+#define DMAE_COMP_GRC 1
+
+/* E2 and onward - PCI error handling in the completion */
+
+#define DMAE_COMP_REGULAR 0
+#define DMAE_COM_SET_ERR 1
+
+#define DMAE_CMD_SRC_PCI (DMAE_SRC_PCI << \
+ DMAE_COMMAND_SRC_SHIFT)
+#define DMAE_CMD_SRC_GRC (DMAE_SRC_GRC << \
+ DMAE_COMMAND_SRC_SHIFT)
+
+#define DMAE_CMD_DST_PCI (DMAE_DST_PCI << \
+ DMAE_COMMAND_DST_SHIFT)
+#define DMAE_CMD_DST_GRC (DMAE_DST_GRC << \
+ DMAE_COMMAND_DST_SHIFT)
+
+#define DMAE_CMD_C_DST_PCI (DMAE_COMP_PCI << \
+ DMAE_COMMAND_C_DST_SHIFT)
+#define DMAE_CMD_C_DST_GRC (DMAE_COMP_GRC << \
+ DMAE_COMMAND_C_DST_SHIFT)
+
+#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
+
+#define DMAE_CMD_ENDIANITY_NO_SWAP (0 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_B_SWAP (1 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_DW_SWAP (2 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_B_DW_SWAP (3 << DMAE_COMMAND_ENDIANITY_SHIFT)
+
+#define DMAE_CMD_PORT_0 0
+#define DMAE_CMD_PORT_1 DMAE_COMMAND_PORT
+
+#define DMAE_CMD_SRC_RESET DMAE_COMMAND_SRC_RESET
+#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
+#define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT
+
+#define DMAE_SRC_PF 0
+#define DMAE_SRC_VF 1
+
+#define DMAE_DST_PF 0
+#define DMAE_DST_VF 1
+
+#define DMAE_C_SRC 0
+#define DMAE_C_DST 1
+
+#define DMAE_LEN32_RD_MAX 0x80
+#define DMAE_LEN32_WR_MAX(bp) (CHIP_IS_E1(bp) ? 0x400 : 0x2000)
+
+#define DMAE_COMP_VAL 0x60d0d0ae /* E2 and on - upper bit
+ * indicates error
+ */
+
+#define MAX_DMAE_C_PER_PORT 8
+#define INIT_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
+ BP_VN(bp))
+#define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
+ E1HVN_MAX)
+
+/* PCIE link and speed */
+#define PCICFG_LINK_WIDTH 0x1f00000
+#define PCICFG_LINK_WIDTH_SHIFT 20
+#define PCICFG_LINK_SPEED 0xf0000
+#define PCICFG_LINK_SPEED_SHIFT 16
+
+#define BNX2X_NUM_TESTS_SF 7
+#define BNX2X_NUM_TESTS_MF 3
+#define BNX2X_NUM_TESTS(bp) (IS_MF(bp) ? BNX2X_NUM_TESTS_MF : \
+ IS_VF(bp) ? 0 : BNX2X_NUM_TESTS_SF)
+
+#define BNX2X_PHY_LOOPBACK 0
+#define BNX2X_MAC_LOOPBACK 1
+#define BNX2X_EXT_LOOPBACK 2
+#define BNX2X_PHY_LOOPBACK_FAILED 1
+#define BNX2X_MAC_LOOPBACK_FAILED 2
+#define BNX2X_EXT_LOOPBACK_FAILED 3
+#define BNX2X_LOOPBACK_FAILED (BNX2X_MAC_LOOPBACK_FAILED | \
+ BNX2X_PHY_LOOPBACK_FAILED)
+
+#define STROM_ASSERT_ARRAY_SIZE 50
+
+/* must be used on a CID before placing it on a HW ring */
+#define HW_CID(bp, x) ((BP_PORT(bp) << 23) | \
+ (BP_VN(bp) << BNX2X_SWCID_SHIFT) | \
+ (x))
+
+#define SP_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_spe))
+#define MAX_SP_DESC_CNT (SP_DESC_CNT - 1)
+
+#define BNX2X_BTR 4
+#define MAX_SPQ_PENDING 8
+
+/* CMNG constants, as derived from system spec calculations */
+/* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */
+#define DEF_MIN_RATE 100
+/* resolution of the rate shaping timer - 400 usec */
+#define RS_PERIODIC_TIMEOUT_USEC 400
+/* number of bytes in single QM arbitration cycle -
+ * coefficient for calculating the fairness timer */
+#define QM_ARB_BYTES 160000
+/* resolution of Min algorithm 1:100 */
+#define MIN_RES 100
+/* how many bytes above threshold for the minimal credit of Min algorithm*/
+#define MIN_ABOVE_THRESH 32768
+/* Fairness algorithm integration time coefficient -
+ * for calculating the actual Tfair */
+#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
+/* Memory of fairness algorithm . 2 cycles */
+#define FAIR_MEM 2
+
+#define ATTN_NIG_FOR_FUNC (1L << 8)
+#define ATTN_SW_TIMER_4_FUNC (1L << 9)
+#define GPIO_2_FUNC (1L << 10)
+#define GPIO_3_FUNC (1L << 11)
+#define GPIO_4_FUNC (1L << 12)
+#define ATTN_GENERAL_ATTN_1 (1L << 13)
+#define ATTN_GENERAL_ATTN_2 (1L << 14)
+#define ATTN_GENERAL_ATTN_3 (1L << 15)
+#define ATTN_GENERAL_ATTN_4 (1L << 13)
+#define ATTN_GENERAL_ATTN_5 (1L << 14)
+#define ATTN_GENERAL_ATTN_6 (1L << 15)
+
+#define ATTN_HARD_WIRED_MASK 0xff00
+#define ATTENTION_ID 4
+
+#define IS_MF_STORAGE_ONLY(bp) (IS_MF_STORAGE_SD(bp) || \
+ IS_MF_FCOE_AFEX(bp))
+
+/* stuff added to make the code fit 80Col */
+
+#define BNX2X_PMF_LINK_ASSERT \
+ GENERAL_ATTEN_OFFSET(LINK_SYNC_ATTENTION_BIT_FUNC_0 + BP_FUNC(bp))
+
+#define BNX2X_MC_ASSERT_BITS \
+ (GENERAL_ATTEN_OFFSET(TSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
+ GENERAL_ATTEN_OFFSET(USTORM_FATAL_ASSERT_ATTENTION_BIT) | \
+ GENERAL_ATTEN_OFFSET(CSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
+ GENERAL_ATTEN_OFFSET(XSTORM_FATAL_ASSERT_ATTENTION_BIT))
+
+#define BNX2X_MCP_ASSERT \
+ GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT)
+
+#define BNX2X_GRC_TIMEOUT GENERAL_ATTEN_OFFSET(LATCHED_ATTN_TIMEOUT_GRC)
+#define BNX2X_GRC_RSV (GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCR) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCT) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCN) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCU) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCP) | \
+ GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RSVD_GRC))
+
+#define HW_INTERRUT_ASSERT_SET_0 \
+ (AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_BRB_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_PBCLIENT_HW_INTERRUPT)
+#define HW_PRTY_ASSERT_SET_0 (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_TCM_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR)
+#define HW_INTERRUT_ASSERT_SET_1 \
+ (AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT)
+#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBF_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_TIMERS_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_XCM_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_NIG_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR)
+#define HW_INTERRUT_ASSERT_SET_2 \
+ (AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT | \
+ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT |\
+ AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT)
+#define HW_PRTY_ASSERT_SET_2 (AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_DMAE_PARITY_ERROR |\
+ AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
+
+#define HW_PRTY_ASSERT_SET_3 (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
+ AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
+ AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
+ AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
+
+#define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \
+ AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)
+
+#define MULTI_MASK 0x7f
+
+#define DEF_USB_FUNC_OFF offsetof(struct cstorm_def_status_block_u, func)
+#define DEF_CSB_FUNC_OFF offsetof(struct cstorm_def_status_block_c, func)
+#define DEF_XSB_FUNC_OFF offsetof(struct xstorm_def_status_block, func)
+#define DEF_TSB_FUNC_OFF offsetof(struct tstorm_def_status_block, func)
+
+#define DEF_USB_IGU_INDEX_OFF \
+ offsetof(struct cstorm_def_status_block_u, igu_index)
+#define DEF_CSB_IGU_INDEX_OFF \
+ offsetof(struct cstorm_def_status_block_c, igu_index)
+#define DEF_XSB_IGU_INDEX_OFF \
+ offsetof(struct xstorm_def_status_block, igu_index)
+#define DEF_TSB_IGU_INDEX_OFF \
+ offsetof(struct tstorm_def_status_block, igu_index)
+
+#define DEF_USB_SEGMENT_OFF \
+ offsetof(struct cstorm_def_status_block_u, segment)
+#define DEF_CSB_SEGMENT_OFF \
+ offsetof(struct cstorm_def_status_block_c, segment)
+#define DEF_XSB_SEGMENT_OFF \
+ offsetof(struct xstorm_def_status_block, segment)
+#define DEF_TSB_SEGMENT_OFF \
+ offsetof(struct tstorm_def_status_block, segment)
+
+#define BNX2X_SP_DSB_INDEX \
+ (&bp->def_status_blk->sp_sb.\
+ index_values[HC_SP_INDEX_ETH_DEF_CONS])
+
+#define CAM_IS_INVALID(x) \
+ (GET_FLAG(x.flags, \
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \
+ (T_ETH_MAC_COMMAND_INVALIDATE))
+
+/* Number of u32 elements in MC hash array */
+#define MC_HASH_SIZE 8
+#define MC_HASH_OFFSET(bp, i) (BAR_TSTRORM_INTMEM + \
+ TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(BP_FUNC(bp)) + i*4)
+
+#ifndef PXP2_REG_PXP2_INT_STS
+#define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0
+#endif
+
+#ifndef ETH_MAX_RX_CLIENTS_E2
+#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H
+#endif
+
+#define BNX2X_VPD_LEN 128
+#define VENDOR_ID_LEN 4
+
+#define VF_ACQUIRE_THRESH 3
+#define VF_ACQUIRE_MAC_FILTERS 1
+#define VF_ACQUIRE_MC_FILTERS 10
+
+#define GOOD_ME_REG(me_reg) (((me_reg) & ME_REG_VF_VALID) && \
+ (!((me_reg) & ME_REG_VF_ERR)))
+int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err);
+
+/* Congestion management fairness mode */
+#define CMNG_FNS_NONE 0
+#define CMNG_FNS_MINMAX 1
+
+#define HC_SEG_ACCESS_DEF 0 /*Driver decision 0-3*/
+#define HC_SEG_ACCESS_ATTN 4
+#define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/
+
+static const u32 dmae_reg_go_c[] = {
+ DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
+ DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
+ DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11,
+ DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15
+};
+
+void bnx2x_set_ethtool_ops(struct bnx2x *bp, struct net_device *netdev);
+void bnx2x_notify_link_changed(struct bnx2x *bp);
+
+#define BNX2X_MF_SD_PROTOCOL(bp) \
+ ((bp)->mf_config[BP_VN(bp)] & FUNC_MF_CFG_PROTOCOL_MASK)
+
+#define BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) \
+ (BNX2X_MF_SD_PROTOCOL(bp) == FUNC_MF_CFG_PROTOCOL_ISCSI)
+
+#define BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp) \
+ (BNX2X_MF_SD_PROTOCOL(bp) == FUNC_MF_CFG_PROTOCOL_FCOE)
+
+#define IS_MF_ISCSI_SD(bp) (IS_MF_SD(bp) && BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp))
+#define IS_MF_FCOE_SD(bp) (IS_MF_SD(bp) && BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp))
+
+#define BNX2X_MF_EXT_PROTOCOL_FCOE(bp) ((bp)->mf_ext_config & \
+ MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD)
+
+#define IS_MF_FCOE_AFEX(bp) (IS_MF_AFEX(bp) && BNX2X_MF_EXT_PROTOCOL_FCOE(bp))
+#define IS_MF_STORAGE_SD(bp) (IS_MF_SD(bp) && \
+ (BNX2X_IS_MF_SD_PROTOCOL_ISCSI(bp) || \
+ BNX2X_IS_MF_SD_PROTOCOL_FCOE(bp)))
+
+#define SET_FLAG(value, mask, flag) \
+ do {\
+ (value) &= ~(mask);\
+ (value) |= ((flag) << (mask##_SHIFT));\
+ } while (0)
+
+#define GET_FLAG(value, mask) \
+ (((value) & (mask)) >> (mask##_SHIFT))
+
+#define GET_FIELD(value, fname) \
+ (((value) & (fname##_MASK)) >> (fname##_SHIFT))
+
+enum {
+ SWITCH_UPDATE,
+ AFEX_UPDATE,
+};
+
+#define NUM_MACS 8
+
+void bnx2x_set_local_cmng(struct bnx2x *bp);
+
+void bnx2x_update_mng_version(struct bnx2x *bp);
+
+#define MCPR_SCRATCH_BASE(bp) \
+ (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
+
+#define E1H_MAX_MF_SB_COUNT (HC_SB_MAX_SB_E1X/(E1HVN_MAX * PORT_MAX))
+
+#endif /* bnx2x.h */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
new file mode 100644
index 00000000000..c43e7238de2
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -0,0 +1,4971 @@
+/* bnx2x_cmn.c: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007-2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
+ * Written by: Eliezer Tamir
+ * Based on code from Michael Chan's bnx2 driver
+ * UDP CSUM errata workaround by Arik Gendelman
+ * Slowpath and fastpath rework by Vladislav Zolotarov
+ * Statistics and Link management by Yitchak Gertner
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/interrupt.h>
+#include <linux/ip.h>
+#include <net/tcp.h>
+#include <net/ipv6.h>
+#include <net/ip6_checksum.h>
+#include <net/busy_poll.h>
+#include <linux/prefetch.h>
+#include "bnx2x_cmn.h"
+#include "bnx2x_init.h"
+#include "bnx2x_sp.h"
+
+static void bnx2x_free_fp_mem_cnic(struct bnx2x *bp);
+static int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp);
+static int bnx2x_alloc_fp_mem(struct bnx2x *bp);
+static int bnx2x_poll(struct napi_struct *napi, int budget);
+
+static void bnx2x_add_all_napi_cnic(struct bnx2x *bp)
+{
+ int i;
+
+ /* Add NAPI objects */
+ for_each_rx_queue_cnic(bp, i) {
+ netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+ bnx2x_poll, NAPI_POLL_WEIGHT);
+ napi_hash_add(&bnx2x_fp(bp, i, napi));
+ }
+}
+
+static void bnx2x_add_all_napi(struct bnx2x *bp)
+{
+ int i;
+
+ /* Add NAPI objects */
+ for_each_eth_queue(bp, i) {
+ netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+ bnx2x_poll, NAPI_POLL_WEIGHT);
+ napi_hash_add(&bnx2x_fp(bp, i, napi));
+ }
+}
+
+static int bnx2x_calc_num_queues(struct bnx2x *bp)
+{
+ int nq = bnx2x_num_queues ? : netif_get_num_default_rss_queues();
+
+ /* Reduce memory usage in kdump environment by using only one queue */
+ if (reset_devices)
+ nq = 1;
+
+ nq = clamp(nq, 1, BNX2X_MAX_QUEUES(bp));
+ return nq;
+}
+
+/**
+ * bnx2x_move_fp - move content of the fastpath structure.
+ *
+ * @bp: driver handle
+ * @from: source FP index
+ * @to: destination FP index
+ *
+ * Makes sure the contents of the bp->fp[to].napi is kept
+ * intact. This is done by first copying the napi struct from
+ * the target to the source, and then mem copying the entire
+ * source onto the target. Update txdata pointers and related
+ * content.
+ */
+static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to)
+{
+ struct bnx2x_fastpath *from_fp = &bp->fp[from];
+ struct bnx2x_fastpath *to_fp = &bp->fp[to];
+ struct bnx2x_sp_objs *from_sp_objs = &bp->sp_objs[from];
+ struct bnx2x_sp_objs *to_sp_objs = &bp->sp_objs[to];
+ struct bnx2x_fp_stats *from_fp_stats = &bp->fp_stats[from];
+ struct bnx2x_fp_stats *to_fp_stats = &bp->fp_stats[to];
+ int old_max_eth_txqs, new_max_eth_txqs;
+ int old_txdata_index = 0, new_txdata_index = 0;
+ struct bnx2x_agg_info *old_tpa_info = to_fp->tpa_info;
+
+ /* Copy the NAPI object as it has been already initialized */
+ from_fp->napi = to_fp->napi;
+
+ /* Move bnx2x_fastpath contents */
+ memcpy(to_fp, from_fp, sizeof(*to_fp));
+ to_fp->index = to;
+
+ /* Retain the tpa_info of the original `to' version as we don't want
+ * 2 FPs to contain the same tpa_info pointer.
+ */
+ to_fp->tpa_info = old_tpa_info;
+
+ /* move sp_objs contents as well, as their indices match fp ones */
+ memcpy(to_sp_objs, from_sp_objs, sizeof(*to_sp_objs));
+
+ /* move fp_stats contents as well, as their indices match fp ones */
+ memcpy(to_fp_stats, from_fp_stats, sizeof(*to_fp_stats));
+
+ /* Update txdata pointers in fp and move txdata content accordingly:
+ * Each fp consumes 'max_cos' txdata structures, so the index should be
+ * decremented by max_cos x delta.
+ */
+
+ old_max_eth_txqs = BNX2X_NUM_ETH_QUEUES(bp) * (bp)->max_cos;
+ new_max_eth_txqs = (BNX2X_NUM_ETH_QUEUES(bp) - from + to) *
+ (bp)->max_cos;
+ if (from == FCOE_IDX(bp)) {
+ old_txdata_index = old_max_eth_txqs + FCOE_TXQ_IDX_OFFSET;
+ new_txdata_index = new_max_eth_txqs + FCOE_TXQ_IDX_OFFSET;
+ }
+
+ memcpy(&bp->bnx2x_txq[new_txdata_index],
+ &bp->bnx2x_txq[old_txdata_index],
+ sizeof(struct bnx2x_fp_txdata));
+ to_fp->txdata_ptr[0] = &bp->bnx2x_txq[new_txdata_index];
+}
+
+/**
+ * bnx2x_fill_fw_str - Fill buffer with FW version string.
+ *
+ * @bp: driver handle
+ * @buf: character buffer to fill with the fw name
+ * @buf_len: length of the above buffer
+ *
+ */
+void bnx2x_fill_fw_str(struct bnx2x *bp, char *buf, size_t buf_len)
+{
+ if (IS_PF(bp)) {
+ u8 phy_fw_ver[PHY_FW_VER_LEN];
+
+ phy_fw_ver[0] = '\0';
+ bnx2x_get_ext_phy_fw_version(&bp->link_params,
+ phy_fw_ver, PHY_FW_VER_LEN);
+ strlcpy(buf, bp->fw_ver, buf_len);
+ snprintf(buf + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver),
+ "bc %d.%d.%d%s%s",
+ (bp->common.bc_ver & 0xff0000) >> 16,
+ (bp->common.bc_ver & 0xff00) >> 8,
+ (bp->common.bc_ver & 0xff),
+ ((phy_fw_ver[0] != '\0') ? " phy " : ""), phy_fw_ver);
+ } else {
+ bnx2x_vf_fill_fw_str(bp, buf, buf_len);
+ }
+}
+
+/**
+ * bnx2x_shrink_eth_fp - guarantees fastpath structures stay intact
+ *
+ * @bp: driver handle
+ * @delta: number of eth queues which were not allocated
+ */
+static void bnx2x_shrink_eth_fp(struct bnx2x *bp, int delta)
+{
+ int i, cos, old_eth_num = BNX2X_NUM_ETH_QUEUES(bp);
+
+ /* Queue pointer cannot be re-set on an fp-basis, as moving pointer
+ * backward along the array could cause memory to be overridden
+ */
+ for (cos = 1; cos < bp->max_cos; cos++) {
+ for (i = 0; i < old_eth_num - delta; i++) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ int new_idx = cos * (old_eth_num - delta) + i;
+
+ memcpy(&bp->bnx2x_txq[new_idx], fp->txdata_ptr[cos],
+ sizeof(struct bnx2x_fp_txdata));
+ fp->txdata_ptr[cos] = &bp->bnx2x_txq[new_idx];
+ }
+ }
+}
+
+int bnx2x_load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */
+
+/* free skb in the packet ring at pos idx
+ * return idx of last bd freed
+ */
+static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
+ u16 idx, unsigned int *pkts_compl,
+ unsigned int *bytes_compl)
+{
+ struct sw_tx_bd *tx_buf = &txdata->tx_buf_ring[idx];
+ struct eth_tx_start_bd *tx_start_bd;
+ struct eth_tx_bd *tx_data_bd;
+ struct sk_buff *skb = tx_buf->skb;
+ u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
+ int nbd;
+ u16 split_bd_len = 0;
+
+ /* prefetch skb end pointer to speedup dev_kfree_skb() */
+ prefetch(&skb->end);
+
+ DP(NETIF_MSG_TX_DONE, "fp[%d]: pkt_idx %d buff @(%p)->skb %p\n",
+ txdata->txq_index, idx, tx_buf, skb);
+
+ tx_start_bd = &txdata->tx_desc_ring[bd_idx].start_bd;
+
+ nbd = le16_to_cpu(tx_start_bd->nbd) - 1;
+#ifdef BNX2X_STOP_ON_ERROR
+ if ((nbd - 1) > (MAX_SKB_FRAGS + 2)) {
+ BNX2X_ERR("BAD nbd!\n");
+ bnx2x_panic();
+ }
+#endif
+ new_cons = nbd + tx_buf->first_bd;
+
+ /* Get the next bd */
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+
+ /* Skip a parse bd... */
+ --nbd;
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+
+ if (tx_buf->flags & BNX2X_HAS_SECOND_PBD) {
+ /* Skip second parse bd... */
+ --nbd;
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ }
+
+ /* TSO headers+data bds share a common mapping. See bnx2x_tx_split() */
+ if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
+ tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
+ split_bd_len = BD_UNMAP_LEN(tx_data_bd);
+ --nbd;
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ }
+
+ /* unmap first bd */
+ dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd),
+ BD_UNMAP_LEN(tx_start_bd) + split_bd_len,
+ DMA_TO_DEVICE);
+
+ /* now free frags */
+ while (nbd > 0) {
+
+ tx_data_bd = &txdata->tx_desc_ring[bd_idx].reg_bd;
+ dma_unmap_page(&bp->pdev->dev, BD_UNMAP_ADDR(tx_data_bd),
+ BD_UNMAP_LEN(tx_data_bd), DMA_TO_DEVICE);
+ if (--nbd)
+ bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+ }
+
+ /* release skb */
+ WARN_ON(!skb);
+ if (likely(skb)) {
+ (*pkts_compl)++;
+ (*bytes_compl) += skb->len;
+ }
+
+ dev_kfree_skb_any(skb);
+ tx_buf->first_bd = 0;
+ tx_buf->skb = NULL;
+
+ return new_cons;
+}
+
+int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata)
+{
+ struct netdev_queue *txq;
+ u16 hw_cons, sw_cons, bd_cons = txdata->tx_bd_cons;
+ unsigned int pkts_compl = 0, bytes_compl = 0;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return -1;
+#endif
+
+ txq = netdev_get_tx_queue(bp->dev, txdata->txq_index);
+ hw_cons = le16_to_cpu(*txdata->tx_cons_sb);
+ sw_cons = txdata->tx_pkt_cons;
+
+ while (sw_cons != hw_cons) {
+ u16 pkt_cons;
+
+ pkt_cons = TX_BD(sw_cons);
+
+ DP(NETIF_MSG_TX_DONE,
+ "queue[%d]: hw_cons %u sw_cons %u pkt_cons %u\n",
+ txdata->txq_index, hw_cons, sw_cons, pkt_cons);
+
+ bd_cons = bnx2x_free_tx_pkt(bp, txdata, pkt_cons,
+ &pkts_compl, &bytes_compl);
+
+ sw_cons++;
+ }
+
+ netdev_tx_completed_queue(txq, pkts_compl, bytes_compl);
+
+ txdata->tx_pkt_cons = sw_cons;
+ txdata->tx_bd_cons = bd_cons;
+
+ /* Need to make the tx_bd_cons update visible to start_xmit()
+ * before checking for netif_tx_queue_stopped(). Without the
+ * memory barrier, there is a small possibility that
+ * start_xmit() will miss it and cause the queue to be stopped
+ * forever.
+ * On the other hand we need an rmb() here to ensure the proper
+ * ordering of bit testing in the following
+ * netif_tx_queue_stopped(txq) call.
+ */
+ smp_mb();
+
+ if (unlikely(netif_tx_queue_stopped(txq))) {
+ /* Taking tx_lock() is needed to prevent re-enabling the queue
+ * while it's empty. This could have happen if rx_action() gets
+ * suspended in bnx2x_tx_int() after the condition before
+ * netif_tx_wake_queue(), while tx_action (bnx2x_start_xmit()):
+ *
+ * stops the queue->sees fresh tx_bd_cons->releases the queue->
+ * sends some packets consuming the whole queue again->
+ * stops the queue
+ */
+
+ __netif_tx_lock(txq, smp_processor_id());
+
+ if ((netif_tx_queue_stopped(txq)) &&
+ (bp->state == BNX2X_STATE_OPEN) &&
+ (bnx2x_tx_avail(bp, txdata) >= MAX_DESC_PER_TX_PKT))
+ netif_tx_wake_queue(txq);
+
+ __netif_tx_unlock(txq);
+ }
+ return 0;
+}
+
+static inline void bnx2x_update_last_max_sge(struct bnx2x_fastpath *fp,
+ u16 idx)
+{
+ u16 last_max = fp->last_max_sge;
+
+ if (SUB_S16(idx, last_max) > 0)
+ fp->last_max_sge = idx;
+}
+
+static inline void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp,
+ u16 sge_len,
+ struct eth_end_agg_rx_cqe *cqe)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 last_max, last_elem, first_elem;
+ u16 delta = 0;
+ u16 i;
+
+ if (!sge_len)
+ return;
+
+ /* First mark all used pages */
+ for (i = 0; i < sge_len; i++)
+ BIT_VEC64_CLEAR_BIT(fp->sge_mask,
+ RX_SGE(le16_to_cpu(cqe->sgl_or_raw_data.sgl[i])));
+
+ DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n",
+ sge_len - 1, le16_to_cpu(cqe->sgl_or_raw_data.sgl[sge_len - 1]));
+
+ /* Here we assume that the last SGE index is the biggest */
+ prefetch((void *)(fp->sge_mask));
+ bnx2x_update_last_max_sge(fp,
+ le16_to_cpu(cqe->sgl_or_raw_data.sgl[sge_len - 1]));
+
+ last_max = RX_SGE(fp->last_max_sge);
+ last_elem = last_max >> BIT_VEC64_ELEM_SHIFT;
+ first_elem = RX_SGE(fp->rx_sge_prod) >> BIT_VEC64_ELEM_SHIFT;
+
+ /* If ring is not full */
+ if (last_elem + 1 != first_elem)
+ last_elem++;
+
+ /* Now update the prod */
+ for (i = first_elem; i != last_elem; i = NEXT_SGE_MASK_ELEM(i)) {
+ if (likely(fp->sge_mask[i]))
+ break;
+
+ fp->sge_mask[i] = BIT_VEC64_ELEM_ONE_MASK;
+ delta += BIT_VEC64_ELEM_SZ;
+ }
+
+ if (delta > 0) {
+ fp->rx_sge_prod += delta;
+ /* clear page-end entries */
+ bnx2x_clear_sge_mask_next_elems(fp);
+ }
+
+ DP(NETIF_MSG_RX_STATUS,
+ "fp->last_max_sge = %d fp->rx_sge_prod = %d\n",
+ fp->last_max_sge, fp->rx_sge_prod);
+}
+
+/* Get Toeplitz hash value in the skb using the value from the
+ * CQE (calculated by HW).
+ */
+static u32 bnx2x_get_rxhash(const struct bnx2x *bp,
+ const struct eth_fast_path_rx_cqe *cqe,
+ enum pkt_hash_types *rxhash_type)
+{
+ /* Get Toeplitz hash from CQE */
+ if ((bp->dev->features & NETIF_F_RXHASH) &&
+ (cqe->status_flags & ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG)) {
+ enum eth_rss_hash_type htype;
+
+ htype = cqe->status_flags & ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE;
+ *rxhash_type = ((htype == TCP_IPV4_HASH_TYPE) ||
+ (htype == TCP_IPV6_HASH_TYPE)) ?
+ PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3;
+
+ return le32_to_cpu(cqe->rss_hash_result);
+ }
+ *rxhash_type = PKT_HASH_TYPE_NONE;
+ return 0;
+}
+
+static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
+ u16 cons, u16 prod,
+ struct eth_fast_path_rx_cqe *cqe)
+{
+ struct bnx2x *bp = fp->bp;
+ struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
+ struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
+ struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
+ dma_addr_t mapping;
+ struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue];
+ struct sw_rx_bd *first_buf = &tpa_info->first_buf;
+
+ /* print error if current state != stop */
+ if (tpa_info->tpa_state != BNX2X_TPA_STOP)
+ BNX2X_ERR("start of bin not in stop [%d]\n", queue);
+
+ /* Try to map an empty data buffer from the aggregation info */
+ mapping = dma_map_single(&bp->pdev->dev,
+ first_buf->data + NET_SKB_PAD,
+ fp->rx_buf_size, DMA_FROM_DEVICE);
+ /*
+ * ...if it fails - move the skb from the consumer to the producer
+ * and set the current aggregation state as ERROR to drop it
+ * when TPA_STOP arrives.
+ */
+
+ if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
+ /* Move the BD from the consumer to the producer */
+ bnx2x_reuse_rx_data(fp, cons, prod);
+ tpa_info->tpa_state = BNX2X_TPA_ERROR;
+ return;
+ }
+
+ /* move empty data from pool to prod */
+ prod_rx_buf->data = first_buf->data;
+ dma_unmap_addr_set(prod_rx_buf, mapping, mapping);
+ /* point prod_bd to new data */
+ prod_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ prod_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+
+ /* move partial skb from cons to pool (don't unmap yet) */
+ *first_buf = *cons_rx_buf;
+
+ /* mark bin state as START */
+ tpa_info->parsing_flags =
+ le16_to_cpu(cqe->pars_flags.flags);
+ tpa_info->vlan_tag = le16_to_cpu(cqe->vlan_tag);
+ tpa_info->tpa_state = BNX2X_TPA_START;
+ tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd);
+ tpa_info->placement_offset = cqe->placement_offset;
+ tpa_info->rxhash = bnx2x_get_rxhash(bp, cqe, &tpa_info->rxhash_type);
+ if (fp->mode == TPA_MODE_GRO) {
+ u16 gro_size = le16_to_cpu(cqe->pkt_len_or_gro_seg_len);
+ tpa_info->full_page = SGE_PAGES / gro_size * gro_size;
+ tpa_info->gro_size = gro_size;
+ }
+
+#ifdef BNX2X_STOP_ON_ERROR
+ fp->tpa_queue_used |= (1 << queue);
+#ifdef _ASM_GENERIC_INT_L64_H
+ DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%lx\n",
+#else
+ DP(NETIF_MSG_RX_STATUS, "fp->tpa_queue_used = 0x%llx\n",
+#endif
+ fp->tpa_queue_used);
+#endif
+}
+
+/* Timestamp option length allowed for TPA aggregation:
+ *
+ * nop nop kind length echo val
+ */
+#define TPA_TSTAMP_OPT_LEN 12
+/**
+ * bnx2x_set_gro_params - compute GRO values
+ *
+ * @skb: packet skb
+ * @parsing_flags: parsing flags from the START CQE
+ * @len_on_bd: total length of the first packet for the
+ * aggregation.
+ * @pkt_len: length of all segments
+ *
+ * Approximate value of the MSS for this aggregation calculated using
+ * the first packet of it.
+ * Compute number of aggregated segments, and gso_type.
+ */
+static void bnx2x_set_gro_params(struct sk_buff *skb, u16 parsing_flags,
+ u16 len_on_bd, unsigned int pkt_len,
+ u16 num_of_coalesced_segs)
+{
+ /* TPA aggregation won't have either IP options or TCP options
+ * other than timestamp or IPv6 extension headers.
+ */
+ u16 hdrs_len = ETH_HLEN + sizeof(struct tcphdr);
+
+ if (GET_FLAG(parsing_flags, PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) ==
+ PRS_FLAG_OVERETH_IPV6) {
+ hdrs_len += sizeof(struct ipv6hdr);
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+ } else {
+ hdrs_len += sizeof(struct iphdr);
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+ }
+
+ /* Check if there was a TCP timestamp, if there is it's will
+ * always be 12 bytes length: nop nop kind length echo val.
+ *
+ * Otherwise FW would close the aggregation.
+ */
+ if (parsing_flags & PARSING_FLAGS_TIME_STAMP_EXIST_FLAG)
+ hdrs_len += TPA_TSTAMP_OPT_LEN;
+
+ skb_shinfo(skb)->gso_size = len_on_bd - hdrs_len;
+
+ /* tcp_gro_complete() will copy NAPI_GRO_CB(skb)->count
+ * to skb_shinfo(skb)->gso_segs
+ */
+ NAPI_GRO_CB(skb)->count = num_of_coalesced_segs;
+}
+
+static int bnx2x_alloc_rx_sge(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ u16 index, gfp_t gfp_mask)
+{
+ struct page *page = alloc_pages(gfp_mask, PAGES_PER_SGE_SHIFT);
+ struct sw_rx_page *sw_buf = &fp->rx_page_ring[index];
+ struct eth_rx_sge *sge = &fp->rx_sge_ring[index];
+ dma_addr_t mapping;
+
+ if (unlikely(page == NULL)) {
+ BNX2X_ERR("Can't alloc sge\n");
+ return -ENOMEM;
+ }
+
+ mapping = dma_map_page(&bp->pdev->dev, page, 0,
+ SGE_PAGES, DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
+ __free_pages(page, PAGES_PER_SGE_SHIFT);
+ BNX2X_ERR("Can't map sge\n");
+ return -ENOMEM;
+ }
+
+ sw_buf->page = page;
+ dma_unmap_addr_set(sw_buf, mapping, mapping);
+
+ sge->addr_hi = cpu_to_le32(U64_HI(mapping));
+ sge->addr_lo = cpu_to_le32(U64_LO(mapping));
+
+ return 0;
+}
+
+static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ struct bnx2x_agg_info *tpa_info,
+ u16 pages,
+ struct sk_buff *skb,
+ struct eth_end_agg_rx_cqe *cqe,
+ u16 cqe_idx)
+{
+ struct sw_rx_page *rx_pg, old_rx_pg;
+ u32 i, frag_len, frag_size;
+ int err, j, frag_id = 0;
+ u16 len_on_bd = tpa_info->len_on_bd;
+ u16 full_page = 0, gro_size = 0;
+
+ frag_size = le16_to_cpu(cqe->pkt_len) - len_on_bd;
+
+ if (fp->mode == TPA_MODE_GRO) {
+ gro_size = tpa_info->gro_size;
+ full_page = tpa_info->full_page;
+ }
+
+ /* This is needed in order to enable forwarding support */
+ if (frag_size)
+ bnx2x_set_gro_params(skb, tpa_info->parsing_flags, len_on_bd,
+ le16_to_cpu(cqe->pkt_len),
+ le16_to_cpu(cqe->num_of_coalesced_segs));
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (pages > min_t(u32, 8, MAX_SKB_FRAGS) * SGE_PAGES) {
+ BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n",
+ pages, cqe_idx);
+ BNX2X_ERR("cqe->pkt_len = %d\n", cqe->pkt_len);
+ bnx2x_panic();
+ return -EINVAL;
+ }
+#endif
+
+ /* Run through the SGL and compose the fragmented skb */
+ for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) {
+ u16 sge_idx = RX_SGE(le16_to_cpu(cqe->sgl_or_raw_data.sgl[j]));
+
+ /* FW gives the indices of the SGE as if the ring is an array
+ (meaning that "next" element will consume 2 indices) */
+ if (fp->mode == TPA_MODE_GRO)
+ frag_len = min_t(u32, frag_size, (u32)full_page);
+ else /* LRO */
+ frag_len = min_t(u32, frag_size, (u32)SGE_PAGES);
+
+ rx_pg = &fp->rx_page_ring[sge_idx];
+ old_rx_pg = *rx_pg;
+
+ /* If we fail to allocate a substitute page, we simply stop
+ where we are and drop the whole packet */
+ err = bnx2x_alloc_rx_sge(bp, fp, sge_idx, GFP_ATOMIC);
+ if (unlikely(err)) {
+ bnx2x_fp_qstats(bp, fp)->rx_skb_alloc_failed++;
+ return err;
+ }
+
+ /* Unmap the page as we're going to pass it to the stack */
+ dma_unmap_page(&bp->pdev->dev,
+ dma_unmap_addr(&old_rx_pg, mapping),
+ SGE_PAGES, DMA_FROM_DEVICE);
+ /* Add one frag and update the appropriate fields in the skb */
+ if (fp->mode == TPA_MODE_LRO)
+ skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len);
+ else { /* GRO */
+ int rem;
+ int offset = 0;
+ for (rem = frag_len; rem > 0; rem -= gro_size) {
+ int len = rem > gro_size ? gro_size : rem;
+ skb_fill_page_desc(skb, frag_id++,
+ old_rx_pg.page, offset, len);
+ if (offset)
+ get_page(old_rx_pg.page);
+ offset += len;
+ }
+ }
+
+ skb->data_len += frag_len;
+ skb->truesize += SGE_PAGES;
+ skb->len += frag_len;
+
+ frag_size -= frag_len;
+ }
+
+ return 0;
+}
+
+static void bnx2x_frag_free(const struct bnx2x_fastpath *fp, void *data)
+{
+ if (fp->rx_frag_size)
+ put_page(virt_to_head_page(data));
+ else
+ kfree(data);
+}
+
+static void *bnx2x_frag_alloc(const struct bnx2x_fastpath *fp, gfp_t gfp_mask)
+{
+ if (fp->rx_frag_size) {
+ /* GFP_KERNEL allocations are used only during initialization */
+ if (unlikely(gfp_mask & __GFP_WAIT))
+ return (void *)__get_free_page(gfp_mask);
+
+ return netdev_alloc_frag(fp->rx_frag_size);
+ }
+
+ return kmalloc(fp->rx_buf_size + NET_SKB_PAD, gfp_mask);
+}
+
+#ifdef CONFIG_INET
+static void bnx2x_gro_ip_csum(struct bnx2x *bp, struct sk_buff *skb)
+{
+ const struct iphdr *iph = ip_hdr(skb);
+ struct tcphdr *th;
+
+ skb_set_transport_header(skb, sizeof(struct iphdr));
+ th = tcp_hdr(skb);
+
+ th->check = ~tcp_v4_check(skb->len - skb_transport_offset(skb),
+ iph->saddr, iph->daddr, 0);
+}
+
+static void bnx2x_gro_ipv6_csum(struct bnx2x *bp, struct sk_buff *skb)
+{
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+ struct tcphdr *th;
+
+ skb_set_transport_header(skb, sizeof(struct ipv6hdr));
+ th = tcp_hdr(skb);
+
+ th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb),
+ &iph->saddr, &iph->daddr, 0);
+}
+
+static void bnx2x_gro_csum(struct bnx2x *bp, struct sk_buff *skb,
+ void (*gro_func)(struct bnx2x*, struct sk_buff*))
+{
+ skb_set_network_header(skb, 0);
+ gro_func(bp, skb);
+ tcp_gro_complete(skb);
+}
+#endif
+
+static void bnx2x_gro_receive(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ struct sk_buff *skb)
+{
+#ifdef CONFIG_INET
+ if (skb_shinfo(skb)->gso_size) {
+ switch (be16_to_cpu(skb->protocol)) {
+ case ETH_P_IP:
+ bnx2x_gro_csum(bp, skb, bnx2x_gro_ip_csum);
+ break;
+ case ETH_P_IPV6:
+ bnx2x_gro_csum(bp, skb, bnx2x_gro_ipv6_csum);
+ break;
+ default:
+ BNX2X_ERR("Error: FW GRO supports only IPv4/IPv6, not 0x%04x\n",
+ be16_to_cpu(skb->protocol));
+ }
+ }
+#endif
+ skb_record_rx_queue(skb, fp->rx_queue);
+ napi_gro_receive(&fp->napi, skb);
+}
+
+static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ struct bnx2x_agg_info *tpa_info,
+ u16 pages,
+ struct eth_end_agg_rx_cqe *cqe,
+ u16 cqe_idx)
+{
+ struct sw_rx_bd *rx_buf = &tpa_info->first_buf;
+ u8 pad = tpa_info->placement_offset;
+ u16 len = tpa_info->len_on_bd;
+ struct sk_buff *skb = NULL;
+ u8 *new_data, *data = rx_buf->data;
+ u8 old_tpa_state = tpa_info->tpa_state;
+
+ tpa_info->tpa_state = BNX2X_TPA_STOP;
+
+ /* If we there was an error during the handling of the TPA_START -
+ * drop this aggregation.
+ */
+ if (old_tpa_state == BNX2X_TPA_ERROR)
+ goto drop;
+
+ /* Try to allocate the new data */
+ new_data = bnx2x_frag_alloc(fp, GFP_ATOMIC);
+ /* Unmap skb in the pool anyway, as we are going to change
+ pool entry status to BNX2X_TPA_STOP even if new skb allocation
+ fails. */
+ dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping),
+ fp->rx_buf_size, DMA_FROM_DEVICE);
+ if (likely(new_data))
+ skb = build_skb(data, fp->rx_frag_size);
+
+ if (likely(skb)) {
+#ifdef BNX2X_STOP_ON_ERROR
+ if (pad + len > fp->rx_buf_size) {
+ BNX2X_ERR("skb_put is about to fail... pad %d len %d rx_buf_size %d\n",
+ pad, len, fp->rx_buf_size);
+ bnx2x_panic();
+ return;
+ }
+#endif
+
+ skb_reserve(skb, pad + NET_SKB_PAD);
+ skb_put(skb, len);
+ skb_set_hash(skb, tpa_info->rxhash, tpa_info->rxhash_type);
+
+ skb->protocol = eth_type_trans(skb, bp->dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ if (!bnx2x_fill_frag_skb(bp, fp, tpa_info, pages,
+ skb, cqe, cqe_idx)) {
+ if (tpa_info->parsing_flags & PARSING_FLAGS_VLAN)
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tpa_info->vlan_tag);
+ bnx2x_gro_receive(bp, fp, skb);
+ } else {
+ DP(NETIF_MSG_RX_STATUS,
+ "Failed to allocate new pages - dropping packet!\n");
+ dev_kfree_skb_any(skb);
+ }
+
+ /* put new data in bin */
+ rx_buf->data = new_data;
+
+ return;
+ }
+ if (new_data)
+ bnx2x_frag_free(fp, new_data);
+drop:
+ /* drop the packet and keep the buffer in the bin */
+ DP(NETIF_MSG_RX_STATUS,
+ "Failed to allocate or map a new skb - dropping packet!\n");
+ bnx2x_fp_stats(bp, fp)->eth_q_stats.rx_skb_alloc_failed++;
+}
+
+static int bnx2x_alloc_rx_data(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ u16 index, gfp_t gfp_mask)
+{
+ u8 *data;
+ struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index];
+ struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
+ dma_addr_t mapping;
+
+ data = bnx2x_frag_alloc(fp, gfp_mask);
+ if (unlikely(data == NULL))
+ return -ENOMEM;
+
+ mapping = dma_map_single(&bp->pdev->dev, data + NET_SKB_PAD,
+ fp->rx_buf_size,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
+ bnx2x_frag_free(fp, data);
+ BNX2X_ERR("Can't map rx data\n");
+ return -ENOMEM;
+ }
+
+ rx_buf->data = data;
+ dma_unmap_addr_set(rx_buf, mapping, mapping);
+
+ rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+
+ return 0;
+}
+
+static
+void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe,
+ struct bnx2x_fastpath *fp,
+ struct bnx2x_eth_q_stats *qstats)
+{
+ /* Do nothing if no L4 csum validation was done.
+ * We do not check whether IP csum was validated. For IPv4 we assume
+ * that if the card got as far as validating the L4 csum, it also
+ * validated the IP csum. IPv6 has no IP csum.
+ */
+ if (cqe->fast_path_cqe.status_flags &
+ ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)
+ return;
+
+ /* If L4 validation was done, check if an error was found. */
+
+ if (cqe->fast_path_cqe.type_error_flags &
+ (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG |
+ ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG))
+ qstats->hw_csum_err++;
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+}
+
+static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 bd_cons, bd_prod, bd_prod_fw, comp_ring_cons;
+ u16 sw_comp_cons, sw_comp_prod;
+ int rx_pkt = 0;
+ union eth_rx_cqe *cqe;
+ struct eth_fast_path_rx_cqe *cqe_fp;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return 0;
+#endif
+ if (budget <= 0)
+ return rx_pkt;
+
+ bd_cons = fp->rx_bd_cons;
+ bd_prod = fp->rx_bd_prod;
+ bd_prod_fw = bd_prod;
+ sw_comp_cons = fp->rx_comp_cons;
+ sw_comp_prod = fp->rx_comp_prod;
+
+ comp_ring_cons = RCQ_BD(sw_comp_cons);
+ cqe = &fp->rx_comp_ring[comp_ring_cons];
+ cqe_fp = &cqe->fast_path_cqe;
+
+ DP(NETIF_MSG_RX_STATUS,
+ "queue[%d]: sw_comp_cons %u\n", fp->index, sw_comp_cons);
+
+ while (BNX2X_IS_CQE_COMPLETED(cqe_fp)) {
+ struct sw_rx_bd *rx_buf = NULL;
+ struct sk_buff *skb;
+ u8 cqe_fp_flags;
+ enum eth_rx_cqe_type cqe_fp_type;
+ u16 len, pad, queue;
+ u8 *data;
+ u32 rxhash;
+ enum pkt_hash_types rxhash_type;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return 0;
+#endif
+
+ bd_prod = RX_BD(bd_prod);
+ bd_cons = RX_BD(bd_cons);
+
+ /* A rmb() is required to ensure that the CQE is not read
+ * before it is written by the adapter DMA. PCI ordering
+ * rules will make sure the other fields are written before
+ * the marker at the end of struct eth_fast_path_rx_cqe
+ * but without rmb() a weakly ordered processor can process
+ * stale data. Without the barrier TPA state-machine might
+ * enter inconsistent state and kernel stack might be
+ * provided with incorrect packet description - these lead
+ * to various kernel crashed.
+ */
+ rmb();
+
+ cqe_fp_flags = cqe_fp->type_error_flags;
+ cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE;
+
+ DP(NETIF_MSG_RX_STATUS,
+ "CQE type %x err %x status %x queue %x vlan %x len %u\n",
+ CQE_TYPE(cqe_fp_flags),
+ cqe_fp_flags, cqe_fp->status_flags,
+ le32_to_cpu(cqe_fp->rss_hash_result),
+ le16_to_cpu(cqe_fp->vlan_tag),
+ le16_to_cpu(cqe_fp->pkt_len_or_gro_seg_len));
+
+ /* is this a slowpath msg? */
+ if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) {
+ bnx2x_sp_event(fp, cqe);
+ goto next_cqe;
+ }
+
+ rx_buf = &fp->rx_buf_ring[bd_cons];
+ data = rx_buf->data;
+
+ if (!CQE_TYPE_FAST(cqe_fp_type)) {
+ struct bnx2x_agg_info *tpa_info;
+ u16 frag_size, pages;
+#ifdef BNX2X_STOP_ON_ERROR
+ /* sanity check */
+ if (fp->disable_tpa &&
+ (CQE_TYPE_START(cqe_fp_type) ||
+ CQE_TYPE_STOP(cqe_fp_type)))
+ BNX2X_ERR("START/STOP packet while disable_tpa type %x\n",
+ CQE_TYPE(cqe_fp_type));
+#endif
+
+ if (CQE_TYPE_START(cqe_fp_type)) {
+ u16 queue = cqe_fp->queue_index;
+ DP(NETIF_MSG_RX_STATUS,
+ "calling tpa_start on queue %d\n",
+ queue);
+
+ bnx2x_tpa_start(fp, queue,
+ bd_cons, bd_prod,
+ cqe_fp);
+
+ goto next_rx;
+ }
+ queue = cqe->end_agg_cqe.queue_index;
+ tpa_info = &fp->tpa_info[queue];
+ DP(NETIF_MSG_RX_STATUS,
+ "calling tpa_stop on queue %d\n",
+ queue);
+
+ frag_size = le16_to_cpu(cqe->end_agg_cqe.pkt_len) -
+ tpa_info->len_on_bd;
+
+ if (fp->mode == TPA_MODE_GRO)
+ pages = (frag_size + tpa_info->full_page - 1) /
+ tpa_info->full_page;
+ else
+ pages = SGE_PAGE_ALIGN(frag_size) >>
+ SGE_PAGE_SHIFT;
+
+ bnx2x_tpa_stop(bp, fp, tpa_info, pages,
+ &cqe->end_agg_cqe, comp_ring_cons);
+#ifdef BNX2X_STOP_ON_ERROR
+ if (bp->panic)
+ return 0;
+#endif
+
+ bnx2x_update_sge_prod(fp, pages, &cqe->end_agg_cqe);
+ goto next_cqe;
+ }
+ /* non TPA */
+ len = le16_to_cpu(cqe_fp->pkt_len_or_gro_seg_len);
+ pad = cqe_fp->placement_offset;
+ dma_sync_single_for_cpu(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ pad + RX_COPY_THRESH,
+ DMA_FROM_DEVICE);
+ pad += NET_SKB_PAD;
+ prefetch(data + pad); /* speedup eth_type_trans() */
+ /* is this an error packet? */
+ if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) {
+ DP(NETIF_MSG_RX_ERR | NETIF_MSG_RX_STATUS,
+ "ERROR flags %x rx packet %u\n",
+ cqe_fp_flags, sw_comp_cons);
+ bnx2x_fp_qstats(bp, fp)->rx_err_discard_pkt++;
+ goto reuse_rx;
+ }
+
+ /* Since we don't have a jumbo ring
+ * copy small packets if mtu > 1500
+ */
+ if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) &&
+ (len <= RX_COPY_THRESH)) {
+ skb = netdev_alloc_skb_ip_align(bp->dev, len);
+ if (skb == NULL) {
+ DP(NETIF_MSG_RX_ERR | NETIF_MSG_RX_STATUS,
+ "ERROR packet dropped because of alloc failure\n");
+ bnx2x_fp_qstats(bp, fp)->rx_skb_alloc_failed++;
+ goto reuse_rx;
+ }
+ memcpy(skb->data, data + pad, len);
+ bnx2x_reuse_rx_data(fp, bd_cons, bd_prod);
+ } else {
+ if (likely(bnx2x_alloc_rx_data(bp, fp, bd_prod,
+ GFP_ATOMIC) == 0)) {
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ fp->rx_buf_size,
+ DMA_FROM_DEVICE);
+ skb = build_skb(data, fp->rx_frag_size);
+ if (unlikely(!skb)) {
+ bnx2x_frag_free(fp, data);
+ bnx2x_fp_qstats(bp, fp)->
+ rx_skb_alloc_failed++;
+ goto next_rx;
+ }
+ skb_reserve(skb, pad);
+ } else {
+ DP(NETIF_MSG_RX_ERR | NETIF_MSG_RX_STATUS,
+ "ERROR packet dropped because of alloc failure\n");
+ bnx2x_fp_qstats(bp, fp)->rx_skb_alloc_failed++;
+reuse_rx:
+ bnx2x_reuse_rx_data(fp, bd_cons, bd_prod);
+ goto next_rx;
+ }
+ }
+
+ skb_put(skb, len);
+ skb->protocol = eth_type_trans(skb, bp->dev);
+
+ /* Set Toeplitz hash for a none-LRO skb */
+ rxhash = bnx2x_get_rxhash(bp, cqe_fp, &rxhash_type);
+ skb_set_hash(skb, rxhash, rxhash_type);
+
+ skb_checksum_none_assert(skb);
+
+ if (bp->dev->features & NETIF_F_RXCSUM)
+ bnx2x_csum_validate(skb, cqe, fp,
+ bnx2x_fp_qstats(bp, fp));
+
+ skb_record_rx_queue(skb, fp->rx_queue);
+
+ if (le16_to_cpu(cqe_fp->pars_flags.flags) &
+ PARSING_FLAGS_VLAN)
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ le16_to_cpu(cqe_fp->vlan_tag));
+
+ skb_mark_napi_id(skb, &fp->napi);
+
+ if (bnx2x_fp_ll_polling(fp))
+ netif_receive_skb(skb);
+ else
+ napi_gro_receive(&fp->napi, skb);
+next_rx:
+ rx_buf->data = NULL;
+
+ bd_cons = NEXT_RX_IDX(bd_cons);
+ bd_prod = NEXT_RX_IDX(bd_prod);
+ bd_prod_fw = NEXT_RX_IDX(bd_prod_fw);
+ rx_pkt++;
+next_cqe:
+ sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod);
+ sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons);
+
+ /* mark CQE as free */
+ BNX2X_SEED_CQE(cqe_fp);
+
+ if (rx_pkt == budget)
+ break;
+
+ comp_ring_cons = RCQ_BD(sw_comp_cons);
+ cqe = &fp->rx_comp_ring[comp_ring_cons];
+ cqe_fp = &cqe->fast_path_cqe;
+ } /* while */
+
+ fp->rx_bd_cons = bd_cons;
+ fp->rx_bd_prod = bd_prod_fw;
+ fp->rx_comp_cons = sw_comp_cons;
+ fp->rx_comp_prod = sw_comp_prod;
+
+ /* Update producers */
+ bnx2x_update_rx_prod(bp, fp, bd_prod_fw, sw_comp_prod,
+ fp->rx_sge_prod);
+
+ fp->rx_pkt += rx_pkt;
+ fp->rx_calls++;
+
+ return rx_pkt;
+}
+
+static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
+{
+ struct bnx2x_fastpath *fp = fp_cookie;
+ struct bnx2x *bp = fp->bp;
+ u8 cos;
+
+ DP(NETIF_MSG_INTR,
+ "got an MSI-X interrupt on IDX:SB [fp %d fw_sd %d igusb %d]\n",
+ fp->index, fp->fw_sb_id, fp->igu_sb_id);
+
+ bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return IRQ_HANDLED;
+#endif
+
+ /* Handle Rx and Tx according to MSI-X vector */
+ for_each_cos_in_tx_queue(fp, cos)
+ prefetch(fp->txdata_ptr[cos]->tx_cons_sb);
+
+ prefetch(&fp->sb_running_index[SM_RX_ID]);
+ napi_schedule(&bnx2x_fp(bp, fp->index, napi));
+
+ return IRQ_HANDLED;
+}
+
+/* HW Lock for shared dual port PHYs */
+void bnx2x_acquire_phy_lock(struct bnx2x *bp)
+{
+ mutex_lock(&bp->port.phy_mutex);
+
+ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
+}
+
+void bnx2x_release_phy_lock(struct bnx2x *bp)
+{
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
+
+ mutex_unlock(&bp->port.phy_mutex);
+}
+
+/* calculates MF speed according to current linespeed and MF configuration */
+u16 bnx2x_get_mf_speed(struct bnx2x *bp)
+{
+ u16 line_speed = bp->link_vars.line_speed;
+ if (IS_MF(bp)) {
+ u16 maxCfg = bnx2x_extract_max_cfg(bp,
+ bp->mf_config[BP_VN(bp)]);
+
+ /* Calculate the current MAX line speed limit for the MF
+ * devices
+ */
+ if (IS_MF_SI(bp))
+ line_speed = (line_speed * maxCfg) / 100;
+ else { /* SD mode */
+ u16 vn_max_rate = maxCfg * 100;
+
+ if (vn_max_rate < line_speed)
+ line_speed = vn_max_rate;
+ }
+ }
+
+ return line_speed;
+}
+
+/**
+ * bnx2x_fill_report_data - fill link report data to report
+ *
+ * @bp: driver handle
+ * @data: link state to update
+ *
+ * It uses a none-atomic bit operations because is called under the mutex.
+ */
+static void bnx2x_fill_report_data(struct bnx2x *bp,
+ struct bnx2x_link_report_data *data)
+{
+ u16 line_speed = bnx2x_get_mf_speed(bp);
+
+ memset(data, 0, sizeof(*data));
+
+ /* Fill the report data: effective line speed */
+ data->line_speed = line_speed;
+
+ /* Link is down */
+ if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &data->link_report_flags);
+
+ /* Full DUPLEX */
+ if (bp->link_vars.duplex == DUPLEX_FULL)
+ __set_bit(BNX2X_LINK_REPORT_FD, &data->link_report_flags);
+
+ /* Rx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
+ __set_bit(BNX2X_LINK_REPORT_RX_FC_ON, &data->link_report_flags);
+
+ /* Tx Flow Control is ON */
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ __set_bit(BNX2X_LINK_REPORT_TX_FC_ON, &data->link_report_flags);
+}
+
+/**
+ * bnx2x_link_report - report link status to OS.
+ *
+ * @bp: driver handle
+ *
+ * Calls the __bnx2x_link_report() under the same locking scheme
+ * as a link/PHY state managing code to ensure a consistent link
+ * reporting.
+ */
+
+void bnx2x_link_report(struct bnx2x *bp)
+{
+ bnx2x_acquire_phy_lock(bp);
+ __bnx2x_link_report(bp);
+ bnx2x_release_phy_lock(bp);
+}
+
+/**
+ * __bnx2x_link_report - report link status to OS.
+ *
+ * @bp: driver handle
+ *
+ * None atomic implementation.
+ * Should be called under the phy_lock.
+ */
+void __bnx2x_link_report(struct bnx2x *bp)
+{
+ struct bnx2x_link_report_data cur_data;
+
+ /* reread mf_cfg */
+ if (IS_PF(bp) && !CHIP_IS_E1(bp))
+ bnx2x_read_mf_cfg(bp);
+
+ /* Read the current link report info */
+ bnx2x_fill_report_data(bp, &cur_data);
+
+ /* Don't report link down or exactly the same link status twice */
+ if (!memcmp(&cur_data, &bp->last_reported_link, sizeof(cur_data)) ||
+ (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->last_reported_link.link_report_flags) &&
+ test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &cur_data.link_report_flags)))
+ return;
+
+ bp->link_cnt++;
+
+ /* We are going to report a new link parameters now -
+ * remember the current data for the next time.
+ */
+ memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data));
+
+ if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &cur_data.link_report_flags)) {
+ netif_carrier_off(bp->dev);
+ netdev_err(bp->dev, "NIC Link is Down\n");
+ return;
+ } else {
+ const char *duplex;
+ const char *flow;
+
+ netif_carrier_on(bp->dev);
+
+ if (test_and_clear_bit(BNX2X_LINK_REPORT_FD,
+ &cur_data.link_report_flags))
+ duplex = "full";
+ else
+ duplex = "half";
+
+ /* Handle the FC at the end so that only these flags would be
+ * possibly set. This way we may easily check if there is no FC
+ * enabled.
+ */
+ if (cur_data.link_report_flags) {
+ if (test_bit(BNX2X_LINK_REPORT_RX_FC_ON,
+ &cur_data.link_report_flags)) {
+ if (test_bit(BNX2X_LINK_REPORT_TX_FC_ON,
+ &cur_data.link_report_flags))
+ flow = "ON - receive & transmit";
+ else
+ flow = "ON - receive";
+ } else {
+ flow = "ON - transmit";
+ }
+ } else {
+ flow = "none";
+ }
+ netdev_info(bp->dev, "NIC Link is Up, %d Mbps %s duplex, Flow control: %s\n",
+ cur_data.line_speed, duplex, flow);
+ }
+}
+
+static void bnx2x_set_next_page_sgl(struct bnx2x_fastpath *fp)
+{
+ int i;
+
+ for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
+ struct eth_rx_sge *sge;
+
+ sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2];
+ sge->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_sge_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
+
+ sge->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_sge_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES)));
+ }
+}
+
+static void bnx2x_free_tpa_pool(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, int last)
+{
+ int i;
+
+ for (i = 0; i < last; i++) {
+ struct bnx2x_agg_info *tpa_info = &fp->tpa_info[i];
+ struct sw_rx_bd *first_buf = &tpa_info->first_buf;
+ u8 *data = first_buf->data;
+
+ if (data == NULL) {
+ DP(NETIF_MSG_IFDOWN, "tpa bin %d empty on free\n", i);
+ continue;
+ }
+ if (tpa_info->tpa_state == BNX2X_TPA_START)
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(first_buf, mapping),
+ fp->rx_buf_size, DMA_FROM_DEVICE);
+ bnx2x_frag_free(fp, data);
+ first_buf->data = NULL;
+ }
+}
+
+void bnx2x_init_rx_rings_cnic(struct bnx2x *bp)
+{
+ int j;
+
+ for_each_rx_queue_cnic(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ fp->rx_bd_cons = 0;
+
+ /* Activate BD ring */
+ /* Warning!
+ * this will generate an interrupt (to the TSTORM)
+ * must only be done after chip is initialized
+ */
+ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
+ fp->rx_sge_prod);
+ }
+}
+
+void bnx2x_init_rx_rings(struct bnx2x *bp)
+{
+ int func = BP_FUNC(bp);
+ u16 ring_prod;
+ int i, j;
+
+ /* Allocate TPA resources */
+ for_each_eth_queue(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ DP(NETIF_MSG_IFUP,
+ "mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
+
+ if (!fp->disable_tpa) {
+ /* Fill the per-aggregation pool */
+ for (i = 0; i < MAX_AGG_QS(bp); i++) {
+ struct bnx2x_agg_info *tpa_info =
+ &fp->tpa_info[i];
+ struct sw_rx_bd *first_buf =
+ &tpa_info->first_buf;
+
+ first_buf->data =
+ bnx2x_frag_alloc(fp, GFP_KERNEL);
+ if (!first_buf->data) {
+ BNX2X_ERR("Failed to allocate TPA skb pool for queue[%d] - disabling TPA on this queue!\n",
+ j);
+ bnx2x_free_tpa_pool(bp, fp, i);
+ fp->disable_tpa = 1;
+ break;
+ }
+ dma_unmap_addr_set(first_buf, mapping, 0);
+ tpa_info->tpa_state = BNX2X_TPA_STOP;
+ }
+
+ /* "next page" elements initialization */
+ bnx2x_set_next_page_sgl(fp);
+
+ /* set SGEs bit mask */
+ bnx2x_init_sge_ring_bit_mask(fp);
+
+ /* Allocate SGEs and initialize the ring elements */
+ for (i = 0, ring_prod = 0;
+ i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) {
+
+ if (bnx2x_alloc_rx_sge(bp, fp, ring_prod,
+ GFP_KERNEL) < 0) {
+ BNX2X_ERR("was only able to allocate %d rx sges\n",
+ i);
+ BNX2X_ERR("disabling TPA for queue[%d]\n",
+ j);
+ /* Cleanup already allocated elements */
+ bnx2x_free_rx_sge_range(bp, fp,
+ ring_prod);
+ bnx2x_free_tpa_pool(bp, fp,
+ MAX_AGG_QS(bp));
+ fp->disable_tpa = 1;
+ ring_prod = 0;
+ break;
+ }
+ ring_prod = NEXT_SGE_IDX(ring_prod);
+ }
+
+ fp->rx_sge_prod = ring_prod;
+ }
+ }
+
+ for_each_eth_queue(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ fp->rx_bd_cons = 0;
+
+ /* Activate BD ring */
+ /* Warning!
+ * this will generate an interrupt (to the TSTORM)
+ * must only be done after chip is initialized
+ */
+ bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
+ fp->rx_sge_prod);
+
+ if (j != 0)
+ continue;
+
+ if (CHIP_IS_E1(bp)) {
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func),
+ U64_LO(fp->rx_comp_mapping));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4,
+ U64_HI(fp->rx_comp_mapping));
+ }
+ }
+}
+
+static void bnx2x_free_tx_skbs_queue(struct bnx2x_fastpath *fp)
+{
+ u8 cos;
+ struct bnx2x *bp = fp->bp;
+
+ for_each_cos_in_tx_queue(fp, cos) {
+ struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos];
+ unsigned pkts_compl = 0, bytes_compl = 0;
+
+ u16 sw_prod = txdata->tx_pkt_prod;
+ u16 sw_cons = txdata->tx_pkt_cons;
+
+ while (sw_cons != sw_prod) {
+ bnx2x_free_tx_pkt(bp, txdata, TX_BD(sw_cons),
+ &pkts_compl, &bytes_compl);
+ sw_cons++;
+ }
+
+ netdev_tx_reset_queue(
+ netdev_get_tx_queue(bp->dev,
+ txdata->txq_index));
+ }
+}
+
+static void bnx2x_free_tx_skbs_cnic(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_tx_queue_cnic(bp, i) {
+ bnx2x_free_tx_skbs_queue(&bp->fp[i]);
+ }
+}
+
+static void bnx2x_free_tx_skbs(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_eth_queue(bp, i) {
+ bnx2x_free_tx_skbs_queue(&bp->fp[i]);
+ }
+}
+
+static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp)
+{
+ struct bnx2x *bp = fp->bp;
+ int i;
+
+ /* ring wasn't allocated */
+ if (fp->rx_buf_ring == NULL)
+ return;
+
+ for (i = 0; i < NUM_RX_BD; i++) {
+ struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
+ u8 *data = rx_buf->data;
+
+ if (data == NULL)
+ continue;
+ dma_unmap_single(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ fp->rx_buf_size, DMA_FROM_DEVICE);
+
+ rx_buf->data = NULL;
+ bnx2x_frag_free(fp, data);
+ }
+}
+
+static void bnx2x_free_rx_skbs_cnic(struct bnx2x *bp)
+{
+ int j;
+
+ for_each_rx_queue_cnic(bp, j) {
+ bnx2x_free_rx_bds(&bp->fp[j]);
+ }
+}
+
+static void bnx2x_free_rx_skbs(struct bnx2x *bp)
+{
+ int j;
+
+ for_each_eth_queue(bp, j) {
+ struct bnx2x_fastpath *fp = &bp->fp[j];
+
+ bnx2x_free_rx_bds(fp);
+
+ if (!fp->disable_tpa)
+ bnx2x_free_tpa_pool(bp, fp, MAX_AGG_QS(bp));
+ }
+}
+
+static void bnx2x_free_skbs_cnic(struct bnx2x *bp)
+{
+ bnx2x_free_tx_skbs_cnic(bp);
+ bnx2x_free_rx_skbs_cnic(bp);
+}
+
+void bnx2x_free_skbs(struct bnx2x *bp)
+{
+ bnx2x_free_tx_skbs(bp);
+ bnx2x_free_rx_skbs(bp);
+}
+
+void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value)
+{
+ /* load old values */
+ u32 mf_cfg = bp->mf_config[BP_VN(bp)];
+
+ if (value != bnx2x_extract_max_cfg(bp, mf_cfg)) {
+ /* leave all but MAX value */
+ mf_cfg &= ~FUNC_MF_CFG_MAX_BW_MASK;
+
+ /* set new MAX value */
+ mf_cfg |= (value << FUNC_MF_CFG_MAX_BW_SHIFT)
+ & FUNC_MF_CFG_MAX_BW_MASK;
+
+ bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, mf_cfg);
+ }
+}
+
+/**
+ * bnx2x_free_msix_irqs - free previously requested MSI-X IRQ vectors
+ *
+ * @bp: driver handle
+ * @nvecs: number of vectors to be released
+ */
+static void bnx2x_free_msix_irqs(struct bnx2x *bp, int nvecs)
+{
+ int i, offset = 0;
+
+ if (nvecs == offset)
+ return;
+
+ /* VFs don't have a default SB */
+ if (IS_PF(bp)) {
+ free_irq(bp->msix_table[offset].vector, bp->dev);
+ DP(NETIF_MSG_IFDOWN, "released sp irq (%d)\n",
+ bp->msix_table[offset].vector);
+ offset++;
+ }
+
+ if (CNIC_SUPPORT(bp)) {
+ if (nvecs == offset)
+ return;
+ offset++;
+ }
+
+ for_each_eth_queue(bp, i) {
+ if (nvecs == offset)
+ return;
+ DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq\n",
+ i, bp->msix_table[offset].vector);
+
+ free_irq(bp->msix_table[offset++].vector, &bp->fp[i]);
+ }
+}
+
+void bnx2x_free_irq(struct bnx2x *bp)
+{
+ if (bp->flags & USING_MSIX_FLAG &&
+ !(bp->flags & USING_SINGLE_MSIX_FLAG)) {
+ int nvecs = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_SUPPORT(bp);
+
+ /* vfs don't have a default status block */
+ if (IS_PF(bp))
+ nvecs++;
+
+ bnx2x_free_msix_irqs(bp, nvecs);
+ } else {
+ free_irq(bp->dev->irq, bp->dev);
+ }
+}
+
+int bnx2x_enable_msix(struct bnx2x *bp)
+{
+ int msix_vec = 0, i, rc;
+
+ /* VFs don't have a default status block */
+ if (IS_PF(bp)) {
+ bp->msix_table[msix_vec].entry = msix_vec;
+ BNX2X_DEV_INFO("msix_table[0].entry = %d (slowpath)\n",
+ bp->msix_table[0].entry);
+ msix_vec++;
+ }
+
+ /* Cnic requires an msix vector for itself */
+ if (CNIC_SUPPORT(bp)) {
+ bp->msix_table[msix_vec].entry = msix_vec;
+ BNX2X_DEV_INFO("msix_table[%d].entry = %d (CNIC)\n",
+ msix_vec, bp->msix_table[msix_vec].entry);
+ msix_vec++;
+ }
+
+ /* We need separate vectors for ETH queues only (not FCoE) */
+ for_each_eth_queue(bp, i) {
+ bp->msix_table[msix_vec].entry = msix_vec;
+ BNX2X_DEV_INFO("msix_table[%d].entry = %d (fastpath #%u)\n",
+ msix_vec, msix_vec, i);
+ msix_vec++;
+ }
+
+ DP(BNX2X_MSG_SP, "about to request enable msix with %d vectors\n",
+ msix_vec);
+
+ rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0],
+ BNX2X_MIN_MSIX_VEC_CNT(bp), msix_vec);
+ /*
+ * reconfigure number of tx/rx queues according to available
+ * MSI-X vectors
+ */
+ if (rc == -ENOSPC) {
+ /* Get by with single vector */
+ rc = pci_enable_msix_range(bp->pdev, &bp->msix_table[0], 1, 1);
+ if (rc < 0) {
+ BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n",
+ rc);
+ goto no_msix;
+ }
+
+ BNX2X_DEV_INFO("Using single MSI-X vector\n");
+ bp->flags |= USING_SINGLE_MSIX_FLAG;
+
+ BNX2X_DEV_INFO("set number of queues to 1\n");
+ bp->num_ethernet_queues = 1;
+ bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
+ } else if (rc < 0) {
+ BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
+ goto no_msix;
+ } else if (rc < msix_vec) {
+ /* how less vectors we will have? */
+ int diff = msix_vec - rc;
+
+ BNX2X_DEV_INFO("Trying to use less MSI-X vectors: %d\n", rc);
+
+ /*
+ * decrease number of queues by number of unallocated entries
+ */
+ bp->num_ethernet_queues -= diff;
+ bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
+
+ BNX2X_DEV_INFO("New queue configuration set: %d\n",
+ bp->num_queues);
+ }
+
+ bp->flags |= USING_MSIX_FLAG;
+
+ return 0;
+
+no_msix:
+ /* fall to INTx if not enough memory */
+ if (rc == -ENOMEM)
+ bp->flags |= DISABLE_MSI_FLAG;
+
+ return rc;
+}
+
+static int bnx2x_req_msix_irqs(struct bnx2x *bp)
+{
+ int i, rc, offset = 0;
+
+ /* no default status block for vf */
+ if (IS_PF(bp)) {
+ rc = request_irq(bp->msix_table[offset++].vector,
+ bnx2x_msix_sp_int, 0,
+ bp->dev->name, bp->dev);
+ if (rc) {
+ BNX2X_ERR("request sp irq failed\n");
+ return -EBUSY;
+ }
+ }
+
+ if (CNIC_SUPPORT(bp))
+ offset++;
+
+ for_each_eth_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ snprintf(fp->name, sizeof(fp->name), "%s-fp-%d",
+ bp->dev->name, i);
+
+ rc = request_irq(bp->msix_table[offset].vector,
+ bnx2x_msix_fp_int, 0, fp->name, fp);
+ if (rc) {
+ BNX2X_ERR("request fp #%d irq (%d) failed rc %d\n", i,
+ bp->msix_table[offset].vector, rc);
+ bnx2x_free_msix_irqs(bp, offset);
+ return -EBUSY;
+ }
+
+ offset++;
+ }
+
+ i = BNX2X_NUM_ETH_QUEUES(bp);
+ if (IS_PF(bp)) {
+ offset = 1 + CNIC_SUPPORT(bp);
+ netdev_info(bp->dev,
+ "using MSI-X IRQs: sp %d fp[%d] %d ... fp[%d] %d\n",
+ bp->msix_table[0].vector,
+ 0, bp->msix_table[offset].vector,
+ i - 1, bp->msix_table[offset + i - 1].vector);
+ } else {
+ offset = CNIC_SUPPORT(bp);
+ netdev_info(bp->dev,
+ "using MSI-X IRQs: fp[%d] %d ... fp[%d] %d\n",
+ 0, bp->msix_table[offset].vector,
+ i - 1, bp->msix_table[offset + i - 1].vector);
+ }
+ return 0;
+}
+
+int bnx2x_enable_msi(struct bnx2x *bp)
+{
+ int rc;
+
+ rc = pci_enable_msi(bp->pdev);
+ if (rc) {
+ BNX2X_DEV_INFO("MSI is not attainable\n");
+ return -1;
+ }
+ bp->flags |= USING_MSI_FLAG;
+
+ return 0;
+}
+
+static int bnx2x_req_irq(struct bnx2x *bp)
+{
+ unsigned long flags;
+ unsigned int irq;
+
+ if (bp->flags & (USING_MSI_FLAG | USING_MSIX_FLAG))
+ flags = 0;
+ else
+ flags = IRQF_SHARED;
+
+ if (bp->flags & USING_MSIX_FLAG)
+ irq = bp->msix_table[0].vector;
+ else
+ irq = bp->pdev->irq;
+
+ return request_irq(irq, bnx2x_interrupt, flags, bp->dev->name, bp->dev);
+}
+
+static int bnx2x_setup_irqs(struct bnx2x *bp)
+{
+ int rc = 0;
+ if (bp->flags & USING_MSIX_FLAG &&
+ !(bp->flags & USING_SINGLE_MSIX_FLAG)) {
+ rc = bnx2x_req_msix_irqs(bp);
+ if (rc)
+ return rc;
+ } else {
+ rc = bnx2x_req_irq(bp);
+ if (rc) {
+ BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
+ return rc;
+ }
+ if (bp->flags & USING_MSI_FLAG) {
+ bp->dev->irq = bp->pdev->irq;
+ netdev_info(bp->dev, "using MSI IRQ %d\n",
+ bp->dev->irq);
+ }
+ if (bp->flags & USING_MSIX_FLAG) {
+ bp->dev->irq = bp->msix_table[0].vector;
+ netdev_info(bp->dev, "using MSIX IRQ %d\n",
+ bp->dev->irq);
+ }
+ }
+
+ return 0;
+}
+
+static void bnx2x_napi_enable_cnic(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_rx_queue_cnic(bp, i) {
+ bnx2x_fp_init_lock(&bp->fp[i]);
+ napi_enable(&bnx2x_fp(bp, i, napi));
+ }
+}
+
+static void bnx2x_napi_enable(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_eth_queue(bp, i) {
+ bnx2x_fp_init_lock(&bp->fp[i]);
+ napi_enable(&bnx2x_fp(bp, i, napi));
+ }
+}
+
+static void bnx2x_napi_disable_cnic(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_rx_queue_cnic(bp, i) {
+ napi_disable(&bnx2x_fp(bp, i, napi));
+ while (!bnx2x_fp_ll_disable(&bp->fp[i]))
+ usleep_range(1000, 2000);
+ }
+}
+
+static void bnx2x_napi_disable(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_eth_queue(bp, i) {
+ napi_disable(&bnx2x_fp(bp, i, napi));
+ while (!bnx2x_fp_ll_disable(&bp->fp[i]))
+ usleep_range(1000, 2000);
+ }
+}
+
+void bnx2x_netif_start(struct bnx2x *bp)
+{
+ if (netif_running(bp->dev)) {
+ bnx2x_napi_enable(bp);
+ if (CNIC_LOADED(bp))
+ bnx2x_napi_enable_cnic(bp);
+ bnx2x_int_enable(bp);
+ if (bp->state == BNX2X_STATE_OPEN)
+ netif_tx_wake_all_queues(bp->dev);
+ }
+}
+
+void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
+{
+ bnx2x_int_disable_sync(bp, disable_hw);
+ bnx2x_napi_disable(bp);
+ if (CNIC_LOADED(bp))
+ bnx2x_napi_disable_cnic(bp);
+}
+
+u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
+ void *accel_priv, select_queue_fallback_t fallback)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (CNIC_LOADED(bp) && !NO_FCOE(bp)) {
+ struct ethhdr *hdr = (struct ethhdr *)skb->data;
+ u16 ether_type = ntohs(hdr->h_proto);
+
+ /* Skip VLAN tag if present */
+ if (ether_type == ETH_P_8021Q) {
+ struct vlan_ethhdr *vhdr =
+ (struct vlan_ethhdr *)skb->data;
+
+ ether_type = ntohs(vhdr->h_vlan_encapsulated_proto);
+ }
+
+ /* If ethertype is FCoE or FIP - use FCoE ring */
+ if ((ether_type == ETH_P_FCOE) || (ether_type == ETH_P_FIP))
+ return bnx2x_fcoe_tx(bp, txq_index);
+ }
+
+ /* select a non-FCoE queue */
+ return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp);
+}
+
+void bnx2x_set_num_queues(struct bnx2x *bp)
+{
+ /* RSS queues */
+ bp->num_ethernet_queues = bnx2x_calc_num_queues(bp);
+
+ /* override in STORAGE SD modes */
+ if (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))
+ bp->num_ethernet_queues = 1;
+
+ /* Add special queues */
+ bp->num_cnic_queues = CNIC_SUPPORT(bp); /* For FCOE */
+ bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
+
+ BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues);
+}
+
+/**
+ * bnx2x_set_real_num_queues - configure netdev->real_num_[tx,rx]_queues
+ *
+ * @bp: Driver handle
+ *
+ * We currently support for at most 16 Tx queues for each CoS thus we will
+ * allocate a multiple of 16 for ETH L2 rings according to the value of the
+ * bp->max_cos.
+ *
+ * If there is an FCoE L2 queue the appropriate Tx queue will have the next
+ * index after all ETH L2 indices.
+ *
+ * If the actual number of Tx queues (for each CoS) is less than 16 then there
+ * will be the holes at the end of each group of 16 ETh L2 indices (0..15,
+ * 16..31,...) with indices that are not coupled with any real Tx queue.
+ *
+ * The proper configuration of skb->queue_mapping is handled by
+ * bnx2x_select_queue() and __skb_tx_hash().
+ *
+ * bnx2x_setup_tc() takes care of the proper TC mappings so that __skb_tx_hash()
+ * will return a proper Tx index if TC is enabled (netdev->num_tc > 0).
+ */
+static int bnx2x_set_real_num_queues(struct bnx2x *bp, int include_cnic)
+{
+ int rc, tx, rx;
+
+ tx = BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos;
+ rx = BNX2X_NUM_ETH_QUEUES(bp);
+
+/* account for fcoe queue */
+ if (include_cnic && !NO_FCOE(bp)) {
+ rx++;
+ tx++;
+ }
+
+ rc = netif_set_real_num_tx_queues(bp->dev, tx);
+ if (rc) {
+ BNX2X_ERR("Failed to set real number of Tx queues: %d\n", rc);
+ return rc;
+ }
+ rc = netif_set_real_num_rx_queues(bp->dev, rx);
+ if (rc) {
+ BNX2X_ERR("Failed to set real number of Rx queues: %d\n", rc);
+ return rc;
+ }
+
+ DP(NETIF_MSG_IFUP, "Setting real num queues to (tx, rx) (%d, %d)\n",
+ tx, rx);
+
+ return rc;
+}
+
+static void bnx2x_set_rx_buf_size(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ u32 mtu;
+
+ /* Always use a mini-jumbo MTU for the FCoE L2 ring */
+ if (IS_FCOE_IDX(i))
+ /*
+ * Although there are no IP frames expected to arrive to
+ * this ring we still want to add an
+ * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer
+ * overrun attack.
+ */
+ mtu = BNX2X_FCOE_MINI_JUMBO_MTU;
+ else
+ mtu = bp->dev->mtu;
+ fp->rx_buf_size = BNX2X_FW_RX_ALIGN_START +
+ IP_HEADER_ALIGNMENT_PADDING +
+ ETH_OVREHEAD +
+ mtu +
+ BNX2X_FW_RX_ALIGN_END;
+ /* Note : rx_buf_size doesn't take into account NET_SKB_PAD */
+ if (fp->rx_buf_size + NET_SKB_PAD <= PAGE_SIZE)
+ fp->rx_frag_size = fp->rx_buf_size + NET_SKB_PAD;
+ else
+ fp->rx_frag_size = 0;
+ }
+}
+
+static int bnx2x_init_rss(struct bnx2x *bp)
+{
+ int i;
+ u8 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp);
+
+ /* Prepare the initial contents for the indirection table if RSS is
+ * enabled
+ */
+ for (i = 0; i < sizeof(bp->rss_conf_obj.ind_table); i++)
+ bp->rss_conf_obj.ind_table[i] =
+ bp->fp->cl_id +
+ ethtool_rxfh_indir_default(i, num_eth_queues);
+
+ /*
+ * For 57710 and 57711 SEARCHER configuration (rss_keys) is
+ * per-port, so if explicit configuration is needed , do it only
+ * for a PMF.
+ *
+ * For 57712 and newer on the other hand it's a per-function
+ * configuration.
+ */
+ return bnx2x_config_rss_eth(bp, bp->port.pmf || !CHIP_IS_E1x(bp));
+}
+
+int bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
+ bool config_hash, bool enable)
+{
+ struct bnx2x_config_rss_params params = {NULL};
+
+ /* Although RSS is meaningless when there is a single HW queue we
+ * still need it enabled in order to have HW Rx hash generated.
+ *
+ * if (!is_eth_multi(bp))
+ * bp->multi_mode = ETH_RSS_MODE_DISABLED;
+ */
+
+ params.rss_obj = rss_obj;
+
+ __set_bit(RAMROD_COMP_WAIT, &params.ramrod_flags);
+
+ if (enable) {
+ __set_bit(BNX2X_RSS_MODE_REGULAR, &params.rss_flags);
+
+ /* RSS configuration */
+ __set_bit(BNX2X_RSS_IPV4, &params.rss_flags);
+ __set_bit(BNX2X_RSS_IPV4_TCP, &params.rss_flags);
+ __set_bit(BNX2X_RSS_IPV6, &params.rss_flags);
+ __set_bit(BNX2X_RSS_IPV6_TCP, &params.rss_flags);
+ if (rss_obj->udp_rss_v4)
+ __set_bit(BNX2X_RSS_IPV4_UDP, &params.rss_flags);
+ if (rss_obj->udp_rss_v6)
+ __set_bit(BNX2X_RSS_IPV6_UDP, &params.rss_flags);
+ } else {
+ __set_bit(BNX2X_RSS_MODE_DISABLED, &params.rss_flags);
+ }
+
+ /* Hash bits */
+ params.rss_result_mask = MULTI_MASK;
+
+ memcpy(params.ind_table, rss_obj->ind_table, sizeof(params.ind_table));
+
+ if (config_hash) {
+ /* RSS keys */
+ prandom_bytes(params.rss_key, T_ETH_RSS_KEY * 4);
+ __set_bit(BNX2X_RSS_SET_SRCH, &params.rss_flags);
+ }
+
+ if (IS_PF(bp))
+ return bnx2x_config_rss(bp, &params);
+ else
+ return bnx2x_vfpf_config_rss(bp, &params);
+}
+
+static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
+{
+ struct bnx2x_func_state_params func_params = {NULL};
+
+ /* Prepare parameters for function state transitions */
+ __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
+
+ func_params.f_obj = &bp->func_obj;
+ func_params.cmd = BNX2X_F_CMD_HW_INIT;
+
+ func_params.params.hw_init.load_phase = load_code;
+
+ return bnx2x_func_state_change(bp, &func_params);
+}
+
+/*
+ * Cleans the object that have internal lists without sending
+ * ramrods. Should be run when interrupts are disabled.
+ */
+void bnx2x_squeeze_objects(struct bnx2x *bp)
+{
+ int rc;
+ unsigned long ramrod_flags = 0, vlan_mac_flags = 0;
+ struct bnx2x_mcast_ramrod_params rparam = {NULL};
+ struct bnx2x_vlan_mac_obj *mac_obj = &bp->sp_objs->mac_obj;
+
+ /***************** Cleanup MACs' object first *************************/
+
+ /* Wait for completion of requested */
+ __set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
+ /* Perform a dry cleanup */
+ __set_bit(RAMROD_DRV_CLR_ONLY, &ramrod_flags);
+
+ /* Clean ETH primary MAC */
+ __set_bit(BNX2X_ETH_MAC, &vlan_mac_flags);
+ rc = mac_obj->delete_all(bp, &bp->sp_objs->mac_obj, &vlan_mac_flags,
+ &ramrod_flags);
+ if (rc != 0)
+ BNX2X_ERR("Failed to clean ETH MACs: %d\n", rc);
+
+ /* Cleanup UC list */
+ vlan_mac_flags = 0;
+ __set_bit(BNX2X_UC_LIST_MAC, &vlan_mac_flags);
+ rc = mac_obj->delete_all(bp, mac_obj, &vlan_mac_flags,
+ &ramrod_flags);
+ if (rc != 0)
+ BNX2X_ERR("Failed to clean UC list MACs: %d\n", rc);
+
+ /***************** Now clean mcast object *****************************/
+ rparam.mcast_obj = &bp->mcast_obj;
+ __set_bit(RAMROD_DRV_CLR_ONLY, &rparam.ramrod_flags);
+
+ /* Add a DEL command... - Since we're doing a driver cleanup only,
+ * we take a lock surrounding both the initial send and the CONTs,
+ * as we don't want a true completion to disrupt us in the middle.
+ */
+ netif_addr_lock_bh(bp->dev);
+ rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_DEL);
+ if (rc < 0)
+ BNX2X_ERR("Failed to add a new DEL command to a multi-cast object: %d\n",
+ rc);
+
+ /* ...and wait until all pending commands are cleared */
+ rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_CONT);
+ while (rc != 0) {
+ if (rc < 0) {
+ BNX2X_ERR("Failed to clean multi-cast object: %d\n",
+ rc);
+ netif_addr_unlock_bh(bp->dev);
+ return;
+ }
+
+ rc = bnx2x_config_mcast(bp, &rparam, BNX2X_MCAST_CMD_CONT);
+ }
+ netif_addr_unlock_bh(bp->dev);
+}
+
+#ifndef BNX2X_STOP_ON_ERROR
+#define LOAD_ERROR_EXIT(bp, label) \
+ do { \
+ (bp)->state = BNX2X_STATE_ERROR; \
+ goto label; \
+ } while (0)
+
+#define LOAD_ERROR_EXIT_CNIC(bp, label) \
+ do { \
+ bp->cnic_loaded = false; \
+ goto label; \
+ } while (0)
+#else /*BNX2X_STOP_ON_ERROR*/
+#define LOAD_ERROR_EXIT(bp, label) \
+ do { \
+ (bp)->state = BNX2X_STATE_ERROR; \
+ (bp)->panic = 1; \
+ return -EBUSY; \
+ } while (0)
+#define LOAD_ERROR_EXIT_CNIC(bp, label) \
+ do { \
+ bp->cnic_loaded = false; \
+ (bp)->panic = 1; \
+ return -EBUSY; \
+ } while (0)
+#endif /*BNX2X_STOP_ON_ERROR*/
+
+static void bnx2x_free_fw_stats_mem(struct bnx2x *bp)
+{
+ BNX2X_PCI_FREE(bp->fw_stats, bp->fw_stats_mapping,
+ bp->fw_stats_data_sz + bp->fw_stats_req_sz);
+ return;
+}
+
+static int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp)
+{
+ int num_groups, vf_headroom = 0;
+ int is_fcoe_stats = NO_FCOE(bp) ? 0 : 1;
+
+ /* number of queues for statistics is number of eth queues + FCoE */
+ u8 num_queue_stats = BNX2X_NUM_ETH_QUEUES(bp) + is_fcoe_stats;
+
+ /* Total number of FW statistics requests =
+ * 1 for port stats + 1 for PF stats + potential 2 for FCoE (fcoe proper
+ * and fcoe l2 queue) stats + num of queues (which includes another 1
+ * for fcoe l2 queue if applicable)
+ */
+ bp->fw_stats_num = 2 + is_fcoe_stats + num_queue_stats;
+
+ /* vf stats appear in the request list, but their data is allocated by
+ * the VFs themselves. We don't include them in the bp->fw_stats_num as
+ * it is used to determine where to place the vf stats queries in the
+ * request struct
+ */
+ if (IS_SRIOV(bp))
+ vf_headroom = bnx2x_vf_headroom(bp);
+
+ /* Request is built from stats_query_header and an array of
+ * stats_query_cmd_group each of which contains
+ * STATS_QUERY_CMD_COUNT rules. The real number or requests is
+ * configured in the stats_query_header.
+ */
+ num_groups =
+ (((bp->fw_stats_num + vf_headroom) / STATS_QUERY_CMD_COUNT) +
+ (((bp->fw_stats_num + vf_headroom) % STATS_QUERY_CMD_COUNT) ?
+ 1 : 0));
+
+ DP(BNX2X_MSG_SP, "stats fw_stats_num %d, vf headroom %d, num_groups %d\n",
+ bp->fw_stats_num, vf_headroom, num_groups);
+ bp->fw_stats_req_sz = sizeof(struct stats_query_header) +
+ num_groups * sizeof(struct stats_query_cmd_group);
+
+ /* Data for statistics requests + stats_counter
+ * stats_counter holds per-STORM counters that are incremented
+ * when STORM has finished with the current request.
+ * memory for FCoE offloaded statistics are counted anyway,
+ * even if they will not be sent.
+ * VF stats are not accounted for here as the data of VF stats is stored
+ * in memory allocated by the VF, not here.
+ */
+ bp->fw_stats_data_sz = sizeof(struct per_port_stats) +
+ sizeof(struct per_pf_stats) +
+ sizeof(struct fcoe_statistics_params) +
+ sizeof(struct per_queue_stats) * num_queue_stats +
+ sizeof(struct stats_counter);
+
+ bp->fw_stats = BNX2X_PCI_ALLOC(&bp->fw_stats_mapping,
+ bp->fw_stats_data_sz + bp->fw_stats_req_sz);
+ if (!bp->fw_stats)
+ goto alloc_mem_err;
+
+ /* Set shortcuts */
+ bp->fw_stats_req = (struct bnx2x_fw_stats_req *)bp->fw_stats;
+ bp->fw_stats_req_mapping = bp->fw_stats_mapping;
+ bp->fw_stats_data = (struct bnx2x_fw_stats_data *)
+ ((u8 *)bp->fw_stats + bp->fw_stats_req_sz);
+ bp->fw_stats_data_mapping = bp->fw_stats_mapping +
+ bp->fw_stats_req_sz;
+
+ DP(BNX2X_MSG_SP, "statistics request base address set to %x %x\n",
+ U64_HI(bp->fw_stats_req_mapping),
+ U64_LO(bp->fw_stats_req_mapping));
+ DP(BNX2X_MSG_SP, "statistics data base address set to %x %x\n",
+ U64_HI(bp->fw_stats_data_mapping),
+ U64_LO(bp->fw_stats_data_mapping));
+ return 0;
+
+alloc_mem_err:
+ bnx2x_free_fw_stats_mem(bp);
+ BNX2X_ERR("Can't allocate FW stats memory\n");
+ return -ENOMEM;
+}
+
+/* send load request to mcp and analyze response */
+static int bnx2x_nic_load_request(struct bnx2x *bp, u32 *load_code)
+{
+ u32 param;
+
+ /* init fw_seq */
+ bp->fw_seq =
+ (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
+ DRV_MSG_SEQ_NUMBER_MASK);
+ BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
+
+ /* Get current FW pulse sequence */
+ bp->fw_drv_pulse_wr_seq =
+ (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb) &
+ DRV_PULSE_SEQ_MASK);
+ BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq);
+
+ param = DRV_MSG_CODE_LOAD_REQ_WITH_LFA;
+
+ if (IS_MF_SD(bp) && bnx2x_port_after_undi(bp))
+ param |= DRV_MSG_CODE_LOAD_REQ_FORCE_LFA;
+
+ /* load request */
+ (*load_code) = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, param);
+
+ /* if mcp fails to respond we must abort */
+ if (!(*load_code)) {
+ BNX2X_ERR("MCP response failure, aborting\n");
+ return -EBUSY;
+ }
+
+ /* If mcp refused (e.g. other port is in diagnostic mode) we
+ * must abort
+ */
+ if ((*load_code) == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+ BNX2X_ERR("MCP refused load request, aborting\n");
+ return -EBUSY;
+ }
+ return 0;
+}
+
+/* check whether another PF has already loaded FW to chip. In
+ * virtualized environments a pf from another VM may have already
+ * initialized the device including loading FW
+ */
+int bnx2x_compare_fw_ver(struct bnx2x *bp, u32 load_code, bool print_err)
+{
+ /* is another pf loaded on this engine? */
+ if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP &&
+ load_code != FW_MSG_CODE_DRV_LOAD_COMMON) {
+ /* build my FW version dword */
+ u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) +
+ (BCM_5710_FW_MINOR_VERSION << 8) +
+ (BCM_5710_FW_REVISION_VERSION << 16) +
+ (BCM_5710_FW_ENGINEERING_VERSION << 24);
+
+ /* read loaded FW from chip */
+ u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
+
+ DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x\n",
+ loaded_fw, my_fw);
+
+ /* abort nic load if version mismatch */
+ if (my_fw != loaded_fw) {
+ if (print_err)
+ BNX2X_ERR("bnx2x with FW %x was already loaded which mismatches my %x FW. Aborting\n",
+ loaded_fw, my_fw);
+ else
+ BNX2X_DEV_INFO("bnx2x with FW %x was already loaded which mismatches my %x FW, possibly due to MF UNDI\n",
+ loaded_fw, my_fw);
+ return -EBUSY;
+ }
+ }
+ return 0;
+}
+
+/* returns the "mcp load_code" according to global load_count array */
+static int bnx2x_nic_load_no_mcp(struct bnx2x *bp, int port)
+{
+ int path = BP_PATH(bp);
+
+ DP(NETIF_MSG_IFUP, "NO MCP - load counts[%d] %d, %d, %d\n",
+ path, bnx2x_load_count[path][0], bnx2x_load_count[path][1],
+ bnx2x_load_count[path][2]);
+ bnx2x_load_count[path][0]++;
+ bnx2x_load_count[path][1 + port]++;
+ DP(NETIF_MSG_IFUP, "NO MCP - new load counts[%d] %d, %d, %d\n",
+ path, bnx2x_load_count[path][0], bnx2x_load_count[path][1],
+ bnx2x_load_count[path][2]);
+ if (bnx2x_load_count[path][0] == 1)
+ return FW_MSG_CODE_DRV_LOAD_COMMON;
+ else if (bnx2x_load_count[path][1 + port] == 1)
+ return FW_MSG_CODE_DRV_LOAD_PORT;
+ else
+ return FW_MSG_CODE_DRV_LOAD_FUNCTION;
+}
+
+/* mark PMF if applicable */
+static void bnx2x_nic_load_pmf(struct bnx2x *bp, u32 load_code)
+{
+ if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) {
+ bp->port.pmf = 1;
+ /* We need the barrier to ensure the ordering between the
+ * writing to bp->port.pmf here and reading it from the
+ * bnx2x_periodic_task().
+ */
+ smp_mb();
+ } else {
+ bp->port.pmf = 0;
+ }
+
+ DP(NETIF_MSG_LINK, "pmf %d\n", bp->port.pmf);
+}
+
+static void bnx2x_nic_load_afex_dcc(struct bnx2x *bp, int load_code)
+{
+ if (((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) ||
+ (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP)) &&
+ (bp->common.shmem2_base)) {
+ if (SHMEM2_HAS(bp, dcc_support))
+ SHMEM2_WR(bp, dcc_support,
+ (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV |
+ SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV));
+ if (SHMEM2_HAS(bp, afex_driver_support))
+ SHMEM2_WR(bp, afex_driver_support,
+ SHMEM_AFEX_SUPPORTED_VERSION_ONE);
+ }
+
+ /* Set AFEX default VLAN tag to an invalid value */
+ bp->afex_def_vlan_tag = -1;
+}
+
+/**
+ * bnx2x_bz_fp - zero content of the fastpath structure.
+ *
+ * @bp: driver handle
+ * @index: fastpath index to be zeroed
+ *
+ * Makes sure the contents of the bp->fp[index].napi is kept
+ * intact.
+ */
+static void bnx2x_bz_fp(struct bnx2x *bp, int index)
+{
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+ int cos;
+ struct napi_struct orig_napi = fp->napi;
+ struct bnx2x_agg_info *orig_tpa_info = fp->tpa_info;
+
+ /* bzero bnx2x_fastpath contents */
+ if (fp->tpa_info)
+ memset(fp->tpa_info, 0, ETH_MAX_AGGREGATION_QUEUES_E1H_E2 *
+ sizeof(struct bnx2x_agg_info));
+ memset(fp, 0, sizeof(*fp));
+
+ /* Restore the NAPI object as it has been already initialized */
+ fp->napi = orig_napi;
+ fp->tpa_info = orig_tpa_info;
+ fp->bp = bp;
+ fp->index = index;
+ if (IS_ETH_FP(fp))
+ fp->max_cos = bp->max_cos;
+ else
+ /* Special queues support only one CoS */
+ fp->max_cos = 1;
+
+ /* Init txdata pointers */
+ if (IS_FCOE_FP(fp))
+ fp->txdata_ptr[0] = &bp->bnx2x_txq[FCOE_TXQ_IDX(bp)];
+ if (IS_ETH_FP(fp))
+ for_each_cos_in_tx_queue(fp, cos)
+ fp->txdata_ptr[cos] = &bp->bnx2x_txq[cos *
+ BNX2X_NUM_ETH_QUEUES(bp) + index];
+
+ /* set the tpa flag for each queue. The tpa flag determines the queue
+ * minimal size so it must be set prior to queue memory allocation
+ */
+ fp->disable_tpa = !(bp->flags & TPA_ENABLE_FLAG ||
+ (bp->flags & GRO_ENABLE_FLAG &&
+ bnx2x_mtu_allows_gro(bp->dev->mtu)));
+ if (bp->flags & TPA_ENABLE_FLAG)
+ fp->mode = TPA_MODE_LRO;
+ else if (bp->flags & GRO_ENABLE_FLAG)
+ fp->mode = TPA_MODE_GRO;
+
+ /* We don't want TPA on an FCoE L2 ring */
+ if (IS_FCOE_FP(fp))
+ fp->disable_tpa = 1;
+}
+
+int bnx2x_load_cnic(struct bnx2x *bp)
+{
+ int i, rc, port = BP_PORT(bp);
+
+ DP(NETIF_MSG_IFUP, "Starting CNIC-related load\n");
+
+ mutex_init(&bp->cnic_mutex);
+
+ if (IS_PF(bp)) {
+ rc = bnx2x_alloc_mem_cnic(bp);
+ if (rc) {
+ BNX2X_ERR("Unable to allocate bp memory for cnic\n");
+ LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic0);
+ }
+ }
+
+ rc = bnx2x_alloc_fp_mem_cnic(bp);
+ if (rc) {
+ BNX2X_ERR("Unable to allocate memory for cnic fps\n");
+ LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic0);
+ }
+
+ /* Update the number of queues with the cnic queues */
+ rc = bnx2x_set_real_num_queues(bp, 1);
+ if (rc) {
+ BNX2X_ERR("Unable to set real_num_queues including cnic\n");
+ LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic0);
+ }
+
+ /* Add all CNIC NAPI objects */
+ bnx2x_add_all_napi_cnic(bp);
+ DP(NETIF_MSG_IFUP, "cnic napi added\n");
+ bnx2x_napi_enable_cnic(bp);
+
+ rc = bnx2x_init_hw_func_cnic(bp);
+ if (rc)
+ LOAD_ERROR_EXIT_CNIC(bp, load_error_cnic1);
+
+ bnx2x_nic_init_cnic(bp);
+
+ if (IS_PF(bp)) {
+ /* Enable Timer scan */
+ REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 1);
+
+ /* setup cnic queues */
+ for_each_cnic_queue(bp, i) {
+ rc = bnx2x_setup_queue(bp, &bp->fp[i], 0);
+ if (rc) {
+ BNX2X_ERR("Queue setup failed\n");
+ LOAD_ERROR_EXIT(bp, load_error_cnic2);
+ }
+ }
+ }
+
+ /* Initialize Rx filter. */
+ bnx2x_set_rx_mode_inner(bp);
+
+ /* re-read iscsi info */
+ bnx2x_get_iscsi_info(bp);
+ bnx2x_setup_cnic_irq_info(bp);
+ bnx2x_setup_cnic_info(bp);
+ bp->cnic_loaded = true;
+ if (bp->state == BNX2X_STATE_OPEN)
+ bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD);
+
+ DP(NETIF_MSG_IFUP, "Ending successfully CNIC-related load\n");
+
+ return 0;
+
+#ifndef BNX2X_STOP_ON_ERROR
+load_error_cnic2:
+ /* Disable Timer scan */
+ REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + port*4, 0);
+
+load_error_cnic1:
+ bnx2x_napi_disable_cnic(bp);
+ /* Update the number of queues without the cnic queues */
+ if (bnx2x_set_real_num_queues(bp, 0))
+ BNX2X_ERR("Unable to set real_num_queues not including cnic\n");
+load_error_cnic0:
+ BNX2X_ERR("CNIC-related load failed\n");
+ bnx2x_free_fp_mem_cnic(bp);
+ bnx2x_free_mem_cnic(bp);
+ return rc;
+#endif /* ! BNX2X_STOP_ON_ERROR */
+}
+
+/* must be called with rtnl_lock */
+int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
+{
+ int port = BP_PORT(bp);
+ int i, rc = 0, load_code = 0;
+
+ DP(NETIF_MSG_IFUP, "Starting NIC load\n");
+ DP(NETIF_MSG_IFUP,
+ "CNIC is %s\n", CNIC_ENABLED(bp) ? "enabled" : "disabled");
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic)) {
+ BNX2X_ERR("Can't load NIC when there is panic\n");
+ return -EPERM;
+ }
+#endif
+
+ bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
+
+ /* zero the structure w/o any lock, before SP handler is initialized */
+ memset(&bp->last_reported_link, 0, sizeof(bp->last_reported_link));
+ __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+ &bp->last_reported_link.link_report_flags);
+
+ if (IS_PF(bp))
+ /* must be called before memory allocation and HW init */
+ bnx2x_ilt_set_info(bp);
+
+ /*
+ * Zero fastpath structures preserving invariants like napi, which are
+ * allocated only once, fp index, max_cos, bp pointer.
+ * Also set fp->disable_tpa and txdata_ptr.
+ */
+ DP(NETIF_MSG_IFUP, "num queues: %d", bp->num_queues);
+ for_each_queue(bp, i)
+ bnx2x_bz_fp(bp, i);
+ memset(bp->bnx2x_txq, 0, (BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS +
+ bp->num_cnic_queues) *
+ sizeof(struct bnx2x_fp_txdata));
+
+ bp->fcoe_init = false;
+
+ /* Set the receive queues buffer size */
+ bnx2x_set_rx_buf_size(bp);
+
+ if (IS_PF(bp)) {
+ rc = bnx2x_alloc_mem(bp);
+ if (rc) {
+ BNX2X_ERR("Unable to allocate bp memory\n");
+ return rc;
+ }
+ }
+
+ /* need to be done after alloc mem, since it's self adjusting to amount
+ * of memory available for RSS queues
+ */
+ rc = bnx2x_alloc_fp_mem(bp);
+ if (rc) {
+ BNX2X_ERR("Unable to allocate memory for fps\n");
+ LOAD_ERROR_EXIT(bp, load_error0);
+ }
+
+ /* Allocated memory for FW statistics */
+ if (bnx2x_alloc_fw_stats_mem(bp))
+ LOAD_ERROR_EXIT(bp, load_error0);
+
+ /* request pf to initialize status blocks */
+ if (IS_VF(bp)) {
+ rc = bnx2x_vfpf_init(bp);
+ if (rc)
+ LOAD_ERROR_EXIT(bp, load_error0);
+ }
+
+ /* As long as bnx2x_alloc_mem() may possibly update
+ * bp->num_queues, bnx2x_set_real_num_queues() should always
+ * come after it. At this stage cnic queues are not counted.
+ */
+ rc = bnx2x_set_real_num_queues(bp, 0);
+ if (rc) {
+ BNX2X_ERR("Unable to set real_num_queues\n");
+ LOAD_ERROR_EXIT(bp, load_error0);
+ }
+
+ /* configure multi cos mappings in kernel.
+ * this configuration may be overridden by a multi class queue
+ * discipline or by a dcbx negotiation result.
+ */
+ bnx2x_setup_tc(bp->dev, bp->max_cos);
+
+ /* Add all NAPI objects */
+ bnx2x_add_all_napi(bp);
+ DP(NETIF_MSG_IFUP, "napi added\n");
+ bnx2x_napi_enable(bp);
+
+ if (IS_PF(bp)) {
+ /* set pf load just before approaching the MCP */
+ bnx2x_set_pf_load(bp);
+
+ /* if mcp exists send load request and analyze response */
+ if (!BP_NOMCP(bp)) {
+ /* attempt to load pf */
+ rc = bnx2x_nic_load_request(bp, &load_code);
+ if (rc)
+ LOAD_ERROR_EXIT(bp, load_error1);
+
+ /* what did mcp say? */
+ rc = bnx2x_compare_fw_ver(bp, load_code, true);
+ if (rc) {
+ bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
+ LOAD_ERROR_EXIT(bp, load_error2);
+ }
+ } else {
+ load_code = bnx2x_nic_load_no_mcp(bp, port);
+ }
+
+ /* mark pmf if applicable */
+ bnx2x_nic_load_pmf(bp, load_code);
+
+ /* Init Function state controlling object */
+ bnx2x__init_func_obj(bp);
+
+ /* Initialize HW */
+ rc = bnx2x_init_hw(bp, load_code);
+ if (rc) {
+ BNX2X_ERR("HW init failed, aborting\n");
+ bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
+ LOAD_ERROR_EXIT(bp, load_error2);
+ }
+ }
+
+ bnx2x_pre_irq_nic_init(bp);
+
+ /* Connect to IRQs */
+ rc = bnx2x_setup_irqs(bp);
+ if (rc) {
+ BNX2X_ERR("setup irqs failed\n");
+ if (IS_PF(bp))
+ bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
+ LOAD_ERROR_EXIT(bp, load_error2);
+ }
+
+ /* Init per-function objects */
+ if (IS_PF(bp)) {
+ /* Setup NIC internals and enable interrupts */
+ bnx2x_post_irq_nic_init(bp, load_code);
+
+ bnx2x_init_bp_objs(bp);
+ bnx2x_iov_nic_init(bp);
+
+ /* Set AFEX default VLAN tag to an invalid value */
+ bp->afex_def_vlan_tag = -1;
+ bnx2x_nic_load_afex_dcc(bp, load_code);
+ bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
+ rc = bnx2x_func_start(bp);
+ if (rc) {
+ BNX2X_ERR("Function start failed!\n");
+ bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
+
+ LOAD_ERROR_EXIT(bp, load_error3);
+ }
+
+ /* Send LOAD_DONE command to MCP */
+ if (!BP_NOMCP(bp)) {
+ load_code = bnx2x_fw_command(bp,
+ DRV_MSG_CODE_LOAD_DONE, 0);
+ if (!load_code) {
+ BNX2X_ERR("MCP response failure, aborting\n");
+ rc = -EBUSY;
+ LOAD_ERROR_EXIT(bp, load_error3);
+ }
+ }
+
+ /* initialize FW coalescing state machines in RAM */
+ bnx2x_update_coalesce(bp);
+ }
+
+ /* setup the leading queue */
+ rc = bnx2x_setup_leading(bp);
+ if (rc) {
+ BNX2X_ERR("Setup leading failed!\n");
+ LOAD_ERROR_EXIT(bp, load_error3);
+ }
+
+ /* set up the rest of the queues */
+ for_each_nondefault_eth_queue(bp, i) {
+ if (IS_PF(bp))
+ rc = bnx2x_setup_queue(bp, &bp->fp[i], false);
+ else /* VF */
+ rc = bnx2x_vfpf_setup_q(bp, &bp->fp[i], false);
+ if (rc) {
+ BNX2X_ERR("Queue %d setup failed\n", i);
+ LOAD_ERROR_EXIT(bp, load_error3);
+ }
+ }
+
+ /* setup rss */
+ rc = bnx2x_init_rss(bp);
+ if (rc) {
+ BNX2X_ERR("PF RSS init failed\n");
+ LOAD_ERROR_EXIT(bp, load_error3);
+ }
+
+ /* Now when Clients are configured we are ready to work */
+ bp->state = BNX2X_STATE_OPEN;
+
+ /* Configure a ucast MAC */
+ if (IS_PF(bp))
+ rc = bnx2x_set_eth_mac(bp, true);
+ else /* vf */
+ rc = bnx2x_vfpf_config_mac(bp, bp->dev->dev_addr, bp->fp->index,
+ true);
+ if (rc) {
+ BNX2X_ERR("Setting Ethernet MAC failed\n");
+ LOAD_ERROR_EXIT(bp, load_error3);
+ }
+
+ if (IS_PF(bp) && bp->pending_max) {
+ bnx2x_update_max_mf_config(bp, bp->pending_max);
+ bp->pending_max = 0;
+ }
+
+ if (bp->port.pmf) {
+ rc = bnx2x_initial_phy_init(bp, load_mode);
+ if (rc)
+ LOAD_ERROR_EXIT(bp, load_error3);
+ }
+ bp->link_params.feature_config_flags &= ~FEATURE_CONFIG_BOOT_FROM_SAN;
+
+ /* Start fast path */
+
+ /* Initialize Rx filter. */
+ bnx2x_set_rx_mode_inner(bp);
+
+ /* Start the Tx */
+ switch (load_mode) {
+ case LOAD_NORMAL:
+ /* Tx queue should be only re-enabled */
+ netif_tx_wake_all_queues(bp->dev);
+ break;
+
+ case LOAD_OPEN:
+ netif_tx_start_all_queues(bp->dev);
+ smp_mb__after_atomic();
+ break;
+
+ case LOAD_DIAG:
+ case LOAD_LOOPBACK_EXT:
+ bp->state = BNX2X_STATE_DIAG;
+ break;
+
+ default:
+ break;
+ }
+
+ if (bp->port.pmf)
+ bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_PORT_MASK, 0);
+ else
+ bnx2x__link_status_update(bp);
+
+ /* start the timer */
+ mod_timer(&bp->timer, jiffies + bp->current_interval);
+
+ if (CNIC_ENABLED(bp))
+ bnx2x_load_cnic(bp);
+
+ if (IS_PF(bp))
+ bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_GET_DRV_VERSION, 0);
+
+ if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
+ /* mark driver is loaded in shmem2 */
+ u32 val;
+ val = SHMEM2_RD(bp, drv_capabilities_flag[BP_FW_MB_IDX(bp)]);
+ SHMEM2_WR(bp, drv_capabilities_flag[BP_FW_MB_IDX(bp)],
+ val | DRV_FLAGS_CAPABILITIES_LOADED_SUPPORTED |
+ DRV_FLAGS_CAPABILITIES_LOADED_L2);
+ }
+
+ /* Wait for all pending SP commands to complete */
+ if (IS_PF(bp) && !bnx2x_wait_sp_comp(bp, ~0x0UL)) {
+ BNX2X_ERR("Timeout waiting for SP elements to complete\n");
+ bnx2x_nic_unload(bp, UNLOAD_CLOSE, false);
+ return -EBUSY;
+ }
+
+ /* If PMF - send ADMIN DCBX msg to MFW to initiate DCBX FSM */
+ if (bp->port.pmf && (bp->state != BNX2X_STATE_DIAG))
+ bnx2x_dcbx_init(bp, false);
+
+ DP(NETIF_MSG_IFUP, "Ending successfully NIC load\n");
+
+ return 0;
+
+#ifndef BNX2X_STOP_ON_ERROR
+load_error3:
+ if (IS_PF(bp)) {
+ bnx2x_int_disable_sync(bp, 1);
+
+ /* Clean queueable objects */
+ bnx2x_squeeze_objects(bp);
+ }
+
+ /* Free SKBs, SGEs, TPA pool and driver internals */
+ bnx2x_free_skbs(bp);
+ for_each_rx_queue(bp, i)
+ bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+load_error2:
+ if (IS_PF(bp) && !BP_NOMCP(bp)) {
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0);
+ bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
+ }
+
+ bp->port.pmf = 0;
+load_error1:
+ bnx2x_napi_disable(bp);
+ bnx2x_del_all_napi(bp);
+
+ /* clear pf_load status, as it was already set */
+ if (IS_PF(bp))
+ bnx2x_clear_pf_load(bp);
+load_error0:
+ bnx2x_free_fw_stats_mem(bp);
+ bnx2x_free_fp_mem(bp);
+ bnx2x_free_mem(bp);
+
+ return rc;
+#endif /* ! BNX2X_STOP_ON_ERROR */
+}
+
+int bnx2x_drain_tx_queues(struct bnx2x *bp)
+{
+ u8 rc = 0, cos, i;
+
+ /* Wait until tx fastpath tasks complete */
+ for_each_tx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ for_each_cos_in_tx_queue(fp, cos)
+ rc = bnx2x_clean_tx_queue(bp, fp->txdata_ptr[cos]);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+/* must be called with rtnl_lock */
+int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
+{
+ int i;
+ bool global = false;
+
+ DP(NETIF_MSG_IFUP, "Starting NIC unload\n");
+
+ /* mark driver is unloaded in shmem2 */
+ if (IS_PF(bp) && SHMEM2_HAS(bp, drv_capabilities_flag)) {
+ u32 val;
+ val = SHMEM2_RD(bp, drv_capabilities_flag[BP_FW_MB_IDX(bp)]);
+ SHMEM2_WR(bp, drv_capabilities_flag[BP_FW_MB_IDX(bp)],
+ val & ~DRV_FLAGS_CAPABILITIES_LOADED_L2);
+ }
+
+ if (IS_PF(bp) && bp->recovery_state != BNX2X_RECOVERY_DONE &&
+ (bp->state == BNX2X_STATE_CLOSED ||
+ bp->state == BNX2X_STATE_ERROR)) {
+ /* We can get here if the driver has been unloaded
+ * during parity error recovery and is either waiting for a
+ * leader to complete or for other functions to unload and
+ * then ifdown has been issued. In this case we want to
+ * unload and let other functions to complete a recovery
+ * process.
+ */
+ bp->recovery_state = BNX2X_RECOVERY_DONE;
+ bp->is_leader = 0;
+ bnx2x_release_leader_lock(bp);
+ smp_mb();
+
+ DP(NETIF_MSG_IFDOWN, "Releasing a leadership...\n");
+ BNX2X_ERR("Can't unload in closed or error state\n");
+ return -EINVAL;
+ }
+
+ /* Nothing to do during unload if previous bnx2x_nic_load()
+ * have not completed successfully - all resources are released.
+ *
+ * we can get here only after unsuccessful ndo_* callback, during which
+ * dev->IFF_UP flag is still on.
+ */
+ if (bp->state == BNX2X_STATE_CLOSED || bp->state == BNX2X_STATE_ERROR)
+ return 0;
+
+ /* It's important to set the bp->state to the value different from
+ * BNX2X_STATE_OPEN and only then stop the Tx. Otherwise bnx2x_tx_int()
+ * may restart the Tx from the NAPI context (see bnx2x_tx_int()).
+ */
+ bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
+ smp_mb();
+
+ /* indicate to VFs that the PF is going down */
+ bnx2x_iov_channel_down(bp);
+
+ if (CNIC_LOADED(bp))
+ bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
+
+ /* Stop Tx */
+ bnx2x_tx_disable(bp);
+ netdev_reset_tc(bp->dev);
+
+ bp->rx_mode = BNX2X_RX_MODE_NONE;
+
+ del_timer_sync(&bp->timer);
+
+ if (IS_PF(bp)) {
+ /* Set ALWAYS_ALIVE bit in shmem */
+ bp->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
+ bnx2x_drv_pulse(bp);
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_save_statistics(bp);
+ }
+
+ /* wait till consumers catch up with producers in all queues */
+ bnx2x_drain_tx_queues(bp);
+
+ /* if VF indicate to PF this function is going down (PF will delete sp
+ * elements and clear initializations
+ */
+ if (IS_VF(bp))
+ bnx2x_vfpf_close_vf(bp);
+ else if (unload_mode != UNLOAD_RECOVERY)
+ /* if this is a normal/close unload need to clean up chip*/
+ bnx2x_chip_cleanup(bp, unload_mode, keep_link);
+ else {
+ /* Send the UNLOAD_REQUEST to the MCP */
+ bnx2x_send_unload_req(bp, unload_mode);
+
+ /* Prevent transactions to host from the functions on the
+ * engine that doesn't reset global blocks in case of global
+ * attention once global blocks are reset and gates are opened
+ * (the engine which leader will perform the recovery
+ * last).
+ */
+ if (!CHIP_IS_E1x(bp))
+ bnx2x_pf_disable(bp);
+
+ /* Disable HW interrupts, NAPI */
+ bnx2x_netif_stop(bp, 1);
+ /* Delete all NAPI objects */
+ bnx2x_del_all_napi(bp);
+ if (CNIC_LOADED(bp))
+ bnx2x_del_all_napi_cnic(bp);
+ /* Release IRQs */
+ bnx2x_free_irq(bp);
+
+ /* Report UNLOAD_DONE to MCP */
+ bnx2x_send_unload_done(bp, false);
+ }
+
+ /*
+ * At this stage no more interrupts will arrive so we may safely clean
+ * the queueable objects here in case they failed to get cleaned so far.
+ */
+ if (IS_PF(bp))
+ bnx2x_squeeze_objects(bp);
+
+ /* There should be no more pending SP commands at this stage */
+ bp->sp_state = 0;
+
+ bp->port.pmf = 0;
+
+ /* clear pending work in rtnl task */
+ bp->sp_rtnl_state = 0;
+ smp_mb();
+
+ /* Free SKBs, SGEs, TPA pool and driver internals */
+ bnx2x_free_skbs(bp);
+ if (CNIC_LOADED(bp))
+ bnx2x_free_skbs_cnic(bp);
+ for_each_rx_queue(bp, i)
+ bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
+
+ bnx2x_free_fp_mem(bp);
+ if (CNIC_LOADED(bp))
+ bnx2x_free_fp_mem_cnic(bp);
+
+ if (IS_PF(bp)) {
+ if (CNIC_LOADED(bp))
+ bnx2x_free_mem_cnic(bp);
+ }
+ bnx2x_free_mem(bp);
+
+ bp->state = BNX2X_STATE_CLOSED;
+ bp->cnic_loaded = false;
+
+ /* Clear driver version indication in shmem */
+ if (IS_PF(bp))
+ bnx2x_update_mng_version(bp);
+
+ /* Check if there are pending parity attentions. If there are - set
+ * RECOVERY_IN_PROGRESS.
+ */
+ if (IS_PF(bp) && bnx2x_chk_parity_attn(bp, &global, false)) {
+ bnx2x_set_reset_in_progress(bp);
+
+ /* Set RESET_IS_GLOBAL if needed */
+ if (global)
+ bnx2x_set_reset_global(bp);
+ }
+
+ /* The last driver must disable a "close the gate" if there is no
+ * parity attention or "process kill" pending.
+ */
+ if (IS_PF(bp) &&
+ !bnx2x_clear_pf_load(bp) &&
+ bnx2x_reset_is_done(bp, BP_PATH(bp)))
+ bnx2x_disable_close_the_gate(bp);
+
+ DP(NETIF_MSG_IFUP, "Ending NIC unload\n");
+
+ return 0;
+}
+
+int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
+{
+ u16 pmcsr;
+
+ /* If there is no power capability, silently succeed */
+ if (!bp->pdev->pm_cap) {
+ BNX2X_DEV_INFO("No power capability. Breaking.\n");
+ return 0;
+ }
+
+ pci_read_config_word(bp->pdev, bp->pdev->pm_cap + PCI_PM_CTRL, &pmcsr);
+
+ switch (state) {
+ case PCI_D0:
+ pci_write_config_word(bp->pdev, bp->pdev->pm_cap + PCI_PM_CTRL,
+ ((pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
+ PCI_PM_CTRL_PME_STATUS));
+
+ if (pmcsr & PCI_PM_CTRL_STATE_MASK)
+ /* delay required during transition out of D3hot */
+ msleep(20);
+ break;
+
+ case PCI_D3hot:
+ /* If there are other clients above don't
+ shut down the power */
+ if (atomic_read(&bp->pdev->enable_cnt) != 1)
+ return 0;
+ /* Don't shut down the power for emulation and FPGA */
+ if (CHIP_REV_IS_SLOW(bp))
+ return 0;
+
+ pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+ pmcsr |= 3;
+
+ if (bp->wol)
+ pmcsr |= PCI_PM_CTRL_PME_ENABLE;
+
+ pci_write_config_word(bp->pdev, bp->pdev->pm_cap + PCI_PM_CTRL,
+ pmcsr);
+
+ /* No more memory access after this point until
+ * device is brought back to D0.
+ */
+ break;
+
+ default:
+ dev_err(&bp->pdev->dev, "Can't support state = %d\n", state);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * net_device service functions
+ */
+static int bnx2x_poll(struct napi_struct *napi, int budget)
+{
+ int work_done = 0;
+ u8 cos;
+ struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
+ napi);
+ struct bnx2x *bp = fp->bp;
+
+ while (1) {
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic)) {
+ napi_complete(napi);
+ return 0;
+ }
+#endif
+ if (!bnx2x_fp_lock_napi(fp))
+ return work_done;
+
+ for_each_cos_in_tx_queue(fp, cos)
+ if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos]))
+ bnx2x_tx_int(bp, fp->txdata_ptr[cos]);
+
+ if (bnx2x_has_rx_work(fp)) {
+ work_done += bnx2x_rx_int(fp, budget - work_done);
+
+ /* must not complete if we consumed full budget */
+ if (work_done >= budget) {
+ bnx2x_fp_unlock_napi(fp);
+ break;
+ }
+ }
+
+ /* Fall out from the NAPI loop if needed */
+ if (!bnx2x_fp_unlock_napi(fp) &&
+ !(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
+
+ /* No need to update SB for FCoE L2 ring as long as
+ * it's connected to the default SB and the SB
+ * has been updated when NAPI was scheduled.
+ */
+ if (IS_FCOE_FP(fp)) {
+ napi_complete(napi);
+ break;
+ }
+ bnx2x_update_fpsb_idx(fp);
+ /* bnx2x_has_rx_work() reads the status block,
+ * thus we need to ensure that status block indices
+ * have been actually read (bnx2x_update_fpsb_idx)
+ * prior to this check (bnx2x_has_rx_work) so that
+ * we won't write the "newer" value of the status block
+ * to IGU (if there was a DMA right after
+ * bnx2x_has_rx_work and if there is no rmb, the memory
+ * reading (bnx2x_update_fpsb_idx) may be postponed
+ * to right before bnx2x_ack_sb). In this case there
+ * will never be another interrupt until there is
+ * another update of the status block, while there
+ * is still unhandled work.
+ */
+ rmb();
+
+ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) {
+ napi_complete(napi);
+ /* Re-enable interrupts */
+ DP(NETIF_MSG_RX_STATUS,
+ "Update index to %d\n", fp->fp_hc_idx);
+ bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID,
+ le16_to_cpu(fp->fp_hc_idx),
+ IGU_INT_ENABLE, 1);
+ break;
+ }
+ }
+ }
+
+ return work_done;
+}
+
+#ifdef CONFIG_NET_RX_BUSY_POLL
+/* must be called with local_bh_disable()d */
+int bnx2x_low_latency_recv(struct napi_struct *napi)
+{
+ struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
+ napi);
+ struct bnx2x *bp = fp->bp;
+ int found = 0;
+
+ if ((bp->state == BNX2X_STATE_CLOSED) ||
+ (bp->state == BNX2X_STATE_ERROR) ||
+ (bp->flags & (TPA_ENABLE_FLAG | GRO_ENABLE_FLAG)))
+ return LL_FLUSH_FAILED;
+
+ if (!bnx2x_fp_lock_poll(fp))
+ return LL_FLUSH_BUSY;
+
+ if (bnx2x_has_rx_work(fp))
+ found = bnx2x_rx_int(fp, 4);
+
+ bnx2x_fp_unlock_poll(fp);
+
+ return found;
+}
+#endif
+
+/* we split the first BD into headers and data BDs
+ * to ease the pain of our fellow microcode engineers
+ * we use one mapping for both BDs
+ */
+static u16 bnx2x_tx_split(struct bnx2x *bp,
+ struct bnx2x_fp_txdata *txdata,
+ struct sw_tx_bd *tx_buf,
+ struct eth_tx_start_bd **tx_bd, u16 hlen,
+ u16 bd_prod)
+{
+ struct eth_tx_start_bd *h_tx_bd = *tx_bd;
+ struct eth_tx_bd *d_tx_bd;
+ dma_addr_t mapping;
+ int old_len = le16_to_cpu(h_tx_bd->nbytes);
+
+ /* first fix first BD */
+ h_tx_bd->nbytes = cpu_to_le16(hlen);
+
+ DP(NETIF_MSG_TX_QUEUED, "TSO split header size is %d (%x:%x)\n",
+ h_tx_bd->nbytes, h_tx_bd->addr_hi, h_tx_bd->addr_lo);
+
+ /* now get a new data BD
+ * (after the pbd) and fill it */
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+ d_tx_bd = &txdata->tx_desc_ring[bd_prod].reg_bd;
+
+ mapping = HILO_U64(le32_to_cpu(h_tx_bd->addr_hi),
+ le32_to_cpu(h_tx_bd->addr_lo)) + hlen;
+
+ d_tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ d_tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ d_tx_bd->nbytes = cpu_to_le16(old_len - hlen);
+
+ /* this marks the BD as one that has no individual mapping */
+ tx_buf->flags |= BNX2X_TSO_SPLIT_BD;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "TSO split data size is %d (%x:%x)\n",
+ d_tx_bd->nbytes, d_tx_bd->addr_hi, d_tx_bd->addr_lo);
+
+ /* update tx_bd */
+ *tx_bd = (struct eth_tx_start_bd *)d_tx_bd;
+
+ return bd_prod;
+}
+
+#define bswab32(b32) ((__force __le32) swab32((__force __u32) (b32)))
+#define bswab16(b16) ((__force __le16) swab16((__force __u16) (b16)))
+static __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix)
+{
+ __sum16 tsum = (__force __sum16) csum;
+
+ if (fix > 0)
+ tsum = ~csum_fold(csum_sub((__force __wsum) csum,
+ csum_partial(t_header - fix, fix, 0)));
+
+ else if (fix < 0)
+ tsum = ~csum_fold(csum_add((__force __wsum) csum,
+ csum_partial(t_header, -fix, 0)));
+
+ return bswab16(tsum);
+}
+
+static u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
+{
+ u32 rc;
+ __u8 prot = 0;
+ __be16 protocol;
+
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return XMIT_PLAIN;
+
+ protocol = vlan_get_protocol(skb);
+ if (protocol == htons(ETH_P_IPV6)) {
+ rc = XMIT_CSUM_V6;
+ prot = ipv6_hdr(skb)->nexthdr;
+ } else {
+ rc = XMIT_CSUM_V4;
+ prot = ip_hdr(skb)->protocol;
+ }
+
+ if (!CHIP_IS_E1x(bp) && skb->encapsulation) {
+ if (inner_ip_hdr(skb)->version == 6) {
+ rc |= XMIT_CSUM_ENC_V6;
+ if (inner_ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
+ rc |= XMIT_CSUM_TCP;
+ } else {
+ rc |= XMIT_CSUM_ENC_V4;
+ if (inner_ip_hdr(skb)->protocol == IPPROTO_TCP)
+ rc |= XMIT_CSUM_TCP;
+ }
+ }
+ if (prot == IPPROTO_TCP)
+ rc |= XMIT_CSUM_TCP;
+
+ if (skb_is_gso(skb)) {
+ if (skb_is_gso_v6(skb)) {
+ rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP);
+ if (rc & XMIT_CSUM_ENC)
+ rc |= XMIT_GSO_ENC_V6;
+ } else {
+ rc |= (XMIT_GSO_V4 | XMIT_CSUM_TCP);
+ if (rc & XMIT_CSUM_ENC)
+ rc |= XMIT_GSO_ENC_V4;
+ }
+ }
+
+ return rc;
+}
+
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
+/* check if packet requires linearization (packet is too fragmented)
+ no need to check fragmentation if page size > 8K (there will be no
+ violation to FW restrictions) */
+static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
+ u32 xmit_type)
+{
+ int to_copy = 0;
+ int hlen = 0;
+ int first_bd_sz = 0;
+
+ /* 3 = 1 (for linear data BD) + 2 (for PBD and last BD) */
+ if (skb_shinfo(skb)->nr_frags >= (MAX_FETCH_BD - 3)) {
+
+ if (xmit_type & XMIT_GSO) {
+ unsigned short lso_mss = skb_shinfo(skb)->gso_size;
+ /* Check if LSO packet needs to be copied:
+ 3 = 1 (for headers BD) + 2 (for PBD and last BD) */
+ int wnd_size = MAX_FETCH_BD - 3;
+ /* Number of windows to check */
+ int num_wnds = skb_shinfo(skb)->nr_frags - wnd_size;
+ int wnd_idx = 0;
+ int frag_idx = 0;
+ u32 wnd_sum = 0;
+
+ /* Headers length */
+ hlen = (int)(skb_transport_header(skb) - skb->data) +
+ tcp_hdrlen(skb);
+
+ /* Amount of data (w/o headers) on linear part of SKB*/
+ first_bd_sz = skb_headlen(skb) - hlen;
+
+ wnd_sum = first_bd_sz;
+
+ /* Calculate the first sum - it's special */
+ for (frag_idx = 0; frag_idx < wnd_size - 1; frag_idx++)
+ wnd_sum +=
+ skb_frag_size(&skb_shinfo(skb)->frags[frag_idx]);
+
+ /* If there was data on linear skb data - check it */
+ if (first_bd_sz > 0) {
+ if (unlikely(wnd_sum < lso_mss)) {
+ to_copy = 1;
+ goto exit_lbl;
+ }
+
+ wnd_sum -= first_bd_sz;
+ }
+
+ /* Others are easier: run through the frag list and
+ check all windows */
+ for (wnd_idx = 0; wnd_idx <= num_wnds; wnd_idx++) {
+ wnd_sum +=
+ skb_frag_size(&skb_shinfo(skb)->frags[wnd_idx + wnd_size - 1]);
+
+ if (unlikely(wnd_sum < lso_mss)) {
+ to_copy = 1;
+ break;
+ }
+ wnd_sum -=
+ skb_frag_size(&skb_shinfo(skb)->frags[wnd_idx]);
+ }
+ } else {
+ /* in non-LSO too fragmented packet should always
+ be linearized */
+ to_copy = 1;
+ }
+ }
+
+exit_lbl:
+ if (unlikely(to_copy))
+ DP(NETIF_MSG_TX_QUEUED,
+ "Linearization IS REQUIRED for %s packet. num_frags %d hlen %d first_bd_sz %d\n",
+ (xmit_type & XMIT_GSO) ? "LSO" : "non-LSO",
+ skb_shinfo(skb)->nr_frags, hlen, first_bd_sz);
+
+ return to_copy;
+}
+#endif
+
+static void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
+ u32 xmit_type)
+{
+ struct ipv6hdr *ipv6;
+
+ *parsing_data |= (skb_shinfo(skb)->gso_size <<
+ ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
+ ETH_TX_PARSE_BD_E2_LSO_MSS;
+
+ if (xmit_type & XMIT_GSO_ENC_V6)
+ ipv6 = inner_ipv6_hdr(skb);
+ else if (xmit_type & XMIT_GSO_V6)
+ ipv6 = ipv6_hdr(skb);
+ else
+ ipv6 = NULL;
+
+ if (ipv6 && ipv6->nexthdr == NEXTHDR_IPV6)
+ *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
+}
+
+/**
+ * bnx2x_set_pbd_gso - update PBD in GSO case.
+ *
+ * @skb: packet skb
+ * @pbd: parse BD
+ * @xmit_type: xmit flags
+ */
+static void bnx2x_set_pbd_gso(struct sk_buff *skb,
+ struct eth_tx_parse_bd_e1x *pbd,
+ struct eth_tx_start_bd *tx_start_bd,
+ u32 xmit_type)
+{
+ pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+ pbd->tcp_send_seq = bswab32(tcp_hdr(skb)->seq);
+ pbd->tcp_flags = pbd_tcp_flags(tcp_hdr(skb));
+
+ if (xmit_type & XMIT_GSO_V4) {
+ pbd->ip_id = bswab16(ip_hdr(skb)->id);
+ pbd->tcp_pseudo_csum =
+ bswab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+ ip_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+
+ /* GSO on 57710/57711 needs FW to calculate IP checksum */
+ tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM;
+ } else {
+ pbd->tcp_pseudo_csum =
+ bswab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+ &ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+ }
+
+ pbd->global_data |=
+ cpu_to_le16(ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN);
+}
+
+/**
+ * bnx2x_set_pbd_csum_enc - update PBD with checksum and return header length
+ *
+ * @bp: driver handle
+ * @skb: packet skb
+ * @parsing_data: data to be updated
+ * @xmit_type: xmit flags
+ *
+ * 57712/578xx related, when skb has encapsulation
+ */
+static u8 bnx2x_set_pbd_csum_enc(struct bnx2x *bp, struct sk_buff *skb,
+ u32 *parsing_data, u32 xmit_type)
+{
+ *parsing_data |=
+ ((((u8 *)skb_inner_transport_header(skb) - skb->data) >> 1) <<
+ ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W_SHIFT) &
+ ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W;
+
+ if (xmit_type & XMIT_CSUM_TCP) {
+ *parsing_data |= ((inner_tcp_hdrlen(skb) / 4) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
+
+ return skb_inner_transport_header(skb) +
+ inner_tcp_hdrlen(skb) - skb->data;
+ }
+
+ /* We support checksum offload for TCP and UDP only.
+ * No need to pass the UDP header length - it's a constant.
+ */
+ return skb_inner_transport_header(skb) +
+ sizeof(struct udphdr) - skb->data;
+}
+
+/**
+ * bnx2x_set_pbd_csum_e2 - update PBD with checksum and return header length
+ *
+ * @bp: driver handle
+ * @skb: packet skb
+ * @parsing_data: data to be updated
+ * @xmit_type: xmit flags
+ *
+ * 57712/578xx related
+ */
+static u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
+ u32 *parsing_data, u32 xmit_type)
+{
+ *parsing_data |=
+ ((((u8 *)skb_transport_header(skb) - skb->data) >> 1) <<
+ ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W_SHIFT) &
+ ETH_TX_PARSE_BD_E2_L4_HDR_START_OFFSET_W;
+
+ if (xmit_type & XMIT_CSUM_TCP) {
+ *parsing_data |= ((tcp_hdrlen(skb) / 4) <<
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
+ ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
+
+ return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
+ }
+ /* We support checksum offload for TCP and UDP only.
+ * No need to pass the UDP header length - it's a constant.
+ */
+ return skb_transport_header(skb) + sizeof(struct udphdr) - skb->data;
+}
+
+/* set FW indication according to inner or outer protocols if tunneled */
+static void bnx2x_set_sbd_csum(struct bnx2x *bp, struct sk_buff *skb,
+ struct eth_tx_start_bd *tx_start_bd,
+ u32 xmit_type)
+{
+ tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM;
+
+ if (xmit_type & (XMIT_CSUM_ENC_V6 | XMIT_CSUM_V6))
+ tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IPV6;
+
+ if (!(xmit_type & XMIT_CSUM_TCP))
+ tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IS_UDP;
+}
+
+/**
+ * bnx2x_set_pbd_csum - update PBD with checksum and return header length
+ *
+ * @bp: driver handle
+ * @skb: packet skb
+ * @pbd: parse BD to be updated
+ * @xmit_type: xmit flags
+ */
+static u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb,
+ struct eth_tx_parse_bd_e1x *pbd,
+ u32 xmit_type)
+{
+ u8 hlen = (skb_network_header(skb) - skb->data) >> 1;
+
+ /* for now NS flag is not used in Linux */
+ pbd->global_data =
+ cpu_to_le16(hlen |
+ ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
+ ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT));
+
+ pbd->ip_hlen_w = (skb_transport_header(skb) -
+ skb_network_header(skb)) >> 1;
+
+ hlen += pbd->ip_hlen_w;
+
+ /* We support checksum offload for TCP and UDP only */
+ if (xmit_type & XMIT_CSUM_TCP)
+ hlen += tcp_hdrlen(skb) / 2;
+ else
+ hlen += sizeof(struct udphdr) / 2;
+
+ pbd->total_hlen_w = cpu_to_le16(hlen);
+ hlen = hlen*2;
+
+ if (xmit_type & XMIT_CSUM_TCP) {
+ pbd->tcp_pseudo_csum = bswab16(tcp_hdr(skb)->check);
+
+ } else {
+ s8 fix = SKB_CS_OFF(skb); /* signed! */
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "hlen %d fix %d csum before fix %x\n",
+ le16_to_cpu(pbd->total_hlen_w), fix, SKB_CS(skb));
+
+ /* HW bug: fixup the CSUM */
+ pbd->tcp_pseudo_csum =
+ bnx2x_csum_fix(skb_transport_header(skb),
+ SKB_CS(skb), fix);
+
+ DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n",
+ pbd->tcp_pseudo_csum);
+ }
+
+ return hlen;
+}
+
+static void bnx2x_update_pbds_gso_enc(struct sk_buff *skb,
+ struct eth_tx_parse_bd_e2 *pbd_e2,
+ struct eth_tx_parse_2nd_bd *pbd2,
+ u16 *global_data,
+ u32 xmit_type)
+{
+ u16 hlen_w = 0;
+ u8 outerip_off, outerip_len = 0;
+
+ /* from outer IP to transport */
+ hlen_w = (skb_inner_transport_header(skb) -
+ skb_network_header(skb)) >> 1;
+
+ /* transport len */
+ hlen_w += inner_tcp_hdrlen(skb) >> 1;
+
+ pbd2->fw_ip_hdr_to_payload_w = hlen_w;
+
+ /* outer IP header info */
+ if (xmit_type & XMIT_CSUM_V4) {
+ struct iphdr *iph = ip_hdr(skb);
+ u32 csum = (__force u32)(~iph->check) -
+ (__force u32)iph->tot_len -
+ (__force u32)iph->frag_off;
+
+ pbd2->fw_ip_csum_wo_len_flags_frag =
+ bswab16(csum_fold((__force __wsum)csum));
+ } else {
+ pbd2->fw_ip_hdr_to_payload_w =
+ hlen_w - ((sizeof(struct ipv6hdr)) >> 1);
+ }
+
+ pbd2->tcp_send_seq = bswab32(inner_tcp_hdr(skb)->seq);
+
+ pbd2->tcp_flags = pbd_tcp_flags(inner_tcp_hdr(skb));
+
+ if (xmit_type & XMIT_GSO_V4) {
+ pbd2->hw_ip_id = bswab16(inner_ip_hdr(skb)->id);
+
+ pbd_e2->data.tunnel_data.pseudo_csum =
+ bswab16(~csum_tcpudp_magic(
+ inner_ip_hdr(skb)->saddr,
+ inner_ip_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+
+ outerip_len = ip_hdr(skb)->ihl << 1;
+ } else {
+ pbd_e2->data.tunnel_data.pseudo_csum =
+ bswab16(~csum_ipv6_magic(
+ &inner_ipv6_hdr(skb)->saddr,
+ &inner_ipv6_hdr(skb)->daddr,
+ 0, IPPROTO_TCP, 0));
+ }
+
+ outerip_off = (skb_network_header(skb) - skb->data) >> 1;
+
+ *global_data |=
+ outerip_off |
+ (!!(xmit_type & XMIT_CSUM_V6) <<
+ ETH_TX_PARSE_2ND_BD_IP_HDR_TYPE_OUTER_SHIFT) |
+ (outerip_len <<
+ ETH_TX_PARSE_2ND_BD_IP_HDR_LEN_OUTER_W_SHIFT) |
+ ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
+ ETH_TX_PARSE_2ND_BD_LLC_SNAP_EN_SHIFT);
+
+ if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
+ SET_FLAG(*global_data, ETH_TX_PARSE_2ND_BD_TUNNEL_UDP_EXIST, 1);
+ pbd2->tunnel_udp_hdr_start_w = skb_transport_offset(skb) >> 1;
+ }
+}
+
+/* called with netif_tx_lock
+ * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
+ * netif_wake_queue()
+ */
+netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ struct netdev_queue *txq;
+ struct bnx2x_fp_txdata *txdata;
+ struct sw_tx_bd *tx_buf;
+ struct eth_tx_start_bd *tx_start_bd, *first_bd;
+ struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
+ struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
+ struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
+ struct eth_tx_parse_2nd_bd *pbd2 = NULL;
+ u32 pbd_e2_parsing_data = 0;
+ u16 pkt_prod, bd_prod;
+ int nbd, txq_index;
+ dma_addr_t mapping;
+ u32 xmit_type = bnx2x_xmit_type(bp, skb);
+ int i;
+ u8 hlen = 0;
+ __le16 pkt_size = 0;
+ struct ethhdr *eth;
+ u8 mac_type = UNICAST_ADDRESS;
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (unlikely(bp->panic))
+ return NETDEV_TX_BUSY;
+#endif
+
+ txq_index = skb_get_queue_mapping(skb);
+ txq = netdev_get_tx_queue(dev, txq_index);
+
+ BUG_ON(txq_index >= MAX_ETH_TXQ_IDX(bp) + (CNIC_LOADED(bp) ? 1 : 0));
+
+ txdata = &bp->bnx2x_txq[txq_index];
+
+ /* enable this debug print to view the transmission queue being used
+ DP(NETIF_MSG_TX_QUEUED, "indices: txq %d, fp %d, txdata %d\n",
+ txq_index, fp_index, txdata_index); */
+
+ /* enable this debug print to view the transmission details
+ DP(NETIF_MSG_TX_QUEUED,
+ "transmitting packet cid %d fp index %d txdata_index %d tx_data ptr %p fp pointer %p\n",
+ txdata->cid, fp_index, txdata_index, txdata, fp); */
+
+ if (unlikely(bnx2x_tx_avail(bp, txdata) <
+ skb_shinfo(skb)->nr_frags +
+ BDS_PER_TX_PKT +
+ NEXT_CNT_PER_TX_PKT(MAX_BDS_PER_TX_PKT))) {
+ /* Handle special storage cases separately */
+ if (txdata->tx_ring_size == 0) {
+ struct bnx2x_eth_q_stats *q_stats =
+ bnx2x_fp_qstats(bp, txdata->parent_fp);
+ q_stats->driver_filtered_tx_pkt++;
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++;
+ netif_tx_stop_queue(txq);
+ BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
+
+ return NETDEV_TX_BUSY;
+ }
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "queue[%d]: SKB: summed %x protocol %x protocol(%x,%x) gso type %x xmit_type %x len %d\n",
+ txq_index, skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr,
+ ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type,
+ skb->len);
+
+ eth = (struct ethhdr *)skb->data;
+
+ /* set flag according to packet type (UNICAST_ADDRESS is default)*/
+ if (unlikely(is_multicast_ether_addr(eth->h_dest))) {
+ if (is_broadcast_ether_addr(eth->h_dest))
+ mac_type = BROADCAST_ADDRESS;
+ else
+ mac_type = MULTICAST_ADDRESS;
+ }
+
+#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - BDS_PER_TX_PKT)
+ /* First, check if we need to linearize the skb (due to FW
+ restrictions). No need to check fragmentation if page size > 8K
+ (there will be no violation to FW restrictions) */
+ if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
+ /* Statistics of linearization */
+ bp->lin_cnt++;
+ if (skb_linearize(skb) != 0) {
+ DP(NETIF_MSG_TX_QUEUED,
+ "SKB linearization failed - silently dropping this SKB\n");
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+ }
+#endif
+ /* Map skb linear data for DMA */
+ mapping = dma_map_single(&bp->pdev->dev, skb->data,
+ skb_headlen(skb), DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
+ DP(NETIF_MSG_TX_QUEUED,
+ "SKB mapping failed - silently dropping this SKB\n");
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+ /*
+ Please read carefully. First we use one BD which we mark as start,
+ then we have a parsing info BD (used for TSO or xsum),
+ and only then we have the rest of the TSO BDs.
+ (don't forget to mark the last one as last,
+ and to unmap only AFTER you write to the BD ...)
+ And above all, all pdb sizes are in words - NOT DWORDS!
+ */
+
+ /* get current pkt produced now - advance it just before sending packet
+ * since mapping of pages may fail and cause packet to be dropped
+ */
+ pkt_prod = txdata->tx_pkt_prod;
+ bd_prod = TX_BD(txdata->tx_bd_prod);
+
+ /* get a tx_buf and first BD
+ * tx_start_bd may be changed during SPLIT,
+ * but first_bd will always stay first
+ */
+ tx_buf = &txdata->tx_buf_ring[TX_BD(pkt_prod)];
+ tx_start_bd = &txdata->tx_desc_ring[bd_prod].start_bd;
+ first_bd = tx_start_bd;
+
+ tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
+
+ /* header nbd: indirectly zero other flags! */
+ tx_start_bd->general_data = 1 << ETH_TX_START_BD_HDR_NBDS_SHIFT;
+
+ /* remember the first BD of the packet */
+ tx_buf->first_bd = txdata->tx_bd_prod;
+ tx_buf->skb = skb;
+ tx_buf->flags = 0;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "sending pkt %u @%p next_idx %u bd %u @%p\n",
+ pkt_prod, tx_buf, txdata->tx_pkt_prod, bd_prod, tx_start_bd);
+
+ if (vlan_tx_tag_present(skb)) {
+ tx_start_bd->vlan_or_ethertype =
+ cpu_to_le16(vlan_tx_tag_get(skb));
+ tx_start_bd->bd_flags.as_bitfield |=
+ (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT);
+ } else {
+ /* when transmitting in a vf, start bd must hold the ethertype
+ * for fw to enforce it
+ */
+ if (IS_VF(bp))
+ tx_start_bd->vlan_or_ethertype =
+ cpu_to_le16(ntohs(eth->h_proto));
+ else
+ /* used by FW for packet accounting */
+ tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
+ }
+
+ nbd = 2; /* start_bd + pbd + frags (updated when pages are mapped) */
+
+ /* turn on parsing and get a BD */
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+
+ if (xmit_type & XMIT_CSUM)
+ bnx2x_set_sbd_csum(bp, skb, tx_start_bd, xmit_type);
+
+ if (!CHIP_IS_E1x(bp)) {
+ pbd_e2 = &txdata->tx_desc_ring[bd_prod].parse_bd_e2;
+ memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
+
+ if (xmit_type & XMIT_CSUM_ENC) {
+ u16 global_data = 0;
+
+ /* Set PBD in enc checksum offload case */
+ hlen = bnx2x_set_pbd_csum_enc(bp, skb,
+ &pbd_e2_parsing_data,
+ xmit_type);
+
+ /* turn on 2nd parsing and get a BD */
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+
+ pbd2 = &txdata->tx_desc_ring[bd_prod].parse_2nd_bd;
+
+ memset(pbd2, 0, sizeof(*pbd2));
+
+ pbd_e2->data.tunnel_data.ip_hdr_start_inner_w =
+ (skb_inner_network_header(skb) -
+ skb->data) >> 1;
+
+ if (xmit_type & XMIT_GSO_ENC)
+ bnx2x_update_pbds_gso_enc(skb, pbd_e2, pbd2,
+ &global_data,
+ xmit_type);
+
+ pbd2->global_data = cpu_to_le16(global_data);
+
+ /* add addition parse BD indication to start BD */
+ SET_FLAG(tx_start_bd->general_data,
+ ETH_TX_START_BD_PARSE_NBDS, 1);
+ /* set encapsulation flag in start BD */
+ SET_FLAG(tx_start_bd->general_data,
+ ETH_TX_START_BD_TUNNEL_EXIST, 1);
+
+ tx_buf->flags |= BNX2X_HAS_SECOND_PBD;
+
+ nbd++;
+ } else if (xmit_type & XMIT_CSUM) {
+ /* Set PBD in checksum offload case w/o encapsulation */
+ hlen = bnx2x_set_pbd_csum_e2(bp, skb,
+ &pbd_e2_parsing_data,
+ xmit_type);
+ }
+
+ /* Add the macs to the parsing BD if this is a vf or if
+ * Tx Switching is enabled.
+ */
+ if (IS_VF(bp)) {
+ /* override GRE parameters in BD */
+ bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.src_hi,
+ &pbd_e2->data.mac_addr.src_mid,
+ &pbd_e2->data.mac_addr.src_lo,
+ eth->h_source);
+
+ bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.dst_hi,
+ &pbd_e2->data.mac_addr.dst_mid,
+ &pbd_e2->data.mac_addr.dst_lo,
+ eth->h_dest);
+ } else if (bp->flags & TX_SWITCHING) {
+ bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.dst_hi,
+ &pbd_e2->data.mac_addr.dst_mid,
+ &pbd_e2->data.mac_addr.dst_lo,
+ eth->h_dest);
+ }
+
+ SET_FLAG(pbd_e2_parsing_data,
+ ETH_TX_PARSE_BD_E2_ETH_ADDR_TYPE, mac_type);
+ } else {
+ u16 global_data = 0;
+ pbd_e1x = &txdata->tx_desc_ring[bd_prod].parse_bd_e1x;
+ memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
+ /* Set PBD in checksum offload case */
+ if (xmit_type & XMIT_CSUM)
+ hlen = bnx2x_set_pbd_csum(bp, skb, pbd_e1x, xmit_type);
+
+ SET_FLAG(global_data,
+ ETH_TX_PARSE_BD_E1X_ETH_ADDR_TYPE, mac_type);
+ pbd_e1x->global_data |= cpu_to_le16(global_data);
+ }
+
+ /* Setup the data pointer of the first BD of the packet */
+ tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+ pkt_size = tx_start_bd->nbytes;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "first bd @%p addr (%x:%x) nbytes %d flags %x vlan %x\n",
+ tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo,
+ le16_to_cpu(tx_start_bd->nbytes),
+ tx_start_bd->bd_flags.as_bitfield,
+ le16_to_cpu(tx_start_bd->vlan_or_ethertype));
+
+ if (xmit_type & XMIT_GSO) {
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "TSO packet len %d hlen %d total len %d tso size %d\n",
+ skb->len, hlen, skb_headlen(skb),
+ skb_shinfo(skb)->gso_size);
+
+ tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO;
+
+ if (unlikely(skb_headlen(skb) > hlen)) {
+ nbd++;
+ bd_prod = bnx2x_tx_split(bp, txdata, tx_buf,
+ &tx_start_bd, hlen,
+ bd_prod);
+ }
+ if (!CHIP_IS_E1x(bp))
+ bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
+ xmit_type);
+ else
+ bnx2x_set_pbd_gso(skb, pbd_e1x, first_bd, xmit_type);
+ }
+
+ /* Set the PBD's parsing_data field if not zero
+ * (for the chips newer than 57711).
+ */
+ if (pbd_e2_parsing_data)
+ pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data);
+
+ tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
+
+ /* Handle fragmented skb */
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ mapping = skb_frag_dma_map(&bp->pdev->dev, frag, 0,
+ skb_frag_size(frag), DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
+ unsigned int pkts_compl = 0, bytes_compl = 0;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "Unable to map page - dropping packet...\n");
+
+ /* we need unmap all buffers already mapped
+ * for this SKB;
+ * first_bd->nbd need to be properly updated
+ * before call to bnx2x_free_tx_pkt
+ */
+ first_bd->nbd = cpu_to_le16(nbd);
+ bnx2x_free_tx_pkt(bp, txdata,
+ TX_BD(txdata->tx_pkt_prod),
+ &pkts_compl, &bytes_compl);
+ return NETDEV_TX_OK;
+ }
+
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+ tx_data_bd = &txdata->tx_desc_ring[bd_prod].reg_bd;
+ if (total_pkt_bd == NULL)
+ total_pkt_bd = &txdata->tx_desc_ring[bd_prod].reg_bd;
+
+ tx_data_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ tx_data_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ tx_data_bd->nbytes = cpu_to_le16(skb_frag_size(frag));
+ le16_add_cpu(&pkt_size, skb_frag_size(frag));
+ nbd++;
+
+ DP(NETIF_MSG_TX_QUEUED,
+ "frag %d bd @%p addr (%x:%x) nbytes %d\n",
+ i, tx_data_bd, tx_data_bd->addr_hi, tx_data_bd->addr_lo,
+ le16_to_cpu(tx_data_bd->nbytes));
+ }
+
+ DP(NETIF_MSG_TX_QUEUED, "last bd @%p\n", tx_data_bd);
+
+ /* update with actual num BDs */
+ first_bd->nbd = cpu_to_le16(nbd);
+
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+
+ /* now send a tx doorbell, counting the next BD
+ * if the packet contains or ends with it
+ */
+ if (TX_BD_POFF(bd_prod) < nbd)
+ nbd++;
+
+ /* total_pkt_bytes should be set on the first data BD if
+ * it's not an LSO packet and there is more than one
+ * data BD. In this case pkt_size is limited by an MTU value.
+ * However we prefer to set it for an LSO packet (while we don't
+ * have to) in order to save some CPU cycles in a none-LSO
+ * case, when we much more care about them.
+ */
+ if (total_pkt_bd != NULL)
+ total_pkt_bd->total_pkt_bytes = pkt_size;
+
+ if (pbd_e1x)
+ DP(NETIF_MSG_TX_QUEUED,
+ "PBD (E1X) @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u tcp_flags %x xsum %x seq %u hlen %u\n",
+ pbd_e1x, pbd_e1x->global_data, pbd_e1x->ip_hlen_w,
+ pbd_e1x->ip_id, pbd_e1x->lso_mss, pbd_e1x->tcp_flags,
+ pbd_e1x->tcp_pseudo_csum, pbd_e1x->tcp_send_seq,
+ le16_to_cpu(pbd_e1x->total_hlen_w));
+ if (pbd_e2)
+ DP(NETIF_MSG_TX_QUEUED,
+ "PBD (E2) @%p dst %x %x %x src %x %x %x parsing_data %x\n",
+ pbd_e2,
+ pbd_e2->data.mac_addr.dst_hi,
+ pbd_e2->data.mac_addr.dst_mid,
+ pbd_e2->data.mac_addr.dst_lo,
+ pbd_e2->data.mac_addr.src_hi,
+ pbd_e2->data.mac_addr.src_mid,
+ pbd_e2->data.mac_addr.src_lo,
+ pbd_e2->parsing_data);
+ DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod);
+
+ netdev_tx_sent_queue(txq, skb->len);
+
+ skb_tx_timestamp(skb);
+
+ txdata->tx_pkt_prod++;
+ /*
+ * Make sure that the BD data is updated before updating the producer
+ * since FW might read the BD right after the producer is updated.
+ * This is only applicable for weak-ordered memory model archs such
+ * as IA-64. The following barrier is also mandatory since FW will
+ * assumes packets must have BDs.
+ */
+ wmb();
+
+ txdata->tx_db.data.prod += nbd;
+ barrier();
+
+ DOORBELL(bp, txdata->cid, txdata->tx_db.raw);
+
+ mmiowb();
+
+ txdata->tx_bd_prod += nbd;
+
+ if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_DESC_PER_TX_PKT)) {
+ netif_tx_stop_queue(txq);
+
+ /* paired memory barrier is in bnx2x_tx_int(), we have to keep
+ * ordering of set_bit() in netif_tx_stop_queue() and read of
+ * fp->bd_tx_cons */
+ smp_mb();
+
+ bnx2x_fp_qstats(bp, txdata->parent_fp)->driver_xoff++;
+ if (bnx2x_tx_avail(bp, txdata) >= MAX_DESC_PER_TX_PKT)
+ netif_tx_wake_queue(txq);
+ }
+ txdata->tx_pkt++;
+
+ return NETDEV_TX_OK;
+}
+
+/**
+ * bnx2x_setup_tc - routine to configure net_device for multi tc
+ *
+ * @netdev: net device to configure
+ * @tc: number of traffic classes to enable
+ *
+ * callback connected to the ndo_setup_tc function pointer
+ */
+int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
+{
+ int cos, prio, count, offset;
+ struct bnx2x *bp = netdev_priv(dev);
+
+ /* setup tc must be called under rtnl lock */
+ ASSERT_RTNL();
+
+ /* no traffic classes requested. Aborting */
+ if (!num_tc) {
+ netdev_reset_tc(dev);
+ return 0;
+ }
+
+ /* requested to support too many traffic classes */
+ if (num_tc > bp->max_cos) {
+ BNX2X_ERR("support for too many traffic classes requested: %d. Max supported is %d\n",
+ num_tc, bp->max_cos);
+ return -EINVAL;
+ }
+
+ /* declare amount of supported traffic classes */
+ if (netdev_set_num_tc(dev, num_tc)) {
+ BNX2X_ERR("failed to declare %d traffic classes\n", num_tc);
+ return -EINVAL;
+ }
+
+ /* configure priority to traffic class mapping */
+ for (prio = 0; prio < BNX2X_MAX_PRIORITY; prio++) {
+ netdev_set_prio_tc_map(dev, prio, bp->prio_to_cos[prio]);
+ DP(BNX2X_MSG_SP | NETIF_MSG_IFUP,
+ "mapping priority %d to tc %d\n",
+ prio, bp->prio_to_cos[prio]);
+ }
+
+ /* Use this configuration to differentiate tc0 from other COSes
+ This can be used for ets or pfc, and save the effort of setting
+ up a multio class queue disc or negotiating DCBX with a switch
+ netdev_set_prio_tc_map(dev, 0, 0);
+ DP(BNX2X_MSG_SP, "mapping priority %d to tc %d\n", 0, 0);
+ for (prio = 1; prio < 16; prio++) {
+ netdev_set_prio_tc_map(dev, prio, 1);
+ DP(BNX2X_MSG_SP, "mapping priority %d to tc %d\n", prio, 1);
+ } */
+
+ /* configure traffic class to transmission queue mapping */
+ for (cos = 0; cos < bp->max_cos; cos++) {
+ count = BNX2X_NUM_ETH_QUEUES(bp);
+ offset = cos * BNX2X_NUM_NON_CNIC_QUEUES(bp);
+ netdev_set_tc_queue(dev, cos, count, offset);
+ DP(BNX2X_MSG_SP | NETIF_MSG_IFUP,
+ "mapping tc %d to offset %d count %d\n",
+ cos, offset, count);
+ }
+
+ return 0;
+}
+
+/* called with rtnl_lock */
+int bnx2x_change_mac_addr(struct net_device *dev, void *p)
+{
+ struct sockaddr *addr = p;
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc = 0;
+
+ if (!bnx2x_is_valid_ether_addr(bp, addr->sa_data)) {
+ BNX2X_ERR("Requested MAC address is not valid\n");
+ return -EINVAL;
+ }
+
+ if ((IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp)) &&
+ !is_zero_ether_addr(addr->sa_data)) {
+ BNX2X_ERR("Can't configure non-zero address on iSCSI or FCoE functions in MF-SD mode\n");
+ return -EINVAL;
+ }
+
+ if (netif_running(dev)) {
+ rc = bnx2x_set_eth_mac(bp, false);
+ if (rc)
+ return rc;
+ }
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ if (netif_running(dev))
+ rc = bnx2x_set_eth_mac(bp, true);
+
+ return rc;
+}
+
+static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index)
+{
+ union host_hc_status_block *sb = &bnx2x_fp(bp, fp_index, status_blk);
+ struct bnx2x_fastpath *fp = &bp->fp[fp_index];
+ u8 cos;
+
+ /* Common */
+
+ if (IS_FCOE_IDX(fp_index)) {
+ memset(sb, 0, sizeof(union host_hc_status_block));
+ fp->status_blk_mapping = 0;
+ } else {
+ /* status blocks */
+ if (!CHIP_IS_E1x(bp))
+ BNX2X_PCI_FREE(sb->e2_sb,
+ bnx2x_fp(bp, fp_index,
+ status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ else
+ BNX2X_PCI_FREE(sb->e1x_sb,
+ bnx2x_fp(bp, fp_index,
+ status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+ }
+
+ /* Rx */
+ if (!skip_rx_queue(bp, fp_index)) {
+ bnx2x_free_rx_bds(fp);
+
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_desc_ring),
+ bnx2x_fp(bp, fp_index, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_comp_ring),
+ bnx2x_fp(bp, fp_index, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) *
+ NUM_RCQ_BD);
+
+ /* SGE ring */
+ BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_page_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_sge_ring),
+ bnx2x_fp(bp, fp_index, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ }
+
+ /* Tx */
+ if (!skip_tx_queue(bp, fp_index)) {
+ /* fastpath tx rings: tx_buf tx_desc */
+ for_each_cos_in_tx_queue(fp, cos) {
+ struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos];
+
+ DP(NETIF_MSG_IFDOWN,
+ "freeing tx memory of fp %d cos %d cid %d\n",
+ fp_index, cos, txdata->cid);
+
+ BNX2X_FREE(txdata->tx_buf_ring);
+ BNX2X_PCI_FREE(txdata->tx_desc_ring,
+ txdata->tx_desc_mapping,
+ sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ }
+ }
+ /* end of fastpath */
+}
+
+static void bnx2x_free_fp_mem_cnic(struct bnx2x *bp)
+{
+ int i;
+ for_each_cnic_queue(bp, i)
+ bnx2x_free_fp_mem_at(bp, i);
+}
+
+void bnx2x_free_fp_mem(struct bnx2x *bp)
+{
+ int i;
+ for_each_eth_queue(bp, i)
+ bnx2x_free_fp_mem_at(bp, i);
+}
+
+static void set_sb_shortcuts(struct bnx2x *bp, int index)
+{
+ union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk);
+ if (!CHIP_IS_E1x(bp)) {
+ bnx2x_fp(bp, index, sb_index_values) =
+ (__le16 *)status_blk.e2_sb->sb.index_values;
+ bnx2x_fp(bp, index, sb_running_index) =
+ (__le16 *)status_blk.e2_sb->sb.running_index;
+ } else {
+ bnx2x_fp(bp, index, sb_index_values) =
+ (__le16 *)status_blk.e1x_sb->sb.index_values;
+ bnx2x_fp(bp, index, sb_running_index) =
+ (__le16 *)status_blk.e1x_sb->sb.running_index;
+ }
+}
+
+/* Returns the number of actually allocated BDs */
+static int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
+ int rx_ring_size)
+{
+ struct bnx2x *bp = fp->bp;
+ u16 ring_prod, cqe_ring_prod;
+ int i, failure_cnt = 0;
+
+ fp->rx_comp_cons = 0;
+ cqe_ring_prod = ring_prod = 0;
+
+ /* This routine is called only during fo init so
+ * fp->eth_q_stats.rx_skb_alloc_failed = 0
+ */
+ for (i = 0; i < rx_ring_size; i++) {
+ if (bnx2x_alloc_rx_data(bp, fp, ring_prod, GFP_KERNEL) < 0) {
+ failure_cnt++;
+ continue;
+ }
+ ring_prod = NEXT_RX_IDX(ring_prod);
+ cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
+ WARN_ON(ring_prod <= (i - failure_cnt));
+ }
+
+ if (failure_cnt)
+ BNX2X_ERR("was only able to allocate %d rx skbs on queue[%d]\n",
+ i - failure_cnt, fp->index);
+
+ fp->rx_bd_prod = ring_prod;
+ /* Limit the CQE producer by the CQE ring size */
+ fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
+ cqe_ring_prod);
+ fp->rx_pkt = fp->rx_calls = 0;
+
+ bnx2x_fp_stats(bp, fp)->eth_q_stats.rx_skb_alloc_failed += failure_cnt;
+
+ return i - failure_cnt;
+}
+
+static void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp)
+{
+ int i;
+
+ for (i = 1; i <= NUM_RCQ_RINGS; i++) {
+ struct eth_rx_cqe_next_page *nextpg;
+
+ nextpg = (struct eth_rx_cqe_next_page *)
+ &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1];
+ nextpg->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_comp_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+ nextpg->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_comp_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+ }
+}
+
+static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
+{
+ union host_hc_status_block *sb;
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+ int ring_size = 0;
+ u8 cos;
+ int rx_ring_size = 0;
+
+ if (!bp->rx_ring_size &&
+ (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) {
+ rx_ring_size = MIN_RX_SIZE_NONTPA;
+ bp->rx_ring_size = rx_ring_size;
+ } else if (!bp->rx_ring_size) {
+ rx_ring_size = MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp);
+
+ if (CHIP_IS_E3(bp)) {
+ u32 cfg = SHMEM_RD(bp,
+ dev_info.port_hw_config[BP_PORT(bp)].
+ default_cfg);
+
+ /* Decrease ring size for 1G functions */
+ if ((cfg & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
+ PORT_HW_CFG_NET_SERDES_IF_SGMII)
+ rx_ring_size /= 10;
+ }
+
+ /* allocate at least number of buffers required by FW */
+ rx_ring_size = max_t(int, bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+ MIN_RX_SIZE_TPA, rx_ring_size);
+
+ bp->rx_ring_size = rx_ring_size;
+ } else /* if rx_ring_size specified - use it */
+ rx_ring_size = bp->rx_ring_size;
+
+ DP(BNX2X_MSG_SP, "calculated rx_ring_size %d\n", rx_ring_size);
+
+ /* Common */
+ sb = &bnx2x_fp(bp, index, status_blk);
+
+ if (!IS_FCOE_IDX(index)) {
+ /* status blocks */
+ if (!CHIP_IS_E1x(bp)) {
+ sb->e2_sb = BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ if (!sb->e2_sb)
+ goto alloc_mem_err;
+ } else {
+ sb->e1x_sb = BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+ if (!sb->e1x_sb)
+ goto alloc_mem_err;
+ }
+ }
+
+ /* FCoE Queue uses Default SB and doesn't ACK the SB, thus no need to
+ * set shortcuts for it.
+ */
+ if (!IS_FCOE_IDX(index))
+ set_sb_shortcuts(bp, index);
+
+ /* Tx */
+ if (!skip_tx_queue(bp, index)) {
+ /* fastpath tx rings: tx_buf tx_desc */
+ for_each_cos_in_tx_queue(fp, cos) {
+ struct bnx2x_fp_txdata *txdata = fp->txdata_ptr[cos];
+
+ DP(NETIF_MSG_IFUP,
+ "allocating tx memory of fp %d cos %d\n",
+ index, cos);
+
+ txdata->tx_buf_ring = kcalloc(NUM_TX_BD,
+ sizeof(struct sw_tx_bd),
+ GFP_KERNEL);
+ if (!txdata->tx_buf_ring)
+ goto alloc_mem_err;
+ txdata->tx_desc_ring = BNX2X_PCI_ALLOC(&txdata->tx_desc_mapping,
+ sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ if (!txdata->tx_desc_ring)
+ goto alloc_mem_err;
+ }
+ }
+
+ /* Rx */
+ if (!skip_rx_queue(bp, index)) {
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
+ bnx2x_fp(bp, index, rx_buf_ring) =
+ kcalloc(NUM_RX_BD, sizeof(struct sw_rx_bd), GFP_KERNEL);
+ if (!bnx2x_fp(bp, index, rx_buf_ring))
+ goto alloc_mem_err;
+ bnx2x_fp(bp, index, rx_desc_ring) =
+ BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+ if (!bnx2x_fp(bp, index, rx_desc_ring))
+ goto alloc_mem_err;
+
+ /* Seed all CQEs by 1s */
+ bnx2x_fp(bp, index, rx_comp_ring) =
+ BNX2X_PCI_FALLOC(&bnx2x_fp(bp, index, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) * NUM_RCQ_BD);
+ if (!bnx2x_fp(bp, index, rx_comp_ring))
+ goto alloc_mem_err;
+
+ /* SGE ring */
+ bnx2x_fp(bp, index, rx_page_ring) =
+ kcalloc(NUM_RX_SGE, sizeof(struct sw_rx_page),
+ GFP_KERNEL);
+ if (!bnx2x_fp(bp, index, rx_page_ring))
+ goto alloc_mem_err;
+ bnx2x_fp(bp, index, rx_sge_ring) =
+ BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ if (!bnx2x_fp(bp, index, rx_sge_ring))
+ goto alloc_mem_err;
+ /* RX BD ring */
+ bnx2x_set_next_page_rx_bd(fp);
+
+ /* CQ ring */
+ bnx2x_set_next_page_rx_cq(fp);
+
+ /* BDs */
+ ring_size = bnx2x_alloc_rx_bds(fp, rx_ring_size);
+ if (ring_size < rx_ring_size)
+ goto alloc_mem_err;
+ }
+
+ return 0;
+
+/* handles low memory cases */
+alloc_mem_err:
+ BNX2X_ERR("Unable to allocate full memory for queue %d (size %d)\n",
+ index, ring_size);
+ /* FW will drop all packets if queue is not big enough,
+ * In these cases we disable the queue
+ * Min size is different for OOO, TPA and non-TPA queues
+ */
+ if (ring_size < (fp->disable_tpa ?
+ MIN_RX_SIZE_NONTPA : MIN_RX_SIZE_TPA)) {
+ /* release memory allocated for this queue */
+ bnx2x_free_fp_mem_at(bp, index);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int bnx2x_alloc_fp_mem_cnic(struct bnx2x *bp)
+{
+ if (!NO_FCOE(bp))
+ /* FCoE */
+ if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX(bp)))
+ /* we will fail load process instead of mark
+ * NO_FCOE_FLAG
+ */
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int bnx2x_alloc_fp_mem(struct bnx2x *bp)
+{
+ int i;
+
+ /* 1. Allocate FP for leading - fatal if error
+ * 2. Allocate RSS - fix number of queues if error
+ */
+
+ /* leading */
+ if (bnx2x_alloc_fp_mem_at(bp, 0))
+ return -ENOMEM;
+
+ /* RSS */
+ for_each_nondefault_eth_queue(bp, i)
+ if (bnx2x_alloc_fp_mem_at(bp, i))
+ break;
+
+ /* handle memory failures */
+ if (i != BNX2X_NUM_ETH_QUEUES(bp)) {
+ int delta = BNX2X_NUM_ETH_QUEUES(bp) - i;
+
+ WARN_ON(delta < 0);
+ bnx2x_shrink_eth_fp(bp, delta);
+ if (CNIC_SUPPORT(bp))
+ /* move non eth FPs next to last eth FP
+ * must be done in that order
+ * FCOE_IDX < FWD_IDX < OOO_IDX
+ */
+
+ /* move FCoE fp even NO_FCOE_FLAG is on */
+ bnx2x_move_fp(bp, FCOE_IDX(bp), FCOE_IDX(bp) - delta);
+ bp->num_ethernet_queues -= delta;
+ bp->num_queues = bp->num_ethernet_queues +
+ bp->num_cnic_queues;
+ BNX2X_ERR("Adjusted num of queues from %d to %d\n",
+ bp->num_queues + delta, bp->num_queues);
+ }
+
+ return 0;
+}
+
+void bnx2x_free_mem_bp(struct bnx2x *bp)
+{
+ int i;
+
+ for (i = 0; i < bp->fp_array_size; i++)
+ kfree(bp->fp[i].tpa_info);
+ kfree(bp->fp);
+ kfree(bp->sp_objs);
+ kfree(bp->fp_stats);
+ kfree(bp->bnx2x_txq);
+ kfree(bp->msix_table);
+ kfree(bp->ilt);
+}
+
+int bnx2x_alloc_mem_bp(struct bnx2x *bp)
+{
+ struct bnx2x_fastpath *fp;
+ struct msix_entry *tbl;
+ struct bnx2x_ilt *ilt;
+ int msix_table_size = 0;
+ int fp_array_size, txq_array_size;
+ int i;
+
+ /*
+ * The biggest MSI-X table we might need is as a maximum number of fast
+ * path IGU SBs plus default SB (for PF only).
+ */
+ msix_table_size = bp->igu_sb_cnt;
+ if (IS_PF(bp))
+ msix_table_size++;
+ BNX2X_DEV_INFO("msix_table_size %d\n", msix_table_size);
+
+ /* fp array: RSS plus CNIC related L2 queues */
+ fp_array_size = BNX2X_MAX_RSS_COUNT(bp) + CNIC_SUPPORT(bp);
+ bp->fp_array_size = fp_array_size;
+ BNX2X_DEV_INFO("fp_array_size %d\n", bp->fp_array_size);
+
+ fp = kcalloc(bp->fp_array_size, sizeof(*fp), GFP_KERNEL);
+ if (!fp)
+ goto alloc_err;
+ for (i = 0; i < bp->fp_array_size; i++) {
+ fp[i].tpa_info =
+ kcalloc(ETH_MAX_AGGREGATION_QUEUES_E1H_E2,
+ sizeof(struct bnx2x_agg_info), GFP_KERNEL);
+ if (!(fp[i].tpa_info))
+ goto alloc_err;
+ }
+
+ bp->fp = fp;
+
+ /* allocate sp objs */
+ bp->sp_objs = kcalloc(bp->fp_array_size, sizeof(struct bnx2x_sp_objs),
+ GFP_KERNEL);
+ if (!bp->sp_objs)
+ goto alloc_err;
+
+ /* allocate fp_stats */
+ bp->fp_stats = kcalloc(bp->fp_array_size, sizeof(struct bnx2x_fp_stats),
+ GFP_KERNEL);
+ if (!bp->fp_stats)
+ goto alloc_err;
+
+ /* Allocate memory for the transmission queues array */
+ txq_array_size =
+ BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS + CNIC_SUPPORT(bp);
+ BNX2X_DEV_INFO("txq_array_size %d", txq_array_size);
+
+ bp->bnx2x_txq = kcalloc(txq_array_size, sizeof(struct bnx2x_fp_txdata),
+ GFP_KERNEL);
+ if (!bp->bnx2x_txq)
+ goto alloc_err;
+
+ /* msix table */
+ tbl = kcalloc(msix_table_size, sizeof(*tbl), GFP_KERNEL);
+ if (!tbl)
+ goto alloc_err;
+ bp->msix_table = tbl;
+
+ /* ilt */
+ ilt = kzalloc(sizeof(*ilt), GFP_KERNEL);
+ if (!ilt)
+ goto alloc_err;
+ bp->ilt = ilt;
+
+ return 0;
+alloc_err:
+ bnx2x_free_mem_bp(bp);
+ return -ENOMEM;
+}
+
+int bnx2x_reload_if_running(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (unlikely(!netif_running(dev)))
+ return 0;
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL, true);
+ return bnx2x_nic_load(bp, LOAD_NORMAL);
+}
+
+int bnx2x_get_cur_phy_idx(struct bnx2x *bp)
+{
+ u32 sel_phy_idx = 0;
+ if (bp->link_params.num_phys <= 1)
+ return INT_PHY;
+
+ if (bp->link_vars.link_up) {
+ sel_phy_idx = EXT_PHY1;
+ /* In case link is SERDES, check if the EXT_PHY2 is the one */
+ if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) &&
+ (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE))
+ sel_phy_idx = EXT_PHY2;
+ } else {
+
+ switch (bnx2x_phy_selection(&bp->link_params)) {
+ case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY1;
+ break;
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
+ case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
+ sel_phy_idx = EXT_PHY2;
+ break;
+ }
+ }
+
+ return sel_phy_idx;
+}
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp)
+{
+ u32 sel_phy_idx = bnx2x_get_cur_phy_idx(bp);
+ /*
+ * The selected activated PHY is always after swapping (in case PHY
+ * swapping is enabled). So when swapping is enabled, we need to reverse
+ * the configuration
+ */
+
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
+ if (sel_phy_idx == EXT_PHY1)
+ sel_phy_idx = EXT_PHY2;
+ else if (sel_phy_idx == EXT_PHY2)
+ sel_phy_idx = EXT_PHY1;
+ }
+ return LINK_CONFIG_IDX(sel_phy_idx);
+}
+
+#ifdef NETDEV_FCOE_WWNN
+int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+
+ switch (type) {
+ case NETDEV_FCOE_WWNN:
+ *wwn = HILO_U64(cp->fcoe_wwn_node_name_hi,
+ cp->fcoe_wwn_node_name_lo);
+ break;
+ case NETDEV_FCOE_WWPN:
+ *wwn = HILO_U64(cp->fcoe_wwn_port_name_hi,
+ cp->fcoe_wwn_port_name_lo);
+ break;
+ default:
+ BNX2X_ERR("Wrong WWN type requested - %d\n", type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
+
+/* called with rtnl_lock */
+int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
+ BNX2X_ERR("Can't perform change MTU during parity recovery\n");
+ return -EAGAIN;
+ }
+
+ if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) ||
+ ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE)) {
+ BNX2X_ERR("Can't support requested MTU size\n");
+ return -EINVAL;
+ }
+
+ /* This does not race with packet allocation
+ * because the actual alloc size is
+ * only updated as part of load
+ */
+ dev->mtu = new_mtu;
+
+ return bnx2x_reload_if_running(dev);
+}
+
+netdev_features_t bnx2x_fix_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ /* TPA requires Rx CSUM offloading */
+ if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa) {
+ features &= ~NETIF_F_LRO;
+ features &= ~NETIF_F_GRO;
+ }
+
+ return features;
+}
+
+int bnx2x_set_features(struct net_device *dev, netdev_features_t features)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 flags = bp->flags;
+ u32 changes;
+ bool bnx2x_reload = false;
+
+ if (features & NETIF_F_LRO)
+ flags |= TPA_ENABLE_FLAG;
+ else
+ flags &= ~TPA_ENABLE_FLAG;
+
+ if (features & NETIF_F_GRO)
+ flags |= GRO_ENABLE_FLAG;
+ else
+ flags &= ~GRO_ENABLE_FLAG;
+
+ if (features & NETIF_F_LOOPBACK) {
+ if (bp->link_params.loopback_mode != LOOPBACK_BMAC) {
+ bp->link_params.loopback_mode = LOOPBACK_BMAC;
+ bnx2x_reload = true;
+ }
+ } else {
+ if (bp->link_params.loopback_mode != LOOPBACK_NONE) {
+ bp->link_params.loopback_mode = LOOPBACK_NONE;
+ bnx2x_reload = true;
+ }
+ }
+
+ changes = flags ^ bp->flags;
+
+ /* if GRO is changed while LRO is enabled, don't force a reload */
+ if ((changes & GRO_ENABLE_FLAG) && (flags & TPA_ENABLE_FLAG))
+ changes &= ~GRO_ENABLE_FLAG;
+
+ if (changes)
+ bnx2x_reload = true;
+
+ bp->flags = flags;
+
+ if (bnx2x_reload) {
+ if (bp->recovery_state == BNX2X_RECOVERY_DONE)
+ return bnx2x_reload_if_running(dev);
+ /* else: bnx2x_nic_load() will be called at end of recovery */
+ }
+
+ return 0;
+}
+
+void bnx2x_tx_timeout(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ if (!bp->panic)
+ bnx2x_panic();
+#endif
+
+ /* This allows the netif to be shutdown gracefully before resetting */
+ bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_TX_TIMEOUT, 0);
+}
+
+int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp;
+
+ if (!dev) {
+ dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n");
+ return -ENODEV;
+ }
+ bp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ pci_save_state(pdev);
+
+ if (!netif_running(dev)) {
+ rtnl_unlock();
+ return 0;
+ }
+
+ netif_device_detach(dev);
+
+ bnx2x_nic_unload(bp, UNLOAD_CLOSE, false);
+
+ bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
+
+ rtnl_unlock();
+
+ return 0;
+}
+
+int bnx2x_resume(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct bnx2x *bp;
+ int rc;
+
+ if (!dev) {
+ dev_err(&pdev->dev, "BAD net device from bnx2x_init_one\n");
+ return -ENODEV;
+ }
+ bp = netdev_priv(dev);
+
+ if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
+ BNX2X_ERR("Handling parity error recovery. Try again later\n");
+ return -EAGAIN;
+ }
+
+ rtnl_lock();
+
+ pci_restore_state(pdev);
+
+ if (!netif_running(dev)) {
+ rtnl_unlock();
+ return 0;
+ }
+
+ bnx2x_set_power_state(bp, PCI_D0);
+ netif_device_attach(dev);
+
+ rc = bnx2x_nic_load(bp, LOAD_OPEN);
+
+ rtnl_unlock();
+
+ return rc;
+}
+
+void bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt,
+ u32 cid)
+{
+ if (!cxt) {
+ BNX2X_ERR("bad context pointer %p\n", cxt);
+ return;
+ }
+
+ /* ustorm cxt validation */
+ cxt->ustorm_ag_context.cdu_usage =
+ CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, cid),
+ CDU_REGION_NUMBER_UCM_AG, ETH_CONNECTION_TYPE);
+ /* xcontext validation */
+ cxt->xstorm_ag_context.cdu_reserved =
+ CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, cid),
+ CDU_REGION_NUMBER_XCM_AG, ETH_CONNECTION_TYPE);
+}
+
+static void storm_memset_hc_timeout(struct bnx2x *bp, u8 port,
+ u8 fw_sb_id, u8 sb_index,
+ u8 ticks)
+{
+ u32 addr = BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_TIMEOUT_OFFSET(fw_sb_id, sb_index);
+ REG_WR8(bp, addr, ticks);
+ DP(NETIF_MSG_IFUP,
+ "port %x fw_sb_id %d sb_index %d ticks %d\n",
+ port, fw_sb_id, sb_index, ticks);
+}
+
+static void storm_memset_hc_disable(struct bnx2x *bp, u8 port,
+ u16 fw_sb_id, u8 sb_index,
+ u8 disable)
+{
+ u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT);
+ u32 addr = BAR_CSTRORM_INTMEM +
+ CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(fw_sb_id, sb_index);
+ u8 flags = REG_RD8(bp, addr);
+ /* clear and set */
+ flags &= ~HC_INDEX_DATA_HC_ENABLED;
+ flags |= enable_flag;
+ REG_WR8(bp, addr, flags);
+ DP(NETIF_MSG_IFUP,
+ "port %x fw_sb_id %d sb_index %d disable %d\n",
+ port, fw_sb_id, sb_index, disable);
+}
+
+void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u8 fw_sb_id,
+ u8 sb_index, u8 disable, u16 usec)
+{
+ int port = BP_PORT(bp);
+ u8 ticks = usec / BNX2X_BTR;
+
+ storm_memset_hc_timeout(bp, port, fw_sb_id, sb_index, ticks);
+
+ disable = disable ? 1 : (usec ? 0 : 1);
+ storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable);
+}
+
+void bnx2x_schedule_sp_rtnl(struct bnx2x *bp, enum sp_rtnl_flag flag,
+ u32 verbose)
+{
+ smp_mb__before_atomic();
+ set_bit(flag, &bp->sp_rtnl_state);
+ smp_mb__after_atomic();
+ DP((BNX2X_MSG_SP | verbose), "Scheduling sp_rtnl task [Flag: %d]\n",
+ flag);
+ schedule_delayed_work(&bp->sp_rtnl_task, 0);
+}
+EXPORT_SYMBOL(bnx2x_schedule_sp_rtnl);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
new file mode 100644
index 00000000000..571427c7226
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -0,0 +1,1326 @@
+/* bnx2x_cmn.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007-2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
+ * Written by: Eliezer Tamir
+ * Based on code from Michael Chan's bnx2 driver
+ * UDP CSUM errata workaround by Arik Gendelman
+ * Slowpath and fastpath rework by Vladislav Zolotarov
+ * Statistics and Link management by Yitchak Gertner
+ *
+ */
+#ifndef BNX2X_CMN_H
+#define BNX2X_CMN_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/irq.h>
+
+#include "bnx2x.h"
+#include "bnx2x_sriov.h"
+
+/* This is used as a replacement for an MCP if it's not present */
+extern int bnx2x_load_count[2][3]; /* per-path: 0-common, 1-port0, 2-port1 */
+extern int bnx2x_num_queues;
+
+/************************ Macros ********************************/
+#define BNX2X_PCI_FREE(x, y, size) \
+ do { \
+ if (x) { \
+ dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
+ x = NULL; \
+ y = 0; \
+ } \
+ } while (0)
+
+#define BNX2X_FREE(x) \
+ do { \
+ if (x) { \
+ kfree((void *)x); \
+ x = NULL; \
+ } \
+ } while (0)
+
+#define BNX2X_PCI_ALLOC(y, size) \
+({ \
+ void *x = dma_zalloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+ if (x) \
+ DP(NETIF_MSG_HW, \
+ "BNX2X_PCI_ALLOC: Physical %Lx Virtual %p\n", \
+ (unsigned long long)(*y), x); \
+ x; \
+})
+#define BNX2X_PCI_FALLOC(y, size) \
+({ \
+ void *x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+ if (x) { \
+ memset(x, 0xff, size); \
+ DP(NETIF_MSG_HW, \
+ "BNX2X_PCI_FALLOC: Physical %Lx Virtual %p\n", \
+ (unsigned long long)(*y), x); \
+ } \
+ x; \
+})
+
+/*********************** Interfaces ****************************
+ * Functions that need to be implemented by each driver version
+ */
+/* Init */
+
+/**
+ * bnx2x_send_unload_req - request unload mode from the MCP.
+ *
+ * @bp: driver handle
+ * @unload_mode: requested function's unload mode
+ *
+ * Return unload mode returned by the MCP: COMMON, PORT or FUNC.
+ */
+u32 bnx2x_send_unload_req(struct bnx2x *bp, int unload_mode);
+
+/**
+ * bnx2x_send_unload_done - send UNLOAD_DONE command to the MCP.
+ *
+ * @bp: driver handle
+ * @keep_link: true iff link should be kept up
+ */
+void bnx2x_send_unload_done(struct bnx2x *bp, bool keep_link);
+
+/**
+ * bnx2x_config_rss_pf - configure RSS parameters in a PF.
+ *
+ * @bp: driver handle
+ * @rss_obj: RSS object to use
+ * @ind_table: indirection table to configure
+ * @config_hash: re-configure RSS hash keys configuration
+ * @enable: enabled or disabled configuration
+ */
+int bnx2x_rss(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
+ bool config_hash, bool enable);
+
+/**
+ * bnx2x__init_func_obj - init function object
+ *
+ * @bp: driver handle
+ *
+ * Initializes the Function Object with the appropriate
+ * parameters which include a function slow path driver
+ * interface.
+ */
+void bnx2x__init_func_obj(struct bnx2x *bp);
+
+/**
+ * bnx2x_setup_queue - setup eth queue.
+ *
+ * @bp: driver handle
+ * @fp: pointer to the fastpath structure
+ * @leading: boolean
+ *
+ */
+int bnx2x_setup_queue(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ bool leading);
+
+/**
+ * bnx2x_setup_leading - bring up a leading eth queue.
+ *
+ * @bp: driver handle
+ */
+int bnx2x_setup_leading(struct bnx2x *bp);
+
+/**
+ * bnx2x_fw_command - send the MCP a request
+ *
+ * @bp: driver handle
+ * @command: request
+ * @param: request's parameter
+ *
+ * block until there is a reply
+ */
+u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param);
+
+/**
+ * bnx2x_initial_phy_init - initialize link parameters structure variables.
+ *
+ * @bp: driver handle
+ * @load_mode: current mode
+ */
+int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode);
+
+/**
+ * bnx2x_link_set - configure hw according to link parameters structure.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_link_set(struct bnx2x *bp);
+
+/**
+ * bnx2x_force_link_reset - Forces link reset, and put the PHY
+ * in reset as well.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_force_link_reset(struct bnx2x *bp);
+
+/**
+ * bnx2x_link_test - query link status.
+ *
+ * @bp: driver handle
+ * @is_serdes: bool
+ *
+ * Returns 0 if link is UP.
+ */
+u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes);
+
+/**
+ * bnx2x_drv_pulse - write driver pulse to shmem
+ *
+ * @bp: driver handle
+ *
+ * writes the value in bp->fw_drv_pulse_wr_seq to drv_pulse mbox
+ * in the shmem.
+ */
+void bnx2x_drv_pulse(struct bnx2x *bp);
+
+/**
+ * bnx2x_igu_ack_sb - update IGU with current SB value
+ *
+ * @bp: driver handle
+ * @igu_sb_id: SB id
+ * @segment: SB segment
+ * @index: SB index
+ * @op: SB operation
+ * @update: is HW update required
+ */
+void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment,
+ u16 index, u8 op, u8 update);
+
+/* Disable transactions from chip to host */
+void bnx2x_pf_disable(struct bnx2x *bp);
+int bnx2x_pretend_func(struct bnx2x *bp, u16 pretend_func_val);
+
+/**
+ * bnx2x__link_status_update - handles link status change.
+ *
+ * @bp: driver handle
+ */
+void bnx2x__link_status_update(struct bnx2x *bp);
+
+/**
+ * bnx2x_link_report - report link status to upper layer.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_link_report(struct bnx2x *bp);
+
+/* None-atomic version of bnx2x_link_report() */
+void __bnx2x_link_report(struct bnx2x *bp);
+
+/**
+ * bnx2x_get_mf_speed - calculate MF speed.
+ *
+ * @bp: driver handle
+ *
+ * Takes into account current linespeed and MF configuration.
+ */
+u16 bnx2x_get_mf_speed(struct bnx2x *bp);
+
+/**
+ * bnx2x_msix_sp_int - MSI-X slowpath interrupt handler
+ *
+ * @irq: irq number
+ * @dev_instance: private instance
+ */
+irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance);
+
+/**
+ * bnx2x_interrupt - non MSI-X interrupt handler
+ *
+ * @irq: irq number
+ * @dev_instance: private instance
+ */
+irqreturn_t bnx2x_interrupt(int irq, void *dev_instance);
+
+/**
+ * bnx2x_cnic_notify - send command to cnic driver
+ *
+ * @bp: driver handle
+ * @cmd: command
+ */
+int bnx2x_cnic_notify(struct bnx2x *bp, int cmd);
+
+/**
+ * bnx2x_setup_cnic_irq_info - provides cnic with IRQ information
+ *
+ * @bp: driver handle
+ */
+void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
+
+/**
+ * bnx2x_setup_cnic_info - provides cnic with updated info
+ *
+ * @bp: driver handle
+ */
+void bnx2x_setup_cnic_info(struct bnx2x *bp);
+
+/**
+ * bnx2x_int_enable - enable HW interrupts.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_int_enable(struct bnx2x *bp);
+
+/**
+ * bnx2x_int_disable_sync - disable interrupts.
+ *
+ * @bp: driver handle
+ * @disable_hw: true, disable HW interrupts.
+ *
+ * This function ensures that there are no
+ * ISRs or SP DPCs (sp_task) are running after it returns.
+ */
+void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
+
+/**
+ * bnx2x_nic_init_cnic - init driver internals for cnic.
+ *
+ * @bp: driver handle
+ * @load_code: COMMON, PORT or FUNCTION
+ *
+ * Initializes:
+ * - rings
+ * - status blocks
+ * - etc.
+ */
+void bnx2x_nic_init_cnic(struct bnx2x *bp);
+
+/**
+ * bnx2x_preirq_nic_init - init driver internals.
+ *
+ * @bp: driver handle
+ *
+ * Initializes:
+ * - fastpath object
+ * - fastpath rings
+ * etc.
+ */
+void bnx2x_pre_irq_nic_init(struct bnx2x *bp);
+
+/**
+ * bnx2x_postirq_nic_init - init driver internals.
+ *
+ * @bp: driver handle
+ * @load_code: COMMON, PORT or FUNCTION
+ *
+ * Initializes:
+ * - status blocks
+ * - slowpath rings
+ * - etc.
+ */
+void bnx2x_post_irq_nic_init(struct bnx2x *bp, u32 load_code);
+/**
+ * bnx2x_alloc_mem_cnic - allocate driver's memory for cnic.
+ *
+ * @bp: driver handle
+ */
+int bnx2x_alloc_mem_cnic(struct bnx2x *bp);
+/**
+ * bnx2x_alloc_mem - allocate driver's memory.
+ *
+ * @bp: driver handle
+ */
+int bnx2x_alloc_mem(struct bnx2x *bp);
+
+/**
+ * bnx2x_free_mem_cnic - release driver's memory for cnic.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_free_mem_cnic(struct bnx2x *bp);
+/**
+ * bnx2x_free_mem - release driver's memory.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_free_mem(struct bnx2x *bp);
+
+/**
+ * bnx2x_set_num_queues - set number of queues according to mode.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_set_num_queues(struct bnx2x *bp);
+
+/**
+ * bnx2x_chip_cleanup - cleanup chip internals.
+ *
+ * @bp: driver handle
+ * @unload_mode: COMMON, PORT, FUNCTION
+ * @keep_link: true iff link should be kept up.
+ *
+ * - Cleanup MAC configuration.
+ * - Closes clients.
+ * - etc.
+ */
+void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link);
+
+/**
+ * bnx2x_acquire_hw_lock - acquire HW lock.
+ *
+ * @bp: driver handle
+ * @resource: resource bit which was locked
+ */
+int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource);
+
+/**
+ * bnx2x_release_hw_lock - release HW lock.
+ *
+ * @bp: driver handle
+ * @resource: resource bit which was locked
+ */
+int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource);
+
+/**
+ * bnx2x_release_leader_lock - release recovery leader lock
+ *
+ * @bp: driver handle
+ */
+int bnx2x_release_leader_lock(struct bnx2x *bp);
+
+/**
+ * bnx2x_set_eth_mac - configure eth MAC address in the HW
+ *
+ * @bp: driver handle
+ * @set: set or clear
+ *
+ * Configures according to the value in netdev->dev_addr.
+ */
+int bnx2x_set_eth_mac(struct bnx2x *bp, bool set);
+
+/**
+ * bnx2x_set_rx_mode - set MAC filtering configurations.
+ *
+ * @dev: netdevice
+ *
+ * called with netif_tx_lock from dev_mcast.c
+ * If bp->state is OPEN, should be called with
+ * netif_addr_lock_bh()
+ */
+void bnx2x_set_rx_mode_inner(struct bnx2x *bp);
+
+/* Parity errors related */
+void bnx2x_set_pf_load(struct bnx2x *bp);
+bool bnx2x_clear_pf_load(struct bnx2x *bp);
+bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print);
+bool bnx2x_reset_is_done(struct bnx2x *bp, int engine);
+void bnx2x_set_reset_in_progress(struct bnx2x *bp);
+void bnx2x_set_reset_global(struct bnx2x *bp);
+void bnx2x_disable_close_the_gate(struct bnx2x *bp);
+int bnx2x_init_hw_func_cnic(struct bnx2x *bp);
+
+/**
+ * bnx2x_sp_event - handle ramrods completion.
+ *
+ * @fp: fastpath handle for the event
+ * @rr_cqe: eth_rx_cqe
+ */
+void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe);
+
+/**
+ * bnx2x_ilt_set_info - prepare ILT configurations.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_ilt_set_info(struct bnx2x *bp);
+
+/**
+ * bnx2x_ilt_set_cnic_info - prepare ILT configurations for SRC
+ * and TM.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_ilt_set_info_cnic(struct bnx2x *bp);
+
+/**
+ * bnx2x_dcbx_init - initialize dcbx protocol.
+ *
+ * @bp: driver handle
+ */
+void bnx2x_dcbx_init(struct bnx2x *bp, bool update_shmem);
+
+/**
+ * bnx2x_set_power_state - set power state to the requested value.
+ *
+ * @bp: driver handle
+ * @state: required state D0 or D3hot
+ *
+ * Currently only D0 and D3hot are supported.
+ */
+int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state);
+
+/**
+ * bnx2x_update_max_mf_config - update MAX part of MF configuration in HW.
+ *
+ * @bp: driver handle
+ * @value: new value
+ */
+void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value);
+/* Error handling */
+void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl);
+
+/* dev_close main block */
+int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link);
+
+/* dev_open main block */
+int bnx2x_nic_load(struct bnx2x *bp, int load_mode);
+
+/* hard_xmit callback */
+netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
+
+/* setup_tc callback */
+int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
+
+int bnx2x_get_vf_config(struct net_device *dev, int vf,
+ struct ifla_vf_info *ivi);
+int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
+int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos);
+
+/* select_queue callback */
+u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
+ void *accel_priv, select_queue_fallback_t fallback);
+
+static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp,
+ u16 bd_prod, u16 rx_comp_prod,
+ u16 rx_sge_prod)
+{
+ struct ustorm_eth_rx_producers rx_prods = {0};
+ u32 i;
+
+ /* Update producers */
+ rx_prods.bd_prod = bd_prod;
+ rx_prods.cqe_prod = rx_comp_prod;
+ rx_prods.sge_prod = rx_sge_prod;
+
+ /* Make sure that the BD and SGE data is updated before updating the
+ * producers since FW might read the BD/SGE right after the producer
+ * is updated.
+ * This is only applicable for weak-ordered memory model archs such
+ * as IA-64. The following barrier is also mandatory since FW will
+ * assumes BDs must have buffers.
+ */
+ wmb();
+
+ for (i = 0; i < sizeof(rx_prods)/4; i++)
+ REG_WR(bp, fp->ustorm_rx_prods_offset + i*4,
+ ((u32 *)&rx_prods)[i]);
+
+ mmiowb(); /* keep prod updates ordered */
+
+ DP(NETIF_MSG_RX_STATUS,
+ "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n",
+ fp->index, bd_prod, rx_comp_prod, rx_sge_prod);
+}
+
+/* reload helper */
+int bnx2x_reload_if_running(struct net_device *dev);
+
+int bnx2x_change_mac_addr(struct net_device *dev, void *p);
+
+/* NAPI poll Tx part */
+int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata);
+
+/* suspend/resume callbacks */
+int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state);
+int bnx2x_resume(struct pci_dev *pdev);
+
+/* Release IRQ vectors */
+void bnx2x_free_irq(struct bnx2x *bp);
+
+void bnx2x_free_fp_mem(struct bnx2x *bp);
+void bnx2x_init_rx_rings(struct bnx2x *bp);
+void bnx2x_init_rx_rings_cnic(struct bnx2x *bp);
+void bnx2x_free_skbs(struct bnx2x *bp);
+void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw);
+void bnx2x_netif_start(struct bnx2x *bp);
+int bnx2x_load_cnic(struct bnx2x *bp);
+
+/**
+ * bnx2x_enable_msix - set msix configuration.
+ *
+ * @bp: driver handle
+ *
+ * fills msix_table, requests vectors, updates num_queues
+ * according to number of available vectors.
+ */
+int bnx2x_enable_msix(struct bnx2x *bp);
+
+/**
+ * bnx2x_enable_msi - request msi mode from OS, updated internals accordingly
+ *
+ * @bp: driver handle
+ */
+int bnx2x_enable_msi(struct bnx2x *bp);
+
+/**
+ * bnx2x_low_latency_recv - LL callback
+ *
+ * @napi: napi structure
+ */
+int bnx2x_low_latency_recv(struct napi_struct *napi);
+
+/**
+ * bnx2x_alloc_mem_bp - allocate memories outsize main driver structure
+ *
+ * @bp: driver handle
+ */
+int bnx2x_alloc_mem_bp(struct bnx2x *bp);
+
+/**
+ * bnx2x_free_mem_bp - release memories outsize main driver structure
+ *
+ * @bp: driver handle
+ */
+void bnx2x_free_mem_bp(struct bnx2x *bp);
+
+/**
+ * bnx2x_change_mtu - change mtu netdev callback
+ *
+ * @dev: net device
+ * @new_mtu: requested mtu
+ *
+ */
+int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+
+#ifdef NETDEV_FCOE_WWNN
+/**
+ * bnx2x_fcoe_get_wwn - return the requested WWN value for this port
+ *
+ * @dev: net_device
+ * @wwn: output buffer
+ * @type: WWN type: NETDEV_FCOE_WWNN (node) or NETDEV_FCOE_WWPN (port)
+ *
+ */
+int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type);
+#endif
+
+netdev_features_t bnx2x_fix_features(struct net_device *dev,
+ netdev_features_t features);
+int bnx2x_set_features(struct net_device *dev, netdev_features_t features);
+
+/**
+ * bnx2x_tx_timeout - tx timeout netdev callback
+ *
+ * @dev: net device
+ */
+void bnx2x_tx_timeout(struct net_device *dev);
+
+/*********************** Inlines **********************************/
+/*********************** Fast path ********************************/
+static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
+{
+ barrier(); /* status block is written to by the chip */
+ fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID];
+}
+
+static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id,
+ u8 segment, u16 index, u8 op,
+ u8 update, u32 igu_addr)
+{
+ struct igu_regular cmd_data = {0};
+
+ cmd_data.sb_id_and_flags =
+ ((index << IGU_REGULAR_SB_INDEX_SHIFT) |
+ (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) |
+ (update << IGU_REGULAR_BUPDATE_SHIFT) |
+ (op << IGU_REGULAR_ENABLE_INT_SHIFT));
+
+ DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n",
+ cmd_data.sb_id_and_flags, igu_addr);
+ REG_WR(bp, igu_addr, cmd_data.sb_id_and_flags);
+
+ /* Make sure that ACK is written */
+ mmiowb();
+ barrier();
+}
+
+static inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id,
+ u8 storm, u16 index, u8 op, u8 update)
+{
+ u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
+ COMMAND_REG_INT_ACK);
+ struct igu_ack_register igu_ack;
+
+ igu_ack.status_block_index = index;
+ igu_ack.sb_id_and_flags =
+ ((sb_id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
+ (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) |
+ (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
+ (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
+
+ REG_WR(bp, hc_addr, (*(u32 *)&igu_ack));
+
+ /* Make sure that ACK is written */
+ mmiowb();
+ barrier();
+}
+
+static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm,
+ u16 index, u8 op, u8 update)
+{
+ if (bp->common.int_block == INT_BLOCK_HC)
+ bnx2x_hc_ack_sb(bp, igu_sb_id, storm, index, op, update);
+ else {
+ u8 segment;
+
+ if (CHIP_INT_MODE_IS_BC(bp))
+ segment = storm;
+ else if (igu_sb_id != bp->igu_dsb_id)
+ segment = IGU_SEG_ACCESS_DEF;
+ else if (storm == ATTENTION_ID)
+ segment = IGU_SEG_ACCESS_ATTN;
+ else
+ segment = IGU_SEG_ACCESS_DEF;
+ bnx2x_igu_ack_sb(bp, igu_sb_id, segment, index, op, update);
+ }
+}
+
+static inline u16 bnx2x_hc_ack_int(struct bnx2x *bp)
+{
+ u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
+ COMMAND_REG_SIMD_MASK);
+ u32 result = REG_RD(bp, hc_addr);
+
+ barrier();
+ return result;
+}
+
+static inline u16 bnx2x_igu_ack_int(struct bnx2x *bp)
+{
+ u32 igu_addr = (BAR_IGU_INTMEM + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8);
+ u32 result = REG_RD(bp, igu_addr);
+
+ DP(NETIF_MSG_INTR, "read 0x%08x from IGU addr 0x%x\n",
+ result, igu_addr);
+
+ barrier();
+ return result;
+}
+
+static inline u16 bnx2x_ack_int(struct bnx2x *bp)
+{
+ barrier();
+ if (bp->common.int_block == INT_BLOCK_HC)
+ return bnx2x_hc_ack_int(bp);
+ else
+ return bnx2x_igu_ack_int(bp);
+}
+
+static inline int bnx2x_has_tx_work_unload(struct bnx2x_fp_txdata *txdata)
+{
+ /* Tell compiler that consumer and producer can change */
+ barrier();
+ return txdata->tx_pkt_prod != txdata->tx_pkt_cons;
+}
+
+static inline u16 bnx2x_tx_avail(struct bnx2x *bp,
+ struct bnx2x_fp_txdata *txdata)
+{
+ s16 used;
+ u16 prod;
+ u16 cons;
+
+ prod = txdata->tx_bd_prod;
+ cons = txdata->tx_bd_cons;
+
+ used = SUB_S16(prod, cons);
+
+#ifdef BNX2X_STOP_ON_ERROR
+ WARN_ON(used < 0);
+ WARN_ON(used > txdata->tx_ring_size);
+ WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL);
+#endif
+
+ return (s16)(txdata->tx_ring_size) - used;
+}
+
+static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata)
+{
+ u16 hw_cons;
+
+ /* Tell compiler that status block fields can change */
+ barrier();
+ hw_cons = le16_to_cpu(*txdata->tx_cons_sb);
+ return hw_cons != txdata->tx_pkt_cons;
+}
+
+static inline bool bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
+{
+ u8 cos;
+ for_each_cos_in_tx_queue(fp, cos)
+ if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos]))
+ return true;
+ return false;
+}
+
+#define BNX2X_IS_CQE_COMPLETED(cqe_fp) (cqe_fp->marker == 0x0)
+#define BNX2X_SEED_CQE(cqe_fp) (cqe_fp->marker = 0xFFFFFFFF)
+static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
+{
+ u16 cons;
+ union eth_rx_cqe *cqe;
+ struct eth_fast_path_rx_cqe *cqe_fp;
+
+ cons = RCQ_BD(fp->rx_comp_cons);
+ cqe = &fp->rx_comp_ring[cons];
+ cqe_fp = &cqe->fast_path_cqe;
+ return BNX2X_IS_CQE_COMPLETED(cqe_fp);
+}
+
+/**
+ * bnx2x_tx_disable - disables tx from stack point of view
+ *
+ * @bp: driver handle
+ */
+static inline void bnx2x_tx_disable(struct bnx2x *bp)
+{
+ netif_tx_disable(bp->dev);
+ netif_carrier_off(bp->dev);
+}
+
+static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, u16 index)
+{
+ struct sw_rx_page *sw_buf = &fp->rx_page_ring[index];
+ struct page *page = sw_buf->page;
+ struct eth_rx_sge *sge = &fp->rx_sge_ring[index];
+
+ /* Skip "next page" elements */
+ if (!page)
+ return;
+
+ dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping),
+ SGE_PAGES, DMA_FROM_DEVICE);
+ __free_pages(page, PAGES_PER_SGE_SHIFT);
+
+ sw_buf->page = NULL;
+ sge->addr_hi = 0;
+ sge->addr_lo = 0;
+}
+
+static inline void bnx2x_del_all_napi_cnic(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_rx_queue_cnic(bp, i) {
+ napi_hash_del(&bnx2x_fp(bp, i, napi));
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
+ }
+}
+
+static inline void bnx2x_del_all_napi(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_eth_queue(bp, i) {
+ napi_hash_del(&bnx2x_fp(bp, i, napi));
+ netif_napi_del(&bnx2x_fp(bp, i, napi));
+ }
+}
+
+int bnx2x_set_int_mode(struct bnx2x *bp);
+
+static inline void bnx2x_disable_msi(struct bnx2x *bp)
+{
+ if (bp->flags & USING_MSIX_FLAG) {
+ pci_disable_msix(bp->pdev);
+ bp->flags &= ~(USING_MSIX_FLAG | USING_SINGLE_MSIX_FLAG);
+ } else if (bp->flags & USING_MSI_FLAG) {
+ pci_disable_msi(bp->pdev);
+ bp->flags &= ~USING_MSI_FLAG;
+ }
+}
+
+static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp)
+{
+ int i, j;
+
+ for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
+ int idx = RX_SGE_CNT * i - 1;
+
+ for (j = 0; j < 2; j++) {
+ BIT_VEC64_CLEAR_BIT(fp->sge_mask, idx);
+ idx--;
+ }
+ }
+}
+
+static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp)
+{
+ /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */
+ memset(fp->sge_mask, 0xff, sizeof(fp->sge_mask));
+
+ /* Clear the two last indices in the page to 1:
+ these are the indices that correspond to the "next" element,
+ hence will never be indicated and should be removed from
+ the calculations. */
+ bnx2x_clear_sge_mask_next_elems(fp);
+}
+
+/* note that we are not allocating a new buffer,
+ * we are just moving one from cons to prod
+ * we are not creating a new mapping,
+ * so there is no need to check for dma_mapping_error().
+ */
+static inline void bnx2x_reuse_rx_data(struct bnx2x_fastpath *fp,
+ u16 cons, u16 prod)
+{
+ struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
+ struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
+ struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons];
+ struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
+
+ dma_unmap_addr_set(prod_rx_buf, mapping,
+ dma_unmap_addr(cons_rx_buf, mapping));
+ prod_rx_buf->data = cons_rx_buf->data;
+ *prod_bd = *cons_bd;
+}
+
+/************************* Init ******************************************/
+
+/* returns func by VN for current port */
+static inline int func_by_vn(struct bnx2x *bp, int vn)
+{
+ return 2 * vn + BP_PORT(bp);
+}
+
+static inline int bnx2x_config_rss_eth(struct bnx2x *bp, bool config_hash)
+{
+ return bnx2x_rss(bp, &bp->rss_conf_obj, config_hash, true);
+}
+
+/**
+ * bnx2x_func_start - init function
+ *
+ * @bp: driver handle
+ *
+ * Must be called before sending CLIENT_SETUP for the first client.
+ */
+static inline int bnx2x_func_start(struct bnx2x *bp)
+{
+ struct bnx2x_func_state_params func_params = {NULL};
+ struct bnx2x_func_start_params *start_params =
+ &func_params.params.start;
+
+ /* Prepare parameters for function state transitions */
+ __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
+
+ func_params.f_obj = &bp->func_obj;
+ func_params.cmd = BNX2X_F_CMD_START;
+
+ /* Function parameters */
+ start_params->mf_mode = bp->mf_mode;
+ start_params->sd_vlan_tag = bp->mf_ov;
+
+ if (CHIP_IS_E2(bp) || CHIP_IS_E3(bp))
+ start_params->network_cos_mode = STATIC_COS;
+ else /* CHIP_IS_E1X */
+ start_params->network_cos_mode = FW_WRR;
+
+ start_params->gre_tunnel_mode = L2GRE_TUNNEL;
+ start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS;
+
+ return bnx2x_func_state_change(bp, &func_params);
+}
+
+/**
+ * bnx2x_set_fw_mac_addr - fill in a MAC address in FW format
+ *
+ * @fw_hi: pointer to upper part
+ * @fw_mid: pointer to middle part
+ * @fw_lo: pointer to lower part
+ * @mac: pointer to MAC address
+ */
+static inline void bnx2x_set_fw_mac_addr(__le16 *fw_hi, __le16 *fw_mid,
+ __le16 *fw_lo, u8 *mac)
+{
+ ((u8 *)fw_hi)[0] = mac[1];
+ ((u8 *)fw_hi)[1] = mac[0];
+ ((u8 *)fw_mid)[0] = mac[3];
+ ((u8 *)fw_mid)[1] = mac[2];
+ ((u8 *)fw_lo)[0] = mac[5];
+ ((u8 *)fw_lo)[1] = mac[4];
+}
+
+static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp,
+ struct bnx2x_fastpath *fp, int last)
+{
+ int i;
+
+ if (fp->disable_tpa)
+ return;
+
+ for (i = 0; i < last; i++)
+ bnx2x_free_rx_sge(bp, fp, i);
+}
+
+static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp)
+{
+ int i;
+
+ for (i = 1; i <= NUM_RX_RINGS; i++) {
+ struct eth_rx_bd *rx_bd;
+
+ rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2];
+ rx_bd->addr_hi =
+ cpu_to_le32(U64_HI(fp->rx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+ rx_bd->addr_lo =
+ cpu_to_le32(U64_LO(fp->rx_desc_mapping +
+ BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+ }
+}
+
+/* Statistics ID are global per chip/path, while Client IDs for E1x are per
+ * port.
+ */
+static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp)
+{
+ struct bnx2x *bp = fp->bp;
+ if (!CHIP_IS_E1x(bp)) {
+ /* there are special statistics counters for FCoE 136..140 */
+ if (IS_FCOE_FP(fp))
+ return bp->cnic_base_cl_id + (bp->pf_num >> 1);
+ return fp->cl_id;
+ }
+ return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x;
+}
+
+static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp,
+ bnx2x_obj_type obj_type)
+{
+ struct bnx2x *bp = fp->bp;
+
+ /* Configure classification DBs */
+ bnx2x_init_mac_obj(bp, &bnx2x_sp_obj(bp, fp).mac_obj, fp->cl_id,
+ fp->cid, BP_FUNC(bp), bnx2x_sp(bp, mac_rdata),
+ bnx2x_sp_mapping(bp, mac_rdata),
+ BNX2X_FILTER_MAC_PENDING,
+ &bp->sp_state, obj_type,
+ &bp->macs_pool);
+}
+
+/**
+ * bnx2x_get_path_func_num - get number of active functions
+ *
+ * @bp: driver handle
+ *
+ * Calculates the number of active (not hidden) functions on the
+ * current path.
+ */
+static inline u8 bnx2x_get_path_func_num(struct bnx2x *bp)
+{
+ u8 func_num = 0, i;
+
+ /* 57710 has only one function per-port */
+ if (CHIP_IS_E1(bp))
+ return 1;
+
+ /* Calculate a number of functions enabled on the current
+ * PATH/PORT.
+ */
+ if (CHIP_REV_IS_SLOW(bp)) {
+ if (IS_MF(bp))
+ func_num = 4;
+ else
+ func_num = 2;
+ } else {
+ for (i = 0; i < E1H_FUNC_MAX / 2; i++) {
+ u32 func_config =
+ MF_CFG_RD(bp,
+ func_mf_config[BP_PORT(bp) + 2 * i].
+ config);
+ func_num +=
+ ((func_config & FUNC_MF_CFG_FUNC_HIDE) ? 0 : 1);
+ }
+ }
+
+ WARN_ON(!func_num);
+
+ return func_num;
+}
+
+static inline void bnx2x_init_bp_objs(struct bnx2x *bp)
+{
+ /* RX_MODE controlling object */
+ bnx2x_init_rx_mode_obj(bp, &bp->rx_mode_obj);
+
+ /* multicast configuration controlling object */
+ bnx2x_init_mcast_obj(bp, &bp->mcast_obj, bp->fp->cl_id, bp->fp->cid,
+ BP_FUNC(bp), BP_FUNC(bp),
+ bnx2x_sp(bp, mcast_rdata),
+ bnx2x_sp_mapping(bp, mcast_rdata),
+ BNX2X_FILTER_MCAST_PENDING, &bp->sp_state,
+ BNX2X_OBJ_TYPE_RX);
+
+ /* Setup CAM credit pools */
+ bnx2x_init_mac_credit_pool(bp, &bp->macs_pool, BP_FUNC(bp),
+ bnx2x_get_path_func_num(bp));
+
+ bnx2x_init_vlan_credit_pool(bp, &bp->vlans_pool, BP_ABS_FUNC(bp)>>1,
+ bnx2x_get_path_func_num(bp));
+
+ /* RSS configuration object */
+ bnx2x_init_rss_config_obj(bp, &bp->rss_conf_obj, bp->fp->cl_id,
+ bp->fp->cid, BP_FUNC(bp), BP_FUNC(bp),
+ bnx2x_sp(bp, rss_rdata),
+ bnx2x_sp_mapping(bp, rss_rdata),
+ BNX2X_FILTER_RSS_CONF_PENDING, &bp->sp_state,
+ BNX2X_OBJ_TYPE_RX);
+}
+
+static inline u8 bnx2x_fp_qzone_id(struct bnx2x_fastpath *fp)
+{
+ if (CHIP_IS_E1x(fp->bp))
+ return fp->cl_id + BP_PORT(fp->bp) * ETH_MAX_RX_CLIENTS_E1H;
+ else
+ return fp->cl_id;
+}
+
+static inline void bnx2x_init_txdata(struct bnx2x *bp,
+ struct bnx2x_fp_txdata *txdata, u32 cid,
+ int txq_index, __le16 *tx_cons_sb,
+ struct bnx2x_fastpath *fp)
+{
+ txdata->cid = cid;
+ txdata->txq_index = txq_index;
+ txdata->tx_cons_sb = tx_cons_sb;
+ txdata->parent_fp = fp;
+ txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size;
+
+ DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n",
+ txdata->cid, txdata->txq_index);
+}
+
+static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx)
+{
+ return bp->cnic_base_cl_id + cl_idx +
+ (bp->pf_num >> 1) * BNX2X_MAX_CNIC_ETH_CL_ID_IDX;
+}
+
+static inline u8 bnx2x_cnic_fw_sb_id(struct bnx2x *bp)
+{
+ /* the 'first' id is allocated for the cnic */
+ return bp->base_fw_ndsb;
+}
+
+static inline u8 bnx2x_cnic_igu_sb_id(struct bnx2x *bp)
+{
+ return bp->igu_base_sb;
+}
+
+static inline int bnx2x_clean_tx_queue(struct bnx2x *bp,
+ struct bnx2x_fp_txdata *txdata)
+{
+ int cnt = 1000;
+
+ while (bnx2x_has_tx_work_unload(txdata)) {
+ if (!cnt) {
+ BNX2X_ERR("timeout waiting for queue[%d]: txdata->tx_pkt_prod(%d) != txdata->tx_pkt_cons(%d)\n",
+ txdata->txq_index, txdata->tx_pkt_prod,
+ txdata->tx_pkt_cons);
+#ifdef BNX2X_STOP_ON_ERROR
+ bnx2x_panic();
+ return -EBUSY;
+#else
+ break;
+#endif
+ }
+ cnt--;
+ usleep_range(1000, 2000);
+ }
+
+ return 0;
+}
+
+int bnx2x_get_link_cfg_idx(struct bnx2x *bp);
+
+static inline void __storm_memset_struct(struct bnx2x *bp,
+ u32 addr, size_t size, u32 *data)
+{
+ int i;
+ for (i = 0; i < size/4; i++)
+ REG_WR(bp, addr + (i * 4), data[i]);
+}
+
+/**
+ * bnx2x_wait_sp_comp - wait for the outstanding SP commands.
+ *
+ * @bp: driver handle
+ * @mask: bits that need to be cleared
+ */
+static inline bool bnx2x_wait_sp_comp(struct bnx2x *bp, unsigned long mask)
+{
+ int tout = 5000; /* Wait for 5 secs tops */
+
+ while (tout--) {
+ smp_mb();
+ netif_addr_lock_bh(bp->dev);
+ if (!(bp->sp_state & mask)) {
+ netif_addr_unlock_bh(bp->dev);
+ return true;
+ }
+ netif_addr_unlock_bh(bp->dev);
+
+ usleep_range(1000, 2000);
+ }
+
+ smp_mb();
+
+ netif_addr_lock_bh(bp->dev);
+ if (bp->sp_state & mask) {
+ BNX2X_ERR("Filtering completion timed out. sp_state 0x%lx, mask 0x%lx\n",
+ bp->sp_state, mask);
+ netif_addr_unlock_bh(bp->dev);
+ return false;
+ }
+ netif_addr_unlock_bh(bp->dev);
+
+ return true;
+}
+
+/**
+ * bnx2x_set_ctx_validation - set CDU context validation values
+ *
+ * @bp: driver handle
+ * @cxt: context of the connection on the host memory
+ * @cid: SW CID of the connection to be configured
+ */
+void bnx2x_set_ctx_validation(struct bnx2x *bp, struct eth_context *cxt,
+ u32 cid);
+
+void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u8 fw_sb_id,
+ u8 sb_index, u8 disable, u16 usec);
+void bnx2x_acquire_phy_lock(struct bnx2x *bp);
+void bnx2x_release_phy_lock(struct bnx2x *bp);
+
+/**
+ * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration.
+ *
+ * @bp: driver handle
+ * @mf_cfg: MF configuration
+ *
+ */
+static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg)
+{
+ u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
+ FUNC_MF_CFG_MAX_BW_SHIFT;
+ if (!max_cfg) {
+ DP(NETIF_MSG_IFUP | BNX2X_MSG_ETHTOOL,
+ "Max BW configured to 0 - using 100 instead\n");
+ max_cfg = 100;
+ }
+ return max_cfg;
+}
+
+/* checks if HW supports GRO for given MTU */
+static inline bool bnx2x_mtu_allows_gro(int mtu)
+{
+ /* gro frags per page */
+ int fpp = SGE_PAGE_SIZE / (mtu - ETH_MAX_TPA_HEADER_SIZE);
+
+ /*
+ * 1. Number of frags should not grow above MAX_SKB_FRAGS
+ * 2. Frag must fit the page
+ */
+ return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS;
+}
+
+/**
+ * bnx2x_get_iscsi_info - update iSCSI params according to licensing info.
+ *
+ * @bp: driver handle
+ *
+ */
+void bnx2x_get_iscsi_info(struct bnx2x *bp);
+
+/**
+ * bnx2x_link_sync_notify - send notification to other functions.
+ *
+ * @bp: driver handle
+ *
+ */
+static inline void bnx2x_link_sync_notify(struct bnx2x *bp)
+{
+ int func;
+ int vn;
+
+ /* Set the attention towards other drivers on the same port */
+ for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
+ if (vn == BP_VN(bp))
+ continue;
+
+ func = func_by_vn(bp, vn);
+ REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
+ (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
+ }
+}
+
+/**
+ * bnx2x_update_drv_flags - update flags in shmem
+ *
+ * @bp: driver handle
+ * @flags: flags to update
+ * @set: set or clear
+ *
+ */
+static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set)
+{
+ if (SHMEM2_HAS(bp, drv_flags)) {
+ u32 drv_flags;
+ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS);
+ drv_flags = SHMEM2_RD(bp, drv_flags);
+
+ if (set)
+ SET_FLAGS(drv_flags, flags);
+ else
+ RESET_FLAGS(drv_flags, flags);
+
+ SHMEM2_WR(bp, drv_flags, drv_flags);
+ DP(NETIF_MSG_IFUP, "drv_flags 0x%08x\n", drv_flags);
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS);
+ }
+}
+
+static inline bool bnx2x_is_valid_ether_addr(struct bnx2x *bp, u8 *addr)
+{
+ if (is_valid_ether_addr(addr) ||
+ (is_zero_ether_addr(addr) &&
+ (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))))
+ return true;
+
+ return false;
+}
+
+/**
+ * bnx2x_fill_fw_str - Fill buffer with FW version string
+ *
+ * @bp: driver handle
+ * @buf: character buffer to fill with the fw name
+ * @buf_len: length of the above buffer
+ *
+ */
+void bnx2x_fill_fw_str(struct bnx2x *bp, char *buf, size_t buf_len);
+
+int bnx2x_drain_tx_queues(struct bnx2x *bp);
+void bnx2x_squeeze_objects(struct bnx2x *bp);
+
+void bnx2x_schedule_sp_rtnl(struct bnx2x*, enum sp_rtnl_flag,
+ u32 verbose);
+
+#endif /* BNX2X_CMN_H */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
new file mode 100644
index 00000000000..51a952c51cb
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
@@ -0,0 +1,2555 @@
+/* bnx2x_dcb.c: Broadcom Everest network driver.
+ *
+ * Copyright 2009-2013 Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available
+ * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *
+ * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
+ * Written by: Dmitry Kravkov
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/rtnetlink.h>
+#include <net/dcbnl.h>
+
+#include "bnx2x.h"
+#include "bnx2x_cmn.h"
+#include "bnx2x_dcb.h"
+
+/* forward declarations of dcbx related functions */
+static void bnx2x_pfc_set_pfc(struct bnx2x *bp);
+static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp);
+static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
+ u32 *set_configuration_ets_pg,
+ u32 *pri_pg_tbl);
+static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp,
+ u32 *pg_pri_orginal_spread,
+ struct pg_help_data *help_data);
+static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp,
+ struct pg_help_data *help_data,
+ struct dcbx_ets_feature *ets,
+ u32 *pg_pri_orginal_spread);
+static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ struct dcbx_ets_feature *ets);
+static void bnx2x_dcbx_fw_struct(struct bnx2x *bp,
+ struct bnx2x_func_tx_start_params*);
+
+/* helpers: read/write len bytes from addr into buff by REG_RD/REG_WR */
+static void bnx2x_read_data(struct bnx2x *bp, u32 *buff,
+ u32 addr, u32 len)
+{
+ int i;
+ for (i = 0; i < len; i += 4, buff++)
+ *buff = REG_RD(bp, addr + i);
+}
+
+static void bnx2x_write_data(struct bnx2x *bp, u32 *buff,
+ u32 addr, u32 len)
+{
+ int i;
+ for (i = 0; i < len; i += 4, buff++)
+ REG_WR(bp, addr + i, *buff);
+}
+
+static void bnx2x_pfc_set(struct bnx2x *bp)
+{
+ struct bnx2x_nig_brb_pfc_port_params pfc_params = {0};
+ u32 pri_bit, val = 0;
+ int i;
+
+ pfc_params.num_of_rx_cos_priority_mask =
+ bp->dcbx_port_params.ets.num_of_cos;
+
+ /* Tx COS configuration */
+ for (i = 0; i < bp->dcbx_port_params.ets.num_of_cos; i++)
+ /*
+ * We configure only the pauseable bits (non pauseable aren't
+ * configured at all) it's done to avoid false pauses from
+ * network
+ */
+ pfc_params.rx_cos_priority_mask[i] =
+ bp->dcbx_port_params.ets.cos_params[i].pri_bitmask
+ & DCBX_PFC_PRI_PAUSE_MASK(bp);
+
+ /*
+ * Rx COS configuration
+ * Changing PFC RX configuration .
+ * In RX COS0 will always be configured to lossless and COS1 to lossy
+ */
+ for (i = 0 ; i < MAX_PFC_PRIORITIES ; i++) {
+ pri_bit = 1 << i;
+
+ if (!(pri_bit & DCBX_PFC_PRI_PAUSE_MASK(bp)))
+ val |= 1 << (i * 4);
+ }
+
+ pfc_params.pkt_priority_to_cos = val;
+
+ /* RX COS0 */
+ pfc_params.llfc_low_priority_classes = DCBX_PFC_PRI_PAUSE_MASK(bp);
+ /* RX COS1 */
+ pfc_params.llfc_high_priority_classes = 0;
+
+ bnx2x_acquire_phy_lock(bp);
+ bp->link_params.feature_config_flags |= FEATURE_CONFIG_PFC_ENABLED;
+ bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &pfc_params);
+ bnx2x_release_phy_lock(bp);
+}
+
+static void bnx2x_pfc_clear(struct bnx2x *bp)
+{
+ struct bnx2x_nig_brb_pfc_port_params nig_params = {0};
+ nig_params.pause_enable = 1;
+ bnx2x_acquire_phy_lock(bp);
+ bp->link_params.feature_config_flags &= ~FEATURE_CONFIG_PFC_ENABLED;
+ bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &nig_params);
+ bnx2x_release_phy_lock(bp);
+}
+
+static void bnx2x_dump_dcbx_drv_param(struct bnx2x *bp,
+ struct dcbx_features *features,
+ u32 error)
+{
+ u8 i = 0;
+ DP(NETIF_MSG_LINK, "local_mib.error %x\n", error);
+
+ /* PG */
+ DP(NETIF_MSG_LINK,
+ "local_mib.features.ets.enabled %x\n", features->ets.enabled);
+ for (i = 0; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++)
+ DP(NETIF_MSG_LINK,
+ "local_mib.features.ets.pg_bw_tbl[%d] %d\n", i,
+ DCBX_PG_BW_GET(features->ets.pg_bw_tbl, i));
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++)
+ DP(NETIF_MSG_LINK,
+ "local_mib.features.ets.pri_pg_tbl[%d] %d\n", i,
+ DCBX_PRI_PG_GET(features->ets.pri_pg_tbl, i));
+
+ /* pfc */
+ DP(BNX2X_MSG_DCB, "dcbx_features.pfc.pri_en_bitmap %x\n",
+ features->pfc.pri_en_bitmap);
+ DP(BNX2X_MSG_DCB, "dcbx_features.pfc.pfc_caps %x\n",
+ features->pfc.pfc_caps);
+ DP(BNX2X_MSG_DCB, "dcbx_features.pfc.enabled %x\n",
+ features->pfc.enabled);
+
+ DP(BNX2X_MSG_DCB, "dcbx_features.app.default_pri %x\n",
+ features->app.default_pri);
+ DP(BNX2X_MSG_DCB, "dcbx_features.app.tc_supported %x\n",
+ features->app.tc_supported);
+ DP(BNX2X_MSG_DCB, "dcbx_features.app.enabled %x\n",
+ features->app.enabled);
+ for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
+ DP(BNX2X_MSG_DCB,
+ "dcbx_features.app.app_pri_tbl[%x].app_id %x\n",
+ i, features->app.app_pri_tbl[i].app_id);
+ DP(BNX2X_MSG_DCB,
+ "dcbx_features.app.app_pri_tbl[%x].pri_bitmap %x\n",
+ i, features->app.app_pri_tbl[i].pri_bitmap);
+ DP(BNX2X_MSG_DCB,
+ "dcbx_features.app.app_pri_tbl[%x].appBitfield %x\n",
+ i, features->app.app_pri_tbl[i].appBitfield);
+ }
+}
+
+static void bnx2x_dcbx_get_ap_priority(struct bnx2x *bp,
+ u8 pri_bitmap,
+ u8 llfc_traf_type)
+{
+ u32 pri = MAX_PFC_PRIORITIES;
+ u32 index = MAX_PFC_PRIORITIES - 1;
+ u32 pri_mask;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+
+ /* Choose the highest priority */
+ while ((MAX_PFC_PRIORITIES == pri) && (0 != index)) {
+ pri_mask = 1 << index;
+ if (GET_FLAGS(pri_bitmap, pri_mask))
+ pri = index ;
+ index--;
+ }
+
+ if (pri < MAX_PFC_PRIORITIES)
+ ttp[llfc_traf_type] = max_t(u32, ttp[llfc_traf_type], pri);
+}
+
+static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp,
+ struct dcbx_app_priority_feature *app,
+ u32 error) {
+ u8 index;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+
+ if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR))
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_APP_ERROR\n");
+
+ if (GET_FLAGS(error, DCBX_LOCAL_APP_MISMATCH))
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_APP_MISMATCH\n");
+
+ if (GET_FLAGS(error, DCBX_REMOTE_APP_TLV_NOT_FOUND))
+ DP(BNX2X_MSG_DCB, "DCBX_REMOTE_APP_TLV_NOT_FOUND\n");
+ if (app->enabled &&
+ !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR | DCBX_LOCAL_APP_MISMATCH |
+ DCBX_REMOTE_APP_TLV_NOT_FOUND)) {
+
+ bp->dcbx_port_params.app.enabled = true;
+
+ for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++)
+ ttp[index] = 0;
+
+ if (app->default_pri < MAX_PFC_PRIORITIES)
+ ttp[LLFC_TRAFFIC_TYPE_NW] = app->default_pri;
+
+ for (index = 0 ; index < DCBX_MAX_APP_PROTOCOL; index++) {
+ struct dcbx_app_priority_entry *entry =
+ app->app_pri_tbl;
+
+ if (GET_FLAGS(entry[index].appBitfield,
+ DCBX_APP_SF_ETH_TYPE) &&
+ ETH_TYPE_FCOE == entry[index].app_id)
+ bnx2x_dcbx_get_ap_priority(bp,
+ entry[index].pri_bitmap,
+ LLFC_TRAFFIC_TYPE_FCOE);
+
+ if (GET_FLAGS(entry[index].appBitfield,
+ DCBX_APP_SF_PORT) &&
+ TCP_PORT_ISCSI == entry[index].app_id)
+ bnx2x_dcbx_get_ap_priority(bp,
+ entry[index].pri_bitmap,
+ LLFC_TRAFFIC_TYPE_ISCSI);
+ }
+ } else {
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_APP_DISABLED\n");
+ bp->dcbx_port_params.app.enabled = false;
+ for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++)
+ ttp[index] = INVALID_TRAFFIC_TYPE_PRIORITY;
+ }
+}
+
+static void bnx2x_dcbx_get_ets_feature(struct bnx2x *bp,
+ struct dcbx_ets_feature *ets,
+ u32 error) {
+ int i = 0;
+ u32 pg_pri_orginal_spread[DCBX_MAX_NUM_PG_BW_ENTRIES] = {0};
+ struct pg_help_data pg_help_data;
+ struct bnx2x_dcbx_cos_params *cos_params =
+ bp->dcbx_port_params.ets.cos_params;
+
+ memset(&pg_help_data, 0, sizeof(struct pg_help_data));
+
+ if (GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR))
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_ETS_ERROR\n");
+
+ if (GET_FLAGS(error, DCBX_REMOTE_ETS_TLV_NOT_FOUND))
+ DP(BNX2X_MSG_DCB, "DCBX_REMOTE_ETS_TLV_NOT_FOUND\n");
+
+ /* Clean up old settings of ets on COS */
+ for (i = 0; i < ARRAY_SIZE(bp->dcbx_port_params.ets.cos_params) ; i++) {
+ cos_params[i].pauseable = false;
+ cos_params[i].strict = BNX2X_DCBX_STRICT_INVALID;
+ cos_params[i].bw_tbl = DCBX_INVALID_COS_BW;
+ cos_params[i].pri_bitmask = 0;
+ }
+
+ if (bp->dcbx_port_params.app.enabled && ets->enabled &&
+ !GET_FLAGS(error,
+ DCBX_LOCAL_ETS_ERROR | DCBX_REMOTE_ETS_TLV_NOT_FOUND)) {
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_ETS_ENABLE\n");
+ bp->dcbx_port_params.ets.enabled = true;
+
+ bnx2x_dcbx_get_ets_pri_pg_tbl(bp,
+ pg_pri_orginal_spread,
+ ets->pri_pg_tbl);
+
+ bnx2x_dcbx_get_num_pg_traf_type(bp,
+ pg_pri_orginal_spread,
+ &pg_help_data);
+
+ bnx2x_dcbx_fill_cos_params(bp, &pg_help_data,
+ ets, pg_pri_orginal_spread);
+
+ } else {
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_ETS_DISABLED\n");
+ bp->dcbx_port_params.ets.enabled = false;
+ ets->pri_pg_tbl[0] = 0;
+
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES ; i++)
+ DCBX_PG_BW_SET(ets->pg_bw_tbl, i, 1);
+ }
+}
+
+static void bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp,
+ struct dcbx_pfc_feature *pfc, u32 error)
+{
+ if (GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR))
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_PFC_ERROR\n");
+
+ if (GET_FLAGS(error, DCBX_REMOTE_PFC_TLV_NOT_FOUND))
+ DP(BNX2X_MSG_DCB, "DCBX_REMOTE_PFC_TLV_NOT_FOUND\n");
+ if (bp->dcbx_port_params.app.enabled && pfc->enabled &&
+ !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR | DCBX_LOCAL_PFC_MISMATCH |
+ DCBX_REMOTE_PFC_TLV_NOT_FOUND)) {
+ bp->dcbx_port_params.pfc.enabled = true;
+ bp->dcbx_port_params.pfc.priority_non_pauseable_mask =
+ ~(pfc->pri_en_bitmap);
+ } else {
+ DP(BNX2X_MSG_DCB, "DCBX_LOCAL_PFC_DISABLED\n");
+ bp->dcbx_port_params.pfc.enabled = false;
+ bp->dcbx_port_params.pfc.priority_non_pauseable_mask = 0;
+ }
+}
+
+/* maps unmapped priorities to to the same COS as L2 */
+static void bnx2x_dcbx_map_nw(struct bnx2x *bp)
+{
+ int i;
+ u32 unmapped = (1 << MAX_PFC_PRIORITIES) - 1; /* all ones */
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+ u32 nw_prio = 1 << ttp[LLFC_TRAFFIC_TYPE_NW];
+ struct bnx2x_dcbx_cos_params *cos_params =
+ bp->dcbx_port_params.ets.cos_params;
+
+ /* get unmapped priorities by clearing mapped bits */
+ for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++)
+ unmapped &= ~(1 << ttp[i]);
+
+ /* find cos for nw prio and extend it with unmapped */
+ for (i = 0; i < ARRAY_SIZE(bp->dcbx_port_params.ets.cos_params); i++) {
+ if (cos_params[i].pri_bitmask & nw_prio) {
+ /* extend the bitmask with unmapped */
+ DP(BNX2X_MSG_DCB,
+ "cos %d extended with 0x%08x\n", i, unmapped);
+ cos_params[i].pri_bitmask |= unmapped;
+ break;
+ }
+ }
+}
+
+static void bnx2x_get_dcbx_drv_param(struct bnx2x *bp,
+ struct dcbx_features *features,
+ u32 error)
+{
+ bnx2x_dcbx_get_ap_feature(bp, &features->app, error);
+
+ bnx2x_dcbx_get_pfc_feature(bp, &features->pfc, error);
+
+ bnx2x_dcbx_get_ets_feature(bp, &features->ets, error);
+
+ bnx2x_dcbx_map_nw(bp);
+}
+
+#define DCBX_LOCAL_MIB_MAX_TRY_READ (100)
+static int bnx2x_dcbx_read_mib(struct bnx2x *bp,
+ u32 *base_mib_addr,
+ u32 offset,
+ int read_mib_type)
+{
+ int max_try_read = 0;
+ u32 mib_size, prefix_seq_num, suffix_seq_num;
+ struct lldp_remote_mib *remote_mib ;
+ struct lldp_local_mib *local_mib;
+
+ switch (read_mib_type) {
+ case DCBX_READ_LOCAL_MIB:
+ mib_size = sizeof(struct lldp_local_mib);
+ break;
+ case DCBX_READ_REMOTE_MIB:
+ mib_size = sizeof(struct lldp_remote_mib);
+ break;
+ default:
+ return 1; /*error*/
+ }
+
+ offset += BP_PORT(bp) * mib_size;
+
+ do {
+ bnx2x_read_data(bp, base_mib_addr, offset, mib_size);
+
+ max_try_read++;
+
+ switch (read_mib_type) {
+ case DCBX_READ_LOCAL_MIB:
+ local_mib = (struct lldp_local_mib *) base_mib_addr;
+ prefix_seq_num = local_mib->prefix_seq_num;
+ suffix_seq_num = local_mib->suffix_seq_num;
+ break;
+ case DCBX_READ_REMOTE_MIB:
+ remote_mib = (struct lldp_remote_mib *) base_mib_addr;
+ prefix_seq_num = remote_mib->prefix_seq_num;
+ suffix_seq_num = remote_mib->suffix_seq_num;
+ break;
+ default:
+ return 1; /*error*/
+ }
+ } while ((prefix_seq_num != suffix_seq_num) &&
+ (max_try_read < DCBX_LOCAL_MIB_MAX_TRY_READ));
+
+ if (max_try_read >= DCBX_LOCAL_MIB_MAX_TRY_READ) {
+ BNX2X_ERR("MIB could not be read\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static void bnx2x_pfc_set_pfc(struct bnx2x *bp)
+{
+ int mfw_configured = SHMEM2_HAS(bp, drv_flags) &&
+ GET_FLAGS(SHMEM2_RD(bp, drv_flags),
+ 1 << DRV_FLAGS_DCB_MFW_CONFIGURED);
+
+ if (bp->dcbx_port_params.pfc.enabled &&
+ (!(bp->dcbx_error & DCBX_REMOTE_MIB_ERROR) || mfw_configured))
+ /*
+ * 1. Fills up common PFC structures if required
+ * 2. Configure NIG, MAC and BRB via the elink
+ */
+ bnx2x_pfc_set(bp);
+ else
+ bnx2x_pfc_clear(bp);
+}
+
+int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp)
+{
+ struct bnx2x_func_state_params func_params = {NULL};
+ int rc;
+
+ func_params.f_obj = &bp->func_obj;
+ func_params.cmd = BNX2X_F_CMD_TX_STOP;
+
+ __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
+ __set_bit(RAMROD_RETRY, &func_params.ramrod_flags);
+
+ DP(BNX2X_MSG_DCB, "STOP TRAFFIC\n");
+
+ rc = bnx2x_func_state_change(bp, &func_params);
+ if (rc) {
+ BNX2X_ERR("Unable to hold traffic for HW configuration\n");
+ bnx2x_panic();
+ }
+
+ return rc;
+}
+
+int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp)
+{
+ struct bnx2x_func_state_params func_params = {NULL};
+ struct bnx2x_func_tx_start_params *tx_params =
+ &func_params.params.tx_start;
+ int rc;
+
+ func_params.f_obj = &bp->func_obj;
+ func_params.cmd = BNX2X_F_CMD_TX_START;
+
+ __set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
+ __set_bit(RAMROD_RETRY, &func_params.ramrod_flags);
+
+ bnx2x_dcbx_fw_struct(bp, tx_params);
+
+ DP(BNX2X_MSG_DCB, "START TRAFFIC\n");
+
+ rc = bnx2x_func_state_change(bp, &func_params);
+ if (rc) {
+ BNX2X_ERR("Unable to resume traffic after HW configuration\n");
+ bnx2x_panic();
+ }
+
+ return rc;
+}
+
+static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp)
+{
+ struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets);
+ int rc = 0;
+
+ if (ets->num_of_cos == 0 || ets->num_of_cos > DCBX_COS_MAX_NUM_E2) {
+ BNX2X_ERR("Illegal number of COSes %d\n", ets->num_of_cos);
+ return;
+ }
+
+ /* valid COS entries */
+ if (ets->num_of_cos == 1) /* no ETS */
+ return;
+
+ /* sanity */
+ if (((BNX2X_DCBX_STRICT_INVALID == ets->cos_params[0].strict) &&
+ (DCBX_INVALID_COS_BW == ets->cos_params[0].bw_tbl)) ||
+ ((BNX2X_DCBX_STRICT_INVALID == ets->cos_params[1].strict) &&
+ (DCBX_INVALID_COS_BW == ets->cos_params[1].bw_tbl))) {
+ BNX2X_ERR("all COS should have at least bw_limit or strict"
+ "ets->cos_params[0].strict= %x"
+ "ets->cos_params[0].bw_tbl= %x"
+ "ets->cos_params[1].strict= %x"
+ "ets->cos_params[1].bw_tbl= %x",
+ ets->cos_params[0].strict,
+ ets->cos_params[0].bw_tbl,
+ ets->cos_params[1].strict,
+ ets->cos_params[1].bw_tbl);
+ return;
+ }
+ /* If we join a group and there is bw_tbl and strict then bw rules */
+ if ((DCBX_INVALID_COS_BW != ets->cos_params[0].bw_tbl) &&
+ (DCBX_INVALID_COS_BW != ets->cos_params[1].bw_tbl)) {
+ u32 bw_tbl_0 = ets->cos_params[0].bw_tbl;
+ u32 bw_tbl_1 = ets->cos_params[1].bw_tbl;
+ /* Do not allow 0-100 configuration
+ * since PBF does not support it
+ * force 1-99 instead
+ */
+ if (bw_tbl_0 == 0) {
+ bw_tbl_0 = 1;
+ bw_tbl_1 = 99;
+ } else if (bw_tbl_1 == 0) {
+ bw_tbl_1 = 1;
+ bw_tbl_0 = 99;
+ }
+
+ bnx2x_ets_bw_limit(&bp->link_params, bw_tbl_0, bw_tbl_1);
+ } else {
+ if (ets->cos_params[0].strict == BNX2X_DCBX_STRICT_COS_HIGHEST)
+ rc = bnx2x_ets_strict(&bp->link_params, 0);
+ else if (ets->cos_params[1].strict
+ == BNX2X_DCBX_STRICT_COS_HIGHEST)
+ rc = bnx2x_ets_strict(&bp->link_params, 1);
+ if (rc)
+ BNX2X_ERR("update_ets_params failed\n");
+ }
+}
+
+/*
+ * In E3B0 the configuration may have more than 2 COS.
+ */
+static void bnx2x_dcbx_update_ets_config(struct bnx2x *bp)
+{
+ struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets);
+ struct bnx2x_ets_params ets_params = { 0 };
+ u8 i;
+
+ ets_params.num_of_cos = ets->num_of_cos;
+
+ for (i = 0; i < ets->num_of_cos; i++) {
+ /* COS is SP */
+ if (ets->cos_params[i].strict != BNX2X_DCBX_STRICT_INVALID) {
+ if (ets->cos_params[i].bw_tbl != DCBX_INVALID_COS_BW) {
+ BNX2X_ERR("COS can't be not BW and not SP\n");
+ return;
+ }
+
+ ets_params.cos[i].state = bnx2x_cos_state_strict;
+ ets_params.cos[i].params.sp_params.pri =
+ ets->cos_params[i].strict;
+ } else { /* COS is BW */
+ if (ets->cos_params[i].bw_tbl == DCBX_INVALID_COS_BW) {
+ BNX2X_ERR("COS can't be not BW and not SP\n");
+ return;
+ }
+ ets_params.cos[i].state = bnx2x_cos_state_bw;
+ ets_params.cos[i].params.bw_params.bw =
+ (u8)ets->cos_params[i].bw_tbl;
+ }
+ }
+
+ /* Configure the ETS in HW */
+ if (bnx2x_ets_e3b0_config(&bp->link_params, &bp->link_vars,
+ &ets_params)) {
+ BNX2X_ERR("bnx2x_ets_e3b0_config failed\n");
+ bnx2x_ets_disabled(&bp->link_params, &bp->link_vars);
+ }
+}
+
+static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp)
+{
+ int mfw_configured = SHMEM2_HAS(bp, drv_flags) &&
+ GET_FLAGS(SHMEM2_RD(bp, drv_flags),
+ 1 << DRV_FLAGS_DCB_MFW_CONFIGURED);
+
+ bnx2x_ets_disabled(&bp->link_params, &bp->link_vars);
+
+ if (!bp->dcbx_port_params.ets.enabled ||
+ ((bp->dcbx_error & DCBX_REMOTE_MIB_ERROR) && !mfw_configured))
+ return;
+
+ if (CHIP_IS_E3B0(bp))
+ bnx2x_dcbx_update_ets_config(bp);
+ else
+ bnx2x_dcbx_2cos_limit_update_ets_config(bp);
+}
+
+#ifdef BCM_DCBNL
+static int bnx2x_dcbx_read_shmem_remote_mib(struct bnx2x *bp)
+{
+ struct lldp_remote_mib remote_mib = {0};
+ u32 dcbx_remote_mib_offset = SHMEM2_RD(bp, dcbx_remote_mib_offset);
+ int rc;
+
+ DP(BNX2X_MSG_DCB, "dcbx_remote_mib_offset 0x%x\n",
+ dcbx_remote_mib_offset);
+
+ if (SHMEM_DCBX_REMOTE_MIB_NONE == dcbx_remote_mib_offset) {
+ BNX2X_ERR("FW doesn't support dcbx_remote_mib_offset\n");
+ return -EINVAL;
+ }
+
+ rc = bnx2x_dcbx_read_mib(bp, (u32 *)&remote_mib, dcbx_remote_mib_offset,
+ DCBX_READ_REMOTE_MIB);
+
+ if (rc) {
+ BNX2X_ERR("Failed to read remote mib from FW\n");
+ return rc;
+ }
+
+ /* save features and flags */
+ bp->dcbx_remote_feat = remote_mib.features;
+ bp->dcbx_remote_flags = remote_mib.flags;
+ return 0;
+}
+#endif
+
+static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
+{
+ struct lldp_local_mib local_mib = {0};
+ u32 dcbx_neg_res_offset = SHMEM2_RD(bp, dcbx_neg_res_offset);
+ int rc;
+
+ DP(BNX2X_MSG_DCB, "dcbx_neg_res_offset 0x%x\n", dcbx_neg_res_offset);
+
+ if (SHMEM_DCBX_NEG_RES_NONE == dcbx_neg_res_offset) {
+ BNX2X_ERR("FW doesn't support dcbx_neg_res_offset\n");
+ return -EINVAL;
+ }
+
+ rc = bnx2x_dcbx_read_mib(bp, (u32 *)&local_mib, dcbx_neg_res_offset,
+ DCBX_READ_LOCAL_MIB);
+
+ if (rc) {
+ BNX2X_ERR("Failed to read local mib from FW\n");
+ return rc;
+ }
+
+ /* save features and error */
+ bp->dcbx_local_feat = local_mib.features;
+ bp->dcbx_error = local_mib.error;
+ return 0;
+}
+
+#ifdef BCM_DCBNL
+static inline
+u8 bnx2x_dcbx_dcbnl_app_up(struct dcbx_app_priority_entry *ent)
+{
+ u8 pri;
+
+ /* Choose the highest priority */
+ for (pri = MAX_PFC_PRIORITIES - 1; pri > 0; pri--)
+ if (ent->pri_bitmap & (1 << pri))
+ break;
+ return pri;
+}
+
+static inline
+u8 bnx2x_dcbx_dcbnl_app_idtype(struct dcbx_app_priority_entry *ent)
+{
+ return ((ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) ==
+ DCBX_APP_SF_PORT) ? DCB_APP_IDTYPE_PORTNUM :
+ DCB_APP_IDTYPE_ETHTYPE;
+}
+
+int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall)
+{
+ int i, err = 0;
+
+ for (i = 0; i < DCBX_MAX_APP_PROTOCOL && err == 0; i++) {
+ struct dcbx_app_priority_entry *ent =
+ &bp->dcbx_local_feat.app.app_pri_tbl[i];
+
+ if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
+ u8 up = bnx2x_dcbx_dcbnl_app_up(ent);
+
+ /* avoid invalid user-priority */
+ if (up) {
+ struct dcb_app app;
+ app.selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
+ app.protocol = ent->app_id;
+ app.priority = delall ? 0 : up;
+ err = dcb_setapp(bp->dev, &app);
+ }
+ }
+ }
+ return err;
+}
+#endif
+
+static inline void bnx2x_dcbx_update_tc_mapping(struct bnx2x *bp)
+{
+ u8 prio, cos;
+ for (cos = 0; cos < bp->dcbx_port_params.ets.num_of_cos; cos++) {
+ for (prio = 0; prio < BNX2X_MAX_PRIORITY; prio++) {
+ if (bp->dcbx_port_params.ets.cos_params[cos].pri_bitmask
+ & (1 << prio)) {
+ bp->prio_to_cos[prio] = cos;
+ DP(BNX2X_MSG_DCB,
+ "tx_mapping %d --> %d\n", prio, cos);
+ }
+ }
+ }
+
+ /* setup tc must be called under rtnl lock, but we can't take it here
+ * as we are handling an attention on a work queue which must be
+ * flushed at some rtnl-locked contexts (e.g. if down)
+ */
+ bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_SETUP_TC, 0);
+}
+
+void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
+{
+ switch (state) {
+ case BNX2X_DCBX_STATE_NEG_RECEIVED:
+ {
+ DP(BNX2X_MSG_DCB, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
+#ifdef BCM_DCBNL
+ /**
+ * Delete app tlvs from dcbnl before reading new
+ * negotiation results
+ */
+ bnx2x_dcbnl_update_applist(bp, true);
+
+ /* Read remote mib if dcbx is in the FW */
+ if (bnx2x_dcbx_read_shmem_remote_mib(bp))
+ return;
+#endif
+ /* Read neg results if dcbx is in the FW */
+ if (bnx2x_dcbx_read_shmem_neg_results(bp))
+ return;
+
+ bnx2x_dump_dcbx_drv_param(bp, &bp->dcbx_local_feat,
+ bp->dcbx_error);
+
+ bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat,
+ bp->dcbx_error);
+
+ /* mark DCBX result for PMF migration */
+ bnx2x_update_drv_flags(bp,
+ 1 << DRV_FLAGS_DCB_CONFIGURED,
+ 1);
+#ifdef BCM_DCBNL
+ /*
+ * Add new app tlvs to dcbnl
+ */
+ bnx2x_dcbnl_update_applist(bp, false);
+#endif
+ /*
+ * reconfigure the netdevice with the results of the new
+ * dcbx negotiation.
+ */
+ bnx2x_dcbx_update_tc_mapping(bp);
+
+ /*
+ * allow other functions to update their netdevices
+ * accordingly
+ */
+ if (IS_MF(bp))
+ bnx2x_link_sync_notify(bp);
+
+ bnx2x_schedule_sp_rtnl(bp, BNX2X_SP_RTNL_TX_STOP, 0);
+ return;
+ }
+ case BNX2X_DCBX_STATE_TX_PAUSED:
+ DP(BNX2X_MSG_DCB, "BNX2X_DCBX_STATE_TX_PAUSED\n");
+ bnx2x_pfc_set_pfc(bp);
+
+ bnx2x_dcbx_update_ets_params(bp);
+
+ /* ets may affect cmng configuration: reinit it in hw */
+ bnx2x_set_local_cmng(bp);
+ return;
+ case BNX2X_DCBX_STATE_TX_RELEASED:
+ DP(BNX2X_MSG_DCB, "BNX2X_DCBX_STATE_TX_RELEASED\n");
+ bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0);
+#ifdef BCM_DCBNL
+ /*
+ * Send a notification for the new negotiated parameters
+ */
+ dcbnl_cee_notify(bp->dev, RTM_GETDCB, DCB_CMD_CEE_GET, 0, 0);
+#endif
+ return;
+ default:
+ BNX2X_ERR("Unknown DCBX_STATE\n");
+ }
+}
+
+#define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \
+ BP_PORT(bp)*sizeof(struct lldp_admin_mib))
+
+static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp,
+ u32 dcbx_lldp_params_offset)
+{
+ struct lldp_admin_mib admin_mib;
+ u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0;
+ u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp);
+
+ /*shortcuts*/
+ struct dcbx_features *af = &admin_mib.features;
+ struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params;
+
+ memset(&admin_mib, 0, sizeof(struct lldp_admin_mib));
+
+ /* Read the data first */
+ bnx2x_read_data(bp, (u32 *)&admin_mib, offset,
+ sizeof(struct lldp_admin_mib));
+
+ if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED);
+
+ if (dp->overwrite_settings == BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE) {
+
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK);
+ admin_mib.ver_cfg_flags |=
+ (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) &
+ DCBX_CEE_VERSION_MASK;
+
+ af->ets.enabled = (u8)dp->admin_ets_enable;
+
+ af->pfc.enabled = (u8)dp->admin_pfc_enable;
+
+ /* FOR IEEE dp->admin_tc_supported_tx_enable */
+ if (dp->admin_ets_configuration_tx_enable)
+ SET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_ETS_CONFIG_TX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_ETS_CONFIG_TX_ENABLED);
+ /* For IEEE admin_ets_recommendation_tx_enable */
+ if (dp->admin_pfc_tx_enable)
+ SET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_PFC_CONFIG_TX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_PFC_CONFIG_TX_ENABLED);
+
+ if (dp->admin_application_priority_tx_enable)
+ SET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_APP_CONFIG_TX_ENABLED);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags,
+ DCBX_APP_CONFIG_TX_ENABLED);
+
+ if (dp->admin_ets_willing)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING);
+ /* For IEEE admin_ets_reco_valid */
+ if (dp->admin_pfc_willing)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING);
+
+ if (dp->admin_app_priority_willing)
+ SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING);
+ else
+ RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING);
+
+ for (i = 0 ; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++) {
+ DCBX_PG_BW_SET(af->ets.pg_bw_tbl, i,
+ (u8)dp->admin_configuration_bw_precentage[i]);
+
+ DP(BNX2X_MSG_DCB, "pg_bw_tbl[%d] = %02x\n",
+ i, DCBX_PG_BW_GET(af->ets.pg_bw_tbl, i));
+ }
+
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) {
+ DCBX_PRI_PG_SET(af->ets.pri_pg_tbl, i,
+ (u8)dp->admin_configuration_ets_pg[i]);
+
+ DP(BNX2X_MSG_DCB, "pri_pg_tbl[%d] = %02x\n",
+ i, DCBX_PRI_PG_GET(af->ets.pri_pg_tbl, i));
+ }
+
+ /*For IEEE admin_recommendation_bw_percentage
+ *For IEEE admin_recommendation_ets_pg */
+ af->pfc.pri_en_bitmap = (u8)dp->admin_pfc_bitmap;
+ for (i = 0; i < DCBX_CONFIG_MAX_APP_PROTOCOL; i++) {
+ if (dp->admin_priority_app_table[i].valid) {
+ struct bnx2x_admin_priority_app_table *table =
+ dp->admin_priority_app_table;
+ if ((ETH_TYPE_FCOE == table[i].app_id) &&
+ (TRAFFIC_TYPE_ETH == table[i].traffic_type))
+ traf_type = FCOE_APP_IDX;
+ else if ((TCP_PORT_ISCSI == table[i].app_id) &&
+ (TRAFFIC_TYPE_PORT == table[i].traffic_type))
+ traf_type = ISCSI_APP_IDX;
+ else
+ traf_type = other_traf_type++;
+
+ af->app.app_pri_tbl[traf_type].app_id =
+ table[i].app_id;
+
+ af->app.app_pri_tbl[traf_type].pri_bitmap =
+ (u8)(1 << table[i].priority);
+
+ af->app.app_pri_tbl[traf_type].appBitfield =
+ (DCBX_APP_ENTRY_VALID);
+
+ af->app.app_pri_tbl[traf_type].appBitfield |=
+ (TRAFFIC_TYPE_ETH == table[i].traffic_type) ?
+ DCBX_APP_SF_ETH_TYPE : DCBX_APP_SF_PORT;
+ }
+ }
+
+ af->app.default_pri = (u8)dp->admin_default_priority;
+ }
+
+ /* Write the data. */
+ bnx2x_write_data(bp, (u32 *)&admin_mib, offset,
+ sizeof(struct lldp_admin_mib));
+}
+
+void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled)
+{
+ if (!CHIP_IS_E1x(bp)) {
+ bp->dcb_state = dcb_on;
+ bp->dcbx_enabled = dcbx_enabled;
+ } else {
+ bp->dcb_state = false;
+ bp->dcbx_enabled = BNX2X_DCBX_ENABLED_INVALID;
+ }
+ DP(BNX2X_MSG_DCB, "DCB state [%s:%s]\n",
+ dcb_on ? "ON" : "OFF",
+ dcbx_enabled == BNX2X_DCBX_ENABLED_OFF ? "user-mode" :
+ dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF ? "on-chip static" :
+ dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON ?
+ "on-chip with negotiation" : "invalid");
+}
+
+void bnx2x_dcbx_init_params(struct bnx2x *bp)
+{
+ bp->dcbx_config_params.admin_dcbx_version = 0x0; /* 0 - CEE; 1 - IEEE */
+ bp->dcbx_config_params.admin_ets_willing = 1;
+ bp->dcbx_config_params.admin_pfc_willing = 1;
+ bp->dcbx_config_params.overwrite_settings = 1;
+ bp->dcbx_config_params.admin_ets_enable = 1;
+ bp->dcbx_config_params.admin_pfc_enable = 1;
+ bp->dcbx_config_params.admin_tc_supported_tx_enable = 1;
+ bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1;
+ bp->dcbx_config_params.admin_pfc_tx_enable = 1;
+ bp->dcbx_config_params.admin_application_priority_tx_enable = 1;
+ bp->dcbx_config_params.admin_ets_reco_valid = 1;
+ bp->dcbx_config_params.admin_app_priority_willing = 1;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[0] = 100;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[1] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[2] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[3] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[4] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[5] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[6] = 0;
+ bp->dcbx_config_params.admin_configuration_bw_precentage[7] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[0] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[1] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[2] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[3] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[4] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[5] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[6] = 0;
+ bp->dcbx_config_params.admin_configuration_ets_pg[7] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[0] = 100;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[1] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[2] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[3] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[4] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[5] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[6] = 0;
+ bp->dcbx_config_params.admin_recommendation_bw_precentage[7] = 0;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[0] = 0;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[1] = 1;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[2] = 2;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[3] = 3;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[4] = 4;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[5] = 5;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[6] = 6;
+ bp->dcbx_config_params.admin_recommendation_ets_pg[7] = 7;
+ bp->dcbx_config_params.admin_pfc_bitmap = 0x0;
+ bp->dcbx_config_params.admin_priority_app_table[0].valid = 0;
+ bp->dcbx_config_params.admin_priority_app_table[1].valid = 0;
+ bp->dcbx_config_params.admin_priority_app_table[2].valid = 0;
+ bp->dcbx_config_params.admin_priority_app_table[3].valid = 0;
+ bp->dcbx_config_params.admin_default_priority = 0;
+}
+
+void bnx2x_dcbx_init(struct bnx2x *bp, bool update_shmem)
+{
+ u32 dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE;
+
+ /* only PMF can send ADMIN msg to MFW in old MFW versions */
+ if ((!bp->port.pmf) && (!(bp->flags & BC_SUPPORTS_DCBX_MSG_NON_PMF)))
+ return;
+
+ if (bp->dcbx_enabled <= 0)
+ return;
+
+ /* validate:
+ * chip of good for dcbx version,
+ * dcb is wanted
+ * shmem2 contains DCBX support fields
+ */
+ DP(BNX2X_MSG_DCB, "dcb_state %d bp->port.pmf %d\n",
+ bp->dcb_state, bp->port.pmf);
+
+ if (bp->dcb_state == BNX2X_DCB_STATE_ON &&
+ SHMEM2_HAS(bp, dcbx_lldp_params_offset)) {
+ dcbx_lldp_params_offset =
+ SHMEM2_RD(bp, dcbx_lldp_params_offset);
+
+ DP(BNX2X_MSG_DCB, "dcbx_lldp_params_offset 0x%x\n",
+ dcbx_lldp_params_offset);
+
+ bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0);
+
+ if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) {
+ /* need HW lock to avoid scenario of two drivers
+ * writing in parallel to shmem
+ */
+ bnx2x_acquire_hw_lock(bp,
+ HW_LOCK_RESOURCE_DCBX_ADMIN_MIB);
+ if (update_shmem)
+ bnx2x_dcbx_admin_mib_updated_params(bp,
+ dcbx_lldp_params_offset);
+
+ /* Let HW start negotiation */
+ bnx2x_fw_command(bp,
+ DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 0);
+ /* release HW lock only after MFW acks that it finished
+ * reading values from shmem
+ */
+ bnx2x_release_hw_lock(bp,
+ HW_LOCK_RESOURCE_DCBX_ADMIN_MIB);
+ }
+ }
+}
+static void
+bnx2x_dcbx_print_cos_params(struct bnx2x *bp,
+ struct bnx2x_func_tx_start_params *pfc_fw_cfg)
+{
+ u8 pri = 0;
+ u8 cos = 0;
+
+ DP(BNX2X_MSG_DCB,
+ "pfc_fw_cfg->dcb_version %x\n", pfc_fw_cfg->dcb_version);
+ DP(BNX2X_MSG_DCB,
+ "pdev->params.dcbx_port_params.pfc.priority_non_pauseable_mask %x\n",
+ bp->dcbx_port_params.pfc.priority_non_pauseable_mask);
+
+ for (cos = 0 ; cos < bp->dcbx_port_params.ets.num_of_cos ; cos++) {
+ DP(BNX2X_MSG_DCB,
+ "pdev->params.dcbx_port_params.ets.cos_params[%d].pri_bitmask %x\n",
+ cos, bp->dcbx_port_params.ets.cos_params[cos].pri_bitmask);
+
+ DP(BNX2X_MSG_DCB,
+ "pdev->params.dcbx_port_params.ets.cos_params[%d].bw_tbl %x\n",
+ cos, bp->dcbx_port_params.ets.cos_params[cos].bw_tbl);
+
+ DP(BNX2X_MSG_DCB,
+ "pdev->params.dcbx_port_params.ets.cos_params[%d].strict %x\n",
+ cos, bp->dcbx_port_params.ets.cos_params[cos].strict);
+
+ DP(BNX2X_MSG_DCB,
+ "pdev->params.dcbx_port_params.ets.cos_params[%d].pauseable %x\n",
+ cos, bp->dcbx_port_params.ets.cos_params[cos].pauseable);
+ }
+
+ for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) {
+ DP(BNX2X_MSG_DCB,
+ "pfc_fw_cfg->traffic_type_to_priority_cos[%d].priority %x\n",
+ pri, pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority);
+
+ DP(BNX2X_MSG_DCB,
+ "pfc_fw_cfg->traffic_type_to_priority_cos[%d].cos %x\n",
+ pri, pfc_fw_cfg->traffic_type_to_priority_cos[pri].cos);
+ }
+}
+
+/* fills help_data according to pg_info */
+static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp,
+ u32 *pg_pri_orginal_spread,
+ struct pg_help_data *help_data)
+{
+ bool pg_found = false;
+ u32 i, traf_type, add_traf_type, add_pg;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+ struct pg_entry_help_data *data = help_data->data; /*shortcut*/
+
+ /* Set to invalid */
+ for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++)
+ data[i].pg = DCBX_ILLEGAL_PG;
+
+ for (add_traf_type = 0;
+ add_traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX; add_traf_type++) {
+ pg_found = false;
+ if (ttp[add_traf_type] < MAX_PFC_PRIORITIES) {
+ add_pg = (u8)pg_pri_orginal_spread[ttp[add_traf_type]];
+ for (traf_type = 0;
+ traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX;
+ traf_type++) {
+ if (data[traf_type].pg == add_pg) {
+ if (!(data[traf_type].pg_priority &
+ (1 << ttp[add_traf_type])))
+ data[traf_type].
+ num_of_dif_pri++;
+ data[traf_type].pg_priority |=
+ (1 << ttp[add_traf_type]);
+ pg_found = true;
+ break;
+ }
+ }
+ if (false == pg_found) {
+ data[help_data->num_of_pg].pg = add_pg;
+ data[help_data->num_of_pg].pg_priority =
+ (1 << ttp[add_traf_type]);
+ data[help_data->num_of_pg].num_of_dif_pri = 1;
+ help_data->num_of_pg++;
+ }
+ }
+ DP(BNX2X_MSG_DCB,
+ "add_traf_type %d pg_found %s num_of_pg %d\n",
+ add_traf_type, (false == pg_found) ? "NO" : "YES",
+ help_data->num_of_pg);
+ }
+}
+
+static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u32 pri_join_mask)
+{
+ /* Only one priority than only one COS */
+ cos_data->data[0].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+ cos_data->data[0].pri_join_mask = pri_join_mask;
+ cos_data->data[0].cos_bw = 100;
+ cos_data->num_of_cos = 1;
+}
+
+static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
+ struct cos_entry_help_data *data,
+ u8 pg_bw)
+{
+ if (data->cos_bw == DCBX_INVALID_COS_BW)
+ data->cos_bw = pg_bw;
+ else
+ data->cos_bw += pg_bw;
+}
+
+static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ struct dcbx_ets_feature *ets)
+{
+ u32 pri_tested = 0;
+ u8 i = 0;
+ u8 entry = 0;
+ u8 pg_entry = 0;
+ u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX;
+
+ cos_data->data[0].pausable = true;
+ cos_data->data[1].pausable = false;
+ cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0;
+
+ for (i = 0 ; i < num_of_pri ; i++) {
+ pri_tested = 1 << bp->dcbx_port_params.
+ app.traffic_type_priority[i];
+
+ if (pri_tested & DCBX_PFC_PRI_NON_PAUSE_MASK(bp)) {
+ cos_data->data[1].pri_join_mask |= pri_tested;
+ entry = 1;
+ } else {
+ cos_data->data[0].pri_join_mask |= pri_tested;
+ entry = 0;
+ }
+ pg_entry = (u8)pg_pri_orginal_spread[bp->dcbx_port_params.
+ app.traffic_type_priority[i]];
+ /* There can be only one strict pg */
+ if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES)
+ bnx2x_dcbx_add_to_cos_bw(bp, &cos_data->data[entry],
+ DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_entry));
+ else
+ /* If we join a group and one is strict
+ * than the bw rules
+ */
+ cos_data->data[entry].strict =
+ BNX2X_DCBX_STRICT_COS_HIGHEST;
+ }
+ if ((0 == cos_data->data[0].pri_join_mask) &&
+ (0 == cos_data->data[1].pri_join_mask))
+ BNX2X_ERR("dcbx error: Both groups must have priorities\n");
+}
+
+#ifndef POWER_OF_2
+#define POWER_OF_2(x) ((0 != x) && (0 == (x & (x-1))))
+#endif
+
+static void bnx2x_dcbx_2cos_limit_cee_single_pg_to_cos_params(struct bnx2x *bp,
+ struct pg_help_data *pg_help_data,
+ struct cos_help_data *cos_data,
+ u32 pri_join_mask,
+ u8 num_of_dif_pri)
+{
+ u8 i = 0;
+ u32 pri_tested = 0;
+ u32 pri_mask_without_pri = 0;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+ /*debug*/
+ if (num_of_dif_pri == 1) {
+ bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data, pri_join_mask);
+ return;
+ }
+ /* single priority group */
+ if (pg_help_data->data[0].pg < DCBX_MAX_NUM_PG_BW_ENTRIES) {
+ /* If there are both pauseable and non-pauseable priorities,
+ * the pauseable priorities go to the first queue and
+ * the non-pauseable priorities go to the second queue.
+ */
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) {
+ /* Pauseable */
+ cos_data->data[0].pausable = true;
+ /* Non pauseable.*/
+ cos_data->data[1].pausable = false;
+
+ if (2 == num_of_dif_pri) {
+ cos_data->data[0].cos_bw = 50;
+ cos_data->data[1].cos_bw = 50;
+ }
+
+ if (3 == num_of_dif_pri) {
+ if (POWER_OF_2(DCBX_PFC_PRI_GET_PAUSE(bp,
+ pri_join_mask))) {
+ cos_data->data[0].cos_bw = 33;
+ cos_data->data[1].cos_bw = 67;
+ } else {
+ cos_data->data[0].cos_bw = 67;
+ cos_data->data[1].cos_bw = 33;
+ }
+ }
+
+ } else if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask)) {
+ /* If there are only pauseable priorities,
+ * then one/two priorities go to the first queue
+ * and one priority goes to the second queue.
+ */
+ if (2 == num_of_dif_pri) {
+ cos_data->data[0].cos_bw = 50;
+ cos_data->data[1].cos_bw = 50;
+ } else {
+ cos_data->data[0].cos_bw = 67;
+ cos_data->data[1].cos_bw = 33;
+ }
+ cos_data->data[1].pausable = true;
+ cos_data->data[0].pausable = true;
+ /* All priorities except FCOE */
+ cos_data->data[0].pri_join_mask = (pri_join_mask &
+ ((u8)~(1 << ttp[LLFC_TRAFFIC_TYPE_FCOE])));
+ /* Only FCOE priority.*/
+ cos_data->data[1].pri_join_mask =
+ (1 << ttp[LLFC_TRAFFIC_TYPE_FCOE]);
+ } else
+ /* If there are only non-pauseable priorities,
+ * they will all go to the same queue.
+ */
+ bnx2x_dcbx_ets_disabled_entry_data(bp,
+ cos_data, pri_join_mask);
+ } else {
+ /* priority group which is not BW limited (PG#15):*/
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) {
+ /* If there are both pauseable and non-pauseable
+ * priorities, the pauseable priorities go to the first
+ * queue and the non-pauseable priorities
+ * go to the second queue.
+ */
+ if (DCBX_PFC_PRI_GET_PAUSE(bp, pri_join_mask) >
+ DCBX_PFC_PRI_GET_NON_PAUSE(bp, pri_join_mask)) {
+ cos_data->data[0].strict =
+ BNX2X_DCBX_STRICT_COS_HIGHEST;
+ cos_data->data[1].strict =
+ BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI(
+ BNX2X_DCBX_STRICT_COS_HIGHEST);
+ } else {
+ cos_data->data[0].strict =
+ BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI(
+ BNX2X_DCBX_STRICT_COS_HIGHEST);
+ cos_data->data[1].strict =
+ BNX2X_DCBX_STRICT_COS_HIGHEST;
+ }
+ /* Pauseable */
+ cos_data->data[0].pausable = true;
+ /* Non pause-able.*/
+ cos_data->data[1].pausable = false;
+ } else {
+ /* If there are only pauseable priorities or
+ * only non-pauseable,* the lower priorities go
+ * to the first queue and the higher priorities go
+ * to the second queue.
+ */
+ cos_data->data[0].pausable =
+ cos_data->data[1].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+
+ for (i = 0 ; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++) {
+ pri_tested = 1 << bp->dcbx_port_params.
+ app.traffic_type_priority[i];
+ /* Remove priority tested */
+ pri_mask_without_pri =
+ (pri_join_mask & ((u8)(~pri_tested)));
+ if (pri_mask_without_pri < pri_tested)
+ break;
+ }
+
+ if (i == LLFC_DRIVER_TRAFFIC_TYPE_MAX)
+ BNX2X_ERR("Invalid value for pri_join_mask - could not find a priority\n");
+
+ cos_data->data[0].pri_join_mask = pri_mask_without_pri;
+ cos_data->data[1].pri_join_mask = pri_tested;
+ /* Both queues are strict priority,
+ * and that with the highest priority
+ * gets the highest strict priority in the arbiter.
+ */
+ cos_data->data[0].strict =
+ BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI(
+ BNX2X_DCBX_STRICT_COS_HIGHEST);
+ cos_data->data[1].strict =
+ BNX2X_DCBX_STRICT_COS_HIGHEST;
+ }
+ }
+}
+
+static void bnx2x_dcbx_2cos_limit_cee_two_pg_to_cos_params(
+ struct bnx2x *bp,
+ struct pg_help_data *pg_help_data,
+ struct dcbx_ets_feature *ets,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ u32 pri_join_mask,
+ u8 num_of_dif_pri)
+{
+ u8 i = 0;
+ u8 pg[DCBX_COS_MAX_NUM_E2] = { 0 };
+
+ /* If there are both pauseable and non-pauseable priorities,
+ * the pauseable priorities go to the first queue and
+ * the non-pauseable priorities go to the second queue.
+ */
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) {
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp,
+ pg_help_data->data[0].pg_priority) ||
+ IS_DCBX_PFC_PRI_MIX_PAUSE(bp,
+ pg_help_data->data[1].pg_priority)) {
+ /* If one PG contains both pauseable and
+ * non-pauseable priorities then ETS is disabled.
+ */
+ bnx2x_dcbx_separate_pauseable_from_non(bp, cos_data,
+ pg_pri_orginal_spread, ets);
+ bp->dcbx_port_params.ets.enabled = false;
+ return;
+ }
+
+ /* Pauseable */
+ cos_data->data[0].pausable = true;
+ /* Non pauseable. */
+ cos_data->data[1].pausable = false;
+ if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp,
+ pg_help_data->data[0].pg_priority)) {
+ /* 0 is pauseable */
+ cos_data->data[0].pri_join_mask =
+ pg_help_data->data[0].pg_priority;
+ pg[0] = pg_help_data->data[0].pg;
+ cos_data->data[1].pri_join_mask =
+ pg_help_data->data[1].pg_priority;
+ pg[1] = pg_help_data->data[1].pg;
+ } else {/* 1 is pauseable */
+ cos_data->data[0].pri_join_mask =
+ pg_help_data->data[1].pg_priority;
+ pg[0] = pg_help_data->data[1].pg;
+ cos_data->data[1].pri_join_mask =
+ pg_help_data->data[0].pg_priority;
+ pg[1] = pg_help_data->data[0].pg;
+ }
+ } else {
+ /* If there are only pauseable priorities or
+ * only non-pauseable, each PG goes to a queue.
+ */
+ cos_data->data[0].pausable = cos_data->data[1].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+ cos_data->data[0].pri_join_mask =
+ pg_help_data->data[0].pg_priority;
+ pg[0] = pg_help_data->data[0].pg;
+ cos_data->data[1].pri_join_mask =
+ pg_help_data->data[1].pg_priority;
+ pg[1] = pg_help_data->data[1].pg;
+ }
+
+ /* There can be only one strict pg */
+ for (i = 0 ; i < ARRAY_SIZE(pg); i++) {
+ if (pg[i] < DCBX_MAX_NUM_PG_BW_ENTRIES)
+ cos_data->data[i].cos_bw =
+ DCBX_PG_BW_GET(ets->pg_bw_tbl, pg[i]);
+ else
+ cos_data->data[i].strict =
+ BNX2X_DCBX_STRICT_COS_HIGHEST;
+ }
+}
+
+static int bnx2x_dcbx_join_pgs(
+ struct bnx2x *bp,
+ struct dcbx_ets_feature *ets,
+ struct pg_help_data *pg_help_data,
+ u8 required_num_of_pg)
+{
+ u8 entry_joined = pg_help_data->num_of_pg - 1;
+ u8 entry_removed = entry_joined + 1;
+ u8 pg_joined = 0;
+
+ if (required_num_of_pg == 0 || ARRAY_SIZE(pg_help_data->data)
+ <= pg_help_data->num_of_pg) {
+
+ BNX2X_ERR("required_num_of_pg can't be zero\n");
+ return -EINVAL;
+ }
+
+ while (required_num_of_pg < pg_help_data->num_of_pg) {
+ entry_joined = pg_help_data->num_of_pg - 2;
+ entry_removed = entry_joined + 1;
+ /* protect index */
+ entry_removed %= ARRAY_SIZE(pg_help_data->data);
+
+ pg_help_data->data[entry_joined].pg_priority |=
+ pg_help_data->data[entry_removed].pg_priority;
+
+ pg_help_data->data[entry_joined].num_of_dif_pri +=
+ pg_help_data->data[entry_removed].num_of_dif_pri;
+
+ if (pg_help_data->data[entry_joined].pg == DCBX_STRICT_PRI_PG ||
+ pg_help_data->data[entry_removed].pg == DCBX_STRICT_PRI_PG)
+ /* Entries joined strict priority rules */
+ pg_help_data->data[entry_joined].pg =
+ DCBX_STRICT_PRI_PG;
+ else {
+ /* Entries can be joined join BW */
+ pg_joined = DCBX_PG_BW_GET(ets->pg_bw_tbl,
+ pg_help_data->data[entry_joined].pg) +
+ DCBX_PG_BW_GET(ets->pg_bw_tbl,
+ pg_help_data->data[entry_removed].pg);
+
+ DCBX_PG_BW_SET(ets->pg_bw_tbl,
+ pg_help_data->data[entry_joined].pg, pg_joined);
+ }
+ /* Joined the entries */
+ pg_help_data->num_of_pg--;
+ }
+
+ return 0;
+}
+
+static void bnx2x_dcbx_2cos_limit_cee_three_pg_to_cos_params(
+ struct bnx2x *bp,
+ struct pg_help_data *pg_help_data,
+ struct dcbx_ets_feature *ets,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ u32 pri_join_mask,
+ u8 num_of_dif_pri)
+{
+ u8 i = 0;
+ u32 pri_tested = 0;
+ u8 entry = 0;
+ u8 pg_entry = 0;
+ bool b_found_strict = false;
+ u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX;
+
+ cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0;
+ /* If there are both pauseable and non-pauseable priorities,
+ * the pauseable priorities go to the first queue and the
+ * non-pauseable priorities go to the second queue.
+ */
+ if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask))
+ bnx2x_dcbx_separate_pauseable_from_non(bp,
+ cos_data, pg_pri_orginal_spread, ets);
+ else {
+ /* If two BW-limited PG-s were combined to one queue,
+ * the BW is their sum.
+ *
+ * If there are only pauseable priorities or only non-pauseable,
+ * and there are both BW-limited and non-BW-limited PG-s,
+ * the BW-limited PG/s go to one queue and the non-BW-limited
+ * PG/s go to the second queue.
+ *
+ * If there are only pauseable priorities or only non-pauseable
+ * and all are BW limited, then two priorities go to the first
+ * queue and one priority goes to the second queue.
+ *
+ * We will join this two cases:
+ * if one is BW limited it will go to the second queue
+ * otherwise the last priority will get it
+ */
+
+ cos_data->data[0].pausable = cos_data->data[1].pausable =
+ IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask);
+
+ for (i = 0 ; i < num_of_pri; i++) {
+ pri_tested = 1 << bp->dcbx_port_params.
+ app.traffic_type_priority[i];
+ pg_entry = (u8)pg_pri_orginal_spread[bp->
+ dcbx_port_params.app.traffic_type_priority[i]];
+
+ if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) {
+ entry = 0;
+
+ if (i == (num_of_pri-1) &&
+ false == b_found_strict)
+ /* last entry will be handled separately
+ * If no priority is strict than last
+ * entry goes to last queue.
+ */
+ entry = 1;
+ cos_data->data[entry].pri_join_mask |=
+ pri_tested;
+ bnx2x_dcbx_add_to_cos_bw(bp,
+ &cos_data->data[entry],
+ DCBX_PG_BW_GET(ets->pg_bw_tbl,
+ pg_entry));
+ } else {
+ b_found_strict = true;
+ cos_data->data[1].pri_join_mask |= pri_tested;
+ /* If we join a group and one is strict
+ * than the bw rules
+ */
+ cos_data->data[1].strict =
+ BNX2X_DCBX_STRICT_COS_HIGHEST;
+ }
+ }
+ }
+}
+
+static void bnx2x_dcbx_2cos_limit_cee_fill_cos_params(struct bnx2x *bp,
+ struct pg_help_data *help_data,
+ struct dcbx_ets_feature *ets,
+ struct cos_help_data *cos_data,
+ u32 *pg_pri_orginal_spread,
+ u32 pri_join_mask,
+ u8 num_of_dif_pri)
+{
+ /* default E2 settings */
+ cos_data->num_of_cos = DCBX_COS_MAX_NUM_E2;
+
+ switch (help_data->num_of_pg) {
+ case 1:
+ bnx2x_dcbx_2cos_limit_cee_single_pg_to_cos_params(
+ bp,
+ help_data,
+ cos_data,
+ pri_join_mask,
+ num_of_dif_pri);
+ break;
+ case 2:
+ bnx2x_dcbx_2cos_limit_cee_two_pg_to_cos_params(
+ bp,
+ help_data,
+ ets,
+ cos_data,
+ pg_pri_orginal_spread,
+ pri_join_mask,
+ num_of_dif_pri);
+ break;
+
+ case 3:
+ bnx2x_dcbx_2cos_limit_cee_three_pg_to_cos_params(
+ bp,
+ help_data,
+ ets,
+ cos_data,
+ pg_pri_orginal_spread,
+ pri_join_mask,
+ num_of_dif_pri);
+ break;
+ default:
+ BNX2X_ERR("Wrong pg_help_data.num_of_pg\n");
+ bnx2x_dcbx_ets_disabled_entry_data(bp,
+ cos_data, pri_join_mask);
+ }
+}
+
+static int bnx2x_dcbx_spread_strict_pri(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u8 entry,
+ u8 num_spread_of_entries,
+ u8 strict_app_pris)
+{
+ u8 strict_pri = BNX2X_DCBX_STRICT_COS_HIGHEST;
+ u8 num_of_app_pri = MAX_PFC_PRIORITIES;
+ u8 app_pri_bit = 0;
+
+ while (num_spread_of_entries && num_of_app_pri > 0) {
+ app_pri_bit = 1 << (num_of_app_pri - 1);
+ if (app_pri_bit & strict_app_pris) {
+ struct cos_entry_help_data *data = &cos_data->
+ data[entry];
+ num_spread_of_entries--;
+ if (num_spread_of_entries == 0) {
+ /* last entry needed put all the entries left */
+ data->cos_bw = DCBX_INVALID_COS_BW;
+ data->strict = strict_pri;
+ data->pri_join_mask = strict_app_pris;
+ data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp,
+ data->pri_join_mask);
+ } else {
+ strict_app_pris &= ~app_pri_bit;
+
+ data->cos_bw = DCBX_INVALID_COS_BW;
+ data->strict = strict_pri;
+ data->pri_join_mask = app_pri_bit;
+ data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp,
+ data->pri_join_mask);
+ }
+
+ strict_pri =
+ BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI(strict_pri);
+ entry++;
+ }
+
+ num_of_app_pri--;
+ }
+
+ if (num_spread_of_entries) {
+ BNX2X_ERR("Didn't succeed to spread strict priorities\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static u8 bnx2x_dcbx_cee_fill_strict_pri(struct bnx2x *bp,
+ struct cos_help_data *cos_data,
+ u8 entry,
+ u8 num_spread_of_entries,
+ u8 strict_app_pris)
+{
+ if (bnx2x_dcbx_spread_strict_pri(bp, cos_data, entry,
+ num_spread_of_entries,
+ strict_app_pris)) {
+ struct cos_entry_help_data *data = &cos_data->
+ data[entry];
+ /* Fill BW entry */
+ data->cos_bw = DCBX_INVALID_COS_BW;
+ data->strict = BNX2X_DCBX_STRICT_COS_HIGHEST;
+ data->pri_join_mask = strict_app_pris;
+ data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp,
+ data->pri_join_mask);
+ return 1;
+ }
+
+ return num_spread_of_entries;
+}
+
+static void bnx2x_dcbx_cee_fill_cos_params(struct bnx2x *bp,
+ struct pg_help_data *help_data,
+ struct dcbx_ets_feature *ets,
+ struct cos_help_data *cos_data,
+ u32 pri_join_mask)
+
+{
+ u8 need_num_of_entries = 0;
+ u8 i = 0;
+ u8 entry = 0;
+
+ /*
+ * if the number of requested PG-s in CEE is greater than 3
+ * then the results are not determined since this is a violation
+ * of the standard.
+ */
+ if (help_data->num_of_pg > DCBX_COS_MAX_NUM_E3B0) {
+ if (bnx2x_dcbx_join_pgs(bp, ets, help_data,
+ DCBX_COS_MAX_NUM_E3B0)) {
+ BNX2X_ERR("Unable to reduce the number of PGs - we will disables ETS\n");
+ bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data,
+ pri_join_mask);
+ return;
+ }
+ }
+
+ for (i = 0 ; i < help_data->num_of_pg; i++) {
+ struct pg_entry_help_data *pg = &help_data->data[i];
+ if (pg->pg < DCBX_MAX_NUM_PG_BW_ENTRIES) {
+ struct cos_entry_help_data *data = &cos_data->
+ data[entry];
+ /* Fill BW entry */
+ data->cos_bw = DCBX_PG_BW_GET(ets->pg_bw_tbl, pg->pg);
+ data->strict = BNX2X_DCBX_STRICT_INVALID;
+ data->pri_join_mask = pg->pg_priority;
+ data->pausable = DCBX_IS_PFC_PRI_SOME_PAUSE(bp,
+ data->pri_join_mask);
+
+ entry++;
+ } else {
+ need_num_of_entries = min_t(u8,
+ (u8)pg->num_of_dif_pri,
+ (u8)DCBX_COS_MAX_NUM_E3B0 -
+ help_data->num_of_pg + 1);
+ /*
+ * If there are still VOQ-s which have no associated PG,
+ * then associate these VOQ-s to PG15. These PG-s will
+ * be used for SP between priorities on PG15.
+ */
+ entry += bnx2x_dcbx_cee_fill_strict_pri(bp, cos_data,
+ entry, need_num_of_entries, pg->pg_priority);
+ }
+ }
+
+ /* the entry will represent the number of COSes used */
+ cos_data->num_of_cos = entry;
+}
+static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp,
+ struct pg_help_data *help_data,
+ struct dcbx_ets_feature *ets,
+ u32 *pg_pri_orginal_spread)
+{
+ struct cos_help_data cos_data;
+ u8 i = 0;
+ u32 pri_join_mask = 0;
+ u8 num_of_dif_pri = 0;
+
+ memset(&cos_data, 0, sizeof(cos_data));
+
+ /* Validate the pg value */
+ for (i = 0; i < help_data->num_of_pg ; i++) {
+ if (DCBX_STRICT_PRIORITY != help_data->data[i].pg &&
+ DCBX_MAX_NUM_PG_BW_ENTRIES <= help_data->data[i].pg)
+ BNX2X_ERR("Invalid pg[%d] data %x\n", i,
+ help_data->data[i].pg);
+ pri_join_mask |= help_data->data[i].pg_priority;
+ num_of_dif_pri += help_data->data[i].num_of_dif_pri;
+ }
+
+ /* defaults */
+ cos_data.num_of_cos = 1;
+ for (i = 0; i < ARRAY_SIZE(cos_data.data); i++) {
+ cos_data.data[i].pri_join_mask = 0;
+ cos_data.data[i].pausable = false;
+ cos_data.data[i].strict = BNX2X_DCBX_STRICT_INVALID;
+ cos_data.data[i].cos_bw = DCBX_INVALID_COS_BW;
+ }
+
+ if (CHIP_IS_E3B0(bp))
+ bnx2x_dcbx_cee_fill_cos_params(bp, help_data, ets,
+ &cos_data, pri_join_mask);
+ else /* E2 + E3A0 */
+ bnx2x_dcbx_2cos_limit_cee_fill_cos_params(bp,
+ help_data, ets,
+ &cos_data,
+ pg_pri_orginal_spread,
+ pri_join_mask,
+ num_of_dif_pri);
+
+ for (i = 0; i < cos_data.num_of_cos ; i++) {
+ struct bnx2x_dcbx_cos_params *p =
+ &bp->dcbx_port_params.ets.cos_params[i];
+
+ p->strict = cos_data.data[i].strict;
+ p->bw_tbl = cos_data.data[i].cos_bw;
+ p->pri_bitmask = cos_data.data[i].pri_join_mask;
+ p->pauseable = cos_data.data[i].pausable;
+
+ /* sanity */
+ if (p->bw_tbl != DCBX_INVALID_COS_BW ||
+ p->strict != BNX2X_DCBX_STRICT_INVALID) {
+ if (p->pri_bitmask == 0)
+ BNX2X_ERR("Invalid pri_bitmask for %d\n", i);
+
+ if (CHIP_IS_E2(bp) || CHIP_IS_E3A0(bp)) {
+
+ if (p->pauseable &&
+ DCBX_PFC_PRI_GET_NON_PAUSE(bp,
+ p->pri_bitmask) != 0)
+ BNX2X_ERR("Inconsistent config for pausable COS %d\n",
+ i);
+
+ if (!p->pauseable &&
+ DCBX_PFC_PRI_GET_PAUSE(bp,
+ p->pri_bitmask) != 0)
+ BNX2X_ERR("Inconsistent config for nonpausable COS %d\n",
+ i);
+ }
+ }
+
+ if (p->pauseable)
+ DP(BNX2X_MSG_DCB, "COS %d PAUSABLE prijoinmask 0x%x\n",
+ i, cos_data.data[i].pri_join_mask);
+ else
+ DP(BNX2X_MSG_DCB,
+ "COS %d NONPAUSABLE prijoinmask 0x%x\n",
+ i, cos_data.data[i].pri_join_mask);
+ }
+
+ bp->dcbx_port_params.ets.num_of_cos = cos_data.num_of_cos ;
+}
+
+static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
+ u32 *set_configuration_ets_pg,
+ u32 *pri_pg_tbl)
+{
+ int i;
+
+ for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) {
+ set_configuration_ets_pg[i] = DCBX_PRI_PG_GET(pri_pg_tbl, i);
+
+ DP(BNX2X_MSG_DCB, "set_configuration_ets_pg[%d] = 0x%x\n",
+ i, set_configuration_ets_pg[i]);
+ }
+}
+
+static void bnx2x_dcbx_fw_struct(struct bnx2x *bp,
+ struct bnx2x_func_tx_start_params *pfc_fw_cfg)
+{
+ u16 pri_bit = 0;
+ u8 cos = 0, pri = 0;
+ struct priority_cos *tt2cos;
+ u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
+ int mfw_configured = SHMEM2_HAS(bp, drv_flags) &&
+ GET_FLAGS(SHMEM2_RD(bp, drv_flags),
+ 1 << DRV_FLAGS_DCB_MFW_CONFIGURED);
+
+ memset(pfc_fw_cfg, 0, sizeof(*pfc_fw_cfg));
+
+ /* to disable DCB - the structure must be zeroed */
+ if ((bp->dcbx_error & DCBX_REMOTE_MIB_ERROR) && !mfw_configured)
+ return;
+
+ /*shortcut*/
+ tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos;
+
+ /* Fw version should be incremented each update */
+ pfc_fw_cfg->dcb_version = ++bp->dcb_version;
+ pfc_fw_cfg->dcb_enabled = 1;
+
+ /* Fill priority parameters */
+ for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) {
+ tt2cos[pri].priority = ttp[pri];
+ pri_bit = 1 << tt2cos[pri].priority;
+
+ /* Fill COS parameters based on COS calculated to
+ * make it more general for future use */
+ for (cos = 0; cos < bp->dcbx_port_params.ets.num_of_cos; cos++)
+ if (bp->dcbx_port_params.ets.cos_params[cos].
+ pri_bitmask & pri_bit)
+ tt2cos[pri].cos = cos;
+ }
+
+ /* we never want the FW to add a 0 vlan tag */
+ pfc_fw_cfg->dont_add_pri_0_en = 1;
+
+ bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg);
+}
+
+void bnx2x_dcbx_pmf_update(struct bnx2x *bp)
+{
+ /* if we need to synchronize DCBX result from prev PMF
+ * read it from shmem and update bp and netdev accordingly
+ */
+ if (SHMEM2_HAS(bp, drv_flags) &&
+ GET_FLAGS(SHMEM2_RD(bp, drv_flags), 1 << DRV_FLAGS_DCB_CONFIGURED)) {
+ /* Read neg results if dcbx is in the FW */
+ if (bnx2x_dcbx_read_shmem_neg_results(bp))
+ return;
+
+ bnx2x_dump_dcbx_drv_param(bp, &bp->dcbx_local_feat,
+ bp->dcbx_error);
+ bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat,
+ bp->dcbx_error);
+#ifdef BCM_DCBNL
+ /*
+ * Add new app tlvs to dcbnl
+ */
+ bnx2x_dcbnl_update_applist(bp, false);
+ /*
+ * Send a notification for the new negotiated parameters
+ */
+ dcbnl_cee_notify(bp->dev, RTM_GETDCB, DCB_CMD_CEE_GET, 0, 0);
+#endif
+ /*
+ * reconfigure the netdevice with the results of the new
+ * dcbx negotiation.
+ */
+ bnx2x_dcbx_update_tc_mapping(bp);
+ }
+}
+
+/* DCB netlink */
+#ifdef BCM_DCBNL
+
+#define BNX2X_DCBX_CAPS (DCB_CAP_DCBX_LLD_MANAGED | \
+ DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC)
+
+static inline bool bnx2x_dcbnl_set_valid(struct bnx2x *bp)
+{
+ /* validate dcbnl call that may change HW state:
+ * DCB is on and DCBX mode was SUCCESSFULLY set by the user.
+ */
+ return bp->dcb_state && bp->dcbx_mode_uset;
+}
+
+static u8 bnx2x_dcbnl_get_state(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcb_state);
+ return bp->dcb_state;
+}
+
+static u8 bnx2x_dcbnl_set_state(struct net_device *netdev, u8 state)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "state = %s\n", state ? "on" : "off");
+
+ /* Fail to set state to "enabled" if dcbx is disabled in nvram */
+ if (state && ((bp->dcbx_enabled == BNX2X_DCBX_ENABLED_OFF) ||
+ (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_INVALID))) {
+ DP(BNX2X_MSG_DCB, "Can not set dcbx to enabled while it is disabled in nvm\n");
+ return 1;
+ }
+
+ bnx2x_dcbx_set_state(bp, (state ? true : false), bp->dcbx_enabled);
+ return 0;
+}
+
+static void bnx2x_dcbnl_get_perm_hw_addr(struct net_device *netdev,
+ u8 *perm_addr)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "GET-PERM-ADDR\n");
+
+ /* first the HW mac address */
+ memcpy(perm_addr, netdev->dev_addr, netdev->addr_len);
+
+ if (CNIC_LOADED(bp))
+ /* second SAN address */
+ memcpy(perm_addr+netdev->addr_len, bp->fip_mac,
+ netdev->addr_len);
+}
+
+static void bnx2x_dcbnl_set_pg_tccfg_tx(struct net_device *netdev, int prio,
+ u8 prio_type, u8 pgid, u8 bw_pct,
+ u8 up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(BNX2X_MSG_DCB, "prio[%d] = %d\n", prio, pgid);
+ if (!bnx2x_dcbnl_set_valid(bp) || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES)
+ return;
+
+ /**
+ * bw_pct ignored - band-width percentage devision between user
+ * priorities within the same group is not
+ * standard and hence not supported
+ *
+ * prio_type ignored - priority levels within the same group are not
+ * standard and hence are not supported. According
+ * to the standard pgid 15 is dedicated to strict
+ * priority traffic (on the port level).
+ *
+ * up_map ignored
+ */
+
+ bp->dcbx_config_params.admin_configuration_ets_pg[prio] = pgid;
+ bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1;
+}
+
+static void bnx2x_dcbnl_set_pg_bwgcfg_tx(struct net_device *netdev,
+ int pgid, u8 bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "pgid[%d] = %d\n", pgid, bw_pct);
+
+ if (!bnx2x_dcbnl_set_valid(bp) || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES)
+ return;
+
+ bp->dcbx_config_params.admin_configuration_bw_precentage[pgid] = bw_pct;
+ bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1;
+}
+
+static void bnx2x_dcbnl_set_pg_tccfg_rx(struct net_device *netdev, int prio,
+ u8 prio_type, u8 pgid, u8 bw_pct,
+ u8 up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "Nothing to set; No RX support\n");
+}
+
+static void bnx2x_dcbnl_set_pg_bwgcfg_rx(struct net_device *netdev,
+ int pgid, u8 bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "Nothing to set; No RX support\n");
+}
+
+static void bnx2x_dcbnl_get_pg_tccfg_tx(struct net_device *netdev, int prio,
+ u8 *prio_type, u8 *pgid, u8 *bw_pct,
+ u8 *up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "prio = %d\n", prio);
+
+ /**
+ * bw_pct ignored - band-width percentage devision between user
+ * priorities within the same group is not
+ * standard and hence not supported
+ *
+ * prio_type ignored - priority levels within the same group are not
+ * standard and hence are not supported. According
+ * to the standard pgid 15 is dedicated to strict
+ * priority traffic (on the port level).
+ *
+ * up_map ignored
+ */
+ *up_map = *bw_pct = *prio_type = *pgid = 0;
+
+ if (!bp->dcb_state || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES)
+ return;
+
+ *pgid = DCBX_PRI_PG_GET(bp->dcbx_local_feat.ets.pri_pg_tbl, prio);
+}
+
+static void bnx2x_dcbnl_get_pg_bwgcfg_tx(struct net_device *netdev,
+ int pgid, u8 *bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "pgid = %d\n", pgid);
+
+ *bw_pct = 0;
+
+ if (!bp->dcb_state || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES)
+ return;
+
+ *bw_pct = DCBX_PG_BW_GET(bp->dcbx_local_feat.ets.pg_bw_tbl, pgid);
+}
+
+static void bnx2x_dcbnl_get_pg_tccfg_rx(struct net_device *netdev, int prio,
+ u8 *prio_type, u8 *pgid, u8 *bw_pct,
+ u8 *up_map)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "Nothing to get; No RX support\n");
+
+ *prio_type = *pgid = *bw_pct = *up_map = 0;
+}
+
+static void bnx2x_dcbnl_get_pg_bwgcfg_rx(struct net_device *netdev,
+ int pgid, u8 *bw_pct)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "Nothing to get; No RX support\n");
+
+ *bw_pct = 0;
+}
+
+static void bnx2x_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio,
+ u8 setting)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "prio[%d] = %d\n", prio, setting);
+
+ if (!bnx2x_dcbnl_set_valid(bp) || prio >= MAX_PFC_PRIORITIES)
+ return;
+
+ if (setting) {
+ bp->dcbx_config_params.admin_pfc_bitmap |= (1 << prio);
+ bp->dcbx_config_params.admin_pfc_tx_enable = 1;
+ } else {
+ bp->dcbx_config_params.admin_pfc_bitmap &= ~(1 << prio);
+ }
+}
+
+static void bnx2x_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio,
+ u8 *setting)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "prio = %d\n", prio);
+
+ *setting = 0;
+
+ if (!bp->dcb_state || prio >= MAX_PFC_PRIORITIES)
+ return;
+
+ *setting = (bp->dcbx_local_feat.pfc.pri_en_bitmap >> prio) & 0x1;
+}
+
+static u8 bnx2x_dcbnl_set_all(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ int rc = 0;
+
+ DP(BNX2X_MSG_DCB, "SET-ALL\n");
+
+ if (!bnx2x_dcbnl_set_valid(bp))
+ return 1;
+
+ if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
+ netdev_err(bp->dev,
+ "Handling parity error recovery. Try again later\n");
+ return 1;
+ }
+ if (netif_running(bp->dev)) {
+ bnx2x_update_drv_flags(bp,
+ 1 << DRV_FLAGS_DCB_MFW_CONFIGURED,
+ 1);
+ bnx2x_dcbx_init(bp, true);
+ }
+ DP(BNX2X_MSG_DCB, "set_dcbx_params done (%d)\n", rc);
+ if (rc)
+ return 1;
+
+ return 0;
+}
+
+static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ if (bp->dcb_state) {
+ switch (capid) {
+ case DCB_CAP_ATTR_PG:
+ *cap = true;
+ break;
+ case DCB_CAP_ATTR_PFC:
+ *cap = true;
+ break;
+ case DCB_CAP_ATTR_UP2TC:
+ *cap = false;
+ break;
+ case DCB_CAP_ATTR_PG_TCS:
+ *cap = 0x80; /* 8 priorities for PGs */
+ break;
+ case DCB_CAP_ATTR_PFC_TCS:
+ *cap = 0x80; /* 8 priorities for PFC */
+ break;
+ case DCB_CAP_ATTR_GSP:
+ *cap = true;
+ break;
+ case DCB_CAP_ATTR_BCN:
+ *cap = false;
+ break;
+ case DCB_CAP_ATTR_DCBX:
+ *cap = BNX2X_DCBX_CAPS;
+ break;
+ default:
+ BNX2X_ERR("Non valid capability ID\n");
+ rval = 1;
+ break;
+ }
+ } else {
+ DP(BNX2X_MSG_DCB, "DCB disabled\n");
+ rval = 1;
+ }
+
+ DP(BNX2X_MSG_DCB, "capid %d:%x\n", capid, *cap);
+ return rval;
+}
+
+static int bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ DP(BNX2X_MSG_DCB, "tcid %d\n", tcid);
+
+ if (bp->dcb_state) {
+ switch (tcid) {
+ case DCB_NUMTCS_ATTR_PG:
+ *num = CHIP_IS_E3B0(bp) ? DCBX_COS_MAX_NUM_E3B0 :
+ DCBX_COS_MAX_NUM_E2;
+ break;
+ case DCB_NUMTCS_ATTR_PFC:
+ *num = CHIP_IS_E3B0(bp) ? DCBX_COS_MAX_NUM_E3B0 :
+ DCBX_COS_MAX_NUM_E2;
+ break;
+ default:
+ BNX2X_ERR("Non valid TC-ID\n");
+ rval = 1;
+ break;
+ }
+ } else {
+ DP(BNX2X_MSG_DCB, "DCB disabled\n");
+ rval = 1;
+ }
+
+ return rval;
+}
+
+static int bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "num tcs = %d; Not supported\n", num);
+ return -EINVAL;
+}
+
+static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcbx_local_feat.pfc.enabled);
+
+ if (!bp->dcb_state)
+ return 0;
+
+ return bp->dcbx_local_feat.pfc.enabled;
+}
+
+static void bnx2x_dcbnl_set_pfc_state(struct net_device *netdev, u8 state)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "state = %s\n", state ? "on" : "off");
+
+ if (!bnx2x_dcbnl_set_valid(bp))
+ return;
+
+ bp->dcbx_config_params.admin_pfc_tx_enable =
+ bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0);
+}
+
+static void bnx2x_admin_app_set_ent(
+ struct bnx2x_admin_priority_app_table *app_ent,
+ u8 idtype, u16 idval, u8 up)
+{
+ app_ent->valid = 1;
+
+ switch (idtype) {
+ case DCB_APP_IDTYPE_ETHTYPE:
+ app_ent->traffic_type = TRAFFIC_TYPE_ETH;
+ break;
+ case DCB_APP_IDTYPE_PORTNUM:
+ app_ent->traffic_type = TRAFFIC_TYPE_PORT;
+ break;
+ default:
+ break; /* never gets here */
+ }
+ app_ent->app_id = idval;
+ app_ent->priority = up;
+}
+
+static bool bnx2x_admin_app_is_equal(
+ struct bnx2x_admin_priority_app_table *app_ent,
+ u8 idtype, u16 idval)
+{
+ if (!app_ent->valid)
+ return false;
+
+ switch (idtype) {
+ case DCB_APP_IDTYPE_ETHTYPE:
+ if (app_ent->traffic_type != TRAFFIC_TYPE_ETH)
+ return false;
+ break;
+ case DCB_APP_IDTYPE_PORTNUM:
+ if (app_ent->traffic_type != TRAFFIC_TYPE_PORT)
+ return false;
+ break;
+ default:
+ return false;
+ }
+ if (app_ent->app_id != idval)
+ return false;
+
+ return true;
+}
+
+static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up)
+{
+ int i, ff;
+
+ /* iterate over the app entries looking for idtype and idval */
+ for (i = 0, ff = -1; i < DCBX_CONFIG_MAX_APP_PROTOCOL; i++) {
+ struct bnx2x_admin_priority_app_table *app_ent =
+ &bp->dcbx_config_params.admin_priority_app_table[i];
+ if (bnx2x_admin_app_is_equal(app_ent, idtype, idval))
+ break;
+
+ if (ff < 0 && !app_ent->valid)
+ ff = i;
+ }
+ if (i < DCBX_CONFIG_MAX_APP_PROTOCOL)
+ /* if found overwrite up */
+ bp->dcbx_config_params.
+ admin_priority_app_table[i].priority = up;
+ else if (ff >= 0)
+ /* not found use first-free */
+ bnx2x_admin_app_set_ent(
+ &bp->dcbx_config_params.admin_priority_app_table[ff],
+ idtype, idval, up);
+ else {
+ /* app table is full */
+ BNX2X_ERR("Application table is too large\n");
+ return -EBUSY;
+ }
+
+ /* up configured, if not 0 make sure feature is enabled */
+ if (up)
+ bp->dcbx_config_params.admin_application_priority_tx_enable = 1;
+
+ return 0;
+}
+
+static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype,
+ u16 idval, u8 up)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(BNX2X_MSG_DCB, "app_type %d, app_id %x, prio bitmap %d\n",
+ idtype, idval, up);
+
+ if (!bnx2x_dcbnl_set_valid(bp)) {
+ DP(BNX2X_MSG_DCB, "dcbnl call not valid\n");
+ return -EINVAL;
+ }
+
+ /* verify idtype */
+ switch (idtype) {
+ case DCB_APP_IDTYPE_ETHTYPE:
+ case DCB_APP_IDTYPE_PORTNUM:
+ break;
+ default:
+ DP(BNX2X_MSG_DCB, "Wrong ID type\n");
+ return -EINVAL;
+ }
+ return bnx2x_set_admin_app_up(bp, idtype, idval, up);
+}
+
+static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 state;
+
+ state = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE;
+
+ if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF)
+ state |= DCB_CAP_DCBX_STATIC;
+
+ return state;
+}
+
+static u8 bnx2x_dcbnl_set_dcbx(struct net_device *netdev, u8 state)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ DP(BNX2X_MSG_DCB, "state = %02x\n", state);
+
+ /* set dcbx mode */
+
+ if ((state & BNX2X_DCBX_CAPS) != state) {
+ BNX2X_ERR("Requested DCBX mode %x is beyond advertised capabilities\n",
+ state);
+ return 1;
+ }
+
+ if (bp->dcb_state != BNX2X_DCB_STATE_ON) {
+ BNX2X_ERR("DCB turned off, DCBX configuration is invalid\n");
+ return 1;
+ }
+
+ if (state & DCB_CAP_DCBX_STATIC)
+ bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_OFF;
+ else
+ bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_ON;
+
+ bp->dcbx_mode_uset = true;
+ return 0;
+}
+
+static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
+ u8 *flags)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ DP(BNX2X_MSG_DCB, "featid %d\n", featid);
+
+ if (bp->dcb_state) {
+ *flags = 0;
+ switch (featid) {
+ case DCB_FEATCFG_ATTR_PG:
+ if (bp->dcbx_local_feat.ets.enabled)
+ *flags |= DCB_FEATCFG_ENABLE;
+ if (bp->dcbx_error & (DCBX_LOCAL_ETS_ERROR |
+ DCBX_REMOTE_MIB_ERROR))
+ *flags |= DCB_FEATCFG_ERROR;
+ break;
+ case DCB_FEATCFG_ATTR_PFC:
+ if (bp->dcbx_local_feat.pfc.enabled)
+ *flags |= DCB_FEATCFG_ENABLE;
+ if (bp->dcbx_error & (DCBX_LOCAL_PFC_ERROR |
+ DCBX_LOCAL_PFC_MISMATCH |
+ DCBX_REMOTE_MIB_ERROR))
+ *flags |= DCB_FEATCFG_ERROR;
+ break;
+ case DCB_FEATCFG_ATTR_APP:
+ if (bp->dcbx_local_feat.app.enabled)
+ *flags |= DCB_FEATCFG_ENABLE;
+ if (bp->dcbx_error & (DCBX_LOCAL_APP_ERROR |
+ DCBX_LOCAL_APP_MISMATCH |
+ DCBX_REMOTE_MIB_ERROR))
+ *flags |= DCB_FEATCFG_ERROR;
+ break;
+ default:
+ BNX2X_ERR("Non valid feature-ID\n");
+ rval = 1;
+ break;
+ }
+ } else {
+ DP(BNX2X_MSG_DCB, "DCB disabled\n");
+ rval = 1;
+ }
+
+ return rval;
+}
+
+static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
+ u8 flags)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ u8 rval = 0;
+
+ DP(BNX2X_MSG_DCB, "featid = %d flags = %02x\n", featid, flags);
+
+ /* ignore the 'advertise' flag */
+ if (bnx2x_dcbnl_set_valid(bp)) {
+ switch (featid) {
+ case DCB_FEATCFG_ATTR_PG:
+ bp->dcbx_config_params.admin_ets_enable =
+ flags & DCB_FEATCFG_ENABLE ? 1 : 0;
+ bp->dcbx_config_params.admin_ets_willing =
+ flags & DCB_FEATCFG_WILLING ? 1 : 0;
+ break;
+ case DCB_FEATCFG_ATTR_PFC:
+ bp->dcbx_config_params.admin_pfc_enable =
+ flags & DCB_FEATCFG_ENABLE ? 1 : 0;
+ bp->dcbx_config_params.admin_pfc_willing =
+ flags & DCB_FEATCFG_WILLING ? 1 : 0;
+ break;
+ case DCB_FEATCFG_ATTR_APP:
+ /* ignore enable, always enabled */
+ bp->dcbx_config_params.admin_app_priority_willing =
+ flags & DCB_FEATCFG_WILLING ? 1 : 0;
+ break;
+ default:
+ BNX2X_ERR("Non valid feature-ID\n");
+ rval = 1;
+ break;
+ }
+ } else {
+ DP(BNX2X_MSG_DCB, "dcbnl call not valid\n");
+ rval = 1;
+ }
+
+ return rval;
+}
+
+static int bnx2x_peer_appinfo(struct net_device *netdev,
+ struct dcb_peer_app_info *info, u16* app_count)
+{
+ int i;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(BNX2X_MSG_DCB, "APP-INFO\n");
+
+ info->willing = (bp->dcbx_remote_flags & DCBX_APP_REM_WILLING) ?: 0;
+ info->error = (bp->dcbx_remote_flags & DCBX_APP_RX_ERROR) ?: 0;
+ *app_count = 0;
+
+ for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
+ if (bp->dcbx_remote_feat.app.app_pri_tbl[i].appBitfield &
+ DCBX_APP_ENTRY_VALID)
+ (*app_count)++;
+ return 0;
+}
+
+static int bnx2x_peer_apptable(struct net_device *netdev,
+ struct dcb_app *table)
+{
+ int i, j;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ DP(BNX2X_MSG_DCB, "APP-TABLE\n");
+
+ for (i = 0, j = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
+ struct dcbx_app_priority_entry *ent =
+ &bp->dcbx_remote_feat.app.app_pri_tbl[i];
+
+ if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
+ table[j].selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
+ table[j].priority = bnx2x_dcbx_dcbnl_app_up(ent);
+ table[j++].protocol = ent->app_id;
+ }
+ }
+ return 0;
+}
+
+static int bnx2x_cee_peer_getpg(struct net_device *netdev, struct cee_pg *pg)
+{
+ int i;
+ struct bnx2x *bp = netdev_priv(netdev);
+
+ pg->willing = (bp->dcbx_remote_flags & DCBX_ETS_REM_WILLING) ?: 0;
+
+ for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
+ pg->pg_bw[i] =
+ DCBX_PG_BW_GET(bp->dcbx_remote_feat.ets.pg_bw_tbl, i);
+ pg->prio_pg[i] =
+ DCBX_PRI_PG_GET(bp->dcbx_remote_feat.ets.pri_pg_tbl, i);
+ }
+ return 0;
+}
+
+static int bnx2x_cee_peer_getpfc(struct net_device *netdev,
+ struct cee_pfc *pfc)
+{
+ struct bnx2x *bp = netdev_priv(netdev);
+ pfc->tcs_supported = bp->dcbx_remote_feat.pfc.pfc_caps;
+ pfc->pfc_en = bp->dcbx_remote_feat.pfc.pri_en_bitmap;
+ return 0;
+}
+
+const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
+ .getstate = bnx2x_dcbnl_get_state,
+ .setstate = bnx2x_dcbnl_set_state,
+ .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr,
+ .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx,
+ .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx,
+ .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx,
+ .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx,
+ .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx,
+ .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx,
+ .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx,
+ .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx,
+ .setpfccfg = bnx2x_dcbnl_set_pfc_cfg,
+ .getpfccfg = bnx2x_dcbnl_get_pfc_cfg,
+ .setall = bnx2x_dcbnl_set_all,
+ .getcap = bnx2x_dcbnl_get_cap,
+ .getnumtcs = bnx2x_dcbnl_get_numtcs,
+ .setnumtcs = bnx2x_dcbnl_set_numtcs,
+ .getpfcstate = bnx2x_dcbnl_get_pfc_state,
+ .setpfcstate = bnx2x_dcbnl_set_pfc_state,
+ .setapp = bnx2x_dcbnl_set_app_up,
+ .getdcbx = bnx2x_dcbnl_get_dcbx,
+ .setdcbx = bnx2x_dcbnl_set_dcbx,
+ .getfeatcfg = bnx2x_dcbnl_get_featcfg,
+ .setfeatcfg = bnx2x_dcbnl_set_featcfg,
+ .peer_getappinfo = bnx2x_peer_appinfo,
+ .peer_getapptable = bnx2x_peer_apptable,
+ .cee_peer_getpg = bnx2x_cee_peer_getpg,
+ .cee_peer_getpfc = bnx2x_cee_peer_getpfc,
+};
+
+#endif /* BCM_DCBNL */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h
new file mode 100644
index 00000000000..c6939ecb02c
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h
@@ -0,0 +1,205 @@
+/* bnx2x_dcb.h: Broadcom Everest network driver.
+ *
+ * Copyright 2009-2013 Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available
+ * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *
+ * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
+ * Written by: Dmitry Kravkov
+ *
+ */
+#ifndef BNX2X_DCB_H
+#define BNX2X_DCB_H
+
+#include "bnx2x_hsi.h"
+
+#define LLFC_DRIVER_TRAFFIC_TYPE_MAX 3 /* NW, iSCSI, FCoE */
+struct bnx2x_dcbx_app_params {
+ u32 enabled;
+ u32 traffic_type_priority[LLFC_DRIVER_TRAFFIC_TYPE_MAX];
+};
+
+#define DCBX_COS_MAX_NUM_E2 DCBX_E2E3_MAX_NUM_COS
+/* bnx2x currently limits numbers of supported COSes to 3 to be extended to 6 */
+#define BNX2X_MAX_COS_SUPPORT 3
+#define DCBX_COS_MAX_NUM_E3B0 BNX2X_MAX_COS_SUPPORT
+#define DCBX_COS_MAX_NUM BNX2X_MAX_COS_SUPPORT
+
+struct bnx2x_dcbx_cos_params {
+ u32 bw_tbl;
+ u32 pri_bitmask;
+ /*
+ * strict priority: valid values are 0..5; 0 is highest priority.
+ * There can't be two COSes with the same priority.
+ */
+ u8 strict;
+#define BNX2X_DCBX_STRICT_INVALID DCBX_COS_MAX_NUM
+#define BNX2X_DCBX_STRICT_COS_HIGHEST 0
+#define BNX2X_DCBX_STRICT_COS_NEXT_LOWER_PRI(sp) ((sp) + 1)
+ u8 pauseable;
+};
+
+struct bnx2x_dcbx_pg_params {
+ u32 enabled;
+ u8 num_of_cos; /* valid COS entries */
+ struct bnx2x_dcbx_cos_params cos_params[DCBX_COS_MAX_NUM];
+};
+
+struct bnx2x_dcbx_pfc_params {
+ u32 enabled;
+ u32 priority_non_pauseable_mask;
+};
+
+struct bnx2x_dcbx_port_params {
+ struct bnx2x_dcbx_pfc_params pfc;
+ struct bnx2x_dcbx_pg_params ets;
+ struct bnx2x_dcbx_app_params app;
+};
+
+#define BNX2X_DCBX_CONFIG_INV_VALUE (0xFFFFFFFF)
+#define BNX2X_DCBX_OVERWRITE_SETTINGS_DISABLE 0
+#define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE 1
+#define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID (BNX2X_DCBX_CONFIG_INV_VALUE)
+#define BNX2X_IS_ETS_ENABLED(bp) ((bp)->dcb_state == BNX2X_DCB_STATE_ON &&\
+ (bp)->dcbx_port_params.ets.enabled)
+
+struct bnx2x_config_lldp_params {
+ u32 overwrite_settings;
+ u32 msg_tx_hold;
+ u32 msg_fast_tx;
+ u32 tx_credit_max;
+ u32 msg_tx_interval;
+ u32 tx_fast;
+};
+
+struct bnx2x_admin_priority_app_table {
+ u32 valid;
+ u32 priority;
+#define INVALID_TRAFFIC_TYPE_PRIORITY (0xFFFFFFFF)
+ u32 traffic_type;
+#define TRAFFIC_TYPE_ETH 0
+#define TRAFFIC_TYPE_PORT 1
+ u32 app_id;
+};
+
+#define DCBX_CONFIG_MAX_APP_PROTOCOL 4
+struct bnx2x_config_dcbx_params {
+ u32 overwrite_settings;
+ u32 admin_dcbx_version;
+ u32 admin_ets_enable;
+ u32 admin_pfc_enable;
+ u32 admin_tc_supported_tx_enable;
+ u32 admin_ets_configuration_tx_enable;
+ u32 admin_ets_recommendation_tx_enable;
+ u32 admin_pfc_tx_enable;
+ u32 admin_application_priority_tx_enable;
+ u32 admin_ets_willing;
+ u32 admin_ets_reco_valid;
+ u32 admin_pfc_willing;
+ u32 admin_app_priority_willing;
+ u32 admin_configuration_bw_precentage[8];
+ u32 admin_configuration_ets_pg[8];
+ u32 admin_recommendation_bw_precentage[8];
+ u32 admin_recommendation_ets_pg[8];
+ u32 admin_pfc_bitmap;
+ struct bnx2x_admin_priority_app_table
+ admin_priority_app_table[DCBX_CONFIG_MAX_APP_PROTOCOL];
+ u32 admin_default_priority;
+};
+
+#define GET_FLAGS(flags, bits) ((flags) & (bits))
+#define SET_FLAGS(flags, bits) ((flags) |= (bits))
+#define RESET_FLAGS(flags, bits) ((flags) &= ~(bits))
+
+enum {
+ DCBX_READ_LOCAL_MIB,
+ DCBX_READ_REMOTE_MIB
+};
+
+#define ETH_TYPE_FCOE (0x8906)
+#define TCP_PORT_ISCSI (0xCBC)
+
+#define PFC_VALUE_FRAME_SIZE (512)
+#define PFC_QUANTA_IN_NANOSEC_FROM_SPEED_MEGA(mega_speed) \
+ ((1000 * PFC_VALUE_FRAME_SIZE)/(mega_speed))
+
+#define PFC_BRB1_REG_HIGH_LLFC_LOW_THRESHOLD 130
+#define PFC_BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD 170
+
+struct cos_entry_help_data {
+ u32 pri_join_mask;
+ u32 cos_bw;
+ u8 strict;
+ bool pausable;
+};
+
+struct cos_help_data {
+ struct cos_entry_help_data data[DCBX_COS_MAX_NUM];
+ u8 num_of_cos;
+};
+
+#define DCBX_ILLEGAL_PG (0xFF)
+#define DCBX_PFC_PRI_MASK (0xFF)
+#define DCBX_STRICT_PRIORITY (15)
+#define DCBX_INVALID_COS_BW (0xFFFFFFFF)
+#define DCBX_PFC_PRI_NON_PAUSE_MASK(bp) \
+ ((bp)->dcbx_port_params.pfc.priority_non_pauseable_mask)
+#define DCBX_PFC_PRI_PAUSE_MASK(bp) \
+ ((u8)~DCBX_PFC_PRI_NON_PAUSE_MASK(bp))
+#define DCBX_PFC_PRI_GET_PAUSE(bp, pg_pri) \
+ ((pg_pri) & (DCBX_PFC_PRI_PAUSE_MASK(bp)))
+#define DCBX_PFC_PRI_GET_NON_PAUSE(bp, pg_pri) \
+ (DCBX_PFC_PRI_NON_PAUSE_MASK(bp) & (pg_pri))
+#define DCBX_IS_PFC_PRI_SOME_PAUSE(bp, pg_pri) \
+ (0 != DCBX_PFC_PRI_GET_PAUSE(bp, pg_pri))
+#define IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pg_pri) \
+ (pg_pri == DCBX_PFC_PRI_GET_PAUSE((bp), (pg_pri)))
+#define IS_DCBX_PFC_PRI_ONLY_NON_PAUSE(bp, pg_pri)\
+ ((pg_pri) == DCBX_PFC_PRI_GET_NON_PAUSE((bp), (pg_pri)))
+#define IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pg_pri) \
+ (!(IS_DCBX_PFC_PRI_ONLY_NON_PAUSE((bp), (pg_pri)) || \
+ IS_DCBX_PFC_PRI_ONLY_PAUSE((bp), (pg_pri))))
+
+struct pg_entry_help_data {
+ u8 num_of_dif_pri;
+ u8 pg;
+ u32 pg_priority;
+};
+
+struct pg_help_data {
+ struct pg_entry_help_data data[LLFC_DRIVER_TRAFFIC_TYPE_MAX];
+ u8 num_of_pg;
+};
+
+/* forward DCB/PFC related declarations */
+struct bnx2x;
+void bnx2x_dcbx_update(struct work_struct *work);
+void bnx2x_dcbx_init_params(struct bnx2x *bp);
+void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled);
+
+enum {
+ BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1,
+ BNX2X_DCBX_STATE_TX_PAUSED,
+ BNX2X_DCBX_STATE_TX_RELEASED
+};
+
+void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
+void bnx2x_dcbx_pmf_update(struct bnx2x *bp);
+/* DCB netlink */
+#ifdef BCM_DCBNL
+extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops;
+int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall);
+#endif /* BCM_DCBNL */
+
+int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
+int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp);
+
+#endif /* BNX2X_DCB_H */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h
new file mode 100644
index 00000000000..12eb4baee9f
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h
@@ -0,0 +1,2220 @@
+/* bnx2x_dump.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2012-2013 Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available
+ * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ */
+
+#ifndef BNX2X_DUMP_H
+#define BNX2X_DUMP_H
+
+/* WaitP Definitions */
+#define DRV_DUMP_XSTORM_WAITP_ADDRESS 0x2b8a80
+#define DRV_DUMP_TSTORM_WAITP_ADDRESS 0x1b8a80
+#define DRV_DUMP_USTORM_WAITP_ADDRESS 0x338a80
+#define DRV_DUMP_CSTORM_WAITP_ADDRESS 0x238a80
+
+/* Possible Chips */
+#define DUMP_CHIP_E1 1
+#define DUMP_CHIP_E1H 2
+#define DUMP_CHIP_E2 4
+#define DUMP_CHIP_E3A0 8
+#define DUMP_CHIP_E3B0 16
+#define DUMP_PATH_0 512
+#define DUMP_PATH_1 1024
+#define NUM_PRESETS 13
+#define NUM_CHIPS 5
+
+struct dump_header {
+ u32 header_size; /* Size in DWORDs excluding this field */
+ u32 version;
+ u32 preset;
+ u32 dump_meta_data; /* OR of CHIP and PATH. */
+};
+
+#define BNX2X_DUMP_VERSION 0x50acff01
+struct reg_addr {
+ u32 addr;
+ u32 size;
+ u32 chips;
+ u32 presets;
+};
+
+struct wreg_addr {
+ u32 addr;
+ u32 size;
+ u32 read_regs_count;
+ const u32 *read_regs;
+ u32 chips;
+ u32 presets;
+};
+
+#define PAGE_MODE_VALUES_E2 2
+#define PAGE_READ_REGS_E2 1
+#define PAGE_WRITE_REGS_E2 1
+static const u32 page_vals_e2[] = {0, 128};
+static const u32 page_write_regs_e2[] = {328476};
+static const struct reg_addr page_read_regs_e2[] = {
+ {0x58000, 4608, DUMP_CHIP_E2, 0x30}
+};
+
+#define PAGE_MODE_VALUES_E3 2
+#define PAGE_READ_REGS_E3 1
+#define PAGE_WRITE_REGS_E3 1
+static const u32 page_vals_e3[] = {0, 128};
+static const u32 page_write_regs_e3[] = {328476};
+static const struct reg_addr page_read_regs_e3[] = {
+ {0x58000, 4608, DUMP_CHIP_E3A0 | DUMP_CHIP_E3B0, 0x30}
+};
+
+static const struct reg_addr reg_addrs[] = {
+ { 0x2000, 1, 0x1f, 0xfff},
+ { 0x2004, 1, 0x1f, 0x1fff},
+ { 0x2008, 25, 0x1f, 0xfff},
+ { 0x206c, 1, 0x1f, 0x1fff},
+ { 0x2070, 313, 0x1f, 0xfff},
+ { 0x2800, 103, 0x1f, 0xfff},
+ { 0x3000, 287, 0x1f, 0xfff},
+ { 0x3800, 331, 0x1f, 0xfff},
+ { 0x8800, 6, 0x1f, 0x924},
+ { 0x8818, 1, 0x1e, 0x924},
+ { 0x9000, 4, 0x1c, 0x924},
+ { 0x9010, 7, 0x1c, 0xfff},
+ { 0x902c, 1, 0x1c, 0x924},
+ { 0x9030, 1, 0x1c, 0xfff},
+ { 0x9034, 13, 0x1c, 0x924},
+ { 0x9068, 16, 0x1c, 0xfff},
+ { 0x90a8, 98, 0x1c, 0x924},
+ { 0x9230, 2, 0x1c, 0xfff},
+ { 0x9238, 3, 0x1c, 0x924},
+ { 0x9244, 1, 0x1c, 0xfff},
+ { 0x9248, 1, 0x1c, 0x924},
+ { 0x924c, 1, 0x4, 0x924},
+ { 0x9250, 16, 0x1c, 0x924},
+ { 0x92a8, 2, 0x1c, 0x1fff},
+ { 0x92b4, 1, 0x1c, 0x1fff},
+ { 0x9400, 33, 0x1c, 0x924},
+ { 0x9484, 5, 0x18, 0x924},
+ { 0xa000, 27, 0x1f, 0x924},
+ { 0xa06c, 1, 0x3, 0x924},
+ { 0xa070, 2, 0x1f, 0x924},
+ { 0xa078, 1, 0x1f, 0x1fff},
+ { 0xa07c, 31, 0x1f, 0x924},
+ { 0xa0f8, 1, 0x1f, 0x1fff},
+ { 0xa0fc, 3, 0x1f, 0x924},
+ { 0xa108, 1, 0x1f, 0x1fff},
+ { 0xa10c, 3, 0x1f, 0x924},
+ { 0xa118, 1, 0x1f, 0x1fff},
+ { 0xa11c, 28, 0x1f, 0x924},
+ { 0xa18c, 4, 0x3, 0x924},
+ { 0xa19c, 3, 0x1f, 0x924},
+ { 0xa1a8, 1, 0x1f, 0x1fff},
+ { 0xa1ac, 3, 0x1f, 0x924},
+ { 0xa1b8, 1, 0x1f, 0x1fff},
+ { 0xa1bc, 54, 0x1f, 0x924},
+ { 0xa294, 2, 0x3, 0x924},
+ { 0xa29c, 2, 0x1f, 0x924},
+ { 0xa2a4, 2, 0x7, 0x924},
+ { 0xa2ac, 2, 0x1f, 0x924},
+ { 0xa2b4, 1, 0x1f, 0x1fff},
+ { 0xa2b8, 49, 0x1f, 0x924},
+ { 0xa38c, 2, 0x1f, 0x1fff},
+ { 0xa398, 1, 0x1f, 0x1fff},
+ { 0xa39c, 7, 0x1e, 0x924},
+ { 0xa3b8, 2, 0x18, 0x924},
+ { 0xa3c0, 1, 0x1e, 0x924},
+ { 0xa3c4, 1, 0x1e, 0xfff},
+ { 0xa3c8, 1, 0x1e, 0x924},
+ { 0xa3d0, 1, 0x1e, 0x924},
+ { 0xa3d8, 1, 0x1e, 0x924},
+ { 0xa3e0, 1, 0x1e, 0x924},
+ { 0xa3e8, 1, 0x1e, 0x924},
+ { 0xa3f0, 1, 0x1e, 0x924},
+ { 0xa3f8, 1, 0x1e, 0x924},
+ { 0xa400, 1, 0x1f, 0x924},
+ { 0xa404, 1, 0x1f, 0xfff},
+ { 0xa408, 2, 0x1f, 0x1fff},
+ { 0xa410, 7, 0x1f, 0x924},
+ { 0xa42c, 12, 0x1f, 0xfff},
+ { 0xa45c, 1, 0x1f, 0x924},
+ { 0xa460, 1, 0x1f, 0x1924},
+ { 0xa464, 15, 0x1f, 0x924},
+ { 0xa4a0, 1, 0x7, 0x924},
+ { 0xa4a4, 2, 0x1f, 0x924},
+ { 0xa4ac, 2, 0x3, 0x924},
+ { 0xa4b4, 1, 0x7, 0x924},
+ { 0xa4b8, 2, 0x3, 0x924},
+ { 0xa4c0, 3, 0x1f, 0x924},
+ { 0xa4cc, 5, 0x3, 0x924},
+ { 0xa4e0, 3, 0x1f, 0x924},
+ { 0xa4fc, 2, 0x1f, 0x924},
+ { 0xa504, 1, 0x3, 0x924},
+ { 0xa508, 3, 0x1f, 0x924},
+ { 0xa518, 1, 0x1f, 0x924},
+ { 0xa520, 1, 0x1f, 0x924},
+ { 0xa528, 1, 0x1f, 0x924},
+ { 0xa530, 1, 0x1f, 0x924},
+ { 0xa538, 1, 0x1f, 0x924},
+ { 0xa540, 1, 0x1f, 0x924},
+ { 0xa548, 1, 0x3, 0x924},
+ { 0xa550, 1, 0x3, 0x924},
+ { 0xa558, 1, 0x3, 0x924},
+ { 0xa560, 1, 0x3, 0x924},
+ { 0xa568, 1, 0x3, 0x924},
+ { 0xa570, 1, 0x1f, 0x924},
+ { 0xa580, 1, 0x1f, 0x1fff},
+ { 0xa590, 1, 0x1f, 0x1fff},
+ { 0xa5a0, 1, 0x7, 0x924},
+ { 0xa5c0, 1, 0x1f, 0x924},
+ { 0xa5e0, 1, 0x1e, 0x924},
+ { 0xa5e8, 1, 0x1e, 0x924},
+ { 0xa5f0, 1, 0x1e, 0x924},
+ { 0xa5f8, 1, 0x6, 0x924},
+ { 0xa5fc, 1, 0x1e, 0x924},
+ { 0xa600, 5, 0x1e, 0xfff},
+ { 0xa614, 1, 0x1e, 0x924},
+ { 0xa618, 1, 0x1e, 0xfff},
+ { 0xa61c, 1, 0x1e, 0x924},
+ { 0xa620, 6, 0x1c, 0x924},
+ { 0xa638, 20, 0x4, 0x924},
+ { 0xa688, 35, 0x1c, 0x924},
+ { 0xa714, 1, 0x1c, 0xfff},
+ { 0xa718, 2, 0x1c, 0x924},
+ { 0xa720, 1, 0x1c, 0xfff},
+ { 0xa724, 3, 0x1c, 0x924},
+ { 0xa730, 1, 0x4, 0x924},
+ { 0xa734, 2, 0x1c, 0x924},
+ { 0xa73c, 4, 0x4, 0x924},
+ { 0xa74c, 1, 0x1c, 0x924},
+ { 0xa750, 1, 0x1c, 0xfff},
+ { 0xa754, 3, 0x1c, 0x924},
+ { 0xa760, 5, 0x4, 0x924},
+ { 0xa774, 7, 0x1c, 0x924},
+ { 0xa790, 15, 0x4, 0x924},
+ { 0xa7cc, 4, 0x1c, 0x924},
+ { 0xa7e0, 6, 0x18, 0x924},
+ { 0xa800, 18, 0x4, 0x924},
+ { 0xa848, 33, 0x1c, 0x924},
+ { 0xa8cc, 2, 0x18, 0x924},
+ { 0xa8d4, 4, 0x1c, 0x924},
+ { 0xa8e4, 1, 0x18, 0x924},
+ { 0xa8e8, 1, 0x1c, 0x924},
+ { 0xa8f0, 1, 0x1c, 0x924},
+ { 0xa8f8, 30, 0x18, 0x924},
+ { 0xa974, 73, 0x18, 0x924},
+ { 0xac30, 1, 0x18, 0x924},
+ { 0xac40, 1, 0x18, 0x924},
+ { 0xac50, 1, 0x18, 0x924},
+ { 0xac60, 1, 0x10, 0x924},
+ { 0x10000, 9, 0x1f, 0x924},
+ { 0x10024, 1, 0x7, 0x924},
+ { 0x10028, 5, 0x1f, 0x924},
+ { 0x1003c, 6, 0x7, 0x924},
+ { 0x10054, 20, 0x1f, 0x924},
+ { 0x100a4, 4, 0x7, 0x924},
+ { 0x100b4, 11, 0x1f, 0x924},
+ { 0x100e0, 4, 0x7, 0x924},
+ { 0x100f0, 8, 0x1f, 0x924},
+ { 0x10110, 6, 0x7, 0x924},
+ { 0x10128, 110, 0x1f, 0x924},
+ { 0x102e0, 4, 0x7, 0x924},
+ { 0x102f0, 18, 0x1f, 0x924},
+ { 0x10338, 20, 0x7, 0x924},
+ { 0x10388, 10, 0x1f, 0x924},
+ { 0x103d0, 2, 0x3, 0x1fff},
+ { 0x103dc, 1, 0x3, 0x1fff},
+ { 0x10400, 6, 0x7, 0x924},
+ { 0x10418, 1, 0x1f, 0xfff},
+ { 0x1041c, 1, 0x1f, 0x924},
+ { 0x10420, 1, 0x1f, 0xfff},
+ { 0x10424, 1, 0x1f, 0x924},
+ { 0x10428, 1, 0x1f, 0xfff},
+ { 0x1042c, 1, 0x1f, 0x924},
+ { 0x10430, 10, 0x7, 0x924},
+ { 0x10458, 2, 0x1f, 0x924},
+ { 0x10460, 1, 0x1f, 0xfff},
+ { 0x10464, 4, 0x1f, 0x924},
+ { 0x10474, 1, 0x1f, 0xfff},
+ { 0x10478, 14, 0x1f, 0x924},
+ { 0x104b0, 12, 0x7, 0x924},
+ { 0x104e0, 1, 0x1f, 0xfff},
+ { 0x104e8, 1, 0x1f, 0x924},
+ { 0x104ec, 1, 0x1f, 0xfff},
+ { 0x104f4, 1, 0x1f, 0x924},
+ { 0x104f8, 1, 0x1f, 0xfff},
+ { 0x10500, 2, 0x1f, 0x924},
+ { 0x10508, 1, 0x1f, 0xfff},
+ { 0x1050c, 9, 0x1f, 0x924},
+ { 0x10530, 1, 0x1f, 0xfff},
+ { 0x10534, 1, 0x1f, 0x924},
+ { 0x10538, 1, 0x1f, 0xfff},
+ { 0x1053c, 3, 0x1f, 0x924},
+ { 0x10548, 1, 0x1f, 0xfff},
+ { 0x1054c, 3, 0x1f, 0x924},
+ { 0x10558, 1, 0x1f, 0xfff},
+ { 0x1055c, 123, 0x1f, 0x924},
+ { 0x10750, 2, 0x7, 0x924},
+ { 0x10760, 2, 0x7, 0x924},
+ { 0x10770, 2, 0x7, 0x924},
+ { 0x10780, 2, 0x7, 0x924},
+ { 0x10790, 2, 0x1f, 0x924},
+ { 0x107a0, 2, 0x7, 0x924},
+ { 0x107b0, 2, 0x7, 0x924},
+ { 0x107c0, 2, 0x7, 0x924},
+ { 0x107d0, 2, 0x7, 0x924},
+ { 0x107e0, 2, 0x1f, 0x924},
+ { 0x10880, 2, 0x1f, 0x924},
+ { 0x10900, 2, 0x1f, 0x924},
+ { 0x16000, 1, 0x6, 0x924},
+ { 0x16004, 25, 0x1e, 0x924},
+ { 0x16070, 8, 0x1e, 0x924},
+ { 0x16090, 4, 0xe, 0x924},
+ { 0x160a0, 6, 0x1e, 0x924},
+ { 0x160c0, 7, 0x1e, 0x924},
+ { 0x160dc, 2, 0x6, 0x924},
+ { 0x160e4, 6, 0x1e, 0x924},
+ { 0x160fc, 4, 0x1e, 0x1fff},
+ { 0x1610c, 2, 0x6, 0x924},
+ { 0x16114, 6, 0x1e, 0x924},
+ { 0x16140, 48, 0x1e, 0x1fff},
+ { 0x16204, 5, 0x1e, 0x924},
+ { 0x18000, 1, 0x1e, 0x924},
+ { 0x18008, 1, 0x1e, 0x924},
+ { 0x18010, 35, 0x1c, 0x924},
+ { 0x180a4, 2, 0x1c, 0x924},
+ { 0x180c0, 9, 0x1c, 0x924},
+ { 0x180e4, 1, 0xc, 0x924},
+ { 0x180e8, 2, 0x1c, 0x924},
+ { 0x180f0, 1, 0xc, 0x924},
+ { 0x180f4, 79, 0x1c, 0x924},
+ { 0x18230, 1, 0xc, 0x924},
+ { 0x18234, 2, 0x1c, 0x924},
+ { 0x1823c, 1, 0xc, 0x924},
+ { 0x18240, 13, 0x1c, 0x924},
+ { 0x18274, 1, 0x4, 0x924},
+ { 0x18278, 12, 0x1c, 0x924},
+ { 0x182a8, 1, 0x1c, 0xfff},
+ { 0x182ac, 3, 0x1c, 0x924},
+ { 0x182b8, 1, 0x1c, 0xfff},
+ { 0x182bc, 19, 0x1c, 0x924},
+ { 0x18308, 1, 0x1c, 0xfff},
+ { 0x1830c, 3, 0x1c, 0x924},
+ { 0x18318, 1, 0x1c, 0xfff},
+ { 0x1831c, 7, 0x1c, 0x924},
+ { 0x18338, 1, 0x1c, 0xfff},
+ { 0x1833c, 3, 0x1c, 0x924},
+ { 0x18348, 1, 0x1c, 0xfff},
+ { 0x1834c, 28, 0x1c, 0x924},
+ { 0x183bc, 2, 0x1c, 0x1fff},
+ { 0x183c8, 3, 0x1c, 0x1fff},
+ { 0x183d8, 1, 0x1c, 0x1fff},
+ { 0x18440, 48, 0x1c, 0x1fff},
+ { 0x18500, 15, 0x1c, 0x924},
+ { 0x18570, 1, 0x18, 0xfff},
+ { 0x18574, 1, 0x18, 0x924},
+ { 0x18578, 1, 0x18, 0xfff},
+ { 0x1857c, 4, 0x18, 0x924},
+ { 0x1858c, 1, 0x18, 0xfff},
+ { 0x18590, 1, 0x18, 0x924},
+ { 0x18594, 1, 0x18, 0xfff},
+ { 0x18598, 32, 0x18, 0x924},
+ { 0x18618, 5, 0x10, 0x924},
+ { 0x1862c, 4, 0x10, 0xfff},
+ { 0x1863c, 16, 0x10, 0x924},
+ { 0x18680, 44, 0x10, 0x924},
+ { 0x18748, 12, 0x10, 0x924},
+ { 0x18788, 1, 0x10, 0x924},
+ { 0x1879c, 6, 0x10, 0x924},
+ { 0x187c4, 51, 0x10, 0x924},
+ { 0x18a00, 48, 0x10, 0x924},
+ { 0x20000, 24, 0x1f, 0x924},
+ { 0x20060, 8, 0x1f, 0x9e4},
+ { 0x20080, 94, 0x1f, 0x924},
+ { 0x201f8, 1, 0x3, 0x924},
+ { 0x201fc, 1, 0x1f, 0x924},
+ { 0x20200, 1, 0x3, 0x924},
+ { 0x20204, 1, 0x1f, 0x924},
+ { 0x20208, 1, 0x3, 0x924},
+ { 0x2020c, 4, 0x1f, 0x924},
+ { 0x2021c, 11, 0x1f, 0xfff},
+ { 0x20248, 24, 0x1f, 0x924},
+ { 0x202b8, 2, 0x1f, 0x1fff},
+ { 0x202c4, 1, 0x1f, 0x1fff},
+ { 0x202c8, 1, 0x1c, 0x924},
+ { 0x202d8, 4, 0x1c, 0x924},
+ { 0x202f0, 1, 0x10, 0x924},
+ { 0x20400, 1, 0x1f, 0x924},
+ { 0x20404, 1, 0x1f, 0xfff},
+ { 0x2040c, 2, 0x1f, 0xfff},
+ { 0x20414, 2, 0x1f, 0x924},
+ { 0x2041c, 2, 0x1f, 0xfff},
+ { 0x20424, 2, 0x1f, 0x924},
+ { 0x2042c, 18, 0x1e, 0x924},
+ { 0x20480, 1, 0x1f, 0x924},
+ { 0x20500, 1, 0x1f, 0x924},
+ { 0x20600, 1, 0x1f, 0x924},
+ { 0x28000, 1, 0x1f, 0x9e4},
+ { 0x28004, 255, 0x1f, 0x180},
+ { 0x28400, 1, 0x1f, 0x1c0},
+ { 0x28404, 255, 0x1f, 0x180},
+ { 0x28800, 1, 0x1f, 0x1c0},
+ { 0x28804, 255, 0x1f, 0x180},
+ { 0x28c00, 1, 0x1f, 0x1c0},
+ { 0x28c04, 255, 0x1f, 0x180},
+ { 0x29000, 1, 0x1f, 0x1c0},
+ { 0x29004, 255, 0x1f, 0x180},
+ { 0x29400, 1, 0x1f, 0x1c0},
+ { 0x29404, 255, 0x1f, 0x180},
+ { 0x29800, 1, 0x1f, 0x1c0},
+ { 0x29804, 255, 0x1f, 0x180},
+ { 0x29c00, 1, 0x1f, 0x1c0},
+ { 0x29c04, 255, 0x1f, 0x180},
+ { 0x2a000, 1, 0x1f, 0x1c0},
+ { 0x2a004, 255, 0x1f, 0x180},
+ { 0x2a400, 1, 0x1f, 0x1c0},
+ { 0x2a404, 255, 0x1f, 0x180},
+ { 0x2a800, 1, 0x1f, 0x1c0},
+ { 0x2a804, 255, 0x1f, 0x180},
+ { 0x2ac00, 1, 0x1f, 0x1c0},
+ { 0x2ac04, 255, 0x1f, 0x180},
+ { 0x2b000, 1, 0x1f, 0x1c0},
+ { 0x2b004, 255, 0x1f, 0x180},
+ { 0x2b400, 1, 0x1f, 0x1c0},
+ { 0x2b404, 255, 0x1f, 0x180},
+ { 0x2b800, 1, 0x1f, 0x1c0},
+ { 0x2b804, 255, 0x1f, 0x180},
+ { 0x2bc00, 1, 0x1f, 0x1c0},
+ { 0x2bc04, 255, 0x1f, 0x180},
+ { 0x2c000, 1, 0x1f, 0x1c0},
+ { 0x2c004, 255, 0x1f, 0x180},
+ { 0x2c400, 1, 0x1f, 0x1c0},
+ { 0x2c404, 255, 0x1f, 0x180},
+ { 0x2c800, 1, 0x1f, 0x1c0},
+ { 0x2c804, 255, 0x1f, 0x180},
+ { 0x2cc00, 1, 0x1f, 0x1c0},
+ { 0x2cc04, 255, 0x1f, 0x180},
+ { 0x2d000, 1, 0x1f, 0x1c0},
+ { 0x2d004, 255, 0x1f, 0x180},
+ { 0x2d400, 1, 0x1f, 0x1c0},
+ { 0x2d404, 255, 0x1f, 0x180},
+ { 0x2d800, 1, 0x1f, 0x1c0},
+ { 0x2d804, 255, 0x1f, 0x180},
+ { 0x2dc00, 1, 0x1f, 0x1c0},
+ { 0x2dc04, 255, 0x1f, 0x180},
+ { 0x2e000, 1, 0x1f, 0x1c0},
+ { 0x2e004, 255, 0x1f, 0x180},
+ { 0x2e400, 1, 0x1f, 0x1c0},
+ { 0x2e404, 255, 0x1f, 0x180},
+ { 0x2e800, 1, 0x1f, 0x1c0},
+ { 0x2e804, 255, 0x1f, 0x180},
+ { 0x2ec00, 1, 0x1f, 0x1c0},
+ { 0x2ec04, 255, 0x1f, 0x180},
+ { 0x2f000, 1, 0x1f, 0x1c0},
+ { 0x2f004, 255, 0x1f, 0x180},
+ { 0x2f400, 1, 0x1f, 0x1c0},
+ { 0x2f404, 255, 0x1f, 0x180},
+ { 0x2f800, 1, 0x1f, 0x1c0},
+ { 0x2f804, 255, 0x1f, 0x180},
+ { 0x2fc00, 1, 0x1f, 0x1c0},
+ { 0x2fc04, 255, 0x1f, 0x180},
+ { 0x30000, 1, 0x1f, 0x9e4},
+ { 0x30004, 255, 0x1f, 0x180},
+ { 0x30400, 1, 0x1f, 0x1c0},
+ { 0x30404, 255, 0x1f, 0x180},
+ { 0x30800, 1, 0x1f, 0x1c0},
+ { 0x30804, 255, 0x1f, 0x180},
+ { 0x30c00, 1, 0x1f, 0x1c0},
+ { 0x30c04, 255, 0x1f, 0x180},
+ { 0x31000, 1, 0x1f, 0x1c0},
+ { 0x31004, 255, 0x1f, 0x180},
+ { 0x31400, 1, 0x1f, 0x1c0},
+ { 0x31404, 255, 0x1f, 0x180},
+ { 0x31800, 1, 0x1f, 0x1c0},
+ { 0x31804, 255, 0x1f, 0x180},
+ { 0x31c00, 1, 0x1f, 0x1c0},
+ { 0x31c04, 255, 0x1f, 0x180},
+ { 0x32000, 1, 0x1f, 0x1c0},
+ { 0x32004, 255, 0x1f, 0x180},
+ { 0x32400, 1, 0x1f, 0x1c0},
+ { 0x32404, 255, 0x1f, 0x180},
+ { 0x32800, 1, 0x1f, 0x1c0},
+ { 0x32804, 255, 0x1f, 0x180},
+ { 0x32c00, 1, 0x1f, 0x1c0},
+ { 0x32c04, 255, 0x1f, 0x180},
+ { 0x33000, 1, 0x1f, 0x1c0},
+ { 0x33004, 255, 0x1f, 0x180},
+ { 0x33400, 1, 0x1f, 0x1c0},
+ { 0x33404, 255, 0x1f, 0x180},
+ { 0x33800, 1, 0x1f, 0x1c0},
+ { 0x33804, 255, 0x1f, 0x180},
+ { 0x33c00, 1, 0x1f, 0x1c0},
+ { 0x33c04, 255, 0x1f, 0x180},
+ { 0x34000, 1, 0x1f, 0x1c0},
+ { 0x34004, 255, 0x1f, 0x180},
+ { 0x34400, 1, 0x1f, 0x1c0},
+ { 0x34404, 255, 0x1f, 0x180},
+ { 0x34800, 1, 0x1f, 0x1c0},
+ { 0x34804, 255, 0x1f, 0x180},
+ { 0x34c00, 1, 0x1f, 0x1c0},
+ { 0x34c04, 255, 0x1f, 0x180},
+ { 0x35000, 1, 0x1f, 0x1c0},
+ { 0x35004, 255, 0x1f, 0x180},
+ { 0x35400, 1, 0x1f, 0x1c0},
+ { 0x35404, 255, 0x1f, 0x180},
+ { 0x35800, 1, 0x1f, 0x1c0},
+ { 0x35804, 255, 0x1f, 0x180},
+ { 0x35c00, 1, 0x1f, 0x1c0},
+ { 0x35c04, 255, 0x1f, 0x180},
+ { 0x36000, 1, 0x1f, 0x1c0},
+ { 0x36004, 255, 0x1f, 0x180},
+ { 0x36400, 1, 0x1f, 0x1c0},
+ { 0x36404, 255, 0x1f, 0x180},
+ { 0x36800, 1, 0x1f, 0x1c0},
+ { 0x36804, 255, 0x1f, 0x180},
+ { 0x36c00, 1, 0x1f, 0x1c0},
+ { 0x36c04, 255, 0x1f, 0x180},
+ { 0x37000, 1, 0x1f, 0x1c0},
+ { 0x37004, 255, 0x1f, 0x180},
+ { 0x37400, 1, 0x1f, 0x1c0},
+ { 0x37404, 255, 0x1f, 0x180},
+ { 0x37800, 1, 0x1f, 0x1c0},
+ { 0x37804, 255, 0x1f, 0x180},
+ { 0x37c00, 1, 0x1f, 0x1c0},
+ { 0x37c04, 255, 0x1f, 0x180},
+ { 0x38000, 1, 0x1f, 0x1c0},
+ { 0x38004, 255, 0x1f, 0x180},
+ { 0x38400, 1, 0x1f, 0x1c0},
+ { 0x38404, 255, 0x1f, 0x180},
+ { 0x38800, 1, 0x1f, 0x1c0},
+ { 0x38804, 255, 0x1f, 0x180},
+ { 0x38c00, 1, 0x1f, 0x1c0},
+ { 0x38c04, 255, 0x1f, 0x180},
+ { 0x39000, 1, 0x1f, 0x1c0},
+ { 0x39004, 255, 0x1f, 0x180},
+ { 0x39400, 1, 0x1f, 0x1c0},
+ { 0x39404, 255, 0x1f, 0x180},
+ { 0x39800, 1, 0x1f, 0x1c0},
+ { 0x39804, 255, 0x1f, 0x180},
+ { 0x39c00, 1, 0x1f, 0x1c0},
+ { 0x39c04, 255, 0x1f, 0x180},
+ { 0x3a000, 1, 0x1f, 0x1c0},
+ { 0x3a004, 255, 0x1f, 0x180},
+ { 0x3a400, 1, 0x1f, 0x1c0},
+ { 0x3a404, 255, 0x1f, 0x180},
+ { 0x3a800, 1, 0x1f, 0x1c0},
+ { 0x3a804, 255, 0x1f, 0x180},
+ { 0x3ac00, 1, 0x1f, 0x1c0},
+ { 0x3ac04, 255, 0x1f, 0x180},
+ { 0x3b000, 1, 0x1f, 0x1c0},
+ { 0x3b004, 255, 0x1f, 0x180},
+ { 0x3b400, 1, 0x1f, 0x1c0},
+ { 0x3b404, 255, 0x1f, 0x180},
+ { 0x3b800, 1, 0x1f, 0x1c0},
+ { 0x3b804, 255, 0x1f, 0x180},
+ { 0x3bc00, 1, 0x1f, 0x1c0},
+ { 0x3bc04, 255, 0x1f, 0x180},
+ { 0x3c000, 1, 0x1f, 0x1c0},
+ { 0x3c004, 255, 0x1f, 0x180},
+ { 0x3c400, 1, 0x1f, 0x1c0},
+ { 0x3c404, 255, 0x1f, 0x180},
+ { 0x3c800, 1, 0x1f, 0x1c0},
+ { 0x3c804, 255, 0x1f, 0x180},
+ { 0x3cc00, 1, 0x1f, 0x1c0},
+ { 0x3cc04, 255, 0x1f, 0x180},
+ { 0x3d000, 1, 0x1f, 0x1c0},
+ { 0x3d004, 255, 0x1f, 0x180},
+ { 0x3d400, 1, 0x1f, 0x1c0},
+ { 0x3d404, 255, 0x1f, 0x180},
+ { 0x3d800, 1, 0x1f, 0x1c0},
+ { 0x3d804, 255, 0x1f, 0x180},
+ { 0x3dc00, 1, 0x1f, 0x1c0},
+ { 0x3dc04, 255, 0x1f, 0x180},
+ { 0x3e000, 1, 0x1f, 0x1c0},
+ { 0x3e004, 255, 0x1f, 0x180},
+ { 0x3e400, 1, 0x1f, 0x1c0},
+ { 0x3e404, 255, 0x1f, 0x180},
+ { 0x3e800, 1, 0x1f, 0x1c0},
+ { 0x3e804, 255, 0x1f, 0x180},
+ { 0x3ec00, 1, 0x1f, 0x1c0},
+ { 0x3ec04, 255, 0x1f, 0x180},
+ { 0x3f000, 1, 0x1f, 0x1c0},
+ { 0x3f004, 255, 0x1f, 0x180},
+ { 0x3f400, 1, 0x1f, 0x1c0},
+ { 0x3f404, 255, 0x1f, 0x180},
+ { 0x3f800, 1, 0x1f, 0x1c0},
+ { 0x3f804, 255, 0x1f, 0x180},
+ { 0x3fc00, 1, 0x1f, 0x1c0},
+ { 0x3fc04, 255, 0x1f, 0x180},
+ { 0x40000, 85, 0x1f, 0x924},
+ { 0x40154, 13, 0x1f, 0xfff},
+ { 0x40198, 2, 0x1f, 0x1fff},
+ { 0x401a4, 1, 0x1f, 0x1fff},
+ { 0x401a8, 8, 0x1e, 0x924},
+ { 0x401c8, 1, 0x2, 0x924},
+ { 0x401cc, 2, 0x1e, 0x924},
+ { 0x401d4, 2, 0x1c, 0x924},
+ { 0x40200, 4, 0x1f, 0x924},
+ { 0x40220, 6, 0x1c, 0x924},
+ { 0x40238, 8, 0xc, 0x924},
+ { 0x40258, 4, 0x1c, 0x924},
+ { 0x40268, 2, 0x18, 0x924},
+ { 0x40270, 17, 0x10, 0x924},
+ { 0x40400, 43, 0x1f, 0x924},
+ { 0x404bc, 2, 0x1f, 0x1fff},
+ { 0x404c8, 1, 0x1f, 0x1fff},
+ { 0x404cc, 3, 0x1e, 0x924},
+ { 0x404e0, 1, 0x1c, 0x924},
+ { 0x40500, 2, 0x1f, 0x924},
+ { 0x40510, 2, 0x1f, 0x924},
+ { 0x40520, 2, 0x1f, 0x924},
+ { 0x40530, 2, 0x1f, 0x924},
+ { 0x40540, 2, 0x1f, 0x924},
+ { 0x40550, 10, 0x1c, 0x924},
+ { 0x40610, 2, 0x1c, 0x924},
+ { 0x42000, 164, 0x1f, 0x924},
+ { 0x422b0, 2, 0x1f, 0x1fff},
+ { 0x422bc, 1, 0x1f, 0x1fff},
+ { 0x422c0, 4, 0x1c, 0x924},
+ { 0x422d4, 5, 0x1e, 0x924},
+ { 0x422e8, 1, 0x1c, 0x924},
+ { 0x42400, 49, 0x1f, 0x924},
+ { 0x424c8, 32, 0x1f, 0x924},
+ { 0x42548, 1, 0x1f, 0xfff},
+ { 0x4254c, 1, 0x1f, 0x924},
+ { 0x42550, 1, 0x1f, 0xfff},
+ { 0x42554, 1, 0x1f, 0x924},
+ { 0x42558, 1, 0x1f, 0xfff},
+ { 0x4255c, 1, 0x1f, 0x924},
+ { 0x42568, 2, 0x1f, 0x924},
+ { 0x42640, 5, 0x1c, 0x924},
+ { 0x42800, 1, 0x1f, 0x924},
+ { 0x50000, 1, 0x1f, 0x1fff},
+ { 0x50004, 19, 0x1f, 0x924},
+ { 0x50050, 8, 0x1f, 0x93c},
+ { 0x50070, 60, 0x1f, 0x924},
+ { 0x50160, 8, 0x1f, 0xfff},
+ { 0x50180, 20, 0x1f, 0x924},
+ { 0x501e0, 2, 0x1f, 0x1fff},
+ { 0x501ec, 1, 0x1f, 0x1fff},
+ { 0x501f0, 4, 0x1e, 0x924},
+ { 0x50200, 1, 0x1f, 0x924},
+ { 0x50204, 1, 0x1f, 0xfff},
+ { 0x5020c, 2, 0x1f, 0xfff},
+ { 0x50214, 2, 0x1f, 0x924},
+ { 0x5021c, 1, 0x1f, 0xfff},
+ { 0x50220, 2, 0x1f, 0x924},
+ { 0x50228, 6, 0x1e, 0x924},
+ { 0x50240, 1, 0x1f, 0x924},
+ { 0x50280, 1, 0x1f, 0x924},
+ { 0x50300, 1, 0x1c, 0x924},
+ { 0x5030c, 1, 0x1c, 0x924},
+ { 0x50318, 1, 0x1c, 0x934},
+ { 0x5031c, 1, 0x1c, 0x924},
+ { 0x50320, 2, 0x1c, 0x934},
+ { 0x50330, 1, 0x10, 0x924},
+ { 0x52000, 1, 0x1f, 0x924},
+ { 0x54000, 1, 0x1f, 0x93c},
+ { 0x54004, 255, 0x1f, 0x30},
+ { 0x54400, 1, 0x1f, 0x38},
+ { 0x54404, 255, 0x1f, 0x30},
+ { 0x54800, 1, 0x1f, 0x38},
+ { 0x54804, 255, 0x1f, 0x30},
+ { 0x54c00, 1, 0x1f, 0x38},
+ { 0x54c04, 255, 0x1f, 0x30},
+ { 0x55000, 1, 0x1f, 0x38},
+ { 0x55004, 255, 0x1f, 0x30},
+ { 0x55400, 1, 0x1f, 0x38},
+ { 0x55404, 255, 0x1f, 0x30},
+ { 0x55800, 1, 0x1f, 0x38},
+ { 0x55804, 255, 0x1f, 0x30},
+ { 0x55c00, 1, 0x1f, 0x38},
+ { 0x55c04, 255, 0x1f, 0x30},
+ { 0x56000, 1, 0x1f, 0x38},
+ { 0x56004, 255, 0x1f, 0x30},
+ { 0x56400, 1, 0x1f, 0x38},
+ { 0x56404, 255, 0x1f, 0x30},
+ { 0x56800, 1, 0x1f, 0x38},
+ { 0x56804, 255, 0x1f, 0x30},
+ { 0x56c00, 1, 0x1f, 0x38},
+ { 0x56c04, 255, 0x1f, 0x30},
+ { 0x57000, 1, 0x1f, 0x38},
+ { 0x57004, 255, 0x1f, 0x30},
+ { 0x58000, 1, 0x1f, 0x934},
+ { 0x58004, 8191, 0x3, 0x30},
+ { 0x60000, 26, 0x1f, 0x924},
+ { 0x60068, 8, 0x3, 0x924},
+ { 0x60088, 2, 0x1f, 0x924},
+ { 0x60090, 1, 0x1f, 0xfff},
+ { 0x60094, 9, 0x1f, 0x924},
+ { 0x600b8, 9, 0x3, 0x924},
+ { 0x600dc, 1, 0x1f, 0x924},
+ { 0x600e0, 5, 0x3, 0x924},
+ { 0x600f4, 1, 0x7, 0x924},
+ { 0x600f8, 1, 0x3, 0x924},
+ { 0x600fc, 8, 0x1f, 0x924},
+ { 0x6012c, 2, 0x1f, 0x1fff},
+ { 0x60138, 1, 0x1f, 0x1fff},
+ { 0x6013c, 24, 0x2, 0x924},
+ { 0x6019c, 2, 0x1c, 0x924},
+ { 0x601ac, 18, 0x1c, 0x924},
+ { 0x60200, 1, 0x1f, 0xb6d},
+ { 0x60204, 2, 0x1f, 0x249},
+ { 0x60210, 13, 0x1c, 0x924},
+ { 0x60244, 16, 0x10, 0x924},
+ { 0x61000, 1, 0x1f, 0xb6d},
+ { 0x61004, 511, 0x1f, 0x249},
+ { 0x61800, 512, 0x18, 0x249},
+ { 0x70000, 8, 0x1f, 0xb6d},
+ { 0x70020, 8184, 0x1f, 0x249},
+ { 0x78000, 8192, 0x18, 0x249},
+ { 0x85000, 3, 0x1f, 0x1000},
+ { 0x8501c, 7, 0x1f, 0x1000},
+ { 0x85048, 1, 0x1f, 0x1000},
+ { 0x85200, 32, 0x1f, 0x1000},
+ { 0xa0000, 16384, 0x3, 0x1000},
+ { 0xb0000, 16384, 0x2, 0x1000},
+ { 0xc1000, 7, 0x1f, 0x924},
+ { 0xc102c, 2, 0x1f, 0x1fff},
+ { 0xc1038, 1, 0x1f, 0x1fff},
+ { 0xc103c, 2, 0x1c, 0x924},
+ { 0xc1800, 2, 0x1f, 0x924},
+ { 0xc2000, 164, 0x1f, 0x924},
+ { 0xc22b0, 2, 0x1f, 0x1fff},
+ { 0xc22bc, 1, 0x1f, 0x1fff},
+ { 0xc22c0, 5, 0x1c, 0x924},
+ { 0xc22d8, 4, 0x1c, 0x924},
+ { 0xc2400, 49, 0x1f, 0x924},
+ { 0xc24c8, 32, 0x1f, 0x924},
+ { 0xc2548, 1, 0x1f, 0xfff},
+ { 0xc254c, 1, 0x1f, 0x924},
+ { 0xc2550, 1, 0x1f, 0xfff},
+ { 0xc2554, 1, 0x1f, 0x924},
+ { 0xc2558, 1, 0x1f, 0xfff},
+ { 0xc255c, 1, 0x1f, 0x924},
+ { 0xc2568, 2, 0x1f, 0x924},
+ { 0xc2600, 1, 0x1f, 0x924},
+ { 0xc4000, 165, 0x1f, 0x924},
+ { 0xc42b4, 2, 0x1f, 0x1fff},
+ { 0xc42c0, 1, 0x1f, 0x1fff},
+ { 0xc42d8, 2, 0x1c, 0x924},
+ { 0xc42e0, 7, 0x1e, 0x924},
+ { 0xc42fc, 1, 0x1c, 0x924},
+ { 0xc4400, 51, 0x1f, 0x924},
+ { 0xc44d0, 32, 0x1f, 0x924},
+ { 0xc4550, 1, 0x1f, 0xfff},
+ { 0xc4554, 1, 0x1f, 0x924},
+ { 0xc4558, 1, 0x1f, 0xfff},
+ { 0xc455c, 1, 0x1f, 0x924},
+ { 0xc4560, 1, 0x1f, 0xfff},
+ { 0xc4564, 1, 0x1f, 0x924},
+ { 0xc4570, 2, 0x1f, 0x924},
+ { 0xc4578, 5, 0x1c, 0x924},
+ { 0xc4600, 1, 0x1f, 0x924},
+ { 0xd0000, 19, 0x1f, 0x924},
+ { 0xd004c, 8, 0x1f, 0x1927},
+ { 0xd006c, 64, 0x1f, 0x924},
+ { 0xd016c, 8, 0x1f, 0xfff},
+ { 0xd018c, 19, 0x1f, 0x924},
+ { 0xd01e8, 2, 0x1f, 0x1fff},
+ { 0xd01f4, 1, 0x1f, 0x1fff},
+ { 0xd01fc, 1, 0x1c, 0x924},
+ { 0xd0200, 1, 0x1f, 0x924},
+ { 0xd0204, 1, 0x1f, 0xfff},
+ { 0xd020c, 3, 0x1f, 0xfff},
+ { 0xd0218, 4, 0x1f, 0x924},
+ { 0xd0228, 18, 0x1e, 0x924},
+ { 0xd0280, 1, 0x1f, 0x924},
+ { 0xd0300, 1, 0x1f, 0x924},
+ { 0xd0400, 1, 0x1f, 0x924},
+ { 0xd0818, 1, 0x10, 0x924},
+ { 0xd4000, 1, 0x1f, 0x1927},
+ { 0xd4004, 255, 0x1f, 0x6},
+ { 0xd4400, 1, 0x1f, 0x1007},
+ { 0xd4404, 255, 0x1f, 0x6},
+ { 0xd4800, 1, 0x1f, 0x1007},
+ { 0xd4804, 255, 0x1f, 0x6},
+ { 0xd4c00, 1, 0x1f, 0x1007},
+ { 0xd4c04, 255, 0x1f, 0x6},
+ { 0xd5000, 1, 0x1f, 0x1007},
+ { 0xd5004, 255, 0x1f, 0x6},
+ { 0xd5400, 1, 0x1f, 0x1007},
+ { 0xd5404, 255, 0x1f, 0x6},
+ { 0xd5800, 1, 0x1f, 0x1007},
+ { 0xd5804, 255, 0x1f, 0x6},
+ { 0xd5c00, 1, 0x1f, 0x1007},
+ { 0xd5c04, 255, 0x1f, 0x6},
+ { 0xd6000, 1, 0x1f, 0x1007},
+ { 0xd6004, 255, 0x1f, 0x6},
+ { 0xd6400, 1, 0x1f, 0x1007},
+ { 0xd6404, 255, 0x1f, 0x6},
+ { 0xd8000, 1, 0x1f, 0x1927},
+ { 0xd8004, 255, 0x1f, 0x6},
+ { 0xd8400, 1, 0x1f, 0x1007},
+ { 0xd8404, 255, 0x1f, 0x6},
+ { 0xd8800, 1, 0x1f, 0x1007},
+ { 0xd8804, 255, 0x1f, 0x6},
+ { 0xd8c00, 1, 0x1f, 0x1007},
+ { 0xd8c04, 255, 0x1f, 0x6},
+ { 0xd9000, 1, 0x1f, 0x1007},
+ { 0xd9004, 255, 0x1f, 0x6},
+ { 0xd9400, 1, 0x1f, 0x1007},
+ { 0xd9404, 255, 0x1f, 0x6},
+ { 0xd9800, 1, 0x1f, 0x1007},
+ { 0xd9804, 255, 0x1f, 0x6},
+ { 0xd9c00, 1, 0x1f, 0x1007},
+ { 0xd9c04, 255, 0x1f, 0x6},
+ { 0xda000, 1, 0x1f, 0x1007},
+ { 0xda004, 255, 0x1f, 0x6},
+ { 0xda400, 1, 0x1f, 0x1007},
+ { 0xda404, 255, 0x1f, 0x6},
+ { 0xda800, 1, 0x1f, 0x1007},
+ { 0xda804, 255, 0x1f, 0x6},
+ { 0xdac00, 1, 0x1f, 0x1007},
+ { 0xdac04, 255, 0x1f, 0x6},
+ { 0xdb000, 1, 0x1f, 0x1007},
+ { 0xdb004, 255, 0x1f, 0x6},
+ { 0xdb400, 1, 0x1f, 0x1007},
+ { 0xdb404, 255, 0x1f, 0x6},
+ { 0xdb800, 1, 0x1f, 0x1007},
+ { 0xdb804, 255, 0x1f, 0x6},
+ { 0xdbc00, 1, 0x1f, 0x1007},
+ { 0xdbc04, 255, 0x1f, 0x6},
+ { 0xdc000, 1, 0x1f, 0x1007},
+ { 0xdc004, 255, 0x1f, 0x6},
+ { 0xdc400, 1, 0x1f, 0x1007},
+ { 0xdc404, 255, 0x1f, 0x6},
+ { 0xdc800, 1, 0x1f, 0x1007},
+ { 0xdc804, 255, 0x1f, 0x6},
+ { 0xdcc00, 1, 0x1f, 0x1007},
+ { 0xdcc04, 255, 0x1f, 0x6},
+ { 0xdd000, 1, 0x1f, 0x1007},
+ { 0xdd004, 255, 0x1f, 0x6},
+ { 0xdd400, 1, 0x1f, 0x1007},
+ { 0xdd404, 255, 0x1f, 0x6},
+ { 0xdd800, 1, 0x1f, 0x1007},
+ { 0xdd804, 255, 0x1f, 0x6},
+ { 0xddc00, 1, 0x1f, 0x1007},
+ { 0xddc04, 255, 0x1f, 0x6},
+ { 0xde000, 1, 0x1f, 0x1007},
+ { 0xde004, 255, 0x1f, 0x6},
+ { 0xde400, 1, 0x1f, 0x1007},
+ { 0xde404, 255, 0x1f, 0x6},
+ { 0xde800, 1, 0x1f, 0x1007},
+ { 0xde804, 255, 0x1f, 0x6},
+ { 0xdec00, 1, 0x1f, 0x1007},
+ { 0xdec04, 255, 0x1f, 0x6},
+ { 0xdf000, 1, 0x1f, 0x1007},
+ { 0xdf004, 255, 0x1f, 0x6},
+ { 0xdf400, 1, 0x1f, 0x1007},
+ { 0xdf404, 255, 0x1f, 0x6},
+ { 0xdf800, 1, 0x1f, 0x1007},
+ { 0xdf804, 255, 0x1f, 0x6},
+ { 0xdfc00, 1, 0x1f, 0x1007},
+ { 0xdfc04, 255, 0x1f, 0x6},
+ { 0xe0000, 21, 0x1f, 0x924},
+ { 0xe0054, 8, 0x1f, 0xf24},
+ { 0xe0074, 49, 0x1f, 0x924},
+ { 0xe0138, 1, 0x3, 0x924},
+ { 0xe013c, 6, 0x1f, 0x924},
+ { 0xe0154, 8, 0x1f, 0xfff},
+ { 0xe0174, 21, 0x1f, 0x924},
+ { 0xe01d8, 2, 0x1f, 0x1fff},
+ { 0xe01e4, 1, 0x1f, 0x1fff},
+ { 0xe01f4, 1, 0x4, 0x924},
+ { 0xe01f8, 1, 0x1c, 0x924},
+ { 0xe0200, 1, 0x1f, 0x924},
+ { 0xe0204, 1, 0x1f, 0xfff},
+ { 0xe020c, 2, 0x1f, 0xfff},
+ { 0xe0214, 2, 0x1f, 0x924},
+ { 0xe021c, 2, 0x1f, 0xfff},
+ { 0xe0224, 2, 0x1f, 0x924},
+ { 0xe022c, 18, 0x1e, 0x924},
+ { 0xe0280, 1, 0x1f, 0x924},
+ { 0xe0300, 1, 0x1f, 0x924},
+ { 0xe0400, 1, 0x10, 0x924},
+ { 0xe1000, 1, 0x1f, 0x924},
+ { 0xe2000, 1, 0x1f, 0xf24},
+ { 0xe2004, 255, 0x1f, 0xc00},
+ { 0xe2400, 1, 0x1f, 0xe00},
+ { 0xe2404, 255, 0x1f, 0xc00},
+ { 0xe2800, 1, 0x1f, 0xe00},
+ { 0xe2804, 255, 0x1f, 0xc00},
+ { 0xe2c00, 1, 0x1f, 0xe00},
+ { 0xe2c04, 255, 0x1f, 0xc00},
+ { 0xe3000, 1, 0x1f, 0xe00},
+ { 0xe3004, 255, 0x1f, 0xc00},
+ { 0xe3400, 1, 0x1f, 0xe00},
+ { 0xe3404, 255, 0x1f, 0xc00},
+ { 0xe3800, 1, 0x1f, 0xe00},
+ { 0xe3804, 255, 0x1f, 0xc00},
+ { 0xe3c00, 1, 0x1f, 0xe00},
+ { 0xe3c04, 255, 0x1f, 0xc00},
+ { 0xf0000, 1, 0x1f, 0xf24},
+ { 0xf0004, 255, 0x1f, 0xc00},
+ { 0xf0400, 1, 0x1f, 0xe00},
+ { 0xf0404, 255, 0x1f, 0xc00},
+ { 0xf0800, 1, 0x1f, 0xe00},
+ { 0xf0804, 255, 0x1f, 0xc00},
+ { 0xf0c00, 1, 0x1f, 0xe00},
+ { 0xf0c04, 255, 0x1f, 0xc00},
+ { 0xf1000, 1, 0x1f, 0xe00},
+ { 0xf1004, 255, 0x1f, 0xc00},
+ { 0xf1400, 1, 0x1f, 0xe00},
+ { 0xf1404, 255, 0x1f, 0xc00},
+ { 0xf1800, 1, 0x1f, 0xe00},
+ { 0xf1804, 255, 0x1f, 0xc00},
+ { 0xf1c00, 1, 0x1f, 0xe00},
+ { 0xf1c04, 255, 0x1f, 0xc00},
+ { 0xf2000, 1, 0x1f, 0xe00},
+ { 0xf2004, 255, 0x1f, 0xc00},
+ { 0xf2400, 1, 0x1f, 0xe00},
+ { 0xf2404, 255, 0x1f, 0xc00},
+ { 0xf2800, 1, 0x1f, 0xe00},
+ { 0xf2804, 255, 0x1f, 0xc00},
+ { 0xf2c00, 1, 0x1f, 0xe00},
+ { 0xf2c04, 255, 0x1f, 0xc00},
+ { 0xf3000, 1, 0x1f, 0xe00},
+ { 0xf3004, 255, 0x1f, 0xc00},
+ { 0xf3400, 1, 0x1f, 0xe00},
+ { 0xf3404, 255, 0x1f, 0xc00},
+ { 0xf3800, 1, 0x1f, 0xe00},
+ { 0xf3804, 255, 0x1f, 0xc00},
+ { 0xf3c00, 1, 0x1f, 0xe00},
+ { 0xf3c04, 255, 0x1f, 0xc00},
+ { 0xf4000, 1, 0x1f, 0xe00},
+ { 0xf4004, 255, 0x1f, 0xc00},
+ { 0xf4400, 1, 0x1f, 0xe00},
+ { 0xf4404, 255, 0x1f, 0xc00},
+ { 0xf4800, 1, 0x1f, 0xe00},
+ { 0xf4804, 255, 0x1f, 0xc00},
+ { 0xf4c00, 1, 0x1f, 0xe00},
+ { 0xf4c04, 255, 0x1f, 0xc00},
+ { 0xf5000, 1, 0x1f, 0xe00},
+ { 0xf5004, 255, 0x1f, 0xc00},
+ { 0xf5400, 1, 0x1f, 0xe00},
+ { 0xf5404, 255, 0x1f, 0xc00},
+ { 0xf5800, 1, 0x1f, 0xe00},
+ { 0xf5804, 255, 0x1f, 0xc00},
+ { 0xf5c00, 1, 0x1f, 0xe00},
+ { 0xf5c04, 255, 0x1f, 0xc00},
+ { 0xf6000, 1, 0x1f, 0xe00},
+ { 0xf6004, 255, 0x1f, 0xc00},
+ { 0xf6400, 1, 0x1f, 0xe00},
+ { 0xf6404, 255, 0x1f, 0xc00},
+ { 0xf6800, 1, 0x1f, 0xe00},
+ { 0xf6804, 255, 0x1f, 0xc00},
+ { 0xf6c00, 1, 0x1f, 0xe00},
+ { 0xf6c04, 255, 0x1f, 0xc00},
+ { 0xf7000, 1, 0x1f, 0xe00},
+ { 0xf7004, 255, 0x1f, 0xc00},
+ { 0xf7400, 1, 0x1f, 0xe00},
+ { 0xf7404, 255, 0x1f, 0xc00},
+ { 0xf7800, 1, 0x1f, 0xe00},
+ { 0xf7804, 255, 0x1f, 0xc00},
+ { 0xf7c00, 1, 0x1f, 0xe00},
+ { 0xf7c04, 255, 0x1f, 0xc00},
+ { 0xf8000, 1, 0x1f, 0xe00},
+ { 0xf8004, 255, 0x1f, 0xc00},
+ { 0xf8400, 1, 0x1f, 0xe00},
+ { 0xf8404, 255, 0x1f, 0xc00},
+ { 0xf8800, 1, 0x1f, 0xe00},
+ { 0xf8804, 255, 0x1f, 0xc00},
+ { 0xf8c00, 1, 0x1f, 0xe00},
+ { 0xf8c04, 255, 0x1f, 0xc00},
+ { 0xf9000, 1, 0x1f, 0xe00},
+ { 0xf9004, 255, 0x1f, 0xc00},
+ { 0xf9400, 1, 0x1f, 0xe00},
+ { 0xf9404, 255, 0x1f, 0xc00},
+ { 0xf9800, 1, 0x1f, 0xe00},
+ { 0xf9804, 255, 0x1f, 0xc00},
+ { 0xf9c00, 1, 0x1f, 0xe00},
+ { 0xf9c04, 255, 0x1f, 0xc00},
+ { 0xfa000, 1, 0x1f, 0xe00},
+ { 0xfa004, 255, 0x1f, 0xc00},
+ { 0xfa400, 1, 0x1f, 0xe00},
+ { 0xfa404, 255, 0x1f, 0xc00},
+ { 0xfa800, 1, 0x1f, 0xe00},
+ { 0xfa804, 255, 0x1f, 0xc00},
+ { 0xfac00, 1, 0x1f, 0xe00},
+ { 0xfac04, 255, 0x1f, 0xc00},
+ { 0xfb000, 1, 0x1f, 0xe00},
+ { 0xfb004, 255, 0x1f, 0xc00},
+ { 0xfb400, 1, 0x1f, 0xe00},
+ { 0xfb404, 255, 0x1f, 0xc00},
+ { 0xfb800, 1, 0x1f, 0xe00},
+ { 0xfb804, 255, 0x1f, 0xc00},
+ { 0xfbc00, 1, 0x1f, 0xe00},
+ { 0xfbc04, 255, 0x1f, 0xc00},
+ { 0xfc000, 1, 0x1f, 0xe00},
+ { 0xfc004, 255, 0x1f, 0xc00},
+ { 0xfc400, 1, 0x1f, 0xe00},
+ { 0xfc404, 255, 0x1f, 0xc00},
+ { 0xfc800, 1, 0x1f, 0xe00},
+ { 0xfc804, 255, 0x1f, 0xc00},
+ { 0xfcc00, 1, 0x1f, 0xe00},
+ { 0xfcc04, 255, 0x1f, 0xc00},
+ { 0xfd000, 1, 0x1f, 0xe00},
+ { 0xfd004, 255, 0x1f, 0xc00},
+ { 0xfd400, 1, 0x1f, 0xe00},
+ { 0xfd404, 255, 0x1f, 0xc00},
+ { 0xfd800, 1, 0x1f, 0xe00},
+ { 0xfd804, 255, 0x1f, 0xc00},
+ { 0xfdc00, 1, 0x1f, 0xe00},
+ { 0xfdc04, 255, 0x1f, 0xc00},
+ { 0xfe000, 1, 0x1f, 0xe00},
+ { 0xfe004, 255, 0x1f, 0xc00},
+ { 0xfe400, 1, 0x1f, 0xe00},
+ { 0xfe404, 255, 0x1f, 0xc00},
+ { 0xfe800, 1, 0x1f, 0xe00},
+ { 0xfe804, 255, 0x1f, 0xc00},
+ { 0xfec00, 1, 0x1f, 0xe00},
+ { 0xfec04, 255, 0x1f, 0xc00},
+ { 0xff000, 1, 0x1f, 0xe00},
+ { 0xff004, 255, 0x1f, 0xc00},
+ { 0xff400, 1, 0x1f, 0xe00},
+ { 0xff404, 255, 0x1f, 0xc00},
+ { 0xff800, 1, 0x1f, 0xe00},
+ { 0xff804, 255, 0x1f, 0xc00},
+ { 0xffc00, 1, 0x1f, 0xe00},
+ { 0xffc04, 255, 0x1f, 0xc00},
+ { 0x101000, 5, 0x1f, 0x924},
+ { 0x101014, 1, 0x1f, 0xfff},
+ { 0x101018, 6, 0x1f, 0x924},
+ { 0x101040, 2, 0x1f, 0x1fff},
+ { 0x10104c, 1, 0x1f, 0x1fff},
+ { 0x101050, 1, 0x1e, 0x924},
+ { 0x101054, 3, 0x1c, 0x924},
+ { 0x101100, 1, 0x1f, 0x924},
+ { 0x101800, 8, 0x1f, 0x924},
+ { 0x102000, 18, 0x1f, 0x924},
+ { 0x102058, 2, 0x1f, 0x1fff},
+ { 0x102064, 1, 0x1f, 0x1fff},
+ { 0x102068, 6, 0x1c, 0x924},
+ { 0x102080, 16, 0x1f, 0xfff},
+ { 0x1020c0, 1, 0x1f, 0x924},
+ { 0x1020c8, 8, 0x2, 0x924},
+ { 0x1020e8, 9, 0x1c, 0x924},
+ { 0x102400, 1, 0x1f, 0x924},
+ { 0x103000, 1, 0x1f, 0x924},
+ { 0x103004, 2, 0x1f, 0xfff},
+ { 0x10300c, 23, 0x1f, 0x924},
+ { 0x103088, 2, 0x1f, 0x1fff},
+ { 0x103094, 1, 0x1f, 0x1fff},
+ { 0x103098, 1, 0x1e, 0x924},
+ { 0x10309c, 2, 0x1e, 0xfff},
+ { 0x1030a4, 2, 0x1e, 0x924},
+ { 0x1030ac, 2, 0x1c, 0x924},
+ { 0x1030b4, 1, 0x4, 0x924},
+ { 0x1030b8, 2, 0x1c, 0xfff},
+ { 0x1030c0, 3, 0x1c, 0x924},
+ { 0x1030cc, 1, 0x1c, 0xfff},
+ { 0x1030d0, 1, 0x1c, 0x924},
+ { 0x1030d8, 2, 0x1c, 0x924},
+ { 0x1030e0, 1, 0x1c, 0xfff},
+ { 0x1030e4, 5, 0x1c, 0x924},
+ { 0x103400, 136, 0x1c, 0x1fff},
+ { 0x103800, 8, 0x1f, 0x924},
+ { 0x104000, 1, 0x1f, 0x924},
+ { 0x104004, 1, 0x1f, 0xfff},
+ { 0x104008, 4, 0x1f, 0x924},
+ { 0x104018, 1, 0x1f, 0xfff},
+ { 0x10401c, 1, 0x1f, 0x924},
+ { 0x104020, 1, 0x1f, 0xfff},
+ { 0x104024, 6, 0x1f, 0x924},
+ { 0x10403c, 1, 0x1f, 0xfff},
+ { 0x104040, 47, 0x1f, 0x924},
+ { 0x10410c, 2, 0x1f, 0x1fff},
+ { 0x104118, 1, 0x1f, 0x1fff},
+ { 0x10411c, 16, 0x1c, 0x924},
+ { 0x104200, 17, 0x1f, 0x924},
+ { 0x104400, 1, 0x1f, 0x1fff},
+ { 0x104404, 63, 0x1f, 0xfff},
+ { 0x104500, 192, 0x1f, 0xdb6},
+ { 0x104800, 1, 0x1f, 0x1fff},
+ { 0x104804, 63, 0x1f, 0xfff},
+ { 0x104900, 192, 0x1f, 0xdb6},
+ { 0x105000, 4, 0x1f, 0x1fff},
+ { 0x105010, 252, 0x1f, 0xfff},
+ { 0x105400, 768, 0x1f, 0xdb6},
+ { 0x107000, 7, 0x1c, 0x924},
+ { 0x10701c, 1, 0x18, 0x924},
+ { 0x108000, 33, 0x3, 0x924},
+ { 0x1080ac, 5, 0x2, 0x924},
+ { 0x108100, 5, 0x3, 0x924},
+ { 0x108120, 5, 0x3, 0x924},
+ { 0x108200, 74, 0x3, 0x924},
+ { 0x108400, 74, 0x3, 0x924},
+ { 0x108800, 152, 0x3, 0x924},
+ { 0x110000, 111, 0x1c, 0x924},
+ { 0x1101cc, 2, 0x1c, 0x1fff},
+ { 0x1101d8, 1, 0x1c, 0x1fff},
+ { 0x1101dc, 1, 0x18, 0x924},
+ { 0x110200, 4, 0x1c, 0x924},
+ { 0x120000, 92, 0x1f, 0x924},
+ { 0x120170, 2, 0x3, 0x924},
+ { 0x120178, 14, 0x1f, 0x924},
+ { 0x1201b0, 2, 0x1f, 0xfff},
+ { 0x1201b8, 93, 0x1f, 0x924},
+ { 0x12032c, 1, 0x1f, 0xfff},
+ { 0x120330, 15, 0x1f, 0x924},
+ { 0x12036c, 3, 0x1f, 0xfff},
+ { 0x120378, 36, 0x1f, 0x924},
+ { 0x120408, 2, 0x1f, 0xfff},
+ { 0x120410, 1, 0x1f, 0x924},
+ { 0x120414, 15, 0x1f, 0xfff},
+ { 0x120450, 10, 0x1f, 0x924},
+ { 0x120478, 2, 0x1f, 0xfff},
+ { 0x120480, 43, 0x1f, 0x924},
+ { 0x12052c, 1, 0x1f, 0xfff},
+ { 0x120530, 5, 0x1f, 0x924},
+ { 0x120544, 4, 0x3, 0x924},
+ { 0x120554, 4, 0x1f, 0x924},
+ { 0x120564, 2, 0x1f, 0xfff},
+ { 0x12057c, 2, 0x1f, 0x1fff},
+ { 0x120588, 3, 0x1f, 0x1fff},
+ { 0x120598, 1, 0x1f, 0x1fff},
+ { 0x12059c, 22, 0x1e, 0x924},
+ { 0x1205f4, 1, 0x6, 0x924},
+ { 0x1205f8, 4, 0x1c, 0x924},
+ { 0x120618, 1, 0x1c, 0x924},
+ { 0x12061c, 31, 0x1e, 0x924},
+ { 0x120698, 3, 0x1c, 0x924},
+ { 0x1206a4, 1, 0x4, 0x924},
+ { 0x1206a8, 1, 0x1c, 0x924},
+ { 0x1206b0, 38, 0x1c, 0x924},
+ { 0x120748, 1, 0x1c, 0xfff},
+ { 0x12074c, 11, 0x1c, 0x924},
+ { 0x120778, 2, 0x1c, 0xfff},
+ { 0x120780, 23, 0x1c, 0x924},
+ { 0x1207dc, 1, 0x4, 0x924},
+ { 0x1207fc, 1, 0x1c, 0x924},
+ { 0x12080c, 2, 0x1f, 0xfff},
+ { 0x120814, 1, 0x1f, 0x924},
+ { 0x120818, 1, 0x1f, 0xfff},
+ { 0x12081c, 1, 0x1f, 0x924},
+ { 0x120820, 1, 0x1f, 0xfff},
+ { 0x120824, 1, 0x1f, 0x924},
+ { 0x120828, 1, 0x1f, 0xfff},
+ { 0x12082c, 1, 0x1f, 0x924},
+ { 0x120830, 1, 0x1f, 0xfff},
+ { 0x120834, 1, 0x1f, 0x924},
+ { 0x120838, 1, 0x1f, 0xfff},
+ { 0x12083c, 1, 0x1f, 0x924},
+ { 0x120840, 1, 0x1f, 0xfff},
+ { 0x120844, 1, 0x1f, 0x924},
+ { 0x120848, 1, 0x1f, 0xfff},
+ { 0x12084c, 1, 0x1f, 0x924},
+ { 0x120850, 1, 0x1f, 0xfff},
+ { 0x120854, 1, 0x1f, 0x924},
+ { 0x120858, 1, 0x1f, 0xfff},
+ { 0x12085c, 1, 0x1f, 0x924},
+ { 0x120860, 1, 0x1f, 0xfff},
+ { 0x120864, 1, 0x1f, 0x924},
+ { 0x120868, 1, 0x1f, 0xfff},
+ { 0x12086c, 1, 0x1f, 0x924},
+ { 0x120870, 1, 0x1f, 0xfff},
+ { 0x120874, 1, 0x1f, 0x924},
+ { 0x120878, 1, 0x1f, 0xfff},
+ { 0x12087c, 1, 0x1f, 0x924},
+ { 0x120880, 1, 0x1f, 0xfff},
+ { 0x120884, 1, 0x1f, 0x924},
+ { 0x120888, 1, 0x1f, 0xfff},
+ { 0x12088c, 1, 0x1f, 0x924},
+ { 0x120890, 1, 0x1f, 0xfff},
+ { 0x120894, 1, 0x1f, 0x924},
+ { 0x120898, 1, 0x1f, 0xfff},
+ { 0x12089c, 1, 0x1f, 0x924},
+ { 0x1208a0, 1, 0x1f, 0xfff},
+ { 0x1208a4, 1, 0x1f, 0x924},
+ { 0x1208a8, 1, 0x1f, 0xfff},
+ { 0x1208ac, 1, 0x1f, 0x924},
+ { 0x1208b0, 1, 0x1f, 0xfff},
+ { 0x1208b4, 1, 0x1f, 0x924},
+ { 0x1208b8, 1, 0x1f, 0xfff},
+ { 0x1208bc, 1, 0x1f, 0x924},
+ { 0x1208c0, 1, 0x1f, 0xfff},
+ { 0x1208c4, 1, 0x1f, 0x924},
+ { 0x1208c8, 1, 0x1f, 0xfff},
+ { 0x1208cc, 1, 0x1f, 0x924},
+ { 0x1208d0, 1, 0x1f, 0xfff},
+ { 0x1208d4, 1, 0x1f, 0x924},
+ { 0x1208d8, 1, 0x1f, 0xfff},
+ { 0x1208dc, 1, 0x1f, 0x924},
+ { 0x1208e0, 1, 0x1f, 0xfff},
+ { 0x1208e4, 1, 0x1f, 0x924},
+ { 0x1208e8, 1, 0x1f, 0xfff},
+ { 0x1208ec, 1, 0x1f, 0x924},
+ { 0x1208f0, 1, 0x1f, 0xfff},
+ { 0x1208f4, 1, 0x1f, 0x924},
+ { 0x1208f8, 1, 0x1f, 0xfff},
+ { 0x1208fc, 1, 0x1f, 0x924},
+ { 0x120900, 1, 0x1f, 0xfff},
+ { 0x120904, 1, 0x1f, 0x924},
+ { 0x120908, 1, 0x1f, 0xfff},
+ { 0x12090c, 1, 0x1f, 0x924},
+ { 0x120910, 7, 0x1c, 0x924},
+ { 0x120930, 9, 0x1c, 0x924},
+ { 0x12095c, 37, 0x18, 0x924},
+ { 0x120a00, 2, 0x7, 0x924},
+ { 0x120b00, 1, 0x18, 0x924},
+ { 0x122000, 2, 0x1f, 0x924},
+ { 0x122008, 2046, 0x1, 0x924},
+ { 0x128000, 6144, 0x1e, 0x924},
+ { 0x130000, 1, 0x1c, 0x1fff},
+ { 0x130004, 11, 0x1c, 0x924},
+ { 0x130030, 1, 0x1c, 0xfff},
+ { 0x130034, 6, 0x1c, 0x924},
+ { 0x13004c, 3, 0x1c, 0xfff},
+ { 0x130058, 3, 0x1c, 0x924},
+ { 0x130064, 2, 0x1c, 0xfff},
+ { 0x13006c, 8, 0x1c, 0x924},
+ { 0x13009c, 2, 0x1c, 0x1fff},
+ { 0x1300a8, 1, 0x1c, 0x1fff},
+ { 0x130100, 12, 0x1c, 0x924},
+ { 0x130130, 1, 0x1c, 0xfff},
+ { 0x130134, 14, 0x1c, 0x924},
+ { 0x13016c, 1, 0x1c, 0xfff},
+ { 0x130170, 1, 0x1c, 0x924},
+ { 0x130180, 1, 0x1c, 0x924},
+ { 0x130200, 1, 0x1c, 0x924},
+ { 0x130280, 1, 0x1c, 0x924},
+ { 0x130300, 1, 0x1c, 0xfff},
+ { 0x130304, 4, 0x1c, 0x924},
+ { 0x130380, 1, 0x1c, 0x924},
+ { 0x130400, 1, 0x1c, 0x924},
+ { 0x130480, 1, 0x1c, 0xfff},
+ { 0x130484, 4, 0x1c, 0x924},
+ { 0x130800, 72, 0x1c, 0x924},
+ { 0x131000, 136, 0x1c, 0x924},
+ { 0x132000, 148, 0x1c, 0x924},
+ { 0x134000, 544, 0x1c, 0x924},
+ { 0x140000, 1, 0x1f, 0x924},
+ { 0x140004, 9, 0xf, 0x924},
+ { 0x140028, 8, 0x1f, 0x924},
+ { 0x140048, 5, 0xf, 0x924},
+ { 0x14005c, 2, 0xf, 0xfff},
+ { 0x140064, 3, 0xf, 0x924},
+ { 0x140070, 1, 0x1f, 0x924},
+ { 0x140074, 10, 0xf, 0x924},
+ { 0x14009c, 1, 0x1f, 0x924},
+ { 0x1400a0, 5, 0xf, 0x924},
+ { 0x1400b4, 7, 0x1f, 0x924},
+ { 0x1400d0, 2, 0xf, 0xfff},
+ { 0x1400d8, 2, 0xf, 0x924},
+ { 0x1400e0, 1, 0xf, 0xfff},
+ { 0x1400e4, 5, 0xf, 0x924},
+ { 0x1400f8, 2, 0x1f, 0x924},
+ { 0x140100, 5, 0x3, 0x924},
+ { 0x140114, 5, 0xf, 0x924},
+ { 0x140128, 7, 0x1f, 0x924},
+ { 0x140144, 9, 0xf, 0x924},
+ { 0x140168, 8, 0x1f, 0x924},
+ { 0x140188, 3, 0xf, 0x924},
+ { 0x140194, 13, 0x1f, 0x924},
+ { 0x1401d8, 2, 0x1f, 0x1fff},
+ { 0x1401e4, 1, 0x1f, 0x1fff},
+ { 0x140200, 6, 0xf, 0xfff},
+ { 0x1402e0, 2, 0xc, 0x924},
+ { 0x1402e8, 2, 0x1c, 0x924},
+ { 0x1402f0, 9, 0xc, 0x924},
+ { 0x140314, 9, 0x10, 0x924},
+ { 0x140338, 7, 0x10, 0xfff},
+ { 0x140354, 7, 0x10, 0x924},
+ { 0x140370, 7, 0x10, 0xfff},
+ { 0x14038c, 14, 0x10, 0x924},
+ { 0x1404b0, 14, 0x10, 0x924},
+ { 0x15c000, 2, 0x1e, 0x924},
+ { 0x15c008, 5, 0x2, 0x924},
+ { 0x15c020, 8, 0x1c, 0x924},
+ { 0x15c040, 1, 0xc, 0x924},
+ { 0x15c044, 2, 0x1c, 0x924},
+ { 0x15c04c, 8, 0xc, 0x924},
+ { 0x15c06c, 8, 0x1c, 0x924},
+ { 0x15c090, 13, 0x1c, 0x924},
+ { 0x15c0c8, 24, 0x1c, 0x924},
+ { 0x15c128, 2, 0xc, 0x924},
+ { 0x15c130, 1, 0x1c, 0x924},
+ { 0x15c138, 6, 0x1c, 0x924},
+ { 0x15c150, 2, 0x18, 0x924},
+ { 0x15c158, 2, 0x8, 0x924},
+ { 0x15c160, 23, 0x10, 0x924},
+ { 0x15c1bc, 6, 0x10, 0xfff},
+ { 0x15c1d4, 23, 0x10, 0x924},
+ { 0x15c230, 7, 0x10, 0xfff},
+ { 0x15c24c, 90, 0x10, 0x924},
+ { 0x160004, 6, 0x18, 0x924},
+ { 0x16003c, 1, 0x10, 0x924},
+ { 0x160040, 6, 0x18, 0x924},
+ { 0x16005c, 6, 0x18, 0x924},
+ { 0x160074, 1, 0x10, 0x924},
+ { 0x160078, 2, 0x18, 0x924},
+ { 0x160300, 8, 0x18, 0x924},
+ { 0x160330, 6, 0x18, 0x924},
+ { 0x160404, 6, 0x18, 0x924},
+ { 0x16043c, 1, 0x10, 0x924},
+ { 0x160440, 6, 0x18, 0x924},
+ { 0x16045c, 6, 0x18, 0x924},
+ { 0x160474, 1, 0x10, 0x924},
+ { 0x160478, 2, 0x18, 0x924},
+ { 0x160700, 8, 0x18, 0x924},
+ { 0x160730, 6, 0x18, 0x924},
+ { 0x161000, 7, 0x1f, 0x924},
+ { 0x16102c, 2, 0x1f, 0x1fff},
+ { 0x161038, 1, 0x1f, 0x1fff},
+ { 0x16103c, 2, 0x1c, 0x924},
+ { 0x161800, 2, 0x1f, 0x924},
+ { 0x162000, 54, 0x18, 0x924},
+ { 0x162200, 60, 0x18, 0x924},
+ { 0x162400, 54, 0x18, 0x924},
+ { 0x162600, 60, 0x18, 0x924},
+ { 0x162800, 54, 0x18, 0x924},
+ { 0x162a00, 60, 0x18, 0x924},
+ { 0x162c00, 54, 0x18, 0x924},
+ { 0x162e00, 60, 0x18, 0x924},
+ { 0x163000, 1, 0x18, 0x924},
+ { 0x163008, 1, 0x18, 0x924},
+ { 0x163010, 1, 0x18, 0x924},
+ { 0x163018, 1, 0x18, 0x924},
+ { 0x163020, 5, 0x18, 0x924},
+ { 0x163038, 3, 0x18, 0x924},
+ { 0x163048, 3, 0x18, 0x924},
+ { 0x163058, 1, 0x18, 0x924},
+ { 0x163060, 1, 0x18, 0x924},
+ { 0x163068, 1, 0x18, 0x924},
+ { 0x163070, 3, 0x18, 0x924},
+ { 0x163080, 1, 0x18, 0x924},
+ { 0x163088, 3, 0x18, 0x924},
+ { 0x163098, 1, 0x18, 0x924},
+ { 0x1630a0, 1, 0x18, 0x924},
+ { 0x1630a8, 1, 0x18, 0x924},
+ { 0x1630b0, 2, 0x10, 0x924},
+ { 0x1630c0, 1, 0x18, 0x924},
+ { 0x1630c8, 1, 0x18, 0x924},
+ { 0x1630d0, 1, 0x18, 0x924},
+ { 0x1630d8, 1, 0x18, 0x924},
+ { 0x1630e0, 2, 0x18, 0x924},
+ { 0x163110, 1, 0x18, 0x924},
+ { 0x163120, 2, 0x18, 0x924},
+ { 0x163420, 4, 0x18, 0x924},
+ { 0x163438, 2, 0x18, 0x924},
+ { 0x163488, 2, 0x18, 0x924},
+ { 0x163520, 2, 0x18, 0x924},
+ { 0x163800, 1, 0x18, 0x924},
+ { 0x163808, 1, 0x18, 0x924},
+ { 0x163810, 1, 0x18, 0x924},
+ { 0x163818, 1, 0x18, 0x924},
+ { 0x163820, 5, 0x18, 0x924},
+ { 0x163838, 3, 0x18, 0x924},
+ { 0x163848, 3, 0x18, 0x924},
+ { 0x163858, 1, 0x18, 0x924},
+ { 0x163860, 1, 0x18, 0x924},
+ { 0x163868, 1, 0x18, 0x924},
+ { 0x163870, 3, 0x18, 0x924},
+ { 0x163880, 1, 0x18, 0x924},
+ { 0x163888, 3, 0x18, 0x924},
+ { 0x163898, 1, 0x18, 0x924},
+ { 0x1638a0, 1, 0x18, 0x924},
+ { 0x1638a8, 1, 0x18, 0x924},
+ { 0x1638b0, 2, 0x10, 0x924},
+ { 0x1638c0, 1, 0x18, 0x924},
+ { 0x1638c8, 1, 0x18, 0x924},
+ { 0x1638d0, 1, 0x18, 0x924},
+ { 0x1638d8, 1, 0x18, 0x924},
+ { 0x1638e0, 2, 0x18, 0x924},
+ { 0x163910, 1, 0x18, 0x924},
+ { 0x163920, 2, 0x18, 0x924},
+ { 0x163c20, 4, 0x18, 0x924},
+ { 0x163c38, 2, 0x18, 0x924},
+ { 0x163c88, 2, 0x18, 0x924},
+ { 0x163d20, 2, 0x18, 0x924},
+ { 0x164000, 5, 0x1f, 0x924},
+ { 0x164014, 2, 0x1f, 0xfff},
+ { 0x16401c, 53, 0x1f, 0x924},
+ { 0x164100, 2, 0x1f, 0x1fff},
+ { 0x16410c, 1, 0x1f, 0x1fff},
+ { 0x164110, 2, 0x1e, 0x924},
+ { 0x164118, 15, 0x1c, 0x924},
+ { 0x164200, 1, 0x1f, 0x924},
+ { 0x164208, 1, 0x1f, 0x924},
+ { 0x164210, 1, 0x1f, 0x924},
+ { 0x164218, 1, 0x1f, 0x924},
+ { 0x164220, 1, 0x1f, 0x924},
+ { 0x164228, 1, 0x1f, 0x924},
+ { 0x164230, 1, 0x1f, 0x924},
+ { 0x164238, 1, 0x1f, 0x924},
+ { 0x164240, 1, 0x1f, 0x924},
+ { 0x164248, 1, 0x1f, 0x924},
+ { 0x164250, 1, 0x1f, 0x924},
+ { 0x164258, 1, 0x1f, 0x924},
+ { 0x164260, 1, 0x1f, 0x924},
+ { 0x164270, 2, 0x1f, 0x924},
+ { 0x164280, 2, 0x1f, 0x924},
+ { 0x164800, 2, 0x1f, 0x924},
+ { 0x165000, 2, 0x1f, 0x924},
+ { 0x166000, 164, 0x1f, 0x924},
+ { 0x1662b0, 2, 0x1f, 0x1fff},
+ { 0x1662bc, 1, 0x1f, 0x1fff},
+ { 0x1662cc, 7, 0x1c, 0x924},
+ { 0x166400, 49, 0x1f, 0x924},
+ { 0x1664c8, 32, 0x1f, 0x924},
+ { 0x166548, 1, 0x1f, 0xfff},
+ { 0x16654c, 1, 0x1f, 0x924},
+ { 0x166550, 1, 0x1f, 0xfff},
+ { 0x166554, 1, 0x1f, 0x924},
+ { 0x166558, 1, 0x1f, 0xfff},
+ { 0x16655c, 1, 0x1f, 0x924},
+ { 0x166568, 2, 0x1f, 0x924},
+ { 0x166570, 5, 0x1c, 0x924},
+ { 0x166800, 1, 0x1f, 0x924},
+ { 0x168000, 1, 0x1f, 0xfff},
+ { 0x168004, 1, 0x1f, 0x924},
+ { 0x168008, 1, 0x1f, 0xfff},
+ { 0x16800c, 1, 0x1f, 0x924},
+ { 0x168010, 1, 0x1f, 0xfff},
+ { 0x168014, 1, 0x1f, 0x924},
+ { 0x168018, 1, 0x1f, 0xfff},
+ { 0x16801c, 3, 0x1f, 0x924},
+ { 0x168028, 2, 0x1f, 0xfff},
+ { 0x168030, 10, 0x1f, 0x924},
+ { 0x168058, 9, 0x1f, 0xfff},
+ { 0x16807c, 106, 0x1f, 0x924},
+ { 0x168224, 2, 0x3, 0x924},
+ { 0x16822c, 3, 0x1f, 0x924},
+ { 0x168238, 1, 0x1f, 0xfff},
+ { 0x16823c, 25, 0x1f, 0x924},
+ { 0x1682a0, 12, 0x3, 0x924},
+ { 0x1682d0, 7, 0x1f, 0xfff},
+ { 0x1682ec, 5, 0x1f, 0x924},
+ { 0x168300, 2, 0x3, 0xfff},
+ { 0x168308, 65, 0x1f, 0xfff},
+ { 0x16840c, 1, 0x1f, 0x924},
+ { 0x168410, 2, 0x1f, 0xfff},
+ { 0x168418, 2, 0x3, 0x924},
+ { 0x168420, 6, 0x1f, 0x924},
+ { 0x168448, 2, 0x1f, 0x1fff},
+ { 0x168454, 1, 0x1f, 0x1fff},
+ { 0x168800, 19, 0x1f, 0x924},
+ { 0x168900, 1, 0x1f, 0x924},
+ { 0x168a00, 128, 0x1f, 0xfff},
+ { 0x16a000, 1536, 0x1f, 0x924},
+ { 0x16c000, 1536, 0x1f, 0x924},
+ { 0x16e000, 16, 0x2, 0x924},
+ { 0x16e040, 8, 0x1c, 0x924},
+ { 0x16e100, 1, 0x2, 0x924},
+ { 0x16e200, 2, 0x2, 0xfff},
+ { 0x16e400, 1, 0x2, 0x924},
+ { 0x16e404, 2, 0x2, 0xfff},
+ { 0x16e40c, 94, 0x2, 0x924},
+ { 0x16e584, 64, 0x2, 0xfff},
+ { 0x16e684, 2, 0x1e, 0xfff},
+ { 0x16e68c, 4, 0x2, 0xfff},
+ { 0x16e69c, 8, 0x2, 0x924},
+ { 0x16e6bc, 4, 0x1e, 0x924},
+ { 0x16e6cc, 4, 0x2, 0x924},
+ { 0x16e6e0, 2, 0x1c, 0x924},
+ { 0x16e6e8, 5, 0xc, 0x924},
+ { 0x16e6fc, 4, 0x1c, 0xfff},
+ { 0x16e70c, 1, 0x1c, 0x924},
+ { 0x16e768, 17, 0x1c, 0x924},
+ { 0x16e7ac, 12, 0x10, 0xfff},
+ { 0x170000, 24, 0x1f, 0x924},
+ { 0x170060, 4, 0x3, 0x924},
+ { 0x170070, 13, 0x1f, 0x924},
+ { 0x1700a4, 1, 0x1f, 0xfff},
+ { 0x1700a8, 1, 0x1f, 0x924},
+ { 0x1700ac, 2, 0x1f, 0xfff},
+ { 0x1700b4, 3, 0x1f, 0x924},
+ { 0x1700c0, 1, 0x1f, 0xfff},
+ { 0x1700c4, 44, 0x1f, 0x924},
+ { 0x170184, 2, 0x1f, 0x1fff},
+ { 0x170190, 1, 0x1f, 0x1fff},
+ { 0x170194, 11, 0x1c, 0x924},
+ { 0x1701c4, 1, 0x1c, 0x924},
+ { 0x1701cc, 7, 0x1c, 0x924},
+ { 0x1701e8, 1, 0x18, 0x924},
+ { 0x1701ec, 1, 0x1c, 0x924},
+ { 0x1701f4, 1, 0x1c, 0x924},
+ { 0x170200, 4, 0x1f, 0x924},
+ { 0x170214, 1, 0x1f, 0x924},
+ { 0x170218, 77, 0x1c, 0x924},
+ { 0x170400, 64, 0x1c, 0x924},
+ { 0x178000, 1, 0x1f, 0x924},
+ { 0x180000, 61, 0x1f, 0x924},
+ { 0x180114, 2, 0x1f, 0x1fff},
+ { 0x180120, 3, 0x1f, 0x1fff},
+ { 0x180130, 1, 0x1f, 0x1fff},
+ { 0x18013c, 2, 0x1e, 0x924},
+ { 0x180200, 27, 0x1f, 0x924},
+ { 0x18026c, 1, 0x1f, 0xfff},
+ { 0x180270, 12, 0x1f, 0x924},
+ { 0x1802a0, 1, 0x1f, 0xfff},
+ { 0x1802a4, 17, 0x1f, 0x924},
+ { 0x180340, 4, 0x1f, 0x924},
+ { 0x180380, 1, 0x1c, 0x924},
+ { 0x180388, 1, 0x1c, 0x924},
+ { 0x180390, 1, 0x1c, 0x924},
+ { 0x180398, 1, 0x1c, 0x924},
+ { 0x1803a0, 5, 0x1c, 0x924},
+ { 0x1803b4, 2, 0x18, 0x924},
+ { 0x180400, 256, 0x3, 0xfff},
+ { 0x181000, 4, 0x1f, 0x93c},
+ { 0x181010, 1020, 0x1f, 0x38},
+ { 0x182000, 4, 0x18, 0x924},
+ { 0x1a0000, 1, 0x1f, 0x92c},
+ { 0x1a0004, 5631, 0x1f, 0x8},
+ { 0x1a5800, 2560, 0x1e, 0x8},
+ { 0x1a8000, 1, 0x1f, 0x92c},
+ { 0x1a8004, 8191, 0x1e, 0x8},
+ { 0x1b0000, 1, 0x1f, 0x92c},
+ { 0x1b0004, 15, 0x2, 0x8},
+ { 0x1b0040, 1, 0x1e, 0x92c},
+ { 0x1b0044, 239, 0x2, 0x8},
+ { 0x1b0400, 1, 0x1f, 0x92c},
+ { 0x1b0404, 255, 0x2, 0x8},
+ { 0x1b0800, 1, 0x1f, 0x924},
+ { 0x1b0840, 1, 0x1e, 0x924},
+ { 0x1b0c00, 1, 0x1f, 0x1fff},
+ { 0x1b1000, 1, 0x1f, 0x1fff},
+ { 0x1b1040, 1, 0x1e, 0x1fff},
+ { 0x1b1400, 1, 0x1f, 0x924},
+ { 0x1b1440, 1, 0x1e, 0x924},
+ { 0x1b1480, 1, 0x1e, 0x924},
+ { 0x1b14c0, 1, 0x1e, 0x924},
+ { 0x1b1800, 128, 0x1f, 0x10},
+ { 0x1b1c00, 128, 0x1f, 0x10},
+ { 0x1b2000, 1, 0x1f, 0xdb6},
+ { 0x1b2400, 1, 0x1e, 0x92c},
+ { 0x1b2404, 5631, 0x1c, 0x8},
+ { 0x1b8000, 1, 0x1f, 0xfff},
+ { 0x1b8040, 1, 0x1f, 0xfff},
+ { 0x1b8080, 1, 0x1f, 0xfff},
+ { 0x1b80c0, 1, 0x1f, 0xfff},
+ { 0x1b8100, 1, 0x1f, 0x924},
+ { 0x1b8140, 1, 0x1f, 0x924},
+ { 0x1b8180, 1, 0x1f, 0x924},
+ { 0x1b81c0, 1, 0x1f, 0x924},
+ { 0x1b8200, 1, 0x1f, 0x924},
+ { 0x1b8240, 1, 0x1f, 0x924},
+ { 0x1b8280, 1, 0x1f, 0x924},
+ { 0x1b82c0, 1, 0x1f, 0x924},
+ { 0x1b8300, 1, 0x1f, 0x924},
+ { 0x1b8340, 1, 0x1f, 0x924},
+ { 0x1b8380, 1, 0x1f, 0x924},
+ { 0x1b83c0, 1, 0x1f, 0x924},
+ { 0x1b8400, 1, 0x1f, 0x924},
+ { 0x1b8440, 1, 0x1f, 0x924},
+ { 0x1b8480, 1, 0x1f, 0x924},
+ { 0x1b84c0, 1, 0x1f, 0x924},
+ { 0x1b8500, 1, 0x1f, 0x924},
+ { 0x1b8540, 1, 0x1f, 0x924},
+ { 0x1b8580, 1, 0x1f, 0x924},
+ { 0x1b85c0, 19, 0x1c, 0x924},
+ { 0x1b8800, 1, 0x1f, 0x924},
+ { 0x1b8840, 1, 0x1f, 0x924},
+ { 0x1b8880, 1, 0x1f, 0x924},
+ { 0x1b88c0, 1, 0x1f, 0x924},
+ { 0x1b8900, 1, 0x1f, 0x924},
+ { 0x1b8940, 1, 0x1f, 0x924},
+ { 0x1b8980, 1, 0x1f, 0x924},
+ { 0x1b89c0, 1, 0x1f, 0x924},
+ { 0x1b8a00, 1, 0x1f, 0x934},
+ { 0x1b8a40, 1, 0x1f, 0x924},
+ { 0x1b8a80, 1, 0x1f, 0x492},
+ { 0x1b8ac0, 1, 0x1f, 0x924},
+ { 0x1b8b00, 1, 0x1f, 0x924},
+ { 0x1b8b40, 1, 0x1f, 0x924},
+ { 0x1b8b80, 1, 0x1f, 0x924},
+ { 0x1b8bc0, 1, 0x1f, 0x924},
+ { 0x1b8c00, 1, 0x1f, 0x924},
+ { 0x1b8c40, 1, 0x1f, 0x924},
+ { 0x1b8c80, 1, 0x1f, 0x924},
+ { 0x1b8cc0, 1, 0x1f, 0x924},
+ { 0x1b8cc4, 1, 0x1c, 0x924},
+ { 0x1b8d00, 1, 0x1f, 0x924},
+ { 0x1b8d40, 1, 0x1f, 0x924},
+ { 0x1b8d80, 1, 0x1f, 0x924},
+ { 0x1b8dc0, 1, 0x1f, 0x924},
+ { 0x1b8e00, 1, 0x1f, 0x924},
+ { 0x1b8e40, 1, 0x1f, 0x924},
+ { 0x1b8e80, 1, 0x1f, 0x924},
+ { 0x1b8e84, 1, 0x1c, 0x924},
+ { 0x1b8ec0, 1, 0x1e, 0x924},
+ { 0x1b8f00, 1, 0x1e, 0x924},
+ { 0x1b8f40, 1, 0x1e, 0x924},
+ { 0x1b8f80, 1, 0x1e, 0x924},
+ { 0x1b8fc0, 1, 0x1e, 0x924},
+ { 0x1b8fd4, 5, 0x1c, 0x924},
+ { 0x1b8fe8, 2, 0x18, 0x924},
+ { 0x1b9000, 1, 0x1c, 0x924},
+ { 0x1b9040, 3, 0x1c, 0x924},
+ { 0x1b905c, 1, 0x18, 0x924},
+ { 0x1b9064, 1, 0x10, 0x924},
+ { 0x1b9080, 10, 0x10, 0x924},
+ { 0x1c0000, 2, 0x1f, 0x924},
+ { 0x200000, 65, 0x1f, 0x924},
+ { 0x200124, 2, 0x1f, 0x1fff},
+ { 0x200130, 3, 0x1f, 0x1fff},
+ { 0x200140, 1, 0x1f, 0x1fff},
+ { 0x20014c, 2, 0x1e, 0x924},
+ { 0x200200, 27, 0x1f, 0x924},
+ { 0x20026c, 1, 0x1f, 0xfff},
+ { 0x200270, 12, 0x1f, 0x924},
+ { 0x2002a0, 1, 0x1f, 0xfff},
+ { 0x2002a4, 17, 0x1f, 0x924},
+ { 0x200340, 4, 0x1f, 0x924},
+ { 0x200380, 1, 0x1c, 0x924},
+ { 0x200388, 1, 0x1c, 0x924},
+ { 0x200390, 1, 0x1c, 0x924},
+ { 0x200398, 1, 0x1c, 0x924},
+ { 0x2003a0, 1, 0x1c, 0x924},
+ { 0x2003a8, 2, 0x1c, 0x924},
+ { 0x200400, 256, 0x3, 0xfff},
+ { 0x202000, 4, 0x1f, 0x1927},
+ { 0x202010, 2044, 0x1f, 0x1007},
+ { 0x204000, 4, 0x18, 0x924},
+ { 0x220000, 1, 0x1f, 0x925},
+ { 0x220004, 5631, 0x1f, 0x1},
+ { 0x225800, 2560, 0x1e, 0x1},
+ { 0x228000, 1, 0x1f, 0x925},
+ { 0x228004, 8191, 0x1e, 0x1},
+ { 0x230000, 1, 0x1f, 0x925},
+ { 0x230004, 15, 0x2, 0x1},
+ { 0x230040, 1, 0x1e, 0x925},
+ { 0x230044, 239, 0x2, 0x1},
+ { 0x230400, 1, 0x1f, 0x925},
+ { 0x230404, 255, 0x2, 0x1},
+ { 0x230800, 1, 0x1f, 0x924},
+ { 0x230840, 1, 0x1e, 0x924},
+ { 0x230c00, 1, 0x1f, 0x924},
+ { 0x231000, 1, 0x1f, 0x924},
+ { 0x231040, 1, 0x1e, 0x924},
+ { 0x231400, 1, 0x1f, 0x924},
+ { 0x231440, 1, 0x1e, 0x924},
+ { 0x231480, 1, 0x1e, 0x924},
+ { 0x2314c0, 1, 0x1e, 0x924},
+ { 0x231800, 128, 0x1f, 0x2},
+ { 0x231c00, 128, 0x1f, 0x2},
+ { 0x232000, 1, 0x1f, 0xdb6},
+ { 0x232400, 1, 0x1e, 0x925},
+ { 0x232404, 5631, 0x1c, 0x1},
+ { 0x238000, 1, 0x1f, 0xfff},
+ { 0x238040, 1, 0x1f, 0xfff},
+ { 0x238080, 1, 0x1f, 0xfff},
+ { 0x2380c0, 1, 0x1f, 0xfff},
+ { 0x238100, 1, 0x1f, 0x924},
+ { 0x238140, 1, 0x1f, 0x924},
+ { 0x238180, 1, 0x1f, 0x924},
+ { 0x2381c0, 1, 0x1f, 0x924},
+ { 0x238200, 1, 0x1f, 0x924},
+ { 0x238240, 1, 0x1f, 0x924},
+ { 0x238280, 1, 0x1f, 0x924},
+ { 0x2382c0, 1, 0x1f, 0x924},
+ { 0x238300, 1, 0x1f, 0x924},
+ { 0x238340, 1, 0x1f, 0x924},
+ { 0x238380, 1, 0x1f, 0x924},
+ { 0x2383c0, 1, 0x1f, 0x924},
+ { 0x238400, 1, 0x1f, 0x924},
+ { 0x238440, 1, 0x1f, 0x924},
+ { 0x238480, 1, 0x1f, 0x924},
+ { 0x2384c0, 1, 0x1f, 0x924},
+ { 0x238500, 1, 0x1f, 0x924},
+ { 0x238540, 1, 0x1f, 0x924},
+ { 0x238580, 1, 0x1f, 0x924},
+ { 0x2385c0, 19, 0x1c, 0x924},
+ { 0x238800, 1, 0x1f, 0x924},
+ { 0x238840, 1, 0x1f, 0x924},
+ { 0x238880, 1, 0x1f, 0x924},
+ { 0x2388c0, 1, 0x1f, 0x924},
+ { 0x238900, 1, 0x1f, 0x924},
+ { 0x238940, 1, 0x1f, 0x924},
+ { 0x238980, 1, 0x1f, 0x924},
+ { 0x2389c0, 1, 0x1f, 0x924},
+ { 0x238a00, 1, 0x1f, 0x926},
+ { 0x238a40, 1, 0x1f, 0x924},
+ { 0x238a80, 1, 0x1f, 0x492},
+ { 0x238ac0, 1, 0x1f, 0x924},
+ { 0x238b00, 1, 0x1f, 0x924},
+ { 0x238b40, 1, 0x1f, 0x924},
+ { 0x238b80, 1, 0x1f, 0x924},
+ { 0x238bc0, 1, 0x1f, 0x924},
+ { 0x238c00, 1, 0x1f, 0x924},
+ { 0x238c40, 1, 0x1f, 0x924},
+ { 0x238c80, 1, 0x1f, 0x924},
+ { 0x238cc0, 1, 0x1f, 0x924},
+ { 0x238cc4, 1, 0x1c, 0x924},
+ { 0x238d00, 1, 0x1f, 0x924},
+ { 0x238d40, 1, 0x1f, 0x924},
+ { 0x238d80, 1, 0x1f, 0x924},
+ { 0x238dc0, 1, 0x1f, 0x924},
+ { 0x238e00, 1, 0x1f, 0x924},
+ { 0x238e40, 1, 0x1f, 0x924},
+ { 0x238e80, 1, 0x1f, 0x924},
+ { 0x238e84, 1, 0x1c, 0x924},
+ { 0x238ec0, 1, 0x1e, 0x924},
+ { 0x238f00, 1, 0x1e, 0x924},
+ { 0x238f40, 1, 0x1e, 0x924},
+ { 0x238f80, 1, 0x1e, 0x924},
+ { 0x238fc0, 1, 0x1e, 0x924},
+ { 0x238fd4, 5, 0x1c, 0x924},
+ { 0x238fe8, 2, 0x18, 0x924},
+ { 0x239000, 1, 0x1c, 0x924},
+ { 0x239040, 3, 0x1c, 0x924},
+ { 0x23905c, 1, 0x18, 0x924},
+ { 0x239064, 1, 0x10, 0x924},
+ { 0x239080, 10, 0x10, 0x924},
+ { 0x240000, 2, 0x1f, 0x924},
+ { 0x280000, 65, 0x1f, 0x924},
+ { 0x280124, 2, 0x1f, 0x1fff},
+ { 0x280130, 3, 0x1f, 0x1fff},
+ { 0x280140, 1, 0x1f, 0x1fff},
+ { 0x28014c, 2, 0x1e, 0x924},
+ { 0x280200, 27, 0x1f, 0x924},
+ { 0x28026c, 1, 0x1f, 0xfff},
+ { 0x280270, 12, 0x1f, 0x924},
+ { 0x2802a0, 1, 0x1f, 0xfff},
+ { 0x2802a4, 17, 0x1f, 0x924},
+ { 0x280340, 4, 0x1f, 0x924},
+ { 0x280380, 1, 0x1c, 0x924},
+ { 0x280388, 1, 0x1c, 0x924},
+ { 0x280390, 1, 0x1c, 0x924},
+ { 0x280398, 1, 0x1c, 0x924},
+ { 0x2803a0, 1, 0x1c, 0x924},
+ { 0x2803a8, 2, 0x1c, 0x924},
+ { 0x280400, 256, 0x3, 0xfff},
+ { 0x282000, 4, 0x1f, 0x9e4},
+ { 0x282010, 2044, 0x1f, 0x1c0},
+ { 0x284000, 4, 0x18, 0x924},
+ { 0x2a0000, 1, 0x1f, 0x964},
+ { 0x2a0004, 5631, 0x1f, 0x40},
+ { 0x2a5800, 2560, 0x1e, 0x40},
+ { 0x2a8000, 1, 0x1f, 0x964},
+ { 0x2a8004, 8191, 0x1e, 0x40},
+ { 0x2b0000, 1, 0x1f, 0x964},
+ { 0x2b0004, 15, 0x2, 0x40},
+ { 0x2b0040, 1, 0x1e, 0x964},
+ { 0x2b0044, 239, 0x2, 0x40},
+ { 0x2b0400, 1, 0x1f, 0x964},
+ { 0x2b0404, 255, 0x2, 0x40},
+ { 0x2b0800, 1, 0x1f, 0x924},
+ { 0x2b0840, 1, 0x1e, 0x924},
+ { 0x2b0c00, 1, 0x1f, 0x924},
+ { 0x2b1000, 1, 0x1f, 0x924},
+ { 0x2b1040, 1, 0x1e, 0x924},
+ { 0x2b1400, 1, 0x1f, 0x924},
+ { 0x2b1440, 1, 0x1e, 0x924},
+ { 0x2b1480, 1, 0x1e, 0x924},
+ { 0x2b14c0, 1, 0x1e, 0x924},
+ { 0x2b1800, 128, 0x1f, 0x80},
+ { 0x2b1c00, 128, 0x1f, 0x80},
+ { 0x2b2000, 1, 0x1f, 0xdb6},
+ { 0x2b2400, 1, 0x1e, 0x964},
+ { 0x2b2404, 5631, 0x1c, 0x40},
+ { 0x2b8000, 1, 0x1f, 0xfff},
+ { 0x2b8040, 1, 0x1f, 0xfff},
+ { 0x2b8080, 1, 0x1f, 0xfff},
+ { 0x2b80c0, 1, 0x1f, 0x924},
+ { 0x2b8100, 1, 0x1f, 0x924},
+ { 0x2b8140, 1, 0x1f, 0x924},
+ { 0x2b8180, 1, 0x1f, 0x924},
+ { 0x2b81c0, 1, 0x1f, 0x924},
+ { 0x2b8200, 1, 0x1f, 0x924},
+ { 0x2b8240, 1, 0x1f, 0x924},
+ { 0x2b8280, 1, 0x1f, 0x924},
+ { 0x2b82c0, 1, 0x1f, 0x924},
+ { 0x2b8300, 1, 0x1f, 0x924},
+ { 0x2b8340, 1, 0x1f, 0x924},
+ { 0x2b8380, 1, 0x1f, 0x924},
+ { 0x2b83c0, 1, 0x1f, 0x924},
+ { 0x2b8400, 1, 0x1f, 0x924},
+ { 0x2b8440, 1, 0x1f, 0x924},
+ { 0x2b8480, 1, 0x1f, 0x924},
+ { 0x2b84c0, 1, 0x1f, 0x924},
+ { 0x2b8500, 1, 0x1f, 0x924},
+ { 0x2b8540, 1, 0x1f, 0x924},
+ { 0x2b8580, 1, 0x1f, 0x924},
+ { 0x2b85c0, 19, 0x1c, 0x924},
+ { 0x2b8800, 1, 0x1f, 0x924},
+ { 0x2b8840, 1, 0x1f, 0x924},
+ { 0x2b8880, 1, 0x1f, 0x924},
+ { 0x2b88c0, 1, 0x1f, 0x924},
+ { 0x2b8900, 1, 0x1f, 0x924},
+ { 0x2b8940, 1, 0x1f, 0x924},
+ { 0x2b8980, 1, 0x1f, 0x924},
+ { 0x2b89c0, 1, 0x1f, 0x924},
+ { 0x2b8a00, 1, 0x1f, 0x9a4},
+ { 0x2b8a40, 1, 0x1f, 0x924},
+ { 0x2b8a80, 1, 0x1f, 0x492},
+ { 0x2b8ac0, 1, 0x1f, 0x924},
+ { 0x2b8b00, 1, 0x1f, 0x924},
+ { 0x2b8b40, 1, 0x1f, 0x924},
+ { 0x2b8b80, 1, 0x1f, 0x924},
+ { 0x2b8bc0, 1, 0x1f, 0x924},
+ { 0x2b8c00, 1, 0x1f, 0x924},
+ { 0x2b8c40, 1, 0x1f, 0x924},
+ { 0x2b8c80, 1, 0x1f, 0x924},
+ { 0x2b8cc0, 1, 0x1f, 0x924},
+ { 0x2b8cc4, 1, 0x1c, 0x924},
+ { 0x2b8d00, 1, 0x1f, 0x924},
+ { 0x2b8d40, 1, 0x1f, 0x924},
+ { 0x2b8d80, 1, 0x1f, 0x924},
+ { 0x2b8dc0, 1, 0x1f, 0x924},
+ { 0x2b8e00, 1, 0x1f, 0x924},
+ { 0x2b8e40, 1, 0x1f, 0x924},
+ { 0x2b8e80, 1, 0x1f, 0x924},
+ { 0x2b8e84, 1, 0x1c, 0x924},
+ { 0x2b8ec0, 1, 0x1e, 0x924},
+ { 0x2b8f00, 1, 0x1e, 0x924},
+ { 0x2b8f40, 1, 0x1e, 0x924},
+ { 0x2b8f80, 1, 0x1e, 0x924},
+ { 0x2b8fc0, 1, 0x1e, 0x924},
+ { 0x2b8fd4, 5, 0x1c, 0x924},
+ { 0x2b8fe8, 2, 0x18, 0x924},
+ { 0x2b9000, 1, 0x1c, 0x924},
+ { 0x2b9040, 3, 0x1c, 0x924},
+ { 0x2b905c, 1, 0x18, 0x924},
+ { 0x2b9064, 1, 0x10, 0x924},
+ { 0x2b9080, 10, 0x10, 0x924},
+ { 0x2c0000, 2, 0x1f, 0x1fff},
+ { 0x300000, 65, 0x1f, 0x924},
+ { 0x300124, 2, 0x1f, 0x1fff},
+ { 0x300130, 3, 0x1f, 0x1fff},
+ { 0x300140, 1, 0x1f, 0x1fff},
+ { 0x30014c, 2, 0x1e, 0x924},
+ { 0x300200, 27, 0x1f, 0x924},
+ { 0x30026c, 1, 0x1f, 0xfff},
+ { 0x300270, 12, 0x1f, 0x924},
+ { 0x3002a0, 1, 0x1f, 0xfff},
+ { 0x3002a4, 17, 0x1f, 0x924},
+ { 0x300340, 4, 0x1f, 0x924},
+ { 0x300380, 1, 0x1c, 0x924},
+ { 0x300388, 1, 0x1c, 0x924},
+ { 0x300390, 1, 0x1c, 0x924},
+ { 0x300398, 1, 0x1c, 0x924},
+ { 0x3003a0, 1, 0x1c, 0x924},
+ { 0x3003a8, 2, 0x1c, 0x924},
+ { 0x300400, 256, 0x3, 0xfff},
+ { 0x302000, 4, 0x1f, 0xf24},
+ { 0x302010, 2044, 0x1f, 0xe00},
+ { 0x304000, 4, 0x18, 0x924},
+ { 0x320000, 1, 0x1f, 0xb24},
+ { 0x320004, 5631, 0x1f, 0x200},
+ { 0x325800, 2560, 0x1e, 0x200},
+ { 0x328000, 1, 0x1f, 0xb24},
+ { 0x328004, 8191, 0x1e, 0x200},
+ { 0x330000, 1, 0x1f, 0xb24},
+ { 0x330004, 15, 0x2, 0x200},
+ { 0x330040, 1, 0x1e, 0xb24},
+ { 0x330044, 239, 0x2, 0x200},
+ { 0x330400, 1, 0x1f, 0xb24},
+ { 0x330404, 255, 0x2, 0x200},
+ { 0x330800, 1, 0x1f, 0x924},
+ { 0x330840, 1, 0x1e, 0x924},
+ { 0x330c00, 1, 0x1f, 0x924},
+ { 0x331000, 1, 0x1f, 0x924},
+ { 0x331040, 1, 0x1e, 0x924},
+ { 0x331400, 1, 0x1f, 0x924},
+ { 0x331440, 1, 0x1e, 0x924},
+ { 0x331480, 1, 0x1e, 0x924},
+ { 0x3314c0, 1, 0x1e, 0x924},
+ { 0x331800, 128, 0x1f, 0x400},
+ { 0x331c00, 128, 0x1f, 0x400},
+ { 0x332000, 1, 0x1f, 0xdb6},
+ { 0x332400, 1, 0x1e, 0xb24},
+ { 0x332404, 5631, 0x1c, 0x200},
+ { 0x338000, 1, 0x1f, 0xfff},
+ { 0x338040, 1, 0x1f, 0xfff},
+ { 0x338080, 1, 0x1f, 0xfff},
+ { 0x3380c0, 1, 0x1f, 0xfff},
+ { 0x338100, 1, 0x1f, 0x924},
+ { 0x338140, 1, 0x1f, 0x924},
+ { 0x338180, 1, 0x1f, 0x924},
+ { 0x3381c0, 1, 0x1f, 0x924},
+ { 0x338200, 1, 0x1f, 0x924},
+ { 0x338240, 1, 0x1f, 0x924},
+ { 0x338280, 1, 0x1f, 0x924},
+ { 0x3382c0, 1, 0x1f, 0x924},
+ { 0x338300, 1, 0x1f, 0x924},
+ { 0x338340, 1, 0x1f, 0x924},
+ { 0x338380, 1, 0x1f, 0x924},
+ { 0x3383c0, 1, 0x1f, 0x924},
+ { 0x338400, 1, 0x1f, 0x924},
+ { 0x338440, 1, 0x1f, 0x924},
+ { 0x338480, 1, 0x1f, 0x924},
+ { 0x3384c0, 1, 0x1f, 0x924},
+ { 0x338500, 1, 0x1f, 0x924},
+ { 0x338540, 1, 0x1f, 0x924},
+ { 0x338580, 1, 0x1f, 0x924},
+ { 0x3385c0, 19, 0x1c, 0x924},
+ { 0x338800, 1, 0x1f, 0x924},
+ { 0x338840, 1, 0x1f, 0x924},
+ { 0x338880, 1, 0x1f, 0x924},
+ { 0x3388c0, 1, 0x1f, 0x924},
+ { 0x338900, 1, 0x1f, 0x924},
+ { 0x338940, 1, 0x1f, 0x924},
+ { 0x338980, 1, 0x1f, 0x924},
+ { 0x3389c0, 1, 0x1f, 0x924},
+ { 0x338a00, 1, 0x1f, 0xd24},
+ { 0x338a40, 1, 0x1f, 0x924},
+ { 0x338a80, 1, 0x1f, 0x492},
+ { 0x338ac0, 1, 0x1f, 0x924},
+ { 0x338b00, 1, 0x1f, 0x924},
+ { 0x338b40, 1, 0x1f, 0x924},
+ { 0x338b80, 1, 0x1f, 0x924},
+ { 0x338bc0, 1, 0x1f, 0x924},
+ { 0x338c00, 1, 0x1f, 0x924},
+ { 0x338c40, 1, 0x1f, 0x924},
+ { 0x338c80, 1, 0x1f, 0x924},
+ { 0x338cc0, 1, 0x1f, 0x924},
+ { 0x338cc4, 1, 0x1c, 0x924},
+ { 0x338d00, 1, 0x1f, 0x924},
+ { 0x338d40, 1, 0x1f, 0x924},
+ { 0x338d80, 1, 0x1f, 0x924},
+ { 0x338dc0, 1, 0x1f, 0x924},
+ { 0x338e00, 1, 0x1f, 0x924},
+ { 0x338e40, 1, 0x1f, 0x924},
+ { 0x338e80, 1, 0x1f, 0x924},
+ { 0x338e84, 1, 0x1c, 0x924},
+ { 0x338ec0, 1, 0x1e, 0x924},
+ { 0x338f00, 1, 0x1e, 0x924},
+ { 0x338f40, 1, 0x1e, 0x924},
+ { 0x338f80, 1, 0x1e, 0x924},
+ { 0x338fc0, 1, 0x1e, 0x924},
+ { 0x338fd4, 5, 0x1c, 0x924},
+ { 0x338fe8, 2, 0x18, 0x924},
+ { 0x339000, 1, 0x1c, 0x924},
+ { 0x339040, 3, 0x1c, 0x924},
+ { 0x33905c, 1, 0x18, 0x924},
+ { 0x339064, 1, 0x10, 0x924},
+ { 0x339080, 10, 0x10, 0x924},
+ { 0x340000, 2, 0x1f, 0x924},
+ { 0x3a0000, 40960, 0x1c, 0x1000}
+};
+
+#define REGS_COUNT ARRAY_SIZE(reg_addrs)
+
+static const struct reg_addr idle_reg_addrs[] = {
+ { 0x2104, 1, 0x1f, 0xfff},
+ { 0x2110, 2, 0x1f, 0xfff},
+ { 0x211c, 8, 0x1f, 0xfff},
+ { 0x2814, 1, 0x1f, 0xfff},
+ { 0x281c, 2, 0x1f, 0xfff},
+ { 0x2854, 1, 0x1f, 0xfff},
+ { 0x285c, 1, 0x1f, 0xfff},
+ { 0x3040, 1, 0x1f, 0xfff},
+ { 0x9010, 7, 0x1c, 0xfff},
+ { 0x9030, 1, 0x1c, 0xfff},
+ { 0x9068, 16, 0x1c, 0xfff},
+ { 0x9230, 2, 0x1c, 0xfff},
+ { 0x9244, 1, 0x1c, 0xfff},
+ { 0x9298, 1, 0x1c, 0xfff},
+ { 0x92a8, 1, 0x1c, 0x1fff},
+ { 0xa38c, 1, 0x1f, 0x1fff},
+ { 0xa3c4, 1, 0x1e, 0xfff},
+ { 0xa404, 1, 0x1f, 0xfff},
+ { 0xa408, 2, 0x1f, 0x1fff},
+ { 0xa42c, 12, 0x1f, 0xfff},
+ { 0xa580, 1, 0x1f, 0x1fff},
+ { 0xa590, 1, 0x1f, 0x1fff},
+ { 0xa600, 5, 0x1e, 0xfff},
+ { 0xa618, 1, 0x1e, 0xfff},
+ { 0xa714, 1, 0x1c, 0xfff},
+ { 0xa720, 1, 0x1c, 0xfff},
+ { 0xa750, 1, 0x1c, 0xfff},
+ { 0xc09c, 1, 0x3, 0xfff},
+ { 0x103b0, 1, 0x1f, 0xfff},
+ { 0x103c0, 1, 0x1f, 0xfff},
+ { 0x103d0, 1, 0x3, 0x1fff},
+ { 0x10418, 1, 0x1f, 0xfff},
+ { 0x10420, 1, 0x1f, 0xfff},
+ { 0x10428, 1, 0x1f, 0xfff},
+ { 0x10460, 1, 0x1f, 0xfff},
+ { 0x10474, 1, 0x1f, 0xfff},
+ { 0x104e0, 1, 0x1f, 0xfff},
+ { 0x104ec, 1, 0x1f, 0xfff},
+ { 0x104f8, 1, 0x1f, 0xfff},
+ { 0x10508, 1, 0x1f, 0xfff},
+ { 0x10530, 1, 0x1f, 0xfff},
+ { 0x10538, 1, 0x1f, 0xfff},
+ { 0x10548, 1, 0x1f, 0xfff},
+ { 0x10558, 1, 0x1f, 0xfff},
+ { 0x182a8, 1, 0x1c, 0xfff},
+ { 0x182b8, 1, 0x1c, 0xfff},
+ { 0x18308, 1, 0x1c, 0xfff},
+ { 0x18318, 1, 0x1c, 0xfff},
+ { 0x18338, 1, 0x1c, 0xfff},
+ { 0x18348, 1, 0x1c, 0xfff},
+ { 0x183bc, 1, 0x1c, 0x1fff},
+ { 0x183cc, 1, 0x1c, 0x1fff},
+ { 0x18570, 1, 0x18, 0xfff},
+ { 0x18578, 1, 0x18, 0xfff},
+ { 0x1858c, 1, 0x18, 0xfff},
+ { 0x18594, 1, 0x18, 0xfff},
+ { 0x1862c, 4, 0x10, 0xfff},
+ { 0x2021c, 11, 0x1f, 0xfff},
+ { 0x202a8, 1, 0x1f, 0xfff},
+ { 0x202b8, 1, 0x1f, 0x1fff},
+ { 0x20404, 1, 0x1f, 0xfff},
+ { 0x2040c, 2, 0x1f, 0xfff},
+ { 0x2041c, 2, 0x1f, 0xfff},
+ { 0x40154, 14, 0x1f, 0xfff},
+ { 0x40198, 1, 0x1f, 0x1fff},
+ { 0x404ac, 1, 0x1f, 0xfff},
+ { 0x404bc, 1, 0x1f, 0x1fff},
+ { 0x42290, 1, 0x1f, 0xfff},
+ { 0x422a0, 1, 0x1f, 0xfff},
+ { 0x422b0, 1, 0x1f, 0x1fff},
+ { 0x42548, 1, 0x1f, 0xfff},
+ { 0x42550, 1, 0x1f, 0xfff},
+ { 0x42558, 1, 0x1f, 0xfff},
+ { 0x50160, 8, 0x1f, 0xfff},
+ { 0x501d0, 1, 0x1f, 0xfff},
+ { 0x501e0, 1, 0x1f, 0x1fff},
+ { 0x50204, 1, 0x1f, 0xfff},
+ { 0x5020c, 2, 0x1f, 0xfff},
+ { 0x5021c, 1, 0x1f, 0xfff},
+ { 0x60090, 1, 0x1f, 0xfff},
+ { 0x6011c, 1, 0x1f, 0xfff},
+ { 0x6012c, 1, 0x1f, 0x1fff},
+ { 0xc101c, 1, 0x1f, 0xfff},
+ { 0xc102c, 1, 0x1f, 0x1fff},
+ { 0xc2290, 1, 0x1f, 0xfff},
+ { 0xc22a0, 1, 0x1f, 0xfff},
+ { 0xc22b0, 1, 0x1f, 0x1fff},
+ { 0xc2548, 1, 0x1f, 0xfff},
+ { 0xc2550, 1, 0x1f, 0xfff},
+ { 0xc2558, 1, 0x1f, 0xfff},
+ { 0xc4294, 1, 0x1f, 0xfff},
+ { 0xc42a4, 1, 0x1f, 0xfff},
+ { 0xc42b4, 1, 0x1f, 0x1fff},
+ { 0xc4550, 1, 0x1f, 0xfff},
+ { 0xc4558, 1, 0x1f, 0xfff},
+ { 0xc4560, 1, 0x1f, 0xfff},
+ { 0xd016c, 8, 0x1f, 0xfff},
+ { 0xd01d8, 1, 0x1f, 0xfff},
+ { 0xd01e8, 1, 0x1f, 0x1fff},
+ { 0xd0204, 1, 0x1f, 0xfff},
+ { 0xd020c, 3, 0x1f, 0xfff},
+ { 0xe0154, 8, 0x1f, 0xfff},
+ { 0xe01c8, 1, 0x1f, 0xfff},
+ { 0xe01d8, 1, 0x1f, 0x1fff},
+ { 0xe0204, 1, 0x1f, 0xfff},
+ { 0xe020c, 2, 0x1f, 0xfff},
+ { 0xe021c, 2, 0x1f, 0xfff},
+ { 0x101014, 1, 0x1f, 0xfff},
+ { 0x101030, 1, 0x1f, 0xfff},
+ { 0x101040, 1, 0x1f, 0x1fff},
+ { 0x102058, 1, 0x1f, 0x1fff},
+ { 0x102080, 16, 0x1f, 0xfff},
+ { 0x103004, 2, 0x1f, 0xfff},
+ { 0x103068, 1, 0x1f, 0xfff},
+ { 0x103078, 1, 0x1f, 0xfff},
+ { 0x103088, 1, 0x1f, 0x1fff},
+ { 0x10309c, 2, 0x1e, 0xfff},
+ { 0x1030b8, 2, 0x1c, 0xfff},
+ { 0x1030cc, 1, 0x1c, 0xfff},
+ { 0x1030e0, 1, 0x1c, 0xfff},
+ { 0x104004, 1, 0x1f, 0xfff},
+ { 0x104018, 1, 0x1f, 0xfff},
+ { 0x104020, 1, 0x1f, 0xfff},
+ { 0x10403c, 1, 0x1f, 0xfff},
+ { 0x1040fc, 1, 0x1f, 0xfff},
+ { 0x10410c, 1, 0x1f, 0x1fff},
+ { 0x104400, 1, 0x1f, 0x1fff},
+ { 0x104404, 63, 0x1f, 0xfff},
+ { 0x104800, 1, 0x1f, 0x1fff},
+ { 0x104804, 63, 0x1f, 0xfff},
+ { 0x105000, 4, 0x1f, 0x1fff},
+ { 0x105010, 252, 0x1f, 0xfff},
+ { 0x108094, 1, 0x3, 0xfff},
+ { 0x1201b0, 2, 0x1f, 0xfff},
+ { 0x12032c, 1, 0x1f, 0xfff},
+ { 0x12036c, 3, 0x1f, 0xfff},
+ { 0x120408, 2, 0x1f, 0xfff},
+ { 0x120414, 15, 0x1f, 0xfff},
+ { 0x120478, 2, 0x1f, 0xfff},
+ { 0x12052c, 1, 0x1f, 0xfff},
+ { 0x120564, 3, 0x1f, 0xfff},
+ { 0x12057c, 1, 0x1f, 0x1fff},
+ { 0x12058c, 1, 0x1f, 0x1fff},
+ { 0x120608, 1, 0x1e, 0xfff},
+ { 0x120748, 1, 0x1c, 0xfff},
+ { 0x120778, 2, 0x1c, 0xfff},
+ { 0x120808, 3, 0x1f, 0xfff},
+ { 0x120818, 1, 0x1f, 0xfff},
+ { 0x120820, 1, 0x1f, 0xfff},
+ { 0x120828, 1, 0x1f, 0xfff},
+ { 0x120830, 1, 0x1f, 0xfff},
+ { 0x120838, 1, 0x1f, 0xfff},
+ { 0x120840, 1, 0x1f, 0xfff},
+ { 0x120848, 1, 0x1f, 0xfff},
+ { 0x120850, 1, 0x1f, 0xfff},
+ { 0x120858, 1, 0x1f, 0xfff},
+ { 0x120860, 1, 0x1f, 0xfff},
+ { 0x120868, 1, 0x1f, 0xfff},
+ { 0x120870, 1, 0x1f, 0xfff},
+ { 0x120878, 1, 0x1f, 0xfff},
+ { 0x120880, 1, 0x1f, 0xfff},
+ { 0x120888, 1, 0x1f, 0xfff},
+ { 0x120890, 1, 0x1f, 0xfff},
+ { 0x120898, 1, 0x1f, 0xfff},
+ { 0x1208a0, 1, 0x1f, 0xfff},
+ { 0x1208a8, 1, 0x1f, 0xfff},
+ { 0x1208b0, 1, 0x1f, 0xfff},
+ { 0x1208b8, 1, 0x1f, 0xfff},
+ { 0x1208c0, 1, 0x1f, 0xfff},
+ { 0x1208c8, 1, 0x1f, 0xfff},
+ { 0x1208d0, 1, 0x1f, 0xfff},
+ { 0x1208d8, 1, 0x1f, 0xfff},
+ { 0x1208e0, 1, 0x1f, 0xfff},
+ { 0x1208e8, 1, 0x1f, 0xfff},
+ { 0x1208f0, 1, 0x1f, 0xfff},
+ { 0x1208f8, 1, 0x1f, 0xfff},
+ { 0x120900, 1, 0x1f, 0xfff},
+ { 0x120908, 1, 0x1f, 0xfff},
+ { 0x130030, 1, 0x1c, 0xfff},
+ { 0x13004c, 3, 0x1c, 0xfff},
+ { 0x130064, 2, 0x1c, 0xfff},
+ { 0x13009c, 1, 0x1c, 0x1fff},
+ { 0x130130, 1, 0x1c, 0xfff},
+ { 0x13016c, 1, 0x1c, 0xfff},
+ { 0x130300, 1, 0x1c, 0xfff},
+ { 0x130480, 1, 0x1c, 0xfff},
+ { 0x14005c, 2, 0xf, 0xfff},
+ { 0x1400d0, 2, 0xf, 0xfff},
+ { 0x1400e0, 1, 0xf, 0xfff},
+ { 0x1401c8, 1, 0xf, 0xfff},
+ { 0x140200, 6, 0xf, 0xfff},
+ { 0x140338, 7, 0x10, 0xfff},
+ { 0x140370, 7, 0x10, 0xfff},
+ { 0x15c1bc, 6, 0x10, 0xfff},
+ { 0x15c230, 7, 0x10, 0xfff},
+ { 0x16101c, 1, 0x1f, 0xfff},
+ { 0x16102c, 1, 0x1f, 0x1fff},
+ { 0x164014, 2, 0x1f, 0xfff},
+ { 0x1640f0, 1, 0x1f, 0xfff},
+ { 0x166290, 1, 0x1f, 0xfff},
+ { 0x1662a0, 1, 0x1f, 0xfff},
+ { 0x1662b0, 1, 0x1f, 0x1fff},
+ { 0x166548, 1, 0x1f, 0xfff},
+ { 0x166550, 1, 0x1f, 0xfff},
+ { 0x166558, 1, 0x1f, 0xfff},
+ { 0x168000, 1, 0x1f, 0xfff},
+ { 0x168008, 1, 0x1f, 0xfff},
+ { 0x168010, 1, 0x1f, 0xfff},
+ { 0x168018, 1, 0x1f, 0xfff},
+ { 0x168028, 2, 0x1f, 0xfff},
+ { 0x168058, 9, 0x1f, 0xfff},
+ { 0x168238, 1, 0x1f, 0xfff},
+ { 0x1682d0, 7, 0x1f, 0xfff},
+ { 0x168300, 2, 0x3, 0xfff},
+ { 0x168308, 65, 0x1f, 0xfff},
+ { 0x168410, 2, 0x1f, 0xfff},
+ { 0x168438, 1, 0x1f, 0xfff},
+ { 0x168448, 1, 0x1f, 0x1fff},
+ { 0x168a00, 128, 0x1f, 0xfff},
+ { 0x16e200, 128, 0x2, 0xfff},
+ { 0x16e404, 2, 0x2, 0xfff},
+ { 0x16e584, 64, 0x2, 0xfff},
+ { 0x16e684, 2, 0x1e, 0xfff},
+ { 0x16e68c, 4, 0x2, 0xfff},
+ { 0x16e6fc, 4, 0x1c, 0xfff},
+ { 0x16e7ac, 12, 0x10, 0xfff},
+ { 0x1700a4, 1, 0x1f, 0xfff},
+ { 0x1700ac, 2, 0x1f, 0xfff},
+ { 0x1700c0, 1, 0x1f, 0xfff},
+ { 0x170174, 1, 0x1f, 0xfff},
+ { 0x170184, 1, 0x1f, 0x1fff},
+ { 0x1800f4, 1, 0x1f, 0xfff},
+ { 0x180104, 1, 0x1f, 0xfff},
+ { 0x180114, 1, 0x1f, 0x1fff},
+ { 0x180124, 1, 0x1f, 0x1fff},
+ { 0x18026c, 1, 0x1f, 0xfff},
+ { 0x1802a0, 1, 0x1f, 0xfff},
+ { 0x1b8000, 1, 0x1f, 0xfff},
+ { 0x1b8040, 1, 0x1f, 0xfff},
+ { 0x1b8080, 1, 0x1f, 0xfff},
+ { 0x1b80c0, 1, 0x1f, 0xfff},
+ { 0x200104, 1, 0x1f, 0xfff},
+ { 0x200114, 1, 0x1f, 0xfff},
+ { 0x200124, 1, 0x1f, 0x1fff},
+ { 0x200134, 1, 0x1f, 0x1fff},
+ { 0x20026c, 1, 0x1f, 0xfff},
+ { 0x2002a0, 1, 0x1f, 0xfff},
+ { 0x238000, 1, 0x1f, 0xfff},
+ { 0x238040, 1, 0x1f, 0xfff},
+ { 0x238080, 1, 0x1f, 0xfff},
+ { 0x2380c0, 1, 0x1f, 0xfff},
+ { 0x280104, 1, 0x1f, 0xfff},
+ { 0x280114, 1, 0x1f, 0xfff},
+ { 0x280124, 1, 0x1f, 0x1fff},
+ { 0x280134, 1, 0x1f, 0x1fff},
+ { 0x28026c, 1, 0x1f, 0xfff},
+ { 0x2802a0, 1, 0x1f, 0xfff},
+ { 0x2b8000, 1, 0x1f, 0xfff},
+ { 0x2b8040, 1, 0x1f, 0xfff},
+ { 0x2b8080, 1, 0x1f, 0xfff},
+ { 0x300104, 1, 0x1f, 0xfff},
+ { 0x300114, 1, 0x1f, 0xfff},
+ { 0x300124, 1, 0x1f, 0x1fff},
+ { 0x300134, 1, 0x1f, 0x1fff},
+ { 0x30026c, 1, 0x1f, 0xfff},
+ { 0x3002a0, 1, 0x1f, 0xfff},
+ { 0x338000, 1, 0x1f, 0xfff},
+ { 0x338040, 1, 0x1f, 0xfff},
+ { 0x338080, 1, 0x1f, 0xfff},
+ { 0x3380c0, 1, 0x1f, 0xfff}
+};
+
+#define IDLE_REGS_COUNT ARRAY_SIZE(idle_reg_addrs)
+
+static const u32 read_reg_e1[] = {
+ 0x1b1000};
+
+static const struct wreg_addr wreg_addr_e1 = {
+ 0x1b0c00, 192, 1, read_reg_e1, 0x1f, 0x1fff};
+
+static const u32 read_reg_e1h[] = {
+ 0x1b1040, 0x1b1000};
+
+static const struct wreg_addr wreg_addr_e1h = {
+ 0x1b0c00, 256, 2, read_reg_e1h, 0x1f, 0x1fff};
+
+static const u32 read_reg_e2[] = {
+ 0x1b1040, 0x1b1000};
+
+static const struct wreg_addr wreg_addr_e2 = {
+ 0x1b0c00, 128, 2, read_reg_e2, 0x1f, 0x1fff};
+
+static const u32 read_reg_e3[] = {
+ 0x1b1040, 0x1b1000};
+
+static const struct wreg_addr wreg_addr_e3 = {
+ 0x1b0c00, 128, 2, read_reg_e3, 0x1f, 0x1fff};
+
+static const u32 read_reg_e3b0[] = {
+ 0x1b1040, 0x1b1000};
+
+static const struct wreg_addr wreg_addr_e3b0 = {
+ 0x1b0c00, 128, 2, read_reg_e3b0, 0x1f, 0x1fff};
+
+static const unsigned int dump_num_registers[NUM_CHIPS][NUM_PRESETS] = {
+ {20782, 18567, 27975, 19729, 18311, 27719, 20836, 32391, 41799, 20812,
+ 26247, 35655, 19074},
+ {32774, 19297, 33277, 31721, 19041, 33021, 32828, 33121, 47101, 32804,
+ 26977, 40957, 35895},
+ {36527, 17928, 33697, 35474, 18700, 34466, 36581, 31752, 47521, 36557,
+ 25608, 41377, 43903},
+ {45239, 17936, 34387, 44186, 18708, 35156, 45293, 31760, 48211, 45269,
+ 25616, 42067, 43903},
+ {45302, 17999, 34802, 44249, 18771, 35571, 45356, 31823, 48626, 45332,
+ 25679, 42482, 43903}
+};
+#endif
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
new file mode 100644
index 00000000000..25eddd90f48
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -0,0 +1,3513 @@
+/* bnx2x_ethtool.c: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007-2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
+ * Written by: Eliezer Tamir
+ * Based on code from Michael Chan's bnx2 driver
+ * UDP CSUM errata workaround by Arik Gendelman
+ * Slowpath and fastpath rework by Vladislav Zolotarov
+ * Statistics and Link management by Yitchak Gertner
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/crc32.h>
+#include "bnx2x.h"
+#include "bnx2x_cmn.h"
+#include "bnx2x_dump.h"
+#include "bnx2x_init.h"
+
+/* Note: in the format strings below %s is replaced by the queue-name which is
+ * either its index or 'fcoe' for the fcoe queue. Make sure the format string
+ * length does not exceed ETH_GSTRING_LEN - MAX_QUEUE_NAME_LEN + 2
+ */
+#define MAX_QUEUE_NAME_LEN 4
+static const struct {
+ long offset;
+ int size;
+ char string[ETH_GSTRING_LEN];
+} bnx2x_q_stats_arr[] = {
+/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%s]: rx_bytes" },
+ { Q_STATS_OFFSET32(total_unicast_packets_received_hi),
+ 8, "[%s]: rx_ucast_packets" },
+ { Q_STATS_OFFSET32(total_multicast_packets_received_hi),
+ 8, "[%s]: rx_mcast_packets" },
+ { Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
+ 8, "[%s]: rx_bcast_packets" },
+ { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%s]: rx_discards" },
+ { Q_STATS_OFFSET32(rx_err_discard_pkt),
+ 4, "[%s]: rx_phy_ip_err_discards"},
+ { Q_STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, "[%s]: rx_skb_alloc_discard" },
+ { Q_STATS_OFFSET32(hw_csum_err), 4, "[%s]: rx_csum_offload_errors" },
+
+ { Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%s]: tx_bytes" },
+/* 10 */{ Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, "[%s]: tx_ucast_packets" },
+ { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi),
+ 8, "[%s]: tx_mcast_packets" },
+ { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
+ 8, "[%s]: tx_bcast_packets" },
+ { Q_STATS_OFFSET32(total_tpa_aggregations_hi),
+ 8, "[%s]: tpa_aggregations" },
+ { Q_STATS_OFFSET32(total_tpa_aggregated_frames_hi),
+ 8, "[%s]: tpa_aggregated_frames"},
+ { Q_STATS_OFFSET32(total_tpa_bytes_hi), 8, "[%s]: tpa_bytes"},
+ { Q_STATS_OFFSET32(driver_filtered_tx_pkt),
+ 4, "[%s]: driver_filtered_tx_pkt" }
+};
+
+#define BNX2X_NUM_Q_STATS ARRAY_SIZE(bnx2x_q_stats_arr)
+
+static const struct {
+ long offset;
+ int size;
+ u32 flags;
+#define STATS_FLAGS_PORT 1
+#define STATS_FLAGS_FUNC 2
+#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
+ char string[ETH_GSTRING_LEN];
+} bnx2x_stats_arr[] = {
+/* 1 */ { STATS_OFFSET32(total_bytes_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_bytes" },
+ { STATS_OFFSET32(error_bytes_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_error_bytes" },
+ { STATS_OFFSET32(total_unicast_packets_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
+ { STATS_OFFSET32(total_multicast_packets_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
+ { STATS_OFFSET32(total_broadcast_packets_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
+ { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
+ 8, STATS_FLAGS_PORT, "rx_crc_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
+ 8, STATS_FLAGS_PORT, "rx_align_errors" },
+ { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
+ { STATS_OFFSET32(etherstatsoverrsizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_oversize_packets" },
+/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
+ 8, STATS_FLAGS_PORT, "rx_fragments" },
+ { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
+ 8, STATS_FLAGS_PORT, "rx_jabbers" },
+ { STATS_OFFSET32(no_buff_discard_hi),
+ 8, STATS_FLAGS_BOTH, "rx_discards" },
+ { STATS_OFFSET32(mac_filter_discard),
+ 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
+ { STATS_OFFSET32(mf_tag_discard),
+ 4, STATS_FLAGS_PORT, "rx_mf_tag_discard" },
+ { STATS_OFFSET32(pfc_frames_received_hi),
+ 8, STATS_FLAGS_PORT, "pfc_frames_received" },
+ { STATS_OFFSET32(pfc_frames_sent_hi),
+ 8, STATS_FLAGS_PORT, "pfc_frames_sent" },
+ { STATS_OFFSET32(brb_drop_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_discard" },
+ { STATS_OFFSET32(brb_truncate_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_truncate" },
+ { STATS_OFFSET32(pause_frames_received_hi),
+ 8, STATS_FLAGS_PORT, "rx_pause_frames" },
+ { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
+ 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
+ { STATS_OFFSET32(nig_timer_max),
+ 4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
+/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
+ 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
+ { STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
+ { STATS_OFFSET32(hw_csum_err),
+ 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
+
+ { STATS_OFFSET32(total_bytes_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_bytes" },
+ { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
+ 8, STATS_FLAGS_PORT, "tx_error_bytes" },
+ { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_ucast_packets" },
+ { STATS_OFFSET32(total_multicast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_mcast_packets" },
+ { STATS_OFFSET32(total_broadcast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_bcast_packets" },
+ { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_mac_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
+/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
+ 8, STATS_FLAGS_PORT, "tx_single_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
+ 8, STATS_FLAGS_PORT, "tx_multi_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
+ 8, STATS_FLAGS_PORT, "tx_deferred" },
+ { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
+ 8, STATS_FLAGS_PORT, "tx_excess_collisions" },
+ { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi),
+ 8, STATS_FLAGS_PORT, "tx_late_collisions" },
+ { STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
+ 8, STATS_FLAGS_PORT, "tx_total_collisions" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" },
+ { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" },
+/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
+ { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
+ { STATS_OFFSET32(etherstatspktsover1522octets_hi),
+ 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
+ { STATS_OFFSET32(pause_frames_sent_hi),
+ 8, STATS_FLAGS_PORT, "tx_pause_frames" },
+ { STATS_OFFSET32(total_tpa_aggregations_hi),
+ 8, STATS_FLAGS_FUNC, "tpa_aggregations" },
+ { STATS_OFFSET32(total_tpa_aggregated_frames_hi),
+ 8, STATS_FLAGS_FUNC, "tpa_aggregated_frames"},
+ { STATS_OFFSET32(total_tpa_bytes_hi),
+ 8, STATS_FLAGS_FUNC, "tpa_bytes"},
+ { STATS_OFFSET32(recoverable_error),
+ 4, STATS_FLAGS_FUNC, "recoverable_errors" },
+ { STATS_OFFSET32(unrecoverable_error),
+ 4, STATS_FLAGS_FUNC, "unrecoverable_errors" },
+ { STATS_OFFSET32(driver_filtered_tx_pkt),
+ 4, STATS_FLAGS_FUNC, "driver_filtered_tx_pkt" },
+ { STATS_OFFSET32(eee_tx_lpi),
+ 4, STATS_FLAGS_PORT, "Tx LPI entry count"}
+};
+
+#define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr)
+
+static int bnx2x_get_port_type(struct bnx2x *bp)
+{
+ int port_type;
+ u32 phy_idx = bnx2x_get_cur_phy_idx(bp);
+ switch (bp->link_params.phy[phy_idx].media_type) {
+ case ETH_PHY_SFPP_10G_FIBER:
+ case ETH_PHY_SFP_1G_FIBER:
+ case ETH_PHY_XFP_FIBER:
+ case ETH_PHY_KR:
+ case ETH_PHY_CX4:
+ port_type = PORT_FIBRE;
+ break;
+ case ETH_PHY_DA_TWINAX:
+ port_type = PORT_DA;
+ break;
+ case ETH_PHY_BASE_T:
+ port_type = PORT_TP;
+ break;
+ case ETH_PHY_NOT_PRESENT:
+ port_type = PORT_NONE;
+ break;
+ case ETH_PHY_UNSPECIFIED:
+ default:
+ port_type = PORT_OTHER;
+ break;
+ }
+ return port_type;
+}
+
+static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+
+ /* Dual Media boards present all available port types */
+ cmd->supported = bp->port.supported[cfg_idx] |
+ (bp->port.supported[cfg_idx ^ 1] &
+ (SUPPORTED_TP | SUPPORTED_FIBRE));
+ cmd->advertising = bp->port.advertising[cfg_idx];
+ if (bp->link_params.phy[bnx2x_get_cur_phy_idx(bp)].media_type ==
+ ETH_PHY_SFP_1G_FIBER) {
+ cmd->supported &= ~(SUPPORTED_10000baseT_Full);
+ cmd->advertising &= ~(ADVERTISED_10000baseT_Full);
+ }
+
+ if ((bp->state == BNX2X_STATE_OPEN) && bp->link_vars.link_up &&
+ !(bp->flags & MF_FUNC_DIS)) {
+ cmd->duplex = bp->link_vars.duplex;
+
+ if (IS_MF(bp) && !BP_NOMCP(bp))
+ ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp));
+ else
+ ethtool_cmd_speed_set(cmd, bp->link_vars.line_speed);
+ } else {
+ cmd->duplex = DUPLEX_UNKNOWN;
+ ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
+ }
+
+ cmd->port = bnx2x_get_port_type(bp);
+
+ cmd->phy_address = bp->mdio.prtad;
+ cmd->transceiver = XCVR_INTERNAL;
+
+ if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG)
+ cmd->autoneg = AUTONEG_ENABLE;
+ else
+ cmd->autoneg = AUTONEG_DISABLE;
+
+ /* Publish LP advertised speeds and FC */
+ if (bp->link_vars.link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
+ u32 status = bp->link_vars.link_status;
+
+ cmd->lp_advertising |= ADVERTISED_Autoneg;
+ if (status & LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE)
+ cmd->lp_advertising |= ADVERTISED_Pause;
+ if (status & LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
+ cmd->lp_advertising |= ADVERTISED_Asym_Pause;
+
+ if (status & LINK_STATUS_LINK_PARTNER_10THD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_10baseT_Half;
+ if (status & LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_10baseT_Full;
+ if (status & LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_100baseT_Half;
+ if (status & LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_100baseT_Full;
+ if (status & LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_1000baseT_Half;
+ if (status & LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_1000baseT_Full;
+ if (status & LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_2500baseX_Full;
+ if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_10000baseT_Full;
+ if (status & LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE)
+ cmd->lp_advertising |= ADVERTISED_20000baseKR2_Full;
+ }
+
+ cmd->maxtxpkt = 0;
+ cmd->maxrxpkt = 0;
+
+ DP(BNX2X_MSG_ETHTOOL, "ethtool_cmd: cmd %d\n"
+ " supported 0x%x advertising 0x%x speed %u\n"
+ " duplex %d port %d phy_address %d transceiver %d\n"
+ " autoneg %d maxtxpkt %d maxrxpkt %d\n",
+ cmd->cmd, cmd->supported, cmd->advertising,
+ ethtool_cmd_speed(cmd),
+ cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
+ cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+
+ return 0;
+}
+
+static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config;
+ u32 speed, phy_idx;
+
+ if (IS_MF_SD(bp))
+ return 0;
+
+ DP(BNX2X_MSG_ETHTOOL, "ethtool_cmd: cmd %d\n"
+ " supported 0x%x advertising 0x%x speed %u\n"
+ " duplex %d port %d phy_address %d transceiver %d\n"
+ " autoneg %d maxtxpkt %d maxrxpkt %d\n",
+ cmd->cmd, cmd->supported, cmd->advertising,
+ ethtool_cmd_speed(cmd),
+ cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
+ cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+
+ speed = ethtool_cmd_speed(cmd);
+
+ /* If received a request for an unknown duplex, assume full*/
+ if (cmd->duplex == DUPLEX_UNKNOWN)
+ cmd->duplex = DUPLEX_FULL;
+
+ if (IS_MF_SI(bp)) {
+ u32 part;
+ u32 line_speed = bp->link_vars.line_speed;
+
+ /* use 10G if no link detected */
+ if (!line_speed)
+ line_speed = 10000;
+
+ if (bp->common.bc_ver < REQ_BC_VER_4_SET_MF_BW) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "To set speed BC %X or higher is required, please upgrade BC\n",
+ REQ_BC_VER_4_SET_MF_BW);
+ return -EINVAL;
+ }
+
+ part = (speed * 100) / line_speed;
+
+ if (line_speed < speed || !part) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Speed setting should be in a range from 1%% to 100%% of actual line speed\n");
+ return -EINVAL;
+ }
+
+ if (bp->state != BNX2X_STATE_OPEN)
+ /* store value for following "load" */
+ bp->pending_max = part;
+ else
+ bnx2x_update_max_mf_config(bp, part);
+
+ return 0;
+ }
+
+ cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ old_multi_phy_config = bp->link_params.multi_phy_config;
+ if (cmd->port != bnx2x_get_port_type(bp)) {
+ switch (cmd->port) {
+ case PORT_TP:
+ if (!(bp->port.supported[0] & SUPPORTED_TP ||
+ bp->port.supported[1] & SUPPORTED_TP)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Unsupported port type\n");
+ return -EINVAL;
+ }
+ bp->link_params.multi_phy_config &=
+ ~PORT_HW_CFG_PHY_SELECTION_MASK;
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED)
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ else
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ break;
+ case PORT_FIBRE:
+ case PORT_DA:
+ case PORT_NONE:
+ if (!(bp->port.supported[0] & SUPPORTED_FIBRE ||
+ bp->port.supported[1] & SUPPORTED_FIBRE)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Unsupported port type\n");
+ return -EINVAL;
+ }
+ bp->link_params.multi_phy_config &=
+ ~PORT_HW_CFG_PHY_SELECTION_MASK;
+ if (bp->link_params.multi_phy_config &
+ PORT_HW_CFG_PHY_SWAPPED_ENABLED)
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
+ else
+ bp->link_params.multi_phy_config |=
+ PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
+ break;
+ default:
+ DP(BNX2X_MSG_ETHTOOL, "Unsupported port type\n");
+ return -EINVAL;
+ }
+ }
+ /* Save new config in case command complete successfully */
+ new_multi_phy_config = bp->link_params.multi_phy_config;
+ /* Get the new cfg_idx */
+ cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ /* Restore old config in case command failed */
+ bp->link_params.multi_phy_config = old_multi_phy_config;
+ DP(BNX2X_MSG_ETHTOOL, "cfg_idx = %x\n", cfg_idx);
+
+ if (cmd->autoneg == AUTONEG_ENABLE) {
+ u32 an_supported_speed = bp->port.supported[cfg_idx];
+ if (bp->link_params.phy[EXT_PHY1].type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+ an_supported_speed |= (SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full);
+ if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
+ DP(BNX2X_MSG_ETHTOOL, "Autoneg not supported\n");
+ return -EINVAL;
+ }
+
+ /* advertise the requested speed and duplex if supported */
+ if (cmd->advertising & ~an_supported_speed) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Advertisement parameters are not supported\n");
+ return -EINVAL;
+ }
+
+ bp->link_params.req_line_speed[cfg_idx] = SPEED_AUTO_NEG;
+ bp->link_params.req_duplex[cfg_idx] = cmd->duplex;
+ bp->port.advertising[cfg_idx] = (ADVERTISED_Autoneg |
+ cmd->advertising);
+ if (cmd->advertising) {
+
+ bp->link_params.speed_cap_mask[cfg_idx] = 0;
+ if (cmd->advertising & ADVERTISED_10baseT_Half) {
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF;
+ }
+ if (cmd->advertising & ADVERTISED_10baseT_Full)
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL;
+
+ if (cmd->advertising & ADVERTISED_100baseT_Full)
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL;
+
+ if (cmd->advertising & ADVERTISED_100baseT_Half) {
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF;
+ }
+ if (cmd->advertising & ADVERTISED_1000baseT_Half) {
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G;
+ }
+ if (cmd->advertising & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_1000baseKX_Full))
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G;
+
+ if (cmd->advertising & (ADVERTISED_10000baseT_Full |
+ ADVERTISED_10000baseKX4_Full |
+ ADVERTISED_10000baseKR_Full))
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_10G;
+
+ if (cmd->advertising & ADVERTISED_20000baseKR2_Full)
+ bp->link_params.speed_cap_mask[cfg_idx] |=
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_20G;
+ }
+ } else { /* forced speed */
+ /* advertise the requested speed and duplex if supported */
+ switch (speed) {
+ case SPEED_10:
+ if (cmd->duplex == DUPLEX_FULL) {
+ if (!(bp->port.supported[cfg_idx] &
+ SUPPORTED_10baseT_Full)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "10M full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_10baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ if (!(bp->port.supported[cfg_idx] &
+ SUPPORTED_10baseT_Half)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "10M half not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_10baseT_Half |
+ ADVERTISED_TP);
+ }
+ break;
+
+ case SPEED_100:
+ if (cmd->duplex == DUPLEX_FULL) {
+ if (!(bp->port.supported[cfg_idx] &
+ SUPPORTED_100baseT_Full)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "100M full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_100baseT_Full |
+ ADVERTISED_TP);
+ } else {
+ if (!(bp->port.supported[cfg_idx] &
+ SUPPORTED_100baseT_Half)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "100M half not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_100baseT_Half |
+ ADVERTISED_TP);
+ }
+ break;
+
+ case SPEED_1000:
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "1G half not supported\n");
+ return -EINVAL;
+ }
+
+ if (!(bp->port.supported[cfg_idx] &
+ SUPPORTED_1000baseT_Full)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "1G full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_1000baseT_Full |
+ ADVERTISED_TP);
+ break;
+
+ case SPEED_2500:
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "2.5G half not supported\n");
+ return -EINVAL;
+ }
+
+ if (!(bp->port.supported[cfg_idx]
+ & SUPPORTED_2500baseX_Full)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "2.5G full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_2500baseX_Full |
+ ADVERTISED_TP);
+ break;
+
+ case SPEED_10000:
+ if (cmd->duplex != DUPLEX_FULL) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "10G half not supported\n");
+ return -EINVAL;
+ }
+ phy_idx = bnx2x_get_cur_phy_idx(bp);
+ if (!(bp->port.supported[cfg_idx]
+ & SUPPORTED_10000baseT_Full) ||
+ (bp->link_params.phy[phy_idx].media_type ==
+ ETH_PHY_SFP_1G_FIBER)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "10G full not supported\n");
+ return -EINVAL;
+ }
+
+ advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ break;
+
+ default:
+ DP(BNX2X_MSG_ETHTOOL, "Unsupported speed %u\n", speed);
+ return -EINVAL;
+ }
+
+ bp->link_params.req_line_speed[cfg_idx] = speed;
+ bp->link_params.req_duplex[cfg_idx] = cmd->duplex;
+ bp->port.advertising[cfg_idx] = advertising;
+ }
+
+ DP(BNX2X_MSG_ETHTOOL, "req_line_speed %d\n"
+ " req_duplex %d advertising 0x%x\n",
+ bp->link_params.req_line_speed[cfg_idx],
+ bp->link_params.req_duplex[cfg_idx],
+ bp->port.advertising[cfg_idx]);
+
+ /* Set new config */
+ bp->link_params.multi_phy_config = new_multi_phy_config;
+ if (netif_running(dev)) {
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_link_set(bp);
+ }
+
+ return 0;
+}
+
+#define DUMP_ALL_PRESETS 0x1FFF
+#define DUMP_MAX_PRESETS 13
+
+static int __bnx2x_get_preset_regs_len(struct bnx2x *bp, u32 preset)
+{
+ if (CHIP_IS_E1(bp))
+ return dump_num_registers[0][preset-1];
+ else if (CHIP_IS_E1H(bp))
+ return dump_num_registers[1][preset-1];
+ else if (CHIP_IS_E2(bp))
+ return dump_num_registers[2][preset-1];
+ else if (CHIP_IS_E3A0(bp))
+ return dump_num_registers[3][preset-1];
+ else if (CHIP_IS_E3B0(bp))
+ return dump_num_registers[4][preset-1];
+ else
+ return 0;
+}
+
+static int __bnx2x_get_regs_len(struct bnx2x *bp)
+{
+ u32 preset_idx;
+ int regdump_len = 0;
+
+ /* Calculate the total preset regs length */
+ for (preset_idx = 1; preset_idx <= DUMP_MAX_PRESETS; preset_idx++)
+ regdump_len += __bnx2x_get_preset_regs_len(bp, preset_idx);
+
+ return regdump_len;
+}
+
+static int bnx2x_get_regs_len(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int regdump_len = 0;
+
+ if (IS_VF(bp))
+ return 0;
+
+ regdump_len = __bnx2x_get_regs_len(bp);
+ regdump_len *= 4;
+ regdump_len += sizeof(struct dump_header);
+
+ return regdump_len;
+}
+
+#define IS_E1_REG(chips) ((chips & DUMP_CHIP_E1) == DUMP_CHIP_E1)
+#define IS_E1H_REG(chips) ((chips & DUMP_CHIP_E1H) == DUMP_CHIP_E1H)
+#define IS_E2_REG(chips) ((chips & DUMP_CHIP_E2) == DUMP_CHIP_E2)
+#define IS_E3A0_REG(chips) ((chips & DUMP_CHIP_E3A0) == DUMP_CHIP_E3A0)
+#define IS_E3B0_REG(chips) ((chips & DUMP_CHIP_E3B0) == DUMP_CHIP_E3B0)
+
+#define IS_REG_IN_PRESET(presets, idx) \
+ ((presets & (1 << (idx-1))) == (1 << (idx-1)))
+
+/******* Paged registers info selectors ********/
+static const u32 *__bnx2x_get_page_addr_ar(struct bnx2x *bp)
+{
+ if (CHIP_IS_E2(bp))
+ return page_vals_e2;
+ else if (CHIP_IS_E3(bp))
+ return page_vals_e3;
+ else
+ return NULL;
+}
+
+static u32 __bnx2x_get_page_reg_num(struct bnx2x *bp)
+{
+ if (CHIP_IS_E2(bp))
+ return PAGE_MODE_VALUES_E2;
+ else if (CHIP_IS_E3(bp))
+ return PAGE_MODE_VALUES_E3;
+ else
+ return 0;
+}
+
+static const u32 *__bnx2x_get_page_write_ar(struct bnx2x *bp)
+{
+ if (CHIP_IS_E2(bp))
+ return page_write_regs_e2;
+ else if (CHIP_IS_E3(bp))
+ return page_write_regs_e3;
+ else
+ return NULL;
+}
+
+static u32 __bnx2x_get_page_write_num(struct bnx2x *bp)
+{
+ if (CHIP_IS_E2(bp))
+ return PAGE_WRITE_REGS_E2;
+ else if (CHIP_IS_E3(bp))
+ return PAGE_WRITE_REGS_E3;
+ else
+ return 0;
+}
+
+static const struct reg_addr *__bnx2x_get_page_read_ar(struct bnx2x *bp)
+{
+ if (CHIP_IS_E2(bp))
+ return page_read_regs_e2;
+ else if (CHIP_IS_E3(bp))
+ return page_read_regs_e3;
+ else
+ return NULL;
+}
+
+static u32 __bnx2x_get_page_read_num(struct bnx2x *bp)
+{
+ if (CHIP_IS_E2(bp))
+ return PAGE_READ_REGS_E2;
+ else if (CHIP_IS_E3(bp))
+ return PAGE_READ_REGS_E3;
+ else
+ return 0;
+}
+
+static bool bnx2x_is_reg_in_chip(struct bnx2x *bp,
+ const struct reg_addr *reg_info)
+{
+ if (CHIP_IS_E1(bp))
+ return IS_E1_REG(reg_info->chips);
+ else if (CHIP_IS_E1H(bp))
+ return IS_E1H_REG(reg_info->chips);
+ else if (CHIP_IS_E2(bp))
+ return IS_E2_REG(reg_info->chips);
+ else if (CHIP_IS_E3A0(bp))
+ return IS_E3A0_REG(reg_info->chips);
+ else if (CHIP_IS_E3B0(bp))
+ return IS_E3B0_REG(reg_info->chips);
+ else
+ return false;
+}
+
+static bool bnx2x_is_wreg_in_chip(struct bnx2x *bp,
+ const struct wreg_addr *wreg_info)
+{
+ if (CHIP_IS_E1(bp))
+ return IS_E1_REG(wreg_info->chips);
+ else if (CHIP_IS_E1H(bp))
+ return IS_E1H_REG(wreg_info->chips);
+ else if (CHIP_IS_E2(bp))
+ return IS_E2_REG(wreg_info->chips);
+ else if (CHIP_IS_E3A0(bp))
+ return IS_E3A0_REG(wreg_info->chips);
+ else if (CHIP_IS_E3B0(bp))
+ return IS_E3B0_REG(wreg_info->chips);
+ else
+ return false;
+}
+
+/**
+ * bnx2x_read_pages_regs - read "paged" registers
+ *
+ * @bp device handle
+ * @p output buffer
+ *
+ * Reads "paged" memories: memories that may only be read by first writing to a
+ * specific address ("write address") and then reading from a specific address
+ * ("read address"). There may be more than one write address per "page" and
+ * more than one read address per write address.
+ */
+static void bnx2x_read_pages_regs(struct bnx2x *bp, u32 *p, u32 preset)
+{
+ u32 i, j, k, n;
+
+ /* addresses of the paged registers */
+ const u32 *page_addr = __bnx2x_get_page_addr_ar(bp);
+ /* number of paged registers */
+ int num_pages = __bnx2x_get_page_reg_num(bp);
+ /* write addresses */
+ const u32 *write_addr = __bnx2x_get_page_write_ar(bp);
+ /* number of write addresses */
+ int write_num = __bnx2x_get_page_write_num(bp);
+ /* read addresses info */
+ const struct reg_addr *read_addr = __bnx2x_get_page_read_ar(bp);
+ /* number of read addresses */
+ int read_num = __bnx2x_get_page_read_num(bp);
+ u32 addr, size;
+
+ for (i = 0; i < num_pages; i++) {
+ for (j = 0; j < write_num; j++) {
+ REG_WR(bp, write_addr[j], page_addr[i]);
+
+ for (k = 0; k < read_num; k++) {
+ if (IS_REG_IN_PRESET(read_addr[k].presets,
+ preset)) {
+ size = read_addr[k].size;
+ for (n = 0; n < size; n++) {
+ addr = read_addr[k].addr + n*4;
+ *p++ = REG_RD(bp, addr);
+ }
+ }
+ }
+ }
+ }
+}
+
+static int __bnx2x_get_preset_regs(struct bnx2x *bp, u32 *p, u32 preset)
+{
+ u32 i, j, addr;
+ const struct wreg_addr *wreg_addr_p = NULL;
+
+ if (CHIP_IS_E1(bp))
+ wreg_addr_p = &wreg_addr_e1;
+ else if (CHIP_IS_E1H(bp))
+ wreg_addr_p = &wreg_addr_e1h;
+ else if (CHIP_IS_E2(bp))
+ wreg_addr_p = &wreg_addr_e2;
+ else if (CHIP_IS_E3A0(bp))
+ wreg_addr_p = &wreg_addr_e3;
+ else if (CHIP_IS_E3B0(bp))
+ wreg_addr_p = &wreg_addr_e3b0;
+
+ /* Read the idle_chk registers */
+ for (i = 0; i < IDLE_REGS_COUNT; i++) {
+ if (bnx2x_is_reg_in_chip(bp, &idle_reg_addrs[i]) &&
+ IS_REG_IN_PRESET(idle_reg_addrs[i].presets, preset)) {
+ for (j = 0; j < idle_reg_addrs[i].size; j++)
+ *p++ = REG_RD(bp, idle_reg_addrs[i].addr + j*4);
+ }
+ }
+
+ /* Read the regular registers */
+ for (i = 0; i < REGS_COUNT; i++) {
+ if (bnx2x_is_reg_in_chip(bp, &reg_addrs[i]) &&
+ IS_REG_IN_PRESET(reg_addrs[i].presets, preset)) {
+ for (j = 0; j < reg_addrs[i].size; j++)
+ *p++ = REG_RD(bp, reg_addrs[i].addr + j*4);
+ }
+ }
+
+ /* Read the CAM registers */
+ if (bnx2x_is_wreg_in_chip(bp, wreg_addr_p) &&
+ IS_REG_IN_PRESET(wreg_addr_p->presets, preset)) {
+ for (i = 0; i < wreg_addr_p->size; i++) {
+ *p++ = REG_RD(bp, wreg_addr_p->addr + i*4);
+
+ /* In case of wreg_addr register, read additional
+ registers from read_regs array
+ */
+ for (j = 0; j < wreg_addr_p->read_regs_count; j++) {
+ addr = *(wreg_addr_p->read_regs);
+ *p++ = REG_RD(bp, addr + j*4);
+ }
+ }
+ }
+
+ /* Paged registers are supported in E2 & E3 only */
+ if (CHIP_IS_E2(bp) || CHIP_IS_E3(bp)) {
+ /* Read "paged" registers */
+ bnx2x_read_pages_regs(bp, p, preset);
+ }
+
+ return 0;
+}
+
+static void __bnx2x_get_regs(struct bnx2x *bp, u32 *p)
+{
+ u32 preset_idx;
+
+ /* Read all registers, by reading all preset registers */
+ for (preset_idx = 1; preset_idx <= DUMP_MAX_PRESETS; preset_idx++) {
+ /* Skip presets with IOR */
+ if ((preset_idx == 2) ||
+ (preset_idx == 5) ||
+ (preset_idx == 8) ||
+ (preset_idx == 11))
+ continue;
+ __bnx2x_get_preset_regs(bp, p, preset_idx);
+ p += __bnx2x_get_preset_regs_len(bp, preset_idx);
+ }
+}
+
+static void bnx2x_get_regs(struct net_device *dev,
+ struct ethtool_regs *regs, void *_p)
+{
+ u32 *p = _p;
+ struct bnx2x *bp = netdev_priv(dev);
+ struct dump_header dump_hdr = {0};
+
+ regs->version = 2;
+ memset(p, 0, regs->len);
+
+ if (!netif_running(bp->dev))
+ return;
+
+ /* Disable parity attentions as long as following dump may
+ * cause false alarms by reading never written registers. We
+ * will re-enable parity attentions right after the dump.
+ */
+
+ bnx2x_disable_blocks_parity(bp);
+
+ dump_hdr.header_size = (sizeof(struct dump_header) / 4) - 1;
+ dump_hdr.preset = DUMP_ALL_PRESETS;
+ dump_hdr.version = BNX2X_DUMP_VERSION;
+
+ /* dump_meta_data presents OR of CHIP and PATH. */
+ if (CHIP_IS_E1(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E1;
+ } else if (CHIP_IS_E1H(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E1H;
+ } else if (CHIP_IS_E2(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E2 |
+ (BP_PATH(bp) ? DUMP_PATH_1 : DUMP_PATH_0);
+ } else if (CHIP_IS_E3A0(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E3A0 |
+ (BP_PATH(bp) ? DUMP_PATH_1 : DUMP_PATH_0);
+ } else if (CHIP_IS_E3B0(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E3B0 |
+ (BP_PATH(bp) ? DUMP_PATH_1 : DUMP_PATH_0);
+ }
+
+ memcpy(p, &dump_hdr, sizeof(struct dump_header));
+ p += dump_hdr.header_size + 1;
+
+ /* Actually read the registers */
+ __bnx2x_get_regs(bp, p);
+
+ /* Re-enable parity attentions */
+ bnx2x_clear_blocks_parity(bp);
+ bnx2x_enable_blocks_parity(bp);
+}
+
+static int bnx2x_get_preset_regs_len(struct net_device *dev, u32 preset)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int regdump_len = 0;
+
+ regdump_len = __bnx2x_get_preset_regs_len(bp, preset);
+ regdump_len *= 4;
+ regdump_len += sizeof(struct dump_header);
+
+ return regdump_len;
+}
+
+static int bnx2x_set_dump(struct net_device *dev, struct ethtool_dump *val)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ /* Use the ethtool_dump "flag" field as the dump preset index */
+ if (val->flag < 1 || val->flag > DUMP_MAX_PRESETS)
+ return -EINVAL;
+
+ bp->dump_preset_idx = val->flag;
+ return 0;
+}
+
+static int bnx2x_get_dump_flag(struct net_device *dev,
+ struct ethtool_dump *dump)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ dump->version = BNX2X_DUMP_VERSION;
+ dump->flag = bp->dump_preset_idx;
+ /* Calculate the requested preset idx length */
+ dump->len = bnx2x_get_preset_regs_len(dev, bp->dump_preset_idx);
+ DP(BNX2X_MSG_ETHTOOL, "Get dump preset %d length=%d\n",
+ bp->dump_preset_idx, dump->len);
+ return 0;
+}
+
+static int bnx2x_get_dump_data(struct net_device *dev,
+ struct ethtool_dump *dump,
+ void *buffer)
+{
+ u32 *p = buffer;
+ struct bnx2x *bp = netdev_priv(dev);
+ struct dump_header dump_hdr = {0};
+
+ /* Disable parity attentions as long as following dump may
+ * cause false alarms by reading never written registers. We
+ * will re-enable parity attentions right after the dump.
+ */
+
+ bnx2x_disable_blocks_parity(bp);
+
+ dump_hdr.header_size = (sizeof(struct dump_header) / 4) - 1;
+ dump_hdr.preset = bp->dump_preset_idx;
+ dump_hdr.version = BNX2X_DUMP_VERSION;
+
+ DP(BNX2X_MSG_ETHTOOL, "Get dump data of preset %d\n", dump_hdr.preset);
+
+ /* dump_meta_data presents OR of CHIP and PATH. */
+ if (CHIP_IS_E1(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E1;
+ } else if (CHIP_IS_E1H(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E1H;
+ } else if (CHIP_IS_E2(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E2 |
+ (BP_PATH(bp) ? DUMP_PATH_1 : DUMP_PATH_0);
+ } else if (CHIP_IS_E3A0(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E3A0 |
+ (BP_PATH(bp) ? DUMP_PATH_1 : DUMP_PATH_0);
+ } else if (CHIP_IS_E3B0(bp)) {
+ dump_hdr.dump_meta_data = DUMP_CHIP_E3B0 |
+ (BP_PATH(bp) ? DUMP_PATH_1 : DUMP_PATH_0);
+ }
+
+ memcpy(p, &dump_hdr, sizeof(struct dump_header));
+ p += dump_hdr.header_size + 1;
+
+ /* Actually read the registers */
+ __bnx2x_get_preset_regs(bp, p, dump_hdr.preset);
+
+ /* Re-enable parity attentions */
+ bnx2x_clear_blocks_parity(bp);
+ bnx2x_enable_blocks_parity(bp);
+
+ return 0;
+}
+
+static void bnx2x_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
+
+ bnx2x_fill_fw_str(bp, info->fw_version, sizeof(info->fw_version));
+
+ strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
+ info->n_stats = BNX2X_NUM_STATS;
+ info->testinfo_len = BNX2X_NUM_TESTS(bp);
+ info->eedump_len = bp->common.flash_size;
+ info->regdump_len = bnx2x_get_regs_len(dev);
+}
+
+static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (bp->flags & NO_WOL_FLAG) {
+ wol->supported = 0;
+ wol->wolopts = 0;
+ } else {
+ wol->supported = WAKE_MAGIC;
+ if (bp->wol)
+ wol->wolopts = WAKE_MAGIC;
+ else
+ wol->wolopts = 0;
+ }
+ memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (wol->wolopts & ~WAKE_MAGIC) {
+ DP(BNX2X_MSG_ETHTOOL, "WOL not supported\n");
+ return -EINVAL;
+ }
+
+ if (wol->wolopts & WAKE_MAGIC) {
+ if (bp->flags & NO_WOL_FLAG) {
+ DP(BNX2X_MSG_ETHTOOL, "WOL not supported\n");
+ return -EINVAL;
+ }
+ bp->wol = 1;
+ } else
+ bp->wol = 0;
+
+ return 0;
+}
+
+static u32 bnx2x_get_msglevel(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ return bp->msg_enable;
+}
+
+static void bnx2x_set_msglevel(struct net_device *dev, u32 level)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (capable(CAP_NET_ADMIN)) {
+ /* dump MCP trace */
+ if (IS_PF(bp) && (level & BNX2X_MSG_MCP))
+ bnx2x_fw_dump_lvl(bp, KERN_INFO);
+ bp->msg_enable = level;
+ }
+}
+
+static int bnx2x_nway_reset(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (!bp->port.pmf)
+ return 0;
+
+ if (netif_running(dev)) {
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_force_link_reset(bp);
+ bnx2x_link_set(bp);
+ }
+
+ return 0;
+}
+
+static u32 bnx2x_get_link(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN))
+ return 0;
+
+ return bp->link_vars.link_up;
+}
+
+static int bnx2x_get_eeprom_len(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ return bp->common.flash_size;
+}
+
+/* Per pf misc lock must be acquired before the per port mcp lock. Otherwise,
+ * had we done things the other way around, if two pfs from the same port would
+ * attempt to access nvram at the same time, we could run into a scenario such
+ * as:
+ * pf A takes the port lock.
+ * pf B succeeds in taking the same lock since they are from the same port.
+ * pf A takes the per pf misc lock. Performs eeprom access.
+ * pf A finishes. Unlocks the per pf misc lock.
+ * Pf B takes the lock and proceeds to perform it's own access.
+ * pf A unlocks the per port lock, while pf B is still working (!).
+ * mcp takes the per port lock and corrupts pf B's access (and/or has it's own
+ * access corrupted by pf B)
+ */
+static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int count, i;
+ u32 val;
+
+ /* acquire HW lock: protect against other PFs in PF Direct Assignment */
+ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM);
+
+ /* adjust timeout for emulation/FPGA */
+ count = BNX2X_NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* request access to nvram interface */
+ REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
+ (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port));
+
+ for (i = 0; i < count*10; i++) {
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
+ if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))
+ break;
+
+ udelay(5);
+ }
+
+ if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot get access to nvram interface\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int bnx2x_release_nvram_lock(struct bnx2x *bp)
+{
+ int port = BP_PORT(bp);
+ int count, i;
+ u32 val;
+
+ /* adjust timeout for emulation/FPGA */
+ count = BNX2X_NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* relinquish nvram interface */
+ REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
+ (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port));
+
+ for (i = 0; i < count*10; i++) {
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
+ if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)))
+ break;
+
+ udelay(5);
+ }
+
+ if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot free access to nvram interface\n");
+ return -EBUSY;
+ }
+
+ /* release HW lock: protect against other PFs in PF Direct Assignment */
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM);
+ return 0;
+}
+
+static void bnx2x_enable_nvram_access(struct bnx2x *bp)
+{
+ u32 val;
+
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
+
+ /* enable both bits, even on read */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
+ (val | MCPR_NVM_ACCESS_ENABLE_EN |
+ MCPR_NVM_ACCESS_ENABLE_WR_EN));
+}
+
+static void bnx2x_disable_nvram_access(struct bnx2x *bp)
+{
+ u32 val;
+
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
+
+ /* disable both bits, even after read */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
+ (val & ~(MCPR_NVM_ACCESS_ENABLE_EN |
+ MCPR_NVM_ACCESS_ENABLE_WR_EN)));
+}
+
+static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
+ u32 cmd_flags)
+{
+ int count, i, rc;
+ u32 val;
+
+ /* build the command word */
+ cmd_flags |= MCPR_NVM_COMMAND_DOIT;
+
+ /* need to clear DONE bit separately */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
+
+ /* address of the NVRAM to read from */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
+ (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
+
+ /* issue a read command */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
+
+ /* adjust timeout for emulation/FPGA */
+ count = BNX2X_NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* wait for completion */
+ *ret_val = 0;
+ rc = -EBUSY;
+ for (i = 0; i < count; i++) {
+ udelay(5);
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
+
+ if (val & MCPR_NVM_COMMAND_DONE) {
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_READ);
+ /* we read nvram data in cpu order
+ * but ethtool sees it as an array of bytes
+ * converting to big-endian will do the work
+ */
+ *ret_val = cpu_to_be32(val);
+ rc = 0;
+ break;
+ }
+ }
+ if (rc == -EBUSY)
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "nvram read timeout expired\n");
+ return rc;
+}
+
+static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
+ int buf_size)
+{
+ int rc;
+ u32 cmd_flags;
+ __be32 val;
+
+ if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
+ offset, buf_size);
+ return -EINVAL;
+ }
+
+ if (offset + buf_size > bp->common.flash_size) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "Invalid parameter: offset (0x%x) + buf_size (0x%x) > flash_size (0x%x)\n",
+ offset, buf_size, bp->common.flash_size);
+ return -EINVAL;
+ }
+
+ /* request access to nvram interface */
+ rc = bnx2x_acquire_nvram_lock(bp);
+ if (rc)
+ return rc;
+
+ /* enable access to nvram interface */
+ bnx2x_enable_nvram_access(bp);
+
+ /* read the first word(s) */
+ cmd_flags = MCPR_NVM_COMMAND_FIRST;
+ while ((buf_size > sizeof(u32)) && (rc == 0)) {
+ rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
+ memcpy(ret_buf, &val, 4);
+
+ /* advance to the next dword */
+ offset += sizeof(u32);
+ ret_buf += sizeof(u32);
+ buf_size -= sizeof(u32);
+ cmd_flags = 0;
+ }
+
+ if (rc == 0) {
+ cmd_flags |= MCPR_NVM_COMMAND_LAST;
+ rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
+ memcpy(ret_buf, &val, 4);
+ }
+
+ /* disable access to nvram interface */
+ bnx2x_disable_nvram_access(bp);
+ bnx2x_release_nvram_lock(bp);
+
+ return rc;
+}
+
+static int bnx2x_nvram_read32(struct bnx2x *bp, u32 offset, u32 *buf,
+ int buf_size)
+{
+ int rc;
+
+ rc = bnx2x_nvram_read(bp, offset, (u8 *)buf, buf_size);
+
+ if (!rc) {
+ __be32 *be = (__be32 *)buf;
+
+ while ((buf_size -= 4) >= 0)
+ *buf++ = be32_to_cpu(*be++);
+ }
+
+ return rc;
+}
+
+static bool bnx2x_is_nvm_accessible(struct bnx2x *bp)
+{
+ int rc = 1;
+ u16 pm = 0;
+ struct net_device *dev = pci_get_drvdata(bp->pdev);
+
+ if (bp->pdev->pm_cap)
+ rc = pci_read_config_word(bp->pdev,
+ bp->pdev->pm_cap + PCI_PM_CTRL, &pm);
+
+ if ((rc && !netif_running(dev)) ||
+ (!rc && ((pm & PCI_PM_CTRL_STATE_MASK) != (__force u16)PCI_D0)))
+ return false;
+
+ return true;
+}
+
+static int bnx2x_get_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *eebuf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (!bnx2x_is_nvm_accessible(bp)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return -EAGAIN;
+ }
+
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
+ " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
+ eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
+ eeprom->len, eeprom->len);
+
+ /* parameters already validated in ethtool_get_eeprom */
+
+ return bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
+}
+
+static int bnx2x_get_module_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *ee,
+ u8 *data)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int rc = -EINVAL, phy_idx;
+ u8 *user_data = data;
+ unsigned int start_addr = ee->offset, xfer_size = 0;
+
+ if (!bnx2x_is_nvm_accessible(bp)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return -EAGAIN;
+ }
+
+ phy_idx = bnx2x_get_cur_phy_idx(bp);
+
+ /* Read A0 section */
+ if (start_addr < ETH_MODULE_SFF_8079_LEN) {
+ /* Limit transfer size to the A0 section boundary */
+ if (start_addr + ee->len > ETH_MODULE_SFF_8079_LEN)
+ xfer_size = ETH_MODULE_SFF_8079_LEN - start_addr;
+ else
+ xfer_size = ee->len;
+ bnx2x_acquire_phy_lock(bp);
+ rc = bnx2x_read_sfp_module_eeprom(&bp->link_params.phy[phy_idx],
+ &bp->link_params,
+ I2C_DEV_ADDR_A0,
+ start_addr,
+ xfer_size,
+ user_data);
+ bnx2x_release_phy_lock(bp);
+ if (rc) {
+ DP(BNX2X_MSG_ETHTOOL, "Failed reading A0 section\n");
+
+ return -EINVAL;
+ }
+ user_data += xfer_size;
+ start_addr += xfer_size;
+ }
+
+ /* Read A2 section */
+ if ((start_addr >= ETH_MODULE_SFF_8079_LEN) &&
+ (start_addr < ETH_MODULE_SFF_8472_LEN)) {
+ xfer_size = ee->len - xfer_size;
+ /* Limit transfer size to the A2 section boundary */
+ if (start_addr + xfer_size > ETH_MODULE_SFF_8472_LEN)
+ xfer_size = ETH_MODULE_SFF_8472_LEN - start_addr;
+ start_addr -= ETH_MODULE_SFF_8079_LEN;
+ bnx2x_acquire_phy_lock(bp);
+ rc = bnx2x_read_sfp_module_eeprom(&bp->link_params.phy[phy_idx],
+ &bp->link_params,
+ I2C_DEV_ADDR_A2,
+ start_addr,
+ xfer_size,
+ user_data);
+ bnx2x_release_phy_lock(bp);
+ if (rc) {
+ DP(BNX2X_MSG_ETHTOOL, "Failed reading A2 section\n");
+ return -EINVAL;
+ }
+ }
+ return rc;
+}
+
+static int bnx2x_get_module_info(struct net_device *dev,
+ struct ethtool_modinfo *modinfo)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int phy_idx, rc;
+ u8 sff8472_comp, diag_type;
+
+ if (!bnx2x_is_nvm_accessible(bp)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return -EAGAIN;
+ }
+ phy_idx = bnx2x_get_cur_phy_idx(bp);
+ bnx2x_acquire_phy_lock(bp);
+ rc = bnx2x_read_sfp_module_eeprom(&bp->link_params.phy[phy_idx],
+ &bp->link_params,
+ I2C_DEV_ADDR_A0,
+ SFP_EEPROM_SFF_8472_COMP_ADDR,
+ SFP_EEPROM_SFF_8472_COMP_SIZE,
+ &sff8472_comp);
+ bnx2x_release_phy_lock(bp);
+ if (rc) {
+ DP(BNX2X_MSG_ETHTOOL, "Failed reading SFF-8472 comp field\n");
+ return -EINVAL;
+ }
+
+ bnx2x_acquire_phy_lock(bp);
+ rc = bnx2x_read_sfp_module_eeprom(&bp->link_params.phy[phy_idx],
+ &bp->link_params,
+ I2C_DEV_ADDR_A0,
+ SFP_EEPROM_DIAG_TYPE_ADDR,
+ SFP_EEPROM_DIAG_TYPE_SIZE,
+ &diag_type);
+ bnx2x_release_phy_lock(bp);
+ if (rc) {
+ DP(BNX2X_MSG_ETHTOOL, "Failed reading Diag Type field\n");
+ return -EINVAL;
+ }
+
+ if (!sff8472_comp ||
+ (diag_type & SFP_EEPROM_DIAG_ADDR_CHANGE_REQ)) {
+ modinfo->type = ETH_MODULE_SFF_8079;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
+ } else {
+ modinfo->type = ETH_MODULE_SFF_8472;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+ }
+ return 0;
+}
+
+static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
+ u32 cmd_flags)
+{
+ int count, i, rc;
+
+ /* build the command word */
+ cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
+
+ /* need to clear DONE bit separately */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
+
+ /* write the data */
+ REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val);
+
+ /* address of the NVRAM to write to */
+ REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
+ (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
+
+ /* issue the write command */
+ REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
+
+ /* adjust timeout for emulation/FPGA */
+ count = BNX2X_NVRAM_TIMEOUT_COUNT;
+ if (CHIP_REV_IS_SLOW(bp))
+ count *= 100;
+
+ /* wait for completion */
+ rc = -EBUSY;
+ for (i = 0; i < count; i++) {
+ udelay(5);
+ val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
+ if (val & MCPR_NVM_COMMAND_DONE) {
+ rc = 0;
+ break;
+ }
+ }
+
+ if (rc == -EBUSY)
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "nvram write timeout expired\n");
+ return rc;
+}
+
+#define BYTE_OFFSET(offset) (8 * (offset & 0x03))
+
+static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
+ int buf_size)
+{
+ int rc;
+ u32 cmd_flags, align_offset, val;
+ __be32 val_be;
+
+ if (offset + buf_size > bp->common.flash_size) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "Invalid parameter: offset (0x%x) + buf_size (0x%x) > flash_size (0x%x)\n",
+ offset, buf_size, bp->common.flash_size);
+ return -EINVAL;
+ }
+
+ /* request access to nvram interface */
+ rc = bnx2x_acquire_nvram_lock(bp);
+ if (rc)
+ return rc;
+
+ /* enable access to nvram interface */
+ bnx2x_enable_nvram_access(bp);
+
+ cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST);
+ align_offset = (offset & ~0x03);
+ rc = bnx2x_nvram_read_dword(bp, align_offset, &val_be, cmd_flags);
+
+ if (rc == 0) {
+ /* nvram data is returned as an array of bytes
+ * convert it back to cpu order
+ */
+ val = be32_to_cpu(val_be);
+
+ val &= ~le32_to_cpu((__force __le32)
+ (0xff << BYTE_OFFSET(offset)));
+ val |= le32_to_cpu((__force __le32)
+ (*data_buf << BYTE_OFFSET(offset)));
+
+ rc = bnx2x_nvram_write_dword(bp, align_offset, val,
+ cmd_flags);
+ }
+
+ /* disable access to nvram interface */
+ bnx2x_disable_nvram_access(bp);
+ bnx2x_release_nvram_lock(bp);
+
+ return rc;
+}
+
+static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
+ int buf_size)
+{
+ int rc;
+ u32 cmd_flags;
+ u32 val;
+ u32 written_so_far;
+
+ if (buf_size == 1) /* ethtool */
+ return bnx2x_nvram_write1(bp, offset, data_buf, buf_size);
+
+ if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "Invalid parameter: offset 0x%x buf_size 0x%x\n",
+ offset, buf_size);
+ return -EINVAL;
+ }
+
+ if (offset + buf_size > bp->common.flash_size) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "Invalid parameter: offset (0x%x) + buf_size (0x%x) > flash_size (0x%x)\n",
+ offset, buf_size, bp->common.flash_size);
+ return -EINVAL;
+ }
+
+ /* request access to nvram interface */
+ rc = bnx2x_acquire_nvram_lock(bp);
+ if (rc)
+ return rc;
+
+ /* enable access to nvram interface */
+ bnx2x_enable_nvram_access(bp);
+
+ written_so_far = 0;
+ cmd_flags = MCPR_NVM_COMMAND_FIRST;
+ while ((written_so_far < buf_size) && (rc == 0)) {
+ if (written_so_far == (buf_size - sizeof(u32)))
+ cmd_flags |= MCPR_NVM_COMMAND_LAST;
+ else if (((offset + 4) % BNX2X_NVRAM_PAGE_SIZE) == 0)
+ cmd_flags |= MCPR_NVM_COMMAND_LAST;
+ else if ((offset % BNX2X_NVRAM_PAGE_SIZE) == 0)
+ cmd_flags |= MCPR_NVM_COMMAND_FIRST;
+
+ memcpy(&val, data_buf, 4);
+
+ /* Notice unlike bnx2x_nvram_read_dword() this will not
+ * change val using be32_to_cpu(), which causes data to flip
+ * if the eeprom is read and then written back. This is due
+ * to tools utilizing this functionality that would break
+ * if this would be resolved.
+ */
+ rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags);
+
+ /* advance to the next dword */
+ offset += sizeof(u32);
+ data_buf += sizeof(u32);
+ written_so_far += sizeof(u32);
+ cmd_flags = 0;
+ }
+
+ /* disable access to nvram interface */
+ bnx2x_disable_nvram_access(bp);
+ bnx2x_release_nvram_lock(bp);
+
+ return rc;
+}
+
+static int bnx2x_set_eeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *eebuf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int port = BP_PORT(bp);
+ int rc = 0;
+ u32 ext_phy_config;
+
+ if (!bnx2x_is_nvm_accessible(bp)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return -EAGAIN;
+ }
+
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n"
+ " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n",
+ eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
+ eeprom->len, eeprom->len);
+
+ /* parameters already validated in ethtool_set_eeprom */
+
+ /* PHY eeprom can be accessed only by the PMF */
+ if ((eeprom->magic >= 0x50485900) && (eeprom->magic <= 0x504859FF) &&
+ !bp->port.pmf) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "wrong magic or interface is not pmf\n");
+ return -EINVAL;
+ }
+
+ ext_phy_config =
+ SHMEM_RD(bp,
+ dev_info.port_hw_config[port].external_phy_config);
+
+ if (eeprom->magic == 0x50485950) {
+ /* 'PHYP' (0x50485950): prepare phy for FW upgrade */
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+
+ bnx2x_acquire_phy_lock(bp);
+ rc |= bnx2x_link_reset(&bp->link_params,
+ &bp->link_vars, 0);
+ if (XGXS_EXT_PHY_TYPE(ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101)
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH, port);
+ bnx2x_release_phy_lock(bp);
+ bnx2x_link_report(bp);
+
+ } else if (eeprom->magic == 0x50485952) {
+ /* 'PHYR' (0x50485952): re-init link after FW upgrade */
+ if (bp->state == BNX2X_STATE_OPEN) {
+ bnx2x_acquire_phy_lock(bp);
+ rc |= bnx2x_link_reset(&bp->link_params,
+ &bp->link_vars, 1);
+
+ rc |= bnx2x_phy_init(&bp->link_params,
+ &bp->link_vars);
+ bnx2x_release_phy_lock(bp);
+ bnx2x_calc_fc_adv(bp);
+ }
+ } else if (eeprom->magic == 0x53985943) {
+ /* 'PHYC' (0x53985943): PHY FW upgrade completed */
+ if (XGXS_EXT_PHY_TYPE(ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) {
+
+ /* DSP Remove Download Mode */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_LOW, port);
+
+ bnx2x_acquire_phy_lock(bp);
+
+ bnx2x_sfx7101_sp_sw_reset(bp,
+ &bp->link_params.phy[EXT_PHY1]);
+
+ /* wait 0.5 sec to allow it to run */
+ msleep(500);
+ bnx2x_ext_phy_hw_reset(bp, port);
+ msleep(500);
+ bnx2x_release_phy_lock(bp);
+ }
+ } else
+ rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
+
+ return rc;
+}
+
+static int bnx2x_get_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *coal)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ memset(coal, 0, sizeof(struct ethtool_coalesce));
+
+ coal->rx_coalesce_usecs = bp->rx_ticks;
+ coal->tx_coalesce_usecs = bp->tx_ticks;
+
+ return 0;
+}
+
+static int bnx2x_set_coalesce(struct net_device *dev,
+ struct ethtool_coalesce *coal)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ bp->rx_ticks = (u16)coal->rx_coalesce_usecs;
+ if (bp->rx_ticks > BNX2X_MAX_COALESCE_TOUT)
+ bp->rx_ticks = BNX2X_MAX_COALESCE_TOUT;
+
+ bp->tx_ticks = (u16)coal->tx_coalesce_usecs;
+ if (bp->tx_ticks > BNX2X_MAX_COALESCE_TOUT)
+ bp->tx_ticks = BNX2X_MAX_COALESCE_TOUT;
+
+ if (netif_running(dev))
+ bnx2x_update_coalesce(bp);
+
+ return 0;
+}
+
+static void bnx2x_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ ering->rx_max_pending = MAX_RX_AVAIL;
+
+ if (bp->rx_ring_size)
+ ering->rx_pending = bp->rx_ring_size;
+ else
+ ering->rx_pending = MAX_RX_AVAIL;
+
+ ering->tx_max_pending = IS_MF_FCOE_AFEX(bp) ? 0 : MAX_TX_AVAIL;
+ ering->tx_pending = bp->tx_ring_size;
+}
+
+static int bnx2x_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ DP(BNX2X_MSG_ETHTOOL,
+ "set ring params command parameters: rx_pending = %d, tx_pending = %d\n",
+ ering->rx_pending, ering->tx_pending);
+
+ if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Handling parity error recovery. Try again later\n");
+ return -EAGAIN;
+ }
+
+ if ((ering->rx_pending > MAX_RX_AVAIL) ||
+ (ering->rx_pending < (bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+ MIN_RX_SIZE_TPA)) ||
+ (ering->tx_pending > (IS_MF_FCOE_AFEX(bp) ? 0 : MAX_TX_AVAIL)) ||
+ (ering->tx_pending <= MAX_SKB_FRAGS + 4)) {
+ DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n");
+ return -EINVAL;
+ }
+
+ bp->rx_ring_size = ering->rx_pending;
+ bp->tx_ring_size = ering->tx_pending;
+
+ return bnx2x_reload_if_running(dev);
+}
+
+static void bnx2x_get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ int cfg_reg;
+
+ epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] ==
+ BNX2X_FLOW_CTRL_AUTO);
+
+ if (!epause->autoneg)
+ cfg_reg = bp->link_params.req_flow_ctrl[cfg_idx];
+ else
+ cfg_reg = bp->link_params.req_fc_auto_adv;
+
+ epause->rx_pause = ((cfg_reg & BNX2X_FLOW_CTRL_RX) ==
+ BNX2X_FLOW_CTRL_RX);
+ epause->tx_pause = ((cfg_reg & BNX2X_FLOW_CTRL_TX) ==
+ BNX2X_FLOW_CTRL_TX);
+
+ DP(BNX2X_MSG_ETHTOOL, "ethtool_pauseparam: cmd %d\n"
+ " autoneg %d rx_pause %d tx_pause %d\n",
+ epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
+}
+
+static int bnx2x_set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ if (IS_MF(bp))
+ return 0;
+
+ DP(BNX2X_MSG_ETHTOOL, "ethtool_pauseparam: cmd %d\n"
+ " autoneg %d rx_pause %d tx_pause %d\n",
+ epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
+
+ bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO;
+
+ if (epause->rx_pause)
+ bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_RX;
+
+ if (epause->tx_pause)
+ bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_TX;
+
+ if (bp->link_params.req_flow_ctrl[cfg_idx] == BNX2X_FLOW_CTRL_AUTO)
+ bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_NONE;
+
+ if (epause->autoneg) {
+ if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) {
+ DP(BNX2X_MSG_ETHTOOL, "autoneg not supported\n");
+ return -EINVAL;
+ }
+
+ if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) {
+ bp->link_params.req_flow_ctrl[cfg_idx] =
+ BNX2X_FLOW_CTRL_AUTO;
+ }
+ bp->link_params.req_fc_auto_adv = 0;
+ if (epause->rx_pause)
+ bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX;
+
+ if (epause->tx_pause)
+ bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX;
+
+ if (!bp->link_params.req_fc_auto_adv)
+ bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_NONE;
+ }
+
+ DP(BNX2X_MSG_ETHTOOL,
+ "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl[cfg_idx]);
+
+ if (netif_running(dev)) {
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_link_set(bp);
+ }
+
+ return 0;
+}
+
+static const char bnx2x_tests_str_arr[BNX2X_NUM_TESTS_SF][ETH_GSTRING_LEN] = {
+ "register_test (offline) ",
+ "memory_test (offline) ",
+ "int_loopback_test (offline)",
+ "ext_loopback_test (offline)",
+ "nvram_test (online) ",
+ "interrupt_test (online) ",
+ "link_test (online) "
+};
+
+enum {
+ BNX2X_PRI_FLAG_ISCSI,
+ BNX2X_PRI_FLAG_FCOE,
+ BNX2X_PRI_FLAG_STORAGE,
+ BNX2X_PRI_FLAG_LEN,
+};
+
+static const char bnx2x_private_arr[BNX2X_PRI_FLAG_LEN][ETH_GSTRING_LEN] = {
+ "iSCSI offload support",
+ "FCoE offload support",
+ "Storage only interface"
+};
+
+static u32 bnx2x_eee_to_adv(u32 eee_adv)
+{
+ u32 modes = 0;
+
+ if (eee_adv & SHMEM_EEE_100M_ADV)
+ modes |= ADVERTISED_100baseT_Full;
+ if (eee_adv & SHMEM_EEE_1G_ADV)
+ modes |= ADVERTISED_1000baseT_Full;
+ if (eee_adv & SHMEM_EEE_10G_ADV)
+ modes |= ADVERTISED_10000baseT_Full;
+
+ return modes;
+}
+
+static u32 bnx2x_adv_to_eee(u32 modes, u32 shift)
+{
+ u32 eee_adv = 0;
+ if (modes & ADVERTISED_100baseT_Full)
+ eee_adv |= SHMEM_EEE_100M_ADV;
+ if (modes & ADVERTISED_1000baseT_Full)
+ eee_adv |= SHMEM_EEE_1G_ADV;
+ if (modes & ADVERTISED_10000baseT_Full)
+ eee_adv |= SHMEM_EEE_10G_ADV;
+
+ return eee_adv << shift;
+}
+
+static int bnx2x_get_eee(struct net_device *dev, struct ethtool_eee *edata)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 eee_cfg;
+
+ if (!SHMEM2_HAS(bp, eee_status[BP_PORT(bp)])) {
+ DP(BNX2X_MSG_ETHTOOL, "BC Version does not support EEE\n");
+ return -EOPNOTSUPP;
+ }
+
+ eee_cfg = bp->link_vars.eee_status;
+
+ edata->supported =
+ bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_SUPPORTED_MASK) >>
+ SHMEM_EEE_SUPPORTED_SHIFT);
+
+ edata->advertised =
+ bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_ADV_STATUS_MASK) >>
+ SHMEM_EEE_ADV_STATUS_SHIFT);
+ edata->lp_advertised =
+ bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_LP_ADV_STATUS_MASK) >>
+ SHMEM_EEE_LP_ADV_STATUS_SHIFT);
+
+ /* SHMEM value is in 16u units --> Convert to 1u units. */
+ edata->tx_lpi_timer = (eee_cfg & SHMEM_EEE_TIMER_MASK) << 4;
+
+ edata->eee_enabled = (eee_cfg & SHMEM_EEE_REQUESTED_BIT) ? 1 : 0;
+ edata->eee_active = (eee_cfg & SHMEM_EEE_ACTIVE_BIT) ? 1 : 0;
+ edata->tx_lpi_enabled = (eee_cfg & SHMEM_EEE_LPI_REQUESTED_BIT) ? 1 : 0;
+
+ return 0;
+}
+
+static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 eee_cfg;
+ u32 advertised;
+
+ if (IS_MF(bp))
+ return 0;
+
+ if (!SHMEM2_HAS(bp, eee_status[BP_PORT(bp)])) {
+ DP(BNX2X_MSG_ETHTOOL, "BC Version does not support EEE\n");
+ return -EOPNOTSUPP;
+ }
+
+ eee_cfg = bp->link_vars.eee_status;
+
+ if (!(eee_cfg & SHMEM_EEE_SUPPORTED_MASK)) {
+ DP(BNX2X_MSG_ETHTOOL, "Board does not support EEE!\n");
+ return -EOPNOTSUPP;
+ }
+
+ advertised = bnx2x_adv_to_eee(edata->advertised,
+ SHMEM_EEE_ADV_STATUS_SHIFT);
+ if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Direct manipulation of EEE advertisement is not supported\n");
+ return -EINVAL;
+ }
+
+ if (edata->tx_lpi_timer > EEE_MODE_TIMER_MASK) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Maximal Tx Lpi timer supported is %x(u)\n",
+ EEE_MODE_TIMER_MASK);
+ return -EINVAL;
+ }
+ if (edata->tx_lpi_enabled &&
+ (edata->tx_lpi_timer < EEE_MODE_NVRAM_AGGRESSIVE_TIME)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Minimal Tx Lpi timer supported is %d(u)\n",
+ EEE_MODE_NVRAM_AGGRESSIVE_TIME);
+ return -EINVAL;
+ }
+
+ /* All is well; Apply changes*/
+ if (edata->eee_enabled)
+ bp->link_params.eee_mode |= EEE_MODE_ADV_LPI;
+ else
+ bp->link_params.eee_mode &= ~EEE_MODE_ADV_LPI;
+
+ if (edata->tx_lpi_enabled)
+ bp->link_params.eee_mode |= EEE_MODE_ENABLE_LPI;
+ else
+ bp->link_params.eee_mode &= ~EEE_MODE_ENABLE_LPI;
+
+ bp->link_params.eee_mode &= ~EEE_MODE_TIMER_MASK;
+ bp->link_params.eee_mode |= (edata->tx_lpi_timer &
+ EEE_MODE_TIMER_MASK) |
+ EEE_MODE_OVERRIDE_NVRAM |
+ EEE_MODE_OUTPUT_TIME;
+
+ /* Restart link to propagate changes */
+ if (netif_running(dev)) {
+ bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+ bnx2x_force_link_reset(bp);
+ bnx2x_link_set(bp);
+ }
+
+ return 0;
+}
+
+enum {
+ BNX2X_CHIP_E1_OFST = 0,
+ BNX2X_CHIP_E1H_OFST,
+ BNX2X_CHIP_E2_OFST,
+ BNX2X_CHIP_E3_OFST,
+ BNX2X_CHIP_E3B0_OFST,
+ BNX2X_CHIP_MAX_OFST
+};
+
+#define BNX2X_CHIP_MASK_E1 (1 << BNX2X_CHIP_E1_OFST)
+#define BNX2X_CHIP_MASK_E1H (1 << BNX2X_CHIP_E1H_OFST)
+#define BNX2X_CHIP_MASK_E2 (1 << BNX2X_CHIP_E2_OFST)
+#define BNX2X_CHIP_MASK_E3 (1 << BNX2X_CHIP_E3_OFST)
+#define BNX2X_CHIP_MASK_E3B0 (1 << BNX2X_CHIP_E3B0_OFST)
+
+#define BNX2X_CHIP_MASK_ALL ((1 << BNX2X_CHIP_MAX_OFST) - 1)
+#define BNX2X_CHIP_MASK_E1X (BNX2X_CHIP_MASK_E1 | BNX2X_CHIP_MASK_E1H)
+
+static int bnx2x_test_registers(struct bnx2x *bp)
+{
+ int idx, i, rc = -ENODEV;
+ u32 wr_val = 0, hw;
+ int port = BP_PORT(bp);
+ static const struct {
+ u32 hw;
+ u32 offset0;
+ u32 offset1;
+ u32 mask;
+ } reg_tbl[] = {
+/* 0 */ { BNX2X_CHIP_MASK_ALL,
+ BRB1_REG_PAUSE_LOW_THRESHOLD_0, 4, 0x000003ff },
+ { BNX2X_CHIP_MASK_ALL,
+ DORQ_REG_DB_ADDR0, 4, 0xffffffff },
+ { BNX2X_CHIP_MASK_E1X,
+ HC_REG_AGG_INT_0, 4, 0x000003ff },
+ { BNX2X_CHIP_MASK_ALL,
+ PBF_REG_MAC_IF0_ENABLE, 4, 0x00000001 },
+ { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2 | BNX2X_CHIP_MASK_E3,
+ PBF_REG_P0_INIT_CRD, 4, 0x000007ff },
+ { BNX2X_CHIP_MASK_E3B0,
+ PBF_REG_INIT_CRD_Q0, 4, 0x000007ff },
+ { BNX2X_CHIP_MASK_ALL,
+ PRS_REG_CID_PORT_0, 4, 0x00ffffff },
+ { BNX2X_CHIP_MASK_ALL,
+ PXP2_REG_PSWRQ_CDU0_L2P, 4, 0x000fffff },
+ { BNX2X_CHIP_MASK_ALL,
+ PXP2_REG_RQ_CDU0_EFIRST_MEM_ADDR, 8, 0x0003ffff },
+ { BNX2X_CHIP_MASK_ALL,
+ PXP2_REG_PSWRQ_TM0_L2P, 4, 0x000fffff },
+/* 10 */ { BNX2X_CHIP_MASK_ALL,
+ PXP2_REG_RQ_USDM0_EFIRST_MEM_ADDR, 8, 0x0003ffff },
+ { BNX2X_CHIP_MASK_ALL,
+ PXP2_REG_PSWRQ_TSDM0_L2P, 4, 0x000fffff },
+ { BNX2X_CHIP_MASK_ALL,
+ QM_REG_CONNNUM_0, 4, 0x000fffff },
+ { BNX2X_CHIP_MASK_ALL,
+ TM_REG_LIN0_MAX_ACTIVE_CID, 4, 0x0003ffff },
+ { BNX2X_CHIP_MASK_ALL,
+ SRC_REG_KEYRSS0_0, 40, 0xffffffff },
+ { BNX2X_CHIP_MASK_ALL,
+ SRC_REG_KEYRSS0_7, 40, 0xffffffff },
+ { BNX2X_CHIP_MASK_ALL,
+ XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 },
+ { BNX2X_CHIP_MASK_ALL,
+ XCM_REG_WU_DA_CNT_CMD00, 4, 0x00000003 },
+ { BNX2X_CHIP_MASK_ALL,
+ XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 4, 0x000000ff },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_T_BIT, 4, 0x00000001 },
+/* 20 */ { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2,
+ NIG_REG_EMAC0_IN_EN, 4, 0x00000001 },
+ { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2,
+ NIG_REG_BMAC0_IN_EN, 4, 0x00000001 },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_XCM0_OUT_EN, 4, 0x00000001 },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_BRB0_OUT_EN, 4, 0x00000001 },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_XCM_MASK, 4, 0x00000007 },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_ACPI_PAT_6_LEN, 68, 0x000000ff },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_ACPI_PAT_0_CRC, 68, 0xffffffff },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_DEST_MAC_0_0, 160, 0xffffffff },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_DEST_IP_0_1, 160, 0xffffffff },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_IPV4_IPV6_0, 160, 0x00000001 },
+/* 30 */ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_DEST_UDP_0, 160, 0x0000ffff },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_DEST_TCP_0, 160, 0x0000ffff },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LLH0_VLAN_ID_0, 160, 0x00000fff },
+ { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2,
+ NIG_REG_XGXS_SERDES0_MODE_SEL, 4, 0x00000001 },
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001},
+ { BNX2X_CHIP_MASK_ALL,
+ NIG_REG_STATUS_INTERRUPT_PORT0, 4, 0x07ffffff },
+ { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2,
+ NIG_REG_XGXS0_CTRL_EXTREMOTEMDIOST, 24, 0x00000001 },
+ { BNX2X_CHIP_MASK_E1X | BNX2X_CHIP_MASK_E2,
+ NIG_REG_SERDES0_CTRL_PHY_ADDR, 16, 0x0000001f },
+
+ { BNX2X_CHIP_MASK_ALL, 0xffffffff, 0, 0x00000000 }
+ };
+
+ if (!bnx2x_is_nvm_accessible(bp)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return rc;
+ }
+
+ if (CHIP_IS_E1(bp))
+ hw = BNX2X_CHIP_MASK_E1;
+ else if (CHIP_IS_E1H(bp))
+ hw = BNX2X_CHIP_MASK_E1H;
+ else if (CHIP_IS_E2(bp))
+ hw = BNX2X_CHIP_MASK_E2;
+ else if (CHIP_IS_E3B0(bp))
+ hw = BNX2X_CHIP_MASK_E3B0;
+ else /* e3 A0 */
+ hw = BNX2X_CHIP_MASK_E3;
+
+ /* Repeat the test twice:
+ * First by writing 0x00000000, second by writing 0xffffffff
+ */
+ for (idx = 0; idx < 2; idx++) {
+
+ switch (idx) {
+ case 0:
+ wr_val = 0;
+ break;
+ case 1:
+ wr_val = 0xffffffff;
+ break;
+ }
+
+ for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
+ u32 offset, mask, save_val, val;
+ if (!(hw & reg_tbl[i].hw))
+ continue;
+
+ offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
+ mask = reg_tbl[i].mask;
+
+ save_val = REG_RD(bp, offset);
+
+ REG_WR(bp, offset, wr_val & mask);
+
+ val = REG_RD(bp, offset);
+
+ /* Restore the original register's value */
+ REG_WR(bp, offset, save_val);
+
+ /* verify value is as expected */
+ if ((val & mask) != (wr_val & mask)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "offset 0x%x: val 0x%x != 0x%x mask 0x%x\n",
+ offset, val, wr_val, mask);
+ goto test_reg_exit;
+ }
+ }
+ }
+
+ rc = 0;
+
+test_reg_exit:
+ return rc;
+}
+
+static int bnx2x_test_memory(struct bnx2x *bp)
+{
+ int i, j, rc = -ENODEV;
+ u32 val, index;
+ static const struct {
+ u32 offset;
+ int size;
+ } mem_tbl[] = {
+ { CCM_REG_XX_DESCR_TABLE, CCM_REG_XX_DESCR_TABLE_SIZE },
+ { CFC_REG_ACTIVITY_COUNTER, CFC_REG_ACTIVITY_COUNTER_SIZE },
+ { CFC_REG_LINK_LIST, CFC_REG_LINK_LIST_SIZE },
+ { DMAE_REG_CMD_MEM, DMAE_REG_CMD_MEM_SIZE },
+ { TCM_REG_XX_DESCR_TABLE, TCM_REG_XX_DESCR_TABLE_SIZE },
+ { UCM_REG_XX_DESCR_TABLE, UCM_REG_XX_DESCR_TABLE_SIZE },
+ { XCM_REG_XX_DESCR_TABLE, XCM_REG_XX_DESCR_TABLE_SIZE },
+
+ { 0xffffffff, 0 }
+ };
+
+ static const struct {
+ char *name;
+ u32 offset;
+ u32 hw_mask[BNX2X_CHIP_MAX_OFST];
+ } prty_tbl[] = {
+ { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS,
+ {0x3ffc0, 0, 0, 0} },
+ { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS,
+ {0x2, 0x2, 0, 0} },
+ { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS,
+ {0, 0, 0, 0} },
+ { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS,
+ {0x3ffc0, 0, 0, 0} },
+ { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS,
+ {0x3ffc0, 0, 0, 0} },
+ { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS,
+ {0x3ffc1, 0, 0, 0} },
+
+ { NULL, 0xffffffff, {0, 0, 0, 0} }
+ };
+
+ if (!bnx2x_is_nvm_accessible(bp)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return rc;
+ }
+
+ if (CHIP_IS_E1(bp))
+ index = BNX2X_CHIP_E1_OFST;
+ else if (CHIP_IS_E1H(bp))
+ index = BNX2X_CHIP_E1H_OFST;
+ else if (CHIP_IS_E2(bp))
+ index = BNX2X_CHIP_E2_OFST;
+ else /* e3 */
+ index = BNX2X_CHIP_E3_OFST;
+
+ /* pre-Check the parity status */
+ for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
+ val = REG_RD(bp, prty_tbl[i].offset);
+ if (val & ~(prty_tbl[i].hw_mask[index])) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "%s is 0x%x\n", prty_tbl[i].name, val);
+ goto test_mem_exit;
+ }
+ }
+
+ /* Go through all the memories */
+ for (i = 0; mem_tbl[i].offset != 0xffffffff; i++)
+ for (j = 0; j < mem_tbl[i].size; j++)
+ REG_RD(bp, mem_tbl[i].offset + j*4);
+
+ /* Check the parity status */
+ for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
+ val = REG_RD(bp, prty_tbl[i].offset);
+ if (val & ~(prty_tbl[i].hw_mask[index])) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "%s is 0x%x\n", prty_tbl[i].name, val);
+ goto test_mem_exit;
+ }
+ }
+
+ rc = 0;
+
+test_mem_exit:
+ return rc;
+}
+
+static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes)
+{
+ int cnt = 1400;
+
+ if (link_up) {
+ while (bnx2x_link_test(bp, is_serdes) && cnt--)
+ msleep(20);
+
+ if (cnt <= 0 && bnx2x_link_test(bp, is_serdes))
+ DP(BNX2X_MSG_ETHTOOL, "Timeout waiting for link up\n");
+
+ cnt = 1400;
+ while (!bp->link_vars.link_up && cnt--)
+ msleep(20);
+
+ if (cnt <= 0 && !bp->link_vars.link_up)
+ DP(BNX2X_MSG_ETHTOOL,
+ "Timeout waiting for link init\n");
+ }
+}
+
+static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
+{
+ unsigned int pkt_size, num_pkts, i;
+ struct sk_buff *skb;
+ unsigned char *packet;
+ struct bnx2x_fastpath *fp_rx = &bp->fp[0];
+ struct bnx2x_fastpath *fp_tx = &bp->fp[0];
+ struct bnx2x_fp_txdata *txdata = fp_tx->txdata_ptr[0];
+ u16 tx_start_idx, tx_idx;
+ u16 rx_start_idx, rx_idx;
+ u16 pkt_prod, bd_prod;
+ struct sw_tx_bd *tx_buf;
+ struct eth_tx_start_bd *tx_start_bd;
+ dma_addr_t mapping;
+ union eth_rx_cqe *cqe;
+ u8 cqe_fp_flags, cqe_fp_type;
+ struct sw_rx_bd *rx_buf;
+ u16 len;
+ int rc = -ENODEV;
+ u8 *data;
+ struct netdev_queue *txq = netdev_get_tx_queue(bp->dev,
+ txdata->txq_index);
+
+ /* check the loopback mode */
+ switch (loopback_mode) {
+ case BNX2X_PHY_LOOPBACK:
+ if (bp->link_params.loopback_mode != LOOPBACK_XGXS) {
+ DP(BNX2X_MSG_ETHTOOL, "PHY loopback not supported\n");
+ return -EINVAL;
+ }
+ break;
+ case BNX2X_MAC_LOOPBACK:
+ if (CHIP_IS_E3(bp)) {
+ int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+ if (bp->port.supported[cfg_idx] &
+ (SUPPORTED_10000baseT_Full |
+ SUPPORTED_20000baseMLD2_Full |
+ SUPPORTED_20000baseKR2_Full))
+ bp->link_params.loopback_mode = LOOPBACK_XMAC;
+ else
+ bp->link_params.loopback_mode = LOOPBACK_UMAC;
+ } else
+ bp->link_params.loopback_mode = LOOPBACK_BMAC;
+
+ bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+ break;
+ case BNX2X_EXT_LOOPBACK:
+ if (bp->link_params.loopback_mode != LOOPBACK_EXT) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Can't configure external loopback\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n");
+ return -EINVAL;
+ }
+
+ /* prepare the loopback packet */
+ pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
+ bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
+ skb = netdev_alloc_skb(bp->dev, fp_rx->rx_buf_size);
+ if (!skb) {
+ DP(BNX2X_MSG_ETHTOOL, "Can't allocate skb\n");
+ rc = -ENOMEM;
+ goto test_loopback_exit;
+ }
+ packet = skb_put(skb, pkt_size);
+ memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
+ memset(packet + ETH_ALEN, 0, ETH_ALEN);
+ memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN));
+ for (i = ETH_HLEN; i < pkt_size; i++)
+ packet[i] = (unsigned char) (i & 0xff);
+ mapping = dma_map_single(&bp->pdev->dev, skb->data,
+ skb_headlen(skb), DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
+ rc = -ENOMEM;
+ dev_kfree_skb(skb);
+ DP(BNX2X_MSG_ETHTOOL, "Unable to map SKB\n");
+ goto test_loopback_exit;
+ }
+
+ /* send the loopback packet */
+ num_pkts = 0;
+ tx_start_idx = le16_to_cpu(*txdata->tx_cons_sb);
+ rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
+
+ netdev_tx_sent_queue(txq, skb->len);
+
+ pkt_prod = txdata->tx_pkt_prod++;
+ tx_buf = &txdata->tx_buf_ring[TX_BD(pkt_prod)];
+ tx_buf->first_bd = txdata->tx_bd_prod;
+ tx_buf->skb = skb;
+ tx_buf->flags = 0;
+
+ bd_prod = TX_BD(txdata->tx_bd_prod);
+ tx_start_bd = &txdata->tx_desc_ring[bd_prod].start_bd;
+ tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+ tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+ tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */
+ tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+ tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod);
+ tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
+ SET_FLAG(tx_start_bd->general_data,
+ ETH_TX_START_BD_HDR_NBDS,
+ 1);
+ SET_FLAG(tx_start_bd->general_data,
+ ETH_TX_START_BD_PARSE_NBDS,
+ 0);
+
+ /* turn on parsing and get a BD */
+ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+
+ if (CHIP_IS_E1x(bp)) {
+ u16 global_data = 0;
+ struct eth_tx_parse_bd_e1x *pbd_e1x =
+ &txdata->tx_desc_ring[bd_prod].parse_bd_e1x;
+ memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
+ SET_FLAG(global_data,
+ ETH_TX_PARSE_BD_E1X_ETH_ADDR_TYPE, UNICAST_ADDRESS);
+ pbd_e1x->global_data = cpu_to_le16(global_data);
+ } else {
+ u32 parsing_data = 0;
+ struct eth_tx_parse_bd_e2 *pbd_e2 =
+ &txdata->tx_desc_ring[bd_prod].parse_bd_e2;
+ memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
+ SET_FLAG(parsing_data,
+ ETH_TX_PARSE_BD_E2_ETH_ADDR_TYPE, UNICAST_ADDRESS);
+ pbd_e2->parsing_data = cpu_to_le32(parsing_data);
+ }
+ wmb();
+
+ txdata->tx_db.data.prod += 2;
+ barrier();
+ DOORBELL(bp, txdata->cid, txdata->tx_db.raw);
+
+ mmiowb();
+ barrier();
+
+ num_pkts++;
+ txdata->tx_bd_prod += 2; /* start + pbd */
+
+ udelay(100);
+
+ tx_idx = le16_to_cpu(*txdata->tx_cons_sb);
+ if (tx_idx != tx_start_idx + num_pkts)
+ goto test_loopback_exit;
+
+ /* Unlike HC IGU won't generate an interrupt for status block
+ * updates that have been performed while interrupts were
+ * disabled.
+ */
+ if (bp->common.int_block == INT_BLOCK_IGU) {
+ /* Disable local BHes to prevent a dead-lock situation between
+ * sch_direct_xmit() and bnx2x_run_loopback() (calling
+ * bnx2x_tx_int()), as both are taking netif_tx_lock().
+ */
+ local_bh_disable();
+ bnx2x_tx_int(bp, txdata);
+ local_bh_enable();
+ }
+
+ rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
+ if (rx_idx != rx_start_idx + num_pkts)
+ goto test_loopback_exit;
+
+ cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)];
+ cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
+ cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE;
+ if (!CQE_TYPE_FAST(cqe_fp_type) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
+ goto test_loopback_rx_exit;
+
+ len = le16_to_cpu(cqe->fast_path_cqe.pkt_len_or_gro_seg_len);
+ if (len != pkt_size)
+ goto test_loopback_rx_exit;
+
+ rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)];
+ dma_sync_single_for_cpu(&bp->pdev->dev,
+ dma_unmap_addr(rx_buf, mapping),
+ fp_rx->rx_buf_size, DMA_FROM_DEVICE);
+ data = rx_buf->data + NET_SKB_PAD + cqe->fast_path_cqe.placement_offset;
+ for (i = ETH_HLEN; i < pkt_size; i++)
+ if (*(data + i) != (unsigned char) (i & 0xff))
+ goto test_loopback_rx_exit;
+
+ rc = 0;
+
+test_loopback_rx_exit:
+
+ fp_rx->rx_bd_cons = NEXT_RX_IDX(fp_rx->rx_bd_cons);
+ fp_rx->rx_bd_prod = NEXT_RX_IDX(fp_rx->rx_bd_prod);
+ fp_rx->rx_comp_cons = NEXT_RCQ_IDX(fp_rx->rx_comp_cons);
+ fp_rx->rx_comp_prod = NEXT_RCQ_IDX(fp_rx->rx_comp_prod);
+
+ /* Update producers */
+ bnx2x_update_rx_prod(bp, fp_rx, fp_rx->rx_bd_prod, fp_rx->rx_comp_prod,
+ fp_rx->rx_sge_prod);
+
+test_loopback_exit:
+ bp->link_params.loopback_mode = LOOPBACK_NONE;
+
+ return rc;
+}
+
+static int bnx2x_test_loopback(struct bnx2x *bp)
+{
+ int rc = 0, res;
+
+ if (BP_NOMCP(bp))
+ return rc;
+
+ if (!netif_running(bp->dev))
+ return BNX2X_LOOPBACK_FAILED;
+
+ bnx2x_netif_stop(bp, 1);
+ bnx2x_acquire_phy_lock(bp);
+
+ res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK);
+ if (res) {
+ DP(BNX2X_MSG_ETHTOOL, " PHY loopback failed (res %d)\n", res);
+ rc |= BNX2X_PHY_LOOPBACK_FAILED;
+ }
+
+ res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK);
+ if (res) {
+ DP(BNX2X_MSG_ETHTOOL, " MAC loopback failed (res %d)\n", res);
+ rc |= BNX2X_MAC_LOOPBACK_FAILED;
+ }
+
+ bnx2x_release_phy_lock(bp);
+ bnx2x_netif_start(bp);
+
+ return rc;
+}
+
+static int bnx2x_test_ext_loopback(struct bnx2x *bp)
+{
+ int rc;
+ u8 is_serdes =
+ (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0;
+
+ if (BP_NOMCP(bp))
+ return -ENODEV;
+
+ if (!netif_running(bp->dev))
+ return BNX2X_EXT_LOOPBACK_FAILED;
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL, false);
+ rc = bnx2x_nic_load(bp, LOAD_LOOPBACK_EXT);
+ if (rc) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Can't perform self-test, nic_load (for external lb) failed\n");
+ return -ENODEV;
+ }
+ bnx2x_wait_for_link(bp, 1, is_serdes);
+
+ bnx2x_netif_stop(bp, 1);
+
+ rc = bnx2x_run_loopback(bp, BNX2X_EXT_LOOPBACK);
+ if (rc)
+ DP(BNX2X_MSG_ETHTOOL, "EXT loopback failed (res %d)\n", rc);
+
+ bnx2x_netif_start(bp);
+
+ return rc;
+}
+
+struct code_entry {
+ u32 sram_start_addr;
+ u32 code_attribute;
+#define CODE_IMAGE_TYPE_MASK 0xf0800003
+#define CODE_IMAGE_VNTAG_PROFILES_DATA 0xd0000003
+#define CODE_IMAGE_LENGTH_MASK 0x007ffffc
+#define CODE_IMAGE_TYPE_EXTENDED_DIR 0xe0000000
+ u32 nvm_start_addr;
+};
+
+#define CODE_ENTRY_MAX 16
+#define CODE_ENTRY_EXTENDED_DIR_IDX 15
+#define MAX_IMAGES_IN_EXTENDED_DIR 64
+#define NVRAM_DIR_OFFSET 0x14
+
+#define EXTENDED_DIR_EXISTS(code) \
+ ((code & CODE_IMAGE_TYPE_MASK) == CODE_IMAGE_TYPE_EXTENDED_DIR && \
+ (code & CODE_IMAGE_LENGTH_MASK) != 0)
+
+#define CRC32_RESIDUAL 0xdebb20e3
+#define CRC_BUFF_SIZE 256
+
+static int bnx2x_nvram_crc(struct bnx2x *bp,
+ int offset,
+ int size,
+ u8 *buff)
+{
+ u32 crc = ~0;
+ int rc = 0, done = 0;
+
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "NVRAM CRC from 0x%08x to 0x%08x\n", offset, offset + size);
+
+ while (done < size) {
+ int count = min_t(int, size - done, CRC_BUFF_SIZE);
+
+ rc = bnx2x_nvram_read(bp, offset + done, buff, count);
+
+ if (rc)
+ return rc;
+
+ crc = crc32_le(crc, buff, count);
+ done += count;
+ }
+
+ if (crc != CRC32_RESIDUAL)
+ rc = -EINVAL;
+
+ return rc;
+}
+
+static int bnx2x_test_nvram_dir(struct bnx2x *bp,
+ struct code_entry *entry,
+ u8 *buff)
+{
+ size_t size = entry->code_attribute & CODE_IMAGE_LENGTH_MASK;
+ u32 type = entry->code_attribute & CODE_IMAGE_TYPE_MASK;
+ int rc;
+
+ /* Zero-length images and AFEX profiles do not have CRC */
+ if (size == 0 || type == CODE_IMAGE_VNTAG_PROFILES_DATA)
+ return 0;
+
+ rc = bnx2x_nvram_crc(bp, entry->nvm_start_addr, size, buff);
+ if (rc)
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "image %x has failed crc test (rc %d)\n", type, rc);
+
+ return rc;
+}
+
+static int bnx2x_test_dir_entry(struct bnx2x *bp, u32 addr, u8 *buff)
+{
+ int rc;
+ struct code_entry entry;
+
+ rc = bnx2x_nvram_read32(bp, addr, (u32 *)&entry, sizeof(entry));
+ if (rc)
+ return rc;
+
+ return bnx2x_test_nvram_dir(bp, &entry, buff);
+}
+
+static int bnx2x_test_nvram_ext_dirs(struct bnx2x *bp, u8 *buff)
+{
+ u32 rc, cnt, dir_offset = NVRAM_DIR_OFFSET;
+ struct code_entry entry;
+ int i;
+
+ rc = bnx2x_nvram_read32(bp,
+ dir_offset +
+ sizeof(entry) * CODE_ENTRY_EXTENDED_DIR_IDX,
+ (u32 *)&entry, sizeof(entry));
+ if (rc)
+ return rc;
+
+ if (!EXTENDED_DIR_EXISTS(entry.code_attribute))
+ return 0;
+
+ rc = bnx2x_nvram_read32(bp, entry.nvm_start_addr,
+ &cnt, sizeof(u32));
+ if (rc)
+ return rc;
+
+ dir_offset = entry.nvm_start_addr + 8;
+
+ for (i = 0; i < cnt && i < MAX_IMAGES_IN_EXTENDED_DIR; i++) {
+ rc = bnx2x_test_dir_entry(bp, dir_offset +
+ sizeof(struct code_entry) * i,
+ buff);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+static int bnx2x_test_nvram_dirs(struct bnx2x *bp, u8 *buff)
+{
+ u32 rc, dir_offset = NVRAM_DIR_OFFSET;
+ int i;
+
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "NVRAM DIRS CRC test-set\n");
+
+ for (i = 0; i < CODE_ENTRY_EXTENDED_DIR_IDX; i++) {
+ rc = bnx2x_test_dir_entry(bp, dir_offset +
+ sizeof(struct code_entry) * i,
+ buff);
+ if (rc)
+ return rc;
+ }
+
+ return bnx2x_test_nvram_ext_dirs(bp, buff);
+}
+
+struct crc_pair {
+ int offset;
+ int size;
+};
+
+static int bnx2x_test_nvram_tbl(struct bnx2x *bp,
+ const struct crc_pair *nvram_tbl, u8 *buf)
+{
+ int i;
+
+ for (i = 0; nvram_tbl[i].size; i++) {
+ int rc = bnx2x_nvram_crc(bp, nvram_tbl[i].offset,
+ nvram_tbl[i].size, buf);
+ if (rc) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "nvram_tbl[%d] has failed crc test (rc %d)\n",
+ i, rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static int bnx2x_test_nvram(struct bnx2x *bp)
+{
+ const struct crc_pair nvram_tbl[] = {
+ { 0, 0x14 }, /* bootstrap */
+ { 0x14, 0xec }, /* dir */
+ { 0x100, 0x350 }, /* manuf_info */
+ { 0x450, 0xf0 }, /* feature_info */
+ { 0x640, 0x64 }, /* upgrade_key_info */
+ { 0x708, 0x70 }, /* manuf_key_info */
+ { 0, 0 }
+ };
+ const struct crc_pair nvram_tbl2[] = {
+ { 0x7e8, 0x350 }, /* manuf_info2 */
+ { 0xb38, 0xf0 }, /* feature_info */
+ { 0, 0 }
+ };
+
+ u8 *buf;
+ int rc;
+ u32 magic;
+
+ if (BP_NOMCP(bp))
+ return 0;
+
+ buf = kmalloc(CRC_BUFF_SIZE, GFP_KERNEL);
+ if (!buf) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "kmalloc failed\n");
+ rc = -ENOMEM;
+ goto test_nvram_exit;
+ }
+
+ rc = bnx2x_nvram_read32(bp, 0, &magic, sizeof(magic));
+ if (rc) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "magic value read (rc %d)\n", rc);
+ goto test_nvram_exit;
+ }
+
+ if (magic != 0x669955aa) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "wrong magic value (0x%08x)\n", magic);
+ rc = -ENODEV;
+ goto test_nvram_exit;
+ }
+
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "Port 0 CRC test-set\n");
+ rc = bnx2x_test_nvram_tbl(bp, nvram_tbl, buf);
+ if (rc)
+ goto test_nvram_exit;
+
+ if (!CHIP_IS_E1x(bp) && !CHIP_IS_57811xx(bp)) {
+ u32 hide = SHMEM_RD(bp, dev_info.shared_hw_config.config2) &
+ SHARED_HW_CFG_HIDE_PORT1;
+
+ if (!hide) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "Port 1 CRC test-set\n");
+ rc = bnx2x_test_nvram_tbl(bp, nvram_tbl2, buf);
+ if (rc)
+ goto test_nvram_exit;
+ }
+ }
+
+ rc = bnx2x_test_nvram_dirs(bp, buf);
+
+test_nvram_exit:
+ kfree(buf);
+ return rc;
+}
+
+/* Send an EMPTY ramrod on the first queue */
+static int bnx2x_test_intr(struct bnx2x *bp)
+{
+ struct bnx2x_queue_state_params params = {NULL};
+
+ if (!netif_running(bp->dev)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return -ENODEV;
+ }
+
+ params.q_obj = &bp->sp_objs->q_obj;
+ params.cmd = BNX2X_Q_CMD_EMPTY;
+
+ __set_bit(RAMROD_COMP_WAIT, &params.ramrod_flags);
+
+ return bnx2x_queue_state_change(bp, &params);
+}
+
+static void bnx2x_self_test(struct net_device *dev,
+ struct ethtool_test *etest, u64 *buf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u8 is_serdes, link_up;
+ int rc, cnt = 0;
+
+ if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
+ netdev_err(bp->dev,
+ "Handling parity error recovery. Try again later\n");
+ etest->flags |= ETH_TEST_FL_FAILED;
+ return;
+ }
+
+ DP(BNX2X_MSG_ETHTOOL,
+ "Self-test command parameters: offline = %d, external_lb = %d\n",
+ (etest->flags & ETH_TEST_FL_OFFLINE),
+ (etest->flags & ETH_TEST_FL_EXTERNAL_LB)>>2);
+
+ memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS(bp));
+
+ if (bnx2x_test_nvram(bp) != 0) {
+ if (!IS_MF(bp))
+ buf[4] = 1;
+ else
+ buf[0] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+
+ if (!netif_running(dev)) {
+ DP(BNX2X_MSG_ETHTOOL, "Interface is down\n");
+ return;
+ }
+
+ is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0;
+ link_up = bp->link_vars.link_up;
+ /* offline tests are not supported in MF mode */
+ if ((etest->flags & ETH_TEST_FL_OFFLINE) && !IS_MF(bp)) {
+ int port = BP_PORT(bp);
+ u32 val;
+
+ /* save current value of input enable for TX port IF */
+ val = REG_RD(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4);
+ /* disable input for TX port IF */
+ REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL, false);
+ rc = bnx2x_nic_load(bp, LOAD_DIAG);
+ if (rc) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+ DP(BNX2X_MSG_ETHTOOL,
+ "Can't perform self-test, nic_load (for offline) failed\n");
+ return;
+ }
+
+ /* wait until link state is restored */
+ bnx2x_wait_for_link(bp, 1, is_serdes);
+
+ if (bnx2x_test_registers(bp) != 0) {
+ buf[0] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+ if (bnx2x_test_memory(bp) != 0) {
+ buf[1] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+
+ buf[2] = bnx2x_test_loopback(bp); /* internal LB */
+ if (buf[2] != 0)
+ etest->flags |= ETH_TEST_FL_FAILED;
+
+ if (etest->flags & ETH_TEST_FL_EXTERNAL_LB) {
+ buf[3] = bnx2x_test_ext_loopback(bp); /* external LB */
+ if (buf[3] != 0)
+ etest->flags |= ETH_TEST_FL_FAILED;
+ etest->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
+ }
+
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL, false);
+
+ /* restore input for TX port IF */
+ REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val);
+ rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+ if (rc) {
+ etest->flags |= ETH_TEST_FL_FAILED;
+ DP(BNX2X_MSG_ETHTOOL,
+ "Can't perform self-test, nic_load (for online) failed\n");
+ return;
+ }
+ /* wait until link state is restored */
+ bnx2x_wait_for_link(bp, link_up, is_serdes);
+ }
+
+ if (bnx2x_test_intr(bp) != 0) {
+ if (!IS_MF(bp))
+ buf[5] = 1;
+ else
+ buf[1] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+
+ if (link_up) {
+ cnt = 100;
+ while (bnx2x_link_test(bp, is_serdes) && --cnt)
+ msleep(20);
+ }
+
+ if (!cnt) {
+ if (!IS_MF(bp))
+ buf[6] = 1;
+ else
+ buf[2] = 1;
+ etest->flags |= ETH_TEST_FL_FAILED;
+ }
+}
+
+#define IS_PORT_STAT(i) \
+ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
+#define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
+#define HIDE_PORT_STAT(bp) \
+ ((IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) || \
+ IS_VF(bp))
+
+/* ethtool statistics are displayed for all regular ethernet queues and the
+ * fcoe L2 queue if not disabled
+ */
+static int bnx2x_num_stat_queues(struct bnx2x *bp)
+{
+ return BNX2X_NUM_ETH_QUEUES(bp);
+}
+
+static int bnx2x_get_sset_count(struct net_device *dev, int stringset)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int i, num_strings = 0;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ if (is_multi(bp)) {
+ num_strings = bnx2x_num_stat_queues(bp) *
+ BNX2X_NUM_Q_STATS;
+ } else
+ num_strings = 0;
+ if (HIDE_PORT_STAT(bp)) {
+ for (i = 0; i < BNX2X_NUM_STATS; i++)
+ if (IS_FUNC_STAT(i))
+ num_strings++;
+ } else
+ num_strings += BNX2X_NUM_STATS;
+
+ return num_strings;
+
+ case ETH_SS_TEST:
+ return BNX2X_NUM_TESTS(bp);
+
+ case ETH_SS_PRIV_FLAGS:
+ return BNX2X_PRI_FLAG_LEN;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static u32 bnx2x_get_private_flags(struct net_device *dev)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 flags = 0;
+
+ flags |= (!(bp->flags & NO_ISCSI_FLAG) ? 1 : 0) << BNX2X_PRI_FLAG_ISCSI;
+ flags |= (!(bp->flags & NO_FCOE_FLAG) ? 1 : 0) << BNX2X_PRI_FLAG_FCOE;
+ flags |= (!!IS_MF_STORAGE_ONLY(bp)) << BNX2X_PRI_FLAG_STORAGE;
+
+ return flags;
+}
+
+static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ int i, j, k, start;
+ char queue_name[MAX_QUEUE_NAME_LEN+1];
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ k = 0;
+ if (is_multi(bp)) {
+ for_each_eth_queue(bp, i) {
+ memset(queue_name, 0, sizeof(queue_name));
+ sprintf(queue_name, "%d", i);
+ for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
+ snprintf(buf + (k + j)*ETH_GSTRING_LEN,
+ ETH_GSTRING_LEN,
+ bnx2x_q_stats_arr[j].string,
+ queue_name);
+ k += BNX2X_NUM_Q_STATS;
+ }
+ }
+
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (HIDE_PORT_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ strcpy(buf + (k + j)*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[i].string);
+ j++;
+ }
+
+ break;
+
+ case ETH_SS_TEST:
+ /* First 4 tests cannot be done in MF mode */
+ if (!IS_MF(bp))
+ start = 0;
+ else
+ start = 4;
+ memcpy(buf, bnx2x_tests_str_arr + start,
+ ETH_GSTRING_LEN * BNX2X_NUM_TESTS(bp));
+ break;
+
+ case ETH_SS_PRIV_FLAGS:
+ memcpy(buf, bnx2x_private_arr,
+ ETH_GSTRING_LEN * BNX2X_PRI_FLAG_LEN);
+ break;
+ }
+}
+
+static void bnx2x_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *buf)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u32 *hw_stats, *offset;
+ int i, j, k = 0;
+
+ if (is_multi(bp)) {
+ for_each_eth_queue(bp, i) {
+ hw_stats = (u32 *)&bp->fp_stats[i].eth_q_stats;
+ for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
+ if (bnx2x_q_stats_arr[j].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ continue;
+ }
+ offset = (hw_stats +
+ bnx2x_q_stats_arr[j].offset);
+ if (bnx2x_q_stats_arr[j].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ }
+ k += BNX2X_NUM_Q_STATS;
+ }
+ }
+
+ hw_stats = (u32 *)&bp->eth_stats;
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (HIDE_PORT_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ if (bnx2x_stats_arr[i].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ j++;
+ continue;
+ }
+ offset = (hw_stats + bnx2x_stats_arr[i].offset);
+ if (bnx2x_stats_arr[i].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
+ j++;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ j++;
+ }
+}
+
+static int bnx2x_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ if (!bnx2x_is_nvm_accessible(bp)) {
+ DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
+ "cannot access eeprom when the interface is down\n");
+ return -EAGAIN;
+ }
+
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 1; /* cycle on/off once per second */
+
+ case ETHTOOL_ID_ON:
+ bnx2x_acquire_phy_lock(bp);
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_ON, SPEED_1000);
+ bnx2x_release_phy_lock(bp);
+ break;
+
+ case ETHTOOL_ID_OFF:
+ bnx2x_acquire_phy_lock(bp);
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_FRONT_PANEL_OFF, 0);
+ bnx2x_release_phy_lock(bp);
+ break;
+
+ case ETHTOOL_ID_INACTIVE:
+ bnx2x_acquire_phy_lock(bp);
+ bnx2x_set_led(&bp->link_params, &bp->link_vars,
+ LED_MODE_OPER,
+ bp->link_vars.line_speed);
+ bnx2x_release_phy_lock(bp);
+ }
+
+ return 0;
+}
+
+static int bnx2x_get_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info)
+{
+ switch (info->flow_type) {
+ case TCP_V4_FLOW:
+ case TCP_V6_FLOW:
+ info->data = RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ break;
+ case UDP_V4_FLOW:
+ if (bp->rss_conf_obj.udp_rss_v4)
+ info->data = RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ else
+ info->data = RXH_IP_SRC | RXH_IP_DST;
+ break;
+ case UDP_V6_FLOW:
+ if (bp->rss_conf_obj.udp_rss_v6)
+ info->data = RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ else
+ info->data = RXH_IP_SRC | RXH_IP_DST;
+ break;
+ case IPV4_FLOW:
+ case IPV6_FLOW:
+ info->data = RXH_IP_SRC | RXH_IP_DST;
+ break;
+ default:
+ info->data = 0;
+ break;
+ }
+
+ return 0;
+}
+
+static int bnx2x_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
+ u32 *rules __always_unused)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ switch (info->cmd) {
+ case ETHTOOL_GRXRINGS:
+ info->data = BNX2X_NUM_ETH_QUEUES(bp);
+ return 0;
+ case ETHTOOL_GRXFH:
+ return bnx2x_get_rss_flags(bp, info);
+ default:
+ DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n");
+ return -EOPNOTSUPP;
+ }
+}
+
+static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info)
+{
+ int udp_rss_requested;
+
+ DP(BNX2X_MSG_ETHTOOL,
+ "Set rss flags command parameters: flow type = %d, data = %llu\n",
+ info->flow_type, info->data);
+
+ switch (info->flow_type) {
+ case TCP_V4_FLOW:
+ case TCP_V6_FLOW:
+ /* For TCP only 4-tupple hash is supported */
+ if (info->data ^ (RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Command parameters not supported\n");
+ return -EINVAL;
+ }
+ return 0;
+
+ case UDP_V4_FLOW:
+ case UDP_V6_FLOW:
+ /* For UDP either 2-tupple hash or 4-tupple hash is supported */
+ if (info->data == (RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3))
+ udp_rss_requested = 1;
+ else if (info->data == (RXH_IP_SRC | RXH_IP_DST))
+ udp_rss_requested = 0;
+ else
+ return -EINVAL;
+ if ((info->flow_type == UDP_V4_FLOW) &&
+ (bp->rss_conf_obj.udp_rss_v4 != udp_rss_requested)) {
+ bp->rss_conf_obj.udp_rss_v4 = udp_rss_requested;
+ DP(BNX2X_MSG_ETHTOOL,
+ "rss re-configured, UDP 4-tupple %s\n",
+ udp_rss_requested ? "enabled" : "disabled");
+ return bnx2x_rss(bp, &bp->rss_conf_obj, false, true);
+ } else if ((info->flow_type == UDP_V6_FLOW) &&
+ (bp->rss_conf_obj.udp_rss_v6 != udp_rss_requested)) {
+ bp->rss_conf_obj.udp_rss_v6 = udp_rss_requested;
+ DP(BNX2X_MSG_ETHTOOL,
+ "rss re-configured, UDP 4-tupple %s\n",
+ udp_rss_requested ? "enabled" : "disabled");
+ return bnx2x_rss(bp, &bp->rss_conf_obj, false, true);
+ }
+ return 0;
+
+ case IPV4_FLOW:
+ case IPV6_FLOW:
+ /* For IP only 2-tupple hash is supported */
+ if (info->data ^ (RXH_IP_SRC | RXH_IP_DST)) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Command parameters not supported\n");
+ return -EINVAL;
+ }
+ return 0;
+
+ case SCTP_V4_FLOW:
+ case AH_ESP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ case SCTP_V6_FLOW:
+ case AH_ESP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ case IP_USER_FLOW:
+ case ETHER_FLOW:
+ /* RSS is not supported for these protocols */
+ if (info->data) {
+ DP(BNX2X_MSG_ETHTOOL,
+ "Command parameters not supported\n");
+ return -EINVAL;
+ }
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int bnx2x_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ switch (info->cmd) {
+ case ETHTOOL_SRXFH:
+ return bnx2x_set_rss_flags(bp, info);
+ default:
+ DP(BNX2X_MSG_ETHTOOL, "Command parameters not supported\n");
+ return -EOPNOTSUPP;
+ }
+}
+
+static u32 bnx2x_get_rxfh_indir_size(struct net_device *dev)
+{
+ return T_ETH_INDIRECTION_TABLE_SIZE;
+}
+
+static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0};
+ size_t i;
+
+ /* Get the current configuration of the RSS indirection table */
+ bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table);
+
+ /*
+ * We can't use a memcpy() as an internal storage of an
+ * indirection table is a u8 array while indir->ring_index
+ * points to an array of u32.
+ *
+ * Indirection table contains the FW Client IDs, so we need to
+ * align the returned table to the Client ID of the leading RSS
+ * queue.
+ */
+ for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++)
+ indir[i] = ind_table[i] - bp->fp->cl_id;
+
+ return 0;
+}
+
+static int bnx2x_set_rxfh(struct net_device *dev, const u32 *indir,
+ const u8 *key)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ size_t i;
+
+ for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) {
+ /*
+ * The same as in bnx2x_get_rxfh: we can't use a memcpy()
+ * as an internal storage of an indirection table is a u8 array
+ * while indir->ring_index points to an array of u32.
+ *
+ * Indirection table contains the FW Client IDs, so we need to
+ * align the received table to the Client ID of the leading RSS
+ * queue
+ */
+ bp->rss_conf_obj.ind_table[i] = indir[i] + bp->fp->cl_id;
+ }
+
+ return bnx2x_config_rss_eth(bp, false);
+}
+
+/**
+ * bnx2x_get_channels - gets the number of RSS queues.
+ *
+ * @dev: net device
+ * @channels: returns the number of max / current queues
+ */
+static void bnx2x_get_channels(struct net_device *dev,
+ struct ethtool_channels *channels)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ channels->max_combined = BNX2X_MAX_RSS_COUNT(bp);
+ channels->combined_count = BNX2X_NUM_ETH_QUEUES(bp);
+}
+
+/**
+ * bnx2x_change_num_queues - change the number of RSS queues.
+ *
+ * @bp: bnx2x private structure
+ *
+ * Re-configure interrupt mode to get the new number of MSI-X
+ * vectors and re-add NAPI objects.
+ */
+static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss)
+{
+ bnx2x_disable_msi(bp);
+ bp->num_ethernet_queues = num_rss;
+ bp->num_queues = bp->num_ethernet_queues + bp->num_cnic_queues;
+ BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues);
+ bnx2x_set_int_mode(bp);
+}
+
+/**
+ * bnx2x_set_channels - sets the number of RSS queues.
+ *
+ * @dev: net device
+ * @channels: includes the number of queues requested
+ */
+static int bnx2x_set_channels(struct net_device *dev,
+ struct ethtool_channels *channels)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ DP(BNX2X_MSG_ETHTOOL,
+ "set-channels command parameters: rx = %d, tx = %d, other = %d, combined = %d\n",
+ channels->rx_count, channels->tx_count, channels->other_count,
+ channels->combined_count);
+
+ /* We don't support separate rx / tx channels.
+ * We don't allow setting 'other' channels.
+ */
+ if (channels->rx_count || channels->tx_count || channels->other_count
+ || (channels->combined_count == 0) ||
+ (channels->combined_count > BNX2X_MAX_RSS_COUNT(bp))) {
+ DP(BNX2X_MSG_ETHTOOL, "command parameters not supported\n");
+ return -EINVAL;
+ }
+
+ /* Check if there was a change in the active parameters */
+ if (channels->combined_count == BNX2X_NUM_ETH_QUEUES(bp)) {
+ DP(BNX2X_MSG_ETHTOOL, "No change in active parameters\n");
+ return 0;
+ }
+
+ /* Set the requested number of queues in bp context.
+ * Note that the actual number of queues created during load may be
+ * less than requested if memory is low.
+ */
+ if (unlikely(!netif_running(dev))) {
+ bnx2x_change_num_queues(bp, channels->combined_count);
+ return 0;
+ }
+ bnx2x_nic_unload(bp, UNLOAD_NORMAL, true);
+ bnx2x_change_num_queues(bp, channels->combined_count);
+ return bnx2x_nic_load(bp, LOAD_NORMAL);
+}
+
+static const struct ethtool_ops bnx2x_ethtool_ops = {
+ .get_settings = bnx2x_get_settings,
+ .set_settings = bnx2x_set_settings,
+ .get_drvinfo = bnx2x_get_drvinfo,
+ .get_regs_len = bnx2x_get_regs_len,
+ .get_regs = bnx2x_get_regs,
+ .get_dump_flag = bnx2x_get_dump_flag,
+ .get_dump_data = bnx2x_get_dump_data,
+ .set_dump = bnx2x_set_dump,
+ .get_wol = bnx2x_get_wol,
+ .set_wol = bnx2x_set_wol,
+ .get_msglevel = bnx2x_get_msglevel,
+ .set_msglevel = bnx2x_set_msglevel,
+ .nway_reset = bnx2x_nway_reset,
+ .get_link = bnx2x_get_link,
+ .get_eeprom_len = bnx2x_get_eeprom_len,
+ .get_eeprom = bnx2x_get_eeprom,
+ .set_eeprom = bnx2x_set_eeprom,
+ .get_coalesce = bnx2x_get_coalesce,
+ .set_coalesce = bnx2x_set_coalesce,
+ .get_ringparam = bnx2x_get_ringparam,
+ .set_ringparam = bnx2x_set_ringparam,
+ .get_pauseparam = bnx2x_get_pauseparam,
+ .set_pauseparam = bnx2x_set_pauseparam,
+ .self_test = bnx2x_self_test,
+ .get_sset_count = bnx2x_get_sset_count,
+ .get_priv_flags = bnx2x_get_private_flags,
+ .get_strings = bnx2x_get_strings,
+ .set_phys_id = bnx2x_set_phys_id,
+ .get_ethtool_stats = bnx2x_get_ethtool_stats,
+ .get_rxnfc = bnx2x_get_rxnfc,
+ .set_rxnfc = bnx2x_set_rxnfc,
+ .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size,
+ .get_rxfh = bnx2x_get_rxfh,
+ .set_rxfh = bnx2x_set_rxfh,
+ .get_channels = bnx2x_get_channels,
+ .set_channels = bnx2x_set_channels,
+ .get_module_info = bnx2x_get_module_info,
+ .get_module_eeprom = bnx2x_get_module_eeprom,
+ .get_eee = bnx2x_get_eee,
+ .set_eee = bnx2x_set_eee,
+ .get_ts_info = ethtool_op_get_ts_info,
+};
+
+static const struct ethtool_ops bnx2x_vf_ethtool_ops = {
+ .get_settings = bnx2x_get_settings,
+ .set_settings = bnx2x_set_settings,
+ .get_drvinfo = bnx2x_get_drvinfo,
+ .get_msglevel = bnx2x_get_msglevel,
+ .set_msglevel = bnx2x_set_msglevel,
+ .get_link = bnx2x_get_link,
+ .get_coalesce = bnx2x_get_coalesce,
+ .get_ringparam = bnx2x_get_ringparam,
+ .set_ringparam = bnx2x_set_ringparam,
+ .get_sset_count = bnx2x_get_sset_count,
+ .get_strings = bnx2x_get_strings,
+ .get_ethtool_stats = bnx2x_get_ethtool_stats,
+ .get_rxnfc = bnx2x_get_rxnfc,
+ .set_rxnfc = bnx2x_set_rxnfc,
+ .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size,
+ .get_rxfh = bnx2x_get_rxfh,
+ .set_rxfh = bnx2x_set_rxfh,
+ .get_channels = bnx2x_get_channels,
+ .set_channels = bnx2x_set_channels,
+};
+
+void bnx2x_set_ethtool_ops(struct bnx2x *bp, struct net_device *netdev)
+{
+ netdev->ethtool_ops = (IS_PF(bp)) ?
+ &bnx2x_ethtool_ops : &bnx2x_vf_ethtool_ops;
+}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
new file mode 100644
index 00000000000..95dc3654354
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
@@ -0,0 +1,392 @@
+/* bnx2x_fw_defs.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007-2013 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef BNX2X_FW_DEFS_H
+#define BNX2X_FW_DEFS_H
+
+#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[148].base)
+#define CSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[147].base + ((assertListEntry) * IRO[147].m1))
+#define CSTORM_EVENT_RING_DATA_OFFSET(pfId) \
+ (IRO[153].base + (((pfId)>>1) * IRO[153].m1) + (((pfId)&1) * \
+ IRO[153].m2))
+#define CSTORM_EVENT_RING_PROD_OFFSET(pfId) \
+ (IRO[154].base + (((pfId)>>1) * IRO[154].m1) + (((pfId)&1) * \
+ IRO[154].m2))
+#define CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(funcId) \
+ (IRO[159].base + ((funcId) * IRO[159].m1))
+#define CSTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[149].base + ((funcId) * IRO[149].m1))
+#define CSTORM_HC_SYNC_LINE_INDEX_E1X_OFFSET(hcIndex, sbId) \
+ (IRO[139].base + ((hcIndex) * IRO[139].m1) + ((sbId) * IRO[139].m2))
+#define CSTORM_HC_SYNC_LINE_INDEX_E2_OFFSET(hcIndex, sbId) \
+ (IRO[138].base + (((hcIndex)>>2) * IRO[138].m1) + (((hcIndex)&3) \
+ * IRO[138].m2) + ((sbId) * IRO[138].m3))
+#define CSTORM_IGU_MODE_OFFSET (IRO[157].base)
+#define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
+ (IRO[317].base + ((pfId) * IRO[317].m1))
+#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
+ (IRO[318].base + ((pfId) * IRO[318].m1))
+#define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \
+ (IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2))
+#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \
+ (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2))
+#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \
+ (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2))
+#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \
+ (IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2))
+#define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \
+ (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2))
+#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \
+ (IRO[315].base + ((pfId) * IRO[315].m1) + ((iscsiEqId) * IRO[315].m2))
+#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \
+ (IRO[314].base + ((pfId) * IRO[314].m1) + ((iscsiEqId) * IRO[314].m2))
+#define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
+ (IRO[316].base + ((pfId) * IRO[316].m1))
+#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[308].base + ((pfId) * IRO[308].m1))
+#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[307].base + ((pfId) * IRO[307].m1))
+#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[306].base + ((pfId) * IRO[306].m1))
+#define CSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
+ (IRO[151].base + ((funcId) * IRO[151].m1))
+#define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \
+ (IRO[142].base + ((pfId) * IRO[142].m1))
+#define CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(pfId) \
+ (IRO[143].base + ((pfId) * IRO[143].m1))
+#define CSTORM_SP_STATUS_BLOCK_OFFSET(pfId) \
+ (IRO[141].base + ((pfId) * IRO[141].m1))
+#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[141].size)
+#define CSTORM_SP_SYNC_BLOCK_OFFSET(pfId) \
+ (IRO[144].base + ((pfId) * IRO[144].m1))
+#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[144].size)
+#define CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(sbId, hcIndex) \
+ (IRO[136].base + ((sbId) * IRO[136].m1) + ((hcIndex) * IRO[136].m2))
+#define CSTORM_STATUS_BLOCK_DATA_OFFSET(sbId) \
+ (IRO[133].base + ((sbId) * IRO[133].m1))
+#define CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(sbId) \
+ (IRO[134].base + ((sbId) * IRO[134].m1))
+#define CSTORM_STATUS_BLOCK_DATA_TIMEOUT_OFFSET(sbId, hcIndex) \
+ (IRO[135].base + ((sbId) * IRO[135].m1) + ((hcIndex) * IRO[135].m2))
+#define CSTORM_STATUS_BLOCK_OFFSET(sbId) \
+ (IRO[132].base + ((sbId) * IRO[132].m1))
+#define CSTORM_STATUS_BLOCK_SIZE (IRO[132].size)
+#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \
+ (IRO[137].base + ((sbId) * IRO[137].m1))
+#define CSTORM_SYNC_BLOCK_SIZE (IRO[137].size)
+#define CSTORM_VF_PF_CHANNEL_STATE_OFFSET(vfId) \
+ (IRO[155].base + ((vfId) * IRO[155].m1))
+#define CSTORM_VF_PF_CHANNEL_VALID_OFFSET(vfId) \
+ (IRO[156].base + ((vfId) * IRO[156].m1))
+#define CSTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[150].base + ((funcId) * IRO[150].m1))
+#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \
+ (IRO[203].base + ((pfId) * IRO[203].m1))
+#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[102].base)
+#define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[101].base + ((assertListEntry) * IRO[101].m1))
+#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \
+ (IRO[201].base + ((pfId) * IRO[201].m1))
+#define TSTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[103].base + ((funcId) * IRO[103].m1))
+#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
+ (IRO[272].base + ((pfId) * IRO[272].m1))
+#define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \
+ (IRO[273].base + ((pfId) * IRO[273].m1))
+#define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \
+ (IRO[274].base + ((pfId) * IRO[274].m1))
+#define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \
+ (IRO[275].base + ((pfId) * IRO[275].m1))
+#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[271].base + ((pfId) * IRO[271].m1))
+#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[270].base + ((pfId) * IRO[270].m1))
+#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[269].base + ((pfId) * IRO[269].m1))
+#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
+ (IRO[268].base + ((pfId) * IRO[268].m1))
+#define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \
+ (IRO[278].base + ((pfId) * IRO[278].m1))
+#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
+ (IRO[264].base + ((pfId) * IRO[264].m1))
+#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
+ (IRO[265].base + ((pfId) * IRO[265].m1))
+#define TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfId) \
+ (IRO[266].base + ((pfId) * IRO[266].m1))
+#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
+ (IRO[267].base + ((pfId) * IRO[267].m1))
+#define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \
+ (IRO[202].base + ((pfId) * IRO[202].m1))
+#define TSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
+ (IRO[105].base + ((funcId) * IRO[105].m1))
+#define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \
+ (IRO[217].base + ((pfId) * IRO[217].m1))
+#define TSTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[104].base + ((funcId) * IRO[104].m1))
+#define USTORM_AGG_DATA_OFFSET (IRO[206].base)
+#define USTORM_AGG_DATA_SIZE (IRO[206].size)
+#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[177].base)
+#define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[176].base + ((assertListEntry) * IRO[176].m1))
+#define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \
+ (IRO[183].base + ((portId) * IRO[183].m1))
+#define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \
+ (IRO[319].base + ((pfId) * IRO[319].m1))
+#define USTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[178].base + ((funcId) * IRO[178].m1))
+#define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
+ (IRO[283].base + ((pfId) * IRO[283].m1))
+#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
+ (IRO[284].base + ((pfId) * IRO[284].m1))
+#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
+ (IRO[288].base + ((pfId) * IRO[288].m1))
+#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \
+ (IRO[285].base + ((pfId) * IRO[285].m1))
+#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[281].base + ((pfId) * IRO[281].m1))
+#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[280].base + ((pfId) * IRO[280].m1))
+#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[279].base + ((pfId) * IRO[279].m1))
+#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
+ (IRO[282].base + ((pfId) * IRO[282].m1))
+#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \
+ (IRO[286].base + ((pfId) * IRO[286].m1))
+#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
+ (IRO[287].base + ((pfId) * IRO[287].m1))
+#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \
+ (IRO[182].base + ((pfId) * IRO[182].m1))
+#define USTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
+ (IRO[180].base + ((funcId) * IRO[180].m1))
+#define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \
+ (IRO[209].base + ((portId) * IRO[209].m1) + ((clientId) * \
+ IRO[209].m2))
+#define USTORM_RX_PRODS_E2_OFFSET(qzoneId) \
+ (IRO[210].base + ((qzoneId) * IRO[210].m1))
+#define USTORM_TPA_BTR_OFFSET (IRO[207].base)
+#define USTORM_TPA_BTR_SIZE (IRO[207].size)
+#define USTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[179].base + ((funcId) * IRO[179].m1))
+#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[67].base)
+#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[66].base)
+#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[51].base)
+#define XSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
+ (IRO[50].base + ((assertListEntry) * IRO[50].m1))
+#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(portId) \
+ (IRO[43].base + ((portId) * IRO[43].m1))
+#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(pfId) \
+ (IRO[45].base + ((pfId) * IRO[45].m1))
+#define XSTORM_FUNC_EN_OFFSET(funcId) \
+ (IRO[47].base + ((funcId) * IRO[47].m1))
+#define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
+ (IRO[296].base + ((pfId) * IRO[296].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \
+ (IRO[299].base + ((pfId) * IRO[299].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \
+ (IRO[300].base + ((pfId) * IRO[300].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \
+ (IRO[301].base + ((pfId) * IRO[301].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \
+ (IRO[302].base + ((pfId) * IRO[302].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \
+ (IRO[303].base + ((pfId) * IRO[303].m1))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \
+ (IRO[304].base + ((pfId) * IRO[304].m1))
+#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \
+ (IRO[305].base + ((pfId) * IRO[305].m1))
+#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
+ (IRO[295].base + ((pfId) * IRO[295].m1))
+#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
+ (IRO[294].base + ((pfId) * IRO[294].m1))
+#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
+ (IRO[293].base + ((pfId) * IRO[293].m1))
+#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
+ (IRO[298].base + ((pfId) * IRO[298].m1))
+#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \
+ (IRO[297].base + ((pfId) * IRO[297].m1))
+#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \
+ (IRO[292].base + ((pfId) * IRO[292].m1))
+#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
+ (IRO[291].base + ((pfId) * IRO[291].m1))
+#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \
+ (IRO[290].base + ((pfId) * IRO[290].m1))
+#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \
+ (IRO[289].base + ((pfId) * IRO[289].m1))
+#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \
+ (IRO[44].base + ((pfId) * IRO[44].m1))
+#define XSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
+ (IRO[49].base + ((funcId) * IRO[49].m1))
+#define XSTORM_SPQ_DATA_OFFSET(funcId) \
+ (IRO[32].base + ((funcId) * IRO[32].m1))
+#define XSTORM_SPQ_DATA_SIZE (IRO[32].size)
+#define XSTORM_SPQ_PAGE_BASE_OFFSET(funcId) \
+ (IRO[30].base + ((funcId) * IRO[30].m1))
+#define XSTORM_SPQ_PROD_OFFSET(funcId) \
+ (IRO[31].base + ((funcId) * IRO[31].m1))
+#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(portId) \
+ (IRO[211].base + ((portId) * IRO[211].m1))
+#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(portId) \
+ (IRO[212].base + ((portId) * IRO[212].m1))
+#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfId) \
+ (IRO[214].base + (((pfId)>>1) * IRO[214].m1) + (((pfId)&1) * \
+ IRO[214].m2))
+#define XSTORM_VF_TO_PF_OFFSET(funcId) \
+ (IRO[48].base + ((funcId) * IRO[48].m1))
+#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
+
+/* Ethernet Ring parameters */
+#define X_ETH_LOCAL_RING_SIZE 13
+#define FIRST_BD_IN_PKT 0
+#define PARSE_BD_INDEX 1
+#define NUM_OF_ETH_BDS_IN_PAGE ((PAGE_SIZE)/(STRUCT_SIZE(eth_tx_bd)/8))
+#define U_ETH_NUM_OF_SGES_TO_FETCH 8
+#define U_ETH_MAX_SGES_FOR_PACKET 3
+
+/* Rx ring params */
+#define U_ETH_LOCAL_BD_RING_SIZE 8
+#define U_ETH_LOCAL_SGE_RING_SIZE 10
+#define U_ETH_SGL_SIZE 8
+ /* The fw will padd the buffer with this value, so the IP header \
+ will be align to 4 Byte */
+#define IP_HEADER_ALIGNMENT_PADDING 2
+
+#define U_ETH_SGES_PER_PAGE_INVERSE_MASK \
+ (0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1))
+
+#define TU_ETH_CQES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe)/8))
+#define U_ETH_BDS_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))
+#define U_ETH_SGES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8))
+
+#define U_ETH_BDS_PER_PAGE_MASK (U_ETH_BDS_PER_PAGE-1)
+#define U_ETH_CQE_PER_PAGE_MASK (TU_ETH_CQES_PER_PAGE-1)
+#define U_ETH_SGES_PER_PAGE_MASK (U_ETH_SGES_PER_PAGE-1)
+
+#define U_ETH_UNDEFINED_Q 0xFF
+
+#define T_ETH_INDIRECTION_TABLE_SIZE 128
+#define T_ETH_RSS_KEY 10
+#define ETH_NUM_OF_RSS_ENGINES_E2 72
+
+#define FILTER_RULES_COUNT 16
+#define MULTICAST_RULES_COUNT 16
+#define CLASSIFY_RULES_COUNT 16
+
+/*The CRC32 seed, that is used for the hash(reduction) multicast address */
+#define ETH_CRC32_HASH_SEED 0x00000000
+
+#define ETH_CRC32_HASH_BIT_SIZE (8)
+#define ETH_CRC32_HASH_MASK EVAL((1<<ETH_CRC32_HASH_BIT_SIZE)-1)
+
+/* Maximal L2 clients supported */
+#define ETH_MAX_RX_CLIENTS_E1 18
+#define ETH_MAX_RX_CLIENTS_E1H 28
+#define ETH_MAX_RX_CLIENTS_E2 152
+
+/* Maximal statistics client Ids */
+#define MAX_STAT_COUNTER_ID_E1 36
+#define MAX_STAT_COUNTER_ID_E1H 56
+#define MAX_STAT_COUNTER_ID_E2 140
+
+#define MAX_MAC_CREDIT_E1 192 /* Per Chip */
+#define MAX_MAC_CREDIT_E1H 256 /* Per Chip */
+#define MAX_MAC_CREDIT_E2 272 /* Per Path */
+#define MAX_VLAN_CREDIT_E1 0 /* Per Chip */
+#define MAX_VLAN_CREDIT_E1H 0 /* Per Chip */
+#define MAX_VLAN_CREDIT_E2 272 /* Per Path */
+
+/* Maximal aggregation queues supported */
+#define ETH_MAX_AGGREGATION_QUEUES_E1 32
+#define ETH_MAX_AGGREGATION_QUEUES_E1H_E2 64
+
+#define ETH_NUM_OF_MCAST_BINS 256
+#define ETH_NUM_OF_MCAST_ENGINES_E2 72
+
+#define ETH_MIN_RX_CQES_WITHOUT_TPA (MAX_RAMRODS_PER_PORT + 3)
+#define ETH_MIN_RX_CQES_WITH_TPA_E1 \
+ (ETH_MAX_AGGREGATION_QUEUES_E1 + ETH_MIN_RX_CQES_WITHOUT_TPA)
+#define ETH_MIN_RX_CQES_WITH_TPA_E1H_E2 \
+ (ETH_MAX_AGGREGATION_QUEUES_E1H_E2 + ETH_MIN_RX_CQES_WITHOUT_TPA)
+
+#define DISABLE_STATISTIC_COUNTER_ID_VALUE 0
+
+
+/* This file defines HSI constants common to all microcode flows */
+
+#define PROTOCOL_STATE_BIT_OFFSET 6
+
+#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+#define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+#define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+
+/* microcode fixed page page size 4K (chains and ring segments) */
+#define MC_PAGE_SIZE 4096
+
+/* Number of indices per slow-path SB */
+#define HC_SP_SB_MAX_INDICES 16
+
+/* Number of indices per SB */
+#define HC_SB_MAX_INDICES_E1X 8
+#define HC_SB_MAX_INDICES_E2 8
+
+#define HC_SB_MAX_SB_E1X 32
+#define HC_SB_MAX_SB_E2 136
+
+#define HC_SP_SB_ID 0xde
+
+#define HC_SB_MAX_SM 2
+
+#define HC_SB_MAX_DYNAMIC_INDICES 4
+
+/* max number of slow path commands per port */
+#define MAX_RAMRODS_PER_PORT 8
+
+/**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
+
+#define TIMERS_TICK_SIZE_CHIP (1e-3)
+
+#define TSEMI_CLK1_RESUL_CHIP (1e-3)
+
+#define XSEMI_CLK1_RESUL_CHIP (1e-3)
+
+#define SDM_TIMER_TICK_RESUL_CHIP (4 * (1e-6))
+
+/**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
+
+#define XSTORM_IP_ID_ROLL_HALF 0x8000
+#define XSTORM_IP_ID_ROLL_ALL 0
+
+#define FW_LOG_LIST_SIZE 50
+
+#define NUM_OF_SAFC_BITS 16
+#define MAX_COS_NUMBER 4
+#define MAX_TRAFFIC_TYPES 8
+#define MAX_PFC_PRIORITIES 8
+
+ /* used by array traffic_type_to_priority[] to mark traffic type \
+ that is not mapped to priority*/
+#define LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED 0xFF
+
+#define C_ERES_PER_PAGE \
+ (PAGE_SIZE / BITS_TO_BYTES(STRUCT_SIZE(event_ring_elem)))
+#define C_ERE_PER_PAGE_MASK (C_ERES_PER_PAGE - 1)
+
+#define STATS_QUERY_CMD_COUNT 16
+
+#define AFEX_LIST_TABLE_SIZE 4096
+
+#define INVALID_VNIC_ID 0xFF
+
+#define UNDEF_IRO 0x80000000
+
+/* used for defining the amount of FCoE tasks supported for PF */
+#define MAX_FCOE_FUNCS_PER_ENGINE 2
+#define MAX_NUM_FCOE_TASKS_PER_ENGINE 4096
+
+#endif /* BNX2X_FW_DEFS_H */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h
new file mode 100644